From 90184f6712a4c0b0b8a58ab42fbec3a7eff0fe15 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 19 Jun 2004 03:39:16 +0000 Subject: [PATCH 1/5] This file has been removed from HEAD when it should (also) have been removed from the vendor branch. --- contrib/gdb/gdb/abug-rom.c | 167 - contrib/gdb/gdb/acconfig.h | 175 - contrib/gdb/gdb/alpha-nat.c | 308 -- contrib/gdb/gdb/arm-tdep.c | 3146 ----------------- contrib/gdb/gdb/coff-solib.c | 134 - contrib/gdb/gdb/coff-solib.h | 186 - contrib/gdb/gdb/core-sol2.c | 196 -- contrib/gdb/gdb/fr30-tdep.c | 601 ---- contrib/gdb/gdb/i386-stub.c | 952 ------ contrib/gdb/gdb/i386aix-nat.c | 377 -- contrib/gdb/gdb/i386ly-tdep.c | 45 - contrib/gdb/gdb/i386m3-nat.c | 426 --- contrib/gdb/gdb/i386mach-nat.c | 172 - contrib/gdb/gdb/i386v-nat.c | 289 -- contrib/gdb/gdb/i386v4-nat.c | 184 - contrib/gdb/gdb/m3-nat.c | 4565 ------------------------- contrib/gdb/gdb/minimon.h | 601 ---- contrib/gdb/gdb/monitor.c | 2386 ------------- contrib/gdb/gdb/monitor.h | 254 -- contrib/gdb/gdb/osfsolib.c | 938 ----- contrib/gdb/gdb/ppcbug-rom.c | 223 -- contrib/gdb/gdb/procfs.c | 5857 -------------------------------- contrib/gdb/gdb/remote-mips.c | 3599 -------------------- contrib/gdb/gdb/remote-rdp.c | 1456 -------- contrib/gdb/gdb/remote-sim.c | 941 ----- contrib/gdb/gdb/remote-st.c | 837 ----- contrib/gdb/gdb/srec.h | 37 - contrib/gdb/gdb/standalone.c | 579 ---- contrib/gdb/gdb/xcoffread.c | 3046 ----------------- contrib/gdb/gdb/xcoffsolib.c | 196 -- 30 files changed, 32873 deletions(-) delete mode 100644 contrib/gdb/gdb/abug-rom.c delete mode 100644 contrib/gdb/gdb/acconfig.h delete mode 100644 contrib/gdb/gdb/alpha-nat.c delete mode 100644 contrib/gdb/gdb/arm-tdep.c delete mode 100644 contrib/gdb/gdb/coff-solib.c delete mode 100644 contrib/gdb/gdb/coff-solib.h delete mode 100644 contrib/gdb/gdb/core-sol2.c delete mode 100644 contrib/gdb/gdb/fr30-tdep.c delete mode 100644 contrib/gdb/gdb/i386-stub.c delete mode 100644 contrib/gdb/gdb/i386aix-nat.c delete mode 100644 contrib/gdb/gdb/i386ly-tdep.c delete mode 100644 contrib/gdb/gdb/i386m3-nat.c delete mode 100644 contrib/gdb/gdb/i386mach-nat.c delete mode 100644 contrib/gdb/gdb/i386v-nat.c delete mode 100644 contrib/gdb/gdb/i386v4-nat.c delete mode 100644 contrib/gdb/gdb/m3-nat.c delete mode 100644 contrib/gdb/gdb/minimon.h delete mode 100644 contrib/gdb/gdb/monitor.c delete mode 100644 contrib/gdb/gdb/monitor.h delete mode 100644 contrib/gdb/gdb/osfsolib.c delete mode 100644 contrib/gdb/gdb/ppcbug-rom.c delete mode 100644 contrib/gdb/gdb/procfs.c delete mode 100644 contrib/gdb/gdb/remote-mips.c delete mode 100644 contrib/gdb/gdb/remote-rdp.c delete mode 100644 contrib/gdb/gdb/remote-sim.c delete mode 100644 contrib/gdb/gdb/remote-st.c delete mode 100644 contrib/gdb/gdb/srec.h delete mode 100644 contrib/gdb/gdb/standalone.c delete mode 100644 contrib/gdb/gdb/xcoffread.c delete mode 100644 contrib/gdb/gdb/xcoffsolib.c diff --git a/contrib/gdb/gdb/abug-rom.c b/contrib/gdb/gdb/abug-rom.c deleted file mode 100644 index b4c44a94b54..00000000000 --- a/contrib/gdb/gdb/abug-rom.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Remote debugging interface for ABug Rom monitor for GDB, the GNU debugger. - Copyright 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - Written by Rob Savoye of Cygnus Support - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "regcache.h" - -/* Prototypes for local functions. */ - -static void abug_open (char *args, int from_tty); - -static void -abug_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - int regno; - - if (regnamelen != 2) - return; - - switch (regname[0]) - { - case 'S': - if (regname[1] != 'R') - return; - regno = PS_REGNUM; - break; - case 'P': - if (regname[1] != 'C') - return; - regno = PC_REGNUM; - break; - case 'D': - if (regname[1] < '0' || regname[1] > '7') - return; - regno = regname[1] - '0' + D0_REGNUM; - break; - case 'A': - if (regname[1] < '0' || regname[1] > '7') - return; - regno = regname[1] - '0' + A0_REGNUM; - break; - default: - return; - } - - monitor_supply_register (regno, val); -} - -/* - * This array of registers needs to match the indexes used by GDB. The - * whole reason this exists is because the various ROM monitors use - * different names than GDB does, and don't support all the - * registers either. So, typing "info reg sp" becomes an "A7". - */ - -static char *abug_regnames[NUM_REGS] = -{ - "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", - "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", - "PC", -}; - -/* - * Define the monitor command strings. Since these are passed directly - * through to a printf style function, we need can include formatting - * strings. We also need a CR or LF on the end. - */ - -static struct target_ops abug_ops; - -static char *abug_inits[] = -{"\r", NULL}; - -static struct monitor_ops abug_cmds; - -static void -init_abug_cmds (void) -{ - abug_cmds.flags = MO_CLR_BREAK_USES_ADDR; - abug_cmds.init = abug_inits; /* Init strings */ - abug_cmds.cont = "g\r"; /* continue command */ - abug_cmds.step = "t\r"; /* single step */ - abug_cmds.stop = NULL; /* interrupt command */ - abug_cmds.set_break = "br %x\r"; /* set a breakpoint */ - abug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */ - abug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */ - abug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */ - abug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */ - abug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */ - abug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */ - abug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - abug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ - abug_cmds.setmem.term = NULL; /* setreg.term */ - abug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ - abug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */ - abug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */ - abug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */ - abug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - abug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */ - abug_cmds.getmem.term = NULL; /* getmem.term */ - abug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - abug_cmds.setreg.cmd = "rm %s %x\r"; /* setreg.cmd (name, value) */ - abug_cmds.setreg.resp_delim = "="; /* setreg.resp_delim */ - abug_cmds.setreg.term = "? "; /* setreg.term */ - abug_cmds.setreg.term_cmd = ".\r"; /* setreg.term_cmd */ - abug_cmds.getreg.cmd = "rm %s\r"; /* getreg.cmd (name) */ - abug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */ - abug_cmds.getreg.term = "? "; /* getreg.term */ - abug_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */ - abug_cmds.dump_registers = "rd\r"; /* dump_registers */ - abug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - abug_cmds.supply_register = abug_supply_register; /* supply_register */ - abug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - abug_cmds.load = "lo 0\r"; /* download command */ - abug_cmds.loadresp = "\n"; /* load response */ - abug_cmds.prompt = "135Bug>"; /* monitor command prompt */ - abug_cmds.line_term = "\r"; /* end-of-line terminator */ - abug_cmds.cmd_end = NULL; /* optional command terminator */ - abug_cmds.target = &abug_ops; /* target operations */ - abug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - abug_cmds.regnames = abug_regnames; /* registers names */ - abug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -}; - -static void -abug_open (char *args, int from_tty) -{ - monitor_open (args, &abug_cmds, from_tty); -} - -void -_initialize_abug_rom (void) -{ - init_abug_cmds (); - init_monitor_ops (&abug_ops); - - abug_ops.to_shortname = "abug"; - abug_ops.to_longname = "ABug monitor"; - abug_ops.to_doc = "Debug via the ABug monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - abug_ops.to_open = abug_open; - - add_target (&abug_ops); -} diff --git a/contrib/gdb/gdb/acconfig.h b/contrib/gdb/gdb/acconfig.h deleted file mode 100644 index 664bbcf926b..00000000000 --- a/contrib/gdb/gdb/acconfig.h +++ /dev/null @@ -1,175 +0,0 @@ -/* Define if compiling on Solaris 7. */ -#undef _MSE_INT_H - -/* Define if your struct reg has r_fs. */ -#undef HAVE_STRUCT_REG_R_FS - -/* Define if your struct reg has r_gs. */ -#undef HAVE_STRUCT_REG_R_GS - -/* Define if pstatus_t type is available */ -#undef HAVE_PSTATUS_T - -/* Define if prrun_t type is available */ -#undef HAVE_PRRUN_T - -/* Define if fpregset_t type is available. */ -#undef HAVE_FPREGSET_T - -/* Define if gregset_t type is available. */ -#undef HAVE_GREGSET_T - -/* Define if has prgregset_t. */ -#undef HAVE_PRGREGSET_T - -/* Define if has prfpregset_t. */ -#undef HAVE_PRFPREGSET_T - -/* Define if has lwpid_t. */ -#undef HAVE_LWPID_T - -/* Define if has psaddr_t. */ -#undef HAVE_PSADDR_T - -/* Define if has prgregset32_t. */ -#undef HAVE_PRGREGSET32_T - -/* Define if has prfpregset32_t. */ -#undef HAVE_PRFPREGSET32_T - -/* Define if has prsysent_t */ -#undef HAVE_PRSYSENT_T - -/* Define if has pr_sigset_t */ -#undef HAVE_PR_SIGSET_T - -/* Define if has pr_sigaction64_t */ -#undef HAVE_PR_SIGACTION64_T - -/* Define if has pr_siginfo64_t */ -#undef HAVE_PR_SIGINFO64_T - -/* Define if exists and defines struct link_map which has - members with an ``l_'' prefix. (For Solaris, SVR4, and - SVR4-like systems.) */ -#undef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS - -/* Define if exists and defines struct link_map which has - members with an ``lm_'' prefix. (For SunOS.) */ -#undef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS - -/* Define if exists and defines a struct so_map which has - members with an ``som_'' prefix. (Found on older *BSD systems.) */ -#undef HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS - -/* Define if has struct link_map32 */ -#undef HAVE_STRUCT_LINK_MAP32 - -/* Define if the prfpregset_t type is broken. */ -#undef PRFPREGSET_T_BROKEN - -/* Define if you want to use new multi-fd /proc interface - (replaces HAVE_MULTIPLE_PROC_FDS as well as other macros). */ -#undef NEW_PROC_API - -/* Define if ioctl argument PIOCSET is available. */ -#undef HAVE_PROCFS_PIOCSET - -/* Define if the `long long' type works. */ -#undef CC_HAS_LONG_LONG - -/* Define if the "ll" format works to print long long ints. */ -#undef PRINTF_HAS_LONG_LONG - -/* Define if the "%Lg" format works to print long doubles. */ -#undef PRINTF_HAS_LONG_DOUBLE - -/* Define if the "%Lg" format works to scan long doubles. */ -#undef SCANF_HAS_LONG_DOUBLE - -/* Define if using Solaris thread debugging. */ -#undef HAVE_THREAD_DB_LIB - -/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */ -#undef START_INFERIOR_TRAPS_EXPECTED -#undef sys_quotactl - -/* Define if you have HPUX threads */ -#undef HAVE_HPUX_THREAD_SUPPORT - -/* Define if you want to use the memory mapped malloc package (mmalloc). */ -#undef USE_MMALLOC - -/* Define if the runtime uses a routine from mmalloc before gdb has a chance - to initialize mmalloc, and we want to force checking to be used anyway. - This may cause spurious memory corruption messages if the runtime tries - to explicitly deallocate that memory when gdb calls exit. */ -#undef MMCHECK_FORCE - -/* Define to 1 if NLS is requested. */ -#undef ENABLE_NLS - -/* Define as 1 if you have catgets and don't want to use GNU gettext. */ -#undef HAVE_CATGETS - -/* Define as 1 if you have gettext and don't want to use GNU gettext. */ -#undef HAVE_GETTEXT - -/* Define as 1 if you have the stpcpy function. */ -#undef HAVE_STPCPY - -/* Define if your locale.h file contains LC_MESSAGES. */ -#undef HAVE_LC_MESSAGES - -/* Define if you want to use the full-screen terminal user interface. */ -#undef TUI - -/* Define if on solaris uses int instead of - size_t, and assorted other type changes. */ -#undef PROC_SERVICE_IS_OLD - -/* If you want to specify a default CPU variant, define this to be its - name, as a C string. */ -#undef TARGET_CPU_DEFAULT - -/* Define if the simulator is being linked in. */ -#undef WITH_SIM - -/* Set to true if the save_state_t structure is present */ -#undef HAVE_STRUCT_SAVE_STATE_T - -/* Set to true if the save_state_t structure has the ss_wide member */ -#undef HAVE_STRUCT_MEMBER_SS_WIDE - -/* Define if defines the PTRACE_GETREGS request. */ -#undef HAVE_PTRACE_GETREGS - -/* Define if defines the PTRACE_GETFPXREGS request. */ -#undef HAVE_PTRACE_GETFPXREGS - -/* Define if defines the PT_GETDBREGS request. */ -#undef HAVE_PT_GETDBREGS - -/* Define if defines the PT_GETXMMREGS request. */ -#undef HAVE_PT_GETXMMREGS - -/* Define if gnu-regex.c included with GDB should be used. */ -#undef USE_INCLUDED_REGEX - -/* BFD's default architecture. */ -#undef DEFAULT_BFD_ARCH - -/* BFD's default target vector. */ -#undef DEFAULT_BFD_VEC - -/* Multi-arch enabled. */ -#undef GDB_MULTI_ARCH - -/* hostfile */ -#undef GDB_XM_FILE - -/* targetfile */ -#undef GDB_TM_FILE - -/* nativefile */ -#undef GDB_NM_FILE diff --git a/contrib/gdb/gdb/alpha-nat.c b/contrib/gdb/gdb/alpha-nat.c deleted file mode 100644 index f7e565b3003..00000000000 --- a/contrib/gdb/gdb/alpha-nat.c +++ /dev/null @@ -1,308 +0,0 @@ -/* Low level Alpha interface, for GDB when running native. - Copyright 1993, 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "gdbcore.h" -#include "target.h" -#include "regcache.h" -#include -#ifdef __linux__ -#include -#include -#else -#include -#endif -#include - -/* Prototypes for local functions. */ - -static void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR); -static void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR); - -/* Size of elements in jmpbuf */ - -#define JB_ELEMENT_SIZE 8 - -/* The definition for JB_PC in machine/reg.h is wrong. - And we can't get at the correct definition in setjmp.h as it is - not always available (eg. if _POSIX_SOURCE is defined which is the - default). As the defintion is unlikely to change (see comment - in , define the correct value here. */ - -#undef JB_PC -#define JB_PC 2 - -/* Figure out where the longjmp will land. - We expect the first arg to be a pointer to the jmp_buf structure from which - we extract the pc (JB_PC) that we will land at. The pc is copied into PC. - This routine returns true on success. */ - -int -get_longjmp_target (CORE_ADDR *pc) -{ - CORE_ADDR jb_addr; - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - - jb_addr = read_register (A0_REGNUM); - - if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, raw_buffer, - sizeof (CORE_ADDR))) - return 0; - - *pc = extract_address (raw_buffer, sizeof (CORE_ADDR)); - return 1; -} - -/* Extract the register values out of the core file and store - them where `read_register' will find them. - - CORE_REG_SECT points to the register values themselves, read into memory. - CORE_REG_SIZE is the size of that area. - WHICH says which set of registers we are handling (0 = int, 2 = float - on machines where they are discontiguous). - REG_ADDR is the offset from u.u_ar0 to the register values relative to - core_reg_sect. This is used with old-fashioned core files to - locate the registers in a large upage-plus-stack ".reg" section. - Original upage address X is at location core_reg_sect+x+reg_addr. - */ - -static void -fetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) -{ - register int regno; - register int addr; - int bad_reg = -1; - - /* Table to map a gdb regnum to an index in the core register - section. The floating point register values are garbage in - OSF/1.2 core files. OSF5 uses different names for the register - enum list, need to handle two cases. The actual values are the - same. */ - static int core_reg_mapping[NUM_REGS] = - { -#ifdef NCF_REGS -#define EFL NCF_REGS - CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6, - CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6, - CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9, - CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1, - EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7, - EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15, - EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23, - EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31, - CF_PC, -1 -#else -#define EFL (EF_SIZE / 8) - EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6, - EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6, - EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9, - EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1, - EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7, - EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15, - EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23, - EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31, - EF_PC, -1 -#endif - }; - static char zerobuf[MAX_REGISTER_RAW_SIZE] = - {0}; - - for (regno = 0; regno < NUM_REGS; regno++) - { - if (CANNOT_FETCH_REGISTER (regno)) - { - supply_register (regno, zerobuf); - continue; - } - addr = 8 * core_reg_mapping[regno]; - if (addr < 0 || addr >= core_reg_size) - { - if (bad_reg < 0) - bad_reg = regno; - } - else - { - supply_register (regno, core_reg_sect + addr); - } - } - if (bad_reg >= 0) - { - error ("Register %s not found in core file.", REGISTER_NAME (bad_reg)); - } -} - -static void -fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) -{ - if (core_reg_size < 32 * 8) - { - error ("Core file register section too small (%u bytes).", core_reg_size); - return; - } - - if (which == 2) - { - /* The FPU Registers. */ - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], core_reg_sect, 31 * 8); - memset (®isters[REGISTER_BYTE (FP0_REGNUM + 31)], 0, 8); - memset (®ister_valid[FP0_REGNUM], 1, 32); - } - else - { - /* The General Registers. */ - memcpy (®isters[REGISTER_BYTE (V0_REGNUM)], core_reg_sect, 31 * 8); - memcpy (®isters[REGISTER_BYTE (PC_REGNUM)], core_reg_sect + 31 * 8, 8); - memset (®isters[REGISTER_BYTE (ZERO_REGNUM)], 0, 8); - memset (®ister_valid[V0_REGNUM], 1, 32); - register_valid[PC_REGNUM] = 1; - } -} - - -/* Map gdb internal register number to a ptrace ``address''. - These ``addresses'' are defined in */ - -#define REGISTER_PTRACE_ADDR(regno) \ - (regno < FP0_REGNUM ? GPR_BASE + (regno) \ - : regno == PC_REGNUM ? PC \ - : regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \ - : 0) - -/* Return the ptrace ``address'' of register REGNO. */ - -CORE_ADDR -register_addr (int regno, CORE_ADDR blockend) -{ - return REGISTER_PTRACE_ADDR (regno); -} - -int -kernel_u_size (void) -{ - return (sizeof (struct user)); -} - -#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T) -#include - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* - * See the comment in m68k-tdep.c regarding the utility of these functions. - */ - -void -supply_gregset (gdb_gregset_t *gregsetp) -{ - register int regi; - register long *regp = ALPHA_REGSET_BASE (gregsetp); - static char zerobuf[MAX_REGISTER_RAW_SIZE] = - {0}; - - for (regi = 0; regi < 31; regi++) - supply_register (regi, (char *) (regp + regi)); - - supply_register (PC_REGNUM, (char *) (regp + 31)); - - /* Fill inaccessible registers with zero. */ - supply_register (ZERO_REGNUM, zerobuf); - supply_register (FP_REGNUM, zerobuf); -} - -void -fill_gregset (gdb_gregset_t *gregsetp, int regno) -{ - int regi; - register long *regp = ALPHA_REGSET_BASE (gregsetp); - - for (regi = 0; regi < 31; regi++) - if ((regno == -1) || (regno == regi)) - *(regp + regi) = *(long *) ®isters[REGISTER_BYTE (regi)]; - - if ((regno == -1) || (regno == PC_REGNUM)) - *(regp + 31) = *(long *) ®isters[REGISTER_BYTE (PC_REGNUM)]; -} - -/* - * Now we do the same thing for floating-point registers. - * Again, see the comments in m68k-tdep.c. - */ - -void -supply_fpregset (gdb_fpregset_t *fpregsetp) -{ - register int regi; - register long *regp = ALPHA_REGSET_BASE (fpregsetp); - - for (regi = 0; regi < 32; regi++) - supply_register (regi + FP0_REGNUM, (char *) (regp + regi)); -} - -void -fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) -{ - int regi; - register long *regp = ALPHA_REGSET_BASE (fpregsetp); - - for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++) - { - if ((regno == -1) || (regno == regi)) - { - *(regp + regi - FP0_REGNUM) = - *(long *) ®isters[REGISTER_BYTE (regi)]; - } - } -} -#endif - - -/* Register that we are able to handle alpha core file formats. */ - -static struct core_fns alpha_osf_core_fns = -{ - /* This really is bfd_target_unknown_flavour. */ - - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_osf_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -static struct core_fns alpha_elf_core_fns = -{ - bfd_target_elf_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_elf_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_core_alpha (void) -{ - add_core_fns (&alpha_osf_core_fns); - add_core_fns (&alpha_elf_core_fns); -} diff --git a/contrib/gdb/gdb/arm-tdep.c b/contrib/gdb/gdb/arm-tdep.c deleted file mode 100644 index b164f8e73a2..00000000000 --- a/contrib/gdb/gdb/arm-tdep.c +++ /dev/null @@ -1,3146 +0,0 @@ -/* Common target dependent code for GDB on ARM systems. - Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include /* XXX for isupper () */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "symfile.h" -#include "gdb_string.h" -#include "dis-asm.h" /* For register flavors. */ -#include "regcache.h" -#include "doublest.h" -#include "value.h" -#include "arch-utils.h" -#include "solib-svr4.h" - -#include "arm-tdep.h" - -#include "elf-bfd.h" -#include "coff/internal.h" -#include "elf/arm.h" - -/* Each OS has a different mechanism for accessing the various - registers stored in the sigcontext structure. - - SIGCONTEXT_REGISTER_ADDRESS should be defined to the name (or - function pointer) which may be used to determine the addresses - of the various saved registers in the sigcontext structure. - - For the ARM target, there are three parameters to this function. - The first is the pc value of the frame under consideration, the - second the stack pointer of this frame, and the last is the - register number to fetch. - - If the tm.h file does not define this macro, then it's assumed that - no mechanism is needed and we define SIGCONTEXT_REGISTER_ADDRESS to - be 0. - - When it comes time to multi-arching this code, see the identically - named machinery in ia64-tdep.c for an example of how it could be - done. It should not be necessary to modify the code below where - this macro is used. */ - -#ifdef SIGCONTEXT_REGISTER_ADDRESS -#ifndef SIGCONTEXT_REGISTER_ADDRESS_P -#define SIGCONTEXT_REGISTER_ADDRESS_P() 1 -#endif -#else -#define SIGCONTEXT_REGISTER_ADDRESS(SP,PC,REG) 0 -#define SIGCONTEXT_REGISTER_ADDRESS_P() 0 -#endif - -/* Macros for setting and testing a bit in a minimal symbol that marks - it as Thumb function. The MSB of the minimal symbol's "info" field - is used for this purpose. This field is already being used to store - the symbol size, so the assumption is that the symbol size cannot - exceed 2^31. - - MSYMBOL_SET_SPECIAL Actually sets the "special" bit. - MSYMBOL_IS_SPECIAL Tests the "special" bit in a minimal symbol. - MSYMBOL_SIZE Returns the size of the minimal symbol, - i.e. the "info" field with the "special" bit - masked out. */ - -#define MSYMBOL_SET_SPECIAL(msym) \ - MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) \ - | 0x80000000) - -#define MSYMBOL_IS_SPECIAL(msym) \ - (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0) - -#define MSYMBOL_SIZE(msym) \ - ((long) MSYMBOL_INFO (msym) & 0x7fffffff) - -/* This table matches the indicees assigned to enum arm_abi. Keep - them in sync. */ - -static const char * const arm_abi_names[] = -{ - "", - "ARM EABI (version 1)", - "ARM EABI (version 2)", - "GNU/Linux", - "NetBSD (a.out)", - "NetBSD (ELF)", - "APCS", - "FreeBSD", - "Windows CE", - NULL -}; - -/* Number of different reg name sets (options). */ -static int num_flavor_options; - -/* We have more registers than the disassembler as gdb can print the value - of special registers as well. - The general register names are overwritten by whatever is being used by - the disassembler at the moment. We also adjust the case of cpsr and fps. */ - -/* Initial value: Register names used in ARM's ISA documentation. */ -static char * arm_register_name_strings[] = -{"r0", "r1", "r2", "r3", /* 0 1 2 3 */ - "r4", "r5", "r6", "r7", /* 4 5 6 7 */ - "r8", "r9", "r10", "r11", /* 8 9 10 11 */ - "r12", "sp", "lr", "pc", /* 12 13 14 15 */ - "f0", "f1", "f2", "f3", /* 16 17 18 19 */ - "f4", "f5", "f6", "f7", /* 20 21 22 23 */ - "fps", "cpsr" }; /* 24 25 */ -static char **arm_register_names = arm_register_name_strings; - -/* Valid register name flavors. */ -static const char **valid_flavors; - -/* Disassembly flavor to use. Default to "std" register names. */ -static const char *disassembly_flavor; -static int current_option; /* Index to that option in the opcodes table. */ - -/* This is used to keep the bfd arch_info in sync with the disassembly - flavor. */ -static void set_disassembly_flavor_sfunc(char *, int, - struct cmd_list_element *); -static void set_disassembly_flavor (void); - -static void convert_from_extended (void *ptr, void *dbl); - -/* Define other aspects of the stack frame. We keep the offsets of - all saved registers, 'cause we need 'em a lot! We also keep the - current size of the stack frame, and the offset of the frame - pointer from the stack pointer (for frameless functions, and when - we're still in the prologue of a function with a frame) */ - -struct frame_extra_info -{ - int framesize; - int frameoffset; - int framereg; -}; - -/* Addresses for calling Thumb functions have the bit 0 set. - Here are some macros to test, set, or clear bit 0 of addresses. */ -#define IS_THUMB_ADDR(addr) ((addr) & 1) -#define MAKE_THUMB_ADDR(addr) ((addr) | 1) -#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1) - -static int -arm_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - return (chain != 0 && (FRAME_SAVED_PC (thisframe) >= LOWEST_PC)); -} - -/* Set to true if the 32-bit mode is in use. */ - -int arm_apcs_32 = 1; - -/* Flag set by arm_fix_call_dummy that tells whether the target - function is a Thumb function. This flag is checked by - arm_push_arguments. FIXME: Change the PUSH_ARGUMENTS macro (and - its use in valops.c) to pass the function address as an additional - parameter. */ - -static int target_is_thumb; - -/* Flag set by arm_fix_call_dummy that tells whether the calling - function is a Thumb function. This flag is checked by - arm_pc_is_thumb and arm_call_dummy_breakpoint_offset. */ - -static int caller_is_thumb; - -/* Determine if the program counter specified in MEMADDR is in a Thumb - function. */ - -int -arm_pc_is_thumb (CORE_ADDR memaddr) -{ - struct minimal_symbol *sym; - - /* If bit 0 of the address is set, assume this is a Thumb address. */ - if (IS_THUMB_ADDR (memaddr)) - return 1; - - /* Thumb functions have a "special" bit set in minimal symbols. */ - sym = lookup_minimal_symbol_by_pc (memaddr); - if (sym) - { - return (MSYMBOL_IS_SPECIAL (sym)); - } - else - { - return 0; - } -} - -/* Determine if the program counter specified in MEMADDR is in a call - dummy being called from a Thumb function. */ - -int -arm_pc_is_thumb_dummy (CORE_ADDR memaddr) -{ - CORE_ADDR sp = read_sp (); - - /* FIXME: Until we switch for the new call dummy macros, this heuristic - is the best we can do. We are trying to determine if the pc is on - the stack, which (hopefully) will only happen in a call dummy. - We hope the current stack pointer is not so far alway from the dummy - frame location (true if we have not pushed large data structures or - gone too many levels deep) and that our 1024 is not enough to consider - code regions as part of the stack (true for most practical purposes) */ - if (PC_IN_CALL_DUMMY (memaddr, sp, sp + 1024)) - return caller_is_thumb; - else - return 0; -} - -/* Remove useless bits from addresses in a running program. */ -static CORE_ADDR -arm_addr_bits_remove (CORE_ADDR val) -{ - if (arm_pc_is_thumb (val)) - return (val & (arm_apcs_32 ? 0xfffffffe : 0x03fffffe)); - else - return (val & (arm_apcs_32 ? 0xfffffffc : 0x03fffffc)); -} - -/* When reading symbols, we need to zap the low bit of the address, - which may be set to 1 for Thumb functions. */ -static CORE_ADDR -arm_smash_text_address (CORE_ADDR val) -{ - return val & ~1; -} - -/* Immediately after a function call, return the saved pc. Can't - always go through the frames for this because on some machines the - new frame is not set up until the new function executes some - instructions. */ - -static CORE_ADDR -arm_saved_pc_after_call (struct frame_info *frame) -{ - return ADDR_BITS_REMOVE (read_register (ARM_LR_REGNUM)); -} - -/* Determine whether the function invocation represented by FI has a - frame on the stack associated with it. If it does return zero, - otherwise return 1. */ - -static int -arm_frameless_function_invocation (struct frame_info *fi) -{ - CORE_ADDR func_start, after_prologue; - int frameless; - - /* Sometimes we have functions that do a little setup (like saving the - vN registers with the stmdb instruction, but DO NOT set up a frame. - The symbol table will report this as a prologue. However, it is - important not to try to parse these partial frames as frames, or we - will get really confused. - - So I will demand 3 instructions between the start & end of the - prologue before I call it a real prologue, i.e. at least - mov ip, sp, - stmdb sp!, {} - sub sp, ip, #4. */ - - func_start = (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET); - after_prologue = SKIP_PROLOGUE (func_start); - - /* There are some frameless functions whose first two instructions - follow the standard APCS form, in which case after_prologue will - be func_start + 8. */ - - frameless = (after_prologue < func_start + 12); - return frameless; -} - -/* The address of the arguments in the frame. */ -static CORE_ADDR -arm_frame_args_address (struct frame_info *fi) -{ - return fi->frame; -} - -/* The address of the local variables in the frame. */ -static CORE_ADDR -arm_frame_locals_address (struct frame_info *fi) -{ - return fi->frame; -} - -/* The number of arguments being passed in the frame. */ -static int -arm_frame_num_args (struct frame_info *fi) -{ - /* We have no way of knowing. */ - return -1; -} - -/* A typical Thumb prologue looks like this: - push {r7, lr} - add sp, sp, #-28 - add r7, sp, #12 - Sometimes the latter instruction may be replaced by: - mov r7, sp - - or like this: - push {r7, lr} - mov r7, sp - sub sp, #12 - - or, on tpcs, like this: - sub sp,#16 - push {r7, lr} - (many instructions) - mov r7, sp - sub sp, #12 - - There is always one instruction of three classes: - 1 - push - 2 - setting of r7 - 3 - adjusting of sp - - When we have found at least one of each class we are done with the prolog. - Note that the "sub sp, #NN" before the push does not count. - */ - -static CORE_ADDR -thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end) -{ - CORE_ADDR current_pc; - int findmask = 0; /* findmask: - bit 0 - push { rlist } - bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7) - bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp) - */ - - for (current_pc = pc; current_pc + 2 < func_end && current_pc < pc + 40; current_pc += 2) - { - unsigned short insn = read_memory_unsigned_integer (current_pc, 2); - - if ((insn & 0xfe00) == 0xb400) /* push { rlist } */ - { - findmask |= 1; /* push found */ - } - else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR sub sp, #simm */ - { - if ((findmask & 1) == 0) /* before push ? */ - continue; - else - findmask |= 4; /* add/sub sp found */ - } - else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */ - { - findmask |= 2; /* setting of r7 found */ - } - else if (insn == 0x466f) /* mov r7, sp */ - { - findmask |= 2; /* setting of r7 found */ - } - else if (findmask == (4+2+1)) - { - break; /* We have found one of each type of prologue instruction */ - } - else - continue; /* something in the prolog that we don't care about or some - instruction from outside the prolog scheduled here for optimization */ - } - - return current_pc; -} - -/* Advance the PC across any function entry prologue instructions to reach - some "real" code. - - The APCS (ARM Procedure Call Standard) defines the following - prologue: - - mov ip, sp - [stmfd sp!, {a1,a2,a3,a4}] - stmfd sp!, {...,fp,ip,lr,pc} - [stfe f7, [sp, #-12]!] - [stfe f6, [sp, #-12]!] - [stfe f5, [sp, #-12]!] - [stfe f4, [sp, #-12]!] - sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn */ - -static CORE_ADDR -arm_skip_prologue (CORE_ADDR pc) -{ - unsigned long inst; - CORE_ADDR skip_pc; - CORE_ADDR func_addr, func_end; - char *func_name; - struct symtab_and_line sal; - - /* See what the symbol table says. */ - - if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end)) - { - struct symbol *sym; - - /* Found a function. */ - sym = lookup_symbol (func_name, NULL, VAR_NAMESPACE, NULL, NULL); - if (sym && SYMBOL_LANGUAGE (sym) != language_asm) - { - /* Don't use this trick for assembly source files. */ - sal = find_pc_line (func_addr, 0); - if ((sal.line != 0) && (sal.end < func_end)) - return sal.end; - } - } - - /* Check if this is Thumb code. */ - if (arm_pc_is_thumb (pc)) - return thumb_skip_prologue (pc, func_end); - - /* Can't find the prologue end in the symbol table, try it the hard way - by disassembling the instructions. */ - skip_pc = pc; - inst = read_memory_integer (skip_pc, 4); - if (inst != 0xe1a0c00d) /* mov ip, sp */ - return pc; - - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } - - if ((inst & 0xfffff800) != 0xe92dd800) /* stmfd sp!,{...,fp,ip,lr,pc} */ - return pc; - - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - - /* Any insns after this point may float into the code, if it makes - for better instruction scheduling, so we skip them only if we - find them, but still consdier the function to be frame-ful. */ - - /* We may have either one sfmfd instruction here, or several stfe - insns, depending on the version of floating point code we - support. */ - if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, , [sp]! */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } - else - { - while ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } - } - - if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ - skip_pc += 4; - - return skip_pc; -} -/* *INDENT-OFF* */ -/* Function: thumb_scan_prologue (helper function for arm_scan_prologue) - This function decodes a Thumb function prologue to determine: - 1) the size of the stack frame - 2) which registers are saved on it - 3) the offsets of saved regs - 4) the offset from the stack pointer to the frame pointer - This information is stored in the "extra" fields of the frame_info. - - A typical Thumb function prologue would create this stack frame - (offsets relative to FP) - old SP -> 24 stack parameters - 20 LR - 16 R7 - R7 -> 0 local variables (16 bytes) - SP -> -12 additional stack space (12 bytes) - The frame size would thus be 36 bytes, and the frame offset would be - 12 bytes. The frame register is R7. - - The comments for thumb_skip_prolog() describe the algorithm we use to detect - the end of the prolog */ -/* *INDENT-ON* */ - -static void -thumb_scan_prologue (struct frame_info *fi) -{ - CORE_ADDR prologue_start; - CORE_ADDR prologue_end; - CORE_ADDR current_pc; - int saved_reg[16]; /* which register has been copied to register n? */ - int findmask = 0; /* findmask: - bit 0 - push { rlist } - bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7) - bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp) - */ - int i; - - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) - { - struct symtab_and_line sal = find_pc_line (prologue_start, 0); - - if (sal.line == 0) /* no line info, use current PC */ - prologue_end = fi->pc; - else if (sal.end < prologue_end) /* next line begins after fn end */ - prologue_end = sal.end; /* (probably means no prologue) */ - } - else - prologue_end = prologue_start + 40; /* We're in the boondocks: allow for */ - /* 16 pushes, an add, and "mv fp,sp" */ - - prologue_end = min (prologue_end, fi->pc); - - /* Initialize the saved register map. When register H is copied to - register L, we will put H in saved_reg[L]. */ - for (i = 0; i < 16; i++) - saved_reg[i] = i; - - /* Search the prologue looking for instructions that set up the - frame pointer, adjust the stack pointer, and save registers. - Do this until all basic prolog instructions are found. */ - - fi->extra_info->framesize = 0; - for (current_pc = prologue_start; - (current_pc < prologue_end) && ((findmask & 7) != 7); - current_pc += 2) - { - unsigned short insn; - int regno; - int offset; - - insn = read_memory_unsigned_integer (current_pc, 2); - - if ((insn & 0xfe00) == 0xb400) /* push { rlist } */ - { - int mask; - findmask |= 1; /* push found */ - /* Bits 0-7 contain a mask for registers R0-R7. Bit 8 says - whether to save LR (R14). */ - mask = (insn & 0xff) | ((insn & 0x100) << 6); - - /* Calculate offsets of saved R0-R7 and LR. */ - for (regno = ARM_LR_REGNUM; regno >= 0; regno--) - if (mask & (1 << regno)) - { - fi->extra_info->framesize += 4; - fi->saved_regs[saved_reg[regno]] = - -(fi->extra_info->framesize); - saved_reg[regno] = regno; /* reset saved register map */ - } - } - else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR sub sp, #simm */ - { - if ((findmask & 1) == 0) /* before push ? */ - continue; - else - findmask |= 4; /* add/sub sp found */ - - offset = (insn & 0x7f) << 2; /* get scaled offset */ - if (insn & 0x80) /* is it signed? (==subtracting) */ - { - fi->extra_info->frameoffset += offset; - offset = -offset; - } - fi->extra_info->framesize -= offset; - } - else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */ - { - findmask |= 2; /* setting of r7 found */ - fi->extra_info->framereg = THUMB_FP_REGNUM; - /* get scaled offset */ - fi->extra_info->frameoffset = (insn & 0xff) << 2; - } - else if (insn == 0x466f) /* mov r7, sp */ - { - findmask |= 2; /* setting of r7 found */ - fi->extra_info->framereg = THUMB_FP_REGNUM; - fi->extra_info->frameoffset = 0; - saved_reg[THUMB_FP_REGNUM] = ARM_SP_REGNUM; - } - else if ((insn & 0xffc0) == 0x4640) /* mov r0-r7, r8-r15 */ - { - int lo_reg = insn & 7; /* dest. register (r0-r7) */ - int hi_reg = ((insn >> 3) & 7) + 8; /* source register (r8-15) */ - saved_reg[lo_reg] = hi_reg; /* remember hi reg was saved */ - } - else - continue; /* something in the prolog that we don't care about or some - instruction from outside the prolog scheduled here for optimization */ - } -} - -/* Check if prologue for this frame's PC has already been scanned. If - it has, copy the relevant information about that prologue and - return non-zero. Otherwise do not copy anything and return zero. - - The information saved in the cache includes: - * the frame register number; - * the size of the stack frame; - * the offsets of saved regs (relative to the old SP); and - * the offset from the stack pointer to the frame pointer - - The cache contains only one entry, since this is adequate for the - typical sequence of prologue scan requests we get. When performing - a backtrace, GDB will usually ask to scan the same function twice - in a row (once to get the frame chain, and once to fill in the - extra frame information). */ - -static struct frame_info prologue_cache; - -static int -check_prologue_cache (struct frame_info *fi) -{ - int i; - - if (fi->pc == prologue_cache.pc) - { - fi->extra_info->framereg = prologue_cache.extra_info->framereg; - fi->extra_info->framesize = prologue_cache.extra_info->framesize; - fi->extra_info->frameoffset = prologue_cache.extra_info->frameoffset; - for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++) - fi->saved_regs[i] = prologue_cache.saved_regs[i]; - return 1; - } - else - return 0; -} - - -/* Copy the prologue information from fi to the prologue cache. */ - -static void -save_prologue_cache (struct frame_info *fi) -{ - int i; - - prologue_cache.pc = fi->pc; - prologue_cache.extra_info->framereg = fi->extra_info->framereg; - prologue_cache.extra_info->framesize = fi->extra_info->framesize; - prologue_cache.extra_info->frameoffset = fi->extra_info->frameoffset; - - for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++) - prologue_cache.saved_regs[i] = fi->saved_regs[i]; -} - - -/* This function decodes an ARM function prologue to determine: - 1) the size of the stack frame - 2) which registers are saved on it - 3) the offsets of saved regs - 4) the offset from the stack pointer to the frame pointer - This information is stored in the "extra" fields of the frame_info. - - There are two basic forms for the ARM prologue. The fixed argument - function call will look like: - - mov ip, sp - stmfd sp!, {fp, ip, lr, pc} - sub fp, ip, #4 - [sub sp, sp, #4] - - Which would create this stack frame (offsets relative to FP): - IP -> 4 (caller's stack) - FP -> 0 PC (points to address of stmfd instruction + 8 in callee) - -4 LR (return address in caller) - -8 IP (copy of caller's SP) - -12 FP (caller's FP) - SP -> -28 Local variables - - The frame size would thus be 32 bytes, and the frame offset would be - 28 bytes. The stmfd call can also save any of the vN registers it - plans to use, which increases the frame size accordingly. - - Note: The stored PC is 8 off of the STMFD instruction that stored it - because the ARM Store instructions always store PC + 8 when you read - the PC register. - - A variable argument function call will look like: - - mov ip, sp - stmfd sp!, {a1, a2, a3, a4} - stmfd sp!, {fp, ip, lr, pc} - sub fp, ip, #20 - - Which would create this stack frame (offsets relative to FP): - IP -> 20 (caller's stack) - 16 A4 - 12 A3 - 8 A2 - 4 A1 - FP -> 0 PC (points to address of stmfd instruction + 8 in callee) - -4 LR (return address in caller) - -8 IP (copy of caller's SP) - -12 FP (caller's FP) - SP -> -28 Local variables - - The frame size would thus be 48 bytes, and the frame offset would be - 28 bytes. - - There is another potential complication, which is that the optimizer - will try to separate the store of fp in the "stmfd" instruction from - the "sub fp, ip, #NN" instruction. Almost anything can be there, so - we just key on the stmfd, and then scan for the "sub fp, ip, #NN"... - - Also, note, the original version of the ARM toolchain claimed that there - should be an - - instruction at the end of the prologue. I have never seen GCC produce - this, and the ARM docs don't mention it. We still test for it below in - case it happens... - - */ - -static void -arm_scan_prologue (struct frame_info *fi) -{ - int regno, sp_offset, fp_offset; - LONGEST return_value; - CORE_ADDR prologue_start, prologue_end, current_pc; - - /* Check if this function is already in the cache of frame information. */ - if (check_prologue_cache (fi)) - return; - - /* Assume there is no frame until proven otherwise. */ - fi->extra_info->framereg = ARM_SP_REGNUM; - fi->extra_info->framesize = 0; - fi->extra_info->frameoffset = 0; - - /* Check for Thumb prologue. */ - if (arm_pc_is_thumb (fi->pc)) - { - thumb_scan_prologue (fi); - save_prologue_cache (fi); - return; - } - - /* Find the function prologue. If we can't find the function in - the symbol table, peek in the stack frame to find the PC. */ - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) - { - /* One way to find the end of the prologue (which works well - for unoptimized code) is to do the following: - - struct symtab_and_line sal = find_pc_line (prologue_start, 0); - - if (sal.line == 0) - prologue_end = fi->pc; - else if (sal.end < prologue_end) - prologue_end = sal.end; - - This mechanism is very accurate so long as the optimizer - doesn't move any instructions from the function body into the - prologue. If this happens, sal.end will be the last - instruction in the first hunk of prologue code just before - the first instruction that the scheduler has moved from - the body to the prologue. - - In order to make sure that we scan all of the prologue - instructions, we use a slightly less accurate mechanism which - may scan more than necessary. To help compensate for this - lack of accuracy, the prologue scanning loop below contains - several clauses which'll cause the loop to terminate early if - an implausible prologue instruction is encountered. - - The expression - - prologue_start + 64 - - is a suitable endpoint since it accounts for the largest - possible prologue plus up to five instructions inserted by - the scheduler. */ - - if (prologue_end > prologue_start + 64) - { - prologue_end = prologue_start + 64; /* See above. */ - } - } - else - { - /* Get address of the stmfd in the prologue of the callee; the saved - PC is the address of the stmfd + 8. */ - if (!safe_read_memory_integer (fi->frame, 4, &return_value)) - return; - else - { - prologue_start = ADDR_BITS_REMOVE (return_value) - 8; - prologue_end = prologue_start + 64; /* See above. */ - } - } - - /* Now search the prologue looking for instructions that set up the - frame pointer, adjust the stack pointer, and save registers. - - Be careful, however, and if it doesn't look like a prologue, - don't try to scan it. If, for instance, a frameless function - begins with stmfd sp!, then we will tell ourselves there is - a frame, which will confuse stack traceback, as well ad"finish" - and other operations that rely on a knowledge of the stack - traceback. - - In the APCS, the prologue should start with "mov ip, sp" so - if we don't see this as the first insn, we will stop. [Note: - This doesn't seem to be true any longer, so it's now an optional - part of the prologue. - Kevin Buettner, 2001-11-20] */ - - sp_offset = fp_offset = 0; - - if (read_memory_unsigned_integer (prologue_start, 4) - == 0xe1a0c00d) /* mov ip, sp */ - current_pc = prologue_start + 4; - else - current_pc = prologue_start; - - for (; current_pc < prologue_end; current_pc += 4) - { - unsigned int insn = read_memory_unsigned_integer (current_pc, 4); - - if ((insn & 0xffff0000) == 0xe92d0000) - /* stmfd sp!, {..., fp, ip, lr, pc} - or - stmfd sp!, {a1, a2, a3, a4} */ - { - int mask = insn & 0xffff; - - /* Calculate offsets of saved registers. */ - for (regno = ARM_PC_REGNUM; regno >= 0; regno--) - if (mask & (1 << regno)) - { - sp_offset -= 4; - fi->saved_regs[regno] = sp_offset; - } - } - else if ((insn & 0xfffff000) == 0xe24cb000) /* sub fp, ip #n */ - { - unsigned imm = insn & 0xff; /* immediate value */ - unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */ - imm = (imm >> rot) | (imm << (32 - rot)); - fp_offset = -imm; - fi->extra_info->framereg = ARM_FP_REGNUM; - } - else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */ - { - unsigned imm = insn & 0xff; /* immediate value */ - unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */ - imm = (imm >> rot) | (imm << (32 - rot)); - sp_offset -= imm; - } - else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */ - { - sp_offset -= 12; - regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07); - fi->saved_regs[regno] = sp_offset; - } - else if ((insn & 0xffbf0fff) == 0xec2d0200) /* sfmfd f0, 4, [sp!] */ - { - int n_saved_fp_regs; - unsigned int fp_start_reg, fp_bound_reg; - - if ((insn & 0x800) == 0x800) /* N0 is set */ - { - if ((insn & 0x40000) == 0x40000) /* N1 is set */ - n_saved_fp_regs = 3; - else - n_saved_fp_regs = 1; - } - else - { - if ((insn & 0x40000) == 0x40000) /* N1 is set */ - n_saved_fp_regs = 2; - else - n_saved_fp_regs = 4; - } - - fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7); - fp_bound_reg = fp_start_reg + n_saved_fp_regs; - for (; fp_start_reg < fp_bound_reg; fp_start_reg++) - { - sp_offset -= 12; - fi->saved_regs[fp_start_reg++] = sp_offset; - } - } - else if ((insn & 0xf0000000) != 0xe0000000) - break; /* Condition not true, exit early */ - else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ - break; /* Don't scan past a block load */ - else - /* The optimizer might shove anything into the prologue, - so we just skip what we don't recognize. */ - continue; - } - - /* The frame size is just the negative of the offset (from the original SP) - of the last thing thing we pushed on the stack. The frame offset is - [new FP] - [new SP]. */ - fi->extra_info->framesize = -sp_offset; - if (fi->extra_info->framereg == ARM_FP_REGNUM) - fi->extra_info->frameoffset = fp_offset - sp_offset; - else - fi->extra_info->frameoffset = 0; - - save_prologue_cache (fi); -} - -/* Find REGNUM on the stack. Otherwise, it's in an active register. - One thing we might want to do here is to check REGNUM against the - clobber mask, and somehow flag it as invalid if it isn't saved on - the stack somewhere. This would provide a graceful failure mode - when trying to get the value of caller-saves registers for an inner - frame. */ - -static CORE_ADDR -arm_find_callers_reg (struct frame_info *fi, int regnum) -{ - for (; fi; fi = fi->next) - -#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, regnum); - else -#endif - if (fi->saved_regs[regnum] != 0) - return read_memory_integer (fi->saved_regs[regnum], - REGISTER_RAW_SIZE (regnum)); - return read_register (regnum); -} -/* Function: frame_chain Given a GDB frame, determine the address of - the calling function's frame. This will be used to create a new - GDB frame struct, and then INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC - will be called for the new frame. For ARM, we save the frame size - when we initialize the frame_info. */ - -static CORE_ADDR -arm_frame_chain (struct frame_info *fi) -{ -#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */ - CORE_ADDR fn_start, callers_pc, fp; - - /* is this a dummy frame? */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return fi->frame; /* dummy frame same as caller's frame */ - - /* is caller-of-this a dummy frame? */ - callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ - fp = arm_find_callers_reg (fi, ARM_FP_REGNUM); - if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) - return fp; /* dummy frame's frame may bear no relation to ours */ - - if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; /* in _start fn, don't chain further */ -#endif - CORE_ADDR caller_pc, fn_start; - int framereg = fi->extra_info->framereg; - - if (fi->pc < LOWEST_PC) - return 0; - - /* If the caller is the startup code, we're at the end of the chain. */ - caller_pc = FRAME_SAVED_PC (fi); - if (find_pc_partial_function (caller_pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; - - /* If the caller is Thumb and the caller is ARM, or vice versa, - the frame register of the caller is different from ours. - So we must scan the prologue of the caller to determine its - frame register number. */ - /* XXX Fixme, we should try to do this without creating a temporary - caller_fi. */ - if (arm_pc_is_thumb (caller_pc) != arm_pc_is_thumb (fi->pc)) - { - struct frame_info caller_fi; - struct cleanup *old_chain; - - /* Create a temporary frame suitable for scanning the caller's - prologue. (Ugh.) */ - memset (&caller_fi, 0, sizeof (caller_fi)); - caller_fi.extra_info = (struct frame_extra_info *) - xcalloc (1, sizeof (struct frame_extra_info)); - old_chain = make_cleanup (xfree, caller_fi.extra_info); - caller_fi.saved_regs = (CORE_ADDR *) - xcalloc (1, SIZEOF_FRAME_SAVED_REGS); - make_cleanup (xfree, caller_fi.saved_regs); - - /* Now, scan the prologue and obtain the frame register. */ - caller_fi.pc = caller_pc; - arm_scan_prologue (&caller_fi); - framereg = caller_fi.extra_info->framereg; - - /* Deallocate the storage associated with the temporary frame - created above. */ - do_cleanups (old_chain); - } - - /* If the caller used a frame register, return its value. - Otherwise, return the caller's stack pointer. */ - if (framereg == ARM_FP_REGNUM || framereg == THUMB_FP_REGNUM) - return arm_find_callers_reg (fi, framereg); - else - return fi->frame + fi->extra_info->framesize; -} - -/* This function actually figures out the frame address for a given pc - and sp. This is tricky because we sometimes don't use an explicit - frame pointer, and the previous stack pointer isn't necessarily - recorded on the stack. The only reliable way to get this info is - to examine the prologue. FROMLEAF is a little confusing, it means - this is the next frame up the chain AFTER a frameless function. If - this is true, then the frame value for this frame is still in the - fp register. */ - -static void -arm_init_extra_frame_info (int fromleaf, struct frame_info *fi) -{ - int reg; - CORE_ADDR sp; - - if (fi->saved_regs == NULL) - frame_saved_regs_zalloc (fi); - - fi->extra_info = (struct frame_extra_info *) - frame_obstack_alloc (sizeof (struct frame_extra_info)); - - fi->extra_info->framesize = 0; - fi->extra_info->frameoffset = 0; - fi->extra_info->framereg = 0; - - if (fi->next) - fi->pc = FRAME_SAVED_PC (fi->next); - - memset (fi->saved_regs, '\000', sizeof fi->saved_regs); - -#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - { - /* We need to setup fi->frame here because run_stack_dummy gets it wrong - by assuming it's always FP. */ - fi->frame = generic_read_register_dummy (fi->pc, fi->frame, - ARM_SP_REGNUM); - fi->extra_info->framesize = 0; - fi->extra_info->frameoffset = 0; - return; - } - else -#endif - - /* Compute stack pointer for this frame. We use this value for both the - sigtramp and call dummy cases. */ - if (!fi->next) - sp = read_sp(); - else - sp = (fi->next->frame - fi->next->extra_info->frameoffset - + fi->next->extra_info->framesize); - - /* Determine whether or not we're in a sigtramp frame. - Unfortunately, it isn't sufficient to test - fi->signal_handler_caller because this value is sometimes set - after invoking INIT_EXTRA_FRAME_INFO. So we test *both* - fi->signal_handler_caller and IN_SIGTRAMP to determine if we need - to use the sigcontext addresses for the saved registers. - - Note: If an ARM IN_SIGTRAMP method ever needs to compare against - the name of the function, the code below will have to be changed - to first fetch the name of the function and then pass this name - to IN_SIGTRAMP. */ - - if (SIGCONTEXT_REGISTER_ADDRESS_P () - && (fi->signal_handler_caller || IN_SIGTRAMP (fi->pc, (char *)0))) - { - for (reg = 0; reg < NUM_REGS; reg++) - fi->saved_regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, fi->pc, reg); - - /* FIXME: What about thumb mode? */ - fi->extra_info->framereg = ARM_SP_REGNUM; - fi->frame = - read_memory_integer (fi->saved_regs[fi->extra_info->framereg], - REGISTER_RAW_SIZE (fi->extra_info->framereg)); - fi->extra_info->framesize = 0; - fi->extra_info->frameoffset = 0; - - } - else if (PC_IN_CALL_DUMMY (fi->pc, sp, fi->frame)) - { - CORE_ADDR rp; - CORE_ADDR callers_sp; - - /* Set rp point at the high end of the saved registers. */ - rp = fi->frame - REGISTER_SIZE; - - /* Fill in addresses of saved registers. */ - fi->saved_regs[ARM_PS_REGNUM] = rp; - rp -= REGISTER_RAW_SIZE (ARM_PS_REGNUM); - for (reg = ARM_PC_REGNUM; reg >= 0; reg--) - { - fi->saved_regs[reg] = rp; - rp -= REGISTER_RAW_SIZE (reg); - } - - callers_sp = read_memory_integer (fi->saved_regs[ARM_SP_REGNUM], - REGISTER_RAW_SIZE (ARM_SP_REGNUM)); - fi->extra_info->framereg = ARM_FP_REGNUM; - fi->extra_info->framesize = callers_sp - sp; - fi->extra_info->frameoffset = fi->frame - sp; - } - else - { - arm_scan_prologue (fi); - - if (!fi->next) - /* this is the innermost frame? */ - fi->frame = read_register (fi->extra_info->framereg); - else if (fi->extra_info->framereg == ARM_FP_REGNUM - || fi->extra_info->framereg == THUMB_FP_REGNUM) - { - /* not the innermost frame */ - /* If we have an FP, the callee saved it. */ - if (fi->next->saved_regs[fi->extra_info->framereg] != 0) - fi->frame = - read_memory_integer (fi->next - ->saved_regs[fi->extra_info->framereg], 4); - else if (fromleaf) - /* If we were called by a frameless fn. then our frame is - still in the frame pointer register on the board... */ - fi->frame = read_fp (); - } - - /* Calculate actual addresses of saved registers using offsets - determined by arm_scan_prologue. */ - for (reg = 0; reg < NUM_REGS; reg++) - if (fi->saved_regs[reg] != 0) - fi->saved_regs[reg] += (fi->frame + fi->extra_info->framesize - - fi->extra_info->frameoffset); - } -} - - -/* Find the caller of this frame. We do this by seeing if ARM_LR_REGNUM - is saved in the stack anywhere, otherwise we get it from the - registers. - - The old definition of this function was a macro: - #define FRAME_SAVED_PC(FRAME) \ - ADDR_BITS_REMOVE (read_memory_integer ((FRAME)->frame - 4, 4)) */ - -static CORE_ADDR -arm_frame_saved_pc (struct frame_info *fi) -{ -#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, ARM_PC_REGNUM); - else -#endif - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->extra_info->frameoffset, - fi->frame)) - { - return read_memory_integer (fi->saved_regs[ARM_PC_REGNUM], - REGISTER_RAW_SIZE (ARM_PC_REGNUM)); - } - else - { - CORE_ADDR pc = arm_find_callers_reg (fi, ARM_LR_REGNUM); - return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc; - } -} - -/* Return the frame address. On ARM, it is R11; on Thumb it is R7. - Examine the Program Status Register to decide which state we're in. */ - -static CORE_ADDR -arm_read_fp (void) -{ - if (read_register (ARM_PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */ - return read_register (THUMB_FP_REGNUM); /* R7 if Thumb */ - else - return read_register (ARM_FP_REGNUM); /* R11 if ARM */ -} - -/* Store into a struct frame_saved_regs the addresses of the saved - registers of frame described by FRAME_INFO. This includes special - registers such as PC and FP saved in special ways in the stack - frame. SP is even more special: the address we return for it IS - the sp for the next frame. */ - -static void -arm_frame_init_saved_regs (struct frame_info *fip) -{ - - if (fip->saved_regs) - return; - - arm_init_extra_frame_info (0, fip); -} - -/* Push an empty stack frame, to record the current PC, etc. */ - -static void -arm_push_dummy_frame (void) -{ - CORE_ADDR old_sp = read_register (ARM_SP_REGNUM); - CORE_ADDR sp = old_sp; - CORE_ADDR fp, prologue_start; - int regnum; - - /* Push the two dummy prologue instructions in reverse order, - so that they'll be in the correct low-to-high order in memory. */ - /* sub fp, ip, #4 */ - sp = push_word (sp, 0xe24cb004); - /* stmdb sp!, {r0-r10, fp, ip, lr, pc} */ - prologue_start = sp = push_word (sp, 0xe92ddfff); - - /* Push a pointer to the dummy prologue + 12, because when stm - instruction stores the PC, it stores the address of the stm - instruction itself plus 12. */ - fp = sp = push_word (sp, prologue_start + 12); - - /* Push the processor status. */ - sp = push_word (sp, read_register (ARM_PS_REGNUM)); - - /* Push all 16 registers starting with r15. */ - for (regnum = ARM_PC_REGNUM; regnum >= 0; regnum--) - sp = push_word (sp, read_register (regnum)); - - /* Update fp (for both Thumb and ARM) and sp. */ - write_register (ARM_FP_REGNUM, fp); - write_register (THUMB_FP_REGNUM, fp); - write_register (ARM_SP_REGNUM, sp); -} - -/* CALL_DUMMY_WORDS: - This sequence of words is the instructions - - mov lr,pc - mov pc,r4 - illegal - - Note this is 12 bytes. */ - -static LONGEST arm_call_dummy_words[] = -{ - 0xe1a0e00f, 0xe1a0f004, 0xe7ffdefe -}; - -/* Adjust the call_dummy_breakpoint_offset for the bp_call_dummy - breakpoint to the proper address in the call dummy, so that - `finish' after a stop in a call dummy works. - - FIXME rearnsha 2002-02018: Tweeking current_gdbarch is not an - optimal solution, but the call to arm_fix_call_dummy is immediately - followed by a call to run_stack_dummy, which is the only function - where call_dummy_breakpoint_offset is actually used. */ - - -static void -arm_set_call_dummy_breakpoint_offset (void) -{ - if (caller_is_thumb) - set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 4); - else - set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 8); -} - -/* Fix up the call dummy, based on whether the processor is currently - in Thumb or ARM mode, and whether the target function is Thumb or - ARM. There are three different situations requiring three - different dummies: - - * ARM calling ARM: uses the call dummy in tm-arm.h, which has already - been copied into the dummy parameter to this function. - * ARM calling Thumb: uses the call dummy in tm-arm.h, but with the - "mov pc,r4" instruction patched to be a "bx r4" instead. - * Thumb calling anything: uses the Thumb dummy defined below, which - works for calling both ARM and Thumb functions. - - All three call dummies expect to receive the target function - address in R4, with the low bit set if it's a Thumb function. */ - -static void -arm_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - static short thumb_dummy[4] = - { - 0xf000, 0xf801, /* bl label */ - 0xdf18, /* swi 24 */ - 0x4720, /* label: bx r4 */ - }; - static unsigned long arm_bx_r4 = 0xe12fff14; /* bx r4 instruction */ - - /* Set flag indicating whether the current PC is in a Thumb function. */ - caller_is_thumb = arm_pc_is_thumb (read_pc ()); - arm_set_call_dummy_breakpoint_offset (); - - /* If the target function is Thumb, set the low bit of the function - address. And if the CPU is currently in ARM mode, patch the - second instruction of call dummy to use a BX instruction to - switch to Thumb mode. */ - target_is_thumb = arm_pc_is_thumb (fun); - if (target_is_thumb) - { - fun |= 1; - if (!caller_is_thumb) - store_unsigned_integer (dummy + 4, sizeof (arm_bx_r4), arm_bx_r4); - } - - /* If the CPU is currently in Thumb mode, use the Thumb call dummy - instead of the ARM one that's already been copied. This will - work for both Thumb and ARM target functions. */ - if (caller_is_thumb) - { - int i; - char *p = dummy; - int len = sizeof (thumb_dummy) / sizeof (thumb_dummy[0]); - - for (i = 0; i < len; i++) - { - store_unsigned_integer (p, sizeof (thumb_dummy[0]), thumb_dummy[i]); - p += sizeof (thumb_dummy[0]); - } - } - - /* Put the target address in r4; the call dummy will copy this to - the PC. */ - write_register (4, fun); -} - -/* Note: ScottB - - This function does not support passing parameters using the FPA - variant of the APCS. It passes any floating point arguments in the - general registers and/or on the stack. */ - -static CORE_ADDR -arm_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) -{ - char *fp; - int argnum, argreg, nstack_size; - - /* Walk through the list of args and determine how large a temporary - stack is required. Need to take care here as structs may be - passed on the stack, and we have to to push them. */ - nstack_size = -4 * REGISTER_SIZE; /* Some arguments go into A1-A4. */ - if (struct_return) /* The struct address goes in A1. */ - nstack_size += REGISTER_SIZE; - - /* Walk through the arguments and add their size to nstack_size. */ - for (argnum = 0; argnum < nargs; argnum++) - { - int len; - struct type *arg_type; - - arg_type = check_typedef (VALUE_TYPE (args[argnum])); - len = TYPE_LENGTH (arg_type); - - nstack_size += len; - } - - /* Allocate room on the stack, and initialize our stack frame - pointer. */ - fp = NULL; - if (nstack_size > 0) - { - sp -= nstack_size; - fp = (char *) sp; - } - - /* Initialize the integer argument register pointer. */ - argreg = ARM_A1_REGNUM; - - /* The struct_return pointer occupies the first parameter passing - register. */ - if (struct_return) - write_register (argreg++, struct_addr); - - /* Process arguments from left to right. Store as many as allowed - in the parameter passing registers (A1-A4), and save the rest on - the temporary stack. */ - for (argnum = 0; argnum < nargs; argnum++) - { - int len; - char *val; - CORE_ADDR regval; - enum type_code typecode; - struct type *arg_type, *target_type; - - arg_type = check_typedef (VALUE_TYPE (args[argnum])); - target_type = TYPE_TARGET_TYPE (arg_type); - len = TYPE_LENGTH (arg_type); - typecode = TYPE_CODE (arg_type); - val = (char *) VALUE_CONTENTS (args[argnum]); - -#if 1 - /* I don't know why this code was disable. The only logical use - for a function pointer is to call that function, so setting - the mode bit is perfectly fine. FN */ - /* If the argument is a pointer to a function, and it is a Thumb - function, set the low bit of the pointer. */ - if (TYPE_CODE_PTR == typecode - && NULL != target_type - && TYPE_CODE_FUNC == TYPE_CODE (target_type)) - { - CORE_ADDR regval = extract_address (val, len); - if (arm_pc_is_thumb (regval)) - store_address (val, len, MAKE_THUMB_ADDR (regval)); - } -#endif - /* Copy the argument to general registers or the stack in - register-sized pieces. Large arguments are split between - registers and stack. */ - while (len > 0) - { - int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE; - - if (argreg <= ARM_LAST_ARG_REGNUM) - { - /* It's an argument being passed in a general register. */ - regval = extract_address (val, partial_len); - write_register (argreg++, regval); - } - else - { - /* Push the arguments onto the stack. */ - write_memory ((CORE_ADDR) fp, val, REGISTER_SIZE); - fp += REGISTER_SIZE; - } - - len -= partial_len; - val += partial_len; - } - } - - /* Return adjusted stack pointer. */ - return sp; -} - -/* Pop the current frame. So long as the frame info has been initialized - properly (see arm_init_extra_frame_info), this code works for dummy frames - as well as regular frames. I.e, there's no need to have a special case - for dummy frames. */ -static void -arm_pop_frame (void) -{ - int regnum; - struct frame_info *frame = get_current_frame (); - CORE_ADDR old_SP = (frame->frame - frame->extra_info->frameoffset - + frame->extra_info->framesize); - - for (regnum = 0; regnum < NUM_REGS; regnum++) - if (frame->saved_regs[regnum] != 0) - write_register (regnum, - read_memory_integer (frame->saved_regs[regnum], - REGISTER_RAW_SIZE (regnum))); - - write_register (ARM_PC_REGNUM, FRAME_SAVED_PC (frame)); - write_register (ARM_SP_REGNUM, old_SP); - - flush_cached_frames (); -} - -static void -print_fpu_flags (int flags) -{ - if (flags & (1 << 0)) - fputs ("IVO ", stdout); - if (flags & (1 << 1)) - fputs ("DVZ ", stdout); - if (flags & (1 << 2)) - fputs ("OFL ", stdout); - if (flags & (1 << 3)) - fputs ("UFL ", stdout); - if (flags & (1 << 4)) - fputs ("INX ", stdout); - putchar ('\n'); -} - -/* Print interesting information about the floating point processor - (if present) or emulator. */ -static void -arm_print_float_info (void) -{ - register unsigned long status = read_register (ARM_FPS_REGNUM); - int type; - - type = (status >> 24) & 127; - printf ("%s FPU type %d\n", - (status & (1 << 31)) ? "Hardware" : "Software", - type); - fputs ("mask: ", stdout); - print_fpu_flags (status >> 16); - fputs ("flags: ", stdout); - print_fpu_flags (status); -} - -/* Return the GDB type object for the "standard" data type of data in - register N. */ - -static struct type * -arm_register_type (int regnum) -{ - if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS) - { - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - return builtin_type_arm_ext_big; - else - return builtin_type_arm_ext_littlebyte_bigword; - } - else - return builtin_type_int32; -} - -/* Index within `registers' of the first byte of the space for - register N. */ - -static int -arm_register_byte (int regnum) -{ - if (regnum < ARM_F0_REGNUM) - return regnum * INT_REGISTER_RAW_SIZE; - else if (regnum < ARM_PS_REGNUM) - return (NUM_GREGS * INT_REGISTER_RAW_SIZE - + (regnum - ARM_F0_REGNUM) * FP_REGISTER_RAW_SIZE); - else - return (NUM_GREGS * INT_REGISTER_RAW_SIZE - + NUM_FREGS * FP_REGISTER_RAW_SIZE - + (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE); -} - -/* Number of bytes of storage in the actual machine representation for - register N. All registers are 4 bytes, except fp0 - fp7, which are - 12 bytes in length. */ - -static int -arm_register_raw_size (int regnum) -{ - if (regnum < ARM_F0_REGNUM) - return INT_REGISTER_RAW_SIZE; - else if (regnum < ARM_FPS_REGNUM) - return FP_REGISTER_RAW_SIZE; - else - return STATUS_REGISTER_SIZE; -} - -/* Number of bytes of storage in a program's representation - for register N. */ -static int -arm_register_virtual_size (int regnum) -{ - if (regnum < ARM_F0_REGNUM) - return INT_REGISTER_VIRTUAL_SIZE; - else if (regnum < ARM_FPS_REGNUM) - return FP_REGISTER_VIRTUAL_SIZE; - else - return STATUS_REGISTER_SIZE; -} - - -/* NOTE: cagney/2001-08-20: Both convert_from_extended() and - convert_to_extended() use floatformat_arm_ext_littlebyte_bigword. - It is thought that this is is the floating-point register format on - little-endian systems. */ - -static void -convert_from_extended (void *ptr, void *dbl) -{ - DOUBLEST d; - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - floatformat_to_doublest (&floatformat_arm_ext_big, ptr, &d); - else - floatformat_to_doublest (&floatformat_arm_ext_littlebyte_bigword, - ptr, &d); - floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &d, dbl); -} - -static void -convert_to_extended (void *dbl, void *ptr) -{ - DOUBLEST d; - floatformat_to_doublest (TARGET_DOUBLE_FORMAT, ptr, &d); - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - floatformat_from_doublest (&floatformat_arm_ext_big, &d, dbl); - else - floatformat_from_doublest (&floatformat_arm_ext_littlebyte_bigword, - &d, dbl); -} - -static int -condition_true (unsigned long cond, unsigned long status_reg) -{ - if (cond == INST_AL || cond == INST_NV) - return 1; - - switch (cond) - { - case INST_EQ: - return ((status_reg & FLAG_Z) != 0); - case INST_NE: - return ((status_reg & FLAG_Z) == 0); - case INST_CS: - return ((status_reg & FLAG_C) != 0); - case INST_CC: - return ((status_reg & FLAG_C) == 0); - case INST_MI: - return ((status_reg & FLAG_N) != 0); - case INST_PL: - return ((status_reg & FLAG_N) == 0); - case INST_VS: - return ((status_reg & FLAG_V) != 0); - case INST_VC: - return ((status_reg & FLAG_V) == 0); - case INST_HI: - return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C); - case INST_LS: - return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C); - case INST_GE: - return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)); - case INST_LT: - return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)); - case INST_GT: - return (((status_reg & FLAG_Z) == 0) && - (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0))); - case INST_LE: - return (((status_reg & FLAG_Z) != 0) || - (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0))); - } - return 1; -} - -/* Support routines for single stepping. Calculate the next PC value. */ -#define submask(x) ((1L << ((x) + 1)) - 1) -#define bit(obj,st) (((obj) >> (st)) & 1) -#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) -#define sbits(obj,st,fn) \ - ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st)))) -#define BranchDest(addr,instr) \ - ((CORE_ADDR) (((long) (addr)) + 8 + (sbits (instr, 0, 23) << 2))) -#define ARM_PC_32 1 - -static unsigned long -shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val, - unsigned long status_reg) -{ - unsigned long res, shift; - int rm = bits (inst, 0, 3); - unsigned long shifttype = bits (inst, 5, 6); - - if (bit (inst, 4)) - { - int rs = bits (inst, 8, 11); - shift = (rs == 15 ? pc_val + 8 : read_register (rs)) & 0xFF; - } - else - shift = bits (inst, 7, 11); - - res = (rm == 15 - ? ((pc_val | (ARM_PC_32 ? 0 : status_reg)) - + (bit (inst, 4) ? 12 : 8)) - : read_register (rm)); - - switch (shifttype) - { - case 0: /* LSL */ - res = shift >= 32 ? 0 : res << shift; - break; - - case 1: /* LSR */ - res = shift >= 32 ? 0 : res >> shift; - break; - - case 2: /* ASR */ - if (shift >= 32) - shift = 31; - res = ((res & 0x80000000L) - ? ~((~res) >> shift) : res >> shift); - break; - - case 3: /* ROR/RRX */ - shift &= 31; - if (shift == 0) - res = (res >> 1) | (carry ? 0x80000000L : 0); - else - res = (res >> shift) | (res << (32 - shift)); - break; - } - - return res & 0xffffffff; -} - -/* Return number of 1-bits in VAL. */ - -static int -bitcount (unsigned long val) -{ - int nbits; - for (nbits = 0; val != 0; nbits++) - val &= val - 1; /* delete rightmost 1-bit in val */ - return nbits; -} - -CORE_ADDR -thumb_get_next_pc (CORE_ADDR pc) -{ - unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */ - unsigned short inst1 = read_memory_integer (pc, 2); - CORE_ADDR nextpc = pc + 2; /* default is next instruction */ - unsigned long offset; - - if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */ - { - CORE_ADDR sp; - - /* Fetch the saved PC from the stack. It's stored above - all of the other registers. */ - offset = bitcount (bits (inst1, 0, 7)) * REGISTER_SIZE; - sp = read_register (ARM_SP_REGNUM); - nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4); - nextpc = ADDR_BITS_REMOVE (nextpc); - if (nextpc == pc) - error ("Infinite loop detected"); - } - else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */ - { - unsigned long status = read_register (ARM_PS_REGNUM); - unsigned long cond = bits (inst1, 8, 11); - if (cond != 0x0f && condition_true (cond, status)) /* 0x0f = SWI */ - nextpc = pc_val + (sbits (inst1, 0, 7) << 1); - } - else if ((inst1 & 0xf800) == 0xe000) /* unconditional branch */ - { - nextpc = pc_val + (sbits (inst1, 0, 10) << 1); - } - else if ((inst1 & 0xf800) == 0xf000) /* long branch with link */ - { - unsigned short inst2 = read_memory_integer (pc + 2, 2); - offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1); - nextpc = pc_val + offset; - } - - return nextpc; -} - -CORE_ADDR -arm_get_next_pc (CORE_ADDR pc) -{ - unsigned long pc_val; - unsigned long this_instr; - unsigned long status; - CORE_ADDR nextpc; - - if (arm_pc_is_thumb (pc)) - return thumb_get_next_pc (pc); - - pc_val = (unsigned long) pc; - this_instr = read_memory_integer (pc, 4); - status = read_register (ARM_PS_REGNUM); - nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */ - - if (condition_true (bits (this_instr, 28, 31), status)) - { - switch (bits (this_instr, 24, 27)) - { - case 0x0: - case 0x1: /* data processing */ - case 0x2: - case 0x3: - { - unsigned long operand1, operand2, result = 0; - unsigned long rn; - int c; - - if (bits (this_instr, 12, 15) != 15) - break; - - if (bits (this_instr, 22, 25) == 0 - && bits (this_instr, 4, 7) == 9) /* multiply */ - error ("Illegal update to pc in instruction"); - - /* Multiply into PC */ - c = (status & FLAG_C) ? 1 : 0; - rn = bits (this_instr, 16, 19); - operand1 = (rn == 15) ? pc_val + 8 : read_register (rn); - - if (bit (this_instr, 25)) - { - unsigned long immval = bits (this_instr, 0, 7); - unsigned long rotate = 2 * bits (this_instr, 8, 11); - operand2 = ((immval >> rotate) | (immval << (32 - rotate))) - & 0xffffffff; - } - else /* operand 2 is a shifted register */ - operand2 = shifted_reg_val (this_instr, c, pc_val, status); - - switch (bits (this_instr, 21, 24)) - { - case 0x0: /*and */ - result = operand1 & operand2; - break; - - case 0x1: /*eor */ - result = operand1 ^ operand2; - break; - - case 0x2: /*sub */ - result = operand1 - operand2; - break; - - case 0x3: /*rsb */ - result = operand2 - operand1; - break; - - case 0x4: /*add */ - result = operand1 + operand2; - break; - - case 0x5: /*adc */ - result = operand1 + operand2 + c; - break; - - case 0x6: /*sbc */ - result = operand1 - operand2 + c; - break; - - case 0x7: /*rsc */ - result = operand2 - operand1 + c; - break; - - case 0x8: - case 0x9: - case 0xa: - case 0xb: /* tst, teq, cmp, cmn */ - result = (unsigned long) nextpc; - break; - - case 0xc: /*orr */ - result = operand1 | operand2; - break; - - case 0xd: /*mov */ - /* Always step into a function. */ - result = operand2; - break; - - case 0xe: /*bic */ - result = operand1 & ~operand2; - break; - - case 0xf: /*mvn */ - result = ~operand2; - break; - } - nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result); - - if (nextpc == pc) - error ("Infinite loop detected"); - break; - } - - case 0x4: - case 0x5: /* data transfer */ - case 0x6: - case 0x7: - if (bit (this_instr, 20)) - { - /* load */ - if (bits (this_instr, 12, 15) == 15) - { - /* rd == pc */ - unsigned long rn; - unsigned long base; - - if (bit (this_instr, 22)) - error ("Illegal update to pc in instruction"); - - /* byte write to PC */ - rn = bits (this_instr, 16, 19); - base = (rn == 15) ? pc_val + 8 : read_register (rn); - if (bit (this_instr, 24)) - { - /* pre-indexed */ - int c = (status & FLAG_C) ? 1 : 0; - unsigned long offset = - (bit (this_instr, 25) - ? shifted_reg_val (this_instr, c, pc_val, status) - : bits (this_instr, 0, 11)); - - if (bit (this_instr, 23)) - base += offset; - else - base -= offset; - } - nextpc = (CORE_ADDR) read_memory_integer ((CORE_ADDR) base, - 4); - - nextpc = ADDR_BITS_REMOVE (nextpc); - - if (nextpc == pc) - error ("Infinite loop detected"); - } - } - break; - - case 0x8: - case 0x9: /* block transfer */ - if (bit (this_instr, 20)) - { - /* LDM */ - if (bit (this_instr, 15)) - { - /* loading pc */ - int offset = 0; - - if (bit (this_instr, 23)) - { - /* up */ - unsigned long reglist = bits (this_instr, 0, 14); - offset = bitcount (reglist) * 4; - if (bit (this_instr, 24)) /* pre */ - offset += 4; - } - else if (bit (this_instr, 24)) - offset = -4; - - { - unsigned long rn_val = - read_register (bits (this_instr, 16, 19)); - nextpc = - (CORE_ADDR) read_memory_integer ((CORE_ADDR) (rn_val - + offset), - 4); - } - nextpc = ADDR_BITS_REMOVE (nextpc); - if (nextpc == pc) - error ("Infinite loop detected"); - } - } - break; - - case 0xb: /* branch & link */ - case 0xa: /* branch */ - { - nextpc = BranchDest (pc, this_instr); - - nextpc = ADDR_BITS_REMOVE (nextpc); - if (nextpc == pc) - error ("Infinite loop detected"); - break; - } - - case 0xc: - case 0xd: - case 0xe: /* coproc ops */ - case 0xf: /* SWI */ - break; - - default: - fprintf_filtered (gdb_stderr, "Bad bit-field extraction\n"); - return (pc); - } - } - - return nextpc; -} - -/* single_step() is called just before we want to resume the inferior, - if we want to single-step it but there is no hardware or kernel - single-step support. We find the target of the coming instruction - and breakpoint it. - - single_step is also called just after the inferior stops. If we had - set up a simulated single-step, we undo our damage. */ - -static void -arm_software_single_step (enum target_signal sig, int insert_bpt) -{ - static int next_pc; /* State between setting and unsetting. */ - static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ - - if (insert_bpt) - { - next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); - target_insert_breakpoint (next_pc, break_mem); - } - else - target_remove_breakpoint (next_pc, break_mem); -} - -#include "bfd-in2.h" -#include "libcoff.h" - -static int -gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info) -{ - if (arm_pc_is_thumb (memaddr)) - { - static asymbol *asym; - static combined_entry_type ce; - static struct coff_symbol_struct csym; - static struct _bfd fake_bfd; - static bfd_target fake_target; - - if (csym.native == NULL) - { - /* Create a fake symbol vector containing a Thumb symbol. This is - solely so that the code in print_insn_little_arm() and - print_insn_big_arm() in opcodes/arm-dis.c will detect the presence - of a Thumb symbol and switch to decoding Thumb instructions. */ - - fake_target.flavour = bfd_target_coff_flavour; - fake_bfd.xvec = &fake_target; - ce.u.syment.n_sclass = C_THUMBEXTFUNC; - csym.native = &ce; - csym.symbol.the_bfd = &fake_bfd; - csym.symbol.name = "fake"; - asym = (asymbol *) & csym; - } - - memaddr = UNMAKE_THUMB_ADDR (memaddr); - info->symbols = &asym; - } - else - info->symbols = NULL; - - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - return print_insn_big_arm (memaddr, info); - else - return print_insn_little_arm (memaddr, info); -} - -/* The following define instruction sequences that will cause ARM - cpu's to take an undefined instruction trap. These are used to - signal a breakpoint to GDB. - - The newer ARMv4T cpu's are capable of operating in ARM or Thumb - modes. A different instruction is required for each mode. The ARM - cpu's can also be big or little endian. Thus four different - instructions are needed to support all cases. - - Note: ARMv4 defines several new instructions that will take the - undefined instruction trap. ARM7TDMI is nominally ARMv4T, but does - not in fact add the new instructions. The new undefined - instructions in ARMv4 are all instructions that had no defined - behaviour in earlier chips. There is no guarantee that they will - raise an exception, but may be treated as NOP's. In practice, it - may only safe to rely on instructions matching: - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - C C C C 0 1 1 x x x x x x x x x x x x x x x x x x x x 1 x x x x - - Even this may only true if the condition predicate is true. The - following use a condition predicate of ALWAYS so it is always TRUE. - - There are other ways of forcing a breakpoint. GNU/Linux, RISC iX, - and NetBSD all use a software interrupt rather than an undefined - instruction to force a trap. This can be handled by by the - abi-specific code during establishment of the gdbarch vector. */ - - -/* NOTE rearnsha 2002-02-18: for now we allow a non-multi-arch gdb to - override these definitions. */ -#ifndef ARM_LE_BREAKPOINT -#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} -#endif -#ifndef ARM_BE_BREAKPOINT -#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} -#endif -#ifndef THUMB_LE_BREAKPOINT -#define THUMB_LE_BREAKPOINT {0xfe,0xdf} -#endif -#ifndef THUMB_BE_BREAKPOINT -#define THUMB_BE_BREAKPOINT {0xdf,0xfe} -#endif - -static const char arm_default_arm_le_breakpoint[] = ARM_LE_BREAKPOINT; -static const char arm_default_arm_be_breakpoint[] = ARM_BE_BREAKPOINT; -static const char arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT; -static const char arm_default_thumb_be_breakpoint[] = THUMB_BE_BREAKPOINT; - -/* Determine the type and size of breakpoint to insert at PCPTR. Uses - the program counter value to determine whether a 16-bit or 32-bit - breakpoint should be used. It returns a pointer to a string of - bytes that encode a breakpoint instruction, stores the length of - the string to *lenptr, and adjusts the program counter (if - necessary) to point to the actual memory location where the - breakpoint should be inserted. */ - -/* XXX ??? from old tm-arm.h: if we're using RDP, then we're inserting - breakpoints and storing their handles instread of what was in - memory. It is nice that this is the same size as a handle - - otherwise remote-rdp will have to change. */ - -unsigned char * -arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr)) - { - *pcptr = UNMAKE_THUMB_ADDR (*pcptr); - *lenptr = tdep->thumb_breakpoint_size; - return tdep->thumb_breakpoint; - } - else - { - *lenptr = tdep->arm_breakpoint_size; - return tdep->arm_breakpoint; - } -} - -/* Extract from an array REGBUF containing the (raw) register state a - function return value of type TYPE, and copy that, in virtual - format, into VALBUF. */ - -static void -arm_extract_return_value (struct type *type, - char regbuf[REGISTER_BYTES], - char *valbuf) -{ - if (TYPE_CODE_FLT == TYPE_CODE (type)) - { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - switch (tdep->fp_model) - { - case ARM_FLOAT_FPA: - convert_from_extended (®buf[REGISTER_BYTE (ARM_F0_REGNUM)], - valbuf); - break; - - case ARM_FLOAT_SOFT: - case ARM_FLOAT_SOFT_VFP: - memcpy (valbuf, ®buf[REGISTER_BYTE (ARM_A1_REGNUM)], - TYPE_LENGTH (type)); - break; - - default: - internal_error - (__FILE__, __LINE__, - "arm_extract_return_value: Floating point model not supported"); - break; - } - } - else - memcpy (valbuf, ®buf[REGISTER_BYTE (ARM_A1_REGNUM)], - TYPE_LENGTH (type)); -} - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value. */ - -static CORE_ADDR -arm_extract_struct_value_address (char *regbuf) -{ - return extract_address (regbuf, REGISTER_RAW_SIZE(ARM_A1_REGNUM)); -} - -/* Will a function return an aggregate type in memory or in a - register? Return 0 if an aggregate type can be returned in a - register, 1 if it must be returned in memory. */ - -static int -arm_use_struct_convention (int gcc_p, struct type *type) -{ - int nRc; - register enum type_code code; - - /* In the ARM ABI, "integer" like aggregate types are returned in - registers. For an aggregate type to be integer like, its size - must be less than or equal to REGISTER_SIZE and the offset of - each addressable subfield must be zero. Note that bit fields are - not addressable, and all addressable subfields of unions always - start at offset zero. - - This function is based on the behaviour of GCC 2.95.1. - See: gcc/arm.c: arm_return_in_memory() for details. - - Note: All versions of GCC before GCC 2.95.2 do not set up the - parameters correctly for a function returning the following - structure: struct { float f;}; This should be returned in memory, - not a register. Richard Earnshaw sent me a patch, but I do not - know of any way to detect if a function like the above has been - compiled with the correct calling convention. */ - - /* All aggregate types that won't fit in a register must be returned - in memory. */ - if (TYPE_LENGTH (type) > REGISTER_SIZE) - { - return 1; - } - - /* The only aggregate types that can be returned in a register are - structs and unions. Arrays must be returned in memory. */ - code = TYPE_CODE (type); - if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code)) - { - return 1; - } - - /* Assume all other aggregate types can be returned in a register. - Run a check for structures, unions and arrays. */ - nRc = 0; - - if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code)) - { - int i; - /* Need to check if this struct/union is "integer" like. For - this to be true, its size must be less than or equal to - REGISTER_SIZE and the offset of each addressable subfield - must be zero. Note that bit fields are not addressable, and - unions always start at offset zero. If any of the subfields - is a floating point type, the struct/union cannot be an - integer type. */ - - /* For each field in the object, check: - 1) Is it FP? --> yes, nRc = 1; - 2) Is it addressable (bitpos != 0) and - not packed (bitsize == 0)? - --> yes, nRc = 1 - */ - - for (i = 0; i < TYPE_NFIELDS (type); i++) - { - enum type_code field_type_code; - field_type_code = TYPE_CODE (TYPE_FIELD_TYPE (type, i)); - - /* Is it a floating point type field? */ - if (field_type_code == TYPE_CODE_FLT) - { - nRc = 1; - break; - } - - /* If bitpos != 0, then we have to care about it. */ - if (TYPE_FIELD_BITPOS (type, i) != 0) - { - /* Bitfields are not addressable. If the field bitsize is - zero, then the field is not packed. Hence it cannot be - a bitfield or any other packed type. */ - if (TYPE_FIELD_BITSIZE (type, i) == 0) - { - nRc = 1; - break; - } - } - } - } - - return nRc; -} - -/* Write into appropriate registers a function return value of type - TYPE, given in virtual format. */ - -static void -arm_store_return_value (struct type *type, char *valbuf) -{ - if (TYPE_CODE (type) == TYPE_CODE_FLT) - { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - char buf[MAX_REGISTER_RAW_SIZE]; - - switch (tdep->fp_model) - { - case ARM_FLOAT_FPA: - - convert_to_extended (valbuf, buf); - write_register_bytes (REGISTER_BYTE (ARM_F0_REGNUM), buf, - MAX_REGISTER_RAW_SIZE); - break; - - case ARM_FLOAT_SOFT: - case ARM_FLOAT_SOFT_VFP: - write_register_bytes (ARM_A1_REGNUM, valbuf, TYPE_LENGTH (type)); - break; - - default: - internal_error - (__FILE__, __LINE__, - "arm_store_return_value: Floating point model not supported"); - break; - } - } - else - write_register_bytes (ARM_A1_REGNUM, valbuf, TYPE_LENGTH (type)); -} - -/* Store the address of the place in which to copy the structure the - subroutine will return. This is called from call_function. */ - -static void -arm_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - write_register (ARM_A1_REGNUM, addr); -} - -static int -arm_get_longjmp_target (CORE_ADDR *pc) -{ - CORE_ADDR jb_addr; - char buf[INT_REGISTER_RAW_SIZE]; - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - jb_addr = read_register (ARM_A1_REGNUM); - - if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf, - INT_REGISTER_RAW_SIZE)) - return 0; - - *pc = extract_address (buf, INT_REGISTER_RAW_SIZE); - return 1; -} - -/* Return non-zero if the PC is inside a thumb call thunk. */ - -int -arm_in_call_stub (CORE_ADDR pc, char *name) -{ - CORE_ADDR start_addr; - - /* Find the starting address of the function containing the PC. If - the caller didn't give us a name, look it up at the same time. */ - if (find_pc_partial_function (pc, name ? NULL : &name, &start_addr, NULL) == 0) - return 0; - - return strncmp (name, "_call_via_r", 11) == 0; -} - -/* If PC is in a Thumb call or return stub, return the address of the - target PC, which is in a register. The thunk functions are called - _called_via_xx, where x is the register name. The possible names - are r0-r9, sl, fp, ip, sp, and lr. */ - -CORE_ADDR -arm_skip_stub (CORE_ADDR pc) -{ - char *name; - CORE_ADDR start_addr; - - /* Find the starting address and name of the function containing the PC. */ - if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0) - return 0; - - /* Call thunks always start with "_call_via_". */ - if (strncmp (name, "_call_via_", 10) == 0) - { - /* Use the name suffix to determine which register contains the - target PC. */ - static char *table[15] = - {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "sl", "fp", "ip", "sp", "lr" - }; - int regno; - - for (regno = 0; regno <= 14; regno++) - if (strcmp (&name[10], table[regno]) == 0) - return read_register (regno); - } - - return 0; /* not a stub */ -} - -/* If the user changes the register disassembly flavor used for info register - and other commands, we have to also switch the flavor used in opcodes - for disassembly output. - This function is run in the set disassembly_flavor command, and does that. */ - -static void -set_disassembly_flavor_sfunc (char *args, int from_tty, - struct cmd_list_element *c) -{ - set_disassembly_flavor (); -} - -/* Return the ARM register name corresponding to register I. */ -static char * -arm_register_name (int i) -{ - return arm_register_names[i]; -} - -static void -set_disassembly_flavor (void) -{ - const char *setname, *setdesc, **regnames; - int numregs, j; - - /* Find the flavor that the user wants in the opcodes table. */ - int current = 0; - numregs = get_arm_regnames (current, &setname, &setdesc, ®names); - while ((disassembly_flavor != setname) - && (current < num_flavor_options)) - get_arm_regnames (++current, &setname, &setdesc, ®names); - current_option = current; - - /* Fill our copy. */ - for (j = 0; j < numregs; j++) - arm_register_names[j] = (char *) regnames[j]; - - /* Adjust case. */ - if (isupper (*regnames[ARM_PC_REGNUM])) - { - arm_register_names[ARM_FPS_REGNUM] = "FPS"; - arm_register_names[ARM_PS_REGNUM] = "CPSR"; - } - else - { - arm_register_names[ARM_FPS_REGNUM] = "fps"; - arm_register_names[ARM_PS_REGNUM] = "cpsr"; - } - - /* Synchronize the disassembler. */ - set_arm_regname_option (current); -} - -/* arm_othernames implements the "othernames" command. This is kind - of hacky, and I prefer the set-show disassembly-flavor which is - also used for the x86 gdb. I will keep this around, however, in - case anyone is actually using it. */ - -static void -arm_othernames (char *names, int n) -{ - /* Circle through the various flavors. */ - current_option = (current_option + 1) % num_flavor_options; - - disassembly_flavor = valid_flavors[current_option]; - set_disassembly_flavor (); -} - -/* Fetch, and possibly build, an appropriate link_map_offsets structure - for ARM linux targets using the struct offsets defined in . - Note, however, that link.h is not actually referred to in this file. - Instead, the relevant structs offsets were obtained from examining - link.h. (We can't refer to link.h from this file because the host - system won't necessarily have it, or if it does, the structs which - it defines will refer to the host system, not the target.) */ - -struct link_map_offsets * -arm_linux_svr4_fetch_link_map_offsets (void) -{ - static struct link_map_offsets lmo; - static struct link_map_offsets *lmp = 0; - - if (lmp == 0) - { - lmp = &lmo; - - lmo.r_debug_size = 8; /* Actual size is 20, but this is all we - need. */ - - lmo.r_map_offset = 4; - lmo.r_map_size = 4; - - lmo.link_map_size = 20; /* Actual size is 552, but this is all we - need. */ - - lmo.l_addr_offset = 0; - lmo.l_addr_size = 4; - - lmo.l_name_offset = 4; - lmo.l_name_size = 4; - - lmo.l_next_offset = 12; - lmo.l_next_size = 4; - - lmo.l_prev_offset = 16; - lmo.l_prev_size = 4; - } - - return lmp; -} - -/* Test whether the coff symbol specific value corresponds to a Thumb - function. */ - -static int -coff_sym_is_thumb (int val) -{ - return (val == C_THUMBEXT || - val == C_THUMBSTAT || - val == C_THUMBEXTFUNC || - val == C_THUMBSTATFUNC || - val == C_THUMBLABEL); -} - -/* arm_coff_make_msymbol_special() - arm_elf_make_msymbol_special() - - These functions test whether the COFF or ELF symbol corresponds to - an address in thumb code, and set a "special" bit in a minimal - symbol to indicate that it does. */ - -static void -arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym) -{ - /* Thumb symbols are of type STT_LOPROC, (synonymous with - STT_ARM_TFUNC). */ - if (ELF_ST_TYPE (((elf_symbol_type *)sym)->internal_elf_sym.st_info) - == STT_LOPROC) - MSYMBOL_SET_SPECIAL (msym); -} - -static void -arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym) -{ - if (coff_sym_is_thumb (val)) - MSYMBOL_SET_SPECIAL (msym); -} - - -static void -process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) -{ - enum arm_abi *os_ident_ptr = obj; - const char *name; - unsigned int sectsize; - - name = bfd_get_section_name (abfd, sect); - sectsize = bfd_section_size (abfd, sect); - - if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0) - { - unsigned int name_length, data_length, note_type; - char *note; - - /* If the section is larger than this, it's probably not what we are - looking for. */ - if (sectsize > 128) - sectsize = 128; - - note = alloca (sectsize); - - bfd_get_section_contents (abfd, sect, note, - (file_ptr) 0, (bfd_size_type) sectsize); - - name_length = bfd_h_get_32 (abfd, note); - data_length = bfd_h_get_32 (abfd, note + 4); - note_type = bfd_h_get_32 (abfd, note + 8); - - if (name_length == 4 && data_length == 16 && note_type == 1 - && strcmp (note + 12, "GNU") == 0) - { - int os_number = bfd_h_get_32 (abfd, note + 16); - - /* The case numbers are from abi-tags in glibc. */ - switch (os_number) - { - case 0 : - *os_ident_ptr = ARM_ABI_LINUX; - break; - - case 1 : - internal_error - (__FILE__, __LINE__, - "process_note_abi_sections: Hurd objects not supported"); - break; - - case 2 : - internal_error - (__FILE__, __LINE__, - "process_note_abi_sections: Solaris objects not supported"); - break; - - default : - internal_error - (__FILE__, __LINE__, - "process_note_abi_sections: unknown OS number %d", - os_number); - break; - } - } - } - /* NetBSD uses a similar trick. */ - else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0) - { - unsigned int name_length, desc_length, note_type; - char *note; - - /* If the section is larger than this, it's probably not what we are - looking for. */ - if (sectsize > 128) - sectsize = 128; - - note = alloca (sectsize); - - bfd_get_section_contents (abfd, sect, note, - (file_ptr) 0, (bfd_size_type) sectsize); - - name_length = bfd_h_get_32 (abfd, note); - desc_length = bfd_h_get_32 (abfd, note + 4); - note_type = bfd_h_get_32 (abfd, note + 8); - - if (name_length == 7 && desc_length == 4 && note_type == 1 - && strcmp (note + 12, "NetBSD") == 0) - /* XXX Should we check the version here? - Probably not necessary yet. */ - *os_ident_ptr = ARM_ABI_NETBSD_ELF; - } -} - -/* Return one of the ELFOSABI_ constants for BFDs representing ELF - executables. If it's not an ELF executable or if the OS/ABI couldn't - be determined, simply return -1. */ - -static int -get_elfosabi (bfd *abfd) -{ - int elfosabi; - enum arm_abi arm_abi = ARM_ABI_UNKNOWN; - - elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; - - /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate - that we're on a SYSV system. However, GNU/Linux uses a note section - to record OS/ABI info, but leaves e_ident[EI_OSABI] zero. So we - have to check the note sections too. - - GNU/ARM tools set the EI_OSABI field to ELFOSABI_ARM, so handle that - as well. */ - if (elfosabi == 0 || elfosabi == ELFOSABI_ARM) - { - bfd_map_over_sections (abfd, - process_note_abi_tag_sections, - &arm_abi); - } - - if (arm_abi != ARM_ABI_UNKNOWN) - return arm_abi; - - switch (elfosabi) - { - case ELFOSABI_NONE: - /* Existing ARM Tools don't set this field, so look at the EI_FLAGS - field for more information. */ - - switch (EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags)) - { - case EF_ARM_EABI_VER1: - return ARM_ABI_EABI_V1; - - case EF_ARM_EABI_VER2: - return ARM_ABI_EABI_V2; - - case EF_ARM_EABI_UNKNOWN: - /* Assume GNU tools. */ - return ARM_ABI_APCS; - - default: - internal_error (__FILE__, __LINE__, - "get_elfosabi: Unknown ARM EABI version 0x%lx", - EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags)); - - } - break; - - case ELFOSABI_NETBSD: - return ARM_ABI_NETBSD_ELF; - - case ELFOSABI_FREEBSD: - return ARM_ABI_FREEBSD; - - case ELFOSABI_LINUX: - return ARM_ABI_LINUX; - - case ELFOSABI_ARM: - /* Assume GNU tools with the old APCS abi. */ - return ARM_ABI_APCS; - - default: - } - - return ARM_ABI_UNKNOWN; -} - -struct arm_abi_handler -{ - struct arm_abi_handler *next; - enum arm_abi abi; - void (*init_abi)(struct gdbarch_info, struct gdbarch *); -}; - -struct arm_abi_handler *arm_abi_handler_list = NULL; - -void -arm_gdbarch_register_os_abi (enum arm_abi abi, - void (*init_abi)(struct gdbarch_info, - struct gdbarch *)) -{ - struct arm_abi_handler **handler_p; - - for (handler_p = &arm_abi_handler_list; *handler_p != NULL; - handler_p = &(*handler_p)->next) - { - if ((*handler_p)->abi == abi) - { - internal_error - (__FILE__, __LINE__, - "arm_gdbarch_register_os_abi: A handler for this ABI variant (%d)" - " has already been registered", (int)abi); - /* If user wants to continue, override previous definition. */ - (*handler_p)->init_abi = init_abi; - return; - } - } - - (*handler_p) - = (struct arm_abi_handler *) xmalloc (sizeof (struct arm_abi_handler)); - (*handler_p)->next = NULL; - (*handler_p)->abi = abi; - (*handler_p)->init_abi = init_abi; -} - -/* Initialize the current architecture based on INFO. If possible, re-use an - architecture from ARCHES, which is a list of architectures already created - during this debugging session. - - Called e.g. at program startup, when reading a core file, and when reading - a binary file. */ - -static struct gdbarch * -arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) -{ - struct gdbarch_tdep *tdep; - struct gdbarch *gdbarch; - enum arm_abi arm_abi = ARM_ABI_UNKNOWN; - struct arm_abi_handler *abi_handler; - - /* Try to deterimine the ABI of the object we are loading. */ - - if (info.abfd != NULL) - { - switch (bfd_get_flavour (info.abfd)) - { - case bfd_target_elf_flavour: - arm_abi = get_elfosabi (info.abfd); - break; - - case bfd_target_aout_flavour: - if (strcmp (bfd_get_target(info.abfd), "a.out-arm-netbsd") == 0) - arm_abi = ARM_ABI_NETBSD_AOUT; - else - /* Assume it's an old APCS-style ABI. */ - arm_abi = ARM_ABI_APCS; - break; - - case bfd_target_coff_flavour: - /* Assume it's an old APCS-style ABI. */ - /* XXX WinCE? */ - arm_abi = ARM_ABI_APCS; - break; - - default: - /* Not sure what to do here, leave the ABI as unknown. */ - break; - } - } - - /* Find a candidate among extant architectures. */ - for (arches = gdbarch_list_lookup_by_info (arches, &info); - arches != NULL; - arches = gdbarch_list_lookup_by_info (arches->next, &info)) - { - /* Make sure the ABI selection matches. */ - tdep = gdbarch_tdep (arches->gdbarch); - if (tdep && tdep->arm_abi == arm_abi) - return arches->gdbarch; - } - - tdep = xmalloc (sizeof (struct gdbarch_tdep)); - gdbarch = gdbarch_alloc (&info, tdep); - - tdep->arm_abi = arm_abi; - if (arm_abi < ARM_ABI_INVALID) - tdep->abi_name = arm_abi_names[arm_abi]; - else - { - internal_error (__FILE__, __LINE__, "Invalid setting of arm_abi %d", - (int) arm_abi); - tdep->abi_name = ""; - } - - /* This is the way it has always defaulted. */ - tdep->fp_model = ARM_FLOAT_FPA; - - /* Breakpoints. */ - switch (info.byte_order) - { - case BFD_ENDIAN_BIG: - tdep->arm_breakpoint = arm_default_arm_be_breakpoint; - tdep->arm_breakpoint_size = sizeof (arm_default_arm_be_breakpoint); - tdep->thumb_breakpoint = arm_default_thumb_be_breakpoint; - tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_be_breakpoint); - - break; - - case BFD_ENDIAN_LITTLE: - tdep->arm_breakpoint = arm_default_arm_le_breakpoint; - tdep->arm_breakpoint_size = sizeof (arm_default_arm_le_breakpoint); - tdep->thumb_breakpoint = arm_default_thumb_le_breakpoint; - tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_le_breakpoint); - - break; - - default: - internal_error (__FILE__, __LINE__, - "arm_gdbarch_init: bad byte order for float format"); - } - - /* On ARM targets char defaults to unsigned. */ - set_gdbarch_char_signed (gdbarch, 0); - - /* This should be low enough for everything. */ - tdep->lowest_pc = 0x20; - tdep->jb_pc = -1; /* Longjump support not enabled by default. */ - - set_gdbarch_use_generic_dummy_frames (gdbarch, 0); - - /* Call dummy code. */ - set_gdbarch_call_dummy_location (gdbarch, ON_STACK); - set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); - /* We have to give this a value now, even though we will re-set it - during each call to arm_fix_call_dummy. */ - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 8); - set_gdbarch_call_dummy_p (gdbarch, 1); - set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); - - set_gdbarch_call_dummy_words (gdbarch, arm_call_dummy_words); - set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (arm_call_dummy_words)); - set_gdbarch_call_dummy_start_offset (gdbarch, 0); - set_gdbarch_call_dummy_length (gdbarch, 0); - - set_gdbarch_fix_call_dummy (gdbarch, arm_fix_call_dummy); - - set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack); - - set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register); - set_gdbarch_push_arguments (gdbarch, arm_push_arguments); - set_gdbarch_coerce_float_to_double (gdbarch, - standard_coerce_float_to_double); - - /* Frame handling. */ - set_gdbarch_frame_chain_valid (gdbarch, arm_frame_chain_valid); - set_gdbarch_init_extra_frame_info (gdbarch, arm_init_extra_frame_info); - set_gdbarch_read_fp (gdbarch, arm_read_fp); - set_gdbarch_frame_chain (gdbarch, arm_frame_chain); - set_gdbarch_frameless_function_invocation - (gdbarch, arm_frameless_function_invocation); - set_gdbarch_frame_saved_pc (gdbarch, arm_frame_saved_pc); - set_gdbarch_frame_args_address (gdbarch, arm_frame_args_address); - set_gdbarch_frame_locals_address (gdbarch, arm_frame_locals_address); - set_gdbarch_frame_num_args (gdbarch, arm_frame_num_args); - set_gdbarch_frame_args_skip (gdbarch, 0); - set_gdbarch_frame_init_saved_regs (gdbarch, arm_frame_init_saved_regs); - set_gdbarch_push_dummy_frame (gdbarch, arm_push_dummy_frame); - set_gdbarch_pop_frame (gdbarch, arm_pop_frame); - - /* Address manipulation. */ - set_gdbarch_smash_text_address (gdbarch, arm_smash_text_address); - set_gdbarch_addr_bits_remove (gdbarch, arm_addr_bits_remove); - - /* Offset from address of function to start of its code. */ - set_gdbarch_function_start_offset (gdbarch, 0); - - /* Advance PC across function entry code. */ - set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue); - - /* Get the PC when a frame might not be available. */ - set_gdbarch_saved_pc_after_call (gdbarch, arm_saved_pc_after_call); - - /* The stack grows downward. */ - set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - - /* Breakpoint manipulation. */ - set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc); - set_gdbarch_decr_pc_after_break (gdbarch, 0); - - /* Information about registers, etc. */ - set_gdbarch_print_float_info (gdbarch, arm_print_float_info); - set_gdbarch_fp_regnum (gdbarch, ARM_FP_REGNUM); /* ??? */ - set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM); - set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM); - set_gdbarch_register_byte (gdbarch, arm_register_byte); - set_gdbarch_register_bytes (gdbarch, - (NUM_GREGS * INT_REGISTER_RAW_SIZE - + NUM_FREGS * FP_REGISTER_RAW_SIZE - + NUM_SREGS * STATUS_REGISTER_SIZE)); - set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS); - set_gdbarch_register_raw_size (gdbarch, arm_register_raw_size); - set_gdbarch_register_virtual_size (gdbarch, arm_register_virtual_size); - set_gdbarch_max_register_raw_size (gdbarch, FP_REGISTER_RAW_SIZE); - set_gdbarch_max_register_virtual_size (gdbarch, FP_REGISTER_VIRTUAL_SIZE); - set_gdbarch_register_virtual_type (gdbarch, arm_register_type); - - /* Integer registers are 4 bytes. */ - set_gdbarch_register_size (gdbarch, 4); - set_gdbarch_register_name (gdbarch, arm_register_name); - - /* Returning results. */ - set_gdbarch_extract_return_value (gdbarch, arm_extract_return_value); - set_gdbarch_store_return_value (gdbarch, arm_store_return_value); - set_gdbarch_store_struct_return (gdbarch, arm_store_struct_return); - set_gdbarch_use_struct_convention (gdbarch, arm_use_struct_convention); - set_gdbarch_extract_struct_value_address (gdbarch, - arm_extract_struct_value_address); - - /* Single stepping. */ - /* XXX For an RDI target we should ask the target if it can single-step. */ - set_gdbarch_software_single_step (gdbarch, arm_software_single_step); - - /* Minsymbol frobbing. */ - set_gdbarch_elf_make_msymbol_special (gdbarch, arm_elf_make_msymbol_special); - set_gdbarch_coff_make_msymbol_special (gdbarch, - arm_coff_make_msymbol_special); - - /* Hook in the ABI-specific overrides, if they have been registered. */ - if (arm_abi == ARM_ABI_UNKNOWN) - { - /* Don't complain about not knowing the ABI variant if we don't - have an inferior. */ - if (info.abfd) - fprintf_filtered - (gdb_stderr, "GDB doesn't recognize the ABI of the inferior. " - "Attempting to continue with the default ARM settings"); - } - else - { - for (abi_handler = arm_abi_handler_list; abi_handler != NULL; - abi_handler = abi_handler->next) - if (abi_handler->abi == arm_abi) - break; - - if (abi_handler) - abi_handler->init_abi (info, gdbarch); - else - { - /* We assume that if GDB_MULTI_ARCH is less than - GDB_MULTI_ARCH_TM that an ABI variant can be supported by - overriding definitions in this file. */ - if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - fprintf_filtered - (gdb_stderr, - "A handler for the ABI variant \"%s\" is not built into this " - "configuration of GDB. " - "Attempting to continue with the default ARM settings", - arm_abi_names[arm_abi]); - } - } - - /* Now we have tuned the configuration, set a few final things, - based on what the OS ABI has told us. */ - - if (tdep->jb_pc >= 0) - set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target); - - /* Floating point sizes and format. */ - switch (info.byte_order) - { - case BFD_ENDIAN_BIG: - set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big); - set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big); - set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); - - break; - - case BFD_ENDIAN_LITTLE: - set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little); - if (tdep->fp_model == ARM_FLOAT_VFP - || tdep->fp_model == ARM_FLOAT_SOFT_VFP) - { - set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little); - set_gdbarch_long_double_format (gdbarch, - &floatformat_ieee_double_little); - } - else - { - set_gdbarch_double_format - (gdbarch, &floatformat_ieee_double_littlebyte_bigword); - set_gdbarch_long_double_format - (gdbarch, &floatformat_ieee_double_littlebyte_bigword); - } - break; - - default: - internal_error (__FILE__, __LINE__, - "arm_gdbarch_init: bad byte order for float format"); - } - - /* We can't use SIZEOF_FRAME_SAVED_REGS here, since that still - references the old architecture vector, not the one we are - building here. */ - if (prologue_cache.saved_regs != NULL) - xfree (prologue_cache.saved_regs); - - prologue_cache.saved_regs = (CORE_ADDR *) - xcalloc (1, (sizeof (CORE_ADDR) - * (gdbarch_num_regs (gdbarch) + NUM_PSEUDO_REGS))); - - return gdbarch; -} - -static void -arm_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - if (tdep == NULL) - return; - - if (tdep->abi_name != NULL) - fprintf_unfiltered (file, "arm_dump_tdep: ABI = %s\n", tdep->abi_name); - else - internal_error (__FILE__, __LINE__, - "arm_dump_tdep: illegal setting of tdep->arm_abi (%d)", - (int) tdep->arm_abi); - - fprintf_unfiltered (file, "arm_dump_tdep: Lowest pc = 0x%lx", - (unsigned long) tdep->lowest_pc); -} - -static void -arm_init_abi_eabi_v1 (struct gdbarch_info info, - struct gdbarch *gdbarch) -{ - /* Place-holder. */ -} - -static void -arm_init_abi_eabi_v2 (struct gdbarch_info info, - struct gdbarch *gdbarch) -{ - /* Place-holder. */ -} - -static void -arm_init_abi_apcs (struct gdbarch_info info, - struct gdbarch *gdbarch) -{ - /* Place-holder. */ -} - -void -_initialize_arm_tdep (void) -{ - struct ui_file *stb; - long length; - struct cmd_list_element *new_cmd; - const char *setname; - const char *setdesc; - const char **regnames; - int numregs, i, j; - static char *helptext; - - if (GDB_MULTI_ARCH) - gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep); - - /* Register some ABI variants for embedded systems. */ - arm_gdbarch_register_os_abi (ARM_ABI_EABI_V1, arm_init_abi_eabi_v1); - arm_gdbarch_register_os_abi (ARM_ABI_EABI_V2, arm_init_abi_eabi_v2); - arm_gdbarch_register_os_abi (ARM_ABI_APCS, arm_init_abi_apcs); - - tm_print_insn = gdb_print_insn_arm; - - /* Get the number of possible sets of register names defined in opcodes. */ - num_flavor_options = get_arm_regname_num_options (); - - /* Sync the opcode insn printer with our register viewer: */ - parse_arm_disassembler_option ("reg-names-std"); - - /* Begin creating the help text. */ - stb = mem_fileopen (); - fprintf_unfiltered (stb, "Set the disassembly flavor.\n\ -The valid values are:\n"); - - /* Initialize the array that will be passed to add_set_enum_cmd(). */ - valid_flavors = xmalloc ((num_flavor_options + 1) * sizeof (char *)); - for (i = 0; i < num_flavor_options; i++) - { - numregs = get_arm_regnames (i, &setname, &setdesc, ®names); - valid_flavors[i] = setname; - fprintf_unfiltered (stb, "%s - %s\n", setname, - setdesc); - /* Copy the default names (if found) and synchronize disassembler. */ - if (!strcmp (setname, "std")) - { - disassembly_flavor = setname; - current_option = i; - for (j = 0; j < numregs; j++) - arm_register_names[j] = (char *) regnames[j]; - set_arm_regname_option (i); - } - } - /* Mark the end of valid options. */ - valid_flavors[num_flavor_options] = NULL; - - /* Finish the creation of the help text. */ - fprintf_unfiltered (stb, "The default is \"std\"."); - helptext = ui_file_xstrdup (stb, &length); - ui_file_delete (stb); - - /* Add the disassembly-flavor command */ - new_cmd = add_set_enum_cmd ("disassembly-flavor", no_class, - valid_flavors, - &disassembly_flavor, - helptext, - &setlist); - set_cmd_sfunc (new_cmd, set_disassembly_flavor_sfunc); - add_show_from_set (new_cmd, &showlist); - - /* ??? Maybe this should be a boolean. */ - add_show_from_set (add_set_cmd ("apcs32", no_class, - var_zinteger, (char *) &arm_apcs_32, - "Set usage of ARM 32-bit mode.\n", &setlist), - &showlist); - - /* Add the deprecated "othernames" command */ - - add_com ("othernames", class_obscure, arm_othernames, - "Switch to the next set of register names."); - - /* Fill in the prologue_cache fields. */ - prologue_cache.saved_regs = NULL; - prologue_cache.extra_info = (struct frame_extra_info *) - xcalloc (1, sizeof (struct frame_extra_info)); -} diff --git a/contrib/gdb/gdb/coff-solib.c b/contrib/gdb/gdb/coff-solib.c deleted file mode 100644 index 64dca7bbefd..00000000000 --- a/contrib/gdb/gdb/coff-solib.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Handle COFF SVR3 shared libraries for GDB, the GNU Debugger. - Copyright 1993, 1994, 1998, 1999, 2000 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -#include "defs.h" - -#include "frame.h" -#include "bfd.h" -#include "gdbcore.h" -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" - -/* - - GLOBAL FUNCTION - - coff_solib_add -- add a shared library files to the symtab list. We - examine the `.lib' section of the exec file and determine the names of - the shared libraries. - - This function is responsible for discovering those names and - addresses, and saving sufficient information about them to allow - their symbols to be read at a later time. - - SYNOPSIS - - void coff_solib_add (char *arg_string, int from_tty, - struct target_ops *target, int readsyms) - - DESCRIPTION - - */ - -void -coff_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) -{ - asection *libsect; - - if (!readsyms) - return; - - libsect = bfd_get_section_by_name (exec_bfd, ".lib"); - - if (libsect) - { - int libsize; - unsigned char *lib; - struct libent - { - bfd_byte len[4]; - bfd_byte nameoffset[4]; - }; - - libsize = bfd_section_size (exec_bfd, libsect); - - lib = (unsigned char *) alloca (libsize); - - bfd_get_section_contents (exec_bfd, libsect, lib, 0, libsize); - - while (libsize > 0) - { - struct libent *ent; - struct objfile *objfile; - int len, nameoffset; - char *filename; - - ent = (struct libent *) lib; - - len = bfd_get_32 (exec_bfd, ent->len); - - nameoffset = bfd_get_32 (exec_bfd, ent->nameoffset); - - if (len <= 0) - break; - - filename = (char *) ent + nameoffset * 4; - - objfile = symbol_file_add (filename, from_tty, - NULL, /* no offsets */ - 0, /* not mainline */ - OBJF_SHARED); /* flags */ - - libsize -= len * 4; - lib += len * 4; - } - - /* Getting new symbols may change our opinion about what is - frameless. */ - reinit_frame_cache (); - } -} - -/* - - GLOBAL FUNCTION - - coff_solib_create_inferior_hook -- shared library startup support - - SYNOPSIS - - void coff_solib_create_inferior_hook() - - DESCRIPTION - - When gdb starts up the inferior, the kernel maps in the shared - libraries. We get here with the target stopped at it's first - instruction, and the libraries already mapped. At this point, this - function gets called via expansion of the macro - SOLIB_CREATE_INFERIOR_HOOK. - */ - -void -coff_solib_create_inferior_hook (void) -{ - coff_solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); -} diff --git a/contrib/gdb/gdb/coff-solib.h b/contrib/gdb/gdb/coff-solib.h deleted file mode 100644 index 144f36df700..00000000000 --- a/contrib/gdb/gdb/coff-solib.h +++ /dev/null @@ -1,186 +0,0 @@ -/* COFF (SVR3) Shared library declarations for GDB, the GNU Debugger. - Copyright 1992, 1993, 1998, 1999, 2000 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Forward decl's for prototypes */ -struct target_ops; - -/* Called when we free all symtabs, to free the shared library information - as well. */ - -#if 0 -#define CLEAR_SOLIB coff_clear_solib - -extern void coff_clear_solib (void); -#endif - -/* Called to add symbols from a shared library to gdb's symbol table. */ - -#define SOLIB_ADD(filename, from_tty, targ, readsyms) \ - coff_solib_add (filename, from_tty, targ, readsyms) - -extern void coff_solib_add (char *, int, struct target_ops *, int); - -/* Function to be called when the inferior starts up, to discover the names - of shared libraries that are dynamically linked, the base addresses to - which they are linked, and sufficient information to read in their symbols - at a later time. */ - -#define SOLIB_CREATE_INFERIOR_HOOK(PID) coff_solib_create_inferior_hook() - -extern void coff_solib_create_inferior_hook (void); /* solib.c */ - -/* Function to be called to remove the connection between debugger and - dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK. - (This operation does not remove shared library information from - the debugger, as CLEAR_SOLIB does.) - - This functionality is presently not implemented for this target. - */ -#define SOLIB_REMOVE_INFERIOR_HOOK(PID) (0) - -/* This function is called by the "catch load" command. It allows - the debugger to be notified by the dynamic linker when a specified - library file (or any library file, if filename is NULL) is loaded. - - Presently, this functionality is not implemented. - */ -#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \ - error("catch of library loads/unloads not yet implemented on this platform") - -/* This function is called by the "catch unload" command. It allows - the debugger to be notified by the dynamic linker when a specified - library file (or any library file, if filename is NULL) is unloaded. - - Presently, this functionality is not implemented. - */ -#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \ - error("catch of library loads/unloads not yet implemented on this platform") - -/* This function returns TRUE if the dynamic linker has just reported - a load of a library. - - This function must be used only when the inferior has stopped in - the dynamic linker hook, or undefined results are guaranteed. - - Presently, this functionality is not implemented. - */ -/* - #define SOLIB_HAVE_LOAD_EVENT(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_HAVE_LOAD_EVENT(pid) \ -(0) - -/* This function returns a pointer to the string representation of the - pathname of the dynamically-linked library that has just been loaded. - - This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE, - or undefined results are guaranteed. - - This string's contents are only valid immediately after the inferior - has stopped in the dynamic linker hook, and becomes invalid as soon - as the inferior is continued. Clients should make a copy of this - string if they wish to continue the inferior and then access the string. - - Presently, this functionality is not implemented. - */ - -/* - #define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ -(0) - -/* This function returns TRUE if the dynamic linker has just reported - an unload of a library. - - This function must be used only when the inferior has stopped in - the dynamic linker hook, or undefined results are guaranteed. - - Presently, this functionality is not implemented. - */ -/* - #define SOLIB_HAVE_UNLOAD_EVENT(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_HAVE_UNLOAD_EVENT(pid) \ -(0) - -/* This function returns a pointer to the string representation of the - pathname of the dynamically-linked library that has just been unloaded. - - This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE, - or undefined results are guaranteed. - - This string's contents are only valid immediately after the inferior - has stopped in the dynamic linker hook, and becomes invalid as soon - as the inferior is continued. Clients should make a copy of this - string if they wish to continue the inferior and then access the string. - - Presently, this functionality is not implemented. - */ -/* - #define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ -(0) - -/* This function returns TRUE if pc is the address of an instruction that - lies within the dynamic linker (such as the event hook, or the dld - itself). - - This function must be used only when a dynamic linker event has been - caught, and the inferior is being stepped out of the hook, or undefined - results are guaranteed. - - Presently, this functionality is not implemented. - */ - -/* - #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ -(0) - -/* This function must be called when the inferior is killed, and the program - restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard - any symbol tables. - - Presently, this functionality is not implemented. - */ -#define SOLIB_RESTART() \ - (0) - -/* If we can't set a breakpoint, and it's in a shared library, just - disable it. */ - -#if 0 -#define DISABLE_UNSETTABLE_BREAK(addr) coff_solib_address(addr) - -extern int solib_address (CORE_ADDR); /* solib.c */ -#endif diff --git a/contrib/gdb/gdb/core-sol2.c b/contrib/gdb/gdb/core-sol2.c deleted file mode 100644 index e72fc2a3632..00000000000 --- a/contrib/gdb/gdb/core-sol2.c +++ /dev/null @@ -1,196 +0,0 @@ -/* Machine independent support for Solaris 2 core files for GDB. - Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -/* Solaris comes with two flavours of core files, cores generated by - an ELF executable and cores generated by programs that were - run under BCP (the part of Solaris which allows it to run SunOS4 - a.out files). - This file combines the core register fetching from core-regset.c - and sparc-nat.c to be able to read both flavours. */ - -/* for Sparc64 cross Sparc32 */ -#define _SYSCALL32 -#include "defs.h" - -#if defined (__sparcv9) -/* Fails to get included by the Solaris system header files. */ -# include -#endif - -#include -#include -#include -#include -#include -#include -#include "gdb_string.h" -#include "regcache.h" - -#include "inferior.h" -#include "target.h" -#include "command.h" -#include "gdbcore.h" - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); - -/* Fetch registers from core file data pointed to by CORE_REG_SECT. When - WHICH is 0, the the general register set is fetched; when WHICH is - 2, the floating point registers are fetched. CORE_REG_SIZE is used - to validate the size of the data pointed to by CORE_REG_SECT. REG_ADDR - is unused. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR reg_addr) -{ - int i; - - if (which == 0) - { - prgregset_t prgregset; - - if (core_reg_size == sizeof (prgregset_t)) - { - memcpy ((char *) &prgregset, core_reg_sect, sizeof (prgregset)); - supply_gregset (&prgregset); - } -#if defined (HAVE_PRGREGSET32_T) - /* 32-bit corefile, 64-bit debugger. */ - else if (core_reg_size == sizeof (prgregset32_t)) - { - prgreg32_t *core_gregs; - - /* Can't use memcpy here, because the core file contains - 32-bit regs; supply_register expects 64-bit regs. */ - core_gregs = (prgreg32_t *) core_reg_sect; - for (i = 0; i < NPRGREG; i++) - prgregset[i] = core_gregs[i]; - - supply_gregset (&prgregset); - } -#endif /* HAVE_PRGREGSET32_T */ - else if (core_reg_size == sizeof (struct regs)) - { - struct regs *gregs = (struct regs *) core_reg_sect; - - /* G0 *always* holds 0. */ - *(int *) ®isters[REGISTER_BYTE (0)] = 0; - - /* The globals and output registers. */ - memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, - 15 * REGISTER_RAW_SIZE (G1_REGNUM)); - *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps; - *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc; - *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc; - *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y; - - /* My best guess at where to get the locals and input - registers is exactly where they usually are, right above - the stack pointer. If the core dump was caused by a bus error - from blowing away the stack pointer (as is possible) then this - won't work, but it's worth the try. */ - { - int sp; - - sp = *(int *) ®isters[REGISTER_BYTE (SP_REGNUM)]; - if (0 != target_read_memory (sp, - ®isters[REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM))) - { - warning ("couldn't read input and local registers from core file\n"); - } - } - } - else - { - warning ("wrong size gregset struct in core file"); - } - } - else if (which == 2) - { - prfpregset_t prfpregset; - - if (core_reg_size == sizeof (prfpregset_t)) - { - memcpy ((char *) &prfpregset, core_reg_sect, sizeof (prfpregset)); - supply_fpregset (&prfpregset); - } -#if defined (HAVE_PRFPREGSET32_T) - /* 32-bit corefile, 64-bit debugger. */ - else if (core_reg_size == sizeof (prfpregset32_t)) - { - prfpregset32_t *core_fpregset; - - /* Can't use memcpy here, because the core file contains - 32-bit regs; supply_fpregset expects 64-bit regs. */ - - core_fpregset = (prfpregset32_t *) core_reg_sect; - for (i = 0; i < 16; i++) - prfpregset.pr_fr.pr_dregs[i] = core_fpregset->pr_fr.pr_dregs[i]; - while (i < 32) - prfpregset.pr_fr.pr_dregs[i++] = 0; - - prfpregset.pr_fsr = core_fpregset->pr_fsr; - prfpregset.pr_qcnt = core_fpregset->pr_qcnt; - prfpregset.pr_q_entrysize = core_fpregset->pr_q_entrysize; - prfpregset.pr_en = core_fpregset->pr_en; - /* We will not use the pr_q array. */ - - supply_fpregset (&prfpregset); - } -#endif /* HAVE_PRFPREGSET32_T */ - else if (core_reg_size >= sizeof (struct fpu)) - { - struct fpu *fpuregs = (struct fpu *) core_reg_sect; - - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &fpuregs->fpu_fr, - sizeof (fpuregs->fpu_fr)); - memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr, - sizeof (FPU_FSR_TYPE)); - } - else - { - warning ("wrong size fpregset struct in core file"); - } - } -} - - -/* Register that we are able to handle solaris core file formats. */ - -static struct core_fns solaris_core_fns = -{ - bfd_target_elf_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_core_solaris (void) -{ - add_core_fns (&solaris_core_fns); -} diff --git a/contrib/gdb/gdb/fr30-tdep.c b/contrib/gdb/gdb/fr30-tdep.c deleted file mode 100644 index 09f886fed87..00000000000 --- a/contrib/gdb/gdb/fr30-tdep.c +++ /dev/null @@ -1,601 +0,0 @@ -/* Target-dependent code for the Fujitsu FR30. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "obstack.h" -#include "target.h" -#include "value.h" -#include "bfd.h" -#include "gdb_string.h" -#include "gdbcore.h" -#include "symfile.h" -#include "regcache.h" - -/* An expression that tells us whether the function invocation represented - by FI does not have a frame on the stack associated with it. */ -int -fr30_frameless_function_invocation (struct frame_info *fi) -{ - int frameless; - CORE_ADDR func_start, after_prologue; - func_start = (get_pc_function_start ((fi)->pc) + - FUNCTION_START_OFFSET); - after_prologue = func_start; - after_prologue = SKIP_PROLOGUE (after_prologue); - frameless = (after_prologue == func_start); - return frameless; -} - -/* Function: pop_frame - This routine gets called when either the user uses the `return' - command, or the call dummy breakpoint gets hit. */ - -void -fr30_pop_frame (void) -{ - struct frame_info *frame = get_current_frame (); - int regnum; - CORE_ADDR sp = read_register (SP_REGNUM); - - if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - generic_pop_dummy_frame (); - else - { - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - - for (regnum = 0; regnum < NUM_REGS; regnum++) - if (frame->fsr.regs[regnum] != 0) - { - write_register (regnum, - read_memory_unsigned_integer (frame->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum))); - } - write_register (SP_REGNUM, sp + frame->framesize); - } - flush_cached_frames (); -} - - -/* Function: fr30_store_return_value - Put a value where a caller expects to see it. Used by the 'return' - command. */ -void -fr30_store_return_value (struct type *type, - char *valbuf) -{ - /* Here's how the FR30 returns values (gleaned from gcc/config/ - fr30/fr30.h): - - If the return value is 32 bits long or less, it goes in r4. - - If the return value is 64 bits long or less, it goes in r4 (most - significant word) and r5 (least significant word. - - If the function returns a structure, of any size, the caller - passes the function an invisible first argument where the callee - should store the value. But GDB doesn't let you do that anyway. - - If you're returning a value smaller than a word, it's not really - necessary to zero the upper bytes of the register; the caller is - supposed to ignore them. However, the FR30 typically keeps its - values extended to the full register width, so we should emulate - that. */ - - /* The FR30 is big-endian, so if we return a small value (like a - short or a char), we need to position it correctly within the - register. We round the size up to a register boundary, and then - adjust the offset so as to place the value at the right end. */ - int value_size = TYPE_LENGTH (type); - int returned_size = (value_size + FR30_REGSIZE - 1) & ~(FR30_REGSIZE - 1); - int offset = (REGISTER_BYTE (RETVAL_REG) - + (returned_size - value_size)); - char *zeros = alloca (returned_size); - memset (zeros, 0, returned_size); - - write_register_bytes (REGISTER_BYTE (RETVAL_REG), zeros, returned_size); - write_register_bytes (offset, valbuf, value_size); -} - - -/* Function: skip_prologue - Return the address of the first code past the prologue of the function. */ - -CORE_ADDR -fr30_skip_prologue (CORE_ADDR pc) -{ - CORE_ADDR func_addr, func_end; - - /* See what the symbol table says */ - - if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - { - struct symtab_and_line sal; - - sal = find_pc_line (func_addr, 0); - - if (sal.line != 0 && sal.end < func_end) - { - return sal.end; - } - } - -/* Either we didn't find the start of this function (nothing we can do), - or there's no line info, or the line after the prologue is after - the end of the function (there probably isn't a prologue). */ - - return pc; -} - - -/* Function: push_arguments - Setup arguments and RP for a call to the target. First four args - go in FIRST_ARGREG -> LAST_ARGREG, subsequent args go on stack... - Structs are passed by reference. XXX not right now Z.R. - 64 bit quantities (doubles and long longs) may be split between - the regs and the stack. - When calling a function that returns a struct, a pointer to the struct - is passed in as a secret first argument (always in FIRST_ARGREG). - - Stack space for the args has NOT been allocated: that job is up to us. - */ - -CORE_ADDR -fr30_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) -{ - int argreg; - int argnum; - int stack_offset; - struct stack_arg - { - char *val; - int len; - int offset; - }; - struct stack_arg *stack_args = - (struct stack_arg *) alloca (nargs * sizeof (struct stack_arg)); - int nstack_args = 0; - - argreg = FIRST_ARGREG; - - /* the struct_return pointer occupies the first parameter-passing reg */ - if (struct_return) - write_register (argreg++, struct_addr); - - stack_offset = 0; - - /* Process args from left to right. Store as many as allowed in - registers, save the rest to be pushed on the stack */ - for (argnum = 0; argnum < nargs; argnum++) - { - char *val; - struct value *arg = args[argnum]; - struct type *arg_type = check_typedef (VALUE_TYPE (arg)); - struct type *target_type = TYPE_TARGET_TYPE (arg_type); - int len = TYPE_LENGTH (arg_type); - enum type_code typecode = TYPE_CODE (arg_type); - CORE_ADDR regval; - int newarg; - - val = (char *) VALUE_CONTENTS (arg); - - { - /* Copy the argument to general registers or the stack in - register-sized pieces. Large arguments are split between - registers and stack. */ - while (len > 0) - { - if (argreg <= LAST_ARGREG) - { - int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE; - regval = extract_address (val, partial_len); - - /* It's a simple argument being passed in a general - register. */ - write_register (argreg, regval); - argreg++; - len -= partial_len; - val += partial_len; - } - else - { - /* keep for later pushing */ - stack_args[nstack_args].val = val; - stack_args[nstack_args++].len = len; - break; - } - } - } - } - /* now do the real stack pushing, process args right to left */ - while (nstack_args--) - { - sp -= stack_args[nstack_args].len; - write_memory (sp, stack_args[nstack_args].val, - stack_args[nstack_args].len); - } - - /* Return adjusted stack pointer. */ - return sp; -} - -void _initialize_fr30_tdep (void); - -void -_initialize_fr30_tdep (void) -{ - extern int print_insn_fr30 (bfd_vma, disassemble_info *); - tm_print_insn = print_insn_fr30; -} - -/* Function: check_prologue_cache - Check if prologue for this frame's PC has already been scanned. - If it has, copy the relevant information about that prologue and - return non-zero. Otherwise do not copy anything and return zero. - - The information saved in the cache includes: - * the frame register number; - * the size of the stack frame; - * the offsets of saved regs (relative to the old SP); and - * the offset from the stack pointer to the frame pointer - - The cache contains only one entry, since this is adequate - for the typical sequence of prologue scan requests we get. - When performing a backtrace, GDB will usually ask to scan - the same function twice in a row (once to get the frame chain, - and once to fill in the extra frame information). - */ - -static struct frame_info prologue_cache; - -static int -check_prologue_cache (struct frame_info *fi) -{ - int i; - - if (fi->pc == prologue_cache.pc) - { - fi->framereg = prologue_cache.framereg; - fi->framesize = prologue_cache.framesize; - fi->frameoffset = prologue_cache.frameoffset; - for (i = 0; i <= NUM_REGS; i++) - fi->fsr.regs[i] = prologue_cache.fsr.regs[i]; - return 1; - } - else - return 0; -} - - -/* Function: save_prologue_cache - Copy the prologue information from fi to the prologue cache. - */ - -static void -save_prologue_cache (struct frame_info *fi) -{ - int i; - - prologue_cache.pc = fi->pc; - prologue_cache.framereg = fi->framereg; - prologue_cache.framesize = fi->framesize; - prologue_cache.frameoffset = fi->frameoffset; - - for (i = 0; i <= NUM_REGS; i++) - { - prologue_cache.fsr.regs[i] = fi->fsr.regs[i]; - } -} - - -/* Function: scan_prologue - Scan the prologue of the function that contains PC, and record what - we find in PI. PI->fsr must be zeroed by the called. Returns the - pc after the prologue. Note that the addresses saved in pi->fsr - are actually just frame relative (negative offsets from the frame - pointer). This is because we don't know the actual value of the - frame pointer yet. In some circumstances, the frame pointer can't - be determined till after we have scanned the prologue. */ - -static void -fr30_scan_prologue (struct frame_info *fi) -{ - int sp_offset, fp_offset; - CORE_ADDR prologue_start, prologue_end, current_pc; - - /* Check if this function is already in the cache of frame information. */ - if (check_prologue_cache (fi)) - return; - - /* Assume there is no frame until proven otherwise. */ - fi->framereg = SP_REGNUM; - fi->framesize = 0; - fi->frameoffset = 0; - - /* Find the function prologue. If we can't find the function in - the symbol table, peek in the stack frame to find the PC. */ - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) - { - /* Assume the prologue is everything between the first instruction - in the function and the first source line. */ - struct symtab_and_line sal = find_pc_line (prologue_start, 0); - - if (sal.line == 0) /* no line info, use current PC */ - prologue_end = fi->pc; - else if (sal.end < prologue_end) /* next line begins after fn end */ - prologue_end = sal.end; /* (probably means no prologue) */ - } - else - { - /* XXX Z.R. What now??? The following is entirely bogus */ - prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12; - prologue_end = prologue_start + 40; - } - - /* Now search the prologue looking for instructions that set up the - frame pointer, adjust the stack pointer, and save registers. */ - - sp_offset = fp_offset = 0; - for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 2) - { - unsigned int insn; - - insn = read_memory_unsigned_integer (current_pc, 2); - - if ((insn & 0xfe00) == 0x8e00) /* stm0 or stm1 */ - { - int reg, mask = insn & 0xff; - - /* scan in one sweep - create virtual 16-bit mask from either insn's mask */ - if ((insn & 0x0100) == 0) - { - mask <<= 8; /* stm0 - move to upper byte in virtual mask */ - } - - /* Calculate offsets of saved registers (to be turned later into addresses). */ - for (reg = R4_REGNUM; reg <= R11_REGNUM; reg++) - if (mask & (1 << (15 - reg))) - { - sp_offset -= 4; - fi->fsr.regs[reg] = sp_offset; - } - } - else if ((insn & 0xfff0) == 0x1700) /* st rx,@-r15 */ - { - int reg = insn & 0xf; - - sp_offset -= 4; - fi->fsr.regs[reg] = sp_offset; - } - else if ((insn & 0xff00) == 0x0f00) /* enter */ - { - fp_offset = fi->fsr.regs[FP_REGNUM] = sp_offset - 4; - sp_offset -= 4 * (insn & 0xff); - fi->framereg = FP_REGNUM; - } - else if (insn == 0x1781) /* st rp,@-sp */ - { - sp_offset -= 4; - fi->fsr.regs[RP_REGNUM] = sp_offset; - } - else if (insn == 0x170e) /* st fp,@-sp */ - { - sp_offset -= 4; - fi->fsr.regs[FP_REGNUM] = sp_offset; - } - else if (insn == 0x8bfe) /* mov sp,fp */ - { - fi->framereg = FP_REGNUM; - } - else if ((insn & 0xff00) == 0xa300) /* addsp xx */ - { - sp_offset += 4 * (signed char) (insn & 0xff); - } - else if ((insn & 0xff0f) == 0x9b00 && /* ldi:20 xx,r0 */ - read_memory_unsigned_integer (current_pc + 4, 2) - == 0xac0f) /* sub r0,sp */ - { - /* large stack adjustment */ - sp_offset -= (((insn & 0xf0) << 12) | read_memory_unsigned_integer (current_pc + 2, 2)); - current_pc += 4; - } - else if (insn == 0x9f80 && /* ldi:32 xx,r0 */ - read_memory_unsigned_integer (current_pc + 6, 2) - == 0xac0f) /* sub r0,sp */ - { - /* large stack adjustment */ - sp_offset -= - (read_memory_unsigned_integer (current_pc + 2, 2) << 16 | - read_memory_unsigned_integer (current_pc + 4, 2)); - current_pc += 6; - } - } - - /* The frame size is just the negative of the offset (from the original SP) - of the last thing thing we pushed on the stack. The frame offset is - [new FP] - [new SP]. */ - fi->framesize = -sp_offset; - fi->frameoffset = fp_offset - sp_offset; - - save_prologue_cache (fi); -} - -/* Function: init_extra_frame_info - Setup the frame's frame pointer, pc, and frame addresses for saved - registers. Most of the work is done in scan_prologue(). - - Note that when we are called for the last frame (currently active frame), - that fi->pc and fi->frame will already be setup. However, fi->frame will - be valid only if this routine uses FP. For previous frames, fi-frame will - always be correct (since that is derived from fr30_frame_chain ()). - - We can be called with the PC in the call dummy under two circumstances. - First, during normal backtracing, second, while figuring out the frame - pointer just prior to calling the target function (see run_stack_dummy). */ - -void -fr30_init_extra_frame_info (struct frame_info *fi) -{ - int reg; - - if (fi->next) - fi->pc = FRAME_SAVED_PC (fi->next); - - memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); - - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - { - /* We need to setup fi->frame here because run_stack_dummy gets it wrong - by assuming it's always FP. */ - fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); - fi->framesize = 0; - fi->frameoffset = 0; - return; - } - fr30_scan_prologue (fi); - - if (!fi->next) /* this is the innermost frame? */ - fi->frame = read_register (fi->framereg); - else - /* not the innermost frame */ - /* If we have an FP, the callee saved it. */ - if (fi->framereg == FP_REGNUM) - if (fi->next->fsr.regs[fi->framereg] != 0) - fi->frame = read_memory_integer (fi->next->fsr.regs[fi->framereg], 4); - - /* Calculate actual addresses of saved registers using offsets determined - by fr30_scan_prologue. */ - for (reg = 0; reg < NUM_REGS; reg++) - if (fi->fsr.regs[reg] != 0) - { - fi->fsr.regs[reg] += fi->frame + fi->framesize - fi->frameoffset; - } -} - -/* Function: find_callers_reg - Find REGNUM on the stack. Otherwise, it's in an active register. - One thing we might want to do here is to check REGNUM against the - clobber mask, and somehow flag it as invalid if it isn't saved on - the stack somewhere. This would provide a graceful failure mode - when trying to get the value of caller-saves registers for an inner - frame. */ - -CORE_ADDR -fr30_find_callers_reg (struct frame_info *fi, int regnum) -{ - for (; fi; fi = fi->next) - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, regnum); - else if (fi->fsr.regs[regnum] != 0) - return read_memory_unsigned_integer (fi->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum)); - - return read_register (regnum); -} - - -/* Function: frame_chain - Figure out the frame prior to FI. Unfortunately, this involves - scanning the prologue of the caller, which will also be done - shortly by fr30_init_extra_frame_info. For the dummy frame, we - just return the stack pointer that was in use at the time the - function call was made. */ - - -CORE_ADDR -fr30_frame_chain (struct frame_info *fi) -{ - CORE_ADDR fn_start, callers_pc, fp; - struct frame_info caller_fi; - int framereg; - - /* is this a dummy frame? */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return fi->frame; /* dummy frame same as caller's frame */ - - /* is caller-of-this a dummy frame? */ - callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ - fp = fr30_find_callers_reg (fi, FP_REGNUM); - if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) - return fp; /* dummy frame's frame may bear no relation to ours */ - - if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; /* in _start fn, don't chain further */ - - framereg = fi->framereg; - - /* If the caller is the startup code, we're at the end of the chain. */ - if (find_pc_partial_function (callers_pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; - - memset (&caller_fi, 0, sizeof (caller_fi)); - caller_fi.pc = callers_pc; - fr30_scan_prologue (&caller_fi); - framereg = caller_fi.framereg; - - /* If the caller used a frame register, return its value. - Otherwise, return the caller's stack pointer. */ - if (framereg == FP_REGNUM) - return fr30_find_callers_reg (fi, framereg); - else - return fi->frame + fi->framesize; -} - -/* Function: frame_saved_pc - Find the caller of this frame. We do this by seeing if RP_REGNUM - is saved in the stack anywhere, otherwise we get it from the - registers. If the inner frame is a dummy frame, return its PC - instead of RP, because that's where "caller" of the dummy-frame - will be found. */ - -CORE_ADDR -fr30_frame_saved_pc (struct frame_info *fi) -{ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); - else - return fr30_find_callers_reg (fi, RP_REGNUM); -} - -/* Function: fix_call_dummy - Pokes the callee function's address into the CALL_DUMMY assembly stub. - Assumes that the CALL_DUMMY looks like this: - jarl , r31 - trap - */ - -int -fr30_fix_call_dummy (char *dummy, CORE_ADDR sp, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - long offset24; - - offset24 = (long) fun - (long) entry_point_address (); - offset24 &= 0x3fffff; - offset24 |= 0xff800000; /* jarl , r31 */ - - store_unsigned_integer ((unsigned int *) &dummy[2], 2, offset24 & 0xffff); - store_unsigned_integer ((unsigned int *) &dummy[0], 2, offset24 >> 16); - return 0; -} diff --git a/contrib/gdb/gdb/i386-stub.c b/contrib/gdb/gdb/i386-stub.c deleted file mode 100644 index 1251567e912..00000000000 --- a/contrib/gdb/gdb/i386-stub.c +++ /dev/null @@ -1,952 +0,0 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for 386 by Jim Kingdon, Cygnus Support. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific 386 vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses it's own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include -#include - -/************************************************************************ - * - * external low-level support routines - */ - -extern void putDebugChar(); /* write a single character */ -extern int getDebugChar(); /* read and return a single char */ -extern void exceptionHandler(); /* assign an exception handler */ - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 400 - -static char initialized; /* boolean flag. != 0 means we've been initialized */ - -int remote_debug; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ - -static const char hexchars[]="0123456789abcdef"; - -/* Number of registers. */ -#define NUMREGS 16 - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) - -enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - PC /* also known as eip */, - PS /* also known as eflags */, - CS, SS, DS, ES, FS, GS}; - -/* - * these should not be static cuz they can be used outside this module - */ -int registers[NUMREGS]; - -#define STACKSIZE 10000 -int remcomStack[STACKSIZE/sizeof(int)]; -static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - -/*************************** ASSEMBLY CODE MACROS *************************/ -/* */ - -extern void -return_to_prog (); - -/* Restore the program's registers (including the stack pointer, which - means we get the right stack and don't have to worry about popping our - return address and any stack frames and so on) and return. */ -asm(".text"); -asm(".globl _return_to_prog"); -asm("_return_to_prog:"); -asm(" movw _registers+44, %ss"); -asm(" movl _registers+16, %esp"); -asm(" movl _registers+4, %ecx"); -asm(" movl _registers+8, %edx"); -asm(" movl _registers+12, %ebx"); -asm(" movl _registers+20, %ebp"); -asm(" movl _registers+24, %esi"); -asm(" movl _registers+28, %edi"); -asm(" movw _registers+48, %ds"); -asm(" movw _registers+52, %es"); -asm(" movw _registers+56, %fs"); -asm(" movw _registers+60, %gs"); -asm(" movl _registers+36, %eax"); -asm(" pushl %eax"); /* saved eflags */ -asm(" movl _registers+40, %eax"); -asm(" pushl %eax"); /* saved cs */ -asm(" movl _registers+32, %eax"); -asm(" pushl %eax"); /* saved eip */ -asm(" movl _registers, %eax"); -/* use iret to restore pc and flags together so - that trace flag works right. */ -asm(" iret"); - -#define BREAKPOINT() asm(" int $3"); - -/* Put the error code here just in case the user cares. */ -int gdb_i386errcode; -/* Likewise, the vector number here (since GDB only gets the signal - number through the usual means, and that's not very specific). */ -int gdb_i386vector = -1; - -/* GDB stores segment registers in 32-bit words (that's just the way - m-i386v.h is written). So zero the appropriate areas in registers. */ -#define SAVE_REGISTERS1() \ - asm ("movl %eax, _registers"); \ - asm ("movl %ecx, _registers+4"); \ - asm ("movl %edx, _registers+8"); \ - asm ("movl %ebx, _registers+12"); \ - asm ("movl %ebp, _registers+20"); \ - asm ("movl %esi, _registers+24"); \ - asm ("movl %edi, _registers+28"); \ - asm ("movw $0, %ax"); \ - asm ("movw %ds, _registers+48"); \ - asm ("movw %ax, _registers+50"); \ - asm ("movw %es, _registers+52"); \ - asm ("movw %ax, _registers+54"); \ - asm ("movw %fs, _registers+56"); \ - asm ("movw %ax, _registers+58"); \ - asm ("movw %gs, _registers+60"); \ - asm ("movw %ax, _registers+62"); -#define SAVE_ERRCODE() \ - asm ("popl %ebx"); \ - asm ("movl %ebx, _gdb_i386errcode"); -#define SAVE_REGISTERS2() \ - asm ("popl %ebx"); /* old eip */ \ - asm ("movl %ebx, _registers+32"); \ - asm ("popl %ebx"); /* old cs */ \ - asm ("movl %ebx, _registers+40"); \ - asm ("movw %ax, _registers+42"); \ - asm ("popl %ebx"); /* old eflags */ \ - asm ("movl %ebx, _registers+36"); \ - /* Now that we've done the pops, we can save the stack pointer."); */ \ - asm ("movw %ss, _registers+44"); \ - asm ("movw %ax, _registers+46"); \ - asm ("movl %esp, _registers+16"); - -/* See if mem_fault_routine is set, if so just IRET to that address. */ -#define CHECK_FAULT() \ - asm ("cmpl $0, _mem_fault_routine"); \ - asm ("jne mem_fault"); - -asm (".text"); -asm ("mem_fault:"); -/* OK to clobber temp registers; we're just going to end up in set_mem_err. */ -/* Pop error code from the stack and save it. */ -asm (" popl %eax"); -asm (" movl %eax, _gdb_i386errcode"); - -asm (" popl %eax"); /* eip */ -/* We don't want to return there, we want to return to the function - pointed to by mem_fault_routine instead. */ -asm (" movl _mem_fault_routine, %eax"); -asm (" popl %ecx"); /* cs (low 16 bits; junk in hi 16 bits). */ -asm (" popl %edx"); /* eflags */ - -/* Remove this stack frame; when we do the iret, we will be going to - the start of a function, so we want the stack to look just like it - would after a "call" instruction. */ -asm (" leave"); - -/* Push the stuff that iret wants. */ -asm (" pushl %edx"); /* eflags */ -asm (" pushl %ecx"); /* cs */ -asm (" pushl %eax"); /* eip */ - -/* Zero mem_fault_routine. */ -asm (" movl $0, %eax"); -asm (" movl %eax, _mem_fault_routine"); - -asm ("iret"); - -#define CALL_HOOK() asm("call _remcomHandler"); - -/* This function is called when a i386 exception occurs. It saves - * all the cpu regs in the _registers array, munges the stack a bit, - * and invokes an exception handler (remcom_handler). - * - * stack on entry: stack on exit: - * old eflags vector number - * old cs (zero-filled to 32 bits) - * old eip - * - */ -extern void _catchException3(); -asm(".text"); -asm(".globl __catchException3"); -asm("__catchException3:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $3"); -CALL_HOOK(); - -/* Same thing for exception 1. */ -extern void _catchException1(); -asm(".text"); -asm(".globl __catchException1"); -asm("__catchException1:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $1"); -CALL_HOOK(); - -/* Same thing for exception 0. */ -extern void _catchException0(); -asm(".text"); -asm(".globl __catchException0"); -asm("__catchException0:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $0"); -CALL_HOOK(); - -/* Same thing for exception 4. */ -extern void _catchException4(); -asm(".text"); -asm(".globl __catchException4"); -asm("__catchException4:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $4"); -CALL_HOOK(); - -/* Same thing for exception 5. */ -extern void _catchException5(); -asm(".text"); -asm(".globl __catchException5"); -asm("__catchException5:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $5"); -CALL_HOOK(); - -/* Same thing for exception 6. */ -extern void _catchException6(); -asm(".text"); -asm(".globl __catchException6"); -asm("__catchException6:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $6"); -CALL_HOOK(); - -/* Same thing for exception 7. */ -extern void _catchException7(); -asm(".text"); -asm(".globl __catchException7"); -asm("__catchException7:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $7"); -CALL_HOOK(); - -/* Same thing for exception 8. */ -extern void _catchException8(); -asm(".text"); -asm(".globl __catchException8"); -asm("__catchException8:"); -SAVE_REGISTERS1(); -SAVE_ERRCODE(); -SAVE_REGISTERS2(); -asm ("pushl $8"); -CALL_HOOK(); - -/* Same thing for exception 9. */ -extern void _catchException9(); -asm(".text"); -asm(".globl __catchException9"); -asm("__catchException9:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $9"); -CALL_HOOK(); - -/* Same thing for exception 10. */ -extern void _catchException10(); -asm(".text"); -asm(".globl __catchException10"); -asm("__catchException10:"); -SAVE_REGISTERS1(); -SAVE_ERRCODE(); -SAVE_REGISTERS2(); -asm ("pushl $10"); -CALL_HOOK(); - -/* Same thing for exception 12. */ -extern void _catchException12(); -asm(".text"); -asm(".globl __catchException12"); -asm("__catchException12:"); -SAVE_REGISTERS1(); -SAVE_ERRCODE(); -SAVE_REGISTERS2(); -asm ("pushl $12"); -CALL_HOOK(); - -/* Same thing for exception 16. */ -extern void _catchException16(); -asm(".text"); -asm(".globl __catchException16"); -asm("__catchException16:"); -SAVE_REGISTERS1(); -SAVE_REGISTERS2(); -asm ("pushl $16"); -CALL_HOOK(); - -/* For 13, 11, and 14 we have to deal with the CHECK_FAULT stuff. */ - -/* Same thing for exception 13. */ -extern void _catchException13 (); -asm (".text"); -asm (".globl __catchException13"); -asm ("__catchException13:"); -CHECK_FAULT(); -SAVE_REGISTERS1(); -SAVE_ERRCODE(); -SAVE_REGISTERS2(); -asm ("pushl $13"); -CALL_HOOK(); - -/* Same thing for exception 11. */ -extern void _catchException11 (); -asm (".text"); -asm (".globl __catchException11"); -asm ("__catchException11:"); -CHECK_FAULT(); -SAVE_REGISTERS1(); -SAVE_ERRCODE(); -SAVE_REGISTERS2(); -asm ("pushl $11"); -CALL_HOOK(); - -/* Same thing for exception 14. */ -extern void _catchException14 (); -asm (".text"); -asm (".globl __catchException14"); -asm ("__catchException14:"); -CHECK_FAULT(); -SAVE_REGISTERS1(); -SAVE_ERRCODE(); -SAVE_REGISTERS2(); -asm ("pushl $14"); -CALL_HOOK(); - -/* - * remcomHandler is a front end for handle_exception. It moves the - * stack pointer into an area reserved for debugger use. - */ -asm("_remcomHandler:"); -asm(" popl %eax"); /* pop off return address */ -asm(" popl %eax"); /* get the exception number */ -asm(" movl _stackPtr, %esp"); /* move to remcom stack area */ -asm(" pushl %eax"); /* push exception onto stack */ -asm(" call _handle_exception"); /* this never returns */ - -void -_returnFromException () -{ - return_to_prog (); -} - -int -hex (ch) - char ch; -{ - if ((ch >= 'a') && (ch <= 'f')) - return (ch - 'a' + 10); - if ((ch >= '0') && (ch <= '9')) - return (ch - '0'); - if ((ch >= 'A') && (ch <= 'F')) - return (ch - 'A' + 10); - return (-1); -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -/* scan for the sequence $# */ - -unsigned char * -getpacket (void) -{ - unsigned char *buffer = &remcomInBuffer[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - char ch; - - while (1) - { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - - retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) - { - ch = getDebugChar (); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - { - if (remote_debug) - { - fprintf (stderr, - "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", - checksum, xmitcsum, buffer); - } - putDebugChar ('-'); /* failed checksum */ - } - else - { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } - } - } -} - -/* send the packet in buffer. */ - -void -putpacket (unsigned char *buffer) -{ - unsigned char checksum; - int count; - char ch; - - /* $#. */ - do - { - putDebugChar ('$'); - checksum = 0; - count = 0; - - while (ch = buffer[count]) - { - putDebugChar (ch); - checksum += ch; - count += 1; - } - - putDebugChar ('#'); - putDebugChar (hexchars[checksum >> 4]); - putDebugChar (hexchars[checksum % 16]); - - } - while (getDebugChar () != '+'); -} - -void -debug_error (format, parm) - char *format; - char *parm; -{ - if (remote_debug) - fprintf (stderr, format, parm); -} - -/* Address of a routine to RTE to if we get a memory fault. */ -static void (*volatile mem_fault_routine) () = NULL; - -/* Indicate to caller of mem2hex or hex2mem that there has been an - error. */ -static volatile int mem_err = 0; - -void -set_mem_err (void) -{ - mem_err = 1; -} - -/* These are separate functions so that they are so short and sweet - that the compiler won't save any registers (if there is a fault - to mem_fault, they won't get restored, so there better not be any - saved). */ -int -get_char (char *addr) -{ - return *addr; -} - -void -set_char (char *addr, int val) -{ - *addr = val; -} - -/* convert the memory pointed to by mem into hex, placing result in buf */ -/* return a pointer to the last char put in buf (null) */ -/* If MAY_FAULT is non-zero, then we should set mem_err in response to - a fault; if zero treat a fault like any other fault in the stub. */ -char * -mem2hex (mem, buf, count, may_fault) - char *mem; - char *buf; - int count; - int may_fault; -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i = 0; i < count; i++) - { - ch = get_char (mem++); - if (may_fault && mem_err) - return (buf); - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - if (may_fault) - mem_fault_routine = NULL; - return (buf); -} - -/* convert the hex array pointed to by buf into binary to be placed in mem */ -/* return a pointer to the character AFTER the last byte written */ -char * -hex2mem (buf, mem, count, may_fault) - char *buf; - char *mem; - int count; - int may_fault; -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i = 0; i < count; i++) - { - ch = hex (*buf++) << 4; - ch = ch + hex (*buf++); - set_char (mem++, ch); - if (may_fault && mem_err) - return (mem); - } - if (may_fault) - mem_fault_routine = NULL; - return (mem); -} - -/* this function takes the 386 exception vector and attempts to - translate this number into a unix compatible signal value */ -int -computeSignal (int exceptionVector) -{ - int sigval; - switch (exceptionVector) - { - case 0: - sigval = 8; - break; /* divide by zero */ - case 1: - sigval = 5; - break; /* debug exception */ - case 3: - sigval = 5; - break; /* breakpoint */ - case 4: - sigval = 16; - break; /* into instruction (overflow) */ - case 5: - sigval = 16; - break; /* bound instruction */ - case 6: - sigval = 4; - break; /* Invalid opcode */ - case 7: - sigval = 8; - break; /* coprocessor not available */ - case 8: - sigval = 7; - break; /* double fault */ - case 9: - sigval = 11; - break; /* coprocessor segment overrun */ - case 10: - sigval = 11; - break; /* Invalid TSS */ - case 11: - sigval = 11; - break; /* Segment not present */ - case 12: - sigval = 11; - break; /* stack exception */ - case 13: - sigval = 11; - break; /* general protection */ - case 14: - sigval = 11; - break; /* page fault */ - case 16: - sigval = 7; - break; /* coprocessor error */ - default: - sigval = 7; /* "software generated" */ - } - return (sigval); -} - -/**********************************************/ -/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ -/* RETURN NUMBER OF CHARS PROCESSED */ -/**********************************************/ -int -hexToInt (char **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - - while (**ptr) - { - hexValue = hex (**ptr); - if (hexValue >= 0) - { - *intValue = (*intValue << 4) | hexValue; - numChars++; - } - else - break; - - (*ptr)++; - } - - return (numChars); -} - -/* - * This function does all command procesing for interfacing to gdb. - */ -void -handle_exception (int exceptionVector) -{ - int sigval, stepping; - int addr, length; - char *ptr; - int newPC; - - gdb_i386vector = exceptionVector; - - if (remote_debug) - { - printf ("vector=%d, sr=0x%x, pc=0x%x\n", - exceptionVector, registers[PS], registers[PC]); - } - - /* reply to host that an exception has occurred */ - sigval = computeSignal (exceptionVector); - - ptr = remcomOutBuffer; - - *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[ESP]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[ESP], ptr, 4, 0); /* SP */ - *ptr++ = ';'; - - *ptr++ = hexchars[EBP]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[EBP], ptr, 4, 0); /* FP */ - *ptr++ = ';'; - - *ptr++ = hexchars[PC]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); /* PC */ - *ptr++ = ';'; - - *ptr = '\0' - - putpacket (remcomOutBuffer); - - stepping = 0; - - while (1 == 1) - { - remcomOutBuffer[0] = 0; - ptr = getpacket (); - - switch (*ptr++) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - case 'd': - remote_debug = !(remote_debug); /* toggle debug flag */ - break; - case 'g': /* return the value of the CPU registers */ - mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0); - break; - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem (ptr, (char *) registers, NUMREGBYTES, 0); - strcpy (remcomOutBuffer, "OK"); - break; - case 'P': /* set the value of a single CPU register - return OK */ - { - int regno; - - if (hexToInt (&ptr, ®no) && *ptr++ == '=') - if (regno >= 0 && regno < NUMREGS) - { - hex2mem (ptr, (char *) ®isters[regno], 4, 0); - strcpy (remcomOutBuffer, "OK"); - break; - } - - strcpy (remcomOutBuffer, "E01"); - break; - } - - /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - case 'm': - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - if (hexToInt (&ptr, &addr)) - if (*(ptr++) == ',') - if (hexToInt (&ptr, &length)) - { - ptr = 0; - mem_err = 0; - mem2hex ((char *) addr, remcomOutBuffer, length, 1); - if (mem_err) - { - strcpy (remcomOutBuffer, "E03"); - debug_error ("memory fault"); - } - } - - if (ptr) - { - strcpy (remcomOutBuffer, "E01"); - } - break; - - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - case 'M': - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - if (hexToInt (&ptr, &addr)) - if (*(ptr++) == ',') - if (hexToInt (&ptr, &length)) - if (*(ptr++) == ':') - { - mem_err = 0; - hex2mem (ptr, (char *) addr, length, 1); - - if (mem_err) - { - strcpy (remcomOutBuffer, "E03"); - debug_error ("memory fault"); - } - else - { - strcpy (remcomOutBuffer, "OK"); - } - - ptr = 0; - } - if (ptr) - { - strcpy (remcomOutBuffer, "E02"); - } - break; - - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 's': - stepping = 1; - case 'c': - /* try to read optional parameter, pc unchanged if no parm */ - if (hexToInt (&ptr, &addr)) - registers[PC] = addr; - - newPC = registers[PC]; - - /* clear the trace bit */ - registers[PS] &= 0xfffffeff; - - /* set the trace bit if we're stepping */ - if (stepping) - registers[PS] |= 0x100; - - _returnFromException (); /* this is a jump */ - break; - - /* kill the program */ - case 'k': /* do nothing */ -#if 0 - /* Huh? This doesn't look like "nothing". - m68k-stub.c and sparc-stub.c don't have it. */ - BREAKPOINT (); -#endif - break; - } /* switch */ - - /* reply to the request */ - putpacket (remcomOutBuffer); - } -} - -/* this function is used to set up exception handlers for tracing and - breakpoints */ -void -set_debug_traps (void) -{ - stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1]; - - exceptionHandler (0, _catchException0); - exceptionHandler (1, _catchException1); - exceptionHandler (3, _catchException3); - exceptionHandler (4, _catchException4); - exceptionHandler (5, _catchException5); - exceptionHandler (6, _catchException6); - exceptionHandler (7, _catchException7); - exceptionHandler (8, _catchException8); - exceptionHandler (9, _catchException9); - exceptionHandler (10, _catchException10); - exceptionHandler (11, _catchException11); - exceptionHandler (12, _catchException12); - exceptionHandler (13, _catchException13); - exceptionHandler (14, _catchException14); - exceptionHandler (16, _catchException16); - - initialized = 1; -} - -/* This function will generate a breakpoint exception. It is used at the - beginning of a program to sync up with a debugger and can be used - otherwise as a quick means to stop program execution and "break" into - the debugger. */ - -void -breakpoint (void) -{ - if (initialized) - BREAKPOINT (); -} diff --git a/contrib/gdb/gdb/i386aix-nat.c b/contrib/gdb/gdb/i386aix-nat.c deleted file mode 100644 index 2d8d7b9c710..00000000000 --- a/contrib/gdb/gdb/i386aix-nat.c +++ /dev/null @@ -1,377 +0,0 @@ -/* Intel 386 native support. - Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, - 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "language.h" -#include "gdbcore.h" -#include "regcache.h" - -#ifdef USG -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include "gdb_stat.h" - -#include -#include - -/* Does AIX define this in ? */ -extern int errno; - -#ifdef HAVE_SYS_REG_H -#include -#endif - -#include "floatformat.h" - -#include "target.h" - -static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); - - -/* this table must line up with REGISTER_NAMES in tm-i386v.h */ -/* symbols like 'EAX' come from */ -static int regmap[] = -{ - EAX, ECX, EDX, EBX, - USP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS, -}; - -/* blockend is the value of u.u_ar0, and points to the - * place where GS is stored - */ - -int -i386_register_u_addr (int blockend, int regnum) -{ -#if 0 - /* this will be needed if fp registers are reinstated */ - /* for now, you can look at them with 'info float' - * sys5 wont let you change them with ptrace anyway - */ - if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) - { - int ubase, fpstate; - struct user u; - ubase = blockend + 4 * (SS + 1) - KSTKSZ; - fpstate = ubase + ((char *) &u.u_fpstate - (char *) &u); - return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM)); - } - else -#endif - return (blockend + 4 * regmap[regnum]); - -} - -/* The code below only work on the aix ps/2 (i386-ibm-aix) - - * mtranle@paris - Sat Apr 11 10:34:12 1992 - */ - -struct env387 -{ - unsigned short control; - unsigned short r0; - unsigned short status; - unsigned short r1; - unsigned short tag; - unsigned short r2; - unsigned long eip; - unsigned short code_seg; - unsigned short opcode; - unsigned long operand; - unsigned short operand_seg; - unsigned short r3; - unsigned char regs[8][10]; -}; - -static -print_387_status (unsigned short status, struct env387 *ep) -{ - int i; - int bothstatus; - int top; - int fpreg; - unsigned char *p; - - bothstatus = ((status != 0) && (ep->status != 0)); - if (status != 0) - { - if (bothstatus) - printf_unfiltered ("u: "); - print_387_status_word (status); - } - - if (ep->status != 0) - { - if (bothstatus) - printf_unfiltered ("e: "); - print_387_status_word (ep->status); - } - - print_387_control_word (ep->control); - printf_unfiltered ("last exception: "); - printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode)); - printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg)); - printf_unfiltered ("%s; ", local_hex_string (ep->eip)); - printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg)); - printf_unfiltered (":%s\n", local_hex_string (ep->operand)); - - top = ((ep->status >> 11) & 7); - - printf_unfiltered ("regno tag msb lsb value\n"); - for (fpreg = 7; fpreg >= 0; fpreg--) - { - double val; - - printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); - - switch ((ep->tag >> ((7 - fpreg) * 2)) & 3) - { - case 0: - printf_unfiltered ("valid "); - break; - case 1: - printf_unfiltered ("zero "); - break; - case 2: - printf_unfiltered ("trap "); - break; - case 3: - printf_unfiltered ("empty "); - break; - } - for (i = 9; i >= 0; i--) - printf_unfiltered ("%02x", ep->regs[fpreg][i]); - - i387_to_double ((char *) ep->regs[fpreg], (char *) &val); - printf_unfiltered (" %#g\n", val); - } -} - -static struct env387 core_env387; - -void -i386_float_info (void) -{ - struct env387 fps; - int fpsaved = 0; - /* We need to reverse the order of the registers. Apparently AIX stores - the highest-numbered ones first. */ - struct env387 fps_fixed; - int i; - - if (! ptid_equal (inferior_ptid, null_ptid)) - { - char buf[10]; - unsigned short status; - - ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf, - offsetof (struct env387, status)); - memcpy (&status, buf, sizeof (status)); - fpsaved = status; - } - else - { - if ((fpsaved = core_env387.status) != 0) - memcpy (&fps, &core_env387, sizeof (fps)); - } - - if (fpsaved == 0) - { - printf_unfiltered ("no floating point status saved\n"); - return; - } - - if (! ptid_equal (inferior_ptid, null_ptid)) - { - int offset; - for (offset = 0; offset < sizeof (fps); offset += 10) - { - char buf[10]; - ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf, offset); - memcpy ((char *) &fps.control + offset, buf, - MIN (10, sizeof (fps) - offset)); - } - } - fps_fixed = fps; - for (i = 0; i < 8; ++i) - memcpy (fps_fixed.regs[i], fps.regs[7 - i], 10); - print_387_status (0, &fps_fixed); -} - -/* Fetch one register. */ -static void -fetch_register (int regno) -{ - char buf[MAX_REGISTER_RAW_SIZE]; - if (regno < FP0_REGNUM) - *(int *) buf = ptrace (PT_READ_GPR, PIDGET (inferior_ptid), - PT_REG (regmap[regno]), 0, 0); - else - ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf, - (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs)); - supply_register (regno, buf); -} - -void -fetch_inferior_registers (int regno) -{ - if (regno < 0) - for (regno = 0; regno < NUM_REGS; regno++) - fetch_register (regno); - else - fetch_register (regno); -} - -/* store one register */ -static void -store_register (int regno) -{ - char buf[80]; - errno = 0; - if (regno < FP0_REGNUM) - ptrace (PT_WRITE_GPR, PIDGET (inferior_ptid), PT_REG (regmap[regno]), - *(int *) ®isters[REGISTER_BYTE (regno)], 0); - else - ptrace (PT_WRITE_FPR, PIDGET (inferior_ptid), - ®isters[REGISTER_BYTE (regno)], - (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs)); - - if (errno != 0) - { - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ -void -store_inferior_registers (int regno) -{ - if (regno < 0) - for (regno = 0; regno < NUM_REGS; regno++) - store_register (regno); - else - store_register (regno); -} - -#ifndef CD_AX /* defined in sys/i386/coredump.h */ -#define CD_AX 0 -#define CD_BX 1 -#define CD_CX 2 -#define CD_DX 3 -#define CD_SI 4 -#define CD_DI 5 -#define CD_BP 6 -#define CD_SP 7 -#define CD_FL 8 -#define CD_IP 9 -#define CD_CS 10 -#define CD_DS 11 -#define CD_ES 12 -#define CD_FS 13 -#define CD_GS 14 -#define CD_SS 15 -#endif - -/* - * The order here in core_regmap[] has to be the same as in - * regmap[] above. - */ -static int core_regmap[] = -{ - CD_AX, CD_CX, CD_DX, CD_BX, - CD_SP, CD_BP, CD_SI, CD_DI, - CD_IP, CD_FL, CD_CS, CD_SS, - CD_DS, CD_ES, CD_FS, CD_GS, -}; - -/* Provide registers to GDB from a core file. - - CORE_REG_SECT points to an array of bytes, which were obtained from - a core file which BFD thinks might contain register contents. - CORE_REG_SIZE is its size. - - WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set - 2 --- the floating-point register set - - REG_ADDR isn't used. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) -{ - - if (which == 0) - { - /* Integer registers */ - -#define cd_regs(n) ((int *)core_reg_sect)[n] -#define regs(n) *((int *) ®isters[REGISTER_BYTE (n)]) - - int i; - for (i = 0; i < FP0_REGNUM; i++) - regs (i) = cd_regs (core_regmap[i]); - } - else if (which == 2) - { - /* Floating point registers */ - - if (core_reg_size >= sizeof (core_env387)) - memcpy (&core_env387, core_reg_sect, core_reg_size); - else - fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n"); - } -} - - -/* Register that we are able to handle i386aix core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns i386aix_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_core_i386aix (void) -{ - add_core_fns (&i386aix_core_fns); -} diff --git a/contrib/gdb/gdb/i386ly-tdep.c b/contrib/gdb/gdb/i386ly-tdep.c deleted file mode 100644 index 92b544deabd..00000000000 --- a/contrib/gdb/gdb/i386ly-tdep.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Target-dependent code for Intel 386 running LynxOS. - Copyright 1993, 1996, 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "regcache.h" - -/* Return the PC of the caller from the call frame. Assumes the subr prologue - has already been executed, and the frame pointer setup. If this is the - outermost frame, we check to see if we are in a system call by examining the - previous instruction. If so, then the return PC is actually at SP+4 because - system calls use a different calling sequence. */ - -CORE_ADDR -i386lynx_saved_pc_after_call (struct frame_info *frame) -{ - char opcode[7]; - static const unsigned char call_inst[] = - {0x9a, 0, 0, 0, 0, 8, 0}; /* lcall 0x8,0x0 */ - - read_memory (frame->pc - 7, opcode, 7); - if (memcmp (opcode, call_inst, 7) == 0) - return read_memory_integer (read_register (SP_REGNUM) + 4, 4); - - return read_memory_integer (read_register (SP_REGNUM), 4); -} diff --git a/contrib/gdb/gdb/i386m3-nat.c b/contrib/gdb/gdb/i386m3-nat.c deleted file mode 100644 index 8fbd1e8e81c..00000000000 --- a/contrib/gdb/gdb/i386m3-nat.c +++ /dev/null @@ -1,426 +0,0 @@ -/* Low level interface to I386 running mach 3.0. - Copyright 1992, 1993, 1994, 1996, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "floatformat.h" -#include "regcache.h" - -#include - -#include -#include -#include -#include - -/* Hmmm... Should this not be here? - * Now for i386_float_info() target_has_execution - */ -#include - -/* This mess is duplicated in bfd/i386mach3.h - - * This is an ugly way to hack around the incorrect - * definition of UPAGES in i386/machparam.h. - * - * The definition should specify the size reserved - * for "struct user" in core files in PAGES, - * but instead it gives it in 512-byte core-clicks - * for i386 and i860. - */ -#include -#if UPAGES == 16 -#define UAREA_SIZE ctob(UPAGES) -#elif UPAGES == 2 -#define UAREA_SIZE (NBPG*UPAGES) -#else -FIXME ! !UPAGES is neither 2 nor 16 -#endif - -/* @@@ Should move print_387_status() to i387-tdep.c */ -extern void print_387_control_word (); /* i387-tdep.h */ -extern void print_387_status_word (); - -#define private static - - -/* Find offsets to thread states at compile time. - * If your compiler does not grok this, calculate offsets - * offsets yourself and use them (or get a compatible compiler :-) - */ - -#define REG_OFFSET(reg) (int)(&((struct i386_thread_state *)0)->reg) - -/* at reg_offset[i] is the offset to the i386_thread_state - * location where the gdb registers[i] is stored. - */ - -static int reg_offset[] = -{ - REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx), - REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi), - REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss), - REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs) -}; - -#define REG_ADDRESS(state,regnum) ((char *)(state)+reg_offset[regnum]) - -/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM - * Caller knows that the regs handled in one transaction are of same size. - */ -#define FETCH_REGS(state, regnum, count) \ - memcpy (®isters[REGISTER_BYTE (regnum)], \ - REG_ADDRESS (state, regnum), \ - count*REGISTER_SIZE) - -/* Store COUNT contiguous registers to thread STATE starting from REGNUM */ -#define STORE_REGS(state, regnum, count) \ - memcpy (REG_ADDRESS (state, regnum), \ - ®isters[REGISTER_BYTE (regnum)], \ - count*REGISTER_SIZE) - -/* - * Fetch inferiors registers for gdb. - * REGNO specifies which (as gdb views it) register, -1 for all. - */ - -void -fetch_inferior_registers (int regno) -{ - kern_return_t ret; - thread_state_data_t state; - unsigned int stateCnt = i386_THREAD_STATE_COUNT; - int index; - - if (!MACH_PORT_VALID (current_thread)) - error ("fetch inferior registers: Invalid thread"); - - if (must_suspend_thread) - setup_thread (current_thread, 1); - - ret = thread_get_state (current_thread, - i386_THREAD_STATE, - state, - &stateCnt); - - if (ret != KERN_SUCCESS) - warning ("fetch_inferior_registers: %s ", - mach_error_string (ret)); -#if 0 - /* It may be more effective to store validate all of them, - * since we fetched them all anyway - */ - else if (regno != -1) - supply_register (regno, (char *) state + reg_offset[regno]); -#endif - else - { - for (index = 0; index < NUM_REGS; index++) - supply_register (index, (char *) state + reg_offset[index]); - } - - if (must_suspend_thread) - setup_thread (current_thread, 0); -} - -/* Store our register values back into the inferior. - * If REGNO is -1, do this for all registers. - * Otherwise, REGNO specifies which register - * - * On mach3 all registers are always saved in one call. - */ -void -store_inferior_registers (int regno) -{ - kern_return_t ret; - thread_state_data_t state; - unsigned int stateCnt = i386_THREAD_STATE_COUNT; - register int index; - - if (!MACH_PORT_VALID (current_thread)) - error ("store inferior registers: Invalid thread"); - - if (must_suspend_thread) - setup_thread (current_thread, 1); - - /* Fetch the state of the current thread */ - ret = thread_get_state (current_thread, - i386_THREAD_STATE, - state, - &stateCnt); - - if (ret != KERN_SUCCESS) - { - warning ("store_inferior_registers (get): %s", - mach_error_string (ret)); - if (must_suspend_thread) - setup_thread (current_thread, 0); - return; - } - - /* move gdb's registers to thread's state - - * Since we save all registers anyway, save the ones - * that gdb thinks are valid (e.g. ignore the regno - * parameter) - */ -#if 0 - if (regno != -1) - STORE_REGS (state, regno, 1); - else -#endif - { - for (index = 0; index < NUM_REGS; index++) - STORE_REGS (state, index, 1); - } - - /* Write gdb's current view of register to the thread - */ - ret = thread_set_state (current_thread, - i386_THREAD_STATE, - state, - i386_THREAD_STATE_COUNT); - - if (ret != KERN_SUCCESS) - warning ("store_inferior_registers (set): %s", - mach_error_string (ret)); - - if (must_suspend_thread) - setup_thread (current_thread, 0); -} - - - -/* Return the address in the core dump or inferior of register REGNO. - * BLOCKEND should be the address of the end of the UPAGES area read - * in memory, but it's not? - * - * Currently our UX server dumps the whole thread state to the - * core file. If your UX does something else, adapt the routine - * below to return the offset to the given register. - * - * Called by core-aout.c(fetch_core_registers) - */ - -CORE_ADDR -register_addr (int regno, CORE_ADDR blockend) -{ - CORE_ADDR addr; - - if (regno < 0 || regno >= NUM_REGS) - error ("Invalid register number %d.", regno); - - /* UAREA_SIZE == 8 kB in i386 */ - addr = (unsigned int) REG_ADDRESS (UAREA_SIZE - sizeof (struct i386_thread_state), regno); - - return addr; -} - -/* jtv@hut.fi: I copied and modified this 387 code from - * gdb/i386-xdep.c. Modifications for Mach 3.0. - * - * i387 status dumper. See also i387-tdep.c - */ -struct env387 -{ - unsigned short control; - unsigned short r0; - unsigned short status; - unsigned short r1; - unsigned short tag; - unsigned short r2; - unsigned long eip; - unsigned short code_seg; - unsigned short opcode; - unsigned long operand; - unsigned short operand_seg; - unsigned short r3; - unsigned char regs[8][10]; -}; -/* This routine is machine independent? - * Should move it to i387-tdep.c but you need to export struct env387 - */ -private -print_387_status (unsigned short status, struct env387 *ep) -{ - int i; - int bothstatus; - int top; - int fpreg; - unsigned char *p; - - bothstatus = ((status != 0) && (ep->status != 0)); - if (status != 0) - { - if (bothstatus) - printf_unfiltered ("u: "); - print_387_status_word (status); - } - - if (ep->status != 0) - { - if (bothstatus) - printf_unfiltered ("e: "); - print_387_status_word (ep->status); - } - - print_387_control_word (ep->control); - printf_unfiltered ("last exception: "); - printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode)); - printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg)); - printf_unfiltered ("%s; ", local_hex_string (ep->eip)); - printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg)); - printf_unfiltered (":%s\n", local_hex_string (ep->operand)); - - top = (ep->status >> 11) & 7; - - printf_unfiltered ("regno tag msb lsb value\n"); - for (fpreg = 7; fpreg >= 0; fpreg--) - { - double val; - - printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); - - switch ((ep->tag >> (fpreg * 2)) & 3) - { - case 0: - printf_unfiltered ("valid "); - break; - case 1: - printf_unfiltered ("zero "); - break; - case 2: - printf_unfiltered ("trap "); - break; - case 3: - printf_unfiltered ("empty "); - break; - } - for (i = 9; i >= 0; i--) - printf_unfiltered ("%02x", ep->regs[fpreg][i]); - - floatformat_to_double (&floatformat_i387_ext, (char *) ep->regs[fpreg], - &val); - printf_unfiltered (" %g\n", val); - } - if (ep->r0) - printf_unfiltered ("warning: reserved0 is %s\n", local_hex_string (ep->r0)); - if (ep->r1) - printf_unfiltered ("warning: reserved1 is %s\n", local_hex_string (ep->r1)); - if (ep->r2) - printf_unfiltered ("warning: reserved2 is %s\n", local_hex_string (ep->r2)); - if (ep->r3) - printf_unfiltered ("warning: reserved3 is %s\n", local_hex_string (ep->r3)); -} - -/* - * values that go into fp_kind (from ) - */ -#define FP_NO 0 /* no fp chip, no emulator (no fp support) */ -#define FP_SW 1 /* no fp chip, using software emulator */ -#define FP_HW 2 /* chip present bit */ -#define FP_287 2 /* 80287 chip present */ -#define FP_387 3 /* 80387 chip present */ - -typedef struct fpstate -{ -#if 1 - unsigned char state[FP_STATE_BYTES]; /* "hardware" state */ -#else - struct env387 state; /* Actually this */ -#endif - int status; /* Duplicate status */ -} - *fpstate_t; - -/* Mach 3 specific routines. - */ -private boolean_t -get_i387_state (struct fpstate *fstate) -{ - kern_return_t ret; - thread_state_data_t state; - unsigned int fsCnt = i386_FLOAT_STATE_COUNT; - struct i386_float_state *fsp; - - ret = thread_get_state (current_thread, - i386_FLOAT_STATE, - state, - &fsCnt); - - if (ret != KERN_SUCCESS) - { - warning ("Can not get live floating point state: %s", - mach_error_string (ret)); - return FALSE; - } - - fsp = (struct i386_float_state *) state; - /* The 387 chip (also 486 counts) or a software emulator? */ - if (!fsp->initialized || (fsp->fpkind != FP_387 && fsp->fpkind != FP_SW)) - return FALSE; - - /* Clear the target then copy thread's float state there. - Make a copy of the status word, for some reason? - */ - memset (fstate, 0, sizeof (struct fpstate)); - - fstate->status = fsp->exc_status; - - memcpy (fstate->state, (char *) &fsp->hw_state, FP_STATE_BYTES); - - return TRUE; -} - -private boolean_t -get_i387_core_state (struct fpstate *fstate) -{ - /* Not implemented yet. Core files do not contain float state. */ - return FALSE; -} - -/* - * This is called by "info float" command - */ -void -i386_mach3_float_info (void) -{ - char buf[sizeof (struct fpstate) + 2 * sizeof (int)]; - boolean_t valid = FALSE; - fpstate_t fps; - - if (target_has_execution) - valid = get_i387_state (buf); -#if 0 - else if (WE HAVE CORE FILE) /* @@@@ Core files not supported */ - valid = get_i387_core_state (buf); -#endif - - if (!valid) - { - warning ("no floating point status saved"); - return; - } - - fps = (fpstate_t) buf; - - print_387_status (fps->status, (struct env387 *) fps->state); -} diff --git a/contrib/gdb/gdb/i386mach-nat.c b/contrib/gdb/gdb/i386mach-nat.c deleted file mode 100644 index 6d4980be4c6..00000000000 --- a/contrib/gdb/gdb/i386mach-nat.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Native dependent code for Mach 386's for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000, - 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "gdbcore.h" -#include "regcache.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include "gdb_stat.h" -#include - -static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); - -void -fetch_inferior_registers (int regno) -{ - struct regs inferior_registers; - struct fp_state inferior_fp_registers; - - registers_fetched (); - - ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers); - ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fp_registers); - - memcpy (registers, &inferior_registers, sizeof inferior_registers); - - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], - inferior_fp_registers.f_st, - sizeof inferior_fp_registers.f_st); - memcpy (®isters[REGISTER_BYTE (FPC_REGNUM)], - &inferior_fp_registers.f_ctrl, - sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st); -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (int regno) -{ - struct regs inferior_registers; - struct fp_state inferior_fp_registers; - - memcpy (&inferior_registers, registers, 20 * 4); - - memcpy (inferior_fp_registers.f_st, ®isters[REGISTER_BYTE (FP0_REGNUM)], - sizeof inferior_fp_registers.f_st); - memcpy (&inferior_fp_registers.f_ctrl, - ®isters[REGISTER_BYTE (FPC_REGNUM)], - sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st); - -#ifdef PTRACE_FP_BUG - if (regno == FP_REGNUM || regno == -1) - /* Storing the frame pointer requires a gross hack, in which an - instruction that moves eax into ebp gets single-stepped. */ - { - int stack = inferior_registers.r_reg[SP_REGNUM]; - int stuff = ptrace (PTRACE_PEEKDATA, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) stack); - int reg = inferior_registers.r_reg[EAX]; - inferior_registers.r_reg[EAX] = - inferior_registers.r_reg[FP_REGNUM]; - ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers); - ptrace (PTRACE_POKEDATA, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) stack, 0xc589); - ptrace (PTRACE_SINGLESTEP, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) stack, 0); - wait (0); - ptrace (PTRACE_POKEDATA, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) stack, stuff); - inferior_registers.r_reg[EAX] = reg; - } -#endif - ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers); - ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fp_registers); -} - - - -/* Provide registers to GDB from a core file. - - CORE_REG_SECT points to an array of bytes, which were obtained from - a core file which BFD thinks might contain register contents. - CORE_REG_SIZE is its size. - - WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set - 2 --- the floating-point register set - - REG_ADDR isn't used. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) -{ - int val; - - switch (which) - { - case 0: - case 1: - memcpy (registers, core_reg_sect, core_reg_size); - break; - - case 2: - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], - core_reg_sect, - core_reg_size); /* FIXME, probably bogus */ -#ifdef FPC_REGNUM - memcpy (®isters[REGISTER_BYTE (FPC_REGNUM)], - &corestr.c_fpu.f_fpstatus.f_ctrl, - sizeof corestr.c_fpu.f_fpstatus - - sizeof corestr.c_fpu.f_fpstatus.f_st); -#endif - break; - } -} - - -/* Register that we are able to handle i386mach core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns i386mach_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_core_i386mach (void) -{ - add_core_fns (&i386mach_core_fns); -} diff --git a/contrib/gdb/gdb/i386v-nat.c b/contrib/gdb/gdb/i386v-nat.c deleted file mode 100644 index 672ddfbf808..00000000000 --- a/contrib/gdb/gdb/i386v-nat.c +++ /dev/null @@ -1,289 +0,0 @@ -/* Intel 386 native support for SYSV systems (pre-SVR4). - - Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2002 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" - -#ifdef HAVE_PTRACE_H -#include -#else -#ifdef HAVE_SYS_PTRACE_H -#include -#endif -#endif - -#include "frame.h" -#include "inferior.h" -#include "language.h" -#include "gdbcore.h" - -#ifdef USG -#include -#endif - -#include -#include -#include -#include -#include -#include - - -/* FIXME: 1998-10-21/jsm: The following used to be just "#include - ", but the the Linux kernel (version 2.1.x) and - glibc 2.0.x are not in sync; including will result - in an error. With luck, these losers will get their act together - and we can trash this hack in the near future. */ - -#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS -#ifdef HAVE_ASM_DEBUGREG_H -#include -#else -#include -#endif -#endif - -#include -#include "gdb_stat.h" - -#ifdef HAVE_SYS_REG_H -#include -#endif - -#include "floatformat.h" - -#include "target.h" - - -/* this table must line up with REGISTER_NAMES in tm-i386v.h */ -/* symbols like 'EAX' come from */ -static int regmap[] = -{ - EAX, ECX, EDX, EBX, - UESP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS, -}; - -/* blockend is the value of u.u_ar0, and points to the - * place where GS is stored - */ - -int -i386_register_u_addr (int blockend, int regnum) -{ - struct user u; - int fpstate; - int ubase; - - ubase = blockend; - /* FIXME: Should have better way to test floating point range */ - if (regnum >= FP0_REGNUM && regnum <= (FP0_REGNUM + 7)) - { -#ifdef KSTKSZ /* SCO, and others? */ - ubase += 4 * (SS + 1) - KSTKSZ; - fpstate = ubase + ((char *) &u.u_fps.u_fpstate - (char *) &u); - return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM)); -#else - fpstate = ubase + ((char *) &u.i387.st_space - (char *) &u); - return (fpstate + 10 * (regnum - FP0_REGNUM)); -#endif - } - else - { - return (ubase + 4 * regmap[regnum]); - } - -} - -int -kernel_u_size (void) -{ - return (sizeof (struct user)); -} - -#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS - -#if !defined (offsetof) -#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) -#endif - -/* Record the value of the debug control register. */ -static int debug_control_mirror; - -/* Record which address associates with which register. */ -static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1]; - -static int -i386_insert_aligned_watchpoint (int, CORE_ADDR, CORE_ADDR, int, int); - -static int -i386_insert_nonaligned_watchpoint (int, CORE_ADDR, CORE_ADDR, int, int); - -/* Insert a watchpoint. */ - -int -i386_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw) -{ - return i386_insert_aligned_watchpoint (pid, addr, addr, len, rw); -} - -static int -i386_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, - int len, int rw) -{ - int i; - int read_write_bits, len_bits; - int free_debug_register; - int register_number; - - /* Look for a free debug register. */ - for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) - { - if (address_lookup[i - DR_FIRSTADDR] == 0) - break; - } - - /* No more debug registers! */ - if (i > DR_LASTADDR) - return -1; - - read_write_bits = (rw & 1) ? DR_RW_READ : DR_RW_WRITE; - - if (len == 1) - len_bits = DR_LEN_1; - else if (len == 2) - { - if (addr % 2) - return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); - len_bits = DR_LEN_2; - } - - else if (len == 4) - { - if (addr % 4) - return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); - len_bits = DR_LEN_4; - } - else - return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); - - free_debug_register = i; - register_number = free_debug_register - DR_FIRSTADDR; - debug_control_mirror |= - ((read_write_bits | len_bits) - << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * register_number)); - debug_control_mirror |= - (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * register_number)); - debug_control_mirror |= DR_LOCAL_SLOWDOWN; - debug_control_mirror &= ~DR_CONTROL_RESERVED; - - ptrace (6, pid, offsetof (struct user, u_debugreg[DR_CONTROL]), - debug_control_mirror); - ptrace (6, pid, offsetof (struct user, u_debugreg[free_debug_register]), - addr); - - /* Record where we came from. */ - address_lookup[register_number] = addr; - return 0; -} - -static int -i386_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, - int len, int rw) -{ - int align; - int size; - int rv; - - static int size_try_array[4][4] = - { - { 1, 1, 1, 1 }, /* trying size one */ - { 2, 1, 2, 1 }, /* trying size two */ - { 2, 1, 2, 1 }, /* trying size three */ - { 4, 1, 2, 1 } /* trying size four */ - }; - - rv = 0; - while (len > 0) - { - align = addr % 4; - /* Four is the maximum length for 386. */ - size = size_try_array[len > 4 ? 3 : len - 1][align]; - - rv = i386_insert_aligned_watchpoint (pid, waddr, addr, size, rw); - if (rv) - { - i386_remove_watchpoint (pid, waddr, size); - return rv; - } - addr += size; - len -= size; - } - return rv; -} - -/* Remove a watchpoint. */ - -int -i386_remove_watchpoint (int pid, CORE_ADDR addr, int len) -{ - int i; - int register_number; - - for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) - { - register_number = i - DR_FIRSTADDR; - if (address_lookup[register_number] == addr) - { - debug_control_mirror &= - ~(1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * register_number)); - address_lookup[register_number] = 0; - } - } - ptrace (6, pid, offsetof (struct user, u_debugreg[DR_CONTROL]), - debug_control_mirror); - ptrace (6, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0); - - return 0; -} - -/* Check if stopped by a watchpoint. */ - -CORE_ADDR -i386_stopped_by_watchpoint (int pid) -{ - int i; - int status; - - status = ptrace (3, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0); - ptrace (6, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0); - - for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) - { - if (status & (1 << (i - DR_FIRSTADDR))) - return address_lookup[i - DR_FIRSTADDR]; - } - - return 0; -} - -#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */ diff --git a/contrib/gdb/gdb/i386v4-nat.c b/contrib/gdb/gdb/i386v4-nat.c deleted file mode 100644 index 33dbde89ac6..00000000000 --- a/contrib/gdb/gdb/i386v4-nat.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Native-dependent code for SVR4 Unix running on i386's, for GDB. - Copyright 1988, 1989, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "value.h" -#include "inferior.h" -#include "regcache.h" - -#ifdef HAVE_SYS_REG_H -#include -#endif -#include "i387-nat.h" - - -#ifdef HAVE_SYS_PROCFS_H - -#include - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* The /proc interface divides the target machine's register set up into - two different sets, the general register set (gregset) and the floating - point register set (fpregset). For each set, there is an ioctl to get - the current register set and another ioctl to set the current values. - - The actual structure passed through the ioctl interface is, of course, - naturally machine dependent, and is different for each set of registers. - For the i386 for example, the general register set is typically defined - by: - - typedef int gregset_t[19]; (in ) - - #define GS 0 (in ) - #define FS 1 - ... - #define UESP 17 - #define SS 18 - - and the floating point set by: - - typedef struct fpregset - { - union - { - struct fpchip_state // fp extension state // - { - int state[27]; // 287/387 saved state // - int status; // status word saved at exception // - } fpchip_state; - struct fp_emul_space // for emulators // - { - char fp_emul[246]; - char fp_epad[2]; - } fp_emul_space; - int f_fpregs[62]; // union of the above // - } fp_reg_set; - long f_wregs[33]; // saved weitek state // - } fpregset_t; - - These routines provide the packing and unpacking of gregset_t and - fpregset_t formatted data. - - */ - -#ifdef HAVE_GREGSET_T - -/* This is a duplicate of the table in i386-xdep.c. */ - -static int regmap[] = -{ - EAX, ECX, EDX, EBX, - UESP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS, -}; - -/* Prototypes for local functions */ - -void fill_gregset (gregset_t *, int); - -void supply_gregset (gregset_t *); - -void supply_fpregset (fpregset_t *); - -void fill_fpregset (fpregset_t *, int); - - -/* FIXME: These routine absolutely depends upon (NUM_REGS - NUM_FREGS) - being less than or equal to the number of registers that can be stored - in a gregset_t. Note that with the current scheme there will typically - be more registers actually stored in a gregset_t that what we know - about. This is bogus and should be fixed. */ - -/* Given a pointer to a general register set in /proc format (gregset_t *), - unpack the register contents and supply them as gdb's idea of the current - register values. */ - -void -supply_gregset (gregset_t *gregsetp) -{ - register int regi; - register greg_t *regp = (greg_t *) gregsetp; - extern int regmap[]; - - for (regi = 0; regi < (NUM_REGS - NUM_FREGS); regi++) - { - supply_register (regi, (char *) (regp + regmap[regi])); - } -} - -void -fill_gregset (gregset_t *gregsetp, int regno) -{ - int regi; - register greg_t *regp = (greg_t *) gregsetp; - extern int regmap[]; - - for (regi = 0; regi < (NUM_REGS - NUM_FREGS); regi++) - { - if ((regno == -1) || (regno == regi)) - { - *(regp + regmap[regi]) = *(int *) ®isters[REGISTER_BYTE (regi)]; - } - } -} - -#endif /* HAVE_GREGSET_T */ - -#if defined (HAVE_FPREGSET_T) - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), unpack the register contents and supply them as gdb's - idea of the current floating point register values. */ - -/* FIXME: Assumes that fpregsetp contains an i387 FSAVE area. */ -#if !defined(FPREGSET_FSAVE_OFFSET) -#define FPREGSET_FSAVE_OFFSET 0 -#endif - -void -supply_fpregset (fpregset_t *fpregsetp) -{ - if (NUM_FREGS == 0) - return; - - i387_supply_fsave ((char *) fpregsetp + FPREGSET_FSAVE_OFFSET); -} - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), update the register specified by REGNO from gdb's idea - of the current floating point register set. If REGNO is -1, update - them all. */ - -void -fill_fpregset (fpregset_t *fpregsetp, int regno) -{ - if (NUM_FREGS == 0) - return; - - i387_fill_fsave ((char *) fpregsetp + FPREGSET_FSAVE_OFFSET, regno); -} - -#endif /* defined (HAVE_FPREGSET_T) */ - -#endif /* HAVE_SYS_PROCFS_H */ diff --git a/contrib/gdb/gdb/m3-nat.c b/contrib/gdb/gdb/m3-nat.c deleted file mode 100644 index 320cbf8e0ce..00000000000 --- a/contrib/gdb/gdb/m3-nat.c +++ /dev/null @@ -1,4565 +0,0 @@ -/* Interface GDB to Mach 3.0 operating systems. - (Most) Mach 3.0 related routines live in this file. - - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* - * Author: Jukka Virtanen - * Computing Centre - * Helsinki University of Technology - * Finland - * - * Thanks to my friends who helped with ideas and testing: - * - * Johannes Helander, Antti Louko, Tero Mononen, - * jvh@cs.hut.fi alo@hut.fi tmo@cs.hut.fi - * - * Tero Kivinen and Eamonn McManus - * kivinen@cs.hut.fi emcmanus@gr.osf.org - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defs.h" -#include "inferior.h" -#include "symtab.h" -#include "value.h" -#include "language.h" -#include "target.h" -#include "gdb_wait.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "regcache.h" - -#if 0 -#include -#else -#define MACH_TYPE_TASK 1 -#define MACH_TYPE_THREAD 2 -#endif - -/* Included only for signal names and NSIG - - * note: There are many problems in signal handling with - * gdb in Mach 3.0 in general. - */ -#include -#define SIG_UNKNOWN 0 /* Exception that has no matching unix signal */ - -#include - -/* This is what a cproc looks like. This is here partly because - cthread_internals.h is not a header we can just #include, partly with - an eye towards perhaps getting this to work with cross-debugging - someday. Best solution is if CMU publishes a real interface to this - stuff. */ -#define CPROC_NEXT_OFFSET 0 -#define CPROC_NEXT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) -#define CPROC_INCARNATION_OFFSET (CPROC_NEXT_OFFSET + CPROC_NEXT_SIZE) -#define CPROC_INCARNATION_SIZE (sizeof (cthread_t)) -#define CPROC_LIST_OFFSET (CPROC_INCARNATION_OFFSET + CPROC_INCARNATION_SIZE) -#define CPROC_LIST_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) -#define CPROC_WAIT_OFFSET (CPROC_LIST_OFFSET + CPROC_LIST_SIZE) -#define CPROC_WAIT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) -#define CPROC_REPLY_OFFSET (CPROC_WAIT_OFFSET + CPROC_WAIT_SIZE) -#define CPROC_REPLY_SIZE (sizeof (mach_port_t)) -#define CPROC_CONTEXT_OFFSET (CPROC_REPLY_OFFSET + CPROC_REPLY_SIZE) -#define CPROC_CONTEXT_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_LOCK_OFFSET (CPROC_CONTEXT_OFFSET + CPROC_CONTEXT_SIZE) -#define CPROC_LOCK_SIZE (sizeof (spin_lock_t)) -#define CPROC_STATE_OFFSET (CPROC_LOCK_OFFSET + CPROC_LOCK_SIZE) -#define CPROC_STATE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_WIRED_OFFSET (CPROC_STATE_OFFSET + CPROC_STATE_SIZE) -#define CPROC_WIRED_SIZE (sizeof (mach_port_t)) -#define CPROC_BUSY_OFFSET (CPROC_WIRED_OFFSET + CPROC_WIRED_SIZE) -#define CPROC_BUSY_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_MSG_OFFSET (CPROC_BUSY_OFFSET + CPROC_BUSY_SIZE) -#define CPROC_MSG_SIZE (sizeof (mach_msg_header_t)) -#define CPROC_BASE_OFFSET (CPROC_MSG_OFFSET + CPROC_MSG_SIZE) -#define CPROC_BASE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_SIZE_OFFSET (CPROC_BASE_OFFSET + CPROC_BASE_SIZE) -#define CPROC_SIZE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_SIZE (CPROC_SIZE_OFFSET + CPROC_SIZE_SIZE) - -/* Values for the state field in the cproc. */ -#define CPROC_RUNNING 0 -#define CPROC_SWITCHING 1 -#define CPROC_BLOCKED 2 -#define CPROC_CONDWAIT 4 - -/* For cproc and kernel thread mapping */ -typedef struct gdb_thread - { - mach_port_t name; - CORE_ADDR sp; - CORE_ADDR pc; - CORE_ADDR fp; - boolean_t in_emulator; - int slotid; - - /* This is for the mthreads list. It points to the cproc list. - Perhaps the two lists should be merged (or perhaps it was a mistake - to make them both use a struct gdb_thread). */ - struct gdb_thread *cproc; - - /* These are for the cproc list, which is linked through the next field - of the struct gdb_thread. */ - char raw_cproc[CPROC_SIZE]; - /* The cthread which is pointed to by the incarnation field from the - cproc. This points to the copy we've read into GDB. */ - cthread_t cthread; - /* Point back to the mthreads list. */ - int reverse_map; - struct gdb_thread *next; - } - *gdb_thread_t; - -/* - * Actions for Mach exceptions. - * - * sigmap field maps the exception to corresponding Unix signal. - * - * I do not know how to map the exception to unix signal - * if SIG_UNKNOWN is specified. - */ - -struct exception_list - { - char *name; - boolean_t forward; - boolean_t print; - int sigmap; - } -exception_map[] = -{ - { - "not_mach3_exception", FALSE, TRUE, SIG_UNKNOWN - } - , - { - "EXC_BAD_ACCESS", FALSE, TRUE, SIGSEGV - } - , - { - "EXC_BAD_INSTRUCTION", FALSE, TRUE, SIGILL - } - , - { - "EXC_ARITHMETIC", FALSE, TRUE, SIGFPE - } - , - { - "EXC_EMULATION", FALSE, TRUE, SIGEMT - } - , /* ??? */ - { - "EXC_SOFTWARE", FALSE, TRUE, SIG_UNKNOWN - } - , - { - "EXC_BREAKPOINT", FALSE, FALSE, SIGTRAP - } -}; - -/* Mach exception table size */ -int max_exception = sizeof (exception_map) / sizeof (struct exception_list) - 1; - -#define MAX_EXCEPTION max_exception - -WAITTYPE wait_status; - -/* If you define this, intercepted bsd server calls will be - * dumped while waiting the inferior to EXEC the correct - * program - */ -/* #define DUMP_SYSCALL /* debugging interceptor */ - -/* xx_debug() outputs messages if this is nonzero. - * If > 1, DUMP_SYSCALL will dump message contents. - */ -int debug_level = 0; - -/* "Temporary" debug stuff */ -void -xx_debug (char *fmt, int a, int b, int c) -{ - if (debug_level) - warning (fmt, a, b, c); -} - -/* This is in libmach.a */ -extern mach_port_t name_server_port; - -/* Set in catch_exception_raise */ -int stop_exception, stop_code, stop_subcode; -int stopped_in_exception; - -/* Thread that was the active thread when we stopped */ -thread_t stop_thread = MACH_PORT_NULL; - -char *hostname = ""; - -/* Set when task is attached or created */ -boolean_t emulator_present = FALSE; - -task_t inferior_task; -thread_t current_thread; - -/* Exception ports for inferior task */ -mach_port_t inferior_exception_port = MACH_PORT_NULL; -mach_port_t inferior_old_exception_port = MACH_PORT_NULL; - -/* task exceptions and notifications */ -mach_port_t inferior_wait_port_set = MACH_PORT_NULL; -mach_port_t our_notify_port = MACH_PORT_NULL; - -/* This is "inferior_wait_port_set" when not single stepping, and - * "singlestepped_thread_port" when we are single stepping. - * - * This is protected by a cleanup function: discard_single_step() - */ -mach_port_t currently_waiting_for = MACH_PORT_NULL; - -/* A port for external messages to gdb. - * External in the meaning that they do not come - * from the inferior_task, but rather from external - * tasks. - * - * As a debugging feature: - * A debugger debugging another debugger can stop the - * inferior debugger by the following command sequence - * (without running external programs) - * - * (top-gdb) set stop_inferior_gdb () - * (top-gdb) continue - */ -mach_port_t our_message_port = MACH_PORT_NULL; - -/* For single stepping */ -mach_port_t thread_exception_port = MACH_PORT_NULL; -mach_port_t thread_saved_exception_port = MACH_PORT_NULL; -mach_port_t singlestepped_thread_port = MACH_PORT_NULL; - -/* For machid calls */ -mach_port_t mid_server = MACH_PORT_NULL; -mach_port_t mid_auth = MACH_PORT_NULL; - -/* If gdb thinks the inferior task is not suspended, it - * must take suspend/abort the threads when it reads the state. - */ -int must_suspend_thread = 0; - -/* When single stepping, we switch the port that mach_really_wait() listens to. - * This cleanup is a guard to prevent the port set from being left to - * the singlestepped_thread_port when error() is called. - * This is nonzero only when we are single stepping. - */ -#define NULL_CLEANUP (struct cleanup *)0 -struct cleanup *cleanup_step = NULL_CLEANUP; - - -static struct target_ops m3_ops; - -static void m3_kill_inferior (); - -#if 0 -#define MACH_TYPE_EXCEPTION_PORT -1 -#endif - -/* Chain of ports to remember requested notifications. */ - -struct port_chain - { - struct port_chain *next; - mach_port_t port; - int type; - int mid; /* Now only valid with MACH_TYPE_THREAD and */ - /* MACH_TYPE_THREAD */ - }; -typedef struct port_chain *port_chain_t; - -/* Room for chain nodes comes from pchain_obstack */ -struct obstack pchain_obstack; -struct obstack *port_chain_obstack = &pchain_obstack; - -/* For thread handling */ -struct obstack Cproc_obstack; -struct obstack *cproc_obstack = &Cproc_obstack; - -/* the list of notified ports */ -port_chain_t notify_chain = (port_chain_t) NULL; - -port_chain_t -port_chain_insert (port_chain_t list, mach_port_t name, int type) -{ - kern_return_t ret; - port_chain_t new; - int mid; - - if (!MACH_PORT_VALID (name)) - return list; - - if (type == MACH_TYPE_TASK || type == MACH_TYPE_THREAD) - { - if (!MACH_PORT_VALID (mid_server)) - { - warning ("Machid server port invalid, can not map port 0x%x to MID", - name); - mid = name; - } - else - { - ret = machid_mach_register (mid_server, mid_auth, name, type, &mid); - - if (ret != KERN_SUCCESS) - { - warning ("Can not map name (0x%x) to MID with machid", name); - mid = name; - } - } - } - else - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - new = (port_chain_t) obstack_alloc (port_chain_obstack, - sizeof (struct port_chain)); - new->next = list; - new->port = name; - new->type = type; - new->mid = mid; - - return new; -} - -port_chain_t -port_chain_delete (port_chain_t list, mach_port_t elem) -{ - if (list) - if (list->port == elem) - list = list->next; - else - while (list->next) - { - if (list->next->port == elem) - list->next = list->next->next; /* GCd with obstack_free() */ - else - list = list->next; - } - return list; -} - -void -port_chain_destroy (struct obstack *ostack) -{ - obstack_free (ostack, 0); - obstack_init (ostack); -} - -port_chain_t -port_chain_member (port_chain_t list, mach_port_t elem) -{ - while (list) - { - if (list->port == elem) - return list; - list = list->next; - } - return (port_chain_t) NULL; -} - -int -map_port_name_to_mid (mach_port_t name, int type) -{ - port_chain_t elem; - - if (!MACH_PORT_VALID (name)) - return -1; - - elem = port_chain_member (notify_chain, name); - - if (elem && (elem->type == type)) - return elem->mid; - - if (elem) - return -1; - - if (!MACH_PORT_VALID (mid_server)) - { - warning ("Machid server port invalid, can not map port 0x%x to mid", - name); - return -1; - } - else - { - int mid; - kern_return_t ret; - - ret = machid_mach_register (mid_server, mid_auth, name, type, &mid); - - if (ret != KERN_SUCCESS) - { - warning ("Can not map name (0x%x) to mid with machid", name); - return -1; - } - return mid; - } -} - -/* Guard for currently_waiting_for and singlestepped_thread_port */ -static void -discard_single_step (thread_t thread) -{ - currently_waiting_for = inferior_wait_port_set; - - cleanup_step = NULL_CLEANUP; - if (MACH_PORT_VALID (thread) && MACH_PORT_VALID (singlestepped_thread_port)) - setup_single_step (thread, FALSE); -} - -setup_single_step (thread_t thread, boolean_t start_step) -{ - kern_return_t ret; - - if (!MACH_PORT_VALID (thread)) - error ("Invalid thread supplied to setup_single_step"); - else - { - mach_port_t teport; - - /* Get the current thread exception port */ - ret = thread_get_exception_port (thread, &teport); - CHK ("Getting thread's exception port", ret); - - if (start_step) - { - if (MACH_PORT_VALID (singlestepped_thread_port)) - { - warning ("Singlestepped_thread_port (0x%x) is still valid?", - singlestepped_thread_port); - singlestepped_thread_port = MACH_PORT_NULL; - } - - /* If we are already stepping this thread */ - if (MACH_PORT_VALID (teport) && teport == thread_exception_port) - { - ret = mach_port_deallocate (mach_task_self (), teport); - CHK ("Could not deallocate thread exception port", ret); - } - else - { - ret = thread_set_exception_port (thread, thread_exception_port); - CHK ("Setting exception port for thread", ret); -#if 0 - /* Insert thread exception port to wait port set */ - ret = mach_port_move_member (mach_task_self (), - thread_exception_port, - inferior_wait_port_set); - CHK ("Moving thread exception port to inferior_wait_port_set", - ret); -#endif - thread_saved_exception_port = teport; - } - - thread_trace (thread, TRUE); - - singlestepped_thread_port = thread_exception_port; - currently_waiting_for = singlestepped_thread_port; - cleanup_step = make_cleanup (discard_single_step, thread); - } - else - { - if (!MACH_PORT_VALID (teport)) - error ("Single stepped thread had an invalid exception port?"); - - if (teport != thread_exception_port) - error ("Single stepped thread had an unknown exception port?"); - - ret = mach_port_deallocate (mach_task_self (), teport); - CHK ("Couldn't deallocate thread exception port", ret); -#if 0 - /* Remove thread exception port from wait port set */ - ret = mach_port_move_member (mach_task_self (), - thread_exception_port, - MACH_PORT_NULL); - CHK ("Removing thread exception port from inferior_wait_port_set", - ret); -#endif - /* Restore thread's old exception port */ - ret = thread_set_exception_port (thread, - thread_saved_exception_port); - CHK ("Restoring stepped thread's exception port", ret); - - if (MACH_PORT_VALID (thread_saved_exception_port)) - (void) mach_port_deallocate (mach_task_self (), - thread_saved_exception_port); - - thread_trace (thread, FALSE); - - singlestepped_thread_port = MACH_PORT_NULL; - currently_waiting_for = inferior_wait_port_set; - if (cleanup_step) - discard_cleanups (cleanup_step); - } - } -} - -static -request_notify (mach_port_t name, mach_msg_id_t variant, int type) -{ - kern_return_t ret; - mach_port_t previous_port_dummy = MACH_PORT_NULL; - - if (!MACH_PORT_VALID (name)) - return; - - if (port_chain_member (notify_chain, name)) - return; - - ret = mach_port_request_notification (mach_task_self (), - name, - variant, - 1, - our_notify_port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - &previous_port_dummy); - CHK ("Serious: request_notify failed", ret); - - (void) mach_port_deallocate (mach_task_self (), - previous_port_dummy); - - notify_chain = port_chain_insert (notify_chain, name, type); -} - -reverse_msg_bits (mach_msg_header_t *msgp, int type) -{ - int rbits, lbits; - rbits = MACH_MSGH_BITS_REMOTE (msgp->msgh_bits); - lbits = type; - msgp->msgh_bits = - (msgp->msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) | - MACH_MSGH_BITS (lbits, rbits); -} - -/* On the third day He said: - - Let this be global - and then it was global. - - When creating the inferior fork, the - child code in inflow.c sets the name of the - bootstrap_port in its address space to this - variable. - - The name is transferred to our address space - with mach3_read_inferior(). - - Thou shalt not do this with - task_get_bootstrap_port() in this task, since - the name in the inferior task is different than - the one we get. - - For blessed are the meek, as they shall inherit - the address space. - */ -mach_port_t original_server_port_name = MACH_PORT_NULL; - - -/* Called from inferior after FORK but before EXEC */ -static void -m3_trace_me (void) -{ - kern_return_t ret; - - /* Get the NAME of the bootstrap port in this task - so that GDB can read it */ - ret = task_get_bootstrap_port (mach_task_self (), - &original_server_port_name); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - ret = mach_port_deallocate (mach_task_self (), - original_server_port_name); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - /* Suspend this task to let the parent change my ports. - Resumed by the debugger */ - ret = task_suspend (mach_task_self ()); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); -} - -/* - * Intercept system calls to Unix server. - * After EXEC_COUNTER calls to exec(), return. - * - * Pre-assertion: Child is suspended. (Not verified) - * Post-condition: Child is suspended after EXEC_COUNTER exec() calls. - */ - -void -intercept_exec_calls (int exec_counter) -{ - int terminal_initted = 0; - - struct syscall_msg_t - { - mach_msg_header_t header; - mach_msg_type_t type; - char room[2000]; /* Enuff space */ - }; - - struct syscall_msg_t syscall_in, syscall_out; - - mach_port_t fake_server; - mach_port_t original_server_send; - mach_port_t original_exec_reply; - mach_port_t exec_reply; - mach_port_t exec_reply_send; - mach_msg_type_name_t acquired; - mach_port_t emulator_server_port_name; - struct task_basic_info info; - mach_msg_type_number_t info_count; - - kern_return_t ret; - - if (exec_counter <= 0) - return; /* We are already set up in the correct program */ - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &fake_server); - CHK ("create inferior_fake_server port failed", ret); - - /* Wait for inferior_task to suspend itself */ - while (1) - { - info_count = sizeof (info); - ret = task_info (inferior_task, - TASK_BASIC_INFO, - (task_info_t) & info, - &info_count); - CHK ("Task info", ret); - - if (info.suspend_count) - break; - - /* Note that the definition of the parameter was undefined - * at the time of this writing, so I just use an `ad hoc' value. - */ - (void) swtch_pri (42); /* Universal Priority Value */ - } - - /* Read the inferior's bootstrap port name */ - if (!mach3_read_inferior (&original_server_port_name, - &original_server_port_name, - sizeof (original_server_port_name))) - error ("Can't read inferior task bootstrap port name"); - - /* @@ BUG: If more than 1 send right GDB will FAIL!!! */ - /* Should get refs, and set them back when restoring */ - /* Steal the original bsd server send right from inferior */ - ret = mach_port_extract_right (inferior_task, - original_server_port_name, - MACH_MSG_TYPE_MOVE_SEND, - &original_server_send, - &acquired); - CHK ("mach_port_extract_right (bsd server send)", ret); - - if (acquired != MACH_MSG_TYPE_PORT_SEND) - error ("Incorrect right extracted, send right to bsd server expected"); - - ret = mach_port_insert_right (inferior_task, - original_server_port_name, - fake_server, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("mach_port_insert_right (fake server send)", ret); - - xx_debug ("inferior task bsd server ports set up \nfs %x, ospn %x, oss %x\n", - fake_server, - original_server_port_name, original_server_send); - - /* A receive right to the reply generated by unix server exec() request */ - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &exec_reply); - CHK ("create intercepted_reply_port port failed", ret); - - /* Pass this send right to Unix server so it replies to us after exec() */ - ret = mach_port_extract_right (mach_task_self (), - exec_reply, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - &exec_reply_send, - &acquired); - CHK ("mach_port_extract_right (exec_reply)", ret); - - if (acquired != MACH_MSG_TYPE_PORT_SEND_ONCE) - error ("Incorrect right extracted, send once expected for exec reply"); - - ret = mach_port_move_member (mach_task_self (), - fake_server, - inferior_wait_port_set); - CHK ("Moving fake syscall port to inferior_wait_port_set", ret); - - xx_debug ("syscall fake server set up, resuming inferior\n"); - - ret = task_resume (inferior_task); - CHK ("task_resume (startup)", ret); - - /* Read requests from the inferior. - Pass directly through everything else except exec() calls. - */ - while (exec_counter > 0) - { - ret = mach_msg (&syscall_in.header, /* header */ - MACH_RCV_MSG, /* options */ - 0, /* send size */ - sizeof (struct syscall_msg_t), /* receive size */ - inferior_wait_port_set, /* receive_name */ - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - CHK ("mach_msg (intercepted sycall)", ret); - -#ifdef DUMP_SYSCALL - print_msg (&syscall_in.header); -#endif - - /* ASSERT : msgh_local_port == fake_server */ - - if (notify_server (&syscall_in.header, &syscall_out.header)) - error ("received a notify while intercepting syscalls"); - - if (syscall_in.header.msgh_id == MIG_EXEC_SYSCALL_ID) - { - xx_debug ("Received EXEC SYSCALL, counter = %d\n", exec_counter); - if (exec_counter == 1) - { - original_exec_reply = syscall_in.header.msgh_remote_port; - syscall_in.header.msgh_remote_port = exec_reply_send; - } - - if (!terminal_initted) - { - /* Now that the child has exec'd we know it has already set its - process group. On POSIX systems, tcsetpgrp will fail with - EPERM if we try it before the child's setpgid. */ - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - target_terminal_init (); - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - terminal_initted = 1; - } - - exec_counter--; - } - - syscall_in.header.msgh_local_port = syscall_in.header.msgh_remote_port; - syscall_in.header.msgh_remote_port = original_server_send; - - reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_COPY_SEND); - - ret = mach_msg_send (&syscall_in.header); - CHK ("Forwarded syscall", ret); - } - - ret = mach_port_move_member (mach_task_self (), - fake_server, - MACH_PORT_NULL); - CHK ("Moving fake syscall out of inferior_wait_port_set", ret); - - ret = mach_port_move_member (mach_task_self (), - exec_reply, - inferior_wait_port_set); - CHK ("Moving exec_reply to inferior_wait_port_set", ret); - - ret = mach_msg (&syscall_in.header, /* header */ - MACH_RCV_MSG, /* options */ - 0, /* send size */ - sizeof (struct syscall_msg_t), /* receive size */ - inferior_wait_port_set, /* receive_name */ - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - CHK ("mach_msg (exec reply)", ret); - - ret = task_suspend (inferior_task); - CHK ("Suspending inferior after last exec", ret); - - must_suspend_thread = 0; - - xx_debug ("Received exec reply from bsd server, suspended inferior task\n"); - -#ifdef DUMP_SYSCALL - print_msg (&syscall_in.header); -#endif - - /* Message should appear as if it came from the unix server */ - syscall_in.header.msgh_local_port = MACH_PORT_NULL; - - /* and go to the inferior task original reply port */ - syscall_in.header.msgh_remote_port = original_exec_reply; - - reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_MOVE_SEND_ONCE); - - ret = mach_msg_send (&syscall_in.header); - CHK ("Forwarding exec reply to inferior", ret); - - /* Garbage collect */ - ret = mach_port_deallocate (inferior_task, - original_server_port_name); - CHK ("deallocating fake server send right", ret); - - ret = mach_port_insert_right (inferior_task, - original_server_port_name, - original_server_send, - MACH_MSG_TYPE_MOVE_SEND); - CHK ("Restoring the original bsd server send right", ret); - - ret = mach_port_destroy (mach_task_self (), - fake_server); - fake_server = MACH_PORT_DEAD; - CHK ("mach_port_destroy (fake_server)", ret); - - ret = mach_port_destroy (mach_task_self (), - exec_reply); - exec_reply = MACH_PORT_DEAD; - CHK ("mach_port_destroy (exec_reply)", ret); - - xx_debug ("Done with exec call interception\n"); -} - -void -consume_send_rights (thread_array_t thread_list, int thread_count) -{ - int index; - - if (!thread_count) - return; - - for (index = 0; index < thread_count; index++) - { - /* Since thread kill command kills threads, don't check ret */ - (void) mach_port_deallocate (mach_task_self (), - thread_list[index]); - } -} - -/* suspend/abort/resume a thread. */ -setup_thread (mach_port_t thread, int what) -{ - kern_return_t ret; - - if (what) - { - ret = thread_suspend (thread); - CHK ("setup_thread thread_suspend", ret); - - ret = thread_abort (thread); - CHK ("setup_thread thread_abort", ret); - } - else - { - ret = thread_resume (thread); - CHK ("setup_thread thread_resume", ret); - } -} - -int -map_slot_to_mid (int slot, thread_array_t threads, int thread_count) -{ - kern_return_t ret; - int deallocate = 0; - int index; - int mid; - - if (!threads) - { - deallocate++; - ret = task_threads (inferior_task, &threads, &thread_count); - CHK ("Can not select a thread from a dead task", ret); - } - - if (slot < 0 || slot >= thread_count) - { - if (deallocate) - { - consume_send_rights (threads, thread_count); - (void) vm_deallocate (mach_task_self (), (vm_address_t) threads, - (thread_count * sizeof (mach_port_t))); - } - if (slot < 0) - error ("invalid slot number"); - else - return -(slot + 1); - } - - mid = map_port_name_to_mid (threads[slot], MACH_TYPE_THREAD); - - if (deallocate) - { - consume_send_rights (threads, thread_count); - (void) vm_deallocate (mach_task_self (), (vm_address_t) threads, - (thread_count * sizeof (mach_port_t))); - } - - return mid; -} - -static int -parse_thread_id (char *arg, int thread_count, int slots) -{ - kern_return_t ret; - int mid; - int slot; - int index; - - if (arg == 0) - return 0; - - while (*arg && (*arg == ' ' || *arg == '\t')) - arg++; - - if (!*arg) - return 0; - - /* Currently parse MID and @SLOTNUMBER */ - if (*arg != '@') - { - mid = atoi (arg); - if (mid <= 0) - error ("valid thread mid expected"); - return mid; - } - - arg++; - slot = atoi (arg); - - if (slot < 0) - error ("invalid slot number"); - - /* If you want slot numbers to remain slot numbers, set slots. - - * Well, since 0 is reserved, return the ordinal number - * of the thread rather than the slot number. Awk, this - * counts as a kludge. - */ - if (slots) - return -(slot + 1); - - if (thread_count && slot >= thread_count) - return -(slot + 1); - - mid = map_slot_to_mid (slot); - - return mid; -} - -/* THREAD_ID 0 is special; it selects the first kernel - * thread from the list (i.e. SLOTNUMBER 0) - * This is used when starting the program with 'run' or when attaching. - * - * If FLAG is 0 the context is not changed, and the registers, frame, etc - * will continue to describe the old thread. - * - * If FLAG is nonzero, really select the thread. - * If FLAG is 2, the THREAD_ID is a slotnumber instead of a mid. - * - */ -kern_return_t -select_thread (mach_port_t task, int thread_id, int flag) -{ - thread_array_t thread_list; - int thread_count; - kern_return_t ret; - int index; - thread_t new_thread = MACH_PORT_NULL; - - if (thread_id < 0) - error ("Can't select cprocs without kernel thread"); - - ret = task_threads (task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - warning ("Can not select a thread from a dead task"); - m3_kill_inferior (); - return KERN_FAILURE; - } - - if (thread_count == 0) - { - /* The task can not do anything anymore, but it still - * exists as a container for memory and ports. - */ - registers_changed (); - warning ("Task %d has no threads", - map_port_name_to_mid (task, MACH_TYPE_TASK)); - current_thread = MACH_PORT_NULL; - (void) vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (mach_port_t))); - return KERN_FAILURE; - } - - if (!thread_id || flag == 2) - { - /* First thread or a slotnumber */ - if (!thread_id) - new_thread = thread_list[0]; - else - { - if (thread_id < thread_count) - new_thread = thread_list[thread_id]; - else - { - (void) vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (mach_port_t))); - error ("No such thread slot number : %d", thread_id); - } - } - } - else - { - for (index = 0; index < thread_count; index++) - if (thread_id == map_port_name_to_mid (thread_list[index], - MACH_TYPE_THREAD)) - { - new_thread = thread_list[index]; - index = -1; - break; - } - - if (index != -1) - error ("No thread with mid %d", thread_id); - } - - /* Notify when the selected thread dies */ - request_notify (new_thread, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_THREAD); - - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (mach_port_t))); - CHK ("vm_deallocate", ret); - - if (!flag) - current_thread = new_thread; - else - { -#if 0 - if (MACH_PORT_VALID (current_thread)) - { - /* Store the gdb's view of the thread we are deselecting - - * @@ I think gdb updates registers immediately when they are - * changed, so don't do this. - */ - ret = thread_abort (current_thread); - CHK ("Could not abort system calls when saving state of old thread", - ret); - target_prepare_to_store (); - target_store_registers (-1); - } -#endif - - registers_changed (); - - current_thread = new_thread; - - ret = thread_abort (current_thread); - CHK ("Could not abort system calls when selecting a thread", ret); - - stop_pc = read_pc (); - flush_cached_frames (); - - select_frame (get_current_frame (), 0); - } - - return KERN_SUCCESS; -} - -/* - * Switch to use thread named NEW_THREAD. - * Return it's MID - */ -int -switch_to_thread (thread_t new_thread) -{ - thread_t saved_thread = current_thread; - int mid; - - mid = map_port_name_to_mid (new_thread, - MACH_TYPE_THREAD); - if (mid == -1) - warning ("Can't map thread name 0x%x to mid", new_thread); - else if (select_thread (inferior_task, mid, 1) != KERN_SUCCESS) - { - if (current_thread) - current_thread = saved_thread; - error ("Could not select thread %d", mid); - } - - return mid; -} - -/* Do this in gdb after doing FORK but before STARTUP_INFERIOR. - * Note that the registers are not yet valid in the inferior task. - */ -static int -m3_trace_him (int pid) -{ - kern_return_t ret; - - push_target (&m3_ops); - - inferior_task = task_by_pid (pid); - - if (!MACH_PORT_VALID (inferior_task)) - error ("Can not map Unix pid %d to Mach task", pid); - - /* Clean up previous notifications and create new ones */ - setup_notify_port (1); - - /* When notification appears, the inferior task has died */ - request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK); - - emulator_present = have_emulator_p (inferior_task); - - /* By default, select the first thread, - * If task has no threads, gives a warning - * Does not fetch registers, since they are not yet valid. - */ - select_thread (inferior_task, 0, 0); - - inferior_exception_port = MACH_PORT_NULL; - - setup_exception_port (); - - xx_debug ("Now the debugged task is created\n"); - - /* One trap to exec the shell, one to exec the program being debugged. */ - intercept_exec_calls (2); - - return pid; -} - -setup_exception_port (void) -{ - kern_return_t ret; - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &inferior_exception_port); - CHK ("mach_port_allocate", ret); - - /* add send right */ - ret = mach_port_insert_right (mach_task_self (), - inferior_exception_port, - inferior_exception_port, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("mach_port_insert_right", ret); - - ret = mach_port_move_member (mach_task_self (), - inferior_exception_port, - inferior_wait_port_set); - CHK ("mach_port_move_member", ret); - - ret = task_get_special_port (inferior_task, - TASK_EXCEPTION_PORT, - &inferior_old_exception_port); - CHK ("task_get_special_port(old exc)", ret); - - ret = task_set_special_port (inferior_task, - TASK_EXCEPTION_PORT, - inferior_exception_port); - CHK ("task_set_special_port", ret); - - ret = mach_port_deallocate (mach_task_self (), - inferior_exception_port); - CHK ("mack_port_deallocate", ret); - -#if 0 - /* When notify appears, the inferior_task's exception - * port has been destroyed. - * - * Not used, since the dead_name_notification already - * appears when task dies. - * - */ - request_notify (inferior_exception_port, - MACH_NOTIFY_NO_SENDERS, - MACH_TYPE_EXCEPTION_PORT); -#endif -} - -/* Nonzero if gdb is waiting for a message */ -int mach_really_waiting; - -/* Wait for the inferior to stop for some reason. - - Loop on notifications until inferior_task dies. - - Loop on exceptions until stopped_in_exception comes true. - (e.g. we receive a single step trace trap) - - a message arrives to gdb's message port - - There is no other way to exit this loop. - - Returns the inferior_ptid for rest of gdb. - Side effects: Set *OURSTATUS. */ -ptid_t -mach_really_wait (ptid_t ptid, struct target_waitstatus *ourstatus) -{ - kern_return_t ret; - int w; - - struct msg - { - mach_msg_header_t header; - mach_msg_type_t foo; - int data[8000]; - } - in_msg, out_msg; - - /* Either notify (death), exception or message can stop the inferior */ - stopped_in_exception = FALSE; - - while (1) - { - QUIT; - - stop_exception = stop_code = stop_subcode = -1; - stop_thread = MACH_PORT_NULL; - - mach_really_waiting = 1; - ret = mach_msg (&in_msg.header, /* header */ - MACH_RCV_MSG, /* options */ - 0, /* send size */ - sizeof (struct msg), /* receive size */ - currently_waiting_for, /* receive name */ - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - mach_really_waiting = 0; - CHK ("mach_msg (receive)", ret); - - /* Check if we received a notify of the childs' death */ - if (notify_server (&in_msg.header, &out_msg.header)) - { - /* If inferior_task is null then the inferior has - gone away and we want to return to command level. - Otherwise it was just an informative message and we - need to look to see if there are any more. */ - if (inferior_task != MACH_PORT_NULL) - continue; - else - { - /* Collect Unix exit status for gdb */ - - wait3 (&w, WNOHANG, 0); - - /* This mess is here to check that the rest of - * gdb knows that the inferior died. It also - * tries to hack around the fact that Mach 3.0 (mk69) - * unix server (ux28) does not always know what - * has happened to it's children when mach-magic - * is applied on them. - */ - if ((!WIFEXITED (w) && WIFSTOPPED (w)) || - (WIFEXITED (w) && WEXITSTATUS (w) > 0377)) - { - WSETEXIT (w, 0); - warning ("Using exit value 0 for terminated task"); - } - else if (!WIFEXITED (w)) - { - int sig = WTERMSIG (w); - - /* Signals cause problems. Warn the user. */ - if (sig != SIGKILL) /* Bad luck if garbage matches this */ - warning ("The terminating signal stuff may be nonsense"); - else if (sig > NSIG) - { - WSETEXIT (w, 0); - warning ("Using exit value 0 for terminated task"); - } - } - store_waitstatus (ourstatus, w); - return inferior_ptid; - } - } - - /* Hmm. Check for exception, as it was not a notification. - exc_server() does an upcall to catch_exception_raise() - if this rpc is an exception. Further actions are decided - there. - */ - if (!exc_server (&in_msg.header, &out_msg.header)) - { - - /* Not an exception, check for message. - - * Messages don't come from the inferior, or if they - * do they better be asynchronous or it will hang. - */ - if (gdb_message_server (&in_msg.header)) - continue; - - error ("Unrecognized message received in mach_really_wait"); - } - - /* Send the reply of the exception rpc to the suspended task */ - ret = mach_msg_send (&out_msg.header); - CHK ("mach_msg_send (exc reply)", ret); - - if (stopped_in_exception) - { - /* Get unix state. May be changed in mach3_exception_actions() */ - wait3 (&w, WNOHANG, 0); - - mach3_exception_actions (&w, FALSE, "Task"); - - store_waitstatus (ourstatus, w); - return inferior_ptid; - } - } -} - -/* Called by macro DO_QUIT() in utils.c(quit). - * This is called just before calling error() to return to command level - */ -void -mach3_quit (void) -{ - int mid; - kern_return_t ret; - - if (mach_really_waiting) - { - ret = task_suspend (inferior_task); - - if (ret != KERN_SUCCESS) - { - warning ("Could not suspend task for interrupt: %s", - mach_error_string (ret)); - mach_really_waiting = 0; - return; - } - } - - must_suspend_thread = 0; - mach_really_waiting = 0; - - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - if (mid == -1) - { - warning ("Selecting first existing kernel thread"); - mid = 0; - } - - current_thread = MACH_PORT_NULL; /* Force setup */ - select_thread (inferior_task, mid, 1); - - return; -} - -#if 0 -/* bogus bogus bogus. It is NOT OK to quit out of target_wait. */ - -/* If ^C is typed when we are waiting for a message - * and your Unix server is able to notice that we - * should quit now. - * - * Called by REQUEST_QUIT() from utils.c(request_quit) - */ -void -mach3_request_quit (void) -{ - if (mach_really_waiting) - immediate_quit = 1; -} -#endif - -/* - * Gdb message server. - * Currently implemented is the STOP message, that causes - * gdb to return to the command level like ^C had been typed from terminal. - */ -int -gdb_message_server (mach_msg_header_t *InP) -{ - kern_return_t ret; - int mid; - - if (InP->msgh_local_port == our_message_port) - { - /* A message coming to our_message_port. Check validity */ - switch (InP->msgh_id) - { - - case GDB_MESSAGE_ID_STOP: - ret = task_suspend (inferior_task); - if (ret != KERN_SUCCESS) - warning ("Could not suspend task for stop message: %s", - mach_error_string (ret)); - - /* QUIT in mach_really_wait() loop. */ - request_quit (0); - break; - - default: - warning ("Invalid message id %d received, ignored.", - InP->msgh_id); - break; - } - - return 1; - } - - /* Message not handled by this server */ - return 0; -} - -/* NOTE: This is not an RPC call. It is a simpleroutine. - - * This is not called from this gdb code. - * - * It may be called by another debugger to cause this - * debugger to enter command level: - * - * (gdb) set stop_inferior_gdb () - * (gdb) continue - * - * External program "stop-gdb" implements this also. - */ -void -stop_inferior_gdb (void) -{ - kern_return_t ret; - - /* Code generated by mig, with minor cleanups :-) - - * simpleroutine stop_inferior_gdb (our_message_port : mach_port_t); - */ - - typedef struct - { - mach_msg_header_t Head; - } - Request; - - Request Mess; - - register Request *InP = &Mess; - - InP->Head.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); - - /* msgh_size passed as argument */ - InP->Head.msgh_remote_port = our_message_port; - InP->Head.msgh_local_port = MACH_PORT_NULL; - InP->Head.msgh_seqno = 0; - InP->Head.msgh_id = GDB_MESSAGE_ID_STOP; - - ret = mach_msg (&InP->Head, - MACH_SEND_MSG | MACH_MSG_OPTION_NONE, - sizeof (Request), - 0, - MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); -} - -#ifdef THREAD_ALLOWED_TO_BREAK -/* - * Return 1 if the MID specifies the thread that caused the - * last exception. - * Since catch_exception_raise() selects the thread causing - * the last exception to current_thread, we just check that - * it is selected and the last exception was a breakpoint. - */ -int -mach_thread_for_breakpoint (int mid) -{ - int cmid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - - if (mid < 0) - { - mid = map_slot_to_mid (-(mid + 1), 0, 0); - if (mid < 0) - return 0; /* Don't stop, no such slot */ - } - - if (!mid || cmid == -1) - return 1; /* stop */ - - return cmid == mid && stop_exception == EXC_BREAKPOINT; -} -#endif /* THREAD_ALLOWED_TO_BREAK */ - -#ifdef THREAD_PARSE_ID -/* - * Map a thread id string (MID or a @SLOTNUMBER) - * to a thread-id. - * - * 0 matches all threads. - * Otherwise the meaning is defined only in this file. - * (mach_thread_for_breakpoint uses it) - * - * @@ This allows non-existent MIDs to be specified. - * It now also allows non-existent slots to be - * specified. (Slot numbers stored are negative, - * and the magnitude is one greater than the actual - * slot index. (Since 0 is reserved)) - */ -int -mach_thread_parse_id (char *arg) -{ - int mid; - if (arg == 0) - error ("thread id expected"); - mid = parse_thread_id (arg, 0, 1); - - return mid; -} -#endif /* THREAD_PARSE_ID */ - -#ifdef THREAD_OUTPUT_ID -char * -mach_thread_output_id (int mid) -{ - static char foobar[20]; - - if (mid > 0) - sprintf (foobar, "mid %d", mid); - else if (mid < 0) - sprintf (foobar, "@%d", -(mid + 1)); - else - sprintf (foobar, "*any thread*"); - - return foobar; -} -#endif /* THREAD_OUTPUT_ID */ - -/* Called with hook PREPARE_TO_PROCEED() from infrun.c. - - * If we have switched threads and stopped at breakpoint return 1 otherwise 0. - * - * if SELECT_IT is nonzero, reselect the thread that was active when - * we stopped at a breakpoint. - * - * Note that this implementation is potentially redundant now that - * default_prepare_to_proceed() has been added. - * - * FIXME This may not support switching threads after Ctrl-C - * correctly. The default implementation does support this. - */ - -mach3_prepare_to_proceed (int select_it) -{ - if (stop_thread && - stop_thread != current_thread && - stop_exception == EXC_BREAKPOINT) - { - int mid; - - if (!select_it) - return 1; - - mid = switch_to_thread (stop_thread); - - return 1; - } - - return 0; -} - -/* this stuff here is an upcall via libmach/excServer.c - and mach_really_wait which does the actual upcall. - - The code will pass the exception to the inferior if: - - - The task that signaled is not the inferior task - (e.g. when debugging another debugger) - - - The user has explicitely requested to pass on the exceptions. - (e.g to the default unix exception handler, which maps - exceptions to signals, or the user has her own exception handler) - - - If the thread that signaled is being single-stepped and it - has set it's own exception port and the exception is not - EXC_BREAKPOINT. (Maybe this is not desirable?) - */ - -kern_return_t -catch_exception_raise (mach_port_t port, thread_t thread, task_t task, - int exception, int code, int subcode) -{ - kern_return_t ret; - boolean_t signal_thread; - int mid = map_port_name_to_mid (thread, MACH_TYPE_THREAD); - - if (!MACH_PORT_VALID (thread)) - { - /* If the exception was sent and thread dies before we - receive it, THREAD will be MACH_PORT_DEAD - */ - - current_thread = thread = MACH_PORT_NULL; - error ("Received exception from nonexistent thread"); - } - - /* Check if the task died in transit. - * @@ Isn't the thread also invalid in such case? - */ - if (!MACH_PORT_VALID (task)) - { - current_thread = thread = MACH_PORT_NULL; - error ("Received exception from nonexistent task"); - } - - if (exception < 0 || exception > MAX_EXCEPTION) - internal_error (__FILE__, __LINE__, - "catch_exception_raise: unknown exception code %d thread %d", - exception, - mid); - - if (!MACH_PORT_VALID (inferior_task)) - error ("got an exception, but inferior_task is null or dead"); - - stop_exception = exception; - stop_code = code; - stop_subcode = subcode; - stop_thread = thread; - - signal_thread = exception != EXC_BREAKPOINT && - port == singlestepped_thread_port && - MACH_PORT_VALID (thread_saved_exception_port); - - /* If it was not our inferior or if we want to forward - * the exception to the inferior's handler, do it here - * - * Note: If you have forwarded EXC_BREAKPOINT I trust you know why. - */ - if (task != inferior_task || - signal_thread || - exception_map[exception].forward) - { - mach_port_t eport = inferior_old_exception_port; - - if (signal_thread) - { - /* - GDB now forwards the exeption to thread's original handler, - since the user propably knows what he is doing. - Give a message, though. - */ - - mach3_exception_actions ((WAITTYPE *) NULL, TRUE, "Thread"); - eport = thread_saved_exception_port; - } - - /* Send the exception to the original handler */ - ret = exception_raise (eport, - thread, - task, - exception, - code, - subcode); - - (void) mach_port_deallocate (mach_task_self (), task); - (void) mach_port_deallocate (mach_task_self (), thread); - - /* If we come here, we don't want to trace any more, since we - * will never stop for tracing anyway. - */ - discard_single_step (thread); - - /* Do not stop the inferior */ - return ret; - } - - /* Now gdb handles the exception */ - stopped_in_exception = TRUE; - - ret = task_suspend (task); - CHK ("Error suspending inferior after exception", ret); - - must_suspend_thread = 0; - - if (current_thread != thread) - { - if (MACH_PORT_VALID (singlestepped_thread_port)) - /* Cleanup discards single stepping */ - error ("Exception from thread %d while singlestepping thread %d", - mid, - map_port_name_to_mid (current_thread, MACH_TYPE_THREAD)); - - /* Then select the thread that caused the exception */ - if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) - error ("Could not select thread %d causing exception", mid); - else - warning ("Gdb selected thread %d", mid); - } - - /* If we receive an exception that is not breakpoint - * exception, we interrupt the single step and return to - * debugger. Trace condition is cleared. - */ - if (MACH_PORT_VALID (singlestepped_thread_port)) - { - if (stop_exception != EXC_BREAKPOINT) - warning ("Single step interrupted by exception"); - else if (port == singlestepped_thread_port) - { - /* Single step exception occurred, remove trace bit - * and return to gdb. - */ - if (!MACH_PORT_VALID (current_thread)) - error ("Single stepped thread is not valid"); - - /* Resume threads, but leave the task suspended */ - resume_all_threads (0); - } - else - warning ("Breakpoint while single stepping?"); - - discard_single_step (current_thread); - } - - (void) mach_port_deallocate (mach_task_self (), task); - (void) mach_port_deallocate (mach_task_self (), thread); - - return KERN_SUCCESS; -} - -int -port_valid (mach_port_t port, int mask) -{ - kern_return_t ret; - mach_port_type_t type; - - ret = mach_port_type (mach_task_self (), - port, - &type); - if (ret != KERN_SUCCESS || (type & mask) != mask) - return 0; - return 1; -} - -/* @@ No vm read cache implemented yet */ -boolean_t vm_read_cache_valid = FALSE; - -/* - * Read inferior task's LEN bytes from ADDR and copy it to MYADDR - * in gdb's address space. - * - * Return 0 on failure; number of bytes read otherwise. - */ -int -mach3_read_inferior (CORE_ADDR addr, char *myaddr, int length) -{ - kern_return_t ret; - vm_address_t low_address = (vm_address_t) trunc_page (addr); - vm_size_t aligned_length = - (vm_size_t) round_page (addr + length) - low_address; - pointer_t copied_memory; - int copy_count; - - /* Get memory from inferior with page aligned addresses */ - ret = vm_read (inferior_task, - low_address, - aligned_length, - &copied_memory, - ©_count); - if (ret != KERN_SUCCESS) - { - /* the problem is that the inferior might be killed for whatever reason - * before we go to mach_really_wait. This is one place that ought to - * catch many of those errors. - * @@ A better fix would be to make all external events to GDB - * to arrive via a SINGLE port set. (Including user input!) - */ - - if (!port_valid (inferior_task, MACH_PORT_TYPE_SEND)) - { - m3_kill_inferior (); - error ("Inferior killed (task port invalid)"); - } - else - { -#ifdef OSF - extern int errno; - /* valprint.c gives nicer format if this does not - screw it. Eamonn seems to like this, so I enable - it if OSF is defined... - */ - warning ("[read inferior %x failed: %s]", - addr, mach_error_string (ret)); - errno = 0; -#endif - return 0; - } - } - - memcpy (myaddr, (char *) addr - low_address + copied_memory, length); - - ret = vm_deallocate (mach_task_self (), - copied_memory, - copy_count); - CHK ("mach3_read_inferior vm_deallocate failed", ret); - - return length; -} - -#define CHK_GOTO_OUT(str,ret) \ - do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0) - -struct vm_region_list -{ - struct vm_region_list *next; - vm_prot_t protection; - vm_address_t start; - vm_size_t length; -}; - -struct obstack region_obstack; - -/* - * Write inferior task's LEN bytes from ADDR and copy it to MYADDR - * in gdb's address space. - */ -int -mach3_write_inferior (CORE_ADDR addr, char *myaddr, int length) -{ - kern_return_t ret; - vm_address_t low_address = (vm_address_t) trunc_page (addr); - vm_size_t aligned_length = - (vm_size_t) round_page (addr + length) - low_address; - pointer_t copied_memory; - int copy_count; - int deallocate = 0; - - char *errstr = "Bug in mach3_write_inferior"; - - struct vm_region_list *region_element; - struct vm_region_list *region_head = (struct vm_region_list *) NULL; - - /* Get memory from inferior with page aligned addresses */ - ret = vm_read (inferior_task, - low_address, - aligned_length, - &copied_memory, - ©_count); - CHK_GOTO_OUT ("mach3_write_inferior vm_read failed", ret); - - deallocate++; - - memcpy ((char *) addr - low_address + copied_memory, myaddr, length); - - obstack_init (®ion_obstack); - - /* Do writes atomically. - * First check for holes and unwritable memory. - */ - { - vm_size_t remaining_length = aligned_length; - vm_address_t region_address = low_address; - - struct vm_region_list *scan; - - while (region_address < low_address + aligned_length) - { - vm_prot_t protection; - vm_prot_t max_protection; - vm_inherit_t inheritance; - boolean_t shared; - mach_port_t object_name; - vm_offset_t offset; - vm_size_t region_length = remaining_length; - vm_address_t old_address = region_address; - - ret = vm_region (inferior_task, - ®ion_address, - ®ion_length, - &protection, - &max_protection, - &inheritance, - &shared, - &object_name, - &offset); - CHK_GOTO_OUT ("vm_region failed", ret); - - /* Check for holes in memory */ - if (old_address != region_address) - { - warning ("No memory at 0x%x. Nothing written", - old_address); - ret = KERN_SUCCESS; - length = 0; - goto out; - } - - if (!(max_protection & VM_PROT_WRITE)) - { - warning ("Memory at address 0x%x is unwritable. Nothing written", - old_address); - ret = KERN_SUCCESS; - length = 0; - goto out; - } - - /* Chain the regions for later use */ - region_element = - (struct vm_region_list *) - obstack_alloc (®ion_obstack, sizeof (struct vm_region_list)); - - region_element->protection = protection; - region_element->start = region_address; - region_element->length = region_length; - - /* Chain the regions along with protections */ - region_element->next = region_head; - region_head = region_element; - - region_address += region_length; - remaining_length = remaining_length - region_length; - } - - /* If things fail after this, we give up. - * Somebody is messing up inferior_task's mappings. - */ - - /* Enable writes to the chained vm regions */ - for (scan = region_head; scan; scan = scan->next) - { - boolean_t protection_changed = FALSE; - - if (!(scan->protection & VM_PROT_WRITE)) - { - ret = vm_protect (inferior_task, - scan->start, - scan->length, - FALSE, - scan->protection | VM_PROT_WRITE); - CHK_GOTO_OUT ("vm_protect: enable write failed", ret); - } - } - - ret = vm_write (inferior_task, - low_address, - copied_memory, - aligned_length); - CHK_GOTO_OUT ("vm_write failed", ret); - - /* Set up the original region protections, if they were changed */ - for (scan = region_head; scan; scan = scan->next) - { - boolean_t protection_changed = FALSE; - - if (!(scan->protection & VM_PROT_WRITE)) - { - ret = vm_protect (inferior_task, - scan->start, - scan->length, - FALSE, - scan->protection); - CHK_GOTO_OUT ("vm_protect: enable write failed", ret); - } - } - } - -out: - if (deallocate) - { - obstack_free (®ion_obstack, 0); - - (void) vm_deallocate (mach_task_self (), - copied_memory, - copy_count); - } - - if (ret != KERN_SUCCESS) - { - warning ("%s %s", errstr, mach_error_string (ret)); - return 0; - } - - return length; -} - -/* Return 0 on failure, number of bytes handled otherwise. TARGET is - ignored. */ -static int -m3_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct target_ops *target) -{ - int result; - - if (write) - result = mach3_write_inferior (memaddr, myaddr, len); - else - result = mach3_read_inferior (memaddr, myaddr, len); - - return result; -} - - -static char * -translate_state (int state) -{ - switch (state) - { - case TH_STATE_RUNNING: - return ("R"); - case TH_STATE_STOPPED: - return ("S"); - case TH_STATE_WAITING: - return ("W"); - case TH_STATE_UNINTERRUPTIBLE: - return ("U"); - case TH_STATE_HALTED: - return ("H"); - default: - return ("?"); - } -} - -static char * -translate_cstate (int state) -{ - switch (state) - { - case CPROC_RUNNING: - return "R"; - case CPROC_SWITCHING: - return "S"; - case CPROC_BLOCKED: - return "B"; - case CPROC_CONDWAIT: - return "C"; - case CPROC_CONDWAIT | CPROC_SWITCHING: - return "CS"; - default: - return "?"; - } -} - -/* type == MACH_MSG_TYPE_COPY_SEND || type == MACH_MSG_TYPE_MAKE_SEND */ - -mach_port_t /* no mach_port_name_t found in include files. */ -map_inferior_port_name (mach_port_t inferior_name, mach_msg_type_name_t type) -{ - kern_return_t ret; - mach_msg_type_name_t acquired; - mach_port_t iport; - - ret = mach_port_extract_right (inferior_task, - inferior_name, - type, - &iport, - &acquired); - CHK ("mach_port_extract_right (map_inferior_port_name)", ret); - - if (acquired != MACH_MSG_TYPE_PORT_SEND) - error ("Incorrect right extracted, (map_inferior_port_name)"); - - ret = mach_port_deallocate (mach_task_self (), - iport); - CHK ("Deallocating mapped port (map_inferior_port_name)", ret); - - return iport; -} - -/* - * Naming convention: - * Always return user defined name if found. - * _K == A kernel thread with no matching CPROC - * _C == A cproc with no current cthread - * _t == A cthread with no user defined name - * - * The digits that follow the _names are the SLOT number of the - * kernel thread if there is such a thing, otherwise just a negation - * of the sequential number of such cprocs. - */ - -static char buf[7]; - -static char * -get_thread_name (gdb_thread_t one_cproc, int id) -{ - if (one_cproc) - if (one_cproc->cthread == NULL) - { - /* cproc not mapped to any cthread */ - sprintf (buf, "_C%d", id); - } - else if (!one_cproc->cthread->name) - { - /* cproc and cthread, but no name */ - sprintf (buf, "_t%d", id); - } - else - return (char *) (one_cproc->cthread->name); - else - { - if (id < 0) - warning ("Inconsistency in thread name id %d", id); - - /* Kernel thread without cproc */ - sprintf (buf, "_K%d", id); - } - - return buf; -} - -int -fetch_thread_info (mach_port_t task, gdb_thread_t *mthreads_out) -{ - kern_return_t ret; - thread_array_t th_table; - int th_count; - gdb_thread_t mthreads = NULL; - int index; - - ret = task_threads (task, &th_table, &th_count); - if (ret != KERN_SUCCESS) - { - warning ("Error getting inferior's thread list:%s", - mach_error_string (ret)); - m3_kill_inferior (); - return -1; - } - - mthreads = (gdb_thread_t) - obstack_alloc - (cproc_obstack, - th_count * sizeof (struct gdb_thread)); - - for (index = 0; index < th_count; index++) - { - thread_t saved_thread = MACH_PORT_NULL; - int mid; - - if (must_suspend_thread) - setup_thread (th_table[index], 1); - - if (th_table[index] != current_thread) - { - saved_thread = current_thread; - - mid = switch_to_thread (th_table[index]); - } - - mthreads[index].name = th_table[index]; - mthreads[index].cproc = NULL; /* map_cprocs_to_kernel_threads() */ - mthreads[index].in_emulator = FALSE; - mthreads[index].slotid = index; - - mthreads[index].sp = read_register (SP_REGNUM); - mthreads[index].fp = read_register (FP_REGNUM); - mthreads[index].pc = read_pc (); - - if (MACH_PORT_VALID (saved_thread)) - mid = switch_to_thread (saved_thread); - - if (must_suspend_thread) - setup_thread (th_table[index], 0); - } - - consume_send_rights (th_table, th_count); - ret = vm_deallocate (mach_task_self (), (vm_address_t) th_table, - (th_count * sizeof (mach_port_t))); - if (ret != KERN_SUCCESS) - { - warning ("Error trying to deallocate thread list : %s", - mach_error_string (ret)); - } - - *mthreads_out = mthreads; - - return th_count; -} - - -/* - * Current emulator always saves the USP on top of - * emulator stack below struct emul_stack_top stuff. - */ -CORE_ADDR -fetch_usp_from_emulator_stack (CORE_ADDR sp) -{ - CORE_ADDR stack_pointer; - - sp = (sp & ~(EMULATOR_STACK_SIZE - 1)) + - EMULATOR_STACK_SIZE - sizeof (struct emul_stack_top); - - if (mach3_read_inferior (sp, - &stack_pointer, - sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) - { - warning ("Can't read user sp from emulator stack address 0x%x", sp); - return 0; - } - - return stack_pointer; -} - -#ifdef MK67 - -/* get_emulation_vector() interface was changed after mk67 */ -#define EMUL_VECTOR_COUNT 400 /* Value does not matter too much */ - -#endif /* MK67 */ - -/* Check if the emulator exists at task's address space. - */ -boolean_t -have_emulator_p (task_t task) -{ - kern_return_t ret; -#ifndef EMUL_VECTOR_COUNT - vm_offset_t *emulation_vector; - int n; -#else - vm_offset_t emulation_vector[EMUL_VECTOR_COUNT]; - int n = EMUL_VECTOR_COUNT; -#endif - int i; - int vector_start; - - ret = task_get_emulation_vector (task, - &vector_start, -#ifndef EMUL_VECTOR_COUNT - &emulation_vector, -#else - emulation_vector, -#endif - &n); - CHK ("task_get_emulation_vector", ret); - xx_debug ("%d vectors from %d at 0x%08x\n", - n, vector_start, emulation_vector); - - for (i = 0; i < n; i++) - { - vm_offset_t entry = emulation_vector[i]; - - if (EMULATOR_BASE <= entry && entry <= EMULATOR_END) - return TRUE; - else if (entry) - { - static boolean_t informed = FALSE; - if (!informed) - { - warning ("Emulation vector address 0x08%x outside emulator space", - entry); - informed = TRUE; - } - } - } - return FALSE; -} - -/* Map cprocs to kernel threads and vice versa. */ - -void -map_cprocs_to_kernel_threads (gdb_thread_t cprocs, gdb_thread_t mthreads, - int thread_count) -{ - int index; - gdb_thread_t scan; - boolean_t all_mapped = TRUE; - LONGEST stack_base; - LONGEST stack_size; - - for (scan = cprocs; scan; scan = scan->next) - { - /* Default to: no kernel thread for this cproc */ - scan->reverse_map = -1; - - /* Check if the cproc is found by its stack */ - for (index = 0; index < thread_count; index++) - { - stack_base = - extract_signed_integer (scan->raw_cproc + CPROC_BASE_OFFSET, - CPROC_BASE_SIZE); - stack_size = - extract_signed_integer (scan->raw_cproc + CPROC_SIZE_OFFSET, - CPROC_SIZE_SIZE); - if ((mthreads + index)->sp > stack_base && - (mthreads + index)->sp <= stack_base + stack_size) - { - (mthreads + index)->cproc = scan; - scan->reverse_map = index; - break; - } - } - all_mapped &= (scan->reverse_map != -1); - } - - /* Check for threads that are currently in the emulator. - * If so, they have a different stack, and the still unmapped - * cprocs may well get mapped to these threads. - * - * If: - * - cproc stack does not match any kernel thread stack pointer - * - there is at least one extra kernel thread - * that has no cproc mapped above. - * - some kernel thread stack pointer points to emulator space - * then we find the user stack pointer saved in the emulator - * stack, and try to map that to the cprocs. - * - * Also set in_emulator for kernel threads. - */ - - if (emulator_present) - { - for (index = 0; index < thread_count; index++) - { - CORE_ADDR emul_sp; - CORE_ADDR usp; - - gdb_thread_t mthread = (mthreads + index); - emul_sp = mthread->sp; - - if (mthread->cproc == NULL && - EMULATOR_BASE <= emul_sp && emul_sp <= EMULATOR_END) - { - mthread->in_emulator = emulator_present; - - if (!all_mapped && cprocs) - { - usp = fetch_usp_from_emulator_stack (emul_sp); - - /* @@ Could be more accurate */ - if (!usp) - error ("Zero stack pointer read from emulator?"); - - /* Try to match this stack pointer to the cprocs that - * don't yet have a kernel thread. - */ - for (scan = cprocs; scan; scan = scan->next) - { - - /* Check is this unmapped CPROC stack contains - * the user stack pointer saved in the - * emulator. - */ - if (scan->reverse_map == -1) - { - stack_base = - extract_signed_integer - (scan->raw_cproc + CPROC_BASE_OFFSET, - CPROC_BASE_SIZE); - stack_size = - extract_signed_integer - (scan->raw_cproc + CPROC_SIZE_OFFSET, - CPROC_SIZE_SIZE); - if (usp > stack_base && - usp <= stack_base + stack_size) - { - mthread->cproc = scan; - scan->reverse_map = index; - break; - } - } - } - } - } - } - } -} - -/* - * Format of the thread_list command - * - * slot mid sel name emul ks susp cstate wired address - */ -#define TL_FORMAT "%-2.2s %5d%c %-10.10s %1.1s%s%-5.5s %-2.2s %-5.5s " - -#define TL_HEADER "\n@ MID Name KState CState Where\n" - -void -print_tl_address (struct ui_file *stream, CORE_ADDR pc) -{ - if (!lookup_minimal_symbol_by_pc (pc)) - fprintf_filtered (stream, local_hex_format (), pc); - else - { - extern int addressprint; - extern int asm_demangle; - - int store = addressprint; - addressprint = 0; - print_address_symbolic (pc, stream, asm_demangle, ""); - addressprint = store; - } -} - -/* For thread names, but also for gdb_message_port external name */ -#define MAX_NAME_LEN 50 - -/* Returns the address of variable NAME or 0 if not found */ -CORE_ADDR -lookup_address_of_variable (char *name) -{ - struct symbol *sym; - CORE_ADDR symaddr = 0; - struct minimal_symbol *msymbol; - - sym = lookup_symbol (name, - (struct block *) NULL, - VAR_NAMESPACE, - (int *) NULL, - (struct symtab **) NULL); - - if (sym) - symaddr = SYMBOL_VALUE (sym); - - if (!symaddr) - { - msymbol = lookup_minimal_symbol (name, NULL, NULL); - - if (msymbol && msymbol->type == mst_data) - symaddr = SYMBOL_VALUE_ADDRESS (msymbol); - } - - return symaddr; -} - -static gdb_thread_t -get_cprocs (void) -{ - gdb_thread_t cproc_head; - gdb_thread_t cproc_copy; - CORE_ADDR their_cprocs; - char *buf; - char *name; - cthread_t cthread; - CORE_ADDR symaddr; - - buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT); - symaddr = lookup_address_of_variable ("cproc_list"); - - if (!symaddr) - { - /* cproc_list is not in a file compiled with debugging - symbols, but don't give up yet */ - - symaddr = lookup_address_of_variable ("cprocs"); - - if (symaddr) - { - static int informed = 0; - if (!informed) - { - informed++; - warning ("Your program is loaded with an old threads library."); - warning ("GDB does not know the old form of threads"); - warning ("so things may not work."); - } - } - } - - /* Stripped or no -lthreads loaded or "cproc_list" is in wrong segment. */ - if (!symaddr) - return NULL; - - /* Get the address of the first cproc in the task */ - if (!mach3_read_inferior (symaddr, - buf, - TARGET_PTR_BIT / HOST_CHAR_BIT)) - error ("Can't read cproc master list at address (0x%x).", symaddr); - their_cprocs = extract_address (buf, TARGET_PTR_BIT / HOST_CHAR_BIT); - - /* Scan the CPROCs in the task. - CPROCs are chained with LIST field, not NEXT field, which - chains mutexes, condition variables and queues */ - - cproc_head = NULL; - - while (their_cprocs != (CORE_ADDR) 0) - { - CORE_ADDR cproc_copy_incarnation; - cproc_copy = (gdb_thread_t) obstack_alloc (cproc_obstack, - sizeof (struct gdb_thread)); - - if (!mach3_read_inferior (their_cprocs, - &cproc_copy->raw_cproc[0], - CPROC_SIZE)) - error ("Can't read next cproc at 0x%x.", their_cprocs); - - their_cprocs = - extract_address (cproc_copy->raw_cproc + CPROC_LIST_OFFSET, - CPROC_LIST_SIZE); - cproc_copy_incarnation = - extract_address (cproc_copy->raw_cproc + CPROC_INCARNATION_OFFSET, - CPROC_INCARNATION_SIZE); - - if (cproc_copy_incarnation == (CORE_ADDR) 0) - cproc_copy->cthread = NULL; - else - { - /* This CPROC has an attached CTHREAD. Get its name */ - cthread = (cthread_t) obstack_alloc (cproc_obstack, - sizeof (struct cthread)); - - if (!mach3_read_inferior (cproc_copy_incarnation, - cthread, - sizeof (struct cthread))) - error ("Can't read next thread at 0x%x.", - cproc_copy_incarnation); - - cproc_copy->cthread = cthread; - - if (cthread->name) - { - name = (char *) obstack_alloc (cproc_obstack, MAX_NAME_LEN); - - if (!mach3_read_inferior (cthread->name, name, MAX_NAME_LEN)) - error ("Can't read next thread's name at 0x%x.", cthread->name); - - cthread->name = name; - } - } - - /* insert in front */ - cproc_copy->next = cproc_head; - cproc_head = cproc_copy; - } - return cproc_head; -} - -#ifndef FETCH_CPROC_STATE -/* - * Check if your machine does not grok the way this routine - * fetches the FP,PC and SP of a cproc that is not - * currently attached to any kernel thread (e.g. its cproc.context - * field points to the place in stack where the context - * is saved). - * - * If it doesn't, define your own routine. - */ -#define FETCH_CPROC_STATE(mth) mach3_cproc_state (mth) - -int -mach3_cproc_state (gdb_thread_t mthread) -{ - int context; - - if (!mthread || !mthread->cproc) - return -1; - - context = extract_signed_integer - (mthread->cproc->raw_cproc + CPROC_CONTEXT_OFFSET, - CPROC_CONTEXT_SIZE); - if (context == 0) - return -1; - - mthread->sp = context + MACHINE_CPROC_SP_OFFSET; - - if (mach3_read_inferior (context + MACHINE_CPROC_PC_OFFSET, - &mthread->pc, - sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) - { - warning ("Can't read cproc pc from inferior"); - return -1; - } - - if (mach3_read_inferior (context + MACHINE_CPROC_FP_OFFSET, - &mthread->fp, - sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) - { - warning ("Can't read cproc fp from inferior"); - return -1; - } - - return 0; -} -#endif /* FETCH_CPROC_STATE */ - - -void -thread_list_command (void) -{ - thread_basic_info_data_t ths; - int thread_count; - gdb_thread_t cprocs; - gdb_thread_t scan; - int index; - char *name; - char selected; - char *wired; - int infoCnt; - kern_return_t ret; - mach_port_t mid_or_port; - gdb_thread_t their_threads; - gdb_thread_t kthread; - - int neworder = 1; - - char *fmt = "There are %d kernel threads in task %d.\n"; - - int tmid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); - - MACH_ERROR_NO_INFERIOR; - - thread_count = fetch_thread_info (inferior_task, - &their_threads); - if (thread_count == -1) - return; - - if (thread_count == 1) - fmt = "There is %d kernel thread in task %d.\n"; - - printf_filtered (fmt, thread_count, tmid); - - puts_filtered (TL_HEADER); - - cprocs = get_cprocs (); - - map_cprocs_to_kernel_threads (cprocs, their_threads, thread_count); - - for (scan = cprocs; scan; scan = scan->next) - { - int mid; - char buf[10]; - char slot[3]; - int cproc_state = - extract_signed_integer - (scan->raw_cproc + CPROC_STATE_OFFSET, CPROC_STATE_SIZE); - - selected = ' '; - - /* a wired cproc? */ - wired = (extract_address (scan->raw_cproc + CPROC_WIRED_OFFSET, - CPROC_WIRED_SIZE) - ? "wired" : ""); - - if (scan->reverse_map != -1) - kthread = (their_threads + scan->reverse_map); - else - kthread = NULL; - - if (kthread) - { - /* These cprocs have a kernel thread */ - - mid = map_port_name_to_mid (kthread->name, MACH_TYPE_THREAD); - - infoCnt = THREAD_BASIC_INFO_COUNT; - - ret = thread_info (kthread->name, - THREAD_BASIC_INFO, - (thread_info_t) & ths, - &infoCnt); - - if (ret != KERN_SUCCESS) - { - warning ("Unable to get basic info on thread %d : %s", - mid, - mach_error_string (ret)); - continue; - } - - /* Who is the first to have more than 100 threads */ - sprintf (slot, "%d", kthread->slotid % 100); - - if (kthread->name == current_thread) - selected = '*'; - - if (ths.suspend_count) - sprintf (buf, "%d", ths.suspend_count); - else - buf[0] = '\000'; - -#if 0 - if (ths.flags & TH_FLAGS_SWAPPED) - strcat (buf, "S"); -#endif - - if (ths.flags & TH_FLAGS_IDLE) - strcat (buf, "I"); - - printf_filtered (TL_FORMAT, - slot, - mid, - selected, - get_thread_name (scan, kthread->slotid), - kthread->in_emulator ? "E" : "", - translate_state (ths.run_state), - buf, - translate_cstate (cproc_state), - wired); - print_tl_address (gdb_stdout, kthread->pc); - } - else - { - /* These cprocs don't have a kernel thread. - * find out the calling frame with - * FETCH_CPROC_STATE. - */ - - struct gdb_thread state; - -#if 0 - /* jtv -> emcmanus: why do you want this here? */ - if (scan->incarnation == NULL) - continue; /* EMcM */ -#endif - - printf_filtered (TL_FORMAT, - "-", - -neworder, /* Pseudo MID */ - selected, - get_thread_name (scan, -neworder), - "", - "-", /* kernel state */ - "", - translate_cstate (cproc_state), - ""); - state.cproc = scan; - - if (FETCH_CPROC_STATE (&state) == -1) - puts_filtered ("???"); - else - print_tl_address (gdb_stdout, state.pc); - - neworder++; - } - puts_filtered ("\n"); - } - - /* Scan for kernel threads without cprocs */ - for (index = 0; index < thread_count; index++) - { - if (!their_threads[index].cproc) - { - int mid; - - char buf[10]; - char slot[3]; - - mach_port_t name = their_threads[index].name; - - mid = map_port_name_to_mid (name, MACH_TYPE_THREAD); - - infoCnt = THREAD_BASIC_INFO_COUNT; - - ret = thread_info (name, - THREAD_BASIC_INFO, - (thread_info_t) & ths, - &infoCnt); - - if (ret != KERN_SUCCESS) - { - warning ("Unable to get basic info on thread %d : %s", - mid, - mach_error_string (ret)); - continue; - } - - sprintf (slot, "%d", index % 100); - - if (name == current_thread) - selected = '*'; - else - selected = ' '; - - if (ths.suspend_count) - sprintf (buf, "%d", ths.suspend_count); - else - buf[0] = '\000'; - -#if 0 - if (ths.flags & TH_FLAGS_SWAPPED) - strcat (buf, "S"); -#endif - - if (ths.flags & TH_FLAGS_IDLE) - strcat (buf, "I"); - - printf_filtered (TL_FORMAT, - slot, - mid, - selected, - get_thread_name (NULL, index), - their_threads[index].in_emulator ? "E" : "", - translate_state (ths.run_state), - buf, - "", /* No cproc state */ - ""); /* Can't be wired */ - print_tl_address (gdb_stdout, their_threads[index].pc); - puts_filtered ("\n"); - } - } - - obstack_free (cproc_obstack, 0); - obstack_init (cproc_obstack); -} - -void -thread_select_command (char *args, int from_tty) -{ - int mid; - thread_array_t thread_list; - int thread_count; - kern_return_t ret; - int is_slot = 0; - - MACH_ERROR_NO_INFERIOR; - - if (!args) - error_no_arg ("MID or @SLOTNUMBER to specify a thread to select"); - - while (*args == ' ' || *args == '\t') - args++; - - if (*args == '@') - { - is_slot++; - args++; - } - - mid = atoi (args); - - if (mid == 0) - if (!is_slot || *args != '0') /* Rudimentary checks */ - error ("You must select threads by MID or @SLOTNUMBER"); - - if (select_thread (inferior_task, mid, is_slot ? 2 : 1) != KERN_SUCCESS) - return; - - if (from_tty) - printf_filtered ("Thread %d selected\n", - is_slot ? map_port_name_to_mid (current_thread, - MACH_TYPE_THREAD) : mid); -} - -thread_trace (mach_port_t thread, boolean_t set) -{ - int flavor = TRACE_FLAVOR; - unsigned int stateCnt = TRACE_FLAVOR_SIZE; - kern_return_t ret; - thread_state_data_t state; - - if (!MACH_PORT_VALID (thread)) - { - warning ("thread_trace: invalid thread"); - return; - } - - if (must_suspend_thread) - setup_thread (thread, 1); - - ret = thread_get_state (thread, flavor, state, &stateCnt); - CHK ("thread_trace: error reading thread state", ret); - - if (set) - { - TRACE_SET (thread, state); - } - else - { - if (!TRACE_CLEAR (thread, state)) - { - if (must_suspend_thread) - setup_thread (thread, 0); - return; - } - } - - ret = thread_set_state (thread, flavor, state, stateCnt); - CHK ("thread_trace: error writing thread state", ret); - if (must_suspend_thread) - setup_thread (thread, 0); -} - -#ifdef FLUSH_INFERIOR_CACHE - -/* When over-writing code on some machines the I-Cache must be flushed - explicitly, because it is not kept coherent by the lazy hardware. - This definitely includes breakpoints, for instance, or else we - end up looping in mysterious Bpt traps */ - -flush_inferior_icache (CORE_ADDR pc, int amount) -{ - vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH; - kern_return_t ret; - - ret = vm_machine_attribute (inferior_task, - pc, - amount, - MATTR_CACHE, - &flush); - if (ret != KERN_SUCCESS) - warning ("Error flushing inferior's cache : %s", - mach_error_string (ret)); -} -#endif /* FLUSH_INFERIOR_CACHE */ - - -static -suspend_all_threads (int from_tty) -{ - kern_return_t ret; - thread_array_t thread_list; - int thread_count, index; - int infoCnt; - thread_basic_info_data_t th_info; - - - ret = task_threads (inferior_task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - warning ("Could not suspend inferior threads."); - m3_kill_inferior (); - throw_exception (RETURN_ERROR); - } - - for (index = 0; index < thread_count; index++) - { - int mid; - - mid = map_port_name_to_mid (thread_list[index], - MACH_TYPE_THREAD); - - ret = thread_suspend (thread_list[index]); - - if (ret != KERN_SUCCESS) - warning ("Error trying to suspend thread %d : %s", - mid, mach_error_string (ret)); - - if (from_tty) - { - infoCnt = THREAD_BASIC_INFO_COUNT; - ret = thread_info (thread_list[index], - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("suspend can't get thread info", ret); - - warning ("Thread %d suspend count is %d", - mid, th_info.suspend_count); - } - } - - consume_send_rights (thread_list, thread_count); - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (int))); - CHK ("Error trying to deallocate thread list", ret); -} - -void -thread_suspend_command (char *args, int from_tty) -{ - kern_return_t ret; - int mid; - mach_port_t saved_thread; - int infoCnt; - thread_basic_info_data_t th_info; - - MACH_ERROR_NO_INFERIOR; - - if (!strcasecmp (args, "all")) - { - suspend_all_threads (from_tty); - return; - } - - saved_thread = current_thread; - - mid = parse_thread_id (args, 0, 0); - - if (mid < 0) - error ("You can suspend only existing kernel threads with MID or @SLOTNUMBER"); - - if (mid == 0) - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) - { - if (current_thread) - current_thread = saved_thread; - error ("Could not select thread %d", mid); - } - - ret = thread_suspend (current_thread); - if (ret != KERN_SUCCESS) - warning ("thread_suspend failed : %s", - mach_error_string (ret)); - - infoCnt = THREAD_BASIC_INFO_COUNT; - ret = thread_info (current_thread, - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("suspend can't get thread info", ret); - - warning ("Thread %d suspend count is %d", mid, th_info.suspend_count); - - current_thread = saved_thread; -} - -resume_all_threads (int from_tty) -{ - kern_return_t ret; - thread_array_t thread_list; - int thread_count, index; - int mid; - int infoCnt; - thread_basic_info_data_t th_info; - - ret = task_threads (inferior_task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - m3_kill_inferior (); - error ("task_threads", mach_error_string (ret)); - } - - for (index = 0; index < thread_count; index++) - { - infoCnt = THREAD_BASIC_INFO_COUNT; - ret = thread_info (thread_list[index], - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("resume_all can't get thread info", ret); - - mid = map_port_name_to_mid (thread_list[index], - MACH_TYPE_THREAD); - - if (!th_info.suspend_count) - { - if (mid != -1 && from_tty) - warning ("Thread %d is not suspended", mid); - continue; - } - - ret = thread_resume (thread_list[index]); - - if (ret != KERN_SUCCESS) - warning ("Error trying to resume thread %d : %s", - mid, mach_error_string (ret)); - else if (mid != -1 && from_tty) - warning ("Thread %d suspend count is %d", - mid, --th_info.suspend_count); - } - - consume_send_rights (thread_list, thread_count); - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (int))); - CHK ("Error trying to deallocate thread list", ret); -} - -void -thread_resume_command (char *args, int from_tty) -{ - int mid; - mach_port_t saved_thread; - kern_return_t ret; - thread_basic_info_data_t th_info; - int infoCnt = THREAD_BASIC_INFO_COUNT; - - MACH_ERROR_NO_INFERIOR; - - if (!strcasecmp (args, "all")) - { - resume_all_threads (from_tty); - return; - } - - saved_thread = current_thread; - - mid = parse_thread_id (args, 0, 0); - - if (mid < 0) - error ("You can resume only existing kernel threads with MID or @SLOTNUMBER"); - - if (mid == 0) - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) - { - if (current_thread) - current_thread = saved_thread; - throw_exception (RETURN_ERROR); - } - - ret = thread_info (current_thread, - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("resume can't get thread info", ret); - - if (!th_info.suspend_count) - { - warning ("Thread %d is not suspended", mid); - goto out; - } - - ret = thread_resume (current_thread); - if (ret != KERN_SUCCESS) - warning ("thread_resume failed : %s", - mach_error_string (ret)); - else - { - th_info.suspend_count--; - warning ("Thread %d suspend count is %d", mid, th_info.suspend_count); - } - -out: - current_thread = saved_thread; -} - -void -thread_kill_command (char *args, int from_tty) -{ - int mid; - kern_return_t ret; - int thread_count; - thread_array_t thread_table; - int index; - mach_port_t thread_to_kill = MACH_PORT_NULL; - - - MACH_ERROR_NO_INFERIOR; - - if (!args) - error_no_arg ("thread mid to kill from the inferior task"); - - mid = parse_thread_id (args, 0, 0); - - if (mid < 0) - error ("You can kill only existing kernel threads with MID or @SLOTNUMBER"); - - if (mid) - { - ret = machid_mach_port (mid_server, mid_auth, mid, &thread_to_kill); - CHK ("thread_kill_command: machid_mach_port map failed", ret); - } - else - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - - /* Don't allow gdb to kill *any* thread in the system. Use mkill program for that */ - ret = task_threads (inferior_task, &thread_table, &thread_count); - CHK ("Error getting inferior's thread list", ret); - - if (thread_to_kill == current_thread) - { - ret = thread_terminate (thread_to_kill); - CHK ("Thread could not be terminated", ret); - - if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS) - warning ("Last thread was killed, use \"kill\" command to kill task"); - } - else - for (index = 0; index < thread_count; index++) - if (thread_table[index] == thread_to_kill) - { - ret = thread_terminate (thread_to_kill); - CHK ("Thread could not be terminated", ret); - } - - if (thread_count > 1) - consume_send_rights (thread_table, thread_count); - - ret = vm_deallocate (mach_task_self (), (vm_address_t) thread_table, - (thread_count * sizeof (mach_port_t))); - CHK ("Error trying to deallocate thread list", ret); - - warning ("Thread %d killed", mid); -} - - -/* Task specific commands; add more if you like */ - -void -task_resume_command (char *args, int from_tty) -{ - kern_return_t ret; - task_basic_info_data_t ta_info; - int infoCnt = TASK_BASIC_INFO_COUNT; - int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); - - MACH_ERROR_NO_INFERIOR; - - /* Would be trivial to change, but is it desirable? */ - if (args) - error ("Currently gdb can resume only it's inferior task"); - - ret = task_info (inferior_task, - TASK_BASIC_INFO, - (task_info_t) & ta_info, - &infoCnt); - CHK ("task_resume_command: task_info failed", ret); - - if (ta_info.suspend_count == 0) - error ("Inferior task %d is not suspended", mid); - else if (ta_info.suspend_count == 1 && - from_tty && - !query ("Suspend count is now 1. Do you know what you are doing? ")) - error ("Task not resumed"); - - ret = task_resume (inferior_task); - CHK ("task_resume_command: task_resume", ret); - - if (ta_info.suspend_count == 1) - { - warning ("Inferior task %d is no longer suspended", mid); - must_suspend_thread = 1; - /* @@ This is not complete: Registers change all the time when not - suspended! */ - registers_changed (); - } - else - warning ("Inferior task %d suspend count is now %d", - mid, ta_info.suspend_count - 1); -} - - -void -task_suspend_command (char *args, int from_tty) -{ - kern_return_t ret; - task_basic_info_data_t ta_info; - int infoCnt = TASK_BASIC_INFO_COUNT; - int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); - - MACH_ERROR_NO_INFERIOR; - - /* Would be trivial to change, but is it desirable? */ - if (args) - error ("Currently gdb can suspend only it's inferior task"); - - ret = task_suspend (inferior_task); - CHK ("task_suspend_command: task_suspend", ret); - - must_suspend_thread = 0; - - ret = task_info (inferior_task, - TASK_BASIC_INFO, - (task_info_t) & ta_info, - &infoCnt); - CHK ("task_suspend_command: task_info failed", ret); - - warning ("Inferior task %d suspend count is now %d", - mid, ta_info.suspend_count); -} - -static char * -get_size (int bytes) -{ - static char size[30]; - int zz = bytes / 1024; - - if (zz / 1024) - sprintf (size, "%-2.1f M", ((float) bytes) / (1024.0 * 1024.0)); - else - sprintf (size, "%d K", zz); - - return size; -} - -/* Does this require the target task to be suspended?? I don't think so. */ -void -task_info_command (char *args, int from_tty) -{ - int mid = -5; - mach_port_t task; - kern_return_t ret; - task_basic_info_data_t ta_info; - int infoCnt = TASK_BASIC_INFO_COUNT; - int page_size = round_page (1); - int thread_count = 0; - - if (MACH_PORT_VALID (inferior_task)) - mid = map_port_name_to_mid (inferior_task, - MACH_TYPE_TASK); - - task = inferior_task; - - if (args) - { - int tmid = atoi (args); - - if (tmid <= 0) - error ("Invalid mid %d for task info", tmid); - - if (tmid != mid) - { - mid = tmid; - ret = machid_mach_port (mid_server, mid_auth, tmid, &task); - CHK ("task_info_command: machid_mach_port map failed", ret); - } - } - - if (mid < 0) - error ("You have to give the task MID as an argument"); - - ret = task_info (task, - TASK_BASIC_INFO, - (task_info_t) & ta_info, - &infoCnt); - CHK ("task_info_command: task_info failed", ret); - - printf_filtered ("\nTask info for task %d:\n\n", mid); - printf_filtered (" Suspend count : %d\n", ta_info.suspend_count); - printf_filtered (" Base priority : %d\n", ta_info.base_priority); - printf_filtered (" Virtual size : %s\n", get_size (ta_info.virtual_size)); - printf_filtered (" Resident size : %s\n", get_size (ta_info.resident_size)); - - { - thread_array_t thread_list; - - ret = task_threads (task, &thread_list, &thread_count); - CHK ("task_info_command: task_threads", ret); - - printf_filtered (" Thread count : %d\n", thread_count); - - consume_send_rights (thread_list, thread_count); - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (int))); - CHK ("Error trying to deallocate thread list", ret); - } - if (have_emulator_p (task)) - printf_filtered (" Emulator at : 0x%x..0x%x\n", - EMULATOR_BASE, EMULATOR_END); - else - printf_filtered (" No emulator.\n"); - - if (thread_count && task == inferior_task) - printf_filtered ("\nUse the \"thread list\" command to see the threads\n"); -} - -/* You may either FORWARD the exception to the inferior, or KEEP - * it and return to GDB command level. - * - * exception mid [ forward | keep ] - */ - -static void -exception_command (char *args, int from_tty) -{ - char *scan = args; - int exception; - int len; - - if (!args) - error_no_arg ("exception number action"); - - while (*scan == ' ' || *scan == '\t') - scan++; - - if ('0' <= *scan && *scan <= '9') - while ('0' <= *scan && *scan <= '9') - scan++; - else - error ("exception number action"); - - exception = atoi (args); - if (exception <= 0 || exception > MAX_EXCEPTION) - error ("Allowed exception numbers are in range 1..%d", - MAX_EXCEPTION); - - if (*scan != ' ' && *scan != '\t') - error ("exception number must be followed by a space"); - else - while (*scan == ' ' || *scan == '\t') - scan++; - - args = scan; - len = 0; - while (*scan) - { - len++; - scan++; - } - - if (!len) - error ("exception number action"); - - if (!strncasecmp (args, "forward", len)) - exception_map[exception].forward = TRUE; - else if (!strncasecmp (args, "keep", len)) - exception_map[exception].forward = FALSE; - else - error ("exception action is either \"keep\" or \"forward\""); -} - -static void -print_exception_info (int exception) -{ - boolean_t forward = exception_map[exception].forward; - - printf_filtered ("%s\t(%d): ", exception_map[exception].name, - exception); - if (!forward) - if (exception_map[exception].sigmap != SIG_UNKNOWN) - printf_filtered ("keep and handle as signal %d\n", - exception_map[exception].sigmap); - else - printf_filtered ("keep and handle as unknown signal %d\n", - exception_map[exception].sigmap); - else - printf_filtered ("forward exception to inferior\n"); -} - -void -exception_info (char *args, int from_tty) -{ - int exception; - - if (!args) - for (exception = 1; exception <= MAX_EXCEPTION; exception++) - print_exception_info (exception); - else - { - exception = atoi (args); - - if (exception <= 0 || exception > MAX_EXCEPTION) - error ("Invalid exception number, values from 1 to %d allowed", - MAX_EXCEPTION); - print_exception_info (exception); - } -} - -/* Check for actions for mach exceptions. - */ -mach3_exception_actions (WAITTYPE *w, boolean_t force_print_only, char *who) -{ - boolean_t force_print = FALSE; - - - if (force_print_only || - exception_map[stop_exception].sigmap == SIG_UNKNOWN) - force_print = TRUE; - else - WSETSTOP (*w, exception_map[stop_exception].sigmap); - - if (exception_map[stop_exception].print || force_print) - { - target_terminal_ours (); - - printf_filtered ("\n%s received %s exception : ", - who, - exception_map[stop_exception].name); - - wrap_here (" "); - - switch (stop_exception) - { - case EXC_BAD_ACCESS: - printf_filtered ("referencing address 0x%x : %s\n", - stop_subcode, - mach_error_string (stop_code)); - break; - case EXC_BAD_INSTRUCTION: - printf_filtered - ("illegal or undefined instruction. code %d subcode %d\n", - stop_code, stop_subcode); - break; - case EXC_ARITHMETIC: - printf_filtered ("code %d\n", stop_code); - break; - case EXC_EMULATION: - printf_filtered ("code %d subcode %d\n", stop_code, stop_subcode); - break; - case EXC_SOFTWARE: - printf_filtered ("%s specific, code 0x%x\n", - stop_code < 0xffff ? "hardware" : "os emulation", - stop_code); - break; - case EXC_BREAKPOINT: - printf_filtered ("type %d (machine dependent)\n", - stop_code); - break; - default: - internal_error (__FILE__, __LINE__, - "Unknown exception"); - } - } -} - -setup_notify_port (int create_new) -{ - kern_return_t ret; - - if (MACH_PORT_VALID (our_notify_port)) - { - ret = mach_port_destroy (mach_task_self (), our_notify_port); - CHK ("Could not destroy our_notify_port", ret); - } - - our_notify_port = MACH_PORT_NULL; - notify_chain = (port_chain_t) NULL; - port_chain_destroy (port_chain_obstack); - - if (create_new) - { - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &our_notify_port); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, - "Creating notify port %s", mach_error_string (ret)); - - ret = mach_port_move_member (mach_task_self (), - our_notify_port, - inferior_wait_port_set); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, - "initial move member %s", mach_error_string (ret)); - } -} - -/* - * Register our message port to the net name server - * - * Currently used only by the external stop-gdb program - * since ^C does not work if you would like to enter - * gdb command level while debugging your program. - * - * NOTE: If the message port is sometimes used for other - * purposes also, the NAME must not be a guessable one. - * Then, there should be a way to change it. - */ - -char registered_name[MAX_NAME_LEN]; - -void -message_port_info (char *args, int from_tty) -{ - if (registered_name[0]) - printf_filtered ("gdb's message port name: '%s'\n", - registered_name); - else - printf_filtered ("gdb's message port is not currently registered\n"); -} - -void -gdb_register_port (char *name, mach_port_t port) -{ - kern_return_t ret; - static int already_signed = 0; - int len; - - if (!MACH_PORT_VALID (port) || !name || !*name) - { - warning ("Invalid registration request"); - return; - } - - if (!already_signed) - { - ret = mach_port_insert_right (mach_task_self (), - our_message_port, - our_message_port, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("Failed to create a signature to our_message_port", ret); - already_signed = 1; - } - else if (already_signed > 1) - { - ret = netname_check_out (name_server_port, - registered_name, - our_message_port); - CHK ("Failed to check out gdb's message port", ret); - registered_name[0] = '\000'; - already_signed = 1; - } - - ret = netname_check_in (name_server_port, /* Name server port */ - name, /* Name of service */ - our_message_port, /* Signature */ - port); /* Creates a new send right */ - CHK ("Failed to check in the port", ret); - - len = 0; - while (len < MAX_NAME_LEN && *(name + len)) - { - registered_name[len] = *(name + len); - len++; - } - registered_name[len] = '\000'; - already_signed = 2; -} - -struct cmd_list_element *cmd_thread_list; -struct cmd_list_element *cmd_task_list; - -/*ARGSUSED */ -static void -thread_command (char *arg, int from_tty) -{ - printf_unfiltered ("\"thread\" must be followed by the name of a thread command.\n"); - help_list (cmd_thread_list, "thread ", -1, gdb_stdout); -} - -/*ARGSUSED */ -static void -task_command (char *arg, int from_tty) -{ - printf_unfiltered ("\"task\" must be followed by the name of a task command.\n"); - help_list (cmd_task_list, "task ", -1, gdb_stdout); -} - -add_mach_specific_commands (void) -{ - /* Thread handling commands */ - - /* FIXME: Move our thread support into the generic thread.c stuff so we - can share that code. */ - add_prefix_cmd ("mthread", class_stack, thread_command, - "Generic command for handling Mach threads in the debugged task.", - &cmd_thread_list, "thread ", 0, &cmdlist); - - add_com_alias ("th", "mthread", class_stack, 1); - - add_cmd ("select", class_stack, thread_select_command, - "Select and print MID of the selected thread", - &cmd_thread_list); - add_cmd ("list", class_stack, thread_list_command, - "List info of task's threads. Selected thread is marked with '*'", - &cmd_thread_list); - add_cmd ("suspend", class_run, thread_suspend_command, - "Suspend one or all of the threads in the selected task.", - &cmd_thread_list); - add_cmd ("resume", class_run, thread_resume_command, - "Resume one or all of the threads in the selected task.", - &cmd_thread_list); - add_cmd ("kill", class_run, thread_kill_command, - "Kill the specified thread MID from inferior task.", - &cmd_thread_list); -#if 0 - /* The rest of this support (condition_thread) was not merged. It probably - should not be merged in this form, but instead added to the generic GDB - thread support. */ - add_cmd ("break", class_breakpoint, condition_thread, - "Breakpoint N will only be effective for thread MID or @SLOT\n\ - If MID/@SLOT is omitted allow all threads to break at breakpoint", - &cmd_thread_list); -#endif - /* Thread command shorthands (for backward compatibility) */ - add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist); - add_alias_cmd ("tl", "mthread list", 0, 0, &cmdlist); - - /* task handling commands */ - - add_prefix_cmd ("task", class_stack, task_command, - "Generic command for handling debugged task.", - &cmd_task_list, "task ", 0, &cmdlist); - - add_com_alias ("ta", "task", class_stack, 1); - - add_cmd ("suspend", class_run, task_suspend_command, - "Suspend the inferior task.", - &cmd_task_list); - add_cmd ("resume", class_run, task_resume_command, - "Resume the inferior task.", - &cmd_task_list); - add_cmd ("info", no_class, task_info_command, - "Print information about the specified task.", - &cmd_task_list); - - /* Print my message port name */ - - add_info ("message-port", message_port_info, - "Returns the name of gdb's message port in the netnameserver"); - - /* Exception commands */ - - add_info ("exceptions", exception_info, - "What debugger does when program gets various exceptions.\n\ -Specify an exception number as argument to print info on that\n\ -exception only."); - - add_com ("exception", class_run, exception_command, - "Specify how to handle an exception.\n\ -Args are exception number followed by \"forward\" or \"keep\".\n\ -`Forward' means forward the exception to the program's normal exception\n\ -handler.\n\ -`Keep' means reenter debugger if this exception happens, and GDB maps\n\ -the exception to some signal (see info exception)\n\ -Normally \"keep\" is used to return to GDB on exception."); -} - -kern_return_t -do_mach_notify_dead_name (mach_port_t notify, mach_port_t name) -{ - kern_return_t kr = KERN_SUCCESS; - - /* Find the thing that notified */ - port_chain_t element = port_chain_member (notify_chain, name); - - /* Take name of from unreceived dead name notification list */ - notify_chain = port_chain_delete (notify_chain, name); - - if (!element) - error ("Received a dead name notify from unchained port (0x%x)", name); - - switch (element->type) - { - - case MACH_TYPE_THREAD: - target_terminal_ours_for_output (); - if (name == current_thread) - { - printf_filtered ("\nCurrent thread %d died", element->mid); - current_thread = MACH_PORT_NULL; - } - else - printf_filtered ("\nThread %d died", element->mid); - - break; - - case MACH_TYPE_TASK: - target_terminal_ours_for_output (); - if (name != inferior_task) - printf_filtered ("Task %d died, but it was not the selected task", - element->mid); - else - { - printf_filtered ("Current task %d died", element->mid); - - mach_port_destroy (mach_task_self (), name); - inferior_task = MACH_PORT_NULL; - - if (notify_chain) - warning ("There were still unreceived dead_name_notifications???"); - - /* Destroy the old notifications */ - setup_notify_port (0); - - } - break; - - default: - error ("Unregistered dead_name 0x%x notification received. Type is %d, mid is 0x%x", - name, element->type, element->mid); - break; - } - - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name) -{ - warning ("do_mach_notify_msg_accepted : notify %x, name %x", - notify, name); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t mscount) -{ - warning ("do_mach_notify_no_senders : notify %x, mscount %x", - notify, mscount); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name) -{ - warning ("do_mach_notify_port_deleted : notify %x, name %x", - notify, name); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t rights) -{ - warning ("do_mach_notify_port_destroyed : notify %x, rights %x", - notify, rights); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_send_once (mach_port_t notify) -{ -#ifdef DUMP_SYSCALL - /* MANY of these are generated. */ - warning ("do_mach_notify_send_once : notify %x", - notify); -#endif - return KERN_SUCCESS; -} - -/* Kills the inferior. It's gone when you call this */ -static void -kill_inferior_fast (void) -{ - WAITTYPE w; - - if (PIDGET (inferior_ptid) == 0 || PIDGET (inferior_ptid) == 1) - return; - - /* kill() it, since the Unix server does not otherwise notice when - * killed with task_terminate(). - */ - if (PIDGET (inferior_ptid) > 0) - kill (PIDGET (inferior_ptid), SIGKILL); - - /* It's propably terminate already */ - (void) task_terminate (inferior_task); - - inferior_task = MACH_PORT_NULL; - current_thread = MACH_PORT_NULL; - - wait3 (&w, WNOHANG, 0); - - setup_notify_port (0); -} - -static void -m3_kill_inferior (void) -{ - kill_inferior_fast (); - target_mourn_inferior (); -} - -/* Clean up after the inferior dies. */ - -static void -m3_mourn_inferior (void) -{ - unpush_target (&m3_ops); - generic_mourn_inferior (); -} - - -/* Fork an inferior process, and start debugging it. */ - -static void -m3_create_inferior (char *exec_file, char *allargs, char **env) -{ - fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL, NULL); - /* We are at the first instruction we care about. */ - /* Pedal to the metal... */ - proceed ((CORE_ADDR) -1, 0, 0); -} - -/* Mark our target-struct as eligible for stray "run" and "attach" - commands. */ -static int -m3_can_run (void) -{ - return 1; -} - -/* Mach 3.0 does not need ptrace for anything - * Make sure nobody uses it on mach. - */ -ptrace (int a, int b, int c, int d) -{ - error ("Lose, Lose! Somebody called ptrace\n"); -} - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -m3_resume (ptid_t ptid, int step, enum target_signal signal) -{ - kern_return_t ret; - - if (step) - { - thread_basic_info_data_t th_info; - unsigned int infoCnt = THREAD_BASIC_INFO_COUNT; - - /* There is no point in single stepping when current_thread - * is dead. - */ - if (!MACH_PORT_VALID (current_thread)) - error ("No thread selected; can not single step"); - - /* If current_thread is suspended, tracing it would never return. - */ - ret = thread_info (current_thread, - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("child_resume: can't get thread info", ret); - - if (th_info.suspend_count) - error ("Can't trace a suspended thread. Use \"thread resume\" command to resume it"); - } - - vm_read_cache_valid = FALSE; - - if (signal && PIDGET (inferior_ptid) > 0) /* Do not signal, if attached by MID */ - kill (PIDGET (inferior_ptid), target_signal_to_host (signal)); - - if (step) - { - suspend_all_threads (0); - - setup_single_step (current_thread, TRUE); - - ret = thread_resume (current_thread); - CHK ("thread_resume", ret); - } - - ret = task_resume (inferior_task); - if (ret == KERN_FAILURE) - warning ("Task was not suspended"); - else - CHK ("Resuming task", ret); - - /* HACK HACK This is needed by the multiserver system HACK HACK */ - while ((ret = task_resume (inferior_task)) == KERN_SUCCESS) - /* make sure it really runs */ ; - /* HACK HACK This is needed by the multiserver system HACK HACK */ -} - -#ifdef ATTACH_DETACH - -/* Start debugging the process with the given task */ -void -task_attach (task_t tid) -{ - kern_return_t ret; - inferior_task = tid; - - ret = task_suspend (inferior_task); - CHK ("task_attach: task_suspend", ret); - - must_suspend_thread = 0; - - setup_notify_port (1); - - request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK); - - setup_exception_port (); - - emulator_present = have_emulator_p (inferior_task); - - attach_flag = 1; -} - -/* Well, we can call error also here and leave the - * target stack inconsistent. Sigh. - * Fix this sometime (the only way to fail here is that - * the task has no threads at all, which is rare, but - * possible; or if the target task has died, which is also - * possible, but unlikely, since it has been suspended. - * (Someone must have killed it)) - */ -void -attach_to_thread (void) -{ - if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS) - error ("Could not select any threads to attach to"); -} - -mid_attach (int mid) -{ - kern_return_t ret; - - ret = machid_mach_port (mid_server, mid_auth, mid, &inferior_task); - CHK ("mid_attach: machid_mach_port", ret); - - task_attach (inferior_task); - - return mid; -} - -/* - * Start debugging the process whose unix process-id is PID. - * A negative "pid" value is legal and signifies a mach_id not a unix pid. - * - * Prevent (possible unwanted) dangerous operations by enabled users - * like "atta 0" or "atta foo" (equal to the previous :-) and - * "atta pidself". Anyway, the latter is allowed by specifying a MID. - */ -static int -m3_do_attach (int pid) -{ - kern_return_t ret; - - if (pid == 0) - error ("MID=0, Debugging the master unix server does not compute"); - - /* Foo. This assumes gdb has a unix pid */ - if (pid == getpid ()) - error ("I will debug myself only by mid. (Gdb would suspend itself!)"); - - if (pid < 0) - { - mid_attach (-(pid)); - - /* inferior_ptid will be NEGATIVE! */ - inferior_ptid = pid_to_ptid (pid); - - return PIDGET (inferior_ptid); - } - - inferior_task = task_by_pid (pid); - if (!MACH_PORT_VALID (inferior_task)) - error ("Cannot map Unix pid %d to Mach task port", pid); - - task_attach (inferior_task); - - inferior_ptid = pid_to_ptid (pid); - - return PIDGET (inferior_ptid); -} - -/* Attach to process PID, then initialize for debugging it - and wait for the trace-trap that results from attaching. */ - -static void -m3_attach (char *args, int from_tty) -{ - char *exec_file; - int pid; - - if (!args) - error_no_arg ("process-id to attach"); - - pid = atoi (args); - - if (pid == getpid ()) /* Trying to masturbate? */ - error ("I refuse to debug myself!"); - - if (from_tty) - { - exec_file = (char *) get_exec_file (0); - - if (exec_file) - printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, - target_pid_to_str (pid_to_ptid (pid))); - else - printf_unfiltered ("Attaching to %s\n", - target_pid_to_str (pid_to_ptid (pid))); - - gdb_flush (gdb_stdout); - } - - m3_do_attach (pid_to_ptid (pid)); - inferior_ptid = pid_to_ptid (pid); - push_target (&m3_ops); -} - -void -deallocate_inferior_ports (void) -{ - kern_return_t ret; - thread_array_t thread_list; - int thread_count, index; - - if (!MACH_PORT_VALID (inferior_task)) - return; - - ret = task_threads (inferior_task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - warning ("deallocate_inferior_ports: task_threads", - mach_error_string (ret)); - return; - } - - /* Get rid of send rights to task threads */ - for (index = 0; index < thread_count; index++) - { - int rights; - ret = mach_port_get_refs (mach_task_self (), - thread_list[index], - MACH_PORT_RIGHT_SEND, - &rights); - CHK ("deallocate_inferior_ports: get refs", ret); - - if (rights > 0) - { - ret = mach_port_mod_refs (mach_task_self (), - thread_list[index], - MACH_PORT_RIGHT_SEND, - -rights); - CHK ("deallocate_inferior_ports: mod refs", ret); - } - } - - ret = mach_port_mod_refs (mach_task_self (), - inferior_exception_port, - MACH_PORT_RIGHT_RECEIVE, - -1); - CHK ("deallocate_inferior_ports: cannot get rid of exception port", ret); - - ret = mach_port_deallocate (mach_task_self (), - inferior_task); - CHK ("deallocate_task_port: deallocating inferior_task", ret); - - current_thread = MACH_PORT_NULL; - inferior_task = MACH_PORT_NULL; -} - -/* Stop debugging the process whose number is PID - and continue it with signal number SIGNAL. - SIGNAL = 0 means just continue it. */ - -static void -m3_do_detach (int signal) -{ - kern_return_t ret; - - MACH_ERROR_NO_INFERIOR; - - if (current_thread != MACH_PORT_NULL) - { - /* Store the gdb's view of the thread we are deselecting - * before we detach. - * @@ I am really not sure if this is ever needeed. - */ - target_prepare_to_store (); - target_store_registers (-1); - } - - ret = task_set_special_port (inferior_task, - TASK_EXCEPTION_PORT, - inferior_old_exception_port); - CHK ("task_set_special_port", ret); - - /* Discard all requested notifications */ - setup_notify_port (0); - - if (remove_breakpoints ()) - warning ("Could not remove breakpoints when detaching"); - - if (signal && PIDGET (inferior_ptid) > 0) - kill (PIDGET (inferior_ptid), signal); - - /* the task might be dead by now */ - (void) task_resume (inferior_task); - - deallocate_inferior_ports (); - - attach_flag = 0; -} - -/* Take a program previously attached to and detaches it. - The program resumes execution and will no longer stop - on signals, etc. We'd better not have left any breakpoints - in the program or it'll die when it hits one. For this - to work, it may be necessary for the process to have been - previously attached. It *might* work if the program was - started via fork. */ - -static void -m3_detach (char *args, int from_tty) -{ - int siggnal = 0; - - if (from_tty) - { - char *exec_file = get_exec_file (0); - if (exec_file == 0) - exec_file = ""; - printf_unfiltered ("Detaching from program: %s %s\n", - exec_file, target_pid_to_str (inferior_ptid)); - gdb_flush (gdb_stdout); - } - if (args) - siggnal = atoi (args); - - m3_do_detach (siggnal); - inferior_ptid = null_ptid; - unpush_target (&m3_ops); /* Pop out of handling an inferior */ -} -#endif /* ATTACH_DETACH */ - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -m3_prepare_to_store (void) -{ -#ifdef CHILD_PREPARE_TO_STORE - CHILD_PREPARE_TO_STORE (); -#endif -} - -/* Print status information about what we're accessing. */ - -static void -m3_files_info (struct target_ops *ignore) -{ - /* FIXME: should print MID and all that crap. */ - printf_unfiltered ("\tUsing the running image of %s %s.\n", - attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); -} - -static void -m3_open (char *arg, int from_tty) -{ - error ("Use the \"run\" command to start a Unix child process."); -} - -#ifdef DUMP_SYSCALL -#define STR(x) #x - -char *bsd1_names[] = -{ - "execve", - "fork", - "take_signal", - "sigreturn", - "getrusage", - "chdir", - "chroot", - "open", - "creat", - "mknod", - "link", - "symlink", - "unlink", - "access", - "stat", - "readlink", - "chmod", - "chown", - "utimes", - "truncate", - "rename", - "mkdir", - "rmdir", - "xutimes", - "mount", - "umount", - "acct", - "setquota", - "write_short", - "write_long", - "send_short", - "send_long", - "sendto_short", - "sendto_long", - "select", - "task_by_pid", - "recvfrom_short", - "recvfrom_long", - "setgroups", - "setrlimit", - "sigvec", - "sigstack", - "settimeofday", - "adjtime", - "setitimer", - "sethostname", - "bind", - "accept", - "connect", - "setsockopt", - "getsockopt", - "getsockname", - "getpeername", - "init_process", - "table_set", - "table_get", - "pioctl", - "emulator_error", - "readwrite", - "share_wakeup", - 0, - "maprw_request_it", - "maprw_release_it", - "maprw_remap", - "pid_by_task", -}; - -int bsd1_nnames = sizeof (bsd1_names) / sizeof (bsd1_names[0]); - -char * -name_str (int name, char *buf) -{ - switch (name) - { - case MACH_MSG_TYPE_BOOLEAN: - return "boolean"; - case MACH_MSG_TYPE_INTEGER_16: - return "short"; - case MACH_MSG_TYPE_INTEGER_32: - return "long"; - case MACH_MSG_TYPE_CHAR: - return "char"; - case MACH_MSG_TYPE_BYTE: - return "byte"; - case MACH_MSG_TYPE_REAL: - return "real"; - case MACH_MSG_TYPE_STRING: - return "string"; - default: - sprintf (buf, "%d", name); - return buf; - } -} - -char * -id_str (int id, char *buf) -{ - char *p; - if (id >= 101000 && id < 101000 + bsd1_nnames) - { - if (p = bsd1_names[id - 101000]) - return p; - } - if (id == 102000) - return "psignal_retry"; - if (id == 100000) - return "syscall"; - sprintf (buf, "%d", id); - return buf; -} - -print_msg (mach_msg_header_t *mp) -{ - char *fmt_x = "%20s : 0x%08x\n"; - char *fmt_d = "%20s : %10d\n"; - char *fmt_s = "%20s : %s\n"; - char buf[100]; - - puts_filtered ("\n"); -#define pr(fmt,h,x) printf_filtered(fmt,STR(x),(h).x) - pr (fmt_x, (*mp), msgh_bits); - pr (fmt_d, (*mp), msgh_size); - pr (fmt_x, (*mp), msgh_remote_port); - pr (fmt_x, (*mp), msgh_local_port); - pr (fmt_d, (*mp), msgh_kind); - printf_filtered (fmt_s, STR (msgh_id), id_str (mp->msgh_id, buf)); - - if (debug_level > 1) - { - char *p, *ep, *dp; - int plen; - p = (char *) mp; - ep = p + mp->msgh_size; - p += sizeof (*mp); - for (; p < ep; p += plen) - { - mach_msg_type_t *tp; - mach_msg_type_long_t *tlp; - int name, size, number; - tp = (mach_msg_type_t *) p; - if (tp->msgt_longform) - { - tlp = (mach_msg_type_long_t *) tp; - name = tlp->msgtl_name; - size = tlp->msgtl_size; - number = tlp->msgtl_number; - plen = sizeof (*tlp); - } - else - { - name = tp->msgt_name; - size = tp->msgt_size; - number = tp->msgt_number; - plen = sizeof (*tp); - } - printf_filtered ("name=%-16s size=%2d number=%7d inline=%d long=%d deal=%d\n", - name_str (name, buf), size, number, tp->msgt_inline, - tp->msgt_longform, tp->msgt_deallocate); - dp = p + plen; - if (tp->msgt_inline) - { - int l; - l = size * number / 8; - l = (l + sizeof (long) - 1) & ~((sizeof (long)) - 1); - plen += l; - print_data (dp, size, number); - } - else - { - plen += sizeof (int *); - } - printf_filtered ("plen=%d\n", plen); - } - } -} - -print_data (char *p, int size, int number) -{ - int *ip; - short *sp; - int i; - - switch (size) - { - case 8: - for (i = 0; i < number; i++) - { - printf_filtered (" %02x", p[i]); - } - break; - case 16: - sp = (short *) p; - for (i = 0; i < number; i++) - { - printf_filtered (" %04x", sp[i]); - } - break; - case 32: - ip = (int *) p; - for (i = 0; i < number; i++) - { - printf_filtered (" %08x", ip[i]); - } - break; - } - puts_filtered ("\n"); -} -#endif /* DUMP_SYSCALL */ - -static void -m3_stop (void) -{ - error ("to_stop target function not implemented"); -} - -static char * -m3_pid_to_exec_file (int pid) -{ - error ("to_pid_to_exec_file target function not implemented"); - return NULL; /* To keep all compilers happy. */ -} - -static void -init_m3_ops (void) -{ - m3_ops.to_shortname = "mach"; - m3_ops.to_longname = "Mach child process"; - m3_ops.to_doc = "Mach child process (started by the \"run\" command)."; - m3_ops.to_open = m3_open; - m3_ops.to_attach = m3_attach; - m3_ops.to_detach = m3_detach; - m3_ops.to_resume = m3_resume; - m3_ops.to_wait = mach_really_wait; - m3_ops.to_fetch_registers = fetch_inferior_registers; - m3_ops.to_store_registers = store_inferior_registers; - m3_ops.to_prepare_to_store = m3_prepare_to_store; - m3_ops.to_xfer_memory = m3_xfer_memory; - m3_ops.to_files_info = m3_files_info; - m3_ops.to_insert_breakpoint = memory_insert_breakpoint; - m3_ops.to_remove_breakpoint = memory_remove_breakpoint; - m3_ops.to_terminal_init = terminal_init_inferior; - m3_ops.to_terminal_inferior = terminal_inferior; - m3_ops.to_terminal_ours_for_output = terminal_ours_for_output; - m3_ops.to_terminal_ours = terminal_ours; - m3_ops.to_terminal_info = child_terminal_info; - m3_ops.to_kill = m3_kill_inferior; - m3_ops.to_create_inferior = m3_create_inferior; - m3_ops.to_mourn_inferior = m3_mourn_inferior; - m3_ops.to_can_run = m3_can_run; - m3_ops.to_stop = m3_stop; - m3_ops.to_pid_to_exec_file = m3_pid_to_exec_file; - m3_ops.to_stratum = process_stratum; - m3_ops.to_has_all_memory = 1; - m3_ops.to_has_memory = 1; - m3_ops.to_has_stack = 1; - m3_ops.to_has_registers = 1; - m3_ops.to_has_execution = 1; - m3_ops.to_magic = OPS_MAGIC; -} - -void -_initialize_m3_nat (void) -{ - kern_return_t ret; - - init_m3_ops (); - add_target (&m3_ops); - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_PORT_SET, - &inferior_wait_port_set); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, - "initial port set %s", mach_error_string (ret)); - - /* mach_really_wait now waits for this */ - currently_waiting_for = inferior_wait_port_set; - - ret = netname_look_up (name_server_port, hostname, "MachID", &mid_server); - if (ret != KERN_SUCCESS) - { - mid_server = MACH_PORT_NULL; - - warning ("initialize machid: netname_lookup_up(MachID) : %s", - mach_error_string (ret)); - warning ("Some (most?) features disabled..."); - } - - mid_auth = mach_privileged_host_port (); - if (mid_auth == MACH_PORT_NULL) - mid_auth = mach_task_self (); - - obstack_init (port_chain_obstack); - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &thread_exception_port); - CHK ("Creating thread_exception_port for single stepping", ret); - - ret = mach_port_insert_right (mach_task_self (), - thread_exception_port, - thread_exception_port, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("Inserting send right to thread_exception_port", ret); - - /* Allocate message port */ - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &our_message_port); - if (ret != KERN_SUCCESS) - warning ("Creating message port %s", mach_error_string (ret)); - else - { - char buf[MAX_NAME_LEN]; - ret = mach_port_move_member (mach_task_self (), - our_message_port, - inferior_wait_port_set); - if (ret != KERN_SUCCESS) - warning ("message move member %s", mach_error_string (ret)); - - - /* @@@@ No way to change message port name currently */ - /* Foo. This assumes gdb has a unix pid */ - sprintf (buf, "gdb-%d", getpid ()); - gdb_register_port (buf, our_message_port); - } - - /* Heap for thread commands */ - obstack_init (cproc_obstack); - - add_mach_specific_commands (); -} diff --git a/contrib/gdb/gdb/minimon.h b/contrib/gdb/gdb/minimon.h deleted file mode 100644 index 94fd774a375..00000000000 --- a/contrib/gdb/gdb/minimon.h +++ /dev/null @@ -1,601 +0,0 @@ -/* Definitions and macros for support of AMD's remote debugger, MiniMON. - Copyright 1990, 1991 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* - * Some basic types. FIXME, this should be done by declaring bitfield - * sizes in the structs. We can't portably depend on a "long int" being - * 32 bits, etc. - */ -typedef long int INT32; /* 32 bit integer */ -typedef unsigned long int UINT32; /* 32 bit integer (unsigned) */ -typedef unsigned long int ADDR32; /* 32 bit address */ -typedef unsigned long int INST32; /* 32 bit instruction */ -typedef long int BOOLEAN; /* Boolean value (32 bit) */ -typedef unsigned char BYTE; /* byte (8 bit) */ -typedef short int INT16; /* 16 bit integer */ -typedef unsigned short int UINT16; /* 16 bit integer (unsigned) */ - -/****************************************************************************/ -/************************* Message Information ******************************/ -/****************************************************************************/ - -/* - * Error codes - */ - -/* General errors */ -#define EMUSAGE 1 /* Bad args / flags */ -#define EMFAIL 2 /* Unrecoverable error */ -#define EMBADADDR 3 /* Illegal address */ -#define EMBADREG 4 /* Illegal register */ -#define EMSYNTAX 5 /* Illegal command syntax */ -#define EMACCESS 6 /* Could not access memory */ -#define EMALLOC 7 /* Could not allocate memory */ -#define EMTARGET 8 /* Unknown target type */ -#define EMHINIT 9 /* Could not initialize host */ -#define EMCOMM 10 /* Could not open communication channel */ - -/* Message errors */ -#define EMBADMSG 11 /* Unknown message type */ -#define EMMSG2BIG 12 /* Message to large for buffer */ -#define EMNOSEND 13 /* Could not send message */ -#define EMNORECV 14 /* Could not receive message */ - -#define EMRESET 15 /* Could not RESET target */ -#define EMCONFIG 16 /* Could not get target CONFIG */ -#define EMSTATUS 17 /* Could not get target STATUS */ -#define EMREAD 18 /* Could not READ target memory */ -#define EMWRITE 19 /* Could not WRITE target memory */ -#define EMBKPTSET 20 /* Could not set breakpoint */ -#define EMBKPTRM 21 /* Could not remove breakpoint */ -#define EMBKPTSTAT 22 /* Could not get breakpoint status */ -#define EMBKPTNONE 23 /* All breakpoints in use */ -#define EMBKPTUSED 24 /* Breakpoints already in use */ -#define EMCOPY 25 /* Could not COPY target memory */ -#define EMFILL 26 /* Could not FILL target memory */ -#define EMINIT 27 /* Could not initialize target memory */ -#define EMGO 28 /* Could not start execution */ -#define EMSTEP 29 /* Could not single step */ -#define EMBREAK 30 /* Could not BREAK */ -#define EMHIF 31 /* Could not perform HIF service */ -#define EMCHANNEL0 32 /* Could not read CHANNEL0 */ -#define EMCHANNEL1 33 /* Could not write CHANNEL1 */ - -/* COFF file loader errors */ -#define EMOPEN 34 /* Could not open COFF file */ -#define EMHDR 35 /* Could not read COFF header */ -#define EMMAGIC 36 /* Bad magic number */ -#define EMAOUT 37 /* Could not read COFF a.out header */ -#define EMSCNHDR 38 /* Could not read COFF section header */ -#define EMSCN 39 /* Could not read COFF section */ -#define EMCLOSE 40 /* Could not close COFF file */ - -/* Log file errors */ -#define EMLOGOPEN 41 /* Could not open log file */ -#define EMLOGREAD 42 /* Could not read log file */ -#define EMLOGWRITE 43 /* Could not write to log file */ -#define EMLOGCLOSE 44 /* Could not close log file */ - -/* Command file errors */ -#define EMCMDOPEN 45 /* Could not open command file */ -#define EMCMDREAD 46 /* Could not read command file */ -#define EMCMDWRITE 47 /* Could not write to command file */ -#define EMCMDCLOSE 48 /* Could not close comand file */ - -#define EMTIMEOUT 49 /* Host timed out waiting for a message */ -#define EMCOMMTYPE 50 /* A '-t' flag must be specified */ -#define EMCOMMERR 51 /* Communication error */ -#define EMBAUD 52 /* Invalid baud rate specified */ -/* - * Memory Spaces - */ -#define LOCAL_REG 0 /* Local processor register */ -#define GLOBAL_REG 1 /* Global processor register */ -#define SPECIAL_REG 2 /* Special processor register */ -#define TLB_REG 3 /* Translation Lookaside Buffer */ -#define COPROC_REG 4 /* Coprocessor register */ -#define I_MEM 5 /* Instruction Memory */ -#define D_MEM 6 /* Data Memory */ -#define I_ROM 7 /* Instruction ROM */ -#define D_ROM 8 /* Data ROM */ -#define I_O 9 /* Input/Output */ -#define I_CACHE 10 /* Instruction Cache */ -#define D_CACHE 11 /* Data Cache */ - -/* To supress warnings for zero length array definitions */ -#define DUMMY 1 - -/* - ** Host to target definitions - */ - -#define RESET 0 -#define CONFIG_REQ 1 -#define STATUS_REQ 2 -#define READ_REQ 3 -#define WRITE_REQ 4 -#define BKPT_SET 5 -#define BKPT_RM 6 -#define BKPT_STAT 7 -#define COPY 8 -#define FILL 9 -#define INIT 10 -#define GO 11 -#define STEP 12 -#define BREAK 13 - -#define HIF_CALL_RTN 64 -#define CHANNEL0 65 -#define CHANNEL1_ACK 66 - - -/* - ** Target to host definitions - */ - -#define RESET_ACK 32 -#define CONFIG 33 -#define STATUS 34 -#define READ_ACK 35 -#define WRITE_ACK 36 -#define BKPT_SET_ACK 37 -#define BKPT_RM_ACK 38 -#define BKPT_STAT_ACK 39 -#define COPY_ACK 40 -#define FILL_ACK 41 -#define INIT_ACK 42 -#define HALT 43 - -#define ERROR 63 - -#define HIF_CALL 96 -#define CHANNEL0_ACK 97 -#define CHANNEL1 98 - - -/* A "generic" message */ -struct generic_msg_t - { - INT32 code; /* generic */ - INT32 length; - BYTE byte[DUMMY]; - }; - - -/* A "generic" message (with an INT32 array) */ -struct generic_int32_msg_t - { - INT32 code; /* generic */ - INT32 length; - INT32 int32[DUMMY]; - }; - - -/* - ** Host to target messages - */ - -struct reset_msg_t - { - INT32 code; /* 0 */ - INT32 length; - }; - - -struct config_req_msg_t - { - INT32 code; /* 1 */ - INT32 length; - }; - - -struct status_req_msg_t - { - INT32 code; /* 2 */ - INT32 length; - }; - - -struct read_req_msg_t - { - INT32 code; /* 3 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 byte_count; - }; - - -struct write_req_msg_t - { - INT32 code; /* 4 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 byte_count; - BYTE data[DUMMY]; - }; - - -struct write_r_msg_t - { - INT32 code; /* 4 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 byte_count; - INT32 data[DUMMY]; - }; - - -struct bkpt_set_msg_t - { - INT32 code; /* 5 */ - INT32 length; - INT32 memory_space; - ADDR32 bkpt_addr; - INT32 pass_count; - INT32 bkpt_type; - }; - - -struct bkpt_rm_msg_t - { - INT32 code; /* 6 */ - INT32 length; - INT32 memory_space; - ADDR32 bkpt_addr; - }; - - -struct bkpt_stat_msg_t - { - INT32 code; /* 7 */ - INT32 length; - INT32 memory_space; - ADDR32 bkpt_addr; - }; - - -struct copy_msg_t - { - INT32 code; /* 8 */ - INT32 length; - INT32 source_space; - ADDR32 source_addr; - INT32 dest_space; - ADDR32 dest_addr; - INT32 byte_count; - }; - - -struct fill_msg_t - { - INT32 code; /* 9 */ - INT32 length; - INT32 memory_space; - ADDR32 start_addr; - INT32 fill_count; - INT32 byte_count; - BYTE fill_data[DUMMY]; - }; - - -struct init_msg_t - { - INT32 code; /* 10 */ - INT32 length; - ADDR32 text_start; - ADDR32 text_end; - ADDR32 data_start; - ADDR32 data_end; - ADDR32 entry_point; - INT32 mem_stack_size; - INT32 reg_stack_size; - ADDR32 arg_start; - INT32 os_control; - }; - - -struct go_msg_t - { - INT32 code; /* 11 */ - INT32 length; - }; - - -struct step_msg_t - { - INT32 code; /* 12 */ - INT32 length; - INT32 count; - }; - - -struct break_msg_t - { - INT32 code; /* 13 */ - INT32 length; - }; - - -struct hif_call_rtn_msg_t - { - INT32 code; /* 64 */ - INT32 length; - INT32 service_number; - INT32 gr121; - INT32 gr96; - INT32 gr97; - }; - - -struct channel0_msg_t - { - INT32 code; /* 65 */ - INT32 length; - BYTE data; - }; - - -struct channel1_ack_msg_t - { - INT32 code; /* 66 */ - INT32 length; - }; - - -/* - ** Target to host messages - */ - - -struct reset_ack_msg_t - { - INT32 code; /* 32 */ - INT32 length; - }; - - -struct config_msg_t - { - INT32 code; /* 33 */ - INT32 length; - INT32 processor_id; - INT32 version; - ADDR32 I_mem_start; - INT32 I_mem_size; - ADDR32 D_mem_start; - INT32 D_mem_size; - ADDR32 ROM_start; - INT32 ROM_size; - INT32 max_msg_size; - INT32 max_bkpts; - INT32 coprocessor; - INT32 reserved; - }; - - -struct status_msg_t - { - INT32 code; /* 34 */ - INT32 length; - INT32 msgs_sent; - INT32 msgs_received; - INT32 errors; - INT32 bkpts_hit; - INT32 bkpts_free; - INT32 traps; - INT32 fills; - INT32 spills; - INT32 cycles; - INT32 reserved; - }; - - -struct read_ack_msg_t - { - INT32 code; /* 35 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 byte_count; - BYTE data[DUMMY]; - }; - -struct read_r_ack_msg_t - { - INT32 code; /* 35 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 byte_count; - INT32 data[DUMMY]; - }; - - -struct write_ack_msg_t - { - INT32 code; /* 36 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 byte_count; - }; - - -struct bkpt_set_ack_msg_t - { - INT32 code; /* 37 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 pass_count; - INT32 bkpt_type; - }; - - -struct bkpt_rm_ack_msg_t - { - INT32 code; /* 38 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - }; - - -struct bkpt_stat_ack_msg_t - { - INT32 code; /* 39 */ - INT32 length; - INT32 memory_space; - ADDR32 address; - INT32 pass_count; - INT32 bkpt_type; - }; - - -struct copy_ack_msg_t - { - INT32 code; /* 40 */ - INT32 length; - INT32 source_space; - ADDR32 source_addr; - INT32 dest_space; - ADDR32 dest_addr; - INT32 byte_count; - }; - - -struct fill_ack_msg_t - { - INT32 code; /* 41 */ - INT32 length; - INT32 memory_space; - ADDR32 start_addr; - INT32 fill_count; - INT32 byte_count; - }; - - -struct init_ack_msg_t - { - INT32 code; /* 42 */ - INT32 length; - }; - - -struct halt_msg_t - { - INT32 code; /* 43 */ - INT32 length; - INT32 memory_space; - ADDR32 pc0; - ADDR32 pc1; - INT32 trap_number; - }; - - -struct error_msg_t - { - INT32 code; /* 63 */ - INT32 length; - INT32 error_code; - INT32 memory_space; - ADDR32 address; - }; - - -struct hif_call_msg_t - { - INT32 code; /* 96 */ - INT32 length; - INT32 service_number; - INT32 lr2; - INT32 lr3; - INT32 lr4; - }; - - -struct channel0_ack_msg_t - { - INT32 code; /* 97 */ - INT32 length; - }; - - -struct channel1_msg_t - { - INT32 code; /* 98 */ - INT32 length; - BYTE data[DUMMY]; - }; - - - -/* - ** Union all of the message types together - */ - -union msg_t - { - struct generic_msg_t generic_msg; - struct generic_int32_msg_t generic_int32_msg; - - struct reset_msg_t reset_msg; - struct config_req_msg_t config_req_msg; - struct status_req_msg_t status_req_msg; - struct read_req_msg_t read_req_msg; - struct write_req_msg_t write_req_msg; - struct write_r_msg_t write_r_msg; - struct bkpt_set_msg_t bkpt_set_msg; - struct bkpt_rm_msg_t bkpt_rm_msg; - struct bkpt_stat_msg_t bkpt_stat_msg; - struct copy_msg_t copy_msg; - struct fill_msg_t fill_msg; - struct init_msg_t init_msg; - struct go_msg_t go_msg; - struct step_msg_t step_msg; - struct break_msg_t break_msg; - - struct hif_call_rtn_msg_t hif_call_rtn_msg; - struct channel0_msg_t channel0_msg; - struct channel1_ack_msg_t channel1_ack_msg; - - struct reset_ack_msg_t reset_ack_msg; - struct config_msg_t config_msg; - struct status_msg_t status_msg; - struct read_ack_msg_t read_ack_msg; - struct read_r_ack_msg_t read_r_ack_msg; - struct write_ack_msg_t write_ack_msg; - struct bkpt_set_ack_msg_t bkpt_set_ack_msg; - struct bkpt_rm_ack_msg_t bkpt_rm_ack_msg; - struct bkpt_stat_ack_msg_t bkpt_stat_ack_msg; - struct copy_ack_msg_t copy_ack_msg; - struct fill_ack_msg_t fill_ack_msg; - struct init_ack_msg_t init_ack_msg; - struct halt_msg_t halt_msg; - - struct error_msg_t error_msg; - - struct hif_call_msg_t hif_call_msg; - struct channel0_ack_msg_t channel0_ack_msg; - struct channel1_msg_t channel1_msg; - }; diff --git a/contrib/gdb/gdb/monitor.c b/contrib/gdb/gdb/monitor.c deleted file mode 100644 index e760d43745a..00000000000 --- a/contrib/gdb/gdb/monitor.c +++ /dev/null @@ -1,2386 +0,0 @@ -/* Remote debugging interface for boot monitors, for GDB. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - - Contributed by Cygnus Support. Written by Rob Savoye for Cygnus. - Resurrected from the ashes by Stu Grossman. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This file was derived from various remote-* modules. It is a collection - of generic support functions so GDB can talk directly to a ROM based - monitor. This saves use from having to hack an exception based handler - into existence, and makes for quick porting. - - This module talks to a debug monitor called 'MONITOR', which - We communicate with MONITOR via either a direct serial line, or a TCP - (or possibly TELNET) stream to a terminal multiplexor, - which in turn talks to the target board. */ - -/* FIXME 32x64: This code assumes that registers and addresses are at - most 32 bits long. If they can be larger, you will need to declare - values as LONGEST and use %llx or some such to print values when - building commands to send to the monitor. Since we don't know of - any actual 64-bit targets with ROM monitors that use this code, - it's not an issue right now. -sts 4/18/96 */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include -#include -#include "gdb_string.h" -#include -#include "command.h" -#include "serial.h" -#include "monitor.h" -#include "gdbcmd.h" -#include "inferior.h" -#include "gdb_regex.h" -#include "srec.h" -#include "regcache.h" - -static char *dev_name; -static struct target_ops *targ_ops; - -static void monitor_vsprintf (char *sndbuf, char *pattern, va_list args); - -static int readchar (int timeout); - -static void monitor_fetch_register (int regno); -static void monitor_store_register (int regno); - -static void monitor_printable_string (char *newstr, char *oldstr, int len); -static void monitor_error (char *function, char *message, CORE_ADDR memaddr, int len, char *string, int final_char); -static void monitor_detach (char *args, int from_tty); -static void monitor_resume (ptid_t ptid, int step, enum target_signal sig); -static void monitor_interrupt (int signo); -static void monitor_interrupt_twice (int signo); -static void monitor_interrupt_query (void); -static void monitor_wait_cleanup (void *old_timeout); - -static ptid_t monitor_wait (ptid_t ptid, struct target_waitstatus *status); -static void monitor_fetch_registers (int regno); -static void monitor_store_registers (int regno); -static void monitor_prepare_to_store (void); -static int monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, - struct mem_attrib *attrib, - struct target_ops *target); -static void monitor_files_info (struct target_ops *ops); -static int monitor_insert_breakpoint (CORE_ADDR addr, char *shadow); -static int monitor_remove_breakpoint (CORE_ADDR addr, char *shadow); -static void monitor_kill (void); -static void monitor_load (char *file, int from_tty); -static void monitor_mourn_inferior (void); -static void monitor_stop (void); - -static int monitor_read_memory (CORE_ADDR addr, char *myaddr, int len); -static int monitor_write_memory (CORE_ADDR addr, char *myaddr, int len); -static int monitor_write_memory_bytes (CORE_ADDR addr, char *myaddr, int len); -static int monitor_write_memory_block (CORE_ADDR memaddr, - char *myaddr, int len); -static int monitor_expect_regexp (struct re_pattern_buffer *pat, - char *buf, int buflen); -static void monitor_dump_regs (void); -#if 0 -static int from_hex (int a); -static unsigned long get_hex_word (void); -#endif -static void parse_register_dump (char *, int); - -static struct monitor_ops *current_monitor; - -static int hashmark; /* flag set by "set hash" */ - -static int timeout = 30; - -static int in_monitor_wait = 0; /* Non-zero means we are in monitor_wait() */ - -static void (*ofunc) (); /* Old SIGINT signal handler */ - -static CORE_ADDR *breakaddr; - -/* Descriptor for I/O to remote machine. Initialize it to NULL so - that monitor_open knows that we don't have a file open when the - program starts. */ - -static struct serial *monitor_desc = NULL; - -/* Pointer to regexp pattern matching data */ - -static struct re_pattern_buffer register_pattern; -static char register_fastmap[256]; - -static struct re_pattern_buffer getmem_resp_delim_pattern; -static char getmem_resp_delim_fastmap[256]; - -static struct re_pattern_buffer setmem_resp_delim_pattern; -static char setmem_resp_delim_fastmap[256]; - -static struct re_pattern_buffer setreg_resp_delim_pattern; -static char setreg_resp_delim_fastmap[256]; - -static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when - monitor_wait wakes up. */ - -static int first_time = 0; /* is this the first time we're executing after - gaving created the child proccess? */ - -#define TARGET_BUF_SIZE 2048 - -/* Monitor specific debugging information. Typically only useful to - the developer of a new monitor interface. */ - -static void monitor_debug (const char *fmt, ...) ATTR_FORMAT(printf, 1, 2); - -static int monitor_debug_p = 0; - -/* NOTE: This file alternates between monitor_debug_p and remote_debug - when determining if debug information is printed. Perhaphs this - could be simplified. */ - -static void -monitor_debug (const char *fmt, ...) -{ - if (monitor_debug_p) - { - va_list args; - va_start (args, fmt); - vfprintf_filtered (gdb_stdlog, fmt, args); - va_end (args); - } -} - - -/* Convert a string into a printable representation, Return # byte in - the new string. When LEN is >0 it specifies the size of the - string. Otherwize strlen(oldstr) is used. */ - -static void -monitor_printable_string (char *newstr, char *oldstr, int len) -{ - int ch; - int i; - - if (len <= 0) - len = strlen (oldstr); - - for (i = 0; i < len; i++) - { - ch = oldstr[i]; - switch (ch) - { - default: - if (isprint (ch)) - *newstr++ = ch; - - else - { - sprintf (newstr, "\\x%02x", ch & 0xff); - newstr += 4; - } - break; - - case '\\': - *newstr++ = '\\'; - *newstr++ = '\\'; - break; - case '\b': - *newstr++ = '\\'; - *newstr++ = 'b'; - break; - case '\f': - *newstr++ = '\\'; - *newstr++ = 't'; - break; - case '\n': - *newstr++ = '\\'; - *newstr++ = 'n'; - break; - case '\r': - *newstr++ = '\\'; - *newstr++ = 'r'; - break; - case '\t': - *newstr++ = '\\'; - *newstr++ = 't'; - break; - case '\v': - *newstr++ = '\\'; - *newstr++ = 'v'; - break; - } - } - - *newstr++ = '\0'; -} - -/* Print monitor errors with a string, converting the string to printable - representation. */ - -static void -monitor_error (char *function, char *message, - CORE_ADDR memaddr, int len, char *string, int final_char) -{ - int real_len = (len == 0 && string != (char *) 0) ? strlen (string) : len; - char *safe_string = alloca ((real_len * 4) + 1); - monitor_printable_string (safe_string, string, real_len); - - if (final_char) - error ("%s (0x%s): %s: %s%c", function, paddr_nz (memaddr), message, safe_string, final_char); - else - error ("%s (0x%s): %s: %s", function, paddr_nz (memaddr), message, safe_string); -} - -/* Convert hex digit A to a number. */ - -static int -fromhex (int a) -{ - if (a >= '0' && a <= '9') - return a - '0'; - else if (a >= 'a' && a <= 'f') - return a - 'a' + 10; - else if (a >= 'A' && a <= 'F') - return a - 'A' + 10; - else - error ("Invalid hex digit %d", a); -} - -/* monitor_vsprintf - similar to vsprintf but handles 64-bit addresses - - This function exists to get around the problem that many host platforms - don't have a printf that can print 64-bit addresses. The %A format - specification is recognized as a special case, and causes the argument - to be printed as a 64-bit hexadecimal address. - - Only format specifiers of the form "[0-9]*[a-z]" are recognized. - If it is a '%s' format, the argument is a string; otherwise the - argument is assumed to be a long integer. - - %% is also turned into a single %. - */ - -static void -monitor_vsprintf (char *sndbuf, char *pattern, va_list args) -{ - char format[10]; - char fmt; - char *p; - int i; - long arg_int; - CORE_ADDR arg_addr; - char *arg_string; - - for (p = pattern; *p; p++) - { - if (*p == '%') - { - /* Copy the format specifier to a separate buffer. */ - format[0] = *p++; - for (i = 1; *p >= '0' && *p <= '9' && i < (int) sizeof (format) - 2; - i++, p++) - format[i] = *p; - format[i] = fmt = *p; - format[i + 1] = '\0'; - - /* Fetch the next argument and print it. */ - switch (fmt) - { - case '%': - strcpy (sndbuf, "%"); - break; - case 'A': - arg_addr = va_arg (args, CORE_ADDR); - strcpy (sndbuf, paddr_nz (arg_addr)); - break; - case 's': - arg_string = va_arg (args, char *); - sprintf (sndbuf, format, arg_string); - break; - default: - arg_int = va_arg (args, long); - sprintf (sndbuf, format, arg_int); - break; - } - sndbuf += strlen (sndbuf); - } - else - *sndbuf++ = *p; - } - *sndbuf = '\0'; -} - - -/* monitor_printf_noecho -- Send data to monitor, but don't expect an echo. - Works just like printf. */ - -void -monitor_printf_noecho (char *pattern,...) -{ - va_list args; - char sndbuf[2000]; - int len; - - va_start (args, pattern); - - monitor_vsprintf (sndbuf, pattern, args); - - len = strlen (sndbuf); - if (len + 1 > sizeof sndbuf) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - if (monitor_debug_p) - { - char *safe_string = (char *) alloca ((strlen (sndbuf) * 4) + 1); - monitor_printable_string (safe_string, sndbuf, 0); - fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string); - } - - monitor_write (sndbuf, len); -} - -/* monitor_printf -- Send data to monitor and check the echo. Works just like - printf. */ - -void -monitor_printf (char *pattern,...) -{ - va_list args; - char sndbuf[2000]; - int len; - - va_start (args, pattern); - - monitor_vsprintf (sndbuf, pattern, args); - - len = strlen (sndbuf); - if (len + 1 > sizeof sndbuf) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - if (monitor_debug_p) - { - char *safe_string = (char *) alloca ((len * 4) + 1); - monitor_printable_string (safe_string, sndbuf, 0); - fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string); - } - - monitor_write (sndbuf, len); - - /* We used to expect that the next immediate output was the characters we - just output, but sometimes some extra junk appeared before the characters - we expected, like an extra prompt, or a portmaster sending telnet negotiations. - So, just start searching for what we sent, and skip anything unknown. */ - monitor_debug ("ExpectEcho\n"); - monitor_expect (sndbuf, (char *) 0, 0); -} - - -/* Write characters to the remote system. */ - -void -monitor_write (char *buf, int buflen) -{ - if (serial_write (monitor_desc, buf, buflen)) - fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n", - safe_strerror (errno)); -} - - -/* Read a binary character from the remote system, doing all the fancy - timeout stuff, but without interpreting the character in any way, - and without printing remote debug information. */ - -int -monitor_readchar (void) -{ - int c; - int looping; - - do - { - looping = 0; - c = serial_readchar (monitor_desc, timeout); - - if (c >= 0) - c &= 0xff; /* don't lose bit 7 */ - } - while (looping); - - if (c >= 0) - return c; - - if (c == SERIAL_TIMEOUT) - error ("Timeout reading from remote system."); - - perror_with_name ("remote-monitor"); -} - - -/* Read a character from the remote system, doing all the fancy - timeout stuff. */ - -static int -readchar (int timeout) -{ - int c; - static enum - { - last_random, last_nl, last_cr, last_crnl - } - state = last_random; - int looping; - - do - { - looping = 0; - c = serial_readchar (monitor_desc, timeout); - - if (c >= 0) - { - c &= 0x7f; - /* This seems to interfere with proper function of the - input stream */ - if (monitor_debug_p || remote_debug) - { - char buf[2]; - buf[0] = c; - buf[1] = '\0'; - puts_debug ("read -->", buf, "<--"); - } - - } - - /* Canonicialize \n\r combinations into one \r */ - if ((current_monitor->flags & MO_HANDLE_NL) != 0) - { - if ((c == '\r' && state == last_nl) - || (c == '\n' && state == last_cr)) - { - state = last_crnl; - looping = 1; - } - else if (c == '\r') - state = last_cr; - else if (c != '\n') - state = last_random; - else - { - state = last_nl; - c = '\r'; - } - } - } - while (looping); - - if (c >= 0) - return c; - - if (c == SERIAL_TIMEOUT) -#if 0 - /* I fail to see how detaching here can be useful */ - if (in_monitor_wait) /* Watchdog went off */ - { - target_mourn_inferior (); - error ("GDB serial timeout has expired. Target detached.\n"); - } - else -#endif - error ("Timeout reading from remote system."); - - perror_with_name ("remote-monitor"); -} - -/* Scan input from the remote system, until STRING is found. If BUF is non- - zero, then collect input until we have collected either STRING or BUFLEN-1 - chars. In either case we terminate BUF with a 0. If input overflows BUF - because STRING can't be found, return -1, else return number of chars in BUF - (minus the terminating NUL). Note that in the non-overflow case, STRING - will be at the end of BUF. */ - -int -monitor_expect (char *string, char *buf, int buflen) -{ - char *p = string; - int obuflen = buflen; - int c; - extern struct target_ops *targ_ops; - - if (monitor_debug_p) - { - char *safe_string = (char *) alloca ((strlen (string) * 4) + 1); - monitor_printable_string (safe_string, string, 0); - fprintf_unfiltered (gdb_stdlog, "MON Expecting '%s'\n", safe_string); - } - - immediate_quit++; - while (1) - { - if (buf) - { - if (buflen < 2) - { - *buf = '\000'; - immediate_quit--; - return -1; - } - - c = readchar (timeout); - if (c == '\000') - continue; - *buf++ = c; - buflen--; - } - else - c = readchar (timeout); - - /* Don't expect any ^C sent to be echoed */ - - if (*p == '\003' || c == *p) - { - p++; - if (*p == '\0') - { - immediate_quit--; - - if (buf) - { - *buf++ = '\000'; - return obuflen - buflen; - } - else - return 0; - } - } - else if ((c == '\021' || c == '\023') && - (STREQ (targ_ops->to_shortname, "m32r") - || STREQ (targ_ops->to_shortname, "mon2000"))) - { /* m32r monitor emits random DC1/DC3 chars */ - continue; - } - else - { - /* We got a character that doesn't match the string. We need to - back up p, but how far? If we're looking for "..howdy" and the - monitor sends "...howdy"? There's certainly a match in there, - but when we receive the third ".", we won't find it if we just - restart the matching at the beginning of the string. - - This is a Boyer-Moore kind of situation. We want to reset P to - the end of the longest prefix of STRING that is a suffix of - what we've read so far. In the example above, that would be - ".." --- the longest prefix of "..howdy" that is a suffix of - "...". This longest prefix could be the empty string, if C - is nowhere to be found in STRING. - - If this longest prefix is not the empty string, it must contain - C, so let's search from the end of STRING for instances of C, - and see if the portion of STRING before that is a suffix of - what we read before C. Actually, we can search backwards from - p, since we know no prefix can be longer than that. - - Note that we can use STRING itself, along with C, as a record - of what we've received so far. :) */ - int i; - - for (i = (p - string) - 1; i >= 0; i--) - if (string[i] == c) - { - /* Is this prefix a suffix of what we've read so far? - In other words, does - string[0 .. i-1] == string[p - i, p - 1]? */ - if (! memcmp (string, p - i, i)) - { - p = string + i + 1; - break; - } - } - if (i < 0) - p = string; - } - } -} - -/* Search for a regexp. */ - -static int -monitor_expect_regexp (struct re_pattern_buffer *pat, char *buf, int buflen) -{ - char *mybuf; - char *p; - monitor_debug ("MON Expecting regexp\n"); - if (buf) - mybuf = buf; - else - { - mybuf = alloca (TARGET_BUF_SIZE); - buflen = TARGET_BUF_SIZE; - } - - p = mybuf; - while (1) - { - int retval; - - if (p - mybuf >= buflen) - { /* Buffer about to overflow */ - -/* On overflow, we copy the upper half of the buffer to the lower half. Not - great, but it usually works... */ - - memcpy (mybuf, mybuf + buflen / 2, buflen / 2); - p = mybuf + buflen / 2; - } - - *p++ = readchar (timeout); - - retval = re_search (pat, mybuf, p - mybuf, 0, p - mybuf, NULL); - if (retval >= 0) - return 1; - } -} - -/* Keep discarding input until we see the MONITOR prompt. - - The convention for dealing with the prompt is that you - o give your command - o *then* wait for the prompt. - - Thus the last thing that a procedure does with the serial line will - be an monitor_expect_prompt(). Exception: monitor_resume does not - wait for the prompt, because the terminal is being handed over to - the inferior. However, the next thing which happens after that is - a monitor_wait which does wait for the prompt. Note that this - includes abnormal exit, e.g. error(). This is necessary to prevent - getting into states from which we can't recover. */ - -int -monitor_expect_prompt (char *buf, int buflen) -{ - monitor_debug ("MON Expecting prompt\n"); - return monitor_expect (current_monitor->prompt, buf, buflen); -} - -/* Get N 32-bit words from remote, each preceded by a space, and put - them in registers starting at REGNO. */ - -#if 0 -static unsigned long -get_hex_word (void) -{ - unsigned long val; - int i; - int ch; - - do - ch = readchar (timeout); - while (isspace (ch)); - - val = from_hex (ch); - - for (i = 7; i >= 1; i--) - { - ch = readchar (timeout); - if (!isxdigit (ch)) - break; - val = (val << 4) | from_hex (ch); - } - - return val; -} -#endif - -static void -compile_pattern (char *pattern, struct re_pattern_buffer *compiled_pattern, - char *fastmap) -{ - int tmp; - const char *val; - - compiled_pattern->fastmap = fastmap; - - tmp = re_set_syntax (RE_SYNTAX_EMACS); - val = re_compile_pattern (pattern, - strlen (pattern), - compiled_pattern); - re_set_syntax (tmp); - - if (val) - error ("compile_pattern: Can't compile pattern string `%s': %s!", pattern, val); - - if (fastmap) - re_compile_fastmap (compiled_pattern); -} - -/* Open a connection to a remote debugger. NAME is the filename used - for communication. */ - -void -monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty) -{ - char *name; - char **p; - - if (mon_ops->magic != MONITOR_OPS_MAGIC) - error ("Magic number of monitor_ops struct wrong."); - - targ_ops = mon_ops->target; - name = targ_ops->to_shortname; - - if (!args) - error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\ -`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name); - - target_preopen (from_tty); - - /* Setup pattern for register dump */ - - if (mon_ops->register_pattern) - compile_pattern (mon_ops->register_pattern, ®ister_pattern, - register_fastmap); - - if (mon_ops->getmem.resp_delim) - compile_pattern (mon_ops->getmem.resp_delim, &getmem_resp_delim_pattern, - getmem_resp_delim_fastmap); - - if (mon_ops->setmem.resp_delim) - compile_pattern (mon_ops->setmem.resp_delim, &setmem_resp_delim_pattern, - setmem_resp_delim_fastmap); - - if (mon_ops->setreg.resp_delim) - compile_pattern (mon_ops->setreg.resp_delim, &setreg_resp_delim_pattern, - setreg_resp_delim_fastmap); - - unpush_target (targ_ops); - - if (dev_name) - xfree (dev_name); - dev_name = xstrdup (args); - - monitor_desc = serial_open (dev_name); - - if (!monitor_desc) - perror_with_name (dev_name); - - if (baud_rate != -1) - { - if (serial_setbaudrate (monitor_desc, baud_rate)) - { - serial_close (monitor_desc); - perror_with_name (dev_name); - } - } - - serial_raw (monitor_desc); - - serial_flush_input (monitor_desc); - - /* some systems only work with 2 stop bits */ - - serial_setstopbits (monitor_desc, mon_ops->stopbits); - - current_monitor = mon_ops; - - /* See if we can wake up the monitor. First, try sending a stop sequence, - then send the init strings. Last, remove all breakpoints. */ - - if (current_monitor->stop) - { - monitor_stop (); - if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0) - { - monitor_debug ("EXP Open echo\n"); - monitor_expect_prompt (NULL, 0); - } - } - - /* wake up the monitor and see if it's alive */ - for (p = mon_ops->init; *p != NULL; p++) - { - /* Some of the characters we send may not be echoed, - but we hope to get a prompt at the end of it all. */ - - if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0) - monitor_printf (*p); - else - monitor_printf_noecho (*p); - monitor_expect_prompt (NULL, 0); - } - - serial_flush_input (monitor_desc); - - /* Alloc breakpoints */ - if (mon_ops->set_break != NULL) - { - if (mon_ops->num_breakpoints == 0) - mon_ops->num_breakpoints = 8; - - breakaddr = (CORE_ADDR *) xmalloc (mon_ops->num_breakpoints * sizeof (CORE_ADDR)); - memset (breakaddr, 0, mon_ops->num_breakpoints * sizeof (CORE_ADDR)); - } - - /* Remove all breakpoints */ - - if (mon_ops->clr_all_break) - { - monitor_printf (mon_ops->clr_all_break); - monitor_expect_prompt (NULL, 0); - } - - if (from_tty) - printf_unfiltered ("Remote target %s connected to %s\n", name, dev_name); - - push_target (targ_ops); - - inferior_ptid = pid_to_ptid (42000); /* Make run command think we are busy... */ - - /* Give monitor_wait something to read */ - - monitor_printf (current_monitor->line_term); - - start_remote (); -} - -/* Close out all files and local state before this target loses - control. */ - -void -monitor_close (int quitting) -{ - if (monitor_desc) - serial_close (monitor_desc); - - /* Free breakpoint memory */ - if (breakaddr != NULL) - { - xfree (breakaddr); - breakaddr = NULL; - } - - monitor_desc = NULL; -} - -/* Terminate the open connection to the remote debugger. Use this - when you want to detach and do something else with your gdb. */ - -static void -monitor_detach (char *args, int from_tty) -{ - pop_target (); /* calls monitor_close to do the real work */ - if (from_tty) - printf_unfiltered ("Ending remote %s debugging\n", target_shortname); -} - -/* Convert VALSTR into the target byte-ordered value of REGNO and store it. */ - -char * -monitor_supply_register (int regno, char *valstr) -{ - ULONGEST val; - unsigned char regbuf[MAX_REGISTER_RAW_SIZE]; - char *p; - - val = 0; - p = valstr; - while (p && *p != '\0') - { - if (*p == '\r' || *p == '\n') - { - while (*p != '\0') - p++; - break; - } - if (isspace (*p)) - { - p++; - continue; - } - if (!isxdigit (*p) && *p != 'x') - { - break; - } - - val <<= 4; - val += fromhex (*p++); - } - monitor_debug ("Supplying Register %d %s\n", regno, valstr); - - if (val == 0 && valstr == p) - error ("monitor_supply_register (%d): bad value from monitor: %s.", - regno, valstr); - - /* supply register stores in target byte order, so swap here */ - - store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), val); - - supply_register (regno, regbuf); - - return p; -} - -/* Tell the remote machine to resume. */ - -static void -monitor_resume (ptid_t ptid, int step, enum target_signal sig) -{ - /* Some monitors require a different command when starting a program */ - monitor_debug ("MON resume\n"); - if (current_monitor->flags & MO_RUN_FIRST_TIME && first_time == 1) - { - first_time = 0; - monitor_printf ("run\r"); - if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT) - dump_reg_flag = 1; - return; - } - if (step) - monitor_printf (current_monitor->step); - else - { - if (current_monitor->continue_hook) - (*current_monitor->continue_hook) (); - else - monitor_printf (current_monitor->cont); - if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT) - dump_reg_flag = 1; - } -} - -/* Parse the output of a register dump command. A monitor specific - regexp is used to extract individual register descriptions of the - form REG=VAL. Each description is split up into a name and a value - string which are passed down to monitor specific code. */ - -static void -parse_register_dump (char *buf, int len) -{ - monitor_debug ("MON Parsing register dump\n"); - while (1) - { - int regnamelen, vallen; - char *regname, *val; - /* Element 0 points to start of register name, and element 1 - points to the start of the register value. */ - struct re_registers register_strings; - - memset (®ister_strings, 0, sizeof (struct re_registers)); - - if (re_search (®ister_pattern, buf, len, 0, len, - ®ister_strings) == -1) - break; - - regnamelen = register_strings.end[1] - register_strings.start[1]; - regname = buf + register_strings.start[1]; - vallen = register_strings.end[2] - register_strings.start[2]; - val = buf + register_strings.start[2]; - - current_monitor->supply_register (regname, regnamelen, val, vallen); - - buf += register_strings.end[0]; - len -= register_strings.end[0]; - } -} - -/* Send ^C to target to halt it. Target will respond, and send us a - packet. */ - -static void -monitor_interrupt (int signo) -{ - /* If this doesn't work, try more severe steps. */ - signal (signo, monitor_interrupt_twice); - - if (monitor_debug_p || remote_debug) - fprintf_unfiltered (gdb_stdlog, "monitor_interrupt called\n"); - - target_stop (); -} - -/* The user typed ^C twice. */ - -static void -monitor_interrupt_twice (int signo) -{ - signal (signo, ofunc); - - monitor_interrupt_query (); - - signal (signo, monitor_interrupt); -} - -/* Ask the user what to do when an interrupt is received. */ - -static void -monitor_interrupt_query (void) -{ - target_terminal_ours (); - - if (query ("Interrupted while waiting for the program.\n\ -Give up (and stop debugging it)? ")) - { - target_mourn_inferior (); - throw_exception (RETURN_QUIT); - } - - target_terminal_inferior (); -} - -static void -monitor_wait_cleanup (void *old_timeout) -{ - timeout = *(int *) old_timeout; - signal (SIGINT, ofunc); - in_monitor_wait = 0; -} - - - -void -monitor_wait_filter (char *buf, - int bufmax, - int *ext_resp_len, - struct target_waitstatus *status -) -{ - int resp_len; - do - { - resp_len = monitor_expect_prompt (buf, bufmax); - *ext_resp_len = resp_len; - - if (resp_len <= 0) - fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf); - } - while (resp_len < 0); - - /* Print any output characters that were preceded by ^O. */ - /* FIXME - This would be great as a user settabgle flag */ - if (monitor_debug_p || remote_debug - || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT) - { - int i; - - for (i = 0; i < resp_len - 1; i++) - if (buf[i] == 0x0f) - putchar_unfiltered (buf[++i]); - } -} - - - -/* Wait until the remote machine stops, then return, storing status in - status just as `wait' would. */ - -static ptid_t -monitor_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int old_timeout = timeout; - char buf[TARGET_BUF_SIZE]; - int resp_len; - struct cleanup *old_chain; - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - old_chain = make_cleanup (monitor_wait_cleanup, &old_timeout); - monitor_debug ("MON wait\n"); - -#if 0 - /* This is somthing other than a maintenance command */ - in_monitor_wait = 1; - timeout = watchdog > 0 ? watchdog : -1; -#else - timeout = -1; /* Don't time out -- user program is running. */ -#endif - - ofunc = (void (*)()) signal (SIGINT, monitor_interrupt); - - if (current_monitor->wait_filter) - (*current_monitor->wait_filter) (buf, sizeof (buf), &resp_len, status); - else - monitor_wait_filter (buf, sizeof (buf), &resp_len, status); - -#if 0 /* Transferred to monitor wait filter */ - do - { - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - - if (resp_len <= 0) - fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf); - } - while (resp_len < 0); - - /* Print any output characters that were preceded by ^O. */ - /* FIXME - This would be great as a user settabgle flag */ - if (monitor_debug_p || remote_debug - || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT) - { - int i; - - for (i = 0; i < resp_len - 1; i++) - if (buf[i] == 0x0f) - putchar_unfiltered (buf[++i]); - } -#endif - - signal (SIGINT, ofunc); - - timeout = old_timeout; -#if 0 - if (dump_reg_flag && current_monitor->dump_registers) - { - dump_reg_flag = 0; - monitor_printf (current_monitor->dump_registers); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - } - - if (current_monitor->register_pattern) - parse_register_dump (buf, resp_len); -#else - monitor_debug ("Wait fetching registers after stop\n"); - monitor_dump_regs (); -#endif - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - - discard_cleanups (old_chain); - - in_monitor_wait = 0; - - return inferior_ptid; -} - -/* Fetch register REGNO, or all registers if REGNO is -1. Returns - errno value. */ - -static void -monitor_fetch_register (int regno) -{ - char *name; - char *zerobuf; - char *regbuf; - int i; - - regbuf = alloca (MAX_REGISTER_RAW_SIZE * 2 + 1); - zerobuf = alloca (MAX_REGISTER_RAW_SIZE); - memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE); - - name = current_monitor->regnames[regno]; - monitor_debug ("MON fetchreg %d '%s'\n", regno, name ? name : "(null name)"); - - if (!name || (*name == '\0')) - { - monitor_debug ("No register known for %d\n", regno); - supply_register (regno, zerobuf); - return; - } - - /* send the register examine command */ - - monitor_printf (current_monitor->getreg.cmd, name); - - /* If RESP_DELIM is specified, we search for that as a leading - delimiter for the register value. Otherwise, we just start - searching from the start of the buf. */ - - if (current_monitor->getreg.resp_delim) - { - monitor_debug ("EXP getreg.resp_delim\n"); - monitor_expect (current_monitor->getreg.resp_delim, NULL, 0); - /* Handle case of first 32 registers listed in pairs. */ - if (current_monitor->flags & MO_32_REGS_PAIRED - && (regno & 1) != 0 && regno < 32) - { - monitor_debug ("EXP getreg.resp_delim\n"); - monitor_expect (current_monitor->getreg.resp_delim, NULL, 0); - } - } - - /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */ - if (current_monitor->flags & MO_HEX_PREFIX) - { - int c; - c = readchar (timeout); - while (c == ' ') - c = readchar (timeout); - if ((c == '0') && ((c = readchar (timeout)) == 'x')) - ; - else - error ("Bad value returned from monitor while fetching register %x.", - regno); - } - - /* Read upto the maximum number of hex digits for this register, skipping - spaces, but stop reading if something else is seen. Some monitors - like to drop leading zeros. */ - - for (i = 0; i < REGISTER_RAW_SIZE (regno) * 2; i++) - { - int c; - c = readchar (timeout); - while (c == ' ') - c = readchar (timeout); - - if (!isxdigit (c)) - break; - - regbuf[i] = c; - } - - regbuf[i] = '\000'; /* terminate the number */ - monitor_debug ("REGVAL '%s'\n", regbuf); - - /* If TERM is present, we wait for that to show up. Also, (if TERM - is present), we will send TERM_CMD if that is present. In any - case, we collect all of the output into buf, and then wait for - the normal prompt. */ - - if (current_monitor->getreg.term) - { - monitor_debug ("EXP getreg.term\n"); - monitor_expect (current_monitor->getreg.term, NULL, 0); /* get response */ - } - - if (current_monitor->getreg.term_cmd) - { - monitor_debug ("EMIT getreg.term.cmd\n"); - monitor_printf (current_monitor->getreg.term_cmd); - } - if (!current_monitor->getreg.term || /* Already expected or */ - current_monitor->getreg.term_cmd) /* ack expected */ - monitor_expect_prompt (NULL, 0); /* get response */ - - monitor_supply_register (regno, regbuf); -} - -/* Sometimes, it takes several commands to dump the registers */ -/* This is a primitive for use by variations of monitor interfaces in - case they need to compose the operation. - */ -int -monitor_dump_reg_block (char *block_cmd) -{ - char buf[TARGET_BUF_SIZE]; - int resp_len; - monitor_printf (block_cmd); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - parse_register_dump (buf, resp_len); - return 1; -} - - -/* Read the remote registers into the block regs. */ -/* Call the specific function if it has been provided */ - -static void -monitor_dump_regs (void) -{ - char buf[TARGET_BUF_SIZE]; - int resp_len; - if (current_monitor->dumpregs) - (*(current_monitor->dumpregs)) (); /* call supplied function */ - else if (current_monitor->dump_registers) /* default version */ - { - monitor_printf (current_monitor->dump_registers); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - parse_register_dump (buf, resp_len); - } - else - internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Need some way to read registers */ -} - -static void -monitor_fetch_registers (int regno) -{ - monitor_debug ("MON fetchregs\n"); - if (current_monitor->getreg.cmd) - { - if (regno >= 0) - { - monitor_fetch_register (regno); - return; - } - - for (regno = 0; regno < NUM_REGS; regno++) - monitor_fetch_register (regno); - } - else - { - monitor_dump_regs (); - } -} - -/* Store register REGNO, or all if REGNO == 0. Return errno value. */ - -static void -monitor_store_register (int regno) -{ - char *name; - ULONGEST val; - - name = current_monitor->regnames[regno]; - if (!name || (*name == '\0')) - { - monitor_debug ("MON Cannot store unknown register\n"); - return; - } - - val = read_register (regno); - monitor_debug ("MON storeg %d %s\n", regno, - phex (val, REGISTER_RAW_SIZE (regno))); - - /* send the register deposit command */ - - if (current_monitor->flags & MO_REGISTER_VALUE_FIRST) - monitor_printf (current_monitor->setreg.cmd, val, name); - else if (current_monitor->flags & MO_SETREG_INTERACTIVE) - monitor_printf (current_monitor->setreg.cmd, name); - else - monitor_printf (current_monitor->setreg.cmd, name, val); - - if (current_monitor->setreg.resp_delim) - { - monitor_debug ("EXP setreg.resp_delim\n"); - monitor_expect_regexp (&setreg_resp_delim_pattern, NULL, 0); - if (current_monitor->flags & MO_SETREG_INTERACTIVE) - monitor_printf ("%s\r", paddr_nz (val)); - } - if (current_monitor->setreg.term) - { - monitor_debug ("EXP setreg.term\n"); - monitor_expect (current_monitor->setreg.term, NULL, 0); - if (current_monitor->flags & MO_SETREG_INTERACTIVE) - monitor_printf ("%s\r", paddr_nz (val)); - monitor_expect_prompt (NULL, 0); - } - else - monitor_expect_prompt (NULL, 0); - if (current_monitor->setreg.term_cmd) /* Mode exit required */ - { - monitor_debug ("EXP setreg_termcmd\n"); - monitor_printf ("%s", current_monitor->setreg.term_cmd); - monitor_expect_prompt (NULL, 0); - } -} /* monitor_store_register */ - -/* Store the remote registers. */ - -static void -monitor_store_registers (int regno) -{ - if (regno >= 0) - { - monitor_store_register (regno); - return; - } - - for (regno = 0; regno < NUM_REGS; regno++) - monitor_store_register (regno); -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -monitor_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -static void -monitor_files_info (struct target_ops *ops) -{ - printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baud_rate); -} - -static int -monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - unsigned int val, hostval; - char *cmd; - int i; - - monitor_debug ("MON write %d %s\n", len, paddr (memaddr)); - - if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - memaddr = ADDR_BITS_REMOVE (memaddr); - - /* Use memory fill command for leading 0 bytes. */ - - if (current_monitor->fill) - { - for (i = 0; i < len; i++) - if (myaddr[i] != 0) - break; - - if (i > 4) /* More than 4 zeros is worth doing */ - { - monitor_debug ("MON FILL %d\n", i); - if (current_monitor->flags & MO_FILL_USES_ADDR) - monitor_printf (current_monitor->fill, memaddr, (memaddr + i) - 1, 0); - else - monitor_printf (current_monitor->fill, memaddr, i, 0); - - monitor_expect_prompt (NULL, 0); - - return i; - } - } - -#if 0 - /* Can't actually use long longs if VAL is an int (nice idea, though). */ - if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->setmem.cmdll) - { - len = 8; - cmd = current_monitor->setmem.cmdll; - } - else -#endif - if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->setmem.cmdl) - { - len = 4; - cmd = current_monitor->setmem.cmdl; - } - else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->setmem.cmdw) - { - len = 2; - cmd = current_monitor->setmem.cmdw; - } - else - { - len = 1; - cmd = current_monitor->setmem.cmdb; - } - - val = extract_unsigned_integer (myaddr, len); - - if (len == 4) - { - hostval = *(unsigned int *) myaddr; - monitor_debug ("Hostval(%08x) val(%08x)\n", hostval, val); - } - - - if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM) - monitor_printf_noecho (cmd, memaddr, val); - else if (current_monitor->flags & MO_SETMEM_INTERACTIVE) - { - - monitor_printf_noecho (cmd, memaddr); - - if (current_monitor->setmem.resp_delim) - { - monitor_debug ("EXP setmem.resp_delim"); - monitor_expect_regexp (&setmem_resp_delim_pattern, NULL, 0); - monitor_printf ("%x\r", val); - } - if (current_monitor->setmem.term) - { - monitor_debug ("EXP setmem.term"); - monitor_expect (current_monitor->setmem.term, NULL, 0); - monitor_printf ("%x\r", val); - } - if (current_monitor->setmem.term_cmd) - { /* Emit this to get out of the memory editing state */ - monitor_printf ("%s", current_monitor->setmem.term_cmd); - /* Drop through to expecting a prompt */ - } - } - else - monitor_printf (cmd, memaddr, val); - - monitor_expect_prompt (NULL, 0); - - return len; -} - - -static int -monitor_write_even_block (CORE_ADDR memaddr, char *myaddr, int len) -{ - unsigned int val; - int written = 0;; - /* Enter the sub mode */ - monitor_printf (current_monitor->setmem.cmdl, memaddr); - monitor_expect_prompt (NULL, 0); - - while (len) - { - val = extract_unsigned_integer (myaddr, 4); /* REALLY */ - monitor_printf ("%x\r", val); - myaddr += 4; - memaddr += 4; - written += 4; - monitor_debug (" @ %s\n", paddr (memaddr)); - /* If we wanted to, here we could validate the address */ - monitor_expect_prompt (NULL, 0); - } - /* Now exit the sub mode */ - monitor_printf (current_monitor->getreg.term_cmd); - monitor_expect_prompt (NULL, 0); - return written; -} - - -static int -monitor_write_memory_bytes (CORE_ADDR memaddr, char *myaddr, int len) -{ - unsigned char val; - int written = 0; - if (len == 0) - return 0; - /* Enter the sub mode */ - monitor_printf (current_monitor->setmem.cmdb, memaddr); - monitor_expect_prompt (NULL, 0); - while (len) - { - val = *myaddr; - monitor_printf ("%x\r", val); - myaddr++; - memaddr++; - written++; - /* If we wanted to, here we could validate the address */ - monitor_expect_prompt (NULL, 0); - len--; - } - /* Now exit the sub mode */ - monitor_printf (current_monitor->getreg.term_cmd); - monitor_expect_prompt (NULL, 0); - return written; -} - - -static void -longlongendswap (unsigned char *a) -{ - int i, j; - unsigned char x; - i = 0; - j = 7; - while (i < 4) - { - x = *(a + i); - *(a + i) = *(a + j); - *(a + j) = x; - i++, j--; - } -} -/* Format 32 chars of long long value, advance the pointer */ -static char *hexlate = "0123456789abcdef"; -static char * -longlong_hexchars (unsigned long long value, - char *outbuff) -{ - if (value == 0) - { - *outbuff++ = '0'; - return outbuff; - } - else - { - static unsigned char disbuf[8]; /* disassembly buffer */ - unsigned char *scan, *limit; /* loop controls */ - unsigned char c, nib; - int leadzero = 1; - scan = disbuf; - limit = scan + 8; - { - unsigned long long *dp; - dp = (unsigned long long *) scan; - *dp = value; - } - longlongendswap (disbuf); /* FIXME: ONly on big endian hosts */ - while (scan < limit) - { - c = *scan++; /* a byte of our long long value */ - if (leadzero) - { - if (c == 0) - continue; - else - leadzero = 0; /* henceforth we print even zeroes */ - } - nib = c >> 4; /* high nibble bits */ - *outbuff++ = hexlate[nib]; - nib = c & 0x0f; /* low nibble bits */ - *outbuff++ = hexlate[nib]; - } - return outbuff; - } -} /* longlong_hexchars */ - - - -/* I am only going to call this when writing virtual byte streams. - Which possably entails endian conversions - */ -static int -monitor_write_memory_longlongs (CORE_ADDR memaddr, char *myaddr, int len) -{ - static char hexstage[20]; /* At least 16 digits required, plus null */ - char *endstring; - long long *llptr; - long long value; - int written = 0; - llptr = (unsigned long long *) myaddr; - if (len == 0) - return 0; - monitor_printf (current_monitor->setmem.cmdll, memaddr); - monitor_expect_prompt (NULL, 0); - while (len >= 8) - { - value = *llptr; - endstring = longlong_hexchars (*llptr, hexstage); - *endstring = '\0'; /* NUll terminate for printf */ - monitor_printf ("%s\r", hexstage); - llptr++; - memaddr += 8; - written += 8; - /* If we wanted to, here we could validate the address */ - monitor_expect_prompt (NULL, 0); - len -= 8; - } - /* Now exit the sub mode */ - monitor_printf (current_monitor->getreg.term_cmd); - monitor_expect_prompt (NULL, 0); - return written; -} /* */ - - - -/* ----- MONITOR_WRITE_MEMORY_BLOCK ---------------------------- */ -/* This is for the large blocks of memory which may occur in downloading. - And for monitors which use interactive entry, - And for monitors which do not have other downloading methods. - Without this, we will end up calling monitor_write_memory many times - and do the entry and exit of the sub mode many times - This currently assumes... - MO_SETMEM_INTERACTIVE - ! MO_NO_ECHO_ON_SETMEM - To use this, the you have to patch the monitor_cmds block with - this function. Otherwise, its not tuned up for use by all - monitor variations. - */ - -static int -monitor_write_memory_block (CORE_ADDR memaddr, char *myaddr, int len) -{ - int written; - written = 0; - /* FIXME: This would be a good place to put the zero test */ -#if 1 - if ((len > 8) && (((len & 0x07)) == 0) && current_monitor->setmem.cmdll) - { - return monitor_write_memory_longlongs (memaddr, myaddr, len); - } -#endif -#if 0 - if (len > 4) - { - int sublen; - written = monitor_write_even_block (memaddr, myaddr, len); - /* Adjust calling parameters by written amount */ - memaddr += written; - myaddr += written; - len -= written; - } -#endif - written = monitor_write_memory_bytes (memaddr, myaddr, len); - return written; -} - -/* This is an alternate form of monitor_read_memory which is used for monitors - which can only read a single byte/word/etc. at a time. */ - -static int -monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len) -{ - unsigned int val; - char membuf[sizeof (int) * 2 + 1]; - char *p; - char *cmd; - - monitor_debug ("MON read single\n"); -#if 0 - /* Can't actually use long longs (nice idea, though). In fact, the - call to strtoul below will fail if it tries to convert a value - that's too big to fit in a long. */ - if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->getmem.cmdll) - { - len = 8; - cmd = current_monitor->getmem.cmdll; - } - else -#endif - if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->getmem.cmdl) - { - len = 4; - cmd = current_monitor->getmem.cmdl; - } - else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->getmem.cmdw) - { - len = 2; - cmd = current_monitor->getmem.cmdw; - } - else - { - len = 1; - cmd = current_monitor->getmem.cmdb; - } - - /* Send the examine command. */ - - monitor_printf (cmd, memaddr); - - /* If RESP_DELIM is specified, we search for that as a leading - delimiter for the memory value. Otherwise, we just start - searching from the start of the buf. */ - - if (current_monitor->getmem.resp_delim) - { - monitor_debug ("EXP getmem.resp_delim\n"); - monitor_expect_regexp (&getmem_resp_delim_pattern, NULL, 0); - } - - /* Now, read the appropriate number of hex digits for this loc, - skipping spaces. */ - - /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set. */ - if (current_monitor->flags & MO_HEX_PREFIX) - { - int c; - - c = readchar (timeout); - while (c == ' ') - c = readchar (timeout); - if ((c == '0') && ((c = readchar (timeout)) == 'x')) - ; - else - monitor_error ("monitor_read_memory_single", - "bad response from monitor", - memaddr, 0, NULL, 0); - } - - { - int i; - for (i = 0; i < len * 2; i++) - { - int c; - - while (1) - { - c = readchar (timeout); - if (isxdigit (c)) - break; - if (c == ' ') - continue; - - monitor_error ("monitor_read_memory_single", - "bad response from monitor", - memaddr, i, membuf, 0); - } - membuf[i] = c; - } - membuf[i] = '\000'; /* terminate the number */ - } - -/* If TERM is present, we wait for that to show up. Also, (if TERM is - present), we will send TERM_CMD if that is present. In any case, we collect - all of the output into buf, and then wait for the normal prompt. */ - - if (current_monitor->getmem.term) - { - monitor_expect (current_monitor->getmem.term, NULL, 0); /* get response */ - - if (current_monitor->getmem.term_cmd) - { - monitor_printf (current_monitor->getmem.term_cmd); - monitor_expect_prompt (NULL, 0); - } - } - else - monitor_expect_prompt (NULL, 0); /* get response */ - - p = membuf; - val = strtoul (membuf, &p, 16); - - if (val == 0 && membuf == p) - monitor_error ("monitor_read_memory_single", - "bad value from monitor", - memaddr, 0, membuf, 0); - - /* supply register stores in target byte order, so swap here */ - - store_unsigned_integer (myaddr, len, val); - - return len; -} - -/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's - memory at MEMADDR. Returns length moved. Currently, we do no more - than 16 bytes at a time. */ - -static int -monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - unsigned int val; - char buf[512]; - char *p, *p1; - int resp_len; - int i; - CORE_ADDR dumpaddr; - - if (len <= 0) - { - monitor_debug ("Zero length call to monitor_read_memory\n"); - return 0; - } - - monitor_debug ("MON read block ta(%s) ha(%lx) %d\n", - paddr_nz (memaddr), (long) myaddr, len); - - if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - memaddr = ADDR_BITS_REMOVE (memaddr); - - if (current_monitor->flags & MO_GETMEM_READ_SINGLE) - return monitor_read_memory_single (memaddr, myaddr, len); - - len = min (len, 16); - - /* Some dumpers align the first data with the preceeding 16 - byte boundary. Some print blanks and start at the - requested boundary. EXACT_DUMPADDR - */ - - dumpaddr = (current_monitor->flags & MO_EXACT_DUMPADDR) - ? memaddr : memaddr & ~0x0f; - - /* See if xfer would cross a 16 byte boundary. If so, clip it. */ - if (((memaddr ^ (memaddr + len - 1)) & ~0xf) != 0) - len = ((memaddr + len) & ~0xf) - memaddr; - - /* send the memory examine command */ - - if (current_monitor->flags & MO_GETMEM_NEEDS_RANGE) - monitor_printf (current_monitor->getmem.cmdb, memaddr, memaddr + len); - else if (current_monitor->flags & MO_GETMEM_16_BOUNDARY) - monitor_printf (current_monitor->getmem.cmdb, dumpaddr); - else - monitor_printf (current_monitor->getmem.cmdb, memaddr, len); - - /* If TERM is present, we wait for that to show up. Also, (if TERM - is present), we will send TERM_CMD if that is present. In any - case, we collect all of the output into buf, and then wait for - the normal prompt. */ - - if (current_monitor->getmem.term) - { - resp_len = monitor_expect (current_monitor->getmem.term, buf, sizeof buf); /* get response */ - - if (resp_len <= 0) - monitor_error ("monitor_read_memory", - "excessive response from monitor", - memaddr, resp_len, buf, 0); - - if (current_monitor->getmem.term_cmd) - { - serial_write (monitor_desc, current_monitor->getmem.term_cmd, - strlen (current_monitor->getmem.term_cmd)); - monitor_expect_prompt (NULL, 0); - } - } - else - resp_len = monitor_expect_prompt (buf, sizeof buf); /* get response */ - - p = buf; - - /* If RESP_DELIM is specified, we search for that as a leading - delimiter for the values. Otherwise, we just start searching - from the start of the buf. */ - - if (current_monitor->getmem.resp_delim) - { - int retval, tmp; - struct re_registers resp_strings; - monitor_debug ("MON getmem.resp_delim %s\n", current_monitor->getmem.resp_delim); - - memset (&resp_strings, 0, sizeof (struct re_registers)); - tmp = strlen (p); - retval = re_search (&getmem_resp_delim_pattern, p, tmp, 0, tmp, - &resp_strings); - - if (retval < 0) - monitor_error ("monitor_read_memory", - "bad response from monitor", - memaddr, resp_len, buf, 0); - - p += resp_strings.end[0]; -#if 0 - p = strstr (p, current_monitor->getmem.resp_delim); - if (!p) - monitor_error ("monitor_read_memory", - "bad response from monitor", - memaddr, resp_len, buf, 0); - p += strlen (current_monitor->getmem.resp_delim); -#endif - } - monitor_debug ("MON scanning %d ,%lx '%s'\n", len, (long) p, p); - if (current_monitor->flags & MO_GETMEM_16_BOUNDARY) - { - char c; - int fetched = 0; - i = len; - c = *p; - - - while (!(c == '\000' || c == '\n' || c == '\r') && i > 0) - { - if (isxdigit (c)) - { - if ((dumpaddr >= memaddr) && (i > 0)) - { - val = fromhex (c) * 16 + fromhex (*(p + 1)); - *myaddr++ = val; - if (monitor_debug_p || remote_debug) - fprintf_unfiltered (gdb_stdlog, "[%02x]", val); - --i; - fetched++; - } - ++dumpaddr; - ++p; - } - ++p; /* skip a blank or other non hex char */ - c = *p; - } - if (fetched == 0) - error ("Failed to read via monitor"); - if (monitor_debug_p || remote_debug) - fprintf_unfiltered (gdb_stdlog, "\n"); - return fetched; /* Return the number of bytes actually read */ - } - monitor_debug ("MON scanning bytes\n"); - - for (i = len; i > 0; i--) - { - /* Skip non-hex chars, but bomb on end of string and newlines */ - - while (1) - { - if (isxdigit (*p)) - break; - - if (*p == '\000' || *p == '\n' || *p == '\r') - monitor_error ("monitor_read_memory", - "badly terminated response from monitor", - memaddr, resp_len, buf, 0); - p++; - } - - val = strtoul (p, &p1, 16); - - if (val == 0 && p == p1) - monitor_error ("monitor_read_memory", - "bad value from monitor", - memaddr, resp_len, buf, 0); - - *myaddr++ = val; - - if (i == 1) - break; - - p = p1; - } - - return len; -} - -/* Transfer LEN bytes between target address MEMADDR and GDB address - MYADDR. Returns 0 for success, errno code for failure. TARGET is - unused. */ - -static int -monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, struct target_ops *target) -{ - int res; - - if (write) - { - if (current_monitor->flags & MO_HAS_BLOCKWRITES) - res = monitor_write_memory_block(memaddr, myaddr, len); - else - res = monitor_write_memory(memaddr, myaddr, len); - } - else - { - res = monitor_read_memory(memaddr, myaddr, len); - } - - return res; -} - -static void -monitor_kill (void) -{ - return; /* ignore attempts to kill target system */ -} - -/* All we actually do is set the PC to the start address of exec_bfd, and start - the program at that point. */ - -static void -monitor_create_inferior (char *exec_file, char *args, char **env) -{ - if (args && (*args != '\000')) - error ("Args are not supported by the monitor."); - - first_time = 1; - clear_proceed_status (); - proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0); -} - -/* Clean up when a program exits. - The program actually lives on in the remote processor's RAM, and may be - run again without a download. Don't leave it full of breakpoint - instructions. */ - -static void -monitor_mourn_inferior (void) -{ - unpush_target (targ_ops); - generic_mourn_inferior (); /* Do all the proper things now */ -} - -/* Tell the monitor to add a breakpoint. */ - -static int -monitor_insert_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - unsigned char *bp; - int bplen; - - monitor_debug ("MON inst bkpt %s\n", paddr (addr)); - if (current_monitor->set_break == NULL) - error ("No set_break defined for this monitor"); - - if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - addr = ADDR_BITS_REMOVE (addr); - - /* Determine appropriate breakpoint size for this address. */ - bp = memory_breakpoint_from_pc (&addr, &bplen); - - for (i = 0; i < current_monitor->num_breakpoints; i++) - { - if (breakaddr[i] == 0) - { - breakaddr[i] = addr; - monitor_read_memory (addr, shadow, bplen); - monitor_printf (current_monitor->set_break, addr); - monitor_expect_prompt (NULL, 0); - return 0; - } - } - - error ("Too many breakpoints (> %d) for monitor.", current_monitor->num_breakpoints); -} - -/* Tell the monitor to remove a breakpoint. */ - -static int -monitor_remove_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - - monitor_debug ("MON rmbkpt %s\n", paddr (addr)); - if (current_monitor->clr_break == NULL) - error ("No clr_break defined for this monitor"); - - if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - addr = ADDR_BITS_REMOVE (addr); - - for (i = 0; i < current_monitor->num_breakpoints; i++) - { - if (breakaddr[i] == addr) - { - breakaddr[i] = 0; - /* some monitors remove breakpoints based on the address */ - if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR) - monitor_printf (current_monitor->clr_break, addr); - else if (current_monitor->flags & MO_CLR_BREAK_1_BASED) - monitor_printf (current_monitor->clr_break, i + 1); - else - monitor_printf (current_monitor->clr_break, i); - monitor_expect_prompt (NULL, 0); - return 0; - } - } - fprintf_unfiltered (gdb_stderr, - "Can't find breakpoint associated with 0x%s\n", - paddr_nz (addr)); - return 1; -} - -/* monitor_wait_srec_ack -- wait for the target to send an acknowledgement for - an S-record. Return non-zero if the ACK is received properly. */ - -static int -monitor_wait_srec_ack (void) -{ - int ch; - - if (current_monitor->flags & MO_SREC_ACK_PLUS) - { - return (readchar (timeout) == '+'); - } - else if (current_monitor->flags & MO_SREC_ACK_ROTATE) - { - /* Eat two backspaces, a "rotating" char (|/-\), and a space. */ - if ((ch = readchar (1)) < 0) - return 0; - if ((ch = readchar (1)) < 0) - return 0; - if ((ch = readchar (1)) < 0) - return 0; - if ((ch = readchar (1)) < 0) - return 0; - } - return 1; -} - -/* monitor_load -- download a file. */ - -static void -monitor_load (char *file, int from_tty) -{ - monitor_debug ("MON load\n"); - - if (current_monitor->load_routine) - current_monitor->load_routine (monitor_desc, file, hashmark); - else - { /* The default is ascii S-records */ - int n; - unsigned long load_offset; - char buf[128]; - - /* enable user to specify address for downloading as 2nd arg to load */ - n = sscanf (file, "%s 0x%lx", buf, &load_offset); - if (n > 1) - file = buf; - else - load_offset = 0; - - monitor_printf (current_monitor->load); - if (current_monitor->loadresp) - monitor_expect (current_monitor->loadresp, NULL, 0); - - load_srec (monitor_desc, file, (bfd_vma) load_offset, - 32, SREC_ALL, hashmark, - current_monitor->flags & MO_SREC_ACK ? - monitor_wait_srec_ack : NULL); - - monitor_expect_prompt (NULL, 0); - } - - /* Finally, make the PC point at the start address */ - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - /* There used to be code here which would clear inferior_ptid and - call clear_symtab_users. None of that should be necessary: - monitor targets should behave like remote protocol targets, and - since generic_load does none of those things, this function - shouldn't either. - - Furthermore, clearing inferior_ptid is *incorrect*. After doing - a load, we still have a valid connection to the monitor, with a - live processor state to fiddle with. The user can type - `continue' or `jump *start' and make the program run. If they do - these things, however, GDB will be talking to a running program - while inferior_ptid is null_ptid; this makes things like - reinit_frame_cache very confused. */ -} - -static void -monitor_stop (void) -{ - monitor_debug ("MON stop\n"); - if ((current_monitor->flags & MO_SEND_BREAK_ON_STOP) != 0) - serial_send_break (monitor_desc); - if (current_monitor->stop) - monitor_printf_noecho (current_monitor->stop); -} - -/* Put a COMMAND string out to MONITOR. Output from MONITOR is placed - in OUTPUT until the prompt is seen. FIXME: We read the characters - ourseleves here cause of a nasty echo. */ - -static void -monitor_rcmd (char *command, - struct ui_file *outbuf) -{ - char *p; - int resp_len; - char buf[1000]; - - if (monitor_desc == NULL) - error ("monitor target not open."); - - p = current_monitor->prompt; - - /* Send the command. Note that if no args were supplied, then we're - just sending the monitor a newline, which is sometimes useful. */ - - monitor_printf ("%s\r", (command ? command : "")); - - resp_len = monitor_expect_prompt (buf, sizeof buf); - - fputs_unfiltered (buf, outbuf); /* Output the response */ -} - -/* Convert hex digit A to a number. */ - -#if 0 -static int -from_hex (int a) -{ - if (a >= '0' && a <= '9') - return a - '0'; - if (a >= 'a' && a <= 'f') - return a - 'a' + 10; - if (a >= 'A' && a <= 'F') - return a - 'A' + 10; - - error ("Reply contains invalid hex digit 0x%x", a); -} -#endif - -char * -monitor_get_dev_name (void) -{ - return dev_name; -} - -static struct target_ops monitor_ops; - -static void -init_base_monitor_ops (void) -{ - monitor_ops.to_shortname = NULL; - monitor_ops.to_longname = NULL; - monitor_ops.to_doc = NULL; - monitor_ops.to_open = NULL; - monitor_ops.to_close = monitor_close; - monitor_ops.to_attach = NULL; - monitor_ops.to_post_attach = NULL; - monitor_ops.to_require_attach = NULL; - monitor_ops.to_detach = monitor_detach; - monitor_ops.to_require_detach = NULL; - monitor_ops.to_resume = monitor_resume; - monitor_ops.to_wait = monitor_wait; - monitor_ops.to_post_wait = NULL; - monitor_ops.to_fetch_registers = monitor_fetch_registers; - monitor_ops.to_store_registers = monitor_store_registers; - monitor_ops.to_prepare_to_store = monitor_prepare_to_store; - monitor_ops.to_xfer_memory = monitor_xfer_memory; - monitor_ops.to_files_info = monitor_files_info; - monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint; - monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint; - monitor_ops.to_terminal_init = 0; - monitor_ops.to_terminal_inferior = 0; - monitor_ops.to_terminal_ours_for_output = 0; - monitor_ops.to_terminal_ours = 0; - monitor_ops.to_terminal_info = 0; - monitor_ops.to_kill = monitor_kill; - monitor_ops.to_load = monitor_load; - monitor_ops.to_lookup_symbol = 0; - monitor_ops.to_create_inferior = monitor_create_inferior; - monitor_ops.to_post_startup_inferior = NULL; - monitor_ops.to_acknowledge_created_inferior = NULL; - monitor_ops.to_clone_and_follow_inferior = NULL; - monitor_ops.to_post_follow_inferior_by_clone = NULL; - monitor_ops.to_insert_fork_catchpoint = NULL; - monitor_ops.to_remove_fork_catchpoint = NULL; - monitor_ops.to_insert_vfork_catchpoint = NULL; - monitor_ops.to_remove_vfork_catchpoint = NULL; - monitor_ops.to_has_forked = NULL; - monitor_ops.to_has_vforked = NULL; - monitor_ops.to_can_follow_vfork_prior_to_exec = NULL; - monitor_ops.to_post_follow_vfork = NULL; - monitor_ops.to_insert_exec_catchpoint = NULL; - monitor_ops.to_remove_exec_catchpoint = NULL; - monitor_ops.to_has_execd = NULL; - monitor_ops.to_reported_exec_events_per_exec_call = NULL; - monitor_ops.to_has_exited = NULL; - monitor_ops.to_mourn_inferior = monitor_mourn_inferior; - monitor_ops.to_can_run = 0; - monitor_ops.to_notice_signals = 0; - monitor_ops.to_thread_alive = 0; - monitor_ops.to_stop = monitor_stop; - monitor_ops.to_rcmd = monitor_rcmd; - monitor_ops.to_pid_to_exec_file = NULL; - monitor_ops.to_stratum = process_stratum; - monitor_ops.DONT_USE = 0; - monitor_ops.to_has_all_memory = 1; - monitor_ops.to_has_memory = 1; - monitor_ops.to_has_stack = 1; - monitor_ops.to_has_registers = 1; - monitor_ops.to_has_execution = 1; - monitor_ops.to_sections = 0; - monitor_ops.to_sections_end = 0; - monitor_ops.to_magic = OPS_MAGIC; -} /* init_base_monitor_ops */ - -/* Init the target_ops structure pointed at by OPS */ - -void -init_monitor_ops (struct target_ops *ops) -{ - if (monitor_ops.to_magic != OPS_MAGIC) - init_base_monitor_ops (); - - memcpy (ops, &monitor_ops, sizeof monitor_ops); -} - -/* Define additional commands that are usually only used by monitors. */ - -void -_initialize_remote_monitors (void) -{ - init_base_monitor_ops (); - add_show_from_set (add_set_cmd ("hash", no_class, var_boolean, - (char *) &hashmark, - "Set display of activity while downloading a file.\n\ -When enabled, a hashmark \'#\' is displayed.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("monitor", no_class, var_zinteger, - (char *) &monitor_debug_p, - "Set debugging of remote monitor communication.\n\ -When enabled, communication between GDB and the remote monitor\n\ -is displayed.", &setdebuglist), - &showdebuglist); -} diff --git a/contrib/gdb/gdb/monitor.h b/contrib/gdb/gdb/monitor.h deleted file mode 100644 index 85a44ff7e71..00000000000 --- a/contrib/gdb/gdb/monitor.h +++ /dev/null @@ -1,254 +0,0 @@ -/* Definitions for remote debugging interface for ROM monitors. - Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. - Contributed by Cygnus Support. Written by Rob Savoye for Cygnus. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - */ - -#ifndef MONITOR_H -#define MONITOR_H - -struct serial; - -/* This structure describes the strings necessary to give small command - sequences to the monitor, and parse the response. - - CMD is the actual command typed at the monitor. Usually this has - embedded sequences ala printf, which are substituted with the - arguments appropriate to that type of command. Ie: to examine a - register, we substitute the register name for the first arg. To - modify memory, we substitute the memory location and the new - contents for the first and second args, etc... - - RESP_DELIM used to home in on the response string, and is used to - disambiguate the answer within the pile of text returned by the - monitor. This should be a unique string that immediately precedes - the answer. Ie: if your monitor prints out `PC: 00000001= ' in - response to asking for the PC, you should use `: ' as the - RESP_DELIM. RESP_DELIM may be NULL if the res- ponse is going to - be ignored, or has no particular leading text. - - TERM is the string that the monitor outputs to indicate that it is - idle, and waiting for input. This is usually a prompt of some - sort. In the previous example, it would be `= '. It is important - that TERM really means that the monitor is idle, otherwise GDB may - try to type at it when it isn't ready for input. This is a problem - because many monitors cannot deal with type-ahead. TERM may be - NULL if the normal prompt is output. - - TERM_CMD is used to quit out of the subcommand mode and get back to - the main prompt. TERM_CMD may be NULL if it isn't necessary. It - will also be ignored if TERM is NULL. */ - -struct memrw_cmd - { - char *cmdb; /* Command to send for byte read/write */ - char *cmdw; /* Command for word (16 bit) read/write */ - char *cmdl; /* Command for long (32 bit) read/write */ - char *cmdll; /* Command for long long (64 bit) read/write */ - char *resp_delim; /* String just prior to the desired value */ - char *term; /* Terminating string to search for */ - char *term_cmd; /* String to get out of sub-mode (if necessary) */ - }; - -struct regrw_cmd - { - char *cmd; /* Command to send for reg read/write */ - char *resp_delim; /* String (actually a regexp if getmem) just - prior to the desired value */ - char *term; /* Terminating string to search for */ - char *term_cmd; /* String to get out of sub-mode (if necessary) */ - }; - -struct monitor_ops - { - int flags; /* See below */ - char **init; /* List of init commands. NULL terminated. */ - char *cont; /* continue command */ - char *step; /* single step */ - char *stop; /* Interrupt program string */ - char *set_break; /* set a breakpoint. If NULL, monitor implementation - sets its own to_insert_breakpoint method. */ - char *clr_break; /* clear a breakpoint */ - char *clr_all_break; /* Clear all breakpoints */ - char *fill; /* Memory fill cmd (addr len val) */ - struct memrw_cmd setmem; /* set memory to a value */ - struct memrw_cmd getmem; /* display memory */ - struct regrw_cmd setreg; /* set a register */ - struct regrw_cmd getreg; /* get a register */ - /* Some commands can dump a bunch of registers - at once. This comes as a set of REG=VAL - pairs. This should be called for each pair - of registers that we can parse to supply - GDB with the value of a register. */ - char *dump_registers; /* Command to dump all regs at once */ - char *register_pattern; /* Pattern that picks out register from reg dump */ - void (*supply_register) (char *name, int namelen, char *val, int vallen); - void (*load_routine) (struct serial *desc, char *file, - int hashmark); /* Download routine */ - int (*dumpregs) (void); /* routine to dump all registers */ - int (*continue_hook) (void); /* Emit the continue command */ - int (*wait_filter) (char *buf, /* Maybe contains registers */ - int bufmax, - int *response_length, - struct target_waitstatus * status); - char *load; /* load command */ - char *loadresp; /* Response to load command */ - char *prompt; /* monitor command prompt */ - char *line_term; /* end-of-command delimitor */ - char *cmd_end; /* optional command terminator */ - struct target_ops *target; /* target operations */ - int stopbits; /* number of stop bits */ - char **regnames; /* array of register names in ascii */ - int num_breakpoints; /* If set_break != NULL, number of supported - breakpoints */ - int magic; /* Check value */ - }; - -/* The monitor ops magic number, used to detect if an ops structure doesn't - have the right number of entries filled in. */ - -#define MONITOR_OPS_MAGIC 600925 - -/* Flag definitions. */ - -/* If set, then clear breakpoint command uses address, otherwise it - uses an index returned by the monitor. */ - -#define MO_CLR_BREAK_USES_ADDR 0x1 - -/* If set, then memory fill command uses STARTADDR, ENDADDR+1, VALUE - as args, else it uses STARTADDR, LENGTH, VALUE as args. */ - -#define MO_FILL_USES_ADDR 0x2 - -/* If set, then monitor doesn't automatically supply register dump - when coming back after a continue. */ - -#define MO_NEED_REGDUMP_AFTER_CONT 0x4 - -/* getmem needs start addr and end addr */ - -#define MO_GETMEM_NEEDS_RANGE 0x8 - -/* getmem can only read one loc at a time */ - -#define MO_GETMEM_READ_SINGLE 0x10 - -/* handle \r\n combinations */ - -#define MO_HANDLE_NL 0x20 - -/* don't expect echos in monitor_open */ - -#define MO_NO_ECHO_ON_OPEN 0x40 - -/* If set, send break to stop monitor */ - -#define MO_SEND_BREAK_ON_STOP 0x80 - -/* If set, target sends an ACK after each S-record */ - -#define MO_SREC_ACK 0x100 - -/* Allow 0x prefix on addresses retured from monitor */ - -#define MO_HEX_PREFIX 0x200 - -/* Some monitors require a different command when starting a program */ - -#define MO_RUN_FIRST_TIME 0x400 - -/* Don't expect echos when getting memory */ - -#define MO_NO_ECHO_ON_SETMEM 0x800 - -/* If set, then register store command expects value BEFORE regname */ - -#define MO_REGISTER_VALUE_FIRST 0x1000 - -/* If set, then the monitor displays registers as pairs. */ - -#define MO_32_REGS_PAIRED 0x2000 - -/* If set, then register setting happens interactively. */ - -#define MO_SETREG_INTERACTIVE 0x4000 - -/* If set, then memory setting happens interactively. */ - -#define MO_SETMEM_INTERACTIVE 0x8000 - -/* If set, then memory dumps are always on 16-byte boundaries, even - when less is desired. */ - -#define MO_GETMEM_16_BOUNDARY 0x10000 - -/* If set, then the monitor numbers its breakpoints starting from 1. */ - -#define MO_CLR_BREAK_1_BASED 0x20000 - -/* If set, then the monitor acks srecords with a plus sign. */ - -#define MO_SREC_ACK_PLUS 0x40000 - -/* If set, then the monitor "acks" srecords with rotating lines. */ - -#define MO_SREC_ACK_ROTATE 0x80000 - -/* If set, then remove useless address bits from memory addresses. */ - -#define MO_ADDR_BITS_REMOVE 0x100000 - -/* If set, then display target program output if prefixed by ^O. */ - -#define MO_PRINT_PROGRAM_OUTPUT 0x200000 - -/* Some dump bytes commands align the first data with the preceeding - 16 byte boundary. Some print blanks and start at the exactly the - requested boundary. */ - -#define MO_EXACT_DUMPADDR 0x400000 - -/* Rather entering and exiting the write memory dialog for each word byte, - we can save time by transferring the whole block without exiting - the memory editing mode. You only need to worry about this - if you are doing memory downloading. - This engages a new write function registered with dcache. - */ -#define MO_HAS_BLOCKWRITES 0x800000 - -#define SREC_SIZE 160 - -extern void monitor_open (char *args, struct monitor_ops *ops, int from_tty); -extern void monitor_close (int quitting); -extern char *monitor_supply_register (int regno, char *valstr); -extern int monitor_expect (char *prompt, char *buf, int buflen); -extern int monitor_expect_prompt (char *buf, int buflen); -extern void monitor_printf (char *, ...) ATTR_FORMAT (printf, 1, 2); -extern void -monitor_printf_noecho (char *, ...) -ATTR_FORMAT (printf, 1, 2); -extern void monitor_write (char *buf, int buflen); -extern int monitor_readchar (void); -extern char *monitor_get_dev_name (void); -extern void init_monitor_ops (struct target_ops *); -extern int monitor_dump_reg_block (char *dump_cmd); - -#endif diff --git a/contrib/gdb/gdb/osfsolib.c b/contrib/gdb/gdb/osfsolib.c deleted file mode 100644 index 345ab0831a9..00000000000 --- a/contrib/gdb/gdb/osfsolib.c +++ /dev/null @@ -1,938 +0,0 @@ -/* Handle OSF/1 shared libraries for GDB, the GNU Debugger. - Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* FIXME: Most of this code could be merged with solib.c by using - next_link_map_member and xfer_link_map_member in solib.c. */ - -#include "defs.h" - -#include -#include -#include "gdb_string.h" -#include - -#include "symtab.h" -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdbcore.h" -#include "command.h" -#include "target.h" -#include "frame.h" -#include "gdb_regex.h" -#include "inferior.h" -#include "language.h" -#include "gdbcmd.h" - -#define MAX_PATH_SIZE 1024 /* FIXME: Should be dynamic */ - -/* When handling shared libraries, GDB has to find out the pathnames - of all shared libraries that are currently loaded (to read in their - symbols) and where the shared libraries are loaded in memory - (to relocate them properly from their prelinked addresses to the - current load address). - - Under OSF/1 there are two possibilities to get at this information: - 1) Peek around in the runtime loader structures. - These are not documented, and they are not defined in the system - header files. The definitions below were obtained by experimentation, - but they seem stable enough. - 2) Use the undocumented libxproc.a library, which contains the - equivalent ldr_* routines. - This approach is somewhat cleaner, but it requires that the GDB - executable is dynamically linked. In addition it requires a - NAT_CLIBS= -lxproc -Wl,-expect_unresolved,ldr_process_context - linker specification for GDB and all applications that are using - libgdb. - We will use the peeking approach until it becomes unwieldy. */ - -#ifndef USE_LDR_ROUTINES - -/* Definition of runtime loader structures, found by experimentation. */ -#define RLD_CONTEXT_ADDRESS 0x3ffc0000000 - -typedef struct - { - CORE_ADDR next; - CORE_ADDR previous; - CORE_ADDR unknown1; - char *module_name; - CORE_ADDR modinfo_addr; - long module_id; - CORE_ADDR unknown2; - CORE_ADDR unknown3; - long region_count; - CORE_ADDR regioninfo_addr; - } -ldr_module_info_t; - -typedef struct - { - long unknown1; - CORE_ADDR regionname_addr; - long protection; - CORE_ADDR vaddr; - CORE_ADDR mapaddr; - long size; - long unknown2[5]; - } -ldr_region_info_t; - -typedef struct - { - CORE_ADDR unknown1; - CORE_ADDR unknown2; - CORE_ADDR head; - CORE_ADDR tail; - } -ldr_context_t; - -static ldr_context_t ldr_context; - -#else - -#include -static ldr_process_t fake_ldr_process; - -/* Called by ldr_* routines to read memory from the current target. */ - -static int ldr_read_memory (CORE_ADDR, char *, int, int); - -static int -ldr_read_memory (CORE_ADDR memaddr, char *myaddr, int len, int readstring) -{ - int result; - char *buffer; - - if (readstring) - { - target_read_string (memaddr, &buffer, len, &result); - if (result == 0) - strcpy (myaddr, buffer); - xfree (buffer); - } - else - result = target_read_memory (memaddr, myaddr, len); - - if (result != 0) - result = -result; - return result; -} - -#endif - -/* Define our own link_map structure. - This will help to share code with solib.c. */ - -struct link_map -{ - CORE_ADDR l_offset; /* prelink to load address offset */ - char *l_name; /* full name of loaded object */ - ldr_module_info_t module_info; /* corresponding module info */ -}; - -#define LM_OFFSET(so) ((so) -> lm.l_offset) -#define LM_NAME(so) ((so) -> lm.l_name) - -struct so_list - { - struct so_list *next; /* next structure in linked list */ - struct link_map lm; /* copy of link map from inferior */ - struct link_map *lmaddr; /* addr in inferior lm was read from */ - CORE_ADDR lmend; /* upper addr bound of mapped object */ - char so_name[MAX_PATH_SIZE]; /* shared object lib name (FIXME) */ - char symbols_loaded; /* flag: symbols read in yet? */ - char from_tty; /* flag: print msgs? */ - struct objfile *objfile; /* objfile for loaded lib */ - struct section_table *sections; - struct section_table *sections_end; - struct section_table *textsection; - bfd *abfd; - }; - -static struct so_list *so_list_head; /* List of known shared objects */ - -extern int fdmatch (int, int); /* In libiberty */ - -/* Local function prototypes */ - -static void sharedlibrary_command (char *, int); - -static void info_sharedlibrary_command (char *, int); - -static int symbol_add_stub (char *); - -static struct so_list *find_solib (struct so_list *); - -static struct link_map *first_link_map_member (void); - -static struct link_map *next_link_map_member (struct so_list *); - -static void xfer_link_map_member (struct so_list *, struct link_map *); - -static int solib_map_sections (char *); - -/* - - LOCAL FUNCTION - - solib_map_sections -- open bfd and build sections for shared lib - - SYNOPSIS - - static int solib_map_sections (struct so_list *so) - - DESCRIPTION - - Given a pointer to one of the shared objects in our list - of mapped objects, use the recorded name to open a bfd - descriptor for the object, build a section table, and then - relocate all the section addresses by the base address at - which the shared object was mapped. - - FIXMES - - In most (all?) cases the shared object file name recorded in the - dynamic linkage tables will be a fully qualified pathname. For - cases where it isn't, do we really mimic the systems search - mechanism correctly in the below code (particularly the tilde - expansion stuff?). - */ - -static int -solib_map_sections (char *arg) -{ - struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */ - char *filename; - char *scratch_pathname; - int scratch_chan; - struct section_table *p; - struct cleanup *old_chain; - bfd *abfd; - - filename = tilde_expand (so->so_name); - old_chain = make_cleanup (xfree, filename); - - scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, - &scratch_pathname); - if (scratch_chan < 0) - { - scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename, - O_RDONLY, 0, &scratch_pathname); - } - if (scratch_chan < 0) - { - perror_with_name (filename); - } - /* Leave scratch_pathname allocated. bfd->name will point to it. */ - - abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan); - if (!abfd) - { - close (scratch_chan); - error ("Could not open `%s' as an executable file: %s", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } - /* Leave bfd open, core_xfer_memory and "info files" need it. */ - so->abfd = abfd; - abfd->cacheable = 1; - - if (!bfd_check_format (abfd, bfd_object)) - { - error ("\"%s\": not in executable format: %s.", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } - if (build_section_table (abfd, &so->sections, &so->sections_end)) - { - error ("Can't find the file sections in `%s': %s", - bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ())); - } - - for (p = so->sections; p < so->sections_end; p++) - { - /* Relocate the section binding addresses as recorded in the shared - object's file by the offset to get the address to which the - object was actually mapped. */ - p->addr += LM_OFFSET (so); - p->endaddr += LM_OFFSET (so); - so->lmend = (CORE_ADDR) max (p->endaddr, so->lmend); - if (STREQ (p->the_bfd_section->name, ".text")) - { - so->textsection = p; - } - } - - /* Free the file names, close the file now. */ - do_cleanups (old_chain); - - return (1); -} - -/* - - LOCAL FUNCTION - - first_link_map_member -- locate first member in dynamic linker's map - - SYNOPSIS - - static struct link_map *first_link_map_member (void) - - DESCRIPTION - - Read in a copy of the first member in the inferior's dynamic - link map from the inferior's dynamic linker structures, and return - a pointer to the copy in our address space. - */ - -static struct link_map * -first_link_map_member (void) -{ - struct link_map *lm = NULL; - static struct link_map first_lm; - -#ifdef USE_LDR_ROUTINES - ldr_module_t mod_id = LDR_NULL_MODULE; - size_t retsize; - - fake_ldr_process = ldr_core_process (); - ldr_set_core_reader (ldr_read_memory); - ldr_xdetach (fake_ldr_process); - if (ldr_xattach (fake_ldr_process) != 0 - || ldr_next_module (fake_ldr_process, &mod_id) != 0 - || mod_id == LDR_NULL_MODULE - || ldr_inq_module (fake_ldr_process, mod_id, - &first_lm.module_info, sizeof (ldr_module_info_t), - &retsize) != 0) - return lm; -#else - CORE_ADDR ldr_context_addr; - - if (target_read_memory ((CORE_ADDR) RLD_CONTEXT_ADDRESS, - (char *) &ldr_context_addr, - sizeof (CORE_ADDR)) != 0 - || target_read_memory (ldr_context_addr, - (char *) &ldr_context, - sizeof (ldr_context_t)) != 0 - || target_read_memory ((CORE_ADDR) ldr_context.head, - (char *) &first_lm.module_info, - sizeof (ldr_module_info_t)) != 0) - return lm; -#endif - - lm = &first_lm; - - /* The first entry is for the main program and should be skipped. */ - lm->l_name = NULL; - - return lm; -} - -static struct link_map * -next_link_map_member (struct so_list *so_list_ptr) -{ - struct link_map *lm = NULL; - static struct link_map next_lm; -#ifdef USE_LDR_ROUTINES - ldr_module_t mod_id = so_list_ptr->lm.module_info.lmi_modid; - size_t retsize; - - if (ldr_next_module (fake_ldr_process, &mod_id) != 0 - || mod_id == LDR_NULL_MODULE - || ldr_inq_module (fake_ldr_process, mod_id, - &next_lm.module_info, sizeof (ldr_module_info_t), - &retsize) != 0) - return lm; - - lm = &next_lm; - lm->l_name = lm->module_info.lmi_name; -#else - CORE_ADDR ldr_context_addr; - - /* Reread context in case ldr_context.tail was updated. */ - - if (target_read_memory ((CORE_ADDR) RLD_CONTEXT_ADDRESS, - (char *) &ldr_context_addr, - sizeof (CORE_ADDR)) != 0 - || target_read_memory (ldr_context_addr, - (char *) &ldr_context, - sizeof (ldr_context_t)) != 0 - || so_list_ptr->lm.module_info.modinfo_addr == ldr_context.tail - || target_read_memory (so_list_ptr->lm.module_info.next, - (char *) &next_lm.module_info, - sizeof (ldr_module_info_t)) != 0) - return lm; - - lm = &next_lm; - lm->l_name = lm->module_info.module_name; -#endif - return lm; -} - -static void -xfer_link_map_member (struct so_list *so_list_ptr, struct link_map *lm) -{ - int i; - so_list_ptr->lm = *lm; - - /* OSF/1 shared libraries are pre-linked to particular addresses, - but the runtime loader may have to relocate them if the - address ranges of the libraries used by the target executable clash, - or if the target executable is linked with the -taso option. - The offset is the difference between the address where the shared - library is mapped and the pre-linked address of the shared library. - - FIXME: GDB is currently unable to relocate the shared library - sections by different offsets. If sections are relocated by - different offsets, put out a warning and use the offset of the - first section for all remaining sections. */ - LM_OFFSET (so_list_ptr) = 0; - - /* There is one entry that has no name (for the inferior executable) - since it is not a shared object. */ - if (LM_NAME (so_list_ptr) != 0) - { - -#ifdef USE_LDR_ROUTINES - int len = strlen (LM_NAME (so_list_ptr) + 1); - - if (len > MAX_PATH_SIZE) - len = MAX_PATH_SIZE; - strncpy (so_list_ptr->so_name, LM_NAME (so_list_ptr), MAX_PATH_SIZE); - so_list_ptr->so_name[MAX_PATH_SIZE - 1] = '\0'; - - for (i = 0; i < lm->module_info.lmi_nregion; i++) - { - ldr_region_info_t region_info; - size_t retsize; - CORE_ADDR region_offset; - - if (ldr_inq_region (fake_ldr_process, lm->module_info.lmi_modid, - i, ®ion_info, sizeof (region_info), - &retsize) != 0) - break; - region_offset = (CORE_ADDR) region_info.lri_mapaddr - - (CORE_ADDR) region_info.lri_vaddr; - if (i == 0) - LM_OFFSET (so_list_ptr) = region_offset; - else if (LM_OFFSET (so_list_ptr) != region_offset) - warning ("cannot handle shared library relocation for %s (%s)", - so_list_ptr->so_name, region_info.lri_name); - } -#else - int errcode; - char *buffer; - target_read_string ((CORE_ADDR) LM_NAME (so_list_ptr), &buffer, - MAX_PATH_SIZE - 1, &errcode); - if (errcode != 0) - error ("xfer_link_map_member: Can't read pathname for load map: %s\n", - safe_strerror (errcode)); - strncpy (so_list_ptr->so_name, buffer, MAX_PATH_SIZE - 1); - xfree (buffer); - so_list_ptr->so_name[MAX_PATH_SIZE - 1] = '\0'; - - for (i = 0; i < lm->module_info.region_count; i++) - { - ldr_region_info_t region_info; - CORE_ADDR region_offset; - - if (target_read_memory (lm->module_info.regioninfo_addr - + i * sizeof (region_info), - (char *) ®ion_info, - sizeof (region_info)) != 0) - break; - region_offset = region_info.mapaddr - region_info.vaddr; - if (i == 0) - LM_OFFSET (so_list_ptr) = region_offset; - else if (LM_OFFSET (so_list_ptr) != region_offset) - { - char *region_name; - target_read_string (region_info.regionname_addr, &buffer, - MAX_PATH_SIZE - 1, &errcode); - if (errcode == 0) - region_name = buffer; - else - region_name = "??"; - warning ("cannot handle shared library relocation for %s (%s)", - so_list_ptr->so_name, region_name); - xfree (buffer); - } - } -#endif - - catch_errors (solib_map_sections, (char *) so_list_ptr, - "Error while mapping shared library sections:\n", - RETURN_MASK_ALL); - } -} - -/* - - LOCAL FUNCTION - - find_solib -- step through list of shared objects - - SYNOPSIS - - struct so_list *find_solib (struct so_list *so_list_ptr) - - DESCRIPTION - - This module contains the routine which finds the names of any - loaded "images" in the current process. The argument in must be - NULL on the first call, and then the returned value must be passed - in on subsequent calls. This provides the capability to "step" down - the list of loaded objects. On the last object, a NULL value is - returned. - - The arg and return value are "struct link_map" pointers, as defined - in . - */ - -static struct so_list * -find_solib (struct so_list *so_list_ptr) -{ - struct so_list *so_list_next = NULL; - struct link_map *lm = NULL; - struct so_list *new; - - if (so_list_ptr == NULL) - { - /* We are setting up for a new scan through the loaded images. */ - if ((so_list_next = so_list_head) == NULL) - { - /* Find the first link map list member. */ - lm = first_link_map_member (); - } - } - else - { - /* We have been called before, and are in the process of walking - the shared library list. Advance to the next shared object. */ - lm = next_link_map_member (so_list_ptr); - so_list_next = so_list_ptr->next; - } - if ((so_list_next == NULL) && (lm != NULL)) - { - /* Get next link map structure from inferior image and build a local - abbreviated load_map structure */ - new = (struct so_list *) xmalloc (sizeof (struct so_list)); - memset ((char *) new, 0, sizeof (struct so_list)); - new->lmaddr = lm; - /* Add the new node as the next node in the list, or as the root - node if this is the first one. */ - if (so_list_ptr != NULL) - { - so_list_ptr->next = new; - } - else - { - so_list_head = new; - } - so_list_next = new; - xfer_link_map_member (new, lm); - } - return (so_list_next); -} - -/* A small stub to get us past the arg-passing pinhole of catch_errors. */ - -static int -symbol_add_stub (char *arg) -{ - register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ - CORE_ADDR text_addr = 0; - struct section_addr_info section_addrs; - - memset (§ion_addrs, 0, sizeof (section_addrs)); - if (so->textsection) - text_addr = so->textsection->addr; - else if (so->abfd != NULL) - { - asection *lowest_sect; - - /* If we didn't find a mapped non zero sized .text section, set up - text_addr so that the relocation in symbol_file_add does no harm. */ - - lowest_sect = bfd_get_section_by_name (so->abfd, ".text"); - if (lowest_sect == NULL) - bfd_map_over_sections (so->abfd, find_lowest_section, - (PTR) &lowest_sect); - if (lowest_sect) - text_addr = bfd_section_vma (so->abfd, lowest_sect) + LM_OFFSET (so); - } - - section_addrs.other[0].addr = text_addr; - section_addrs.other[0].name = ".text"; - so->objfile = symbol_file_add (so->so_name, so->from_tty, - §ion_addrs, 0, OBJF_SHARED); - return (1); -} - -/* - - GLOBAL FUNCTION - - solib_add -- add a shared library file to the symtab and section list - - SYNOPSIS - - void solib_add (char *arg_string, int from_tty, - struct target_ops *target, int readsyms) - - DESCRIPTION - - */ - -void -solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) -{ - register struct so_list *so = NULL; /* link map state variable */ - - /* Last shared library that we read. */ - struct so_list *so_last = NULL; - - char *re_err; - int count; - int old; - - if (!readsyms) - return; - - if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL) - { - error ("Invalid regexp: %s", re_err); - } - - - /* Add the shared library sections to the section table of the - specified target, if any. */ - if (target) - { - /* Count how many new section_table entries there are. */ - so = NULL; - count = 0; - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0]) - { - count += so->sections_end - so->sections; - } - } - - if (count) - { - /* Add these section table entries to the target's table. */ - - old = target_resize_to_sections (target, count); - - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0]) - { - count = so->sections_end - so->sections; - memcpy ((char *) (target->to_sections + old), - so->sections, - (sizeof (struct section_table)) * count); - old += count; - } - } - } - } - - /* Now add the symbol files. */ - so = NULL; - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0] && re_exec (so->so_name)) - { - so->from_tty = from_tty; - if (so->symbols_loaded) - { - if (from_tty) - { - printf_unfiltered ("Symbols already loaded for %s\n", so->so_name); - } - } - else if (catch_errors - (symbol_add_stub, (char *) so, - "Error while reading shared library symbols:\n", - RETURN_MASK_ALL)) - { - so_last = so; - so->symbols_loaded = 1; - } - } - } - - /* Getting new symbols may change our opinion about what is - frameless. */ - if (so_last) - reinit_frame_cache (); -} - -/* - - LOCAL FUNCTION - - info_sharedlibrary_command -- code for "info sharedlibrary" - - SYNOPSIS - - static void info_sharedlibrary_command () - - DESCRIPTION - - Walk through the shared library list and print information - about each attached library. - */ - -static void -info_sharedlibrary_command (char *ignore, int from_tty) -{ - register struct so_list *so = NULL; /* link map state variable */ - int header_done = 0; - - if (exec_bfd == NULL) - { - printf_unfiltered ("No executable file.\n"); - return; - } - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0]) - { - unsigned long txt_start = 0; - unsigned long txt_end = 0; - - if (!header_done) - { - printf_unfiltered ("%-20s%-20s%-12s%s\n", "From", "To", "Syms Read", - "Shared Object Library"); - header_done++; - } - if (so->textsection) - { - txt_start = (unsigned long) so->textsection->addr; - txt_end = (unsigned long) so->textsection->endaddr; - } - printf_unfiltered ("%-20s", local_hex_string_custom (txt_start, "08l")); - printf_unfiltered ("%-20s", local_hex_string_custom (txt_end, "08l")); - printf_unfiltered ("%-12s", so->symbols_loaded ? "Yes" : "No"); - printf_unfiltered ("%s\n", so->so_name); - } - } - if (so_list_head == NULL) - { - printf_unfiltered ("No shared libraries loaded at this time.\n"); - } -} - -/* - - GLOBAL FUNCTION - - solib_address -- check to see if an address is in a shared lib - - SYNOPSIS - - char *solib_address (CORE_ADDR address) - - DESCRIPTION - - Provides a hook for other gdb routines to discover whether or - not a particular address is within the mapped address space of - a shared library. Any address between the base mapping address - and the first address beyond the end of the last mapping, is - considered to be within the shared library address space, for - our purposes. - - For example, this routine is called at one point to disable - breakpoints which are in shared libraries that are not currently - mapped in. - */ - -char * -solib_address (CORE_ADDR address) -{ - register struct so_list *so = 0; /* link map state variable */ - - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0] && so->textsection) - { - if ((address >= (CORE_ADDR) so->textsection->addr) && - (address < (CORE_ADDR) so->textsection->endaddr)) - return (so->so_name); - } - } - return (0); -} - -/* Called by free_all_symtabs */ - -void -clear_solib (void) -{ - struct so_list *next; - char *bfd_filename; - - disable_breakpoints_in_shlibs (1); - - while (so_list_head) - { - if (so_list_head->sections) - { - xfree (so_list_head->sections); - } - if (so_list_head->abfd) - { - remove_target_sections (so_list_head->abfd); - bfd_filename = bfd_get_filename (so_list_head->abfd); - if (!bfd_close (so_list_head->abfd)) - warning ("cannot close \"%s\": %s", - bfd_filename, bfd_errmsg (bfd_get_error ())); - } - else - /* This happens for the executable on SVR4. */ - bfd_filename = NULL; - - next = so_list_head->next; - if (bfd_filename) - xfree (bfd_filename); - xfree (so_list_head); - so_list_head = next; - } -} - -/* - - GLOBAL FUNCTION - - solib_create_inferior_hook -- shared library startup support - - SYNOPSIS - - void solib_create_inferior_hook() - - DESCRIPTION - - When gdb starts up the inferior, it nurses it along (through the - shell) until it is ready to execute it's first instruction. At this - point, this function gets called via expansion of the macro - SOLIB_CREATE_INFERIOR_HOOK. - For a statically bound executable, this first instruction is the - one at "_start", or a similar text label. No further processing is - needed in that case. - For a dynamically bound executable, this first instruction is somewhere - in the rld, and the actual user executable is not yet mapped in. - We continue the inferior again, rld then maps in the actual user - executable and any needed shared libraries and then sends - itself a SIGTRAP. - At that point we discover the names of all shared libraries and - read their symbols in. - - FIXME - - This code does not properly handle hitting breakpoints which the - user might have set in the rld itself. Proper handling would have - to check if the SIGTRAP happened due to a kill call. - - Also, what if child has exit()ed? Must exit loop somehow. - */ - -void -solib_create_inferior_hook (void) -{ - - /* Nothing to do for statically bound executables. */ - - if (symfile_objfile == NULL - || symfile_objfile->obfd == NULL - || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0)) - return; - - /* Now run the target. It will eventually get a SIGTRAP, at - which point all of the libraries will have been mapped in and we - can go groveling around in the rld structures to find - out what we need to know about them. */ - - clear_proceed_status (); - stop_soon_quietly = 1; - stop_signal = TARGET_SIGNAL_0; - do - { - target_resume (minus_one_ptid, 0, stop_signal); - wait_for_inferior (); - } - while (stop_signal != TARGET_SIGNAL_TRAP); - - /* solib_add will call reinit_frame_cache. - But we are stopped in the runtime loader and we do not have symbols - for the runtime loader. So heuristic_proc_start will be called - and will put out an annoying warning. - Delaying the resetting of stop_soon_quietly until after symbol loading - suppresses the warning. */ - solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); - stop_soon_quietly = 0; -} - - -/* - - LOCAL FUNCTION - - sharedlibrary_command -- handle command to explicitly add library - - SYNOPSIS - - static void sharedlibrary_command (char *args, int from_tty) - - DESCRIPTION - - */ - -static void -sharedlibrary_command (char *args, int from_tty) -{ - dont_repeat (); - solib_add (args, from_tty, (struct target_ops *) 0, 1); -} - -void -_initialize_solib (void) -{ - add_com ("sharedlibrary", class_files, sharedlibrary_command, - "Load shared object library symbols for files matching REGEXP."); - add_info ("sharedlibrary", info_sharedlibrary_command, - "Status of loaded shared object libraries."); - - add_show_from_set - (add_set_cmd ("auto-solib-add", class_support, var_boolean, - (char *) &auto_solib_add, - "Set autoloading of shared library symbols.\n\ -If \"on\", symbols from all shared object libraries will be loaded\n\ -automatically when the inferior begins execution, when the dynamic linker\n\ -informs gdb that a new library has been loaded, or when attaching to the\n\ -inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", - &setlist), - &showlist); -} diff --git a/contrib/gdb/gdb/ppcbug-rom.c b/contrib/gdb/gdb/ppcbug-rom.c deleted file mode 100644 index 712af06d3ff..00000000000 --- a/contrib/gdb/gdb/ppcbug-rom.c +++ /dev/null @@ -1,223 +0,0 @@ -/* Remote debugging interface for PPCbug (PowerPC) Rom monitor - for GDB, the GNU debugger. - Copyright 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - - Written by Stu Grossman of Cygnus Support - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "regcache.h" - -static void -ppcbug_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - int regno = 0; - - if (regnamelen < 2 || regnamelen > 4) - return; - - switch (regname[0]) - { - case 'R': - if (regname[1] < '0' || regname[1] > '9') - return; - if (regnamelen == 2) - regno = regname[1] - '0'; - else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9') - regno = (regname[1] - '0') * 10 + (regname[2] - '0'); - else - return; - break; - case 'F': - if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9') - return; - if (regnamelen == 3) - regno = 32 + regname[2] - '0'; - else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9') - regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0'); - else - return; - break; - case 'I': - if (regnamelen != 2 || regname[1] != 'P') - return; - regno = 64; - break; - case 'M': - if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R') - return; - regno = 65; - break; - case 'C': - if (regnamelen != 2 || regname[1] != 'R') - return; - regno = 66; - break; - case 'S': - if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R') - return; - else if (regname[3] == '8') - regno = 67; - else if (regname[3] == '9') - regno = 68; - else if (regname[3] == '1') - regno = 69; - else if (regname[3] == '0') - regno = 70; - else - return; - break; - default: - return; - } - - monitor_supply_register (regno, val); -} - -/* - * This array of registers needs to match the indexes used by GDB. The - * whole reason this exists is because the various ROM monitors use - * different names than GDB does, and don't support all the - * registers either. So, typing "info reg sp" becomes an "A7". - */ - -static char *ppcbug_regnames[] = -{ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - - "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", - "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", - "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", - "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31", - -/* pc ps cnd lr cnt xer mq */ - "ip", "msr", "cr", "spr8", "spr9", "spr1", "spr0" -}; - -/* - * Define the monitor command strings. Since these are passed directly - * through to a printf style function, we need can include formatting - * strings. We also need a CR or LF on the end. - */ - -static struct target_ops ppcbug_ops0; -static struct target_ops ppcbug_ops1; - -static char *ppcbug_inits[] = -{"\r", NULL}; - -static void -init_ppc_cmds (char *LOAD_CMD, - struct monitor_ops *OPS, - struct target_ops *targops) -{ - OPS->flags = MO_CLR_BREAK_USES_ADDR | MO_HANDLE_NL; - OPS->init = ppcbug_inits; /* Init strings */ - OPS->cont = "g\r"; /* continue command */ - OPS->step = "t\r"; /* single step */ - OPS->stop = NULL; /* interrupt command */ - OPS->set_break = "br %x\r"; /* set a breakpoint */ - OPS->clr_break = "nobr %x\r"; /* clear a breakpoint */ - OPS->clr_all_break = "nobr\r"; /* clear all breakpoints */ - OPS->fill = "bf %x:%x %x;b\r"; /* fill (start count val) */ - OPS->setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */ - OPS->setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */ - OPS->setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */ - OPS->setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - OPS->setmem.resp_delim = NULL; /* setreg.resp_delim */ - OPS->setmem.term = NULL; /* setreg.term */ - OPS->setmem.term_cmd = NULL; /* setreg.term_cmd */ - OPS->getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */ - OPS->getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */ - OPS->getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */ - OPS->getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - OPS->getmem.resp_delim = " "; /* getmem.resp_delim */ - OPS->getmem.term = NULL; /* getmem.term */ - OPS->getmem.term_cmd = NULL; /* getmem.term_cmd */ - OPS->setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */ - OPS->setreg.resp_delim = NULL; /* setreg.resp_delim */ - OPS->setreg.term = NULL; /* setreg.term */ - OPS->setreg.term_cmd = NULL; /* setreg.term_cmd */ - OPS->getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */ - OPS->getreg.resp_delim = "="; /* getreg.resp_delim */ - OPS->getreg.term = NULL; /* getreg.term */ - OPS->getreg.term_cmd = NULL; /* getreg.term_cmd */ - OPS->register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - OPS->supply_register = ppcbug_supply_register; /* supply_register */ - OPS->dump_registers = "rd\r"; /* dump all registers */ - OPS->load_routine = NULL; /* load_routine (defaults to SRECs) */ - OPS->load = LOAD_CMD; /* download command */ - OPS->loadresp = NULL; /* load response */ - OPS->prompt = "PPC1-Bug>"; /* monitor command prompt */ - OPS->line_term = "\r"; /* end-of-line terminator */ - OPS->cmd_end = NULL; /* optional command terminator */ - OPS->target = targops; /* target operations */ - OPS->stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - OPS->regnames = ppcbug_regnames; /* registers names */ - OPS->magic = MONITOR_OPS_MAGIC; /* magic */ -} - - -static struct monitor_ops ppcbug_cmds0; -static struct monitor_ops ppcbug_cmds1; - -static void -ppcbug_open0 (char *args, int from_tty) -{ - monitor_open (args, &ppcbug_cmds0, from_tty); -} - -static void -ppcbug_open1 (char *args, int from_tty) -{ - monitor_open (args, &ppcbug_cmds1, from_tty); -} - -void -_initialize_ppcbug_rom (void) -{ - init_ppc_cmds ("lo 0\r", &ppcbug_cmds0, &ppcbug_ops0); - init_ppc_cmds ("lo 1\r", &ppcbug_cmds1, &ppcbug_ops1); - init_monitor_ops (&ppcbug_ops0); - - ppcbug_ops0.to_shortname = "ppcbug"; - ppcbug_ops0.to_longname = "PowerPC PPCBug monitor on port 0"; - ppcbug_ops0.to_doc = "Debug via the PowerPC PPCBug monitor using port 0.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - ppcbug_ops0.to_open = ppcbug_open0; - - add_target (&ppcbug_ops0); - - init_monitor_ops (&ppcbug_ops1); - - ppcbug_ops1.to_shortname = "ppcbug1"; - ppcbug_ops1.to_longname = "PowerPC PPCBug monitor on port 1"; - ppcbug_ops1.to_doc = "Debug via the PowerPC PPCBug monitor using port 1.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - ppcbug_ops1.to_open = ppcbug_open1; - - add_target (&ppcbug_ops1); -} diff --git a/contrib/gdb/gdb/procfs.c b/contrib/gdb/gdb/procfs.c deleted file mode 100644 index 55e0496bc78..00000000000 --- a/contrib/gdb/gdb/procfs.c +++ /dev/null @@ -1,5857 +0,0 @@ -/* Machine independent support for SVR4 /proc (process file system) for GDB. - Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Written by Michael Snyder at Cygnus Solutions. - Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "elf-bfd.h" /* for elfcore_write_* */ -#include "gdbcmd.h" -#include "gdbthread.h" - -#if defined (NEW_PROC_API) -#define _STRUCTURED_PROC 1 /* Should be done by configure script. */ -#endif - -#include -#ifdef HAVE_SYS_FAULT_H -#include -#endif -#ifdef HAVE_SYS_SYSCALL_H -#include -#endif -#include -#include -#include -#include - -/* - * PROCFS.C - * - * This module provides the interface between GDB and the - * /proc file system, which is used on many versions of Unix - * as a means for debuggers to control other processes. - * Examples of the systems that use this interface are: - * Irix - * Solaris - * OSF - * Unixware - * AIX5 - * - * /proc works by imitating a file system: you open a simulated file - * that represents the process you wish to interact with, and - * perform operations on that "file" in order to examine or change - * the state of the other process. - * - * The most important thing to know about /proc and this module - * is that there are two very different interfaces to /proc: - * One that uses the ioctl system call, and - * another that uses read and write system calls. - * This module has to support both /proc interfaces. This means - * that there are two different ways of doing every basic operation. - * - * In order to keep most of the code simple and clean, I have - * defined an interface "layer" which hides all these system calls. - * An ifdef (NEW_PROC_API) determines which interface we are using, - * and most or all occurrances of this ifdef should be confined to - * this interface layer. - */ - - -/* Determine which /proc API we are using: - The ioctl API defines PIOCSTATUS, while - the read/write (multiple fd) API never does. */ - -#ifdef NEW_PROC_API -#include -#include "gdb_dirent.h" /* opendir/readdir, for listing the LWP's */ -#endif - -#include /* for O_RDONLY */ -#include /* for "X_OK" */ -#include "gdb_stat.h" /* for struct stat */ - -/* Note: procfs-utils.h must be included after the above system header - files, because it redefines various system calls using macros. - This may be incompatible with the prototype declarations. */ - -#include "proc-utils.h" - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* =================== TARGET_OPS "MODULE" =================== */ - -/* - * This module defines the GDB target vector and its methods. - */ - -static void procfs_open (char *, int); -static void procfs_attach (char *, int); -static void procfs_detach (char *, int); -static void procfs_resume (ptid_t, int, enum target_signal); -static int procfs_can_run (void); -static void procfs_stop (void); -static void procfs_files_info (struct target_ops *); -static void procfs_fetch_registers (int); -static void procfs_store_registers (int); -static void procfs_notice_signals (ptid_t); -static void procfs_prepare_to_store (void); -static void procfs_kill_inferior (void); -static void procfs_mourn_inferior (void); -static void procfs_create_inferior (char *, char *, char **); -static ptid_t procfs_wait (ptid_t, struct target_waitstatus *); -static int procfs_xfer_memory (CORE_ADDR, char *, int, int, - struct mem_attrib *attrib, - struct target_ops *); - -static int procfs_thread_alive (ptid_t); - -void procfs_find_new_threads (void); -char *procfs_pid_to_str (ptid_t); - -static int proc_find_memory_regions (int (*) (CORE_ADDR, - unsigned long, - int, int, int, - void *), - void *); - -static char * procfs_make_note_section (bfd *, int *); - -struct target_ops procfs_ops; /* the target vector */ - -static void -init_procfs_ops (void) -{ - procfs_ops.to_shortname = "procfs"; - procfs_ops.to_longname = "Unix /proc child process"; - procfs_ops.to_doc = - "Unix /proc child process (started by the \"run\" command)."; - procfs_ops.to_open = procfs_open; - procfs_ops.to_can_run = procfs_can_run; - procfs_ops.to_create_inferior = procfs_create_inferior; - procfs_ops.to_kill = procfs_kill_inferior; - procfs_ops.to_mourn_inferior = procfs_mourn_inferior; - procfs_ops.to_attach = procfs_attach; - procfs_ops.to_detach = procfs_detach; - procfs_ops.to_wait = procfs_wait; - procfs_ops.to_resume = procfs_resume; - procfs_ops.to_prepare_to_store = procfs_prepare_to_store; - procfs_ops.to_fetch_registers = procfs_fetch_registers; - procfs_ops.to_store_registers = procfs_store_registers; - procfs_ops.to_xfer_memory = procfs_xfer_memory; - procfs_ops.to_insert_breakpoint = memory_insert_breakpoint; - procfs_ops.to_remove_breakpoint = memory_remove_breakpoint; - procfs_ops.to_notice_signals = procfs_notice_signals; - procfs_ops.to_files_info = procfs_files_info; - procfs_ops.to_stop = procfs_stop; - - procfs_ops.to_terminal_init = terminal_init_inferior; - procfs_ops.to_terminal_inferior = terminal_inferior; - procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output; - procfs_ops.to_terminal_ours = terminal_ours; - procfs_ops.to_terminal_info = child_terminal_info; - - procfs_ops.to_find_new_threads = procfs_find_new_threads; - procfs_ops.to_thread_alive = procfs_thread_alive; - procfs_ops.to_pid_to_str = procfs_pid_to_str; - - procfs_ops.to_has_all_memory = 1; - procfs_ops.to_has_memory = 1; - procfs_ops.to_has_execution = 1; - procfs_ops.to_has_stack = 1; - procfs_ops.to_has_registers = 1; - procfs_ops.to_stratum = process_stratum; - procfs_ops.to_has_thread_control = tc_schedlock; - procfs_ops.to_find_memory_regions = proc_find_memory_regions; - procfs_ops.to_make_corefile_notes = procfs_make_note_section; - procfs_ops.to_magic = OPS_MAGIC; -} - -/* =================== END, TARGET_OPS "MODULE" =================== */ - -/* - * World Unification: - * - * Put any typedefs, defines etc. here that are required for - * the unification of code that handles different versions of /proc. - */ - -#ifdef NEW_PROC_API /* Solaris 7 && 8 method for watchpoints */ -#ifdef WA_READ - enum { READ_WATCHFLAG = WA_READ, - WRITE_WATCHFLAG = WA_WRITE, - EXEC_WATCHFLAG = WA_EXEC, - AFTER_WATCHFLAG = WA_TRAPAFTER - }; -#endif -#else /* Irix method for watchpoints */ - enum { READ_WATCHFLAG = MA_READ, - WRITE_WATCHFLAG = MA_WRITE, - EXEC_WATCHFLAG = MA_EXEC, - AFTER_WATCHFLAG = 0 /* trapafter not implemented */ - }; -#endif - -/* gdb_sigset_t */ -#ifdef HAVE_PR_SIGSET_T -typedef pr_sigset_t gdb_sigset_t; -#else -typedef sigset_t gdb_sigset_t; -#endif - -/* sigaction */ -#ifdef HAVE_PR_SIGACTION64_T -typedef pr_sigaction64_t gdb_sigaction_t; -#else -typedef struct sigaction gdb_sigaction_t; -#endif - -/* siginfo */ -#ifdef HAVE_PR_SIGINFO64_T -typedef pr_siginfo64_t gdb_siginfo_t; -#else -typedef struct siginfo gdb_siginfo_t; -#endif - -/* gdb_premptysysset */ -#ifdef premptysysset -#define gdb_premptysysset premptysysset -#else -#define gdb_premptysysset premptyset -#endif - -/* praddsysset */ -#ifdef praddsysset -#define gdb_praddsysset praddsysset -#else -#define gdb_praddsysset praddset -#endif - -/* prdelsysset */ -#ifdef prdelsysset -#define gdb_prdelsysset prdelsysset -#else -#define gdb_prdelsysset prdelset -#endif - -/* prissyssetmember */ -#ifdef prissyssetmember -#define gdb_pr_issyssetmember prissyssetmember -#else -#define gdb_pr_issyssetmember prismember -#endif - -/* As a feature test, saying ``#if HAVE_PRSYSENT_T'' everywhere isn't - as intuitively descriptive as it could be, so we'll define - DYNAMIC_SYSCALLS to mean the same thing. Anyway, at the time of - this writing, this feature is only found on AIX5 systems and - basically means that the set of syscalls is not fixed. I.e, - there's no nice table that one can #include to get all of the - syscall numbers. Instead, they're stored in /proc/PID/sysent - for each process. We are at least guaranteed that they won't - change over the lifetime of the process. But each process could - (in theory) have different syscall numbers. -*/ -#ifdef HAVE_PRSYSENT_T -#define DYNAMIC_SYSCALLS -#endif - - - -/* =================== STRUCT PROCINFO "MODULE" =================== */ - - /* FIXME: this comment will soon be out of date W.R.T. threads. */ - -/* The procinfo struct is a wrapper to hold all the state information - concerning a /proc process. There should be exactly one procinfo - for each process, and since GDB currently can debug only one - process at a time, that means there should be only one procinfo. - All of the LWP's of a process can be accessed indirectly thru the - single process procinfo. - - However, against the day when GDB may debug more than one process, - this data structure is kept in a list (which for now will hold no - more than one member), and many functions will have a pointer to a - procinfo as an argument. - - There will be a separate procinfo structure for use by the (not yet - implemented) "info proc" command, so that we can print useful - information about any random process without interfering with the - inferior's procinfo information. */ - -#ifdef NEW_PROC_API -/* format strings for /proc paths */ -# ifndef CTL_PROC_NAME_FMT -# define MAIN_PROC_NAME_FMT "/proc/%d" -# define CTL_PROC_NAME_FMT "/proc/%d/ctl" -# define AS_PROC_NAME_FMT "/proc/%d/as" -# define MAP_PROC_NAME_FMT "/proc/%d/map" -# define STATUS_PROC_NAME_FMT "/proc/%d/status" -# define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus") -# endif -/* the name of the proc status struct depends on the implementation */ -typedef pstatus_t gdb_prstatus_t; -typedef lwpstatus_t gdb_lwpstatus_t; -#else /* ! NEW_PROC_API */ -/* format strings for /proc paths */ -# ifndef CTL_PROC_NAME_FMT -# define MAIN_PROC_NAME_FMT "/proc/%05d" -# define CTL_PROC_NAME_FMT "/proc/%05d" -# define AS_PROC_NAME_FMT "/proc/%05d" -# define MAP_PROC_NAME_FMT "/proc/%05d" -# define STATUS_PROC_NAME_FMT "/proc/%05d" -# define MAX_PROC_NAME_SIZE sizeof("/proc/ttttppppp") -# endif -/* the name of the proc status struct depends on the implementation */ -typedef prstatus_t gdb_prstatus_t; -typedef prstatus_t gdb_lwpstatus_t; -#endif /* NEW_PROC_API */ - -typedef struct procinfo { - struct procinfo *next; - int pid; /* Process ID */ - int tid; /* Thread/LWP id */ - - /* process state */ - int was_stopped; - int ignore_next_sigstop; - - /* The following four fd fields may be identical, or may contain - several different fd's, depending on the version of /proc - (old ioctl or new read/write). */ - - int ctl_fd; /* File descriptor for /proc control file */ - /* - * The next three file descriptors are actually only needed in the - * read/write, multiple-file-descriptor implemenation (NEW_PROC_API). - * However, to avoid a bunch of #ifdefs in the code, we will use - * them uniformly by (in the case of the ioctl single-file-descriptor - * implementation) filling them with copies of the control fd. - */ - int status_fd; /* File descriptor for /proc status file */ - int as_fd; /* File descriptor for /proc as file */ - - char pathname[MAX_PROC_NAME_SIZE]; /* Pathname to /proc entry */ - - fltset_t saved_fltset; /* Saved traced hardware fault set */ - gdb_sigset_t saved_sigset; /* Saved traced signal set */ - gdb_sigset_t saved_sighold; /* Saved held signal set */ - sysset_t *saved_exitset; /* Saved traced system call exit set */ - sysset_t *saved_entryset; /* Saved traced system call entry set */ - - gdb_prstatus_t prstatus; /* Current process status info */ - -#ifndef NEW_PROC_API - gdb_fpregset_t fpregset; /* Current floating point registers */ -#endif - -#ifdef DYNAMIC_SYSCALLS - int num_syscalls; /* Total number of syscalls */ - char **syscall_names; /* Syscall number to name map */ -#endif - - struct procinfo *thread_list; - - int status_valid : 1; - int gregs_valid : 1; - int fpregs_valid : 1; - int threads_valid: 1; -} procinfo; - -static char errmsg[128]; /* shared error msg buffer */ - -/* Function prototypes for procinfo module: */ - -static procinfo *find_procinfo_or_die (int pid, int tid); -static procinfo *find_procinfo (int pid, int tid); -static procinfo *create_procinfo (int pid, int tid); -static void destroy_procinfo (procinfo * p); -static void do_destroy_procinfo_cleanup (void *); -static void dead_procinfo (procinfo * p, char *msg, int killp); -static int open_procinfo_files (procinfo * p, int which); -static void close_procinfo_files (procinfo * p); -static int sysset_t_size (procinfo *p); -static sysset_t *sysset_t_alloc (procinfo * pi); -#ifdef DYNAMIC_SYSCALLS -static void load_syscalls (procinfo *pi); -static void free_syscalls (procinfo *pi); -static int find_syscall (procinfo *pi, char *name); -#endif /* DYNAMIC_SYSCALLS */ - -/* The head of the procinfo list: */ -static procinfo * procinfo_list; - -/* - * Function: find_procinfo - * - * Search the procinfo list. - * - * Returns: pointer to procinfo, or NULL if not found. - */ - -static procinfo * -find_procinfo (int pid, int tid) -{ - procinfo *pi; - - for (pi = procinfo_list; pi; pi = pi->next) - if (pi->pid == pid) - break; - - if (pi) - if (tid) - { - /* Don't check threads_valid. If we're updating the - thread_list, we want to find whatever threads are already - here. This means that in general it is the caller's - responsibility to check threads_valid and update before - calling find_procinfo, if the caller wants to find a new - thread. */ - - for (pi = pi->thread_list; pi; pi = pi->next) - if (pi->tid == tid) - break; - } - - return pi; -} - -/* - * Function: find_procinfo_or_die - * - * Calls find_procinfo, but errors on failure. - */ - -static procinfo * -find_procinfo_or_die (int pid, int tid) -{ - procinfo *pi = find_procinfo (pid, tid); - - if (pi == NULL) - { - if (tid) - error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.", - pid, tid); - else - error ("procfs: couldn't find pid %d in procinfo list.", pid); - } - return pi; -} - -/* open_with_retry() is a wrapper for open(). The appropriate - open() call is attempted; if unsuccessful, it will be retried as - many times as needed for the EAGAIN and EINTR conditions. - - For other conditions, open_with_retry() will retry the open() a - limited number of times. In addition, a short sleep is imposed - prior to retrying the open(). The reason for this sleep is to give - the kernel a chance to catch up and create the file in question in - the event that GDB "wins" the race to open a file before the kernel - has created it. */ - -static int -open_with_retry (const char *pathname, int flags) -{ - int retries_remaining, status; - - retries_remaining = 2; - - while (1) - { - status = open (pathname, flags); - - if (status >= 0 || retries_remaining == 0) - break; - else if (errno != EINTR && errno != EAGAIN) - { - retries_remaining--; - sleep (1); - } - } - - return status; -} - -/* - * Function: open_procinfo_files - * - * Open the file descriptor for the process or LWP. - * ifdef NEW_PROC_API, we only open the control file descriptor; - * the others are opened lazily as needed. - * else (if not NEW_PROC_API), there is only one real - * file descriptor, but we keep multiple copies of it so that - * the code that uses them does not have to be #ifdef'd. - * - * Return: file descriptor, or zero for failure. - */ - -enum { FD_CTL, FD_STATUS, FD_AS }; - -static int -open_procinfo_files (procinfo *pi, int which) -{ -#ifdef NEW_PROC_API - char tmp[MAX_PROC_NAME_SIZE]; -#endif - int fd; - - /* - * This function is getting ALMOST long enough to break up into several. - * Here is some rationale: - * - * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware): - * There are several file descriptors that may need to be open - * for any given process or LWP. The ones we're intereted in are: - * - control (ctl) write-only change the state - * - status (status) read-only query the state - * - address space (as) read/write access memory - * - map (map) read-only virtual addr map - * Most of these are opened lazily as they are needed. - * The pathnames for the 'files' for an LWP look slightly - * different from those of a first-class process: - * Pathnames for a process (): - * /proc//ctl - * /proc//status - * /proc//as - * /proc//map - * Pathnames for an LWP (lwp-id): - * /proc//lwp//lwpctl - * /proc//lwp//lwpstatus - * An LWP has no map or address space file descriptor, since - * the memory map and address space are shared by all LWPs. - * - * Everyone else (Solaris 2.5, Irix, OSF) - * There is only one file descriptor for each process or LWP. - * For convenience, we copy the same file descriptor into all - * three fields of the procinfo struct (ctl_fd, status_fd, and - * as_fd, see NEW_PROC_API above) so that code that uses them - * doesn't need any #ifdef's. - * Pathname for all: - * /proc/ - * - * Solaris 2.5 LWP's: - * Each LWP has an independent file descriptor, but these - * are not obtained via the 'open' system call like the rest: - * instead, they're obtained thru an ioctl call (PIOCOPENLWP) - * to the file descriptor of the parent process. - * - * OSF threads: - * These do not even have their own independent file descriptor. - * All operations are carried out on the file descriptor of the - * parent process. Therefore we just call open again for each - * thread, getting a new handle for the same 'file'. - */ - -#ifdef NEW_PROC_API - /* - * In this case, there are several different file descriptors that - * we might be asked to open. The control file descriptor will be - * opened early, but the others will be opened lazily as they are - * needed. - */ - - strcpy (tmp, pi->pathname); - switch (which) { /* which file descriptor to open? */ - case FD_CTL: - if (pi->tid) - strcat (tmp, "/lwpctl"); - else - strcat (tmp, "/ctl"); - fd = open_with_retry (tmp, O_WRONLY); - if (fd <= 0) - return 0; /* fail */ - pi->ctl_fd = fd; - break; - case FD_AS: - if (pi->tid) - return 0; /* there is no 'as' file descriptor for an lwp */ - strcat (tmp, "/as"); - fd = open_with_retry (tmp, O_RDWR); - if (fd <= 0) - return 0; /* fail */ - pi->as_fd = fd; - break; - case FD_STATUS: - if (pi->tid) - strcat (tmp, "/lwpstatus"); - else - strcat (tmp, "/status"); - fd = open_with_retry (tmp, O_RDONLY); - if (fd <= 0) - return 0; /* fail */ - pi->status_fd = fd; - break; - default: - return 0; /* unknown file descriptor */ - } -#else /* not NEW_PROC_API */ - /* - * In this case, there is only one file descriptor for each procinfo - * (ie. each process or LWP). In fact, only the file descriptor for - * the process can actually be opened by an 'open' system call. - * The ones for the LWPs have to be obtained thru an IOCTL call - * on the process's file descriptor. - * - * For convenience, we copy each procinfo's single file descriptor - * into all of the fields occupied by the several file descriptors - * of the NEW_PROC_API implementation. That way, the code that uses - * them can be written without ifdefs. - */ - - -#ifdef PIOCTSTATUS /* OSF */ - /* Only one FD; just open it. */ - if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0) - return 0; -#else /* Sol 2.5, Irix, other? */ - if (pi->tid == 0) /* Master procinfo for the process */ - { - fd = open_with_retry (pi->pathname, O_RDWR); - if (fd <= 0) - return 0; /* fail */ - } - else /* LWP thread procinfo */ - { -#ifdef PIOCOPENLWP /* Sol 2.5, thread/LWP */ - procinfo *process; - int lwpid = pi->tid; - - /* Find the procinfo for the entire process. */ - if ((process = find_procinfo (pi->pid, 0)) == NULL) - return 0; /* fail */ - - /* Now obtain the file descriptor for the LWP. */ - if ((fd = ioctl (process->ctl_fd, PIOCOPENLWP, &lwpid)) <= 0) - return 0; /* fail */ -#else /* Irix, other? */ - return 0; /* Don't know how to open threads */ -#endif /* Sol 2.5 PIOCOPENLWP */ - } -#endif /* OSF PIOCTSTATUS */ - pi->ctl_fd = pi->as_fd = pi->status_fd = fd; -#endif /* NEW_PROC_API */ - - return 1; /* success */ -} - -/* - * Function: create_procinfo - * - * Allocate a data structure and link it into the procinfo list. - * (First tries to find a pre-existing one (FIXME: why?) - * - * Return: pointer to new procinfo struct. - */ - -static procinfo * -create_procinfo (int pid, int tid) -{ - procinfo *pi, *parent; - - if ((pi = find_procinfo (pid, tid))) - return pi; /* Already exists, nothing to do. */ - - /* find parent before doing malloc, to save having to cleanup */ - if (tid != 0) - parent = find_procinfo_or_die (pid, 0); /* FIXME: should I - create it if it - doesn't exist yet? */ - - pi = (procinfo *) xmalloc (sizeof (procinfo)); - memset (pi, 0, sizeof (procinfo)); - pi->pid = pid; - pi->tid = tid; - -#ifdef DYNAMIC_SYSCALLS - load_syscalls (pi); -#endif - - pi->saved_entryset = sysset_t_alloc (pi); - pi->saved_exitset = sysset_t_alloc (pi); - - /* Chain into list. */ - if (tid == 0) - { - sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid); - pi->next = procinfo_list; - procinfo_list = pi; - } - else - { -#ifdef NEW_PROC_API - sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid); -#else - sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid); -#endif - pi->next = parent->thread_list; - parent->thread_list = pi; - } - return pi; -} - -/* - * Function: close_procinfo_files - * - * Close all file descriptors associated with the procinfo - */ - -static void -close_procinfo_files (procinfo *pi) -{ - if (pi->ctl_fd > 0) - close (pi->ctl_fd); -#ifdef NEW_PROC_API - if (pi->as_fd > 0) - close (pi->as_fd); - if (pi->status_fd > 0) - close (pi->status_fd); -#endif - pi->ctl_fd = pi->as_fd = pi->status_fd = 0; -} - -/* - * Function: destroy_procinfo - * - * Destructor function. Close, unlink and deallocate the object. - */ - -static void -destroy_one_procinfo (procinfo **list, procinfo *pi) -{ - procinfo *ptr; - - /* Step one: unlink the procinfo from its list */ - if (pi == *list) - *list = pi->next; - else - for (ptr = *list; ptr; ptr = ptr->next) - if (ptr->next == pi) - { - ptr->next = pi->next; - break; - } - - /* Step two: close any open file descriptors */ - close_procinfo_files (pi); - - /* Step three: free the memory. */ -#ifdef DYNAMIC_SYSCALLS - free_syscalls (pi); -#endif - xfree (pi->saved_entryset); - xfree (pi->saved_exitset); - xfree (pi); -} - -static void -destroy_procinfo (procinfo *pi) -{ - procinfo *tmp; - - if (pi->tid != 0) /* destroy a thread procinfo */ - { - tmp = find_procinfo (pi->pid, 0); /* find the parent process */ - destroy_one_procinfo (&tmp->thread_list, pi); - } - else /* destroy a process procinfo and all its threads */ - { - /* First destroy the children, if any; */ - while (pi->thread_list != NULL) - destroy_one_procinfo (&pi->thread_list, pi->thread_list); - /* Then destroy the parent. Genocide!!! */ - destroy_one_procinfo (&procinfo_list, pi); - } -} - -static void -do_destroy_procinfo_cleanup (void *pi) -{ - destroy_procinfo (pi); -} - -enum { NOKILL, KILL }; - -/* - * Function: dead_procinfo - * - * To be called on a non_recoverable error for a procinfo. - * Prints error messages, optionally sends a SIGKILL to the process, - * then destroys the data structure. - */ - -static void -dead_procinfo (procinfo *pi, char *msg, int kill_p) -{ - char procfile[80]; - - if (pi->pathname) - { - print_sys_errmsg (pi->pathname, errno); - } - else - { - sprintf (procfile, "process %d", pi->pid); - print_sys_errmsg (procfile, errno); - } - if (kill_p == KILL) - kill (pi->pid, SIGKILL); - - destroy_procinfo (pi); - error (msg); -} - -/* - * Function: sysset_t_size - * - * Returns the (complete) size of a sysset_t struct. Normally, this - * is just sizeof (syset_t), but in the case of Monterey/64, the actual - * size of sysset_t isn't known until runtime. - */ - -static int -sysset_t_size (procinfo * pi) -{ -#ifndef DYNAMIC_SYSCALLS - return sizeof (sysset_t); -#else - return sizeof (sysset_t) - sizeof (uint64_t) - + sizeof (uint64_t) * ((pi->num_syscalls + (8 * sizeof (uint64_t) - 1)) - / (8 * sizeof (uint64_t))); -#endif -} - -/* Function: sysset_t_alloc - - Allocate and (partially) initialize a sysset_t struct. */ - -static sysset_t * -sysset_t_alloc (procinfo * pi) -{ - sysset_t *ret; - int size = sysset_t_size (pi); - ret = xmalloc (size); -#ifdef DYNAMIC_SYSCALLS - ret->pr_size = (pi->num_syscalls + (8 * sizeof (uint64_t) - 1)) - / (8 * sizeof (uint64_t)); -#endif - return ret; -} - -#ifdef DYNAMIC_SYSCALLS - -/* Function: load_syscalls - - Extract syscall numbers and names from /proc//sysent. Initialize - pi->num_syscalls with the number of syscalls and pi->syscall_names - with the names. (Certain numbers may be skipped in which case the - names for these numbers will be left as NULL.) */ - -#define MAX_SYSCALL_NAME_LENGTH 256 -#define MAX_SYSCALLS 65536 - -static void -load_syscalls (procinfo *pi) -{ - char pathname[MAX_PROC_NAME_SIZE]; - int sysent_fd; - prsysent_t header; - prsyscall_t *syscalls; - int i, size, maxcall; - - pi->num_syscalls = 0; - pi->syscall_names = 0; - - /* Open the file descriptor for the sysent file */ - sprintf (pathname, "/proc/%d/sysent", pi->pid); - sysent_fd = open_with_retry (pathname, O_RDONLY); - if (sysent_fd < 0) - { - error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid); - } - - size = sizeof header - sizeof (prsyscall_t); - if (read (sysent_fd, &header, size) != size) - { - error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid); - } - - if (header.pr_nsyscalls == 0) - { - error ("load_syscalls: /proc/%d/sysent contains no syscalls!", pi->pid); - } - - size = header.pr_nsyscalls * sizeof (prsyscall_t); - syscalls = xmalloc (size); - - if (read (sysent_fd, syscalls, size) != size) - { - xfree (syscalls); - error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid); - } - - /* Find maximum syscall number. This may not be the same as - pr_nsyscalls since that value refers to the number of entries - in the table. (Also, the docs indicate that some system - call numbers may be skipped.) */ - - maxcall = syscalls[0].pr_number; - - for (i = 1; i < header.pr_nsyscalls; i++) - if (syscalls[i].pr_number > maxcall - && syscalls[i].pr_nameoff > 0 - && syscalls[i].pr_number < MAX_SYSCALLS) - maxcall = syscalls[i].pr_number; - - pi->num_syscalls = maxcall+1; - pi->syscall_names = xmalloc (pi->num_syscalls * sizeof (char *)); - - for (i = 0; i < pi->num_syscalls; i++) - pi->syscall_names[i] = NULL; - - /* Read the syscall names in */ - for (i = 0; i < header.pr_nsyscalls; i++) - { - char namebuf[MAX_SYSCALL_NAME_LENGTH]; - int nread; - int callnum; - - if (syscalls[i].pr_number >= MAX_SYSCALLS - || syscalls[i].pr_number < 0 - || syscalls[i].pr_nameoff <= 0 - || (lseek (sysent_fd, (off_t) syscalls[i].pr_nameoff, SEEK_SET) - != (off_t) syscalls[i].pr_nameoff)) - continue; - - nread = read (sysent_fd, namebuf, sizeof namebuf); - if (nread <= 0) - continue; - - callnum = syscalls[i].pr_number; - - if (pi->syscall_names[callnum] != NULL) - { - /* FIXME: Generate warning */ - continue; - } - - namebuf[nread-1] = '\0'; - size = strlen (namebuf) + 1; - pi->syscall_names[callnum] = xmalloc (size); - strncpy (pi->syscall_names[callnum], namebuf, size-1); - pi->syscall_names[callnum][size-1] = '\0'; - } - - close (sysent_fd); - xfree (syscalls); -} - -/* Function: free_syscalls - - Free the space allocated for the syscall names from the procinfo - structure. */ - -static void -free_syscalls (procinfo *pi) -{ - if (pi->syscall_names) - { - int i; - - for (i = 0; i < pi->num_syscalls; i++) - if (pi->syscall_names[i] != NULL) - xfree (pi->syscall_names[i]); - - xfree (pi->syscall_names); - pi->syscall_names = 0; - } -} - -/* Function: find_syscall - - Given a name, look up (and return) the corresponding syscall number. - If no match is found, return -1. */ - -static int -find_syscall (procinfo *pi, char *name) -{ - int i; - for (i = 0; i < pi->num_syscalls; i++) - { - if (pi->syscall_names[i] && strcmp (name, pi->syscall_names[i]) == 0) - return i; - } - return -1; -} -#endif - -/* =================== END, STRUCT PROCINFO "MODULE" =================== */ - -/* =================== /proc "MODULE" =================== */ - -/* - * This "module" is the interface layer between the /proc system API - * and the gdb target vector functions. This layer consists of - * access functions that encapsulate each of the basic operations - * that we need to use from the /proc API. - * - * The main motivation for this layer is to hide the fact that - * there are two very different implementations of the /proc API. - * Rather than have a bunch of #ifdefs all thru the gdb target vector - * functions, we do our best to hide them all in here. - */ - -int proc_get_status (procinfo * pi); -long proc_flags (procinfo * pi); -int proc_why (procinfo * pi); -int proc_what (procinfo * pi); -int proc_set_run_on_last_close (procinfo * pi); -int proc_unset_run_on_last_close (procinfo * pi); -int proc_set_inherit_on_fork (procinfo * pi); -int proc_unset_inherit_on_fork (procinfo * pi); -int proc_set_async (procinfo * pi); -int proc_unset_async (procinfo * pi); -int proc_stop_process (procinfo * pi); -int proc_trace_signal (procinfo * pi, int signo); -int proc_ignore_signal (procinfo * pi, int signo); -int proc_clear_current_fault (procinfo * pi); -int proc_set_current_signal (procinfo * pi, int signo); -int proc_clear_current_signal (procinfo * pi); -int proc_set_gregs (procinfo * pi); -int proc_set_fpregs (procinfo * pi); -int proc_wait_for_stop (procinfo * pi); -int proc_run_process (procinfo * pi, int step, int signo); -int proc_kill (procinfo * pi, int signo); -int proc_parent_pid (procinfo * pi); -int proc_get_nthreads (procinfo * pi); -int proc_get_current_thread (procinfo * pi); -int proc_set_held_signals (procinfo * pi, gdb_sigset_t * sighold); -int proc_set_traced_sysexit (procinfo * pi, sysset_t * sysset); -int proc_set_traced_sysentry (procinfo * pi, sysset_t * sysset); -int proc_set_traced_faults (procinfo * pi, fltset_t * fltset); -int proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset); - -int proc_update_threads (procinfo * pi); -int proc_iterate_over_threads (procinfo * pi, - int (*func) (procinfo *, procinfo *, void *), - void *ptr); - -gdb_gregset_t *proc_get_gregs (procinfo * pi); -gdb_fpregset_t *proc_get_fpregs (procinfo * pi); -sysset_t *proc_get_traced_sysexit (procinfo * pi, sysset_t * save); -sysset_t *proc_get_traced_sysentry (procinfo * pi, sysset_t * save); -fltset_t *proc_get_traced_faults (procinfo * pi, fltset_t * save); -gdb_sigset_t *proc_get_traced_signals (procinfo * pi, gdb_sigset_t * save); -gdb_sigset_t *proc_get_held_signals (procinfo * pi, gdb_sigset_t * save); -gdb_sigset_t *proc_get_pending_signals (procinfo * pi, gdb_sigset_t * save); -gdb_sigaction_t *proc_get_signal_actions (procinfo * pi, gdb_sigaction_t *save); - -void proc_warn (procinfo * pi, char *func, int line); -void proc_error (procinfo * pi, char *func, int line); - -void -proc_warn (procinfo *pi, char *func, int line) -{ - sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname); - print_sys_errmsg (errmsg, errno); -} - -void -proc_error (procinfo *pi, char *func, int line) -{ - sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname); - perror_with_name (errmsg); -} - -/* - * Function: proc_get_status - * - * Updates the status struct in the procinfo. - * There is a 'valid' flag, to let other functions know when - * this function needs to be called (so the status is only - * read when it is needed). The status file descriptor is - * also only opened when it is needed. - * - * Return: non-zero for success, zero for failure. - */ - -int -proc_get_status (procinfo *pi) -{ - /* Status file descriptor is opened "lazily" */ - if (pi->status_fd == 0 && - open_procinfo_files (pi, FD_STATUS) == 0) - { - pi->status_valid = 0; - return 0; - } - -#ifdef NEW_PROC_API - if (lseek (pi->status_fd, 0, SEEK_SET) < 0) - pi->status_valid = 0; /* fail */ - else - { - /* Sigh... I have to read a different data structure, - depending on whether this is a main process or an LWP. */ - if (pi->tid) - pi->status_valid = (read (pi->status_fd, - (char *) &pi->prstatus.pr_lwp, - sizeof (lwpstatus_t)) - == sizeof (lwpstatus_t)); - else - { - pi->status_valid = (read (pi->status_fd, - (char *) &pi->prstatus, - sizeof (gdb_prstatus_t)) - == sizeof (gdb_prstatus_t)); -#if 0 /*def UNIXWARE*/ - if (pi->status_valid && - (pi->prstatus.pr_lwp.pr_flags & PR_ISTOP) && - pi->prstatus.pr_lwp.pr_why == PR_REQUESTED) - /* Unixware peculiarity -- read the damn thing again! */ - pi->status_valid = (read (pi->status_fd, - (char *) &pi->prstatus, - sizeof (gdb_prstatus_t)) - == sizeof (gdb_prstatus_t)); -#endif /* UNIXWARE */ - } - } -#else /* ioctl method */ -#ifdef PIOCTSTATUS /* osf */ - if (pi->tid == 0) /* main process */ - { - /* Just read the danged status. Now isn't that simple? */ - pi->status_valid = - (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0); - } - else - { - int win; - struct { - long pr_count; - tid_t pr_error_thread; - struct prstatus status; - } thread_status; - - thread_status.pr_count = 1; - thread_status.status.pr_tid = pi->tid; - win = (ioctl (pi->status_fd, PIOCTSTATUS, &thread_status) >= 0); - if (win) - { - memcpy (&pi->prstatus, &thread_status.status, - sizeof (pi->prstatus)); - pi->status_valid = 1; - } - } -#else - /* Just read the danged status. Now isn't that simple? */ - pi->status_valid = (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0); -#endif -#endif - - if (pi->status_valid) - { - PROC_PRETTYFPRINT_STATUS (proc_flags (pi), - proc_why (pi), - proc_what (pi), - proc_get_current_thread (pi)); - } - - /* The status struct includes general regs, so mark them valid too */ - pi->gregs_valid = pi->status_valid; -#ifdef NEW_PROC_API - /* In the read/write multiple-fd model, - the status struct includes the fp regs too, so mark them valid too */ - pi->fpregs_valid = pi->status_valid; -#endif - return pi->status_valid; /* True if success, false if failure. */ -} - -/* - * Function: proc_flags - * - * returns the process flags (pr_flags field). - */ - -long -proc_flags (procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; /* FIXME: not a good failure value (but what is?) */ - -#ifdef NEW_PROC_API -# ifdef UNIXWARE - /* UnixWare 7.1 puts process status flags, e.g. PR_ASYNC, in - pstatus_t and LWP status flags, e.g. PR_STOPPED, in lwpstatus_t. - The two sets of flags don't overlap. */ - return pi->prstatus.pr_flags | pi->prstatus.pr_lwp.pr_flags; -# else - return pi->prstatus.pr_lwp.pr_flags; -# endif -#else - return pi->prstatus.pr_flags; -#endif -} - -/* - * Function: proc_why - * - * returns the pr_why field (why the process stopped). - */ - -int -proc_why (procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; /* FIXME: not a good failure value (but what is?) */ - -#ifdef NEW_PROC_API - return pi->prstatus.pr_lwp.pr_why; -#else - return pi->prstatus.pr_why; -#endif -} - -/* - * Function: proc_what - * - * returns the pr_what field (details of why the process stopped). - */ - -int -proc_what (procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; /* FIXME: not a good failure value (but what is?) */ - -#ifdef NEW_PROC_API - return pi->prstatus.pr_lwp.pr_what; -#else - return pi->prstatus.pr_what; -#endif -} - -#ifndef PIOCSSPCACT /* The following is not supported on OSF. */ -/* - * Function: proc_nsysarg - * - * returns the pr_nsysarg field (number of args to the current syscall). - */ - -int -proc_nsysarg (procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; - -#ifdef NEW_PROC_API - return pi->prstatus.pr_lwp.pr_nsysarg; -#else - return pi->prstatus.pr_nsysarg; -#endif -} - -/* - * Function: proc_sysargs - * - * returns the pr_sysarg field (pointer to the arguments of current syscall). - */ - -long * -proc_sysargs (procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - -#ifdef NEW_PROC_API - return (long *) &pi->prstatus.pr_lwp.pr_sysarg; -#else - return (long *) &pi->prstatus.pr_sysarg; -#endif -} - -/* - * Function: proc_syscall - * - * returns the pr_syscall field (id of current syscall if we are in one). - */ - -int -proc_syscall (procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; - -#ifdef NEW_PROC_API - return pi->prstatus.pr_lwp.pr_syscall; -#else - return pi->prstatus.pr_syscall; -#endif -} -#endif /* PIOCSSPCACT */ - -/* - * Function: proc_cursig: - * - * returns the pr_cursig field (current signal). - */ - -long -proc_cursig (struct procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; /* FIXME: not a good failure value (but what is?) */ - -#ifdef NEW_PROC_API - return pi->prstatus.pr_lwp.pr_cursig; -#else - return pi->prstatus.pr_cursig; -#endif -} - -/* - * Function: proc_modify_flag - * - * === I appologize for the messiness of this function. - * === This is an area where the different versions of - * === /proc are more inconsistent than usual. MVS - * - * Set or reset any of the following process flags: - * PR_FORK -- forked child will inherit trace flags - * PR_RLC -- traced process runs when last /proc file closed. - * PR_KLC -- traced process is killed when last /proc file closed. - * PR_ASYNC -- LWP's get to run/stop independently. - * - * There are three methods for doing this function: - * 1) Newest: read/write [PCSET/PCRESET/PCUNSET] - * [Sol6, Sol7, UW] - * 2) Middle: PIOCSET/PIOCRESET - * [Irix, Sol5] - * 3) Oldest: PIOCSFORK/PIOCRFORK/PIOCSRLC/PIOCRRLC - * [OSF, Sol5] - * - * Note: Irix does not define PR_ASYNC. - * Note: OSF does not define PR_KLC. - * Note: OSF is the only one that can ONLY use the oldest method. - * - * Arguments: - * pi -- the procinfo - * flag -- one of PR_FORK, PR_RLC, or PR_ASYNC - * mode -- 1 for set, 0 for reset. - * - * Returns non-zero for success, zero for failure. - */ - -enum { FLAG_RESET, FLAG_SET }; - -static int -proc_modify_flag (procinfo *pi, long flag, long mode) -{ - long win = 0; /* default to fail */ - - /* - * These operations affect the process as a whole, and applying - * them to an individual LWP has the same meaning as applying them - * to the main process. Therefore, if we're ever called with a - * pointer to an LWP's procinfo, let's substitute the process's - * procinfo and avoid opening the LWP's file descriptor - * unnecessarily. - */ - - if (pi->pid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API /* Newest method: UnixWare and newer Solarii */ - /* First normalize the PCUNSET/PCRESET command opcode - (which for no obvious reason has a different definition - from one operating system to the next...) */ -#ifdef PCUNSET -#define GDBRESET PCUNSET -#else -#ifdef PCRESET -#define GDBRESET PCRESET -#endif -#endif - { - procfs_ctl_t arg[2]; - - if (mode == FLAG_SET) /* Set the flag (RLC, FORK, or ASYNC) */ - arg[0] = PCSET; - else /* Reset the flag */ - arg[0] = GDBRESET; - - arg[1] = flag; - win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); - } -#else -#ifdef PIOCSET /* Irix/Sol5 method */ - if (mode == FLAG_SET) /* Set the flag (hopefully RLC, FORK, or ASYNC) */ - { - win = (ioctl (pi->ctl_fd, PIOCSET, &flag) >= 0); - } - else /* Reset the flag */ - { - win = (ioctl (pi->ctl_fd, PIOCRESET, &flag) >= 0); - } - -#else -#ifdef PIOCSRLC /* Oldest method: OSF */ - switch (flag) { - case PR_RLC: - if (mode == FLAG_SET) /* Set run-on-last-close */ - { - win = (ioctl (pi->ctl_fd, PIOCSRLC, NULL) >= 0); - } - else /* Clear run-on-last-close */ - { - win = (ioctl (pi->ctl_fd, PIOCRRLC, NULL) >= 0); - } - break; - case PR_FORK: - if (mode == FLAG_SET) /* Set inherit-on-fork */ - { - win = (ioctl (pi->ctl_fd, PIOCSFORK, NULL) >= 0); - } - else /* Clear inherit-on-fork */ - { - win = (ioctl (pi->ctl_fd, PIOCRFORK, NULL) >= 0); - } - break; - default: - win = 0; /* fail -- unknown flag (can't do PR_ASYNC) */ - break; - } -#endif -#endif -#endif -#undef GDBRESET - /* The above operation renders the procinfo's cached pstatus obsolete. */ - pi->status_valid = 0; - - if (!win) - warning ("procfs: modify_flag failed to turn %s %s", - flag == PR_FORK ? "PR_FORK" : - flag == PR_RLC ? "PR_RLC" : -#ifdef PR_ASYNC - flag == PR_ASYNC ? "PR_ASYNC" : -#endif -#ifdef PR_KLC - flag == PR_KLC ? "PR_KLC" : -#endif - "", - mode == FLAG_RESET ? "off" : "on"); - - return win; -} - -/* - * Function: proc_set_run_on_last_close - * - * Set the run_on_last_close flag. - * Process with all threads will become runnable - * when debugger closes all /proc fds. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_run_on_last_close (procinfo *pi) -{ - return proc_modify_flag (pi, PR_RLC, FLAG_SET); -} - -/* - * Function: proc_unset_run_on_last_close - * - * Reset the run_on_last_close flag. - * Process will NOT become runnable - * when debugger closes its file handles. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_unset_run_on_last_close (procinfo *pi) -{ - return proc_modify_flag (pi, PR_RLC, FLAG_RESET); -} - -#ifdef PR_KLC -/* - * Function: proc_set_kill_on_last_close - * - * Set the kill_on_last_close flag. - * Process with all threads will be killed when debugger - * closes all /proc fds (or debugger exits or dies). - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_kill_on_last_close (procinfo *pi) -{ - return proc_modify_flag (pi, PR_KLC, FLAG_SET); -} - -/* - * Function: proc_unset_kill_on_last_close - * - * Reset the kill_on_last_close flag. - * Process will NOT be killed when debugger - * closes its file handles (or exits or dies). - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_unset_kill_on_last_close (procinfo *pi) -{ - return proc_modify_flag (pi, PR_KLC, FLAG_RESET); -} -#endif /* PR_KLC */ - -/* - * Function: proc_set_inherit_on_fork - * - * Set inherit_on_fork flag. - * If the process forks a child while we are registered for events - * in the parent, then we will also recieve events from the child. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_inherit_on_fork (procinfo *pi) -{ - return proc_modify_flag (pi, PR_FORK, FLAG_SET); -} - -/* - * Function: proc_unset_inherit_on_fork - * - * Reset inherit_on_fork flag. - * If the process forks a child while we are registered for events - * in the parent, then we will NOT recieve events from the child. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_unset_inherit_on_fork (procinfo *pi) -{ - return proc_modify_flag (pi, PR_FORK, FLAG_RESET); -} - -#ifdef PR_ASYNC -/* - * Function: proc_set_async - * - * Set PR_ASYNC flag. - * If one LWP stops because of a debug event (signal etc.), - * the remaining LWPs will continue to run. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_async (procinfo *pi) -{ - return proc_modify_flag (pi, PR_ASYNC, FLAG_SET); -} - -/* - * Function: proc_unset_async - * - * Reset PR_ASYNC flag. - * If one LWP stops because of a debug event (signal etc.), - * then all other LWPs will stop as well. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_unset_async (procinfo *pi) -{ - return proc_modify_flag (pi, PR_ASYNC, FLAG_RESET); -} -#endif /* PR_ASYNC */ - -/* - * Function: proc_stop_process - * - * Request the process/LWP to stop. Does not wait. - * Returns non-zero for success, zero for failure. - */ - -int -proc_stop_process (procinfo *pi) -{ - int win; - - /* - * We might conceivably apply this operation to an LWP, and - * the LWP's ctl file descriptor might not be open. - */ - - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - return 0; - else - { -#ifdef NEW_PROC_API - procfs_ctl_t cmd = PCSTOP; - win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); -#else /* ioctl method */ - win = (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) >= 0); - /* Note: the call also reads the prstatus. */ - if (win) - { - pi->status_valid = 1; - PROC_PRETTYFPRINT_STATUS (proc_flags (pi), - proc_why (pi), - proc_what (pi), - proc_get_current_thread (pi)); - } -#endif - } - - return win; -} - -/* - * Function: proc_wait_for_stop - * - * Wait for the process or LWP to stop (block until it does). - * Returns non-zero for success, zero for failure. - */ - -int -proc_wait_for_stop (procinfo *pi) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - procfs_ctl_t cmd = PCWSTOP; - win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); - /* We been runnin' and we stopped -- need to update status. */ - pi->status_valid = 0; - } -#else /* ioctl method */ - win = (ioctl (pi->ctl_fd, PIOCWSTOP, &pi->prstatus) >= 0); - /* Above call also refreshes the prstatus. */ - if (win) - { - pi->status_valid = 1; - PROC_PRETTYFPRINT_STATUS (proc_flags (pi), - proc_why (pi), - proc_what (pi), - proc_get_current_thread (pi)); - } -#endif - - return win; -} - -/* - * Function: proc_run_process - * - * Make the process or LWP runnable. - * Options (not all are implemented): - * - single-step - * - clear current fault - * - clear current signal - * - abort the current system call - * - stop as soon as finished with system call - * - (ioctl): set traced signal set - * - (ioctl): set held signal set - * - (ioctl): set traced fault set - * - (ioctl): set start pc (vaddr) - * Always clear the current fault. - * Clear the current signal if 'signo' is zero. - * - * Arguments: - * pi the process or LWP to operate on. - * step if true, set the process or LWP to trap after one instr. - * signo if zero, clear the current signal if any. - * if non-zero, set the current signal to this one. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_run_process (procinfo *pi, int step, int signo) -{ - int win; - int runflags; - - /* - * We will probably have to apply this operation to individual threads, - * so make sure the control file descriptor is open. - */ - - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } - - runflags = PRCFAULT; /* always clear current fault */ - if (step) - runflags |= PRSTEP; - if (signo == 0) - runflags |= PRCSIG; - else if (signo != -1) /* -1 means do nothing W.R.T. signals */ - proc_set_current_signal (pi, signo); - -#ifdef NEW_PROC_API - { - procfs_ctl_t cmd[2]; - - cmd[0] = PCRUN; - cmd[1] = runflags; - win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); - } -#else /* ioctl method */ - { - prrun_t prrun; - - memset (&prrun, 0, sizeof (prrun)); - prrun.pr_flags = runflags; - win = (ioctl (pi->ctl_fd, PIOCRUN, &prrun) >= 0); - } -#endif - - return win; -} - -/* - * Function: proc_set_traced_signals - * - * Register to trace signals in the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - struct { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char sigset[sizeof (gdb_sigset_t)]; - } arg; - - arg.cmd = PCSTRACE; - memcpy (&arg.sigset, sigset, sizeof (gdb_sigset_t)); - - win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg)); - } -#else /* ioctl method */ - win = (ioctl (pi->ctl_fd, PIOCSTRACE, sigset) >= 0); -#endif - /* The above operation renders the procinfo's cached pstatus obsolete. */ - pi->status_valid = 0; - - if (!win) - warning ("procfs: set_traced_signals failed"); - return win; -} - -/* - * Function: proc_set_traced_faults - * - * Register to trace hardware faults in the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_traced_faults (procinfo *pi, fltset_t *fltset) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - struct { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char fltset[sizeof (fltset_t)]; - } arg; - - arg.cmd = PCSFAULT; - memcpy (&arg.fltset, fltset, sizeof (fltset_t)); - - win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg)); - } -#else /* ioctl method */ - win = (ioctl (pi->ctl_fd, PIOCSFAULT, fltset) >= 0); -#endif - /* The above operation renders the procinfo's cached pstatus obsolete. */ - pi->status_valid = 0; - - return win; -} - -/* - * Function: proc_set_traced_sysentry - * - * Register to trace entry to system calls in the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - struct gdb_proc_ctl_pcsentry { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char sysset[sizeof (sysset_t)]; - } *argp; - int argp_size = sizeof (struct gdb_proc_ctl_pcsentry) - - sizeof (sysset_t) - + sysset_t_size (pi); - - argp = xmalloc (argp_size); - - argp->cmd = PCSENTRY; - memcpy (&argp->sysset, sysset, sysset_t_size (pi)); - - win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size); - xfree (argp); - } -#else /* ioctl method */ - win = (ioctl (pi->ctl_fd, PIOCSENTRY, sysset) >= 0); -#endif - /* The above operation renders the procinfo's cached pstatus obsolete. */ - pi->status_valid = 0; - - return win; -} - -/* - * Function: proc_set_traced_sysexit - * - * Register to trace exit from system calls in the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - struct gdb_proc_ctl_pcsexit { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char sysset[sizeof (sysset_t)]; - } *argp; - int argp_size = sizeof (struct gdb_proc_ctl_pcsexit) - - sizeof (sysset_t) - + sysset_t_size (pi); - - argp = xmalloc (argp_size); - - argp->cmd = PCSEXIT; - memcpy (&argp->sysset, sysset, sysset_t_size (pi)); - - win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size); - xfree (argp); - } -#else /* ioctl method */ - win = (ioctl (pi->ctl_fd, PIOCSEXIT, sysset) >= 0); -#endif - /* The above operation renders the procinfo's cached pstatus obsolete. */ - pi->status_valid = 0; - - return win; -} - -/* - * Function: proc_set_held_signals - * - * Specify the set of blocked / held signals in the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - struct { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char hold[sizeof (gdb_sigset_t)]; - } arg; - - arg.cmd = PCSHOLD; - memcpy (&arg.hold, sighold, sizeof (gdb_sigset_t)); - win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); - } -#else - win = (ioctl (pi->ctl_fd, PIOCSHOLD, sighold) >= 0); -#endif - /* The above operation renders the procinfo's cached pstatus obsolete. */ - pi->status_valid = 0; - - return win; -} - -/* - * Function: proc_get_pending_signals - * - * returns the set of signals that are pending in the process or LWP. - * Will also copy the sigset if 'save' is non-zero. - */ - -gdb_sigset_t * -proc_get_pending_signals (procinfo *pi, gdb_sigset_t *save) -{ - gdb_sigset_t *ret = NULL; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - -#ifdef NEW_PROC_API - ret = &pi->prstatus.pr_lwp.pr_lwppend; -#else - ret = &pi->prstatus.pr_sigpend; -#endif - if (save && ret) - memcpy (save, ret, sizeof (gdb_sigset_t)); - - return ret; -} - -/* - * Function: proc_get_signal_actions - * - * returns the set of signal actions. - * Will also copy the sigactionset if 'save' is non-zero. - */ - -gdb_sigaction_t * -proc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save) -{ - gdb_sigaction_t *ret = NULL; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - -#ifdef NEW_PROC_API - ret = &pi->prstatus.pr_lwp.pr_action; -#else - ret = &pi->prstatus.pr_action; -#endif - if (save && ret) - memcpy (save, ret, sizeof (gdb_sigaction_t)); - - return ret; -} - -/* - * Function: proc_get_held_signals - * - * returns the set of signals that are held / blocked. - * Will also copy the sigset if 'save' is non-zero. - */ - -gdb_sigset_t * -proc_get_held_signals (procinfo *pi, gdb_sigset_t *save) -{ - gdb_sigset_t *ret = NULL; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - -#ifdef UNIXWARE - ret = &pi->prstatus.pr_lwp.pr_context.uc_sigmask; -#else - ret = &pi->prstatus.pr_lwp.pr_lwphold; -#endif /* UNIXWARE */ -#else /* not NEW_PROC_API */ - { - static gdb_sigset_t sigheld; - - if (ioctl (pi->ctl_fd, PIOCGHOLD, &sigheld) >= 0) - ret = &sigheld; - } -#endif /* NEW_PROC_API */ - if (save && ret) - memcpy (save, ret, sizeof (gdb_sigset_t)); - - return ret; -} - -/* - * Function: proc_get_traced_signals - * - * returns the set of signals that are traced / debugged. - * Will also copy the sigset if 'save' is non-zero. - */ - -gdb_sigset_t * -proc_get_traced_signals (procinfo *pi, gdb_sigset_t *save) -{ - gdb_sigset_t *ret = NULL; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - - ret = &pi->prstatus.pr_sigtrace; -#else - { - static gdb_sigset_t sigtrace; - - if (ioctl (pi->ctl_fd, PIOCGTRACE, &sigtrace) >= 0) - ret = &sigtrace; - } -#endif - if (save && ret) - memcpy (save, ret, sizeof (gdb_sigset_t)); - - return ret; -} - -/* - * Function: proc_trace_signal - * - * Add 'signo' to the set of signals that are traced. - * Returns non-zero for success, zero for failure. - */ - -int -proc_trace_signal (procinfo *pi, int signo) -{ - gdb_sigset_t temp; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - if (pi) - { - if (proc_get_traced_signals (pi, &temp)) - { - praddset (&temp, signo); - return proc_set_traced_signals (pi, &temp); - } - } - - return 0; /* failure */ -} - -/* - * Function: proc_ignore_signal - * - * Remove 'signo' from the set of signals that are traced. - * Returns non-zero for success, zero for failure. - */ - -int -proc_ignore_signal (procinfo *pi, int signo) -{ - gdb_sigset_t temp; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - if (pi) - { - if (proc_get_traced_signals (pi, &temp)) - { - prdelset (&temp, signo); - return proc_set_traced_signals (pi, &temp); - } - } - - return 0; /* failure */ -} - -/* - * Function: proc_get_traced_faults - * - * returns the set of hardware faults that are traced /debugged. - * Will also copy the faultset if 'save' is non-zero. - */ - -fltset_t * -proc_get_traced_faults (procinfo *pi, fltset_t *save) -{ - fltset_t *ret = NULL; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - - ret = &pi->prstatus.pr_flttrace; -#else - { - static fltset_t flttrace; - - if (ioctl (pi->ctl_fd, PIOCGFAULT, &flttrace) >= 0) - ret = &flttrace; - } -#endif - if (save && ret) - memcpy (save, ret, sizeof (fltset_t)); - - return ret; -} - -/* - * Function: proc_get_traced_sysentry - * - * returns the set of syscalls that are traced /debugged on entry. - * Will also copy the syscall set if 'save' is non-zero. - */ - -sysset_t * -proc_get_traced_sysentry (procinfo *pi, sysset_t *save) -{ - sysset_t *ret = NULL; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - -#ifndef DYNAMIC_SYSCALLS - ret = &pi->prstatus.pr_sysentry; -#else /* DYNAMIC_SYSCALLS */ - { - static sysset_t *sysentry; - size_t size; - - if (!sysentry) - sysentry = sysset_t_alloc (pi); - ret = sysentry; - if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0) - return NULL; - if (pi->prstatus.pr_sysentry_offset == 0) - { - gdb_premptysysset (sysentry); - } - else - { - int rsize; - - if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysentry_offset, - SEEK_SET) - != (off_t) pi->prstatus.pr_sysentry_offset) - return NULL; - size = sysset_t_size (pi); - gdb_premptysysset (sysentry); - rsize = read (pi->status_fd, sysentry, size); - if (rsize < 0) - return NULL; - } - } -#endif /* DYNAMIC_SYSCALLS */ -#else /* !NEW_PROC_API */ - { - static sysset_t sysentry; - - if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysentry) >= 0) - ret = &sysentry; - } -#endif /* NEW_PROC_API */ - if (save && ret) - memcpy (save, ret, sysset_t_size (pi)); - - return ret; -} - -/* - * Function: proc_get_traced_sysexit - * - * returns the set of syscalls that are traced /debugged on exit. - * Will also copy the syscall set if 'save' is non-zero. - */ - -sysset_t * -proc_get_traced_sysexit (procinfo *pi, sysset_t *save) -{ - sysset_t * ret = NULL; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - if (!pi->status_valid) - if (!proc_get_status (pi)) - return NULL; - -#ifndef DYNAMIC_SYSCALLS - ret = &pi->prstatus.pr_sysexit; -#else /* DYNAMIC_SYSCALLS */ - { - static sysset_t *sysexit; - size_t size; - - if (!sysexit) - sysexit = sysset_t_alloc (pi); - ret = sysexit; - if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0) - return NULL; - if (pi->prstatus.pr_sysexit_offset == 0) - { - gdb_premptysysset (sysexit); - } - else - { - int rsize; - - if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysexit_offset, SEEK_SET) - != (off_t) pi->prstatus.pr_sysexit_offset) - return NULL; - size = sysset_t_size (pi); - gdb_premptysysset (sysexit); - rsize = read (pi->status_fd, sysexit, size); - if (rsize < 0) - return NULL; - } - } -#endif /* DYNAMIC_SYSCALLS */ -#else - { - static sysset_t sysexit; - - if (ioctl (pi->ctl_fd, PIOCGEXIT, &sysexit) >= 0) - ret = &sysexit; - } -#endif - if (save && ret) - memcpy (save, ret, sysset_t_size (pi)); - - return ret; -} - -/* - * Function: proc_clear_current_fault - * - * The current fault (if any) is cleared; the associated signal - * will not be sent to the process or LWP when it resumes. - * Returns non-zero for success, zero for failure. - */ - -int -proc_clear_current_fault (procinfo *pi) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - procfs_ctl_t cmd = PCCFAULT; - win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd)); - } -#else - win = (ioctl (pi->ctl_fd, PIOCCFAULT, 0) >= 0); -#endif - - return win; -} - -/* - * Function: proc_set_current_signal - * - * Set the "current signal" that will be delivered next to the process. - * NOTE: semantics are different from those of KILL. - * This signal will be delivered to the process or LWP - * immediately when it is resumed (even if the signal is held/blocked); - * it will NOT immediately cause another event of interest, and will NOT - * first trap back to the debugger. - * - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_current_signal (procinfo *pi, int signo) -{ - int win; - struct { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char sinfo[sizeof (gdb_siginfo_t)]; - } arg; - gdb_siginfo_t *mysinfo; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef PROCFS_DONT_PIOCSSIG_CURSIG - /* With Alpha OSF/1 procfs, the kernel gets really confused if it - * receives a PIOCSSIG with a signal identical to the current signal, - * it messes up the current signal. Work around the kernel bug. - */ - if (signo > 0 && - signo == proc_cursig (pi)) - return 1; /* I assume this is a success? */ -#endif - - /* The pointer is just a type alias. */ - mysinfo = (gdb_siginfo_t *) &arg.sinfo; - mysinfo->si_signo = signo; - mysinfo->si_code = 0; - mysinfo->si_pid = getpid (); /* ?why? */ - mysinfo->si_uid = getuid (); /* ?why? */ - -#ifdef NEW_PROC_API - arg.cmd = PCSSIG; - win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); -#else - win = (ioctl (pi->ctl_fd, PIOCSSIG, (void *) &arg.sinfo) >= 0); -#endif - - return win; -} - -/* - * Function: proc_clear_current_signal - * - * The current signal (if any) is cleared, and - * is not sent to the process or LWP when it resumes. - * Returns non-zero for success, zero for failure. - */ - -int -proc_clear_current_signal (procinfo *pi) -{ - int win; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - -#ifdef NEW_PROC_API - { - struct { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char sinfo[sizeof (gdb_siginfo_t)]; - } arg; - gdb_siginfo_t *mysinfo; - - arg.cmd = PCSSIG; - /* The pointer is just a type alias. */ - mysinfo = (gdb_siginfo_t *) &arg.sinfo; - mysinfo->si_signo = 0; - mysinfo->si_code = 0; - mysinfo->si_errno = 0; - mysinfo->si_pid = getpid (); /* ?why? */ - mysinfo->si_uid = getuid (); /* ?why? */ - - win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); - } -#else - win = (ioctl (pi->ctl_fd, PIOCSSIG, 0) >= 0); -#endif - - return win; -} - -/* - * Function: proc_get_gregs - * - * Get the general registers for the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -gdb_gregset_t * -proc_get_gregs (procinfo *pi) -{ - if (!pi->status_valid || !pi->gregs_valid) - if (!proc_get_status (pi)) - return NULL; - - /* - * OK, sorry about the ifdef's. - * There's three cases instead of two, because - * in this instance Unixware and Solaris/RW differ. - */ - -#ifdef NEW_PROC_API -#ifdef UNIXWARE /* ugh, a true architecture dependency */ - return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs; -#else /* not Unixware */ - return &pi->prstatus.pr_lwp.pr_reg; -#endif /* Unixware */ -#else /* not NEW_PROC_API */ - return &pi->prstatus.pr_reg; -#endif /* NEW_PROC_API */ -} - -/* - * Function: proc_get_fpregs - * - * Get the floating point registers for the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -gdb_fpregset_t * -proc_get_fpregs (procinfo *pi) -{ -#ifdef NEW_PROC_API - if (!pi->status_valid || !pi->fpregs_valid) - if (!proc_get_status (pi)) - return NULL; - -#ifdef UNIXWARE /* a true architecture dependency */ - return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs; -#else - return &pi->prstatus.pr_lwp.pr_fpreg; -#endif /* Unixware */ - -#else /* not NEW_PROC_API */ - if (pi->fpregs_valid) - return &pi->fpregset; /* already got 'em */ - else - { - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - { - return NULL; - } - else - { -#ifdef PIOCTGFPREG - struct { - long pr_count; - tid_t pr_error_thread; - tfpregset_t thread_1; - } thread_fpregs; - - thread_fpregs.pr_count = 1; - thread_fpregs.thread_1.tid = pi->tid; - - if (pi->tid == 0 && - ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0) - { - pi->fpregs_valid = 1; - return &pi->fpregset; /* got 'em now! */ - } - else if (pi->tid != 0 && - ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0) - { - memcpy (&pi->fpregset, &thread_fpregs.thread_1.pr_fpregs, - sizeof (pi->fpregset)); - pi->fpregs_valid = 1; - return &pi->fpregset; /* got 'em now! */ - } - else - { - return NULL; - } -#else - if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0) - { - pi->fpregs_valid = 1; - return &pi->fpregset; /* got 'em now! */ - } - else - { - return NULL; - } -#endif - } - } -#endif -} - -/* - * Function: proc_set_gregs - * - * Write the general registers back to the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_gregs (procinfo *pi) -{ - gdb_gregset_t *gregs; - int win; - - if ((gregs = proc_get_gregs (pi)) == NULL) - return 0; /* get_regs has already warned */ - - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } - else - { -#ifdef NEW_PROC_API - struct { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char gregs[sizeof (gdb_gregset_t)]; - } arg; - - arg.cmd = PCSREG; - memcpy (&arg.gregs, gregs, sizeof (arg.gregs)); - win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); -#else - win = (ioctl (pi->ctl_fd, PIOCSREG, gregs) >= 0); -#endif - } - - /* Policy: writing the regs invalidates our cache. */ - pi->gregs_valid = 0; - return win; -} - -/* - * Function: proc_set_fpregs - * - * Modify the floating point register set of the process or LWP. - * Returns non-zero for success, zero for failure. - */ - -int -proc_set_fpregs (procinfo *pi) -{ - gdb_fpregset_t *fpregs; - int win; - - if ((fpregs = proc_get_fpregs (pi)) == NULL) - return 0; /* get_fpregs has already warned */ - - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } - else - { -#ifdef NEW_PROC_API - struct { - procfs_ctl_t cmd; - /* Use char array to avoid alignment issues. */ - char fpregs[sizeof (gdb_fpregset_t)]; - } arg; - - arg.cmd = PCSFPREG; - memcpy (&arg.fpregs, fpregs, sizeof (arg.fpregs)); - win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); -#else -#ifdef PIOCTSFPREG - if (pi->tid == 0) - win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0); - else - { - struct { - long pr_count; - tid_t pr_error_thread; - tfpregset_t thread_1; - } thread_fpregs; - - thread_fpregs.pr_count = 1; - thread_fpregs.thread_1.tid = pi->tid; - memcpy (&thread_fpregs.thread_1.pr_fpregs, fpregs, - sizeof (*fpregs)); - win = (ioctl (pi->ctl_fd, PIOCTSFPREG, &thread_fpregs) >= 0); - } -#else - win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0); -#endif /* osf PIOCTSFPREG */ -#endif /* NEW_PROC_API */ - } - - /* Policy: writing the regs invalidates our cache. */ - pi->fpregs_valid = 0; - return win; -} - -/* - * Function: proc_kill - * - * Send a signal to the proc or lwp with the semantics of "kill()". - * Returns non-zero for success, zero for failure. - */ - -int -proc_kill (procinfo *pi, int signo) -{ - int win; - - /* - * We might conceivably apply this operation to an LWP, and - * the LWP's ctl file descriptor might not be open. - */ - - if (pi->ctl_fd == 0 && - open_procinfo_files (pi, FD_CTL) == 0) - { - return 0; - } - else - { -#ifdef NEW_PROC_API - procfs_ctl_t cmd[2]; - - cmd[0] = PCKILL; - cmd[1] = signo; - win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); -#else /* ioctl method */ - /* FIXME: do I need the Alpha OSF fixups present in - procfs.c/unconditionally_kill_inferior? Perhaps only for SIGKILL? */ - win = (ioctl (pi->ctl_fd, PIOCKILL, &signo) >= 0); -#endif - } - - return win; -} - -/* - * Function: proc_parent_pid - * - * Find the pid of the process that started this one. - * Returns the parent process pid, or zero. - */ - -int -proc_parent_pid (procinfo *pi) -{ - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; - - return pi->prstatus.pr_ppid; -} - - -/* - * Function: proc_set_watchpoint - * - */ - -int -proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags) -{ -#if !defined (TARGET_HAS_HARDWARE_WATCHPOINTS) - return 0; -#else -/* Horrible hack! Detect Solaris 2.5, because this doesn't work on 2.5 */ -#if defined (PIOCOPENLWP) || defined (UNIXWARE) /* Solaris 2.5: bail out */ - return 0; -#else - struct { - procfs_ctl_t cmd; - char watch[sizeof (prwatch_t)]; - } arg; - prwatch_t *pwatch; - - pwatch = (prwatch_t *) &arg.watch; -#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */ - pwatch->pr_vaddr = (uintptr_t) address_to_host_pointer (addr); -#else - pwatch->pr_vaddr = (caddr_t) address_to_host_pointer (addr); -#endif - pwatch->pr_size = len; - pwatch->pr_wflags = wflags; -#if defined(NEW_PROC_API) && defined (PCWATCH) - arg.cmd = PCWATCH; - return (write (pi->ctl_fd, &arg, sizeof (arg)) == sizeof (arg)); -#else -#if defined (PIOCSWATCH) - return (ioctl (pi->ctl_fd, PIOCSWATCH, pwatch) >= 0); -#else - return 0; /* Fail */ -#endif -#endif -#endif -#endif -} - -#ifdef TM_I386SOL2_H /* Is it hokey to use this? */ - -#include - -/* - * Function: proc_get_LDT_entry - * - * Inputs: - * procinfo *pi; - * int key; - * - * The 'key' is actually the value of the lower 16 bits of - * the GS register for the LWP that we're interested in. - * - * Return: matching ssh struct (LDT entry). - */ - -struct ssd * -proc_get_LDT_entry (procinfo *pi, int key) -{ - static struct ssd *ldt_entry = NULL; -#ifdef NEW_PROC_API - char pathname[MAX_PROC_NAME_SIZE]; - struct cleanup *old_chain = NULL; - int fd; - - /* Allocate space for one LDT entry. - This alloc must persist, because we return a pointer to it. */ - if (ldt_entry == NULL) - ldt_entry = (struct ssd *) xmalloc (sizeof (struct ssd)); - - /* Open the file descriptor for the LDT table. */ - sprintf (pathname, "/proc/%d/ldt", pi->pid); - if ((fd = open_with_retry (pathname, O_RDONLY)) < 0) - { - proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__); - return NULL; - } - /* Make sure it gets closed again! */ - old_chain = make_cleanup_close (fd); - - /* Now 'read' thru the table, find a match and return it. */ - while (read (fd, ldt_entry, sizeof (struct ssd)) == sizeof (struct ssd)) - { - if (ldt_entry->sel == 0 && - ldt_entry->bo == 0 && - ldt_entry->acc1 == 0 && - ldt_entry->acc2 == 0) - break; /* end of table */ - /* If key matches, return this entry. */ - if (ldt_entry->sel == key) - return ldt_entry; - } - /* Loop ended, match not found. */ - return NULL; -#else - int nldt, i; - static int nalloc = 0; - - /* Get the number of LDT entries. */ - if (ioctl (pi->ctl_fd, PIOCNLDT, &nldt) < 0) - { - proc_warn (pi, "proc_get_LDT_entry (PIOCNLDT)", __LINE__); - return NULL; - } - - /* Allocate space for the number of LDT entries. */ - /* This alloc has to persist, 'cause we return a pointer to it. */ - if (nldt > nalloc) - { - ldt_entry = (struct ssd *) - xrealloc (ldt_entry, (nldt + 1) * sizeof (struct ssd)); - nalloc = nldt; - } - - /* Read the whole table in one gulp. */ - if (ioctl (pi->ctl_fd, PIOCLDT, ldt_entry) < 0) - { - proc_warn (pi, "proc_get_LDT_entry (PIOCLDT)", __LINE__); - return NULL; - } - - /* Search the table and return the (first) entry matching 'key'. */ - for (i = 0; i < nldt; i++) - if (ldt_entry[i].sel == key) - return &ldt_entry[i]; - - /* Loop ended, match not found. */ - return NULL; -#endif -} - -#endif /* TM_I386SOL2_H */ - -/* =============== END, non-thread part of /proc "MODULE" =============== */ - -/* =================== Thread "MODULE" =================== */ - -/* NOTE: you'll see more ifdefs and duplication of functions here, - since there is a different way to do threads on every OS. */ - -/* - * Function: proc_get_nthreads - * - * Return the number of threads for the process - */ - -#if defined (PIOCNTHR) && defined (PIOCTLIST) -/* - * OSF version - */ -int -proc_get_nthreads (procinfo *pi) -{ - int nthreads = 0; - - if (ioctl (pi->ctl_fd, PIOCNTHR, &nthreads) < 0) - proc_warn (pi, "procfs: PIOCNTHR failed", __LINE__); - - return nthreads; -} - -#else -#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */ -/* - * Solaris and Unixware version - */ -int -proc_get_nthreads (procinfo *pi) -{ - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; - - /* - * NEW_PROC_API: only works for the process procinfo, - * because the LWP procinfos do not get prstatus filled in. - */ -#ifdef NEW_PROC_API - if (pi->tid != 0) /* find the parent process procinfo */ - pi = find_procinfo_or_die (pi->pid, 0); -#endif - return pi->prstatus.pr_nlwp; -} - -#else -/* - * Default version - */ -int -proc_get_nthreads (procinfo *pi) -{ - return 0; -} -#endif -#endif - -/* - * Function: proc_get_current_thread (LWP version) - * - * Return the ID of the thread that had an event of interest. - * (ie. the one that hit a breakpoint or other traced event). - * All other things being equal, this should be the ID of a - * thread that is currently executing. - */ - -#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */ -/* - * Solaris and Unixware version - */ -int -proc_get_current_thread (procinfo *pi) -{ - /* - * Note: this should be applied to the root procinfo for the process, - * not to the procinfo for an LWP. If applied to the procinfo for - * an LWP, it will simply return that LWP's ID. In that case, - * find the parent process procinfo. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - if (!pi->status_valid) - if (!proc_get_status (pi)) - return 0; - -#ifdef NEW_PROC_API - return pi->prstatus.pr_lwp.pr_lwpid; -#else - return pi->prstatus.pr_who; -#endif -} - -#else -#if defined (PIOCNTHR) && defined (PIOCTLIST) -/* - * OSF version - */ -int -proc_get_current_thread (procinfo *pi) -{ -#if 0 /* FIXME: not ready for prime time? */ - return pi->prstatus.pr_tid; -#else - return 0; -#endif -} - -#else -/* - * Default version - */ -int -proc_get_current_thread (procinfo *pi) -{ - return 0; -} - -#endif -#endif - -/* - * Function: proc_update_threads - * - * Discover the IDs of all the threads within the process, and - * create a procinfo for each of them (chained to the parent). - * - * This unfortunately requires a different method on every OS. - * - * Return: non-zero for success, zero for failure. - */ - -int -proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore) -{ - if (thread && parent) /* sanity */ - { - thread->status_valid = 0; - if (!proc_get_status (thread)) - destroy_one_procinfo (&parent->thread_list, thread); - } - return 0; /* keep iterating */ -} - -#if defined (PIOCLSTATUS) -/* - * Solaris 2.5 (ioctl) version - */ -int -proc_update_threads (procinfo *pi) -{ - gdb_prstatus_t *prstatus; - struct cleanup *old_chain = NULL; - procinfo *thread; - int nlwp, i; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); - - if ((nlwp = proc_get_nthreads (pi)) <= 1) - return 1; /* Process is not multi-threaded; nothing to do. */ - - prstatus = xmalloc (sizeof (gdb_prstatus_t) * (nlwp + 1)); - - old_chain = make_cleanup (xfree, prstatus); - if (ioctl (pi->ctl_fd, PIOCLSTATUS, prstatus) < 0) - proc_error (pi, "update_threads (PIOCLSTATUS)", __LINE__); - - /* Skip element zero, which represents the process as a whole. */ - for (i = 1; i < nlwp + 1; i++) - { - if ((thread = create_procinfo (pi->pid, prstatus[i].pr_who)) == NULL) - proc_error (pi, "update_threads, create_procinfo", __LINE__); - - memcpy (&thread->prstatus, &prstatus[i], sizeof (*prstatus)); - thread->status_valid = 1; - } - pi->threads_valid = 1; - do_cleanups (old_chain); - return 1; -} -#else -#ifdef NEW_PROC_API -/* - * Unixware and Solaris 6 (and later) version - */ -static void -do_closedir_cleanup (void *dir) -{ - closedir (dir); -} - -int -proc_update_threads (procinfo *pi) -{ - char pathname[MAX_PROC_NAME_SIZE + 16]; - struct dirent *direntry; - struct cleanup *old_chain = NULL; - procinfo *thread; - DIR *dirp; - int lwpid; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); - - /* - * Unixware - * - * Note: this brute-force method is the only way I know of - * to accomplish this task on Unixware. This method will - * also work on Solaris 2.6 and 2.7. There is a much simpler - * and more elegant way to do this on Solaris, but the margins - * of this manuscript are too small to write it here... ;-) - */ - - strcpy (pathname, pi->pathname); - strcat (pathname, "/lwp"); - if ((dirp = opendir (pathname)) == NULL) - proc_error (pi, "update_threads, opendir", __LINE__); - - old_chain = make_cleanup (do_closedir_cleanup, dirp); - while ((direntry = readdir (dirp)) != NULL) - if (direntry->d_name[0] != '.') /* skip '.' and '..' */ - { - lwpid = atoi (&direntry->d_name[0]); - if ((thread = create_procinfo (pi->pid, lwpid)) == NULL) - proc_error (pi, "update_threads, create_procinfo", __LINE__); - } - pi->threads_valid = 1; - do_cleanups (old_chain); - return 1; -} -#else -#ifdef PIOCTLIST -/* - * OSF version - */ -int -proc_update_threads (procinfo *pi) -{ - int nthreads, i; - tid_t *threads; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); - - nthreads = proc_get_nthreads (pi); - if (nthreads < 2) - return 0; /* nothing to do for 1 or fewer threads */ - - threads = xmalloc (nthreads * sizeof (tid_t)); - - if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0) - proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__); - - for (i = 0; i < nthreads; i++) - { - if (!find_procinfo (pi->pid, threads[i])) - if (!create_procinfo (pi->pid, threads[i])) - proc_error (pi, "update_threads, create_procinfo", __LINE__); - } - pi->threads_valid = 1; - return 1; -} -#else -/* - * Default version - */ -int -proc_update_threads (procinfo *pi) -{ - return 0; -} -#endif /* OSF PIOCTLIST */ -#endif /* NEW_PROC_API */ -#endif /* SOL 2.5 PIOCLSTATUS */ - -/* - * Function: proc_iterate_over_threads - * - * Description: - * Given a pointer to a function, call that function once - * for each lwp in the procinfo list, until the function - * returns non-zero, in which event return the value - * returned by the function. - * - * Note: this function does NOT call update_threads. - * If you want to discover new threads first, you must - * call that function explicitly. This function just makes - * a quick pass over the currently-known procinfos. - * - * Arguments: - * pi - parent process procinfo - * func - per-thread function - * ptr - opaque parameter for function. - * - * Return: - * First non-zero return value from the callee, or zero. - */ - -int -proc_iterate_over_threads (procinfo *pi, - int (*func) (procinfo *, procinfo *, void *), - void *ptr) -{ - procinfo *thread, *next; - int retval = 0; - - /* - * We should never have to apply this operation to any procinfo - * except the one for the main process. If that ever changes - * for any reason, then take out the following clause and - * replace it with one that makes sure the ctl_fd is open. - */ - - if (pi->tid != 0) - pi = find_procinfo_or_die (pi->pid, 0); - - for (thread = pi->thread_list; thread != NULL; thread = next) - { - next = thread->next; /* in case thread is destroyed */ - if ((retval = (*func) (pi, thread, ptr)) != 0) - break; - } - - return retval; -} - -/* =================== END, Thread "MODULE" =================== */ - -/* =================== END, /proc "MODULE" =================== */ - -/* =================== GDB "MODULE" =================== */ - -/* - * Here are all of the gdb target vector functions and their friends. - */ - -static ptid_t do_attach (ptid_t ptid); -static void do_detach (int signo); -static int register_gdb_signals (procinfo *, gdb_sigset_t *); - -/* - * Function: procfs_debug_inferior - * - * Sets up the inferior to be debugged. - * Registers to trace signals, hardware faults, and syscalls. - * Note: does not set RLC flag: caller may want to customize that. - * - * Returns: zero for success (note! unlike most functions in this module) - * On failure, returns the LINE NUMBER where it failed! - */ - -static int -procfs_debug_inferior (procinfo *pi) -{ - fltset_t traced_faults; - gdb_sigset_t traced_signals; - sysset_t *traced_syscall_entries; - sysset_t *traced_syscall_exits; - int status; - -#ifdef PROCFS_DONT_TRACE_FAULTS - /* On some systems (OSF), we don't trace hardware faults. - Apparently it's enough that we catch them as signals. - Wonder why we don't just do that in general? */ - premptyset (&traced_faults); /* don't trace faults. */ -#else - /* Register to trace hardware faults in the child. */ - prfillset (&traced_faults); /* trace all faults... */ - prdelset (&traced_faults, FLTPAGE); /* except page fault. */ -#endif - if (!proc_set_traced_faults (pi, &traced_faults)) - return __LINE__; - - /* Register to trace selected signals in the child. */ - premptyset (&traced_signals); - if (!register_gdb_signals (pi, &traced_signals)) - return __LINE__; - - - /* Register to trace the 'exit' system call (on entry). */ - traced_syscall_entries = sysset_t_alloc (pi); - gdb_premptysysset (traced_syscall_entries); -#ifdef SYS_exit - gdb_praddsysset (traced_syscall_entries, SYS_exit); -#endif -#ifdef SYS_lwpexit - gdb_praddsysset (traced_syscall_entries, SYS_lwpexit); /* And _lwp_exit... */ -#endif -#ifdef SYS_lwp_exit - gdb_praddsysset (traced_syscall_entries, SYS_lwp_exit); -#endif -#ifdef DYNAMIC_SYSCALLS - { - int callnum = find_syscall (pi, "_exit"); - if (callnum >= 0) - gdb_praddsysset (traced_syscall_entries, callnum); - } -#endif - - status = proc_set_traced_sysentry (pi, traced_syscall_entries); - xfree (traced_syscall_entries); - if (!status) - return __LINE__; - -#ifdef PRFS_STOPEXEC /* defined on OSF */ - /* OSF method for tracing exec syscalls. Quoting: - Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace - exits from exec system calls because of the user level loader. */ - /* FIXME: make nice and maybe move into an access function. */ - { - int prfs_flags; - - if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0) - return __LINE__; - - prfs_flags |= PRFS_STOPEXEC; - - if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0) - return __LINE__; - } -#else /* not PRFS_STOPEXEC */ - /* Everyone else's (except OSF) method for tracing exec syscalls */ - /* GW: Rationale... - Not all systems with /proc have all the exec* syscalls with the same - names. On the SGI, for example, there is no SYS_exec, but there - *is* a SYS_execv. So, we try to account for that. */ - - traced_syscall_exits = sysset_t_alloc (pi); - gdb_premptysysset (traced_syscall_exits); -#ifdef SYS_exec - gdb_praddsysset (traced_syscall_exits, SYS_exec); -#endif -#ifdef SYS_execve - gdb_praddsysset (traced_syscall_exits, SYS_execve); -#endif -#ifdef SYS_execv - gdb_praddsysset (traced_syscall_exits, SYS_execv); -#endif - -#ifdef SYS_lwpcreate - gdb_praddsysset (traced_syscall_exits, SYS_lwpcreate); - gdb_praddsysset (traced_syscall_exits, SYS_lwpexit); -#endif - -#ifdef SYS_lwp_create /* FIXME: once only, please */ - gdb_praddsysset (traced_syscall_exits, SYS_lwp_create); - gdb_praddsysset (traced_syscall_exits, SYS_lwp_exit); -#endif - -#ifdef DYNAMIC_SYSCALLS - { - int callnum = find_syscall (pi, "execve"); - if (callnum >= 0) - gdb_praddsysset (traced_syscall_exits, callnum); - callnum = find_syscall (pi, "ra_execve"); - if (callnum >= 0) - gdb_praddsysset (traced_syscall_exits, callnum); - } -#endif - - status = proc_set_traced_sysexit (pi, traced_syscall_exits); - xfree (traced_syscall_exits); - if (!status) - return __LINE__; - -#endif /* PRFS_STOPEXEC */ - return 0; -} - -static void -procfs_attach (char *args, int from_tty) -{ - char *exec_file; - int pid; - - if (!args) - error_no_arg ("process-id to attach"); - - pid = atoi (args); - if (pid == getpid ()) - error ("Attaching GDB to itself is not a good idea..."); - - if (from_tty) - { - exec_file = get_exec_file (0); - - if (exec_file) - printf_filtered ("Attaching to program `%s', %s\n", - exec_file, target_pid_to_str (pid_to_ptid (pid))); - else - printf_filtered ("Attaching to %s\n", - target_pid_to_str (pid_to_ptid (pid))); - - fflush (stdout); - } - inferior_ptid = do_attach (pid_to_ptid (pid)); - push_target (&procfs_ops); -} - -static void -procfs_detach (char *args, int from_tty) -{ - char *exec_file; - int signo = 0; - - if (from_tty) - { - exec_file = get_exec_file (0); - if (exec_file == 0) - exec_file = ""; - printf_filtered ("Detaching from program: %s %s\n", - exec_file, target_pid_to_str (inferior_ptid)); - fflush (stdout); - } - if (args) - signo = atoi (args); - - do_detach (signo); - inferior_ptid = null_ptid; - unpush_target (&procfs_ops); /* Pop out of handling an inferior */ -} - -static ptid_t -do_attach (ptid_t ptid) -{ - procinfo *pi; - int fail; - - if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL) - perror ("procfs: out of memory in 'attach'"); - - if (!open_procinfo_files (pi, FD_CTL)) - { - fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__); - sprintf (errmsg, "do_attach: couldn't open /proc file for process %d", - PIDGET (ptid)); - dead_procinfo (pi, errmsg, NOKILL); - } - - /* Stop the process (if it isn't already stopped). */ - if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) - { - pi->was_stopped = 1; - proc_prettyprint_why (proc_why (pi), proc_what (pi), 1); - } - else - { - pi->was_stopped = 0; - /* Set the process to run again when we close it. */ - if (!proc_set_run_on_last_close (pi)) - dead_procinfo (pi, "do_attach: couldn't set RLC.", NOKILL); - - /* Now stop the process. */ - if (!proc_stop_process (pi)) - dead_procinfo (pi, "do_attach: couldn't stop the process.", NOKILL); - pi->ignore_next_sigstop = 1; - } - /* Save some of the /proc state to be restored if we detach. */ - if (!proc_get_traced_faults (pi, &pi->saved_fltset)) - dead_procinfo (pi, "do_attach: couldn't save traced faults.", NOKILL); - if (!proc_get_traced_signals (pi, &pi->saved_sigset)) - dead_procinfo (pi, "do_attach: couldn't save traced signals.", NOKILL); - if (!proc_get_traced_sysentry (pi, pi->saved_entryset)) - dead_procinfo (pi, "do_attach: couldn't save traced syscall entries.", - NOKILL); - if (!proc_get_traced_sysexit (pi, pi->saved_exitset)) - dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.", - NOKILL); - if (!proc_get_held_signals (pi, &pi->saved_sighold)) - dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL); - - if ((fail = procfs_debug_inferior (pi)) != 0) - dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL); - - /* Let GDB know that the inferior was attached. */ - attach_flag = 1; - return MERGEPID (pi->pid, proc_get_current_thread (pi)); -} - -static void -do_detach (int signo) -{ - procinfo *pi; - - /* Find procinfo for the main process */ - pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); /* FIXME: threads */ - if (signo) - if (!proc_set_current_signal (pi, signo)) - proc_warn (pi, "do_detach, set_current_signal", __LINE__); - - if (!proc_set_traced_signals (pi, &pi->saved_sigset)) - proc_warn (pi, "do_detach, set_traced_signal", __LINE__); - - if (!proc_set_traced_faults (pi, &pi->saved_fltset)) - proc_warn (pi, "do_detach, set_traced_faults", __LINE__); - - if (!proc_set_traced_sysentry (pi, pi->saved_entryset)) - proc_warn (pi, "do_detach, set_traced_sysentry", __LINE__); - - if (!proc_set_traced_sysexit (pi, pi->saved_exitset)) - proc_warn (pi, "do_detach, set_traced_sysexit", __LINE__); - - if (!proc_set_held_signals (pi, &pi->saved_sighold)) - proc_warn (pi, "do_detach, set_held_signals", __LINE__); - - if (signo || (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))) - if (signo || !(pi->was_stopped) || - query ("Was stopped when attached, make it runnable again? ")) - { - /* Clear any pending signal. */ - if (!proc_clear_current_fault (pi)) - proc_warn (pi, "do_detach, clear_current_fault", __LINE__); - - if (!proc_set_run_on_last_close (pi)) - proc_warn (pi, "do_detach, set_rlc", __LINE__); - } - - attach_flag = 0; - destroy_procinfo (pi); -} - -/* - * fetch_registers - * - * Since the /proc interface cannot give us individual registers, - * we pay no attention to the (regno) argument, and just fetch them all. - * This results in the possibility that we will do unnecessarily many - * fetches, since we may be called repeatedly for individual registers. - * So we cache the results, and mark the cache invalid when the process - * is resumed. - */ - -static void -procfs_fetch_registers (int regno) -{ - gdb_fpregset_t *fpregs; - gdb_gregset_t *gregs; - procinfo *pi; - int pid; - int tid; - - pid = PIDGET (inferior_ptid); - tid = TIDGET (inferior_ptid); - - /* First look up procinfo for the main process. */ - pi = find_procinfo_or_die (pid, 0); - - /* If the event thread is not the same as GDB's requested thread - (ie. inferior_ptid), then look up procinfo for the requested - thread. */ - if ((tid != 0) && - (tid != proc_get_current_thread (pi))) - pi = find_procinfo_or_die (pid, tid); - - if (pi == NULL) - error ("procfs: fetch_registers failed to find procinfo for %s", - target_pid_to_str (inferior_ptid)); - - if ((gregs = proc_get_gregs (pi)) == NULL) - proc_error (pi, "fetch_registers, get_gregs", __LINE__); - - supply_gregset (gregs); - - if (FP0_REGNUM >= 0) /* need floating point? */ - { - if ((regno >= 0 && regno < FP0_REGNUM) || - regno == PC_REGNUM || - (NPC_REGNUM >= 0 && regno == NPC_REGNUM) || - regno == FP_REGNUM || - regno == SP_REGNUM) - return; /* not a floating point register */ - - if ((fpregs = proc_get_fpregs (pi)) == NULL) - proc_error (pi, "fetch_registers, get_fpregs", __LINE__); - - supply_fpregset (fpregs); - } -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On - machines which store all the registers in one fell swoop, such as - /proc, this makes sure that registers contains all the registers - from the program being debugged. */ - -static void -procfs_prepare_to_store (void) -{ -#ifdef CHILD_PREPARE_TO_STORE - CHILD_PREPARE_TO_STORE (); -#endif -} - -/* - * store_registers - * - * Since the /proc interface will not read individual registers, - * we will cache these requests until the process is resumed, and - * only then write them back to the inferior process. - * - * FIXME: is that a really bad idea? Have to think about cases - * where writing one register might affect the value of others, etc. - */ - -static void -procfs_store_registers (int regno) -{ - gdb_fpregset_t *fpregs; - gdb_gregset_t *gregs; - procinfo *pi; - int pid; - int tid; - - pid = PIDGET (inferior_ptid); - tid = TIDGET (inferior_ptid); - - /* First find procinfo for main process */ - pi = find_procinfo_or_die (pid, 0); - - /* If current lwp for process is not the same as requested thread - (ie. inferior_ptid), then find procinfo for the requested thread. */ - - if ((tid != 0) && - (tid != proc_get_current_thread (pi))) - pi = find_procinfo_or_die (pid, tid); - - if (pi == NULL) - error ("procfs: store_registers: failed to find procinfo for %s", - target_pid_to_str (inferior_ptid)); - - if ((gregs = proc_get_gregs (pi)) == NULL) - proc_error (pi, "store_registers, get_gregs", __LINE__); - - fill_gregset (gregs, regno); - if (!proc_set_gregs (pi)) - proc_error (pi, "store_registers, set_gregs", __LINE__); - - if (FP0_REGNUM >= 0) /* need floating point? */ - { - if ((regno >= 0 && regno < FP0_REGNUM) || - regno == PC_REGNUM || - (NPC_REGNUM >= 0 && regno == NPC_REGNUM) || - regno == FP_REGNUM || - regno == SP_REGNUM) - return; /* not a floating point register */ - - if ((fpregs = proc_get_fpregs (pi)) == NULL) - proc_error (pi, "store_registers, get_fpregs", __LINE__); - - fill_fpregset (fpregs, regno); - if (!proc_set_fpregs (pi)) - proc_error (pi, "store_registers, set_fpregs", __LINE__); - } -} - -static int -syscall_is_lwp_exit (procinfo *pi, int scall) -{ - -#ifdef SYS_lwp_exit - if (scall == SYS_lwp_exit) - return 1; -#endif -#ifdef SYS_lwpexit - if (scall == SYS_lwpexit) - return 1; -#endif - return 0; -} - -static int -syscall_is_exit (procinfo *pi, int scall) -{ -#ifdef SYS_exit - if (scall == SYS_exit) - return 1; -#endif -#ifdef DYNAMIC_SYSCALLS - if (find_syscall (pi, "_exit") == scall) - return 1; -#endif - return 0; -} - -static int -syscall_is_exec (procinfo *pi, int scall) -{ -#ifdef SYS_exec - if (scall == SYS_exec) - return 1; -#endif -#ifdef SYS_execv - if (scall == SYS_execv) - return 1; -#endif -#ifdef SYS_execve - if (scall == SYS_execve) - return 1; -#endif -#ifdef DYNAMIC_SYSCALLS - if (find_syscall (pi, "_execve")) - return 1; - if (find_syscall (pi, "ra_execve")) - return 1; -#endif - return 0; -} - -static int -syscall_is_lwp_create (procinfo *pi, int scall) -{ -#ifdef SYS_lwp_create - if (scall == SYS_lwp_create) - return 1; -#endif -#ifdef SYS_lwpcreate - if (scall == SYS_lwpcreate) - return 1; -#endif - return 0; -} - -/* - * Function: target_wait - * - * Retrieve the next stop event from the child process. - * If child has not stopped yet, wait for it to stop. - * Translate /proc eventcodes (or possibly wait eventcodes) - * into gdb internal event codes. - * - * Return: id of process (and possibly thread) that incurred the event. - * event codes are returned thru a pointer parameter. - */ - -static ptid_t -procfs_wait (ptid_t ptid, struct target_waitstatus *status) -{ - /* First cut: loosely based on original version 2.1 */ - procinfo *pi; - int wstat; - int temp_tid; - ptid_t retval, temp_ptid; - int why, what, flags; - int retry = 0; - -wait_again: - - retry++; - wstat = 0; - retval = pid_to_ptid (-1); - - /* Find procinfo for main process */ - pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - if (pi) - { - /* We must assume that the status is stale now... */ - pi->status_valid = 0; - pi->gregs_valid = 0; - pi->fpregs_valid = 0; - -#if 0 /* just try this out... */ - flags = proc_flags (pi); - why = proc_why (pi); - if ((flags & PR_STOPPED) && (why == PR_REQUESTED)) - pi->status_valid = 0; /* re-read again, IMMEDIATELY... */ -#endif - /* If child is not stopped, wait for it to stop. */ - if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) && - !proc_wait_for_stop (pi)) - { - /* wait_for_stop failed: has the child terminated? */ - if (errno == ENOENT) - { - int wait_retval; - - /* /proc file not found; presumably child has terminated. */ - wait_retval = wait (&wstat); /* "wait" for the child's exit */ - - if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */ - error ("procfs: couldn't stop process %d: wait returned %d\n", - PIDGET (inferior_ptid), wait_retval); - /* FIXME: might I not just use waitpid? - Or try find_procinfo to see if I know about this child? */ - retval = pid_to_ptid (wait_retval); - } - else if (errno == EINTR) - goto wait_again; - else - { - /* Unknown error from wait_for_stop. */ - proc_error (pi, "target_wait (wait_for_stop)", __LINE__); - } - } - else - { - /* This long block is reached if either: - a) the child was already stopped, or - b) we successfully waited for the child with wait_for_stop. - This block will analyze the /proc status, and translate it - into a waitstatus for GDB. - - If we actually had to call wait because the /proc file - is gone (child terminated), then we skip this block, - because we already have a waitstatus. */ - - flags = proc_flags (pi); - why = proc_why (pi); - what = proc_what (pi); - - if (flags & (PR_STOPPED | PR_ISTOP)) - { -#ifdef PR_ASYNC - /* If it's running async (for single_thread control), - set it back to normal again. */ - if (flags & PR_ASYNC) - if (!proc_unset_async (pi)) - proc_error (pi, "target_wait, unset_async", __LINE__); -#endif - - if (info_verbose) - proc_prettyprint_why (why, what, 1); - - /* The 'pid' we will return to GDB is composed of - the process ID plus the lwp ID. */ - retval = MERGEPID (pi->pid, proc_get_current_thread (pi)); - - switch (why) { - case PR_SIGNALLED: - wstat = (what << 8) | 0177; - break; - case PR_SYSENTRY: - if (syscall_is_lwp_exit (pi, what)) - { - printf_filtered ("[%s exited]\n", - target_pid_to_str (retval)); - delete_thread (retval); - status->kind = TARGET_WAITKIND_SPURIOUS; - return retval; - } - else if (syscall_is_exit (pi, what)) - { - /* Handle SYS_exit call only */ - /* Stopped at entry to SYS_exit. - Make it runnable, resume it, then use - the wait system call to get its exit code. - Proc_run_process always clears the current - fault and signal. - Then return its exit status. */ - pi->status_valid = 0; - wstat = 0; - /* FIXME: what we should do is return - TARGET_WAITKIND_SPURIOUS. */ - if (!proc_run_process (pi, 0, 0)) - proc_error (pi, "target_wait, run_process", __LINE__); - if (attach_flag) - { - /* Don't call wait: simulate waiting for exit, - return a "success" exit code. Bogus: what if - it returns something else? */ - wstat = 0; - retval = inferior_ptid; /* ? ? ? */ - } - else - { - int temp = wait (&wstat); - - /* FIXME: shouldn't I make sure I get the right - event from the right process? If (for - instance) I have killed an earlier inferior - process but failed to clean up after it - somehow, I could get its termination event - here. */ - - /* If wait returns -1, that's what we return to GDB. */ - if (temp < 0) - retval = pid_to_ptid (temp); - } - } - else - { - printf_filtered ("procfs: trapped on entry to "); - proc_prettyprint_syscall (proc_what (pi), 0); - printf_filtered ("\n"); -#ifndef PIOCSSPCACT - { - long i, nsysargs, *sysargs; - - if ((nsysargs = proc_nsysarg (pi)) > 0 && - (sysargs = proc_sysargs (pi)) != NULL) - { - printf_filtered ("%ld syscall arguments:\n", nsysargs); - for (i = 0; i < nsysargs; i++) - printf_filtered ("#%ld: 0x%08lx\n", - i, sysargs[i]); - } - - } -#endif - if (status) - { - /* How to exit gracefully, returning "unknown event" */ - status->kind = TARGET_WAITKIND_SPURIOUS; - return inferior_ptid; - } - else - { - /* How to keep going without returning to wfi: */ - target_resume (ptid, 0, TARGET_SIGNAL_0); - goto wait_again; - } - } - break; - case PR_SYSEXIT: - if (syscall_is_exec (pi, what)) - { - /* Hopefully this is our own "fork-child" execing - the real child. Hoax this event into a trap, and - GDB will see the child about to execute its start - address. */ - wstat = (SIGTRAP << 8) | 0177; - } - else if (syscall_is_lwp_create (pi, what)) - { - /* - * This syscall is somewhat like fork/exec. - * We will get the event twice: once for the parent LWP, - * and once for the child. We should already know about - * the parent LWP, but the child will be new to us. So, - * whenever we get this event, if it represents a new - * thread, simply add the thread to the list. - */ - - /* If not in procinfo list, add it. */ - temp_tid = proc_get_current_thread (pi); - if (!find_procinfo (pi->pid, temp_tid)) - create_procinfo (pi->pid, temp_tid); - - temp_ptid = MERGEPID (pi->pid, temp_tid); - /* If not in GDB's thread list, add it. */ - if (!in_thread_list (temp_ptid)) - { - printf_filtered ("[New %s]\n", - target_pid_to_str (temp_ptid)); - add_thread (temp_ptid); - } - /* Return to WFI, but tell it to immediately resume. */ - status->kind = TARGET_WAITKIND_SPURIOUS; - return inferior_ptid; - } - else if (syscall_is_lwp_exit (pi, what)) - { - printf_filtered ("[%s exited]\n", - target_pid_to_str (retval)); - delete_thread (retval); - status->kind = TARGET_WAITKIND_SPURIOUS; - return retval; - } - else if (0) - { - /* FIXME: Do we need to handle SYS_sproc, - SYS_fork, or SYS_vfork here? The old procfs - seemed to use this event to handle threads on - older (non-LWP) systems, where I'm assuming - that threads were actually separate processes. - Irix, maybe? Anyway, low priority for now. */ - } - else - { - printf_filtered ("procfs: trapped on exit from "); - proc_prettyprint_syscall (proc_what (pi), 0); - printf_filtered ("\n"); -#ifndef PIOCSSPCACT - { - long i, nsysargs, *sysargs; - - if ((nsysargs = proc_nsysarg (pi)) > 0 && - (sysargs = proc_sysargs (pi)) != NULL) - { - printf_filtered ("%ld syscall arguments:\n", nsysargs); - for (i = 0; i < nsysargs; i++) - printf_filtered ("#%ld: 0x%08lx\n", - i, sysargs[i]); - } - } -#endif - status->kind = TARGET_WAITKIND_SPURIOUS; - return inferior_ptid; - } - break; - case PR_REQUESTED: -#if 0 /* FIXME */ - wstat = (SIGSTOP << 8) | 0177; - break; -#else - if (retry < 5) - { - printf_filtered ("Retry #%d:\n", retry); - pi->status_valid = 0; - goto wait_again; - } - else - { - /* If not in procinfo list, add it. */ - temp_tid = proc_get_current_thread (pi); - if (!find_procinfo (pi->pid, temp_tid)) - create_procinfo (pi->pid, temp_tid); - - /* If not in GDB's thread list, add it. */ - temp_ptid = MERGEPID (pi->pid, temp_tid); - if (!in_thread_list (temp_ptid)) - { - printf_filtered ("[New %s]\n", - target_pid_to_str (temp_ptid)); - add_thread (temp_ptid); - } - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = 0; - return retval; - } -#endif - case PR_JOBCONTROL: - wstat = (what << 8) | 0177; - break; - case PR_FAULTED: - switch (what) { /* FIXME: FAULTED_USE_SIGINFO */ -#ifdef FLTWATCH - case FLTWATCH: - wstat = (SIGTRAP << 8) | 0177; - break; -#endif -#ifdef FLTKWATCH - case FLTKWATCH: - wstat = (SIGTRAP << 8) | 0177; - break; -#endif - /* FIXME: use si_signo where possible. */ - case FLTPRIV: -#if (FLTILL != FLTPRIV) /* avoid "duplicate case" error */ - case FLTILL: -#endif - wstat = (SIGILL << 8) | 0177; - break; - case FLTBPT: -#if (FLTTRACE != FLTBPT) /* avoid "duplicate case" error */ - case FLTTRACE: -#endif - wstat = (SIGTRAP << 8) | 0177; - break; - case FLTSTACK: - case FLTACCESS: -#if (FLTBOUNDS != FLTSTACK) /* avoid "duplicate case" error */ - case FLTBOUNDS: -#endif - wstat = (SIGSEGV << 8) | 0177; - break; - case FLTIOVF: - case FLTIZDIV: -#if (FLTFPE != FLTIOVF) /* avoid "duplicate case" error */ - case FLTFPE: -#endif - wstat = (SIGFPE << 8) | 0177; - break; - case FLTPAGE: /* Recoverable page fault */ - default: /* FIXME: use si_signo if possible for fault */ - retval = pid_to_ptid (-1); - printf_filtered ("procfs:%d -- ", __LINE__); - printf_filtered ("child stopped for unknown reason:\n"); - proc_prettyprint_why (why, what, 1); - error ("... giving up..."); - break; - } - break; /* case PR_FAULTED: */ - default: /* switch (why) unmatched */ - printf_filtered ("procfs:%d -- ", __LINE__); - printf_filtered ("child stopped for unknown reason:\n"); - proc_prettyprint_why (why, what, 1); - error ("... giving up..."); - break; - } - /* - * Got this far without error: - * If retval isn't in the threads database, add it. - */ - if (PIDGET (retval) > 0 && - !ptid_equal (retval, inferior_ptid) && - !in_thread_list (retval)) - { - /* - * We have a new thread. - * We need to add it both to GDB's list and to our own. - * If we don't create a procinfo, resume may be unhappy - * later. - */ - printf_filtered ("[New %s]\n", target_pid_to_str (retval)); - add_thread (retval); - if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL) - create_procinfo (PIDGET (retval), TIDGET (retval)); - - /* In addition, it's possible that this is the first - * new thread we've seen, in which case we may not - * have created entries for inferior_ptid yet. - */ - if (TIDGET (inferior_ptid) != 0) - { - if (!in_thread_list (inferior_ptid)) - add_thread (inferior_ptid); - if (find_procinfo (PIDGET (inferior_ptid), - TIDGET (inferior_ptid)) == NULL) - create_procinfo (PIDGET (inferior_ptid), - TIDGET (inferior_ptid)); - } - } - } - else /* flags do not indicate STOPPED */ - { - /* surely this can't happen... */ - printf_filtered ("procfs:%d -- process not stopped.\n", - __LINE__); - proc_prettyprint_flags (flags, 1); - error ("procfs: ...giving up..."); - } - } - - if (status) - store_waitstatus (status, wstat); - } - - return retval; -} - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If DOWRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - The return value is 0 if an error occurred or no bytes were - transferred. Otherwise, it will be a positive value which - indicates the number of bytes transferred between gdb and the - target. (Note that the interface also makes provisions for - negative values, but this capability isn't implemented here.) */ - -static int -procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite, - struct mem_attrib *attrib, struct target_ops *target) -{ - procinfo *pi; - int nbytes = 0; - - /* Find procinfo for main process */ - pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - if (pi->as_fd == 0 && - open_procinfo_files (pi, FD_AS) == 0) - { - proc_warn (pi, "xfer_memory, open_proc_files", __LINE__); - return 0; - } - - if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr) - { - if (dowrite) - { -#ifdef NEW_PROC_API - PROCFS_NOTE ("write memory: "); -#else - PROCFS_NOTE ("write memory: \n"); -#endif - nbytes = write (pi->as_fd, myaddr, len); - } - else - { - PROCFS_NOTE ("read memory: \n"); - nbytes = read (pi->as_fd, myaddr, len); - } - if (nbytes < 0) - { - nbytes = 0; - } - } - return nbytes; -} - -/* - * Function: invalidate_cache - * - * Called by target_resume before making child runnable. - * Mark cached registers and status's invalid. - * If there are "dirty" caches that need to be written back - * to the child process, do that. - * - * File descriptors are also cached. - * As they are a limited resource, we cannot hold onto them indefinitely. - * However, as they are expensive to open, we don't want to throw them - * away indescriminately either. As a compromise, we will keep the - * file descriptors for the parent process, but discard any file - * descriptors we may have accumulated for the threads. - * - * Return value: - * As this function is called by iterate_over_threads, it always - * returns zero (so that iterate_over_threads will keep iterating). - */ - - -static int -invalidate_cache (procinfo *parent, procinfo *pi, void *ptr) -{ - /* - * About to run the child; invalidate caches and do any other cleanup. - */ - -#if 0 - if (pi->gregs_dirty) - if (parent == NULL || - proc_get_current_thread (parent) != pi->tid) - if (!proc_set_gregs (pi)) /* flush gregs cache */ - proc_warn (pi, "target_resume, set_gregs", - __LINE__); - if (FP0_REGNUM >= 0) - if (pi->fpregs_dirty) - if (parent == NULL || - proc_get_current_thread (parent) != pi->tid) - if (!proc_set_fpregs (pi)) /* flush fpregs cache */ - proc_warn (pi, "target_resume, set_fpregs", - __LINE__); -#endif - - if (parent != NULL) - { - /* The presence of a parent indicates that this is an LWP. - Close any file descriptors that it might have open. - We don't do this to the master (parent) procinfo. */ - - close_procinfo_files (pi); - } - pi->gregs_valid = 0; - pi->fpregs_valid = 0; -#if 0 - pi->gregs_dirty = 0; - pi->fpregs_dirty = 0; -#endif - pi->status_valid = 0; - pi->threads_valid = 0; - - return 0; -} - -#if 0 -/* - * Function: make_signal_thread_runnable - * - * A callback function for iterate_over_threads. - * Find the asynchronous signal thread, and make it runnable. - * See if that helps matters any. - */ - -static int -make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr) -{ -#ifdef PR_ASLWP - if (proc_flags (pi) & PR_ASLWP) - { - if (!proc_run_process (pi, 0, -1)) - proc_error (pi, "make_signal_thread_runnable", __LINE__); - return 1; - } -#endif - return 0; -} -#endif - -/* - * Function: target_resume - * - * Make the child process runnable. Normally we will then call - * procfs_wait and wait for it to stop again (unles gdb is async). - * - * Arguments: - * step: if true, then arrange for the child to stop again - * after executing a single instruction. - * signo: if zero, then cancel any pending signal. - * If non-zero, then arrange for the indicated signal - * to be delivered to the child when it runs. - * pid: if -1, then allow any child thread to run. - * if non-zero, then allow only the indicated thread to run. - ******* (not implemented yet) - */ - -static void -procfs_resume (ptid_t ptid, int step, enum target_signal signo) -{ - procinfo *pi, *thread; - int native_signo; - - /* 2.1: - prrun.prflags |= PRSVADDR; - prrun.pr_vaddr = $PC; set resume address - prrun.prflags |= PRSTRACE; trace signals in pr_trace (all) - prrun.prflags |= PRSFAULT; trace faults in pr_fault (all but PAGE) - prrun.prflags |= PRCFAULT; clear current fault. - - PRSTRACE and PRSFAULT can be done by other means - (proc_trace_signals, proc_trace_faults) - PRSVADDR is unnecessary. - PRCFAULT may be replaced by a PIOCCFAULT call (proc_clear_current_fault) - This basically leaves PRSTEP and PRCSIG. - PRCSIG is like PIOCSSIG (proc_clear_current_signal). - So basically PR_STEP is the sole argument that must be passed - to proc_run_process (for use in the prrun struct by ioctl). */ - - /* Find procinfo for main process */ - pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - - /* First cut: ignore pid argument */ - errno = 0; - - /* Convert signal to host numbering. */ - if (signo == 0 || - (signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop)) - native_signo = 0; - else - native_signo = target_signal_to_host (signo); - - pi->ignore_next_sigstop = 0; - - /* Running the process voids all cached registers and status. */ - /* Void the threads' caches first */ - proc_iterate_over_threads (pi, invalidate_cache, NULL); - /* Void the process procinfo's caches. */ - invalidate_cache (NULL, pi, NULL); - - if (PIDGET (ptid) != -1) - { - /* Resume a specific thread, presumably suppressing the others. */ - thread = find_procinfo (PIDGET (ptid), TIDGET (ptid)); - if (thread != NULL) - { - if (thread->tid != 0) - { - /* We're to resume a specific thread, and not the others. - * Set the child process's PR_ASYNC flag. - */ -#ifdef PR_ASYNC - if (!proc_set_async (pi)) - proc_error (pi, "target_resume, set_async", __LINE__); -#endif -#if 0 - proc_iterate_over_threads (pi, - make_signal_thread_runnable, - NULL); -#endif - pi = thread; /* substitute the thread's procinfo for run */ - } - } - } - - if (!proc_run_process (pi, step, native_signo)) - { - if (errno == EBUSY) - warning ("resume: target already running. Pretend to resume, and hope for the best!\n"); - else - proc_error (pi, "target_resume", __LINE__); - } -} - -/* - * Function: register_gdb_signals - * - * Traverse the list of signals that GDB knows about - * (see "handle" command), and arrange for the target - * to be stopped or not, according to these settings. - * - * Returns non-zero for success, zero for failure. - */ - -static int -register_gdb_signals (procinfo *pi, gdb_sigset_t *signals) -{ - int signo; - - for (signo = 0; signo < NSIG; signo ++) - if (signal_stop_state (target_signal_from_host (signo)) == 0 && - signal_print_state (target_signal_from_host (signo)) == 0 && - signal_pass_state (target_signal_from_host (signo)) == 1) - prdelset (signals, signo); - else - praddset (signals, signo); - - return proc_set_traced_signals (pi, signals); -} - -/* - * Function: target_notice_signals - * - * Set up to trace signals in the child process. - */ - -static void -procfs_notice_signals (ptid_t ptid) -{ - gdb_sigset_t signals; - procinfo *pi = find_procinfo_or_die (PIDGET (ptid), 0); - - if (proc_get_traced_signals (pi, &signals) && - register_gdb_signals (pi, &signals)) - return; - else - proc_error (pi, "notice_signals", __LINE__); -} - -/* - * Function: target_files_info - * - * Print status information about the child process. - */ - -static void -procfs_files_info (struct target_ops *ignore) -{ - printf_filtered ("\tUsing the running image of %s %s via /proc.\n", - attach_flag? "attached": "child", - target_pid_to_str (inferior_ptid)); -} - -/* - * Function: target_open - * - * A dummy: you don't open procfs. - */ - -static void -procfs_open (char *args, int from_tty) -{ - error ("Use the \"run\" command to start a Unix child process."); -} - -/* - * Function: target_can_run - * - * This tells GDB that this target vector can be invoked - * for "run" or "attach". - */ - -int procfs_suppress_run = 0; /* Non-zero if procfs should pretend not to - be a runnable target. Used by targets - that can sit atop procfs, such as solaris - thread support. */ - - -static int -procfs_can_run (void) -{ - /* This variable is controlled by modules that sit atop procfs that - may layer their own process structure atop that provided here. - sol-thread.c does this because of the Solaris two-level thread - model. */ - - /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */ - - return !procfs_suppress_run; -} - -/* - * Function: target_stop - * - * Stop the child process asynchronously, as when the - * gdb user types control-c or presses a "stop" button. - * - * Works by sending kill(SIGINT) to the child's process group. - */ - -static void -procfs_stop (void) -{ - extern pid_t inferior_process_group; - - kill (-inferior_process_group, SIGINT); -} - -/* - * Function: unconditionally_kill_inferior - * - * Make it die. Wait for it to die. Clean up after it. - * Note: this should only be applied to the real process, - * not to an LWP, because of the check for parent-process. - * If we need this to work for an LWP, it needs some more logic. - */ - -static void -unconditionally_kill_inferior (procinfo *pi) -{ - int parent_pid; - - parent_pid = proc_parent_pid (pi); -#ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL - /* FIXME: use access functions */ - /* Alpha OSF/1-3.x procfs needs a clear of the current signal - before the PIOCKILL, otherwise it might generate a corrupted core - file for the inferior. */ - if (ioctl (pi->ctl_fd, PIOCSSIG, NULL) < 0) - { - printf_filtered ("unconditionally_kill: SSIG failed!\n"); - } -#endif -#ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL - /* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal - to kill the inferior, otherwise it might remain stopped with a - pending SIGKILL. - We do not check the result of the PIOCSSIG, the inferior might have - died already. */ - { - gdb_siginfo_t newsiginfo; - - memset ((char *) &newsiginfo, 0, sizeof (newsiginfo)); - newsiginfo.si_signo = SIGKILL; - newsiginfo.si_code = 0; - newsiginfo.si_errno = 0; - newsiginfo.si_pid = getpid (); - newsiginfo.si_uid = getuid (); - /* FIXME: use proc_set_current_signal */ - ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo); - } -#else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */ - if (!proc_kill (pi, SIGKILL)) - proc_error (pi, "unconditionally_kill, proc_kill", __LINE__); -#endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */ - destroy_procinfo (pi); - - /* If pi is GDB's child, wait for it to die. */ - if (parent_pid == getpid ()) - /* FIXME: should we use waitpid to make sure we get the right event? - Should we check the returned event? */ - { -#if 0 - int status, ret; - - ret = waitpid (pi->pid, &status, 0); -#else - wait (NULL); -#endif - } -} - -/* - * Function: target_kill_inferior - * - * We're done debugging it, and we want it to go away. - * Then we want GDB to forget all about it. - */ - -static void -procfs_kill_inferior (void) -{ - if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */ - { - /* Find procinfo for main process */ - procinfo *pi = find_procinfo (PIDGET (inferior_ptid), 0); - - if (pi) - unconditionally_kill_inferior (pi); - target_mourn_inferior (); - } -} - -/* - * Function: target_mourn_inferior - * - * Forget we ever debugged this thing! - */ - -static void -procfs_mourn_inferior (void) -{ - procinfo *pi; - - if (!ptid_equal (inferior_ptid, null_ptid)) - { - /* Find procinfo for main process */ - pi = find_procinfo (PIDGET (inferior_ptid), 0); - if (pi) - destroy_procinfo (pi); - } - unpush_target (&procfs_ops); - generic_mourn_inferior (); -} - -/* - * Function: init_inferior - * - * When GDB forks to create a runnable inferior process, - * this function is called on the parent side of the fork. - * It's job is to do whatever is necessary to make the child - * ready to be debugged, and then wait for the child to synchronize. - */ - -static void -procfs_init_inferior (int pid) -{ - procinfo *pi; - gdb_sigset_t signals; - int fail; - - /* This routine called on the parent side (GDB side) - after GDB forks the inferior. */ - - push_target (&procfs_ops); - - if ((pi = create_procinfo (pid, 0)) == NULL) - perror ("procfs: out of memory in 'init_inferior'"); - - if (!open_procinfo_files (pi, FD_CTL)) - proc_error (pi, "init_inferior, open_proc_files", __LINE__); - - /* - xmalloc // done - open_procinfo_files // done - link list // done - prfillset (trace) - procfs_notice_signals - prfillset (fault) - prdelset (FLTPAGE) - PIOCWSTOP - PIOCSFAULT - */ - - /* If not stopped yet, wait for it to stop. */ - if (!(proc_flags (pi) & PR_STOPPED) && - !(proc_wait_for_stop (pi))) - dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL); - - /* Save some of the /proc state to be restored if we detach. */ - /* FIXME: Why? In case another debugger was debugging it? - We're it's parent, for Ghu's sake! */ - if (!proc_get_traced_signals (pi, &pi->saved_sigset)) - proc_error (pi, "init_inferior, get_traced_signals", __LINE__); - if (!proc_get_held_signals (pi, &pi->saved_sighold)) - proc_error (pi, "init_inferior, get_held_signals", __LINE__); - if (!proc_get_traced_faults (pi, &pi->saved_fltset)) - proc_error (pi, "init_inferior, get_traced_faults", __LINE__); - if (!proc_get_traced_sysentry (pi, pi->saved_entryset)) - proc_error (pi, "init_inferior, get_traced_sysentry", __LINE__); - if (!proc_get_traced_sysexit (pi, pi->saved_exitset)) - proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__); - - /* Register to trace selected signals in the child. */ - prfillset (&signals); - if (!register_gdb_signals (pi, &signals)) - proc_error (pi, "init_inferior, register_signals", __LINE__); - - if ((fail = procfs_debug_inferior (pi)) != 0) - proc_error (pi, "init_inferior (procfs_debug_inferior)", fail); - - /* FIXME: logically, we should really be turning OFF run-on-last-close, - and possibly even turning ON kill-on-last-close at this point. But - I can't make that change without careful testing which I don't have - time to do right now... */ - /* Turn on run-on-last-close flag so that the child - will die if GDB goes away for some reason. */ - if (!proc_set_run_on_last_close (pi)) - proc_error (pi, "init_inferior, set_RLC", __LINE__); - - /* The 'process ID' we return to GDB is composed of - the actual process ID plus the lwp ID. */ - inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi)); - -#ifdef START_INFERIOR_TRAPS_EXPECTED - startup_inferior (START_INFERIOR_TRAPS_EXPECTED); -#else - /* One trap to exec the shell, one to exec the program being debugged. */ - startup_inferior (2); -#endif /* START_INFERIOR_TRAPS_EXPECTED */ -} - -/* - * Function: set_exec_trap - * - * When GDB forks to create a new process, this function is called - * on the child side of the fork before GDB exec's the user program. - * Its job is to make the child minimally debuggable, so that the - * parent GDB process can connect to the child and take over. - * This function should do only the minimum to make that possible, - * and to synchronize with the parent process. The parent process - * should take care of the details. - */ - -static void -procfs_set_exec_trap (void) -{ - /* This routine called on the child side (inferior side) - after GDB forks the inferior. It must use only local variables, - because it may be sharing data space with its parent. */ - - procinfo *pi; - sysset_t *exitset; - - if ((pi = create_procinfo (getpid (), 0)) == NULL) - perror_with_name ("procfs: create_procinfo failed in child."); - - if (open_procinfo_files (pi, FD_CTL) == 0) - { - proc_warn (pi, "set_exec_trap, open_proc_files", __LINE__); - gdb_flush (gdb_stderr); - /* no need to call "dead_procinfo", because we're going to exit. */ - _exit (127); - } - -#ifdef PRFS_STOPEXEC /* defined on OSF */ - /* OSF method for tracing exec syscalls. Quoting: - Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace - exits from exec system calls because of the user level loader. */ - /* FIXME: make nice and maybe move into an access function. */ - { - int prfs_flags; - - if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0) - { - proc_warn (pi, "set_exec_trap (PIOCGSPCACT)", __LINE__); - gdb_flush (gdb_stderr); - _exit (127); - } - prfs_flags |= PRFS_STOPEXEC; - - if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0) - { - proc_warn (pi, "set_exec_trap (PIOCSSPCACT)", __LINE__); - gdb_flush (gdb_stderr); - _exit (127); - } - } -#else /* not PRFS_STOPEXEC */ - /* Everyone else's (except OSF) method for tracing exec syscalls */ - /* GW: Rationale... - Not all systems with /proc have all the exec* syscalls with the same - names. On the SGI, for example, there is no SYS_exec, but there - *is* a SYS_execv. So, we try to account for that. */ - - exitset = sysset_t_alloc (pi); - gdb_premptysysset (exitset); -#ifdef SYS_exec - gdb_praddsysset (exitset, SYS_exec); -#endif -#ifdef SYS_execve - gdb_praddsysset (exitset, SYS_execve); -#endif -#ifdef SYS_execv - gdb_praddsysset (exitset, SYS_execv); -#endif -#ifdef DYNAMIC_SYSCALLS - { - int callnum = find_syscall (pi, "execve"); - - if (callnum >= 0) - gdb_praddsysset (exitset, callnum); - - callnum = find_syscall (pi, "ra_execve"); - if (callnum >= 0) - gdb_praddsysset (exitset, callnum); - } -#endif /* DYNAMIC_SYSCALLS */ - - if (!proc_set_traced_sysexit (pi, exitset)) - { - proc_warn (pi, "set_exec_trap, set_traced_sysexit", __LINE__); - gdb_flush (gdb_stderr); - _exit (127); - } -#endif /* PRFS_STOPEXEC */ - - /* FIXME: should this be done in the parent instead? */ - /* Turn off inherit on fork flag so that all grand-children - of gdb start with tracing flags cleared. */ - if (!proc_unset_inherit_on_fork (pi)) - proc_warn (pi, "set_exec_trap, unset_inherit", __LINE__); - - /* Turn off run on last close flag, so that the child process - cannot run away just because we close our handle on it. - We want it to wait for the parent to attach. */ - if (!proc_unset_run_on_last_close (pi)) - proc_warn (pi, "set_exec_trap, unset_RLC", __LINE__); - - /* FIXME: No need to destroy the procinfo -- - we have our own address space, and we're about to do an exec! */ - /*destroy_procinfo (pi);*/ -} - -/* - * Function: create_inferior - * - * This function is called BEFORE gdb forks the inferior process. - * Its only real responsibility is to set things up for the fork, - * and tell GDB which two functions to call after the fork (one - * for the parent, and one for the child). - * - * This function does a complicated search for a unix shell program, - * which it then uses to parse arguments and environment variables - * to be sent to the child. I wonder whether this code could not - * be abstracted out and shared with other unix targets such as - * infptrace? - */ - -static void -procfs_create_inferior (char *exec_file, char *allargs, char **env) -{ - char *shell_file = getenv ("SHELL"); - char *tryname; - if (shell_file != NULL && strchr (shell_file, '/') == NULL) - { - - /* We will be looking down the PATH to find shell_file. If we - just do this the normal way (via execlp, which operates by - attempting an exec for each element of the PATH until it - finds one which succeeds), then there will be an exec for - each failed attempt, each of which will cause a PR_SYSEXIT - stop, and we won't know how to distinguish the PR_SYSEXIT's - for these failed execs with the ones for successful execs - (whether the exec has succeeded is stored at that time in the - carry bit or some such architecture-specific and - non-ABI-specified place). - - So I can't think of anything better than to search the PATH - now. This has several disadvantages: (1) There is a race - condition; if we find a file now and it is deleted before we - exec it, we lose, even if the deletion leaves a valid file - further down in the PATH, (2) there is no way to know exactly - what an executable (in the sense of "capable of being - exec'd") file is. Using access() loses because it may lose - if the caller is the superuser; failing to use it loses if - there are ACLs or some such. */ - - char *p; - char *p1; - /* FIXME-maybe: might want "set path" command so user can change what - path is used from within GDB. */ - char *path = getenv ("PATH"); - int len; - struct stat statbuf; - - if (path == NULL) - path = "/bin:/usr/bin"; - - tryname = alloca (strlen (path) + strlen (shell_file) + 2); - for (p = path; p != NULL; p = p1 ? p1 + 1: NULL) - { - p1 = strchr (p, ':'); - if (p1 != NULL) - len = p1 - p; - else - len = strlen (p); - strncpy (tryname, p, len); - tryname[len] = '\0'; - strcat (tryname, "/"); - strcat (tryname, shell_file); - if (access (tryname, X_OK) < 0) - continue; - if (stat (tryname, &statbuf) < 0) - continue; - if (!S_ISREG (statbuf.st_mode)) - /* We certainly need to reject directories. I'm not quite - as sure about FIFOs, sockets, etc., but I kind of doubt - that people want to exec() these things. */ - continue; - break; - } - if (p == NULL) - /* Not found. This must be an error rather than merely passing - the file to execlp(), because execlp() would try all the - exec()s, causing GDB to get confused. */ - error ("procfs:%d -- Can't find shell %s in PATH", - __LINE__, shell_file); - - shell_file = tryname; - } - - fork_inferior (exec_file, allargs, env, procfs_set_exec_trap, - procfs_init_inferior, NULL, shell_file); - - /* We are at the first instruction we care about. */ - /* Pedal to the metal... */ - - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0); -} - -/* - * Function: notice_thread - * - * Callback for find_new_threads. - * Calls "add_thread". - */ - -static int -procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr) -{ - ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid); - - if (!in_thread_list (gdb_threadid)) - add_thread (gdb_threadid); - - return 0; -} - -/* - * Function: target_find_new_threads - * - * Query all the threads that the target knows about, - * and give them back to GDB to add to its list. - */ - -void -procfs_find_new_threads (void) -{ - procinfo *pi; - - /* Find procinfo for main process */ - pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - proc_update_threads (pi); - proc_iterate_over_threads (pi, procfs_notice_thread, NULL); -} - -/* - * Function: target_thread_alive - * - * Return true if the thread is still 'alive'. - * - * This guy doesn't really seem to be doing his job. - * Got to investigate how to tell when a thread is really gone. - */ - -static int -procfs_thread_alive (ptid_t ptid) -{ - int proc, thread; - procinfo *pi; - - proc = PIDGET (ptid); - thread = TIDGET (ptid); - /* If I don't know it, it ain't alive! */ - if ((pi = find_procinfo (proc, thread)) == NULL) - return 0; - - /* If I can't get its status, it ain't alive! - What's more, I need to forget about it! */ - if (!proc_get_status (pi)) - { - destroy_procinfo (pi); - return 0; - } - /* I couldn't have got its status if it weren't alive, so it's alive. */ - return 1; -} - -/* - * Function: target_pid_to_str - * - * Return a string to be used to identify the thread in - * the "info threads" display. - */ - -char * -procfs_pid_to_str (ptid_t ptid) -{ - static char buf[80]; - int proc, thread; - procinfo *pi; - - proc = PIDGET (ptid); - thread = TIDGET (ptid); - pi = find_procinfo (proc, thread); - - if (thread == 0) - sprintf (buf, "Process %d", proc); - else - sprintf (buf, "LWP %d", thread); - return &buf[0]; -} - -/* - * Function: procfs_set_watchpoint - * Insert a watchpoint - */ - -int -procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag, - int after) -{ -#ifndef UNIXWARE -#ifndef AIX5 - int pflags = 0; - procinfo *pi; - - pi = find_procinfo_or_die (PIDGET (ptid) == -1 ? - PIDGET (inferior_ptid) : PIDGET (ptid), 0); - - /* Translate from GDB's flags to /proc's */ - if (len > 0) /* len == 0 means delete watchpoint */ - { - switch (rwflag) { /* FIXME: need an enum! */ - case hw_write: /* default watchpoint (write) */ - pflags = WRITE_WATCHFLAG; - break; - case hw_read: /* read watchpoint */ - pflags = READ_WATCHFLAG; - break; - case hw_access: /* access watchpoint */ - pflags = READ_WATCHFLAG | WRITE_WATCHFLAG; - break; - case hw_execute: /* execution HW breakpoint */ - pflags = EXEC_WATCHFLAG; - break; - default: /* Something weird. Return error. */ - return -1; - } - if (after) /* Stop after r/w access is completed. */ - pflags |= AFTER_WATCHFLAG; - } - - if (!proc_set_watchpoint (pi, addr, len, pflags)) - { - if (errno == E2BIG) /* Typical error for no resources */ - return -1; /* fail */ - /* GDB may try to remove the same watchpoint twice. - If a remove request returns no match, don't error. */ - if (errno == ESRCH && len == 0) - return 0; /* ignore */ - proc_error (pi, "set_watchpoint", __LINE__); - } -#endif /* AIX5 */ -#endif /* UNIXWARE */ - return 0; -} - -/* - * Function: stopped_by_watchpoint - * - * Returns non-zero if process is stopped on a hardware watchpoint fault, - * else returns zero. - */ - -int -procfs_stopped_by_watchpoint (ptid_t ptid) -{ - procinfo *pi; - - pi = find_procinfo_or_die (PIDGET (ptid) == -1 ? - PIDGET (inferior_ptid) : PIDGET (ptid), 0); - - if (!pi) /* If no process, then not stopped by watchpoint! */ - return 0; - - if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) - { - if (proc_why (pi) == PR_FAULTED) - { -#ifdef FLTWATCH - if (proc_what (pi) == FLTWATCH) - return 1; -#endif -#ifdef FLTKWATCH - if (proc_what (pi) == FLTKWATCH) - return 1; -#endif - } - } - return 0; -} - -#ifdef TM_I386SOL2_H -/* - * Function: procfs_find_LDT_entry - * - * Input: - * ptid_t ptid; // The GDB-style pid-plus-LWP. - * - * Return: - * pointer to the corresponding LDT entry. - */ - -struct ssd * -procfs_find_LDT_entry (ptid_t ptid) -{ - gdb_gregset_t *gregs; - int key; - procinfo *pi; - - /* Find procinfo for the lwp. */ - if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL) - { - warning ("procfs_find_LDT_entry: could not find procinfo for %d:%d.", - PIDGET (ptid), TIDGET (ptid)); - return NULL; - } - /* get its general registers. */ - if ((gregs = proc_get_gregs (pi)) == NULL) - { - warning ("procfs_find_LDT_entry: could not read gregs for %d:%d.", - PIDGET (ptid), TIDGET (ptid)); - return NULL; - } - /* Now extract the GS register's lower 16 bits. */ - key = (*gregs)[GS] & 0xffff; - - /* Find the matching entry and return it. */ - return proc_get_LDT_entry (pi, key); -} -#endif /* TM_I386SOL2_H */ - -/* - * Memory Mappings Functions: - */ - -/* - * Function: iterate_over_mappings - * - * Call a callback function once for each mapping, passing it the mapping, - * an optional secondary callback function, and some optional opaque data. - * Quit and return the first non-zero value returned from the callback. - * - * Arguments: - * pi -- procinfo struct for the process to be mapped. - * func -- callback function to be called by this iterator. - * data -- optional opaque data to be passed to the callback function. - * child_func -- optional secondary function pointer to be passed - * to the child function. - * - * Return: First non-zero return value from the callback function, - * or zero. - */ - -static int -iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data, - int (*func) (struct prmap *map, - int (*child_func) (), - void *data)) -{ - char pathname[MAX_PROC_NAME_SIZE]; - struct prmap *prmaps; - struct prmap *prmap; - int funcstat; - int map_fd; - int nmap; -#ifdef NEW_PROC_API - struct stat sbuf; -#endif - - /* Get the number of mappings, allocate space, - and read the mappings into prmaps. */ -#ifdef NEW_PROC_API - /* Open map fd. */ - sprintf (pathname, "/proc/%d/map", pi->pid); - if ((map_fd = open (pathname, O_RDONLY)) < 0) - proc_error (pi, "iterate_over_mappings (open)", __LINE__); - - /* Make sure it gets closed again. */ - make_cleanup_close (map_fd); - - /* Use stat to determine the file size, and compute - the number of prmap_t objects it contains. */ - if (fstat (map_fd, &sbuf) != 0) - proc_error (pi, "iterate_over_mappings (fstat)", __LINE__); - - nmap = sbuf.st_size / sizeof (prmap_t); - prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps)); - if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps)) - != (nmap * sizeof (*prmaps))) - proc_error (pi, "iterate_over_mappings (read)", __LINE__); -#else - /* Use ioctl command PIOCNMAP to get number of mappings. */ - if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0) - proc_error (pi, "iterate_over_mappings (PIOCNMAP)", __LINE__); - - prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps)); - if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0) - proc_error (pi, "iterate_over_mappings (PIOCMAP)", __LINE__); -#endif - - for (prmap = prmaps; nmap > 0; prmap++, nmap--) - if ((funcstat = (*func) (prmap, child_func, data)) != 0) - return funcstat; - - return 0; -} - -/* - * Function: solib_mappings_callback - * - * Calls the supplied callback function once for each mapped address - * space in the process. The callback function receives an open - * file descriptor for the file corresponding to that mapped - * address space (if there is one), and the base address of the - * mapped space. Quit when the callback function returns a - * nonzero value, or at teh end of the mappings. - * - * Returns: the first non-zero return value of the callback function, - * or zero. - */ - -int solib_mappings_callback (struct prmap *map, - int (*func) (int, CORE_ADDR), - void *data) -{ - procinfo *pi = data; - int fd; - -#ifdef NEW_PROC_API - char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)]; - - if (map->pr_vaddr == 0 && map->pr_size == 0) - return -1; /* sanity */ - - if (map->pr_mapname[0] == 0) - { - fd = -1; /* no map file */ - } - else - { - sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname); - /* Note: caller's responsibility to close this fd! */ - fd = open_with_retry (name, O_RDONLY); - /* Note: we don't test the above call for failure; - we just pass the FD on as given. Sometimes there is - no file, so the open may return failure, but that's - not a problem. */ - } -#else - fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr); - /* Note: we don't test the above call for failure; - we just pass the FD on as given. Sometimes there is - no file, so the ioctl may return failure, but that's - not a problem. */ -#endif - return (*func) (fd, (CORE_ADDR) map->pr_vaddr); -} - -/* - * Function: proc_iterate_over_mappings - * - * Uses the unified "iterate_over_mappings" function - * to implement the exported interface to solib-svr4.c. - * - * Given a pointer to a function, call that function once for every - * mapped address space in the process. The callback function - * receives an open file descriptor for the file corresponding to - * that mapped address space (if there is one), and the base address - * of the mapped space. Quit when the callback function returns a - * nonzero value, or at teh end of the mappings. - * - * Returns: the first non-zero return value of the callback function, - * or zero. - */ - -int -proc_iterate_over_mappings (int (*func) (int, CORE_ADDR)) -{ - procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - - return iterate_over_mappings (pi, func, pi, solib_mappings_callback); -} - -/* - * Function: find_memory_regions_callback - * - * Implements the to_find_memory_regions method. - * Calls an external function for each memory region. - * External function will have the signiture: - * - * int callback (CORE_ADDR vaddr, - * unsigned long size, - * int read, int write, int execute, - * void *data); - * - * Returns the integer value returned by the callback. - */ - -static int -find_memory_regions_callback (struct prmap *map, - int (*func) (CORE_ADDR, - unsigned long, - int, int, int, - void *), - void *data) -{ - return (*func) ((CORE_ADDR) map->pr_vaddr, - map->pr_size, - (map->pr_mflags & MA_READ) != 0, - (map->pr_mflags & MA_WRITE) != 0, - (map->pr_mflags & MA_EXEC) != 0, - data); -} - -/* - * Function: proc_find_memory_regions - * - * External interface. Calls a callback function once for each - * mapped memory region in the child process, passing as arguments - * CORE_ADDR virtual_address, - * unsigned long size, - * int read, TRUE if region is readable by the child - * int write, TRUE if region is writable by the child - * int execute TRUE if region is executable by the child. - * - * Stops iterating and returns the first non-zero value - * returned by the callback. - */ - -static int -proc_find_memory_regions (int (*func) (CORE_ADDR, - unsigned long, - int, int, int, - void *), - void *data) -{ - procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - - return iterate_over_mappings (pi, func, data, - find_memory_regions_callback); -} - -/* - * Function: mappingflags - * - * Returns an ascii representation of a memory mapping's flags. - */ - -static char * -mappingflags (flags) - long flags; -{ - static char asciiflags[8]; - - strcpy (asciiflags, "-------"); -#if defined (MA_PHYS) - if (flags & MA_PHYS) - asciiflags[0] = 'd'; -#endif - if (flags & MA_STACK) - asciiflags[1] = 's'; - if (flags & MA_BREAK) - asciiflags[2] = 'b'; - if (flags & MA_SHARED) - asciiflags[3] = 's'; - if (flags & MA_READ) - asciiflags[4] = 'r'; - if (flags & MA_WRITE) - asciiflags[5] = 'w'; - if (flags & MA_EXEC) - asciiflags[6] = 'x'; - return (asciiflags); -} - -/* - * Function: info_mappings_callback - * - * Callback function, does the actual work for 'info proc mappings'. - */ - -/* ARGSUSED */ -static int -info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused) -{ - char *data_fmt_string; - - if (TARGET_ADDR_BIT == 32) - data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n"; - else - data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n"; - - printf_filtered (data_fmt_string, - (unsigned long) map->pr_vaddr, - (unsigned long) map->pr_vaddr + map->pr_size - 1, - map->pr_size, -#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */ - (unsigned int) map->pr_offset, -#else - map->pr_off, -#endif - mappingflags (map->pr_mflags)); - - return 0; -} - -/* - * Function: info_proc_mappings - * - * Implement the "info proc mappings" subcommand. - */ - -static void -info_proc_mappings (procinfo *pi, int summary) -{ - char *header_fmt_string; - - if (TARGET_PTR_BIT == 32) - header_fmt_string = "\t%10s %10s %10s %10s %7s\n"; - else - header_fmt_string = " %18s %18s %10s %10s %7s\n"; - - if (summary) - return; /* No output for summary mode. */ - - printf_filtered ("Mapped address spaces:\n\n"); - printf_filtered (header_fmt_string, - "Start Addr", - " End Addr", - " Size", - " Offset", - "Flags"); - - iterate_over_mappings (pi, NULL, NULL, info_mappings_callback); - printf_filtered ("\n"); -} - -/* - * Function: info_proc_cmd - * - * Implement the "info proc" command. - */ - -static void -info_proc_cmd (char *args, int from_tty) -{ - struct cleanup *old_chain; - procinfo *process = NULL; - procinfo *thread = NULL; - char **argv = NULL; - char *tmp = NULL; - int pid = 0; - int tid = 0; - int mappings = 0; - - old_chain = make_cleanup (null_cleanup, 0); - if (args) - { - if ((argv = buildargv (args)) == NULL) - nomem (0); - else - make_cleanup_freeargv (argv); - } - while (argv != NULL && *argv != NULL) - { - if (isdigit (argv[0][0])) - { - pid = strtoul (argv[0], &tmp, 10); - if (*tmp == '/') - tid = strtoul (++tmp, NULL, 10); - } - else if (argv[0][0] == '/') - { - tid = strtoul (argv[0] + 1, NULL, 10); - } - else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0) - { - mappings = 1; - } - else - { - /* [...] */ - } - argv++; - } - if (pid == 0) - pid = PIDGET (inferior_ptid); - if (pid == 0) - error ("No current process: you must name one."); - else - { - /* Have pid, will travel. - First see if it's a process we're already debugging. */ - process = find_procinfo (pid, 0); - if (process == NULL) - { - /* No. So open a procinfo for it, but - remember to close it again when finished. */ - process = create_procinfo (pid, 0); - make_cleanup (do_destroy_procinfo_cleanup, process); - if (!open_procinfo_files (process, FD_CTL)) - proc_error (process, "info proc, open_procinfo_files", __LINE__); - } - } - if (tid != 0) - thread = create_procinfo (pid, tid); - - if (process) - { - printf_filtered ("process %d flags:\n", process->pid); - proc_prettyprint_flags (proc_flags (process), 1); - if (proc_flags (process) & (PR_STOPPED | PR_ISTOP)) - proc_prettyprint_why (proc_why (process), proc_what (process), 1); - if (proc_get_nthreads (process) > 1) - printf_filtered ("Process has %d threads.\n", - proc_get_nthreads (process)); - } - if (thread) - { - printf_filtered ("thread %d flags:\n", thread->tid); - proc_prettyprint_flags (proc_flags (thread), 1); - if (proc_flags (thread) & (PR_STOPPED | PR_ISTOP)) - proc_prettyprint_why (proc_why (thread), proc_what (thread), 1); - } - - if (mappings) - { - info_proc_mappings (process, 0); - } - - do_cleanups (old_chain); -} - -static void -proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode) -{ - procinfo *pi; - sysset_t *sysset; - int syscallnum = 0; - - if (PIDGET (inferior_ptid) <= 0) - error ("you must be debugging a process to use this command."); - - if (args == NULL || args[0] == 0) - error_no_arg ("system call to trace"); - - pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - if (isdigit (args[0])) - { - syscallnum = atoi (args); - if (entry_or_exit == PR_SYSENTRY) - sysset = proc_get_traced_sysentry (pi, NULL); - else - sysset = proc_get_traced_sysexit (pi, NULL); - - if (sysset == NULL) - proc_error (pi, "proc-trace, get_traced_sysset", __LINE__); - - if (mode == FLAG_SET) - gdb_praddsysset (sysset, syscallnum); - else - gdb_prdelsysset (sysset, syscallnum); - - if (entry_or_exit == PR_SYSENTRY) - { - if (!proc_set_traced_sysentry (pi, sysset)) - proc_error (pi, "proc-trace, set_traced_sysentry", __LINE__); - } - else - { - if (!proc_set_traced_sysexit (pi, sysset)) - proc_error (pi, "proc-trace, set_traced_sysexit", __LINE__); - } - } -} - -static void -proc_trace_sysentry_cmd (char *args, int from_tty) -{ - proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET); -} - -static void -proc_trace_sysexit_cmd (char *args, int from_tty) -{ - proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET); -} - -static void -proc_untrace_sysentry_cmd (char *args, int from_tty) -{ - proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET); -} - -static void -proc_untrace_sysexit_cmd (char *args, int from_tty) -{ - proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET); -} - - -void -_initialize_procfs (void) -{ - init_procfs_ops (); - add_target (&procfs_ops); - add_info ("proc", info_proc_cmd, - "Show /proc process information about any running process.\n\ -Specify process id, or use the program being debugged by default.\n\ -Specify keyword 'mappings' for detailed info on memory mappings."); - add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd, - "Give a trace of entries into the syscall."); - add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd, - "Give a trace of exits from the syscall."); - add_com ("proc-untrace-entry", no_class, proc_untrace_sysentry_cmd, - "Cancel a trace of entries into the syscall."); - add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd, - "Cancel a trace of exits from the syscall."); -} - -/* =================== END, GDB "MODULE" =================== */ - - - -/* miscellaneous stubs: */ -/* The following satisfy a few random symbols mostly created by */ -/* the solaris threads implementation, which I will chase down */ -/* later. */ - -/* - * Return a pid for which we guarantee - * we will be able to find a 'live' procinfo. - */ - -ptid_t -procfs_first_available (void) -{ - return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1); -} - -/* =================== GCORE .NOTE "MODULE" =================== */ -#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT) -/* gcore only implemented on solaris and unixware (so far) */ - -static char * -procfs_do_thread_registers (bfd *obfd, ptid_t ptid, - char *note_data, int *note_size) -{ - gdb_gregset_t gregs; - gdb_fpregset_t fpregs; - unsigned long merged_pid; - - merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid); - - fill_gregset (&gregs, -1); -#if defined (UNIXWARE) - note_data = (char *) elfcore_write_lwpstatus (obfd, - note_data, - note_size, - merged_pid, - stop_signal, - &gregs); -#else - note_data = (char *) elfcore_write_prstatus (obfd, - note_data, - note_size, - merged_pid, - stop_signal, - &gregs); -#endif - fill_fpregset (&fpregs, -1); - note_data = (char *) elfcore_write_prfpreg (obfd, - note_data, - note_size, - &fpregs, - sizeof (fpregs)); - return note_data; -} - -struct procfs_corefile_thread_data { - bfd *obfd; - char *note_data; - int *note_size; -}; - -static int -procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data) -{ - struct procfs_corefile_thread_data *args = data; - - if (pi != NULL && thread->tid != 0) - { - ptid_t saved_ptid = inferior_ptid; - inferior_ptid = MERGEPID (pi->pid, thread->tid); - args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid, - args->note_data, - args->note_size); - inferior_ptid = saved_ptid; - } - return 0; -} - -static char * -procfs_make_note_section (bfd *obfd, int *note_size) -{ - struct cleanup *old_chain; - gdb_gregset_t gregs; - gdb_fpregset_t fpregs; - char fname[16] = {'\0'}; - char psargs[80] = {'\0'}; - procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); - char *note_data = NULL; - char *inf_args; - struct procfs_corefile_thread_data thread_args; - - if (get_exec_file (0)) - { - strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname)); - strncpy (psargs, get_exec_file (0), - sizeof (psargs)); - - inf_args = get_inferior_args (); - if (inf_args && *inf_args && - strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs))) - { - strncat (psargs, " ", - sizeof (psargs) - strlen (psargs)); - strncat (psargs, inf_args, - sizeof (psargs) - strlen (psargs)); - } - } - - note_data = (char *) elfcore_write_prpsinfo (obfd, - note_data, - note_size, - fname, - psargs); - -#ifdef UNIXWARE - fill_gregset (&gregs, -1); - note_data = elfcore_write_pstatus (obfd, note_data, note_size, - PIDGET (inferior_ptid), - stop_signal, &gregs); -#endif - - thread_args.obfd = obfd; - thread_args.note_data = note_data; - thread_args.note_size = note_size; - proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args); - - if (thread_args.note_data == note_data) - { - /* iterate_over_threads didn't come up with any threads; - just use inferior_ptid. */ - note_data = procfs_do_thread_registers (obfd, inferior_ptid, - note_data, note_size); - } - else - { - note_data = thread_args.note_data; - } - - make_cleanup (xfree, note_data); - return note_data; -} -#else /* !(Solaris or Unixware) */ -static char * -procfs_make_note_section (bfd *obfd, int *note_size) -{ - error ("gcore not implemented for this host."); - return NULL; /* lint */ -} -#endif /* Solaris or Unixware */ -/* =================== END GCORE .NOTE "MODULE" =================== */ diff --git a/contrib/gdb/gdb/remote-mips.c b/contrib/gdb/gdb/remote-mips.c deleted file mode 100644 index 385b69a4252..00000000000 --- a/contrib/gdb/gdb/remote-mips.c +++ /dev/null @@ -1,3599 +0,0 @@ -/* Remote debugging interface for MIPS remote debugging protocol. - - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation, Inc. - - Contributed by Cygnus Support. Written by Ian Lance Taylor - . - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "bfd.h" -#include "symfile.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "serial.h" -#include "target.h" -#include "remote-utils.h" -#include "gdb_string.h" -#include "gdb_stat.h" -#include "regcache.h" -#include - - -/* Breakpoint types. Values 0, 1, and 2 must agree with the watch - types passed by breakpoint.c to target_insert_watchpoint. - Value 3 is our own invention, and is used for ordinary instruction - breakpoints. Value 4 is used to mark an unused watchpoint in tables. */ -enum break_type - { - BREAK_WRITE, /* 0 */ - BREAK_READ, /* 1 */ - BREAK_ACCESS, /* 2 */ - BREAK_FETCH, /* 3 */ - BREAK_UNUSED /* 4 */ - }; - -/* Prototypes for local functions. */ - -static int mips_readchar (int timeout); - -static int mips_receive_header (unsigned char *hdr, int *pgarbage, - int ch, int timeout); - -static int mips_receive_trailer (unsigned char *trlr, int *pgarbage, - int *pch, int timeout); - -static int mips_cksum (const unsigned char *hdr, - const unsigned char *data, int len); - -static void mips_send_packet (const char *s, int get_ack); - -static void mips_send_command (const char *cmd, int prompt); - -static int mips_receive_packet (char *buff, int throw_error, int timeout); - -static ULONGEST mips_request (int cmd, ULONGEST addr, ULONGEST data, - int *perr, int timeout, char *buff); - -static void mips_initialize (void); - -static void mips_open (char *name, int from_tty); - -static void pmon_open (char *name, int from_tty); - -static void ddb_open (char *name, int from_tty); - -static void lsi_open (char *name, int from_tty); - -static void mips_close (int quitting); - -static void mips_detach (char *args, int from_tty); - -static void mips_resume (ptid_t ptid, int step, - enum target_signal siggnal); - -static ptid_t mips_wait (ptid_t ptid, - struct target_waitstatus *status); - -static int mips_map_regno (int regno); - -static void mips_fetch_registers (int regno); - -static void mips_prepare_to_store (void); - -static void mips_store_registers (int regno); - -static unsigned int mips_fetch_word (CORE_ADDR addr); - -static int mips_store_word (CORE_ADDR addr, unsigned int value, - char *old_contents); - -static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, - struct mem_attrib *attrib, - struct target_ops *target); - -static void mips_files_info (struct target_ops *ignore); - -static void mips_create_inferior (char *execfile, char *args, char **env); - -static void mips_mourn_inferior (void); - -static int pmon_makeb64 (unsigned long v, char *p, int n, int *chksum); - -static int pmon_zeroset (int recsize, char **buff, int *amount, - unsigned int *chksum); - -static int pmon_checkset (int recsize, char **buff, int *value); - -static void pmon_make_fastrec (char **outbuf, unsigned char *inbuf, - int *inptr, int inamount, int *recsize, - unsigned int *csum, unsigned int *zerofill); - -static int pmon_check_ack (char *mesg); - -static void pmon_start_download (void); - -static void pmon_end_download (int final, int bintotal); - -static void pmon_download (char *buffer, int length); - -static void pmon_load_fast (char *file); - -static void mips_load (char *file, int from_tty); - -static int mips_make_srec (char *buffer, int type, CORE_ADDR memaddr, - unsigned char *myaddr, int len); - -static int set_breakpoint (CORE_ADDR addr, int len, enum break_type type); - -static int clear_breakpoint (CORE_ADDR addr, int len, enum break_type type); - -static int common_breakpoint (int set, CORE_ADDR addr, int len, - enum break_type type); - -/* Forward declarations. */ -extern struct target_ops mips_ops; -extern struct target_ops pmon_ops; -extern struct target_ops ddb_ops; - /* *INDENT-OFF* */ -/* The MIPS remote debugging interface is built on top of a simple - packet protocol. Each packet is organized as follows: - - SYN The first character is always a SYN (ASCII 026, or ^V). SYN - may not appear anywhere else in the packet. Any time a SYN is - seen, a new packet should be assumed to have begun. - - TYPE_LEN - This byte contains the upper five bits of the logical length - of the data section, plus a single bit indicating whether this - is a data packet or an acknowledgement. The documentation - indicates that this bit is 1 for a data packet, but the actual - board uses 1 for an acknowledgement. The value of the byte is - 0x40 + (ack ? 0x20 : 0) + (len >> 6) - (we always have 0 <= len < 1024). Acknowledgement packets do - not carry data, and must have a data length of 0. - - LEN1 This byte contains the lower six bits of the logical length of - the data section. The value is - 0x40 + (len & 0x3f) - - SEQ This byte contains the six bit sequence number of the packet. - The value is - 0x40 + seq - An acknowlegment packet contains the sequence number of the - packet being acknowledged plus 1 modulo 64. Data packets are - transmitted in sequence. There may only be one outstanding - unacknowledged data packet at a time. The sequence numbers - are independent in each direction. If an acknowledgement for - the previous packet is received (i.e., an acknowledgement with - the sequence number of the packet just sent) the packet just - sent should be retransmitted. If no acknowledgement is - received within a timeout period, the packet should be - retransmitted. This has an unfortunate failure condition on a - high-latency line, as a delayed acknowledgement may lead to an - endless series of duplicate packets. - - DATA The actual data bytes follow. The following characters are - escaped inline with DLE (ASCII 020, or ^P): - SYN (026) DLE S - DLE (020) DLE D - ^C (003) DLE C - ^S (023) DLE s - ^Q (021) DLE q - The additional DLE characters are not counted in the logical - length stored in the TYPE_LEN and LEN1 bytes. - - CSUM1 - CSUM2 - CSUM3 - These bytes contain an 18 bit checksum of the complete - contents of the packet excluding the SEQ byte and the - CSUM[123] bytes. The checksum is simply the twos complement - addition of all the bytes treated as unsigned characters. The - values of the checksum bytes are: - CSUM1: 0x40 + ((cksum >> 12) & 0x3f) - CSUM2: 0x40 + ((cksum >> 6) & 0x3f) - CSUM3: 0x40 + (cksum & 0x3f) - - It happens that the MIPS remote debugging protocol always - communicates with ASCII strings. Because of this, this - implementation doesn't bother to handle the DLE quoting mechanism, - since it will never be required. */ -/* *INDENT-ON* */ - - -/* The SYN character which starts each packet. */ -#define SYN '\026' - -/* The 0x40 used to offset each packet (this value ensures that all of - the header and trailer bytes, other than SYN, are printable ASCII - characters). */ -#define HDR_OFFSET 0x40 - -/* The indices of the bytes in the packet header. */ -#define HDR_INDX_SYN 0 -#define HDR_INDX_TYPE_LEN 1 -#define HDR_INDX_LEN1 2 -#define HDR_INDX_SEQ 3 -#define HDR_LENGTH 4 - -/* The data/ack bit in the TYPE_LEN header byte. */ -#define TYPE_LEN_DA_BIT 0x20 -#define TYPE_LEN_DATA 0 -#define TYPE_LEN_ACK TYPE_LEN_DA_BIT - -/* How to compute the header bytes. */ -#define HDR_SET_SYN(data, len, seq) (SYN) -#define HDR_SET_TYPE_LEN(data, len, seq) \ - (HDR_OFFSET \ - + ((data) ? TYPE_LEN_DATA : TYPE_LEN_ACK) \ - + (((len) >> 6) & 0x1f)) -#define HDR_SET_LEN1(data, len, seq) (HDR_OFFSET + ((len) & 0x3f)) -#define HDR_SET_SEQ(data, len, seq) (HDR_OFFSET + (seq)) - -/* Check that a header byte is reasonable. */ -#define HDR_CHECK(ch) (((ch) & HDR_OFFSET) == HDR_OFFSET) - -/* Get data from the header. These macros evaluate their argument - multiple times. */ -#define HDR_IS_DATA(hdr) \ - (((hdr)[HDR_INDX_TYPE_LEN] & TYPE_LEN_DA_BIT) == TYPE_LEN_DATA) -#define HDR_GET_LEN(hdr) \ - ((((hdr)[HDR_INDX_TYPE_LEN] & 0x1f) << 6) + (((hdr)[HDR_INDX_LEN1] & 0x3f))) -#define HDR_GET_SEQ(hdr) ((unsigned int)(hdr)[HDR_INDX_SEQ] & 0x3f) - -/* The maximum data length. */ -#define DATA_MAXLEN 1023 - -/* The trailer offset. */ -#define TRLR_OFFSET HDR_OFFSET - -/* The indices of the bytes in the packet trailer. */ -#define TRLR_INDX_CSUM1 0 -#define TRLR_INDX_CSUM2 1 -#define TRLR_INDX_CSUM3 2 -#define TRLR_LENGTH 3 - -/* How to compute the trailer bytes. */ -#define TRLR_SET_CSUM1(cksum) (TRLR_OFFSET + (((cksum) >> 12) & 0x3f)) -#define TRLR_SET_CSUM2(cksum) (TRLR_OFFSET + (((cksum) >> 6) & 0x3f)) -#define TRLR_SET_CSUM3(cksum) (TRLR_OFFSET + (((cksum) ) & 0x3f)) - -/* Check that a trailer byte is reasonable. */ -#define TRLR_CHECK(ch) (((ch) & TRLR_OFFSET) == TRLR_OFFSET) - -/* Get data from the trailer. This evaluates its argument multiple - times. */ -#define TRLR_GET_CKSUM(trlr) \ - ((((trlr)[TRLR_INDX_CSUM1] & 0x3f) << 12) \ - + (((trlr)[TRLR_INDX_CSUM2] & 0x3f) << 6) \ - + ((trlr)[TRLR_INDX_CSUM3] & 0x3f)) - -/* The sequence number modulos. */ -#define SEQ_MODULOS (64) - -/* PMON commands to load from the serial port or UDP socket. */ -#define LOAD_CMD "load -b -s tty0\r" -#define LOAD_CMD_UDP "load -b -s udp\r" - -/* The target vectors for the four different remote MIPS targets. - These are initialized with code in _initialize_remote_mips instead - of static initializers, to make it easier to extend the target_ops - vector later. */ -struct target_ops mips_ops, pmon_ops, ddb_ops, lsi_ops; - -enum mips_monitor_type - { - /* IDT/SIM monitor being used: */ - MON_IDT, - /* PMON monitor being used: */ - MON_PMON, /* 3.0.83 [COGENT,EB,FP,NET] Algorithmics Ltd. Nov 9 1995 17:19:50 */ - MON_DDB, /* 2.7.473 [DDBVR4300,EL,FP,NET] Risq Modular Systems, Thu Jun 6 09:28:40 PDT 1996 */ - MON_LSI, /* 4.3.12 [EB,FP], LSI LOGIC Corp. Tue Feb 25 13:22:14 1997 */ - /* Last and unused value, for sizing vectors, etc. */ - MON_LAST - }; -static enum mips_monitor_type mips_monitor = MON_LAST; - -/* The monitor prompt text. If the user sets the PMON prompt - to some new value, the GDB `set monitor-prompt' command must also - be used to inform GDB about the expected prompt. Otherwise, GDB - will not be able to connect to PMON in mips_initialize(). - If the `set monitor-prompt' command is not used, the expected - default prompt will be set according the target: - target prompt - ----- ----- - pmon PMON> - ddb NEC010> - lsi PMON> - */ -static char *mips_monitor_prompt; - -/* Set to 1 if the target is open. */ -static int mips_is_open; - -/* Currently active target description (if mips_is_open == 1) */ -static struct target_ops *current_ops; - -/* Set to 1 while the connection is being initialized. */ -static int mips_initializing; - -/* Set to 1 while the connection is being brought down. */ -static int mips_exiting; - -/* The next sequence number to send. */ -static unsigned int mips_send_seq; - -/* The next sequence number we expect to receive. */ -static unsigned int mips_receive_seq; - -/* The time to wait before retransmitting a packet, in seconds. */ -static int mips_retransmit_wait = 3; - -/* The number of times to try retransmitting a packet before giving up. */ -static int mips_send_retries = 10; - -/* The number of garbage characters to accept when looking for an - SYN for the next packet. */ -static int mips_syn_garbage = 10; - -/* The time to wait for a packet, in seconds. */ -static int mips_receive_wait = 5; - -/* Set if we have sent a packet to the board but have not yet received - a reply. */ -static int mips_need_reply = 0; - -/* Handle used to access serial I/O stream. */ -static struct serial *mips_desc; - -/* UDP handle used to download files to target. */ -static struct serial *udp_desc; -static int udp_in_use; - -/* TFTP filename used to download files to DDB board, in the form - host:filename. */ -static char *tftp_name; /* host:filename */ -static char *tftp_localname; /* filename portion of above */ -static int tftp_in_use; -static FILE *tftp_file; - -/* Counts the number of times the user tried to interrupt the target (usually - via ^C. */ -static int interrupt_count; - -/* If non-zero, means that the target is running. */ -static int mips_wait_flag = 0; - -/* If non-zero, monitor supports breakpoint commands. */ -static int monitor_supports_breakpoints = 0; - -/* Data cache header. */ - -#if 0 /* not used (yet?) */ -static DCACHE *mips_dcache; -#endif - -/* Non-zero means that we've just hit a read or write watchpoint */ -static int hit_watchpoint; - -/* Table of breakpoints/watchpoints (used only on LSI PMON target). - The table is indexed by a breakpoint number, which is an integer - from 0 to 255 returned by the LSI PMON when a breakpoint is set. - */ -#define MAX_LSI_BREAKPOINTS 256 -struct lsi_breakpoint_info - { - enum break_type type; /* type of breakpoint */ - CORE_ADDR addr; /* address of breakpoint */ - int len; /* length of region being watched */ - unsigned long value; /* value to watch */ - } -lsi_breakpoints[MAX_LSI_BREAKPOINTS]; - -/* Error/warning codes returned by LSI PMON for breakpoint commands. - Warning values may be ORed together; error values may not. */ -#define W_WARN 0x100 /* This bit is set if the error code is a warning */ -#define W_MSK 0x101 /* warning: Range feature is supported via mask */ -#define W_VAL 0x102 /* warning: Value check is not supported in hardware */ -#define W_QAL 0x104 /* warning: Requested qualifiers are not supported in hardware */ - -#define E_ERR 0x200 /* This bit is set if the error code is an error */ -#define E_BPT 0x200 /* error: No such breakpoint number */ -#define E_RGE 0x201 /* error: Range is not supported */ -#define E_QAL 0x202 /* error: The requested qualifiers can not be used */ -#define E_OUT 0x203 /* error: Out of hardware resources */ -#define E_NON 0x204 /* error: Hardware breakpoint not supported */ - -struct lsi_error - { - int code; /* error code */ - char *string; /* string associated with this code */ - }; - -struct lsi_error lsi_warning_table[] = -{ - {W_MSK, "Range feature is supported via mask"}, - {W_VAL, "Value check is not supported in hardware"}, - {W_QAL, "Requested qualifiers are not supported in hardware"}, - {0, NULL} -}; - -struct lsi_error lsi_error_table[] = -{ - {E_BPT, "No such breakpoint number"}, - {E_RGE, "Range is not supported"}, - {E_QAL, "The requested qualifiers can not be used"}, - {E_OUT, "Out of hardware resources"}, - {E_NON, "Hardware breakpoint not supported"}, - {0, NULL} -}; - -/* Set to 1 with the 'set monitor-warnings' command to enable printing - of warnings returned by PMON when hardware breakpoints are used. */ -static int monitor_warnings; - - -static void -close_ports (void) -{ - mips_is_open = 0; - serial_close (mips_desc); - - if (udp_in_use) - { - serial_close (udp_desc); - udp_in_use = 0; - } - tftp_in_use = 0; -} - -/* Handle low-level error that we can't recover from. Note that just - error()ing out from target_wait or some such low-level place will cause - all hell to break loose--the rest of GDB will tend to get left in an - inconsistent state. */ - -static NORETURN void -mips_error (char *string,...) -{ - va_list args; - - va_start (args, string); - - target_terminal_ours (); - wrap_here (""); /* Force out any buffered output */ - gdb_flush (gdb_stdout); - if (error_pre_print) - fprintf_filtered (gdb_stderr, error_pre_print); - vfprintf_filtered (gdb_stderr, string, args); - fprintf_filtered (gdb_stderr, "\n"); - va_end (args); - gdb_flush (gdb_stderr); - - /* Clean up in such a way that mips_close won't try to talk to the - board (it almost surely won't work since we weren't able to talk to - it). */ - close_ports (); - - printf_unfiltered ("Ending remote MIPS debugging.\n"); - target_mourn_inferior (); - - throw_exception (RETURN_ERROR); -} - -/* putc_readable - print a character, displaying non-printable chars in - ^x notation or in hex. */ - -static void -fputc_readable (int ch, struct ui_file *file) -{ - if (ch == '\n') - fputc_unfiltered ('\n', file); - else if (ch == '\r') - fprintf_unfiltered (file, "\\r"); - else if (ch < 0x20) /* ASCII control character */ - fprintf_unfiltered (file, "^%c", ch + '@'); - else if (ch >= 0x7f) /* non-ASCII characters (rubout or greater) */ - fprintf_unfiltered (file, "[%02x]", ch & 0xff); - else - fputc_unfiltered (ch, file); -} - - -/* puts_readable - print a string, displaying non-printable chars in - ^x notation or in hex. */ - -static void -fputs_readable (const char *string, struct ui_file *file) -{ - int c; - - while ((c = *string++) != '\0') - fputc_readable (c, file); -} - - -/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if - timed out. TIMEOUT specifies timeout value in seconds. - */ - -int -mips_expect_timeout (const char *string, int timeout) -{ - const char *p = string; - - if (remote_debug) - { - fprintf_unfiltered (gdb_stdlog, "Expected \""); - fputs_readable (string, gdb_stdlog); - fprintf_unfiltered (gdb_stdlog, "\", got \""); - } - - immediate_quit++; - while (1) - { - int c; - - /* Must use serial_readchar() here cuz mips_readchar would get - confused if we were waiting for the mips_monitor_prompt... */ - - c = serial_readchar (mips_desc, timeout); - - if (c == SERIAL_TIMEOUT) - { - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "\": FAIL\n"); - return 0; - } - - if (remote_debug) - fputc_readable (c, gdb_stdlog); - - if (c == *p++) - { - if (*p == '\0') - { - immediate_quit--; - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "\": OK\n"); - return 1; - } - } - else - { - p = string; - if (c == *p) - p++; - } - } -} - -/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if - timed out. The timeout value is hard-coded to 2 seconds. Use - mips_expect_timeout if a different timeout value is needed. - */ - -int -mips_expect (const char *string) -{ - return mips_expect_timeout (string, remote_timeout); -} - -/* Read the required number of characters into the given buffer (which - is assumed to be large enough). The only failure is a timeout. */ -int -mips_getstring (char *string, int n) -{ - char *p = string; - int c; - - immediate_quit++; - while (n > 0) - { - c = serial_readchar (mips_desc, remote_timeout); - - if (c == SERIAL_TIMEOUT) - { - fprintf_unfiltered (gdb_stderr, - "Failed to read %d characters from target (TIMEOUT)\n", n); - immediate_quit--; - return 0; - } - - *p++ = c; - n--; - } - - immediate_quit--; - return 1; -} - -/* Read a character from the remote, aborting on error. Returns - SERIAL_TIMEOUT on timeout (since that's what serial_readchar() - returns). FIXME: If we see the string mips_monitor_prompt from the - board, then we are debugging on the main console port, and we have - somehow dropped out of remote debugging mode. In this case, we - automatically go back in to remote debugging mode. This is a hack, - put in because I can't find any way for a program running on the - remote board to terminate without also ending remote debugging - mode. I assume users won't have any trouble with this; for one - thing, the IDT documentation generally assumes that the remote - debugging port is not the console port. This is, however, very - convenient for DejaGnu when you only have one connected serial - port. */ - -static int -mips_readchar (int timeout) -{ - int ch; - static int state = 0; - int mips_monitor_prompt_len = strlen (mips_monitor_prompt); - - { - int i; - - i = timeout; - if (i == -1 && watchdog > 0) - i = watchdog; - } - - if (state == mips_monitor_prompt_len) - timeout = 1; - ch = serial_readchar (mips_desc, timeout); - - if (ch == SERIAL_TIMEOUT && timeout == -1) /* Watchdog went off */ - { - target_mourn_inferior (); - error ("Watchdog has expired. Target detached.\n"); - } - - if (ch == SERIAL_EOF) - mips_error ("End of file from remote"); - if (ch == SERIAL_ERROR) - mips_error ("Error reading from remote: %s", safe_strerror (errno)); - if (remote_debug > 1) - { - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - if (ch != SERIAL_TIMEOUT) - fprintf_unfiltered (gdb_stdlog, "Read '%c' %d 0x%x\n", ch, ch, ch); - else - fprintf_unfiltered (gdb_stdlog, "Timed out in read\n"); - } - - /* If we have seen mips_monitor_prompt and we either time out, or - we see a @ (which was echoed from a packet we sent), reset the - board as described above. The first character in a packet after - the SYN (which is not echoed) is always an @ unless the packet is - more than 64 characters long, which ours never are. */ - if ((ch == SERIAL_TIMEOUT || ch == '@') - && state == mips_monitor_prompt_len - && !mips_initializing - && !mips_exiting) - { - if (remote_debug > 0) - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - fprintf_unfiltered (gdb_stdlog, "Reinitializing MIPS debugging mode\n"); - - mips_need_reply = 0; - mips_initialize (); - - state = 0; - - /* At this point, about the only thing we can do is abort the command - in progress and get back to command level as quickly as possible. */ - - error ("Remote board reset, debug protocol re-initialized."); - } - - if (ch == mips_monitor_prompt[state]) - ++state; - else - state = 0; - - return ch; -} - -/* Get a packet header, putting the data in the supplied buffer. - PGARBAGE is a pointer to the number of garbage characters received - so far. CH is the last character received. Returns 0 for success, - or -1 for timeout. */ - -static int -mips_receive_header (unsigned char *hdr, int *pgarbage, int ch, int timeout) -{ - int i; - - while (1) - { - /* Wait for a SYN. mips_syn_garbage is intended to prevent - sitting here indefinitely if the board sends us one garbage - character per second. ch may already have a value from the - last time through the loop. */ - while (ch != SYN) - { - ch = mips_readchar (timeout); - if (ch == SERIAL_TIMEOUT) - return -1; - if (ch != SYN) - { - /* Printing the character here lets the user of gdb see - what the program is outputting, if the debugging is - being done on the console port. Don't use _filtered: - we can't deal with a QUIT out of target_wait and - buffered target output confuses the user. */ - if (!mips_initializing || remote_debug > 0) - { - if (isprint (ch) || isspace (ch)) - { - fputc_unfiltered (ch, gdb_stdtarg); - } - else - { - fputc_readable (ch, gdb_stdtarg); - } - gdb_flush (gdb_stdtarg); - } - - /* Only count unprintable characters. */ - if (! (isprint (ch) || isspace (ch))) - (*pgarbage) += 1; - - if (mips_syn_garbage > 0 - && *pgarbage > mips_syn_garbage) - mips_error ("Debug protocol failure: more than %d characters before a sync.", - mips_syn_garbage); - } - } - - /* Get the packet header following the SYN. */ - for (i = 1; i < HDR_LENGTH; i++) - { - ch = mips_readchar (timeout); - if (ch == SERIAL_TIMEOUT) - return -1; - /* Make sure this is a header byte. */ - if (ch == SYN || !HDR_CHECK (ch)) - break; - - hdr[i] = ch; - } - - /* If we got the complete header, we can return. Otherwise we - loop around and keep looking for SYN. */ - if (i >= HDR_LENGTH) - return 0; - } -} - -/* Get a packet header, putting the data in the supplied buffer. - PGARBAGE is a pointer to the number of garbage characters received - so far. The last character read is returned in *PCH. Returns 0 - for success, -1 for timeout, -2 for error. */ - -static int -mips_receive_trailer (unsigned char *trlr, int *pgarbage, int *pch, int timeout) -{ - int i; - int ch; - - for (i = 0; i < TRLR_LENGTH; i++) - { - ch = mips_readchar (timeout); - *pch = ch; - if (ch == SERIAL_TIMEOUT) - return -1; - if (!TRLR_CHECK (ch)) - return -2; - trlr[i] = ch; - } - return 0; -} - -/* Get the checksum of a packet. HDR points to the packet header. - DATA points to the packet data. LEN is the length of DATA. */ - -static int -mips_cksum (const unsigned char *hdr, const unsigned char *data, int len) -{ - register const unsigned char *p; - register int c; - register int cksum; - - cksum = 0; - - /* The initial SYN is not included in the checksum. */ - c = HDR_LENGTH - 1; - p = hdr + 1; - while (c-- != 0) - cksum += *p++; - - c = len; - p = data; - while (c-- != 0) - cksum += *p++; - - return cksum; -} - -/* Send a packet containing the given ASCII string. */ - -static void -mips_send_packet (const char *s, int get_ack) -{ - /* unsigned */ int len; - unsigned char *packet; - register int cksum; - int try; - - len = strlen (s); - if (len > DATA_MAXLEN) - mips_error ("MIPS protocol data packet too long: %s", s); - - packet = (unsigned char *) alloca (HDR_LENGTH + len + TRLR_LENGTH + 1); - - packet[HDR_INDX_SYN] = HDR_SET_SYN (1, len, mips_send_seq); - packet[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (1, len, mips_send_seq); - packet[HDR_INDX_LEN1] = HDR_SET_LEN1 (1, len, mips_send_seq); - packet[HDR_INDX_SEQ] = HDR_SET_SEQ (1, len, mips_send_seq); - - memcpy (packet + HDR_LENGTH, s, len); - - cksum = mips_cksum (packet, packet + HDR_LENGTH, len); - packet[HDR_LENGTH + len + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum); - packet[HDR_LENGTH + len + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum); - packet[HDR_LENGTH + len + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum); - - /* Increment the sequence number. This will set mips_send_seq to - the sequence number we expect in the acknowledgement. */ - mips_send_seq = (mips_send_seq + 1) % SEQ_MODULOS; - - /* We can only have one outstanding data packet, so we just wait for - the acknowledgement here. Keep retransmitting the packet until - we get one, or until we've tried too many times. */ - for (try = 0; try < mips_send_retries; try++) - { - int garbage; - int ch; - - if (remote_debug > 0) - { - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - packet[HDR_LENGTH + len + TRLR_LENGTH] = '\0'; - fprintf_unfiltered (gdb_stdlog, "Writing \"%s\"\n", packet + 1); - } - - if (serial_write (mips_desc, packet, - HDR_LENGTH + len + TRLR_LENGTH) != 0) - mips_error ("write to target failed: %s", safe_strerror (errno)); - - if (!get_ack) - return; - - garbage = 0; - ch = 0; - while (1) - { - unsigned char hdr[HDR_LENGTH + 1]; - unsigned char trlr[TRLR_LENGTH + 1]; - int err; - unsigned int seq; - - /* Get the packet header. If we time out, resend the data - packet. */ - err = mips_receive_header (hdr, &garbage, ch, mips_retransmit_wait); - if (err != 0) - break; - - ch = 0; - - /* If we get a data packet, assume it is a duplicate and - ignore it. FIXME: If the acknowledgement is lost, this - data packet may be the packet the remote sends after the - acknowledgement. */ - if (HDR_IS_DATA (hdr)) - { - int i; - - /* Ignore any errors raised whilst attempting to ignore - packet. */ - - len = HDR_GET_LEN (hdr); - - for (i = 0; i < len; i++) - { - int rch; - - rch = mips_readchar (remote_timeout); - if (rch == SYN) - { - ch = SYN; - break; - } - if (rch == SERIAL_TIMEOUT) - break; - /* ignore the character */ - } - - if (i == len) - (void) mips_receive_trailer (trlr, &garbage, &ch, - remote_timeout); - - /* We don't bother checking the checksum, or providing an - ACK to the packet. */ - continue; - } - - /* If the length is not 0, this is a garbled packet. */ - if (HDR_GET_LEN (hdr) != 0) - continue; - - /* Get the packet trailer. */ - err = mips_receive_trailer (trlr, &garbage, &ch, - mips_retransmit_wait); - - /* If we timed out, resend the data packet. */ - if (err == -1) - break; - - /* If we got a bad character, reread the header. */ - if (err != 0) - continue; - - /* If the checksum does not match the trailer checksum, this - is a bad packet; ignore it. */ - if (mips_cksum (hdr, (unsigned char *) NULL, 0) - != TRLR_GET_CKSUM (trlr)) - continue; - - if (remote_debug > 0) - { - hdr[HDR_LENGTH] = '\0'; - trlr[TRLR_LENGTH] = '\0'; - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - fprintf_unfiltered (gdb_stdlog, "Got ack %d \"%s%s\"\n", - HDR_GET_SEQ (hdr), hdr + 1, trlr); - } - - /* If this ack is for the current packet, we're done. */ - seq = HDR_GET_SEQ (hdr); - if (seq == mips_send_seq) - return; - - /* If this ack is for the last packet, resend the current - packet. */ - if ((seq + 1) % SEQ_MODULOS == mips_send_seq) - break; - - /* Otherwise this is a bad ack; ignore it. Increment the - garbage count to ensure that we do not stay in this loop - forever. */ - ++garbage; - } - } - - mips_error ("Remote did not acknowledge packet"); -} - -/* Receive and acknowledge a packet, returning the data in BUFF (which - should be DATA_MAXLEN + 1 bytes). The protocol documentation - implies that only the sender retransmits packets, so this code just - waits silently for a packet. It returns the length of the received - packet. If THROW_ERROR is nonzero, call error() on errors. If not, - don't print an error message and return -1. */ - -static int -mips_receive_packet (char *buff, int throw_error, int timeout) -{ - int ch; - int garbage; - int len; - unsigned char ack[HDR_LENGTH + TRLR_LENGTH + 1]; - int cksum; - - ch = 0; - garbage = 0; - while (1) - { - unsigned char hdr[HDR_LENGTH]; - unsigned char trlr[TRLR_LENGTH]; - int i; - int err; - - if (mips_receive_header (hdr, &garbage, ch, timeout) != 0) - { - if (throw_error) - mips_error ("Timed out waiting for remote packet"); - else - return -1; - } - - ch = 0; - - /* An acknowledgement is probably a duplicate; ignore it. */ - if (!HDR_IS_DATA (hdr)) - { - len = HDR_GET_LEN (hdr); - /* Check if the length is valid for an ACK, we may aswell - try and read the remainder of the packet: */ - if (len == 0) - { - /* Ignore the error condition, since we are going to - ignore the packet anyway. */ - (void) mips_receive_trailer (trlr, &garbage, &ch, timeout); - } - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - if (remote_debug > 0) - fprintf_unfiltered (gdb_stdlog, "Ignoring unexpected ACK\n"); - continue; - } - - len = HDR_GET_LEN (hdr); - for (i = 0; i < len; i++) - { - int rch; - - rch = mips_readchar (timeout); - if (rch == SYN) - { - ch = SYN; - break; - } - if (rch == SERIAL_TIMEOUT) - { - if (throw_error) - mips_error ("Timed out waiting for remote packet"); - else - return -1; - } - buff[i] = rch; - } - - if (i < len) - { - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - if (remote_debug > 0) - fprintf_unfiltered (gdb_stdlog, - "Got new SYN after %d chars (wanted %d)\n", - i, len); - continue; - } - - err = mips_receive_trailer (trlr, &garbage, &ch, timeout); - if (err == -1) - { - if (throw_error) - mips_error ("Timed out waiting for packet"); - else - return -1; - } - if (err == -2) - { - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - if (remote_debug > 0) - fprintf_unfiltered (gdb_stdlog, "Got SYN when wanted trailer\n"); - continue; - } - - /* If this is the wrong sequence number, ignore it. */ - if (HDR_GET_SEQ (hdr) != mips_receive_seq) - { - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - if (remote_debug > 0) - fprintf_unfiltered (gdb_stdlog, - "Ignoring sequence number %d (want %d)\n", - HDR_GET_SEQ (hdr), mips_receive_seq); - continue; - } - - if (mips_cksum (hdr, buff, len) == TRLR_GET_CKSUM (trlr)) - break; - - if (remote_debug > 0) - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - printf_unfiltered ("Bad checksum; data %d, trailer %d\n", - mips_cksum (hdr, buff, len), - TRLR_GET_CKSUM (trlr)); - - /* The checksum failed. Send an acknowledgement for the - previous packet to tell the remote to resend the packet. */ - ack[HDR_INDX_SYN] = HDR_SET_SYN (0, 0, mips_receive_seq); - ack[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (0, 0, mips_receive_seq); - ack[HDR_INDX_LEN1] = HDR_SET_LEN1 (0, 0, mips_receive_seq); - ack[HDR_INDX_SEQ] = HDR_SET_SEQ (0, 0, mips_receive_seq); - - cksum = mips_cksum (ack, (unsigned char *) NULL, 0); - - ack[HDR_LENGTH + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum); - ack[HDR_LENGTH + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum); - ack[HDR_LENGTH + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum); - - if (remote_debug > 0) - { - ack[HDR_LENGTH + TRLR_LENGTH] = '\0'; - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - printf_unfiltered ("Writing ack %d \"%s\"\n", mips_receive_seq, - ack + 1); - } - - if (serial_write (mips_desc, ack, HDR_LENGTH + TRLR_LENGTH) != 0) - { - if (throw_error) - mips_error ("write to target failed: %s", safe_strerror (errno)); - else - return -1; - } - } - - if (remote_debug > 0) - { - buff[len] = '\0'; - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - printf_unfiltered ("Got packet \"%s\"\n", buff); - } - - /* We got the packet. Send an acknowledgement. */ - mips_receive_seq = (mips_receive_seq + 1) % SEQ_MODULOS; - - ack[HDR_INDX_SYN] = HDR_SET_SYN (0, 0, mips_receive_seq); - ack[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (0, 0, mips_receive_seq); - ack[HDR_INDX_LEN1] = HDR_SET_LEN1 (0, 0, mips_receive_seq); - ack[HDR_INDX_SEQ] = HDR_SET_SEQ (0, 0, mips_receive_seq); - - cksum = mips_cksum (ack, (unsigned char *) NULL, 0); - - ack[HDR_LENGTH + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum); - ack[HDR_LENGTH + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum); - ack[HDR_LENGTH + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum); - - if (remote_debug > 0) - { - ack[HDR_LENGTH + TRLR_LENGTH] = '\0'; - /* Don't use _filtered; we can't deal with a QUIT out of - target_wait, and I think this might be called from there. */ - printf_unfiltered ("Writing ack %d \"%s\"\n", mips_receive_seq, - ack + 1); - } - - if (serial_write (mips_desc, ack, HDR_LENGTH + TRLR_LENGTH) != 0) - { - if (throw_error) - mips_error ("write to target failed: %s", safe_strerror (errno)); - else - return -1; - } - - return len; -} - -/* Optionally send a request to the remote system and optionally wait - for the reply. This implements the remote debugging protocol, - which is built on top of the packet protocol defined above. Each - request has an ADDR argument and a DATA argument. The following - requests are defined: - - \0 don't send a request; just wait for a reply - i read word from instruction space at ADDR - d read word from data space at ADDR - I write DATA to instruction space at ADDR - D write DATA to data space at ADDR - r read register number ADDR - R set register number ADDR to value DATA - c continue execution (if ADDR != 1, set pc to ADDR) - s single step (if ADDR != 1, set pc to ADDR) - - The read requests return the value requested. The write requests - return the previous value in the changed location. The execution - requests return a UNIX wait value (the approximate signal which - caused execution to stop is in the upper eight bits). - - If PERR is not NULL, this function waits for a reply. If an error - occurs, it sets *PERR to 1 and sets errno according to what the - target board reports. */ - -static ULONGEST -mips_request (int cmd, - ULONGEST addr, - ULONGEST data, - int *perr, - int timeout, - char *buff) -{ - char myBuff[DATA_MAXLEN + 1]; - int len; - int rpid; - char rcmd; - int rerrflg; - unsigned long rresponse; - - if (buff == (char *) NULL) - buff = myBuff; - - if (cmd != '\0') - { - if (mips_need_reply) - internal_error (__FILE__, __LINE__, - "mips_request: Trying to send command before reply"); - sprintf (buff, "0x0 %c 0x%s 0x%s", cmd, paddr_nz (addr), paddr_nz (data)); - mips_send_packet (buff, 1); - mips_need_reply = 1; - } - - if (perr == (int *) NULL) - return 0; - - if (!mips_need_reply) - internal_error (__FILE__, __LINE__, - "mips_request: Trying to get reply before command"); - - mips_need_reply = 0; - - len = mips_receive_packet (buff, 1, timeout); - buff[len] = '\0'; - - if (sscanf (buff, "0x%x %c 0x%x 0x%lx", - &rpid, &rcmd, &rerrflg, &rresponse) != 4 - || (cmd != '\0' && rcmd != cmd)) - mips_error ("Bad response from remote board"); - - if (rerrflg != 0) - { - *perr = 1; - - /* FIXME: This will returns MIPS errno numbers, which may or may - not be the same as errno values used on other systems. If - they stick to common errno values, they will be the same, but - if they don't, they must be translated. */ - errno = rresponse; - - return 0; - } - - *perr = 0; - return rresponse; -} - -static void -mips_initialize_cleanups (PTR arg) -{ - mips_initializing = 0; -} - -static void -mips_exit_cleanups (PTR arg) -{ - mips_exiting = 0; -} - -static void -mips_send_command (const char *cmd, int prompt) -{ - serial_write (mips_desc, cmd, strlen (cmd)); - mips_expect (cmd); - mips_expect ("\n"); - if (prompt) - mips_expect (mips_monitor_prompt); -} - -/* Enter remote (dbx) debug mode: */ -static void -mips_enter_debug (void) -{ - /* Reset the sequence numbers, ready for the new debug sequence: */ - mips_send_seq = 0; - mips_receive_seq = 0; - - if (mips_monitor != MON_IDT) - mips_send_command ("debug\r", 0); - else /* assume IDT monitor by default */ - mips_send_command ("db tty0\r", 0); - - sleep (1); - serial_write (mips_desc, "\r", sizeof "\r" - 1); - - /* We don't need to absorb any spurious characters here, since the - mips_receive_header will eat up a reasonable number of characters - whilst looking for the SYN, however this avoids the "garbage" - being displayed to the user. */ - if (mips_monitor != MON_IDT) - mips_expect ("\r"); - - { - char buff[DATA_MAXLEN + 1]; - if (mips_receive_packet (buff, 1, 3) < 0) - mips_error ("Failed to initialize (didn't receive packet)."); - } -} - -/* Exit remote (dbx) debug mode, returning to the monitor prompt: */ -static int -mips_exit_debug (void) -{ - int err; - struct cleanup *old_cleanups = make_cleanup (mips_exit_cleanups, NULL); - - mips_exiting = 1; - - if (mips_monitor != MON_IDT) - { - /* The DDB (NEC) and MiniRISC (LSI) versions of PMON exit immediately, - so we do not get a reply to this command: */ - mips_request ('x', 0, 0, NULL, mips_receive_wait, NULL); - mips_need_reply = 0; - if (!mips_expect (" break!")) - return -1; - } - else - mips_request ('x', 0, 0, &err, mips_receive_wait, NULL); - - if (!mips_expect (mips_monitor_prompt)) - return -1; - - do_cleanups (old_cleanups); - - return 0; -} - -/* Initialize a new connection to the MIPS board, and make sure we are - really connected. */ - -static void -mips_initialize (void) -{ - int err; - struct cleanup *old_cleanups = make_cleanup (mips_initialize_cleanups, NULL); - int j; - - /* What is this code doing here? I don't see any way it can happen, and - it might mean mips_initializing didn't get cleared properly. - So I'll make it a warning. */ - - if (mips_initializing) - { - warning ("internal error: mips_initialize called twice"); - return; - } - - mips_wait_flag = 0; - mips_initializing = 1; - - /* At this point, the packit protocol isn't responding. We'll try getting - into the monitor, and restarting the protocol. */ - - /* Force the system into the monitor. After this we *should* be at - the mips_monitor_prompt. */ - if (mips_monitor != MON_IDT) - j = 0; /* start by checking if we are already at the prompt */ - else - j = 1; /* start by sending a break */ - for (; j <= 4; j++) - { - switch (j) - { - case 0: /* First, try sending a CR */ - serial_flush_input (mips_desc); - serial_write (mips_desc, "\r", 1); - break; - case 1: /* First, try sending a break */ - serial_send_break (mips_desc); - break; - case 2: /* Then, try a ^C */ - serial_write (mips_desc, "\003", 1); - break; - case 3: /* Then, try escaping from download */ - { - if (mips_monitor != MON_IDT) - { - char tbuff[7]; - - /* We shouldn't need to send multiple termination - sequences, since the target performs line (or - block) reads, and then processes those - packets. In-case we were downloading a large packet - we flush the output buffer before inserting a - termination sequence. */ - serial_flush_output (mips_desc); - sprintf (tbuff, "\r/E/E\r"); - serial_write (mips_desc, tbuff, 6); - } - else - { - char srec[10]; - int i; - - /* We are possibly in binary download mode, having - aborted in the middle of an S-record. ^C won't - work because of binary mode. The only reliable way - out is to send enough termination packets (8 bytes) - to fill up and then overflow the largest size - S-record (255 bytes in this case). This amounts to - 256/8 + 1 packets. - */ - - mips_make_srec (srec, '7', 0, NULL, 0); - - for (i = 1; i <= 33; i++) - { - serial_write (mips_desc, srec, 8); - - if (serial_readchar (mips_desc, 0) >= 0) - break; /* Break immediatly if we get something from - the board. */ - } - } - } - break; - case 4: - mips_error ("Failed to initialize."); - } - - if (mips_expect (mips_monitor_prompt)) - break; - } - - if (mips_monitor != MON_IDT) - { - /* Sometimes PMON ignores the first few characters in the first - command sent after a load. Sending a blank command gets - around that. */ - mips_send_command ("\r", -1); - - /* Ensure the correct target state: */ - if (mips_monitor != MON_LSI) - mips_send_command ("set regsize 64\r", -1); - mips_send_command ("set hostport tty0\r", -1); - mips_send_command ("set brkcmd \"\"\r", -1); - /* Delete all the current breakpoints: */ - mips_send_command ("db *\r", -1); - /* NOTE: PMON does not have breakpoint support through the - "debug" mode, only at the monitor command-line. */ - } - - mips_enter_debug (); - - /* Clear all breakpoints: */ - if ((mips_monitor == MON_IDT - && clear_breakpoint (-1, 0, BREAK_UNUSED) == 0) - || mips_monitor == MON_LSI) - monitor_supports_breakpoints = 1; - else - monitor_supports_breakpoints = 0; - - do_cleanups (old_cleanups); - - /* If this doesn't call error, we have connected; we don't care if - the request itself succeeds or fails. */ - - mips_request ('r', 0, 0, &err, mips_receive_wait, NULL); - set_current_frame (create_new_frame (read_fp (), read_pc ())); - select_frame (get_current_frame (), 0); -} - -/* Open a connection to the remote board. */ -static void -common_open (struct target_ops *ops, char *name, int from_tty, - enum mips_monitor_type new_monitor, - const char *new_monitor_prompt) -{ - char *ptype; - char *serial_port_name; - char *remote_name = 0; - char *local_name = 0; - char **argv; - - if (name == 0) - error ( - "To open a MIPS remote debugging connection, you need to specify what serial\n\ -device is attached to the target board (e.g., /dev/ttya).\n" - "If you want to use TFTP to download to the board, specify the name of a\n" - "temporary file to be used by GDB for downloads as the second argument.\n" - "This filename must be in the form host:filename, where host is the name\n" - "of the host running the TFTP server, and the file must be readable by the\n" - "world. If the local name of the temporary file differs from the name as\n" - "seen from the board via TFTP, specify that name as the third parameter.\n"); - - /* Parse the serial port name, the optional TFTP name, and the - optional local TFTP name. */ - if ((argv = buildargv (name)) == NULL) - nomem (0); - make_cleanup_freeargv (argv); - - serial_port_name = xstrdup (argv[0]); - if (argv[1]) /* remote TFTP name specified? */ - { - remote_name = argv[1]; - if (argv[2]) /* local TFTP filename specified? */ - local_name = argv[2]; - } - - target_preopen (from_tty); - - if (mips_is_open) - unpush_target (current_ops); - - /* Open and initialize the serial port. */ - mips_desc = serial_open (serial_port_name); - if (mips_desc == NULL) - perror_with_name (serial_port_name); - - if (baud_rate != -1) - { - if (serial_setbaudrate (mips_desc, baud_rate)) - { - serial_close (mips_desc); - perror_with_name (serial_port_name); - } - } - - serial_raw (mips_desc); - - /* Open and initialize the optional download port. If it is in the form - hostname#portnumber, it's a UDP socket. If it is in the form - hostname:filename, assume it's the TFTP filename that must be - passed to the DDB board to tell it where to get the load file. */ - if (remote_name) - { - if (strchr (remote_name, '#')) - { - udp_desc = serial_open (remote_name); - if (!udp_desc) - perror_with_name ("Unable to open UDP port"); - udp_in_use = 1; - } - else - { - /* Save the remote and local names of the TFTP temp file. If - the user didn't specify a local name, assume it's the same - as the part of the remote name after the "host:". */ - if (tftp_name) - xfree (tftp_name); - if (tftp_localname) - xfree (tftp_localname); - if (local_name == NULL) - if ((local_name = strchr (remote_name, ':')) != NULL) - local_name++; /* skip over the colon */ - if (local_name == NULL) - local_name = remote_name; /* local name same as remote name */ - tftp_name = xstrdup (remote_name); - tftp_localname = xstrdup (local_name); - tftp_in_use = 1; - } - } - - current_ops = ops; - mips_is_open = 1; - - /* Reset the expected monitor prompt if it's never been set before. */ - if (mips_monitor_prompt == NULL) - mips_monitor_prompt = xstrdup (new_monitor_prompt); - mips_monitor = new_monitor; - - mips_initialize (); - - if (from_tty) - printf_unfiltered ("Remote MIPS debugging using %s\n", serial_port_name); - - /* Switch to using remote target now. */ - push_target (ops); - - /* FIXME: Should we call start_remote here? */ - - /* Try to figure out the processor model if possible. */ - ptype = mips_read_processor_type (); - if (ptype) - mips_set_processor_type_command (xstrdup (ptype), 0); - -/* This is really the job of start_remote however, that makes an assumption - that the target is about to print out a status message of some sort. That - doesn't happen here (in fact, it may not be possible to get the monitor to - send the appropriate packet). */ - - flush_cached_frames (); - registers_changed (); - stop_pc = read_pc (); - set_current_frame (create_new_frame (read_fp (), stop_pc)); - select_frame (get_current_frame (), 0); - print_stack_frame (selected_frame, -1, 1); - xfree (serial_port_name); -} - -static void -mips_open (char *name, int from_tty) -{ - const char *monitor_prompt = NULL; - if (TARGET_ARCHITECTURE != NULL - && TARGET_ARCHITECTURE->arch == bfd_arch_mips) - { - switch (TARGET_ARCHITECTURE->mach) - { - case bfd_mach_mips4100: - case bfd_mach_mips4300: - case bfd_mach_mips4600: - case bfd_mach_mips4650: - case bfd_mach_mips5000: - monitor_prompt = " "; - break; - } - } - if (monitor_prompt == NULL) - monitor_prompt = ""; - common_open (&mips_ops, name, from_tty, MON_IDT, monitor_prompt); -} - -static void -pmon_open (char *name, int from_tty) -{ - common_open (&pmon_ops, name, from_tty, MON_PMON, "PMON> "); -} - -static void -ddb_open (char *name, int from_tty) -{ - common_open (&ddb_ops, name, from_tty, MON_DDB, "NEC010>"); -} - -static void -lsi_open (char *name, int from_tty) -{ - int i; - - /* Clear the LSI breakpoint table. */ - for (i = 0; i < MAX_LSI_BREAKPOINTS; i++) - lsi_breakpoints[i].type = BREAK_UNUSED; - - common_open (&lsi_ops, name, from_tty, MON_LSI, "PMON> "); -} - -/* Close a connection to the remote board. */ - -static void -mips_close (int quitting) -{ - if (mips_is_open) - { - /* Get the board out of remote debugging mode. */ - (void) mips_exit_debug (); - - close_ports (); - } -} - -/* Detach from the remote board. */ - -static void -mips_detach (char *args, int from_tty) -{ - if (args) - error ("Argument given to \"detach\" when remotely debugging."); - - pop_target (); - - mips_close (1); - - if (from_tty) - printf_unfiltered ("Ending remote MIPS debugging.\n"); -} - -/* Tell the target board to resume. This does not wait for a reply - from the board, except in the case of single-stepping on LSI boards, - where PMON does return a reply. */ - -static void -mips_resume (ptid_t ptid, int step, enum target_signal siggnal) -{ - int err; - - /* LSI PMON requires returns a reply packet "0x1 s 0x0 0x57f" after - a single step, so we wait for that. */ - mips_request (step ? 's' : 'c', 1, siggnal, - mips_monitor == MON_LSI && step ? &err : (int *) NULL, - mips_receive_wait, NULL); -} - -/* Return the signal corresponding to SIG, where SIG is the number which - the MIPS protocol uses for the signal. */ -enum target_signal -mips_signal_from_protocol (int sig) -{ - /* We allow a few more signals than the IDT board actually returns, on - the theory that there is at least *some* hope that perhaps the numbering - for these signals is widely agreed upon. */ - if (sig <= 0 - || sig > 31) - return TARGET_SIGNAL_UNKNOWN; - - /* Don't want to use target_signal_from_host because we are converting - from MIPS signal numbers, not host ones. Our internal numbers - match the MIPS numbers for the signals the board can return, which - are: SIGINT, SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP. */ - return (enum target_signal) sig; -} - -/* Wait until the remote stops, and return a wait status. */ - -static ptid_t -mips_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int rstatus; - int err; - char buff[DATA_MAXLEN]; - int rpc, rfp, rsp; - char flags[20]; - int nfields; - int i; - - interrupt_count = 0; - hit_watchpoint = 0; - - /* If we have not sent a single step or continue command, then the - board is waiting for us to do something. Return a status - indicating that it is stopped. */ - if (!mips_need_reply) - { - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - return inferior_ptid; - } - - /* No timeout; we sit here as long as the program continues to execute. */ - mips_wait_flag = 1; - rstatus = mips_request ('\000', 0, 0, &err, -1, buff); - mips_wait_flag = 0; - if (err) - mips_error ("Remote failure: %s", safe_strerror (errno)); - - /* On returning from a continue, the PMON monitor seems to start - echoing back the messages we send prior to sending back the - ACK. The code can cope with this, but to try and avoid the - unnecessary serial traffic, and "spurious" characters displayed - to the user, we cheat and reset the debug protocol. The problems - seems to be caused by a check on the number of arguments, and the - command length, within the monitor causing it to echo the command - as a bad packet. */ - if (mips_monitor == MON_PMON) - { - mips_exit_debug (); - mips_enter_debug (); - } - - /* See if we got back extended status. If so, pick out the pc, fp, sp, etc... */ - - nfields = sscanf (buff, "0x%*x %*c 0x%*x 0x%*x 0x%x 0x%x 0x%x 0x%*x %s", - &rpc, &rfp, &rsp, flags); - if (nfields >= 3) - { - char buf[MAX_REGISTER_RAW_SIZE]; - - store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), rpc); - supply_register (PC_REGNUM, buf); - - store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), rfp); - supply_register (30, buf); /* This register they are avoiding and so it is unnamed */ - - store_unsigned_integer (buf, REGISTER_RAW_SIZE (SP_REGNUM), rsp); - supply_register (SP_REGNUM, buf); - - store_unsigned_integer (buf, REGISTER_RAW_SIZE (FP_REGNUM), 0); - supply_register (FP_REGNUM, buf); - - if (nfields == 9) - { - int i; - - for (i = 0; i <= 2; i++) - if (flags[i] == 'r' || flags[i] == 'w') - hit_watchpoint = 1; - else if (flags[i] == '\000') - break; - } - } - - if (strcmp (target_shortname, "lsi") == 0) - { -#if 0 - /* If this is an LSI PMON target, see if we just hit a hardrdware watchpoint. - Right now, PMON doesn't give us enough information to determine which - breakpoint we hit. So we have to look up the PC in our own table - of breakpoints, and if found, assume it's just a normal instruction - fetch breakpoint, not a data watchpoint. FIXME when PMON - provides some way to tell us what type of breakpoint it is. */ - int i; - CORE_ADDR pc = read_pc (); - - hit_watchpoint = 1; - for (i = 0; i < MAX_LSI_BREAKPOINTS; i++) - { - if (lsi_breakpoints[i].addr == pc - && lsi_breakpoints[i].type == BREAK_FETCH) - { - hit_watchpoint = 0; - break; - } - } -#else - /* If a data breakpoint was hit, PMON returns the following packet: - 0x1 c 0x0 0x57f 0x1 - The return packet from an ordinary breakpoint doesn't have the - extra 0x01 field tacked onto the end. */ - if (nfields == 1 && rpc == 1) - hit_watchpoint = 1; -#endif - } - - /* NOTE: The following (sig) numbers are defined by PMON: - SPP_SIGTRAP 5 breakpoint - SPP_SIGINT 2 - SPP_SIGSEGV 11 - SPP_SIGBUS 10 - SPP_SIGILL 4 - SPP_SIGFPE 8 - SPP_SIGTERM 15 */ - - /* Translate a MIPS waitstatus. We use constants here rather than WTERMSIG - and so on, because the constants we want here are determined by the - MIPS protocol and have nothing to do with what host we are running on. */ - if ((rstatus & 0xff) == 0) - { - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = (((rstatus) >> 8) & 0xff); - } - else if ((rstatus & 0xff) == 0x7f) - { - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = mips_signal_from_protocol (((rstatus) >> 8) & 0xff); - - /* If the stop PC is in the _exit function, assume - we hit the 'break 0x3ff' instruction in _exit, so this - is not a normal breakpoint. */ - if (strcmp (target_shortname, "lsi") == 0) - { - char *func_name; - CORE_ADDR func_start; - CORE_ADDR pc = read_pc (); - - find_pc_partial_function (pc, &func_name, &func_start, NULL); - if (func_name != NULL && strcmp (func_name, "_exit") == 0 - && func_start == pc) - status->kind = TARGET_WAITKIND_EXITED; - } - } - else - { - status->kind = TARGET_WAITKIND_SIGNALLED; - status->value.sig = mips_signal_from_protocol (rstatus & 0x7f); - } - - return inferior_ptid; -} - -/* We have to map between the register numbers used by gdb and the - register numbers used by the debugging protocol. This function - assumes that we are using tm-mips.h. */ - -#define REGNO_OFFSET 96 - -static int -mips_map_regno (int regno) -{ - if (regno < 32) - return regno; - if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) - return regno - FP0_REGNUM + 32; - switch (regno) - { - case PC_REGNUM: - return REGNO_OFFSET + 0; - case CAUSE_REGNUM: - return REGNO_OFFSET + 1; - case HI_REGNUM: - return REGNO_OFFSET + 2; - case LO_REGNUM: - return REGNO_OFFSET + 3; - case FCRCS_REGNUM: - return REGNO_OFFSET + 4; - case FCRIR_REGNUM: - return REGNO_OFFSET + 5; - default: - /* FIXME: Is there a way to get the status register? */ - return 0; - } -} - -/* Fetch the remote registers. */ - -static void -mips_fetch_registers (int regno) -{ - unsigned LONGEST val; - int err; - - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - mips_fetch_registers (regno); - return; - } - - if (regno == FP_REGNUM || regno == ZERO_REGNUM) - /* FP_REGNUM on the mips is a hack which is just supposed to read - zero (see also mips-nat.c). */ - val = 0; - else - { - /* If PMON doesn't support this register, don't waste serial - bandwidth trying to read it. */ - int pmon_reg = mips_map_regno (regno); - if (regno != 0 && pmon_reg == 0) - val = 0; - else - { - /* Unfortunately the PMON version in the Vr4300 board has been - compiled without the 64bit register access commands. This - means we cannot get hold of the full register width. */ - if (mips_monitor == MON_DDB) - val = (unsigned) mips_request ('t', pmon_reg, 0, - &err, mips_receive_wait, NULL); - else - val = mips_request ('r', pmon_reg, 0, - &err, mips_receive_wait, NULL); - if (err) - mips_error ("Can't read register %d: %s", regno, - safe_strerror (errno)); - } - } - - { - char buf[MAX_REGISTER_RAW_SIZE]; - - /* We got the number the register holds, but gdb expects to see a - value in the target byte ordering. */ - store_unsigned_integer (buf, REGISTER_RAW_SIZE (regno), val); - supply_register (regno, buf); - } -} - -/* Prepare to store registers. The MIPS protocol can store individual - registers, so this function doesn't have to do anything. */ - -static void -mips_prepare_to_store (void) -{ -} - -/* Store remote register(s). */ - -static void -mips_store_registers (int regno) -{ - int err; - - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - mips_store_registers (regno); - return; - } - - mips_request ('R', mips_map_regno (regno), - read_register (regno), - &err, mips_receive_wait, NULL); - if (err) - mips_error ("Can't write register %d: %s", regno, safe_strerror (errno)); -} - -/* Fetch a word from the target board. */ - -static unsigned int -mips_fetch_word (CORE_ADDR addr) -{ - unsigned int val; - int err; - - val = mips_request ('d', addr, 0, &err, mips_receive_wait, NULL); - if (err) - { - /* Data space failed; try instruction space. */ - val = mips_request ('i', addr, 0, &err, - mips_receive_wait, NULL); - if (err) - mips_error ("Can't read address 0x%s: %s", - paddr_nz (addr), safe_strerror (errno)); - } - return val; -} - -/* Store a word to the target board. Returns errno code or zero for - success. If OLD_CONTENTS is non-NULL, put the old contents of that - memory location there. */ - -/* FIXME! make sure only 32-bit quantities get stored! */ -static int -mips_store_word (CORE_ADDR addr, unsigned int val, char *old_contents) -{ - int err; - unsigned int oldcontents; - - oldcontents = mips_request ('D', addr, val, &err, - mips_receive_wait, NULL); - if (err) - { - /* Data space failed; try instruction space. */ - oldcontents = mips_request ('I', addr, val, &err, - mips_receive_wait, NULL); - if (err) - return errno; - } - if (old_contents != NULL) - store_unsigned_integer (old_contents, 4, oldcontents); - return 0; -} - -/* Read or write LEN bytes from inferior memory at MEMADDR, - transferring to or from debugger address MYADDR. Write to inferior - if SHOULD_WRITE is nonzero. Returns length of data written or - read; 0 for error. Note that protocol gives us the correct value - for a longword, since it transfers values in ASCII. We want the - byte values, so we have to swap the longword values. */ - -static int mask_address_p = 1; - -static int -mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, struct target_ops *target) -{ - int i; - CORE_ADDR addr; - int count; - char *buffer; - int status; - - /* PMON targets do not cope well with 64 bit addresses. Mask the - value down to 32 bits. */ - if (mask_address_p) - memaddr &= (CORE_ADDR) 0xffffffff; - - /* Round starting address down to longword boundary. */ - addr = memaddr & ~3; - /* Round ending address up; get number of longwords that makes. */ - count = (((memaddr + len) - addr) + 3) / 4; - /* Allocate buffer of that many longwords. */ - buffer = alloca (count * 4); - - if (write) - { - /* Fill start and end extra bytes of buffer with existing data. */ - if (addr != memaddr || len < 4) - { - /* Need part of initial word -- fetch it. */ - store_unsigned_integer (&buffer[0], 4, mips_fetch_word (addr)); - } - - if (count > 1) - { - /* Need part of last word -- fetch it. FIXME: we do this even - if we don't need it. */ - store_unsigned_integer (&buffer[(count - 1) * 4], 4, - mips_fetch_word (addr + (count - 1) * 4)); - } - - /* Copy data to be written over corresponding part of buffer */ - - memcpy ((char *) buffer + (memaddr & 3), myaddr, len); - - /* Write the entire buffer. */ - - for (i = 0; i < count; i++, addr += 4) - { - status = mips_store_word (addr, - extract_unsigned_integer (&buffer[i * 4], 4), - NULL); - /* Report each kilobyte (we download 32-bit words at a time) */ - if (i % 256 == 255) - { - printf_unfiltered ("*"); - gdb_flush (gdb_stdout); - } - if (status) - { - errno = status; - return 0; - } - /* FIXME: Do we want a QUIT here? */ - } - if (count >= 256) - printf_unfiltered ("\n"); - } - else - { - /* Read all the longwords */ - for (i = 0; i < count; i++, addr += 4) - { - store_unsigned_integer (&buffer[i * 4], 4, mips_fetch_word (addr)); - QUIT; - } - - /* Copy appropriate bytes out of the buffer. */ - memcpy (myaddr, buffer + (memaddr & 3), len); - } - return len; -} - -/* Print info on this target. */ - -static void -mips_files_info (struct target_ops *ignore) -{ - printf_unfiltered ("Debugging a MIPS board over a serial line.\n"); -} - -/* Kill the process running on the board. This will actually only - work if we are doing remote debugging over the console input. I - think that if IDT/sim had the remote debug interrupt enabled on the - right port, we could interrupt the process with a break signal. */ - -static void -mips_kill (void) -{ - if (!mips_wait_flag) - return; - - interrupt_count++; - - if (interrupt_count >= 2) - { - interrupt_count = 0; - - target_terminal_ours (); - - if (query ("Interrupted while waiting for the program.\n\ -Give up (and stop debugging it)? ")) - { - /* Clean up in such a way that mips_close won't try to talk to the - board (it almost surely won't work since we weren't able to talk to - it). */ - mips_wait_flag = 0; - close_ports (); - - printf_unfiltered ("Ending remote MIPS debugging.\n"); - target_mourn_inferior (); - - throw_exception (RETURN_QUIT); - } - - target_terminal_inferior (); - } - - if (remote_debug > 0) - printf_unfiltered ("Sending break\n"); - - serial_send_break (mips_desc); - -#if 0 - if (mips_is_open) - { - char cc; - - /* Send a ^C. */ - cc = '\003'; - serial_write (mips_desc, &cc, 1); - sleep (1); - target_mourn_inferior (); - } -#endif -} - -/* Start running on the target board. */ - -static void -mips_create_inferior (char *execfile, char *args, char **env) -{ - CORE_ADDR entry_pt; - - if (args && *args) - { - warning ("\ -Can't pass arguments to remote MIPS board; arguments ignored."); - /* And don't try to use them on the next "run" command. */ - execute_command ("set args", 0); - } - - if (execfile == 0 || exec_bfd == 0) - error ("No executable file specified"); - - entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd); - - init_wait_for_inferior (); - - /* FIXME: Should we set inferior_ptid here? */ - - proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0); -} - -/* Clean up after a process. Actually nothing to do. */ - -static void -mips_mourn_inferior (void) -{ - if (current_ops != NULL) - unpush_target (current_ops); - generic_mourn_inferior (); -} - -/* We can write a breakpoint and read the shadow contents in one - operation. */ - -/* Insert a breakpoint. On targets that don't have built-in breakpoint - support, we read the contents of the target location and stash it, - then overwrite it with a breakpoint instruction. ADDR is the target - location in the target machine. CONTENTS_CACHE is a pointer to - memory allocated for saving the target contents. It is guaranteed - by the caller to be long enough to save sizeof BREAKPOINT bytes (this - is accomplished via BREAKPOINT_MAX). */ - -static int -mips_insert_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - if (monitor_supports_breakpoints) - return set_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH); - else - return memory_insert_breakpoint (addr, contents_cache); -} - -static int -mips_remove_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - if (monitor_supports_breakpoints) - return clear_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH); - else - return memory_remove_breakpoint (addr, contents_cache); -} - -#if 0 /* currently not used */ -/* PMON does not currently provide support for the debug mode 'b' - commands to manipulate breakpoints. However, if we wanted to use - the monitor breakpoints (rather than the GDB BREAK_INSN version) - then this code performs the work needed to leave debug mode, - set/clear the breakpoint, and then return to debug mode. */ - -#define PMON_MAX_BP (33) /* 32 SW, 1 HW */ -static CORE_ADDR mips_pmon_bp_info[PMON_MAX_BP]; -/* NOTE: The code relies on this vector being zero-initialised by the system */ - -static int -pmon_insert_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - int status; - - if (monitor_supports_breakpoints) - { - char tbuff[12]; /* space for breakpoint command */ - int bpnum; - CORE_ADDR bpaddr; - - /* PMON does not support debug level breakpoint set/remove: */ - if (mips_exit_debug ()) - mips_error ("Failed to exit debug mode"); - - sprintf (tbuff, "b %08x\r", addr); - mips_send_command (tbuff, 0); - - mips_expect ("Bpt "); - - if (!mips_getstring (tbuff, remote_timeout)) - return 1; - tbuff[2] = '\0'; /* terminate the string */ - if (sscanf (tbuff, "%d", &bpnum) != 1) - { - fprintf_unfiltered (gdb_stderr, - "Invalid decimal breakpoint number from target: %s\n", tbuff); - return 1; - } - - mips_expect (" = "); - - /* Lead in the hex number we are expecting: */ - tbuff[0] = '0'; - tbuff[1] = 'x'; - - /* FIXME!! only 8 bytes! need to expand for Bfd64; - which targets return 64-bit addresses? PMON returns only 32! */ - if (!mips_getstring (&tbuff[2], 8)) - return 1; - tbuff[10] = '\0'; /* terminate the string */ - - if (sscanf (tbuff, "0x%08x", &bpaddr) != 1) - { - fprintf_unfiltered (gdb_stderr, - "Invalid hex address from target: %s\n", tbuff); - return 1; - } - - if (bpnum >= PMON_MAX_BP) - { - fprintf_unfiltered (gdb_stderr, - "Error: Returned breakpoint number %d outside acceptable range (0..%d)\n", - bpnum, PMON_MAX_BP - 1); - return 1; - } - - if (bpaddr != addr) - fprintf_unfiltered (gdb_stderr, "Warning: Breakpoint addresses do not match: 0x%x != 0x%x\n", addr, bpaddr); - - mips_pmon_bp_info[bpnum] = bpaddr; - - mips_expect ("\r\n"); - mips_expect (mips_monitor_prompt); - - mips_enter_debug (); - - return 0; - } - - return mips_store_word (addr, BREAK_INSN, contents_cache); -} - -static int -pmon_remove_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - if (monitor_supports_breakpoints) - { - int bpnum; - char tbuff[7]; /* enough for delete breakpoint command */ - - for (bpnum = 0; bpnum < PMON_MAX_BP; bpnum++) - if (mips_pmon_bp_info[bpnum] == addr) - break; - - if (bpnum >= PMON_MAX_BP) - { - fprintf_unfiltered (gdb_stderr, - "pmon_remove_breakpoint: Failed to find breakpoint at address 0x%s\n", - paddr_nz (addr)); - return 1; - } - - if (mips_exit_debug ()) - mips_error ("Failed to exit debug mode"); - - sprintf (tbuff, "db %02d\r", bpnum); - - mips_send_command (tbuff, -1); - /* NOTE: If the breakpoint does not exist then a "Bpt
not - set" message will be returned. */ - - mips_enter_debug (); - - return 0; - } - - return target_write_memory (addr, contents_cache, BREAK_INSN_SIZE); -} -#endif - - -/* Tell whether this target can support a hardware breakpoint. CNT - is the number of hardware breakpoints already installed. This - implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro. */ - -int -remote_mips_can_use_hardware_watchpoint (int cnt) -{ - return cnt < MAX_LSI_BREAKPOINTS && strcmp (target_shortname, "lsi") == 0; -} - - -/* Compute a don't care mask for the region bounding ADDR and ADDR + LEN - 1. - This is used for memory ref breakpoints. */ - -static unsigned long -calculate_mask (CORE_ADDR addr, int len) -{ - unsigned long mask; - int i; - - mask = addr ^ (addr + len - 1); - - for (i = 32; i >= 0; i--) - if (mask == 0) - break; - else - mask >>= 1; - - mask = (unsigned long) 0xffffffff >> i; - - return mask; -} - - -/* Insert a hardware breakpoint. This works only on LSI targets, which - implement ordinary breakpoints using hardware facilities. */ - -int -remote_mips_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - if (strcmp (target_shortname, "lsi") == 0) - return mips_insert_breakpoint (addr, contents_cache); - else - return -1; -} - - -/* Remove a hardware breakpoint. This works only on LSI targets, which - implement ordinary breakpoints using hardware facilities. */ - -int -remote_mips_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - if (strcmp (target_shortname, "lsi") == 0) - return mips_remove_breakpoint (addr, contents_cache); - else - return -1; -} - -/* Set a data watchpoint. ADDR and LEN should be obvious. TYPE is 0 - for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write - watchpoint. */ - -int -remote_mips_set_watchpoint (CORE_ADDR addr, int len, int type) -{ - if (set_breakpoint (addr, len, type)) - return -1; - - return 0; -} - -int -remote_mips_remove_watchpoint (CORE_ADDR addr, int len, int type) -{ - if (clear_breakpoint (addr, len, type)) - return -1; - - return 0; -} - -int -remote_mips_stopped_by_watchpoint (void) -{ - return hit_watchpoint; -} - - -/* Insert a breakpoint. */ - -static int -set_breakpoint (CORE_ADDR addr, int len, enum break_type type) -{ - return common_breakpoint (1, addr, len, type); -} - - -/* Clear a breakpoint. */ - -static int -clear_breakpoint (CORE_ADDR addr, int len, enum break_type type) -{ - return common_breakpoint (0, addr, len, type); -} - - -/* Check the error code from the return packet for an LSI breakpoint - command. If there's no error, just return 0. If it's a warning, - print the warning text and return 0. If it's an error, print - the error text and return 1. is the address of the breakpoint - that was being set. is the error code returned by PMON. - This is a helper function for common_breakpoint. */ - -static int -check_lsi_error (CORE_ADDR addr, int rerrflg) -{ - struct lsi_error *err; - char *saddr = paddr_nz (addr); /* printable address string */ - - if (rerrflg == 0) /* no error */ - return 0; - - /* Warnings can be ORed together, so check them all. */ - if (rerrflg & W_WARN) - { - if (monitor_warnings) - { - int found = 0; - for (err = lsi_warning_table; err->code != 0; err++) - { - if ((err->code & rerrflg) == err->code) - { - found = 1; - fprintf_unfiltered (gdb_stderr, - "common_breakpoint (0x%s): Warning: %s\n", - saddr, - err->string); - } - } - if (!found) - fprintf_unfiltered (gdb_stderr, - "common_breakpoint (0x%s): Unknown warning: 0x%x\n", - saddr, - rerrflg); - } - return 0; - } - - /* Errors are unique, i.e. can't be ORed together. */ - for (err = lsi_error_table; err->code != 0; err++) - { - if ((err->code & rerrflg) == err->code) - { - fprintf_unfiltered (gdb_stderr, - "common_breakpoint (0x%s): Error: %s\n", - saddr, - err->string); - return 1; - } - } - fprintf_unfiltered (gdb_stderr, - "common_breakpoint (0x%s): Unknown error: 0x%x\n", - saddr, - rerrflg); - return 1; -} - - -/* This routine sends a breakpoint command to the remote target. - - is 1 if setting a breakpoint, or 0 if clearing a breakpoint. - is the address of the breakpoint. - the length of the region to break on. - is the type of breakpoint: - 0 = write (BREAK_WRITE) - 1 = read (BREAK_READ) - 2 = read/write (BREAK_ACCESS) - 3 = instruction fetch (BREAK_FETCH) - - Return 0 if successful; otherwise 1. */ - -static int -common_breakpoint (int set, CORE_ADDR addr, int len, enum break_type type) -{ - char buf[DATA_MAXLEN + 1]; - char cmd, rcmd; - int rpid, rerrflg, rresponse, rlen; - int nfields; - - addr = ADDR_BITS_REMOVE (addr); - - if (mips_monitor == MON_LSI) - { - if (set == 0) /* clear breakpoint */ - { - /* The LSI PMON "clear breakpoint" has this form: - 'b' 0x0 - reply: - 'b' 0x0 - - is a breakpoint number returned by an earlier 'B' command. - Possible return codes: OK, E_BPT. */ - - int i; - - /* Search for the breakpoint in the table. */ - for (i = 0; i < MAX_LSI_BREAKPOINTS; i++) - if (lsi_breakpoints[i].type == type - && lsi_breakpoints[i].addr == addr - && lsi_breakpoints[i].len == len) - break; - - /* Clear the table entry and tell PMON to clear the breakpoint. */ - if (i == MAX_LSI_BREAKPOINTS) - { - warning ("common_breakpoint: Attempt to clear bogus breakpoint at %s\n", - paddr_nz (addr)); - return 1; - } - - lsi_breakpoints[i].type = BREAK_UNUSED; - sprintf (buf, "0x0 b 0x%x 0x0", i); - mips_send_packet (buf, 1); - - rlen = mips_receive_packet (buf, 1, mips_receive_wait); - buf[rlen] = '\0'; - - nfields = sscanf (buf, "0x%x b 0x0 0x%x", &rpid, &rerrflg); - if (nfields != 2) - mips_error ("common_breakpoint: Bad response from remote board: %s", buf); - - return (check_lsi_error (addr, rerrflg)); - } - else - /* set a breakpoint */ - { - /* The LSI PMON "set breakpoint" command has this form: - 'B' 0x0 - reply: - 'B' - - The "set data breakpoint" command has this form: - - 'A' [ []] - - where: type= "0x1" = read - "0x2" = write - "0x3" = access (read or write) - - The reply returns two values: - bptn - a breakpoint number, which is a small integer with - possible values of zero through 255. - code - an error return code, a value of zero indicates a - succesful completion, other values indicate various - errors and warnings. - - Possible return codes: OK, W_QAL, E_QAL, E_OUT, E_NON. - - */ - - if (type == BREAK_FETCH) /* instruction breakpoint */ - { - cmd = 'B'; - sprintf (buf, "0x0 B 0x%s 0x0", paddr_nz (addr)); - } - else - /* watchpoint */ - { - cmd = 'A'; - sprintf (buf, "0x0 A 0x%s 0x%x 0x%s", paddr_nz (addr), - type == BREAK_READ ? 1 : (type == BREAK_WRITE ? 2 : 3), - paddr_nz (addr + len - 1)); - } - mips_send_packet (buf, 1); - - rlen = mips_receive_packet (buf, 1, mips_receive_wait); - buf[rlen] = '\0'; - - nfields = sscanf (buf, "0x%x %c 0x%x 0x%x", - &rpid, &rcmd, &rresponse, &rerrflg); - if (nfields != 4 || rcmd != cmd || rresponse > 255) - mips_error ("common_breakpoint: Bad response from remote board: %s", buf); - - if (rerrflg != 0) - if (check_lsi_error (addr, rerrflg)) - return 1; - - /* rresponse contains PMON's breakpoint number. Record the - information for this breakpoint so we can clear it later. */ - lsi_breakpoints[rresponse].type = type; - lsi_breakpoints[rresponse].addr = addr; - lsi_breakpoints[rresponse].len = len; - - return 0; - } - } - else - { - /* On non-LSI targets, the breakpoint command has this form: - 0x0 - is a don't care mask for addresses. - is any combination of `r', `w', or `f' for read/write/fetch. - */ - unsigned long mask; - - mask = calculate_mask (addr, len); - addr &= ~mask; - - if (set) /* set a breakpoint */ - { - char *flags; - switch (type) - { - case BREAK_WRITE: /* write */ - flags = "w"; - break; - case BREAK_READ: /* read */ - flags = "r"; - break; - case BREAK_ACCESS: /* read/write */ - flags = "rw"; - break; - case BREAK_FETCH: /* fetch */ - flags = "f"; - break; - default: - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } - - cmd = 'B'; - sprintf (buf, "0x0 B 0x%s 0x%s %s", paddr_nz (addr), - paddr_nz (mask), flags); - } - else - { - cmd = 'b'; - sprintf (buf, "0x0 b 0x%s", paddr_nz (addr)); - } - - mips_send_packet (buf, 1); - - rlen = mips_receive_packet (buf, 1, mips_receive_wait); - buf[rlen] = '\0'; - - nfields = sscanf (buf, "0x%x %c 0x%x 0x%x", - &rpid, &rcmd, &rerrflg, &rresponse); - - if (nfields != 4 || rcmd != cmd) - mips_error ("common_breakpoint: Bad response from remote board: %s", - buf); - - if (rerrflg != 0) - { - /* Ddb returns "0x0 b 0x16 0x0\000", whereas - Cogent returns "0x0 b 0xffffffff 0x16\000": */ - if (mips_monitor == MON_DDB) - rresponse = rerrflg; - if (rresponse != 22) /* invalid argument */ - fprintf_unfiltered (gdb_stderr, - "common_breakpoint (0x%s): Got error: 0x%x\n", - paddr_nz (addr), rresponse); - return 1; - } - } - return 0; -} - -static void -send_srec (char *srec, int len, CORE_ADDR addr) -{ - while (1) - { - int ch; - - serial_write (mips_desc, srec, len); - - ch = mips_readchar (remote_timeout); - - switch (ch) - { - case SERIAL_TIMEOUT: - error ("Timeout during download."); - break; - case 0x6: /* ACK */ - return; - case 0x15: /* NACK */ - fprintf_unfiltered (gdb_stderr, "Download got a NACK at byte %s! Retrying.\n", paddr_u (addr)); - continue; - default: - error ("Download got unexpected ack char: 0x%x, retrying.\n", ch); - } - } -} - -/* Download a binary file by converting it to S records. */ - -static void -mips_load_srec (char *args) -{ - bfd *abfd; - asection *s; - char *buffer, srec[1024]; - unsigned int i; - unsigned int srec_frame = 200; - int reclen; - static int hashmark = 1; - - buffer = alloca (srec_frame * 2 + 256); - - abfd = bfd_openr (args, 0); - if (!abfd) - { - printf_filtered ("Unable to open file %s\n", args); - return; - } - - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - return; - } - -/* This actually causes a download in the IDT binary format: */ - mips_send_command (LOAD_CMD, 0); - - for (s = abfd->sections; s; s = s->next) - { - if (s->flags & SEC_LOAD) - { - unsigned int numbytes; - - /* FIXME! vma too small????? */ - printf_filtered ("%s\t: 0x%4lx .. 0x%4lx ", s->name, - (long) s->vma, - (long) (s->vma + s->_raw_size)); - gdb_flush (gdb_stdout); - - for (i = 0; i < s->_raw_size; i += numbytes) - { - numbytes = min (srec_frame, s->_raw_size - i); - - bfd_get_section_contents (abfd, s, buffer, i, numbytes); - - reclen = mips_make_srec (srec, '3', s->vma + i, buffer, numbytes); - send_srec (srec, reclen, s->vma + i); - - if (ui_load_progress_hook) - ui_load_progress_hook (s->name, i); - - if (hashmark) - { - putchar_unfiltered ('#'); - gdb_flush (gdb_stdout); - } - - } /* Per-packet (or S-record) loop */ - - putchar_unfiltered ('\n'); - } /* Loadable sections */ - } - if (hashmark) - putchar_unfiltered ('\n'); - - /* Write a type 7 terminator record. no data for a type 7, and there - is no data, so len is 0. */ - - reclen = mips_make_srec (srec, '7', abfd->start_address, NULL, 0); - - send_srec (srec, reclen, abfd->start_address); - - serial_flush_input (mips_desc); -} - -/* - * mips_make_srec -- make an srecord. This writes each line, one at a - * time, each with it's own header and trailer line. - * An srecord looks like this: - * - * byte count-+ address - * start ---+ | | data +- checksum - * | | | | - * S01000006F6B692D746573742E73726563E4 - * S315000448600000000000000000FC00005900000000E9 - * S31A0004000023C1400037DE00F023604000377B009020825000348D - * S30B0004485A0000000000004E - * S70500040000F6 - * - * S
- * - * Where - * - length - * is the number of bytes following upto the checksum. Note that - * this is not the number of chars following, since it takes two - * chars to represent a byte. - * - type - * is one of: - * 0) header record - * 1) two byte address data record - * 2) three byte address data record - * 3) four byte address data record - * 7) four byte address termination record - * 8) three byte address termination record - * 9) two byte address termination record - * - * - address - * is the start address of the data following, or in the case of - * a termination record, the start address of the image - * - data - * is the data. - * - checksum - * is the sum of all the raw byte data in the record, from the length - * upwards, modulo 256 and subtracted from 255. - * - * This routine returns the length of the S-record. - * - */ - -static int -mips_make_srec (char *buf, int type, CORE_ADDR memaddr, unsigned char *myaddr, - int len) -{ - unsigned char checksum; - int i; - - /* Create the header for the srec. addr_size is the number of bytes in the address, - and 1 is the number of bytes in the count. */ - - /* FIXME!! bigger buf required for 64-bit! */ - buf[0] = 'S'; - buf[1] = type; - buf[2] = len + 4 + 1; /* len + 4 byte address + 1 byte checksum */ - /* This assumes S3 style downloads (4byte addresses). There should - probably be a check, or the code changed to make it more - explicit. */ - buf[3] = memaddr >> 24; - buf[4] = memaddr >> 16; - buf[5] = memaddr >> 8; - buf[6] = memaddr; - memcpy (&buf[7], myaddr, len); - - /* Note that the checksum is calculated on the raw data, not the - hexified data. It includes the length, address and the data - portions of the packet. */ - checksum = 0; - buf += 2; /* Point at length byte */ - for (i = 0; i < len + 4 + 1; i++) - checksum += *buf++; - - *buf = ~checksum; - - return len + 8; -} - -/* The following manifest controls whether we enable the simple flow - control support provided by the monitor. If enabled the code will - wait for an affirmative ACK between transmitting packets. */ -#define DOETXACK (1) - -/* The PMON fast-download uses an encoded packet format constructed of - 3byte data packets (encoded as 4 printable ASCII characters), and - escape sequences (preceded by a '/'): - - 'K' clear checksum - 'C' compare checksum (12bit value, not included in checksum calculation) - 'S' define symbol name (for addr) terminated with "," and padded to 4char boundary - 'Z' zero fill multiple of 3bytes - 'B' byte (12bit encoded value, of 8bit data) - 'A' address (36bit encoded value) - 'E' define entry as original address, and exit load - - The packets are processed in 4 character chunks, so the escape - sequences that do not have any data (or variable length data) - should be padded to a 4 character boundary. The decoder will give - an error if the complete message block size is not a multiple of - 4bytes (size of record). - - The encoding of numbers is done in 6bit fields. The 6bit value is - used to index into this string to get the specific character - encoding for the value: */ -static char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,."; - -/* Convert the number of bits required into an encoded number, 6bits - at a time (range 0..63). Keep a checksum if required (passed - pointer non-NULL). The function returns the number of encoded - characters written into the buffer. */ -static int -pmon_makeb64 (unsigned long v, char *p, int n, int *chksum) -{ - int count = (n / 6); - - if ((n % 12) != 0) - { - fprintf_unfiltered (gdb_stderr, - "Fast encoding bitcount must be a multiple of 12bits: %dbit%s\n", n, (n == 1) ? "" : "s"); - return (0); - } - if (n > 36) - { - fprintf_unfiltered (gdb_stderr, - "Fast encoding cannot process more than 36bits at the moment: %dbits\n", n); - return (0); - } - - /* Deal with the checksum: */ - if (chksum != NULL) - { - switch (n) - { - case 36: - *chksum += ((v >> 24) & 0xFFF); - case 24: - *chksum += ((v >> 12) & 0xFFF); - case 12: - *chksum += ((v >> 0) & 0xFFF); - } - } - - do - { - n -= 6; - *p++ = encoding[(v >> n) & 0x3F]; - } - while (n > 0); - - return (count); -} - -/* Shorthand function (that could be in-lined) to output the zero-fill - escape sequence into the data stream. */ -static int -pmon_zeroset (int recsize, char **buff, int *amount, unsigned int *chksum) -{ - int count; - - sprintf (*buff, "/Z"); - count = pmon_makeb64 (*amount, (*buff + 2), 12, chksum); - *buff += (count + 2); - *amount = 0; - return (recsize + count + 2); -} - -static int -pmon_checkset (int recsize, char **buff, int *value) -{ - int count; - - /* Add the checksum (without updating the value): */ - sprintf (*buff, "/C"); - count = pmon_makeb64 (*value, (*buff + 2), 12, NULL); - *buff += (count + 2); - sprintf (*buff, "\n"); - *buff += 2; /* include zero terminator */ - /* Forcing a checksum validation clears the sum: */ - *value = 0; - return (recsize + count + 3); -} - -/* Amount of padding we leave after at the end of the output buffer, - for the checksum and line termination characters: */ -#define CHECKSIZE (4 + 4 + 4 + 2) -/* zero-fill, checksum, transfer end and line termination space. */ - -/* The amount of binary data loaded from the object file in a single - operation: */ -#define BINCHUNK (1024) - -/* Maximum line of data accepted by the monitor: */ -#define MAXRECSIZE (550) -/* NOTE: This constant depends on the monitor being used. This value - is for PMON 5.x on the Cogent Vr4300 board. */ - -static void -pmon_make_fastrec (char **outbuf, unsigned char *inbuf, int *inptr, - int inamount, int *recsize, unsigned int *csum, - unsigned int *zerofill) -{ - int count = 0; - char *p = *outbuf; - - /* This is a simple check to ensure that our data will fit within - the maximum allowable record size. Each record output is 4bytes - in length. We must allow space for a pending zero fill command, - the record, and a checksum record. */ - while ((*recsize < (MAXRECSIZE - CHECKSIZE)) && ((inamount - *inptr) > 0)) - { - /* Process the binary data: */ - if ((inamount - *inptr) < 3) - { - if (*zerofill != 0) - *recsize = pmon_zeroset (*recsize, &p, zerofill, csum); - sprintf (p, "/B"); - count = pmon_makeb64 (inbuf[*inptr], &p[2], 12, csum); - p += (2 + count); - *recsize += (2 + count); - (*inptr)++; - } - else - { - unsigned int value = ((inbuf[*inptr + 0] << 16) | (inbuf[*inptr + 1] << 8) | inbuf[*inptr + 2]); - /* Simple check for zero data. TODO: A better check would be - to check the last, and then the middle byte for being zero - (if the first byte is not). We could then check for - following runs of zeros, and if above a certain size it is - worth the 4 or 8 character hit of the byte insertions used - to pad to the start of the zeroes. NOTE: This also depends - on the alignment at the end of the zero run. */ - if (value == 0x00000000) - { - (*zerofill)++; - if (*zerofill == 0xFFF) /* 12bit counter */ - *recsize = pmon_zeroset (*recsize, &p, zerofill, csum); - } - else - { - if (*zerofill != 0) - *recsize = pmon_zeroset (*recsize, &p, zerofill, csum); - count = pmon_makeb64 (value, p, 24, csum); - p += count; - *recsize += count; - } - *inptr += 3; - } - } - - *outbuf = p; - return; -} - -static int -pmon_check_ack (char *mesg) -{ -#if defined(DOETXACK) - int c; - - if (!tftp_in_use) - { - c = serial_readchar (udp_in_use ? udp_desc : mips_desc, - remote_timeout); - if ((c == SERIAL_TIMEOUT) || (c != 0x06)) - { - fprintf_unfiltered (gdb_stderr, - "Failed to receive valid ACK for %s\n", mesg); - return (-1); /* terminate the download */ - } - } -#endif /* DOETXACK */ - return (0); -} - -/* pmon_download - Send a sequence of characters to the PMON download port, - which is either a serial port or a UDP socket. */ - -static void -pmon_start_download (void) -{ - if (tftp_in_use) - { - /* Create the temporary download file. */ - if ((tftp_file = fopen (tftp_localname, "w")) == NULL) - perror_with_name (tftp_localname); - } - else - { - mips_send_command (udp_in_use ? LOAD_CMD_UDP : LOAD_CMD, 0); - mips_expect ("Downloading from "); - mips_expect (udp_in_use ? "udp" : "tty0"); - mips_expect (", ^C to abort\r\n"); - } -} - -static int -mips_expect_download (char *string) -{ - if (!mips_expect (string)) - { - fprintf_unfiltered (gdb_stderr, "Load did not complete successfully.\n"); - if (tftp_in_use) - remove (tftp_localname); /* Remove temporary file */ - return 0; - } - else - return 1; -} - -static void -pmon_check_entry_address (char *entry_address, int final) -{ - char hexnumber[9]; /* includes '\0' space */ - mips_expect_timeout (entry_address, tftp_in_use ? 15 : remote_timeout); - sprintf (hexnumber, "%x", final); - mips_expect (hexnumber); - mips_expect ("\r\n"); -} - -static int -pmon_check_total (int bintotal) -{ - char hexnumber[9]; /* includes '\0' space */ - mips_expect ("\r\ntotal = 0x"); - sprintf (hexnumber, "%x", bintotal); - mips_expect (hexnumber); - return mips_expect_download (" bytes\r\n"); -} - -static void -pmon_end_download (int final, int bintotal) -{ - char hexnumber[9]; /* includes '\0' space */ - - if (tftp_in_use) - { - static char *load_cmd_prefix = "load -b -s "; - char *cmd; - struct stat stbuf; - - /* Close off the temporary file containing the load data. */ - fclose (tftp_file); - tftp_file = NULL; - - /* Make the temporary file readable by the world. */ - if (stat (tftp_localname, &stbuf) == 0) - chmod (tftp_localname, stbuf.st_mode | S_IROTH); - - /* Must reinitialize the board to prevent PMON from crashing. */ - mips_send_command ("initEther\r", -1); - - /* Send the load command. */ - cmd = xmalloc (strlen (load_cmd_prefix) + strlen (tftp_name) + 2); - strcpy (cmd, load_cmd_prefix); - strcat (cmd, tftp_name); - strcat (cmd, "\r"); - mips_send_command (cmd, 0); - xfree (cmd); - if (!mips_expect_download ("Downloading from ")) - return; - if (!mips_expect_download (tftp_name)) - return; - if (!mips_expect_download (", ^C to abort\r\n")) - return; - } - - /* Wait for the stuff that PMON prints after the load has completed. - The timeout value for use in the tftp case (15 seconds) was picked - arbitrarily but might be too small for really large downloads. FIXME. */ - switch (mips_monitor) - { - case MON_LSI: - pmon_check_ack ("termination"); - pmon_check_entry_address ("Entry address is ", final); - if (!pmon_check_total (bintotal)) - return; - break; - default: - pmon_check_entry_address ("Entry Address = ", final); - pmon_check_ack ("termination"); - if (!pmon_check_total (bintotal)) - return; - break; - } - - if (tftp_in_use) - remove (tftp_localname); /* Remove temporary file */ -} - -static void -pmon_download (char *buffer, int length) -{ - if (tftp_in_use) - fwrite (buffer, 1, length, tftp_file); - else - serial_write (udp_in_use ? udp_desc : mips_desc, buffer, length); -} - -static void -pmon_load_fast (char *file) -{ - bfd *abfd; - asection *s; - unsigned char *binbuf; - char *buffer; - int reclen; - unsigned int csum = 0; - int hashmark = !tftp_in_use; - int bintotal = 0; - int final = 0; - int finished = 0; - - buffer = (char *) xmalloc (MAXRECSIZE + 1); - binbuf = (unsigned char *) xmalloc (BINCHUNK); - - abfd = bfd_openr (file, 0); - if (!abfd) - { - printf_filtered ("Unable to open file %s\n", file); - return; - } - - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - return; - } - - /* Setup the required download state: */ - mips_send_command ("set dlproto etxack\r", -1); - mips_send_command ("set dlecho off\r", -1); - /* NOTE: We get a "cannot set variable" message if the variable is - already defined to have the argument we give. The code doesn't - care, since it just scans to the next prompt anyway. */ - /* Start the download: */ - pmon_start_download (); - - /* Zero the checksum */ - sprintf (buffer, "/Kxx\n"); - reclen = strlen (buffer); - pmon_download (buffer, reclen); - finished = pmon_check_ack ("/Kxx"); - - for (s = abfd->sections; s && !finished; s = s->next) - if (s->flags & SEC_LOAD) /* only deal with loadable sections */ - { - bintotal += s->_raw_size; - final = (s->vma + s->_raw_size); - - printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, (unsigned int) s->vma, - (unsigned int) (s->vma + s->_raw_size)); - gdb_flush (gdb_stdout); - - /* Output the starting address */ - sprintf (buffer, "/A"); - reclen = pmon_makeb64 (s->vma, &buffer[2], 36, &csum); - buffer[2 + reclen] = '\n'; - buffer[3 + reclen] = '\0'; - reclen += 3; /* for the initial escape code and carriage return */ - pmon_download (buffer, reclen); - finished = pmon_check_ack ("/A"); - - if (!finished) - { - unsigned int binamount; - unsigned int zerofill = 0; - char *bp = buffer; - unsigned int i; - - reclen = 0; - - for (i = 0; ((i < s->_raw_size) && !finished); i += binamount) - { - int binptr = 0; - - binamount = min (BINCHUNK, s->_raw_size - i); - - bfd_get_section_contents (abfd, s, binbuf, i, binamount); - - /* This keeps a rolling checksum, until we decide to output - the line: */ - for (; ((binamount - binptr) > 0);) - { - pmon_make_fastrec (&bp, binbuf, &binptr, binamount, &reclen, &csum, &zerofill); - if (reclen >= (MAXRECSIZE - CHECKSIZE)) - { - reclen = pmon_checkset (reclen, &bp, &csum); - pmon_download (buffer, reclen); - finished = pmon_check_ack ("data record"); - if (finished) - { - zerofill = 0; /* do not transmit pending zerofills */ - break; - } - - if (ui_load_progress_hook) - ui_load_progress_hook (s->name, i); - - if (hashmark) - { - putchar_unfiltered ('#'); - gdb_flush (gdb_stdout); - } - - bp = buffer; - reclen = 0; /* buffer processed */ - } - } - } - - /* Ensure no out-standing zerofill requests: */ - if (zerofill != 0) - reclen = pmon_zeroset (reclen, &bp, &zerofill, &csum); - - /* and then flush the line: */ - if (reclen > 0) - { - reclen = pmon_checkset (reclen, &bp, &csum); - /* Currently pmon_checkset outputs the line terminator by - default, so we write out the buffer so far: */ - pmon_download (buffer, reclen); - finished = pmon_check_ack ("record remnant"); - } - } - - putchar_unfiltered ('\n'); - } - - /* Terminate the transfer. We know that we have an empty output - buffer at this point. */ - sprintf (buffer, "/E/E\n"); /* include dummy padding characters */ - reclen = strlen (buffer); - pmon_download (buffer, reclen); - - if (finished) - { /* Ignore the termination message: */ - serial_flush_input (udp_in_use ? udp_desc : mips_desc); - } - else - { /* Deal with termination message: */ - pmon_end_download (final, bintotal); - } - - return; -} - -/* mips_load -- download a file. */ - -static void -mips_load (char *file, int from_tty) -{ - /* Get the board out of remote debugging mode. */ - if (mips_exit_debug ()) - error ("mips_load: Couldn't get into monitor mode."); - - if (mips_monitor != MON_IDT) - pmon_load_fast (file); - else - mips_load_srec (file); - - mips_initialize (); - - /* Finally, make the PC point at the start address */ - if (mips_monitor != MON_IDT) - { - /* Work around problem where PMON monitor updates the PC after a load - to a different value than GDB thinks it has. The following ensures - that the write_pc() WILL update the PC value: */ - register_valid[PC_REGNUM] = 0; - } - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - inferior_ptid = null_ptid; /* No process now */ - -/* This is necessary because many things were based on the PC at the time that - we attached to the monitor, which is no longer valid now that we have loaded - new code (and just changed the PC). Another way to do this might be to call - normal_stop, except that the stack may not be valid, and things would get - horribly confused... */ - - clear_symtab_users (); -} - - -/* Pass the command argument as a packet to PMON verbatim. */ - -static void -pmon_command (char *args, int from_tty) -{ - char buf[DATA_MAXLEN + 1]; - int rlen; - - sprintf (buf, "0x0 %s", args); - mips_send_packet (buf, 1); - printf_filtered ("Send packet: %s\n", buf); - - rlen = mips_receive_packet (buf, 1, mips_receive_wait); - buf[rlen] = '\0'; - printf_filtered ("Received packet: %s\n", buf); -} - -void -_initialize_remote_mips (void) -{ - /* Initialize the fields in mips_ops that are common to all four targets. */ - mips_ops.to_longname = "Remote MIPS debugging over serial line"; - mips_ops.to_close = mips_close; - mips_ops.to_detach = mips_detach; - mips_ops.to_resume = mips_resume; - mips_ops.to_fetch_registers = mips_fetch_registers; - mips_ops.to_store_registers = mips_store_registers; - mips_ops.to_prepare_to_store = mips_prepare_to_store; - mips_ops.to_xfer_memory = mips_xfer_memory; - mips_ops.to_files_info = mips_files_info; - mips_ops.to_insert_breakpoint = mips_insert_breakpoint; - mips_ops.to_remove_breakpoint = mips_remove_breakpoint; - mips_ops.to_kill = mips_kill; - mips_ops.to_load = mips_load; - mips_ops.to_create_inferior = mips_create_inferior; - mips_ops.to_mourn_inferior = mips_mourn_inferior; - mips_ops.to_stratum = process_stratum; - mips_ops.to_has_all_memory = 1; - mips_ops.to_has_memory = 1; - mips_ops.to_has_stack = 1; - mips_ops.to_has_registers = 1; - mips_ops.to_has_execution = 1; - mips_ops.to_magic = OPS_MAGIC; - - /* Copy the common fields to all four target vectors. */ - pmon_ops = ddb_ops = lsi_ops = mips_ops; - - /* Initialize target-specific fields in the target vectors. */ - mips_ops.to_shortname = "mips"; - mips_ops.to_doc = "\ -Debug a board using the MIPS remote debugging protocol over a serial line.\n\ -The argument is the device it is connected to or, if it contains a colon,\n\ -HOST:PORT to access a board over a network"; - mips_ops.to_open = mips_open; - mips_ops.to_wait = mips_wait; - - pmon_ops.to_shortname = "pmon"; - pmon_ops.to_doc = "\ -Debug a board using the PMON MIPS remote debugging protocol over a serial\n\ -line. The argument is the device it is connected to or, if it contains a\n\ -colon, HOST:PORT to access a board over a network"; - pmon_ops.to_open = pmon_open; - pmon_ops.to_wait = mips_wait; - - ddb_ops.to_shortname = "ddb"; - ddb_ops.to_doc = "\ -Debug a board using the PMON MIPS remote debugging protocol over a serial\n\ -line. The first argument is the device it is connected to or, if it contains\n\ -a colon, HOST:PORT to access a board over a network. The optional second\n\ -parameter is the temporary file in the form HOST:FILENAME to be used for\n\ -TFTP downloads to the board. The optional third parameter is the local name\n\ -of the TFTP temporary file, if it differs from the filename seen by the board."; - ddb_ops.to_open = ddb_open; - ddb_ops.to_wait = mips_wait; - - lsi_ops.to_shortname = "lsi"; - lsi_ops.to_doc = pmon_ops.to_doc; - lsi_ops.to_open = lsi_open; - lsi_ops.to_wait = mips_wait; - - /* Add the targets. */ - add_target (&mips_ops); - add_target (&pmon_ops); - add_target (&ddb_ops); - add_target (&lsi_ops); - - add_show_from_set ( - add_set_cmd ("timeout", no_class, var_zinteger, - (char *) &mips_receive_wait, - "Set timeout in seconds for remote MIPS serial I/O.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("retransmit-timeout", no_class, var_zinteger, - (char *) &mips_retransmit_wait, - "Set retransmit timeout in seconds for remote MIPS serial I/O.\n\ -This is the number of seconds to wait for an acknowledgement to a packet\n\ -before resending the packet.", &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("syn-garbage-limit", no_class, var_zinteger, - (char *) &mips_syn_garbage, - "Set the maximum number of characters to ignore when scanning for a SYN.\n\ -This is the maximum number of characters GDB will ignore when trying to\n\ -synchronize with the remote system. A value of -1 means that there is no limit\n\ -(Note that these characters are printed out even though they are ignored.)", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("monitor-prompt", class_obscure, var_string, - (char *) &mips_monitor_prompt, - "Set the prompt that GDB expects from the monitor.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("monitor-warnings", class_obscure, var_zinteger, - (char *) &monitor_warnings, - "Set printing of monitor warnings.\n" - "When enabled, monitor warnings about hardware breakpoints " - "will be displayed.", - &setlist), - &showlist); - - add_com ("pmon ", class_obscure, pmon_command, - "Send a packet to PMON (must be in debug mode)."); - - add_show_from_set (add_set_cmd ("mask-address", no_class, - var_boolean, &mask_address_p, - "Set zeroing of upper 32 bits of 64-bit addresses when talking to PMON targets.\n\ -Use \"on\" to enable the masking and \"off\" to disable it.\n", - &setlist), - &showlist); -} diff --git a/contrib/gdb/gdb/remote-rdp.c b/contrib/gdb/gdb/remote-rdp.c deleted file mode 100644 index 2f9183a9bc7..00000000000 --- a/contrib/gdb/gdb/remote-rdp.c +++ /dev/null @@ -1,1456 +0,0 @@ -/* Remote debugging for the ARM RDP interface. - - Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - - */ - - -/* - Much of this file (in particular the SWI stuff) is based on code by - David Taylor (djt1000@uk.ac.cam.hermes). - - I hacked on and simplified it by removing a lot of sexy features he - had added, and some of the (unix specific) workarounds he'd done - for other GDB problems - which if they still exist should be fixed - in GDB, not in a remote-foo thing . I also made it conform more to - the doc I have; which may be wrong. - - Steve Chamberlain (sac@cygnus.com). - */ - - -#include "defs.h" -#include "inferior.h" -#include "value.h" -#include "callback.h" -#include "command.h" -#include -#include -#include "symfile.h" -#include "remote-utils.h" -#include "gdb_string.h" -#include "gdbcore.h" -#include "regcache.h" -#include "serial.h" - -#include "arm-tdep.h" - -#ifdef HAVE_TIME_H -#include -#endif - -extern struct target_ops remote_rdp_ops; -static struct serial *io; -static host_callback *callback = &default_callback; - -struct - { - int step_info; - int break_info; - int model_info; - int target_info; - int can_step; - char command_line[10]; - int rdi_level; - int rdi_stopped_status; - } -ds; - - - -/* Definitions for the RDP protocol. */ - -#define RDP_MOUTHFULL (1<<6) -#define FPU_COPRO_NUMBER 1 - -#define RDP_OPEN 0 -#define RDP_OPEN_TYPE_COLD 0 -#define RDP_OPEN_TYPE_WARM 1 -#define RDP_OPEN_TYPE_BAUDRATE 2 - -#define RDP_OPEN_BAUDRATE_9600 1 -#define RDP_OPEN_BAUDRATE_19200 2 -#define RDP_OPEN_BAUDRATE_38400 3 - -#define RDP_OPEN_TYPE_RETURN_SEX (1<<3) - -#define RDP_CLOSE 1 - -#define RDP_MEM_READ 2 - -#define RDP_MEM_WRITE 3 - -#define RDP_CPU_READ 4 -#define RDP_CPU_WRITE 5 -#define RDP_CPU_READWRITE_MODE_CURRENT 255 -#define RDP_CPU_READWRITE_MASK_PC (1<<16) -#define RDP_CPU_READWRITE_MASK_CPSR (1<<17) -#define RDP_CPU_READWRITE_MASK_SPSR (1<<18) - -#define RDP_COPRO_READ 6 -#define RDP_COPRO_WRITE 7 -#define RDP_FPU_READWRITE_MASK_FPS (1<<8) - -#define RDP_SET_BREAK 0xa -#define RDP_SET_BREAK_TYPE_PC_EQUAL 0 -#define RDP_SET_BREAK_TYPE_GET_HANDLE (0x10) - -#define RDP_CLEAR_BREAK 0xb - -#define RDP_EXEC 0x10 -#define RDP_EXEC_TYPE_SYNC 0 - -#define RDP_STEP 0x11 - -#define RDP_INFO 0x12 -#define RDP_INFO_ABOUT_STEP 2 -#define RDP_INFO_ABOUT_STEP_GT_1 1 -#define RDP_INFO_ABOUT_STEP_TO_JMP 2 -#define RDP_INFO_ABOUT_STEP_1 4 -#define RDP_INFO_ABOUT_TARGET 0 -#define RDP_INFO_ABOUT_BREAK 1 -#define RDP_INFO_ABOUT_BREAK_COMP 1 -#define RDP_INFO_ABOUT_BREAK_RANGE 2 -#define RDP_INFO_ABOUT_BREAK_BYTE_READ 4 -#define RDP_INFO_ABOUT_BREAK_HALFWORD_READ 8 -#define RDP_INFO_ABOUT_BREAK_WORD_READ (1<<4) -#define RDP_INFO_ABOUT_BREAK_BYTE_WRITE (1<<5) -#define RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE (1<<6) -#define RDP_INFO_ABOUT_BREAK_WORD_WRITE (1<<7) -#define RDP_INFO_ABOUT_BREAK_MASK (1<<8) -#define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9) -#define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10) -#define RDP_INFO_ABOUT_BREAK_COND (1<<11) -#define RDP_INFO_VECTOR_CATCH (0x180) -#define RDP_INFO_ICEBREAKER (7) -#define RDP_INFO_SET_CMDLINE (0x300) - -#define RDP_SELECT_CONFIG (0x16) -#define RDI_ConfigCPU 0 -#define RDI_ConfigSystem 1 -#define RDI_MatchAny 0 -#define RDI_MatchExactly 1 -#define RDI_MatchNoEarlier 2 - -#define RDP_RESET 0x7f - -/* Returns from RDP */ -#define RDP_RES_STOPPED 0x20 -#define RDP_RES_SWI 0x21 -#define RDP_RES_FATAL 0x5e -#define RDP_RES_VALUE 0x5f -#define RDP_RES_VALUE_LITTLE_ENDIAN 240 -#define RDP_RES_VALUE_BIG_ENDIAN 241 -#define RDP_RES_RESET 0x7f -#define RDP_RES_AT_BREAKPOINT 143 -#define RDP_RES_IDUNNO 0xe6 -#define RDP_OSOpReply 0x13 -#define RDP_OSOpWord 2 -#define RDP_OSOpNothing 0 - -static int timeout = 2; - -static char *commandline = NULL; - -static int -remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, - struct mem_attrib *attrib, - struct target_ops *target); - - -/* Stuff for talking to the serial layer. */ - -static unsigned char -get_byte (void) -{ - int c = serial_readchar (io, timeout); - - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c); - - if (c == SERIAL_TIMEOUT) - { - if (timeout == 0) - return (unsigned char) c; - - error ("Timeout reading from remote_system"); - } - - return c; -} - -/* Note that the target always speaks little-endian to us, - even if it's a big endian machine. */ -static unsigned int -get_word (void) -{ - unsigned int val = 0; - unsigned int c; - int n; - for (n = 0; n < 4; n++) - { - c = get_byte (); - val |= c << (n * 8); - } - return val; -} - -static void -put_byte (char val) -{ - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "(%02x)\n", val); - serial_write (io, &val, 1); -} - -static void -put_word (int val) -{ - /* We always send in little endian */ - unsigned char b[4]; - b[0] = val; - b[1] = val >> 8; - b[2] = val >> 16; - b[3] = val >> 24; - - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "(%04x)", val); - - serial_write (io, b, 4); -} - - - -/* Stuff for talking to the RDP layer. */ - -/* This is a bit more fancy that need be so that it syncs even in nasty cases. - - I'be been unable to make it reliably sync up with the change - baudrate open command. It likes to sit and say it's been reset, - with no more action. So I took all that code out. I'd rather sync - reliably at 9600 than wait forever for a possible 19200 connection. - - */ -static void -rdp_init (int cold, int tty) -{ - int sync = 0; - int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM; - int baudtry = 9600; - - time_t now = time (0); - time_t stop_time = now + 10; /* Try and sync for 10 seconds, then give up */ - - - while (time (0) < stop_time && !sync) - { - int restype; - QUIT; - - serial_flush_input (io); - serial_flush_output (io); - - if (tty) - printf_unfiltered ("Trying to connect at %d baud.\n", baudtry); - - /* - ** It seems necessary to reset an EmbeddedICE to get it going. - ** This has the side benefit of displaying the startup banner. - */ - if (cold) - { - put_byte (RDP_RESET); - while ((restype = serial_readchar (io, 1)) > 0) - { - switch (restype) - { - case SERIAL_TIMEOUT: - break; - case RDP_RESET: - /* Sent at start of reset process: ignore */ - break; - default: - printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); - break; - } - } - - if (restype == 0) - { - /* Got end-of-banner mark */ - printf_filtered ("\n"); - } - } - - put_byte (RDP_OPEN); - - put_byte (type | RDP_OPEN_TYPE_RETURN_SEX); - put_word (0); - - while (!sync && (restype = serial_readchar (io, 1)) > 0) - { - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype); - - switch (restype) - { - case SERIAL_TIMEOUT: - break; - - case RDP_RESET: - while ((restype = serial_readchar (io, 1)) == RDP_RESET) - ; - do - { - printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); - } - while ((restype = serial_readchar (io, 1)) > 0); - - if (tty) - { - printf_unfiltered ("\nThe board has sent notification that it was reset.\n"); - printf_unfiltered ("Waiting for it to settle down...\n"); - } - sleep (3); - if (tty) - printf_unfiltered ("\nTrying again.\n"); - cold = 0; - break; - - default: - break; - - case RDP_RES_VALUE: - { - int resval = serial_readchar (io, 1); - - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval); - - switch (resval) - { - case SERIAL_TIMEOUT: - break; - case RDP_RES_VALUE_LITTLE_ENDIAN: - target_byte_order = BFD_ENDIAN_LITTLE; - sync = 1; - break; - case RDP_RES_VALUE_BIG_ENDIAN: - target_byte_order = BFD_ENDIAN_BIG; - sync = 1; - break; - default: - break; - } - } - } - } - } - - if (!sync) - { - error ("Couldn't reset the board, try pressing the reset button"); - } -} - - -void -send_rdp (char *template,...) -{ - char buf[200]; - char *dst = buf; - va_list alist; - va_start (alist, template); - - while (*template) - { - unsigned int val; - int *pi; - int *pstat; - char *pc; - int i; - switch (*template++) - { - case 'b': - val = va_arg (alist, int); - *dst++ = val; - break; - case 'w': - val = va_arg (alist, int); - *dst++ = val; - *dst++ = val >> 8; - *dst++ = val >> 16; - *dst++ = val >> 24; - break; - case 'S': - val = get_byte (); - if (val != RDP_RES_VALUE) - { - printf_unfiltered ("got bad res value of %d, %x\n", val, val); - } - break; - case 'V': - pstat = va_arg (alist, int *); - pi = va_arg (alist, int *); - - *pstat = get_byte (); - /* Check the result was zero, if not read the syndrome */ - if (*pstat) - { - *pi = get_word (); - } - break; - case 'Z': - /* Check the result code */ - switch (get_byte ()) - { - case 0: - /* Success */ - break; - case 253: - /* Target can't do it; never mind */ - printf_unfiltered ("RDP: Insufficient privilege\n"); - return; - case 254: - /* Target can't do it; never mind */ - printf_unfiltered ("RDP: Unimplemented message\n"); - return; - case 255: - error ("Command garbled"); - break; - default: - error ("Corrupt reply from target"); - break; - } - break; - case 'W': - /* Read a word from the target */ - pi = va_arg (alist, int *); - *pi = get_word (); - break; - case 'P': - /* Read in some bytes from the target. */ - pc = va_arg (alist, char *); - val = va_arg (alist, int); - for (i = 0; i < val; i++) - { - pc[i] = get_byte (); - } - break; - case 'p': - /* send what's being pointed at */ - pc = va_arg (alist, char *); - val = va_arg (alist, int); - dst = buf; - serial_write (io, pc, val); - break; - case '-': - /* Send whats in the queue */ - if (dst != buf) - { - serial_write (io, buf, dst - buf); - dst = buf; - } - break; - case 'B': - pi = va_arg (alist, int *); - *pi = get_byte (); - break; - default: - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } - } - va_end (alist); - - if (dst != buf) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); -} - - -static int -rdp_write (CORE_ADDR memaddr, char *buf, int len) -{ - int res; - int val; - - send_rdp ("bww-p-SV", RDP_MEM_WRITE, memaddr, len, buf, len, &res, &val); - - if (res) - { - return val; - } - return len; -} - - -static int -rdp_read (CORE_ADDR memaddr, char *buf, int len) -{ - int res; - int val; - send_rdp ("bww-S-P-V", - RDP_MEM_READ, memaddr, len, - buf, len, - &res, &val); - if (res) - { - return val; - } - return len; -} - -static void -rdp_fetch_one_register (int mask, char *buf) -{ - int val; - send_rdp ("bbw-SWZ", RDP_CPU_READ, RDP_CPU_READWRITE_MODE_CURRENT, mask, &val); - store_signed_integer (buf, 4, val); -} - -static void -rdp_fetch_one_fpu_register (int mask, char *buf) -{ -#if 0 - /* !!! Since the PIE board doesn't work as documented, - and it doesn't have FPU hardware anyway and since it - slows everything down, I've disabled this. */ - int val; - if (mask == RDP_FPU_READWRITE_MASK_FPS) - { - /* this guy is only a word */ - send_rdp ("bbw-SWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, &val); - store_signed_integer (buf, 4, val); - } - else - { - /* There are 12 bytes long - !! fixme about endianness - */ - int dummy; /* I've seen these come back as four words !! */ - send_rdp ("bbw-SWWWWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, buf + 0, buf + 4, buf + 8, &dummy); - } -#endif - memset (buf, 0, MAX_REGISTER_RAW_SIZE); -} - - -static void -rdp_store_one_register (int mask, char *buf) -{ - int val = extract_unsigned_integer (buf, 4); - - send_rdp ("bbww-SZ", - RDP_CPU_WRITE, RDP_CPU_READWRITE_MODE_CURRENT, mask, val); -} - - -static void -rdp_store_one_fpu_register (int mask, char *buf) -{ -#if 0 - /* See comment in fetch_one_fpu_register */ - if (mask == RDP_FPU_READWRITE_MASK_FPS) - { - int val = extract_unsigned_integer (buf, 4); - /* this guy is only a word */ - send_rdp ("bbww-SZ", RDP_COPRO_WRITE, - FPU_COPRO_NUMBER, - mask, val); - } - else - { - /* There are 12 bytes long - !! fixme about endianness - */ - int dummy = 0; - /* I've seen these come as four words, not the three advertized !! */ - printf ("Sending mask %x\n", mask); - send_rdp ("bbwwwww-SZ", - RDP_COPRO_WRITE, - FPU_COPRO_NUMBER, - mask, - *(int *) (buf + 0), - *(int *) (buf + 4), - *(int *) (buf + 8), - 0); - - printf ("done mask %x\n", mask); - } -#endif -} - - -/* Convert between GDB requests and the RDP layer. */ - -static void -remote_rdp_fetch_register (int regno) -{ - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - remote_rdp_fetch_register (regno); - } - else - { - char buf[MAX_REGISTER_RAW_SIZE]; - if (regno < 15) - rdp_fetch_one_register (1 << regno, buf); - else if (regno == ARM_PC_REGNUM) - rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_PC, buf); - else if (regno == ARM_PS_REGNUM) - rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_CPSR, buf); - else if (regno == ARM_FPS_REGNUM) - rdp_fetch_one_fpu_register (RDP_FPU_READWRITE_MASK_FPS, buf); - else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) - rdp_fetch_one_fpu_register (1 << (regno - ARM_F0_REGNUM), buf); - else - { - printf ("Help me with fetch reg %d\n", regno); - } - supply_register (regno, buf); - } -} - - -static void -remote_rdp_store_register (int regno) -{ - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - remote_rdp_store_register (regno); - } - else - { - char tmp[MAX_REGISTER_RAW_SIZE]; - read_register_gen (regno, tmp); - if (regno < 15) - rdp_store_one_register (1 << regno, tmp); - else if (regno == ARM_PC_REGNUM) - rdp_store_one_register (RDP_CPU_READWRITE_MASK_PC, tmp); - else if (regno == ARM_PS_REGNUM) - rdp_store_one_register (RDP_CPU_READWRITE_MASK_CPSR, tmp); - else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) - rdp_store_one_fpu_register (1 << (regno - ARM_F0_REGNUM), tmp); - else - { - printf ("Help me with reg %d\n", regno); - } - } -} - -static void -remote_rdp_kill (void) -{ - callback->shutdown (callback); -} - - -static void -rdp_info (void) -{ - send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_STEP, - &ds.step_info); - send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_BREAK, - &ds.break_info); - send_rdp ("bw-S-WW-Z", RDP_INFO, RDP_INFO_ABOUT_TARGET, - &ds.target_info, - &ds.model_info); - - ds.can_step = ds.step_info & RDP_INFO_ABOUT_STEP_1; - - ds.rdi_level = (ds.target_info >> 5) & 3; -} - - -static void -rdp_execute_start (void) -{ - /* Start it off, but don't wait for it */ - send_rdp ("bb-", RDP_EXEC, RDP_EXEC_TYPE_SYNC); -} - - -static void -rdp_set_command_line (char *command, char *args) -{ - /* - ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems - ** don't implement that, and get all confused at the unexpected text. - ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv - */ - - if (commandline != NULL) - xfree (commandline); - - xasprintf (&commandline, "%s %s", command, args); -} - -static void -rdp_catch_vectors (void) -{ - /* - ** We want the target monitor to intercept the abort vectors - ** i.e. stop the program if any of these are used. - */ - send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH, - /* - ** Specify a bitmask including - ** the reset vector - ** the undefined instruction vector - ** the prefetch abort vector - ** the data abort vector - ** the address exception vector - */ - (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) - ); -} - - - -#define a_byte 1 -#define a_word 2 -#define a_string 3 - - -typedef struct -{ - CORE_ADDR n; - const char *s; -} -argsin; - -#define ABYTE 1 -#define AWORD 2 -#define ASTRING 3 -#define ADDRLEN 4 - -#define SWI_WriteC 0x0 -#define SWI_Write0 0x2 -#define SWI_ReadC 0x4 -#define SWI_CLI 0x5 -#define SWI_GetEnv 0x10 -#define SWI_Exit 0x11 -#define SWI_EnterOS 0x16 - -#define SWI_GetErrno 0x60 -#define SWI_Clock 0x61 - -#define SWI_Time 0x63 -#define SWI_Remove 0x64 -#define SWI_Rename 0x65 -#define SWI_Open 0x66 - -#define SWI_Close 0x68 -#define SWI_Write 0x69 -#define SWI_Read 0x6a -#define SWI_Seek 0x6b -#define SWI_Flen 0x6c - -#define SWI_IsTTY 0x6e -#define SWI_TmpNam 0x6f -#define SWI_InstallHandler 0x70 -#define SWI_GenerateError 0x71 - - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -static int translate_open_mode[] = -{ - O_RDONLY, /* "r" */ - O_RDONLY + O_BINARY, /* "rb" */ - O_RDWR, /* "r+" */ - O_RDWR + O_BINARY, /* "r+b" */ - O_WRONLY + O_CREAT + O_TRUNC, /* "w" */ - O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */ - O_RDWR + O_CREAT + O_TRUNC, /* "w+" */ - O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */ - O_WRONLY + O_APPEND + O_CREAT, /* "a" */ - O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */ - O_RDWR + O_APPEND + O_CREAT, /* "a+" */ - O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */ -}; - -static int -exec_swi (int swi, argsin *args) -{ - int i; - char c; - switch (swi) - { - case SWI_WriteC: - callback->write_stdout (callback, &c, 1); - return 0; - case SWI_Write0: - for (i = 0; i < args->n; i++) - callback->write_stdout (callback, args->s, strlen (args->s)); - return 0; - case SWI_ReadC: - callback->read_stdin (callback, &c, 1); - args->n = c; - return 1; - case SWI_CLI: - args->n = callback->system (callback, args->s); - return 1; - case SWI_GetErrno: - args->n = callback->get_errno (callback); - return 1; - case SWI_Time: - args->n = callback->time (callback, NULL); - return 1; - - case SWI_Clock: - /* return number of centi-seconds... */ - args->n = -#ifdef CLOCKS_PER_SEC - (CLOCKS_PER_SEC >= 100) - ? (clock () / (CLOCKS_PER_SEC / 100)) - : ((clock () * 100) / CLOCKS_PER_SEC); -#else - /* presume unix... clock() returns microseconds */ - clock () / 10000; -#endif - return 1; - - case SWI_Remove: - args->n = callback->unlink (callback, args->s); - return 1; - case SWI_Rename: - args->n = callback->rename (callback, args[0].s, args[1].s); - return 1; - - case SWI_Open: - /* Now we need to decode the Demon open mode */ - i = translate_open_mode[args[1].n]; - - /* Filename ":tt" is special: it denotes stdin/out */ - if (strcmp (args->s, ":tt") == 0) - { - if (i == O_RDONLY) /* opening tty "r" */ - args->n = 0 /* stdin */ ; - else - args->n = 1 /* stdout */ ; - } - else - args->n = callback->open (callback, args->s, i); - return 1; - - case SWI_Close: - args->n = callback->close (callback, args->n); - return 1; - - case SWI_Write: - /* Return the number of bytes *not* written */ - args->n = args[1].n - - callback->write (callback, args[0].n, args[1].s, args[1].n); - return 1; - - case SWI_Read: - { - char *copy = alloca (args[2].n); - int done = callback->read (callback, args[0].n, copy, args[2].n); - if (done > 0) - remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0); - args->n = args[2].n - done; - return 1; - } - - case SWI_Seek: - /* Return non-zero on failure */ - args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0; - return 1; - - case SWI_Flen: - { - long old = callback->lseek (callback, args->n, 0, SEEK_CUR); - args->n = callback->lseek (callback, args->n, 0, SEEK_END); - callback->lseek (callback, args->n, old, 0); - return 1; - } - - case SWI_IsTTY: - args->n = callback->isatty (callback, args->n); - return 1; - - case SWI_GetEnv: - if (commandline != NULL) - { - int len = strlen (commandline); - if (len > 255) - { - len = 255; - commandline[255] = '\0'; - } - remote_rdp_xfer_inferior_memory (args[0].n, - commandline, len + 1, 1, 0, 0); - } - else - remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0); - return 1; - - default: - return 0; - } -} - - -static void -handle_swi (void) -{ - argsin args[3]; - char *buf; - int len; - int count = 0; - - int swino = get_word (); - int type = get_byte (); - while (type != 0) - { - switch (type & 0x3) - { - case ABYTE: - args[count].n = get_byte (); - break; - - case AWORD: - args[count].n = get_word (); - break; - - case ASTRING: - /* If the word is under 32 bytes it will be sent otherwise - an address to it is passed. Also: Special case of 255 */ - - len = get_byte (); - if (len > 32) - { - if (len == 255) - { - len = get_word (); - } - buf = alloca (len); - remote_rdp_xfer_inferior_memory (get_word (), - buf, - len, - 0, - 0, - 0); - } - else - { - int i; - buf = alloca (len + 1); - for (i = 0; i < len; i++) - buf[i] = get_byte (); - buf[i] = 0; - } - args[count].n = len; - args[count].s = buf; - break; - - default: - error ("Unimplemented SWI argument"); - } - - type = type >> 2; - count++; - } - - if (exec_swi (swino, args)) - { - /* We have two options here reply with either a byte or a word - which is stored in args[0].n. There is no harm in replying with - a word all the time, so thats what I do! */ - send_rdp ("bbw-", RDP_OSOpReply, RDP_OSOpWord, args[0].n); - } - else - { - send_rdp ("bb-", RDP_OSOpReply, RDP_OSOpNothing); - } -} - -static void -rdp_execute_finish (void) -{ - int running = 1; - - while (running) - { - int res; - res = serial_readchar (io, 1); - while (res == SERIAL_TIMEOUT) - { - QUIT; - printf_filtered ("Waiting for target..\n"); - res = serial_readchar (io, 1); - } - - switch (res) - { - case RDP_RES_SWI: - handle_swi (); - break; - case RDP_RES_VALUE: - send_rdp ("B", &ds.rdi_stopped_status); - running = 0; - break; - case RDP_RESET: - printf_filtered ("Target reset\n"); - running = 0; - break; - default: - printf_filtered ("Ignoring %x\n", res); - break; - } - } -} - - -static void -rdp_execute (void) -{ - rdp_execute_start (); - rdp_execute_finish (); -} - -static int -remote_rdp_insert_breakpoint (CORE_ADDR addr, char *save) -{ - int res; - if (ds.rdi_level > 0) - { - send_rdp ("bwb-SWB", - RDP_SET_BREAK, - addr, - RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE, - save, - &res); - } - else - { - send_rdp ("bwb-SB", - RDP_SET_BREAK, - addr, - RDP_SET_BREAK_TYPE_PC_EQUAL, - &res); - } - return res; -} - -static int -remote_rdp_remove_breakpoint (CORE_ADDR addr, char *save) -{ - int res; - if (ds.rdi_level > 0) - { - send_rdp ("b-p-S-B", - RDP_CLEAR_BREAK, - save, 4, - &res); - } - else - { - send_rdp ("bw-S-B", - RDP_CLEAR_BREAK, - addr, - &res); - } - return res; -} - -static void -rdp_step (void) -{ - if (ds.can_step && 0) - { - /* The pie board can't do steps so I can't test this, and - the other code will always work. */ - int status; - send_rdp ("bbw-S-B", - RDP_STEP, 0, 1, - &status); - } - else - { - char handle[4]; - CORE_ADDR pc = read_register (ARM_PC_REGNUM); - pc = arm_get_next_pc (pc); - remote_rdp_insert_breakpoint (pc, handle); - rdp_execute (); - remote_rdp_remove_breakpoint (pc, handle); - } -} - -static void -remote_rdp_open (char *args, int from_tty) -{ - int not_icebreaker; - - if (!args) - error_no_arg ("serial port device name"); - - baud_rate = 9600; - - target_preopen (from_tty); - - io = serial_open (args); - - if (!io) - perror_with_name (args); - - serial_raw (io); - - rdp_init (1, from_tty); - - - if (from_tty) - { - printf_unfiltered ("Remote RDP debugging using %s at %d baud\n", args, baud_rate); - } - - rdp_info (); - - /* Need to set up the vector interception state */ - rdp_catch_vectors (); - - /* - ** If it's an EmbeddedICE, we need to set the processor config. - ** Assume we can always have ARM7TDI... - */ - send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, ¬_icebreaker); - if (!not_icebreaker) - { - const char *CPU = "ARM7TDI"; - int ICEversion; - int len = strlen (CPU); - - send_rdp ("bbbbw-p-SWZ", - RDP_SELECT_CONFIG, - RDI_ConfigCPU, /* Aspect: set the CPU */ - len, /* The number of bytes in the name */ - RDI_MatchAny, /* We'll take whatever we get */ - 0, /* We'll take whatever version's there */ - CPU, len, - &ICEversion); - } - - /* command line initialised on 'run' */ - - push_target (&remote_rdp_ops); - - callback->init (callback); - flush_cached_frames (); - registers_changed (); - stop_pc = read_pc (); - set_current_frame (create_new_frame (read_fp (), stop_pc)); - select_frame (get_current_frame (), 0); - print_stack_frame (selected_frame, -1, 1); -} - - - -/* Close out all files and local state before this target loses control. */ - -static void -remote_rdp_close (int quitting) -{ - callback->shutdown (callback); - if (io) - serial_close (io); - io = 0; -} - - -/* Resume execution of the target process. STEP says whether to single-step - or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given - to the target, or zero for no signal. */ - -static void -remote_rdp_resume (ptid_t ptid, int step, enum target_signal siggnal) -{ - if (step) - rdp_step (); - else - rdp_execute (); -} - -/* Wait for inferior process to do something. Return pid of child, - or -1 in case of error; store status through argument pointer STATUS, - just as `wait' would. */ - -static ptid_t -remote_rdp_wait (ptid_t ptid, struct target_waitstatus *status) -{ - switch (ds.rdi_stopped_status) - { - default: - case RDP_RES_RESET: - case RDP_RES_SWI: - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = read_register (0); - break; - case RDP_RES_AT_BREAKPOINT: - status->kind = TARGET_WAITKIND_STOPPED; - /* The signal in sigrc is a host signal. That probably - should be fixed. */ - status->value.sig = TARGET_SIGNAL_TRAP; - break; -#if 0 - case rdp_signalled: - status->kind = TARGET_WAITKIND_SIGNALLED; - /* The signal in sigrc is a host signal. That probably - should be fixed. */ - status->value.sig = target_signal_from_host (sigrc); - break; -#endif - } - - return inferior_ptid; -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -remote_rdp_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If WRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - Returns the number of bytes transferred. */ - -static int -remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, struct mem_attrib *attrib, - struct target_ops *target) -{ - /* I infer from D Taylor's code that there's a limit on the amount - we can transfer in one chunk.. */ - int done = 0; - while (done < len) - { - int justdone; - int thisbite = len - done; - if (thisbite > RDP_MOUTHFULL) - thisbite = RDP_MOUTHFULL; - - QUIT; - - if (write) - { - justdone = rdp_write (memaddr + done, myaddr + done, thisbite); - } - else - { - justdone = rdp_read (memaddr + done, myaddr + done, thisbite); - } - - done += justdone; - - if (justdone != thisbite) - break; - } - return done; -} - - - -struct yn -{ - const char *name; - int bit; -}; -static struct yn stepinfo[] = -{ - {"Step more than one instruction", RDP_INFO_ABOUT_STEP_GT_1}, - {"Step to jump", RDP_INFO_ABOUT_STEP_TO_JMP}, - {"Step one instruction", RDP_INFO_ABOUT_STEP_1}, - {0} -}; - -static struct yn breakinfo[] = -{ - {"comparison breakpoints supported", RDP_INFO_ABOUT_BREAK_COMP}, - {"range breakpoints supported", RDP_INFO_ABOUT_BREAK_RANGE}, - {"watchpoints for byte reads supported", RDP_INFO_ABOUT_BREAK_BYTE_READ}, - {"watchpoints for half-word reads supported", RDP_INFO_ABOUT_BREAK_HALFWORD_READ}, - {"watchpoints for word reads supported", RDP_INFO_ABOUT_BREAK_WORD_READ}, - {"watchpoints for byte writes supported", RDP_INFO_ABOUT_BREAK_BYTE_WRITE}, - {"watchpoints for half-word writes supported", RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE}, - {"watchpoints for word writes supported", RDP_INFO_ABOUT_BREAK_WORD_WRITE}, - {"mask break/watch-points supported", RDP_INFO_ABOUT_BREAK_MASK}, -{"thread-specific breakpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_BREAK}, -{"thread-specific watchpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_WATCH}, - {"conditional breakpoints supported", RDP_INFO_ABOUT_BREAK_COND}, - {0} -}; - - -static void -dump_bits (struct yn *t, int info) -{ - while (t->name) - { - printf_unfiltered (" %-45s : %s\n", t->name, (info & t->bit) ? "Yes" : "No"); - t++; - } -} - -static void -remote_rdp_files_info (struct target_ops *target) -{ - printf_filtered ("Target capabilities:\n"); - dump_bits (stepinfo, ds.step_info); - dump_bits (breakinfo, ds.break_info); - printf_unfiltered ("target level RDI %x\n", (ds.target_info >> 5) & 3); -} - - -static void -remote_rdp_create_inferior (char *exec_file, char *allargs, char **env) -{ - CORE_ADDR entry_point; - - if (exec_file == 0 || exec_bfd == 0) - error ("No executable file specified."); - - entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd); - - remote_rdp_kill (); - remove_breakpoints (); - init_wait_for_inferior (); - - /* This gives us a chance to set up the command line */ - rdp_set_command_line (exec_file, allargs); - - inferior_ptid = pid_to_ptid (42); - insert_breakpoints (); /* Needed to get correct instruction in cache */ - - /* - ** RDP targets don't provide any facility to set the top of memory, - ** so we don't bother to look for MEMSIZE in the environment. - */ - - /* Let's go! */ - proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0); -} - -/* Accept any stray run/attach commands */ -static int -remote_rdp_can_run (void) -{ - return 1; -} - -/* Attach doesn't need to do anything */ -static void -remote_rdp_attach (char *args, int from_tty) -{ - return; -} - -/* Define the target subroutine names */ - -struct target_ops remote_rdp_ops; - -static void -init_remote_rdp_ops (void) -{ - remote_rdp_ops.to_shortname = "rdp"; - remote_rdp_ops.to_longname = "Remote Target using the RDProtocol"; - remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol"; - remote_rdp_ops.to_open = remote_rdp_open; - remote_rdp_ops.to_close = remote_rdp_close; - remote_rdp_ops.to_attach = remote_rdp_attach; - remote_rdp_ops.to_post_attach = NULL; - remote_rdp_ops.to_require_attach = NULL; - remote_rdp_ops.to_detach = NULL; - remote_rdp_ops.to_require_detach = NULL; - remote_rdp_ops.to_resume = remote_rdp_resume; - remote_rdp_ops.to_wait = remote_rdp_wait; - remote_rdp_ops.to_post_wait = NULL; - remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register; - remote_rdp_ops.to_store_registers = remote_rdp_store_register; - remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store; - remote_rdp_ops.to_xfer_memory = remote_rdp_xfer_inferior_memory; - remote_rdp_ops.to_files_info = remote_rdp_files_info; - remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint; - remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint; - remote_rdp_ops.to_terminal_init = NULL; - remote_rdp_ops.to_terminal_inferior = NULL; - remote_rdp_ops.to_terminal_ours_for_output = NULL; - remote_rdp_ops.to_terminal_ours = NULL; - remote_rdp_ops.to_terminal_info = NULL; - remote_rdp_ops.to_kill = remote_rdp_kill; - remote_rdp_ops.to_load = generic_load; - remote_rdp_ops.to_lookup_symbol = NULL; - remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior; - remote_rdp_ops.to_post_startup_inferior = NULL; - remote_rdp_ops.to_acknowledge_created_inferior = NULL; - remote_rdp_ops.to_clone_and_follow_inferior = NULL; - remote_rdp_ops.to_post_follow_inferior_by_clone = NULL; - remote_rdp_ops.to_insert_fork_catchpoint = NULL; - remote_rdp_ops.to_remove_fork_catchpoint = NULL; - remote_rdp_ops.to_insert_vfork_catchpoint = NULL; - remote_rdp_ops.to_remove_vfork_catchpoint = NULL; - remote_rdp_ops.to_has_forked = NULL; - remote_rdp_ops.to_has_vforked = NULL; - remote_rdp_ops.to_can_follow_vfork_prior_to_exec = NULL; - remote_rdp_ops.to_post_follow_vfork = NULL; - remote_rdp_ops.to_insert_exec_catchpoint = NULL; - remote_rdp_ops.to_remove_exec_catchpoint = NULL; - remote_rdp_ops.to_has_execd = NULL; - remote_rdp_ops.to_reported_exec_events_per_exec_call = NULL; - remote_rdp_ops.to_has_exited = NULL; - remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior; - remote_rdp_ops.to_can_run = remote_rdp_can_run; - remote_rdp_ops.to_notice_signals = 0; - remote_rdp_ops.to_thread_alive = 0; - remote_rdp_ops.to_stop = 0; - remote_rdp_ops.to_pid_to_exec_file = NULL; - remote_rdp_ops.to_stratum = process_stratum; - remote_rdp_ops.DONT_USE = NULL; - remote_rdp_ops.to_has_all_memory = 1; - remote_rdp_ops.to_has_memory = 1; - remote_rdp_ops.to_has_stack = 1; - remote_rdp_ops.to_has_registers = 1; - remote_rdp_ops.to_has_execution = 1; - remote_rdp_ops.to_sections = NULL; - remote_rdp_ops.to_sections_end = NULL; - remote_rdp_ops.to_magic = OPS_MAGIC; -} - -void -_initialize_remote_rdp (void) -{ - init_remote_rdp_ops (); - add_target (&remote_rdp_ops); -} diff --git a/contrib/gdb/gdb/remote-sim.c b/contrib/gdb/gdb/remote-sim.c deleted file mode 100644 index 1d037c8fa79..00000000000 --- a/contrib/gdb/gdb/remote-sim.c +++ /dev/null @@ -1,941 +0,0 @@ -/* Generic remote debugging interface for simulators. - - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation, Inc. - - Contributed by Cygnus Support. - Steve Chamberlain (sac@cygnus.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "value.h" -#include "gdb_string.h" -#include -#include -#include -#include -#include -#include "terminal.h" -#include "target.h" -#include "gdbcore.h" -#include "callback.h" -#include "remote-sim.h" -#include "remote-utils.h" -#include "command.h" -#include "regcache.h" - -/* Prototypes */ - -extern void _initialize_remote_sim (void); - -extern int (*ui_loop_hook) (int signo); - -static void dump_mem (char *buf, int len); - -static void init_callbacks (void); - -static void end_callbacks (void); - -static int gdb_os_write_stdout (host_callback *, const char *, int); - -static void gdb_os_flush_stdout (host_callback *); - -static int gdb_os_write_stderr (host_callback *, const char *, int); - -static void gdb_os_flush_stderr (host_callback *); - -static int gdb_os_poll_quit (host_callback *); - -/* printf_filtered is depreciated */ -static void gdb_os_printf_filtered (host_callback *, const char *, ...); - -static void gdb_os_vprintf_filtered (host_callback *, const char *, va_list); - -static void gdb_os_evprintf_filtered (host_callback *, const char *, va_list); - -static void gdb_os_error (host_callback *, const char *, ...); - -static void gdbsim_fetch_register (int regno); - -static void gdbsim_store_register (int regno); - -static void gdbsim_kill (void); - -static void gdbsim_load (char *prog, int fromtty); - -static void gdbsim_create_inferior (char *exec_file, char *args, char **env); - -static void gdbsim_open (char *args, int from_tty); - -static void gdbsim_close (int quitting); - -static void gdbsim_detach (char *args, int from_tty); - -static void gdbsim_resume (ptid_t ptid, int step, enum target_signal siggnal); - -static ptid_t gdbsim_wait (ptid_t ptid, struct target_waitstatus *status); - -static void gdbsim_prepare_to_store (void); - -static int gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, - int len, int write, - struct mem_attrib *attrib, - struct target_ops *target); - -static void gdbsim_files_info (struct target_ops *target); - -static void gdbsim_mourn_inferior (void); - -static void gdbsim_stop (void); - -void simulator_command (char *args, int from_tty); - -/* Naming convention: - - sim_* are the interface to the simulator (see remote-sim.h). - gdbsim_* are stuff which is internal to gdb. */ - -/* Forward data declarations */ -extern struct target_ops gdbsim_ops; - -static int program_loaded = 0; - -/* We must keep track of whether the simulator has been opened or not because - GDB can call a target's close routine twice, but sim_close doesn't allow - this. We also need to record the result of sim_open so we can pass it - back to the other sim_foo routines. */ -static SIM_DESC gdbsim_desc = 0; - -static void -dump_mem (char *buf, int len) -{ - if (len <= 8) - { - if (len == 8 || len == 4) - { - long l[2]; - memcpy (l, buf, len); - printf_filtered ("\t0x%lx", l[0]); - if (len == 8) - printf_filtered (" 0x%lx", l[1]); - printf_filtered ("\n"); - } - else - { - int i; - printf_filtered ("\t"); - for (i = 0; i < len; i++) - printf_filtered ("0x%x ", buf[i]); - printf_filtered ("\n"); - } - } -} - -static host_callback gdb_callback; -static int callbacks_initialized = 0; - -/* Initialize gdb_callback. */ - -static void -init_callbacks (void) -{ - if (!callbacks_initialized) - { - gdb_callback = default_callback; - gdb_callback.init (&gdb_callback); - gdb_callback.write_stdout = gdb_os_write_stdout; - gdb_callback.flush_stdout = gdb_os_flush_stdout; - gdb_callback.write_stderr = gdb_os_write_stderr; - gdb_callback.flush_stderr = gdb_os_flush_stderr; - gdb_callback.printf_filtered = gdb_os_printf_filtered; - gdb_callback.vprintf_filtered = gdb_os_vprintf_filtered; - gdb_callback.evprintf_filtered = gdb_os_evprintf_filtered; - gdb_callback.error = gdb_os_error; - gdb_callback.poll_quit = gdb_os_poll_quit; - gdb_callback.magic = HOST_CALLBACK_MAGIC; - callbacks_initialized = 1; - } -} - -/* Release callbacks (free resources used by them). */ - -static void -end_callbacks (void) -{ - if (callbacks_initialized) - { - gdb_callback.shutdown (&gdb_callback); - callbacks_initialized = 0; - } -} - -/* GDB version of os_write_stdout callback. */ - -static int -gdb_os_write_stdout (host_callback *p, const char *buf, int len) -{ - int i; - char b[2]; - - ui_file_write (gdb_stdtarg, buf, len); - return len; -} - -/* GDB version of os_flush_stdout callback. */ - -static void -gdb_os_flush_stdout (host_callback *p) -{ - gdb_flush (gdb_stdtarg); -} - -/* GDB version of os_write_stderr callback. */ - -static int -gdb_os_write_stderr (host_callback *p, const char *buf, int len) -{ - int i; - char b[2]; - - for (i = 0; i < len; i++) - { - b[0] = buf[i]; - b[1] = 0; - fputs_unfiltered (b, gdb_stdtarg); - } - return len; -} - -/* GDB version of os_flush_stderr callback. */ - -static void -gdb_os_flush_stderr (host_callback *p) -{ - gdb_flush (gdb_stderr); -} - -/* GDB version of printf_filtered callback. */ - -static void -gdb_os_printf_filtered (host_callback * p, const char *format,...) -{ - va_list args; - va_start (args, format); - - vfprintf_filtered (gdb_stdout, format, args); - - va_end (args); -} - -/* GDB version of error vprintf_filtered. */ - -static void -gdb_os_vprintf_filtered (host_callback * p, const char *format, va_list ap) -{ - vfprintf_filtered (gdb_stdout, format, ap); -} - -/* GDB version of error evprintf_filtered. */ - -static void -gdb_os_evprintf_filtered (host_callback * p, const char *format, va_list ap) -{ - vfprintf_filtered (gdb_stderr, format, ap); -} - -/* GDB version of error callback. */ - -static void -gdb_os_error (host_callback * p, const char *format,...) -{ - if (error_hook) - (*error_hook) (); - else - { - va_list args; - va_start (args, format); - verror (format, args); - va_end (args); - } -} - -static void -gdbsim_fetch_register (int regno) -{ - static int warn_user = 1; - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - gdbsim_fetch_register (regno); - } - else if (REGISTER_NAME (regno) != NULL - && *REGISTER_NAME (regno) != '\0') - { - char buf[MAX_REGISTER_RAW_SIZE]; - int nr_bytes; - if (REGISTER_SIM_REGNO (regno) >= 0) - nr_bytes = sim_fetch_register (gdbsim_desc, - REGISTER_SIM_REGNO (regno), - buf, REGISTER_RAW_SIZE (regno)); - else - nr_bytes = 0; - if (nr_bytes == 0) - /* register not applicable, supply zero's */ - memset (buf, 0, MAX_REGISTER_RAW_SIZE); - else if (nr_bytes > 0 && nr_bytes != REGISTER_RAW_SIZE (regno) - && warn_user) - { - fprintf_unfiltered (gdb_stderr, - "Size of register %s (%d/%d) incorrect (%d instead of %d))", - REGISTER_NAME (regno), - regno, REGISTER_SIM_REGNO (regno), - nr_bytes, REGISTER_RAW_SIZE (regno)); - warn_user = 0; - } - supply_register (regno, buf); - if (sr_get_debug ()) - { - printf_filtered ("gdbsim_fetch_register: %d", regno); - /* FIXME: We could print something more intelligible. */ - dump_mem (buf, REGISTER_RAW_SIZE (regno)); - } - } -} - - -static void -gdbsim_store_register (int regno) -{ - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - gdbsim_store_register (regno); - } - else if (REGISTER_NAME (regno) != NULL - && *REGISTER_NAME (regno) != '\0' - && REGISTER_SIM_REGNO (regno) >= 0) - { - char tmp[MAX_REGISTER_RAW_SIZE]; - int nr_bytes; - read_register_gen (regno, tmp); - nr_bytes = sim_store_register (gdbsim_desc, - REGISTER_SIM_REGNO (regno), - tmp, REGISTER_RAW_SIZE (regno)); - if (nr_bytes > 0 && nr_bytes != REGISTER_RAW_SIZE (regno)) - internal_error (__FILE__, __LINE__, - "Register size different to expected"); - if (sr_get_debug ()) - { - printf_filtered ("gdbsim_store_register: %d", regno); - /* FIXME: We could print something more intelligible. */ - dump_mem (tmp, REGISTER_RAW_SIZE (regno)); - } - } -} - -/* Kill the running program. This may involve closing any open files - and releasing other resources acquired by the simulated program. */ - -static void -gdbsim_kill (void) -{ - if (sr_get_debug ()) - printf_filtered ("gdbsim_kill\n"); - - /* There is no need to `kill' running simulator - the simulator is - not running */ - inferior_ptid = null_ptid; -} - -/* Load an executable file into the target process. This is expected to - not only bring new code into the target process, but also to update - GDB's symbol tables to match. */ - -static void -gdbsim_load (char *prog, int fromtty) -{ - if (sr_get_debug ()) - printf_filtered ("gdbsim_load: prog \"%s\"\n", prog); - - inferior_ptid = null_ptid; - - /* FIXME: We will print two messages on error. - Need error to either not print anything if passed NULL or need - another routine that doesn't take any arguments. */ - if (sim_load (gdbsim_desc, prog, NULL, fromtty) == SIM_RC_FAIL) - error ("unable to load program"); - - /* FIXME: If a load command should reset the targets registers then - a call to sim_create_inferior() should go here. */ - - program_loaded = 1; -} - - -/* Start an inferior process and set inferior_ptid to its pid. - EXEC_FILE is the file to run. - ARGS is a string containing the arguments to the program. - ENV is the environment vector to pass. Errors reported with error(). - On VxWorks and various standalone systems, we ignore exec_file. */ -/* This is called not only when we first attach, but also when the - user types "run" after having attached. */ - -static void -gdbsim_create_inferior (char *exec_file, char *args, char **env) -{ - int len; - char *arg_buf, **argv; - - if (exec_file == 0 || exec_bfd == 0) - warning ("No executable file specified."); - if (!program_loaded) - warning ("No program loaded."); - - if (sr_get_debug ()) - printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n", - (exec_file ? exec_file : "(NULL)"), - args); - - gdbsim_kill (); - remove_breakpoints (); - init_wait_for_inferior (); - - if (exec_file != NULL) - { - len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10; - arg_buf = (char *) alloca (len); - arg_buf[0] = '\0'; - strcat (arg_buf, exec_file); - strcat (arg_buf, " "); - strcat (arg_buf, args); - argv = buildargv (arg_buf); - make_cleanup_freeargv (argv); - } - else - argv = NULL; - sim_create_inferior (gdbsim_desc, exec_bfd, argv, env); - - inferior_ptid = pid_to_ptid (42); - insert_breakpoints (); /* Needed to get correct instruction in cache */ - - clear_proceed_status (); - - /* NB: Entry point already set by sim_create_inferior. */ - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); -} - -/* The open routine takes the rest of the parameters from the command, - and (if successful) pushes a new target onto the stack. - Targets should supply this routine, if only to provide an error message. */ -/* Called when selecting the simulator. EG: (gdb) target sim name. */ - -static void -gdbsim_open (char *args, int from_tty) -{ - int len; - char *arg_buf; - char **argv; - - if (sr_get_debug ()) - printf_filtered ("gdbsim_open: args \"%s\"\n", args ? args : "(null)"); - - /* Remove current simulator if one exists. Only do this if the simulator - has been opened because sim_close requires it. - This is important because the call to push_target below will cause - sim_close to be called if the simulator is already open, but push_target - is called after sim_open! We can't move the call to push_target before - the call to sim_open because sim_open may invoke `error'. */ - if (gdbsim_desc != NULL) - unpush_target (&gdbsim_ops); - - len = (7 + 1 /* gdbsim */ - + strlen (" -E little") - + strlen (" --architecture=xxxxxxxxxx") - + (args ? strlen (args) : 0) - + 50) /* slack */ ; - arg_buf = (char *) alloca (len); - strcpy (arg_buf, "gdbsim"); /* 7 */ - /* Specify the byte order for the target when it is both selectable - and explicitly specified by the user (not auto detected). */ - if (!TARGET_BYTE_ORDER_AUTO) - { - switch (TARGET_BYTE_ORDER) - { - case BFD_ENDIAN_BIG: - strcat (arg_buf, " -E big"); - break; - case BFD_ENDIAN_LITTLE: - strcat (arg_buf, " -E little"); - break; - default: - internal_error (__FILE__, __LINE__, - "Value of TARGET_BYTE_ORDER unknown"); - } - } - /* Specify the architecture of the target when it has been - explicitly specified */ - if (!TARGET_ARCHITECTURE_AUTO) - { - strcat (arg_buf, " --architecture="); - strcat (arg_buf, TARGET_ARCHITECTURE->printable_name); - } - /* finally, any explicit args */ - if (args) - { - strcat (arg_buf, " "); /* 1 */ - strcat (arg_buf, args); - } - argv = buildargv (arg_buf); - if (argv == NULL) - error ("Insufficient memory available to allocate simulator arg list."); - make_cleanup_freeargv (argv); - - init_callbacks (); - gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, argv); - - if (gdbsim_desc == 0) - error ("unable to create simulator instance"); - - push_target (&gdbsim_ops); - target_fetch_registers (-1); - printf_filtered ("Connected to the simulator.\n"); -} - -/* Does whatever cleanup is required for a target that we are no longer - going to be calling. Argument says whether we are quitting gdb and - should not get hung in case of errors, or whether we want a clean - termination even if it takes a while. This routine is automatically - always called just before a routine is popped off the target stack. - Closing file descriptors and freeing memory are typical things it should - do. */ -/* Close out all files and local state before this target loses control. */ - -static void -gdbsim_close (int quitting) -{ - if (sr_get_debug ()) - printf_filtered ("gdbsim_close: quitting %d\n", quitting); - - program_loaded = 0; - - if (gdbsim_desc != NULL) - { - sim_close (gdbsim_desc, quitting); - gdbsim_desc = NULL; - } - - end_callbacks (); - generic_mourn_inferior (); -} - -/* Takes a program previously attached to and detaches it. - The program may resume execution (some targets do, some don't) and will - no longer stop on signals, etc. We better not have left any breakpoints - in the program or it'll die when it hits one. ARGS is arguments - typed by the user (e.g. a signal to send the process). FROM_TTY - says whether to be verbose or not. */ -/* Terminate the open connection to the remote debugger. - Use this when you want to detach and do something else with your gdb. */ - -static void -gdbsim_detach (char *args, int from_tty) -{ - if (sr_get_debug ()) - printf_filtered ("gdbsim_detach: args \"%s\"\n", args); - - pop_target (); /* calls gdbsim_close to do the real work */ - if (from_tty) - printf_filtered ("Ending simulator %s debugging\n", target_shortname); -} - -/* Resume execution of the target process. STEP says whether to single-step - or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given - to the target, or zero for no signal. */ - -static enum target_signal resume_siggnal; -static int resume_step; - -static void -gdbsim_resume (ptid_t ptid, int step, enum target_signal siggnal) -{ - if (PIDGET (inferior_ptid) != 42) - error ("The program is not being run."); - - if (sr_get_debug ()) - printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal); - - resume_siggnal = siggnal; - resume_step = step; -} - -/* Notify the simulator of an asynchronous request to stop. - - The simulator shall ensure that the stop request is eventually - delivered to the simulator. If the call is made while the - simulator is not running then the stop request is processed when - the simulator is next resumed. - - For simulators that do not support this operation, just abort */ - -static void -gdbsim_stop (void) -{ - if (!sim_stop (gdbsim_desc)) - { - quit (); - } -} - -/* GDB version of os_poll_quit callback. - Taken from gdb/util.c - should be in a library */ - -static int -gdb_os_poll_quit (host_callback *p) -{ - if (ui_loop_hook != NULL) - ui_loop_hook (0); - - if (quit_flag) /* gdb's idea of quit */ - { - quit_flag = 0; /* we've stolen it */ - return 1; - } - else if (immediate_quit) - { - return 1; - } - return 0; -} - -/* Wait for inferior process to do something. Return pid of child, - or -1 in case of error; store status through argument pointer STATUS, - just as `wait' would. */ - -static void -gdbsim_cntrl_c (int signo) -{ - gdbsim_stop (); -} - -static ptid_t -gdbsim_wait (ptid_t ptid, struct target_waitstatus *status) -{ - static RETSIGTYPE (*prev_sigint) (); - int sigrc = 0; - enum sim_stop reason = sim_running; - - if (sr_get_debug ()) - printf_filtered ("gdbsim_wait\n"); - -#if defined (HAVE_SIGACTION) && defined (SA_RESTART) - { - struct sigaction sa, osa; - sa.sa_handler = gdbsim_cntrl_c; - sigemptyset (&sa.sa_mask); - sa.sa_flags = 0; - sigaction (SIGINT, &sa, &osa); - prev_sigint = osa.sa_handler; - } -#else - prev_sigint = signal (SIGINT, gdbsim_cntrl_c); -#endif - sim_resume (gdbsim_desc, resume_step, - target_signal_to_host (resume_siggnal)); - signal (SIGINT, prev_sigint); - resume_step = 0; - - sim_stop_reason (gdbsim_desc, &reason, &sigrc); - - switch (reason) - { - case sim_exited: - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = sigrc; - break; - case sim_stopped: - switch (sigrc) - { - case SIGABRT: - quit (); - break; - case SIGINT: - case SIGTRAP: - default: - status->kind = TARGET_WAITKIND_STOPPED; - /* The signal in sigrc is a host signal. That probably - should be fixed. */ - status->value.sig = target_signal_from_host (sigrc); - break; - } - break; - case sim_signalled: - status->kind = TARGET_WAITKIND_SIGNALLED; - /* The signal in sigrc is a host signal. That probably - should be fixed. */ - status->value.sig = target_signal_from_host (sigrc); - break; - case sim_running: - case sim_polling: - /* FIXME: Is this correct? */ - break; - } - - return inferior_ptid; -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -gdbsim_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If WRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - Returns the number of bytes transferred. */ - -static int -gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, struct mem_attrib *attrib, - struct target_ops *target) -{ - if (!program_loaded) - error ("No program loaded."); - - if (sr_get_debug ()) - { - /* FIXME: Send to something other than STDOUT? */ - printf_filtered ("gdbsim_xfer_inferior_memory: myaddr 0x"); - gdb_print_host_address (myaddr, gdb_stdout); - printf_filtered (", memaddr 0x%s, len %d, write %d\n", - paddr_nz (memaddr), len, write); - if (sr_get_debug () && write) - dump_mem (myaddr, len); - } - - if (write) - { - len = sim_write (gdbsim_desc, memaddr, myaddr, len); - } - else - { - len = sim_read (gdbsim_desc, memaddr, myaddr, len); - if (sr_get_debug () && len > 0) - dump_mem (myaddr, len); - } - return len; -} - -static void -gdbsim_files_info (struct target_ops *target) -{ - char *file = "nothing"; - - if (exec_bfd) - file = bfd_get_filename (exec_bfd); - - if (sr_get_debug ()) - printf_filtered ("gdbsim_files_info: file \"%s\"\n", file); - - if (exec_bfd) - { - printf_filtered ("\tAttached to %s running program %s\n", - target_shortname, file); - sim_info (gdbsim_desc, 0); - } -} - -/* Clear the simulator's notion of what the break points are. */ - -static void -gdbsim_mourn_inferior (void) -{ - if (sr_get_debug ()) - printf_filtered ("gdbsim_mourn_inferior:\n"); - - remove_breakpoints (); - generic_mourn_inferior (); -} - -static int -gdbsim_insert_breakpoint (CORE_ADDR addr, char *contents_cache) -{ -#ifdef SIM_HAS_BREAKPOINTS - SIM_RC retcode; - - retcode = sim_set_breakpoint (gdbsim_desc, addr); - - switch (retcode) - { - case SIM_RC_OK: - return 0; - case SIM_RC_INSUFFICIENT_RESOURCES: - return ENOMEM; - default: - return EIO; - } -#else - return memory_insert_breakpoint (addr, contents_cache); -#endif -} - -static int -gdbsim_remove_breakpoint (CORE_ADDR addr, char *contents_cache) -{ -#ifdef SIM_HAS_BREAKPOINTS - SIM_RC retcode; - - retcode = sim_clear_breakpoint (gdbsim_desc, addr); - - switch (retcode) - { - case SIM_RC_OK: - case SIM_RC_UNKNOWN_BREAKPOINT: - return 0; - case SIM_RC_INSUFFICIENT_RESOURCES: - return ENOMEM; - default: - return EIO; - } -#else - return memory_remove_breakpoint (addr, contents_cache); -#endif -} - -/* Pass the command argument through to the simulator verbatim. The - simulator must do any command interpretation work. */ - -void -simulator_command (char *args, int from_tty) -{ - if (gdbsim_desc == NULL) - { - - /* PREVIOUSLY: The user may give a command before the simulator - is opened. [...] (??? assuming of course one wishes to - continue to allow commands to be sent to unopened simulators, - which isn't entirely unreasonable). */ - - /* The simulator is a builtin abstraction of a remote target. - Consistent with that model, access to the simulator, via sim - commands, is restricted to the period when the channel to the - simulator is open. */ - - error ("Not connected to the simulator target"); - } - - sim_do_command (gdbsim_desc, args); - - /* Invalidate the register cache, in case the simulator command does - something funny. */ - registers_changed (); -} - -/* Define the target subroutine names */ - -struct target_ops gdbsim_ops; - -static void -init_gdbsim_ops (void) -{ - gdbsim_ops.to_shortname = "sim"; - gdbsim_ops.to_longname = "simulator"; - gdbsim_ops.to_doc = "Use the compiled-in simulator."; - gdbsim_ops.to_open = gdbsim_open; - gdbsim_ops.to_close = gdbsim_close; - gdbsim_ops.to_attach = NULL; - gdbsim_ops.to_post_attach = NULL; - gdbsim_ops.to_require_attach = NULL; - gdbsim_ops.to_detach = gdbsim_detach; - gdbsim_ops.to_require_detach = NULL; - gdbsim_ops.to_resume = gdbsim_resume; - gdbsim_ops.to_wait = gdbsim_wait; - gdbsim_ops.to_post_wait = NULL; - gdbsim_ops.to_fetch_registers = gdbsim_fetch_register; - gdbsim_ops.to_store_registers = gdbsim_store_register; - gdbsim_ops.to_prepare_to_store = gdbsim_prepare_to_store; - gdbsim_ops.to_xfer_memory = gdbsim_xfer_inferior_memory; - gdbsim_ops.to_files_info = gdbsim_files_info; - gdbsim_ops.to_insert_breakpoint = gdbsim_insert_breakpoint; - gdbsim_ops.to_remove_breakpoint = gdbsim_remove_breakpoint; - gdbsim_ops.to_terminal_init = NULL; - gdbsim_ops.to_terminal_inferior = NULL; - gdbsim_ops.to_terminal_ours_for_output = NULL; - gdbsim_ops.to_terminal_ours = NULL; - gdbsim_ops.to_terminal_info = NULL; - gdbsim_ops.to_kill = gdbsim_kill; - gdbsim_ops.to_load = gdbsim_load; - gdbsim_ops.to_lookup_symbol = NULL; - gdbsim_ops.to_create_inferior = gdbsim_create_inferior; - gdbsim_ops.to_post_startup_inferior = NULL; - gdbsim_ops.to_acknowledge_created_inferior = NULL; - gdbsim_ops.to_clone_and_follow_inferior = NULL; - gdbsim_ops.to_post_follow_inferior_by_clone = NULL; - gdbsim_ops.to_insert_fork_catchpoint = NULL; - gdbsim_ops.to_remove_fork_catchpoint = NULL; - gdbsim_ops.to_insert_vfork_catchpoint = NULL; - gdbsim_ops.to_remove_vfork_catchpoint = NULL; - gdbsim_ops.to_has_forked = NULL; - gdbsim_ops.to_has_vforked = NULL; - gdbsim_ops.to_can_follow_vfork_prior_to_exec = NULL; - gdbsim_ops.to_post_follow_vfork = NULL; - gdbsim_ops.to_insert_exec_catchpoint = NULL; - gdbsim_ops.to_remove_exec_catchpoint = NULL; - gdbsim_ops.to_has_execd = NULL; - gdbsim_ops.to_reported_exec_events_per_exec_call = NULL; - gdbsim_ops.to_has_exited = NULL; - gdbsim_ops.to_mourn_inferior = gdbsim_mourn_inferior; - gdbsim_ops.to_can_run = 0; - gdbsim_ops.to_notice_signals = 0; - gdbsim_ops.to_thread_alive = 0; - gdbsim_ops.to_stop = gdbsim_stop; - gdbsim_ops.to_pid_to_exec_file = NULL; - gdbsim_ops.to_stratum = process_stratum; - gdbsim_ops.DONT_USE = NULL; - gdbsim_ops.to_has_all_memory = 1; - gdbsim_ops.to_has_memory = 1; - gdbsim_ops.to_has_stack = 1; - gdbsim_ops.to_has_registers = 1; - gdbsim_ops.to_has_execution = 1; - gdbsim_ops.to_sections = NULL; - gdbsim_ops.to_sections_end = NULL; - gdbsim_ops.to_magic = OPS_MAGIC; - -#ifdef TARGET_REDEFINE_DEFAULT_OPS - TARGET_REDEFINE_DEFAULT_OPS (&gdbsim_ops); -#endif -} - -void -_initialize_remote_sim (void) -{ - init_gdbsim_ops (); - add_target (&gdbsim_ops); - - add_com ("sim ", class_obscure, simulator_command, - "Send a command to the simulator."); -} diff --git a/contrib/gdb/gdb/remote-st.c b/contrib/gdb/gdb/remote-st.c deleted file mode 100644 index 46d8eab15a2..00000000000 --- a/contrib/gdb/gdb/remote-st.c +++ /dev/null @@ -1,837 +0,0 @@ -/* Remote debugging interface for Tandem ST2000 phone switch, for GDB. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. - - Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This file was derived from remote-eb.c, which did a similar job, but for - an AMD-29K running EBMON. That file was in turn derived from remote.c - as mentioned in the following comment (left in for comic relief): - - "This is like remote.c but is for an esoteric situation-- - having an a29k board in a PC hooked up to a unix machine with - a serial line, and running ctty com1 on the PC, through which - the unix machine can run ebmon. Not to mention that the PC - has PC/NFS, so it can access the same executables that gdb can, - over the net in real time." - - In reality, this module talks to a debug monitor called 'STDEBUG', which - runs in a phone switch. We communicate with STDEBUG via either a direct - serial line, or a TCP (or possibly TELNET) stream to a terminal multiplexor, - which in turn talks to the phone switch. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "gdb_string.h" -#include -#include "serial.h" -#include "regcache.h" - -extern struct target_ops st2000_ops; /* Forward declaration */ - -static void st2000_close (); -static void st2000_fetch_register (); -static void st2000_store_register (); - -#define LOG_FILE "st2000.log" -#if defined (LOG_FILE) -FILE *log_file; -#endif - -static int timeout = 24; - -/* Descriptor for I/O to remote machine. Initialize it to -1 so that - st2000_open knows that we don't have a file open when the program - starts. */ - -static struct serial *st2000_desc; - -/* Send data to stdebug. Works just like printf. */ - -static void -printf_stdebug (char *pattern,...) -{ - va_list args; - char buf[200]; - - va_start (args, pattern); - - vsprintf (buf, pattern, args); - va_end (args); - - if (serial_write (st2000_desc, buf, strlen (buf))) - fprintf (stderr, "serial_write failed: %s\n", safe_strerror (errno)); -} - -/* Read a character from the remote system, doing all the fancy timeout - stuff. */ - -static int -readchar (int timeout) -{ - int c; - - c = serial_readchar (st2000_desc, timeout); - -#ifdef LOG_FILE - putc (c & 0x7f, log_file); -#endif - - if (c >= 0) - return c & 0x7f; - - if (c == SERIAL_TIMEOUT) - { - if (timeout == 0) - return c; /* Polls shouldn't generate timeout errors */ - - error ("Timeout reading from remote system."); - } - - perror_with_name ("remote-st2000"); -} - -/* Scan input from the remote system, until STRING is found. If DISCARD is - non-zero, then discard non-matching input, else print it out. - Let the user break out immediately. */ -static void -expect (char *string, int discard) -{ - char *p = string; - int c; - - immediate_quit++; - while (1) - { - c = readchar (timeout); - if (c == *p++) - { - if (*p == '\0') - { - immediate_quit--; - return; - } - } - else - { - if (!discard) - { - fwrite (string, 1, (p - 1) - string, stdout); - putchar ((char) c); - fflush (stdout); - } - p = string; - } - } -} - -/* Keep discarding input until we see the STDEBUG prompt. - - The convention for dealing with the prompt is that you - o give your command - o *then* wait for the prompt. - - Thus the last thing that a procedure does with the serial line - will be an expect_prompt(). Exception: st2000_resume does not - wait for the prompt, because the terminal is being handed over - to the inferior. However, the next thing which happens after that - is a st2000_wait which does wait for the prompt. - Note that this includes abnormal exit, e.g. error(). This is - necessary to prevent getting into states from which we can't - recover. */ -static void -expect_prompt (int discard) -{ -#if defined (LOG_FILE) - /* This is a convenient place to do this. The idea is to do it often - enough that we never lose much data if we terminate abnormally. */ - fflush (log_file); -#endif - expect ("dbug> ", discard); -} - -/* Get a hex digit from the remote system & return its value. - If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ -static int -get_hex_digit (int ignore_space) -{ - int ch; - while (1) - { - ch = readchar (timeout); - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else if (ch == ' ' && ignore_space) - ; - else - { - expect_prompt (1); - error ("Invalid hex digit from remote system."); - } - } -} - -/* Get a byte from stdebug and put it in *BYT. Accept any number - leading spaces. */ -static void -get_hex_byte (char *byt) -{ - int val; - - val = get_hex_digit (1) << 4; - val |= get_hex_digit (0); - *byt = val; -} - -/* Get N 32-bit words from remote, each preceded by a space, - and put them in registers starting at REGNO. */ -static void -get_hex_regs (int n, int regno) -{ - long val; - int i; - - for (i = 0; i < n; i++) - { - int j; - - val = 0; - for (j = 0; j < 8; j++) - val = (val << 4) + get_hex_digit (j == 0); - supply_register (regno++, (char *) &val); - } -} - -/* This is called not only when we first attach, but also when the - user types "run" after having attached. */ -static void -st2000_create_inferior (char *execfile, char *args, char **env) -{ - int entry_pt; - - if (args && *args) - error ("Can't pass arguments to remote STDEBUG process"); - - if (execfile == 0 || exec_bfd == 0) - error ("No executable file specified"); - - entry_pt = (int) bfd_get_start_address (exec_bfd); - -/* The "process" (board) is already stopped awaiting our commands, and - the program is already downloaded. We just set its PC and go. */ - - clear_proceed_status (); - - /* Tell wait_for_inferior that we've started a new process. */ - init_wait_for_inferior (); - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - target_terminal_init (); - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - /* insert_step_breakpoint (); FIXME, do we need this? */ - /* Let 'er rip... */ - proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0); -} - -/* Open a connection to a remote debugger. - NAME is the filename used for communication. */ - -static int baudrate = 9600; -static char dev_name[100]; - -static void -st2000_open (char *args, int from_tty) -{ - int n; - char junk[100]; - - target_preopen (from_tty); - - n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk); - - if (n != 2) - error ("Bad arguments. Usage: target st2000 \n\ -or target st2000 \n"); - - st2000_close (0); - - st2000_desc = serial_open (dev_name); - - if (!st2000_desc) - perror_with_name (dev_name); - - if (serial_setbaudrate (st2000_desc, baudrate)) - { - serial_close (dev_name); - perror_with_name (dev_name); - } - - serial_raw (st2000_desc); - - push_target (&st2000_ops); - -#if defined (LOG_FILE) - log_file = fopen (LOG_FILE, "w"); - if (log_file == NULL) - perror_with_name (LOG_FILE); -#endif - - /* Hello? Are you there? */ - printf_stdebug ("\003"); /* ^C wakes up dbug */ - - expect_prompt (1); - - if (from_tty) - printf ("Remote %s connected to %s\n", target_shortname, - dev_name); -} - -/* Close out all files and local state before this target loses control. */ - -static void -st2000_close (int quitting) -{ - serial_close (st2000_desc); - -#if defined (LOG_FILE) - if (log_file) - { - if (ferror (log_file)) - fprintf (stderr, "Error writing log file.\n"); - if (fclose (log_file) != 0) - fprintf (stderr, "Error closing log file.\n"); - } -#endif -} - -/* Terminate the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. */ -static void -st2000_detach (int from_tty) -{ - pop_target (); /* calls st2000_close to do the real work */ - if (from_tty) - printf ("Ending remote %s debugging\n", target_shortname); -} - -/* Tell the remote machine to resume. */ - -static void -st2000_resume (ptid_t ptid, int step, enum target_signal sig) -{ - if (step) - { - printf_stdebug ("ST\r"); - /* Wait for the echo. */ - expect ("ST\r", 1); - } - else - { - printf_stdebug ("GO\r"); - /* Swallow the echo. */ - expect ("GO\r", 1); - } -} - -/* Wait until the remote machine stops, then return, - storing status in STATUS just as `wait' would. */ - -static ptid_t -st2000_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int old_timeout = timeout; - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - timeout = 0; /* Don't time out -- user program is running. */ - - expect_prompt (0); /* Wait for prompt, outputting extraneous text */ - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - - timeout = old_timeout; - - return inferior_ptid; -} - -/* Return the name of register number REGNO in the form input and output by - STDEBUG. Currently, REGISTER_NAMES just happens to contain exactly what - STDEBUG wants. Lets take advantage of that just as long as possible! */ - -static char * -get_reg_name (int regno) -{ - static char buf[50]; - const char *p; - char *b; - - b = buf; - - for (p = REGISTER_NAME (regno); *p; p++) - *b++ = toupper (*p); - *b = '\000'; - - return buf; -} - -/* Read the remote registers into the block REGS. */ - -static void -st2000_fetch_registers (void) -{ - int regno; - - /* Yeah yeah, I know this is horribly inefficient. But it isn't done - very often... I'll clean it up later. */ - - for (regno = 0; regno <= PC_REGNUM; regno++) - st2000_fetch_register (regno); -} - -/* Fetch register REGNO, or all registers if REGNO is -1. - Returns errno value. */ -static void -st2000_fetch_register (int regno) -{ - if (regno == -1) - st2000_fetch_registers (); - else - { - char *name = get_reg_name (regno); - printf_stdebug ("DR %s\r", name); - expect (name, 1); - expect (" : ", 1); - get_hex_regs (1, regno); - expect_prompt (1); - } - return; -} - -/* Store the remote registers from the contents of the block REGS. */ - -static void -st2000_store_registers (void) -{ - int regno; - - for (regno = 0; regno <= PC_REGNUM; regno++) - st2000_store_register (regno); - - registers_changed (); -} - -/* Store register REGNO, or all if REGNO == 0. - Return errno value. */ -static void -st2000_store_register (int regno) -{ - if (regno == -1) - st2000_store_registers (); - else - { - printf_stdebug ("PR %s %x\r", get_reg_name (regno), - read_register (regno)); - - expect_prompt (1); - } -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -st2000_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -static void -st2000_files_info (void) -{ - printf ("\tAttached to %s at %d baud.\n", - dev_name, baudrate); -} - -/* Copy LEN bytes of data from debugger memory at MYADDR - to inferior's memory at MEMADDR. Returns length moved. */ -static int -st2000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - int i; - - for (i = 0; i < len; i++) - { - printf_stdebug ("PM.B %x %x\r", memaddr + i, myaddr[i]); - expect_prompt (1); - } - return len; -} - -/* Read LEN bytes from inferior memory at MEMADDR. Put the result - at debugger address MYADDR. Returns length moved. */ -static int -st2000_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - int i; - - /* Number of bytes read so far. */ - int count; - - /* Starting address of this pass. */ - unsigned long startaddr; - - /* Number of bytes to read in this pass. */ - int len_this_pass; - - /* Note that this code works correctly if startaddr is just less - than UINT_MAX (well, really CORE_ADDR_MAX if there was such a - thing). That is, something like - st2000_read_bytes (CORE_ADDR_MAX - 4, foo, 4) - works--it never adds len to memaddr and gets 0. */ - /* However, something like - st2000_read_bytes (CORE_ADDR_MAX - 3, foo, 4) - doesn't need to work. Detect it and give up if there's an attempt - to do that. */ - if (((memaddr - 1) + len) < memaddr) - { - errno = EIO; - return 0; - } - - startaddr = memaddr; - count = 0; - while (count < len) - { - len_this_pass = 16; - if ((startaddr % 16) != 0) - len_this_pass -= startaddr % 16; - if (len_this_pass > (len - count)) - len_this_pass = (len - count); - - printf_stdebug ("DI.L %x %x\r", startaddr, len_this_pass); - expect (": ", 1); - - for (i = 0; i < len_this_pass; i++) - get_hex_byte (&myaddr[count++]); - - expect_prompt (1); - - startaddr += len_this_pass; - } - return len; -} - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If WRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - Returns the number of bytes transferred. */ - -static int -st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, struct mem_attrib *attrib, - struct target_ops *target) -{ - if (write) - return st2000_write_inferior_memory (memaddr, myaddr, len); - else - return st2000_read_inferior_memory (memaddr, myaddr, len); -} - -static void -st2000_kill (char *args, int from_tty) -{ - return; /* Ignore attempts to kill target system */ -} - -/* Clean up when a program exits. - - The program actually lives on in the remote processor's RAM, and may be - run again without a download. Don't leave it full of breakpoint - instructions. */ - -static void -st2000_mourn_inferior (void) -{ - remove_breakpoints (); - unpush_target (&st2000_ops); - generic_mourn_inferior (); /* Do all the proper things now */ -} - -#define MAX_STDEBUG_BREAKPOINTS 16 - -static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] = -{0}; - -static int -st2000_insert_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - CORE_ADDR bp_addr = addr; - int bp_size = 0; - - BREAKPOINT_FROM_PC (&bp_addr, &bp_size); - - for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++) - if (breakaddr[i] == 0) - { - breakaddr[i] = addr; - - st2000_read_inferior_memory (bp_addr, shadow, bp_size); - printf_stdebug ("BR %x H\r", addr); - expect_prompt (1); - return 0; - } - - fprintf (stderr, "Too many breakpoints (> 16) for STDBUG\n"); - return 1; -} - -static int -st2000_remove_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - - for (i = 0; i < MAX_STDEBUG_BREAKPOINTS; i++) - if (breakaddr[i] == addr) - { - breakaddr[i] = 0; - - printf_stdebug ("CB %d\r", i); - expect_prompt (1); - return 0; - } - - fprintf (stderr, "Can't find breakpoint associated with 0x%x\n", addr); - return 1; -} - - -/* Put a command string, in args, out to STDBUG. Output from STDBUG is placed - on the users terminal until the prompt is seen. */ - -static void -st2000_command (char *args, int fromtty) -{ - if (!st2000_desc) - error ("st2000 target not open."); - - if (!args) - error ("Missing command."); - - printf_stdebug ("%s\r", args); - expect_prompt (0); -} - -/* Connect the user directly to STDBUG. This command acts just like the - 'cu' or 'tip' command. Use ~. or ~^D to break out. */ - -/*static struct ttystate ttystate; */ - -static void -cleanup_tty (void) -{ - printf ("\r\n[Exiting connect mode]\r\n"); -/* serial_restore(0, &ttystate); */ -} - -#if 0 -/* This all should now be in serial.c */ - -static void -connect_command (char *args, int fromtty) -{ - fd_set readfds; - int numfds; - int c; - char cur_esc = 0; - - dont_repeat (); - - if (st2000_desc < 0) - error ("st2000 target not open."); - - if (args) - fprintf ("This command takes no args. They have been ignored.\n"); - - printf ("[Entering connect mode. Use ~. or ~^D to escape]\n"); - - serial_raw (0, &ttystate); - - make_cleanup (cleanup_tty, 0); - - FD_ZERO (&readfds); - - while (1) - { - do - { - FD_SET (0, &readfds); - FD_SET (deprecated_serial_fd (st2000_desc), &readfds); - numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0); - } - while (numfds == 0); - - if (numfds < 0) - perror_with_name ("select"); - - if (FD_ISSET (0, &readfds)) - { /* tty input, send to stdebug */ - c = getchar (); - if (c < 0) - perror_with_name ("connect"); - - printf_stdebug ("%c", c); - switch (cur_esc) - { - case 0: - if (c == '\r') - cur_esc = c; - break; - case '\r': - if (c == '~') - cur_esc = c; - else - cur_esc = 0; - break; - case '~': - if (c == '.' || c == '\004') - return; - else - cur_esc = 0; - } - } - - if (FD_ISSET (deprecated_serial_fd (st2000_desc), &readfds)) - { - while (1) - { - c = readchar (0); - if (c < 0) - break; - putchar (c); - } - fflush (stdout); - } - } -} -#endif /* 0 */ - -/* Define the target subroutine names */ - -struct target_ops st2000_ops; - -static void -init_st2000_ops (void) -{ - st2000_ops.to_shortname = "st2000"; - st2000_ops.to_longname = "Remote serial Tandem ST2000 target"; - st2000_ops.to_doc = "Use a remote computer running STDEBUG connected by a serial line;\n\ -or a network connection.\n\ -Arguments are the name of the device for the serial line,\n\ -the speed to connect at in bits per second."; - st2000_ops.to_open = st2000_open; - st2000_ops.to_close = st2000_close; - st2000_ops.to_attach = 0; - st2000_run_ops.to_post_attach = NULL; - st2000_ops.to_require_attach = NULL; - st2000_ops.to_detach = st2000_detach; - st2000_ops.to_require_detach = NULL; - st2000_ops.to_resume = st2000_resume; - st2000_ops.to_wait = st2000_wait; - st2000_ops.to_post_wait = NULL; - st2000_ops.to_fetch_registers = st2000_fetch_register; - st2000_ops.to_store_registers = st2000_store_register; - st2000_ops.to_prepare_to_store = st2000_prepare_to_store; - st2000_ops.to_xfer_memory = st2000_xfer_inferior_memory; - st2000_ops.to_files_info = st2000_files_info; - st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint; - st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint; /* Breakpoints */ - st2000_ops.to_terminal_init = 0; - st2000_ops.to_terminal_inferior = 0; - st2000_ops.to_terminal_ours_for_output = 0; - st2000_ops.to_terminal_ours = 0; - st2000_ops.to_terminal_info = 0; /* Terminal handling */ - st2000_ops.to_kill = st2000_kill; - st2000_ops.to_load = 0; /* load */ - st2000_ops.to_lookup_symbol = 0; /* lookup_symbol */ - st2000_ops.to_create_inferior = st2000_create_inferior; - st2000_ops.to_post_startup_inferior = NULL; - st2000_ops.to_acknowledge_created_inferior = NULL; - st2000_ops.to_clone_and_follow_inferior = NULL; - st2000_ops.to_post_follow_inferior_by_clone = NULL; - st2000_run_ops.to_insert_fork_catchpoint = NULL; - st2000_run_ops.to_remove_fork_catchpoint = NULL; - st2000_run_ops.to_insert_vfork_catchpoint = NULL; - st2000_run_ops.to_remove_vfork_catchpoint = NULL; - st2000_ops.to_has_forked = NULL; - st2000_ops.to_has_vforked = NULL; - st2000_run_ops.to_can_follow_vfork_prior_to_exec = NULL; - st2000_ops.to_post_follow_vfork = NULL; - st2000_run_ops.to_insert_exec_catchpoint = NULL; - st2000_run_ops.to_remove_exec_catchpoint = NULL; - st2000_run_ops.to_has_execd = NULL; - st2000_run_ops.to_reported_exec_events_per_exec_call = NULL; - st2000_run_ops.to_has_exited = NULL; - st2000_ops.to_mourn_inferior = st2000_mourn_inferior; - st2000_ops.to_can_run = 0; /* can_run */ - st2000_ops.to_notice_signals = 0; /* notice_signals */ - st2000_ops.to_thread_alive = 0; /* thread alive */ - st2000_ops.to_stop = 0; /* to_stop */ - st2000_ops.to_pid_to_exec_file = NULL; - st2000_ops.to_stratum = process_stratum; - st2000_ops.DONT_USE = 0; /* next */ - st2000_ops.to_has_all_memory = 1; - st2000_ops.to_has_memory = 1; - st2000_ops.to_has_stack = 1; - st2000_ops.to_has_registers = 1; - st2000_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */ - st2000_ops.to_sections = 0; - st2000_ops.to_sections_end = 0; /* Section pointers */ - st2000_ops.to_magic = OPS_MAGIC; /* Always the last thing */ -}; - -void -_initialize_remote_st2000 (void) -{ - init_st2000_ops (); - add_target (&st2000_ops); - add_com ("st2000 ", class_obscure, st2000_command, - "Send a command to the STDBUG monitor."); - add_com ("connect", class_obscure, connect_command, - "Connect the terminal directly up to the STDBUG command monitor.\n\ -Use ~. or ~^D to break out."); -} diff --git a/contrib/gdb/gdb/srec.h b/contrib/gdb/gdb/srec.h deleted file mode 100644 index d2d9876da4c..00000000000 --- a/contrib/gdb/gdb/srec.h +++ /dev/null @@ -1,37 +0,0 @@ -/* S-record download support for GDB, the GNU debugger. - Copyright 1995, 1996, 2000 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -void load_srec (struct serial *desc, const char *file, bfd_vma load_offset, - int maxrecsize, int flags, int hashmark, - int (*waitack) (void)); - -/* S-record capability flags */ - -/* Which record types are supported */ -#define SREC_2_BYTE_ADDR 0x00000001 -#define SREC_3_BYTE_ADDR 0x00000002 -#define SREC_4_BYTE_ADDR 0x00000004 -#define SREC_TERM_SHIFT 3 - -#define SREC_ALL (SREC_2_BYTE_ADDR | SREC_3_BYTE_ADDR | SREC_4_BYTE_ADDR \ - | ((SREC_2_BYTE_ADDR | SREC_3_BYTE_ADDR | SREC_4_BYTE_ADDR) \ - << SREC_TERM_SHIFT)) - -#define SREC_BINARY 0x00000040 /* Supports binary form of S-records */ diff --git a/contrib/gdb/gdb/standalone.c b/contrib/gdb/gdb/standalone.c deleted file mode 100644 index 6ae8f5398b8..00000000000 --- a/contrib/gdb/gdb/standalone.c +++ /dev/null @@ -1,579 +0,0 @@ -/* Interface to bare machine for GDB running as kernel debugger. - Copyright 1986, 1989, 1991, 1992, 1993, 1995, 1996, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include -#include -#include -#include "gdb_stat.h" - -#if defined (SIGTSTP) && defined (SIGIO) -#include -#include -#endif /* SIGTSTP and SIGIO defined (must be 4.2) */ - -#include "defs.h" -#include -#include "symtab.h" -#include "frame.h" -#include "inferior.h" -#include "gdb_wait.h" - - -/* Random system calls, mostly no-ops to prevent link problems */ - -ioctl (int desc, int code, int arg) -{ -} - -int (*signal ()) () -{ -} - -kill (void) -{ -} - -getpid (void) -{ - return 0; -} - -sigsetmask (void) -{ -} - -chdir (void) -{ -} - -char * -getcwd (char *buf, unsigned int len) -{ - buf[0] = '/'; - buf[1] = 0; - return buf; -} - -/* Used to check for existence of .gdbinit. Say no. */ - -access (void) -{ - return -1; -} - -exit (void) -{ - error ("Fatal error; restarting."); -} - -/* Reading "files". The contents of some files are written into kdb's - data area before it is run. These files are used to contain the - symbol table for kdb to load, and the source files (in case the - kdb user wants to print them). The symbols are stored in a file - named "kdb-symbols" in a.out format (except that all the text and - data have been stripped to save room). - - The files are stored in the following format: - int number of bytes of data for this file, including these four. - char[] name of the file, ending with a null. - padding to multiple of 4 boundary. - char[] file contents. The length can be deduced from what was - specified before. There is no terminating null here. - - If the int at the front is zero, it means there are no more files. - - Opening a file in kdb returns a nonzero value to indicate success, - but the value does not matter. Only one file can be open, and only - for reading. All the primitives for input from the file know - which file is open and ignore what is specified for the descriptor - or for the stdio stream. - - Input with fgetc can be done either on the file that is open - or on stdin (which reads from the terminal through tty_input () */ - -/* Address of data for the files stored in format described above. */ -char *files_start; - -/* The file stream currently open: */ - -char *sourcebeg; /* beginning of contents */ -int sourcesize; /* size of contents */ -char *sourceptr; /* current read pointer */ -int sourceleft; /* number of bytes to eof */ - -/* "descriptor" for the file now open. - Incremented at each close. - If specified descriptor does not match this, - it means the program is trying to use a closed descriptor. - We report an error for that. */ - -int sourcedesc; - -open (char *filename, int modes) -{ - register char *next; - - if (modes) - { - errno = EROFS; - return -1; - } - - if (sourceptr) - { - errno = EMFILE; - return -1; - } - - for (next = files_start; *(int *) next; next += *(int *) next) - { - if (!strcmp (next + 4, filename)) - { - sourcebeg = next + 4 + strlen (next + 4) + 1; - sourcebeg = (char *) (((int) sourcebeg + 3) & (-4)); - sourceptr = sourcebeg; - sourcesize = next + *(int *) next - sourceptr; - sourceleft = sourcesize; - return sourcedesc; - } - } - return 0; -} - -close (int desc) -{ - sourceptr = 0; - sourcedesc++; - /* Don't let sourcedesc get big enough to be confused with stdin. */ - if (sourcedesc == 100) - sourcedesc = 5; -} - -FILE * -fopen (char *filename, char *modes) -{ - return (FILE *) open (filename, *modes == 'w'); -} - -FILE * -fdopen (int desc) -{ - return (FILE *) desc; -} - -fclose (int desc) -{ - close (desc); -} - -fstat (int desc, struct stat *statbuf) -{ - if (desc != sourcedesc) - { - errno = EBADF; - return -1; - } - statbuf->st_size = sourcesize; -} - -myread (int desc, char *destptr, int size, char *filename) -{ - int len = min (sourceleft, size); - - if (desc != sourcedesc) - { - errno = EBADF; - return -1; - } - - memcpy (destptr, sourceptr, len); - sourceleft -= len; - return len; -} - -int -fread (int bufp, int numelts, int eltsize, int stream) -{ - register int elts = min (numelts, sourceleft / eltsize); - register int len = elts * eltsize; - - if (stream != sourcedesc) - { - errno = EBADF; - return -1; - } - - memcpy (bufp, sourceptr, len); - sourceleft -= len; - return elts; -} - -int -fgetc (int desc) -{ - - if (desc == (int) stdin) - return tty_input (); - - if (desc != sourcedesc) - { - errno = EBADF; - return -1; - } - - if (sourceleft-- <= 0) - return EOF; - return *sourceptr++; -} - -lseek (int desc, int pos) -{ - - if (desc != sourcedesc) - { - errno = EBADF; - return -1; - } - - if (pos < 0 || pos > sourcesize) - { - errno = EINVAL; - return -1; - } - - sourceptr = sourcebeg + pos; - sourceleft = sourcesize - pos; -} - -/* Output in kdb can go only to the terminal, so the stream - specified may be ignored. */ - -printf (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) -{ - char buffer[1024]; - sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9); - display_string (buffer); -} - -fprintf (int ign, int a1, int a2, int a3, int a4, int a5, int a6, int a7, - int a8, int a9) -{ - char buffer[1024]; - sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9); - display_string (buffer); -} - -fwrite (register char *buf, int numelts, int size, int stream) -{ - register int i = numelts * size; - while (i-- > 0) - fputc (*buf++, stream); -} - -fputc (int c, int ign) -{ - char buf[2]; - buf[0] = c; - buf[1] = 0; - display_string (buf); -} - -/* sprintf refers to this, but loading this from the - library would cause fflush to be loaded from it too. - In fact there should be no need to call this (I hope). */ - -_flsbuf (void) -{ - error ("_flsbuf was actually called."); -} - -fflush (int ign) -{ -} - -/* Entries into core and inflow, needed only to make things link ok. */ - -exec_file_command (void) -{ -} - -core_file_command (void) -{ -} - -char * -get_exec_file (int err) -{ - /* Makes one printout look reasonable; value does not matter otherwise. */ - return "run"; -} - -/* Nonzero if there is a core file. */ - -have_core_file_p (void) -{ - return 0; -} - -kill_command (void) -{ - inferior_ptid = null_ptid; -} - -terminal_inferior (void) -{ -} - -terminal_ours (void) -{ -} - -terminal_init_inferior (void) -{ -} - -write_inferior_register (void) -{ -} - -read_inferior_register (void) -{ -} - -read_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - memcpy (myaddr, memaddr, len); -} - -/* Always return 0 indicating success. */ - -write_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - memcpy (memaddr, myaddr, len); - return 0; -} - -static REGISTER_TYPE saved_regs[NUM_REGS]; - -REGISTER_TYPE -read_register (int regno) -{ - if (regno < 0 || regno >= NUM_REGS) - error ("Register number %d out of range.", regno); - return saved_regs[regno]; -} - -void -write_register (int regno, REGISTER_TYPE value) -{ - if (regno < 0 || regno >= NUM_REGS) - error ("Register number %d out of range.", regno); - saved_regs[regno] = value; -} - -/* System calls needed in relation to running the "inferior". */ - -vfork (void) -{ - /* Just appear to "succeed". Say the inferior's pid is 1. */ - return 1; -} - -/* These are called by code that normally runs in the inferior - that has just been forked. That code never runs, when standalone, - and these definitions are so it will link without errors. */ - -ptrace (void) -{ -} - -setpgrp (void) -{ -} - -execle (void) -{ -} - -_exit (void) -{ -} - -/* Malloc calls these. */ - -malloc_warning (char *str) -{ - printf ("\n%s.\n\n", str); -} - -char *next_free; -char *memory_limit; - -char * -sbrk (int amount) -{ - if (next_free + amount > memory_limit) - return (char *) -1; - next_free += amount; - return next_free - amount; -} - -/* Various ways malloc might ask where end of memory is. */ - -char * -ulimit (void) -{ - return memory_limit; -} - -int -vlimit (void) -{ - return memory_limit - next_free; -} - -getrlimit (struct rlimit *addr) -{ - addr->rlim_cur = memory_limit - next_free; -} - -/* Context switching to and from program being debugged. */ - -/* GDB calls here to run the user program. - The frame pointer for this function is saved in - gdb_stack by save_frame_pointer; then we restore - all of the user program's registers, including PC and PS. */ - -static int fault_code; -static REGISTER_TYPE gdb_stack; - -resume (void) -{ - REGISTER_TYPE restore[NUM_REGS]; - - PUSH_FRAME_PTR; - save_frame_pointer (); - - memcpy (restore, saved_regs, sizeof restore); - POP_REGISTERS; - /* Control does not drop through here! */ -} - -save_frame_pointer (CORE_ADDR val) -{ - gdb_stack = val; -} - -/* Fault handlers call here, running in the user program stack. - They must first push a fault code, - old PC, old PS, and any other info about the fault. - The exact format is machine-dependent and is known only - in the definition of PUSH_REGISTERS. */ - -fault (void) -{ - /* Transfer all registers and fault code to the stack - in canonical order: registers in order of GDB register number, - followed by fault code. */ - PUSH_REGISTERS; - - /* Transfer them to saved_regs and fault_code. */ - save_registers (); - - restore_gdb (); - /* Control does not reach here */ -} - -restore_gdb (void) -{ - CORE_ADDR new_fp = gdb_stack; - /* Switch to GDB's stack */ - POP_FRAME_PTR; - /* Return from the function `resume'. */ -} - -/* Assuming register contents and fault code have been pushed on the stack as - arguments to this function, copy them into the standard place - for the program's registers while GDB is running. */ - -save_registers (int firstreg) -{ - memcpy (saved_regs, &firstreg, sizeof saved_regs); - fault_code = (&firstreg)[NUM_REGS]; -} - -/* Store into the structure such as `wait' would return - the information on why the program faulted, - converted into a machine-independent signal number. */ - -static int fault_table[] = FAULT_TABLE; - -int -wait (WAITTYPE *w) -{ - WSETSTOP (*w, fault_table[fault_code / FAULT_CODE_UNITS]); - return PIDGET (inferior_ptid); -} - -/* Allocate a big space in which files for kdb to read will be stored. - Whatever is left is where malloc can allocate storage. - - Initialize it, so that there will be space in the executable file - for it. Then the files can be put into kdb by writing them into - kdb's executable file. */ - -/* The default size is as much space as we expect to be available - for kdb to use! */ - -#ifndef HEAP_SIZE -#define HEAP_SIZE 400000 -#endif - -char heap[HEAP_SIZE] = -{0}; - -#ifndef STACK_SIZE -#define STACK_SIZE 100000 -#endif - -int kdb_stack_beg[STACK_SIZE / sizeof (int)]; -int kdb_stack_end; - -_initialize_standalone (void) -{ - register char *next; - - /* Find start of data on files. */ - - files_start = heap; - - /* Find the end of the data on files. */ - - for (next = files_start; *(int *) next; next += *(int *) next) - { - } - - /* That is where free storage starts for sbrk to give out. */ - next_free = next; - - memory_limit = heap + sizeof heap; -} diff --git a/contrib/gdb/gdb/xcoffread.c b/contrib/gdb/gdb/xcoffread.c deleted file mode 100644 index 965473a54c4..00000000000 --- a/contrib/gdb/gdb/xcoffread.c +++ /dev/null @@ -1,3046 +0,0 @@ -/* Read AIX xcoff symbol tables and convert to internal format, for GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - Derived from coffread.c, dbxread.c, and a lot of hacking. - Contributed by IBM Corporation. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "bfd.h" - -#include -#include -#include -#include "gdb_string.h" - -#include -#ifndef NO_SYS_FILE -#include -#endif -#include "gdb_stat.h" - -#include "coff/internal.h" -#include "libcoff.h" /* FIXME, internal data from BFD */ -#include "coff/rs6000.h" - -#include "symtab.h" -#include "gdbtypes.h" -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "stabsread.h" -#include "expression.h" -#include "complaints.h" - -#include "gdb-stabs.h" - -/* For interface with stabsread.c. */ -#include "aout/stab_gnu.h" - - -/* We put a pointer to this structure in the read_symtab_private field - of the psymtab. */ - -struct symloc - { - - /* First symbol number for this file. */ - - int first_symnum; - - /* Number of symbols in the section of the symbol table devoted to - this file's symbols (actually, the section bracketed may contain - more than just this file's symbols). If numsyms is 0, the only - reason for this thing's existence is the dependency list. Nothing - else will happen when it is read in. */ - - int numsyms; - - /* Position of the start of the line number information for this psymtab. */ - unsigned int lineno_off; - }; - -/* Remember what we deduced to be the source language of this psymtab. */ - -static enum language psymtab_language = language_unknown; - - -/* Simplified internal version of coff symbol table information */ - -struct coff_symbol - { - char *c_name; - int c_symnum; /* symbol number of this entry */ - int c_naux; /* 0 if syment only, 1 if syment + auxent */ - long c_value; - unsigned char c_sclass; - int c_secnum; - unsigned int c_type; - }; - -/* last function's saved coff symbol `cs' */ - -static struct coff_symbol fcn_cs_saved; - -static bfd *symfile_bfd; - -/* Core address of start and end of text of current source file. - This is calculated from the first function seen after a C_FILE - symbol. */ - - -static CORE_ADDR cur_src_end_addr; - -/* Core address of the end of the first object file. */ - -static CORE_ADDR first_object_file_end; - -/* initial symbol-table-debug-string vector length */ - -#define INITIAL_STABVECTOR_LENGTH 40 - -/* Nonzero if within a function (so symbols should be local, - if nothing says specifically). */ - -int within_function; - -/* Size of a COFF symbol. I think it is always 18, so I'm not sure - there is any reason not to just use a #define, but might as well - ask BFD for the size and store it here, I guess. */ - -static unsigned local_symesz; - -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 */ - - /* Pointer to the string table. */ - char *strtbl; - - /* Pointer to debug section. */ - char *debugsec; - - /* Pointer to the a.out symbol table. */ - char *symtbl; - - /* Number of symbols in symtbl. */ - int symtbl_num_syms; - - /* Offset in data section to TOC anchor. */ - CORE_ADDR toc_offset; - }; - -static struct complaint storclass_complaint = -{"Unexpected storage class: %d", 0, 0}; - -static struct complaint bf_notfound_complaint = -{"line numbers off, `.bf' symbol not found", 0, 0}; - -static struct complaint ef_complaint = -{"Mismatched .ef symbol ignored starting at symnum %d", 0, 0}; - -static struct complaint eb_complaint = -{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0}; - -static void xcoff_initial_scan (struct objfile *, int); - -static void scan_xcoff_symtab (struct objfile *); - -static char *xcoff_next_symbol_text (struct objfile *); - -static void record_include_begin (struct coff_symbol *); - -static void -enter_line_range (struct subfile *, unsigned, unsigned, - CORE_ADDR, CORE_ADDR, unsigned *); - -static void init_stringtab (bfd *, file_ptr, struct objfile *); - -static void xcoff_symfile_init (struct objfile *); - -static void xcoff_new_init (struct objfile *); - -static void xcoff_symfile_finish (struct objfile *); - -static void -xcoff_symfile_offsets (struct objfile *, struct section_addr_info *addrs); - -static void find_linenos (bfd *, sec_ptr, PTR); - -static char *coff_getfilename (union internal_auxent *, struct objfile *); - -static void read_symbol (struct internal_syment *, int); - -static int read_symbol_lineno (int); - -static CORE_ADDR read_symbol_nvalue (int); - -static struct symbol *process_xcoff_symbol (struct coff_symbol *, - struct objfile *); - -static void read_xcoff_symtab (struct partial_symtab *); - -#if 0 -static void add_stab_to_list (char *, struct pending_stabs **); -#endif - -static int compare_lte (const void *, const void *); - -static struct linetable *arrange_linetable (struct linetable *); - -static void record_include_end (struct coff_symbol *); - -static void process_linenos (CORE_ADDR, CORE_ADDR); - - -/* Translate from a COFF section number (target_index) to a SECT_OFF_* - code. */ -static int secnum_to_section (int, struct objfile *); -static asection *secnum_to_bfd_section (int, struct objfile *); - -struct find_targ_sec_arg - { - int targ_index; - int *resultp; - asection **bfd_sect; - struct objfile *objfile; - }; - -static void find_targ_sec (bfd *, asection *, void *); - -static void -find_targ_sec (bfd *abfd, asection *sect, PTR obj) -{ - struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj; - struct objfile *objfile = args->objfile; - if (sect->target_index == args->targ_index) - { - /* This is the section. Figure out what SECT_OFF_* code it is. */ - if (bfd_get_section_flags (abfd, sect) & SEC_CODE) - *args->resultp = SECT_OFF_TEXT (objfile); - else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) - *args->resultp = SECT_OFF_DATA (objfile); - else - *args->resultp = sect->index; - *args->bfd_sect = sect; - } -} - -/* Return the section number (SECT_OFF_*) that CS points to. */ -static int -secnum_to_section (int secnum, struct objfile *objfile) -{ - int off = SECT_OFF_TEXT (objfile); - asection *sect = NULL; - struct find_targ_sec_arg args; - args.targ_index = secnum; - args.resultp = &off; - args.bfd_sect = § - args.objfile = objfile; - bfd_map_over_sections (objfile->obfd, find_targ_sec, &args); - return off; -} - -/* Return the BFD section that CS points to. */ -static asection * -secnum_to_bfd_section (int secnum, struct objfile *objfile) -{ - int off = SECT_OFF_TEXT (objfile); - asection *sect = NULL; - struct find_targ_sec_arg args; - args.targ_index = secnum; - args.resultp = &off; - args.bfd_sect = § - args.objfile = objfile; - bfd_map_over_sections (objfile->obfd, find_targ_sec, &args); - return sect; -} - -/* add a given stab string into given stab vector. */ - -#if 0 - -static void -add_stab_to_list (char *stabname, struct pending_stabs **stabvector) -{ - if (*stabvector == NULL) - { - *stabvector = (struct pending_stabs *) - xmalloc (sizeof (struct pending_stabs) + - INITIAL_STABVECTOR_LENGTH * sizeof (char *)); - (*stabvector)->count = 0; - (*stabvector)->length = INITIAL_STABVECTOR_LENGTH; - } - else if ((*stabvector)->count >= (*stabvector)->length) - { - (*stabvector)->length += INITIAL_STABVECTOR_LENGTH; - *stabvector = (struct pending_stabs *) - xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) + - (*stabvector)->length * sizeof (char *)); - } - (*stabvector)->stab[(*stabvector)->count++] = stabname; -} - -#endif - /* *INDENT-OFF* */ -/* Linenos are processed on a file-by-file basis. - - Two reasons: - - 1) xlc (IBM's native c compiler) postpones static function code - emission to the end of a compilation unit. This way it can - determine if those functions (statics) are needed or not, and - can do some garbage collection (I think). This makes line - numbers and corresponding addresses unordered, and we end up - with a line table like: - - - lineno addr - foo() 10 0x100 - 20 0x200 - 30 0x300 - - foo3() 70 0x400 - 80 0x500 - 90 0x600 - - static foo2() - 40 0x700 - 50 0x800 - 60 0x900 - - and that breaks gdb's binary search on line numbers, if the - above table is not sorted on line numbers. And that sort - should be on function based, since gcc can emit line numbers - like: - - 10 0x100 - for the init/test part of a for stmt. - 20 0x200 - 30 0x300 - 10 0x400 - for the increment part of a for stmt. - - arrange_linetable() will do this sorting. - - 2) aix symbol table might look like: - - c_file // beginning of a new file - .bi // beginning of include file - .ei // end of include file - .bi - .ei - - basically, .bi/.ei pairs do not necessarily encapsulate - their scope. They need to be recorded, and processed later - on when we come the end of the compilation unit. - Include table (inclTable) and process_linenos() handle - that. */ -/* *INDENT-ON* */ - - - -/* compare line table entry addresses. */ - -static int -compare_lte (const void *lte1p, const void *lte2p) -{ - struct linetable_entry *lte1 = (struct linetable_entry *) lte1p; - struct linetable_entry *lte2 = (struct linetable_entry *) lte2p; - return lte1->pc - lte2->pc; -} - -/* Given a line table with function entries are marked, arrange its functions - in ascending order and strip off function entry markers and return it in - a newly created table. If the old one is good enough, return the old one. */ -/* FIXME: I think all this stuff can be replaced by just passing - sort_linevec = 1 to end_symtab. */ - -static struct linetable * -arrange_linetable (struct linetable *oldLineTb) -{ - int ii, jj, newline, /* new line count */ - function_count; /* # of functions */ - - struct linetable_entry *fentry; /* function entry vector */ - int fentry_size; /* # of function entries */ - struct linetable *newLineTb; /* new line table */ - -#define NUM_OF_FUNCTIONS 20 - - fentry_size = NUM_OF_FUNCTIONS; - fentry = (struct linetable_entry *) - xmalloc (fentry_size * sizeof (struct linetable_entry)); - - for (function_count = 0, ii = 0; ii < oldLineTb->nitems; ++ii) - { - - if (oldLineTb->item[ii].line == 0) - { /* function entry found. */ - - if (function_count >= fentry_size) - { /* make sure you have room. */ - fentry_size *= 2; - fentry = (struct linetable_entry *) - xrealloc (fentry, fentry_size * sizeof (struct linetable_entry)); - } - fentry[function_count].line = ii; - fentry[function_count].pc = oldLineTb->item[ii].pc; - ++function_count; - } - } - - if (function_count == 0) - { - xfree (fentry); - return oldLineTb; - } - else if (function_count > 1) - qsort (fentry, function_count, sizeof (struct linetable_entry), compare_lte); - - /* allocate a new line table. */ - newLineTb = (struct linetable *) - xmalloc - (sizeof (struct linetable) + - (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry)); - - /* if line table does not start with a function beginning, copy up until - a function begin. */ - - newline = 0; - if (oldLineTb->item[0].line != 0) - for (newline = 0; - newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline) - newLineTb->item[newline] = oldLineTb->item[newline]; - - /* Now copy function lines one by one. */ - - for (ii = 0; ii < function_count; ++ii) - { - for (jj = fentry[ii].line + 1; - jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0; - ++jj, ++newline) - newLineTb->item[newline] = oldLineTb->item[jj]; - } - xfree (fentry); - newLineTb->nitems = oldLineTb->nitems - function_count; - return newLineTb; -} - -/* include file support: C_BINCL/C_EINCL pairs will be kept in the - following `IncludeChain'. At the end of each symtab (end_symtab), - we will determine if we should create additional symtab's to - represent if (the include files. */ - - -typedef struct _inclTable -{ - char *name; /* include filename */ - - /* Offsets to the line table. end points to the last entry which is - part of this include file. */ - int begin, end; - - struct subfile *subfile; - unsigned funStartLine; /* start line # of its function */ -} -InclTable; - -#define INITIAL_INCLUDE_TABLE_LENGTH 20 -static InclTable *inclTable; /* global include table */ -static int inclIndx; /* last entry to table */ -static int inclLength; /* table length */ -static int inclDepth; /* nested include depth */ - -static void allocate_include_entry (void); - -static void -record_include_begin (struct coff_symbol *cs) -{ - if (inclDepth) - { - /* In xcoff, we assume include files cannot be nested (not in .c files - of course, but in corresponding .s files.). */ - - /* This can happen with old versions of GCC. - GCC 2.3.3-930426 does not exhibit this on a test case which - a user said produced the message for him. */ - static struct complaint msg = - {"Nested C_BINCL symbols", 0, 0}; - complain (&msg); - } - ++inclDepth; - - allocate_include_entry (); - - inclTable[inclIndx].name = cs->c_name; - inclTable[inclIndx].begin = cs->c_value; -} - -static void -record_include_end (struct coff_symbol *cs) -{ - InclTable *pTbl; - - if (inclDepth == 0) - { - static struct complaint msg = - {"Mismatched C_BINCL/C_EINCL pair", 0, 0}; - complain (&msg); - } - - allocate_include_entry (); - - pTbl = &inclTable[inclIndx]; - pTbl->end = cs->c_value; - - --inclDepth; - ++inclIndx; -} - -static void -allocate_include_entry (void) -{ - if (inclTable == NULL) - { - inclTable = (InclTable *) - xmalloc (sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH); - memset (inclTable, - '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH); - inclLength = INITIAL_INCLUDE_TABLE_LENGTH; - inclIndx = 0; - } - else if (inclIndx >= inclLength) - { - inclLength += INITIAL_INCLUDE_TABLE_LENGTH; - inclTable = (InclTable *) - xrealloc (inclTable, sizeof (InclTable) * inclLength); - memset (inclTable + inclLength - INITIAL_INCLUDE_TABLE_LENGTH, - '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH); - } -} - -/* Global variable to pass the psymtab down to all the routines involved - in psymtab to symtab processing. */ -static struct partial_symtab *this_symtab_psymtab; - -/* given the start and end addresses of a compilation unit (or a csect, - at times) process its lines and create appropriate line vectors. */ - -static void -process_linenos (CORE_ADDR start, CORE_ADDR end) -{ - int offset, ii; - file_ptr max_offset = - ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) - ->max_lineno_offset; - - /* subfile structure for the main compilation unit. */ - struct subfile main_subfile; - - /* In the main source file, any time we see a function entry, we - reset this variable to function's absolute starting line number. - All the following line numbers in the function are relative to - this, and we record absolute line numbers in record_line(). */ - - unsigned int main_source_baseline = 0; - - unsigned *firstLine; - - offset = - ((struct symloc *) this_symtab_psymtab->read_symtab_private)->lineno_off; - if (offset == 0) - goto return_after_cleanup; - - memset (&main_subfile, '\0', sizeof (main_subfile)); - - if (inclIndx == 0) - /* All source lines were in the main source file. None in include files. */ - - enter_line_range (&main_subfile, offset, 0, start, end, - &main_source_baseline); - - else - { - /* There was source with line numbers in include files. */ - - int linesz = - coff_data (this_symtab_psymtab->objfile->obfd)->local_linesz; - main_source_baseline = 0; - - for (ii = 0; ii < inclIndx; ++ii) - { - struct subfile *tmpSubfile; - - /* If there is main file source before include file, enter it. */ - if (offset < inclTable[ii].begin) - { - enter_line_range - (&main_subfile, offset, inclTable[ii].begin - linesz, - start, 0, &main_source_baseline); - } - - /* Have a new subfile for the include file. */ - - tmpSubfile = inclTable[ii].subfile = - (struct subfile *) xmalloc (sizeof (struct subfile)); - - memset (tmpSubfile, '\0', sizeof (struct subfile)); - firstLine = &(inclTable[ii].funStartLine); - - /* Enter include file's lines now. */ - enter_line_range (tmpSubfile, inclTable[ii].begin, - inclTable[ii].end, start, 0, firstLine); - - if (offset <= inclTable[ii].end) - offset = inclTable[ii].end + linesz; - } - - /* All the include files' line have been processed at this point. Now, - enter remaining lines of the main file, if any left. */ - if (offset < max_offset + 1 - linesz) - { - enter_line_range (&main_subfile, offset, 0, start, end, - &main_source_baseline); - } - } - - /* Process main file's line numbers. */ - if (main_subfile.line_vector) - { - struct linetable *lineTb, *lv; - - lv = main_subfile.line_vector; - - /* Line numbers are not necessarily ordered. xlc compilation will - put static function to the end. */ - - lineTb = arrange_linetable (lv); - if (lv == lineTb) - { - current_subfile->line_vector = (struct linetable *) - xrealloc (lv, (sizeof (struct linetable) - + lv->nitems * sizeof (struct linetable_entry))); - } - else - { - xfree (lv); - current_subfile->line_vector = lineTb; - } - - current_subfile->line_vector_length = - current_subfile->line_vector->nitems; - } - - /* Now, process included files' line numbers. */ - - for (ii = 0; ii < inclIndx; ++ii) - { - if ((inclTable[ii].subfile)->line_vector) /* Useless if!!! FIXMEmgo */ - { - struct linetable *lineTb, *lv; - - lv = (inclTable[ii].subfile)->line_vector; - - /* Line numbers are not necessarily ordered. xlc compilation will - put static function to the end. */ - - lineTb = arrange_linetable (lv); - - push_subfile (); - - /* For the same include file, we might want to have more than one - subfile. This happens if we have something like: - - ...... - #include "foo.h" - ...... - #include "foo.h" - ...... - - while foo.h including code in it. (stupid but possible) - Since start_subfile() looks at the name and uses an - existing one if finds, we need to provide a fake name and - fool it. */ - -#if 0 - start_subfile (inclTable[ii].name, (char *) 0); -#else - { - /* Pick a fake name that will produce the same results as this - one when passed to deduce_language_from_filename. Kludge on - top of kludge. */ - char *fakename = strrchr (inclTable[ii].name, '.'); - if (fakename == NULL) - fakename = " ?"; - start_subfile (fakename, (char *) 0); - xfree (current_subfile->name); - } - current_subfile->name = xstrdup (inclTable[ii].name); -#endif - - if (lv == lineTb) - { - current_subfile->line_vector = - (struct linetable *) xrealloc - (lv, (sizeof (struct linetable) - + lv->nitems * sizeof (struct linetable_entry))); - - } - else - { - xfree (lv); - current_subfile->line_vector = lineTb; - } - - current_subfile->line_vector_length = - current_subfile->line_vector->nitems; - start_subfile (pop_subfile (), (char *) 0); - } - } - -return_after_cleanup: - - /* We don't want to keep alloc/free'ing the global include file table. */ - inclIndx = 0; - - /* Start with a fresh subfile structure for the next file. */ - memset (&main_subfile, '\0', sizeof (struct subfile)); -} - -void -aix_process_linenos (void) -{ - /* process line numbers and enter them into line vector */ - process_linenos (last_source_start_addr, cur_src_end_addr); -} - - -/* Enter a given range of lines into the line vector. - can be called in the following two ways: - enter_line_range (subfile, beginoffset, endoffset, startaddr, 0, firstLine) or - enter_line_range (subfile, beginoffset, 0, startaddr, endaddr, firstLine) - - endoffset points to the last line table entry that we should pay - attention to. */ - -static void -enter_line_range (struct subfile *subfile, unsigned beginoffset, unsigned endoffset, /* offsets to line table */ - CORE_ADDR startaddr, /* offsets to line table */ - CORE_ADDR endaddr, unsigned *firstLine) -{ - unsigned int curoffset; - CORE_ADDR addr; - void *ext_lnno; - struct internal_lineno int_lnno; - unsigned int limit_offset; - bfd *abfd; - int linesz; - - if (endoffset == 0 && startaddr == 0 && endaddr == 0) - return; - curoffset = beginoffset; - limit_offset = - ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) - ->max_lineno_offset; - - if (endoffset != 0) - { - if (endoffset >= limit_offset) - { - static struct complaint msg = - {"Bad line table offset in C_EINCL directive", 0, 0}; - complain (&msg); - return; - } - limit_offset = endoffset; - } - else - limit_offset -= 1; - - abfd = this_symtab_psymtab->objfile->obfd; - linesz = coff_data (abfd)->local_linesz; - ext_lnno = alloca (linesz); - - while (curoffset <= limit_offset) - { - bfd_seek (abfd, curoffset, SEEK_SET); - bfd_bread (ext_lnno, linesz, abfd); - bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno); - - /* Find the address this line represents. */ - addr = (int_lnno.l_lnno - ? int_lnno.l_addr.l_paddr - : read_symbol_nvalue (int_lnno.l_addr.l_symndx)); - addr += ANOFFSET (this_symtab_psymtab->objfile->section_offsets, - SECT_OFF_TEXT (this_symtab_psymtab->objfile)); - - if (addr < startaddr || (endaddr && addr >= endaddr)) - return; - - if (int_lnno.l_lnno == 0) - { - *firstLine = read_symbol_lineno (int_lnno.l_addr.l_symndx); - record_line (subfile, 0, addr); - --(*firstLine); - } - else - record_line (subfile, *firstLine + int_lnno.l_lnno, addr); - curoffset += linesz; - } -} - - -/* Save the vital information for use when closing off the current file. - NAME is the file name the symbols came from, START_ADDR is the first - text address for the file, and SIZE is the number of bytes of text. */ - -#define complete_symtab(name, start_addr) { \ - last_source_file = savestring (name, strlen (name)); \ - last_source_start_addr = start_addr; \ -} - - -/* Refill the symbol table input buffer - and set the variables that control fetching entries from it. - Reports an error if no data available. - This function can read past the end of the symbol table - (into the string table) but this does no harm. */ - -/* Reading symbol table has to be fast! Keep the followings as macros, rather - than functions. */ - -#define RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, SECTION, OBJFILE) \ -{ \ - char *namestr; \ - namestr = (NAME); \ - if (namestr[0] == '.') ++namestr; \ - prim_record_minimal_symbol_and_info (namestr, (ADDR), (TYPE), \ - (char *)NULL, (SECTION), (asection *)NULL, (OBJFILE)); \ - misc_func_recorded = 1; \ -} - - -/* xcoff has static blocks marked in `.bs', `.es' pairs. They cannot be - nested. At any given time, a symbol can only be in one static block. - This is the base address of current static block, zero if non exists. */ - -static int static_block_base = 0; - -/* Section number for the current static block. */ - -static int static_block_section = -1; - -/* true if space for symbol name has been allocated. */ - -static int symname_alloced = 0; - -/* Next symbol to read. Pointer into raw seething symbol table. */ - -static char *raw_symbol; - -/* This is the function which stabsread.c calls to get symbol - continuations. */ - -static char * -xcoff_next_symbol_text (struct objfile *objfile) -{ - struct internal_syment symbol; - static struct complaint msg = - {"Unexpected symbol continuation", 0, 0}; - char *retval; - /* FIXME: is this the same as the passed arg? */ - objfile = this_symtab_psymtab->objfile; - - bfd_coff_swap_sym_in (objfile->obfd, raw_symbol, &symbol); - if (symbol.n_zeroes) - { - complain (&msg); - - /* Return something which points to '\0' and hope the symbol reading - code does something reasonable. */ - retval = ""; - } - else if (symbol.n_sclass & 0x80) - { - retval = - ((struct coff_symfile_info *) objfile->sym_private)->debugsec - + symbol.n_offset; - raw_symbol += - coff_data (objfile->obfd)->local_symesz; - ++symnum; - } - else - { - complain (&msg); - - /* Return something which points to '\0' and hope the symbol reading - code does something reasonable. */ - retval = ""; - } - return retval; -} - -/* Read symbols for a given partial symbol table. */ - -static void -read_xcoff_symtab (struct partial_symtab *pst) -{ - struct objfile *objfile = pst->objfile; - bfd *abfd = objfile->obfd; - char *raw_auxptr; /* Pointer to first raw aux entry for sym */ - char *strtbl = ((struct coff_symfile_info *) objfile->sym_private)->strtbl; - char *debugsec = - ((struct coff_symfile_info *) objfile->sym_private)->debugsec; - char *debugfmt = xcoff_data (abfd)->xcoff64 ? "XCOFF64" : "XCOFF"; - - struct internal_syment symbol[1]; - union internal_auxent main_aux; - struct coff_symbol cs[1]; - CORE_ADDR file_start_addr = 0; - CORE_ADDR file_end_addr = 0; - - int next_file_symnum = -1; - unsigned int max_symnum; - int just_started = 1; - int depth = 0; - int fcn_start_addr = 0; - - struct coff_symbol fcn_stab_saved; - - /* fcn_cs_saved is global because process_xcoff_symbol needs it. */ - union internal_auxent fcn_aux_saved; - struct context_stack *new; - - char *filestring = " _start_ "; /* Name of the current file. */ - - char *last_csect_name; /* last seen csect's name and value */ - CORE_ADDR last_csect_val; - int last_csect_sec; - - this_symtab_psymtab = pst; - - /* Get the appropriate COFF "constants" related to the file we're - handling. */ - local_symesz = coff_data (abfd)->local_symesz; - - last_source_file = NULL; - last_csect_name = 0; - last_csect_val = 0; - - start_stabs (); - start_symtab (filestring, (char *) NULL, file_start_addr); - record_debugformat (debugfmt); - symnum = ((struct symloc *) pst->read_symtab_private)->first_symnum; - max_symnum = - symnum + ((struct symloc *) pst->read_symtab_private)->numsyms; - first_object_file_end = 0; - - raw_symbol = - ((struct coff_symfile_info *) objfile->sym_private)->symtbl - + symnum * local_symesz; - - while (symnum < max_symnum) - { - - QUIT; /* make this command interruptable. */ - - /* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */ - /* read one symbol into `cs' structure. After processing the - whole symbol table, only string table will be kept in memory, - symbol table and debug section of xcoff will be freed. Thus - we can mark symbols with names in string table as - `alloced'. */ - { - int ii; - - /* Swap and align the symbol into a reasonable C structure. */ - bfd_coff_swap_sym_in (abfd, raw_symbol, symbol); - - cs->c_symnum = symnum; - cs->c_naux = symbol->n_numaux; - if (symbol->n_zeroes) - { - symname_alloced = 0; - /* We must use the original, unswapped, name here so the name field - pointed to by cs->c_name will persist throughout xcoffread. If - we use the new field, it gets overwritten for each symbol. */ - cs->c_name = ((struct external_syment *) raw_symbol)->e.e_name; - /* If it's exactly E_SYMNMLEN characters long it isn't - '\0'-terminated. */ - if (cs->c_name[E_SYMNMLEN - 1] != '\0') - { - char *p; - p = obstack_alloc (&objfile->symbol_obstack, E_SYMNMLEN + 1); - strncpy (p, cs->c_name, E_SYMNMLEN); - p[E_SYMNMLEN] = '\0'; - cs->c_name = p; - symname_alloced = 1; - } - } - else if (symbol->n_sclass & 0x80) - { - cs->c_name = debugsec + symbol->n_offset; - symname_alloced = 0; - } - else - { - /* in string table */ - cs->c_name = strtbl + (int) symbol->n_offset; - symname_alloced = 1; - } - cs->c_value = symbol->n_value; - cs->c_sclass = symbol->n_sclass; - cs->c_secnum = symbol->n_scnum; - cs->c_type = (unsigned) symbol->n_type; - - raw_symbol += local_symesz; - ++symnum; - - /* Save addr of first aux entry. */ - raw_auxptr = raw_symbol; - - /* Skip all the auxents associated with this symbol. */ - for (ii = symbol->n_numaux; ii; --ii) - { - raw_symbol += coff_data (abfd)->local_auxesz; - ++symnum; - } - } - - /* if symbol name starts with ".$" or "$", ignore it. */ - if (cs->c_name[0] == '$' - || (cs->c_name[1] == '$' && cs->c_name[0] == '.')) - continue; - - if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) - { - if (last_source_file) - { - pst->symtab = - end_symtab (cur_src_end_addr, objfile, SECT_OFF_TEXT (objfile)); - end_stabs (); - } - - start_stabs (); - start_symtab ("_globals_", (char *) NULL, (CORE_ADDR) 0); - record_debugformat (debugfmt); - cur_src_end_addr = first_object_file_end; - /* done with all files, everything from here on is globals */ - } - - if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT) - && cs->c_naux == 1) - { - /* Dealing with a symbol with a csect entry. */ - -#define CSECT(PP) ((PP)->x_csect) -#define CSECT_LEN(PP) (CSECT(PP).x_scnlen.l) -#define CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp)) -#define CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp)) -#define CSECT_SCLAS(PP) (CSECT(PP).x_smclas) - - /* Convert the auxent to something we can access. */ - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); - - switch (CSECT_SMTYP (&main_aux)) - { - - case XTY_ER: - /* Ignore all external references. */ - continue; - - case XTY_SD: - /* A section description. */ - { - switch (CSECT_SCLAS (&main_aux)) - { - - case XMC_PR: - { - - /* A program csect is seen. We have to allocate one - symbol table for each program csect. Normally gdb - prefers one symtab for each source file. In case - of AIX, one source file might include more than one - [PR] csect, and they don't have to be adjacent in - terms of the space they occupy in memory. Thus, one - single source file might get fragmented in the - memory and gdb's file start and end address - approach does not work! GCC (and I think xlc) seem - to put all the code in the unnamed program csect. */ - - if (last_csect_name) - { - complete_symtab (filestring, file_start_addr); - cur_src_end_addr = file_end_addr; - end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile)); - end_stabs (); - start_stabs (); - /* Give all csects for this source file the same - name. */ - start_symtab (filestring, NULL, (CORE_ADDR) 0); - record_debugformat (debugfmt); - } - - /* If this is the very first csect seen, - basically `__start'. */ - if (just_started) - { - first_object_file_end - = cs->c_value + CSECT_LEN (&main_aux); - just_started = 0; - } - - file_start_addr = - cs->c_value + ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile)); - file_end_addr = file_start_addr + CSECT_LEN (&main_aux); - - if (cs->c_name && (cs->c_name[0] == '.' - || cs->c_name[0] == '@')) - { - last_csect_name = cs->c_name; - last_csect_val = cs->c_value; - last_csect_sec = secnum_to_section (cs->c_secnum, objfile); - } - } - continue; - - /* All other symbols are put into the minimal symbol - table only. */ - - case XMC_RW: - continue; - - case XMC_TC0: - continue; - - case XMC_TC: - continue; - - default: - /* Ignore the symbol. */ - continue; - } - } - break; - - case XTY_LD: - - switch (CSECT_SCLAS (&main_aux)) - { - case XMC_PR: - /* a function entry point. */ - function_entry_point: - - fcn_start_addr = cs->c_value; - - /* save the function header info, which will be used - when `.bf' is seen. */ - fcn_cs_saved = *cs; - fcn_aux_saved = main_aux; - continue; - - case XMC_GL: - /* shared library function trampoline code entry point. */ - continue; - - case XMC_DS: - /* The symbols often have the same names as debug symbols for - functions, and confuse lookup_symbol. */ - continue; - - default: - /* xlc puts each variable in a separate csect, so we get - an XTY_SD for each variable. But gcc puts several - variables in a csect, so that each variable only gets - an XTY_LD. This will typically be XMC_RW; I suspect - XMC_RO and XMC_BS might be possible too. - These variables are put in the minimal symbol table - only. */ - continue; - } - break; - - case XTY_CM: - /* Common symbols are put into the minimal symbol table only. */ - continue; - - default: - break; - } - } - - /* If explicitly specified as a function, treat is as one. This check - evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur - after the above CSECT check. */ - if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF) - { - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); - goto function_entry_point; - } - - switch (cs->c_sclass) - { - - case C_FILE: - - /* c_value field contains symnum of next .file entry in table - or symnum of first global after last .file. */ - - next_file_symnum = cs->c_value; - - /* Complete symbol table for last object file containing - debugging information. */ - - /* Whether or not there was a csect in the previous file, we - have to call `end_stabs' and `start_stabs' to reset - type_vector, line_vector, etc. structures. */ - - complete_symtab (filestring, file_start_addr); - cur_src_end_addr = file_end_addr; - end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile)); - end_stabs (); - - /* XCOFF, according to the AIX 3.2 documentation, puts the filename - in cs->c_name. But xlc 1.3.0.2 has decided to do things the - standard COFF way and put it in the auxent. We use the auxent if - the symbol is ".file" and an auxent exists, otherwise use the symbol - itself. Simple enough. */ - if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0) - { - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); - filestring = coff_getfilename (&main_aux, objfile); - } - else - filestring = cs->c_name; - - start_stabs (); - start_symtab (filestring, (char *) NULL, (CORE_ADDR) 0); - record_debugformat (debugfmt); - last_csect_name = 0; - - /* reset file start and end addresses. A compilation unit with no text - (only data) should have zero file boundaries. */ - file_start_addr = file_end_addr = 0; - break; - - case C_FUN: - fcn_stab_saved = *cs; - break; - - case C_FCN: - if (STREQ (cs->c_name, ".bf")) - { - CORE_ADDR off = ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile)); - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); - - within_function = 1; - - new = push_context (0, fcn_start_addr + off); - - new->name = define_symbol - (fcn_cs_saved.c_value + off, - fcn_stab_saved.c_name, 0, 0, objfile); - if (new->name != NULL) - SYMBOL_SECTION (new->name) = SECT_OFF_TEXT (objfile); - } - else if (STREQ (cs->c_name, ".ef")) - { - - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); - - /* The value of .ef is the address of epilogue code; - not useful for gdb. */ - /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno - contains number of lines to '}' */ - - if (context_stack_depth <= 0) - { /* We attempted to pop an empty context stack */ - complain (&ef_complaint, cs->c_symnum); - within_function = 0; - break; - } - new = pop_context (); - /* Stack must be empty now. */ - if (context_stack_depth > 0 || new == NULL) - { - complain (&ef_complaint, cs->c_symnum); - within_function = 0; - break; - } - - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, - (fcn_cs_saved.c_value - + fcn_aux_saved.x_sym.x_misc.x_fsize - + ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile))), - objfile); - within_function = 0; - } - break; - - case C_BSTAT: - /* Begin static block. */ - { - struct internal_syment symbol; - - read_symbol (&symbol, cs->c_value); - static_block_base = symbol.n_value; - static_block_section = - secnum_to_section (symbol.n_scnum, objfile); - } - break; - - case C_ESTAT: - /* End of static block. */ - static_block_base = 0; - static_block_section = -1; - break; - - case C_ARG: - case C_REGPARM: - case C_REG: - case C_TPDEF: - case C_STRTAG: - case C_UNTAG: - case C_ENTAG: - { - static struct complaint msg = - {"Unrecognized storage class %d.", 0, 0}; - complain (&msg, cs->c_sclass); - } - break; - - case C_LABEL: - case C_NULL: - /* Ignore these. */ - break; - - case C_HIDEXT: - case C_STAT: - break; - - case C_BINCL: - /* beginning of include file */ - /* In xlc output, C_BINCL/C_EINCL pair doesn't show up in sorted - order. Thus, when wee see them, we might not know enough info - to process them. Thus, we'll be saving them into a table - (inclTable) and postpone their processing. */ - - record_include_begin (cs); - break; - - case C_EINCL: - /* End of include file. */ - /* See the comment after case C_BINCL. */ - record_include_end (cs); - break; - - case C_BLOCK: - if (STREQ (cs->c_name, ".bb")) - { - depth++; - new = push_context (depth, - (cs->c_value - + ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile)))); - } - else if (STREQ (cs->c_name, ".eb")) - { - if (context_stack_depth <= 0) - { /* We attempted to pop an empty context stack */ - complain (&eb_complaint, cs->c_symnum); - break; - } - new = pop_context (); - if (depth-- != new->depth) - { - complain (&eb_complaint, cs->c_symnum); - break; - } - if (local_symbols && context_stack_depth > 0) - { - /* Make a block for the local symbols within. */ - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, - (cs->c_value - + ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile))), - objfile); - } - local_symbols = new->locals; - } - break; - - default: - process_xcoff_symbol (cs, objfile); - break; - } - } - - if (last_source_file) - { - struct symtab *s; - - complete_symtab (filestring, file_start_addr); - cur_src_end_addr = file_end_addr; - s = end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile)); - /* When reading symbols for the last C_FILE of the objfile, try - to make sure that we set pst->symtab to the symtab for the - file, not to the _globals_ symtab. I'm not sure whether this - actually works right or when/if it comes up. */ - if (pst->symtab == NULL) - pst->symtab = s; - end_stabs (); - } -} - -#define SYMBOL_DUP(SYMBOL1, SYMBOL2) \ - (SYMBOL2) = (struct symbol *) \ - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); \ - *(SYMBOL2) = *(SYMBOL1); - - -#define SYMNAME_ALLOC(NAME, ALLOCED) \ - (ALLOCED) ? (NAME) : obsavestring ((NAME), strlen (NAME), &objfile->symbol_obstack); - - -static struct type *func_symbol_type; -static struct type *var_symbol_type; - -/* process one xcoff symbol. */ - -static struct symbol * -process_xcoff_symbol (register struct coff_symbol *cs, struct objfile *objfile) -{ - struct symbol onesymbol; - register struct symbol *sym = &onesymbol; - struct symbol *sym2 = NULL; - char *name, *pp; - - int sec; - CORE_ADDR off; - - if (cs->c_secnum < 0) - { - /* The value is a register number, offset within a frame, etc., - and does not get relocated. */ - off = 0; - sec = -1; - } - else - { - sec = secnum_to_section (cs->c_secnum, objfile); - off = ANOFFSET (objfile->section_offsets, sec); - } - - name = cs->c_name; - if (name[0] == '.') - ++name; - - memset (sym, '\0', sizeof (struct symbol)); - - /* default assumptions */ - SYMBOL_VALUE_ADDRESS (sym) = cs->c_value + off; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_SECTION (sym) = secnum_to_section (cs->c_secnum, objfile); - - if (ISFCN (cs->c_type)) - { - /* At this point, we don't know the type of the function. This - will be patched with the type from its stab entry later on in - patch_block_stabs (), unless the file was compiled without -g. */ - - SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); - SYMBOL_TYPE (sym) = func_symbol_type; - - SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_DUP (sym, sym2); - - if (cs->c_sclass == C_EXT) - add_symbol_to_list (sym2, &global_symbols); - else if (cs->c_sclass == C_HIDEXT || cs->c_sclass == C_STAT) - add_symbol_to_list (sym2, &file_symbols); - } - else - { - /* In case we can't figure out the type, provide default. */ - SYMBOL_TYPE (sym) = var_symbol_type; - - switch (cs->c_sclass) - { -#if 0 - /* The values of functions and global symbols are now resolved - via the global_sym_chain in stabsread.c. */ - case C_FUN: - if (fcn_cs_saved.c_sclass == C_EXT) - add_stab_to_list (name, &global_stabs); - else - add_stab_to_list (name, &file_stabs); - break; - - case C_GSYM: - add_stab_to_list (name, &global_stabs); - break; -#endif - - case C_BCOMM: - common_block_start (cs->c_name, objfile); - break; - - case C_ECOMM: - common_block_end (objfile); - break; - - default: - complain (&storclass_complaint, cs->c_sclass); - /* FALLTHROUGH */ - - case C_DECL: - case C_PSYM: - case C_RPSYM: - case C_ECOML: - case C_LSYM: - case C_RSYM: - case C_GSYM: - - { - sym = define_symbol (cs->c_value + off, cs->c_name, 0, 0, objfile); - if (sym != NULL) - { - SYMBOL_SECTION (sym) = sec; - } - return sym; - } - - case C_STSYM: - - /* For xlc (not GCC), the 'V' symbol descriptor is used for - all statics and we need to distinguish file-scope versus - function-scope using within_function. We do this by - changing the string we pass to define_symbol to use 'S' - where we need to, which is not necessarily super-clean, - but seems workable enough. */ - - if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL) - return NULL; - - ++pp; - if (*pp == 'V' && !within_function) - *pp = 'S'; - sym = define_symbol ((cs->c_value - + ANOFFSET (objfile->section_offsets, - static_block_section)), - cs->c_name, 0, 0, objfile); - if (sym != NULL) - { - SYMBOL_VALUE_ADDRESS (sym) += static_block_base; - SYMBOL_SECTION (sym) = static_block_section; - } - return sym; - - } - } - return sym2; -} - -/* Extract the file name from the aux entry of a C_FILE symbol. - Result is in static storage and is only good for temporary use. */ - -static char * -coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile) -{ - static char buffer[BUFSIZ]; - - if (aux_entry->x_file.x_n.x_zeroes == 0) - strcpy (buffer, - ((struct coff_symfile_info *) objfile->sym_private)->strtbl - + aux_entry->x_file.x_n.x_offset); - else - { - strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN); - buffer[FILNMLEN] = '\0'; - } - return (buffer); -} - -/* Set *SYMBOL to symbol number symno in symtbl. */ -static void -read_symbol (struct internal_syment *symbol, int symno) -{ - int nsyms = - ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) - ->symtbl_num_syms; - char *stbl = - ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) - ->symtbl; - if (symno < 0 || symno >= nsyms) - { - static struct complaint msg = - {"Invalid symbol offset", 0, 0}; - complain (&msg); - symbol->n_value = 0; - symbol->n_scnum = -1; - return; - } - bfd_coff_swap_sym_in (this_symtab_psymtab->objfile->obfd, - stbl + (symno * local_symesz), - symbol); -} - -/* Get value corresponding to symbol number symno in symtbl. */ - -static CORE_ADDR -read_symbol_nvalue (int symno) -{ - struct internal_syment symbol[1]; - - read_symbol (symbol, symno); - return symbol->n_value; -} - - -/* Find the address of the function corresponding to symno, where - symno is the symbol pointed to by the linetable. */ - -static int -read_symbol_lineno (int symno) -{ - struct objfile *objfile = this_symtab_psymtab->objfile; - boolean xcoff64 = xcoff_data (objfile->obfd)->xcoff64; - - struct coff_symfile_info *info = - (struct coff_symfile_info *)objfile->sym_private; - int nsyms = info->symtbl_num_syms; - char *stbl = info->symtbl; - char *strtbl = info->strtbl; - - struct internal_syment symbol[1]; - union internal_auxent main_aux[1]; - - if (symno < 0) - { - complain (&bf_notfound_complaint); - return 0; - } - - /* Note that just searching for a short distance (e.g. 50 symbols) - is not enough, at least in the following case. - - .extern foo - [many .stabx entries] - [a few functions, referring to foo] - .globl foo - .bf - - What happens here is that the assembler moves the .stabx entries - to right before the ".bf" for foo, but the symbol for "foo" is before - all the stabx entries. See PR gdb/2222. */ - - /* Maintaining a table of .bf entries might be preferable to this search. - If I understand things correctly it would need to be done only for - the duration of a single psymtab to symtab conversion. */ - while (symno < nsyms) - { - bfd_coff_swap_sym_in (symfile_bfd, - stbl + (symno * local_symesz), symbol); - if (symbol->n_sclass == C_FCN) - { - char *name = xcoff64 ? strtbl + symbol->n_offset : symbol->n_name; - if (STREQ (name, ".bf")) - goto gotit; - } - symno += symbol->n_numaux + 1; - } - - complain (&bf_notfound_complaint); - return 0; - -gotit: - /* take aux entry and return its lineno */ - symno++; - bfd_coff_swap_aux_in (objfile->obfd, stbl + symno * local_symesz, - symbol->n_type, symbol->n_sclass, - 0, symbol->n_numaux, main_aux); - - return main_aux->x_sym.x_misc.x_lnsz.x_lnno; -} - -/* Support for line number handling */ - -/* This function is called for every section; it finds the outer limits - * of the line table (minimum and maximum file offset) so that the - * mainline code can read the whole thing for efficiency. - */ -static void -find_linenos (bfd *abfd, sec_ptr asect, PTR vpinfo) -{ - struct coff_symfile_info *info; - int size, count; - file_ptr offset, maxoff; - - count = asect->lineno_count; - - if (!STREQ (asect->name, ".text") || count == 0) - return; - - size = count * coff_data (abfd)->local_linesz; - info = (struct coff_symfile_info *) vpinfo; - offset = asect->line_filepos; - maxoff = offset + size; - - if (offset < info->min_lineno_offset || info->min_lineno_offset == 0) - info->min_lineno_offset = offset; - - if (maxoff > info->max_lineno_offset) - info->max_lineno_offset = maxoff; -} - -static void xcoff_psymtab_to_symtab_1 (struct partial_symtab *); - -static void -xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst) -{ - struct cleanup *old_chain; - int i; - - if (!pst) - return; - - if (pst->readin) - { - fprintf_unfiltered - (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", - pst->filename); - return; - } - - /* Read in all partial symtabs on which this one is dependent */ - for (i = 0; i < pst->number_of_dependencies; i++) - if (!pst->dependencies[i]->readin) - { - /* Inform about additional files that need to be read in. */ - if (info_verbose) - { - fputs_filtered (" ", gdb_stdout); - wrap_here (""); - fputs_filtered ("and ", gdb_stdout); - wrap_here (""); - printf_filtered ("%s...", pst->dependencies[i]->filename); - wrap_here (""); /* Flush output */ - gdb_flush (gdb_stdout); - } - xcoff_psymtab_to_symtab_1 (pst->dependencies[i]); - } - - if (((struct symloc *) pst->read_symtab_private)->numsyms != 0) - { - /* Init stuff necessary for reading in symbols. */ - stabsread_init (); - buildsym_init (); - old_chain = make_cleanup (really_free_pendings, 0); - - read_xcoff_symtab (pst); - sort_symtab_syms (pst->symtab); - - do_cleanups (old_chain); - } - - pst->readin = 1; -} - -static void xcoff_psymtab_to_symtab (struct partial_symtab *); - -/* Read in all of the symbols for a given psymtab for real. - Be verbose about it if the user wants that. */ - -static void -xcoff_psymtab_to_symtab (struct partial_symtab *pst) -{ - bfd *sym_bfd; - - if (!pst) - return; - - if (pst->readin) - { - fprintf_unfiltered - (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", - pst->filename); - return; - } - - if (((struct symloc *) pst->read_symtab_private)->numsyms != 0 - || pst->number_of_dependencies) - { - /* Print the message now, before reading the string table, - to avoid disconcerting pauses. */ - if (info_verbose) - { - printf_filtered ("Reading in symbols for %s...", pst->filename); - gdb_flush (gdb_stdout); - } - - sym_bfd = pst->objfile->obfd; - - next_symbol_text_func = xcoff_next_symbol_text; - - xcoff_psymtab_to_symtab_1 (pst); - - /* Match with global symbols. This only needs to be done once, - after all of the symtabs and dependencies have been read in. */ - scan_file_globals (pst->objfile); - - /* Finish up the debug error message. */ - if (info_verbose) - printf_filtered ("done.\n"); - } -} - -static void -xcoff_new_init (struct objfile *objfile) -{ - stabsread_new_init (); - buildsym_new_init (); -} - -/* Do initialization in preparation for reading symbols from OBJFILE. - - We will only be called if this is an XCOFF or XCOFF-like file. - BFD handles figuring out the format of the file, and code in symfile.c - uses BFD's determination to vector to us. */ - -static void -xcoff_symfile_init (struct objfile *objfile) -{ - /* Allocate struct to keep track of the symfile */ - objfile->sym_private = xmmalloc (objfile->md, - sizeof (struct coff_symfile_info)); - - /* XCOFF objects may be reordered, so set OBJF_REORDERED. If we - find this causes a significant slowdown in gdb then we could - set it in the debug symbol readers only when necessary. */ - objfile->flags |= OBJF_REORDERED; - - init_entry_point_info (objfile); -} - -/* Perform any local cleanups required when we are done with a particular - objfile. I.E, we are in the process of discarding all symbol information - for an objfile, freeing up all memory held for it, and unlinking the - objfile struct from the global list of known objfiles. */ - -static void -xcoff_symfile_finish (struct objfile *objfile) -{ - if (objfile->sym_private != NULL) - { - xmfree (objfile->md, objfile->sym_private); - } - - /* Start with a fresh include table for the next objfile. */ - if (inclTable) - { - xfree (inclTable); - inclTable = NULL; - } - inclIndx = inclLength = inclDepth = 0; -} - - -static void -init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile) -{ - long length; - int val; - unsigned char lengthbuf[4]; - char *strtbl; - - ((struct coff_symfile_info *) objfile->sym_private)->strtbl = NULL; - - if (bfd_seek (abfd, offset, SEEK_SET) < 0) - error ("cannot seek to string table in %s: %s", - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - - val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd); - length = bfd_h_get_32 (abfd, lengthbuf); - - /* If no string table is needed, then the file may end immediately - after the symbols. Just return with `strtbl' set to NULL. */ - - if (val != sizeof lengthbuf || length < sizeof lengthbuf) - return; - - /* Allocate string table from symbol_obstack. We will need this table - as long as we have its symbol table around. */ - - strtbl = (char *) obstack_alloc (&objfile->symbol_obstack, length); - ((struct coff_symfile_info *) objfile->sym_private)->strtbl = strtbl; - - /* Copy length buffer, the first byte is usually zero and is - used for stabs with a name length of zero. */ - memcpy (strtbl, lengthbuf, sizeof lengthbuf); - if (length == sizeof lengthbuf) - return; - - val = bfd_bread (strtbl + sizeof lengthbuf, length - sizeof lengthbuf, abfd); - - if (val != length - sizeof lengthbuf) - error ("cannot read string table from %s: %s", - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - if (strtbl[length - 1] != '\0') - error ("bad symbol file: string table does not end with null character"); - - return; -} - -/* If we have not yet seen a function for this psymtab, this is 0. If we - have seen one, it is the offset in the line numbers of the line numbers - for the psymtab. */ -static unsigned int first_fun_line_offset; - -static struct partial_symtab *xcoff_start_psymtab - (struct objfile *, char *, int, - struct partial_symbol **, struct partial_symbol **); - -/* Allocate and partially fill a partial symtab. It will be - completely filled at the end of the symbol list. - - SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR - is the address relative to which its symbols are (incremental) or 0 - (normal). */ - -static struct partial_symtab * -xcoff_start_psymtab (struct objfile *objfile, char *filename, int first_symnum, - struct partial_symbol **global_syms, - struct partial_symbol **static_syms) -{ - struct partial_symtab *result = - start_psymtab_common (objfile, objfile->section_offsets, - filename, - /* We fill in textlow later. */ - 0, - global_syms, static_syms); - - result->read_symtab_private = (char *) - obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc)); - ((struct symloc *) result->read_symtab_private)->first_symnum = first_symnum; - result->read_symtab = xcoff_psymtab_to_symtab; - - /* Deduce the source language from the filename for this psymtab. */ - psymtab_language = deduce_language_from_filename (filename); - - return result; -} - -static struct partial_symtab *xcoff_end_psymtab - (struct partial_symtab *, char **, int, int, - struct partial_symtab **, int, int); - -/* Close off the current usage of PST. - Returns PST, or NULL if the partial symtab was empty and thrown away. - - CAPPING_SYMBOL_NUMBER is the end of pst (exclusive). - - INCLUDE_LIST, NUM_INCLUDES, DEPENDENCY_LIST, and NUMBER_DEPENDENCIES - are the information for includes and dependencies. */ - -static struct partial_symtab * -xcoff_end_psymtab (struct partial_symtab *pst, char **include_list, - int num_includes, int capping_symbol_number, - struct partial_symtab **dependency_list, - int number_dependencies, int textlow_not_set) -{ - int i; - struct objfile *objfile = pst->objfile; - - if (capping_symbol_number != -1) - ((struct symloc *) pst->read_symtab_private)->numsyms = - capping_symbol_number - - ((struct symloc *) pst->read_symtab_private)->first_symnum; - ((struct symloc *) pst->read_symtab_private)->lineno_off = - first_fun_line_offset; - first_fun_line_offset = 0; - pst->n_global_syms = - objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset); - pst->n_static_syms = - objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset); - - pst->number_of_dependencies = number_dependencies; - if (number_dependencies) - { - pst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, - number_dependencies * sizeof (struct partial_symtab *)); - memcpy (pst->dependencies, dependency_list, - number_dependencies * sizeof (struct partial_symtab *)); - } - else - pst->dependencies = 0; - - for (i = 0; i < num_includes; i++) - { - struct partial_symtab *subpst = - allocate_psymtab (include_list[i], objfile); - - subpst->section_offsets = pst->section_offsets; - subpst->read_symtab_private = - (char *) obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct symloc)); - ((struct symloc *) subpst->read_symtab_private)->first_symnum = 0; - ((struct symloc *) subpst->read_symtab_private)->numsyms = 0; - subpst->textlow = 0; - subpst->texthigh = 0; - - /* We could save slight bits of space by only making one of these, - shared by the entire set of include files. FIXME-someday. */ - subpst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct partial_symtab *)); - subpst->dependencies[0] = pst; - subpst->number_of_dependencies = 1; - - subpst->globals_offset = - subpst->n_global_syms = - subpst->statics_offset = - subpst->n_static_syms = 0; - - subpst->readin = 0; - subpst->symtab = 0; - subpst->read_symtab = pst->read_symtab; - } - - sort_pst_symbols (pst); - - /* If there is already a psymtab or symtab for a file of this name, - remove it. (If there is a symtab, more drastic things also - happen.) This happens in VxWorks. */ - 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. */ - /* Empty psymtabs happen as a result of header files which don't have - any symbols in them. There can be a lot of them. */ - - discard_psymtab (pst); - - /* Indicate that psymtab was thrown away. */ - pst = (struct partial_symtab *) NULL; - } - return pst; -} - -static void swap_sym (struct internal_syment *, - union internal_auxent *, char **, char **, - unsigned int *, struct objfile *); - -/* Swap raw symbol at *RAW and put the name in *NAME, the symbol in - *SYMBOL, the first auxent in *AUX. Advance *RAW and *SYMNUMP over - the symbol and its auxents. */ - -static void -swap_sym (struct internal_syment *symbol, union internal_auxent *aux, - char **name, char **raw, unsigned int *symnump, - struct objfile *objfile) -{ - bfd_coff_swap_sym_in (objfile->obfd, *raw, symbol); - if (symbol->n_zeroes) - { - /* If it's exactly E_SYMNMLEN characters long it isn't - '\0'-terminated. */ - if (symbol->n_name[E_SYMNMLEN - 1] != '\0') - { - /* FIXME: wastes memory for symbols which we don't end up putting - into the minimal symbols. */ - char *p; - p = obstack_alloc (&objfile->psymbol_obstack, E_SYMNMLEN + 1); - strncpy (p, symbol->n_name, E_SYMNMLEN); - p[E_SYMNMLEN] = '\0'; - *name = p; - } - else - /* Point to the unswapped name as that persists as long as the - objfile does. */ - *name = ((struct external_syment *) *raw)->e.e_name; - } - else if (symbol->n_sclass & 0x80) - { - *name = ((struct coff_symfile_info *) objfile->sym_private)->debugsec - + symbol->n_offset; - } - else - { - *name = ((struct coff_symfile_info *) objfile->sym_private)->strtbl - + symbol->n_offset; - } - ++*symnump; - *raw += coff_data (objfile->obfd)->local_symesz; - if (symbol->n_numaux > 0) - { - bfd_coff_swap_aux_in (objfile->obfd, *raw, symbol->n_type, - symbol->n_sclass, 0, symbol->n_numaux, aux); - - *symnump += symbol->n_numaux; - *raw += coff_data (objfile->obfd)->local_symesz * symbol->n_numaux; - } -} - -static void -scan_xcoff_symtab (struct objfile *objfile) -{ - CORE_ADDR toc_offset = 0; /* toc offset value in data section. */ - char *filestring = NULL; - - char *namestring; - int past_first_source_file = 0; - bfd *abfd; - asection *bfd_sect; - unsigned int nsyms; - - /* Current partial symtab */ - struct partial_symtab *pst; - - /* List of current psymtab's include files */ - char **psymtab_include_list; - int includes_allocated; - int includes_used; - - /* Index within current psymtab dependency list */ - struct partial_symtab **dependency_list; - int dependencies_used, dependencies_allocated; - - char *sraw_symbol; - struct internal_syment symbol; - union internal_auxent main_aux[5]; - unsigned int ssymnum; - - char *last_csect_name = NULL; /* last seen csect's name and value */ - CORE_ADDR last_csect_val = 0; - int last_csect_sec = 0; - int misc_func_recorded = 0; /* true if any misc. function */ - int textlow_not_set = 1; - - pst = (struct partial_symtab *) 0; - - includes_allocated = 30; - includes_used = 0; - psymtab_include_list = (char **) alloca (includes_allocated * - sizeof (char *)); - - dependencies_allocated = 30; - dependencies_used = 0; - dependency_list = - (struct partial_symtab **) alloca (dependencies_allocated * - sizeof (struct partial_symtab *)); - - last_source_file = NULL; - - abfd = objfile->obfd; - - sraw_symbol = ((struct coff_symfile_info *) objfile->sym_private)->symtbl; - nsyms = ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms; - ssymnum = 0; - while (ssymnum < nsyms) - { - int sclass; - - QUIT; - - bfd_coff_swap_sym_in (abfd, sraw_symbol, &symbol); - sclass = symbol.n_sclass; - - switch (sclass) - { - case C_EXT: - case C_HIDEXT: - { - /* The CSECT auxent--always the last auxent. */ - union internal_auxent csect_aux; - unsigned int symnum_before = ssymnum; - - swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, - &ssymnum, objfile); - if (symbol.n_numaux > 1) - { - bfd_coff_swap_aux_in - (objfile->obfd, - sraw_symbol - coff_data (abfd)->local_symesz, - symbol.n_type, - symbol.n_sclass, - symbol.n_numaux - 1, - symbol.n_numaux, - &csect_aux); - } - else - csect_aux = main_aux[0]; - - /* If symbol name starts with ".$" or "$", ignore it. */ - if (namestring[0] == '$' - || (namestring[0] == '.' && namestring[1] == '$')) - break; - - switch (csect_aux.x_csect.x_smtyp & 0x7) - { - case XTY_SD: - switch (csect_aux.x_csect.x_smclas) - { - case XMC_PR: - if (last_csect_name) - { - /* If no misc. function recorded in the last - seen csect, enter it as a function. This - will take care of functions like strcmp() - compiled by xlc. */ - - if (!misc_func_recorded) - { - RECORD_MINIMAL_SYMBOL - (last_csect_name, last_csect_val, - mst_text, last_csect_sec, - objfile); - } - - if (pst != NULL) - { - /* We have to allocate one psymtab for - each program csect, because their text - sections need not be adjacent. */ - xcoff_end_psymtab - (pst, psymtab_include_list, includes_used, - symnum_before, dependency_list, - dependencies_used, textlow_not_set); - includes_used = 0; - dependencies_used = 0; - /* Give all psymtabs for this source file the same - name. */ - pst = xcoff_start_psymtab - (objfile, - filestring, - symnum_before, - objfile->global_psymbols.next, - objfile->static_psymbols.next); - } - } - /* Activate the misc_func_recorded mechanism for - compiler- and linker-generated CSECTs like ".strcmp" - and "@FIX1". */ - if (namestring && (namestring[0] == '.' - || namestring[0] == '@')) - { - last_csect_name = namestring; - last_csect_val = symbol.n_value; - last_csect_sec = - secnum_to_section (symbol.n_scnum, objfile); - } - if (pst != NULL) - { - CORE_ADDR highval = - symbol.n_value + csect_aux.x_csect.x_scnlen.l; - if (highval > pst->texthigh) - pst->texthigh = highval; - if (pst->textlow == 0 || symbol.n_value < pst->textlow) - pst->textlow = symbol.n_value; - } - misc_func_recorded = 0; - break; - - case XMC_RW: - /* Data variables are recorded in the minimal symbol - table, except for section symbols. */ - if (*namestring != '.') - prim_record_minimal_symbol_and_info - (namestring, symbol.n_value, - sclass == C_HIDEXT ? mst_file_data : mst_data, - NULL, secnum_to_section (symbol.n_scnum, objfile), - NULL, objfile); - break; - - case XMC_TC0: - if (toc_offset) - warning ("More than one XMC_TC0 symbol found."); - toc_offset = symbol.n_value; - - /* Make TOC offset relative to start address of section. */ - bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile); - if (bfd_sect) - toc_offset -= bfd_section_vma (objfile->obfd, bfd_sect); - break; - - case XMC_TC: - /* These symbols tell us where the TOC entry for a - variable is, not the variable itself. */ - break; - - default: - break; - } - break; - - case XTY_LD: - switch (csect_aux.x_csect.x_smclas) - { - case XMC_PR: - /* A function entry point. */ - - if (first_fun_line_offset == 0 && symbol.n_numaux > 1) - first_fun_line_offset = - main_aux[0].x_sym.x_fcnary.x_fcn.x_lnnoptr; - RECORD_MINIMAL_SYMBOL - (namestring, symbol.n_value, - sclass == C_HIDEXT ? mst_file_text : mst_text, - secnum_to_section (symbol.n_scnum, objfile), - objfile); - break; - - case XMC_GL: - /* shared library function trampoline code entry - point. */ - - /* record trampoline code entries as - mst_solib_trampoline symbol. When we lookup mst - symbols, we will choose mst_text over - mst_solib_trampoline. */ - RECORD_MINIMAL_SYMBOL - (namestring, symbol.n_value, - mst_solib_trampoline, - secnum_to_section (symbol.n_scnum, objfile), - objfile); - break; - - case XMC_DS: - /* The symbols often have the same names as - debug symbols for functions, and confuse - lookup_symbol. */ - break; - - default: - - /* xlc puts each variable in a separate csect, - so we get an XTY_SD for each variable. But - gcc puts several variables in a csect, so - that each variable only gets an XTY_LD. We - still need to record them. This will - typically be XMC_RW; I suspect XMC_RO and - XMC_BS might be possible too. */ - if (*namestring != '.') - prim_record_minimal_symbol_and_info - (namestring, symbol.n_value, - sclass == C_HIDEXT ? mst_file_data : mst_data, - NULL, secnum_to_section (symbol.n_scnum, objfile), - NULL, objfile); - break; - } - break; - - case XTY_CM: - switch (csect_aux.x_csect.x_smclas) - { - case XMC_RW: - case XMC_BS: - /* Common variables are recorded in the minimal symbol - table, except for section symbols. */ - if (*namestring != '.') - prim_record_minimal_symbol_and_info - (namestring, symbol.n_value, - sclass == C_HIDEXT ? mst_file_bss : mst_bss, - NULL, secnum_to_section (symbol.n_scnum, objfile), - NULL, objfile); - break; - } - break; - - default: - break; - } - } - break; - case C_FILE: - { - unsigned int symnum_before; - - symnum_before = ssymnum; - swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, - &ssymnum, objfile); - - /* See if the last csect needs to be recorded. */ - - if (last_csect_name && !misc_func_recorded) - { - - /* If no misc. function recorded in the last seen csect, enter - it as a function. This will take care of functions like - strcmp() compiled by xlc. */ - - RECORD_MINIMAL_SYMBOL - (last_csect_name, last_csect_val, - mst_text, last_csect_sec, objfile); - } - - if (pst) - { - xcoff_end_psymtab (pst, psymtab_include_list, includes_used, - symnum_before, dependency_list, - dependencies_used, textlow_not_set); - includes_used = 0; - dependencies_used = 0; - } - first_fun_line_offset = 0; - - /* XCOFF, according to the AIX 3.2 documentation, puts the - filename in cs->c_name. But xlc 1.3.0.2 has decided to - do things the standard COFF way and put it in the auxent. - We use the auxent if the symbol is ".file" and an auxent - exists, otherwise use the symbol itself. */ - if (!strcmp (namestring, ".file") && symbol.n_numaux > 0) - { - filestring = coff_getfilename (&main_aux[0], objfile); - } - else - filestring = namestring; - - pst = xcoff_start_psymtab (objfile, - filestring, - symnum_before, - objfile->global_psymbols.next, - objfile->static_psymbols.next); - last_csect_name = NULL; - } - break; - - default: - { - static struct complaint msg = - {"Storage class %d not recognized during scan", 0, 0}; - complain (&msg, sclass); - } - /* FALLTHROUGH */ - - /* C_FCN is .bf and .ef symbols. I think it is sufficient - to handle only the C_FUN and C_EXT. */ - case C_FCN: - - case C_BSTAT: - case C_ESTAT: - case C_ARG: - case C_REGPARM: - case C_REG: - case C_TPDEF: - case C_STRTAG: - case C_UNTAG: - case C_ENTAG: - case C_LABEL: - case C_NULL: - - /* C_EINCL means we are switching back to the main file. But there - is no reason to care; the only thing we want to know about - includes is the names of all the included (.h) files. */ - case C_EINCL: - - case C_BLOCK: - - /* I don't think C_STAT is used in xcoff; C_HIDEXT appears to be - used instead. */ - case C_STAT: - - /* I don't think the name of the common block (as opposed to the - variables within it) is something which is user visible - currently. */ - case C_BCOMM: - case C_ECOMM: - - case C_PSYM: - case C_RPSYM: - - /* I think we can ignore C_LSYM; types on xcoff seem to use C_DECL - so C_LSYM would appear to be only for locals. */ - case C_LSYM: - - case C_AUTO: - case C_RSYM: - { - /* We probably could save a few instructions by assuming that - C_LSYM, C_PSYM, etc., never have auxents. */ - int naux1 = symbol.n_numaux + 1; - ssymnum += naux1; - sraw_symbol += bfd_coff_symesz (abfd) * naux1; - } - break; - - case C_BINCL: - { - /* Mark down an include file in the current psymtab */ - enum language tmp_language; - swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, - &ssymnum, objfile); - - tmp_language = deduce_language_from_filename (namestring); - - /* Only change the psymtab's language if we've learned - something useful (eg. tmp_language is not language_unknown). - In addition, to match what start_subfile does, never change - from C++ to C. */ - if (tmp_language != language_unknown - && (tmp_language != language_c - || psymtab_language != language_cplus)) - psymtab_language = tmp_language; - - /* In C++, one may expect the same filename to come round many - times, when code is coming alternately from the main file - and from inline functions in other files. So I check to see - if this is a file we've seen before -- either the main - source file, or a previously included file. - - This seems to be a lot of time to be spending on N_SOL, but - things like "break c-exp.y:435" need to work (I - suppose the psymtab_include_list could be hashed or put - in a binary tree, if profiling shows this is a major hog). */ - if (pst && STREQ (namestring, pst->filename)) - continue; - { - register int i; - for (i = 0; i < includes_used; i++) - if (STREQ (namestring, psymtab_include_list[i])) - { - i = -1; - break; - } - if (i == -1) - continue; - } - psymtab_include_list[includes_used++] = namestring; - if (includes_used >= includes_allocated) - { - char **orig = psymtab_include_list; - - psymtab_include_list = (char **) - alloca ((includes_allocated *= 2) * - sizeof (char *)); - memcpy ((PTR) psymtab_include_list, (PTR) orig, - includes_used * sizeof (char *)); - } - continue; - } - case C_FUN: - /* The value of the C_FUN is not the address of the function (it - appears to be the address before linking), but as long as it - is smaller than the actual address, then find_pc_partial_function - will use the minimal symbols instead. I hope. */ - - case C_GSYM: - case C_ECOML: - case C_DECL: - case C_STSYM: - { - - static struct complaint function_outside_compilation_unit = { - "function `%s' appears to be defined outside of all compilation units", 0, 0 - }; - - char *p; - swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, - &ssymnum, objfile); - - p = (char *) strchr (namestring, ':'); - if (!p) - continue; /* Not a debugging symbol. */ - - /* Main processing section for debugging symbols which - the initial read through the symbol tables needs to worry - about. If we reach this point, the symbol which we are - considering is definitely one we are interested in. - p must also contain the (valid) index into the namestring - which indicates the debugging type symbol. */ - - switch (p[1]) - { - case 'S': - symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)); -#ifdef STATIC_TRANSFORM_NAME - namestring = STATIC_TRANSFORM_NAME (namestring); -#endif - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - &objfile->static_psymbols, - 0, symbol.n_value, - psymtab_language, objfile); - continue; - - case 'G': - symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)); - /* The addresses in these entries are reported to be - wrong. See the code that reads 'G's for symtabs. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - &objfile->global_psymbols, - 0, symbol.n_value, - psymtab_language, objfile); - continue; - - case 'T': - /* When a 'T' entry is defining an anonymous enum, it - may have a name which is the empty string, or a - single space. Since they're not really defining a - symbol, those shouldn't go in the partial symbol - table. We do pick up the elements of such enums at - 'check_enum:', below. */ - if (p >= namestring + 2 - || (p == namestring + 1 - && namestring[0] != ' ')) - { - add_psymbol_to_list (namestring, p - namestring, - STRUCT_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - symbol.n_value, 0, - psymtab_language, objfile); - if (p[2] == 't') - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - symbol.n_value, 0, - psymtab_language, objfile); - p += 1; - } - /* The semantics of C++ state that "struct foo { ... }" - also defines a typedef for "foo". Unfortuantely, cfront - never makes the typedef when translating from C++ to C. - We make the typedef here so that "ptype foo" works as - expected for cfront translated code. */ - else if (psymtab_language == language_cplus) - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - symbol.n_value, 0, - psymtab_language, objfile); - } - } - goto check_enum; - - case 't': - if (p != namestring) /* a name is there, not just :T... */ - { - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - symbol.n_value, 0, - psymtab_language, objfile); - } - check_enum: - /* If this is an enumerated type, we need to - add all the enum constants to the partial symbol - table. This does not cover enums without names, e.g. - "enum {a, b} c;" in C, but fortunately those are - rare. There is no way for GDB to find those from the - enum type without spending too much time on it. Thus - to solve this problem, the compiler needs to put out the - enum in a nameless type. GCC2 does this. */ - - /* We are looking for something of the form - ":" ("t" | "T") [ "="] "e" - { ":" ","} ";". */ - - /* Skip over the colon and the 't' or 'T'. */ - p += 2; - /* This type may be given a number. Also, numbers can come - in pairs like (0,26). Skip over it. */ - while ((*p >= '0' && *p <= '9') - || *p == '(' || *p == ',' || *p == ')' - || *p == '=') - p++; - - if (*p++ == 'e') - { - /* The aix4 compiler emits extra crud before the members. */ - if (*p == '-') - { - /* Skip over the type (?). */ - while (*p != ':') - p++; - - /* Skip over the colon. */ - p++; - } - - /* We have found an enumerated type. */ - /* According to comments in read_enum_type - a comma could end it instead of a semicolon. - I don't know where that happens. - Accept either. */ - while (*p && *p != ';' && *p != ',') - { - char *q; - - /* Check for and handle cretinous dbx symbol name - continuation! */ - if (*p == '\\' || (*p == '?' && p[1] == '\0')) - p = next_symbol_text (objfile); - - /* Point to the character after the name - of the enum constant. */ - for (q = p; *q && *q != ':'; q++) - ; - /* Note that the value doesn't matter for - enum constants in psymtabs, just in symtabs. */ - add_psymbol_to_list (p, q - p, - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, 0, - 0, psymtab_language, objfile); - /* Point past the name. */ - p = q; - /* Skip over the value. */ - while (*p && *p != ',') - p++; - /* Advance past the comma. */ - if (*p) - p++; - } - } - continue; - - case 'c': - /* Constant, e.g. from "const" in Pascal. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, symbol.n_value, - 0, psymtab_language, objfile); - continue; - - case 'f': - if (! pst) - { - int name_len = p - namestring; - char *name = xmalloc (name_len + 1); - memcpy (name, namestring, name_len); - name[name_len] = '\0'; - complain (&function_outside_compilation_unit, name); - xfree (name); - } - symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - &objfile->static_psymbols, - 0, symbol.n_value, - psymtab_language, objfile); - continue; - - /* Global functions were ignored here, but now they - are put into the global psymtab like one would expect. - They're also in the minimal symbol table. */ - case 'F': - if (! pst) - { - int name_len = p - namestring; - char *name = xmalloc (name_len + 1); - memcpy (name, namestring, name_len); - name[name_len] = '\0'; - complain (&function_outside_compilation_unit, name); - xfree (name); - } - symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - &objfile->global_psymbols, - 0, symbol.n_value, - psymtab_language, objfile); - continue; - - /* Two things show up here (hopefully); static symbols of - local scope (static used inside braces) or extensions - of structure symbols. We can ignore both. */ - case 'V': - case '(': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - case '#': /* for symbol identification (used in live ranges) */ - /* added to support cfront stabs strings */ - case 'Z': /* for definition continuations */ - case 'P': /* for prototypes */ - continue; - - case ':': - /* It is a C++ nested symbol. We don't need to record it - (I don't think); if we try to look up foo::bar::baz, - then symbols for the symtab containing foo should get - read in, I think. */ - /* Someone says sun cc puts out symbols like - /foo/baz/maclib::/usr/local/bin/maclib, - which would get here with a symbol type of ':'. */ - continue; - - default: - /* Unexpected symbol descriptor. The second and subsequent stabs - of a continued stab can show up here. The question is - whether they ever can mimic a normal stab--it would be - nice if not, since we certainly don't want to spend the - time searching to the end of every string looking for - a backslash. */ - - complain (&unknown_symchar_complaint, p[1]); - - /* Ignore it; perhaps it is an extension that we don't - know about. */ - continue; - } - } - } - } - - if (pst) - { - xcoff_end_psymtab (pst, psymtab_include_list, includes_used, - ssymnum, dependency_list, - dependencies_used, textlow_not_set); - } - - /* Record the toc offset value of this symbol table into objfile structure. - If no XMC_TC0 is found, toc_offset should be zero. Another place to obtain - this information would be file auxiliary header. */ - - ((struct coff_symfile_info *) objfile->sym_private)->toc_offset = toc_offset; -} - -/* Return the toc offset value for a given objfile. */ - -CORE_ADDR -get_toc_offset (struct objfile *objfile) -{ - if (objfile) - return ((struct coff_symfile_info *) objfile->sym_private)->toc_offset; - return 0; -} - -/* Scan and build partial symbols for a symbol file. - We have been initialized by a call to dbx_symfile_init, which - put all the relevant info into a "struct dbx_symfile_info", - hung off the objfile structure. - - SECTION_OFFSETS contains offsets relative to which the symbols in the - various sections are (depending where the sections were actually loaded). - MAINLINE is true if we are reading the main symbol - table (as opposed to a shared lib or dynamically loaded file). */ - -static void -xcoff_initial_scan (struct objfile *objfile, int mainline) -{ - bfd *abfd; - int val; - struct cleanup *back_to; - int num_symbols; /* # of symbols */ - file_ptr symtab_offset; /* symbol table and */ - file_ptr stringtab_offset; /* string table file offsets */ - struct coff_symfile_info *info; - char *name; - unsigned int size; - - info = (struct coff_symfile_info *) objfile->sym_private; - symfile_bfd = abfd = objfile->obfd; - name = objfile->name; - - num_symbols = bfd_get_symcount (abfd); /* # of symbols */ - symtab_offset = obj_sym_filepos (abfd); /* symbol table file offset */ - stringtab_offset = symtab_offset + - num_symbols * coff_data (abfd)->local_symesz; - - info->min_lineno_offset = 0; - info->max_lineno_offset = 0; - bfd_map_over_sections (abfd, find_linenos, info); - - if (num_symbols > 0) - { - /* Read the string table. */ - init_stringtab (abfd, stringtab_offset, objfile); - - /* Read the .debug section, if present. */ - { - sec_ptr secp; - bfd_size_type length; - char *debugsec = NULL; - - secp = bfd_get_section_by_name (abfd, ".debug"); - if (secp) - { - length = bfd_section_size (abfd, secp); - if (length) - { - debugsec = - (char *) obstack_alloc (&objfile->symbol_obstack, length); - - if (!bfd_get_section_contents (abfd, secp, debugsec, - (file_ptr) 0, length)) - { - error ("Error reading .debug section of `%s': %s", - name, bfd_errmsg (bfd_get_error ())); - } - } - } - ((struct coff_symfile_info *) objfile->sym_private)->debugsec = - debugsec; - } - } - - /* Read the symbols. We keep them in core because we will want to - access them randomly in read_symbol*. */ - val = bfd_seek (abfd, symtab_offset, SEEK_SET); - if (val < 0) - error ("Error reading symbols from %s: %s", - name, bfd_errmsg (bfd_get_error ())); - size = coff_data (abfd)->local_symesz * num_symbols; - ((struct coff_symfile_info *) objfile->sym_private)->symtbl = - obstack_alloc (&objfile->symbol_obstack, size); - ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms = - num_symbols; - - val = bfd_bread (((struct coff_symfile_info *) objfile->sym_private)->symtbl, - size, abfd); - if (val != size) - perror_with_name ("reading symbol table"); - - /* If we are reinitializing, or if we have never loaded syms yet, init */ - if (mainline - || (objfile->global_psymbols.size == 0 - && objfile->static_psymbols.size == 0)) - /* I'm not sure how how good num_symbols is; the rule of thumb in - init_psymbol_list was developed for a.out. On the one hand, - num_symbols includes auxents. On the other hand, it doesn't - include N_SLINE. */ - init_psymbol_list (objfile, num_symbols); - - free_pending_blocks (); - back_to = make_cleanup (really_free_pendings, 0); - - init_minimal_symbol_collection (); - make_cleanup_discard_minimal_symbols (); - - /* Now that the symbol table data of the executable file are all in core, - process them and define symbols accordingly. */ - - scan_xcoff_symtab (objfile); - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); -} - -static void -xcoff_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs) -{ - asection *sect = NULL; - int i; - - objfile->num_sections = SECT_OFF_MAX; - objfile->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS); - - /* Initialize the section indexes for future use. */ - sect = bfd_get_section_by_name (objfile->obfd, ".text"); - if (sect) - objfile->sect_index_text = sect->index; - - sect = bfd_get_section_by_name (objfile->obfd, ".data"); - if (sect) - objfile->sect_index_data = sect->index; - - sect = bfd_get_section_by_name (objfile->obfd, ".bss"); - if (sect) - objfile->sect_index_bss = sect->index; - - sect = bfd_get_section_by_name (objfile->obfd, ".rodata"); - if (sect) - objfile->sect_index_rodata = sect->index; - - for (i = 0; i < objfile->num_sections; ++i) - { - /* syms_from_objfile kindly subtracts from addr the - bfd_section_vma of the .text section. This strikes me as - wrong--whether the offset to be applied to symbol reading is - relative to the start address of the section depends on the - symbol format. In any event, this whole "addr" concept is - pretty broken (it doesn't handle any section but .text - sensibly), so just ignore the addr parameter and use 0. - rs6000-nat.c will set the correct section offsets via - objfile_relocate. */ - (objfile->section_offsets)->offsets[i] = 0; - } -} - -/* Register our ability to parse symbols for xcoff BFD files. */ - -static struct sym_fns xcoff_sym_fns = -{ - - /* It is possible that coff and xcoff should be merged as - they do have fundamental similarities (for example, the extra storage - classes used for stabs could presumably be recognized in any COFF file). - However, in addition to obvious things like all the csect hair, there are - some subtler differences between xcoffread.c and coffread.c, notably - the fact that coffread.c has no need to read in all the symbols, but - xcoffread.c reads all the symbols and does in fact randomly access them - (in C_BSTAT and line number processing). */ - - bfd_target_xcoff_flavour, - - xcoff_new_init, /* sym_new_init: init anything gbl to entire symtab */ - xcoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ - xcoff_initial_scan, /* sym_read: read a symbol file into symtab */ - xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */ - xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_xcoffread (void) -{ - add_symtab_fns (&xcoff_sym_fns); - - func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0, - "", NULL); - TYPE_TARGET_TYPE (func_symbol_type) = builtin_type_int; - var_symbol_type = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0, - "", NULL); -} diff --git a/contrib/gdb/gdb/xcoffsolib.c b/contrib/gdb/gdb/xcoffsolib.c deleted file mode 100644 index 99d2cc8e8f7..00000000000 --- a/contrib/gdb/gdb/xcoffsolib.c +++ /dev/null @@ -1,196 +0,0 @@ -/* Shared library support for RS/6000 (xcoff) object files, for GDB. - Copyright 1991, 1992, 1995, 1996, 1999, 2000, 2001 - Free Software Foundation, Inc. - Contributed by IBM Corporation. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "bfd.h" -#include "xcoffsolib.h" -#include "inferior.h" -#include "gdbcmd.h" -#include "symfile.h" -#include "frame.h" -#include "gdb_regex.h" - - -/* If ADDR lies in a shared library, return its name. - Note that returned name points to static data whose content is overwritten - by each call. */ - -char * -xcoff_solib_address (CORE_ADDR addr) -{ - static char *buffer = NULL; - struct vmap *vp = vmap; - - /* The first vmap entry is for the exec file. */ - - if (vp == NULL) - return NULL; - for (vp = vp->nxt; vp; vp = vp->nxt) - if (vp->tstart <= addr && addr < vp->tend) - { - xfree (buffer); - xasprintf (&buffer, "%s%s%s%s", - vp->name, - *vp->member ? "(" : "", - vp->member, - *vp->member ? ")" : ""); - return buffer; - } - return NULL; -} - -static void solib_info (char *, int); -static void sharedlibrary_command (char *pattern, int from_tty); - -static void -solib_info (char *args, int from_tty) -{ - struct vmap *vp = vmap; - - /* Check for new shared libraries loaded with load (). */ - if (! ptid_equal (inferior_ptid, null_ptid)) - xcoff_relocate_symtab (PIDGET (inferior_ptid)); - - if (vp == NULL || vp->nxt == NULL) - { - printf_unfiltered ("No shared libraries loaded at this time.\n"); - return; - } - - /* Skip over the first vmap, it is the main program, always loaded. */ - vp = vp->nxt; - - printf_unfiltered ("\ -Text Range Data Range Syms Shared Object Library\n"); - - for (; vp != NULL; vp = vp->nxt) - { - printf_unfiltered ("0x%s-0x%s 0x%s-0x%s %s %s%s%s%s\n", - paddr (vp->tstart),paddr (vp->tend), - paddr (vp->dstart), paddr (vp->dend), - vp->loaded ? "Yes" : "No ", - vp->name, - *vp->member ? "(" : "", - vp->member, - *vp->member ? ")" : ""); - } -} - -static void -sharedlibrary_command (char *pattern, int from_tty) -{ - dont_repeat (); - - /* Check for new shared libraries loaded with load (). */ - if (! ptid_equal (inferior_ptid, null_ptid)) - xcoff_relocate_symtab (PIDGET (inferior_ptid)); - - if (pattern) - { - char *re_err = re_comp (pattern); - - if (re_err) - error ("Invalid regexp: %s", re_err); - } - - /* Walk the list of currently loaded shared libraries, and read - symbols for any that match the pattern --- or any whose symbols - aren't already loaded, if no pattern was given. */ - { - int any_matches = 0; - int loaded_any_symbols = 0; - struct vmap *vp = vmap; - - if (!vp) - return; - - /* skip over the first vmap, it is the main program, always loaded. */ - for (vp = vp->nxt; vp; vp = vp->nxt) - if (! pattern - || re_exec (vp->name) - || (*vp->member && re_exec (vp->member))) - { - any_matches = 1; - - if (vp->loaded) - { - if (from_tty) - printf_unfiltered ("Symbols already loaded for %s\n", - vp->name); - } - else - { - if (vmap_add_symbols (vp)) - loaded_any_symbols = 1; - } - } - - if (from_tty && pattern && ! any_matches) - printf_unfiltered - ("No loaded shared libraries match the pattern `%s'.\n", pattern); - - if (loaded_any_symbols) - { - /* Getting new symbols may change our opinion about what is - frameless. */ - reinit_frame_cache (); - } - } -} - -/* LOCAL FUNCTION - - no_shared_libraries -- handle command to explicitly discard symbols - from shared libraries. - - DESCRIPTION - - Implements the command "nosharedlibrary", which discards symbols - that have been auto-loaded from shared libraries. Symbols from - shared libraries that were added by explicit request of the user - are not discarded. Also called from remote.c. */ - -void -no_shared_libraries (char *ignored, int from_tty) -{ - /* FIXME */ -} - -void -_initialize_xcoffsolib (void) -{ - add_com ("sharedlibrary", class_files, sharedlibrary_command, - "Load shared object library symbols for files matching REGEXP."); - add_info ("sharedlibrary", solib_info, - "Status of loaded shared object libraries"); - - add_show_from_set - (add_set_cmd ("auto-solib-add", class_support, var_boolean, - (char *) &auto_solib_add, - "Set autoloading of shared library symbols.\n\ -If \"on\", symbols from all shared object libraries will be loaded\n\ -automatically when the inferior begins execution, when the dynamic linker\n\ -informs gdb that a new library has been loaded, or when attaching to the\n\ -inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", - &setlist), - &showlist); -} From fdedc45ff6ac8d3d358f1544d3f6f2b1c66c4365 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 19 Jun 2004 15:43:52 +0000 Subject: [PATCH 2/5] This file was not part of the GDB 5.2.1 import and should have been deleted from the vendor branch. --- contrib/gdb/ChangeLog | 7746 ---------------------------- contrib/gdb/MAINTAINERS | 114 - contrib/gdb/bfd/COPYING | 339 -- contrib/gdb/bfd/Makefile.in | 1090 ---- contrib/gdb/bfd/PORTING | 83 - contrib/gdb/bfd/TODO | 25 - contrib/gdb/bfd/VERSION | 1 - contrib/gdb/bfd/acconfig.h | 19 - contrib/gdb/bfd/aclocal.m4 | 43 - contrib/gdb/bfd/aix386-core.c | 285 - contrib/gdb/bfd/aout-adobe.c | 528 -- contrib/gdb/bfd/aout-arm.c | 548 -- contrib/gdb/bfd/aout-encap.c | 236 - contrib/gdb/bfd/aout-ns32k.c | 399 -- contrib/gdb/bfd/aout-target.h | 607 --- contrib/gdb/bfd/aout0.c | 32 - contrib/gdb/bfd/aout32.c | 23 - contrib/gdb/bfd/aout64.c | 31 - contrib/gdb/bfd/aoutf1.h | 788 --- contrib/gdb/bfd/aoutx.h | 5525 -------------------- contrib/gdb/bfd/archive.c | 2094 -------- contrib/gdb/bfd/archures.c | 720 --- contrib/gdb/bfd/bfd-in.h | 668 --- contrib/gdb/bfd/bfd-in2.h | 2479 --------- contrib/gdb/bfd/bfd.c | 1144 ---- contrib/gdb/bfd/binary.c | 348 -- contrib/gdb/bfd/bout.c | 1471 ------ contrib/gdb/bfd/cache.c | 347 -- contrib/gdb/bfd/cf-i386lynx.c | 31 - contrib/gdb/bfd/cf-m68klynx.c | 223 - contrib/gdb/bfd/cf-sparclynx.c | 28 - contrib/gdb/bfd/cisco-core.c | 313 -- contrib/gdb/bfd/coff-a29k.c | 641 --- contrib/gdb/bfd/coff-alpha.c | 2390 --------- contrib/gdb/bfd/coff-apollo.c | 162 - contrib/gdb/bfd/coff-arm.c | 537 -- contrib/gdb/bfd/coff-aux.c | 332 -- contrib/gdb/bfd/coff-go32.c | 25 - contrib/gdb/bfd/coff-h8300.c | 650 --- contrib/gdb/bfd/coff-h8500.c | 355 -- contrib/gdb/bfd/coff-i386.c | 493 -- contrib/gdb/bfd/coff-i860.c | 423 -- contrib/gdb/bfd/coff-i960.c | 683 --- contrib/gdb/bfd/coff-m68k.c | 203 - contrib/gdb/bfd/coff-m88k.c | 311 -- contrib/gdb/bfd/coff-mips.c | 2596 ---------- contrib/gdb/bfd/coff-pmac.c | 27 - contrib/gdb/bfd/coff-ppc.c | 3255 ------------ contrib/gdb/bfd/coff-rs6000.c | 1403 ----- contrib/gdb/bfd/coff-sh.c | 1525 ------ contrib/gdb/bfd/coff-sparc.c | 278 - contrib/gdb/bfd/coff-u68k.c | 35 - contrib/gdb/bfd/coff-w65.c | 446 -- contrib/gdb/bfd/coff-we32k.c | 110 - contrib/gdb/bfd/coff-z8k.c | 281 - contrib/gdb/bfd/coffcode.h | 3612 ------------- contrib/gdb/bfd/coffgen.c | 2121 -------- contrib/gdb/bfd/cofflink.c | 2327 --------- contrib/gdb/bfd/coffswap.h | 807 --- contrib/gdb/bfd/config.bfd | 491 -- contrib/gdb/bfd/config.in | 67 - contrib/gdb/bfd/configure | 2439 --------- contrib/gdb/bfd/configure.bat | 18 - contrib/gdb/bfd/configure.host | 128 - contrib/gdb/bfd/configure.in | 577 --- contrib/gdb/bfd/corefile.c | 106 - contrib/gdb/bfd/cpu-a29k.c | 39 - contrib/gdb/bfd/cpu-alpha.c | 38 - contrib/gdb/bfd/cpu-arm.c | 39 - contrib/gdb/bfd/cpu-h8300.c | 246 - contrib/gdb/bfd/cpu-h8500.c | 199 - contrib/gdb/bfd/cpu-hppa.c | 54 - contrib/gdb/bfd/cpu-i386.c | 38 - contrib/gdb/bfd/cpu-i860.c | 40 - contrib/gdb/bfd/cpu-i960.c | 162 - contrib/gdb/bfd/cpu-m68k.c | 42 - contrib/gdb/bfd/cpu-m88k.c | 42 - contrib/gdb/bfd/cpu-mips.c | 85 - contrib/gdb/bfd/cpu-ns32k.c | 868 ---- contrib/gdb/bfd/cpu-powerpc.c | 124 - contrib/gdb/bfd/cpu-rs6000.c | 70 - contrib/gdb/bfd/cpu-sh.c | 68 - contrib/gdb/bfd/cpu-sparc.c | 111 - contrib/gdb/bfd/cpu-vax.c | 39 - contrib/gdb/bfd/cpu-w65.c | 54 - contrib/gdb/bfd/cpu-we32k.c | 39 - contrib/gdb/bfd/cpu-z8k.c | 198 - contrib/gdb/bfd/demo64.c | 24 - contrib/gdb/bfd/dep-in.sed | 24 - contrib/gdb/bfd/doc/ChangeLog | 268 - contrib/gdb/bfd/doc/Makefile.in | 311 -- contrib/gdb/bfd/doc/bfd.texinfo | 348 -- contrib/gdb/bfd/doc/bfdsumm.texi | 148 - contrib/gdb/bfd/doc/chew.c | 1551 ------ contrib/gdb/bfd/doc/doc.str | 158 - contrib/gdb/bfd/doc/proto.str | 135 - contrib/gdb/bfd/ecoff.c | 4740 ----------------- contrib/gdb/bfd/ecofflink.c | 2452 --------- contrib/gdb/bfd/ecoffswap.h | 853 --- contrib/gdb/bfd/elf-bfd.h | 858 --- contrib/gdb/bfd/elf.c | 3318 ------------ contrib/gdb/bfd/elf32-gen.c | 37 - contrib/gdb/bfd/elf32-hppa.c | 2984 ----------- contrib/gdb/bfd/elf32-hppa.h | 152 - contrib/gdb/bfd/elf32-i386.c | 1546 ------ contrib/gdb/bfd/elf32-i860.c | 33 - contrib/gdb/bfd/elf32-m68k.c | 1600 ------ contrib/gdb/bfd/elf32-m88k.c | 35 - contrib/gdb/bfd/elf32-mips.c | 5867 --------------------- contrib/gdb/bfd/elf32-ppc.c | 2554 --------- contrib/gdb/bfd/elf32-sparc.c | 1795 ------- contrib/gdb/bfd/elf32.c | 23 - contrib/gdb/bfd/elf64-gen.c | 37 - contrib/gdb/bfd/elf64-sparc.c | 421 -- contrib/gdb/bfd/elf64.c | 22 - contrib/gdb/bfd/elfcode.h | 1406 ----- contrib/gdb/bfd/elfcore.h | 475 -- contrib/gdb/bfd/elflink.c | 372 -- contrib/gdb/bfd/elflink.h | 3424 ------------ contrib/gdb/bfd/elfxx-target.h | 450 -- contrib/gdb/bfd/filemode.c | 193 - contrib/gdb/bfd/format.c | 319 -- contrib/gdb/bfd/freebsd.h | 109 - contrib/gdb/bfd/gen-aout.c | 101 - contrib/gdb/bfd/genlink.h | 106 - contrib/gdb/bfd/hash.c | 734 --- contrib/gdb/bfd/host-aout.c | 83 - contrib/gdb/bfd/hosts/alphalinux.h | 6 - contrib/gdb/bfd/hosts/decstation.h | 17 - contrib/gdb/bfd/hosts/delta68.h | 18 - contrib/gdb/bfd/hosts/dpx2.h | 8 - contrib/gdb/bfd/hosts/hp300bsd.h | 13 - contrib/gdb/bfd/hosts/i386bsd.h | 25 - contrib/gdb/bfd/hosts/i386linux.h | 8 - contrib/gdb/bfd/hosts/i386mach3.h | 25 - contrib/gdb/bfd/hosts/i386sco.h | 19 - contrib/gdb/bfd/hosts/i860mach3.h | 27 - contrib/gdb/bfd/hosts/m68kaux.h | 16 - contrib/gdb/bfd/hosts/m68klinux.h | 6 - contrib/gdb/bfd/hosts/m88kmach3.h | 11 - contrib/gdb/bfd/hosts/mipsbsd.h | 12 - contrib/gdb/bfd/hosts/mipsmach3.h | 10 - contrib/gdb/bfd/hosts/news-mips.h | 12 - contrib/gdb/bfd/hosts/news.h | 9 - contrib/gdb/bfd/hosts/pc532mach.h | 24 - contrib/gdb/bfd/hosts/riscos.h | 10 - contrib/gdb/bfd/hosts/symmetry.h | 20 - contrib/gdb/bfd/hosts/tahoe.h | 12 - contrib/gdb/bfd/hosts/vaxbsd.h | 19 - contrib/gdb/bfd/hosts/vaxult.h | 8 - contrib/gdb/bfd/hosts/vaxult2.h | 8 - contrib/gdb/bfd/hp300bsd.c | 38 - contrib/gdb/bfd/hp300hpux.c | 865 ---- contrib/gdb/bfd/hppa_stubs.h | 23 - contrib/gdb/bfd/hppabsd-core.c | 305 -- contrib/gdb/bfd/hpux-core.c | 270 - contrib/gdb/bfd/i386aout.c | 68 - contrib/gdb/bfd/i386bsd.c | 46 - contrib/gdb/bfd/i386dynix.c | 80 - contrib/gdb/bfd/i386freebsd.c | 33 - contrib/gdb/bfd/i386linux.c | 762 --- contrib/gdb/bfd/i386lynx.c | 563 -- contrib/gdb/bfd/i386mach3.c | 65 - contrib/gdb/bfd/i386msdos.c | 243 - contrib/gdb/bfd/i386netbsd.c | 33 - contrib/gdb/bfd/i386os9k.c | 370 -- contrib/gdb/bfd/ieee.c | 3738 -------------- contrib/gdb/bfd/ihex.c | 1005 ---- contrib/gdb/bfd/init.c | 50 - contrib/gdb/bfd/irix-core.c | 263 - contrib/gdb/bfd/libaout.h | 608 --- contrib/gdb/bfd/libbfd-in.h | 503 -- contrib/gdb/bfd/libbfd.c | 1197 ----- contrib/gdb/bfd/libbfd.h | 735 --- contrib/gdb/bfd/libcoff-in.h | 482 -- contrib/gdb/bfd/libcoff.h | 823 --- contrib/gdb/bfd/libecoff.h | 352 -- contrib/gdb/bfd/libhppa.h | 549 -- contrib/gdb/bfd/libieee.h | 135 - contrib/gdb/bfd/libnlm.h | 264 - contrib/gdb/bfd/liboasys.h | 83 - contrib/gdb/bfd/linker.c | 2781 ---------- contrib/gdb/bfd/lynx-core.c | 233 - contrib/gdb/bfd/m68k4knetbsd.c | 35 - contrib/gdb/bfd/m68klinux.c | 767 --- contrib/gdb/bfd/m68klynx.c | 54 - contrib/gdb/bfd/m68knetbsd.c | 35 - contrib/gdb/bfd/m88kmach3.c | 38 - contrib/gdb/bfd/makefile.dos | 49 - contrib/gdb/bfd/mipsbsd.c | 467 -- contrib/gdb/bfd/mpw-config.in | 73 - contrib/gdb/bfd/mpw-make.sed | 70 - contrib/gdb/bfd/netbsd-core.c | 310 -- contrib/gdb/bfd/netbsd.h | 108 - contrib/gdb/bfd/newsos3.c | 40 - contrib/gdb/bfd/nlm-target.h | 228 - contrib/gdb/bfd/nlm.c | 55 - contrib/gdb/bfd/nlm32-alpha.c | 892 ---- contrib/gdb/bfd/nlm32-i386.c | 451 -- contrib/gdb/bfd/nlm32-ppc.c | 1045 ---- contrib/gdb/bfd/nlm32-sparc.c | 440 -- contrib/gdb/bfd/nlm32.c | 21 - contrib/gdb/bfd/nlm64.c | 21 - contrib/gdb/bfd/nlmcode.h | 2057 -------- contrib/gdb/bfd/nlmswap.h | 157 - contrib/gdb/bfd/ns32knetbsd.c | 53 - contrib/gdb/bfd/oasys.c | 1533 ------ contrib/gdb/bfd/opncls.c | 604 --- contrib/gdb/bfd/osf-core.c | 256 - contrib/gdb/bfd/pc532-mach.c | 121 - contrib/gdb/bfd/pe-arm.c | 32 - contrib/gdb/bfd/pe-i386.c | 30 - contrib/gdb/bfd/pe-ppc.c | 39 - contrib/gdb/bfd/pei-arm.c | 33 - contrib/gdb/bfd/pei-i386.c | 33 - contrib/gdb/bfd/pei-ppc.c | 44 - contrib/gdb/bfd/peicode.h | 1861 ------- contrib/gdb/bfd/ptrace-core.c | 233 - contrib/gdb/bfd/reloc.c | 2391 --------- contrib/gdb/bfd/reloc16.c | 289 -- contrib/gdb/bfd/riscix.c | 644 --- contrib/gdb/bfd/rs6000-core.c | 396 -- contrib/gdb/bfd/section.c | 976 ---- contrib/gdb/bfd/som.c | 5999 --------------------- contrib/gdb/bfd/som.h | 224 - contrib/gdb/bfd/sparclynx.c | 265 - contrib/gdb/bfd/sparcnetbsd.c | 33 - contrib/gdb/bfd/srec.c | 1324 ----- contrib/gdb/bfd/stab-syms.c | 57 - contrib/gdb/bfd/sunos.c | 2767 ---------- contrib/gdb/bfd/syms.c | 1084 ---- contrib/gdb/bfd/sysdep.h | 114 - contrib/gdb/bfd/targets.c | 886 ---- contrib/gdb/bfd/tekhex.c | 1031 ---- contrib/gdb/bfd/trad-core.c | 316 -- contrib/gdb/bfd/versados.c | 906 ---- contrib/gdb/bfd/xcofflink.c | 5798 --------------------- contrib/gdb/install.sh | 236 - contrib/gdb/move-if-change | 32 - 239 files changed, 156804 deletions(-) delete mode 100644 contrib/gdb/ChangeLog delete mode 100644 contrib/gdb/MAINTAINERS delete mode 100644 contrib/gdb/bfd/COPYING delete mode 100644 contrib/gdb/bfd/Makefile.in delete mode 100644 contrib/gdb/bfd/PORTING delete mode 100644 contrib/gdb/bfd/TODO delete mode 100644 contrib/gdb/bfd/VERSION delete mode 100644 contrib/gdb/bfd/acconfig.h delete mode 100644 contrib/gdb/bfd/aclocal.m4 delete mode 100644 contrib/gdb/bfd/aix386-core.c delete mode 100644 contrib/gdb/bfd/aout-adobe.c delete mode 100644 contrib/gdb/bfd/aout-arm.c delete mode 100644 contrib/gdb/bfd/aout-encap.c delete mode 100644 contrib/gdb/bfd/aout-ns32k.c delete mode 100644 contrib/gdb/bfd/aout-target.h delete mode 100644 contrib/gdb/bfd/aout0.c delete mode 100644 contrib/gdb/bfd/aout32.c delete mode 100644 contrib/gdb/bfd/aout64.c delete mode 100644 contrib/gdb/bfd/aoutf1.h delete mode 100644 contrib/gdb/bfd/aoutx.h delete mode 100644 contrib/gdb/bfd/archive.c delete mode 100644 contrib/gdb/bfd/archures.c delete mode 100644 contrib/gdb/bfd/bfd-in.h delete mode 100644 contrib/gdb/bfd/bfd-in2.h delete mode 100644 contrib/gdb/bfd/bfd.c delete mode 100644 contrib/gdb/bfd/binary.c delete mode 100644 contrib/gdb/bfd/bout.c delete mode 100644 contrib/gdb/bfd/cache.c delete mode 100644 contrib/gdb/bfd/cf-i386lynx.c delete mode 100644 contrib/gdb/bfd/cf-m68klynx.c delete mode 100644 contrib/gdb/bfd/cf-sparclynx.c delete mode 100644 contrib/gdb/bfd/cisco-core.c delete mode 100644 contrib/gdb/bfd/coff-a29k.c delete mode 100644 contrib/gdb/bfd/coff-alpha.c delete mode 100644 contrib/gdb/bfd/coff-apollo.c delete mode 100644 contrib/gdb/bfd/coff-arm.c delete mode 100644 contrib/gdb/bfd/coff-aux.c delete mode 100644 contrib/gdb/bfd/coff-go32.c delete mode 100644 contrib/gdb/bfd/coff-h8300.c delete mode 100644 contrib/gdb/bfd/coff-h8500.c delete mode 100644 contrib/gdb/bfd/coff-i386.c delete mode 100644 contrib/gdb/bfd/coff-i860.c delete mode 100644 contrib/gdb/bfd/coff-i960.c delete mode 100644 contrib/gdb/bfd/coff-m68k.c delete mode 100644 contrib/gdb/bfd/coff-m88k.c delete mode 100644 contrib/gdb/bfd/coff-mips.c delete mode 100644 contrib/gdb/bfd/coff-pmac.c delete mode 100644 contrib/gdb/bfd/coff-ppc.c delete mode 100644 contrib/gdb/bfd/coff-rs6000.c delete mode 100644 contrib/gdb/bfd/coff-sh.c delete mode 100644 contrib/gdb/bfd/coff-sparc.c delete mode 100644 contrib/gdb/bfd/coff-u68k.c delete mode 100644 contrib/gdb/bfd/coff-w65.c delete mode 100644 contrib/gdb/bfd/coff-we32k.c delete mode 100644 contrib/gdb/bfd/coff-z8k.c delete mode 100644 contrib/gdb/bfd/coffcode.h delete mode 100644 contrib/gdb/bfd/coffgen.c delete mode 100644 contrib/gdb/bfd/cofflink.c delete mode 100644 contrib/gdb/bfd/coffswap.h delete mode 100644 contrib/gdb/bfd/config.bfd delete mode 100644 contrib/gdb/bfd/config.in delete mode 100644 contrib/gdb/bfd/configure delete mode 100644 contrib/gdb/bfd/configure.bat delete mode 100644 contrib/gdb/bfd/configure.host delete mode 100644 contrib/gdb/bfd/configure.in delete mode 100644 contrib/gdb/bfd/corefile.c delete mode 100644 contrib/gdb/bfd/cpu-a29k.c delete mode 100644 contrib/gdb/bfd/cpu-alpha.c delete mode 100644 contrib/gdb/bfd/cpu-arm.c delete mode 100644 contrib/gdb/bfd/cpu-h8300.c delete mode 100644 contrib/gdb/bfd/cpu-h8500.c delete mode 100644 contrib/gdb/bfd/cpu-hppa.c delete mode 100644 contrib/gdb/bfd/cpu-i386.c delete mode 100644 contrib/gdb/bfd/cpu-i860.c delete mode 100644 contrib/gdb/bfd/cpu-i960.c delete mode 100644 contrib/gdb/bfd/cpu-m68k.c delete mode 100644 contrib/gdb/bfd/cpu-m88k.c delete mode 100644 contrib/gdb/bfd/cpu-mips.c delete mode 100644 contrib/gdb/bfd/cpu-ns32k.c delete mode 100644 contrib/gdb/bfd/cpu-powerpc.c delete mode 100644 contrib/gdb/bfd/cpu-rs6000.c delete mode 100644 contrib/gdb/bfd/cpu-sh.c delete mode 100644 contrib/gdb/bfd/cpu-sparc.c delete mode 100644 contrib/gdb/bfd/cpu-vax.c delete mode 100644 contrib/gdb/bfd/cpu-w65.c delete mode 100644 contrib/gdb/bfd/cpu-we32k.c delete mode 100644 contrib/gdb/bfd/cpu-z8k.c delete mode 100644 contrib/gdb/bfd/demo64.c delete mode 100644 contrib/gdb/bfd/dep-in.sed delete mode 100644 contrib/gdb/bfd/doc/ChangeLog delete mode 100644 contrib/gdb/bfd/doc/Makefile.in delete mode 100644 contrib/gdb/bfd/doc/bfd.texinfo delete mode 100644 contrib/gdb/bfd/doc/bfdsumm.texi delete mode 100644 contrib/gdb/bfd/doc/chew.c delete mode 100644 contrib/gdb/bfd/doc/doc.str delete mode 100644 contrib/gdb/bfd/doc/proto.str delete mode 100644 contrib/gdb/bfd/ecoff.c delete mode 100644 contrib/gdb/bfd/ecofflink.c delete mode 100644 contrib/gdb/bfd/ecoffswap.h delete mode 100644 contrib/gdb/bfd/elf-bfd.h delete mode 100644 contrib/gdb/bfd/elf.c delete mode 100644 contrib/gdb/bfd/elf32-gen.c delete mode 100644 contrib/gdb/bfd/elf32-hppa.c delete mode 100644 contrib/gdb/bfd/elf32-hppa.h delete mode 100644 contrib/gdb/bfd/elf32-i386.c delete mode 100644 contrib/gdb/bfd/elf32-i860.c delete mode 100644 contrib/gdb/bfd/elf32-m68k.c delete mode 100644 contrib/gdb/bfd/elf32-m88k.c delete mode 100644 contrib/gdb/bfd/elf32-mips.c delete mode 100644 contrib/gdb/bfd/elf32-ppc.c delete mode 100644 contrib/gdb/bfd/elf32-sparc.c delete mode 100644 contrib/gdb/bfd/elf32.c delete mode 100644 contrib/gdb/bfd/elf64-gen.c delete mode 100644 contrib/gdb/bfd/elf64-sparc.c delete mode 100644 contrib/gdb/bfd/elf64.c delete mode 100644 contrib/gdb/bfd/elfcode.h delete mode 100644 contrib/gdb/bfd/elfcore.h delete mode 100644 contrib/gdb/bfd/elflink.c delete mode 100644 contrib/gdb/bfd/elflink.h delete mode 100644 contrib/gdb/bfd/elfxx-target.h delete mode 100644 contrib/gdb/bfd/filemode.c delete mode 100644 contrib/gdb/bfd/format.c delete mode 100644 contrib/gdb/bfd/freebsd.h delete mode 100644 contrib/gdb/bfd/gen-aout.c delete mode 100644 contrib/gdb/bfd/genlink.h delete mode 100644 contrib/gdb/bfd/hash.c delete mode 100644 contrib/gdb/bfd/host-aout.c delete mode 100644 contrib/gdb/bfd/hosts/alphalinux.h delete mode 100644 contrib/gdb/bfd/hosts/decstation.h delete mode 100644 contrib/gdb/bfd/hosts/delta68.h delete mode 100644 contrib/gdb/bfd/hosts/dpx2.h delete mode 100644 contrib/gdb/bfd/hosts/hp300bsd.h delete mode 100644 contrib/gdb/bfd/hosts/i386bsd.h delete mode 100644 contrib/gdb/bfd/hosts/i386linux.h delete mode 100644 contrib/gdb/bfd/hosts/i386mach3.h delete mode 100644 contrib/gdb/bfd/hosts/i386sco.h delete mode 100644 contrib/gdb/bfd/hosts/i860mach3.h delete mode 100644 contrib/gdb/bfd/hosts/m68kaux.h delete mode 100644 contrib/gdb/bfd/hosts/m68klinux.h delete mode 100644 contrib/gdb/bfd/hosts/m88kmach3.h delete mode 100644 contrib/gdb/bfd/hosts/mipsbsd.h delete mode 100644 contrib/gdb/bfd/hosts/mipsmach3.h delete mode 100644 contrib/gdb/bfd/hosts/news-mips.h delete mode 100644 contrib/gdb/bfd/hosts/news.h delete mode 100644 contrib/gdb/bfd/hosts/pc532mach.h delete mode 100644 contrib/gdb/bfd/hosts/riscos.h delete mode 100644 contrib/gdb/bfd/hosts/symmetry.h delete mode 100644 contrib/gdb/bfd/hosts/tahoe.h delete mode 100644 contrib/gdb/bfd/hosts/vaxbsd.h delete mode 100644 contrib/gdb/bfd/hosts/vaxult.h delete mode 100644 contrib/gdb/bfd/hosts/vaxult2.h delete mode 100644 contrib/gdb/bfd/hp300bsd.c delete mode 100644 contrib/gdb/bfd/hp300hpux.c delete mode 100644 contrib/gdb/bfd/hppa_stubs.h delete mode 100644 contrib/gdb/bfd/hppabsd-core.c delete mode 100644 contrib/gdb/bfd/hpux-core.c delete mode 100644 contrib/gdb/bfd/i386aout.c delete mode 100644 contrib/gdb/bfd/i386bsd.c delete mode 100644 contrib/gdb/bfd/i386dynix.c delete mode 100644 contrib/gdb/bfd/i386freebsd.c delete mode 100644 contrib/gdb/bfd/i386linux.c delete mode 100644 contrib/gdb/bfd/i386lynx.c delete mode 100644 contrib/gdb/bfd/i386mach3.c delete mode 100644 contrib/gdb/bfd/i386msdos.c delete mode 100644 contrib/gdb/bfd/i386netbsd.c delete mode 100644 contrib/gdb/bfd/i386os9k.c delete mode 100644 contrib/gdb/bfd/ieee.c delete mode 100644 contrib/gdb/bfd/ihex.c delete mode 100644 contrib/gdb/bfd/init.c delete mode 100644 contrib/gdb/bfd/irix-core.c delete mode 100644 contrib/gdb/bfd/libaout.h delete mode 100644 contrib/gdb/bfd/libbfd-in.h delete mode 100644 contrib/gdb/bfd/libbfd.c delete mode 100644 contrib/gdb/bfd/libbfd.h delete mode 100644 contrib/gdb/bfd/libcoff-in.h delete mode 100644 contrib/gdb/bfd/libcoff.h delete mode 100644 contrib/gdb/bfd/libecoff.h delete mode 100644 contrib/gdb/bfd/libhppa.h delete mode 100644 contrib/gdb/bfd/libieee.h delete mode 100644 contrib/gdb/bfd/libnlm.h delete mode 100644 contrib/gdb/bfd/liboasys.h delete mode 100644 contrib/gdb/bfd/linker.c delete mode 100644 contrib/gdb/bfd/lynx-core.c delete mode 100644 contrib/gdb/bfd/m68k4knetbsd.c delete mode 100644 contrib/gdb/bfd/m68klinux.c delete mode 100644 contrib/gdb/bfd/m68klynx.c delete mode 100644 contrib/gdb/bfd/m68knetbsd.c delete mode 100644 contrib/gdb/bfd/m88kmach3.c delete mode 100644 contrib/gdb/bfd/makefile.dos delete mode 100644 contrib/gdb/bfd/mipsbsd.c delete mode 100644 contrib/gdb/bfd/mpw-config.in delete mode 100644 contrib/gdb/bfd/mpw-make.sed delete mode 100644 contrib/gdb/bfd/netbsd-core.c delete mode 100644 contrib/gdb/bfd/netbsd.h delete mode 100644 contrib/gdb/bfd/newsos3.c delete mode 100644 contrib/gdb/bfd/nlm-target.h delete mode 100644 contrib/gdb/bfd/nlm.c delete mode 100644 contrib/gdb/bfd/nlm32-alpha.c delete mode 100644 contrib/gdb/bfd/nlm32-i386.c delete mode 100644 contrib/gdb/bfd/nlm32-ppc.c delete mode 100644 contrib/gdb/bfd/nlm32-sparc.c delete mode 100644 contrib/gdb/bfd/nlm32.c delete mode 100644 contrib/gdb/bfd/nlm64.c delete mode 100644 contrib/gdb/bfd/nlmcode.h delete mode 100644 contrib/gdb/bfd/nlmswap.h delete mode 100644 contrib/gdb/bfd/ns32knetbsd.c delete mode 100644 contrib/gdb/bfd/oasys.c delete mode 100644 contrib/gdb/bfd/opncls.c delete mode 100644 contrib/gdb/bfd/osf-core.c delete mode 100644 contrib/gdb/bfd/pc532-mach.c delete mode 100644 contrib/gdb/bfd/pe-arm.c delete mode 100644 contrib/gdb/bfd/pe-i386.c delete mode 100644 contrib/gdb/bfd/pe-ppc.c delete mode 100644 contrib/gdb/bfd/pei-arm.c delete mode 100644 contrib/gdb/bfd/pei-i386.c delete mode 100644 contrib/gdb/bfd/pei-ppc.c delete mode 100644 contrib/gdb/bfd/peicode.h delete mode 100644 contrib/gdb/bfd/ptrace-core.c delete mode 100644 contrib/gdb/bfd/reloc.c delete mode 100644 contrib/gdb/bfd/reloc16.c delete mode 100644 contrib/gdb/bfd/riscix.c delete mode 100644 contrib/gdb/bfd/rs6000-core.c delete mode 100644 contrib/gdb/bfd/section.c delete mode 100644 contrib/gdb/bfd/som.c delete mode 100644 contrib/gdb/bfd/som.h delete mode 100644 contrib/gdb/bfd/sparclynx.c delete mode 100644 contrib/gdb/bfd/sparcnetbsd.c delete mode 100644 contrib/gdb/bfd/srec.c delete mode 100644 contrib/gdb/bfd/stab-syms.c delete mode 100644 contrib/gdb/bfd/sunos.c delete mode 100644 contrib/gdb/bfd/syms.c delete mode 100644 contrib/gdb/bfd/sysdep.h delete mode 100644 contrib/gdb/bfd/targets.c delete mode 100644 contrib/gdb/bfd/tekhex.c delete mode 100644 contrib/gdb/bfd/trad-core.c delete mode 100644 contrib/gdb/bfd/versados.c delete mode 100644 contrib/gdb/bfd/xcofflink.c delete mode 100755 contrib/gdb/install.sh delete mode 100755 contrib/gdb/move-if-change diff --git a/contrib/gdb/ChangeLog b/contrib/gdb/ChangeLog deleted file mode 100644 index 83ec2be7480..00000000000 --- a/contrib/gdb/ChangeLog +++ /dev/null @@ -1,7746 +0,0 @@ -2002-04-07 Andrew Cagney - - * Makefile.in (do-tar-bz2): Delete rule. Replace with ... - (do-tar, do-bz2): New rules. - (taz): Update. Replace do-tar-bz2 with do-tar and do-bz2. - (gdb-tar): New rule. - (gdb-taz): Rewrite. Use gdb-tar and do-bz2. - (insight_dejagnu.tar): New rule. - (insight.tar): New rule. - (gdb+dejagnu.tar): New rule. - (gdb.tar): New rule. - -2002-02-28 Alexandre Oliva - - * configure.in (libstdcxx_flags): Don't add libstdc++-v3 flags for - libjava. - (CXX_FOR_TARGET): Add -shared-libgcc for libstdc++-v3 and libjava. - -2002-02-24 Andrew Cagney - - * texinfo/texinfo.tex: Update to version 2002-02-14.08. - -2002-02-23 Daniel Jacobowitz - - * config.guess: Import from master sources, rev 1.232. - * config.sub: Import from master sources, rev 1.246. - -2002-02-23 Alexandre Oliva - - * Makefile.in (MAKEINFO): Don't assume makeinfo will be built just - because its Makefile is there; test for the executable instead. - -2002-02-09 Alexandre Oliva - - Contribute sh64-elf. - 2000-12-01 Alexandre Oliva - * configure.in: Added sh64-*-*. - -2002-02-04 Jeff Johnston - - * COPYING.NEWLIB: Remove advertising clause from - Berkeley and Red Hat licenses. - -2002-02-01 Mo DeJong - - * Makefile.in: Add all-tix to deps for all-snavigator - so that tix is built when building snavigator. - -2002-02-01 Ben Elliston - - * config.guess: Import from master sources, rev 1.229. - * config.sub: Import from master sources, rev 1.240. - -2002-01-27 Daniel Jacobowitz - - From Steve Ellcey : - * libtool.m4 (HPUX_IA64_MODE): Set to 32 or 64 based on ABI. - (lt_cv_deplibs_check_method, lt_cv_file_magic_cmd, - lt_cv_file_magic_test_file): Set to appropriate values for HP-UX - IA64. - * ltcf-c.sh (archive_cmds, hardcode_*): Ditto. - * ltconfig (shlibpath_*, dynamic_linker, library_names_spec, - soname_spec, sys_lib_search_path_spec): Ditto. - -2002-01-26 Jason Thorpe - - * configure.in (*-*-netbsd*): New. Skip target-newlib, - target-libiberty, and target-libgloss. Skip Java-related - libraries if not supported for NetBSD on target CPU. - -2002-01-23 Nick Clifton - - * configure.in: Import StrongARM and XScale target_configdirs from - FSF GCC version. - -2002-01-16 H.J. Lu (hjl@gnu.org) - - * config.guess: Import from master sources, rev 1.225. - * config.sub: Import from master sources, rev 1.238. - - * MAINTAINERS: Updated notes on config.guess and config.sub. - -2002-01-11 Steve Ellcey - - * configure.in (ia64*-*-hpux*): New target for IA64 HP-UX, - ld and gdb are not supported. - -2002-01-07 Jeff Johnston - - * Change reference to Cygnus Solutions to be Red Hat. - -2002-01-07 Jeff Johnston - - * COPYING.NEWLIB: Update generic copyright date. - -2002-01-07 Mark Salter - - * configure.in: Remove target-bsp and target-cygmon from arm builds. - Allow target-libgloss to be built for arm, strongarm, and xscale. - -2002-01-03 Ben Elliston - - * MAINTAINERS: Update URL for config.* scripts. - -2001-12-18 Alan Modra - - * config.sub: Import latest version. - * config.guess: Likewise. - -2001-12-13 Thomas Fitzsimmons - - * configure.in (FLAGS_FOR_TARGET): Remove -nostdinc and -isystem - options for i[3456]86-pc-linux* native builds. - -2001-12-05 Laurent Guerby - - * MAINTAINERS: gcc adopts symlink-tree, refer more to - libiberty. - - Import this patch from gcc: - - 2000-12-09 Laurynas Biveinis - - * symlink-tree: handle DOS-style absolute paths. - -2001-11-28 DJ Delorie - Zack Weinberg - - When build != host, create libiberty for the build machine. - - * Makefile.in (TARGET_CONFIGARGS, BUILD_CONFIGARGS): Replace - CONFIG_ARGUMENTS. - (ALL_BUILD_MODULES_LIST, BUILD_CONFIGDIRS, BUILD_SUBDIR): - New variables. - (ALL_BUILD_MODULES, CONFIGURE_BUILD_MODULES): New variables - and rules. - (all.normal): Depend on ALL_BUILD_MODULES. - (CONFIGURE_TARGET_MODULES rule): Use TARGET_CONFIGARGS. - (all-build-libiberty): Depend on configure-build-libiberty. - - * configure: Calculate and substitute proper value for - ALL_BUILD_MODULES. - * configure.in: Create the build subdirectory. - Calculate and substitute TARGET_CONFIGARGS (formerly - CONFIG_ARGUMENTS); also BUILD_SUBDIR and BUILD_CONFIGARGS (new). - -2001-11-26 Geoffrey Keating - - * config.sub: Update to version 1.232 on subversion. - -2001-11-20 Nick Clifton - - * Makefile.in (do-proto-toplev): Use msgfmt to generate .gmo - files from .po files for a distribution. - -2001-11-19 Hans-Peter Nilsson - - * COPYING.NEWLIB: Mention preserved notice in specific parts. - -2001-11-13 Jeff Holcomb - - Merged from net gcc: - 2001-07-30 Jeff Sturm - * ltcf-c.sh: Use $objext, not $ac_objext. - 2001-07-27 Mark Kettenis - * ltcf-cxx.sh: Add support for GNU. - 2001-07-22 Timothy Wall - * ltcf-c.sh: Don't disable shared libraries for AIX5/IA64. Preserve - default settings if using GNU tools with that configuration. - * ltcf-cxx.sh: Ditto. - * ltcf-gcj.sh: Ditto. - 2001-07-21 Michael Chastain - * ltconfig: Set max_cmd_len to a maximum of 512Kb, as it seems some - HPUX 11.0 systems have trouble with 1MB. Mark as gcc-local. - * ltmain.sh: Mark as gcc-local. - -2001-11-13 Jeff Holcomb - - * Makefile.in (all-bison): Revert 2001-10-24. - Don't depend on texinfo. - -2001-11-12 Hans-Peter Nilsson - - * COPYING.NEWLIB: Add BSD-style license/copyright blurb for my work. - -2001-11-08 Phil Edwards - - * configure.in (--enable-languages): Be more permissive about - syntax. Check for empty lists better. Warn about $LANGUAGES. - -2001-11-06 Hans-Peter Nilsson - - * Makefile.in (MAKEINFO): Use "missing" for makeinfo older than 4.0. - -2001-10-24 Jeff Holcomb - - Makefile.in (all-bison): Don't depend on texinfo. - -2001-10-03 Alan Modra - - * gettext.m4: Test po/POTFILES.in exists before trying to read. - -2001-09-29 Alexandre Oliva - - * Makefile.in (configure-target-gperf): Depend on $(ALL_GCC_CXX). - -2001-09-28 Hans-Peter Nilsson - - * config.sub, config.guess: Import latest from subversions. - -2001-09-21 Alexandre Oliva - - * Makefile.in (AS_FOR_TARGET, LD_FOR_TARGET, - DLLTOOL_FOR_TARGET, WINDRES_FOR_TARGET, AR_FOR_TARGET, - RANLIB_FOR_TARGET, NM_FOR_TARGET): Don't use double quotes to - avoid quotes nesting problems. - (NATIVE_CHECK_MODULES): Ditto, just for consistency. - (DO_X): Export only variables that are set. - -2001-09-19 Ben Elliston - - * configure.in (sparc-sun-solaris2*): Don't use /usr/bin/which on - Solaris when testing for the /usr/ucb/cc compiler; it has incorrect - semantics. Use the shell built-in "type" command instead. - -2001-09-15 Thiemo Seufer - - * config.sub: Reverted the earlier change, this version is not the - master file. - -2001-09-14 Thiemo Seufer - - * config.sub: Change machine triplets from mipsel*-* to mips*el-*. - Add support for mips64. - -2001-09-03 Jeff Holcomb - - * configure.in: Enable libstdc++-v3 for h8300 targets. - -2001-08-30 Eric Christopher - Jason Eckhardt - - * config.sub: Add support for mipsisa32. - -2001-08-30 Eric Christopher - - * config.sub, config.guess: Import latest from subversions. - -2001-08-20 Alan Modra - - * config.sub, config.guess: Import latest from subversions. - -2001-07-26 DJ Delorie - - * MAINTAINERS: Clarify libiberty merge rules and procedures. - -2001-06-19 Alan Modra - - * Makefile.in: Revert 2001-06-17. - (VER): If AM_INIT_AUTOMAKE uses BFD_VERSION, get version from bfd/. - -2001-06-17 H.J. Lu - - * Makefile.in (gas.tar.bz2): Pass TOOL=bfd PACKAGE=gas to make. - (gas+binutils.tar.bz2): Likewise. - (binutils.tar.bz2): Pass TOOL=bfd PACKAGE=binutils to make. - -Fri Jun 8 11:14:02 2001 Andrew Cagney - - * Makefile.in (VER): When present, extract the version number from - the file version.in. - -2001-06-08 Alexandre Oliva , Jeff Sturm - - * Makefile.in (AS_FOR_TARGET, LD_FOR_TARGET, NM_FOR_TARGET): If - gcc/xgcc is built, use -print-prog-name to find out the program - name to use. - -2001-06-04 Mark Mitchell - - * ltcf-c.sh (archive_cmds, archive_expsym_cmds) [solaris, - with_gcc]: Use `gcc -shared' to build a shared library. - -2001-06-04 John David Anglin - - * ltcf-c.sh (archive_cmd) [hpux, with_gcc]: Use gcc to link shared - archives. - -2001-05-28 Simon Patarin - - * ltcf-cxx.sh (osf3/osf4/osf5): Support creation of C++ shared - libraries when using g++ with native linker. - -2001-05-28 Alexandre Oliva - - * ltconfig, ltmain.sh: Upgrade to libtool 1.4a 1.641.2.256. - -2001-05-24 Tom Rix - - * configure.in : enable ld for aix - -2001-05-22 Alexandre Oliva - - * ltcf-cxx.sh (allow_undefined_flag, no_undefined_flag) - [aix4*|aix5*]: Prepend blank. - -2001-05-20 Alexandre Oliva - - * ltconfig, ltmain.sh, libtool.m4, ltcf-c.sh, ltcf-cxx.sh, - ltcf-gcj.sh: Upgraded to libtool 1.4a 1.641.2.254. Rebuilt a number - of subdir/configure scripts to use the new libtool.m4. - -2001-05-14 H.J. Lu - - * config.if (libc_interface): Set to -libc6.2- for cross - compiling to Linux/glibc 2.2. - -2001-05-03 Alexandre Oliva - - * configure.in (noconfigdirs) [*-cygwin*, *-mingw*, *-beos]: Disable - libgcj. - -2001-04-26 Alexandre Oliva - - * configure.in (noconfigdirs): Don't reset it from scratch in the - target case; only append to it. - -2001-04-26 Alexandre Oliva - - * configure.in (noconfigdirs) [hppa*-*-*, mips*-*-irix6*, - sparc-*-solaris2.8]: Disable ${libgcj}. - -2001-04-25 Alexandre Oliva - - * configure.in (libgcj_saved): Copy from $libgcj. - (libgcj): Zero out if --enable-libgcj; add to noconfigdirs is - --disable-libgcj. - -2001-04-20 Alexandre Oliva - - * ltconfig, ltmain.sh, ltcf-cxx.sh: Upgraded to libtool 1.4a - 1.641.2.228. - -2001-04-12 Alexandre Oliva - - * ltconfig, ltmain.sh, libtool.m4, ltcf-c.sh, ltcf-cxx.sh, - ltcf-gcj.sh: Upgraded to libtool 1.4a 1.641.2.226. - -2001-04-01 Alexandre Oliva - - * Makefile.in (CXX_FOR_TARGET_FOR_RECURSIVE_MAKE, RECURSE_FLAGS): - New macros. - (bootstrap, cross): Use RECURSE_FLAGS. - * configure.in: Subst CXX_FOR_TARGET_FOR_RECURSIVE_MAKE. - -2001-03-27 Alexandre Oliva - - * configure.in (CXX_FOR_TARGET): Use xgcc for libstdc++-v3. - -2001-03-23 Nick Clifton - - * README-maintainer-mode: Add note about inability to use "make - distclean" in maintainer mode. - -2001-03-22 Alexandre Oliva - - Re-installed: - 2001-01-02 Laurynas Biveinis - * ltcf-c.sh: Clear ac_cv_prog_cc_pic for DJGPP. Do not add - '-DPIC' to ac_cv_prog_cc_pic for DJGPP. - * ltcf-cxx.sh: Likewise. - * ltcf-gcj.sh: Likewise. - -2001-03-22 Philip Blundell - - * config.sub, config.guess: Import latest from subversions. - -2001-03-22 Alexandre Oliva - - * ltconfig, ltmain.sh, libtool.m4, ltcf-c.sh, ltcf-cxx.sh, - ltcf-gcj.sh: Upgraded to libtool 1.4a 1.641.2.198. - -2001-03-20 Michael Chastain - - * Makefile.in: all-m4 depends on all-texinfo. - -2001-03-08 Alexandre Oliva - - * Makefile.in (ALL_GCC, ALL_GCC_C, ALL_GCC_CXX): Set before use. - -2001-02-22 Jeff Johnston - - * COPYING.NEWLIB: Remove DJ Delorie's address because it is no - longer valid. - -2001-02-16 Nick Clifton - - * configure.in (noconfigdirs): Allow configuration of texinfo - for Cygwin hosts. - -2001-02-09 Martin Schwidefsky - - * config.guess: Add linux target for S/390. - * config.sub: Likewise. - * configure.in: Likewise. - -2001-02-06 Ben Elliston - - * configure: Output host type to stdout, not stderr. - -2001-02-04 Michael Sokolov - - * config.guess: Import from subversions.gnu.org (revision 1.181). - * config.sub: Import from subversions.gnu.org (revision 1.199). - -2001-01-30 Alan Modra - - * config.guess: Handle hppa64-linux systems. - -2001-01-27 Michael Sokolov - - * ltcf-cxx.sh (ac_cv_prog_cc_pic_works, ac_cv_prog_cc_static_works): - Don't unset, it's non-portable and no longer necessary, set to empty - instead. - -2001-01-27 Michael Sokolov , Alexandre Oliva - - * ltconfig: Shell portability fix for the tagname validity check. - -2001-01-27 Michael Sokolov - - * ltcf-cxx.sh: Use parentheses around eval $ac_compile. - -2001-01-27 Alexandre Oliva - - * ltcf-c.sh (ld_shlibs) [aix5*]: Disable on unknown CPU types. - * ltcf-cxx.sh, ltcf-gcj.sh: Likewise. - -2001-01-24 Alexandre Oliva - - * ltmain.sh (TAG disable-shared, TAG disable-static): Make sure we - keep at least one of build_libtool_libs or build_old_libs set to - yes. - -2001-01-24 Alexandre Oliva - - * ltcf-gcj.sh (lt_simple_link_test_code): Remove stray `(0)'. - * libtool.m4 (_AC_LIBTOOL_GCJ): Pass $CPPFLAGS on. - -2000-11-07 Philip Blundell - - * Makefile.in (ETC_SUPPORT): Also add configbuild.* and configdev.*. - -2000-11-03 Philip Blundell - - * Makefile.in (ETC_SUPPORT): Add configure.texi and associated info - files. - -2001-01-15 Jeff Johnston - - * COPYING.NEWLIB: Put into source repository. - -2001-01-15 Ben Elliston - - * configure.in (host_tools): Add sid. - Always configure cgen. - * Makefile.in (all-sid): New target. - (check-sid, clean-sid, install-sid): Likewise. - -2001-01-07 Andreas Jaeger - - * config.sub, config.guess: Update from subversions. - -2000-12-12 Alexandre Oliva - - * configure.in: Disable language-specific target libraries for - languages that aren't enabled. - -2000-11-24 Nick Clifton - - * configure.in (xscale-elf): Add target. - (xscale-coff): Add target. - (c4x, c5x, tic54x): Move after ARM targets. - -2000-11-23 Alexandre Oliva - - * ltcf-gcj.sh: Added file, required by 2000-11-18 merge. - -2000-11-20 Ian Lance Taylor - - * ltcf-cxx.sh: Added file, required by 2000-11-18 merge. - -2000-11-18 Alexandre Oliva - - * Makefile.in: Merge with GCC and libgcj. - (ALL_GCC_C, ALL_GCC_CXX): New macros. Use them as dependencies of - configure-target- when their configure scripts need the C - or C++ library to have already been built to work properly. - (do_proto_toplev): Set them to an empty string. - -2000-11-18 Alexandre Oliva - - * Makefile.in (HOST_LIB_PATH, TARGET_LIB_PATH): New macros. - (REALLY_SET_LIB_PATH): Use them. - -2000-11-06 Christopher Faylor - - * config.sub: Add support for Sun Chorus - -2000-11-02 Per Lundberg - - * config.sub: Add support for the *-storm-chaos OS. - -2000-10-30 Stephane Carrez - - * configure.in (noconfigdirs): Don't compile some - of the libraries for 68HC11 & 68hc12 targets. - -2000-09-30 Alexandre Oliva - - * ltconfig, ltmain.sh, libtool.m4: Updated from libtool - multi-language branch, to work around Solaris' /bin/sh bug. Rebuilt - all affected `configure' scripts. - -2000-09-25 Alexandre Oliva - - * Makefile.in (DEVO_SUPPORT): Added gettext.m4, libtool.m4 and - ltcf-c.sh. - -2000-09-12 Philip Blundell - - * config.sub, config.guess: Update from subversions. - -2000-09-06 Alexandre Oliva - - * Makefile.in (all-zlib): Added dummy target. - - * ltconfig, ltmain.sh, libtool.m4, ltcf-c.sh: Updated from libtool - multi-language branch. - -2000-09-05 Alexandre Oliva - - * Makefile.in (all-bootstrap): Added all-texinfo and all-zlib. - (bootstrap*): Depend on all-bootstrap. - -2000-09-02 Alexandre Oliva , DJ Delorie - - * configure.in (FLAGS_FOR_TARGET): Use -nostdinc even for Canadian - crosses, but add gcc/include to the header search path for them. - -2000-08-31 Alexandre Oliva - - * ltconfig, ltmain.sh: Updated from libtool multi-language branch. - * libtool.m4, ltcf-c.sh: Copied from libtool multi-language branch. - * gettext.m4: New file, extracted from aclocal.m4. - -2000-08-22 Alexandre Oliva - - * config-ml.in (CC, CXX): Avoid trailing whitespace. - (LD_LIBRARY_PATH, SHLIB_PATH): Adjust for multilibs and export to - sub-configures. - -2000-08-20 Doug Evans - - * Makefile.in (ALL_MODULES): Add all-cgen. - (CROSS_CHECK_MODULES,INSTALL_MODULES,CLEAN_MODULES): Similarily. - (all-cgen): New target. - (all-opcodes,all-sim): Depend on all-cgen. - * configure.in (host_tools): Add cgen. - Only configure cgen if --enable-cgen-maint. - -2000-08-17 Alexandre Oliva - - * config-ml.in (CC, CXX): Don't introduce a leading space. - -2000-08-16 Alexandre Oliva - - * configure.in (libstdcxx_flags): Use - libstdc++-v3/src/libstdc++.INC. - -2000-08-15 Alexandre Oliva - - * configure.in (libstdcxx_flags): Use libstdc++-v3/src/INCLUDES. - -2000-08-11 Jason Merrill - - * configure.in (CC_FOR_TARGET, CHILL_FOR_TARGET, - CXX_FOR_TARGET): Add -B$$r/gcc/ here. - (FLAGS_FOR_TARGET): Not here. - (CHILL_FOR_TARGET, CXX_FOR_TARGET): Don't check the list of languages. - -2000-08-07 DJ Delorie - - * configure.in (FLAGS_FOR_TARGET): invert test for xgcc, should mean - "if we're also building gcc, and it's a gcc that will run on the - build machine, we want to use its includes instead of the system's - default includes". - -2000-08-03 Alexandre Oliva - - * configure.in (libstdcxx_flags): Don't use `"'. - - * config-ml.in: Adjust multilib search paths to the - appropriate multilib tree. - -2000-08-02 Alexandre Oliva - - * configure.in (CHILL_FOR_TARGET, CXX_FOR_TARGET): Convert blanks to - commas in $LANGUAGES. - -2000-08-01 Alexandre Oliva - - * configure.in (qCXX_FOR_TARGET): Use echo instead of expr. - -2000-07-31 Alexandre Oliva - - * configure.in (qCXX_FOR_TARGET): Quote `&' characters in - CXX_FOR_TARGET for sed. - -2000-07-30 Alexandre Oliva - - * configure.in (CC_FOR_TARGET, CHILL_FOR_TARGET, CXX_FOR_TARGET): - Do not override if already set in the environment or in configure. - Don't duplicate $(FLAGS_FOR_TARGET) if it already appears in them. - (FLAGS_FOR_TARGET): Don't use host directories on Canadian crosses. - -2000-07-27 Alexandre Oliva - - * Makefile.in (FLAGS_FOR_TARGET): New macro. - (GCC_FOR_TARGET): Use it. - (CC_FOR_TARGET, CXX_FOR_TARGET, CHILL_FOR_TARGET): Now defined... - * configure.in: ... here. - (FLAGS_FOR_TARGET): Define. Add ld build dir to -L path. - (libstdcxx_flags): Define and append to CXX_FOR_TARGET. - -2000-07-24 Alexandre Oliva - - * Makefile.in (configure-target-libf2c): Depend on $(ALL_GCC). - (configure-target-libchill, configure-target-libobjc): Likewise. - - * configure.in: Use the same cache file for all target libs. - * config-ml.in: But different cache files per multilib variant. - -2000-07-23 Michael Sokolov - - * configure (topsrcdir): Don't use dirname. - -2000-07-20 Jason Merrill - - * configure.in: Remove all references to libg++ and librx. - - * configure, configure.in, Makefile.in: Unify gcc and binutils. - -2000-07-20 Hans-Peter Nilsson - - * config.sub: Update to subversions version 2000-07-06. - -2000-07-12 Andrew Haley - - * configure.in (host_makefile_frag): Use mh-ia64pic on IA-64 hosts. - (target_makefile_frag): Use mt-ia64pic on IA-64 targets. - -2000-07-07 Phil Edwards - - * symlink-tree: Check number of arguments. - -2000-06-06 Andrew Cagney - - * texinfo/texinfo.tex: Update to version 2000-05-28.15. - -2000-07-05 Jim Wilson - - * Makefile.in (CXX_FOR_TARGET): Add libstdc++ to the library - search path for a g++ extracted from the build tree. This - will allow link tests run by configure scripts in - subdirectories to succeed. - -2000-07-01 Koundinya K - - * ltconfig: Add support for mips-dde-sysv4.2MP - -2000-06-28 Corinna Vinschen - - * ltconfig: Check for host_os beeing one of `cygwin', `mingw' or - `os2'. Force ac_cv_exeext to be ".exe" in that case. - -2000-06-19 Timothy Wall - - * configure.in (noconfigdirs): Set noconfigdirs for tic54x target. - * config.sub: Add tic54x target. - -2000-06-07 Phillip Thomas - - * README-maintainer-mode: New file: Contains notes on using - --enable-maintainer-mode with binutils. - -2000-05-29 Andrew Cagney - - * texinfo/texinfo.tex: Update. Version from makeinfo 4.0. - -2000-05-30 Andrew Cagney - - * config.sub: Import CVS version 1.167 Tue May 30 09:00:07 2000. - * config.guess: Import CVS version 1.148 Tue May 30 09:00:06 2000 - -20000-05-21 H.J. Lu (hjl@gnu.org) - - * Makefile.in (CC_FOR_TARGET): Make sure as/ld in the gcc - directory are used if they exist. Make sure - $(build_tooldir)/include is searched for header files, - $(build_tooldir)/lib/ for library files. - (GCC_FOR_TARGET): Likewise. - (CXX_FOR_TARGET): Likewise. - -2000-05-18 Jeffrey A Law (law@cygnus.com) - - * configure.in (hppa*64*-*-*): Do build ld for this configuration. - -2000-05-17 Alexandre Oliva - - * Makefile.in (configure-target-libiberty): Depend on - configure-target-newlib. - -2000-05-16 Alexandre Oliva - - * configure.in, Makefile.in: Merge all libffi-related - configury stuff from the libgcj tree. - -2000-05-16 Andrew Cagney - - Thu Apr 27 11:01:48 2000 Andrew Cagney : - * Makefile.in (do-tar-bz2, do-md5sum): Skip CVS directories. - -2000-05-16 Andrew Cagney - - Wed Apr 26 17:03:53 2000 Andrew Cagney : - * Makefile.in (do-djunpack): New target. Update djunpack.bat with - current version information. Add to proto-toplev directory. - (gdb-taz): Build do-djunpack. - -2000-05-15 David Edelsohn - - * configure.in: Special case powerpc*-*-aix* target_makefile_frag. - -2000-05-13 Alexandre Oliva - - * ltmain.sh: Preserve in relink_command any environment - variables that may affect the linker behavior. - -2000-05-12 Jeffrey A Law (law@cygnus.com) - - * config.sub (basic_machine): Recognize hppa64 as a valid cpu type. - -2000-05-10 Jim Wilson - - * configure.in (ia64*-*-elf*): Add gdb and friends to noconfigdirs. - -2000-05-08 Eli Zaretskii - - * djunpack.bat: Change the Sed script to replace @V@ in fnchange.lst - with the version name. - -2000-05-01 Benjamin Kosnik - - * config.if: Tweak. - -2000-04-23 Eli Zaretskii - - * djunpack.bat: New file. - -2000-04-19 Andrew Cagney - - * Makefile.in (taz, gdb-taz, gas.tar.bz2, binutils.tar.bz2, - gas+binutils.tar.bz2, libg++.tar.bz2, gnats.tar.bz2, gdb.tar.bz2, - dejagnu.tar.bz2, gdb+dejagnu.tar.bz2, insight.tar.bz2, - insight+dejagnu.tar.bz2, newlib.tar.bz2): Pass MD5PROG to sub-make. - -2000-04-16 Dave Pitts - - * config.sub (case $basic_machine): Change default for "ibm-*" - to "openedition". - -2000-04-12 Andrew Cagney - - * Makefile.in (gdb-taz): New target. GDB specific archive. - (do-md5sum): New target. - (MD5PROG): Define. - (PACKAGE): Default to TOOL. - (VER): Default to a shell script. - (taz): Rewrite target. Move real work to do-proto-toplev. Include - md5 checksum generation. - (do-proto-toplev): New target. Create $(PACKAGE)-$(VER) link. - (do-tar-bz2): Delete creation of $(PACKAGE)-$(VER) link. - (gdb.tar.bz2, dejagnu.tar.bz2, gdb+dejagnu.tar.bz2, - insight.tar.bz2): Use gdb-taz to create archive. - -2000-04-07 Andrew Cagney - - * configure (warn_cflags): Delete. - -2000-04-05 Benjamin Kosnik - Martin v. Loewis - - * configure.in (enable_libstdcxx_v3): Add. - (target_libs): Add bits here to switch between libstdc++-v2 and - libstdc++-v3. - * config.if: And this file too. - * Makefile.in: Add libstdc++-v3 targets. - -2000-04-05 Michael Meissner - - * config.sub (d30v): Add d30v as a basic machine type. - -2000-03-29 Jason Merrill - - * configure.in: -linux-gnu*, not -linux-gnu. - -2000-03-03 Andrew Cagney - - * Makefile.in (taz): Set PACKAGE to TOOL when not defined. - (do-tar-bz2): Replace TOOL with PACKAGE. - (gdb.tar.bz2): Remove GDBTK from GDB package. - (gdb+dejagnu.tar.bz2, insight.tar.bz2, insight+dejagnu.tar.bz2, - dejagnu.tar.bz2): New packages. - -2000-02-27 Andreas Jaeger - - * configure.in: Add entry for mips*-*-linux*, move catch all - *-*-*linux* entry below this one. - -2000-02-27 Ian Lance Taylor - - * ltconfig, ltmain.sh: Update to libtool 1.3.4. - -2000-02-24 Nick Clifton - - * config.sub: Support an OS of "wince". - -2000-02-24 Andrew Cagney - - * config.guess, config.sub: Updated to match config's 2000-02-15 - version. - -2000-02-23 Linas Vepstas - - * config.sub: Add support for Linux/IBM 370. - * configure.in: Likewise. - -2000-02-22 Nick Clifton - - * configure.in: Add mips-pe, sh-pe and arm-wince-pe targets. - -2000-02-20 Christopher Faylor - - * config.guess: Guess "cygwin" rather than "cygwin32". - -2000-02-16 Kaveh R. Ghazi - - * configure (gcc_version): When setting, narrow search to - lines containing `version_string'. - -2000-02-15 Denis Chertykov - - * config.sub: Add support for avr target. - -2000-02-01 Hans-Peter Nilsson - - * config.sub: Add mmix-knuth-mmixware. - -2000-01-27 Christopher Faylor - - * Makefile.in (CC_FOR_TARGET): Add new winsup directory - structure stuff to -L library search. - (CXX_FOR_TARGET): Ditto. - (CROSS_CHECK_MODULES): Fix spelling mistake. - -2000-01-24 Mark Mitchell - - * Makefile.in (CXX_FOR_TARGET): Use g++, not xgcc, to invoke - the C++ compiler. - -2000-01-12 Richard Henderson - - * configure.in: Don't build some bits for beos. - -2000-01-12 Joel Sherrill (joel@OARcorp.com) - - * Makefile.in (CC_FOR_TARGET): Use newlib libraries as well - as include files. - -2000-01-06 Geoff Keating - - * configure.in: Use mt-aix43 to handle *_TARGET defs, - not mh-aix43. - -1999-12-14 Richard Henderson - - * config.guess (alpha-osf, alpha-linux): Detect ev67. - * config.sub: Accept alphaev[78], alphaev8. - -1999-12-03 Alexandre Oliva - - * config.guess, config.sub: Update from autoconf. - -Tue Nov 23 00:57:41 1999 Rainer Orth - - * config-ml.in (sparc*-*-*): Disable sparcv9 support if the - necessary libraries are missing. - -1999-10-25 Andreas Schwab - - * configure: Fix quoting inside arguments of eval. - -1999-10-21 Nick Clifton - - * config-ml.in: Allow suppression of some ARM multilibs. - -Tue Sep 7 23:33:57 1999 Linas Vepstas - - * config.guess: Add OS/390 match pattern. - * config.sub: Add mvs, openedition targets. - * configure.in (i370-ibm-opened*): New. - -1999-09-04 Steve Chamberlain - - * config.sub: Add support for configuring for pj. - -1999-08-31 Nick Clifton - - * config.sub (maybe_os): Add support for configuring for fr30. - -1999-08-25 Nick Clifton - - * configure.in: Do not configure or build ld for AIX - platforms. ld is known to be broken on these platforms. - -Wed Aug 25 01:12:25 1999 Rainer Orth - - * config-ml.in: Pass compiler flag corresponding to multidirs to - subdir configures. - -1999-08-09 Ian Lance Taylor - - * Makefile.in (LDFLAGS): Define. - -1999-08-08 Mumit Khan - - * configure.in (i[3456]-*-mingw32*): Don't put gprof in - noconfigdirs. - (*-*-cygwin*): Likewise. - -1999-08-08 Ian Lance Taylor - - * mkdep: New file. - * Makefile.in (GAS_SUPPORT_DIRS): Add mkdep. - (BINUTILS_SUPPORT_DIRS): Add mkdep. - - From Eli Zaretskii : - * configure (tmpfile): Change cONf$$ to cNf$$ to avoid an overly - long file name when using DJGPP on MS-DOS. - -Wed Aug 4 02:07:14 1999 Jeffrey A Law (law@cygnus.com) - - * config.sub (vxworks case): Use os=-vxworks, not os=vxworks. - -1999-07-30 Alan Modra - - * Makefile.in (check-target-libio): Remove all-target-libstdc++ - dependency as this causes "make check" to globally "make all" - -Tue Jun 22 23:45:18 1999 Tom Tromey - - * configure.in (target_libs): Added target-zlib. - * Makefile.in (ALL_TARGET_MODULES): Added zlib. - (CONFIGURE_TARGET_MODULES): Likewise. - (CHECK_TARGET_MODULES): Likewise. - (INSTALL_TARGET_MODULES): Likewise. - (CLEAN_TARGET_MODULES): Likewise. - (configure-target-zlib): New target. - (all-target-zlib): Likewise. - (all-target-libjava): Depend on all-target-zlib. - (configure-target-libjava): Depend on configure-target-zlib. - - * Makefile.in (configure-target-libjava): Depend on - configure-target-newlib. - (configure-target-boehm-gc): New target. - (configure-target-qthreads): New target. - - * configure.in (target_libs): Added target-qthreads. - * Makefile.in (ALL_TARGET_MODULES): Added qthreads. - (CONFIGURE_TARGET_MODULES): Likewise. - (CHECK_TARGET_MODULES): Likewise. - (INSTALL_TARGET_MODULES): Likewise. - (CLEAN_TARGET_MODULES): Likewise. - (all-target-qthreads): New target. - (configure-target-libjava): Depend on configure-target-qthreads. - (all-target-libjava): Depend on all-target-qthreads. - - * Makefile.in (ALL_TARGET_MODULES): Added libjava, boehm-gc. - (CONFIGURE_TARGET_MODULES): Likewise. - (CHECK_TARGET_MODULES): Likewise. - (INSTALL_TARGET_MODULES): Likewise. - (CLEAN_TARGET_MODULES): Likewise. - (all-target-libjava): New target. - (all-target-boehm-gc): Likewise. - * configure.in (target_libs): Added libjava, boehm-gc. - -1999-07-22 Ian Lance Taylor - - * Makefile.in (binutils.tar.bz2): Don't pass makeall.bat and - configure.bat in SUPPORT_FILES. - (gas+binutils.tar.bz2): Likewise. - - * makeall.bat: Remove; obsolete. - -1999-07-21 Ian Lance Taylor - - From Mark Elbrecht: - * configure.bat: Remove; obsolete. - -1999-07-11 Ian Lance Taylor - - * configure: Add -W -Wall to the default CFLAGS when compiling with - gcc. - -Thu Jul 8 12:32:23 1999 John David Anglin - - * configure.in: Build ld, binutils & gas for hppa*-*-linux-gnu*. - -1999-06-30 Mark Mitchell - - * configure.in: Build ld on IRIX6. - -1999-06-12 Ian Lance Taylor - - * Makefile.in: Change distribution targets to use bzip2 instead of - gzip. - (TEXINFO_SUPPORT): Set to just texinfo/texinfo.tex. - (taz): Don't use texinfo/gpl.texinfo or texinfo/lgpl.texinfo. - -1999-06-04 Nick Clifton - - * config.sub: Add mcore target. - -1999-05-30 Cort Dougan - - * config.guess (ppc-*-linux-gnu): Also use ld emul elf32ppclinux. - -1999-05-25 H.J. Lu (hjl@gnu.org) - - * config.guess (dummy): Changed to $dummy. - -1999-05-24 Nick Clifton - - * config.sub: Tidied up case statements. - -1999-05-22 Ben Elliston - - * config.guess: Handle NEC UX/4800. Contributed by Jiro Takabatake - . - - * config.guess: Merge with FSF version. Future changes will be - more accurately recorded in this ChangeLog. - * config.sub: Likewise. - -1999-05-20 Stephen L Moshier - - * Makefile.in (GCC_FOR_TARGET): Add -I$(build_tooldir)/include. - -1999-04-30 Tom Tromey - - * ltmain.sh: [mode link] Always use CC given by ltconfig. - -1999-04-23 Tom Tromey - - * ltconfig, ltmain.sh: Update to libtool 1.2f. - -1999-04-20 Drew Moseley - - * configure.in (noconfigdirs): Don't build libstub for arm-elf targets. - (noconfigdirs): Don't build any bsp stuff for for arm-oabi targets. - Bad merge removed these two changes. - -Tue Apr 13 22:50:54 1999 Donn Terry (donn@interix.com) - Martin Heller (Ing.-Buero_Heller@t-online.de) - - * config.guess (interix Alpha): Add. - -1999-04-11 Richard Henderson - - * configure.in (i?86-*-beos*): Do config gperf; don't config - gdb, newlib, or libgloss. - -1999-04-11 Alexandre Oliva - - * config-ml.in: On mips*-*-*, if multidirs contains mabi=64, try to - link a trivial program with -mabi=64. If it fails, remove mabi=64 - from multidirs. - -1999-04-10 Philipp Thomas (kthomas@gwdg.de) - - * config.sub: Set basic_machine to i586 when target_alias = k6-*. - -1999-04-08 Nick Clifton - - * config.sub: Add support for mcore targets. - -1999-04-07 Michael Meissner - - * configure.in (d30v-*): Use config/mt-d30v as makefile fragment, - not mt-ospace, in order to shut up assembler warning about using - symbols that are named the same as registers. - -1999-04-07 Drew Moseley - - * Makefile.in (all-target-cygmon): Added all-target-bsp to the - dependency list for all-target-cygmon. - -1999-04-05 Doug Evans - - * config-ml.in: Check $host, not $target, for selective multilibs. - (arm-*-*): Allow disabling of biendian, h/w fp, 26 bit apcs, - thumb interworking, and underscore prefix multilibs. - -1999-04-04 Ian Lance Taylor - - * missing: Update to version from current automake. - -Fri Apr 2 15:11:32 1999 H.J. Lu (hjl@gnu.org) - - * configure (gxx_include_dir): Removed. - - * configure.in (gxx_include_dir): Handle it. - * Makefile.in: Likewise. - -1999-03-29 Gavin Romig-Koch - - * config.sub (mips64vr4111,mips64vr4111el) Add. - -1999-03-21 Ben Elliston - - * config.guess: Correct typo for detecting ELF on FreeBSD. - -Thu Mar 18 00:17:50 1999 Mark Elbrecht - - * config/mh-go32: Delete. - * config/mh-djgpp: New. Renamed from mh-go32. - * configure.in (pc-msdosdjgpp): Set host_makefile_frag to - config/mh-djgpp. - -Thu Mar 11 18:37:23 1999 Drew Moseley - - * Makefile.in (all-target-bsp): Added all-gcc all-binutils and - all-target-newlib to dependency list for all-target-bsp. - -Thu Mar 11 01:19:31 1999 Mumit Khan - - * config.sub: Add i386-uwin support. - * config.guess: Likewise. - -Thu Mar 11 01:07:55 1999 Franz Sirl - - * configure.in: cleanup, add mh-*pic handling for arm, special - case powerpc*-*-aix* - -Wed Mar 10 18:35:07 1999 Jeff Johnston - - * configure.in (noconfigdirs): Removed target-libgloss so libnosys.a - can be built. - -Wed Mar 10 17:39:09 1999 Drew Moseley - - * configure.in: Added bsp support to arm-*-coff and arm-*-elf - targets. - -1999-03-02 Nick Clifton - - * config.sub: Rename CYGNUS LOCAL to EGCS LOCAL - -1999-02-28 Geoffrey Noer - - * config.sub: Check for "cygwin*" rather than "cygwin32*" - -1999-02-24 Nick Clifton - - * config.sub: Fix typo in arm recognition. - -1999-02-24 Drew Moseley - - * configure.in (noconfigdirs): Changed target_configdirs to - include target-bsp only for m68k-*-elf* and m68k-*-coff* - rather than m68k-*-* since it is not known to work on - m68k-aout. Ditto for arm-*-*oabi. - -1999-02-24 Stan Shebs - - * configure.in (*-*-windows*): Remove, no longer used. - * config/mh-windows: Ditto. - -1999-02-19 Ben Elliston - - * config.guess: Automatically recognise ELF on FreeBSD. From Niall - Smart and improved by Andrew Cagney. - -1999-02-18 Marc Espie - - * config.guess: Recognize openbsd-*-hppa. - -1999-02-17 H.J. Lu (hjl@gnu.org) - - * Makefile.in (REALLY_SET_LIB_PATH): Append $$$(RPATH_ENVVAR) - only if it is not empty. - -1999-02-17 Nick Clifton - - Patch from: Scott Bambrough - - * config.guess: Modified to recognize uname's armv* syntax. - - * config.sub: Modified to recognize uname's armv* syntax. - -1999-02-17 Mark Salter - - * configure.in: Added target-bsp for sparclite. - -1999-02-08 Richard Henderson - - * config.sub: Recognize alphapca5[67] and up to alphaev8. - -1999-02-08 Nick Clifton - - * configure.in: Add support for strongarm port. - * config.sub: Add support for strongarm target. - -1999-02-07 Mumit Khan - - * configure.in (*-*-cygwin32*): Use config/mh-cygwin instead of - the old name config/mh-cygwin32. - Enable texinfo. - -1999-02-04 Ian Lance Taylor - - * configure.in: Do build ld for ix86 Solaris. - -1999-02-02 Jim Wilson - - * Makefile.in (EXTRA_GCC_FLAGS): Set AR to $AR instead of - $AR_FOR_TARGET. Likewise for RANLIB. - -1999-02-02 Catherine Moore - - * config.sub (oabi): Recognize. - * configure.in (arm-*-oabi): Handle. - -1999-01-30 Robert Lipe (robertlipe@usa.net) - - * config.guess: Improve detection of i686 on UnixWare 7. - -1999-01-30 Mumit Khan - - * config.guess: Add support for i386-pc-interix. - * config.sub: Likewise. - * configure.in: Likewise. - * config/mh-interix: New file. - -1999-01-18 Christopher Faylor - - * Makefile.in: Remove unneeded all-target-libio from - from all-target-winsup target since it is now unneeded. - Add all-target-libtermcap in its place since it is now - needed. - -1998-12-30 Christopher Faylor - - * configure.in: makefile stub for cygwin target is probably - unnecessary. Remove it for now. - * config/mt-cygwin: Remove. - -1998-12-30 Christopher Faylor - - * configure.in: libtermcap.a should be built when cygwin is the - target as well as the host. - * config.guess: Allow mixed case in cygwin uname output. - * Makefile.in: Add libtermcap target. - * config/mt-cygwin: New file. libtermcap target info. - -1998-12-23 Jeffrey A Law (law@cygnus.com) - - * config.sub: Clean up handling of hppa2.0. - -1998-12-22 Rodney Brown (rodneybrown@pmsc.com) - - * config.guess: Use C code to identify more HP machines. - -Thu Dec 17 01:22:30 1998 Jeffrey A Law (law@cygnus.com) - - * config.sub: Handle hppa2.0. - -Tue Dec 15 17:02:58 1998 Bob Manson - - * configure.in: Add cygmon for x86-coff and x86-elf. Configure - cygmon for all sparclite targets, regardless of object format. - -1998-12-15 Mark Salter - - * configure.in: Added target-bsp for several target architectures. - - * Makefile.in: Added rules for bsp. - -Fri Dec 4 01:34:02 1998 Jeffrey A Law (law@cygnus.com) - - * config.guess: Improve detection of hppa2.0 processors. - -Fri Dec 4 01:33:05 1998 Niall Smart - - * config.guess: Recognize FreeBSD using ELF automatically. - -1998-11-26 Manfred Hollstein - - * configure (skip-this-dir): Add handling for new shell script, which - might be created by a sub-directory's configure to indicate, this particular - directory is "unwanted". - * Makefile.in ($(CONFIGURE_TARGET_MODULES)): Likewise. - -Wed Nov 18 18:28:45 1998 Geoffrey Noer - - * ltconfig: import from libtool, after changing libtool to - account for the cygwin name change. - -Wed Nov 18 18:09:14 1998 Geoffrey Noer - - * Makefile.in: CC_FOR_TARGET and CXX_FOR_TARGET should also - include newlib/libc/sys/cygwin and newlib/libc/sys/cygwin32. - -Wed Nov 18 20:13:29 1998 Christopher Faylor - - * configure.in: Add libtermcap to list of cygwin dependencies. - -1998-11-17 Geoffrey Noer - - * Makefile.in: modify CC_FOR_TARGET and CXX_FOR_TARGET so that - they include winsup/include when it's a cygwin target. - -1998-11-12 Tom Tromey - - * configure.in (host_tools): Added zip. - * Makefile.in (all-target-libjava): Depend on all-zip. - (all-zip): New target. - (ALL_MODULES): Added all-zip. - (NATIVE_CHECK_MODULES): Added check-zip. - (INSTALL_MODULES): Added install-zip. - (CLEAN_MODULES): Added clean-zip. - -1998-11-12 Geoffrey Noer - - * Makefile.in: lose "32" from comment about cygwin. - -1998-11-05 Nick Clifton - - * configure.in: Use -Os to build target libraries for the fr30. - -1998-11-04 Dave Brolley - - * config.sub: Add fr30. - -1998-11-02 Geoffrey Noer - - * configure.in: drop "32" from config/mh-cygwin32. Check - cygwin* instead of cygwin32*. - * config.sub: Check cygwin* instead of cygwin32*. - -1998-10-22 Robert Lipe - - * config.guess: Match any version of Unixware7. - -1998-10-20 Syd Polk - - * Makefile.in configure.in: Add the ability to use tcl8.1 and tk8.1 - if desired. - -1998-10-18 Jeffrey A Law (law@cygnus.com) - - * config.if (cxx_interface, libstdcxx_interface): Do not try to set - these if the appropriate directories and files to not exist. - -1998-10-14 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (DEVO_SUPPORT): Add config.if. - -1998-10-13 Manfred Hollstein - - * configure: Add pattern to replace "build_tooldir"'s - definition in the generated Makefile with "tooldir"'s - actual value. - -Tue Oct 13 09:17:06 1998 Jeffrey A Law (law@cygnus.com) - - * config.sub: Bring back lost sparcv9. - - * Makefile.in (all-snvavigator): Remove all-flexlm dependency. - -Mon Oct 12 12:09:44 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (CHILL_FOR_TARGET): Mirror recent changes to - CC_FOR_TARGET and friends. - -Mon Oct 12 12:09:30 1998 Alexandre Oliva - - * Makefile.in (build_tooldir): New variable, same as tooldir. - (CC_FOR_TARGET, GCC_FOR_TARGET, CXX_FOR_TARGET): Add - -B$(build_tooldir)/bin/. - (BASE_FLAGS_TO_PASS): Pass build_tooldir down. - -Wed Sep 30 22:20:50 1998 Robert Lipe - - * config.sub: Add support for i[34567]86-pc-udk. - * configure.in: Likewise. - -Wed Sep 30 19:23:48 1998 Geoffrey Noer - - * Makefile.in: add bzip2 package building bits for user - tools module - * configure.in: ditto - -Wed Sep 30 03:00:05 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (TARGET_CONFIGDIRS): Add libobjc. - (ALL_TARGET_MODULES): Add all-target-libobjc. - (CONFIGURE_TARGET_MODULES, CHECK_TARGET_MODULES): Similarly. - (INSTALL_TARGET_MODULES, CLEAN_TARGET_MODULES): Similarly. - (all-target-libchill): Add dependencies. - * configure.in (target_libs): Add libchill. - -1998-09-30 Manfred Hollstein - - * configure.in (target_subdir): Remove duplicate line. - -Tue Sep 29 22:45:41 1998 Felix Lee - - * Makefile.in (all-automake): fix dependencies. - -Mon Sep 28 04:04:27 1998 Jeffrey A Law (law@cygnus.com) - - * configure.in: Minor cleanups for building in the $(target_alias) - subdir. - -1998-09-22 Jim Wilson - - * Makefile.in (bootstrap): Set r and s before make all. Use - BASE_FLAGS_TO_PASS in make all. - (cross): Likewise. - -1998-09-20 Mark Mitchell - - * Makefile.in (bootstrap): Pass TARGET_FLAGS_TO_PASS to `make all'. - -Sun Sep 20 00:13:02 1998 Richard Henderson - - * config.sub: Fix typo in last change. - -1998-09-19 Michael Hayes - - * config.sub: Add support for C4x target. - * configure.in: Likewise. - -1998-09-13 David S. Miller - - * config.sub: Recognize sparcv9 just like sparc64. - -Wed Sep 9 15:44:52 1998 Robert Lipe - - * config.guess: Match "Pent II" or "PentII" for OpenServer. - -Tue Sep 8 01:18:39 1998 Jeffrey A Law (law@cygnus.com) - - * config.guess: Correctly identify Pentium II sco boxes. - - * config.guess: Fix "tr" code. From Weiwen Liu. - -Sat Sep 5 13:56:52 1998 John Hughes - - * configure.in: Do not assume x86-svr4 or x86-unixware can handle - stabs. - -Sat Sep 5 02:12:02 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (TARGET_CONFIGDIRS): Add libchill. - (ALL_TARGET_MODULES): Add all-target-libchill. - (CONFIGURE_TARGET_MODULES, CHECK_TARGET_MODULES): Similarly. - (INSTALL_TARGET_MODULES, CLEAN_TARGET_MODULES): Similarly. - (all-target-libchill): Add dependencies. - * configure.in (target_libs): Add libchill. - -Sun Aug 30 22:27:02 1998 Lutz Wohlrab - - * config.guess: Avoid assumptions about "tr" behaves when - LANG is set to something other than English. - -Sun Aug 30 22:14:44 1998 H.J. Lu (hjl@gnu.org) - - * configure (gxx_include_dir): Changed to - '${prefix}/include/g++'-${libstdcxx_interface}. - - * config.if: New to determine the interfaces. - -Sun Aug 30 21:15:19 1998 Mark Klein (mklein@dis.com) - - * config.guess: Detect and handle MPE/IX. - * config.sub: Deal with MPE/IX. - -Sat Aug 29 14:32:55 1998 David Edelsohn - - * configure.in: Use mh-aix43. - -1998-07-29 Manfred Hollstein - - * configure: Fix --without/--disable cases for gxx-include-dir. - -Fri Aug 28 12:28:26 1998 Per Bothner - - * mdata-sh: Imported. Needed for automake support. - -Thu Aug 13 12:49:29 1998 H.J. Lu - - * Makefile.in (taz): Try "chmod -R og=u ." before - "chmod og=u `find . -print`". - -Fri Jul 31 09:38:33 1998 Catherine Moore - - * configure.in: Add arm-elf and thumb-elf support. - -Mon Jul 27 16:23:58 1998 Doug Evans - - * Makefile.in: Undo previous patch. - -Fri Jul 24 19:55:24 1998 Doug Evans - - * Makefile.in (INSTALL_TARGET): Move EXTRA_TARGET_HOST_INSTALL_MODULES - to here ... - (install-no-fixedincludes): and here - (INSTALL_MODULES): ... from here. - -Fri Jul 24 17:01:42 1998 Ian Lance Taylor - - * config.sub: Merge with FSF. - - * config.guess: Merge with FSF. - -Fri Jul 24 08:43:36 1998 Doug Evans - - * configure (extraconfigdirs): New variable. - (SUBDIRS): Add extraconfigdirs and recurse on them too. - * Makefile.in (all): Move higher in file. - (EXTRA_TARGET_HOST_ALL_MODULES): New variable. - (EXTRA_TARGET_HOST_{INSTALL,CHECK}_MODULES): New variables. - (ALL_MODULES): Add EXTRA_TARGET_HOST_ALL_MODULES. - (CROSS_CHECK_MODULES): Add EXTRA_TARGET_HOST_CHECK_MODULES. - (INSTALL_MODULES): Add EXTRA_TARGET_HOST_INSTALL_MODULES. - -1998-07-23 Brendan Kehoe - - * Makefile.in (all-target-libjava): Depend on all-gcc and - all-target-newlib. - (configure-target-libjava): Depend on $(ALL_GCC). - -Sat Jul 18 14:32:43 CDT 1998 Robert Lipe - - * config.guess: (*-pc-sco3.2v5) Add detection for Pentium II. - (*-pc-unixware7) Add detection for Pentium II, Pentium Pro. - -Fri Jul 17 13:30:18 1998 Ian Lance Taylor - - * ylwrap: Change absolute path checks to check for DOS style path - names. - - * ylwrap: Don't use a full path name if the source file is in the - same directory. From hjl@lucon.org (H.J. Lu). - - * config-ml.in: Default to being verbose, to match Feb 18 change to - configure. - -Thu Jul 16 12:29:51 1998 Ian Lance Taylor - - Brought over from egcs: - - Sat Jun 27 22:46:32 1998 Jeffrey A Law (law@cygnus.com) - - * configure.in (target_subdir): Set to ${target_alias} instead - of "libraries". - - Mon Sep 1 16:45:44 1997 Jim Wilson - - * configure.in (target_subdir): Set to libraries if enable_multilib. - -Wed Jul 15 01:00:54 1998 Ian Lance Taylor - - * Makefile.in ($(CONFIGURE_TARGET_MODULES)): If there are any - multilibs, force reconfiguration the first time we create - multilib.out in a subdirectory, in case TARGET_SUBDIR is `.'. - -Tue Jul 14 23:41:03 1998 Ian Lance Taylor - - * configure.in: Strip any --no option from CONFIG_ARGUMENTS, to - avoid confusion with --no-recursion. - -Tue Jul 14 15:37:41 1998 Geoffrey Noer - - * configure.in: Win32 hosts shouldn't use install -x - * install-sh: remove -x option, and special .exe-handling - hack. - -Tue Jul 14 15:28:41 1998 Richard Henderson - - * config.guess: Recognize i586-pc-beos. - * configure.in: Don't build some bits for beos. - -Tue Jul 14 13:22:18 1998 Ian Lance Taylor - - * configure: If CC is set but CFLAGS is not, and CC is gcc, make - CFLAGS default to -O2. - - * ltmain.sh: Add some hacks to make SunOS --enable-shared work - when using GNU ld. - -Fri Jul 10 13:18:23 1998 Ian Lance Taylor - - * ltmain.sh: Correct install when using a different shell. - -Tue Jul 7 15:24:38 1998 Ian Lance Taylor - - * ltconfig, ltmain.sh: Update to libtool 1.2b. - -Thu Jul 2 13:57:36 1998 Klaus Kaempf - - * makefile.vms: Update to build binutils/makefile.vms. Add install - target. - -Wed Jul 1 16:45:21 1998 Ian Lance Taylor - - * ltconfig: Update to correct AIX handling. - -Sat Jun 27 22:46:32 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (BASE_FLAGS_TO_PASS): Add TARGET_SUBDIR. - - * configure.in (target_subdir): Set to ${target_alias} instead - of "libraries". - -1998-06-26 Manfred Hollstein - - * Makefile.in (BASE_FLAGS_TO_PASS): Add gcc_version_trigger. - (Makefile): Depend on $(gcc_version_trigger). - - * configure (gcc_version): Change default initializer to empty - string. - (gcc_version_trigger): New variable; pass this variable down - to subdir configures to enable them checking gcc's version - themselves. Emit make macros for both gcc_version vars. - (topsrcdir): Initialize reliably. - (recursion line): Remove --with-gcc-version=${gcc_version}. - -1998-06-24 Manfred Hollstein - - * configure (enable_version_specific_runtime_libs): Implement new flag - --enable-version-specific-runtime-libs which installs C++ runtime stuff - in $(libsubdir); emit definition in each generated Makefile. - (gxx_include_dir): Initialize depending on - $enable_version_specific_runtime_libs. - -1998-06-24 Manfred Hollstein - - * configure (gcc_version): Initialize properly depending on - how and where configure is started. - (recursion line): Pass a --with-gcc-version=${gcc_version} - to configures in subdirs. - -Wed Jun 24 16:01:59 1998 John Metzler - - * configure.in (noconfigdirs): Add configure pattern for mips tx39 - cygmon - -Tue Jun 23 22:42:32 1998 Mark Alexander - - * configure.in: Add cygmon and libstub support for mn10200. - -1998-06-19 Manfred Hollstein - - * configure (gcc_version): Add new variable describing the - particular gcc version we're building. - * Makefile.in (libsubdir): Add new macro for the directory - in which the compiler finds executables, libraries, etc. - (BASE_FLAGS_TO_PASS): Pass down gcc_version, target_alias - and libsubdir. - -Fri Jun 19 02:36:59 1998 Alexandre Oliva - - * Makefile.in (local-clean): Remove *.log. - (warning.log): Built with warn_summary from build.log. - (mail-report.log): Run test_summary. - (mail-report-with-warnings.log): Run test_summary including - warning.log in the report. - -Thu Jun 18 11:26:03 1998 Robert Lipe - - * config.guess: Detection of Pentium II for *-sco-3.2v5*. - -Mon Jun 15 14:53:54 1998 Andrew Cagney - - * Makefile.in (grep): Grep no longer depends on libiberty. - -Fri Jun 12 14:03:34 1998 Syd Polk - - * Makefile.in: all-snavigator needs all-libgui. - -Thu Jun 11 19:43:47 1998 Mark Alexander - - * configure.in: Add cygmon and libstub support for mn10300. - -Wed Jun 10 11:19:47 1998 Ian Lance Taylor - - * missing: Update to version from automake 1.3. - - * ltmain.sh: On installation, don't get confused if the same name - appears more than once in the list of library names. - -Wed Jun 3 14:51:42 1998 Ian Lance Taylor - - * config.sub: Accept m68060 and m5200 as CPU names. - -Mon Jun 1 17:25:16 1998 Ian Lance Taylor - - * configure: Use && rather than using -a in test, because odd - strings can confuse test. - * configure.in: Likewise. - -Thu May 28 19:31:13 1998 Ian Lance Taylor - - * ltconfig, ltmain.sh: Bring in Visual C++ support. - -Sat May 23 23:44:13 1998 Alexandre Oliva - - * Makefile.in (boostrap2-lean, bootstrap3-lean, - bootstrap4-lean): New targets. - -Mon May 11 23:55:56 1998 Jeffrey A Law (law@cygnus.com) - - * mpw-* Delete. Not used. - -Mon May 11 23:11:34 1998 Jeffrey A Law (law@cygnus.com) - - * COPYING.LIB: Update FSF address. - -Fri May 8 01:30:20 1998 Ian Lance Taylor - - * ltconfig, ltmain.sh: Update to libtool 1.2a. - - * Makefile.in (GASB_SUPPORT_DIRS): Remove intl; already included via - GAS_SUPPORT_DIRS. - -Thu May 7 17:27:35 1998 Ian Lance Taylor - - * ltconfig, ltmain.sh: Avoid producing a version number if - -version-info was not used. - -Tue May 5 18:02:24 1998 Ian Lance Taylor - - * configure.in: Add --with-newlib to CONFIG_ARGUMENTS if we are - building with newlib. - -1998-04-30 Paul Eggert - - * Makefile.in (EXTRA_GCC_FLAGS): Remove backslash at end; - Solaris `make' causes it to continue to next definition. - -Tue Apr 28 16:24:24 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in (install-gdbtk): Call this 'install-gdb' so that - the right GUI libraries and files are installed along with GDB. - -Tue Apr 28 18:11:24 1998 Ian Lance Taylor - - * configure.in: Change alpha to alpha* in several places. - -Tue Apr 28 07:42:00 1998 Mark Alexander - - * config.sub: Recognize sparc86x. - -Tue Apr 28 07:35:02 1998 Michael Meissner - - * configure.in (--enable-target-optspace): Remove debug echo. - -Thu Apr 23 21:31:16 1998 Jim Wilson - - * configure: Set CXXFLAGS from CXXFLAGS, not CFLAGS. - -Thu Apr 23 12:26:38 1998 Ian Lance Taylor - - * ltconfig: Update cygwin32 support. - - * Makefile.in (GAS_SUPPORT_DIRS): Add intl. - (BINUTILS_SUPPORT_DIRS, GASB_SUPPORT_DIRS): Likewise. - (GDB_SUPPORT_DIRS): Likewise. - -Wed Apr 22 12:30:10 1998 Michael Meissner - - * configure.in (target_makefile_frag): If --enable-target-optspace, - use -Os to compile target libraries rather than -O2. Default to - using -Os for d10v and m32r if --{enable,disable}-target-optspace is - not used. - * configure.in (target_cflags): Ditto for d30v. - -Tue Apr 21 23:06:54 1998 Tom Tromey - - * Makefile.in (all-bfd): Depend on all-intl. - (all-binutils): Likewise. - (all-gas): Likewise. - (all-gprof): Likewise. - (all-ld): Likewise. - -1998-04-19 Brendan Kehoe - - * configure.in (host_tools): Fix typo, lbtool -> libtool. - -Fri Apr 17 16:20:42 1998 Ian Lance Taylor - - * Makefile.in (all-bfd): Depend upon all-libiberty. - - * ltconfig, ltmain.sh: Bring in newer cygwin32 support. - -Fri Apr 17 12:22:22 1998 Bob Manson - - * Makefile.in: Add libstub. - - * configure.in: Ditto. Build libstub for targets that have cygmon - support. - -Tue Apr 14 18:01:55 1998 Ian Lance Taylor - - * configure.in: Don't set PICFLAG on ix86-cygwin32. - -Tue Apr 14 12:24:45 1998 J. Kean Johnston - - * configure.in: Recognise i[3456]96-*-sysv5* as a valid host, and - use mh-sysv5 if specified. Support gprof on SCO Open Server. - -Tue Apr 14 11:33:51 1998 Krister Walfridsson - - * configure: Define DEFAULT_M4 by searching PATH. - * Makfile.in: Use DEFAULT_M4. - -Mon Apr 13 15:37:24 1998 Ian Lance Taylor - - * ltconfig: Add cygwin32 support. - - * Makefile.in, configure.in: Add libtool as a native only directory - to configure and build. - -Sun Apr 12 20:58:46 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (INSTALL_MODULES): Remove texinfo. - -Wed Apr 8 13:18:56 1998 Philippe De Muyter - - * Makefile.in (EXTRA_GCC_FLAGS): XFOO lines shortened. - -Thu Apr 2 14:48:44 1998 Geoffrey Noer - - * Makefile.in: add ash make rules - * configure.in: add ash to native_only and host_tools lists - -Thu Mar 26 12:53:20 1998 Tom Tromey - - * Makefile.in (all-gettext, all-intl): New targets. - (ALL_MODULES): Added all-gettext, all-intl. - (CROSS_CHECK_MODULES): Added check-gettext, check-intl. - (INSTALL_MODULES): Added install-gettext, install-intl. - (CLEAN_MODULES): Added clean-gettext, clean-intl. - - * configure.in (host_tools): Added gettext. - (native_only): Likewise. - (noconfigdirs) [various cases]: Likewise. - (host_libs): Added intl. - -Thu Mar 26 15:00:11 1998 Keith Seitz - - * configure: Do not disable building gdbtk for cygwin32 hosts. - -Wed Mar 25 10:04:18 1998 Nick Clifton - - * configure.in: Add thumb-coff target. - * config.sub: Add thumb-coff target. - -Wed Mar 25 11:49:12 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in: Revert yesterday's change. - (all-target-winsup): all-target-librx stays out of here. - -Tue Mar 24 16:58:29 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in (TARGET_CONFIGDIRS, ALL_TARGET_MODULES, - CONFIGURE_TARGET_MODULES, CHECK_TARGET_MODULES, - INSTALL_TARGET_MODULES, CLEAN_TARGET_MODULES, all-target-winsup): - Remove references to librx and libg++. - -Tue Mar 24 18:28:12 1998 Eric Mumpower - - * Makefile.in (BASE_FLAGS_TO_PASS): Pass $(lispdir) down to - recursive makes - -Tue Mar 24 11:37:45 1998 Ian Lance Taylor - - * Makefile.in (CC_FOR_TARGET): Use $(TARGET_SUBDIR) when passing -B - for newlib directory. - (CXX_FOR_TARGET): Likewise. - -Mon Mar 23 11:30:21 1998 Jeffrey A Law (law@cygnus.com) - - * ltconfig: Update after libtool/ltconfig.in change for - hpux11. - -Fri Mar 20 18:51:43 1998 Ian Lance Taylor - - * ltconfig, ltmain.sh: Update to libtool 1.2. - -Fri Mar 20 09:32:14 1998 Manfred Hollstein - - * Makefile.in (install-gcc): Don't specify LANGUAGES here. - (install-gcc-cross): Instead, override LANGUAGES here. - -1998-03-18 Dave Love - - * Makefile.in ($(CONFIGURE_TARGET_MODULES)): Set CONFIG_SITE to a - non-existent file since /dev/null loses with bash 2.0/autoconf 2.12. - -Wed Mar 18 09:24:59 1998 Nick Clifton - - * configure.in: Add Thumb-pe target. - -Tue Mar 17 16:59:00 1998 Syd Polk - - * Makefile.in - changed sn targets to snavigator - * configure.in - changed sn targets to snavigator - -Tue Mar 17 10:33:28 1998 Manfred Hollstein - - * config-ml.in: After building symlink tree call make distclean - if a Makefile got linked into ${ml_dir}/${ml_libdir}; this happens - to be the case for libiberty. - -Tue Mar 17 10:22:37 1998 H.J. Lu (hjl@gnu.ai.mit.edu) - - * configure: When making link, also check the current - directory. The configure scripts may create one. - -Fri Mar 6 01:02:03 1998 Richard Henderson - - * config.sub: Accept alphapca56 and alphaev6 properly. - -Fri Mar 6 00:14:55 1998 Franz Sirl - - * configure.in: Revert 3 Jan change for powerpc-linux-gnulibc1. - -Mon Feb 23 15:09:18 1998 Bruno Haible - - * Makefile.in (INSTALL_MODULES): Move install-tcl before - install-itcl. - (install-itcl): Remove dependency on install-tcl. - -Mon Feb 23 09:53:28 1998 Mark Alexander - - * configure.in: Remove libgloss from noconfigdirs for MN10300. - -Thu Feb 19 13:40:41 1998 Ian Lance Taylor - - * configure.in: Don't build libgui for a cygwin32 target when not on - a cygwin32 host. - -Wed Feb 18 12:29:00 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * configure (redirect): Set to null, so default behavior of - configure is now --verbose. - -1998-02-16 Dave Love - - * Makefile.in ($(CONFIGURE_TARGET_MODULES)): Run configure with - CONFIG_SITE=/dev/null to forestall lossage with site configuration. - -Mon Feb 16 12:23:53 1998 Manfred Hollstein - - * Makefile.in (BASE_FLAGS_TO_PASS, EXTRA_TARGET_FLAGS): Really add - this change to sync Makefile.in with its ChangeLog entries. - -Thu Feb 12 15:03:08 1998 H.J. Lu - - * ltmain.sh (mkdir): Check that the directory doesn't exist - before we exit with error, so that we don't get races during - parallel builds. - -Sat Feb 7 15:19:18 1998 Ian Lance Taylor - - * ltconfig, ltmain.sh: Update from libtool 1.0i. - -Fri Feb 6 01:33:52 1998 Manfred Hollstein - - * Makefile.in (BASE_FLAGS_TO_PASS): Don't pass PICFLAG and - PICFLAG_FOR_TARGET. - (EXTRA_TARGET_FLAGS): Don't pass PICFLAG_FOR_TARGET. - - * configure: Emit a definition for the new macro enable_shared - into each Makefile. - - * config/mh-sparcpic (PICFLAG): Define to properly according - to current multilib configuration. - * config/mt-sparcpic (PICFLAG_FOR_TARGET): Define to properly - according to current multilib configuration. - -Thu Feb 5 17:01:12 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * configure.in (host_tools, native_only): Add libtool. - -Wed Feb 4 16:53:58 1998 Geoffrey Noer - - * configure.in: add target-gperf to noconfigdirs for Cygwin32. - Fix typo in ming config comment. - -Wed Feb 4 18:56:13 1998 Ian Lance Taylor - - * ltconfig, ltmain.sh: Update from libtool 1.0h. - -Mon Feb 2 19:38:19 1998 Ian Lance Taylor - - * config.sub: Add tic30 cases, and map c30 to tic30. - -Sun Feb 1 02:40:41 1998 Richard Henderson - - * Makefile.in (TARGET_CONFIGDIRS): Add libf2c. - (ALL_TARGET_MODULES, CONFIGURE_TARGET_MODULES): Similarly - (CHECK_TARGET_MODULES, INSTALL_TARGET_MODULES): Similarly - (CLEAN_TARGET_MODULES): Similarly - (all-target-libf2c): Add dependences. - * configure.in (target_libs): Add libf2c. - -Fri Jan 30 17:18:32 1998 Geoffrey Noer - - * configure.in: Remove expect from noconfigdirs when target - is cygwin32. OK to build expect and dejagnu with Canadian - Cross. - -Wed Jan 28 12:58:49 1998 Ian Lance Taylor - - * configure.in: Do build expect, dejagnu, and cvssrc for a cygwin32 - host. - - * config.guess: Use ${UNAME_MACHINE} rather than i386 for cygwin32 - and mingw32. - -Wed Jan 28 10:26:37 1998 Manfred Hollstein - - * Makefile.in (BASE_FLAGS_TO_PASS): Remove passing $(local_prefix) - here as it is not defined in the toplevel Makefile. - -Tue Jan 27 23:25:06 1998 Manfred Hollstein - - * configure (package_makefile_rules_frag): New variable, which names - a file with generic rules, ... - Change comment to mention we now have FIVE parts. - * configure: Undo last change. - -Tue Jan 27 23:15:55 1998 Lassi A. Tuura - - * config.guess: More accurate determination of HP processor types. - * config.sub: More accurate determination of HP processor types. - -Sat Jan 24 01:59:45 1998 Manfred Hollstein - - * configure (package_makefile_frag): Move inserting the - ${package_makefile_frag} to where it should be according - to the comment. - -Fri Jan 23 00:29:28 1998 Philip Blundell - - * config.guess: Add support for Linux/ARM. - -Thu Jan 22 15:14:01 1998 Fred Fish - - * .cvsignore: Remove *-info and *-install since they match - release-info and mpw-install, which we don't want to just ignore. - -Thu Jan 22 01:38:33 1998 Richard Henderson - - * configure.in: Revert 3 Jan change for alpha-linux-gnulibc1. - -Sat Jan 17 21:28:08 1998 Pieter Nagel - - * Makefile.in (FLAGS_TO_PASS): Pass down gcc_include_dir and - local_prefix to sub-make invocations. - -Sat Jan 17 21:04:59 1998 H.J. Lu (hjl@gnu.org) - - * configure.in: Check makefile fragments in the source - directory. - -Fri Jan 16 00:41:37 1998 Alexandre Oliva - - * configure.in: Check whether host and target makefile - fragments exist before adding them to *_makefile_frag. - -Wed Jan 14 23:39:10 1998 Bob Manson - - * configure.in (target_configdirs): Add cygmon for sparc64-elf. - -Wed Jan 14 12:48:07 1998 Keith Seitz - - * configure.in: Make sure we only replace RPATH_ENVVAR on - lines which begin with RPATH_ENVVAR, i.e. add "^" to the - regexp to sed. - - * Makefile.in (BASE_FLAGS_TO_PASS): Pass RRPATH_ENVVAR down - to sub-makes. - -1998-01-13 Lee Iverson (leei@ai.sri.com) - - * config-ml.in (multi-do): LDFLAGS must include multilib - designator. - -Tue Jan 13 01:13:24 1998 Robert Lipe (robertl@dgii.com) - - * config.guess: Recognize i[3456]-i586-UnixWare7-sysv5. - -Sun Jan 4 01:06:55 1998 Mumit Khan - - * config.sub: Add mingw32 support. - * configure.in: Likewise. - * config/mh-mingw32: New file. - -Sat Jan 3 12:11:05 1998 Franz Sirl - - * configure.in: Finalize support for {alpha|powerpc}*-*-linux-gnulibc1 - -Sun Dec 28 11:28:58 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (INSTALL_TARGET): Do install-gcc first. - * configure (gxx_include_dir): Provide a definition for subdirs - which do not use autoconf. - -Wed Dec 24 22:46:55 1997 Jeffrey A Law (law@cygnus.com) - - * config.guess: Sync with egcs. Picks up new alpha support, - BeOS & some additional linux support. - -Tue Dec 23 12:44:24 1997 Jeffrey A Law (law@cygnus.com) - - * config.guess: HP 9000/803 is a PA1.1 machine. - -Mon Dec 22 02:39:24 1997 Richard Henderson - - * configure.in: It's alpha*-... - -Sun Dec 21 16:53:12 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * configure.in (host_makefile_frag, target_makefile_frag): - Handle multiple config files. - (alpha-*-linux*): Treat alpha-*-linux* as alpha-*-linux* and - alpha-*-*. - -Thu Dec 18 13:13:03 1997 Doug Evans - - * mkdep: New file. - -Wed Dec 17 09:53:02 1997 Michael Meissner - - * configure.in (d30v-*-*): Allow configuring of libide, vmake, etc. - -Tue Dec 16 17:36:05 1997 Ian Lance Taylor - - * Makefile.in: Add libgui directory. - (GDB_TK): Add all-libgui. - * configure.in: Add libgui directory. - * configure: Add all-libgui to GDB_TK. - -Mon Dec 15 16:12:28 1997 Nick Clifton - - * config-ml.in (multidirs): Add m32r to multilib list. - -Fri Dec 12 10:43:31 1997 Brendan Kehoe - - * Makefile.in (all-target-gperf): Change dependency to - all-target-libstdc++. - -Thu Dec 11 23:30:51 1997 Fred Fish - - * config.guess: Add BeOS support. - -Wed Dec 10 15:10:38 1997 Ian Lance Taylor - - Source directory cvs renamed to cvssrc: - * configure.in (host_tools): Change cvs to cvssrc. - (native_only): Likewise. - (noconfigdirs) [various cases]: Likewise. - * Makefile.in (ALL_MODULES): Change all-cvs to all-cvssrc. - (CROSS_CHECK_MODULES): Change check-cvs to check-cvssrc. - (INSTALL_MODULES): Change install-cvs to install-cvssrc. - (CLEAN_MODULES): Change clean-cvs to clean-cvssrc. - (all-cvssrc): Rename target from all-cvs. - -Wed Dec 3 07:55:59 1997 Jeffrey A Law (law@cygnus.com) - - * configure (gxx_include_dir): Fix thinko. - -Tue Dec 2 10:55:34 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (INSTALL_TARGET_CROSS): Define. - (install-cross, install-gcc-cross): New targets. - -Tue Dec 2 10:08:31 1997 Nick Clifton - - * configure.in (noconfigdirs): Add support for Thumb target. - - * config.sub (maybe_os): Add support for Thumb target. - -Sun Nov 30 16:12:27 1997 Bob Manson - - * Makefile.in: Add rules for cygmon. - - * configure.in: Build cygmon for sparc-elf and sparclite-aout. - -Thu Nov 27 01:31:30 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (INSTALL_TARGET): Do install-gcc first. - * configure (gxx_include_dir): Provide a definition for subdirs - which do not use autoconf. - -Wed Nov 26 11:53:33 1997 Keith Seitz - - * Makefile.in, configure, configure.in, ChangeLog: merge with foundry's - 11/18/97 build - -Wed Nov 26 16:08:50 1997 Jeffrey A Law (law@cygnus.com) - - * From Franz Sirl. - * config.guess (powerpc*-*-linux): Handle glibc2 beta release - found on RedHat Linux systems. - -Fri Nov 21 09:51:01 1997 Jeffrey A Law (law@cygnus.com) - - * config.guess (alpha stuff): Merge with FSF to avoid incorrect - guesses. - -Thu Nov 13 11:38:37 1997 Jeffrey A Law (law@cygnus.com) - - * configure.in (i[3456]86-ncr-sysv4.3*): Tweak. - -Mon Nov 10 15:23:21 1997 H.J. Lu - - * ltmain.sh: If mkdir fails, check whether the directory was created - anyhow by some other process. - -Mon Nov 10 14:38:03 1997 Michael Meissner - - * configure.in (d30v-*-*): Configure all directories. - -Sun Nov 9 17:36:20 1997 Michael Meissner - - * configure.in (d30v-*-*): Configure newlib, libiberty directories - for the D30V. - -Sat Nov 8 14:42:59 1997 Michael Meissner - - * configure.in (d30v-*-*): Configure target-libgloss on the D30V. - -Fri Nov 7 10:34:09 1997 Rob Savoye - - * include/libiberty.h: Add extern "C" { so it can be used with C++ - progrms. - * include/remote-sim.h: Add extern "C" { so it can be used with C++ - programs. - -Thu Oct 30 11:09:29 1997 Michael Meissner - - * configure.in (d30v-*-*): Configure GCC now. - -Mon Oct 27 13:17:24 1997 Stan Shebs - - * configure.in: Remove a "second pass" of tweaking noconfigdirs, - is no longer needed. - -Mon Oct 27 12:03:53 1997 Jason Merrill - - * Makefile.in: check-target-libio depends on all-target-libstdc++. - -Sun Oct 26 11:48:27 1997 Manfred Hollstein (manfred@s-direktnet.de) - - * Makefile.in (bootstrap-lean): Combined with `normal' bootstrap - targets using "$@" to provide support for similar but not identical - targets without having to duplicate code. - -Mon Oct 20 15:28:49 1997 Klaus K"ampf - - * makefile.vms: Fix to work with DEC C. - -Tue Oct 7 23:58:57 1997 Gavin Koch - - * config.sub: Add mips-tx39-elf to marketing names. - -Tue Oct 7 14:24:41 1997 Ian Lance Taylor - - * ltmain.sh: Handle symlinks in generated script. - -Wed Oct 1 13:11:27 1997 Ian Lance Taylor - - * configure: Handle autoconf style directory options: --bindir, - --datadir, --includedir, --infodir, --libdir, --libexecdir, - --mandir, --oldincludedir, --sbindir, --sharedstatedir, - --sysconfdir. - * Makefile.in (sbindir, libexecdir, sysconfdir): New variables. - (sharedstatedir, localstatedir, oldincludedir): New variables. - (BASE_FLAGS_TO_PASS): Pass down bindir, datadir, includedir, - infodir, libdir, libexecdir, localstatedir, mandir, oldincludedir, - sbindir, sharedstatedir, and sysconfdir. - -Mon Sep 29 00:38:08 1997 Aaron Jackson - - * Makefile.in (bootstrap-lean): New target. - -Wed Sep 24 18:06:27 1997 Stu Grossman - - * configure.in (d30v): Remove tcl, tk, expect, gdb, itcl, tix, db, - sn, and gnuserv from noconfigdirs. - -Wed Sep 24 15:18:32 1997 Ian Lance Taylor - - * ltmain.sh: Tweak shell pattern to avoid bug in NetBSD /bin/sh. - -Thu Sep 18 23:58:27 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (cross): New target. - -Thu Sep 18 21:43:23 1997 Alexandre Oliva - Jeff Law - - * Makefile.in (bootstrap2, bootstrap3): New targets. - (all-bootstrap): Remove outdated and confusing target. - (bootstrap, bootstrap2, bootstrap3): Don't pass BOOT_CFLAGS down. - -Thu Sep 18 15:37:42 1997 Andrew Cagney - - * configure (tooldir): enable_gdbtk=YES for cygwin32, NO for - windows. Consistent with gdb/configure. - -1997-09-15 02:37 Ulrich Drepper - - * config/mt-linux: Define CXXFLAGS to make sure -fvtable-thunks is - used. - * configure.in: Name Linux target fragment. - - * configure: Rewrite so that project Makefile fragment is inserted - first and appears last in the resulting Makefile. - -Tue Sep 16 09:55:07 1997 Andrew Cagney - - * Makefile.in (install-itcl): Install tcl first. - -Sun Sep 14 20:53:42 1997 Geoffrey Noer - - * config/mh-cygwin32: ok to build split texinfo files - -Fri Sep 12 16:19:20 1997 Geoffrey Noer - - * configure.in: remove bison from noconfigdirs for Cygwin32 host - -Thu Sep 11 16:40:46 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * Makefile.in (local-distclean): Also remove mh-frag mt-frag. - - * configure.in (skipdirs): Add target-librx for Linux. - (alpha-*-linux*): Use config/mh-elfalphapic and config/mt-elfalphapic. - -Wed Sep 10 21:29:54 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (bootstrap): New target. - -Wed Sep 10 15:19:22 1997 Jeffrey A Law (law@cygnus.com) - - * config.sub: Accept 'amigados' for backward compatability. - -Mon Sep 8 20:46:20 1997 Ian Lance Taylor - - * config.guess: Merge with FSF. - -Sun Sep 7 23:18:32 1997 Fred Fish - - * config.sub: Change 'amigados' to 'amigaos' to match current usage. - -Sun Sep 7 15:55:28 1997 Gavin Koch - - * config.sub: Add "marketing-names" patch. - -Fri Sep 5 16:11:28 1997 Joel Sherrill (joel@OARcorp.com) - - * configure.in (*-*-rtems*): Do not build libgloss for rtems. - -Fri Sep 5 12:27:17 1997 Jeffrey A Law (law@cygnus.com) - - * config.sub: Handle v850-elf. - -Wed Sep 3 22:01:58 1997 Fred Fish - - * .cvsignore (*-install): Remove. - -Wed Sep 3 12:15:24 1997 Chris Provenzano - - * ltconfig: Set CONFIG_SHELL in libtool. - * ltmain.sh: Use CONFIG_SHELL instead of /bin/sh - -Mon Sep 1 16:45:44 1997 Jim Wilson - - * configure.in (target_subdir): Set to libraries if enable_multilib. - -Wed Aug 27 16:15:11 1997 Jim Wilson - - * config.guess: Update from gcc directory. - -Tue Aug 26 16:46:46 1997 Andrew Cagney - - * Makefile.in (all-sim): Depends on all-readline. - -Wed Aug 20 19:57:37 1997 Jason Merrill - - * Makefile.in (BISON, YACC): Use $$s. - (all-bison): Depend on all-texinfo. - -Tue Aug 19 01:41:32 1997 Jason Merrill - - * Makefile.in (BISON): Add -L flag. - (YACC): Likewise. - -Mon Aug 18 11:30:50 1997 Nick Clifton - - * configure.in (noconfigdirs): Add support for v850e target. - - * config.sub (maybe_os): Add support for v850e target. - -Mon Aug 18 11:30:50 1997 Nick Clifton - - * configure.in (noconfigdirs): Add support for v850ea target. - - * config.sub (maybe_os): Add support for v850ea target. - -Mon Aug 18 09:24:06 1997 Gavin Koch - - * config.sub: Add mipstx39. Delete r3900. - -Mon Aug 18 17:20:10 1997 Jason Molenda (crash@godzilla.cygnus.co.jp) - - * Makefile.in (all-autoconf): Depends on all-texinfo. - -Fri Aug 15 23:09:26 1997 Michael Meissner - - * config-ml.in ({powerpc,rs6000}*-*-*): Update to current AIX and - eabi targets. - -Thu Aug 14 14:42:17 1997 Ian Lance Taylor - - * configure: Get CFLAGS and CXXFLAGS from Makefile, if possible. - - * configure: When handling a Canadian Cross, handle YACC as well as - BISON. Just set BISON to bison. When setting YACC, prefer bison. - * Makefile.in (all-bison): Depend upon all-texinfo. - -Tue Aug 12 20:09:48 1997 Jason Merrill - - * Makefile.in (BISON): bison, not byacc or bison -y. - (YACC): bison -y or byacc or yacc. - (various): Add *-bison as appropriate. - (taz): No need to mess with BISON anymore. - -Tue Aug 12 22:33:08 1997 Ian Lance Taylor - - * configure: If OSTYPE matches *win32*, try to find a good value for - CONFIG_SHELL. - -Sun Aug 10 14:41:11 1997 Ian Lance Taylor - - * Makefile.in (taz): Get the version number from AM_INIT_AUTOMAKE in - configure.in if it is present. - -Sat Aug 9 00:58:01 1997 Ian Lance Taylor - - * Makefile.in (LD_FOR_TARGET): Change ld.new to ld-new. - -Fri Aug 8 16:30:13 1997 Doug Evans - - * config.sub: Recognize `arc' cpu. - * configure.in: Likewise. - * config-ml.in: Likewise. - -Thu Aug 7 11:02:34 1997 Ian Lance Taylor - - * Makefile.in ($(INSTALL_X11_MODULES)): Depend upon installdirs. - -Wed Aug 6 16:27:29 1997 Chris Provenzano - - * configure: Changed sed delimiter from ':' to '|' when - attempting to substitute ${config_shell} for SHELL. On - NT ${config_shell} may contain a ':' in it. - -Wed Aug 6 12:29:05 1997 Jason Merrill - - * Makefile.in (EXTRA_GCC_FLAGS): Fix for non-bash shells. - -Wed Aug 6 00:42:35 1997 Ian Lance Taylor - - * Makefile.in (AS_FOR_TARGET): Change as.new to as-new. - -Tue Aug 5 14:08:51 1997 Ian Lance Taylor - - * Makefile.in (NM_FOR_TARGET): Change nm.new to nm-new. - - * ylwrap: If the program is a relative path, force it to be - absolute. - -Tue Aug 5 12:12:44 1997 Andrew Cagney - - * configure (tooldir): Set BISON to `bison -y' and not just bison. - -Mon Aug 4 22:59:02 1997 Andrew Cagney - - * Makefile.in (CC_FOR_TARGET): When winsup/Makefile present, - correctly specify the target build directory $(TARGET_SUBDIR)/winsup - for libraries. - -Mon Aug 4 12:40:24 1997 Jason Merrill - - * Makefile.in (EXTRA_GCC_FLAGS): Fix handling of macros with values - separated by spaces. - -Thu Jul 31 19:49:49 1997 Ian Lance Taylor - - * ylwrap: New file. - * Makefile.in (DEVO_SUPPORT): Add ylwrap. - - * ltmain.sh: Handle /bin/sh at start of install program. - - * Makefile.in (DEVO_SUPPORT): Add ltconfig, ltmain.sh, and missing. - - * ltconfig, ltmain.sh: New files, from libtool 1.0. - * missing: New file, from automake 1.2. - -Thu Jul 24 12:57:56 1997 Ian Lance Taylor - - * Makefile.in: Treat tix like tk, putting it in X11_MODULES. Add - check-tk to CHECK_X11_MODULES. - -Wed Jul 23 17:03:29 1997 Ian Lance Taylor - - * config.sub: Merge with FSF. - -Tue Jul 22 19:08:29 1997 Ian Lance Taylor - - * config.guess: Merge with FSF. - -Tue Jul 22 14:50:42 1997 Robert Hoehne - - * configure: Treat msdosdjgpp like go32. - * configure.in: Likewise. Don't remove gprof for go32. - - * configure: Change Makefile.tem2 to Makefile.tm2. - -Mon Jul 21 10:31:26 1997 Stephen Peters - - * configure.in (noconfigdirs): For alpha-dec-osf*, don't ignore grep. - -Tue Jul 15 14:33:03 1997 Brendan Kehoe - - * install-sh (chmodcmd): Set to null if the DST directory already - exists. Same as Nov 11th change. - -Mon Jul 14 11:01:15 1997 Martin M. Hunt - - * configure (GDB_TK): Needs itcl and tix. - -Mon Jul 14 00:32:10 1997 Jason Merrill - - * config.guess: Update from FSF. - -Fri Jul 11 11:57:11 1997 Martin M. Hunt - - * Makefile.in (GDB_TK): Depend on itcl and tix. - -Fri Jul 4 13:25:31 1997 Ian Lance Taylor - - * Makefile.in (INSTALL_PROGRAM_ARGS): New variable. - (INSTALL_PROGRAM): Use $(INSTALL_PROGRAM_ARGS). - (INSTALL_SCRIPT): New variable. - (BASE_FLAGS_TO_PASS): Pass down INSTALL_SCRIPT. - * configure.in: If host is *-*-cygwin32*, set INSTALL_PROGRAM_ARGS - to -x. - * install-sh: Add support for -x option. - -Mon Jun 30 15:51:30 1997 Ian Lance Taylor - - * configure.in, Makefile.in: Treat tix like itcl. - -Thu Jun 26 13:59:19 1997 Ian Lance Taylor - - * Makefile.in (WINDRES): New variable. - (WINDRES_FOR_TARGET): New variable. - (BASE_FLAGS_TO_PASS): Add WINDRES_FOR_TARGET. - (EXTRA_HOST_FLAGS): Add WINDRES. - (EXTRA_TARGET_FLAGS): Add WINDRES. - (EXTRA_GCC_FLAGS): Add WINDRES. - ($(DO_X)): Pass down WINDRES. - ($(CONFIGURE_TARGET_MODULES)): Set WINDRES when configuring. - * configure: Treat WINDRES like DLLTOOL, and WINDRES_FOR_TARGET like - DLLTOOL_FOR_TARGET. - -Wed Jun 25 15:01:26 1997 Felix Lee - - * configure.in: configure sim before gdb for win32-x-ppc - -Wed Jun 25 12:18:54 1997 Brendan Kehoe - - Move gperf into the toplevel, from libg++. - * configure.in (target_tools): Add target-gperf. - (native_only): Add target-gperf. - * Makefile.in (all-target-gperf): New target, depend on - all-target-libg++. - (configure-target-gperf): Empty rule. - (ALL_TARGET_MODULES): Add all-target-gperf. - (CONFIGURE_TARGET_MODULES): Add configure-target-gperf. - (CHECK_TARGET_MODULES): Add check-target-gperf. - (INSTALL_TARGET_MODULES): Add install-target-gperf. - (CLEAN_TARGET_MODULES): Add clean-target-gperf. - -Mon Jun 23 10:51:53 1997 Jeffrey A Law (law@cygnus.com) - - * config.sub (mn10200): Recognize new basic machine. - -Thu Jun 19 14:16:42 1997 Brendan Kehoe - - * configure.in: Don't set ENABLE_MULTILIB, so we'll be passing - --enable-multilib down to subdirs; setting TARGET_SUBDIR was enough. - -Tue Jun 17 15:31:20 1997 Brendan Kehoe - - * configure.in: If we're building mips-sgi-irix6* native, turn on - ENABLE_MULTILIB and set TARGET_SUBDIR. - -Tue Jun 17 12:20:59 1997 Tom Tromey - - * Makefile.in (all-sn): Depend on all-grep. - -Mon Jun 16 11:11:10 1997 Ian Lance Taylor - - * configure.in: Use mh-ppcpic and mt-ppcpic for powerpc*-* targets. - - * configure: Set CFLAGS and CXXFLAGS, and substitute them into - Makefile. From Jeff Makey . - * Makefile.in: Add comment for CFLAGS and CXXFLAGS. - - * Makefile.in (DISTBISONFILES): Remove. - (taz): Don't futz with DISTBISONFILES. Change BISON to use - $(DEFAULT_YACC). - - * configure.in: Build itl, db, sn, etc., when building for native - cygwin32. - - * Makefile.in (LD): New variable. - (EXTRA_HOST_FLAGS): Pass down LD. - ($(DO_X)): Likewise. - -Mon Jun 16 11:10:35 1997 Philip Blundell - - * Makefile.in (INSTALL): Use $(SHELL) when executing install-sh. - -Fri Jun 13 10:22:56 1997 Bob Manson - - * configure.in (targargs): Strip out any supplied --build argument - before adding our own. Always add --build. - -Thu Jun 12 21:12:28 1997 Bob Manson - - * configure.in (targargs): Pass --build if we're doing - a cross-compile. - -Fri Jun 6 21:38:40 1997 Rob Savoye - - * configure: Use '|' instead of ":" as the separator in - sed. Otherwise sed chokes on NT path names with drive - designators. Also look for "?:*" as the leading characters in an - absolute pathname. - -Mon Jun 2 13:05:20 1997 Gavin Koch - - * config.sub: Support for r3900. - -Wed May 21 17:33:31 1997 Ian Lance Taylor - - * configure.in: Use install-sh, not install.sh. - -Wed May 14 16:06:51 1997 Ian Lance Taylor - - * Makefile.in (taz): Improve check for BISON so it doesn't try to - apply it twice. - -Fri May 9 17:22:05 1997 Ian Lance Taylor - - * Makefile.in (INSTALL_MODULES): Put install-opcodes before - install-binutils. - -Thu May 8 17:29:50 1997 Ian Lance Taylor - - * Makefile.in: Add automake targets. - * configure.in (host_tools): Add automake. - -Tue May 6 15:49:52 1997 Ian Lance Taylor - - * configure: Default CXX to c++, not gcc. - * Makefile.in (CXX): Set to c++, not gcc. - (CXX_FOR_TARGET): When cross, transform c++, not gcc. - -Thu May 1 10:11:43 1997 Geoffrey Noer - - * install-sh: try appending a .exe if source file doesn't - exist - -Wed Apr 30 12:05:36 1997 Jason Merrill - - * configure.in: Turn on multilib by default. - (cross_only): Remove target-libiberty. - - * Makefile.in (all-gcc): Don't depend on libiberty. - -Mon Apr 28 18:39:45 1997 Michael Snyder - - * config.guess: improve algorithm for recognizing Gnu Hurd x86. - -Thu Apr 24 19:30:07 1997 Ian Lance Taylor - - * Makefile.in (DEVO_SUPPORT): Add mpw-install. - (DISTBISONFILES): Add ld/Makefile.in - -Tue Apr 22 17:17:28 1997 Geoffrey Noer - - * configure.in: if target is cygwin32 but host isn't cygwin32, - don't configure gdb tcl tk expect, not just gdb. - -Mon Apr 21 13:33:39 1997 Tom Tromey - - * configure.in: Added gnuserv everywhere sn appears. - - * Makefile.in (ALL_MODULES): Added all-gnuserv. - (CROSS_CHECK_MODULES): Added check-gnuserv. - (INSTALL_MODULES): Added install-gnuserv. - (CLEAN_MODULES): Added clean-gnuserv. - (all-gnuserv): New target. - -Thu Apr 17 13:57:06 1997 Per Fogelstrom - - * config.guess: Fixes for MIPS OpenBSD systems. - -Tue Apr 15 12:21:07 1997 Ian Lance Taylor - - * Makefile.in (INSTALL_XFORM): Remove. - (BASE_FLAGS_TO_PASS): Remove INSTALL_XFORM. - - * mkinstalldirs: New file, copied from automake. - * Makefile.in (installdirs): Rename from install-dirs. Use - mkinstalldirs. Change all users. - (DEVO_SUPPORT): Add mkinstalldirs. - -Mon Apr 14 11:21:38 1997 Ian Lance Taylor - - * install-sh: Rename from install.sh. - * Makefile.in (INSTALL): Change install.sh to install-sh. - (DEVO_SUPPORT): Likewise. - - * configure: Use ${config_shell} with ${moveifchange}. From Thomas - Graichen . - -Fri Apr 11 16:37:10 1997 Niklas Hallqvist - - * config.guess: Recognize OpenBSD systems correctly. - -Fri Apr 11 17:07:04 1997 Jason Molenda (crash@godzilla.cygnus.co.jp) - - * README, Makefile.in (ETC_SUPPORT): Remove references to - cfg-paper*, configure.{texi,man,info*}._ - -Sun Apr 6 18:47:57 1997 Andrew Cagney - - * Makefile.in (all.normal): Ensure that gcc is built after all - the x11 - ie gdb - targets. - -Tue Apr 1 16:28:50 1997 Klaus Kaempf - - * makefile.vms: Don't run conf-a-gas. - -Mon Mar 31 16:26:55 1997 Joel Sherrill - - * configure.in (hppa1.1-*-rtems*): New target, like hppa-*-*elf*. - -Sun Mar 30 12:38:27 1997 Fred Fish - - * configure.in: Remove noconfigdirs case since gdb also - configures and builds for tic80-coff. - -Fri Mar 28 18:28:52 1997 Ian Lance Taylor - - * configure: Set cache_file to config.cache. - * Makefile.in (local-distclean): Remove config.cache. - -Wed Mar 26 18:49:39 1997 Ian Lance Taylor - - * COPYING: Update FSF address. - -Wed Mar 26 10:38:25 1997 Michael Meissner - - * configure.in (tic80-*-*): Remove G++ libraries and libgloss from - noconfigdirs. - -Mon Mar 24 15:02:39 1997 Ian Lance Taylor - - * Makefile.in (install-dirs): Don't crash if prefix, and hence - MAKEDIRS, is empty. - -Mon Mar 24 12:40:55 1997 Doug Evans - - * config.sub: Tweak mn10300 entry. - -Fri Mar 21 15:35:27 1997 Michael Meissner - - * configure.in (host_tools): Put sim before gdb, so gdb's - configure.tgt can determine if the simulator was configured. - -Sun Mar 16 16:07:08 1997 Fred Fish - - * config.sub: Move BeOS $os case to be with other Cygnus - local cases. - -Sun Mar 16 01:34:55 1997 Martin Hunt - - * config.sub: Remove misplaced comment that broke Linux. - -Sat Mar 15 22:50:15 1997 Fred Fish - - * config.sub: Add BeOS support. - -Mon Mar 10 13:30:11 1997 Tom Tromey - - * Makefile.in (CHECK_X11_MODULES): Don't run check-tk. - -Wed Mar 5 12:09:29 1997 Martin - - * configure.in (noconfigdirs): Remove tcl and tk from - noconfigdirs for cygwin32 builds. - -Fri Feb 28 18:20:15 1997 Fred Fish - - * configure.in (tic80-*-*): Remove ld from noconfigdirs. - -Thu Feb 27 14:57:26 1997 Ken Raeburn - - * Makefile.in (GAS_SUPPORT_DIRS, BINUTILS_SUPPORT_DIRS): Remove - make-all.com, use makefile.vms instead. - -Tue Feb 25 18:46:14 1997 Stan Shebs - - * config.sub: Accept -lnews*. - -Tue Feb 25 13:19:14 1997 Andrew Cagney - - * configure.in (noconfigdirs): Disable target-newlib, - target-examples and target-libiberty for d30v. - -Fri Feb 21 17:56:25 1997 Martin M. Hunt - - * configure.in (noconfigdirs): Enable ld for d30v. - -Fri Feb 21 20:58:51 1997 Michael Meissner - - * configure.in (tic80-*-*): Build compiler. - -Sun Feb 16 15:41:09 1997 Andrew Cagney - - * configure.in (d30v-*): Remove sim directory from list of - unsupported d30v directories - -Tue Feb 18 17:32:42 1997 Martin M. Hunt - - * config.sub, configure.in: Add d30v target cpu. - -Thu Feb 13 22:04:44 1997 Klaus Kaempf - - * makefile.vms: New file. - * make-all.com: Remove. - -Wed Feb 12 12:54:18 1997 Jim Wilson - - * Makefile.in (EXTRA_GCC_FLAGS): Add LIBGCC2_DEBUG_CFLAGS. - -Sat Feb 8 20:36:49 1997 Michael Meissner - - * Makefile.in (all-itcl): The rule is all-itcl, not all-tcl. - -Tue Feb 4 11:39:29 1997 Tom Tromey - - * Makefile.in (ALL_MODULES): Added all-db. - (CROSS_CHECK_MODULES): Addec check-db. - (INSTALL_MODULES): Added install-db. - (CLEAN_MODULES): Added clean-db. - -Mon Feb 3 13:29:36 1997 Ian Lance Taylor - - * config.guess: Merge with latest FSF sources. - -Tue Jan 28 09:20:37 1997 Tom Tromey - - * Makefile.in (ALL_MODULES): Added all-itcl. - (CROSS_CHECK_MODULES): Added check-itcl. - (INSTALL_MODULES): Added install-itcl. - (CLEAN_MODULES): Added clean-itcl. - -Thu Jan 23 01:44:27 1997 Geoffrey Noer - - * configure.in: build gdb for mn10200 - -Fri Jan 17 15:32:15 1997 Doug Evans - - * Makefile.in (all-target-winsup): Depend on all-target-libio. - -Mon Jan 13 22:46:54 1997 Michael Meissner - - * configure.in (tic80-*-*): Turn off most targets right now. - -Fri Jan 3 16:04:03 1997 Ian Lance Taylor - - * Makefile.in (MAKEINFO): Check for the existence of the Makefile, - rather than the makeinfo program. - (do-info): Depend upon all-texinfo. - -Tue Dec 31 16:00:31 1996 Ian Lance Taylor - - * configure.in: Remove uses of config/mh-linux. - - * config.sub, config.guess: Merge with latest FSF sources. - -Fri Dec 27 23:04:33 1996 Fred Fish - - * config.sub (case $basic_machine): Add tic80 entries. - -Fri Dec 27 12:07:59 1996 Ian Lance Taylor - - * config.sub, config.guess: Merge with latest FSF sources. - -Wed Dec 18 22:46:39 1996 Stan Shebs - - * mpw-build.in: Build ld before gcc, use NewFolderRecursive. - * mpw-config.in: Test for NewFolderRecursive. - * mpw-install: Use symbolic name for startup filename. - * mpw-README: Add various additional details. - -Wed Dec 18 13:11:46 1996 Jim Wilson - - * configure.in (mips*-sgi-irix6*): Remove binutils from noconfigdirs. - -Wed Dec 18 10:29:31 1996 Jeffrey A Law (law@cygnus.com) - - * configure.in: Do build gcc and the target libraries for - the mn10200. - -Wed Dec 4 16:53:05 1996 Geoffrey Noer - - * configure.in: don't avoid building gdb for mn10300 any more - * Makefile.in: double-quote GCC_FOR_TARGET line in EXTRA_GCC_FLAGS - instead of single-quoting it. - -Tue Dec 3 23:26:50 1996 Jason Merrill - - * configure.in: Don't use --with-stabs on IRIX 6. - -Tue Dec 3 09:05:25 1996 Doug Evans - - * configure.in (m32r): Build gdb, libg++ now. - -Sun Dec 1 00:18:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * configure.in (mips*-sgi-irix6*): Remove gdb and related - directories from noconfigdirs. - -Tue Nov 26 11:45:33 1996 Kim Knuttila - - * config.sub (basic_machine): added mips16 configuration - -Sat Nov 23 19:26:22 1996 Michael Meissner - - * config.sub: Handle d10v-unknown. - -Sat Nov 23 10:23:01 1996 Gavin Koch - - * config.sub: Handle v850-unknown. - -Thu Nov 21 16:19:44 1996 Geoffrey Noer - - * Makefile.in: add findutils - * configure.in: add findutils to list of host_tools - -Wed Nov 20 10:09:01 1996 Jeffrey A Law (law@cygnus.com) - - * config.sub: Handle mn10200 and mn10300. - -Tue Nov 19 16:35:14 1996 Michael Meissner - - * configure.in (d10v-*): Do not build librx. - -Mon Nov 18 13:28:41 1996 Jeffrey A Law (law@cygnus.com) - - * configure.in (mn10300): Build everything except gdb & libgloss. - -Wed Nov 13 14:59:46 1996 Per Bothner - - * config.guess: Patch for Dansk Data Elektronik servers, - from Niels Skou Olsen . - - For ncr, use /bin/uname rather than uname, since GNU uname does not - support -p. Suggested by Mark Mitchell . - - Patch for MIPS R4000 running System V, - from Eric S. Raymond . - - Fix thinko for nextstep. - - Patch for OSF1 in i?86, from Dan Murphy via Harlan Stenn. - - Sat Jun 24 18:58:17 1995 Morten Welinder - * config.guess: Guess mips-dec-mach_bsd4.3. - - Thu Oct 10 04:07:04 1996 Harlan Stenn - * config.guess (i?86-ncr-sysv*): Emit just enough of the minor - release numbers. - * config.guess (mips-mips-riscos*): Emit just enough of the - release number. - - Tue Oct 8 10:37:22 1996 Frank Vance - * config.guess (sparc-auspex-sunos*): Added. - (f300-fujitsu-*): Added. - - Wed Sep 25 22:00:35 1996 Jeff Woolsey - * config.guess: Recognize a Tadpole as a sparc. - -Wed Nov 13 00:53:09 1996 David J. MacKenzie - - * config.guess: Don't assume that NextStep version is either 2 or - 3. NextStep 4 (aka OpenStep 4) has come out now. - -Mon Nov 11 23:52:03 1996 David J. MacKenzie - - * config.guess: Support Cray T90 that reports itself as "CRAY TS". - From Rik Faith . - -Fri Nov 8 11:34:58 1996 David J. MacKenzie - - * config.sub: Contributions from bug-gnu-utils to: - Support plain "hppa" (no version given) architecture, reported by - OpenStep. - OpenBSD like NetBSD. - LynxOs is not a hardware supplier. - - * config.guess: Contributions from bug-gnu-utils to add support for: - OpenBSD like NetBSD. - Stratus systems. - More Pyramid systems. - i[n>4]86 Intel chips. - M680[n>4]0 Motorola chips. - Use unknown instead of lynx for hardware manufacturer. - -Mon Nov 11 10:09:08 1996 Brendan Kehoe - - * install.sh (chmodcmd): Set to null if the DST directory already - exists. - -Mon Nov 11 10:43:41 1996 Michael Meissner - - * configure.in (powerpc*-{eabi,elf,linux,rtem,sysv,solaris}*): Do - not use mt-ppc target Makefile fragment any more. - -Sun Nov 3 19:17:07 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure.in (*-*-windows): Exclude everything but those dirs - needed to build windows. - -Tue Oct 29 16:41:31 1996 Doug Evans - - * Makefile.in (all-target-winsup): Depend on all-target-librx. - -Mon Oct 28 17:32:46 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure.in: Exclude mmalloc from i386-windows. - * config/mh-windows: Add rules for building MSVC makefiles. - -Thu Oct 24 09:22:46 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Undo my previous change. - -Thu Oct 24 12:12:04 1996 Ian Lance Taylor - - * Makefile.in (EXTRA_GCC_FLAGS): Pass down GCC_FOR_TARGET - unconditionally. - (MAKEOVERRIDES): Define (revert this part of October 18 change). - -Thu Oct 24 09:02:07 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (FLAGS_TO_PASS): Add $(HOST_FLAGS) to allow the - host to add it's own flags. - * config/mh-windows (HOST_FLAGS): Set srcroot, which is needed - for MSVC build procedure. - -Tue Oct 22 15:20:26 1996 Ian Lance Taylor - - * configure: Handle GCC_FOR_TARGET like CC_FOR_TARGET. - -Fri Oct 18 13:37:13 1996 Ian Lance Taylor - - * Makefile.in (CC_FOR_TARGET): Check for xgcc, not Makefile. - (CXX_FOR_TARGET): Likewise. - (GCC_FOR_TARGET): Define. - (BASE_FLAGS_TO_PASS): Remove GCC_FOR_TARGET. - (EXTRA_GCC_FLAGS): Define GCC_FOR_TARGET based on whether - CC_FOR_TARGET was specified on the command line. - (MAKEOVERRIDES): Don't define. - -Thu Oct 17 10:27:56 1996 Doug Evans - - * configure.in (m32r): Fix spelling of libg++ libs. - -Thu Oct 10 10:37:17 1996 Stan Shebs - - * config.sub (-apple*): Remove, now redundant. - -Thu Oct 10 12:30:54 1996 Ian Lance Taylor - - * configure: Don't get confused by CPU-VENDOR-linux-gnu. - - * configure: Rework yesterday's sed script patch. - - * config.sub: Merge with FSF. - -Wed Oct 9 17:24:59 1996 Per Bothner - - * config.guess: Merge from FSF. - - 1996-09-12 Richard Stallman - * config.guess: Use pc instead of unknown, for pc clone systems. - Change linux to linux-gnu. - - Mon Jul 15 23:51:11 1996 Karl Heuer - * config.guess: Avoid non-portable tr syntax. - -Wed Oct 9 06:06:46 1996 Jeffrey A Law (law@cygnus.com) - - * test-build.mk (HOLES): Add "xargs" for gdb. - - * configure: Avoid hpux10.20 sed bug. - -Tue Oct 8 08:32:48 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure.in config/mh-windows: Add support for windows host - (that is a build done under the Microsoft build environment). - -Tue Oct 8 10:39:08 1996 Ian Lance Taylor - - * Makefile.in: Replace all uses of srcroot with s, to shrink - command line lengths. - - Patches from Geoffrey Noer : - * configure.in: If configuring for newlib, pass --with-newlib to - subdirectories. - * Makefile.in (CC_FOR_TARGET): If winsup/Makefile exists, pass a - -Bnewlib/ and -Lwinsup to gcc. - (CXX_FOR_TARGET): Likewise. - -Mon Oct 7 10:59:35 1996 Ian Lance Taylor - - * Makefile.in (ETC_SUPPORT): Add configure. - -Fri Oct 4 12:22:58 1996 Angela Marie Thomas (angela@cygnus.com) - - * configure.in: Use config/mh-dgux386 for i[345]86-dg-dgux - host configuration file. - -Thu Oct 3 09:28:25 1996 Jeffrey A Law (law@cygnus.com) - - * configure.in: Break mn10x00 support into separate - mn10200 and mn10300 configurations. - * config.sub: Likewise. - -Wed Oct 2 22:27:52 1996 Jeffrey A Law (law@cygnus.com) - - * configure.in: Add lots of stuff to noconfigdirs for - the mn10x00 targets. - - * config.sub, configure.in: Add mn10x00 support. - -Wed Oct 2 15:52:36 1996 Klaus Kaempf - - * make-all.com: Call conf-a-gas, not config-a-gas. - -Tue Oct 1 01:28:41 1996 James G. Smith - - * configure.in (noconfigdirs): Don't build libgloss for arm-coff - targets. - -Mon Sep 30 14:24:01 1996 Stan Shebs - - * mpw-README: Add much more detail for native PowerMac. - * mpw-install: New file. - * mpw-configure: Add --norecursion and --help options. - * mpw-config.in: Translate readme and install files when - copying to objdir. - * mpw-build.in: Don't always depend on byacc and flex. - (install-only-top): New action. - -Fri Sep 27 17:39:44 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure.in: You can now configure GDB for the v850. - -Tue Sep 24 19:05:12 1996 Stan Shebs - - * configure.in (noconfigdirs): Don't configure any C++ dirs - if targeting D10V. - -Tue Sep 17 12:15:31 1996 Ian Lance Taylor - - * config.sub: Recognize mips64vr5000. - -Mon Sep 16 17:00:52 1996 Ian Lance Taylor - - * configure.in: Use a single line for host_tools and native_only. - -Tue Sep 16 09:55:07 1997 Andrew Cagney - - * Makefile.in (install-itcl): Install tcl first. - -Sun Sep 14 20:53:42 1997 Geoffrey Noer - - * config/mh-cygwin32: ok to build split texinfo files - -Fri Sep 12 16:19:20 1997 Geoffrey Noer - - * configure.in: remove bison from noconfigdirs for Cygwin32 host - -Mon Sep 9 12:21:30 1996 Doug Evans - - * config.sub, configure.in: Add entries for m32r. - -Mon Sep 8 20:46:20 1997 Ian Lance Taylor - - * config.guess: Merge with FSF. - -Thu Sep 5 13:52:47 1996 Tom Tromey - - * Makefile.in (inet-install): Don't run install-gzip. - -Wed Sep 4 17:26:13 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure.in: Don't config lots of things for *-*-windows*. - -Sat Aug 31 11:45:57 1996 Stan Shebs - - * mpw-config.in: Test for mpw-true, true, and null-command scripts. - (host_libs, host_tools): Copy from configure.in. - * mpw-configure: Don't complain about directories not found. - -Thu Aug 29 16:44:58 1996 Michael Meissner - - * configure.in (i[345]86): Recognize i686 for pentium pro. - (i[3456]86-*-dgux*): Use config/mh-sysv for the host configuration - file. - - * config.guess (i[345]86): Ditto. - -Mon Aug 26 18:34:42 1996 Martin M. Hunt - - * configure.in (noconfigdirs): Removed gdb for D10V. - -Thu Aug 22 17:13:52 1996 Jeffrey A Law (law@cygnus.com) - - * configure.in: Remove ld, target-libio, target-libg++, and - target-libstdc++ from noconfigdirs. - -Wed Aug 21 18:56:38 1996 Fred Fish - - * configure: Fix three locations where shell scripts were - being run directly rather than with config_shell. - -Tue Aug 20 13:08:47 1996 J.T. Conklin - - * configure.in (v850-*-*): Set up initial $noconfigdirs. - * config.sub (basic_machine): Recognize v850. - -Thu Aug 15 12:19:33 1996 Stan Shebs - - * mpw-configure: Handle multiple enable/disable options and - pass them down recursively, handle -c and -s flags appropriately - depending on choice of compiler, add escape mechanism for - quoted arguments to gC. - -Mon Aug 12 13:15:13 1996 Michael Meissner - - * configure.in (powerpc*-*-*): For eabi, system V.4, Linux, and - solaris targets, use config/mt-ppc to set C{,XX}FLAGS_FOR_TARGETS - so that -mrelocatable-lib and -mno-eabi are used. - - * Makefile.in (CONFIGURE_TARGET_MODULES): If target compiler does - not support --print-multi-lib, don't abort. - -Sun Aug 11 20:51:50 1996 Stu Grossman (grossman@critters.cygnus.com) - - * config/mh-cygwin32 (CFLAGS): Define _WIN32 to be compatible - with normal Windows compilation environment. - -Thu Aug 8 12:18:59 1996 Klaus Kaempf - - * make-all.com: Run config-a-gas. - * setup.com: Don't copy subdirectory files around. - -Tue Jul 30 17:49:31 1996 Brendan Kehoe - - * configure.in (*-*-ose): Remove exclusion of libgloss for this - target, it now compiles correctly. - -Sat Jul 27 15:10:43 1996 Stan Shebs - - * mpw-config.in: Generate Mac include for elf/dwarf2.h. - -Tue Jul 23 10:47:04 1996 Martin M. Hunt - - * configure.in (d10v-*-*): Remove ld from $noconfigdirs. - -Mon Jul 22 13:28:51 1996 Brendan Kehoe - - * configure.in (native_only): Add prms. - -Mon Jul 22 12:27:58 1996 Ian Lance Taylor - - * Makefile.in (GAS_SUPPORT_DIRS): Add make-all.com and setup.com. - (BINUTILS_SUPPORT_DIRS): Likewise. - -Thu Jul 18 12:55:40 1996 Michael Meissner - - * configure.in (d10v-*-*): Don't configure ld or gdb until the - d10v support is added. - -Wed Jul 17 14:33:09 1996 Martin M. Hunt - - * configure.in (d10v-*-*): New target. - -Mon Jul 15 11:53:00 1996 Jeffrey A Law (law@cygnus.com) - - * config.guess (HP 9000/811): Recognize this as a PA1.1 - machine. - -Fri Jul 12 23:21:17 1996 Ken Raeburn - - * Makefile.in (do-tar-gz): New target, split out from tail end of - taz target. Run each command separately, don't use pipes. - (taz): Use it. - -Fri Jul 12 12:08:04 1996 Stan Shebs - - * mpw-configure: Look for g-mpw-make.sed in config/mpw. - * mpw-build.in: No builds should depend on building byacc or flex, - they are assumed to be installed already. - -Fri Jul 12 09:52:52 1996 Michael Meissner - - * Makefile.in (CONFIGURE_TARGET_MODULES): Set r environment - variable that CC_FOR_TARGET needs. - -Thu Jul 11 10:09:45 1996 Michael Meissner - - * Makefile.in (CONFIGURE_TARGET_MODULES): Determine if the multlib - options have changed since the last time the subdirectory was - configured, and if it has, reconfigure. - (CLEAN_TARGET_MODULES): Delete multilib.out and tmpmulti.out, which - CONFIGURE_TARGET_MODULES uses to remember the old multilib options. - -Wed Jul 10 18:56:59 1996 Doug Evans - - * Makefile.in (ALL_MODULES,CROSS_CHECK_MODULES,INSTALL_MODULES, - CLEAN_MODULES): Add bash. - (all-bash): New target. - -Mon Jul 8 17:33:14 1996 Jim Wilson - - * configure.in (mips-sgi-irix6*): Use mh-irix6 instead of mh-irix5. - -Mon Jul 1 13:31:35 1996 Michael Meissner - - * config.sub (basic_machine): Recognize d10v as a valid processor. - -Fri Jun 28 12:14:35 1996 Stan Shebs - - * mpw-configure: Add support for --bindir. - * mpw-build.in: Use a GCC-specific build script for GCC actions. - -Wed Jun 26 17:20:12 1996 Geoffrey Noer - - * configure.in: add bash, time, gawk to list of hosttools and things - to only build for native toolchains - -Tue Jun 25 23:09:03 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) - - * Makefile.in (docdir): Remove. - -Tue Jun 25 19:00:08 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) - - * Makefile.in (datadir): Set to $(prefix)/share. - -Mon Jun 24 23:26:07 1996 Geoffrey Noer - - * configure.in: build diff and patch for cygwin32-hosted - toolchains. - -Mon Jun 24 15:01:12 1996 Joel Sherrill - - * config.sub: Accept -rtems*. - -Sun Jun 23 22:41:54 1996 Geoffrey Noer - - * configure.in: enable dosrel for cygwin32-hosted builds, - remove diff from the list of things not buildable - via Canadian Cross - -Sat Jun 22 11:39:01 1996 Jason Merrill - - * Makefile.in (TARGET_SUBDIR): Move comment to previous line so we - don't get ". ". - -Fri Jun 21 17:24:48 1996 Jim Wilson - - * configure.in (mips*-sgi-irix6*): Set noconfigdirs appropriately. - -Thu Jun 20 16:57:40 1996 Ken Raeburn - - * Makefile.in (taz): Handle case where tex3patch didn't even get - checked out. Also, if it was found, put the symlink in a new util - subdirectory. - -Thu Jun 20 12:20:33 1996 Michael Meissner - - * config.guess (*:Linux:*:*): Add support for PowerPC Linux. - -Tue Jun 18 14:24:12 1996 Klaus Kaempf (kkaempf@progis.de) - - * config.sub: Recognize -openvms. - * configure.in (alpha*-*-*vms*): Set noconfigdirs. - * make-all.com, setup.com: New files. - -Mon Jun 17 16:34:46 1996 Jason Merrill - - * Makefile.in (taz): tex3patch moved to texinfo/util. - -Sat Jun 15 17:13:25 1996 Geoffrey Noer - - * configure: enable_gdbtk=no for cygwin32-hosted toolchains - * configure.in: remove make from disable-if-Can-Cross list - enable gdb if ${host} and ${target} are cygwin32 - -Fri Jun 7 18:16:52 1996 Harlan Stenn - - * config.guess (i?86-ncr-sysv*): Emit minor release numbers. - Recognize the NCR 4850 machine and NCR Pentium-based platforms. - -Wed Jun 5 00:09:17 1996 Per Bothner - - * config.guess: Combine mips-mips-riscos cases, and use cpp to - distinguish sysv/svr4/bsd variants. - Based on a patch from Harlan Stenn . - -Fri Jun 7 14:24:49 1996 Tom Tromey - - * configure.in: Added copyright notice. - * move-if-change: Added copyright notice. - -Thu Jun 6 16:27:05 1996 Michael Meissner - - * configure.in (powerpcle-*-solaris*): Until we get shared - libraries working, don't build gdb, sim, make, tcl, tk, or - expect. - -Tue Jun 4 20:41:45 1996 Per Bothner - - * config.guess: Merge with FSF: - - Mon Jun 3 08:49:14 1996 Karl Heuer - * config.guess (*:Linux:*:*): Add guess for sparc-unknown-linux. - - Fri May 24 18:34:53 1996 Roland McGrath - * config.guess (AViiON:dgux:*:*): Fix typo in recognizing mc88110. - - Fri Apr 12 20:03:59 1996 Per Bothner - * config.guess: Combine two OSF1 rules. - Also recognize field test versions. From mjr@zk3.dec.com. - * config.guess (dgux): Use /usr/bin/uname rather than uname, - because GNU uname does not support -p. From pmr@pajato.com. - -Tue Jun 4 11:07:25 1996 Tom Tromey - - * Makefile.in (MAKEDIRS): Removed $(tooldir). - -Tue May 28 12:30:50 1996 Stan Shebs - - * mpw-README: Document GCCIncludes. - -Sun May 26 15:16:27 1996 Fred Fish - - * configure.in (alpha-*-linux*): Set enable_shared to yes. - -Tue May 21 15:41:39 1996 Stan Shebs - - * mpw-configure: Handle --enable-FOO and --disable-FOO. - -Mon May 20 10:12:29 1996 Geoffrey Noer - - * configure.in (*-*-cygwin32): Configure make. - -Tue May 7 14:19:42 1996 Tom Tromey - - * Makefile.in (inet-install): Quote value of INSTALL_MODULES. - -Fri May 3 08:57:17 1996 Tom Tromey - - * Makefile.in (all-inet): Depend on all-perl. - - * Makefile.in (inet-install): New target. - - * Makefile.in (all-inet): Depend on all-tcl. - (all-inet): Depend on all-send-pr. - -Tue Apr 30 13:55:51 1996 Michael Meissner - - * configure.in (powerpcle-*-solaris*): Turn off tk and tcl - temporarily. - -Thu Apr 25 11:48:20 1996 Ian Lance Taylor - - * configure.in: Don't configure --with-gnu-ld on AIX. - -Thu Apr 25 06:33:36 1996 Michael Meissner - - * configure.in (powerpcle-*-solaris*): Turn off gdb temporarily. - -Tue Apr 23 09:07:39 1996 Tom Tromey - - * Makefile.in (ALL_MODULES): Added all-inet. - (CROSS_CHECK_MODULES): Added check-inet. - (INSTALL_MODULES): Added install-inet. - (CLEAN_MODULES): Added clean-inet. - (all-indent): New target. - - * configure.in (host_tools): Added inet. - (native_only): Added inet. - (noconfigdirs): Added inet. - -Fri Apr 19 15:35:29 1996 Ian Lance Taylor - - * configure.in: Don't configure libgloss if we are not configuring - newlib. - -Wed Apr 17 19:30:01 1996 Rob Savoye - - * configure.in: Don't configure libgloss for unsupported - architectures. - -Tue Apr 16 11:17:05 1996 Michael Meissner - - * Makefile.in (CLEAN_MODULES): Add clean-apache. - -Mon Apr 15 15:09:05 1996 Tom Tromey - - * Makefile.in (ALL_MODULES): Include all-apache. - (CROSS_CHECK_MODULES): Include check-apache. - (INSTALL_MODULES): Include install-apache. - (all-apache): New target. - - * configure.in: Added apache everywhere perl is seen. - -Mon Apr 15 14:59:13 1996 Michael Meissner - - * Makefile.in: Add support for clean-{module} and - clean-target-{module} rules. - -Wed Apr 10 21:37:41 PDT 1996 Marilyn E. Sander - - * configure.in (*-*-ose) do not build libgloss. - -Mon Apr 8 16:16:20 1996 Michael Meissner - - * config.guess (prep*:SunOS:5.*:*): Turn into - powerpele-unknown-solaris2. - -Mon Apr 8 14:45:41 1996 Ian Lance Taylor - - * configure.in: Permit --enable-shared to specify a list of - directories. - -Fri Apr 5 08:17:57 1996 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (host==solaris): Pass only the first word of $CC - to /usr/bin/which when checking if we're using /usr/ccs/bin/cc. - -Fri Apr 5 03:16:13 1996 Jason Molenda (crash@phydeaux.cygnus.com) - - * Makefile.in (BASE_FLAGS_TO_PASS): pass down $(MAKE). - -Thu Mar 28 14:11:11 1996 Tom Tromey - - * Makefile.in (ALL_MODULES): Include all-perl. - (CROSS_CHECK_MODULES): Include check-perl. - (INSTALL_MODULES): Include install-perl. - (ALL_X11_MODULES): Include all-guile. - (CHECK_X11_MODULES): Include check-guile. - (INSTALL_X11_MODULES): Include install-guile. - (all-perl): New target. - (all-guile): New target. - - * configure.in (host_tools): Include perl and guile. - (native_only): Include perl and guile. - (noconfigdirs): Don't build guile and perl; no ports have been - done. - -Tue Mar 26 21:18:50 1996 Andrew Cagney - - * configure (--enable-*): Handle quoted option lists such as - --enable-sim-cflags='-g0 -O' better. - -Thu Mar 21 11:53:08 1996 Michael Meissner - - * Makefile.in ({,inst}all-target): New rule so we can make and - install all of the target directories easily. - -Wed Mar 20 18:10:57 1996 Andreas Schwab - - * configure.in: Add missing global flag in sed substitution when - deleting `target-' from ${configdirs}. - -Thu Mar 14 19:15:06 1996 Ian Lance Taylor - - * Makefile.in (DO_X): Don't get confused if CC contains `=' in an - option. - - * configure.in (mips*-nec-sysvr4*): Use a host_makefile_frag of - config/mh-necv4. - - * install.sh: Correct misspelling of transformbasename. - - * config.guess: Recognize mips-*-sysv*. - -Mon Mar 11 15:36:42 1996 Dawn Perchik - - * config.sub: Recognize mon960. - -Sun Mar 10 13:18:38 1996 Ian Lance Taylor - - * configure: Restore Canadian Cross handling of BISON and LEX, - removed in Feb 20 change. - -Fri Mar 8 20:07:09 1996 Per Bothner - - * README: Suggestions from Torbjorn Granlund : - Mention make install. Remove the old copyright date as well the - clumsy and rather pointless copyright on the README file. - -Fri Mar 8 17:51:35 1996 Ian Lance Taylor - - * Makefile.in ($(CONFIGURE_TARGET_MODULES)): If there is a - Makefile after running symlink-tree, then run `make distclean' to - avoid clobbering any generated files in srcdir. - -Tue Mar 5 08:21:44 1996 J.T. Conklin - - * configure.in (m68k-*-netbsd*): Build everything now. - -Wed Feb 28 12:25:46 1996 Jason Merrill - - * Makefile.in (taz): Fix quoting. - -Tue Feb 27 11:33:57 1996 Doug Evans - - * configure.in (sparclet-*-*): Build everything now. - -Tue Feb 27 14:31:51 1996 Andreas Schwab - - * configure.in (m68k-*-linux*): New host. - -Mon Feb 26 14:32:44 1996 Ian Lance Taylor - - * configure: Check for bison before byacc. - -Tue Feb 20 23:12:35 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in configure: Change the way LEX and BISON/YACC are - set. configure now defines DEFAULT_LEX and DEFAULT_YACC by - searching PATH. These are used as fallbacks by Makefile.in if - flex/bison/byacc aren't in objdir. - -Mon Feb 19 11:45:30 1996 Ian Lance Taylor - - * Makefile.in: Make everything which depends upon all-bfd also - depend upon all-opcodes, in case --with-commonbfdlib is used. - -Thu Feb 15 19:50:50 1996 Michael Meissner - - * configure.in (host *-*-cygwin32): Don't build gdb if we are - building NT native compilers on Unix. - -Thu Feb 15 17:42:25 1996 Ian Lance Taylor - - * configure.in: Don't get CC from the host Makefile fragment if we - can find gcc in PATH, or if this is a Canadian Cross. Move the - Solaris test for /usr/ucb/cc to the post target script, just after - the compiler sanity test. - -Wed Feb 14 16:57:40 1996 Ian Lance Taylor - - * config.sub: Merge with FSF. - -Tue Feb 13 14:27:48 1996 Ian Lance Taylor - - * Makefile.in (RPATH_ENVVAR): New variable. - (REALLY_SET_LIB_PATH): Use it. - * configure.in: On HP/UX, set RPATH_ENVVAR to SHLIB_PATH. - -Mon Feb 12 15:28:49 1996 Doug Evans - - * config.sub, configure.in: Recognize sparclet cpu. - -Mon Feb 12 15:33:59 1996 Christian Bauernfeind - - * config.guess: Support m68k-cbm-sysv4. - -Sat Feb 10 12:06:42 1996 Andreas Schwab - - * config.guess (*:Linux:*:*): Guess m68k-unknown-linux and - m68k-unknown-linuxaout from linker help string. Put quotes around - $ld_help_string. - -Thu Dec 7 09:03:24 1995 Tom Horsley - - * config.guess (powerpc-harris-powerunix): Add guess for port - to new target. - -Thu Feb 8 15:37:52 1996 Brendan Kehoe - - * config.guess (UNAME_VERSION): Recognize X4.x as an OSF version. - -Mon Feb 5 16:36:51 1996 Ian Lance Taylor - - * configure.in: If --enable-shared was used, set SET_LIB_PATH to - $(REALLY_SET_LIB_PATH) in Makefile. - * Makefile.in (SET_LIB_PATH): New variable. - (REALLY_SET_LIB_PATH): New variable. - ($(DO_X)): Use $(SET_LIB_PATH). - (install.all, gcc-no-fixedincludes, $(ALL_MODULES)): Likewise. - ($(NATIVE_CHECK_MODULES), $(CROSS_CHECK_MODULES)): Likewise. - ($(INSTALL_MODULES), $(CONFIGURE_TARGET_MODULES)): Likewise. - ($(ALL_TARGET_MODULES), $(CHECK_TARGET_MODULES)): Likewise. - ($(INSTALL_TARGET_MODULES), $(ALL_X11_MODULES)): Likewise. - ($(CHECK_X11_MODULES), $(INSTALL_X11_MODULES)): Likewise. - (all-gcc, all-bootstrap, check-gcc, install-gcc): Likewise. - (install-dosrel): Likewise. - (all-opcodes): Depend upon all-libiberty. - -Sun Feb 4 16:51:11 1996 Steve Chamberlain - - * config.guess (*:CYGWIN*): New - -Sat Feb 3 10:42:35 1996 Michael Meissner - - * Makefile.in (all-target-winsup): All all-target-libiberty. - -Fri Feb 2 17:58:56 1996 Michael Meissner - - * configure.in (noconfigdirs): Add missing # in front of comment. - -Thu Feb 1 14:38:13 1996 Geoffrey Noer - - * configure.in: add second pass to things added to noconfigdirs - so *-gm-magic can exclude libgloss properly. - -Thu Feb 1 11:10:16 1996 Stan Shebs - - * mpw-configure (extralibs_name, rez_name): Set correctly - for MWC68K compiler. - - * mpw-README: Add more info on the necessary build tools. - -Thu Feb 1 10:22:38 1996 Steve Chamberlain - - * configure.in, config.sub: Recognize cygwin32. - -Wed Jan 31 14:17:10 1996 Richard Henderson - - * config.guess, config.sub: Recognize A/UX. - -Wed Jan 31 13:52:14 1996 Ian Lance Taylor - - * config.sub: Merge with gcc/config.sub. - -Thu Jan 25 11:01:10 1996 Raymond Jou - - * mpw-build.in (do-binutils): Add build of stamps. - -Thu Jan 25 17:05:26 1996 James G. Smith - - * config.sub: Add recognition for mips64vr4100*-* targets. - -Wed Jan 24 12:47:55 1996 Brendan Kehoe - - * test-build.mk: Add checking of `hpux9' rather than just `hpux'. - Add creation of gconfigargs with `--enable-shared' turned on. - ($(host)-stamp-stage2-configured): Pass $(gconfigargs). - ($(host)-stamp-stage3-configured): Likewise. - (HOLES): Add chatr and ldd. - (i386-ncr-sysv4.3*): Add use of /usr/ccs/bin in the PATH and HOLE_DIRS. - -Wed Jan 24 20:32:30 1996 Torbjorn Granlund - - * configure: Pass --nfp to recursive configures. - -Mon Jan 22 10:41:56 1996 Steve Chamberlain - - * Makefile.in (DLLTOOL): New. - (DLLTOOL_FOR_TARGET): New. - (EXTRA_HOST_FLAGS): Pass down DLLTOOL. - (EXTRA_TARGET_FLAGS): Ditto. - (EXTRA_GCC_FLAGS): Ditto. - (CONFIGURE_TARGET_MODULES): Ditto. - (DO_X): Ditto. - * configure: Add DLLTOOL. - -Fri Jan 19 13:30:15 1996 Stan Shebs - - SCO OpenServer 5 changes from Robert Lipe : - * configure.in (i[345]86-*-sco3.2v5*): Use mh-sysv instead of - mh-sco, since old workarounds no longer needed, and don't - build ld, since libraries have weak symbols in COFF. - -Sun Jan 14 23:01:31 1996 Fred Fish - - * Makefile.in (CONFIGURE_TARGET_MODULES): Add missing ';'. - -Fri Jan 12 15:25:35 1996 Ian Lance Taylor - - * configure.in: Make sure that ${CC} can be used to compile an - executable. - -Sat Jan 6 07:23:33 1996 Michael Meissner - - * Makefile.in (all-gdb): Depend on $(GDB_TK). - * configure (GDB_TK): Set GDB_TK to either "all-tcl all-tk" or - nothing depending on whether gdbtk is being built. - -Wed Jan 3 17:54:41 1996 Doug Evans - - * Makefile.in (newlib.tar.gz): Delete building of newlib's info files. - -Mon Jan 1 19:09:14 1996 Brendan Kehoe - - * configure.in (noconfigdirs): Put ld or gas in this early, if the - user specifically used --with-gnu-ld=no or --with-gnu-as=no. - -Sat Dec 30 16:08:57 1995 Doug Evans - - * config-ml.in: Add support for - --disable-{softfloat,m68881,m68000,m68020} on m68*-*-*. - Simplify setting of multidirs from --disable-foo. - -Fri Dec 29 07:56:11 1995 Michael Meissner - - * Makefile.in (EXTRA_GCC_FLAGS): If any of the make variables - LANGUAGES, BOOT_CFLAGS, STMP_FIXPROTO, LIMITS_H_TEST, - LIBGCC1_TEST, LIBGCC2_CFLAGS, LIBGCC2_INCLUDES, and ENQUIRE are - non-empty, pass them on to the GCC make. - (all-bootstrap): New rule that is like all-gcc, except it executes - the GCC bootstrap rule instead of the GCC all rule. - -Wed Dec 27 15:51:48 1995 Doug Evans - - * config-ml.in (ml_realsrcdir): New, to account for ${subdir}. - -Tue Dec 26 11:45:31 1995 Michael Meissner - - * config.guess (AViiON:dgux:*:*): Update from FSF to add pentium - DG/UX support. - -Fri Dec 15 10:01:27 1995 Stan Cox - - * config.sub (i*86*) Change [345] to [3456] - -Wed Dec 20 17:41:40 1995 Brendan Kehoe - - * configure.in (noconfigdirs): Add gas or ld if --with-gnu-as=no or - --with-gnu-ld=no. - -Wed Dec 20 15:15:35 1995 Michael Meissner - - * config-ml.in (rs6000*, powerpc*): Add switches to control which - AIX multilibs get built. - -Mon Dec 18 17:55:46 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (i386-win32): Don't build expect if we're not - building the tcl subdir. - -Mon Dec 18 11:47:19 1995 Stan Shebs - - * Makefile.in: (configure-target-examples, all-target-examples): - New targets, configure and build example programs. - -Fri Dec 15 16:13:03 1995 Stan Shebs - - * mpw-configure: If an mpw-config.in generated a file mk.sed, - use it as input to sedit the generated MPW makefile. - * mpw-README: Add a suggestion about Gestalt.h. - -Wed Dec 13 16:43:51 1995 Ian Lance Taylor - - * config.sub: Accept *-*-ieee*. - -Tue Dec 12 11:52:57 1995 Ian Lance Taylor - - * Makefile.in (local-distclean): Remove $(TARGET_SUBDIR). From - Ronald F. Guilmette . - -Mon Dec 11 15:31:58 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (host==powerpc-pe): Add many directories to noconfigdirs - for powerpc-pe native. - (target==i386-win32): add tcl, make to noconfigdirs if canadian cross. - (target==powerpc-pe): duplicate i386-win32 entry. - -Sat Dec 9 14:58:28 1995 Jim Wilson - - * configure.in (noconfigdirs): Exclude target-newlib for all versions - of vxworks, not just vxworks5.1. - -Mon Dec 4 12:05:40 1995 Stan Shebs - - * mpw-configure: Add support for exec-prefix. - -Mon Dec 4 10:22:50 1995 Jeffrey A. Law - - * config.guess: Recognize HP model 816 machines as having - a PA1.1 processor. - -Mon Dec 4 12:38:15 1995 Ian Lance Taylor - - * configure: Ignore new autoconf configure options. - -Thu Nov 30 14:45:25 1995 J.T. Conklin - - * config/mt-v810 (CC_FOR_TARGET): Add -ansi flag. NEC compiler - defaults to K&R mode, but doesn't have varargs.h, so we have to - compile in ANSI mode. - -Thu Nov 30 16:57:33 1995 Per Bothner - - * config.guess: Recognize Pentium under SCO. - From Robert Lipe . - -Wed Nov 29 13:49:08 1995 J.T. Conklin - - * configure.in (noconfigdirs): Disable target-libio on v810-*-*. - * config/mt-v810 (CC_FOR_TARGET, AS_FOR_TARGET, AR_FOR_TARGET, - RANLIB_FOR_TARGET): Set as appropriate for NEC v810 toolchain. - -Wed Nov 29 12:12:01 1995 Ian Lance Taylor - - * configure.in: Don't configure gas for alpha-dec-osf*. - -Tue Nov 28 17:16:48 1995 Ian Lance Taylor - - * configure.in: Default to --with-stabs for some targets for which - it makes sense: mips*-*-*, alpha*-*-osf*, i[345]86*-*-sysv4* and - i[345]86*-*-unixware*. - -Mon Nov 27 13:44:15 1995 Ian Lance Taylor - - * config-ml.in: Get list of multidirs using gcc --print-multi-lib - rather than basing it on the target. Simplify handling of options - controlling which directories to configure. Remove extraneous - slash in multi-clean target. - -Fri Nov 24 17:29:29 1995 Doug Evans - - * config-ml.in: Prefix more variables with ml_ so they don't collide - with configure's. - -Wed Nov 22 11:27:02 1995 Ian Lance Taylor - - * configure: Don't turn -v into --v. - -Tue Nov 21 16:48:02 1995 Doug Evans - - * configure.in (targargs): Fix typo. - - * Makefile.in (DEVO_SUPPORT): Add symlink-tree. - -Tue Nov 21 14:08:28 1995 Ian Lance Taylor - - * configure.in: Strip --host and --target options from - CONFIG_ARGUMENTS, and always configure for --host only. Add - --with-cross-host option when building with a cross-compiler. - * configure: Canonicalize the arguments put into config.status by - always using `=' for an option with an argument. Pass a presumed - --host or --target explicitly. - -Fri Nov 17 17:50:30 1995 Stan Shebs - - * config.sub: Merge -macos*, -magic*, -pe*, and -win32 cases - into general OS recognition case. - -Fri Nov 17 17:42:25 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (target_configdirs): add target-winsup only - for win32 target systems. - -Thu Nov 16 14:04:47 1995 Ian Lance Taylor - - * Makefile.in (all-target-libgloss): Depend upon - configure-target-newlib, since when libgloss is built it looks to - see if the newlib directory exists. - -Wed Nov 15 14:47:52 1995 Ken Raeburn - - * Makefile.in (DEVO_SUPPORT): Use config-ml.in instead of - cfg-ml-*.in. - -Wed Nov 15 11:45:23 1995 Ian Lance Taylor - - * configure: Handle LD and LD_FOR_TARGET when configuring a - Canadian Cross. - -Tue Nov 14 15:03:12 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * config/mh-i386win32: add LD_FOR_TARGET. - -Tue Nov 14 14:56:11 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (target_libs): add target-winsup. - (target==i386-win32): add patch diff flex make to $noconfigdirs. - (target==ppcle-pe): remove ld from $noconfigdirs. - -Tue Nov 14 01:25:50 1995 Doug Evans - - * Makefile.in (CONFIGURE_TARGET_MODULES): Pass --with-target-subdir. - Preserve relative path names in $srcdir. Build symlink tree if - configuring cross target dir and srcdir=. (= no VPATH support). - (configure-target-libg++): Depend on configure-target-librx. - * cfg-ml-com.in, cfg-ml-pos.in: Deleted. - * config-ml.in: New file. - * symlink-tree: New file. - * configure: Ensure srcdir="." if that's what it is. - -Mon Nov 13 12:34:20 1995 Stan Shebs - - * mpw-README: Clarify some phrasing, add notes about CodeWarrior - includes and FLEX_SKELETON setting. - * mpw-configure (--with-gnu-ld): New option, controls whether - to use PPCLink or ld with PowerMac GCC. - * mpw-build.in (all-grez, do-grez, install-grez): New targets. - * mpw-config.in: Configure grez if targeting Mac. - - * config.sub: Accept pmac and pmac-mpw as names for PowerMacs, - accept mpw and mac-mpw as names for m68k Macs, change macos7 to - just macos. - * configure.in: Configure grez resource compiler if targeting Mac. - * Makefile.in (all-grez, install-grez): New targets. - -Wed Nov 8 17:33:51 1995 Jason Merrill - - * configure: CXX defaults to gcc, not g++. If we find - gcc in the path, set CC to gcc -O2. - -Tue Nov 7 15:45:17 1995 Ian Lance Taylor - - * configure: Default ${build} correctly. Avoid picking up extra - spaces when reading CC and CXX from Makefile. When doing a - Canadian Cross, use plausible default values for numerous - variables. - * configure.in: When doing a Canadian Cross, don't try to - configure tools whose configure script can't handle it. - -Mon Nov 6 19:32:17 1995 Jim Wilson - - * cfg-ml-com.in (sh-*-*): Add m2 and ml/m2 to multidirs. - -Sun Nov 5 00:15:41 1995 Per Bothner - - * configure: Remove dubious bug reporting address. - -Fri Nov 3 08:17:54 1995 Per Bothner - - * Makefile.in ($(CONFIGURE_TARGET_MODULES)): If subdir has - configure script, run that instead of this directory's configure. - In either case, print a message that we're configuring the sub-dir. - -Thu Nov 2 23:23:36 1995 Per Bothner - - * configure.in: Before checking for the existence of various files, - use sed to filter out "target-". - -Thu Nov 2 13:24:56 1995 Ian Lance Taylor - - * Makefile.in (DO_X): Split rule to decrease command line length - for systems with small ARG_MAX values. From phdm@info.ucl.ac.be - (Philippe De Muyter). - -Wed Nov 1 15:18:35 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * Makefile.in (all-patch): depend on all-libiberty. - -Wed Nov 1 12:23:20 1995 Ian Lance Taylor - - * configure.in: If the only directory in target_configdirs which - actually exists is libiberty, then set target_configdirs to empty, - to avoid trying to build a target libiberty in a gas or gdb - distribution. - -Tue Oct 31 17:52:39 1995 J.T. Conklin - - * configure.in (host_makefile_frag): Use m68k-sun-sunos* instead - of m68k-sun-* when selecting mh-sun3 to avoid matching NetBSD/sun3 - systems. - -Tue Oct 31 16:57:32 1995 Jim Wilson - - * configure.in (copy_dirs): Use sys-include instead of include - for --with-headers option. - -Tue Oct 31 10:29:36 1995 steve chamberlain - - * Makefile.in, configure.in: Make winsup builds work with - new scheme. - -Mon Oct 30 18:57:09 1995 Ian Lance Taylor - - * configure.in: Build the linker on AIX. - -Mon Oct 30 12:27:16 1995 Per Bothner - - * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Add $(TARGET_SUBDIR) - where needed. - -Mon Oct 30 12:45:25 1995 Doug Evans - - * Makefile.in (all-gcc): Fix typo. - -Sat Oct 28 10:27:59 1995 Per Bothner - - * Makefile.in ($(CHECK_TARGET_MODULES)): Fix typo. - -Fri Oct 27 23:14:12 1995 Per Bothner - - * configure.in: Rename libFOO to target-libFOO, and xiberty - to target-xiberty, to provide more flexibility. - (target_subdir): Define. Create if cross. - Set TARGET_SUBDIR in Makefile to ${target_subdir}. - * Makefile.in: Rename all-libFOO -> all-target-libFOO, all-xiberty - -> all-target-libiberty, configure-libFOO -> configure-target-libFOO, - check-libFOO -> check-target-libFOO, etc. - ($(DO_X)): Iterate over TARGET_CONFIGDIRS after SUBDIRS. - ($(CONFIGURE_TARGET_MODULES), $(CHECK_TARGET_MODULES), - $(ALL_TARGET_MODULES), $(INSTALL_TARGET_MODULES)): Update accordingly. - (configure-target-XXX): Depend on $(ALL_GCC), not all-gcc, to - allow ALL_GCC="" to only configure. - (DEVO_SUPPORT): Add cfg-ml-com.in and cfg-ml-pos.in. - (ETC_SUPPORT, ETC_SUPPORT_PFX): Merge; update 'taz' accordingly. - (LIBGXX_SUPPORT_DIRS): Remove xiberty. - -Sat Oct 28 01:53:49 1995 Ken Raeburn - - * Makefile.in (taz): Build "info" in etc explicitly. - -Fri Oct 27 09:32:30 1995 Stu Grossman (grossman@cygnus.com) - - * configure.in: Make sure that CC is undefined (as opposed to - null) if toplevel/config/mh-{host} doesn't define it. Fixes a - problem with autoconf trying to configure on a host without GCC. - -Thu Oct 26 22:35:01 1995 Stan Shebs - - * mpw-configure: Set host alias from choice of host compiler, - only use generic MPW Makefile sed if present, edit a file - named "hacked_Makefile.in" instead of "Makefile.in" if present. - * mpw-README: Add problem notes about CW6 and CW7. - -Thu Oct 26 05:45:10 1995 Ken Raeburn - - * Makefile.in (taz): Use ";" instead of ";;". - -Wed Oct 25 15:18:24 1995 Per Bothner - - * Makefile.in (taz): Grep for '^diststuff:' or '^info:' in - sub-directory Makefiles, instead of using DISTSTUFFDIRS and - DISTDOCDIRS. - (DISTSTUFFDIRS, DISTDOCDIRS): Removed - no longer used. - (newlib.tar.gz): Don't pass DISTDOCDIRS to recursive make. - -Wed Oct 25 14:43:55 1995 Per Bothner - - * Makefile.in (DISTDOCDIRS): Remove ld gprof bnutils gas libg++ gdb - and gnats, because they are now subsumed by DISTSTUFFDIRS. - Move bfd to DISTSTUFFDIRS. - -Tue Oct 24 18:19:09 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * Makefile.in (X11_LIB): Removed. - (X11_FLAGS_TO_PASS): pass only X11_EXTRA_CFLAGS and X11_EXTRA_LIBS. - - * configure.in (host_makefile_frag): mh-aix & mh-sun removed. - -Sun Oct 22 13:04:42 1995 Michael Meissner - - * cfg-ml-com.in (powerpc*): Shorten some of the multilib directory - names. - -Fri Oct 20 18:02:10 1995 Michael Meissner - - * cfg-ml-com.in (powerpc*-eabi*): Add mcall-aixdesc varients. - -Thu Oct 19 10:40:57 1995 steve chamberlain - - * configure.in (i[345]86-*-win32): Always build newlib. - Don't configure cvs, autoconf or texinfo. - * Makefile.in (LD_FOR_TARGET): New. - (BASE_FLAGS_TO_PASS, EXTRA_TARGET_FLAGS, CONFIGURE_TARGET_MODULES): - Pass down LD_FOR_TARGET. - -Wed Oct 18 15:53:56 1995 steve chamberlain - - * winsup: New directory. - * Makefile.in: Build winsup. - * configure.in: Winsup is configured when target is win32. - Can only build win32 target GDB when native. - -Mon Oct 16 09:42:31 1995 Jeffrey A Law (law@cygnus.com) - - * config.guess: Recognize HP model 819 machines as having - a PA 1.1 processor. - -Mon Oct 16 10:49:43 1995 Ian Lance Taylor - - * configure: Fix sed loop which substitutes for CC and CXX to - avoid bug found in various sed implementations. - -Wed Oct 11 16:16:20 1995 Michael Meissner - - * cfg-ml-com.in (powerpc-*-eabisim): Delete separate rule for - simulator. Use standard powerpc-*-eabi*. - -Mon Oct 9 17:21:56 1995 Ian Lance Taylor - - * configure.in: Stop putting gas and binutils in noconfigdirs for - powerpc-*-aix* and rs6000-*-*. - -Mon Oct 9 12:38:40 1995 Michael Meissner - - * cfg-ml-com.in (powerpc*-*-eabisim*): Add support for building - -mcall-aixdesc libraries. - -Fri Oct 6 16:17:57 1995 Ken Raeburn - - Mon Sep 25 22:49:32 1995 Andreas Schwab - - * config.sub (arm | armel | armeb): Fix shell syntax. - -Fri Oct 6 14:40:28 1995 Michael Meissner - - * cfg-ml-com.in ({powerpc,rs6000}-ibm-aix*): Add multilibs for - -msoft-float and -mcpu=common support. - (powerpc*-*-eabisim*): Add support for building -mcall-aix - libraries. - -Thu Oct 5 13:26:37 1995 Brendan Kehoe - - * configure.in: Allow configuration and build of emacs19 for the alpha. - -Wed Oct 4 22:05:36 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (CC): Get ^CC, not just any old CC, from - ${host_makefile_frag}. - -Wed Oct 4 21:55:00 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (CC): Try to get CC from - ${srcdir}/${host_makefile_frag}, not ${host_makefile_frag}. - -Wed Oct 4 21:44:12 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * Makefile.in (TARGET_CONFIGDIRS): configure targetdirs - only if it exists in $(srcdir). - -Wed Oct 4 11:52:31 1995 Ian Lance Taylor - - * configure: If CC and CXX are not set in the environment, set - them, based on either an existing Makefile or on searching for gcc - in PATH. Substitute for CC and CXX in Makefile. - * configure.in: Remove libm from target_libs. Separate - target_configdirs from configdirs. If CC is not set in - environment, try to get it from a host Makefile fragment. Rewrite - changes of configdirs to use skipdirs instead. A few minor - tweaks. Take directories out of target_configdirs as they are - taken out of configdirs. Remove existing Makefile files from - subdirectories. Substitute for TARGET_CONFIGDIRS and - CONFIG_ARGUMENTS in Makefile. - * Makefile.in (TARGET_CONFIGDIRS): New variable, automatically set - by configure.in. - (CONFIG_ARGUMENTS): Likewise. - (CONFIGURE_TARGET_MODULES): New variable. - ($(DO_X)): Loop over TARGET_CONFIGDIRS as well as SUBDIRS. - ($(CONFIGURE_TARGET_MODULES)): New target. - (configure-libg++, configure-libio): New targets. - (all-libg++): Depend upon configure-libg++. - (all-libio): Depend upon configure-libio. - (configure-libgloss, all-libgloss): New targets. - (configure-libstdc++): New target. - (all-libstdc++): Depend upon configure-libstdc++. - (configure-librx, all-librx): New targets. - (configure-newlib): New target. - (all-newlib): Depend upon configure-newlib - (configure-xiberty): New target. - (all-xiberty): Depend upon configure-xiberty. - -Sat Sep 30 04:32:59 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (host i[345]86-*-win32): Expand the - noconfigdirs again. - -Thu Sep 28 21:18:49 1995 Stan Shebs - - * mpw-configure: Fix sed command file name. - -Thu Sep 28 17:39:56 1995 steve chamberlain - - * configure.in (host i[345]86-*-win32): Reduce the - noconfigdirs again. - -Wed Sep 27 12:24:00 1995 Ian Lance Taylor - - * configure.in: Don't configure ld and gdb for powerpc*-*-winnt* - or powerpc*-*-pe*, since they are not yet supported. - -Tue Sep 26 14:30:01 1995 Stan Shebs - - Add PowerMac support and many other enhancements. - * mpw-configure: New option --cc to select compiler to use, - paste options set according to --cc into the generated - Makefile, generate the Makefile by sed'ing the Unix Makefile.in - if mpw-make.sed is present. - * mpw-config.in: Don't test for gC1, test for mpw-touch, - add forward includes for PowerPC include files. - * mpw-build.in: Build using Makefile.PPC if present. - (do-byacc, etc): Remove separate version resource builds. - (do-gas): Build "stamps" before "all". - (do-gcc): Build "stamps-h" and "stamps-c" before "all". - * mpw-README: Update to reflect --cc option, PowerMac support, - and recently-reported compatibility problems. - -Fri Sep 22 12:15:42 1995 Doug Evans - - * cfg-ml-com.in (m68*-*-*): Only build multilibs for - embedded m68k systems (-aout, -coff, -elf, -vxworks). - (--with-multilib-top): Pass to recursive invocations. - -Tue Sep 19 13:51:05 1995 J.T. Conklin - - * configure.in (noconfigdirs): Disable libg++ and libstdc++ on - v810-*-*. - -Mon Sep 18 23:08:26 1995 J.T. Conklin - - * configure.in (noconfigdirs): Disable bfd, binutils, gas, gcc, - gdb, ld and opcodes on v810-*-*. - -Sat Sep 16 18:31:08 PDT 1995 Angela Marie Thomas - - * config/mh-ncrsvr43: Removed AR_FLAGS - -Tue Sep 12 18:03:31 1995 Ian Lance Taylor - - * Makefile.in (DO_X): Change do-realclean to do-maintainer-clean. - (local-maintainer-clean): New target. - (maintainer-clean): New target. - (realclean): Just depend upon maintainer-clean. - -Fri Sep 8 17:11:14 1995 J.T. Conklin - - * configure.in (noconfigdirs): Disable gdb on m68k-*-netbsd*. - -Fri Sep 8 16:46:29 1995 Ian Lance Taylor - - * configure.in: Build ld in mips*-*-bsd* case. - -Thu Sep 7 20:03:41 1995 Ken Raeburn - - * config.sub: Accept -lites* OS. From Ian Dall. - -Fri Sep 1 08:06:58 1995 James G. Smith - - * config.sub: recognise mips64vr4300 and mips64vr4300el as valid - targets. - -Wed Aug 30 21:06:50 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in: treat i386-win32 canadian cross the same as - i386-go32 canadian cross. - -Thu Aug 24 14:53:20 1995 Michael Meissner - - * cfg-ml-com.in (powerpc*-*-eabisim): Add support for PowerPC - running under the simulator to build a reduced set of libraries. - (powerpc-*-eabiaix): Add fine grained multilib support added to - other powerpc targets yesterday. - -Wed Aug 23 09:41:56 1995 Michael Meissner - - * cfg-ml-com.in (powerpc*): Add support for -disable-biendian, - -disable-softfloat, -disable-relocatable, -disable-aix, and - -disable-sysv to control which multilib libraries get built. - -Thu Aug 17 16:03:41 1995 Ken Raeburn - - * configure: Add Makefile.tem to list of files to remove in trap - handler. - -Mon Aug 14 19:27:56 1995 Per Bothner - - * config.guess (*Linux*): Add missing "exit"s. - Also, need specific check for alpha-unknown-linux (uses COFF). - -Fri Aug 11 15:38:20 1995 Per Bothner - - * config.guess: Merge with FSF: - - Wed Jun 28 17:57:27 1995 David Edelsohn - * config.guess (AIX4): More robust release numbering discovery. - - Thu Jun 22 19:01:24 1995 Kenneth Stailey (kstailey@eagle.dol-esa.gov) - * config.guess (i386-sequent-ptx): Properly get version number. - - Thu Jun 22 18:36:42 1995 Uwe Seimet (seimet@iris1.chemie.uni-kl.de) - * config.guess (mips:*:4*:UMIPS): New case. - -Mon Aug 7 09:21:35 1995 Doug Evans - - * configure.in (i386-go32 host): Fix typo (deja-gnu -> dejagnu). - (i386-win32 host): Likewise. Don't build readline. - -Sat Aug 5 09:51:49 1995 Fred Fish - - * Makefile.in (GDBTK_SUPPORT_DIRS): Define and pass as part of - SUPPORT_FILES to submakes. - -Fri Aug 4 13:04:36 1995 Fred Fish - - * Makefile.in (GDB_SUPPORT_DIRS): Add utils. - (DEVO_SUPPORT): Add mpw-README, mpw-build.in, mpw-config.h and - mpw-configure. - -Wed Aug 2 16:32:40 1995 Ken Raeburn - - * configure.in (appdirs): Use =, not ==, in test expression when - trying to build the text to print in the warning message for - Solaris users. - -Mon Jul 31 09:56:18 1995 steve chamberlain - - * cfg-ml-com.in (z8k-*-coff): Add 'std' multilib build. - -Fri Jul 28 00:16:31 1995 Jeffrey A. Law - - * config.guess: Recognize lynx-2.3. - -Thu Jul 27 15:47:59 1995 steve chamberlain - - * config.sub (z8ksim): Deleted - (z8k-*-coff): New, this is the one true name of the target. - -Thu Jul 27 14:33:33 1995 Doug Evans - - * cfg-ml-pos.in (dotdot): Work around SunOS sed bug. - -Thu Jul 27 13:31:05 1995 Fred Fish (fnf@cygnus.com) - - * config.guess (*:Linux:*:*): First try asking the linker what the - default object file format is (elf, aout, or coff). Then if this - fails, try previous methods. - -Thu Jul 27 11:28:17 1995 J.T. Conklin - - * configure.in: Don't build newlib for *-*-vxworks5.1. - -Thu Jul 27 11:18:47 1995 Brendan Kehoe - - * configure.in: Don't build newlib for a29k-*-vxworks5.1. - * test-build.mk: Add setting of --with-headers for a29k-vxworks5.1. - -Tue Jul 25 21:25:39 1995 Doug Evans - - * cfg-ml-pos.in (MULTITOP): Trim excess trailing "/.". - -Fri Jul 21 10:41:12 1995 Doug Evans - - * cfg-ml-com.in: New file. - * cfg-ml-pos.in: New file. - -Wed Jul 19 00:37:27 1995 Jeffrey A. Law - - * COPYING.NEWLIB: Add HP free copyright to list. - -Tue Jul 18 10:58:51 1995 Michael Meissner - - * config.sub: Recognize -eabi* for the system, not just -eabi. - -Mon Jul 3 13:44:51 1995 Steve Chamberlain - - * Makfile.in (DLLTOOL_FOR_TARGET): New name, pass it down. - * config.sub, configure.in (win32): New target and host. - -Wed Jun 28 23:57:08 1995 Steve Chamberlain - - * configure.in: Add i386-pe configuration. - -Fri Jun 23 14:28:44 1995 Stan Shebs - - * mpw-build.in (install): Install GDB after LD. - -Thu Jun 22 17:10:53 1995 Stan Shebs - - * mpw-config.in (elf/mips.h): Always forward-include, needed - for GDB to build. - -Wed Jun 21 15:17:30 1995 Rob Savoye - - * testsuite: New directory for customer acceptance and whole tool - chain tests. - -Wed Jun 21 16:50:29 1995 Ken Raeburn - - * configure: If per-host line isn't found, but AC_OUTPUT is found - and a configure script exists, run it instead. - -Thu Jun 15 21:09:24 1995 Per Bothner - - * config.guess: Update from FSF, for alpha-dec-winnt3.5 and Crays. - -Tue Jun 13 21:43:27 1995 Rob Savoye - - * configure: Set build_{cpu,vendor,os,alias} to host values when - --build isn't specified. - -Mon Jun 5 18:26:36 1995 Jason Merrill - - * Makefile.in (PICFLAG, PICFLAG_FOR_TARGET): New macros. - (FLAGS_TO_PASS): Pass them. - (EXTRA_TARGET_FLAGS): Ditto. - - * config/m?-*pic: Define PICFLAG* instead of LIB*FLAGS*. - -Wed May 31 22:27:42 1995 Jim Wilson - - * Makefile.in (all-libg++): Depend on all-libstdc++. - -Thu May 25 22:40:59 1995 J.T. Conklin - - * configure.in (noconfigdirs): Enable all packages for - i386-unknown-netbsd. - -Sat May 20 13:22:31 1995 Angela Marie Thomas - - * configure.in (noconfigdirs): Don't configure tk for i386-go32 - hosted builds (DOS builds) - -Thu May 18 18:08:49 1995 Ken Raeburn - - Changes for ARM based on patches from Richard Earnshaw: - * config.sub: Handle armeb and armel. - * configure.in: Omit arm linker only for riscix. - -Thu May 11 17:23:26 1995 Per Bothner - - * config.guess: Update from FSF. - -Tue May 9 15:52:05 1995 Michael Meissner - - * config.sub: Recognize powerpcle as the little endian varient of - the PowerPC. Recgonize ppc as a PowerPC variant, and ppcle as a - powerpcle variant. Convert pentium into i586, not i486. Add p5 - alias for i586. Map new x86 variants p6, k5, nexgen into i586 - temporarily. - -Tue May 2 16:29:41 1995 Jeff Law (law@snake.cs.utah.edu) - - * configure.in (hppa*-*-lites*): Treat like hppa*-*-*elf*. - -Sun Apr 30 21:38:09 1995 Jeff Law (law@snake.cs.utah.edu) - - * config.sub: Accept -lites* as a basic system type. - -Thu Apr 27 11:33:29 1995 Michael Meissner (meissner@cygnus.com) - - * config.guess (*:Linux:*:*): Check for whether the pre-BFD linker is - installed, and if so return linuxoldld as the system name. - -Wed Apr 26 10:59:02 1995 Jeff Law (law@snake.cs.utah.edu) - - * config.guess: Add hppa1.1-hp-lites support. - -Tue Apr 25 11:08:11 1995 Rob Savoye - - * configure.in: Don't build newlib for m68k-vxworks5.1. - -Wed Apr 19 17:02:43 1995 Jim Wilson - - * configure.in (mips-sgi-irix6): Use mh-irix5. - -Fri Apr 14 15:21:17 1995 Doug Evans - - * Makefile.in (all-gcc): Depend on all-ld (for libgcc1-test). - -Wed Apr 12 16:06:01 1995 Jason Merrill - - * test-build.mk: Enable building of shared libraries on IRIX 5 and - OSF/1. Fix compiler flags. - * build-all.mk: Support Linux and OSF/1 3.0. Fix compiler flags. - -Tue Apr 11 18:55:40 1995 Doug Evans - - * configure.in: Recognize --with-newlib. - (sparc-*-sunos4*): Build sim, dejagnu, expect, tcl if cross target. - -Mon Apr 10 14:38:20 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * Makefile.in: move {all,check,install}-gdb from *_MODULES - to *_X11_MODULES due to gdbtk needing X include files et al. - -Mon Apr 10 11:42:22 1995 Stan Shebs - - Merge in support for Mac MPW as a host. - (Old change descriptions retained for informational value.) - - * mpw-config.in: Add generic include forwards for cpu-specific - include files in aout and elf directories. - - * mpw-configure: Added copyright. - * mpw-config.in: Check for presence of required build tools. - (target_libs): Add newlib. - (target_tools): Add examples. - (Read Me): Generate as "Read Me for MPW" instead. - * mpw-build.in: Base sub-builds on all-foo instead of do-foo. - (all-byacc, do-byacc, all-flex, do-flex, do-newlib): New actions. - (do-gas, do-gcc, do-gdb, do-ld): Build Version.r first. - - * mpw-configure: Remove subdir-specific makefile hackery, - delete mk.tmp after using it. - - * mpw-build.in (all): Display start and end times. - - * mpw-configure (host_canonical): Set. - (target_cpu): Always add to makefiles. - (ARCHDEFS, EMUL): Add to makefile only if nonempty. - (TM_FILE, XM_FILE, NM_FILE): No longer add to makefile. - (mpw-mh-mpw): Look for in srcdir and srcroot. - Use sed instead of mpw-edit-prefix to edit prefix definitions. - - * mpw-build.in: (install-only): New target. - - * mpw-configure (host_alias, target_alias): Rename from hostalias - and targetalias, add into generated Makefile. - (mk.tmp): If present, add into generated Makefile. - * mpw-build.in (all-gas): Build config.h first before gas proper. - - * mpw-configure (config.status): Write only if changed. - * mpw-config.in (readline): Configure it (not built, just used for - definitions). - - * mpw-config.in (elf/mips.h): Add a forward include. - - * mpw-config.in: Forward-include most .h files in include into - extra-include. - (readline): Don't build. - mpw-build.in (install): Install GDB. - - * mpw-configure (prefix, mpw_prefix): Handle it. - * mpw-config.in (mmalloc, readline): Don't configure. - * mpw-build.in (thisscript): Rename to ThisScript. - Use mpw-build instead of BuildProgram everywhere. - (mmalloc, readline): Don't build. - * mpw-README: New file, basic documentation about the MPW port. - - * mpw-config.in: Use forward-include to create include files. - - * mpw-configure: Add more things to the top of each configured - Makefile, including contents of config/mpw-mh-mpw. - * mpw-config.in (extra-include): Create this directory and fill it - with Posix-like include files when configuring. - - * config.sub (apple, mac, mpw): Add various aliases. - - * mpw-build.in: New file, top-level build script fragment for MPW. - * mpw-configure: New file, configure script for MPW. - * mpw-config.in: New file, config fragment for MPW. - -Fri Apr 7 19:33:16 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in (host_libs): Remove glob, since it is gone from the - sources. - -Fri Mar 31 11:36:17 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * Makefile.in: define empty GDB_NLM_DEPS var. - - * configure.in(target_makefile_frag): use config/mt-netware - for netware targets. - -Thu Mar 30 13:51:43 1995 Ian Lance Taylor - - * config.sub: Merge in recent FSF changes. Remove linux special - cases. - -Tue Mar 28 14:47:34 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - build-all.mk,config/mh-solaris: revert these two changes: - - Tue Mar 30 10:03:09 1993 Ian Lance Taylor (ian@cygnus.com) - - * build-all.mk: Use CC=cc -Xs on Solaris. - - Mon Mar 29 19:59:26 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config/mh-solaris: SunPRO C needs -Xs to be able to get a - working xmakefile for Emacs. - -Tue Mar 21 10:43:32 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * glob/*: Removed. Schauer's 24 Feb 1994 readline change made us - stop using it. - * Makefile.in: Nuke all references to glob subdirectory. - -Thu Mar 16 13:35:30 1995 Jason Merrill - - * configure.in: Fix --enable-shared logic in per-host. - -Mon Mar 13 12:33:15 1995 Ian Lance Taylor - - * configure.in (*-hp-hpux[78]*): Use mh-hpux8. - -Mon Mar 6 10:21:58 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in (noconfigdirs): Don't build gas on AIX, for - powerpc*-*-aix* as well as for rs6000*-*-aix*. - -Wed Mar 1 12:51:53 1995 Ian Lance Taylor - - * configure: Fix --cache-file to work if the file argument is a - relative path. - -Tue Feb 28 17:36:07 1995 Ian Lance Taylor - - * configure: If the --cache-file is used, pass it down to - configure in subdirectories. - -Mon Feb 27 12:52:46 1995 Kung Hsu - - * config.sub: add vxworks29k configuration. - -Fri Feb 10 16:12:26 1995 Ken Raeburn - - * Makefile.in (taz): Do "diststuff" part quietly. - -Sun Feb 5 14:16:35 1995 Doug Evans - - * config.sub: Mini-merge with gcc/config.sub. - -Sat Feb 4 12:11:35 1995 Jim Wilson - - * config.guess (IRIX): Sed - to _. - -Fri Feb 3 11:54:42 1995 J.T. Conklin - - * Makefile.in (source-vault, binary-vault): New targets. - -Thu Jan 26 13:00:11 1995 Michael Meissner - - * config.sub: Recognize -eabi as a basic system type. - -Thu Jan 12 13:13:23 1995 Jason Merrill - - * configure.in (enable_shared stuff): Fix typo. - -Thu Jan 12 01:36:51 1995 deanm@medulla.LABS.TEK.COM (Dean Messing) - - * Makefile.in (BASE_FLAGS_TO_PASS): Fix typo in passing LIBCXXFLAGS*. - -Wed Jan 11 16:29:53 1995 Jason Merrill - - * Makefile.in (LIBCXXFLAGS_FOR_TARGET): Add -fno-implicit-templates. - -Mon Jan 9 12:48:01 1995 Jim Kingdon - - * configure.in (rs6000-*-*): Don't build gas. - -Wed Jan 4 23:53:49 1995 Ian Lance Taylor - - * Makefile.in: Use /x/x/ instead of /brokensed/brokensed/, to - reduce command line length. - (AS_FOR_TARGET): Check for as.new, not Makefile. - (NM_FOR_TARGET): Check for nm.new, not Makefile. - -Wed Jan 4 13:02:39 1995 Per Bothner - - * config.guess: Merge from FSF. - -Thu Dec 15 17:11:37 1994 Ian Lance Taylor - - * configure: Don't use $ when handling program_suffix. - -Mon Dec 12 12:09:37 1994 Stu Grossman (grossman@cygnus.com) - - * configure.in: Configure tk for hppa/hpux. - -Fri Dec 2 15:55:38 1994 Per Bothner - - * Makefile.in (LIBGXX_SUPPORT_DIRS): Add libstdc++. - -Tue Nov 29 19:37:56 1994 Per Bothner - - * Makefile.in: Move -fno-implicit-template from CXXFLAGS - to LIBCXXFLAGS. Tests are better run without it. - -Wed Nov 23 10:29:25 1994 Brendan Kehoe (brendan@lisa.cygnus.com) - - * Makefile.in (all-ispell): Depend on all-emacs19 instead of all-emacs. - -Mon Nov 21 11:14:01 1994 J.T. Conklin - - * configure.in (*-*-netware*): Don't configure xiberty. - -Mon Nov 14 08:49:15 1994 Stu Grossman (grossman@cygnus.com) - - * configure.in: Remove tk from native_only list. - -Fri Nov 11 15:31:26 1994 Bill Cox (bill@rtl.cygnus.com) - - * build-all.mk: Add mips-ncd-elf target to sun4 targets - for special NCD build. - -Mon Nov 7 20:58:17 1994 Ken Raeburn - - * Makefile.in (DEVO_SUPPORT): Remove configure.bat and - makeall.bat, they're only useful for binutils snapshots. - (binutils.tar.gz, gas+binutils.tar.gz): Add configure.bat and - makeall.bat to specified SUPPORT_FILES. - -Mon Nov 7 17:25:18 1994 Bill Cox (bill@cirdan.cygnus.com) - - * build-all.mk: Add Ericsson targets to sun4 and solaris - hosts. Add BNR's sun4 target to solaris host, so their - build-from-source will be tested in-house first. - -Sat Nov 5 18:43:30 1994 Jason Merrill (jason@phydeaux.cygnus.com) - - * Makefile.in (LIBCFLAGS): New variable. - (CFLAGS_FOR_TARGET): Ditto. - (LIBCFLAGS_FOR_TARGET): Ditto. - (LIBCXXFLAGS): Ditto. - (CXXFLAGS_FOR_TARGET): Ditto. - (LIBCXXFLAGS_FOR_TARGET): Ditto. - (BASE_FLAGS_TO_PASS): Pass them. - (EXTRA_TARGET_FLAGS): Ditto. - - * configure.in, config/m[th]-*pic: Support --enable-shared. - -Sat Nov 5 15:44:00 1994 Per Bothner - - * configure.in (target_libs): Include libstdc++ again. - * config.guess: Update from FSF (for FreeBSD). - -Thu Nov 3 16:32:30 1994 Ken Raeburn - - * Makefile.in (DEVO_SUPPORT): Include configure.bat and - makeall.bat. - (DISTDOCDIRS): Add `etc'. - (ETC_SUPPORT_PFX): New variable. - (taz): Include anything from etc starting with a word in - ETC_SUPPORT_PFX. - -Wed Oct 26 16:19:35 1994 Ian Lance Taylor - - * config.sub: Update for recent FSF changes. Remove obsolete - h8300hds entry. Add -windows* and -osx as basic os. Minor - spacing changes. - -Thu Oct 20 18:41:56 1994 Per Bothner - - * configure.in (target_libs): Remove libstdc++ for libg++-2.6.1. - - * config.guess: Merge with FSF. - * configure.in: Match on i?86-ncr-sysv4.3, not i?86-ncr-sysv43. - -Thu Oct 20 19:26:56 1994 Ken Raeburn - - * configure: Since the "trap 0" handler will override the exit - status on many systems, only use it for "exit 1", and make it set - a non-zero exit status; reset it before "exit 0". Also, check - exit status of config.sub, and error out if it failed. - -Wed Oct 19 18:49:55 1994 Rob Savoye (rob@cygnus.com) - - * Makefile.in: (ALL_TARGET_MODULES,INSTALL_TARGET_MODULES) Build - and install libgloss. - -Tue Oct 18 15:25:24 1994 Ian Lance Taylor - - * Makefile.in (all-binutils): Depend upon all-byacc. - - * configure.in: Don't build emacs on Irix 5. - -Mon Oct 17 16:22:12 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * configure.in (*-*-netware*): Add libio. - -Thu Oct 13 15:51:20 1994 Jason Merrill (jason@phydeaux.cygnus.com) - - * Makefile.in (ALL_TARGET_MODULES): Add libstdc++. - (CHECK_TARGET_MODULES): Ditto. - (INSTALL_TARGET_MODULES): Ditto. - (TARGET_LIBS): Ditto. - (all-libstdc++): Note dependencies. - -Thu Oct 13 01:43:08 1994 Ken Raeburn - - * Makefile.in (BINUTILS_SUPPORT_DIRS): Add gas. - -Tue Oct 11 12:12:29 1994 Jason Merrill (jason@phydeaux.cygnus.com) - - * Makefile.in (CXXFLAGS): Use -fno-implicit-templates instead of - -fexternal-templates. - - * configure.in (target_libs): Add libstdc++. - (noconfigdirs): Add libstdc++ as appropriate. - -Thu Oct 6 18:00:54 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Update from FSF. - -Tue Oct 4 12:05:42 1994 Ian Lance Taylor - - * configure: Use ${config_shell} when running ${configsub}. - -Mon Oct 3 14:28:34 1994 Doug Evans - - * config.sub: No longer recognize h8300h. - -Mon Oct 3 12:40:54 1994 Ian Lance Taylor - - * config.sub: Remove extraneous differences between config.sub and - gcc/config.sub. - -Sat Oct 1 00:23:12 1994 Ken Raeburn - - * Makefile.in (DISTSTUFFDIRS): Add gas. - -Thu Sep 22 19:04:55 1994 Doug Evans (dje@canuck.cygnus.com) - - * COPYING.NEWLIB: New file. - -Mon Sep 19 18:25:40 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess (HP-UX): Patch from Harlan Stenn - to also emit release level. - -Wed Sep 7 13:15:25 1994 Jim Wilson (wilson@sphagnum.cygnus.com) - - * config.guess (sun4*:SunOS:*:*): Change '-JL' to '_JL'. - -Tue Sep 6 23:23:18 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.sub: Merge nextstep cleanup from FSF. - -Mon Sep 5 05:01:30 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * configure.in (arm-*-*): Don't configure ld for this target. - -Thu Sep 1 09:35:00 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * configure.in (*-*-netware): don't configure libg++, libio, - librx, or newlib. - -Wed Aug 31 13:52:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure.in (alpha-dec-osf*): Use osf*, not osf1*. Don't - configure ld--it works, but it doesn't support shared libraries. - -Sun Aug 28 18:13:45 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess (*-unknown-freebsd*): Get rid of possible - trailing "(Release)" in version string. - Patch from Paul Richards . - -Sat Aug 27 15:00:49 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Fix i486-ncr-sysv43 -> i486-ncr-sysv4.3. - Fix type: *-next-neststep -> *-next-nextstep. - - * config.guess: Merge from FSF: - - Fri Aug 26 18:45:25 1994 Philippe De Muyter (phdm@info.ucl.ac.be) - - * config.guess: Recognize powerpc-ibm-aix3.2.5. - - Wed Apr 20 06:36:32 1994 Philippe De Muyter (phdm@info.ucl.ac.be) - - * config.guess: Recognize UnixWare 1.1 (UNAME_SYSTEM is SYSTEM_V - instead of UNIX_SV for UnixWare 1.0). - -Sat Aug 27 01:56:30 1994 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (all-gdb): Add dependencies on all-gcc and all-ld - to make gdb/nlm/* build after the compiler and linker. - -Fri Aug 26 14:30:05 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess (netbsd, freebsd, linux): Accept any machine, - not just i[34]86. - (m68k-atari-sysv4): Relocate to match FSF version. - - * config.guess: More merges from the FSF: - - Add a space before function call or macro invocation. - - Tue May 10 16:53:55 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * config.guess: Add trap cmd to remove dummy.c and dummy when - interrupted. - - Wed Apr 20 18:07:13 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * config.guess (dummy.c): Redirect stderr for `hostinfo' command. - (dummy): Redirect stderr from compilation of dummy.c. - - Sat Apr 9 14:59:28 1994 Christian Kranz (kranz@sent5.uni-duisburg.de) - - * config.guess: Distinguish between NeXTStep 2.1 and 3.x. - -Fri Aug 26 13:42:20 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com) - - * configure: Accept and ignore --cache*, for compatibility with - new autoconf. - -Fri Aug 26 13:05:27 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Merge from FSF: - - Thu Aug 25 20:28:51 1994 Richard Stallman - - * config.guess (Pyramid*:OSx*:*:*): New case. - (PATH): Add /.attbin at end for finding uname. - (dummy.c): Handle i860-alliant-bsd. Follow whitespace conventions. - - Wed Aug 17 18:21:02 1994 Tor Egge (tegge@pvv.unit.no) - - * config.guess (M88*:DolphinOS:*:*): New case. - - Thu Aug 11 17:00:13 1994 Stan Cox (coxs@dg-rtp.dg.com) - - * config.guess (AViiON:dgux:*:*): Use TARGET_BINARY_INTERFACE - to select whether to use ELF or COFF. - - Sun Jul 24 16:20:53 1994 Richard Stallman - - * config.guess: Recognize i860-stardent-sysv and i860-unknown-sysv. - - Sun May 1 10:23:10 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu) - - * config.guess: Guess the OS version for HPUX. - - Tue Mar 1 21:53:03 1994 Karl Heuer (kwzh@hal.gnu.ai.mit.edu) - - * config.guess (UNAME_VERSION): Recognize aix3.2.4 and aix3.2.5. - -Fri Aug 26 11:19:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure.in: Recognize --with-headers, --with-libs, and - --without-newlib. - * Makefile.in (all-xiberty): Depend upon all-ld. - -Wed Aug 24 12:36:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure.in: Change i[34]86 to i[345]86. - -Mon Aug 22 10:58:33 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure (version): A few more tweaks to help message. - -Fri Aug 19 12:40:25 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * Makefile.in: Remove (for now) librx as a host library, - now that we're building it for target. - -Fri Aug 19 10:49:17 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure: Fix up help message; from karl@owl.hq.ileaf.com - (Karl Berry). - -Tue Aug 16 16:11:08 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * configure.in: Also configure librx. - -Mon Aug 15 16:51:45 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * Makefile.in: Update various rules to reflect that librx - is now needed for libg++. - -Fri Aug 12 18:07:21 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * config.sub: Accept mips64orion and mips64orionel as a CPU name. - -Mon Aug 8 11:36:17 1994 Stan Shebs (shebs@andros.cygnus.com) - - * configure.in: Configure the examples directory. - -Thu Aug 4 16:12:36 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure: Simplify Jun 2 1994 change. - -Wed Aug 3 04:58:16 1994 D. V. Henkel-Wallace (gumby@cygnus.com) - - * change CC to /usr/latest/bin/gcc for lynx host builds, since - /bin/gcc isn't good enough to build gcc. - -Wed Jul 27 09:07:14 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (GDB_SUPPORT_FILES): Remove - (setup-dirs-gdb, gdb.tar.gz, make-gdb.tar.gz): Remove old rules. - (gdb.tar.gz): Add new rule to use standard distribution building - mechanism. - -Mon Jul 25 11:10:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Warn about use of /usr/ucb/cc on Solaris. From - Bill Cox . - -Sat Jul 23 12:19:46 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Recognize ISC. Patch from kwzh@gnu.ai.mit.edu. - -Fri Jul 22 17:53:59 1994 Stu Grossman (grossman@cygnus.com) - - * configure: Search current dir first in .gdbinit. - -Fri Jul 22 11:28:30 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.sub: Recognize freebsd (merged from gcc config.sub). - -Thu Jul 21 14:10:52 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.sub: Refer to NeXT's operating system as nextstep. - - * config.sub (case $basic_machine): Re-order the cases, to match - the order in the FSF version (which is mostly alphabethical). - Merge in some additions and changes from the FSF. - -Sat Jul 16 12:03:08 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config.guess: Recognize m68k-atari-sysv4 and m88k-harris-csux7. - * config.sub: Recognize cxux7. - * configure.in: Use mh-cxux for m88k-harris-cxux*. - -Mon Jul 11 14:37:39 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.sub: Fix typo powerpc -> powerpc-*. - -Sat Jul 9 13:03:43 1994 Michael Tiemann (tiemann@blues.cygnus.com) - - * Makefile.in: `all-emacs19' depends on `all-byacc'. - - * Makefile.in: Add all-emacs19 and install-emacs19 rules (in - parallel with all-emacs and install-emacs). Top-level command - `make all-emacs19 CC=gcc' now behaves as `make all-emacs CC=gcc'. - -Thu Jun 30 16:53:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * test-build.mk ($(host)-stamp-stage2-installed): Remove - $(relbindir)/make before doing ``make install'', and use - $(GNU_MAKE) while doing it. Avoids problem on SunOS with - installing over running make binary. - ($(host)-stamp-stage3-installed): Likewise. - -Tue Jun 28 13:43:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Recognize Mach. - -Mon Jun 27 16:41:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure: Check ${exec_prefixoption}, not ${exec_prefix}, to - see whether --exec-prefix was used. - -Sun Jun 26 21:15:54 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * README: Explicitly mention libg++/README. (Zoo's idea.) - -Tue Jun 21 12:45:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Add all-librx target similar to all-libproc. - -Wed Jun 8 23:11:55 1994 Stu Grossman (grossman@cygnus.com) - - * config.guess: Rearrange tests for Alpha-OSF1 to properly deal - with post 1.2 uname bogosity. - -Thu Jun 9 00:27:59 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure: Remove temporary files on receipt of a signal. - -Tue Jun 7 12:06:24 1994 Ian Lance Taylor (ian@cygnus.com) - - * configure: If there is a package_makefile_frag, remove - ${subdir}/Makefile.tem after copying it in. - -Mon Jun 6 21:35:02 1994 D. V. Henkel-Wallace (gumby@cygnus.com) - - * build_all.mk: support rs6000 lynx identifies itself as - rs6000-lynx-lynxos2.2.2. Also, use /usr/cygnus/progressive/bin/gcc - since /bin/gcc is too feeble to compile a modern gcc. - -Mon Jun 6 16:06:34 1994 Karen Christiansen (karen@cirdan.cygnus.com) - - * brought devo/test-build.mk update-to-date with progressive/ - test-build.mk. Add lynx targets and hppa flag info. - -Sat Jun 4 17:23:54 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * configure.in: Use mh-ncrsvr43. Patch from - Tom McConnell . - -Fri Jun 3 17:47:24 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess (i386-unknown-bsdi): No longer need to - check #if defined(__bsdi__) && defined(__i386__). - -Thu Jun 2 18:56:46 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure: Set program_transform_nameoption correctly. - -Thu Jun 2 10:57:06 1994 Karen Christiansen (karen@cirdan.cygnus.com) - - * brought build-all.mk update-to-date with progressive build-all.mk, - added new targets and hppa info. - -Thu Jun 2 00:12:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure: If config.guess result is a prefix of the user - specified target, assume a native build and use the user specified - target as the host alias. Remove SunOS patch suffix removal hack. - * configure.in: Remove SunOS patch suffix removal hack. - - * Makefile.in (CROSS_CHECK_MODULES): Remove check-flex, since it's - in NATIVE_CHECK_MODULES. - -Wed Jun 1 10:49:41 1994 Bill Cox (bill@rtl.cygnus.com) - - * Makefile.in: Rename HOST_ONLY to NATIVE. - * configure: Delete SunOs patch suffix from host_canonical - and build_canonical variables that are prepended to Makefiles. - * configure.in: Add comments for easier maintenance. - -Tue May 31 19:39:47 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Add all-libproc target similar to all-gui. - -Tue May 31 17:16:33 1994 Tom Lord (lord@cygnus.com) - - * Makefile.in (CHECK_MODULES): split into - HOST_ONLY_CHECK_MODULES and CROSS_CHECK_MODULES. - -Tue May 31 16:36:36 1994 Paul Eggert (eggert@twinsun.com) - - * config.guess (i386-unknown-bsdi): New system to guess. - -Wed May 25 16:47:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Add all-gui target (but not yet build by "all"). - -Thu May 26 08:53:19 1994 Bill Cox (bill@rtl.cygnus.com) - - * config.sub: Move deletion of patch suffix from here... - * configure.in: To here, at Ian's suggestion. The top- - level scripts might need to know of a patch level. - -Wed May 25 09:15:54 1994 Bill Cox (bill@rtl.cygnus.com) - - * config.sub: Strip off patch suffix so rtl is recognized - as a sunos4.1.3 machine, even though it's been patched. - -Fri May 20 08:25:49 1994 Steve Chamberlain (sac@deneb.cygnus.com) - - * Makefile.in (INSTALL_LAST): Delete. - (INSTALL_DOSREL): New. - -Thu May 19 17:12:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Use ld for i[34]86-*-sysv4* and sparc-*-solaris2*. - Don't set use_gnu_ld to no for *-*-sysv4; that only controls - whether we pass down --with-gnu-ld anyhow. - -Thu May 19 09:29:12 1994 Steve Chamberlain (sac@cygnus.com) - - * Makefile.in (INSTALL_LAST): Change operation so it works - on more flavors of make. - * configure.in (go32): Don't build libg++ or libio. - -Fri May 13 13:28:34 1994 Steve Chamberlain (sac@cygnus.com) - - * Makefile.in (Move HOST_PREFIX_1 and friends up so - they can be overriden by templates. - -Sat May 7 16:46:44 1994 Steve Chamberlain (sac@cygnus.com) - - * configure.in (target==go32): Don't build gdb. - * dosrel: New directory. - -Fri May 6 14:19:25 1994 Steve Chamberlain (sac@cygnus.com) - - * configure.in (host==go32): Configure dosrel too. - * Makefile.in (INTALL_TARGET): Call INSTALL_LAST last. - (HOST_CC, HOST_PREFIX, HOST_PREFIX_1): Undefine, they should - be set by incoming names or templates. - (INSTALL_LAST): New rule. - * config/mh-go32: New fragment. - -Thu May 5 17:35:05 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config.sub (sparclitefrw, sparclitefrwcompat): Don't set the os. - -Thu May 5 20:06:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * config/mh-lynxrs6k: Renamed from mh-lynxosrs6k, to make it - unique in 8.3 naming schemes. - * configure.in (appdirs): New variable. Currently empty, but will - be used in gas distribution. If nonempty, lists a set of - directories at least one of which must get configured, or top - level configuration is considered to have failed. - (rs6000-*-lynxos*): Use new file name. - -Thu May 5 13:38:36 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - Eliminate XTRAFLAGS. - * Makefile.in (CC_FOR_TARGET): If newlib exists, refer to the - newlib include files using -idirafter, and also use -nostdinc. - (CXX_FOR_TARGET): Likewise. - (XTRAFLAGS): Removed. - (BASE_FLAGS_TO_PASS): Remove XTRAFLAGS_FOR_TARGET. - (EXTRA_HOST_FLAGS): Remove XTRAFLAGS. - (EXTRA_TARGET_FLAGS, EXTRA_GCC_FLAGS): Likewise. - ($(DO_X)): Don't pass down XTRAFLAGS. - -Thu May 5 00:16:36 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * configure.in (mips*-dec-bsd*): New target; do build linker. - (mips*-*-bsd*): New target; don't build linker. - -Wed May 4 20:10:10 1994 D. V. Henkel-Wallace (gumby@cygnus.com) - - * configure.in: support rs6000-*-lynxos* configuration. - support sunos4 as a cross target. - - * config.sub: look for lynx*, not lynx since the OS version may - legitimately be part of the name. - -Tue May 3 21:48:11 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * configure.in (i[34]86-*-sco*): Move to be with other i386 - targets. - (romp-*-*): New target. Skip various binary utilities. - (vax-*-*): New target. Don't build newlib. - (vax-*-vms): Renamed from *-*-vms. Don't build opcodes or newlib. - -Thu Apr 28 15:03:05 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * configure.in: Only set host_makefile_frag if config - directory exists. - -Wed Apr 27 12:14:30 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * install.sh: If $dstdir exists, don't check whether each - component does. - -Tue Apr 26 18:11:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * test-build.mk (HOLES): Add sleep; used by rcs/src/conf.sh. - -Mon Apr 25 15:06:34 1994 Stan Shebs (shebs@andros.cygnus.com) - - * configure.in (*-*-lynxos*): Don't configure newlib for either - native or cross Lynx. - -Sat Apr 16 11:58:16 1994 Doug Evans (dje@canuck.cygnus.com) - - * config.sub (sparc64-elf): Fix os. - (z8k): Remove duplicate. - -Thu Apr 14 23:33:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * Makefile.in (gcc-no-fixedincludes): Touch gcc/include/fixed, not - gcc/stmp-fixproto, to try to prevent fixproto from being run. - -Wed Apr 13 15:14:52 1994 Bill Cox (bill@cygnus.com) - - * configure: Make file links cleanly even if Lynx fails on - an NFS symlink (at least fail cleanly). - -Mon Apr 11 10:58:56 1994 Jim Wilson (wilson@sphagnum.cygnus.com) - - * test-build.mk (CC): For mips-sgi-irix4, change -XNh1500 to - -XNh2000. - -Sat Apr 9 15:10:45 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * configure: Unknown options are fatal again. - -Fri Apr 8 12:01:41 1994 David J. Mackenzie (djm@cygnus.com) - - * configure: Ignore --x-includes and --x-libraries, for Autoconf - compatibility. - -Thu Apr 7 17:31:43 1994 Doug Evans (dje@canuck.cygnus.com) - - * build-all.mk: Add `clean' target. - -Wed Apr 6 20:44:56 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config.guess: Add SINIX support. - * configure.in: Add mips-*-sysv4* support. - -Mon Apr 4 17:41:44 1994 Doug Evans (dje@canuck.cygnus.com) - - * build-all.mk: Document all useful targets. - If canonhost is sparc-sun-solaris2.3, change it to sparc-sun-solaris2. - If canonhost is mips-sgi-irix4.0.5H, change it to mips-sgi-irix4. - -Thu Mar 31 04:55:57 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * configure: Support --silent, --quiet. - -Wed Mar 30 21:37:38 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * configure: Support --disable-FEATURE. - -Tue Mar 29 19:15:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Recognize NCR running SVR4.3. - -Mon Mar 28 14:55:15 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Make BSDI generate i386-unknown-bsd386. - Patch from Paul Eggert . - -Mon Mar 28 12:54:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in (powerpc-*-aix*): Treat like rs6000-*-*. - -Sat Mar 26 11:25:48 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * configure: Make unrecognized options give nonfatal warnings - instead of fatal errors, and pass them to any subdirectory - configures in case they recognize them. - Make --x equivalent to --with-x. - -Fri Mar 25 21:52:10 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * configure: Add --enable-* options. Clean up usage message and - some comments. - -Thu Mar 24 09:12:53 1994 Doug Evans (dje@canuck.cygnus.com) - - * Makefile.in (NM_FOR_TARGET): Build tree version is now nm.new. - -Sun Mar 20 11:28:22 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * configure.in (hppa*-*-*): Enable binutils. - -Sat Mar 19 11:50:16 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.sub: Recognize cisco. - -Fri Mar 18 16:42:32 1994 Jason Merrill (jason@deneb.cygnus.com) - - * Makefile.in (CXXFLAGS): Add -fexternal-templates. - -Tue Mar 15 11:25:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: about target *-hitachi-hiuxwe2, don't print more - than one configuration name. Add comment. - -Sun Mar 6 23:13:38 1994 Hisashi MINAMINO (minamino@sra.co.jp) - - * config.guess: about target *-hitachi-hiuxwe2, fixed - machine guessing order. [Hitachi's CPU_IS_HP_MC68K - macro is incorrect.] - -Sun Mar 13 09:10:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (TAGS): Just build TAGS in each subdirectory, rather - than the "make ls" stuff which used to be here. - -Fri Mar 11 12:52:39 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Recognize i[34]86-unknown-freebsd. - From Shawn M Carey . - -Thu Mar 3 14:24:21 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * configure.in (noconfigdirs for alpha): Remove libg++ and libio. - -Wed Mar 2 13:28:48 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * config.guess: Check for ptx. - -Mon Feb 28 16:46:50 1994 Kung Hsu (kung@mexican.cygnus.com) - - * config.sub: Add os9k checking. - -Thu Feb 24 07:09:04 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * config.guess: Handle OSF1 running on HPPA processors - -Fri Feb 18 14:14:00 1994 Ken Raeburn (raeburn@rtl.cygnus.com) - - * configure: If subdir configure fails, print out a message with - subdirectory name, in case subdir's configure code didn't identify - itself. - -Fri Feb 18 12:50:15 1994 Doug Evans (dje@cygnus.com) - - * configure.in: Remove embedded newlines from configdirs. - Avoid mismatches of substrings. Fix matching strings at end - of configdirs. - -Fri Feb 11 15:33:33 1994 Stu Grossman (grossman at cygnus.com) - - * config.guess: Add Lynx/rs6000 config support. - -Tue Feb 8 13:41:09 1994 Ken Raeburn (raeburn@rtl.cygnus.com) - - * configure.in (alpha-dec-osf1*, alpha*-*-*): Build gas. - -Mon Feb 7 15:42:36 1994 Jeffrey A. Law (law@cygnus.com) - - * configure.in (hppa*-*-osf*): Treat this just like most other - PA configurations (eg no binutils or ld). - (hppa*-*-*elf*): These configurations have binutils and ld. - -Sun Feb 6 16:35:07 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * config.sub (hiux): Fix typo. From m-kasahr@sramhc.sra.co.JP. - -Sat Feb 5 01:00:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in (rs6000-*-*): Build gas. - -Wed Feb 2 13:57:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * Makefile.in: Avoid bug in losing hpux sed. - -Wed Feb 2 14:53:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in, test-build.mk: Remove MUNCH_NM; it was only needed - for GDB and GDB has been fixed to not need it. - -Mon Jan 31 18:40:55 1994 Stu Grossman (grossman at cygnus.com) - - * config/mh-lynxosrs6k: Account for lack of ranlib! - -Sun Jan 30 17:58:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * config.guess: Recognize vax hosts. - -Fri Jan 28 15:29:38 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * configure (while loop): Don't use "break 2" inside case - statement -- the case statement isn't an enclosing loop. - -Mon Jan 24 18:40:06 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Clean up NeXT support, to allow nextstep - on Intel machines. Make OS be nextstep. - -Sun Jan 23 18:47:22 1994 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - * config.guess: Add alternate forms for Convex. - -Thu Jan 20 16:13:41 1994 Stu Grossman (grossman at cygnus.com) - - * configure: Completely rewrite option processing. Take - advantage of pattern-matching to avoid invoking test frequently. - Also clean up host and target defaulting logic. - -Mon Jan 17 15:06:56 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * Makefile.in: Replace all occurrances of "rootme" with "r" and - "$${rootme}" with "$$r", to increase the likelihood that the do-* - commands (plus user environment) will fit SCO limits. - -Thu Jan 6 11:20:57 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Don't issue warnings about directories which are - not being configured if -norecursion is set. Correct test for - --with-gnu-as and --with-gnu-ld to not get confused by substring - matches. - - * configure.in: Don't build gas for alpha-dec-osf1*. - -Tue Jan 4 17:10:19 1994 Stu Grossman (grossman at cygnus.com) - - * configure: Back out Per's change of 12/19/1993. It changes the - behavior of configure in unexpected and confusing ways. - - Also, use different delim char when calculating - program_transform_name so that the name can contain slashes. - -Sat Jan 1 13:45:31 1994 Rob Savoye (rob@darkstar.cygnus.com) - - * configure.in, config.sub: Add support for VSTa micro-kernel. - -Sat Dec 25 20:00:47 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * configure.in: Nuke hacks which were used to get a special - version of GAS for HPPA configurations. - -Sun Dec 19 20:40:44 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * configure: If only ${target_alias} is given, use that - as the default for ${host_alias}. - * configure: Add missing back-slashes before nested quotes. - -Wed Dec 15 18:07:18 1993 david d `zoo' zuhn (zoo@andros.cygnus.com) - - * Makefile.in (BASE_FLAGS_TO_PASS): add YACC=$(BISON) - -Tue Dec 14 21:25:33 1993 Per Bothner (bothner@cygnus.com) - - * config.guess: Recognize some Tektronix configurations. - From Kaveh R. Ghazi . - -Sat Dec 11 11:18:00 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * config.sub: Match any flavor of SH. - -Thu Dec 2 17:16:58 1993 Ken Raeburn (raeburn@cujo.cygnus.com) - - * configure.in: Don't try to configure newlib for Alpha. - -Thu Dec 2 14:35:54 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Don't build ld for Irix 5. Don't build gas, - libg++ or libio for any Alpha target. - - * configure.in (mips*-sgi-irix5*): New target; use mh-irix5. - * config/mh-irix5. New file for Irix 5. - -Wed Dec 1 17:00:33 1993 Jason Merrill (jason@deneb.cygnus.com) - - * Makefile.in (GZIPPROG): Renamed from GZIP, which gzip uses for - default arguments -- so it tried to compress itself. - -Tue Nov 30 13:45:15 1993 david d `zoo' zuhn (zoo@andros.cygnus.com) - - * configure.in (notsupp): ensure that a space is always at the end - of the configdirs list, since the grep checks for an explicit space - -Tue Nov 16 15:04:27 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in (target i386-sysv4.2): don't build ld, since static - versions of many libraries are not available. - -Tue Nov 16 14:28:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Recognize Apollos (using environment variables). - * configure.in: Don't configure ld, binutils, or gprof for Apollo. - -Thu Nov 11 12:03:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Recognize Sony news mips running newsos. - -Wed Nov 10 16:57:00 1993 Mark Eichin (eichin@cygnus.com) - - * Makefile.in (all-cygnus, build-cygnus): "fi else" needs to be - "fi ; else" for bash. - -Tue Nov 9 15:54:01 1993 Mark Eichin (eichin@cygnus.com) - - * Makefile.in (BASE_FLAGS_TO_PASS): pass SHELL. - -Fri Nov 5 08:07:27 1993 D. V. Henkel-Wallace (gumby@blues.cygnus.com) - - * config.sub: accept unixware as an alias for svr4.2. - Fix some inconsistancies with the gcc version. - -Fri Nov 5 15:14:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (DISTDOCDIRS): Add gdb. - -Fri Nov 5 11:59:42 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * Makefile.in (DISTDOCDIRS): Add libg++ and libio. - -Fri Nov 5 10:35:05 1993 Ken Raeburn (raeburn@rover.cygnus.com) - - * Makefile.in (taz): Only build "info" in DISTDOCDIRS. - (DISTDOCDIRS): Don't assume libg++ and gdb folks necessarily want - this now. - -Thu Nov 4 18:58:23 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.sub: Accept hiux* as an OS name. - - * Makefile.in: Change RUNTEST_FLAGS back to RUNTESTFLAGS per - etc/make-stds.texi. The underscore came from gcc, and dje now - agrees that RUNTESTFLAGS is the correct name. - -Thu Nov 4 10:49:01 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * install.sh: Remove 'set -e'. It makes any conditionals - in the script useless. - - * config.guess: Automatically recognize arm-acorn-riscix - Patch from Richard Earnshaw (rwe11@cl.cam.ac.uk). - -Thu Nov 04 08:08:04 1993 Jeffrey Wheat (cassidy@cygnus.com) - - * Makefile.in: Change RUNTESTFLAGS to RUNTEST_FLAGS - -Wed Nov 3 22:09:46 1993 Ken Raeburn (raeburn@rtl.cygnus.com) - - * Makefile.in (DISTDOCDIRS): New variable. - (taz): Edit local Makefile.in sooner, instead of proto-toplev - Makefile.in later. Build "info" and "dvi" in DISTDOCDIRS. - -Wed Nov 3 21:31:52 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in (hppa target): check the source directory for the - pagas sub-directory - -Wed Nov 3 11:12:22 1993 Doug Evans (dje@canuck.cygnus.com) - - * config.sub: Allow -aout* and -elf*. - -Wed Nov 3 11:08:33 1993 Ken Raeburn (raeburn@rtl.cygnus.com) - - * configure.in: Don't build ld on i386-solaris2, same as for - sparc-solaris2. - -Tue Nov 2 14:21:25 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * Makefile.in (taz): Add texinfo/lgpl.texinfo (for libg++). - -Tue Nov 2 13:38:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * configure.in: Configure gdb for alpha. - -Mon Nov 1 10:42:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (CXXFLAGS): Add -O. - -Wed Oct 27 10:45:06 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * config.guess: added support for DG Aviion - -Tue Oct 26 14:37:37 1993 Ken Raeburn (raeburn@rover.cygnus.com) - - * configure.in: Produce warning message for subdirectories not - configurable for this host/target combination. Don't try to - configure gdb for vms. - -Mon Oct 25 11:22:15 1993 Ken Raeburn (raeburn@rover.cygnus.com) - - * Makefile.in (taz): Replace "byacc" with "bison -y" in the - appropriate files before making "diststuff". - (DISTBISONFILES): New var: list of files to be edited. - (DISTSTUFFDIRS): Add binutils. - -Fri Oct 22 20:32:15 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * config.sub: also handle mipsel and mips64el (for little endian mips) - -Fri Oct 22 07:59:20 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Add * to end of all OS names. - -Thu Oct 21 11:38:28 1993 Stan Shebs (shebs@rtl.cygnus.com) - - * configure.in: Build newlib for LynxOS native. - -Wed Oct 20 09:56:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Add support for delta 88k running SVR3. - - * configure.in: Add comment about HP compiler vs. emacs. - -Tue Oct 19 16:02:22 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in: don't build ld on solaris2 (not a viable option - due to bugs in getpwnam & getpwuid) - -Tue Oct 19 15:13:56 1993 Ken Raeburn (raeburn@rtl.cygnus.com) - - * configure.in: Accept alpha-dec-osf1*, not just -osf1, since - config.guess will produce a full version number. - -Tue Oct 19 15:58:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Build linker and binutils for alpha-dec-osf1. - -Tue Oct 19 11:41:55 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Remove -O from CXXFLAGS for consistency with CFLAGS, - and gdb/testsuite/Makefile.in. - -Sat Oct 9 18:39:07 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in: recognize mips*- instead of mips- - -Fri Oct 8 14:15:39 1993 Ken Raeburn (raeburn@cygnus.com) - - * config.sub: Accept linux*coff and linux*elf as operating - systems. - -Tue Oct 7 14:24:41 1997 Ian Lance Taylor - - * ltmain.sh: Handle symlinks in generated script. - -Thu Oct 7 12:57:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * config.sub: Recognize mips64, and mips3 as an alias for it. - -Wed Oct 6 13:54:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * configure.in: Remove alpha-dec-osf*, no longer necessary now that - gdb knows how to handle OSF/1 shared libraries. - -Tue Oct 5 11:55:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Recognize hppa*-*-hiux* (currently synonym for hpux). - * config.guess: Recognize Hitachi's HIUX. - * config.sub: Recognize h3050r* and hppahitachi. - Remove redundant cases for hp9k[23]*. - -Mon Oct 4 16:15:09 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in: default to '--with-gnu-as' and '--with-gnu-ld' - if gas and ld are in the source tree and are in ${configdirs}. - If ${use_gnu_as} or ${use_gnu_ld} are 'no', then don't set the - --with options (but still pass them down on the command line, - if they were explicitly specified). - -Wed Oct 1 13:11:27 1997 Ian Lance Taylor - - * configure: Handle autoconf style directory options: --bindir, - --datadir, --includedir, --infodir, --libdir, --libexecdir, - --mandir, --oldincludedir, --sbindir, --sharedstatedir, - --sysconfdir. - * Makefile.in (sbindir, libexecdir, sysconfdir): New variables. - (sharedstatedir, localstatedir, oldincludedir): New variables. - (BASE_FLAGS_TO_PASS): Pass down bindir, datadir, includedir, - infodir, libdir, libexecdir, localstatedir, mandir, oldincludedir, - sbindir, sharedstatedir, and sysconfdir. - -Fri Sep 24 19:11:13 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure: substitute SHELL value in Makefile.in with - ${CONFIG_SHELL} - -Wed Sep 24 15:18:32 1997 Ian Lance Taylor - - * ltmain.sh: Tweak shell pattern to avoid bug in NetBSD /bin/sh. - -Thu Sep 23 18:05:13 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Build gas, ld, and binutils for *-*-sysv4* and - *-*-solaris2* targets. - -Sun Sep 19 17:01:41 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * Makefile.in: define M4, and pass it down to sub-makes; - all-autoconf now depends on all-m4 - -Sat Sep 18 00:38:23 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * Makefile.in ({AR,RANLIB}_FOR_TARGET): make contingent on - presence of {ar,ranlib} instead of a configured directory - -Wed Sep 15 08:41:44 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * config.guess: Accept 34?? as well as 33?? for NCR. - -Mon Sep 13 12:28:43 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in: grab mt-hppa for HPPA targets; use 'gas ' instead - of 'gas' in sed commands, since 'gash' is now in the tree as well. - -Fri Sep 10 11:23:52 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure: grab values for $(CC) and $(CXX) from the - environment, so that someone can do "CC=gcc configure; make" and - have it work right (matching the way that autoconf works now) - - * configure.in, Makefile.in: add support for gash, the tcl - interface to Galaxy - - * config.guess: add NetBSD variants (hp300, x86) - -Thu Sep 9 16:48:52 1993 Jason Merrill (jason@deneb.cygnus.com) - - * install.sh: Support -d option (in the manner of SunOS 4 install, - as it is more deterministic than that of GNU install) - (chmodcmd): Set file to mode 755 by default (should also do default - chgrp and chown, but I don't feel like dealing with that now) - -Tue Sep 7 11:59:39 1993 Doug Evans (dje@canuck.cygnus.com) - - * config.sub: Remove h8300hhms alias. - -Tue Aug 31 11:00:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Match *-*-solaris2* not *-sun-solaris2*. - -Mon Aug 30 18:29:10 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * Makefile.in (gcc-no-fixedincludes): touch stmp-fixproto as well - as stmp-fixinc - -Wed Aug 25 16:35:59 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * config.sub: recognize m88110-bug-coff. - -Tue Aug 24 10:23:24 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * Makefile.in (all-libio): all dependencies on the toolchain used - to build this (gcc, gas, ld, etc) - -Fri Aug 20 17:24:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Deal with OSF/1 1.3 on alpha. - -Thu Aug 19 11:43:04 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * install.sh: add some 'else true' clauses for portability - - * configure.in: don't build libio for h8[35]00-*-* targets - -Tue Aug 17 19:02:31 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * Makefile.in: Add support for new libio. - -Sun Aug 15 20:48:55 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * install.sh: If one command fails, don't try the rest. Don't try - to remove $dsttmp (via trap) unless we have already created it. - If $src doesn't exist, detect it and exit with an error. - - * config.guess: Recognize BSD on hp300. - -Wed Aug 11 18:35:13 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * config.guess: Map (9000/[34]??:HP-UX:*:*) to m68k-hp-hpux. - Bug report from "Hamish (H.I.) Macdonald" . - -Wed Aug 11 15:37:51 1993 Jason Merrill (jason@deneb.cygnus.com) - - * Makefile.in (all-send-pr): depends on all-prms - -Wed Aug 11 16:56:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Fix typo (9000/8??:4.3bsd -> 9000/7??:4.3bsd). - -Fri Aug 6 14:45:02 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * config.guess: From michael@mercury.cs.mun.ca (Michael Rendell): - Added test for mips-mips-riscos5. - -Thu Aug 5 15:45:08 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in: use mh-hp300 for 68k HP hosts - -Mon Aug 2 11:56:53 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure: add support for CONFIG_SHELL, so that you can use - some alternate shell for evaluating configure scripts - -Sun Aug 1 11:36:27 1993 Fred Fish (fnf@deneb.cygnus.com) - - * Makefile.in (make-gdb.tar.gz): Sed bug reporting address - in configure script to bug-gdb@prep.ai.mit.edu when building - distribution archive. - * Makefile.in (COMPRESS): Remove def. - * Makefile.in (gdb.tar.gz, make-gdb.tar.gz): Renamed from - gdb.tar.Z and make-gdb.tar.Z respectively. - * Makefile.in (make-gdb.tar.gz): Now only build gzip'd archive. - * Makefile.in (make-gdb.tar.gz): Minor changes to move closer - to convergence with 'taz' target in Makefile.in. - -Fri Jul 30 12:34:57 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * install.sh (dsttmp): use trap to ensure that tmp files go - away on error conditions - -Wed Jul 28 11:57:36 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * Makefile.in (BASE_FLAGS_TO_PASS): remove LOADLIBES - -Tue Jul 27 12:43:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (install-dirs): Deal with a prefix like /gnu; - its parent is '/' not ''. - - * Makefile.in (DEVO_SUPPORT): Add comments about ChangeLog. - -Fri Jul 23 09:53:37 1993 Jason Merrill (jason@wahini.cygnus.com) - - * configure: if ${newsrcdir}/configure doesn't exist, don't assume - that ${newsrcdir}/configure.in does. - -Tue Jul 20 11:28:50 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * test-build.mk: support for CONFIG_SHELL - -Mon Jul 19 21:54:46 1993 Fred Fish (fnf@deneb.cygnus.com) - - * config.sub (netware): Add as a basic system type. - -Wed Jul 14 12:03:11 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * Makefile.in (Makefile): depend on configure.in. Also drop the - $(srcdir)/ from the dependency on Makefile.in. - -Tue Jul 13 20:10:58 1993 Doug Evans (dje@canuck.cygnus.com) - - * config.sub: Recognize h8300hhms as h8300h-hitachi-hms. - (h8300hhms is temporary until multi-libraries are implemented). - * configure.in: Handle h8300h too. - -Sun Jul 11 17:35:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Recognize dpx/2 as m68k-bull-sysv3. - -Thu Jul 8 18:26:12 1993 John Gilmore (gnu@cygnus.com) - - * configure: Remove extraneous output when guessing host type. - * config.guess: Remove extraneous output when guessing using C - compiler rather than uname, or when guessing fails. - -Wed Jul 7 17:58:14 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com) - - * Makefile.in: remove all.cross and install.cross targets - - * configure: remove CROSS=-DCROSS_COMPILE and ALL=all.cross - definitions - -Tue Jul 6 10:39:44 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * configure.in (target sh): Build gprof. - -Thu Jul 1 16:52:56 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config.sub: change -solaris to -solaris2 - -Thu Jul 1 15:46:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Use config/mh-riscos for mips-*-sysv*. - -Wed Jun 30 09:31:58 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure: Correct error message for missing Makefile.in to - print correct directory. - -Tue Jun 29 13:52:16 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * install.sh: kludge around 386BSD shell bug - -Tue Jun 29 13:06:49 1993 Per Bothner (bothner@rtl.cygnus.com) - - * config.guess: Recognize NeXT. - * config.guess: Recognize i486-ncr-sysv4. - * Makefile.in (taz): rm $(TOOL)-$$VER before linking. - -Tue Jun 29 12:50:57 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (MAKEINFOFLAGS): New variable. - (FLAGS_TO_PASS): Pass MAKEINFO as MAKEINFO MAKEINFOFLAGS. - * build-all.mk, test-build.mk: Pass down --no-split as - MAKEINFOFLAGS when hosted on DOS. Compile DOS hosted without -g. - -Thu Jun 24 13:39:11 1993 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in (DEVO_SUPPORT): Add COPYING COPYING.LIB install.sh. - -Wed Jun 23 12:59:21 1993 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in (libg++.tar.z): New rule. - * Makefile.in (taz): Replace 'configure -rm' by 'make distclean'. - * Makefile.in (taz): Only do a single chmod. - -Fri Jun 18 12:03:10 1993 david d `zoo' zuhn (zoo at majipoor.cygnus.com) - - * install.sh: don't use dirname anymore (replaced with sed usage) - -Thu Jun 17 18:43:42 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in: Change extension for gzip'd files from '.z' to - '.gz' per new FSF standard usage. - -Thu Jun 17 16:58:50 1993 david d `zoo' zuhn (zoo at majipoor.cygnus.com) - - * configure: put quotes around the final value of program_transform_name - -Tue Jun 15 16:48:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: new install.sh support; update install-info rules - -Wed Jun 9 12:31:34 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure.in: Build diff for crosses, but not for go32 host. - - * configure.in: Build gprof only for native, and don't build it - for mips-*-*, rs6000-*-*, or i[34]86-*-sco*. - -Mon Jun 7 13:12:11 1993 david d `zoo' zuhn (zoo at deneb.cygnus.com) - - * configure.in: don't build gas,ld,binutils on for *-*-sysv4 - -Mon Jun 7 11:40:11 1993 Brendan Kehoe (brendan@lisa.cygnus.com) - - * configure.in (host_tools): Add prms. - -Fri Jun 4 13:30:42 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: install gcc, do installation of $(INSTALL_MODULES) - with $(FLAGS_TO_PASS) on the command line - - * config.sub: Recognize lynx and lynxos - -Fri Jun 4 10:59:56 1993 Ian Lance Taylor (ian@cygnus.com) - - * config.sub: Accept -ecoff*, not just -ecoff. - -Thu Jun 3 17:38:54 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (taz): Use .gz suffix instead of .z. - (binutils.tar.gz, gas+binutils.tar.gz, gas.tar.gz): Fixed target - names. - -Thu Jun 3 00:27:06 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in (vault-install): add an 'else true' (for Ultrix) - -Wed Jun 2 18:19:16 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in (install-no-fixedincludes): install gcc last, so - that rebuilds that might happen during 'make install' don't get - bogus gcc include files - -Wed Jun 2 16:14:10 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - Change from Utah for HPPA support: - * config.guess: Recognize hppa1.x-hp-bsd. - -Wed Jun 2 11:53:33 1993 Per Bothner (bothner@rtl.cygnus.com) - - * config.guess: Add support for Motorola Delta 68k, up to r3v7. - Patch from pot@fly.cnuce.cnr.it (Francesco Potorti`). - -Tue Jun 1 17:48:42 1993 Rob Savoye (rob at darkstar.cygnus.com) - - * config.sub: Add support for rom68k and bug boot monitors. - -Mon May 31 09:36:37 1993 Jim Kingdon (kingdon@cygnus.com) - - * Makefile.in: Make all-opcodes depend on all-bfd. - -Thu May 27 08:05:31 1993 Ian Lance Taylor (ian@cygnus.com) - - * config.guess: Added special check for i[34]86-univel-sysv4*. - -Wed May 26 16:33:40 1993 Ian Lance Taylor (ian@cygnus.com) - - * config.guess: For i[34]86-unknown-sysv4 use UNAME_MACHINE for - the processor rather than assuming i486. - -Wed May 26 09:40:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.guess: Recognize SunOS6 as Solaris3. - -Tue May 25 23:03:11 1993 Per Bothner (bothner@cygnus.com) - - * config.guess: Fix typo. Avoid #elif (not in K&R 1). - Recognize SunOS 5.* only (and not [6-9].*) as being Solaris2. - -Tue May 25 12:44:18 1993 Ian Lance Taylor (ian@cygnus.com) - - * build-all.mk (all-cross): New target for Canadian Cross. - Added Q2 go32 targets. - * test-build.mk: Configure go32 cross sparclite-aout and - mips-idt-ecoff -with-gnu-ld. Moved build binary directory from - PARTIAL_HOLE_DIRS to BUILD_HOLES_DIRS. - -Mon May 24 15:30:06 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: fix Alpha GDB typo; also, don't build DejaGnu for - GO32 hosted toolchains - -Mon May 24 14:18:41 1993 Rob Savoye (rob at darkstar.cygnus.com) - - * configure: change so "-exec-prefix" gets passed down rather - than "-exec_prefix" so autoconf generated Makefiles get the - exec_prefix set right. - -Fri May 21 10:42:25 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config.guess: get the Solaris2 minor version number - - * Makefile.in: add standards.texi and make-stds.texi to ETC_SUPPORT - -Fri May 21 06:20:52 1993 Brendan Kehoe (brendan@lisa.cygnus.com) - - * config.guess: Recognize some Sequent platforms. - -Thu May 20 14:33:48 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: added the vault-install target - - * configure.in: actually use the Sun3 makefile fragment that's in - config, also added the release dir to configdirs - -Thu May 20 14:19:18 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (taz): Fix modes on stuff in $(TOOL) dir also. - -Tue May 18 20:26:41 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: remove some program from Alpha targetted toolchains - -Tue May 18 15:23:19 1993 Ken Raeburn (raeburn@cygnus.com) - - * Makefile.in (DISTSTUFFDIRS): Renamed from PROTODIRS. Add ld and - gprof. - (taz): Run "make diststuff" in those directories instead of "make - proto-dir". Look for "VERSION=" only at start of line in subdir - Makefile. Use "gzip -9" for compression. - (TEXINFO_SUPPORT, DIST_SUPPORT, BINUTILS_SUPPORT_DIRS): New vars. - (binutils.tar.z): New target. - -Mon May 17 17:01:15 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * Makefile.in (taz): Include gpl.texinfo. - -Fri May 14 06:48:38 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * Makefile.in (setup-dirs): Merged into "taz" target. - (taz): Only do `proto-dir' stuff if a directory is actually needed - for this target. - -Wed May 12 13:09:44 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (MUNCH_NM): New variable, defined to be $(NM). - (FLAGS_TO_PASS): Pass down MUNCH_NM. - (HOST_CC, HOST_PREFIX, HOST_PREFIX_1): New variables. - (EXTRA_GCC_FLAGS): Pass down HOST_* variables. - (gcc-no-fixedincludes): Correct for current gcc Makefile. - -Tue May 11 10:14:25 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (make-gdb.tar.Z): Add configure, config.guess, - config.sub, and move-if-change to gdb testsuite distribution - archive, so the testsuite can be extracted, configured, and - run separately from the gdb distribution. Blow away the Chill - tests that require a Chill compiled executable, since GNU Chill - is not yet publically available. - -Mon May 10 17:22:26 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * test-build.mk: set environment variables in a single command, - instead of a list of assignments and exports - - * config.guess: recognize Alpha/OSF1 systems - -Mon May 10 14:55:51 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * configure: Change help message to prefer --options rather than - -options. - -Mon May 10 05:58:35 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * config.sub: Convergent Tech. "miniframe" uses m68010, sez - zippy@ecst.csuchico.edu. - * config.guess: Recognize miniframe. - -Sun May 9 17:47:57 1993 Rob Savoye (rob at darkstar.cygnus.com) - - * Makefile.in: Use srcroot to find runtest rather than rootme. - Pass RUNTESTFLAGS and EXPECT down in BASE_FLAGS_TO_PASS. - -Fri May 7 14:55:59 1993 Ian Lance Taylor (ian@cygnus.com) - - * test-build.mk: Extensive additions to support building on a - machine other than the host. - -Wed May 5 08:35:04 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * configure (tooldir): Fix for i386-aix again. - -Mon May 3 19:00:27 1993 Per Bothner (bothner@cygnus.com) - - * configure, Makefile.in: Change definition of $(tooldir) - to match the FSF. - -Fri Apr 30 15:55:21 1993 Fred Fish (fnf@cygnus.com) - - * config.guess: Recognize i[34]86/SVR4. - -Fri Apr 30 15:52:46 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * Makefile.in (all-gdb): gdb depends on sim. - -Thu Apr 29 23:30:48 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (gdb.tar.Z): Make prototype gdb testsuite directory - at the same time we make the prototype gdb directory. - * Makefile.in (make-gdb.tar.Z): Make the testsuite distribution - files at the same time as the gdb base release distribution. - -Thu Apr 29 12:50:37 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (check): Use individual check targets rather than - DO_X rule. - (check-gcc): Added. - -Thu Apr 29 09:50:07 1993 Jim Kingdon (kingdon@cygnus.com) - - * config.sub: Use sysv3.2 not sysv32 for canonical OS - for System V release 3.2. - -Thu Apr 29 10:33:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * config.sub: Recognize hppaosf. - * configure.in: Do configure ld/binutils/gas for it. - -Tue Apr 27 06:25:34 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * configure (tooldir): Alter syntax used to set this, for systems - where "\$" isn't handled right, like i386-aix. - -Thu Apr 22 08:17:35 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure: Pass program-transform-name, not - program_transform_name, to recursive configures. - -Thu Apr 22 02:58:21 1993 Ken Raeburn (raeburn@cygnus.com) - - * Makefile.in (gas+binutils.tar.z): New rule for building snapshots - of gas+ld+binutils. - -Mon Apr 19 17:41:30 1993 Per Bothner (bothner@cygnus.com) - - * config.guess: Recognize AIX3.2 as distinct from 3.1. - -Sat Apr 17 17:19:50 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: rename m88k-motorola-m88kbcs to m88k-motorola-sysv - - * config/mh-delta88: remove extraneous GCC references - -Tue Apr 13 16:52:16 1993 Brendan Kehoe (brendan@lisa.cygnus.com) - - * Makefile.in (PRMS): Set back to all-prms. - -Sat Apr 10 12:04:07 1993 Ian Lance Taylor (ian@cygnus.com) - - * test-build.mk: Pass -with-gnu-as for known MIPS native and MIPS - targets, rather than for MIPS hosts. - -Fri Apr 9 13:51:06 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: add comment for --with-x default values - - * config.guess: handle Motorola Delta88 box for SVR3 and SVR4. - - * Makefile.in: add check-* targets for each of the directories in - the tree. Add a definition of RUNTEST that will use the one we - just built, if it exists. Pass this down via FLAGS_TO_PASS. - -Thu Apr 8 09:21:30 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure.in: Removed obsolete references to bfd_target and - target_makefile_frag. - - * build-all.mk: Set assorted targets for Q2. - * config.sub: Recognize z8k-sim and h8300-hms. - * test-build.mk: Really don't pass host to configure. - (HOLES): Added uname. - -Wed Apr 7 15:48:19 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure: Handle an empty program-prefix, program-suffix or - program-transform-name correctly. - -Tue Apr 6 13:48:41 1993 Ian Lance Taylor (ian@cygnus.com) - - * build-all.mk: -G 8 no longer required for MIPS targets. - * test-build.mk: Don't pass host argument to configure; make it - guess. - -Tue Apr 6 10:36:53 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (gdb.tar.Z): Fix for building gzip'd distribution. - * Makefile.in (COMPRESS): New macro, like GZIP. - -Fri Apr 2 09:02:31 1993 Ian Lance Taylor (ian@cygnus.com) - - * test-build.mk: Use -with-gnu-as for mips-sgi-irix4 as well. - - * build-all.mk: Set GCC to gcc -O -G 8 for MIPS targets, since gcc - with gas currently defaults to -G 0. - -Thu Apr 1 08:25:42 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (all-flex): flex depends on byacc. - - * build-all.mk: If host not specified, use config.guess. Pass TAG - to test-build.mk as RELEASE_TAG. - * test-build.mk (configargs): New variable containing arguments to - pass to configure. Set to -with-gnu-as on mips-dec-ultrix. - (FLAGS_TO_PASS): Pass down RELEASE_TAG. - - * config.guess: Use /bin/uname when checking -X argument on SCO, - to avoid invoking GNU uname which doesn't understand -X. - - * test-build.mk: Don't use /usr/unsupported/bin/as on AIX. - - * configure.in: Build gas for mips-*-*. - -Wed Mar 31 21:20:58 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in (all.normal): insert missing backslash. - -Wed Mar 31 12:31:56 1993 Ian Lance Taylor (ian@cygnus.com) - - * build-all.mk, config/mh-irix4: Bump -XNh value to 1500 to match - gcc requirements. - - * Makefile.in: Complete overhaul to merge many almost identical - targets. - -Tue Mar 30 20:17:01 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (setup-dirs-gdb): Renamed from setup-dirs. - (gdb.tar.Z): Adjusted. - - * Makefile.in (setup-dirs, taz): New targets; should be general - enough to adapt for gdb sometime. Build only .z file. - (gas.tar.z): New target. - -Tue Mar 30 10:03:09 1993 Ian Lance Taylor (ian@cygnus.com) - - * build-all.mk: Use CC=cc -Xs on Solaris. - -Mon Mar 29 19:59:26 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config/mh-sun3: cc needs -J to compile cp-parse.c correctly - - * config/mh-solaris: SunPRO C needs -Xs to be able to get a - working xmakefile for Emacs. - -Thu Mar 25 15:14:30 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in: Incorporate changes suggested by wilson@cygnus.com - for handling BISON for FSF releases. - -Thu Mar 25 06:19:48 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * configure: Actually implement the change zoo just documented. - -Wed Mar 24 13:02:44 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com) - - * configure: when using config.guess, only set target_alias when - it's not already been set (ie, on the command line) - -Mon Mar 22 23:07:39 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: add installcheck target, set PRMS to install-prms - -Sun Mar 21 16:46:12 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure: add support for package_makefile_fragment, handle the - case where a directory has a configure.in file but no Makefile.in - more gracefully (with an actual understandable error message, even); - add support for --without (and add this to the usage message); also - explicitly add a --host=${host_alias} to the command line when - config.guess is used - -Sun Mar 21 12:11:58 1993 Jim Wilson (wilson@sphagnum.cygnus.com) - - * configure: Must use both --host and --target in recursive calls. - -Thu Mar 18 12:31:35 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: Change deja-gnu to dejagnu. - -Mon Mar 15 15:44:35 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure.in (h8300-*-*, h8500-*-*): Don't build libg++. - -Fri Mar 12 18:30:14 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: canonicalize all instances to *-*-solaris2*, - also strip out a number of tools to not build for go32 host - -Wed Mar 10 12:08:27 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * config.guess: add GPL. - - * Makefile.in, config.guess, config.sub, configure: bump - copyrights to 93. - -Wed Mar 10 07:12:48 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (do-info): Removed obsolete check for existence of - localenv file. - - * Makefile.in (MAKEOVERRIDES): Define to be empty. - -Wed Mar 10 03:11:56 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: a couple of 'else true' for decstation, - support for TclX - - * configure.in: configure tclX too; don't remove Tk on RS/6000 anymore - -Tue Mar 9 16:06:12 1993 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in (setup-dirs): change invocation of make to $(MAKE). - -Mon Mar 8 14:52:11 1993 Ken Raeburn (raeburn@cambridge) - - * config.guess: Recognize i386-ibm-aix (PS/2). - * configure.in: Use config/mh-aix386 file for it. - -Mon Mar 8 11:12:43 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (GCC_FOR_TARGET): Eliminated definition; use - CC_FOR_TARGET instead. - (BASE_FLAGS_TO_PASS): Pass GCC_FOR_TARGET=$(CC_FOR_TARGET). - -Wed Mar 3 16:00:28 1993 Steve Chamberlain (sac@ok.cygnus.com) - - * Makefile.in: Add sim to list of directories sent with gdb - -Wed Mar 3 11:42:39 1993 Ken Raeburn (raeburn@cygnus.com) - - * configure.in: Put back mips-dec-bsd* case. - -Tue Mar 2 21:15:58 1993 Fred Fish (fnf@cygnus.com) - - (Ultrix 2.2 support from Michael Rendell ) - * configure.in (vax-*-ultrix2*): Add Ultrix 2.2 triplet. - * config.guess: Change 'VAX*:ULTRIX:*:*' to 'VAX*:ULTRIX*:*:*'. - * config/mh-vaxult2: New file. - -Tue Mar 2 18:11:03 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: remove no-op mips-dec-bsd* in "case $target" - - * Makefile.in (dir.info): only run gen-info-dir if it exists, - (install-info): install dir.info only if it exists, - (all-expect, install-expect): pass along X11_FLAGS_TO_PASS - -Tue Mar 2 09:01:30 1993 Ken Raeburn (raeburn@cygnus.com) - - * configure.in: For vms target, skip bfd, ld, binutils. Do build - gas for mips-dec-bsd. - -Tue Mar 2 08:35:24 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure (makesrcdir): If ${srcdir} is relative and not ".", - and ${subdir} is not ".", set makesrcdir based on ${invsubdir}. - -Tue Feb 23 14:18:28 1993 Mike Werner (mtw@poseidon.cygnus.com) - - * configure.in: Added "dejagnu" to hosttools list. - -Mon Feb 22 23:28:38 1993 Per Bothner (bothner@rtl.cygnus.com) - - * config.sub, configure.in, config.guess: Add support - for Bosx, an AIX variant from Bull. - Patches from F.Pierresteguy@frcl.bull.fr. - -Sun Feb 21 11:15:22 1993 Mike Werner (mtw@poseidon.cygnus.com) - - * devo/dejagnu: Initial creation of devo/dejagnu. - Migrated dejagnu testcases and support files for testing software - tools to reside as subdirectories, currently called "testsuite", - within the directory of the software tool. Migrated all programs, - support libraries, etc. beloging to dejagnu proper from - devo/deja-gnu to devo/dejagnu. These files were moved "as is" - with no modifications. The changes to these files which will - allow them to configure, build, and execute properly will be made - in a future update. - -Fri Feb 19 20:19:39 1993 Brendan Kehoe (brendan@lisa.cygnus.com) - - * Makefile.in: Change send_pr to send-pr. - * configure.in: Likewise. - * send_pr: Renamed directory to send-pr. - -Fri Feb 19 19:00:13 1993 Per Bothner (bothner@cygnus.com) - - * Makefile.in: Add some extra semi-colons (needed if SHELL=bash). - -Fri Feb 19 00:59:33 1993 John Gilmore (gnu@cygnus.com) - - * README: Update for gdb-4.8 release. - * Makefile.in (gdb.tar.Z): Add texinfo/tex3patch. Build - gdb-xxx.tar.z (gzip'd) file also. - -Thu Feb 18 09:16:17 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: make all-diff depend on all-libiberty - -Tue Feb 16 16:06:31 1993 K. Richard Pixley (rich@cygnus.com) - - * config.guess: add vax-ultrix in the spirit of mips-ultrix. - -Tue Feb 16 05:57:15 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in, Makefile.in: add hello, tar, gzip, recode, indent - -Tue Feb 16 00:58:20 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (DEVO_SUPPORT): Remove etc directory - (ETC_SUPPORT): Only add the files GDB wants from etc/. - (gdb.tar.Z): Use ETC_SUPPORT. Use byacc when building the file. - -Thu Feb 11 20:14:28 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: makeinfo binary is in a new location - -Tue Feb 9 12:42:27 1993 Ian Lance Taylor (ian@cygnus.com) - - * config.sub: Accept -ecoff as an OS. - - * Makefile.in: Various changes to eliminate a level of make - recursion and reduce the required command line length. - (BASE_FLAGS_TO_PASS): New variable holding flags passed to all - sub-makes. - (EXTRA_HOST_FLAGS, EXTRA_TARGET_FLAGS, EXTRA_GCC_FLAGS): New - variables holding settings for specific sub-makes. - (FLAGS_TO_PASS, TARGET_FLAGS_TO_PASS, GCC_FLAGS_TO_PASS): Rewrote - in terms of BASE_FLAGS_TO_PASS. - (TARGET_LIBS): New variable listing directories which use - TARGET_FLAGS_TO_PASS. - (subdir_do): Eliminated. - (do-*): New set of targets to replace subdir_do. - (various): All targets which used subdir_do now depend on do-*. - (local-clean): Renamed from do_clean. - (local-distclean): New target, dependency of distclean and - realclean. - (install-info): Don't create directories. Depend on dir.info - rather than calling make recursively. - (install-dir.info): Eliminated. - (install-info-dirs): Create all info directories here. - (dir.info): Depend upon do-install-info. - - * test-build.mk (HOLES): Added false. - -Sat Feb 6 14:05:09 1993 Per Bothner (bothner@rtl.cygnus.com) - - * config.guess: Recognize BSDI and BSDJ (Jolitz 386bsd). - -Thu Feb 4 20:49:18 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in (info): remove dependency on all-texinfo. The - problem was really in texinfo/C, not at this level. - -Thu Feb 4 13:38:41 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (info): Added dependency on all-texinfo (PR 2112). - -Thu Feb 4 01:50:53 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (make-gdb.tar.Z): Change BISON to 'bison -y' for - GDB releases. - -Wed Feb 3 17:22:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * configure: Include srcdir in message about target of link not - being found. Don't convert `-' to `_' in `with' options being - passed to subdirs. - -Tue Feb 2 18:57:59 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: add uudecode to host_tools - - * Makefile.in: added {all,install}-uudecode targets, added them to - the appropriate lists - -Tue Feb 2 11:45:53 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (all-gcc): Added dependency on all-gas. - - * configure.in (mips-*-*): Build ld and binutils. - -Mon Feb 1 12:35:41 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * configure: check return code from mkdir, print error message and - exit on failure. - -Sat Jan 30 16:40:28 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (make-gdb.tar.Z): New location for texinfo.tex. - -Thu Jan 28 15:09:59 1993 Ian Lance Taylor (ian@cygnus.com) - - * test-build.mk (HOLES): Added tar, cpio and uudecode. - -Wed Jan 27 16:50:32 1993 Jim Wilson (wilson@sphagnum.cygnus.com) - - * config.sub (h8500): Recognize this as a cpu type. - -Sat Jan 23 20:32:01 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure: source directory missing is no longer a warning - - * configure.in: recognize irix[34]* instead of irix[34] - - * Makefile.in: define and pass down X11_LIB - - * config/mh-sco: define X11_LIB to the mess that SCO ODT requires - -Sat Jan 23 13:49:40 1993 Per Bothner (bothner@cygnus.com) - - * guess-systype: Renamed to ... - * config.guess: ... by popular request. - * configure.in, Makefile.in: Update accordingly. - -Thu Jan 21 12:20:55 1993 Per Bothner (bothner@cygnus.com) - - * guess-systype: Patches from John Eaton : - + Add Convex, Cray/Unicos, and Encore/Multimax support. - + Execute ./dummy instead of assuming . is in PATH. - -Tue Jan 19 17:18:06 1993 Per Bothner (bothner@cygnus.com) - - * guess-systype: New shell script. Attempts to guess the - canonical host name of the executing host. - Only a few hosts are supported so far. - * configure: Call guess-systype if no host is specified. - -Tue Jan 19 08:26:07 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (gcc-no-fixedincludes): Made to work with current - gcc Makefile. - - -Fri Jan 15 10:27:02 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (GCC_FLAGS_TO_PASS): New variable. - (all-gcc, install-gcc, subdir_do): Use it. - -Wed Jan 13 17:06:45 1993 Jim Wilson (wilson@sphagnum.cygnus.com) - - * Makefile.in: Rename uninstalled gcc driver from gcc to xgcc. - -Wed Jan 6 20:29:16 1993 Mike Werner (mtw@rtl.cygnus.com) - - * Makefile.in: Removed explicit setting of SUBDIRS. SUBDIRS is now - set exclusively by configure, using configure.in . - -Wed Jan 6 13:44:11 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * test-build.mk: set $PATH for all builds - - * Makefile.in: pass TARGET_FLAGS_TO_PASS for xiberty and libm - -Wed Jan 6 11:02:10 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (GCC_FOR_TARGET): Supply a default that matches - the one used in gcc/Makefile.in, so that a null expansion doesn't - override the one needed to build gcc with a native cc. - - -Tue Jan 5 07:55:12 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * configure: Accept -with arguments. - -Sun Jan 3 15:15:09 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * Makefile.in: added h8300sim - -Tue Dec 29 15:06:00 1992 Ian Lance Taylor (ian@cygnus.com) - - * config/mh-sco: Don't override BISON definition. - - * build-all.mk: If canonhost is i386-unknown-sco3.2v4, change it - to i386-sco3.2v4. Set TARGETS and CFLAGS for i386-sco3.2v4. - (all-cygnus, native, build-cygnus): Make - $(canonhost)-stamp-3stage-done, not $(host).... - * test-build.mk (stamp-3stage-compared): Use tail +10c for - i386-sco3.2v4. Added else true to if command. - -Mon Dec 28 12:08:56 1992 Ken Raeburn (raeburn@cygnus.com) - - * config.sub: (from FSF) Sequent uses a BSD-like OS. - -Mon Dec 28 08:32:06 1992 Minh Tran-Le (mtranle@paris.intellicorp.com) - - * configure.in (i[34]86-*-isc*): added; uses mh-sysv. - -Thu Dec 24 17:26:24 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: don't remove binutils from Solaris builds - -Thu Dec 24 14:08:38 1992 david d`zoo' zuhn (zoo@cygnus.com) - - * Makefile.in: get rid of earlier definitions for *clean, - also handle the recursive info rule better - -Thu Dec 24 12:40:21 1992 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in (mostlyclean, distclean, realclean): Fix to - do more-or-less the right thing. - -Wed Dec 16 10:25:31 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: Add lines defining CC and CXX, and use CXX rather - than gcc in definitions of CXX_FOR_BUILD and CXX_FOR_TARGET. - -Tue Dec 15 00:34:32 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: change all $(host_cpu)-$(host_vendor)-$(host_os) to - $(host_canonical). - - * configure.in: split the configdirs list into 4 categories (native - v. cross, library v. tool) and handle the cross-only and native- - only in more reasonable (and correct!) way. - -Mon Dec 14 17:04:22 1992 Stu Grossman (grossman at cygnus.com) - - * configure.in (hppa*-*-*): Don't remove bfd and gdb from - configdirs anymore. - -Sun Dec 13 00:37:26 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: extensive cleanup:: removed all of the explicit - clean-* targets, collapsed many wrappers around subdir_do into - one, added additional targets to satisfy standards.texi, deleted - some old targets, some changes for consistency - -Fri Dec 11 20:18:02 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: handle some programs as cross-only, and others as - native only - - * test-build.mk: handle partial holes in a more generic manner - - * Makefile.in: m4 depends on libiberty - -Mon Dec 7 06:43:27 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config/mh-sco: don't default $(CC) to gcc - -Thu Dec 3 21:52:11 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: add m4, textutils, fileutils, sed, shellutils, - time, wdiff, and find to configdirs - - * Makefile.in: all, clean, and install rules for the new programs - added to configure.in - -Mon Nov 30 14:54:34 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: use mh-sun for all *-sun-* hosts - - * config/mh-solaris: rework standard X location to use - $OPENWINHOME, if defined. - - * config/mh-sun: handle X11 include locations - - * config/mh-decstation: define NeedFunctionPrototypes to 0, to - work around dain-bramaged DECwindows include files - -Fri Nov 27 18:35:54 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: define flags for X11 include files and library file - locations, pass them down to the programs that need this info - - * build-all.mk: added a 'native' target, to 3stage the native toolchain - - * config/{mh-hpux,mh-solaris}: define the "standard" locations for - the vendor supplied X11 headers and libraries - -Sun Nov 22 18:59:13 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: start building libg++ for HP-UX targets - -Wed Nov 18 19:33:11 1992 John Gilmore (gnu@cygnus.com) - - * README: Update references to files moved into etc/. - -Sun Nov 15 09:36:08 1992 Fred Fish (fnf@cygnus.com) - - * config.sub (i386sol2, i486sol2): i[34]86-unknown-solaris2. - * configure.in (i[34]86-*-solaris2*): Use config/mh-sysv4. - -Thu Nov 12 08:50:42 1992 Ian Lance Taylor (ian@cygnus.com) - - * configure: accept dash as well as underscore in long option - names for FSF compatibility. - -Wed Nov 11 08:04:37 1992 Ian Lance Taylor (ian@cygnus.com) - - * config.sub: added -sco3.2v4 support from FSF. - -Sun Nov 8 21:14:30 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: expand the section that adds or removes - directories from the list of programs to build, to handle native - vs. cross in addition to host v. native - -Sat Nov 7 18:52:27 1992 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in: Replace C++ in macro names with CXX. - This is less likely to break ... - -Sat Nov 7 15:16:58 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * test-build.mk: add -w to GNU_MAKE - -Fri Nov 6 23:10:37 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config.sub: remove 'sparc'-->'sparc-sun' default transformation, - add 'sparc' to list of recognized cpus. This needed to make - 'sparc-aout' expand to 'sparc-unknown-aout' instead of 'sparc-sun-aout'. - Delete some redundant ose68 variants. Recognize -wrs as an os, - then changes that into $CPU-wrs-vxworks. - - * configure.in: remove most references to gdbtest, regularize - target based program removal - - * test-build.mk: import from p3 tree (many fixes and changes) - -Fri Nov 6 20:59:00 1992 david d `zoo' zuhn (zoo@cygnus.com) - - * Makefile.in: added rules to handle tcl, tk, and expect - - * configure.in: handle those directories if they exist - -Thu Nov 5 14:35:41 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config.sub: removed bogus hppabsd and hppahpux names, since - "hppa" is not a valid cpu (hppa1.1 or hppa1.0 are, though) - -Thu Oct 29 00:12:41 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: all-gcc now depends on all-binutils. all-libg++ - depends upon all-xiberty - - * Makefile.in: changes from p3, including: - - Thu Oct 8 15:00:17 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (XTRAFLAGS): include newlib directories if - newlib/Makefile exists, rather than if host != target. - - Fri Sep 25 13:41:52 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: added -nostdinc to XTRAFLAGS if we are using gcc - from the same source tree and not building a cross-compiler. This - matters for the libg++ configuration if reconfiguring a tree that - has already been installed. - - Thu Sep 10 10:35:51 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: added -I for newlib/targ-include to XTRAFLAGS, to - pick up the machine and system specific header files. - - * Makefile.in: added AS_FOR_TARGET, passed down in - TARGET_FLAGS_TO_PASS. Added CC_FOR_BUILD, which is intended to be - the C compiler to use to create programs which are run in the - build environment, set it to default to $(CC), and passed it down - in FLAGS_TO_PASS and TARGET_FLAGS_TO_PASS. - - Mon Sep 7 22:34:42 1992 Ian Lance Taylor (ian@cirdan.cygnus.com) - - * Makefile.in: add $(host) = $(target) tests back to *_FOR_TARGET. - We need them for unusual native builds, like systems without - ranlib. - - * configure: also define $(host_canonical) and - $(target_canonical), which are the full, canonical names for the - given host and target - -Sun Nov 1 16:38:17 1992 Per Bothner (bothner@cygnus.com) - - * Makefile.in: Added separate definitions for C++. - -Fri Oct 30 11:37:52 1992 Fred Fish (fnf@cygnus.com) - - * configure.in (configdirs): Add deja-gnu. - -Fri Oct 23 00:39:18 1992 John Gilmore (gnu@cygnus.com) - - * README: Update for configure.texi and gdb-4.7 release. - -Wed Oct 21 21:54:27 1992 John Gilmore (gnu@cygnus.com) - - * Makefile.in: Move "all" target to top of file. - Previously, first target was ".PHONY" which caused BSD4.4 make - to build .PHONY when make was run without arguments. - -Mon Oct 19 01:17:54 1992 John Gilmore (gnu@cygnus.com) - - * Makefile.in: Add COPYING.LIB to GDB releases, now that there's - Library-copylefted code in libiberty. - -Tue Oct 13 01:22:32 1992 John Gilmore (gnu@cygnus.com) - - * config.sub: Replace m68kmote with plain old m68k. - -Fri Oct 9 03:14:24 1992 John Gilmore (gnu@cygnus.com) - - * Makefile.in: Remove space from blank line, avoid Make complaints. - -Thu Oct 8 18:41:45 1992 Ken Raeburn (raeburn@cygnus.com) - - * config.sub: Complain if no argument is given. Added support for - 386bsd as OS and target alias. - -Thu Oct 8 15:07:22 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (XTRAFLAGS): include newlib directories if - newlib/Makefile exists, rather than if host != target. - -Mon Oct 5 03:00:09 1992 Mark Eichin (eichin at tweedledumber.cygnus.com) - - * config.sub: recognize sparclite-wrs-vxworks. - - * Makefile.in (install-xiberty): added *-xiberty make rules (from - p3.) Added clean-xiberty to clean. - -Thu Oct 1 17:59:19 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: use *-*-* instead of nested cases for host and target - -Tue Sep 29 14:11:18 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: added -nostdinc to XTRAFLAGS if we are using gcc - from the same source tree and not building a cross-compiler. This - matters for the libg++ configuration if reconfiguring a tree that - has already been installed. - -Sep 20 08:53:10 1992 Fred Fish (fnf@cygnus.com) - - * config.sub (i486v/i486v4): Merge in from FSF version. - -Fri Sep 18 00:32:00 1992 Mark Eichin (eichin@cygnus.com) - - * configure: only set PWD if it is already set. - -Thu Sep 17 23:05:53 1992 Mark Eichin (eichin@cygnus.com) - - * configure: just set PWD=`pwd` at the top, since Ultrix sh - doesn't have unset and all success paths (and most error paths) - out set it anyway. (Note: should change all uses of ${PWD=`pwd`} - to just ${PWD} to avoid confusion.) - -Tue Sep 15 16:00:54 1992 Ian Lance Taylor (ian@cygnus.com) - - * configure: always set $(tooldir) to $(libdir)/$(target_alias), - even for a native compilation. - -Tue Sep 15 02:22:56 1992 John Gilmore (gnu@cygnus.com) - - Changes to make the gdb.tar.Z rule work better. - - * Makefile.in (GDB_SUPPORT_DIRS): Add opcodes. - (DEVO_SUPPORT): Add configure.texi. - (bfd-ilrt.tar.Z): Remove ancient rule. - -Thu Sep 10 10:43:19 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: added -I for newlib/targ-include to XTRAFLAGS, to - pick up the machine and system specific header files. - - * configure.in, config.sub: added new target m68010-adobe-scout, - with alias of adobe68k. Changed configure.in to check for - -scout before -sco* to avoid a false match. - - * Makefile.in: added AS_FOR_TARGET, passed down in - TARGET_FLAGS_TO_PASS. Added CC_FOR_BUILD, which is intended to be - the C compiler to use to create programs which are run in the - build environment, set it to default to $(CC), and passed it down - in FLAGS_TO_PASS and TARGET_FLAGS_TO_PASS. - -Wed Sep 9 12:21:42 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: added TARGET_FLAGS_TO_PASS, CC_FOR_TARGET, - AR_FOR_TARGET, RANLIB_FOR_TARGET, NM_FOR_TARGET. Pass - TARGET_FLAGS_TO_PASS, which defines CC, AR, RANLIB and NM as the - FOR_TARGET variants, to newlib and libg++. - -Tue Sep 8 17:28:30 1992 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (all-gas, all-gdb): Require all-opcodes to be built - first. - -Wed Sep 2 02:50:05 1992 John Gilmore (gnu@cygnus.com) - - * config.sub: Accept `elf' as an environment. - -Tue Sep 1 15:48:30 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * Makefile.in (all-opcodes): cd into the right directory - -Sun Aug 30 21:12:11 1992 Ian Lance Taylor (ian@cygnus.com) - - * configure: added -program_transform_name option, used as - argument to sed when installing programs. - configure.texi: added documentation for -program_prefix, - -program_suffix and -program_transform_name. - -Thu Aug 27 21:59:44 1992 John Gilmore (gnu@cygnus.com) - - * config.sub: Accept i486 where i386 ok. - -Thu Aug 27 13:04:42 1992 Brendan Kehoe (brendan@rtl.cygnus.com) - - * config.sub: accept we32k - -Mon Aug 24 14:05:14 1992 Ian Lance Taylor (ian@cygnus.com) - - * config.sub, configure.in: accept OSE68000 and OSE68k. - - * Makefile.in: don't create all directories for ``make install''; - let the subdirectories create the ones they need. - -Tue Aug 11 23:13:17 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * COPYING: new file, GPL v2 - -Tue Aug 4 01:12:43 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: use the new gen-info-dir, which needs a template - argument (which also lives in texinfo) - - * configure.texi, standards.texi: fix INFO-DIR-ENTRY - -Mon Aug 3 15:41:28 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config/mh-solaris: removed the -xs from CFLAGS (let the people - with Sun's C compiler deal with it themselved) - -Mon Aug 3 00:34:17 1992 Fred Fish (fnf@cygnus.com) - - * config.sub (ncr3000): Change i386 to i486. - -Thu Jul 23 00:12:17 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: add install-rcs, install-grep to - install-no-fixedincludes, removed install-bison and install-libgcc - -Tue Jul 21 01:01:50 1992 david d `zoo' zuhn (zoo@cygnus.com) - - * configure.in: grab the HPUX makefile fragment if on HPUX - -Mon Jul 20 11:02:09 1992 D. V. Henkel-Wallace (gumby@cygnus.com) - - * Makefile.in: eradicate bison spoor (ditto libgcc). - configure.in: recognise m68{k,000}-ericsson-OSE. - es1800 is alias for m68k-ericsson-OSE - -Sun Jul 19 17:49:02 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: rearrange the parts that remove programs from - configdirs, based now on HOST==TARGET or by canonical triple. - -Fri Jul 17 22:52:49 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * test-build.mk: recurse explicitly with -f test-build.mk when - appropriate. predicate stage3 and comparison on the existence - of gcc. That is, if gcc isn't around, we aren't three-staging. - On very clean, also remove ...stamp-co. Build in-place before - doing other builds. - -Thu Jul 16 18:33:09 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * Makefile.in, configure.in: add tgas - -Thu Jul 16 16:05:28 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in: a number of changes merged in from progressive. - - * configure.in: add libm. - - * .cvsignore: ignore some stuff that comes from test-build.mk. - -Wed Jul 8 00:01:30 1992 Stu Grossman (grossman at cygnus.com) - - * config/mh-solaris: Use -xs when compiling so that Sun-C puts - a symbol-table into the executable. - -Tue Jul 7 00:24:52 1992 Fred Fish (fnf@cygnus.com) - - * config.sub: Add es1800 (m68k-ericsson-es1800). - -Tue Jun 30 20:24:41 1992 D. V. Henkel-Wallace (gumby@cygnus.com) - - * configure: Add program_suffix (parallel to program_prefix) - * Makefile.in: adjust directory-creating script for losing decstation - -Mon Jun 22 23:43:48 1992 Per Bothner (bothner@cygnus.com) - - * configure: Minor $subdir-related fixes. - -Mon Jun 22 18:30:26 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * configure: fix various problems with propogating - makefile_target_frag in subdirs. - * configure.in: config libgcc if its there - -Fri Jun 19 15:19:40 1992 Stu Grossman (grossman at cygnus.com) - - * config.sub: HPPA merge. - -Mon Jun 15 12:31:52 1992 Fred Fish (fnf@cygnus.com) - - * config/mh-ncr3000 (INSTALL): Don't use /usr/ucb/install, - it is broken on ncr 3000's. - -Sun Jun 14 10:29:19 1992 John Gilmore (gnu at cygnus.com) - - * Makefile.in: Replace all-bison with all-byacc in all - dependency lines for other tools (which now use byacc). - -Fri Jun 12 22:21:57 1992 John Gilmore (gnu at cygnus.com) - - * config.sub: Add sun4sol2 => sparc-sun-solaris2. - -Tue Jun 9 17:18:11 1992 Fred Fish (fnf at cygnus.com) - - * config/{mh-ncr3000, mh-sysv4}: Add INSTALL. - -Thu Jun 4 12:07:32 1992 Mark Eichin (eichin@cygnus.com) - - * Makefile.in: make gprof rules similar to byacc rules (instead of - vestigal $(unsubdir) that didn't work...) - -Thu Jun 4 00:37:05 1992 Per Bothner (bothner@rtl.cygnus.com) - - * config.sub: Add support for Linux. - * Makefile.in: Use $(FLAGS_TO_PASS) more consistently - (at least for libg++). - -Tue Jun 02 20:03:00 1992 david d `zoo' zuhn (zoo@cygnus.com) - - * configure.texi: fix doc for the -nfp option to configure - -Tue Jun 2 17:20:52 1992 Michael Tiemann (tiemann@cygnus.com) - - * Makefile.in (all-binutils): ar needs flex, so depend on all-flex. - -Sun May 31 15:04:08 1992 Mark Eichin (eichin at cygnus.com) - - * config.sub: changed [^-]+ to [^-][^-]* so that it works under - Sun sed. (BSD 4.3 sed doesn't handle [^-]+ either.) - * configure.in: added solaris* host_makefile_frag hook. - -Sun May 31 01:10:34 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config.sub: changed recognition of m68000 so that various - m68k types can be specified via m680[01234]0 - -Sat May 30 21:01:06 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config.sub (basic_machine): fix sed so that '-foo' isn't - completely substituted out while .+'-foo' loses the '-foo' - -Wed May 27 23:18:52 1992 Michael Tiemann (tiemann@rtl.cygnus.com) - - * config.sub ($os): Add -aout. - -Fri May 22 14:00:02 1992 Per Bothner (bothner@cygnus.com) - - * configure: If host_makefile_frag is absolute, don't - prefix ${invsubdir} (relevant to libg++ auto-configure). - -Thu May 21 18:00:09 1992 Michael Tiemann (tiemann@rtl.cygnus.com) - - * Makefile.in (tooldir): Define it. - (all-ld): Depend on all-flex. - -Sun May 10 21:45:59 1992 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in (check): Fix libg++ special case. - -Fri May 8 08:31:41 1992 K. Richard Pixley (rich@cygnus.com) - - * configure: do not bury `pwd` into config.status, thus do fewer - pwd's. - - * configure: print the "Building in" message only when building in - other than "." AND verbose. - - * configure: remove -s, rework -v to better accomodate guested - configures. - - * standards.texi: updated to 3 may, fixed librid <-> libdir typo. - -Fri May 1 18:00:50 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: macroize flags passed on recursion. remove - fileutils. - -Thu Apr 30 08:56:20 1992 K. Richard Pixley (rich@cygnus.com) - - * configure: get makesrcdir right for subdirs deeper than 1. - - * Makefile.in: pass INSTALL, INSTALL_DATA, INSTALL_PROGRAM on - install. - -Fri Apr 24 15:51:51 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: don't print subdir_do or recursion lines. - -Fri Apr 24 15:22:04 1992 K. Richard Pixley (rich@cygnus.com) - - * standards.texi: added menu item. - - * Makefile.in: build and install standards.info. - - * standards.texi: new file. - -Wed Apr 22 18:06:55 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * configure: test for and move config.status pieces from - ${subdir}/. - -Wed Apr 22 14:38:34 1992 Fred Fish (fnf@cygnus.com) - - * config/mh-delta88, config/mh-ncr3000: Replace MINUS_G with - CFLAGS per new configuration strategy. - * configure: Test for existance of files before trying to mv - them, to avoid numerous non-existance messages. - -Tue Apr 21 12:31:33 1992 K. Richard Pixley (rich@cygnus.com) - - * configure: correct final line of config.status. - - * configure: patch from eggert. Avoids a protection problem if - the original Makefile.in is read only. - - * configure: use move-if-change from gcc to create config.status. - Some makefiles depend on config.status to tell if a directory - has been reconfigured for a different host. This change - prevents those directories from remaking everything in the case - where the reconfig was only intended to rebuild a Makefile. - - * configure: test for config.sub with "config.sub sun4" rather - than "config.sub ${host_alias}". Otherwise we can't tell a bad - host alias from a missing config.sub. - -Mon Apr 20 18:16:36 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in: explicitly pass CFLAGS on recursion. no longer pass - MINUS_G (this can be done with CFLAGS). Default CFLAGS to -g. - -Fri Apr 17 18:27:51 1992 Per Bothner (bothner@cygnus.com) - - * configure: mkdir ${subdir} as needed. - -Wed Apr 15 17:37:22 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in,configure.in: added autoconf. - -Wed Apr 15 17:27:34 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in: no longer pass against on recursion. - - * Makefile.in: added .NOEXPORT: so that stray makefile_frag - definitions are not inherited. - - * configure: correct makesrcdir when subdir is . - -Tue Apr 14 11:56:09 1992 Per Bothner (bothner@cygnus.com) - - * configure: Add support for 'subdirs' variable, which is - like 'configdirs', except that configure doesn't re-invoke - itself for subdirs, it just creates a Makefile for each subdir. - * configure.texi: Document subdirs. - -Mon Apr 13 18:50:16 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: added flex to configdirs - -Mon Apr 13 18:43:55 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: remove clean-stamps from clean. - -Sat Apr 11 03:52:03 1992 John Gilmore (gnu at cygnus.com) - - * configure.in: Add gdbtest to configdirs. - -Fri Apr 10 23:11:49 1992 Fred Fish (fnf@cygnus.com) - - * Makefile.in (MINUS_G): Add macro, default to -g, pass on - to recursive makes. - * configure.in: Recognize new ncr3000 config. - -Wed Apr 8 23:08:12 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed references to gdbm. - -Tue Apr 7 16:48:20 1992 Per Bothner (bothner@cygnus.com) - - * config.sub: Don't canonicalize os value - newsos* to bsd (readline needs to check for newsos). - (This fix was earlier made Jan 31, but got re-broken.) - -Mon Apr 6 14:34:08 1992 Stu Grossman (grossman at cygnus.com) - - * configure.in: sco is an os, not a vendor! - - * configure: Quote $( better. Keep various shells happy. - -Tue Mar 31 16:32:57 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: eliminate stamp-files. - -Mon Mar 30 22:20:23 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: add send_pr. remove "force" from .stmp-gprof rule. - Supress echoing of all the "if [ -d ... $(MAKE)" lines. - -Wed Mar 25 15:20:04 1992 Stu Grossman (grossman@cygnus.com) - - * config.sub: fix iris/iris3. - -Wed Mar 25 10:34:19 1992 K. Richard Pixley (rich@cygnus.com) - - * configure: re-add -rm. - -Tue Mar 24 23:50:16 1992 K. Richard Pixley (rich@cygnus.com) - - * Maskefile.in: add .stmp-rcs to all. - - * configure.in: remove gas from rs6000 build, use aix host fragment. - -Mon Mar 23 19:43:35 1992 K. Richard Pixley (rich@cygnus.com) - - * configure: pass down site_option during recursion. - -Thu Mar 19 16:49:36 1992 Stu Grossman (grossman at cygnus.com) - - * Makefile.in (all.cross): Add .stmp-bfd .stmp-readline. - -Wed Mar 18 15:29:33 1992 Mike Stump (mrs@cygnus.com) - - * configure: Change exec_prefix so that it really defaults to prefix. - -Sat Mar 14 17:20:38 1992 Fred Fish (fnf@cygnus.com) - - * Makefile.in, configure.in: Add support for mmalloc library. - -Fri Mar 13 18:44:18 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: add stmp dependencies for a few more things. - -Thu Mar 12 04:56:24 1992 K. Richard Pixley (rich@cygnus.com) - - * configure: adjusted error message on objdir/srcdir configure - collision, per john's suggestion. - - * Makefile.in: add libiberty stmp to all and all.cross. - -Wed Mar 11 02:07:52 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: remove force dependencies, add grep to all. - -Tue Mar 10 21:49:18 1992 K. Richard Pixley (rich@mars.cygnus.com) - - * Makefile.in: drop flex. make stamp files work. - - * configure: added test for conflicting configuration in srcdir, - remove trailing slashes from srcdir. Otherwise emacs gdb mode - gets cranky. use relative paths for configure and srcdir - whenever possible. Send some error messages to stderr that were - going to stdout. - -Tue Mar 10 18:01:55 1992 Per Bothner (bothner@cygnus.com) - - * Makefile.in: Fix libg++ rule to check for gcc directory - before using gcc/gcc. Also pass XTRAFLAGS. - -Thu Mar 5 21:45:07 1992 K. Richard Pixley (rich@sendai) - - * Makefile.in: added stmp-files so that directories aren't polled - when they are already built. - - * configure.texi: fixed a node pointer problem. - -Thu Mar 5 12:05:58 1992 Stu Grossman (grossman at cygnus.com) - - * config.sub configure.in config/mh-irix4 gdb/configure.in - gdb/mips-tdep.c gdb/mipsread.c gdb/procfs.c gdb/signame.h - gdb/tm-irix3.h gdb/tm-mips.h gdb/xm-irix4.h gdb/config/mt-irix3 - gdb/config/mh-irix4 texinfo/configure.in: Port to SGI Irix-4.x. - -Wed Mar 4 02:57:46 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * configure: -recurring becomes -silent. corrected help message - for -site= option. - - * Makefile.in: mkdir $(exec_prefix) and $(tooldir). - -Tue Mar 3 14:51:21 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * configure: when building Makefile for crosses, replace - tooldir and program_prefix. default srcdir from location of - config.sub. remove "for host in hosts" and "for target in - targets" loops. - -Wed Feb 26 19:48:25 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in: Do not pass bindir or mandir to cvs. - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - - * configure.texi: remove most references to multiple hosts, - multiple targets, subdirs, etc. - - * configure.man: removed rcsid. reference config.sub not - config.subr. - - * Makefile.in: mkdir $(infodir) on install-info. - -Wed Feb 19 15:41:13 1992 John Gilmore (gnu at cygnus.com) - - * configure.texi: Explain better about .gdbinit and about - the environment that configure.in sections run in. - -Fri Feb 7 07:55:00 1992 John Gilmore (gnu at cygnus.com) - - * configure.in: Ultrix is only a decstation if it's a MIPS. - -Fri Jan 31 21:54:51 1992 John Gilmore (gnu at cygnus.com) - - * README: DOC.configure => cfg-paper.texi. - -Fri Jan 31 21:48:18 1992 Stu Grossman (grossman at cygnus.com) - - * config.sub (near case $os): Don't convert newsos* to bsd! - -Fri Jan 31 02:27:32 1992 John Gilmore (gnu at cygnus.com) - - * Makefile.in: Reinstall change from gdb-4.3 that reduces - the number of copies of COPYING that go into the GDB tar file. - -Thu Jan 30 16:17:30 1992 Stu Grossman (grossman at cygnus.com) - - * bfd/configure.in, config/mh-sco, gdb/config/mh-i386sco, - gdb/config/mt-i386v32, gdb/configure.in, readline/configure.in: - Fix SCO configuration stuff. - -Tue Jan 28 23:51:07 1992 Per Bothner (bothner at cygnus.com) - - * Makefile.in: For libg++, make sure the -I pointing - to the gcc directory goes *after* all the libg++-local -I flags. - Also, move just-gcc dependency from just-libg++ to all-libg++. - -Tue Jan 28 12:56:24 1992 Stu Grossman (grossman at cygnus.com) - - * configure: Change -x to -f to keep Ultrix /bin/test happy. - -Sat Jan 18 17:45:11 1992 Stu Grossman (grossman at cygnus.com) - - * Makefile.in (make-gdb.tar.Z): Remove texinfo targets. - -Sat Jan 18 17:03:21 1992 Fred Fish (fnf at cygnus.com) - - * config.sub: Add stratus configuration frags. Also - submitted to FSF. - -Sat Jan 18 15:35:29 1992 Stu Grossman (grossman at cygnus.com) - - * Makefile.in (DEV_SUPPORT): add configure.man. - - * config.sub(Decode manufacturer-specific): add -none*. - -Fri Jan 17 17:58:05 1992 Stu Grossman (grossman at cygnus.com) - - * Makefile.in: remove form feeds to make Sun's make happy. - (DEVO_SUPPORT): DOC.configure => cfg-paper.texi. - -Sat Jan 4 16:11:44 1992 John Gilmore (gnu at cygnus.com) - - * Makefile.in (AR_FLAGS): Make quieter. - -Thu Jan 2 22:57:12 1992 John Gilmore (gnu at cygnus.com) - - * configure.in: Add libg++. - * configure: When verbose, don't output the command line at each - level; it will be unremarkably the same as the previous version, - which will be the same as what the user typed. - -Fri Dec 27 16:26:47 1991 K. Richard Pixley (rich at cygnus.com) - - * configure.in, Makefile.in: fix clean-info, add flex. add - fileutils. - - * configure: be less sensitive to spaces in Makefile.in. Do not - look for sources in "..". Doing so breaks subdirectories that - might have their own configure. If a subdir has it's own - configure script, use it. - -Thu Dec 26 16:30:26 1991 K. Richard Pixley (rich at cygnus.com) - - * cfg-paper.texi: some changes suggested by rms. - -Thu Dec 26 10:13:36 1991 Fred Fish (fnf at cygnus.com) - - * config.sub: Merge in some small additions from the FSF version, - taken from the gcc distribution, to bring the Cygnus and FSF - versions into closer sync. - -Fri Dec 20 11:34:18 1991 Fred Fish (fnf at cygnus.com) - - * configure.in: Changed svr4 references to sysv4. - -Thu Dec 19 15:54:29 1991 K. Richard Pixley (rich at cygnus.com) - - * configure: added -V for version number option. - -Wed Dec 18 15:39:34 1991 K. Richard Pixley (rich at cygnus.com) - - * DOC.configure, cfg-paper.texi: revised, updated, and texinfo'd. - renamed from DOC.configure to cfg-paper.texi. - -Mon Dec 16 23:05:19 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * configure, config.subr, config.sub: config.subr is now - config.sub again. - -Fri Dec 13 01:17:06 1991 K. Richard Pixley (rich at cygnus.com) - - * configure.texi: new file, in progress. - - * Makefile.in: build info file and install the man page for - configure. - - * configure.man: new file, first cut. - - * configure: find config.subr again now that configuration "none" - has gone. removed all traces of the -ansi option. removed all - traces of the -languages option. - - * config.subr: resync from rms. - -1991-12-11 K. Richard Pixley (rich at rtl.cygnus.com) - - * configure, config.sub, config.subr: merge config.sub into - config.subr, call the result config.subr, remove config.sub, use - config.subr. - - * Makefile.in: revised install for dir.info. - -1991-12-10 K. Richard Pixley (rich at rtl.cygnus.com) - - * configure.in: add decstation host makefile frag. - - * Makefile.in: BISON now bison -y again. also install-gcc on - install. clean-gdbm on clean. infodir belongs in datadir. - Make directories for info install. Build dir.info here then - install it. - -1991-12-09 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: fix for bad directory tests. - -1991-12-07 K. Richard Pixley (rich at rtl.cygnus.com) - - * configure: \{1,2\} appears to be a sysv'ism. Use a different - regexp. -srcdir relative was being handled incorrectly. - - * Makefile.in: unwrapped some for loops so that parallel makes - work again and so one can focus one's attention on a particular - package. - -1991-12-06 K. Richard Pixley (rich at rtl.cygnus.com) - - * configure: added PWD as a stand in for `pwd` (for speed). use - elif wherever possible. make -srcdir work without -objdir. - -objdir= commented out. - -1991-12-05 K. Richard Pixley (rich at rtl.cygnus.com) - - * configure: +options become --options. -subdirs commented out. - added -host, -datadir. Renamed -destdir to -prefix. Comment in - Makefile now at top of generated Makefile. Removed cvs log - entries. added -srcdir. create .gdbinit only if there is one - in ${srcdir}. - - * Makefile.in: idestdir and ddestdir go away. Added copyrights - and shift gpl to v2. Added ChangeLog if it didn't exist. docdir - and mandir now keyed off datadir by default. - -1991-11-22 K. Richard Pixley (rich at rtl.cygnus.com) - - * Freshly created ChangeLog. - - -Local Variables: -mode: change-log -left-margin: 8 -fill-column: 76 -version-control: never -End: diff --git a/contrib/gdb/MAINTAINERS b/contrib/gdb/MAINTAINERS deleted file mode 100644 index 75f32405314..00000000000 --- a/contrib/gdb/MAINTAINERS +++ /dev/null @@ -1,114 +0,0 @@ -Please feel free to add, edit, delete this file. -Please do not make ChangeLog entries. - -COPYING, COPYING.LIB, README - http://gnu.org. - -Makefile.in; configure; configure.in - Please notify the following of any committed patches. - binutils@sources.redhat.com - gdb-patches@sources.redhat.com - -bfd/; binutils/; gas/; gprof/; ld/; opcodes/; BFD's part of include/ - binutils: http://sources.redhat.com/binutils/ - Patches to binutils@sources.redhat.com. - Please notify the following of any interface changes: - gdb-patches@sources.redhat.com - -cgen/; cgen parts of opcodes/, sim/ & include/ - cgen: http://sources.redhat.com/cgen/ - Patches to cgen@sources.redhat.com - May need separate opcodes/ or sim/ approval for - commits of regenerated files there. - -config.guess; config.sub; dejagnu/config.guess; -readline/support/config.sub; readline/support/config.guess - config: http://savannah.gnu.org/projects/config - Patches to config-patches@gnu.org. - Changes need to be done in tandem with the official CONFIG - sources or submitted to the master file maintainer and brought - in via a merge. - Please notify the following of any committed patches: - binutils@sources.redhat.com - gdb-patches@sources.redhat.com - -dejagnu/ - Notify http://dejagnu.sourceforge.net/ of generic changes. - Generic patches to gdb-patches@sources.redhat.com; - Other dependents of dejagnu include sid@, binutils@, gcc@, etc. - -gdb/; mmalloc/; readline/; sim/; GDB's part of include/ & dejagnu/ - gdb: http://sources.redhat.com/gdb/ - Patches to gdb-patches@sources.redhat.com. - See also gdb/MAINTAINERS, sim/MAINTAINERS, mmalloc/MAINTAINERS. - -include/ - See binutils/, gdb/, sid/, gcc/, libiberty/ etc. - -libiberty/; libiberty's part of include/ - gcc: http://gcc.gnu.org - Changes need to be done in tandem with the official GCC - sources or submitted to the master file maintainer and brought - in via a merge. Note: approved patches in gcc's libiberty - are automatically approved in this libiberty also; feel free - to merge them yourself if needed sooner than the next merge. - Otherwise, changes are automatically merged, usually within - a day. - -ltconfig; ltmain.sh - libtool: http://gnu.org - Changes need to be done in tandem with the official LIBTOOL - sources or submitted to the master file maintainer and brought - in via a merge. - -mkinstalldirs; move-if-change - autoconf: http://gnu.org - Patches to autoconf-patches@gnu.org. - Changes need to be done in tandem with the official AUTOCONF - sources or submitted to the master file maintainer and brought - in via a merge. - -symlink-tree - gcc: http://gcc.gnu.org - See libiberty. - -newlib/; libgloss/ - http://sources.redhat.com/newlib/ - Patches to newlib@sources.redhat.com. - -sid/; SID's part of cgen/ & dejagnu/ - sid: http://sources.redhat.com/sid/ - Patches to sid@sources.redhat.com - -texinfo/texinfo.tex - texinfo: http://ftp.gnu.org. - Latest version can be found on ftp://ftp.gnu.org and can be - imported at any (reasonable) time. - Please not use GCC's texinfo. Please do not import texinfo. - -tcl/; tix/; itcl/; tk/; libgui/ - insight: http://sources.redhat.com/insight/ - Contact insight@sources.redhat.com. - -winsup/ - cygwin: http://sources.redhat.com/cygwin - Patches to cygwin-patches@sources.redhat.com. - General discussion cygwin@sources.redhat.com. - See also winsup/MAINTAINERS. - -expect/; config-ml.in; mpw-README; mpw-build.in; mpw-config.in; -mpw-configure; mpw-install; setup.com; missing; makefile.vms; utils/; -config/; config.if; makefile.vms; missing; ylwrap; mkdep; etc/; -install-sh; intl/ - Ask DJ Delorie after reading the libiberty entry. - -modules file - Obviously changes to this file should not go through - overseers@sources.redhat.com. If you understand the file - format (or can cut-and-paste existing entries), modify it. If - it scares you, get someone who does understand it to help you. - Be prepared to fix it if you do break it. - -/* Local variables: */ -/* change-log-default-name: "/dev/null" */ -/* End: */ diff --git a/contrib/gdb/bfd/COPYING b/contrib/gdb/bfd/COPYING deleted file mode 100644 index a43ea2126fb..00000000000 --- a/contrib/gdb/bfd/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/contrib/gdb/bfd/Makefile.in b/contrib/gdb/bfd/Makefile.in deleted file mode 100644 index e531cf85dc5..00000000000 --- a/contrib/gdb/bfd/Makefile.in +++ /dev/null @@ -1,1090 +0,0 @@ -# Makefile template for Configure for the BFD library. -# Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 -# Free Software Foundation, Inc. -# Written by Cygnus Support. -# -# This file is part of BFD, the Binary File Descriptor library. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -VPATH = @srcdir@ -srcdir = @srcdir@ - -prefix = @prefix@ - -program_transform_name = @program_transform_name@ -exec_prefix = @exec_prefix@ -bindir = $(exec_prefix)/bin -libdir = $(exec_prefix)/lib - -datadir = $(prefix)/lib -mandir = $(prefix)/man -man1dir = $(mandir)/man1 -man2dir = $(mandir)/man2 -man3dir = $(mandir)/man3 -man4dir = $(mandir)/man4 -man5dir = $(mandir)/man5 -man6dir = $(mandir)/man6 -man7dir = $(mandir)/man7 -man8dir = $(mandir)/man8 -man9dir = $(mandir)/man9 -infodir = $(prefix)/info -includedir = $(prefix)/include -oldincludedir = -docdir = doc - -SHELL = /bin/sh - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ - -AR = @AR@ -AR_FLAGS = rc -CC = @CC@ -CFLAGS = @CFLAGS@ -MAKEINFO = makeinfo -RANLIB = @RANLIB@ - -ALLLIBS = @ALLLIBS@ - -PICFLAG = @PICFLAG@ -SHLIB = @SHLIB@ -SHLIB_CC = @SHLIB_CC@ -SHLIB_CFLAGS = @SHLIB_CFLAGS@ -COMMON_SHLIB = @COMMON_SHLIB@ -SHLINK = @SHLINK@ - -SONAME = lib`echo $(SHLIB) | sed -e 's/^lib//' | sed '$(program_transform_name)'` - -CC_FOR_BUILD = @CC_FOR_BUILD@ - -INCDIR = $(srcdir)/../include -CSEARCH = -I. -I$(srcdir) -I$(INCDIR) -DEP = mkdep - -SUBDIRS = doc - -TARGETLIB = libbfd.a - -# bfd.h goes here, for now -BFD_H = bfd.h - -# Some of these files should be in BFD*_BACKENDS below, but some programs -# won't link without them. So, in order for some of the minimal-bfd -# hacks to work, they're also included here for now. -# gdb: elf.o -# objdump: elf.o -# -# Also, Jim Kingdon notes: -# Writing S-records should be included in all (or at least most) -# *-*-coff, *-*-aout, etc., configurations, because people will want to -# be able to use objcopy to create S-records. (S-records are not useful -# for the debugger, so if you are downloading things as S-records you -# need two copies of the executable, one to download and one for the -# debugger). -BFD_LIBS = \ - archive.o archures.o bfd.o cache.o coffgen.o corefile.o \ - format.o init.o libbfd.o opncls.o reloc.o \ - section.o syms.o targets.o hash.o linker.o \ - elf.o srec.o binary.o tekhex.o ihex.o stab-syms.o - -BFD_LIBS_CFILES = \ - archive.c archures.c bfd.c cache.c coffgen.c corefile.c \ - format.c init.c libbfd.c opncls.c reloc.c \ - section.c syms.c targets.c hash.c linker.c \ - elf.c srec.c binary.c tekhex.c ihex.c stab-syms.c - -# This list is alphabetized to make it easier to keep in sync -# with the decls and initializer in archures.c. -ALL_MACHINES = \ - cpu-a29k.o \ - cpu-alpha.o \ - cpu-arm.o \ - cpu-h8300.o \ - cpu-h8500.o \ - cpu-hppa.o \ - cpu-i386.o \ - cpu-i860.o \ - cpu-i960.o \ - cpu-m68k.o \ - cpu-m88k.o \ - cpu-mips.o \ - cpu-ns32k.o \ - cpu-powerpc.o \ - cpu-rs6000.o \ - cpu-sh.o \ - cpu-sparc.o \ - cpu-vax.o \ - cpu-we32k.o \ - cpu-w65.o \ - cpu-z8k.o - -ALL_MACHINES_CFILES = \ - cpu-a29k.c \ - cpu-alpha.c \ - cpu-arm.c \ - cpu-h8300.c \ - cpu-h8500.c \ - cpu-hppa.c \ - cpu-i386.c \ - cpu-i860.c \ - cpu-i960.c \ - cpu-m68k.c \ - cpu-m88k.c \ - cpu-mips.c \ - cpu-ns32k.c \ - cpu-powerpc.c \ - cpu-rs6000.c \ - cpu-sh.c \ - cpu-sparc.c \ - cpu-vax.c \ - cpu-we32k.c \ - cpu-w65.c \ - cpu-z8k.c - -# The .o files needed by all of the 32 bit vectors that are configured into -# target_vector in targets.c if configured with --enable-targets=all. -BFD32_BACKENDS = \ - aout-adobe.o \ - aout-ns32k.o \ - aout0.o \ - aout32.o \ - bout.o \ - cf-i386lynx.o \ - cf-m68klynx.o \ - cf-sparclynx.o \ - coff-a29k.o \ - coff-apollo.o \ - coff-arm.o \ - coff-aux.o \ - coff-h8300.o \ - coff-h8500.o \ - coff-i386.o \ - coff-go32.o \ - coff-i860.o \ - coff-i960.o \ - coff-m68k.o \ - coff-m88k.o \ - coff-mips.o \ - coff-pmac.o \ - coff-rs6000.o \ - coff-sh.o \ - coff-sparc.o \ - coff-u68k.o \ - coff-we32k.o \ - coff-w65.o \ - coff-z8k.o \ - cofflink.o \ - ecoff.o \ - ecofflink.o \ - elf32-gen.o \ - elf32-hppa.o \ - elf32-i386.o \ - elf32-i860.o \ - elf32-m68k.o \ - elf32-m88k.o \ - elf32-mips.o \ - elf32-ppc.o \ - elf32-sparc.o \ - elf32.o \ - elflink.o \ - hp300hpux.o \ - som.o \ - i386aout.o \ - i386bsd.o \ - i386freebsd.o \ - i386linux.o \ - i386lynx.o \ - i386msdos.o \ - i386netbsd.o \ - i386mach3.o \ - i386os9k.o \ - ieee.o \ - m68klinux.o \ - m68klynx.o \ - m68knetbsd.o \ - m88kmach3.o \ - mipsbsd.o \ - newsos3.o \ - nlm.o \ - nlm32-i386.o \ - nlm32-sparc.o \ - nlm32-ppc.o \ - nlm32.o \ - ns32knetbsd.o \ - oasys.o \ - pc532-mach.o \ - pe-arm.o \ - pei-arm.o \ - pe-i386.o \ - pei-i386.o \ - pe-ppc.o \ - pei-ppc.o \ - reloc16.o \ - sparclynx.o \ - sparcnetbsd.o \ - sunos.o \ - tekhex.o \ - versados.o \ - xcofflink.o - -BFD32_BACKENDS_CFILES = \ - aout-adobe.c \ - aout-ns32k.c \ - aout0.c \ - aout32.c \ - bout.c \ - cf-i386lynx.c \ - cf-m68klynx.c \ - cf-sparclynx.c \ - coff-a29k.c \ - coff-apollo.c \ - coff-arm.c \ - coff-aux.c \ - coff-h8300.c \ - coff-h8500.c \ - coff-i386.c \ - coff-i860.c \ - coff-go32.c \ - coff-i960.c \ - coff-m68k.c \ - coff-m88k.c \ - coff-mips.c \ - coff-pmac.c \ - coff-rs6000.c \ - coff-sh.c \ - coff-sparc.c \ - coff-u68k.c \ - coff-we32k.c \ - coff-w65.c \ - coff-z8k.c \ - cofflink.c \ - ecoff.c \ - ecofflink.c \ - elf32-gen.c \ - elf32-hppa.c \ - elf32-i386.c \ - elf32-i860.c \ - elf32-m68k.c \ - elf32-m88k.c \ - elf32-mips.c \ - elf32-ppc.c \ - elf32-sparc.c \ - elf32.c \ - elflink.c \ - hp300hpux.c \ - som.c \ - i386aout.c \ - i386bsd.c \ - i386freebsd.c \ - i386linux.c \ - i386lynx.c \ - i386msdos.c \ - i386netbsd.c \ - i386mach3.c \ - i386os9k.c \ - ieee.c \ - m68klinux.c \ - m68klynx.c \ - m68knetbsd.c \ - m88kmach3.c \ - mipsbsd.c \ - newsos3.c \ - nlm.c \ - nlm32-i386.c \ - nlm32-sparc.c \ - nlm32-ppc.c \ - nlm32.c \ - ns32knetbsd.c \ - oasys.c \ - pc532-mach.c \ - pe-arm.c \ - pei-arm.c \ - pe-i386.c \ - pei-i386.c \ - pe-ppc.c \ - pei-ppc.c \ - reloc16.c \ - sparclynx.c \ - sparcnetbsd.c \ - sunos.c \ - tekhex.c \ - versados.c \ - xcofflink.c - -# The .o files needed by all of the 64 bit vectors that are configured into -# target_vector in targets.c if configured with --enable-targets=all -# and --enable-64-bit-bfd. -BFD64_BACKENDS = \ - aout64.o \ - coff-alpha.o \ - demo64.o \ - elf64-gen.o \ - elf64-sparc.o \ - elf64.o \ - nlm32-alpha.o \ - nlm64.o - -BFD64_BACKENDS_CFILES = \ - aout64.c \ - coff-alpha.c \ - demo64.c \ - elf64-gen.c \ - elf64-sparc.c \ - elf64.c \ - nlm32-alpha.c \ - nlm64.c - -OPTIONAL_BACKENDS = \ - aix386-core.o \ - hpux-core.o \ - irix-core.o \ - lynx-core.o \ - osf-core.o \ - trad-core.o \ - cisco-core.o - -OPTIONAL_BACKENDS_CFILES = \ - aix386-core.c \ - hpux-core.c \ - irix-core.c \ - lynx-core.c \ - osf-core.c \ - trad-core.c \ - cisco-core.c - -# These are defined by configure.in: -WORDSIZE = @wordsize@ -ALL_BACKENDS = @all_backends@ -BFD_BACKENDS = @bfd_backends@ -BFD_MACHINES = @bfd_machines@ -TDEFAULTS = @tdefaults@ - -all: - -FLAGS_TO_PASS = \ - "prefix=$(prefix)" \ - "exec_prefix=$(exec_prefix)" \ - "against=$(against)" \ - "AR=$(AR)" \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC=$(CC)" \ - "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ - "CFLAGS=$(CFLAGS)" \ - "RANLIB=$(RANLIB)" \ - "MAKEINFO=$(MAKEINFO)" \ - "INSTALL=$(INSTALL)" \ - "INSTALL_DATA=$(INSTALL_DATA)" \ - "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" - -ALL_CFLAGS=@HDEFINES@ @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES) $(CFLAGS) -.c.o: - if [ -n "$(PICFLAG)" ]; then \ - $(CC) -c $(PICFLAG) $(ALL_CFLAGS) $< -o pic/$@; \ - else true; fi - $(CC) -c $(ALL_CFLAGS) $< - -bfd_libs_here = -all_machines_here = -bfd32_backends_here = -core_files_here = -configs_not_included_in_all_targets_option_here = - -# C source files that correspond to .o's. -CFILES = \ - $(BFD_LIBS_CFILES) \ - $(ALL_MACHINES_CFILES) \ - $(BFD32_BACKENDS_CFILES) \ - $(BFD64_BACKENDS_CFILES) \ - $(OPTIONAL_BACKENDS_CFILES) \ - i386dynix.c hp300bsd.c - -HFILES = aout-target.h aoutf1.h aoutx.h coffcode.h \ - coffswap.h ecoffswap.h elf32-hppa.h elf32-target.h elf64-target.h \ - elfcode.h hppa_stubs.h libaout.h libbfd.h \ - libcoff.h libecoff.h elf-bfd.h libhppa.h libieee.h libnlm.h \ - liboasys.h nlm-target.h nlmcode.h som.h genlink.h netbsd.h - -all: Makefile $(ALLLIBS) @PICLIST@ - @$(MAKE) subdir_do DO=all "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) - -.NOEXPORT: -MAKEOVERRIDES= - -.PHONY: check installcheck -check: - @echo No testsuites exist for the BFD library. Nothing to check. - -installcheck: - @echo No testsuites exist for the BFD library. Nothing to check. - -info dvi : force - @$(MAKE) subdir_do DO=$@ "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) - -clean-info: - @$(MAKE) subdir_do DO=clean-info "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) - -install-info: force - @$(MAKE) subdir_do DO=install-info "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) - -diststuff: info - -# Various kinds of .o files to put in libbfd.a: -# BFD_LIBS Generic routines, always needed. -# BFD_BACKENDS Routines the configured targets need. -# BFD_MACHINES Architecture-specific routines the configured targets need. -# COREFILE Core file routines for a native configuration -OFILES = $(BFD_LIBS) $(BFD_BACKENDS) $(BFD_MACHINES) @COREFILE@ - -stamp-ofiles: Makefile - rm -f tofiles - f=""; \ - for i in $(OFILES) ; do \ - case " $$f " in \ - *" $$i "*) ;; \ - *) f="$$f $$i" ;; \ - esac ; \ - done ; \ - echo $$f > tofiles - $(srcdir)/../move-if-change tofiles ofiles - touch stamp-ofiles - -ofiles: stamp-ofiles ; @true - -$(TARGETLIB): $(OFILES) ofiles - rm -f $(TARGETLIB) - @echo ofiles = `cat ofiles` - $(AR) $(AR_FLAGS) $(TARGETLIB) `cat ofiles` - $(RANLIB) $(TARGETLIB) - -stamp-piclist: ofiles - rm -f tpiclist - if [ -n "$(PICFLAG)" ]; then \ - sed -e 's,\([^ ][^ ]*\),pic/\1,g' ofiles > tpiclist; \ - else \ - cp ofiles tpiclist; \ - fi - $(srcdir)/../move-if-change tpiclist piclist - touch stamp-piclist - -piclist: stamp-piclist ; @true - -$(SHLIB): stamp-picdir $(OFILES) piclist - rm -f $(SHLIB) - $(SHLIB_CC) $(SHLIB_CFLAGS) -o $(SHLIB) `cat piclist` - -# We make a link from libbfd.so to libbfd.so.VERSION for linking, and -# also a link from libTARGET-bfd.so.VERSION for running. -$(SHLINK): $(SHLIB) - ts=lib`echo $(SHLIB) | sed -e 's/^lib//' | sed -e '$(program_transform_name)'`; \ - if [ "$$ts" != "$(SHLIB)" ]; then \ - rm -f $$ts; \ - ln -sf $(SHLIB) $$ts; \ - else true; fi - rm -f $(SHLINK) - ln -sf $(SHLIB) $(SHLINK) - -# This target creates libTARGET-bfd.so.VERSION as a symlink to -# libbfd.so.VERSION. It is used on SunOS, which does not have SONAME. -stamp-tshlink: $(SHLIB) - tf=lib`echo $(SHLIB) | sed -e 's/^lib//' | sed '$(program_transform_name)'`; \ - if [ "$$tf" != "$(SHLIB)" ]; then \ - rm -f $$tf; \ - ln -sf $(SHLIB) $$tf; \ - else true; fi - touch stamp-tshlink - -# When compiling archures.c and targets.c, supply the default target -# info from configure. - -targets.o: targets.c Makefile - if [ -n "$(PICFLAG)" ]; then \ - $(CC) -c $(PICFLAG) $(TDEFAULTS) $(ALL_CFLAGS) $(srcdir)/targets.c -o pic/targets.o; \ - else true; fi - $(CC) -c $(TDEFAULTS) $(ALL_CFLAGS) $(srcdir)/targets.c - -archures.o: archures.c Makefile - if [ -n "$(PICFLAG)" ]; then \ - $(CC) -c $(PICFLAG) $(TDEFAULTS) $(ALL_CFLAGS) $(srcdir)/archures.c -o pic/archures.o; \ - else true; fi - $(CC) -c $(TDEFAULTS) $(ALL_CFLAGS) $(srcdir)/archures.c - -elf32-target.h : elfxx-target.h - rm -f elf32-target.h - sed -e s/NN/32/g < $(srcdir)/elfxx-target.h > elf32-target.new - mv -f elf32-target.new elf32-target.h - -elf64-target.h : elfxx-target.h - rm -f elf64-target.h - sed -e s/NN/64/g < $(srcdir)/elfxx-target.h > elf64-target.new - mv -f elf64-target.new elf64-target.h - -subdir_do: force - @for i in $(DODIRS); do \ - if [ -d ./$$i ] ; then \ - if (cd ./$$i; \ - $(MAKE) $(FLAGS_TO_PASS) $(DO)) ; then true ; \ - else exit 1 ; fi ; \ - else true ; fi ; \ - done - -tags etags: TAGS - -TAGS: force - etags $(INCDIR)/*.h $(srcdir)/*.h $(srcdir)/*.c - -do_mostlyclean: - rm -f *.o *~ core *.E *.p *.ip aout-params.h gen-aout config.log \ - pic/*.o -do_clean: do_mostlyclean - rm -f libbfd.a TAGS bfd.h stmp-bfd.h ofiles stamp-ofiles \ - elf32-target.h elf64-target.h $(SHLIB) $(SHLINK) \ - piclist stamp-piclist -do_distclean: do_clean - rm -f Makefile config.status config.cache config.h stamp-h - rm -rf pic stamp-picdir -do_maintainer_clean: do_distclean - rm -f $(srcdir)/bfd-in2.h $(srcdir)/libbfd.h $(srcdir)/libcoff.h - -mostlyclean: do_mostlyclean - $(MAKE) subdir_do DO=mostlyclean "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) -clean: do_clean - $(MAKE) subdir_do DO=clean "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) -distclean: - $(MAKE) subdir_do DO=distclean "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) - $(MAKE) do_distclean -clobber maintainer-clean realclean: - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - $(MAKE) subdir_do DO=maintainer-clean "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) - $(MAKE) do_maintainer_clean - -BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/obstack.h -LOCAL_H_DEPS= libbfd.h sysdep.h config.h -$(BFD_LIBS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS) -$(BFD_MACHINES): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS) -$(BFD_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS) -$(OPTIONAL_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS) - -# Get around a Sun Make bug in SunOS 4.1.1 with VPATH -cpu-i386.o:cpu-i386.c -cpu-z8k.o: cpu-z8k.c -cpu-h8500.o: cpu-h8500.c -cpu-we32k.o: cpu-we32k.c - -saber: - #suppress 65 on bfd_map_over_sections - #suppress 66 on bfd_map_over_sections - #suppress 67 on bfd_map_over_sections - #suppress 68 on bfd_map_over_sections - #suppress 69 on bfd_map_over_sections - #suppress 70 on bfd_map_over_sections - #suppress 110 in bfd_map_over_sections - #suppress 112 in bfd_map_over_sections - #suppress 530 - #suppress 590 in swap_exec_header - #suppress 590 in _bfd_dummy_core_file_matches_executable_p - #suppress 590 in bfd_dont_truncate_arname - #suppress 590 on ignore - #suppress 590 on abfd - #setopt load_flags $(CFLAGS) - #load $(CFILES) - - -#----------------------------------------------------------------------------- -# 'STANDARD' GNU/960 TARGETS BELOW THIS POINT -# -# 'VERSION' file must be present and contain a string of the form "x.y" -#----------------------------------------------------------------------------- - -ver960.c: FORCE - rm -f ver960.c - echo "char ${TARG}_ver[]= \"${TARG} `cat VERSION`, `date`\";" > ver960.c - - -# This target should be invoked before building a new release. -# 'VERSION' file must be present and contain a string of the form "x.y" -# -roll: - @V=`cat VERSION` ; \ - MAJ=`sed 's/\..*//' VERSION` ; \ - MIN=`sed 's/.*\.//' VERSION` ; \ - V=$$MAJ.`expr $$MIN + 1` ; \ - rm -f VERSION ; \ - echo $$V >VERSION ; \ - echo Version $$V - -# Dummy target to force execution of dependent targets. -# -force: - -install: $(ALLLIBS) - for f in $(ALLLIBS); do \ - if [ "$$f" = "stamp-tshlink" ]; then \ - continue; \ - fi; \ - tf=lib`echo $$f | sed -e 's/^lib//' | sed '$(program_transform_name)'`; \ - rm -f $(libdir)/$$tf; \ - if [ "$$f" = "$(SHLINK)" ]; then \ - ts=lib`echo $(SHLIB) | sed -e 's/^lib//' | sed '$(program_transform_name)'`; \ - ln -sf $$ts $(libdir)/$$tf; \ - elif [ "$$f" = "$(SHLIB)" ]; then \ - $(INSTALL_PROGRAM) $$f $(libdir)/$$tf; \ - else \ - $(INSTALL_DATA) $$f $(libdir)/$$tf; \ - $(RANLIB) $(libdir)/$$tf; \ - chmod a-x $(libdir)/$$tf; \ - fi; \ - done -# Install BFD include file, and others that it needs. Install them -# both in GCC's include directory, and in the system include dir -# if configured as $(oldincludedir) -- which it usually isnt. - $(INSTALL_DATA) $(BFD_H) $(includedir)/bfd.h - $(INSTALL_DATA) $(INCDIR)/ansidecl.h $(includedir)/ansidecl.h - $(INSTALL_DATA) $(INCDIR)/bfdlink.h $(includedir)/bfdlink.h - $(INSTALL_DATA) $(INCDIR)/obstack.h $(includedir)/obstack.h - -if test -z "$(oldincludedir)"; then true; else \ - test -d $(oldincludedir) || mkdir $(oldincludedir); \ - $(INSTALL_DATA) $(BFD_H) $(oldincludedir)/bfd.h; \ - $(INSTALL_DATA) $(INCDIR)/ansidecl.h $(oldincludedir)/ansidecl.h; \ - $(INSTALL_DATA) $(INCDIR)/bfdlink.h $(oldincludedir)/bfdlink.h; \ - $(INSTALL_DATA) $(INCDIR)/obstack.h $(oldincludedir)/obstack.h; \ - $(MAKE) subdir_do DO=install "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS); \ - fi - -Makefile: Makefile.in config.status - CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status - -config.h: stamp-h ; @true -stamp-h: config.in config.status - CONFIG_FILES= CONFIG_HEADERS=config.h:config.in $(SHELL) ./config.status - -config.status: configure configure.host config.bfd - $(SHELL) config.status --recheck - -# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES). -.dep: dep.sed $(CFILES) $(HFILES) bfd.h - rm -f .dep1 - $(MAKE) DEP=$(DEP) .dep1 - sed -f dep.sed <.dep1 >.dep - -# This rule really wants a mkdep that runs "gcc -MM". -# The NetBSD mkdep overwrites any existing file contents, and doesn't insert -# the "DO NOT DELETE" line. -# Other mkdep versions require a file that already exists, and do insert it. -# Hence the weirdness.... -.dep1: $(CFILES) - rm -f .dep2 .dep2a - echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2 - echo > .dep2a - $(DEP) -f .dep2a $(ALL_CFLAGS) $? - sed -e '/DO NOT DELETE/d' -e '/^$$/d' < .dep2a >> .dep2 - rm -f .dep2a - $(srcdir)/../move-if-change .dep2 .dep1 - -dep.sed: dep-in.sed config.status - sed <$(srcdir)/dep-in.sed >dep.sed \ - -e 's!@BFD_H@!$(BFD_H)!' \ - -e 's!@INCDIR@!$(INCDIR)!' \ - -e 's!@SRCDIR@!$(srcdir)!' - -dep: .dep - sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile - cat .dep >> tmp-Makefile - $(srcdir)/../move-if-change tmp-Makefile Makefile - -dep-in: .dep - sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in - cat .dep >> tmp-Makefile.in - $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in - -host-aout.o: Makefile - -# The following program can be used to generate a simple config file -# which can be folded into an h-XXX file for a new host, with some editing. -aout-params.h: gen-aout - ./gen-aout host > aout-params.h -gen-aout: $(srcdir)/gen-aout.c Makefile - $(CC) -o gen-aout $(CFLAGS) $(LFLAGS) $(srcdir)/gen-aout.c - -BFDIN_H= $(srcdir)/bfd-in2.h - -$(BFD_H): stmp-bfd.h ; @true - -stmp-bfd.h : $(srcdir)/bfd-in2.h Makefile - rm -f bfd.h-new - sed -e 's/@WORDSIZE@/$(WORDSIZE)/' \ - -e "s/@VERSION@/`cat $(srcdir)/VERSION`/" \ - -e 's/@BFD_HOST_64BIT_LONG@/@HOST_64BIT_LONG@/' \ - < $(srcdir)/bfd-in2.h \ - > bfd.h-new - $(srcdir)/../move-if-change bfd.h-new $(BFD_H) - touch stmp-bfd.h - -# Could really use a "copy-if-change"... -headers: - (cd $(docdir); $(MAKE) protos $(FLAGS_TO_PASS)) - cp $(docdir)/bfd.h bfd-in2.h-new - $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h - cp $(docdir)/libbfd.h libbfd.h-new - $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h - cp $(docdir)/libcoff.h libcoff.h-new - $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h - -# The rules for the generated header files are here so that people can -# type `make bfd-in2.h' if they remove it. They are not run by default. -$(srcdir)/bfd-in2.h: - (cd $(docdir); $(MAKE) bfd.h $(FLAGS_TO_PASS)) - cp $(docdir)/bfd.h bfd-in2.h-new - $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h -$(srcdir)/libbfd.h: - (cd $(docdir); $(MAKE) libbfd.h $(FLAGS_TO_PASS)) - cp $(docdir)/libbfd.h libbfd.h-new - $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h -$(srcdir)/libcoff.h: - (cd $(docdir); $(MAKE) libcoff.h $(FLAGS_TO_PASS)) - cp $(docdir)/libcoff.h libcoff.h-new - $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h - -bfd.info: - (cd $(docdir); $(MAKE) bfd.info $(FLAGS_TO_PASS)) - -bfd.dvi: - (cd $(docdir); $(MAKE) bfd.dvi $(FLAGS_TO_PASS)) - -bfd.ps: - (cd $(docdir); $(MAKE) bfd.ps $(FLAGS_TO_PASS)) - - -$(OFILES): stamp-picdir - -stamp-picdir: - if [ -n "$(PICFLAG)" ] && [ ! -d pic ]; then \ - mkdir pic; \ - else true; fi - touch stamp-picdir - -# What appears below is generated by a hacked mkdep using gcc -MM. - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. -archive.o: archive.c $(INCDIR)/aout/ar.h $(INCDIR)/aout/ranlib.h -archures.o: archures.c -bfd.o: bfd.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/sym.h libcoff.h libecoff.h $(INCDIR)/coff/ecoff.h \ - elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ - $(INCDIR)/elf/external.h -cache.o: cache.c -coffgen.o: coffgen.c $(INCDIR)/coff/internal.h libcoff.h \ - $(INCDIR)/bfdlink.h -corefile.o: corefile.c -format.o: format.c -init.o: init.c -libbfd.o: libbfd.c -opncls.o: opncls.c -reloc.o: reloc.c $(INCDIR)/bfdlink.h -section.o: section.c -syms.o: syms.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def -targets.o: targets.c -hash.o: hash.c -linker.o: linker.c $(INCDIR)/bfdlink.h genlink.h -elf.o: elf.c $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \ - $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h -srec.o: srec.c $(INCDIR)/libiberty.h -binary.o: binary.c -tekhex.o: tekhex.c $(INCDIR)/libiberty.h -ihex.o: ihex.c $(INCDIR)/libiberty.h -stab-syms.o: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \ - $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def -cpu-a29k.o: cpu-a29k.c -cpu-alpha.o: cpu-alpha.c -cpu-arm.o: cpu-arm.c -cpu-h8300.o: cpu-h8300.c -cpu-h8500.o: cpu-h8500.c -cpu-hppa.o: cpu-hppa.c -cpu-i386.o: cpu-i386.c -cpu-i860.o: cpu-i860.c -cpu-i960.o: cpu-i960.c -cpu-m68k.o: cpu-m68k.c -cpu-m88k.o: cpu-m88k.c -cpu-mips.o: cpu-mips.c -cpu-ns32k.o: cpu-ns32k.c -cpu-powerpc.o: cpu-powerpc.c -cpu-rs6000.o: cpu-rs6000.c -cpu-sh.o: cpu-sh.c -cpu-sparc.o: cpu-sparc.c -cpu-vax.o: cpu-vax.c -cpu-we32k.o: cpu-we32k.c -cpu-w65.o: cpu-w65.c -cpu-z8k.o: cpu-z8k.c -aout-adobe.o: aout-adobe.c $(INCDIR)/aout/adobe.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def libaout.h $(INCDIR)/bfdlink.h -aout-ns32k.o: aout-ns32k.c $(INCDIR)/aout/aout64.h \ - libaout.h $(INCDIR)/bfdlink.h -aout0.o: aout0.c aoutf1.h $(INCDIR)/aout/sun4.h libaout.h \ - $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h -aout32.o: aout32.c aoutx.h $(INCDIR)/bfdlink.h libaout.h \ - $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \ - $(INCDIR)/aout/ar.h -bout.o: bout.c $(INCDIR)/bfdlink.h genlink.h $(INCDIR)/bout.h \ - $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def libaout.h -cf-i386lynx.o: cf-i386lynx.c coff-i386.c $(INCDIR)/coff/i386.h \ - $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -cf-m68klynx.o: cf-m68klynx.c coff-m68k.c $(INCDIR)/coff/m68k.h \ - $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -cf-sparclynx.o: cf-sparclynx.c coff-sparc.c $(INCDIR)/coff/sparc.h \ - $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -coff-a29k.o: coff-a29k.c $(INCDIR)/coff/a29k.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-apollo.o: coff-apollo.c $(INCDIR)/coff/apollo.h \ - $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -coff-arm.o: coff-arm.c $(INCDIR)/coff/arm.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-aux.o: coff-aux.c $(INCDIR)/coff/aux-coff.h $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/m68k.h coff-m68k.c libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -coff-h8300.o: coff-h8300.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/h8300.h \ - $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h -coff-h8500.o: coff-h8500.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/h8500.h \ - $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h -coff-i386.o: coff-i386.c $(INCDIR)/coff/i386.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-i860.o: coff-i860.c $(INCDIR)/coff/i860.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-go32.o: coff-go32.c coff-i386.c $(INCDIR)/coff/i386.h \ - $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -coff-i960.o: coff-i960.c $(INCDIR)/coff/i960.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-m68k.o: coff-m68k.c $(INCDIR)/coff/m68k.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-m88k.o: coff-m88k.c $(INCDIR)/coff/m88k.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-mips.o: coff-mips.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \ - $(INCDIR)/coff/mips.h libcoff.h libecoff.h coffswap.h \ - ecoffswap.h -coff-pmac.o: coff-pmac.c coff-rs6000.c $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/rs6000.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -coff-rs6000.o: coff-rs6000.c $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/rs6000.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -coff-sh.o: coff-sh.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/sh.h \ - $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h -coff-sparc.o: coff-sparc.c $(INCDIR)/coff/sparc.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-u68k.o: coff-u68k.c coff-m68k.c $(INCDIR)/coff/m68k.h \ - $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ - coffcode.h coffswap.h -coff-we32k.o: coff-we32k.c $(INCDIR)/coff/we32k.h $(INCDIR)/coff/internal.h \ - libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h -coff-w65.o: coff-w65.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/w65.h \ - $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h -coff-z8k.o: coff-z8k.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/z8k.h \ - $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h -cofflink.o: cofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \ - libcoff.h -ecoff.o: ecoff.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/ar.h \ - $(INCDIR)/aout/ranlib.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \ - libaout.h $(INCDIR)/aout/aout64.h $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \ - libcoff.h libecoff.h -ecofflink.o: ecofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h \ - $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h -elf32-gen.o: elf32-gen.c elf-bfd.h $(INCDIR)/elf/common.h \ - $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \ - elf32-target.h -elf32-hppa.o: elf32-hppa.c $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ - elf32-hppa.h libhppa.h $(INCDIR)/elf/hppa.h hppa_stubs.h \ - elf32-target.h -elf32-i386.o: elf32-i386.c $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ - elf32-target.h -elf32-i860.o: elf32-i860.c elf-bfd.h $(INCDIR)/elf/common.h \ - $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \ - elf32-target.h -elf32-m68k.o: elf32-m68k.c $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ - elf32-target.h -elf32-m88k.o: elf32-m88k.c elf-bfd.h $(INCDIR)/elf/common.h \ - $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \ - elf32-target.h -elf32-mips.o: elf32-mips.c $(INCDIR)/bfdlink.h genlink.h \ - elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ - $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/coff/sym.h \ - $(INCDIR)/coff/symconst.h $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/mips.h ecoffswap.h \ - elf32-target.h -elf32-ppc.o: elf32-ppc.c $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ - $(INCDIR)/elf/ppc.h elf32-target.h -elf32-sparc.o: elf32-sparc.c $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ - $(INCDIR)/elf/sparc.h elf32-target.h -elf32.o: elf32.c elfcode.h $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ - elfcore.h elflink.h -elflink.o: elflink.c $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h -hp300hpux.o: hp300hpux.c $(INCDIR)/aout/hp300hpux.h \ - aoutx.h $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \ - $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \ - aout-target.h -som.o: som.c -i386aout.o: i386aout.c libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -i386bsd.o: i386bsd.c libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -i386freebsd.o: i386freebsd.c freebsd.h libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -i386linux.o: i386linux.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \ - $(INCDIR)/bfdlink.h aout-target.h -i386lynx.o: i386lynx.c libaout.h $(INCDIR)/bfdlink.h \ - $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -i386msdos.o: i386msdos.c libaout.h $(INCDIR)/bfdlink.h -i386netbsd.o: i386netbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -i386mach3.o: i386mach3.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \ - $(INCDIR)/bfdlink.h aout-target.h -i386os9k.o: i386os9k.c $(INCDIR)/bfdlink.h libaout.h \ - $(INCDIR)/os9k.h -ieee.o: ieee.c $(INCDIR)/ieee.h libieee.h -m68klinux.o: m68klinux.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \ - $(INCDIR)/bfdlink.h aout-target.h -m68klynx.o: m68klynx.c libaout.h $(INCDIR)/bfdlink.h \ - $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -m68knetbsd.o: m68knetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -m88kmach3.o: m88kmach3.c libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -mipsbsd.o: mipsbsd.c libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -newsos3.o: newsos3.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \ - $(INCDIR)/bfdlink.h aout-target.h -nlm.o: nlm.c libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \ - $(INCDIR)/nlm/external.h -nlm32-i386.o: nlm32-i386.c $(INCDIR)/nlm/i386-ext.h \ - libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \ - $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h -nlm32-sparc.o: nlm32-sparc.c $(INCDIR)/nlm/sparc32-ext.h \ - libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \ - $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h -nlm32-ppc.o: nlm32-ppc.c $(INCDIR)/nlm/ppc-ext.h libnlm.h \ - $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h \ - nlmswap.h nlm-target.h -nlm32.o: nlm32.c nlmcode.h libnlm.h $(INCDIR)/nlm/common.h \ - $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h -ns32knetbsd.o: ns32knetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -oasys.o: oasys.c $(INCDIR)/oasys.h liboasys.h -pc532-mach.o: pc532-mach.c libaout.h $(INCDIR)/bfdlink.h \ - $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -pe-arm.o: pe-arm.c coff-arm.c $(INCDIR)/coff/arm.h \ - $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ - $(INCDIR)/bfdlink.h coffcode.h peicode.h -pei-arm.o: pei-arm.c coff-arm.c $(INCDIR)/coff/arm.h \ - $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ - $(INCDIR)/bfdlink.h coffcode.h peicode.h -pe-i386.o: pe-i386.c coff-i386.c $(INCDIR)/coff/i386.h \ - $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ - $(INCDIR)/bfdlink.h coffcode.h peicode.h -pei-i386.o: pei-i386.c coff-i386.c $(INCDIR)/coff/i386.h \ - $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ - $(INCDIR)/bfdlink.h coffcode.h peicode.h -pe-ppc.o: pe-ppc.c coff-ppc.c $(INCDIR)/coff/powerpc.h \ - $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ - $(INCDIR)/bfdlink.h coffcode.h peicode.h -pei-ppc.o: pei-ppc.c coff-ppc.c $(INCDIR)/coff/powerpc.h \ - $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ - $(INCDIR)/bfdlink.h coffcode.h peicode.h -reloc16.o: reloc16.c $(INCDIR)/bfdlink.h genlink.h \ - $(INCDIR)/coff/internal.h libcoff.h -sparclynx.o: sparclynx.c $(INCDIR)/aout/sun4.h libaout.h \ - $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h -sparcnetbsd.o: sparcnetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -sunos.o: sunos.c $(INCDIR)/bfdlink.h libaout.h aoutf1.h \ - $(INCDIR)/aout/sun4.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h -versados.o: versados.c $(INCDIR)/libiberty.h -xcofflink.o: xcofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \ - libcoff.h -aout64.o: aout64.c aoutx.h $(INCDIR)/bfdlink.h libaout.h \ - $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \ - $(INCDIR)/aout/ar.h -coff-alpha.o: coff-alpha.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \ - $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \ - $(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h libcoff.h \ - libecoff.h coffswap.h ecoffswap.h -demo64.o: demo64.c aoutf1.h $(INCDIR)/aout/sun4.h libaout.h \ - $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h -elf64-gen.o: elf64-gen.c elf-bfd.h $(INCDIR)/elf/common.h \ - $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \ - elf64-target.h -elf64-sparc.o: elf64-sparc.c elf-bfd.h $(INCDIR)/elf/common.h \ - $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \ - $(INCDIR)/elf/sparc.h elf64-target.h -elf64.o: elf64.c elfcode.h $(INCDIR)/bfdlink.h elf-bfd.h \ - $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ - elfcore.h elflink.h -nlm32-alpha.o: nlm32-alpha.c $(INCDIR)/nlm/alpha-ext.h \ - libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \ - $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h -nlm64.o: nlm64.c nlmcode.h libnlm.h $(INCDIR)/nlm/common.h \ - $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h -aix386-core.o: aix386-core.c $(INCDIR)/coff/i386.h \ - $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h -hpux-core.o: hpux-core.c -irix-core.o: irix-core.c -lynx-core.o: lynx-core.c -osf-core.o: osf-core.c -trad-core.o: trad-core.c libaout.h $(INCDIR)/bfdlink.h -cisco-core.o: cisco-core.c -i386dynix.o: i386dynix.c $(INCDIR)/aout/dynix3.h aoutx.h \ - $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \ - $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \ - aout-target.h -hp300bsd.o: hp300bsd.c libaout.h $(INCDIR)/bfdlink.h \ - aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ - $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h -# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/contrib/gdb/bfd/PORTING b/contrib/gdb/bfd/PORTING deleted file mode 100644 index c8bfd77b96f..00000000000 --- a/contrib/gdb/bfd/PORTING +++ /dev/null @@ -1,83 +0,0 @@ - Preliminary Notes on Porting BFD - -------------------------------- - -The 'host' is the system a tool runs *on*. -The 'target' is the system a tool runs *for*, i.e. -a tool can read/write the binaries of the target. - -Porting to a new host ---------------------- -Pick a name for your host. Call that . -( might be sun4, ...) -Create a file hosts/.mh. - -Porting to a new target ------------------------ -Pick a name for your target. Call that . -Call the name for your CPU architecture . -You need to create .c and config/.mt, -and add a case for it to a case statements in bfd/configure.host and -bfd/config.bfd, which associates each canonical host type with a BFD -host type (used as the base of the makefile fragment names), and to the -table in bfd/configure.in which associates each target vector with -the .o files it uses. - -config/.mt is a Makefile fragment. -The following is usually enough: -DEFAULT_VECTOR=_vec -SELECT_ARCHITECTURES=bfd__arch - -See the list of cpu types in archures.c, or "ls cpu-*.c". -If your architecture is new, you need to add it to the tables -in bfd/archures.c, opcodes/configure.in, and binutils/objdump.c. - -For more information about .mt and .mh files, see config/README. - -The file .c is the hard part. It implements the -bfd_target _vec, which includes pointers to -functions that do the actual -specific methods. - -Porting to a that uses the a.out binary format -------------------------------------------------------- - -In this case, the include file aout-target.h probaby does most -of what you need. The program gen-aout generates .c for -you automatically for many a.out systems. Do: - make gen-aout - ./gen-aout > .c -(This only works if you are building on the target ("native"). -If you must make a cross-port from scratch, copy the most -similar existing file that includes aout-target.h, and fix what is wrong.) - -Check the parameters in .c, and fix anything that is wrong. -(Also let us know about it; perhaps we can improve gen-aout.c.) - -TARGET_IS_BIG_ENDIAN_P - Should be defined if is big-endian. - -N_HEADER_IN_TEXT(x) - See discussion in ../include/aout/aout64.h. - -BYTES_IN_WORD - Number of bytes per word. (Usually 4 but can be 8.) - -ARCH - Number of bits per word. (Usually 32, but can be 64.) - -ENTRY_CAN_BE_ZERO - Define if the extry point (start address of an - executable program) can be 0x0. - -TEXT_START_ADDR - The address of the start of the text segemnt in - virtual memory. Normally, the same as the entry point. - -TARGET_PAGE_SIZE - -SEGMENT_SIZE - Usually, the same as the TARGET_PAGE_SIZE. - Alignment needed for the data segment. - -TARGETNAME - The name of the target, for run-time lookups. - Usually "a.out-" diff --git a/contrib/gdb/bfd/TODO b/contrib/gdb/bfd/TODO deleted file mode 100644 index 08a3641b1ad..00000000000 --- a/contrib/gdb/bfd/TODO +++ /dev/null @@ -1,25 +0,0 @@ -Things that still need to be done: -*- Text -*- - - o - A source of space lossage is that all the target-dependent code - is in a single bfd_target structure. Hence all the code for - *writing* object files is still pulled into all the applications - that only care about *reading* (gdb, nm, objdump), while gas has - to carry along all the unneded baggage for reading objects. And - so on. This would be a substantial change, and the payoff would - not all that great (essentially none if bfd is used as a shared - library). - - o - The storage needed by BFD data structures is also larger than strictly - needed. This may be difficult to do much about. - - o - implement bfd_abort, which should close the bfd but not alter the - filesystem. - - o - update the bfd doc; write a how-to-write-a-backend doc, take out - the stupid quips and fill in all the blanks. - - o - upgrade the reloc handling as per Steve's suggestion. - - - - diff --git a/contrib/gdb/bfd/VERSION b/contrib/gdb/bfd/VERSION deleted file mode 100644 index 9ddf6b5ad1a..00000000000 --- a/contrib/gdb/bfd/VERSION +++ /dev/null @@ -1 +0,0 @@ -cygnus-2.6 diff --git a/contrib/gdb/bfd/acconfig.h b/contrib/gdb/bfd/acconfig.h deleted file mode 100644 index 647798cbe9f..00000000000 --- a/contrib/gdb/bfd/acconfig.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* Whether malloc must be declared even if is included. */ -#undef NEED_DECLARATION_MALLOC - -/* Whether free must be declared even if is included. */ -#undef NEED_DECLARATION_FREE -@TOP@ - -/* Do we need to use the b modifier when opening binary files? */ -#undef USE_BINARY_FOPEN - -/* Name of host specific header file to include in trad-core.c. */ -#undef TRAD_HEADER - -/* Define only if is available *and* it defines prstatus_t. */ -#undef HAVE_SYS_PROCFS_H - -/* Do we really want to use mmap if it's available? */ -#undef USE_MMAP diff --git a/contrib/gdb/bfd/aclocal.m4 b/contrib/gdb/bfd/aclocal.m4 deleted file mode 100644 index 1f5027e4858..00000000000 --- a/contrib/gdb/bfd/aclocal.m4 +++ /dev/null @@ -1,43 +0,0 @@ -dnl See whether we need to use fopen-bin.h rather than fopen-same.h. -AC_DEFUN(BFD_BINARY_FOPEN, -[AC_REQUIRE([AC_CANONICAL_SYSTEM]) -case "${host}" in -changequote(,)dnl -i[345]86-*-msdos* | i[345]86-*-go32* | *-*-cygwin32) -changequote([,])dnl - AC_DEFINE(USE_BINARY_FOPEN) ;; -esac])dnl - -dnl Get a default for CC_FOR_BUILD to put into Makefile. -AC_DEFUN(BFD_CC_FOR_BUILD, -[# Put a plausible default for CC_FOR_BUILD in Makefile. -AC_REQUIRE([AC_C_CROSS])dnl -if test -z "$CC_FOR_BUILD"; then - if test "x$cross_compiling" = "xno"; then - CC_FOR_BUILD='$(CC)' - else - CC_FOR_BUILD=gcc - fi -fi -AC_SUBST(CC_FOR_BUILD)])dnl - -dnl See whether we need a declaration for a function. -AC_DEFUN(BFD_NEED_DECLARATION, -[AC_MSG_CHECKING([whether $1 must be declared]) -AC_CACHE_VAL(bfd_cv_decl_needed_$1, -[AC_TRY_COMPILE([ -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif], -[char *(*pfn) = (char *(*)) $1], -bfd_cv_decl_needed_$1=no, bfd_cv_decl_needed_$1=yes)]) -AC_MSG_RESULT($bfd_cv_decl_needed_$1) -if test $bfd_cv_decl_needed_$1 = yes; then - bfd_tr_decl=NEED_DECLARATION_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - AC_DEFINE_UNQUOTED($bfd_tr_decl) -fi -])dnl diff --git a/contrib/gdb/bfd/aix386-core.c b/contrib/gdb/bfd/aix386-core.c deleted file mode 100644 index 21ec9a6d431..00000000000 --- a/contrib/gdb/bfd/aix386-core.c +++ /dev/null @@ -1,285 +0,0 @@ -/* BFD back-end for AIX on PS/2 core files. - This was based on trad-core.c, which was written by John Gilmore of - Cygnus Support. - Copyright 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Minh Tran-Le . - Converted to back end form by Ian Lance Taylor . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/i386.h" -#include "coff/internal.h" -#include "libcoff.h" - -#include -#include -#include - -#include - -#if defined (_AIX) && defined (_I386) -#define NOCHECKS /* this is for coredump.h */ -#define _h_USER /* avoid including user.h from coredump.h */ -#include -#include -#endif /* _AIX && _I386 */ - -/* maybe this could work on some other i386 but I have not tried it - * mtranle@paris - Tue Sep 24 12:49:35 1991 - */ - -#ifndef COR_MAGIC -# define COR_MAGIC "core" -#endif - -/* need this cast because ptr is really void * */ -#define core_hdr(bfd) \ - (((bfd->tdata.trad_core_data))->hdr) -#define core_section(bfd,n) \ - (((bfd)->tdata.trad_core_data)->sections[n]) -#define core_regsec(bfd) \ - (((bfd)->tdata.trad_core_data)->reg_section) -#define core_reg2sec(bfd) \ - (((bfd)->tdata.trad_core_data)->reg2_section) - -/* These are stored in the bfd's tdata */ -struct trad_core_struct { - struct corehdr *hdr; /* core file header */ - asection *reg_section; - asection *reg2_section; - asection *sections[MAX_CORE_SEGS]; -}; - -static const bfd_target * -aix386_core_file_p (abfd) - bfd *abfd; -{ - int i,n; - unsigned char longbuf[4]; /* Raw bytes of various header fields */ - int core_size = sizeof (struct corehdr); - struct corehdr *core; - struct mergem { - struct trad_core_struct coredata; - struct corehdr internal_core; - } *mergem; - - if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) != sizeof (longbuf)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (strncmp(longbuf,COR_MAGIC,4)) return 0; - - if (bfd_seek (abfd, 0L, false) < 0) return 0; - - mergem = (struct mergem *)bfd_zalloc (abfd, sizeof (struct mergem)); - if (mergem == NULL) - return 0; - - core = &mergem->internal_core; - - if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - bfd_release (abfd, (char *)mergem); - return 0; - } - - set_tdata (abfd, &mergem->coredata); - core_hdr (abfd) = core; - - /* create the sections. This is raunchy, but bfd_close wants to reclaim - them */ - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) - { - loser: - bfd_release (abfd, (char *)mergem); - return 0; - } - core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_reg2sec (abfd) == NULL) - { - loser1: - bfd_release (abfd, core_regsec (abfd)); - goto loser; - } - - for (i=0, n=0 ; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type) ; i++) - { - if (core->cd_segs[i].cs_offset == 0) - continue; - core_section (abfd,n) = - (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_section (abfd,n) == NULL) - { - int j; - if (n > 0) - { - for (j=0; j < n; j++) - bfd_release (abfd, core_section(abfd, j)); - } - bfd_release (abfd, (char *)mergem); - goto loser1; - } - - switch (core->cd_segs[i].cs_type) - { - case COR_TYPE_DATA: - core_section (abfd, n)->name = ".data"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD + - SEC_HAS_CONTENTS); - break; - case COR_TYPE_STACK: - core_section (abfd, n)->name = ".stack"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD + - SEC_HAS_CONTENTS); - break; - case COR_TYPE_LIBDATA: - core_section (abfd, n)->name = ".libdata"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - case COR_TYPE_WRITE: - core_section (abfd, n)->name = ".writeable"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - case COR_TYPE_MSC: - core_section (abfd, n)->name = ".misc"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - default: - core_section (abfd, n)->name = ".unknown"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - } - core_section (abfd, n)->_raw_size = core->cd_segs[i].cs_len; - core_section (abfd, n)->vma = core->cd_segs[i].cs_address; - core_section (abfd, n)->filepos = core->cd_segs[i].cs_offset; - core_section (abfd, n)->alignment_power = 2; - core_section (abfd, n)->next = NULL; - if (n > 0) - core_section (abfd, (n-1))->next = core_section (abfd, n); - - abfd->section_count = ++n; - } - - core_regsec (abfd)->name = ".reg"; - core_reg2sec (abfd)->name = ".reg2"; - - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; - - core_regsec (abfd)->_raw_size = sizeof(core->cd_regs); - core_reg2sec (abfd)->_raw_size = sizeof(core->cd_fpregs); - - core_regsec (abfd)->vma = -1; - core_reg2sec (abfd)->vma = -1; - - /* We'll access the regs afresh in the core file, like any section: */ - core_regsec (abfd)->filepos = (file_ptr)offsetof(struct corehdr,cd_regs[0]); - core_reg2sec (abfd)->filepos = (file_ptr)offsetof(struct corehdr, - cd_fpregs); - - /* add the 2 reg fake sections to abfd */ - abfd->section_count += 2; - abfd->sections = core_regsec (abfd); - core_regsec (abfd)->next = core_reg2sec (abfd); - core_reg2sec (abfd)->next = core_section (abfd, 0); - - return abfd->xvec; -} - -static char * -aix386_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->cd_comm; -} - -static int -aix386_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->cd_cursig; -} - -static boolean -aix386_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this - point */ -} - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((PROTO(bfd_vma, (*), ( const bfd_byte *))) swap_abort ) -#define NO_GETS ((PROTO(bfd_signed_vma, (*), (const bfd_byte *))) swap_abort ) -#define NO_PUT ((PROTO(void, (*), (bfd_vma, bfd_byte *))) swap_abort ) - -const bfd_target aix386_core_vec = - { - "aix386-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIANG_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, /* data */ - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, /* hdrs */ - - {_bfd_dummy_target, _bfd_dummy_target, - _bfd_dummy_target, aix386_core_file_p}, - {bfd_false, bfd_false, /* bfd_create_object */ - bfd_false, bfd_false}, - {bfd_false, bfd_false, /* bfd_write_contents */ - bfd_false, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (aix386), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/aout-adobe.c b/contrib/gdb/bfd/aout-adobe.c deleted file mode 100644 index 36d230de9e8..00000000000 --- a/contrib/gdb/bfd/aout-adobe.c +++ /dev/null @@ -1,528 +0,0 @@ -/* BFD back-end for a.out.adobe binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. Based on bout.c. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "aout/adobe.h" - -#include "aout/stab_gnu.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -extern const bfd_target a_out_adobe_vec; /* Forward decl */ - -static const bfd_target *aout_adobe_callback PARAMS ((bfd *)); - -extern boolean aout_32_slurp_symbol_table PARAMS ((bfd *abfd)); -extern boolean aout_32_write_syms PARAMS ((bfd *)); -static void aout_adobe_write_section PARAMS ((bfd *abfd, sec_ptr sect)); - -/* Swaps the information in an executable header taken from a raw byte - stream memory image, into the internal exec_header structure. */ - -void aout_adobe_swap_exec_header_in - PARAMS ((bfd *abfd, struct external_exec *raw_bytes, - struct internal_exec *execp)); - -void -aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); -} - -/* Swaps the information in an internal exec header structure into the - supplied buffer ready for writing to disk. */ - -PROTO(void, aout_adobe_swap_exec_header_out, - (bfd *abfd, - struct internal_exec *execp, - struct external_exec *raw_bytes)); -void -aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - struct external_exec *raw_bytes; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info , bytes->e_info); - PUT_WORD (abfd, execp->a_text , bytes->e_text); - PUT_WORD (abfd, execp->a_data , bytes->e_data); - PUT_WORD (abfd, execp->a_bss , bytes->e_bss); - PUT_WORD (abfd, execp->a_syms , bytes->e_syms); - PUT_WORD (abfd, execp->a_entry , bytes->e_entry); - PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize); - PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize); -} - - -static const bfd_target * -aout_adobe_object_p (abfd) - bfd *abfd; -{ - struct internal_exec anexec; - struct external_exec exec_bytes; - char *targ; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info); - - /* Normally we just compare for the magic number. - However, a bunch of Adobe tools aren't fixed up yet; they generate - files using ZMAGIC(!). - If the environment variable GNUTARGET is set to "a.out.adobe", we will - take just about any a.out file as an Adobe a.out file. FIXME! */ - - if (N_BADMAG (anexec)) { - extern char *getenv (); - - targ = getenv ("GNUTARGET"); - if (targ && !strcmp (targ, a_out_adobe_vec.name)) - ; /* Just continue anyway, if specifically set to this format */ - else - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - } - - aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec); - return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback); -} - - -/* Finish up the opening of a b.out file for reading. Fill in all the - fields that are not handled by common code. */ - -static const bfd_target * -aout_adobe_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - asection *sect; - struct external_segdesc ext[1]; - char *section_name; - char try_again[30]; /* name and number */ - char *newname; - int trynum; - flagword flags; - - /* Architecture and machine type -- unknown in this format. */ - bfd_set_arch_mach(abfd, bfd_arch_unknown, 0); - - /* The positions of the string table and symbol table. */ - obj_str_filepos (abfd) = N_STROFF (*execp); - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - - /* Suck up the section information from the file, one section at a time. */ - - for (;;) { - if (bfd_read ((PTR) ext, 1, sizeof (*ext), abfd) != sizeof (*ext)) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - switch (ext->e_type[0]) { - case N_TEXT: - section_name = ".text"; - flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; - break; - - case N_DATA: - section_name = ".data"; - flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; - break; - - case N_BSS: - section_name = ".bss"; - flags = SEC_DATA | SEC_HAS_CONTENTS; - break; - - case 0: - goto no_more_sections; - - default: - (*_bfd_error_handler) - ("%s: Unknown section type in a.out.adobe file: %x\n", - bfd_get_filename (abfd), ext->e_type[0]); - goto no_more_sections; - } - - /* First one is called ".text" or whatever; subsequent ones are - ".text1", ".text2", ... */ - - bfd_set_error (bfd_error_no_error); - sect = bfd_make_section (abfd, section_name); - trynum = 0; - while (!sect) { - if (bfd_get_error () != bfd_error_no_error) - return 0; /* Some other error -- slide into the sunset */ - sprintf (try_again, "%s%d", section_name, ++trynum); - sect = bfd_make_section (abfd, try_again); - } - - /* Fix the name, if it is a sprintf'd name. */ - if (sect->name == try_again) { - newname = (char *) bfd_zalloc(abfd, strlen (sect->name)); - if (newname == NULL) - return 0; - strcpy (newname, sect->name); - sect->name = newname; - } - - /* Now set the section's attributes. */ - bfd_set_section_flags (abfd, sect, flags); - sect->_raw_size = ((ext->e_size[0] << 8) /* Assumed big-endian */ - | ext->e_size[1] << 8) - | ext->e_size[2]; - sect->_cooked_size = sect->_raw_size; - sect->vma = bfd_h_get_32 (abfd, ext->e_virtbase); - sect->filepos = bfd_h_get_32 (abfd, ext->e_filebase); - /* FIXME XXX alignment? */ - - /* Set relocation information for first section of each type. */ - if (trynum == 0) switch (ext->e_type[0]) { - case N_TEXT: - sect->rel_filepos = N_TRELOFF (*execp); - sect->reloc_count = execp->a_trsize; - break; - - case N_DATA: - sect->rel_filepos = N_DRELOFF (*execp); - sect->reloc_count = execp->a_drsize; - break; - } - } -no_more_sections: - - adata(abfd).reloc_entry_size = sizeof (struct reloc_std_external); - adata(abfd).symbol_entry_size = sizeof (struct external_nlist); - adata(abfd).page_size = 1; /* Not applicable. */ - adata(abfd).segment_size = 1; /* Not applicable. */ - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; - - return abfd->xvec; -} - -struct bout_data_struct { - struct aoutdata a; - struct internal_exec e; -}; - -static boolean -aout_adobe_mkobject (abfd) - bfd *abfd; -{ - struct bout_data_struct *rawptr; - - rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct)); - if (rawptr == NULL) - return false; - - abfd->tdata.bout_data = rawptr; - exec_hdr (abfd) = &rawptr->e; - - adata(abfd).reloc_entry_size = sizeof (struct reloc_std_external); - adata(abfd).symbol_entry_size = sizeof (struct external_nlist); - adata(abfd).page_size = 1; /* Not applicable. */ - adata(abfd).segment_size = 1; /* Not applicable. */ - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; - - return true; -} - - -static boolean -aout_adobe_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec swapped_hdr; - static struct external_segdesc sentinel[1]; /* Initialized to zero */ - asection *sect; - - exec_hdr (abfd)->a_info = ZMAGIC; - - /* Calculate text size as total of text sections, etc. */ - - exec_hdr (abfd)->a_text = 0; - exec_hdr (abfd)->a_data = 0; - exec_hdr (abfd)->a_bss = 0; - exec_hdr (abfd)->a_trsize = 0; - exec_hdr (abfd)->a_drsize = 0; - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - exec_hdr (abfd)->a_text += sect->_raw_size; - exec_hdr (abfd)->a_trsize += sect->reloc_count * - sizeof (struct reloc_std_external); - } else if (sect->flags & SEC_DATA) { - exec_hdr (abfd)->a_data += sect->_raw_size; - exec_hdr (abfd)->a_drsize += sect->reloc_count * - sizeof (struct reloc_std_external); - } else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD)) { - exec_hdr (abfd)->a_bss += sect->_raw_size; - } - } - - exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) - * sizeof (struct external_nlist); - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - - aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Now write out the section information. Text first, data next, rest - afterward. */ - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - aout_adobe_write_section (abfd, sect); - } - } - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_DATA) { - aout_adobe_write_section (abfd, sect); - } - } - for (sect = abfd->sections; sect; sect = sect->next) { - if (!(sect->flags & (SEC_CODE|SEC_DATA))) { - aout_adobe_write_section (abfd, sect); - } - } - - /* Write final `sentinel` section header (with type of 0). */ - if (bfd_write ((PTR) sentinel, 1, sizeof (*sentinel), abfd) - != sizeof (*sentinel)) - return false; - - /* Now write out reloc info, followed by syms and strings */ - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - if (! aout_32_write_syms (abfd)) - return false; - - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - if (!aout_32_squirt_out_relocs (abfd, sect)) - return false; - } - } - - if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_DATA) { - if (!aout_32_squirt_out_relocs (abfd, sect)) - return false; - } - } - } - return true; -} - -static void -aout_adobe_write_section (abfd, sect) - bfd *abfd; - sec_ptr sect; -{ - /* FIXME XXX */ -} - -static boolean -aout_adobe_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - file_ptr section_start; - sec_ptr sect; - - if (abfd->output_has_begun == false) { /* set by bfd.c handler */ - - /* Assign file offsets to sections. Text sections are first, and - are contiguous. Then data sections. Everything else at the end. */ - - section_start = N_TXTOFF (ignore<-->me); - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - sect->filepos = section_start; - /* FIXME: Round to alignment */ - section_start += sect->_raw_size; - } - } - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_DATA) { - sect->filepos = section_start; - /* FIXME: Round to alignment */ - section_start += sect->_raw_size; - } - } - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_HAS_CONTENTS && - !(sect->flags & (SEC_CODE|SEC_DATA))) { - sect->filepos = section_start; - /* FIXME: Round to alignment */ - section_start += sect->_raw_size; - } - } - } - - /* regardless, once we know what we're doing, we might as well get going */ - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) - return false; - - if (count != 0) { - return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false; - } - return true; -} - -static boolean -aout_adobe_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - if (! bfd_default_set_arch_mach (abfd, arch, machine)) - return false; - - if (arch == bfd_arch_unknown - || arch == bfd_arch_m68k) - return true; - - return false; -} - -static int -aout_adobe_sizeof_headers (ignore_abfd, ignore) - bfd *ignore_abfd; - boolean ignore; -{ - return sizeof(struct internal_exec); -} - - - - -/* Build the transfer vector for Adobe A.Out files. */ - -#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info - -#define aout_32_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) - -#define aout_32_bfd_reloc_type_lookup \ - ((reloc_howto_type *(*) \ - PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr) - -#define aout_32_set_arch_mach aout_adobe_set_arch_mach -#define aout_32_set_section_contents aout_adobe_set_section_contents - -#define aout_32_sizeof_headers aout_adobe_sizeof_headers -#define aout_32_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#define aout_32_bfd_relax_section bfd_generic_relax_section -#define aout_32_bfd_link_hash_table_create \ - _bfd_generic_link_hash_table_create -#define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define aout_32_bfd_final_link _bfd_generic_final_link -#define aout_32_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target a_out_adobe_vec = -{ - "a.out.adobe", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_BIG, /* data byte order is unknown (big assumed) */ - BFD_ENDIAN_BIG, /* hdr byte order is big */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT ), - /* section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC), - '_', /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, aout_adobe_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, aout_adobe_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, aout_adobe_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (aout_32), - BFD_JUMP_TABLE_WRITE (aout_32), - BFD_JUMP_TABLE_LINK (aout_32), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/aout-arm.c b/contrib/gdb/bfd/aout-arm.c deleted file mode 100644 index 978664a48aa..00000000000 --- a/contrib/gdb/bfd/aout-arm.c +++ /dev/null @@ -1,548 +0,0 @@ -/* BFD back-end for raw ARM a.out binaries. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#define N_TXTADDR(x) \ - ((N_MAGIC(x) == NMAGIC) ? 0x8000 : \ - (N_MAGIC(x) != ZMAGIC) ? 0 : \ - (N_SHARED_LIB(x)) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) : \ - TEXT_START_ADDR) - -#define TEXT_START_ADDR 0x8000 -#define TARGET_PAGE_SIZE 0x8000 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_arm - -#define MY(OP) CAT(aoutarm_,OP) -#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \ - (((x).a_info & ~006000) != OMAGIC) && \ - ((x).a_info != NMAGIC)) -#define N_MAGIC(x) ((x).a_info & ~07200) - -#include "bfd.h" -#include "sysdep.h" -#include "assert.h" - -#define MYARM(OP) CAT(aoutarm_,OP) -reloc_howto_type *MYARM(bfd_reloc_type_lookup) - PARAMS((bfd *, bfd_reloc_code_real_type)); -static boolean MYARM(write_object_contents) PARAMS((bfd *)); - -/* Avoid multiple defininitions from aoutx if supporting standarad a.out - as well as our own. */ -#define NAME(x,y) CAT3(aoutarm,_32_,y) - -#define MY_bfd_reloc_type_lookup aoutarm_bfd_reloc_type_lookup - -#include "libaout.h" -#include "aout/aout64.h" - -static bfd_reloc_status_type -MY(fix_pcrel_26_done) PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -MY(fix_pcrel_26) PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); -static void MY(swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *, - arelent *, asymbol **, - bfd_size_type)); -void MY(swap_std_reloc_out) PARAMS ((bfd *, arelent *, - struct reloc_std_external *)); - -reloc_howto_type MY(howto_table)[] = -{ - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask - pcdone */ - HOWTO (0, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, - 0x000000ff, 0x000000ff, false), - HOWTO (1, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, - 0x0000ffff, 0x0000ffff, false), - HOWTO (2, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, - 0xffffffff, 0xffffffff, false), - HOWTO (3, 2, 2, 26, true, 0, complain_overflow_signed, MY(fix_pcrel_26), - "ARM26", true, 0x00ffffff, 0x00ffffff, true), - HOWTO (4, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, - 0x000000ff, 0x000000ff, true), - HOWTO (5, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, - 0x0000ffff, 0x0000ffff, true), - HOWTO (6, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, - 0xffffffff, 0xffffffff, true), - HOWTO (7, 2, 2, 26, false, 0, complain_overflow_signed, - MY(fix_pcrel_26_done), "ARM26D", true, 0x0, 0x0, - false), - {-1}, - HOWTO (9, 0, -1, 16, false, 0, complain_overflow_bitfield, 0, "NEG16", true, - 0x0000ffff, 0x0000ffff, false), - HOWTO (10, 0, -2, 32, false, 0, complain_overflow_bitfield, 0, "NEG32", true, - 0xffffffff, 0xffffffff, false) -}; - -#define RELOC_ARM_BITS_NEG_BIG ((unsigned int) 0x08) -#define RELOC_ARM_BITS_NEG_LITTLE ((unsigned int) 0x10) - -reloc_howto_type * -MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel) - bfd *abfd; - struct reloc_std_external *rel; - int *r_index; - int *r_extern; - int *r_pcrel; -{ - unsigned int r_length; - unsigned int r_pcrel_done; - unsigned int r_neg; - int index; - - *r_pcrel = 0; - if (bfd_header_big_endian (abfd)) - { - *r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); - r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_BIG)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG); - } - else - { - *r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_LITTLE)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE); - } - index = r_length + 4 * r_pcrel_done + 8 * r_neg; - if (index == 3) - *r_pcrel = 1; - - return MY(howto_table) + index; -} - -#define MY_reloc_howto(BFD, REL, IN, EX, PC) \ - MY(reloc_howto) (BFD, REL, &IN, &EX, &PC) - -void -MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc) - bfd *abfd; - int r_extern; - int r_index; - long value; - reloc_howto_type *howto; - struct reloc_std_external *reloc; -{ - unsigned int r_length; - int r_pcrel; - int r_neg; - - PUT_WORD (abfd, value, reloc->r_address); - r_length = howto->size ; /* Size as a power of two */ - - /* Special case for branch relocations. */ - if (howto->type == 3 || howto->type == 7) - r_length = 3; - - r_pcrel = howto->type & 4; /* PC Relative done? */ - r_neg = howto->type & 8; /* Negative relocation */ - if (bfd_header_big_endian (abfd)) - { - reloc->r_index[0] = r_index >> 16; - reloc->r_index[1] = r_index >> 8; - reloc->r_index[2] = r_index; - reloc->r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) - | (r_neg ? RELOC_ARM_BITS_NEG_BIG : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - reloc->r_index[2] = r_index >> 16; - reloc->r_index[1] = r_index >> 8; - reloc->r_index[0] = r_index; - reloc->r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) - | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } -} - -#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \ - MY(put_reloc)(BFD, EXT, IDX, VAL, HOWTO, RELOC) - -void -MY(relocatable_reloc)(howto, abfd, reloc, amount, r_addr) - reloc_howto_type *howto; - bfd *abfd; - struct reloc_std_external *reloc; - bfd_vma *amount; - bfd_vma r_addr; -{ - if (howto->type == 3) - { - if (reloc->r_type[0] - & (bfd_header_big_endian (abfd) - ? RELOC_STD_BITS_EXTERN_BIG : RELOC_STD_BITS_EXTERN_LITTLE)) - { - /* The reloc is still external, so don't modify anything. */ - *amount = 0; - } - else - { - *amount -= r_addr; - /* Change the r_pcrel value -- on the ARM, this bit is set once the - relocation is done. */ - if (bfd_header_big_endian (abfd)) - reloc->r_type[0] |= RELOC_STD_BITS_PCREL_BIG; - else - reloc->r_type[0] |= RELOC_STD_BITS_PCREL_LITTLE; - } - } - else if (howto->type == 7) - *amount = 0; -} - -#define MY_relocatable_reloc(HOW, BFD, REL, AMOUNT, ADDR) \ - MY(relocatable_reloc)(HOW, BFD, REL, &(AMOUNT), ADDR) - -static bfd_reloc_status_type -MY(fix_pcrel_26_done) (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* This is dead simple at present. */ - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -MY(fix_pcrel_26) (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_size_type addr = reloc_entry->address; - long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); - bfd_reloc_status_type flag = bfd_reloc_ok; - - /* If this is an undefined symbol, return error */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0) - return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined; - - /* If the sections are different, and we are doing a partial relocation, - just ignore it for now. */ - if (symbol->section->name != input_section->name - && output_bfd != (bfd *)NULL) - return bfd_reloc_ok; - - relocation = (target & 0x00ffffff) << 2; - relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ - relocation += symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - relocation -= input_section->output_section->vma; - relocation -= input_section->output_offset; - relocation -= addr; - if (relocation & 3) - return bfd_reloc_overflow; - - /* Check for overflow */ - if (relocation & 0x02000000) - { - if ((relocation & ~0x03ffffff) != ~0x03ffffff) - flag = bfd_reloc_overflow; - } - else if (relocation & ~0x03ffffff) - flag = bfd_reloc_overflow; - - target &= ~0x00ffffff; - target |= (relocation >> 2) & 0x00ffffff; - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); - - /* Now the ARM magic... Change the reloc type so that it is marked as done. - Strictly this is only necessary if we are doing a partial relocation. */ - reloc_entry->howto = &MY(howto_table)[7]; - - return flag; -} - -reloc_howto_type * -MY(bfd_reloc_type_lookup)(abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ -#define ASTD(i,j) case i: return &MY(howto_table)[j] - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - default: return (CONST struct reloc_howto_struct *) 0; - } - - switch (code) - { - ASTD (BFD_RELOC_16, 1); - ASTD (BFD_RELOC_32, 2); - ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); - ASTD (BFD_RELOC_8_PCREL, 4); - ASTD (BFD_RELOC_16_PCREL, 5); - ASTD (BFD_RELOC_32_PCREL, 6); - default: return (CONST struct reloc_howto_struct *) 0; - } -} - -#define MY_swap_std_reloc_in MY(swap_std_reloc_in) -#define MY_swap_std_reloc_out MY(swap_std_reloc_out) -#define MY_get_section_contents _bfd_generic_get_section_contents -/* #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create */ -/* #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols */ -/* #define MY_bfd_final_link _bfd_generic_final_link */ - -#include "aoutx.h" - -static void -MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - unsigned int r_length; - int r_pcrel; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - cache_ptr->howto = MY_reloc_howto (abfd, bytes, r_index, r_extern, r_pcrel); - - MOVE_ADDRESS (0); -} - -void -MY_swap_std_reloc_out (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - int r_length; - int r_pcrel; - int r_neg = 0; /* Negative relocs use the BASEREL bit. */ - asection *output_section = sym->section->output_section; - - PUT_WORD(abfd, g->address, natptr->r_address); - - r_length = g->howto->size ; /* Size as a power of two */ - if (r_length < 0) - { - r_length = -r_length; - r_neg = 1; - } - - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - - /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the - relocation has been done already (Only for the 26-bit one I think)???!!! - */ - - if (g->howto->type == 3) - { - r_length = 3; - r_pcrel = 0; - } - else if (g->howto->type == 7) - { - r_length = 3; - r_pcrel = 1; - } - - -#if 0 - /* For a standard reloc, the addend is in the object file. */ - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; -#endif - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - if (bfd_is_com_section (output_section) - || output_section == &bfd_abs_section - || output_section == &bfd_und_section) - { - if (bfd_abs_section.symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = (*(g->sym_ptr_ptr))->KEEPIT; - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0) - | (r_neg ? RELOC_ARM_BITS_NEG_BIG: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } -} - -#define MY_BFD_TARGET - -#include "aout-target.h" - -const bfd_target aout_arm_little_vec = -{ - "a.out-arm-little", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* target byte order (little) */ - BFD_ENDIAN_LITTLE, /* target headers byte order (little) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - AR_PAD_CHAR, /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (MY), - - (PTR) MY_backend_data, -}; - -const bfd_target aout_arm_big_vec = -{ - "a.out-arm-big", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_BIG, /* target byte order (big) */ - BFD_ENDIAN_BIG, /* target headers byte order (big) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - AR_PAD_CHAR, /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (MY), - - (PTR) MY_backend_data, -}; diff --git a/contrib/gdb/bfd/aout-encap.c b/contrib/gdb/bfd/aout-encap.c deleted file mode 100644 index c25f9037dce..00000000000 --- a/contrib/gdb/bfd/aout-encap.c +++ /dev/null @@ -1,236 +0,0 @@ -/* BFD back-end for a.out files encapsulated with COFF headers. - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* THIS MODULE IS NOT FINISHED. IT PROBABLY DOESN'T EVEN COMPILE. */ - -#if 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0 -#define BYTES_IN_WORD 4 -#endif - -#include "bfd.h" -#include -#include "libbfd.h" -#include -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -const bfd_target *encap_real_callback (); - -const bfd_target * -encap_object_p (abfd) - bfd *abfd; -{ - unsigned char magicbuf[4]; /* Raw bytes of magic number from file */ - unsigned long magic; /* Swapped magic number */ - short coff_magic; - struct external_exec exec_bytes; - struct internal_exec exec; - - if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) != - sizeof (magicbuf)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - coff_magic = bfd_h_get_16 (abfd, magicbuf); - if (coff_magic != COFF_MAGIC) - return 0; /* Not an encap coff file */ - - __header_offset_temp==COFF_MAGIC ? sizeof(struct coffheader) : 0) - (fseek ((f), HEADER_OFFSET((f)), 1)) - - magic = bfd_h_get_32 (abfd, magicbuf); - - if (N_BADMAG (*((struct internal_exec *) &magic))) return 0; - - struct external_exec exec_bytes; - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec); - - return aout_32_some_aout_object_p (abfd, &exec, encap_realcallback); -} - -/* Finish up the reading of a encapsulated-coff a.out file header */ -const bfd_target * -encap_real_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - - MY(callback)(abfd, execp); - - /* If we have a coff header, it can give us better values for - text_start and exec_data_start. This is particularly useful - for remote debugging of embedded systems. */ - if (N_FLAGS(exec_aouthdr) & N_FLAGS_COFF_ENCAPSULATE) - { - struct coffheader ch; - int val; - val = lseek (execchan, -(sizeof (AOUTHDR) + sizeof (ch)), 1); - if (val == -1) - perror_with_name (filename); - val = myread (execchan, &ch, sizeof (ch)); - if (val < 0) - perror_with_name (filename); - text_start = ch.text_start; - exec_data_start = ch.data_start; - } else - { - text_start = - IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr); - exec_data_start = IS_OBJECT_FILE (exec_aouthdr) - ? exec_aouthdr.a_text : N_DATADDR (exec_aouthdr); - } - - /* Determine the architecture and machine type of the object file. */ - bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0); /* FIXME */ - - return abfd->xvec; -} - -/* Write an object file in Encapsulated COFF format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -boolean -encap_write_object_contents (abfd) - bfd *abfd; -{ - bfd_size_type data_pad = 0; - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -/****** FIXME: Fragments from the old GNU LD program for dealing with - encap coff. */ -struct coffheader coffheader; -int need_coff_header; - - /* Determine whether to count the header as part of - the text size, and initialize the text size accordingly. - This depends on the kind of system and on the output format selected. */ - - N_SET_MAGIC (outheader, magic); -#ifdef INITIALIZE_HEADER - INITIALIZE_HEADER; -#endif - - text_size = sizeof (struct exec); -#ifdef COFF_ENCAPSULATE - if (relocatable_output == 0 && file_table[0].just_syms_flag == 0) - { - need_coff_header = 1; - /* set this flag now, since it will change the values of N_TXTOFF, etc */ - N_SET_FLAGS (outheader, aout_backend_info (abfd)->exec_hdr_flags); - text_size += sizeof (struct coffheader); - } -#endif - -#ifdef COFF_ENCAPSULATE - if (need_coff_header) - { - /* We are encapsulating BSD format within COFF format. */ - struct coffscn *tp, *dp, *bp; - - tp = &coffheader.scns[0]; - dp = &coffheader.scns[1]; - bp = &coffheader.scns[2]; - - strcpy (tp->s_name, ".text"); - tp->s_paddr = text_start; - tp->s_vaddr = text_start; - tp->s_size = text_size; - tp->s_scnptr = sizeof (struct coffheader) + sizeof (struct exec); - tp->s_relptr = 0; - tp->s_lnnoptr = 0; - tp->s_nreloc = 0; - tp->s_nlnno = 0; - tp->s_flags = 0x20; - strcpy (dp->s_name, ".data"); - dp->s_paddr = data_start; - dp->s_vaddr = data_start; - dp->s_size = data_size; - dp->s_scnptr = tp->s_scnptr + tp->s_size; - dp->s_relptr = 0; - dp->s_lnnoptr = 0; - dp->s_nreloc = 0; - dp->s_nlnno = 0; - dp->s_flags = 0x40; - strcpy (bp->s_name, ".bss"); - bp->s_paddr = dp->s_vaddr + dp->s_size; - bp->s_vaddr = bp->s_paddr; - bp->s_size = bss_size; - bp->s_scnptr = 0; - bp->s_relptr = 0; - bp->s_lnnoptr = 0; - bp->s_nreloc = 0; - bp->s_nlnno = 0; - bp->s_flags = 0x80; - - coffheader.f_magic = COFF_MAGIC; - coffheader.f_nscns = 3; - /* store an unlikely time so programs can - * tell that there is a bsd header - */ - coffheader.f_timdat = 1; - coffheader.f_symptr = 0; - coffheader.f_nsyms = 0; - coffheader.f_opthdr = 28; - coffheader.f_flags = 0x103; - /* aouthdr */ - coffheader.magic = ZMAGIC; - coffheader.vstamp = 0; - coffheader.tsize = tp->s_size; - coffheader.dsize = dp->s_size; - coffheader.bsize = bp->s_size; - coffheader.entry = outheader.a_entry; - coffheader.text_start = tp->s_vaddr; - coffheader.data_start = dp->s_vaddr; - } -#endif - -#ifdef COFF_ENCAPSULATE - if (need_coff_header) - mywrite (&coffheader, sizeof coffheader, 1, outdesc); -#endif - -#ifndef COFF_ENCAPSULATE - padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc); -#endif - - text_size -= N_TXTOFF (outheader); - WRITE_HEADERS(abfd, execp); - return true; -} - -#define MY_write_object_content encap_write_object_contents -#define MY_object_p encap_object_p -#define MY_exec_hdr_flags N_FLAGS_COFF_ENCAPSULATE - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/aout-ns32k.c b/contrib/gdb/bfd/aout-ns32k.c deleted file mode 100644 index 269e053fe5a..00000000000 --- a/contrib/gdb/bfd/aout-ns32k.c +++ /dev/null @@ -1,399 +0,0 @@ -/* BFD back-end for ns32k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992, 1994, 1995 Free Software Foundation, Inc. - Contributed by Ian Dall (idall@eleceng.adelaide.edu.au). - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 - -#include "bfd.h" -#include "aout/aout64.h" - -#define MYNS(OP) CAT(ns32kaout_,OP) -reloc_howto_type * -MYNS(bfd_reloc_type_lookup) - PARAMS((bfd *abfd AND - bfd_reloc_code_real_type code)); - -boolean -MYNS(write_object_contents) - PARAMS((bfd *abfd)); - -/* Avoid multiple definitions from aoutx if supporting standard a.out format(s) - * as well as this one - */ -#define NAME(x,y) CAT3(ns32kaout,_32_,y) - -void bfd_ns32k_arch PARAMS ((void)); -long ns32k_get_displacement PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_displacement PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -long ns32k_get_immediate PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_immediate PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -bfd_reloc_status_type - ns32k_reloc_disp PARAMS ((bfd *abfd, arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type - ns32k_reloc_imm PARAMS ((bfd *abfd, - arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type - ns32k_final_link_relocate PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - bfd_vma address, - bfd_vma value, - bfd_vma addend )); -bfd_reloc_status_type - ns32k_relocate_contents PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - bfd_vma relocation, - bfd_byte *location)); - -#include "libaout.h" - -#define MY(OP) MYNS(OP) - -#define MY_swap_std_reloc_in MY(swap_std_reloc_in) -#define MY_swap_std_reloc_out MY(swap_std_reloc_out) - -static void -MY_swap_std_reloc_in PARAMS ((bfd *abfd, struct reloc_std_external *bytes, - arelent *cache_ptr, asymbol **symbols, - bfd_size_type symcount)); - -static void -MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g, - struct reloc_std_external *natptr)); - -/* The ns32k series is ah, unusual, when it comes to relocation. - * There are three storage methods for relocateable objects. There - * are displacements, immediate operands and ordinary twos complement - * data. Of these, only the last fits into the standard relocation - * scheme. Immediate operands are stored huffman encoded and - * immediate operands are stored big endian (where as the natural byte - * order is little endian for this achitecture). - - * Note that the ns32k displacement storage method is orthogonal to - * whether the relocation is pc relative or not. The "displacement" - * storage scheme is used for essentially all address constants. The - * displacement can be relative to zero (absolute displacement), - * relative to the pc (pc relative), the stack pointer, the frame - * pointer, the static base register and general purpose register etc. - - * For example: - * - * sym1: .long . # pc relative 2's complement - * sym1: .long foo # 2's complement not pc relative - * - * self: movd @self, r0 # pc relative displacement - * movd foo, r0 # non pc relative displacement - * - * self: movd self, r0 # pc relative immediate - * movd foo, r0 # non pc relative immediate - * - * In addition, for historical reasons the encoding of the relocation types - * in the a.out format relocation entries is such that even the relocation - * methods which are standard are not encoded the standard way. - * - */ - -reloc_howto_type MY(howto_table)[] = -{ -/* ns32k immediate operands */ -HOWTO(BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true, - ns32k_reloc_imm, "NS32K_IMM_8", - true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true, - ns32k_reloc_imm, "NS32K_IMM_16", - true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true, - ns32k_reloc_imm, "NS32K_IMM_32", - true, 0xffffffff,0xffffffff, false), -HOWTO(BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false, - ns32k_reloc_imm, "PCREL_NS32K_IMM_8", - true, 0x000000ff, 0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false, - ns32k_reloc_imm, "PCREL_NS32K_IMM_16", - true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false, - ns32k_reloc_imm, "PCREL_NS32K_IMM_32", - true, 0xffffffff,0xffffffff, false), - -/* ns32k displacements */ -HOWTO(BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true, - ns32k_reloc_disp, "NS32K_DISP_8", - true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true, - ns32k_reloc_disp, "NS32K_DISP_16", - true, 0x0000ffff, 0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true, - ns32k_reloc_disp, "NS32K_DISP_32", - true, 0xffffffff, 0xffffffff, false), -HOWTO(BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false, - ns32k_reloc_disp, "PCREL_NS32K_DISP_8", - true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false, - ns32k_reloc_disp, "PCREL_NS32K_DISP_16", - true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false, - ns32k_reloc_disp, "PCREL_NS32K_DISP_32", - true, 0xffffffff,0xffffffff, false), - -/* Normal 2's complement */ -HOWTO(BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0, - "8", true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0, - "16", true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0, - "32", true, 0xffffffff,0xffffffff, false), -HOWTO(BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0, - "PCREL_8", true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0, - "PCREL_16", true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0, - "PCREL_32", true, 0xffffffff,0xffffffff, false), -}; - - -#define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14) - -#define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06 -#define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60 -#define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1 -#define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE 5 - -reloc_howto_type * -MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel) - bfd *abfd; - struct reloc_std_external *rel; - int *r_index; - int *r_extern; - int *r_pcrel; -{ - unsigned int r_length; - int r_ns32k_type; -/* BFD_ASSERT(bfd_header_little_endian (abfd)); */ - *r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0] ); - *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - *r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE); - r_ns32k_type = ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE) - >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE); - return (MY(howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type); -} - -#define MY_reloc_howto(BFD,REL,IN,EX,PC) MY(reloc_howto)(BFD, REL, &IN, &EX, &PC) - -void -MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc) - bfd *abfd; - int r_extern; - int r_index; - long value; - reloc_howto_type *howto; - struct reloc_std_external *reloc; -{ - unsigned int r_length; - int r_pcrel; - int r_ns32k_type; - PUT_WORD (abfd, value, reloc->r_address); - r_length = howto->size ; /* Size as a power of two */ - r_pcrel = (int) howto->pc_relative; /* Relative to PC? */ - r_ns32k_type = (howto - MY(howto_table) )/6; -/* BFD_ASSERT (bfd_header_little_endian (abfd)); */ - reloc->r_index[2] = r_index >> 16; - reloc->r_index[1] = r_index >> 8; - reloc->r_index[0] = r_index; - reloc->r_type[0] = - (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE) - | (r_ns32k_type << RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE); -} - -#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \ - MY(put_reloc)(BFD, EXT, IDX, VAL, HOWTO, RELOC) - -#define STAT_FOR_EXEC - -#define MY_final_link_relocate ns32k_final_link_relocate -#define MY_relocate_contents ns32k_relocate_contents - -#include - -reloc_howto_type * - MY(bfd_reloc_type_lookup)(abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - -#define ENTRY(i,j) case i: return &MY(howto_table)[j] - - int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE; - - BFD_ASSERT(ext == 0); - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - } - switch (code) - { - ENTRY(BFD_RELOC_NS32K_IMM_8, 0); - ENTRY(BFD_RELOC_NS32K_IMM_16, 1); - ENTRY(BFD_RELOC_NS32K_IMM_32, 2); - ENTRY(BFD_RELOC_NS32K_IMM_8_PCREL, 3); - ENTRY(BFD_RELOC_NS32K_IMM_16_PCREL, 4); - ENTRY(BFD_RELOC_NS32K_IMM_32_PCREL, 5); - ENTRY(BFD_RELOC_NS32K_DISP_8, 6); - ENTRY(BFD_RELOC_NS32K_DISP_16, 7); - ENTRY(BFD_RELOC_NS32K_DISP_32, 8); - ENTRY(BFD_RELOC_NS32K_DISP_8_PCREL, 9); - ENTRY(BFD_RELOC_NS32K_DISP_16_PCREL, 10); - ENTRY(BFD_RELOC_NS32K_DISP_32_PCREL, 11); - ENTRY(BFD_RELOC_8, 12); - ENTRY(BFD_RELOC_16, 13); - ENTRY(BFD_RELOC_32, 14); - ENTRY(BFD_RELOC_8_PCREL, 15); - ENTRY(BFD_RELOC_16_PCREL, 16); - ENTRY(BFD_RELOC_32_PCREL, 17); - default: return (reloc_howto_type *) NULL; - } -#undef ENTRY -} - - -static void -MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - int r_pcrel; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - /* now the fun stuff */ - - cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel); - - MOVE_ADDRESS(0); -} - -static void -MY_swap_std_reloc_out (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - unsigned int r_addend; - asection *output_section = sym->section->output_section; - - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - Check for that here. */ - - if (bfd_is_com_section (output_section) - || output_section == &bfd_abs_section - || output_section == &bfd_und_section) - { - if (bfd_abs_section.symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; -#undef KEEPIT -#define KEEPIT udata.i - r_index = (*(g->sym_ptr_ptr))->KEEPIT; -#undef KEEPIT - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr); -} - -bfd_reloc_status_type -ns32k_relocate_contents (howto, input_bfd, relocation, location) - reloc_howto_type *howto; - bfd *input_bfd; - bfd_vma relocation; - bfd_byte *location; -{ - int r_ns32k_type = (howto - MY(howto_table)) / 6; - long (*get_data)(); - int (*put_data)(); - - switch (r_ns32k_type) - { - case 0: - get_data = ns32k_get_immediate; - put_data = ns32k_put_immediate; - break; - case 1: - get_data = ns32k_get_displacement; - put_data = ns32k_put_displacement; - break; - case 2: - return _bfd_relocate_contents (howto, input_bfd, relocation, - location); - /* NOT REACHED */ - break; - } - return do_ns32k_reloc_contents (howto, input_bfd, relocation, - location, get_data, put_data); -} diff --git a/contrib/gdb/bfd/aout-target.h b/contrib/gdb/bfd/aout-target.h deleted file mode 100644 index 6711a714a57..00000000000 --- a/contrib/gdb/bfd/aout-target.h +++ /dev/null @@ -1,607 +0,0 @@ -/* Define a target vector and some small routines for a variant of a.out. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -/*#include "libaout.h"*/ - -extern reloc_howto_type * 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 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); - - /* The virtual memory addresses of the sections */ - obj_textsec (abfd)->vma = N_TXTADDR(*execp); - obj_datasec (abfd)->vma = N_DATADDR(*execp); - obj_bsssec (abfd)->vma = N_BSSADDR(*execp); - - obj_textsec (abfd)->lma = obj_textsec (abfd)->vma; - obj_datasec (abfd)->lma = obj_datasec (abfd)->vma; - obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma; - - /* The file offsets of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF (*execp); - obj_datasec (abfd)->filepos = N_DATOFF (*execp); - - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); - - /* The file offsets of the string table and symbol table. */ - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - obj_str_filepos (abfd) = N_STROFF (*execp); - - /* Determine the architecture and machine type of the object file. */ -#ifdef SET_ARCH_MACH - SET_ARCH_MACH(abfd, *execp); -#else - bfd_default_set_arch_mach(abfd, DEFAULT_ARCH, 0); -#endif - - /* 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 - adata(abfd).page_size = TARGET_PAGE_SIZE; -#ifdef SEGMENT_SIZE - adata(abfd).segment_size = SEGMENT_SIZE; -#else - adata(abfd).segment_size = TARGET_PAGE_SIZE; -#endif - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; -#endif - - return abfd->xvec; -} -#endif - -#ifndef MY_object_p -/* Finish up the reading of an a.out file header */ - -static const bfd_target * -MY(object_p) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; /* Raw exec header from file */ - struct internal_exec exec; /* Cleaned-up exec header */ - const bfd_target *target; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - -#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 /* SWAP_MAGIC */ - - if (N_BADMAG (exec)) return 0; -#ifdef MACHTYPE_OK - if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0; -#endif - - NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec); - -#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 - /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage) - * means that it isn't obvious if EXEC_P should be set. - * All of the following must be true for an executable: - * There must be no relocations, the bfd can be neither an - * archive nor an archive element, and the file must be executable. */ - - if (exec.a_trsize + exec.a_drsize == 0 - && bfd_get_format(abfd) == bfd_object && abfd->my_archive == NULL) - { - struct stat buf; -#ifndef S_IXUSR -#define S_IXUSR 0100 /* Execute by owner. */ -#endif - if (stat(abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR)) - abfd->flags |= EXEC_P; - } -#endif /* ENTRY_CAN_BE_ZERO */ - - return target; -} -#define MY_object_p MY(object_p) -#endif - - -#ifndef MY_mkobject -static boolean -MY(mkobject) (abfd) - bfd *abfd; -{ - if (NAME(aout,mkobject)(abfd) == false) - return false; -#if 0 /* Sizes get set in set_sizes callback, later, after we know - the architecture and machine. */ - adata(abfd).page_size = TARGET_PAGE_SIZE; -#ifdef SEGMENT_SIZE - adata(abfd).segment_size = SEGMENT_SIZE; -#else - adata(abfd).segment_size = TARGET_PAGE_SIZE; -#endif - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; -#endif - return true; -} -#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; -{ - if (bfd_get_flavour (obfd) == bfd_target_aout_flavour) - 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 -MY(write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE(abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - WRITE_HEADERS(abfd, execp); - - return true; -} -#define MY_write_object_contents MY(write_object_contents) -#endif - -#ifndef MY_set_sizes -static boolean -MY(set_sizes) (abfd) - bfd *abfd; -{ - adata(abfd).page_size = TARGET_PAGE_SIZE; - -#ifdef SEGMENT_SIZE - adata(abfd).segment_size = SEGMENT_SIZE; -#else - adata(abfd).segment_size = TARGET_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 = TARGET_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_zmagic_contiguous -#define MY_zmagic_contiguous 0 -#endif -#ifndef MY_text_includes_header -#define MY_text_includes_header 0 -#endif -#ifndef MY_exec_header_not_counted -#define MY_exec_header_not_counted 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) = { - MY_zmagic_contiguous, - MY_text_includes_header, - MY_exec_hdr_flags, - 0, /* text vma? */ - MY_set_sizes, - MY_exec_header_not_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 -#endif -#ifndef MY_get_elt_at_index -#define MY_get_elt_at_index _bfd_generic_get_elt_at_index -#endif -#ifndef MY_generic_stat_arch_elt -#define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt -#endif -#ifndef MY_slurp_armap -#define MY_slurp_armap bfd_slurp_bsd_armap -#endif -#ifndef MY_slurp_extended_name_table -#define MY_slurp_extended_name_table _bfd_slurp_extended_name_table -#endif -#ifndef MY_construct_extended_name_table -#define MY_construct_extended_name_table \ - _bfd_archive_bsd_construct_extended_name_table -#endif -#ifndef MY_write_armap -#define MY_write_armap bsd_write_armap -#endif -#ifndef MY_read_ar_hdr -#define MY_read_ar_hdr _bfd_generic_read_ar_hdr -#endif -#ifndef MY_truncate_arname -#define MY_truncate_arname bfd_bsd_truncate_arname -#endif -#ifndef MY_update_armap_timestamp -#define MY_update_armap_timestamp _bfd_archive_bsd_update_armap_timestamp -#endif - -/* No core file defined here -- configure in trad-core.c separately. */ -#ifndef MY_core_file_failing_command -#define MY_core_file_failing_command _bfd_nocore_core_file_failing_command -#endif -#ifndef MY_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_nocore_core_file_matches_executable_p -#endif -#ifndef MY_core_file_p -#define MY_core_file_p _bfd_dummy_target -#endif - -#ifndef MY_bfd_debug_info_start -#define MY_bfd_debug_info_start bfd_void -#endif -#ifndef MY_bfd_debug_info_end -#define MY_bfd_debug_info_end bfd_void -#endif -#ifndef MY_bfd_debug_info_accumulate -#define MY_bfd_debug_info_accumulate \ - (void (*) PARAMS ((bfd*, struct sec *))) bfd_void -#endif - -#ifndef MY_core_file_failing_command -#define MY_core_file_failing_command NAME(aout,core_file_failing_command) -#endif -#ifndef MY_core_file_failing_signal -#define MY_core_file_failing_signal NAME(aout,core_file_failing_signal) -#endif -#ifndef MY_core_file_matches_executable_p -#define MY_core_file_matches_executable_p NAME(aout,core_file_matches_executable_p) -#endif -#ifndef MY_set_section_contents -#define MY_set_section_contents NAME(aout,set_section_contents) -#endif -#ifndef MY_get_section_contents -#define MY_get_section_contents NAME(aout,get_section_contents) -#endif -#ifndef MY_get_section_contents_in_window -#define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#endif -#ifndef MY_new_section_hook -#define MY_new_section_hook NAME(aout,new_section_hook) -#endif -#ifndef MY_get_symtab_upper_bound -#define MY_get_symtab_upper_bound NAME(aout,get_symtab_upper_bound) -#endif -#ifndef MY_get_symtab -#define MY_get_symtab NAME(aout,get_symtab) -#endif -#ifndef MY_get_reloc_upper_bound -#define MY_get_reloc_upper_bound NAME(aout,get_reloc_upper_bound) -#endif -#ifndef MY_canonicalize_reloc -#define MY_canonicalize_reloc NAME(aout,canonicalize_reloc) -#endif -#ifndef MY_make_empty_symbol -#define MY_make_empty_symbol NAME(aout,make_empty_symbol) -#endif -#ifndef MY_print_symbol -#define MY_print_symbol NAME(aout,print_symbol) -#endif -#ifndef MY_get_symbol_info -#define MY_get_symbol_info NAME(aout,get_symbol_info) -#endif -#ifndef MY_get_lineno -#define MY_get_lineno NAME(aout,get_lineno) -#endif -#ifndef MY_set_arch_mach -#define MY_set_arch_mach NAME(aout,set_arch_mach) -#endif -#ifndef MY_find_nearest_line -#define MY_find_nearest_line NAME(aout,find_nearest_line) -#endif -#ifndef MY_sizeof_headers -#define MY_sizeof_headers NAME(aout,sizeof_headers) -#endif -#ifndef MY_bfd_get_relocated_section_contents -#define MY_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#endif -#ifndef MY_bfd_relax_section -#define MY_bfd_relax_section bfd_generic_relax_section -#endif -#ifndef MY_bfd_reloc_type_lookup -#define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup) -#endif -#ifndef MY_bfd_make_debug_symbol -#define MY_bfd_make_debug_symbol 0 -#endif -#ifndef MY_read_minisymbols -#define MY_read_minisymbols NAME(aout,read_minisymbols) -#endif -#ifndef MY_minisymbol_to_symbol -#define MY_minisymbol_to_symbol NAME(aout,minisymbol_to_symbol) -#endif -#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_link_split_section -#define MY_bfd_link_split_section _bfd_generic_link_split_section -#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_merge_private_bfd_data -#define MY_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data -#endif - -#ifndef MY_bfd_copy_private_symbol_data -#define MY_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data -#endif - -#ifndef MY_bfd_print_private_bfd_data -#define MY_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data -#endif - -#ifndef MY_bfd_set_private_flags -#define MY_bfd_set_private_flags _bfd_generic_bfd_set_private_flags -#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 */ -#ifndef MY_symbol_leading_char -#define MY_symbol_leading_char '_' -#endif - -/* Aout archives normally use spaces for padding */ -#ifndef AR_PAD_CHAR -#define AR_PAD_CHAR ' ' -#endif - -#ifndef MY_BFD_TARGET -const bfd_target MY(vec) = -{ - TARGETNAME, /* name */ - bfd_target_aout_flavour, -#ifdef TARGET_IS_BIG_ENDIAN_P - BFD_ENDIAN_BIG, /* target byte order (big) */ - BFD_ENDIAN_BIG, /* target headers byte order (big) */ -#else - BFD_ENDIAN_LITTLE, /* target byte order (little) */ - BFD_ENDIAN_LITTLE, /* target headers byte order (little) */ -#endif - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - AR_PAD_CHAR, /* ar_pad_char */ - 15, /* ar_max_namelen */ -#ifdef TARGET_IS_BIG_ENDIAN_P - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ -#else - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ -#endif - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - 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 */ diff --git a/contrib/gdb/bfd/aout0.c b/contrib/gdb/bfd/aout0.c deleted file mode 100644 index 5bc7ae0f67f..00000000000 --- a/contrib/gdb/bfd/aout0.c +++ /dev/null @@ -1,32 +0,0 @@ -/* BFD backend for SunOS style a.out with flags set to 0 - Copyright (C) 1990, 91, 92, 93, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGETNAME "a.out-zero-big" -#define MY(OP) CAT(aout0_big_,OP) - -#include "bfd.h" - -#define MY_exec_hdr_flags 0 - -#define MACHTYPE_OK(mtype) \ - ((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) - -/* Include the usual a.out support. */ -#include "aoutf1.h" diff --git a/contrib/gdb/bfd/aout32.c b/contrib/gdb/bfd/aout32.c deleted file mode 100644 index bfc40b46303..00000000000 --- a/contrib/gdb/bfd/aout32.c +++ /dev/null @@ -1,23 +0,0 @@ -/* BFD back-end for 32-bit a.out files. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define ARCH_SIZE 32 - -#include "aoutx.h" diff --git a/contrib/gdb/bfd/aout64.c b/contrib/gdb/bfd/aout64.c deleted file mode 100644 index 84036c885a2..00000000000 --- a/contrib/gdb/bfd/aout64.c +++ /dev/null @@ -1,31 +0,0 @@ -/* BFD back-end for 64-bit a.out files. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define ARCH_SIZE 64 - -/* aoutx.h requires definitions for BMAGIC and QMAGIC. */ -#ifndef BMAGIC -#define BMAGIC 0 -#endif -#ifndef QMAGIC -#define QMAGIC 0 -#endif - -#include "aoutx.h" diff --git a/contrib/gdb/bfd/aoutf1.h b/contrib/gdb/bfd/aoutf1.h deleted file mode 100644 index 690d528b5c4..00000000000 --- a/contrib/gdb/bfd/aoutf1.h +++ /dev/null @@ -1,788 +0,0 @@ -/* A.out "format 1" file handling code for BFD. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "aout/sun4.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" - -/* This is needed to reject a NewsOS file, e.g. in - gdb/testsuite/gdb.t10/crossload.exp. - I needed to add M_UNKNOWN to recognize a 68000 object, so this will - probably no longer reject a NewsOS object. . */ -#ifndef MACHTYPE_OK -#define MACHTYPE_OK(mtype) \ - (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \ - || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \ - && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL)) -#endif - -/* -The file @code{aoutf1.h} contains the code for BFD's -a.out back end. Control over the generated back end is given by these -two preprocessor names: -@table @code -@item ARCH_SIZE -This value should be either 32 or 64, depending upon the size of an -int in the target format. It changes the sizes of the structs which -perform the memory/disk mapping of structures. - -The 64 bit backend may only be used if the host compiler supports 64 -ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. -With this name defined, @emph{all} bfd operations are performed with 64bit -arithmetic, not just those to a 64bit target. - -@item TARGETNAME -The name put into the target vector. -@item -@end table - -*/ - -/*SUPPRESS558*/ -/*SUPPRESS529*/ - -static void -#if ARCH_SIZE == 64 -sunos_64_set_arch_mach -#else -sunos_32_set_arch_mach -#endif - (abfd, machtype) - bfd *abfd; - int machtype; -{ - /* Determine the architecture and machine type of the object file. */ - enum bfd_architecture arch; - long machine; - switch (machtype) - { - - case M_UNKNOWN: - /* Some Sun3s make magic numbers without cpu types in them, so - we'll default to the 68000. */ - arch = bfd_arch_m68k; - machine = 68000; - break; - - case M_68010: - case M_HP200: - arch = bfd_arch_m68k; - machine = 68010; - break; - - case M_68020: - case M_HP300: - arch = bfd_arch_m68k; - machine = 68020; - break; - - case M_SPARC: - arch = bfd_arch_sparc; - machine = 0; - break; - - case M_386: - case M_386_DYNIX: - arch = bfd_arch_i386; - machine = 0; - break; - - case M_29K: - arch = bfd_arch_a29k; - machine = 0; - break; - - case M_HPUX: - arch = bfd_arch_m68k; - machine = 0; - break; - - default: - arch = bfd_arch_obscure; - machine = 0; - break; - } - bfd_set_arch_mach (abfd, arch, machine); -} - -#define SET_ARCH_MACH(ABFD, EXEC) \ - NAME(sunos,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ - choose_reloc_size(ABFD); - -/* Determine the size of a relocation entry, based on the architecture */ -static void -choose_reloc_size (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_sparc: - case bfd_arch_a29k: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } -} - -/* Write an object file in SunOS format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -#if ARCH_SIZE == 64 -aout_64_sunos4_write_object_contents -#else -aout_32_sunos4_write_object_contents -#endif - (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - /* Magic number, maestro, please! */ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - switch (bfd_get_mach (abfd)) - { - case 68000: - N_SET_MACHTYPE (*execp, M_UNKNOWN); - break; - case 68010: - N_SET_MACHTYPE (*execp, M_68010); - break; - default: - case 68020: - N_SET_MACHTYPE (*execp, M_68020); - break; - } - break; - case bfd_arch_sparc: - N_SET_MACHTYPE (*execp, M_SPARC); - break; - case bfd_arch_i386: - N_SET_MACHTYPE (*execp, M_386); - break; - case bfd_arch_a29k: - N_SET_MACHTYPE (*execp, M_29K); - break; - default: - N_SET_MACHTYPE (*execp, M_UNKNOWN); - } - - choose_reloc_size (abfd); - - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - N_SET_DYNAMIC (*execp, bfd_get_file_flags (abfd) & DYNAMIC); - - WRITE_HEADERS (abfd, execp); - - return true; -} - -/* core files */ - -#define CORE_MAGIC 0x080456 -#define CORE_NAMELEN 16 - -/* The core structure is taken from the Sun documentation. - Unfortunately, they don't document the FPA structure, or at least I - can't find it easily. Fortunately the core header contains its own - length. So this shouldn't cause problems, except for c_ucode, which - so far we don't use but is easy to find with a little arithmetic. */ - -/* But the reg structure can be gotten from the SPARC processor handbook. - This really should be in a GNU include file though so that gdb can use - the same info. */ -struct regs -{ - int r_psr; - int r_pc; - int r_npc; - int r_y; - int r_g1; - int r_g2; - int r_g3; - int r_g4; - int r_g5; - int r_g6; - int r_g7; - int r_o0; - int r_o1; - int r_o2; - int r_o3; - int r_o4; - int r_o5; - int r_o6; - int r_o7; -}; - -/* Taken from Sun documentation: */ - -/* FIXME: It's worse than we expect. This struct contains TWO substructs - neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't - even portably access the stuff in between! */ - -struct external_sparc_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ -#define SPARC_CORE_LEN 432 - int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */ - struct external_exec c_aouthdr; /* A.out header */ - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - int c_ssize; /* Stack size (bytes) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - double fp_stuff[1]; /* external FPU state (size unknown by us) */ - /* The type "double" is critical here, for alignment. - SunOS declares a struct here, but the struct's alignment - is double since it contains doubles. */ - int c_ucode; /* Exception no. from u_code */ - /* (this member is not accessible by name since we don't - portably know the size of fp_stuff.) */ - }; - -/* Core files generated by the BCP (the part of Solaris which allows - it to run SunOS4 a.out files). */ -struct external_solaris_bcp_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ -#define SOLARIS_BCP_CORE_LEN 456 - int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */ - int c_exdata_vp; /* exdata structure */ - int c_exdata_tsize; - int c_exdata_dsize; - int c_exdata_bsize; - int c_exdata_lsize; - int c_exdata_nshlibs; - short c_exdata_mach; - short c_exdata_mag; - int c_exdata_toffset; - int c_exdata_doffset; - int c_exdata_loffset; - int c_exdata_txtorg; - int c_exdata_datorg; - int c_exdata_entloc; - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - int c_ssize; /* Stack size (bytes) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - double fp_stuff[1]; /* external FPU state (size unknown by us) */ - /* The type "double" is critical here, for alignment. - SunOS declares a struct here, but the struct's alignment - is double since it contains doubles. */ - int c_ucode; /* Exception no. from u_code */ - /* (this member is not accessible by name since we don't - portably know the size of fp_stuff.) */ - }; - -struct external_sun3_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ -#define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1 */ - int c_regs[18]; /* General purpose registers -- MACHDEP SIZE */ - struct external_exec c_aouthdr; /* A.out header */ - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - int c_ssize; /* Stack size (bytes) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - double fp_stuff[1]; /* external FPU state (size unknown by us) */ - /* The type "double" is critical here, for alignment. - SunOS declares a struct here, but the struct's alignment - is double since it contains doubles. */ - int c_ucode; /* Exception no. from u_code */ - /* (this member is not accessible by name since we don't - portably know the size of fp_stuff.) */ - }; - -struct internal_sunos_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ - long c_regs_pos; /* file offset of General purpose registers */ - int c_regs_size; /* size of General purpose registers */ - struct internal_exec c_aouthdr; /* A.out header */ - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - bfd_vma c_data_addr; /* Data start (address) */ - int c_ssize; /* Stack size (bytes) */ - bfd_vma c_stacktop; /* Stack top (address) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - long fp_stuff_pos; /* file offset of external FPU state (regs) */ - int fp_stuff_size; /* Size of it */ - int c_ucode; /* Exception no. from u_code */ - }; - -/* byte-swap in the Sun-3 core structure */ -static void -swapcore_sun3 (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; -{ - struct external_sun3_core *extcore = (struct external_sun3_core *) ext; - - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs); - intcore->c_regs_size = sizeof (extcore->c_regs); -#if ARCH_SIZE == 64 - aout_64_swap_exec_header_in -#else - aout_32_swap_exec_header_in -#endif - (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); - memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ - intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff); - /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); - intcore->c_stacktop = 0x0E000000; /* By experimentation */ -} - - -/* byte-swap in the Sparc core structure */ -static void -swapcore_sparc (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; -{ - struct external_sparc_core *extcore = (struct external_sparc_core *) ext; - - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs); - intcore->c_regs_size = sizeof (extcore->c_regs); -#if ARCH_SIZE == 64 - aout_64_swap_exec_header_in -#else - aout_32_swap_exec_header_in -#endif - (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); - memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ - intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff); - /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); - - /* Supposedly the user stack grows downward from the bottom of kernel memory. - Presuming that this remains true, this definition will work. */ - /* Now sun has provided us with another challenge. The value is different - for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or - the other based on the current value of the stack pointer. This - loses (a) if the stack pointer has been clobbered, or (b) if the stack - is larger than 128 megabytes. - - It's times like these you're glad they're switching to ELF. - - Note that using include files or nlist on /vmunix would be wrong, - because we want the value for this core file, no matter what kind of - machine we were compiled on or are running on. */ -#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) -#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) - { - bfd_vma sp = bfd_h_get_32 - (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6); - if (sp < SPARC_USRSTACK_SPARC10) - intcore->c_stacktop = SPARC_USRSTACK_SPARC10; - else - intcore->c_stacktop = SPARC_USRSTACK_SPARC2; - } -} - -/* byte-swap in the Solaris BCP core structure */ -static void -swapcore_solaris_bcp (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; -{ - struct external_solaris_bcp_core *extcore = - (struct external_solaris_bcp_core *) ext; - - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_solaris_bcp_core *) 0)->c_regs); - intcore->c_regs_size = sizeof (extcore->c_regs); - - /* The Solaris BCP exdata structure does not contain an a_syms field, - so we are unable to synthesize an internal exec header. - Luckily we are able to figure out the start address of the data section, - which is the only thing needed from the internal exec header, - from the exdata structure. - - As of Solaris 2.3, BCP core files for statically linked executables - are buggy. The exdata structure is not properly filled in, and - the data section is written from address zero instead of the data - start address. */ - memset ((PTR) &intcore->c_aouthdr, 0, sizeof (struct internal_exec)); - intcore->c_data_addr = - bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_exdata_datorg); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); - memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = - (long) (((struct external_solaris_bcp_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ - intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_solaris_bcp_core *) 0)->fp_stuff); - /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); - - /* Supposedly the user stack grows downward from the bottom of kernel memory. - Presuming that this remains true, this definition will work. */ - /* Now sun has provided us with another challenge. The value is different - for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or - the other based on the current value of the stack pointer. This - loses (a) if the stack pointer has been clobbered, or (b) if the stack - is larger than 128 megabytes. - - It's times like these you're glad they're switching to ELF. - - Note that using include files or nlist on /vmunix would be wrong, - because we want the value for this core file, no matter what kind of - machine we were compiled on or are running on. */ -#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) -#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) - { - bfd_vma sp = bfd_h_get_32 - (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6); - if (sp < SPARC_USRSTACK_SPARC10) - intcore->c_stacktop = SPARC_USRSTACK_SPARC10; - else - intcore->c_stacktop = SPARC_USRSTACK_SPARC2; - } -} - -/* need this cast because ptr is really void * */ -#define core_hdr(bfd) ((bfd)->tdata.sun_core_data) -#define core_datasec(bfd) (core_hdr(bfd)->data_section) -#define core_stacksec(bfd) (core_hdr(bfd)->stack_section) -#define core_regsec(bfd) (core_hdr(bfd)->reg_section) -#define core_reg2sec(bfd) (core_hdr(bfd)->reg2_section) - -/* These are stored in the bfd's tdata */ -struct sun_core_struct -{ - struct internal_sunos_core *hdr; /* core file header */ - asection *data_section; - asection *stack_section; - asection *reg_section; - asection *reg2_section; -}; - -static const bfd_target * -sunos4_core_file_p (abfd) - bfd *abfd; -{ - unsigned char longbuf[4]; /* Raw bytes of various header fields */ - bfd_size_type core_size; - unsigned long core_mag; - struct internal_sunos_core *core; - char *extcore; - struct mergem - { - struct sun_core_struct suncoredata; - struct internal_sunos_core internal_sunos_core; - char external_core[1]; - } - *mergem; - - if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) != - sizeof (longbuf)) - return 0; - core_mag = bfd_h_get_32 (abfd, longbuf); - - if (core_mag != CORE_MAGIC) - return 0; - - /* SunOS core headers can vary in length; second word is size; */ - if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) != - sizeof (longbuf)) - return 0; - core_size = bfd_h_get_32 (abfd, longbuf); - /* Sanity check */ - if (core_size > 20000) - return 0; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0) - return 0; - - mergem = (struct mergem *) bfd_zalloc (abfd, core_size + sizeof (struct mergem)); - if (mergem == NULL) - return 0; - - extcore = mergem->external_core; - - if ((bfd_read ((PTR) extcore, 1, core_size, abfd)) != core_size) - { - bfd_release (abfd, (char *) mergem); - return 0; - } - - /* Validate that it's a core file we know how to handle, due to sun - botching the positioning of registers and other fields in a machine - dependent way. */ - core = &mergem->internal_sunos_core; - switch (core_size) - { - case SPARC_CORE_LEN: - swapcore_sparc (abfd, extcore, core); - break; - case SUN3_CORE_LEN: - swapcore_sun3 (abfd, extcore, core); - break; - case SOLARIS_BCP_CORE_LEN: - swapcore_solaris_bcp (abfd, extcore, core); - break; - default: - bfd_set_error (bfd_error_system_call); /* FIXME */ - bfd_release (abfd, (char *) mergem); - return 0; - } - - abfd->tdata.sun_core_data = &mergem->suncoredata; - abfd->tdata.sun_core_data->hdr = core; - - /* create the sections. This is raunchy, but bfd_close wants to reclaim - them */ - core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_stacksec (abfd) == NULL) - { - loser: - bfd_release (abfd, (char *) mergem); - return 0; - } - core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_datasec (abfd) == NULL) - { - loser1: - bfd_release (abfd, core_stacksec (abfd)); - goto loser; - } - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) - { - loser2: - bfd_release (abfd, core_datasec (abfd)); - goto loser1; - } - core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_reg2sec (abfd) == NULL) - { - bfd_release (abfd, core_regsec (abfd)); - goto loser2; - } - - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - core_reg2sec (abfd)->name = ".reg2"; - - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; - - core_stacksec (abfd)->_raw_size = core->c_ssize; - core_datasec (abfd)->_raw_size = core->c_dsize; - core_regsec (abfd)->_raw_size = core->c_regs_size; - core_reg2sec (abfd)->_raw_size = core->fp_stuff_size; - - core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize); - core_datasec (abfd)->vma = core->c_data_addr; - core_regsec (abfd)->vma = 0; - core_reg2sec (abfd)->vma = 0; - - core_stacksec (abfd)->filepos = core->c_len + core->c_dsize; - core_datasec (abfd)->filepos = core->c_len; - /* We'll access the regs afresh in the core file, like any section: */ - core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos; - core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos; - - /* Align to word at least */ - core_stacksec (abfd)->alignment_power = 2; - core_datasec (abfd)->alignment_power = 2; - core_regsec (abfd)->alignment_power = 2; - core_reg2sec (abfd)->alignment_power = 2; - - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_datasec (abfd); - core_datasec (abfd)->next = core_regsec (abfd); - core_regsec (abfd)->next = core_reg2sec (abfd); - - abfd->section_count = 4; - - return abfd->xvec; -} - -static char * -sunos4_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->hdr->c_cmdname; -} - -static int -sunos4_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->hdr->c_signo; -} - -static boolean -sunos4_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - if (core_bfd->xvec != exec_bfd->xvec) - { - bfd_set_error (bfd_error_system_call); - return false; - } - - /* Solaris core files do not include an aouthdr. */ - if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN) - return true; - - return (memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr), - (char *) exec_hdr (exec_bfd), - sizeof (struct internal_exec)) == 0) ? true : false; -} - -#define MY_set_sizes sunos4_set_sizes -static boolean -sunos4_set_sizes (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - default: - return false; - case bfd_arch_sparc: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x2000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - case bfd_arch_m68k: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x20000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - } -} - -/* We default to setting the toolversion field to 1, as is required by - SunOS. */ -#ifndef MY_exec_hdr_flags -#define MY_exec_hdr_flags 1 -#endif - -#ifndef MY_add_dynamic_symbols -#define MY_add_dynamic_symbols 0 -#endif -#ifndef MY_add_one_symbol -#define MY_add_one_symbol 0 -#endif -#ifndef MY_link_dynamic_object -#define MY_link_dynamic_object 0 -#endif -#ifndef MY_write_dynamic_symbol -#define MY_write_dynamic_symbol 0 -#endif -#ifndef MY_check_dynamic_reloc -#define MY_check_dynamic_reloc 0 -#endif -#ifndef MY_finish_dynamic_link -#define MY_finish_dynamic_link 0 -#endif - -static CONST struct aout_backend_data sunos4_aout_backend = -{ - 0, /* zmagic files are not contiguous */ - 1, /* text includes header */ - MY_exec_hdr_flags, - 0, /* default text vma */ - sunos4_set_sizes, - 0, /* header is counted in zmagic text */ - MY_add_dynamic_symbols, - MY_add_one_symbol, - MY_link_dynamic_object, - MY_write_dynamic_symbol, - MY_check_dynamic_reloc, - MY_finish_dynamic_link -}; - -#define MY_core_file_failing_command sunos4_core_file_failing_command -#define MY_core_file_failing_signal sunos4_core_file_failing_signal -#define MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p - -#define MY_bfd_debug_info_start bfd_void -#define MY_bfd_debug_info_end bfd_void -#define MY_bfd_debug_info_accumulate \ - (void (*) PARAMS ((bfd *, struct sec *))) bfd_void -#define MY_core_file_p sunos4_core_file_p -#define MY_write_object_contents NAME(aout,sunos4_write_object_contents) -#define MY_backend_data &sunos4_aout_backend - -#define TARGET_IS_BIG_ENDIAN_P - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/aoutx.h b/contrib/gdb/bfd/aoutx.h deleted file mode 100644 index 4b04943e028..00000000000 --- a/contrib/gdb/bfd/aoutx.h +++ /dev/null @@ -1,5525 +0,0 @@ -/* BFD semi-generic back-end for a.out binaries. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - a.out backends - - -DESCRIPTION - - BFD supports a number of different flavours of a.out format, - though the major differences are only the sizes of the - structures on disk, and the shape of the relocation - information. - - The support is split into a basic support file @file{aoutx.h} - and other files which derive functions from the base. One - derivation file is @file{aoutf1.h} (for a.out flavour 1), and - adds to the basic a.out functions support for sun3, sun4, 386 - and 29k a.out files, to create a target jump vector for a - specific target. - - This information is further split out into more specific files - for each machine, including @file{sunos.c} for sun3 and sun4, - @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a - demonstration of a 64 bit a.out format. - - The base file @file{aoutx.h} defines general mechanisms for - reading and writing records to and from disk and various - other methods which BFD requires. It is included by - @file{aout32.c} and @file{aout64.c} to form the names - <>, <>, etc. - - As an example, this is what goes on to make the back end for a - sun4, from @file{aout32.c}: - -| #define ARCH_SIZE 32 -| #include "aoutx.h" - - Which exports names: - -| ... -| aout_32_canonicalize_reloc -| aout_32_find_nearest_line -| aout_32_get_lineno -| aout_32_get_reloc_upper_bound -| ... - - from @file{sunos.c}: - -| #define TARGET_NAME "a.out-sunos-big" -| #define VECNAME sunos_big_vec -| #include "aoutf1.h" - - requires all the names from @file{aout32.c}, and produces the jump vector - -| sunos_big_vec - - The file @file{host-aout.c} is a special case. It is for a large set - of hosts that use ``more or less standard'' a.out files, and - for which cross-debugging is not interesting. It uses the - standard 32-bit a.out support routines, but determines the - file offsets and addresses of the text, data, and BSS - sections, the machine architecture and machine type, and the - entry point address, in a host-dependent manner. Once these - values have been determined, generic code is used to handle - the object file. - - When porting it to run on a new system, you must supply: - -| HOST_PAGE_SIZE -| HOST_SEGMENT_SIZE -| HOST_MACHINE_ARCH (optional) -| HOST_MACHINE_MACHINE (optional) -| HOST_TEXT_START_ADDR -| HOST_STACK_END_ADDR - - in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These - values, plus the structures and macros defined in @file{a.out.h} on - your host system, will produce a BFD target that will access - ordinary a.out files on your host. To configure a new machine - to use @file{host-aout.c}, specify: - -| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec -| TDEPFILES= host-aout.o trad-core.o - - in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in} - to use the - @file{@var{XXX}.mt} file (by setting "<>") when your - configuration is selected. - -*/ - -/* Some assumptions: - * Any BFD with D_PAGED set is ZMAGIC, and vice versa. - Doesn't matter what the setting of WP_TEXT is on output, but it'll - get set on input. - * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC. - * Any BFD with both flags clear is OMAGIC. - (Just want to make these explicit, so the conditions tested in this - file make sense if you're more familiar with a.out than with BFD.) */ - -#define KEEPIT udata.i - -#include /* For strchr and friends */ -#include -#include "bfd.h" -#include -#include "bfdlink.h" - -#include "libaout.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" - -static boolean aout_get_external_symbols PARAMS ((bfd *)); -static boolean translate_from_native_sym_flags - PARAMS ((bfd *, aout_symbol_type *)); -static boolean translate_to_native_sym_flags - PARAMS ((bfd *, asymbol *, struct external_nlist *)); - -/* -SUBSECTION - Relocations - -DESCRIPTION - The file @file{aoutx.h} provides for both the @emph{standard} - and @emph{extended} forms of a.out relocation records. - - The standard records contain only an - address, a symbol index, and a type field. The extended records - (used on 29ks and sparcs) also have a full integer for an - addend. - -*/ -#ifndef CTOR_TABLE_RELOC_HOWTO -#define CTOR_TABLE_RELOC_IDX 2 -#define CTOR_TABLE_RELOC_HOWTO(BFD) ((obj_reloc_entry_size(BFD) == RELOC_EXT_SIZE \ - ? howto_table_ext : howto_table_std) \ - + CTOR_TABLE_RELOC_IDX) -#endif - -#ifndef MY_swap_std_reloc_in -#define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in) -#endif - -#ifndef MY_swap_std_reloc_out -#define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out) -#endif - -#ifndef MY_final_link_relocate -#define MY_final_link_relocate _bfd_final_link_relocate -#endif - -#ifndef MY_relocate_contents -#define MY_relocate_contents _bfd_relocate_contents -#endif - -#define howto_table_ext NAME(aout,ext_howto_table) -#define howto_table_std NAME(aout,std_howto_table) - -reloc_howto_type howto_table_ext[] = -{ - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ - HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false), - HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false), - HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false), - HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false), - HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false), - HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false), - HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false), - HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false), - HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false), - HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false), - HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false), - HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false), - HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false), - HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false), - HOWTO(RELOC_BASE10, 0, 2, 10, false, 0, complain_overflow_dont,0,"BASE10", false, 0,0x000003ff, false), - HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"BASE13", false, 0,0x00001fff, false), - HOWTO(RELOC_BASE22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x003fffff, false), - HOWTO(RELOC_PC10, 0, 2, 10, true, 0, complain_overflow_dont,0,"PC10", false, 0,0x000003ff, true), - HOWTO(RELOC_PC22, 10, 2, 22, true, 0, complain_overflow_signed,0,"PC22", false, 0,0x003fffff, true), - HOWTO(RELOC_JMP_TBL,2, 2, 30, true, 0, complain_overflow_signed,0,"JMP_TBL", false, 0,0x3fffffff, false), - HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false), - HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false), - HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false), - HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false), -}; - -/* Convert standard reloc records to "arelent" format (incl byte swap). */ - -reloc_howto_type howto_table_std[] = { - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ -HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false), -HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false), -HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false), -HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false), -HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false), -HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false), -HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false), -HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false), -HOWTO( 8, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false), -HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false), -HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false), -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, - HOWTO(16, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false), -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, - HOWTO(32, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false), -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, - HOWTO(40, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false), -}; - -#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0])) - -reloc_howto_type * -NAME(aout,reloc_type_lookup) (abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ -#define EXT(i,j) case i: return &howto_table_ext[j] -#define STD(i,j) case i: return &howto_table_std[j] - int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE; - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - case 64: - code = BFD_RELOC_64; - break; - } - if (ext) - switch (code) - { - EXT (BFD_RELOC_32, 2); - EXT (BFD_RELOC_HI22, 8); - EXT (BFD_RELOC_LO10, 11); - EXT (BFD_RELOC_32_PCREL_S2, 6); - EXT (BFD_RELOC_SPARC_WDISP22, 7); - EXT (BFD_RELOC_SPARC13, 10); - EXT (BFD_RELOC_SPARC_GOT10, 14); - EXT (BFD_RELOC_SPARC_BASE13, 15); - EXT (BFD_RELOC_SPARC_GOT13, 15); - EXT (BFD_RELOC_SPARC_GOT22, 16); - EXT (BFD_RELOC_SPARC_PC10, 17); - EXT (BFD_RELOC_SPARC_PC22, 18); - EXT (BFD_RELOC_SPARC_WPLT30, 19); - default: return (reloc_howto_type *) NULL; - } - else - /* std relocs */ - switch (code) - { - STD (BFD_RELOC_16, 1); - STD (BFD_RELOC_32, 2); - STD (BFD_RELOC_8_PCREL, 4); - STD (BFD_RELOC_16_PCREL, 5); - STD (BFD_RELOC_32_PCREL, 6); - STD (BFD_RELOC_16_BASEREL, 9); - STD (BFD_RELOC_32_BASEREL, 10); - default: return (reloc_howto_type *) NULL; - } -} - -/* -SUBSECTION - Internal entry points - -DESCRIPTION - @file{aoutx.h} exports several routines for accessing the - contents of an a.out file, which are gathered and exported in - turn by various format specific files (eg sunos.c). - -*/ - -/* -FUNCTION - aout_@var{size}_swap_exec_header_in - -SYNOPSIS - void aout_@var{size}_swap_exec_header_in, - (bfd *abfd, - struct external_exec *raw_bytes, - struct internal_exec *execp); - -DESCRIPTION - Swap the information in an executable header @var{raw_bytes} taken - from a raw byte stream memory image into the internal exec header - structure @var{execp}. -*/ - -#ifndef NAME_swap_exec_header_in -void -NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* The internal_exec structure has some fields that are unused in this - configuration (IE for i960), so ensure that all such uninitialized - fields are zero'd out. There are places where two of these structs - are memcmp'd, and thus the contents do matter. */ - memset ((PTR) execp, 0, sizeof (struct internal_exec)); - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); -} -#define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in) -#endif - -/* -FUNCTION - aout_@var{size}_swap_exec_header_out - -SYNOPSIS - void aout_@var{size}_swap_exec_header_out - (bfd *abfd, - struct internal_exec *execp, - struct external_exec *raw_bytes); - -DESCRIPTION - Swap the information in an internal exec header structure - @var{execp} into the buffer @var{raw_bytes} ready for writing to disk. -*/ -void -NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - struct external_exec *raw_bytes; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info , bytes->e_info); - PUT_WORD (abfd, execp->a_text , bytes->e_text); - PUT_WORD (abfd, execp->a_data , bytes->e_data); - PUT_WORD (abfd, execp->a_bss , bytes->e_bss); - PUT_WORD (abfd, execp->a_syms , bytes->e_syms); - PUT_WORD (abfd, execp->a_entry , bytes->e_entry); - PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize); - PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize); -} - -/* Make all the section for an a.out file. */ - -boolean -NAME(aout,make_sections) (abfd) - bfd *abfd; -{ - if (obj_textsec (abfd) == (asection *) NULL - && bfd_make_section (abfd, ".text") == (asection *) NULL) - return false; - if (obj_datasec (abfd) == (asection *) NULL - && bfd_make_section (abfd, ".data") == (asection *) NULL) - return false; - if (obj_bsssec (abfd) == (asection *) NULL - && bfd_make_section (abfd, ".bss") == (asection *) NULL) - return false; - return true; -} - -/* -FUNCTION - aout_@var{size}_some_aout_object_p - -SYNOPSIS - const bfd_target *aout_@var{size}_some_aout_object_p - (bfd *abfd, - const bfd_target *(*callback_to_real_object_p)()); - -DESCRIPTION - Some a.out variant thinks that the file open in @var{abfd} - checking is an a.out file. Do some more checking, and set up - for access if it really is. Call back to the calling - environment's "finish up" function just before returning, to - handle any last-minute setup. -*/ - -const bfd_target * -NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p) - bfd *abfd; - struct internal_exec *execp; - const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)); -{ - struct aout_data_struct *rawptr, *oldrawptr; - const bfd_target *result; - - rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct )); - if (rawptr == NULL) - return 0; - - oldrawptr = abfd->tdata.aout_data; - abfd->tdata.aout_data = rawptr; - - /* Copy the contents of the old tdata struct. - In particular, we want the subformat, since for hpux it was set in - hp300hpux.c:swap_exec_header_in and will be used in - hp300hpux.c:callback. */ - if (oldrawptr != NULL) - *abfd->tdata.aout_data = *oldrawptr; - - abfd->tdata.aout_data->a.hdr = &rawptr->e; - *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct */ - execp = abfd->tdata.aout_data->a.hdr; - - /* Set the file flags */ - abfd->flags = NO_FLAGS; - if (execp->a_drsize || execp->a_trsize) - abfd->flags |= HAS_RELOC; - /* Setting of EXEC_P has been deferred to the bottom of this function */ - if (execp->a_syms) - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - if (N_DYNAMIC(*execp)) - abfd->flags |= DYNAMIC; - - if (N_MAGIC (*execp) == ZMAGIC) - { - abfd->flags |= D_PAGED | WP_TEXT; - adata (abfd).magic = z_magic; - } - else if (N_MAGIC (*execp) == QMAGIC) - { - abfd->flags |= D_PAGED | WP_TEXT; - adata (abfd).magic = z_magic; - adata (abfd).subformat = q_magic_format; - } - else if (N_MAGIC (*execp) == NMAGIC) - { - abfd->flags |= WP_TEXT; - adata (abfd).magic = n_magic; - } - else if (N_MAGIC (*execp) == OMAGIC - || N_MAGIC (*execp) == BMAGIC) - adata (abfd).magic = o_magic; - else - { - /* Should have been checked with N_BADMAG before this routine - was called. */ - abort (); - } - - bfd_get_start_address (abfd) = execp->a_entry; - - obj_aout_symbols (abfd) = (aout_symbol_type *)NULL; - bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist); - - /* The default relocation entry size is that of traditional V7 Unix. */ - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - /* The default symbol entry size is that of traditional Unix. */ - obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE; - -#ifdef USE_MMAP - bfd_init_window (&obj_aout_sym_window (abfd)); - bfd_init_window (&obj_aout_string_window (abfd)); -#endif - obj_aout_external_syms (abfd) = NULL; - obj_aout_external_strings (abfd) = NULL; - obj_aout_sym_hashes (abfd) = NULL; - - if (! NAME(aout,make_sections) (abfd)) - return NULL; - - obj_datasec (abfd)->_raw_size = execp->a_data; - obj_bsssec (abfd)->_raw_size = execp->a_bss; - - obj_textsec (abfd)->flags = - (execp->a_trsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)); - obj_datasec (abfd)->flags = - (execp->a_drsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)); - obj_bsssec (abfd)->flags = SEC_ALLOC; - -#ifdef THIS_IS_ONLY_DOCUMENTATION - /* The common code can't fill in these things because they depend - on either the start address of the text segment, the rounding - up of virtual addresses between segments, or the starting file - position of the text segment -- all of which varies among different - versions of a.out. */ - - /* Call back to the format-dependent code to fill in the rest of the - fields and do any further cleanup. Things that should be filled - in by the callback: */ - - struct exec *execp = exec_hdr (abfd); - - obj_textsec (abfd)->size = N_TXTSIZE(*execp); - obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp); - /* data and bss are already filled in since they're so standard */ - - /* The virtual memory addresses of the sections */ - obj_textsec (abfd)->vma = N_TXTADDR(*execp); - obj_datasec (abfd)->vma = N_DATADDR(*execp); - obj_bsssec (abfd)->vma = N_BSSADDR(*execp); - - /* The file offsets of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF(*execp); - obj_datasec (abfd)->filepos = N_DATOFF(*execp); - - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); - - /* The file offsets of the string table and symbol table. */ - obj_str_filepos (abfd) = N_STROFF (*execp); - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - - /* Determine the architecture and machine type of the object file. */ - switch (N_MACHTYPE (*exec_hdr (abfd))) { - default: - abfd->obj_arch = bfd_arch_obscure; - break; - } - - adata(abfd)->page_size = TARGET_PAGE_SIZE; - adata(abfd)->segment_size = SEGMENT_SIZE; - adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE; - - return abfd->xvec; - - /* The architecture is encoded in various ways in various a.out variants, - or is not encoded at all in some of them. The relocation size depends - on the architecture and the a.out variant. Finally, the return value - is the bfd_target vector in use. If an error occurs, return zero and - set bfd_error to the appropriate error code. - - Formats such as b.out, which have additional fields in the a.out - header, should cope with them in this callback as well. */ -#endif /* DOCUMENTATION */ - - result = (*callback_to_real_object_p)(abfd); - - /* Now that the segment addresses have been worked out, take a better - guess at whether the file is executable. If the entry point - is within the text segment, assume it is. (This makes files - executable even if their entry point address is 0, as long as - their text starts at zero.). */ - if ((execp->a_entry >= obj_textsec(abfd)->vma) && - (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size)) - abfd->flags |= EXEC_P; -#ifdef STAT_FOR_EXEC - else - { - struct stat stat_buf; - - /* The original heuristic doesn't work in some important cases. - The a.out file has no information about the text start - address. For files (like kernels) linked to non-standard - addresses (ld -Ttext nnn) the entry point may not be between - the default text start (obj_textsec(abfd)->vma) and - (obj_textsec(abfd)->vma) + text size. This is not just a mach - issue. Many kernels are loaded at non standard addresses. */ - if (abfd->iostream != NULL - && (abfd->flags & BFD_IN_MEMORY) == 0 - && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0) - && ((stat_buf.st_mode & 0111) != 0)) - abfd->flags |= EXEC_P; - } -#endif /* STAT_FOR_EXEC */ - - if (result) - { -#if 0 /* These should be set correctly anyways. */ - abfd->sections = obj_textsec (abfd); - obj_textsec (abfd)->next = obj_datasec (abfd); - obj_datasec (abfd)->next = obj_bsssec (abfd); -#endif - } - else - { - free (rawptr); - abfd->tdata.aout_data = oldrawptr; - } - return result; -} - -/* -FUNCTION - aout_@var{size}_mkobject - -SYNOPSIS - boolean aout_@var{size}_mkobject, (bfd *abfd); - -DESCRIPTION - Initialize BFD @var{abfd} for use with a.out files. -*/ - -boolean -NAME(aout,mkobject) (abfd) - bfd *abfd; -{ - struct aout_data_struct *rawptr; - - bfd_set_error (bfd_error_system_call); - - /* Use an intermediate variable for clarity */ - rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct )); - - if (rawptr == NULL) - return false; - - abfd->tdata.aout_data = rawptr; - exec_hdr (abfd) = &(rawptr->e); - - obj_textsec (abfd) = (asection *)NULL; - obj_datasec (abfd) = (asection *)NULL; - obj_bsssec (abfd) = (asection *)NULL; - - return true; -} - - -/* -FUNCTION - aout_@var{size}_machine_type - -SYNOPSIS - enum machine_type aout_@var{size}_machine_type - (enum bfd_architecture arch, - unsigned long machine)); - -DESCRIPTION - Keep track of machine architecture and machine type for - a.out's. Return the <> for a particular - architecture and machine, or <> if that exact architecture - and machine can't be represented in a.out format. - - If the architecture is understood, machine type 0 (default) - is always understood. -*/ - -enum machine_type -NAME(aout,machine_type) (arch, machine, unknown) - enum bfd_architecture arch; - unsigned long machine; - boolean *unknown; -{ - enum machine_type arch_flags; - - arch_flags = M_UNKNOWN; - *unknown = true; - - switch (arch) { - case bfd_arch_sparc: - if (machine == 0 - || machine == bfd_mach_sparc - || machine == bfd_mach_sparc_v9) - arch_flags = M_SPARC; - break; - - case bfd_arch_m68k: - switch (machine) { - case 0: arch_flags = M_68010; break; - case 68000: arch_flags = M_UNKNOWN; *unknown = false; break; - case 68010: arch_flags = M_68010; break; - case 68020: arch_flags = M_68020; break; - default: arch_flags = M_UNKNOWN; break; - } - break; - - case bfd_arch_i386: - if (machine == 0) arch_flags = M_386; - break; - - case bfd_arch_a29k: - if (machine == 0) arch_flags = M_29K; - break; - - case bfd_arch_arm: - if (machine == 0) arch_flags = M_ARM; - break; - - case bfd_arch_mips: - switch (machine) { - case 0: - case 2000: - case 3000: arch_flags = M_MIPS1; break; - case 4000: /* mips3 */ - case 4400: - case 8000: /* mips4 */ - /* real mips2: */ - case 6000: arch_flags = M_MIPS2; break; - default: arch_flags = M_UNKNOWN; break; - } - break; - - case bfd_arch_ns32k: - switch (machine) { - case 0: arch_flags = M_NS32532; break; - case 32032: arch_flags = M_NS32032; break; - case 32532: arch_flags = M_NS32532; break; - default: arch_flags = M_UNKNOWN; break; - } - break; - - case bfd_arch_vax: - *unknown = false; - break; - - - default: - arch_flags = M_UNKNOWN; - } - - if (arch_flags != M_UNKNOWN) - *unknown = false; - - return arch_flags; -} - - -/* -FUNCTION - aout_@var{size}_set_arch_mach - -SYNOPSIS - boolean aout_@var{size}_set_arch_mach, - (bfd *, - enum bfd_architecture arch, - unsigned long machine)); - -DESCRIPTION - Set the architecture and the machine of the BFD @var{abfd} to the - values @var{arch} and @var{machine}. Verify that @var{abfd}'s format - can support the architecture required. -*/ - -boolean -NAME(aout,set_arch_mach) (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - if (! bfd_default_set_arch_mach (abfd, arch, machine)) - return false; - - if (arch != bfd_arch_unknown) - { - boolean unknown; - - NAME(aout,machine_type) (arch, machine, &unknown); - if (unknown) - return false; - } - - /* Determine the size of a relocation entry */ - switch (arch) { - case bfd_arch_sparc: - case bfd_arch_a29k: - case bfd_arch_mips: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } - - return (*aout_backend_info(abfd)->set_sizes) (abfd); -} - -static void -adjust_o_magic (abfd, execp) - bfd *abfd; - struct internal_exec *execp; -{ - file_ptr pos = adata (abfd).exec_bytes_size; - bfd_vma vma = 0; - int pad = 0; - - /* Text. */ - obj_textsec(abfd)->filepos = pos; - if (!obj_textsec(abfd)->user_set_vma) - obj_textsec(abfd)->vma = vma; - else - vma = obj_textsec(abfd)->vma; - - pos += obj_textsec(abfd)->_raw_size; - vma += obj_textsec(abfd)->_raw_size; - - /* Data. */ - if (!obj_datasec(abfd)->user_set_vma) - { -#if 0 /* ?? Does alignment in the file image really matter? */ - pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma; -#endif - obj_textsec(abfd)->_raw_size += pad; - pos += pad; - vma += pad; - obj_datasec(abfd)->vma = vma; - } - else - vma = obj_datasec(abfd)->vma; - obj_datasec(abfd)->filepos = pos; - pos += obj_datasec(abfd)->_raw_size; - vma += obj_datasec(abfd)->_raw_size; - - /* BSS. */ - if (!obj_bsssec(abfd)->user_set_vma) - { -#if 0 - pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma; -#endif - obj_datasec(abfd)->_raw_size += pad; - pos += pad; - vma += pad; - obj_bsssec(abfd)->vma = vma; - } - else - { - /* The VMA of the .bss section is set by the the VMA of the - .data section plus the size of the .data section. We may - need to add padding bytes to make this true. */ - pad = obj_bsssec (abfd)->vma - vma; - if (pad > 0) - { - obj_datasec (abfd)->_raw_size += pad; - pos += pad; - } - } - obj_bsssec(abfd)->filepos = pos; - - /* Fix up the exec header. */ - execp->a_text = obj_textsec(abfd)->_raw_size; - execp->a_data = obj_datasec(abfd)->_raw_size; - execp->a_bss = obj_bsssec(abfd)->_raw_size; - N_SET_MAGIC (*execp, OMAGIC); -} - -static void -adjust_z_magic (abfd, execp) - bfd *abfd; - struct internal_exec *execp; -{ - bfd_size_type data_pad, text_pad; - file_ptr text_end; - CONST struct aout_backend_data *abdp; - int ztih; /* Nonzero if text includes exec header. */ - - abdp = aout_backend_info (abfd); - - /* Text. */ - ztih = (abdp != NULL - && (abdp->text_includes_header - || obj_aout_subformat (abfd) == q_magic_format)); - obj_textsec(abfd)->filepos = (ztih - ? adata(abfd).exec_bytes_size - : adata(abfd).zmagic_disk_block_size); - if (! obj_textsec(abfd)->user_set_vma) - { - /* ?? Do we really need to check for relocs here? */ - obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC) - ? 0 - : (ztih - ? (abdp->default_text_vma - + adata(abfd).exec_bytes_size) - : abdp->default_text_vma)); - text_pad = 0; - } - else - { - /* The .text section is being loaded at an unusual address. We - may need to pad it such that the .data section starts at a page - boundary. */ - if (ztih) - text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma) - & (adata (abfd).page_size - 1)); - else - text_pad = ((- obj_textsec (abfd)->vma) - & (adata (abfd).page_size - 1)); - } - - /* Find start of data. */ - if (ztih) - { - text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->_raw_size; - text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end; - } - else - { - /* Note that if page_size == zmagic_disk_block_size, then - filepos == page_size, and this case is the same as the ztih - case. */ - text_end = obj_textsec (abfd)->_raw_size; - text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end; - text_end += obj_textsec (abfd)->filepos; - } - obj_textsec(abfd)->_raw_size += text_pad; - text_end += text_pad; - - /* Data. */ - if (!obj_datasec(abfd)->user_set_vma) - { - bfd_vma vma; - vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size; - obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size); - } - if (abdp && abdp->zmagic_mapped_contiguous) - { - text_pad = (obj_datasec(abfd)->vma - - obj_textsec(abfd)->vma - - obj_textsec(abfd)->_raw_size); - obj_textsec(abfd)->_raw_size += text_pad; - } - obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos - + obj_textsec(abfd)->_raw_size); - - /* Fix up exec header while we're at it. */ - execp->a_text = obj_textsec(abfd)->_raw_size; - if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted))) - execp->a_text += adata(abfd).exec_bytes_size; - if (obj_aout_subformat (abfd) == q_magic_format) - N_SET_MAGIC (*execp, QMAGIC); - else - N_SET_MAGIC (*execp, ZMAGIC); - - /* Spec says data section should be rounded up to page boundary. */ - obj_datasec(abfd)->_raw_size - = align_power (obj_datasec(abfd)->_raw_size, - obj_bsssec(abfd)->alignment_power); - execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size, - adata(abfd).page_size); - data_pad = execp->a_data - obj_datasec(abfd)->_raw_size; - - /* BSS. */ - if (!obj_bsssec(abfd)->user_set_vma) - obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma - + obj_datasec(abfd)->_raw_size); - /* If the BSS immediately follows the data section and extra space - in the page is left after the data section, fudge data - in the header so that the bss section looks smaller by that - amount. We'll start the bss section there, and lie to the OS. - (Note that a linker script, as well as the above assignment, - could have explicitly set the BSS vma to immediately follow - the data section.) */ - if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power) - == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size) - execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 : - obj_bsssec(abfd)->_raw_size - data_pad; - else - execp->a_bss = obj_bsssec(abfd)->_raw_size; -} - -static void -adjust_n_magic (abfd, execp) - bfd *abfd; - struct internal_exec *execp; -{ - file_ptr pos = adata(abfd).exec_bytes_size; - bfd_vma vma = 0; - int pad; - - /* Text. */ - obj_textsec(abfd)->filepos = pos; - if (!obj_textsec(abfd)->user_set_vma) - obj_textsec(abfd)->vma = vma; - else - vma = obj_textsec(abfd)->vma; - pos += obj_textsec(abfd)->_raw_size; - vma += obj_textsec(abfd)->_raw_size; - - /* Data. */ - obj_datasec(abfd)->filepos = pos; - if (!obj_datasec(abfd)->user_set_vma) - obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size); - vma = obj_datasec(abfd)->vma; - - /* Since BSS follows data immediately, see if it needs alignment. */ - vma += obj_datasec(abfd)->_raw_size; - pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma; - obj_datasec(abfd)->_raw_size += pad; - pos += obj_datasec(abfd)->_raw_size; - - /* BSS. */ - if (!obj_bsssec(abfd)->user_set_vma) - obj_bsssec(abfd)->vma = vma; - else - vma = obj_bsssec(abfd)->vma; - - /* Fix up exec header. */ - execp->a_text = obj_textsec(abfd)->_raw_size; - execp->a_data = obj_datasec(abfd)->_raw_size; - execp->a_bss = obj_bsssec(abfd)->_raw_size; - N_SET_MAGIC (*execp, NMAGIC); -} - -boolean -NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end) - bfd *abfd; - bfd_size_type *text_size; - file_ptr *text_end; -{ - struct internal_exec *execp = exec_hdr (abfd); - - if (! NAME(aout,make_sections) (abfd)) - return false; - - if (adata(abfd).magic != undecided_magic) - return true; - - obj_textsec(abfd)->_raw_size = - align_power(obj_textsec(abfd)->_raw_size, - obj_textsec(abfd)->alignment_power); - - *text_size = obj_textsec (abfd)->_raw_size; - /* Rule (heuristic) for when to pad to a new page. Note that there - are (at least) two ways demand-paged (ZMAGIC) files have been - handled. Most Berkeley-based systems start the text segment at - (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text - segment right after the exec header; the latter is counted in the - text segment size, and is paged in by the kernel with the rest of - the text. */ - - /* This perhaps isn't the right way to do this, but made it simpler for me - to understand enough to implement it. Better would probably be to go - right from BFD flags to alignment/positioning characteristics. But the - old code was sloppy enough about handling the flags, and had enough - other magic, that it was a little hard for me to understand. I think - I understand it better now, but I haven't time to do the cleanup this - minute. */ - - if (abfd->flags & D_PAGED) - /* Whether or not WP_TEXT is set -- let D_PAGED override. */ - adata(abfd).magic = z_magic; - else if (abfd->flags & WP_TEXT) - adata(abfd).magic = n_magic; - else - adata(abfd).magic = o_magic; - -#ifdef BFD_AOUT_DEBUG /* requires gcc2 */ -#if __GNUC__ >= 2 - fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n", - ({ char *str; - switch (adata(abfd).magic) { - case n_magic: str = "NMAGIC"; break; - case o_magic: str = "OMAGIC"; break; - case z_magic: str = "ZMAGIC"; break; - default: abort (); - } - str; - }), - obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, - obj_textsec(abfd)->alignment_power, - obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, - obj_datasec(abfd)->alignment_power, - obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size, - obj_bsssec(abfd)->alignment_power); -#endif -#endif - - switch (adata(abfd).magic) - { - case o_magic: - adjust_o_magic (abfd, execp); - break; - case z_magic: - adjust_z_magic (abfd, execp); - break; - case n_magic: - adjust_n_magic (abfd, execp); - break; - default: - abort (); - } - -#ifdef BFD_AOUT_DEBUG - fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n", - obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, - obj_textsec(abfd)->filepos, - obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, - obj_datasec(abfd)->filepos, - obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size); -#endif - - return true; -} - -/* -FUNCTION - aout_@var{size}_new_section_hook - -SYNOPSIS - boolean aout_@var{size}_new_section_hook, - (bfd *abfd, - asection *newsect)); - -DESCRIPTION - Called by the BFD in response to a @code{bfd_make_section} - request. -*/ -boolean -NAME(aout,new_section_hook) (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - /* align to double at least */ - newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power; - - - if (bfd_get_format (abfd) == bfd_object) - { - if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) { - obj_textsec(abfd)= newsect; - newsect->target_index = N_TEXT; - return true; - } - - if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) { - obj_datasec(abfd) = newsect; - newsect->target_index = N_DATA; - return true; - } - - if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) { - obj_bsssec(abfd) = newsect; - newsect->target_index = N_BSS; - return true; - } - - } - - /* We allow more than three sections internally */ - return true; -} - -boolean -NAME(aout,set_section_contents) (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - file_ptr text_end; - bfd_size_type text_size; - - if (! abfd->output_has_begun) - { - if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end)) - return false; - } - - if (section == obj_bsssec (abfd)) - { - bfd_set_error (bfd_error_no_contents); - return false; - } - - if (section != obj_textsec (abfd) - && section != obj_datasec (abfd)) - { - (*_bfd_error_handler) - ("%s: can not represent section `%s' in a.out object file format", - bfd_get_filename (abfd), bfd_get_section_name (abfd, section)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - - if (count != 0) - { - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 - || bfd_write (location, 1, count, abfd) != count) - return false; - } - - return true; -} - -/* Read the external symbols from an a.out file. */ - -static boolean -aout_get_external_symbols (abfd) - bfd *abfd; -{ - if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL) - { - bfd_size_type count; - struct external_nlist *syms; - - count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE; - -#ifdef USE_MMAP - if (bfd_get_file_window (abfd, - obj_sym_filepos (abfd), exec_hdr (abfd)->a_syms, - &obj_aout_sym_window (abfd), true) == false) - return false; - syms = (struct external_nlist *) obj_aout_sym_window (abfd).data; -#else - /* We allocate using malloc to make the values easy to free - later on. If we put them on the obstack it might not be - possible to free them. */ - syms = ((struct external_nlist *) - bfd_malloc ((size_t) count * EXTERNAL_NLIST_SIZE)); - if (syms == (struct external_nlist *) NULL && count != 0) - return false; - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd) - != exec_hdr (abfd)->a_syms)) - { - free (syms); - return false; - } -#endif - - obj_aout_external_syms (abfd) = syms; - obj_aout_external_sym_count (abfd) = count; - } - - if (obj_aout_external_strings (abfd) == NULL - && exec_hdr (abfd)->a_syms != 0) - { - unsigned char string_chars[BYTES_IN_WORD]; - bfd_size_type stringsize; - char *strings; - - /* Get the size of the strings. */ - if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0 - || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd) - != BYTES_IN_WORD)) - return false; - stringsize = GET_WORD (abfd, string_chars); - -#ifdef USE_MMAP - if (bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize, - &obj_aout_string_window (abfd), true) == false) - return false; - strings = (char *) obj_aout_string_window (abfd).data; -#else - strings = (char *) bfd_malloc ((size_t) stringsize + 1); - if (strings == NULL) - return false; - - /* Skip space for the string count in the buffer for convenience - when using indexes. */ - if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD, - abfd) - != stringsize - BYTES_IN_WORD) - { - free (strings); - return false; - } -#endif - - /* Ensure that a zero index yields an empty string. */ - strings[0] = '\0'; - - strings[stringsize - 1] = 0; - - obj_aout_external_strings (abfd) = strings; - obj_aout_external_string_size (abfd) = stringsize; - } - - return true; -} - -/* Translate an a.out symbol into a BFD symbol. The desc, other, type - and symbol->value fields of CACHE_PTR will be set from the a.out - nlist structure. This function is responsible for setting - symbol->flags and symbol->section, and adjusting symbol->value. */ - -static boolean -translate_from_native_sym_flags (abfd, cache_ptr) - bfd *abfd; - aout_symbol_type *cache_ptr; -{ - flagword visible; - - if ((cache_ptr->type & N_STAB) != 0 - || cache_ptr->type == N_FN) - { - asection *sec; - - /* This is a debugging symbol. */ - - cache_ptr->symbol.flags = BSF_DEBUGGING; - - /* Work out the symbol section. */ - switch (cache_ptr->type & N_TYPE) - { - case N_TEXT: - case N_FN: - sec = obj_textsec (abfd); - break; - case N_DATA: - sec = obj_datasec (abfd); - break; - case N_BSS: - sec = obj_bsssec (abfd); - break; - default: - case N_ABS: - sec = bfd_abs_section_ptr; - break; - } - - cache_ptr->symbol.section = sec; - cache_ptr->symbol.value -= sec->vma; - - return true; - } - - /* Get the default visibility. This does not apply to all types, so - we just hold it in a local variable to use if wanted. */ - if ((cache_ptr->type & N_EXT) == 0) - visible = BSF_LOCAL; - else - visible = BSF_GLOBAL; - - switch (cache_ptr->type) - { - default: - case N_ABS: case N_ABS | N_EXT: - cache_ptr->symbol.section = bfd_abs_section_ptr; - cache_ptr->symbol.flags = visible; - break; - - case N_UNDF | N_EXT: - if (cache_ptr->symbol.value != 0) - { - /* This is a common symbol. */ - cache_ptr->symbol.flags = BSF_GLOBAL; - cache_ptr->symbol.section = bfd_com_section_ptr; - } - else - { - cache_ptr->symbol.flags = 0; - cache_ptr->symbol.section = bfd_und_section_ptr; - } - break; - - case N_TEXT: case N_TEXT | N_EXT: - cache_ptr->symbol.section = obj_textsec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = visible; - break; - - /* N_SETV symbols used to represent set vectors placed in the - data section. They are no longer generated. Theoretically, - it was possible to extract the entries and combine them with - new ones, although I don't know if that was ever actually - done. Unless that feature is restored, treat them as data - symbols. */ - case N_SETV: case N_SETV | N_EXT: - case N_DATA: case N_DATA | N_EXT: - cache_ptr->symbol.section = obj_datasec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = visible; - break; - - case N_BSS: case N_BSS | N_EXT: - cache_ptr->symbol.section = obj_bsssec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = visible; - break; - - case N_SETA: case N_SETA | N_EXT: - case N_SETT: case N_SETT | N_EXT: - case N_SETD: case N_SETD | N_EXT: - case N_SETB: case N_SETB | N_EXT: - { - asection *section; - arelent_chain *reloc; - asection *into_section; - - /* This is a set symbol. The name of the symbol is the name - of the set (e.g., __CTOR_LIST__). The value of the symbol - is the value to add to the set. We create a section with - the same name as the symbol, and add a reloc to insert the - appropriate value into the section. - - This action is actually obsolete; it used to make the - linker do the right thing, but the linker no longer uses - this function. */ - - section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name); - if (section == NULL) - { - char *copy; - - copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1); - if (copy == NULL) - return false; - - strcpy (copy, cache_ptr->symbol.name); - section = bfd_make_section (abfd, copy); - if (section == NULL) - return false; - } - - reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain)); - if (reloc == NULL) - return false; - - /* Build a relocation entry for the constructor. */ - switch (cache_ptr->type & N_TYPE) - { - case N_SETA: - into_section = bfd_abs_section_ptr; - cache_ptr->type = N_ABS; - break; - case N_SETT: - into_section = obj_textsec (abfd); - cache_ptr->type = N_TEXT; - break; - case N_SETD: - into_section = obj_datasec (abfd); - cache_ptr->type = N_DATA; - break; - case N_SETB: - into_section = obj_bsssec (abfd); - cache_ptr->type = N_BSS; - break; - } - - /* Build a relocation pointing into the constructor section - pointing at the symbol in the set vector specified. */ - reloc->relent.addend = cache_ptr->symbol.value; - cache_ptr->symbol.section = into_section; - reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr; - - /* We modify the symbol to belong to a section depending upon - the name of the symbol, and add to the size of the section - to contain a pointer to the symbol. Build a reloc entry to - relocate to this symbol attached to this section. */ - section->flags = SEC_CONSTRUCTOR | SEC_RELOC; - - section->reloc_count++; - section->alignment_power = 2; - - reloc->next = section->constructor_chain; - section->constructor_chain = reloc; - reloc->relent.address = section->_raw_size; - section->_raw_size += BYTES_IN_WORD; - - reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO(abfd); - - cache_ptr->symbol.flags |= BSF_CONSTRUCTOR; - } - break; - - case N_WARNING: - /* This symbol is the text of a warning message. The next - symbol is the symbol to associate the warning with. If a - reference is made to that symbol, a warning is issued. */ - cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING; - cache_ptr->symbol.section = bfd_abs_section_ptr; - break; - - case N_INDR: case N_INDR | N_EXT: - /* An indirect symbol. This consists of two symbols in a row. - The first symbol is the name of the indirection. The second - symbol is the name of the target. A reference to the first - symbol becomes a reference to the second. */ - cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible; - cache_ptr->symbol.section = bfd_ind_section_ptr; - break; - - case N_WEAKU: - cache_ptr->symbol.section = bfd_und_section_ptr; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKA: - cache_ptr->symbol.section = bfd_abs_section_ptr; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKT: - cache_ptr->symbol.section = obj_textsec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKD: - cache_ptr->symbol.section = obj_datasec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKB: - cache_ptr->symbol.section = obj_bsssec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = BSF_WEAK; - break; - } - - return true; -} - -/* Set the fields of SYM_POINTER according to CACHE_PTR. */ - -static boolean -translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer) - bfd *abfd; - asymbol *cache_ptr; - struct external_nlist *sym_pointer; -{ - bfd_vma value = cache_ptr->value; - asection *sec; - bfd_vma off; - - /* Mask out any existing type bits in case copying from one section - to another. */ - sym_pointer->e_type[0] &= ~N_TYPE; - - sec = bfd_get_section (cache_ptr); - off = 0; - - if (sec == NULL) - { - /* This case occurs, e.g., for the *DEBUG* section of a COFF - file. */ - (*_bfd_error_handler) - ("%s: can not represent section `%s' in a.out object file format", - bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - - if (sec->output_section != NULL) - { - off = sec->output_offset; - sec = sec->output_section; - } - - if (bfd_is_abs_section (sec)) - sym_pointer->e_type[0] |= N_ABS; - else if (sec == obj_textsec (abfd)) - sym_pointer->e_type[0] |= N_TEXT; - else if (sec == obj_datasec (abfd)) - sym_pointer->e_type[0] |= N_DATA; - else if (sec == obj_bsssec (abfd)) - sym_pointer->e_type[0] |= N_BSS; - else if (bfd_is_und_section (sec)) - sym_pointer->e_type[0] = N_UNDF | N_EXT; - else if (bfd_is_ind_section (sec)) - sym_pointer->e_type[0] = N_INDR; - else if (bfd_is_com_section (sec)) - sym_pointer->e_type[0] = N_UNDF | N_EXT; - else - { - (*_bfd_error_handler) - ("%s: can not represent section `%s' in a.out object file format", - bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - - /* Turn the symbol from section relative to absolute again */ - value += sec->vma + off; - - if ((cache_ptr->flags & BSF_WARNING) != 0) - sym_pointer->e_type[0] = N_WARNING; - - if ((cache_ptr->flags & BSF_DEBUGGING) != 0) - sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type; - else if ((cache_ptr->flags & BSF_GLOBAL) != 0) - sym_pointer->e_type[0] |= N_EXT; - - if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0) - { - int type = ((aout_symbol_type *) cache_ptr)->type; - switch (type) - { - case N_ABS: type = N_SETA; break; - case N_TEXT: type = N_SETT; break; - case N_DATA: type = N_SETD; break; - case N_BSS: type = N_SETB; break; - } - sym_pointer->e_type[0] = type; - } - - if ((cache_ptr->flags & BSF_WEAK) != 0) - { - int type; - - switch (sym_pointer->e_type[0] & N_TYPE) - { - default: - case N_ABS: type = N_WEAKA; break; - case N_TEXT: type = N_WEAKT; break; - case N_DATA: type = N_WEAKD; break; - case N_BSS: type = N_WEAKB; break; - case N_UNDF: type = N_WEAKU; break; - } - sym_pointer->e_type[0] = type; - } - - PUT_WORD(abfd, value, sym_pointer->e_value); - - return true; -} - -/* Native-level interface to symbols. */ - -asymbol * -NAME(aout,make_empty_symbol) (abfd) - bfd *abfd; -{ - aout_symbol_type *new = - (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type)); - if (!new) - return NULL; - new->symbol.the_bfd = abfd; - - return &new->symbol; -} - -/* Translate a set of internal symbols into external symbols. */ - -boolean -NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic) - bfd *abfd; - aout_symbol_type *in; - struct external_nlist *ext; - bfd_size_type count; - char *str; - bfd_size_type strsize; - boolean dynamic; -{ - struct external_nlist *ext_end; - - ext_end = ext + count; - for (; ext < ext_end; ext++, in++) - { - bfd_vma x; - - x = GET_WORD (abfd, ext->e_strx); - in->symbol.the_bfd = abfd; - - /* For the normal symbols, the zero index points at the number - of bytes in the string table but is to be interpreted as the - null string. For the dynamic symbols, the number of bytes in - the string table is stored in the __DYNAMIC structure and the - zero index points at an actual string. */ - if (x == 0 && ! dynamic) - in->symbol.name = ""; - else if (x < strsize) - in->symbol.name = str + x; - else - return false; - - in->symbol.value = GET_SWORD (abfd, ext->e_value); - in->desc = bfd_h_get_16 (abfd, ext->e_desc); - in->other = bfd_h_get_8 (abfd, ext->e_other); - in->type = bfd_h_get_8 (abfd, ext->e_type); - in->symbol.udata.p = NULL; - - if (! translate_from_native_sym_flags (abfd, in)) - return false; - - if (dynamic) - in->symbol.flags |= BSF_DYNAMIC; - } - - return true; -} - -/* We read the symbols into a buffer, which is discarded when this - function exits. We read the strings into a buffer large enough to - hold them all plus all the cached symbol entries. */ - -boolean -NAME(aout,slurp_symbol_table) (abfd) - bfd *abfd; -{ - struct external_nlist *old_external_syms; - aout_symbol_type *cached; - size_t cached_size; - - /* If there's no work to be done, don't do any */ - if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL) - return true; - - old_external_syms = obj_aout_external_syms (abfd); - - if (! aout_get_external_symbols (abfd)) - return false; - - cached_size = (obj_aout_external_sym_count (abfd) - * sizeof (aout_symbol_type)); - cached = (aout_symbol_type *) bfd_malloc (cached_size); - if (cached == NULL && cached_size != 0) - return false; - if (cached_size != 0) - memset (cached, 0, cached_size); - - /* Convert from external symbol information to internal. */ - if (! (NAME(aout,translate_symbol_table) - (abfd, cached, - obj_aout_external_syms (abfd), - obj_aout_external_sym_count (abfd), - obj_aout_external_strings (abfd), - obj_aout_external_string_size (abfd), - false))) - { - free (cached); - return false; - } - - bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd); - - obj_aout_symbols (abfd) = cached; - - /* It is very likely that anybody who calls this function will not - want the external symbol information, so if it was allocated - because of our call to aout_get_external_symbols, we free it up - right away to save space. */ - if (old_external_syms == (struct external_nlist *) NULL - && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL) - { -#ifdef USE_MMAP - bfd_free_window (&obj_aout_sym_window (abfd)); -#else - free (obj_aout_external_syms (abfd)); -#endif - obj_aout_external_syms (abfd) = NULL; - } - - return true; -} - -/* We use a hash table when writing out symbols so that we only write - out a particular string once. This helps particularly when the - linker writes out stabs debugging entries, because each different - contributing object file tends to have many duplicate stabs - strings. - - This hash table code breaks dbx on SunOS 4.1.3, so we don't do it - if BFD_TRADITIONAL_FORMAT is set. */ - -static bfd_size_type add_to_stringtab - PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean)); -static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *)); - -/* Get the index of a string in a strtab, adding it if it is not - already present. */ - -static INLINE bfd_size_type -add_to_stringtab (abfd, tab, str, copy) - bfd *abfd; - struct bfd_strtab_hash *tab; - const char *str; - boolean copy; -{ - boolean hash; - bfd_size_type index; - - /* An index of 0 always means the empty string. */ - if (str == 0 || *str == '\0') - return 0; - - /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx - doesn't understand a hashed string table. */ - hash = true; - if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - - index = _bfd_stringtab_add (tab, str, hash, copy); - - if (index != (bfd_size_type) -1) - { - /* Add BYTES_IN_WORD to the return value to account for the - space taken up by the string table size. */ - index += BYTES_IN_WORD; - } - - return index; -} - -/* Write out a strtab. ABFD is already at the right location in the - file. */ - -static boolean -emit_stringtab (abfd, tab) - register bfd *abfd; - struct bfd_strtab_hash *tab; -{ - bfd_byte buffer[BYTES_IN_WORD]; - - /* The string table starts with the size. */ - PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer); - if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD) - return false; - - return _bfd_stringtab_emit (abfd, tab); -} - -boolean -NAME(aout,write_syms) (abfd) - bfd *abfd; -{ - unsigned int count ; - asymbol **generic = bfd_get_outsymbols (abfd); - struct bfd_strtab_hash *strtab; - - strtab = _bfd_stringtab_init (); - if (strtab == NULL) - return false; - - for (count = 0; count < bfd_get_symcount (abfd); count++) - { - asymbol *g = generic[count]; - bfd_size_type indx; - struct external_nlist nsp; - - indx = add_to_stringtab (abfd, strtab, g->name, false); - if (indx == (bfd_size_type) -1) - goto error_return; - PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx); - - if (bfd_asymbol_flavour(g) == abfd->xvec->flavour) - { - bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc); - bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other); - bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type); - } - else - { - bfd_h_put_16(abfd,0, nsp.e_desc); - bfd_h_put_8(abfd, 0, nsp.e_other); - bfd_h_put_8(abfd, 0, nsp.e_type); - } - - if (! translate_to_native_sym_flags (abfd, g, &nsp)) - goto error_return; - - if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd) - != EXTERNAL_NLIST_SIZE) - goto error_return; - - /* NB: `KEEPIT' currently overlays `udata.p', so set this only - here, at the end. */ - g->KEEPIT = count; - } - - if (! emit_stringtab (abfd, strtab)) - goto error_return; - - _bfd_stringtab_free (strtab); - - return true; - -error_return: - _bfd_stringtab_free (strtab); - return false; -} - - -long -NAME(aout,get_symtab) (abfd, location) - bfd *abfd; - asymbol **location; -{ - unsigned int counter = 0; - aout_symbol_type *symbase; - - if (!NAME(aout,slurp_symbol_table)(abfd)) - return -1; - - for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);) - *(location++) = (asymbol *)( symbase++); - *location++ =0; - return bfd_get_symcount (abfd); -} - - -/* Standard reloc stuff */ -/* Output standard relocation information to a file in target byte order. */ - -void -NAME(aout,swap_std_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - asection *output_section = sym->section->output_section; - - PUT_WORD(abfd, g->address, natptr->r_address); - - r_length = g->howto->size ; /* Size as a power of two */ - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - /* XXX This relies on relocs coming from a.out files. */ - r_baserel = (g->howto->type & 8) != 0; - r_jmptable = (g->howto->type & 16) != 0; - r_relative = (g->howto->type & 32) != 0; - -#if 0 - /* For a standard reloc, the addend is in the object file. */ - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; -#endif - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - - if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = (*(g->sym_ptr_ptr))->KEEPIT; - - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0) - | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0) - | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0) - | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0) - | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG); - } else { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0) - | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0) - | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE); - } -} - - -/* Extended stuff */ -/* Output extended relocation information to a file in target byte order. */ - -void -NAME(aout,swap_ext_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - register struct reloc_ext_external *natptr; -{ - int r_index; - int r_extern; - unsigned int r_type; - unsigned int r_addend; - asymbol *sym = *(g->sym_ptr_ptr); - asection *output_section = sym->section->output_section; - - PUT_WORD (abfd, g->address, natptr->r_address); - - r_type = (unsigned int) g->howto->type; - - r_addend = g->addend; - if ((sym->flags & BSF_SECTION_SYM) != 0) - r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma; - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here. */ - - if (bfd_is_abs_section (bfd_get_section (sym))) - { - r_extern = 0; - r_index = 0; - } - else if ((sym->flags & BSF_SECTION_SYM) == 0) - { - if (bfd_is_und_section (bfd_get_section (sym)) - || (sym->flags & BSF_GLOBAL) != 0) - r_extern = 1; - else - r_extern = 0; - r_index = (*(g->sym_ptr_ptr))->KEEPIT; - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG)); - } else { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - PUT_WORD (abfd, r_addend, natptr->r_addend); -} - -/* BFD deals internally with all things based from the section they're - in. so, something in 10 bytes into a text section with a base of - 50 would have a symbol (.text+10) and know .text vma was 50. - - Aout keeps all it's symbols based from zero, so the symbol would - contain 60. This macro subs the base of each section from the value - to give the true offset from the section */ - - -#define MOVE_ADDRESS(ad) \ - if (r_extern) { \ - /* undefined symbol */ \ - cache_ptr->sym_ptr_ptr = symbols + r_index; \ - cache_ptr->addend = ad; \ - } else { \ - /* defined, section relative. replace symbol with pointer to \ - symbol which points to section */ \ - switch (r_index) { \ - case N_TEXT: \ - case N_TEXT | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->textsec->vma; \ - break; \ - case N_DATA: \ - case N_DATA | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->datasec->vma; \ - break; \ - case N_BSS: \ - case N_BSS | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->bsssec->vma; \ - break; \ - default: \ - case N_ABS: \ - case N_ABS | N_EXT: \ - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ - cache_ptr->addend = ad; \ - break; \ - } \ - } \ - -void -NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_ext_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - unsigned int r_index; - int r_extern; - unsigned int r_type; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) { - r_index = (bytes->r_index[0] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[2]; - r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG; - } else { - r_index = (bytes->r_index[2] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[0]; - r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); - r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE; - } - - cache_ptr->howto = howto_table_ext + r_type; - - /* Base relative relocs are always against the symbol table, - regardless of the setting of r_extern. r_extern just reflects - whether the symbol the reloc is against is local or global. */ - if (r_type == RELOC_BASE10 - || r_type == RELOC_BASE13 - || r_type == RELOC_BASE22) - r_extern = 1; - - if (r_extern && r_index > symcount) - { - /* We could arrange to return an error, but it might be useful - to see the file even if it is bad. */ - r_extern = 0; - r_index = N_ABS; - } - - MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend)); -} - -void -NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - unsigned int r_index; - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - unsigned int howto_idx; - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) { - r_index = (bytes->r_index[0] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[2]; - r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); - r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); - r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG)); - r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG; - } else { - r_index = (bytes->r_index[2] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[0]; - r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE)); - r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE)); - r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE)); - r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE; - } - - howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel - + 16 * r_jmptable + 32 * r_relative; - BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std)); - cache_ptr->howto = howto_table_std + howto_idx; - BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1); - - /* Base relative relocs are always against the symbol table, - regardless of the setting of r_extern. r_extern just reflects - whether the symbol the reloc is against is local or global. */ - if (r_baserel) - r_extern = 1; - - if (r_extern && r_index > symcount) - { - /* We could arrange to return an error, but it might be useful - to see the file even if it is bad. */ - r_extern = 0; - r_index = N_ABS; - } - - MOVE_ADDRESS(0); -} - -/* Read and swap the relocs for a section. */ - -boolean -NAME(aout,slurp_reloc_table) (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - unsigned int count; - bfd_size_type reloc_size; - PTR relocs; - arelent *reloc_cache; - size_t each_size; - unsigned int counter = 0; - arelent *cache_ptr; - - if (asect->relocation) - return true; - - if (asect->flags & SEC_CONSTRUCTOR) - return true; - - if (asect == obj_datasec (abfd)) - reloc_size = exec_hdr(abfd)->a_drsize; - else if (asect == obj_textsec (abfd)) - reloc_size = exec_hdr(abfd)->a_trsize; - else if (asect == obj_bsssec (abfd)) - reloc_size = 0; - else - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) - return false; - - each_size = obj_reloc_entry_size (abfd); - - count = reloc_size / each_size; - - reloc_cache = (arelent *) bfd_malloc ((size_t) (count * sizeof (arelent))); - if (reloc_cache == NULL && count != 0) - return false; - memset (reloc_cache, 0, count * sizeof (arelent)); - - relocs = bfd_malloc ((size_t) reloc_size); - if (relocs == NULL && reloc_size != 0) - { - free (reloc_cache); - return false; - } - - if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) - { - free (relocs); - free (reloc_cache); - return false; - } - - cache_ptr = reloc_cache; - if (each_size == RELOC_EXT_SIZE) - { - register struct reloc_ext_external *rptr = - (struct reloc_ext_external *) relocs; - - for (; counter < count; counter++, rptr++, cache_ptr++) - NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - else - { - register struct reloc_std_external *rptr = - (struct reloc_std_external *) relocs; - - for (; counter < count; counter++, rptr++, cache_ptr++) - MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - - free (relocs); - - asect->relocation = reloc_cache; - asect->reloc_count = cache_ptr - reloc_cache; - - return true; -} - -/* Write out a relocation section into an object file. */ - -boolean -NAME(aout,squirt_out_relocs) (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - unsigned char *native, *natptr; - size_t each_size; - - unsigned int count = section->reloc_count; - size_t natsize; - - if (count == 0) return true; - - each_size = obj_reloc_entry_size (abfd); - natsize = each_size * count; - native = (unsigned char *) bfd_zalloc (abfd, natsize); - if (!native) - return false; - - generic = section->orelocation; - - if (each_size == RELOC_EXT_SIZE) - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr); - } - else - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - MY_swap_std_reloc_out(abfd, *generic, (struct reloc_std_external *)natptr); - } - - if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { - bfd_release(abfd, native); - return false; - } - bfd_release (abfd, native); - - return true; -} - -/* This is stupid. This function should be a boolean predicate */ -long -NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count; - - if (section == obj_bsssec (abfd)) - { - *relptr = NULL; - return 0; - } - - if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols))) - return -1; - - if (section->flags & SEC_CONSTRUCTOR) { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count ++) { - *relptr ++ = &chain->relent; - chain = chain->next; - } - } - else { - tblptr = section->relocation; - - for (count = 0; count++ < section->reloc_count;) - { - *relptr++ = tblptr++; - } - } - *relptr = 0; - - return section->reloc_count; -} - -long -NAME(aout,get_reloc_upper_bound) (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (bfd_get_format (abfd) != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - if (asect->flags & SEC_CONSTRUCTOR) { - return (sizeof (arelent *) * (asect->reloc_count+1)); - } - - if (asect == obj_datasec (abfd)) - return (sizeof (arelent *) - * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd)) - + 1)); - - if (asect == obj_textsec (abfd)) - return (sizeof (arelent *) - * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd)) - + 1)); - - if (asect == obj_bsssec (abfd)) - return sizeof (arelent *); - - if (asect == obj_bsssec (abfd)) - return 0; - - bfd_set_error (bfd_error_invalid_operation); - return -1; -} - - -long -NAME(aout,get_symtab_upper_bound) (abfd) - bfd *abfd; -{ - if (!NAME(aout,slurp_symbol_table)(abfd)) - return -1; - - return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *)); -} - -/*ARGSUSED*/ - alent * -NAME(aout,get_lineno) (ignore_abfd, ignore_symbol) - bfd *ignore_abfd; - asymbol *ignore_symbol; -{ -return (alent *)NULL; -} - -/*ARGSUSED*/ -void -NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); - - if (ret->type == '?') - { - int type_code = aout_symbol(symbol)->type & 0xff; - const char *stab_name = bfd_get_stab_name (type_code); - static char buf[10]; - - if (stab_name == NULL) - { - sprintf(buf, "(%d)", type_code); - stab_name = buf; - } - ret->type = '-'; - ret->stab_type = type_code; - ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff); - ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff); - ret->stab_name = stab_name; - } -} - -/*ARGSUSED*/ -void -NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *)afile; - - switch (how) { - case bfd_print_symbol_name: - if (symbol->name) - fprintf(file,"%s", symbol->name); - break; - case bfd_print_symbol_more: - fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff), - (unsigned)(aout_symbol(symbol)->other & 0xff), - (unsigned)(aout_symbol(symbol)->type)); - break; - case bfd_print_symbol_all: - { - CONST char *section_name = symbol->section->name; - - - bfd_print_symbol_vandf((PTR)file,symbol); - - fprintf(file," %-5s %04x %02x %02x", - section_name, - (unsigned)(aout_symbol(symbol)->desc & 0xffff), - (unsigned)(aout_symbol(symbol)->other & 0xff), - (unsigned)(aout_symbol(symbol)->type & 0xff)); - if (symbol->name) - fprintf(file," %s", symbol->name); - } - break; - } -} - -/* If we don't have to allocate more than 1MB to hold the generic - symbols, we use the generic minisymbol methord: it's faster, since - it only translates the symbols once, not multiple times. */ -#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol)) - -/* Read minisymbols. For minisymbols, we use the unmodified a.out - symbols. The minisymbol_to_symbol function translates these into - BFD asymbol structures. */ - -long -NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep) - bfd *abfd; - boolean dynamic; - PTR *minisymsp; - unsigned int *sizep; -{ - if (dynamic) - { - /* We could handle the dynamic symbols here as well, but it's - easier to hand them off. */ - return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep); - } - - if (! aout_get_external_symbols (abfd)) - return -1; - - if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD) - return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep); - - *minisymsp = (PTR) obj_aout_external_syms (abfd); - - /* By passing the external symbols back from this routine, we are - giving up control over the memory block. Clear - obj_aout_external_syms, so that we do not try to free it - ourselves. */ - obj_aout_external_syms (abfd) = NULL; - - *sizep = EXTERNAL_NLIST_SIZE; - return obj_aout_external_sym_count (abfd); -} - -/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an - unmodified a.out symbol. The SYM argument is a structure returned - by bfd_make_empty_symbol, which we fill in here. */ - -asymbol * -NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym) - bfd *abfd; - boolean dynamic; - const PTR minisym; - asymbol *sym; -{ - if (dynamic - || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD) - return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym); - - memset (sym, 0, sizeof (aout_symbol_type)); - - /* We call translate_symbol_table to translate a single symbol. */ - if (! (NAME(aout,translate_symbol_table) - (abfd, - (aout_symbol_type *) sym, - (struct external_nlist *) minisym, - (bfd_size_type) 1, - obj_aout_external_strings (abfd), - obj_aout_external_string_size (abfd), - false))) - return NULL; - - return sym; -} - -/* - provided a BFD, a section and an offset into the section, calculate - and return the name of the source file and the line nearest to the - wanted location. -*/ - -boolean -NAME(aout,find_nearest_line) - (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - /* Run down the file looking for the filename, function and linenumber */ - asymbol **p; - CONST char *directory_name = NULL; - CONST char *main_file_name = NULL; - CONST char *current_file_name = NULL; - CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */ - bfd_vma low_line_vma = 0; - bfd_vma low_func_vma = 0; - asymbol *func = 0; - size_t filelen, funclen; - char *buf; - - *filename_ptr = abfd->filename; - *functionname_ptr = 0; - *line_ptr = 0; - if (symbols != (asymbol **)NULL) { - for (p = symbols; *p; p++) { - aout_symbol_type *q = (aout_symbol_type *)(*p); - next: - switch (q->type){ - case N_SO: - main_file_name = current_file_name = q->symbol.name; - /* Look ahead to next symbol to check if that too is an N_SO. */ - p++; - if (*p == NULL) - break; - q = (aout_symbol_type *)(*p); - if (q->type != (int)N_SO) - goto next; - - /* Found a second N_SO First is directory; second is filename. */ - directory_name = current_file_name; - main_file_name = current_file_name = q->symbol.name; - if (obj_textsec(abfd) != section) - goto done; - break; - case N_SOL: - current_file_name = q->symbol.name; - break; - - case N_SLINE: - - case N_DSLINE: - case N_BSLINE: - /* We'll keep this if it resolves nearer than the one we have - already. */ - if (q->symbol.value >= low_line_vma - && q->symbol.value <= offset) - { - *line_ptr = q->desc; - low_line_vma = q->symbol.value; - line_file_name = current_file_name; - } - break; - case N_FUN: - { - /* We'll keep this if it is nearer than the one we have already */ - if (q->symbol.value >= low_func_vma && - q->symbol.value <= offset) { - low_func_vma = q->symbol.value; - func = (asymbol *)q; - } - else if (q->symbol.value > offset) - goto done; - } - break; - } - } - } - - done: - if (*line_ptr != 0) - main_file_name = line_file_name; - - if (main_file_name == NULL - || main_file_name[0] == '/' - || directory_name == NULL) - filelen = 0; - else - filelen = strlen (directory_name) + strlen (main_file_name); - if (func == NULL) - funclen = 0; - else - funclen = strlen (bfd_asymbol_name (func)); - - if (adata (abfd).line_buf != NULL) - free (adata (abfd).line_buf); - if (filelen + funclen == 0) - adata (abfd).line_buf = buf = NULL; - else - { - buf = (char *) bfd_malloc (filelen + funclen + 2); - adata (abfd).line_buf = buf; - if (buf == NULL) - return false; - } - - if (main_file_name != NULL) - { - if (main_file_name[0] == '/' || directory_name == NULL) - *filename_ptr = main_file_name; - else - { - sprintf (buf, "%s%s", directory_name, main_file_name); - *filename_ptr = buf; - buf += filelen + 1; - } - } - - if (func) - { - const char *function = func->name; - char *p; - - /* The caller expects a symbol name. We actually have a - function name, without the leading underscore. Put the - underscore back in, so that the caller gets a symbol name. */ - if (bfd_get_symbol_leading_char (abfd) == '\0') - strcpy (buf, function); - else - { - buf[0] = bfd_get_symbol_leading_char (abfd); - strcpy (buf + 1, function); - } - /* Have to remove : stuff */ - p = strchr (buf, ':'); - if (p != NULL) - *p = '\0'; - *functionname_ptr = buf; - } - - return true; -} - -/*ARGSUSED*/ -int -NAME(aout,sizeof_headers) (abfd, execable) - bfd *abfd; - boolean execable; -{ - return adata(abfd).exec_bytes_size; -} - -/* Free all information we have cached for this BFD. We can always - read it again later if we need it. */ - -boolean -NAME(aout,bfd_free_cached_info) (abfd) - bfd *abfd; -{ - asection *o; - - if (bfd_get_format (abfd) != bfd_object) - return true; - -#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; } - BFCI_FREE (obj_aout_symbols (abfd)); -#ifdef USE_MMAP - obj_aout_external_syms (abfd) = 0; - bfd_free_window (&obj_aout_sym_window (abfd)); - bfd_free_window (&obj_aout_string_window (abfd)); - obj_aout_external_strings (abfd) = 0; -#else - BFCI_FREE (obj_aout_external_syms (abfd)); - BFCI_FREE (obj_aout_external_strings (abfd)); -#endif - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - BFCI_FREE (o->relocation); -#undef BFCI_FREE - - return true; -} - -/* a.out link code. */ - -static boolean aout_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean aout_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean aout_link_free_symbols PARAMS ((bfd *)); -static boolean aout_link_check_ar_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean aout_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Routine to create an entry in an a.out link hash table. */ - -struct bfd_hash_entry * -NAME(aout,link_hash_newfunc) (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct aout_link_hash_entry *) NULL) - ret = ((struct aout_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry))); - if (ret == (struct aout_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct aout_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret) - { - /* Set local fields. */ - ret->written = false; - ret->indx = -1; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize an a.out link hash table. */ - -boolean -NAME(aout,link_hash_table_init) (table, abfd, newfunc) - struct aout_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return _bfd_link_hash_table_init (&table->root, abfd, newfunc); -} - -/* Create an a.out link hash table. */ - -struct bfd_link_hash_table * -NAME(aout,link_hash_table_create) (abfd) - bfd *abfd; -{ - struct aout_link_hash_table *ret; - - ret = ((struct aout_link_hash_table *) - bfd_alloc (abfd, sizeof (struct aout_link_hash_table))); - if (ret == NULL) - return (struct bfd_link_hash_table *) NULL; - if (! NAME(aout,link_hash_table_init) (ret, abfd, - NAME(aout,link_hash_newfunc))) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Given an a.out BFD, add symbols to the global hash table as - appropriate. */ - -boolean -NAME(aout,link_add_symbols) (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return aout_link_add_object_symbols (abfd, info); - case bfd_archive: - return _bfd_generic_link_add_archive_symbols - (abfd, info, aout_link_check_archive_element); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add symbols from an a.out object file. */ - -static boolean -aout_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (! aout_get_external_symbols (abfd)) - return false; - if (! aout_link_add_symbols (abfd, info)) - return false; - if (! info->keep_memory) - { - if (! aout_link_free_symbols (abfd)) - return false; - } - return true; -} - -/* Check a single archive element to see if we need to include it in - the link. *PNEEDED is set according to whether this element is - needed in the link or not. This is called from - _bfd_generic_link_add_archive_symbols. */ - -static boolean -aout_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - if (! aout_get_external_symbols (abfd)) - return false; - - if (! aout_link_check_ar_symbols (abfd, info, pneeded)) - return false; - - if (*pneeded) - { - if (! aout_link_add_symbols (abfd, info)) - return false; - } - - if (! info->keep_memory || ! *pneeded) - { - if (! aout_link_free_symbols (abfd)) - return false; - } - - return true; -} - -/* Free up the internal symbols read from an a.out file. */ - -static boolean -aout_link_free_symbols (abfd) - bfd *abfd; -{ - if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL) - { -#ifdef USE_MMAP - bfd_free_window (&obj_aout_sym_window (abfd)); -#else - free ((PTR) obj_aout_external_syms (abfd)); -#endif - obj_aout_external_syms (abfd) = (struct external_nlist *) NULL; - } - if (obj_aout_external_strings (abfd) != (char *) NULL) - { -#ifdef USE_MMAP - bfd_free_window (&obj_aout_string_window (abfd)); -#else - free ((PTR) obj_aout_external_strings (abfd)); -#endif - obj_aout_external_strings (abfd) = (char *) NULL; - } - return true; -} - -/* Look through the internal symbols to see if this object file should - be included in the link. We should include this object file if it - defines any symbols which are currently undefined. If this object - file defines a common symbol, then we may adjust the size of the - known symbol but we do not include the object file in the link - (unless there is some other reason to include it). */ - -static boolean -aout_link_check_ar_symbols (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - register struct external_nlist *p; - struct external_nlist *pend; - char *strings; - - *pneeded = false; - - /* Look through all the symbols. */ - p = obj_aout_external_syms (abfd); - pend = p + obj_aout_external_sym_count (abfd); - strings = obj_aout_external_strings (abfd); - for (; p < pend; p++) - { - int type = bfd_h_get_8 (abfd, p->e_type); - const char *name; - struct bfd_link_hash_entry *h; - - /* Ignore symbols that are not externally visible. This is an - optimization only, as we check the type more thoroughly - below. */ - if (((type & N_EXT) == 0 - || (type & N_STAB) != 0 - || type == N_FN) - && type != N_WEAKA - && type != N_WEAKT - && type != N_WEAKD - && type != N_WEAKB) - { - if (type == N_WARNING - || type == N_INDR) - ++p; - continue; - } - - name = strings + GET_WORD (abfd, p->e_strx); - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* We are only interested in symbols that are currently - undefined or common. */ - if (h == (struct bfd_link_hash_entry *) NULL - || (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common)) - { - if (type == (N_INDR | N_EXT)) - ++p; - continue; - } - - if (type == (N_TEXT | N_EXT) - || type == (N_DATA | N_EXT) - || type == (N_BSS | N_EXT) - || type == (N_ABS | N_EXT) - || type == (N_INDR | N_EXT)) - { - /* This object file defines this symbol. We must link it - in. This is true regardless of whether the current - definition of the symbol is undefined or common. If the - current definition is common, we have a case in which we - have already seen an object file including - int a; - and this object file from the archive includes - int a = 5; - In such a case we must include this object file. - - FIXME: The SunOS 4.1.3 linker will pull in the archive - element if the symbol is defined in the .data section, - but not if it is defined in the .text section. That - seems a bit crazy to me, and I haven't implemented it. - However, it might be correct. */ - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - - if (type == (N_UNDF | N_EXT)) - { - bfd_vma value; - - value = GET_WORD (abfd, p->e_value); - if (value != 0) - { - /* This symbol is common in the object from the archive - file. */ - if (h->type == bfd_link_hash_undefined) - { - bfd *symbfd; - unsigned int power; - - symbfd = h->u.undef.abfd; - if (symbfd == (bfd *) NULL) - { - /* This symbol was created as undefined from - outside BFD. We assume that we should link - in the object file. This is done for the -u - option in the linker. */ - if (! (*info->callbacks->add_archive_element) (info, - abfd, - name)) - return false; - *pneeded = true; - return true; - } - /* Turn the current link symbol into a common - symbol. It is already on the undefs list. */ - h->type = bfd_link_hash_common; - h->u.c.p = ((struct bfd_link_hash_common_entry *) - bfd_hash_allocate (&info->hash->table, - sizeof (struct bfd_link_hash_common_entry))); - if (h->u.c.p == NULL) - return false; - - h->u.c.size = value; - - /* FIXME: This isn't quite right. The maximum - alignment of a common symbol should be set by the - architecture of the output file, not of the input - file. */ - power = bfd_log2 (value); - if (power > bfd_get_arch_info (abfd)->section_align_power) - power = bfd_get_arch_info (abfd)->section_align_power; - h->u.c.p->alignment_power = power; - - h->u.c.p->section = bfd_make_section_old_way (symbfd, - "COMMON"); - } - else - { - /* Adjust the size of the common symbol if - necessary. */ - if (value > h->u.c.size) - h->u.c.size = value; - } - } - } - - if (type == N_WEAKA - || type == N_WEAKT - || type == N_WEAKD - || type == N_WEAKB) - { - /* This symbol is weak but defined. We must pull it in if - the current link symbol is undefined, but we don't want - it if the current link symbol is common. */ - if (h->type == bfd_link_hash_undefined) - { - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - } - } - - /* We do not need this object file. */ - return true; -} - -/* Add all symbols from an object file to the hash table. */ - -static boolean -aout_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - 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 **)); - struct external_nlist *syms; - bfd_size_type sym_count; - char *strings; - boolean copy; - struct aout_link_hash_entry **sym_hash; - register struct external_nlist *p; - struct external_nlist *pend; - - syms = obj_aout_external_syms (abfd); - sym_count = obj_aout_external_sym_count (abfd); - strings = obj_aout_external_strings (abfd); - if (info->keep_memory) - copy = false; - else - copy = true; - - if ((abfd->flags & DYNAMIC) != 0 - && aout_backend_info (abfd)->add_dynamic_symbols != NULL) - { - if (! ((*aout_backend_info (abfd)->add_dynamic_symbols) - (abfd, info, &syms, &sym_count, &strings))) - return false; - } - - /* We keep a list of the linker hash table entries that correspond - to particular symbols. We could just look them up in the hash - table, but keeping the list is more efficient. Perhaps this - should be conditional on info->keep_memory. */ - sym_hash = ((struct aout_link_hash_entry **) - bfd_alloc (abfd, - ((size_t) sym_count - * sizeof (struct aout_link_hash_entry *)))); - if (sym_hash == NULL && sym_count != 0) - return false; - obj_aout_sym_hashes (abfd) = sym_hash; - - add_one_symbol = aout_backend_info (abfd)->add_one_symbol; - if (add_one_symbol == NULL) - add_one_symbol = _bfd_generic_link_add_one_symbol; - - p = syms; - pend = p + sym_count; - for (; p < pend; p++, sym_hash++) - { - int type; - const char *name; - bfd_vma value; - asection *section; - flagword flags; - const char *string; - - *sym_hash = NULL; - - type = bfd_h_get_8 (abfd, p->e_type); - - /* Ignore debugging symbols. */ - if ((type & N_STAB) != 0) - continue; - - name = strings + GET_WORD (abfd, p->e_strx); - value = GET_WORD (abfd, p->e_value); - flags = BSF_GLOBAL; - string = NULL; - switch (type) - { - default: - abort (); - - case N_UNDF: - case N_ABS: - case N_TEXT: - case N_DATA: - case N_BSS: - case N_FN_SEQ: - case N_COMM: - case N_SETV: - case N_FN: - /* Ignore symbols that are not externally visible. */ - continue; - case N_INDR: - /* Ignore local indirect symbol. */ - ++p; - ++sym_hash; - continue; - - case N_UNDF | N_EXT: - if (value == 0) - { - section = bfd_und_section_ptr; - flags = 0; - } - else - section = bfd_com_section_ptr; - break; - case N_ABS | N_EXT: - section = bfd_abs_section_ptr; - break; - case N_TEXT | N_EXT: - section = obj_textsec (abfd); - value -= bfd_get_section_vma (abfd, section); - break; - case N_DATA | N_EXT: - case N_SETV | N_EXT: - /* Treat N_SETV symbols as N_DATA symbol; see comment in - translate_from_native_sym_flags. */ - section = obj_datasec (abfd); - value -= bfd_get_section_vma (abfd, section); - break; - case N_BSS | N_EXT: - section = obj_bsssec (abfd); - value -= bfd_get_section_vma (abfd, section); - break; - case N_INDR | N_EXT: - /* An indirect symbol. The next symbol is the symbol - which this one really is. */ - BFD_ASSERT (p + 1 < pend); - ++p; - string = strings + GET_WORD (abfd, p->e_strx); - section = bfd_ind_section_ptr; - flags |= BSF_INDIRECT; - break; - case N_COMM | N_EXT: - section = bfd_com_section_ptr; - break; - case N_SETA: case N_SETA | N_EXT: - section = bfd_abs_section_ptr; - flags |= BSF_CONSTRUCTOR; - break; - case N_SETT: case N_SETT | N_EXT: - section = obj_textsec (abfd); - flags |= BSF_CONSTRUCTOR; - value -= bfd_get_section_vma (abfd, section); - break; - case N_SETD: case N_SETD | N_EXT: - section = obj_datasec (abfd); - flags |= BSF_CONSTRUCTOR; - value -= bfd_get_section_vma (abfd, section); - break; - case N_SETB: case N_SETB | N_EXT: - section = obj_bsssec (abfd); - flags |= BSF_CONSTRUCTOR; - value -= bfd_get_section_vma (abfd, section); - break; - case N_WARNING: - /* A warning symbol. The next symbol is the one to warn - about. */ - BFD_ASSERT (p + 1 < pend); - ++p; - string = name; - name = strings + GET_WORD (abfd, p->e_strx); - section = bfd_und_section_ptr; - flags |= BSF_WARNING; - break; - case N_WEAKU: - section = bfd_und_section_ptr; - flags = BSF_WEAK; - break; - case N_WEAKA: - section = bfd_abs_section_ptr; - flags = BSF_WEAK; - break; - case N_WEAKT: - section = obj_textsec (abfd); - value -= bfd_get_section_vma (abfd, section); - flags = BSF_WEAK; - break; - case N_WEAKD: - section = obj_datasec (abfd); - value -= bfd_get_section_vma (abfd, section); - flags = BSF_WEAK; - break; - case N_WEAKB: - section = obj_bsssec (abfd); - value -= bfd_get_section_vma (abfd, section); - flags = BSF_WEAK; - break; - } - - if (! ((*add_one_symbol) - (info, abfd, name, flags, section, value, string, copy, false, - (struct bfd_link_hash_entry **) sym_hash))) - return false; - - /* Restrict the maximum alignment of a common symbol based on - the architecture, since a.out has no way to represent - alignment requirements of a section in a .o file. FIXME: - This isn't quite right: it should use the architecture of the - output file, not the input files. */ - if ((*sym_hash)->root.type == bfd_link_hash_common - && ((*sym_hash)->root.u.c.p->alignment_power > - bfd_get_arch_info (abfd)->section_align_power)) - (*sym_hash)->root.u.c.p->alignment_power = - bfd_get_arch_info (abfd)->section_align_power; - - /* If this is a set symbol, and we are not building sets, then - it is possible for the hash entry to not have been set. In - such a case, treat the symbol as not globally defined. */ - if ((*sym_hash)->root.type == bfd_link_hash_new) - { - BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0); - *sym_hash = NULL; - } - - if (type == (N_INDR | N_EXT) || type == N_WARNING) - ++sym_hash; - } - - return true; -} - -/* A hash table used for header files with N_BINCL entries. */ - -struct aout_link_includes_table -{ - struct bfd_hash_table root; -}; - -/* A linked list of totals that we have found for a particular header - file. */ - -struct aout_link_includes_totals -{ - struct aout_link_includes_totals *next; - bfd_vma total; -}; - -/* An entry in the header file hash table. */ - -struct aout_link_includes_entry -{ - struct bfd_hash_entry root; - /* List of totals we have found for this file. */ - struct aout_link_includes_totals *totals; -}; - -/* Look up an entry in an the header file hash table. */ - -#define aout_link_includes_lookup(table, string, create, copy) \ - ((struct aout_link_includes_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* During the final link step we need to pass around a bunch of - information, so we do it in an instance of this structure. */ - -struct aout_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output bfd. */ - bfd *output_bfd; - /* Reloc file positions. */ - file_ptr treloff, dreloff; - /* File position of symbols. */ - file_ptr symoff; - /* String table. */ - struct bfd_strtab_hash *strtab; - /* Header file hash table. */ - struct aout_link_includes_table includes; - /* A buffer large enough to hold the contents of any section. */ - bfd_byte *contents; - /* A buffer large enough to hold the relocs of any section. */ - PTR relocs; - /* A buffer large enough to hold the symbol map of any input BFD. */ - int *symbol_map; - /* A buffer large enough to hold output symbols of any input BFD. */ - struct external_nlist *output_syms; -}; - -static struct bfd_hash_entry *aout_link_includes_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static boolean aout_link_input_bfd - PARAMS ((struct aout_final_link_info *, bfd *input_bfd)); -static boolean aout_link_write_symbols - PARAMS ((struct aout_final_link_info *, bfd *input_bfd)); -static boolean aout_link_write_other_symbol - PARAMS ((struct aout_link_hash_entry *, PTR)); -static boolean aout_link_input_section - PARAMS ((struct aout_final_link_info *, bfd *input_bfd, - asection *input_section, file_ptr *reloff_ptr, - bfd_size_type rel_size)); -static boolean aout_link_input_section_std - PARAMS ((struct aout_final_link_info *, bfd *input_bfd, - asection *input_section, struct reloc_std_external *, - bfd_size_type rel_size, bfd_byte *contents)); -static boolean aout_link_input_section_ext - PARAMS ((struct aout_final_link_info *, bfd *input_bfd, - asection *input_section, struct reloc_ext_external *, - bfd_size_type rel_size, bfd_byte *contents)); -static INLINE asection *aout_reloc_index_to_section - PARAMS ((bfd *, int)); -static boolean aout_link_reloc_link_order - PARAMS ((struct aout_final_link_info *, asection *, - struct bfd_link_order *)); - -/* The function to create a new entry in the header file hash table. */ - -static struct bfd_hash_entry * -aout_link_includes_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct aout_link_includes_entry *ret = - (struct aout_link_includes_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct aout_link_includes_entry *) NULL) - ret = ((struct aout_link_includes_entry *) - bfd_hash_allocate (table, - sizeof (struct aout_link_includes_entry))); - if (ret == (struct aout_link_includes_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct aout_link_includes_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret) - { - /* Set local fields. */ - ret->totals = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Do the final link step. This is called on the output BFD. The - INFO structure should point to a list of BFDs linked through the - link_next field which can be used to find each BFD which takes part - in the output. Also, each section in ABFD should point to a list - of bfd_link_order structures which list all the input sections for - the output section. */ - -boolean -NAME(aout,final_link) (abfd, info, callback) - bfd *abfd; - struct bfd_link_info *info; - void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); -{ - struct aout_final_link_info aout_info; - boolean includes_hash_initialized = false; - register bfd *sub; - bfd_size_type trsize, drsize; - size_t max_contents_size; - size_t max_relocs_size; - size_t max_sym_count; - bfd_size_type text_size; - file_ptr text_end; - register struct bfd_link_order *p; - asection *o; - boolean have_link_order_relocs; - - if (info->shared) - abfd->flags |= DYNAMIC; - - aout_info.info = info; - aout_info.output_bfd = abfd; - aout_info.contents = NULL; - aout_info.relocs = NULL; - aout_info.symbol_map = NULL; - aout_info.output_syms = NULL; - - if (! bfd_hash_table_init_n (&aout_info.includes.root, - aout_link_includes_newfunc, - 251)) - goto error_return; - includes_hash_initialized = true; - - /* Figure out the largest section size. Also, if generating - relocateable output, count the relocs. */ - trsize = 0; - drsize = 0; - max_contents_size = 0; - max_relocs_size = 0; - max_sym_count = 0; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - size_t sz; - - if (info->relocateable) - { - if (bfd_get_flavour (sub) == bfd_target_aout_flavour) - { - trsize += exec_hdr (sub)->a_trsize; - drsize += exec_hdr (sub)->a_drsize; - } - else - { - /* FIXME: We need to identify the .text and .data sections - and call get_reloc_upper_bound and canonicalize_reloc to - work out the number of relocs needed, and then multiply - by the reloc size. */ - (*_bfd_error_handler) - ("%s: relocateable link from %s to %s not supported", - bfd_get_filename (abfd), - sub->xvec->name, abfd->xvec->name); - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - } - - if (bfd_get_flavour (sub) == bfd_target_aout_flavour) - { - sz = bfd_section_size (sub, obj_textsec (sub)); - if (sz > max_contents_size) - max_contents_size = sz; - sz = bfd_section_size (sub, obj_datasec (sub)); - if (sz > max_contents_size) - max_contents_size = sz; - - sz = exec_hdr (sub)->a_trsize; - if (sz > max_relocs_size) - max_relocs_size = sz; - sz = exec_hdr (sub)->a_drsize; - if (sz > max_relocs_size) - max_relocs_size = sz; - - sz = obj_aout_external_sym_count (sub); - if (sz > max_sym_count) - max_sym_count = sz; - } - } - - if (info->relocateable) - { - if (obj_textsec (abfd) != (asection *) NULL) - trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd) - ->link_order_head) - * obj_reloc_entry_size (abfd)); - if (obj_datasec (abfd) != (asection *) NULL) - drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd) - ->link_order_head) - * obj_reloc_entry_size (abfd)); - } - - exec_hdr (abfd)->a_trsize = trsize; - exec_hdr (abfd)->a_drsize = drsize; - - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - - /* Adjust the section sizes and vmas according to the magic number. - This sets a_text, a_data and a_bss in the exec_hdr and sets the - filepos for each section. */ - if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end)) - goto error_return; - - /* The relocation and symbol file positions differ among a.out - targets. We are passed a callback routine from the backend - specific code to handle this. - FIXME: At this point we do not know how much space the symbol - table will require. This will not work for any (nonstandard) - a.out target that needs to know the symbol table size before it - can compute the relocation file positions. This may or may not - be the case for the hp300hpux target, for example. */ - (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff, - &aout_info.symoff); - obj_textsec (abfd)->rel_filepos = aout_info.treloff; - obj_datasec (abfd)->rel_filepos = aout_info.dreloff; - obj_sym_filepos (abfd) = aout_info.symoff; - - /* We keep a count of the symbols as we output them. */ - obj_aout_external_sym_count (abfd) = 0; - - /* We accumulate the string table as we write out the symbols. */ - aout_info.strtab = _bfd_stringtab_init (); - if (aout_info.strtab == NULL) - goto error_return; - - /* Allocate buffers to hold section contents and relocs. */ - aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size); - aout_info.relocs = (PTR) bfd_malloc (max_relocs_size); - aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *)); - aout_info.output_syms = ((struct external_nlist *) - bfd_malloc ((max_sym_count + 1) - * sizeof (struct external_nlist))); - if ((aout_info.contents == NULL && max_contents_size != 0) - || (aout_info.relocs == NULL && max_relocs_size != 0) - || (aout_info.symbol_map == NULL && max_sym_count != 0) - || aout_info.output_syms == NULL) - goto error_return; - - /* If we have a symbol named __DYNAMIC, force it out now. This is - required by SunOS. Doing this here rather than in sunos.c is a - hack, but it's easier than exporting everything which would be - needed. */ - { - struct aout_link_hash_entry *h; - - h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC", - false, false, false); - if (h != NULL) - aout_link_write_other_symbol (h, &aout_info); - } - - /* The most time efficient way to do the link would be to read all - the input object files into memory and then sort out the - information into the output file. Unfortunately, that will - probably use too much memory. Another method would be to step - through everything that composes the text section and write it - out, and then everything that composes the data section and write - it out, and then write out the relocs, and then write out the - symbols. Unfortunately, that requires reading stuff from each - input file several times, and we will not be able to keep all the - input files open simultaneously, and reopening them will be slow. - - What we do is basically process one input file at a time. We do - everything we need to do with an input file once--copy over the - section contents, handle the relocation information, and write - out the symbols--and then we throw away the information we read - from it. This approach requires a lot of lseeks of the output - file, which is unfortunate but still faster than reopening a lot - of files. - - We use the output_has_begun field of the input BFDs to see - whether we have already handled it. */ - for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next) - sub->output_has_begun = false; - - have_link_order_relocs = false; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_aout_flavour)) - { - bfd *input_bfd; - - input_bfd = p->u.indirect.section->owner; - if (! input_bfd->output_has_begun) - { - if (! aout_link_input_bfd (&aout_info, input_bfd)) - goto error_return; - input_bfd->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - /* These are handled below. */ - have_link_order_relocs = true; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* Write out any symbols that we have not already written out. */ - aout_link_hash_traverse (aout_hash_table (info), - aout_link_write_other_symbol, - (PTR) &aout_info); - - /* Now handle any relocs we were asked to create by the linker. - These did not come from any input file. We must do these after - we have written out all the symbols, so that we know the symbol - indices to use. */ - if (have_link_order_relocs) - { - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! aout_link_reloc_link_order (&aout_info, o, p)) - goto error_return; - } - } - } - } - - if (aout_info.contents != NULL) - { - free (aout_info.contents); - aout_info.contents = NULL; - } - if (aout_info.relocs != NULL) - { - free (aout_info.relocs); - aout_info.relocs = NULL; - } - if (aout_info.symbol_map != NULL) - { - free (aout_info.symbol_map); - aout_info.symbol_map = NULL; - } - if (aout_info.output_syms != NULL) - { - free (aout_info.output_syms); - aout_info.output_syms = NULL; - } - if (includes_hash_initialized) - { - bfd_hash_table_free (&aout_info.includes.root); - includes_hash_initialized = false; - } - - /* Finish up any dynamic linking we may be doing. */ - if (aout_backend_info (abfd)->finish_dynamic_link != NULL) - { - if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info)) - goto error_return; - } - - /* Update the header information. */ - abfd->symcount = obj_aout_external_sym_count (abfd); - exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE; - obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms; - obj_textsec (abfd)->reloc_count = - exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd); - obj_datasec (abfd)->reloc_count = - exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd); - - /* Write out the string table. */ - if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0) - goto error_return; - return emit_stringtab (abfd, aout_info.strtab); - - error_return: - if (aout_info.contents != NULL) - free (aout_info.contents); - if (aout_info.relocs != NULL) - free (aout_info.relocs); - if (aout_info.symbol_map != NULL) - free (aout_info.symbol_map); - if (aout_info.output_syms != NULL) - free (aout_info.output_syms); - if (includes_hash_initialized) - bfd_hash_table_free (&aout_info.includes.root); - return false; -} - -/* Link an a.out input BFD into the output file. */ - -static boolean -aout_link_input_bfd (finfo, input_bfd) - struct aout_final_link_info *finfo; - bfd *input_bfd; -{ - bfd_size_type sym_count; - - BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object); - - /* If this is a dynamic object, it may need special handling. */ - if ((input_bfd->flags & DYNAMIC) != 0 - && aout_backend_info (input_bfd)->link_dynamic_object != NULL) - { - return ((*aout_backend_info (input_bfd)->link_dynamic_object) - (finfo->info, input_bfd)); - } - - /* Get the symbols. We probably have them already, unless - finfo->info->keep_memory is false. */ - if (! aout_get_external_symbols (input_bfd)) - return false; - - sym_count = obj_aout_external_sym_count (input_bfd); - - /* Write out the symbols and get a map of the new indices. The map - is placed into finfo->symbol_map. */ - if (! aout_link_write_symbols (finfo, input_bfd)) - return false; - - /* Relocate and write out the sections. These functions use the - symbol map created by aout_link_write_symbols. */ - if (! aout_link_input_section (finfo, input_bfd, - obj_textsec (input_bfd), - &finfo->treloff, - exec_hdr (input_bfd)->a_trsize) - || ! aout_link_input_section (finfo, input_bfd, - obj_datasec (input_bfd), - &finfo->dreloff, - exec_hdr (input_bfd)->a_drsize)) - return false; - - /* If we are not keeping memory, we don't need the symbols any - longer. We still need them if we are keeping memory, because the - strings in the hash table point into them. */ - if (! finfo->info->keep_memory) - { - if (! aout_link_free_symbols (input_bfd)) - return false; - } - - return true; -} - -/* Adjust and write out the symbols for an a.out file. Set the new - symbol indices into a symbol_map. */ - -static boolean -aout_link_write_symbols (finfo, input_bfd) - struct aout_final_link_info *finfo; - bfd *input_bfd; -{ - bfd *output_bfd; - bfd_size_type sym_count; - char *strings; - enum bfd_link_strip strip; - enum bfd_link_discard discard; - struct external_nlist *outsym; - bfd_size_type strtab_index; - register struct external_nlist *sym; - struct external_nlist *sym_end; - struct aout_link_hash_entry **sym_hash; - int *symbol_map; - boolean pass; - boolean skip_next; - - output_bfd = finfo->output_bfd; - sym_count = obj_aout_external_sym_count (input_bfd); - strings = obj_aout_external_strings (input_bfd); - strip = finfo->info->strip; - discard = finfo->info->discard; - outsym = finfo->output_syms; - - /* First write out a symbol for this object file, unless we are - discarding such symbols. */ - if (strip != strip_all - && (strip != strip_some - || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename, - false, false) != NULL) - && discard != discard_all) - { - bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type); - bfd_h_put_8 (output_bfd, 0, outsym->e_other); - bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc); - strtab_index = add_to_stringtab (output_bfd, finfo->strtab, - input_bfd->filename, false); - if (strtab_index == (bfd_size_type) -1) - return false; - PUT_WORD (output_bfd, strtab_index, outsym->e_strx); - PUT_WORD (output_bfd, - (bfd_get_section_vma (output_bfd, - obj_textsec (input_bfd)->output_section) - + obj_textsec (input_bfd)->output_offset), - outsym->e_value); - ++obj_aout_external_sym_count (output_bfd); - ++outsym; - } - - pass = false; - skip_next = false; - sym = obj_aout_external_syms (input_bfd); - sym_end = sym + sym_count; - sym_hash = obj_aout_sym_hashes (input_bfd); - symbol_map = finfo->symbol_map; - memset (symbol_map, 0, sym_count * sizeof *symbol_map); - for (; sym < sym_end; sym++, sym_hash++, symbol_map++) - { - const char *name; - int type; - struct aout_link_hash_entry *h; - boolean skip; - asection *symsec; - bfd_vma val = 0; - boolean copy; - - /* We set *symbol_map to 0 above for all symbols. If it has - already been set to -1 for this symbol, it means that we are - discarding it because it appears in a duplicate header file. - See the N_BINCL code below. */ - if (*symbol_map == -1) - continue; - - /* Initialize *symbol_map to -1, which means that the symbol was - not copied into the output file. We will change it later if - we do copy the symbol over. */ - *symbol_map = -1; - - type = bfd_h_get_8 (input_bfd, sym->e_type); - name = strings + GET_WORD (input_bfd, sym->e_strx); - - h = NULL; - - if (pass) - { - /* Pass this symbol through. It is the target of an - indirect or warning symbol. */ - val = GET_WORD (input_bfd, sym->e_value); - pass = false; - } - else if (skip_next) - { - /* Skip this symbol, which is the target of an indirect - symbol that we have changed to no longer be an indirect - symbol. */ - skip_next = false; - continue; - } - else - { - struct aout_link_hash_entry *hresolve; - - /* We have saved the hash table entry for this symbol, if - there is one. Note that we could just look it up again - in the hash table, provided we first check that it is an - external symbol. */ - h = *sym_hash; - - /* Use the name from the hash table, in case the symbol was - wrapped. */ - if (h != NULL) - name = h->root.root.string; - - /* If this is an indirect or warning symbol, then change - hresolve to the base symbol. We also change *sym_hash so - that the relocation routines relocate against the real - symbol. */ - hresolve = h; - if (h != (struct aout_link_hash_entry *) NULL - && (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning)) - { - hresolve = (struct aout_link_hash_entry *) h->root.u.i.link; - while (hresolve->root.type == bfd_link_hash_indirect - || hresolve->root.type == bfd_link_hash_warning) - hresolve = ((struct aout_link_hash_entry *) - hresolve->root.u.i.link); - *sym_hash = hresolve; - } - - /* If the symbol has already been written out, skip it. */ - if (h != (struct aout_link_hash_entry *) NULL - && h->root.type != bfd_link_hash_warning - && h->written) - { - if ((type & N_TYPE) == N_INDR - || type == N_WARNING) - skip_next = true; - *symbol_map = h->indx; - continue; - } - - /* See if we are stripping this symbol. */ - skip = false; - switch (strip) - { - case strip_none: - break; - case strip_debugger: - if ((type & N_STAB) != 0) - skip = true; - break; - case strip_some: - if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false) - == NULL) - skip = true; - break; - case strip_all: - skip = true; - break; - } - if (skip) - { - if (h != (struct aout_link_hash_entry *) NULL) - h->written = true; - continue; - } - - /* Get the value of the symbol. */ - if ((type & N_TYPE) == N_TEXT - || type == N_WEAKT) - symsec = obj_textsec (input_bfd); - else if ((type & N_TYPE) == N_DATA - || type == N_WEAKD) - symsec = obj_datasec (input_bfd); - else if ((type & N_TYPE) == N_BSS - || type == N_WEAKB) - symsec = obj_bsssec (input_bfd); - else if ((type & N_TYPE) == N_ABS - || type == N_WEAKA) - symsec = bfd_abs_section_ptr; - else if (((type & N_TYPE) == N_INDR - && (hresolve == (struct aout_link_hash_entry *) NULL - || (hresolve->root.type != bfd_link_hash_defined - && hresolve->root.type != bfd_link_hash_defweak - && hresolve->root.type != bfd_link_hash_common))) - || type == N_WARNING) - { - /* Pass the next symbol through unchanged. The - condition above for indirect symbols is so that if - the indirect symbol was defined, we output it with - the correct definition so the debugger will - understand it. */ - pass = true; - val = GET_WORD (input_bfd, sym->e_value); - symsec = NULL; - } - else if ((type & N_STAB) != 0) - { - val = GET_WORD (input_bfd, sym->e_value); - symsec = NULL; - } - else - { - /* If we get here with an indirect symbol, it means that - we are outputting it with a real definition. In such - a case we do not want to output the next symbol, - which is the target of the indirection. */ - if ((type & N_TYPE) == N_INDR) - skip_next = true; - - symsec = NULL; - - /* We need to get the value from the hash table. We use - hresolve so that if we have defined an indirect - symbol we output the final definition. */ - if (h == (struct aout_link_hash_entry *) NULL) - { - switch (type & N_TYPE) - { - case N_SETT: - symsec = obj_textsec (input_bfd); - break; - case N_SETD: - symsec = obj_datasec (input_bfd); - break; - case N_SETB: - symsec = obj_bsssec (input_bfd); - break; - case N_SETA: - symsec = bfd_abs_section_ptr; - break; - default: - val = 0; - break; - } - } - else if (hresolve->root.type == bfd_link_hash_defined - || hresolve->root.type == bfd_link_hash_defweak) - { - asection *input_section; - asection *output_section; - - /* This case usually means a common symbol which was - turned into a defined symbol. */ - input_section = hresolve->root.u.def.section; - output_section = input_section->output_section; - BFD_ASSERT (bfd_is_abs_section (output_section) - || output_section->owner == output_bfd); - val = (hresolve->root.u.def.value - + bfd_get_section_vma (output_bfd, output_section) - + input_section->output_offset); - - /* Get the correct type based on the section. If - this is a constructed set, force it to be - globally visible. */ - if (type == N_SETT - || type == N_SETD - || type == N_SETB - || type == N_SETA) - type |= N_EXT; - - type &=~ N_TYPE; - - if (output_section == obj_textsec (output_bfd)) - type |= (hresolve->root.type == bfd_link_hash_defined - ? N_TEXT - : N_WEAKT); - else if (output_section == obj_datasec (output_bfd)) - type |= (hresolve->root.type == bfd_link_hash_defined - ? N_DATA - : N_WEAKD); - else if (output_section == obj_bsssec (output_bfd)) - type |= (hresolve->root.type == bfd_link_hash_defined - ? N_BSS - : N_WEAKB); - else - type |= (hresolve->root.type == bfd_link_hash_defined - ? N_ABS - : N_WEAKA); - } - else if (hresolve->root.type == bfd_link_hash_common) - val = hresolve->root.u.c.size; - else if (hresolve->root.type == bfd_link_hash_undefweak) - { - val = 0; - type = N_WEAKU; - } - else - val = 0; - } - if (symsec != (asection *) NULL) - val = (symsec->output_section->vma - + symsec->output_offset - + (GET_WORD (input_bfd, sym->e_value) - - symsec->vma)); - - /* If this is a global symbol set the written flag, and if - it is a local symbol see if we should discard it. */ - if (h != (struct aout_link_hash_entry *) NULL) - { - h->written = true; - h->indx = obj_aout_external_sym_count (output_bfd); - } - else if ((type & N_TYPE) != N_SETT - && (type & N_TYPE) != N_SETD - && (type & N_TYPE) != N_SETB - && (type & N_TYPE) != N_SETA) - { - switch (discard) - { - case discard_none: - break; - case discard_l: - if (*name == *finfo->info->lprefix - && (finfo->info->lprefix_len == 1 - || strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - skip = true; - break; - case discard_all: - skip = true; - break; - } - if (skip) - { - pass = false; - continue; - } - } - - /* An N_BINCL symbol indicates the start of the stabs - entries for a header file. We need to scan ahead to the - next N_EINCL symbol, ignoring nesting, adding up all the - characters in the symbol names, not including the file - numbers in types (the first number after an open - parenthesis). */ - if (type == N_BINCL) - { - struct external_nlist *incl_sym; - int nest; - struct aout_link_includes_entry *incl_entry; - struct aout_link_includes_totals *t; - - val = 0; - nest = 0; - for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++) - { - int incl_type; - - incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type); - if (incl_type == N_EINCL) - { - if (nest == 0) - break; - --nest; - } - else if (incl_type == N_BINCL) - ++nest; - else if (nest == 0) - { - const char *s; - - s = strings + GET_WORD (input_bfd, incl_sym->e_strx); - for (; *s != '\0'; s++) - { - val += *s; - if (*s == '(') - { - /* Skip the file number. */ - ++s; - while (isdigit ((unsigned char) *s)) - ++s; - --s; - } - } - } - } - - /* If we have already included a header file with the - same value, then replace this one with an N_EXCL - symbol. */ - copy = ! finfo->info->keep_memory; - incl_entry = aout_link_includes_lookup (&finfo->includes, - name, true, copy); - if (incl_entry == NULL) - return false; - for (t = incl_entry->totals; t != NULL; t = t->next) - if (t->total == val) - break; - if (t == NULL) - { - /* This is the first time we have seen this header - file with this set of stabs strings. */ - t = ((struct aout_link_includes_totals *) - bfd_hash_allocate (&finfo->includes.root, - sizeof *t)); - if (t == NULL) - return false; - t->total = val; - t->next = incl_entry->totals; - incl_entry->totals = t; - } - else - { - int *incl_map; - - /* This is a duplicate header file. We must change - it to be an N_EXCL entry, and mark all the - included symbols to prevent outputting them. */ - type = N_EXCL; - - nest = 0; - for (incl_sym = sym + 1, incl_map = symbol_map + 1; - incl_sym < sym_end; - incl_sym++, incl_map++) - { - int incl_type; - - incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type); - if (incl_type == N_EINCL) - { - if (nest == 0) - { - *incl_map = -1; - break; - } - --nest; - } - else if (incl_type == N_BINCL) - ++nest; - else if (nest == 0) - *incl_map = -1; - } - } - } - } - - /* Copy this symbol into the list of symbols we are going to - write out. */ - bfd_h_put_8 (output_bfd, type, outsym->e_type); - bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other), - outsym->e_other); - bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc), - outsym->e_desc); - copy = false; - if (! finfo->info->keep_memory) - { - /* name points into a string table which we are going to - free. If there is a hash table entry, use that string. - Otherwise, copy name into memory. */ - if (h != (struct aout_link_hash_entry *) NULL) - name = h->root.root.string; - else - copy = true; - } - strtab_index = add_to_stringtab (output_bfd, finfo->strtab, - name, copy); - if (strtab_index == (bfd_size_type) -1) - return false; - PUT_WORD (output_bfd, strtab_index, outsym->e_strx); - PUT_WORD (output_bfd, val, outsym->e_value); - *symbol_map = obj_aout_external_sym_count (output_bfd); - ++obj_aout_external_sym_count (output_bfd); - ++outsym; - } - - /* Write out the output symbols we have just constructed. */ - if (outsym > finfo->output_syms) - { - bfd_size_type outsym_count; - - if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0) - return false; - outsym_count = outsym - finfo->output_syms; - if (bfd_write ((PTR) finfo->output_syms, - (bfd_size_type) EXTERNAL_NLIST_SIZE, - (bfd_size_type) outsym_count, output_bfd) - != outsym_count * EXTERNAL_NLIST_SIZE) - return false; - finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE; - } - - return true; -} - -/* Write out a symbol that was not associated with an a.out input - object. */ - -static boolean -aout_link_write_other_symbol (h, data) - struct aout_link_hash_entry *h; - PTR data; -{ - struct aout_final_link_info *finfo = (struct aout_final_link_info *) data; - bfd *output_bfd; - int type; - bfd_vma val; - struct external_nlist outsym; - bfd_size_type indx; - - output_bfd = finfo->output_bfd; - - if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL) - { - if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol) - (output_bfd, finfo->info, h))) - { - /* FIXME: No way to handle errors. */ - abort (); - } - } - - if (h->written) - return true; - - h->written = true; - - /* An indx of -2 means the symbol must be written. */ - if (h->indx != -2 - && (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string, - false, false) == NULL))) - return true; - - switch (h->root.type) - { - default: - abort (); - /* Avoid variable not initialized warnings. */ - return true; - case bfd_link_hash_new: - /* This can happen for set symbols when sets are not being - built. */ - return true; - case bfd_link_hash_undefined: - type = N_UNDF | N_EXT; - val = 0; - break; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - asection *sec; - - sec = h->root.u.def.section->output_section; - BFD_ASSERT (bfd_is_abs_section (sec) - || sec->owner == output_bfd); - if (sec == obj_textsec (output_bfd)) - type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT; - else if (sec == obj_datasec (output_bfd)) - type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD; - else if (sec == obj_bsssec (output_bfd)) - type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB; - else - type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA; - type |= N_EXT; - val = (h->root.u.def.value - + sec->vma - + h->root.u.def.section->output_offset); - } - break; - case bfd_link_hash_common: - type = N_UNDF | N_EXT; - val = h->root.u.c.size; - break; - case bfd_link_hash_undefweak: - type = N_WEAKU; - val = 0; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: Ignore these for now. The circumstances under which - they should be written out are not clear to me. */ - return true; - } - - bfd_h_put_8 (output_bfd, type, outsym.e_type); - bfd_h_put_8 (output_bfd, 0, outsym.e_other); - bfd_h_put_16 (output_bfd, 0, outsym.e_desc); - indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string, - false); - if (indx == (bfd_size_type) -1) - { - /* FIXME: No way to handle errors. */ - abort (); - } - PUT_WORD (output_bfd, indx, outsym.e_strx); - PUT_WORD (output_bfd, val, outsym.e_value); - - if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0 - || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE, - (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE) - { - /* FIXME: No way to handle errors. */ - abort (); - } - - finfo->symoff += EXTERNAL_NLIST_SIZE; - h->indx = obj_aout_external_sym_count (output_bfd); - ++obj_aout_external_sym_count (output_bfd); - - return true; -} - -/* Link an a.out section into the output file. */ - -static boolean -aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr, - rel_size) - struct aout_final_link_info *finfo; - bfd *input_bfd; - asection *input_section; - file_ptr *reloff_ptr; - bfd_size_type rel_size; -{ - bfd_size_type input_size; - PTR relocs; - - /* Get the section contents. */ - input_size = bfd_section_size (input_bfd, input_section); - if (! bfd_get_section_contents (input_bfd, input_section, - (PTR) finfo->contents, - (file_ptr) 0, input_size)) - return false; - - /* Read in the relocs if we haven't already done it. */ - if (aout_section_data (input_section) != NULL - && aout_section_data (input_section)->relocs != NULL) - relocs = aout_section_data (input_section)->relocs; - else - { - relocs = finfo->relocs; - if (rel_size > 0) - { - if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0 - || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size) - return false; - } - } - - /* Relocate the section contents. */ - if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE) - { - if (! aout_link_input_section_std (finfo, input_bfd, input_section, - (struct reloc_std_external *) relocs, - rel_size, finfo->contents)) - return false; - } - else - { - if (! aout_link_input_section_ext (finfo, input_bfd, input_section, - (struct reloc_ext_external *) relocs, - rel_size, finfo->contents)) - return false; - } - - /* Write out the section contents. */ - if (! bfd_set_section_contents (finfo->output_bfd, - input_section->output_section, - (PTR) finfo->contents, - input_section->output_offset, - input_size)) - return false; - - /* If we are producing relocateable output, the relocs were - modified, and we now write them out. */ - if (finfo->info->relocateable && rel_size > 0) - { - if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0) - return false; - if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd) - != rel_size) - return false; - *reloff_ptr += rel_size; - - /* Assert that the relocs have not run into the symbols, and - that if these are the text relocs they have not run into the - data relocs. */ - BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd) - && (reloff_ptr != &finfo->treloff - || (*reloff_ptr - <= obj_datasec (finfo->output_bfd)->rel_filepos))); - } - - return true; -} - -/* Get the section corresponding to a reloc index. */ - -static INLINE asection * -aout_reloc_index_to_section (abfd, indx) - bfd *abfd; - int indx; -{ - switch (indx & N_TYPE) - { - case N_TEXT: - return obj_textsec (abfd); - case N_DATA: - return obj_datasec (abfd); - case N_BSS: - return obj_bsssec (abfd); - case N_ABS: - case N_UNDF: - return bfd_abs_section_ptr; - default: - abort (); - } -} - -/* Relocate an a.out section using standard a.out relocs. */ - -static boolean -aout_link_input_section_std (finfo, input_bfd, input_section, relocs, - rel_size, contents) - struct aout_final_link_info *finfo; - bfd *input_bfd; - asection *input_section; - struct reloc_std_external *relocs; - bfd_size_type rel_size; - bfd_byte *contents; -{ - boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *, - bfd *, asection *, - struct aout_link_hash_entry *, - PTR, bfd_byte *, boolean *, - bfd_vma *)); - bfd *output_bfd; - boolean relocateable; - struct external_nlist *syms; - char *strings; - struct aout_link_hash_entry **sym_hashes; - int *symbol_map; - bfd_size_type reloc_count; - register struct reloc_std_external *rel; - struct reloc_std_external *rel_end; - - output_bfd = finfo->output_bfd; - check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc; - - BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE); - BFD_ASSERT (input_bfd->xvec->header_byteorder - == output_bfd->xvec->header_byteorder); - - relocateable = finfo->info->relocateable; - syms = obj_aout_external_syms (input_bfd); - strings = obj_aout_external_strings (input_bfd); - sym_hashes = obj_aout_sym_hashes (input_bfd); - symbol_map = finfo->symbol_map; - - reloc_count = rel_size / RELOC_STD_SIZE; - rel = relocs; - rel_end = rel + reloc_count; - for (; rel < rel_end; rel++) - { - bfd_vma r_addr; - int r_index; - int r_extern; - int r_pcrel; - int r_baserel = 0; - reloc_howto_type *howto; - struct aout_link_hash_entry *h = NULL; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_addr = GET_SWORD (input_bfd, rel->r_address); - -#ifdef MY_reloc_howto - howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel); -#else - { - int r_jmptable; - int r_relative; - int r_length; - unsigned int howto_idx; - - if (bfd_header_big_endian (input_bfd)) - { - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); - r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); - r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG); - } - else - { - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_baserel = (0 != (rel->r_type[0] - & RELOC_STD_BITS_BASEREL_LITTLE)); - r_jmptable= (0 != (rel->r_type[0] - & RELOC_STD_BITS_JMPTABLE_LITTLE)); - r_relative= (0 != (rel->r_type[0] - & RELOC_STD_BITS_RELATIVE_LITTLE)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE); - } - - howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel - + 16 * r_jmptable + 32 * r_relative); - BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std)); - howto = howto_table_std + howto_idx; - } -#endif - - if (relocateable) - { - /* We are generating a relocateable output file, and must - modify the reloc accordingly. */ - if (r_extern) - { - /* If we know the symbol this relocation is against, - convert it into a relocation against a section. This - is what the native linker does. */ - h = sym_hashes[r_index]; - if (h != (struct aout_link_hash_entry *) NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - asection *output_section; - - /* Change the r_extern value. */ - if (bfd_header_big_endian (output_bfd)) - rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG; - else - rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE; - - /* Compute a new r_index. */ - output_section = h->root.u.def.section->output_section; - if (output_section == obj_textsec (output_bfd)) - r_index = N_TEXT; - else if (output_section == obj_datasec (output_bfd)) - r_index = N_DATA; - else if (output_section == obj_bsssec (output_bfd)) - r_index = N_BSS; - else - r_index = N_ABS; - - /* Add the symbol value and the section VMA to the - addend stored in the contents. */ - relocation = (h->root.u.def.value - + output_section->vma - + h->root.u.def.section->output_offset); - } - else - { - /* We must change r_index according to the symbol - map. */ - r_index = symbol_map[r_index]; - - if (r_index == -1) - { - if (h != NULL) - { - /* We decided to strip this symbol, but it - turns out that we can't. Note that we - lose the other and desc information here. - I don't think that will ever matter for a - global symbol. */ - if (h->indx < 0) - { - h->indx = -2; - h->written = false; - if (! aout_link_write_other_symbol (h, - (PTR) finfo)) - return false; - } - r_index = h->indx; - } - else - { - const char *name; - - name = strings + GET_WORD (input_bfd, - syms[r_index].e_strx); - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, input_section, - r_addr))) - return false; - r_index = 0; - } - } - - relocation = 0; - } - - /* Write out the new r_index value. */ - if (bfd_header_big_endian (output_bfd)) - { - rel->r_index[0] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[2] = r_index; - } - else - { - rel->r_index[2] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[0] = r_index; - } - } - else - { - asection *section; - - /* This is a relocation against a section. We must - adjust by the amount that the section moved. */ - section = aout_reloc_index_to_section (input_bfd, r_index); - relocation = (section->output_section->vma - + section->output_offset - - section->vma); - } - - /* Change the address of the relocation. */ - PUT_WORD (output_bfd, - r_addr + input_section->output_offset, - rel->r_address); - - /* Adjust a PC relative relocation by removing the reference - to the original address in the section and including the - reference to the new address. */ - if (r_pcrel) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - -#ifdef MY_relocatable_reloc - MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr); -#endif - - if (relocation == 0) - r = bfd_reloc_ok; - else - r = MY_relocate_contents (howto, - input_bfd, relocation, - contents + r_addr); - } - else - { - boolean hundef; - - /* We are generating an executable, and must do a full - relocation. */ - hundef = false; - if (r_extern) - { - h = sym_hashes[r_index]; - - if (h != (struct aout_link_hash_entry *) NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - relocation = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else - { - hundef = true; - relocation = 0; - } - } - else - { - asection *section; - - section = aout_reloc_index_to_section (input_bfd, r_index); - relocation = (section->output_section->vma - + section->output_offset - - section->vma); - if (r_pcrel) - relocation += input_section->vma; - } - - if (check_dynamic_reloc != NULL) - { - boolean skip; - - if (! ((*check_dynamic_reloc) - (finfo->info, input_bfd, input_section, h, - (PTR) rel, contents, &skip, &relocation))) - return false; - if (skip) - continue; - } - - /* Now warn if a global symbol is undefined. We could not - do this earlier, because check_dynamic_reloc might want - to skip this reloc. */ - if (hundef && ! finfo->info->shared && ! r_baserel) - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, name, input_bfd, input_section, r_addr))) - return false; - } - - r = MY_final_link_relocate (howto, - input_bfd, input_section, - contents, r_addr, relocation, - (bfd_vma) 0); - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (r_extern) - name = strings + GET_WORD (input_bfd, - syms[r_index].e_strx); - else - { - asection *s; - - s = aout_reloc_index_to_section (input_bfd, r_index); - name = bfd_section_name (input_bfd, s); - } - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, name, howto->name, - (bfd_vma) 0, input_bfd, input_section, r_addr))) - return false; - } - break; - } - } - } - - return true; -} - -/* Relocate an a.out section using extended a.out relocs. */ - -static boolean -aout_link_input_section_ext (finfo, input_bfd, input_section, relocs, - rel_size, contents) - struct aout_final_link_info *finfo; - bfd *input_bfd; - asection *input_section; - struct reloc_ext_external *relocs; - bfd_size_type rel_size; - bfd_byte *contents; -{ - boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *, - bfd *, asection *, - struct aout_link_hash_entry *, - PTR, bfd_byte *, boolean *, - bfd_vma *)); - bfd *output_bfd; - boolean relocateable; - struct external_nlist *syms; - char *strings; - struct aout_link_hash_entry **sym_hashes; - int *symbol_map; - bfd_size_type reloc_count; - register struct reloc_ext_external *rel; - struct reloc_ext_external *rel_end; - - output_bfd = finfo->output_bfd; - check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc; - - BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE); - BFD_ASSERT (input_bfd->xvec->header_byteorder - == output_bfd->xvec->header_byteorder); - - relocateable = finfo->info->relocateable; - syms = obj_aout_external_syms (input_bfd); - strings = obj_aout_external_strings (input_bfd); - sym_hashes = obj_aout_sym_hashes (input_bfd); - symbol_map = finfo->symbol_map; - - reloc_count = rel_size / RELOC_EXT_SIZE; - rel = relocs; - rel_end = rel + reloc_count; - for (; rel < rel_end; rel++) - { - bfd_vma r_addr; - int r_index; - int r_extern; - unsigned int r_type; - bfd_vma r_addend; - struct aout_link_hash_entry *h = NULL; - asection *r_section = NULL; - bfd_vma relocation; - - r_addr = GET_SWORD (input_bfd, rel->r_address); - - if (bfd_header_big_endian (input_bfd)) - { - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG); - } - else - { - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - r_addend = GET_SWORD (input_bfd, rel->r_addend); - - BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext)); - - if (relocateable) - { - /* We are generating a relocateable output file, and must - modify the reloc accordingly. */ - if (r_extern) - { - /* If we know the symbol this relocation is against, - convert it into a relocation against a section. This - is what the native linker does. */ - h = sym_hashes[r_index]; - if (h != (struct aout_link_hash_entry *) NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - asection *output_section; - - /* Change the r_extern value. */ - if (bfd_header_big_endian (output_bfd)) - rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG; - else - rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE; - - /* Compute a new r_index. */ - output_section = h->root.u.def.section->output_section; - if (output_section == obj_textsec (output_bfd)) - r_index = N_TEXT; - else if (output_section == obj_datasec (output_bfd)) - r_index = N_DATA; - else if (output_section == obj_bsssec (output_bfd)) - r_index = N_BSS; - else - r_index = N_ABS; - - /* Add the symbol value and the section VMA to the - addend. */ - relocation = (h->root.u.def.value - + output_section->vma - + h->root.u.def.section->output_offset); - - /* Now RELOCATION is the VMA of the final - destination. If this is a PC relative reloc, - then ADDEND is the negative of the source VMA. - We want to set ADDEND to the difference between - the destination VMA and the source VMA, which - means we must adjust RELOCATION by the change in - the source VMA. This is done below. */ - } - else - { - /* We must change r_index according to the symbol - map. */ - r_index = symbol_map[r_index]; - - if (r_index == -1) - { - if (h != NULL) - { - /* We decided to strip this symbol, but it - turns out that we can't. Note that we - lose the other and desc information here. - I don't think that will ever matter for a - global symbol. */ - if (h->indx < 0) - { - h->indx = -2; - h->written = false; - if (! aout_link_write_other_symbol (h, - (PTR) finfo)) - return false; - } - r_index = h->indx; - } - else - { - const char *name; - - name = strings + GET_WORD (input_bfd, - syms[r_index].e_strx); - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, input_section, - r_addr))) - return false; - r_index = 0; - } - } - - relocation = 0; - - /* If this is a PC relative reloc, then the addend - is the negative of the source VMA. We must - adjust it by the change in the source VMA. This - is done below. */ - } - - /* Write out the new r_index value. */ - if (bfd_header_big_endian (output_bfd)) - { - rel->r_index[0] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[2] = r_index; - } - else - { - rel->r_index[2] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[0] = r_index; - } - } - else - { - /* This is a relocation against a section. We must - adjust by the amount that the section moved. */ - r_section = aout_reloc_index_to_section (input_bfd, r_index); - relocation = (r_section->output_section->vma - + r_section->output_offset - - r_section->vma); - - /* If this is a PC relative reloc, then the addend is - the difference in VMA between the destination and the - source. We have just adjusted for the change in VMA - of the destination, so we must also adjust by the - change in VMA of the source. This is done below. */ - } - - /* As described above, we must always adjust a PC relative - reloc by the change in VMA of the source. */ - if (howto_table_ext[r_type].pc_relative) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Change the addend if necessary. */ - if (relocation != 0) - PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend); - - /* Change the address of the relocation. */ - PUT_WORD (output_bfd, - r_addr + input_section->output_offset, - rel->r_address); - } - else - { - boolean hundef; - bfd_reloc_status_type r; - - /* We are generating an executable, and must do a full - relocation. */ - hundef = false; - if (r_extern) - { - h = sym_hashes[r_index]; - - if (h != (struct aout_link_hash_entry *) NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - relocation = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else - { - hundef = true; - relocation = 0; - } - } - else if (r_type == RELOC_BASE10 - || r_type == RELOC_BASE13 - || r_type == RELOC_BASE22) - { - struct external_nlist *sym; - int type; - - /* For base relative relocs, r_index is always an index - into the symbol table, even if r_extern is 0. */ - sym = syms + r_index; - type = bfd_h_get_8 (input_bfd, sym->e_type); - if ((type & N_TYPE) == N_TEXT - || type == N_WEAKT) - r_section = obj_textsec (input_bfd); - else if ((type & N_TYPE) == N_DATA - || type == N_WEAKD) - r_section = obj_datasec (input_bfd); - else if ((type & N_TYPE) == N_BSS - || type == N_WEAKB) - r_section = obj_bsssec (input_bfd); - else if ((type & N_TYPE) == N_ABS - || type == N_WEAKA) - r_section = bfd_abs_section_ptr; - else - abort (); - relocation = (r_section->output_section->vma - + r_section->output_offset - + (GET_WORD (input_bfd, sym->e_value) - - r_section->vma)); - } - else - { - r_section = aout_reloc_index_to_section (input_bfd, r_index); - - /* If this is a PC relative reloc, then R_ADDEND is the - difference between the two vmas, or - old_dest_sec + old_dest_off - (old_src_sec + old_src_off) - where - old_dest_sec == section->vma - and - old_src_sec == input_section->vma - and - old_src_off == r_addr - - _bfd_final_link_relocate expects RELOCATION + - R_ADDEND to be the VMA of the destination minus - r_addr (the minus r_addr is because this relocation - is not pcrel_offset, which is a bit confusing and - should, perhaps, be changed), or - new_dest_sec - where - new_dest_sec == output_section->vma + output_offset - We arrange for this to happen by setting RELOCATION to - new_dest_sec + old_src_sec - old_dest_sec - - If this is not a PC relative reloc, then R_ADDEND is - simply the VMA of the destination, so we set - RELOCATION to the change in the destination VMA, or - new_dest_sec - old_dest_sec - */ - relocation = (r_section->output_section->vma - + r_section->output_offset - - r_section->vma); - if (howto_table_ext[r_type].pc_relative) - relocation += input_section->vma; - } - - if (check_dynamic_reloc != NULL) - { - boolean skip; - - if (! ((*check_dynamic_reloc) - (finfo->info, input_bfd, input_section, h, - (PTR) rel, contents, &skip, &relocation))) - return false; - if (skip) - continue; - } - - /* Now warn if a global symbol is undefined. We could not - do this earlier, because check_dynamic_reloc might want - to skip this reloc. */ - if (hundef - && ! finfo->info->shared - && r_type != RELOC_BASE10 - && r_type != RELOC_BASE13 - && r_type != RELOC_BASE22) - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, name, input_bfd, input_section, r_addr))) - return false; - } - - r = MY_final_link_relocate (howto_table_ext + r_type, - input_bfd, input_section, - contents, r_addr, relocation, - r_addend); - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (r_extern - || r_type == RELOC_BASE10 - || r_type == RELOC_BASE13 - || r_type == RELOC_BASE22) - name = strings + GET_WORD (input_bfd, - syms[r_index].e_strx); - else - { - asection *s; - - s = aout_reloc_index_to_section (input_bfd, r_index); - name = bfd_section_name (input_bfd, s); - } - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, name, howto_table_ext[r_type].name, - r_addend, input_bfd, input_section, r_addr))) - return false; - } - break; - } - } - } - } - - return true; -} - -/* Handle a link order which is supposed to generate a reloc. */ - -static boolean -aout_link_reloc_link_order (finfo, o, p) - struct aout_final_link_info *finfo; - asection *o; - struct bfd_link_order *p; -{ - struct bfd_link_order_reloc *pr; - int r_index; - int r_extern; - reloc_howto_type *howto; - file_ptr *reloff_ptr; - struct reloc_std_external srel; - struct reloc_ext_external erel; - PTR rel_ptr; - - pr = p->u.reloc.p; - - if (p->type == bfd_section_reloc_link_order) - { - r_extern = 0; - if (bfd_is_abs_section (pr->u.section)) - r_index = N_ABS | N_EXT; - else - { - BFD_ASSERT (pr->u.section->owner == finfo->output_bfd); - r_index = pr->u.section->target_index; - } - } - else - { - struct aout_link_hash_entry *h; - - BFD_ASSERT (p->type == bfd_symbol_reloc_link_order); - r_extern = 1; - h = ((struct aout_link_hash_entry *) - bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info, - pr->u.name, false, false, true)); - if (h != (struct aout_link_hash_entry *) NULL - && h->indx >= 0) - r_index = h->indx; - else if (h != NULL) - { - /* We decided to strip this symbol, but it turns out that we - can't. Note that we lose the other and desc information - here. I don't think that will ever matter for a global - symbol. */ - h->indx = -2; - h->written = false; - if (! aout_link_write_other_symbol (h, (PTR) finfo)) - return false; - r_index = h->indx; - } - else - { - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, pr->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - r_index = 0; - } - } - - howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc); - if (howto == 0) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (o == obj_textsec (finfo->output_bfd)) - reloff_ptr = &finfo->treloff; - else if (o == obj_datasec (finfo->output_bfd)) - reloff_ptr = &finfo->dreloff; - else - abort (); - - if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE) - { -#ifdef MY_put_reloc - MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto, - &srel); -#else - { - int r_pcrel; - int r_baserel; - int r_jmptable; - int r_relative; - int r_length; - - r_pcrel = howto->pc_relative; - r_baserel = (howto->type & 8) != 0; - r_jmptable = (howto->type & 16) != 0; - r_relative = (howto->type & 32) != 0; - r_length = howto->size; - - PUT_WORD (finfo->output_bfd, p->offset, srel.r_address); - if (bfd_header_big_endian (finfo->output_bfd)) - { - srel.r_index[0] = r_index >> 16; - srel.r_index[1] = r_index >> 8; - srel.r_index[2] = r_index; - srel.r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - srel.r_index[2] = r_index >> 16; - srel.r_index[1] = r_index >> 8; - srel.r_index[0] = r_index; - srel.r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } - } -#endif - rel_ptr = (PTR) &srel; - - /* We have to write the addend into the object file, since - standard a.out relocs are in place. It would be more - reliable if we had the current contents of the file here, - rather than assuming zeroes, but we can't read the file since - it was opened using bfd_openw. */ - if (pr->addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type r; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - return false; - r = MY_relocate_contents (howto, finfo->output_bfd, - pr->addend, buf); - switch (r) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, - (p->type == bfd_section_reloc_link_order - ? bfd_section_name (finfo->output_bfd, - pr->u.section) - : pr->u.name), - howto->name, pr->addend, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (finfo->output_bfd, o, - (PTR) buf, - (file_ptr) p->offset, - size); - free (buf); - if (! ok) - return false; - } - } - else - { - PUT_WORD (finfo->output_bfd, p->offset, erel.r_address); - - if (bfd_header_big_endian (finfo->output_bfd)) - { - erel.r_index[0] = r_index >> 16; - erel.r_index[1] = r_index >> 8; - erel.r_index[2] = r_index; - erel.r_type[0] = - ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) - | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG)); - } - else - { - erel.r_index[2] = r_index >> 16; - erel.r_index[1] = r_index >> 8; - erel.r_index[0] = r_index; - erel.r_type[0] = - (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) - | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend); - - rel_ptr = (PTR) &erel; - } - - if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0 - || (bfd_write (rel_ptr, (bfd_size_type) 1, - obj_reloc_entry_size (finfo->output_bfd), - finfo->output_bfd) - != obj_reloc_entry_size (finfo->output_bfd))) - return false; - - *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd); - - /* Assert that the relocs have not run into the symbols, and that n - the text relocs have not run into the data relocs. */ - BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd) - && (reloff_ptr != &finfo->treloff - || (*reloff_ptr - <= obj_datasec (finfo->output_bfd)->rel_filepos))); - - return true; -} diff --git a/contrib/gdb/bfd/archive.c b/contrib/gdb/bfd/archive.c deleted file mode 100644 index 248b9181e75..00000000000 --- a/contrib/gdb/bfd/archive.c +++ /dev/null @@ -1,2094 +0,0 @@ -/* BFD back-end for archive files (libraries). - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -@setfilename archive-info -SECTION - Archives - -DESCRIPTION - An archive (or library) is just another BFD. It has a symbol - table, although there's not much a user program will do with it. - - The big difference between an archive BFD and an ordinary BFD - is that the archive doesn't have sections. Instead it has a - chain of BFDs that are considered its contents. These BFDs can - be manipulated like any other. The BFDs contained in an - archive opened for reading will all be opened for reading. You - may put either input or output BFDs into an archive opened for - output; they will be handled correctly when the archive is closed. - - Use <> to step through - the contents of an archive opened for input. You don't - have to read the entire archive if you don't want - to! Read it until you find what you want. - - Archive contents of output BFDs are chained through the - <> pointer in a BFD. The first one is findable through - the <> slot of the archive. Set it with - <> (q.v.). A given BFD may be in only one - open output archive at a time. - - As expected, the BFD archive code is more general than the - archive code of any given environment. BFD archives may - contain files of different formats (e.g., a.out and coff) and - even different architectures. You may even place archives - recursively into archives! - - This can cause unexpected confusion, since some archive - formats are more expressive than others. For instance, Intel - COFF archives can preserve long filenames; SunOS a.out archives - cannot. If you move a file from the first to the second - format and back again, the filename may be truncated. - Likewise, different a.out environments have different - conventions as to how they truncate filenames, whether they - preserve directory names in filenames, etc. When - interoperating with native tools, be sure your files are - homogeneous. - - Beware: most of these formats do not react well to the - presence of spaces in filenames. We do the best we can, but - can't always handle this case due to restrictions in the format of - archives. Many Unix utilities are braindead in regards to - spaces and such in filenames anyway, so this shouldn't be much - of a restriction. - - Archives are supported in BFD in <>. - -*/ - -/* Assumes: - o - all archive elements start on an even boundary, newline padded; - o - all arch headers are char *; - o - all arch headers are the same size (across architectures). -*/ - -/* Some formats provide a way to cram a long filename into the short - (16 chars) space provided by a BSD archive. The trick is: make a - special "file" in the front of the archive, sort of like the SYMDEF - entry. If the filename is too long to fit, put it in the extended - name table, and use its index as the filename. To prevent - confusion prepend the index with a space. This means you can't - have filenames that start with a space, but then again, many Unix - utilities can't handle that anyway. - - This scheme unfortunately requires that you stand on your head in - order to write an archive since you need to put a magic file at the - front, and need to touch every entry to do so. C'est la vie. - - We support two variants of this idea: - The SVR4 format (extended name table is named "//"), - and an extended pseudo-BSD variant (extended name table is named - "ARFILENAMES/"). The origin of the latter format is uncertain. - - BSD 4.4 uses a third scheme: It writes a long filename - directly after the header. This allows 'ar q' to work. - We currently can read BSD 4.4 archives, but not write them. -*/ - -/* Summary of archive member names: - - Symbol table (must be first): - "__.SYMDEF " - Symbol table, Berkeley style, produced by ranlib. - "/ " - Symbol table, system 5 style. - - Long name table (must be before regular file members): - "// " - Long name table, System 5 R4 style. - "ARFILENAMES/ " - Long name table, non-standard extended BSD (not BSD 4.4). - - Regular file members with short names: - "filename.o/ " - Regular file, System 5 style (embedded spaces ok). - "filename.o " - Regular file, Berkeley style (no embedded spaces). - - Regular files with long names (or embedded spaces, for BSD variants): - "/18 " - SVR4 style, name at offset 18 in name table. - "#1/23 " - Long name (or embedded paces) 23 characters long, - BSD 4.4 style, full name follows header. - Implemented for reading, not writing. - " 18 " - Long name 18 characters long, extended pseudo-BSD. - */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/ar.h" -#include "aout/ranlib.h" -#include -#include /* For memchr, strrchr and friends */ -#include - -#ifndef errno -extern int errno; -#endif - -#ifdef GNU960 -#define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB) -#endif - -/* Can't define this in hosts/foo.h, because (e.g. in gprof) the hosts file - is included, then obstack.h, which thinks if offsetof is defined, it - doesn't need to include stddef.h. */ -/* Define offsetof for those systems which lack it */ - -#if !defined (offsetof) -#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) -#endif - -/* We keep a cache of archive filepointers to archive elements to - speed up searching the archive by filepos. We only add an entry to - the cache when we actually read one. We also don't sort the cache; - it's generally short enough to search linearly. - Note that the pointers here point to the front of the ar_hdr, not - to the front of the contents! -*/ -struct ar_cache -{ - file_ptr ptr; - bfd *arelt; - struct ar_cache *next; -}; - -#define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char) -#define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen) - -#define arch_eltdata(bfd) ((struct areltdata *)((bfd)->arelt_data)) -#define arch_hdr(bfd) ((struct ar_hdr *)arch_eltdata(bfd)->arch_header) - -static char *get_extended_arelt_filename PARAMS ((bfd *arch, - const char *name)); -static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd)); -static boolean do_slurp_coff_armap PARAMS ((bfd *abfd)); -static const char *normalize PARAMS ((bfd *, const char *file)); -static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd, - const char *)); - -boolean -_bfd_generic_mkarchive (abfd) - bfd *abfd; -{ - abfd->tdata.aout_ar_data = ((struct artdata *) - bfd_zalloc (abfd, sizeof (struct artdata))); - - if (bfd_ardata (abfd) == NULL) - return false; - - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->tdata = NULL; - - return true; -} - -/* -FUNCTION - bfd_get_next_mapent - -SYNOPSIS - symindex bfd_get_next_mapent(bfd *abfd, symindex previous, carsym **sym); - -DESCRIPTION - Step through archive @var{abfd}'s symbol table (if it - has one). Successively update @var{sym} with the next symbol's - information, returning that symbol's (internal) index into the - symbol table. - - Supply <> as the @var{previous} entry to get - the first one; returns <> when you've already - got the last one. - - A <> is a canonical archive symbol. The only - user-visible element is its name, a null-terminated string. -*/ - -symindex -bfd_get_next_mapent (abfd, prev, entry) - bfd *abfd; - symindex prev; - carsym **entry; -{ - if (!bfd_has_map (abfd)) - { - bfd_set_error (bfd_error_invalid_operation); - return BFD_NO_MORE_SYMBOLS; - } - - if (prev == BFD_NO_MORE_SYMBOLS) - prev = 0; - else - ++prev; - if (prev >= bfd_ardata (abfd)->symdef_count) - return BFD_NO_MORE_SYMBOLS; - - *entry = (bfd_ardata (abfd)->symdefs + prev); - return prev; -} - -/* To be called by backends only */ - -bfd * -_bfd_create_empty_archive_element_shell (obfd) - bfd *obfd; -{ - return _bfd_new_bfd_contained_in (obfd); -} - -/* -FUNCTION - bfd_set_archive_head - -SYNOPSIS - boolean bfd_set_archive_head(bfd *output, bfd *new_head); - -DESCRIPTION - Set the head of the chain of - BFDs contained in the archive @var{output} to @var{new_head}. -*/ - -boolean -bfd_set_archive_head (output_archive, new_head) - bfd *output_archive; - bfd *new_head; -{ - - output_archive->archive_head = new_head; - return true; -} - -bfd * -_bfd_look_for_bfd_in_cache (arch_bfd, filepos) - bfd *arch_bfd; - file_ptr filepos; -{ - struct ar_cache *current; - - for (current = bfd_ardata (arch_bfd)->cache; current != NULL; - current = current->next) - if (current->ptr == filepos) - return current->arelt; - - return NULL; -} - -/* Kind of stupid to call cons for each one, but we don't do too many */ -boolean -_bfd_add_bfd_to_archive_cache (arch_bfd, filepos, new_elt) - bfd *arch_bfd, *new_elt; - file_ptr filepos; -{ - struct ar_cache *new_cache = ((struct ar_cache *) - bfd_zalloc (arch_bfd, - sizeof (struct ar_cache))); - - if (new_cache == NULL) - return false; - - new_cache->ptr = filepos; - new_cache->arelt = new_elt; - new_cache->next = (struct ar_cache *) NULL; - if (bfd_ardata (arch_bfd)->cache == NULL) - bfd_ardata (arch_bfd)->cache = new_cache; - else - { - struct ar_cache *current = bfd_ardata (arch_bfd)->cache; - - while (current->next != NULL) - current = current->next; - current->next = new_cache; - } - - return true; -} - -/* The name begins with space. Hence the rest of the name is an index into - the string table. */ - -static char * -get_extended_arelt_filename (arch, name) - bfd *arch; - const char *name; -{ - unsigned long index = 0; - - /* Should extract string so that I can guarantee not to overflow into - the next region, but I'm too lazy. */ - errno = 0; - /* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */ - index = strtol (name + 1, NULL, 10); - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - return bfd_ardata (arch)->extended_names + index; -} - -/* This functions reads an arch header and returns an areltdata pointer, or - NULL on error. - - Presumes the file pointer is already in the right place (ie pointing - to the ar_hdr in the file). Moves the file pointer; on success it - should be pointing to the front of the file contents; on failure it - could have been moved arbitrarily. -*/ - -PTR -_bfd_generic_read_ar_hdr (abfd) - bfd *abfd; -{ - return _bfd_generic_read_ar_hdr_mag (abfd, (const char *) NULL); -} - -/* Alpha ECOFF uses an optional different ARFMAG value, so we have a - variant of _bfd_generic_read_ar_hdr which accepts a magic string. */ - -PTR -_bfd_generic_read_ar_hdr_mag (abfd, mag) - bfd *abfd; - const char *mag; -{ - struct ar_hdr hdr; - char *hdrp = (char *) &hdr; - unsigned int parsed_size; - struct areltdata *ared; - char *filename = NULL; - unsigned int namelen = 0; - unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr); - char *allocptr = 0; - - if (bfd_read ((PTR) hdrp, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0 - && (mag == NULL - || strncmp (hdr.ar_fmag, mag, 2) != 0)) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - errno = 0; - parsed_size = strtol (hdr.ar_size, NULL, 10); - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - /* Extract the filename from the archive - there are two ways to - specify an extendend name table, either the first char of the - name is a space, or it's a slash. */ - if ((hdr.ar_name[0] == '/' - || (hdr.ar_name[0] == ' ' - && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL)) - && bfd_ardata (abfd)->extended_names != NULL) - { - filename = get_extended_arelt_filename (abfd, hdr.ar_name); - if (filename == NULL) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - } - /* BSD4.4-style long filename. - Only implemented for reading, so far! */ - else if (hdr.ar_name[0] == '#' && hdr.ar_name[1] == '1' - && hdr.ar_name[2] == '/' && isdigit (hdr.ar_name[3])) - { - /* BSD-4.4 extended name */ - namelen = atoi (&hdr.ar_name[3]); - allocsize += namelen + 1; - parsed_size -= namelen; - - allocptr = bfd_zalloc (abfd, allocsize); - if (allocptr == NULL) - return NULL; - filename = (allocptr - + sizeof (struct areltdata) - + sizeof (struct ar_hdr)); - if (bfd_read (filename, 1, namelen, abfd) != namelen) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - filename[namelen] = '\0'; - } - else - { - /* We judge the end of the name by looking for '/' or ' '. - Note: The SYSV format (terminated by '/') allows embedded - spaces, so only look for ' ' if we don't find '/'. */ - - namelen = 0; - while (hdr.ar_name[namelen] != '\0' && - hdr.ar_name[namelen] != '/') - { - namelen++; - if (namelen == (unsigned) ar_maxnamelen (abfd)) - { - namelen = 0; - while (hdr.ar_name[namelen] != ' ' - && namelen < (unsigned) ar_maxnamelen (abfd)) - namelen++; - break; - } - } - - allocsize += namelen + 1; - } - - if (!allocptr) - { - allocptr = bfd_zalloc (abfd, allocsize); - if (allocptr == NULL) - return NULL; - } - - ared = (struct areltdata *) allocptr; - - ared->arch_header = allocptr + sizeof (struct areltdata); - memcpy ((char *) ared->arch_header, (char *) &hdr, sizeof (struct ar_hdr)); - ared->parsed_size = parsed_size; - - if (filename != NULL) - ared->filename = filename; - else - { - ared->filename = allocptr + (sizeof (struct areltdata) + - sizeof (struct ar_hdr)); - if (namelen) - memcpy (ared->filename, hdr.ar_name, namelen); - ared->filename[namelen] = '\0'; - } - - return (PTR) ared; -} - -/* This is an internal function; it's mainly used when indexing - through the archive symbol table, but also used to get the next - element, since it handles the bookkeeping so nicely for us. */ - -bfd * -_bfd_get_elt_at_filepos (archive, filepos) - bfd *archive; - file_ptr filepos; -{ - struct areltdata *new_areldata; - bfd *n_nfd; - - n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos); - if (n_nfd) - return n_nfd; - - if (0 > bfd_seek (archive, filepos, SEEK_SET)) - return NULL; - - if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL) - return NULL; - - n_nfd = _bfd_create_empty_archive_element_shell (archive); - if (n_nfd == NULL) - { - bfd_release (archive, (PTR) new_areldata); - return NULL; - } - - n_nfd->origin = bfd_tell (archive); - n_nfd->arelt_data = (PTR) new_areldata; - n_nfd->filename = new_areldata->filename; - - if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd)) - return n_nfd; - - /* huh? */ - bfd_release (archive, (PTR) n_nfd); - bfd_release (archive, (PTR) new_areldata); - return NULL; -} - -/* Return the BFD which is referenced by the symbol in ABFD indexed by - INDEX. INDEX should have been returned by bfd_get_next_mapent. */ - -bfd * -_bfd_generic_get_elt_at_index (abfd, index) - bfd *abfd; - symindex index; -{ - carsym *entry; - - entry = bfd_ardata (abfd)->symdefs + index; - return _bfd_get_elt_at_filepos (abfd, entry->file_offset); -} - -/* -FUNCTION - bfd_openr_next_archived_file - -SYNOPSIS - bfd *bfd_openr_next_archived_file(bfd *archive, bfd *previous); - -DESCRIPTION - Provided a BFD, @var{archive}, containing an archive and NULL, open - an input BFD on the first contained element and returns that. - Subsequent calls should pass - the archive and the previous return value to return a created - BFD to the next contained element. NULL is returned when there - are no more. - -*/ - -bfd * -bfd_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - if ((bfd_get_format (archive) != bfd_archive) || - (archive->direction == write_direction)) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - return BFD_SEND (archive, - openr_next_archived_file, - (archive, - last_file)); -} - -bfd * -bfd_generic_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - file_ptr filestart; - - if (!last_file) - filestart = bfd_ardata (archive)->first_file_filepos; - else - { - unsigned int size = arelt_size (last_file); - /* Pad to an even boundary... - Note that last_file->origin can be odd in the case of - BSD-4.4-style element with a long odd size. */ - filestart = last_file->origin + size; - filestart += filestart % 2; - } - - return _bfd_get_elt_at_filepos (archive, filestart); -} - - -const bfd_target * -bfd_generic_archive_p (abfd) - bfd *abfd; -{ - struct artdata *tdata_hold; - char armag[SARMAG + 1]; - - tdata_hold = abfd->tdata.aout_ar_data; - - if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - -#ifdef GNU960 - if (strncmp (armag, BFD_GNU960_ARMAG (abfd), SARMAG) != 0) - return 0; -#else - if (strncmp (armag, ARMAG, SARMAG) != 0 && - strncmp (armag, ARMAGB, SARMAG) != 0) - return 0; -#endif - - /* We are setting bfd_ardata(abfd) here, but since bfd_ardata - involves a cast, we can't do it as the left operand of assignment. */ - abfd->tdata.aout_ar_data = ((struct artdata *) - bfd_zalloc (abfd, sizeof (struct artdata))); - - if (bfd_ardata (abfd) == NULL) - return NULL; - - bfd_ardata (abfd)->first_file_filepos = SARMAG; - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->tdata = NULL; - - if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = tdata_hold; - return NULL; - } - - if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = tdata_hold; - return NULL; - } - - if (bfd_has_map (abfd)) - { - bfd *first; - - /* This archive has a map, so we may presume that the contents - are object files. Make sure that if the first file in the - archive can be recognized as an object file, it is for this - target. If not, assume that this is the wrong format. If - the first file is not an object file, somebody is doing - something weird, and we permit it so that ar -t will work. - - This is done because any normal format will recognize any - normal archive, regardless of the format of the object files. - We do accept an empty archive. */ - - first = bfd_openr_next_archived_file (abfd, (bfd *) NULL); - if (first != NULL) - { - boolean fail; - - first->target_defaulted = false; - fail = false; - if (bfd_check_format (first, bfd_object) - && first->xvec != abfd->xvec) - { - (void) bfd_close (first); - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = tdata_hold; - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* We ought to close first here, but we can't, because we - have no way to remove it from the archive cache. FIXME. */ - } - } - - return abfd->xvec; -} - -/* Some constants for a 32 bit BSD archive structure. We do not - support 64 bit archives presently; so far as I know, none actually - exist. Supporting them would require changing these constants, and - changing some bfd_h_get_32 to bfd_h_get_64. */ - -/* The size of an external symdef structure. */ -#define BSD_SYMDEF_SIZE 8 - -/* The offset from the start of a symdef structure to the file offset. */ -#define BSD_SYMDEF_OFFSET_SIZE 4 - -/* The size of the symdef count. */ -#define BSD_SYMDEF_COUNT_SIZE 4 - -/* The size of the string count. */ -#define BSD_STRING_COUNT_SIZE 4 - -/* Returns false on error, true otherwise */ - -static boolean -do_slurp_bsd_armap (abfd) - bfd *abfd; -{ - struct areltdata *mapdata; - unsigned int counter; - bfd_byte *raw_armap, *rbase; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - unsigned int parsed_size; - carsym *set; - - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == NULL) - return false; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, (PTR) mapdata); /* Don't need it any more. */ - - raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size); - if (raw_armap == (bfd_byte *) NULL) - return false; - - if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - byebye: - bfd_release (abfd, (PTR) raw_armap); - return false; - } - - ardata->symdef_count = bfd_h_get_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE; - - if (ardata->symdef_count * BSD_SYMDEF_SIZE > - parsed_size - BSD_SYMDEF_COUNT_SIZE) - { - /* Probably we're using the wrong byte ordering. */ - bfd_set_error (bfd_error_wrong_format); - goto byebye; - } - - ardata->cache = 0; - rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE; - stringbase = ((char *) rbase - + ardata->symdef_count * BSD_SYMDEF_SIZE - + BSD_STRING_COUNT_SIZE); - ardata->symdefs = (carsym *) bfd_alloc (abfd, - (ardata->symdef_count - * sizeof (carsym))); - if (!ardata->symdefs) - return false; - - for (counter = 0, set = ardata->symdefs; - counter < ardata->symdef_count; - counter++, set++, rbase += BSD_SYMDEF_SIZE) - { - set->name = bfd_h_get_32 (abfd, rbase) + stringbase; - set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - /* FIXME, we should provide some way to free raw_ardata when - we are done using the strings from it. For now, it seems - to be allocated on an obstack anyway... */ - bfd_has_map (abfd) = true; - return true; -} - -/* Returns false on error, true otherwise */ -static boolean -do_slurp_coff_armap (abfd) - bfd *abfd; -{ - struct areltdata *mapdata; - int *raw_armap, *rawptr; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - unsigned int stringsize; - unsigned int parsed_size; - carsym *carsyms; - unsigned int nsymz; /* Number of symbols in armap. */ - bfd_vma (*swap) PARAMS ((const bfd_byte *)); - char int_buf[sizeof (long)]; - unsigned int carsym_size, ptrsize, i; - - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == NULL) - return false; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, (PTR) mapdata); /* Don't need it any more. */ - - if (bfd_read ((PTR) int_buf, 1, 4, abfd) != 4) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - return false; - } - /* It seems that all numeric information in a coff archive is always - in big endian format, nomatter the host or target. */ - swap = bfd_getb32; - nsymz = bfd_getb32 ((PTR) int_buf); - stringsize = parsed_size - (4 * nsymz) - 4; - -#if 1 - /* ... except that some archive formats are broken, and it may be our - fault - the i960 little endian coff sometimes has big and sometimes - little, because our tools changed. Here's a horrible hack to clean - up the crap. */ - - if (stringsize > 0xfffff) - { - /* This looks dangerous, let's do it the other way around */ - nsymz = bfd_getl32 ((PTR) int_buf); - stringsize = parsed_size - (4 * nsymz) - 4; - swap = bfd_getl32; - } -#endif - - /* The coff armap must be read sequentially. So we construct a - bsd-style one in core all at once, for simplicity. */ - - carsym_size = (nsymz * sizeof (carsym)); - ptrsize = (4 * nsymz); - - ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1); - if (ardata->symdefs == NULL) - return false; - carsyms = ardata->symdefs; - stringbase = ((char *) ardata->symdefs) + carsym_size; - - /* Allocate and read in the raw offsets. */ - raw_armap = (int *) bfd_alloc (abfd, ptrsize); - if (raw_armap == NULL) - goto release_symdefs; - if (bfd_read ((PTR) raw_armap, 1, ptrsize, abfd) != ptrsize - || bfd_read ((PTR) stringbase, 1, stringsize, abfd) != stringsize) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - goto release_raw_armap; - } - - /* OK, build the carsyms */ - for (i = 0; i < nsymz; i++) - { - rawptr = raw_armap + i; - carsyms->file_offset = swap ((PTR) rawptr); - carsyms->name = stringbase; - stringbase += strlen (stringbase) + 1; - carsyms++; - } - *stringbase = 0; - - ardata->symdef_count = nsymz; - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - - - bfd_has_map (abfd) = true; - bfd_release (abfd, (PTR) raw_armap); - - - /* Check for a second archive header (as used by PE) */ - { - struct areltdata *tmp; - - bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET); - tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (tmp != NULL) - { - if (tmp->arch_header[0] == '/' - && tmp->arch_header[1] == ' ') - { - ardata->first_file_filepos += - (tmp->parsed_size + sizeof(struct ar_hdr) + 1) & ~1; - } - bfd_release (abfd, tmp); - } - } - - return true; - -release_raw_armap: - bfd_release (abfd, (PTR) raw_armap); -release_symdefs: - bfd_release (abfd, (PTR) (ardata)->symdefs); - return false; -} - -/* This routine can handle either coff-style or bsd-style armaps. - Returns false on error, true otherwise */ - -boolean -bfd_slurp_armap (abfd) - bfd *abfd; -{ - char nextname[17]; - int i = bfd_read ((PTR) nextname, 1, 16, abfd); - - if (i == 0) - return true; - if (i != 16) - return false; - - if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) - return false; - - if (!strncmp (nextname, "__.SYMDEF ", 16) - || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */ - return do_slurp_bsd_armap (abfd); - else if (!strncmp (nextname, "/ ", 16)) - return do_slurp_coff_armap (abfd); - - bfd_has_map (abfd) = false; - return true; -} - -/* Returns false on error, true otherwise */ -/* flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the - header is in a slightly different order and the map name is '/'. - This flavour is used by hp300hpux. */ - -#define HPUX_SYMDEF_COUNT_SIZE 2 - -boolean -bfd_slurp_bsd_armap_f2 (abfd) - bfd *abfd; -{ - struct areltdata *mapdata; - char nextname[17]; - unsigned int counter; - bfd_byte *raw_armap, *rbase; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - unsigned int stringsize; - carsym *set; - int i = bfd_read ((PTR) nextname, 1, 16, abfd); - - if (i == 0) - return true; - if (i != 16) - return false; - - /* The archive has at least 16 bytes in it */ - if (bfd_seek (abfd, -16L, SEEK_CUR) != 0) - return false; - - if (!strncmp (nextname, "__.SYMDEF ", 16) - || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */ - return do_slurp_bsd_armap (abfd); - - if (strncmp (nextname, "/ ", 16)) - { - bfd_has_map (abfd) = false; - return true; - } - - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == NULL) - return false; - - raw_armap = (bfd_byte *) bfd_zalloc (abfd, mapdata->parsed_size); - if (raw_armap == NULL) - { - byebye: - bfd_release (abfd, (PTR) mapdata); - return false; - } - - if (bfd_read ((PTR) raw_armap, 1, mapdata->parsed_size, abfd) != - mapdata->parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - byebyebye: - bfd_release (abfd, (PTR) raw_armap); - goto byebye; - } - - ardata->symdef_count = bfd_h_get_16 (abfd, (PTR) raw_armap); - - if (ardata->symdef_count * BSD_SYMDEF_SIZE - > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE) - { - /* Probably we're using the wrong byte ordering. */ - bfd_set_error (bfd_error_wrong_format); - goto byebyebye; - } - - ardata->cache = 0; - - stringsize = bfd_h_get_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE); - /* skip sym count and string sz */ - stringbase = ((char *) raw_armap - + HPUX_SYMDEF_COUNT_SIZE - + BSD_STRING_COUNT_SIZE); - rbase = (bfd_byte *) stringbase + stringsize; - ardata->symdefs = (carsym *) bfd_alloc (abfd, - (ardata->symdef_count - * BSD_SYMDEF_SIZE)); - if (!ardata->symdefs) - return false; - - for (counter = 0, set = ardata->symdefs; - counter < ardata->symdef_count; - counter++, set++, rbase += BSD_SYMDEF_SIZE) - { - set->name = bfd_h_get_32 (abfd, rbase) + stringbase; - set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - /* FIXME, we should provide some way to free raw_ardata when - we are done using the strings from it. For now, it seems - to be allocated on an obstack anyway... */ - bfd_has_map (abfd) = true; - return true; -} - -/** Extended name table. - - Normally archives support only 14-character filenames. - - Intel has extended the format: longer names are stored in a special - element (the first in the archive, or second if there is an armap); - the name in the ar_hdr is replaced by . Index is the P.R. of an int (decimal). Data General have - extended the format by using the prefix // for the special element */ - -/* Returns false on error, true otherwise */ -boolean -_bfd_slurp_extended_name_table (abfd) - bfd *abfd; -{ - char nextname[17]; - struct areltdata *namedata; - - /* FIXME: Formatting sucks here, and in case of failure of BFD_READ, - we probably don't want to return true. */ - bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET); - if (bfd_read ((PTR) nextname, 1, 16, abfd) == 16) - { - if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) - return false; - - if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 && - strncmp (nextname, "// ", 16) != 0) - { - bfd_ardata (abfd)->extended_names = NULL; - return true; - } - - namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (namedata == NULL) - return false; - - bfd_ardata (abfd)->extended_names = - bfd_zalloc (abfd, namedata->parsed_size); - if (bfd_ardata (abfd)->extended_names == NULL) - { - byebye: - bfd_release (abfd, (PTR) namedata); - return false; - } - - if (bfd_read ((PTR) bfd_ardata (abfd)->extended_names, 1, - namedata->parsed_size, abfd) != namedata->parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - bfd_release (abfd, (PTR) (bfd_ardata (abfd)->extended_names)); - bfd_ardata (abfd)->extended_names = NULL; - goto byebye; - } - - /* Since the archive is supposed to be printable if it contains - text, the entries in the list are newline-padded, not null - padded. In SVR4-style archives, the names also have a - trailing '/'. DOS/NT created archive often have \ in them - We'll fix all problems here.. */ - { - char *temp = bfd_ardata (abfd)->extended_names; - char *limit = temp + namedata->parsed_size; - for (; temp < limit; ++temp) { - if (*temp == '\012') - temp[temp[-1] == '/' ? -1 : 0] = '\0'; - if (*temp == '\\') - *temp = '/'; - } - } - - /* Pad to an even boundary if you have to */ - bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd); - bfd_ardata (abfd)->first_file_filepos += - (bfd_ardata (abfd)->first_file_filepos) % 2; - - /* FIXME, we can't release namedata here because it was allocated - below extended_names on the obstack... */ - /* bfd_release (abfd, namedata); */ - } - return true; -} - -#ifdef VMS - -/* Return a copy of the stuff in the filename between any :]> and a - semicolon */ -static const char * -normalize (abfd, file) - bfd *abfd; - const char *file; -{ - CONST char *first; - CONST char *last; - char *copy; - - first = file + strlen (file) - 1; - last = first + 1; - - while (first != file) - { - if (*first == ';') - last = first; - if (*first == ':' || *first == ']' || *first == '>') - { - first++; - break; - } - first--; - } - - copy = (char *) bfd_alloc (abfd, last - first + 1); - if (copy == NULL) - return NULL; - - memcpy (copy, first, last - first); - copy[last - first] = 0; - - return copy; -} - -#else -static const char * -normalize (abfd, file) - bfd *abfd; - const char *file; -{ - const char *filename = strrchr (file, '/'); - - if (filename != (char *) NULL) - filename++; - else - filename = file; - return filename; -} -#endif - -/* Build a BFD style extended name table. */ - -boolean -_bfd_archive_bsd_construct_extended_name_table (abfd, tabloc, tablen, name) - bfd *abfd; - char **tabloc; - bfd_size_type *tablen; - const char **name; -{ - *name = "ARFILENAMES/"; - return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen); -} - -/* Build an SVR4 style extended name table. */ - -boolean -_bfd_archive_coff_construct_extended_name_table (abfd, tabloc, tablen, name) - bfd *abfd; - char **tabloc; - bfd_size_type *tablen; - const char **name; -{ - *name = "//"; - return _bfd_construct_extended_name_table (abfd, true, tabloc, tablen); -} - -/* Follows archive_head and produces an extended name table if - necessary. Returns (in tabloc) a pointer to an extended name - table, and in tablen the length of the table. If it makes an entry - it clobbers the filename so that the element may be written without - further massage. Returns true if it ran successfully, false if - something went wrong. A successful return may still involve a - zero-length tablen! */ - -boolean -_bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen) - bfd *abfd; - boolean trailing_slash; - char **tabloc; - bfd_size_type *tablen; -{ - unsigned int maxname = abfd->xvec->ar_max_namelen; - unsigned int total_namelen = 0; - bfd *current; - char *strptr; - - *tablen = 0; - - /* Figure out how long the table should be */ - for (current = abfd->archive_head; current != NULL; current = current->next) - { - const char *normal; - unsigned int thislen; - - normal = normalize (current, current->filename); - if (normal == NULL) - return false; - - thislen = strlen (normal); - - if (thislen > maxname - && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0) - thislen = maxname; - - if (thislen > maxname) - { - /* Add one to leave room for \n. */ - total_namelen += thislen + 1; - if (trailing_slash) - { - /* Leave room for trailing slash. */ - ++total_namelen; - } - } - else - { - struct ar_hdr *hdr = arch_hdr (current); - if (strncmp (normal, hdr->ar_name, thislen) != 0 - || (thislen < sizeof hdr->ar_name - && hdr->ar_name[thislen] != ar_padchar (current))) - { - /* Must have been using extended format even though it - didn't need to. Fix it to use normal format. */ - memcpy (hdr->ar_name, normal, thislen); - if (thislen < maxname - || (thislen == maxname && thislen < sizeof hdr->ar_name)) - hdr->ar_name[thislen] = ar_padchar (current); - } - } - } - - if (total_namelen == 0) - return true; - - *tabloc = bfd_zalloc (abfd, total_namelen); - if (*tabloc == NULL) - return false; - - *tablen = total_namelen; - strptr = *tabloc; - - for (current = abfd->archive_head; current != NULL; current = - current->next) - { - const char *normal; - unsigned int thislen; - - normal = normalize (current, current->filename); - if (normal == NULL) - return false; - - thislen = strlen (normal); - if (thislen > maxname) - { - /* Works for now; may need to be re-engineered if we - encounter an oddball archive format and want to - generalise this hack. */ - struct ar_hdr *hdr = arch_hdr (current); - strcpy (strptr, normal); - if (! trailing_slash) - strptr[thislen] = '\012'; - else - { - strptr[thislen] = '/'; - strptr[thislen + 1] = '\012'; - } - hdr->ar_name[0] = ar_padchar (current); - /* We know there will always be enough room (one of the few - cases where you may safely use sprintf). */ - sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc)); - /* Kinda Kludgy. We should just use the returned value of - sprintf but not all implementations get this right */ - { - char *temp = hdr->ar_name + 2; - for (; temp < hdr->ar_name + maxname; temp++) - if (*temp == '\0') - *temp = ' '; - } - strptr += thislen + 1; - if (trailing_slash) - ++strptr; - } - } - - return true; -} - -/** A couple of functions for creating ar_hdrs */ - -/* Takes a filename, returns an arelt_data for it, or NULL if it can't - make one. The filename must refer to a filename in the filesystem. - The filename field of the ar_hdr will NOT be initialized */ - -static struct areltdata * -bfd_ar_hdr_from_filesystem (abfd, filename) - bfd *abfd; - const char *filename; -{ - struct stat status; - struct areltdata *ared; - struct ar_hdr *hdr; - char *temp, *temp1; - - if (stat (filename, &status) != 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - ared = (struct areltdata *) bfd_zalloc (abfd, sizeof (struct ar_hdr) + - sizeof (struct areltdata)); - if (ared == NULL) - return NULL; - hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata)); - - /* ar headers are space padded, not null padded! */ - memset ((PTR) hdr, ' ', sizeof (struct ar_hdr)); - - strncpy (hdr->ar_fmag, ARFMAG, 2); - - /* Goddamned sprintf doesn't permit MAXIMUM field lengths */ - sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime); - sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid); - sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid); - sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode); - sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size); - /* Correct for a lossage in sprintf whereby it null-terminates. I cannot - understand how these C losers could design such a ramshackle bunch of - IO operations */ - temp = (char *) hdr; - temp1 = temp + sizeof (struct ar_hdr) - 2; - for (; temp < temp1; temp++) - { - if (*temp == '\0') - *temp = ' '; - } - strncpy (hdr->ar_fmag, ARFMAG, 2); - ared->parsed_size = status.st_size; - ared->arch_header = (char *) hdr; - - return ared; -} - -/* This is magic required by the "ar" program. Since it's - undocumented, it's undocumented. You may think that it would take - a strong stomach to write this, and it does, but it takes even a - stronger stomach to try to code around such a thing! */ - -struct ar_hdr * -bfd_special_undocumented_glue (abfd, filename) - bfd *abfd; - char *filename; -{ - struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename); - if (ar_elt == NULL) - return NULL; - return (struct ar_hdr *) ar_elt->arch_header; -} - - -/* Analogous to stat call */ -int -bfd_generic_stat_arch_elt (abfd, buf) - bfd *abfd; - struct stat *buf; -{ - struct ar_hdr *hdr; - char *aloser; - - if (abfd->arelt_data == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - hdr = arch_hdr (abfd); - -#define foo(arelt, stelt, size) \ - buf->stelt = strtol (hdr->arelt, &aloser, size); \ - if (aloser == hdr->arelt) return -1; - - foo (ar_date, st_mtime, 10); - foo (ar_uid, st_uid, 10); - foo (ar_gid, st_gid, 10); - foo (ar_mode, st_mode, 8); - - buf->st_size = arch_eltdata (abfd)->parsed_size; - - return 0; -} - -void -bfd_dont_truncate_arname (abfd, pathname, arhdr) - bfd *abfd; - CONST char *pathname; - char *arhdr; -{ - /* FIXME: This interacts unpleasantly with ar's quick-append option. - Fortunately ic960 users will never use that option. Fixing this - is very hard; fortunately I know how to do it and will do so once - intel's release is out the door. */ - - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - size_t length; - const char *filename; - size_t maxlen = ar_maxnamelen (abfd); - - if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0) - { - bfd_bsd_truncate_arname (abfd, pathname, arhdr); - return; - } - - filename = normalize (abfd, pathname); - if (filename == NULL) - { - /* FIXME */ - abort (); - } - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - - /* Add the padding character if there is room for it. */ - if (length < maxlen - || (length == maxlen && length < sizeof hdr->ar_name)) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -void -bfd_bsd_truncate_arname (abfd, pathname, arhdr) - bfd *abfd; - CONST char *pathname; - char *arhdr; -{ - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - int length; - CONST char *filename = strrchr (pathname, '/'); - int maxlen = ar_maxnamelen (abfd); - - if (filename == NULL) - filename = pathname; - else - ++filename; - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - else - { - /* pathname: meet procrustes */ - memcpy (hdr->ar_name, filename, maxlen); - length = maxlen; - } - - if (length < maxlen) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -/* Store name into ar header. Truncates the name to fit. - 1> strip pathname to be just the basename. - 2> if it's short enuf to fit, stuff it in. - 3> If it doesn't end with .o, truncate it to fit - 4> truncate it before the .o, append .o, stuff THAT in. */ - -/* This is what gnu ar does. It's better but incompatible with the - bsd ar. */ - -void -bfd_gnu_truncate_arname (abfd, pathname, arhdr) - bfd *abfd; - CONST char *pathname; - char *arhdr; -{ - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - int length; - CONST char *filename = strrchr (pathname, '/'); - int maxlen = ar_maxnamelen (abfd); - - if (filename == NULL) - filename = pathname; - else - ++filename; - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - else - { /* pathname: meet procrustes */ - memcpy (hdr->ar_name, filename, maxlen); - if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) - { - hdr->ar_name[maxlen - 2] = '.'; - hdr->ar_name[maxlen - 1] = 'o'; - } - length = maxlen; - } - - if (length < 16) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -/* The BFD is open for write and has its format set to bfd_archive */ - -boolean -_bfd_write_archive_contents (arch) - bfd *arch; -{ - bfd *current; - char *etable = NULL; - bfd_size_type elength = 0; - const char *ename = NULL; - boolean makemap = bfd_has_map (arch); - boolean hasobjects = false; /* if no .o's, don't bother to make a map */ - bfd_size_type wrote; - unsigned int i; - int tries; - - /* Verify the viability of all entries; if any of them live in the - filesystem (as opposed to living in an archive open for input) - then construct a fresh ar_hdr for them. */ - for (current = arch->archive_head; current; current = current->next) - { - if (bfd_write_p (current)) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - if (!current->arelt_data) - { - current->arelt_data = - (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename); - if (!current->arelt_data) - return false; - - /* Put in the file name */ - BFD_SEND (arch, _bfd_truncate_arname, (arch, - current->filename, - (char *) arch_hdr (current))); - } - - if (makemap && ! hasobjects) - { /* don't bother if we won't make a map! */ - if ((bfd_check_format (current, bfd_object)) -#if 0 /* FIXME -- these are not set correctly */ - && ((bfd_get_file_flags (current) & HAS_SYMS)) -#endif - ) - hasobjects = true; - } - } - - if (!BFD_SEND (arch, _bfd_construct_extended_name_table, - (arch, &etable, &elength, &ename))) - return false; - - if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0) - return false; -#ifdef GNU960 - wrote = bfd_write (BFD_GNU960_ARMAG (arch), 1, SARMAG, arch); -#else - wrote = bfd_write (ARMAG, 1, SARMAG, arch); -#endif - if (wrote != SARMAG) - return false; - - if (makemap && hasobjects) - { - if (_bfd_compute_and_write_armap (arch, elength) != true) - return false; - } - - if (elength != 0) - { - struct ar_hdr hdr; - - memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); - strcpy (hdr.ar_name, ename); - /* Round size up to even number in archive header. */ - sprintf (&(hdr.ar_size[0]), "%-10d", - (int) ((elength + 1) & ~1)); - strncpy (hdr.ar_fmag, ARFMAG, 2); - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - if ((bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - || bfd_write (etable, 1, elength, arch) != elength) - return false; - if ((elength % 2) == 1) - { - if (bfd_write ("\012", 1, 1, arch) != 1) - return false; - } - } - - for (current = arch->archive_head; current; current = current->next) - { - char buffer[DEFAULT_BUFFERSIZE]; - unsigned int remaining = arelt_size (current); - struct ar_hdr *hdr = arch_hdr (current); - - /* write ar header */ - if (bfd_write ((char *) hdr, 1, sizeof (*hdr), arch) != sizeof (*hdr)) - return false; - if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0) - return false; - while (remaining) - { - unsigned int amt = DEFAULT_BUFFERSIZE; - if (amt > remaining) - amt = remaining; - errno = 0; - if (bfd_read (buffer, amt, 1, current) != amt) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - return false; - } - if (bfd_write (buffer, amt, 1, arch) != amt) - return false; - remaining -= amt; - } - if ((arelt_size (current) % 2) == 1) - { - if (bfd_write ("\012", 1, 1, arch) != 1) - return false; - } - } - - if (makemap && hasobjects) - { - /* Verify the timestamp in the archive file. If it would not be - accepted by the linker, rewrite it until it would be. If - anything odd happens, break out and just return. (The - Berkeley linker checks the timestamp and refuses to read the - table-of-contents if it is >60 seconds less than the file's - modified-time. That painful hack requires this painful hack. */ - tries = 1; - do - { - if (bfd_update_armap_timestamp (arch)) - break; - (*_bfd_error_handler) - ("Warning: writing archive was slow: rewriting timestamp\n"); - } - while (++tries < 6); - } - - return true; -} - -/* Note that the namidx for the first symbol is 0 */ - -boolean -_bfd_compute_and_write_armap (arch, elength) - bfd *arch; - unsigned int elength; -{ - char *first_name = NULL; - bfd *current; - file_ptr elt_no = 0; - struct orl *map = NULL; - int orl_max = 1024; /* fine initial default */ - int orl_count = 0; - int stridx = 0; /* string index */ - asymbol **syms = NULL; - long syms_max = 0; - boolean ret; - - /* Dunno if this is the best place for this info... */ - if (elength != 0) - elength += sizeof (struct ar_hdr); - elength += elength % 2; - - map = (struct orl *) bfd_malloc (orl_max * sizeof (struct orl)); - if (map == NULL) - goto error_return; - - /* We put the symbol names on the arch obstack, and then discard - them when done. */ - first_name = bfd_alloc (arch, 1); - if (first_name == NULL) - goto error_return; - - /* Drop all the files called __.SYMDEF, we're going to make our - own */ - while (arch->archive_head && - strcmp (arch->archive_head->filename, "__.SYMDEF") == 0) - arch->archive_head = arch->archive_head->next; - - /* Map over each element */ - for (current = arch->archive_head; - current != (bfd *) NULL; - current = current->next, elt_no++) - { - if ((bfd_check_format (current, bfd_object) == true) - && ((bfd_get_file_flags (current) & HAS_SYMS))) - { - long storage; - long symcount; - long src_count; - - storage = bfd_get_symtab_upper_bound (current); - if (storage < 0) - goto error_return; - - if (storage != 0) - { - if (storage > syms_max) - { - if (syms_max > 0) - free (syms); - syms_max = storage; - syms = (asymbol **) bfd_malloc ((size_t) syms_max); - if (syms == NULL) - goto error_return; - } - symcount = bfd_canonicalize_symtab (current, syms); - if (symcount < 0) - goto error_return; - - /* Now map over all the symbols, picking out the ones we want */ - for (src_count = 0; src_count < symcount; src_count++) - { - flagword flags = (syms[src_count])->flags; - asection *sec = syms[src_count]->section; - - if ((flags & BSF_GLOBAL || - flags & BSF_WEAK || - flags & BSF_INDIRECT || - bfd_is_com_section (sec)) - && ! bfd_is_und_section (sec)) - { - size_t namelen; - struct orl *new_map; - - /* This symbol will go into the archive header */ - if (orl_count == orl_max) - { - orl_max *= 2; - new_map = - ((struct orl *) - bfd_realloc (map, orl_max * sizeof (struct orl))); - if (new_map == (struct orl *) NULL) - goto error_return; - - map = new_map; - } - - namelen = strlen (syms[src_count]->name); - map[orl_count].name = ((char **) - bfd_alloc (arch, - sizeof (char *))); - if (map[orl_count].name == NULL) - goto error_return; - *(map[orl_count].name) = bfd_alloc (arch, namelen + 1); - if (*(map[orl_count].name) == NULL) - goto error_return; - strcpy (*(map[orl_count].name), syms[src_count]->name); - (map[orl_count]).pos = (file_ptr) current; - (map[orl_count]).namidx = stridx; - - stridx += namelen + 1; - ++orl_count; - } - } - } - - /* Now ask the BFD to free up any cached information, so we - don't fill all of memory with symbol tables. */ - if (! bfd_free_cached_info (current)) - goto error_return; - } - } - - /* OK, now we have collected all the data, let's write them out */ - ret = BFD_SEND (arch, write_armap, - (arch, elength, map, orl_count, stridx)); - - if (syms_max > 0) - free (syms); - if (map != NULL) - free (map); - if (first_name != NULL) - bfd_release (arch, first_name); - - return ret; - - error_return: - if (syms_max > 0) - free (syms); - if (map != NULL) - free (map); - if (first_name != NULL) - bfd_release (arch, first_name); - - return false; -} - -boolean -bsd_write_armap (arch, elength, map, orl_count, stridx) - bfd *arch; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - int padit = stridx & 1; - unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE; - unsigned int stringsize = stridx + padit; - /* Include 8 bytes to store ranlibsize and stringsize in output. */ - unsigned int mapsize = ranlibsize + stringsize + 8; - file_ptr firstreal; - bfd *current = arch->archive_head; - bfd *last_elt = current; /* last element arch seen */ - bfd_byte temp[4]; - unsigned int count; - struct ar_hdr hdr; - struct stat statbuf; - unsigned int i; - - firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG; - - stat (arch->filename, &statbuf); - memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); - sprintf (hdr.ar_name, RANLIBMAG); - /* Remember the timestamp, to keep it holy. But fudge it a little. */ - bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET; - bfd_ardata (arch)->armap_datepos = (SARMAG - + offsetof (struct ar_hdr, ar_date[0])); - sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); - sprintf (hdr.ar_uid, "%ld", (long) getuid ()); - sprintf (hdr.ar_gid, "%ld", (long) getgid ()); - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - strncpy (hdr.ar_fmag, ARFMAG, 2); - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - if (bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - return false; - bfd_h_put_32 (arch, (bfd_vma) ranlibsize, temp); - if (bfd_write (temp, 1, sizeof (temp), arch) != sizeof (temp)) - return false; - - for (count = 0; count < orl_count; count++) - { - bfd_byte buf[BSD_SYMDEF_SIZE]; - - if (((bfd *) (map[count]).pos) != last_elt) - { - do - { - firstreal += arelt_size (current) + sizeof (struct ar_hdr); - firstreal += firstreal % 2; - current = current->next; - } - while (current != (bfd *) (map[count]).pos); - } /* if new archive element */ - - last_elt = current; - bfd_h_put_32 (arch, map[count].namidx, buf); - bfd_h_put_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE); - if (bfd_write (buf, BSD_SYMDEF_SIZE, 1, arch) != BSD_SYMDEF_SIZE) - return false; - } - - /* now write the strings themselves */ - bfd_h_put_32 (arch, stringsize, temp); - if (bfd_write (temp, 1, sizeof (temp), arch) != sizeof (temp)) - return false; - for (count = 0; count < orl_count; count++) - { - size_t len = strlen (*map[count].name) + 1; - - if (bfd_write (*map[count].name, 1, len, arch) != len) - return false; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for sun's ar we use a null. */ - if (padit) - { - if (bfd_write ("", 1, 1, arch) != 1) - return false; - } - - return true; -} - -/* At the end of archive file handling, update the timestamp in the - file, so the linker will accept it. - - Return true if the timestamp was OK, or an unusual problem happened. - Return false if we updated the timestamp. */ - -boolean -_bfd_archive_bsd_update_armap_timestamp (arch) - bfd *arch; -{ - struct stat archstat; - struct ar_hdr hdr; - unsigned int i; - - /* Flush writes, get last-write timestamp from file, and compare it - to the timestamp IN the file. */ - bfd_flush (arch); - if (bfd_stat (arch, &archstat) == -1) - { - perror ("Reading archive file mod timestamp"); - return true; /* Can't read mod time for some reason */ - } - if (archstat.st_mtime <= bfd_ardata (arch)->armap_timestamp) - return true; /* OK by the linker's rules */ - - /* Update the timestamp. */ - bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET; - - /* Prepare an ASCII version suitable for writing. */ - memset (hdr.ar_date, 0, sizeof (hdr.ar_date)); - sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); - for (i = 0; i < sizeof (hdr.ar_date); i++) - if (hdr.ar_date[i] == '\0') - (hdr.ar_date)[i] = ' '; - - /* Write it into the file. */ - bfd_ardata (arch)->armap_datepos = (SARMAG - + offsetof (struct ar_hdr, ar_date[0])); - if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0 - || (bfd_write (hdr.ar_date, sizeof (hdr.ar_date), 1, arch) - != sizeof (hdr.ar_date))) - { - /* FIXME: bfd can't call perror. */ - perror ("Writing updated armap timestamp"); - return true; /* Some error while writing */ - } - - return false; /* We updated the timestamp successfully. */ -} - -/* A coff armap looks like : - lARMAG - struct ar_hdr with name = '/' - number of symbols - offset of file for symbol 0 - offset of file for symbol 1 - - offset of file for symbol n-1 - symbol name 0 - symbol name 1 - - symbol name n-1 -*/ - -boolean -coff_write_armap (arch, elength, map, symbol_count, stridx) - bfd *arch; - unsigned int elength; - struct orl *map; - unsigned int symbol_count; - int stridx; -{ - /* The size of the ranlib is the number of exported symbols in the - archive * the number of bytes in a int, + an int for the count */ - unsigned int ranlibsize = (symbol_count * 4) + 4; - unsigned int stringsize = stridx; - unsigned int mapsize = stringsize + ranlibsize; - file_ptr archive_member_file_ptr; - bfd *current = arch->archive_head; - unsigned int count; - struct ar_hdr hdr; - unsigned int i; - int padit = mapsize & 1; - - if (padit) - mapsize++; - - /* work out where the first object file will go in the archive */ - archive_member_file_ptr = (mapsize - + elength - + sizeof (struct ar_hdr) - + SARMAG); - - memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); - hdr.ar_name[0] = '/'; - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - sprintf (hdr.ar_date, "%ld", (long) time (NULL)); - /* This, at least, is what Intel coff sets the values to.: */ - sprintf ((hdr.ar_uid), "%d", 0); - sprintf ((hdr.ar_gid), "%d", 0); - sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); - strncpy (hdr.ar_fmag, ARFMAG, 2); - - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - - /* Write the ar header for this item and the number of symbols */ - - if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - return false; - - bfd_write_bigendian_4byte_int (arch, symbol_count); - - /* Two passes, first write the file offsets for each symbol - - remembering that each offset is on a two byte boundary. */ - - /* Write out the file offset for the file associated with each - symbol, and remember to keep the offsets padded out. */ - - current = arch->archive_head; - count = 0; - while (current != (bfd *) NULL && count < symbol_count) - { - /* For each symbol which is used defined in this object, write out - the object file's address in the archive */ - - while (((bfd *) (map[count]).pos) == current) - { - bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr); - count++; - } - /* Add size of this archive entry */ - archive_member_file_ptr += (arelt_size (current) - + sizeof (struct ar_hdr)); - /* remember aboout the even alignment */ - archive_member_file_ptr += archive_member_file_ptr % 2; - current = current->next; - } - - /* now write the strings themselves */ - for (count = 0; count < symbol_count; count++) - { - size_t len = strlen (*map[count].name) + 1; - - if (bfd_write (*map[count].name, 1, len, arch) != len) - return false; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for arc960 we use a null. */ - if (padit) - { - if (bfd_write ("", 1, 1, arch) != 1) - return false; - } - - return true; -} diff --git a/contrib/gdb/bfd/archures.c b/contrib/gdb/bfd/archures.c deleted file mode 100644 index 1db8bc24b86..00000000000 --- a/contrib/gdb/bfd/archures.c +++ /dev/null @@ -1,720 +0,0 @@ -/* BFD library support routines for architectures. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Hacked by John Gilmore and Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include - -/* - -SECTION - Architectures - - BFD keeps one atom in a BFD describing the - architecture of the data attached to the BFD: a pointer to a - <>. - - Pointers to structures can be requested independently of a BFD - so that an architecture's information can be interrogated - without access to an open BFD. - - The architecture information is provided by each architecture package. - The set of default architectures is selected by the macro - <>. This is normally set up in the - @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 - initialize method. It is up to the architecture back end to - insert as many items into the list of architectures as it wants to; - generally this would be one for each machine and one for the - default case (an item with a machine field of 0). - - BFD's idea of an architecture is implemented in @file{archures.c}. -*/ - -/* - -SUBSECTION - bfd_architecture - -DESCRIPTION - This enum gives the object file's CPU architecture, in a - global sense---i.e., what processor family does it belong to? - Another field indicates which processor within - the family is in use. The machine gives a number which - 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 -.{ -. bfd_arch_unknown, {* File arch not known *} -. bfd_arch_obscure, {* Arch known, not one of these *} -. bfd_arch_m68k, {* Motorola 68xxx *} -. bfd_arch_vax, {* DEC Vax *} -. bfd_arch_i960, {* Intel 960 *} -. {* The order of the following is important. -. lower number indicates a machine type that -. only accepts a subset of the instructions -. available to machines with higher numbers. -. The exception is the "ca", which is -. incompatible with all other machines except -. "core". *} -. -.#define bfd_mach_i960_core 1 -.#define bfd_mach_i960_ka_sa 2 -.#define bfd_mach_i960_kb_sb 3 -.#define bfd_mach_i960_mc 4 -.#define bfd_mach_i960_xa 5 -.#define bfd_mach_i960_ca 6 -.#define bfd_mach_i960_jx 7 -.#define bfd_mach_i960_hx 8 -. -. bfd_arch_a29k, {* AMD 29000 *} -. bfd_arch_sparc, {* SPARC *} -.#define bfd_mach_sparc 1 -.{* The difference between v8plus and v9 is that v9 is a true 64 bit env. *} -.#define bfd_mach_sparc_v8plus 2 -.#define bfd_mach_sparc_v8plusa 3 {* with ultrasparc add'ns *} -.#define bfd_mach_sparc_v9 4 -.#define bfd_mach_sparc_v9a 5 {* with ultrasparc add'ns *} -.{* Nonzero if MACH has the v9 instruction set. *} -.#define bfd_mach_sparc_v9_p(mach) ((mach) != bfd_mach_sparc) -. bfd_arch_mips, {* MIPS Rxxxx *} -. bfd_arch_i386, {* Intel 386 *} -. bfd_arch_we32k, {* AT&T WE32xxx *} -. bfd_arch_tahoe, {* CCI/Harris Tahoe *} -. bfd_arch_i860, {* Intel 860 *} -. bfd_arch_romp, {* IBM ROMP PC/RT *} -. bfd_arch_alliant, {* Alliant *} -. bfd_arch_convex, {* Convex *} -. bfd_arch_m88k, {* Motorola 88xxx *} -. bfd_arch_pyramid, {* Pyramid Technology *} -. bfd_arch_h8300, {* Hitachi H8/300 *} -.#define bfd_mach_h8300 1 -.#define bfd_mach_h8300h 2 -. bfd_arch_powerpc, {* PowerPC *} -. bfd_arch_rs6000, {* IBM RS/6000 *} -. bfd_arch_hppa, {* HP PA RISC *} -. bfd_arch_z8k, {* Zilog Z8000 *} -.#define bfd_mach_z8001 1 -.#define bfd_mach_z8002 2 -. bfd_arch_h8500, {* Hitachi H8/500 *} -. bfd_arch_sh, {* Hitachi SH *} -. bfd_arch_alpha, {* Dec Alpha *} -. bfd_arch_arm, {* Advanced Risc Machines ARM *} -. bfd_arch_ns32k, {* National Semiconductors ns32000 *} -. bfd_arch_w65, {* WDC 65816 *} -. bfd_arch_last -. }; - - -*/ - -/* - -SUBSECTION - bfd_arch_info - -DESCRIPTION - This structure contains information on architectures for use - within BFD. - -. -.typedef struct bfd_arch_info -.{ -. int bits_per_word; -. int bits_per_address; -. int bits_per_byte; -. enum bfd_architecture arch; -. unsigned long mach; -. const char *arch_name; -. const char *printable_name; -. unsigned int section_align_power; -. {* true if this is the default machine for the architecture *} -. boolean the_default; -. const struct bfd_arch_info * (*compatible) -. PARAMS ((const struct bfd_arch_info *a, -. const struct bfd_arch_info *b)); -. -. boolean (*scan) PARAMS ((const struct bfd_arch_info *, const char *)); -. -. const struct bfd_arch_info *next; -.} bfd_arch_info_type; -*/ - -extern const bfd_arch_info_type bfd_a29k_arch; -extern const bfd_arch_info_type bfd_alpha_arch; -extern const bfd_arch_info_type bfd_arm_arch; -extern const bfd_arch_info_type bfd_h8300_arch; -extern const bfd_arch_info_type bfd_h8500_arch; -extern const bfd_arch_info_type bfd_hppa_arch; -extern const bfd_arch_info_type bfd_i386_arch; -extern const bfd_arch_info_type bfd_i860_arch; -extern const bfd_arch_info_type bfd_i960_arch; -extern const bfd_arch_info_type bfd_m68k_arch; -extern const bfd_arch_info_type bfd_m88k_arch; -extern const bfd_arch_info_type bfd_mips_arch; -extern const bfd_arch_info_type bfd_powerpc_arch; -extern const bfd_arch_info_type bfd_rs6000_arch; -extern const bfd_arch_info_type bfd_sh_arch; -extern const bfd_arch_info_type bfd_sparc_arch; -extern const bfd_arch_info_type bfd_vax_arch; -extern const bfd_arch_info_type bfd_we32k_arch; -extern const bfd_arch_info_type bfd_z8k_arch; -extern const bfd_arch_info_type bfd_ns32k_arch; -extern const bfd_arch_info_type bfd_w65_arch; - -static const bfd_arch_info_type * const bfd_archures_list[] = -{ -#ifdef SELECT_ARCHITECTURES - SELECT_ARCHITECTURES, -#else - &bfd_a29k_arch, - &bfd_alpha_arch, - &bfd_arm_arch, - &bfd_h8300_arch, - &bfd_h8500_arch, - &bfd_hppa_arch, - &bfd_i386_arch, - &bfd_i860_arch, - &bfd_i960_arch, - &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, - &bfd_w65_arch, -#endif - 0 -}; - -/* -FUNCTION - bfd_printable_name - -SYNOPSIS - const char *bfd_printable_name(bfd *abfd); - -DESCRIPTION - Return a printable string representing the architecture and machine - from the pointer to the architecture info structure. - -*/ - -const char * -bfd_printable_name (abfd) - bfd *abfd; -{ - return abfd->arch_info->printable_name; -} - - - -/* -FUNCTION - bfd_scan_arch - -SYNOPSIS - const bfd_arch_info_type *bfd_scan_arch(const char *string); - -DESCRIPTION - Figure out if BFD supports any cpu which could be described with - the name @var{string}. Return a pointer to an <> - structure if a machine is found, otherwise NULL. - -*/ - -const bfd_arch_info_type * -bfd_scan_arch (string) - const char *string; -{ - const bfd_arch_info_type * const *app, *ap; - - /* Look through all the installed architectures */ - for (app = bfd_archures_list; *app != NULL; app++) - { - for (ap = *app; ap != NULL; ap = ap->next) - { - if (ap->scan (ap, string)) - return ap; - } - } - - return NULL; -} - - - -/* -FUNCTION - bfd_arch_get_compatible - -SYNOPSIS - const bfd_arch_info_type *bfd_arch_get_compatible( - const bfd *abfd, - const bfd *bbfd); - -DESCRIPTION - 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 <> structure describing the compatible machine. -*/ - -const bfd_arch_info_type * -bfd_arch_get_compatible (abfd, bbfd) - const bfd *abfd; - const bfd *bbfd; -{ - /* If either architecture is unknown, then all we can do is assume - the user knows what he's doing. */ - if (abfd->arch_info->arch == bfd_arch_unknown) - return bbfd->arch_info; - if (bbfd->arch_info->arch == bfd_arch_unknown) - return abfd->arch_info; - - /* Otherwise architecture-specific code has to decide. */ - return abfd->arch_info->compatible (abfd->arch_info, bbfd->arch_info); -} - - -/* -INTERNAL_DEFINITION - bfd_default_arch_struct - -DESCRIPTION - The <> is an item of - <> which has been initialized to a fairly - generic state. A BFD starts life by pointing to this - structure, until the correct back end has determined the real - architecture of the file. - -.extern const bfd_arch_info_type bfd_default_arch_struct; - -*/ - -const bfd_arch_info_type bfd_default_arch_struct = -{ - 32,32,8,bfd_arch_unknown,0,"unknown","unknown",2,true, - bfd_default_compatible, - bfd_default_scan, - 0, -}; - -/* -FUNCTION - bfd_set_arch_info - -SYNOPSIS - void bfd_set_arch_info(bfd *abfd, const bfd_arch_info_type *arg); - -DESCRIPTION - Set the architecture info of @var{abfd} to @var{arg}. -*/ - -void -bfd_set_arch_info (abfd, arg) - bfd *abfd; - const bfd_arch_info_type *arg; -{ - abfd->arch_info = arg; -} - -/* -INTERNAL_FUNCTION - bfd_default_set_arch_mach - -SYNOPSIS - boolean bfd_default_set_arch_mach(bfd *abfd, - enum bfd_architecture arch, - unsigned long mach); - -DESCRIPTION - Set the architecture and machine type in BFD @var{abfd} - to @var{arch} and @var{mach}. Find the correct - pointer to a structure and insert it into the <> - pointer. -*/ - -boolean -bfd_default_set_arch_mach (abfd, arch, mach) - bfd *abfd; - enum bfd_architecture arch; - unsigned long mach; -{ - const bfd_arch_info_type * const *app, *ap; - - for (app = bfd_archures_list; *app != NULL; app++) - { - for (ap = *app; ap != NULL; ap = ap->next) - { - if (ap->arch == arch - && (ap->mach == mach - || (mach == 0 && ap->the_default))) - { - abfd->arch_info = ap; - return true; - } - } - } - - abfd->arch_info = &bfd_default_arch_struct; - bfd_set_error (bfd_error_bad_value); - return false; -} - - -/* -FUNCTION - bfd_get_arch - -SYNOPSIS - enum bfd_architecture bfd_get_arch(bfd *abfd); - -DESCRIPTION - Return the enumerated type which describes the BFD @var{abfd}'s - architecture. - -*/ - -enum bfd_architecture -bfd_get_arch (abfd) - bfd *abfd; -{ - return abfd->arch_info->arch; -} - -/* -FUNCTION - bfd_get_mach - -SYNOPSIS - unsigned long bfd_get_mach(bfd *abfd); - -DESCRIPTION - Return the long type which describes the BFD @var{abfd}'s - machine. -*/ - -unsigned long -bfd_get_mach (abfd) - bfd *abfd; -{ - return abfd->arch_info->mach; -} - -/* -FUNCTION - bfd_arch_bits_per_byte - -SYNOPSIS - unsigned int bfd_arch_bits_per_byte(bfd *abfd); - -DESCRIPTION - Return the number of bits in one of the BFD @var{abfd}'s - architecture's bytes. - -*/ - -unsigned int -bfd_arch_bits_per_byte (abfd) - bfd *abfd; -{ - return abfd->arch_info->bits_per_byte; -} - -/* -FUNCTION - bfd_arch_bits_per_address - -SYNOPSIS - unsigned int bfd_arch_bits_per_address(bfd *abfd); - -DESCRIPTION - Return the number of bits in one of the BFD @var{abfd}'s - architecture's addresses. -*/ - -unsigned int -bfd_arch_bits_per_address (abfd) - bfd *abfd; -{ - return abfd->arch_info->bits_per_address; -} - - -/* -INTERNAL_FUNCTION - bfd_default_compatible - -SYNOPSIS - const bfd_arch_info_type *bfd_default_compatible - (const bfd_arch_info_type *a, - const bfd_arch_info_type *b); - -DESCRIPTION - The default function for testing for compatibility. -*/ - -const bfd_arch_info_type * -bfd_default_compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->arch != b->arch) - return NULL; - - if (a->mach > b->mach) - return a; - - if (b->mach > a->mach) - return b; - - return a; -} - - -/* -INTERNAL_FUNCTION - bfd_default_scan - -SYNOPSIS - boolean bfd_default_scan(const struct bfd_arch_info *info, const char *string); - -DESCRIPTION - The default function for working out whether this is an - architecture hit and a machine hit. -*/ - -boolean -bfd_default_scan (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - const char *ptr_src; - const char *ptr_tst; - unsigned long number; - enum bfd_architecture arch; - - /* First test for an exact match */ - if (strcmp (string, info->printable_name) == 0) - return true; - - /* See how much of the supplied string matches with the - architecture, eg the string m68k:68020 would match the 68k entry - up to the :, then we get left with the machine number */ - - for (ptr_src = string, ptr_tst = info->arch_name; - *ptr_src && *ptr_tst; - ptr_src++, ptr_tst++) - { - if (*ptr_src != *ptr_tst) break; - } - - /* Chewed up as much of the architecture as will match, skip any - colons */ - if (*ptr_src == ':') - ptr_src++; - - if (*ptr_src == 0) - { - /* nothing more, then only keep this one if it is the default - machine for this architecture */ - return info->the_default; - } - - number = 0; - while (isdigit(*ptr_src)) - { - number = number * 10 + *ptr_src - '0'; - ptr_src++; - } - - switch (number) - { - case 65: - arch = bfd_arch_w65; - break; - - case 300: - arch = bfd_arch_h8300; - break; - - case 500: - arch = bfd_arch_h8500; - break; - - case 68010: - case 68020: - case 68030: - case 68040: - case 68332: - case 68050: - case 68000: - arch = bfd_arch_m68k; - break; - - case 386: - case 80386: - case 486: - case 80486: - arch = bfd_arch_i386; - break; - - case 29000: - arch = bfd_arch_a29k; - break; - - case 8000: - arch = bfd_arch_z8k; - break; - - case 32000: - arch = bfd_arch_we32k; - break; - - case 860: - case 80860: - arch = bfd_arch_i860; - break; - case 960: - case 80960: - arch = bfd_arch_i960; - break; - - case 2000: - case 3000: - case 4000: - case 4400: - arch = bfd_arch_mips; - break; - - case 6000: - arch = bfd_arch_rs6000; - break; - - default: - return false; - } - - if (arch != info->arch) - return false; - - if (number != info->mach) - return false; - - return true; -} - - -/* -FUNCTION - bfd_get_arch_info - -SYNOPSIS - const bfd_arch_info_type * bfd_get_arch_info(bfd *abfd); - -DESCRIPTION - Return the architecture info struct in @var{abfd}. -*/ - -const bfd_arch_info_type * -bfd_get_arch_info (abfd) - bfd *abfd; -{ - return abfd->arch_info; -} - - -/* -FUNCTION - bfd_lookup_arch - -SYNOPSIS - const bfd_arch_info_type *bfd_lookup_arch - (enum bfd_architecture - arch, - unsigned long machine); - -DESCRIPTION - 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. -*/ - -const bfd_arch_info_type * -bfd_lookup_arch (arch, machine) - enum bfd_architecture arch; - unsigned long machine; -{ - const bfd_arch_info_type * const *app, *ap; - - for (app = bfd_archures_list; *app != NULL; app++) - { - for (ap = *app; ap != NULL; ap = ap->next) - { - if (ap->arch == arch - && (ap->mach == machine - || (machine == 0 && ap->the_default))) - return ap; - } - } - - return NULL; -} - - -/* -FUNCTION - bfd_printable_arch_mach - -SYNOPSIS - const char *bfd_printable_arch_mach - (enum bfd_architecture arch, unsigned long machine); - -DESCRIPTION - Return a printable string representing the architecture and - machine type. - - This routine is depreciated. -*/ - -const char * -bfd_printable_arch_mach (arch, machine) - enum bfd_architecture arch; - unsigned long machine; -{ - const bfd_arch_info_type *ap = bfd_lookup_arch (arch, machine); - - if (ap) - return ap->printable_name; - return "UNKNOWN!"; -} diff --git a/contrib/gdb/bfd/bfd-in.h b/contrib/gdb/bfd/bfd-in.h deleted file mode 100644 index d2912396551..00000000000 --- a/contrib/gdb/bfd/bfd-in.h +++ /dev/null @@ -1,668 +0,0 @@ -/* Main header file for the bfd library -- portable access to object files. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -** NOTE: bfd.h and bfd-in2.h are GENERATED files. Don't change them; -** instead, change bfd-in.h or the other BFD source files processed to -** generate these files. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* bfd.h -- The only header file required by users of the bfd library - -The bfd.h file is generated from bfd-in.h and various .c files; if you -change it, your changes will probably be lost. - -All the prototypes and definitions following the comment "THE FOLLOWING -IS EXTRACTED FROM THE SOURCE" are extracted from the source files for -BFD. If you change it, someone oneday will extract it from the source -again, and your changes will be lost. To save yourself from this bind, -change the definitions in the source in the bfd directory. Type "make -docs" and then "make headers" in that directory, and magically this file -will change to reflect your changes. - -If you don't have the tools to perform the extraction, then you are -safe from someone on your system trampling over your header files. -You should still maintain the equivalence between the source and this -file though; every change you make to the .c file should be reflected -here. */ - -#ifndef __BFD_H_SEEN__ -#define __BFD_H_SEEN__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ansidecl.h" -#include "obstack.h" - -/* These two lines get substitutions done by commands in Makefile.in. */ -#define BFD_VERSION "@VERSION@" -#define BFD_ARCH_SIZE @WORDSIZE@ -#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@ - -#if BFD_ARCH_SIZE >= 64 -#define BFD64 -#endif - -#ifndef INLINE -#if __GNUC__ >= 2 -#define INLINE __inline__ -#else -#define INLINE -#endif -#endif - -/* forward declaration */ -typedef struct _bfd bfd; - -/* To squelch erroneous compiler warnings ("illegal pointer - combination") from the SVR3 compiler, we would like to typedef - boolean to int (it doesn't like functions which return boolean. - Making sure they are never implicitly declared to return int - doesn't seem to help). But this file is not configured based on - the host. */ -/* General rules: functions which are boolean return true on success - and false on failure (unless they're a predicate). -- bfd.doc */ -/* I'm sure this is going to break something and someone is going to - force me to change it. */ -/* typedef enum boolean {false, true} boolean; */ -/* Yup, SVR4 has a "typedef enum boolean" in -fnf */ -/* It gets worse if the host also defines a true/false enum... -sts */ -/* And even worse if your compiler has built-in boolean types... -law */ -#if defined (__GNUG__) && (__GNUC_MINOR__ > 5) -#define TRUE_FALSE_ALREADY_DEFINED -#endif -#ifdef MPW -/* Pre-emptive strike - get the file with the enum. */ -#include -#define TRUE_FALSE_ALREADY_DEFINED -#endif /* MPW */ -#ifndef TRUE_FALSE_ALREADY_DEFINED -typedef enum bfd_boolean {false, true} boolean; -#define BFD_TRUE_FALSE -#else -/* Use enum names that will appear nowhere else. */ -typedef enum bfd_boolean {bfd_fffalse, bfd_tttrue} boolean; -#endif - -/* A pointer to a position in a file. */ -/* FIXME: This should be using off_t from . - For now, try to avoid breaking stuff by not including here. - This will break on systems with 64-bit file offsets (e.g. 4.4BSD). - Probably the best long-term answer is to avoid using file_ptr AND off_t - in this header file, and to handle this in the BFD implementation - rather than in its interface. */ -/* typedef off_t file_ptr; */ -typedef long int file_ptr; - -/* Support for different sizes of target format ints and addresses. - If the type `long' is at least 64 bits, BFD_HOST_64BIT_LONG will be - set to 1 above. Otherwise, if gcc is being used, this code will - use gcc's "long long" type. Otherwise, the compilation will fail - if 64-bit targets are requested. */ - -#ifdef BFD64 - -#ifndef BFD_HOST_64_BIT -#if BFD_HOST_64BIT_LONG -#define BFD_HOST_64_BIT long -#else -#ifdef __GNUC__ -#define BFD_HOST_64_BIT long long -#endif /* defined (__GNUC__) */ -#endif /* ! BFD_HOST_64BIT_LONG */ -#endif /* ! defined (BFD_HOST_64_BIT) */ - -typedef unsigned BFD_HOST_64_BIT bfd_vma; -typedef BFD_HOST_64_BIT bfd_signed_vma; -typedef unsigned BFD_HOST_64_BIT bfd_size_type; -typedef unsigned BFD_HOST_64_BIT symvalue; - -#ifndef fprintf_vma -#if BFD_HOST_64BIT_LONG -#define sprintf_vma(s,x) sprintf (s, "%016lx", x) -#define fprintf_vma(f,x) fprintf (f, "%016lx", x) -#else -#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) -#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) -#define fprintf_vma(s,x) \ - fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) -#define sprintf_vma(s,x) \ - sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) -#endif -#endif - -#else /* not BFD64 */ - -/* Represent a target address. Also used as a generic unsigned type - which is guaranteed to be big enough to hold any arithmetic types - we need to deal with. */ -typedef unsigned long bfd_vma; - -/* A generic signed type which is guaranteed to be big enough to hold any - arithmetic types we need to deal with. Can be assumed to be compatible - with bfd_vma in the same way that signed and unsigned ints are compatible - (as parameters, in assignment, etc). */ -typedef long bfd_signed_vma; - -typedef unsigned long symvalue; -typedef unsigned long bfd_size_type; - -/* Print a bfd_vma x on stream s. */ -#define fprintf_vma(s,x) fprintf(s, "%08lx", x) -#define sprintf_vma(s,x) sprintf(s, "%08lx", x) -#endif /* not BFD64 */ -#define printf_vma(x) fprintf_vma(stdout,x) - -typedef unsigned int flagword; /* 32 bits of flags */ -typedef unsigned char bfd_byte; - -/** File formats */ - -typedef enum bfd_format { - bfd_unknown = 0, /* file format is unknown */ - bfd_object, /* linker/assember/compiler output */ - bfd_archive, /* object archive file */ - bfd_core, /* core dump */ - bfd_type_end} /* marks the end; don't use it! */ - bfd_format; - -/* Values that may appear in the flags field of a BFD. These also - appear in the object_flags field of the bfd_target structure, where - they indicate the set of flags used by that backend (not all flags - are meaningful for all object file formats) (FIXME: at the moment, - the object_flags values have mostly just been copied from backend - to another, and are not necessarily correct). */ - -/* No flags. */ -#define NO_FLAGS 0x00 - -/* BFD contains relocation entries. */ -#define HAS_RELOC 0x01 - -/* BFD is directly executable. */ -#define EXEC_P 0x02 - -/* BFD has line number information (basically used for F_LNNO in a - COFF header). */ -#define HAS_LINENO 0x04 - -/* BFD has debugging information. */ -#define HAS_DEBUG 0x08 - -/* BFD has symbols. */ -#define HAS_SYMS 0x10 - -/* BFD has local symbols (basically used for F_LSYMS in a COFF - header). */ -#define HAS_LOCALS 0x20 - -/* BFD is a dynamic object. */ -#define DYNAMIC 0x40 - -/* Text section is write protected (if D_PAGED is not set, this is - like an a.out NMAGIC file) (the linker sets this by default, but - clears it for -r or -N). */ -#define WP_TEXT 0x80 - -/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the - linker sets this by default, but clears it for -r or -n or -N). */ -#define D_PAGED 0x100 - -/* BFD is relaxable (this means that bfd_relax_section may be able to - do something) (sometimes bfd_relax_section can do something even if - this is not set). */ -#define BFD_IS_RELAXABLE 0x200 - -/* This may be set before writing out a BFD to request using a - traditional format. For example, this is used to request that when - writing out an a.out object the symbols not be hashed to eliminate - duplicates. */ -#define BFD_TRADITIONAL_FORMAT 0x400 - -/* This flag indicates that the BFD contents are actually cached in - memory. If this is set, iostream points to a bfd_in_memory struct. */ -#define BFD_IN_MEMORY 0x800 - -/* symbols and relocation */ - -/* A count of carsyms (canonical archive symbols). */ -typedef unsigned long symindex; - -/* How to perform a relocation. */ -typedef const struct reloc_howto_struct reloc_howto_type; - -#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) - -/* General purpose part of a symbol X; - target specific parts are in libcoff.h, libaout.h, etc. */ - -#define bfd_get_section(x) ((x)->section) -#define bfd_get_output_section(x) ((x)->section->output_section) -#define bfd_set_section(x,y) ((x)->section) = (y) -#define bfd_asymbol_base(x) ((x)->section->vma) -#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) -#define bfd_asymbol_name(x) ((x)->name) -/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ -#define bfd_asymbol_bfd(x) ((x)->the_bfd) -#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) - -/* A canonical archive symbol. */ -/* This is a type pun with struct ranlib on purpose! */ -typedef struct carsym { - char *name; - file_ptr file_offset; /* look here to find the file */ -} carsym; /* to make these you call a carsymogen */ - - -/* Used in generating armaps (archive tables of contents). - Perhaps just a forward definition would do? */ -struct orl { /* output ranlib */ - char **name; /* symbol name */ - file_ptr pos; /* bfd* or file position */ - int namidx; /* index into string table */ -}; - - -/* Linenumber stuff */ -typedef struct lineno_cache_entry { - unsigned int line_number; /* Linenumber from start of function*/ - union { - struct symbol_cache_entry *sym; /* Function name */ - unsigned long offset; /* Offset into section */ - } u; -} alent; - -/* object and core file sections */ - -#define align_power(addr, align) \ - ( ((addr) + ((1<<(align))-1)) & (-1 << (align))) - -typedef struct sec *sec_ptr; - -#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) -#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) -#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) -#define bfd_section_name(bfd, ptr) ((ptr)->name) -#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr)) -#define bfd_section_vma(bfd, ptr) ((ptr)->vma) -#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) -#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) -#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) - -#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) - -#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = (boolean)true), true) -#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true) -#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true) - -typedef struct stat stat_type; - -typedef enum bfd_print_symbol -{ - bfd_print_symbol_name, - bfd_print_symbol_more, - bfd_print_symbol_all -} bfd_print_symbol_type; - -/* Information about a symbol that nm needs. */ - -typedef struct _symbol_info -{ - symvalue value; - char type; - CONST char *name; /* Symbol name. */ - unsigned char stab_type; /* Stab type. */ - char stab_other; /* Stab other. */ - short stab_desc; /* Stab desc. */ - CONST char *stab_name; /* String for stab type. */ -} symbol_info; - -/* Get the name of a stabs type code. */ - -extern const char *bfd_get_stab_name PARAMS ((int)); - -/* Hash table routines. There is no way to free up a hash table. */ - -/* An element in the hash table. Most uses will actually use a larger - structure, and an instance of this will be the first field. */ - -struct bfd_hash_entry -{ - /* Next entry for this hash code. */ - struct bfd_hash_entry *next; - /* String being hashed. */ - const char *string; - /* Hash code. This is the full hash code, not the index into the - table. */ - unsigned long hash; -}; - -/* A hash table. */ - -struct bfd_hash_table -{ - /* The hash array. */ - struct bfd_hash_entry **table; - /* The number of slots in the hash table. */ - unsigned int size; - /* A function used to create new elements in the hash table. The - first entry is itself a pointer to an element. When this - function is first invoked, this pointer will be NULL. However, - having the pointer permits a hierarchy of method functions to be - built each of which calls the function in the superclass. Thus - each function should be written to allocate a new block of memory - only if the argument is NULL. */ - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); - /* An obstack for this hash table. */ - struct obstack memory; -}; - -/* Initialize a hash table. */ -extern boolean bfd_hash_table_init - PARAMS ((struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Initialize a hash table specifying a size. */ -extern boolean bfd_hash_table_init_n - PARAMS ((struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int size)); - -/* Free up a hash table. */ -extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *)); - -/* Look up a string in a hash table. If CREATE is true, a new entry - will be created for this string if one does not already exist. The - COPY argument must be true if this routine should copy the string - into newly allocated memory when adding an entry. */ -extern struct bfd_hash_entry *bfd_hash_lookup - PARAMS ((struct bfd_hash_table *, const char *, boolean create, - boolean copy)); - -/* Replace an entry in a hash table. */ -extern void bfd_hash_replace - PARAMS ((struct bfd_hash_table *, struct bfd_hash_entry *old, - struct bfd_hash_entry *nw)); - -/* Base method for creating a hash table entry. */ -extern struct bfd_hash_entry *bfd_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); - -/* Grab some space for a hash table entry. */ -extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *, - unsigned int)); - -/* Traverse a hash table in a random order, calling a function on each - element. If the function returns false, the traversal stops. The - INFO argument is passed to the function. */ -extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *, - boolean (*) (struct bfd_hash_entry *, - PTR), - PTR info)); - -/* Semi-portable string concatenation in cpp. - The CAT4 hack is to avoid a problem with some strict ANSI C preprocessors. - The problem is, "32_" is not a valid preprocessing token, and we don't - want extra underscores (e.g., "nlm_32_"). The XCAT2 macro will cause the - inner CAT macros to be evaluated first, producing still-valid pp-tokens. - Then the final concatenation can be done. (Sigh.) */ -#ifndef CAT -#ifdef SABER -#define CAT(a,b) a##b -#define CAT3(a,b,c) a##b##c -#define CAT4(a,b,c,d) a##b##c##d -#else -#if defined(__STDC__) || defined(ALMOST_STDC) -#define CAT(a,b) a##b -#define CAT3(a,b,c) a##b##c -#define XCAT2(a,b) CAT(a,b) -#define CAT4(a,b,c,d) XCAT2(CAT(a,b),CAT(c,d)) -#else -#define CAT(a,b) a/**/b -#define CAT3(a,b,c) a/**/b/**/c -#define CAT4(a,b,c,d) a/**/b/**/c/**/d -#endif -#endif -#endif - -#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table - -/* User program access to BFD facilities */ - -/* Direct I/O routines, for programs which know more about the object - file than BFD does. Use higher level routines if possible. */ - -extern bfd_size_type bfd_read - PARAMS ((PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); -extern bfd_size_type bfd_write - PARAMS ((const PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); -extern int bfd_seek PARAMS ((bfd *abfd, file_ptr fp, int direction)); -extern long bfd_tell PARAMS ((bfd *abfd)); -extern int bfd_flush PARAMS ((bfd *abfd)); -extern int bfd_stat PARAMS ((bfd *abfd, struct stat *)); - - -/* Cast from const char * to char * so that caller can assign to - a char * without a warning. */ -#define bfd_get_filename(abfd) ((char *) (abfd)->filename) -#define bfd_get_cacheable(abfd) ((abfd)->cacheable) -#define bfd_get_format(abfd) ((abfd)->format) -#define bfd_get_target(abfd) ((abfd)->xvec->name) -#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) -#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) -#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) -#define bfd_header_big_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) -#define bfd_header_little_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) -#define bfd_get_file_flags(abfd) ((abfd)->flags) -#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) -#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) -#define bfd_my_archive(abfd) ((abfd)->my_archive) -#define bfd_has_map(abfd) ((abfd)->has_armap) - -#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) -#define bfd_usrdata(abfd) ((abfd)->usrdata) - -#define bfd_get_start_address(abfd) ((abfd)->start_address) -#define bfd_get_symcount(abfd) ((abfd)->symcount) -#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) -#define bfd_count_sections(abfd) ((abfd)->section_count) - -#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) - -#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (boolean)(bool)), true) - -extern boolean bfd_record_phdr - PARAMS ((bfd *, unsigned long, boolean, flagword, boolean, bfd_vma, - boolean, boolean, unsigned int, struct sec **)); - -/* Byte swapping routines. */ - -bfd_vma bfd_getb64 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl64 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_64 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_64 PARAMS ((const unsigned char *)); -bfd_vma bfd_getb32 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl32 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_32 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_32 PARAMS ((const unsigned char *)); -bfd_vma bfd_getb16 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl16 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_16 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_16 PARAMS ((const unsigned char *)); -void bfd_putb64 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl64 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putb32 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl32 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putb16 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl16 PARAMS ((bfd_vma, unsigned char *)); - -/* Externally visible ECOFF routines. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_debug_info; -struct ecoff_debug_swap; -struct ecoff_extr; -struct symbol_cache_entry; -struct bfd_link_info; -struct bfd_link_hash_entry; -#endif -extern bfd_vma bfd_ecoff_get_gp_value PARAMS ((bfd * abfd)); -extern boolean bfd_ecoff_set_gp_value PARAMS ((bfd *abfd, bfd_vma gp_value)); -extern boolean bfd_ecoff_set_regmasks - PARAMS ((bfd *abfd, unsigned long gprmask, unsigned long fprmask, - unsigned long *cprmask)); -extern PTR bfd_ecoff_debug_init - PARAMS ((bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - struct bfd_link_info *)); -extern void bfd_ecoff_debug_free - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_accumulate - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - bfd *input_bfd, struct ecoff_debug_info *input_debug, - const struct ecoff_debug_swap *input_swap, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_accumulate_other - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, bfd *input_bfd, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_externals - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - boolean relocateable, - boolean (*get_extr) (struct symbol_cache_entry *, - struct ecoff_extr *), - void (*set_index) (struct symbol_cache_entry *, - bfd_size_type))); -extern boolean bfd_ecoff_debug_one_external - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - const char *name, struct ecoff_extr *esym)); -extern bfd_size_type bfd_ecoff_debug_size - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap)); -extern boolean bfd_ecoff_write_debug - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, file_ptr where)); -extern boolean bfd_ecoff_write_accumulated_debug - PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - struct bfd_link_info *info, file_ptr where)); -extern boolean bfd_mips_ecoff_create_embedded_relocs - PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, - char **)); - -/* Externally visible ELF routines. */ - -struct bfd_link_needed_list -{ - struct bfd_link_needed_list *next; - bfd *by; - const char *name; -}; - -extern boolean bfd_elf32_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); -extern boolean bfd_elf64_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); -extern struct bfd_link_needed_list *bfd_elf_get_needed_list - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_elf32_size_dynamic_sections - PARAMS ((bfd *, const char *, const char *, boolean, - struct bfd_link_info *, struct sec **)); -extern boolean bfd_elf64_size_dynamic_sections - PARAMS ((bfd *, const char *, const char *, boolean, - struct bfd_link_info *, struct sec **)); -extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *)); -extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *)); - -/* SunOS shared library support routines for the linker. */ - -extern struct bfd_link_needed_list *bfd_sunos_get_needed_list - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_sunos_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_sunos_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, struct sec **, struct sec **, - struct sec **)); - -/* Linux shared library support routines for the linker. */ - -extern boolean bfd_i386linux_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_m68klinux_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -/* mmap hacks */ - -struct _bfd_window_internal; -typedef struct _bfd_window_internal bfd_window_internal; - -typedef struct _bfd_window { - /* What the user asked for. */ - PTR data; - bfd_size_type size; - /* The actual window used by BFD. Small user-requested read-only - regions sharing a page may share a single window into the object - file. Read-write versions shouldn't until I've fixed things to - keep track of which portions have been claimed by the - application; don't want to give the same region back when the - application wants two writable copies! */ - struct _bfd_window_internal *i; -} bfd_window; - -extern void bfd_init_window PARAMS ((bfd_window *)); -extern void bfd_free_window PARAMS ((bfd_window *)); -extern boolean bfd_get_file_window - PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, boolean)); - -/* XCOFF support routines for the linker. */ - -extern boolean bfd_xcoff_link_record_set - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_size_type)); -extern boolean bfd_xcoff_import_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_vma, const char *, const char *, const char *)); -extern boolean bfd_xcoff_export_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - boolean)); -extern boolean bfd_xcoff_link_count_reloc - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_xcoff_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_xcoff_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *, - unsigned long, unsigned long, unsigned long, boolean, - int, boolean, boolean, struct sec **)); - -/* And more from the source. */ diff --git a/contrib/gdb/bfd/bfd-in2.h b/contrib/gdb/bfd/bfd-in2.h deleted file mode 100644 index d238d5afa4a..00000000000 --- a/contrib/gdb/bfd/bfd-in2.h +++ /dev/null @@ -1,2479 +0,0 @@ -/* Main header file for the bfd library -- portable access to object files. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -** NOTE: bfd.h and bfd-in2.h are GENERATED files. Don't change them; -** instead, change bfd-in.h or the other BFD source files processed to -** generate these files. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* bfd.h -- The only header file required by users of the bfd library - -The bfd.h file is generated from bfd-in.h and various .c files; if you -change it, your changes will probably be lost. - -All the prototypes and definitions following the comment "THE FOLLOWING -IS EXTRACTED FROM THE SOURCE" are extracted from the source files for -BFD. If you change it, someone oneday will extract it from the source -again, and your changes will be lost. To save yourself from this bind, -change the definitions in the source in the bfd directory. Type "make -docs" and then "make headers" in that directory, and magically this file -will change to reflect your changes. - -If you don't have the tools to perform the extraction, then you are -safe from someone on your system trampling over your header files. -You should still maintain the equivalence between the source and this -file though; every change you make to the .c file should be reflected -here. */ - -#ifndef __BFD_H_SEEN__ -#define __BFD_H_SEEN__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ansidecl.h" -#include "obstack.h" - -/* These two lines get substitutions done by commands in Makefile.in. */ -#define BFD_VERSION "@VERSION@" -#define BFD_ARCH_SIZE @WORDSIZE@ -#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@ - -#if BFD_ARCH_SIZE >= 64 -#define BFD64 -#endif - -#ifndef INLINE -#if __GNUC__ >= 2 -#define INLINE __inline__ -#else -#define INLINE -#endif -#endif - -/* forward declaration */ -typedef struct _bfd bfd; - -/* To squelch erroneous compiler warnings ("illegal pointer - combination") from the SVR3 compiler, we would like to typedef - boolean to int (it doesn't like functions which return boolean. - Making sure they are never implicitly declared to return int - doesn't seem to help). But this file is not configured based on - the host. */ -/* General rules: functions which are boolean return true on success - and false on failure (unless they're a predicate). -- bfd.doc */ -/* I'm sure this is going to break something and someone is going to - force me to change it. */ -/* typedef enum boolean {false, true} boolean; */ -/* Yup, SVR4 has a "typedef enum boolean" in -fnf */ -/* It gets worse if the host also defines a true/false enum... -sts */ -/* And even worse if your compiler has built-in boolean types... -law */ -#if defined (__GNUG__) && (__GNUC_MINOR__ > 5) -#define TRUE_FALSE_ALREADY_DEFINED -#endif -#ifdef MPW -/* Pre-emptive strike - get the file with the enum. */ -#include -#define TRUE_FALSE_ALREADY_DEFINED -#endif /* MPW */ -#ifndef TRUE_FALSE_ALREADY_DEFINED -typedef enum bfd_boolean {false, true} boolean; -#define BFD_TRUE_FALSE -#else -/* Use enum names that will appear nowhere else. */ -typedef enum bfd_boolean {bfd_fffalse, bfd_tttrue} boolean; -#endif - -/* A pointer to a position in a file. */ -/* FIXME: This should be using off_t from . - For now, try to avoid breaking stuff by not including here. - This will break on systems with 64-bit file offsets (e.g. 4.4BSD). - Probably the best long-term answer is to avoid using file_ptr AND off_t - in this header file, and to handle this in the BFD implementation - rather than in its interface. */ -/* typedef off_t file_ptr; */ -typedef long int file_ptr; - -/* Support for different sizes of target format ints and addresses. - If the type `long' is at least 64 bits, BFD_HOST_64BIT_LONG will be - set to 1 above. Otherwise, if gcc is being used, this code will - use gcc's "long long" type. Otherwise, the compilation will fail - if 64-bit targets are requested. */ - -#ifdef BFD64 - -#ifndef BFD_HOST_64_BIT -#if BFD_HOST_64BIT_LONG -#define BFD_HOST_64_BIT long -#else -#ifdef __GNUC__ -#define BFD_HOST_64_BIT long long -#endif /* defined (__GNUC__) */ -#endif /* ! BFD_HOST_64BIT_LONG */ -#endif /* ! defined (BFD_HOST_64_BIT) */ - -typedef unsigned BFD_HOST_64_BIT bfd_vma; -typedef BFD_HOST_64_BIT bfd_signed_vma; -typedef unsigned BFD_HOST_64_BIT bfd_size_type; -typedef unsigned BFD_HOST_64_BIT symvalue; - -#ifndef fprintf_vma -#if BFD_HOST_64BIT_LONG -#define sprintf_vma(s,x) sprintf (s, "%016lx", x) -#define fprintf_vma(f,x) fprintf (f, "%016lx", x) -#else -#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) -#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) -#define fprintf_vma(s,x) \ - fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) -#define sprintf_vma(s,x) \ - sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) -#endif -#endif - -#else /* not BFD64 */ - -/* Represent a target address. Also used as a generic unsigned type - which is guaranteed to be big enough to hold any arithmetic types - we need to deal with. */ -typedef unsigned long bfd_vma; - -/* A generic signed type which is guaranteed to be big enough to hold any - arithmetic types we need to deal with. Can be assumed to be compatible - with bfd_vma in the same way that signed and unsigned ints are compatible - (as parameters, in assignment, etc). */ -typedef long bfd_signed_vma; - -typedef unsigned long symvalue; -typedef unsigned long bfd_size_type; - -/* Print a bfd_vma x on stream s. */ -#define fprintf_vma(s,x) fprintf(s, "%08lx", x) -#define sprintf_vma(s,x) sprintf(s, "%08lx", x) -#endif /* not BFD64 */ -#define printf_vma(x) fprintf_vma(stdout,x) - -typedef unsigned int flagword; /* 32 bits of flags */ -typedef unsigned char bfd_byte; - -/** File formats */ - -typedef enum bfd_format { - bfd_unknown = 0, /* file format is unknown */ - bfd_object, /* linker/assember/compiler output */ - bfd_archive, /* object archive file */ - bfd_core, /* core dump */ - bfd_type_end} /* marks the end; don't use it! */ - bfd_format; - -/* Values that may appear in the flags field of a BFD. These also - appear in the object_flags field of the bfd_target structure, where - they indicate the set of flags used by that backend (not all flags - are meaningful for all object file formats) (FIXME: at the moment, - the object_flags values have mostly just been copied from backend - to another, and are not necessarily correct). */ - -/* No flags. */ -#define NO_FLAGS 0x00 - -/* BFD contains relocation entries. */ -#define HAS_RELOC 0x01 - -/* BFD is directly executable. */ -#define EXEC_P 0x02 - -/* BFD has line number information (basically used for F_LNNO in a - COFF header). */ -#define HAS_LINENO 0x04 - -/* BFD has debugging information. */ -#define HAS_DEBUG 0x08 - -/* BFD has symbols. */ -#define HAS_SYMS 0x10 - -/* BFD has local symbols (basically used for F_LSYMS in a COFF - header). */ -#define HAS_LOCALS 0x20 - -/* BFD is a dynamic object. */ -#define DYNAMIC 0x40 - -/* Text section is write protected (if D_PAGED is not set, this is - like an a.out NMAGIC file) (the linker sets this by default, but - clears it for -r or -N). */ -#define WP_TEXT 0x80 - -/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the - linker sets this by default, but clears it for -r or -n or -N). */ -#define D_PAGED 0x100 - -/* BFD is relaxable (this means that bfd_relax_section may be able to - do something) (sometimes bfd_relax_section can do something even if - this is not set). */ -#define BFD_IS_RELAXABLE 0x200 - -/* This may be set before writing out a BFD to request using a - traditional format. For example, this is used to request that when - writing out an a.out object the symbols not be hashed to eliminate - duplicates. */ -#define BFD_TRADITIONAL_FORMAT 0x400 - -/* This flag indicates that the BFD contents are actually cached in - memory. If this is set, iostream points to a bfd_in_memory struct. */ -#define BFD_IN_MEMORY 0x800 - -/* symbols and relocation */ - -/* A count of carsyms (canonical archive symbols). */ -typedef unsigned long symindex; - -/* How to perform a relocation. */ -typedef const struct reloc_howto_struct reloc_howto_type; - -#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) - -/* General purpose part of a symbol X; - target specific parts are in libcoff.h, libaout.h, etc. */ - -#define bfd_get_section(x) ((x)->section) -#define bfd_get_output_section(x) ((x)->section->output_section) -#define bfd_set_section(x,y) ((x)->section) = (y) -#define bfd_asymbol_base(x) ((x)->section->vma) -#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) -#define bfd_asymbol_name(x) ((x)->name) -/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ -#define bfd_asymbol_bfd(x) ((x)->the_bfd) -#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) - -/* A canonical archive symbol. */ -/* This is a type pun with struct ranlib on purpose! */ -typedef struct carsym { - char *name; - file_ptr file_offset; /* look here to find the file */ -} carsym; /* to make these you call a carsymogen */ - - -/* Used in generating armaps (archive tables of contents). - Perhaps just a forward definition would do? */ -struct orl { /* output ranlib */ - char **name; /* symbol name */ - file_ptr pos; /* bfd* or file position */ - int namidx; /* index into string table */ -}; - - -/* Linenumber stuff */ -typedef struct lineno_cache_entry { - unsigned int line_number; /* Linenumber from start of function*/ - union { - struct symbol_cache_entry *sym; /* Function name */ - unsigned long offset; /* Offset into section */ - } u; -} alent; - -/* object and core file sections */ - -#define align_power(addr, align) \ - ( ((addr) + ((1<<(align))-1)) & (-1 << (align))) - -typedef struct sec *sec_ptr; - -#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) -#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) -#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) -#define bfd_section_name(bfd, ptr) ((ptr)->name) -#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr)) -#define bfd_section_vma(bfd, ptr) ((ptr)->vma) -#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) -#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) -#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) - -#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) - -#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = (boolean)true), true) -#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true) -#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true) - -typedef struct stat stat_type; - -typedef enum bfd_print_symbol -{ - bfd_print_symbol_name, - bfd_print_symbol_more, - bfd_print_symbol_all -} bfd_print_symbol_type; - -/* Information about a symbol that nm needs. */ - -typedef struct _symbol_info -{ - symvalue value; - char type; - CONST char *name; /* Symbol name. */ - unsigned char stab_type; /* Stab type. */ - char stab_other; /* Stab other. */ - short stab_desc; /* Stab desc. */ - CONST char *stab_name; /* String for stab type. */ -} symbol_info; - -/* Get the name of a stabs type code. */ - -extern const char *bfd_get_stab_name PARAMS ((int)); - -/* Hash table routines. There is no way to free up a hash table. */ - -/* An element in the hash table. Most uses will actually use a larger - structure, and an instance of this will be the first field. */ - -struct bfd_hash_entry -{ - /* Next entry for this hash code. */ - struct bfd_hash_entry *next; - /* String being hashed. */ - const char *string; - /* Hash code. This is the full hash code, not the index into the - table. */ - unsigned long hash; -}; - -/* A hash table. */ - -struct bfd_hash_table -{ - /* The hash array. */ - struct bfd_hash_entry **table; - /* The number of slots in the hash table. */ - unsigned int size; - /* A function used to create new elements in the hash table. The - first entry is itself a pointer to an element. When this - function is first invoked, this pointer will be NULL. However, - having the pointer permits a hierarchy of method functions to be - built each of which calls the function in the superclass. Thus - each function should be written to allocate a new block of memory - only if the argument is NULL. */ - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); - /* An obstack for this hash table. */ - struct obstack memory; -}; - -/* Initialize a hash table. */ -extern boolean bfd_hash_table_init - PARAMS ((struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Initialize a hash table specifying a size. */ -extern boolean bfd_hash_table_init_n - PARAMS ((struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int size)); - -/* Free up a hash table. */ -extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *)); - -/* Look up a string in a hash table. If CREATE is true, a new entry - will be created for this string if one does not already exist. The - COPY argument must be true if this routine should copy the string - into newly allocated memory when adding an entry. */ -extern struct bfd_hash_entry *bfd_hash_lookup - PARAMS ((struct bfd_hash_table *, const char *, boolean create, - boolean copy)); - -/* Replace an entry in a hash table. */ -extern void bfd_hash_replace - PARAMS ((struct bfd_hash_table *, struct bfd_hash_entry *old, - struct bfd_hash_entry *nw)); - -/* Base method for creating a hash table entry. */ -extern struct bfd_hash_entry *bfd_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); - -/* Grab some space for a hash table entry. */ -extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *, - unsigned int)); - -/* Traverse a hash table in a random order, calling a function on each - element. If the function returns false, the traversal stops. The - INFO argument is passed to the function. */ -extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *, - boolean (*) (struct bfd_hash_entry *, - PTR), - PTR info)); - -/* Semi-portable string concatenation in cpp. - The CAT4 hack is to avoid a problem with some strict ANSI C preprocessors. - The problem is, "32_" is not a valid preprocessing token, and we don't - want extra underscores (e.g., "nlm_32_"). The XCAT2 macro will cause the - inner CAT macros to be evaluated first, producing still-valid pp-tokens. - Then the final concatenation can be done. (Sigh.) */ -#ifndef CAT -#ifdef SABER -#define CAT(a,b) a##b -#define CAT3(a,b,c) a##b##c -#define CAT4(a,b,c,d) a##b##c##d -#else -#if defined(__STDC__) || defined(ALMOST_STDC) -#define CAT(a,b) a##b -#define CAT3(a,b,c) a##b##c -#define XCAT2(a,b) CAT(a,b) -#define CAT4(a,b,c,d) XCAT2(CAT(a,b),CAT(c,d)) -#else -#define CAT(a,b) a/**/b -#define CAT3(a,b,c) a/**/b/**/c -#define CAT4(a,b,c,d) a/**/b/**/c/**/d -#endif -#endif -#endif - -#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table - -/* User program access to BFD facilities */ - -/* Direct I/O routines, for programs which know more about the object - file than BFD does. Use higher level routines if possible. */ - -extern bfd_size_type bfd_read - PARAMS ((PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); -extern bfd_size_type bfd_write - PARAMS ((const PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); -extern int bfd_seek PARAMS ((bfd *abfd, file_ptr fp, int direction)); -extern long bfd_tell PARAMS ((bfd *abfd)); -extern int bfd_flush PARAMS ((bfd *abfd)); -extern int bfd_stat PARAMS ((bfd *abfd, struct stat *)); - - -/* Cast from const char * to char * so that caller can assign to - a char * without a warning. */ -#define bfd_get_filename(abfd) ((char *) (abfd)->filename) -#define bfd_get_cacheable(abfd) ((abfd)->cacheable) -#define bfd_get_format(abfd) ((abfd)->format) -#define bfd_get_target(abfd) ((abfd)->xvec->name) -#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) -#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) -#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) -#define bfd_header_big_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) -#define bfd_header_little_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) -#define bfd_get_file_flags(abfd) ((abfd)->flags) -#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) -#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) -#define bfd_my_archive(abfd) ((abfd)->my_archive) -#define bfd_has_map(abfd) ((abfd)->has_armap) - -#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) -#define bfd_usrdata(abfd) ((abfd)->usrdata) - -#define bfd_get_start_address(abfd) ((abfd)->start_address) -#define bfd_get_symcount(abfd) ((abfd)->symcount) -#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) -#define bfd_count_sections(abfd) ((abfd)->section_count) - -#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) - -#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (boolean)(bool)), true) - -extern boolean bfd_record_phdr - PARAMS ((bfd *, unsigned long, boolean, flagword, boolean, bfd_vma, - boolean, boolean, unsigned int, struct sec **)); - -/* Byte swapping routines. */ - -bfd_vma bfd_getb64 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl64 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_64 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_64 PARAMS ((const unsigned char *)); -bfd_vma bfd_getb32 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl32 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_32 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_32 PARAMS ((const unsigned char *)); -bfd_vma bfd_getb16 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl16 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_16 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_16 PARAMS ((const unsigned char *)); -void bfd_putb64 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl64 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putb32 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl32 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putb16 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl16 PARAMS ((bfd_vma, unsigned char *)); - -/* Externally visible ECOFF routines. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_debug_info; -struct ecoff_debug_swap; -struct ecoff_extr; -struct symbol_cache_entry; -struct bfd_link_info; -struct bfd_link_hash_entry; -#endif -extern bfd_vma bfd_ecoff_get_gp_value PARAMS ((bfd * abfd)); -extern boolean bfd_ecoff_set_gp_value PARAMS ((bfd *abfd, bfd_vma gp_value)); -extern boolean bfd_ecoff_set_regmasks - PARAMS ((bfd *abfd, unsigned long gprmask, unsigned long fprmask, - unsigned long *cprmask)); -extern PTR bfd_ecoff_debug_init - PARAMS ((bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - struct bfd_link_info *)); -extern void bfd_ecoff_debug_free - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_accumulate - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - bfd *input_bfd, struct ecoff_debug_info *input_debug, - const struct ecoff_debug_swap *input_swap, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_accumulate_other - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, bfd *input_bfd, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_externals - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - boolean relocateable, - boolean (*get_extr) (struct symbol_cache_entry *, - struct ecoff_extr *), - void (*set_index) (struct symbol_cache_entry *, - bfd_size_type))); -extern boolean bfd_ecoff_debug_one_external - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - const char *name, struct ecoff_extr *esym)); -extern bfd_size_type bfd_ecoff_debug_size - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap)); -extern boolean bfd_ecoff_write_debug - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, file_ptr where)); -extern boolean bfd_ecoff_write_accumulated_debug - PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - struct bfd_link_info *info, file_ptr where)); -extern boolean bfd_mips_ecoff_create_embedded_relocs - PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, - char **)); - -/* Externally visible ELF routines. */ - -struct bfd_link_needed_list -{ - struct bfd_link_needed_list *next; - bfd *by; - const char *name; -}; - -extern boolean bfd_elf32_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); -extern boolean bfd_elf64_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); -extern struct bfd_link_needed_list *bfd_elf_get_needed_list - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_elf32_size_dynamic_sections - PARAMS ((bfd *, const char *, const char *, boolean, - struct bfd_link_info *, struct sec **)); -extern boolean bfd_elf64_size_dynamic_sections - PARAMS ((bfd *, const char *, const char *, boolean, - struct bfd_link_info *, struct sec **)); -extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *)); -extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *)); - -/* SunOS shared library support routines for the linker. */ - -extern struct bfd_link_needed_list *bfd_sunos_get_needed_list - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_sunos_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_sunos_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, struct sec **, struct sec **, - struct sec **)); - -/* Linux shared library support routines for the linker. */ - -extern boolean bfd_i386linux_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_m68klinux_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -/* mmap hacks */ - -struct _bfd_window_internal; -typedef struct _bfd_window_internal bfd_window_internal; - -typedef struct _bfd_window { - /* What the user asked for. */ - PTR data; - bfd_size_type size; - /* The actual window used by BFD. Small user-requested read-only - regions sharing a page may share a single window into the object - file. Read-write versions shouldn't until I've fixed things to - keep track of which portions have been claimed by the - application; don't want to give the same region back when the - application wants two writable copies! */ - struct _bfd_window_internal *i; -} bfd_window; - -extern void bfd_init_window PARAMS ((bfd_window *)); -extern void bfd_free_window PARAMS ((bfd_window *)); -extern boolean bfd_get_file_window - PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, boolean)); - -/* XCOFF support routines for the linker. */ - -extern boolean bfd_xcoff_link_record_set - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_size_type)); -extern boolean bfd_xcoff_import_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_vma, const char *, const char *, const char *)); -extern boolean bfd_xcoff_export_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - boolean)); -extern boolean bfd_xcoff_link_count_reloc - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_xcoff_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_xcoff_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *, - unsigned long, unsigned long, unsigned long, boolean, - int, boolean, boolean, struct sec **)); - -/* And more from the source. */ -void -bfd_init PARAMS ((void)); - -bfd * -bfd_openr PARAMS ((CONST char *filename, CONST char *target)); - -bfd * -bfd_fdopenr PARAMS ((CONST char *filename, CONST char *target, int fd)); - -bfd * -bfd_openstreamr PARAMS (()); - -bfd * -bfd_openw PARAMS ((CONST char *filename, CONST char *target)); - -boolean -bfd_close PARAMS ((bfd *abfd)); - -boolean -bfd_close_all_done PARAMS ((bfd *)); - -bfd_size_type -bfd_alloc_size PARAMS ((bfd *abfd)); - -bfd * -bfd_create PARAMS ((CONST char *filename, bfd *templ)); - - - /* Byte swapping macros for user section data. */ - -#define bfd_put_8(abfd, val, ptr) \ - (*((unsigned char *)(ptr)) = (unsigned char)(val)) -#define bfd_put_signed_8 \ - bfd_put_8 -#define bfd_get_8(abfd, ptr) \ - (*(unsigned char *)(ptr)) -#define bfd_get_signed_8(abfd, ptr) \ - ((*(unsigned char *)(ptr) ^ 0x80) - 0x80) - -#define bfd_put_16(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_putx16, ((val),(ptr))) -#define bfd_put_signed_16 \ - bfd_put_16 -#define bfd_get_16(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx16, (ptr)) -#define bfd_get_signed_16(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) - -#define bfd_put_32(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_putx32, ((val),(ptr))) -#define bfd_put_signed_32 \ - bfd_put_32 -#define bfd_get_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx32, (ptr)) -#define bfd_get_signed_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx_signed_32, (ptr)) - -#define bfd_put_64(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_putx64, ((val), (ptr))) -#define bfd_put_signed_64 \ - bfd_put_64 -#define bfd_get_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx64, (ptr)) -#define bfd_get_signed_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) - - - /* Byte swapping macros for file header data. */ - -#define bfd_h_put_8(abfd, val, ptr) \ - bfd_put_8 (abfd, val, ptr) -#define bfd_h_put_signed_8(abfd, val, ptr) \ - bfd_put_8 (abfd, val, ptr) -#define bfd_h_get_8(abfd, ptr) \ - bfd_get_8 (abfd, ptr) -#define bfd_h_get_signed_8(abfd, ptr) \ - bfd_get_signed_8 (abfd, ptr) - -#define bfd_h_put_16(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_h_putx16,(val,ptr)) -#define bfd_h_put_signed_16 \ - bfd_h_put_16 -#define bfd_h_get_16(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx16,(ptr)) -#define bfd_h_get_signed_16(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr)) - -#define bfd_h_put_32(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_h_putx32,(val,ptr)) -#define bfd_h_put_signed_32 \ - bfd_h_put_32 -#define bfd_h_get_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx32,(ptr)) -#define bfd_h_get_signed_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr)) - -#define bfd_h_put_64(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_h_putx64,(val, ptr)) -#define bfd_h_put_signed_64 \ - bfd_h_put_64 -#define bfd_h_get_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx64,(ptr)) -#define bfd_h_get_signed_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr)) - -typedef struct sec -{ - /* The name of the section; the name isn't a copy, the pointer is - the same as that passed to bfd_make_section. */ - - CONST char *name; - - /* Which section is it; 0..nth. */ - - int index; - - /* The next section in the list belonging to the BFD, or NULL. */ - - struct sec *next; - - /* The field flags contains attributes of the section. Some - flags are read in from the object file, and some are - synthesized from other information. */ - - flagword flags; - -#define SEC_NO_FLAGS 0x000 - - /* Tells the OS to allocate space for this section when loading. - This is clear for a section containing debug information - only. */ -#define SEC_ALLOC 0x001 - - /* Tells the OS to load the section from the file when loading. - This is clear for a .bss section. */ -#define SEC_LOAD 0x002 - - /* The section contains data still to be relocated, so there is - some relocation information too. */ -#define SEC_RELOC 0x004 - -#if 0 /* Obsolete ? */ -#define SEC_BALIGN 0x008 -#endif - - /* A signal to the OS that the section contains read only - data. */ -#define SEC_READONLY 0x010 - - /* The section contains code only. */ -#define SEC_CODE 0x020 - - /* The section contains data only. */ -#define SEC_DATA 0x040 - - /* The section will reside in ROM. */ -#define SEC_ROM 0x080 - - /* The section contains constructor information. This section - type is used by the linker to create lists of constructors and - destructors used by <>. When a back end sees a symbol - which should be used in a constructor list, it creates a new - section for the type of name (e.g., <<__CTOR_LIST__>>), attaches - the symbol to it, and builds a relocation. To build the lists - of constructors, all the linker has to do is catenate all the - sections called <<__CTOR_LIST__>> and relocate the data - contained within - exactly the operations it would peform on - standard data. */ -#define SEC_CONSTRUCTOR 0x100 - - /* The section is a constuctor, and should be placed at the - end of the text, data, or bss section(?). */ -#define SEC_CONSTRUCTOR_TEXT 0x1100 -#define SEC_CONSTRUCTOR_DATA 0x2100 -#define SEC_CONSTRUCTOR_BSS 0x3100 - - /* The section has contents - a data section could be - <> | <>; a debug section could be - <> */ -#define SEC_HAS_CONTENTS 0x200 - - /* An instruction to the linker to not output the section - even if it has information which would normally be written. */ -#define SEC_NEVER_LOAD 0x400 - - /* The section is a COFF shared library section. This flag is - only for the linker. If this type of section appears in - the input file, the linker must copy it to the output file - without changing the vma or size. FIXME: Although this - was originally intended to be general, it really is COFF - specific (and the flag was renamed to indicate this). It - might be cleaner to have some more general mechanism to - allow the back end to control what the linker does with - sections. */ -#define SEC_COFF_SHARED_LIBRARY 0x800 - - /* The section is a common section (symbols may be defined - multiple times, the value of a symbol is the amount of - space it requires, and the largest symbol value is the one - used). Most targets have exactly one of these (which we - translate to bfd_com_section_ptr), but ECOFF has two. */ -#define SEC_IS_COMMON 0x8000 - - /* The section contains only debugging information. For - example, this is set for ELF .debug and .stab sections. - strip tests this flag to see if a section can be - discarded. */ -#define SEC_DEBUGGING 0x10000 - - /* The contents of this section are held in memory pointed to - by the contents field. This is checked by - bfd_get_section_contents, and the data is retrieved from - memory if appropriate. */ -#define SEC_IN_MEMORY 0x20000 - - /* The contents of this section are to be excluded by the - linker for executable and shared objects unless those - objects are to be further relocated. */ -#define SEC_EXCLUDE 0x40000 - - /* The contents of this section are to be sorted by the - based on the address specified in the associated symbol - table. */ -#define SEC_SORT_ENTRIES 0x80000 - - /* End of section flags. */ - - /* The virtual memory address of the section - where it will be - at run time. The symbols are relocated against this. The - user_set_vma flag is maintained by bfd; if it's not set, the - backend can assign addresses (for example, in <>, where - the default address for <<.data>> is dependent on the specific - target and various flags). */ - - bfd_vma vma; - boolean user_set_vma; - - /* The load address of the section - where it would be in a - rom image; really only used for writing section header - information. */ - - bfd_vma lma; - - /* The size of the section in bytes, as it will be output. - contains a value even if the section has no contents (e.g., the - size of <<.bss>>). This will be filled in after relocation */ - - bfd_size_type _cooked_size; - - /* The original size on disk of the section, in bytes. Normally this - value is the same as the size, but if some relaxing has - been done, then this value will be bigger. */ - - bfd_size_type _raw_size; - - /* If this section is going to be output, then this value is the - offset into the output section of the first byte in the input - section. E.g., if this was going to start at the 100th byte in - the output section, this value would be 100. */ - - bfd_vma output_offset; - - /* The output section through which to map on output. */ - - struct sec *output_section; - - /* The alignment requirement of the section, as an exponent of 2 - - e.g., 3 aligns to 2^3 (or 8). */ - - unsigned int alignment_power; - - /* If an input section, a pointer to a vector of relocation - records for the data in this section. */ - - struct reloc_cache_entry *relocation; - - /* If an output section, a pointer to a vector of pointers to - relocation records for the data in this section. */ - - struct reloc_cache_entry **orelocation; - - /* The number of relocation records in one of the above */ - - unsigned reloc_count; - - /* Information below is back end specific - and not always used - or updated. */ - - /* File position of section data */ - - file_ptr filepos; - - /* File position of relocation info */ - - file_ptr rel_filepos; - - /* File position of line data */ - - file_ptr line_filepos; - - /* Pointer to data for applications */ - - PTR userdata; - - /* If the SEC_IN_MEMORY flag is set, this points to the actual - contents. */ - unsigned char *contents; - - /* Attached line number information */ - - alent *lineno; - - /* Number of line number records */ - - unsigned int lineno_count; - - /* When a section is being output, this value changes as more - linenumbers are written out */ - - file_ptr moving_line_filepos; - - /* What the section number is in the target world */ - - int target_index; - - PTR used_by_bfd; - - /* If this is a constructor section then here is a list of the - relocations created to relocate items within it. */ - - struct relent_chain *constructor_chain; - - /* The BFD which owns the section. */ - - bfd *owner; - - boolean reloc_done; - /* A symbol which points at this section only */ - struct symbol_cache_entry *symbol; - struct symbol_cache_entry **symbol_ptr_ptr; - - struct bfd_link_order *link_order_head; - struct bfd_link_order *link_order_tail; -} asection ; - - /* These sections are global, and are managed by BFD. The application - and target back end are not permitted to change the values in - these sections. New code should use the section_ptr macros rather - than referring directly to the const sections. The const sections - may eventually vanish. */ -#define BFD_ABS_SECTION_NAME "*ABS*" -#define BFD_UND_SECTION_NAME "*UND*" -#define BFD_COM_SECTION_NAME "*COM*" -#define BFD_IND_SECTION_NAME "*IND*" - - /* the absolute section */ -extern const asection bfd_abs_section; -#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) -#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) - /* Pointer to the undefined section */ -extern const asection bfd_und_section; -#define bfd_und_section_ptr ((asection *) &bfd_und_section) -#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) - /* Pointer to the common section */ -extern const asection bfd_com_section; -#define bfd_com_section_ptr ((asection *) &bfd_com_section) - /* Pointer to the indirect section */ -extern const asection bfd_ind_section; -#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) -#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) - -extern const struct symbol_cache_entry * const bfd_abs_symbol; -extern const struct symbol_cache_entry * const bfd_com_symbol; -extern const struct symbol_cache_entry * const bfd_und_symbol; -extern const struct symbol_cache_entry * const bfd_ind_symbol; -#define bfd_get_section_size_before_reloc(section) \ - (section->reloc_done ? (abort(),1): (section)->_raw_size) -#define bfd_get_section_size_after_reloc(section) \ - ((section->reloc_done) ? (section)->_cooked_size: (abort(),1)) -asection * -bfd_get_section_by_name PARAMS ((bfd *abfd, CONST char *name)); - -asection * -bfd_make_section_old_way PARAMS ((bfd *abfd, CONST char *name)); - -asection * -bfd_make_section_anyway PARAMS ((bfd *abfd, CONST char *name)); - -asection * -bfd_make_section PARAMS ((bfd *, CONST char *name)); - -boolean -bfd_set_section_flags PARAMS ((bfd *abfd, asection *sec, flagword flags)); - -void -bfd_map_over_sections PARAMS ((bfd *abfd, - void (*func)(bfd *abfd, - asection *sect, - PTR obj), - PTR obj)); - -boolean -bfd_set_section_size PARAMS ((bfd *abfd, asection *sec, bfd_size_type val)); - -boolean -bfd_set_section_contents - PARAMS ((bfd *abfd, - asection *section, - PTR data, - file_ptr offset, - bfd_size_type count)); - -boolean -bfd_get_section_contents - PARAMS ((bfd *abfd, asection *section, PTR location, - file_ptr offset, bfd_size_type count)); - -boolean -bfd_copy_private_section_data PARAMS ((bfd *ibfd, asection *isec, bfd *obfd, asection *osec)); - -#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ - BFD_SEND (ibfd, _bfd_copy_private_section_data, \ - (ibfd, isection, obfd, osection)) -enum bfd_architecture -{ - bfd_arch_unknown, /* File arch not known */ - bfd_arch_obscure, /* Arch known, not one of these */ - bfd_arch_m68k, /* Motorola 68xxx */ - bfd_arch_vax, /* DEC Vax */ - bfd_arch_i960, /* Intel 960 */ - /* The order of the following is important. - lower number indicates a machine type that - only accepts a subset of the instructions - available to machines with higher numbers. - The exception is the "ca", which is - incompatible with all other machines except - "core". */ - -#define bfd_mach_i960_core 1 -#define bfd_mach_i960_ka_sa 2 -#define bfd_mach_i960_kb_sb 3 -#define bfd_mach_i960_mc 4 -#define bfd_mach_i960_xa 5 -#define bfd_mach_i960_ca 6 -#define bfd_mach_i960_jx 7 -#define bfd_mach_i960_hx 8 - - bfd_arch_a29k, /* AMD 29000 */ - bfd_arch_sparc, /* SPARC */ -#define bfd_mach_sparc 1 - /* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ -#define bfd_mach_sparc_v8plus 2 -#define bfd_mach_sparc_v8plusa 3 /* with ultrasparc add'ns */ -#define bfd_mach_sparc_v9 4 -#define bfd_mach_sparc_v9a 5 /* with ultrasparc add'ns */ - /* Nonzero if MACH has the v9 instruction set. */ -#define bfd_mach_sparc_v9_p(mach) ((mach) != bfd_mach_sparc) - bfd_arch_mips, /* MIPS Rxxxx */ - bfd_arch_i386, /* Intel 386 */ - bfd_arch_we32k, /* AT&T WE32xxx */ - bfd_arch_tahoe, /* CCI/Harris Tahoe */ - bfd_arch_i860, /* Intel 860 */ - bfd_arch_romp, /* IBM ROMP PC/RT */ - bfd_arch_alliant, /* Alliant */ - bfd_arch_convex, /* Convex */ - bfd_arch_m88k, /* Motorola 88xxx */ - bfd_arch_pyramid, /* Pyramid Technology */ - bfd_arch_h8300, /* Hitachi H8/300 */ -#define bfd_mach_h8300 1 -#define bfd_mach_h8300h 2 - bfd_arch_powerpc, /* PowerPC */ - bfd_arch_rs6000, /* IBM RS/6000 */ - bfd_arch_hppa, /* HP PA RISC */ - bfd_arch_z8k, /* Zilog Z8000 */ -#define bfd_mach_z8001 1 -#define bfd_mach_z8002 2 - bfd_arch_h8500, /* Hitachi H8/500 */ - bfd_arch_sh, /* Hitachi SH */ - bfd_arch_alpha, /* Dec Alpha */ - bfd_arch_arm, /* Advanced Risc Machines ARM */ - bfd_arch_ns32k, /* National Semiconductors ns32000 */ - bfd_arch_w65, /* WDC 65816 */ - bfd_arch_last - }; - -typedef struct bfd_arch_info -{ - int bits_per_word; - int bits_per_address; - int bits_per_byte; - enum bfd_architecture arch; - unsigned long mach; - const char *arch_name; - const char *printable_name; - unsigned int section_align_power; - /* true if this is the default machine for the architecture */ - boolean the_default; - const struct bfd_arch_info * (*compatible) - PARAMS ((const struct bfd_arch_info *a, - const struct bfd_arch_info *b)); - - boolean (*scan) PARAMS ((const struct bfd_arch_info *, const char *)); - - const struct bfd_arch_info *next; -} bfd_arch_info_type; -const char * -bfd_printable_name PARAMS ((bfd *abfd)); - -const bfd_arch_info_type * -bfd_scan_arch PARAMS ((const char *string)); - -const bfd_arch_info_type * -bfd_arch_get_compatible PARAMS (( - const bfd *abfd, - const bfd *bbfd)); - -void -bfd_set_arch_info PARAMS ((bfd *abfd, const bfd_arch_info_type *arg)); - -enum bfd_architecture -bfd_get_arch PARAMS ((bfd *abfd)); - -unsigned long -bfd_get_mach PARAMS ((bfd *abfd)); - -unsigned int -bfd_arch_bits_per_byte PARAMS ((bfd *abfd)); - -unsigned int -bfd_arch_bits_per_address PARAMS ((bfd *abfd)); - -const bfd_arch_info_type * -bfd_get_arch_info PARAMS ((bfd *abfd)); - -const bfd_arch_info_type * -bfd_lookup_arch - PARAMS ((enum bfd_architecture - arch, - unsigned long machine)); - -const char * -bfd_printable_arch_mach - PARAMS ((enum bfd_architecture arch, unsigned long machine)); - -typedef enum bfd_reloc_status -{ - /* No errors detected */ - bfd_reloc_ok, - - /* The relocation was performed, but there was an overflow. */ - bfd_reloc_overflow, - - /* The address to relocate was not within the section supplied. */ - bfd_reloc_outofrange, - - /* Used by special functions */ - bfd_reloc_continue, - - /* Unsupported relocation size requested. */ - bfd_reloc_notsupported, - - /* Unused */ - bfd_reloc_other, - - /* The symbol to relocate against was undefined. */ - bfd_reloc_undefined, - - /* The relocation was performed, but may not be ok - presently - generated only when linking i960 coff files with i960 b.out - symbols. If this type is returned, the error_message argument - to bfd_perform_relocation will be set. */ - bfd_reloc_dangerous - } - bfd_reloc_status_type; - - -typedef struct reloc_cache_entry -{ - /* A pointer into the canonical table of pointers */ - struct symbol_cache_entry **sym_ptr_ptr; - - /* offset in section */ - bfd_size_type address; - - /* addend for relocation value */ - bfd_vma addend; - - /* Pointer to how to perform the required relocation */ - reloc_howto_type *howto; - -} arelent; -enum complain_overflow -{ - /* Do not complain on overflow. */ - complain_overflow_dont, - - /* Complain if the bitfield overflows, whether it is considered - as signed or unsigned. */ - complain_overflow_bitfield, - - /* Complain if the value overflows when considered as signed - number. */ - complain_overflow_signed, - - /* Complain if the value overflows when considered as an - unsigned number. */ - complain_overflow_unsigned -}; - -struct reloc_howto_struct -{ - /* The type field has mainly a documetary use - the back end can - do what it wants with it, though normally the back end's - external idea of what a reloc number is stored - in this field. For example, a PC relative word relocation - in a coff environment has the type 023 - because that's - what the outside world calls a R_PCRWORD reloc. */ - unsigned int type; - - /* The value the final relocation is shifted right by. This drops - unwanted data from the relocation. */ - unsigned int rightshift; - - /* The size of the item to be relocated. This is *not* a - power-of-two measure. To get the number of bytes operated - on by a type of relocation, use bfd_get_reloc_size. */ - int size; - - /* The number of bits in the item to be relocated. This is used - when doing overflow checking. */ - unsigned int bitsize; - - /* Notes that the relocation is relative to the location in the - data section of the addend. The relocation function will - subtract from the relocation value the address of the location - being relocated. */ - boolean pc_relative; - - /* The bit position of the reloc value in the destination. - The relocated value is left shifted by this amount. */ - unsigned int bitpos; - - /* What type of overflow error should be checked for when - relocating. */ - enum complain_overflow complain_on_overflow; - - /* If this field is non null, then the supplied function is - called rather than the normal function. This allows really - strange relocation methods to be accomodated (e.g., i960 callj - instructions). */ - bfd_reloc_status_type (*special_function) - PARAMS ((bfd *abfd, - arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); - - /* The textual name of the relocation type. */ - char *name; - - /* When performing a partial link, some formats must modify the - relocations rather than the data - this flag signals this.*/ - boolean partial_inplace; - - /* The src_mask selects which parts of the read in data - are to be used in the relocation sum. E.g., if this was an 8 bit - bit of data which we read and relocated, this would be - 0x000000ff. When we have relocs which have an addend, such as - sun4 extended relocs, the value in the offset part of a - relocating field is garbage so we never use it. In this case - the mask would be 0x00000000. */ - bfd_vma src_mask; - - /* The dst_mask selects which parts of the instruction are replaced - into the instruction. In most cases src_mask == dst_mask, - except in the above special case, where dst_mask would be - 0x000000ff, and src_mask would be 0x00000000. */ - bfd_vma dst_mask; - - /* When some formats create PC relative instructions, they leave - the value of the pc of the place being relocated in the offset - slot of the instruction, so that a PC relative relocation can - be made just by adding in an ordinary offset (e.g., sun3 a.out). - Some formats leave the displacement part of an instruction - empty (e.g., m88k bcs); this flag signals the fact.*/ - boolean pcrel_offset; - -}; -#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ - {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC} -#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN) - -#define HOWTO_PREPARE(relocation, symbol) \ - { \ - if (symbol != (asymbol *)NULL) { \ - if (bfd_is_com_section (symbol->section)) { \ - relocation = 0; \ - } \ - else { \ - relocation = symbol->value; \ - } \ - } \ -} -int -bfd_get_reloc_size PARAMS ((reloc_howto_type *)); - -typedef struct relent_chain { - arelent relent; - struct relent_chain *next; -} arelent_chain; -bfd_reloc_status_type - -bfd_perform_relocation - PARAMS ((bfd *abfd, - arelent *reloc_entry, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); - -bfd_reloc_status_type - -bfd_install_relocation - PARAMS ((bfd *abfd, - arelent *reloc_entry, - PTR data, bfd_vma data_start, - asection *input_section, - char **error_message)); - -enum bfd_reloc_code_real { - _dummy_first_bfd_reloc_code_real, - - -/* Basic absolute relocations of N bits. */ - BFD_RELOC_64, - BFD_RELOC_32, - BFD_RELOC_26, - BFD_RELOC_16, - BFD_RELOC_14, - BFD_RELOC_8, - -/* PC-relative relocations. Sometimes these are relative to the address -of the relocation itself; sometimes they are relative to the start of -the section containing the relocation. It depends on the specific target. - -The 24-bit relocation is used in some Intel 960 configurations. */ - BFD_RELOC_64_PCREL, - BFD_RELOC_32_PCREL, - BFD_RELOC_24_PCREL, - BFD_RELOC_16_PCREL, - BFD_RELOC_12_PCREL, - BFD_RELOC_8_PCREL, - -/* For ELF. */ - BFD_RELOC_32_GOT_PCREL, - BFD_RELOC_16_GOT_PCREL, - BFD_RELOC_8_GOT_PCREL, - BFD_RELOC_32_GOTOFF, - BFD_RELOC_16_GOTOFF, - BFD_RELOC_LO16_GOTOFF, - BFD_RELOC_HI16_GOTOFF, - BFD_RELOC_HI16_S_GOTOFF, - BFD_RELOC_8_GOTOFF, - BFD_RELOC_32_PLT_PCREL, - BFD_RELOC_24_PLT_PCREL, - BFD_RELOC_16_PLT_PCREL, - BFD_RELOC_8_PLT_PCREL, - BFD_RELOC_32_PLTOFF, - BFD_RELOC_16_PLTOFF, - BFD_RELOC_LO16_PLTOFF, - BFD_RELOC_HI16_PLTOFF, - BFD_RELOC_HI16_S_PLTOFF, - BFD_RELOC_8_PLTOFF, - -/* Relocations used by 68K ELF. */ - BFD_RELOC_68K_GLOB_DAT, - BFD_RELOC_68K_JMP_SLOT, - BFD_RELOC_68K_RELATIVE, - -/* Linkage-table relative. */ - BFD_RELOC_32_BASEREL, - BFD_RELOC_16_BASEREL, - BFD_RELOC_LO16_BASEREL, - BFD_RELOC_HI16_BASEREL, - BFD_RELOC_HI16_S_BASEREL, - BFD_RELOC_8_BASEREL, - BFD_RELOC_RVA, - -/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ - BFD_RELOC_8_FFnn, - -/* These PC-relative relocations are stored as word displacements -- -i.e., byte displacements shifted right two bits. The 30-bit word -displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the -SPARC. (SPARC tools generally refer to this as <>.) The -signed 16-bit displacement is used on the MIPS, and the 23-bit -displacement is used on the Alpha. */ - BFD_RELOC_32_PCREL_S2, - BFD_RELOC_16_PCREL_S2, - BFD_RELOC_23_PCREL_S2, - -/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of -the target word. These are used on the SPARC. */ - BFD_RELOC_HI22, - BFD_RELOC_LO10, - -/* For systems that allocate a Global Pointer register, these are -displacements off that register. These relocation types are -handled specially, because the value the register will have is -decided relatively late. */ - BFD_RELOC_GPREL16, - BFD_RELOC_GPREL32, - -/* Reloc types used for i960/b.out. */ - BFD_RELOC_I960_CALLJ, - -/* SPARC ELF relocations. There is probably some overlap with other -relocation types already defined. */ - BFD_RELOC_NONE, - BFD_RELOC_SPARC_WDISP22, - BFD_RELOC_SPARC22, - BFD_RELOC_SPARC13, - BFD_RELOC_SPARC_GOT10, - BFD_RELOC_SPARC_GOT13, - BFD_RELOC_SPARC_GOT22, - BFD_RELOC_SPARC_PC10, - BFD_RELOC_SPARC_PC22, - BFD_RELOC_SPARC_WPLT30, - BFD_RELOC_SPARC_COPY, - BFD_RELOC_SPARC_GLOB_DAT, - BFD_RELOC_SPARC_JMP_SLOT, - BFD_RELOC_SPARC_RELATIVE, - BFD_RELOC_SPARC_UA32, - -/* I think these are specific to SPARC a.out (e.g., Sun 4). */ - BFD_RELOC_SPARC_BASE13, - BFD_RELOC_SPARC_BASE22, - -/* Some relocations we're using for SPARC V9 -- subject to change. */ -#define BFD_RELOC_SPARC_64 BFD_RELOC_64 - BFD_RELOC_SPARC_10, - BFD_RELOC_SPARC_11, - BFD_RELOC_SPARC_OLO10, - BFD_RELOC_SPARC_HH22, - BFD_RELOC_SPARC_HM10, - BFD_RELOC_SPARC_LM22, - BFD_RELOC_SPARC_PC_HH22, - BFD_RELOC_SPARC_PC_HM10, - BFD_RELOC_SPARC_PC_LM22, - BFD_RELOC_SPARC_WDISP16, - BFD_RELOC_SPARC_WDISP19, - BFD_RELOC_SPARC_GLOB_JMP, - BFD_RELOC_SPARC_7, - BFD_RELOC_SPARC_6, - BFD_RELOC_SPARC_5, - -/* Alpha ECOFF relocations. Some of these treat the symbol or "addend" -in some special way. -For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when -writing; when reading, it will be the absolute section symbol. The -addend is the displacement in bytes of the "lda" instruction from -the "ldah" instruction (which is at the address of this reloc). */ - BFD_RELOC_ALPHA_GPDISP_HI16, - -/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as -with GPDISP_HI16 relocs. The addend is ignored when writing the -relocations out, and is filled in with the file's GP value on -reading, for convenience. */ - BFD_RELOC_ALPHA_GPDISP_LO16, - -/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; -the assembler turns it into a LDQ instruction to load the address of -the symbol, and then fills in a register in the real instruction. - -The LITERAL reloc, at the LDQ instruction, refers to the .lita -section symbol. The addend is ignored when writing, but is filled -in with the file's GP value on reading, for convenience, as with the -GPDISP_LO16 reloc. - -The LITUSE reloc, on the instruction using the loaded address, gives -information to the linker that it might be able to use to optimize -away some literal section references. The symbol is ignored (read -as the absolute section symbol), and the "addend" indicates the type -of instruction using the register: -1 - "memory" fmt insn -2 - byte-manipulation (byte offset reg) -3 - jsr (target of branch) - -The GNU linker currently doesn't do any of this optimizing. */ - BFD_RELOC_ALPHA_LITERAL, - BFD_RELOC_ALPHA_LITUSE, - -/* The HINT relocation indicates a value that should be filled into the -"hint" field of a jmp/jsr/ret instruction, for possible branch- -prediction logic which may be provided on some processors. */ - BFD_RELOC_ALPHA_HINT, - -/* Bits 27..2 of the relocation address shifted right 2 bits; -simple reloc otherwise. */ - BFD_RELOC_MIPS_JMP, - -/* High 16 bits of 32-bit value; simple reloc. */ - BFD_RELOC_HI16, - -/* High 16 bits of 32-bit value but the low 16 bits will be sign -extended and added to form the final result. If the low 16 -bits form a negative number, we need to add one to the high value -to compensate for the borrow when the low bits are added. */ - BFD_RELOC_HI16_S, - -/* Low 16 bits. */ - BFD_RELOC_LO16, - -/* Like BFD_RELOC_HI16_S, but PC relative. */ - BFD_RELOC_PCREL_HI16_S, - -/* Like BFD_RELOC_LO16, but PC relative. */ - BFD_RELOC_PCREL_LO16, - -/* Relocation relative to the global pointer. */ -#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16 - -/* Relocation against a MIPS literal section. */ - BFD_RELOC_MIPS_LITERAL, - -/* MIPS ELF relocations. */ - BFD_RELOC_MIPS_GOT16, - BFD_RELOC_MIPS_CALL16, -#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32 - BFD_RELOC_MIPS_GOT_HI16, - BFD_RELOC_MIPS_GOT_LO16, - BFD_RELOC_MIPS_CALL_HI16, - BFD_RELOC_MIPS_CALL_LO16, - -/* i386/elf relocations */ - BFD_RELOC_386_GOT32, - BFD_RELOC_386_PLT32, - BFD_RELOC_386_COPY, - BFD_RELOC_386_GLOB_DAT, - BFD_RELOC_386_JUMP_SLOT, - BFD_RELOC_386_RELATIVE, - BFD_RELOC_386_GOTOFF, - BFD_RELOC_386_GOTPC, - -/* ns32k relocations */ - BFD_RELOC_NS32K_IMM_8, - BFD_RELOC_NS32K_IMM_16, - BFD_RELOC_NS32K_IMM_32, - BFD_RELOC_NS32K_IMM_8_PCREL, - BFD_RELOC_NS32K_IMM_16_PCREL, - BFD_RELOC_NS32K_IMM_32_PCREL, - BFD_RELOC_NS32K_DISP_8, - BFD_RELOC_NS32K_DISP_16, - BFD_RELOC_NS32K_DISP_32, - BFD_RELOC_NS32K_DISP_8_PCREL, - BFD_RELOC_NS32K_DISP_16_PCREL, - BFD_RELOC_NS32K_DISP_32_PCREL, - -/* Power(rs6000) and PowerPC relocations. */ - BFD_RELOC_PPC_B26, - BFD_RELOC_PPC_BA26, - BFD_RELOC_PPC_TOC16, - BFD_RELOC_PPC_B16, - BFD_RELOC_PPC_B16_BRTAKEN, - BFD_RELOC_PPC_B16_BRNTAKEN, - BFD_RELOC_PPC_BA16, - BFD_RELOC_PPC_BA16_BRTAKEN, - BFD_RELOC_PPC_BA16_BRNTAKEN, - BFD_RELOC_PPC_COPY, - BFD_RELOC_PPC_GLOB_DAT, - BFD_RELOC_PPC_JMP_SLOT, - BFD_RELOC_PPC_RELATIVE, - BFD_RELOC_PPC_LOCAL24PC, - BFD_RELOC_PPC_EMB_NADDR32, - BFD_RELOC_PPC_EMB_NADDR16, - BFD_RELOC_PPC_EMB_NADDR16_LO, - BFD_RELOC_PPC_EMB_NADDR16_HI, - BFD_RELOC_PPC_EMB_NADDR16_HA, - BFD_RELOC_PPC_EMB_SDAI16, - BFD_RELOC_PPC_EMB_SDA2I16, - BFD_RELOC_PPC_EMB_SDA2REL, - BFD_RELOC_PPC_EMB_SDA21, - BFD_RELOC_PPC_EMB_MRKREF, - BFD_RELOC_PPC_EMB_RELSEC16, - BFD_RELOC_PPC_EMB_RELST_LO, - BFD_RELOC_PPC_EMB_RELST_HI, - BFD_RELOC_PPC_EMB_RELST_HA, - BFD_RELOC_PPC_EMB_BIT_FLD, - BFD_RELOC_PPC_EMB_RELSDA, - -/* The type of reloc used to build a contructor table - at the moment -probably a 32 bit wide absolute relocation, but the target can choose. -It generally does map to one of the other relocation types. */ - BFD_RELOC_CTOR, - -/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are -not stored in the instruction. */ - BFD_RELOC_ARM_PCREL_BRANCH, - -/* These relocs are only used within the ARM assembler. They are not -(at present) written to any object files. */ - BFD_RELOC_ARM_IMMEDIATE, - BFD_RELOC_ARM_OFFSET_IMM, - BFD_RELOC_ARM_SHIFT_IMM, - BFD_RELOC_ARM_SWI, - BFD_RELOC_ARM_MULTI, - BFD_RELOC_ARM_CP_OFF_IMM, - BFD_RELOC_ARM_ADR_IMM, - BFD_RELOC_ARM_LDR_IMM, - BFD_RELOC_ARM_LITERAL, - BFD_RELOC_ARM_IN_POOL, - BFD_RELOC_UNUSED }; -typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; -reloc_howto_type * - -bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); - -const char * -bfd_get_reloc_code_name PARAMS ((bfd_reloc_code_real_type code)); - - -typedef struct symbol_cache_entry -{ - /* A pointer to the BFD which owns the symbol. This information - is necessary so that a back end can work out what additional - information (invisible to the application writer) is carried - with the symbol. - - This field is *almost* redundant, since you can use section->owner - instead, except that some symbols point to the global sections - bfd_{abs,com,und}_section. This could be fixed by making - these globals be per-bfd (or per-target-flavor). FIXME. */ - - struct _bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ - - /* The text of the symbol. The name is left alone, and not copied; the - application may not alter it. */ - CONST char *name; - - /* The value of the symbol. This really should be a union of a - numeric value with a pointer, since some flags indicate that - a pointer to another symbol is stored here. */ - symvalue value; - - /* Attributes of a symbol: */ - -#define BSF_NO_FLAGS 0x00 - - /* The symbol has local scope; <> in <>. The value - is the offset into the section of the data. */ -#define BSF_LOCAL 0x01 - - /* The symbol has global scope; initialized data in <>. The - value is the offset into the section of the data. */ -#define BSF_GLOBAL 0x02 - - /* The symbol has global scope and is exported. The value is - the offset into the section of the data. */ -#define BSF_EXPORT BSF_GLOBAL /* no real difference */ - - /* A normal C symbol would be one of: - <>, <>, <> or - <> */ - - /* The symbol is a debugging record. The value has an arbitary - meaning. */ -#define BSF_DEBUGGING 0x08 - - /* The symbol denotes a function entry point. Used in ELF, - perhaps others someday. */ -#define BSF_FUNCTION 0x10 - - /* Used by the linker. */ -#define BSF_KEEP 0x20 -#define BSF_KEEP_G 0x40 - - /* A weak global symbol, overridable without warnings by - a regular global symbol of the same name. */ -#define BSF_WEAK 0x80 - - /* This symbol was created to point to a section, e.g. ELF's - STT_SECTION symbols. */ -#define BSF_SECTION_SYM 0x100 - - /* The symbol used to be a common symbol, but now it is - allocated. */ -#define BSF_OLD_COMMON 0x200 - - /* The default value for common data. */ -#define BFD_FORT_COMM_DEFAULT_VALUE 0 - - /* In some files the type of a symbol sometimes alters its - location in an output file - ie in coff a <> symbol - which is also <> symbol appears where it was - declared and not at the end of a section. This bit is set - by the target BFD part to convey this information. */ - -#define BSF_NOT_AT_END 0x400 - - /* Signal that the symbol is the label of constructor section. */ -#define BSF_CONSTRUCTOR 0x800 - - /* Signal that the symbol is a warning symbol. The name is a - warning. The name of the next symbol is the one to warn about; - if a reference is made to a symbol with the same name as the next - symbol, a warning is issued by the linker. */ -#define BSF_WARNING 0x1000 - - /* Signal that the symbol is indirect. This symbol is an indirect - pointer to the symbol with the same name as the next symbol. */ -#define BSF_INDIRECT 0x2000 - - /* BSF_FILE marks symbols that contain a file name. This is used - for ELF STT_FILE symbols. */ -#define BSF_FILE 0x4000 - - /* Symbol is from dynamic linking information. */ -#define BSF_DYNAMIC 0x8000 - - /* The symbol denotes a data object. Used in ELF, and perhaps - others someday. */ -#define BSF_OBJECT 0x10000 - - flagword flags; - - /* A pointer to the section to which this symbol is - relative. This will always be non NULL, there are special - sections for undefined and absolute symbols. */ - struct sec *section; - - /* Back end special data. */ - union - { - PTR p; - bfd_vma i; - } udata; - -} asymbol; -#define bfd_get_symtab_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) -boolean -bfd_is_local_label PARAMS ((bfd *abfd, asymbol *sym)); - -#define bfd_is_local_label(abfd, sym) \ - BFD_SEND (abfd, _bfd_is_local_label,(abfd, sym)) -#define bfd_canonicalize_symtab(abfd, location) \ - BFD_SEND (abfd, _bfd_canonicalize_symtab,\ - (abfd, location)) -boolean -bfd_set_symtab PARAMS ((bfd *abfd, asymbol **location, unsigned int count)); - -void -bfd_print_symbol_vandf PARAMS ((PTR file, asymbol *symbol)); - -#define bfd_make_empty_symbol(abfd) \ - BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) -#define bfd_make_debug_symbol(abfd,ptr,size) \ - BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) -int -bfd_decode_symclass PARAMS ((asymbol *symbol)); - -void -bfd_symbol_info PARAMS ((asymbol *symbol, symbol_info *ret)); - -boolean -bfd_copy_private_symbol_data PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym)); - -#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ - BFD_SEND (ibfd, _bfd_copy_private_symbol_data, \ - (ibfd, isymbol, obfd, osymbol)) -struct _bfd -{ - /* The filename the application opened the BFD with. */ - CONST char *filename; - - /* A pointer to the target jump table. */ - const struct bfd_target *xvec; - - /* To avoid dragging too many header files into every file that - includes `<>', IOSTREAM has been declared as a "char - *", and MTIME as a "long". Their correct types, to which they - are cast when used, are "FILE *" and "time_t". The iostream - is the result of an fopen on the filename. However, if the - BFD_IN_MEMORY flag is set, then iostream is actually a pointer - to a bfd_in_memory struct. */ - PTR iostream; - - /* Is the file descriptor being cached? That is, can it be closed as - needed, and re-opened when accessed later? */ - - boolean cacheable; - - /* Marks whether there was a default target specified when the - BFD was opened. This is used to select which matching algorithm - to use to choose the back end. */ - - boolean target_defaulted; - - /* The caching routines use these to maintain a - least-recently-used list of BFDs */ - - struct _bfd *lru_prev, *lru_next; - - /* When a file is closed by the caching routines, BFD retains - state information on the file here: */ - - file_ptr where; - - /* and here: (``once'' means at least once) */ - - boolean opened_once; - - /* Set if we have a locally maintained mtime value, rather than - getting it from the file each time: */ - - boolean mtime_set; - - /* File modified time, if mtime_set is true: */ - - long mtime; - - /* Reserved for an unimplemented file locking extension.*/ - - int ifd; - - /* The format which belongs to the BFD. (object, core, etc.) */ - - bfd_format format; - - /* The direction the BFD was opened with*/ - - enum bfd_direction {no_direction = 0, - read_direction = 1, - write_direction = 2, - both_direction = 3} direction; - - /* Format_specific flags*/ - - flagword flags; - - /* Currently my_archive is tested before adding origin to - anything. I believe that this can become always an add of - origin, with origin set to 0 for non archive files. */ - - file_ptr origin; - - /* Remember when output has begun, to stop strange things - from happening. */ - boolean output_has_begun; - - /* Pointer to linked list of sections*/ - struct sec *sections; - - /* The number of sections */ - unsigned int section_count; - - /* Stuff only useful for object files: - The start address. */ - bfd_vma start_address; - - /* Used for input and output*/ - unsigned int symcount; - - /* Symbol table for output BFD (with symcount entries) */ - struct symbol_cache_entry **outsymbols; - - /* Pointer to structure which contains architecture information*/ - const struct bfd_arch_info *arch_info; - - /* Stuff only useful for archives:*/ - PTR arelt_data; - struct _bfd *my_archive; /* The containing archive BFD. */ - struct _bfd *next; /* The next BFD in the archive. */ - struct _bfd *archive_head; /* The first BFD in the archive. */ - boolean has_armap; - - /* A chain of BFD structures involved in a link. */ - struct _bfd *link_next; - - /* A field used by _bfd_generic_link_add_archive_symbols. This will - be used only for archive elements. */ - int archive_pass; - - /* Used by the back end to hold private data. */ - - union - { - struct aout_data_struct *aout_data; - struct artdata *aout_ar_data; - struct _oasys_data *oasys_obj_data; - struct _oasys_ar_data *oasys_ar_data; - struct coff_tdata *coff_obj_data; - struct pe_tdata *pe_obj_data; - struct xcoff_tdata *xcoff_obj_data; - struct ecoff_tdata *ecoff_obj_data; - struct ieee_data_struct *ieee_data; - struct ieee_ar_data_struct *ieee_ar_data; - struct srec_data_struct *srec_data; - struct ihex_data_struct *ihex_data; - struct tekhex_data_struct *tekhex_data; - struct elf_obj_tdata *elf_obj_data; - struct nlm_obj_tdata *nlm_obj_data; - struct bout_data_struct *bout_data; - struct sun_core_struct *sun_core_data; - struct trad_core_struct *trad_core_data; - struct som_data_struct *som_data; - struct hpux_core_struct *hpux_core_data; - struct hppabsd_core_struct *hppabsd_core_data; - struct sgi_core_struct *sgi_core_data; - struct lynx_core_struct *lynx_core_data; - struct osf_core_struct *osf_core_data; - struct cisco_core_struct *cisco_core_data; - struct versados_data_struct *versados_data; - struct netbsd_core_struct *netbsd_core_data; - PTR any; - } tdata; - - /* Used by the application to hold private data*/ - PTR usrdata; - - /* Where all the allocated stuff under this BFD goes */ - struct obstack memory; -}; - -typedef enum bfd_error -{ - bfd_error_no_error = 0, - bfd_error_system_call, - bfd_error_invalid_target, - bfd_error_wrong_format, - bfd_error_invalid_operation, - bfd_error_no_memory, - bfd_error_no_symbols, - bfd_error_no_armap, - bfd_error_no_more_archived_files, - bfd_error_malformed_archive, - bfd_error_file_not_recognized, - bfd_error_file_ambiguously_recognized, - bfd_error_no_contents, - bfd_error_nonrepresentable_section, - bfd_error_no_debug_section, - bfd_error_bad_value, - bfd_error_file_truncated, - bfd_error_file_too_big, - bfd_error_invalid_error_code -} bfd_error_type; - -bfd_error_type -bfd_get_error PARAMS ((void)); - -void -bfd_set_error PARAMS ((bfd_error_type error_tag)); - -CONST char * -bfd_errmsg PARAMS ((bfd_error_type error_tag)); - -void -bfd_perror PARAMS ((CONST char *message)); - -typedef void (*bfd_error_handler_type) PARAMS ((const char *, ...)); - -bfd_error_handler_type -bfd_set_error_handler PARAMS ((bfd_error_handler_type)); - -void -bfd_set_error_program_name PARAMS ((const char *)); - -long -bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect)); - -long -bfd_canonicalize_reloc - PARAMS ((bfd *abfd, - asection *sec, - arelent **loc, - asymbol **syms)); - -void -bfd_set_reloc - PARAMS ((bfd *abfd, asection *sec, arelent **rel, unsigned int count) - - ); - -boolean -bfd_set_file_flags PARAMS ((bfd *abfd, flagword flags)); - -boolean -bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma)); - -long -bfd_get_mtime PARAMS ((bfd *abfd)); - -long -bfd_get_size PARAMS ((bfd *abfd)); - -int -bfd_get_gp_size PARAMS ((bfd *abfd)); - -void -bfd_set_gp_size PARAMS ((bfd *abfd, int i)); - -bfd_vma -bfd_scan_vma PARAMS ((CONST char *string, CONST char **end, int base)); - -boolean -bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); - -#define bfd_copy_private_bfd_data(ibfd, obfd) \ - BFD_SEND (ibfd, _bfd_copy_private_bfd_data, \ - (ibfd, obfd)) -boolean -bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); - -#define bfd_merge_private_bfd_data(ibfd, obfd) \ - BFD_SEND (ibfd, _bfd_merge_private_bfd_data, \ - (ibfd, obfd)) -boolean -bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags)); - -#define bfd_set_private_flags(abfd, flags) \ - BFD_SEND (abfd, _bfd_set_private_flags, \ - (abfd, flags)) -#define bfd_sizeof_headers(abfd, reloc) \ - BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) - -#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ - BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line)) - - /* Do these three do anything useful at all, for any back end? */ -#define bfd_debug_info_start(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) - -#define bfd_debug_info_end(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) - -#define bfd_debug_info_accumulate(abfd, section) \ - BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) - - -#define bfd_stat_arch_elt(abfd, stat) \ - BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) - -#define bfd_update_armap_timestamp(abfd) \ - BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) - -#define bfd_set_arch_mach(abfd, arch, mach)\ - BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) - -#define bfd_relax_section(abfd, section, link_info, again) \ - BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) - -#define bfd_link_hash_table_create(abfd) \ - BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) - -#define bfd_link_add_symbols(abfd, info) \ - BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) - -#define bfd_final_link(abfd, info) \ - BFD_SEND (abfd, _bfd_final_link, (abfd, info)) - -#define bfd_free_cached_info(abfd) \ - BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) - -#define bfd_get_dynamic_symtab_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) - -#define bfd_print_private_bfd_data(abfd, file)\ - BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) - -#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ - BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) - -#define bfd_get_dynamic_reloc_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) - -#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ - BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) - -extern bfd_byte *bfd_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, - struct bfd_link_order *, bfd_byte *, - boolean, asymbol **)); - -symindex -bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym)); - -boolean -bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head)); - -bfd * -bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous)); - -CONST char * -bfd_core_file_failing_command PARAMS ((bfd *abfd)); - -int -bfd_core_file_failing_signal PARAMS ((bfd *abfd)); - -boolean -core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -#define BFD_SEND(bfd, message, arglist) \ - ((*((bfd)->xvec->message)) arglist) - -#ifdef DEBUG_BFD_SEND -#undef BFD_SEND -#define BFD_SEND(bfd, message, arglist) \ - (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ - ((*((bfd)->xvec->message)) arglist) : \ - (bfd_assert (__FILE__,__LINE__), NULL)) -#endif -#define BFD_SEND_FMT(bfd, message, arglist) \ - (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) - -#ifdef DEBUG_BFD_SEND -#undef BFD_SEND_FMT -#define BFD_SEND_FMT(bfd, message, arglist) \ - (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ - (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) : \ - (bfd_assert (__FILE__,__LINE__), NULL)) -#endif -enum bfd_flavour { - bfd_target_unknown_flavour, - bfd_target_aout_flavour, - bfd_target_coff_flavour, - bfd_target_ecoff_flavour, - bfd_target_elf_flavour, - bfd_target_ieee_flavour, - bfd_target_nlm_flavour, - bfd_target_oasys_flavour, - bfd_target_tekhex_flavour, - bfd_target_srec_flavour, - bfd_target_ihex_flavour, - bfd_target_som_flavour, - bfd_target_os9k_flavour, - bfd_target_versados_flavour, - bfd_target_msdos_flavour -}; - -enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; - - /* Forward declaration. */ -typedef struct bfd_link_info _bfd_link_info; - -typedef struct bfd_target -{ - char *name; - enum bfd_flavour flavour; - enum bfd_endian byteorder; - enum bfd_endian header_byteorder; - flagword object_flags; - flagword section_flags; - char symbol_leading_char; - char ar_pad_char; - unsigned short ar_max_namelen; - bfd_vma (*bfd_getx64) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *)); - void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_getx32) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *)); - void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_getx16) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *)); - void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_h_getx64) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *)); - void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_h_getx32) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *)); - void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_h_getx16) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *)); - void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *)); - const struct bfd_target *(*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *)); - boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *)); - boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *)); - - /* Generic entry points. */ -#define BFD_JUMP_TABLE_GENERIC(NAME)\ -CAT(NAME,_close_and_cleanup),\ -CAT(NAME,_bfd_free_cached_info),\ -CAT(NAME,_new_section_hook),\ -CAT(NAME,_get_section_contents),\ -CAT(NAME,_get_section_contents_in_window) - - /* Called when the BFD is being closed to do any necessary cleanup. */ - boolean (*_close_and_cleanup) PARAMS ((bfd *)); - /* Ask the BFD to free all cached information. */ - boolean (*_bfd_free_cached_info) PARAMS ((bfd *)); - /* Called when a new section is created. */ - boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr)); - /* Read the contents of a section. */ - boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); - boolean (*_bfd_get_section_contents_in_window) - PARAMS ((bfd *, sec_ptr, bfd_window *, - file_ptr, bfd_size_type)); - - /* Entry points to copy private data. */ -#define BFD_JUMP_TABLE_COPY(NAME)\ -CAT(NAME,_bfd_copy_private_bfd_data),\ -CAT(NAME,_bfd_merge_private_bfd_data),\ -CAT(NAME,_bfd_copy_private_section_data),\ -CAT(NAME,_bfd_copy_private_symbol_data),\ -CAT(NAME,_bfd_set_private_flags),\ -CAT(NAME,_bfd_print_private_bfd_data)\ - /* Called to copy BFD general private data from one object file - to another. */ - boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *)); - /* Called to merge BFD general private data from one object file - to a common output file when linking. */ - boolean (*_bfd_merge_private_bfd_data) PARAMS ((bfd *, bfd *)); - /* Called to copy BFD private section data from one object file - to another. */ - boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr, - bfd *, sec_ptr)); - /* Called to copy BFD private symbol data from one symbol - to another. */ - boolean (*_bfd_copy_private_symbol_data) PARAMS ((bfd *, asymbol *, - bfd *, asymbol *)); - /* Called to set private backend flags */ - boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword)); - - /* Called to print private BFD data */ - boolean (*_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR)); - - /* Core file entry points. */ -#define BFD_JUMP_TABLE_CORE(NAME)\ -CAT(NAME,_core_file_failing_command),\ -CAT(NAME,_core_file_failing_signal),\ -CAT(NAME,_core_file_matches_executable_p) - char * (*_core_file_failing_command) PARAMS ((bfd *)); - int (*_core_file_failing_signal) PARAMS ((bfd *)); - boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *)); - - /* Archive entry points. */ -#define BFD_JUMP_TABLE_ARCHIVE(NAME)\ -CAT(NAME,_slurp_armap),\ -CAT(NAME,_slurp_extended_name_table),\ -CAT(NAME,_construct_extended_name_table),\ -CAT(NAME,_truncate_arname),\ -CAT(NAME,_write_armap),\ -CAT(NAME,_read_ar_hdr),\ -CAT(NAME,_openr_next_archived_file),\ -CAT(NAME,_get_elt_at_index),\ -CAT(NAME,_generic_stat_arch_elt),\ -CAT(NAME,_update_armap_timestamp) - boolean (*_bfd_slurp_armap) PARAMS ((bfd *)); - boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *)); - boolean (*_bfd_construct_extended_name_table) - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); - void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *)); - boolean (*write_armap) PARAMS ((bfd *arch, - unsigned int elength, - struct orl *map, - unsigned int orl_count, - int stridx)); - PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *)); - bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); -#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i)) - bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex)); - int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); - boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *)); - - /* Entry points used for symbols. */ -#define BFD_JUMP_TABLE_SYMBOLS(NAME)\ -CAT(NAME,_get_symtab_upper_bound),\ -CAT(NAME,_get_symtab),\ -CAT(NAME,_make_empty_symbol),\ -CAT(NAME,_print_symbol),\ -CAT(NAME,_get_symbol_info),\ -CAT(NAME,_bfd_is_local_label),\ -CAT(NAME,_get_lineno),\ -CAT(NAME,_find_nearest_line),\ -CAT(NAME,_bfd_make_debug_symbol),\ -CAT(NAME,_read_minisymbols),\ -CAT(NAME,_minisymbol_to_symbol) - long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *)); - long (*_bfd_canonicalize_symtab) PARAMS ((bfd *, - struct symbol_cache_entry **)); - struct symbol_cache_entry * - (*_bfd_make_empty_symbol) PARAMS ((bfd *)); - void (*_bfd_print_symbol) PARAMS ((bfd *, PTR, - struct symbol_cache_entry *, - bfd_print_symbol_type)); -#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e)) - void (*_bfd_get_symbol_info) PARAMS ((bfd *, - struct symbol_cache_entry *, - symbol_info *)); -#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e)) - boolean (*_bfd_is_local_label) PARAMS ((bfd *, asymbol *)); - - alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *)); - boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd, - struct sec *section, struct symbol_cache_entry **symbols, - bfd_vma offset, CONST char **file, CONST char **func, - unsigned int *line)); - /* Back-door to allow format-aware applications to create debug symbols - while using BFD for everything else. Currently used by the assembler - when creating COFF files. */ - asymbol * (*_bfd_make_debug_symbol) PARAMS (( - bfd *abfd, - void *ptr, - unsigned long size)); -#define bfd_read_minisymbols(b, d, m, s) \ - BFD_SEND (b, _read_minisymbols, (b, d, m, s)) - long (*_read_minisymbols) PARAMS ((bfd *, boolean, PTR *, - unsigned int *)); -#define bfd_minisymbol_to_symbol(b, d, m, f) \ - BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) - asymbol *(*_minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR, - asymbol *)); - - /* Routines for relocs. */ -#define BFD_JUMP_TABLE_RELOCS(NAME)\ -CAT(NAME,_get_reloc_upper_bound),\ -CAT(NAME,_canonicalize_reloc),\ -CAT(NAME,_bfd_reloc_type_lookup) - long (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr)); - long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, - struct symbol_cache_entry **)); - /* See documentation on reloc types. */ - reloc_howto_type * - (*reloc_type_lookup) PARAMS ((bfd *abfd, - bfd_reloc_code_real_type code)); - - /* Routines used when writing an object file. */ -#define BFD_JUMP_TABLE_WRITE(NAME)\ -CAT(NAME,_set_arch_mach),\ -CAT(NAME,_set_section_contents) - boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); - boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); - - /* Routines used by the linker. */ -#define BFD_JUMP_TABLE_LINK(NAME)\ -CAT(NAME,_sizeof_headers),\ -CAT(NAME,_bfd_get_relocated_section_contents),\ -CAT(NAME,_bfd_relax_section),\ -CAT(NAME,_bfd_link_hash_table_create),\ -CAT(NAME,_bfd_link_add_symbols),\ -CAT(NAME,_bfd_final_link),\ -CAT(NAME,_bfd_link_split_section) - int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean)); - bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *, - struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *data, boolean relocateable, - struct symbol_cache_entry **)); - - boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *, - struct bfd_link_info *, boolean *again)); - - /* Create a hash table for the linker. Different backends store - different information in this table. */ - struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *)); - - /* Add symbols from this object file into the hash table. */ - boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *)); - - /* Do a link based on the link_order structures attached to each - section of the BFD. */ - boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *)); - - /* Should this section be split up into smaller pieces during linking. */ - boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *)); - - /* Routines to handle dynamic symbols and relocs. */ -#define BFD_JUMP_TABLE_DYNAMIC(NAME)\ -CAT(NAME,_get_dynamic_symtab_upper_bound),\ -CAT(NAME,_canonicalize_dynamic_symtab),\ -CAT(NAME,_get_dynamic_reloc_upper_bound),\ -CAT(NAME,_canonicalize_dynamic_reloc) - /* Get the amount of memory required to hold the dynamic symbols. */ - long (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *)); - /* Read in the dynamic symbols. */ - long (*_bfd_canonicalize_dynamic_symtab) - PARAMS ((bfd *, struct symbol_cache_entry **)); - /* Get the amount of memory required to hold the dynamic relocs. */ - long (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *)); - /* Read in the dynamic relocs. */ - long (*_bfd_canonicalize_dynamic_reloc) - PARAMS ((bfd *, arelent **, struct symbol_cache_entry **)); - - PTR backend_data; -} bfd_target; -const bfd_target * -bfd_find_target PARAMS ((CONST char *target_name, bfd *abfd)); - -const char ** -bfd_target_list PARAMS ((void)); - -boolean -bfd_check_format PARAMS ((bfd *abfd, bfd_format format)); - -boolean -bfd_check_format_matches PARAMS ((bfd *abfd, bfd_format format, char ***matching)); - -boolean -bfd_set_format PARAMS ((bfd *abfd, bfd_format format)); - -CONST char * -bfd_format_string PARAMS ((bfd_format format)); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/contrib/gdb/bfd/bfd.c b/contrib/gdb/bfd/bfd.c deleted file mode 100644 index 10ec67efaa6..00000000000 --- a/contrib/gdb/bfd/bfd.c +++ /dev/null @@ -1,1144 +0,0 @@ -/* Generic BFD library interface and support routines. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - <> - - A BFD has type <>; 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 structure that defines the type <>. It - contains the major data about the file and pointers - to the rest of the data. - -CODE_FRAGMENT -. -.struct _bfd -.{ -. {* The filename the application opened the BFD with. *} -. CONST char *filename; -. -. {* A pointer to the target jump table. *} -. const struct bfd_target *xvec; -. -. {* To avoid dragging too many header files into every file that -. includes `<>', IOSTREAM has been declared as a "char -. *", and MTIME as a "long". Their correct types, to which they -. are cast when used, are "FILE *" and "time_t". The iostream -. is the result of an fopen on the filename. However, if the -. BFD_IN_MEMORY flag is set, then iostream is actually a pointer -. to a bfd_in_memory struct. *} -. PTR iostream; -. -. {* Is the file descriptor being cached? That is, can it be closed as -. needed, and re-opened when accessed later? *} -. -. boolean cacheable; -. -. {* Marks whether there was a default target specified when the -. BFD was opened. This is used to select which matching algorithm -. to use to choose the back end. *} -. -. boolean target_defaulted; -. -. {* The caching routines use these to maintain a -. least-recently-used list of BFDs *} -. -. struct _bfd *lru_prev, *lru_next; -. -. {* When a file is closed by the caching routines, BFD retains -. state information on the file here: *} -. -. file_ptr where; -. -. {* and here: (``once'' means at least once) *} -. -. boolean opened_once; -. -. {* Set if we have a locally maintained mtime value, rather than -. getting it from the file each time: *} -. -. boolean mtime_set; -. -. {* File modified time, if mtime_set is true: *} -. -. long mtime; -. -. {* Reserved for an unimplemented file locking extension.*} -. -. int ifd; -. -. {* The format which belongs to the BFD. (object, core, etc.) *} -. -. bfd_format format; -. -. {* The direction the BFD was opened with*} -. -. enum bfd_direction {no_direction = 0, -. read_direction = 1, -. write_direction = 2, -. both_direction = 3} direction; -. -. {* Format_specific flags*} -. -. flagword flags; -. -. {* Currently my_archive is tested before adding origin to -. anything. I believe that this can become always an add of -. origin, with origin set to 0 for non archive files. *} -. -. file_ptr origin; -. -. {* Remember when output has begun, to stop strange things -. from happening. *} -. boolean output_has_begun; -. -. {* Pointer to linked list of sections*} -. struct sec *sections; -. -. {* The number of sections *} -. unsigned int section_count; -. -. {* Stuff only useful for object files: -. The start address. *} -. bfd_vma start_address; -. -. {* Used for input and output*} -. unsigned int symcount; -. -. {* Symbol table for output BFD (with symcount entries) *} -. struct symbol_cache_entry **outsymbols; -. -. {* Pointer to structure which contains architecture information*} -. const struct bfd_arch_info *arch_info; -. -. {* Stuff only useful for archives:*} -. PTR arelt_data; -. struct _bfd *my_archive; {* The containing archive BFD. *} -. struct _bfd *next; {* The next BFD in the archive. *} -. struct _bfd *archive_head; {* The first BFD in the archive. *} -. boolean has_armap; -. -. {* A chain of BFD structures involved in a link. *} -. struct _bfd *link_next; -. -. {* A field used by _bfd_generic_link_add_archive_symbols. This will -. be used only for archive elements. *} -. int archive_pass; -. -. {* Used by the back end to hold private data. *} -. -. union -. { -. struct aout_data_struct *aout_data; -. struct artdata *aout_ar_data; -. struct _oasys_data *oasys_obj_data; -. struct _oasys_ar_data *oasys_ar_data; -. struct coff_tdata *coff_obj_data; -. struct pe_tdata *pe_obj_data; -. struct xcoff_tdata *xcoff_obj_data; -. struct ecoff_tdata *ecoff_obj_data; -. struct ieee_data_struct *ieee_data; -. struct ieee_ar_data_struct *ieee_ar_data; -. struct srec_data_struct *srec_data; -. struct ihex_data_struct *ihex_data; -. struct tekhex_data_struct *tekhex_data; -. struct elf_obj_tdata *elf_obj_data; -. struct nlm_obj_tdata *nlm_obj_data; -. struct bout_data_struct *bout_data; -. struct sun_core_struct *sun_core_data; -. struct trad_core_struct *trad_core_data; -. struct som_data_struct *som_data; -. struct hpux_core_struct *hpux_core_data; -. struct hppabsd_core_struct *hppabsd_core_data; -. struct sgi_core_struct *sgi_core_data; -. struct lynx_core_struct *lynx_core_data; -. struct osf_core_struct *osf_core_data; -. struct cisco_core_struct *cisco_core_data; -. struct versados_data_struct *versados_data; -. struct netbsd_core_struct *netbsd_core_data; -. PTR any; -. } tdata; -. -. {* Used by the application to hold private data*} -. PTR usrdata; -. -. {* Where all the allocated stuff under this BFD goes *} -. struct obstack memory; -.}; -. -*/ - -#include "bfd.h" -#include "sysdep.h" - -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "libcoff.h" -#include "libecoff.h" -#undef obj_symbols -#include "elf-bfd.h" - -#include - -/* provide storage for subsystem, stack and heap data which may have been - passed in on the command line. Ld puts this data into a bfd_link_info - struct which ultimately gets passed in to the bfd. When it arrives, copy - it to the following struct so that the data will be available in coffcode.h - where it is needed. The typedef's used are defined in bfd.h */ - - - -/* -SECTION - Error reporting - - Most BFD functions return nonzero on success (check their - individual documentation for precise semantics). On an error, - they call <> to set an error condition that callers - can check by calling <>. - If that returns <>, then check - <>. - - The easiest way to report a BFD error to the user is to - use <>. - -SUBSECTION - Type <> - - The values returned by <> are defined by the - enumerated 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_armap, -. bfd_error_no_more_archived_files, -. bfd_error_malformed_archive, -. bfd_error_file_not_recognized, -. bfd_error_file_ambiguously_recognized, -. bfd_error_no_contents, -. bfd_error_nonrepresentable_section, -. bfd_error_no_debug_section, -. bfd_error_bad_value, -. bfd_error_file_truncated, -. bfd_error_file_too_big, -. bfd_error_invalid_error_code -.} bfd_error_type; -. -*/ - -#undef strerror -extern char *strerror(); - -static bfd_error_type bfd_error = bfd_error_no_error; - -CONST char *CONST bfd_errmsgs[] = { - "No error", - "System call error", - "Invalid bfd target", - "File in wrong format", - "Invalid operation", - "Memory exhausted", - "No symbols", - "Archive has no index; run ranlib to add one", - "No more archived files", - "Malformed archive", - "File format not recognized", - "File format is ambiguous", - "Section has no contents", - "Nonrepresentable section on output", - "Symbol needs debug section which does not exist", - "Bad value", - "File truncated", - "File too big", - "#" - }; - -/* -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 () -{ - return bfd_error; -} - -/* -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; -{ - bfd_error = error_tag; -} - -/* -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 <>. -*/ - -CONST char * -bfd_errmsg (error_tag) - bfd_error_type error_tag; -{ -#ifndef errno - extern int errno; -#endif - if (error_tag == bfd_error_system_call) - { - const char *errmsg; - - errmsg = strerror (errno); - if (errmsg == NULL) - { - static char buf[32]; - - sprintf (buf, "Error %d", errno); - errmsg = buf; - } - return errmsg; - } - - 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]; -} - -/* -FUNCTION - bfd_perror - -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 -bfd_perror (message) - CONST char *message; -{ - 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_get_error ())); - else - fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ())); - } -} - -/* -SUBSECTION - BFD error handler - - Some BFD functions want to print messages describing the - problem. They call a BFD error handler function. This - function may be overriden by the program. - - The BFD error handler acts like printf. - -CODE_FRAGMENT -. -.typedef void (*bfd_error_handler_type) PARAMS ((const char *, ...)); -. -*/ - -/* The program name used when printing BFD error messages. */ - -static const char *_bfd_error_program_name; - -/* This is the default routine to handle BFD error messages. */ - -#ifdef ANSI_PROTOTYPES - -static void _bfd_default_error_handler PARAMS ((const char *s, ...)); - -static void -_bfd_default_error_handler (const char *s, ...) -{ - va_list p; - - if (_bfd_error_program_name != NULL) - fprintf (stderr, "%s: ", _bfd_error_program_name); - - va_start (p, s); - - vfprintf (stderr, s, p); - - va_end (p); - - fprintf (stderr, "\n"); -} - -#else /* ! defined (ANSI_PROTOTYPES) */ - -static void _bfd_default_error_handler (); - -static void -_bfd_default_error_handler (va_alist) - va_dcl -{ - va_list p; - const char *s; - - if (_bfd_error_program_name != NULL) - fprintf (stderr, "%s: ", _bfd_error_program_name); - - va_start (p); - - s = va_arg (p, const char *); - vfprintf (stderr, s, p); - - va_end (p); - - fprintf (stderr, "\n"); -} - -#endif /* ! defined (ANSI_PROTOTYPES) */ - -/* This is a function pointer to the routine which should handle BFD - error messages. It is called when a BFD routine encounters an - error for which it wants to print a message. Going through a - function pointer permits a program linked against BFD to intercept - the messages and deal with them itself. */ - -bfd_error_handler_type _bfd_error_handler = _bfd_default_error_handler; - -/* -FUNCTION - bfd_set_error_handler - -SYNOPSIS - bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); - -DESCRIPTION - Set the BFD error handler function. Returns the previous - function. -*/ - -bfd_error_handler_type -bfd_set_error_handler (pnew) - bfd_error_handler_type pnew; -{ - bfd_error_handler_type pold; - - pold = _bfd_error_handler; - _bfd_error_handler = pnew; - return pold; -} - -/* -FUNCTION - bfd_set_error_program_name - -SYNOPSIS - void bfd_set_error_program_name (const char *); - -DESCRIPTION - Set the program name to use when printing a BFD error. This - is printed before the error message followed by a colon and - space. The string must not be changed after it is passed to - this function. -*/ - -void -bfd_set_error_program_name (name) - const char *name; -{ - _bfd_error_program_name = name; -} - -/* -SECTION - Symbols -*/ - -/* -FUNCTION - bfd_get_reloc_upper_bound - -SYNOPSIS - long bfd_get_reloc_upper_bound(bfd *abfd, asection *sect); - -DESCRIPTION - 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. - -*/ - - -long -bfd_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (abfd->format != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect)); -} - -/* -FUNCTION - bfd_canonicalize_reloc - -SYNOPSIS - long bfd_canonicalize_reloc - (bfd *abfd, - asection *sec, - arelent **loc, - asymbol **syms); - -DESCRIPTION - 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 - <>. Returns the number of relocs, or - -1 on error. - - The @var{syms} table is also needed for horrible internal magic - reasons. - - -*/ -long -bfd_canonicalize_reloc (abfd, asect, location, symbols) - bfd *abfd; - sec_ptr asect; - arelent **location; - asymbol **symbols; -{ - if (abfd->format != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - return BFD_SEND (abfd, _bfd_canonicalize_reloc, - (abfd, asect, location, symbols)); -} - -/* -FUNCTION - bfd_set_reloc - -SYNOPSIS - void bfd_set_reloc - (bfd *abfd, asection *sec, arelent **rel, unsigned int count) - -DESCRIPTION - 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*/ -void -bfd_set_reloc (ignore_abfd, asect, location, count) - bfd *ignore_abfd; - sec_ptr asect; - arelent **location; - unsigned int count; -{ - asect->orelocation = location; - asect->reloc_count = count; -} - -/* -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 <> - The target bfd was not of object format. - o <> - The target bfd was open for reading. - o <> - - The flag word contained a bit which was not applicable to the - type of file. E.g., an attempt was made to set the <> 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) - const char *file; - int line; -{ - (*_bfd_error_handler) ("bfd assertion fail %s:%d", file, line); -} - - -/* -FUNCTION - bfd_set_start_address - -SYNOPSIS - boolean bfd_set_start_address(bfd *abfd, bfd_vma vma); - -DESCRIPTION - Make @var{vma} the entry point of output BFD @var{abfd}. - -RETURNS - Returns <> on success, <> otherwise. -*/ - -boolean -bfd_set_start_address(abfd, vma) -bfd *abfd; -bfd_vma vma; -{ - abfd->start_address = vma; - return true; -} - - -/* -FUNCTION - bfd_get_mtime - -SYNOPSIS - long bfd_get_mtime(bfd *abfd); - -DESCRIPTION - Return the file modification time (as read from the file system, or - from the archive header for archive members). - -*/ - -long -bfd_get_mtime (abfd) - bfd *abfd; -{ - FILE *fp; - struct stat buf; - - if (abfd->mtime_set) - return abfd->mtime; - - fp = bfd_cache_lookup (abfd); - if (0 != fstat (fileno (fp), &buf)) - return 0; - - abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */ - return buf.st_mtime; -} - -/* -FUNCTION - bfd_get_size - -SYNOPSIS - long bfd_get_size(bfd *abfd); - -DESCRIPTION - Return the file size (as read from file system) for the file - associated with BFD @var{abfd}. - - 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 do this, some object formats - use string tables for which the first <> bytes of the - table contain the size of the table itself, including the size bytes. - If an application tries to read what it thinks is one of these - string tables, without some way to validate the size, and for - some reason the size is wrong (byte swapping error, wrong location - for the string table, etc.), the only clue is likely to be a read - error when it tries to read the table, or a "virtual memory - exhausted" error when it tries to 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?". -*/ - -long -bfd_get_size (abfd) - bfd *abfd; -{ - FILE *fp; - struct stat buf; - - if ((abfd->flags & BFD_IN_MEMORY) != 0) - return ((struct bfd_in_memory *) abfd->iostream)->size; - - fp = bfd_cache_lookup (abfd); - if (0 != fstat (fileno (fp), &buf)) - return 0; - - return buf.st_size; -} - -/* -FUNCTION - bfd_get_gp_size - -SYNOPSIS - int bfd_get_gp_size(bfd *abfd); - -DESCRIPTION - 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. -*/ - -int -bfd_get_gp_size (abfd) - bfd *abfd; -{ - 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 - bfd_set_gp_size - -SYNOPSIS - 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. -*/ - -void -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) - elf_gp_size (abfd) = i; -} - -/* Get the GP value. This is an internal function used by some of the - relocation special_function routines on targets which support a GP - register. */ - -bfd_vma -_bfd_get_gp_value (abfd) - bfd *abfd; -{ - if (abfd->format == bfd_object) - { - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - return ecoff_data (abfd)->gp; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - return elf_gp (abfd); - } - return 0; -} - -/* Set the GP value. */ - -void -_bfd_set_gp_value (abfd, v) - bfd *abfd; - bfd_vma v; -{ - if (abfd->format != bfd_object) - return; - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - ecoff_data (abfd)->gp = v; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - elf_gp (abfd) = v; -} - -/* -FUNCTION - bfd_scan_vma - -SYNOPSIS - bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base); - -DESCRIPTION - Convert, like <>, a numerical expression - @var{string} into a <> integer, and return that integer. - (Though without as many bells and whistles as <>.) - 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. -*/ - -bfd_vma -bfd_scan_vma (string, end, base) - CONST char *string; - CONST char **end; - int base; -{ - bfd_vma value; - int digit; - - /* Let the host do it if possible. */ - if (sizeof(bfd_vma) <= sizeof(unsigned long)) - return (bfd_vma) strtoul (string, (char **) end, base); - - /* A negative base makes no sense, and we only need to go as high as hex. */ - if ((base < 0) || (base > 16)) - return (bfd_vma) 0; - - if (base == 0) - { - if (string[0] == '0') - { - if ((string[1] == 'x') || (string[1] == 'X')) - base = 16; - /* XXX should we also allow "0b" or "0B" to set base to 2? */ - else - base = 8; - } - else - base = 10; - } - if ((base == 16) && - (string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) - string += 2; - /* XXX should we also skip over "0b" or "0B" if base is 2? */ - -/* Speed could be improved with a table like hex_value[] in gas. */ -#define HEX_VALUE(c) \ - (isxdigit(c) ? \ - (isdigit(c) ? \ - (c - '0') : \ - (10 + c - (islower(c) ? 'a' : 'A'))) : \ - 42) - - for (value = 0; (digit = HEX_VALUE(*string)) < base; string++) - { - value = value * base + digit; - } - - if (end) - *end = string; - - return value; -} - -/* -FUNCTION - 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 <> on success, <> on error. - Possible error returns are: - - o <> - - 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 - bfd_merge_private_bfd_data - -SYNOPSIS - boolean bfd_merge_private_bfd_data(bfd *ibfd, bfd *obfd); - -DESCRIPTION - Merge private BFD information from the BFD @var{ibfd} to the - the output file BFD @var{obfd} when linking. Return <> - on success, <> on error. Possible error returns are: - - o <> - - Not enough memory exists to create private data for @var{obfd}. - -.#define bfd_merge_private_bfd_data(ibfd, obfd) \ -. BFD_SEND (ibfd, _bfd_merge_private_bfd_data, \ -. (ibfd, obfd)) - -*/ - -/* -FUNCTION - bfd_set_private_flags - -SYNOPSIS - boolean bfd_set_private_flags(bfd *abfd, flagword flags); - -DESCRIPTION - Set private BFD flag information in the BFD @var{abfd}. - Return <> on success, <> on error. Possible error - returns are: - - o <> - - Not enough memory exists to create private data for @var{obfd}. - -.#define bfd_set_private_flags(abfd, flags) \ -. BFD_SEND (abfd, _bfd_set_private_flags, \ -. (abfd, flags)) - -*/ - -/* -FUNCTION - stuff - -DESCRIPTION - Stuff which should be documented: - -.#define bfd_sizeof_headers(abfd, reloc) \ -. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) -. -.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ -. BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line)) -. -. {* Do these three do anything useful at all, for any back end? *} -.#define bfd_debug_info_start(abfd) \ -. BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) -. -.#define bfd_debug_info_end(abfd) \ -. BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) -. -.#define bfd_debug_info_accumulate(abfd, section) \ -. BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) -. -. -.#define bfd_stat_arch_elt(abfd, stat) \ -. BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) -. -.#define bfd_update_armap_timestamp(abfd) \ -. BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) -. -.#define bfd_set_arch_mach(abfd, arch, mach)\ -. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) -. -.#define bfd_relax_section(abfd, section, link_info, again) \ -. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) -. -.#define bfd_link_hash_table_create(abfd) \ -. BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) -. -.#define bfd_link_add_symbols(abfd, info) \ -. BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) -. -.#define bfd_final_link(abfd, info) \ -. BFD_SEND (abfd, _bfd_final_link, (abfd, info)) -. -.#define bfd_free_cached_info(abfd) \ -. BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) -. -.#define bfd_get_dynamic_symtab_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) -. -.#define bfd_print_private_bfd_data(abfd, file)\ -. BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) -. -.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ -. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) -. -.#define bfd_get_dynamic_reloc_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) -. -.#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ -. BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) -. -.extern bfd_byte *bfd_get_relocated_section_contents -. PARAMS ((bfd *, struct bfd_link_info *, -. struct bfd_link_order *, bfd_byte *, -. boolean, asymbol **)); -. - -*/ - -bfd_byte * -bfd_get_relocated_section_contents (abfd, link_info, link_order, data, - relocateable, symbols) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - bfd *abfd2; - bfd_byte *(*fn) PARAMS ((bfd *, struct bfd_link_info *, - struct bfd_link_order *, bfd_byte *, boolean, - asymbol **)); - - if (link_order->type == bfd_indirect_link_order) - { - abfd2 = link_order->u.indirect.section->owner; - if (abfd2 == 0) - abfd2 = abfd; - } - else - abfd2 = abfd; - fn = abfd2->xvec->_bfd_get_relocated_section_contents; - - return (*fn) (abfd, link_info, link_order, data, relocateable, symbols); -} - -/* Record information about an ELF program header. */ - -boolean -bfd_record_phdr (abfd, type, flags_valid, flags, at_valid, at, - includes_filehdr, includes_phdrs, count, secs) - bfd *abfd; - unsigned long type; - boolean flags_valid; - flagword flags; - boolean at_valid; - bfd_vma at; - boolean includes_filehdr; - boolean includes_phdrs; - unsigned int count; - asection **secs; -{ - struct elf_segment_map *m, **pm; - - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - return true; - - m = ((struct elf_segment_map *) - bfd_alloc (abfd, - (sizeof (struct elf_segment_map) - + (count - 1) * sizeof (asection *)))); - if (m == NULL) - return false; - - m->next = NULL; - m->p_type = type; - m->p_flags = flags; - m->p_paddr = at; - m->p_flags_valid = flags_valid; - m->p_paddr_valid = at_valid; - m->includes_filehdr = includes_filehdr; - m->includes_phdrs = includes_phdrs; - m->count = count; - if (count > 0) - memcpy (m->sections, secs, count * sizeof (asection *)); - - for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next) - ; - *pm = m; - - return true; -} diff --git a/contrib/gdb/bfd/binary.c b/contrib/gdb/bfd/binary.c deleted file mode 100644 index a480e464e96..00000000000 --- a/contrib/gdb/bfd/binary.c +++ /dev/null @@ -1,348 +0,0 @@ -/* BFD back-end for binary objects. - Copyright 1994 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support, - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This is a BFD backend which may be used to write binary objects. - It may only be used for output, not input. The intention is that - this may be used as an output format for objcopy in order to - generate raw binary data. - - This is very simple. The only complication is that the real data - will start at some address X, and in some cases we will not want to - include X zeroes just to get to that point. Since the start - address is not meaningful for this object file format, we use it - instead to indicate the number of zeroes to skip at the start of - the file. objcopy cooperates by specially setting the start - address to zero by default. */ - -#include - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* Any bfd we create by reading a binary file has three symbols: - a start symbol, an end symbol, and an absolute length symbol. */ -#define BIN_SYMS 3 - -static boolean binary_mkobject PARAMS ((bfd *)); -static const bfd_target *binary_object_p PARAMS ((bfd *)); -static boolean binary_get_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); -static long binary_get_symtab_upper_bound PARAMS ((bfd *)); -static char *mangle_name PARAMS ((bfd *, char *)); -static long binary_get_symtab PARAMS ((bfd *, asymbol **)); -static asymbol *binary_make_empty_symbol PARAMS ((bfd *)); -static void binary_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); -static boolean binary_set_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); -static int binary_sizeof_headers PARAMS ((bfd *, boolean)); - -/* Create a binary object. Invoked via bfd_set_format. */ - -static boolean -binary_mkobject (abfd) - bfd *abfd; -{ - return true; -} - -/* Any file may be considered to be a binary file, provided the target - was not defaulted. That is, it must be explicitly specified as - being binary. */ - -static const bfd_target * -binary_object_p (abfd) - bfd *abfd; -{ - struct stat statbuf; - asection *sec; - - if (abfd->target_defaulted) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - abfd->symcount = BIN_SYMS; - - /* Find the file size. */ - if (bfd_stat (abfd, &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - /* One data section. */ - sec = bfd_make_section (abfd, ".data"); - if (sec == NULL) - return NULL; - sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS; - sec->vma = 0; - sec->_raw_size = statbuf.st_size; - sec->filepos = 0; - - abfd->tdata.any = (PTR) sec; - - return abfd->xvec; -} - -#define binary_close_and_cleanup _bfd_generic_close_and_cleanup -#define binary_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define binary_new_section_hook _bfd_generic_new_section_hook - -/* Get contents of the only section. */ - -static boolean -binary_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (bfd_seek (abfd, offset, SEEK_SET) != 0 - || bfd_read (location, 1, count, abfd) != count) - return false; - return true; -} - -/* Return the amount of memory needed to read the symbol table. */ - -static long -binary_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - return (BIN_SYMS + 1) * sizeof (asymbol *); -} - -/* Create a symbol name based on the bfd's filename. */ - -static char * -mangle_name (abfd, suffix) - bfd *abfd; - char *suffix; -{ - int size; - char *buf; - char *p; - - size = (strlen (bfd_get_filename (abfd)) - + strlen (suffix) - + sizeof "_binary__"); - - buf = (char *) bfd_alloc (abfd, size); - if (buf == NULL) - return ""; - - sprintf (buf, "_binary_%s_%s", bfd_get_filename (abfd), suffix); - - /* Change any non-alphanumeric characters to underscores. */ - for (p = buf; *p; p++) - if (! isalnum (*p)) - *p = '_'; - - return buf; -} - -/* Return the symbol table. */ - -static long -binary_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - asection *sec = (asection *) abfd->tdata.any; - asymbol *syms; - unsigned int i; - - syms = (asymbol *) bfd_alloc (abfd, BIN_SYMS * sizeof (asymbol)); - if (syms == NULL) - return false; - - /* Start symbol. */ - syms[0].the_bfd = abfd; - syms[0].name = mangle_name (abfd, "start"); - syms[0].value = 0; - syms[0].flags = BSF_GLOBAL; - syms[0].section = sec; - syms[0].udata.p = NULL; - - /* End symbol. */ - syms[1].the_bfd = abfd; - syms[1].name = mangle_name (abfd, "end"); - syms[1].value = sec->_raw_size; - syms[1].flags = BSF_GLOBAL; - syms[1].section = sec; - syms[1].udata.p = NULL; - - /* Size symbol. */ - syms[2].the_bfd = abfd; - syms[2].name = mangle_name (abfd, "size"); - syms[2].value = sec->_raw_size; - syms[2].flags = BSF_GLOBAL; - syms[2].section = bfd_abs_section_ptr; - syms[2].udata.p = NULL; - - for (i = 0; i < BIN_SYMS; i++) - *alocation++ = syms++; - *alocation = NULL; - - return BIN_SYMS; -} - -/* Make an empty symbol. */ - -static asymbol * -binary_make_empty_symbol (abfd) - bfd *abfd; -{ - return (asymbol *) bfd_alloc (abfd, sizeof (asymbol)); -} - -#define binary_print_symbol _bfd_nosymbols_print_symbol - -/* Get information about a symbol. */ - -static void -binary_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -#define binary_bfd_is_local_label bfd_generic_is_local_label -#define binary_get_lineno _bfd_nosymbols_get_lineno -#define binary_find_nearest_line _bfd_nosymbols_find_nearest_line -#define binary_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define binary_read_minisymbols _bfd_generic_read_minisymbols -#define binary_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define binary_get_reloc_upper_bound \ - ((long (*) PARAMS ((bfd *, asection *))) bfd_0l) -#define binary_canonicalize_reloc \ - ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l) -#define binary_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -/* Set the architecture of a binary file. */ -#define binary_set_arch_mach _bfd_generic_set_arch_mach - -/* Write section contents of a binary file. */ - -static boolean -binary_set_section_contents (abfd, sec, data, offset, size) - bfd *abfd; - asection *sec; - PTR data; - file_ptr offset; - bfd_size_type size; -{ - if (! abfd->output_has_begun) - { - bfd_vma low; - asection *s; - - /* The lowest section VMA sets the virtual address of the start - of the file. We use the set the file position of all the - sections. */ - low = abfd->sections->vma; - for (s = abfd->sections->next; s != NULL; s = s->next) - if (s->vma < low) - low = s->vma; - - for (s = abfd->sections; s != NULL; s = s->next) - s->filepos = s->vma - low; - - abfd->output_has_begun = true; - } - - return _bfd_generic_set_section_contents (abfd, sec, data, offset, size); -} - -/* No space is required for header information. */ - -static int -binary_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -#define binary_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define binary_bfd_relax_section bfd_generic_relax_section -#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define binary_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define binary_bfd_final_link _bfd_generic_final_link -#define binary_bfd_link_split_section _bfd_generic_link_split_section -#define binary_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -const bfd_target binary_vec = -{ - "binary", /* name */ - bfd_target_unknown_flavour, /* flavour */ - BFD_ENDIAN_UNKNOWN, /* byteorder */ - BFD_ENDIAN_UNKNOWN, /* header_byteorder */ - EXEC_P, /* object_flags */ - (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA - | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */ - 0, /* symbol_leading_char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - { /* bfd_check_format */ - _bfd_dummy_target, - binary_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { /* bfd_set_format */ - bfd_false, - binary_mkobject, - bfd_false, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - bfd_true, - bfd_false, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (binary), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (binary), - BFD_JUMP_TABLE_RELOCS (binary), - BFD_JUMP_TABLE_WRITE (binary), - BFD_JUMP_TABLE_LINK (binary), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - NULL -}; diff --git a/contrib/gdb/bfd/bout.c b/contrib/gdb/bfd/bout.c deleted file mode 100644 index 9da4b825b02..00000000000 --- a/contrib/gdb/bfd/bout.c +++ /dev/null @@ -1,1471 +0,0 @@ -/* BFD back-end for Intel 960 b.out binaries. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "bout.h" - -#include "aout/stab_gnu.h" -#include "libaout.h" /* BFD a.out internal data structures */ - - -static int aligncode PARAMS ((bfd *abfd, asection *input_section, - arelent *r, unsigned int shrink)); -static void perform_slip PARAMS ((bfd *abfd, unsigned int slip, - asection *input_section, bfd_vma value)); -static boolean b_out_squirt_out_relocs PARAMS ((bfd *abfd, asection *section)); -static const bfd_target *b_out_callback PARAMS ((bfd *)); -static bfd_reloc_status_type calljx_callback - PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR src, PTR dst, - asection *)); -static bfd_reloc_status_type callj_callback - PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR data, - unsigned int srcidx, unsigned int dstidx, asection *, boolean)); -static bfd_vma get_value PARAMS ((arelent *, struct bfd_link_info *, - asection *)); -static int abs32code PARAMS ((bfd *, asection *, arelent *, - unsigned int, struct bfd_link_info *)); -static boolean b_out_bfd_relax_section PARAMS ((bfd *, asection *, - struct bfd_link_info *, - boolean *)); -static bfd_byte *b_out_bfd_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); - -/* Swaps the information in an executable header taken from a raw byte - stream memory image, into the internal exec_header structure. */ - -void -bout_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); - execp->a_tload = GET_WORD (abfd, bytes->e_tload); - execp->a_dload = GET_WORD (abfd, bytes->e_dload); - execp->a_talign = bytes->e_talign[0]; - execp->a_dalign = bytes->e_dalign[0]; - execp->a_balign = bytes->e_balign[0]; - execp->a_relaxable = bytes->e_relaxable[0]; -} - -/* Swaps the information in an internal exec header structure into the - supplied buffer ready for writing to disk. */ - -PROTO(void, bout_swap_exec_header_out, - (bfd *abfd, - struct internal_exec *execp, - struct external_exec *raw_bytes)); -void -bout_swap_exec_header_out (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - struct external_exec *raw_bytes; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info , bytes->e_info); - PUT_WORD (abfd, execp->a_text , bytes->e_text); - PUT_WORD (abfd, execp->a_data , bytes->e_data); - PUT_WORD (abfd, execp->a_bss , bytes->e_bss); - PUT_WORD (abfd, execp->a_syms , bytes->e_syms); - PUT_WORD (abfd, execp->a_entry , bytes->e_entry); - PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize); - PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize); - PUT_WORD (abfd, execp->a_tload , bytes->e_tload); - PUT_WORD (abfd, execp->a_dload , bytes->e_dload); - bytes->e_talign[0] = execp->a_talign; - bytes->e_dalign[0] = execp->a_dalign; - bytes->e_balign[0] = execp->a_balign; - bytes->e_relaxable[0] = execp->a_relaxable; -} - - -static const bfd_target * -b_out_object_p (abfd) - bfd *abfd; -{ - struct internal_exec anexec; - struct external_exec exec_bytes; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info); - - if (N_BADMAG (anexec)) { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - bout_swap_exec_header_in (abfd, &exec_bytes, &anexec); - return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback); -} - - -/* Finish up the opening of a b.out file for reading. Fill in all the - fields that are not handled by common code. */ - -static const bfd_target * -b_out_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - unsigned long bss_start; - - /* Architecture and machine type */ - bfd_set_arch_mach(abfd, - bfd_arch_i960, /* B.out only used on i960 */ - bfd_mach_i960_core /* Default */ - ); - - /* The positions of the string table and symbol table. */ - obj_str_filepos (abfd) = N_STROFF (*execp); - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - - /* The alignments of the sections */ - obj_textsec (abfd)->alignment_power = execp->a_talign; - obj_datasec (abfd)->alignment_power = execp->a_dalign; - obj_bsssec (abfd)->alignment_power = execp->a_balign; - - /* The starting addresses of the sections. */ - obj_textsec (abfd)->vma = execp->a_tload; - obj_datasec (abfd)->vma = execp->a_dload; - - /* And reload the sizes, since the aout module zaps them */ - obj_textsec (abfd)->_raw_size = execp->a_text; - - bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */ - obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); - - /* The file positions of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF(*execp); - obj_datasec (abfd)->filepos = N_DATOFF(*execp); - - /* The file positions of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TROFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DROFF(*execp); - - adata(abfd).page_size = 1; /* Not applicable. */ - adata(abfd).segment_size = 1; /* Not applicable. */ - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; - - if (execp->a_relaxable) - abfd->flags |= BFD_IS_RELAXABLE; - return abfd->xvec; -} - -struct bout_data_struct { - struct aoutdata a; - struct internal_exec e; -}; - -static boolean -b_out_mkobject (abfd) - bfd *abfd; -{ - struct bout_data_struct *rawptr; - - rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct)); - if (rawptr == NULL) - return false; - - abfd->tdata.bout_data = rawptr; - exec_hdr (abfd) = &rawptr->e; - - obj_textsec (abfd) = (asection *)NULL; - obj_datasec (abfd) = (asection *)NULL; - obj_bsssec (abfd) = (asection *)NULL; - - return true; -} - -static boolean -b_out_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec swapped_hdr; - - if (! aout_32_make_sections (abfd)) - return false; - - exec_hdr (abfd)->a_info = BMAGIC; - - exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size; - exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size; - exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size; - exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist); - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - - exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power; - exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power; - exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power; - - exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma; - exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma; - - bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Now write out reloc info, followed by syms and strings */ - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - if (! aout_32_write_syms (abfd)) - return false; - - if (bfd_seek (abfd, (file_ptr)(N_TROFF(*exec_hdr(abfd))), SEEK_SET) != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false; - if (bfd_seek (abfd, (file_ptr)(N_DROFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false; - } - return true; -} - -/** Some reloc hackery */ - -#define CALLS 0x66003800 /* Template for 'calls' instruction */ -#define BAL 0x0b000000 /* Template for 'bal' instruction */ -#define BALX 0x85000000 /* Template for 'balx' instruction */ -#define BAL_MASK 0x00ffffff -#define CALL 0x09000000 -#define PCREL13_MASK 0x1fff - - -#define output_addr(sec) ((sec)->output_offset+(sec)->output_section->vma) - -/* Magic to turn callx into calljx */ -static bfd_reloc_status_type -calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section) - bfd *abfd; - struct bfd_link_info *link_info; - arelent *reloc_entry; - PTR src; - PTR dst; - asection *input_section; -{ - int word = bfd_get_32 (abfd, src); - asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); - aout_symbol_type *symbol = aout_symbol (symbol_in); - bfd_vma value; - - value = get_value (reloc_entry, link_info, input_section); - - if (IS_CALLNAME (symbol->other)) - { - aout_symbol_type *balsym = symbol+1; - int inst = bfd_get_32 (abfd, (bfd_byte *) src-4); - /* The next symbol should be an N_BALNAME */ - BFD_ASSERT (IS_BALNAME (balsym->other)); - inst &= BAL_MASK; - inst |= BALX; - bfd_put_32 (abfd, inst, (bfd_byte *) dst-4); - symbol = balsym; - value = (symbol->symbol.value - + output_addr (symbol->symbol.section)); - } - - word += value + reloc_entry->addend; - - bfd_put_32(abfd, word, dst); - return bfd_reloc_ok; -} - - -/* Magic to turn call into callj */ -static bfd_reloc_status_type -callj_callback (abfd, link_info, reloc_entry, data, srcidx, dstidx, - input_section, shrinking) - bfd *abfd; - struct bfd_link_info *link_info; - arelent *reloc_entry; - PTR data; - unsigned int srcidx; - unsigned int dstidx; - asection *input_section; - boolean shrinking; -{ - int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx); - asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); - aout_symbol_type *symbol = aout_symbol (symbol_in); - bfd_vma value; - - value = get_value (reloc_entry, link_info, input_section); - - if (IS_OTHER(symbol->other)) - { - /* Call to a system procedure - replace code with system - procedure number. */ - word = CALLS | (symbol->other - 1); - } - else if (IS_CALLNAME(symbol->other)) - { - aout_symbol_type *balsym = symbol+1; - - /* The next symbol should be an N_BALNAME. */ - BFD_ASSERT(IS_BALNAME(balsym->other)); - - /* We are calling a leaf, so replace the call instruction with a - bal. */ - word = BAL | ((word - + output_addr (balsym->symbol.section) - + balsym->symbol.value + reloc_entry->addend - - dstidx - - output_addr (input_section)) - & BAL_MASK); - } - else if ((symbol->symbol.flags & BSF_SECTION_SYM) != 0) - { - /* A callj against a symbol in the same section is a fully - resolved relative call. We don't need to do anything here. - If the symbol is not in the same section, I'm not sure what - to do; fortunately, this case will probably never arise. */ - BFD_ASSERT (! shrinking); - BFD_ASSERT (symbol->symbol.section == input_section); - } - else - { - word = CALL | (((word & BAL_MASK) - + value - + reloc_entry->addend - - (shrinking ? dstidx : 0) - - output_addr (input_section)) - & BAL_MASK); - } - bfd_put_32(abfd, word, (bfd_byte *) data + dstidx); - return bfd_reloc_ok; -} - -/* type rshift size bitsize pcrel bitpos absolute overflow check*/ - -#define ABS32CODE 0 -#define ABS32CODE_SHRUNK 1 -#define PCREL24 2 -#define CALLJ 3 -#define ABS32 4 -#define PCREL13 5 -#define ABS32_MAYBE_RELAXABLE 1 -#define ABS32_WAS_RELAXABLE 2 - -#define ALIGNER 10 -#define ALIGNDONE 11 -static reloc_howto_type howto_reloc_callj = -HOWTO(CALLJ, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callj", true, 0x00ffffff, 0x00ffffff,false); -static reloc_howto_type howto_reloc_abs32 = -HOWTO(ABS32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"abs32", true, 0xffffffff,0xffffffff,false); -static reloc_howto_type howto_reloc_pcrel24 = -HOWTO(PCREL24, 0, 2, 24, true, 0, complain_overflow_signed,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false); - -static reloc_howto_type howto_reloc_pcrel13 = -HOWTO(PCREL13, 0, 2, 13, true, 0, complain_overflow_signed,0,"pcrel13", true, 0x00001fff,0x00001fff,false); - - -static reloc_howto_type howto_reloc_abs32codeshrunk = -HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false); - -static reloc_howto_type howto_reloc_abs32code = -HOWTO(ABS32CODE, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"callx", true, 0xffffffff,0xffffffff,false); - -static reloc_howto_type howto_align_table[] = { - HOWTO (ALIGNER, 0, 0x1, 0, false, 0, complain_overflow_dont, 0, "align16", false, 0, 0, false), - HOWTO (ALIGNER, 0, 0x3, 0, false, 0, complain_overflow_dont, 0, "align32", false, 0, 0, false), - HOWTO (ALIGNER, 0, 0x7, 0, false, 0, complain_overflow_dont, 0, "align64", false, 0, 0, false), - HOWTO (ALIGNER, 0, 0xf, 0, false, 0, complain_overflow_dont, 0, "align128", false, 0, 0, false), -}; - -static reloc_howto_type howto_done_align_table[] = { - HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, complain_overflow_dont, 0, "donealign16", false, 0, 0, false), - HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, complain_overflow_dont, 0, "donealign32", false, 0, 0, false), - HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, complain_overflow_dont, 0, "donealign64", false, 0, 0, false), - HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, complain_overflow_dont, 0, "donealign128", false, 0, 0, false), -}; - -static reloc_howto_type * -b_out_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - default: - return 0; - case BFD_RELOC_I960_CALLJ: - return &howto_reloc_callj; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - return &howto_reloc_abs32; - case BFD_RELOC_24_PCREL: - return &howto_reloc_pcrel24; - } -} - -/* Allocate enough room for all the reloc entries, plus pointers to them all */ - -static boolean -b_out_slurp_reloc_table (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - register struct relocation_info *rptr; - unsigned int counter ; - arelent *cache_ptr ; - int extern_mask, pcrel_mask, callj_mask, length_shift; - int incode_mask; - int size_mask; - bfd_vma prev_addr = 0; - unsigned int count; - size_t reloc_size; - struct relocation_info *relocs; - arelent *reloc_cache; - - if (asect->relocation) - return true; - if (!aout_32_slurp_symbol_table (abfd)) - return false; - - if (asect == obj_datasec (abfd)) { - reloc_size = exec_hdr(abfd)->a_drsize; - goto doit; - } - - if (asect == obj_textsec (abfd)) { - reloc_size = exec_hdr(abfd)->a_trsize; - goto doit; - } - - if (asect == obj_bsssec (abfd)) { - reloc_size = 0; - goto doit; - } - - bfd_set_error (bfd_error_invalid_operation); - return false; - - doit: - if (bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET) != 0) - return false; - count = reloc_size / sizeof (struct relocation_info); - - relocs = (struct relocation_info *) bfd_malloc (reloc_size); - if (!relocs && reloc_size != 0) - return false; - reloc_cache = (arelent *) bfd_malloc ((count+1) * sizeof (arelent)); - if (!reloc_cache) { - if (relocs != NULL) - free ((char*)relocs); - return false; - } - - if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) { - free (reloc_cache); - if (relocs != NULL) - free (relocs); - return false; - } - - - - if (bfd_header_big_endian (abfd)) { - /* big-endian bit field allocation order */ - pcrel_mask = 0x80; - extern_mask = 0x10; - incode_mask = 0x08; - callj_mask = 0x02; - size_mask = 0x20; - length_shift = 5; - } else { - /* little-endian bit field allocation order */ - pcrel_mask = 0x01; - extern_mask = 0x08; - incode_mask = 0x10; - callj_mask = 0x40; - size_mask = 0x02; - length_shift = 1; - } - - for (rptr = relocs, cache_ptr = reloc_cache, counter = 0; - counter < count; - counter++, rptr++, cache_ptr++) - { - unsigned char *raw = (unsigned char *)rptr; - unsigned int symnum; - cache_ptr->address = bfd_h_get_32 (abfd, raw + 0); - cache_ptr->howto = 0; - if (bfd_header_big_endian (abfd)) - { - symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6]; - } - else - { - symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4]; - } - - if (raw[7] & extern_mask) - { - /* if this is set then the r_index is a index into the symbol table; - * if the bit is not set then r_index contains a section map. - * we either fill in the sym entry with a pointer to the symbol, - * or point to the correct section - */ - cache_ptr->sym_ptr_ptr = symbols + symnum; - cache_ptr->addend = 0; - } else - { - /* in a.out symbols are relative to the beginning of the - * file rather than sections ? - * (look in translate_from_native_sym_flags) - * the reloc entry addend has added to it the offset into the - * file of the data, so subtract the base to make the reloc - * section relative */ - int s; - { - /* sign-extend symnum from 24 bits to whatever host uses */ - s = symnum; - if (s & (1 << 23)) - s |= (~0) << 24; - } - cache_ptr->sym_ptr_ptr = (asymbol **)NULL; - switch (s) - { - case N_TEXT: - case N_TEXT | N_EXT: - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_textsec(abfd)->vma; - break; - case N_DATA: - case N_DATA | N_EXT: - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_datasec(abfd)->vma; - break; - case N_BSS: - case N_BSS | N_EXT: - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_bsssec(abfd)->vma; - break; - case N_ABS: - case N_ABS | N_EXT: - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = 0; - break; - case -2: /* .align */ - if (raw[7] & pcrel_mask) - { - cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3]; - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - else - { - /* .org? */ - abort (); - } - cache_ptr->addend = 0; - break; - default: - BFD_ASSERT(0); - break; - } - - } - - /* the i960 only has a few relocation types: - abs 32-bit and pcrel 24bit. except for callj's! */ - if (cache_ptr->howto != 0) - ; - else if (raw[7] & callj_mask) - { - cache_ptr->howto = &howto_reloc_callj; - } - else if ( raw[7] & pcrel_mask) - { - if (raw[7] & size_mask) - cache_ptr->howto = &howto_reloc_pcrel13; - else - cache_ptr->howto = &howto_reloc_pcrel24; - } - else - { - if (raw[7] & incode_mask) - { - cache_ptr->howto = &howto_reloc_abs32code; - } - else - { - cache_ptr->howto = &howto_reloc_abs32; - } - } - if (cache_ptr->address < prev_addr) - { - /* Ouch! this reloc is out of order, insert into the right place - */ - arelent tmp; - arelent *cursor = cache_ptr-1; - bfd_vma stop = cache_ptr->address; - tmp = *cache_ptr; - while (cursor->address > stop && cursor >= reloc_cache) - { - cursor[1] = cursor[0]; - cursor--; - } - cursor[1] = tmp; - } - else - { - prev_addr = cache_ptr->address; - } - } - - - if (relocs != NULL) - free (relocs); - asect->relocation = reloc_cache; - asect->reloc_count = count; - - - return true; -} - - -static boolean -b_out_squirt_out_relocs (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - int r_extern = 0; - int r_idx; - int incode_mask; - int len_1; - unsigned int count = section->reloc_count; - struct relocation_info *native, *natptr; - size_t natsize = count * sizeof (struct relocation_info); - int extern_mask, pcrel_mask, len_2, callj_mask; - if (count == 0) return true; - generic = section->orelocation; - native = ((struct relocation_info *) bfd_malloc (natsize)); - if (!native && natsize != 0) - return false; - - if (bfd_header_big_endian (abfd)) - { - /* Big-endian bit field allocation order */ - pcrel_mask = 0x80; - extern_mask = 0x10; - len_2 = 0x40; - len_1 = 0x20; - callj_mask = 0x02; - incode_mask = 0x08; - } - else - { - /* Little-endian bit field allocation order */ - pcrel_mask = 0x01; - extern_mask = 0x08; - len_2 = 0x04; - len_1 = 0x02; - callj_mask = 0x40; - incode_mask = 0x10; - } - - for (natptr = native; count > 0; --count, ++natptr, ++generic) - { - arelent *g = *generic; - unsigned char *raw = (unsigned char *)natptr; - asymbol *sym = *(g->sym_ptr_ptr); - - asection *output_section = sym->section->output_section; - - bfd_h_put_32(abfd, g->address, raw); - /* Find a type in the output format which matches the input howto - - * at the moment we assume input format == output format FIXME!! - */ - r_idx = 0; - /* FIXME: Need callj stuff here, and to check the howto entries to - be sure they are real for this architecture. */ - if (g->howto== &howto_reloc_callj) - { - raw[7] = callj_mask + pcrel_mask + len_2; - } - else if (g->howto == &howto_reloc_pcrel24) - { - raw[7] = pcrel_mask + len_2; - } - else if (g->howto == &howto_reloc_pcrel13) - { - raw[7] = pcrel_mask + len_1; - } - else if (g->howto == &howto_reloc_abs32code) - { - raw[7] = len_2 + incode_mask; - } - else if (g->howto >= howto_align_table - && g->howto <= (howto_align_table - + sizeof (howto_align_table) / sizeof (howto_align_table[0]) - - 1)) - { - /* symnum == -2; extern_mask not set, pcrel_mask set */ - r_idx = -2; - r_extern = 0; - raw[7] = (pcrel_mask - | ((g->howto - howto_align_table) << 1)); - } - else { - raw[7] = len_2; - } - - if (r_idx != 0) - /* already mucked with r_extern, r_idx */; - else if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_idx = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - - r_extern = 1; - r_idx = (*g->sym_ptr_ptr)->udata.i; - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_idx = output_section->target_index; - } - - if (bfd_header_big_endian (abfd)) { - raw[4] = (unsigned char) (r_idx >> 16); - raw[5] = (unsigned char) (r_idx >> 8); - raw[6] = (unsigned char) (r_idx ); - } else { - raw[6] = (unsigned char) (r_idx >> 16); - raw[5] = (unsigned char) (r_idx>> 8); - raw[4] = (unsigned char) (r_idx ); - } - if (r_extern) - raw[7] |= extern_mask; - } - - if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { - free((PTR)native); - return false; - } - free ((PTR)native); - - return true; -} - -/* This is stupid. This function should be a boolean predicate */ -static long -b_out_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr; - unsigned int count; - - if ((section->flags & SEC_CONSTRUCTOR) != 0) - { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - } - else - { - if (section->relocation == NULL - && ! b_out_slurp_reloc_table (abfd, section, symbols)) - return -1; - - tblptr = section->relocation; - for (count = 0; count++ < section->reloc_count;) - *relptr++ = tblptr++; - } - - *relptr = NULL; - - return section->reloc_count; -} - -static long -b_out_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (bfd_get_format (abfd) != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - if (asect->flags & SEC_CONSTRUCTOR) - return sizeof (arelent *) * (asect->reloc_count + 1); - - if (asect == obj_datasec (abfd)) - return (sizeof (arelent *) * - ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info)) - +1)); - - if (asect == obj_textsec (abfd)) - return (sizeof (arelent *) * - ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info)) - +1)); - - if (asect == obj_bsssec (abfd)) - return 0; - - bfd_set_error (bfd_error_invalid_operation); - return -1; -} - -static boolean -b_out_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - - if (abfd->output_has_begun == false) { /* set by bfd.c handler */ - if (! aout_32_make_sections (abfd)) - return false; - - obj_textsec (abfd)->filepos = sizeof(struct internal_exec); - obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos - + obj_textsec (abfd)->_raw_size; - - } - /* regardless, once we know what we're doing, we might as well get going */ - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) - return false; - - if (count != 0) { - return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false; - } - return true; -} - -static boolean -b_out_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - bfd_default_set_arch_mach(abfd, arch, machine); - - if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */ - return true; - if (arch == bfd_arch_i960) /* i960 default is OK */ - switch (machine) { - case bfd_mach_i960_core: - case bfd_mach_i960_kb_sb: - case bfd_mach_i960_mc: - case bfd_mach_i960_xa: - case bfd_mach_i960_ca: - case bfd_mach_i960_ka_sa: - case bfd_mach_i960_jx: - case bfd_mach_i960_hx: - case 0: - return true; - default: - return false; - } - - return false; -} - -static int -b_out_sizeof_headers (ignore_abfd, ignore) - bfd *ignore_abfd; - boolean ignore; -{ - return sizeof(struct internal_exec); -} - - - -/************************************************************************/ -static bfd_vma -get_value (reloc, link_info, input_section) - arelent *reloc; - struct bfd_link_info *link_info; - asection *input_section; -{ - bfd_vma value; - asymbol *symbol = *(reloc->sym_ptr_ptr); - - /* A symbol holds a pointer to a section, and an offset from the - base of the section. To relocate, we find where the section will - live in the output and add that in */ - - if (bfd_is_und_section (symbol->section)) - { - struct bfd_link_hash_entry *h; - - /* The symbol is undefined in this BFD. Look it up in the - global linker hash table. FIXME: This should be changed when - we convert b.out to use a specific final_link function and - change the interface to bfd_relax_section to not require the - generic symbols. */ - h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, - bfd_asymbol_name (symbol), - false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) - value = h->u.def.value + output_addr (h->u.def.section); - else if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_common) - value = h->u.c.size; - else - { - if (! ((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (symbol), - input_section->owner, input_section, reloc->address))) - abort (); - value = 0; - } - } - else - { - value = symbol->value + output_addr (symbol->section); - } - - /* Add the value contained in the relocation */ - value += reloc->addend; - - return value; -} - -static void -perform_slip (abfd, slip, input_section, value) - bfd *abfd; - unsigned int slip; - asection *input_section; - bfd_vma value; -{ - asymbol **s; - - s = _bfd_generic_link_get_symbols (abfd); - BFD_ASSERT (s != (asymbol **) NULL); - - /* Find all symbols past this point, and make them know - what's happened */ - while (*s) - { - asymbol *p = *s; - if (p->section == input_section) - { - /* This was pointing into this section, so mangle it */ - if (p->value > value) - { - p->value -=slip; - if (p->udata.p != NULL) - { - struct generic_link_hash_entry *h; - - h = (struct generic_link_hash_entry *) p->udata.p; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - h->root.u.def.value -= slip; - BFD_ASSERT (h->root.u.def.value == p->value); - } - } - } - s++; - - } -} - -/* This routine works out if the thing we want to get to can be - reached with a 24bit offset instead of a 32 bit one. - If it can, then it changes the amode */ - -static int -abs32code (abfd, input_section, r, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *r; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - bfd_vma value = get_value (r, link_info, input_section); - bfd_vma dot = output_addr (input_section) + r->address; - bfd_vma gap; - - /* See if the address we're looking at within 2^23 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - (dot - shrink); - - - if (-1<<23 < (long)gap && (long)gap < 1<<23 ) - { - /* Change the reloc type from 32bitcode possible 24, to 24bit - possible 32 */ - - r->howto = &howto_reloc_abs32codeshrunk; - /* The place to relc moves back by four bytes */ - r->address -=4; - - /* This will be four bytes smaller in the long run */ - shrink += 4 ; - perform_slip (abfd, 4, input_section, r->address-shrink + 4); - } - return shrink; -} - -static int -aligncode (abfd, input_section, r, shrink) - bfd *abfd; - asection *input_section; - arelent *r; - unsigned int shrink; -{ - bfd_vma dot = output_addr (input_section) + r->address; - bfd_vma gap; - bfd_vma old_end; - bfd_vma new_end; - int shrink_delta; - int size = r->howto->size; - - /* Reduce the size of the alignment so that it's still aligned but - smaller - the current size is already the same size as or bigger - than the alignment required. */ - - /* calculate the first byte following the padding before we optimize */ - old_end = ((dot + size ) & ~size) + size+1; - /* work out where the new end will be - remember that we're smaller - than we used to be */ - new_end = ((dot - shrink + size) & ~size); - - /* This is the new end */ - gap = old_end - ((dot + size) & ~size); - - shrink_delta = (old_end - new_end) - shrink; - - if (shrink_delta) - { - /* Change the reloc so that it knows how far to align to */ - r->howto = howto_done_align_table + (r->howto - howto_align_table); - - /* Encode the stuff into the addend - for future use we need to - know how big the reloc used to be */ - r->addend = old_end - dot + r->address; - - /* This will be N bytes smaller in the long run, adjust all the symbols */ - perform_slip (abfd, shrink_delta, input_section, r->address - shrink); - shrink += shrink_delta; - } - return shrink; -} - -static boolean -b_out_bfd_relax_section (abfd, i, link_info, again) - bfd *abfd; - asection *i; - struct bfd_link_info *link_info; - boolean *again; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = i->owner; - asection *input_section = i; - int shrink = 0 ; - arelent **reloc_vector = NULL; - long reloc_size = bfd_get_reloc_upper_bound(input_bfd, - input_section); - - if (reloc_size < 0) - return false; - - /* We only run this relaxation once. It might work to run it - multiple times, but it hasn't been tested. */ - *again = false; - - if (reloc_size) - { - long reloc_count; - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - /* Get the relocs and think about them */ - reloc_count = - bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, - _bfd_generic_link_get_symbols (input_bfd)); - if (reloc_count < 0) - goto error_return; - if (reloc_count > 0) - { - arelent **parent; - for (parent = reloc_vector; *parent; parent++) - { - arelent *r = *parent; - switch (r->howto->type) - { - case ALIGNER: - /* An alignment reloc */ - shrink = aligncode (abfd, input_section, r, shrink); - break; - case ABS32CODE: - /* A 32bit reloc in an addressing mode */ - shrink = abs32code (input_bfd, input_section, r, shrink, - link_info); - break; - case ABS32CODE_SHRUNK: - shrink+=4; - break; - } - } - } - } - input_section->_cooked_size = input_section->_raw_size - shrink; - - if (reloc_vector != NULL) - free (reloc_vector); - return true; - error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return false; -} - -static bfd_byte * -b_out_bfd_get_relocated_section_contents (in_abfd, link_info, link_order, - data, relocateable, symbols) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - long reloc_size = bfd_get_reloc_upper_bound(input_bfd, - input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - if (reloc_size < 0) - goto error_return; - - /* If producing relocateable output, don't bother to relax. */ - if (relocateable) - return bfd_generic_get_relocated_section_contents (in_abfd, link_info, - link_order, - data, relocateable, - symbols); - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - input_section->reloc_done = 1; - - /* read in the section */ - BFD_ASSERT (true == bfd_get_section_contents(input_bfd, - input_section, - data, - 0, - input_section->_raw_size)); - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - goto error_return; - if (reloc_count > 0) - { - arelent **parent = reloc_vector; - arelent *reloc ; - - unsigned int dst_address = 0; - unsigned int src_address = 0; - unsigned int run; - unsigned int idx; - - /* Find how long a run we can do */ - while (dst_address < link_order->size) - { - reloc = *parent; - if (reloc) - { - /* Note that the relaxing didn't tie up the addresses in the - relocation, so we use the original address to work out the - run of non-relocated data */ - BFD_ASSERT (reloc->address >= src_address); - run = reloc->address - src_address; - parent++; - } - else - { - run = link_order->size - dst_address; - } - /* Copy the bytes */ - for (idx = 0; idx < run; idx++) - { - data[dst_address++] = data[src_address++]; - } - - /* Now do the relocation */ - - if (reloc) - { - switch (reloc->howto->type) - { - case ABS32CODE: - calljx_callback (in_abfd, link_info, reloc, - src_address + data, dst_address + data, - input_section); - src_address+=4; - dst_address+=4; - break; - case ABS32: - bfd_put_32(in_abfd, - (bfd_get_32 (in_abfd, data+src_address) - + get_value (reloc, link_info, input_section)), - data+dst_address); - src_address+=4; - dst_address+=4; - break; - case CALLJ: - callj_callback (in_abfd, link_info, reloc, data, src_address, - dst_address, input_section, false); - src_address+=4; - dst_address+=4; - break; - case ALIGNDONE: - BFD_ASSERT (reloc->addend >= src_address); - BFD_ASSERT (reloc->addend <= input_section->_raw_size); - src_address = reloc->addend; - dst_address = ((dst_address + reloc->howto->size) - & ~reloc->howto->size); - break; - case ABS32CODE_SHRUNK: - /* This used to be a callx, but we've found out that a - callj will reach, so do the right thing. */ - callj_callback (in_abfd, link_info, reloc, data, - src_address + 4, dst_address, input_section, - true); - dst_address+=4; - src_address+=8; - break; - case PCREL24: - { - long int word = bfd_get_32(in_abfd, data+src_address); - bfd_vma value; - - value = get_value (reloc, link_info, input_section); - word = ((word & ~BAL_MASK) - | (((word & BAL_MASK) - + value - - output_addr (input_section) - + reloc->addend) - & BAL_MASK)); - - bfd_put_32(in_abfd,word, data+dst_address); - dst_address+=4; - src_address+=4; - - } - break; - - case PCREL13: - { - long int word = bfd_get_32(in_abfd, data+src_address); - bfd_vma value; - - value = get_value (reloc, link_info, input_section); - word = ((word & ~PCREL13_MASK) - | (((word & PCREL13_MASK) - + value - + reloc->addend - - output_addr (input_section)) - & PCREL13_MASK)); - - bfd_put_32(in_abfd,word, data+dst_address); - dst_address+=4; - src_address+=4; - - } - break; - - default: - abort(); - } - } - } - } - if (reloc_vector != NULL) - free (reloc_vector); - return data; - error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} -/***********************************************************************/ - -/* Build the transfer vectors for Big and Little-Endian B.OUT files. */ - -#define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info - -#define b_out_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define b_out_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define b_out_bfd_final_link _bfd_generic_final_link -#define b_out_bfd_link_split_section _bfd_generic_link_split_section - -#define aout_32_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -const bfd_target b_out_vec_big_host = -{ - "b.out.big", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_BIG, /* hdr byte order is big */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, b_out_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (b_out), - BFD_JUMP_TABLE_WRITE (b_out), - BFD_JUMP_TABLE_LINK (b_out), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0, -}; - - -const bfd_target b_out_vec_little_host = -{ - "b.out.little", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, b_out_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (b_out), - BFD_JUMP_TABLE_WRITE (b_out), - BFD_JUMP_TABLE_LINK (b_out), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/cache.c b/contrib/gdb/bfd/cache.c deleted file mode 100644 index ef15877ccd5..00000000000 --- a/contrib/gdb/bfd/cache.c +++ /dev/null @@ -1,347 +0,0 @@ -/* BFD library -- caching of file descriptors. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com). - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - File caching - - The file caching mechanism is embedded within BFD and allows - the application to open as many BFDs as it wants without - regard to the underlying operating system's file descriptor - limit (often as low as 20 open files). The module in - <> maintains a least recently used list of - <> files, and exports the name - <>, which runs around and makes sure that - the required BFD is open. If not, then it chooses a file to - close, closes it and opens the one wanted, returning its file - handle. - -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -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 - -DESCRIPTION - The maximum number of files which the cache will keep open at - one time. - -.#define BFD_CACHE_MAX_OPEN 10 - -*/ - -/* The number of BFD files we have open. */ - -static int open_files; - -/* -INTERNAL_FUNCTION - bfd_last_cache - -SYNOPSIS - extern bfd *bfd_last_cache; - -DESCRIPTION - Zero, or a pointer to the topmost BFD on the chain. This is - used by the <> macro in @file{libbfd.h} to - determine when it can avoid a function call. -*/ - -bfd *bfd_last_cache; - -/* - 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)) - - - */ - -/* Insert a BFD into the cache. */ - -static INLINE void -insert (abfd) - bfd *abfd; -{ - if (bfd_last_cache == NULL) - { - abfd->lru_next = abfd; - abfd->lru_prev = abfd; - } - 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; -} - -/* 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 (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 -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) - ret = true; - else - { - ret = false; - bfd_set_error (bfd_error_system_call); - } - - snip (abfd); - - abfd->iostream = NULL; - --open_files; - - return ret; -} - -/* -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) - { - if (! close_one ()) - return false; - } - insert (abfd); - ++open_files; - return true; -} - -/* -INTERNAL_FUNCTION - bfd_cache_close - -SYNOPSIS - 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 - <> is returned if closing the file fails, <> is - returned if all is well. -*/ - -boolean -bfd_cache_close (abfd) - bfd *abfd; -{ - if (abfd->iostream == NULL - || (abfd->flags & BFD_IN_MEMORY) != 0) - return true; - - return bfd_cache_delete (abfd); -} - -/* -INTERNAL_FUNCTION - bfd_open_file - -SYNOPSIS - FILE* bfd_open_file(bfd *abfd); - -DESCRIPTION - Call the OS to open a file for @var{abfd}. Return the <> - (possibly <>) that results from this operation. Set up the - BFD so that future accesses know the file is open. If the <> - returned is <>, then it won't have been put in the - cache, so it won't have to be removed from it. -*/ - -FILE * -bfd_open_file (abfd) - bfd *abfd; -{ - abfd->cacheable = true; /* Allow it to be closed later. */ - - if (open_files >= BFD_CACHE_MAX_OPEN) - { - if (! close_one ()) - return NULL; - } - - switch (abfd->direction) - { - case read_direction: - case no_direction: - abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB); - break; - case both_direction: - case write_direction: - if (abfd->opened_once == true) - { - abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB); - if (abfd->iostream == NULL) - abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB); - } - else - { - /*open for creat */ - abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WB); - abfd->opened_once = true; - } - break; - } - - 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 <> fails to find a - quick answer. Find a file descriptor for @var{abfd}. If - necessary, it open it. If there are already more than - <> files open, it tries to close one first, to - avoid running out of file descriptors. -*/ - -FILE * -bfd_cache_lookup_worker (abfd) - bfd *abfd; -{ - if ((abfd->flags & BFD_IN_MEMORY) != 0) - abort (); - - if (abfd->my_archive) - abfd = abfd->my_archive; - - if (abfd->iostream != NULL) - { - /* Move the file to the start of the cache. */ - if (abfd != bfd_last_cache) - { - snip (abfd); - insert (abfd); - } - } - else - { - if (bfd_open_file (abfd) == NULL) - return NULL; - if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0) - return NULL; - } - - return (FILE *) abfd->iostream; -} diff --git a/contrib/gdb/bfd/cf-i386lynx.c b/contrib/gdb/bfd/cf-i386lynx.c deleted file mode 100644 index 2a14bde8f12..00000000000 --- a/contrib/gdb/bfd/cf-i386lynx.c +++ /dev/null @@ -1,31 +0,0 @@ -/* BFD back-end for Intel 386 COFF LynxOS files. - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_SYM i386lynx_coff_vec -#define TARGET_NAME "coff-i386-lynx" - -#define LYNXOS - -#define COFF_LONG_FILENAMES - -#include "coff-i386.c" diff --git a/contrib/gdb/bfd/cf-m68klynx.c b/contrib/gdb/bfd/cf-m68klynx.c deleted file mode 100644 index 8149dc68319..00000000000 --- a/contrib/gdb/bfd/cf-m68klynx.c +++ /dev/null @@ -1,223 +0,0 @@ -/* BFD back-end for Motorola M68K COFF LynxOS files. - Copyright 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_SYM m68klynx_coff_vec -#define TARGET_NAME "coff-m68k-lynx" - -#define LYNXOS - -#define COFF_LONG_FILENAMES - -#define _bfd_m68kcoff_howto_table _bfd_m68klynx_howto_table -#define _bfd_m68kcoff_rtype2howto _bfd_m68klynx_rtype2howto -#define _bfd_m68kcoff_howto2rtype _bfd_m68klynx_howto2rtype -#define _bfd_m68kcoff_reloc_type_lookup _bfd_m68klynx_reloc_type_lookup - -#define LYNX_SPECIAL_FN _bfd_m68klynx_special_fn - -#include "bfd.h" -#include "sysdep.h" - -#ifdef ANSI_PROTOTYPES -struct internal_reloc; -struct coff_link_hash_entry; -struct internal_syment; -#endif - -static bfd_reloc_status_type _bfd_m68klynx_special_fn - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_m68k_lynx_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *)); - -/* For some reason when using m68k COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. (taken from work done by Ian Taylor, Cygnus Support, - for I386 COFF). */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -_bfd_m68klynx_special_fn (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 386 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && (reloc.r_type == R_PCRBYTE \ - || reloc.r_type == R_PCRWORD \ - || reloc.r_type == R_PCRLONG)) \ - cache_ptr->addend += asect->vma; \ - } - -#define coff_rtype_to_howto coff_m68k_lynx_rtype_to_howto - -#include "coff-m68k.c" - -/* coff-m68k.c uses the special COFF backend linker. We need to - adjust common symbols. - - We can't define this function until after we have included - coff-m68k.c, because it uses RTYPE2HOWTO. */ - -/*ARGSUSED*/ -static reloc_howto_type * -coff_m68k_lynx_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - arelent relent; - reloc_howto_type *howto; - - RTYPE2HOWTO (&relent, rel); - - howto = relent.howto; - - if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) - { - /* This is a common symbol. The section contents include the - size (sym->n_value) as an addend. The relocate_section - function will be adding in the final value of the symbol. We - need to subtract out the current size in order to get the - correct result. */ - BFD_ASSERT (h != NULL); - *addendp -= sym->n_value; - } - - /* If the output symbol is common (in which case this must be a - relocateable link), we need to add in the final size of the - common symbol. */ - if (h != NULL && h->root.type == bfd_link_hash_common) - *addendp += h->root.u.c.size; - - return howto; -} diff --git a/contrib/gdb/bfd/cf-sparclynx.c b/contrib/gdb/bfd/cf-sparclynx.c deleted file mode 100644 index 774a099fefb..00000000000 --- a/contrib/gdb/bfd/cf-sparclynx.c +++ /dev/null @@ -1,28 +0,0 @@ -/* BFD back-end for Sparc COFF LynxOS files. - Copyright 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_SYM sparclynx_coff_vec -#define TARGET_NAME "coff-sparc-lynx" - -#define LYNXOS - -#define COFF_LONG_FILENAMES - -#include "coff-sparc.c" diff --git a/contrib/gdb/bfd/cisco-core.c b/contrib/gdb/bfd/cisco-core.c deleted file mode 100644 index a25115cc523..00000000000 --- a/contrib/gdb/bfd/cisco-core.c +++ /dev/null @@ -1,313 +0,0 @@ -/* BFD back-end for CISCO crash dumps. - -Copyright 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -/* core_file_failing_signal returns a host signal (this probably should - be fixed). */ -#include - -#define CRASH_INFO (0xffc) -#define CRASH_MAGIC 0xdead1234 - -typedef enum { - CRASH_REASON_NOTCRASHED = 0, - CRASH_REASON_EXCEPTION = 1, - CRASH_REASON_CORRUPT = 2, - } crashreason; - -struct crashinfo_external -{ - char magic[4]; /* Magic number */ - char version[4]; /* Version number */ - char reason[4]; /* Crash reason */ - char cpu_vector[4]; /* CPU vector for exceptions */ - char registers[4]; /* Pointer to saved registers */ - char rambase[4]; /* Base of RAM (not in V1 crash info) */ -}; - -struct cisco_core_struct -{ - int sig; -}; - -static const bfd_target * -cisco_core_file_p (abfd) - bfd *abfd; -{ - char buf[4]; - unsigned int crashinfo_offset; - struct crashinfo_external crashinfo; - int nread; - unsigned int rambase; - sec_ptr asect; - struct stat statbuf; - - if (bfd_seek (abfd, CRASH_INFO, SEEK_SET) != 0) - return NULL; - - nread = bfd_read (buf, 1, 4, abfd); - if (nread != 4) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - crashinfo_offset = bfd_get_32 (abfd, buf); - - if (bfd_seek (abfd, crashinfo_offset, SEEK_SET) != 0) - return NULL; - - nread = bfd_read (&crashinfo, 1, sizeof (crashinfo), abfd); - if (nread != sizeof (crashinfo)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (bfd_stat (abfd, &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - if (bfd_get_32 (abfd, crashinfo.magic) != CRASH_MAGIC) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - switch (bfd_get_32 (abfd, crashinfo.version)) - { - case 0: - bfd_set_error (bfd_error_wrong_format); - return NULL; - case 1: - rambase = 0; - break; - default: - case 2: - rambase = bfd_get_32 (abfd, crashinfo.rambase); - break; - } - - /* OK, we believe you. You're a core file. */ - - abfd->tdata.cisco_core_data = - ((struct cisco_core_struct *) - bfd_zmalloc (sizeof (struct cisco_core_struct))); - if (abfd->tdata.cisco_core_data == NULL) - return NULL; - - switch ((crashreason) bfd_get_32 (abfd, crashinfo.reason)) - { - case CRASH_REASON_NOTCRASHED: - /* Crash file probably came from write core. */ - abfd->tdata.cisco_core_data->sig = 0; - break; - case CRASH_REASON_CORRUPT: - /* The crash context area was corrupt -- proceed with caution. - We have no way of passing this information back to the caller. */ - abfd->tdata.cisco_core_data->sig = 0; - break; - case CRASH_REASON_EXCEPTION: - /* Crash occured due to CPU exception. */ - - /* This is 68k-specific; for MIPS we'll need to interpret - cpu_vector differently based on the target configuration - (since CISCO core files don't seem to have the processor - encoded in them). */ - - switch (bfd_get_32 (abfd, crashinfo.cpu_vector)) - { - /* bus error */ - case 2 : abfd->tdata.cisco_core_data->sig = SIGBUS; break; - /* address error */ - case 3 : abfd->tdata.cisco_core_data->sig = SIGBUS; break; - /* illegal instruction */ - case 4 : abfd->tdata.cisco_core_data->sig = SIGILL; break; - /* zero divide */ - case 5 : abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* chk instruction */ - case 6 : abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* trapv instruction */ - case 7 : abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* privilege violation */ - case 8 : abfd->tdata.cisco_core_data->sig = SIGSEGV; break; - /* trace trap */ - case 9 : abfd->tdata.cisco_core_data->sig = SIGTRAP; break; - /* line 1010 emulator */ - case 10: abfd->tdata.cisco_core_data->sig = SIGILL; break; - /* line 1111 emulator */ - case 11: abfd->tdata.cisco_core_data->sig = SIGILL; break; - - /* Coprocessor protocol violation. Using a standard MMU or FPU - this cannot be triggered by software. Call it a SIGBUS. */ - case 13: abfd->tdata.cisco_core_data->sig = SIGBUS; break; - - /* interrupt */ - case 31: abfd->tdata.cisco_core_data->sig = SIGINT; break; - /* breakpoint */ - case 33: abfd->tdata.cisco_core_data->sig = SIGTRAP; break; - - /* floating point err */ - case 48: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* floating point err */ - case 49: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* zero divide */ - case 50: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* underflow */ - case 51: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* operand error */ - case 52: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* overflow */ - case 53: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* NAN */ - case 54: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - default: - /* "software generated"*/ - abfd->tdata.cisco_core_data->sig = SIGEMT; - } - break; - default: - /* Unknown crash reason. */ - abfd->tdata.cisco_core_data->sig = 0; - break; - } - - abfd->sections = NULL; - abfd->section_count = 0; - - asect = (asection *) bfd_zmalloc (sizeof (asection)); - if (asect == NULL) - goto error_return; - asect->name = ".reg"; - asect->flags = SEC_HAS_CONTENTS; - /* This can be bigger than the real size. Set it to the size of the whole - core file. */ - asect->_raw_size = statbuf.st_size; - asect->vma = 0; - asect->filepos = bfd_get_32 (abfd, crashinfo.registers) - rambase; - asect->next = abfd->sections; - abfd->sections = asect; - ++abfd->section_count; - - /* There is only one section containing data from the target system's RAM. - We call it .data. */ - asect = (asection *) bfd_zmalloc (sizeof (asection)); - if (asect == NULL) - goto error_return; - asect->name = ".data"; - asect->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; - /* The size of memory is the size of the core file itself. */ - asect->_raw_size = statbuf.st_size; - asect->vma = rambase; - asect->filepos = 0; - asect->next = abfd->sections; - abfd->sections = asect; - ++abfd->section_count; - - return abfd->xvec; - - error_return: - { - sec_ptr nextsect; - for (asect = abfd->sections; asect != NULL;) - { - nextsect = asect->next; - free (asect); - asect = nextsect; - } - free (abfd->tdata.cisco_core_data); - return NULL; - } -} - -char * -cisco_core_file_failing_command (abfd) - bfd *abfd; -{ - return NULL; -} - -int -cisco_core_file_failing_signal (abfd) - bfd *abfd; -{ - return abfd->tdata.cisco_core_data->sig; -} - -boolean -cisco_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - return true; -} - -const bfd_target cisco_core_vec = - { - "trad-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - cisco_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (cisco), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/coff-a29k.c b/contrib/gdb/bfd/coff-a29k.c deleted file mode 100644 index 3ceabfba5c4..00000000000 --- a/contrib/gdb/bfd/coff-a29k.c +++ /dev/null @@ -1,641 +0,0 @@ -/* BFD back-end for AMD 29000 COFF binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by David Wood at New York University 7/8/91. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define A29K 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/a29k.h" -#include "coff/internal.h" -#include "libcoff.h" - -static long get_symbol_value PARAMS ((asymbol *)); -static bfd_reloc_status_type a29k_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static boolean coff_a29k_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); -static boolean coff_a29k_adjust_symndx - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - struct internal_reloc *, boolean *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) - -#define INSERT_HWORD(WORD,HWORD) \ - (((WORD) & 0xff00ff00) | (((HWORD) & 0xff00) << 8) | ((HWORD)& 0xff)) -#define EXTRACT_HWORD(WORD) \ - ((((WORD) & 0x00ff0000) >> 8) | ((WORD)& 0xff)) -#define SIGN_EXTEND_HWORD(HWORD) \ - ((HWORD) & 0x8000 ? (HWORD)|(~0xffffL) : (HWORD)) - -/* Provided the symbol, returns the value reffed */ -static long -get_symbol_value (symbol) - asymbol *symbol; -{ - long relocation = 0; - - if (bfd_is_com_section (symbol->section)) - { - relocation = 0; - } - else - { - relocation = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; - } - - return(relocation); -} - -/* this function is in charge of performing all the 29k relocations */ - -static bfd_reloc_status_type -a29k_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* the consth relocation comes in two parts, we have to remember - the state between calls, in these variables */ - static boolean part1_consth_active = false; - static unsigned long part1_consth_value; - - unsigned long insn; - unsigned long sym_value; - unsigned long unsigned_value; - unsigned short r_type; - long signed_value; - - unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/ - bfd_byte *hit_data =addr + (bfd_byte *)(data); - - r_type = reloc_entry->howto->type; - - if (output_bfd) { - /* Partial linking - do nothing */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - - } - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - { - /* Keep the state machine happy in case we're called again */ - if (r_type == R_IHIHALF) - { - part1_consth_active = true; - part1_consth_value = 0; - } - return(bfd_reloc_undefined); - } - - if ((part1_consth_active) && (r_type != R_IHCONST)) - { - part1_consth_active = false; - *error_message = (char *) "Missing IHCONST"; - return(bfd_reloc_dangerous); - } - - - sym_value = get_symbol_value(symbol_in); - - switch (r_type) - { - case R_IREL: - insn = bfd_get_32(abfd, hit_data); - /* Take the value in the field and sign extend it */ - signed_value = EXTRACT_HWORD(insn); - signed_value = SIGN_EXTEND_HWORD(signed_value); - signed_value <<= 2; - - /* See the note on the R_IREL reloc in coff_a29k_relocate_section. */ - if (signed_value == - (long) reloc_entry->address) - signed_value = 0; - - signed_value += sym_value + reloc_entry->addend; - if ((signed_value & ~0x3ffff) == 0) - { /* Absolute jmp/call */ - insn |= (1<<24); /* Make it absolute */ - /* FIXME: Should we change r_type to R_IABS */ - } - else - { - /* Relative jmp/call, so subtract from the value the - address of the place we're coming from */ - signed_value -= (reloc_entry->address - + input_section->output_section->vma - + input_section->output_offset); - if (signed_value>0x1ffff || signed_value<-0x20000) - return(bfd_reloc_overflow); - } - signed_value >>= 2; - insn = INSERT_HWORD(insn, signed_value); - bfd_put_32(abfd, insn ,hit_data); - break; - case R_ILOHALF: - insn = bfd_get_32(abfd, hit_data); - unsigned_value = EXTRACT_HWORD(insn); - unsigned_value += sym_value + reloc_entry->addend; - insn = INSERT_HWORD(insn, unsigned_value); - bfd_put_32(abfd, insn, hit_data); - break; - case R_IHIHALF: - insn = bfd_get_32(abfd, hit_data); - /* consth, part 1 - Just get the symbol value that is referenced */ - part1_consth_active = true; - part1_consth_value = sym_value + reloc_entry->addend; - /* Don't modify insn until R_IHCONST */ - break; - case R_IHCONST: - insn = bfd_get_32(abfd, hit_data); - /* consth, part 2 - Now relocate the reference */ - if (part1_consth_active == false) { - *error_message = (char *) "Missing IHIHALF"; - return(bfd_reloc_dangerous); - } - /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */ - unsigned_value = 0; /*EXTRACT_HWORD(insn) << 16;*/ - unsigned_value += reloc_entry->addend; /* r_symndx */ - unsigned_value += part1_consth_value; - unsigned_value = unsigned_value >> 16; - insn = INSERT_HWORD(insn, unsigned_value); - part1_consth_active = false; - bfd_put_32(abfd, insn, hit_data); - break; - case R_BYTE: - insn = bfd_get_8(abfd, hit_data); - unsigned_value = insn + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffffff00) - return(bfd_reloc_overflow); - bfd_put_8(abfd, unsigned_value, hit_data); - break; - case R_HWORD: - insn = bfd_get_16(abfd, hit_data); - unsigned_value = insn + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffff0000) - return(bfd_reloc_overflow); - bfd_put_16(abfd, insn, hit_data); - break; - case R_WORD: - insn = bfd_get_32(abfd, hit_data); - insn += sym_value + reloc_entry->addend; - bfd_put_32(abfd, insn, hit_data); - break; - default: - *error_message = "Unrecognized reloc"; - return (bfd_reloc_dangerous); - } - - - return(bfd_reloc_ok); -} - -/* type rightshift - size - bitsize - pc-relative - bitpos - absolute - complain_on_overflow - special_function - relocation name - partial_inplace - src_mask -*/ - -/*FIXME: I'm not real sure about this table */ -static reloc_howto_type howto_table[] = -{ - {R_ABS, 0, 3, 32, false, 0, complain_overflow_bitfield,a29k_reloc,"ABS", true, 0xffffffff,0xffffffff, false}, - {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, - {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, - {21}, {22}, {23}, - {R_IREL, 0, 3, 32, true, 0, complain_overflow_signed,a29k_reloc,"IREL", true, 0xffffffff,0xffffffff, false}, - {R_IABS, 0, 3, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"IABS", true, 0xffffffff,0xffffffff, false}, - {R_ILOHALF, 0, 3, 16, true, 0, complain_overflow_signed, a29k_reloc,"ILOHALF", true, 0x0000ffff,0x0000ffff, false}, - {R_IHIHALF, 0, 3, 16, true, 16, complain_overflow_signed, a29k_reloc,"IHIHALF", true, 0xffff0000,0xffff0000, false}, - {R_IHCONST, 0, 3, 16, true, 0, complain_overflow_signed, a29k_reloc,"IHCONST", true, 0xffff0000,0xffff0000, false}, - {R_BYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, a29k_reloc,"BYTE", true, 0x000000ff,0x000000ff, false}, - {R_HWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, a29k_reloc,"HWORD", true, 0x0000ffff,0x0000ffff, false}, - {R_WORD, 0, 2, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"WORD", true, 0xffffffff,0xffffffff, false}, -}; - -#define BADMAG(x) A29KBADMAG(x) - -#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent,reloc, symbols, abfd, section) - arelent *relent; - struct internal_reloc *reloc; - asymbol **symbols; - bfd *abfd; - asection *section; -{ - static bfd_vma ihihalf_vaddr = (bfd_vma) -1; - - relent->address = reloc->r_vaddr; - relent->howto = howto_table + reloc->r_type; - if (reloc->r_type == R_IHCONST) - { - /* The address of an R_IHCONST should always be the address of - the immediately preceding R_IHIHALF. relocs generated by gas - are correct, but relocs generated by High C are different (I - can't figure out what the address means for High C). We can - handle both gas and High C by ignoring the address here, and - simply reusing the address saved for R_IHIHALF. */ - if (ihihalf_vaddr == (bfd_vma) -1) - abort (); - relent->address = ihihalf_vaddr; - ihihalf_vaddr = (bfd_vma) -1; - relent->addend = reloc->r_symndx; - relent->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr; - } - else - { - asymbol *ptr; - relent->sym_ptr_ptr = symbols + obj_convert(abfd)[reloc->r_symndx]; - - ptr = *(relent->sym_ptr_ptr); - - if (ptr - && bfd_asymbol_bfd(ptr) == abfd - - && ((ptr->flags & BSF_OLD_COMMON)== 0)) - { - relent->addend = 0; - } - else - { - relent->addend = 0; - } - relent->address-= section->vma; - if (reloc->r_type == R_IHIHALF) - ihihalf_vaddr = relent->address; - else if (ihihalf_vaddr != (bfd_vma) -1) - abort (); - } -} - -/* The reloc processing routine for the optimized COFF linker. */ - -static boolean -coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - boolean hihalf; - bfd_vma hihalf_val; - - /* If we are performing a relocateable link, we don't need to do a - thing. The caller will take care of adjusting the reloc - addresses and symbol indices. */ - if (info->relocateable) - return true; - - hihalf = false; - hihalf_val = 0; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - bfd_byte *loc; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - asection *sec; - bfd_vma val; - boolean overflow; - unsigned long insn; - long signed_value; - unsigned long unsigned_value; - bfd_reloc_status_type rstat; - - symndx = rel->r_symndx; - loc = contents + rel->r_vaddr - input_section->vma; - - if (symndx == -1) - h = NULL; - else - h = obj_coff_sym_hashes (input_bfd)[symndx]; - - sym = NULL; - sec = NULL; - val = 0; - - /* An R_IHCONST reloc does not have a symbol. Instead, the - symbol index is an addend. R_IHCONST is always used in - conjunction with R_IHHALF. */ - if (rel->r_type != R_IHCONST) - { - if (h == NULL) - { - if (symndx == -1) - sec = bfd_abs_section_ptr; - else - { - sym = syms + symndx; - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - if (hihalf) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "missing IHCONST reloc", input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - hihalf = false; - } - } - - overflow = false; - - switch (rel->r_type) - { - default: - bfd_set_error (bfd_error_bad_value); - return false; - - case R_IREL: - insn = bfd_get_32 (input_bfd, loc); - - /* Extract the addend. */ - signed_value = EXTRACT_HWORD (insn); - signed_value = SIGN_EXTEND_HWORD (signed_value); - signed_value <<= 2; - - /* Unfortunately, there are two different versions of COFF - a29k. In the original AMD version, the value stored in - the field for the R_IREL reloc is a simple addend. In - the GNU version, the value is the negative of the address - of the reloc within section. We try to cope here by - assuming the AMD version, unless the addend is exactly - the negative of the address; in the latter case we assume - the GNU version. This means that something like - .text - nop - jmp i-4 - will fail, because the addend of -4 will happen to equal - the negative of the address within the section. The - compiler will never generate code like this. - - At some point in the future we may want to take out this - check. */ - - if (signed_value == - (long) (rel->r_vaddr - input_section->vma)) - signed_value = 0; - - /* Determine the destination of the jump. */ - signed_value += val; - - if ((signed_value & ~0x3ffff) == 0) - { - /* We can use an absolute jump. */ - insn |= (1 << 24); - } - else - { - /* Make the destination PC relative. */ - signed_value -= (input_section->output_section->vma - + input_section->output_offset - + (rel->r_vaddr - input_section->vma)); - if (signed_value > 0x1ffff || signed_value < - 0x20000) - { - overflow = true; - signed_value = 0; - } - } - - /* Put the adjusted value back into the instruction. */ - signed_value >>= 2; - insn = INSERT_HWORD (insn, signed_value); - - bfd_put_32 (input_bfd, (bfd_vma) insn, loc); - - break; - - case R_ILOHALF: - insn = bfd_get_32 (input_bfd, loc); - unsigned_value = EXTRACT_HWORD (insn); - unsigned_value += val; - insn = INSERT_HWORD (insn, unsigned_value); - bfd_put_32 (input_bfd, insn, loc); - break; - - case R_IHIHALF: - /* Save the value for the R_IHCONST reloc. */ - hihalf = true; - hihalf_val = val; - break; - - case R_IHCONST: - if (! hihalf) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "missing IHIHALF reloc", input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - hihalf_val = 0; - } - - insn = bfd_get_32 (input_bfd, loc); - unsigned_value = rel->r_symndx + hihalf_val; - unsigned_value >>= 16; - insn = INSERT_HWORD (insn, unsigned_value); - bfd_put_32 (input_bfd, (bfd_vma) insn, loc); - - hihalf = false; - - break; - - case R_BYTE: - case R_HWORD: - case R_WORD: - rstat = _bfd_relocate_contents (howto_table + rel->r_type, - input_bfd, val, loc); - if (rstat == bfd_reloc_overflow) - overflow = true; - else if (rstat != bfd_reloc_ok) - abort (); - break; - } - - if (overflow) - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else if (sym == NULL) - name = "*unknown*"; - else if (sym->_n._n_n._n_zeroes == 0 - && sym->_n._n_n._n_offset != 0) - name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; - else - { - strncpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - name = buf; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto_table[rel->r_type].name, (bfd_vma) 0, - input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - return true; -} - -#define coff_relocate_section coff_a29k_relocate_section - -/* We don't want to change the symndx of a R_IHCONST reloc, since it - is actually an addend, not a symbol index at all. */ - -/*ARGSUSED*/ -static boolean -coff_a29k_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) - bfd *obfd; - struct bfd_link_info *info; - bfd *ibfd; - asection *sec; - struct internal_reloc *irel; - boolean *adjustedp; -{ - if (irel->r_type == R_IHCONST) - *adjustedp = true; - else - *adjustedp = false; - return true; -} - -#define coff_adjust_symndx coff_a29k_adjust_symndx - -#include "coffcode.h" - -const bfd_target a29kcoff_big_vec = -{ - "coff-a29k-big", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC /* section flags */ - | SEC_LOAD | SEC_RELOC - | SEC_READONLY ), - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - /* hdrs */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - { - - _bfd_dummy_target, - coff_object_p, - bfd_generic_archive_p, - _bfd_dummy_target - }, - { - bfd_false, - coff_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { - bfd_false, - coff_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE - }; diff --git a/contrib/gdb/bfd/coff-alpha.c b/contrib/gdb/bfd/coff-alpha.c deleted file mode 100644 index b14f3ef207b..00000000000 --- a/contrib/gdb/bfd/coff-alpha.c +++ /dev/null @@ -1,2390 +0,0 @@ -/* BFD back-end for ALPHA Extended-Coff files. - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Modified from coff-mips.c by Steve Chamberlain and - Ian Lance Taylor . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" -#include "coff/alpha.h" -#include "aout/ar.h" -#include "libcoff.h" -#include "libecoff.h" - -/* Prototypes for static functions. */ - -static const bfd_target *alpha_ecoff_object_p PARAMS ((bfd *)); -static boolean alpha_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr)); -static PTR alpha_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr)); -static void alpha_ecoff_swap_reloc_in PARAMS ((bfd *, PTR, - struct internal_reloc *)); -static void alpha_ecoff_swap_reloc_out PARAMS ((bfd *, - const struct internal_reloc *, - PTR)); -static void alpha_adjust_reloc_in PARAMS ((bfd *, - const struct internal_reloc *, - arelent *)); -static void alpha_adjust_reloc_out PARAMS ((bfd *, const arelent *, - struct internal_reloc *)); -static bfd_byte *alpha_ecoff_get_relocated_section_contents - PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *data, boolean relocateable, asymbol **symbols)); -static bfd_vma alpha_convert_external_reloc - PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *, - struct ecoff_link_hash_entry *)); -static boolean alpha_relocate_section PARAMS ((bfd *, struct bfd_link_info *, - bfd *, asection *, - bfd_byte *, PTR)); -static boolean alpha_adjust_headers - PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *)); -static PTR alpha_ecoff_read_ar_hdr PARAMS ((bfd *)); -static bfd *alpha_ecoff_get_elt_at_filepos PARAMS ((bfd *, file_ptr)); -static bfd *alpha_ecoff_openr_next_archived_file PARAMS ((bfd *, bfd *)); -static bfd *alpha_ecoff_get_elt_at_index PARAMS ((bfd *, symindex)); - -/* ECOFF has COFF sections, but the debugging information is stored in - a completely different format. ECOFF targets use some of the - swapping routines from coffswap.h, and some of the generic COFF - routines in coffgen.c, but, unlike the real COFF targets, do not - use coffcode.h itself. - - Get the generic COFF swapping routines, except for the reloc, - symbol, and lineno ones. Give them ecoff names. Define some - accessor macros for the large sizes used for Alpha ECOFF. */ - -#define GET_FILEHDR_SYMPTR bfd_h_get_64 -#define PUT_FILEHDR_SYMPTR bfd_h_put_64 -#define GET_AOUTHDR_TSIZE bfd_h_get_64 -#define PUT_AOUTHDR_TSIZE bfd_h_put_64 -#define GET_AOUTHDR_DSIZE bfd_h_get_64 -#define PUT_AOUTHDR_DSIZE bfd_h_put_64 -#define GET_AOUTHDR_BSIZE bfd_h_get_64 -#define PUT_AOUTHDR_BSIZE bfd_h_put_64 -#define GET_AOUTHDR_ENTRY bfd_h_get_64 -#define PUT_AOUTHDR_ENTRY bfd_h_put_64 -#define GET_AOUTHDR_TEXT_START bfd_h_get_64 -#define PUT_AOUTHDR_TEXT_START bfd_h_put_64 -#define GET_AOUTHDR_DATA_START bfd_h_get_64 -#define PUT_AOUTHDR_DATA_START bfd_h_put_64 -#define GET_SCNHDR_PADDR bfd_h_get_64 -#define PUT_SCNHDR_PADDR bfd_h_put_64 -#define GET_SCNHDR_VADDR bfd_h_get_64 -#define PUT_SCNHDR_VADDR bfd_h_put_64 -#define GET_SCNHDR_SIZE bfd_h_get_64 -#define PUT_SCNHDR_SIZE bfd_h_put_64 -#define GET_SCNHDR_SCNPTR bfd_h_get_64 -#define PUT_SCNHDR_SCNPTR bfd_h_put_64 -#define GET_SCNHDR_RELPTR bfd_h_get_64 -#define PUT_SCNHDR_RELPTR bfd_h_put_64 -#define GET_SCNHDR_LNNOPTR bfd_h_get_64 -#define PUT_SCNHDR_LNNOPTR bfd_h_put_64 - -#define ALPHAECOFF - -#define NO_COFF_RELOCS -#define NO_COFF_SYMBOLS -#define NO_COFF_LINENOS -#define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in -#define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out -#define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in -#define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out -#define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in -#define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out -#include "coffswap.h" - -/* Get the ECOFF swapping routines. */ -#define ECOFF_64 -#include "ecoffswap.h" - -/* How to process the various reloc types. */ - -static bfd_reloc_status_type -reloc_nil PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message) - bfd *abfd; - arelent *reloc; - asymbol *sym; - PTR data; - asection *sec; - bfd *output_bfd; - char **error_message; -{ - return bfd_reloc_ok; -} - -/* In case we're on a 32-bit machine, construct a 64-bit "-1" value - from smaller values. Start with zero, widen, *then* decrement. */ -#define MINUS_ONE (((bfd_vma)0) - 1) - -static reloc_howto_type alpha_howto_table[] = -{ - /* Reloc type 0 is ignored by itself. However, it appears after a - GPDISP reloc to identify the location where the low order 16 bits - of the gp register are loaded. */ - HOWTO (ALPHA_R_IGNORE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - reloc_nil, /* special_function */ - "IGNORE", /* name */ - true, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ - - /* A 32 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFLONG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFQUAD, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFQUAD", /* name */ - true, /* partial_inplace */ - MINUS_ONE, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit GP relative offset. This is just like REFLONG except - that when the value is used the value of the gp register will be - added in. */ - HOWTO (ALPHA_R_GPREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "GPREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Used for an instruction that refers to memory off the GP - register. The offset is 16 bits of the 32 bit instruction. This - reloc always seems to be against the .lita section. */ - HOWTO (ALPHA_R_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* This reloc only appears immediately following a LITERAL reloc. - It identifies a use of the literal. It seems that the linker can - use this to eliminate a portion of the .lita section. The symbol - index is special: 1 means the literal address is in the base - register of a memory format instruction; 2 means the literal - address is in the byte offset register of a byte-manipulation - instruction; 3 means the literal address is in the target - register of a jsr instruction. This does not actually do any - relocation. */ - HOWTO (ALPHA_R_LITUSE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - reloc_nil, /* special_function */ - "LITUSE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load the gp register. This is always used for a ldah instruction - which loads the upper 16 bits of the gp register. The next reloc - will be an IGNORE reloc which identifies the location of the lda - instruction which loads the lower 16 bits. The symbol index of - the GPDISP instruction appears to actually be the number of bytes - between the ldah and lda instructions. This gives two different - ways to determine where the lda instruction is; I don't know why - both are used. The value to use for the relocation is the - difference between the GP value and the current location; the - load will always be done against a register holding the current - address. */ - HOWTO (ALPHA_R_GPDISP, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - reloc_nil, /* special_function */ - "GPDISP", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* A 21 bit branch. The native assembler generates these for - branches within the text segment, and also fills in the PC - relative offset in the instruction. */ - HOWTO (ALPHA_R_BRADDR, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 21, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "BRADDR", /* name */ - true, /* partial_inplace */ - 0x1fffff, /* src_mask */ - 0x1fffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A hint for a jump to a register. */ - HOWTO (ALPHA_R_HINT, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 14, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "HINT", /* name */ - true, /* partial_inplace */ - 0x3fff, /* src_mask */ - 0x3fff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL64, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL64", /* name */ - true, /* partial_inplace */ - MINUS_ONE, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* Push a value on the reloc evaluation stack. */ - HOWTO (ALPHA_R_OP_PUSH, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PUSH", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Store the value from the stack at the given address. Store it in - a bitfield of size r_size starting at bit position r_offset. */ - HOWTO (ALPHA_R_OP_STORE, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_STORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* Subtract the reloc address from the value on the top of the - relocation stack. */ - HOWTO (ALPHA_R_OP_PSUB, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PSUB", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Shift the value on the top of the relocation stack right by the - given value. */ - HOWTO (ALPHA_R_OP_PRSHIFT, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PRSHIFT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Adjust the GP value for a new range in the object file. */ - HOWTO (ALPHA_R_GPVALUE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "GPVALUE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false) /* pcrel_offset */ -}; - -/* Recognize an Alpha ECOFF file. */ - -static const bfd_target * -alpha_ecoff_object_p (abfd) - bfd *abfd; -{ - static const bfd_target *ret; - - ret = coff_object_p (abfd); - - if (ret != NULL) - { - asection *sec; - - /* Alpha ECOFF has a .pdata section. The lnnoptr field of the - .pdata section is the number of entries it contains. Each - entry takes up 8 bytes. The number of entries is required - since the section is aligned to a 16 byte boundary. When we - link .pdata sections together, we do not want to include the - alignment bytes. We handle this on input by faking the size - of the .pdata section to remove the unwanted alignment bytes. - On output we will set the lnnoptr field and force the - alignment. */ - sec = bfd_get_section_by_name (abfd, _PDATA); - if (sec != (asection *) NULL) - { - bfd_size_type size; - - size = sec->line_filepos * 8; - BFD_ASSERT (size == bfd_section_size (abfd, sec) - || size + 8 == bfd_section_size (abfd, sec)); - if (! bfd_set_section_size (abfd, sec, size)) - return NULL; - } - } - - return ret; -} - -/* See whether the magic number matches. */ - -static boolean -alpha_ecoff_bad_format_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - if (ALPHA_ECOFF_BADMAG (*internal_f)) - return false; - - return true; -} - -/* This is a hook called by coff_real_object_p to create any backend - specific information. */ - -static PTR -alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr) - bfd *abfd; - PTR filehdr; - PTR aouthdr; -{ - PTR ecoff; - - ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr); - - if (ecoff != NULL) - { - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - /* Set additional BFD flags according to the object type from the - machine specific file header flags. */ - switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK) - { - case F_ALPHA_SHARABLE: - abfd->flags |= DYNAMIC; - break; - case F_ALPHA_CALL_SHARED: - /* Always executable if using shared libraries as the run time - loader might resolve undefined references. */ - abfd->flags |= (DYNAMIC | EXEC_P); - break; - } - } - return ecoff; -} - -/* Reloc handling. */ - -/* Swap a reloc in. */ - -static void -alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern) - bfd *abfd; - PTR ext_ptr; - struct internal_reloc *intern; -{ - const RELOC *ext = (RELOC *) ext_ptr; - - intern->r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext->r_vaddr); - intern->r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_symndx); - - BFD_ASSERT (bfd_header_little_endian (abfd)); - - intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) - >> RELOC_BITS0_TYPE_SH_LITTLE); - intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; - intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) - >> RELOC_BITS1_OFFSET_SH_LITTLE); - /* Ignored the reserved bits. */ - intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) - >> RELOC_BITS3_SIZE_SH_LITTLE); - - if (intern->r_type == ALPHA_R_LITUSE - || intern->r_type == ALPHA_R_GPDISP) - { - /* Handle the LITUSE and GPDISP relocs specially. Its symndx - value is not actually a symbol index, but is instead a - special code. We put the code in the r_size field, and - clobber the symndx. */ - if (intern->r_size != 0) - abort (); - intern->r_size = intern->r_symndx; - intern->r_symndx = RELOC_SECTION_NONE; - } - else if (intern->r_type == ALPHA_R_IGNORE) - { - /* The IGNORE reloc generally follows a GPDISP reloc, and is - against the .lita section. The section is irrelevant. */ - if (! intern->r_extern && - intern->r_symndx == RELOC_SECTION_ABS) - abort (); - if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA) - intern->r_symndx = RELOC_SECTION_ABS; - } -} - -/* Swap a reloc out. */ - -static void -alpha_ecoff_swap_reloc_out (abfd, intern, dst) - bfd *abfd; - const struct internal_reloc *intern; - PTR dst; -{ - RELOC *ext = (RELOC *) dst; - long symndx; - unsigned char size; - - /* Undo the hackery done in swap_reloc_in. */ - if (intern->r_type == ALPHA_R_LITUSE - || intern->r_type == ALPHA_R_GPDISP) - { - symndx = intern->r_size; - size = 0; - } - else if (intern->r_type == ALPHA_R_IGNORE - && ! intern->r_extern - && intern->r_symndx == RELOC_SECTION_ABS) - { - symndx = RELOC_SECTION_LITA; - size = intern->r_size; - } - else - { - symndx = intern->r_symndx; - size = intern->r_size; - } - - BFD_ASSERT (intern->r_extern - || (intern->r_symndx >= 0 && intern->r_symndx <= 14)); - - bfd_h_put_64 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr); - bfd_h_put_32 (abfd, symndx, (bfd_byte *) ext->r_symndx); - - BFD_ASSERT (bfd_header_little_endian (abfd)); - - ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE) - & RELOC_BITS0_TYPE_LITTLE); - ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0) - | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE) - & RELOC_BITS1_OFFSET_LITTLE)); - ext->r_bits[2] = 0; - ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE) - & RELOC_BITS3_SIZE_LITTLE); -} - -/* Finish canonicalizing a reloc. Part of this is generic to all - ECOFF targets, and that part is in ecoff.c. The rest is done in - this backend routine. It must fill in the howto field. */ - -static void -alpha_adjust_reloc_in (abfd, intern, rptr) - bfd *abfd; - const struct internal_reloc *intern; - arelent *rptr; -{ - if (intern->r_type > ALPHA_R_GPVALUE) - abort (); - - switch (intern->r_type) - { - case ALPHA_R_BRADDR: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - /* The PC relative relocs do not seem to use the section VMA as - a negative addend. */ - rptr->addend = 0; - break; - - case ALPHA_R_GPREL32: - case ALPHA_R_LITERAL: - /* Copy the gp value for this object file into the addend, to - ensure that we are not confused by the linker. */ - if (! intern->r_extern) - rptr->addend += ecoff_data (abfd)->gp; - break; - - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - /* The LITUSE and GPDISP relocs do not use a symbol, or an - addend, but they do use a special code. Put this code in the - addend field. */ - rptr->addend = intern->r_size; - break; - - case ALPHA_R_OP_STORE: - /* The STORE reloc needs the size and offset fields. We store - them in the addend. */ - BFD_ASSERT (intern->r_offset <= 256 && intern->r_size <= 256); - rptr->addend = (intern->r_offset << 8) + intern->r_size; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - /* The PUSH, PSUB and PRSHIFT relocs do not actually use an - address. I believe that the address supplied is really an - addend. */ - rptr->addend = intern->r_vaddr; - break; - - case ALPHA_R_GPVALUE: - /* Set the addend field to the new GP value. */ - rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp; - break; - - case ALPHA_R_IGNORE: - /* If the type is ALPHA_R_IGNORE, make sure this is a reference - to the absolute section so that the reloc is ignored. For - some reason the address of this reloc type is not adjusted by - the section vma. We record the gp value for this object file - here, for convenience when doing the GPDISP relocation. */ - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rptr->address = intern->r_vaddr; - rptr->addend = ecoff_data (abfd)->gp; - break; - - default: - break; - } - - rptr->howto = &alpha_howto_table[intern->r_type]; -} - -/* When writing out a reloc we need to pull some values back out of - the addend field into the reloc. This is roughly the reverse of - alpha_adjust_reloc_in, except that there are several changes we do - not need to undo. */ - -static void -alpha_adjust_reloc_out (abfd, rel, intern) - bfd *abfd; - const arelent *rel; - struct internal_reloc *intern; -{ - switch (intern->r_type) - { - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - intern->r_size = rel->addend; - break; - - case ALPHA_R_OP_STORE: - intern->r_size = rel->addend & 0xff; - intern->r_offset = (rel->addend >> 8) & 0xff; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - intern->r_vaddr = rel->addend; - break; - - case ALPHA_R_IGNORE: - intern->r_vaddr = rel->address; - break; - - default: - break; - } -} - -/* The size of the stack for the relocation evaluator. */ -#define RELOC_STACKSIZE (10) - -/* Alpha ECOFF relocs have a built in expression evaluator as well as - other interdependencies. Rather than use a bunch of special - functions and global variables, we use a single routine to do all - the relocation for a section. I haven't yet worked out how the - assembler is going to handle this. */ - -static bfd_byte * -alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order, - data, relocateable, symbols) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - bfd *output_bfd = relocateable ? abfd : (bfd *) NULL; - bfd_vma gp; - boolean gp_undefined; - bfd_vma stack[RELOC_STACKSIZE]; - int tos = 0; - - if (reloc_size < 0) - goto error_return; - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - if (! bfd_get_section_contents (input_bfd, input_section, data, - (file_ptr) 0, input_section->_raw_size)) - goto error_return; - - /* The section size is not going to change. */ - input_section->_cooked_size = input_section->_raw_size; - input_section->reloc_done = true; - - reloc_count = bfd_canonicalize_reloc (input_bfd, input_section, - reloc_vector, symbols); - if (reloc_count < 0) - goto error_return; - if (reloc_count == 0) - goto successful_return; - - /* Get the GP value for the output BFD. */ - gp_undefined = false; - gp = _bfd_get_gp_value (abfd); - if (gp == 0) - { - if (relocateable != false) - { - asection *sec; - bfd_vma lo; - - /* Make up a value. */ - lo = (bfd_vma) -1; - for (sec = abfd->sections; sec != NULL; sec = sec->next) - { - if (sec->vma < lo - && (strcmp (sec->name, ".sbss") == 0 - || strcmp (sec->name, ".sdata") == 0 - || strcmp (sec->name, ".lit4") == 0 - || strcmp (sec->name, ".lit8") == 0 - || strcmp (sec->name, ".lita") == 0)) - lo = sec->vma; - } - gp = lo + 0x8000; - _bfd_set_gp_value (abfd, gp); - } - else - { - struct bfd_link_hash_entry *h; - - h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false, - true); - if (h == (struct bfd_link_hash_entry *) NULL - || h->type != bfd_link_hash_defined) - gp_undefined = true; - else - { - gp = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - _bfd_set_gp_value (abfd, gp); - } - } - } - - for (; *reloc_vector != (arelent *) NULL; reloc_vector++) - { - arelent *rel; - bfd_reloc_status_type r; - char *err; - - rel = *reloc_vector; - r = bfd_reloc_ok; - switch (rel->howto->type) - { - case ALPHA_R_IGNORE: - rel->address += input_section->output_offset; - break; - - case ALPHA_R_REFLONG: - case ALPHA_R_REFQUAD: - case ALPHA_R_BRADDR: - case ALPHA_R_HINT: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - if (relocateable - && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0) - { - rel->address += input_section->output_offset; - break; - } - r = bfd_perform_relocation (input_bfd, rel, data, input_section, - output_bfd, &err); - break; - - case ALPHA_R_GPREL32: - /* This relocation is used in a switch table. It is a 32 - bit offset from the current GP value. We must adjust it - by the different between the original GP value and the - current GP value. The original GP value is stored in the - addend. We adjust the addend and let - bfd_perform_relocation finish the job. */ - rel->addend -= gp; - r = bfd_perform_relocation (input_bfd, rel, data, input_section, - output_bfd, &err); - if (r == bfd_reloc_ok && gp_undefined) - { - r = bfd_reloc_dangerous; - err = (char *) "GP relative relocation used when GP not defined"; - } - break; - - case ALPHA_R_LITERAL: - /* This is a reference to a literal value, generally - (always?) in the .lita section. This is a 16 bit GP - relative relocation. Sometimes the subsequent reloc is a - LITUSE reloc, which indicates how this reloc is used. - This sometimes permits rewriting the two instructions - referred to by the LITERAL and the LITUSE into different - instructions which do not refer to .lita. This can save - a memory reference, and permits removing a value from - .lita thus saving GP relative space. - - We do not these optimizations. To do them we would need - to arrange to link the .lita section first, so that by - the time we got here we would know the final values to - use. This would not be particularly difficult, but it is - not currently implemented. */ - - { - unsigned long insn; - - /* I believe that the LITERAL reloc will only apply to a - ldq or ldl instruction, so check my assumption. */ - insn = bfd_get_32 (input_bfd, data + rel->address); - BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 - || ((insn >> 26) & 0x3f) == 0x28); - - rel->addend -= gp; - r = bfd_perform_relocation (input_bfd, rel, data, input_section, - output_bfd, &err); - if (r == bfd_reloc_ok && gp_undefined) - { - r = bfd_reloc_dangerous; - err = - (char *) "GP relative relocation used when GP not defined"; - } - } - break; - - case ALPHA_R_LITUSE: - /* See ALPHA_R_LITERAL above for the uses of this reloc. It - does not cause anything to happen, itself. */ - rel->address += input_section->output_offset; - break; - - case ALPHA_R_GPDISP: - /* This marks the ldah of an ldah/lda pair which loads the - gp register with the difference of the gp value and the - current location. The second of the pair is r_size bytes - ahead; it used to be marked with an ALPHA_R_IGNORE reloc, - but that no longer happens in OSF/1 3.2. */ - { - unsigned long insn1, insn2; - bfd_vma addend; - - /* Get the two instructions. */ - insn1 = bfd_get_32 (input_bfd, data + rel->address); - insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend); - - BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ - BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ - - /* Get the existing addend. We must account for the sign - extension done by lda and ldah. */ - addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); - if (insn1 & 0x8000) - { - addend -= 0x80000000; - addend -= 0x80000000; - } - if (insn2 & 0x8000) - addend -= 0x10000; - - /* The existing addend includes the different between the - gp of the input BFD and the address in the input BFD. - Subtract this out. */ - addend -= (ecoff_data (input_bfd)->gp - - (input_section->vma + rel->address)); - - /* Now add in the final gp value, and subtract out the - final address. */ - addend += (gp - - (input_section->output_section->vma - + input_section->output_offset - + rel->address)); - - /* Change the instructions, accounting for the sign - extension, and write them out. */ - if (addend & 0x8000) - addend += 0x10000; - insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); - insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); - - bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address); - bfd_put_32 (input_bfd, (bfd_vma) insn2, - data + rel->address + rel->addend); - - rel->address += input_section->output_offset; - } - break; - - case ALPHA_R_OP_PUSH: - /* Push a value on the reloc evaluation stack. */ - { - asymbol *symbol; - bfd_vma relocation; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - /* Figure out the relocation of this symbol. */ - symbol = *rel->sym_ptr_ptr; - - if (bfd_is_und_section (symbol->section)) - r = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += rel->addend; - - if (tos >= RELOC_STACKSIZE) - abort (); - - stack[tos++] = relocation; - } - break; - - case ALPHA_R_OP_STORE: - /* Store a value from the reloc stack into a bitfield. */ - { - bfd_vma val; - int offset, size; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - if (tos == 0) - abort (); - - /* The offset and size for this reloc are encoded into the - addend field by alpha_adjust_reloc_in. */ - offset = (rel->addend >> 8) & 0xff; - size = rel->addend & 0xff; - - val = bfd_get_64 (abfd, data + rel->address); - val &=~ (((1 << size) - 1) << offset); - val |= (stack[--tos] & ((1 << size) - 1)) << offset; - bfd_put_64 (abfd, val, data + rel->address); - } - break; - - case ALPHA_R_OP_PSUB: - /* Subtract a value from the top of the stack. */ - { - asymbol *symbol; - bfd_vma relocation; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - /* Figure out the relocation of this symbol. */ - symbol = *rel->sym_ptr_ptr; - - if (bfd_is_und_section (symbol->section)) - r = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += rel->addend; - - if (tos == 0) - abort (); - - stack[tos - 1] -= relocation; - } - break; - - case ALPHA_R_OP_PRSHIFT: - /* Shift the value on the top of the stack. */ - { - asymbol *symbol; - bfd_vma relocation; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - /* Figure out the relocation of this symbol. */ - symbol = *rel->sym_ptr_ptr; - - if (bfd_is_und_section (symbol->section)) - r = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += rel->addend; - - if (tos == 0) - abort (); - - stack[tos - 1] >>= relocation; - } - break; - - case ALPHA_R_GPVALUE: - /* I really don't know if this does the right thing. */ - gp = rel->addend; - gp_undefined = false; - break; - - default: - abort (); - } - - if (relocateable) - { - asection *os = input_section->output_section; - - /* A partial link, so keep the relocs. */ - os->orelocation[os->reloc_count] = rel; - os->reloc_count++; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - case bfd_reloc_undefined: - if (! ((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), - input_bfd, input_section, rel->address))) - goto error_return; - break; - case bfd_reloc_dangerous: - if (! ((*link_info->callbacks->reloc_dangerous) - (link_info, err, input_bfd, input_section, - rel->address))) - goto error_return; - break; - case bfd_reloc_overflow: - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), - rel->howto->name, rel->addend, input_bfd, - input_section, rel->address))) - goto error_return; - break; - case bfd_reloc_outofrange: - default: - abort (); - break; - } - } - } - - if (tos != 0) - abort (); - - successful_return: - if (reloc_vector != NULL) - free (reloc_vector); - return data; - - error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} - -/* Get the howto structure for a generic reloc type. */ - -static reloc_howto_type * -alpha_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - int alpha_type; - - switch (code) - { - case BFD_RELOC_32: - alpha_type = ALPHA_R_REFLONG; - break; - case BFD_RELOC_64: - case BFD_RELOC_CTOR: - alpha_type = ALPHA_R_REFQUAD; - break; - case BFD_RELOC_GPREL32: - alpha_type = ALPHA_R_GPREL32; - break; - case BFD_RELOC_ALPHA_LITERAL: - alpha_type = ALPHA_R_LITERAL; - break; - case BFD_RELOC_ALPHA_LITUSE: - alpha_type = ALPHA_R_LITUSE; - break; - case BFD_RELOC_ALPHA_GPDISP_HI16: - alpha_type = ALPHA_R_GPDISP; - break; - case BFD_RELOC_ALPHA_GPDISP_LO16: - alpha_type = ALPHA_R_IGNORE; - break; - case BFD_RELOC_23_PCREL_S2: - alpha_type = ALPHA_R_BRADDR; - break; - case BFD_RELOC_ALPHA_HINT: - alpha_type = ALPHA_R_HINT; - break; - case BFD_RELOC_16_PCREL: - alpha_type = ALPHA_R_SREL16; - break; - case BFD_RELOC_32_PCREL: - alpha_type = ALPHA_R_SREL32; - break; - case BFD_RELOC_64_PCREL: - alpha_type = ALPHA_R_SREL64; - break; -#if 0 - case ???: - alpha_type = ALPHA_R_OP_PUSH; - break; - case ???: - alpha_type = ALPHA_R_OP_STORE; - break; - case ???: - alpha_type = ALPHA_R_OP_PSUB; - break; - case ???: - alpha_type = ALPHA_R_OP_PRSHIFT; - break; - case ???: - alpha_type = ALPHA_R_GPVALUE; - break; -#endif - default: - return (reloc_howto_type *) NULL; - } - - return &alpha_howto_table[alpha_type]; -} - -/* A helper routine for alpha_relocate_section which converts an - external reloc when generating relocateable output. Returns the - relocation amount. */ - -static bfd_vma -alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - struct external_reloc *ext_rel; - struct ecoff_link_hash_entry *h; -{ - unsigned long r_symndx; - bfd_vma relocation; - - BFD_ASSERT (info->relocateable); - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - const char *name; - - /* This symbol is defined in the output. Convert the reloc from - being against the symbol to being against the section. */ - - /* Clear the r_extern bit. */ - ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE; - - /* Compute a new r_symndx value. */ - hsec = h->root.u.def.section; - name = bfd_get_section_name (output_bfd, hsec->output_section); - - r_symndx = -1; - switch (name[1]) - { - case 'A': - if (strcmp (name, "*ABS*") == 0) - r_symndx = RELOC_SECTION_ABS; - break; - case 'b': - if (strcmp (name, ".bss") == 0) - r_symndx = RELOC_SECTION_BSS; - break; - case 'd': - if (strcmp (name, ".data") == 0) - r_symndx = RELOC_SECTION_DATA; - break; - case 'f': - if (strcmp (name, ".fini") == 0) - r_symndx = RELOC_SECTION_FINI; - break; - case 'i': - if (strcmp (name, ".init") == 0) - r_symndx = RELOC_SECTION_INIT; - break; - case 'l': - if (strcmp (name, ".lita") == 0) - r_symndx = RELOC_SECTION_LITA; - else if (strcmp (name, ".lit8") == 0) - r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - r_symndx = RELOC_SECTION_LIT4; - break; - case 'p': - if (strcmp (name, ".pdata") == 0) - r_symndx = RELOC_SECTION_PDATA; - break; - case 'r': - if (strcmp (name, ".rdata") == 0) - r_symndx = RELOC_SECTION_RDATA; - else if (strcmp (name, ".rconst") == 0) - r_symndx = RELOC_SECTION_RCONST; - break; - case 's': - if (strcmp (name, ".sdata") == 0) - r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - r_symndx = RELOC_SECTION_SBSS; - break; - case 't': - if (strcmp (name, ".text") == 0) - r_symndx = RELOC_SECTION_TEXT; - break; - case 'x': - if (strcmp (name, ".xdata") == 0) - r_symndx = RELOC_SECTION_XDATA; - break; - } - - if (r_symndx == -1) - abort (); - - /* Add the section VMA and the symbol value. */ - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - } - else - { - /* Change the symndx value to the right one for - the output BFD. */ - r_symndx = h->indx; - if (r_symndx == -1) - { - /* Caller must give an error. */ - r_symndx = 0; - } - relocation = 0; - } - - /* Write out the new r_symndx value. */ - bfd_h_put_32 (input_bfd, (bfd_vma) r_symndx, - (bfd_byte *) ext_rel->r_symndx); - - return relocation; -} - -/* Relocate a section while linking an Alpha ECOFF file. This is - quite similar to get_relocated_section_contents. Perhaps they - could be combined somehow. */ - -static boolean -alpha_relocate_section (output_bfd, info, input_bfd, input_section, - contents, external_relocs) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - PTR external_relocs; -{ - asection **symndx_to_section, *lita_sec; - struct ecoff_link_hash_entry **sym_hashes; - bfd_vma gp; - boolean gp_undefined; - bfd_vma stack[RELOC_STACKSIZE]; - int tos = 0; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - - /* We keep a table mapping the symndx found in an internal reloc to - the appropriate section. This is faster than looking up the - section by name each time. */ - symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; - if (symndx_to_section == (asection **) NULL) - { - symndx_to_section = ((asection **) - bfd_alloc (input_bfd, - (NUM_RELOC_SECTIONS - * sizeof (asection *)))); - if (!symndx_to_section) - return false; - - symndx_to_section[RELOC_SECTION_NONE] = NULL; - symndx_to_section[RELOC_SECTION_TEXT] = - bfd_get_section_by_name (input_bfd, ".text"); - symndx_to_section[RELOC_SECTION_RDATA] = - bfd_get_section_by_name (input_bfd, ".rdata"); - symndx_to_section[RELOC_SECTION_DATA] = - bfd_get_section_by_name (input_bfd, ".data"); - symndx_to_section[RELOC_SECTION_SDATA] = - bfd_get_section_by_name (input_bfd, ".sdata"); - symndx_to_section[RELOC_SECTION_SBSS] = - bfd_get_section_by_name (input_bfd, ".sbss"); - symndx_to_section[RELOC_SECTION_BSS] = - bfd_get_section_by_name (input_bfd, ".bss"); - symndx_to_section[RELOC_SECTION_INIT] = - bfd_get_section_by_name (input_bfd, ".init"); - symndx_to_section[RELOC_SECTION_LIT8] = - bfd_get_section_by_name (input_bfd, ".lit8"); - symndx_to_section[RELOC_SECTION_LIT4] = - bfd_get_section_by_name (input_bfd, ".lit4"); - symndx_to_section[RELOC_SECTION_XDATA] = - bfd_get_section_by_name (input_bfd, ".xdata"); - symndx_to_section[RELOC_SECTION_PDATA] = - bfd_get_section_by_name (input_bfd, ".pdata"); - symndx_to_section[RELOC_SECTION_FINI] = - bfd_get_section_by_name (input_bfd, ".fini"); - symndx_to_section[RELOC_SECTION_LITA] = - bfd_get_section_by_name (input_bfd, ".lita"); - symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr; - symndx_to_section[RELOC_SECTION_RCONST] = - bfd_get_section_by_name (input_bfd, ".rconst"); - - ecoff_data (input_bfd)->symndx_to_section = symndx_to_section; - } - - sym_hashes = ecoff_data (input_bfd)->sym_hashes; - - /* On the Alpha, the .lita section must be addressable by the global - pointer. To support large programs, we need to allow multiple - global pointers. This works as long as each input .lita section - is <64KB big. This implies that when producing relocatable - output, the .lita section is limited to 64KB. . */ - - lita_sec = symndx_to_section[RELOC_SECTION_LITA]; - gp = _bfd_get_gp_value (output_bfd); - if (! info->relocateable && lita_sec != NULL) - { - struct ecoff_section_tdata *lita_sec_data; - - /* Make sure we have a section data structure to which we can - hang on to the gp value we pick for the section. */ - lita_sec_data = ecoff_section_data (input_bfd, lita_sec); - if (lita_sec_data == NULL) - { - lita_sec_data = ((struct ecoff_section_tdata *) - bfd_zalloc (input_bfd, - sizeof (struct ecoff_section_tdata))); - ecoff_section_data (input_bfd, lita_sec) = lita_sec_data; - } - - if (lita_sec_data->gp != 0) - { - /* If we already assigned a gp to this section, we better - stick with that value. */ - gp = lita_sec_data->gp; - } - else - { - bfd_vma lita_vma; - bfd_size_type lita_size; - - lita_vma = lita_sec->output_offset + lita_sec->output_section->vma; - lita_size = lita_sec->_cooked_size; - if (lita_size == 0) - lita_size = lita_sec->_raw_size; - - if (gp == 0 - || lita_vma < gp - 0x8000 - || lita_vma + lita_size >= gp + 0x8000) - { - /* Either gp hasn't been set at all or the current gp - cannot address this .lita section. In both cases we - reset the gp to point into the "middle" of the - current input .lita section. */ - if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning) - { - (*info->callbacks->warning) (info, - "using multiple gp values", - (char *) NULL, output_bfd, - (asection *) NULL, (bfd_vma) 0); - ecoff_data (output_bfd)->issued_multiple_gp_warning = true; - } - if (lita_vma < gp - 0x8000) - gp = lita_vma + lita_size - 0x8000; - else - gp = lita_vma + 0x8000; - - } - - lita_sec_data->gp = gp; - } - - _bfd_set_gp_value (output_bfd, gp); - } - - gp_undefined = (gp == 0); - - BFD_ASSERT (bfd_header_little_endian (output_bfd)); - BFD_ASSERT (bfd_header_little_endian (input_bfd)); - - ext_rel = (struct external_reloc *) external_relocs; - ext_rel_end = ext_rel + input_section->reloc_count; - for (; ext_rel < ext_rel_end; ext_rel++) - { - bfd_vma r_vaddr; - unsigned long r_symndx; - int r_type; - int r_extern; - int r_offset; - int r_size; - boolean relocatep; - boolean adjust_addrp; - boolean gp_usedp; - bfd_vma addend; - - r_vaddr = bfd_h_get_64 (input_bfd, (bfd_byte *) ext_rel->r_vaddr); - r_symndx = bfd_h_get_32 (input_bfd, (bfd_byte *) ext_rel->r_symndx); - - r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) - >> RELOC_BITS0_TYPE_SH_LITTLE); - r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; - r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) - >> RELOC_BITS1_OFFSET_SH_LITTLE); - /* Ignored the reserved bits. */ - r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) - >> RELOC_BITS3_SIZE_SH_LITTLE); - - relocatep = false; - adjust_addrp = true; - gp_usedp = false; - addend = 0; - - switch (r_type) - { - default: - abort (); - - case ALPHA_R_IGNORE: - /* This reloc appears after a GPDISP reloc. On earlier - versions of OSF/1, It marked the position of the second - instruction to be altered by the GPDISP reloc, but it is - not otherwise used for anything. For some reason, the - address of the relocation does not appear to include the - section VMA, unlike the other relocation types. */ - if (info->relocateable) - bfd_h_put_64 (input_bfd, - input_section->output_offset + r_vaddr, - (bfd_byte *) ext_rel->r_vaddr); - adjust_addrp = false; - break; - - case ALPHA_R_REFLONG: - case ALPHA_R_REFQUAD: - case ALPHA_R_BRADDR: - case ALPHA_R_HINT: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - relocatep = true; - break; - - case ALPHA_R_GPREL32: - /* This relocation is used in a switch table. It is a 32 - bit offset from the current GP value. We must adjust it - by the different between the original GP value and the - current GP value. */ - relocatep = true; - addend = ecoff_data (input_bfd)->gp - gp; - gp_usedp = true; - break; - - case ALPHA_R_LITERAL: - /* This is a reference to a literal value, generally - (always?) in the .lita section. This is a 16 bit GP - relative relocation. Sometimes the subsequent reloc is a - LITUSE reloc, which indicates how this reloc is used. - This sometimes permits rewriting the two instructions - referred to by the LITERAL and the LITUSE into different - instructions which do not refer to .lita. This can save - a memory reference, and permits removing a value from - .lita thus saving GP relative space. - - We do not these optimizations. To do them we would need - to arrange to link the .lita section first, so that by - the time we got here we would know the final values to - use. This would not be particularly difficult, but it is - not currently implemented. */ - - /* I believe that the LITERAL reloc will only apply to a ldq - or ldl instruction, so check my assumption. */ - { - unsigned long insn; - - insn = bfd_get_32 (input_bfd, - contents + r_vaddr - input_section->vma); - BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 - || ((insn >> 26) & 0x3f) == 0x28); - } - - relocatep = true; - addend = ecoff_data (input_bfd)->gp - gp; - gp_usedp = true; - break; - - case ALPHA_R_LITUSE: - /* See ALPHA_R_LITERAL above for the uses of this reloc. It - does not cause anything to happen, itself. */ - break; - - case ALPHA_R_GPDISP: - /* This marks the ldah of an ldah/lda pair which loads the - gp register with the difference of the gp value and the - current location. The second of the pair is r_symndx - bytes ahead. It used to be marked with an ALPHA_R_IGNORE - reloc, but OSF/1 3.2 no longer does that. */ - { - unsigned long insn1, insn2; - - /* Get the two instructions. */ - insn1 = bfd_get_32 (input_bfd, - contents + r_vaddr - input_section->vma); - insn2 = bfd_get_32 (input_bfd, - (contents - + r_vaddr - - input_section->vma - + r_symndx)); - - BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ - BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ - - /* Get the existing addend. We must account for the sign - extension done by lda and ldah. */ - addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); - if (insn1 & 0x8000) - { - /* This is addend -= 0x100000000 without causing an - integer overflow on a 32 bit host. */ - addend -= 0x80000000; - addend -= 0x80000000; - } - if (insn2 & 0x8000) - addend -= 0x10000; - - /* The existing addend includes the difference between the - gp of the input BFD and the address in the input BFD. - We want to change this to the difference between the - final GP and the final address. */ - addend += (gp - - ecoff_data (input_bfd)->gp - + input_section->vma - - (input_section->output_section->vma - + input_section->output_offset)); - - /* Change the instructions, accounting for the sign - extension, and write them out. */ - if (addend & 0x8000) - addend += 0x10000; - insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); - insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); - - bfd_put_32 (input_bfd, (bfd_vma) insn1, - contents + r_vaddr - input_section->vma); - bfd_put_32 (input_bfd, (bfd_vma) insn2, - contents + r_vaddr - input_section->vma + r_symndx); - - gp_usedp = true; - } - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - /* Manipulate values on the reloc evaluation stack. The - r_vaddr field is not an address in input_section, it is - the current value (including any addend) of the object - being used. */ - if (! r_extern) - { - asection *s; - - s = symndx_to_section[r_symndx]; - if (s == (asection *) NULL) - abort (); - addend = s->output_section->vma + s->output_offset - s->vma; - } - else - { - struct ecoff_link_hash_entry *h; - - h = sym_hashes[r_symndx]; - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - - if (! info->relocateable) - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - else - { - /* Note that we pass the address as 0, since we - do not have a meaningful number for the - location within the section that is being - relocated. */ - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, (bfd_vma) 0))) - return false; - addend = 0; - } - } - else - { - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak - && h->indx == -1) - { - /* This symbol is not being written out. Pass - the address as 0, as with undefined_symbol, - above. */ - if (! ((*info->callbacks->unattached_reloc) - (info, h->root.root.string, input_bfd, - input_section, (bfd_vma) 0))) - return false; - } - - addend = alpha_convert_external_reloc (output_bfd, info, - input_bfd, - ext_rel, h); - } - } - - addend += r_vaddr; - - if (info->relocateable) - { - /* Adjust r_vaddr by the addend. */ - bfd_h_put_64 (input_bfd, addend, - (bfd_byte *) ext_rel->r_vaddr); - } - else - { - switch (r_type) - { - case ALPHA_R_OP_PUSH: - if (tos >= RELOC_STACKSIZE) - abort (); - stack[tos++] = addend; - break; - - case ALPHA_R_OP_PSUB: - if (tos == 0) - abort (); - stack[tos - 1] -= addend; - break; - - case ALPHA_R_OP_PRSHIFT: - if (tos == 0) - abort (); - stack[tos - 1] >>= addend; - break; - } - } - - adjust_addrp = false; - break; - - case ALPHA_R_OP_STORE: - /* Store a value from the reloc stack into a bitfield. If - we are generating relocateable output, all we do is - adjust the address of the reloc. */ - if (! info->relocateable) - { - bfd_vma mask; - bfd_vma val; - - if (tos == 0) - abort (); - - /* Get the relocation mask. The separate steps and the - casts to bfd_vma are attempts to avoid a bug in the - Alpha OSF 1.3 C compiler. See reloc.c for more - details. */ - mask = 1; - mask <<= (bfd_vma) r_size; - mask -= 1; - - /* FIXME: I don't know what kind of overflow checking, - if any, should be done here. */ - val = bfd_get_64 (input_bfd, - contents + r_vaddr - input_section->vma); - val &=~ mask << (bfd_vma) r_offset; - val |= (stack[--tos] & mask) << (bfd_vma) r_offset; - bfd_put_64 (input_bfd, val, - contents + r_vaddr - input_section->vma); - } - break; - - case ALPHA_R_GPVALUE: - /* I really don't know if this does the right thing. */ - gp = ecoff_data (input_bfd)->gp + r_symndx; - gp_undefined = false; - break; - } - - if (relocatep) - { - reloc_howto_type *howto; - struct ecoff_link_hash_entry *h = NULL; - asection *s = NULL; - bfd_vma relocation; - bfd_reloc_status_type r; - - /* Perform a relocation. */ - - howto = &alpha_howto_table[r_type]; - - if (r_extern) - { - h = sym_hashes[r_symndx]; - /* If h is NULL, that means that there is a reloc - against an external symbol which we thought was just - a debugging symbol. This should not happen. */ - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - } - else - { - if (r_symndx >= NUM_RELOC_SECTIONS) - s = NULL; - else - s = symndx_to_section[r_symndx]; - - if (s == (asection *) NULL) - abort (); - } - - if (info->relocateable) - { - /* We are generating relocateable output, and must - convert the existing reloc. */ - if (r_extern) - { - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak - && h->indx == -1) - { - /* This symbol is not being written out. */ - if (! ((*info->callbacks->unattached_reloc) - (info, h->root.root.string, input_bfd, - input_section, r_vaddr - input_section->vma))) - return false; - } - - relocation = alpha_convert_external_reloc (output_bfd, - info, - input_bfd, - ext_rel, - h); - } - else - { - /* This is a relocation against a section. Adjust - the value by the amount the section moved. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - } - - /* If this is PC relative, the existing object file - appears to already have the reloc worked out. We - must subtract out the old value and add in the new - one. */ - if (howto->pc_relative) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Put in any addend. */ - relocation += addend; - - /* Adjust the contents. */ - r = _bfd_relocate_contents (howto, input_bfd, relocation, - (contents - + r_vaddr - - input_section->vma)); - } - else - { - /* We are producing a final executable. */ - if (r_extern) - { - /* This is a reloc against a symbol. */ - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - - hsec = h->root.u.def.section; - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, - r_vaddr - input_section->vma))) - return false; - relocation = 0; - } - } - else - { - /* This is a reloc against a section. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - - /* Adjust a PC relative relocation by removing the - reference to the original source section. */ - if (howto->pc_relative) - relocation += input_section->vma; - } - - r = _bfd_final_link_relocate (howto, - input_bfd, - input_section, - contents, - r_vaddr - input_section->vma, - relocation, - addend); - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (r_extern) - name = sym_hashes[r_symndx]->root.root.string; - else - name = bfd_section_name (input_bfd, - symndx_to_section[r_symndx]); - if (! ((*info->callbacks->reloc_overflow) - (info, name, alpha_howto_table[r_type].name, - (bfd_vma) 0, input_bfd, input_section, - r_vaddr - input_section->vma))) - return false; - } - break; - } - } - } - - if (info->relocateable && adjust_addrp) - { - /* Change the address of the relocation. */ - bfd_h_put_64 (input_bfd, - (input_section->output_section->vma - + input_section->output_offset - - input_section->vma - + r_vaddr), - (bfd_byte *) ext_rel->r_vaddr); - } - - if (gp_usedp && gp_undefined) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "GP relative relocation when GP not defined", - input_bfd, input_section, r_vaddr - input_section->vma))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - gp_undefined = false; - } - } - - if (tos != 0) - abort (); - - return true; -} - -/* Do final adjustments to the filehdr and the aouthdr. This routine - sets the dynamic bits in the file header. */ - -/*ARGSUSED*/ -static boolean -alpha_adjust_headers (abfd, fhdr, ahdr) - bfd *abfd; - struct internal_filehdr *fhdr; - struct internal_aouthdr *ahdr; -{ - if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P)) - fhdr->f_flags |= F_ALPHA_CALL_SHARED; - else if ((abfd->flags & DYNAMIC) != 0) - fhdr->f_flags |= F_ALPHA_SHARABLE; - return true; -} - -/* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital - introduced archive packing, in which the elements in an archive are - optionally compressed using a simple dictionary scheme. We know - how to read such archives, but we don't write them. */ - -#define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap -#define alpha_ecoff_slurp_extended_name_table \ - _bfd_ecoff_slurp_extended_name_table -#define alpha_ecoff_construct_extended_name_table \ - _bfd_ecoff_construct_extended_name_table -#define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname -#define alpha_ecoff_write_armap _bfd_ecoff_write_armap -#define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt -#define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp - -/* A compressed file uses this instead of ARFMAG. */ - -#define ARFZMAG "Z\012" - -/* Read an archive header. This is like the standard routine, but it - also accepts ARFZMAG. */ - -static PTR -alpha_ecoff_read_ar_hdr (abfd) - bfd *abfd; -{ - struct areltdata *ret; - struct ar_hdr *h; - - ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG); - if (ret == NULL) - return NULL; - - h = (struct ar_hdr *) ret->arch_header; - if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0) - { - bfd_byte ab[8]; - - /* This is a compressed file. We must set the size correctly. - The size is the eight bytes after the dummy file header. */ - if (bfd_seek (abfd, FILHSZ, SEEK_CUR) != 0 - || bfd_read (ab, 1, 8, abfd) != 8 - || bfd_seek (abfd, - (FILHSZ + 8), SEEK_CUR) != 0) - return NULL; - - ret->parsed_size = bfd_h_get_64 (abfd, ab); - } - - return (PTR) ret; -} - -/* Get an archive element at a specified file position. This is where - we uncompress the archive element if necessary. */ - -static bfd * -alpha_ecoff_get_elt_at_filepos (archive, filepos) - bfd *archive; - file_ptr filepos; -{ - bfd *nbfd = NULL; - struct areltdata *tdata; - struct ar_hdr *hdr; - bfd_byte ab[8]; - bfd_size_type size; - bfd_byte *buf, *p; - struct bfd_in_memory *bim; - - nbfd = _bfd_get_elt_at_filepos (archive, filepos); - if (nbfd == NULL) - goto error_return; - - if ((nbfd->flags & BFD_IN_MEMORY) != 0) - { - /* We have already expanded this BFD. */ - return nbfd; - } - - tdata = (struct areltdata *) nbfd->arelt_data; - hdr = (struct ar_hdr *) tdata->arch_header; - if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0) - return nbfd; - - /* We must uncompress this element. We do this by copying it into a - memory buffer, and making bfd_read and bfd_seek use that buffer. - This can use a lot of memory, but it's simpler than getting a - temporary file, making that work with the file descriptor caching - code, and making sure that it is deleted at all appropriate - times. It can be changed if it ever becomes important. */ - - /* The compressed file starts with a dummy ECOFF file header. */ - if (bfd_seek (nbfd, FILHSZ, SEEK_SET) != 0) - goto error_return; - - /* The next eight bytes are the real file size. */ - if (bfd_read (ab, 1, 8, nbfd) != 8) - goto error_return; - size = bfd_h_get_64 (nbfd, ab); - - if (size == 0) - buf = NULL; - else - { - bfd_size_type left; - bfd_byte dict[4096]; - unsigned int h; - bfd_byte b; - - buf = (bfd_byte *) bfd_alloc (nbfd, size); - if (buf == NULL) - goto error_return; - p = buf; - - left = size; - - /* I don't know what the next eight bytes are for. */ - if (bfd_read (ab, 1, 8, nbfd) != 8) - goto error_return; - - /* This is the uncompression algorithm. It's a simple - dictionary based scheme in which each character is predicted - by a hash of the previous three characters. A control byte - indicates whether the character is predicted or whether it - appears in the input stream; each control byte manages the - next eight bytes in the output stream. */ - memset (dict, 0, sizeof dict); - h = 0; - while (bfd_read (&b, 1, 1, nbfd) == 1) - { - unsigned int i; - - for (i = 0; i < 8; i++, b >>= 1) - { - bfd_byte n; - - if ((b & 1) == 0) - n = dict[h]; - else - { - if (! bfd_read (&n, 1, 1, nbfd)) - goto error_return; - dict[h] = n; - } - - *p++ = n; - - --left; - if (left == 0) - break; - - h <<= 4; - h ^= n; - h &= sizeof dict - 1; - } - - if (left == 0) - break; - } - } - - /* Now the uncompressed file contents are in buf. */ - bim = ((struct bfd_in_memory *) - bfd_alloc (nbfd, sizeof (struct bfd_in_memory))); - if (bim == NULL) - goto error_return; - bim->size = size; - bim->buffer = buf; - - nbfd->mtime_set = true; - nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10); - - nbfd->flags |= BFD_IN_MEMORY; - nbfd->iostream = (PTR) bim; - BFD_ASSERT (! nbfd->cacheable); - - return nbfd; - - error_return: - if (nbfd != NULL) - bfd_close (nbfd); - return NULL; -} - -/* Open the next archived file. */ - -static bfd * -alpha_ecoff_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - file_ptr filestart; - - if (last_file == NULL) - filestart = bfd_ardata (archive)->first_file_filepos; - else - { - struct areltdata *t; - struct ar_hdr *h; - bfd_size_type size; - - /* We can't use arelt_size here, because that uses parsed_size, - which is the uncompressed size. We need the compressed size. */ - t = (struct areltdata *) last_file->arelt_data; - h = (struct ar_hdr *) t->arch_header; - size = strtol (h->ar_size, (char **) NULL, 10); - - /* Pad to an even boundary... - Note that last_file->origin can be odd in the case of - BSD-4.4-style element with a long odd size. */ - filestart = last_file->origin + size; - filestart += filestart % 2; - } - - return alpha_ecoff_get_elt_at_filepos (archive, filestart); -} - -/* Open the archive file given an index into the armap. */ - -static bfd * -alpha_ecoff_get_elt_at_index (abfd, index) - bfd *abfd; - symindex index; -{ - carsym *entry; - - entry = bfd_ardata (abfd)->symdefs + index; - return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset); -} - -/* This is the ECOFF backend structure. The backend field of the - target vector points to this. */ - -static const struct ecoff_backend_data alpha_ecoff_backend_data = -{ - /* COFF backend structure. */ - { - (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */ - (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */ - alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out, - alpha_ecoff_swap_scnhdr_out, - FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, - alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in, - alpha_ecoff_swap_scnhdr_in, NULL, - alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, - alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, - _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }, - /* Supported architecture. */ - bfd_arch_alpha, - /* Initial portion of armap string. */ - "________64", - /* The page boundary used to align sections in a demand-paged - executable file. E.g., 0x1000. */ - 0x2000, - /* True if the .rdata section is part of the text segment, as on the - Alpha. False if .rdata is part of the data segment, as on the - MIPS. */ - true, - /* Bitsize of constructor entries. */ - 64, - /* Reloc to use for constructor entries. */ - &alpha_howto_table[ALPHA_R_REFQUAD], - { - /* Symbol table magic number. */ - magicSym2, - /* Alignment of debugging information. E.g., 4. */ - 8, - /* Sizes of external symbolic information. */ - sizeof (struct hdr_ext), - sizeof (struct dnr_ext), - sizeof (struct pdr_ext), - sizeof (struct sym_ext), - sizeof (struct opt_ext), - sizeof (struct fdr_ext), - sizeof (struct rfd_ext), - sizeof (struct ext_ext), - /* Functions to swap in external symbolic data. */ - ecoff_swap_hdr_in, - ecoff_swap_dnr_in, - ecoff_swap_pdr_in, - ecoff_swap_sym_in, - ecoff_swap_opt_in, - ecoff_swap_fdr_in, - ecoff_swap_rfd_in, - ecoff_swap_ext_in, - _bfd_ecoff_swap_tir_in, - _bfd_ecoff_swap_rndx_in, - /* Functions to swap out external symbolic data. */ - ecoff_swap_hdr_out, - ecoff_swap_dnr_out, - ecoff_swap_pdr_out, - ecoff_swap_sym_out, - ecoff_swap_opt_out, - ecoff_swap_fdr_out, - ecoff_swap_rfd_out, - ecoff_swap_ext_out, - _bfd_ecoff_swap_tir_out, - _bfd_ecoff_swap_rndx_out, - /* Function to read in symbolic data. */ - _bfd_ecoff_slurp_symbolic_info - }, - /* External reloc size. */ - RELSZ, - /* Reloc swapping functions. */ - alpha_ecoff_swap_reloc_in, - alpha_ecoff_swap_reloc_out, - /* Backend reloc tweaking. */ - alpha_adjust_reloc_in, - alpha_adjust_reloc_out, - /* Relocate section contents while linking. */ - alpha_relocate_section, - /* Do final adjustments to filehdr and aouthdr. */ - alpha_adjust_headers, - /* Read an element from an archive at a given file position. */ - alpha_ecoff_get_elt_at_filepos -}; - -/* Looking up a reloc type is Alpha specific. */ -#define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup - -/* So is getting relocated section contents. */ -#define _bfd_ecoff_bfd_get_relocated_section_contents \ - alpha_ecoff_get_relocated_section_contents - -/* Handling file windows is generic. */ -#define _bfd_ecoff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Relaxing sections is generic. */ -#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section - -const bfd_target ecoffalpha_little_vec = -{ - "ecoff-littlealpha", /* name */ - bfd_target_ecoff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */ - _bfd_ecoff_archive_p, _bfd_dummy_target}, - {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), - BFD_JUMP_TABLE_COPY (_bfd_ecoff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff), - BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), - BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), - BFD_JUMP_TABLE_WRITE (_bfd_ecoff), - BFD_JUMP_TABLE_LINK (_bfd_ecoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) &alpha_ecoff_backend_data -}; diff --git a/contrib/gdb/bfd/coff-apollo.c b/contrib/gdb/bfd/coff-apollo.c deleted file mode 100644 index 561b1c7ab62..00000000000 --- a/contrib/gdb/bfd/coff-apollo.c +++ /dev/null @@ -1,162 +0,0 @@ -/* BFD back-end for Apollo 68000 COFF binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - By Troy Rollo (troy@cbme.unsw.edu.au) - Based on m68k standard COFF version Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/apollo.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -#ifdef ONLY_DECLARE_RELOCS -extern reloc_howto_type apollocoff_howto_table[]; -#else -reloc_howto_type apollocoff_howto_table[] = -{ - HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_RELLONG_NEG, 0, -2, 32, false, 0, complain_overflow_bitfield, 0, "-32", true, 0xffffffff,0xffffffff, false), -}; -#endif /* not ONLY_DECLARE_RELOCS */ - -#ifndef BADMAG -#define BADMAG(x) M68KBADMAG(x) -#endif -#define APOLLO_M68 1 /* Customize coffcode.h */ - -/* Turn a howto into a reloc number */ - -#ifdef ONLY_DECLARE_RELOCS -extern void apollo_rtype2howto PARAMS ((arelent *internal, int relocentry)); -extern int apollo_howto2rtype PARAMS ((reloc_howto_type *)); -#else -void -apollo_rtype2howto(internal, relocentry) - arelent *internal; - int relocentry; -{ - switch (relocentry) - { - case R_RELBYTE: internal->howto = apollocoff_howto_table + 0; break; - case R_RELWORD: internal->howto = apollocoff_howto_table + 1; break; - case R_RELLONG: internal->howto = apollocoff_howto_table + 2; break; - case R_PCRBYTE: internal->howto = apollocoff_howto_table + 3; break; - case R_PCRWORD: internal->howto = apollocoff_howto_table + 4; break; - case R_PCRLONG: internal->howto = apollocoff_howto_table + 5; break; - case R_RELLONG_NEG: internal->howto = apollocoff_howto_table + 6; break; - } -} - -int -apollo_howto2rtype (internal) - reloc_howto_type *internal; -{ - if (internal->pc_relative) - { - switch (internal->bitsize) - { - case 32: return R_PCRLONG; - case 16: return R_PCRWORD; - case 8: return R_PCRBYTE; - } - } - else - { - switch (internal->bitsize) - { - case 32: return R_RELLONG; - case 16: return R_RELWORD; - case 8: return R_RELBYTE; - } - } - return R_RELLONG; -} -#endif /* not ONLY_DECLARE_RELOCS */ - -#define RTYPE2HOWTO(internal, relocentry) \ - apollo_rtype2howto(internal, (relocentry)->r_type) - -#define SELECT_RELOC(external, internal) \ - external.r_type = apollo_howto2rtype(internal); - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - apollocoff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "apollo-m68k", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef NAMES_HAVE_UNDERSCORE - '_', -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE - }; diff --git a/contrib/gdb/bfd/coff-arm.c b/contrib/gdb/bfd/coff-arm.c deleted file mode 100644 index bb16b046ae1..00000000000 --- a/contrib/gdb/bfd/coff-arm.c +++ /dev/null @@ -1,537 +0,0 @@ -/* BFD back-end for ARM COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -#include "coff/arm.h" - -#include "coff/internal.h" - -#ifdef COFF_WITH_PE -#include "coff/pe.h" -#endif - -#include "libcoff.h" - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - - -static bfd_reloc_status_type coff_arm_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - - -/* Used by the assembler. */ -static bfd_reloc_status_type -coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - diff = reloc_entry->addend; - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - -#ifndef PCRELOFFSET -#define PCRELOFFSET true -#endif - -static reloc_howto_type aoutarm_std_reloc_howto[] = -{ - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ - HOWTO(0, /* type */ - 0, /* rs */ - 0, /* size */ - 8, /* bsz */ - false, /* pcrel */ - 0, /* bitpos */ - complain_overflow_bitfield, /* ovf */ - coff_arm_reloc, /* sf */ - "8", /*name */ - true, /* partial */ - 0x000000ff, /*read mask */ - 0x000000ff, /* setmask */ - PCRELOFFSET /* pcdone */), - HOWTO(1, - 0, - 1, - 16, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "16", - true, - 0x0000ffff, - 0x0000ffff, - PCRELOFFSET), - HOWTO( 2, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), - HOWTO( 3, - 2, - 2, - 26, - true, - 0, - complain_overflow_signed, - aoutarm_fix_pcrel_26 , - "ARM26", - false, - 0x00ffffff, - 0x00ffffff, - PCRELOFFSET), - HOWTO( 4, - 0, - 0, - 8, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "DISP8", - true, - 0x000000ff, - 0x000000ff, - true), - HOWTO( 5, - 0, - 1, - 16, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "DISP16", - true, - 0x0000ffff, - 0x0000ffff, - true), - HOWTO( 6, - 0, - 2, - 32, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "DISP32", - true, - 0xffffffff, - 0xffffffff, - true), - HOWTO( 7, - 2, - 2, - 26, - false, - 0, - complain_overflow_signed, - aoutarm_fix_pcrel_26_done, - "ARM26D", - true, - 0x00ffffff, - 0x00ffffff, - false), - {-1}, - HOWTO( 9, - 0, - -1, - 16, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "NEG16", - true, - 0x0000ffff, - 0x0000ffff, - false), - HOWTO( 10, - 0, - -2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "NEG32", - true, - 0xffffffff, - 0xffffffff, - false), - HOWTO( 11, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "rva32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), -}; -#ifdef COFF_WITH_PE -/* Return true if this relocation should - appear in the output .reloc section. */ - -static boolean in_reloc_p (abfd, howto) - bfd * abfd; - reloc_howto_type *howto; -{ - return !howto->pc_relative && howto->type != 11; -} -#endif - - -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = aoutarm_std_reloc_howto + (dst)->r_type; - -#define coff_rtype_to_howto coff_arm_rtype_to_howto - -static reloc_howto_type * -coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - reloc_howto_type *howto; - - howto = aoutarm_std_reloc_howto + rel->r_type; - - if (rel->r_type == 11) - { - *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; - } - return howto; - -} -/* Used by the assembler. */ - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* This is dead simple at present. */ - return bfd_reloc_ok; -} - -/* Used by the assembler. */ - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_size_type addr = reloc_entry->address; - long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); - bfd_reloc_status_type flag = bfd_reloc_ok; - - /* If this is an undefined symbol, return error */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0) - return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; - - /* If the sections are different, and we are doing a partial relocation, - just ignore it for now. */ - if (symbol->section->name != input_section->name - && output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - relocation = (target & 0x00ffffff) << 2; - relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ - relocation += symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - relocation -= input_section->output_section->vma; - relocation -= input_section->output_offset; - relocation -= addr; - if (relocation & 3) - return bfd_reloc_overflow; - - /* Check for overflow */ - if (relocation & 0x02000000) - { - if ((relocation & ~0x03ffffff) != ~0x03ffffff) - flag = bfd_reloc_overflow; - } - else if (relocation & ~0x03ffffff) - flag = bfd_reloc_overflow; - - target &= ~0x00ffffff; - target |= (relocation >> 2) & 0x00ffffff; - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); - - /* Now the ARM magic... Change the reloc type so that it is marked as done. - Strictly this is only necessary if we are doing a partial relocation. */ - reloc_entry->howto = &aoutarm_std_reloc_howto[7]; - - return flag; -} - - -static CONST struct reloc_howto_struct * -arm_reloc_type_lookup(abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ -#define ASTD(i,j) case i: return &aoutarm_std_reloc_howto[j] - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - default: return (CONST struct reloc_howto_struct *) 0; - } - - switch (code) - { - ASTD (BFD_RELOC_16, 1); - ASTD (BFD_RELOC_32, 2); - ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); - ASTD (BFD_RELOC_8_PCREL, 4); - ASTD (BFD_RELOC_16_PCREL, 5); - ASTD (BFD_RELOC_32_PCREL, 6); - ASTD (BFD_RELOC_RVA, 11); - default: return (CONST struct reloc_howto_struct *) 0; - } -} - - -#define coff_bfd_reloc_type_lookup arm_reloc_type_lookup - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) -#define COFF_PAGE_SIZE 0x1000 -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) ARMBADMAG(x) -#define ARM 1 /* Customize coffcode.h */ - - -/* We use the special COFF backend linker. */ -#define coff_relocate_section _bfd_coff_generic_relocate_section - - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_LITTLE_SYM -TARGET_LITTLE_SYM = -#else -armcoff_little_vec = -#endif -{ -#ifdef TARGET_LITTLE_NAME - TARGET_LITTLE_NAME, -#else - "coff-arm-little", -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef TARGET_UNDERSCORE - TARGET_UNDERSCORE, /* leading underscore */ -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - -const bfd_target -#ifdef TARGET_BIG_SYM -TARGET_BIG_SYM = -#else -armcoff_big_vec = -#endif -{ -#ifdef TARGET_BIG_NAME - TARGET_BIG_NAME, -#else - "coff-arm-big", -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef TARGET_UNDERSCORE - TARGET_UNDERSCORE, /* leading underscore */ -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-aux.c b/contrib/gdb/bfd/coff-aux.c deleted file mode 100644 index 1dba9d5c465..00000000000 --- a/contrib/gdb/bfd/coff-aux.c +++ /dev/null @@ -1,332 +0,0 @@ -/* BFD back-end for Apple M68K COFF A/UX 3.x files. - Copyright 1996 Free Software Foundation, Inc. - Portions written by Richard Henderson , - COMMON symbol munging cribbed from cf-m68klynx.c which was - written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_SYM m68kaux_coff_vec -#define TARGET_NAME "coff-m68k-aux" - -#ifndef TARG_AUX -#define TARG_AUX -#endif - -#define COFF_LONG_FILENAMES - -/* 4k pages */ -#define COFF_PAGE_SIZE 0x1000 - -/* On AUX, a STYP_NOLOAD|STYP_BSS section is part of a shared library. */ -#define BSS_NOLOAD_IS_SHARED_LIBRARY - -#define _bfd_m68kcoff_howto_table _bfd_m68kaux_howto_table -#define _bfd_m68kcoff_rtype2howto _bfd_m68kaux_rtype2howto -#define _bfd_m68kcoff_howto2rtype _bfd_m68kaux_howto2rtype -#define _bfd_m68kcoff_reloc_type_lookup _bfd_m68kaux_reloc_type_lookup - -/* Rather than change names lots of places, reuse the same hack */ -#define LYNX_SPECIAL_FN _bfd_m68kaux_special_fn - -#include "bfd.h" -#include "sysdep.h" - -#ifdef ANSI_PROTOTYPES -struct internal_reloc; -struct coff_link_hash_entry; -struct internal_syment; -#endif - - -static bfd_reloc_status_type _bfd_m68kaux_special_fn - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_m68k_aux_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *)); -static boolean coff_m68k_aux_link_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, - asection *, bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); - - -#define coff_rtype_to_howto coff_m68k_aux_rtype_to_howto -#define coff_link_add_one_symbol coff_m68k_aux_link_add_one_symbol - - -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && (reloc.r_type == R_PCRBYTE \ - || reloc.r_type == R_PCRWORD \ - || reloc.r_type == R_PCRLONG)) \ - cache_ptr->addend += asect->vma; \ - } - - - -#include "coff/aux-coff.h" /* override coff/internal.h and coff/m68k.h */ -#include "coff-m68k.c" - - - -/* For some reason when using m68k COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. (taken from work done by Ian Taylor, Cygnus Support, - for I386 COFF). */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -_bfd_m68kaux_special_fn (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 386 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | \ - (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - - -/* coff-m68k.c uses the special COFF backend linker. We need to - adjust common symbols. */ - -/*ARGSUSED*/ -static reloc_howto_type * -coff_m68k_aux_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - arelent relent; - reloc_howto_type *howto; - - RTYPE2HOWTO (&relent, rel); - - howto = relent.howto; - - if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) - { - /* This is a common symbol. The section contents include the - size (sym->n_value) as an addend. The relocate_section - function will be adding in the final value of the symbol. We - need to subtract out the current size in order to get the - correct result. */ - BFD_ASSERT (h != NULL); - *addendp -= sym->n_value; - } - - /* If the output symbol is common (in which case this must be a - relocateable link), we need to add in the final size of the - common symbol. */ - if (h != NULL && h->root.type == bfd_link_hash_common) - *addendp += h->root.u.c.size; - - return howto; -} - - -/* We need non-absolute symbols to override absolute symbols. This - mirrors Apple's "solution" to let a static library symbol override - a shared library symbol. On the whole not a good thing, given how - shared libraries work here, but can work if you are careful with - what you include in the shared object. */ - -boolean -coff_m68k_aux_link_add_one_symbol (info, abfd, name, flags, section, value, - string, copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct bfd_link_hash_entry *h; - - if ((flags & (BSF_WARNING | BSF_CONSTRUCTOR | BSF_WEAK)) == 0 && - !bfd_is_und_section (section) && - !bfd_is_com_section (section)) - { - /* The new symbol is a definition or an indirect definition */ - - /* This bit copied from linker.c */ - if (hashp != NULL && *hashp != NULL) - { - h = *hashp; - BFD_ASSERT (strcmp (h->root.string, name) == 0); - } - else - { - h = bfd_link_hash_lookup (info->hash, name, true, copy, false); - if (h == NULL) - { - if (hashp != NULL) - *hashp = NULL; - return false; - } - } - - if (info->notice_hash != (struct bfd_hash_table *) NULL - && (bfd_hash_lookup (info->notice_hash, name, false, false) - != (struct bfd_hash_entry *) NULL)) - { - if (! (*info->callbacks->notice) (info, name, abfd, section, value)) - return false; - } - - if (hashp != (struct bfd_link_hash_entry **) NULL) - *hashp = h; - /* end duplication from linker.c */ - - if (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_indirect) - { - asection *msec; - - if (h->type == bfd_link_hash_defined) - msec = h->u.def.section; - else - msec = bfd_ind_section_ptr; - - if (bfd_is_abs_section (msec) && !bfd_is_abs_section (section)) - { - h->u.def.section = section; - h->u.def.value = value; - return true; - } - else if (bfd_is_abs_section (section) && !bfd_is_abs_section (msec)) - return true; - } - } - - /* If we didn't exit early, finish processing in the generic routine */ - return _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp); -} diff --git a/contrib/gdb/bfd/coff-go32.c b/contrib/gdb/bfd/coff-go32.c deleted file mode 100644 index be4adb24f52..00000000000 --- a/contrib/gdb/bfd/coff-go32.c +++ /dev/null @@ -1,25 +0,0 @@ -/* BFD back-end for Intel 386 COFF files (go32 variant). - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by DJ Delorie. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_SYM go32coff_vec -#define TARGET_NAME "coff-go32" -#define TARGET_UNDERSCORE '_' - -#include "coff-i386.c" diff --git a/contrib/gdb/bfd/coff-h8300.c b/contrib/gdb/bfd/coff-h8300.c deleted file mode 100644 index 48d0d5a213b..00000000000 --- a/contrib/gdb/bfd/coff-h8300.c +++ /dev/null @@ -1,650 +0,0 @@ -/* BFD back-end for Hitachi H8/300 COFF binaries. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "coff/h8300.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) - - -/* special handling for H8/300 relocs. - We only come here for pcrel stuff and return normally if not an -r link. - When doing -r, we can't do any arithmetic for the pcrel stuff, because - the code in reloc.c assumes that we can manipulate the targets of - the pcrel branches. This isn't so, since the H8/300 can do relaxing, - which means that the gap after the instruction may not be enough to - contain the offset required for the branch, so we have to use the only - the addend until the final link */ - -static bfd_reloc_status_type -special (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static reloc_howto_type howto_table[] = -{ - HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8", false, 0x000000ff, 0x000000ff, false), - HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "32", false, 0xffffffff, 0xffffffff, false), - HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8", false, 0x000000ff, 0x000000ff, true), - HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, special, "DISP16", false, 0x0000ffff, 0x0000ffff, true), - HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, special, "DISP32", false, 0xffffffff, 0xffffffff, true), - HOWTO (R_MOVB1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/8", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_MOVB2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "8/16", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_JMP1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/pcrel", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_JMP2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pcrecl/16", false, 0x000000ff, 0x000000ff, false), - - - HOWTO (R_JMPL1, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "24/pcrell", false, 0x00ffffff, 0x00ffffff, false), - HOWTO (R_JMPL_B8, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pc8/24", false, 0x000000ff, 0x000000ff, false), - - HOWTO (R_MOVLB1, 0, 1, 16, false, 0, complain_overflow_bitfield,special, "24/8", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_MOVLB2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "8/24", false, 0x0000ffff, 0x0000ffff, false), - - /* An indirect reference to a function. This causes the function's address - to be added to the function vector in lo-mem and puts the address of - the function vector's entry in the jsr instruction. */ - HOWTO (R_MEM_INDIRECT, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8/indirect", false, 0x000000ff, 0x000000ff, false), - -}; - - -/* Turn a howto into a reloc number */ - -#define SELECT_RELOC(x,howto) \ - { x.r_type = select_reloc(howto); } - -#define BADMAG(x) (H8300BADMAG(x)&& H8300HBADMAG(x)) -#define H8300 1 /* Customize coffcode.h */ -#define __A_MAGIC_SET__ - - - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - - -static int -select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type; -} - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto (internal, dst) - arelent *internal; - struct internal_reloc *dst; -{ - switch (dst->r_type) - { - case R_RELBYTE: - internal->howto = howto_table + 0; - break; - case R_RELWORD: - internal->howto = howto_table + 1; - break; - case R_RELLONG: - internal->howto = howto_table + 2; - break; - case R_PCRBYTE: - internal->howto = howto_table + 3; - break; - case R_PCRWORD: - internal->howto = howto_table + 4; - break; - case R_PCRLONG: - internal->howto = howto_table + 5; - break; - case R_MOVB1: - internal->howto = howto_table + 6; - break; - case R_MOVB2: - internal->howto = howto_table + 7; - break; - case R_JMP1: - internal->howto = howto_table + 8; - break; - case R_JMP2: - internal->howto = howto_table + 9; - break; - case R_JMPL1: - internal->howto = howto_table + 10; - break; - case R_JMPL_B8: - internal->howto = howto_table + 11; - break; - case R_MOVLB1: - internal->howto = howto_table + 12; - break; - case R_MOVLB2: - internal->howto = howto_table + 13; - break; - case R_MEM_INDIRECT: - internal->howto = howto_table + 14; - break; - default: - abort (); - break; - } -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (((int) reloc->r_symndx) > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - - - relent->addend = reloc->r_offset; - - relent->address -= section->vma; - /* relent->section = 0;*/ -} - - -static int -h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *reloc; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - bfd_vma value; - bfd_vma dot; - bfd_vma gap; - - /* The address of the thing to be relocated will have moved back by - the size of the shrink - but we don't change reloc->address here, - since we need it to know where the relocation lives in the source - uncooked section */ - - /* reloc->address -= shrink; conceptual */ - - bfd_vma address = reloc->address - shrink; - - - switch (reloc->howto->type) - { - case R_MOVB2: - case R_JMP2: - shrink+=2; - break; - - /* Thing is a move one byte */ - case R_MOVB1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - if (value >= 0xff00) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - - break; - /* This is the 24 bit branch which could become an 8 bitter, - the relocation points to the first byte of the insn, not the - actual data */ - - case R_JMPL1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - dot ; - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 24bit, possible 8 to 8bit - possible 32 */ - reloc->howto = reloc->howto + 1; - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - - case R_JMP1: - - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - (dot - shrink); - - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - } - - - return shrink; -} - - -/* First phase of a relaxing link */ - -/* Reloc types - large small - R_MOVB1 R_MOVB2 mov.b with 16bit or 8 bit address - R_JMP1 R_JMP2 jmp or pcrel branch - R_JMPL1 R_JMPL_B8 24jmp or pcrel branch - R_MOVLB1 R_MOVLB2 24 or 8 bit reloc for mov.b - -*/ - -static void -h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, - dst_ptr) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - unsigned int src_address = *src_ptr; - unsigned int dst_address = *dst_ptr; - asection *input_section = link_order->u.indirect.section; - - switch (reloc->howto->type) - { - /* A 24 bit branch which could be a 8 bit pcrel, really pointing to - the byte before the 24bit hole, so we can treat it as a 32bit pointer */ - case R_PCRBYTE: - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot); - if (gap > 127 || gap < -128) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - gap &= ~1; - bfd_put_8 (abfd, gap, data + dst_address); - dst_address++; - src_address++; - - break; - } - case R_PCRWORD: - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot) - 1; - if (gap > 32767 || gap < -32768) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - - bfd_put_16 (abfd, gap, data + dst_address); - dst_address+=2; - src_address+=2; - - break; - } - - case R_MEM_INDIRECT: /* Temporary */ - case R_RELBYTE: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - if (gap < 0xff - || (gap >= 0x0000ff00 - && gap <= 0x0000ffff) - || ( gap >= 0x00ffff00 - && gap <= 0x00ffffff) - || ( gap >= 0xffffff00 - && gap <= 0xffffffff)) - { - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - else - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - } - break; - case R_JMP1: - /* A relword which would have like to have been a pcrel */ - case R_MOVB1: - /* A relword which would like to have been modified but - didn't make it */ - case R_RELWORD: - bfd_put_16 (abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + dst_address); - dst_address += 2; - src_address += 2; - break; - case R_RELLONG: - bfd_put_32 (abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + dst_address); - dst_address += 4; - src_address += 4; - break; - - case R_MOVB2: - /* Special relaxed type, there will be a gap between where we - get stuff from and where we put stuff to now - - for a mov.b @aa:16 -> mov.b @aa:8 - opcode 0x6a 0x0y offset - -> 0x2y off - */ - if (data[dst_address - 1] != 0x6a) - abort (); - switch (data[src_address] & 0xf0) - { - case 0x00: - /* Src is memory */ - data[dst_address - 1] = (data[src_address] & 0xf) | 0x20; - break; - case 0x80: - /* Src is reg */ - data[dst_address - 1] = (data[src_address] & 0xf) | 0x30; - break; - default: - abort (); - } - - /* the offset must fit ! after all, what was all the relaxing - about ? */ - - bfd_put_8 (abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + dst_address); - - /* Note the magic - src goes up by two bytes, but dst by only - one */ - dst_address += 1; - src_address += 3; - - break; - - case R_JMP2: - - /* Speciial relaxed type */ - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot - 1); - - if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00)) - abort (); - - bfd_put_8 (abfd, gap, data + dst_address); - - switch (data[dst_address - 1]) - { - case 0x5e: - /* jsr -> bsr */ - bfd_put_8 (abfd, 0x55, data + dst_address - 1); - break; - case 0x5a: - /* jmp ->bra */ - bfd_put_8 (abfd, 0x40, data + dst_address - 1); - break; - - default: - abort (); - } - dst_address++; - src_address += 3; - - break; - } - break; - - case R_JMPL_B8: /* 24 bit branch which is now 8 bits */ - - /* Speciial relaxed type */ - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot - 2); - - if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00)) - abort (); - - switch (data[src_address]) - { - case 0x5e: - /* jsr -> bsr */ - bfd_put_8 (abfd, 0x55, data + dst_address); - break; - case 0x5a: - /* jmp ->bra */ - bfd_put_8 (abfd, 0x40, data + dst_address); - break; - - default: - bfd_put_8 (abfd, 0xde, data + dst_address); - break; - } - - bfd_put_8 (abfd, gap, data + dst_address + 1); - dst_address += 2; - src_address += 4; - - break; - } - - case R_JMPL1: - { - int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section); - int o = bfd_get_32 (abfd, data + src_address); - v = (v & 0x00ffffff) | (o & 0xff000000); - bfd_put_32 (abfd, v, data + dst_address); - dst_address += 4; - src_address += 4; - } - - break; - - - /* A 24 bit mov which could be an 8 bit move, really pointing to - the byte before the 24bit hole, so we can treat it as a 32bit pointer */ - case R_MOVLB1: - { - int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section); - int o = bfd_get_32 (abfd, data + dst_address); - v = (v & 0x00ffffff) | (o & 0xff000000); - bfd_put_32 (abfd, v, data + dst_address); - dst_address += 4; - src_address += 4; - } - - break; - default: - - abort (); - break; - - } - *src_ptr = src_address; - *dst_ptr = dst_address; - -} - -#define coff_reloc16_extra_cases h8300_reloc16_extra_cases -#define coff_reloc16_estimate h8300_reloc16_estimate - -#define COFF_LONG_FILENAMES -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - - - -const bfd_target h8300coff_vec = -{ - "coff-h8300", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-h8500.c b/contrib/gdb/bfd/coff-h8500.c deleted file mode 100644 index f416f8fa282..00000000000 --- a/contrib/gdb/bfd/coff-h8500.c +++ /dev/null @@ -1,355 +0,0 @@ -/* BFD back-end for Hitachi H8/500 COFF binaries. - Copyright 1993, 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support. - Written by Steve Chamberlain, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/h8500.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) - -static reloc_howto_type r_imm8 = -HOWTO (R_H8500_IMM8, 0, 1, 8, false, 0, - complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff, false); - -static reloc_howto_type r_imm16 = -HOWTO (R_H8500_IMM16, 0, 1, 16, false, 0, - complain_overflow_bitfield, 0, "r_imm16", true, 0x0000ffff, 0x0000ffff, false); - -static reloc_howto_type r_imm24 = -HOWTO (R_H8500_IMM24, 0, 1, 24, false, 0, - complain_overflow_bitfield, 0, "r_imm24", true, 0x00ffffff, 0x00ffffff, false); - -static reloc_howto_type r_imm32 = -HOWTO (R_H8500_IMM32, 0, 1, 32, false, 0, - complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff, 0xffffffff, false); - - -static reloc_howto_type r_high8 = -HOWTO (R_H8500_HIGH8, 0, 1, 8, false, 0, - complain_overflow_dont, 0, "r_high8", true, 0x000000ff, 0x000000ff, false); - -static reloc_howto_type r_low16 = -HOWTO (R_H8500_LOW16, 0, 1, 16, false, 0, - complain_overflow_dont, 0, "r_low16", true, 0x0000ffff, 0x0000ffff, false); - -static reloc_howto_type r_pcrel8 = -HOWTO (R_H8500_PCREL8, 0, 1, 8, true, 0, complain_overflow_signed, 0, "r_pcrel8", true, 0, 0, true); - - -static reloc_howto_type r_pcrel16 = -HOWTO (R_H8500_PCREL16, 0, 1, 16, true, 0, complain_overflow_signed, 0, "r_pcrel16", true, 0, 0, true); - -static reloc_howto_type r_high16 = -HOWTO (R_H8500_HIGH16, 0, 1, 8, false, 0, - complain_overflow_dont, 0, "r_high16", true, 0x000ffff, 0x0000ffff, false); - - -/* Turn a howto into a reloc number */ - -static int -coff_h8500_select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type; -} - -#define SELECT_RELOC(x,howto) x.r_type = coff_h8500_select_reloc(howto) - - -#define BADMAG(x) H8500BADMAG(x) -#define H8500 1 /* Customize coffcode.h */ - -#define __A_MAGIC_SET__ - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto(internal, dst) - arelent * internal; - struct internal_reloc *dst; -{ - switch (dst->r_type) - { - default: - abort (); - break; - case R_H8500_IMM8: - internal->howto = &r_imm8; - break; - case R_H8500_IMM16: - internal->howto = &r_imm16; - break; - case R_H8500_IMM24: - internal->howto = &r_imm24; - break; - case R_H8500_IMM32: - internal->howto = &r_imm32; - break; - case R_H8500_PCREL8: - internal->howto = &r_pcrel8; - break; - case R_H8500_PCREL16: - internal->howto = &r_pcrel16; - break; - case R_H8500_HIGH8: - internal->howto = &r_high8; - break; - case R_H8500_HIGH16: - internal->howto = &r_high16; - break; - case R_H8500_LOW16: - internal->howto = &r_low16; - break; - } -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (reloc->r_symndx > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - - relent->addend = reloc->r_offset; - relent->address -= section->vma; -} - -static void -extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - bfd_byte *d = data+*dst_ptr; - asection *input_section = link_order->u.indirect.section; - switch (reloc->howto->type) - { - case R_H8500_IMM8: - bfd_put_8 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - d); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_H8500_HIGH8: - bfd_put_8 (in_abfd, - (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - >> 16), - d ); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_H8500_IMM16: - bfd_put_16 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - d ); - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_H8500_LOW16: - bfd_put_16 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - d); - - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_H8500_HIGH16: - bfd_put_16 (in_abfd, - (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - >>16), - d); - - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_H8500_IMM24: - { - int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - int o = bfd_get_32(in_abfd, data+ *dst_ptr -1); - v = (v & 0x00ffffff) | (o & 0xff00000); - bfd_put_32 (in_abfd, v, data + *dst_ptr -1); - (*dst_ptr) +=3; - (*src_ptr)+=3;; - } - break; - case R_H8500_IMM32: - { - int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - bfd_put_32 (in_abfd, v, data + *dst_ptr); - (*dst_ptr) +=4; - (*src_ptr)+=4;; - } - break; - - - case R_H8500_PCREL8: - { - bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + *dst_ptr - + link_order->u.indirect.section->output_section->vma; - int gap = dst - dot - 1; /* -1 since were in the odd byte of the - word and the pc's been incremented */ - - if (gap > 128 || gap < -128) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - bfd_put_8 (in_abfd, gap, data + *dst_ptr); - (*dst_ptr)++; - (*src_ptr)++; - break; - } - case R_H8500_PCREL16: - { - bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + *dst_ptr - + link_order->u.indirect.section->output_section->vma; - int gap = dst - dot - 1; /* -1 since were in the odd byte of the - word and the pc's been incremented */ - - if (gap > 32767 || gap < -32768) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - bfd_put_16 (in_abfd, gap, data + *dst_ptr); - (*dst_ptr)+=2; - (*src_ptr)+=2; - break; - } - - default: - abort (); - } -} - -#define coff_reloc16_extra_cases extra_case - -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - -const bfd_target h8500coff_vec = -{ - "coff-h8500", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-i386.c b/contrib/gdb/bfd/coff-i386.c deleted file mode 100644 index d905b53cda8..00000000000 --- a/contrib/gdb/bfd/coff-i386.c +++ /dev/null @@ -1,493 +0,0 @@ -/* BFD back-end for Intel 386 COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -#include "coff/i386.h" - -#include "coff/internal.h" - -#ifdef COFF_WITH_PE -#include "coff/pe.h" -#endif - -#include "libcoff.h" - -static bfd_reloc_status_type coff_i386_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_i386_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - - bfd_vma *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) -/* The page size is a guess based on ELF. */ - -#define COFF_PAGE_SIZE 0x1000 - -/* For some reason when using i386 COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. Ian Taylor, Cygnus Support. */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 386 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - - -#ifdef COFF_WITH_PE - if (reloc_entry->howto->type == 7) - { -/* diff -= coff_data(output_bfd)->link_info->pe_info.image_base.value;*/ - exit(1); - } -#endif - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - -#ifdef COFF_WITH_PE -/* Return true if this relocation should - appear in the output .reloc section. */ - -static boolean in_reloc_p(abfd, howto) - bfd * abfd; - reloc_howto_type *howto; -{ - return ! howto->pc_relative && howto->type != R_IMAGEBASE; -} -#endif - -#ifndef PCRELOFFSET -#define PCRELOFFSET false -#endif - -static reloc_howto_type howto_table[] = -{ - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - HOWTO (R_DIR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "dir32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - /* {7}, */ - HOWTO (R_IMAGEBASE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "rva32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - {010}, - {011}, - {012}, - {013}, - {014}, - {015}, - {016}, - HOWTO (R_RELBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_RELWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_RELLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "DISP8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "DISP16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "DISP32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - PCRELOFFSET) /* pcrel_offset */ -}; - -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) I386BADMAG(x) -#define I386 1 /* Customize coffcode.h */ - -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = howto_table + (dst)->r_type; - -/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared - library. On some other COFF targets STYP_BSS is normally - STYP_NOLOAD. */ -#define BSS_NOLOAD_IS_SHARED_LIBRARY - -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && howto_table[reloc.r_type].pc_relative) \ - cache_ptr->addend += asect->vma; \ - } - -/* We use the special COFF backend linker. */ -#define coff_relocate_section _bfd_coff_generic_relocate_section - -static reloc_howto_type * -coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - - reloc_howto_type *howto; - - howto = howto_table + rel->r_type; - -#ifdef COFF_WITH_PE - *addendp = 0; -#endif - - if (howto->pc_relative) - *addendp += sec->vma; - - if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) - { - /* This is a common symbol. The section contents include the - size (sym->n_value) as an addend. The relocate_section - function will be adding in the final value of the symbol. We - need to subtract out the current size in order to get the - correct result. */ - - BFD_ASSERT (h != NULL); - - -#ifndef COFF_WITH_PE - /* I think we *do* want to bypass this. If we don't, I have seen some data - parameters get the wrong relcation address. If I link two versions - with and without this section bypassed and then do a binary comparison, - the addresses which are different can be looked up in the map. The - case in which this section has been bypassed has addresses which correspond - to values I can find in the map */ - *addendp -= sym->n_value; -#endif - } - - /* If the output symbol is common (in which case this must be a - relocateable link), we need to add in the final size of the - common symbol. */ - if (h != NULL && h->root.type == bfd_link_hash_common) - *addendp += h->root.u.c.size; - - -#ifdef COFF_WITH_PE - if (howto->pc_relative) - *addendp -= 4; - - if (rel->r_type == R_IMAGEBASE) - { - *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; - } -#endif - - return howto; -} - - -#define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup - - -static reloc_howto_type * -coff_i386_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_RVA: - return howto_table +R_IMAGEBASE; - case BFD_RELOC_32: - return howto_table + R_DIR32; - case BFD_RELOC_32_PCREL: - return howto_table + R_PCRLONG; - default: - BFD_FAIL (); - return 0; - } -} - - - -#define coff_rtype_to_howto coff_i386_rtype_to_howto - -#include "coffcode.h" - -static const bfd_target * -i3coff_object_p(a) - bfd *a; -{ - return coff_object_p(a); -} - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - i386coff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-i386", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef TARGET_UNDERSCORE - TARGET_UNDERSCORE, /* leading underscore */ -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, i3coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-i860.c b/contrib/gdb/bfd/coff-i860.c deleted file mode 100644 index 9605cdf0b85..00000000000 --- a/contrib/gdb/bfd/coff-i860.c +++ /dev/null @@ -1,423 +0,0 @@ -/* BFD back-end for Intel 860 COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Created mostly by substituting "860" for "386" in coff-i386.c - Harry Dolan , October 1995 - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -#include "coff/i860.h" - -#include "coff/internal.h" - -#include "libcoff.h" - -static bfd_reloc_status_type coff_i860_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_i860_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) -/* The page size is a guess based on ELF. */ - -#define COFF_PAGE_SIZE 0x1000 - -/* For some reason when using i860 COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. Ian Taylor, Cygnus Support. */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -coff_i860_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 860 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - -#ifndef PCRELOFFSET -#define PCRELOFFSET false -#endif - -static reloc_howto_type howto_table[] = -{ - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - HOWTO (R_DIR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "dir32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - /* {7}, */ - HOWTO (R_IMAGEBASE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "rva32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - {010}, - {011}, - {012}, - {013}, - {014}, - {015}, - {016}, - HOWTO (R_RELBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_RELWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_RELLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "DISP8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "DISP16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "DISP32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - PCRELOFFSET) /* pcrel_offset */ -}; - -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) I860BADMAG(x) -#define I860 1 /* Customize coffcode.h */ - -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = howto_table + (dst)->r_type; - -/* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared - library. On some other COFF targets STYP_BSS is normally - STYP_NOLOAD. */ -#define BSS_NOLOAD_IS_SHARED_LIBRARY - -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && howto_table[reloc.r_type].pc_relative) \ - cache_ptr->addend += asect->vma; \ - } - -/* We use the special COFF backend linker. */ -#define coff_relocate_section _bfd_coff_generic_relocate_section - -static reloc_howto_type * -coff_i860_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - - reloc_howto_type *howto; - - howto = howto_table + rel->r_type; - - if (howto->pc_relative) - *addendp += sec->vma; - - if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) - { - /* This is a common symbol. The section contents include the - size (sym->n_value) as an addend. The relocate_section - function will be adding in the final value of the symbol. We - need to subtract out the current size in order to get the - correct result. */ - - BFD_ASSERT (h != NULL); - - - /* I think we *do* want to bypass this. If we don't, I have seen some data - parameters get the wrong relcation address. If I link two versions - with and without this section bypassed and then do a binary comparison, - the addresses which are different can be looked up in the map. The - case in which this section has been bypassed has addresses which correspond - to values I can find in the map */ - *addendp -= sym->n_value; - } - - /* If the output symbol is common (in which case this must be a - relocateable link), we need to add in the final size of the - common symbol. */ - if (h != NULL && h->root.type == bfd_link_hash_common) - *addendp += h->root.u.c.size; - - return howto; -} - -#define coff_rtype_to_howto coff_i860_rtype_to_howto - -#include "coffcode.h" - -static const bfd_target * -i3coff_object_p(a) - bfd *a; -{ - return coff_object_p(a); -} - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - i860coff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-i860", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, i3coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-i960.c b/contrib/gdb/bfd/coff-i960.c deleted file mode 100644 index ed30125f0fa..00000000000 --- a/contrib/gdb/bfd/coff-i960.c +++ /dev/null @@ -1,683 +0,0 @@ -/* BFD back-end for Intel 960 COFF files. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define I960 1 -#define BADMAG(x) I960BADMAG(x) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/i960.h" -#include "coff/internal.h" -#include "libcoff.h" /* to allow easier abstraction-breaking */ - -static bfd_reloc_status_type optcall_callback - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type coff_i960_relocate - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_i960_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static boolean coff_i960_start_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean coff_i960_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); -static boolean coff_i960_adjust_symndx - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - struct internal_reloc *, boolean *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -/* The i960 does not support an MMU, so COFF_PAGE_SIZE can be - arbitrarily small. */ -#define COFF_PAGE_SIZE 1 - -#define COFF_LONG_FILENAMES - -/* This is just like the usual CALC_ADDEND, but it includes the - section VMA for PC relative relocs. */ -#ifndef CALC_ADDEND -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && (reloc.r_type == 25 || reloc.r_type == 27)) \ - cache_ptr->addend += asect->vma; \ - } -#endif - -#define CALLS 0x66003800 /* Template for 'calls' instruction */ -#define BAL 0x0b000000 /* Template for 'bal' instruction */ -#define BAL_MASK 0x00ffffff - -static bfd_reloc_status_type -optcall_callback (abfd, reloc_entry, symbol_in, data, - input_section, ignore_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *ignore_bfd; - char **error_message; -{ - /* This item has already been relocated correctly, but we may be - * able to patch in yet better code - done by digging out the - * correct info on this symbol */ - bfd_reloc_status_type result; - coff_symbol_type *cs = coffsymbol(symbol_in); - - /* Don't do anything with symbols which aren't tied up yet, - except move the reloc. */ - if (bfd_is_und_section (cs->symbol.section)) { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* So the target symbol has to be of coff type, and the symbol - has to have the correct native information within it */ - if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour) - || (cs->native == (combined_entry_type *)NULL)) - { - /* This is interesting, consider the case where we're outputting coff - from a mix n match input, linking from coff to a symbol defined in a - bout file will cause this match to be true. Should I complain? This - will only work if the bout symbol is non leaf. */ - *error_message = - (char *) "uncertain calling convention for non-COFF symbol"; - result = bfd_reloc_dangerous; - } - else - { - switch (cs->native->u.syment.n_sclass) - { - case C_LEAFSTAT: - case C_LEAFEXT: - /* This is a call to a leaf procedure, replace instruction with a bal - to the correct location. */ - { - union internal_auxent *aux = &((cs->native+2)->u.auxent); - int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address); - int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value); - BFD_ASSERT(cs->native->u.syment.n_numaux==2); - - /* We replace the original call instruction with a bal to - the bal entry point - the offset of which is described in - the 2nd auxent of the original symbol. We keep the native - sym and auxents untouched, so the delta between the two - is the offset of the bal entry point. */ - word = ((word + olf) & BAL_MASK) | BAL; - bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address); - } - result = bfd_reloc_ok; - break; - case C_SCALL: - /* This is a call to a system call, replace with a calls to # */ - BFD_ASSERT(0); - result = bfd_reloc_ok; - break; - default: - result = bfd_reloc_ok; - break; - } - } - return result; -} - -/* i960 COFF is used by VxWorks 5.1. However, VxWorks 5.1 does not - appear to correctly handle a reloc against a symbol defined in the - same object file. It appears to simply discard such relocs, rather - than adding their values into the object file. We handle this here - by converting all relocs against defined symbols into relocs - against the section symbol, when generating a relocateable output - file. - - Note that this function is only called if we are not using the COFF - specific backend linker. It only does something when doing a - relocateable link, which will almost certainly fail when not - generating COFF i960 output, so this function is actually no longer - useful. It was used before this target was converted to use the - COFF specific backend linker. */ - -static bfd_reloc_status_type -coff_i960_relocate (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - asection *osec; - - if (output_bfd == NULL) - { - /* Not generating relocateable output file. */ - return bfd_reloc_continue; - } - - if (bfd_is_und_section (bfd_get_section (symbol))) - { - /* Symbol is not defined, so no need to worry about it. */ - return bfd_reloc_continue; - } - - if (bfd_is_com_section (bfd_get_section (symbol))) - { - /* I don't really know what the right action is for a common - symbol. */ - return bfd_reloc_continue; - } - - /* Convert the reloc to use the section symbol. FIXME: This method - is ridiculous. */ - osec = bfd_get_section (symbol)->output_section; - if (coff_section_data (output_bfd, osec) != NULL - && coff_section_data (output_bfd, osec)->tdata != NULL) - reloc_entry->sym_ptr_ptr = - (asymbol **) coff_section_data (output_bfd, osec)->tdata; - else - { - const char *sec_name; - asymbol **syms, **sym_end; - - sec_name = bfd_get_section_name (output_bfd, osec); - syms = bfd_get_outsymbols (output_bfd); - sym_end = syms + bfd_get_symcount (output_bfd); - for (; syms < sym_end; syms++) - { - if (bfd_asymbol_name (*syms) != NULL - && (*syms)->value == 0 - && strcmp ((*syms)->section->output_section->name, - sec_name) == 0) - break; - } - - if (syms >= sym_end) - abort (); - - reloc_entry->sym_ptr_ptr = syms; - - if (coff_section_data (output_bfd, osec) == NULL) - { - osec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, - sizeof (struct coff_section_tdata))); - if (osec->used_by_bfd == NULL) - return bfd_reloc_overflow; - } - coff_section_data (output_bfd, osec)->tdata = (PTR) syms; - } - - /* Let bfd_perform_relocation do its thing, which will include - stuffing the symbol addend into the object file. */ - return bfd_reloc_continue; -} - -static reloc_howto_type howto_rellong = - HOWTO ((unsigned int) R_RELLONG, 0, 2, 32,false, 0, - complain_overflow_bitfield, coff_i960_relocate,"rellong", true, - 0xffffffff, 0xffffffff, 0); -static reloc_howto_type howto_iprmed = - HOWTO (R_IPRMED, 0, 2, 24,true,0, complain_overflow_signed, - coff_i960_relocate, "iprmed ", true, 0x00ffffff, 0x00ffffff, 0); -static reloc_howto_type howto_optcall = - HOWTO (R_OPTCALL, 0,2,24,true,0, complain_overflow_signed, - optcall_callback, "optcall", true, 0x00ffffff, 0x00ffffff, 0); - -static reloc_howto_type * -coff_i960_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - default: - return 0; - case BFD_RELOC_I960_CALLJ: - return &howto_optcall; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - return &howto_rellong; - case BFD_RELOC_24_PCREL: - return &howto_iprmed; - } -} - -/* The real code is in coffcode.h */ - -#define RTYPE2HOWTO(cache_ptr, dst) \ -{ \ - reloc_howto_type *howto_ptr; \ - switch ((dst)->r_type) { \ - case 17: howto_ptr = &howto_rellong; break; \ - case 25: howto_ptr = &howto_iprmed; break; \ - case 27: howto_ptr = &howto_optcall; break; \ - default: howto_ptr = 0; break; \ - } \ - (cache_ptr)->howto = howto_ptr; \ - } - -/* i960 COFF is used by VxWorks 5.1. However, VxWorks 5.1 does not - appear to correctly handle a reloc against a symbol defined in the - same object file. It appears to simply discard such relocs, rather - than adding their values into the object file. We handle this by - converting all relocs against global symbols into relocs against - internal symbols at the start of the section. This routine is - called at the start of the linking process, and it creates the - necessary symbols. */ - -static boolean -coff_i960_start_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz = bfd_coff_symesz (abfd); - asection *o; - bfd_byte *esym; - - if (! info->relocateable) - return true; - - esym = (bfd_byte *) bfd_malloc (symesz); - if (esym == NULL) - return false; - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) - return false; - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_syment isym; - - strncpy (isym._n._n_name, o->name, SYMNMLEN); - isym.n_value = 0; - isym.n_scnum = o->target_index; - isym.n_type = T_NULL; - isym.n_sclass = C_STAT; - isym.n_numaux = 0; - - bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym); - - if (bfd_write (esym, symesz, 1, abfd) != symesz) - { - free (esym); - return false; - } - - obj_raw_syment_count (abfd) += 1; - } - - free (esym); - - return true; -} - -/* The reloc processing routine for the optimized COFF linker. */ - -static boolean -coff_i960_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - reloc_howto_type *howto; - bfd_reloc_status_type rstat = bfd_reloc_ok; - boolean done; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = obj_coff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - } - - if (sym != NULL && sym->n_scnum != 0) - addend = - sym->n_value; - else - addend = 0; - - switch (rel->r_type) - { - case 17: howto = &howto_rellong; break; - case 25: howto = &howto_iprmed; break; - case 27: howto = &howto_optcall; break; - default: - bfd_set_error (bfd_error_bad_value); - return false; - } - - val = 0; - - if (h == NULL) - { - asection *sec; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (! info->relocateable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - done = false; - - if (howto->type == R_OPTCALL && ! info->relocateable && symndx != -1) - { - int class; - - if (h != NULL) - class = h->class; - else - class = sym->n_sclass; - - switch (class) - { - case C_NULL: - /* This symbol is apparently not from a COFF input file. - We warn, and then assume that it is not a leaf - function. */ - if (! ((*info->callbacks->reloc_dangerous) - (info, - "uncertain calling convention for non-COFF symbol", - input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - break; - case C_LEAFSTAT: - case C_LEAFEXT: - /* This is a call to a leaf procedure; use the bal - instruction. */ - { - long olf; - unsigned long word; - - if (h != NULL) - { - BFD_ASSERT (h->numaux == 2); - olf = h->aux[1].x_bal.x_balntry; - } - else - { - bfd_byte *esyms; - union internal_auxent aux; - - BFD_ASSERT (sym->n_numaux == 2); - esyms = (bfd_byte *) obj_coff_external_syms (input_bfd); - esyms += (symndx + 2) * bfd_coff_symesz (input_bfd); - bfd_coff_swap_aux_in (input_bfd, (PTR) esyms, sym->n_type, - sym->n_sclass, 1, sym->n_numaux, - (PTR) &aux); - olf = aux.x_bal.x_balntry; - } - - word = bfd_get_32 (input_bfd, - (contents - + (rel->r_vaddr - input_section->vma))); - word = ((word + olf - val) & BAL_MASK) | BAL; - bfd_put_32 (input_bfd, - word, - (contents - + (rel->r_vaddr - input_section->vma))); - done = true; - } - break; - case C_SCALL: - BFD_ASSERT (0); - break; - } - } - - if (! done) - { - if (howto->pc_relative) - addend += input_section->vma; - rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - } - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - - return true; -} - -/* Adjust the symbol index of any reloc against a global symbol to - instead be a reloc against the internal symbol we created specially - for the section. */ - -/*ARGSUSED*/ -static boolean -coff_i960_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) - bfd *obfd; - struct bfd_link_info *info; - bfd *ibfd; - asection *sec; - struct internal_reloc *irel; - boolean *adjustedp; -{ - struct coff_link_hash_entry *h; - - *adjustedp = false; - - h = obj_coff_sym_hashes (ibfd)[irel->r_symndx]; - if (h == NULL - || (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak)) - return true; - - irel->r_symndx = h->root.u.def.section->output_section->target_index - 1; - *adjustedp = true; - - return true; -} - -#define coff_start_final_link coff_i960_start_final_link - -#define coff_relocate_section coff_i960_relocate_section - -#define coff_adjust_symndx coff_i960_adjust_symndx - -#define coff_bfd_reloc_type_lookup coff_i960_reloc_type_lookup - -#include "coffcode.h" - -const bfd_target icoff_little_vec = -{ - "coff-Intel-little", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - - -const bfd_target icoff_big_vec = -{ - "coff-Intel-big", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - -bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ -bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-m68k.c b/contrib/gdb/bfd/coff-m68k.c deleted file mode 100644 index 77fb45b6d64..00000000000 --- a/contrib/gdb/bfd/coff-m68k.c +++ /dev/null @@ -1,203 +0,0 @@ -/* BFD back-end for Motorola 68000 COFF binaries. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/m68k.h" -#include "coff/internal.h" -#include "libcoff.h" - -#ifndef LYNX_SPECIAL_FN -#define LYNX_SPECIAL_FN 0 -#endif - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) - -#ifndef COFF_PAGE_SIZE -/* The page size is a guess based on ELF. */ -#define COFF_PAGE_SIZE 0x2000 -#endif - -/* Clean up namespace. */ -#define m68kcoff_howto_table _bfd_m68kcoff_howto_table -#define m68k_rtype2howto _bfd_m68kcoff_rtype2howto -#define m68k_howto2rtype _bfd_m68kcoff_howto2rtype -#define m68k_reloc_type_lookup _bfd_m68kcoff_reloc_type_lookup - -#ifdef ONLY_DECLARE_RELOCS -extern reloc_howto_type m68kcoff_howto_table[]; -#else -reloc_howto_type m68kcoff_howto_table[] = -{ - HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, LYNX_SPECIAL_FN, "DISP8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, LYNX_SPECIAL_FN, "DISP16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, LYNX_SPECIAL_FN, "DISP32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_RELLONG_NEG, 0, -2, 32, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "-32", true, 0xffffffff,0xffffffff, false), -}; -#endif /* not ONLY_DECLARE_RELOCS */ - -#ifndef BADMAG -#define BADMAG(x) M68KBADMAG(x) -#endif -#define M68 1 /* Customize coffcode.h */ - -/* Turn a howto into a reloc number */ - -#ifdef ONLY_DECLARE_RELOCS -extern void m68k_rtype2howto PARAMS ((arelent *internal, int relocentry)); -extern int m68k_howto2rtype PARAMS ((reloc_howto_type *)); -extern reloc_howto_type *m68k_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -#else -void -m68k_rtype2howto(internal, relocentry) - arelent *internal; - int relocentry; -{ - switch (relocentry) - { - case R_RELBYTE: internal->howto = m68kcoff_howto_table + 0; break; - case R_RELWORD: internal->howto = m68kcoff_howto_table + 1; break; - case R_RELLONG: internal->howto = m68kcoff_howto_table + 2; break; - case R_PCRBYTE: internal->howto = m68kcoff_howto_table + 3; break; - case R_PCRWORD: internal->howto = m68kcoff_howto_table + 4; break; - case R_PCRLONG: internal->howto = m68kcoff_howto_table + 5; break; - case R_RELLONG_NEG: internal->howto = m68kcoff_howto_table + 6; break; - } -} - -int -m68k_howto2rtype (internal) - reloc_howto_type *internal; -{ - if (internal->pc_relative) - { - switch (internal->bitsize) - { - case 32: return R_PCRLONG; - case 16: return R_PCRWORD; - case 8: return R_PCRBYTE; - } - } - else - { - switch (internal->bitsize) - { - case 32: return R_RELLONG; - case 16: return R_RELWORD; - case 8: return R_RELBYTE; - } - } - return R_RELLONG; -} - -reloc_howto_type * -m68k_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - default: return NULL; - case BFD_RELOC_8: return m68kcoff_howto_table + 0; - case BFD_RELOC_16: return m68kcoff_howto_table + 1; - case BFD_RELOC_CTOR: - case BFD_RELOC_32: return m68kcoff_howto_table + 2; - case BFD_RELOC_8_PCREL: return m68kcoff_howto_table + 3; - case BFD_RELOC_16_PCREL: return m68kcoff_howto_table + 4; - case BFD_RELOC_32_PCREL: return m68kcoff_howto_table + 5; - /* FIXME: There doesn't seem to be a code for R_RELLONG_NEG. */ - } - /*NOTREACHED*/ -} - -#endif /* not ONLY_DECLARE_RELOCS */ - -#define RTYPE2HOWTO(internal, relocentry) \ - m68k_rtype2howto(internal, (relocentry)->r_type) - -#define SELECT_RELOC(external, internal) \ - external.r_type = m68k_howto2rtype(internal); - -#define coff_bfd_reloc_type_lookup m68k_reloc_type_lookup - -#define coff_relocate_section _bfd_coff_generic_relocate_section - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - m68kcoff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-m68k", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef NAMES_HAVE_UNDERSCORE - '_', -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE - }; diff --git a/contrib/gdb/bfd/coff-m88k.c b/contrib/gdb/bfd/coff-m88k.c deleted file mode 100644 index 414106d7bcb..00000000000 --- a/contrib/gdb/bfd/coff-m88k.c +++ /dev/null @@ -1,311 +0,0 @@ -/* BFD back-end for Motorola 88000 COFF "Binary Compatability Standard" files. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define M88 1 /* Customize various include files */ -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/m88k.h" -#include "coff/internal.h" -#include "libcoff.h" - -static bfd_reloc_status_type m88k_special_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static void rtype2howto PARAMS ((arelent *, struct internal_reloc *)); -static void reloc_processing - PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -static bfd_reloc_status_type -m88k_special_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - reloc_howto_type *howto = reloc_entry->howto; - - switch (howto->type) - { - case R_HVRT16: - case R_LVRT16: - if (output_bfd != (bfd *) NULL) - { - /* This is a partial relocation, and we want to apply the - relocation to the reloc entry rather than the raw data. - Modify the reloc inplace to reflect what we now know. */ - - reloc_entry->address += input_section->output_offset; - } - else - { - bfd_vma output_base = 0; - bfd_vma addr = reloc_entry->address; - bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - asection *reloc_target_output_section; - long relocation = 0; - - /* Work out which section the relocation is targetted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (output_bfd) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += ((reloc_entry->addend << howto->bitsize) + x); - - reloc_entry->addend = 0; - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= (bfd_vma) howto->bitpos; - - if (relocation) - bfd_put_16 (abfd, relocation, (unsigned char *) data + addr); - } - - return bfd_reloc_ok; - break; - - default: - if (output_bfd != (bfd *) NULL) - { - /* This is a partial relocation, and we want to apply the - relocation to the reloc entry rather than the raw data. - Modify the reloc inplace to reflect what we now know. */ - - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - break; - } - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static reloc_howto_type howto_table[] = -{ - HOWTO (R_PCR16L, /* type */ - 02, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "PCR16L", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_PCR26L, /* type */ - 02, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "PCR26L", /* name */ - false, /* partial_inplace */ - 0x03ffffff, /* src_mask */ - 0x03ffffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_VRT16, /* type */ - 00, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "VRT16", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_HVRT16, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "HVRT16", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_LVRT16, /* type */ - 00, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "LVRT16", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_VRT32, /* type */ - 00, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "VRT32", /* name */ - false, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ -}; - -/* Code to turn an external r_type into a pointer to an entry in the - above howto table. */ -static void -rtype2howto (cache_ptr, dst) - arelent *cache_ptr; - struct internal_reloc *dst; -{ - if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32) - { - cache_ptr->howto = howto_table + dst->r_type - R_PCR16L; - } - else - { - BFD_ASSERT (0); - } -} - -#define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst) - - -/* Code to swap in the reloc offset */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_16 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_16 - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent *relent; - struct internal_reloc *reloc; - asymbol **symbols; - bfd *abfd; - asection *section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (((int) reloc->r_symndx) > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - relent->addend = reloc->r_offset; - relent->address -= section->vma; -} - -#define BADMAG(x) MC88BADMAG(x) -#include "coffcode.h" - -#undef coff_write_armap - -const bfd_target m88kbcs_vec = -{ - "coff-m88kbcs", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-mips.c b/contrib/gdb/bfd/coff-mips.c deleted file mode 100644 index c860f9a4d53..00000000000 --- a/contrib/gdb/bfd/coff-mips.c +++ /dev/null @@ -1,2596 +0,0 @@ -/* BFD back-end for MIPS Extended-Coff files. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Original version by Per Bothner. - Full support added by Ian Lance Taylor, ian@cygnus.com. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" -#include "coff/mips.h" -#include "libcoff.h" -#include "libecoff.h" - -/* Prototypes for static functions. */ - -static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr)); -static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR, - struct internal_reloc *)); -static void mips_ecoff_swap_reloc_out PARAMS ((bfd *, - const struct internal_reloc *, - PTR)); -static void mips_adjust_reloc_in PARAMS ((bfd *, - const struct internal_reloc *, - arelent *)); -static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *, - struct internal_reloc *)); -static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_relhi_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_rello_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_switch_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static void mips_relocate_hi PARAMS ((struct internal_reloc *refhi, - struct internal_reloc *reflo, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - size_t adjust, - bfd_vma relocation, - boolean pcrel)); -static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *, - bfd *, asection *, - bfd_byte *, PTR)); -static boolean mips_read_relocs PARAMS ((bfd *, asection *)); -static boolean mips_relax_section PARAMS ((bfd *, asection *, - struct bfd_link_info *, - boolean *)); -static boolean mips_relax_pcrel16 PARAMS ((struct bfd_link_info *, bfd *, - asection *, - struct ecoff_link_hash_entry *, - bfd_byte *, bfd_vma)); - -/* ECOFF has COFF sections, but the debugging information is stored in - a completely different format. ECOFF targets use some of the - swapping routines from coffswap.h, and some of the generic COFF - routines in coffgen.c, but, unlike the real COFF targets, do not - use coffcode.h itself. - - Get the generic COFF swapping routines, except for the reloc, - symbol, and lineno ones. Give them ECOFF names. */ -#define MIPSECOFF -#define NO_COFF_RELOCS -#define NO_COFF_SYMBOLS -#define NO_COFF_LINENOS -#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in -#define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out -#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in -#define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out -#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in -#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out -#include "coffswap.h" - -/* Get the ECOFF swapping routines. */ -#define ECOFF_32 -#include "ecoffswap.h" - -/* How to process the various relocs types. */ - -static reloc_howto_type mips_howto_table[] = -{ - /* Reloc type 0 is ignored. The reloc reading code ensures that - this is a reference to the .abs section, which will cause - bfd_perform_relocation to do nothing. */ - HOWTO (MIPS_R_IGNORE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "IGNORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 16 bit reference to a symbol, normally from a data section. */ - HOWTO (MIPS_R_REFHALF, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_generic_reloc, /* special_function */ - "REFHALF", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit reference to a symbol, normally from a data section. */ - HOWTO (MIPS_R_REFWORD, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_generic_reloc, /* special_function */ - "REFWORD", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 26 bit absolute jump address. */ - HOWTO (MIPS_R_JMPADDR, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - /* This needs complex overflow - detection, because the upper four - bits must match the PC. */ - mips_generic_reloc, /* special_function */ - "JMPADDR", /* name */ - true, /* partial_inplace */ - 0x3ffffff, /* src_mask */ - 0x3ffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high 16 bits of a symbol value. Handled by the function - mips_refhi_reloc. */ - HOWTO (MIPS_R_REFHI, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_refhi_reloc, /* special_function */ - "REFHI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The low 16 bits of a symbol value. */ - HOWTO (MIPS_R_REFLO, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_reflo_reloc, /* special_function */ - "REFLO", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A reference to an offset from the gp register. Handled by the - function mips_gprel_reloc. */ - HOWTO (MIPS_R_GPREL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_gprel_reloc, /* special_function */ - "GPREL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A reference to a literal using an offset from the gp register. - Handled by the function mips_gprel_reloc. */ - HOWTO (MIPS_R_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_gprel_reloc, /* special_function */ - "LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 8 }, - { 9 }, - { 10 }, - { 11 }, - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents a 16 bit PC - relative reloc rightshifted twice as used in the MIPS branch - instructions. */ - HOWTO (MIPS_R_PCREL16, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_generic_reloc, /* special_function */ - "PCREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents the high 16 - bits of a PC relative reloc. The next reloc must be - MIPS_R_RELLO, and the addend is formed from the addends of the - two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO. The - final value is actually PC relative to the location of the - MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc. */ - HOWTO (MIPS_R_RELHI, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_relhi_reloc, /* special_function */ - "RELHI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents the low 16 - bits of a PC relative reloc. */ - HOWTO (MIPS_R_RELLO, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_rello_reloc, /* special_function */ - "RELLO", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - { 15 }, - { 16 }, - { 17 }, - { 18 }, - { 19 }, - { 20 }, - { 21 }, - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents an entry in - a switch table, which is the difference between two symbols in - the .text section. The symndx is actually the offset from the - reloc address to the subtrahend. See include/coff/mips.h for - more details. */ - HOWTO (MIPS_R_SWITCH, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_switch_reloc, /* special_function */ - "SWITCH", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true) /* pcrel_offset */ -}; - -#define MIPS_HOWTO_COUNT \ - (sizeof mips_howto_table / sizeof mips_howto_table[0]) - -/* When the linker is doing relaxing, it may change a external PCREL16 - reloc. This typically represents an instruction like - bal foo - We change it to - .set noreorder - bal $L1 - lui $at,%hi(foo - $L1) - $L1: - addiu $at,%lo(foo - $L1) - addu $at,$at,$31 - jalr $at - PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the - instruction by. */ - -#define PCREL16_EXPANSION_ADJUSTMENT (4 * 4) - -/* See whether the magic number matches. */ - -static boolean -mips_ecoff_bad_format_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - switch (internal_f->f_magic) - { - case MIPS_MAGIC_1: - /* I don't know what endianness this implies. */ - return true; - - case MIPS_MAGIC_BIG: - case MIPS_MAGIC_BIG2: - case MIPS_MAGIC_BIG3: - return bfd_big_endian (abfd); - - case MIPS_MAGIC_LITTLE: - case MIPS_MAGIC_LITTLE2: - case MIPS_MAGIC_LITTLE3: - return bfd_little_endian (abfd); - - default: - return false; - } -} - -/* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in - external form. They use a bit which indicates whether the symbol - is external. */ - -/* Swap a reloc in. */ - -static void -mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern) - bfd *abfd; - PTR ext_ptr; - struct internal_reloc *intern; -{ - const RELOC *ext = (RELOC *) ext_ptr; - - intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr); - if (bfd_header_big_endian (abfd)) - { - intern->r_symndx = (((int) ext->r_bits[0] - << RELOC_BITS0_SYMNDX_SH_LEFT_BIG) - | ((int) ext->r_bits[1] - << RELOC_BITS1_SYMNDX_SH_LEFT_BIG) - | ((int) ext->r_bits[2] - << RELOC_BITS2_SYMNDX_SH_LEFT_BIG)); - intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG) - >> RELOC_BITS3_TYPE_SH_BIG); - intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0; - } - else - { - intern->r_symndx = (((int) ext->r_bits[0] - << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE) - | ((int) ext->r_bits[1] - << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE) - | ((int) ext->r_bits[2] - << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE)); - intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE) - >> RELOC_BITS3_TYPE_SH_LITTLE) - | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE) - << RELOC_BITS3_TYPEHI_SH_LITTLE)); - intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0; - } - - /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or - MIPS_R_RELLO reloc, r_symndx is actually the offset from the - reloc address to the base of the difference (see - include/coff/mips.h for more details). We copy symndx into the - r_offset field so as not to confuse ecoff_slurp_reloc_table in - ecoff.c. In adjust_reloc_in we then copy r_offset into the reloc - addend. */ - if (intern->r_type == MIPS_R_SWITCH - || (! intern->r_extern - && (intern->r_type == MIPS_R_RELLO - || intern->r_type == MIPS_R_RELHI))) - { - BFD_ASSERT (! intern->r_extern); - intern->r_offset = intern->r_symndx; - if (intern->r_offset & 0x800000) - intern->r_offset -= 0x1000000; - intern->r_symndx = RELOC_SECTION_TEXT; - } -} - -/* Swap a reloc out. */ - -static void -mips_ecoff_swap_reloc_out (abfd, intern, dst) - bfd *abfd; - const struct internal_reloc *intern; - PTR dst; -{ - RELOC *ext = (RELOC *) dst; - long r_symndx; - - BFD_ASSERT (intern->r_extern - || (intern->r_symndx >= 0 && intern->r_symndx <= 12)); - - /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELLO or - MIPS_R_RELHI reloc, we actually want to write the contents of - r_offset out as the symbol index. This undoes the change made by - mips_ecoff_swap_reloc_in. */ - if (intern->r_type != MIPS_R_SWITCH - && (intern->r_extern - || (intern->r_type != MIPS_R_RELHI - && intern->r_type != MIPS_R_RELLO))) - r_symndx = intern->r_symndx; - else - { - BFD_ASSERT (intern->r_symndx == RELOC_SECTION_TEXT); - r_symndx = intern->r_offset & 0xffffff; - } - - bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr); - if (bfd_header_big_endian (abfd)) - { - ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG; - ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG; - ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG; - ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG) - & RELOC_BITS3_TYPE_BIG) - | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0)); - } - else - { - ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE; - ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE; - ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE; - ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE) - & RELOC_BITS3_TYPE_LITTLE) - | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE - & RELOC_BITS3_TYPEHI_LITTLE)) - | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0)); - } -} - -/* Finish canonicalizing a reloc. Part of this is generic to all - ECOFF targets, and that part is in ecoff.c. The rest is done in - this backend routine. It must fill in the howto field. */ - -static void -mips_adjust_reloc_in (abfd, intern, rptr) - bfd *abfd; - const struct internal_reloc *intern; - arelent *rptr; -{ - if (intern->r_type > MIPS_R_SWITCH) - abort (); - - if (! intern->r_extern - && (intern->r_type == MIPS_R_GPREL - || intern->r_type == MIPS_R_LITERAL)) - rptr->addend += ecoff_data (abfd)->gp; - - /* If the type is MIPS_R_IGNORE, make sure this is a reference to - the absolute section so that the reloc is ignored. */ - if (intern->r_type == MIPS_R_IGNORE) - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - - /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or - MIPS_R_RELLO reloc, we want the addend field of the BFD relocto - hold the value which was originally in the symndx field of the - internal MIPS ECOFF reloc. This value was copied into - intern->r_offset by mips_swap_reloc_in, and here we copy it into - the addend field. */ - if (intern->r_type == MIPS_R_SWITCH - || (! intern->r_extern - && (intern->r_type == MIPS_R_RELHI - || intern->r_type == MIPS_R_RELLO))) - rptr->addend = intern->r_offset; - - rptr->howto = &mips_howto_table[intern->r_type]; -} - -/* Make any adjustments needed to a reloc before writing it out. None - are needed for MIPS. */ - -static void -mips_adjust_reloc_out (abfd, rel, intern) - bfd *abfd; - const arelent *rel; - struct internal_reloc *intern; -{ - /* For a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or - MIPS_R_RELLO reloc, we must copy rel->addend into - intern->r_offset. This will then be written out as the symbol - index by mips_ecoff_swap_reloc_out. This operation parallels the - action of mips_adjust_reloc_in. */ - if (intern->r_type == MIPS_R_SWITCH - || (! intern->r_extern - && (intern->r_type == MIPS_R_RELHI - || intern->r_type == MIPS_R_RELLO))) - intern->r_offset = rel->addend; -} - -/* ECOFF relocs are either against external symbols, or against - sections. If we are producing relocateable output, and the reloc - is against an external symbol, and nothing has given us any - additional addend, the resulting reloc will also be against the - same symbol. In such a case, we don't want to change anything - about the way the reloc is handled, since it will all be done at - final link time. Rather than put special case code into - bfd_perform_relocation, all the reloc types use this howto - function. It just short circuits the reloc if producing - relocateable output against an external symbol. */ - -static bfd_reloc_status_type -mips_generic_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -/* Do a REFHI relocation. This has to be done in combination with a - REFLO reloc, because there is a carry from the REFLO to the REFHI. - Here we just save the information we need; we do the actual - relocation when we see the REFLO. MIPS ECOFF requires that the - REFLO immediately follow the REFHI, so this ought to work. */ - -static bfd_byte *mips_refhi_addr; -static bfd_vma mips_refhi_addend; - -static bfd_reloc_status_type -mips_refhi_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - - /* If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let REFLO do the actual relocation. */ - mips_refhi_addr = (bfd_byte *) data + reloc_entry->address; - mips_refhi_addend = relocation; - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a REFLO relocation. This is a straightforward 16 bit inplace - relocation; this function exists in order to do the REFHI - relocation described above. */ - -static bfd_reloc_status_type -mips_reflo_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (mips_refhi_addr != (bfd_byte *) NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - - /* Do the REFHI relocation. Note that we actually don't need to - know anything about the REFLO itself, except where to find - the low 16 bits of the addend needed by the REFHI. */ - insn = bfd_get_32 (abfd, mips_refhi_addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += mips_refhi_addend; - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the - data, and once for the bits we are putting back in to the - data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, insn, mips_refhi_addr); - - mips_refhi_addr = (bfd_byte *) NULL; - } - - /* Now do the REFLO reloc in the usual way. */ - return mips_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* Do a GPREL relocation. This is a 16 bit value which must become - the offset from the gp register. */ - -static bfd_reloc_status_type -mips_gprel_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - boolean relocateable; - bfd_vma gp; - bfd_vma relocation; - unsigned long val; - unsigned long insn; - - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ECOFF - file. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != (bfd *) NULL) - relocateable = true; - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - } - - if (bfd_is_und_section (symbol->section) - && relocateable == false) - return bfd_reloc_undefined; - - /* We have to figure out the gp value, so that we can adjust the - symbol value correctly. We look up the symbol _gp in the output - BFD. If we can't find it, we're stuck. We cache it in the ECOFF - target data. We don't need to adjust the symbol value for an - external symbol if we are producing relocateable output. */ - gp = _bfd_get_gp_value (output_bfd); - if (gp == 0 - && (relocateable == false - || (symbol->flags & BSF_SECTION_SYM) != 0)) - { - if (relocateable != false) - { - /* Make up a value. */ - gp = symbol->section->output_section->vma + 0x4000; - _bfd_set_gp_value (output_bfd, gp); - } - else - { - unsigned int count; - asymbol **sym; - unsigned int i; - - count = bfd_get_symcount (output_bfd); - sym = bfd_get_outsymbols (output_bfd); - - if (sym == (asymbol **) NULL) - i = count; - else - { - for (i = 0; i < count; i++, sym++) - { - register CONST char *name; - - name = bfd_asymbol_name (*sym); - if (*name == '_' && strcmp (name, "_gp") == 0) - { - gp = bfd_asymbol_value (*sym); - _bfd_set_gp_value (output_bfd, gp); - break; - } - } - } - - if (i >= count) - { - /* Only get the error once. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - *error_message = - (char *) "GP relative relocation when _gp not defined"; - return bfd_reloc_dangerous; - } - } - } - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - - /* Set val to the offset into the section or symbol. */ - val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff; - if (val & 0x8000) - val -= 0x10000; - - /* Adjust val for the final section location and GP value. If we - are producing relocateable output, we don't want to do this for - an external symbol. */ - if (relocateable == false - || (symbol->flags & BSF_SECTION_SYM) != 0) - val += relocation - gp; - - insn = (insn &~ 0xffff) | (val & 0xffff); - bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); - - if (relocateable != false) - reloc_entry->address += input_section->output_offset; - - /* Make sure it fit in 16 bits. */ - if (val >= 0x8000 && val < 0xffff8000) - return bfd_reloc_overflow; - - return bfd_reloc_ok; -} - -/* Do a RELHI relocation. We do this in conjunction with a RELLO - reloc, just as REFHI and REFLO are done together. RELHI and RELLO - are Cygnus extensions used when generating position independent - code for embedded systems. */ - -static bfd_byte *mips_relhi_addr; -static bfd_vma mips_relhi_addend; - -static bfd_reloc_status_type -mips_relhi_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - - /* If this is a reloc against a section symbol, then it is correct - in the object file. The only time we want to change this case is - when we are relaxing, and that is handled entirely by - mips_relocate_section and never calls this function. */ - if ((symbol->flags & BSF_SECTION_SYM) != 0) - { - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* This is an external symbol. If we're relocating, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let RELLO do the actual relocation. */ - mips_relhi_addr = (bfd_byte *) data + reloc_entry->address; - mips_relhi_addend = relocation; - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a RELLO relocation. This is a straightforward 16 bit PC - relative relocation; this function exists in order to do the RELHI - relocation described above. */ - -static bfd_reloc_status_type -mips_rello_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (mips_relhi_addr != (bfd_byte *) NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - - /* Do the RELHI relocation. Note that we actually don't need to - know anything about the RELLO itself, except where to find - the low 16 bits of the addend needed by the RELHI. */ - insn = bfd_get_32 (abfd, mips_relhi_addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += mips_relhi_addend; - - /* If the symbol is defined, make val PC relative. If the - symbol is not defined we don't want to do this, because we - don't want the value in the object file to incorporate the - address of the reloc. */ - if (! bfd_is_und_section (bfd_get_section (symbol)) - && ! bfd_is_com_section (bfd_get_section (symbol))) - val -= (input_section->output_section->vma - + input_section->output_offset - + reloc_entry->address); - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the - data, and once for the bits we are putting back in to the - data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, insn, mips_relhi_addr); - - mips_relhi_addr = (bfd_byte *) NULL; - } - - /* If this is a reloc against a section symbol, then it is correct - in the object file. The only time we want to change this case is - when we are relaxing, and that is handled entirely by - mips_relocate_section and never calls this function. */ - if ((symbol->flags & BSF_SECTION_SYM) != 0) - { - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* bfd_perform_relocation does not handle pcrel_offset relocations - correctly when generating a relocateable file, so handle them - directly here. */ - if (output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* Now do the RELLO reloc in the usual way. */ - return mips_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* This is the special function for the MIPS_R_SWITCH reloc. This - special reloc is normally correct in the object file, and only - requires special handling when relaxing. We don't want - bfd_perform_relocation to tamper with it at all. */ - -/*ARGSUSED*/ -static bfd_reloc_status_type -mips_switch_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return bfd_reloc_ok; -} - -/* Get the howto structure for a generic reloc type. */ - -static reloc_howto_type * -mips_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - int mips_type; - - switch (code) - { - case BFD_RELOC_16: - mips_type = MIPS_R_REFHALF; - break; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - mips_type = MIPS_R_REFWORD; - break; - case BFD_RELOC_MIPS_JMP: - mips_type = MIPS_R_JMPADDR; - break; - case BFD_RELOC_HI16_S: - mips_type = MIPS_R_REFHI; - break; - case BFD_RELOC_LO16: - mips_type = MIPS_R_REFLO; - break; - case BFD_RELOC_MIPS_GPREL: - mips_type = MIPS_R_GPREL; - break; - case BFD_RELOC_MIPS_LITERAL: - mips_type = MIPS_R_LITERAL; - break; - case BFD_RELOC_16_PCREL_S2: - mips_type = MIPS_R_PCREL16; - break; - case BFD_RELOC_PCREL_HI16_S: - mips_type = MIPS_R_RELHI; - break; - case BFD_RELOC_PCREL_LO16: - mips_type = MIPS_R_RELLO; - break; - case BFD_RELOC_GPREL32: - mips_type = MIPS_R_SWITCH; - break; - default: - return (reloc_howto_type *) NULL; - } - - return &mips_howto_table[mips_type]; -} - -/* A helper routine for mips_relocate_section which handles the REFHI - and RELHI relocations. The REFHI relocation must be followed by a - REFLO relocation (and RELHI by a RELLO), and the addend used is - formed from the addends of both instructions. */ - -static void -mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust, - relocation, pcrel) - struct internal_reloc *refhi; - struct internal_reloc *reflo; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - size_t adjust; - bfd_vma relocation; - boolean pcrel; -{ - unsigned long insn; - unsigned long val; - unsigned long vallo; - - insn = bfd_get_32 (input_bfd, - contents + adjust + refhi->r_vaddr - input_section->vma); - vallo = (bfd_get_32 (input_bfd, - contents + adjust + reflo->r_vaddr - input_section->vma) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += relocation; - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the data, - and once for the bits we are putting back in to the data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - - if (pcrel) - val -= (input_section->output_section->vma - + input_section->output_offset - + (reflo->r_vaddr - input_section->vma + adjust)); - - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (input_bfd, (bfd_vma) insn, - contents + adjust + refhi->r_vaddr - input_section->vma); -} - -/* Relocate a section while linking a MIPS ECOFF file. */ - -static boolean -mips_relocate_section (output_bfd, info, input_bfd, input_section, - contents, external_relocs) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - PTR external_relocs; -{ - asection **symndx_to_section; - struct ecoff_link_hash_entry **sym_hashes; - bfd_vma gp; - boolean gp_undefined; - size_t adjust; - long *offsets; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - unsigned int i; - boolean got_lo; - struct internal_reloc lo_int_rel; - - BFD_ASSERT (input_bfd->xvec->header_byteorder - == output_bfd->xvec->header_byteorder); - - /* We keep a table mapping the symndx found in an internal reloc to - the appropriate section. This is faster than looking up the - section by name each time. */ - symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; - if (symndx_to_section == (asection **) NULL) - { - symndx_to_section = ((asection **) - bfd_alloc (input_bfd, - (NUM_RELOC_SECTIONS - * sizeof (asection *)))); - if (!symndx_to_section) - return false; - - symndx_to_section[RELOC_SECTION_NONE] = NULL; - symndx_to_section[RELOC_SECTION_TEXT] = - bfd_get_section_by_name (input_bfd, ".text"); - symndx_to_section[RELOC_SECTION_RDATA] = - bfd_get_section_by_name (input_bfd, ".rdata"); - symndx_to_section[RELOC_SECTION_DATA] = - bfd_get_section_by_name (input_bfd, ".data"); - symndx_to_section[RELOC_SECTION_SDATA] = - bfd_get_section_by_name (input_bfd, ".sdata"); - symndx_to_section[RELOC_SECTION_SBSS] = - bfd_get_section_by_name (input_bfd, ".sbss"); - symndx_to_section[RELOC_SECTION_BSS] = - bfd_get_section_by_name (input_bfd, ".bss"); - symndx_to_section[RELOC_SECTION_INIT] = - bfd_get_section_by_name (input_bfd, ".init"); - symndx_to_section[RELOC_SECTION_LIT8] = - bfd_get_section_by_name (input_bfd, ".lit8"); - symndx_to_section[RELOC_SECTION_LIT4] = - bfd_get_section_by_name (input_bfd, ".lit4"); - symndx_to_section[RELOC_SECTION_XDATA] = NULL; - symndx_to_section[RELOC_SECTION_PDATA] = NULL; - symndx_to_section[RELOC_SECTION_FINI] = - bfd_get_section_by_name (input_bfd, ".fini"); - symndx_to_section[RELOC_SECTION_LITA] = NULL; - symndx_to_section[RELOC_SECTION_ABS] = NULL; - - ecoff_data (input_bfd)->symndx_to_section = symndx_to_section; - } - - sym_hashes = ecoff_data (input_bfd)->sym_hashes; - - gp = _bfd_get_gp_value (output_bfd); - if (gp == 0) - gp_undefined = true; - else - gp_undefined = false; - - got_lo = false; - - adjust = 0; - - if (ecoff_section_data (input_bfd, input_section) == NULL) - offsets = NULL; - else - offsets = ecoff_section_data (input_bfd, input_section)->offsets; - - ext_rel = (struct external_reloc *) external_relocs; - ext_rel_end = ext_rel + input_section->reloc_count; - for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++) - { - struct internal_reloc int_rel; - bfd_vma addend; - reloc_howto_type *howto; - struct ecoff_link_hash_entry *h = NULL; - asection *s = NULL; - bfd_vma relocation; - bfd_reloc_status_type r; - - if (! got_lo) - mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel); - else - { - int_rel = lo_int_rel; - got_lo = false; - } - - BFD_ASSERT (int_rel.r_type - < sizeof mips_howto_table / sizeof mips_howto_table[0]); - - /* The REFHI and RELHI relocs requires special handling. they - must be followed by a REFLO or RELLO reloc, respectively, and - the addend is formed from both relocs. */ - if (int_rel.r_type == MIPS_R_REFHI - || int_rel.r_type == MIPS_R_RELHI) - { - BFD_ASSERT ((ext_rel + 1) < ext_rel_end); - mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1), - &lo_int_rel); - BFD_ASSERT ((lo_int_rel.r_type - == (int_rel.r_type == MIPS_R_REFHI - ? MIPS_R_REFLO - : MIPS_R_RELLO)) - && int_rel.r_extern == lo_int_rel.r_extern - && int_rel.r_symndx == lo_int_rel.r_symndx); - got_lo = true; - } - - howto = &mips_howto_table[int_rel.r_type]; - - /* The SWITCH reloc must be handled specially. This reloc is - marks the location of a difference between two portions of an - object file. The symbol index does not reference a symbol, - but is actually the offset from the reloc to the subtrahend - of the difference. This reloc is correct in the object file, - and needs no further adjustment, unless we are relaxing. If - we are relaxing, we may have to add in an offset. Since no - symbols are involved in this reloc, we handle it completely - here. */ - if (int_rel.r_type == MIPS_R_SWITCH) - { - if (offsets != NULL - && offsets[i] != 0) - { - r = _bfd_relocate_contents (howto, input_bfd, - (bfd_vma) offsets[i], - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - BFD_ASSERT (r == bfd_reloc_ok); - } - - continue; - } - - if (int_rel.r_extern) - { - h = sym_hashes[int_rel.r_symndx]; - /* If h is NULL, that means that there is a reloc against an - external symbol which we thought was just a debugging - symbol. This should not happen. */ - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - } - else - { - if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS) - s = NULL; - else - s = symndx_to_section[int_rel.r_symndx]; - - if (s == (asection *) NULL) - abort (); - } - - /* The GPREL reloc uses an addend: the difference in the GP - values. */ - if (int_rel.r_type != MIPS_R_GPREL - && int_rel.r_type != MIPS_R_LITERAL) - addend = 0; - else - { - if (gp_undefined) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "GP relative relocation when GP not defined", - input_bfd, input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - gp_undefined = false; - } - if (! int_rel.r_extern) - { - /* This is a relocation against a section. The current - addend in the instruction is the difference between - INPUT_SECTION->vma and the GP value of INPUT_BFD. We - must change this to be the difference between the - final definition (which will end up in RELOCATION) - and the GP value of OUTPUT_BFD (which is in GP). */ - addend = ecoff_data (input_bfd)->gp - gp; - } - else if (! info->relocateable - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - /* This is a relocation against a defined symbol. The - current addend in the instruction is simply the - desired offset into the symbol (normally zero). We - are going to change this into a relocation against a - defined symbol, so we want the instruction to hold - the difference between the final definition of the - symbol (which will end up in RELOCATION) and the GP - value of OUTPUT_BFD (which is in GP). */ - addend = - gp; - } - else - { - /* This is a relocation against an undefined or common - symbol. The current addend in the instruction is - simply the desired offset into the symbol (normally - zero). We are generating relocateable output, and we - aren't going to define this symbol, so we just leave - the instruction alone. */ - addend = 0; - } - } - - /* If we are relaxing, mips_relax_section may have set - offsets[i] to some value. A value of 1 means we must expand - a PC relative branch into a multi-instruction of sequence, - and any other value is an addend. */ - if (offsets != NULL - && offsets[i] != 0) - { - BFD_ASSERT (! info->relocateable); - BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16 - || int_rel.r_type == MIPS_R_RELHI - || int_rel.r_type == MIPS_R_RELLO); - if (offsets[i] != 1) - addend += offsets[i]; - else - { - bfd_byte *here; - - BFD_ASSERT (int_rel.r_extern - && int_rel.r_type == MIPS_R_PCREL16); - - /* Move the rest of the instructions up. */ - here = (contents - + adjust - + int_rel.r_vaddr - - input_section->vma); - memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here, - (size_t) (input_section->_raw_size - - (int_rel.r_vaddr - input_section->vma))); - - /* Generate the new instructions. */ - if (! mips_relax_pcrel16 (info, input_bfd, input_section, - h, here, - (input_section->output_section->vma - + input_section->output_offset - + (int_rel.r_vaddr - - input_section->vma) - + adjust))) - return false; - - /* We must adjust everything else up a notch. */ - adjust += PCREL16_EXPANSION_ADJUSTMENT; - - /* mips_relax_pcrel16 handles all the details of this - relocation. */ - continue; - } - } - - /* If we are relaxing, and this is a reloc against the .text - segment, we may need to adjust it if some branches have been - expanded. The reloc types which are likely to occur in the - .text section are handled efficiently by mips_relax_section, - and thus do not need to be handled here. */ - if (ecoff_data (input_bfd)->debug_info.adjust != NULL - && ! int_rel.r_extern - && int_rel.r_symndx == RELOC_SECTION_TEXT - && (strcmp (bfd_get_section_name (input_bfd, input_section), - ".text") != 0 - || (int_rel.r_type != MIPS_R_PCREL16 - && int_rel.r_type != MIPS_R_SWITCH - && int_rel.r_type != MIPS_R_RELHI - && int_rel.r_type != MIPS_R_RELLO))) - { - bfd_vma adr; - struct ecoff_value_adjust *a; - - /* We need to get the addend so that we know whether we need - to adjust the address. */ - BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD); - - adr = bfd_get_32 (input_bfd, - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - - for (a = ecoff_data (input_bfd)->debug_info.adjust; - a != (struct ecoff_value_adjust *) NULL; - a = a->next) - { - if (adr >= a->start && adr < a->end) - addend += a->adjust; - } - } - - if (info->relocateable) - { - /* We are generating relocateable output, and must convert - the existing reloc. */ - if (int_rel.r_extern) - { - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && ! bfd_is_abs_section (h->root.u.def.section)) - { - const char *name; - - /* This symbol is defined in the output. Convert - the reloc from being against the symbol to being - against the section. */ - - /* Clear the r_extern bit. */ - int_rel.r_extern = 0; - - /* Compute a new r_symndx value. */ - s = h->root.u.def.section; - name = bfd_get_section_name (output_bfd, - s->output_section); - - int_rel.r_symndx = -1; - switch (name[1]) - { - case 'b': - if (strcmp (name, ".bss") == 0) - int_rel.r_symndx = RELOC_SECTION_BSS; - break; - case 'd': - if (strcmp (name, ".data") == 0) - int_rel.r_symndx = RELOC_SECTION_DATA; - break; - case 'f': - if (strcmp (name, ".fini") == 0) - int_rel.r_symndx = RELOC_SECTION_FINI; - break; - case 'i': - if (strcmp (name, ".init") == 0) - int_rel.r_symndx = RELOC_SECTION_INIT; - break; - case 'l': - if (strcmp (name, ".lit8") == 0) - int_rel.r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - int_rel.r_symndx = RELOC_SECTION_LIT4; - break; - case 'r': - if (strcmp (name, ".rdata") == 0) - int_rel.r_symndx = RELOC_SECTION_RDATA; - break; - case 's': - if (strcmp (name, ".sdata") == 0) - int_rel.r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - int_rel.r_symndx = RELOC_SECTION_SBSS; - break; - case 't': - if (strcmp (name, ".text") == 0) - int_rel.r_symndx = RELOC_SECTION_TEXT; - break; - } - - if (int_rel.r_symndx == -1) - abort (); - - /* Add the section VMA and the symbol value. */ - relocation = (h->root.u.def.value - + s->output_section->vma - + s->output_offset); - - /* For a PC relative relocation, the object file - currently holds just the addend. We must adjust - by the address to get the right value. */ - if (howto->pc_relative) - { - relocation -= int_rel.r_vaddr - input_section->vma; - - /* If we are converting a RELHI or RELLO reloc - from being against an external symbol to - being against a section, we must put a - special value into the r_offset field. This - value is the old addend. The r_offset for - both the RELOHI and RELLO relocs are the - same, and we set both when we see RELHI. */ - if (int_rel.r_type == MIPS_R_RELHI) - { - long addhi, addlo; - - addhi = bfd_get_32 (input_bfd, - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - addhi &= 0xffff; - if (addhi & 0x8000) - addhi -= 0x10000; - addhi <<= 16; - - addlo = bfd_get_32 (input_bfd, - (contents - + adjust - + lo_int_rel.r_vaddr - - input_section->vma)); - addlo &= 0xffff; - if (addlo & 0x8000) - addlo -= 0x10000; - - int_rel.r_offset = addhi + addlo; - lo_int_rel.r_offset = int_rel.r_offset; - } - } - - h = NULL; - } - else - { - /* Change the symndx value to the right one for the - output BFD. */ - int_rel.r_symndx = h->indx; - if (int_rel.r_symndx == -1) - { - /* This symbol is not being written out. */ - if (! ((*info->callbacks->unattached_reloc) - (info, h->root.root.string, input_bfd, - input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - int_rel.r_symndx = 0; - } - relocation = 0; - } - } - else - { - /* This is a relocation against a section. Adjust the - value by the amount the section moved. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - } - - relocation += addend; - addend = 0; - - /* Adjust a PC relative relocation by removing the reference - to the original address in the section and including the - reference to the new address. However, external RELHI - and RELLO relocs are PC relative, but don't include any - reference to the address. The addend is merely an - addend. */ - if (howto->pc_relative - && (! int_rel.r_extern - || (int_rel.r_type != MIPS_R_RELHI - && int_rel.r_type != MIPS_R_RELLO))) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Adjust the contents. */ - if (relocation == 0) - r = bfd_reloc_ok; - else - { - if (int_rel.r_type != MIPS_R_REFHI - && int_rel.r_type != MIPS_R_RELHI) - r = _bfd_relocate_contents (howto, input_bfd, relocation, - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - else - { - mips_relocate_hi (&int_rel, &lo_int_rel, - input_bfd, input_section, contents, - adjust, relocation, - int_rel.r_type == MIPS_R_RELHI); - r = bfd_reloc_ok; - } - } - - /* Adjust the reloc address. */ - int_rel.r_vaddr += (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Save the changed reloc information. */ - mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel); - } - else - { - /* We are producing a final executable. */ - if (int_rel.r_extern) - { - /* This is a reloc against a symbol. */ - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - - hsec = h->root.u.def.section; - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - relocation = 0; - } - } - else - { - /* This is a reloc against a section. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - - /* A PC relative reloc is already correct in the object - file. Make it look like a pcrel_offset relocation by - adding in the start address. */ - if (howto->pc_relative) - { - if (int_rel.r_type != MIPS_R_RELHI) - relocation += int_rel.r_vaddr + adjust; - else - relocation += lo_int_rel.r_vaddr + adjust; - } - } - - if (int_rel.r_type != MIPS_R_REFHI - && int_rel.r_type != MIPS_R_RELHI) - r = _bfd_final_link_relocate (howto, - input_bfd, - input_section, - contents, - (int_rel.r_vaddr - - input_section->vma - + adjust), - relocation, - addend); - else - { - mips_relocate_hi (&int_rel, &lo_int_rel, input_bfd, - input_section, contents, adjust, - relocation, - int_rel.r_type == MIPS_R_RELHI); - r = bfd_reloc_ok; - } - } - - /* MIPS_R_JMPADDR requires peculiar overflow detection. The - instruction provides a 28 bit address (the two lower bits are - implicit zeroes) which is combined with the upper four bits - of the instruction address. */ - if (r == bfd_reloc_ok - && int_rel.r_type == MIPS_R_JMPADDR - && (((relocation - + addend - + (int_rel.r_extern ? 0 : s->vma)) - & 0xf0000000) - != ((input_section->output_section->vma - + input_section->output_offset - + (int_rel.r_vaddr - input_section->vma) - + adjust) - & 0xf0000000))) - r = bfd_reloc_overflow; - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (int_rel.r_extern) - name = h->root.root.string; - else - name = bfd_section_name (input_bfd, s); - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - } - break; - } - } - } - - return true; -} - -/* Read in the relocs for a section. */ - -static boolean -mips_read_relocs (abfd, sec) - bfd *abfd; - asection *sec; -{ - struct ecoff_section_tdata *section_tdata; - - section_tdata = ecoff_section_data (abfd, sec); - if (section_tdata == (struct ecoff_section_tdata *) NULL) - { - sec->used_by_bfd = - (PTR) bfd_alloc_by_size_t (abfd, sizeof (struct ecoff_section_tdata)); - if (sec->used_by_bfd == NULL) - return false; - - section_tdata = ecoff_section_data (abfd, sec); - section_tdata->external_relocs = NULL; - section_tdata->contents = NULL; - section_tdata->offsets = NULL; - } - - if (section_tdata->external_relocs == NULL) - { - bfd_size_type external_relocs_size; - - external_relocs_size = (ecoff_backend (abfd)->external_reloc_size - * sec->reloc_count); - - section_tdata->external_relocs = - (PTR) bfd_alloc (abfd, external_relocs_size); - if (section_tdata->external_relocs == NULL && external_relocs_size != 0) - return false; - - if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 - || (bfd_read (section_tdata->external_relocs, 1, - external_relocs_size, abfd) - != external_relocs_size)) - return false; - } - - return true; -} - -/* Relax a section when linking a MIPS ECOFF file. This is used for - embedded PIC code, which always uses PC relative branches which - only have an 18 bit range on MIPS. If a branch is not in range, we - generate a long instruction sequence to compensate. Each time we - find a branch to expand, we have to check all the others again to - make sure they are still in range. This is slow, but it only has - to be done when -relax is passed to the linker. - - This routine figures out which branches need to expand; the actual - expansion is done in mips_relocate_section when the section - contents are relocated. The information is stored in the offsets - field of the ecoff_section_tdata structure. An offset of 1 means - that the branch must be expanded into a multi-instruction PC - relative branch (such an offset will only occur for a PC relative - branch to an external symbol). Any other offset must be a multiple - of four, and is the amount to change the branch by (such an offset - will only occur for a PC relative branch within the same section). - - We do not modify the section relocs or contents themselves so that - if memory usage becomes an issue we can discard them and read them - again. The only information we must save in memory between this - routine and the mips_relocate_section routine is the table of - offsets. */ - -static boolean -mips_relax_section (abfd, sec, info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *info; - boolean *again; -{ - struct ecoff_section_tdata *section_tdata; - bfd_byte *contents = NULL; - long *offsets; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - unsigned int i; - - /* Assume we are not going to need another pass. */ - *again = false; - - /* If we are not generating an ECOFF file, this is much too - confusing to deal with. */ - if (info->hash->creator->flavour != bfd_get_flavour (abfd)) - return true; - - /* If there are no relocs, there is nothing to do. */ - if (sec->reloc_count == 0) - return true; - - /* We are only interested in PC relative relocs, and why would there - ever be one from anything but the .text section? */ - if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0) - return true; - - /* Read in the relocs, if we haven't already got them. */ - section_tdata = ecoff_section_data (abfd, sec); - if (section_tdata == (struct ecoff_section_tdata *) NULL - || section_tdata->external_relocs == NULL) - { - if (! mips_read_relocs (abfd, sec)) - goto error_return; - section_tdata = ecoff_section_data (abfd, sec); - } - - if (sec->_cooked_size == 0) - { - /* We must initialize _cooked_size only the first time we are - called. */ - sec->_cooked_size = sec->_raw_size; - } - - contents = section_tdata->contents; - offsets = section_tdata->offsets; - - /* Look for any external PC relative relocs. Internal PC relative - relocs are already correct in the object file, so they certainly - can not overflow. */ - ext_rel = (struct external_reloc *) section_tdata->external_relocs; - ext_rel_end = ext_rel + sec->reloc_count; - for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++) - { - struct internal_reloc int_rel; - struct ecoff_link_hash_entry *h; - asection *hsec; - bfd_signed_vma relocation; - struct external_reloc *adj_ext_rel; - unsigned int adj_i; - unsigned long ext_count; - struct ecoff_link_hash_entry **adj_h_ptr; - struct ecoff_link_hash_entry **adj_h_ptr_end; - struct ecoff_value_adjust *adjust; - - /* If we have already expanded this reloc, we certainly don't - need to do it again. */ - if (offsets != (long *) NULL && offsets[i] == 1) - continue; - - /* Quickly check that this reloc is external PCREL16. */ - if (bfd_header_big_endian (abfd)) - { - if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0 - || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG) - >> RELOC_BITS3_TYPE_SH_BIG) - != MIPS_R_PCREL16)) - continue; - } - else - { - if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0 - || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE) - >> RELOC_BITS3_TYPE_SH_LITTLE) - != MIPS_R_PCREL16)) - continue; - } - - mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel); - - h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx]; - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - { - /* Just ignore undefined symbols. These will presumably - generate an error later in the link. */ - continue; - } - - /* Get the value of the symbol. */ - hsec = h->root.u.def.section; - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - - /* Subtract out the current address. */ - relocation -= (sec->output_section->vma - + sec->output_offset - + (int_rel.r_vaddr - sec->vma)); - - /* The addend is stored in the object file. In the normal case - of ``bal symbol'', the addend will be -4. It will only be - different in the case of ``bal symbol+constant''. To avoid - always reading in the section contents, we don't check the - addend in the object file (we could easily check the contents - if we happen to have already read them in, but I fear that - this could be confusing). This means we will screw up if - there is a branch to a symbol that is in range, but added to - a constant which puts it out of range; in such a case the - link will fail with a reloc overflow error. Since the - compiler will never generate such code, it should be easy - enough to work around it by changing the assembly code in the - source file. */ - relocation -= 4; - - /* Now RELOCATION is the number we want to put in the object - file. See whether it fits. */ - if (relocation >= -0x20000 && relocation < 0x20000) - continue; - - /* Now that we know this reloc needs work, which will rarely - happen, go ahead and grab the section contents. */ - if (contents == (bfd_byte *) NULL) - { - if (info->keep_memory) - contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size); - else - contents = (bfd_byte *) bfd_malloc ((size_t) sec->_raw_size); - if (contents == (bfd_byte *) NULL) - goto error_return; - if (! bfd_get_section_contents (abfd, sec, (PTR) contents, - (file_ptr) 0, sec->_raw_size)) - goto error_return; - if (info->keep_memory) - section_tdata->contents = contents; - } - - /* We only support changing the bal instruction. It would be - possible to handle other PC relative branches, but some of - them (the conditional branches) would require a different - length instruction sequence which would complicate both this - routine and mips_relax_pcrel16. It could be written if - somebody felt it were important. Ignoring this reloc will - presumably cause a reloc overflow error later on. */ - if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma) - != 0x0411ffff) /* bgezal $0,. == bal . */ - continue; - - /* Bother. We need to expand this reloc, and we will need to - make another relaxation pass since this change may put other - relocs out of range. We need to examine the local branches - and we need to allocate memory to hold the offsets we must - add to them. We also need to adjust the values of all - symbols in the object file following this location. */ - - sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT; - *again = true; - - if (offsets == (long *) NULL) - { - size_t size; - - size = sec->reloc_count * sizeof (long); - offsets = (long *) bfd_alloc_by_size_t (abfd, size); - if (offsets == (long *) NULL) - goto error_return; - memset (offsets, 0, size); - section_tdata->offsets = offsets; - } - - offsets[i] = 1; - - /* Now look for all PC relative references that cross this reloc - and adjust their offsets. */ - adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs; - for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++) - { - struct internal_reloc adj_int_rel; - bfd_vma start, stop; - int change; - - mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel); - - if (adj_int_rel.r_type == MIPS_R_PCREL16) - { - unsigned long insn; - - /* We only care about local references. External ones - will be relocated correctly anyhow. */ - if (adj_int_rel.r_extern) - continue; - - /* We are only interested in a PC relative reloc within - this section. FIXME: Cross section PC relative - relocs may not be handled correctly; does anybody - care? */ - if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT) - continue; - - start = adj_int_rel.r_vaddr; - - insn = bfd_get_32 (abfd, - contents + adj_int_rel.r_vaddr - sec->vma); - - stop = (insn & 0xffff) << 2; - if ((stop & 0x20000) != 0) - stop -= 0x40000; - stop += adj_int_rel.r_vaddr + 4; - } - else if (adj_int_rel.r_type == MIPS_R_RELHI) - { - struct internal_reloc rello; - long addhi, addlo; - - /* The next reloc must be MIPS_R_RELLO, and we handle - them together. */ - BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end); - - mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello); - - BFD_ASSERT (rello.r_type == MIPS_R_RELLO); - - addhi = bfd_get_32 (abfd, - contents + adj_int_rel.r_vaddr - sec->vma); - addhi &= 0xffff; - if (addhi & 0x8000) - addhi -= 0x10000; - addhi <<= 16; - - addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma); - addlo &= 0xffff; - if (addlo & 0x8000) - addlo -= 0x10000; - - if (adj_int_rel.r_extern) - { - /* The value we want here is - sym - RELLOaddr + addend - which we can express as - sym - (RELLOaddr - addend) - Therefore if we are expanding the area between - RELLOaddr and RELLOaddr - addend we must adjust - the addend. This is admittedly ambiguous, since - we might mean (sym + addend) - RELLOaddr, but in - practice we don't, and there is no way to handle - that case correctly since at this point we have - no idea whether any reloc is being expanded - between sym and sym + addend. */ - start = rello.r_vaddr - (addhi + addlo); - stop = rello.r_vaddr; - } - else - { - /* An internal RELHI/RELLO pair represents the - difference between two addresses, $LC0 - foo. - The symndx value is actually the difference - between the reloc address and $LC0. This lets us - compute $LC0, and, by considering the addend, - foo. If the reloc we are expanding falls between - those two relocs, we must adjust the addend. At - this point, the symndx value is actually in the - r_offset field, where it was put by - mips_ecoff_swap_reloc_in. */ - start = rello.r_vaddr - adj_int_rel.r_offset; - stop = start + addhi + addlo; - } - } - else if (adj_int_rel.r_type == MIPS_R_SWITCH) - { - /* A MIPS_R_SWITCH reloc represents a word of the form - .word $L3-$LS12 - The value in the object file is correct, assuming the - original value of $L3. The symndx value is actually - the difference between the reloc address and $LS12. - This lets us compute the original value of $LS12 as - vaddr - symndx - and the original value of $L3 as - vaddr - symndx + addend - where addend is the value from the object file. At - this point, the symndx value is actually found in the - r_offset field, since it was moved by - mips_ecoff_swap_reloc_in. */ - start = adj_int_rel.r_vaddr - adj_int_rel.r_offset; - stop = start + bfd_get_32 (abfd, - (contents - + adj_int_rel.r_vaddr - - sec->vma)); - } - else - continue; - - /* If the range expressed by this reloc, which is the - distance between START and STOP crosses the reloc we are - expanding, we must adjust the offset. The sign of the - adjustment depends upon the direction in which the range - crosses the reloc being expanded. */ - if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr) - change = PCREL16_EXPANSION_ADJUSTMENT; - else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr) - change = - PCREL16_EXPANSION_ADJUSTMENT; - else - change = 0; - - offsets[adj_i] += change; - - if (adj_int_rel.r_type == MIPS_R_RELHI) - { - adj_ext_rel++; - adj_i++; - offsets[adj_i] += change; - } - } - - /* Find all symbols in this section defined by this object file - and adjust their values. Note that we decide whether to - adjust the value based on the value stored in the ECOFF EXTR - structure, because the value stored in the hash table may - have been changed by an earlier expanded reloc and thus may - no longer correctly indicate whether the symbol is before or - after the expanded reloc. */ - ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax; - adj_h_ptr = ecoff_data (abfd)->sym_hashes; - adj_h_ptr_end = adj_h_ptr + ext_count; - for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++) - { - struct ecoff_link_hash_entry *adj_h; - - adj_h = *adj_h_ptr; - if (adj_h != (struct ecoff_link_hash_entry *) NULL - && (adj_h->root.type == bfd_link_hash_defined - || adj_h->root.type == bfd_link_hash_defweak) - && adj_h->root.u.def.section == sec - && adj_h->esym.asym.value > int_rel.r_vaddr) - adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT; - } - - /* Add an entry to the symbol value adjust list. This is used - by bfd_ecoff_debug_accumulate to adjust the values of - internal symbols and FDR's. */ - adjust = ((struct ecoff_value_adjust *) - bfd_alloc (abfd, sizeof (struct ecoff_value_adjust))); - if (adjust == (struct ecoff_value_adjust *) NULL) - goto error_return; - - adjust->start = int_rel.r_vaddr; - adjust->end = sec->vma + sec->_raw_size; - adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT; - - adjust->next = ecoff_data (abfd)->debug_info.adjust; - ecoff_data (abfd)->debug_info.adjust = adjust; - } - - if (contents != (bfd_byte *) NULL && ! info->keep_memory) - free (contents); - - return true; - - error_return: - if (contents != (bfd_byte *) NULL && ! info->keep_memory) - free (contents); - return false; -} - -/* This routine is called from mips_relocate_section when a PC - relative reloc must be expanded into the five instruction sequence. - It handles all the details of the expansion, including resolving - the reloc. */ - -static boolean -mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address) - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - struct ecoff_link_hash_entry *h; - bfd_byte *location; - bfd_vma address; -{ - bfd_vma relocation; - - /* 0x0411ffff is bgezal $0,. == bal . */ - BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff); - - /* We need to compute the distance between the symbol and the - current address plus eight. */ - relocation = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - relocation -= address + 8; - - /* If the lower half is negative, increment the upper 16 half. */ - if ((relocation & 0x8000) != 0) - relocation += 0x10000; - - bfd_put_32 (input_bfd, 0x04110001, location); /* bal .+8 */ - bfd_put_32 (input_bfd, - 0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */ - location + 4); - bfd_put_32 (input_bfd, - 0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */ - location + 8); - bfd_put_32 (input_bfd, 0x003f0821, location + 12); /* addu $at,$at,$ra */ - bfd_put_32 (input_bfd, 0x0020f809, location + 16); /* jalr $at */ - - return true; -} - -/* Given a .sdata section and a .rel.sdata in-memory section, store - relocation information into the .rel.sdata section which can be - used at runtime to relocate the section. This is called by the - linker when the --embedded-relocs switch is used. This is called - after the add_symbols entry point has been called for all the - objects, and before the final_link entry point is called. This - function presumes that the object was compiled using - -membedded-pic. */ - -boolean -bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) - bfd *abfd; - struct bfd_link_info *info; - asection *datasec; - asection *relsec; - char **errmsg; -{ - struct ecoff_link_hash_entry **sym_hashes; - struct ecoff_section_tdata *section_tdata; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - bfd_byte *p; - - BFD_ASSERT (! info->relocateable); - - *errmsg = NULL; - - if (datasec->reloc_count == 0) - return true; - - sym_hashes = ecoff_data (abfd)->sym_hashes; - - if (! mips_read_relocs (abfd, datasec)) - return false; - - relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 4); - if (relsec->contents == NULL) - return false; - - p = relsec->contents; - - section_tdata = ecoff_section_data (abfd, datasec); - ext_rel = (struct external_reloc *) section_tdata->external_relocs; - ext_rel_end = ext_rel + datasec->reloc_count; - for (; ext_rel < ext_rel_end; ext_rel++, p += 4) - { - struct internal_reloc int_rel; - boolean text_relative; - - mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel); - - /* We are going to write a four byte word into the runtime reloc - section. The word will be the address in the data section - which must be relocated. This must be on a word boundary, - which means the lower two bits must be zero. We use the - least significant bit to indicate how the value in the data - section must be relocated. A 0 means that the value is - relative to the text section, while a 1 indicates that the - value is relative to the data section. Given that we are - assuming the code was compiled using -membedded-pic, there - should not be any other possibilities. */ - - /* We can only relocate REFWORD relocs at run time. */ - if (int_rel.r_type != MIPS_R_REFWORD) - { - *errmsg = "unsupported reloc type"; - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (int_rel.r_extern) - { - struct ecoff_link_hash_entry *h; - - h = sym_hashes[int_rel.r_symndx]; - /* If h is NULL, that means that there is a reloc against an - external symbol which we thought was just a debugging - symbol. This should not happen. */ - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && (h->root.u.def.section->flags & SEC_CODE) != 0) - text_relative = true; - else - text_relative = false; - } - else - { - switch (int_rel.r_symndx) - { - case RELOC_SECTION_TEXT: - text_relative = true; - break; - case RELOC_SECTION_SDATA: - case RELOC_SECTION_SBSS: - case RELOC_SECTION_LIT8: - text_relative = false; - break; - default: - /* No other sections should appear in -membedded-pic - code. */ - *errmsg = "reloc against unsupported section"; - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - if ((int_rel.r_offset & 3) != 0) - { - *errmsg = "reloc not properly aligned"; - bfd_set_error (bfd_error_bad_value); - return false; - } - - bfd_put_32 (abfd, - (int_rel.r_vaddr - datasec->vma + datasec->output_offset - + (text_relative ? 0 : 1)), - p); - } - - return true; -} - -/* This is the ECOFF backend structure. The backend field of the - target vector points to this. */ - -static const struct ecoff_backend_data mips_ecoff_backend_data = -{ - /* COFF backend structure. */ - { - (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */ - (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */ - mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out, - mips_ecoff_swap_scnhdr_out, - FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, - mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in, - mips_ecoff_swap_scnhdr_in, NULL, - mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, - _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, - _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }, - /* Supported architecture. */ - bfd_arch_mips, - /* Initial portion of armap string. */ - "__________", - /* The page boundary used to align sections in a demand-paged - executable file. E.g., 0x1000. */ - 0x1000, - /* True if the .rdata section is part of the text segment, as on the - Alpha. False if .rdata is part of the data segment, as on the - MIPS. */ - false, - /* Bitsize of constructor entries. */ - 32, - /* Reloc to use for constructor entries. */ - &mips_howto_table[MIPS_R_REFWORD], - { - /* Symbol table magic number. */ - magicSym, - /* Alignment of debugging information. E.g., 4. */ - 4, - /* Sizes of external symbolic information. */ - sizeof (struct hdr_ext), - sizeof (struct dnr_ext), - sizeof (struct pdr_ext), - sizeof (struct sym_ext), - sizeof (struct opt_ext), - sizeof (struct fdr_ext), - sizeof (struct rfd_ext), - sizeof (struct ext_ext), - /* Functions to swap in external symbolic data. */ - ecoff_swap_hdr_in, - ecoff_swap_dnr_in, - ecoff_swap_pdr_in, - ecoff_swap_sym_in, - ecoff_swap_opt_in, - ecoff_swap_fdr_in, - ecoff_swap_rfd_in, - ecoff_swap_ext_in, - _bfd_ecoff_swap_tir_in, - _bfd_ecoff_swap_rndx_in, - /* Functions to swap out external symbolic data. */ - ecoff_swap_hdr_out, - ecoff_swap_dnr_out, - ecoff_swap_pdr_out, - ecoff_swap_sym_out, - ecoff_swap_opt_out, - ecoff_swap_fdr_out, - ecoff_swap_rfd_out, - ecoff_swap_ext_out, - _bfd_ecoff_swap_tir_out, - _bfd_ecoff_swap_rndx_out, - /* Function to read in symbolic data. */ - _bfd_ecoff_slurp_symbolic_info - }, - /* External reloc size. */ - RELSZ, - /* Reloc swapping functions. */ - mips_ecoff_swap_reloc_in, - mips_ecoff_swap_reloc_out, - /* Backend reloc tweaking. */ - mips_adjust_reloc_in, - mips_adjust_reloc_out, - /* Relocate section contents while linking. */ - mips_relocate_section, - /* Do final adjustments to filehdr and aouthdr. */ - NULL, - /* Read an element from an archive at a given file position. */ - _bfd_get_elt_at_filepos -}; - -/* Looking up a reloc type is MIPS specific. */ -#define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup - -/* Getting relocated section contents is generic. */ -#define _bfd_ecoff_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents - -/* Handling file windows is generic. */ -#define _bfd_ecoff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Relaxing sections is MIPS specific. */ -#define _bfd_ecoff_bfd_relax_section mips_relax_section - -const bfd_target ecoff_little_vec = -{ - "ecoff-littlemips", /* name */ - bfd_target_ecoff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - _bfd_ecoff_archive_p, _bfd_dummy_target}, - {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), - BFD_JUMP_TABLE_COPY (_bfd_ecoff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff), - BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), - BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), - BFD_JUMP_TABLE_WRITE (_bfd_ecoff), - BFD_JUMP_TABLE_LINK (_bfd_ecoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) &mips_ecoff_backend_data -}; - -const bfd_target ecoff_big_vec = -{ - "ecoff-bigmips", /* name */ - bfd_target_ecoff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - _bfd_ecoff_archive_p, _bfd_dummy_target}, - {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), - BFD_JUMP_TABLE_COPY (_bfd_ecoff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff), - BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), - BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), - BFD_JUMP_TABLE_WRITE (_bfd_ecoff), - BFD_JUMP_TABLE_LINK (_bfd_ecoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) &mips_ecoff_backend_data -}; diff --git a/contrib/gdb/bfd/coff-pmac.c b/contrib/gdb/bfd/coff-pmac.c deleted file mode 100644 index f3332d98959..00000000000 --- a/contrib/gdb/bfd/coff-pmac.c +++ /dev/null @@ -1,27 +0,0 @@ -/* BFD back-end for Apple et al PowerPC Mac "XCOFF" files. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_SYM pmac_xcoff_vec -#define TARGET_NAME "xcoff-powermac" - -/* Tweak coffcode.h based on this being a PowerMac instead of RS/6000. */ - -#define POWERMAC - -#include "coff-rs6000.c" diff --git a/contrib/gdb/bfd/coff-ppc.c b/contrib/gdb/bfd/coff-ppc.c deleted file mode 100644 index 4caf3d8dc01..00000000000 --- a/contrib/gdb/bfd/coff-ppc.c +++ /dev/null @@ -1,3255 +0,0 @@ -/* BFD back-end for PowerPC Microsoft Portable Executable files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - - Original version pieced together by Kim Knuttila (krk@cygnus.com) - - There is nothing new under the sun. This file draws a lot on other - coff files, in particular, those for the rs/6000, alpha, mips, and - intel backends, and the PE work for the arm. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Current State: - - objdump works - - relocs generated by gas - - ld will link files, but they do not run. - - dlltool will not produce correct output in some .reloc cases, and will - not produce the right glue code for dll function calls. -*/ - - -#include "bfd.h" -#include "sysdep.h" - -#include "libbfd.h" -#include "obstack.h" - -#include "coff/powerpc.h" -#include "coff/internal.h" - -#include "coff/pe.h" - -#ifdef BADMAG -#undef BADMAG -#endif - -#define BADMAG(x) PPCBADMAG(x) - -#include "libcoff.h" - -/* The toc is a set of bfd_vma fields. We use the fact that valid */ -/* addresses are even (i.e. the bit representing "1" is off) to allow */ -/* us to encode a little extra information in the field */ -/* - Unallocated addresses are intialized to 1. */ -/* - Allocated addresses are even numbers. */ -/* The first time we actually write a reference to the toc in the bfd, */ -/* we want to record that fact in a fixup file (if it is asked for), so */ -/* we keep track of whether or not an address has been written by marking */ -/* the low order bit with a "1" upon writing */ - -#define SET_UNALLOCATED(x) ((x) = 1) -#define IS_UNALLOCATED(x) ((x) == 1) - -#define IS_WRITTEN(x) ((x) & 1) -#define MARK_AS_WRITTEN(x) ((x) |= 1) -#define MAKE_ADDR_AGAIN(x) ((x) &= ~1) - -/* In order not to add an int to every hash table item for every coff - linker, we define our own hash table, derived from the coff one */ - -/* PE linker hash table entries. */ - -struct ppc_coff_link_hash_entry -{ - struct coff_link_hash_entry root; /* First entry, as required */ - - /* As we wonder around the relocs, we'll keep the assigned toc_offset - here */ - bfd_vma toc_offset; /* Our addition, as required */ - int symbol_is_glue; - unsigned long int glue_insn; - char eye_catcher[8]; -}; - -/* Need a 7 char string for an eye catcher */ -#define EYE "krkjunk" - -#define CHECK_EYE(addr) \ - if (strcmp(addr, EYE) != 0) \ - { \ - fprintf(stderr,\ - "File %s, line %d, Hash check failure, bad eye %8s\n", \ - __FILE__, __LINE__, addr); \ - abort(); \ - } - -/* PE linker hash table. */ - -struct ppc_coff_link_hash_table -{ - struct coff_link_hash_table root; /* First entry, as required */ -}; - -static struct bfd_hash_entry *ppc_coff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); - -/* Routine to create an entry in the link hash table. */ - -static struct bfd_hash_entry * -ppc_coff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct ppc_coff_link_hash_entry *ret = - (struct ppc_coff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct ppc_coff_link_hash_entry *) NULL) - ret = (struct ppc_coff_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct ppc_coff_link_hash_entry)); - - if (ret == (struct ppc_coff_link_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct ppc_coff_link_hash_entry *) - _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - - if (ret) - { - /* Initialize the local fields. */ - SET_UNALLOCATED(ret->toc_offset); - ret->symbol_is_glue = 0; - ret->glue_insn = 0; - strcpy(ret->eye_catcher, EYE); - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a PE linker hash table. */ - -static boolean -ppc_coff_link_hash_table_init (table, abfd, newfunc) - struct ppc_coff_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc); -} - -/* Create a PE linker hash table. */ - -static struct bfd_link_hash_table * -ppc_coff_link_hash_table_create (abfd) - bfd *abfd; -{ - struct ppc_coff_link_hash_table *ret; - - ret = ((struct ppc_coff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct ppc_coff_link_hash_table))); - if (ret == NULL) - return NULL; - if (! ppc_coff_link_hash_table_init (ret, abfd, - ppc_coff_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root.root; -} - -/* Now, tailor coffcode.h to use our hash stuff */ - -#define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create - - -/* The nt loader points the toc register to &toc + 32768, in order to */ -/* use the complete range of a 16-bit displacement (I guess). We have */ -/* to adjust for this when we fix up loads displaced off the toc reg. */ -#define TOC_LOAD_ADJUSTMENT (-32768) -#define TOC_SECTION_NAME ".private.toc" - -/* The main body of code is in coffcode.h. */ - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -/* In case we're on a 32-bit machine, construct a 64-bit "-1" value - from smaller values. Start with zero, widen, *then* decrement. */ -#define MINUS_ONE (((bfd_vma)0) - 1) - -/* these should definitely go in a header file somewhere... */ - -/* NOP */ -#define IMAGE_REL_PPC_ABSOLUTE 0x0000 - -/* 64-bit address */ -#define IMAGE_REL_PPC_ADDR64 0x0001 - -/* 32-bit address */ -#define IMAGE_REL_PPC_ADDR32 0x0002 - -/* 26-bit address, shifted left 2 (branch absolute) */ -#define IMAGE_REL_PPC_ADDR24 0x0003 - -/* 16-bit address */ -#define IMAGE_REL_PPC_ADDR16 0x0004 - -/* 16-bit address, shifted left 2 (load doubleword) */ -#define IMAGE_REL_PPC_ADDR14 0x0005 - -/* 26-bit PC-relative offset, shifted left 2 (branch relative) */ -#define IMAGE_REL_PPC_REL24 0x0006 - -/* 16-bit PC-relative offset, shifted left 2 (br cond relative) */ -#define IMAGE_REL_PPC_REL14 0x0007 - -/* 16-bit offset from TOC base */ -#define IMAGE_REL_PPC_TOCREL16 0x0008 - -/* 16-bit offset from TOC base, shifted left 2 (load doubleword) */ -#define IMAGE_REL_PPC_TOCREL14 0x0009 - -/* 32-bit addr w/o image base */ -#define IMAGE_REL_PPC_ADDR32NB 0x000A - -/* va of containing section (as in an image sectionhdr) */ -#define IMAGE_REL_PPC_SECREL 0x000B - -/* sectionheader number */ -#define IMAGE_REL_PPC_SECTION 0x000C - -/* substitute TOC restore instruction iff symbol is glue code */ -#define IMAGE_REL_PPC_IFGLUE 0x000D - -/* symbol is glue code; virtual address is TOC restore instruction */ -#define IMAGE_REL_PPC_IMGLUE 0x000E - -/* va of containing section (limited to 16 bits) */ -#define IMAGE_REL_PPC_SECREL16 0x000F - -/* stuff to handle immediate data when the number of bits in the */ -/* data is greater than the number of bits in the immediate field */ -/* We need to do (usually) 32 bit arithmetic on 16 bit chunks */ -#define IMAGE_REL_PPC_REFHI 0x0010 -#define IMAGE_REL_PPC_REFLO 0x0011 -#define IMAGE_REL_PPC_PAIR 0x0012 - -/* This is essentially the same as tocrel16, with TOCDEFN assumed */ -#define IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 - -/* Flag bits in IMAGE_RELOCATION.TYPE */ - -/* subtract reloc value rather than adding it */ -#define IMAGE_REL_PPC_NEG 0x0100 - -/* fix branch prediction bit to predict branch taken */ -#define IMAGE_REL_PPC_BRTAKEN 0x0200 - -/* fix branch prediction bit to predict branch not taken */ -#define IMAGE_REL_PPC_BRNTAKEN 0x0400 - -/* toc slot defined in file (or, data in toc) */ -#define IMAGE_REL_PPC_TOCDEFN 0x0800 - -/* masks to isolate above values in IMAGE_RELOCATION.Type */ -#define IMAGE_REL_PPC_TYPEMASK 0x00FF -#define IMAGE_REL_PPC_FLAGMASK 0x0F00 - -#define EXTRACT_TYPE(x) ((x) & IMAGE_REL_PPC_TYPEMASK) -#define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK) -#define EXTRACT_JUNK(x) \ - ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK)) - - -/* static helper functions to make relocation work */ -/* (Work In Progress) */ - -static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - - -static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - - - -static boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto)); - - -/* FIXME: It'll take a while to get through all of these. I only need a few to - get us started, so those I'll make sure work. Those marked FIXME are either - completely unverified or have a specific unknown marked in the comment */ - -/*---------------------------------------------------------------------------*/ -/* */ -/* Relocation entries for Windows/NT on PowerPC. */ -/* */ -/* From the document "" we find the following listed as used relocs: */ -/* */ -/* ABSOLUTE : The noop */ -/* ADDR[64|32|16] : fields that hold addresses in data fields or the */ -/* 16 bit displacement field on a load/store. */ -/* ADDR[24|14] : fields that hold addresses in branch and cond */ -/* branches. These represent [26|16] bit addresses. */ -/* The low order 2 bits are preserved. */ -/* REL[24|14] : branches relative to the Instruction Address */ -/* register. These represent [26|16] bit addresses, */ -/* as before. The instruction field will be zero, and */ -/* the address of the SYM will be inserted at link time. */ -/* TOCREL16 : 16 bit displacement field referring to a slot in */ -/* toc. */ -/* TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14. */ -/* ADDR32NB : 32 bit address relative to the virtual origin. */ -/* (On the alpha, this is always a linker generated thunk)*/ -/* (i.e. 32bit addr relative to the image base) */ -/* SECREL : The value is relative to the start of the section */ -/* containing the symbol. */ -/* SECTION : access to the header containing the item. Supports the */ -/* codeview debugger. */ -/* */ -/* In particular, note that the document does not indicate that the */ -/* relocations listed in the header file are used. */ -/* */ -/* */ -/* */ -/*---------------------------------------------------------------------------*/ - -static reloc_howto_type ppc_coff_howto_table[] = -{ - /* IMAGE_REL_PPC_ABSOLUTE 0x0000 NOP */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* dont complain_on_overflow */ - 0, /* special_function */ - "ABSOLUTE", /* name */ - false, /* partial_inplace */ - 0x00, /* src_mask */ - 0x00, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR64 0x0001 64-bit address */ - /* Unused: */ - HOWTO(IMAGE_REL_PPC_ADDR64, /* type */ - 0, /* rightshift */ - 3, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR64", /* name */ - true, /* partial_inplace */ - MINUS_ONE, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR32 0x0002 32-bit address */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_ADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR24 0x0003 26-bit address, shifted left 2 (branch absolute) */ - /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */ - /* Of course, That's the IBM approved bit numbering, which is not what */ - /* anyone else uses.... The li field is in bit 2 thru 25 */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_ADDR24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR24", /* name */ - true, /* partial_inplace */ - 0x07fffffc, /* src_mask */ - 0x07fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR16 0x0004 16-bit address */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_ADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR14 0x0005 */ - /* 16-bit address, shifted left 2 (load doubleword) */ - /* FIXME: the mask is likely wrong, and the bit position may be as well */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ADDR14, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REL24 0x0006 */ - /* 26-bit PC-relative offset, shifted left 2 (branch relative) */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_REL24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "REL24", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REL14 0x0007 */ - /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */ - /* FIXME: the mask is likely wrong, and the bit position may be as well */ - /* FIXME: how does it know how far to shift? */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ADDR14, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_TOCREL16 0x0008 */ - /* 16-bit offset from TOC base */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - ppc_toc16_reloc, /* special_function */ - "TOCREL16", /* name */ - false, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_TOCREL14 0x0009 */ - /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "TOCREL14", /* name */ - false, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR32NB 0x000A */ - /* 32-bit addr w/ image base */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR32NB", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_SECREL 0x000B */ - /* va of containing section (as in an image sectionhdr) */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_SECREL,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_secrel_reloc, /* special_function */ - "SECREL", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_SECTION 0x000C */ - /* sectionheader number */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_SECTION,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_section_reloc, /* special_function */ - "SECTION", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_IFGLUE 0x000D */ - /* substitute TOC restore instruction iff symbol is glue code */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "IFGLUE", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_IMGLUE 0x000E */ - /* symbol is glue code; virtual address is TOC restore instruction */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - ppc_imglue_reloc, /* special_function */ - "IMGLUE", /* name */ - false, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_SECREL16 0x000F */ - /* va of containing section (limited to 16 bits) */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_SECREL16,/* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SECREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REFHI 0x0010 */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_REFHI, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_refhi_reloc, /* special_function */ - "REFHI", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REFLO 0x0011 */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_REFLO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_refhi_reloc, /* special_function */ - "REFLO", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_PAIR 0x0012 */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_PAIR, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_pair_reloc, /* special_function */ - "PAIR", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 */ - /* 16-bit offset from TOC base, without causing a definition */ - /* Used: */ - HOWTO ( (IMAGE_REL_PPC_TOCREL16 | IMAGE_REL_PPC_TOCDEFN), /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "TOCREL16, TOCDEFN", /* name */ - false, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - -}; - - - - -/* Some really cheezy macros that can be turned on to test stderr :-) */ - -#ifdef DEBUG_RELOC -#define UN_IMPL(x) \ -{ \ - static int i; \ - if (i == 0) \ - { \ - i = 1; \ - fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \ - } \ -} - -#define DUMP_RELOC(n,r) \ -{ \ - fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \ - n, (*(r->sym_ptr_ptr))->name, \ - r->address, r->addend); \ -} - -/* Given a reloc name, n, and a pointer to an internal_reloc, - dump out interesting information on the contents - -#define n_name _n._n_name -#define n_zeroes _n._n_n._n_zeroes -#define n_offset _n._n_n._n_offset - -*/ - -#define DUMP_RELOC2(n,r) \ -{ \ - fprintf(stderr,"%s sym %d, r_vaddr %d %s\n", \ - n, r->r_symndx, r->r_vaddr,\ - (((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \ - ?" ":" TOCDEFN" ); \ -} - -#else -#define UN_IMPL(x) -#define DUMP_RELOC(n,r) -#define DUMP_RELOC2(n,r) -#endif - - - -/* toc construction and management routines */ -extern bfd* bfd_of_toc_owner; -extern long int global_toc_size; - -extern long int import_table_size; -extern long int first_thunk_address; -extern long int thunk_size; - -enum toc_type -{ - default_toc, - toc_32, - toc_64 -}; - -enum ref_category -{ - priv, - pub, - data -}; - -struct list_ele -{ - struct list_ele *next; - bfd_vma addr; - enum ref_category cat; - int offset; - const char *name; -}; - -extern struct list_ele *head; -extern struct list_ele *tail; - -static void -record_toc(toc_section, our_toc_offset, cat, name) - asection *toc_section; - int our_toc_offset; - enum ref_category cat; - const char *name; -{ - /* add this entry to our toc addr-offset-name list */ - struct list_ele *t; - t = bfd_malloc (sizeof (struct list_ele)); - if (t == NULL) - abort (); - t->next = 0; - t->offset = our_toc_offset; - t->name = name; - t->cat = cat; - t->addr = toc_section->output_offset + our_toc_offset; - - if (head == 0) - { - head = t; - tail = t; - } - else - { - tail->next = t; - tail = t; - } -} - -/* record a toc offset against a symbol */ -static int -ppc_record_toc_entry(abfd, info, sec, sym, toc_kind) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - int sym; - enum toc_type toc_kind; -{ - bfd_byte *t; - bfd_byte *old_contents; - asection *s; - int element_size; - int data; - int offset; - struct ppc_coff_link_hash_entry *h; - struct coff_symbol_struct *target; - int ret_val; - const char *name; - - int *local_syms; - - h = 0; - - h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - if (h != 0) - { - CHECK_EYE(h->eye_catcher); - } - - if (h == 0) - { - local_syms = obj_coff_local_toc_table(abfd); - if (local_syms == 0) - { - int i; - /* allocate a table */ - local_syms = - (int *) bfd_zalloc (abfd, - obj_raw_syment_count(abfd) * sizeof(int)); - if (local_syms == 0) - return false; - obj_coff_local_toc_table(abfd) = local_syms; - for (i = 0; i < obj_raw_syment_count(abfd); ++i) - { - SET_UNALLOCATED(local_syms[i]); - } - } - - if (IS_UNALLOCATED(local_syms[sym])) - { - local_syms[sym] = global_toc_size; - ret_val = global_toc_size; - global_toc_size += 4; - - /* The size must fit in a 16bit displacment */ - if (global_toc_size >= 65535) - { - fprintf(stderr, - "Exceeded toc size of 65535\n"); - abort(); - } - -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting toc_offset for local sym %d to %d\n", - sym, ret_val); -#endif - } - else - { - ret_val = local_syms[sym]; -#ifdef TOC_DEBUG - fprintf(stderr, - "toc_offset already set for local sym %d to %d\n", - sym, ret_val); -#endif - } - } - else - { - name = h->root.root.root.string; - - /* check to see if there's a toc slot allocated. If not, do it - here. It will be used in relocate_section */ - if (IS_UNALLOCATED(h->toc_offset)) - { - h->toc_offset = global_toc_size; - ret_val = global_toc_size; - global_toc_size += 4; - - /* The size must fit in a 16bit displacment */ - if (global_toc_size >= 65535) - { - fprintf(stderr, - "Exceeded toc size of 65535\n"); - abort(); - } - -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting toc_offset for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - else - { - ret_val = h->toc_offset; -#ifdef TOC_DEBUG - fprintf(stderr, - "toc_offset already set for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - } - - return ret_val; -} -/* FIXME: record a toc offset against a data-in-toc symbol */ -/* Now, there is currenly some confusion on what this means. In some - compilers one sees the moral equivalent of: - .tocd - define some data - .text - refer to the data with a [tocv] qualifier - In general, one sees something to indicate that a tocd has been - seen, and that would trigger the allocation of data in toc. The IBM - docs seem to suggest that anything with the TOCDEFN qualifier should - never trigger storage allocation. However, in the kernel32.lib that - we've been using for our test bed, there are a couple of variables - referenced that fail that test. - - So it can't work that way. -*/ -static int -ppc_record_data_in_toc_entry(abfd, info, sec, sym, toc_kind) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - int sym; - enum toc_type toc_kind; -{ - bfd_byte *t; - bfd_byte *old_contents; - asection *s; - int element_size; - int data; - int offset; - struct ppc_coff_link_hash_entry *h = 0; - struct coff_symbol_struct *target; - int ret_val; - const char *name; - - int *local_syms; - - h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - - if (h == 0) - { - local_syms = obj_coff_local_toc_table(abfd); - if (local_syms == 0) - { - int i; - /* allocate a table */ - local_syms = - (int *) bfd_zalloc (abfd, - obj_raw_syment_count(abfd) * sizeof(int)); - if (local_syms == 0) - return false; - obj_coff_local_toc_table(abfd) = local_syms; - for (i = 0; i < obj_raw_syment_count(abfd); ++i) - { - SET_UNALLOCATED(local_syms[i]); - } - } - - if (IS_UNALLOCATED(local_syms[sym])) - { - local_syms[sym] = global_toc_size; - ret_val = global_toc_size; - global_toc_size += 4; -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting data_in_toc_offset for local sym %d to %d\n", - sym, ret_val); -#endif - } - else - { - ret_val = local_syms[sym]; -#ifdef TOC_DEBUG - fprintf(stderr, - "data_in_toc_offset already set for local sym %d to %d\n", - sym, ret_val); -#endif - } - } - else - { - CHECK_EYE(h->eye_catcher); - - name = h->root.root.root.string; - - /* check to see if there's a toc slot allocated. If not, do it - here. It will be used in relocate_section */ - if (IS_UNALLOCATED(h->toc_offset)) - { -#if 0 - h->toc_offset = global_toc_size; -#endif - ret_val = global_toc_size; - /* We're allocating a chunk of the toc, as opposed to a slot */ - /* FIXME: alignment? */ - - global_toc_size += 4; -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting data_in_toc_offset for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - else - { - ret_val = h->toc_offset; -#ifdef TOC_DEBUG - fprintf(stderr, - "data_in_toc_offset already set for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - } - - return ret_val; -} - -/* record a toc offset against a symbol */ -static void -ppc_mark_symbol_as_glue(abfd, sym, rel) - bfd *abfd; - int sym; - struct internal_reloc *rel; -{ - struct ppc_coff_link_hash_entry *h; - - h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - - CHECK_EYE(h->eye_catcher); - - h->symbol_is_glue = 1; - h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr); - - return; -} - - -/* Provided the symbol, returns the value reffed */ -static long get_symbol_value PARAMS ((asymbol *)); - -static long -get_symbol_value (symbol) - asymbol *symbol; -{ - long relocation = 0; - - if (bfd_is_com_section (symbol->section)) - { - relocation = 0; - } - else - { - relocation = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; - } - - return(relocation); -} - -/* Return true if this relocation should - appear in the output .reloc section. */ - -static boolean in_reloc_p(abfd, howto) - bfd * abfd; - reloc_howto_type *howto; -{ - return - (! howto->pc_relative) - && (howto->type != IMAGE_REL_PPC_ADDR32NB) - && (howto->type != IMAGE_REL_PPC_TOCREL16) - && (howto->type != IMAGE_REL_PPC_IMGLUE) - && (howto->type != IMAGE_REL_PPC_IFGLUE) - && (howto->type != IMAGE_REL_PPC_SECREL) - && (howto->type != IMAGE_REL_PPC_SECTION) - && (howto->type != IMAGE_REL_PPC_SECREL16) - && (howto->type != IMAGE_REL_PPC_REFHI) - && (howto->type != IMAGE_REL_PPC_REFLO) - && (howto->type != IMAGE_REL_PPC_PAIR) - && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ; -} - -/* this function is in charge of performing all the ppc PE relocations */ -/* Don't yet know if we want to do this this particular way ... (krk) */ -/* FIXME: (it is not yet enabled) */ - -static bfd_reloc_status_type -pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* the consth relocation comes in two parts, we have to remember - the state between calls, in these variables */ - static boolean part1_consth_active = false; - static unsigned long part1_consth_value; - - unsigned long insn; - unsigned long sym_value; - unsigned long unsigned_value; - unsigned short r_type; - long signed_value; - - unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/ - bfd_byte *hit_data =addr + (bfd_byte *)(data); - - fprintf(stderr, "pe_ppc_reloc (%s)\n", TARGET_LITTLE_NAME); - - r_type = reloc_entry->howto->type; - - if (output_bfd) - { - /* Partial linking - do nothing */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - { - /* Keep the state machine happy in case we're called again */ - if (r_type == IMAGE_REL_PPC_REFHI) - { - part1_consth_active = true; - part1_consth_value = 0; - } - return(bfd_reloc_undefined); - } - - if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR)) - { - part1_consth_active = false; - *error_message = (char *) "Missing PAIR"; - return(bfd_reloc_dangerous); - } - - - sym_value = get_symbol_value(symbol_in); - - return(bfd_reloc_ok); -} - -/* The reloc processing routine for the optimized COFF linker. */ - -static boolean -coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - boolean hihalf; - bfd_vma hihalf_val; - asection *toc_section = 0; - bfd_vma relocation; - reloc_howto_type *howto = 0; - -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - - /* If we are performing a relocateable link, we don't need to do a - thing. The caller will take care of adjusting the reloc - addresses and symbol indices. */ - if (info->relocateable) - return true; - - hihalf = false; - hihalf_val = 0; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct ppc_coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma val; - - asection *sec; - bfd_reloc_status_type rstat; - bfd_byte *loc; - - unsigned short r_type = EXTRACT_TYPE (rel->r_type); - unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - symndx = rel->r_symndx; - loc = contents + rel->r_vaddr - input_section->vma; - - /* FIXME: check bounds on r_type */ - howto = ppc_coff_howto_table + r_type; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = (struct ppc_coff_link_hash_entry *) - (obj_coff_sym_hashes (input_bfd)[symndx]); - if (h != 0) - { - CHECK_EYE(h->eye_catcher); - } - - sym = syms + symndx; - } - - sec = NULL; - val = 0; - - /* FIXME: PAIR unsupported in the following code */ - if (h == NULL) - { - if (symndx == -1) - sec = bfd_abs_section_ptr; - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - CHECK_EYE(h->eye_catcher); - - if (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - { - sec = h->root.root.u.def.section; - val = (h->root.root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else - { -fprintf(stderr, - "missing %s\n",h->root.root.root.string); - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - rstat = bfd_reloc_ok; - - /* Each case must do its own relocation, setting rstat appropriately */ - switch (r_type) - { - default: - fprintf( stderr, - "ERROR: during reloc processing -- unsupported reloc %s\n", - howto->name); - bfd_set_error (bfd_error_bad_value); - abort(); - return false; - case IMAGE_REL_PPC_TOCREL16: - { - bfd_vma our_toc_offset; - int fixit; - - DUMP_RELOC2(howto->name, rel); - - if (toc_section == 0) - { - toc_section = bfd_get_section_by_name (bfd_of_toc_owner, - TOC_SECTION_NAME); -#ifdef TOC_DEBUG - - fprintf(stderr, - "BFD of toc owner %p (%s), section addr of %s %p\n", - bfd_of_toc_owner, bfd_of_toc_owner->filename, - TOC_SECTION_NAME, toc_section); -#endif - - if ( toc_section == NULL ) - { - fprintf(stderr, "No Toc section!\n"); - abort(); - } - } - - /* - * Amazing bit tricks present. As we may have seen earlier, we - * use the 1 bit to tell us whether or not a toc offset has been - * allocated. Now that they've all been allocated, we will use - * the 1 bit to tell us if we've written this particular toc - * entry out. - */ - fixit = false; - if (h == 0) - { /* it is a file local symbol */ - int *local_toc_table; - const char *name; - - sym = syms + symndx; - name = sym->_n._n_name; - - local_toc_table = obj_coff_local_toc_table(input_bfd); - our_toc_offset = local_toc_table[symndx]; - - if (IS_WRITTEN(our_toc_offset)) - { - /* if it has been written out, it is marked with the - 1 bit. Fix up our offset, but do not write it out - again. - */ - MAKE_ADDR_AGAIN(our_toc_offset); -#ifdef TOC_DEBUG - - fprintf(stderr, - "Not writing out toc_offset of %d for %s\n", - our_toc_offset, name); -#endif - } - else - { - /* write out the toc entry */ - record_toc(toc_section, our_toc_offset, priv, strdup(name)); -#ifdef TOC_DEBUG - fprintf(stderr, - "Writing out toc_offset " - "toc_section (%p,%p)+%d val %d for %s\n", - toc_section, - toc_section->contents, - our_toc_offset, - val, - name); -#endif - - bfd_put_32(output_bfd, - val, - toc_section->contents + our_toc_offset); - - MARK_AS_WRITTEN(local_toc_table[symndx]); - fixit = true; - } - } - else - { - const char *name = h->root.root.root.string; - our_toc_offset = h->toc_offset; - - if ((r_flags & IMAGE_REL_PPC_TOCDEFN) - == IMAGE_REL_PPC_TOCDEFN ) -#if 0 - /* This is wrong. If tocdefn is on, we must unconditionally - assume the following path */ - && IS_UNALLOCATED(our_toc_offset)) -#endif - { - /* This is unbelievable cheese. Some knowledgable asm - hacker has decided to use r2 as a base for loading - a value. He/She does this by setting the tocdefn bit, - and not supplying a toc definition. The behaviour is - then to use the difference between the value of the - symbol and the actual location of the toc as the toc - index. - - In fact, what is usually happening is, because the - Import Address Table is mapped immediately following - the toc, some trippy library code trying for speed on - dll linkage, takes advantage of that and considers - the IAT to be part of the toc, thus saving a load. - */ -#ifdef DEBUG_RELOC - fprintf(stderr, - "TOCDEFN is on, (%s) (%p) our_toc_offset = %x\n", - name, h, our_toc_offset); -#endif - - our_toc_offset = val - - (toc_section->output_section->vma + - toc_section->output_offset); - -#ifdef DEBUG_RELOC - fprintf(stderr, - " our_toc_offset set to %x\n", our_toc_offset); -#endif - - /* The size must still fit in a 16bit displacment */ - if (our_toc_offset >= 65535) - { - fprintf(stderr, - "TOCDEFN Relocation exceeded " - "displacment of 65535\n"); - abort(); - } - - record_toc(toc_section, our_toc_offset, pub, strdup(name)); - } - else if (IS_WRITTEN(our_toc_offset)) - { - /* if it has been written out, it is marked with the - 1 bit. Fix up our offset, but do not write it out - again. - */ - MAKE_ADDR_AGAIN(our_toc_offset); -#ifdef TOC_DEBUG - fprintf(stderr, - "Not writing out toc_offset of %d for %s\n", - our_toc_offset, name); -#endif - } - else - { - record_toc(toc_section, our_toc_offset, pub, strdup(name)); - -#ifdef TOC_DEBUG - /* write out the toc entry */ - fprintf(stderr, - "Writing out toc_offset " - "toc_section (%p,%p)+%d val %d for %s\n", - toc_section, - toc_section->contents, - our_toc_offset, - val, - name); -#endif - - /* write out the toc entry */ - bfd_put_32(output_bfd, - val, - toc_section->contents + our_toc_offset); - - MARK_AS_WRITTEN(h->toc_offset); - /* The tricky part is that this is the address that */ - /* needs a .reloc entry for it */ - fixit = true; - } - } - - if (fixit && info->base_file) - { - /* So if this is non pcrelative, and is referenced - to a section or a common symbol, then it needs a reloc */ - - /* relocation to a symbol in a section which - isn't absolute - we output the address here - to a file */ - - bfd_vma addr = toc_section->output_section->vma - + toc_section->output_offset + our_toc_offset; - - if (coff_data(output_bfd)->pe) - addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; - -#ifdef DEBUG_RELOC - fprintf(stderr, - " Toc Section .reloc candidate addr = %x\n", addr); -#endif - fwrite (&addr, 1,4, (FILE *) info->base_file); - } - - - /* FIXME: this test is conservative */ - if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN && - our_toc_offset > toc_section->_raw_size) - { - fprintf(stderr, - "reloc offset is bigger than the toc size!\n"); - abort(); - } - - /* Now we know the relocation for this toc reference */ - relocation = our_toc_offset + TOC_LOAD_ADJUSTMENT; - rstat = _bfd_relocate_contents (howto, - input_bfd, - relocation, - loc); - } - break; - case IMAGE_REL_PPC_IFGLUE: - { - /* To solve this, we need to know whether or not the symbol */ - /* appearing on the call instruction is a glue function or not. */ - /* A glue function must announce itself via a IMGLUE reloc, and */ - /* the reloc contains the required toc restore instruction */ - - bfd_vma x; - const char *my_name; - DUMP_RELOC2(howto->name, rel); - - if (h != 0) - { - my_name = h->root.root.root.string; - if (h->symbol_is_glue == 1) - { - x = bfd_get_32(input_bfd, loc); - bfd_put_32(input_bfd, h->glue_insn, loc); - } - } - } - break; - case IMAGE_REL_PPC_SECREL: - /* Unimplemented: codeview debugging information */ - /* For fast access to the header of the section - containing the item. */ - break; - case IMAGE_REL_PPC_SECTION: - /* Unimplemented: codeview debugging information */ - /* Is used to indicate that the value should be relative - to the beginning of the section that contains the - symbol */ - break; - case IMAGE_REL_PPC_ABSOLUTE: - { - const char *my_name; - if (h == 0) - my_name = (syms+symndx)->_n._n_name; - else - { - my_name = h->root.root.root.string; - } - - fprintf(stderr, - "Warning: unsupported reloc %s \n", - howto->name, - bfd_get_filename(input_bfd), - input_section->name); - - fprintf(stderr,"sym %d (%s), r_vaddr %d (%x)\n", - rel->r_symndx, my_name, rel->r_vaddr, rel->r_vaddr); - } - break; - case IMAGE_REL_PPC_IMGLUE: - { - /* There is nothing to do now. This reloc was noted in the first - pass over the relocs, and the glue instruction extracted */ - const char *my_name; - if (h->symbol_is_glue == 1) - break; - my_name = h->root.root.root.string; - fprintf(stderr, - "Warning: previously missed IMGLUE reloc %s \n", - howto->name, - bfd_get_filename(input_bfd), - input_section->name); - break; - - } - break; - - case IMAGE_REL_PPC_ADDR32NB: - { - struct coff_link_hash_entry *myh = 0; - const char *name = 0; - DUMP_RELOC2(howto->name, rel); - - if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0) - { - /* set magic values */ - int idata5offset; - struct coff_link_hash_entry *myh = 0; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata5_magic__", - false, false, true); - first_thunk_address = myh->root.u.def.value + - sec->output_section->vma + - sec->output_offset - - pe_data(output_bfd)->pe_opthdr.ImageBase; - - idata5offset = myh->root.u.def.value; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata6_magic__", - false, false, true); - - thunk_size = myh->root.u.def.value - idata5offset; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata4_magic__", - false, false, true); - import_table_size = myh->root.u.def.value; -#ifdef DEBUG_RELOC - fprintf(stderr, - "first computation triggered fta %x, ts %d(%x), its %d(%x)\n", - first_thunk_address, thunk_size, thunk_size, import_table_size, - import_table_size); -#endif - } - - if (h == 0) - { /* it is a file local symbol */ - sym = syms + symndx; - name = sym->_n._n_name; - } - else - { - char *target = 0; - - name = h->root.root.root.string; - if (strcmp(".idata$2", name) == 0) - target = "__idata2_magic__"; - else if (strcmp(".idata$4", name) == 0) - target = "__idata4_magic__"; - else if (strcmp(".idata$5", name) == 0) - target = "__idata5_magic__"; - - if (target != 0) - { - myh = 0; - - myh = coff_link_hash_lookup (coff_hash_table (info), - target, - false, false, true); - if (myh == 0) - { - fprintf(stderr, "Missing idata magic cookies, " - "this cannot work anyway...\n"); - abort(); - } - - val = myh->root.u.def.value + - sec->output_section->vma + sec->output_offset; - if (first_thunk_address == 0) - { - int idata5offset; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata5_magic__", - false, false, true); - first_thunk_address = myh->root.u.def.value + - sec->output_section->vma + - sec->output_offset - - pe_data(output_bfd)->pe_opthdr.ImageBase; - - idata5offset = myh->root.u.def.value; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata6_magic__", - false, false, true); - - thunk_size = myh->root.u.def.value - idata5offset; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata4_magic__", - false, false, true); - import_table_size = myh->root.u.def.value; -#ifdef DEBUG_RELOC - - fprintf(stderr, - "second computation triggered fta %x, ts %d(%x), its %d(%x)\n", - first_thunk_address, thunk_size, thunk_size, import_table_size, - import_table_size); -#endif - } - } - } - - rstat = _bfd_relocate_contents (howto, - input_bfd, - val - - pe_data(output_bfd)->pe_opthdr.ImageBase, - loc); - } - break; - - case IMAGE_REL_PPC_REL24: - DUMP_RELOC2(howto->name, rel); - val -= (input_section->output_section->vma - + input_section->output_offset); - - rstat = _bfd_relocate_contents (howto, - input_bfd, - val, - loc); - break; - case IMAGE_REL_PPC_ADDR16: - case IMAGE_REL_PPC_ADDR24: - case IMAGE_REL_PPC_ADDR32: - DUMP_RELOC2(howto->name, rel); - rstat = _bfd_relocate_contents (howto, - input_bfd, - val, - loc); - break; - } - - if ( info->base_file ) - { - /* So if this is non pcrelative, and is referenced - to a section or a common symbol, then it needs a reloc */ - if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)) - { - /* relocation to a symbol in a section which - isn't absolute - we output the address here - to a file */ - bfd_vma addr = rel->r_vaddr - - input_section->vma - + input_section->output_offset - + input_section->output_section->vma; - - if (coff_data(output_bfd)->pe) - { - bfd_vma before_addr = addr; - addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; -#ifdef DEBUG_RELOC - fprintf(stderr, - " adjusted down from %x to %x", before_addr, addr); -#endif - } -#ifdef DEBUG_RELOC - fprintf(stderr, "\n"); -#endif - - fwrite (&addr, 1,4, (FILE *) info->base_file); - } - } - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.root.string; - else if (sym == NULL) - name = "*unknown*"; - else if (sym->_n._n_n._n_zeroes == 0 - && sym->_n._n_n._n_offset != 0) - name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; - else - { - strncpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - name = buf; - } -#if 0 - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } -#endif - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, - (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - { -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - return false; - } - } - } - - } - -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - - return true; -} - - -#ifdef COFF_IMAGE_WITH_PE - -long int global_toc_size = 4; - -bfd* bfd_of_toc_owner = 0; - -long int import_table_size; -long int first_thunk_address; -long int thunk_size; - -struct list_ele *head; -struct list_ele *tail; - -static char * -h1 = "\n\t\t\tTOC MAPPING\n\n"; -static char * -h2 = " TOC disassembly Comments Name\n"; -static char * -h3 = " Offset spelling (if present)\n"; - -void -dump_toc(vfile) - void *vfile; -{ - FILE *file = vfile; - struct list_ele *t; - - fprintf(file, h1); - fprintf(file, h2); - fprintf(file, h3); - - for(t = head; t != 0; t=t->next) - { - char *cat; - - if (t->cat == priv) - cat = "private "; - else if (t->cat == pub) - cat = "public "; - else if (t->cat == data) - cat = "data-in-toc "; - - if (t->offset > global_toc_size) - { - if (t->offset <= global_toc_size + thunk_size) - cat = "IAT reference "; - else - { - fprintf(file, - "**** global_toc_size %d(%x), thunk_size %d(%x)\n", - global_toc_size, global_toc_size, thunk_size, thunk_size); - cat = "Out of bounds!"; - } - } - - fprintf(file, - " %04lx (%d)", t->offset, t->offset - 32768); - fprintf(file, - " %s %s\n", - cat, t->name); - - } - - fprintf(file, "\n"); -} - -boolean -ppc_allocate_toc_section (info) - struct bfd_link_info *info; -{ - asection *s; - bfd_byte *foo; - static char test_char = '1'; - - if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */ - return true; - - if (bfd_of_toc_owner == 0) - { - fprintf(stderr, - "There is no bfd that owns the toc section!\n"); - abort(); - } - - s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME); - if (s == NULL) - { - fprintf(stderr, "No Toc section!\n"); - abort(); - } - - foo = bfd_alloc(bfd_of_toc_owner, global_toc_size); - memset(foo, test_char, global_toc_size); - - s->_raw_size = s->_cooked_size = global_toc_size; - s->contents = foo; - - return true; -} - -boolean -ppc_process_before_allocation (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - asection *sec; - struct internal_reloc *i, *rel; - -#ifdef DEBUG_RELOC - fprintf(stderr, - "ppc_process_before_allocation: BFD %s\n", - bfd_get_filename(abfd)); -#endif - - /* here we have a bfd that is to be included on the link. We have a hook - to do reloc rummaging, before section sizes are nailed down. */ - - _bfd_coff_get_external_symbols(abfd); - - /* rummage around all the relocs and map the toc */ - sec = abfd->sections; - - if (sec == 0) - { - return true; - } - - for (; sec != 0; sec = sec->next) - { - int toc_offset; - -#ifdef DEBUG_RELOC - fprintf(stderr, - " section %s reloc count %d\n", - sec->name, - sec->reloc_count); -#endif - - if (sec->reloc_count == 0) - continue; - - /* load the relocs */ - /* FIXME: there may be a storage leak here */ - i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0); - - if (i == 0) - abort(); - - for (rel=i;relreloc_count;++rel) - { - unsigned short r_type = EXTRACT_TYPE (rel->r_type); - unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - - switch(r_type) - { - case IMAGE_REL_PPC_TOCREL16: -#if 0 - /* FIXME: - This remains unimplemented for now, as it currently adds - un-necessary elements to the toc. All we need to do today - is not do anything if TOCDEFN is on. - */ - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - toc_offset = ppc_record_data_in_toc_entry(abfd, info, sec, - rel->r_symndx, - default_toc); - else - toc_offset = ppc_record_toc_entry(abfd, info, sec, - rel->r_symndx, default_toc); -#endif - if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN ) - toc_offset = ppc_record_toc_entry(abfd, info, sec, - rel->r_symndx, default_toc); - break; - case IMAGE_REL_PPC_IMGLUE: - ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel); - break; - default: - break; - } - } - } -} - -#endif - - -static bfd_reloc_status_type -ppc_refhi_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("REFHI"); - DUMP_RELOC("REFHI",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_undefined; -} - -static bfd_reloc_status_type -ppc_reflo_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("REFLO"); - DUMP_RELOC("REFLO",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_undefined; -} - -static bfd_reloc_status_type -ppc_pair_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("PAIR"); - DUMP_RELOC("PAIR",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_undefined; -} - - -static bfd_reloc_status_type -ppc_toc16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("TOCREL16"); - DUMP_RELOC("TOCREL16",reloc_entry); - - if (output_bfd == (bfd *) NULL) - { - return bfd_reloc_continue; - } - - return bfd_reloc_ok; -} - -/* ADDR32NB : 32 bit address relative to the virtual origin. */ -/* (On the alpha, this is always a linker generated thunk)*/ -/* (i.e. 32bit addr relative to the image base) */ -/* */ -/* */ - -static bfd_reloc_status_type -ppc_addr32nb_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("ADDR32NB"); - DUMP_RELOC("ADDR32NB",reloc_entry); - - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -ppc_secrel_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("SECREL"); - DUMP_RELOC("SECREL",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -ppc_section_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("SECTION"); - DUMP_RELOC("SECTION",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -ppc_imglue_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("IMGLUE"); - DUMP_RELOC("IMGLUE",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - - - -#define MAX_RELOC_INDEX \ - (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1) - - -/* FIXME: There is a possiblity that when we read in a reloc from a file, - that there are some bits encoded in the upper portion of the - type field. Not yet implemented. -*/ -static void ppc_coff_rtype2howto PARAMS ((arelent *relent, - struct internal_reloc *internal)); - -static void -ppc_coff_rtype2howto (relent, internal) - arelent *relent; - struct internal_reloc *internal; -{ - - /* We can encode one of three things in the type field, aside from the - type: - 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction - value, rather than an addition value - 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that - the branch is expected to be taken or not. - 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file - For now, we just strip this stuff to find the type, and ignore it other - than that. - */ - reloc_howto_type *howto; - unsigned short r_type = EXTRACT_TYPE (internal->r_type); - unsigned short r_flags = EXTRACT_FLAGS(internal->r_type); - unsigned short junk = EXTRACT_JUNK (internal->r_type); - - /* the masking process only slices off the bottom byte for r_type. */ - if ( r_type > MAX_RELOC_INDEX ) - { - fprintf(stderr, - "ppc_coff_rtype2howto: reloc index %d out of range [%d, %d]\n", - internal->r_type, 0, MAX_RELOC_INDEX); - abort(); - } - - /* check for absolute crap */ - if ( junk != 0 ) - { - fprintf(stderr, - "ppc_coff_rtype2howto: reloc index %d contains junk %d\n", - internal->r_type, junk); - abort(); - } - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - switch(r_type) - { - case IMAGE_REL_PPC_ADDR16: - case IMAGE_REL_PPC_REL24: - case IMAGE_REL_PPC_ADDR24: - case IMAGE_REL_PPC_ADDR32: - case IMAGE_REL_PPC_IFGLUE: - case IMAGE_REL_PPC_ADDR32NB: - case IMAGE_REL_PPC_SECTION: - case IMAGE_REL_PPC_SECREL: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal); - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_IMGLUE: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal); - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_TOCREL16: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal); - if (r_flags & IMAGE_REL_PPC_TOCDEFN) - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN; - else - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16; - break; - default: - fprintf(stderr, - "Warning: Unsupported reloc %s [%d] used -- it may not work.\n", - ppc_coff_howto_table[r_type].name, - r_type); - howto = ppc_coff_howto_table + r_type; - break; - } - - relent->howto = howto; - -} - -static reloc_howto_type * -coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - reloc_howto_type *howto; - - /* We can encode one of three things in the type field, aside from the - type: - 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction - value, rather than an addition value - 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that - the branch is expected to be taken or not. - 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file - For now, we just strip this stuff to find the type, and ignore it other - than that. - */ - - unsigned short r_type = EXTRACT_TYPE (rel->r_type); - unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); - - /* the masking process only slices off the bottom byte for r_type. */ - if ( r_type > MAX_RELOC_INDEX ) - { - fprintf(stderr, - "coff_ppc_rtype_to_howto: index %d out of range [%d, %d]\n", - r_type, 0, MAX_RELOC_INDEX); - abort(); - } - - /* check for absolute crap */ - if ( junk != 0 ) - { - fprintf(stderr, - "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n", - rel->r_type, junk); - abort(); - } - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - switch(r_type) - { - case IMAGE_REL_PPC_ADDR32NB: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_TOCREL16: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - if (r_flags & IMAGE_REL_PPC_TOCDEFN) - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN; - else - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16; - break; - case IMAGE_REL_PPC_ADDR16: - case IMAGE_REL_PPC_REL24: - case IMAGE_REL_PPC_ADDR24: - case IMAGE_REL_PPC_ADDR32: - case IMAGE_REL_PPC_IFGLUE: - case IMAGE_REL_PPC_SECTION: - case IMAGE_REL_PPC_SECREL: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_IMGLUE: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - howto = ppc_coff_howto_table + r_type; - break; - default: - fprintf(stderr, - "Warning: Unsupported reloc %s [%d] used -- it may not work.\n", - ppc_coff_howto_table[r_type].name, - r_type); - howto = ppc_coff_howto_table + r_type; - break; - } - - return howto; -} - - -/* a cheesy little macro to make the code a little more readable */ -#define HOW2MAP(bfd_rtype,ppc_rtype) \ - case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype] - -static reloc_howto_type *ppc_coff_reloc_type_lookup -PARAMS ((bfd *, bfd_reloc_code_real_type)); - -static reloc_howto_type * -ppc_coff_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - -#ifdef DEBUG_RELOC - fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n", - bfd_get_reloc_code_name(code)); -#endif - - switch (code) - { - HOW2MAP(BFD_RELOC_32_GOTOFF, IMAGE_REL_PPC_IMGLUE); - HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE); - HOW2MAP(BFD_RELOC_16, IMAGE_REL_PPC_ADDR16); - HOW2MAP(BFD_RELOC_PPC_B26, IMAGE_REL_PPC_REL24); - HOW2MAP(BFD_RELOC_PPC_BA26, IMAGE_REL_PPC_ADDR24); - HOW2MAP(BFD_RELOC_PPC_TOC16, IMAGE_REL_PPC_TOCREL16); - HOW2MAP(BFD_RELOC_16_GOTOFF, IMAGE_REL_PPC_TOCREL16_DEFN); - HOW2MAP(BFD_RELOC_32, IMAGE_REL_PPC_ADDR32); - HOW2MAP(BFD_RELOC_RVA, IMAGE_REL_PPC_ADDR32NB); - default: - return NULL; - } - - return NULL; -} - -#undef HOW2MAP - - -/* Tailor coffcode.h -- macro heaven. */ - -#define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst) - -#ifndef COFF_IMAGE_WITH_PE -static void -ppc_coff_swap_sym_in_hook (); -#endif - -/* We use the special COFF backend linker, with our own special touch. */ - -#define coff_bfd_reloc_type_lookup ppc_coff_reloc_type_lookup -#define coff_rtype_to_howto coff_ppc_rtype_to_howto -#define coff_relocate_section coff_ppc_relocate_section -#define coff_bfd_final_link ppc_bfd_coff_final_link - -#ifndef COFF_IMAGE_WITH_PE -#define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook -#endif - -#define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;} - -#define COFF_PAGE_SIZE 0x1000 - -#define POWERPC_LE_PE - -#include "coffcode.h" - - - -#ifndef COFF_IMAGE_WITH_PE -/* FIXME: - What we're trying to do here is allocate a toc section (early), and attach - it to the last bfd to be processed. This avoids the problem of having a toc - written out before all files have been processed. This code allocates - a toc section for every file, and records the last one seen. There are - at least two problems with this approach: - 1. We allocate whole bunches of toc sections that are ignored, but at - at least we will not allocate a toc if no .toc is present. - 2. It's not clear to me that being the last bfd read necessarily means - that you are the last bfd closed. - 3. Doing it on a "swap in" hook depends on when the "swap in" is called, - and how often, etc. It's not clear to me that there isn't a hole here. -*/ - -static void -ppc_coff_swap_sym_in_hook (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - SYMENT *ext = (SYMENT *)ext1; - struct internal_syment *in = (struct internal_syment *)in1; - - if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */ - return; - - if (strcmp(in->_n._n_name, ".toc") == 0) - { - flagword flags; - register asection *s; - char *foo; - - s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME); - if (s != NULL) - { - return; - } - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ; - -#ifdef TOC_DEBUG - fprintf(stderr, - "ppc_coff_swap_sym_in_hook: about to create the %s section\n", - TOC_SECTION_NAME); -#endif - - s = bfd_make_section (abfd, TOC_SECTION_NAME); - - if (s == NULL - || !bfd_set_section_flags (abfd, s, flags) - || !bfd_set_section_alignment (abfd, s, 2)) - { - fprintf(stderr, - "toc section allocation failed!\n"); - abort(); - } - - /* save the bfd for later allocation */ - bfd_of_toc_owner = abfd; - } - - return; -} -#endif - -boolean -ppc_bfd_coff_final_link (); - -#ifndef COFF_IMAGE_WITH_PE - -static boolean -ppc_do_last(abfd) - bfd *abfd; -{ - if (abfd == bfd_of_toc_owner) - return true; - else - return false; -} - -static bfd * -ppc_get_last() -{ - return bfd_of_toc_owner; -} - -/* this piece of machinery exists only to guarantee that the bfd that holds - the toc section is written last. - - This does depend on bfd_make_section attaching a new section to the - end of the section list for the bfd. - - This is otherwise intended to be functionally the same as - cofflink.c:_bfd_coff_final_link(). It is specifically different only - where the POWERPC_LE_PE macro modifies the code. It is left in as a - precise form of comment. krk@cygnus.com -*/ -#define POWERPC_LE_PE - - -/* Do the final link step. */ - -boolean -ppc_bfd_coff_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz; - struct coff_final_link_info finfo; - boolean debug_merge_allocated; - asection *o; - struct bfd_link_order *p; - size_t max_sym_count; - size_t max_lineno_count; - size_t max_reloc_count; - size_t max_output_reloc_count; - size_t max_contents_size; - file_ptr rel_filepos; - unsigned int relsz; - file_ptr line_filepos; - unsigned int linesz; - bfd *sub; - bfd_byte *external_relocs = NULL; - char strbuf[STRING_SIZE_SIZE]; - - symesz = bfd_coff_symesz (abfd); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.strtab = NULL; - finfo.section_info = NULL; - finfo.last_file_index = -1; - finfo.internal_syms = NULL; - finfo.sec_ptrs = NULL; - finfo.sym_indices = NULL; - finfo.outsyms = NULL; - finfo.linenos = NULL; - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - debug_merge_allocated = false; - - coff_data (abfd)->link_info = info; - - finfo.strtab = _bfd_stringtab_init (); - if (finfo.strtab == NULL) - goto error_return; - - if (! coff_debug_merge_hash_table_init (&finfo.debug_merge)) - goto error_return; - debug_merge_allocated = true; - - /* Compute the file positions for all the sections. */ - if (! abfd->output_has_begun) - bfd_coff_compute_section_file_positions (abfd); - - /* Count the line numbers and relocation entries required for the - output file. Set the file positions for the relocs. */ - rel_filepos = obj_relocbase (abfd); - relsz = bfd_coff_relsz (abfd); - max_contents_size = 0; - max_lineno_count = 0; - max_reloc_count = 0; - - for (o = abfd->sections; o != NULL; o = o->next) - { - o->reloc_count = 0; - o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) - { - - if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->strip == strip_none - || info->strip == strip_some) - o->lineno_count += sec->lineno_count; - - if (info->relocateable) - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->lineno_count > max_lineno_count) - max_lineno_count = sec->lineno_count; - if (sec->reloc_count > max_reloc_count) - max_reloc_count = sec->reloc_count; - } - else if (info->relocateable - && (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order)) - ++o->reloc_count; - } - if (o->reloc_count == 0) - o->rel_filepos = 0; - else - { - o->flags |= SEC_RELOC; - o->rel_filepos = rel_filepos; - rel_filepos += o->reloc_count * relsz; - } - } - - /* If doing a relocateable link, allocate space for the pointers we - need to keep. */ - if (info->relocateable) - { - unsigned int i; - - /* We use section_count + 1, rather than section_count, because - the target_index fields are 1 based. */ - finfo.section_info = - ((struct coff_link_section_info *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct coff_link_section_info))); - if (finfo.section_info == NULL) - goto error_return; - for (i = 0; i <= abfd->section_count; i++) - { - finfo.section_info[i].relocs = NULL; - finfo.section_info[i].rel_hashes = NULL; - } - } - - /* We now know the size of the relocs, so we can determine the file - positions of the line numbers. */ - line_filepos = rel_filepos; - linesz = bfd_coff_linesz (abfd); - max_output_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->lineno_count == 0) - o->line_filepos = 0; - else - { - o->line_filepos = line_filepos; - line_filepos += o->lineno_count * linesz; - } - - if (o->reloc_count != 0) - { - /* We don't know the indices of global symbols until we have - written out all the local symbols. For each section in - the output file, we keep an array of pointers to hash - table entries. Each entry in the array corresponds to a - reloc. When we find a reloc against a global symbol, we - set the corresponding entry in this array so that we can - fix up the symbol index after we have written out all the - local symbols. - - Because of this problem, we also keep the relocs in - memory until the end of the link. This wastes memory, - but only when doing a relocateable link, which is not the - common case. */ - BFD_ASSERT (info->relocateable); - finfo.section_info[o->target_index].relocs = - ((struct internal_reloc *) - bfd_malloc (o->reloc_count * sizeof (struct internal_reloc))); - finfo.section_info[o->target_index].rel_hashes = - ((struct coff_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct coff_link_hash_entry *))); - if (finfo.section_info[o->target_index].relocs == NULL - || finfo.section_info[o->target_index].rel_hashes == NULL) - goto error_return; - - if (o->reloc_count > max_output_reloc_count) - max_output_reloc_count = o->reloc_count; - } - - /* Reset the reloc and lineno counts, so that we can use them to - count the number of entries we have output so far. */ - o->reloc_count = 0; - o->lineno_count = 0; - } - - obj_sym_filepos (abfd) = line_filepos; - - /* Figure out the largest number of symbols in an input BFD. Take - the opportunity to clear the output_has_begun fields of all the - input BFD's. */ - max_sym_count = 0; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - size_t sz; - - sub->output_has_begun = false; - sz = obj_raw_syment_count (sub); - if (sz > max_sym_count) - max_sym_count = sz; - } - - /* Allocate some buffers used while linking. */ - finfo.internal_syms = ((struct internal_syment *) - bfd_malloc (max_sym_count - * sizeof (struct internal_syment))); - finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count - * sizeof (asection *)); - finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.outsyms = ((bfd_byte *) - bfd_malloc ((size_t) ((max_sym_count + 1) * symesz))); - finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count - * bfd_coff_linesz (abfd)); - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz); - if (! info->relocateable) - finfo.internal_relocs = ((struct internal_reloc *) - bfd_malloc (max_reloc_count - * sizeof (struct internal_reloc))); - if ((finfo.internal_syms == NULL && max_sym_count > 0) - || (finfo.sec_ptrs == NULL && max_sym_count > 0) - || (finfo.sym_indices == NULL && max_sym_count > 0) - || finfo.outsyms == NULL - || (finfo.linenos == NULL && max_lineno_count > 0) - || (finfo.contents == NULL && max_contents_size > 0) - || (finfo.external_relocs == NULL && max_reloc_count > 0) - || (! info->relocateable - && finfo.internal_relocs == NULL - && max_reloc_count > 0)) - goto error_return; - - /* We now know the position of everything in the file, except that - we don't know the size of the symbol table and therefore we don't - know where the string table starts. We just build the string - table in memory as we go along. We process all the relocations - for a single input file at once. */ - obj_raw_syment_count (abfd) = 0; - - if (coff_backend_info (abfd)->_bfd_coff_start_final_link) - { - if (! bfd_coff_start_final_link (abfd, info)) - goto error_return; - } - - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_coff_flavour)) - { - sub = p->u.indirect.section->owner; -#ifdef POWERPC_LE_PE - if (! sub->output_has_begun && !ppc_do_last(sub)) -#else - if (! sub->output_has_begun) -#endif - { - if (! _bfd_coff_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - -#ifdef POWERPC_LE_PE - { - extern bfd* ppc_get_last(); - bfd* last_one = ppc_get_last(); - if (last_one) - { - if (! _bfd_coff_link_input_bfd (&finfo, last_one)) - goto error_return; - } - last_one->output_has_begun = true; - } -#endif - - /* Free up the buffers used by _bfd_coff_link_input_bfd. */ - - coff_debug_merge_hash_table_free (&finfo.debug_merge); - debug_merge_allocated = false; - - if (finfo.internal_syms != NULL) - { - free (finfo.internal_syms); - finfo.internal_syms = NULL; - } - if (finfo.sec_ptrs != NULL) - { - free (finfo.sec_ptrs); - finfo.sec_ptrs = NULL; - } - if (finfo.sym_indices != NULL) - { - free (finfo.sym_indices); - finfo.sym_indices = NULL; - } - if (finfo.linenos != NULL) - { - free (finfo.linenos); - finfo.linenos = NULL; - } - if (finfo.contents != NULL) - { - free (finfo.contents); - finfo.contents = NULL; - } - if (finfo.external_relocs != NULL) - { - free (finfo.external_relocs); - finfo.external_relocs = NULL; - } - if (finfo.internal_relocs != NULL) - { - free (finfo.internal_relocs); - finfo.internal_relocs = NULL; - } - - /* The value of the last C_FILE symbol is supposed to be the symbol - index of the first external symbol. Write it out again if - necessary. */ - if (finfo.last_file_index != -1 - && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd)) - { - finfo.last_file.n_value = obj_raw_syment_count (abfd); - bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, - (PTR) finfo.outsyms); - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + finfo.last_file_index * symesz), - SEEK_SET) != 0 - || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz) - return false; - } - - /* Write out the global symbols. */ - finfo.failed = false; - coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym, - (PTR) &finfo); - if (finfo.failed) - goto error_return; - - /* The outsyms buffer is used by _bfd_coff_write_global_sym. */ - if (finfo.outsyms != NULL) - { - free (finfo.outsyms); - finfo.outsyms = NULL; - } - - if (info->relocateable) - { - /* Now that we have written out all the global symbols, we know - the symbol indices to use for relocs against them, and we can - finally write out the relocs. */ - external_relocs = ((bfd_byte *) - bfd_malloc (max_output_reloc_count * relsz)); - if (external_relocs == NULL) - goto error_return; - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *irel; - struct internal_reloc *irelend; - struct coff_link_hash_entry **rel_hash; - bfd_byte *erel; - - if (o->reloc_count == 0) - continue; - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - rel_hash = finfo.section_info[o->target_index].rel_hashes; - erel = external_relocs; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - { - if (*rel_hash != NULL) - { - BFD_ASSERT ((*rel_hash)->indx >= 0); - irel->r_symndx = (*rel_hash)->indx; - } - bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); - } - - if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || bfd_write ((PTR) external_relocs, relsz, o->reloc_count, - abfd) != relsz * o->reloc_count) - goto error_return; - } - - free (external_relocs); - external_relocs = NULL; - } - - /* Free up the section information. */ - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - finfo.section_info = NULL; - } - - /* Write out the string table. */ - if (obj_raw_syment_count (abfd) != 0) - { - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * symesz), - SEEK_SET) != 0) - return false; - -#if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, - _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, - (bfd_byte *) strbuf); -#else - #error Change bfd_h_put_32 -#endif - - if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) - return false; - - if (! _bfd_stringtab_emit (abfd, finfo.strtab)) - return false; - } - - _bfd_stringtab_free (finfo.strtab); - - /* Setting bfd_get_symcount to 0 will cause write_object_contents to - not try to write out the symbols. */ - bfd_get_symcount (abfd) = 0; - - return true; - - error_return: - if (debug_merge_allocated) - coff_debug_merge_hash_table_free (&finfo.debug_merge); - if (finfo.strtab != NULL) - _bfd_stringtab_free (finfo.strtab); - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - } - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.sec_ptrs != NULL) - free (finfo.sec_ptrs); - if (finfo.sym_indices != NULL) - free (finfo.sym_indices); - if (finfo.outsyms != NULL) - free (finfo.outsyms); - if (finfo.linenos != NULL) - free (finfo.linenos); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (external_relocs != NULL) - free (external_relocs); - return false; -} -#endif - - -/* The transfer vectors that lead the outside world to all of the above. */ - -#ifdef TARGET_LITTLE_SYM -const bfd_target -TARGET_LITTLE_SYM = -{ - TARGET_LITTLE_NAME, /* name or coff-arm-little */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* FIXME: object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen??? FIXMEmgo */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p }, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; -#endif - -#ifdef TARGET_BIG_SYM -const bfd_target -TARGET_BIG_SYM = -{ - TARGET_BIG_NAME, - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* FIXME: object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen??? FIXMEmgo */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p }, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - -#endif diff --git a/contrib/gdb/bfd/coff-rs6000.c b/contrib/gdb/bfd/coff-rs6000.c deleted file mode 100644 index c065bd4f005..00000000000 --- a/contrib/gdb/bfd/coff-rs6000.c +++ /dev/null @@ -1,1403 +0,0 @@ -/* BFD back-end for IBM RS/6000 "XCOFF" files. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, - and John Gilmore. - Archive support from Damon A. Permezel. - Contributed by IBM Corporation and Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Internalcoff.h and coffcode.h modify themselves based on this flag. */ -#define RS6000COFF_C 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/internal.h" -#include "coff/rs6000.h" -#include "libcoff.h" - -/* The main body of code is in coffcode.h. */ - -static boolean xcoff_mkobject PARAMS ((bfd *)); -static boolean xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static void xcoff_rtype2howto - PARAMS ((arelent *, struct internal_reloc *)); -static reloc_howto_type *xcoff_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static boolean xcoff_slurp_armap PARAMS ((bfd *)); -static const bfd_target *xcoff_archive_p PARAMS ((bfd *)); -static PTR xcoff_read_ar_hdr PARAMS ((bfd *)); -static bfd *xcoff_openr_next_archived_file PARAMS ((bfd *, bfd *)); -static int xcoff_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); -static const char *normalize_filename PARAMS ((bfd *)); -static boolean xcoff_write_armap - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); -static boolean xcoff_write_archive_contents PARAMS ((bfd *)); - -/* We use our own tdata type. Its first field is the COFF tdata type, - so the COFF routines are compatible. */ - -static boolean -xcoff_mkobject (abfd) - bfd *abfd; -{ - coff_data_type *coff; - - abfd->tdata.xcoff_obj_data = - ((struct xcoff_tdata *) - bfd_zalloc (abfd, sizeof (struct xcoff_tdata))); - if (abfd->tdata.xcoff_obj_data == NULL) - return false; - coff = coff_data (abfd); - coff->symbols = (coff_symbol_type *) NULL; - coff->conversion_table = (unsigned int *) NULL; - coff->raw_syments = (struct coff_ptr_struct *) NULL; - coff->relocbase = 0; - - xcoff_data (abfd)->modtype = ('1' << 8) | 'L'; - - /* We set cputype to -1 to indicate that it has not been - initialized. */ - xcoff_data (abfd)->cputype = -1; - - xcoff_data (abfd)->csects = NULL; - xcoff_data (abfd)->debug_indices = NULL; - - return true; -} - -/* Copy XCOFF data from one BFD to another. */ - -static boolean -xcoff_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - struct xcoff_tdata *ix, *ox; - asection *sec; - - if (ibfd->xvec != obfd->xvec) - return true; - ix = xcoff_data (ibfd); - ox = xcoff_data (obfd); - ox->full_aouthdr = ix->full_aouthdr; - ox->toc = ix->toc; - if (ix->sntoc == 0) - ox->sntoc = 0; - else - { - sec = coff_section_from_bfd_index (ibfd, ix->sntoc); - if (sec == NULL) - ox->sntoc = 0; - else - ox->sntoc = sec->output_section->target_index; - } - if (ix->snentry == 0) - ox->snentry = 0; - else - { - sec = coff_section_from_bfd_index (ibfd, ix->snentry); - if (sec == NULL) - ox->snentry = 0; - else - ox->snentry = sec->output_section->target_index; - } - ox->text_align_power = ix->text_align_power; - ox->data_align_power = ix->data_align_power; - ox->modtype = ix->modtype; - ox->cputype = ix->cputype; - ox->maxdata = ix->maxdata; - ox->maxstack = ix->maxstack; - return true; -} - -/* The XCOFF reloc table. Actually, XCOFF relocations specify the - bitsize and whether they are signed or not, along with a - conventional type. This table is for the types, which are used for - different algorithms for putting in the reloc. Many of these - relocs need special_function entries, which I have not written. */ - -static reloc_howto_type xcoff_howto_table[] = -{ - /* Standard 32 bit relocation. */ - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_POS", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit relocation, but store negative value. */ - HOWTO (1, /* type */ - 0, /* rightshift */ - -2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_NEG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative relocation. */ - HOWTO (2, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit TOC relative relocation. */ - HOWTO (3, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TOC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* I don't really know what this is. */ - HOWTO (4, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RTB", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* External TOC relative symbol. */ - HOWTO (5, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_GL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Local TOC relative symbol. */ - HOWTO (6, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TCL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 7 }, - - /* Non modifiable absolute branch. */ - HOWTO (8, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_BA", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 9 }, - - /* Non modifiable relative branch. */ - HOWTO (0xa, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_BR", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xb }, - - /* Indirect load. */ - HOWTO (0xc, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load address. */ - HOWTO (0xd, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xe }, - - /* Non-relocating reference. */ - HOWTO (0xf, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REF", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - { 0x10 }, - { 0x11 }, - - /* TOC relative indirect load. */ - HOWTO (0x12, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* TOC relative load address. */ - HOWTO (0x13, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable relative branch. */ - HOWTO (0x14, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBI", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable absolute branch. */ - HOWTO (0x15, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBA", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call absolute indirect. */ - HOWTO (0x16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_CAI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call relative. */ - HOWTO (0x17, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_CREL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x18, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x19, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBAC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch relative. */ - HOWTO (0x1a, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBR", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x1b, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBRC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -static void -xcoff_rtype2howto (relent, internal) - arelent *relent; - struct internal_reloc *internal; -{ - relent->howto = xcoff_howto_table + internal->r_type; - - /* The r_size field of an XCOFF reloc encodes the bitsize of the - relocation, as well as indicating whether it is signed or not. - Doublecheck that the relocation information gathered from the - type matches this information. */ - if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1) - abort (); -#if 0 - if ((internal->r_size & 0x80) != 0 - ? (relent->howto->complain_on_overflow != complain_overflow_signed) - : (relent->howto->complain_on_overflow != complain_overflow_bitfield)) - abort (); -#endif -} - -static reloc_howto_type * -xcoff_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_PPC_B26: - return &xcoff_howto_table[0xa]; - case BFD_RELOC_PPC_BA26: - return &xcoff_howto_table[8]; - case BFD_RELOC_PPC_TOC16: - return &xcoff_howto_table[3]; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - return &xcoff_howto_table[0]; - default: - return NULL; - } -} - -#define SELECT_RELOC(internal, howto) \ - { \ - internal.r_type = howto->type; \ - internal.r_size = \ - ((howto->complain_on_overflow == complain_overflow_signed \ - ? 0x80 \ - : 0) \ - | (howto->bitsize - 1)); \ - } - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -#define COFF_LONG_FILENAMES - -#define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst) - -#define coff_mkobject xcoff_mkobject -#define coff_bfd_copy_private_bfd_data xcoff_copy_private_bfd_data -#define coff_bfd_reloc_type_lookup xcoff_reloc_type_lookup -#define coff_relocate_section _bfd_ppc_xcoff_relocate_section - -#include "coffcode.h" - -/* XCOFF archive support. The original version of this code was by - Damon A. Permezel. It was enhanced to permit cross support, and - writing archive files, by Ian Lance Taylor, Cygnus Support. - - XCOFF uses its own archive format. Everything is hooked together - with file offset links, so it is possible to rapidly update an - archive in place. Of course, we don't do that. An XCOFF archive - has a real file header, not just an ARMAG string. The structure of - the file header and of each archive header appear below. - - An XCOFF archive also has a member table, which is a list of - elements in the archive (you can get that by looking through the - linked list, but you have to read a lot more of the file). The - member table has a normal archive header with an empty name. It is - normally (and perhaps must be) the second to last entry in the - archive. The member table data is almost printable ASCII. It - starts with a 12 character decimal string which is the number of - entries in the table. For each entry it has a 12 character decimal - string which is the offset in the archive of that member. These - entries are followed by a series of null terminated strings which - are the member names for each entry. - - Finally, an XCOFF archive has a global symbol table, which is what - we call the armap. The global symbol table has a normal archive - header with an empty name. It is normally (and perhaps must be) - the last entry in the archive. The contents start with a four byte - binary number which is the number of entries. This is followed by - a that many four byte binary numbers; each is the file offset of an - entry in the archive. These numbers are followed by a series of - null terminated strings, which are symbol names. */ - -/* XCOFF archives use this as a magic string. */ - -#define XCOFFARMAG "\012" -#define SXCOFFARMAG 8 - -/* This terminates an XCOFF archive member name. */ - -#define XCOFFARFMAG "`\012" -#define SXCOFFARFMAG 2 - -/* XCOFF archives start with this (printable) structure. */ - -struct xcoff_ar_file_hdr -{ - /* Magic string. */ - char magic[SXCOFFARMAG]; - - /* Offset of the member table (decimal ASCII string). */ - char memoff[12]; - - /* Offset of the global symbol table (decimal ASCII string). */ - char symoff[12]; - - /* Offset of the first member in the archive (decimal ASCII string). */ - char firstmemoff[12]; - - /* Offset of the last member in the archive (decimal ASCII string). */ - char lastmemoff[12]; - - /* Offset of the first member on the free list (decimal ASCII - string). */ - char freeoff[12]; -}; - -#define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG) - -/* Each XCOFF archive member starts with this (printable) structure. */ - -struct xcoff_ar_hdr -{ - /* File size not including the header (decimal ASCII string). */ - char size[12]; - - /* File offset of next archive member (decimal ASCII string). */ - char nextoff[12]; - - /* File offset of previous archive member (decimal ASCII string). */ - char prevoff[12]; - - /* File mtime (decimal ASCII string). */ - char date[12]; - - /* File UID (decimal ASCII string). */ - char uid[12]; - - /* File GID (decimal ASCII string). */ - char gid[12]; - - /* File mode (octal ASCII string). */ - char mode[12]; - - /* Length of file name (decimal ASCII string). */ - char namlen[4]; - - /* This structure is followed by the file name. The length of the - name is given in the namlen field. If the length of the name is - odd, the name is followed by a null byte. The name and optional - null byte are followed by XCOFFARFMAG, which is not included in - namlen. The contents of the archive member follow; the number of - bytes is given in the size field. */ -}; - -#define SIZEOF_AR_HDR (7 * 12 + 4) - -/* We store a copy of the xcoff_ar_file_hdr in the tdata field of the - artdata structure. */ -#define xcoff_ardata(abfd) \ - ((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata) - -/* We store a copy of the xcoff_ar_hdr in the arelt_data field of an - archive element. */ -#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data)) -#define arch_xhdr(bfd) \ - ((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header) - -/* XCOFF archives do not have anything which corresponds to an - extended name table. */ - -#define xcoff_slurp_extended_name_table bfd_false -#define xcoff_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_false) -#define xcoff_truncate_arname bfd_dont_truncate_arname - -/* We can use the standard get_elt_at_index routine. */ - -#define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index - -/* XCOFF archives do not have a timestamp. */ - -#define xcoff_update_armap_timestamp bfd_true - -/* Read in the armap of an XCOFF archive. */ - -static boolean -xcoff_slurp_armap (abfd) - bfd *abfd; -{ - file_ptr off; - struct xcoff_ar_hdr hdr; - size_t namlen; - bfd_size_type sz; - bfd_byte *contents, *cend; - unsigned int c, i; - carsym *arsym; - bfd_byte *p; - - if (xcoff_ardata (abfd) == NULL) - { - bfd_has_map (abfd) = false; - return true; - } - - off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10); - if (off == 0) - { - bfd_has_map (abfd) = false; - return true; - } - - if (bfd_seek (abfd, off, SEEK_SET) != 0) - return false; - - /* The symbol table starts with a normal archive header. */ - if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR) - return false; - - /* Skip the name (normally empty). */ - namlen = strtol (hdr.namlen, (char **) NULL, 10); - if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0) - return false; - - /* Read in the entire symbol table. */ - sz = strtol (hdr.size, (char **) NULL, 10); - contents = (bfd_byte *) bfd_alloc (abfd, sz); - if (contents == NULL) - return false; - if (bfd_read ((PTR) contents, 1, sz, abfd) != sz) - return false; - - /* The symbol table starts with a four byte count. */ - c = bfd_h_get_32 (abfd, contents); - - if (c * 4 >= sz) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - bfd_ardata (abfd)->symdefs = ((carsym *) - bfd_alloc (abfd, c * sizeof (carsym))); - if (bfd_ardata (abfd)->symdefs == NULL) - return false; - - /* After the count comes a list of four byte file offsets. */ - for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4; - i < c; - ++i, ++arsym, p += 4) - arsym->file_offset = bfd_h_get_32 (abfd, p); - - /* After the file offsets come null terminated symbol names. */ - cend = contents + sz; - for (i = 0, arsym = bfd_ardata (abfd)->symdefs; - i < c; - ++i, ++arsym, p += strlen ((char *) p) + 1) - { - if (p >= cend) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - arsym->name = (char *) p; - } - - bfd_ardata (abfd)->symdef_count = c; - bfd_has_map (abfd) = true; - - return true; -} - -/* See if this is an XCOFF archive. */ - -static const bfd_target * -xcoff_archive_p (abfd) - bfd *abfd; -{ - struct xcoff_ar_file_hdr hdr; - - if (bfd_read ((PTR) &hdr, SIZEOF_AR_FILE_HDR, 1, abfd) - != SIZEOF_AR_FILE_HDR) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (strncmp (hdr.magic, XCOFFARMAG, SXCOFFARMAG) != 0) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* We are setting bfd_ardata(abfd) here, but since bfd_ardata - involves a cast, we can't do it as the left operand of - assignment. */ - abfd->tdata.aout_ar_data = - (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata)); - - if (bfd_ardata (abfd) == (struct artdata *) NULL) - return NULL; - - bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, - (char **) NULL, 10); - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - - bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR); - if (bfd_ardata (abfd)->tdata == NULL) - return NULL; - - memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR); - - if (! xcoff_slurp_armap (abfd)) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = (struct artdata *) NULL; - return NULL; - } - - return abfd->xvec; -} - -/* Read the archive header in an XCOFF archive. */ - -static PTR -xcoff_read_ar_hdr (abfd) - bfd *abfd; -{ - struct xcoff_ar_hdr hdr; - size_t namlen; - struct xcoff_ar_hdr *hdrp; - struct areltdata *ret; - - if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR) - return NULL; - - namlen = strtol (hdr.namlen, (char **) NULL, 10); - hdrp = bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1); - if (hdrp == NULL) - return NULL; - memcpy (hdrp, &hdr, SIZEOF_AR_HDR); - if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen) - return NULL; - ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0'; - - ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata)); - if (ret == NULL) - return NULL; - ret->arch_header = (char *) hdrp; - ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); - ret->filename = (char *) hdrp + SIZEOF_AR_HDR; - - /* Skip over the XCOFFARFMAG at the end of the file name. */ - if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0) - return NULL; - - return (PTR) ret; -} - -/* Open the next element in an XCOFF archive. */ - -static bfd * -xcoff_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - file_ptr filestart; - - if (xcoff_ardata (archive) == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - if (last_file == NULL) - filestart = bfd_ardata (archive)->first_file_filepos; - else - filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10); - - if (filestart == 0 - || filestart == strtol (xcoff_ardata (archive)->memoff, - (char **) NULL, 10) - || filestart == strtol (xcoff_ardata (archive)->symoff, - (char **) NULL, 10)) - { - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - - return _bfd_get_elt_at_filepos (archive, filestart); -} - -/* Stat an element in an XCOFF archive. */ - -static int -xcoff_generic_stat_arch_elt (abfd, s) - bfd *abfd; - struct stat *s; -{ - struct xcoff_ar_hdr *hdrp; - - if (abfd->arelt_data == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - hdrp = arch_xhdr (abfd); - - s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); - s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); - s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); - s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); - s->st_size = arch_eltdata (abfd)->parsed_size; - - return 0; -} - -/* Normalize a file name for inclusion in an archive. */ - -static const char * -normalize_filename (abfd) - bfd *abfd; -{ - const char *file; - const char *filename; - - file = bfd_get_filename (abfd); - filename = strrchr (file, '/'); - if (filename != NULL) - filename++; - else - filename = file; - return filename; -} - -/* Write out an XCOFF armap. */ - -/*ARGSUSED*/ -static boolean -xcoff_write_armap (abfd, elength, map, orl_count, stridx) - bfd *abfd; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - struct xcoff_ar_hdr hdr; - char *p; - unsigned char buf[4]; - bfd *sub; - file_ptr fileoff; - unsigned int i; - - memset (&hdr, 0, sizeof hdr); - sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx)); - sprintf (hdr.nextoff, "%d", 0); - memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12); - sprintf (hdr.date, "%d", 0); - sprintf (hdr.uid, "%d", 0); - sprintf (hdr.gid, "%d", 0); - sprintf (hdr.mode, "%d", 0); - sprintf (hdr.namlen, "%d", 0); - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR - || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG) - return false; - - bfd_h_put_32 (abfd, orl_count, buf); - if (bfd_write (buf, 1, 4, abfd) != 4) - return false; - - sub = abfd->archive_head; - fileoff = SIZEOF_AR_FILE_HDR; - i = 0; - while (sub != NULL && i < orl_count) - { - size_t namlen; - - while (((bfd *) (map[i]).pos) == sub) - { - bfd_h_put_32 (abfd, fileoff, buf); - if (bfd_write (buf, 1, 4, abfd) != 4) - return false; - ++i; - } - namlen = strlen (normalize_filename (sub)); - namlen = (namlen + 1) &~ 1; - fileoff += (SIZEOF_AR_HDR - + namlen - + SXCOFFARFMAG - + arelt_size (sub)); - fileoff = (fileoff + 1) &~ 1; - sub = sub->next; - } - - for (i = 0; i < orl_count; i++) - { - const char *name; - size_t namlen; - - name = *map[i].name; - namlen = strlen (name); - if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1) - return false; - } - - if ((stridx & 1) != 0) - { - char b; - - b = '\0'; - if (bfd_write (&b, 1, 1, abfd) != 1) - return false; - } - - return true; -} - -/* Write out an XCOFF archive. We always write an entire archive, - rather than fussing with the freelist and so forth. */ - -static boolean -xcoff_write_archive_contents (abfd) - bfd *abfd; -{ - struct xcoff_ar_file_hdr fhdr; - size_t count; - size_t total_namlen; - file_ptr *offsets; - boolean makemap; - boolean hasobjects; - file_ptr prevoff, nextoff; - bfd *sub; - unsigned int i; - struct xcoff_ar_hdr ahdr; - bfd_size_type size; - char *p; - char decbuf[13]; - - memset (&fhdr, 0, sizeof fhdr); - strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG); - sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR); - sprintf (fhdr.freeoff, "%d", 0); - - count = 0; - total_namlen = 0; - for (sub = abfd->archive_head; sub != NULL; sub = sub->next) - { - ++count; - total_namlen += strlen (normalize_filename (sub)) + 1; - } - offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr)); - if (offsets == NULL) - return false; - - if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0) - return false; - - makemap = bfd_has_map (abfd); - hasobjects = false; - prevoff = 0; - nextoff = SIZEOF_AR_FILE_HDR; - for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++) - { - const char *name; - size_t namlen; - struct xcoff_ar_hdr *ahdrp; - bfd_size_type remaining; - - if (makemap && ! hasobjects) - { - if (bfd_check_format (sub, bfd_object)) - hasobjects = true; - } - - name = normalize_filename (sub); - namlen = strlen (name); - - if (sub->arelt_data != NULL) - ahdrp = arch_xhdr (sub); - else - ahdrp = NULL; - - if (ahdrp == NULL) - { - struct stat s; - - memset (&ahdr, 0, sizeof ahdr); - ahdrp = &ahdr; - if (stat (bfd_get_filename (sub), &s) != 0) - { - bfd_set_error (bfd_error_system_call); - return false; - } - - sprintf (ahdrp->size, "%ld", (long) s.st_size); - sprintf (ahdrp->date, "%ld", (long) s.st_mtime); - sprintf (ahdrp->uid, "%ld", (long) s.st_uid); - sprintf (ahdrp->gid, "%ld", (long) s.st_gid); - sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode); - - if (sub->arelt_data == NULL) - { - sub->arelt_data = ((struct areltdata *) - bfd_alloc (sub, sizeof (struct areltdata))); - if (sub->arelt_data == NULL) - return false; - } - - arch_eltdata (sub)->parsed_size = s.st_size; - } - - sprintf (ahdrp->prevoff, "%ld", (long) prevoff); - sprintf (ahdrp->namlen, "%ld", (long) namlen); - - /* If the length of the name is odd, we write out the null byte - after the name as well. */ - namlen = (namlen + 1) &~ 1; - - remaining = arelt_size (sub); - size = (SIZEOF_AR_HDR - + namlen - + SXCOFFARFMAG - + remaining); - - BFD_ASSERT (nextoff == bfd_tell (abfd)); - - offsets[i] = nextoff; - - prevoff = nextoff; - nextoff += size + (size & 1); - - sprintf (ahdrp->nextoff, "%ld", (long) nextoff); - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR - || bfd_write ((PTR) name, 1, namlen, abfd) != namlen - || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) - != SXCOFFARFMAG)) - return false; - - if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0) - return false; - while (remaining != 0) - { - bfd_size_type amt; - bfd_byte buffer[DEFAULT_BUFFERSIZE]; - - amt = sizeof buffer; - if (amt > remaining) - amt = remaining; - if (bfd_read (buffer, 1, amt, sub) != amt - || bfd_write (buffer, 1, amt, abfd) != amt) - return false; - remaining -= amt; - } - - if ((size & 1) != 0) - { - bfd_byte b; - - b = '\0'; - if (bfd_write (&b, 1, 1, abfd) != 1) - return false; - } - } - - sprintf (fhdr.lastmemoff, "%ld", (long) prevoff); - - /* Write out the member table. */ - - BFD_ASSERT (nextoff == bfd_tell (abfd)); - sprintf (fhdr.memoff, "%ld", (long) nextoff); - - memset (&ahdr, 0, sizeof ahdr); - sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen)); - sprintf (ahdr.prevoff, "%ld", (long) prevoff); - sprintf (ahdr.date, "%d", 0); - sprintf (ahdr.uid, "%d", 0); - sprintf (ahdr.gid, "%d", 0); - sprintf (ahdr.mode, "%d", 0); - sprintf (ahdr.namlen, "%d", 0); - - size = (SIZEOF_AR_HDR - + 12 - + count * 12 - + total_namlen - + SXCOFFARFMAG); - - prevoff = nextoff; - nextoff += size + (size & 1); - - if (makemap && hasobjects) - sprintf (ahdr.nextoff, "%ld", (long) nextoff); - else - sprintf (ahdr.nextoff, "%d", 0); - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR - || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) - != SXCOFFARFMAG)) - return false; - - sprintf (decbuf, "%-12ld", (long) count); - if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12) - return false; - for (i = 0; i < count; i++) - { - sprintf (decbuf, "%-12ld", (long) offsets[i]); - if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12) - return false; - } - for (sub = abfd->archive_head; sub != NULL; sub = sub->next) - { - const char *name; - size_t namlen; - - name = normalize_filename (sub); - namlen = strlen (name); - if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1) - return false; - } - if ((size & 1) != 0) - { - bfd_byte b; - - b = '\0'; - if (bfd_write ((PTR) &b, 1, 1, abfd) != 1) - return false; - } - - /* Write out the armap, if appropriate. */ - - if (! makemap || ! hasobjects) - sprintf (fhdr.symoff, "%d", 0); - else - { - BFD_ASSERT (nextoff == bfd_tell (abfd)); - sprintf (fhdr.symoff, "%ld", (long) nextoff); - bfd_ardata (abfd)->tdata = (PTR) &fhdr; - if (! _bfd_compute_and_write_armap (abfd, 0)) - return false; - } - - /* Write out the archive file header. */ - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR, 1, abfd) != - SIZEOF_AR_FILE_HDR)) - return false; - - return true; -} - -/* We can't use the usual coff_sizeof_headers routine, because AIX - always uses an a.out header. */ - -/*ARGSUSED*/ -static int -_bfd_xcoff_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - int size; - - size = FILHSZ; - if (xcoff_data (abfd)->full_aouthdr) - size += AOUTSZ; - else - size += SMALL_AOUTSZ; - size += abfd->section_count * SCNHSZ; - return size; -} - -#define CORE_FILE_P _bfd_dummy_target - -#define coff_core_file_failing_command _bfd_nocore_core_file_failing_command -#define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal -#define coff_core_file_matches_executable_p \ - _bfd_nocore_core_file_matches_executable_p - -#ifdef AIX_CORE -#undef CORE_FILE_P -#define CORE_FILE_P rs6000coff_core_p -extern const bfd_target * rs6000coff_core_p (); -extern boolean rs6000coff_get_section_contents (); -extern boolean rs6000coff_core_file_matches_executable_p (); - -#undef coff_core_file_matches_executable_p -#define coff_core_file_matches_executable_p \ - rs6000coff_core_file_matches_executable_p - -extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_command -#define coff_core_file_failing_command rs6000coff_core_file_failing_command - -extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_signal -#define coff_core_file_failing_signal rs6000coff_core_file_failing_signal - -#undef coff_get_section_contents -#define coff_get_section_contents rs6000coff_get_section_contents -#endif /* AIX_CORE */ - -#ifdef LYNX_CORE - -#undef CORE_FILE_P -#define CORE_FILE_P lynx_core_file_p -extern const bfd_target *lynx_core_file_p PARAMS ((bfd *abfd)); - -extern boolean lynx_core_file_matches_executable_p PARAMS ((bfd *core_bfd, - bfd *exec_bfd)); -#undef coff_core_file_matches_executable_p -#define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p - -extern char *lynx_core_file_failing_command PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_command -#define coff_core_file_failing_command lynx_core_file_failing_command - -extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_signal -#define coff_core_file_failing_signal lynx_core_file_failing_signal - -#endif /* LYNX_CORE */ - -#define _bfd_xcoff_bfd_get_relocated_section_contents \ - coff_bfd_get_relocated_section_contents -#define _bfd_xcoff_bfd_relax_section coff_bfd_relax_section -#define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section - -/* The transfer vector that leads the outside world to all of the above. */ - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - rs6000coff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "aixcoff-rs6000", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | DYNAMIC | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen??? FIXMEmgo */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - xcoff_archive_p, CORE_FILE_P}, - {bfd_false, coff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - xcoff_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (coff), - BFD_JUMP_TABLE_ARCHIVE (xcoff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (_bfd_xcoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-sh.c b/contrib/gdb/bfd/coff-sh.c deleted file mode 100644 index 17bb4b17d81..00000000000 --- a/contrib/gdb/bfd/coff-sh.c +++ /dev/null @@ -1,1525 +0,0 @@ -/* BFD back-end for Hitachi Super-H COFF binaries. - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - Written by Steve Chamberlain, . - Relaxing code written by Ian Lance Taylor, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/sh.h" -#include "coff/internal.h" -#include "libcoff.h" - -/* Internal functions. */ -static bfd_reloc_status_type sh_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static long get_symbol_value PARAMS ((asymbol *)); -static boolean sh_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); -static boolean sh_relax_delete_bytes - PARAMS ((bfd *, asection *, bfd_vma, int)); -static boolean sh_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); -static bfd_byte *sh_coff_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); - -/* Default section alignment to 2**2. */ -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) - -/* Generate long file names. */ -#define COFF_LONG_FILENAMES - -/* The supported relocations. There are a lot of relocations defined - in coff/internal.h which we do not expect to ever see. */ -static reloc_howto_type sh_coff_howtos[] = -{ - { 0 }, - { 1 }, - { 2 }, - { 3 }, /* R_SH_PCREL8 */ - { 4 }, /* R_SH_PCREL16 */ - { 5 }, /* R_SH_HIGH8 */ - { 6 }, /* R_SH_IMM24 */ - { 7 }, /* R_SH_LOW16 */ - { 8 }, - { 9 }, /* R_SH_PCDISP8BY4 */ - - HOWTO (R_SH_PCDISP8BY2, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcdisp8by2", /* name */ - true, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - true), /* pcrel_offset */ - - { 11 }, /* R_SH_PCDISP8 */ - - HOWTO (R_SH_PCDISP, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 12, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcdisp12by2", /* name */ - true, /* partial_inplace */ - 0xfff, /* src_mask */ - 0xfff, /* dst_mask */ - true), /* pcrel_offset */ - - { 13 }, - - HOWTO (R_SH_IMM32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_imm32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 15 }, - { 16 }, /* R_SH_IMM8 */ - { 17 }, /* R_SH_IMM8BY2 */ - { 18 }, /* R_SH_IMM8BY4 */ - { 19 }, /* R_SH_IMM4 */ - { 20 }, /* R_SH_IMM4BY2 */ - { 21 }, /* R_SH_IMM4BY4 */ - - HOWTO (R_SH_PCRELIMM8BY2, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_unsigned, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcrelimm8by2", /* name */ - true, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_SH_PCRELIMM8BY4, /* type */ - 2, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_unsigned, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcrelimm8by4", /* name */ - true, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_SH_IMM16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_imm16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_SWITCH16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_switch16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_SWITCH32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_switch32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_USES, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_uses", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_COUNT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_count", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_ALIGN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_align", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -#define SH_COFF_HOWTO_COUNT (sizeof sh_coff_howtos / sizeof sh_coff_howtos[0]) - -/* Check for a bad magic number. */ -#define BADMAG(x) SHBADMAG(x) - -/* Customize coffcode.h (this is not currently used). */ -#define SH 1 - -/* FIXME: This should not be set here. */ -#define __A_MAGIC_SET__ - -/* Swap the r_offset field in and out. */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 - -/* Swap out extra information in the reloc structure. */ -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - do \ - { \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; \ - } \ - while (0) - -/* Get the value of a symbol, when performing a relocation. */ - -static long -get_symbol_value (symbol) - asymbol *symbol; -{ - bfd_vma relocation; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = (symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset); - - return relocation; -} - -/* This macro is used in coffcode.h to get the howto corresponding to - an internal reloc. */ - -#define RTYPE2HOWTO(relent, internal) \ - ((relent)->howto = \ - ((internal)->r_type < SH_COFF_HOWTO_COUNT \ - ? &sh_coff_howtos[(internal)->r_type] \ - : (reloc_howto_type *) NULL)) - -/* This is the same as the macro in coffcode.h, except that it copies - r_offset into reloc_entry->addend for some relocs. */ -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if ((reloc).r_type == R_SH_SWITCH16 \ - || (reloc).r_type == R_SH_SWITCH32 \ - || (reloc).r_type == R_SH_USES \ - || (reloc).r_type == R_SH_COUNT \ - || (reloc).r_type == R_SH_ALIGN) \ - cache_ptr->addend = (reloc).r_offset; \ - } - -/* This is the howto function for the SH relocations. */ - -static bfd_reloc_status_type -sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - unsigned long insn; - bfd_vma sym_value; - unsigned short r_type; - bfd_vma addr = reloc_entry->address; - bfd_byte *hit_data = addr + (bfd_byte *) data; - - r_type = reloc_entry->howto->type; - - if (output_bfd != NULL) - { - /* Partial linking--do nothing. */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* Almost all relocs have to do with relaxing. If any work must be - done for them, it has been done in sh_relax_section. */ - if (r_type != R_SH_IMM32 - && (r_type != R_SH_PCDISP - || (symbol_in->flags & BSF_LOCAL) != 0)) - return bfd_reloc_ok; - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - return bfd_reloc_undefined; - - sym_value = get_symbol_value (symbol_in); - - switch (r_type) - { - case R_SH_IMM32: - insn = bfd_get_32 (abfd, hit_data); - insn += sym_value + reloc_entry->addend; - bfd_put_32 (abfd, insn, hit_data); - break; - case R_SH_PCDISP: - insn = bfd_get_16 (abfd, hit_data); - sym_value += reloc_entry->addend; - sym_value -= (input_section->output_section->vma - + input_section->output_offset - + addr - + 4); - sym_value += (insn & 0xfff) << 1; - if (insn & 0x800) - sym_value -= 0x1000; - insn = (insn & 0xf000) | (sym_value & 0xfff); - bfd_put_16 (abfd, insn, hit_data); - if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000) - return bfd_reloc_overflow; - break; - default: - abort (); - break; - } - - return bfd_reloc_ok; -} - -/* We can do relaxing. */ -#define coff_bfd_relax_section sh_relax_section - -/* We use the special COFF backend linker. */ -#define coff_relocate_section sh_relocate_section - -/* When relaxing, we need to use special code to get the relocated - section contents. */ -#define coff_bfd_get_relocated_section_contents \ - sh_coff_get_relocated_section_contents - -#include "coffcode.h" - -/* This function handles relaxing on the SH. - - Function calls on the SH look like this: - - movl L1,r0 - ... - jsr @r0 - ... - L1: - .long function - - The compiler and assembler will cooperate to create R_SH_USES - relocs on the jsr instructions. The r_offset field of the - R_SH_USES reloc is the PC relative offset to the instruction which - loads the register (the r_offset field is computed as though it - were a jump instruction, so the offset value is actually from four - bytes past the instruction). The linker can use this reloc to - determine just which function is being called, and thus decide - whether it is possible to replace the jsr with a bsr. - - If multiple function calls are all based on a single register load - (i.e., the same function is called multiple times), the compiler - guarantees that each function call will have an R_SH_USES reloc. - Therefore, if the linker is able to convert each R_SH_USES reloc - which refers to that address, it can safely eliminate the register - load. - - When the assembler creates an R_SH_USES reloc, it examines it to - determine which address is being loaded (L1 in the above example). - It then counts the number of references to that address, and - creates an R_SH_COUNT reloc at that address. The r_offset field of - the R_SH_COUNT reloc will be the number of references. If the - linker is able to eliminate a register load, it can use the - R_SH_COUNT reloc to see whether it can also eliminate the function - address. */ - -static boolean -sh_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - boolean *again; -{ - struct internal_reloc *internal_relocs; - struct internal_reloc *free_relocs = NULL; - struct internal_reloc *irel, *irelend; - bfd_byte *contents = NULL; - bfd_byte *free_contents = NULL; - - *again = false; - - if (link_info->relocateable - || (sec->flags & SEC_RELOC) == 0 - || sec->reloc_count == 0) - return true; - - /* If this is the first time we have been called for this section, - initialize the cooked size. */ - if (sec->_cooked_size == 0) - sec->_cooked_size = sec->_raw_size; - - internal_relocs = (_bfd_coff_read_internal_relocs - (abfd, sec, link_info->keep_memory, - (bfd_byte *) NULL, false, - (struct internal_reloc *) NULL)); - if (internal_relocs == NULL) - goto error_return; - if (! link_info->keep_memory) - free_relocs = internal_relocs; - - irelend = internal_relocs + sec->reloc_count; - for (irel = internal_relocs; irel < irelend; irel++) - { - bfd_vma laddr, paddr, symval; - unsigned short insn; - struct internal_reloc *irelfn, *irelscan, *irelcount; - struct internal_syment sym; - bfd_signed_vma foff; - - if (irel->r_type != R_SH_USES) - continue; - - /* Get the section contents. */ - if (contents == NULL) - { - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->contents != NULL) - contents = coff_section_data (abfd, sec)->contents; - else - { - contents = (bfd_byte *) bfd_malloc (sec->_raw_size); - if (contents == NULL) - goto error_return; - free_contents = contents; - - if (! bfd_get_section_contents (abfd, sec, contents, - (file_ptr) 0, sec->_raw_size)) - goto error_return; - } - } - - /* The r_offset field of the R_SH_USES reloc will point us to - the register load. The 4 is because the r_offset field is - computed as though it were a jump offset, which are based - from 4 bytes after the jump instruction. */ - laddr = irel->r_vaddr - sec->vma + 4 + irel->r_offset; - if (laddr >= sec->_raw_size) - { - (*_bfd_error_handler) ("%s: 0x%lx: warning: bad R_SH_USES offset", - bfd_get_filename (abfd), - (unsigned long) irel->r_vaddr); - continue; - } - insn = bfd_get_16 (abfd, contents + laddr); - - /* If the instruction is not mov.l NN,rN, we don't know what to - do. */ - if ((insn & 0xf000) != 0xd000) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr, insn)); - continue; - } - - /* Get the address from which the register is being loaded. The - displacement in the mov.l instruction is quadrupled. It is a - displacement from four bytes after the movl instruction, but, - before adding in the PC address, two least significant bits - of the PC are cleared. We assume that the section is aligned - on a four byte boundary. */ - paddr = insn & 0xff; - paddr *= 4; - paddr += (laddr + 4) &~ 3; - if (paddr >= sec->_raw_size) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: bad R_SH_USES load offset", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr)); - continue; - } - - /* Get the reloc for the address from which the register is - being loaded. This reloc will tell us which function is - actually being called. */ - paddr += sec->vma; - for (irelfn = internal_relocs; irelfn < irelend; irelfn++) - if (irelfn->r_vaddr == paddr - && irelfn->r_type == R_SH_IMM32) - break; - if (irelfn >= irelend) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: could not find expected reloc", - bfd_get_filename (abfd), (unsigned long) paddr)); - continue; - } - - /* Get the value of the symbol referred to by the reloc. */ - if (! _bfd_coff_get_external_symbols (abfd)) - goto error_return; - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irelfn->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_scnum != 0 && sym.n_scnum != sec->target_index) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: symbol in unexpected section", - bfd_get_filename (abfd), (unsigned long) paddr)); - continue; - } - - if (sym.n_sclass != C_EXT) - { - symval = (sym.n_value - - sec->vma - + sec->output_section->vma - + sec->output_offset); - } - else - { - struct coff_link_hash_entry *h; - - h = obj_coff_sym_hashes (abfd)[irelfn->r_symndx]; - BFD_ASSERT (h != NULL); - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - { - /* This appears to be a reference to an undefined - symbol. Just ignore it--it will be caught by the - regular reloc processing. */ - continue; - } - - symval = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - - symval += bfd_get_32 (abfd, contents + paddr - sec->vma); - - /* See if this function call can be shortened. */ - foff = (symval - - (irel->r_vaddr - - sec->vma - + sec->output_section->vma - + sec->output_offset - + 4)); - if (foff < -0x1000 || foff >= 0x1000) - { - /* After all that work, we can't shorten this function call. */ - continue; - } - - /* Shorten the function call. */ - - /* For simplicity of coding, we are going to modify the section - contents, the section relocs, and the BFD symbol table. We - must tell the rest of the code not to free up this - information. It would be possible to instead create a table - of changes which have to be made, as is done in coff-mips.c; - that would be more work, but would require less memory when - the linker is run. */ - - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (sec->used_by_bfd == NULL) - goto error_return; - } - - coff_section_data (abfd, sec)->relocs = internal_relocs; - coff_section_data (abfd, sec)->keep_relocs = true; - free_relocs = NULL; - - coff_section_data (abfd, sec)->contents = contents; - coff_section_data (abfd, sec)->keep_contents = true; - free_contents = NULL; - - obj_coff_keep_syms (abfd) = true; - - /* Replace the jsr with a bsr. */ - - /* Change the R_SH_USES reloc into an R_SH_PCDISP reloc, and - replace the jsr with a bsr. */ - irel->r_type = R_SH_PCDISP; - irel->r_symndx = irelfn->r_symndx; - if (sym.n_sclass != C_EXT) - { - /* If this needs to be changed because of future relaxing, - it will be handled here like other internal PCDISP - relocs. */ - bfd_put_16 (abfd, - 0xb000 | ((foff >> 1) & 0xfff), - contents + irel->r_vaddr - sec->vma); - } - else - { - /* We can't fully resolve this yet, because the external - symbol value may be changed by future relaxing. We let - the final link phase handle it. */ - bfd_put_16 (abfd, 0xb000, contents + irel->r_vaddr - sec->vma); - } - - /* See if there is another R_SH_USES reloc referring to the same - register load. */ - for (irelscan = internal_relocs; irelscan < irelend; irelscan++) - if (irelscan->r_type == R_SH_USES - && laddr == irelscan->r_vaddr - sec->vma + 4 + irelscan->r_offset) - break; - if (irelscan < irelend) - { - /* Some other function call depends upon this register load, - and we have not yet converted that function call. - Indeed, we may never be able to convert it. There is - nothing else we can do at this point. */ - continue; - } - - /* Look for a R_SH_COUNT reloc on the location where the - function address is stored. Do this before deleting any - bytes, to avoid confusion about the address. */ - for (irelcount = internal_relocs; irelcount < irelend; irelcount++) - if (irelcount->r_vaddr == paddr - && irelcount->r_type == R_SH_COUNT) - break; - - /* Delete the register load. */ - if (! sh_relax_delete_bytes (abfd, sec, laddr, 2)) - goto error_return; - - /* That will change things, so, just in case it permits some - other function call to come within range, we should relax - again. Note that this is not required, and it may be slow. */ - *again = true; - - /* Now check whether we got a COUNT reloc. */ - if (irelcount >= irelend) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: could not find expected COUNT reloc", - bfd_get_filename (abfd), (unsigned long) paddr)); - continue; - } - - /* The number of uses is stored in the r_offset field. We've - just deleted one. */ - if (irelcount->r_offset == 0) - { - ((*_bfd_error_handler) ("%s: 0x%lx: warning: bad count", - bfd_get_filename (abfd), - (unsigned long) paddr)); - continue; - } - - --irelcount->r_offset; - - /* If there are no more uses, we can delete the address. Reload - the address from irelfn, in case it was changed by the - previous call to sh_relax_delete_bytes. */ - if (irelcount->r_offset == 0) - { - if (! sh_relax_delete_bytes (abfd, sec, - irelfn->r_vaddr - sec->vma, 4)) - goto error_return; - } - - /* We've done all we can with that function call. */ - } - - if (free_relocs != NULL) - { - free (free_relocs); - free_relocs = NULL; - } - - if (free_contents != NULL) - { - if (! link_info->keep_memory) - free (free_contents); - else - { - /* Cache the section contents for coff_link_input_bfd. */ - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (sec->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, sec)->relocs = NULL; - } - coff_section_data (abfd, sec)->contents = contents; - } - } - - return true; - - error_return: - if (free_relocs != NULL) - free (free_relocs); - if (free_contents != NULL) - free (free_contents); - return false; -} - -/* Delete some bytes from a section while relaxing. */ - -static boolean -sh_relax_delete_bytes (abfd, sec, addr, count) - bfd *abfd; - asection *sec; - bfd_vma addr; - int count; -{ - bfd_byte *contents; - struct internal_reloc *irel, *irelend; - struct internal_reloc *irelalign; - bfd_vma toaddr; - bfd_byte *esym, *esymend; - bfd_size_type symesz; - struct coff_link_hash_entry **sym_hash; - asection *o; - - contents = coff_section_data (abfd, sec)->contents; - - /* The deletion must stop at the next ALIGN reloc for an aligment - power larger than the number of bytes we are deleting. */ - - irelalign = NULL; - toaddr = sec->_cooked_size; - - irel = coff_section_data (abfd, sec)->relocs; - irelend = irel + sec->reloc_count; - for (; irel < irelend; irel++) - { - if (irel->r_type == R_SH_ALIGN - && irel->r_vaddr - sec->vma > addr - && count < (1 << irel->r_offset)) - { - irelalign = irel; - toaddr = irel->r_vaddr - sec->vma; - break; - } - } - - /* Actually delete the bytes. */ - memmove (contents + addr, contents + addr + count, toaddr - addr - count); - if (irelalign == NULL) - sec->_cooked_size -= count; - else - memset (contents + toaddr - count, 0, count); - - /* Adjust all the relocs. */ - for (irel = coff_section_data (abfd, sec)->relocs; irel < irelend; irel++) - { - bfd_vma nraddr, start, stop; - int insn = 0; - struct internal_syment sym; - int off, adjust, oinsn; - bfd_signed_vma voff; - boolean overflow; - - /* Get the new reloc address. */ - nraddr = irel->r_vaddr - sec->vma; - if ((irel->r_vaddr - sec->vma > addr - && irel->r_vaddr - sec->vma < toaddr) - || (irel->r_type == R_SH_ALIGN - && irel->r_vaddr - sec->vma == toaddr)) - nraddr -= count; - - /* See if this reloc was for the bytes we have deleted, in which - case we no longer care about it. */ - if (irel->r_vaddr - sec->vma >= addr - && irel->r_vaddr - sec->vma < addr + count - && irel->r_type != R_SH_ALIGN) - irel->r_type = R_SH_UNUSED; - - /* If this is a PC relative reloc, see if the range it covers - includes the bytes we have deleted. */ - switch (irel->r_type) - { - default: - break; - - case R_SH_PCDISP8BY2: - case R_SH_PCDISP: - case R_SH_PCRELIMM8BY2: - case R_SH_PCRELIMM8BY4: - start = irel->r_vaddr - sec->vma; - insn = bfd_get_16 (abfd, contents + nraddr); - break; - } - - switch (irel->r_type) - { - default: - start = stop = addr; - break; - - case R_SH_IMM32: - /* If this reloc is against a symbol defined in this - section, and the symbol will not be adjusted below, we - must check the addend to see it will put the value in - range to be adjusted, and hence must be changed. */ - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irel->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_sclass != C_EXT - && sym.n_scnum == sec->target_index - && ((bfd_vma) sym.n_value <= addr - || (bfd_vma) sym.n_value >= toaddr)) - { - bfd_vma val; - - val = bfd_get_32 (abfd, contents + nraddr); - val += sym.n_value; - if (val >= addr && val < toaddr) - bfd_put_32 (abfd, val - count, contents + nraddr); - } - start = stop = addr; - break; - - case R_SH_PCDISP8BY2: - off = insn & 0xff; - if (off & 0x80) - off -= 0x100; - stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2); - break; - - case R_SH_PCDISP: - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irel->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_sclass == C_EXT) - start = stop = addr; - else - { - off = insn & 0xfff; - if (off & 0x800) - off -= 0x1000; - stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2); - } - break; - - case R_SH_PCRELIMM8BY2: - off = insn & 0xff; - stop = start + 4 + off * 2; - break; - - case R_SH_PCRELIMM8BY4: - off = insn & 0xff; - stop = (start &~ (bfd_vma) 3) + 4 + off * 4; - break; - - case R_SH_SWITCH16: - case R_SH_SWITCH32: - /* These relocs types represent - .word L2-L1 - The r_offset field holds the difference between the reloc - address and L1. That is the start of the reloc, and - adding in the contents gives us the top. We must adjust - both the r_offset field and the section contents. */ - - start = irel->r_vaddr - sec->vma; - stop = (bfd_vma) ((bfd_signed_vma) start - (long) irel->r_offset); - - if (start > addr - && start < toaddr - && (stop <= addr || stop >= toaddr)) - irel->r_offset += count; - else if (stop > addr - && stop < toaddr - && (start <= addr || start >= toaddr)) - irel->r_offset -= count; - - start = stop; - - if (irel->r_type == R_SH_SWITCH16) - voff = bfd_get_signed_16 (abfd, contents + nraddr); - else - voff = bfd_get_signed_32 (abfd, contents + nraddr); - stop = (bfd_vma) ((bfd_signed_vma) start + voff); - - break; - - case R_SH_USES: - start = irel->r_vaddr - sec->vma; - stop = (bfd_vma) ((bfd_signed_vma) start - + (long) irel->r_offset - + 4); - break; - } - - if (start > addr - && start < toaddr - && (stop <= addr || stop >= toaddr)) - adjust = count; - else if (stop > addr - && stop < toaddr - && (start <= addr || start >= toaddr)) - adjust = - count; - else - adjust = 0; - - if (adjust != 0) - { - oinsn = insn; - overflow = false; - switch (irel->r_type) - { - default: - abort (); - break; - - case R_SH_PCDISP8BY2: - case R_SH_PCRELIMM8BY2: - insn += adjust / 2; - if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); - break; - - case R_SH_PCDISP: - insn += adjust / 2; - if ((oinsn & 0xf000) != (insn & 0xf000)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); - break; - - case R_SH_PCRELIMM8BY4: - BFD_ASSERT (adjust == count || count >= 4); - if (count >= 4) - insn += adjust / 4; - else - { - if ((irel->r_vaddr & 3) == 0) - ++insn; - } - if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); - break; - - case R_SH_SWITCH16: - voff += adjust; - if (voff < - 0x8000 || voff >= 0x8000) - overflow = true; - bfd_put_signed_16 (abfd, voff, contents + nraddr); - break; - - case R_SH_SWITCH32: - voff += adjust; - bfd_put_signed_32 (abfd, voff, contents + nraddr); - break; - - case R_SH_USES: - irel->r_offset += adjust; - break; - } - - if (overflow) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: fatal: reloc overflow while relaxing", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr)); - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - irel->r_vaddr = nraddr + sec->vma; - } - - /* Look through all the other sections. If there contain any IMM32 - relocs against internal symbols which we are not going to adjust - below, we may need to adjust the addends. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *internal_relocs; - struct internal_reloc *irelscan, *irelscanend; - bfd_byte *ocontents; - - if (o == sec - || (o->flags & SEC_RELOC) == 0 - || o->reloc_count == 0) - continue; - - /* We always cache the relocs. Perhaps, if info->keep_memory is - false, we should free them, if we are permitted to, when we - leave sh_coff_relax_section. */ - internal_relocs = (_bfd_coff_read_internal_relocs - (abfd, o, true, (bfd_byte *) NULL, false, - (struct internal_reloc *) NULL)); - if (internal_relocs == NULL) - return false; - - ocontents = NULL; - irelscanend = internal_relocs + o->reloc_count; - for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++) - { - struct internal_syment sym; - - if (irelscan->r_type != R_SH_IMM32) - continue; - - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irelscan->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_sclass != C_EXT - && sym.n_scnum == sec->target_index - && ((bfd_vma) sym.n_value <= addr - || (bfd_vma) sym.n_value >= toaddr)) - { - bfd_vma val; - - if (ocontents == NULL) - { - if (coff_section_data (abfd, o)->contents != NULL) - ocontents = coff_section_data (abfd, o)->contents; - else - { - /* We always cache the section contents. - Perhaps, if info->keep_memory is false, we - should free them, if we are permitted to, - when we leave sh_coff_relax_section. */ - ocontents = (bfd_byte *) bfd_malloc (o->_raw_size); - if (ocontents == NULL) - return false; - if (! bfd_get_section_contents (abfd, o, ocontents, - (file_ptr) 0, - o->_raw_size)) - return false; - coff_section_data (abfd, o)->contents = ocontents; - } - } - - val = bfd_get_32 (abfd, ocontents + irelscan->r_vaddr - o->vma); - val += sym.n_value; - if (val >= addr && val < toaddr) - bfd_put_32 (abfd, val - count, - ocontents + irelscan->r_vaddr - o->vma); - - coff_section_data (abfd, o)->keep_contents = true; - } - } - } - - /* Adjusting the internal symbols will not work if something has - already retrieved the generic symbols. It would be possible to - make this work by adjusting the generic symbols at the same time. - However, this case should not arise in normal usage. */ - if (obj_symbols (abfd) != NULL - || obj_raw_syments (abfd) != NULL) - { - ((*_bfd_error_handler) - ("%s: fatal: generic symbols retrieved before relaxing", - bfd_get_filename (abfd))); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* Adjust all the symbols. */ - sym_hash = obj_coff_sym_hashes (abfd); - symesz = bfd_coff_symesz (abfd); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esymend = esym + obj_raw_syment_count (abfd) * symesz; - while (esym < esymend) - { - struct internal_syment isym; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym); - - if (isym.n_scnum == sec->target_index - && (bfd_vma) isym.n_value > addr - && (bfd_vma) isym.n_value < toaddr) - { - isym.n_value -= count; - - bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym); - - if (*sym_hash != NULL) - { - BFD_ASSERT ((*sym_hash)->root.type == bfd_link_hash_defined - || (*sym_hash)->root.type == bfd_link_hash_defweak); - BFD_ASSERT ((*sym_hash)->root.u.def.value >= addr - && (*sym_hash)->root.u.def.value < toaddr); - (*sym_hash)->root.u.def.value -= count; - } - } - - esym += (isym.n_numaux + 1) * symesz; - sym_hash += isym.n_numaux + 1; - } - - /* See if we can move the ALIGN reloc forward. We have adjusted - r_vaddr for it already. */ - if (irelalign != NULL) - { - bfd_vma alignaddr; - - alignaddr = BFD_ALIGN (irelalign->r_vaddr - sec->vma, - 1 << irelalign->r_offset); - if (alignaddr != toaddr) - { - /* Tail recursion. */ - return sh_relax_delete_bytes (abfd, sec, - irelalign->r_vaddr - sec->vma, - 1 << irelalign->r_offset); - } - } - - return true; -} - -/* This is a modification of _bfd_coff_generic_relocate_section, which - will handle SH relaxing. */ - -static boolean -sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, - relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - reloc_howto_type *howto; - bfd_reloc_status_type rstat; - - /* Almost all relocs have to do with relaxing. If any work must - be done for them, it has been done in sh_relax_section. */ - if (rel->r_type != R_SH_IMM32 - && rel->r_type != R_SH_PCDISP) - continue; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = obj_coff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - } - - if (sym != NULL && sym->n_scnum != 0) - addend = - sym->n_value; - else - addend = 0; - - if (rel->r_type == R_SH_PCDISP) - addend -= 4; - - if (rel->r_type >= SH_COFF_HOWTO_COUNT) - howto = NULL; - else - howto = &sh_coff_howtos[rel->r_type]; - - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - val = 0; - - if (h == NULL) - { - asection *sec; - - /* There is nothing to do for an internal PCDISP reloc. */ - if (rel->r_type == R_SH_PCDISP) - continue; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (! info->relocateable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else if (sym->_n._n_n._n_zeroes == 0 - && sym->_n._n_n._n_offset != 0) - name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; - else - { - strncpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - name = buf; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - - return true; -} - -/* This is a version of bfd_generic_get_relocated_section_contents - which uses sh_relocate_section. */ - -static bfd_byte * -sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order, - data, relocateable, symbols) - bfd *output_bfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - asection *input_section = link_order->u.indirect.section; - bfd *input_bfd = input_section->owner; - asection **sections = NULL; - struct internal_reloc *internal_relocs = NULL; - struct internal_syment *internal_syms = NULL; - - /* We only need to handle the case of relaxing, or of having a - particular set of section contents, specially. */ - if (relocateable - || coff_section_data (input_bfd, input_section) == NULL - || coff_section_data (input_bfd, input_section)->contents == NULL) - return bfd_generic_get_relocated_section_contents (output_bfd, link_info, - link_order, data, - relocateable, - symbols); - - memcpy (data, coff_section_data (input_bfd, input_section)->contents, - input_section->_raw_size); - - if ((input_section->flags & SEC_RELOC) != 0 - && input_section->reloc_count > 0) - { - bfd_size_type symesz = bfd_coff_symesz (input_bfd); - bfd_byte *esym, *esymend; - struct internal_syment *isymp; - asection **secpp; - - if (! _bfd_coff_get_external_symbols (input_bfd)) - goto error_return; - - internal_relocs = (_bfd_coff_read_internal_relocs - (input_bfd, input_section, false, (bfd_byte *) NULL, - false, (struct internal_reloc *) NULL)); - if (internal_relocs == NULL) - goto error_return; - - internal_syms = ((struct internal_syment *) - bfd_malloc (obj_raw_syment_count (input_bfd) - * sizeof (struct internal_syment))); - if (internal_syms == NULL) - goto error_return; - - sections = (asection **) bfd_malloc (obj_raw_syment_count (input_bfd) - * sizeof (asection *)); - if (sections == NULL) - goto error_return; - - isymp = internal_syms; - secpp = sections; - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esymend = esym + obj_raw_syment_count (input_bfd) * symesz; - while (esym < esymend) - { - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); - - if (isymp->n_scnum != 0) - *secpp = coff_section_from_bfd_index (input_bfd, isymp->n_scnum); - else - { - if (isymp->n_value == 0) - *secpp = bfd_und_section_ptr; - else - *secpp = bfd_com_section_ptr; - } - - esym += (isymp->n_numaux + 1) * symesz; - secpp += isymp->n_numaux + 1; - isymp += isymp->n_numaux + 1; - } - - if (! sh_relocate_section (output_bfd, link_info, input_bfd, - input_section, data, internal_relocs, - internal_syms, sections)) - goto error_return; - - free (sections); - sections = NULL; - free (internal_syms); - internal_syms = NULL; - free (internal_relocs); - internal_relocs = NULL; - } - - return data; - - error_return: - if (internal_relocs != NULL) - free (internal_relocs); - if (internal_syms != NULL) - free (internal_syms); - if (sections != NULL) - free (sections); - return NULL; -} - -/* The target vectors. */ - -const bfd_target shcoff_vec = -{ - "coff-sh", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - -const bfd_target shlcoff_vec = -{ - "coff-shl", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little endian too*/ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-sparc.c b/contrib/gdb/bfd/coff-sparc.c deleted file mode 100644 index b9bc595dc5a..00000000000 --- a/contrib/gdb/bfd/coff-sparc.c +++ /dev/null @@ -1,278 +0,0 @@ -/* BFD back-end for Sparc COFF files. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/sparc.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -#define BADMAG(x) ((x).f_magic != SPARCMAGIC && (x).f_magic != LYNXCOFFMAGIC) - -/* The page size is a guess based on ELF. */ -#define COFF_PAGE_SIZE 0x10000 - -enum reloc_type - { - R_SPARC_NONE = 0, - R_SPARC_8, R_SPARC_16, R_SPARC_32, - R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32, - R_SPARC_WDISP30, R_SPARC_WDISP22, - R_SPARC_HI22, R_SPARC_22, - R_SPARC_13, R_SPARC_LO10, - R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22, - R_SPARC_PC10, R_SPARC_PC22, - R_SPARC_WPLT30, - R_SPARC_COPY, - R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT, - R_SPARC_RELATIVE, - R_SPARC_UA32, - R_SPARC_max - }; - -#if 0 -static CONST char *CONST reloc_type_names[] = -{ - "R_SPARC_NONE", - "R_SPARC_8", "R_SPARC_16", "R_SPARC_32", - "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32", - "R_SPARC_WDISP30", "R_SPARC_WDISP22", - "R_SPARC_HI22", "R_SPARC_22", - "R_SPARC_13", "R_SPARC_LO10", - "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", - "R_SPARC_PC10", "R_SPARC_PC22", - "R_SPARC_WPLT30", - "R_SPARC_COPY", - "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", - "R_SPARC_RELATIVE", - "R_SPARC_UA32", -}; -#endif - -/* This is stolen pretty directly from elf.c. */ -static bfd_reloc_status_type -bfd_coff_generic_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -bfd_coff_generic_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -static reloc_howto_type coff_sparc_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_WPLT30", false,0,0x00000000,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_UA32", false,0,0x00000000,true), -}; - -struct coff_reloc_map { - unsigned char bfd_reloc_val; - unsigned char coff_reloc_val; -}; - -static CONST struct coff_reloc_map sparc_reloc_map[] = -{ - { BFD_RELOC_NONE, R_SPARC_NONE, }, - { BFD_RELOC_16, R_SPARC_16, }, - { BFD_RELOC_8, R_SPARC_8 }, - { BFD_RELOC_8_PCREL, R_SPARC_DISP8 }, - { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */ - { BFD_RELOC_32, R_SPARC_32 }, - { BFD_RELOC_32_PCREL, R_SPARC_DISP32 }, - { BFD_RELOC_HI22, R_SPARC_HI22 }, - { BFD_RELOC_LO10, R_SPARC_LO10, }, - { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 }, - { BFD_RELOC_SPARC22, R_SPARC_22 }, - { BFD_RELOC_SPARC13, R_SPARC_13 }, - { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 }, - { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 }, - { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 }, - { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 }, - { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 }, - { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 }, - { BFD_RELOC_SPARC_COPY, R_SPARC_COPY }, - { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT }, - { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT }, - { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE }, - { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 }, - /* { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */ -}; - -static reloc_howto_type * -coff_sparc_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct coff_reloc_map); i++) - { - if (sparc_reloc_map[i].bfd_reloc_val == code) - return &coff_sparc_howto_table[(int) sparc_reloc_map[i].coff_reloc_val]; - } - return 0; -} -#define coff_bfd_reloc_type_lookup coff_sparc_reloc_type_lookup - -static void -rtype2howto (cache_ptr, dst) - arelent *cache_ptr; - struct internal_reloc *dst; -{ - BFD_ASSERT (dst->r_type < (unsigned int) R_SPARC_max); - cache_ptr->howto = &coff_sparc_howto_table[dst->r_type]; -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -/* This is just like the standard one, except that we don't set up an - addend for relocs against global symbols (otherwise linking objects - created by -r fails), and we add in the reloc offset at the end. */ -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL \ - && (ptr->flags & BSF_GLOBAL) == 0) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - cache_ptr->addend += reloc.r_offset; \ - } - -/* Clear the r_spare field in relocs. */ -#define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \ - do { \ - dst->r_spare[0] = 0; \ - dst->r_spare[1] = 0; \ - } while (0) - -#define __A_MAGIC_SET__ - -/* Enable Sparc-specific hacks in coffcode.h. */ - -#define COFF_SPARC - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - sparccoff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-sparc", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-u68k.c b/contrib/gdb/bfd/coff-u68k.c deleted file mode 100644 index 97ea73fa9c6..00000000000 --- a/contrib/gdb/bfd/coff-u68k.c +++ /dev/null @@ -1,35 +0,0 @@ -/* BFD back-end for Motorola 68000 COFF binaries having underscore with name. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_SYM m68kcoffun_vec -#define TARGET_NAME "coff-m68k-un" - -#define NAMES_HAVE_UNDERSCORE - -/* define this to not have multiple copy of m68k_rtype2howto - in the executable file */ -#define ONLY_DECLARE_RELOCS - -/* This magic number indicates that the names have underscores. - Other 68k magic numbers indicate that the names do not have - underscores. */ -#define BADMAG(x) ((x).f_magic != MC68KBCSMAGIC) - -#include "coff-m68k.c" diff --git a/contrib/gdb/bfd/coff-w65.c b/contrib/gdb/bfd/coff-w65.c deleted file mode 100644 index a02243f1d1b..00000000000 --- a/contrib/gdb/bfd/coff-w65.c +++ /dev/null @@ -1,446 +0,0 @@ -/* BFD back-end for WDC 65816 COFF binaries. - Copyright 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/w65.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) -static reloc_howto_type howto_table[] = -{ - HOWTO (R_W65_ABS8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "abs8", true, 0x000000ff, 0x000000ff, false), - HOWTO (R_W65_ABS16, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_W65_ABS24, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs24", true, 0x00ffffff, 0x00ffffff, false), - HOWTO (R_W65_ABS8S8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, ">abs8", true, 0x000000ff, 0x000000ff, false), - HOWTO (R_W65_ABS8S16, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "^abs8", true, 0x000000ff, 0x000000ff, false), - HOWTO (R_W65_ABS16S8, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, ">abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_W65_ABS16S16,1, 0, 16, false, 0, complain_overflow_bitfield, 0, "^abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_W65_PCR8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "pcrel8", true, 0x000000ff, 0x000000ff, true), - HOWTO (R_W65_PCR16, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, true), - HOWTO (R_W65_DP, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "dp", true, 0x000000ff, 0x000000ff, false), - -}; - - -/* Turn a howto into a reloc number */ - -#define SELECT_RELOC(x,howto) \ - { x.r_type = select_reloc(howto); } - -#define BADMAG(x) (W65BADMAG(x)) -#define W65 1 /* Customize coffcode.h */ -#define __A_MAGIC_SET__ - - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - - -static int -select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type ; -} - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto (internal, dst) - arelent *internal; - struct internal_reloc *dst; -{ - internal->howto = howto_table + dst->r_type - 1; -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (((int) reloc->r_symndx) > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = (asymbol **)&(bfd_abs_symbol); - } - - - - relent->addend = reloc->r_offset; - - relent->address -= section->vma; - /* relent->section = 0;*/ -} - - -static int -h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *reloc; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - bfd_vma value; - bfd_vma dot; - bfd_vma gap; - - /* The address of the thing to be relocated will have moved back by - the size of the shrink - but we don't change reloc->address here, - since we need it to know where the relocation lives in the source - uncooked section */ - - /* reloc->address -= shrink; conceptual */ - - bfd_vma address = reloc->address - shrink; - - - switch (reloc->howto->type) - { - case R_MOVB2: - case R_JMP2: - shrink+=2; - break; - - /* Thing is a move one byte */ - case R_MOVB1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - if (value >= 0xff00) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - - break; - /* This is the 24 bit branch which could become an 8 bitter, - the relocation points to the first byte of the insn, not the - actual data */ - - case R_JMPL1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - dot ; - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 24bit, possible 8 to 8bit - possible 32 */ - reloc->howto = reloc->howto + 1; - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - - case R_JMP1: - - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - (dot - shrink); - - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - } - - - return shrink; -} - - -/* First phase of a relaxing link */ - -/* Reloc types - large small - R_MOVB1 R_MOVB2 mov.b with 16bit or 8 bit address - R_JMP1 R_JMP2 jmp or pcrel branch - R_JMPL1 R_JMPL_B8 24jmp or pcrel branch - R_MOVLB1 R_MOVLB2 24 or 8 bit reloc for mov.b - -*/ - -static void -h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, - dst_ptr) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - unsigned int src_address = *src_ptr; - unsigned int dst_address = *dst_ptr; - asection *input_section = link_order->u.indirect.section; - - switch (reloc->howto->type) - { - case R_W65_ABS8: - case R_W65_DP: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_ABS8S8: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>= 8; - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_ABS8S16: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>=16; - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_ABS16: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - case R_W65_ABS16S8: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>= 8; - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - case R_W65_ABS16S16: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>= 16; - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - - case R_W65_ABS24: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_put_16 (abfd, gap, data + dst_address); - bfd_put_8 (abfd, gap>>16, data+dst_address+2); - dst_address += 3; - src_address += 3; - } - break; - - case R_W65_PCR8: - { - int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - gap -= dot + 1; - if (gap < -128 || gap > 127) { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort(); - } - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_PCR16: - { - bfd_vma gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - - /* This wraps within the page, so ignore the relativeness, look at the - high part */ - if ((gap & 0xf0000) != (dot & 0xf0000)) { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort(); - } - - gap -= dot + 2; - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - default: - printf("ignoring reloc %s\n", reloc->howto->name); - break; - - } - *src_ptr = src_address; - *dst_ptr = dst_address; - -} - -#define coff_reloc16_extra_cases h8300_reloc16_extra_cases -#define coff_reloc16_estimate h8300_reloc16_estimate - -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - - - -bfd_target w65_vec = -{ - "coff-w65", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-we32k.c b/contrib/gdb/bfd/coff-we32k.c deleted file mode 100644 index 36f1fa17fde..00000000000 --- a/contrib/gdb/bfd/coff-we32k.c +++ /dev/null @@ -1,110 +0,0 @@ -/* BFD back-end for we32k COFF files. - Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by Brendan Kehoe (brendan@cs.widener.edu). - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/we32k.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -static reloc_howto_type howto_table[] = -{ - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - HOWTO(R_DIR32, 0, 2, 32, false, 0,complain_overflow_bitfield, 0, "dir32", true, 0xffffffff,0xffffffff, false), - {7}, - {010}, - {011}, - {012}, - {013}, - {014}, - {015}, - {016}, - HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff,0xffffffff, false), -}; - -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) WE32KBADMAG(x) -#define WE32K 1 - -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = howto_table + (dst)->r_type; - -#include "coffcode.h" - -#define coff_write_armap bsd_write_armap - -const bfd_target we32kcoff_vec = -{ - "coff-we32k", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-z8k.c b/contrib/gdb/bfd/coff-z8k.c deleted file mode 100644 index 5609d35d0f2..00000000000 --- a/contrib/gdb/bfd/coff-z8k.c +++ /dev/null @@ -1,281 +0,0 @@ -/* BFD back-end for Zilog Z800n COFF binaries. - Copyright 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support. - Written by Steve Chamberlain, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/z8k.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) - -static reloc_howto_type r_imm32 = -HOWTO (R_IMM32, 0, 1, 32, false, 0, - complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff, - 0xffffffff, false); - -static reloc_howto_type r_imm4l = -HOWTO (R_IMM4L, 0, 1, 4, false, 0, - complain_overflow_bitfield, 0, "r_imm4l", true, 0xf, 0xf, false); - -static reloc_howto_type r_da = -HOWTO (R_IMM16, 0, 1, 16, false, 0, - complain_overflow_bitfield, 0, "r_da", true, 0x0000ffff, 0x0000ffff, - false); - -static reloc_howto_type r_imm8 = -HOWTO (R_IMM8, 0, 1, 8, false, 0, - complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff, - false); - -static reloc_howto_type r_jr = -HOWTO (R_JR, 0, 1, 8, true, 0, complain_overflow_signed, 0, - "r_jr", true, 0, 0, true); - -/* Turn a howto into a reloc number */ - -static int -coff_z8k_select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type; -} - -#define SELECT_RELOC(x,howto) x.r_type = coff_z8k_select_reloc(howto) - - -#define BADMAG(x) Z8KBADMAG(x) -#define Z8K 1 /* Customize coffcode.h */ -#define __A_MAGIC_SET__ - - - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto (internal, dst) - arelent * internal; - struct internal_reloc *dst; -{ - switch (dst->r_type) - { - default: - abort (); - break; - case R_IMM8: - internal->howto = &r_imm8; - break; - case R_IMM16: - internal->howto = &r_da; - break; - case R_JR: - internal->howto = &r_jr; - break; - case R_IMM32: - internal->howto = &r_imm32; - break; - case R_IMM4L: - internal->howto = &r_imm4l; - break; - } -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (reloc->r_symndx > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - - relent->addend = reloc->r_offset; - relent->address -= section->vma; -} - -static void -extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - asection *input_section = link_order->u.indirect.section; - - switch (reloc->howto->type) - { - case R_IMM8: - bfd_put_8 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + *dst_ptr); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_IMM32: - bfd_put_32 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + *dst_ptr); - (*dst_ptr) += 4; - (*src_ptr) += 4; - break; - - case R_IMM4L: - bfd_put_8 (in_abfd, - ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0) - | (0x0f - & bfd_coff_reloc16_get_value (reloc, link_info, - input_section))), - data + *dst_ptr); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_IMM16: - bfd_put_16 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + *dst_ptr); - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_JR: - { - bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = (link_order->offset - + *dst_ptr - + input_section->output_section->vma); - int gap = dst - dot - 1;/* -1 since were in the odd byte of the - word and the pc's been incremented */ - - if (gap & 1) - abort (); - gap /= 2; - if (gap > 128 || gap < -128) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - bfd_put_8 (in_abfd, gap, data + *dst_ptr); - (*dst_ptr)++; - (*src_ptr)++; - break; - } - default: - abort (); - } -} - -#define coff_reloc16_extra_cases extra_case - -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - -const bfd_target z8kcoff_vec = -{ - "coff-z8k", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coffcode.h b/contrib/gdb/bfd/coffcode.h deleted file mode 100644 index 22babd0d0c7..00000000000 --- a/contrib/gdb/bfd/coffcode.h +++ /dev/null @@ -1,3612 +0,0 @@ -/* Support for the generic parts of most COFF variants, for BFD. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -Most of this hacked by Steve Chamberlain, - sac@cygnus.com -*/ -/* - -SECTION - coff backends - - BFD supports a number of different flavours of coff format. - The major differences between formats are the sizes and - alignments of fields in structures on disk, and the occasional - extra field. - - Coff in all its varieties is implemented with a few common - files and a number of implementation specific files. For - example, The 88k bcs coff format is implemented in the file - @file{coff-m88k.c}. This file @code{#include}s - @file{coff/m88k.h} which defines the external structure of the - coff format for the 88k, and @file{coff/internal.h} which - defines the internal structure. @file{coff-m88k.c} also - defines the relocations used by the 88k format - @xref{Relocations}. - - The Intel i960 processor version of coff is implemented in - @file{coff-i960.c}. This file has the same structure as - @file{coff-m88k.c}, except that it includes @file{coff/i960.h} - rather than @file{coff-m88k.h}. - -SUBSECTION - Porting to a new version of coff - - The recommended method is to select from the existing - implementations the version of coff which is most like the one - you want to use. For example, we'll say that i386 coff is - the one you select, and that your coff flavour is called foo. - Copy @file{i386coff.c} to @file{foocoff.c}, copy - @file{../include/coff/i386.h} to @file{../include/coff/foo.h}, - and add the lines to @file{targets.c} and @file{Makefile.in} - so that your new back end is used. Alter the shapes of the - structures in @file{../include/coff/foo.h} so that they match - what you need. You will probably also have to add - @code{#ifdef}s to the code in @file{coff/internal.h} and - @file{coffcode.h} if your version of coff is too wild. - - You can verify that your new BFD backend works quite simply by - building @file{objdump} from the @file{binutils} directory, - and making sure that its version of what's going on and your - host system's idea (assuming it has the pretty standard coff - dump utility, usually called @code{att-dump} or just - @code{dump}) are the same. Then clean up your code, and send - what you've done to Cygnus. Then your stuff will be in the - next release, and you won't have to keep integrating it. - -SUBSECTION - How the coff backend works - -SUBSUBSECTION - File layout - - The Coff backend is split into generic routines that are - applicable to any Coff target and routines that are specific - to a particular target. The target-specific routines are - further split into ones which are basically the same for all - Coff targets except that they use the external symbol format - or use different values for certain constants. - - The generic routines are in @file{coffgen.c}. These routines - work for any Coff target. They use some hooks into the target - specific code; the hooks are in a @code{bfd_coff_backend_data} - structure, one of which exists for each target. - - The essentially similar target-specific routines are in - @file{coffcode.h}. This header file includes executable C code. - The various Coff targets first include the appropriate Coff - header file, make any special defines that are needed, and - then include @file{coffcode.h}. - - Some of the Coff targets then also have additional routines in - the target source file itself. - - For example, @file{coff-i960.c} includes - @file{coff/internal.h} and @file{coff/i960.h}. It then - defines a few constants, such as @code{I960}, and includes - @file{coffcode.h}. Since the i960 has complex relocation - types, @file{coff-i960.c} also includes some code to - manipulate the i960 relocs. This code is not in - @file{coffcode.h} because it would not be used by any other - target. - -SUBSUBSECTION - Bit twiddling - - Each flavour of coff supported in BFD has its own header file - describing the external layout of the structures. There is also - an internal description of the coff layout, in - @file{coff/internal.h}. A major function of the - coff backend is swapping the bytes and twiddling the bits to - translate the external form of the structures into the normal - internal form. This is all performed in the - @code{bfd_swap}_@i{thing}_@i{direction} routines. Some - elements are different sizes between different versions of - coff; it is the duty of the coff version specific include file - to override the definitions of various packing routines in - @file{coffcode.h}. E.g., the size of line number entry in coff is - sometimes 16 bits, and sometimes 32 bits. @code{#define}ing - @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the - correct one. No doubt, some day someone will find a version of - coff which has a varying field size not catered to at the - moment. To port BFD, that person will have to add more @code{#defines}. - Three of the bit twiddling routines are exported to - @code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in} - and @code{coff_swap_linno_in}. @code{GDB} reads the symbol - table on its own, but uses BFD to fix things up. More of the - bit twiddlers are exported for @code{gas}; - @code{coff_swap_aux_out}, @code{coff_swap_sym_out}, - @code{coff_swap_lineno_out}, @code{coff_swap_reloc_out}, - @code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out}, - @code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track - of all the symbol table and reloc drudgery itself, thereby - saving the internal BFD overhead, but uses BFD to swap things - on the way out, making cross ports much safer. Doing so also - allows BFD (and thus the linker) to use the same header files - as @code{gas}, which makes one avenue to disaster disappear. - -SUBSUBSECTION - Symbol reading - - The simple canonical form for symbols used by BFD is not rich - enough to keep all the information available in a coff symbol - table. The back end gets around this problem by keeping the original - symbol table around, "behind the scenes". - - When a symbol table is requested (through a call to - @code{bfd_canonicalize_symtab}), a request gets through to - @code{coff_get_normalized_symtab}. This reads the symbol table from - the coff file and swaps all the structures inside into the - internal form. It also fixes up all the pointers in the table - (represented in the file by offsets from the first symbol in - the table) into physical pointers to elements in the new - internal table. This involves some work since the meanings of - fields change depending upon context: a field that is a - pointer to another structure in the symbol table at one moment - may be the size in bytes of a structure at the next. Another - pass is made over the table. All symbols which mark file names - (<> symbols) are modified so that the internal - string points to the value in the auxent (the real filename) - rather than the normal text associated with the symbol - (@code{".file"}). - - At this time the symbol names are moved around. Coff stores - all symbols less than nine characters long physically - within the symbol table; longer strings are kept at the end of - the file in the string table. This pass moves all strings - into memory and replaces them with pointers to the strings. - - - The symbol table is massaged once again, this time to create - the canonical table used by the BFD application. Each symbol - is inspected in turn, and a decision made (using the - @code{sclass} field) about the various flags to set in the - @code{asymbol}. @xref{Symbols}. The generated canonical table - shares strings with the hidden internal symbol table. - - Any linenumbers are read from the coff file too, and attached - to the symbols which own the functions the linenumbers belong to. - -SUBSUBSECTION - Symbol writing - - Writing a symbol to a coff file which didn't come from a coff - file will lose any debugging information. The @code{asymbol} - structure remembers the BFD from which the symbol was taken, and on - output the back end makes sure that the same destination target as - source target is present. - - When the symbols have come from a coff file then all the - debugging information is preserved. - - Symbol tables are provided for writing to the back end in a - vector of pointers to pointers. This allows applications like - the linker to accumulate and output large symbol tables - without having to do too much byte copying. - - This function runs through the provided symbol table and - patches each symbol marked as a file place holder - (@code{C_FILE}) to point to the next file place holder in the - list. It also marks each @code{offset} field in the list with - the offset from the first symbol of the current symbol. - - Another function of this procedure is to turn the canonical - value form of BFD into the form used by coff. Internally, BFD - expects symbol values to be offsets from a section base; so a - symbol physically at 0x120, but in a section starting at - 0x100, would have the value 0x20. Coff expects symbols to - contain their final value, so symbols have their values - changed at this point to reflect their sum with their owning - section. This transformation uses the - <> field of the @code{asymbol}'s - @code{asection} @xref{Sections}. - - o <> - - This routine runs though the provided symbol table and uses - the offsets generated by the previous pass and the pointers - generated when the symbol table was read in to create the - structured hierachy required by coff. It changes each pointer - to a symbol into the index into the symbol table of the asymbol. - - o <> - - This routine runs through the symbol table and patches up the - symbols from their internal form into the coff way, calls the - bit twiddlers, and writes out the table to the file. - -*/ - -/* -INTERNAL_DEFINITION - coff_symbol_type - -DESCRIPTION - The hidden information for an <> is described in a - <>: - -CODE_FRAGMENT -. -.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. *} -.unsigned int fix_tag : 1; -. -. {* Should the endidx field of this symbol be renumbered. -. Created by coff_pointerize_aux. *} -.unsigned int fix_end : 1; -. -. {* Should the x_csect.x_scnlen field be renumbered. -. Created by coff_pointerize_aux. *} -.unsigned int fix_scnlen : 1; -. -. {* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the -. index into the line number entries. Set by -. coff_slurp_symbol_table. *} -.unsigned int fix_line : 1; -. -. {* The container for the symbol structure as read and translated -. from the file. *} -. -.union { -. union internal_auxent auxent; -. struct internal_syment syment; -. } u; -.} combined_entry_type; -. -. -.{* Each canonical asymbol really looks like this: *} -. -.typedef struct coff_symbol_struct -.{ -. {* The actual symbol which the rest of BFD works with *} -.asymbol symbol; -. -. {* A pointer to the hidden information for this symbol *} -.combined_entry_type *native; -. -. {* A pointer to the linenumber information for this symbol *} -.struct lineno_cache_entry *lineno; -. -. {* Have the line numbers been relocated yet ? *} -.boolean done_lineno; -.} coff_symbol_type; - - -*/ - -#ifdef COFF_WITH_PE -#include "peicode.h" -#else -#include "coffswap.h" -#endif - - -/* void warning(); */ - -/* - * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the - * incoming SEC_* flags. The inverse of this function is styp_to_sec_flags(). - * NOTE: If you add to/change this routine, you should mirror the changes - * in styp_to_sec_flags(). - */ -static long -sec_to_styp_flags (sec_name, sec_flags) - CONST char *sec_name; - flagword sec_flags; -{ - long styp_flags = 0; - - if (!strcmp (sec_name, _TEXT)) - { - styp_flags = STYP_TEXT; - } - else if (!strcmp (sec_name, _DATA)) - { - styp_flags = STYP_DATA; - } - else if (!strcmp (sec_name, _BSS)) - { - styp_flags = STYP_BSS; -#ifdef _COMMENT - } - else if (!strcmp (sec_name, _COMMENT)) - { - styp_flags = STYP_INFO; -#endif /* _COMMENT */ -#ifdef _LIB - } - else if (!strcmp (sec_name, _LIB)) - { - styp_flags = STYP_LIB; -#endif /* _LIB */ -#ifdef _LIT - } - else if (!strcmp (sec_name, _LIT)) - { - styp_flags = STYP_LIT; -#endif /* _LIT */ - } - else if (!strcmp (sec_name, ".debug")) - { -#ifdef STYP_DEBUG - styp_flags = STYP_DEBUG; -#else - styp_flags = STYP_INFO; -#endif - } - else if (!strncmp (sec_name, ".stab", 5)) - { - styp_flags = STYP_INFO; - } -#ifdef COFF_WITH_PE - else if (!strcmp (sec_name, ".edata")) - { - styp_flags = STYP_DATA; - } -#endif -#ifdef RS6000COFF_C - else if (!strcmp (sec_name, _PAD)) - { - styp_flags = STYP_PAD; - } - else if (!strcmp (sec_name, _LOADER)) - { - styp_flags = STYP_LOADER; - } -#endif - /* Try and figure out what it should be */ - else if (sec_flags & SEC_CODE) - { - styp_flags = STYP_TEXT; - } - else if (sec_flags & SEC_DATA) - { - styp_flags = STYP_DATA; - } - else if (sec_flags & SEC_READONLY) - { -#ifdef STYP_LIT /* 29k readonly text/data section */ - styp_flags = STYP_LIT; -#else - styp_flags = STYP_TEXT; -#endif /* STYP_LIT */ - } - else if (sec_flags & SEC_LOAD) - { - styp_flags = STYP_TEXT; - } - else if (sec_flags & SEC_ALLOC) - { - styp_flags = STYP_BSS; - } - -#ifdef STYP_NOLOAD - if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0) - styp_flags |= STYP_NOLOAD; -#endif - - return (styp_flags); -} -/* - * Return a word with SEC_* flags set to represent the incoming - * STYP_* flags (from scnhdr.s_flags). The inverse of this - * function is sec_to_styp_flags(). - * NOTE: If you add to/change this routine, you should mirror the changes - * in sec_to_styp_flags(). - */ -static flagword -styp_to_sec_flags (abfd, hdr, name) - bfd *abfd; - PTR hdr; - const char *name; -{ - struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; - long styp_flags = internal_s->s_flags; - flagword sec_flags = 0; - -#ifdef STYP_NOLOAD - if (styp_flags & STYP_NOLOAD) - { - sec_flags |= SEC_NEVER_LOAD; - } -#endif /* STYP_NOLOAD */ - - /* For 386 COFF, at least, an unloadable text or data section is - actually a shared library section. */ - if (styp_flags & STYP_TEXT) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; - } - else if (styp_flags & STYP_DATA) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; - } - else if (styp_flags & STYP_BSS) - { -#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY; - else -#endif - sec_flags |= SEC_ALLOC; - } - else if (styp_flags & STYP_INFO) - { - /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is - defined. coff_compute_section_file_positions uses - COFF_PAGE_SIZE to ensure that the low order bits of the - section VMA and the file offset match. If we don't know - COFF_PAGE_SIZE, we can't ensure the correct correspondence, - and demand page loading of the file will fail. */ -#ifdef COFF_PAGE_SIZE - sec_flags |= SEC_DEBUGGING; -#endif - } - else if (styp_flags & STYP_PAD) - { - sec_flags = 0; - } - else if (strcmp (name, _TEXT) == 0) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; - } - else if (strcmp (name, _DATA) == 0) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; - } - else if (strcmp (name, _BSS) == 0) - { -#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY; - else -#endif - sec_flags |= SEC_ALLOC; - } - else if (strcmp (name, ".debug") == 0 -#ifdef _COMMENT - || strcmp (name, _COMMENT) == 0 -#endif - || strncmp (name, ".stab", 5) == 0) - { -#ifdef COFF_PAGE_SIZE - sec_flags |= SEC_DEBUGGING; -#endif - } -#ifdef _LIB - else if (strcmp (name, _LIB) == 0) - ; -#endif -#ifdef _LIT - else if (strcmp (name, _LIT) == 0) - { - sec_flags = SEC_LOAD | SEC_ALLOC | SEC_READONLY; - } -#endif - else - { - sec_flags |= SEC_ALLOC | SEC_LOAD; - } - -#ifdef STYP_LIT /* A29k readonly text/data section type */ - if ((styp_flags & STYP_LIT) == STYP_LIT) - { - sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY); - } -#endif /* STYP_LIT */ -#ifdef STYP_OTHER_LOAD /* Other loaded sections */ - if (styp_flags & STYP_OTHER_LOAD) - { - sec_flags = (SEC_LOAD | SEC_ALLOC); - } -#endif /* STYP_SDATA */ - - return (sec_flags); -} - -#define get_index(symbol) ((symbol)->udata.i) - -/* -INTERNAL_DEFINITION - bfd_coff_backend_data - -CODE_FRAGMENT - -Special entry points for gdb to swap in coff symbol table parts: -.typedef struct -.{ -. void (*_bfd_coff_swap_aux_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. int type, -. int class, -. int indaux, -. int numaux, -. PTR in)); -. -. void (*_bfd_coff_swap_sym_in) PARAMS (( -. bfd *abfd , -. PTR ext, -. PTR in)); -. -. void (*_bfd_coff_swap_lineno_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. - -Special entry points for gas to swap out coff parts: - -. unsigned int (*_bfd_coff_swap_aux_out) PARAMS (( -. bfd *abfd, -. PTR in, -. int type, -. int class, -. int indaux, -. int numaux, -. PTR ext)); -. -. unsigned int (*_bfd_coff_swap_sym_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR ext)); -. -. unsigned int (*_bfd_coff_swap_lineno_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR ext)); -. -. unsigned int (*_bfd_coff_swap_reloc_out) PARAMS (( -. bfd *abfd, -. PTR src, -. PTR dst)); -. -. unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR out)); -. -. unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR out)); -. -. unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR out)); -. - -Special entry points for generic COFF routines to call target -dependent COFF routines: - -. unsigned int _bfd_filhsz; -. unsigned int _bfd_aoutsz; -. unsigned int _bfd_scnhsz; -. unsigned int _bfd_symesz; -. unsigned int _bfd_auxesz; -. unsigned int _bfd_relsz; -. unsigned int _bfd_linesz; -. boolean _bfd_coff_long_filenames; -. void (*_bfd_coff_swap_filehdr_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. void (*_bfd_coff_swap_aouthdr_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. void (*_bfd_coff_swap_scnhdr_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. void (*_bfd_coff_swap_reloc_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. boolean (*_bfd_coff_bad_format_hook) PARAMS (( -. bfd *abfd, -. PTR internal_filehdr)); -. boolean (*_bfd_coff_set_arch_mach_hook) PARAMS (( -. bfd *abfd, -. PTR internal_filehdr)); -. PTR (*_bfd_coff_mkobject_hook) PARAMS (( -. bfd *abfd, -. PTR internal_filehdr, -. PTR internal_aouthdr)); -. flagword (*_bfd_styp_to_sec_flags_hook) PARAMS (( -. bfd *abfd, -. PTR internal_scnhdr, -. const char *name)); -. void (*_bfd_set_alignment_hook) PARAMS (( -. bfd *abfd, -. asection *sec, -. PTR internal_scnhdr)); -. boolean (*_bfd_coff_slurp_symbol_table) PARAMS (( -. bfd *abfd)); -. boolean (*_bfd_coff_symname_in_debug) PARAMS (( -. bfd *abfd, -. struct internal_syment *sym)); -. boolean (*_bfd_coff_pointerize_aux_hook) PARAMS (( -. bfd *abfd, -. combined_entry_type *table_base, -. combined_entry_type *symbol, -. unsigned int indaux, -. combined_entry_type *aux)); -. boolean (*_bfd_coff_print_aux) PARAMS (( -. bfd *abfd, -. FILE *file, -. combined_entry_type *table_base, -. combined_entry_type *symbol, -. combined_entry_type *aux, -. unsigned int indaux)); -. void (*_bfd_coff_reloc16_extra_cases) PARAMS (( -. bfd *abfd, -. struct bfd_link_info *link_info, -. struct bfd_link_order *link_order, -. arelent *reloc, -. bfd_byte *data, -. unsigned int *src_ptr, -. unsigned int *dst_ptr)); -. int (*_bfd_coff_reloc16_estimate) PARAMS (( -. bfd *abfd, -. asection *input_section, -. arelent *r, -. unsigned int shrink, -. struct bfd_link_info *link_info)); -. boolean (*_bfd_coff_sym_is_global) PARAMS (( -. bfd *abfd, -. struct internal_syment *)); -. void (*_bfd_coff_compute_section_file_positions) PARAMS (( -. bfd *abfd)); -. boolean (*_bfd_coff_start_final_link) PARAMS (( -. bfd *output_bfd, -. struct bfd_link_info *info)); -. boolean (*_bfd_coff_relocate_section) PARAMS (( -. bfd *output_bfd, -. struct bfd_link_info *info, -. bfd *input_bfd, -. asection *input_section, -. bfd_byte *contents, -. struct internal_reloc *relocs, -. struct internal_syment *syms, -. asection **sections)); -. reloc_howto_type *(*_bfd_coff_rtype_to_howto) PARAMS (( -. bfd *abfd, -. asection *sec, -. struct internal_reloc *rel, -. struct coff_link_hash_entry *h, -. struct internal_syment *sym, -. bfd_vma *addendp)); -. boolean (*_bfd_coff_adjust_symndx) PARAMS (( -. bfd *obfd, -. struct bfd_link_info *info, -. bfd *ibfd, -. asection *sec, -. struct internal_reloc *reloc, -. boolean *adjustedp)); -. boolean (*_bfd_coff_link_add_one_symbol) PARAMS (( -. struct bfd_link_info *info, -. bfd *abfd, -. const char *name, -. flagword flags, -. asection *section, -. bfd_vma value, -. const char *string, -. boolean copy, -. boolean collect, -. struct bfd_link_hash_entry **hashp)); -. -.} 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,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)) -. -.#define bfd_coff_swap_lineno_in(a,e,i) \ -. ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) -. -.#define bfd_coff_swap_reloc_out(abfd, i, o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) -. -.#define bfd_coff_swap_lineno_out(abfd, i, o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) -. -.#define bfd_coff_swap_aux_out(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)) -. -.#define bfd_coff_swap_scnhdr_out(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) -. -.#define bfd_coff_swap_filehdr_out(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) -. -.#define bfd_coff_swap_aouthdr_out(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) -. -.#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) -.#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) -.#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) -.#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) -.#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) -.#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz) -.#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) -.#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames) -.#define bfd_coff_swap_filehdr_in(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) -. -.#define bfd_coff_swap_aouthdr_in(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) -. -.#define bfd_coff_swap_scnhdr_in(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) -. -.#define bfd_coff_swap_reloc_in(abfd, i, o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o)) -. -.#define bfd_coff_bad_format_hook(abfd, filehdr) \ -. ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) -. -.#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ -. ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) -.#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ -. ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr)) -. -.#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name)\ -. ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr, name)) -. -.#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ -. ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) -. -.#define bfd_coff_slurp_symbol_table(abfd)\ -. ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) -. -.#define bfd_coff_symname_in_debug(abfd, sym)\ -. ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) -. -.#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\ -. ((coff_backend_info (abfd)->_bfd_coff_print_aux)\ -. (abfd, file, base, symbol, aux, indaux)) -. -.#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, link_info, link_order, reloc, data, src_ptr, dst_ptr)) -. -.#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ -. ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ -. (abfd, section, reloc, shrink, link_info)) -. -.#define bfd_coff_sym_is_global(abfd, sym)\ -. ((coff_backend_info (abfd)->_bfd_coff_sym_is_global)\ -. (abfd, sym)) -. -.#define bfd_coff_compute_section_file_positions(abfd)\ -. ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\ -. (abfd)) -. -.#define bfd_coff_start_final_link(obfd, info)\ -. ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\ -. (obfd, info)) -.#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\ -. ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\ -. (obfd, info, ibfd, o, con, rel, isyms, secs)) -.#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\ -. ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\ -. (abfd, sec, rel, h, sym, addendp)) -.#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ -. ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ -. (obfd, info, ibfd, sec, rel, adjustedp)) -.#define bfd_coff_link_add_one_symbol(info,abfd,name,flags,section,value,string,cp,coll,hashp)\ -. ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ -. (info, abfd, name, flags, section, value, string, cp, coll, hashp)) -. -*/ - -/* See whether the magic number matches. */ - -static boolean -coff_bad_format_hook (abfd, filehdr) - bfd * abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - if (BADMAG (*internal_f)) - return false; - - /* if the optional header is NULL or not the correct size then - quit; the only difference I can see between m88k dgux headers (MC88DMAGIC) - and Intel 960 readwrite headers (I960WRMAGIC) is that the - optional header is of a different size. - - But the mips keeps extra stuff in it's opthdr, so dont check - when doing that - */ - -#if defined(M88) || defined(I960) - if (internal_f->f_opthdr != 0 && AOUTSZ != internal_f->f_opthdr) - return false; -#endif - - return true; -} - -/* - initialize a section structure with information peculiar to this - particular implementation of coff -*/ - -static boolean -coff_new_section_hook (abfd, section) - bfd * abfd; - asection * section; -{ - section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER; - -#ifdef RS6000COFF_C - if (xcoff_data (abfd)->text_align_power != 0 - && strcmp (bfd_get_section_name (abfd, section), ".text") == 0) - section->alignment_power = xcoff_data (abfd)->text_align_power; - if (xcoff_data (abfd)->data_align_power != 0 - && strcmp (bfd_get_section_name (abfd, section), ".data") == 0) - section->alignment_power = xcoff_data (abfd)->data_align_power; -#endif - - /* Allocate aux records for section symbols, to store size and - related info. - - @@ Shouldn't use constant multiplier here! */ - coffsymbol (section->symbol)->native = - (combined_entry_type *) bfd_zalloc (abfd, - sizeof (combined_entry_type) * 10); - - /* The .stab section must be aligned to 2**2 at most, because - otherwise there may be gaps in the section which gdb will not - know how to interpret. Examining the section name is a hack, but - that is also how gdb locates the section. - We need to handle the .ctors and .dtors sections similarly, to - avoid introducing null words in the tables. */ - if (COFF_DEFAULT_SECTION_ALIGNMENT_POWER > 2 - && (strncmp (section->name, ".stab", 5) == 0 - || strcmp (section->name, ".ctors") == 0 - || strcmp (section->name, ".dtors") == 0)) - section->alignment_power = 2; - - /* Similarly, the .stabstr section must be aligned to 2**0 at most. */ - if (COFF_DEFAULT_SECTION_ALIGNMENT_POWER > 0 - && strncmp (section->name, ".stabstr", 8) == 0) - section->alignment_power = 0; - - return true; -} - -#ifdef I960 - -/* Set the alignment of a BFD section. */ - -static void -coff_set_alignment_hook (abfd, section, scnhdr) - bfd * abfd; - asection * section; - PTR scnhdr; -{ - struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr; - unsigned int i; - - for (i = 0; i < 32; i++) - if ((1 << i) >= hdr->s_align) - break; - section->alignment_power = i; -} - -#else /* ! I960 */ -#ifdef COFF_WITH_PE - -/* a couple of macros to help setting the alignment power field */ -#define ALIGN_SET(field,x,y) \ - if (((field) & IMAGE_SCN_ALIGN_64BYTES) == x )\ - {\ - section->alignment_power = y;\ - } - -#define ELIFALIGN_SET(field,x,y) \ - else if (( (field) & IMAGE_SCN_ALIGN_64BYTES) == x ) \ - {\ - section->alignment_power = y;\ - } - -static void -coff_set_alignment_hook (abfd, section, scnhdr) - bfd * abfd; - asection * section; - PTR scnhdr; -{ - struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr; - - ALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_64BYTES, 6) - ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_32BYTES, 5) - ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_16BYTES, 4) - ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_8BYTES, 3) - ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_4BYTES, 2) - ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_2BYTES, 1) - ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_1BYTES, 0) - -#ifdef POWERPC_LE_PE - if (strcmp (section->name, ".idata$2") == 0) - { - section->alignment_power = 0; - } - else if (strcmp (section->name, ".idata$3") == 0) - { - section->alignment_power = 0; - } - else if (strcmp (section->name, ".idata$4") == 0) - { - section->alignment_power = 2; - } - else if (strcmp (section->name, ".idata$5") == 0) - { - section->alignment_power = 2; - } - else if (strcmp (section->name, ".idata$6") == 0) - { - section->alignment_power = 1; - } - else if (strcmp (section->name, ".reloc") == 0) - { - section->alignment_power = 1; - } - else if (strncmp (section->name, ".stab", 5) == 0) - { - section->alignment_power = 2; - } -#endif -} -#undef ALIGN_SET -#undef ELIFALIGN_SET - -#else /* ! COFF_WITH_PE */ -#ifdef RS6000COFF_C - -/* We grossly abuse this function to handle XCOFF overflow headers. - When we see one, we correct the reloc and line number counts in the - real header, and remove the section we just created. */ - -static void -coff_set_alignment_hook (abfd, section, scnhdr) - bfd *abfd; - asection *section; - PTR scnhdr; -{ - struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr; - asection *real_sec; - asection **ps; - - if ((hdr->s_flags & STYP_OVRFLO) == 0) - return; - - real_sec = coff_section_from_bfd_index (abfd, hdr->s_nreloc); - if (real_sec == NULL) - return; - - real_sec->reloc_count = hdr->s_paddr; - real_sec->lineno_count = hdr->s_vaddr; - - for (ps = &abfd->sections; *ps != NULL; ps = &(*ps)->next) - { - if (*ps == section) - { - *ps = (*ps)->next; - --abfd->section_count; - break; - } - } -} - -#else /* ! RS6000COFF_C */ - -#define coff_set_alignment_hook \ - ((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void) - -#endif /* ! RS6000COFF_C */ -#endif /* ! COFF_WITH_PE */ -#endif /* ! I960 */ - -#ifndef coff_mkobject -static boolean -coff_mkobject (abfd) - bfd * abfd; -{ - coff_data_type *coff; - - abfd->tdata.coff_obj_data = (struct coff_tdata *) bfd_zalloc (abfd, sizeof (coff_data_type)); - if (abfd->tdata.coff_obj_data == 0) - return false; - coff = coff_data (abfd); - coff->symbols = (coff_symbol_type *) NULL; - coff->conversion_table = (unsigned int *) NULL; - coff->raw_syments = (struct coff_ptr_struct *) NULL; - coff->relocbase = 0; - coff->local_toc_sym_map = 0; - -/* make_abs_section(abfd);*/ - - return true; -} -#endif - -/* Create the COFF backend specific information. */ -#ifndef coff_mkobject_hook -static PTR -coff_mkobject_hook (abfd, filehdr, aouthdr) - bfd * abfd; - PTR filehdr; - PTR aouthdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - coff_data_type *coff; - - if (coff_mkobject (abfd) == false) - return NULL; - - coff = coff_data (abfd); - - coff->sym_filepos = internal_f->f_symptr; - - /* These members communicate important constants about the symbol - table to GDB's symbol-reading code. These `constants' - unfortunately vary among coff implementations... */ - coff->local_n_btmask = N_BTMASK; - coff->local_n_btshft = N_BTSHFT; - coff->local_n_tmask = N_TMASK; - coff->local_n_tshift = N_TSHIFT; - coff->local_symesz = SYMESZ; - coff->local_auxesz = AUXESZ; - coff->local_linesz = LINESZ; - - obj_raw_syment_count (abfd) = - obj_conv_table_size (abfd) = - internal_f->f_nsyms; - -#ifdef RS6000COFF_C - if ((internal_f->f_flags & F_SHROBJ) != 0) - abfd->flags |= DYNAMIC; - if (aouthdr != NULL && internal_f->f_opthdr >= AOUTSZ) - { - struct internal_aouthdr *internal_a = - (struct internal_aouthdr *) aouthdr; - struct xcoff_tdata *xcoff; - - xcoff = xcoff_data (abfd); - xcoff->full_aouthdr = true; - xcoff->toc = internal_a->o_toc; - xcoff->sntoc = internal_a->o_sntoc; - xcoff->snentry = internal_a->o_snentry; - xcoff->text_align_power = internal_a->o_algntext; - xcoff->data_align_power = internal_a->o_algndata; - xcoff->modtype = internal_a->o_modtype; - xcoff->cputype = internal_a->o_cputype; - xcoff->maxdata = internal_a->o_maxdata; - xcoff->maxstack = internal_a->o_maxstack; - } -#endif - - return (PTR) coff; -} -#endif - -/* Determine the machine architecture and type. FIXME: This is target - dependent because the magic numbers are defined in the target - dependent header files. But there is no particular need for this. - If the magic numbers were moved to a separate file, this function - would be target independent and would also be much more successful - at linking together COFF files for different architectures. */ - -static boolean -coff_set_arch_mach_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - long machine; - enum bfd_architecture arch; - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - machine = 0; - switch (internal_f->f_magic) - { -#ifdef PPCMAGIC - case PPCMAGIC: - arch = bfd_arch_powerpc; - machine = 0; /* what does this mean? (krk) */ - break; -#endif -#ifdef I386MAGIC - case I386MAGIC: - case I386PTXMAGIC: - case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler */ - case LYNXCOFFMAGIC: /* shadows the m68k Lynx number below, sigh */ - arch = bfd_arch_i386; - machine = 0; - break; -#endif -#ifdef A29K_MAGIC_BIG - case A29K_MAGIC_BIG: - case A29K_MAGIC_LITTLE: - arch = bfd_arch_a29k; - machine = 0; - break; -#endif -#ifdef ARMMAGIC - case ARMMAGIC: - arch = bfd_arch_arm; - machine =0; - break; -#endif -#ifdef MC68MAGIC - case MC68MAGIC: - case M68MAGIC: -#ifdef MC68KBCSMAGIC - case MC68KBCSMAGIC: -#endif -#ifdef APOLLOM68KMAGIC - case APOLLOM68KMAGIC: -#endif -#ifdef LYNXCOFFMAGIC - case LYNXCOFFMAGIC: -#endif - arch = bfd_arch_m68k; - machine = 68020; - break; -#endif -#ifdef MC88MAGIC - case MC88MAGIC: - case MC88DMAGIC: - case MC88OMAGIC: - arch = bfd_arch_m88k; - machine = 88100; - break; -#endif -#ifdef Z8KMAGIC - case Z8KMAGIC: - arch = bfd_arch_z8k; - switch (internal_f->f_flags & F_MACHMASK) - { - case F_Z8001: - machine = bfd_mach_z8001; - break; - case F_Z8002: - machine = bfd_mach_z8002; - break; - default: - return false; - } - break; -#endif -#ifdef I860 - case I860MAGIC: - arch = bfd_arch_i860; - break; -#endif -#ifdef I960 -#ifdef I960ROMAGIC - case I960ROMAGIC: - case I960RWMAGIC: - arch = bfd_arch_i960; - switch (F_I960TYPE & internal_f->f_flags) - { - default: - case F_I960CORE: - machine = bfd_mach_i960_core; - break; - case F_I960KB: - machine = bfd_mach_i960_kb_sb; - break; - case F_I960MC: - machine = bfd_mach_i960_mc; - break; - case F_I960XA: - machine = bfd_mach_i960_xa; - break; - case F_I960CA: - machine = bfd_mach_i960_ca; - break; - case F_I960KA: - machine = bfd_mach_i960_ka_sa; - break; - case F_I960JX: - machine = bfd_mach_i960_jx; - break; - case F_I960HX: - machine = bfd_mach_i960_hx; - break; - } - break; -#endif -#endif - -#ifdef RS6000COFF_C - case U802ROMAGIC: - case U802WRMAGIC: - case U802TOCMAGIC: - { - int cputype; - - if (xcoff_data (abfd)->cputype != -1) - cputype = xcoff_data (abfd)->cputype & 0xff; - else - { - /* We did not get a value from the a.out header. If the - file has not been stripped, we may be able to get the - architecture information from the first symbol, if it - is a .file symbol. */ - if (obj_raw_syment_count (abfd) == 0) - cputype = 0; - else - { - bfd_byte buf[SYMESZ]; - struct internal_syment sym; - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || bfd_read (buf, 1, SYMESZ, abfd) != SYMESZ) - return false; - coff_swap_sym_in (abfd, (PTR) buf, (PTR) &sym); - if (sym.n_sclass == C_FILE) - cputype = sym.n_type & 0xff; - else - cputype = 0; - } - } - - /* FIXME: We don't handle all cases here. */ - switch (cputype) - { - default: - case 0: -#ifdef POWERMAC - /* PowerPC Macs use the same magic numbers as RS/6000 - (because that's how they were bootstrapped originally), - but they are always PowerPC architecture. */ - arch = bfd_arch_powerpc; - machine = 0; -#else - arch = bfd_arch_rs6000; - machine = 6000; -#endif /* POWERMAC */ - break; - - case 1: - arch = bfd_arch_powerpc; - machine = 601; - break; - case 2: /* 64 bit PowerPC */ - arch = bfd_arch_powerpc; - machine = 620; - break; - case 3: - arch = bfd_arch_powerpc; - machine = 0; - break; - case 4: - arch = bfd_arch_rs6000; - machine = 6000; - break; - } - } - break; -#endif - -#ifdef WE32KMAGIC - case WE32KMAGIC: - arch = bfd_arch_we32k; - machine = 0; - break; -#endif - -#ifdef H8300MAGIC - case H8300MAGIC: - arch = bfd_arch_h8300; - machine = bfd_mach_h8300; - /* !! FIXME this probably isn't the right place for this */ - abfd->flags |= BFD_IS_RELAXABLE; - break; -#endif - -#ifdef H8300HMAGIC - case H8300HMAGIC: - arch = bfd_arch_h8300; - machine = bfd_mach_h8300h; - /* !! FIXME this probably isn't the right place for this */ - abfd->flags |= BFD_IS_RELAXABLE; - break; -#endif - -#ifdef SH_ARCH_MAGIC_BIG - case SH_ARCH_MAGIC_BIG: - case SH_ARCH_MAGIC_LITTLE: - arch = bfd_arch_sh; - machine = 0; - break; -#endif - -#ifdef H8500MAGIC - case H8500MAGIC: - arch = bfd_arch_h8500; - machine = 0; - break; -#endif - -#ifdef SPARCMAGIC - case SPARCMAGIC: -#ifdef LYNXCOFFMAGIC - case LYNXCOFFMAGIC: -#endif - arch = bfd_arch_sparc; - machine = 0; - break; -#endif - - default: /* Unreadable input file type */ - arch = bfd_arch_obscure; - break; - } - - bfd_default_set_arch_mach (abfd, arch, machine); - return true; -} - -#ifdef SYMNAME_IN_DEBUG - -static boolean -symname_in_debug_hook (abfd, sym) - bfd * abfd; - struct internal_syment *sym; -{ - return SYMNAME_IN_DEBUG (sym) ? true : false; -} - -#else - -#define symname_in_debug_hook \ - (boolean (*) PARAMS ((bfd *, struct internal_syment *))) bfd_false - -#endif - -#ifdef RS6000COFF_C - -/* Handle the csect auxent of a C_EXT or C_HIDEXT symbol. */ - -static boolean coff_pointerize_aux_hook - PARAMS ((bfd *, combined_entry_type *, combined_entry_type *, - unsigned int, combined_entry_type *)); - -/*ARGSUSED*/ -static boolean -coff_pointerize_aux_hook (abfd, table_base, symbol, indaux, aux) - bfd *abfd; - combined_entry_type *table_base; - combined_entry_type *symbol; - unsigned int indaux; - combined_entry_type *aux; -{ - int class = symbol->u.syment.n_sclass; - - if ((class == C_EXT || class == C_HIDEXT) - && indaux + 1 == symbol->u.syment.n_numaux) - { - if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD) - { - aux->u.auxent.x_csect.x_scnlen.p = - table_base + aux->u.auxent.x_csect.x_scnlen.l; - aux->fix_scnlen = 1; - } - - /* Return true to indicate that the caller should not do any - further work on this auxent. */ - return true; - } - - /* Return false to indicate that this auxent should be handled by - the caller. */ - return false; -} - -#else -#ifdef I960 - -/* We don't want to pointerize bal entries. */ - -static boolean coff_pointerize_aux_hook - PARAMS ((bfd *, combined_entry_type *, combined_entry_type *, - unsigned int, combined_entry_type *)); - -/*ARGSUSED*/ -static boolean -coff_pointerize_aux_hook (abfd, table_base, symbol, indaux, aux) - bfd *abfd; - combined_entry_type *table_base; - combined_entry_type *symbol; - unsigned int indaux; - combined_entry_type *aux; -{ - /* Return true if we don't want to pointerize this aux entry, which - is the case for the lastfirst aux entry for a C_LEAFPROC symbol. */ - return (indaux == 1 - && (symbol->u.syment.n_sclass == C_LEAFPROC - || symbol->u.syment.n_sclass == C_LEAFSTAT - || symbol->u.syment.n_sclass == C_LEAFEXT)); -} - -#else /* ! I960 */ - -#define coff_pointerize_aux_hook 0 - -#endif /* ! I960 */ -#endif /* ! RS6000COFF_C */ - -/* Print an aux entry. This returns true if it has printed it. */ - -static boolean coff_print_aux - PARAMS ((bfd *, FILE *, combined_entry_type *, combined_entry_type *, - combined_entry_type *, unsigned int)); - -static boolean -coff_print_aux (abfd, file, table_base, symbol, aux, indaux) - bfd *abfd; - FILE *file; - combined_entry_type *table_base; - combined_entry_type *symbol; - combined_entry_type *aux; - unsigned int indaux; -{ -#ifdef RS6000COFF_C - if ((symbol->u.syment.n_sclass == C_EXT - || symbol->u.syment.n_sclass == C_HIDEXT) - && indaux + 1 == symbol->u.syment.n_numaux) - { - /* This is a csect entry. */ - fprintf (file, "AUX "); - if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) != XTY_LD) - { - BFD_ASSERT (! aux->fix_scnlen); - fprintf (file, "val %5ld", aux->u.auxent.x_csect.x_scnlen.l); - } - else - { - fprintf (file, "indx "); - if (! aux->fix_scnlen) - fprintf (file, "%4ld", aux->u.auxent.x_csect.x_scnlen.l); - else - fprintf (file, "%4ld", - (long) (aux->u.auxent.x_csect.x_scnlen.p - table_base)); - } - fprintf (file, - " prmhsh %ld snhsh %u typ %d algn %d clss %u stb %ld snstb %u", - aux->u.auxent.x_csect.x_parmhash, - (unsigned int) aux->u.auxent.x_csect.x_snhash, - SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp), - SMTYP_ALIGN (aux->u.auxent.x_csect.x_smtyp), - (unsigned int) aux->u.auxent.x_csect.x_smclas, - aux->u.auxent.x_csect.x_stab, - (unsigned int) aux->u.auxent.x_csect.x_snstab); - return true; - } -#endif - - /* Return false to indicate that no special action was taken. */ - return false; -} - -/* -SUBSUBSECTION - Writing relocations - - To write relocations, the back end steps though the - canonical relocation table and create an - @code{internal_reloc}. The symbol index to use is removed from - the @code{offset} field in the symbol table supplied. The - address comes directly from the sum of the section base - address and the relocation offset; the type is dug directly - from the howto field. Then the @code{internal_reloc} is - swapped into the shape of an @code{external_reloc} and written - out to disk. - -*/ - -#ifdef TARG_AUX - -static int compare_arelent_ptr PARAMS ((const PTR, const PTR)); - -/* AUX's ld wants relocations to be sorted */ -static int -compare_arelent_ptr (x, y) - const PTR x; - const PTR y; -{ - const arelent **a = (const arelent **) x; - const arelent **b = (const arelent **) y; - bfd_size_type aadr = (*a)->address; - bfd_size_type badr = (*b)->address; - - return (aadr < badr ? -1 : badr < aadr ? 1 : 0); -} - -#endif /* TARG_AUX */ - -static boolean -coff_write_relocs (abfd, first_undef) - bfd * abfd; - int first_undef; -{ - asection *s; - - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - unsigned int i; - struct external_reloc dst; - arelent **p; - -#ifndef TARG_AUX - p = s->orelocation; -#else - /* sort relocations before we write them out */ - p = (arelent **) bfd_malloc (s->reloc_count * sizeof (arelent *)); - if (p == NULL && s->reloc_count > 0) - return false; - memcpy (p, s->orelocation, s->reloc_count * sizeof (arelent *)); - qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); -#endif - - if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0) - return false; - for (i = 0; i < s->reloc_count; i++) - { - struct internal_reloc n; - arelent *q = p[i]; - memset ((PTR) & n, 0, sizeof (n)); - - /* Now we've renumbered the symbols we know where the - undefined symbols live in the table. Check the reloc - entries for symbols who's output bfd isn't the right one. - This is because the symbol was undefined (which means - that all the pointers are never made to point to the same - place). This is a bad thing,'cause the symbols attached - to the output bfd are indexed, so that the relocation - entries know which symbol index they point to. So we - have to look up the output symbol here. */ - - if (q->sym_ptr_ptr[0]->the_bfd != abfd) - { - int i; - const char *sname = q->sym_ptr_ptr[0]->name; - asymbol **outsyms = abfd->outsymbols; - for (i = first_undef; outsyms[i]; i++) - { - const char *intable = outsyms[i]->name; - if (strcmp (intable, sname) == 0) { - /* got a hit, so repoint the reloc */ - q->sym_ptr_ptr = outsyms + i; - break; - } - } - } - - n.r_vaddr = q->address + s->vma; - -#ifdef R_IHCONST - /* The 29k const/consth reloc pair is a real kludge. The consth - part doesn't have a symbol; it has an offset. So rebuilt - that here. */ - if (q->howto->type == R_IHCONST) - n.r_symndx = q->addend; - else -#endif - if (q->sym_ptr_ptr) - { - if (q->sym_ptr_ptr == bfd_abs_section_ptr->symbol_ptr_ptr) - /* This is a relocation relative to the absolute symbol. */ - n.r_symndx = -1; - else - { - n.r_symndx = get_index ((*(q->sym_ptr_ptr))); - /* Take notice if the symbol reloc points to a symbol - we don't have in our symbol table. What should we - do for this?? */ - if (n.r_symndx > obj_conv_table_size (abfd)) - abort (); - } - } - -#ifdef SWAP_OUT_RELOC_OFFSET - n.r_offset = q->addend; -#endif - -#ifdef SELECT_RELOC - /* Work out reloc type from what is required */ - SELECT_RELOC (n, q->howto); -#else - n.r_type = q->howto->type; -#endif - coff_swap_reloc_out (abfd, &n, &dst); - if (bfd_write ((PTR) & dst, 1, RELSZ, abfd) != RELSZ) - return false; - } - -#ifdef TARG_AUX - if (p != NULL) - free (p); -#endif - } - - return true; -} - -/* Set flags and magic number of a coff file from architecture and machine - type. Result is true if we can represent the arch&type, false if not. */ - -static boolean -coff_set_flags (abfd, magicp, flagsp) - bfd * abfd; - unsigned *magicp; - unsigned short *flagsp; -{ - switch (bfd_get_arch (abfd)) - { -#ifdef Z8KMAGIC - case bfd_arch_z8k: - *magicp = Z8KMAGIC; - switch (bfd_get_mach (abfd)) - { - case bfd_mach_z8001: - *flagsp = F_Z8001; - break; - case bfd_mach_z8002: - *flagsp = F_Z8002; - break; - default: - return false; - } - return true; -#endif -#ifdef I960ROMAGIC - - case bfd_arch_i960: - - { - unsigned flags; - *magicp = I960ROMAGIC; - /* - ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC : - I960RWMAGIC); FIXME??? - */ - switch (bfd_get_mach (abfd)) - { - case bfd_mach_i960_core: - flags = F_I960CORE; - break; - case bfd_mach_i960_kb_sb: - flags = F_I960KB; - break; - case bfd_mach_i960_mc: - flags = F_I960MC; - break; - case bfd_mach_i960_xa: - flags = F_I960XA; - break; - case bfd_mach_i960_ca: - flags = F_I960CA; - break; - case bfd_mach_i960_ka_sa: - flags = F_I960KA; - break; - case bfd_mach_i960_jx: - flags = F_I960JX; - break; - case bfd_mach_i960_hx: - flags = F_I960HX; - break; - default: - return false; - } - *flagsp = flags; - return true; - } - break; -#endif -#ifdef ARMMAGIC - case bfd_arch_arm: - *magicp = ARMMAGIC; - return true; -#endif -#ifdef PPCMAGIC - case bfd_arch_powerpc: - *magicp = PPCMAGIC; - return true; - break; -#endif -#ifdef I386MAGIC - case bfd_arch_i386: - *magicp = I386MAGIC; -#ifdef LYNXOS - /* Just overwrite the usual value if we're doing Lynx. */ - *magicp = LYNXCOFFMAGIC; -#endif - return true; - break; -#endif -#ifdef I860MAGIC - case bfd_arch_i860: - *magicp = I860MAGIC; - return true; - break; -#endif -#ifdef MC68MAGIC - case bfd_arch_m68k: -#ifdef APOLLOM68KMAGIC - *magicp = APOLLO_COFF_VERSION_NUMBER; -#else - *magicp = MC68MAGIC; -#endif -#ifdef LYNXOS - /* Just overwrite the usual value if we're doing Lynx. */ - *magicp = LYNXCOFFMAGIC; -#endif - return true; - break; -#endif - -#ifdef MC88MAGIC - case bfd_arch_m88k: - *magicp = MC88OMAGIC; - return true; - break; -#endif -#ifdef H8300MAGIC - case bfd_arch_h8300: - switch (bfd_get_mach (abfd)) - { - case bfd_mach_h8300: - *magicp = H8300MAGIC; - return true; - case bfd_mach_h8300h: - *magicp = H8300HMAGIC; - return true; - } - break; -#endif - -#ifdef SH_ARCH_MAGIC_BIG - case bfd_arch_sh: - if (bfd_big_endian (abfd)) - *magicp = SH_ARCH_MAGIC_BIG; - else - *magicp = SH_ARCH_MAGIC_LITTLE; - return true; - break; -#endif - -#ifdef SPARCMAGIC - case bfd_arch_sparc: - *magicp = SPARCMAGIC; -#ifdef LYNXOS - /* Just overwrite the usual value if we're doing Lynx. */ - *magicp = LYNXCOFFMAGIC; -#endif - return true; - break; -#endif - -#ifdef H8500MAGIC - case bfd_arch_h8500: - *magicp = H8500MAGIC; - return true; - break; -#endif -#ifdef A29K_MAGIC_BIG - case bfd_arch_a29k: - if (bfd_big_endian (abfd)) - *magicp = A29K_MAGIC_BIG; - else - *magicp = A29K_MAGIC_LITTLE; - return true; - break; -#endif - -#ifdef WE32KMAGIC - case bfd_arch_we32k: - *magicp = WE32KMAGIC; - return true; - break; -#endif - -#ifdef U802TOCMAGIC - case bfd_arch_rs6000: -#ifndef PPCMAGIC - case bfd_arch_powerpc: -#endif - *magicp = U802TOCMAGIC; - return true; - break; -#endif - - default: /* Unknown architecture */ - /* return false; -- fall through to "return false" below, to avoid - "statement never reached" errors on the one below. */ - break; - } - - return false; -} - - -static boolean -coff_set_arch_mach (abfd, arch, machine) - bfd * abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - unsigned dummy1; - unsigned short dummy2; - - if (! bfd_default_set_arch_mach (abfd, arch, machine)) - return false; - - if (arch != bfd_arch_unknown && - coff_set_flags (abfd, &dummy1, &dummy2) != true) - return false; /* We can't represent this type */ - - return true; /* We're easy ... */ -} - - -/* Calculate the file position for each section. */ - -static void -coff_compute_section_file_positions (abfd) - bfd * abfd; -{ - asection *current; - asection *previous = (asection *) NULL; - file_ptr sofar = FILHSZ; - -#ifndef I960 - file_ptr old_sofar; -#endif - unsigned int count; - -#ifdef RS6000COFF_C - /* On XCOFF, if we have symbols, set up the .debug section. */ - if (bfd_get_symcount (abfd) > 0) - { - bfd_size_type sz; - bfd_size_type i, symcount; - asymbol **symp; - - sz = 0; - symcount = bfd_get_symcount (abfd); - for (symp = abfd->outsymbols, i = 0; i < symcount; symp++, i++) - { - coff_symbol_type *cf; - - cf = coff_symbol_from (abfd, *symp); - if (cf != NULL - && cf->native != NULL - && SYMNAME_IN_DEBUG (&cf->native->u.syment)) - { - size_t len; - - len = strlen (bfd_asymbol_name (*symp)); - if (len > SYMNMLEN) - sz += len + 3; - } - } - if (sz > 0) - { - asection *dsec; - - dsec = bfd_make_section_old_way (abfd, ".debug"); - if (dsec == NULL) - abort (); - dsec->_raw_size = sz; - dsec->flags |= SEC_HAS_CONTENTS; - } - } -#endif - -#ifdef COFF_IMAGE_WITH_PE - int page_size; - if (coff_data (abfd)->link_info) - { - page_size = pe_data (abfd)->pe_opthdr.FileAlignment; - } - else - page_size = PE_DEF_FILE_ALIGNMENT; -#else -#ifdef COFF_PAGE_SIZE - int page_size = COFF_PAGE_SIZE; -#endif -#endif - - if (bfd_get_start_address (abfd)) - { - /* A start address may have been added to the original file. In this - case it will need an optional header to record it. */ - abfd->flags |= EXEC_P; - } - - if (abfd->flags & EXEC_P) - sofar += AOUTSZ; -#ifdef RS6000COFF_C - else if (xcoff_data (abfd)->full_aouthdr) - sofar += AOUTSZ; - else - sofar += SMALL_AOUTSZ; -#endif - - sofar += abfd->section_count * SCNHSZ; - -#ifdef RS6000COFF_C - /* XCOFF handles overflows in the reloc and line number count fields - by allocating a new section header to hold the correct counts. */ - for (current = abfd->sections; current != NULL; current = current->next) - if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff) - sofar += SCNHSZ; -#endif - - for (current = abfd->sections, count = 1; - current != (asection *) NULL; - current = current->next, ++count) - { - current->target_index = count; - - /* Only deal with sections which have contents */ - if (!(current->flags & SEC_HAS_CONTENTS)) - continue; - -#ifdef COFF_WITH_PE - /* Do not include the .junk section. This is where we collect section - data which we don't need. This is mainly the MS .debug$ data which - stores codeview debug data. */ - if (strcmp (current->name, ".junk") == 0) - { - continue; - } -#endif - - /* Align the sections in the file to the same boundary on - which they are aligned in virtual memory. I960 doesn't - do this (FIXME) so we can stay in sync with Intel. 960 - doesn't yet page from files... */ -#ifndef I960 - if ((abfd->flags & EXEC_P) != 0) - { - /* make sure this section is aligned on the right boundary - by - padding the previous section up if necessary */ - - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); - if (previous != (asection *) NULL) - { - previous->_raw_size += sofar - old_sofar; - } - } - -#endif - - /* In demand paged files the low order bits of the file offset - must match the low order bits of the virtual address. */ -#ifdef COFF_PAGE_SIZE - if ((abfd->flags & D_PAGED) != 0 - && (current->flags & SEC_ALLOC) != 0) - sofar += (current->vma - sofar) % page_size; -#endif - current->filepos = sofar; - -#ifdef COFF_IMAGE_WITH_PE - /* With PE we have to pad each section to be a multiple of its page size - too, and remember both sizes. Cooked_size becomes very useful. */ - current->_cooked_size = current->_raw_size; - current->_raw_size = (current->_raw_size + page_size -1) & -page_size; -#endif - - sofar += current->_raw_size; - -#ifndef I960 - /* make sure that this section is of the right size too */ - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); - current->_raw_size += sofar - old_sofar; -#endif - -#ifdef _LIB - /* Force .lib sections to start at zero. The vma is then - incremented in coff_set_section_contents. This is right for - SVR3.2. */ - if (strcmp (current->name, _LIB) == 0) - bfd_set_section_vma (abfd, current, 0); -#endif - - previous = current; - } - - obj_relocbase (abfd) = sofar; - abfd->output_has_begun = true; - -} - -#if 0 - -/* This can never work, because it is called too late--after the - section positions have been set. I can't figure out what it is - for, so I am going to disable it--Ian Taylor 20 March 1996. */ - -/* If .file, .text, .data, .bss symbols are missing, add them. */ -/* @@ Should we only be adding missing symbols, or overriding the aux - values for existing section symbols? */ -static boolean -coff_add_missing_symbols (abfd) - bfd *abfd; -{ - unsigned int nsyms = bfd_get_symcount (abfd); - asymbol **sympp = abfd->outsymbols; - asymbol **sympp2; - unsigned int i; - int need_text = 1, need_data = 1, need_bss = 1, need_file = 1; - - for (i = 0; i < nsyms; i++) - { - coff_symbol_type *csym = coff_symbol_from (abfd, sympp[i]); - CONST char *name; - if (csym) - { - /* only do this if there is a coff representation of the input - symbol */ - if (csym->native && csym->native->u.syment.n_sclass == C_FILE) - { - need_file = 0; - continue; - } - name = csym->symbol.name; - if (!name) - continue; - if (!strcmp (name, _TEXT)) - need_text = 0; -#ifdef APOLLO_M68 - else if (!strcmp (name, ".wtext")) - need_text = 0; -#endif - else if (!strcmp (name, _DATA)) - need_data = 0; - else if (!strcmp (name, _BSS)) - need_bss = 0; - } - } - /* Now i == bfd_get_symcount (abfd). */ - /* @@ For now, don't deal with .file symbol. */ - need_file = 0; - - if (!need_text && !need_data && !need_bss && !need_file) - return true; - nsyms += need_text + need_data + need_bss + need_file; - sympp2 = (asymbol **) bfd_alloc_by_size_t (abfd, nsyms * sizeof (asymbol *)); - if (!sympp2) - return false; - memcpy (sympp2, sympp, i * sizeof (asymbol *)); - if (need_file) - { - /* @@ Generate fake .file symbol, in sympp2[i], and increment i. */ - abort (); - } - if (need_text) - sympp2[i++] = coff_section_symbol (abfd, _TEXT); - if (need_data) - sympp2[i++] = coff_section_symbol (abfd, _DATA); - if (need_bss) - sympp2[i++] = coff_section_symbol (abfd, _BSS); - BFD_ASSERT (i == nsyms); - bfd_set_symtab (abfd, sympp2, nsyms); - return true; -} - -#endif /* 0 */ - -/* SUPPRESS 558 */ -/* SUPPRESS 529 */ -static boolean -coff_write_object_contents (abfd) - bfd * abfd; -{ - asection *current; - boolean hasrelocs = false; - boolean haslinno = false; - file_ptr scn_base; - file_ptr reloc_base; - file_ptr lineno_base; - file_ptr sym_base; - unsigned long reloc_size = 0; - unsigned long lnno_size = 0; - asection *text_sec = NULL; - asection *data_sec = NULL; - asection *bss_sec = NULL; - - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - - bfd_set_error (bfd_error_system_call); - - /* Make a pass through the symbol table to count line number entries and - put them into the correct asections */ - - lnno_size = coff_count_linenumbers (abfd) * LINESZ; - - if (abfd->output_has_begun == false) - coff_compute_section_file_positions (abfd); - - reloc_base = obj_relocbase (abfd); - - /* Work out the size of the reloc and linno areas */ - - for (current = abfd->sections; current != NULL; current = - current->next) - reloc_size += current->reloc_count * RELSZ; - - lineno_base = reloc_base + reloc_size; - sym_base = lineno_base + lnno_size; - - /* Indicate in each section->line_filepos its actual file address */ - for (current = abfd->sections; current != NULL; current = - current->next) - { - if (current->lineno_count) - { - current->line_filepos = lineno_base; - current->moving_line_filepos = lineno_base; - lineno_base += current->lineno_count * LINESZ; - } - else - { - current->line_filepos = 0; - } - if (current->reloc_count) - { - current->rel_filepos = reloc_base; - reloc_base += current->reloc_count * RELSZ; - } - else - { - current->rel_filepos = 0; - } - } - - /* Write section headers to the file. */ - internal_f.f_nscns = 0; - - if ((abfd->flags & EXEC_P) != 0) - scn_base = FILHSZ + AOUTSZ; - else - { - scn_base = FILHSZ; -#ifdef RS6000COFF_C - if (xcoff_data (abfd)->full_aouthdr) - scn_base += AOUTSZ; - else - scn_base += SMALL_AOUTSZ; -#endif - } - - if (bfd_seek (abfd, scn_base, SEEK_SET) != 0) - return false; - - for (current = abfd->sections; - current != NULL; - current = current->next) - { - struct internal_scnhdr section; - -#ifdef COFF_WITH_PE - /* Do not include the .junk section. This is where we collect section - data which we don't need. This is mainly the MS .debug$ data which - stores codeview debug data. */ - if (strcmp (current->name, ".junk") == 0) - { - continue; - } - - /* If we've got a .reloc section, remember. */ - -#ifdef COFF_IMAGE_WITH_PE - if (strcmp (current->name, ".reloc") == 0) - { - pe_data (abfd)->has_reloc_section = 1; - } -#endif - -#endif - internal_f.f_nscns++; - strncpy (&(section.s_name[0]), current->name, 8); -#ifdef _LIB - /* Always set s_vaddr of .lib to 0. This is right for SVR3.2 - Ian Taylor . */ - if (strcmp (current->name, _LIB) == 0) - section.s_vaddr = 0; - else -#endif - section.s_vaddr = current->vma; - section.s_paddr = current->lma; - section.s_size = current->_raw_size; - -#ifdef COFF_WITH_PE - section.s_paddr = current->_cooked_size; -#endif - - /* - If this section has no size or is unloadable then the scnptr - will be 0 too - */ - if (current->_raw_size == 0 || - (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - { - section.s_scnptr = 0; - } - else - { - section.s_scnptr = current->filepos; - } - section.s_relptr = current->rel_filepos; - section.s_lnnoptr = current->line_filepos; - section.s_nreloc = current->reloc_count; - section.s_nlnno = current->lineno_count; - if (current->reloc_count != 0) - hasrelocs = true; - if (current->lineno_count != 0) - haslinno = true; - -#ifdef RS6000COFF_C - /* Indicate the use of an XCOFF overflow section header. */ - if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff) - { - section.s_nreloc = 0xffff; - section.s_nlnno = 0xffff; - } -#endif - - section.s_flags = sec_to_styp_flags (current->name, current->flags); - - if (!strcmp (current->name, _TEXT)) - { - text_sec = current; - } - else if (!strcmp (current->name, _DATA)) - { - data_sec = current; - } - else if (!strcmp (current->name, _BSS)) - { - bss_sec = current; - } - -#ifdef I960 - section.s_align = (current->alignment_power - ? 1 << current->alignment_power - : 0); - -#endif - -#ifdef COFF_IMAGE_WITH_PE - /* suppress output of the sections if they are null. ld includes - the bss and data sections even if there is no size assigned - to them. NT loader doesn't like it if these section headers are - included if the sections themselves are not needed */ - if (section.s_size == 0) - internal_f.f_nscns--; - else -#endif - { - SCNHDR buff; - if (coff_swap_scnhdr_out (abfd, §ion, &buff) == 0 - || bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ) - return false; - } - } - -#ifdef RS6000COFF_C - /* XCOFF handles overflows in the reloc and line number count fields - by creating a new section header to hold the correct values. */ - for (current = abfd->sections; current != NULL; current = current->next) - { - if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff) - { - struct internal_scnhdr scnhdr; - SCNHDR buff; - - internal_f.f_nscns++; - strncpy (&(scnhdr.s_name[0]), current->name, 8); - scnhdr.s_paddr = current->reloc_count; - scnhdr.s_vaddr = current->lineno_count; - scnhdr.s_size = 0; - scnhdr.s_scnptr = 0; - scnhdr.s_relptr = current->rel_filepos; - scnhdr.s_lnnoptr = current->line_filepos; - scnhdr.s_nreloc = current->target_index; - scnhdr.s_nlnno = current->target_index; - scnhdr.s_flags = STYP_OVRFLO; - if (coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0 - || bfd_write ((PTR) &buff, 1, SCNHSZ, abfd) != SCNHSZ) - return false; - } - } -#endif - - /* OK, now set up the filehdr... */ - - /* Don't include the internal abs section in the section count */ - - /* - We will NOT put a fucking timestamp in the header here. Every time you - put it back, I will come in and take it out again. I'm sorry. This - field does not belong here. We fill it with a 0 so it compares the - same but is not a reasonable time. -- gnu@cygnus.com - */ - internal_f.f_timdat = 0; - - internal_f.f_flags = 0; - - if (abfd->flags & EXEC_P) - internal_f.f_opthdr = AOUTSZ; - else - { - internal_f.f_opthdr = 0; -#ifdef RS6000COFF_C - if (xcoff_data (abfd)->full_aouthdr) - internal_f.f_opthdr = AOUTSZ; - else - internal_f.f_opthdr = SMALL_AOUTSZ; -#endif - } - - if (!hasrelocs) - internal_f.f_flags |= F_RELFLG; - if (!haslinno) - internal_f.f_flags |= F_LNNO; - if (abfd->flags & EXEC_P) - internal_f.f_flags |= F_EXEC; - - /* FIXME: this is wrong for PPC_PE! */ - if (bfd_little_endian (abfd)) - internal_f.f_flags |= F_AR32WR; - else - internal_f.f_flags |= F_AR32W; - - /* - FIXME, should do something about the other byte orders and - architectures. - */ - -#ifdef RS6000COFF_C - if ((abfd->flags & DYNAMIC) != 0) - internal_f.f_flags |= F_SHROBJ; - if (bfd_get_section_by_name (abfd, _LOADER) != NULL) - internal_f.f_flags |= F_DYNLOAD; -#endif - - memset (&internal_a, 0, sizeof internal_a); - - /* Set up architecture-dependent stuff */ - - { - unsigned int magic = 0; - unsigned short flags = 0; - coff_set_flags (abfd, &magic, &flags); - internal_f.f_magic = magic; - internal_f.f_flags |= flags; - /* ...and the "opt"hdr... */ - -#ifdef A29K -#ifdef ULTRA3 /* NYU's machine */ - /* FIXME: This is a bogus check. I really want to see if there - * is a .shbss or a .shdata section, if so then set the magic - * number to indicate a shared data executable. - */ - if (internal_f.f_nscns >= 7) - internal_a.magic = SHMAGIC; /* Shared magic */ - else -#endif /* ULTRA3 */ - internal_a.magic = NMAGIC; /* Assume separate i/d */ -#define __A_MAGIC_SET__ -#endif /* A29K */ -#ifdef I860 - /* FIXME: What are the a.out magic numbers for the i860? */ - internal_a.magic = 0; -#define __A_MAGIC_SET__ -#endif /* I860 */ -#ifdef I960 - internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC); -#define __A_MAGIC_SET__ -#endif /* I960 */ -#if M88 -#define __A_MAGIC_SET__ - internal_a.magic = PAGEMAGICBCS; -#endif /* M88 */ - -#if APOLLO_M68 -#define __A_MAGIC_SET__ - internal_a.magic = APOLLO_COFF_VERSION_NUMBER; -#endif - -#if defined(M68) || defined(WE32K) || defined(M68K) -#define __A_MAGIC_SET__ -#if defined(LYNXOS) - internal_a.magic = LYNXCOFFMAGIC; -#else -#if defined(TARG_AUX) - internal_a.magic = (abfd->flags & D_PAGED ? PAGEMAGICPEXECPAGED : - abfd->flags & WP_TEXT ? PAGEMAGICPEXECSWAPPED : - PAGEMAGICEXECSWAPPED); -#else -#if defined (PAGEMAGICPEXECPAGED) - internal_a.magic = PAGEMAGICPEXECPAGED; -#endif -#endif /* TARG_AUX */ -#endif /* LYNXOS */ -#endif /* M68 || WE32K || M68K */ - -#if defined(ARM) -#define __A_MAGIC_SET__ - internal_a.magic = ZMAGIC; -#endif -#if defined(PPC) -#define __A_MAGIC_SET__ - internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; -#endif -#if defined(I386) -#define __A_MAGIC_SET__ -#if defined(LYNXOS) - internal_a.magic = LYNXCOFFMAGIC; -#else /* LYNXOS */ - internal_a.magic = ZMAGIC; -#endif /* LYNXOS */ -#endif /* I386 */ - -#if defined(SPARC) -#define __A_MAGIC_SET__ -#if defined(LYNXOS) - internal_a.magic = LYNXCOFFMAGIC; -#endif /* LYNXOS */ -#endif /* SPARC */ - -#if RS6000COFF_C -#define __A_MAGIC_SET__ - internal_a.magic = (abfd->flags & D_PAGED) ? RS6K_AOUTHDR_ZMAGIC : - (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC : - RS6K_AOUTHDR_OMAGIC; -#endif - -#ifndef __A_MAGIC_SET__ -#include "Your aouthdr magic number is not being set!" -#else -#undef __A_MAGIC_SET__ -#endif - } - - /* FIXME: Does anybody ever set this to another value? */ - internal_a.vstamp = 0; - - /* Now should write relocs, strings, syms */ - obj_sym_filepos (abfd) = sym_base; - - if (bfd_get_symcount (abfd) != 0) - { - int firstundef; -#if 0 - if (!coff_add_missing_symbols (abfd)) - return false; -#endif - if (!coff_renumber_symbols (abfd, &firstundef)) - return false; - coff_mangle_symbols (abfd); - if (! coff_write_symbols (abfd)) - return false; - if (! coff_write_linenumbers (abfd)) - return false; - if (! coff_write_relocs (abfd, firstundef)) - return false; - } -#ifdef COFF_IMAGE_WITH_PE -#ifdef PPC - else if ((abfd->flags & EXEC_P) != 0) - { - bfd_byte b; - - /* PowerPC PE appears to require that all executable files be - rounded up to the page size. */ - b = 0; - if (bfd_seek (abfd, - BFD_ALIGN (sym_base, COFF_PAGE_SIZE) - 1, - SEEK_SET) != 0 - || bfd_write (&b, 1, 1, abfd) != 1) - return false; - } -#endif -#endif - - /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF - backend linker, and obj_raw_syment_count is not valid until after - coff_write_symbols is called. */ - if (obj_raw_syment_count (abfd) != 0) - { - internal_f.f_symptr = sym_base; -#ifdef RS6000COFF_C - /* AIX appears to require that F_RELFLG not be set if there are - local symbols but no relocations. */ - internal_f.f_flags &=~ F_RELFLG; -#endif - } - else - { - internal_f.f_symptr = 0; - internal_f.f_flags |= F_LSYMS; - } - - if (text_sec) - { - internal_a.tsize = bfd_get_section_size_before_reloc (text_sec); - internal_a.text_start = internal_a.tsize ? text_sec->vma : 0; - } - if (data_sec) - { - internal_a.dsize = bfd_get_section_size_before_reloc (data_sec); - internal_a.data_start = internal_a.dsize ? data_sec->vma : 0; - } - if (bss_sec) - { - internal_a.bsize = bfd_get_section_size_before_reloc (bss_sec); - if (internal_a.bsize && bss_sec->vma < internal_a.data_start) - internal_a.data_start = bss_sec->vma; - } - - internal_a.entry = bfd_get_start_address (abfd); - internal_f.f_nsyms = obj_raw_syment_count (abfd); - -#ifdef RS6000COFF_C - if (xcoff_data (abfd)->full_aouthdr) - { - bfd_vma toc; - asection *loader_sec; - - internal_a.vstamp = 1; - - internal_a.o_snentry = xcoff_data (abfd)->snentry; - if (internal_a.o_snentry == 0) - internal_a.entry = (bfd_vma) -1; - - if (text_sec != NULL) - { - internal_a.o_sntext = text_sec->target_index; - internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec); - } - else - { - internal_a.o_sntext = 0; - internal_a.o_algntext = 0; - } - if (data_sec != NULL) - { - internal_a.o_sndata = data_sec->target_index; - internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec); - } - else - { - internal_a.o_sndata = 0; - internal_a.o_algndata = 0; - } - loader_sec = bfd_get_section_by_name (abfd, ".loader"); - if (loader_sec != NULL) - internal_a.o_snloader = loader_sec->target_index; - else - internal_a.o_snloader = 0; - if (bss_sec != NULL) - internal_a.o_snbss = bss_sec->target_index; - else - internal_a.o_snbss = 0; - - toc = xcoff_data (abfd)->toc; - internal_a.o_toc = toc; - internal_a.o_sntoc = xcoff_data (abfd)->sntoc; - - internal_a.o_modtype = xcoff_data (abfd)->modtype; - if (xcoff_data (abfd)->cputype != -1) - internal_a.o_cputype = xcoff_data (abfd)->cputype; - else - { - switch (bfd_get_arch (abfd)) - { - case bfd_arch_rs6000: - internal_a.o_cputype = 4; - break; - case bfd_arch_powerpc: - if (bfd_get_mach (abfd) == 0) - internal_a.o_cputype = 3; - else - internal_a.o_cputype = 1; - break; - default: - abort (); - } - } - internal_a.o_maxstack = xcoff_data (abfd)->maxstack; - internal_a.o_maxdata = xcoff_data (abfd)->maxdata; - } -#endif - - /* now write them */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return false; - { - FILHDR buff; - coff_swap_filehdr_out (abfd, (PTR) & internal_f, (PTR) & buff); - if (bfd_write ((PTR) & buff, 1, FILHSZ, abfd) != FILHSZ) - return false; - } - if (abfd->flags & EXEC_P) - { - AOUTHDR buff; - coff_swap_aouthdr_out (abfd, (PTR) & internal_a, (PTR) & buff); - if (bfd_write ((PTR) & buff, 1, AOUTSZ, abfd) != AOUTSZ) - return false; - } -#ifdef RS6000COFF_C - else - { - AOUTHDR buff; - size_t size; - - /* XCOFF seems to always write at least a small a.out header. */ - coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) &buff); - if (xcoff_data (abfd)->full_aouthdr) - size = AOUTSZ; - else - size = SMALL_AOUTSZ; - if (bfd_write ((PTR) &buff, 1, size, abfd) != size) - return false; - } -#endif - - return true; -} - -static boolean -coff_set_section_contents (abfd, section, location, offset, count) - bfd * abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (abfd->output_has_begun == false) /* set by bfd.c handler */ - coff_compute_section_file_positions (abfd); - -#ifdef _LIB - - /* The physical address field of a .lib section is used to hold the - number of shared libraries in the section. This code counts the - number of sections being written, and increments the lma field - with the number. - - I have found no documentation on the contents of this section. - Experimentation indicates that the section contains zero or more - records, each of which has the following structure: - - - a (four byte) word holding the length of this record, in words, - - a word that always seems to be set to "2", - - the path to a shared library, null-terminated and then padded - to a whole word boundary. - - bfd_assert calls have been added to alert if an attempt is made - to write a section which doesn't follow these assumptions. The - code has been tested on ISC 4.1 by me, and on SCO by Robert Lipe - (Thanks!). - - Gvran Uddeborg */ - - if (strcmp (section->name, _LIB) == 0) - { - bfd_byte *rec, *recend; - - rec = (bfd_byte *) location; - recend = rec + count; - while (rec < recend) - { - ++section->lma; - rec += bfd_get_32 (abfd, rec) * 4; - } - - BFD_ASSERT (rec == recend); - } - -#endif - - /* Don't write out bss sections - one way to do this is to - see if the filepos has not been set. */ - if (section->filepos == 0) - return true; - - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0) - return false; - - if (count != 0) - { - return (bfd_write (location, 1, count, abfd) == count) ? true : false; - } - return true; -} -#if 0 -static boolean -coff_close_and_cleanup (abfd) - bfd *abfd; -{ - if (!bfd_read_p (abfd)) - switch (abfd->format) - { - case bfd_archive: - if (!_bfd_write_archive_contents (abfd)) - return false; - break; - case bfd_object: - if (!coff_write_object_contents (abfd)) - return false; - break; - default: - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* We depend on bfd_close to free all the memory on the obstack. */ - /* FIXME if bfd_release is not using obstacks! */ - return true; -} - -#endif - -static PTR -buy_and_read (abfd, where, seek_direction, size) - bfd *abfd; - file_ptr where; - int seek_direction; - size_t size; -{ - PTR area = (PTR) bfd_alloc (abfd, size); - if (!area) - return (NULL); - if (bfd_seek (abfd, where, seek_direction) != 0 - || bfd_read (area, 1, size, abfd) != size) - return (NULL); - return (area); -} /* buy_and_read() */ - -/* -SUBSUBSECTION - Reading linenumbers - - Creating the linenumber table is done by reading in the entire - coff linenumber table, and creating another table for internal use. - - A coff linenumber table is structured so that each function - is marked as having a line number of 0. Each line within the - function is an offset from the first line in the function. The - base of the line number information for the table is stored in - the symbol associated with the function. - - The information is copied from the external to the internal - table, and each symbol which marks a function is marked by - pointing its... - - How does this work ? - -*/ - -static boolean -coff_slurp_line_table (abfd, asect) - bfd *abfd; - asection *asect; -{ - LINENO *native_lineno; - alent *lineno_cache; - - BFD_ASSERT (asect->lineno == (alent *) NULL); - - native_lineno = (LINENO *) buy_and_read (abfd, - asect->line_filepos, - SEEK_SET, - (size_t) (LINESZ * - asect->lineno_count)); - lineno_cache = - (alent *) bfd_alloc (abfd, (size_t) ((asect->lineno_count + 1) * sizeof (alent))); - if (lineno_cache == NULL) - return false; - else - { - unsigned int counter = 0; - alent *cache_ptr = lineno_cache; - LINENO *src = native_lineno; - - while (counter < asect->lineno_count) - { - struct internal_lineno dst; - coff_swap_lineno_in (abfd, src, &dst); - cache_ptr->line_number = dst.l_lnno; - - if (cache_ptr->line_number == 0) - { - coff_symbol_type *sym = - (coff_symbol_type *) (dst.l_addr.l_symndx - + obj_raw_syments (abfd))->u.syment._n._n_n._n_zeroes; - cache_ptr->u.sym = (asymbol *) sym; - if (sym->lineno != NULL) - { - (*_bfd_error_handler) - ("%s: warning: duplicate line number information for `%s'", - bfd_get_filename (abfd), - bfd_asymbol_name (&sym->symbol)); - } - sym->lineno = cache_ptr; - } - else - { - cache_ptr->u.offset = dst.l_addr.l_paddr - - bfd_section_vma (abfd, asect); - } /* If no linenumber expect a symbol index */ - - cache_ptr++; - src++; - counter++; - } - cache_ptr->line_number = 0; - - } - asect->lineno = lineno_cache; - /* FIXME, free native_lineno here, or use alloca or something. */ - return true; -} - -static boolean -coff_slurp_symbol_table (abfd) - bfd * abfd; -{ - combined_entry_type *native_symbols; - coff_symbol_type *cached_area; - unsigned int *table_ptr; - - unsigned int number_of_symbols = 0; - - if (obj_symbols (abfd)) - return true; - - /* Read in the symbol table */ - if ((native_symbols = coff_get_normalized_symtab (abfd)) == NULL) - { - return (false); - } /* on error */ - - /* Allocate enough room for all the symbols in cached form */ - cached_area = ((coff_symbol_type *) - bfd_alloc (abfd, - (obj_raw_syment_count (abfd) - * sizeof (coff_symbol_type)))); - - if (cached_area == NULL) - return false; - table_ptr = ((unsigned int *) - bfd_alloc (abfd, - (obj_raw_syment_count (abfd) - * sizeof (unsigned int)))); - - if (table_ptr == NULL) - return false; - else - { - coff_symbol_type *dst = cached_area; - unsigned int last_native_index = obj_raw_syment_count (abfd); - unsigned int this_index = 0; - while (this_index < last_native_index) - { - combined_entry_type *src = native_symbols + this_index; - table_ptr[this_index] = number_of_symbols; - dst->symbol.the_bfd = abfd; - - dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset); - /* We use the native name field to point to the cached field. */ - src->u.syment._n._n_n._n_zeroes = (long) dst; - dst->symbol.section = coff_section_from_bfd_index (abfd, - src->u.syment.n_scnum); - dst->symbol.flags = 0; - dst->done_lineno = false; - - switch (src->u.syment.n_sclass) - { -#ifdef I960 - case C_LEAFEXT: -#if 0 - dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma; - dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; - dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION; -#endif - /* Fall through to next case */ - -#endif - - case C_EXT: -#ifdef RS6000COFF_C - case C_HIDEXT: -#endif -#ifdef COFF_WITH_PE - /* PE uses storage class 0x68 to denote a section symbol */ - case C_SECTION: - /* PE uses storage class 0x67 for a weak external symbol. */ - case C_NT_WEAK: -#endif - if ((src->u.syment.n_scnum) == 0) - { - if ((src->u.syment.n_value) == 0) - { - dst->symbol.section = bfd_und_section_ptr; - dst->symbol.value = 0; - } - else - { - dst->symbol.section = bfd_com_section_ptr; - dst->symbol.value = (src->u.syment.n_value); - } - } - else - { - /* Base the value as an index from the base of the - section */ - - dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; - dst->symbol.value = (src->u.syment.n_value - - dst->symbol.section->vma); - - if (ISFCN ((src->u.syment.n_type))) - { - /* A function ext does not go at the end of a - file. */ - dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION; - } - } - -#ifdef RS6000COFF_C - /* A C_HIDEXT symbol is not global. */ - if (src->u.syment.n_sclass == C_HIDEXT) - dst->symbol.flags = BSF_LOCAL; - /* A symbol with a csect entry should not go at the end. */ - if (src->u.syment.n_numaux > 0) - dst->symbol.flags |= BSF_NOT_AT_END; -#endif - -#ifdef COFF_WITH_PE - if (src->u.syment.n_sclass == C_NT_WEAK) - dst->symbol.flags = BSF_WEAK; -#endif - - break; - - case C_STAT: /* static */ -#ifdef I960 - case C_LEAFSTAT: /* static leaf procedure */ -#endif - case C_LABEL: /* label */ - if (src->u.syment.n_scnum == -2) - dst->symbol.flags = BSF_DEBUGGING; - else - dst->symbol.flags = BSF_LOCAL; - /* - Base the value as an index from the base of the section, if - there is one - */ - if (dst->symbol.section) - dst->symbol.value = (src->u.syment.n_value) - - dst->symbol.section->vma; - else - dst->symbol.value = (src->u.syment.n_value); - break; - - case C_MOS: /* member of structure */ - case C_EOS: /* end of structure */ -#ifdef NOTDEF /* C_AUTOARG has the same value */ -#ifdef C_GLBLREG - case C_GLBLREG: /* A29k-specific storage class */ -#endif -#endif - case C_REGPARM: /* register parameter */ - case C_REG: /* register variable */ -#ifdef C_AUTOARG - case C_AUTOARG: /* 960-specific storage class */ -#endif - case C_TPDEF: /* type definition */ - case C_ARG: - case C_AUTO: /* automatic variable */ - case C_FIELD: /* bit field */ - case C_ENTAG: /* enumeration tag */ - case C_MOE: /* member of enumeration */ - case C_MOU: /* member of union */ - case C_UNTAG: /* union tag */ - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->u.syment.n_value); - break; - - case C_FILE: /* file name */ - case C_STRTAG: /* structure tag */ -#ifdef RS6000COFF_C - case C_GSYM: - case C_LSYM: - case C_PSYM: - case C_RSYM: - case C_RPSYM: - case C_STSYM: - case C_BCOMM: - case C_ECOMM: - case C_DECL: - case C_ENTRY: - case C_FUN: - case C_ESTAT: -#endif - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->u.syment.n_value); - break; - -#ifdef RS6000COFF_C - case C_BINCL: /* beginning of include file */ - case C_EINCL: /* ending of include file */ - /* The value is actually a pointer into the line numbers - of the file. We locate the line number entry, and - set the section to the section which contains it, and - the value to the index in that section. */ - { - asection *sec; - - dst->symbol.flags = BSF_DEBUGGING; - for (sec = abfd->sections; sec != NULL; sec = sec->next) - if (sec->line_filepos <= (file_ptr) src->u.syment.n_value - && ((file_ptr) (sec->line_filepos - + sec->lineno_count * LINESZ) - > (file_ptr) src->u.syment.n_value)) - break; - if (sec == NULL) - dst->symbol.value = 0; - else - { - dst->symbol.section = sec; - dst->symbol.value = ((src->u.syment.n_value - - sec->line_filepos) - / LINESZ); - src->fix_line = 1; - } - } - break; - - case C_BSTAT: - dst->symbol.flags = BSF_DEBUGGING; - - /* The value is actually a symbol index. Save a pointer - to the symbol instead of the index. FIXME: This - should use a union. */ - src->u.syment.n_value = - (long) (native_symbols + src->u.syment.n_value); - dst->symbol.value = src->u.syment.n_value; - src->fix_value = 1; - break; -#endif - - case C_BLOCK: /* ".bb" or ".eb" */ - case C_FCN: /* ".bf" or ".ef" */ - case C_EFCN: /* physical end of function */ - dst->symbol.flags = BSF_LOCAL; - /* - Base the value as an index from the base of the section - */ - dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma; - break; - - case C_NULL: - case C_EXTDEF: /* external definition */ - case C_ULABEL: /* undefined label */ - case C_USTATIC: /* undefined static */ -#ifndef COFF_WITH_PE - /* C_LINE in regular coff is 0x68. NT has taken over this storage - class to represent a section symbol */ - case C_LINE: /* line # reformatted as symbol table entry */ - /* NT uses 0x67 for a weak symbol, not C_ALIAS. */ - case C_ALIAS: /* duplicate tag */ -#endif - case C_HIDDEN: /* ext symbol in dmert public lib */ - default: - (*_bfd_error_handler) - ("%s: Unrecognized storage class %d for %s symbol `%s'", - bfd_get_filename (abfd), src->u.syment.n_sclass, - dst->symbol.section->name, dst->symbol.name); - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->u.syment.n_value); - break; - } - -/* BFD_ASSERT(dst->symbol.flags != 0);*/ - - dst->native = src; - - dst->symbol.udata.i = 0; - dst->lineno = (alent *) NULL; - this_index += (src->u.syment.n_numaux) + 1; - dst++; - number_of_symbols++; - } /* walk the native symtab */ - } /* bfdize the native symtab */ - - obj_symbols (abfd) = cached_area; - obj_raw_syments (abfd) = native_symbols; - - bfd_get_symcount (abfd) = number_of_symbols; - obj_convert (abfd) = table_ptr; - /* Slurp the line tables for each section too */ - { - asection *p; - p = abfd->sections; - while (p) - { - coff_slurp_line_table (abfd, p); - p = p->next; - } - } - return true; -} /* coff_slurp_symbol_table() */ - -/* Check whether a symbol is globally visible. This is used by the - COFF backend linker code in cofflink.c, since a couple of targets - have globally visible symbols which are not class C_EXT. This - function need not handle the case of n_class == C_EXT. */ - -#undef OTHER_GLOBAL_CLASS - -#ifdef I960 -#define OTHER_GLOBAL_CLASS C_LEAFEXT -#endif - -#ifdef COFF_WITH_PE -#define OTHER_GLOBAL_CLASS C_SECTION -#endif - -#ifdef OTHER_GLOBAL_CLASS - -static boolean -coff_sym_is_global (abfd, syment) - bfd *abfd; - struct internal_syment *syment; -{ - if (syment->n_sclass == OTHER_GLOBAL_CLASS) - return true; - return false; -} - -#undef OTHER_GLOBAL_CLASS - -#else /* ! defined (OTHER_GLOBAL_CLASS) */ - -/* sym_is_global should not be defined if it has nothing to do. */ - -#define coff_sym_is_global 0 - -#endif /* ! defined (OTHER_GLOBAL_CLASS) */ - -/* -SUBSUBSECTION - Reading relocations - - Coff relocations are easily transformed into the internal BFD form - (@code{arelent}). - - Reading a coff relocation table is done in the following stages: - - o Read the entire coff relocation table into memory. - - o Process each relocation in turn; first swap it from the - external to the internal form. - - o Turn the symbol referenced in the relocation's symbol index - into a pointer into the canonical symbol table. - This table is the same as the one returned by a call to - @code{bfd_canonicalize_symtab}. The back end will call that - routine and save the result if a canonicalization hasn't been done. - - o The reloc index is turned into a pointer to a howto - structure, in a back end specific way. For instance, the 386 - and 960 use the @code{r_type} to directly produce an index - into a howto table vector; the 88k subtracts a number from the - @code{r_type} field and creates an addend field. - - -*/ - -#ifndef CALC_ADDEND -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - } -#endif - -static boolean -coff_slurp_reloc_table (abfd, asect, symbols) - bfd * abfd; - sec_ptr asect; - asymbol ** symbols; -{ - RELOC *native_relocs; - arelent *reloc_cache; - arelent *cache_ptr; - - unsigned int idx; - - if (asect->relocation) - return true; - if (asect->reloc_count == 0) - return true; - if (asect->flags & SEC_CONSTRUCTOR) - return true; - if (!coff_slurp_symbol_table (abfd)) - return false; - native_relocs = - (RELOC *) buy_and_read (abfd, - asect->rel_filepos, - SEEK_SET, - (size_t) (RELSZ * - asect->reloc_count)); - reloc_cache = (arelent *) - bfd_alloc (abfd, (size_t) (asect->reloc_count * sizeof (arelent))); - - if (reloc_cache == NULL) - return false; - - - for (idx = 0; idx < asect->reloc_count; idx++) - { -#ifdef RELOC_PROCESSING - struct internal_reloc dst; - struct external_reloc *src; - - cache_ptr = reloc_cache + idx; - src = native_relocs + idx; - coff_swap_reloc_in (abfd, src, &dst); - - RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect); -#else - struct internal_reloc dst; - asymbol *ptr; - struct external_reloc *src; - - cache_ptr = reloc_cache + idx; - src = native_relocs + idx; - - coff_swap_reloc_in (abfd, src, &dst); - - - cache_ptr->address = dst.r_vaddr; - - if (dst.r_symndx != -1) - { - /* @@ Should never be greater than count of symbols! */ - if (dst.r_symndx >= obj_conv_table_size (abfd)) - abort (); - cache_ptr->sym_ptr_ptr = symbols + obj_convert (abfd)[dst.r_symndx]; - ptr = *(cache_ptr->sym_ptr_ptr); - } - else - { - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - ptr = 0; - } - - /* The symbols definitions that we have read in have been - relocated as if their sections started at 0. But the offsets - refering to the symbols in the raw data have not been - modified, so we have to have a negative addend to compensate. - - Note that symbols which used to be common must be left alone */ - - /* Calculate any reloc addend by looking at the symbol */ - CALC_ADDEND (abfd, ptr, dst, cache_ptr); - - cache_ptr->address -= asect->vma; -/* !! cache_ptr->section = (asection *) NULL;*/ - - /* Fill in the cache_ptr->howto field from dst.r_type */ - RTYPE2HOWTO (cache_ptr, &dst); -#endif - - } - - asect->relocation = reloc_cache; - return true; -} - -#ifndef coff_rtype_to_howto -#ifdef RTYPE2HOWTO - -/* Get the howto structure for a reloc. This is only used if the file - including this one defines coff_relocate_section to be - _bfd_coff_generic_relocate_section, so it is OK if it does not - always work. It is the responsibility of the including file to - make sure it is reasonable if it is needed. */ - -static reloc_howto_type *coff_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *)); - -/*ARGSUSED*/ -static reloc_howto_type * -coff_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - arelent genrel; - - RTYPE2HOWTO (&genrel, rel); - return genrel.howto; -} - -#else /* ! defined (RTYPE2HOWTO) */ - -#define coff_rtype_to_howto NULL - -#endif /* ! defined (RTYPE2HOWTO) */ -#endif /* ! defined (coff_rtype_to_howto) */ - -/* This is stupid. This function should be a boolean predicate. */ -static long -coff_canonicalize_reloc (abfd, section, relptr, symbols) - bfd * abfd; - sec_ptr section; - arelent ** relptr; - asymbol ** symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count = 0; - - - if (section->flags & SEC_CONSTRUCTOR) - { - /* this section has relocs made up by us, they are not in the - file, so take them out of their chain and place them into - the data area provided */ - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - - } - else - { - if (! coff_slurp_reloc_table (abfd, section, symbols)) - return -1; - - tblptr = section->relocation; - - for (; count++ < section->reloc_count;) - *relptr++ = tblptr++; - - - } - *relptr = 0; - return section->reloc_count; -} - -#ifdef GNU960 -file_ptr -coff_sym_filepos (abfd) - bfd *abfd; -{ - return obj_sym_filepos (abfd); -} -#endif - -#ifndef coff_reloc16_estimate -#define coff_reloc16_estimate dummy_reloc16_estimate - -static int -dummy_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *reloc; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - abort (); -} - -#endif - -#ifndef coff_reloc16_extra_cases -#define coff_reloc16_extra_cases dummy_reloc16_extra_cases -/* This works even if abort is not declared in any header file. */ -static void -dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, - dst_ptr) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - abort (); -} -#endif - -/* If coff_relocate_section is defined, we can use the optimized COFF - backend linker. Otherwise we must continue to use the old linker. */ -#ifdef coff_relocate_section -#ifndef coff_bfd_link_hash_table_create -#define coff_bfd_link_hash_table_create _bfd_coff_link_hash_table_create -#endif -#ifndef coff_bfd_link_add_symbols -#define coff_bfd_link_add_symbols _bfd_coff_link_add_symbols -#endif -#ifndef coff_bfd_final_link -#define coff_bfd_final_link _bfd_coff_final_link -#endif -#else /* ! defined (coff_relocate_section) */ -#define coff_relocate_section NULL -#define coff_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#ifndef coff_bfd_link_add_symbols -#define coff_bfd_link_add_symbols _bfd_generic_link_add_symbols -#endif -#define coff_bfd_final_link _bfd_generic_final_link -#endif /* ! defined (coff_relocate_section) */ -#define coff_bfd_link_split_section _bfd_generic_link_split_section - -#ifndef coff_start_final_link -#define coff_start_final_link NULL -#endif - -#ifndef coff_adjust_symndx -#define coff_adjust_symndx NULL -#endif - -#ifndef coff_link_add_one_symbol -#define coff_link_add_one_symbol _bfd_generic_link_add_one_symbol -#endif - -static CONST bfd_coff_backend_data bfd_coff_std_swap_table = -{ - coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, - coff_swap_aux_out, coff_swap_sym_out, - coff_swap_lineno_out, coff_swap_reloc_out, - coff_swap_filehdr_out, coff_swap_aouthdr_out, - coff_swap_scnhdr_out, - FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ, -#ifdef COFF_LONG_FILENAMES - true, -#else - false, -#endif - coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in, - coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, - coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, - coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook, - coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, - coff_sym_is_global, coff_compute_section_file_positions, - coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, - coff_adjust_symndx, coff_link_add_one_symbol -}; - -#define coff_close_and_cleanup _bfd_generic_close_and_cleanup -#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define coff_get_section_contents _bfd_generic_get_section_contents - -#ifndef coff_bfd_copy_private_symbol_data -#define coff_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data -#endif - -#ifndef coff_bfd_copy_private_section_data -#define coff_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data -#endif - -#ifndef coff_bfd_copy_private_bfd_data -#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data -#endif - -#define coff_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data -#define coff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags - -#ifndef coff_bfd_print_private_bfd_data -#define coff_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data -#endif - -#ifndef coff_bfd_is_local_label -#define coff_bfd_is_local_label bfd_generic_is_local_label -#endif -#ifndef coff_read_minisymbols -#define coff_read_minisymbols _bfd_generic_read_minisymbols -#endif -#ifndef coff_minisymbol_to_symbol -#define coff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#endif - -/* The reloc lookup routine must be supplied by each individual COFF - backend. */ -#ifndef coff_bfd_reloc_type_lookup -#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup -#endif - -#ifndef coff_bfd_get_relocated_section_contents -#define coff_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#endif -#ifndef coff_bfd_relax_section -#define coff_bfd_relax_section bfd_generic_relax_section -#endif diff --git a/contrib/gdb/bfd/coffgen.c b/contrib/gdb/bfd/coffgen.c deleted file mode 100644 index 285fe61ccc5..00000000000 --- a/contrib/gdb/bfd/coffgen.c +++ /dev/null @@ -1,2121 +0,0 @@ -/* Support for the generic parts of COFF, for BFD. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Most of this hacked by Steve Chamberlain, sac@cygnus.com. - Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */ - -/* This file contains COFF code that is not dependent on any - particular COFF target. There is only one version of this file in - libbfd.a, so no target specific code may be put in here. Or, to - put it another way, - - ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE ********** - - If you need to add some target specific behaviour, add a new hook - function to bfd_coff_backend_data. - - Some of these functions are also called by the ECOFF routines. - Those functions may not use any COFF specific information, such as - coff_data (abfd). */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -static void coff_fix_symbol_name - PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_size_type *, - asection **, bfd_size_type *)); -static boolean coff_write_symbol - PARAMS ((bfd *, asymbol *, combined_entry_type *, unsigned int *, - bfd_size_type *, asection **, bfd_size_type *)); -static boolean coff_write_alien_symbol - PARAMS ((bfd *, asymbol *, unsigned int *, bfd_size_type *, - asection **, bfd_size_type *)); -static boolean coff_write_native_symbol - PARAMS ((bfd *, coff_symbol_type *, unsigned int *, bfd_size_type *, - asection **, bfd_size_type *)); -static void coff_pointerize_aux - PARAMS ((bfd *, combined_entry_type *, combined_entry_type *, - unsigned int, combined_entry_type *)); - -#define STRING_SIZE_SIZE (4) - -/* Take a section header read from a coff file (in HOST byte order), - and make a BFD "section" out of it. This is used by ECOFF. */ -static boolean -make_a_section_from_file (abfd, hdr, target_index) - bfd *abfd; - struct internal_scnhdr *hdr; - unsigned int target_index; -{ - asection *return_section; - char *name; - - /* Assorted wastage to null-terminate the name, thanks AT&T! */ - name = bfd_alloc (abfd, sizeof (hdr->s_name) + 1); - if (name == NULL) - return false; - strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); - name[sizeof (hdr->s_name)] = 0; - - return_section = bfd_make_section_anyway (abfd, name); - if (return_section == NULL) - return false; - - return_section->vma = hdr->s_vaddr; - return_section->lma = hdr->s_paddr; - return_section->_raw_size = hdr->s_size; - return_section->filepos = hdr->s_scnptr; - return_section->rel_filepos = hdr->s_relptr; - return_section->reloc_count = hdr->s_nreloc; - - bfd_coff_set_alignment_hook (abfd, return_section, hdr); - - return_section->line_filepos = hdr->s_lnnoptr; - - return_section->lineno_count = hdr->s_nlnno; - return_section->userdata = NULL; - return_section->next = (asection *) NULL; - return_section->flags = bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name); - - return_section->target_index = target_index; - - /* At least on i386-coff, the line number count for a shared library - section must be ignored. */ - if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0) - return_section->lineno_count = 0; - - if (hdr->s_nreloc != 0) - return_section->flags |= SEC_RELOC; - /* FIXME: should this check 'hdr->s_size > 0' */ - if (hdr->s_scnptr != 0) - return_section->flags |= SEC_HAS_CONTENTS; - return true; -} - -/* Read in a COFF object and make it into a BFD. This is used by - ECOFF as well. */ - -static const bfd_target * -coff_real_object_p (abfd, nscns, internal_f, internal_a) - bfd *abfd; - unsigned nscns; - struct internal_filehdr *internal_f; - struct internal_aouthdr *internal_a; -{ - flagword oflags = abfd->flags; - bfd_vma ostart = bfd_get_start_address (abfd); - PTR tdata; - size_t readsize; /* length of file_info */ - unsigned int scnhsz; - char *external_sections; - - if (!(internal_f->f_flags & F_RELFLG)) - abfd->flags |= HAS_RELOC; - if ((internal_f->f_flags & F_EXEC)) - abfd->flags |= EXEC_P; - if (!(internal_f->f_flags & F_LNNO)) - abfd->flags |= HAS_LINENO; - if (!(internal_f->f_flags & F_LSYMS)) - abfd->flags |= HAS_LOCALS; - - /* FIXME: How can we set D_PAGED correctly? */ - if ((internal_f->f_flags & F_EXEC) != 0) - abfd->flags |= D_PAGED; - - bfd_get_symcount (abfd) = internal_f->f_nsyms; - if (internal_f->f_nsyms) - abfd->flags |= HAS_SYMS; - - if (internal_a != (struct internal_aouthdr *) NULL) - bfd_get_start_address (abfd) = internal_a->entry; - else - bfd_get_start_address (abfd) = 0; - - /* Set up the tdata area. ECOFF uses its own routine, and overrides - abfd->flags. */ - tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a); - if (tdata == NULL) - return 0; - - scnhsz = bfd_coff_scnhsz (abfd); - readsize = nscns * scnhsz; - external_sections = (char *) bfd_alloc (abfd, readsize); - if (!external_sections) - goto fail; - - if (bfd_read ((PTR) external_sections, 1, readsize, abfd) != readsize) - goto fail; - - /* Now copy data as required; construct all asections etc */ - if (nscns != 0) - { - unsigned int i; - for (i = 0; i < nscns; i++) - { - struct internal_scnhdr tmp; - bfd_coff_swap_scnhdr_in (abfd, - (PTR) (external_sections + i * scnhsz), - (PTR) & tmp); - make_a_section_from_file (abfd, &tmp, i + 1); - } - } - - /* make_abs_section (abfd); */ - - if (bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f) == false) - goto fail; - - return abfd->xvec; - - fail: - bfd_release (abfd, tdata); - abfd->flags = oflags; - bfd_get_start_address (abfd) = ostart; - return (const bfd_target *) NULL; -} - -/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is - not a COFF file. This is also used by ECOFF. */ - -const bfd_target * -coff_object_p (abfd) - bfd *abfd; -{ - unsigned int filhsz; - unsigned int aoutsz; - int nscns; - PTR filehdr; - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - - /* figure out how much to read */ - filhsz = bfd_coff_filhsz (abfd); - aoutsz = bfd_coff_aoutsz (abfd); - - filehdr = bfd_alloc (abfd, filhsz); - if (filehdr == NULL) - return 0; - if (bfd_read (filehdr, 1, filhsz, abfd) != filhsz) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f); - bfd_release (abfd, filehdr); - - if (bfd_coff_bad_format_hook (abfd, &internal_f) == false) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - nscns = internal_f.f_nscns; - - if (internal_f.f_opthdr) - { - PTR opthdr; - - opthdr = bfd_alloc (abfd, aoutsz); - if (opthdr == NULL) - return 0;; - if (bfd_read (opthdr, 1, aoutsz, abfd) != aoutsz) - { - return 0; - } - bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) & internal_a); - } - - /* Seek past the opt hdr stuff */ - if (bfd_seek (abfd, (file_ptr) (internal_f.f_opthdr + filhsz), SEEK_SET) - != 0) - return NULL; - - return coff_real_object_p (abfd, nscns, &internal_f, - (internal_f.f_opthdr != 0 - ? &internal_a - : (struct internal_aouthdr *) NULL)); -} - -/* Get the BFD section from a COFF symbol section number. */ - -asection * -coff_section_from_bfd_index (abfd, index) - bfd *abfd; - int index; -{ - struct sec *answer = abfd->sections; - - if (index == N_ABS) - return bfd_abs_section_ptr; - if (index == N_UNDEF) - return bfd_und_section_ptr; - if (index == N_DEBUG) - return bfd_abs_section_ptr; - - while (answer) - { - if (answer->target_index == index) - return answer; - answer = answer->next; - } - - /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a - has a bad symbol table in biglitpow.o. */ - return bfd_und_section_ptr; -} - -/* Get the upper bound of a COFF symbol table. */ - -long -coff_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - if (!bfd_coff_slurp_symbol_table (abfd)) - return -1; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *)); -} - - -/* Canonicalize a COFF symbol table. */ - -long -coff_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - unsigned int counter; - coff_symbol_type *symbase; - coff_symbol_type **location = (coff_symbol_type **) alocation; - - if (!bfd_coff_slurp_symbol_table (abfd)) - return -1; - - symbase = obj_symbols (abfd); - counter = bfd_get_symcount (abfd); - while (counter-- > 0) - *location++ = symbase++; - - *location = NULL; - - return bfd_get_symcount (abfd); -} - -/* Get the name of a symbol. The caller must pass in a buffer of size - >= SYMNMLEN + 1. */ - -const char * -_bfd_coff_internal_syment_name (abfd, sym, buf) - bfd *abfd; - const struct internal_syment *sym; - char *buf; -{ - /* FIXME: It's not clear this will work correctly if sizeof - (_n_zeroes) != 4. */ - if (sym->_n._n_n._n_zeroes != 0 - || sym->_n._n_n._n_offset == 0) - { - memcpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - return buf; - } - else - { - const char *strings; - - BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE); - strings = obj_coff_strings (abfd); - if (strings == NULL) - { - strings = _bfd_coff_read_string_table (abfd); - if (strings == NULL) - return NULL; - } - return strings + sym->_n._n_n._n_offset; - } -} - -/* Read in and swap the relocs. This returns a buffer holding the - relocs for section SEC in file ABFD. If CACHE is true and - INTERNAL_RELOCS is NULL, the relocs read in will be saved in case - the function is called again. If EXTERNAL_RELOCS is not NULL, it - is a buffer large enough to hold the unswapped relocs. If - INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold - the swapped relocs. If REQUIRE_INTERNAL is true, then the return - value must be INTERNAL_RELOCS. The function returns NULL on error. */ - -struct internal_reloc * -_bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, - require_internal, internal_relocs) - bfd *abfd; - asection *sec; - boolean cache; - bfd_byte *external_relocs; - boolean require_internal; - struct internal_reloc *internal_relocs; -{ - bfd_size_type relsz; - bfd_byte *free_external = NULL; - struct internal_reloc *free_internal = NULL; - bfd_byte *erel; - bfd_byte *erel_end; - struct internal_reloc *irel; - - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->relocs != NULL) - { - if (! require_internal) - return coff_section_data (abfd, sec)->relocs; - memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs, - sec->reloc_count * sizeof (struct internal_reloc)); - return internal_relocs; - } - - relsz = bfd_coff_relsz (abfd); - - if (external_relocs == NULL) - { - free_external = (bfd_byte *) bfd_malloc (sec->reloc_count * relsz); - if (free_external == NULL && sec->reloc_count > 0) - goto error_return; - external_relocs = free_external; - } - - if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 - || (bfd_read (external_relocs, relsz, sec->reloc_count, abfd) - != relsz * sec->reloc_count)) - goto error_return; - - if (internal_relocs == NULL) - { - free_internal = ((struct internal_reloc *) - bfd_malloc (sec->reloc_count - * sizeof (struct internal_reloc))); - if (free_internal == NULL && sec->reloc_count > 0) - goto error_return; - internal_relocs = free_internal; - } - - /* Swap in the relocs. */ - erel = external_relocs; - erel_end = erel + relsz * sec->reloc_count; - irel = internal_relocs; - for (; erel < erel_end; erel += relsz, irel++) - bfd_coff_swap_reloc_in (abfd, (PTR) erel, (PTR) irel); - - if (free_external != NULL) - { - free (free_external); - free_external = NULL; - } - - if (cache && free_internal != NULL) - { - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - (PTR) bfd_zalloc (abfd, - sizeof (struct coff_section_tdata)); - if (sec->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, sec)->contents = NULL; - } - coff_section_data (abfd, sec)->relocs = free_internal; - } - - return internal_relocs; - - error_return: - if (free_external != NULL) - free (free_external); - if (free_internal != NULL) - free (free_internal); - return NULL; -} - -/* Set lineno_count for the output sections of a COFF file. */ - -int -coff_count_linenumbers (abfd) - bfd *abfd; -{ - unsigned int limit = bfd_get_symcount (abfd); - unsigned int i; - int total = 0; - asymbol **p; - asection *s; - - if (limit == 0) - { - /* This may be from the backend linker, in which case the - lineno_count in the sections is correct. */ - for (s = abfd->sections; s != NULL; s = s->next) - total += s->lineno_count; - return total; - } - - for (s = abfd->sections; s != NULL; s = s->next) - BFD_ASSERT (s->lineno_count == 0); - - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) - { - asymbol *q_maybe = *p; - - if (bfd_asymbol_flavour (q_maybe) == bfd_target_coff_flavour) - { - coff_symbol_type *q = coffsymbol (q_maybe); - - /* The AIX 4.1 compiler can sometimes generate line numbers - attached to debugging symbols. We try to simply ignore - those here. */ - if (q->lineno != NULL - && q->symbol.section->owner != NULL) - { - /* This symbol has line numbers. Increment the owning - section's linenumber count. */ - alent *l = q->lineno; - - ++q->symbol.section->output_section->lineno_count; - ++total; - ++l; - while (l->line_number != 0) - { - ++total; - ++q->symbol.section->output_section->lineno_count; - ++l; - } - } - } - } - - return total; -} - -/* Takes a bfd and a symbol, returns a pointer to the coff specific - area of the symbol if there is one. */ - -/*ARGSUSED*/ -coff_symbol_type * -coff_symbol_from (ignore_abfd, symbol) - bfd *ignore_abfd; - asymbol *symbol; -{ - if (bfd_asymbol_flavour (symbol) != bfd_target_coff_flavour) - return (coff_symbol_type *) NULL; - - if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL) - return (coff_symbol_type *) NULL; - - return (coff_symbol_type *) symbol; -} - -static void -fixup_symbol_value (coff_symbol_ptr, syment) - coff_symbol_type *coff_symbol_ptr; - struct internal_syment *syment; -{ - - /* Normalize the symbol flags */ - if (bfd_is_com_section (coff_symbol_ptr->symbol.section)) - { - /* a common symbol is undefined with a value */ - syment->n_scnum = N_UNDEF; - syment->n_value = coff_symbol_ptr->symbol.value; - } - else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) - { - syment->n_value = coff_symbol_ptr->symbol.value; - } - else if (bfd_is_und_section (coff_symbol_ptr->symbol.section)) - { - syment->n_scnum = N_UNDEF; - syment->n_value = 0; - } - else - { - if (coff_symbol_ptr->symbol.section) - { - syment->n_scnum = - coff_symbol_ptr->symbol.section->output_section->target_index; - - syment->n_value = - coff_symbol_ptr->symbol.value + - coff_symbol_ptr->symbol.section->output_offset + - coff_symbol_ptr->symbol.section->output_section->vma; - } - else - { - BFD_ASSERT (0); - /* This can happen, but I don't know why yet (steve@cygnus.com) */ - syment->n_scnum = N_ABS; - syment->n_value = coff_symbol_ptr->symbol.value; - } - } -} - -/* Run through all the symbols in the symbol table and work out what - their indexes into the symbol table will be when output. - - Coff requires that each C_FILE symbol points to the next one in the - chain, and that the last one points to the first external symbol. We - do that here too. */ - -boolean -coff_renumber_symbols (bfd_ptr, first_undef) - bfd *bfd_ptr; - int *first_undef; -{ - unsigned int symbol_count = bfd_get_symcount (bfd_ptr); - asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; - unsigned int native_index = 0; - struct internal_syment *last_file = (struct internal_syment *) NULL; - unsigned int symbol_index; - - /* COFF demands that undefined symbols come after all other symbols. - Since we don't need to impose this extra knowledge on all our - client programs, deal with that here. Sort the symbol table; - just move the undefined symbols to the end, leaving the rest - alone. The O'Reilly book says that defined global symbols come - at the end before the undefined symbols, so we do that here as - well. */ - /* @@ Do we have some condition we could test for, so we don't always - have to do this? I don't think relocatability is quite right, but - I'm not certain. [raeburn:19920508.1711EST] */ - { - asymbol **newsyms; - unsigned int i; - - newsyms = (asymbol **) bfd_alloc_by_size_t (bfd_ptr, - sizeof (asymbol *) - * (symbol_count + 1)); - if (!newsyms) - return false; - bfd_ptr->outsymbols = newsyms; - for (i = 0; i < symbol_count; i++) - if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 - || (!bfd_is_und_section (symbol_ptr_ptr[i]->section) - && !bfd_is_com_section (symbol_ptr_ptr[i]->section) - && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_FUNCTION)) - != BSF_GLOBAL))) - *newsyms++ = symbol_ptr_ptr[i]; - - for (i = 0; i < symbol_count; i++) - if (!bfd_is_und_section (symbol_ptr_ptr[i]->section) - && (bfd_is_com_section (symbol_ptr_ptr[i]->section) - || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL - | BSF_NOT_AT_END - | BSF_FUNCTION)) - == BSF_GLOBAL))) - *newsyms++ = symbol_ptr_ptr[i]; - - *first_undef = newsyms - bfd_ptr->outsymbols; - - for (i = 0; i < symbol_count; i++) - if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 - && bfd_is_und_section (symbol_ptr_ptr[i]->section)) - *newsyms++ = symbol_ptr_ptr[i]; - *newsyms = (asymbol *) NULL; - symbol_ptr_ptr = bfd_ptr->outsymbols; - } - - for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) - { - coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); - symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; - if (coff_symbol_ptr && coff_symbol_ptr->native) - { - combined_entry_type *s = coff_symbol_ptr->native; - int i; - - if (s->u.syment.n_sclass == C_FILE) - { - if (last_file != (struct internal_syment *) NULL) - last_file->n_value = native_index; - last_file = &(s->u.syment); - } - else - { - - /* Modify the symbol values according to their section and - type */ - - fixup_symbol_value (coff_symbol_ptr, &(s->u.syment)); - } - for (i = 0; i < s->u.syment.n_numaux + 1; i++) - s[i].offset = native_index++; - } - else - { - native_index++; - } - } - obj_conv_table_size (bfd_ptr) = native_index; - - return true; -} - -/* Run thorough the symbol table again, and fix it so that all - pointers to entries are changed to the entries' index in the output - symbol table. */ - -void -coff_mangle_symbols (bfd_ptr) - bfd *bfd_ptr; -{ - unsigned int symbol_count = bfd_get_symcount (bfd_ptr); - asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; - unsigned int symbol_index; - - for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) - { - coff_symbol_type *coff_symbol_ptr = - coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); - - if (coff_symbol_ptr && coff_symbol_ptr->native) - { - int i; - combined_entry_type *s = coff_symbol_ptr->native; - - if (s->fix_value) - { - /* FIXME: We should use a union here. */ - s->u.syment.n_value = - ((combined_entry_type *) s->u.syment.n_value)->offset; - s->fix_value = 0; - } - if (s->fix_line) - { - /* The value is the offset into the line number entries - for the symbol's section. On output, the symbol's - section should be N_DEBUG. */ - s->u.syment.n_value = - (coff_symbol_ptr->symbol.section->output_section->line_filepos - + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr)); - coff_symbol_ptr->symbol.section = - coff_section_from_bfd_index (bfd_ptr, N_DEBUG); - BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING); - } - for (i = 0; i < s->u.syment.n_numaux; i++) - { - combined_entry_type *a = s + i + 1; - if (a->fix_tag) - { - a->u.auxent.x_sym.x_tagndx.l = - a->u.auxent.x_sym.x_tagndx.p->offset; - a->fix_tag = 0; - } - if (a->fix_end) - { - a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l = - a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset; - a->fix_end = 0; - } - if (a->fix_scnlen) - { - a->u.auxent.x_csect.x_scnlen.l = - a->u.auxent.x_csect.x_scnlen.p->offset; - a->fix_scnlen = 0; - } - } - } - } -} - -static void -coff_fix_symbol_name (abfd, symbol, native, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - asymbol *symbol; - combined_entry_type *native; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; -{ - unsigned int name_length; - union internal_auxent *auxent; - char *name = (char *) (symbol->name); - - if (name == (char *) NULL) - { - /* coff symbols always have names, so we'll make one up */ - symbol->name = "strange"; - name = (char *) symbol->name; - } - name_length = strlen (name); - - if (native->u.syment.n_sclass == C_FILE - && native->u.syment.n_numaux > 0) - { - strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); - auxent = &(native + 1)->u.auxent; - - if (bfd_coff_long_filenames (abfd)) - { - if (name_length <= FILNMLEN) - { - strncpy (auxent->x_file.x_fname, name, FILNMLEN); - } - else - { - auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; - auxent->x_file.x_n.x_zeroes = 0; - *string_size_p += name_length + 1; - } - } - else - { - strncpy (auxent->x_file.x_fname, name, FILNMLEN); - if (name_length > FILNMLEN) - { - name[FILNMLEN] = '\0'; - } - } - } - else - { - if (name_length <= SYMNMLEN) - { - /* This name will fit into the symbol neatly */ - strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN); - } - else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment)) - { - native->u.syment._n._n_n._n_offset = (*string_size_p - + STRING_SIZE_SIZE); - native->u.syment._n._n_n._n_zeroes = 0; - *string_size_p += name_length + 1; - } - else - { - long filepos; - bfd_byte buf[2]; - - /* This name should be written into the .debug section. For - some reason each name is preceded by a two byte length - and also followed by a null byte. FIXME: We assume that - the .debug section has already been created, and that it - is large enough. */ - if (*debug_string_section_p == (asection *) NULL) - *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug"); - filepos = bfd_tell (abfd); - bfd_put_16 (abfd, name_length + 1, buf); - if (!bfd_set_section_contents (abfd, - *debug_string_section_p, - (PTR) buf, - (file_ptr) *debug_string_size_p, - (bfd_size_type) 2) - || !bfd_set_section_contents (abfd, - *debug_string_section_p, - (PTR) symbol->name, - ((file_ptr) *debug_string_size_p - + 2), - (bfd_size_type) name_length + 1)) - abort (); - if (bfd_seek (abfd, filepos, SEEK_SET) != 0) - abort (); - native->u.syment._n._n_n._n_offset = *debug_string_size_p + 2; - native->u.syment._n._n_n._n_zeroes = 0; - *debug_string_size_p += name_length + 3; - } - } -} - -/* We need to keep track of the symbol index so that when we write out - the relocs we can get the index for a symbol. This method is a - hack. FIXME. */ - -#define set_index(symbol, idx) ((symbol)->udata.i = (idx)) - -/* Write a symbol out to a COFF file. */ - -static boolean -coff_write_symbol (abfd, symbol, native, written, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - asymbol *symbol; - combined_entry_type *native; - unsigned int *written; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; -{ - unsigned int numaux = native->u.syment.n_numaux; - int type = native->u.syment.n_type; - int class = native->u.syment.n_sclass; - PTR buf; - bfd_size_type symesz; - - if (native->u.syment.n_sclass == C_FILE) - symbol->flags |= BSF_DEBUGGING; - - if (symbol->flags & BSF_DEBUGGING - && bfd_is_abs_section (symbol->section)) - { - native->u.syment.n_scnum = N_DEBUG; - } - else if (bfd_is_abs_section (symbol->section)) - { - native->u.syment.n_scnum = N_ABS; - } - else if (bfd_is_und_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - } - else - { - native->u.syment.n_scnum = - symbol->section->output_section->target_index; - } - - coff_fix_symbol_name (abfd, symbol, native, string_size_p, - debug_string_section_p, debug_string_size_p); - - symesz = bfd_coff_symesz (abfd); - buf = bfd_alloc (abfd, symesz); - if (!buf) - return false; - bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); - if (bfd_write (buf, 1, symesz, abfd) != symesz) - return false; - bfd_release (abfd, buf); - - if (native->u.syment.n_numaux > 0) - { - bfd_size_type auxesz; - unsigned int j; - - auxesz = bfd_coff_auxesz (abfd); - buf = bfd_alloc (abfd, auxesz); - if (!buf) - return false; - for (j = 0; j < native->u.syment.n_numaux; j++) - { - bfd_coff_swap_aux_out (abfd, - &((native + j + 1)->u.auxent), - type, - class, - j, - native->u.syment.n_numaux, - buf); - if (bfd_write (buf, 1, auxesz, abfd) != auxesz) - return false; - } - bfd_release (abfd, buf); - } - - /* Store the index for use when we write out the relocs. */ - set_index (symbol, *written); - - *written += numaux + 1; - return true; -} - -/* Write out a symbol to a COFF file that does not come from a COFF - file originally. This symbol may have been created by the linker, - or we may be linking a non COFF file to a COFF file. */ - -static boolean -coff_write_alien_symbol (abfd, symbol, written, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - asymbol *symbol; - unsigned int *written; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; -{ - combined_entry_type *native; - combined_entry_type dummy; - - native = &dummy; - native->u.syment.n_type = T_NULL; - native->u.syment.n_flags = 0; - if (bfd_is_und_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else if (bfd_is_com_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else if (symbol->flags & BSF_DEBUGGING) - { - /* There isn't much point to writing out a debugging symbol - unless we are prepared to convert it into COFF debugging - format. So, we just ignore them. We must clobber the symbol - name to keep it from being put in the string table. */ - symbol->name = ""; - return true; - } - else - { - native->u.syment.n_scnum = - symbol->section->output_section->target_index; - native->u.syment.n_value = (symbol->value - + symbol->section->output_section->vma - + symbol->section->output_offset); - - /* Copy the any flags from the the file header into the symbol. - FIXME: Why? */ - { - coff_symbol_type *c = coff_symbol_from (abfd, symbol); - if (c != (coff_symbol_type *) NULL) - native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; - } - } - - native->u.syment.n_type = 0; - if (symbol->flags & BSF_LOCAL) - native->u.syment.n_sclass = C_STAT; - else - native->u.syment.n_sclass = C_EXT; - native->u.syment.n_numaux = 0; - - return coff_write_symbol (abfd, symbol, native, written, string_size_p, - debug_string_section_p, debug_string_size_p); -} - -/* Write a native symbol to a COFF file. */ - -static boolean -coff_write_native_symbol (abfd, symbol, written, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - coff_symbol_type *symbol; - unsigned int *written; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; -{ - combined_entry_type *native = symbol->native; - alent *lineno = symbol->lineno; - - /* If this symbol has an associated line number, we must store the - symbol index in the line number field. We also tag the auxent to - point to the right place in the lineno table. */ - if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL) - { - unsigned int count = 0; - lineno[count].u.offset = *written; - if (native->u.syment.n_numaux) - { - union internal_auxent *a = &((native + 1)->u.auxent); - - a->x_sym.x_fcnary.x_fcn.x_lnnoptr = - symbol->symbol.section->output_section->moving_line_filepos; - } - - /* Count and relocate all other linenumbers. */ - count++; - while (lineno[count].line_number != 0) - { -#if 0 - /* 13 april 92. sac - I've been told this, but still need proof: - > The second bug is also in `bfd/coffcode.h'. This bug - > causes the linker to screw up the pc-relocations for - > all the line numbers in COFF code. This bug isn't only - > specific to A29K implementations, but affects all - > systems using COFF format binaries. Note that in COFF - > object files, the line number core offsets output by - > the assembler are relative to the start of each - > procedure, not to the start of the .text section. This - > patch relocates the line numbers relative to the - > `native->u.syment.n_value' instead of the section - > virtual address. - > modular!olson@cs.arizona.edu (Jon Olson) - */ - lineno[count].u.offset += native->u.syment.n_value; -#else - lineno[count].u.offset += - (symbol->symbol.section->output_section->vma - + symbol->symbol.section->output_offset); -#endif - count++; - } - symbol->done_lineno = true; - - symbol->symbol.section->output_section->moving_line_filepos += - count * bfd_coff_linesz (abfd); - } - - return coff_write_symbol (abfd, &(symbol->symbol), native, written, - string_size_p, debug_string_section_p, - debug_string_size_p); -} - -/* Write out the COFF symbols. */ - -boolean -coff_write_symbols (abfd) - bfd *abfd; -{ - bfd_size_type string_size; - asection *debug_string_section; - bfd_size_type debug_string_size; - unsigned int i; - unsigned int limit = bfd_get_symcount (abfd); - unsigned int written = 0; - asymbol **p; - - string_size = 0; - debug_string_section = NULL; - debug_string_size = 0; - - /* Seek to the right place */ - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) - return false; - - /* Output all the symbols we have */ - - written = 0; - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) - { - asymbol *symbol = *p; - coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol); - - if (c_symbol == (coff_symbol_type *) NULL - || c_symbol->native == (combined_entry_type *) NULL) - { - if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size, - &debug_string_section, - &debug_string_size)) - return false; - } - else - { - if (!coff_write_native_symbol (abfd, c_symbol, &written, - &string_size, &debug_string_section, - &debug_string_size)) - return false; - } - } - - obj_raw_syment_count (abfd) = written; - - /* Now write out strings */ - - if (string_size != 0) - { - unsigned int size = string_size + STRING_SIZE_SIZE; - bfd_byte buffer[STRING_SIZE_SIZE]; - -#if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, size, buffer); -#else - #error Change bfd_h_put_32 -#endif - if (bfd_write ((PTR) buffer, 1, sizeof (buffer), abfd) != sizeof (buffer)) - return false; - for (p = abfd->outsymbols, i = 0; - i < limit; - i++, p++) - { - asymbol *q = *p; - size_t name_length = strlen (q->name); - coff_symbol_type *c_symbol = coff_symbol_from (abfd, q); - size_t maxlen; - - /* Figure out whether the symbol name should go in the string - table. Symbol names that are short enough are stored - directly in the syment structure. File names permit a - different, longer, length in the syment structure. On - XCOFF, some symbol names are stored in the .debug section - rather than in the string table. */ - - if (c_symbol == NULL - || c_symbol->native == NULL) - { - /* This is not a COFF symbol, so it certainly is not a - file name, nor does it go in the .debug section. */ - maxlen = SYMNMLEN; - } - else if (bfd_coff_symname_in_debug (abfd, - &c_symbol->native->u.syment)) - { - /* This symbol name is in the XCOFF .debug section. - Don't write it into the string table. */ - maxlen = name_length; - } - else if (c_symbol->native->u.syment.n_sclass == C_FILE - && c_symbol->native->u.syment.n_numaux > 0) - maxlen = FILNMLEN; - else - maxlen = SYMNMLEN; - - if (name_length > maxlen) - { - if (bfd_write ((PTR) (q->name), 1, name_length + 1, abfd) - != name_length + 1) - return false; - } - } - } - else - { - /* We would normally not write anything here, but we'll write - out 4 so that any stupid coff reader which tries to read the - string table even when there isn't one won't croak. */ - unsigned int size = STRING_SIZE_SIZE; - bfd_byte buffer[STRING_SIZE_SIZE]; - -#if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, size, buffer); -#else - #error Change bfd_h_put_32 -#endif - if (bfd_write ((PTR) buffer, 1, STRING_SIZE_SIZE, abfd) - != STRING_SIZE_SIZE) - return false; - } - - /* Make sure the .debug section was created to be the correct size. - We should create it ourselves on the fly, but we don't because - BFD won't let us write to any section until we know how large all - the sections are. We could still do it by making another pass - over the symbols. FIXME. */ - BFD_ASSERT (debug_string_size == 0 - || (debug_string_section != (asection *) NULL - && (BFD_ALIGN (debug_string_size, - 1 << debug_string_section->alignment_power) - == bfd_section_size (abfd, debug_string_section)))); - - return true; -} - -boolean -coff_write_linenumbers (abfd) - bfd *abfd; -{ - asection *s; - bfd_size_type linesz; - PTR buff; - - linesz = bfd_coff_linesz (abfd); - buff = bfd_alloc (abfd, linesz); - if (!buff) - return false; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (s->lineno_count) - { - asymbol **q = abfd->outsymbols; - if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0) - return false; - /* Find all the linenumbers in this section */ - while (*q) - { - asymbol *p = *q; - if (p->section->output_section == s) - { - alent *l = - BFD_SEND (bfd_asymbol_bfd (p), _get_lineno, - (bfd_asymbol_bfd (p), p)); - if (l) - { - /* Found a linenumber entry, output */ - struct internal_lineno out; - memset ((PTR) & out, 0, sizeof (out)); - out.l_lnno = 0; - out.l_addr.l_symndx = l->u.offset; - bfd_coff_swap_lineno_out (abfd, &out, buff); - if (bfd_write (buff, 1, linesz, abfd) != linesz) - return false; - l++; - while (l->line_number) - { - out.l_lnno = l->line_number; - out.l_addr.l_symndx = l->u.offset; - bfd_coff_swap_lineno_out (abfd, &out, buff); - if (bfd_write (buff, 1, linesz, abfd) != linesz) - return false; - l++; - } - } - } - q++; - } - } - } - bfd_release (abfd, buff); - return true; -} - -/*ARGSUSED */ -alent * -coff_get_lineno (ignore_abfd, symbol) - bfd *ignore_abfd; - asymbol *symbol; -{ - return coffsymbol (symbol)->lineno; -} - -#if 0 - -/* This is only called from coff_add_missing_symbols, which has been - disabled. */ - -asymbol * -coff_section_symbol (abfd, name) - bfd *abfd; - char *name; -{ - asection *sec = bfd_make_section_old_way (abfd, name); - asymbol *sym; - combined_entry_type *csym; - - sym = sec->symbol; - csym = coff_symbol_from (abfd, sym)->native; - /* Make sure back-end COFF stuff is there. */ - if (csym == 0) - { - struct foo - { - coff_symbol_type sym; - /* @@FIXME This shouldn't use a fixed size!! */ - combined_entry_type e[10]; - }; - struct foo *f; - f = (struct foo *) bfd_alloc_by_size_t (abfd, sizeof (*f)); - if (!f) - { - bfd_set_error (bfd_error_no_error); - return NULL; - } - memset ((char *) f, 0, sizeof (*f)); - coff_symbol_from (abfd, sym)->native = csym = f->e; - } - csym[0].u.syment.n_sclass = C_STAT; - csym[0].u.syment.n_numaux = 1; -/* SF_SET_STATICS (sym); @@ ??? */ - csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size; - csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count; - csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count; - - if (sec->output_section == NULL) - { - sec->output_section = sec; - sec->output_offset = 0; - } - - return sym; -} - -#endif /* 0 */ - -/* This function transforms the offsets into the symbol table into - pointers to syments. */ - -static void -coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent) - bfd *abfd; - combined_entry_type *table_base; - combined_entry_type *symbol; - unsigned int indaux; - combined_entry_type *auxent; -{ - int type = symbol->u.syment.n_type; - int class = symbol->u.syment.n_sclass; - - if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) - { - if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) - (abfd, table_base, symbol, indaux, auxent)) - return; - } - - /* Don't bother if this is a file or a section */ - if (class == C_STAT && type == T_NULL) - return; - if (class == C_FILE) - return; - - /* Otherwise patch up */ -#define N_TMASK coff_data (abfd)->local_n_tmask -#define N_BTSHFT coff_data (abfd)->local_n_btshft - if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK) - && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) - { - auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = - table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; - auxent->fix_end = 1; - } - /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can - generate one, so we must be careful to ignore it. */ - if (auxent->u.auxent.x_sym.x_tagndx.l > 0) - { - auxent->u.auxent.x_sym.x_tagndx.p = - table_base + auxent->u.auxent.x_sym.x_tagndx.l; - auxent->fix_tag = 1; - } -} - -/* Allocate space for the ".debug" section, and read it. - We did not read the debug section until now, because - we didn't want to go to the trouble until someone needed it. */ - -static char * -build_debug_section (abfd) - bfd *abfd; -{ - char *debug_section; - long position; - - asection *sect = bfd_get_section_by_name (abfd, ".debug"); - - if (!sect) - { - bfd_set_error (bfd_error_no_debug_section); - return NULL; - } - - debug_section = (PTR) bfd_alloc (abfd, - bfd_get_section_size_before_reloc (sect)); - if (debug_section == NULL) - return NULL; - - /* Seek to the beginning of the `.debug' section and read it. - Save the current position first; it is needed by our caller. - Then read debug section and reset the file pointer. */ - - position = bfd_tell (abfd); - if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0 - || (bfd_read (debug_section, - bfd_get_section_size_before_reloc (sect), 1, abfd) - != bfd_get_section_size_before_reloc (sect)) - || bfd_seek (abfd, position, SEEK_SET) != 0) - return NULL; - return debug_section; -} - - -/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be - \0-terminated, but will not exceed 'maxlen' characters. The copy *will* - be \0-terminated. */ -static char * -copy_name (abfd, name, maxlen) - bfd *abfd; - char *name; - int maxlen; -{ - int len; - char *newname; - - for (len = 0; len < maxlen; ++len) - { - if (name[len] == '\0') - { - break; - } - } - - if ((newname = (PTR) bfd_alloc (abfd, len + 1)) == NULL) - return (NULL); - strncpy (newname, name, len); - newname[len] = '\0'; - return newname; -} - -/* Read in the external symbols. */ - -boolean -_bfd_coff_get_external_symbols (abfd) - bfd *abfd; -{ - bfd_size_type symesz; - size_t size; - PTR syms; - - if (obj_coff_external_syms (abfd) != NULL) - return true; - - symesz = bfd_coff_symesz (abfd); - - size = obj_raw_syment_count (abfd) * symesz; - - syms = (PTR) bfd_malloc (size); - if (syms == NULL && size != 0) - return false; - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || bfd_read (syms, size, 1, abfd) != size) - { - if (syms != NULL) - free (syms); - return false; - } - - obj_coff_external_syms (abfd) = syms; - - return true; -} - -/* Read in the external strings. The strings are not loaded until - they are needed. This is because we have no simple way of - detecting a missing string table in an archive. */ - -const char * -_bfd_coff_read_string_table (abfd) - bfd *abfd; -{ - char extstrsize[STRING_SIZE_SIZE]; - size_t strsize; - char *strings; - - if (obj_coff_strings (abfd) != NULL) - return obj_coff_strings (abfd); - - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd)), - SEEK_SET) != 0) - return NULL; - - if (bfd_read (extstrsize, sizeof extstrsize, 1, abfd) != sizeof extstrsize) - { - if (bfd_get_error () != bfd_error_file_truncated) - return NULL; - - /* There is no string table. */ - strsize = STRING_SIZE_SIZE; - } - else - { -#if STRING_SIZE_SIZE == 4 - strsize = bfd_h_get_32 (abfd, (bfd_byte *) extstrsize); -#else - #error Change bfd_h_get_32 -#endif - } - - if (strsize < STRING_SIZE_SIZE) - { - (*_bfd_error_handler) - ("%s: bad string table size %lu", bfd_get_filename (abfd), - (unsigned long) strsize); - bfd_set_error (bfd_error_bad_value); - return NULL; - } - - strings = (char *) bfd_malloc (strsize); - if (strings == NULL) - return NULL; - - if (bfd_read (strings + STRING_SIZE_SIZE, - strsize - STRING_SIZE_SIZE, 1, abfd) - != strsize - STRING_SIZE_SIZE) - { - free (strings); - return NULL; - } - - obj_coff_strings (abfd) = strings; - - return strings; -} - -/* Free up the external symbols and strings read from a COFF file. */ - -boolean -_bfd_coff_free_symbols (abfd) - bfd *abfd; -{ - if (obj_coff_external_syms (abfd) != NULL - && ! obj_coff_keep_syms (abfd)) - { - free (obj_coff_external_syms (abfd)); - obj_coff_external_syms (abfd) = NULL; - } - if (obj_coff_strings (abfd) != NULL - && ! obj_coff_keep_strings (abfd)) - { - free (obj_coff_strings (abfd)); - obj_coff_strings (abfd) = NULL; - } - return true; -} - -/* Read a symbol table into freshly bfd_allocated memory, swap it, and - knit the symbol names into a normalized form. By normalized here I - mean that all symbols have an n_offset pointer that points to a null- - terminated string. */ - -combined_entry_type * -coff_get_normalized_symtab (abfd) - bfd *abfd; -{ - combined_entry_type *internal; - combined_entry_type *internal_ptr; - combined_entry_type *symbol_ptr; - combined_entry_type *internal_end; - bfd_size_type symesz; - char *raw_src; - char *raw_end; - const char *string_table = NULL; - char *debug_section = NULL; - unsigned long size; - - if (obj_raw_syments (abfd) != NULL) - return obj_raw_syments (abfd); - - size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type); - internal = (combined_entry_type *) bfd_zalloc (abfd, size); - if (internal == NULL && size != 0) - return NULL; - internal_end = internal + obj_raw_syment_count (abfd); - - if (! _bfd_coff_get_external_symbols (abfd)) - return NULL; - - raw_src = (char *) obj_coff_external_syms (abfd); - - /* mark the end of the symbols */ - symesz = bfd_coff_symesz (abfd); - raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz; - - /* FIXME SOMEDAY. A string table size of zero is very weird, but - probably possible. If one shows up, it will probably kill us. */ - - /* Swap all the raw entries */ - for (internal_ptr = internal; - raw_src < raw_end; - raw_src += symesz, internal_ptr++) - { - - unsigned int i; - bfd_coff_swap_sym_in (abfd, (PTR) raw_src, - (PTR) & internal_ptr->u.syment); - symbol_ptr = internal_ptr; - - for (i = 0; - i < symbol_ptr->u.syment.n_numaux; - i++) - { - internal_ptr++; - raw_src += symesz; - bfd_coff_swap_aux_in (abfd, (PTR) raw_src, - symbol_ptr->u.syment.n_type, - symbol_ptr->u.syment.n_sclass, - i, symbol_ptr->u.syment.n_numaux, - &(internal_ptr->u.auxent)); - coff_pointerize_aux (abfd, internal, symbol_ptr, i, - internal_ptr); - } - } - - /* Free the raw symbols, but not the strings (if we have them). */ - obj_coff_keep_strings (abfd) = true; - if (! _bfd_coff_free_symbols (abfd)) - return NULL; - - for (internal_ptr = internal; internal_ptr < internal_end; - internal_ptr++) - { - if (internal_ptr->u.syment.n_sclass == C_FILE - && internal_ptr->u.syment.n_numaux > 0) - { - /* make a file symbol point to the name in the auxent, since - the text ".file" is redundant */ - if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0) - { - /* the filename is a long one, point into the string table */ - if (string_table == NULL) - { - string_table = _bfd_coff_read_string_table (abfd); - if (string_table == NULL) - return NULL; - } - - internal_ptr->u.syment._n._n_n._n_offset = - ((long) - (string_table - + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset)); - } - else - { - /* ordinary short filename, put into memory anyway */ - internal_ptr->u.syment._n._n_n._n_offset = (long) - copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname, - FILNMLEN); - } - } - else - { - if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) - { - /* This is a "short" name. Make it long. */ - unsigned long i = 0; - char *newstring = NULL; - - /* find the length of this string without walking into memory - that isn't ours. */ - for (i = 0; i < 8; ++i) - { - if (internal_ptr->u.syment._n._n_name[i] == '\0') - { - break; - } /* if end of string */ - } /* possible lengths of this string. */ - - if ((newstring = (PTR) bfd_alloc (abfd, ++i)) == NULL) - return (NULL); - memset (newstring, 0, i); - strncpy (newstring, internal_ptr->u.syment._n._n_name, i - 1); - internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring; - internal_ptr->u.syment._n._n_n._n_zeroes = 0; - } - else if (internal_ptr->u.syment._n._n_n._n_offset == 0) - internal_ptr->u.syment._n._n_n._n_offset = (long int) ""; - else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment)) - { - /* Long name already. Point symbol at the string in the - table. */ - if (string_table == NULL) - { - string_table = _bfd_coff_read_string_table (abfd); - if (string_table == NULL) - return NULL; - } - internal_ptr->u.syment._n._n_n._n_offset = - ((long int) - (string_table - + internal_ptr->u.syment._n._n_n._n_offset)); - } - else - { - /* Long name in debug section. Very similar. */ - if (debug_section == NULL) - debug_section = build_debug_section (abfd); - internal_ptr->u.syment._n._n_n._n_offset = (long int) - (debug_section + internal_ptr->u.syment._n._n_n._n_offset); - } - } - internal_ptr += internal_ptr->u.syment.n_numaux; - } - - obj_raw_syments (abfd) = internal; - BFD_ASSERT (obj_raw_syment_count (abfd) - == (unsigned int) (internal_ptr - internal)); - - return (internal); -} /* coff_get_normalized_symtab() */ - -long -coff_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -asymbol * -coff_make_empty_symbol (abfd) - bfd *abfd; -{ - coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type)); - if (new == NULL) - return (NULL); - memset (new, 0, sizeof *new); - new->symbol.section = 0; - new->native = 0; - new->lineno = (alent *) NULL; - new->done_lineno = false; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/* Make a debugging symbol. */ - -asymbol * -coff_bfd_make_debug_symbol (abfd, ptr, sz) - bfd *abfd; - PTR ptr; - unsigned long sz; -{ - coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type)); - if (new == NULL) - return (NULL); - /* @@ This shouldn't be using a constant multiplier. */ - new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10); - if (!new->native) - return (NULL); - new->symbol.section = bfd_abs_section_ptr; - new->symbol.flags = BSF_DEBUGGING; - new->lineno = (alent *) NULL; - new->done_lineno = false; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/*ARGSUSED */ -void -coff_get_symbol_info (abfd, symbol, ret) - bfd *abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); - if (coffsymbol (symbol)->native != NULL - && coffsymbol (symbol)->native->fix_value) - { - combined_entry_type *psym; - - psym = ((combined_entry_type *) - coffsymbol (symbol)->native->u.syment.n_value); - ret->value = (bfd_vma) (psym - obj_raw_syments (abfd)); - } -} - -/* Print out information about COFF symbol. */ - -void -coff_print_symbol (abfd, filep, symbol, how) - bfd *abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) filep; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - - case bfd_print_symbol_more: - fprintf (file, "coff %s %s", - coffsymbol (symbol)->native ? "n" : "g", - coffsymbol (symbol)->lineno ? "l" : " "); - break; - - case bfd_print_symbol_all: - if (coffsymbol (symbol)->native) - { - unsigned long val; - unsigned int aux; - combined_entry_type *combined = coffsymbol (symbol)->native; - combined_entry_type *root = obj_raw_syments (abfd); - struct lineno_cache_entry *l = coffsymbol (symbol)->lineno; - - fprintf (file, "[%3ld]", (long) (combined - root)); - - if (! combined->fix_value) - val = (unsigned long) combined->u.syment.n_value; - else - val = ((unsigned long) - ((combined_entry_type *) combined->u.syment.n_value - - root)); - - fprintf (file, - "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x%08lx %s", - combined->u.syment.n_scnum, - combined->u.syment.n_flags, - combined->u.syment.n_type, - combined->u.syment.n_sclass, - combined->u.syment.n_numaux, - val, - symbol->name); - - for (aux = 0; aux < combined->u.syment.n_numaux; aux++) - { - combined_entry_type *auxp = combined + aux + 1; - long tagndx; - - if (auxp->fix_tag) - tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root; - else - tagndx = auxp->u.auxent.x_sym.x_tagndx.l; - - fprintf (file, "\n"); - - if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux)) - continue; - - switch (combined->u.syment.n_sclass) - { - case C_FILE: - fprintf (file, "File "); - break; - - case C_STAT: - if (combined->u.syment.n_type == T_NULL) - /* probably a section symbol? */ - { - fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d", - (long) auxp->u.auxent.x_scn.x_scnlen, - auxp->u.auxent.x_scn.x_nreloc, - auxp->u.auxent.x_scn.x_nlinno); - break; - } - /* else fall through */ - - default: - fprintf (file, "AUX lnno %d size 0x%x tagndx %ld", - auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno, - auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size, - tagndx); - if (auxp->fix_end) - fprintf (file, " endndx %ld", - ((long) - (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p - - root))); - break; - } - } - - if (l) - { - fprintf (file, "\n%s :", l->u.sym->name); - l++; - while (l->line_number) - { - fprintf (file, "\n%4d : 0x%lx", - l->line_number, - ((unsigned long) - (l->u.offset + symbol->section->vma))); - l++; - } - } - } - else - { - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s %s %s %s", - symbol->section->name, - coffsymbol (symbol)->native ? "n" : "g", - coffsymbol (symbol)->lineno ? "l" : " ", - symbol->name); - } - } -} - -/* Provided a BFD, a section and an offset into the section, calculate - and return the name of the source file and the line nearest to the - wanted location. */ - -/*ARGSUSED*/ -boolean -coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, - functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - boolean found; - unsigned int i; - unsigned int line_base; - coff_data_type *cof = coff_data (abfd); - /* Run through the raw syments if available */ - combined_entry_type *p; - combined_entry_type *pend; - alent *l; - struct coff_section_tdata *sec_data; - - /* Before looking through the symbol table, try to use a .stab - section to find the information. */ - if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, - &found, filename_ptr, - functionname_ptr, line_ptr, - &coff_data (abfd)->line_info)) - return false; - if (found) - return true; - - *filename_ptr = 0; - *functionname_ptr = 0; - *line_ptr = 0; - - /* Don't try and find line numbers in a non coff file */ - if (abfd->xvec->flavour != bfd_target_coff_flavour) - return false; - - if (cof == NULL) - return false; - - /* Find the first C_FILE symbol. */ - p = cof->raw_syments; - pend = p + cof->raw_syment_count; - while (p < pend) - { - if (p->u.syment.n_sclass == C_FILE) - break; - p += 1 + p->u.syment.n_numaux; - } - - if (p < pend) - { - bfd_vma maxdiff; - - /* Look through the C_FILE symbols to find the best one. */ - *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; - maxdiff = (bfd_vma) 0 - (bfd_vma) 1; - while (1) - { - combined_entry_type *p2; - - for (p2 = p + 1 + p->u.syment.n_numaux; - p2 < pend; - p2 += 1 + p2->u.syment.n_numaux) - { - if (p2->u.syment.n_scnum > 0 - && (section - == coff_section_from_bfd_index (abfd, - p2->u.syment.n_scnum))) - break; - if (p2->u.syment.n_sclass == C_FILE) - { - p2 = pend; - break; - } - } - - if (p2 < pend - && offset >= (bfd_vma) p2->u.syment.n_value - && offset - (bfd_vma) p2->u.syment.n_value < maxdiff) - { - *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; - maxdiff = offset - p2->u.syment.n_value; - } - - /* Avoid endless loops on erroneous files by ensuring that - we always move forward in the file. */ - if (p - cof->raw_syments >= p->u.syment.n_value) - break; - - p = cof->raw_syments + p->u.syment.n_value; - if (p > pend || p->u.syment.n_sclass != C_FILE) - break; - } - } - - /* Now wander though the raw linenumbers of the section */ - /* If we have been called on this section before, and the offset we - want is further down then we can prime the lookup loop. */ - sec_data = coff_section_data (abfd, section); - if (sec_data != NULL - && sec_data->i > 0 - && offset >= sec_data->offset) - { - i = sec_data->i; - *functionname_ptr = sec_data->function; - line_base = sec_data->line_base; - } - else - { - i = 0; - line_base = 0; - } - - if (section->lineno != NULL) - { - l = §ion->lineno[i]; - - for (; i < section->lineno_count; i++) - { - if (l->line_number == 0) - { - /* Get the symbol this line number points at */ - coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); - if (coff->symbol.value > offset) - break; - *functionname_ptr = coff->symbol.name; - if (coff->native) - { - combined_entry_type *s = coff->native; - s = s + 1 + s->u.syment.n_numaux; - - /* In XCOFF a debugging symbol can follow the - function symbol. */ - if (s->u.syment.n_scnum == N_DEBUG) - s = s + 1 + s->u.syment.n_numaux; - - /* S should now point to the .bf of the function. */ - if (s->u.syment.n_numaux) - { - /* The linenumber is stored in the auxent. */ - union internal_auxent *a = &((s + 1)->u.auxent); - line_base = a->x_sym.x_misc.x_lnsz.x_lnno; - *line_ptr = line_base; - } - } - } - else - { - if (l->u.offset + bfd_get_section_vma (abfd, section) > offset) - break; - *line_ptr = l->line_number + line_base - 1; - } - l++; - } - } - - /* Cache the results for the next call. */ - if (sec_data == NULL && section->owner == abfd) - { - section->used_by_bfd = - ((PTR) bfd_zalloc (abfd, - sizeof (struct coff_section_tdata))); - sec_data = (struct coff_section_tdata *) section->used_by_bfd; - } - if (sec_data != NULL) - { - sec_data->offset = offset; - sec_data->i = i; - sec_data->function = *functionname_ptr; - sec_data->line_base = line_base; - } - - return true; -} - -int -coff_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - size_t size; - - if (reloc == false) - { - size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); - } - else - { - size = bfd_coff_filhsz (abfd); - } - - size += abfd->section_count * bfd_coff_scnhsz (abfd); - return size; -} diff --git a/contrib/gdb/bfd/cofflink.c b/contrib/gdb/bfd/cofflink.c deleted file mode 100644 index c4a42a09147..00000000000 --- a/contrib/gdb/bfd/cofflink.c +++ /dev/null @@ -1,2327 +0,0 @@ -/* COFF specific linker code. - Copyright 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file contains the COFF backend linker code. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -static boolean coff_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean coff_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean coff_link_check_ar_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean coff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *)); - -/* Create an entry in a COFF linker hash table. */ - -struct bfd_hash_entry * -_bfd_coff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct coff_link_hash_entry *) NULL) - ret = ((struct coff_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct coff_link_hash_entry))); - if (ret == (struct coff_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct coff_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct coff_link_hash_entry *) NULL) - { - /* Set local fields. */ - ret->indx = -1; - ret->type = T_NULL; - ret->class = C_NULL; - ret->numaux = 0; - ret->auxbfd = NULL; - ret->aux = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a COFF linker hash table. */ - -boolean -_bfd_coff_link_hash_table_init (table, abfd, newfunc) - struct coff_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return _bfd_link_hash_table_init (&table->root, abfd, newfunc); -} - -/* Create a COFF linker hash table. */ - -struct bfd_link_hash_table * -_bfd_coff_link_hash_table_create (abfd) - bfd *abfd; -{ - struct coff_link_hash_table *ret; - - ret = ((struct coff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct coff_link_hash_table))); - if (ret == NULL) - return NULL; - if (! _bfd_coff_link_hash_table_init (ret, abfd, - _bfd_coff_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Create an entry in a COFF debug merge hash table. */ - -struct bfd_hash_entry * -_bfd_coff_debug_merge_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct coff_debug_merge_hash_entry *ret = - (struct coff_debug_merge_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct coff_debug_merge_hash_entry *) NULL) - ret = ((struct coff_debug_merge_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct coff_debug_merge_hash_entry))); - if (ret == (struct coff_debug_merge_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct coff_debug_merge_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret != (struct coff_debug_merge_hash_entry *) NULL) - { - /* Set local fields. */ - ret->types = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Given a COFF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -_bfd_coff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return coff_link_add_object_symbols (abfd, info); - case bfd_archive: - return (_bfd_generic_link_add_archive_symbols - (abfd, info, coff_link_check_archive_element)); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add symbols from a COFF object file. */ - -static boolean -coff_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - if (! coff_link_add_symbols (abfd, info)) - return false; - - if (! info->keep_memory) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - return true; -} - -/* Check a single archive element to see if we need to include it in - the link. *PNEEDED is set according to whether this element is - needed in the link or not. This is called via - _bfd_generic_link_add_archive_symbols. */ - -static boolean -coff_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - - if (! coff_link_check_ar_symbols (abfd, info, pneeded)) - return false; - - if (*pneeded) - { - if (! coff_link_add_symbols (abfd, info)) - return false; - } - - if (! info->keep_memory || ! *pneeded) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - - return true; -} - -/* Look through the symbols to see if this object file should be - included in the link. */ - -static boolean -coff_link_check_ar_symbols (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *)); - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - - *pneeded = false; - - sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global; - - symesz = bfd_coff_symesz (abfd); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + obj_raw_syment_count (abfd) * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - if ((sym.n_sclass == C_EXT - || (sym_is_global && (*sym_is_global) (abfd, &sym))) - && (sym.n_scnum != 0 || sym.n_value != 0)) - { - const char *name; - char buf[SYMNMLEN + 1]; - struct bfd_link_hash_entry *h; - - /* This symbol is externally visible, and is defined by this - object file. */ - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - return false; - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* We are only interested in symbols that are currently - undefined. If a symbol is currently known to be common, - COFF linkers do not bring in an object file which defines - it. */ - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_undefined) - { - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - } - - esym += (sym.n_numaux + 1) * symesz; - } - - /* We do not need this object file. */ - return true; -} - -/* Add all the symbols from an object file to the hash table. */ - -static boolean -coff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *)); - boolean default_copy; - bfd_size_type symcount; - struct coff_link_hash_entry **sym_hash; - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - - sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global; - - if (info->keep_memory) - default_copy = false; - else - default_copy = true; - - symcount = obj_raw_syment_count (abfd); - - /* We keep a list of the linker hash table entries that correspond - to particular symbols. */ - sym_hash = ((struct coff_link_hash_entry **) - bfd_alloc (abfd, - ((size_t) symcount - * sizeof (struct coff_link_hash_entry *)))); - if (sym_hash == NULL && symcount != 0) - return false; - obj_coff_sym_hashes (abfd) = sym_hash; - memset (sym_hash, 0, - (size_t) symcount * sizeof (struct coff_link_hash_entry *)); - - symesz = bfd_coff_symesz (abfd); - BFD_ASSERT (symesz == bfd_coff_auxesz (abfd)); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + symcount * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - boolean copy; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - if (sym.n_sclass == C_EXT - || (sym_is_global && (*sym_is_global) (abfd, &sym))) - { - const char *name; - char buf[SYMNMLEN + 1]; - flagword flags; - asection *section; - bfd_vma value; - - /* This symbol is externally visible. */ - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - return false; - - /* We must copy the name into memory if we got it from the - syment itself, rather than the string table. */ - copy = default_copy; - if (sym._n._n_n._n_zeroes != 0 - || sym._n._n_n._n_offset == 0) - copy = true; - - value = sym.n_value; - - if (sym.n_scnum == 0) - { - if (value == 0) - { - flags = 0; - section = bfd_und_section_ptr; - } - else - { - flags = BSF_GLOBAL; - section = bfd_com_section_ptr; - } - } - else - { - flags = BSF_EXPORT | BSF_GLOBAL; - section = coff_section_from_bfd_index (abfd, sym.n_scnum); - value -= section->vma; - } - - if (! (bfd_coff_link_add_one_symbol - (info, abfd, name, flags, section, value, - (const char *) NULL, copy, false, - (struct bfd_link_hash_entry **) sym_hash))) - return false; - - if (info->hash->creator->flavour == bfd_get_flavour (abfd)) - { - if (((*sym_hash)->class == C_NULL - && (*sym_hash)->type == T_NULL) - || sym.n_scnum != 0 - || (sym.n_value != 0 - && (*sym_hash)->root.type != bfd_link_hash_defined)) - { - (*sym_hash)->class = sym.n_sclass; - (*sym_hash)->type = sym.n_type; - (*sym_hash)->numaux = sym.n_numaux; - (*sym_hash)->auxbfd = abfd; - if (sym.n_numaux != 0) - { - union internal_auxent *alloc; - unsigned int i; - bfd_byte *eaux; - union internal_auxent *iaux; - - alloc = ((union internal_auxent *) - bfd_hash_allocate (&info->hash->table, - (sym.n_numaux - * sizeof (*alloc)))); - if (alloc == NULL) - return false; - for (i = 0, eaux = esym + symesz, iaux = alloc; - i < sym.n_numaux; - i++, eaux += symesz, iaux++) - bfd_coff_swap_aux_in (abfd, (PTR) eaux, sym.n_type, - sym.n_sclass, i, sym.n_numaux, - (PTR) iaux); - (*sym_hash)->aux = alloc; - } - } - } - } - - esym += (sym.n_numaux + 1) * symesz; - sym_hash += sym.n_numaux + 1; - } - - return true; -} - -/* Do the final link step. */ - -boolean -_bfd_coff_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz; - struct coff_final_link_info finfo; - boolean debug_merge_allocated; - asection *o; - struct bfd_link_order *p; - size_t max_sym_count; - size_t max_lineno_count; - size_t max_reloc_count; - size_t max_output_reloc_count; - size_t max_contents_size; - file_ptr rel_filepos; - unsigned int relsz; - file_ptr line_filepos; - unsigned int linesz; - bfd *sub; - bfd_byte *external_relocs = NULL; - char strbuf[STRING_SIZE_SIZE]; - - symesz = bfd_coff_symesz (abfd); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.strtab = NULL; - finfo.section_info = NULL; - finfo.last_file_index = -1; - finfo.internal_syms = NULL; - finfo.sec_ptrs = NULL; - finfo.sym_indices = NULL; - finfo.outsyms = NULL; - finfo.linenos = NULL; - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - debug_merge_allocated = false; - - coff_data (abfd)->link_info = info; - - finfo.strtab = _bfd_stringtab_init (); - if (finfo.strtab == NULL) - goto error_return; - - if (! coff_debug_merge_hash_table_init (&finfo.debug_merge)) - goto error_return; - debug_merge_allocated = true; - - /* Compute the file positions for all the sections. */ - if (! abfd->output_has_begun) - bfd_coff_compute_section_file_positions (abfd); - - /* Count the line numbers and relocation entries required for the - output file. Set the file positions for the relocs. */ - rel_filepos = obj_relocbase (abfd); - relsz = bfd_coff_relsz (abfd); - max_contents_size = 0; - max_lineno_count = 0; - max_reloc_count = 0; - - for (o = abfd->sections; o != NULL; o = o->next) - { - o->reloc_count = 0; - o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) - { - - if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->strip == strip_none - || info->strip == strip_some) - o->lineno_count += sec->lineno_count; - - if (info->relocateable) - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->lineno_count > max_lineno_count) - max_lineno_count = sec->lineno_count; - if (sec->reloc_count > max_reloc_count) - max_reloc_count = sec->reloc_count; - } - else if (info->relocateable - && (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order)) - ++o->reloc_count; - } - if (o->reloc_count == 0) - o->rel_filepos = 0; - else - { - o->flags |= SEC_RELOC; - o->rel_filepos = rel_filepos; - rel_filepos += o->reloc_count * relsz; - } - } - - /* If doing a relocateable link, allocate space for the pointers we - need to keep. */ - if (info->relocateable) - { - unsigned int i; - - /* We use section_count + 1, rather than section_count, because - the target_index fields are 1 based. */ - finfo.section_info = - ((struct coff_link_section_info *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct coff_link_section_info))); - if (finfo.section_info == NULL) - goto error_return; - for (i = 0; i <= abfd->section_count; i++) - { - finfo.section_info[i].relocs = NULL; - finfo.section_info[i].rel_hashes = NULL; - } - } - - /* We now know the size of the relocs, so we can determine the file - positions of the line numbers. */ - line_filepos = rel_filepos; - linesz = bfd_coff_linesz (abfd); - max_output_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->lineno_count == 0) - o->line_filepos = 0; - else - { - o->line_filepos = line_filepos; - line_filepos += o->lineno_count * linesz; - } - - if (o->reloc_count != 0) - { - /* We don't know the indices of global symbols until we have - written out all the local symbols. For each section in - the output file, we keep an array of pointers to hash - table entries. Each entry in the array corresponds to a - reloc. When we find a reloc against a global symbol, we - set the corresponding entry in this array so that we can - fix up the symbol index after we have written out all the - local symbols. - - Because of this problem, we also keep the relocs in - memory until the end of the link. This wastes memory, - but only when doing a relocateable link, which is not the - common case. */ - BFD_ASSERT (info->relocateable); - finfo.section_info[o->target_index].relocs = - ((struct internal_reloc *) - bfd_malloc (o->reloc_count * sizeof (struct internal_reloc))); - finfo.section_info[o->target_index].rel_hashes = - ((struct coff_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct coff_link_hash_entry *))); - if (finfo.section_info[o->target_index].relocs == NULL - || finfo.section_info[o->target_index].rel_hashes == NULL) - goto error_return; - - if (o->reloc_count > max_output_reloc_count) - max_output_reloc_count = o->reloc_count; - } - - /* Reset the reloc and lineno counts, so that we can use them to - count the number of entries we have output so far. */ - o->reloc_count = 0; - o->lineno_count = 0; - } - - obj_sym_filepos (abfd) = line_filepos; - - /* Figure out the largest number of symbols in an input BFD. Take - the opportunity to clear the output_has_begun fields of all the - input BFD's. */ - max_sym_count = 0; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - size_t sz; - - sub->output_has_begun = false; - sz = obj_raw_syment_count (sub); - if (sz > max_sym_count) - max_sym_count = sz; - } - - /* Allocate some buffers used while linking. */ - finfo.internal_syms = ((struct internal_syment *) - bfd_malloc (max_sym_count - * sizeof (struct internal_syment))); - finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count - * sizeof (asection *)); - finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.outsyms = ((bfd_byte *) - bfd_malloc ((size_t) ((max_sym_count + 1) * symesz))); - finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count - * bfd_coff_linesz (abfd)); - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz); - if (! info->relocateable) - finfo.internal_relocs = ((struct internal_reloc *) - bfd_malloc (max_reloc_count - * sizeof (struct internal_reloc))); - if ((finfo.internal_syms == NULL && max_sym_count > 0) - || (finfo.sec_ptrs == NULL && max_sym_count > 0) - || (finfo.sym_indices == NULL && max_sym_count > 0) - || finfo.outsyms == NULL - || (finfo.linenos == NULL && max_lineno_count > 0) - || (finfo.contents == NULL && max_contents_size > 0) - || (finfo.external_relocs == NULL && max_reloc_count > 0) - || (! info->relocateable - && finfo.internal_relocs == NULL - && max_reloc_count > 0)) - goto error_return; - - /* We now know the position of everything in the file, except that - we don't know the size of the symbol table and therefore we don't - know where the string table starts. We just build the string - table in memory as we go along. We process all the relocations - for a single input file at once. */ - obj_raw_syment_count (abfd) = 0; - - if (coff_backend_info (abfd)->_bfd_coff_start_final_link) - { - if (! bfd_coff_start_final_link (abfd, info)) - goto error_return; - } - - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_coff_flavour)) - { - sub = p->u.indirect.section->owner; - if (! sub->output_has_begun) - { - if (! _bfd_coff_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* Free up the buffers used by _bfd_coff_link_input_bfd. */ - - coff_debug_merge_hash_table_free (&finfo.debug_merge); - debug_merge_allocated = false; - - if (finfo.internal_syms != NULL) - { - free (finfo.internal_syms); - finfo.internal_syms = NULL; - } - if (finfo.sec_ptrs != NULL) - { - free (finfo.sec_ptrs); - finfo.sec_ptrs = NULL; - } - if (finfo.sym_indices != NULL) - { - free (finfo.sym_indices); - finfo.sym_indices = NULL; - } - if (finfo.linenos != NULL) - { - free (finfo.linenos); - finfo.linenos = NULL; - } - if (finfo.contents != NULL) - { - free (finfo.contents); - finfo.contents = NULL; - } - if (finfo.external_relocs != NULL) - { - free (finfo.external_relocs); - finfo.external_relocs = NULL; - } - if (finfo.internal_relocs != NULL) - { - free (finfo.internal_relocs); - finfo.internal_relocs = NULL; - } - - /* The value of the last C_FILE symbol is supposed to be the symbol - index of the first external symbol. Write it out again if - necessary. */ - if (finfo.last_file_index != -1 - && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd)) - { - finfo.last_file.n_value = obj_raw_syment_count (abfd); - bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, - (PTR) finfo.outsyms); - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + finfo.last_file_index * symesz), - SEEK_SET) != 0 - || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz) - return false; - } - - /* Write out the global symbols. */ - finfo.failed = false; - coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym, - (PTR) &finfo); - if (finfo.failed) - goto error_return; - - /* The outsyms buffer is used by _bfd_coff_write_global_sym. */ - if (finfo.outsyms != NULL) - { - free (finfo.outsyms); - finfo.outsyms = NULL; - } - - if (info->relocateable) - { - /* Now that we have written out all the global symbols, we know - the symbol indices to use for relocs against them, and we can - finally write out the relocs. */ - external_relocs = ((bfd_byte *) - bfd_malloc (max_output_reloc_count * relsz)); - if (external_relocs == NULL) - goto error_return; - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *irel; - struct internal_reloc *irelend; - struct coff_link_hash_entry **rel_hash; - bfd_byte *erel; - - if (o->reloc_count == 0) - continue; - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - rel_hash = finfo.section_info[o->target_index].rel_hashes; - erel = external_relocs; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - { - if (*rel_hash != NULL) - { - BFD_ASSERT ((*rel_hash)->indx >= 0); - irel->r_symndx = (*rel_hash)->indx; - } - bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); - } - - if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || bfd_write ((PTR) external_relocs, relsz, o->reloc_count, - abfd) != relsz * o->reloc_count) - goto error_return; - } - - free (external_relocs); - external_relocs = NULL; - } - - /* Free up the section information. */ - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - finfo.section_info = NULL; - } - - /* Write out the string table. */ - if (obj_raw_syment_count (abfd) != 0) - { - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * symesz), - SEEK_SET) != 0) - return false; - -#if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, - _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, - (bfd_byte *) strbuf); -#else - #error Change bfd_h_put_32 -#endif - - if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) - return false; - - if (! _bfd_stringtab_emit (abfd, finfo.strtab)) - return false; - } - - _bfd_stringtab_free (finfo.strtab); - - /* Setting bfd_get_symcount to 0 will cause write_object_contents to - not try to write out the symbols. */ - bfd_get_symcount (abfd) = 0; - - return true; - - error_return: - if (debug_merge_allocated) - coff_debug_merge_hash_table_free (&finfo.debug_merge); - if (finfo.strtab != NULL) - _bfd_stringtab_free (finfo.strtab); - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - } - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.sec_ptrs != NULL) - free (finfo.sec_ptrs); - if (finfo.sym_indices != NULL) - free (finfo.sym_indices); - if (finfo.outsyms != NULL) - free (finfo.outsyms); - if (finfo.linenos != NULL) - free (finfo.linenos); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (external_relocs != NULL) - free (external_relocs); - return false; -} - -/* parse out a -heap , line */ - -static char * -dores_com (ptr, output_bfd, heap) - char *ptr; - bfd *output_bfd; - int heap; -{ - if (coff_data(output_bfd)->pe) - { - int val = strtoul (ptr, &ptr, 0); - if (heap) - pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve =val; - else - pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve =val; - - if (ptr[0] == ',') - { - int val = strtoul (ptr+1, &ptr, 0); - if (heap) - pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit =val; - else - pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit =val; - } - } - return ptr; -} - -static char *get_name(ptr, dst) -char *ptr; -char **dst; -{ - while (*ptr == ' ') - ptr++; - *dst = ptr; - while (*ptr && *ptr != ' ') - ptr++; - *ptr = 0; - return ptr+1; -} - -/* Process any magic embedded commands in a section called .drectve */ - -static int -process_embedded_commands (output_bfd, info, abfd) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *abfd; -{ - asection *sec = bfd_get_section_by_name (abfd, ".drectve"); - char *s; - char *e; - char *copy; - if (!sec) - return 1; - - copy = bfd_malloc ((size_t) sec->_raw_size); - if (!copy) - return 0; - if (! bfd_get_section_contents(abfd, sec, copy, 0, sec->_raw_size)) - { - free (copy); - return 0; - } - e = copy + sec->_raw_size; - for (s = copy; s < e ; ) - { - if (s[0]!= '-') { - s++; - continue; - } - if (strncmp (s,"-attr", 5) == 0) - { - char *name; - char *attribs; - asection *asec; - - int loop = 1; - int had_write = 0; - int had_read = 0; - int had_exec= 0; - int had_shared= 0; - s += 5; - s = get_name(s, &name); - s = get_name(s, &attribs); - while (loop) { - switch (*attribs++) - { - case 'W': - had_write = 1; - break; - case 'R': - had_read = 1; - break; - case 'S': - had_shared = 1; - break; - case 'X': - had_exec = 1; - break; - default: - loop = 0; - } - } - asec = bfd_get_section_by_name (abfd, name); - if (asec) { - if (had_exec) - asec->flags |= SEC_CODE; - if (!had_write) - asec->flags |= SEC_READONLY; - } - } - else if (strncmp (s,"-heap", 5) == 0) - { - s = dores_com (s+5, output_bfd, 1); - } - else if (strncmp (s,"-stack", 6) == 0) - { - s = dores_com (s+6, output_bfd, 0); - } - else - s++; - } - free (copy); - return 1; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. */ - -boolean -_bfd_coff_link_input_bfd (finfo, input_bfd) - struct coff_final_link_info *finfo; - bfd *input_bfd; -{ - boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *)); - boolean (*adjust_symndx) PARAMS ((bfd *, struct bfd_link_info *, bfd *, - asection *, struct internal_reloc *, - boolean *)); - bfd *output_bfd; - const char *strings; - bfd_size_type syment_base; - unsigned int n_tmask; - unsigned int n_btshft; - boolean copy, hash; - bfd_size_type isymesz; - bfd_size_type osymesz; - bfd_size_type linesz; - bfd_byte *esym; - bfd_byte *esym_end; - struct internal_syment *isymp; - asection **secpp; - long *indexp; - unsigned long output_index; - bfd_byte *outsym; - struct coff_link_hash_entry **sym_hash; - asection *o; - - /* Move all the symbols to the output file. */ - - output_bfd = finfo->output_bfd; - sym_is_global = coff_backend_info (input_bfd)->_bfd_coff_sym_is_global; - strings = NULL; - syment_base = obj_raw_syment_count (output_bfd); - isymesz = bfd_coff_symesz (input_bfd); - osymesz = bfd_coff_symesz (output_bfd); - linesz = bfd_coff_linesz (input_bfd); - BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd)); - - n_tmask = coff_data (input_bfd)->local_n_tmask; - n_btshft = coff_data (input_bfd)->local_n_btshft; - - /* Define macros so that ISFCN, et. al., macros work correctly. */ -#define N_TMASK n_tmask -#define N_BTSHFT n_btshft - - copy = false; - if (! finfo->info->keep_memory) - copy = true; - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - - if (! _bfd_coff_get_external_symbols (input_bfd)) - return false; - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - isymp = finfo->internal_syms; - secpp = finfo->sec_ptrs; - indexp = finfo->sym_indices; - output_index = syment_base; - outsym = finfo->outsyms; - - if (coff_data(output_bfd)->pe) - { - if (!process_embedded_commands (output_bfd, finfo->info, input_bfd)) - return false; - } - - while (esym < esym_end) - { - struct internal_syment isym; - boolean skip; - boolean global; - int add; - - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); - - /* Make a copy of *isymp so that the relocate_section function - always sees the original values. This is more reliable than - always recomputing the symbol value even if we are stripping - the symbol. */ - isym = *isymp; - - if (isym.n_scnum != 0) - *secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum); - else - { - if (isym.n_value == 0) - *secpp = bfd_und_section_ptr; - else - *secpp = bfd_com_section_ptr; - } - - *indexp = -1; - - skip = false; - global = false; - add = 1 + isym.n_numaux; - - /* If we are stripping all symbols, we want to skip this one. */ - if (finfo->info->strip == strip_all) - skip = true; - - if (! skip) - { - if (isym.n_sclass == C_EXT - || (sym_is_global && (*sym_is_global) (input_bfd, &isym))) - { - /* This is a global symbol. Global symbols come at the - end of the symbol table, so skip them for now. - Function symbols, however, are an exception, and are - not moved to the end. */ - global = true; - if (! ISFCN (isym.n_type)) - skip = true; - } - else - { - /* This is a local symbol. Skip it if we are discarding - local symbols. */ - if (finfo->info->discard == discard_all) - skip = true; - } - } - - /* If we stripping debugging symbols, and this is a debugging - symbol, then skip it. */ - if (! skip - && finfo->info->strip == strip_debugger - && isym.n_scnum == N_DEBUG) - skip = true; - - /* If some symbols are stripped based on the name, work out the - name and decide whether to skip this symbol. */ - if (! skip - && (finfo->info->strip == strip_some - || finfo->info->discard == discard_l)) - { - const char *name; - char buf[SYMNMLEN + 1]; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); - if (name == NULL) - return false; - - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, false, - false) == NULL)) - || (! global - && finfo->info->discard == discard_l - && strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - skip = true; - } - - /* If this is an enum, struct, or union tag, see if we have - already output an identical type. */ - if (! skip - && (finfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0 - && (isym.n_sclass == C_ENTAG - || isym.n_sclass == C_STRTAG - || isym.n_sclass == C_UNTAG) - && isym.n_numaux == 1) - { - const char *name; - char buf[SYMNMLEN + 1]; - struct coff_debug_merge_hash_entry *mh; - struct coff_debug_merge_type *mt; - union internal_auxent aux; - struct coff_debug_merge_element **epp; - bfd_byte *esl, *eslend; - struct internal_syment *islp; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); - if (name == NULL) - return false; - - /* Ignore fake names invented by compiler; treat them all as - the same name. */ - if (*name == '~' || *name == '.' || *name == '$' - || (*name == bfd_get_symbol_leading_char (input_bfd) - && (name[1] == '~' || name[1] == '.' || name[1] == '$'))) - name = ""; - - mh = coff_debug_merge_hash_lookup (&finfo->debug_merge, name, - true, true); - if (mh == NULL) - return false; - - /* Allocate memory to hold type information. If this turns - out to be a duplicate, we pass this address to - bfd_release. */ - mt = ((struct coff_debug_merge_type *) - bfd_alloc (input_bfd, - sizeof (struct coff_debug_merge_type))); - if (mt == NULL) - return false; - mt->class = isym.n_sclass; - - /* Pick up the aux entry, which points to the end of the tag - entries. */ - bfd_coff_swap_aux_in (input_bfd, (PTR) (esym + isymesz), - isym.n_type, isym.n_sclass, 0, isym.n_numaux, - (PTR) &aux); - - /* Gather the elements. */ - epp = &mt->elements; - mt->elements = NULL; - islp = isymp + 2; - esl = esym + 2 * isymesz; - eslend = ((bfd_byte *) obj_coff_external_syms (input_bfd) - + aux.x_sym.x_fcnary.x_fcn.x_endndx.l * isymesz); - while (esl < eslend) - { - const char *elename; - char elebuf[SYMNMLEN + 1]; - char *copy; - - bfd_coff_swap_sym_in (input_bfd, (PTR) esl, (PTR) islp); - - *epp = ((struct coff_debug_merge_element *) - bfd_alloc (input_bfd, - sizeof (struct coff_debug_merge_element))); - if (*epp == NULL) - return false; - - elename = _bfd_coff_internal_syment_name (input_bfd, islp, - elebuf); - if (elename == NULL) - return false; - - copy = (char *) bfd_alloc (input_bfd, strlen (elename) + 1); - if (copy == NULL) - return false; - strcpy (copy, elename); - - (*epp)->name = copy; - (*epp)->type = islp->n_type; - (*epp)->tagndx = 0; - if (islp->n_numaux >= 1 - && islp->n_type != T_NULL - && islp->n_sclass != C_EOS) - { - union internal_auxent eleaux; - long indx; - - bfd_coff_swap_aux_in (input_bfd, (PTR) (esl + isymesz), - islp->n_type, islp->n_sclass, 0, - islp->n_numaux, (PTR) &eleaux); - indx = eleaux.x_sym.x_tagndx.l; - - /* FIXME: If this tagndx entry refers to a symbol - defined later in this file, we just ignore it. - Handling this correctly would be tedious, and may - not be required. */ - - if (indx > 0 - && (indx - < ((esym - - (bfd_byte *) obj_coff_external_syms (input_bfd)) - / (long) isymesz))) - { - (*epp)->tagndx = finfo->sym_indices[indx]; - if ((*epp)->tagndx < 0) - (*epp)->tagndx = 0; - } - } - epp = &(*epp)->next; - *epp = NULL; - - esl += (islp->n_numaux + 1) * isymesz; - islp += islp->n_numaux + 1; - } - - /* See if we already have a definition which matches this - type. We always output the type if it has no elements, - for simplicity. */ - if (mt->elements == NULL) - bfd_release (input_bfd, (PTR) mt); - else - { - struct coff_debug_merge_type *mtl; - - for (mtl = mh->types; mtl != NULL; mtl = mtl->next) - { - struct coff_debug_merge_element *me, *mel; - - if (mtl->class != mt->class) - continue; - - for (me = mt->elements, mel = mtl->elements; - me != NULL && mel != NULL; - me = me->next, mel = mel->next) - { - if (strcmp (me->name, mel->name) != 0 - || me->type != mel->type - || me->tagndx != mel->tagndx) - break; - } - - if (me == NULL && mel == NULL) - break; - } - - if (mtl == NULL || (bfd_size_type) mtl->indx >= syment_base) - { - /* This is the first definition of this type. */ - mt->indx = output_index; - mt->next = mh->types; - mh->types = mt; - } - else - { - /* This is a redefinition which can be merged. */ - bfd_release (input_bfd, (PTR) mt); - *indexp = mtl->indx; - add = (eslend - esym) / isymesz; - skip = true; - } - } - } - - /* We now know whether we are to skip this symbol or not. */ - if (! skip) - { - /* Adjust the symbol in order to output it. */ - - if (isym._n._n_n._n_zeroes == 0 - && isym._n._n_n._n_offset != 0) - { - const char *name; - bfd_size_type indx; - - /* This symbol has a long name. Enter it in the string - table we are building. Note that we do not check - bfd_coff_symname_in_debug. That is only true for - XCOFF, and XCOFF requires different linking code - anyhow. */ - name = _bfd_coff_internal_syment_name (input_bfd, &isym, - (char *) NULL); - if (name == NULL) - return false; - indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy); - if (indx == (bfd_size_type) -1) - return false; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - - if (isym.n_scnum > 0) - { - isym.n_scnum = (*secpp)->output_section->target_index; - isym.n_value += ((*secpp)->output_section->vma - + (*secpp)->output_offset - - (*secpp)->vma); - } - - /* The value of a C_FILE symbol is the symbol index of the - next C_FILE symbol. The value of the last C_FILE symbol - is the symbol index to the first external symbol - (actually, coff_renumber_symbols does not get this - right--it just sets the value of the last C_FILE symbol - to zero--and nobody has ever complained about it). We - try to get this right, below, just before we write the - symbols out, but in the general case we may have to write - the symbol out twice. */ - if (isym.n_sclass == C_FILE) - { - if (finfo->last_file_index != -1 - && finfo->last_file.n_value != (long) output_index) - { - /* We must correct the value of the last C_FILE entry. */ - finfo->last_file.n_value = output_index; - if ((bfd_size_type) finfo->last_file_index >= syment_base) - { - /* The last C_FILE symbol is in this input file. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - - syment_base) - * osymesz))); - } - else - { - /* We have already written out the last C_FILE - symbol. We need to write it out again. We - borrow *outsym temporarily. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) outsym); - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + finfo->last_file_index * osymesz), - SEEK_SET) != 0 - || (bfd_write (outsym, osymesz, 1, output_bfd) - != osymesz)) - return false; - } - } - - finfo->last_file_index = output_index; - finfo->last_file = isym; - } - - /* Output the symbol. */ - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - - *indexp = output_index; - - if (global) - { - long indx; - struct coff_link_hash_entry *h; - - indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd)) - / isymesz); - h = obj_coff_sym_hashes (input_bfd)[indx]; - BFD_ASSERT (h != NULL); - h->indx = output_index; - } - - output_index += add; - outsym += add * osymesz; - } - - esym += add * isymesz; - isymp += add; - ++secpp; - ++indexp; - for (--add; add > 0; --add) - { - *secpp++ = NULL; - *indexp++ = -1; - } - } - - /* Fix up the aux entries. This must be done in a separate pass, - because we don't know the correct symbol indices until we have - already decided which symbols we are going to keep. */ - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - isymp = finfo->internal_syms; - indexp = finfo->sym_indices; - sym_hash = obj_coff_sym_hashes (input_bfd); - outsym = finfo->outsyms; - while (esym < esym_end) - { - int add; - - add = 1 + isymp->n_numaux; - - if ((*indexp < 0 - || (bfd_size_type) *indexp < syment_base) - && (*sym_hash == NULL - || (*sym_hash)->auxbfd != input_bfd)) - esym += add * isymesz; - else - { - struct coff_link_hash_entry *h; - int i; - - h = NULL; - if (*indexp < 0) - { - h = *sym_hash; - BFD_ASSERT (h->numaux == isymp->n_numaux); - } - - esym += isymesz; - - if (h == NULL) - outsym += osymesz; - - /* Handle the aux entries. This handling is based on - coff_pointerize_aux. I don't know if it always correct. */ - for (i = 0; i < isymp->n_numaux && esym < esym_end; i++) - { - union internal_auxent aux; - union internal_auxent *auxp; - - if (h != NULL) - auxp = h->aux + i; - else - { - bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) &aux); - auxp = &aux; - } - - if (isymp->n_sclass == C_FILE) - { - /* If this is a long filename, we must put it in the - string table. */ - if (auxp->x_file.x_n.x_zeroes == 0 - && auxp->x_file.x_n.x_offset != 0) - { - const char *filename; - bfd_size_type indx; - - BFD_ASSERT (auxp->x_file.x_n.x_offset - >= STRING_SIZE_SIZE); - if (strings == NULL) - { - strings = _bfd_coff_read_string_table (input_bfd); - if (strings == NULL) - return false; - } - filename = strings + auxp->x_file.x_n.x_offset; - indx = _bfd_stringtab_add (finfo->strtab, filename, - hash, copy); - if (indx == (bfd_size_type) -1) - return false; - auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; - } - } - else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) - { - unsigned long indx; - - if (ISFCN (isymp->n_type) - || ISTAG (isymp->n_sclass) - || isymp->n_sclass == C_BLOCK) - { - indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l; - if (indx > 0 - && indx < obj_raw_syment_count (input_bfd)) - { - /* We look forward through the symbol for - the index of the next symbol we are going - to include. I don't know if this is - entirely right. */ - while ((finfo->sym_indices[indx] < 0 - || ((bfd_size_type) finfo->sym_indices[indx] - < syment_base)) - && indx < obj_raw_syment_count (input_bfd)) - ++indx; - if (indx >= obj_raw_syment_count (input_bfd)) - indx = output_index; - else - indx = finfo->sym_indices[indx]; - auxp->x_sym.x_fcnary.x_fcn.x_endndx.l = indx; - } - } - - indx = auxp->x_sym.x_tagndx.l; - if (indx > 0 && indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - auxp->x_sym.x_tagndx.l = 0; - else - auxp->x_sym.x_tagndx.l = symindx; - } - } - - if (h == NULL) - { - bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) outsym); - outsym += osymesz; - } - - esym += isymesz; - } - } - - indexp += add; - isymp += add; - sym_hash += add; - } - - /* Relocate the line numbers, unless we are stripping them. */ - if (finfo->info->strip == strip_none - || finfo->info->strip == strip_some) - { - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_vma offset; - bfd_byte *eline; - bfd_byte *elineend; - - /* FIXME: If SEC_HAS_CONTENTS is not for the section, then - build_link_order in ldwrite.c will not have created a - link order, which means that we will not have seen this - input section in _bfd_coff_final_link, which means that - we will not have allocated space for the line numbers of - this section. I don't think line numbers can be - meaningful for a section which does not have - SEC_HAS_CONTENTS set, but, if they do, this must be - changed. */ - if (o->lineno_count == 0 - || (o->output_section->flags & SEC_HAS_CONTENTS) == 0) - continue; - - if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0 - || bfd_read (finfo->linenos, linesz, o->lineno_count, - input_bfd) != linesz * o->lineno_count) - return false; - - offset = o->output_section->vma + o->output_offset - o->vma; - eline = finfo->linenos; - elineend = eline + linesz * o->lineno_count; - for (; eline < elineend; eline += linesz) - { - struct internal_lineno iline; - - bfd_coff_swap_lineno_in (input_bfd, (PTR) eline, (PTR) &iline); - - if (iline.l_lnno != 0) - iline.l_addr.l_paddr += offset; - else if (iline.l_addr.l_symndx >= 0 - && ((unsigned long) iline.l_addr.l_symndx - < obj_raw_syment_count (input_bfd))) - { - long indx; - - indx = finfo->sym_indices[iline.l_addr.l_symndx]; - - if (indx < 0) - { - /* These line numbers are attached to a symbol - which we are stripping. We should really - just discard the line numbers, but that would - be a pain because we have already counted - them. */ - indx = 0; - } - else - { - struct internal_syment is; - union internal_auxent ia; - - /* Fix up the lnnoptr field in the aux entry of - the symbol. It turns out that we can't do - this when we modify the symbol aux entries, - because gas sometimes screws up the lnnoptr - field and makes it an offset from the start - of the line numbers rather than an absolute - file index. */ - bfd_coff_swap_sym_in (output_bfd, - (PTR) (finfo->outsyms - + ((indx - syment_base) - * osymesz)), - (PTR) &is); - if ((ISFCN (is.n_type) - || is.n_sclass == C_BLOCK) - && is.n_numaux >= 1) - { - PTR auxptr; - - auxptr = (PTR) (finfo->outsyms - + ((indx - syment_base + 1) - * osymesz)); - bfd_coff_swap_aux_in (output_bfd, auxptr, - is.n_type, is.n_sclass, - 0, is.n_numaux, (PTR) &ia); - ia.x_sym.x_fcnary.x_fcn.x_lnnoptr = - (o->output_section->line_filepos - + o->output_section->lineno_count * linesz - + eline - finfo->linenos); - bfd_coff_swap_aux_out (output_bfd, (PTR) &ia, - is.n_type, is.n_sclass, 0, - is.n_numaux, auxptr); - } - } - - iline.l_addr.l_symndx = indx; - } - - bfd_coff_swap_lineno_out (output_bfd, (PTR) &iline, (PTR) eline); - } - - if (bfd_seek (output_bfd, - (o->output_section->line_filepos - + o->output_section->lineno_count * linesz), - SEEK_SET) != 0 - || bfd_write (finfo->linenos, linesz, o->lineno_count, - output_bfd) != linesz * o->lineno_count) - return false; - - o->output_section->lineno_count += o->lineno_count; - } - } - - /* If we swapped out a C_FILE symbol, guess that the next C_FILE - symbol will be the first symbol in the next input file. In the - normal case, this will save us from writing out the C_FILE symbol - again. */ - if (finfo->last_file_index != -1 - && (bfd_size_type) finfo->last_file_index >= syment_base) - { - finfo->last_file.n_value = output_index; - bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - syment_base) - * osymesz))); - } - - /* Write the modified symbols to the output file. */ - if (outsym > finfo->outsyms) - { - if (bfd_seek (output_bfd, - obj_sym_filepos (output_bfd) + syment_base * osymesz, - SEEK_SET) != 0 - || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, - output_bfd) - != (bfd_size_type) (outsym - finfo->outsyms))) - return false; - - BFD_ASSERT ((obj_raw_syment_count (output_bfd) - + (outsym - finfo->outsyms) / osymesz) - == output_index); - - obj_raw_syment_count (output_bfd) = output_index; - } - - /* Relocate the contents of each section. */ - adjust_symndx = coff_backend_info (input_bfd)->_bfd_coff_adjust_symndx; - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_byte *contents; - - if ((o->flags & SEC_HAS_CONTENTS) == 0) - { - if ((o->flags & SEC_RELOC) != 0 - && o->reloc_count != 0) - { - ((*_bfd_error_handler) - ("%s: relocs in section `%s', but it has no contents", - bfd_get_filename (input_bfd), - bfd_get_section_name (input_bfd, o))); - bfd_set_error (bfd_error_no_contents); - return false; - } - - continue; - } - - if (coff_section_data (input_bfd, o) != NULL - && coff_section_data (input_bfd, o)->contents != NULL) - contents = coff_section_data (input_bfd, o)->contents; - else - { - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; - contents = finfo->contents; - } - - if ((o->flags & SEC_RELOC) != 0) - { - int target_index; - struct internal_reloc *internal_relocs; - struct internal_reloc *irel; - - /* Read in the relocs. */ - target_index = o->output_section->target_index; - internal_relocs = (_bfd_coff_read_internal_relocs - (input_bfd, o, false, finfo->external_relocs, - finfo->info->relocateable, - (finfo->info->relocateable - ? (finfo->section_info[target_index].relocs - + o->output_section->reloc_count) - : finfo->internal_relocs))); - if (internal_relocs == NULL) - return false; - - /* Call processor specific code to relocate the section - contents. */ - if (! bfd_coff_relocate_section (output_bfd, finfo->info, - input_bfd, o, - contents, - internal_relocs, - finfo->internal_syms, - finfo->sec_ptrs)) - return false; - - if (finfo->info->relocateable) - { - bfd_vma offset; - struct internal_reloc *irelend; - struct coff_link_hash_entry **rel_hash; - - offset = o->output_section->vma + o->output_offset - o->vma; - irel = internal_relocs; - irelend = irel + o->reloc_count; - rel_hash = (finfo->section_info[target_index].rel_hashes - + o->output_section->reloc_count); - for (; irel < irelend; irel++, rel_hash++) - { - struct coff_link_hash_entry *h; - boolean adjusted; - - *rel_hash = NULL; - - /* Adjust the reloc address and symbol index. */ - - irel->r_vaddr += offset; - - if (irel->r_symndx == -1) - continue; - - if (adjust_symndx) - { - if (! (*adjust_symndx) (output_bfd, finfo->info, - input_bfd, o, irel, - &adjusted)) - return false; - if (adjusted) - continue; - } - - h = obj_coff_sym_hashes (input_bfd)[irel->r_symndx]; - if (h != NULL) - { - /* This is a global symbol. */ - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* This symbol is being written at the end - of the file, and we do not yet know the - symbol index. We save the pointer to the - hash table entry in the rel_hash list. - We set the indx field to -2 to indicate - that this symbol must not be stripped. */ - *rel_hash = h; - h->indx = -2; - } - } - else - { - long indx; - - indx = finfo->sym_indices[irel->r_symndx]; - if (indx != -1) - irel->r_symndx = indx; - else - { - struct internal_syment *is; - const char *name; - char buf[SYMNMLEN + 1]; - - /* This reloc is against a symbol we are - stripping. It would be possible to - handle this case, but I don't think it's - worth it. */ - is = finfo->internal_syms + irel->r_symndx; - - name = (_bfd_coff_internal_syment_name - (input_bfd, is, buf)); - if (name == NULL) - return false; - - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, o, - irel->r_vaddr))) - return false; - } - } - } - - o->output_section->reloc_count += o->reloc_count; - } - } - - /* Write out the modified section contents. */ - if (! bfd_set_section_contents (output_bfd, o->output_section, - contents, o->output_offset, - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) - return false; - } - - if (! finfo->info->keep_memory) - { - if (! _bfd_coff_free_symbols (input_bfd)) - return false; - } - - return true; -} - -/* Write out a global symbol. Called via coff_link_hash_traverse. */ - -boolean -_bfd_coff_write_global_sym (h, data) - struct coff_link_hash_entry *h; - PTR data; -{ - struct coff_final_link_info *finfo = (struct coff_final_link_info *) data; - bfd *output_bfd; - struct internal_syment isym; - bfd_size_type symesz; - unsigned int i; - - output_bfd = finfo->output_bfd; - - if (h->indx >= 0) - return true; - - if (h->indx != -2 - && (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, false, false) - == NULL)))) - return true; - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - return false; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - isym.n_scnum = N_UNDEF; - isym.n_value = 0; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - asection *sec; - - sec = h->root.u.def.section->output_section; - if (bfd_is_abs_section (sec)) - isym.n_scnum = N_ABS; - else - isym.n_scnum = sec->target_index; - isym.n_value = (h->root.u.def.value - + sec->vma - + h->root.u.def.section->output_offset); - } - break; - - case bfd_link_hash_common: - isym.n_scnum = N_UNDEF; - isym.n_value = h->root.u.c.size; - break; - - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* Just ignore these. They can't be handled anyhow. */ - return true; - } - - if (strlen (h->root.root.string) <= SYMNMLEN) - strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN); - else - { - boolean hash; - bfd_size_type indx; - - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash, - false); - if (indx == (bfd_size_type) -1) - { - finfo->failed = true; - return false; - } - isym._n._n_n._n_zeroes = 0; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - - isym.n_sclass = h->class; - isym.n_type = h->type; - - if (isym.n_sclass == C_NULL) - isym.n_sclass = C_EXT; - - isym.n_numaux = h->numaux; - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms); - - symesz = bfd_coff_symesz (output_bfd); - - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + obj_raw_syment_count (output_bfd) * symesz), - SEEK_SET) != 0 - || bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz) - { - finfo->failed = true; - return false; - } - - h->indx = obj_raw_syment_count (output_bfd); - - ++obj_raw_syment_count (output_bfd); - - /* Write out any associated aux entries. There normally will be - none. If there are any, I have no idea how to modify them. */ - for (i = 0; i < isym.n_numaux; i++) - { - bfd_coff_swap_aux_out (output_bfd, (PTR) (h->aux + i), isym.n_type, - isym.n_sclass, i, isym.n_numaux, - (PTR) finfo->outsyms); - if (bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz) - { - finfo->failed = true; - return false; - } - ++obj_raw_syment_count (output_bfd); - } - - return true; -} - -/* Handle a link order which is supposed to generate a reloc. */ - -boolean -_bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) - bfd *output_bfd; - struct coff_final_link_info *finfo; - asection *output_section; - struct bfd_link_order *link_order; -{ - reloc_howto_type *howto; - struct internal_reloc *irel; - struct coff_link_hash_entry **rel_hash_ptr; - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (link_order->u.reloc.p->addend != 0) - { - bfd_size_type size; - bfd_byte *buf; - bfd_reloc_status_type rstat; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == NULL) - return false; - - rstat = _bfd_relocate_contents (howto, output_bfd, - link_order->u.reloc.p->addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - howto->name, link_order->u.reloc.p->addend, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - /* Store the reloc information in the right place. It will get - swapped and written out at the end of the final_link routine. */ - - irel = (finfo->section_info[output_section->target_index].relocs - + output_section->reloc_count); - rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes - + output_section->reloc_count); - - memset (irel, 0, sizeof (struct internal_reloc)); - *rel_hash_ptr = NULL; - - irel->r_vaddr = output_section->vma + link_order->offset; - - if (link_order->type == bfd_section_reloc_link_order) - { - /* We need to somehow locate a symbol in the right section. The - symbol must either have a value of zero, or we must adjust - the addend by the value of the symbol. FIXME: Write this - when we need it. The old linker couldn't handle this anyhow. */ - abort (); - *rel_hash_ptr = NULL; - irel->r_symndx = 0; - } - else - { - struct coff_link_hash_entry *h; - - h = ((struct coff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, finfo->info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h != NULL) - { - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* Set the index to -2 to force this symbol to get - written out. */ - h->indx = -2; - *rel_hash_ptr = h; - irel->r_symndx = 0; - } - } - else - { - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - irel->r_symndx = 0; - } - } - - /* FIXME: Is this always right? */ - irel->r_type = howto->type; - - /* r_size is only used on the RS/6000, which needs its own linker - routines anyhow. r_extern is only used for ECOFF. */ - - /* FIXME: What is the right value for r_offset? Is zero OK? */ - - ++output_section->reloc_count; - - return true; -} - -/* A basic reloc handling routine which may be used by processors with - simple relocs. */ - -boolean -_bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, - input_section, contents, relocs, syms, - sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - reloc_howto_type *howto; - bfd_reloc_status_type rstat; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = obj_coff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - } - - /* COFF treats common symbols in one of two ways. Either the - size of the symbol is included in the section contents, or it - is not. We assume that the size is not included, and force - the rtype_to_howto function to adjust the addend as needed. */ - - if (sym != NULL && sym->n_scnum != 0) - addend = - sym->n_value; - else - addend = 0; - - - howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, - sym, &addend); - if (howto == NULL) - return false; - - val = 0; - - if (h == NULL) - { - asection *sec; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - - else if (! info->relocateable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - if (info->base_file) - { - /* Emit a reloc if the backend thinks it needs it. */ - if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)) - { - /* relocation to a symbol in a section which - isn't absolute - we output the address here - to a file */ - bfd_vma addr = rel->r_vaddr - - input_section->vma - + input_section->output_offset - + input_section->output_section->vma; - if (coff_data(output_bfd)->pe) - addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; - fwrite (&addr, 1,4, (FILE *) info->base_file); - } - } - - rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - return true; -} - diff --git a/contrib/gdb/bfd/coffswap.h b/contrib/gdb/bfd/coffswap.h deleted file mode 100644 index ef1b6b3a913..00000000000 --- a/contrib/gdb/bfd/coffswap.h +++ /dev/null @@ -1,807 +0,0 @@ -/* Generic COFF swapping routines, for BFD. - Copyright 1990, 1991, 1992, 1993, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file contains routines used to swap COFF data. It is a header - file because the details of swapping depend on the details of the - structures used by each COFF implementation. This is included by - coffcode.h, as well as by the ECOFF backend. - - Any file which uses this must first include "coff/internal.h" and - "coff/CPU.h". The functions will then be correct for that CPU. */ - -#ifndef IMAGE_BASE -#define IMAGE_BASE 0 -#endif - -#define PUTWORD bfd_h_put_32 -#define PUTHALF bfd_h_put_16 -#define PUTBYTE bfd_h_put_8 - -#ifndef GET_FCN_LNNOPTR -#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif - -#ifndef GET_FCN_ENDNDX -#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif - -#ifndef PUT_FCN_LNNOPTR -#define PUT_FCN_LNNOPTR(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif -#ifndef PUT_FCN_ENDNDX -#define PUT_FCN_ENDNDX(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif -#ifndef GET_LNSZ_LNNO -#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef GET_LNSZ_SIZE -#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef PUT_LNSZ_LNNO -#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef PUT_LNSZ_SIZE -#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef GET_SCN_SCNLEN -#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef GET_SCN_NRELOC -#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef GET_SCN_NLINNO -#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno) -#endif -#ifndef PUT_SCN_SCNLEN -#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef PUT_SCN_NRELOC -#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef PUT_SCN_NLINNO -#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno) -#endif -#ifndef GET_LINENO_LNNO -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno)); -#endif -#ifndef PUT_LINENO_LNNO -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno)); -#endif - -/* The f_symptr field in the filehdr is sometimes 64 bits. */ -#ifndef GET_FILEHDR_SYMPTR -#define GET_FILEHDR_SYMPTR bfd_h_get_32 -#endif -#ifndef PUT_FILEHDR_SYMPTR -#define PUT_FILEHDR_SYMPTR bfd_h_put_32 -#endif - -/* Some fields in the aouthdr are sometimes 64 bits. */ -#ifndef GET_AOUTHDR_TSIZE -#define GET_AOUTHDR_TSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TSIZE -#define PUT_AOUTHDR_TSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DSIZE -#define GET_AOUTHDR_DSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DSIZE -#define PUT_AOUTHDR_DSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_BSIZE -#define GET_AOUTHDR_BSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_BSIZE -#define PUT_AOUTHDR_BSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_ENTRY -#define GET_AOUTHDR_ENTRY bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_ENTRY -#define PUT_AOUTHDR_ENTRY bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_TEXT_START -#define GET_AOUTHDR_TEXT_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TEXT_START -#define PUT_AOUTHDR_TEXT_START bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DATA_START -#define GET_AOUTHDR_DATA_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DATA_START -#define PUT_AOUTHDR_DATA_START bfd_h_put_32 -#endif - -/* Some fields in the scnhdr are sometimes 64 bits. */ -#ifndef GET_SCNHDR_PADDR -#define GET_SCNHDR_PADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_PADDR -#define PUT_SCNHDR_PADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_VADDR -#define GET_SCNHDR_VADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_VADDR -#define PUT_SCNHDR_VADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SIZE -#define GET_SCNHDR_SIZE bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SIZE -#define PUT_SCNHDR_SIZE bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SCNPTR -#define GET_SCNHDR_SCNPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SCNPTR -#define PUT_SCNHDR_SCNPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_RELPTR -#define GET_SCNHDR_RELPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_RELPTR -#define PUT_SCNHDR_RELPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_LNNOPTR -#define GET_SCNHDR_LNNOPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_LNNOPTR -#define PUT_SCNHDR_LNNOPTR bfd_h_put_32 -#endif - -#ifndef NO_COFF_RELOCS - -static void -coff_swap_reloc_in (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - RELOC *reloc_src = (RELOC *) src; - struct internal_reloc *reloc_dst = (struct internal_reloc *) dst; - - reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr); - reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx); - -#ifdef RS6000COFF_C - reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type); - reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size); -#else - reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type); -#endif - -#ifdef SWAP_IN_RELOC_OFFSET - reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd, - (bfd_byte *) reloc_src->r_offset); -#endif -} - - -static unsigned int -coff_swap_reloc_out (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - struct internal_reloc *reloc_src = (struct internal_reloc *)src; - struct external_reloc *reloc_dst = (struct external_reloc *)dst; - bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr); - bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx); - -#ifdef RS6000COFF_C - bfd_h_put_8 (abfd, reloc_src->r_type, (bfd_byte *) reloc_dst->r_type); - bfd_h_put_8 (abfd, reloc_src->r_size, (bfd_byte *) reloc_dst->r_size); -#else - bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *) - reloc_dst->r_type); -#endif - -#ifdef SWAP_OUT_RELOC_OFFSET - SWAP_OUT_RELOC_OFFSET(abfd, - reloc_src->r_offset, - (bfd_byte *) reloc_dst->r_offset); -#endif -#ifdef SWAP_OUT_RELOC_EXTRA - SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst); -#endif - - return sizeof(struct external_reloc); -} - -#endif /* NO_COFF_RELOCS */ - -static void -coff_swap_filehdr_in (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - FILHDR *filehdr_src = (FILHDR *) src; - struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; - filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic); - filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns); - filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat); - filehdr_dst->f_symptr = - GET_FILEHDR_SYMPTR (abfd, (bfd_byte *) filehdr_src->f_symptr); - filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms); - filehdr_dst->f_opthdr = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_opthdr); - filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags); -} - -static unsigned int -coff_swap_filehdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in; - FILHDR *filehdr_out = (FILHDR *)out; - - bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic); - bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns); - bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat); - PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr, - (bfd_byte *) filehdr_out->f_symptr); - bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms); - bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr); - bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags); - - return sizeof(FILHDR); -} - - -#ifndef NO_COFF_SYMBOLS - -static void -coff_swap_sym_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - SYMENT *ext = (SYMENT *)ext1; - struct internal_syment *in = (struct internal_syment *)in1; - - if( ext->e.e_name[0] == 0) { - in->_n._n_n._n_zeroes = 0; - in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN); -#endif - } - in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); - in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2){ - in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type); - } - else { - in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type); - } - in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass); - in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux); -} - -static unsigned int -coff_swap_sym_out (abfd, inp, extp) - bfd *abfd; - PTR inp; - PTR extp; -{ - struct internal_syment *in = (struct internal_syment *)inp; - SYMENT *ext =(SYMENT *)extp; - if(in->_n._n_name[0] == 0) { - bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes); - bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN); -#endif - } - bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value); - bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2) - { - bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - else - { - bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass); - bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux); - return sizeof(SYMENT); -} - -static void -coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) - bfd *abfd; - PTR ext1; - int type; - int class; - int indx; - int numaux; - PTR in1; -{ - AUXENT *ext = (AUXENT *)ext1; - union internal_auxent *in = (union internal_auxent *)in1; - - switch (class) { - case C_FILE: - if (ext->x_file.x_fname[0] == 0) { - in->x_file.x_n.x_zeroes = 0; - in->x_file.x_n.x_offset = - bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset); - } else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); -#endif - } - return; - - /* RS/6000 "csect" auxents */ -#ifdef RS6000COFF_C - case C_EXT: - case C_HIDEXT: - if (indx + 1 == numaux) - { - in->x_csect.x_scnlen.l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen); - in->x_csect.x_parmhash = bfd_h_get_32 (abfd, - ext->x_csect.x_parmhash); - in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash); - /* We don't have to hack bitfields in x_smtyp because it's - defined by shifts-and-ands, which are equivalent on all - byte orders. */ - in->x_csect.x_smtyp = bfd_h_get_8 (abfd, ext->x_csect.x_smtyp); - in->x_csect.x_smclas = bfd_h_get_8 (abfd, ext->x_csect.x_smclas); - in->x_csect.x_stab = bfd_h_get_32 (abfd, ext->x_csect.x_stab); - in->x_csect.x_snstab = bfd_h_get_16 (abfd, ext->x_csect.x_snstab); - return; - } - break; -#endif - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext); - in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext); - in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext); - return; - } - break; - } - - in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) - { - in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext); - in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext); - } - else - { -#if DIMNUM != E_DIMNUM - #error we need to cope with truncating or extending DIMNUM -#endif - in->x_sym.x_fcnary.x_ary.x_dimen[0] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - in->x_sym.x_fcnary.x_ary.x_dimen[1] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - in->x_sym.x_fcnary.x_ary.x_dimen[2] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - in->x_sym.x_fcnary.x_ary.x_dimen[3] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } - - if (ISFCN(type)) { - in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize); - } - else { - in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext); - in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext); - } -} - -static unsigned int -coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) - bfd *abfd; - PTR inp; - int type; - int class; - int indx; - int numaux; - PTR extp; -{ - union internal_auxent *in = (union internal_auxent *)inp; - AUXENT *ext = (AUXENT *)extp; - - memset((PTR)ext, 0, AUXESZ); - switch (class) { - case C_FILE: - if (in->x_file.x_fname[0] == 0) { - PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes); - PUTWORD(abfd, - in->x_file.x_n.x_offset, - (bfd_byte *) ext->x_file.x_n.x_offset); - } - else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); -#endif - } - return sizeof (AUXENT); - -#ifdef RS6000COFF_C - /* RS/6000 "csect" auxents */ - case C_EXT: - case C_HIDEXT: - if (indx + 1 == numaux) - { - PUTWORD (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen); - PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash); - PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash); - /* We don't have to hack bitfields in x_smtyp because it's - defined by shifts-and-ands, which are equivalent on all - byte orders. */ - PUTBYTE (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp); - PUTBYTE (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas); - PUTWORD (abfd, in->x_csect.x_stab, ext->x_csect.x_stab); - PUTHALF (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab); - return sizeof (AUXENT); - } - break; -#endif - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext); - PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext); - PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext); - return sizeof (AUXENT); - } - break; - } - - PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) - { - PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); - PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); - } - else - { -#if DIMNUM != E_DIMNUM - #error we need to cope with truncating or extending DIMNUM -#endif - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } - - if (ISFCN (type)) - PUTWORD (abfd, in->x_sym.x_misc.x_fsize, - (bfd_byte *) ext->x_sym.x_misc.x_fsize); - else - { - PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext); - PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext); - } - - return sizeof(AUXENT); -} - -#endif /* NO_COFF_SYMBOLS */ - -#ifndef NO_COFF_LINENOS - -static void -coff_swap_lineno_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - LINENO *ext = (LINENO *)ext1; - struct internal_lineno *in = (struct internal_lineno *)in1; - - in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx); - in->l_lnno = GET_LINENO_LNNO(abfd, ext); -} - -static unsigned int -coff_swap_lineno_out (abfd, inp, outp) - bfd *abfd; - PTR inp; - PTR outp; -{ - struct internal_lineno *in = (struct internal_lineno *)inp; - struct external_lineno *ext = (struct external_lineno *)outp; - PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *) - ext->l_addr.l_symndx); - - PUT_LINENO_LNNO (abfd, in->l_lnno, ext); - return sizeof(struct external_lineno); -} - -#endif /* NO_COFF_LINENOS */ - - -static void -coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) - bfd *abfd; - PTR aouthdr_ext1; - PTR aouthdr_int1; -{ - AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1; - struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1; - - aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic); - aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp); - aouthdr_int->tsize = - GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize); - aouthdr_int->dsize = - GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize); - aouthdr_int->bsize = - GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize); - aouthdr_int->entry = - GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry); - aouthdr_int->text_start = - GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start); - aouthdr_int->data_start = - GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start); - -#ifdef I960 - aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries); -#endif - -#ifdef APOLLO_M68 - bfd_h_put_32(abfd, aouthdr_int->o_inlib, (bfd_byte *) aouthdr_ext->o_inlib); - bfd_h_put_32(abfd, aouthdr_int->o_sri, (bfd_byte *) aouthdr_ext->o_sri); - bfd_h_put_32(abfd, aouthdr_int->vid[0], (bfd_byte *) aouthdr_ext->vid); - bfd_h_put_32(abfd, aouthdr_int->vid[1], (bfd_byte *) aouthdr_ext->vid + 4); -#endif - - -#ifdef RS6000COFF_C - aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc); - aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry); - aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext); - aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata); - aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc); - aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader); - aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss); - aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext); - aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata); - aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype); - aouthdr_int->o_cputype = bfd_h_get_16(abfd, aouthdr_ext->o_cputype); - aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack); - aouthdr_int->o_maxdata = bfd_h_get_32(abfd, aouthdr_ext->o_maxdata); -#endif - -#ifdef MIPSECOFF - aouthdr_int->bss_start = bfd_h_get_32(abfd, aouthdr_ext->bss_start); - aouthdr_int->gp_value = bfd_h_get_32(abfd, aouthdr_ext->gp_value); - aouthdr_int->gprmask = bfd_h_get_32(abfd, aouthdr_ext->gprmask); - aouthdr_int->cprmask[0] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[0]); - aouthdr_int->cprmask[1] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[1]); - aouthdr_int->cprmask[2] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[2]); - aouthdr_int->cprmask[3] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[3]); -#endif - -#ifdef ALPHAECOFF - aouthdr_int->bss_start = bfd_h_get_64(abfd, aouthdr_ext->bss_start); - aouthdr_int->gp_value = bfd_h_get_64(abfd, aouthdr_ext->gp_value); - aouthdr_int->gprmask = bfd_h_get_32(abfd, aouthdr_ext->gprmask); - aouthdr_int->fprmask = bfd_h_get_32(abfd, aouthdr_ext->fprmask); -#endif -} - -static unsigned int -coff_swap_aouthdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in; - AOUTHDR *aouthdr_out = (AOUTHDR *)out; - - bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->magic); - bfd_h_put_16(abfd, aouthdr_in->vstamp, (bfd_byte *) aouthdr_out->vstamp); - PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->tsize); - PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->dsize); - PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->bsize); - PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->entry); - PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start, - (bfd_byte *) aouthdr_out->text_start); - PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, - (bfd_byte *) aouthdr_out->data_start); - -#ifdef I960 - bfd_h_put_32(abfd, aouthdr_in->tagentries, (bfd_byte *) aouthdr_out->tagentries); -#endif - -#ifdef RS6000COFF_C - bfd_h_put_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc); - bfd_h_put_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry); - bfd_h_put_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext); - bfd_h_put_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata); - bfd_h_put_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc); - bfd_h_put_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader); - bfd_h_put_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss); - bfd_h_put_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext); - bfd_h_put_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata); - bfd_h_put_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype); - bfd_h_put_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype); - bfd_h_put_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack); - bfd_h_put_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata); - memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2); -#endif - -#ifdef MIPSECOFF - bfd_h_put_32(abfd, aouthdr_in->bss_start, (bfd_byte *) aouthdr_out->bss_start); - bfd_h_put_32(abfd, aouthdr_in->gp_value, (bfd_byte *) aouthdr_out->gp_value); - bfd_h_put_32(abfd, aouthdr_in->gprmask, (bfd_byte *) aouthdr_out->gprmask); - bfd_h_put_32(abfd, aouthdr_in->cprmask[0], (bfd_byte *) aouthdr_out->cprmask[0]); - bfd_h_put_32(abfd, aouthdr_in->cprmask[1], (bfd_byte *) aouthdr_out->cprmask[1]); - bfd_h_put_32(abfd, aouthdr_in->cprmask[2], (bfd_byte *) aouthdr_out->cprmask[2]); - bfd_h_put_32(abfd, aouthdr_in->cprmask[3], (bfd_byte *) aouthdr_out->cprmask[3]); -#endif - -#ifdef ALPHAECOFF - /* FIXME: What does bldrev mean? */ - bfd_h_put_16(abfd, (bfd_vma) 2, (bfd_byte *) aouthdr_out->bldrev); - bfd_h_put_16(abfd, (bfd_vma) 0, (bfd_byte *) aouthdr_out->padding); - bfd_h_put_64(abfd, aouthdr_in->bss_start, (bfd_byte *) aouthdr_out->bss_start); - bfd_h_put_64(abfd, aouthdr_in->gp_value, (bfd_byte *) aouthdr_out->gp_value); - bfd_h_put_32(abfd, aouthdr_in->gprmask, (bfd_byte *) aouthdr_out->gprmask); - bfd_h_put_32(abfd, aouthdr_in->fprmask, (bfd_byte *) aouthdr_out->fprmask); -#endif - - return sizeof(AOUTHDR); -} - -static void -coff_swap_scnhdr_in (abfd, ext, in) - bfd *abfd; - PTR ext; - PTR in; -{ - SCNHDR *scnhdr_ext = (SCNHDR *) ext; - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; - - memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name)); - scnhdr_int->s_vaddr = - GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr); - scnhdr_int->s_paddr = - GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr); - scnhdr_int->s_size = - GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size); - - scnhdr_int->s_scnptr = - GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr); - scnhdr_int->s_relptr = - GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr); - scnhdr_int->s_lnnoptr = - GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr); - scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags); -#if defined(M88) - scnhdr_int->s_nreloc = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_nreloc); - scnhdr_int->s_nlnno = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_nlnno); -#else - scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc); - scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno); -#endif -#ifdef I960 - scnhdr_int->s_align = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_align); -#endif -} - -static unsigned int -coff_swap_scnhdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in; - SCNHDR *scnhdr_ext = (SCNHDR *)out; - unsigned int ret = sizeof (SCNHDR); - - memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name)); - - PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, - (bfd_byte *) scnhdr_ext->s_vaddr); - - - PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, - (bfd_byte *) scnhdr_ext->s_paddr); - PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, - (bfd_byte *) scnhdr_ext->s_size); - - PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, - (bfd_byte *) scnhdr_ext->s_scnptr); - PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, - (bfd_byte *) scnhdr_ext->s_relptr); - PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, - (bfd_byte *) scnhdr_ext->s_lnnoptr); - PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags); -#if defined(M88) - PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); - PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); -#else - if (scnhdr_int->s_nlnno <= 0xffff) - PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); - else - { - (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff", - bfd_get_filename (abfd), - scnhdr_int->s_nlnno); - bfd_set_error (bfd_error_file_truncated); - PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno); - ret = 0; - } - if (scnhdr_int->s_nreloc <= 0xffff) - PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); - else - { - (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff", - bfd_get_filename (abfd), - scnhdr_int->s_nreloc); - bfd_set_error (bfd_error_file_truncated); - PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc); - ret = 0; - } -#endif - -#if defined(I960) - PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align); -#endif - return ret; -} diff --git a/contrib/gdb/bfd/config.bfd b/contrib/gdb/bfd/config.bfd deleted file mode 100644 index 7757d5fec29..00000000000 --- a/contrib/gdb/bfd/config.bfd +++ /dev/null @@ -1,491 +0,0 @@ -# config.bfd -# Convert a canonical host type into a BFD host type. -# Set shell variable targ to canonical target name, and run -# using ``. config.bfd''. -# Sets the following shell variables: -# targ_defvec Default vector for this target -# targ_selvecs Vectors to build for this target -# targ_archs Architectures for this target -# targ_cflags $(CFLAGS) for this target (FIXME: pretty bogus) -# targ_undercore Whether underscores are used: yes or no - -# The binutils c++filt program wants to know whether underscores are -# stripped or not. That is why we set targ_underscore. c++filt uses -# this information to choose a default. This information is -# duplicated in the symbol_leading_char field of the BFD target -# vector, but c++filt does not deal with object files and is not -# linked against libbfd.a. It is not terribly important that c++filt -# get this right; it is just convenient. - -targ_defvec= -targ_selvecs= -targ_cflags= -targ_underscore=no - -targ_cpu=`echo $targ | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` -case "${targ_cpu}" in -arm*) targ_archs=bfd_arm_arch ;; -hppa*) targ_archs=bfd_hppa_arch ;; -i[345]86) targ_archs=bfd_i386_arch ;; -m68*) targ_archs=bfd_m68k_arch ;; -m88*) targ_archs=bfd_m88k_arch ;; -mips*) targ_archs=bfd_mips_arch ;; -powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;; -rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;; -sparc*) targ_archs=bfd_sparc_arch ;; -z8k*) targ_archs=bfd_z8k_arch ;; -*) targ_archs=bfd_${targ_cpu}_arch ;; -esac - -# WHEN ADDING ENTRIES TO THIS MATRIX: -# Make sure that the left side always has two dashes. Otherwise you -# can get spurious matches. Even for unambiguous cases, do this as a -# convention, else the table becomes a real mess to understand and maintain. - -case "${targ}" in - alpha-*-netware*) - targ_defvec=ecoffalpha_little_vec - targ_selvecs=nlm32_alpha_vec - ;; - alpha-*-*) - targ_defvec=ecoffalpha_little_vec - ;; - - - arm-*-riscix*) - targ_defvec=riscix_vec - ;; - arm-*-pe*) - targ_defvec=armpe_little_vec - targ_selvecs="armpe_little_vec armpe_big_vec armpei_little_vec armpei_big_vec" - targ_underscore=yes - ;; - arm-*-aout | armel-*-aout) - targ_defvec=aout_arm_little_vec - targ_selvecs=aout_arm_big_vec - ;; - armeb-*-aout) - targ_defvec=aout_arm_big_vec - targ_selvecs=aout_arm_little_vec - ;; - arm-*-coff) - targ_defvec=armcoff_little_vec - targ_selvecs=armcoff_big_vec - targ_underscore=yes - ;; - - a29k-*-ebmon* | a29k-*-udi* | a29k-*-coff* | a29k-*-sym1* | \ - a29k-*-vxworks* | a29k-*-sysv*) - targ_defvec=a29kcoff_big_vec - targ_selvecs=sunos_big_vec - targ_underscore=yes - ;; - a29k-*-aout* | a29k-*-bsd* | a29k-*-vsta*) - targ_defvec=sunos_big_vec - targ_underscore=yes - ;; - - h8300*-*-*) - targ_defvec=h8300coff_vec - targ_underscore=yes - ;; - - h8500-*-*) - targ_defvec=h8500coff_vec - targ_underscore=yes - ;; - - sh-*-*) - targ_defvec=shcoff_vec - targ_selvecs="shcoff_vec shlcoff_vec" - targ_underscore=yes - ;; - - hppa*-*-*elf* | hppa*-*-lites* | hppa*-*-sysv4*) - targ_defvec=bfd_elf32_hppa_vec - ;; - hppa*-*-bsd*) - targ_defvec=som_vec - targ_selvecs=bfd_elf32_hppa_vec - ;; - hppa*-*-hpux* | hppa*-*-hiux*) - targ_defvec=som_vec - ;; - hppa*-*-osf*) - targ_defvec=som_vec - targ_selvecs=bfd_elf32_hppa_vec - ;; - - i[345]86-*-sysv4* | i[345]86-*-unixware | i[345]86-*-solaris2* | \ - i[345]86-*-elf | i[345]86-*-sco*elf*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386coff_vec - ;; - i[345]86-*-sysv* | i[345]86-*-isc* | i[345]86-*-sco* | i[345]86-*-coff | \ - i[345]86-*-aix* | i[345]86-*-go32*) - targ_defvec=i386coff_vec - ;; - i[345]86-sequent-bsd*) - targ_defvec=i386dynix_vec - targ_underscore=yes - ;; - i[345]86-*-bsd*) - targ_defvec=i386bsd_vec - targ_underscore=yes - ;; - i[345]86-*-freebsd*) - targ_defvec=i386freebsd_vec - targ_selvecs=i386bsd_vec - targ_underscore=yes - ;; - i[345]86-*-netbsd*) - targ_defvec=i386netbsd_vec - targ_selvecs=i386bsd_vec - targ_underscore=yes - ;; - i[345]86-*-netware*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="nlm32_i386_vec i386coff_vec i386aout_vec" - ;; - i[345]86-*-linuxaout*) - targ_defvec=i386linux_vec - targ_selvecs=bfd_elf32_i386_vec - targ_underscore=yes - ;; - i[345]86-*-linux*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386linux_vec - targ_underscore=yes - ;; - i[345]86-*-lynxos*) - targ_defvec=i386lynx_coff_vec - targ_selvecs=i386lynx_aout_vec - ;; - i[345]86-*-gnu*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386mach3_vec - targ_cflags=-DSTAT_FOR_EXEC - targ_underscore=yes - ;; - i[345]86-*-mach* | i[345]86-*-osf1mk*) - targ_defvec=i386mach3_vec - targ_cflags=-DSTAT_FOR_EXEC - targ_underscore=yes - ;; - i[345]86-*-os9k) - targ_defvec=i386os9k_vec - ;; - i[345]86-*-msdos*) - targ_defvec=i386aout_vec - targ_selvecs=i386msdos_vec - ;; - i[345]86-*-moss*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="i386msdos_vec i386aout_vec" - ;; - i[345]86-*-cygwin32 | i[345]86-*-winnt | i[345]86-*-pe) - targ_defvec=i386pe_vec - targ_selvecs="i386pe_vec i386pei_vec" - ;; - i[345]86-none-*) - targ_defvec=i386coff_vec - ;; - i[345]86-*-aout* | i[345]86*-*-vsta*) - targ_defvec=i386aout_vec - ;; - - i860-*-mach3* | i860-*-osf1* | i860-*-coff*) - targ_defvec=i860coff_vec - ;; - i860-*-sysv4* | i860-*-elf*) - targ_defvec=bfd_elf32_i860_vec - ;; - - i960-*-vxworks4* | i960-*-vxworks5.0) - targ_defvec=b_out_vec_little_host - targ_selvecs="b_out_vec_big_host icoff_little_vec icoff_big_vec" - targ_underscore=yes - ;; - i960-*-vxworks5.* | i960-*-coff* | i960-*-sysv*) - targ_defvec=icoff_little_vec - targ_selvecs="icoff_big_vec b_out_vec_little_host b_out_vec_big_host" - targ_underscore=yes - ;; - i960-*-vxworks* | i960-*-aout* | i960-*-bout* | i960-*-nindy*) - targ_defvec=b_out_vec_little_host - targ_selvecs="b_out_vec_big_host icoff_little_vec icoff_big_vec" - targ_underscore=yes - ;; - - m68*-apollo-*) - targ_defvec=apollocoff_vec - ;; - m68*-bull-sysv*) - targ_defvec=m68kcoffun_vec - targ_underscore=yes - ;; - m68*-hp-bsd*) - targ_defvec=hp300bsd_vec - targ_underscore=yes - ;; - m68*-*-aout*) - targ_defvec=aout0_big_vec - # We include this here, rather than making a separate cisco - # configuration, so that cisco-core.c gets routinely tested at - # least for compilation. - targ_selvecs=cisco_core_vec - targ_underscore=yes - ;; - m68*-*-elf* | m68*-*-sysv4*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs=m68kcoff_vec - ;; - m68*-*-coff* | m68*-*-sysv*) - targ_defvec=m68kcoff_vec - targ_selvecs="m68kcoff_vec versados_vec" - ;; - m68*-*-hpux*) - targ_defvec=hp300hpux_vec - targ_underscore=yes - ;; - m68*-*-linuxaout*) - targ_defvec=m68klinux_vec - targ_selvecs=bfd_elf32_m68k_vec - targ_underscore=yes - ;; - m68*-*-linux*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs=m68klinux_vec - ;; - m68*-*-lynxos*) - targ_defvec=m68klynx_coff_vec - targ_selvecs=m68klynx_aout_vec - ;; - m68*-hp*-netbsd*) - targ_defvec=m68k4knetbsd_vec - targ_selvecs="m68knetbsd_vec hp300bsd_vec sunos_big_vec" - targ_underscore=yes - ;; - m68*-*-netbsd*) - targ_defvec=m68knetbsd_vec - targ_selvecs="m68k4knetbsd_vec hp300bsd_vec sunos_big_vec" - targ_underscore=yes - ;; - m68*-*-sunos* | m68*-*-os68k* | m68*-*-vxworks* | m68*-netx-* | \ - m68*-*-bsd* | m68*-*-vsta*) - targ_defvec=sunos_big_vec - targ_underscore=yes - ;; - m68*-ericsson-*) - targ_defvec=sunos_big_vec - targ_selvecs="m68kcoff_vec tekhex_vec" - targ_underscore=yes - ;; - m68*-cbm-*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs=m68kcoff_vec - ;; - m68*-apple-aux*) - targ_defvec=m68kaux_coff_vec - ;; - m68*-*-psos*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs=ieee_vec - targ_underscore=yes - ;; - - m88*-harris-cxux* | m88*-*-dgux* | m88*-*-sysv4*) - targ_defvec=bfd_elf32_m88k_vec - targ_selvecs=m88kbcs_vec - ;; - m88*-*-mach3*) - targ_defvec=m88kmach3_vec - targ_cflags=-DSTAT_FOR_EXEC - ;; - m88*-*-*) - targ_defvec=m88kbcs_vec - targ_underscore=yes - ;; - - mips*-big-*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; - mips-dec-netbsd*) - targ_defvec=bfd_elf32_littlemips_vec - targ_selvecs=bfd_elf32_bigmips_vec - ;; - mips*-dec-bsd*) - targ_defvec=aout_mips_little_vec - targ_underscore=yes - ;; - mips*-dec-mach3*) - targ_defvec=aout_mips_little_vec - targ_cflags=-DSTAT_FOR_EXEC - ;; - mips*-dec-* | mips*el-*-ecoff*) - targ_defvec=ecoff_little_vec - targ_selvecs=ecoff_big_vec - ;; - mips*-*-ecoff*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; - mips*-*-irix5*) - targ_defvec=bfd_elf32_bigmips_vec - targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec" - ;; - mips*-sgi-* | mips*-*-bsd*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; - mips*-*-mach3*) - targ_defvec=aout_mips_little_vec - targ_cflags=-DSTAT_FOR_EXEC - ;; - mips*-*-sysv4*) - targ_defvec=bfd_elf32_bigmips_vec - targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec" - ;; - mips*-*-sysv* | mips*-*-riscos*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; - mips*el-*-elf*) - targ_defvec=bfd_elf32_littlemips_vec - targ_selvecs=bfd_elf32_bigmips_vec - ;; - mips*-*-elf*) - targ_defvec=bfd_elf32_bigmips_vec - targ_selvecs=bfd_elf32_littlemips_vec - ;; - - ns32k-pc532-mach* | ns32k-pc532-ux*) - targ_defvec=pc532machaout_vec - targ_underscore=yes - ;; - ns32k-*-netbsd* | ns32k-*-lites*) - targ_defvec=pc532netbsd_vec - targ_underscore=yes - ;; - - powerpc-*-aix*) - targ_defvec=rs6000coff_vec - ;; - powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | powerpc-*-solaris2*) - targ_defvec=bfd_elf32_powerpc_vec - targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_vec bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec" - ;; - powerpc-*-macos* | powerpc-*-mpw*) - targ_defvec=pmac_xcoff_vec - ;; - powerpc-*-netware*) - targ_defvec=bfd_elf32_powerpc_vec - targ_selvecs="nlm32_powerpc_vec rs6000coff_vec" - ;; - powerpcle-*-elf* | powerpcle-*-sysv4* | powerpcle-*-eabi* | \ - powerpcle-*-solaris2*) - targ_defvec=bfd_elf32_powerpcle_vec - targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec" - ;; - - powerpcle-*-pe | powerpcle-*-winnt* | powerpcle-*-cygwin32) - targ_defvec=bfd_powerpcle_pe_vec - targ_selvecs="bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec" - ;; - - rs6000-*-*) - targ_defvec=rs6000coff_vec - ;; - - sparc-*-lynxos*) - targ_defvec=sparclynx_coff_vec - targ_selvecs=sparclynx_aout_vec - ;; - sparc-*-netbsd*) - targ_defvec=sparcnetbsd_vec - targ_underscore=yes - ;; - sparc-*-elf* | sparc-*-sysv4* | sparc-*-solaris2*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs=sunos_big_vec - ;; - sparc64-*-aout*) - targ_defvec=sunos_big_vec - targ_underscore=yes - ;; - sparc64-*-elf*) - targ_defvec=bfd_elf64_sparc_vec - targ_selvecs=bfd_elf32_sparc_vec - ;; - sparc64-*-solaris2* | sparc64-*-sysv4*) - targ_defvec=bfd_elf32_sparc_vec - # Adding 64 bit support by default causes things like objdump to - # print addresses as 64 bits. - #targ_selvecs=bfd_elf64_sparc_vec - ;; - sparc-*-netware*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs="nlm32_sparc_vec sunos_big_vec" - ;; - sparc*-*-coff*) - targ_defvec=sparccoff_vec - ;; - sparc*-*-*) - targ_defvec=sunos_big_vec - targ_underscore=yes - ;; - - tahoe-*-*) - targ_defvec=host_aout_vec - targ_underscore=yes - ;; - - vax-*-vms*) - echo 1>&2 "*** BFD does not support target ${targ}." - echo 1>&2 "*** Look in bfd/config.bfd for supported targets." - exit 1 - ;; - vax-*-*) - targ_defvec=host_aout_vec - targ_underscore=yes - ;; - - we32k-*-*) - targ_defvec=we32kcoff_vec - ;; - - w65-*-*) - targ_defvec=w65_vec - ;; - - z8k*-*-*) - targ_defvec=z8kcoff_vec - targ_underscore=yes - ;; - - *-*-ieee*) - targ_defvec=ieee_vec - ;; - - *-adobe-*) - targ_defvec=a_aout_adobe_vec - targ_underscore=yes - ;; - - *-sony-*) - targ_defvec=newsos3_vec - targ_underscore=yes - ;; - - *-tandem-*) - targ_defvec=m68kcoff_vec - targ_selvecs=ieee_vec - ;; - - *) - echo 1>&2 "*** BFD does not support target ${targ}." - echo 1>&2 "*** Look in bfd/config.bfd for supported targets." - exit 1 - ;; -esac diff --git a/contrib/gdb/bfd/config.in b/contrib/gdb/bfd/config.in deleted file mode 100644 index dd4f968e794..00000000000 --- a/contrib/gdb/bfd/config.in +++ /dev/null @@ -1,67 +0,0 @@ -/* config.in. Generated automatically from configure.in by autoheader. */ - -/* Whether malloc must be declared even if is included. */ -#undef NEED_DECLARATION_MALLOC - -/* Whether free must be declared even if is included. */ -#undef NEED_DECLARATION_FREE - -/* Define if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Do we need to use the b modifier when opening binary files? */ -#undef USE_BINARY_FOPEN - -/* Name of host specific header file to include in trad-core.c. */ -#undef TRAD_HEADER - -/* Define only if is available *and* it defines prstatus_t. */ -#undef HAVE_SYS_PROCFS_H - -/* Do we really want to use mmap if it's available? */ -#undef USE_MMAP - -/* Define if you have the fcntl function. */ -#undef HAVE_FCNTL - -/* Define if you have the getpagesize function. */ -#undef HAVE_GETPAGESIZE - -/* Define if you have the madvise function. */ -#undef HAVE_MADVISE - -/* Define if you have the mprotect function. */ -#undef HAVE_MPROTECT - -/* Define if you have the valloc function. */ -#undef HAVE_VALLOC - -/* Define if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define if you have the header file. */ -#undef HAVE_STDDEF_H - -/* Define if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define if you have the header file. */ -#undef HAVE_STRING_H - -/* Define if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_FILE_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define if you have the header file. */ -#undef HAVE_TIME_H - -/* Define if you have the header file. */ -#undef HAVE_UNISTD_H diff --git a/contrib/gdb/bfd/configure b/contrib/gdb/bfd/configure deleted file mode 100644 index 5db14db15a9..00000000000 --- a/contrib/gdb/bfd/configure +++ /dev/null @@ -1,2439 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.8 -# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)" -ac_help="$ac_help - --enable-targets alternative target configurations" -ac_help="$ac_help - --enable-shared build shared BFD library" -ac_help="$ac_help - --enable-commonbfdlib build shared BFD/opcodes/libiberty library" -ac_help="$ac_help - --with-mmap try using mmap for BFD input files if available" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.8" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set LANG and LC_ALL to C if already set. -# These must not be set unconditionally because not all systems understand -# e.g. LANG=C (notably SCO). -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LANG+set}" = set; then LANG=C; export LANG; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=libbfd.c - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' - -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - -# Check whether --enable-64-bit-bfd or --disable-64-bit-bfd was given. -if test "${enable_64_bit_bfd+set}" = set; then - enableval="$enable_64_bit_bfd" - case "${enableval}" in - yes) want64=true ;; - no) want64=false ;; - *) { echo "configure: error: bad value ${enableval} for 64-bit-bfd option" 1>&2; exit 1; } ;; -esac -else - want64=false -fi -# Check whether --enable-targets or --disable-targets was given. -if test "${enable_targets+set}" = set; then - enableval="$enable_targets" - case "${enableval}" in - yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; } - ;; - no) enable_targets= ;; - *) enable_targets=$enableval ;; -esac -fi -# Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - case "${enableval}" in - yes) shared=true ;; - no) shared=false ;; - *) { echo "configure: error: bad value ${enableval} for BFD shared option" 1>&2; exit 1; } ;; -esac -fi -# Check whether --enable-commonbfdlib or --disable-commonbfdlib was given. -if test "${enable_commonbfdlib+set}" = set; then - enableval="$enable_commonbfdlib" - case "${enableval}" in - yes) commonbfdlib=true ;; - no) commonbfdlib=false ;; - *) { echo "configure: error: bad value ${enableval} for BFD commonbfdlib option" 1>&2; exit 1; } ;; -esac -fi -# Check whether --with-mmap or --without-mmap was given. -if test "${with_mmap+set}" = set; then - withval="$with_mmap" - case "${withval}" in - yes) want_mmap=true ;; - no) want_mmap=false ;; - *) { echo "configure: error: bad value ${withval} for BFD with-mmap option" 1>&2; exit 1; } ;; -esac -else - want_mmap=false -fi - - - -ac_aux_dir= -for ac_dir in `cd $srcdir/..;pwd` $srcdir/`cd $srcdir/..;pwd`; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir/..;pwd` $srcdir/`cd $srcdir/..;pwd`" 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - - -# Do some error checking and defaulting for the host and target type. -# The inputs are: -# configure --host=HOST --target=TARGET --build=BUILD NONOPT -# -# The rules are: -# 1. You are not allowed to specify --host, --target, and nonopt at the -# same time. -# 2. Host defaults to nonopt. -# 3. If nonopt is not specified, then host defaults to the current host, -# as determined by config.guess. -# 4. Target and build default to nonopt. -# 5. If nonopt is not specified, then target and build default to host. - -# The aliases save the names the user supplied, while $host etc. -# will get canonicalized. -case $host---$target---$nonopt in -NONE---*---* | *---NONE---* | *---*---NONE) ;; -*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; -esac - - -# Make sure we can run config.sub. -if $ac_config_sub sun4 >/dev/null 2>&1; then : -else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } -fi - -echo $ac_n "checking host system type""... $ac_c" 1>&6 - -host_alias=$host -case "$host_alias" in -NONE) - case $nonopt in - NONE) - if host_alias=`$ac_config_guess`; then : - else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } - fi ;; - *) host_alias=$nonopt ;; - esac ;; -esac - -host=`$ac_config_sub $host_alias` -host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` -echo "$ac_t""$host" 1>&6 - -echo $ac_n "checking target system type""... $ac_c" 1>&6 - -target_alias=$target -case "$target_alias" in -NONE) - case $nonopt in - NONE) target_alias=$host_alias ;; - *) target_alias=$nonopt ;; - esac ;; -esac - -target=`$ac_config_sub $target_alias` -target_cpu=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` -target_vendor=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` -target_os=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` -echo "$ac_t""$target" 1>&6 - -echo $ac_n "checking build system type""... $ac_c" 1>&6 - -build_alias=$build -case "$build_alias" in -NONE) - case $nonopt in - NONE) build_alias=$host_alias ;; - *) build_alias=$nonopt ;; - esac ;; -esac - -build=`$ac_config_sub $build_alias` -build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` -build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` -build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` -echo "$ac_t""$build" 1>&6 - -test "$host_alias" != "$target_alias" && - test "$program_prefix$program_suffix$program_transform_name" = \ - NONENONEs,x,x, && - program_prefix=${target_alias}- - -if test -z "$target" ; then - { echo "configure: error: Unrecognized target system type; please check config.sub." 1>&2; exit 1; } -fi -if test "$program_transform_name" = s,x,x,; then - program_transform_name= -else - # Double any \ or $. echo might interpret backslashes. - cat <<\EOF_SED > conftestsed -s,\\,\\\\,g; s,\$,$$,g -EOF_SED - program_transform_name="`echo $program_transform_name|sed -f conftestsed`" - rm -f conftestsed -fi -test "$program_prefix" != NONE && - program_transform_name="s,^,${program_prefix},; $program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" - -# sed with no file args requires a program. -test "$program_transform_name" = "" && program_transform_name="s,x,x," - - -host64=false -target64=false - -# host stuff: - -ALLLIBS='$(TARGETLIB)' -PICFLAG= -SHLIB=unused-shlib -SHLINK=unused-shlink -if test "${shared}" = "true"; then - PICFLAG=-fpic - if test "${commonbfdlib}" = "true"; then - ALLLIBS='$(TARGETLIB)' - else - ALLLIBS='$(TARGETLIB) $(SHLIB) $(SHLINK)' - SHLIB=libbfd.so.`sed -e 's/[^0-9]*\([0-9.]*\).*/\1/' ${srcdir}/VERSION` - SHLINK=libbfd.so - fi -fi - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - ac_prog_rejected=no - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 -if test $ac_cv_prog_gcc = yes; then - GCC=yes - if test "${CFLAGS+set}" != set; then - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_gcc_g=yes -else - ac_cv_prog_gcc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 - if test $ac_cv_prog_gcc_g = yes; then - CFLAGS="-g -O" - else - CFLAGS="-O" - fi - fi -else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" -fi - - -# Permit host specific settings. -. ${srcdir}/configure.host - - -if test $host != $build; then - ac_tool_prefix=${host_alias}- -else - ac_tool_prefix= -fi - -# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" -fi -fi -AR="$ac_cv_prog_AR" -if test -n "$AR"; then - echo "$ac_t""$AR" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - - -# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -if test -z "$ac_cv_prog_RANLIB"; then -if test -n "$ac_tool_prefix"; then - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="ranlib" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -else - RANLIB=":" -fi -fi - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_ifs" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -if test "${shared}" = "true"; then - if test "${GCC}" != "yes" && test "${shared_non_gcc}" != "yes"; then - echo "configure: warning: BFD --enable-shared only supported when using gcc" 1>&2 - shared=false - ALLLIBS='$(TARGETLIB)' - PICFLAG= - SHLIB=unused-shlib - fi -fi - - - - - - -if test "${commonbfdlib}" = "true"; then - COMMON_SHLIB=yes - PICLIST=piclist -else - COMMON_SHLIB= - PICLIST= -fi - - - - -HOST_64BIT_LONG=0 -if test "x${HOST_64BIT_TYPE}" = "xlong"; then - HOST_64BIT_LONG=1 -fi - - -# If we cannot run a trivial program, we must be cross compiling. -echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - ac_cv_c_cross=yes -else -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } -if test -s conftest && (./conftest; exit) 2>/dev/null; then - ac_cv_c_cross=no -else - ac_cv_c_cross=yes -fi -fi -rm -fr conftest* -fi - -echo "$ac_t""$ac_cv_c_cross" 1>&6 -cross_compiling=$ac_cv_c_cross - -# Put a plausible default for CC_FOR_BUILD in Makefile. -if test -z "$CC_FOR_BUILD"; then - if test "x$cross_compiling" = "xno"; then - CC_FOR_BUILD='$(CC)' - else - CC_FOR_BUILD=gcc - fi -fi - - -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1104: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1119: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -for ac_hdr in stddef.h string.h strings.h stdlib.h time.h unistd.h -do -ac_safe=`echo "$ac_hdr" | tr './\055' '___'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'` - cat >> confdefs.h <&6 -fi -done - -for ac_hdr in fcntl.h sys/file.h sys/time.h -do -ac_safe=`echo "$ac_hdr" | tr './\055' '___'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1189: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'` - cat >> confdefs.h <&6 -fi -done - -echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -#include -int main() { return 0; } -int t() { -struct tm *tp; -; return 0; } -EOF -if { (eval echo configure:1228: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_header_time=yes -else - rm -rf conftest* - ac_cv_header_time=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_header_time" 1>&6 -if test $ac_cv_header_time = yes; then - cat >> confdefs.h <<\EOF -#define TIME_WITH_SYS_TIME 1 -EOF - -fi - -for ac_func in fcntl getpagesize -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -char $ac_func(); - -int main() { return 0; } -int t() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:1276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* - -fi -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 -fi -done - - - -case "${host}" in -i[345]86-*-msdos* | i[345]86-*-go32* | *-*-cygwin32) - cat >> confdefs.h <<\EOF -#define USE_BINARY_FOPEN 1 -EOF - ;; -esac - -echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -int main() { return 0; } -int t() { -char *(*pfn) = (char *(*)) malloc -; return 0; } -EOF -if { (eval echo configure:1328: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - bfd_cv_decl_needed_malloc=no -else - rm -rf conftest* - bfd_cv_decl_needed_malloc=yes -fi -rm -f conftest* - -fi - -echo "$ac_t""$bfd_cv_decl_needed_malloc" 1>&6 -if test $bfd_cv_decl_needed_malloc = yes; then - bfd_tr_decl=NEED_DECLARATION_`echo malloc | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 -if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -int main() { return 0; } -int t() { -char *(*pfn) = (char *(*)) free -; return 0; } -EOF -if { (eval echo configure:1368: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - bfd_cv_decl_needed_free=no -else - rm -rf conftest* - bfd_cv_decl_needed_free=yes -fi -rm -f conftest* - -fi - -echo "$ac_t""$bfd_cv_decl_needed_free" 1>&6 -if test $bfd_cv_decl_needed_free = yes; then - bfd_tr_decl=NEED_DECLARATION_`echo free | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/alphalinux.h" -EOF - - ;; - alpha*-*-*) COREFILE=osf-core.o ;; - arm-*-riscix) COREFILE=trad-core.o ;; - hppa*-*-hpux*) COREFILE=hpux-core.o ;; - hppa*-*-hiux*) COREFILE=hpux-core.o ;; - hppa*-*-bsd*) COREFILE="hpux-core.o hppabsd-core.o" - COREFLAG="-DHPUX_CORE -DHPPABSD_CORE" ;; - i[345]86-sequent-bsd*) - COREFILE=trad-core.o; - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/symmetry.h" -EOF - - ;; - i[345]86-sequent-sysv4*) ;; - i[345]86-sequent-sysv*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/symmetry.h" -EOF - - ;; - i[345]86-*-bsd* | i[345]86-*-freebsd*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/i386bsd.h" -EOF - - ;; - i[345]86-*-netbsd*) - COREFILE=netbsd-core.o - ;; - i[345]86-esix-sysv3*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/esix.h" -EOF - - ;; - i[345]86-*-sco* | i[345]86-*-isc*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/i386sco.h" -EOF - - ;; - i[345]86-*-mach3*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/i386mach3.h" -EOF - - ;; - i[345]86-*-linux*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/i386linux.h" -EOF - - ;; - i[345]86-*-isc*) COREFILE=trad-core.o ;; - i[345]86-*-aix*) COREFILE=aix386-core.o ;; - i860-*-mach3* | i860-*-osf1*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/i860mach3.h" -EOF - - ;; - mips-dec-bsd*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/mipsbsd.h" -EOF - - ;; - mips-dec-mach3*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/mipsmach3.h" -EOF - - ;; - mips-*-netbsd*) - COREFILE=netbsd-core.o - ;; - mips-dec-*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/decstation.h" -EOF - - ;; - mips-sgi-irix4*) COREFILE=irix-core.o ;; - mips-sgi-irix5*) COREFILE=irix-core.o ;; - mips-*-mach3*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/mipsmach3.h" -EOF - - ;; - mips-*-sysv4*) ;; - mips-*-sysv* | mips-*-riscos*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/riscos.h" -EOF - - ;; - mips-sony-bsd*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/news-mips.h" -EOF - - ;; - m68*-bull*-sysv*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/dpx2.h" -EOF - - ;; - m68*-hp-hpux*) COREFILE=hpux-core.o ;; - m68*-hp-bsd*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/hp300bsd.h" -EOF - - ;; - m68*-*-linux*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/m68klinux.h" -EOF - - ;; - m68*-motorola-sysv*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/delta68.h" -EOF - - ;; - m68*-sony-*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/news.h" -EOF - - ;; - m68*-*-netbsd*) - COREFILE=netbsd-core.o - ;; - m68*-apple-aux*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/m68kaux.h" -EOF - - ;; - m88*-*-sysv4*) ;; - m88*-motorola-sysv*) COREFILE=ptrace-core.o ;; - m88*-*-mach3*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/m88kmach3.h" -EOF - - ;; - ns32k-pc532-mach) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/pc532mach.h" -EOF - - ;; - ns32k-*-netbsd*) - COREFILE=netbsd-core.o - ;; - rs6000-*-lynx*) COREFILE=lynx-core.o ;; - rs6000-*-aix4*) COREFILE=rs6000-core.o ;; - rs6000-*-*) COREFILE=rs6000-core.o ;; - powerpc-*-aix4*) COREFILE=rs6000-core.o ;; - powerpc-*-aix*) COREFILE=rs6000-core.o ;; - sparc-*-netbsd*) - COREFILE=netbsd-core.o - ;; - tahoe-*-*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/tahoe.h" -EOF - - ;; - vax-*-ultrix2*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/vaxult2.h" -EOF - - ;; - vax-*-ultrix*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/vaxult2.h" -EOF - - ;; - vax-*-*) - COREFILE=trad-core.o - cat >> confdefs.h <<\EOF -#define TRAD_HEADER "hosts/vaxbsd.h" -EOF - - ;; - esac - - case "$COREFILE" in - aix386-core.o) COREFLAG=-DAIX386_CORE ;; - hppabsd-core.o) COREFLAG=-DHPPABSD_CORE ;; - hpux-core.o) COREFLAG=-DHPUX_CORE ;; - irix-core.o) COREFLAG=-DIRIX_CORE ;; - lynx-core.o) COREFLAG=-DLYNX_CORE ;; - osf-core.o) COREFLAG=-DOSF_CORE ;; - ptrace-core.o) COREFLAG=-DPTRACE_CORE ;; - rs6000-core.o) COREFLAG="$COREFLAG -DAIX_CORE" ;; - trad-core.o) COREFLAG="$COREFLAG -DTRAD_CORE" ;; - esac - - # The ELF code uses the native to handle core files. - # Define HAVE_SYS_PROCFS_H if the file exists and defines - # prstatus_t. - echo $ac_n "checking for sys/procfs.h""... $ac_c" 1>&6 - if eval "test \"`echo '$''{'bfd_cv_header_sys_procfs_h'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -int main() { return 0; } -int t() { -prstatus_t t; -; return 0; } -EOF -if { (eval echo configure:1648: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - bfd_cv_header_sys_procfs_h=yes -else - rm -rf conftest* - bfd_cv_header_sys_procfs_h=no -fi -rm -f conftest* - -fi - - echo "$ac_t""$bfd_cv_header_sys_procfs_h" 1>&6 - if test $bfd_cv_header_sys_procfs_h = yes; then - cat >> confdefs.h <<\EOF -#define HAVE_SYS_PROCFS_H 1 -EOF - - fi - -fi - - - -# target stuff: - -# Canonicalize the secondary target names. -if test -n "$enable_targets" ; then - for targ in `echo $enable_targets | sed 's/,/ /g'` - do - result=`$ac_config_sub $targ 2>/dev/null` - if test -n "$result" ; then - canon_targets="$canon_targets $result" - else - # Allow targets that config.sub doesn't recognize, like "all". - canon_targets="$canon_targets $targ" - fi - done -fi - -all_targets=false -defvec= -selvecs= -selarchs= -TDEFINES= -for targ in $target $canon_targets -do - if test "x$targ" = "xall"; then - all_targets=true - else - . $srcdir/config.bfd - if test "x$targ" = "x$target"; then - defvec=$targ_defvec - fi - selvecs="$selvecs $targ_defvec $targ_selvecs" - selarchs="$selarchs $targ_archs" - TDEFINES="$TDEFINES $targ_cflags" - fi -done - - -# This processing still needs to be done if we're to decide properly whether -# 64-bit support needs to be compiled in. Currently, it will be included if -# the default or any other explicitly requested target requires it; it -# will not be included on a 32-bit host if no 64-bit target is requested, and -# no "--with-64-bit-bfd" option is given, even if "--with-targets=all" is -# used. - -# uniq the default and selected vectors in all the configured targets. -f="" -for i in $selvecs ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -selvecs="$f" - -# uniq the architectures in all the configured targets. -f="" -for i in $selarchs ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -selarchs="$f" - -# Target backend .o files. -tb= - -elf="elf.o elflink.o" - -for vec in $selvecs -do - case "$vec" in - # This list is alphabetized to make it easy to compare - # with the two vector lists in targets.c. - a29kcoff_big_vec) tb="$tb coff-a29k.o cofflink.o" ;; - a_out_adobe_vec) tb="$tb aout-adobe.o aout32.o" ;; - armcoff_little_vec) tb="$tb coff-arm.o cofflink.o " ;; - armcoff_big_vec) tb="$tb coff-arm.o cofflink.o " ;; - armpe_little_vec) tb="$tb pe-arm.o cofflink.o " ;; - armpe_big_vec) tb="$tb pe-arm.o cofflink.o " ;; - armpei_little_vec) tb="$tb pei-arm.o cofflink.o " ;; - armpei_big_vec) tb="$tb pei-arm.o cofflink.o " ;; - aout0_big_vec) tb="$tb aout0.o aout32.o" ;; - aout_arm_big_vec) tb="$tb aout-arm.o aout32.o" ;; - aout_arm_little_vec) tb="$tb aout-arm.o aout32.o" ;; - aout_mips_big_vec) tb="$tb mipsbsd.o aout32.o" ;; - aout_mips_little_vec) tb="$tb mipsbsd.o aout32.o" ;; - apollocoff_vec) tb="$tb coff-apollo.o" ;; - b_out_vec_big_host) tb="$tb bout.o aout32.o" ;; - b_out_vec_little_host) tb="$tb bout.o aout32.o" ;; - bfd_elf32_big_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; - bfd_elf32_bigmips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; - bfd_elf32_hppa_vec) tb="$tb elf32-hppa.o elf32.o $elf" ;; - bfd_elf32_i386_vec) tb="$tb elf32-i386.o elf32.o $elf" ;; - bfd_elf32_i860_vec) tb="$tb elf32-i860.o elf32.o $elf" ;; - bfd_elf32_little_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; - bfd_elf32_littlemips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; - bfd_elf32_m68k_vec) tb="$tb elf32-m68k.o elf32.o $elf" ;; - bfd_elf32_m88k_vec) tb="$tb elf32-m88k.o elf32.o $elf" ;; - bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.o elf32.o $elf" ;; - bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.o elf32.o $elf" ;; - bfd_elf32_sparc_vec) tb="$tb elf32-sparc.o elf32.o $elf" ;; - bfd_elf64_big_generic_vec) tb="$tb elf64-gen.o elf64.o $elf" - target64=true ;; - bfd_elf64_little_generic_vec) tb="$tb elf64-gen.o elf64.o $elf" - target64=true ;; - bfd_elf64_sparc_vec) tb="$tb elf64-sparc.o elf64.o $elf" - target64=true ;; - cisco_core_vec) tb="$tb cisco-core.o" ;; - demo_64_vec) tb="$tb demo64.o aout64.o" - target64=true ;; - ecoff_big_vec) tb="$tb coff-mips.o ecoff.o ecofflink.o" ;; - ecoff_little_vec) tb="$tb coff-mips.o ecoff.o ecofflink.o" ;; - ecoffalpha_little_vec) tb="$tb coff-alpha.o ecoff.o ecofflink.o" - target64=true ;; - h8300coff_vec) tb="$tb coff-h8300.o reloc16.o" ;; - h8500coff_vec) tb="$tb coff-h8500.o reloc16.o" ;; - host_aout_vec) tb="$tb host-aout.o aout32.o" ;; - hp300bsd_vec) tb="$tb hp300bsd.o aout32.o" ;; - hp300hpux_vec) tb="$tb hp300hpux.o aout32.o" ;; - i386aout_vec) tb="$tb i386aout.o aout32.o" ;; - i386bsd_vec) tb="$tb i386bsd.o aout32.o" ;; - i386coff_vec) tb="$tb coff-i386.o cofflink.o" ;; - i386dynix_vec) tb="$tb i386dynix.o aout32.o" ;; - i386freebsd_vec) tb="$tb i386freebsd.o aout32.o" ;; - i386msdos_vec) tb="$tb i386msdos.o" ;; - i386pe_vec) tb="$tb pe-i386.o cofflink.o " ;; - i386pei_vec) tb="$tb pei-i386.o cofflink.o" ;; - i386linux_vec) tb="$tb i386linux.o aout32.o" ;; - i386lynx_aout_vec) tb="$tb i386lynx.o lynx-core.o aout32.o" ;; - i386lynx_coff_vec) tb="$tb cf-i386lynx.o cofflink.o lynx-core.o" ;; - i386mach3_vec) tb="$tb i386mach3.o aout32.o" ;; - i386netbsd_vec) tb="$tb i386netbsd.o aout32.o" ;; - i386os9k_vec) tb="$tb i386os9k.o aout32.o" ;; - i860coff_vec) tb="$tb coff-i860.o cofflink.o" ;; - icoff_big_vec) tb="$tb coff-i960.o cofflink.o" ;; - icoff_little_vec) tb="$tb coff-i960.o cofflink.o" ;; - ieee_vec) tb="$tb ieee.o" ;; - m68kcoff_vec) tb="$tb coff-m68k.o cofflink.o" ;; - m68kcoffun_vec) tb="$tb coff-u68k.o coff-m68k.o cofflink.o" ;; - m68klinux_vec) tb="$tb m68klinux.o aout32.o" ;; - m68klynx_aout_vec) tb="$tb m68klynx.o lynx-core.o aout32.o" ;; - m68klynx_coff_vec) tb="$tb cf-m68klynx.o coff-m68k.o cofflink.o lynx-core.o" ;; - m68knetbsd_vec) tb="$tb m68knetbsd.o aout32.o" ;; - m68k4knetbsd_vec) tb="$tb m68k4knetbsd.o aout32.o" ;; - m68kaux_coff_vec) tb="$tb coff-aux.o coff-m68k.o cofflink.o" ;; - m88kbcs_vec) tb="$tb coff-m88k.o" ;; - newsos3_vec) tb="$tb newsos3.o aout32.o" ;; - nlm32_i386_vec) tb="$tb nlm32-i386.o nlm32.o nlm.o" ;; - nlm32_sparc_vec) tb="$tb nlm32-sparc.o nlm32.o nlm.o" ;; - nlm32_alpha_vec) tb="$tb nlm32-alpha.o nlm32.o nlm.o" - target64=true ;; - riscix_vec) tb="$tb aout32.o riscix.o" ;; - nlm32_powerpc_vec) tb="$tb nlm32-ppc.o nlm32.o nlm.o" ;; - pc532netbsd_vec) tb="$tb ns32knetbsd.o aout-ns32k.o" ;; - pc532machaout_vec) tb="$tb pc532-mach.o aout-ns32k.o" ;; - pmac_xcoff_vec) tb="$tb coff-pmac.o xcofflink.o" ;; - rs6000coff_vec) tb="$tb coff-rs6000.o xcofflink.o" ;; - bfd_powerpc_pe_vec) tb="$tb pe-ppc.o cofflink.o" ;; - bfd_powerpcle_pe_vec) tb="$tb pe-ppc.o cofflink.o" ;; - bfd_powerpc_pei_vec) tb="$tb pei-ppc.o cofflink.o" ;; - bfd_powerpcle_pei_vec) tb="$tb pei-ppc.o cofflink.o" ;; - shcoff_vec) tb="$tb coff-sh.o cofflink.o" ;; - shlcoff_vec) tb="$tb coff-sh.o cofflink.o" ;; - som_vec) tb="$tb som.o" ;; - sparclynx_aout_vec) tb="$tb sparclynx.o lynx-core.o aout32.o" ;; - sparclynx_coff_vec) tb="$tb cf-sparclynx.o lynx-core.o" ;; - sparcnetbsd_vec) tb="$tb sparcnetbsd.o aout32.o" ;; - sparccoff_vec) tb="$tb coff-sparc.o" ;; - srec_vec) tb="$tb srec.o" ;; - sunos_big_vec) tb="$tb sunos.o aout32.o" ;; - symbolsrec_vec) tb="$tb srec.o" ;; - tekhex_vec) tb="$tb tekhex.o" ;; - we32kcoff_vec) tb="$tb coff-we32k.o" ;; - z8kcoff_vec) tb="$tb coff-z8k.o reloc16.o" ;; - w65_vec) tb="$tb coff-w65.o reloc16.o" ;; - versados_vec) tb="$tb versados.o" ;; - - "") ;; - *) { echo "configure: error: *** unknown target vector $vec" 1>&2; exit 1; } ;; - esac -done - -# Target architecture .o files. -ta=`echo $selarchs | sed -e s/bfd_/cpu-/g -e s/_arch/.o/g` - -# Weed out duplicate .o files. -f="" -for i in $tb ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -tb="$f" - -f="" -for i in $ta ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -ta="$f" - -bfd_backends="$tb" -bfd_machines="$ta" - -if test x${all_targets} = xtrue ; then - bfd_backends="${bfd_backends}"' $(ALL_BACKENDS)' - bfd_machines="${bfd_machines}"' $(ALL_MACHINES)' - selvecs= - selarchs= -else # all_targets is true - # Only set these if they will be nonempty, for the clever echo. - test -n "$selvecs" && - selvecs=`echo $selvecs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'` - test -n "$selarchs" && - selarchs=`echo $selarchs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'` -fi # all_targets is true - -case ${host64}-${target64}-${want64} in - *true*) - wordsize=64 - all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)' - ;; - false-false-false) - wordsize=32 - all_backends='$(BFD32_BACKENDS)' - ;; -esac - - - - - - -tdefaults="" -test -n "${defvec}" && tdefaults="${tdefaults} -DDEFAULT_VECTOR=${defvec}" -test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'" -test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'" - - -for ac_func in valloc getpagesize -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -char $ac_func(); - -int main() { return 0; } -int t() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:1950: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* - -fi -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 -fi -done - -echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_func_mmap'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_mmap=no -else -cat > conftest.$ac_ext < -#include -#include - -#ifndef HAVE_GETPAGESIZE -# include -# ifdef EXEC_PAGESIZE -# define getpagesize() EXEC_PAGESIZE -# else -# ifdef NBPG -# define getpagesize() NBPG * CLSIZE -# ifndef CLSIZE -# define CLSIZE 1 -# endif -# else -# ifdef NBPC -# define getpagesize() NBPC -# else -# define getpagesize() PAGESIZE /* SVR4 */ -# endif -# endif -# endif -#endif - -#ifndef HAVE_VALLOC -# define valloc malloc -#endif - -#ifdef __cplusplus -extern "C" { void *valloc(unsigned), *malloc(unsigned); } -#else -char *valloc(), *malloc(); -#endif - -int -main() -{ - char *buf1, *buf2, *buf3; - int i = getpagesize(), j; - int i2 = i * 2; - int fd; - - buf1 = (char *)valloc(i2); - buf2 = (char *)valloc(i); - buf3 = (char *)malloc(i2); - for (j = 0; j < i2; ++j) - *(buf1 + j) = rand(); - fd = open("conftestmmap", O_CREAT | O_RDWR, 0666); - write(fd, buf1, i2); - mmap(buf2, i, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, 0); - for (j = 0; j < i; ++j) - if (*(buf1 + j) != *(buf2 + j)) - exit(1); - lseek(fd, (long)i, 0); - read(fd, buf2, i); /* read into mapped memory -- file should not change */ - /* (it does in i386 SVR4.0 - Jim Avera, jima@netcom.com) */ - lseek(fd, (long)0, 0); - read(fd, buf3, i2); - for (j = 0; j < i2; ++j) - if (*(buf1 + j) != *(buf3 + j)) - exit(1); - exit(0); -} - -EOF -{ (eval echo configure:2049: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } -if test -s conftest && (./conftest; exit) 2>/dev/null; then - ac_cv_func_mmap=yes -else - ac_cv_func_mmap=no -fi -fi -rm -fr conftest* -fi - -echo "$ac_t""$ac_cv_func_mmap" 1>&6 -if test $ac_cv_func_mmap = yes; then - cat >> confdefs.h <<\EOF -#define HAVE_MMAP 1 -EOF - -fi - -for ac_func in madvise mprotect -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -char $ac_func(); - -int main() { return 0; } -int t() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:2096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* - -fi -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 -fi -done - -case ${want_mmap}+${ac_cv_func_mmap} in - true+yes ) cat >> confdefs.h <<\EOF -#define USE_MMAP 1 -EOF - ;; -esac - -rm -f doc/config.status -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ - >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -DEFS=-DHAVE_CONFIG_H - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.8" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile doc/Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@host@%$host%g -s%@host_alias@%$host_alias%g -s%@host_cpu@%$host_cpu%g -s%@host_vendor@%$host_vendor%g -s%@host_os@%$host_os%g -s%@target@%$target%g -s%@target_alias@%$target_alias%g -s%@target_cpu@%$target_cpu%g -s%@target_vendor@%$target_vendor%g -s%@target_os@%$target_os%g -s%@build@%$build%g -s%@build_alias@%$build_alias%g -s%@build_cpu@%$build_cpu%g -s%@build_vendor@%$build_vendor%g -s%@build_os@%$build_os%g -s%@CC@%$CC%g -s%@HDEFINES@%$HDEFINES%g -s%@AR@%$AR%g -s%@RANLIB@%$RANLIB%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@ALLLIBS@%$ALLLIBS%g -s%@PICFLAG@%$PICFLAG%g -s%@SHLIB@%$SHLIB%g -s%@SHLIB_CC@%$SHLIB_CC%g -s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g -s%@COMMON_SHLIB@%$COMMON_SHLIB%g -s%@PICLIST@%$PICLIST%g -s%@SHLINK@%$SHLINK%g -s%@HOST_64BIT_LONG@%$HOST_64BIT_LONG%g -s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g -s%@CPP@%$CPP%g -s%@COREFILE@%$COREFILE%g -s%@COREFLAG@%$COREFLAG%g -s%@TDEFINES@%$TDEFINES%g -s%@wordsize@%$wordsize%g -s%@all_backends@%$all_backends%g -s%@bfd_backends@%$bfd_backends%g -s%@bfd_machines@%$bfd_machines%g -s%@tdefaults@%$tdefaults%g - -CEOF -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust relative srcdir, etc. for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file -fi; done -rm -f conftest.subs - -# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where -# NAME is the cpp macro being defined and VALUE is the value it is being given. -# -# ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' -ac_dC='\3' -ac_dD='%g' -# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". -ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_uB='\([ ]\)%\1#\2define\3' -ac_uC=' ' -ac_uD='\4%g' -# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_eB='$%\1#\2define\3' -ac_eC=' ' -ac_eD='%g' - -CONFIG_HEADERS=${CONFIG_HEADERS-"config.h:config.in"} -for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then - # Support "outfile[:infile]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - echo creating $ac_file - - rm -f conftest.frag conftest.in conftest.out - cp $ac_given_srcdir/$ac_file_in conftest.in - -EOF - -# Transform confdefs.h into a sed script conftest.vals that substitutes -# the proper values into config.h.in to produce config.h. And first: -# Protect against being on the right side of a sed subst in config.status. -# Protect against being in an unquoted here document in config.status. -rm -f conftest.vals -cat > conftest.hdr <<\EOF -s/[\\&%]/\\&/g -s%[\\$`]%\\&%g -s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp -s%ac_d%ac_u%gp -s%ac_u%ac_e%gp -EOF -sed -n -f conftest.hdr confdefs.h > conftest.vals -rm -f conftest.hdr - -# This sed command replaces #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -cat >> conftest.vals <<\EOF -s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% -EOF - -# Break up conftest.vals because some shells have a limit on -# the size of here documents, and old seds have small limits too. -# Maximum number of lines to put in a single here document. -ac_max_here_lines=12 - -rm -f conftest.tail -while : -do - ac_lines=`grep -c . conftest.vals` - # grep -c gives empty output for an empty file on some AIX systems. - if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi - # Write a limited-size here document to conftest.frag. - echo ' cat > conftest.frag <> $CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS - echo 'CEOF - sed -f conftest.frag conftest.in > conftest.out - rm -f conftest.in - mv conftest.out conftest.in -' >> $CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail - rm -f conftest.vals - mv conftest.tail conftest.vals -done -rm -f conftest.vals - -cat >> $CONFIG_STATUS <<\EOF - rm -f conftest.frag conftest.h - echo "/* $ac_file. Generated automatically by configure. */" > conftest.h - cat conftest.in >> conftest.h - rm -f conftest.in - if cmp -s $ac_file conftest.h 2>/dev/null; then - echo "$ac_file is unchanged" - rm -f conftest.h - else - rm -f $ac_file - mv conftest.h $ac_file - fi -fi; done - - -case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - diff --git a/contrib/gdb/bfd/configure.bat b/contrib/gdb/bfd/configure.bat deleted file mode 100644 index 78fe79e9112..00000000000 --- a/contrib/gdb/bfd/configure.bat +++ /dev/null @@ -1,18 +0,0 @@ -@echo off -if "%1" == "h8/300" goto h8300 - -echo Configuring bfd for go32 -update hosts\go32.h sysdep.h -update Makefile.dos Makefile -echo s/@WORDSIZE@/32/g>config.sed -sed -e s/^/s\/@VERSION@\// -e s/$/\/g/g version >>config.sed -sed -f config.sed < bfd-in2.h > bfd.h2 -update bfd.h2 bfd.h -goto exit - -:h8300 -echo Configuring bfd for H8/300 -update hosts\h-go32.h sysdep.h -update Makefile.dos Makefile - -:exit diff --git a/contrib/gdb/bfd/configure.host b/contrib/gdb/bfd/configure.host deleted file mode 100644 index 484e5bda90e..00000000000 --- a/contrib/gdb/bfd/configure.host +++ /dev/null @@ -1,128 +0,0 @@ -# This file is a shell script that overrides some of the tools and -# flags used on a host specific basis. - -# Since the "bfd/hosts" directory is shared by the bfd, opcodes, and -# binutils directories (at least), the index to it is also shared. -# This is that index. Each configure.in file should source this file -# in its per-host part. - -# This sets the following shell variables: -# HDEFINES host specific compiler options -# host64 set to true if this is a 64 bit host -# HOST_64BIT_TYPE host 64 bit type -# SHLIB_CC compiler to use when building shared library -# SHLIB_CFLAGS flags to use when building shared library -# PICFLAG may be set to flag to use to compile PIC -# SHLINK may be set to the name to link the shared library to -# ALLLIBS may be set to libraries to build -# HLDFLAGS LDFLAGS specific to the host -# RPATH_ENVVAR environment variable used to find shared libraries - -HDEFINES= -host64=false -HOST_64BIT_TYPE= - -case "${host}" in - -alpha-*-*) host64=true; HOST_64BIT_TYPE=long ;; - -hppa*-*-hpux*) HDEFINES=-DHOST_HPPAHPUX ;; -hppa*-*-hiux*) HDEFINES=-DHOST_HPPAHPUX ;; -hppa*-*-bsd*) HDEFINES=-DHOST_HPPABSD ;; -hppa*-*-osf*) HDEFINES=-DHOST_HPPAOSF ;; - -i[345]86-sequent-bsd*) HDEFINES=-Dshared=genshared ;; -i[345]86-sequent-sysv4*) ;; -i[345]86-sequent-sysv*) HDEFINES=-Dshared=genshared ;; - -mips-dec-netbsd*) ;; -mips-dec-*) HDEFINES="-G 4" ;; -mips-sgi-irix3*) HDEFINES="-G 4" ;; -mips-sgi-irix4*) HDEFINES="-G 4" ;; -mips-*-sysv4*) ;; -mips-*-sysv*) HDEFINES="-G 4" ;; -mips-*-riscos*) HDEFINES="-G 4" ;; - -m68*-hp-hpux*) HDEFINES=-DHOST_HP300HPUX ;; - -esac - -# If we are configuring with --enable-shared, adjust the shared -# library support based on the host. This support must work for both -# the BFD and the opcodes libraries. -HLDFLAGS= -RPATH_ENVVAR=LD_LIBRARY_PATH -SHLIB_CC='$(CC)' -SHLIB_CFLAGS='-shared' -if [ "${shared}" = "true" ]; then - case "${host}" in - hppa*-*-*) picfrag=../config/mh-papic ;; - i[3456]86-*-*) picfrag=../config/mh-x86pic ;; - *-*-*) picfrag=../config/mh-${host_cpu}pic ;; - esac - if [ -f "${picfrag}" ]; then - pic=`sed -n -e 's/^PICFLAG[ ]*=[ ]*\(.*\)$/\1/p' ${picfrag}` - if [ -n "${pic}" ]; then - PICFLAG=${pic} - fi - fi - - case "${host}" in - *-dec-osf*) - # -fpic is not needed on the Alpha. - PICFLAG= - ;; - *-*-hpux*) - # HP/UX uses .sl for shared libraries. - SHLINK=`echo ${SHLINK} | sed -e 's/so$/sl/'` - SHLIB_CFLAGS='-shared $(PICFLAG)' - HLDFLAGS='-Wl,+s,+b,$(libdir)' - RPATH_ENVVAR=SHLIB_PATH - ;; - *-*-irix5*) - # -fpic is not needed on Irix 5. - PICFLAG= - SHLIB_CFLAGS='-shared -Wl,-soname,$(SONAME)' - HLDFLAGS='-Wl,-rpath,$(libdir)' - ;; - *-*-linux*aout*) - ;; - *-*-linux*) - SHLIB_CFLAGS='-shared -Wl,-soname,$(SONAME)' - case "$(libdir)" in - /lib | /usr/lib) ;; - *) HLDFLAGS='-Wl,-rpath,$(libdir)' ;; - esac - ;; - *-*-sysv4* | *-*-solaris*) - SHLIB_CFLAGS='-shared -h $(SONAME)' - HLDFLAGS='-R $(libdir)' - ;; - *-*-sunos*) - # Build a libTARGET-bfd.so.VERSION symlink in the object directory. - ALLLIBS=`echo ${ALLLIBS} | sed -e 's/\$(SHLINK)/stamp-tshlink/'` - ;; - esac -fi - -# On SunOS, if the linker supports the -rpath option, use it to -# prevent ../bfd and ../opcodes from being included in the run time -# search path. -case "${host}" in - *-*-sunos*) - echo 'main () { }' > conftest.c - ${CC} -o conftest -Wl,-rpath= conftest.c >/dev/null 2>conftest.t - if grep 'unrecognized' conftest.t >/dev/null 2>&1; then - : - elif grep 'No such file' conftest.t >/dev/null 2>&1; then - : - elif grep 'do not mix' conftest.t >/dev/null 2>&1; then - : - elif [ "${shared}" = "true" ]; then - HLDFLAGS='-Wl,-rpath=$(libdir)' - else - HLDFLAGS='-Wl,-rpath=' - fi - rm -f conftest.t conftest.c conftest - ;; -esac diff --git a/contrib/gdb/bfd/configure.in b/contrib/gdb/bfd/configure.in deleted file mode 100644 index c8b8de54fe9..00000000000 --- a/contrib/gdb/bfd/configure.in +++ /dev/null @@ -1,577 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -dnl -AC_PREREQ(2.3) -AC_INIT(libbfd.c) - -AC_ARG_ENABLE(64-bit-bfd, -[ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)], -[case "${enableval}" in - yes) want64=true ;; - no) want64=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for 64-bit-bfd option) ;; -esac],[want64=false])dnl -AC_ARG_ENABLE(targets, -[ --enable-targets alternative target configurations], -[case "${enableval}" in - yes | "") AC_ERROR(enable-targets option must specify target names or 'all') - ;; - no) enable_targets= ;; - *) enable_targets=$enableval ;; -esac])dnl -AC_ARG_ENABLE(shared, -[ --enable-shared build shared BFD library], -[case "${enableval}" in - yes) shared=true ;; - no) shared=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for BFD shared option]) ;; -esac])dnl -AC_ARG_ENABLE(commonbfdlib, -[ --enable-commonbfdlib build shared BFD/opcodes/libiberty library], -[case "${enableval}" in - yes) commonbfdlib=true ;; - no) commonbfdlib=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for BFD commonbfdlib option]) ;; -esac])dnl -AC_ARG_WITH(mmap, -[ --with-mmap try using mmap for BFD input files if available], -[case "${withval}" in - yes) want_mmap=true ;; - no) want_mmap=false ;; - *) AC_MSG_ERROR(bad value ${withval} for BFD with-mmap option) ;; -esac],[want_mmap=false])dnl - -AC_CONFIG_HEADER(config.h:config.in) - -AC_CONFIG_AUX_DIR(`cd $srcdir/..;pwd`) -AC_CANONICAL_SYSTEM -if test -z "$target" ; then - AC_MSG_ERROR(Unrecognized target system type; please check config.sub.) -fi -AC_ARG_PROGRAM - -host64=false -target64=false - -# host stuff: - -ALLLIBS='$(TARGETLIB)' -PICFLAG= -SHLIB=unused-shlib -SHLINK=unused-shlink -if test "${shared}" = "true"; then - PICFLAG=-fpic - if test "${commonbfdlib}" = "true"; then - ALLLIBS='$(TARGETLIB)' - else - ALLLIBS='$(TARGETLIB) $(SHLIB) $(SHLINK)' -changequote(,)dnl - SHLIB=libbfd.so.`sed -e 's/[^0-9]*\([0-9.]*\).*/\1/' ${srcdir}/VERSION` -changequote([,])dnl - SHLINK=libbfd.so - fi -fi - -AC_PROG_CC - -# Permit host specific settings. -. ${srcdir}/configure.host - -AC_SUBST(HDEFINES) -AC_CHECK_TOOL(AR, ar) -AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_PROG_INSTALL - -if test "${shared}" = "true"; then - if test "${GCC}" != "yes" && test "${shared_non_gcc}" != "yes"; then - AC_MSG_WARN([BFD --enable-shared only supported when using gcc]) - shared=false - ALLLIBS='$(TARGETLIB)' - PICFLAG= - SHLIB=unused-shlib - fi -fi - -AC_SUBST(ALLLIBS) -AC_SUBST(PICFLAG) -AC_SUBST(SHLIB) -AC_SUBST(SHLIB_CC) -AC_SUBST(SHLIB_CFLAGS) -if test "${commonbfdlib}" = "true"; then - COMMON_SHLIB=yes - PICLIST=piclist -else - COMMON_SHLIB= - PICLIST= -fi -AC_SUBST(COMMON_SHLIB) -AC_SUBST(PICLIST) -AC_SUBST(SHLINK) - -HOST_64BIT_LONG=0 -if test "x${HOST_64BIT_TYPE}" = "xlong"; then - HOST_64BIT_LONG=1 -fi -AC_SUBST(HOST_64BIT_LONG) - -BFD_CC_FOR_BUILD - -AC_CHECK_HEADERS(stddef.h string.h strings.h stdlib.h time.h unistd.h) -AC_CHECK_HEADERS(fcntl.h sys/file.h sys/time.h) -AC_HEADER_TIME -AC_CHECK_FUNCS(fcntl getpagesize) - -BFD_BINARY_FOPEN - -BFD_NEED_DECLARATION(malloc) -BFD_NEED_DECLARATION(free) - -# If we are configured native, pick a core file support file. -COREFILE= -COREFLAG= -if test "${target}" = "${host}"; then - case "${host}" in - alpha*-*-linux*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/alphalinux.h") - ;; - alpha*-*-*) COREFILE=osf-core.o ;; - arm-*-riscix) COREFILE=trad-core.o ;; - hppa*-*-hpux*) COREFILE=hpux-core.o ;; - hppa*-*-hiux*) COREFILE=hpux-core.o ;; - hppa*-*-bsd*) COREFILE="hpux-core.o hppabsd-core.o" - COREFLAG="-DHPUX_CORE -DHPPABSD_CORE" ;; -changequote(,)dnl - i[345]86-sequent-bsd*) -changequote([,])dnl - COREFILE=trad-core.o; - AC_DEFINE(TRAD_HEADER,"hosts/symmetry.h") - ;; -changequote(,)dnl - i[345]86-sequent-sysv4*) ;; - i[345]86-sequent-sysv*) -changequote([,])dnl - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/symmetry.h") - ;; -changequote(,)dnl - i[345]86-*-bsd* | i[345]86-*-freebsd*) -changequote([,])dnl - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/i386bsd.h") - ;; -changequote(,)dnl - i[345]86-*-netbsd*) -changequote([,])dnl - COREFILE=netbsd-core.o - ;; -changequote(,)dnl - i[345]86-esix-sysv3*) -changequote([,])dnl - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/esix.h") - ;; -changequote(,)dnl - i[345]86-*-sco* | i[345]86-*-isc*) -changequote([,])dnl - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/i386sco.h") - ;; -changequote(,)dnl - i[345]86-*-mach3*) -changequote([,])dnl - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/i386mach3.h") - ;; -changequote(,)dnl - i[345]86-*-linux*) -changequote([,])dnl - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/i386linux.h") - ;; -changequote(,)dnl - i[345]86-*-isc*) COREFILE=trad-core.o ;; - i[345]86-*-aix*) COREFILE=aix386-core.o ;; -changequote([,])dnl - i860-*-mach3* | i860-*-osf1*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/i860mach3.h") - ;; - mips-dec-bsd*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/mipsbsd.h") - ;; - mips-dec-mach3*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/mipsmach3.h") - ;; - mips-*-netbsd*) - COREFILE=netbsd-core.o - ;; - mips-dec-*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/decstation.h") - ;; - mips-sgi-irix4*) COREFILE=irix-core.o ;; - mips-sgi-irix5*) COREFILE=irix-core.o ;; - mips-*-mach3*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/mipsmach3.h") - ;; - mips-*-sysv4*) ;; - mips-*-sysv* | mips-*-riscos*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/riscos.h") - ;; - mips-sony-bsd*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/news-mips.h") - ;; - m68*-bull*-sysv*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/dpx2.h") - ;; - m68*-hp-hpux*) COREFILE=hpux-core.o ;; - m68*-hp-bsd*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/hp300bsd.h") - ;; - m68*-*-linux*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/m68klinux.h") - ;; - m68*-motorola-sysv*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER, "hosts/delta68.h") - ;; - m68*-sony-*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/news.h") - ;; - m68*-*-netbsd*) - COREFILE=netbsd-core.o - ;; - m68*-apple-aux*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/m68kaux.h") - ;; - m88*-*-sysv4*) ;; - m88*-motorola-sysv*) COREFILE=ptrace-core.o ;; - m88*-*-mach3*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/m88kmach3.h") - ;; - ns32k-pc532-mach) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/pc532mach.h") - ;; - ns32k-*-netbsd*) - COREFILE=netbsd-core.o - ;; - rs6000-*-lynx*) COREFILE=lynx-core.o ;; - rs6000-*-aix4*) COREFILE=rs6000-core.o ;; - rs6000-*-*) COREFILE=rs6000-core.o ;; - powerpc-*-aix4*) COREFILE=rs6000-core.o ;; - powerpc-*-aix*) COREFILE=rs6000-core.o ;; - sparc-*-netbsd*) - COREFILE=netbsd-core.o - ;; - tahoe-*-*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/tahoe.h") - ;; - vax-*-ultrix2*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/vaxult2.h") - ;; - vax-*-ultrix*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/vaxult2.h") - ;; - vax-*-*) - COREFILE=trad-core.o - AC_DEFINE(TRAD_HEADER,"hosts/vaxbsd.h") - ;; - esac - - case "$COREFILE" in - aix386-core.o) COREFLAG=-DAIX386_CORE ;; - hppabsd-core.o) COREFLAG=-DHPPABSD_CORE ;; - hpux-core.o) COREFLAG=-DHPUX_CORE ;; - irix-core.o) COREFLAG=-DIRIX_CORE ;; - lynx-core.o) COREFLAG=-DLYNX_CORE ;; - osf-core.o) COREFLAG=-DOSF_CORE ;; - ptrace-core.o) COREFLAG=-DPTRACE_CORE ;; - rs6000-core.o) COREFLAG="$COREFLAG -DAIX_CORE" ;; - trad-core.o) COREFLAG="$COREFLAG -DTRAD_CORE" ;; - esac - - # The ELF code uses the native to handle core files. - # Define HAVE_SYS_PROCFS_H if the file exists and defines - # prstatus_t. - AC_MSG_CHECKING([for sys/procfs.h]) - AC_CACHE_VAL(bfd_cv_header_sys_procfs_h, - [AC_TRY_COMPILE([#include ], - [prstatus_t t;], - bfd_cv_header_sys_procfs_h=yes, bfd_cv_header_sys_procfs_h=no)]) - AC_MSG_RESULT($bfd_cv_header_sys_procfs_h) - if test $bfd_cv_header_sys_procfs_h = yes; then - AC_DEFINE(HAVE_SYS_PROCFS_H) - fi - -fi -AC_SUBST(COREFILE) -AC_SUBST(COREFLAG) - -# target stuff: - -# Canonicalize the secondary target names. -if test -n "$enable_targets" ; then - for targ in `echo $enable_targets | sed 's/,/ /g'` - do - result=`$ac_config_sub $targ 2>/dev/null` - if test -n "$result" ; then - canon_targets="$canon_targets $result" - else - # Allow targets that config.sub doesn't recognize, like "all". - canon_targets="$canon_targets $targ" - fi - done -fi - -all_targets=false -defvec= -selvecs= -selarchs= -TDEFINES= -for targ in $target $canon_targets -do - if test "x$targ" = "xall"; then - all_targets=true - else - . $srcdir/config.bfd - if test "x$targ" = "x$target"; then - defvec=$targ_defvec - fi - selvecs="$selvecs $targ_defvec $targ_selvecs" - selarchs="$selarchs $targ_archs" - TDEFINES="$TDEFINES $targ_cflags" - fi -done -AC_SUBST(TDEFINES) - -# This processing still needs to be done if we're to decide properly whether -# 64-bit support needs to be compiled in. Currently, it will be included if -# the default or any other explicitly requested target requires it; it -# will not be included on a 32-bit host if no 64-bit target is requested, and -# no "--with-64-bit-bfd" option is given, even if "--with-targets=all" is -# used. - -# uniq the default and selected vectors in all the configured targets. -f="" -for i in $selvecs ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -selvecs="$f" - -# uniq the architectures in all the configured targets. -f="" -for i in $selarchs ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -selarchs="$f" - -# Target backend .o files. -tb= - -elf="elf.o elflink.o" - -for vec in $selvecs -do - case "$vec" in - # This list is alphabetized to make it easy to compare - # with the two vector lists in targets.c. - a29kcoff_big_vec) tb="$tb coff-a29k.o cofflink.o" ;; - a_out_adobe_vec) tb="$tb aout-adobe.o aout32.o" ;; - armcoff_little_vec) tb="$tb coff-arm.o cofflink.o " ;; - armcoff_big_vec) tb="$tb coff-arm.o cofflink.o " ;; - armpe_little_vec) tb="$tb pe-arm.o cofflink.o " ;; - armpe_big_vec) tb="$tb pe-arm.o cofflink.o " ;; - armpei_little_vec) tb="$tb pei-arm.o cofflink.o " ;; - armpei_big_vec) tb="$tb pei-arm.o cofflink.o " ;; - aout0_big_vec) tb="$tb aout0.o aout32.o" ;; - aout_arm_big_vec) tb="$tb aout-arm.o aout32.o" ;; - aout_arm_little_vec) tb="$tb aout-arm.o aout32.o" ;; - aout_mips_big_vec) tb="$tb mipsbsd.o aout32.o" ;; - aout_mips_little_vec) tb="$tb mipsbsd.o aout32.o" ;; - apollocoff_vec) tb="$tb coff-apollo.o" ;; - b_out_vec_big_host) tb="$tb bout.o aout32.o" ;; - b_out_vec_little_host) tb="$tb bout.o aout32.o" ;; - bfd_elf32_big_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; - bfd_elf32_bigmips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; - bfd_elf32_hppa_vec) tb="$tb elf32-hppa.o elf32.o $elf" ;; - bfd_elf32_i386_vec) tb="$tb elf32-i386.o elf32.o $elf" ;; - bfd_elf32_i860_vec) tb="$tb elf32-i860.o elf32.o $elf" ;; - bfd_elf32_little_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; - bfd_elf32_littlemips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; - bfd_elf32_m68k_vec) tb="$tb elf32-m68k.o elf32.o $elf" ;; - bfd_elf32_m88k_vec) tb="$tb elf32-m88k.o elf32.o $elf" ;; - bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.o elf32.o $elf" ;; - bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.o elf32.o $elf" ;; - bfd_elf32_sparc_vec) tb="$tb elf32-sparc.o elf32.o $elf" ;; - bfd_elf64_big_generic_vec) tb="$tb elf64-gen.o elf64.o $elf" - target64=true ;; - bfd_elf64_little_generic_vec) tb="$tb elf64-gen.o elf64.o $elf" - target64=true ;; - bfd_elf64_sparc_vec) tb="$tb elf64-sparc.o elf64.o $elf" - target64=true ;; - cisco_core_vec) tb="$tb cisco-core.o" ;; - demo_64_vec) tb="$tb demo64.o aout64.o" - target64=true ;; - ecoff_big_vec) tb="$tb coff-mips.o ecoff.o ecofflink.o" ;; - ecoff_little_vec) tb="$tb coff-mips.o ecoff.o ecofflink.o" ;; - ecoffalpha_little_vec) tb="$tb coff-alpha.o ecoff.o ecofflink.o" - target64=true ;; - h8300coff_vec) tb="$tb coff-h8300.o reloc16.o" ;; - h8500coff_vec) tb="$tb coff-h8500.o reloc16.o" ;; - host_aout_vec) tb="$tb host-aout.o aout32.o" ;; - hp300bsd_vec) tb="$tb hp300bsd.o aout32.o" ;; - hp300hpux_vec) tb="$tb hp300hpux.o aout32.o" ;; - i386aout_vec) tb="$tb i386aout.o aout32.o" ;; - i386bsd_vec) tb="$tb i386bsd.o aout32.o" ;; - i386coff_vec) tb="$tb coff-i386.o cofflink.o" ;; - i386dynix_vec) tb="$tb i386dynix.o aout32.o" ;; - i386freebsd_vec) tb="$tb i386freebsd.o aout32.o" ;; - i386msdos_vec) tb="$tb i386msdos.o" ;; - i386pe_vec) tb="$tb pe-i386.o cofflink.o " ;; - i386pei_vec) tb="$tb pei-i386.o cofflink.o" ;; - i386linux_vec) tb="$tb i386linux.o aout32.o" ;; - i386lynx_aout_vec) tb="$tb i386lynx.o lynx-core.o aout32.o" ;; - i386lynx_coff_vec) tb="$tb cf-i386lynx.o cofflink.o lynx-core.o" ;; - i386mach3_vec) tb="$tb i386mach3.o aout32.o" ;; - i386netbsd_vec) tb="$tb i386netbsd.o aout32.o" ;; - i386os9k_vec) tb="$tb i386os9k.o aout32.o" ;; - i860coff_vec) tb="$tb coff-i860.o cofflink.o" ;; - icoff_big_vec) tb="$tb coff-i960.o cofflink.o" ;; - icoff_little_vec) tb="$tb coff-i960.o cofflink.o" ;; - ieee_vec) tb="$tb ieee.o" ;; - m68kcoff_vec) tb="$tb coff-m68k.o cofflink.o" ;; - m68kcoffun_vec) tb="$tb coff-u68k.o coff-m68k.o cofflink.o" ;; - m68klinux_vec) tb="$tb m68klinux.o aout32.o" ;; - m68klynx_aout_vec) tb="$tb m68klynx.o lynx-core.o aout32.o" ;; - m68klynx_coff_vec) tb="$tb cf-m68klynx.o coff-m68k.o cofflink.o lynx-core.o" ;; - m68knetbsd_vec) tb="$tb m68knetbsd.o aout32.o" ;; - m68k4knetbsd_vec) tb="$tb m68k4knetbsd.o aout32.o" ;; - m68kaux_coff_vec) tb="$tb coff-aux.o coff-m68k.o cofflink.o" ;; - m88kbcs_vec) tb="$tb coff-m88k.o" ;; - newsos3_vec) tb="$tb newsos3.o aout32.o" ;; - nlm32_i386_vec) tb="$tb nlm32-i386.o nlm32.o nlm.o" ;; - nlm32_sparc_vec) tb="$tb nlm32-sparc.o nlm32.o nlm.o" ;; - nlm32_alpha_vec) tb="$tb nlm32-alpha.o nlm32.o nlm.o" - target64=true ;; - riscix_vec) tb="$tb aout32.o riscix.o" ;; - nlm32_powerpc_vec) tb="$tb nlm32-ppc.o nlm32.o nlm.o" ;; - pc532netbsd_vec) tb="$tb ns32knetbsd.o aout-ns32k.o" ;; - pc532machaout_vec) tb="$tb pc532-mach.o aout-ns32k.o" ;; - pmac_xcoff_vec) tb="$tb coff-pmac.o xcofflink.o" ;; - rs6000coff_vec) tb="$tb coff-rs6000.o xcofflink.o" ;; - bfd_powerpc_pe_vec) tb="$tb pe-ppc.o cofflink.o" ;; - bfd_powerpcle_pe_vec) tb="$tb pe-ppc.o cofflink.o" ;; - bfd_powerpc_pei_vec) tb="$tb pei-ppc.o cofflink.o" ;; - bfd_powerpcle_pei_vec) tb="$tb pei-ppc.o cofflink.o" ;; - shcoff_vec) tb="$tb coff-sh.o cofflink.o" ;; - shlcoff_vec) tb="$tb coff-sh.o cofflink.o" ;; - som_vec) tb="$tb som.o" ;; - sparclynx_aout_vec) tb="$tb sparclynx.o lynx-core.o aout32.o" ;; - sparclynx_coff_vec) tb="$tb cf-sparclynx.o lynx-core.o" ;; - sparcnetbsd_vec) tb="$tb sparcnetbsd.o aout32.o" ;; - sparccoff_vec) tb="$tb coff-sparc.o" ;; - srec_vec) tb="$tb srec.o" ;; - sunos_big_vec) tb="$tb sunos.o aout32.o" ;; - symbolsrec_vec) tb="$tb srec.o" ;; - tekhex_vec) tb="$tb tekhex.o" ;; - we32kcoff_vec) tb="$tb coff-we32k.o" ;; - z8kcoff_vec) tb="$tb coff-z8k.o reloc16.o" ;; - w65_vec) tb="$tb coff-w65.o reloc16.o" ;; - versados_vec) tb="$tb versados.o" ;; - - "") ;; - *) AC_MSG_ERROR(*** unknown target vector $vec) ;; - esac -done - -# Target architecture .o files. -ta=`echo $selarchs | sed -e s/bfd_/cpu-/g -e s/_arch/.o/g` - -# Weed out duplicate .o files. -f="" -for i in $tb ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -tb="$f" - -f="" -for i in $ta ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac -done -ta="$f" - -bfd_backends="$tb" -bfd_machines="$ta" - -if test x${all_targets} = xtrue ; then - bfd_backends="${bfd_backends}"' $(ALL_BACKENDS)' - bfd_machines="${bfd_machines}"' $(ALL_MACHINES)' - selvecs= - selarchs= -else # all_targets is true - # Only set these if they will be nonempty, for the clever echo. - test -n "$selvecs" && - selvecs=`echo $selvecs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'` - test -n "$selarchs" && - selarchs=`echo $selarchs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'` -fi # all_targets is true - -case ${host64}-${target64}-${want64} in - *true*) - wordsize=64 - all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)' - ;; - false-false-false) - wordsize=32 - all_backends='$(BFD32_BACKENDS)' - ;; -esac - -AC_SUBST(wordsize) -AC_SUBST(all_backends) -AC_SUBST(bfd_backends) -AC_SUBST(bfd_machines) - -tdefaults="" -test -n "${defvec}" && tdefaults="${tdefaults} -DDEFAULT_VECTOR=${defvec}" -test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'" -test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'" -AC_SUBST(tdefaults) - -dnl AC_CHECK_HEADERS(sys/mman.h) -AC_FUNC_MMAP -AC_CHECK_FUNCS(madvise mprotect) -case ${want_mmap}+${ac_cv_func_mmap} in - true+yes ) AC_DEFINE(USE_MMAP) ;; -esac - -rm -f doc/config.status -AC_OUTPUT(Makefile doc/Makefile, -[case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac]) diff --git a/contrib/gdb/bfd/corefile.c b/contrib/gdb/bfd/corefile.c deleted file mode 100644 index 212f519ce8a..00000000000 --- a/contrib/gdb/bfd/corefile.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Core file generic interface routines for BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - Core files - -DESCRIPTION - These are functions pertaining to core files. -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -/* -FUNCTION - bfd_core_file_failing_command - -SYNOPSIS - CONST char *bfd_core_file_failing_command(bfd *abfd); - -DESCRIPTION - Return a read-only string explaining which program was running - when it failed and produced the core file @var{abfd}. - -*/ - -CONST char * -bfd_core_file_failing_command (abfd) - bfd *abfd; -{ - if (abfd->format != bfd_core) { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - return BFD_SEND (abfd, _core_file_failing_command, (abfd)); -} - -/* -FUNCTION - bfd_core_file_failing_signal - -SYNOPSIS - int bfd_core_file_failing_signal(bfd *abfd); - -DESCRIPTION - Returns the signal number which caused the core dump which - generated the file the BFD @var{abfd} is attached to. -*/ - -int -bfd_core_file_failing_signal (abfd) - bfd *abfd; -{ - if (abfd->format != bfd_core) { - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - return BFD_SEND (abfd, _core_file_failing_signal, (abfd)); -} - - -/* -FUNCTION - core_file_matches_executable_p - -SYNOPSIS - boolean core_file_matches_executable_p - (bfd *core_bfd, bfd *exec_bfd); - -DESCRIPTION - Return <> if the core file attached to @var{core_bfd} - was generated by a run of the executable file attached to - @var{exec_bfd}, <> 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_set_error (bfd_error_wrong_format); - return false; - } - - return BFD_SEND (core_bfd, _core_file_matches_executable_p, - (core_bfd, exec_bfd)); -} diff --git a/contrib/gdb/bfd/cpu-a29k.c b/contrib/gdb/bfd/cpu-a29k.c deleted file mode 100644 index 5bd25a47720..00000000000 --- a/contrib/gdb/bfd/cpu-a29k.c +++ /dev/null @@ -1,39 +0,0 @@ -/* BFD support for the AMD 29000 architecture. - Copyright 1992 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_a29k_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_a29k, - 0, /* only 1 machine */ - "a29k", - "a29k", - 4, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-alpha.c b/contrib/gdb/bfd/cpu-alpha.c deleted file mode 100644 index 0d66a8b74e8..00000000000 --- a/contrib/gdb/bfd/cpu-alpha.c +++ /dev/null @@ -1,38 +0,0 @@ -/* BFD support for the Alpha architecture. - Copyright 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_alpha_arch = - { - 64, /* 32 bits in a word */ - 64, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_alpha, - 0, /* only 1 machine */ - "alpha", - "alpha", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-arm.c b/contrib/gdb/bfd/cpu-arm.c deleted file mode 100644 index 92103e632f0..00000000000 --- a/contrib/gdb/bfd/cpu-arm.c +++ /dev/null @@ -1,39 +0,0 @@ -/* BFD support for the ARM processor - Copyright 1994 Free Software Foundation, Inc. - Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_arm_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_arm, - 0, /* only 1 machine */ - "arm", - "arm", - 4, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-h8300.c b/contrib/gdb/bfd/cpu-h8300.c deleted file mode 100644 index 380dfb5556e..00000000000 --- a/contrib/gdb/bfd/cpu-h8300.c +++ /dev/null @@ -1,246 +0,0 @@ -/* BFD library support routines for the Hitachi H8/300 architecture. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if 0 /* not used currently */ -/* -Relocations for the H8 - -*/ -static bfd_reloc_status_type -howto16_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_16 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static reloc_howto_type howto_16 -= NEWHOWTO (howto16_callback, "abs16", 1, false, false); -static reloc_howto_type howto_8 -= NEWHOWTO (howto8_callback, "abs8", 0, false, false); - -static reloc_howto_type howto_8_FFnn -= NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, false, false); - -static reloc_howto_type howto_8_pcrel -= NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, false, true); - -static reloc_howto_type * -local_bfd_reloc_type_lookup (arch, code) - const struct bfd_arch_info *arch; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_16: - return &howto_16; - case BFD_RELOC_8_FFnn: - return &howto_8_FFnn; - case BFD_RELOC_8: - return &howto_8; - case BFD_RELOC_8_PCREL: - return &howto_8_pcrel; - default: - return (reloc_howto_type *) NULL; - } - } -#endif - -int bfd_default_scan_num_mach (); - -static boolean -h8300_scan (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (*string != 'h' && *string != 'H') - return false; - - string++; - if (*string != '8') - return false; - - string++; - if (*string == '/') - string++; - - if (*string != '3') - return false; - string++; - if (*string != '0') - return false; - string++; - if (*string != '0') - return false; - string++; - if (*string == '-') - string++; - if (*string == 'h' || *string == 'H') - { - return (info->mach == bfd_mach_h8300h); - } - else - { - return info->mach == bfd_mach_h8300; - } -} - - -/* This routine is provided two arch_infos and works out the - machine which would be compatible with both and returns a pointer - to its info structure */ - -static const bfd_arch_info_type * -compatible (in, out) - const bfd_arch_info_type * in; - const bfd_arch_info_type * out; -{ - /* If the output is non-H and the input is -H, that's bad */ - if (in->mach == bfd_mach_h8300h && - out->mach == bfd_mach_h8300) - return 0; - - /* If either is an -H, the answer is -H */ - if (in->mach == bfd_mach_h8300h) - return in; - return out; -} - -static const bfd_arch_info_type h8300_info_struct = -{ - 16, /* 16 bits in a word */ - 16, /* 16 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_h8300, - bfd_mach_h8300, - "h8300", /* arch_name */ - "h8300", /* printable name */ - 1, - true, /* the default machine */ - compatible, - h8300_scan, -/* local_bfd_reloc_type_lookup, */ - 0, -}; - - -const bfd_arch_info_type bfd_h8300_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_h8300, - bfd_mach_h8300h, - "h8300h", /* arch_name */ - "h8300h", /* printable name */ - 1, - false, /* the default machine */ - compatible, - h8300_scan, -/* local_bfd_reloc_type_lookup, */ - &h8300_info_struct, -}; diff --git a/contrib/gdb/bfd/cpu-h8500.c b/contrib/gdb/bfd/cpu-h8500.c deleted file mode 100644 index e4abfd17807..00000000000 --- a/contrib/gdb/bfd/cpu-h8500.c +++ /dev/null @@ -1,199 +0,0 @@ -/* BFD library support routines for the H8/500 architecture. - Copyright (C) 1993 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if 0 - -/* -Relocations for the Z8K - -*/ -static bfd_reloc_status_type -howto16_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_16(abfd, (bfd_byte *)data + addr); - - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_16(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8(abfd, (bfd_byte *)data + addr); - - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - - long x = bfd_get_8(abfd, (bfd_byte *)data + addr); - abort(); - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8(abfd, (bfd_byte *)data + addr); - abort(); - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - - - -static reloc_howto_type howto_16 - = NEWHOWTO(howto16_callback,"abs16",1,false,false); -static reloc_howto_type howto_8 - = NEWHOWTO(howto8_callback,"abs8",0,false,false); - -static reloc_howto_type howto_8_FFnn - = NEWHOWTO(howto8_FFnn_callback,"ff00+abs8",0,false,false); - -static reloc_howto_type howto_8_pcrel - = NEWHOWTO(howto8_pcrel_callback,"pcrel8",0,false,true); - - -static reloc_howto_type * -local_bfd_reloc_type_lookup (arch, code) - const struct bfd_arch_info *arch; - bfd_reloc_code_real_type code; -{ - switch (code) { - case BFD_RELOC_16: - return &howto_16; - case BFD_RELOC_8_FFnn: - return &howto_8_FFnn; - case BFD_RELOC_8: - return &howto_8; - case BFD_RELOC_8_PCREL: - return &howto_8_pcrel; - } - return (reloc_howto_type *)NULL; -} -#endif - -int bfd_default_scan_num_mach(); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp(string,"h8/500") == 0) return true; - if (strcmp(string,"H8/500") == 0) return true; - if (strcmp(string,"h8500") == 0) return true; - if (strcmp(string,"H8500") == 0) return true; - return false; -} - - -#if 0 /* not used currently */ -/* This routine is provided two arch_infos and returns whether - they'd be compatible */ - -static const bfd_arch_info_type * -compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->arch != b->arch || a->mach != b->mach) - return NULL; - return a; -} -#endif - -const bfd_arch_info_type bfd_h8500_arch = -{ - 16, /* 16 bits in a word */ - 24, /* 24 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_h8500, - 0, /* only 1 machine */ - "h8500", /* arch_name */ - "h8500", /* printable name */ - 1, - true, /* the default machine */ - bfd_default_compatible, - scan_mach, - 0, -}; diff --git a/contrib/gdb/bfd/cpu-hppa.c b/contrib/gdb/bfd/cpu-hppa.c deleted file mode 100644 index 5201008dfe1..00000000000 --- a/contrib/gdb/bfd/cpu-hppa.c +++ /dev/null @@ -1,54 +0,0 @@ -/* BFD support for the HP Precision Architecture architecture. - Copyright 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static const bfd_arch_info_type bfd_hppa10_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_hppa, - 10, /* By convention PA1.0 = 10 */ - "hppa", - "hppa1.0", - 3, - true, /* Unless we use 1.1 specific features */ - bfd_default_compatible, - bfd_default_scan , - 0, -}; - -const bfd_arch_info_type bfd_hppa_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_hppa, - 11, /* By convention PA1.1 = 11 */ - "hppa", - "hppa1.1", - 3, - false, /* 1.1 specific features used */ - bfd_default_compatible, - bfd_default_scan , - &bfd_hppa10_arch, -}; diff --git a/contrib/gdb/bfd/cpu-i386.c b/contrib/gdb/bfd/cpu-i386.c deleted file mode 100644 index 404109033b7..00000000000 --- a/contrib/gdb/bfd/cpu-i386.c +++ /dev/null @@ -1,38 +0,0 @@ -/* BFD support for the Intel 386 architecture. - Copyright 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_i386_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - 0, /* only 1 machine */ - "i386", - "i386", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-i860.c b/contrib/gdb/bfd/cpu-i860.c deleted file mode 100644 index 57c867cdb2c..00000000000 --- a/contrib/gdb/bfd/cpu-i860.c +++ /dev/null @@ -1,40 +0,0 @@ -/* BFD support for the Intel 860 architecture. - Copyright 1992, 1995 Free Software Foundation, Inc. - Created mostly by substituting "860" for "386" in cpu-i386.c - Harry Dolan , October 1995 - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_i860_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i860, - 0, /* only 1 machine */ - "i860", - "i860", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-i960.c b/contrib/gdb/bfd/cpu-i960.c deleted file mode 100644 index 6970f89fca5..00000000000 --- a/contrib/gdb/bfd/cpu-i960.c +++ /dev/null @@ -1,162 +0,0 @@ -/* BFD library support routines for the i960 architecture. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -/* This routine is provided a string, and tries to work out if it - could possibly refer to the i960 machine pointed at in the - info_struct pointer */ - -static boolean -scan_960_mach (ap, string) - const bfd_arch_info_type *ap; - const char *string; -{ - unsigned long machine; - - /* Look for the string i960, or somesuch at the front of the string */ - - if (strncmp("i960",string,4) == 0) { - string+=4; - } - else { - /* no match, can be us */ - return false; - } - if (string[0] == 0) { - /* i960 on it's own means core to us*/ - if (ap->mach == bfd_mach_i960_core) return true; - return false; - } - - if (string[0] != ':') { - return false; - } - string++; - if (string[0] == '\0') - return false; - if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' && - string[3] == 'e' && string[4] == '\0') - machine = bfd_mach_i960_core; - else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char */ - return false; - else if (string[0] == 'k' && string[1] == 'b') - machine = bfd_mach_i960_kb_sb; - else if (string[0] == 's' && string[1] == 'b') - machine = bfd_mach_i960_kb_sb; - else if (string[0] == 'm' && string[1] == 'c') - machine = bfd_mach_i960_mc; - else if (string[0] == 'x' && string[1] == 'a') - machine = bfd_mach_i960_xa; - else if (string[0] == 'c' && string[1] == 'a') - machine = bfd_mach_i960_ca; - else if (string[0] == 'k' && string[1] == 'a') - machine = bfd_mach_i960_ka_sa; - else if (string[0] == 's' && string[1] == 'a') - machine = bfd_mach_i960_ka_sa; - else if (string[0] == 'j' && string[1] == 'x') - machine = bfd_mach_i960_jx; - else if (string[0] == 'h' && string[1] == 'x') - machine = bfd_mach_i960_hx; - else - return false; - if (machine == ap->mach) return true; - return false; -} - - - -/* This routine is provided two arch_infos and works out the i960 - machine which would be compatible with both and returns a pointer - to its info structure */ - -static const bfd_arch_info_type * -compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - - /* The i960 has distinct subspecies which may not interbreed: - CORE CA - CORE KA KB MC XA - CORE HX JX - Any architecture on the same line is compatible, the one on - the right is the least restrictive. - - We represent this information in an array, each machine to a side */ - -#define ERROR 0 -#define CORE bfd_mach_i960_core /*1*/ -#define KA bfd_mach_i960_ka_sa /*2*/ -#define KB bfd_mach_i960_kb_sb /*3*/ -#define MC bfd_mach_i960_mc /*4*/ -#define XA bfd_mach_i960_xa /*5*/ -#define CA bfd_mach_i960_ca /*6*/ -#define JX bfd_mach_i960_jx /*7*/ -#define HX bfd_mach_i960_hx /*8*/ -#define MAX_ARCH ((int)HX) - - static CONST unsigned long matrix[MAX_ARCH+1][MAX_ARCH+1] = - { - { ERROR, CORE, KA, KB, MC, XA, CA, JX, HX }, - { CORE, CORE, KA, KB, MC, XA, CA, JX, HX }, - { KA, KA, KA, KB, MC, XA, ERROR, ERROR, ERROR}, - { KB, KB, KB, KB, MC, XA, ERROR, ERROR, ERROR}, - { MC, MC, MC, MC, MC, XA, ERROR, ERROR, ERROR}, - { XA, XA, XA, XA, XA, XA, ERROR, ERROR, ERROR}, - { CA, CA, ERROR, ERROR, ERROR, ERROR, CA, ERROR, ERROR}, - { JX, JX, ERROR, ERROR, ERROR, ERROR, ERROR, JX, HX }, - { HX, HX, ERROR, ERROR, ERROR, ERROR, ERROR, HX, HX }, - }; - - - if (a->arch != b->arch || matrix[a->mach][b->mach] == ERROR) - { - return NULL; - } - else - { - return (a->mach == matrix[a->mach][b->mach]) ? a : b; - } -} - - - -int bfd_default_scan_num_mach(); -#define N(a,b,d,n) \ -{ 32, 32, 8,bfd_arch_i960,a,"i960",b,3,d,compatible,scan_960_mach,n,} - -static const bfd_arch_info_type arch_info_struct[] = -{ - N(bfd_mach_i960_ka_sa,"i960:ka_sa",false, &arch_info_struct[1]), - N(bfd_mach_i960_kb_sb,"i960:kb_sb",false, &arch_info_struct[2]), - N(bfd_mach_i960_mc, "i960:mc", false, &arch_info_struct[3]), - N(bfd_mach_i960_xa, "i960:xa", false, &arch_info_struct[4]), - N(bfd_mach_i960_ca, "i960:ca", false, &arch_info_struct[5]), - N(bfd_mach_i960_jx, "i960:jx", false, &arch_info_struct[6]), - N(bfd_mach_i960_hx, "i960:hx", false, 0), -}; - -const bfd_arch_info_type bfd_i960_arch = - N(bfd_mach_i960_core, "i960:core", true, &arch_info_struct[0]); diff --git a/contrib/gdb/bfd/cpu-m68k.c b/contrib/gdb/bfd/cpu-m68k.c deleted file mode 100644 index 17a37391675..00000000000 --- a/contrib/gdb/bfd/cpu-m68k.c +++ /dev/null @@ -1,42 +0,0 @@ -/* BFD library support routines for architectures. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -int bfd_default_scan_num_mach(); - - -#define N(name, print,d,next) \ -{ 32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_default_compatible,bfd_default_scan, next, } - -static const bfd_arch_info_type arch_info_struct[] = -{ - N(68008,"m68k:68008",false, &arch_info_struct[1]), - N(68010,"m68k:68010",false, &arch_info_struct[2]), - N(68020,"m68k:68020",true, &arch_info_struct[3]), - N(68030,"m68k:68030",false, &arch_info_struct[4]), - N(68040,"m68k:68040",false, &arch_info_struct[5]), - N(68070,"m68k:68070",false, 0), -}; - -const bfd_arch_info_type bfd_m68k_arch = - N(68000,"m68k:68000",false, &arch_info_struct[0]); diff --git a/contrib/gdb/bfd/cpu-m88k.c b/contrib/gdb/bfd/cpu-m88k.c deleted file mode 100644 index c3716c5a394..00000000000 --- a/contrib/gdb/bfd/cpu-m88k.c +++ /dev/null @@ -1,42 +0,0 @@ -/* bfd back-end for m88k support - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - - - -const bfd_arch_info_type bfd_m88k_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_m88k, - 88100, /* only 1 machine */ - "m88k", - "m88k:88100", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-mips.c b/contrib/gdb/bfd/cpu-mips.c deleted file mode 100644 index 5e1934210a2..00000000000 --- a/contrib/gdb/bfd/cpu-mips.c +++ /dev/null @@ -1,85 +0,0 @@ -/* bfd back-end for mips support - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static const bfd_arch_info_type arch_info_struct[] = -{ - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 6000, - "mips", - "mips:6000", - 3, - false, - bfd_default_compatible, - bfd_default_scan, - &arch_info_struct[1], - }, - { - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 4000, - "mips", - "mips:4000", - 3, - false, - bfd_default_compatible, - bfd_default_scan , - &arch_info_struct[2], - }, - { - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 8000, - "mips", - "mips:8000", - 3, - false, - bfd_default_compatible, - bfd_default_scan , - 0, - } -}; - -const bfd_arch_info_type bfd_mips_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 3000, - "mips", - "mips:3000", - 3, - true, - bfd_default_compatible, - bfd_default_scan, - &arch_info_struct[0], -}; diff --git a/contrib/gdb/bfd/cpu-ns32k.c b/contrib/gdb/bfd/cpu-ns32k.c deleted file mode 100644 index e18e3cfc9ba..00000000000 --- a/contrib/gdb/bfd/cpu-ns32k.c +++ /dev/null @@ -1,868 +0,0 @@ -/* BFD support for the ns32k architecture. - Copyright (C) 1990, 1991, 1994, 1995 Free Software Foundation, Inc. - Almost totally rewritten by Ian Dall from initial work - by Andrew Cagney. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -long ns32k_get_displacement PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_displacement PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -long ns32k_get_immediate PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_immediate PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -bfd_reloc_status_type - ns32k_reloc_disp PARAMS ((bfd *abfd, arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type - ns32k_reloc_imm PARAMS ((bfd *abfd, - arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type ns32k_final_link_relocate PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - bfd_vma address, - bfd_vma value, - bfd_vma addend )); -bfd_reloc_status_type ns32k_relocate_contents PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - bfd_vma relocation, - bfd_byte *location)); - -int bfd_default_scan_num_mach(); - -#define N(machine, printable, d, next) \ -{ 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, } - -static const bfd_arch_info_type arch_info_struct[] = -{ - N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */ -}; - -const bfd_arch_info_type bfd_ns32k_arch = - N(32032,"ns32k:32032",false, &arch_info_struct[0]); - -static long -ns32k_sign_extend(value, bits) - int value; - int bits; -{ - value = value & ((1 << bits) - 1); - return (value & (1 << (bits-1)) - ? value | (~((1 << bits) - 1)) - : value); -} - -long -ns32k_get_displacement(buffer, offset, size) - bfd_byte *buffer; - long offset; - long size; -{ - long value; - buffer += offset; - switch (size) - { - case 1: - value = ns32k_sign_extend (*buffer, 7); - break; - case 2: - value = ns32k_sign_extend(*buffer++, 6); - value = (value << 8) | (0xff & *buffer); - break; - case 4: - value = ns32k_sign_extend(*buffer++, 6); - value = (value << 8) | (0xff & *buffer++); - value = (value << 8) | (0xff & *buffer++); - value = (value << 8) | (0xff & *buffer); - break; - } - return value; -} - -int -ns32k_put_displacement(value, buffer, offset, size) - long value; - bfd_byte *buffer; - long offset; - long size; -{ - buffer += offset; - switch (size) - { - case 1: - if (value < -64 || value > 63) - return -1; - value&=0x7f; - *buffer++=value; - break; - case 2: - if (value < -8192 || value > 8191) - return -1; - value&=0x3fff; - value|=0x8000; - *buffer++=(value>>8); - *buffer++=value; - break; - case 4: - if (value < -0x1f000000 || value >= 0x20000000) - return -1; - value|=0xc0000000; - *buffer++=(value>>24); - *buffer++=(value>>16); - *buffer++=(value>>8); - *buffer++=value; - break; - default: - return -1; - } - return 0; -} - -long -ns32k_get_immediate(buffer, offset, size) - bfd_byte *buffer; - long offset; - long size; -{ - long value = 0; - buffer += offset; - switch (size) - { - case 4: - value = (value << 8) | (*buffer++ & 0xff); - case 3: - value = (value << 8) | (*buffer++ & 0xff); - case 2: - value = (value << 8) | (*buffer++ & 0xff); - case 1: - value = (value << 8) | (*buffer++ & 0xff); - } - return value; -} - -int -ns32k_put_immediate (value, buffer, offset, size) - long value; - bfd_byte *buffer; - long offset; - long size; -{ - buffer += offset + size - 1; - switch (size) - { - case 4: - *buffer-- = (value & 0xff); value >>= 8; - case 3: - *buffer-- = (value & 0xff); value >>= 8; - case 2: - *buffer-- = (value & 0xff); value >>= 8; - case 1: - *buffer-- = (value & 0xff); value >>= 8; - } - return 0; -} - -/* This is just like the standard perform_relocation except we - * use get_data and put_data which know about the ns32k - * storage methods. - * This is probably a lot more complicated than it needs to be! - */ -static bfd_reloc_status_type -do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message, get_data, put_data) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; - long (*get_data)(); - int (*put_data)(); -{ - int overflow = 0; - bfd_vma relocation; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type addr = reloc_entry->address; - bfd_vma output_base = 0; - reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - - if ((symbol->section == &bfd_abs_section) - && output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If we are not producing relocateable output, return an error if - the symbol is not defined. An undefined weak symbol is - considered to have a value of zero (SVR4 ABI, p. 4-27). */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == (bfd *) NULL) - flag = bfd_reloc_undefined; - - - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Work out which section the relocation is targetted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (output_bfd && howto->partial_inplace == false) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += reloc_entry->addend; - - /* Here the variable relocation holds the final address of the - symbol we are relocating against, plus any addend. */ - - if (howto->pc_relative == true) - { - /* This is a PC relative relocation. We want to set RELOCATION - to the distance between the address of the symbol and the - location. RELOCATION is already the address of the symbol. - - We start by subtracting the address of the section containing - the location. - - If pcrel_offset is set, we must further subtract the position - of the location within the section. Some targets arrange for - the addend to be the negative of the position of the location - within the section; for example, i386-aout does this. For - i386-aout, pcrel_offset is false. Some other targets do not - include the position of the location; for example, m88kbcs, - or ELF. For those targets, pcrel_offset is true. - - If we are producing relocateable output, then we must ensure - that this reloc will be correctly computed when the final - relocation is done. If pcrel_offset is false we want to wind - up with the negative of the location within the section, - which means we must adjust the existing addend by the change - in the location within the section. If pcrel_offset is true - we do not want to adjust the existing addend at all. - - FIXME: This seems logical to me, but for the case of - producing relocateable output it is not what the code - actually does. I don't want to change it, because it seems - far too likely that something will break. */ - - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset == true) - relocation -= reloc_entry->address; - } - - if (output_bfd != (bfd *) NULL) - { - if (howto->partial_inplace == false) - { - /* This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. */ - reloc_entry->addend = relocation; - reloc_entry->address += input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol. */ - - reloc_entry->address += input_section->output_offset; - - /* WTF?? */ - if (abfd->xvec->flavour == bfd_target_coff_flavour - && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0) - { -#if 1 - /* For m68k-coff, the addend was being subtracted twice during - relocation with -r. Removing the line below this comment - fixes that problem; see PR 2953. - -However, Ian wrote the following, regarding removing the line below, -which explains why it is still enabled: --djm - -If you put a patch like that into BFD you need to check all the COFF -linkers. I am fairly certain that patch will break coff-i386 (e.g., -SCO); see coff_i386_reloc in coff-i386.c where I worked around the -problem in a different way. There may very well be a reason that the -code works as it does. - -Hmmm. The first obvious point is that bfd_perform_relocation should -not have any tests that depend upon the flavour. It's seem like -entirely the wrong place for such a thing. The second obvious point -is that the current code ignores the reloc addend when producing -relocateable output for COFF. That's peculiar. In fact, I really -have no idea what the point of the line you want to remove is. - -A typical COFF reloc subtracts the old value of the symbol and adds in -the new value to the location in the object file (if it's a pc -relative reloc it adds the difference between the symbol value and the -location). When relocating we need to preserve that property. - -BFD handles this by setting the addend to the negative of the old -value of the symbol. Unfortunately it handles common symbols in a -non-standard way (it doesn't subtract the old value) but that's a -different story (we can't change it without losing backward -compatibility with old object files) (coff-i386 does subtract the old -value, to be compatible with existing coff-i386 targets, like SCO). - -So everything works fine when not producing relocateable output. When -we are producing relocateable output, logically we should do exactly -what we do when not producing relocateable output. Therefore, your -patch is correct. In fact, it should probably always just set -reloc_entry->addend to 0 for all cases, since it is, in fact, going to -add the value into the object file. This won't hurt the COFF code, -which doesn't use the addend; I'm not sure what it will do to other -formats (the thing to check for would be whether any formats both use -the addend and set partial_inplace). - -When I wanted to make coff-i386 produce relocateable output, I ran -into the problem that you are running into: I wanted to remove that -line. Rather than risk it, I made the coff-i386 relocs use a special -function; it's coff_i386_reloc in coff-i386.c. The function -specifically adds the addend field into the object file, knowing that -bfd_perform_relocation is not going to. If you remove that line, then -coff-i386.c will wind up adding the addend field in twice. It's -trivial to fix; it just needs to be done. - -The problem with removing the line is just that it may break some -working code. With BFD it's hard to be sure of anything. The right -way to deal with this is simply to build and test at least all the -supported COFF targets. It should be straightforward if time and disk -space consuming. For each target: - 1) build the linker - 2) generate some executable, and link it using -r (I would - probably use paranoia.o and link against newlib/libc.a, which - for all the supported targets would be available in - /usr/cygnus/progressive/H-host/target/lib/libc.a). - 3) make the change to reloc.c - 4) rebuild the linker - 5) repeat step 2 - 6) if the resulting object files are the same, you have at least - made it no worse - 7) if they are different you have to figure out which version is - right -*/ - relocation -= reloc_entry->addend; -#endif - reloc_entry->addend = 0; - } - else - { - reloc_entry->addend = relocation; - } - } - } - else - { - reloc_entry->addend = 0; - } - - /* FIXME: This overflow checking is incomplete, because the value - might have overflowed before we get here. For a correct check we - need to compute the value in a size larger than bitsize, but we - can't reasonably do that for a reloc the same size as a host - machine word. - FIXME: We should also do overflow checking on the result after - adding in the value contained in the object file. */ - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - - /* Get the value that will be used for the relocation, but - starting at bit position zero. */ - if (howto->rightshift > howto->bitpos) - check = relocation >> (howto->rightshift - howto->bitpos); - else - check = relocation << (howto->bitpos - howto->rightshift); - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - /* The above right shift is incorrect for a signed value. - Fix it up by forcing on the upper bits. */ - if (howto->rightshift > howto->bitpos - && (bfd_signed_vma) relocation < 0) - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> (howto->rightshift - howto->bitpos))); - if ((bfd_signed_vma) check > reloc_signed_max - || (bfd_signed_vma) check < reloc_signed_min) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((bfd_vma) check > reloc_unsigned_max) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - { - /* The above right shift is incorrect for a signed - value. See if turning on the upper bits fixes the - overflow. */ - if (howto->rightshift > howto->bitpos - && (bfd_signed_vma) relocation < 0) - { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> (howto->rightshift - howto->bitpos))); - if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - flag = bfd_reloc_overflow; - } - else - flag = bfd_reloc_overflow; - } - } - break; - default: - abort (); - } - } - - /* - Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs) - */ - - /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler - (OSF version 1.3, compiler version 3.11). It miscompiles the - following program: - - struct str - { - unsigned int i0; - } s = { 0 }; - - int - main () - { - unsigned long x; - - x = 0x100000000; - x <<= (unsigned long) s.i0; - if (x == 0) - printf ("failed\n"); - else - printf ("succeeded (%lx)\n", x); - } - */ - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= (bfd_vma) howto->bitpos; - - /* Wait for the day when all have the mask in them */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - i i i i i o o o o o from bfd_get - and S S S S S to get the size offset we want - + r r r r r r r r r r to get the final value to place - and D D D D D to chop to right size - ----------------------- - A A A A A - And this: - ... i i i i i o o o o o from bfd_get - and N N N N N get instruction - ----------------------- - ... B B B B B - - And then: - B B B B B - or A A A A A - ----------------------- - R R R R R R R R R R put into bfd_put - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - switch (howto->size) - { - case 0: - { - char x = get_data (data, addr, 1); - DOIT (x); - overflow = put_data(x, data, addr, 1); - } - break; - - case 1: - if (relocation) - { - short x = get_data (data, addr, 2); - DOIT (x); - overflow = put_data(x, (unsigned char *) data, addr, 2); - } - break; - case 2: - if (relocation) - { - long x = get_data (data, addr, 4); - DOIT (x); - overflow = put_data(x, data, addr, 4); - } - break; - case -2: - { - long x = get_data(data, addr, 4); - relocation = -relocation; - DOIT(x); - overflow = put_data(x, data , addr, 4); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: -#ifdef BFD64 - if (relocation) - { - bfd_vma x = get_data (data, addr, 8); - DOIT (x); - overflow = put_data(x, data, addr, 8); - } -#else - abort (); -#endif - break; - default: - return bfd_reloc_other; - } - if ((howto->complain_on_overflow != complain_overflow_dont) && overflow) - return bfd_reloc_overflow; - - return flag; -} - -/* Relocate a given location using a given value and howto. */ - -bfd_reloc_status_type -do_ns32k_reloc_contents ( howto, input_bfd, relocation, location, get_data, - put_data) - reloc_howto_type *howto; - bfd *input_bfd; - bfd_vma relocation; - bfd_byte *location; - long (*get_data)(); - int (*put_data)(); -{ - int size; - bfd_vma x; - boolean overflow; - - /* If the size is negative, negate RELOCATION. This isn't very - general. */ - if (howto->size < 0) - relocation = -relocation; - - /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - case 0: - abort (); - case 1: - case 2: - case 4: -#ifdef BFD64 - case 8: -#endif - x = get_data (location, 0, size); - break; - } - - /* Check for overflow. FIXME: We may drop bits during the addition - which we don't check for. We must either check at every single - operation, which would be tedious, or we must do the computations - in a type larger than bfd_vma, which would be inefficient. */ - overflow = false; - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - bfd_signed_vma signed_check; - bfd_vma add; - bfd_signed_vma signed_add; - - if (howto->rightshift == 0) - { - check = relocation; - signed_check = (bfd_signed_vma) relocation; - } - else - { - /* Drop unwanted bits from the value we are relocating to. */ - check = relocation >> howto->rightshift; - - /* If this is a signed value, the rightshift just dropped - leading 1 bits (assuming twos complement). */ - if ((bfd_signed_vma) relocation >= 0) - signed_check = check; - else - signed_check = (check - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->rightshift))); - } - - /* Get the value from the object file. */ - add = x & howto->src_mask; - - /* Get the value from the object file with an appropriate sign. - The expression involving howto->src_mask isolates the upper - bit of src_mask. If that bit is set in the value we are - adding, it is negative, and we subtract out that number times - two. If src_mask includes the highest possible bit, then we - can not get the upper bit, but that does not matter since - signed_add needs no adjustment to become negative in that - case. */ - signed_add = add; - if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0) - signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1; - - /* Add the value from the object file, shifted so that it is a - straight number. */ - if (howto->bitpos == 0) - { - check += add; - signed_check += signed_add; - } - else - { - check += add >> howto->bitpos; - - /* For the signed case we use ADD, rather than SIGNED_ADD, - to avoid warnings from SVR4 cc. This is OK since we - explictly handle the sign bits. */ - if (signed_add >= 0) - signed_check += add >> howto->bitpos; - else - signed_check += ((add >> howto->bitpos) - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->bitpos))); - } - - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - if (signed_check > reloc_signed_max - || signed_check < reloc_signed_min) - overflow = true; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (check > reloc_unsigned_max) - overflow = true; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((check & ~reloc_bits) != 0 - && (((bfd_vma) signed_check & ~reloc_bits) - != (-1 & ~reloc_bits))) - overflow = true; - } - break; - default: - abort (); - } - } - - /* Put RELOCATION in the right bits. */ - relocation >>= (bfd_vma) howto->rightshift; - relocation <<= (bfd_vma) howto->bitpos; - - /* Add RELOCATION to the right bits of X. */ - x = ((x & ~howto->dst_mask) - | (((x & howto->src_mask) + relocation) & howto->dst_mask)); - - /* Put the relocated value back in the object file. */ - switch (size) - { - default: - case 0: - abort (); - case 1: - case 2: - case 4: -#ifdef BFD64 - case 8: -#endif - put_data(x, location, 0, size); - break; - } - - return overflow ? bfd_reloc_overflow : bfd_reloc_ok; -} - -bfd_reloc_status_type -ns32k_reloc_disp(abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return do_ns32k_reloc(abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message, ns32k_get_displacement, ns32k_put_displacement); -} - -bfd_reloc_status_type -ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return do_ns32k_reloc(abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message, ns32k_get_immediate, ns32k_put_immediate); -} - -bfd_reloc_status_type -ns32k_final_link_relocate (howto, input_bfd, input_section, contents, address, value, addend ) - reloc_howto_type *howto; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - bfd_vma address; - bfd_vma value; - bfd_vma addend; -{ - bfd_vma relocation; - - /* Sanity check the address. */ - if (address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* This function assumes that we are dealing with a basic relocation - against a symbol. We want to compute the value of the symbol to - relocate to. This is just VALUE, the value of the symbol, plus - ADDEND, any addend associated with the reloc. */ - relocation = value + addend; - - /* If the relocation is PC relative, we want to set RELOCATION to - the distance between the symbol (currently in RELOCATION) and the - location we are relocating. Some targets (e.g., i386-aout) - arrange for the contents of the section to be the negative of the - offset of the location within the section; for such targets - pcrel_offset is false. Other targets (e.g., m88kbcs or ELF) - simply leave the contents of the section as zero; for such - targets pcrel_offset is true. If pcrel_offset is false we do not - need to subtract out the offset of the location within the - section (which is just ADDRESS). */ - if (howto->pc_relative) - { - relocation -= (input_section->output_section->vma - + input_section->output_offset); - if (howto->pcrel_offset) - relocation -= address; - } - - return ns32k_relocate_contents (howto, input_bfd, relocation, - contents + address); -} diff --git a/contrib/gdb/bfd/cpu-powerpc.c b/contrib/gdb/bfd/cpu-powerpc.c deleted file mode 100644 index 11f0f80af5a..00000000000 --- a/contrib/gdb/bfd/cpu-powerpc.c +++ /dev/null @@ -1,124 +0,0 @@ -/* BFD PowerPC CPU definition - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. - Contributed by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* The common PowerPC architecture is compatible with the RS/6000. */ - -static const bfd_arch_info_type *powerpc_compatible - PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *)); - -static const bfd_arch_info_type * -powerpc_compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - BFD_ASSERT (a->arch == bfd_arch_powerpc); - switch (b->arch) - { - default: - return NULL; - case bfd_arch_powerpc: - return bfd_default_compatible (a, b); - case bfd_arch_rs6000: - if (a->mach == 0) - return a; - return NULL; - } - /*NOTREACHED*/ -} - -static const bfd_arch_info_type arch_info_struct[] = -{ - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 603, /* for the mpc603 */ - "powerpc", - "powerpc:603", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[1] - }, - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 604, /* for the mpc604 */ - "powerpc", - "powerpc:604", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[2] - }, - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 403, /* for the 403 */ - "powerpc", - "powerpc:403", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[3] - }, - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 601, /* for the mpc601 */ - "powerpc", - "powerpc:601", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - 0 - } -}; - -const bfd_arch_info_type bfd_powerpc_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 0, /* for the POWER/PowerPC common architecture */ - "powerpc", - "powerpc:common", - 3, - true, /* the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[0] - }; diff --git a/contrib/gdb/bfd/cpu-rs6000.c b/contrib/gdb/bfd/cpu-rs6000.c deleted file mode 100644 index 9852ae9a053..00000000000 --- a/contrib/gdb/bfd/cpu-rs6000.c +++ /dev/null @@ -1,70 +0,0 @@ -/* BFD back-end for rs6000 support - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM - and John Gilmore of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* The RS/6000 architecture is compatible with the PowerPC common - architecture. */ - -static const bfd_arch_info_type *rs6000_compatible - PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *)); - -static const bfd_arch_info_type * -rs6000_compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - BFD_ASSERT (a->arch == bfd_arch_rs6000); - switch (b->arch) - { - default: - return NULL; - case bfd_arch_rs6000: - return bfd_default_compatible (a, b); - case bfd_arch_powerpc: - if (b->mach == 0) - return b; - return NULL; - } - /*NOTREACHED*/ -} - -const bfd_arch_info_type bfd_rs6000_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_rs6000, - 6000, /* only 1 machine */ - "rs6000", - "rs6000:6000", - 3, - true, /* the one and only */ - rs6000_compatible, - bfd_default_scan, - 0, - }; diff --git a/contrib/gdb/bfd/cpu-sh.c b/contrib/gdb/bfd/cpu-sh.c deleted file mode 100644 index 7f6dd68ba04..00000000000 --- a/contrib/gdb/bfd/cpu-sh.c +++ /dev/null @@ -1,68 +0,0 @@ -/* BFD library support routines for the Hitachi-SH architecture. - Copyright (C) 1993 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -int bfd_default_scan_num_mach(); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp(string,"sh") == 0) return true; - if (strcmp(string,"SH") == 0) return true; - return false; -} - - -#if 0 -/* This routine is provided two arch_infos and returns whether - they'd be compatible */ - -static const bfd_arch_info_type * -compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->arch != b->arch || a->mach != b->mach) - return NULL; - return a; -} -#endif - -const bfd_arch_info_type bfd_sh_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_sh, - 0, /* only 1 machine */ - "sh", /* arch_name */ - "sh", /* printable name */ - 1, - true, /* the default machine */ - bfd_default_compatible, - scan_mach, - 0, -}; diff --git a/contrib/gdb/bfd/cpu-sparc.c b/contrib/gdb/bfd/cpu-sparc.c deleted file mode 100644 index e48aa5e7f2b..00000000000 --- a/contrib/gdb/bfd/cpu-sparc.c +++ /dev/null @@ -1,111 +0,0 @@ -/* BFD support for the SPARC architecture. - Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* Don't mix 32 bit and 64 bit files. */ - -static const bfd_arch_info_type * -sparc_compatible (a, b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->bits_per_word != b->bits_per_word) - return NULL; - - return bfd_default_compatible (a, b); -} - -static const bfd_arch_info_type arch_info_struct[] = -{ - { - 32, /* bits in a word */ - 32, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v8plus, - "sparc", - "sparc:v8plus", - 3, - false, - sparc_compatible, - bfd_default_scan, - &arch_info_struct[1], - }, - { - 32, /* bits in a word */ - 32, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v8plusa, - "sparc", - "sparc:v8plusa", - 3, - false, - sparc_compatible, - bfd_default_scan, - &arch_info_struct[2], - }, - { - 64, /* bits in a word */ - 64, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v9, - "sparc", - "sparc:v9", - 3, - false, - sparc_compatible, - bfd_default_scan, - &arch_info_struct[3], - }, - { - 64, /* bits in a word */ - 64, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v9a, - "sparc", - "sparc:v9a", - 3, - false, - sparc_compatible, - bfd_default_scan, - 0, - } -}; - -const bfd_arch_info_type bfd_sparc_arch = - { - 32, /* bits in a word */ - 32, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc, - "sparc", - "sparc", - 3, - true, /* the default */ - sparc_compatible, - bfd_default_scan, - &arch_info_struct[0], - }; diff --git a/contrib/gdb/bfd/cpu-vax.c b/contrib/gdb/bfd/cpu-vax.c deleted file mode 100644 index bdc6d39e451..00000000000 --- a/contrib/gdb/bfd/cpu-vax.c +++ /dev/null @@ -1,39 +0,0 @@ -/* bfd back-end for vax support - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_vax_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_vax, - 0, /* only 1 machine */ - "vax", - "vax", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-w65.c b/contrib/gdb/bfd/cpu-w65.c deleted file mode 100644 index c0bbf045219..00000000000 --- a/contrib/gdb/bfd/cpu-w65.c +++ /dev/null @@ -1,54 +0,0 @@ -/* BFD library support routines for the WDC 65816 architecture. - Copyright (C) 1995 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as publiw65ed by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You w65ould have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -int bfd_default_scan_num_mach(); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp(string,"w65") == 0) return true; - if (strcmp(string,"w65816") == 0) return true; - return false; -} - - - -const bfd_arch_info_type bfd_w65_arch = -{ - 16, /* 16 bits in a word */ - 24, /* 24 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_w65, - 0, /* only 1 machine */ - "w65", /* arch_name */ - "w65", /* printable name */ - 1, - true, /* the default machine */ - bfd_default_compatible, - scan_mach, - 0, -}; diff --git a/contrib/gdb/bfd/cpu-we32k.c b/contrib/gdb/bfd/cpu-we32k.c deleted file mode 100644 index a38cbc1268b..00000000000 --- a/contrib/gdb/bfd/cpu-we32k.c +++ /dev/null @@ -1,39 +0,0 @@ -/* bfd back-end for we32k support - Copyright (C) 1992 Free Software Foundation, Inc. - Contributed by Brendan Kehoe (brendan@cs.widener.edu). - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_we32k_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_we32k, - 32000, /* only 1 machine */ - "we32k", - "we32k:32000", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-z8k.c b/contrib/gdb/bfd/cpu-z8k.c deleted file mode 100644 index 5cce8eb0689..00000000000 --- a/contrib/gdb/bfd/cpu-z8k.c +++ /dev/null @@ -1,198 +0,0 @@ -/* BFD library support routines for the Z800n architecture. - Copyright (C) 1992 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -#if 0 /* not used currently */ -/* -Relocations for the Z8K - -*/ -static bfd_reloc_status_type -howto16_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_16 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - - -static reloc_howto_type howto_16 -= NEWHOWTO (howto16_callback, "abs16", 1, false, false); -static reloc_howto_type howto_8 -= NEWHOWTO (howto8_callback, "abs8", 0, false, false); - -static reloc_howto_type howto_8_FFnn -= NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, false, false); - -static reloc_howto_type howto_8_pcrel -= NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, false, true); - - -static reloc_howto_type * -local_bfd_reloc_type_lookup (arch, code) - const struct bfd_arch_info *arch; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_16: - return &howto_16; - case BFD_RELOC_8_FFnn: - return &howto_8_FFnn; - case BFD_RELOC_8: - return &howto_8; - case BFD_RELOC_8_PCREL: - return &howto_8_pcrel; - default: - return (reloc_howto_type *) NULL; - } -} -#endif - -int bfd_default_scan_num_mach (); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp (string, "z8001") == 0 || strcmp (string, "z8k") == 0) - { - return bfd_mach_z8001 == info->mach; - } - if (strcmp (string, "z8002") == 0) - { - return bfd_mach_z8002 == info->mach; - } - return false; -} - - -/* This routine is provided two arch_infos and returns whether - they'd be compatible */ - -static const bfd_arch_info_type * -compatible (a, b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->arch != b->arch || a->mach != b->mach) - return NULL; - return a; -} - - -static const bfd_arch_info_type arch_info_struct[] = -{ - {32, 32, 8, bfd_arch_z8k, bfd_mach_z8001, "z8k", "z8001", 1, false, compatible, scan_mach, 0,}, -}; - -const bfd_arch_info_type bfd_z8k_arch = -{ - 32, 16, 8, bfd_arch_z8k, bfd_mach_z8002, "z8k", "z8002", 1, true, compatible, scan_mach, &arch_info_struct[0], -}; diff --git a/contrib/gdb/bfd/demo64.c b/contrib/gdb/bfd/demo64.c deleted file mode 100644 index c91381d46e9..00000000000 --- a/contrib/gdb/bfd/demo64.c +++ /dev/null @@ -1,24 +0,0 @@ -/* BFD backend for demonstration 64-bit a.out binaries. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define ARCH_SIZE 64 -#define MY(OP) CAT(demo_64_,OP) -#define TARGETNAME "demo64" -#include "aoutf1.h" diff --git a/contrib/gdb/bfd/dep-in.sed b/contrib/gdb/bfd/dep-in.sed deleted file mode 100644 index 1cbd786fb2e..00000000000 --- a/contrib/gdb/bfd/dep-in.sed +++ /dev/null @@ -1,24 +0,0 @@ -:loop -/\\$/N -/\\$/b loop - -s! @BFD_H@!!g -s!@INCDIR@!$(INCDIR)!g -s!@SRCDIR@/!!g -s!hosts/[^ ]*\.h ! !g -s/ sysdep.h//g -s/ libbfd.h//g -s/ config.h//g -s! \$(INCDIR)/fopen-[^ ]*\.h!!g -s! \$(INCDIR)/ansidecl\.h!!g -s! \$(INCDIR)/obstack\.h!!g - -s/\\\n */ /g - -s/ *$// -s/ */ /g -s/ *:/:/g -/:$/d - -s/\(.\{50\}[^ ]*\) /\1 \\\ - /g diff --git a/contrib/gdb/bfd/doc/ChangeLog b/contrib/gdb/bfd/doc/ChangeLog deleted file mode 100644 index f076e3777b5..00000000000 --- a/contrib/gdb/bfd/doc/ChangeLog +++ /dev/null @@ -1,268 +0,0 @@ -Tue Jan 30 14:10:46 1996 Ian Lance Taylor - - From Ronald F. Guilmette : - * Makefile.in (libbfd.h): Depend upon proto.str. - (libcoff.h, bfd.h): Likewise. - -Fri Nov 3 14:46:48 1995 Fred Fish - - * Makefile.in (SRCDOC, SRCPROT, core.texi, bfd.h): Use corefile.c, - renamed from core.c. - -Wed Nov 1 14:28:23 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 - - * chew.c: Include . - -Fri Oct 6 16:23:34 1995 Ken Raeburn - - Mon Sep 25 22:49:32 1995 Andreas Schwab - - * Makefile.in (Makefile): Only remake this Makefile. - -Wed Oct 4 15:51:05 1995 Ken Raeburn - - * chew.c: Include . - -Tue Sep 12 18:14:50 1995 Ian Lance Taylor - - * Makefile.in (maintainer-clean): New target. - -Thu Aug 31 12:18:43 1995 Ian Lance Taylor - - * Makefile.in (bfd.h): Add additional #endif at end of bfd.h if - __cplusplus is defined. - -Tue Nov 29 16:13:34 1994 Doug Evans - - * chew.c (write_buffer): New argument `f', all callers changed. - (stdout, stderr, print, drop, idrop): New forth words. - * proto.str (COMMENT): New command. - * doc.str (COMMENT): Likewise. - -Mon Sep 12 11:44:17 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * Makefile.in (DOCFILES): Remove ctor.texi. - (IPROTOS): Remove ctor.ip. - (SRCIPROT): Remove $(srcdir)/../ctor.c. - (ctor.texi): Remove target. - (libbfd.h): Remove dependency on $(srcdir)/../ctor.c. Remove - $(MKDOC) run on $(srcdir)/../ctor.c. - * bfd.texinfo (Constructors): Remove section. - -Fri Sep 2 13:33:44 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * chew.c: Include assert.h. Added prototypes for most functions. - Changed most uses of int to long. Do bounds checking on the - stacks. Added comment at the beginning documenting most of the - intrinsics. Lots of whitespace changes. Re-ordered some - functions. - (die, check_range, icheck_range): New functions. - (strip_trailing_newlines, print_stack_level): New functions. - (translatecomments): Don't insert tab before "/*". - (iscommand): Minimum command length is now 4. - (nextword): Handle some \-sequences. - (push_addr): Deleted. - (main): Add new intrinsics strip_trailing_newlines and - print_stack_level. Complain at end if stack contains more than - one element, or less. - (remchar): Make sure the string is not empty before chopping off a - character. - - * doc.str, proto.str: Handle new commands SENUM, ENUM, ENUMX, - ENUMEQ, ENUMEQX, ENUMDOC. - -Wed Jan 12 18:37:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfd.texinfo: Added Linker Functions node. - * doc/Makefile.in (DOCFILES): Added linker.texi. - (SRCDOC): Added linker.c. - (linker.texi): New target. - -Tue Jan 4 10:52:56 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * chew.c: Don't rely on a correct declaration of exit. - (chew_exit): New function which just calls exit. - (main): Use it. - -Mon Jan 3 11:40:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfd.texinfo: Added Hash Tables node. - * Makefile.in (DOCFILES): Added hash.texi. - (SRCDOC): Added hash.c. - (hash.texi): New target. - -Thu Dec 30 16:57:04 1993 Ken Raeburn (raeburn@cujo.cygnus.com) - - * Makefile.in: Delete all references to seclet.c, since it's just - been deleted. Don't mention hash.c, linker.c, or genlink.h yet, - since they don't contain documentation yet (hint, hint!). - -Fri Nov 5 10:58:53 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * bfd.texinfo: Small cleanups. - -Fri Nov 19 03:46:11 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (archures.texi): Depends on $(MKDOC). - -Tue Aug 10 14:22:39 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * bfd.texinfo (BFD back end): Don't include elfcode.texi, since - it's empty now and that triggers a makeinfo bug. - -Mon Aug 9 16:27:30 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * bfd.texinfo (BFD back end): New section on ELF, includes - elf.texi and elfcode.texi. - * Makefile.in (DOCFILES): Include elf.texi, elfcode.texi. - (SRCDOC): Include elfcode.h, elf.c. - (elf.texi, elfcode.texi): New intermediate targets. - -Thu Jun 24 13:48:13 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * Makefile.in (.c.o, chew.o): Put CFLAGS last. - * bfdsumm.texi: New file, broken out of bfd.texinfo, to share - with ld.texinfo. - -Mon Jun 14 12:07:07 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com) - - * Makefile.in (install-info): remove parentdir cruft, - -Wed Jun 9 16:00:32 1993 Jim Kingdon (kingdon@cygnus.com) - - * Makefile.in (mostlyclean): Remove chew.o. - -Tue May 25 14:46:58 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (libbfd.h): Use elfcode.h, not elf32.c. - -Mon May 24 15:50:07 1993 Ken Raeburn (raeburn@cygnus.com) - - * chew.c (compile): Add a couple of missing casts. - -Wed May 12 14:45:14 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (CC_FOR_BUILD): New variable, define to be $(CC). - (chew.o, $(MKDOC)): Build using CC_FOR_BUILD rather than CC, since - it must run on the build machine. - -Tue Apr 6 22:38:10 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (chew): Don't compile from .c to executable in a - single step; it puts a temporary .o filename into the executable, - which makes multi-stage comparisons fail. Compile chew.c to - chew.o, and link that, which makes identical executables every time. - -Wed Mar 24 17:26:29 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com) - - * Makefile.in: fix typo (bfd.texinfo not bfd.texino) - -Fri Mar 19 01:13:00 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * bfd.texinfo: Since BFD version number has been bumped, do same - to "version number" on title page, and elsewhere. Should be - fixed to extract real version number. - -Tue Mar 16 12:15:13 1993 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in: Add *clean rules. - -Mon Jan 11 18:43:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * Makefile.in (libbfd.h): Removed duplicate init.c and libbfd.c. - Added seclet.c. - (bfd.h): Added dependency on bfd.c and seclet.c. Added seclet.c - to build. - -Thu Dec 17 19:35:43 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: added dvi target, define and use $(TEXI2DVI) - -Thu Dec 3 17:42:48 1992 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (TEXIDIR): New variable. - (bfd.dvi): Look for bfd.texinfo in $(srcdir). Generate index. - - * bfd.texinfo: Minor doc fixes. - -Thu Nov 5 03:13:55 1992 John Gilmore (gnu@cygnus.com) - - Cleanup: Replace all uses of EXFUN in the BFD sources, with PARAMS. - - * doc/chew.c (exfunstuff): Eliminate. - (paramstuff): Replace exfunstuff with function to generate PARAMS. - * doc/proto.str: Use paramstuff rather than exfunstuff. - -Mon Aug 17 12:40:32 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * chew.c: various patches provided by Howard Chu. - -Fri Jun 19 18:59:54 1992 John Gilmore (gnu at cygnus.com) - - * Makefile.in (libbfd.h): Add elf.c as a source of prototypes. - -Mon May 11 18:55:59 1992 John Gilmore (gnu at cygnus.com) - - * chew.c: exit() should be declared by config files, not by - portable source code. Its type could be int or void function. - -Mon May 4 13:45:57 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in: another CFLAGS correction. - -Tue Apr 28 10:21:32 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in: Do the CFLAGS thing. - -Fri Apr 10 22:34:52 1992 Fred Fish (fnf@cygnus.com) - - * Makefile.in (MINUS_G): Add macro and default to -g. - -Fri Mar 6 18:53:18 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * chew.c: now has -w switch turn on warnings - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - -Tue Dec 10 22:11:05 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: build chew into the current directory. Complete - the MKDOC macro transition. - -Tue Dec 10 08:26:28 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * chew.c: don't core dump when can't open file - * Makefile.in: get proto.str from the right place when built in - odd directories - -Tue Dec 10 04:07:25 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: infodir belongs in datadir. - -Sat Dec 7 17:01:23 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * chew.c: Much modified - * proto.str, doc.str: New files for extracting to product - prototypes and documents respectively. - - -Fri Dec 6 22:57:12 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: added standards.text support, host/site/target - inclusion hooks, install using INSTALL_DATA rather than cp, - don't echo on install. - -Thu Dec 5 22:46:17 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: idestdir and ddestdir go away. Added copyrights - and shift gpl to v2. Added ChangeLog if it didn't exist. docdir - and mandir now keyed off datadir by default. - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/bfd/doc/Makefile.in b/contrib/gdb/bfd/doc/Makefile.in deleted file mode 100644 index aa3a76c26ae..00000000000 --- a/contrib/gdb/bfd/doc/Makefile.in +++ /dev/null @@ -1,311 +0,0 @@ -# -# Makefile -# Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -# - -VPATH = @srcdir@ -srcdir = @srcdir@ - -prefix = @prefix@ - -exec_prefix = @exec_prefix@ -bindir = $(exec_prefix)/bin -libdir = $(exec_prefix)/lib - -datadir = $(prefix)/lib -mandir = $(prefix)/man -man1dir = $(mandir)/man1 -man2dir = $(mandir)/man2 -man3dir = $(mandir)/man3 -man4dir = $(mandir)/man4 -man5dir = $(mandir)/man5 -man6dir = $(mandir)/man6 -man7dir = $(mandir)/man7 -man8dir = $(mandir)/man8 -man9dir = $(mandir)/man9 -infodir = $(prefix)/info -includedir = $(prefix)/include -docdir = $(datadir)/doc - -MKDOC=./chew -SHELL = /bin/sh - -INSTALL = `cd $(srcdir)/../..;pwd`/install.sh -c -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) - -MAKEINFO = makeinfo -TEXI2DVI = texi2dvi -CFLAGS = -g - -CC_FOR_BUILD = $(CC) - -#### Host, target, and site specific Makefile fragments come in here. -### - -.c.o: - $(CC) -c -I.. -I$(srcdir)/.. -I$(srcdir)/../../include $(H_CFLAGS) $(CFLAGS) $< - -DOCFILES = aoutx.texi archive.texi archures.texi \ - bfd.texi cache.texi coffcode.texi \ - core.texi elf.texi elfcode.texi format.texi libbfd.texi \ - opncls.texi reloc.texi section.texi \ - syms.texi targets.texi init.texi hash.texi linker.texi - -PROTOS = archive.p archures.p bfd.p \ - core.p format.p \ - libbfd.p opncls.p reloc.p \ - section.p syms.p targets.p \ - format.p core.p init.p - -IPROTOS = cache.ip libbfd.ip reloc.ip init.ip archures.ip coffcode.ip - -# SRCDOC, SRCPROT, SRCIPROT only used to sidestep Sun Make bug in interaction -# between VPATH and suffix rules. If you use GNU Make, perhaps other Makes, -# you don't need these three: -SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \ - $(srcdir)/../archures.c $(srcdir)/../bfd.c \ - $(srcdir)/../cache.c $(srcdir)/../coffcode.h \ - $(srcdir)/../corefile.c $(srcdir)/../elf.c \ - $(srcdir)/../elfcode.h $(srcdir)/../format.c \ - $(srcdir)/../libbfd.c $(srcdir)/../opncls.c \ - $(srcdir)/../reloc.c $(srcdir)/../section.c \ - $(srcdir)/../syms.c $(srcdir)/../targets.c \ - $(srcdir)/../hash.c $(srcdir)/../linker.c - -SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \ - $(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \ - $(srcdir)/../format.c $(srcdir)/../libbfd.c \ - $(srcdir)/../opncls.c $(srcdir)/../reloc.c \ - $(srcdir)/../section.c $(srcdir)/../syms.c \ - $(srcdir)/../targets.c $(srcdir)/../init.c - -SRCIPROT = $(srcdir)/../cache.c $(srcdir)/../libbfd.c \ - $(srcdir)/../reloc.c $(srcdir)/../cpu-h8300.c \ - $(srcdir)/../cpu-i960.c $(srcdir)/../archures.c \ - $(srcdir)/../init.c - -STAGESTUFF = $(DOCFILES) *.info* - -TEXIDIR = $(srcdir)/../../texinfo/fsf - -all install: - -info: bfd.info - -dvi: bfd.dvi - -install-info: info - for i in *.info* ; do \ - $(INSTALL_DATA) $$i $(infodir)/$$i ; \ - done - -docs: $(MKDOC) protos bfd.info bfd.dvi bfd.ps - -$(MKDOC): chew.o - $(CC_FOR_BUILD) -o $(MKDOC) chew.o $(LOADLIBES) $(LDFLAGS) - -chew.o: chew.c - $(CC_FOR_BUILD) -c -I.. -I$(srcdir)/.. -I$(srcdir)/../../include $(H_CFLAGS) $(CFLAGS) $(srcdir)/chew.c - -protos: libbfd.h libcoff.h bfd.h - - -# We can't replace these rules with an implicit rule, because -# makes without VPATH support couldn't find the .h files in `..'. - -aoutx.texi: $(MKDOC) $(srcdir)/../aoutx.h $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../aoutx.h >aoutx.texi - -archive.texi: $(MKDOC) $(srcdir)/../archive.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../archive.c >archive.texi - -archures.texi: $(MKDOC) $(srcdir)/../archures.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../archures.c >archures.texi - -bfd.texi: $(MKDOC) $(srcdir)/../bfd.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../bfd.c >bfd.texi - -cache.texi: $(MKDOC) $(srcdir)/../cache.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../cache.c >cache.texi - -coffcode.texi: $(MKDOC) $(srcdir)/../coffcode.h $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../coffcode.h >coffcode.texi - -core.texi: $(MKDOC) $(srcdir)/../corefile.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../corefile.c >core.texi - -elf.texi: $(MKDOC) $(srcdir)/../elf.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../elf.c >elf.texi - -elfcode.texi: $(MKDOC) $(srcdir)/../elfcode.h $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../elfcode.h >elfcode.texi - -format.texi: $(MKDOC) $(srcdir)/../format.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../format.c >format.texi - -libbfd.texi: $(MKDOC) $(srcdir)/../libbfd.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../libbfd.c >libbfd.texi - -opncls.texi: $(MKDOC) $(srcdir)/../opncls.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../opncls.c >opncls.texi - -reloc.texi : $(MKDOC) $(srcdir)/../reloc.c - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../reloc.c >reloc.texi - -section.texi: $(MKDOC) $(srcdir)/../section.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../section.c >section.texi - -syms.texi : $(MKDOC) $(srcdir)/../syms.c - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../syms.c >syms.texi - -targets.texi: $(MKDOC) $(srcdir)/../targets.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../targets.c >targets.texi - -init.texi: $(MKDOC) $(srcdir)/../init.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../init.c >init.texi - -hash.texi: $(MKDOC) $(srcdir)/../hash.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../hash.c >hash.texi - -linker.texi: $(MKDOC) $(srcdir)/../linker.c $(srcdir)/doc.str - $(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../linker.c >linker.texi - -libbfd.h: $(srcdir)/../libbfd-in.h \ - $(srcdir)/../init.c \ - $(srcdir)/../libbfd.c \ - $(srcdir)/../cache.c \ - $(srcdir)/../reloc.c \ - $(srcdir)/../cpu-h8300.c \ - $(srcdir)/../cpu-i960.c \ - $(srcdir)/../archures.c \ - $(srcdir)/../elfcode.h \ - $(srcdir)/proto.str \ - $(MKDOC) - cat $(srcdir)/../libbfd-in.h >libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../init.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../libbfd.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../cache.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../reloc.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../cpu-h8300.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../cpu-i960.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../archures.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../elf.c >>libbfd.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../elfcode.h >>libbfd.h - -libcoff.h: $(srcdir)/../libcoff-in.h \ - $(srcdir)/../coffcode.h \ - $(srcdir)/proto.str \ - $(MKDOC) - cat $(srcdir)/../libcoff-in.h >libcoff.h - $(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../coffcode.h >>libcoff.h - -bfd.h: $(srcdir)/../bfd-in.h \ - $(srcdir)/../init.c \ - $(srcdir)/../opncls.c \ - $(srcdir)/../libbfd.c \ - $(srcdir)/../section.c \ - $(srcdir)/../archures.c \ - $(srcdir)/../reloc.c \ - $(srcdir)/../syms.c \ - $(srcdir)/../bfd.c \ - $(srcdir)/../archive.c \ - $(srcdir)/../corefile.c \ - $(srcdir)/../targets.c \ - $(srcdir)/../format.c \ - $(srcdir)/proto.str \ - $(MKDOC) - cat $(srcdir)/../bfd-in.h >bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../init.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../opncls.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../libbfd.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../section.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../archures.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../reloc.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../syms.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../bfd.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../archive.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../corefile.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../targets.c >>bfd.h - $(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../format.c >>bfd.h - echo "#ifdef __cplusplus" >>bfd.h - echo "}" >>bfd.h - echo "#endif" >>bfd.h - echo "#endif" >>bfd.h - - -clean-info: clean - -mostlyclean: - rm -rf *.log *.ps *~* *.dvi *# $(MKDOC) *.o - -clean: mostlyclean - rm -rf $(STAGESTUFF) - rm -f *.p *.ip bfd.?? bfd.??? bfd.h libbfd.h libcoff.h texput.log - -distclean: clean - rm -f Makefile config.status - -maintainer-clean realclean: clean - rm -f Makefile config.status - -bfd.info: $(DOCFILES) bfdsumm.texi bfd.texinfo - $(MAKEINFO) -I$(srcdir) -o bfd.info $(srcdir)/bfd.texinfo - -bfd.dvi: $(DOCFILES) bfdsumm.texi bfd.texinfo - $(TEXI2DVI) $(srcdir)/bfd.texinfo - -bfd.ps: bfd.dvi - dvips bfd -o - -quickdoc: $(DOCFILES) bfdsumm.texi bfd.texinfo - TEXINPUTS=${TEXIDIR}:.:$$TEXINPUTS tex bfd.texinfo - -stage1: force - - mkdir stage1 - - mv -f $(STAGESTUFF) stage1 - -stage2: force - - mkdir stage2 - - mv -f $(STAGESTUFF) stage2 - -stage3: force - - mkdir stage3 - - mv -f $(STAGESTUFF) stage3 - -against=stage2 - -comparison: force - for i in $(STAGESTUFF) ; do cmp $$i $(against)/$$i || exit 1 ; done - -de-stage1: force - - (cd stage1 ; mv -f $(STAGESTUFF) ..) - - rmdir stage1 - -de-stage2: force - - (cd stage2 ; mv -f $(STAGESTUFF) ..) - - rmdir stage2 - -de-stage3: force - - (cd stage3 ; mv -f $(STAGESTUFF) ..) - - rmdir stage3 - -force: - -Makefile: $(srcdir)/Makefile.in - cd .. && CONFIG_FILES=doc/$@ CONFIG_HEADERS= $(SHELL) ./config.status - diff --git a/contrib/gdb/bfd/doc/bfd.texinfo b/contrib/gdb/bfd/doc/bfd.texinfo deleted file mode 100644 index af7bc10062d..00000000000 --- a/contrib/gdb/bfd/doc/bfd.texinfo +++ /dev/null @@ -1,348 +0,0 @@ -\input texinfo.tex -@setfilename bfd.info -@c $Id: bfd.texinfo,v 1.28 1995/11/10 20:04:12 victoria Exp $ -@tex -% NOTE LOCAL KLUGE TO AVOID TOO MUCH WHITESPACE -\global\long\def\example{% -\begingroup -\let\aboveenvbreak=\par -\let\afterenvbreak=\par -\parskip=0pt -\lisp} -\global\long\def\Eexample{% -\Elisp -\endgroup -\vskip -\parskip% to cancel out effect of following \par -} -@end tex -@synindex fn cp - -@ifinfo -@format -START-INFO-DIR-ENTRY -* Bfd: (bfd). The Binary File Descriptor library. -END-INFO-DIR-ENTRY -@end format -@end ifinfo - -@ifinfo -This file documents the BFD library. - -Copyright (C) 1991 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, subject to the terms -of the GNU General Public License, which includes the provision that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ifinfo -@iftex -@c@finalout -@setchapternewpage on -@c@setchapternewpage odd -@settitle LIB BFD, the Binary File Descriptor Library -@titlepage -@title{libbfd} -@subtitle{The Binary File Descriptor Library} -@sp 1 -@subtitle First Edition---BFD version < 3.0 -@subtitle April 1991 -@author {Steve Chamberlain} -@author {Cygnus Support} -@page - -@tex -\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$ -\xdef\manvers{\$Revision: 1.28 $} % For use in headers, footers too -{\parskip=0pt -\hfill Cygnus Support\par -\hfill sac\@cygnus.com\par -\hfill {\it BFD}, \manvers\par -\hfill \TeX{}info \texinfoversion\par -} -\global\parindent=0pt % Steve likes it this way -@end tex - -@vskip 0pt plus 1filll -Copyright @copyright{} 1991 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, subject to the terms -of the GNU General Public License, which includes the provision that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end titlepage -@end iftex - -@node Top, Overview, (dir), (dir) -@ifinfo -This file documents the binary file descriptor library libbfd. -@end ifinfo - -@menu -* Overview:: Overview of BFD -* BFD front end:: BFD front end -* BFD back ends:: BFD back ends -* Index:: Index -@end menu - -@node Overview, BFD front end, Top, Top -@chapter Introduction -@cindex BFD -@cindex what is it? -BFD is a package which allows applications to use the -same routines to operate on object files whatever the object file -format. A new object file format can be supported simply by -creating a new BFD back end and adding it to the library. - -BFD is split into two parts: the front end, and the back ends (one for -each object file format). -@itemize @bullet -@item The front end of BFD provides the interface to the user. It manages -memory and various canonical data structures. The front end also -decides which back end to use and when to call back end routines. -@item The back ends provide BFD its view of the real world. Each back -end provides a set of calls which the BFD front end can use to maintain -its canonical form. The back ends also may keep around information for -their own use, for greater efficiency. -@end itemize -@menu -* History:: History -* How It Works:: How It Works -* What BFD Version 2 Can Do:: What BFD Version 2 Can Do -@end menu - -@node History, How It Works, Overview, Overview -@section History - -One spur behind BFD was the desire, on the part of the GNU 960 team at -Intel Oregon, for interoperability of applications on their COFF and -b.out file formats. Cygnus was providing GNU support for the team, and -was contracted to provide the required functionality. - -The name came from a conversation David Wallace was having with Richard -Stallman about the library: RMS said that it would be quite hard---David -said ``BFD''. Stallman was right, but the name stuck. - -At the same time, Ready Systems wanted much the same thing, but for -different object file formats: IEEE-695, Oasys, Srecords, a.out and 68k -coff. - -BFD was first implemented by members of Cygnus Support; Steve -Chamberlain (@code{sac@@cygnus.com}), John Gilmore -(@code{gnu@@cygnus.com}), K. Richard Pixley (@code{rich@@cygnus.com}) -and David Henkel-Wallace (@code{gumby@@cygnus.com}). - - - -@node How It Works, What BFD Version 2 Can Do, History, Overview -@section How To Use BFD - -To use the library, include @file{bfd.h} and link with @file{libbfd.a}. - -BFD provides a common interface to the parts of an object file -for a calling application. - -When an application sucessfully opens a target file (object, archive, or -whatever), a pointer to an internal structure is returned. This pointer -points to a structure called @code{bfd}, described in -@file{bfd.h}. Our convention is to call this pointer a BFD, and -instances of it within code @code{abfd}. All operations on -the target object file are applied as methods to the BFD. The mapping is -defined within @code{bfd.h} in a set of macros, all beginning -with @samp{bfd_} to reduce namespace pollution. - -For example, this sequence does what you would probably expect: -return the number of sections in an object file attached to a BFD -@code{abfd}. - -@lisp -@c @cartouche -#include "bfd.h" - -unsigned int number_of_sections(abfd) -bfd *abfd; -@{ - return bfd_count_sections(abfd); -@} -@c @end cartouche -@end lisp - -The abstraction used within BFD is that an object file has: - -@itemize @bullet -@item -a header, -@item -a number of sections containing raw data (@pxref{Sections}), -@item -a set of relocations (@pxref{Relocations}), and -@item -some symbol information (@pxref{Symbols}). -@end itemize -@noindent -Also, BFDs opened for archives have the additional attribute of an index -and contain subordinate BFDs. This approach is fine for a.out and coff, -but loses efficiency when applied to formats such as S-records and -IEEE-695. - -@node What BFD Version 2 Can Do, , How It Works, Overview -@section What BFD Version 2 Can Do -@include bfdsumm.texi - -@node BFD front end, BFD back ends, Overview, Top -@chapter BFD front end -@include bfd.texi - -@menu -* Memory Usage:: -* Initialization:: -* Sections:: -* Symbols:: -* Archives:: -* Formats:: -* Relocations:: -* Core Files:: -* Targets:: -* Architectures:: -* Opening and Closing:: -* Internal:: -* File Caching:: -* Linker Functions:: -* Hash Tables:: -@end menu - -@node Memory Usage, Initialization, BFD front end, BFD front end -@section Memory usage -BFD keeps all of its internal structures in obstacks. There is one obstack -per open BFD file, into which the current state is stored. When a BFD is -closed, the obstack is deleted, and so everything which has been -allocated by BFD for the closing file is thrown away. - -BFD does not free anything created by an application, but pointers into -@code{bfd} structures become invalid on a @code{bfd_close}; for example, -after a @code{bfd_close} the vector passed to -@code{bfd_canonicalize_symtab} is still around, since it has been -allocated by the application, but the data that it pointed to are -lost. - -The general rule is to not close a BFD until all operations dependent -upon data from the BFD have been completed, or all the data from within -the file has been copied. To help with the management of memory, there -is a function (@code{bfd_alloc_size}) which returns the number of bytes -in obstacks associated with the supplied BFD. This could be used to -select the greediest open BFD, close it to reclaim the memory, perform -some operation and reopen the BFD again, to get a fresh copy of the data -structures. - -@node Initialization, Sections, Memory Usage, BFD front end -@include init.texi - -@node Sections, Symbols, Initialization, BFD front end -@include section.texi - -@node Symbols, Archives, Sections, BFD front end -@include syms.texi - -@node Archives, Formats, Symbols, BFD front end -@include archive.texi - -@node Formats, Relocations, Archives, BFD front end -@include format.texi - -@node Relocations, Core Files, Formats, BFD front end -@include reloc.texi - -@node Core Files, Targets, Relocations, BFD front end -@include core.texi - -@node Targets, Architectures, Core Files, BFD front end -@include targets.texi - -@node Architectures, Opening and Closing, Targets, BFD front end -@include archures.texi - -@node Opening and Closing, Internal, Architectures, BFD front end -@include opncls.texi - -@node Internal, File Caching, Opening and Closing, BFD front end -@include libbfd.texi - -@node File Caching, Linker Functions, Internal, BFD front end -@include cache.texi - -@node Linker Functions, Hash Tables, File Caching, BFD front end -@include linker.texi - -@node Hash Tables, , Linker Functions, BFD front end -@include hash.texi - -@node BFD back ends, Index, BFD front end, Top -@chapter BFD back ends -@menu -* What to Put Where:: -* aout :: a.out backends -* coff :: coff backends -* elf :: elf backends -@ignore -* oasys :: oasys backends -* ieee :: ieee backend -* srecord :: s-record backend -@end ignore -@end menu -@node What to Put Where, aout, BFD back ends, BFD back ends -All of BFD lives in one directory. - -@node aout, coff, What to Put Where, BFD back ends -@include aoutx.texi - -@node coff, elf, aout, BFD back ends -@include coffcode.texi - -@node elf, , coff, BFD back ends -@include elf.texi -@c Leave this out until the file has some actual contents... -@c @include elfcode.texi - -@node Index, , BFD back ends , Top -@unnumbered Index -@printindex cp - -@tex -% I think something like @colophon should be in texinfo. In the -% meantime: -\long\def\colophon{\hbox to0pt{}\vfill -\centerline{The body of this manual is set in} -\centerline{\fontname\tenrm,} -\centerline{with headings in {\bf\fontname\tenbf}} -\centerline{and examples in {\tt\fontname\tentt}.} -\centerline{{\it\fontname\tenit\/} and} -\centerline{{\sl\fontname\tensl\/}} -\centerline{are used for emphasis.}\vfill} -\page\colophon -% Blame: doc@cygnus.com, 28mar91. -@end tex - -@contents -@bye diff --git a/contrib/gdb/bfd/doc/bfdsumm.texi b/contrib/gdb/bfd/doc/bfdsumm.texi deleted file mode 100644 index 844531aff8c..00000000000 --- a/contrib/gdb/bfd/doc/bfdsumm.texi +++ /dev/null @@ -1,148 +0,0 @@ -@c This summary of BFD is shared by the BFD and LD docs. -When an object file is opened, BFD subroutines automatically determine -the format of the input object file. They then build a descriptor in -memory with pointers to routines that will be used to access elements of -the object file's data structures. - -As different information from the the object files is required, -BFD reads from different sections of the file and processes them. -For example, a very common operation for the linker is processing symbol -tables. Each BFD back end provides a routine for converting -between the object file's representation of symbols and an internal -canonical format. When the linker asks for the symbol table of an object -file, it calls through a memory pointer to the routine from the -relevant BFD back end which reads and converts the table into a canonical -form. The linker then operates upon the canonical form. When the link is -finished and the linker writes the output file's symbol table, -another BFD back end routine is called to take the newly -created symbol table and convert it into the chosen output format. - -@menu -* BFD information loss:: Information Loss -* Canonical format:: The BFD canonical object-file format -@end menu - -@node BFD information loss -@subsection Information Loss - -@emph{Information can be lost during output.} The output formats -supported by BFD do not provide identical facilities, and -information which can be described in one form has nowhere to go in -another format. One example of this is alignment information in -@code{b.out}. There is nowhere in an @code{a.out} format file to store -alignment information on the contained data, so when a file is linked -from @code{b.out} and an @code{a.out} image is produced, alignment -information will not propagate to the output file. (The linker will -still use the alignment information internally, so the link is performed -correctly). - -Another example is COFF section names. COFF files may contain an -unlimited number of sections, each one with a textual section name. If -the target of the link is a format which does not have many sections (e.g., -@code{a.out}) or has sections without names (e.g., the Oasys format), the -link cannot be done simply. You can circumvent this problem by -describing the desired input-to-output section mapping with the linker command -language. - -@emph{Information can be lost during canonicalization.} The BFD -internal canonical form of the external formats is not exhaustive; there -are structures in input formats for which there is no direct -representation internally. This means that the BFD back ends -cannot maintain all possible data richness through the transformation -between external to internal and back to external formats. - -This limitation is only a problem when an application reads one -format and writes another. Each BFD back end is responsible for -maintaining as much data as possible, and the internal BFD -canonical form has structures which are opaque to the BFD core, -and exported only to the back ends. When a file is read in one format, -the canonical form is generated for BFD and the application. At the -same time, the back end saves away any information which may otherwise -be lost. If the data is then written back in the same format, the back -end routine will be able to use the canonical form provided by the -BFD core as well as the information it prepared earlier. Since -there is a great deal of commonality between back ends, -there is no information lost when -linking or copying big endian COFF to little endian COFF, or @code{a.out} to -@code{b.out}. When a mixture of formats is linked, the information is -only lost from the files whose format differs from the destination. - -@node Canonical format -@subsection The BFD canonical object-file format - -The greatest potential for loss of information occurs when there is the least -overlap between the information provided by the source format, that -stored by the canonical format, and that needed by the -destination format. A brief description of the canonical form may help -you understand which kinds of data you can count on preserving across -conversions. -@cindex BFD canonical format -@cindex internal object-file format - -@table @emph -@item files -Information stored on a per-file basis includes target machine -architecture, particular implementation format type, a demand pageable -bit, and a write protected bit. Information like Unix magic numbers is -not stored here---only the magic numbers' meaning, so a @code{ZMAGIC} -file would have both the demand pageable bit and the write protected -text bit set. The byte order of the target is stored on a per-file -basis, so that big- and little-endian object files may be used with one -another. - -@item sections -Each section in the input file contains the name of the section, the -section's original address in the object file, size and alignment -information, various flags, and pointers into other BFD data -structures. - -@item symbols -Each symbol contains a pointer to the information for the object file -which originally defined it, its name, its value, and various flag -bits. When a BFD back end reads in a symbol table, it relocates all -symbols to make them relative to the base of the section where they were -defined. Doing this ensures that each symbol points to its containing -section. Each symbol also has a varying amount of hidden private data -for the BFD back end. Since the symbol points to the original file, the -private data format for that symbol is accessible. @code{ld} can -operate on a collection of symbols of wildly different formats without -problems. - -Normal global and simple local symbols are maintained on output, so an -output file (no matter its format) will retain symbols pointing to -functions and to global, static, and common variables. Some symbol -information is not worth retaining; in @code{a.out}, type information is -stored in the symbol table as long symbol names. This information would -be useless to most COFF debuggers; the linker has command line switches -to allow users to throw it away. - -There is one word of type information within the symbol, so if the -format supports symbol type information within symbols (for example, COFF, -IEEE, Oasys) and the type is simple enough to fit within one word -(nearly everything but aggregates), the information will be preserved. - -@item relocation level -Each canonical BFD relocation record contains a pointer to the symbol to -relocate to, the offset of the data to relocate, the section the data -is in, and a pointer to a relocation type descriptor. Relocation is -performed by passing messages through the relocation type -descriptor and the symbol pointer. Therefore, relocations can be performed -on output data using a relocation method that is only available in one of the -input formats. For instance, Oasys provides a byte relocation format. -A relocation record requesting this relocation type would point -indirectly to a routine to perform this, so the relocation may be -performed on a byte being written to a 68k COFF file, even though 68k COFF -has no such relocation type. - -@item line numbers -Object formats can contain, for debugging purposes, some form of mapping -between symbols, source line numbers, and addresses in the output file. -These addresses have to be relocated along with the symbol information. -Each symbol with an associated list of line number records points to the -first record of the list. The head of a line number list consists of a -pointer to the symbol, which allows finding out the address of the -function whose line number is being described. The rest of the list is -made up of pairs: offsets into the section and line numbers. Any format -which can simply derive this information can pass it successfully -between formats (COFF, IEEE and Oasys). -@end table diff --git a/contrib/gdb/bfd/doc/chew.c b/contrib/gdb/bfd/doc/chew.c deleted file mode 100644 index 5c04404f7a6..00000000000 --- a/contrib/gdb/bfd/doc/chew.c +++ /dev/null @@ -1,1551 +0,0 @@ -/* chew - Copyright (C) 1990-1991 Free Software Foundation, Inc. - Contributed by steve chamberlain @cygnus - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Yet another way of extracting documentation from source. - No, I haven't finished it yet, but I hope you people like it better - than the old way - - sac - - Basically, this is a sort of string forth, maybe we should call it - struth? - - You define new words thus: - : ; - -*/ - -/* Primitives provided by the program: - - Two stacks are provided, a string stack and an integer stack. - - Internal state variables: - internal_wanted - indicates whether `-i' was passed - internal_mode - user-settable - - Commands: - push_text - ! - pop top of integer stack for address, pop next for value; store - @ - treat value on integer stack as the address of an integer; push - that integer on the integer stack after popping the "address" - hello - print "hello\n" to stdout - stdout - put stdout marker on TOS - stderr - put stderr marker on TOS - print - print TOS-1 on TOS (eg: "hello\n" stdout print) - skip_past_newline - catstr - fn icatstr - copy_past_newline - append input, up to and including newline into TOS - dup - fn other_dup - drop - discard TOS - idrop - ditto - remchar - delete last character from TOS - get_stuff_in_command - do_fancy_stuff - translate <> to @code{foo} in TOS - bulletize - if "o" lines found, prepend @itemize @bullet to TOS - and @item to each "o" line; append @end itemize - courierize - put @example around . and | lines, translate {* *} { } - exit - fn chew_exit - swap - outputdots - strip out lines without leading dots - paramstuff - convert full declaration into "PARAMS" form if not already - maybecatstr - do catstr if internal_mode == internal_wanted, discard - value in any case - translatecomments - turn {* and *} into comment delimiters - kill_bogus_lines - get rid of extra newlines - indent - internalmode - pop from integer stack, set `internalmode' to that value - print_stack_level - print current stack depth to stderr - strip_trailing_newlines - go ahead, guess... - [quoted string] - push string onto string stack - [word starting with digit] - push atol(str) onto integer stack - - A command must be all upper-case, and alone on a line. - - Foo. */ - - -#include -#include "sysdep.h" -#include -#include -#include - -#define DEF_SIZE 5000 -#define STACK 50 - -int internal_wanted; -int internal_mode; - -int warning; - -/* Here is a string type ... */ - -typedef struct buffer -{ - char *ptr; - unsigned long write_idx; - unsigned long size; -} string_type; - - -#ifdef __STDC__ -static void init_string_with_size (string_type *, unsigned int); -static void init_string (string_type *); -static int find (string_type *, char *); -static void write_buffer (string_type *, FILE *); -static void delete_string (string_type *); -static char *addr (string_type *, unsigned int); -static char at (string_type *, unsigned int); -static void catchar (string_type *, int); -static void overwrite_string (string_type *, string_type *); -static void catbuf (string_type *, char *, unsigned int); -static void cattext (string_type *, char *); -static void catstr (string_type *, string_type *); -static unsigned int skip_white_and_starts (string_type *, unsigned int); -#endif - - -static void DEFUN(init_string_with_size,(buffer, size), - string_type *buffer AND - unsigned int size ) -{ - buffer->write_idx = 0; - buffer->size = size; - buffer->ptr = malloc(size); -} - -static void DEFUN(init_string,(buffer), - string_type *buffer) -{ - init_string_with_size(buffer, DEF_SIZE); - -} - -static int DEFUN(find, (str, what), - string_type *str AND - char *what) -{ - unsigned int i; - char *p; - p = what; - for (i = 0; i < str->write_idx && *p; i++) - { - if (*p == str->ptr[i]) - p++; - else - p = what; - } - return (*p == 0); - -} - -static void DEFUN(write_buffer,(buffer, f), - string_type *buffer AND - FILE *f) -{ - fwrite(buffer->ptr, buffer->write_idx, 1, f); -} - - -static void DEFUN(delete_string,(buffer), - string_type *buffer) -{ - free(buffer->ptr); -} - - -static char *DEFUN(addr, (buffer, idx), - string_type *buffer AND - unsigned int idx) -{ - return buffer->ptr + idx; -} - -static char DEFUN(at,(buffer, pos), - string_type *buffer AND - unsigned int pos) -{ - if (pos >= buffer->write_idx) - return 0; - return buffer->ptr[pos]; -} - -static void DEFUN(catchar,(buffer, ch), - string_type *buffer AND - int ch) -{ - if (buffer->write_idx == buffer->size) - { - buffer->size *=2; - buffer->ptr = realloc(buffer->ptr, buffer->size); - } - - buffer->ptr[buffer->write_idx ++ ] = ch; -} - - -static void DEFUN(overwrite_string,(dst, src), - string_type *dst AND - string_type *src) -{ - free(dst->ptr); - dst->size = src->size; - dst->write_idx = src->write_idx; - dst->ptr = src->ptr; -} - -static void DEFUN(catbuf,(buffer, buf, len), - string_type *buffer AND - char *buf AND - unsigned int len) -{ - if (buffer->write_idx + len >= buffer->size) - { - while (buffer->write_idx + len >= buffer->size) - buffer->size *= 2; - buffer->ptr = realloc (buffer->ptr, buffer->size); - } - memcpy (buffer->ptr + buffer->write_idx, buf, len); - buffer->write_idx += len; -} - -static void DEFUN(cattext,(buffer, string), - string_type *buffer AND - char *string) -{ - catbuf (buffer, string, (unsigned int) strlen (string)); -} - -static void DEFUN(catstr,(dst, src), - string_type *dst AND - string_type *src) -{ - catbuf (dst, src->ptr, src->write_idx); -} - - -static unsigned int -DEFUN(skip_white_and_stars,(src, idx), - string_type *src AND - unsigned int idx) -{ - char c; - while ((c = at(src,idx)), - isspace (c) - || (c == '*' - /* Don't skip past end-of-comment or star as first - character on its line. */ - && at(src,idx +1) != '/' - && at(src,idx -1) != '\n')) - idx++; - return idx; -} - -/***********************************************************************/ - - -string_type stack[STACK]; -string_type *tos; - -unsigned int idx = 0; /* Pos in input buffer */ -string_type *ptr; /* and the buffer */ -typedef void (*stinst_type)(); -stinst_type *pc; -stinst_type sstack[STACK]; -stinst_type *ssp = &sstack[0]; -long istack[STACK]; -long *isp = &istack[0]; - -typedef int *word_type; - - - -struct dict_struct -{ - char *word; - struct dict_struct *next; - stinst_type *code; - int code_length; - int code_end; - int var; - -}; -typedef struct dict_struct dict_type; -#define WORD(x) static void x() - -static void -die (msg) - char *msg; -{ - fprintf (stderr, "%s\n", msg); - exit (1); -} - -static void -check_range () -{ - if (tos < stack) - die ("underflow in string stack"); - if (tos >= stack + STACK) - die ("overflow in string stack"); -} - -static void -icheck_range () -{ - if (isp < istack) - die ("underflow in integer stack"); - if (isp >= istack + STACK) - die ("overflow in integer stack"); -} - -#ifdef __STDC__ -static void exec (dict_type *); -static void call (void); -static void remchar (void), strip_trailing_newlines (void), push_number (void); -static void push_text (void); -static void remove_noncomments (string_type *, string_type *); -static void print_stack_level (void); -static void paramstuff (void), translatecomments (void), manglecomments (void); -static void outputdots (void), courierize (void), bulletize (void); -static void do_fancy_stuff (void); -static int iscommand (string_type *, unsigned int); -static int copy_past_newline (string_type *, unsigned int, string_type *); -static void icopy_past_newline (void), kill_bogus_lines (void), indent (void); -static void get_stuff_in_command (void), swap (void), other_dup (void); -static void drop (void), idrop (void); -static void icatstr (void), skip_past_newline (void), internalmode (void); -static void maybecatstr (void); -static char *nextword (char *, char **); -dict_type *lookup_word (char *); -static void perform (void); -dict_type *newentry (char *); -unsigned int add_to_definition (dict_type *, stinst_type); -void add_intrinsic (char *, void (*)()); -void add_var (char *); -void compile (char *); -static void bang (void); -static void atsign (void); -static void hello (void); -static void stdout_ (void); -static void stderr_ (void); -static void print (void); -static void read_in (string_type *, FILE *); -static void usage (void); -static void chew_exit (void); -#endif - -static void DEFUN(exec,(word), - dict_type *word) -{ - pc = word->code; - while (*pc) - (*pc)(); -} -WORD(call) -{ - stinst_type *oldpc = pc; - dict_type *e; - e = (dict_type *)(pc [1]); - exec(e); - pc = oldpc + 2; - -} - -WORD(remchar) -{ - if (tos->write_idx) - tos->write_idx--; - pc++; -} - -static void -strip_trailing_newlines () -{ - while ((isspace (at (tos, tos->write_idx - 1)) - || at (tos, tos->write_idx - 1) == '\n') - && tos->write_idx > 0) - tos->write_idx--; - pc++; -} - -WORD(push_number) -{ - isp++; - icheck_range (); - pc++; - *isp = (long)(*pc); - pc++; -} - -WORD(push_text) -{ - tos++; - check_range (); - init_string(tos); - pc++; - cattext(tos,*((char **)pc)); - pc++; - -} - - -/* This function removes everything not inside comments starting on - the first char of the line from the string, also when copying - comments, removes blank space and leading *'s. - Blank lines are turned into one blank line. */ - -static void -DEFUN(remove_noncomments,(src,dst), - string_type *src AND - string_type *dst) -{ - unsigned int idx = 0; - - while (at(src,idx)) - { - /* Now see if we have a comment at the start of the line */ - if (at(src,idx) == '\n' - && at(src,idx+1) == '/' - && at(src,idx+2) == '*') - { - idx+=3; - - idx = skip_white_and_stars(src,idx); - - /* Remove leading dot */ - if (at(src, idx) == '.') - idx++; - - /* Copy to the end of the line, or till the end of the - comment */ - while (at(src, idx)) - { - if (at(src, idx) == '\n') - { - /* end of line, echo and scrape of leading blanks */ - if (at(src,idx +1) == '\n') - catchar(dst,'\n'); - catchar(dst,'\n'); - idx++; - idx = skip_white_and_stars(src, idx); - } - else if (at(src, idx) == '*' && at(src,idx+1) == '/') - { - idx +=2 ; - cattext(dst,"\nENDDD\n"); - break; - } - else - { - catchar(dst, at(src, idx)); - idx++; - } - } - } - else idx++; - } -} - -static void -print_stack_level () -{ - fprintf (stderr, "current string stack depth = %d, ", tos - stack); - fprintf (stderr, "current integer stack depth = %d\n", isp - istack); - pc++; -} - -/* turn: - foobar name(stuff); - into: - foobar - name PARAMS ((stuff)); - and a blank line. - */ - -static void -DEFUN_VOID(paramstuff) -{ - unsigned int openp; - unsigned int fname; - unsigned int idx; - string_type out; - init_string(&out); - - - /* make sure that it's not already param'd or proto'd */ - if(find(tos,"PARAMS") || find(tos,"PROTO") || !find(tos,"(")) { - catstr(&out,tos); - } - else - { - /* Find the open paren */ - for (openp = 0; at(tos, openp) != '(' && at(tos,openp); openp++) - ; - - fname = openp; - /* Step back to the fname */ - fname--; - while (fname && isspace(at(tos, fname))) - fname --; - while (fname && !isspace(at(tos,fname)) && at(tos,fname) != '*') - fname--; - - fname++; - - for (idx = 0; idx < fname; idx++) /* Output type */ - { - catchar(&out, at(tos,idx)); - } - - cattext(&out, "\n"); /* Insert a newline between type and fnname */ - - for (idx = fname; idx < openp; idx++) /* Output fnname */ - { - catchar(&out, at(tos,idx)); - } - - cattext(&out," PARAMS ("); - - while (at(tos,idx) && at(tos,idx) !=';') - { - catchar(&out, at(tos, idx)); - idx++; - } - cattext(&out,");\n\n"); - } - overwrite_string(tos, &out); - pc++; - -} - - - -/* turn {* - and *} into comments */ - -WORD(translatecomments) -{ - unsigned int idx = 0; - string_type out; - init_string(&out); - - while (at(tos, idx)) - { - if (at(tos,idx) == '{' && at(tos,idx+1) =='*') - { - cattext(&out,"/*"); - idx+=2; - } - else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') - { - cattext(&out,"*/"); - idx+=2; - } - else - { - catchar(&out, at(tos, idx)); - idx++; - } - } - - - overwrite_string(tos, &out); - - pc++; - -} - -/* turn everything not starting with a . into a comment */ - -WORD(manglecomments) -{ - unsigned int idx = 0; - string_type out; - init_string(&out); - - while (at(tos, idx)) - { - if (at(tos,idx) == '\n' && at(tos,idx+1) =='*') - { - cattext(&out," /*"); - idx+=2; - } - else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') - { - cattext(&out,"*/"); - idx+=2; - } - else - { - catchar(&out, at(tos, idx)); - idx++; - } - } - - - overwrite_string(tos, &out); - - pc++; - -} - -/* Mod tos so that only lines with leading dots remain */ -static void -DEFUN_VOID(outputdots) -{ - unsigned int idx = 0; - string_type out; - init_string(&out); - - while (at(tos, idx)) - { - if (at(tos, idx) == '\n' && at(tos, idx+1) == '.') - { - char c, c2; - idx += 2; - - while ((c = at(tos, idx)) && c != '\n') - { - if (c == '{' && at(tos,idx+1) =='*') - { - cattext(&out," /*"); - idx+=2; - } - else if (c == '*' && at(tos,idx+1) =='}') - { - cattext(&out,"*/"); - idx+=2; - } - else - { - catchar(&out, c); - idx++; - } - } - catchar(&out,'\n'); - } - else - { - idx++; - } - } - - overwrite_string(tos, &out); - pc++; - -} - -/* Find lines starting with . and | and put example around them on tos */ -WORD(courierize) -{ - string_type out; - unsigned int idx = 0; - int command = 0; - - init_string(&out); - - while (at(tos, idx)) - { - if (at(tos, idx) == '\n' - && (at(tos, idx +1 ) == '.' - || at(tos,idx+1) == '|')) - { - cattext(&out,"\n@example\n"); - do - { - idx += 2; - - while (at(tos, idx) && at(tos, idx)!='\n') - { - if (at(tos,idx)=='{' && at(tos,idx+1) =='*') - { - cattext(&out," /*"); - idx+=2; - } - else if (at(tos,idx)=='*' && at(tos,idx+1) =='}') - { - cattext(&out,"*/"); - idx+=2; - } - else if (at(tos,idx) == '{' && !command) - { - cattext(&out,"@{"); - idx++; - } - else if (at(tos,idx) == '}' && !command) - { - cattext(&out,"@}"); - idx++; - } - else - { - if (at(tos,idx) == '@') - command = 1; - else if (isspace(at(tos,idx)) || at(tos,idx) == '}') - command = 0; - catchar(&out, at(tos, idx)); - idx++; - } - - } - catchar(&out,'\n'); - } - while (at(tos, idx) == '\n' - && (at(tos, idx+1) == '.') - || (at(tos,idx+1) == '|')); - cattext(&out,"@end example"); - } - else - { - catchar(&out, at(tos, idx)); - idx++; - } - } - - overwrite_string(tos, &out); - pc++; - - -} - -/* Finds any lines starting with "o ", if there are any, then turns - on @itemize @bullet, and @items each of them. Then ends with @end - itemize, inplace at TOS*/ - - -WORD(bulletize) -{ - unsigned int idx = 0; - int on = 0; - string_type out; - init_string(&out); - - while (at(tos, idx)) { - if (at(tos, idx) == '@' && - at(tos, idx+1) == '*') - { - cattext(&out,"*"); - idx+=2; - } - -else - if (at(tos, idx) == '\n' && - at(tos, idx+1) == 'o' && - isspace(at(tos, idx +2))) - { - if (!on) - { - cattext(&out,"\n@itemize @bullet\n"); - on = 1; - - } - cattext(&out,"\n@item\n"); - idx+=3; - } - else - { - catchar(&out, at(tos, idx)); - if (on && at(tos, idx) == '\n' && - at(tos, idx+1) == '\n' && - at(tos, idx+2) != 'o') - { - cattext(&out, "@end itemize"); - on = 0; - } - idx++; - - } - } - if (on) - { - cattext(&out,"@end itemize\n"); - } - - delete_string(tos); - *tos = out; - pc++; - -} - -/* Turn <> into @code{foo} in place at TOS*/ - - -WORD(do_fancy_stuff) -{ - unsigned int idx = 0; - string_type out; - init_string(&out); - while (at(tos, idx)) - { - if (at(tos, idx) == '<' - && at(tos, idx+1) == '<' - && !isspace(at(tos,idx + 2))) - { - /* This qualifies as a << startup */ - idx +=2; - cattext(&out,"@code{"); - while(at(tos,idx) && - at(tos,idx) != '>' ) - { - catchar(&out, at(tos, idx)); - idx++; - - } - cattext(&out,"}"); - idx+=2; - } - else - { - catchar(&out, at(tos, idx)); - idx++; - } - } - delete_string(tos); - *tos = out; - pc++; - -} -/* A command is all upper case,and alone on a line */ -static int -DEFUN( iscommand,(ptr, idx), - string_type *ptr AND - unsigned int idx) -{ - unsigned int len = 0; - while (at(ptr,idx)) { - if (isupper(at(ptr,idx)) || at(ptr,idx) == ' ' || - at(ptr,idx) == '_') - { - len++; - idx++; - } - else if(at(ptr,idx) == '\n') - { - if (len > 3) return 1; - return 0; - } - else return 0; - } - return 0; - -} - - -DEFUN(copy_past_newline,(ptr, idx, dst), - string_type *ptr AND - unsigned int idx AND - string_type *dst) -{ - while (at(ptr, idx) && at(ptr, idx) != '\n') - { - catchar(dst, at(ptr, idx)); - idx++; - - } - catchar(dst, at(ptr, idx)); - idx++; - return idx; - -} - -WORD(icopy_past_newline) -{ - tos++; - check_range (); - init_string(tos); - idx = copy_past_newline(ptr, idx, tos); - pc++; -} - -/* indent - Take the string at the top of the stack, do some prettying */ - - -WORD(kill_bogus_lines) -{ - int sl ; - - int nl = 0; - int idx = 0; - int c; - int dot = 0 ; - - string_type out; - init_string(&out); - /* Drop leading nl */ - while (at(tos,idx) == '\n') - { - idx++; - } - c = idx; - - /* Find the last char */ - while (at(tos,idx)) - { - idx++; - } - - /* find the last non white before the nl */ - idx--; - - while (idx && isspace(at(tos,idx))) - idx--; - idx++; - - /* Copy buffer upto last char, but blank lines before and after - dots don't count */ - sl = 1; - - while (c < idx) - { - if (at(tos,c) == '\n' - && at(tos,c+1) == '\n' - && at(tos,c+2) == '.') - { - /* Ignore two newlines before a dot*/ - c++; - } - else if (at(tos,c) == '.' && sl) - { - /* remember that this line started with a dot */ - dot=2; - } - else if (at(tos,c) == '\n' - && at(tos,c+1) == '\n' - && dot) - { - c++; - /* Ignore two newlines when last line was dot */ - } - - catchar(&out, at(tos,c)); - if (at(tos,c) == '\n') - { - sl = 1; - - if (dot == 2)dot=1;else dot = 0; - } - - c++; - - } - - /* Append nl*/ - catchar(&out, '\n'); - pc++; - delete_string(tos); - *tos = out; - - -} - -WORD(indent) -{ - string_type out; - int tab = 0; - int idx = 0; - int ol =0; - init_string(&out); - while (at(tos,idx)) { - switch (at(tos,idx)) - { - case '\n': - cattext(&out,"\n"); - idx++; - if (tab) - { - cattext(&out," "); - } - ol = 0; - break; - case '(': - tab++; - if (ol == 0) - cattext(&out," "); - idx++; - cattext(&out,"("); - ol = 1; - break; - case ')': - tab--; - cattext(&out,")"); - idx++; - ol=1; - - break; - default: - catchar(&out,at(tos,idx)); - ol=1; - - idx++; - break; - } - } - - pc++; - delete_string(tos); - *tos = out; - -} - - -WORD(get_stuff_in_command) -{ - tos++; - check_range (); - init_string(tos); - - while (at(ptr, idx)) { - if (iscommand(ptr, idx)) break; - idx = copy_past_newline(ptr, idx, tos); - } - pc++; -} - -WORD(swap) -{ - string_type t; - - t = tos[0]; - tos[0] = tos[-1]; - tos[-1] =t; - pc++; - -} - -WORD(other_dup) -{ - tos++; - check_range (); - init_string(tos); - catstr(tos, tos-1); - pc++; -} - -WORD(drop) -{ - tos--; - check_range (); - pc++; -} - -WORD(idrop) -{ - isp--; - icheck_range (); - pc++; -} - -WORD(icatstr) -{ - tos--; - check_range (); - catstr(tos, tos+1); - delete_string(tos+1); - pc++; -} - -WORD(skip_past_newline) -{ - while (at(ptr,idx) - && at(ptr,idx) != '\n') - idx++; - idx++; - pc++; -} - - -WORD(internalmode) -{ - internal_mode = *(isp); - isp--; - icheck_range (); - pc++; -} - -WORD(maybecatstr) -{ - if (internal_wanted == internal_mode) - { - catstr(tos-1, tos); - } - delete_string(tos); - tos--; - check_range (); - pc++; -} - -char * -DEFUN(nextword,(string, word), - char *string AND - char **word) -{ - char *word_start; - int idx; - char *dst; - char *src; - - int length = 0; - - while (isspace(*string) || *string == '-') { - if (*string == '-') - { - while (*string && *string != '\n') - string++; - - } - else { - string++; - } - } - if (!*string) return 0; - - word_start = string; - if (*string == '"') - { - do - { - string++; - length++; - if (*string == '\\') - { - string += 2; - length += 2; - } - } - while (*string != '"'); - } - else - { - while (!isspace(*string)) - { - string++; - length++; - - } - } - - *word = malloc(length + 1); - - dst = *word; - src = word_start; - - - for (idx= 0; idx < length; idx++) - { - if (src[idx] == '\\') - switch (src[idx+1]) - { - case 'n': - *dst++ = '\n'; - idx++; - break; - case '"': - case '\\': - *dst++ = src[idx+1]; - idx++; - break; - default: - *dst++ = '\\'; - break; - } - else - *dst++ = src[idx]; - } - *dst++ = 0; - - - - - - if(*string) - return string + 1; - else - return 0; - -} -dict_type *root; -dict_type * -DEFUN(lookup_word,(word), - char *word) -{ - dict_type *ptr = root; - while (ptr) { - if (strcmp(ptr->word, word) == 0) return ptr; - ptr = ptr->next; - - } - if (warning) - fprintf(stderr,"Can't find %s\n",word); - return 0; - - -} - -static void DEFUN_VOID(perform) -{ - tos = stack; - - while (at(ptr, idx)) { - /* It's worth looking through the command list */ - if (iscommand(ptr, idx)) - { - unsigned int i; - int found = 0; - - char *next; - dict_type *word ; - - (void) nextword(addr(ptr, idx), &next); - - - word = lookup_word(next); - - - - - if (word) - { - exec(word); - } - else - { - if (warning) - fprintf(stderr,"warning, %s is not recognised\n", next); - skip_past_newline(); - } - - } - else skip_past_newline(); - - } -} - -dict_type * -DEFUN(newentry,(word), - char *word) -{ - dict_type *new = (dict_type *)malloc(sizeof(dict_type)); - new->word = word; - new->next = root; - root = new; - new->code = (stinst_type *)malloc(sizeof(stinst_type )); - new->code_length = 1; - new->code_end = 0; - return new; - -} - - -unsigned int -DEFUN(add_to_definition,(entry, word), - dict_type *entry AND - stinst_type word) -{ - if (entry->code_end == entry->code_length) - { - entry->code_length += 2; - entry->code = - (stinst_type *) realloc((char *)(entry->code), - entry->code_length *sizeof(word_type)); - } - entry->code[entry->code_end] = word; - -return entry->code_end++; -} - - - - - - - -void -DEFUN(add_intrinsic,(name, func), - char *name AND - void (*func)()) -{ - dict_type *new = newentry(name); - add_to_definition(new, func); - add_to_definition(new, 0); -} - -void -DEFUN(add_var,(name), - char *name) -{ - dict_type *new = newentry(name); - add_to_definition(new, push_number); - add_to_definition(new, (stinst_type)(&(new->var))); - add_to_definition(new,0); -} - - -void -DEFUN(compile, (string), - char *string) -{ - int jstack[STACK]; - int *jptr = jstack; - /* add words to the dictionary */ - char *word; - string = nextword(string, &word); - while (string && *string && word[0]) - { - if (strcmp(word,"var")==0) - { - string=nextword(string, &word); - - add_var(word); - string=nextword(string, &word); - } -else - - if (word[0] == ':') - { - dict_type *ptr; - /* Compile a word and add to dictionary */ - string = nextword(string, &word); - - ptr = newentry(word); - string = nextword(string, &word); - while (word[0] != ';' ) - { - switch (word[0]) - { - case '"': - /* got a string, embed magic push string - function */ - add_to_definition(ptr, push_text); - add_to_definition(ptr, (stinst_type)(word+1)); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* Got a number, embedd the magic push number - function */ - add_to_definition(ptr, push_number); - add_to_definition(ptr, (stinst_type)atol(word)); - break; - default: - add_to_definition(ptr, call); - add_to_definition(ptr, (stinst_type)lookup_word(word)); - } - - string = nextword(string, &word); - } - add_to_definition(ptr,0); - string = nextword(string, &word); - } - else - { - fprintf(stderr,"syntax error at %s\n",string-1); - } - } - -} - - -static void DEFUN_VOID(bang) -{ - *(long *)((isp[0])) = isp[-1]; - isp-=2; - icheck_range (); - pc++; -} - -WORD(atsign) -{ - isp[0] = *(long *)(isp[0]); - pc++; -} - -WORD(hello) -{ - printf("hello\n"); - pc++; -} - -WORD(stdout_) -{ - isp++; - icheck_range (); - *isp = 1; - pc++; -} - -WORD(stderr_) -{ - isp++; - icheck_range (); - *isp = 2; - pc++; -} - -WORD(print) -{ - if (*isp == 1) - write_buffer (tos, stdout); - else if (*isp == 2) - write_buffer (tos, stderr); - else - fprintf (stderr, "print: illegal print destination `%d'\n", *isp); - isp--; - tos--; - icheck_range (); - check_range (); - pc++; -} - - -static void DEFUN(read_in, (str, file), - string_type *str AND - FILE *file) -{ - char buff[10000]; - unsigned int r; - do - { - r = fread(buff, 1, sizeof(buff), file); - catbuf(str, buff, r); - } - while (r); - buff[0] = 0; - - catbuf(str, buff,1); -} - - -static void DEFUN_VOID(usage) -{ - fprintf(stderr,"usage: -[d|i|g] file\n"); - exit(33); -} - -/* There is no reliable way to declare exit. Sometimes it returns - int, and sometimes it returns void. Sometimes it changes between - OS releases. Trying to get it declared correctly in the hosts file - is a pointless waste of time. */ - -static void -chew_exit () -{ - exit (0); -} - -int DEFUN(main,(ac,av), -int ac AND -char *av[]) -{ - unsigned int i; - string_type buffer; - string_type pptr; - - init_string(&buffer); - init_string(&pptr); - init_string(stack+0); - tos=stack+1; - ptr = &pptr; - - add_intrinsic("push_text", push_text); - add_intrinsic("!", bang); - add_intrinsic("@", atsign); - add_intrinsic("hello",hello); - add_intrinsic("stdout",stdout_); - add_intrinsic("stderr",stderr_); - add_intrinsic("print",print); - add_intrinsic("skip_past_newline", skip_past_newline ); - add_intrinsic("catstr", icatstr ); - add_intrinsic("copy_past_newline", icopy_past_newline ); - add_intrinsic("dup", other_dup ); - add_intrinsic("drop", drop); - add_intrinsic("idrop", idrop); - add_intrinsic("remchar", remchar ); - add_intrinsic("get_stuff_in_command", get_stuff_in_command ); - add_intrinsic("do_fancy_stuff", do_fancy_stuff ); - add_intrinsic("bulletize", bulletize ); - add_intrinsic("courierize", courierize ); - /* If the following line gives an error, exit() is not declared in the - ../hosts/foo.h file for this host. Fix it there, not here! */ - /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */ - add_intrinsic("exit", chew_exit ); - add_intrinsic("swap", swap ); - add_intrinsic("outputdots", outputdots ); - add_intrinsic("paramstuff", paramstuff ); - add_intrinsic("maybecatstr", maybecatstr ); - add_intrinsic("translatecomments", translatecomments ); - add_intrinsic("kill_bogus_lines", kill_bogus_lines); - add_intrinsic("indent", indent); - add_intrinsic("internalmode", internalmode); - add_intrinsic("print_stack_level", print_stack_level); - add_intrinsic("strip_trailing_newlines", strip_trailing_newlines); - - /* Put a nl at the start */ - catchar(&buffer,'\n'); - - read_in(&buffer, stdin); - remove_noncomments(&buffer, ptr); - for (i= 1; i < ac; i++) - { - if (av[i][0] == '-') - { - if (av[i][1] == 'f') - { - string_type b; - FILE *f; - init_string(&b); - - f = fopen(av[i+1],"r"); - if (!f) - { - fprintf(stderr,"Can't open the input file %s\n",av[i+1]); - return 33; - } - - read_in(&b, f); - compile(b.ptr); - perform(); - } - else if (av[i][1] == 'i') - { - internal_wanted = 1; - } - else if (av[i][1] == 'w') - { - warning = 1; - } - } - } - write_buffer(stack+0, stdout); - if (tos != stack) - { - fprintf (stderr, "finishing with current stack level %d\n", tos - stack); - return 1; - } - return 0; -} diff --git a/contrib/gdb/bfd/doc/doc.str b/contrib/gdb/bfd/doc/doc.str deleted file mode 100644 index 93685996e06..00000000000 --- a/contrib/gdb/bfd/doc/doc.str +++ /dev/null @@ -1,158 +0,0 @@ -: DOCDD - skip_past_newline - get_stuff_in_command kill_bogus_lines catstr - ; - -: ENDDD - skip_past_newline - ; - -: EXAMPLE - skip_past_newline - get_stuff_in_command kill_bogus_lines do_fancy_stuff translatecomments - courierize catstr - - ; - -: INODE - "@node " catstr skip_past_newline copy_past_newline catstr - ; - -: CODE_FRAGMENT - EXAMPLE - ; - -: COMMENT - skip_past_newline - get_stuff_in_command - drop - ; - -: SYNOPSIS - skip_past_newline - "@strong{Synopsis}\n" catstr - "@example\n" catstr - get_stuff_in_command - kill_bogus_lines - indent - catstr - "@end example\n" catstr - - ; - -: func - "@findex " - a - skip_past_newline - copy_past_newline - dup - a x x - "@subsubsection @code{" - a x x b - swap - remchar - "}\n" - a x b x c - catstr catstr catstr catstr catstr - ; - -: FUNCTION - "@findex " - a - skip_past_newline - copy_past_newline - dup - a x x - "@subsubsection @code{" - a x x b - swap - remchar - "}\n" - a x b x c - catstr catstr catstr catstr catstr - ; - -: bodytext - get_stuff_in_command - bulletize - kill_bogus_lines - do_fancy_stuff - courierize - catstr - "@*\n" catstr - ; - -: asection - skip_past_newline - catstr - copy_past_newline - do_fancy_stuff catstr - bodytext - ; - -: SECTION - "@section " asection ; - -: SUBSECTION - "@subsection " asection ; - -: SUBSUBSECTION - "@subsubsection " asection ; - -: subhead - skip_past_newline - bodytext - ; - - - - -: DESCRIPTION - "@strong{Description}@*\n" catstr subhead ; - -: RETURNS - "@strong{Returns}@*\n" catstr subhead ; - -: INTERNAL_FUNCTION - func ; - - -: INTERNAL_DEFINITION - func ; - - -: INTERNAL - func ; - -: TYPEDEF - FUNCTION ; - -: SENUM - skip_past_newline - "Here are the possible values for @code{enum " - copy_past_newline remchar catstr - "}:\n\n" catstr catstr - ; -: ENUM - skip_past_newline - "@deffn {} " - copy_past_newline catstr catstr - ; -: ENUMX - skip_past_newline - "@deffnx {} " - copy_past_newline catstr - catstr - ; -: ENUMEQ - skip_past_newline - "@deffn {} " - copy_past_newline catstr catstr - skip_past_newline - ; -: ENUMEQX - skip_past_newline - "@deffnx {} " - copy_past_newline catstr - catstr - skip_past_newline - ; -: ENUMDOC - skip_past_newline - get_stuff_in_command - strip_trailing_newlines - catstr - "\n@end deffn\n" catstr - ; diff --git a/contrib/gdb/bfd/doc/proto.str b/contrib/gdb/bfd/doc/proto.str deleted file mode 100644 index 8431c16bd57..00000000000 --- a/contrib/gdb/bfd/doc/proto.str +++ /dev/null @@ -1,135 +0,0 @@ - -: SYNOPSIS - skip_past_newline - get_stuff_in_command - paramstuff - indent - maybecatstr -; - -: ignore - skip_past_newline - get_stuff_in_command - outputdots - maybecatstr - ; - -: CODE_FRAGMENT - ignore ; - -: external - 0 internalmode ignore ; - -: internal - 1 internalmode ignore ; - -- input stack { a b } output b if internal, a if external -: ifinternal - "" swap 1 internalmode maybecatstr - swap - "" swap 0 internalmode maybecatstr - catstr - ; - -- Put note in output string, regardless of internal mode. -: COMMENT - skip_past_newline - get_stuff_in_command - translatecomments - catstr - ; - -- SENUM enum-type-name -- ENUM enum-name -- ENUMX addl-enum-name -- ENUMDOC doc for preceding enums -- ENDSENUM max-enum-name - -: make_enum_header - dup - "enum " swap catstr - " {\n" catstr - swap " _dummy_first_" swap catstr catstr - ",\n" catstr - ; -: make_string_table_header - dup - "#ifdef _BFD_MAKE_TABLE_" swap catstr swap - "\n\nstatic const char *const " swap catstr catstr - "_names[] = { \"@@uninitialized@@\",\n" catstr - ; -: SENUM - skip_past_newline - copy_past_newline - remchar - dup - make_enum_header - swap - make_string_table_header - ifinternal - catstr - get_stuff_in_command catstr - translatecomments ; -: ENDSENUM - skip_past_newline - copy_past_newline strip_trailing_newlines - dup - " " swap catstr " };\n" catstr swap - " \"@@overflow: " swap catstr "@@\",\n};\n#endif\n\n" catstr - ifinternal - catstr - ; -: make_enumerator - " " swap catstr - ",\n" catstr - ; -: make_enumerator_string - " \"" swap catstr - "\",\n" catstr - ; -: ENUM - skip_past_newline - copy_past_newline - remchar - dup - make_enumerator - swap - make_enumerator_string - ifinternal - ; -: ENUMX ENUM catstr ; -: ENUMEQ - skip_past_newline - "#define " - copy_past_newline remchar - catstr - " " - catstr - copy_past_newline - catstr - "" swap 0 internalmode maybecatstr - ; -: ENUMEQX ENUMEQ catstr ; -: ENUMDOC - skip_past_newline - get_stuff_in_command - strip_trailing_newlines - "\n{* " swap catstr " *}\n" catstr - translatecomments - - discard it if we're doing internal mode - "" swap 0 internalmode maybecatstr - swap - catstr catstr - ; -: ENDDD external ; -: SECTION ignore ; -: SUBSECTION ignore ; -: SUBSUBSECTION ignore ; -: INTERNAL_DEFINITION internal ; -: DESCRIPTION ignore ; -: FUNCTION external ; -: RETURNS ignore ; -: TYPEDEF external ; -: INTERNAL_FUNCTION internal ; -: INTERNAL internal ; -: INODE ignore ; diff --git a/contrib/gdb/bfd/ecoff.c b/contrib/gdb/bfd/ecoff.c deleted file mode 100644 index e219ff77a23..00000000000 --- a/contrib/gdb/bfd/ecoff.c +++ /dev/null @@ -1,4740 +0,0 @@ -/* Generic ECOFF (Extended-COFF) routines. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Original version by Per Bothner. - Full support added by Ian Lance Taylor, ian@cygnus.com. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "aout/ar.h" -#include "aout/ranlib.h" -#include "aout/stab_gnu.h" - -/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines - some other stuff which we don't want and which conflicts with stuff - we do want. */ -#include "libaout.h" -#include "aout/aout64.h" -#undef N_ABS -#undef exec_hdr -#undef obj_sym_filepos - -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" -#include "libcoff.h" -#include "libecoff.h" - -/* Prototypes for static functions. */ - -static int ecoff_get_magic PARAMS ((bfd *abfd)); -static long ecoff_sec_to_styp_flags PARAMS ((const char *name, - flagword flags)); -static boolean ecoff_slurp_symbolic_header PARAMS ((bfd *abfd)); -static boolean ecoff_set_symbol_info PARAMS ((bfd *abfd, SYMR *ecoff_sym, - asymbol *asym, int ext, int weak)); -static void ecoff_emit_aggregate PARAMS ((bfd *abfd, FDR *fdr, - char *string, - RNDXR *rndx, long isym, - const char *which)); -static char *ecoff_type_to_string PARAMS ((bfd *abfd, FDR *fdr, - unsigned int indx)); -static boolean ecoff_slurp_reloc_table PARAMS ((bfd *abfd, asection *section, - asymbol **symbols)); -static int ecoff_sort_hdrs PARAMS ((const PTR, const PTR)); -static boolean ecoff_compute_section_file_positions PARAMS ((bfd *abfd)); -static bfd_size_type ecoff_compute_reloc_file_positions PARAMS ((bfd *abfd)); -static boolean ecoff_get_extr PARAMS ((asymbol *, EXTR *)); -static void ecoff_set_index PARAMS ((asymbol *, bfd_size_type)); -static unsigned int ecoff_armap_hash PARAMS ((CONST char *s, - unsigned int *rehash, - unsigned int size, - unsigned int hlog)); - -/* This stuff is somewhat copied from coffcode.h. */ - -static asection bfd_debug_section = { "*DEBUG*" }; - -/* Create an ECOFF object. */ - -boolean -_bfd_ecoff_mkobject (abfd) - bfd *abfd; -{ - abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *) - bfd_zalloc (abfd, sizeof (ecoff_data_type))); - if (abfd->tdata.ecoff_obj_data == NULL) - return false; - - return true; -} - -/* This is a hook called by coff_real_object_p to create any backend - specific information. */ - -PTR -_bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr) - bfd *abfd; - PTR filehdr; - PTR aouthdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr; - ecoff_data_type *ecoff; - - if (_bfd_ecoff_mkobject (abfd) == false) - return NULL; - - ecoff = ecoff_data (abfd); - ecoff->gp_size = 8; - ecoff->sym_filepos = internal_f->f_symptr; - - if (internal_a != (struct internal_aouthdr *) NULL) - { - int i; - - ecoff->text_start = internal_a->text_start; - ecoff->text_end = internal_a->text_start + internal_a->tsize; - ecoff->gp = internal_a->gp_value; - ecoff->gprmask = internal_a->gprmask; - for (i = 0; i < 4; i++) - ecoff->cprmask[i] = internal_a->cprmask[i]; - ecoff->fprmask = internal_a->fprmask; - if (internal_a->magic == ECOFF_AOUT_ZMAGIC) - abfd->flags |= D_PAGED; - else - abfd->flags &=~ D_PAGED; - } - - /* It turns out that no special action is required by the MIPS or - Alpha ECOFF backends. They have different information in the - a.out header, but we just copy it all (e.g., gprmask, cprmask and - fprmask) and let the swapping routines ensure that only relevant - information is written out. */ - - return (PTR) ecoff; -} - -/* Initialize a new section. */ - -boolean -_bfd_ecoff_new_section_hook (abfd, section) - bfd *abfd; - asection *section; -{ - /* For the .pdata section, which has a special meaning on the Alpha, - we set the alignment power to 3. We correct this later in - ecoff_compute_section_file_positions. We do this hackery because - we need to know the exact unaligned size of the .pdata section in - order to set the lnnoptr field correctly. For every other - section we use an alignment power of 4; this could be made target - dependent by adding a field to ecoff_backend_data, but 4 appears - to be correct for both the MIPS and the Alpha. */ - if (strcmp (section->name, _PDATA) == 0) - section->alignment_power = 3; - else - section->alignment_power = 4; - - if (strcmp (section->name, _TEXT) == 0) - section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; - else if (strcmp (section->name, _DATA) == 0 - || strcmp (section->name, _SDATA) == 0) - section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; - else if (strcmp (section->name, _RDATA) == 0 - || strcmp (section->name, _LIT8) == 0 - || strcmp (section->name, _LIT4) == 0 - || strcmp (section->name, _RCONST) == 0) - section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; - else if (strcmp (section->name, _BSS) == 0 - || strcmp (section->name, _SBSS) == 0) - section->flags |= SEC_ALLOC; - else if (strcmp (section->name, _LIB) == 0) - { - /* An Irix 4 shared libary. */ - section->flags |= SEC_COFF_SHARED_LIBRARY; - } - - /* Probably any other section name is SEC_NEVER_LOAD, but I'm - uncertain about .init on some systems and I don't know how shared - libraries work. */ - - return true; -} - -/* Determine the machine architecture and type. This is called from - the generic COFF routines. It is the inverse of ecoff_get_magic, - below. This could be an ECOFF backend routine, with one version - for each target, but there aren't all that many ECOFF targets. */ - -boolean -_bfd_ecoff_set_arch_mach_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - enum bfd_architecture arch; - unsigned long mach; - - switch (internal_f->f_magic) - { - case MIPS_MAGIC_1: - case MIPS_MAGIC_LITTLE: - case MIPS_MAGIC_BIG: - arch = bfd_arch_mips; - mach = 3000; - break; - - case MIPS_MAGIC_LITTLE2: - case MIPS_MAGIC_BIG2: - /* MIPS ISA level 2: the r6000 */ - arch = bfd_arch_mips; - mach = 6000; - break; - - case MIPS_MAGIC_LITTLE3: - case MIPS_MAGIC_BIG3: - /* MIPS ISA level 3: the r4000 */ - arch = bfd_arch_mips; - mach = 4000; - break; - - case ALPHA_MAGIC: - arch = bfd_arch_alpha; - mach = 0; - break; - - default: - arch = bfd_arch_obscure; - mach = 0; - break; - } - - return bfd_default_set_arch_mach (abfd, arch, mach); -} - -/* Get the magic number to use based on the architecture and machine. - This is the inverse of _bfd_ecoff_set_arch_mach_hook, above. */ - -static int -ecoff_get_magic (abfd) - bfd *abfd; -{ - int big, little; - - switch (bfd_get_arch (abfd)) - { - case bfd_arch_mips: - switch (bfd_get_mach (abfd)) - { - default: - case 0: - case 3000: - big = MIPS_MAGIC_BIG; - little = MIPS_MAGIC_LITTLE; - break; - - case 6000: - big = MIPS_MAGIC_BIG2; - little = MIPS_MAGIC_LITTLE2; - break; - - case 4000: - big = MIPS_MAGIC_BIG3; - little = MIPS_MAGIC_LITTLE3; - break; - } - - return bfd_big_endian (abfd) ? big : little; - - case bfd_arch_alpha: - return ALPHA_MAGIC; - - default: - abort (); - return 0; - } -} - -/* Get the section s_flags to use for a section. */ - -static long -ecoff_sec_to_styp_flags (name, flags) - const char *name; - flagword flags; -{ - long styp; - - styp = 0; - - if (strcmp (name, _TEXT) == 0) - styp = STYP_TEXT; - else if (strcmp (name, _DATA) == 0) - styp = STYP_DATA; - else if (strcmp (name, _SDATA) == 0) - styp = STYP_SDATA; - else if (strcmp (name, _RDATA) == 0) - styp = STYP_RDATA; - else if (strcmp (name, _LITA) == 0) - styp = STYP_LITA; - else if (strcmp (name, _LIT8) == 0) - styp = STYP_LIT8; - else if (strcmp (name, _LIT4) == 0) - styp = STYP_LIT4; - else if (strcmp (name, _BSS) == 0) - styp = STYP_BSS; - else if (strcmp (name, _SBSS) == 0) - styp = STYP_SBSS; - else if (strcmp (name, _INIT) == 0) - styp = STYP_ECOFF_INIT; - else if (strcmp (name, _FINI) == 0) - styp = STYP_ECOFF_FINI; - else if (strcmp (name, _PDATA) == 0) - styp = STYP_PDATA; - else if (strcmp (name, _XDATA) == 0) - styp = STYP_XDATA; - else if (strcmp (name, _LIB) == 0) - styp = STYP_ECOFF_LIB; - else if (strcmp (name, _GOT) == 0) - styp = STYP_GOT; - else if (strcmp (name, _HASH) == 0) - styp = STYP_HASH; - else if (strcmp (name, _DYNAMIC) == 0) - styp = STYP_DYNAMIC; - else if (strcmp (name, _LIBLIST) == 0) - styp = STYP_LIBLIST; - else if (strcmp (name, _RELDYN) == 0) - styp = STYP_RELDYN; - else if (strcmp (name, _CONFLIC) == 0) - styp = STYP_CONFLIC; - else if (strcmp (name, _DYNSTR) == 0) - styp = STYP_DYNSTR; - else if (strcmp (name, _DYNSYM) == 0) - styp = STYP_DYNSYM; - else if (strcmp (name, _COMMENT) == 0) - { - styp = STYP_COMMENT; - flags &=~ SEC_NEVER_LOAD; - } - else if (strcmp (name, _RCONST) == 0) - styp = STYP_RCONST; - else if (flags & SEC_CODE) - styp = STYP_TEXT; - else if (flags & SEC_DATA) - styp = STYP_DATA; - else if (flags & SEC_READONLY) - styp = STYP_RDATA; - else if (flags & SEC_LOAD) - styp = STYP_REG; - else - styp = STYP_BSS; - - if (flags & SEC_NEVER_LOAD) - styp |= STYP_NOLOAD; - - return styp; -} - -/* Get the BFD flags to use for a section. */ - -/*ARGSUSED*/ -flagword -_bfd_ecoff_styp_to_sec_flags (abfd, hdr, name) - bfd *abfd; - PTR hdr; - const char *name; -{ - struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; - long styp_flags = internal_s->s_flags; - flagword sec_flags=0; - - if (styp_flags & STYP_NOLOAD) - sec_flags |= SEC_NEVER_LOAD; - - /* For 386 COFF, at least, an unloadable text or data section is - actually a shared library section. */ - if ((styp_flags & STYP_TEXT) - || (styp_flags & STYP_ECOFF_INIT) - || (styp_flags & STYP_ECOFF_FINI) - || (styp_flags & STYP_DYNAMIC) - || (styp_flags & STYP_LIBLIST) - || (styp_flags & STYP_RELDYN) - || styp_flags == STYP_CONFLIC - || (styp_flags & STYP_DYNSTR) - || (styp_flags & STYP_DYNSYM) - || (styp_flags & STYP_HASH)) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; - } - else if ((styp_flags & STYP_DATA) - || (styp_flags & STYP_RDATA) - || (styp_flags & STYP_SDATA) - || styp_flags == STYP_PDATA - || styp_flags == STYP_XDATA - || (styp_flags & STYP_GOT) - || styp_flags == STYP_RCONST) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; - if ((styp_flags & STYP_RDATA) - || styp_flags == STYP_PDATA - || styp_flags == STYP_RCONST) - sec_flags |= SEC_READONLY; - } - else if ((styp_flags & STYP_BSS) - || (styp_flags & STYP_SBSS)) - { - sec_flags |= SEC_ALLOC; - } - else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT) - { - sec_flags |= SEC_NEVER_LOAD; - } - else if ((styp_flags & STYP_LITA) - || (styp_flags & STYP_LIT8) - || (styp_flags & STYP_LIT4)) - { - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; - } - else if (styp_flags & STYP_ECOFF_LIB) - { - sec_flags |= SEC_COFF_SHARED_LIBRARY; - } - else - { - sec_flags |= SEC_ALLOC | SEC_LOAD; - } - - return sec_flags; -} - -/* Read in the symbolic header for an ECOFF object file. */ - -static boolean -ecoff_slurp_symbolic_header (abfd) - bfd *abfd; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - bfd_size_type external_hdr_size; - PTR raw = NULL; - HDRR *internal_symhdr; - - /* See if we've already read it in. */ - if (ecoff_data (abfd)->debug_info.symbolic_header.magic == - backend->debug_swap.sym_magic) - return true; - - /* See whether there is a symbolic header. */ - if (ecoff_data (abfd)->sym_filepos == 0) - { - bfd_get_symcount (abfd) = 0; - return true; - } - - /* At this point bfd_get_symcount (abfd) holds the number of symbols - as read from the file header, but on ECOFF this is always the - size of the symbolic information header. It would be cleaner to - handle this when we first read the file in coffgen.c. */ - external_hdr_size = backend->debug_swap.external_hdr_size; - if (bfd_get_symcount (abfd) != external_hdr_size) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Read the symbolic information header. */ - raw = (PTR) bfd_malloc ((size_t) external_hdr_size); - if (raw == NULL) - goto error_return; - - if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) == -1 - || (bfd_read (raw, external_hdr_size, 1, abfd) - != external_hdr_size)) - goto error_return; - internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; - (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr); - - if (internal_symhdr->magic != backend->debug_swap.sym_magic) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - /* Now we can get the correct number of symbols. */ - bfd_get_symcount (abfd) = (internal_symhdr->isymMax - + internal_symhdr->iextMax); - - if (raw != NULL) - free (raw); - return true; - error_return: - if (raw != NULL) - free (raw); - return false; -} - -/* Read in and swap the important symbolic information for an ECOFF - object file. This is called by gdb via the read_debug_info entry - point in the backend structure. */ - -/*ARGSUSED*/ -boolean -_bfd_ecoff_slurp_symbolic_info (abfd, ignore, debug) - bfd *abfd; - asection *ignore; - struct ecoff_debug_info *debug; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - HDRR *internal_symhdr; - bfd_size_type raw_base; - bfd_size_type raw_size; - PTR raw; - bfd_size_type external_fdr_size; - char *fraw_src; - char *fraw_end; - struct fdr *fdr_ptr; - bfd_size_type raw_end; - bfd_size_type cb_end; - - BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info); - - /* Check whether we've already gotten it, and whether there's any to - get. */ - if (ecoff_data (abfd)->raw_syments != (PTR) NULL) - return true; - if (ecoff_data (abfd)->sym_filepos == 0) - { - bfd_get_symcount (abfd) = 0; - return true; - } - - if (! ecoff_slurp_symbolic_header (abfd)) - return false; - - internal_symhdr = &debug->symbolic_header; - - /* Read all the symbolic information at once. */ - raw_base = (ecoff_data (abfd)->sym_filepos - + backend->debug_swap.external_hdr_size); - - /* Alpha ecoff makes the determination of raw_size difficult. It has - an undocumented debug data section between the symhdr and the first - documented section. And the ordering of the sections varies between - statically and dynamically linked executables. - If bfd supports SEEK_END someday, this code could be simplified. */ - - raw_end = 0; - -#define UPDATE_RAW_END(start, count, size) \ - cb_end = internal_symhdr->start + internal_symhdr->count * (size); \ - if (cb_end > raw_end) \ - raw_end = cb_end - - UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char)); - UPDATE_RAW_END (cbDnOffset, idnMax, backend->debug_swap.external_dnr_size); - UPDATE_RAW_END (cbPdOffset, ipdMax, backend->debug_swap.external_pdr_size); - UPDATE_RAW_END (cbSymOffset, isymMax, backend->debug_swap.external_sym_size); - UPDATE_RAW_END (cbOptOffset, ioptMax, backend->debug_swap.external_opt_size); - UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext)); - UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char)); - UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char)); - UPDATE_RAW_END (cbFdOffset, ifdMax, backend->debug_swap.external_fdr_size); - UPDATE_RAW_END (cbRfdOffset, crfd, backend->debug_swap.external_rfd_size); - UPDATE_RAW_END (cbExtOffset, iextMax, backend->debug_swap.external_ext_size); - -#undef UPDATE_RAW_END - - raw_size = raw_end - raw_base; - if (raw_size == 0) - { - ecoff_data (abfd)->sym_filepos = 0; - return true; - } - raw = (PTR) bfd_alloc (abfd, raw_size); - if (raw == NULL) - return false; - if (bfd_seek (abfd, - (ecoff_data (abfd)->sym_filepos - + backend->debug_swap.external_hdr_size), - SEEK_SET) != 0 - || bfd_read (raw, raw_size, 1, abfd) != raw_size) - { - bfd_release (abfd, raw); - return false; - } - - ecoff_data (abfd)->raw_syments = raw; - - /* Get pointers for the numeric offsets in the HDRR structure. */ -#define FIX(off1, off2, type) \ - if (internal_symhdr->off1 == 0) \ - debug->off2 = (type) NULL; \ - else \ - debug->off2 = (type) ((char *) raw \ - + (internal_symhdr->off1 \ - - raw_base)) - FIX (cbLineOffset, line, unsigned char *); - FIX (cbDnOffset, external_dnr, PTR); - FIX (cbPdOffset, external_pdr, PTR); - FIX (cbSymOffset, external_sym, PTR); - FIX (cbOptOffset, external_opt, PTR); - FIX (cbAuxOffset, external_aux, union aux_ext *); - FIX (cbSsOffset, ss, char *); - FIX (cbSsExtOffset, ssext, char *); - FIX (cbFdOffset, external_fdr, PTR); - FIX (cbRfdOffset, external_rfd, PTR); - FIX (cbExtOffset, external_ext, PTR); -#undef FIX - - /* I don't want to always swap all the data, because it will just - waste time and most programs will never look at it. The only - time the linker needs most of the debugging information swapped - is when linking big-endian and little-endian MIPS object files - together, which is not a common occurrence. - - We need to look at the fdr to deal with a lot of information in - the symbols, so we swap them here. */ - debug->fdr = (struct fdr *) bfd_alloc (abfd, - (internal_symhdr->ifdMax * - sizeof (struct fdr))); - if (debug->fdr == NULL) - return false; - external_fdr_size = backend->debug_swap.external_fdr_size; - fdr_ptr = debug->fdr; - fraw_src = (char *) debug->external_fdr; - fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size; - for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) - (*backend->debug_swap.swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); - - return true; -} - -/* ECOFF symbol table routines. The ECOFF symbol table is described - in gcc/mips-tfile.c. */ - -/* ECOFF uses two common sections. One is the usual one, and the - other is for small objects. All the small objects are kept - together, and then referenced via the gp pointer, which yields - faster assembler code. This is what we use for the small common - section. */ -static asection ecoff_scom_section; -static asymbol ecoff_scom_symbol; -static asymbol *ecoff_scom_symbol_ptr; - -/* Create an empty symbol. */ - -asymbol * -_bfd_ecoff_make_empty_symbol (abfd) - bfd *abfd; -{ - ecoff_symbol_type *new; - - new = (ecoff_symbol_type *) bfd_alloc (abfd, sizeof (ecoff_symbol_type)); - if (new == (ecoff_symbol_type *) NULL) - return (asymbol *) NULL; - memset ((PTR) new, 0, sizeof *new); - new->symbol.section = (asection *) NULL; - new->fdr = (FDR *) NULL; - new->local = false; - new->native = NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/* Set the BFD flags and section for an ECOFF symbol. */ - -static boolean -ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, weak) - bfd *abfd; - SYMR *ecoff_sym; - asymbol *asym; - int ext; - int weak; -{ - asym->the_bfd = abfd; - asym->value = ecoff_sym->value; - asym->section = &bfd_debug_section; - asym->udata.i = 0; - - /* Most symbol types are just for debugging. */ - switch (ecoff_sym->st) - { - case stGlobal: - case stStatic: - case stLabel: - case stProc: - case stStaticProc: - break; - case stNil: - if (ECOFF_IS_STAB (ecoff_sym)) - { - asym->flags = BSF_DEBUGGING; - return true; - } - break; - default: - asym->flags = BSF_DEBUGGING; - return true; - } - - if (weak) - asym->flags = BSF_EXPORT | BSF_WEAK; - else if (ext) - asym->flags = BSF_EXPORT | BSF_GLOBAL; - else - { - asym->flags = BSF_LOCAL; - /* Normally, a local stProc symbol will have a corresponding - external symbol. We mark the local symbol as a debugging - symbol, in order to prevent nm from printing both out. - Similarly, we mark stLabel and stabs symbols as debugging - symbols. In both cases, we do want to set the value - correctly based on the symbol class. */ - if (ecoff_sym->st == stProc - || ecoff_sym->st == stLabel - || ECOFF_IS_STAB (ecoff_sym)) - asym->flags |= BSF_DEBUGGING; - } - switch (ecoff_sym->sc) - { - case scNil: - /* Used for compiler generated labels. Leave them in the - debugging section, and mark them as local. If BSF_DEBUGGING - is set, then nm does not display them for some reason. If no - flags are set then the linker whines about them. */ - asym->flags = BSF_LOCAL; - break; - case scText: - asym->section = bfd_make_section_old_way (abfd, ".text"); - asym->value -= asym->section->vma; - break; - case scData: - asym->section = bfd_make_section_old_way (abfd, ".data"); - asym->value -= asym->section->vma; - break; - case scBss: - asym->section = bfd_make_section_old_way (abfd, ".bss"); - asym->value -= asym->section->vma; - break; - case scRegister: - asym->flags = BSF_DEBUGGING; - break; - case scAbs: - asym->section = bfd_abs_section_ptr; - break; - case scUndefined: - asym->section = bfd_und_section_ptr; - asym->flags = 0; - asym->value = 0; - break; - case scCdbLocal: - case scBits: - case scCdbSystem: - case scRegImage: - case scInfo: - case scUserStruct: - asym->flags = BSF_DEBUGGING; - break; - case scSData: - asym->section = bfd_make_section_old_way (abfd, ".sdata"); - asym->value -= asym->section->vma; - break; - case scSBss: - asym->section = bfd_make_section_old_way (abfd, ".sbss"); - asym->value -= asym->section->vma; - break; - case scRData: - asym->section = bfd_make_section_old_way (abfd, ".rdata"); - asym->value -= asym->section->vma; - break; - case scVar: - asym->flags = BSF_DEBUGGING; - break; - case scCommon: - if (asym->value > ecoff_data (abfd)->gp_size) - { - asym->section = bfd_com_section_ptr; - asym->flags = 0; - break; - } - /* Fall through. */ - case scSCommon: - if (ecoff_scom_section.name == NULL) - { - /* Initialize the small common section. */ - ecoff_scom_section.name = SCOMMON; - ecoff_scom_section.flags = SEC_IS_COMMON; - ecoff_scom_section.output_section = &ecoff_scom_section; - ecoff_scom_section.symbol = &ecoff_scom_symbol; - ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr; - ecoff_scom_symbol.name = SCOMMON; - ecoff_scom_symbol.flags = BSF_SECTION_SYM; - ecoff_scom_symbol.section = &ecoff_scom_section; - ecoff_scom_symbol_ptr = &ecoff_scom_symbol; - } - asym->section = &ecoff_scom_section; - asym->flags = 0; - break; - case scVarRegister: - case scVariant: - asym->flags = BSF_DEBUGGING; - break; - case scSUndefined: - asym->section = bfd_und_section_ptr; - asym->flags = 0; - asym->value = 0; - break; - case scInit: - asym->section = bfd_make_section_old_way (abfd, ".init"); - asym->value -= asym->section->vma; - break; - case scBasedVar: - case scXData: - case scPData: - asym->flags = BSF_DEBUGGING; - break; - case scFini: - asym->section = bfd_make_section_old_way (abfd, ".fini"); - asym->value -= asym->section->vma; - break; - case scRConst: - asym->section = bfd_make_section_old_way (abfd, ".rconst"); - asym->value -= asym->section->vma; - break; - default: - break; - } - - /* Look for special constructors symbols and make relocation entries - in a special construction section. These are produced by the - -fgnu-linker argument to g++. */ - if (ECOFF_IS_STAB (ecoff_sym)) - { - switch (ECOFF_UNMARK_STAB (ecoff_sym->index)) - { - default: - break; - - case N_SETA: - case N_SETT: - case N_SETD: - case N_SETB: - { - const char *name; - asection *section; - arelent_chain *reloc_chain; - unsigned int bitsize; - - /* Get a section with the same name as the symbol (usually - __CTOR_LIST__ or __DTOR_LIST__). FIXME: gcc uses the - name ___CTOR_LIST (three underscores). We need - __CTOR_LIST (two underscores), since ECOFF doesn't use - a leading underscore. This should be handled by gcc, - but instead we do it here. Actually, this should all - be done differently anyhow. */ - name = bfd_asymbol_name (asym); - if (name[0] == '_' && name[1] == '_' && name[2] == '_') - { - ++name; - asym->name = name; - } - section = bfd_get_section_by_name (abfd, name); - if (section == (asection *) NULL) - { - char *copy; - - copy = (char *) bfd_alloc (abfd, strlen (name) + 1); - if (!copy) - return false; - strcpy (copy, name); - section = bfd_make_section (abfd, copy); - } - - /* Build a reloc pointing to this constructor. */ - reloc_chain = - (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain)); - if (!reloc_chain) - return false; - reloc_chain->relent.sym_ptr_ptr = - bfd_get_section (asym)->symbol_ptr_ptr; - reloc_chain->relent.address = section->_raw_size; - reloc_chain->relent.addend = asym->value; - reloc_chain->relent.howto = - ecoff_backend (abfd)->constructor_reloc; - - /* Set up the constructor section to hold the reloc. */ - section->flags = SEC_CONSTRUCTOR; - ++section->reloc_count; - - /* Constructor sections must be rounded to a boundary - based on the bitsize. These are not real sections-- - they are handled specially by the linker--so the ECOFF - 16 byte alignment restriction does not apply. */ - bitsize = ecoff_backend (abfd)->constructor_bitsize; - section->alignment_power = 1; - while ((1 << section->alignment_power) < bitsize / 8) - ++section->alignment_power; - - reloc_chain->next = section->constructor_chain; - section->constructor_chain = reloc_chain; - section->_raw_size += bitsize / 8; - - /* Mark the symbol as a constructor. */ - asym->flags |= BSF_CONSTRUCTOR; - } - break; - } - } - return true; -} - -/* Read an ECOFF symbol table. */ - -boolean -_bfd_ecoff_slurp_symbol_table (abfd) - bfd *abfd; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - const bfd_size_type external_ext_size - = backend->debug_swap.external_ext_size; - const bfd_size_type external_sym_size - = backend->debug_swap.external_sym_size; - void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) - = backend->debug_swap.swap_ext_in; - void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) - = backend->debug_swap.swap_sym_in; - bfd_size_type internal_size; - ecoff_symbol_type *internal; - ecoff_symbol_type *internal_ptr; - char *eraw_src; - char *eraw_end; - FDR *fdr_ptr; - FDR *fdr_end; - - /* If we've already read in the symbol table, do nothing. */ - if (ecoff_data (abfd)->canonical_symbols != NULL) - return true; - - /* Get the symbolic information. */ - if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, - &ecoff_data (abfd)->debug_info)) - return false; - if (bfd_get_symcount (abfd) == 0) - return true; - - internal_size = bfd_get_symcount (abfd) * sizeof (ecoff_symbol_type); - internal = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size); - if (internal == NULL) - return false; - - internal_ptr = internal; - eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext; - eraw_end = (eraw_src - + (ecoff_data (abfd)->debug_info.symbolic_header.iextMax - * external_ext_size)); - for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++) - { - EXTR internal_esym; - - (*swap_ext_in) (abfd, (PTR) eraw_src, &internal_esym); - internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext - + internal_esym.asym.iss); - if (!ecoff_set_symbol_info (abfd, &internal_esym.asym, - &internal_ptr->symbol, 1, - internal_esym.weakext)) - return false; - /* The alpha uses a negative ifd field for section symbols. */ - if (internal_esym.ifd >= 0) - internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr - + internal_esym.ifd); - else - internal_ptr->fdr = NULL; - internal_ptr->local = false; - internal_ptr->native = (PTR) eraw_src; - } - - /* The local symbols must be accessed via the fdr's, because the - string and aux indices are relative to the fdr information. */ - fdr_ptr = ecoff_data (abfd)->debug_info.fdr; - fdr_end = fdr_ptr + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax; - for (; fdr_ptr < fdr_end; fdr_ptr++) - { - char *lraw_src; - char *lraw_end; - - lraw_src = ((char *) ecoff_data (abfd)->debug_info.external_sym - + fdr_ptr->isymBase * external_sym_size); - lraw_end = lraw_src + fdr_ptr->csym * external_sym_size; - for (; - lraw_src < lraw_end; - lraw_src += external_sym_size, internal_ptr++) - { - SYMR internal_sym; - - (*swap_sym_in) (abfd, (PTR) lraw_src, &internal_sym); - internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ss - + fdr_ptr->issBase - + internal_sym.iss); - if (!ecoff_set_symbol_info (abfd, &internal_sym, - &internal_ptr->symbol, 0, 0)) - return false; - internal_ptr->fdr = fdr_ptr; - internal_ptr->local = true; - internal_ptr->native = (PTR) lraw_src; - } - } - - ecoff_data (abfd)->canonical_symbols = internal; - - return true; -} - -/* Return the amount of space needed for the canonical symbols. */ - -long -_bfd_ecoff_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, - &ecoff_data (abfd)->debug_info)) - return -1; - - if (bfd_get_symcount (abfd) == 0) - return 0; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (ecoff_symbol_type *)); -} - -/* Get the canonical symbols. */ - -long -_bfd_ecoff_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - unsigned int counter = 0; - ecoff_symbol_type *symbase; - ecoff_symbol_type **location = (ecoff_symbol_type **) alocation; - - if (_bfd_ecoff_slurp_symbol_table (abfd) == false) - return -1; - if (bfd_get_symcount (abfd) == 0) - return 0; - - symbase = ecoff_data (abfd)->canonical_symbols; - while (counter < bfd_get_symcount (abfd)) - { - *(location++) = symbase++; - counter++; - } - *location++ = (ecoff_symbol_type *) NULL; - return bfd_get_symcount (abfd); -} - -/* Turn ECOFF type information into a printable string. - ecoff_emit_aggregate and ecoff_type_to_string are from - gcc/mips-tdump.c, with swapping added and used_ptr removed. */ - -/* Write aggregate information to a string. */ - -static void -ecoff_emit_aggregate (abfd, fdr, string, rndx, isym, which) - bfd *abfd; - FDR *fdr; - char *string; - RNDXR *rndx; - long isym; - const char *which; -{ - const struct ecoff_debug_swap * const debug_swap = - &ecoff_backend (abfd)->debug_swap; - struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info; - unsigned int ifd = rndx->rfd; - unsigned int indx = rndx->index; - const char *name; - - if (ifd == 0xfff) - ifd = isym; - - /* An ifd of -1 is an opaque type. An escaped index of 0 is a - struct return type of a procedure compiled without -g. */ - if (ifd == 0xffffffff - || (rndx->rfd == 0xfff && indx == 0)) - name = ""; - else if (indx == indexNil) - name = ""; - else - { - SYMR sym; - - if (debug_info->external_rfd == NULL) - fdr = debug_info->fdr + ifd; - else - { - RFDT rfd; - - (*debug_swap->swap_rfd_in) (abfd, - ((char *) debug_info->external_rfd - + ((fdr->rfdBase + ifd) - * debug_swap->external_rfd_size)), - &rfd); - fdr = debug_info->fdr + rfd; - } - - indx += fdr->isymBase; - - (*debug_swap->swap_sym_in) (abfd, - ((char *) debug_info->external_sym - + indx * debug_swap->external_sym_size), - &sym); - - name = debug_info->ss + fdr->issBase + sym.iss; - } - - sprintf (string, - "%s %s { ifd = %u, index = %lu }", - which, name, ifd, - ((long) indx - + debug_info->symbolic_header.iextMax)); -} - -/* Convert the type information to string format. */ - -static char * -ecoff_type_to_string (abfd, fdr, indx) - bfd *abfd; - FDR *fdr; - unsigned int indx; -{ - union aux_ext *aux_ptr; - int bigendian; - AUXU u; - struct qual { - unsigned int type; - int low_bound; - int high_bound; - int stride; - } qualifiers[7]; - unsigned int basic_type; - int i; - char buffer1[1024]; - static char buffer2[1024]; - char *p1 = buffer1; - char *p2 = buffer2; - RNDXR rndx; - - aux_ptr = ecoff_data (abfd)->debug_info.external_aux + fdr->iauxBase; - bigendian = fdr->fBigendian; - - for (i = 0; i < 7; i++) - { - qualifiers[i].low_bound = 0; - qualifiers[i].high_bound = 0; - qualifiers[i].stride = 0; - } - - if (AUX_GET_ISYM (bigendian, &aux_ptr[indx]) == (bfd_vma) -1) - return "-1 (no type)"; - _bfd_ecoff_swap_tir_in (bigendian, &aux_ptr[indx++].a_ti, &u.ti); - - basic_type = u.ti.bt; - qualifiers[0].type = u.ti.tq0; - qualifiers[1].type = u.ti.tq1; - qualifiers[2].type = u.ti.tq2; - qualifiers[3].type = u.ti.tq3; - qualifiers[4].type = u.ti.tq4; - qualifiers[5].type = u.ti.tq5; - qualifiers[6].type = tqNil; - - /* - * Go get the basic type. - */ - switch (basic_type) - { - case btNil: /* undefined */ - strcpy (p1, "nil"); - break; - - case btAdr: /* address - integer same size as pointer */ - strcpy (p1, "address"); - break; - - case btChar: /* character */ - strcpy (p1, "char"); - break; - - case btUChar: /* unsigned character */ - strcpy (p1, "unsigned char"); - break; - - case btShort: /* short */ - strcpy (p1, "short"); - break; - - case btUShort: /* unsigned short */ - strcpy (p1, "unsigned short"); - break; - - case btInt: /* int */ - strcpy (p1, "int"); - break; - - case btUInt: /* unsigned int */ - strcpy (p1, "unsigned int"); - break; - - case btLong: /* long */ - strcpy (p1, "long"); - break; - - case btULong: /* unsigned long */ - strcpy (p1, "unsigned long"); - break; - - case btFloat: /* float (real) */ - strcpy (p1, "float"); - break; - - case btDouble: /* Double (real) */ - strcpy (p1, "double"); - break; - - /* Structures add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to struct def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case btStruct: /* Structure (Record) */ - _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); - ecoff_emit_aggregate (abfd, fdr, p1, &rndx, - (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), - "struct"); - indx++; /* skip aux words */ - break; - - /* Unions add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to union def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case btUnion: /* Union */ - _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); - ecoff_emit_aggregate (abfd, fdr, p1, &rndx, - (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), - "union"); - indx++; /* skip aux words */ - break; - - /* Enumerations add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to enum def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case btEnum: /* Enumeration */ - _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); - ecoff_emit_aggregate (abfd, fdr, p1, &rndx, - (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), - "enum"); - indx++; /* skip aux words */ - break; - - case btTypedef: /* defined via a typedef, isymRef points */ - strcpy (p1, "typedef"); - break; - - case btRange: /* subrange of int */ - strcpy (p1, "subrange"); - break; - - case btSet: /* pascal sets */ - strcpy (p1, "set"); - break; - - case btComplex: /* fortran complex */ - strcpy (p1, "complex"); - break; - - case btDComplex: /* fortran double complex */ - strcpy (p1, "double complex"); - break; - - case btIndirect: /* forward or unnamed typedef */ - strcpy (p1, "forward/unamed typedef"); - break; - - case btFixedDec: /* Fixed Decimal */ - strcpy (p1, "fixed decimal"); - break; - - case btFloatDec: /* Float Decimal */ - strcpy (p1, "float decimal"); - break; - - case btString: /* Varying Length Character String */ - strcpy (p1, "string"); - break; - - case btBit: /* Aligned Bit String */ - strcpy (p1, "bit"); - break; - - case btPicture: /* Picture */ - strcpy (p1, "picture"); - break; - - case btVoid: /* Void */ - strcpy (p1, "void"); - break; - - default: - sprintf (p1, "Unknown basic type %d", (int) basic_type); - break; - } - - p1 += strlen (buffer1); - - /* - * If this is a bitfield, get the bitsize. - */ - if (u.ti.fBitfield) - { - int bitsize; - - bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]); - sprintf (p1, " : %d", bitsize); - p1 += strlen (buffer1); - } - - - /* - * Deal with any qualifiers. - */ - if (qualifiers[0].type != tqNil) - { - /* - * Snarf up any array bounds in the correct order. Arrays - * store 5 successive words in the aux. table: - * word 0 RNDXR to type of the bounds (ie, int) - * word 1 Current file descriptor index - * word 2 low bound - * word 3 high bound (or -1 if []) - * word 4 stride size in bits - */ - for (i = 0; i < 7; i++) - { - if (qualifiers[i].type == tqArray) - { - qualifiers[i].low_bound = - AUX_GET_DNLOW (bigendian, &aux_ptr[indx+2]); - qualifiers[i].high_bound = - AUX_GET_DNHIGH (bigendian, &aux_ptr[indx+3]); - qualifiers[i].stride = - AUX_GET_WIDTH (bigendian, &aux_ptr[indx+4]); - indx += 5; - } - } - - /* - * Now print out the qualifiers. - */ - for (i = 0; i < 6; i++) - { - switch (qualifiers[i].type) - { - case tqNil: - case tqMax: - break; - - case tqPtr: - strcpy (p2, "ptr to "); - p2 += sizeof ("ptr to ")-1; - break; - - case tqVol: - strcpy (p2, "volatile "); - p2 += sizeof ("volatile ")-1; - break; - - case tqFar: - strcpy (p2, "far "); - p2 += sizeof ("far ")-1; - break; - - case tqProc: - strcpy (p2, "func. ret. "); - p2 += sizeof ("func. ret. "); - break; - - case tqArray: - { - int first_array = i; - int j; - - /* Print array bounds reversed (ie, in the order the C - programmer writes them). C is such a fun language.... */ - - while (i < 5 && qualifiers[i+1].type == tqArray) - i++; - - for (j = i; j >= first_array; j--) - { - strcpy (p2, "array ["); - p2 += sizeof ("array [")-1; - if (qualifiers[j].low_bound != 0) - sprintf (p2, - "%ld:%ld {%ld bits}", - (long) qualifiers[j].low_bound, - (long) qualifiers[j].high_bound, - (long) qualifiers[j].stride); - - else if (qualifiers[j].high_bound != -1) - sprintf (p2, - "%ld {%ld bits}", - (long) (qualifiers[j].high_bound + 1), - (long) (qualifiers[j].stride)); - - else - sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride)); - - p2 += strlen (p2); - strcpy (p2, "] of "); - p2 += sizeof ("] of ")-1; - } - } - break; - } - } - } - - strcpy (p2, buffer1); - return buffer2; -} - -/* Return information about ECOFF symbol SYMBOL in RET. */ - -/*ARGSUSED*/ -void -_bfd_ecoff_get_symbol_info (abfd, symbol, ret) - bfd *abfd; /* Ignored. */ - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/* Return whether this is a local label. */ - -/*ARGSUSED*/ -boolean -_bfd_ecoff_bfd_is_local_label (abfd, symbol) - bfd *abfd; - asymbol *symbol; -{ - return symbol->name[0] == '$'; -} - -/* Print information about an ECOFF symbol. */ - -void -_bfd_ecoff_print_symbol (abfd, filep, symbol, how) - bfd *abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; -{ - const struct ecoff_debug_swap * const debug_swap - = &ecoff_backend (abfd)->debug_swap; - FILE *file = (FILE *)filep; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - if (ecoffsymbol (symbol)->local) - { - SYMR ecoff_sym; - - (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_sym); - fprintf (file, "ecoff local "); - fprintf_vma (file, (bfd_vma) ecoff_sym.value); - fprintf (file, " %x %x", (unsigned) ecoff_sym.st, - (unsigned) ecoff_sym.sc); - } - else - { - EXTR ecoff_ext; - - (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_ext); - fprintf (file, "ecoff extern "); - fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value); - fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st, - (unsigned) ecoff_ext.asym.sc); - } - break; - case bfd_print_symbol_all: - /* Print out the symbols in a reasonable way */ - { - char type; - int pos; - EXTR ecoff_ext; - char jmptbl; - char cobol_main; - char weakext; - - if (ecoffsymbol (symbol)->local) - { - (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_ext.asym); - type = 'l'; - pos = ((((char *) ecoffsymbol (symbol)->native - - (char *) ecoff_data (abfd)->debug_info.external_sym) - / debug_swap->external_sym_size) - + ecoff_data (abfd)->debug_info.symbolic_header.iextMax); - jmptbl = ' '; - cobol_main = ' '; - weakext = ' '; - } - else - { - (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_ext); - type = 'e'; - pos = (((char *) ecoffsymbol (symbol)->native - - (char *) ecoff_data (abfd)->debug_info.external_ext) - / debug_swap->external_ext_size); - jmptbl = ecoff_ext.jmptbl ? 'j' : ' '; - cobol_main = ecoff_ext.cobol_main ? 'c' : ' '; - weakext = ecoff_ext.weakext ? 'w' : ' '; - } - - fprintf (file, "[%3d] %c ", - pos, type); - fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value); - fprintf (file, " st %x sc %x indx %x %c%c%c %s", - (unsigned) ecoff_ext.asym.st, - (unsigned) ecoff_ext.asym.sc, - (unsigned) ecoff_ext.asym.index, - jmptbl, cobol_main, weakext, - symbol->name); - - if (ecoffsymbol (symbol)->fdr != NULL - && ecoff_ext.asym.index != indexNil) - { - FDR *fdr; - unsigned int indx; - int bigendian; - bfd_size_type sym_base; - union aux_ext *aux_base; - - fdr = ecoffsymbol (symbol)->fdr; - indx = ecoff_ext.asym.index; - - /* sym_base is used to map the fdr relative indices which - appear in the file to the position number which we are - using. */ - sym_base = fdr->isymBase; - if (ecoffsymbol (symbol)->local) - sym_base += - ecoff_data (abfd)->debug_info.symbolic_header.iextMax; - - /* aux_base is the start of the aux entries for this file; - asym.index is an offset from this. */ - aux_base = (ecoff_data (abfd)->debug_info.external_aux - + fdr->iauxBase); - - /* The aux entries are stored in host byte order; the - order is indicated by a bit in the fdr. */ - bigendian = fdr->fBigendian; - - /* This switch is basically from gcc/mips-tdump.c */ - switch (ecoff_ext.asym.st) - { - case stNil: - case stLabel: - break; - - case stFile: - case stBlock: - fprintf (file, "\n End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - case stEnd: - if (ecoff_ext.asym.sc == scText - || ecoff_ext.asym.sc == scInfo) - fprintf (file, "\n First symbol: %ld", - (long) (indx + sym_base)); - else - fprintf (file, "\n First symbol: %ld", - ((long) - (AUX_GET_ISYM (bigendian, - &aux_base[ecoff_ext.asym.index]) - + sym_base))); - break; - - case stProc: - case stStaticProc: - if (ECOFF_IS_STAB (&ecoff_ext.asym)) - ; - else if (ecoffsymbol (symbol)->local) - fprintf (file, "\n End+1 symbol: %-7ld Type: %s", - ((long) - (AUX_GET_ISYM (bigendian, - &aux_base[ecoff_ext.asym.index]) - + sym_base)), - ecoff_type_to_string (abfd, fdr, indx + 1)); - else - fprintf (file, "\n Local symbol: %ld", - ((long) indx - + (long) sym_base - + (ecoff_data (abfd) - ->debug_info.symbolic_header.iextMax))); - break; - - case stStruct: - fprintf (file, "\n struct; End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - case stUnion: - fprintf (file, "\n union; End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - case stEnum: - fprintf (file, "\n enum; End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - default: - if (! ECOFF_IS_STAB (&ecoff_ext.asym)) - fprintf (file, "\n Type: %s", - ecoff_type_to_string (abfd, fdr, indx)); - break; - } - } - } - break; - } -} - -/* Read in the relocs for a section. */ - -static boolean -ecoff_slurp_reloc_table (abfd, section, symbols) - bfd *abfd; - asection *section; - asymbol **symbols; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - arelent *internal_relocs; - bfd_size_type external_reloc_size; - bfd_size_type external_relocs_size; - char *external_relocs; - arelent *rptr; - unsigned int i; - - if (section->relocation != (arelent *) NULL - || section->reloc_count == 0 - || (section->flags & SEC_CONSTRUCTOR) != 0) - return true; - - if (_bfd_ecoff_slurp_symbol_table (abfd) == false) - return false; - - internal_relocs = (arelent *) bfd_alloc (abfd, - (sizeof (arelent) - * section->reloc_count)); - external_reloc_size = backend->external_reloc_size; - external_relocs_size = external_reloc_size * section->reloc_count; - external_relocs = (char *) bfd_alloc (abfd, external_relocs_size); - if (internal_relocs == (arelent *) NULL - || external_relocs == (char *) NULL) - return false; - if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0) - return false; - if (bfd_read (external_relocs, 1, external_relocs_size, abfd) - != external_relocs_size) - return false; - - for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++) - { - struct internal_reloc intern; - - (*backend->swap_reloc_in) (abfd, - external_relocs + i * external_reloc_size, - &intern); - - if (intern.r_extern) - { - /* r_symndx is an index into the external symbols. */ - BFD_ASSERT (intern.r_symndx >= 0 - && (intern.r_symndx - < (ecoff_data (abfd) - ->debug_info.symbolic_header.iextMax))); - rptr->sym_ptr_ptr = symbols + intern.r_symndx; - rptr->addend = 0; - } - else if (intern.r_symndx == RELOC_SECTION_NONE - || intern.r_symndx == RELOC_SECTION_ABS) - { - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rptr->addend = 0; - } - else - { - CONST char *sec_name; - asection *sec; - - /* r_symndx is a section key. */ - switch (intern.r_symndx) - { - case RELOC_SECTION_TEXT: sec_name = ".text"; break; - case RELOC_SECTION_RDATA: sec_name = ".rdata"; break; - case RELOC_SECTION_DATA: sec_name = ".data"; break; - case RELOC_SECTION_SDATA: sec_name = ".sdata"; break; - case RELOC_SECTION_SBSS: sec_name = ".sbss"; break; - case RELOC_SECTION_BSS: sec_name = ".bss"; break; - case RELOC_SECTION_INIT: sec_name = ".init"; break; - case RELOC_SECTION_LIT8: sec_name = ".lit8"; break; - case RELOC_SECTION_LIT4: sec_name = ".lit4"; break; - case RELOC_SECTION_XDATA: sec_name = ".xdata"; break; - case RELOC_SECTION_PDATA: sec_name = ".pdata"; break; - case RELOC_SECTION_FINI: sec_name = ".fini"; break; - case RELOC_SECTION_LITA: sec_name = ".lita"; break; - case RELOC_SECTION_RCONST: sec_name = ".rconst"; break; - default: abort (); - } - - sec = bfd_get_section_by_name (abfd, sec_name); - if (sec == (asection *) NULL) - abort (); - rptr->sym_ptr_ptr = sec->symbol_ptr_ptr; - - rptr->addend = - bfd_get_section_vma (abfd, sec); - } - - rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section); - - /* Let the backend select the howto field and do any other - required processing. */ - (*backend->adjust_reloc_in) (abfd, &intern, rptr); - } - - bfd_release (abfd, external_relocs); - - section->relocation = internal_relocs; - - return true; -} - -/* Get a canonical list of relocs. */ - -long -_bfd_ecoff_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - asection *section; - arelent **relptr; - asymbol **symbols; -{ - unsigned int count; - - if (section->flags & SEC_CONSTRUCTOR) - { - arelent_chain *chain; - - /* This section has relocs made up by us, not the file, so take - them out of their chain and place them into the data area - provided. */ - for (count = 0, chain = section->constructor_chain; - count < section->reloc_count; - count++, chain = chain->next) - *relptr++ = &chain->relent; - } - else - { - arelent *tblptr; - - if (ecoff_slurp_reloc_table (abfd, section, symbols) == false) - return -1; - - tblptr = section->relocation; - - for (count = 0; count < section->reloc_count; count++) - *relptr++ = tblptr++; - } - - *relptr = (arelent *) NULL; - - return section->reloc_count; -} - -/* Provided a BFD, a section and an offset into the section, calculate - and return the name of the source file and the line nearest to the - wanted location. */ - -/*ARGSUSED*/ -boolean -_bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset, - filename_ptr, functionname_ptr, retline_ptr) - bfd *abfd; - asection *section; - asymbol **ignore_symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *retline_ptr; -{ - const struct ecoff_debug_swap * const debug_swap - = &ecoff_backend (abfd)->debug_swap; - struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info; - struct ecoff_find_line *line_info; - - /* Make sure we have the FDR's. */ - if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, debug_info) - || bfd_get_symcount (abfd) == 0) - return false; - - if (ecoff_data (abfd)->find_line_info == NULL) - { - ecoff_data (abfd)->find_line_info = - ((struct ecoff_find_line *) - bfd_alloc (abfd, sizeof (struct ecoff_find_line))); - if (ecoff_data (abfd)->find_line_info == NULL) - return false; - ecoff_data (abfd)->find_line_info->find_buffer = NULL; - ecoff_data (abfd)->find_line_info->fdrtab_len = 0; - ecoff_data (abfd)->find_line_info->fdrtab = NULL; - } - line_info = ecoff_data (abfd)->find_line_info; - - return _bfd_ecoff_locate_line (abfd, section, offset, debug_info, - debug_swap, line_info, filename_ptr, - functionname_ptr, retline_ptr); -} - -/* Copy private BFD data. This is called by objcopy and strip. We - use it to copy the ECOFF debugging information from one BFD to the - other. It would be theoretically possible to represent the ECOFF - debugging information in the symbol table. However, it would be a - lot of work, and there would be little gain (gas, gdb, and ld - already access the ECOFF debugging information via the - ecoff_debug_info structure, and that structure would have to be - retained in order to support ECOFF debugging in MIPS ELF). - - The debugging information for the ECOFF external symbols comes from - the symbol table, so this function only handles the other debugging - information. */ - -boolean -_bfd_ecoff_bfd_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info; - struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info; - register int i; - asymbol **sym_ptr_ptr; - size_t c; - boolean local; - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses ECOFF - format. */ - if (bfd_get_flavour (obfd) != bfd_target_ecoff_flavour) - return true; - - /* Copy the GP value and the register masks. */ - ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp; - ecoff_data (obfd)->gprmask = ecoff_data (ibfd)->gprmask; - ecoff_data (obfd)->fprmask = ecoff_data (ibfd)->fprmask; - for (i = 0; i < 3; i++) - ecoff_data (obfd)->cprmask[i] = ecoff_data (ibfd)->cprmask[i]; - - /* Copy the version stamp. */ - oinfo->symbolic_header.vstamp = iinfo->symbolic_header.vstamp; - - /* If there are no symbols, don't copy any debugging information. */ - c = bfd_get_symcount (obfd); - sym_ptr_ptr = bfd_get_outsymbols (obfd); - if (c == 0 || sym_ptr_ptr == (asymbol **) NULL) - return true; - - /* See if there are any local symbols. */ - local = false; - for (; c > 0; c--, sym_ptr_ptr++) - { - if (ecoffsymbol (*sym_ptr_ptr)->local) - { - local = true; - break; - } - } - - if (local) - { - /* There are some local symbols. We just bring over all the - debugging information. FIXME: This is not quite the right - thing to do. If the user has asked us to discard all - debugging information, then we are probably going to wind up - keeping it because there will probably be some local symbol - which objcopy did not discard. We should actually break - apart the debugging information and only keep that which - applies to the symbols we want to keep. */ - oinfo->symbolic_header.ilineMax = iinfo->symbolic_header.ilineMax; - oinfo->symbolic_header.cbLine = iinfo->symbolic_header.cbLine; - oinfo->line = iinfo->line; - - oinfo->symbolic_header.idnMax = iinfo->symbolic_header.idnMax; - oinfo->external_dnr = iinfo->external_dnr; - - oinfo->symbolic_header.ipdMax = iinfo->symbolic_header.ipdMax; - oinfo->external_pdr = iinfo->external_pdr; - - oinfo->symbolic_header.isymMax = iinfo->symbolic_header.isymMax; - oinfo->external_sym = iinfo->external_sym; - - oinfo->symbolic_header.ioptMax = iinfo->symbolic_header.ioptMax; - oinfo->external_opt = iinfo->external_opt; - - oinfo->symbolic_header.iauxMax = iinfo->symbolic_header.iauxMax; - oinfo->external_aux = iinfo->external_aux; - - oinfo->symbolic_header.issMax = iinfo->symbolic_header.issMax; - oinfo->ss = iinfo->ss; - - oinfo->symbolic_header.ifdMax = iinfo->symbolic_header.ifdMax; - oinfo->external_fdr = iinfo->external_fdr; - - oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd; - oinfo->external_rfd = iinfo->external_rfd; - } - else - { - /* We are discarding all the local symbol information. Look - through the external symbols and remove all references to FDR - or aux information. */ - c = bfd_get_symcount (obfd); - sym_ptr_ptr = bfd_get_outsymbols (obfd); - for (; c > 0; c--, sym_ptr_ptr++) - { - EXTR esym; - - (*(ecoff_backend (obfd)->debug_swap.swap_ext_in)) - (obfd, ecoffsymbol (*sym_ptr_ptr)->native, &esym); - esym.ifd = ifdNil; - esym.asym.index = indexNil; - (*(ecoff_backend (obfd)->debug_swap.swap_ext_out)) - (obfd, &esym, ecoffsymbol (*sym_ptr_ptr)->native); - } - } - - return true; -} - -/* Set the architecture. The supported architecture is stored in the - backend pointer. We always set the architecture anyhow, since many - callers ignore the return value. */ - -boolean -_bfd_ecoff_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - bfd_default_set_arch_mach (abfd, arch, machine); - return arch == ecoff_backend (abfd)->arch; -} - -/* Get the size of the section headers. */ - -/*ARGSUSED*/ -int -_bfd_ecoff_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - asection *current; - int c; - int ret; - - c = 0; - for (current = abfd->sections; - current != (asection *)NULL; - current = current->next) - ++c; - - ret = (bfd_coff_filhsz (abfd) - + bfd_coff_aoutsz (abfd) - + c * bfd_coff_scnhsz (abfd)); - return BFD_ALIGN (ret, 16); -} - -/* Get the contents of a section. */ - -boolean -_bfd_ecoff_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - return _bfd_generic_get_section_contents (abfd, section, location, - offset, count); -} - -/* Sort sections by VMA, but put SEC_ALLOC sections first. This is - called via qsort. */ - -static int -ecoff_sort_hdrs (arg1, arg2) - const PTR arg1; - const PTR arg2; -{ - const asection *hdr1 = *(const asection **) arg1; - const asection *hdr2 = *(const asection **) arg2; - - if ((hdr1->flags & SEC_ALLOC) != 0) - { - if ((hdr2->flags & SEC_ALLOC) == 0) - return -1; - } - else - { - if ((hdr2->flags & SEC_ALLOC) != 0) - return 1; - } - if (hdr1->vma < hdr2->vma) - return -1; - else if (hdr1->vma > hdr2->vma) - return 1; - else - return 0; -} - -/* Calculate the file position for each section, and set - reloc_filepos. */ - -static boolean -ecoff_compute_section_file_positions (abfd) - bfd *abfd; -{ - file_ptr sofar; - asection **sorted_hdrs; - asection *current; - unsigned int i; - file_ptr old_sofar; - boolean first_data, first_nonalloc; - const bfd_vma round = ecoff_backend (abfd)->round; - - sofar = _bfd_ecoff_sizeof_headers (abfd, false); - - /* Sort the sections by VMA. */ - sorted_hdrs = (asection **) bfd_malloc (abfd->section_count - * sizeof (asection *)); - if (sorted_hdrs == NULL) - return false; - for (current = abfd->sections, i = 0; - current != NULL; - current = current->next, i++) - sorted_hdrs[i] = current; - BFD_ASSERT (i == abfd->section_count); - - qsort (sorted_hdrs, abfd->section_count, sizeof (asection *), - ecoff_sort_hdrs); - - first_data = true; - first_nonalloc = true; - for (i = 0; i < abfd->section_count; i++) - { - unsigned int alignment_power; - - current = sorted_hdrs[i]; - - /* For the Alpha ECOFF .pdata section the lnnoptr field is - supposed to indicate the number of .pdata entries that are - really in the section. Each entry is 8 bytes. We store this - away in line_filepos before increasing the section size. */ - if (strcmp (current->name, _PDATA) != 0) - alignment_power = current->alignment_power; - else - { - current->line_filepos = current->_raw_size / 8; - alignment_power = 4; - } - - /* On Ultrix, the data sections in an executable file must be - aligned to a page boundary within the file. This does not - affect the section size, though. FIXME: Does this work for - other platforms? It requires some modification for the - Alpha, because .rdata on the Alpha goes with the text, not - the data. */ - if ((abfd->flags & EXEC_P) != 0 - && (abfd->flags & D_PAGED) != 0 - && ! first_data - && (current->flags & SEC_CODE) == 0 - && (! ecoff_backend (abfd)->rdata_in_text - || strcmp (current->name, _RDATA) != 0) - && strcmp (current->name, _PDATA) != 0 - && strcmp (current->name, _RCONST) != 0) - { - sofar = (sofar + round - 1) &~ (round - 1); - first_data = false; - } - else if (strcmp (current->name, _LIB) == 0) - { - /* On Irix 4, the location of contents of the .lib section - from a shared library section is also rounded up to a - page boundary. */ - - sofar = (sofar + round - 1) &~ (round - 1); - } - else if (first_nonalloc - && (current->flags & SEC_ALLOC) == 0 - && (abfd->flags & D_PAGED) != 0) - { - /* Skip up to the next page for an unallocated section, such - as the .comment section on the Alpha. This leaves room - for the .bss section. */ - first_nonalloc = false; - sofar = (sofar + round - 1) &~ (round - 1); - } - - /* Align the sections in the file to the same boundary on - which they are aligned in virtual memory. */ - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << alignment_power); - - if ((abfd->flags & D_PAGED) != 0 - && (current->flags & SEC_ALLOC) != 0) - sofar += (current->vma - sofar) % round; - - if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) != 0) - current->filepos = sofar; - - sofar += current->_raw_size; - - /* make sure that this section is of the right size too */ - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << alignment_power); - current->_raw_size += sofar - old_sofar; - } - - free (sorted_hdrs); - sorted_hdrs = NULL; - - ecoff_data (abfd)->reloc_filepos = sofar; - - return true; -} - -/* Determine the location of the relocs for all the sections in the - output file, as well as the location of the symbolic debugging - information. */ - -static bfd_size_type -ecoff_compute_reloc_file_positions (abfd) - bfd *abfd; -{ - const bfd_size_type external_reloc_size = - ecoff_backend (abfd)->external_reloc_size; - file_ptr reloc_base; - bfd_size_type reloc_size; - asection *current; - file_ptr sym_base; - - if (! abfd->output_has_begun) - { - if (! ecoff_compute_section_file_positions (abfd)) - abort (); - abfd->output_has_begun = true; - } - - reloc_base = ecoff_data (abfd)->reloc_filepos; - - reloc_size = 0; - for (current = abfd->sections; - current != (asection *)NULL; - current = current->next) - { - if (current->reloc_count == 0) - current->rel_filepos = 0; - else - { - bfd_size_type relsize; - - current->rel_filepos = reloc_base; - relsize = current->reloc_count * external_reloc_size; - reloc_size += relsize; - reloc_base += relsize; - } - } - - sym_base = ecoff_data (abfd)->reloc_filepos + reloc_size; - - /* At least on Ultrix, the symbol table of an executable file must - be aligned to a page boundary. FIXME: Is this true on other - platforms? */ - if ((abfd->flags & EXEC_P) != 0 - && (abfd->flags & D_PAGED) != 0) - sym_base = ((sym_base + ecoff_backend (abfd)->round - 1) - &~ (ecoff_backend (abfd)->round - 1)); - - ecoff_data (abfd)->sym_filepos = sym_base; - - return reloc_size; -} - -/* Set the contents of a section. */ - -boolean -_bfd_ecoff_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - /* This must be done first, because bfd_set_section_contents is - going to set output_has_begun to true. */ - if (abfd->output_has_begun == false) - { - if (! ecoff_compute_section_file_positions (abfd)) - return false; - } - - /* If this is a .lib section, bump the vma address so that it winds - up being the number of .lib sections output. This is right for - Irix 4. Ian Taylor . */ - if (strcmp (section->name, _LIB) == 0) - ++section->vma; - - if (count == 0) - return true; - - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 - || bfd_write (location, 1, count, abfd) != count) - return false; - - return true; -} - -/* Get the GP value for an ECOFF file. This is a hook used by - nlmconv. */ - -bfd_vma -bfd_ecoff_get_gp_value (abfd) - bfd *abfd; -{ - if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour - || bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - - return ecoff_data (abfd)->gp; -} - -/* Set the GP value for an ECOFF file. This is a hook used by the - assembler. */ - -boolean -bfd_ecoff_set_gp_value (abfd, gp_value) - bfd *abfd; - bfd_vma gp_value; -{ - if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour - || bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - ecoff_data (abfd)->gp = gp_value; - - return true; -} - -/* Set the register masks for an ECOFF file. This is a hook used by - the assembler. */ - -boolean -bfd_ecoff_set_regmasks (abfd, gprmask, fprmask, cprmask) - bfd *abfd; - unsigned long gprmask; - unsigned long fprmask; - unsigned long *cprmask; -{ - ecoff_data_type *tdata; - - if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour - || bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - tdata = ecoff_data (abfd); - tdata->gprmask = gprmask; - tdata->fprmask = fprmask; - if (cprmask != (unsigned long *) NULL) - { - register int i; - - for (i = 0; i < 3; i++) - tdata->cprmask[i] = cprmask[i]; - } - - return true; -} - -/* Get ECOFF EXTR information for an external symbol. This function - is passed to bfd_ecoff_debug_externals. */ - -static boolean -ecoff_get_extr (sym, esym) - asymbol *sym; - EXTR *esym; -{ - ecoff_symbol_type *ecoff_sym_ptr; - bfd *input_bfd; - - if (bfd_asymbol_flavour (sym) != bfd_target_ecoff_flavour - || ecoffsymbol (sym)->native == NULL) - { - /* Don't include debugging, local, or section symbols. */ - if ((sym->flags & BSF_DEBUGGING) != 0 - || (sym->flags & BSF_LOCAL) != 0 - || (sym->flags & BSF_SECTION_SYM) != 0) - return false; - - esym->jmptbl = 0; - esym->cobol_main = 0; - esym->weakext = (sym->flags & BSF_WEAK) != 0; - esym->reserved = 0; - esym->ifd = ifdNil; - /* FIXME: we can do better than this for st and sc. */ - esym->asym.st = stGlobal; - esym->asym.sc = scAbs; - esym->asym.reserved = 0; - esym->asym.index = indexNil; - return true; - } - - ecoff_sym_ptr = ecoffsymbol (sym); - - if (ecoff_sym_ptr->local) - return false; - - input_bfd = bfd_asymbol_bfd (sym); - (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in)) - (input_bfd, ecoff_sym_ptr->native, esym); - - /* If the symbol was defined by the linker, then esym will be - undefined but sym will not be. Get a better class for such a - symbol. */ - if ((esym->asym.sc == scUndefined - || esym->asym.sc == scSUndefined) - && ! bfd_is_und_section (bfd_get_section (sym))) - esym->asym.sc = scAbs; - - /* Adjust the FDR index for the symbol by that used for the input - BFD. */ - if (esym->ifd != -1) - { - struct ecoff_debug_info *input_debug; - - input_debug = &ecoff_data (input_bfd)->debug_info; - BFD_ASSERT (esym->ifd < input_debug->symbolic_header.ifdMax); - if (input_debug->ifdmap != (RFDT *) NULL) - esym->ifd = input_debug->ifdmap[esym->ifd]; - } - - return true; -} - -/* Set the external symbol index. This routine is passed to - bfd_ecoff_debug_externals. */ - -static void -ecoff_set_index (sym, indx) - asymbol *sym; - bfd_size_type indx; -{ - ecoff_set_sym_index (sym, indx); -} - -/* Write out an ECOFF file. */ - -boolean -_bfd_ecoff_write_object_contents (abfd) - bfd *abfd; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - const bfd_vma round = backend->round; - const bfd_size_type filhsz = bfd_coff_filhsz (abfd); - const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd); - const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd); - const bfd_size_type external_hdr_size - = backend->debug_swap.external_hdr_size; - const bfd_size_type external_reloc_size = backend->external_reloc_size; - void (* const adjust_reloc_out) PARAMS ((bfd *, - const arelent *, - struct internal_reloc *)) - = backend->adjust_reloc_out; - void (* const swap_reloc_out) PARAMS ((bfd *, - const struct internal_reloc *, - PTR)) - = backend->swap_reloc_out; - struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info; - HDRR * const symhdr = &debug->symbolic_header; - asection *current; - unsigned int count; - bfd_size_type reloc_size; - bfd_size_type text_size; - bfd_vma text_start; - boolean set_text_start; - bfd_size_type data_size; - bfd_vma data_start; - boolean set_data_start; - bfd_size_type bss_size; - PTR buff = NULL; - PTR reloc_buff = NULL; - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - int i; - - /* Determine where the sections and relocs will go in the output - file. */ - reloc_size = ecoff_compute_reloc_file_positions (abfd); - - count = 1; - for (current = abfd->sections; - current != (asection *)NULL; - current = current->next) - { - current->target_index = count; - ++count; - } - - if ((abfd->flags & D_PAGED) != 0) - text_size = _bfd_ecoff_sizeof_headers (abfd, false); - else - text_size = 0; - text_start = 0; - set_text_start = false; - data_size = 0; - data_start = 0; - set_data_start = false; - bss_size = 0; - - /* Write section headers to the file. */ - - /* Allocate buff big enough to hold a section header, - file header, or a.out header. */ - { - bfd_size_type siz; - siz = scnhsz; - if (siz < filhsz) - siz = filhsz; - if (siz < aoutsz) - siz = aoutsz; - buff = (PTR) bfd_malloc ((size_t) siz); - if (buff == NULL) - goto error_return; - } - - internal_f.f_nscns = 0; - if (bfd_seek (abfd, (file_ptr) (filhsz + aoutsz), SEEK_SET) != 0) - goto error_return; - for (current = abfd->sections; - current != (asection *) NULL; - current = current->next) - { - struct internal_scnhdr section; - bfd_vma vma; - - ++internal_f.f_nscns; - - strncpy (section.s_name, current->name, sizeof section.s_name); - - /* This seems to be correct for Irix 4 shared libraries. */ - vma = bfd_get_section_vma (abfd, current); - if (strcmp (current->name, _LIB) == 0) - section.s_vaddr = 0; - else - section.s_vaddr = vma; - - section.s_paddr = current->lma; - section.s_size = bfd_get_section_size_before_reloc (current); - - /* If this section is unloadable then the scnptr will be 0. */ - if ((current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - section.s_scnptr = 0; - else - section.s_scnptr = current->filepos; - section.s_relptr = current->rel_filepos; - - /* FIXME: the lnnoptr of the .sbss or .sdata section of an - object file produced by the assembler is supposed to point to - information about how much room is required by objects of - various different sizes. I think this only matters if we - want the linker to compute the best size to use, or - something. I don't know what happens if the information is - not present. */ - if (strcmp (current->name, _PDATA) != 0) - section.s_lnnoptr = 0; - else - { - /* The Alpha ECOFF .pdata section uses the lnnoptr field to - hold the number of entries in the section (each entry is - 8 bytes). We stored this in the line_filepos field in - ecoff_compute_section_file_positions. */ - section.s_lnnoptr = current->line_filepos; - } - - section.s_nreloc = current->reloc_count; - section.s_nlnno = 0; - section.s_flags = ecoff_sec_to_styp_flags (current->name, - current->flags); - - if (bfd_coff_swap_scnhdr_out (abfd, (PTR) §ion, buff) == 0 - || bfd_write (buff, 1, scnhsz, abfd) != scnhsz) - goto error_return; - - if ((section.s_flags & STYP_TEXT) != 0 - || ((section.s_flags & STYP_RDATA) != 0 - && backend->rdata_in_text) - || section.s_flags == STYP_PDATA - || (section.s_flags & STYP_DYNAMIC) != 0 - || (section.s_flags & STYP_LIBLIST) != 0 - || (section.s_flags & STYP_RELDYN) != 0 - || section.s_flags == STYP_CONFLIC - || (section.s_flags & STYP_DYNSTR) != 0 - || (section.s_flags & STYP_DYNSYM) != 0 - || (section.s_flags & STYP_HASH) != 0 - || (section.s_flags & STYP_ECOFF_INIT) != 0 - || (section.s_flags & STYP_ECOFF_FINI) != 0 - || section.s_flags == STYP_RCONST) - { - text_size += bfd_get_section_size_before_reloc (current); - if (! set_text_start || text_start > vma) - { - text_start = vma; - set_text_start = true; - } - } - else if ((section.s_flags & STYP_RDATA) != 0 - || (section.s_flags & STYP_DATA) != 0 - || (section.s_flags & STYP_LITA) != 0 - || (section.s_flags & STYP_LIT8) != 0 - || (section.s_flags & STYP_LIT4) != 0 - || (section.s_flags & STYP_SDATA) != 0 - || section.s_flags == STYP_XDATA - || (section.s_flags & STYP_GOT) != 0) - { - data_size += bfd_get_section_size_before_reloc (current); - if (! set_data_start || data_start > vma) - { - data_start = vma; - set_data_start = true; - } - } - else if ((section.s_flags & STYP_BSS) != 0 - || (section.s_flags & STYP_SBSS) != 0) - bss_size += bfd_get_section_size_before_reloc (current); - else if (section.s_flags == 0 - || (section.s_flags & STYP_ECOFF_LIB) != 0 - || section.s_flags == STYP_COMMENT) - /* Do nothing */ ; - else - abort (); - } - - /* Set up the file header. */ - - internal_f.f_magic = ecoff_get_magic (abfd); - - /* We will NOT put a fucking timestamp in the header here. Every - time you put it back, I will come in and take it out again. I'm - sorry. This field does not belong here. We fill it with a 0 so - it compares the same but is not a reasonable time. -- - gnu@cygnus.com. */ - internal_f.f_timdat = 0; - - if (bfd_get_symcount (abfd) != 0) - { - /* The ECOFF f_nsyms field is not actually the number of - symbols, it's the size of symbolic information header. */ - internal_f.f_nsyms = external_hdr_size; - internal_f.f_symptr = ecoff_data (abfd)->sym_filepos; - } - else - { - internal_f.f_nsyms = 0; - internal_f.f_symptr = 0; - } - - internal_f.f_opthdr = aoutsz; - - internal_f.f_flags = F_LNNO; - if (reloc_size == 0) - internal_f.f_flags |= F_RELFLG; - if (bfd_get_symcount (abfd) == 0) - internal_f.f_flags |= F_LSYMS; - if (abfd->flags & EXEC_P) - internal_f.f_flags |= F_EXEC; - - if (bfd_little_endian (abfd)) - internal_f.f_flags |= F_AR32WR; - else - internal_f.f_flags |= F_AR32W; - - /* Set up the ``optional'' header. */ - if ((abfd->flags & D_PAGED) != 0) - internal_a.magic = ECOFF_AOUT_ZMAGIC; - else - internal_a.magic = ECOFF_AOUT_OMAGIC; - - /* FIXME: Is this really correct? */ - internal_a.vstamp = symhdr->vstamp; - - /* At least on Ultrix, these have to be rounded to page boundaries. - FIXME: Is this true on other platforms? */ - if ((abfd->flags & D_PAGED) != 0) - { - internal_a.tsize = (text_size + round - 1) &~ (round - 1); - internal_a.text_start = text_start &~ (round - 1); - internal_a.dsize = (data_size + round - 1) &~ (round - 1); - internal_a.data_start = data_start &~ (round - 1); - } - else - { - internal_a.tsize = text_size; - internal_a.text_start = text_start; - internal_a.dsize = data_size; - internal_a.data_start = data_start; - } - - /* On Ultrix, the initial portions of the .sbss and .bss segments - are at the end of the data section. The bsize field in the - optional header records how many bss bytes are required beyond - those in the data section. The value is not rounded to a page - boundary. */ - if (bss_size < internal_a.dsize - data_size) - bss_size = 0; - else - bss_size -= internal_a.dsize - data_size; - internal_a.bsize = bss_size; - internal_a.bss_start = internal_a.data_start + internal_a.dsize; - - internal_a.entry = bfd_get_start_address (abfd); - - internal_a.gp_value = ecoff_data (abfd)->gp; - - internal_a.gprmask = ecoff_data (abfd)->gprmask; - internal_a.fprmask = ecoff_data (abfd)->fprmask; - for (i = 0; i < 4; i++) - internal_a.cprmask[i] = ecoff_data (abfd)->cprmask[i]; - - /* Let the backend adjust the headers if necessary. */ - if (backend->adjust_headers) - { - if (! (*backend->adjust_headers) (abfd, &internal_f, &internal_a)) - goto error_return; - } - - /* Write out the file header and the optional header. */ - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto error_return; - - bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, buff); - if (bfd_write (buff, 1, filhsz, abfd) != filhsz) - goto error_return; - - bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, buff); - if (bfd_write (buff, 1, aoutsz, abfd) != aoutsz) - goto error_return; - - /* Build the external symbol information. This must be done before - writing out the relocs so that we know the symbol indices. We - don't do this if this BFD was created by the backend linker, - since it will have already handled the symbols and relocs. */ - if (! ecoff_data (abfd)->linker) - { - symhdr->iextMax = 0; - symhdr->issExtMax = 0; - debug->external_ext = debug->external_ext_end = NULL; - debug->ssext = debug->ssext_end = NULL; - if (bfd_ecoff_debug_externals (abfd, debug, &backend->debug_swap, - (((abfd->flags & EXEC_P) == 0) - ? true : false), - ecoff_get_extr, ecoff_set_index) - == false) - goto error_return; - - /* Write out the relocs. */ - for (current = abfd->sections; - current != (asection *) NULL; - current = current->next) - { - arelent **reloc_ptr_ptr; - arelent **reloc_end; - char *out_ptr; - - if (current->reloc_count == 0) - continue; - - reloc_buff = - bfd_alloc (abfd, current->reloc_count * external_reloc_size); - if (reloc_buff == NULL) - goto error_return; - - reloc_ptr_ptr = current->orelocation; - reloc_end = reloc_ptr_ptr + current->reloc_count; - out_ptr = (char *) reloc_buff; - for (; - reloc_ptr_ptr < reloc_end; - reloc_ptr_ptr++, out_ptr += external_reloc_size) - { - arelent *reloc; - asymbol *sym; - struct internal_reloc in; - - memset ((PTR) &in, 0, sizeof in); - - reloc = *reloc_ptr_ptr; - sym = *reloc->sym_ptr_ptr; - - in.r_vaddr = (reloc->address - + bfd_get_section_vma (abfd, current)); - in.r_type = reloc->howto->type; - - if ((sym->flags & BSF_SECTION_SYM) == 0) - { - in.r_symndx = ecoff_get_sym_index (*reloc->sym_ptr_ptr); - in.r_extern = 1; - } - else - { - CONST char *name; - - name = bfd_get_section_name (abfd, bfd_get_section (sym)); - if (strcmp (name, ".text") == 0) - in.r_symndx = RELOC_SECTION_TEXT; - else if (strcmp (name, ".rdata") == 0) - in.r_symndx = RELOC_SECTION_RDATA; - else if (strcmp (name, ".data") == 0) - in.r_symndx = RELOC_SECTION_DATA; - else if (strcmp (name, ".sdata") == 0) - in.r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - in.r_symndx = RELOC_SECTION_SBSS; - else if (strcmp (name, ".bss") == 0) - in.r_symndx = RELOC_SECTION_BSS; - else if (strcmp (name, ".init") == 0) - in.r_symndx = RELOC_SECTION_INIT; - else if (strcmp (name, ".lit8") == 0) - in.r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - in.r_symndx = RELOC_SECTION_LIT4; - else if (strcmp (name, ".xdata") == 0) - in.r_symndx = RELOC_SECTION_XDATA; - else if (strcmp (name, ".pdata") == 0) - in.r_symndx = RELOC_SECTION_PDATA; - else if (strcmp (name, ".fini") == 0) - in.r_symndx = RELOC_SECTION_FINI; - else if (strcmp (name, ".lita") == 0) - in.r_symndx = RELOC_SECTION_LITA; - else if (strcmp (name, "*ABS*") == 0) - in.r_symndx = RELOC_SECTION_ABS; - else if (strcmp (name, ".rconst") == 0) - in.r_symndx = RELOC_SECTION_RCONST; - else - abort (); - in.r_extern = 0; - } - - (*adjust_reloc_out) (abfd, reloc, &in); - - (*swap_reloc_out) (abfd, &in, (PTR) out_ptr); - } - - if (bfd_seek (abfd, current->rel_filepos, SEEK_SET) != 0) - goto error_return; - if (bfd_write (reloc_buff, - external_reloc_size, current->reloc_count, abfd) - != external_reloc_size * current->reloc_count) - goto error_return; - bfd_release (abfd, reloc_buff); - reloc_buff = NULL; - } - - /* Write out the symbolic debugging information. */ - if (bfd_get_symcount (abfd) > 0) - { - /* Write out the debugging information. */ - if (bfd_ecoff_write_debug (abfd, debug, &backend->debug_swap, - ecoff_data (abfd)->sym_filepos) - == false) - goto error_return; - } - } - - /* The .bss section of a demand paged executable must receive an - entire page. If there are symbols, the symbols will start on the - next page. If there are no symbols, we must fill out the page by - hand. */ - if (bfd_get_symcount (abfd) == 0 - && (abfd->flags & EXEC_P) != 0 - && (abfd->flags & D_PAGED) != 0) - { - char c; - - if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1, - SEEK_SET) != 0) - goto error_return; - if (bfd_read (&c, 1, 1, abfd) == 0) - c = 0; - if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1, - SEEK_SET) != 0) - goto error_return; - if (bfd_write (&c, 1, 1, abfd) != 1) - goto error_return; - } - - if (reloc_buff != NULL) - bfd_release (abfd, reloc_buff); - if (buff != NULL) - free (buff); - return true; - error_return: - if (reloc_buff != NULL) - bfd_release (abfd, reloc_buff); - if (buff != NULL) - free (buff); - return false; -} - -/* Archive handling. ECOFF uses what appears to be a unique type of - archive header (armap). The byte ordering of the armap and the - contents are encoded in the name of the armap itself. At least for - now, we only support archives with the same byte ordering in the - armap and the contents. - - The first four bytes in the armap are the number of symbol - definitions. This is always a power of two. - - This is followed by the symbol definitions. Each symbol definition - occupies 8 bytes. The first four bytes are the offset from the - start of the armap strings to the null-terminated string naming - this symbol. The second four bytes are the file offset to the - archive member which defines this symbol. If the second four bytes - are 0, then this is not actually a symbol definition, and it should - be ignored. - - The symbols are hashed into the armap with a closed hashing scheme. - See the functions below for the details of the algorithm. - - After the symbol definitions comes four bytes holding the size of - the string table, followed by the string table itself. */ - -/* The name of an archive headers looks like this: - __________E[BL]E[BL]_ (with a trailing space). - The trailing space is changed to an X if the archive is changed to - indicate that the armap is out of date. - - The Alpha seems to use ________64E[BL]E[BL]_. */ - -#define ARMAP_BIG_ENDIAN 'B' -#define ARMAP_LITTLE_ENDIAN 'L' -#define ARMAP_MARKER 'E' -#define ARMAP_START_LENGTH 10 -#define ARMAP_HEADER_MARKER_INDEX 10 -#define ARMAP_HEADER_ENDIAN_INDEX 11 -#define ARMAP_OBJECT_MARKER_INDEX 12 -#define ARMAP_OBJECT_ENDIAN_INDEX 13 -#define ARMAP_END_INDEX 14 -#define ARMAP_END "_ " - -/* This is a magic number used in the hashing algorithm. */ -#define ARMAP_HASH_MAGIC 0x9dd68ab5 - -/* This returns the hash value to use for a string. It also sets - *REHASH to the rehash adjustment if the first slot is taken. SIZE - is the number of entries in the hash table, and HLOG is the log - base 2 of SIZE. */ - -static unsigned int -ecoff_armap_hash (s, rehash, size, hlog) - CONST char *s; - unsigned int *rehash; - unsigned int size; - unsigned int hlog; -{ - unsigned int hash; - - hash = *s++; - while (*s != '\0') - hash = ((hash >> 27) | (hash << 5)) + *s++; - hash *= ARMAP_HASH_MAGIC; - *rehash = (hash & (size - 1)) | 1; - return hash >> (32 - hlog); -} - -/* Read in the armap. */ - -boolean -_bfd_ecoff_slurp_armap (abfd) - bfd *abfd; -{ - char nextname[17]; - unsigned int i; - struct areltdata *mapdata; - bfd_size_type parsed_size; - char *raw_armap; - struct artdata *ardata; - unsigned int count; - char *raw_ptr; - struct symdef *symdef_ptr; - char *stringbase; - - /* Get the name of the first element. */ - i = bfd_read ((PTR) nextname, 1, 16, abfd); - if (i == 0) - return true; - if (i != 16) - return false; - - if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) - return false; - - /* Irix 4.0.5F apparently can use either an ECOFF armap or a - standard COFF armap. We could move the ECOFF armap stuff into - bfd_slurp_armap, but that seems inappropriate since no other - target uses this format. Instead, we check directly for a COFF - armap. */ - if (strncmp (nextname, "/ ", 16) == 0) - return bfd_slurp_armap (abfd); - - /* See if the first element is an armap. */ - if (strncmp (nextname, ecoff_backend (abfd)->armap_start, - ARMAP_START_LENGTH) != 0 - || nextname[ARMAP_HEADER_MARKER_INDEX] != ARMAP_MARKER - || (nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN - && nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN) - || nextname[ARMAP_OBJECT_MARKER_INDEX] != ARMAP_MARKER - || (nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN - && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN) - || strncmp (nextname + ARMAP_END_INDEX, - ARMAP_END, sizeof ARMAP_END - 1) != 0) - { - bfd_has_map (abfd) = false; - return true; - } - - /* Make sure we have the right byte ordering. */ - if (((nextname[ARMAP_HEADER_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN) - ^ (bfd_header_big_endian (abfd))) - || ((nextname[ARMAP_OBJECT_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN) - ^ (bfd_big_endian (abfd)))) - { - bfd_set_error (bfd_error_wrong_format); - return false; - } - - /* Read in the armap. */ - ardata = bfd_ardata (abfd); - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == (struct areltdata *) NULL) - return false; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, (PTR) mapdata); - - raw_armap = (char *) bfd_alloc (abfd, parsed_size); - if (raw_armap == (char *) NULL) - return false; - - if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - bfd_release (abfd, (PTR) raw_armap); - return false; - } - - ardata->tdata = (PTR) raw_armap; - - count = bfd_h_get_32 (abfd, (PTR) raw_armap); - - ardata->symdef_count = 0; - ardata->cache = (struct ar_cache *) NULL; - - /* This code used to overlay the symdefs over the raw archive data, - but that doesn't work on a 64 bit host. */ - - stringbase = raw_armap + count * 8 + 8; - -#ifdef CHECK_ARMAP_HASH - { - unsigned int hlog; - - /* Double check that I have the hashing algorithm right by making - sure that every symbol can be looked up successfully. */ - hlog = 0; - for (i = 1; i < count; i <<= 1) - hlog++; - BFD_ASSERT (i == count); - - raw_ptr = raw_armap + 4; - for (i = 0; i < count; i++, raw_ptr += 8) - { - unsigned int name_offset, file_offset; - unsigned int hash, rehash, srch; - - name_offset = bfd_h_get_32 (abfd, (PTR) raw_ptr); - file_offset = bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4)); - if (file_offset == 0) - continue; - hash = ecoff_armap_hash (stringbase + name_offset, &rehash, count, - hlog); - if (hash == i) - continue; - - /* See if we can rehash to this location. */ - for (srch = (hash + rehash) & (count - 1); - srch != hash && srch != i; - srch = (srch + rehash) & (count - 1)) - BFD_ASSERT (bfd_h_get_32 (abfd, (PTR) (raw_armap + 8 + srch * 8)) - != 0); - BFD_ASSERT (srch == i); - } - } - -#endif /* CHECK_ARMAP_HASH */ - - raw_ptr = raw_armap + 4; - for (i = 0; i < count; i++, raw_ptr += 8) - if (bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4)) != 0) - ++ardata->symdef_count; - - symdef_ptr = ((struct symdef *) - bfd_alloc (abfd, - ardata->symdef_count * sizeof (struct symdef))); - if (!symdef_ptr) - return false; - - ardata->symdefs = (carsym *) symdef_ptr; - - raw_ptr = raw_armap + 4; - for (i = 0; i < count; i++, raw_ptr += 8) - { - unsigned int name_offset, file_offset; - - file_offset = bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4)); - if (file_offset == 0) - continue; - name_offset = bfd_h_get_32 (abfd, (PTR) raw_ptr); - symdef_ptr->s.name = stringbase + name_offset; - symdef_ptr->file_offset = file_offset; - ++symdef_ptr; - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary. */ - ardata->first_file_filepos += ardata->first_file_filepos % 2; - - bfd_has_map (abfd) = true; - - return true; -} - -/* Write out an armap. */ - -boolean -_bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx) - bfd *abfd; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - unsigned int hashsize, hashlog; - unsigned int symdefsize; - int padit; - unsigned int stringsize; - unsigned int mapsize; - file_ptr firstreal; - struct ar_hdr hdr; - struct stat statbuf; - unsigned int i; - bfd_byte temp[4]; - bfd_byte *hashtable; - bfd *current; - bfd *last_elt; - - /* Ultrix appears to use as a hash table size the least power of two - greater than twice the number of entries. */ - for (hashlog = 0; (1 << hashlog) <= 2 * orl_count; hashlog++) - ; - hashsize = 1 << hashlog; - - symdefsize = hashsize * 8; - padit = stridx % 2; - stringsize = stridx + padit; - - /* Include 8 bytes to store symdefsize and stringsize in output. */ - mapsize = symdefsize + stringsize + 8; - - firstreal = SARMAG + sizeof (struct ar_hdr) + mapsize + elength; - - memset ((PTR) &hdr, 0, sizeof hdr); - - /* Work out the ECOFF armap name. */ - strcpy (hdr.ar_name, ecoff_backend (abfd)->armap_start); - hdr.ar_name[ARMAP_HEADER_MARKER_INDEX] = ARMAP_MARKER; - hdr.ar_name[ARMAP_HEADER_ENDIAN_INDEX] = - (bfd_header_big_endian (abfd) - ? ARMAP_BIG_ENDIAN - : ARMAP_LITTLE_ENDIAN); - hdr.ar_name[ARMAP_OBJECT_MARKER_INDEX] = ARMAP_MARKER; - hdr.ar_name[ARMAP_OBJECT_ENDIAN_INDEX] = - bfd_big_endian (abfd) ? ARMAP_BIG_ENDIAN : ARMAP_LITTLE_ENDIAN; - memcpy (hdr.ar_name + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1); - - /* Write the timestamp of the archive header to be just a little bit - later than the timestamp of the file, otherwise the linker will - complain that the index is out of date. Actually, the Ultrix - linker just checks the archive name; the GNU linker may check the - date. */ - stat (abfd->filename, &statbuf); - sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60)); - - /* The DECstation uses zeroes for the uid, gid and mode of the - armap. */ - hdr.ar_uid[0] = '0'; - hdr.ar_gid[0] = '0'; - hdr.ar_mode[0] = '0'; - - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - - hdr.ar_fmag[0] = '`'; - hdr.ar_fmag[1] = '\012'; - - /* Turn all null bytes in the header into spaces. */ - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *)(&hdr))[i] == '\0') - (((char *)(&hdr))[i]) = ' '; - - if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - return false; - - bfd_h_put_32 (abfd, (bfd_vma) hashsize, temp); - if (bfd_write ((PTR) temp, 1, 4, abfd) != 4) - return false; - - hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize); - if (!hashtable) - return false; - - current = abfd->archive_head; - last_elt = current; - for (i = 0; i < orl_count; i++) - { - unsigned int hash, rehash; - - /* Advance firstreal to the file position of this archive - element. */ - if (((bfd *) map[i].pos) != last_elt) - { - do - { - firstreal += arelt_size (current) + sizeof (struct ar_hdr); - firstreal += firstreal % 2; - current = current->next; - } - while (current != (bfd *) map[i].pos); - } - - last_elt = current; - - hash = ecoff_armap_hash (*map[i].name, &rehash, hashsize, hashlog); - if (bfd_h_get_32 (abfd, (PTR) (hashtable + (hash * 8) + 4)) != 0) - { - unsigned int srch; - - /* The desired slot is already taken. */ - for (srch = (hash + rehash) & (hashsize - 1); - srch != hash; - srch = (srch + rehash) & (hashsize - 1)) - if (bfd_h_get_32 (abfd, (PTR) (hashtable + (srch * 8) + 4)) == 0) - break; - - BFD_ASSERT (srch != hash); - - hash = srch; - } - - bfd_h_put_32 (abfd, (bfd_vma) map[i].namidx, - (PTR) (hashtable + hash * 8)); - bfd_h_put_32 (abfd, (bfd_vma) firstreal, - (PTR) (hashtable + hash * 8 + 4)); - } - - if (bfd_write ((PTR) hashtable, 1, symdefsize, abfd) != symdefsize) - return false; - - bfd_release (abfd, hashtable); - - /* Now write the strings. */ - bfd_h_put_32 (abfd, (bfd_vma) stringsize, temp); - if (bfd_write ((PTR) temp, 1, 4, abfd) != 4) - return false; - for (i = 0; i < orl_count; i++) - { - bfd_size_type len; - - len = strlen (*map[i].name) + 1; - if (bfd_write ((PTR) (*map[i].name), 1, len, abfd) != len) - return false; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for DECstation ar we use a null. */ - if (padit) - { - if (bfd_write ("", 1, 1, abfd) != 1) - return false; - } - - return true; -} - -/* See whether this BFD is an archive. If it is, read in the armap - and the extended name table. */ - -const bfd_target * -_bfd_ecoff_archive_p (abfd) - bfd *abfd; -{ - char armag[SARMAG + 1]; - - if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG - || strncmp (armag, ARMAG, SARMAG) != 0) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return (const bfd_target *) NULL; - } - - /* We are setting bfd_ardata(abfd) here, but since bfd_ardata - involves a cast, we can't do it as the left operand of - assignment. */ - abfd->tdata.aout_ar_data = - (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata)); - - if (bfd_ardata (abfd) == (struct artdata *) NULL) - return (const bfd_target *) NULL; - - bfd_ardata (abfd)->first_file_filepos = SARMAG; - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->tdata = NULL; - - if (_bfd_ecoff_slurp_armap (abfd) == false - || _bfd_ecoff_slurp_extended_name_table (abfd) == false) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = (struct artdata *) NULL; - return (const bfd_target *) NULL; - } - - return abfd->xvec; -} - -/* ECOFF linker code. */ - -static struct bfd_hash_entry *ecoff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string)); -static boolean ecoff_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean ecoff_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean ecoff_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean ecoff_link_add_externals - PARAMS ((bfd *, struct bfd_link_info *, PTR, char *)); - -/* Routine to create an entry in an ECOFF link hash table. */ - -static struct bfd_hash_entry * -ecoff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct ecoff_link_hash_entry *ret = (struct ecoff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct ecoff_link_hash_entry *) NULL) - ret = ((struct ecoff_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct ecoff_link_hash_entry))); - if (ret == (struct ecoff_link_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct ecoff_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - - if (ret) - { - /* Set local fields. */ - ret->indx = -1; - ret->abfd = NULL; - ret->written = 0; - ret->small = 0; - } - memset ((PTR) &ret->esym, 0, sizeof ret->esym); - - return (struct bfd_hash_entry *) ret; -} - -/* Create an ECOFF link hash table. */ - -struct bfd_link_hash_table * -_bfd_ecoff_bfd_link_hash_table_create (abfd) - bfd *abfd; -{ - struct ecoff_link_hash_table *ret; - - ret = ((struct ecoff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct ecoff_link_hash_table))); - if (ret == NULL) - return NULL; - if (! _bfd_link_hash_table_init (&ret->root, abfd, - ecoff_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Look up an entry in an ECOFF link hash table. */ - -#define ecoff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct ecoff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) - -/* Traverse an ECOFF link hash table. */ - -#define ecoff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the ECOFF link hash table from the info structure. This is - just a cast. */ - -#define ecoff_hash_table(p) ((struct ecoff_link_hash_table *) ((p)->hash)) - -/* Given an ECOFF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -_bfd_ecoff_bfd_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return ecoff_link_add_object_symbols (abfd, info); - case bfd_archive: - return ecoff_link_add_archive_symbols (abfd, info); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add the symbols from an archive file to the global hash table. - This looks through the undefined symbols, looks each one up in the - archive hash table, and adds any associated object file. We do not - use _bfd_generic_link_add_archive_symbols because ECOFF archives - already have a hash table, so there is no reason to construct - another one. */ - -static boolean -ecoff_link_add_archive_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - const bfd_byte *raw_armap; - struct bfd_link_hash_entry **pundef; - unsigned int armap_count; - unsigned int armap_log; - unsigned int i; - const bfd_byte *hashtable; - const char *stringbase; - - if (! bfd_has_map (abfd)) - { - /* An empty archive is a special case. */ - if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL) - return true; - bfd_set_error (bfd_error_no_armap); - return false; - } - - /* If we don't have any raw data for this archive, as can happen on - Irix 4.0.5F, we call the generic routine. - FIXME: We should be more clever about this, since someday tdata - may get to something for a generic archive. */ - raw_armap = (const bfd_byte *) bfd_ardata (abfd)->tdata; - if (raw_armap == (bfd_byte *) NULL) - return (_bfd_generic_link_add_archive_symbols - (abfd, info, ecoff_link_check_archive_element)); - - armap_count = bfd_h_get_32 (abfd, raw_armap); - - armap_log = 0; - for (i = 1; i < armap_count; i <<= 1) - armap_log++; - BFD_ASSERT (i == armap_count); - - hashtable = raw_armap + 4; - stringbase = (const char *) raw_armap + armap_count * 8 + 8; - - /* Look through the list of undefined symbols. */ - pundef = &info->hash->undefs; - while (*pundef != (struct bfd_link_hash_entry *) NULL) - { - struct bfd_link_hash_entry *h; - unsigned int hash, rehash; - unsigned int file_offset; - const char *name; - bfd *element; - - h = *pundef; - - /* When a symbol is defined, it is not necessarily removed from - the list. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - { - /* Remove this entry from the list, for general cleanliness - and because we are going to look through the list again - if we search any more libraries. We can't remove the - entry if it is the tail, because that would lose any - entries we add to the list later on. */ - if (*pundef != info->hash->undefs_tail) - *pundef = (*pundef)->next; - else - pundef = &(*pundef)->next; - continue; - } - - /* Native ECOFF linkers do not pull in archive elements merely - to satisfy common definitions, so neither do we. We leave - them on the list, though, in case we are linking against some - other object format. */ - if (h->type != bfd_link_hash_undefined) - { - pundef = &(*pundef)->next; - continue; - } - - /* Look for this symbol in the archive hash table. */ - hash = ecoff_armap_hash (h->root.string, &rehash, armap_count, - armap_log); - - file_offset = bfd_h_get_32 (abfd, hashtable + (hash * 8) + 4); - if (file_offset == 0) - { - /* Nothing in this slot. */ - pundef = &(*pundef)->next; - continue; - } - - name = stringbase + bfd_h_get_32 (abfd, hashtable + (hash * 8)); - if (name[0] != h->root.string[0] - || strcmp (name, h->root.string) != 0) - { - unsigned int srch; - boolean found; - - /* That was the wrong symbol. Try rehashing. */ - found = false; - for (srch = (hash + rehash) & (armap_count - 1); - srch != hash; - srch = (srch + rehash) & (armap_count - 1)) - { - file_offset = bfd_h_get_32 (abfd, hashtable + (srch * 8) + 4); - if (file_offset == 0) - break; - name = stringbase + bfd_h_get_32 (abfd, hashtable + (srch * 8)); - if (name[0] == h->root.string[0] - && strcmp (name, h->root.string) == 0) - { - found = true; - break; - } - } - - if (! found) - { - pundef = &(*pundef)->next; - continue; - } - - hash = srch; - } - - element = (*backend->get_elt_at_filepos) (abfd, file_offset); - if (element == (bfd *) NULL) - return false; - - if (! bfd_check_format (element, bfd_object)) - return false; - - /* Unlike the generic linker, we know that this element provides - a definition for an undefined symbol and we know that we want - to include it. We don't need to check anything. */ - if (! (*info->callbacks->add_archive_element) (info, element, name)) - return false; - if (! ecoff_link_add_object_symbols (element, info)) - return false; - - pundef = &(*pundef)->next; - } - - return true; -} - -/* This is called if we used _bfd_generic_link_add_archive_symbols - because we were not dealing with an ECOFF archive. */ - -static boolean -ecoff_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) - = backend->debug_swap.swap_ext_in; - HDRR *symhdr; - bfd_size_type external_ext_size; - PTR external_ext = NULL; - size_t esize; - char *ssext = NULL; - char *ext_ptr; - char *ext_end; - - *pneeded = false; - - if (! ecoff_slurp_symbolic_header (abfd)) - goto error_return; - - /* If there are no symbols, we don't want it. */ - if (bfd_get_symcount (abfd) == 0) - goto successful_return; - - symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; - - /* Read in the external symbols and external strings. */ - external_ext_size = backend->debug_swap.external_ext_size; - esize = symhdr->iextMax * external_ext_size; - external_ext = (PTR) bfd_malloc (esize); - if (external_ext == NULL && esize != 0) - goto error_return; - - if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0 - || bfd_read (external_ext, 1, esize, abfd) != esize) - goto error_return; - - ssext = (char *) bfd_malloc (symhdr->issExtMax); - if (ssext == NULL && symhdr->issExtMax != 0) - goto error_return; - - if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0 - || (bfd_read (ssext, 1, symhdr->issExtMax, abfd) != - (bfd_size_type) symhdr->issExtMax)) - goto error_return; - - /* Look through the external symbols to see if they define some - symbol that is currently undefined. */ - ext_ptr = (char *) external_ext; - ext_end = ext_ptr + esize; - for (; ext_ptr < ext_end; ext_ptr += external_ext_size) - { - EXTR esym; - boolean def; - const char *name; - struct bfd_link_hash_entry *h; - - (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym); - - /* See if this symbol defines something. */ - if (esym.asym.st != stGlobal - && esym.asym.st != stLabel - && esym.asym.st != stProc) - continue; - - switch (esym.asym.sc) - { - case scText: - case scData: - case scBss: - case scAbs: - case scSData: - case scSBss: - case scRData: - case scCommon: - case scSCommon: - case scInit: - case scFini: - case scRConst: - def = true; - break; - default: - def = false; - break; - } - - if (! def) - continue; - - name = ssext + esym.asym.iss; - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* Unlike the generic linker, we do not pull in elements because - of common symbols. */ - if (h == (struct bfd_link_hash_entry *) NULL - || h->type != bfd_link_hash_undefined) - continue; - - /* Include this element. */ - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - goto error_return; - if (! ecoff_link_add_externals (abfd, info, external_ext, ssext)) - goto error_return; - - *pneeded = true; - goto successful_return; - } - - successful_return: - if (external_ext != NULL) - free (external_ext); - if (ssext != NULL) - free (ssext); - return true; - error_return: - if (external_ext != NULL) - free (external_ext); - if (ssext != NULL) - free (ssext); - return false; -} - -/* Add symbols from an ECOFF object file to the global linker hash - table. */ - -static boolean -ecoff_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - HDRR *symhdr; - bfd_size_type external_ext_size; - PTR external_ext = NULL; - size_t esize; - char *ssext = NULL; - boolean result; - - if (! ecoff_slurp_symbolic_header (abfd)) - return false; - - /* If there are no symbols, we don't want it. */ - if (bfd_get_symcount (abfd) == 0) - return true; - - symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; - - /* Read in the external symbols and external strings. */ - external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size; - esize = symhdr->iextMax * external_ext_size; - external_ext = (PTR) bfd_malloc (esize); - if (external_ext == NULL && esize != 0) - goto error_return; - - if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0 - || bfd_read (external_ext, 1, esize, abfd) != esize) - goto error_return; - - ssext = (char *) bfd_malloc (symhdr->issExtMax); - if (ssext == NULL && symhdr->issExtMax != 0) - goto error_return; - - if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0 - || (bfd_read (ssext, 1, symhdr->issExtMax, abfd) - != (bfd_size_type) symhdr->issExtMax)) - goto error_return; - - result = ecoff_link_add_externals (abfd, info, external_ext, ssext); - - if (ssext != NULL) - free (ssext); - if (external_ext != NULL) - free (external_ext); - return result; - - error_return: - if (ssext != NULL) - free (ssext); - if (external_ext != NULL) - free (external_ext); - return false; -} - -/* Add the external symbols of an object file to the global linker - hash table. The external symbols and strings we are passed are - just allocated on the stack, and will be discarded. We must - explicitly save any information we may need later on in the link. - We do not want to read the external symbol information again. */ - -static boolean -ecoff_link_add_externals (abfd, info, external_ext, ssext) - bfd *abfd; - struct bfd_link_info *info; - PTR external_ext; - char *ssext; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) - = backend->debug_swap.swap_ext_in; - bfd_size_type external_ext_size = backend->debug_swap.external_ext_size; - unsigned long ext_count; - struct ecoff_link_hash_entry **sym_hash; - char *ext_ptr; - char *ext_end; - - ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax; - - sym_hash = ((struct ecoff_link_hash_entry **) - bfd_alloc (abfd, - ext_count * sizeof (struct bfd_link_hash_entry *))); - if (!sym_hash) - return false; - ecoff_data (abfd)->sym_hashes = sym_hash; - - ext_ptr = (char *) external_ext; - ext_end = ext_ptr + ext_count * external_ext_size; - for (; ext_ptr < ext_end; ext_ptr += external_ext_size, sym_hash++) - { - EXTR esym; - boolean skip; - bfd_vma value; - asection *section; - const char *name; - struct ecoff_link_hash_entry *h; - - *sym_hash = NULL; - - (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym); - - /* Skip debugging symbols. */ - skip = false; - switch (esym.asym.st) - { - case stGlobal: - case stStatic: - case stLabel: - case stProc: - case stStaticProc: - break; - default: - skip = true; - break; - } - - if (skip) - continue; - - /* Get the information for this symbol. */ - value = esym.asym.value; - switch (esym.asym.sc) - { - default: - case scNil: - case scRegister: - case scCdbLocal: - case scBits: - case scCdbSystem: - case scRegImage: - case scInfo: - case scUserStruct: - case scVar: - case scVarRegister: - case scVariant: - case scBasedVar: - case scXData: - case scPData: - section = NULL; - break; - case scText: - section = bfd_make_section_old_way (abfd, ".text"); - value -= section->vma; - break; - case scData: - section = bfd_make_section_old_way (abfd, ".data"); - value -= section->vma; - break; - case scBss: - section = bfd_make_section_old_way (abfd, ".bss"); - value -= section->vma; - break; - case scAbs: - section = bfd_abs_section_ptr; - break; - case scUndefined: - section = bfd_und_section_ptr; - break; - case scSData: - section = bfd_make_section_old_way (abfd, ".sdata"); - value -= section->vma; - break; - case scSBss: - section = bfd_make_section_old_way (abfd, ".sbss"); - value -= section->vma; - break; - case scRData: - section = bfd_make_section_old_way (abfd, ".rdata"); - value -= section->vma; - break; - case scCommon: - if (value > ecoff_data (abfd)->gp_size) - { - section = bfd_com_section_ptr; - break; - } - /* Fall through. */ - case scSCommon: - if (ecoff_scom_section.name == NULL) - { - /* Initialize the small common section. */ - ecoff_scom_section.name = SCOMMON; - ecoff_scom_section.flags = SEC_IS_COMMON; - ecoff_scom_section.output_section = &ecoff_scom_section; - ecoff_scom_section.symbol = &ecoff_scom_symbol; - ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr; - ecoff_scom_symbol.name = SCOMMON; - ecoff_scom_symbol.flags = BSF_SECTION_SYM; - ecoff_scom_symbol.section = &ecoff_scom_section; - ecoff_scom_symbol_ptr = &ecoff_scom_symbol; - } - section = &ecoff_scom_section; - break; - case scSUndefined: - section = bfd_und_section_ptr; - break; - case scInit: - section = bfd_make_section_old_way (abfd, ".init"); - value -= section->vma; - break; - case scFini: - section = bfd_make_section_old_way (abfd, ".fini"); - value -= section->vma; - break; - case scRConst: - section = bfd_make_section_old_way (abfd, ".rconst"); - value -= section->vma; - break; - } - - if (section == (asection *) NULL) - continue; - - name = ssext + esym.asym.iss; - - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, - esym.weakext ? BSF_WEAK : BSF_GLOBAL, - section, value, (const char *) NULL, true, true, - (struct bfd_link_hash_entry **) &h))) - return false; - - *sym_hash = h; - - /* If we are building an ECOFF hash table, save the external - symbol information. */ - if (info->hash->creator->flavour == bfd_get_flavour (abfd)) - { - if (h->abfd == (bfd *) NULL - || (! bfd_is_und_section (section) - && (! bfd_is_com_section (section) - || (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak)))) - { - h->abfd = abfd; - h->esym = esym; - } - - /* Remember whether this symbol was small undefined. */ - if (esym.asym.sc == scSUndefined) - h->small = 1; - - /* If this symbol was ever small undefined, it needs to wind - up in a GP relative section. We can't control the - section of a defined symbol, but we can control the - section of a common symbol. This case is actually needed - on Ultrix 4.2 to handle the symbol cred in -lckrb. */ - if (h->small - && h->root.type == bfd_link_hash_common - && strcmp (h->root.u.c.p->section->name, SCOMMON) != 0) - { - h->root.u.c.p->section = bfd_make_section_old_way (abfd, - SCOMMON); - h->root.u.c.p->section->flags = SEC_ALLOC; - if (h->esym.asym.sc == scCommon) - h->esym.asym.sc = scSCommon; - } - } - } - - return true; -} - -/* ECOFF final link routines. */ - -static boolean ecoff_final_link_debug_accumulate - PARAMS ((bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *, - PTR handle)); -static boolean ecoff_link_write_external - PARAMS ((struct ecoff_link_hash_entry *, PTR)); -static boolean ecoff_indirect_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); -static boolean ecoff_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Structure used to pass information to ecoff_link_write_external. */ - -struct extsym_info -{ - bfd *abfd; - struct bfd_link_info *info; -}; - -/* ECOFF final link routine. This looks through all the input BFDs - and gathers together all the debugging information, and then - processes all the link order information. This may cause it to - close and reopen some input BFDs; I'll see how bad this is. */ - -boolean -_bfd_ecoff_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info; - HDRR *symhdr; - PTR handle; - register bfd *input_bfd; - asection *o; - struct bfd_link_order *p; - struct extsym_info einfo; - - /* We accumulate the debugging information counts in the symbolic - header. */ - symhdr = &debug->symbolic_header; - symhdr->vstamp = 0; - symhdr->ilineMax = 0; - symhdr->cbLine = 0; - symhdr->idnMax = 0; - symhdr->ipdMax = 0; - symhdr->isymMax = 0; - symhdr->ioptMax = 0; - symhdr->iauxMax = 0; - symhdr->issMax = 0; - symhdr->issExtMax = 0; - symhdr->ifdMax = 0; - symhdr->crfd = 0; - symhdr->iextMax = 0; - - /* We accumulate the debugging information itself in the debug_info - structure. */ - debug->line = NULL; - debug->external_dnr = NULL; - debug->external_pdr = NULL; - debug->external_sym = NULL; - debug->external_opt = NULL; - debug->external_aux = NULL; - debug->ss = NULL; - debug->ssext = debug->ssext_end = NULL; - debug->external_fdr = NULL; - debug->external_rfd = NULL; - debug->external_ext = debug->external_ext_end = NULL; - - handle = bfd_ecoff_debug_init (abfd, debug, &backend->debug_swap, info); - if (handle == (PTR) NULL) - return false; - - /* Accumulate the debugging symbols from each input BFD. */ - for (input_bfd = info->input_bfds; - input_bfd != (bfd *) NULL; - input_bfd = input_bfd->link_next) - { - boolean ret; - - if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour) - { - /* Abitrarily set the symbolic header vstamp to the vstamp - of the first object file in the link. */ - if (symhdr->vstamp == 0) - symhdr->vstamp - = ecoff_data (input_bfd)->debug_info.symbolic_header.vstamp; - ret = ecoff_final_link_debug_accumulate (abfd, input_bfd, info, - handle); - } - else - ret = bfd_ecoff_debug_accumulate_other (handle, abfd, - debug, &backend->debug_swap, - input_bfd, info); - if (! ret) - return false; - - /* Combine the register masks. */ - ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask; - ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask; - ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0]; - ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1]; - ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2]; - ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3]; - } - - /* Write out the external symbols. */ - einfo.abfd = abfd; - einfo.info = info; - ecoff_link_hash_traverse (ecoff_hash_table (info), - ecoff_link_write_external, - (PTR) &einfo); - - if (info->relocateable) - { - /* We need to make a pass over the link_orders to count up the - number of relocations we will need to output, so that we know - how much space they will take up. */ - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - o->reloc_count = 0; - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - if (p->type == bfd_indirect_link_order) - o->reloc_count += p->u.indirect.section->reloc_count; - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - } - } - - /* Compute the reloc and symbol file positions. */ - ecoff_compute_reloc_file_positions (abfd); - - /* Write out the debugging information. */ - if (! bfd_ecoff_write_accumulated_debug (handle, abfd, debug, - &backend->debug_swap, info, - ecoff_data (abfd)->sym_filepos)) - return false; - - bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info); - - if (info->relocateable) - { - /* Now reset the reloc_count field of the sections in the output - BFD to 0, so that we can use them to keep track of how many - relocs we have output thus far. */ - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - o->reloc_count = 0; - } - - /* Get a value for the GP register. */ - if (ecoff_data (abfd)->gp == 0) - { - struct bfd_link_hash_entry *h; - - h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_defined) - ecoff_data (abfd)->gp = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - else if (info->relocateable) - { - bfd_vma lo; - - /* Make up a value. */ - lo = (bfd_vma) -1; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - if (o->vma < lo - && (strcmp (o->name, _SBSS) == 0 - || strcmp (o->name, _SDATA) == 0 - || strcmp (o->name, _LIT4) == 0 - || strcmp (o->name, _LIT8) == 0 - || strcmp (o->name, _LITA) == 0)) - lo = o->vma; - } - ecoff_data (abfd)->gp = lo + 0x8000; - } - else - { - /* If the relocate_section function needs to do a reloc - involving the GP value, it should make a reloc_dangerous - callback to warn that GP is not defined. */ - } - } - - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_ecoff_flavour)) - { - if (! ecoff_indirect_link_order (abfd, info, o, p)) - return false; - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! ecoff_reloc_link_order (abfd, info, o, p)) - return false; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - return false; - } - } - } - - bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax; - - ecoff_data (abfd)->linker = true; - - return true; -} - -/* Accumulate the debugging information for an input BFD into the - output BFD. This must read in the symbolic information of the - input BFD. */ - -static boolean -ecoff_final_link_debug_accumulate (output_bfd, input_bfd, info, handle) - bfd *output_bfd; - bfd *input_bfd; - struct bfd_link_info *info; - PTR handle; -{ - struct ecoff_debug_info * const debug = &ecoff_data (input_bfd)->debug_info; - const struct ecoff_debug_swap * const swap = - &ecoff_backend (input_bfd)->debug_swap; - HDRR *symhdr = &debug->symbolic_header; - boolean ret; - -#define READ(ptr, offset, count, size, type) \ - if (symhdr->count == 0) \ - debug->ptr = NULL; \ - else \ - { \ - debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \ - if (debug->ptr == NULL) \ - { \ - ret = false; \ - goto return_something; \ - } \ - if ((bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) \ - != 0) \ - || (bfd_read (debug->ptr, size, symhdr->count, \ - input_bfd) != size * symhdr->count)) \ - { \ - ret = false; \ - goto return_something; \ - } \ - } - - /* If raw_syments is not NULL, then the data was already by read by - _bfd_ecoff_slurp_symbolic_info. */ - if (ecoff_data (input_bfd)->raw_syments == NULL) - { - READ (line, cbLineOffset, cbLine, sizeof (unsigned char), - unsigned char *); - READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); - READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); - READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); - READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); - READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), - union aux_ext *); - READ (ss, cbSsOffset, issMax, sizeof (char), char *); - READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); - READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); - } -#undef READ - - /* We do not read the external strings or the external symbols. */ - - ret = (bfd_ecoff_debug_accumulate - (handle, output_bfd, &ecoff_data (output_bfd)->debug_info, - &ecoff_backend (output_bfd)->debug_swap, - input_bfd, debug, swap, info)); - - return_something: - if (ecoff_data (input_bfd)->raw_syments == NULL) - { - if (debug->line != NULL) - free (debug->line); - if (debug->external_dnr != NULL) - free (debug->external_dnr); - if (debug->external_pdr != NULL) - free (debug->external_pdr); - if (debug->external_sym != NULL) - free (debug->external_sym); - if (debug->external_opt != NULL) - free (debug->external_opt); - if (debug->external_aux != NULL) - free (debug->external_aux); - if (debug->ss != NULL) - free (debug->ss); - if (debug->external_fdr != NULL) - free (debug->external_fdr); - if (debug->external_rfd != NULL) - free (debug->external_rfd); - - /* Make sure we don't accidentally follow one of these pointers - into freed memory. */ - debug->line = NULL; - debug->external_dnr = NULL; - debug->external_pdr = NULL; - debug->external_sym = NULL; - debug->external_opt = NULL; - debug->external_aux = NULL; - debug->ss = NULL; - debug->external_fdr = NULL; - debug->external_rfd = NULL; - } - - return ret; -} - -/* Put out information for an external symbol. These come only from - the hash table. */ - -static boolean -ecoff_link_write_external (h, data) - struct ecoff_link_hash_entry *h; - PTR data; -{ - struct extsym_info *einfo = (struct extsym_info *) data; - bfd *output_bfd = einfo->abfd; - boolean strip; - - /* We need to check if this symbol is being stripped. */ - if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - strip = false; - else if (einfo->info->strip == strip_all - || (einfo->info->strip == strip_some - && bfd_hash_lookup (einfo->info->keep_hash, - h->root.root.string, - false, false) == NULL)) - strip = true; - else - strip = false; - - if (strip || h->written) - return true; - - if (h->abfd == (bfd *) NULL) - { - h->esym.jmptbl = 0; - h->esym.cobol_main = 0; - h->esym.weakext = 0; - h->esym.reserved = 0; - h->esym.ifd = ifdNil; - h->esym.asym.value = 0; - h->esym.asym.st = stGlobal; - - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - h->esym.asym.sc = scAbs; - else - { - asection *output_section; - const char *name; - - output_section = h->root.u.def.section->output_section; - name = bfd_section_name (output_section->owner, output_section); - - if (strcmp (name, _TEXT) == 0) - h->esym.asym.sc = scText; - else if (strcmp (name, _DATA) == 0) - h->esym.asym.sc = scData; - else if (strcmp (name, _SDATA) == 0) - h->esym.asym.sc = scSData; - else if (strcmp (name, _RDATA) == 0) - h->esym.asym.sc = scRData; - else if (strcmp (name, _BSS) == 0) - h->esym.asym.sc = scBss; - else if (strcmp (name, _SBSS) == 0) - h->esym.asym.sc = scSBss; - else if (strcmp (name, _INIT) == 0) - h->esym.asym.sc = scInit; - else if (strcmp (name, _FINI) == 0) - h->esym.asym.sc = scFini; - else if (strcmp (name, _PDATA) == 0) - h->esym.asym.sc = scPData; - else if (strcmp (name, _XDATA) == 0) - h->esym.asym.sc = scXData; - else if (strcmp (name, _RCONST) == 0) - h->esym.asym.sc = scRConst; - else - h->esym.asym.sc = scAbs; - } - - h->esym.asym.reserved = 0; - h->esym.asym.index = indexNil; - } - else if (h->esym.ifd != -1) - { - struct ecoff_debug_info *debug; - - /* Adjust the FDR index for the symbol by that used for the - input BFD. */ - debug = &ecoff_data (h->abfd)->debug_info; - BFD_ASSERT (h->esym.ifd >= 0 - && h->esym.ifd < debug->symbolic_header.ifdMax); - h->esym.ifd = debug->ifdmap[h->esym.ifd]; - } - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - if (h->esym.asym.sc != scUndefined - && h->esym.asym.sc != scSUndefined) - h->esym.asym.sc = scUndefined; - break; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - if (h->esym.asym.sc == scUndefined - || h->esym.asym.sc == scSUndefined) - h->esym.asym.sc = scAbs; - else if (h->esym.asym.sc == scCommon) - h->esym.asym.sc = scBss; - else if (h->esym.asym.sc == scSCommon) - h->esym.asym.sc = scSBss; - h->esym.asym.value = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - break; - case bfd_link_hash_common: - if (h->esym.asym.sc != scCommon - && h->esym.asym.sc != scSCommon) - h->esym.asym.sc = scCommon; - h->esym.asym.value = h->root.u.c.size; - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: Ignore these for now. The circumstances under which - they should be written out are not clear to me. */ - return true; - } - - /* bfd_ecoff_debug_one_external uses iextMax to keep track of the - symbol number. */ - h->indx = ecoff_data (output_bfd)->debug_info.symbolic_header.iextMax; - h->written = 1; - - return (bfd_ecoff_debug_one_external - (output_bfd, &ecoff_data (output_bfd)->debug_info, - &ecoff_backend (output_bfd)->debug_swap, h->root.root.string, - &h->esym)); -} - -/* Relocate and write an ECOFF section into an ECOFF output file. */ - -static boolean -ecoff_indirect_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - asection *input_section; - bfd *input_bfd; - struct ecoff_section_tdata *section_tdata; - bfd_size_type raw_size; - bfd_size_type cooked_size; - bfd_byte *contents = NULL; - bfd_size_type external_reloc_size; - bfd_size_type external_relocs_size; - PTR external_relocs = NULL; - - BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); - - if (link_order->size == 0) - return true; - - input_section = link_order->u.indirect.section; - input_bfd = input_section->owner; - section_tdata = ecoff_section_data (input_bfd, input_section); - - raw_size = input_section->_raw_size; - cooked_size = input_section->_cooked_size; - if (cooked_size == 0) - cooked_size = raw_size; - - BFD_ASSERT (input_section->output_section == output_section); - BFD_ASSERT (input_section->output_offset == link_order->offset); - BFD_ASSERT (cooked_size == link_order->size); - - /* Get the section contents. We allocate memory for the larger of - the size before relocating and the size after relocating. */ - contents = (bfd_byte *) bfd_malloc (raw_size >= cooked_size - ? (size_t) raw_size - : (size_t) cooked_size); - if (contents == NULL && raw_size != 0) - goto error_return; - - /* If we are relaxing, the contents may have already been read into - memory, in which case we copy them into our new buffer. We don't - simply reuse the old buffer in case cooked_size > raw_size. */ - if (section_tdata != (struct ecoff_section_tdata *) NULL - && section_tdata->contents != (bfd_byte *) NULL) - memcpy (contents, section_tdata->contents, (size_t) raw_size); - else - { - if (! bfd_get_section_contents (input_bfd, input_section, - (PTR) contents, - (file_ptr) 0, raw_size)) - goto error_return; - } - - /* Get the relocs. If we are relaxing MIPS code, they will already - have been read in. Otherwise, we read them in now. */ - external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size; - external_relocs_size = external_reloc_size * input_section->reloc_count; - - if (section_tdata != (struct ecoff_section_tdata *) NULL - && section_tdata->external_relocs != NULL) - external_relocs = section_tdata->external_relocs; - else - { - external_relocs = (PTR) bfd_malloc ((size_t) external_relocs_size); - if (external_relocs == NULL && external_relocs_size != 0) - goto error_return; - - if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0 - || (bfd_read (external_relocs, 1, external_relocs_size, input_bfd) - != external_relocs_size)) - goto error_return; - } - - /* Relocate the section contents. */ - if (! ((*ecoff_backend (input_bfd)->relocate_section) - (output_bfd, info, input_bfd, input_section, contents, - external_relocs))) - goto error_return; - - /* Write out the relocated section. */ - if (! bfd_set_section_contents (output_bfd, - output_section, - (PTR) contents, - input_section->output_offset, - cooked_size)) - goto error_return; - - /* If we are producing relocateable output, the relocs were - modified, and we write them out now. We use the reloc_count - field of output_section to keep track of the number of relocs we - have output so far. */ - if (info->relocateable) - { - if (bfd_seek (output_bfd, - (output_section->rel_filepos + - output_section->reloc_count * external_reloc_size), - SEEK_SET) != 0 - || (bfd_write (external_relocs, 1, external_relocs_size, output_bfd) - != external_relocs_size)) - goto error_return; - output_section->reloc_count += input_section->reloc_count; - } - - if (contents != NULL) - free (contents); - if (external_relocs != NULL && section_tdata == NULL) - free (external_relocs); - return true; - - error_return: - if (contents != NULL) - free (contents); - if (external_relocs != NULL && section_tdata == NULL) - free (external_relocs); - return false; -} - -/* Generate a reloc when linking an ECOFF file. This is a reloc - requested by the linker, and does come from any input file. This - is used to build constructor and destructor tables when linking - with -Ur. */ - -static boolean -ecoff_reloc_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - enum bfd_link_order_type type; - asection *section; - bfd_vma addend; - arelent rel; - struct internal_reloc in; - bfd_size_type external_reloc_size; - bfd_byte *rbuf; - boolean ok; - - type = link_order->type; - section = NULL; - addend = link_order->u.reloc.p->addend; - - /* We set up an arelent to pass to the backend adjust_reloc_out - routine. */ - rel.address = link_order->offset; - - rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (rel.howto == 0) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (type == bfd_section_reloc_link_order) - { - section = link_order->u.reloc.p->u.section; - rel.sym_ptr_ptr = section->symbol_ptr_ptr; - } - else - { - struct bfd_link_hash_entry *h; - - /* Treat a reloc against a defined symbol as though it were - actually against the section. */ - h = bfd_wrapped_link_hash_lookup (output_bfd, info, - link_order->u.reloc.p->u.name, - false, false, false); - if (h != NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) - { - type = bfd_section_reloc_link_order; - section = h->u.def.section->output_section; - /* It seems that we ought to add the symbol value to the - addend here, but in practice it has already been added - because it was passed to constructor_callback. */ - addend += section->vma + h->u.def.section->output_offset; - } - else - { - /* We can't set up a reloc against a symbol correctly, - because we have no asymbol structure. Currently no - adjust_reloc_out routine cares. */ - rel.sym_ptr_ptr = (asymbol **) NULL; - } - } - - /* All ECOFF relocs are in-place. Put the addend into the object - file. */ - - BFD_ASSERT (rel.howto->partial_inplace); - if (addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (rel.howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - return false; - rstat = _bfd_relocate_contents (rel.howto, output_bfd, addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, section) - : link_order->u.reloc.p->u.name), - rel.howto->name, addend, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - rel.addend = 0; - - /* Move the information into a internal_reloc structure. */ - in.r_vaddr = (rel.address - + bfd_get_section_vma (output_bfd, output_section)); - in.r_type = rel.howto->type; - - if (type == bfd_symbol_reloc_link_order) - { - struct ecoff_link_hash_entry *h; - - h = ((struct ecoff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h != (struct ecoff_link_hash_entry *) NULL - && h->indx != -1) - in.r_symndx = h->indx; - else - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - in.r_symndx = 0; - } - in.r_extern = 1; - } - else - { - CONST char *name; - - name = bfd_get_section_name (output_bfd, section); - if (strcmp (name, ".text") == 0) - in.r_symndx = RELOC_SECTION_TEXT; - else if (strcmp (name, ".rdata") == 0) - in.r_symndx = RELOC_SECTION_RDATA; - else if (strcmp (name, ".data") == 0) - in.r_symndx = RELOC_SECTION_DATA; - else if (strcmp (name, ".sdata") == 0) - in.r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - in.r_symndx = RELOC_SECTION_SBSS; - else if (strcmp (name, ".bss") == 0) - in.r_symndx = RELOC_SECTION_BSS; - else if (strcmp (name, ".init") == 0) - in.r_symndx = RELOC_SECTION_INIT; - else if (strcmp (name, ".lit8") == 0) - in.r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - in.r_symndx = RELOC_SECTION_LIT4; - else if (strcmp (name, ".xdata") == 0) - in.r_symndx = RELOC_SECTION_XDATA; - else if (strcmp (name, ".pdata") == 0) - in.r_symndx = RELOC_SECTION_PDATA; - else if (strcmp (name, ".fini") == 0) - in.r_symndx = RELOC_SECTION_FINI; - else if (strcmp (name, ".lita") == 0) - in.r_symndx = RELOC_SECTION_LITA; - else if (strcmp (name, "*ABS*") == 0) - in.r_symndx = RELOC_SECTION_ABS; - else if (strcmp (name, ".rconst") == 0) - in.r_symndx = RELOC_SECTION_RCONST; - else - abort (); - in.r_extern = 0; - } - - /* Let the BFD backend adjust the reloc. */ - (*ecoff_backend (output_bfd)->adjust_reloc_out) (output_bfd, &rel, &in); - - /* Get some memory and swap out the reloc. */ - external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size; - rbuf = (bfd_byte *) bfd_malloc ((size_t) external_reloc_size); - if (rbuf == (bfd_byte *) NULL) - return false; - - (*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (PTR) rbuf); - - ok = (bfd_seek (output_bfd, - (output_section->rel_filepos + - output_section->reloc_count * external_reloc_size), - SEEK_SET) == 0 - && (bfd_write ((PTR) rbuf, 1, external_reloc_size, output_bfd) - == external_reloc_size)); - - if (ok) - ++output_section->reloc_count; - - free (rbuf); - - return ok; -} diff --git a/contrib/gdb/bfd/ecofflink.c b/contrib/gdb/bfd/ecofflink.c deleted file mode 100644 index 03d6e00ad18..00000000000 --- a/contrib/gdb/bfd/ecofflink.c +++ /dev/null @@ -1,2452 +0,0 @@ -/* Routines to link ECOFF debugging information. - Copyright 1993 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "obstack.h" -#include "aout/stab_gnu.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" - -static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend, - size_t need)); -static struct bfd_hash_entry *string_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); -static void ecoff_align_debug PARAMS ((bfd *abfd, - struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap)); -static boolean ecoff_write_symhdr PARAMS ((bfd *, struct ecoff_debug_info *, - const struct ecoff_debug_swap *, - file_ptr where)); -static int cmp_fdrtab_entry PARAMS ((const PTR, const PTR)); -static boolean mk_fdrtab PARAMS ((bfd *, - struct ecoff_debug_info * const, - const struct ecoff_debug_swap * const, - struct ecoff_find_line *)); -static long fdrtab_lookup PARAMS ((struct ecoff_find_line *, bfd_vma)); - -/* Obstack allocation and deallocation routines. */ -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free - -/* Routines to swap auxiliary information in and out. I am assuming - that the auxiliary information format is always going to be target - independent. */ - -/* Swap in a type information record. - BIGEND says whether AUX symbols are big-endian or little-endian; this - info comes from the file header record (fh-fBigendian). */ - -void -_bfd_ecoff_swap_tir_in (bigend, ext_copy, intern) - int bigend; - const struct tir_ext *ext_copy; - TIR *intern; -{ - struct tir_ext ext[1]; - - *ext = *ext_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG); - intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG); - intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_BIG) - >> TIR_BITS1_BT_SH_BIG; - intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG) - >> TIR_BITS_TQ4_SH_BIG; - intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG) - >> TIR_BITS_TQ5_SH_BIG; - intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG) - >> TIR_BITS_TQ0_SH_BIG; - intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG) - >> TIR_BITS_TQ1_SH_BIG; - intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG) - >> TIR_BITS_TQ2_SH_BIG; - intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG) - >> TIR_BITS_TQ3_SH_BIG; - } else { - intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE); - intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE); - intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE) - >> TIR_BITS1_BT_SH_LITTLE; - intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE) - >> TIR_BITS_TQ4_SH_LITTLE; - intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE) - >> TIR_BITS_TQ5_SH_LITTLE; - intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE) - >> TIR_BITS_TQ0_SH_LITTLE; - intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE) - >> TIR_BITS_TQ1_SH_LITTLE; - intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE) - >> TIR_BITS_TQ2_SH_LITTLE; - intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE) - >> TIR_BITS_TQ3_SH_LITTLE; - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a type information record. - BIGEND says whether AUX symbols are big-endian or little-endian; this - info comes from the file header record (fh-fBigendian). */ - -void -_bfd_ecoff_swap_tir_out (bigend, intern_copy, ext) - int bigend; - const TIR *intern_copy; - struct tir_ext *ext; -{ - TIR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0) - | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0) - | ((intern->bt << TIR_BITS1_BT_SH_BIG) - & TIR_BITS1_BT_BIG)); - ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG) - & TIR_BITS_TQ4_BIG) - | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG) - & TIR_BITS_TQ5_BIG)); - ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG) - & TIR_BITS_TQ0_BIG) - | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG) - & TIR_BITS_TQ1_BIG)); - ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG) - & TIR_BITS_TQ2_BIG) - | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG) - & TIR_BITS_TQ3_BIG)); - } else { - ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0) - | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0) - | ((intern->bt << TIR_BITS1_BT_SH_LITTLE) - & TIR_BITS1_BT_LITTLE)); - ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE) - & TIR_BITS_TQ4_LITTLE) - | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE) - & TIR_BITS_TQ5_LITTLE)); - ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE) - & TIR_BITS_TQ0_LITTLE) - | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE) - & TIR_BITS_TQ1_LITTLE)); - ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE) - & TIR_BITS_TQ2_LITTLE) - | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE) - & TIR_BITS_TQ3_LITTLE)); - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in a relative symbol record. BIGEND says whether it is in - big-endian or little-endian format.*/ - -void -_bfd_ecoff_swap_rndx_in (bigend, ext_copy, intern) - int bigend; - const struct rndx_ext *ext_copy; - RNDXR *intern; -{ - struct rndx_ext ext[1]; - - *ext = *ext_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG) - | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG) - >> RNDX_BITS1_RFD_SH_BIG); - intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG) - << RNDX_BITS1_INDEX_SH_LEFT_BIG) - | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG) - | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG); - } else { - intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE) - | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE) - << RNDX_BITS1_RFD_SH_LEFT_LITTLE); - intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE) - >> RNDX_BITS1_INDEX_SH_LITTLE) - | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE) - | ((unsigned int) ext->r_bits[3] - << RNDX_BITS3_INDEX_SH_LEFT_LITTLE); - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a relative symbol record. BIGEND says whether it is in - big-endian or little-endian format.*/ - -void -_bfd_ecoff_swap_rndx_out (bigend, intern_copy, ext) - int bigend; - const RNDXR *intern_copy; - struct rndx_ext *ext; -{ - RNDXR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG; - ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG) - & RNDX_BITS1_RFD_BIG) - | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG) - & RNDX_BITS1_INDEX_BIG)); - ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG; - ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG; - } else { - ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE; - ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE) - & RNDX_BITS1_RFD_LITTLE) - | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE) - & RNDX_BITS1_INDEX_LITTLE)); - ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE; - ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE; - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* The minimum amount of data to allocate. */ -#define ALLOC_SIZE (4064) - -/* Add bytes to a buffer. Return success. */ - -static boolean -ecoff_add_bytes (buf, bufend, need) - char **buf; - char **bufend; - size_t need; -{ - size_t have; - size_t want; - char *newbuf; - - have = *bufend - *buf; - if (have > need) - want = ALLOC_SIZE; - else - { - want = need - have; - if (want < ALLOC_SIZE) - want = ALLOC_SIZE; - } - newbuf = (char *) bfd_realloc (*buf, have + want); - if (newbuf == NULL) - return false; - *buf = newbuf; - *bufend = *buf + have + want; - return true; -} - -/* We keep a hash table which maps strings to numbers. We use it to - map FDR names to indices in the output file, and to map local - strings when combining stabs debugging information. */ - -struct string_hash_entry -{ - struct bfd_hash_entry root; - /* FDR index or string table offset. */ - long val; - /* Next entry in string table. */ - struct string_hash_entry *next; -}; - -struct string_hash_table -{ - struct bfd_hash_table table; -}; - -/* Routine to create an entry in a string hash table. */ - -static struct bfd_hash_entry * -string_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct string_hash_entry *ret = (struct string_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct string_hash_entry *) NULL) - ret = ((struct string_hash_entry *) - bfd_hash_allocate (table, sizeof (struct string_hash_entry))); - if (ret == (struct string_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct string_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->val = -1; - ret->next = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in an string hash table. */ - -#define string_hash_lookup(t, string, create, copy) \ - ((struct string_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* We can't afford to read in all the debugging information when we do - a link. Instead, we build a list of these structures to show how - different parts of the input file map to the output file. */ - -struct shuffle -{ - /* The next entry in this linked list. */ - struct shuffle *next; - /* The length of the information. */ - unsigned long size; - /* Whether this information comes from a file or not. */ - boolean filep; - union - { - struct - { - /* The BFD the data comes from. */ - bfd *input_bfd; - /* The offset within input_bfd. */ - file_ptr offset; - } file; - /* The data to be written out. */ - PTR memory; - } u; -}; - -/* This structure holds information across calls to - bfd_ecoff_debug_accumulate. */ - -struct accumulate -{ - /* The FDR hash table. */ - struct string_hash_table fdr_hash; - /* The strings hash table. */ - struct string_hash_table str_hash; - /* Linked lists describing how to shuffle the input debug - information into the output file. We keep a pointer to both the - head and the tail. */ - struct shuffle *line; - struct shuffle *line_end; - struct shuffle *pdr; - struct shuffle *pdr_end; - struct shuffle *sym; - struct shuffle *sym_end; - struct shuffle *opt; - struct shuffle *opt_end; - struct shuffle *aux; - struct shuffle *aux_end; - struct shuffle *ss; - struct shuffle *ss_end; - struct string_hash_entry *ss_hash; - struct string_hash_entry *ss_hash_end; - struct shuffle *fdr; - struct shuffle *fdr_end; - struct shuffle *rfd; - struct shuffle *rfd_end; - /* The size of the largest file shuffle. */ - unsigned long largest_file_shuffle; - /* An obstack for debugging information. */ - struct obstack memory; -}; - -/* Add a file entry to a shuffle list. */ - -static boolean add_file_shuffle PARAMS ((struct accumulate *, - struct shuffle **, - struct shuffle **, bfd *, file_ptr, - unsigned long)); - -static boolean -add_file_shuffle (ainfo, head, tail, input_bfd, offset, size) - struct accumulate *ainfo; - struct shuffle **head; - struct shuffle **tail; - bfd *input_bfd; - file_ptr offset; - unsigned long size; -{ - struct shuffle *n; - - if (*tail != (struct shuffle *) NULL - && (*tail)->filep - && (*tail)->u.file.input_bfd == input_bfd - && (*tail)->u.file.offset + (*tail)->size == (unsigned long) offset) - { - /* Just merge this entry onto the existing one. */ - (*tail)->size += size; - if ((*tail)->size > ainfo->largest_file_shuffle) - ainfo->largest_file_shuffle = (*tail)->size; - return true; - } - - n = (struct shuffle *) obstack_alloc (&ainfo->memory, - sizeof (struct shuffle)); - if (!n) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - n->next = NULL; - n->size = size; - n->filep = true; - n->u.file.input_bfd = input_bfd; - n->u.file.offset = offset; - if (*head == (struct shuffle *) NULL) - *head = n; - if (*tail != (struct shuffle *) NULL) - (*tail)->next = n; - *tail = n; - if (size > ainfo->largest_file_shuffle) - ainfo->largest_file_shuffle = size; - return true; -} - -/* Add a memory entry to a shuffle list. */ - -static boolean add_memory_shuffle PARAMS ((struct accumulate *, - struct shuffle **head, - struct shuffle **tail, - bfd_byte *data, unsigned long size)); - -static boolean -add_memory_shuffle (ainfo, head, tail, data, size) - struct accumulate *ainfo; - struct shuffle **head; - struct shuffle **tail; - bfd_byte *data; - unsigned long size; -{ - struct shuffle *n; - - n = (struct shuffle *) obstack_alloc (&ainfo->memory, - sizeof (struct shuffle)); - if (!n) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - n->next = NULL; - n->size = size; - n->filep = false; - n->u.memory = (PTR) data; - if (*head == (struct shuffle *) NULL) - *head = n; - if (*tail != (struct shuffle *) NULL) - (*tail)->next = n; - *tail = n; - return true; -} - -/* Initialize the FDR hash table. This returns a handle which is then - passed in to bfd_ecoff_debug_accumulate, et. al. */ - -/*ARGSUSED*/ -PTR -bfd_ecoff_debug_init (output_bfd, output_debug, output_swap, info) - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - struct bfd_link_info *info; -{ - struct accumulate *ainfo; - - ainfo = (struct accumulate *) bfd_malloc (sizeof (struct accumulate)); - if (!ainfo) - return NULL; - if (! bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc, - 1021)) - return NULL; - - ainfo->line = NULL; - ainfo->line_end = NULL; - ainfo->pdr = NULL; - ainfo->pdr_end = NULL; - ainfo->sym = NULL; - ainfo->sym_end = NULL; - ainfo->opt = NULL; - ainfo->opt_end = NULL; - ainfo->aux = NULL; - ainfo->aux_end = NULL; - ainfo->ss = NULL; - ainfo->ss_end = NULL; - ainfo->ss_hash = NULL; - ainfo->ss_hash_end = NULL; - ainfo->fdr = NULL; - ainfo->fdr_end = NULL; - ainfo->rfd = NULL; - ainfo->rfd_end = NULL; - - ainfo->largest_file_shuffle = 0; - - if (! info->relocateable) - { - if (! bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc)) - return NULL; - - /* The first entry in the string table is the empty string. */ - output_debug->symbolic_header.issMax = 1; - } - - if (!obstack_begin (&ainfo->memory, 4050)) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - return (PTR) ainfo; -} - -/* Free the accumulated debugging information. */ - -/*ARGSUSED*/ -void -bfd_ecoff_debug_free (handle, output_bfd, output_debug, output_swap, info) - PTR handle; - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - struct bfd_link_info *info; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - - bfd_hash_table_free (&ainfo->fdr_hash.table); - - if (! info->relocateable) - bfd_hash_table_free (&ainfo->str_hash.table); - - obstack_free (&ainfo->memory, (PTR) NULL); - - free (ainfo); -} - -/* Accumulate the debugging information from INPUT_BFD into - OUTPUT_BFD. The INPUT_DEBUG argument points to some ECOFF - debugging information which we want to link into the information - pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and - INPUT_SWAP point to the swapping information needed. INFO is the - linker information structure. HANDLE is returned by - bfd_ecoff_debug_init. */ - -/*ARGSUSED*/ -boolean -bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap, - input_bfd, input_debug, input_swap, - info) - PTR handle; - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - bfd *input_bfd; - struct ecoff_debug_info *input_debug; - const struct ecoff_debug_swap *input_swap; - struct bfd_link_info *info; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) - = input_swap->swap_sym_in; - void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *)) - = input_swap->swap_rfd_in; - void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR)) - = output_swap->swap_sym_out; - void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR)) - = output_swap->swap_fdr_out; - void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR)) - = output_swap->swap_rfd_out; - bfd_size_type external_pdr_size = output_swap->external_pdr_size; - bfd_size_type external_sym_size = output_swap->external_sym_size; - bfd_size_type external_opt_size = output_swap->external_opt_size; - bfd_size_type external_fdr_size = output_swap->external_fdr_size; - bfd_size_type external_rfd_size = output_swap->external_rfd_size; - HDRR * const output_symhdr = &output_debug->symbolic_header; - HDRR * const input_symhdr = &input_debug->symbolic_header; - bfd_vma section_adjust[scMax]; - asection *sec; - bfd_byte *fdr_start; - bfd_byte *fdr_ptr; - bfd_byte *fdr_end; - bfd_size_type fdr_add; - unsigned int copied; - RFDT i; - unsigned long sz; - bfd_byte *rfd_out; - bfd_byte *rfd_in; - bfd_byte *rfd_end; - long newrfdbase = 0; - long oldrfdbase = 0; - bfd_byte *fdr_out; - - /* Use section_adjust to hold the value to add to a symbol in a - particular section. */ - memset ((PTR) section_adjust, 0, sizeof section_adjust); - -#define SET(name, indx) \ - sec = bfd_get_section_by_name (input_bfd, name); \ - if (sec != NULL) \ - section_adjust[indx] = (sec->output_section->vma \ - + sec->output_offset \ - - sec->vma); - - SET (".text", scText); - SET (".data", scData); - SET (".bss", scBss); - SET (".sdata", scSData); - SET (".sbss", scSBss); - /* scRdata section may be either .rdata or .rodata. */ - SET (".rdata", scRData); - SET (".rodata", scRData); - SET (".init", scInit); - SET (".fini", scFini); - SET (".rconst", scRConst); - -#undef SET - - /* Find all the debugging information based on the FDR's. We need - to handle them whether they are swapped or not. */ - if (input_debug->fdr != (FDR *) NULL) - { - fdr_start = (bfd_byte *) input_debug->fdr; - fdr_add = sizeof (FDR); - } - else - { - fdr_start = (bfd_byte *) input_debug->external_fdr; - fdr_add = input_swap->external_fdr_size; - } - fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add; - - input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, - (input_symhdr->ifdMax - * sizeof (RFDT))); - - sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size; - rfd_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!input_debug->ifdmap || !rfd_out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz)) - return false; - - copied = 0; - - /* Look through the FDR's to see which ones we are going to include - in the final output. We do not want duplicate FDR information - for header files, because ECOFF debugging is often very large. - When we find an FDR with no line information which can be merged, - we look it up in a hash table to ensure that we only include it - once. We keep a table mapping FDR numbers to the final number - they get with the BFD, so that we can refer to it when we write - out the external symbols. */ - for (fdr_ptr = fdr_start, i = 0; - fdr_ptr < fdr_end; - fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size) - { - FDR fdr; - - if (input_debug->fdr != (FDR *) NULL) - fdr = *(FDR *) fdr_ptr; - else - (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr); - - /* See if this FDR can be merged with an existing one. */ - if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge) - { - const char *name; - char *lookup; - struct string_hash_entry *fh; - - /* We look up a string formed from the file name and the - number of symbols. Sometimes an include file will - conditionally define a typedef or something based on the - order of include files. Using the number of symbols as a - hash reduces the chance that we will merge symbol - information that should not be merged. */ - name = input_debug->ss + fdr.issBase + fdr.rss; - - lookup = (char *) bfd_malloc (strlen (name) + 20); - if (lookup == NULL) - return false; - sprintf (lookup, "%s %lx", name, fdr.csym); - - fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true); - free (lookup); - if (fh == (struct string_hash_entry *) NULL) - return false; - - if (fh->val != -1) - { - input_debug->ifdmap[i] = fh->val; - (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, - (PTR) rfd_out); - - /* Don't copy this FDR. */ - continue; - } - - fh->val = output_symhdr->ifdMax + copied; - } - - input_debug->ifdmap[i] = output_symhdr->ifdMax + copied; - (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, (PTR) rfd_out); - ++copied; - } - - newrfdbase = output_symhdr->crfd; - output_symhdr->crfd += input_symhdr->ifdMax; - - /* Copy over any existing RFD's. RFD's are only created by the - linker, so this will only happen for input files which are the - result of a partial link. */ - rfd_in = (bfd_byte *) input_debug->external_rfd; - rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size; - for (; - rfd_in < rfd_end; - rfd_in += input_swap->external_rfd_size) - { - RFDT rfd; - - (*swap_rfd_in) (input_bfd, (PTR) rfd_in, &rfd); - BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax); - rfd = input_debug->ifdmap[rfd]; - (*swap_rfd_out) (output_bfd, &rfd, (PTR) rfd_out); - rfd_out += external_rfd_size; - } - - oldrfdbase = output_symhdr->crfd; - output_symhdr->crfd += input_symhdr->crfd; - - /* Look through the FDR's and copy over all associated debugging - information. */ - sz = copied * external_fdr_size; - fdr_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!fdr_out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz)) - return false; - for (fdr_ptr = fdr_start, i = 0; - fdr_ptr < fdr_end; - fdr_ptr += fdr_add, i++) - { - FDR fdr; - bfd_vma fdr_adr; - bfd_byte *sym_out; - bfd_byte *lraw_src; - bfd_byte *lraw_end; - boolean fgotfilename; - - if (input_debug->ifdmap[i] < output_symhdr->ifdMax) - { - /* We are not copying this FDR. */ - continue; - } - - if (input_debug->fdr != (FDR *) NULL) - fdr = *(FDR *) fdr_ptr; - else - (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr); - - fdr_adr = fdr.adr; - - /* Adjust the FDR address for any changes that may have been - made by relaxing. */ - if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) - { - struct ecoff_value_adjust *adjust; - - for (adjust = input_debug->adjust; - adjust != (struct ecoff_value_adjust *) NULL; - adjust = adjust->next) - if (fdr_adr >= adjust->start - && fdr_adr < adjust->end) - fdr.adr += adjust->adjust; - } - - /* FIXME: It is conceivable that this FDR points to the .init or - .fini section, in which case this will not do the right - thing. */ - fdr.adr += section_adjust[scText]; - - /* Swap in the local symbols, adjust their values, and swap them - out again. */ - fgotfilename = false; - sz = fdr.csym * external_sym_size; - sym_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!sym_out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out, - sz)) - return false; - lraw_src = ((bfd_byte *) input_debug->external_sym - + fdr.isymBase * input_swap->external_sym_size); - lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size; - for (; lraw_src < lraw_end; lraw_src += input_swap->external_sym_size) - { - SYMR internal_sym; - - (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym); - - BFD_ASSERT (internal_sym.sc != scCommon - && internal_sym.sc != scSCommon); - - /* Adjust the symbol value if appropriate. */ - switch (internal_sym.st) - { - case stNil: - if (ECOFF_IS_STAB (&internal_sym)) - break; - /* Fall through. */ - case stGlobal: - case stStatic: - case stLabel: - case stProc: - case stStaticProc: - if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) - { - bfd_vma value; - struct ecoff_value_adjust *adjust; - - value = internal_sym.value; - for (adjust = input_debug->adjust; - adjust != (struct ecoff_value_adjust *) NULL; - adjust = adjust->next) - if (value >= adjust->start - && value < adjust->end) - internal_sym.value += adjust->adjust; - } - internal_sym.value += section_adjust[internal_sym.sc]; - break; - - default: - break; - } - - /* If we are doing a final link, we hash all the strings in - the local symbol table together. This reduces the amount - of space required by debugging information. We don't do - this when performing a relocateable link because it would - prevent us from easily merging different FDR's. */ - if (! info->relocateable) - { - boolean ffilename; - const char *name; - - if (! fgotfilename && internal_sym.iss == fdr.rss) - ffilename = true; - else - ffilename = false; - - /* Hash the name into the string table. */ - name = input_debug->ss + fdr.issBase + internal_sym.iss; - if (*name == '\0') - internal_sym.iss = 0; - else - { - struct string_hash_entry *sh; - - sh = string_hash_lookup (&ainfo->str_hash, name, true, true); - if (sh == (struct string_hash_entry *) NULL) - return false; - if (sh->val == -1) - { - sh->val = output_symhdr->issMax; - output_symhdr->issMax += strlen (name) + 1; - if (ainfo->ss_hash == (struct string_hash_entry *) NULL) - ainfo->ss_hash = sh; - if (ainfo->ss_hash_end - != (struct string_hash_entry *) NULL) - ainfo->ss_hash_end->next = sh; - ainfo->ss_hash_end = sh; - } - internal_sym.iss = sh->val; - } - - if (ffilename) - { - fdr.rss = internal_sym.iss; - fgotfilename = true; - } - } - - (*swap_sym_out) (output_bfd, &internal_sym, sym_out); - sym_out += external_sym_size; - } - - fdr.isymBase = output_symhdr->isymMax; - output_symhdr->isymMax += fdr.csym; - - /* Copy the information that does not need swapping. */ - - /* FIXME: If we are relaxing, we need to adjust the line - numbers. Frankly, forget it. Anybody using stabs debugging - information will not use this line number information, and - stabs are adjusted correctly. */ - if (fdr.cbLine > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end, - input_bfd, - input_symhdr->cbLineOffset + fdr.cbLineOffset, - fdr.cbLine)) - return false; - fdr.ilineBase = output_symhdr->ilineMax; - fdr.cbLineOffset = output_symhdr->cbLine; - output_symhdr->ilineMax += fdr.cline; - output_symhdr->cbLine += fdr.cbLine; - } - if (fdr.caux > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end, - input_bfd, - (input_symhdr->cbAuxOffset - + fdr.iauxBase * sizeof (union aux_ext)), - fdr.caux * sizeof (union aux_ext))) - return false; - fdr.iauxBase = output_symhdr->iauxMax; - output_symhdr->iauxMax += fdr.caux; - } - if (! info->relocateable) - { - - /* When are are hashing strings, we lie about the number of - strings attached to each FDR. We need to set cbSs - because some versions of dbx apparently use it to decide - how much of the string table to read in. */ - fdr.issBase = 0; - fdr.cbSs = output_symhdr->issMax; - } - else if (fdr.cbSs > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, - input_bfd, - input_symhdr->cbSsOffset + fdr.issBase, - fdr.cbSs)) - return false; - fdr.issBase = output_symhdr->issMax; - output_symhdr->issMax += fdr.cbSs; - } - - if ((output_bfd->xvec->header_byteorder - == input_bfd->xvec->header_byteorder) - && input_debug->adjust == (struct ecoff_value_adjust *) NULL) - { - /* The two BFD's have the same endianness, and we don't have - to adjust the PDR addresses, so simply copying the - information will suffice. */ - BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size); - if (fdr.cpd > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, - input_bfd, - (input_symhdr->cbPdOffset - + fdr.ipdFirst * external_pdr_size), - fdr.cpd * external_pdr_size)) - return false; - } - BFD_ASSERT (external_opt_size == input_swap->external_opt_size); - if (fdr.copt > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, - input_bfd, - (input_symhdr->cbOptOffset - + fdr.ioptBase * external_opt_size), - fdr.copt * external_opt_size)) - return false; - } - } - else - { - bfd_size_type outsz, insz; - bfd_byte *in; - bfd_byte *end; - bfd_byte *out; - - /* The two BFD's have different endianness, so we must swap - everything in and out. This code would always work, but - it would be unnecessarily slow in the normal case. */ - outsz = external_pdr_size; - insz = input_swap->external_pdr_size; - in = ((bfd_byte *) input_debug->external_pdr - + fdr.ipdFirst * insz); - end = in + fdr.cpd * insz; - sz = fdr.cpd * outsz; - out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out, - sz)) - return false; - for (; in < end; in += insz, out += outsz) - { - PDR pdr; - - (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr); - - /* If we have been relaxing, we may have to adjust the - address. */ - if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) - { - bfd_vma adr; - struct ecoff_value_adjust *adjust; - - adr = fdr_adr + pdr.adr; - for (adjust = input_debug->adjust; - adjust != (struct ecoff_value_adjust *) NULL; - adjust = adjust->next) - if (adr >= adjust->start - && adr < adjust->end) - pdr.adr += adjust->adjust; - } - - (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out); - } - - /* Swap over the optimization information. */ - outsz = external_opt_size; - insz = input_swap->external_opt_size; - in = ((bfd_byte *) input_debug->external_opt - + fdr.ioptBase * insz); - end = in + fdr.copt * insz; - sz = fdr.copt * outsz; - out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out, - sz)) - return false; - for (; in < end; in += insz, out += outsz) - { - OPTR opt; - - (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt); - (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out); - } - } - - fdr.ipdFirst = output_symhdr->ipdMax; - output_symhdr->ipdMax += fdr.cpd; - fdr.ioptBase = output_symhdr->ioptMax; - output_symhdr->ioptMax += fdr.copt; - - if (fdr.crfd <= 0) - { - /* Point this FDR at the table of RFD's we created. */ - fdr.rfdBase = newrfdbase; - fdr.crfd = input_symhdr->ifdMax; - } - else - { - /* Point this FDR at the remapped RFD's. */ - fdr.rfdBase += oldrfdbase; - } - - (*swap_fdr_out) (output_bfd, &fdr, fdr_out); - fdr_out += external_fdr_size; - ++output_symhdr->ifdMax; - } - - return true; -} - -/* Add a string to the debugging information we are accumulating. - Return the offset from the fdr string base. */ - -static long ecoff_add_string PARAMS ((struct accumulate *, - struct bfd_link_info *, - struct ecoff_debug_info *, - FDR *fdr, const char *string)); - -static long -ecoff_add_string (ainfo, info, debug, fdr, string) - struct accumulate *ainfo; - struct bfd_link_info *info; - struct ecoff_debug_info *debug; - FDR *fdr; - const char *string; -{ - HDRR *symhdr; - size_t len; - bfd_size_type ret; - - symhdr = &debug->symbolic_header; - len = strlen (string); - if (info->relocateable) - { - if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string, - len + 1)) - return -1; - ret = symhdr->issMax; - symhdr->issMax += len + 1; - fdr->cbSs += len + 1; - } - else - { - struct string_hash_entry *sh; - - sh = string_hash_lookup (&ainfo->str_hash, string, true, true); - if (sh == (struct string_hash_entry *) NULL) - return -1; - if (sh->val == -1) - { - sh->val = symhdr->issMax; - symhdr->issMax += len + 1; - if (ainfo->ss_hash == (struct string_hash_entry *) NULL) - ainfo->ss_hash = sh; - if (ainfo->ss_hash_end - != (struct string_hash_entry *) NULL) - ainfo->ss_hash_end->next = sh; - ainfo->ss_hash_end = sh; - } - ret = sh->val; - } - - return ret; -} - -/* Add debugging information from a non-ECOFF file. */ - -boolean -bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug, - output_swap, input_bfd, info) - PTR handle; - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - bfd *input_bfd; - struct bfd_link_info *info; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR)) - = output_swap->swap_sym_out; - HDRR *output_symhdr = &output_debug->symbolic_header; - FDR fdr; - asection *sec; - asymbol **symbols; - asymbol **sym_ptr; - asymbol **sym_end; - long symsize; - long symcount; - PTR external_fdr; - - memset ((PTR) &fdr, 0, sizeof fdr); - - sec = bfd_get_section_by_name (input_bfd, ".text"); - if (sec != NULL) - fdr.adr = sec->output_section->vma + sec->output_offset; - else - { - /* FIXME: What about .init or .fini? */ - fdr.adr = 0; - } - - fdr.issBase = output_symhdr->issMax; - fdr.cbSs = 0; - fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr, - bfd_get_filename (input_bfd)); - if (fdr.rss == -1) - return false; - fdr.isymBase = output_symhdr->isymMax; - - /* Get the local symbols from the input BFD. */ - symsize = bfd_get_symtab_upper_bound (input_bfd); - if (symsize < 0) - return false; - symbols = (asymbol **) bfd_alloc (output_bfd, symsize); - if (symbols == (asymbol **) NULL) - return false; - symcount = bfd_canonicalize_symtab (input_bfd, symbols); - if (symcount < 0) - return false; - sym_end = symbols + symcount; - - /* Handle the local symbols. Any external symbols are handled - separately. */ - fdr.csym = 0; - for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++) - { - SYMR internal_sym; - PTR external_sym; - - if (((*sym_ptr)->flags & BSF_EXPORT) != 0) - continue; - memset ((PTR) &internal_sym, 0, sizeof internal_sym); - internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr, - (*sym_ptr)->name); - - if (internal_sym.iss == -1) - return false; - if (bfd_is_com_section ((*sym_ptr)->section) - || bfd_is_und_section ((*sym_ptr)->section)) - internal_sym.value = (*sym_ptr)->value; - else - internal_sym.value = ((*sym_ptr)->value - + (*sym_ptr)->section->output_offset - + (*sym_ptr)->section->output_section->vma); - internal_sym.st = stNil; - internal_sym.sc = scUndefined; - internal_sym.index = indexNil; - - external_sym = (PTR) obstack_alloc (&ainfo->memory, - output_swap->external_sym_size); - if (!external_sym) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - (*swap_sym_out) (output_bfd, &internal_sym, external_sym); - add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, - external_sym, output_swap->external_sym_size); - ++fdr.csym; - ++output_symhdr->isymMax; - } - - bfd_release (output_bfd, (PTR) symbols); - - /* Leave everything else in the FDR zeroed out. This will cause - the lang field to be langC. The fBigendian field will - indicate little endian format, but it doesn't matter because - it only applies to aux fields and there are none. */ - external_fdr = (PTR) obstack_alloc (&ainfo->memory, - output_swap->external_fdr_size); - if (!external_fdr) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr); - add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, - external_fdr, output_swap->external_fdr_size); - - ++output_symhdr->ifdMax; - - return true; -} - -/* Set up ECOFF debugging information for the external symbols. - FIXME: This is done using a memory buffer, but it should be - probably be changed to use a shuffle structure. The assembler uses - this interface, so that must be changed to do something else. */ - -boolean -bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr, - set_index) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - boolean relocateable; - boolean (*get_extr) PARAMS ((asymbol *, EXTR *)); - void (*set_index) PARAMS ((asymbol *, bfd_size_type)); -{ - HDRR * const symhdr = &debug->symbolic_header; - asymbol **sym_ptr_ptr; - size_t c; - - sym_ptr_ptr = bfd_get_outsymbols (abfd); - if (sym_ptr_ptr == NULL) - return true; - - for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++) - { - asymbol *sym_ptr; - EXTR esym; - - sym_ptr = *sym_ptr_ptr; - - /* Get the external symbol information. */ - if ((*get_extr) (sym_ptr, &esym) == false) - continue; - - /* If we're producing an executable, move common symbols into - bss. */ - if (relocateable == false) - { - if (esym.asym.sc == scCommon) - esym.asym.sc = scBss; - else if (esym.asym.sc == scSCommon) - esym.asym.sc = scSBss; - } - - if (bfd_is_com_section (sym_ptr->section) - || bfd_is_und_section (sym_ptr->section) - || sym_ptr->section->output_section == (asection *) NULL) - { - /* FIXME: gas does not keep the value of a small undefined - symbol in the symbol itself, because of relocation - problems. */ - if (esym.asym.sc != scSUndefined - || esym.asym.value == 0 - || sym_ptr->value != 0) - esym.asym.value = sym_ptr->value; - } - else - esym.asym.value = (sym_ptr->value - + sym_ptr->section->output_offset - + sym_ptr->section->output_section->vma); - - if (set_index) - (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax); - - if (! bfd_ecoff_debug_one_external (abfd, debug, swap, - sym_ptr->name, &esym)) - return false; - } - - return true; -} - -/* Add a single external symbol to the debugging information. */ - -boolean -bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - const char *name; - EXTR *esym; -{ - const bfd_size_type external_ext_size = swap->external_ext_size; - void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR)) - = swap->swap_ext_out; - HDRR * const symhdr = &debug->symbolic_header; - size_t namelen; - - namelen = strlen (name); - - if ((size_t) (debug->ssext_end - debug->ssext) - < symhdr->issExtMax + namelen + 1) - { - if (ecoff_add_bytes ((char **) &debug->ssext, - (char **) &debug->ssext_end, - symhdr->issExtMax + namelen + 1) - == false) - return false; - } - if ((size_t) ((char *) debug->external_ext_end - - (char *) debug->external_ext) - < (symhdr->iextMax + 1) * external_ext_size) - { - if (ecoff_add_bytes ((char **) &debug->external_ext, - (char **) &debug->external_ext_end, - (symhdr->iextMax + 1) * external_ext_size) - == false) - return false; - } - - esym->asym.iss = symhdr->issExtMax; - - (*swap_ext_out) (abfd, esym, - ((char *) debug->external_ext - + symhdr->iextMax * swap->external_ext_size)); - - ++symhdr->iextMax; - - strcpy (debug->ssext + symhdr->issExtMax, name); - symhdr->issExtMax += namelen + 1; - - return true; -} - -/* Align the ECOFF debugging information. */ - -/*ARGSUSED*/ -static void -ecoff_align_debug (abfd, debug, swap) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; -{ - HDRR * const symhdr = &debug->symbolic_header; - bfd_size_type debug_align, aux_align, rfd_align; - size_t add; - - /* Adjust the counts so that structures are aligned. */ - debug_align = swap->debug_align; - aux_align = debug_align / sizeof (union aux_ext); - rfd_align = debug_align / swap->external_rfd_size; - - add = debug_align - (symhdr->cbLine & (debug_align - 1)); - if (add != debug_align) - { - if (debug->line != (unsigned char *) NULL) - memset ((PTR) (debug->line + symhdr->cbLine), 0, add); - symhdr->cbLine += add; - } - - add = debug_align - (symhdr->issMax & (debug_align - 1)); - if (add != debug_align) - { - if (debug->ss != (char *) NULL) - memset ((PTR) (debug->ss + symhdr->issMax), 0, add); - symhdr->issMax += add; - } - - add = debug_align - (symhdr->issExtMax & (debug_align - 1)); - if (add != debug_align) - { - if (debug->ssext != (char *) NULL) - memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add); - symhdr->issExtMax += add; - } - - add = aux_align - (symhdr->iauxMax & (aux_align - 1)); - if (add != aux_align) - { - if (debug->external_aux != (union aux_ext *) NULL) - memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0, - add * sizeof (union aux_ext)); - symhdr->iauxMax += add; - } - - add = rfd_align - (symhdr->crfd & (rfd_align - 1)); - if (add != rfd_align) - { - if (debug->external_rfd != (PTR) NULL) - memset ((PTR) ((char *) debug->external_rfd - + symhdr->crfd * swap->external_rfd_size), - 0, (size_t) (add * swap->external_rfd_size)); - symhdr->crfd += add; - } -} - -/* Return the size required by the ECOFF debugging information. */ - -bfd_size_type -bfd_ecoff_debug_size (abfd, debug, swap) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; -{ - bfd_size_type tot; - - ecoff_align_debug (abfd, debug, swap); - tot = swap->external_hdr_size; - -#define ADD(count, size) \ - tot += debug->symbolic_header.count * size - - ADD (cbLine, sizeof (unsigned char)); - ADD (idnMax, swap->external_dnr_size); - ADD (ipdMax, swap->external_pdr_size); - ADD (isymMax, swap->external_sym_size); - ADD (ioptMax, swap->external_opt_size); - ADD (iauxMax, sizeof (union aux_ext)); - ADD (issMax, sizeof (char)); - ADD (issExtMax, sizeof (char)); - ADD (ifdMax, swap->external_fdr_size); - ADD (crfd, swap->external_rfd_size); - ADD (iextMax, swap->external_ext_size); - -#undef ADD - - return tot; -} - -/* Write out the ECOFF symbolic header, given the file position it is - going to be placed at. This assumes that the counts are set - correctly. */ - -static boolean -ecoff_write_symhdr (abfd, debug, swap, where) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - file_ptr where; -{ - HDRR * const symhdr = &debug->symbolic_header; - char *buff = NULL; - - ecoff_align_debug (abfd, debug, swap); - - /* Go to the right location in the file. */ - if (bfd_seek (abfd, where, SEEK_SET) != 0) - return false; - - where += swap->external_hdr_size; - - symhdr->magic = swap->sym_magic; - - /* Fill in the file offsets. */ -#define SET(offset, count, size) \ - if (symhdr->count == 0) \ - symhdr->offset = 0; \ - else \ - { \ - symhdr->offset = where; \ - where += symhdr->count * size; \ - } - - SET (cbLineOffset, cbLine, sizeof (unsigned char)); - SET (cbDnOffset, idnMax, swap->external_dnr_size); - SET (cbPdOffset, ipdMax, swap->external_pdr_size); - SET (cbSymOffset, isymMax, swap->external_sym_size); - SET (cbOptOffset, ioptMax, swap->external_opt_size); - SET (cbAuxOffset, iauxMax, sizeof (union aux_ext)); - SET (cbSsOffset, issMax, sizeof (char)); - SET (cbSsExtOffset, issExtMax, sizeof (char)); - SET (cbFdOffset, ifdMax, swap->external_fdr_size); - SET (cbRfdOffset, crfd, swap->external_rfd_size); - SET (cbExtOffset, iextMax, swap->external_ext_size); -#undef SET - - buff = (PTR) bfd_malloc ((size_t) swap->external_hdr_size); - if (buff == NULL && swap->external_hdr_size != 0) - goto error_return; - - (*swap->swap_hdr_out) (abfd, symhdr, buff); - if (bfd_write (buff, 1, swap->external_hdr_size, abfd) - != swap->external_hdr_size) - goto error_return; - - if (buff != NULL) - free (buff); - return true; - error_return: - if (buff != NULL) - free (buff); - return false; -} - -/* Write out the ECOFF debugging information. This function assumes - that the information (the pointers and counts) in *DEBUG have been - set correctly. WHERE is the position in the file to write the - information to. This function fills in the file offsets in the - symbolic header. */ - -boolean -bfd_ecoff_write_debug (abfd, debug, swap, where) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - file_ptr where; -{ - HDRR * const symhdr = &debug->symbolic_header; - - if (! ecoff_write_symhdr (abfd, debug, swap, where)) - return false; - -#define WRITE(ptr, count, size, offset) \ - BFD_ASSERT (symhdr->offset == 0 \ - || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \ - if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \ - != size * symhdr->count) \ - return false; - - WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset); - WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset); - WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset); - WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset); - WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset); - WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset); - WRITE (ss, issMax, sizeof (char), cbSsOffset); - WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset); - WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset); - WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset); - WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset); -#undef WRITE - - return true; -} - -/* Write out a shuffle list. */ - -static boolean ecoff_write_shuffle PARAMS ((bfd *, - const struct ecoff_debug_swap *, - struct shuffle *, PTR space)); - -static boolean -ecoff_write_shuffle (abfd, swap, shuffle, space) - bfd *abfd; - const struct ecoff_debug_swap *swap; - struct shuffle *shuffle; - PTR space; -{ - register struct shuffle *l; - unsigned long total; - - total = 0; - for (l = shuffle; l != (struct shuffle *) NULL; l = l->next) - { - if (! l->filep) - { - if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size) - return false; - } - else - { - if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0 - || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size - || bfd_write (space, 1, l->size, abfd) != l->size) - return false; - } - total += l->size; - } - - if ((total & (swap->debug_align - 1)) != 0) - { - unsigned int i; - bfd_byte *s; - - i = swap->debug_align - (total & (swap->debug_align - 1)); - s = (bfd_byte *) bfd_malloc (i); - if (s == NULL && i != 0) - return false; - - memset ((PTR) s, 0, i); - if (bfd_write ((PTR) s, 1, i, abfd) != i) - { - free (s); - return false; - } - free (s); - } - - return true; -} - -/* Write out debugging information using accumulated linker - information. */ - -boolean -bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) - PTR handle; - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - struct bfd_link_info *info; - file_ptr where; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - PTR space = NULL; - - if (! ecoff_write_symhdr (abfd, debug, swap, where)) - goto error_return; - - space = (PTR) bfd_malloc (ainfo->largest_file_shuffle); - if (space == NULL && ainfo->largest_file_shuffle != 0) - goto error_return; - - if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space)) - goto error_return; - - /* The string table is written out from the hash table if this is a - final link. */ - if (info->relocateable) - { - BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL); - if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space)) - goto error_return; - } - else - { - unsigned long total; - bfd_byte null; - struct string_hash_entry *sh; - - BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL); - null = 0; - if (bfd_write ((PTR) &null, 1, 1, abfd) != 1) - goto error_return; - total = 1; - BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1); - for (sh = ainfo->ss_hash; - sh != (struct string_hash_entry *) NULL; - sh = sh->next) - { - size_t len; - - len = strlen (sh->root.string); - if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1) - goto error_return; - total += len + 1; - } - - if ((total & (swap->debug_align - 1)) != 0) - { - unsigned int i; - bfd_byte *s; - - i = swap->debug_align - (total & (swap->debug_align - 1)); - s = (bfd_byte *) bfd_malloc (i); - if (s == NULL && i != 0) - goto error_return; - memset ((PTR) s, 0, i); - if (bfd_write ((PTR) s, 1, i, abfd) != i) - { - free (s); - goto error_return; - } - free (s); - } - } - - /* The external strings and symbol are not converted over to using - shuffles. FIXME: They probably should be. */ - if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd) - != (bfd_size_type) debug->symbolic_header.issExtMax) - goto error_return; - if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0) - { - unsigned int i; - bfd_byte *s; - - i = (swap->debug_align - - (debug->symbolic_header.issExtMax & (swap->debug_align - 1))); - s = (bfd_byte *) bfd_malloc (i); - if (s == NULL && i != 0) - goto error_return; - memset ((PTR) s, 0, i); - if (bfd_write ((PTR) s, 1, i, abfd) != i) - { - free (s); - goto error_return; - } - free (s); - } - - if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space)) - goto error_return; - - BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0 - || (debug->symbolic_header.cbExtOffset - == (bfd_vma) bfd_tell (abfd))); - - if (bfd_write (debug->external_ext, swap->external_ext_size, - debug->symbolic_header.iextMax, abfd) - != debug->symbolic_header.iextMax * swap->external_ext_size) - goto error_return; - - if (space != NULL) - free (space); - return true; - - error_return: - if (space != NULL) - free (space); - return false; -} - -/* Handle the find_nearest_line function for both ECOFF and MIPS ELF - files. */ - -/* Compare FDR entries. This is called via qsort. */ - -static int -cmp_fdrtab_entry (leftp, rightp) - const PTR leftp; - const PTR rightp; -{ - const struct ecoff_fdrtab_entry *lp = - (const struct ecoff_fdrtab_entry *) leftp; - const struct ecoff_fdrtab_entry *rp = - (const struct ecoff_fdrtab_entry *) rightp; - - if (lp->base_addr < rp->base_addr) - return -1; - if (lp->base_addr > rp->base_addr) - return 1; - return 0; -} - -/* Each file descriptor (FDR) has a memory address, to simplify - looking up an FDR by address, we build a table covering all FDRs - that have a least one procedure descriptor in them. The final - table will be sorted by address so we can look it up via binary - search. */ - -static boolean -mk_fdrtab (abfd, debug_info, debug_swap, line_info) - bfd *abfd; - struct ecoff_debug_info * const debug_info; - const struct ecoff_debug_swap * const debug_swap; - struct ecoff_find_line *line_info; -{ - struct ecoff_fdrtab_entry *tab; - FDR *fdr_ptr; - FDR *fdr_start; - FDR *fdr_end; - boolean stabs; - long len; - - fdr_start = debug_info->fdr; - fdr_end = fdr_start + debug_info->symbolic_header.ifdMax; - - /* First, let's see how long the table needs to be: */ - for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++) - { - if (fdr_ptr->cpd == 0) /* skip FDRs that have no PDRs */ - continue; - ++len; - } - - /* Now, create and fill in the table: */ - - line_info->fdrtab = ((struct ecoff_fdrtab_entry*) - bfd_zalloc (abfd, - len * sizeof (struct ecoff_fdrtab_entry))); - if (line_info->fdrtab == NULL) - return false; - line_info->fdrtab_len = len; - - tab = line_info->fdrtab; - for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++) - { - if (fdr_ptr->cpd == 0) - continue; - - /* Check whether this file has stabs debugging information. In - a file with stabs debugging information, the second local - symbol is named @stabs. */ - stabs = false; - if (fdr_ptr->csym >= 2) - { - char *sym_ptr; - SYMR sym; - - sym_ptr = ((char *) debug_info->external_sym - + (fdr_ptr->isymBase + 1)*debug_swap->external_sym_size); - (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym); - if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss, - STABS_SYMBOL) == 0) - stabs = true; - } - - if (!stabs) - { - bfd_size_type external_pdr_size; - char *pdr_ptr; - PDR pdr; - - external_pdr_size = debug_swap->external_pdr_size; - - pdr_ptr = ((char *) debug_info->external_pdr - + fdr_ptr->ipdFirst * external_pdr_size); - (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); - /* The address of the first PDR is the offset of that - procedure relative to the beginning of file FDR. */ - tab->base_addr = fdr_ptr->adr - pdr.adr; - } - else - { - /* XXX I don't know about stabs, so this is a guess - (davidm@cs.arizona.edu): */ - tab->base_addr = fdr_ptr->adr; - } - tab->fdr = fdr_ptr; - ++tab; - } - - /* Finally, the table is sorted in increasing memory-address order. - The table is mostly sorted already, but there are cases (e.g., - static functions in include files), where this does not hold. - Use "odump -PFv" to verify... */ - qsort ((PTR) line_info->fdrtab, len, - sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry); - - return true; -} - -/* Return index of first FDR that covers to OFFSET. */ - -static long -fdrtab_lookup (line_info, offset) - struct ecoff_find_line *line_info; - bfd_vma offset; -{ - long low, high, len; - long mid = -1; - struct ecoff_fdrtab_entry *tab; - - len = line_info->fdrtab_len; - if (len == 0) - return -1; - - tab = line_info->fdrtab; - for (low = 0, high = len - 1 ; low != high ;) - { - mid = (high + low) / 2; - if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr) - goto find_min; - - if (tab[mid].base_addr > offset) - high = mid; - else - low = mid + 1; - } - ++mid; - - /* last entry is catch-all for all higher addresses: */ - if (offset < tab[mid].base_addr) - return -1; - - find_min: - - while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr) - --mid; - - return mid; -} - -/* Do the work of find_nearest_line. */ - -boolean -_bfd_ecoff_locate_line (abfd, section, offset, debug_info, debug_swap, - line_info, filename_ptr, functionname_ptr, retline_ptr) - bfd *abfd; - asection *section; - bfd_vma offset; - struct ecoff_debug_info * const debug_info; - const struct ecoff_debug_swap * const debug_swap; - struct ecoff_find_line *line_info; - const char **filename_ptr; - const char **functionname_ptr; - unsigned int *retline_ptr; -{ - struct ecoff_fdrtab_entry *tab; - boolean stabs; - FDR *fdr_ptr; - int i; - - offset += section->vma; - - /* Build FDR table (sorted by object file's base-address) if we - don't have it already. */ - if (line_info->fdrtab == NULL - && !mk_fdrtab (abfd, debug_info, debug_swap, line_info)) - return false; - - tab = line_info->fdrtab; - - /* find first FDR for address OFFSET */ - i = fdrtab_lookup (line_info, offset); - if (i < 0) - return false; /* no FDR, no fun... */ - fdr_ptr = tab[i].fdr; - - /* Check whether this file has stabs debugging information. In a - file with stabs debugging information, the second local symbol is - named @stabs. */ - stabs = false; - if (fdr_ptr->csym >= 2) - { - char *sym_ptr; - SYMR sym; - - sym_ptr = ((char *) debug_info->external_sym - + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size); - (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym); - if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss, - STABS_SYMBOL) == 0) - stabs = true; - } - - if (!stabs) - { - bfd_size_type external_pdr_size; - char *pdr_ptr; - char *best_pdr = NULL; - FDR *best_fdr; - bfd_vma best_dist = ~0; - PDR pdr; - unsigned char *line_ptr; - unsigned char *line_end; - int lineno; - /* This file uses ECOFF debugging information. Each FDR has a - list of procedure descriptors (PDR). The address in the FDR - is the absolute address of the first procedure. The address - in the first PDR gives the offset of that procedure relative - to the object file's base-address. The addresses in - subsequent PDRs specify each procedure's address relative to - the object file's base-address. To make things more juicy, - whenever the PROF bit in the PDR is set, the real entry point - of the procedure may be 16 bytes below what would normally be - the procedure's entry point. Instead, DEC came up with a - wicked scheme to create profiled libraries "on the fly": - instead of shipping a regular and a profiled version of each - library, they insert 16 bytes of unused space in front of - each procedure and set the "prof" bit in the PDR to indicate - that there is a gap there (this is done automagically by "as" - when option "-pg" is specified). Thus, normally, you link - against such a library and, except for lots of 16 byte gaps - between functions, things will behave as usual. However, - when invoking "ld" with option "-pg", it will fill those gaps - with code that calls mcount(). It then moves the function's - entry point down by 16 bytes, and out pops a binary that has - all functions profiled. - - NOTE: Neither FDRs nor PDRs are strictly sorted in memory - order. For example, when including header-files that - define functions, the FDRs follow behind the including - file, even though their code may have been generated at - a lower address. File coff-alpha.c from libbfd - illustrates this (use "odump -PFv" to look at a file's - FDR/PDR). Similarly, PDRs are sometimes out of order - as well. An example of this is OSF/1 v3.0 libc's - malloc.c. I'm not sure why this happens, but it could - be due to optimizations that reorder a function's - position within an object-file. - - Strategy: - - On the first call to this function, we build a table of FDRs - that is sorted by the base-address of the object-file the FDR - is referring to. Notice that each object-file may contain - code from multiple source files (e.g., due to code defined in - include files). Thus, for any given base-address, there may - be multiple FDRs (but this case is, fortunately, uncommon). - lookup(addr) guarantees to return the first FDR that applies - to address ADDR. Thus, after invoking lookup(), we have a - list of FDRs that may contain the PDR for ADDR. Next, we - walk through the PDRs of these FDRs and locate the one that - is closest to ADDR (i.e., for which the difference between - ADDR and the PDR's entry point is positive and minimal). - Once, the right FDR and PDR are located, we simply walk - through the line-number table to lookup the line-number that - best matches ADDR. Obviously, things could be sped up by - keeping a sorted list of PDRs instead of a sorted list of - FDRs. However, this would increase space requirements - considerably, which is undesirable. */ - external_pdr_size = debug_swap->external_pdr_size; - - /* Make offset relative to object file's start-address: */ - offset -= tab[i].base_addr; - /* Search FDR list starting at tab[i] for the PDR that best matches - OFFSET. Normally, the FDR list is only one entry long. */ - best_fdr = NULL; - do - { - bfd_vma dist, min_dist = 0; - char *pdr_hold; - char *pdr_end; - - fdr_ptr = tab[i].fdr; - - pdr_ptr = ((char *) debug_info->external_pdr - + fdr_ptr->ipdFirst * external_pdr_size); - pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size; - (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); - /* Find PDR that is closest to OFFSET. If pdr.prof is set, - the procedure entry-point *may* be 0x10 below pdr.adr. We - simply pretend that pdr.prof *implies* a lower entry-point. - This is safe because it just means that may identify 4 NOPs - in front of the function as belonging to the function. */ - for (pdr_hold = NULL; - pdr_ptr < pdr_end; - (pdr_ptr += external_pdr_size, - (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr))) - { - if (offset >= (pdr.adr - 0x10 * pdr.prof)) - { - dist = offset - (pdr.adr - 0x10 * pdr.prof); - if (!pdr_hold || dist < min_dist) - { - min_dist = dist; - pdr_hold = pdr_ptr; - } - } - } - - if (!best_pdr || min_dist < best_dist) - { - best_dist = min_dist; - best_fdr = fdr_ptr; - best_pdr = pdr_hold; - } - /* continue looping until base_addr of next entry is different: */ - } - while (++i < line_info->fdrtab_len - && tab[i].base_addr == tab[i - 1].base_addr); - - if (!best_fdr || !best_pdr) - return false; /* shouldn't happen... */ - - /* phew, finally we got something that we can hold onto: */ - fdr_ptr = best_fdr; - pdr_ptr = best_pdr; - (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); - /* Now we can look for the actual line number. The line numbers - are stored in a very funky format, which I won't try to - describe. The search is bounded by the end of the FDRs line - number entries. */ - line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine; - - /* Make offset relative to procedure entry: */ - offset -= pdr.adr - 0x10 * pdr.prof; - lineno = pdr.lnLow; - line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset; - while (line_ptr < line_end) - { - int delta; - unsigned int count; - - delta = *line_ptr >> 4; - if (delta >= 0x8) - delta -= 0x10; - count = (*line_ptr & 0xf) + 1; - ++line_ptr; - if (delta == -8) - { - delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff); - if (delta >= 0x8000) - delta -= 0x10000; - line_ptr += 2; - } - lineno += delta; - if (offset < count * 4) - break; - offset -= count * 4; - } - - /* If fdr_ptr->rss is -1, then this file does not have full - symbols, at least according to gdb/mipsread.c. */ - if (fdr_ptr->rss == -1) - { - *filename_ptr = NULL; - if (pdr.isym == -1) - *functionname_ptr = NULL; - else - { - EXTR proc_ext; - - (*debug_swap->swap_ext_in) - (abfd, - ((char *) debug_info->external_ext - + pdr.isym * debug_swap->external_ext_size), - &proc_ext); - *functionname_ptr = debug_info->ssext + proc_ext.asym.iss; - } - } - else - { - SYMR proc_sym; - - *filename_ptr = debug_info->ss + fdr_ptr->issBase + fdr_ptr->rss; - (*debug_swap->swap_sym_in) - (abfd, - ((char *) debug_info->external_sym - + (fdr_ptr->isymBase + pdr.isym) * debug_swap->external_sym_size), - &proc_sym); - *functionname_ptr = debug_info->ss + fdr_ptr->issBase + proc_sym.iss; - } - if (lineno == ilineNil) - lineno = 0; - *retline_ptr = lineno; - } - else - { - bfd_size_type external_sym_size; - const char *directory_name; - const char *main_file_name; - const char *current_file_name; - const char *function_name; - const char *line_file_name; - bfd_vma low_func_vma; - bfd_vma low_line_vma; - boolean past_line; - boolean past_fn; - char *sym_ptr, *sym_ptr_end; - size_t len, funclen; - char *buffer = NULL; - - /* This file uses stabs debugging information. When gcc is not - optimizing, it will put the line number information before - the function name stabs entry. When gcc is optimizing, it - will put the stabs entry for all the function first, followed - by the line number information. (This appears to happen - because of the two output files used by the -mgpopt switch, - which is implied by -O). This means that we must keep - looking through the symbols until we find both a line number - and a function name which are beyond the address we want. */ - - *filename_ptr = NULL; - *functionname_ptr = NULL; - *retline_ptr = 0; - - directory_name = NULL; - main_file_name = NULL; - current_file_name = NULL; - function_name = NULL; - line_file_name = NULL; - low_func_vma = 0; - low_line_vma = 0; - past_line = false; - past_fn = false; - - external_sym_size = debug_swap->external_sym_size; - - sym_ptr = ((char *) debug_info->external_sym - + (fdr_ptr->isymBase + 2) * external_sym_size); - sym_ptr_end = sym_ptr + (fdr_ptr->csym - 2) * external_sym_size; - for (; - sym_ptr < sym_ptr_end && (! past_line || ! past_fn); - sym_ptr += external_sym_size) - { - SYMR sym; - - (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym); - - if (ECOFF_IS_STAB (&sym)) - { - switch (ECOFF_UNMARK_STAB (sym.index)) - { - case N_SO: - main_file_name = current_file_name = - debug_info->ss + fdr_ptr->issBase + sym.iss; - - /* Check the next symbol to see if it is also an - N_SO symbol. */ - if (sym_ptr + external_sym_size < sym_ptr_end) - { - SYMR nextsym; - - (*debug_swap->swap_sym_in) (abfd, - sym_ptr + external_sym_size, - &nextsym); - if (ECOFF_IS_STAB (&nextsym) - && ECOFF_UNMARK_STAB (nextsym.index) == N_SO) - { - directory_name = current_file_name; - main_file_name = current_file_name = - debug_info->ss + fdr_ptr->issBase + nextsym.iss; - sym_ptr += external_sym_size; - } - } - break; - - case N_SOL: - current_file_name = - debug_info->ss + fdr_ptr->issBase + sym.iss; - break; - - case N_FUN: - if (sym.value > offset) - past_fn = true; - else if (sym.value >= low_func_vma) - { - low_func_vma = sym.value; - function_name = - debug_info->ss + fdr_ptr->issBase + sym.iss; - } - break; - } - } - else if (sym.st == stLabel && sym.index != indexNil) - { - if (sym.value > offset) - past_line = true; - else if (sym.value >= low_line_vma) - { - low_line_vma = sym.value; - line_file_name = current_file_name; - *retline_ptr = sym.index; - } - } - } - - if (*retline_ptr != 0) - main_file_name = line_file_name; - - /* We need to remove the stuff after the colon in the function - name. We also need to put the directory name and the file - name together. */ - if (function_name == NULL) - len = funclen = 0; - else - len = funclen = strlen (function_name) + 1; - - if (main_file_name != NULL - && directory_name != NULL - && main_file_name[0] != '/') - len += strlen (directory_name) + strlen (main_file_name) + 1; - - if (len != 0) - { - if (line_info->find_buffer != NULL) - free (line_info->find_buffer); - buffer = (char *) bfd_malloc (len); - if (buffer == NULL) - return false; - line_info->find_buffer = buffer; - } - - if (function_name != NULL) - { - char *colon; - - strcpy (buffer, function_name); - colon = strchr (buffer, ':'); - if (colon != NULL) - *colon = '\0'; - *functionname_ptr = buffer; - } - - if (main_file_name != NULL) - { - if (directory_name == NULL || main_file_name[0] == '/') - *filename_ptr = main_file_name; - else - { - sprintf (buffer + funclen, "%s%s", directory_name, - main_file_name); - *filename_ptr = buffer + funclen; - } - } - } - - return true; -} - -/* These routines copy symbolic information into a memory buffer. - - FIXME: The whole point of the shuffle code is to avoid storing - everything in memory, since the linker is such a memory hog. This - code makes that effort useless. It is only called by the MIPS ELF - code when generating a shared library, so it is not that big a - deal, but it should be fixed eventually. */ - -/* Collect a shuffle into a memory buffer. */ - -static boolean ecoff_collect_shuffle PARAMS ((struct shuffle *, bfd_byte *)); - -static boolean -ecoff_collect_shuffle (l, buff) - struct shuffle *l; - bfd_byte *buff; -{ - unsigned long total; - - total = 0; - for (; l != (struct shuffle *) NULL; l = l->next) - { - if (! l->filep) - memcpy (buff, l->u.memory, l->size); - else - { - if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0 - || bfd_read (buff, 1, l->size, l->u.file.input_bfd) != l->size) - return false; - } - total += l->size; - buff += l->size; - } - - return true; -} - -/* Copy PDR information into a memory buffer. */ - -boolean -_bfd_ecoff_get_accumulated_pdr (handle, buff) - PTR handle; - bfd_byte *buff; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - - return ecoff_collect_shuffle (ainfo->pdr, buff); -} - -/* Copy symbol information into a memory buffer. */ - -boolean -_bfd_ecoff_get_accumulated_sym (handle, buff) - PTR handle; - bfd_byte *buff; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - - return ecoff_collect_shuffle (ainfo->sym, buff); -} - -/* Copy the string table into a memory buffer. */ - -boolean -_bfd_ecoff_get_accumulated_ss (handle, buff) - PTR handle; - bfd_byte *buff; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - struct string_hash_entry *sh; - unsigned long total; - - /* The string table is written out from the hash table if this is a - final link. */ - BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL); - *buff++ = '\0'; - total = 1; - BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1); - for (sh = ainfo->ss_hash; - sh != (struct string_hash_entry *) NULL; - sh = sh->next) - { - size_t len; - - len = strlen (sh->root.string); - memcpy (buff, (PTR) sh->root.string, len + 1); - total += len + 1; - buff += len + 1; - } - - return true; -} diff --git a/contrib/gdb/bfd/ecoffswap.h b/contrib/gdb/bfd/ecoffswap.h deleted file mode 100644 index 0d28d16883e..00000000000 --- a/contrib/gdb/bfd/ecoffswap.h +++ /dev/null @@ -1,853 +0,0 @@ -/* Generic ECOFF swapping routines, for BFD. - Copyright 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* NOTE: This is a header file, but it contains executable routines. - This is done this way because these routines are substantially - similar, but are not identical, for all ECOFF targets. - - These are routines to swap the ECOFF symbolic information in and - out. The routines are defined statically. You can set breakpoints - on them in gdb by naming the including source file; e.g., - 'coff-mips.c':ecoff_swap_hdr_in. - - Before including this header file, one of ECOFF_32 or ECOFF_64 must - be defined. These are checked when swapping information that - depends upon the target size. This code works for 32 bit and 64 - bit ECOFF, but may need to be generalized in the future. - - Some header file which defines the external forms of these - structures must also be included before including this header file. - Currently this is either coff/mips.h or coff/alpha.h. - - If the symbol TEST is defined when this file is compiled, a - comparison is made to ensure that, in fact, the output is - bit-for-bit the same as the input. Of course, this symbol should - only be defined when deliberately testing the code on a machine - with the proper byte sex and such. */ - -#ifdef ECOFF_32 -#define ecoff_get_off bfd_h_get_32 -#define ecoff_put_off bfd_h_put_32 -#endif -#ifdef ECOFF_64 -#define ecoff_get_off bfd_h_get_64 -#define ecoff_put_off bfd_h_put_64 -#endif - -/* ECOFF auxiliary information swapping routines. These are the same - for all ECOFF targets, so they are defined in ecofflink.c. */ - -extern void _bfd_ecoff_swap_tir_in - PARAMS ((int, const struct tir_ext *, TIR *)); -extern void _bfd_ecoff_swap_tir_out - PARAMS ((int, const TIR *, struct tir_ext *)); -extern void _bfd_ecoff_swap_rndx_in - PARAMS ((int, const struct rndx_ext *, RNDXR *)); -extern void _bfd_ecoff_swap_rndx_out - PARAMS ((int, const RNDXR *, struct rndx_ext *)); - -/* Prototypes for functions defined in this file. */ - -static void ecoff_swap_hdr_in PARAMS ((bfd *, PTR, HDRR *)); -static void ecoff_swap_hdr_out PARAMS ((bfd *, const HDRR *, PTR)); -static void ecoff_swap_fdr_in PARAMS ((bfd *, PTR, FDR *)); -static void ecoff_swap_fdr_out PARAMS ((bfd *, const FDR *, PTR)); -static void ecoff_swap_pdr_in PARAMS ((bfd *, PTR, PDR *)); -static void ecoff_swap_pdr_out PARAMS ((bfd *, const PDR *, PTR)); -static void ecoff_swap_sym_in PARAMS ((bfd *, PTR, SYMR *)); -static void ecoff_swap_sym_out PARAMS ((bfd *, const SYMR *, PTR)); -static void ecoff_swap_ext_in PARAMS ((bfd *, PTR, EXTR *)); -static void ecoff_swap_ext_out PARAMS ((bfd *, const EXTR *, PTR)); -static void ecoff_swap_rfd_in PARAMS ((bfd *, PTR, RFDT *)); -static void ecoff_swap_rfd_out PARAMS ((bfd *, const RFDT *, PTR)); -static void ecoff_swap_opt_in PARAMS ((bfd *, PTR, OPTR *)); -static void ecoff_swap_opt_out PARAMS ((bfd *, const OPTR *, PTR)); -static void ecoff_swap_dnr_in PARAMS ((bfd *, PTR, DNR *)); -static void ecoff_swap_dnr_out PARAMS ((bfd *, const DNR *, PTR)); - -/* Swap in the symbolic header. */ - -static void -ecoff_swap_hdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - HDRR *intern; -{ - struct hdr_ext ext[1]; - - *ext = *(struct hdr_ext *) ext_copy; - - intern->magic = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_magic); - intern->vstamp = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_vstamp); - intern->ilineMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ilineMax); - intern->cbLine = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLine); - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLineOffset); - intern->idnMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_idnMax); - intern->cbDnOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbDnOffset); - intern->ipdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ipdMax); - intern->cbPdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbPdOffset); - intern->isymMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_isymMax); - intern->cbSymOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSymOffset); - intern->ioptMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ioptMax); - intern->cbOptOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbOptOffset); - intern->iauxMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iauxMax); - intern->cbAuxOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbAuxOffset); - intern->issMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issMax); - intern->cbSsOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsOffset); - intern->issExtMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issExtMax); - intern->cbSsExtOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsExtOffset); - intern->ifdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ifdMax); - intern->cbFdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbFdOffset); - intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_crfd); - intern->cbRfdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbRfdOffset); - intern->iextMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iextMax); - intern->cbExtOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbExtOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the symbolic header. */ - -static void -ecoff_swap_hdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const HDRR *intern_copy; - PTR ext_ptr; -{ - struct hdr_ext *ext = (struct hdr_ext *) ext_ptr; - HDRR intern[1]; - - *intern = *intern_copy; - - bfd_h_put_signed_16 (abfd, intern->magic, (bfd_byte *)ext->h_magic); - bfd_h_put_signed_16 (abfd, intern->vstamp, (bfd_byte *)ext->h_vstamp); - bfd_h_put_32 (abfd, intern->ilineMax, (bfd_byte *)ext->h_ilineMax); - ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->h_cbLine); - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->h_cbLineOffset); - bfd_h_put_32 (abfd, intern->idnMax, (bfd_byte *)ext->h_idnMax); - ecoff_put_off (abfd, intern->cbDnOffset, (bfd_byte *)ext->h_cbDnOffset); - bfd_h_put_32 (abfd, intern->ipdMax, (bfd_byte *)ext->h_ipdMax); - ecoff_put_off (abfd, intern->cbPdOffset, (bfd_byte *)ext->h_cbPdOffset); - bfd_h_put_32 (abfd, intern->isymMax, (bfd_byte *)ext->h_isymMax); - ecoff_put_off (abfd, intern->cbSymOffset, (bfd_byte *)ext->h_cbSymOffset); - bfd_h_put_32 (abfd, intern->ioptMax, (bfd_byte *)ext->h_ioptMax); - ecoff_put_off (abfd, intern->cbOptOffset, (bfd_byte *)ext->h_cbOptOffset); - bfd_h_put_32 (abfd, intern->iauxMax, (bfd_byte *)ext->h_iauxMax); - ecoff_put_off (abfd, intern->cbAuxOffset, (bfd_byte *)ext->h_cbAuxOffset); - bfd_h_put_32 (abfd, intern->issMax, (bfd_byte *)ext->h_issMax); - ecoff_put_off (abfd, intern->cbSsOffset, (bfd_byte *)ext->h_cbSsOffset); - bfd_h_put_32 (abfd, intern->issExtMax, (bfd_byte *)ext->h_issExtMax); - ecoff_put_off (abfd, intern->cbSsExtOffset, (bfd_byte *)ext->h_cbSsExtOffset); - bfd_h_put_32 (abfd, intern->ifdMax, (bfd_byte *)ext->h_ifdMax); - ecoff_put_off (abfd, intern->cbFdOffset, (bfd_byte *)ext->h_cbFdOffset); - bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->h_crfd); - ecoff_put_off (abfd, intern->cbRfdOffset, (bfd_byte *)ext->h_cbRfdOffset); - bfd_h_put_32 (abfd, intern->iextMax, (bfd_byte *)ext->h_iextMax); - ecoff_put_off (abfd, intern->cbExtOffset, (bfd_byte *)ext->h_cbExtOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in the file descriptor record. */ - -static void -ecoff_swap_fdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - FDR *intern; -{ - struct fdr_ext ext[1]; - - *ext = *(struct fdr_ext *) ext_copy; - - intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->f_adr); - intern->rss = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rss); -#ifdef ECOFF_64 - if (intern->rss == 0xffffffff) - intern->rss = -1; -#endif - intern->issBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_issBase); - intern->cbSs = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbSs); - intern->isymBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_isymBase); - intern->csym = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_csym); - intern->ilineBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ilineBase); - intern->cline = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cline); - intern->ioptBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ioptBase); - intern->copt = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_copt); -#ifdef ECOFF_32 - intern->ipdFirst = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_ipdFirst); - intern->cpd = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_cpd); -#endif -#ifdef ECOFF_64 - intern->ipdFirst = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ipdFirst); - intern->cpd = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cpd); -#endif - intern->iauxBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_iauxBase); - intern->caux = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_caux); - intern->rfdBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rfdBase); - intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_crfd); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_BIG) - >> FDR_BITS1_LANG_SH_BIG; - intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_BIG); - intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_BIG); - intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_BIG); - intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_BIG) - >> FDR_BITS2_GLEVEL_SH_BIG; - } else { - intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_LITTLE) - >> FDR_BITS1_LANG_SH_LITTLE; - intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_LITTLE); - intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_LITTLE); - intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_LITTLE); - intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_LITTLE) - >> FDR_BITS2_GLEVEL_SH_LITTLE; - } - intern->reserved = 0; - - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLineOffset); - intern->cbLine = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLine); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the file descriptor record. */ - -static void -ecoff_swap_fdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const FDR *intern_copy; - PTR ext_ptr; -{ - struct fdr_ext *ext = (struct fdr_ext *) ext_ptr; - FDR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->f_adr); - bfd_h_put_32 (abfd, intern->rss, (bfd_byte *)ext->f_rss); - bfd_h_put_32 (abfd, intern->issBase, (bfd_byte *)ext->f_issBase); - ecoff_put_off (abfd, intern->cbSs, (bfd_byte *)ext->f_cbSs); - bfd_h_put_32 (abfd, intern->isymBase, (bfd_byte *)ext->f_isymBase); - bfd_h_put_32 (abfd, intern->csym, (bfd_byte *)ext->f_csym); - bfd_h_put_32 (abfd, intern->ilineBase, (bfd_byte *)ext->f_ilineBase); - bfd_h_put_32 (abfd, intern->cline, (bfd_byte *)ext->f_cline); - bfd_h_put_32 (abfd, intern->ioptBase, (bfd_byte *)ext->f_ioptBase); - bfd_h_put_32 (abfd, intern->copt, (bfd_byte *)ext->f_copt); -#ifdef ECOFF_32 - bfd_h_put_16 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst); - bfd_h_put_16 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd); -#endif -#ifdef ECOFF_64 - bfd_h_put_32 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst); - bfd_h_put_32 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd); -#endif - bfd_h_put_32 (abfd, intern->iauxBase, (bfd_byte *)ext->f_iauxBase); - bfd_h_put_32 (abfd, intern->caux, (bfd_byte *)ext->f_caux); - bfd_h_put_32 (abfd, intern->rfdBase, (bfd_byte *)ext->f_rfdBase); - bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->f_crfd); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_BIG) - & FDR_BITS1_LANG_BIG) - | (intern->fMerge ? FDR_BITS1_FMERGE_BIG : 0) - | (intern->fReadin ? FDR_BITS1_FREADIN_BIG : 0) - | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_BIG : 0)); - ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_BIG) - & FDR_BITS2_GLEVEL_BIG); - ext->f_bits2[1] = 0; - ext->f_bits2[2] = 0; - } else { - ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_LITTLE) - & FDR_BITS1_LANG_LITTLE) - | (intern->fMerge ? FDR_BITS1_FMERGE_LITTLE : 0) - | (intern->fReadin ? FDR_BITS1_FREADIN_LITTLE : 0) - | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_LITTLE : 0)); - ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_LITTLE) - & FDR_BITS2_GLEVEL_LITTLE); - ext->f_bits2[1] = 0; - ext->f_bits2[2] = 0; - } - - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->f_cbLineOffset); - ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->f_cbLine); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -#ifndef MPW_C - -/* Swap in the procedure descriptor record. */ - -static void -ecoff_swap_pdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - PDR *intern; -{ - struct pdr_ext ext[1]; - - *ext = *(struct pdr_ext *) ext_copy; - - memset ((PTR) intern, 0, sizeof (*intern)); - - intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr); - intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym); - intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline); - intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask); - intern->regoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_regoffset); - intern->iopt = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt); - intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask); - intern->fregoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_fregoffset); - intern->frameoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_frameoffset); - intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg); - intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg); - intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow); - intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh); - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef ECOFF_64 - intern->gp_prologue = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_gp_prologue); - if (bfd_header_big_endian (abfd)) - { - intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_BIG); - intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_BIG); - intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_BIG); - intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_BIG) - << PDR_BITS1_RESERVED_SH_LEFT_BIG) - | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_BIG) - >> PDR_BITS2_RESERVED_SH_BIG)); - } - else - { - intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_LITTLE); - intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_LITTLE); - intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_LITTLE); - intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_LITTLE) - >> PDR_BITS1_RESERVED_SH_LITTLE) - | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_LITTLE) - << PDR_BITS2_RESERVED_SH_LEFT_LITTLE)); - } - intern->localoff = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_localoff); -#endif - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the procedure descriptor record. */ - -static void -ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const PDR *intern_copy; - PTR ext_ptr; -{ - struct pdr_ext *ext = (struct pdr_ext *) ext_ptr; - PDR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr); - bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym); - bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline); - bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask); - bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset); - bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt); - bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask); - bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset); - bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset); - bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg); - bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg); - bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow); - bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh); - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef ECOFF_64 - bfd_h_put_8 (abfd, intern->gp_prologue, (bfd_byte *) ext->p_gp_prologue); - if (bfd_header_big_endian (abfd)) - { - ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_BIG : 0) - | (intern->reg_frame ? PDR_BITS1_REG_FRAME_BIG : 0) - | (intern->prof ? PDR_BITS1_PROF_BIG : 0) - | ((intern->reserved - >> PDR_BITS1_RESERVED_SH_LEFT_BIG) - & PDR_BITS1_RESERVED_BIG)); - ext->p_bits2[0] = ((intern->reserved << PDR_BITS2_RESERVED_SH_BIG) - & PDR_BITS2_RESERVED_BIG); - } - else - { - ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_LITTLE : 0) - | (intern->reg_frame ? PDR_BITS1_REG_FRAME_LITTLE : 0) - | (intern->prof ? PDR_BITS1_PROF_LITTLE : 0) - | ((intern->reserved << PDR_BITS1_RESERVED_SH_LITTLE) - & PDR_BITS1_RESERVED_LITTLE)); - ext->p_bits2[0] = ((intern->reserved >> - PDR_BITS2_RESERVED_SH_LEFT_LITTLE) - & PDR_BITS2_RESERVED_LITTLE); - } - bfd_h_put_8 (abfd, intern->localoff, (bfd_byte *) ext->p_localoff); -#endif - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -#else /* MPW_C */ -/* Same routines, but with ECOFF_64 code removed, so ^&%$#&! MPW C doesn't - corrupt itself and then freak out. */ -/* Swap in the procedure descriptor record. */ - -static void -ecoff_swap_pdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - PDR *intern; -{ - struct pdr_ext ext[1]; - - *ext = *(struct pdr_ext *) ext_copy; - - intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr); - intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym); - intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline); - intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask); - intern->regoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_regoffset); - intern->iopt = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt); - intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask); - intern->fregoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_fregoffset); - intern->frameoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_frameoffset); - intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg); - intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg); - intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow); - intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh); - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the procedure descriptor record. */ - -static void -ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const PDR *intern_copy; - PTR ext_ptr; -{ - struct pdr_ext *ext = (struct pdr_ext *) ext_ptr; - PDR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr); - bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym); - bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline); - bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask); - bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset); - bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt); - bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask); - bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset); - bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset); - bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg); - bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg); - bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow); - bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh); - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} -#endif /* MPW_C */ - -/* Swap in a symbol record. */ - -static void -ecoff_swap_sym_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - SYMR *intern; -{ - struct sym_ext ext[1]; - - *ext = *(struct sym_ext *) ext_copy; - - intern->iss = bfd_h_get_32 (abfd, (bfd_byte *)ext->s_iss); - intern->value = ecoff_get_off (abfd, (bfd_byte *)ext->s_value); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_BIG) - >> SYM_BITS1_ST_SH_BIG; - intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_BIG) - << SYM_BITS1_SC_SH_LEFT_BIG) - | ((ext->s_bits2[0] & SYM_BITS2_SC_BIG) - >> SYM_BITS2_SC_SH_BIG); - intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_BIG); - intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_BIG) - << SYM_BITS2_INDEX_SH_LEFT_BIG) - | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_BIG) - | (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_BIG); - } else { - intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_LITTLE) - >> SYM_BITS1_ST_SH_LITTLE; - intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_LITTLE) - >> SYM_BITS1_SC_SH_LITTLE) - | ((ext->s_bits2[0] & SYM_BITS2_SC_LITTLE) - << SYM_BITS2_SC_SH_LEFT_LITTLE); - intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_LITTLE); - intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_LITTLE) - >> SYM_BITS2_INDEX_SH_LITTLE) - | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE) - | ((unsigned int) ext->s_bits4[0] - << SYM_BITS4_INDEX_SH_LEFT_LITTLE); - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a symbol record. */ - -static void -ecoff_swap_sym_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const SYMR *intern_copy; - PTR ext_ptr; -{ - struct sym_ext *ext = (struct sym_ext *) ext_ptr; - SYMR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - bfd_h_put_32 (abfd, intern->iss, (bfd_byte *)ext->s_iss); - ecoff_put_off (abfd, intern->value, (bfd_byte *)ext->s_value); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_BIG) - & SYM_BITS1_ST_BIG) - | ((intern->sc >> SYM_BITS1_SC_SH_LEFT_BIG) - & SYM_BITS1_SC_BIG)); - ext->s_bits2[0] = (((intern->sc << SYM_BITS2_SC_SH_BIG) - & SYM_BITS2_SC_BIG) - | (intern->reserved ? SYM_BITS2_RESERVED_BIG : 0) - | ((intern->index >> SYM_BITS2_INDEX_SH_LEFT_BIG) - & SYM_BITS2_INDEX_BIG)); - ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_BIG) & 0xff; - ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_BIG) & 0xff; - } else { - ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_LITTLE) - & SYM_BITS1_ST_LITTLE) - | ((intern->sc << SYM_BITS1_SC_SH_LITTLE) - & SYM_BITS1_SC_LITTLE)); - ext->s_bits2[0] = (((intern->sc >> SYM_BITS2_SC_SH_LEFT_LITTLE) - & SYM_BITS2_SC_LITTLE) - | (intern->reserved ? SYM_BITS2_RESERVED_LITTLE : 0) - | ((intern->index << SYM_BITS2_INDEX_SH_LITTLE) - & SYM_BITS2_INDEX_LITTLE)); - ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_LITTLE) & 0xff; - ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_LITTLE) & 0xff; - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in an external symbol record. */ - -static void -ecoff_swap_ext_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - EXTR *intern; -{ - struct ext_ext ext[1]; - - *ext = *(struct ext_ext *) ext_copy; - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_BIG); - intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_BIG); - intern->weakext = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_BIG); - } else { - intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_LITTLE); - intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_LITTLE); - intern->weakext = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_LITTLE); - } - intern->reserved = 0; - -#ifdef ECOFF_32 - intern->ifd = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->es_ifd); -#endif -#ifdef ECOFF_64 - intern->ifd = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->es_ifd); -#endif - - ecoff_swap_sym_in (abfd, &ext->es_asym, &intern->asym); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out an external symbol record. */ - -static void -ecoff_swap_ext_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const EXTR *intern_copy; - PTR ext_ptr; -{ - struct ext_ext *ext = (struct ext_ext *) ext_ptr; - EXTR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_BIG : 0) - | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_BIG : 0) - | (intern->weakext ? EXT_BITS1_WEAKEXT_BIG : 0)); - ext->es_bits2[0] = 0; -#ifdef ECOFF_64 - ext->es_bits2[1] = 0; - ext->es_bits2[2] = 0; -#endif - } else { - ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_LITTLE : 0) - | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_LITTLE : 0) - | (intern->weakext ? EXT_BITS1_WEAKEXT_LITTLE : 0)); - ext->es_bits2[0] = 0; -#ifdef ECOFF_64 - ext->es_bits2[1] = 0; - ext->es_bits2[2] = 0; -#endif - } - -#ifdef ECOFF_32 - bfd_h_put_signed_16 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd); -#endif -#ifdef ECOFF_64 - bfd_h_put_signed_32 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd); -#endif - - ecoff_swap_sym_out (abfd, &intern->asym, &ext->es_asym); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in a relative file descriptor. */ - -static void -ecoff_swap_rfd_in (abfd, ext_ptr, intern) - bfd *abfd; - PTR ext_ptr; - RFDT *intern; -{ - struct rfd_ext *ext = (struct rfd_ext *) ext_ptr; - - *intern = bfd_h_get_32 (abfd, (bfd_byte *)ext->rfd); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a relative file descriptor. */ - -static void -ecoff_swap_rfd_out (abfd, intern, ext_ptr) - bfd *abfd; - const RFDT *intern; - PTR ext_ptr; -{ - struct rfd_ext *ext = (struct rfd_ext *) ext_ptr; - - bfd_h_put_32 (abfd, *intern, (bfd_byte *)ext->rfd); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in an optimization symbol. */ - -static void -ecoff_swap_opt_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - OPTR *intern; -{ - struct opt_ext ext[1]; - - *ext = *(struct opt_ext *) ext_copy; - - if (bfd_header_big_endian (abfd)) - { - intern->ot = ext->o_bits1[0]; - intern->value = (((unsigned int) ext->o_bits2[0] - << OPT_BITS2_VALUE_SH_LEFT_BIG) - | ((unsigned int) ext->o_bits3[0] - << OPT_BITS2_VALUE_SH_LEFT_BIG) - | ((unsigned int) ext->o_bits4[0] - << OPT_BITS2_VALUE_SH_LEFT_BIG)); - } - else - { - intern->ot = ext->o_bits1[0]; - intern->value = ((ext->o_bits2[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE) - | (ext->o_bits3[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE) - | (ext->o_bits4[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)); - } - - _bfd_ecoff_swap_rndx_in (bfd_header_big_endian (abfd), - &ext->o_rndx, &intern->rndx); - - intern->offset = bfd_h_get_32 (abfd, (bfd_byte *) ext->o_offset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out an optimization symbol. */ - -static void -ecoff_swap_opt_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const OPTR *intern_copy; - PTR ext_ptr; -{ - struct opt_ext *ext = (struct opt_ext *) ext_ptr; - OPTR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - if (bfd_header_big_endian (abfd)) - { - ext->o_bits1[0] = intern->ot; - ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_BIG; - ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_BIG; - ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_BIG; - } - else - { - ext->o_bits1[0] = intern->ot; - ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_LITTLE; - ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_LITTLE; - ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_LITTLE; - } - - _bfd_ecoff_swap_rndx_out (bfd_header_big_endian (abfd), - &intern->rndx, &ext->o_rndx); - - bfd_h_put_32 (abfd, intern->value, (bfd_byte *) ext->o_offset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in a dense number. */ - -static void -ecoff_swap_dnr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - DNR *intern; -{ - struct dnr_ext ext[1]; - - *ext = *(struct dnr_ext *) ext_copy; - - intern->rfd = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_rfd); - intern->index = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_index); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a dense number. */ - -static void -ecoff_swap_dnr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const DNR *intern_copy; - PTR ext_ptr; -{ - struct dnr_ext *ext = (struct dnr_ext *) ext_ptr; - DNR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - bfd_h_put_32 (abfd, intern->rfd, (bfd_byte *) ext->d_rfd); - bfd_h_put_32 (abfd, intern->index, (bfd_byte *) ext->d_index); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} diff --git a/contrib/gdb/bfd/elf-bfd.h b/contrib/gdb/bfd/elf-bfd.h deleted file mode 100644 index ee38e5b12f4..00000000000 --- a/contrib/gdb/bfd/elf-bfd.h +++ /dev/null @@ -1,858 +0,0 @@ -/* BFD back-end data structures for ELF files. - Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _LIBELF_H_ -#define _LIBELF_H_ 1 - -#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 -#if ARCH_SIZE==64 -#define NAME(x,y) CAT4(x,64,_,y) -#endif -#if ARCH_SIZE==32 -#define NAME(x,y) CAT4(x,32,_,y) -#endif -#endif - -#ifndef NAME -#define NAME(x,y) CAT4(x,NOSIZE,_,y) -#endif - -#define ElfNAME(X) NAME(Elf,X) -#define elfNAME(X) NAME(elf,X) - -/* 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 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; - - /* If this symbol requires an entry in the global offset table, the - processor specific backend uses this field to hold the offset - into the .got section. If this field is -1, then the symbol does - not require a global offset table entry. */ - bfd_vma got_offset; - - /* If this symbol requires an entry in the procedure linkage table, - the processor specific backend uses these two fields to hold the - offset into the procedure linkage section and the offset into the - .got section. If plt_offset is -1, then the symbol does not - require an entry in the procedure linkage table. */ - bfd_vma plt_offset; - - /* If this symbol is used in the linker created sections, the processor - specific backend uses this field to map the field into the offset - from the beginning of the section. */ - struct elf_linker_section_pointers *linker_section_pointer; - - /* 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 - /* Dynamic symbol has been adjustd. */ -#define ELF_LINK_HASH_DYNAMIC_ADJUSTED 020 - /* Symbol needs a copy reloc. */ -#define ELF_LINK_HASH_NEEDS_COPY 040 - /* Symbol needs a procedure linkage table entry. */ -#define ELF_LINK_HASH_NEEDS_PLT 0100 - /* Symbol appears in a non-ELF input file. */ -#define ELF_LINK_NON_ELF 0200 - /* Note: If you add more flags, you must change the type of - elf_link_hash_flags. */ -}; - -/* ELF linker hash table. */ - -struct elf_link_hash_table -{ - struct bfd_link_hash_table root; - /* Whether we have created the special dynamic sections required - when linking against or generating a shared object. */ - boolean dynamic_sections_created; - /* The BFD used to hold special sections created by the linker. - This will be the first BFD found which requires these sections to - be created. */ - bfd *dynobj; - /* The number of symbols found in the link which must be put into - the .dynsym section. */ - bfd_size_type dynsymcount; - /* The string table of dynamic symbols, which becomes the .dynstr - section. */ - struct bfd_strtab_hash *dynstr; - /* The number of buckets in the hash table in the .hash section. - This is based on the number of dynamic symbols. */ - bfd_size_type bucketcount; - /* A linked list of DT_NEEDED names found in dynamic objects - included in the link. */ - struct bfd_link_needed_list *needed; -}; - -/* 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_size_info { - unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr; - unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note; - - unsigned char arch_size, file_align; - unsigned char elfclass, ev_current; - int (*write_out_phdrs) PARAMS ((bfd *, Elf_Internal_Phdr *, int)); - boolean (*write_shdrs_and_ehdr) PARAMS ((bfd *)); - void (*write_relocs) PARAMS ((bfd *, asection *, PTR)); - void (*swap_symbol_out) PARAMS ((bfd *, Elf_Internal_Sym *, PTR)); - boolean (*slurp_reloc_table) PARAMS ((bfd *, asection *, asymbol **)); - long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean)); - void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); -}; - -#define elf_symbol_from(ABFD,S) \ - (((S)->the_bfd->xvec->flavour == bfd_target_elf_flavour \ - && (S)->the_bfd->tdata.elf_obj_data != 0) \ - ? (elf_symbol_type *) (S) \ - : 0) - -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; - - /* 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; - - /* This is true if the linker should ignore changes to the type of a - symbol. This is true for MIPS ELF because some Irix 5 objects - record undefined functions as STT_OBJECT although the definitions - are STT_FUNC. */ - boolean type_change_ok; - - /* 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 *)); - - /* 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 *)); - - /* 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 *, - unsigned 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 CHECK_RELOCS function is called by the add_symbols phase of - the ELF backend linker. It is called once for each section with - relocs of an object file, just after the symbols for the object - file have been added to the global linker hash table. The - function must look through the relocs and do any special handling - required. This generally means allocating space in the global - offset table, and perhaps allocating space for a reloc. The - relocs are always passed as Rela structures; if the section - actually uses Rel structures, the r_addend field will always be - zero. */ - boolean (*check_relocs) - PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *o, - const Elf_Internal_Rela *relocs)); - - /* 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 ore bfd_link_hash_defweak, 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)); - - /* 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. The LINKER argument is true if this BFD - was created by the ELF backend linker. */ - void (*elf_backend_final_write_processing) - PARAMS ((bfd *, boolean linker)); - - /* This function is called by get_program_header_size. It should - return the number of additional program segments which this BFD - will need. It should return -1 on error. */ - int (*elf_backend_additional_program_headers) PARAMS ((bfd *)); - - /* This function is called to modify an existing segment map in a - backend specific fashion. */ - boolean (*elf_backend_modify_segment_map) PARAMS ((bfd *)); - - /* 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; - - /* Alternate EM_xxxx machine codes for this backend. */ - int elf_machine_alt1; - int elf_machine_alt2; - - const struct elf_size_info *s; - - unsigned want_got_plt : 1; - unsigned plt_readonly : 1; - unsigned want_plt_sym : 1; -}; - -/* 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; - /* 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 swapped relocs. If the section uses REL relocs, - rather than RELA, all the r_addend fields will be zero. This - pointer may be NULL. It is used by the backend linker. */ - Elf_Internal_Rela *relocs; - /* Used by the backend linker when generating a shared library to - record the dynamic symbol index for a section symbol - corresponding to this section. */ - long dynindx; - /* A pointer available for the processor specific ELF backend. */ - PTR tdata; -}; - -#define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd) - -#define get_elf_backend_data(abfd) \ - ((struct elf_backend_data *) (abfd)->xvec->backend_data) - -/* Enumeration to specify the special section. */ -typedef enum elf_linker_section_enum -{ - LINKER_SECTION_UNKNOWN, /* not used */ - LINKER_SECTION_GOT, /* .got section for global offset pointers */ - LINKER_SECTION_PLT, /* .plt section for generated procedure stubs */ - LINKER_SECTION_SDATA, /* .sdata/.sbss section for PowerPC */ - LINKER_SECTION_SDATA2, /* .sdata2/.sbss2 section for PowerPC */ - LINKER_SECTION_MAX /* # of linker sections */ -} elf_linker_section_enum_t; - -/* Sections created by the linker. */ - -typedef struct elf_linker_section -{ - char *name; /* name of the section */ - char *rel_name; /* name of the associated .rel{,a}. section */ - char *bss_name; /* name of a related .bss section */ - char *sym_name; /* name of symbol to reference this section */ - asection *section; /* pointer to the section */ - asection *bss_section; /* pointer to the bss section associated with this */ - asection *rel_section; /* pointer to the relocations needed for this section */ - struct elf_link_hash_entry *sym_hash; /* pointer to the created symbol hash value */ - bfd_vma initial_size; /* initial size before any linker generated allocations */ - bfd_vma sym_offset; /* offset of symbol from beginning of section */ - bfd_vma hole_size; /* size of reserved address hole in allocation */ - bfd_vma hole_offset; /* current offset for the hole */ - bfd_vma max_hole_offset; /* maximum offset for the hole */ - elf_linker_section_enum_t which; /* which section this is */ - boolean hole_written_p; /* whether the hole has been initialized */ - int alignment; /* alignment for the section */ - flagword flags; /* flags to use to create the section */ -} elf_linker_section_t; - -/* Linked list of allocated pointer entries. This hangs off of the symbol lists, and - provides allows us to return different pointers, based on different addend's. */ - -typedef struct elf_linker_section_pointers -{ - struct elf_linker_section_pointers *next; /* next allocated pointer for this symbol */ - bfd_vma offset; /* offset of pointer from beginning of section */ - bfd_signed_vma addend; /* addend used */ - elf_linker_section_enum_t which; /* which linker section this is */ - boolean written_address_p; /* whether address was written yet */ -} elf_linker_section_pointers_t; - -/* Some private data is stashed away for future use using the tdata pointer - in the bfd structure. */ - -struct elf_obj_tdata -{ - Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */ - Elf_Internal_Shdr **elf_sect_ptr; - Elf_Internal_Phdr *phdr; - struct elf_segment_map *segment_map; - struct bfd_strtab_hash *strtab_ptr; - int num_locals; - int num_globals; - asymbol **section_syms; /* STT_SECTION symbols for each section */ - Elf_Internal_Shdr symtab_hdr; - Elf_Internal_Shdr shstrtab_hdr; - Elf_Internal_Shdr strtab_hdr; - Elf_Internal_Shdr dynsymtab_hdr; - Elf_Internal_Shdr dynstrtab_hdr; - unsigned int symtab_section, shstrtab_section; - unsigned int 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) */ - unsigned int gp_size; /* The gp size (MIPS only, for now) */ - - /* This is set to true if the object was created by the backend - linker. */ - boolean linker; - - /* 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; - - /* A mapping from local symbols to offsets into the global offset - table, used when linking. This is indexed by the symbol index. */ - bfd_vma *local_got_offsets; - - /* A mapping from local symbols to offsets into the various linker - sections added. This is index by the symbol index. */ - elf_linker_section_pointers_t **linker_section_pointers; - - /* 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. The emulation code then - sometimes needs to know what name was actually used. Until the - file has been added to the linker symbol table, this field holds - the name the linker wants. After it has been added, it holds the - name actually used, which will be the DT_SONAME entry if there is - one. */ - const char *dt_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; - - /* Records the result of `get_program_header_size'. */ - bfd_size_type program_header_size; - - /* Used by find_nearest_line entry point. */ - PTR line_info; - - /* Used by MIPS ELF find_nearest_line entry point. The structure - could be included directly in this one, but there's no point to - wasting the memory just for the infrequently called - find_nearest_line. */ - struct mips_elf_find_line *find_line_info; - - /* Used to determine if the e_flags field has been initialized */ - boolean flags_init; - - /* Linker sections that we are interested in. */ - struct elf_linker_section *linker_section[ (int)LINKER_SECTION_MAX ]; -}; - -#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data) -#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header) -#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr) -#define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr) -#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) -#define elf_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_section_syms(bfd) (elf_tdata(bfd) -> section_syms) -#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo) -#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus) -#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_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got_offsets) -#define elf_local_ptr_offsets(bfd) (elf_tdata(bfd) -> linker_section_pointers) -#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name) -#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab) -#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init) -#define elf_linker_section(bfd,n) (elf_tdata(bfd) -> linker_section[(int)n]) - -extern int _bfd_elf_section_from_bfd_section PARAMS ((bfd *, asection *)); -extern char *bfd_elf_string_from_elf_section - PARAMS ((bfd *, unsigned, unsigned)); -extern char *bfd_elf_get_str_section PARAMS ((bfd *, unsigned)); - -extern boolean _bfd_elf_print_private_bfd_data PARAMS ((bfd *, PTR)); -extern void bfd_elf_print_symbol PARAMS ((bfd *, PTR, asymbol *, - bfd_print_symbol_type)); -#define elf_string_from_elf_strtab(abfd,strindex) \ - bfd_elf_string_from_elf_section(abfd,elf_elfheader(abfd)->e_shstrndx,strindex) - -#define bfd_elf32_print_symbol bfd_elf_print_symbol -#define bfd_elf64_print_symbol bfd_elf_print_symbol -#define bfd_elf32_mkobject bfd_elf_mkobject -#define bfd_elf64_mkobject bfd_elf_mkobject -#define elf_mkobject bfd_elf_mkobject - -extern unsigned long bfd_elf_hash PARAMS ((CONST unsigned char *)); - -extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *, - arelent *, - asymbol *, - PTR, - asection *, - bfd *, - 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_elf_copy_private_symbol_data - PARAMS ((bfd *, asymbol *, bfd *, asymbol *)); -extern boolean _bfd_elf_copy_private_section_data - PARAMS ((bfd *, asection *, bfd *, asection *)); -extern boolean _bfd_elf_write_object_contents PARAMS ((bfd *)); -extern boolean _bfd_elf_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, - bfd_size_type)); -extern long _bfd_elf_get_symtab_upper_bound PARAMS ((bfd *)); -extern long _bfd_elf_get_symtab PARAMS ((bfd *, asymbol **)); -extern long _bfd_elf_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); -extern long _bfd_elf_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); -extern long _bfd_elf_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -extern long _bfd_elf_canonicalize_reloc PARAMS ((bfd *, sec_ptr, - arelent **, asymbol **)); -extern asymbol *_bfd_elf_make_empty_symbol PARAMS ((bfd *)); -extern void _bfd_elf_get_symbol_info PARAMS ((bfd *, asymbol *, - symbol_info *)); -extern alent *_bfd_elf_get_lineno PARAMS ((bfd *, asymbol *)); -extern boolean _bfd_elf_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); -extern boolean _bfd_elf_find_nearest_line PARAMS ((bfd *, asection *, - asymbol **, - bfd_vma, CONST char **, - CONST char **, - unsigned int *)); -#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols -#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -extern int _bfd_elf_sizeof_headers PARAMS ((bfd *, boolean)); -extern boolean _bfd_elf_new_section_hook PARAMS ((bfd *, asection *)); - -/* If the target doesn't have reloc handling written yet: */ -extern void _bfd_elf_no_info_to_howto PARAMS ((bfd *, arelent *, - Elf_Internal_Rela *)); - -asection *bfd_section_from_elf_index PARAMS ((bfd *, unsigned int)); -boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *, - struct bfd_link_info *)); -struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void)); -boolean -_bfd_elf_link_record_dynamic_symbol PARAMS ((struct bfd_link_info *, - struct elf_link_hash_entry *)); -boolean -_bfd_elf_compute_section_file_positions PARAMS ((bfd *, - struct bfd_link_info *)); -void _bfd_elf_assign_file_positions_for_relocs PARAMS ((bfd *)); -file_ptr _bfd_elf_assign_file_position_for_section PARAMS ((Elf_Internal_Shdr *, - file_ptr, - boolean)); - -boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *, - struct bfd_link_info *)); -boolean _bfd_elf_create_got_section PARAMS ((bfd *, - struct bfd_link_info *)); - -elf_linker_section_t *_bfd_elf_create_linker_section - PARAMS ((bfd *abfd, - struct bfd_link_info *info, - enum elf_linker_section_enum, - elf_linker_section_t *defaults)); - -elf_linker_section_pointers_t *_bfd_elf_find_pointer_linker_section - PARAMS ((elf_linker_section_pointers_t *linker_pointers, - bfd_signed_vma addend, - elf_linker_section_enum_t which)); - -boolean bfd_elf32_create_pointer_linker_section - PARAMS ((bfd *abfd, - struct bfd_link_info *info, - elf_linker_section_t *lsect, - struct elf_link_hash_entry *h, - const Elf32_Internal_Rela *rel)); - -bfd_vma bfd_elf32_finish_pointer_linker_section - PARAMS ((bfd *output_abfd, - bfd *input_bfd, - struct bfd_link_info *info, - elf_linker_section_t *lsect, - struct elf_link_hash_entry *h, - bfd_vma relocation, - const Elf32_Internal_Rela *rel, - int relative_reloc)); - -boolean bfd_elf64_create_pointer_linker_section - PARAMS ((bfd *abfd, - struct bfd_link_info *info, - elf_linker_section_t *lsect, - struct elf_link_hash_entry *h, - const Elf64_Internal_Rela *rel)); - -bfd_vma bfd_elf64_finish_pointer_linker_section - PARAMS ((bfd *output_abfd, - bfd *input_bfd, - struct bfd_link_info *info, - elf_linker_section_t *lsect, - struct elf_link_hash_entry *h, - bfd_vma relocation, - const Elf64_Internal_Rela *rel, - int relative_reloc)); - -boolean _bfd_elf_make_linker_section_rela - PARAMS ((bfd *dynobj, - elf_linker_section_t *lsect, - int alignment)); - -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 *, - bfd *)); - -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 *, PTR)); -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_phdr_in - PARAMS ((bfd *, Elf32_External_Phdr *, Elf_Internal_Phdr *)); -extern void bfd_elf32_swap_phdr_out - PARAMS ((bfd *, Elf_Internal_Phdr *, Elf32_External_Phdr *)); -extern void bfd_elf32_swap_dyn_in - PARAMS ((bfd *, const PTR, 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)); -extern boolean bfd_elf32_link_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -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 *, - bfd *)); -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 *, PTR)); -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_phdr_in - PARAMS ((bfd *, Elf64_External_Phdr *, Elf_Internal_Phdr *)); -extern void bfd_elf64_swap_phdr_out - PARAMS ((bfd *, Elf_Internal_Phdr *, Elf64_External_Phdr *)); -extern void bfd_elf64_swap_dyn_in - PARAMS ((bfd *, const PTR, 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)); -extern boolean bfd_elf64_link_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -#define bfd_elf32_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol -#define bfd_elf64_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol - -#endif /* _LIBELF_H_ */ diff --git a/contrib/gdb/bfd/elf.c b/contrib/gdb/bfd/elf.c deleted file mode 100644 index 981d3ee2309..00000000000 --- a/contrib/gdb/bfd/elf.c +++ /dev/null @@ -1,3318 +0,0 @@ -/* ELF executable support for BFD. - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - -SECTION - ELF backends - - BFD support for ELF formats is being worked on. - Currently, the best supported back ends are for sparc and i386 - (running svr4 or Solaris 2). - - Documentation of the internals of the support code still needs - to be written. The code is changing quickly enough that we - haven't bothered yet. - */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#define ARCH_SIZE 0 -#include "elf-bfd.h" - -static INLINE struct elf_segment_map *make_mapping - PARAMS ((bfd *, asection **, unsigned int, unsigned int, boolean)); -static int elf_sort_sections PARAMS ((const PTR, const PTR)); -static boolean assign_file_positions_for_segments PARAMS ((bfd *)); -static boolean assign_file_positions_except_relocs PARAMS ((bfd *)); -static boolean prep_headers PARAMS ((bfd *)); -static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **)); -static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *)); - -/* Standard ELF hash function. Do not change this function; you will - cause invalid hash tables to be generated. (Well, you would if this - were being used yet.) */ -unsigned long -bfd_elf_hash (name) - CONST unsigned char *name; -{ - unsigned long h = 0; - unsigned long g; - int ch; - - while ((ch = *name++) != '\0') - { - h = (h << 4) + ch; - if ((g = (h & 0xf0000000)) != 0) - { - h ^= g >> 24; - h &= ~g; - } - } - return h; -} - -/* Read a specified number of bytes at a specified offset in an ELF - file, into a newly allocated buffer, and return a pointer to the - buffer. */ - -static char * -elf_read (abfd, offset, size) - bfd * abfd; - long offset; - unsigned int size; -{ - char *buf; - - if ((buf = bfd_alloc (abfd, size)) == NULL) - return NULL; - if (bfd_seek (abfd, offset, SEEK_SET) == -1) - return NULL; - if (bfd_read ((PTR) buf, size, 1, abfd) != size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_file_truncated); - return NULL; - } - return buf; -} - -boolean -elf_mkobject (abfd) - bfd * abfd; -{ - /* this just does initialization */ - /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */ - elf_tdata (abfd) = (struct elf_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); - if (elf_tdata (abfd) == 0) - return false; - /* since everything is done at close time, do we need any - initialization? */ - - return true; -} - -char * -bfd_elf_get_str_section (abfd, shindex) - bfd * abfd; - unsigned int shindex; -{ - Elf_Internal_Shdr **i_shdrp; - char *shstrtab = NULL; - unsigned int offset; - unsigned int shstrtabsize; - - i_shdrp = elf_elfsections (abfd); - if (i_shdrp == 0 || i_shdrp[shindex] == 0) - return 0; - - shstrtab = (char *) i_shdrp[shindex]->contents; - if (shstrtab == NULL) - { - /* No cached one, attempt to read, and cache what we read. */ - offset = i_shdrp[shindex]->sh_offset; - shstrtabsize = i_shdrp[shindex]->sh_size; - shstrtab = elf_read (abfd, offset, shstrtabsize); - i_shdrp[shindex]->contents = (PTR) shstrtab; - } - return shstrtab; -} - -char * -bfd_elf_string_from_elf_section (abfd, shindex, strindex) - bfd * abfd; - unsigned int shindex; - unsigned int strindex; -{ - Elf_Internal_Shdr *hdr; - - if (strindex == 0) - return ""; - - hdr = elf_elfsections (abfd)[shindex]; - - if (hdr->contents == NULL - && bfd_elf_get_str_section (abfd, shindex) == NULL) - return NULL; - - return ((char *) hdr->contents) + strindex; -} - -/* Make a BFD section from an ELF section. We store a pointer to the - BFD section in the bfd_section 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->bfd_section != NULL) - { - BFD_ASSERT (strcmp (name, - bfd_get_section_name (abfd, hdr->bfd_section)) == 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; - - if ((flags & SEC_ALLOC) != 0) - { - Elf_Internal_Phdr *phdr; - unsigned int i; - - /* Look through the phdrs to see if we need to adjust the lma. */ - phdr = elf_tdata (abfd)->phdr; - for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) - { - if (phdr->p_type == PT_LOAD - && phdr->p_paddr != 0 - && phdr->p_vaddr != phdr->p_paddr - && phdr->p_vaddr <= hdr->sh_addr - && phdr->p_vaddr + phdr->p_memsz >= hdr->sh_addr + hdr->sh_size) - { - newsect->lma += phdr->p_paddr - phdr->p_vaddr; - break; - } - } - } - - hdr->bfd_section = newsect; - elf_section_data (newsect)->this_hdr = *hdr; - - return true; -} - -/* -INTERNAL_FUNCTION - bfd_elf_find_section - -SYNOPSIS - struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name); - -DESCRIPTION - Helper functions for GDB to locate the string tables. - Since BFD hides string tables from callers, GDB needs to use an - internal hook to find them. Sun's .stabstr, in particular, - isn't even pointed to by the .stab section, so ordinary - mechanisms wouldn't work to find it, even if we had some. -*/ - -struct elf_internal_shdr * -bfd_elf_find_section (abfd, name) - bfd * abfd; - char *name; -{ - Elf_Internal_Shdr **i_shdrp; - char *shstrtab; - unsigned int max; - unsigned int i; - - i_shdrp = elf_elfsections (abfd); - if (i_shdrp != NULL) - { - shstrtab = bfd_elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx); - if (shstrtab != NULL) - { - max = elf_elfheader (abfd)->e_shnum; - for (i = 1; i < max; i++) - if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name)) - return i_shdrp[i]; - } - } - return 0; -} - -const char *const bfd_elf_section_type_names[] = { - "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB", - "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE", - "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM", -}; - -/* ELF relocs are against symbols. If we are producing relocateable - output, and the reloc is against an external symbol, and nothing - has given us any additional addend, the resulting reloc will also - be against the same symbol. In such a case, we don't want to - change anything about the way the reloc is handled, since it will - all be done at final link time. Rather than put special case code - into bfd_perform_relocation, all the reloc types use this howto - function. It just short circuits the reloc if producing - relocateable output against an external symbol. */ - -/*ARGSUSED*/ -bfd_reloc_status_type -bfd_elf_generic_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -/* Print out the program headers. */ - -boolean -_bfd_elf_print_private_bfd_data (abfd, farg) - bfd *abfd; - PTR farg; -{ - FILE *f = (FILE *) farg; - Elf_Internal_Phdr *p; - asection *s; - bfd_byte *dynbuf = NULL; - - p = elf_tdata (abfd)->phdr; - if (p != NULL) - { - unsigned int i, c; - - fprintf (f, "\nProgram Header:\n"); - c = elf_elfheader (abfd)->e_phnum; - for (i = 0; i < c; i++, p++) - { - const char *s; - char buf[20]; - - switch (p->p_type) - { - case PT_NULL: s = "NULL"; break; - case PT_LOAD: s = "LOAD"; break; - case PT_DYNAMIC: s = "DYNAMIC"; break; - case PT_INTERP: s = "INTERP"; break; - case PT_NOTE: s = "NOTE"; break; - case PT_SHLIB: s = "SHLIB"; break; - case PT_PHDR: s = "PHDR"; break; - default: sprintf (buf, "0x%lx", p->p_type); s = buf; break; - } - fprintf (f, "%8s off 0x", s); - fprintf_vma (f, p->p_offset); - fprintf (f, " vaddr 0x"); - fprintf_vma (f, p->p_vaddr); - fprintf (f, " paddr 0x"); - fprintf_vma (f, p->p_paddr); - fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align)); - fprintf (f, " filesz 0x"); - fprintf_vma (f, p->p_filesz); - fprintf (f, " memsz 0x"); - fprintf_vma (f, p->p_memsz); - fprintf (f, " flags %c%c%c", - (p->p_flags & PF_R) != 0 ? 'r' : '-', - (p->p_flags & PF_W) != 0 ? 'w' : '-', - (p->p_flags & PF_X) != 0 ? 'x' : '-'); - if ((p->p_flags &~ (PF_R | PF_W | PF_X)) != 0) - fprintf (f, " %lx", p->p_flags &~ (PF_R | PF_W | PF_X)); - fprintf (f, "\n"); - } - } - - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - int elfsec; - unsigned long link; - bfd_byte *extdyn, *extdynend; - size_t extdynsize; - void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); - - fprintf (f, "\nDynamic Section:\n"); - - dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size); - if (dynbuf == NULL) - goto error_return; - if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0, - s->_raw_size)) - goto error_return; - - elfsec = _bfd_elf_section_from_bfd_section (abfd, s); - if (elfsec == -1) - goto error_return; - link = elf_elfsections (abfd)[elfsec]->sh_link; - - extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; - swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; - - extdyn = dynbuf; - extdynend = extdyn + s->_raw_size; - for (; extdyn < extdynend; extdyn += extdynsize) - { - Elf_Internal_Dyn dyn; - const char *name; - char ab[20]; - boolean stringp; - - (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn); - - if (dyn.d_tag == DT_NULL) - break; - - stringp = false; - switch (dyn.d_tag) - { - default: - sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag); - name = ab; - break; - - case DT_NEEDED: name = "NEEDED"; stringp = true; break; - case DT_PLTRELSZ: name = "PLTRELSZ"; break; - case DT_PLTGOT: name = "PLTGOT"; break; - case DT_HASH: name = "HASH"; break; - case DT_STRTAB: name = "STRTAB"; break; - case DT_SYMTAB: name = "SYMTAB"; break; - case DT_RELA: name = "RELA"; break; - case DT_RELASZ: name = "RELASZ"; break; - case DT_RELAENT: name = "RELAENT"; break; - case DT_STRSZ: name = "STRSZ"; break; - case DT_SYMENT: name = "SYMENT"; break; - case DT_INIT: name = "INIT"; break; - case DT_FINI: name = "FINI"; break; - case DT_SONAME: name = "SONAME"; stringp = true; break; - case DT_RPATH: name = "RPATH"; stringp = true; break; - case DT_SYMBOLIC: name = "SYMBOLIC"; break; - case DT_REL: name = "REL"; break; - case DT_RELSZ: name = "RELSZ"; break; - case DT_RELENT: name = "RELENT"; break; - case DT_PLTREL: name = "PLTREL"; break; - case DT_DEBUG: name = "DEBUG"; break; - case DT_TEXTREL: name = "TEXTREL"; break; - case DT_JMPREL: name = "JMPREL"; break; - } - - fprintf (f, " %-11s ", name); - if (! stringp) - fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val); - else - { - const char *string; - - string = bfd_elf_string_from_elf_section (abfd, link, - dyn.d_un.d_val); - if (string == NULL) - goto error_return; - fprintf (f, "%s", string); - } - fprintf (f, "\n"); - } - - free (dynbuf); - dynbuf = NULL; - } - - return true; - - error_return: - if (dynbuf != NULL) - free (dynbuf); - return false; -} - -/* Display ELF-specific fields of a symbol. */ -void -bfd_elf_print_symbol (ignore_abfd, filep, symbol, how) - bfd *ignore_abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) filep; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - fprintf (file, "elf "); - fprintf_vma (file, symbol->value); - fprintf (file, " %lx", (long) symbol->flags); - break; - case bfd_print_symbol_all: - { - CONST char *section_name; - section_name = symbol->section ? symbol->section->name : "(*none*)"; - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %s\t", section_name); - /* Print the "other" value for a symbol. For common symbols, - we've already printed the size; now print the alignment. - For other symbols, we have no specified alignment, and - we've printed the address; now print the size. */ - fprintf_vma (file, - (bfd_is_com_section (symbol->section) - ? ((elf_symbol_type *) symbol)->internal_elf_sym.st_value - : ((elf_symbol_type *) symbol)->internal_elf_sym.st_size)); - fprintf (file, " %s", symbol->name); - } - break; - } -} - -/* 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) - 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->dynindx = -1; - ret->dynstr_index = 0; - ret->weakdef = NULL; - ret->got_offset = (bfd_vma) -1; - ret->plt_offset = (bfd_vma) -1; - ret->linker_section_pointer = (elf_linker_section_pointers_t *)0; - ret->type = STT_NOTYPE; - /* Assume that we have been called by a non-ELF symbol reader. - This flag is then reset by the code which reads an ELF input - file. This ensures that a symbol created by a non-ELF symbol - reader will have the flag set correctly. */ - ret->elf_link_hash_flags = ELF_LINK_NON_ELF; - } - - 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->dynamic_sections_created = false; - table->dynobj = NULL; - /* The first dynamic symbol is a dummy. */ - table->dynsymcount = 1; - table->dynstr = NULL; - table->bucketcount = 0; - table->needed = NULL; - 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) - 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. The generic linker passes name as an - empty string to indicate that no DT_NEEDED entry should be made. */ - -void -bfd_elf_set_dt_needed_name (abfd, name) - bfd *abfd; - const char *name; -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && bfd_get_format (abfd) == bfd_object) - elf_dt_name (abfd) = name; -} - -/* Get the list of DT_NEEDED entries for a link. This is a hook for - the ELF emulation code. */ - -struct bfd_link_needed_list * -bfd_elf_get_needed_list (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (info->hash->creator->flavour != bfd_target_elf_flavour) - return NULL; - return elf_hash_table (info)->needed; -} - -/* Get the name actually used for a dynamic object for a link. This - is the SONAME entry if there is one. Otherwise, it is the string - passed to bfd_elf_set_dt_needed_name, or it is the filename. */ - -const char * -bfd_elf_get_dt_soname (abfd) - bfd *abfd; -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && bfd_get_format (abfd) == bfd_object) - return elf_dt_name (abfd); - return NULL; -} - -/* Allocate an ELF string table--force the first byte to be zero. */ - -struct bfd_strtab_hash * -_bfd_elf_stringtab_init () -{ - struct bfd_strtab_hash *ret; - - ret = _bfd_stringtab_init (); - if (ret != NULL) - { - bfd_size_type loc; - - loc = _bfd_stringtab_add (ret, "", true, false); - BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1); - if (loc == (bfd_size_type) -1) - { - _bfd_stringtab_free (ret); - ret = NULL; - } - } - return ret; -} - -/* ELF .o/exec file reading */ - -/* Create a new bfd section from an ELF section header. */ - -boolean -bfd_section_from_shdr (abfd, shindex) - bfd *abfd; - unsigned int shindex; -{ - Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex]; - Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd); - struct elf_backend_data *bed = get_elf_backend_data (abfd); - char *name; - - name = elf_string_from_elf_strtab (abfd, hdr->sh_name); - - switch (hdr->sh_type) - { - case SHT_NULL: - /* Inactive section. Throw it away. */ - return true; - - case SHT_PROGBITS: /* Normal section with contents. */ - case SHT_DYNAMIC: /* Dynamic linking information. */ - case SHT_NOBITS: /* .bss section. */ - case SHT_HASH: /* .hash section. */ - case SHT_NOTE: /* .note section. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - case SHT_SYMTAB: /* A symbol table */ - if (elf_onesymtab (abfd) == shindex) - return true; - - BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym); - BFD_ASSERT (elf_onesymtab (abfd) == 0); - elf_onesymtab (abfd) = shindex; - elf_tdata (abfd)->symtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr; - abfd->flags |= HAS_SYMS; - - /* Sometimes a shared object will map in the symbol table. If - SHF_ALLOC is set, and this is a shared object, then we also - treat this section as a BFD section. We can not base the - decision purely on SHF_ALLOC, because that flag is sometimes - set in a relocateable object file, which would confuse the - linker. */ - if ((hdr->sh_flags & SHF_ALLOC) != 0 - && (abfd->flags & DYNAMIC) != 0 - && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; - - return true; - - case SHT_DYNSYM: /* A dynamic symbol table */ - if (elf_dynsymtab (abfd) == shindex) - return true; - - BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym); - BFD_ASSERT (elf_dynsymtab (abfd) == 0); - elf_dynsymtab (abfd) = shindex; - elf_tdata (abfd)->dynsymtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr; - abfd->flags |= HAS_SYMS; - - /* Besides being a symbol table, we also treat this as a regular - section, so that objcopy can handle it. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - case SHT_STRTAB: /* A string table */ - if (hdr->bfd_section != NULL) - return true; - if (ehdr->e_shstrndx == shindex) - { - elf_tdata (abfd)->shstrtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr; - return true; - } - { - unsigned int i; - - for (i = 1; i < ehdr->e_shnum; i++) - { - Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; - if (hdr2->sh_link == shindex) - { - if (! bfd_section_from_shdr (abfd, i)) - return false; - if (elf_onesymtab (abfd) == i) - { - elf_tdata (abfd)->strtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = - &elf_tdata (abfd)->strtab_hdr; - return true; - } - if (elf_dynsymtab (abfd) == i) - { - elf_tdata (abfd)->dynstrtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = hdr = - &elf_tdata (abfd)->dynstrtab_hdr; - /* We also treat this as a regular section, so - that objcopy can handle it. */ - break; - } -#if 0 /* Not handling other string tables specially right now. */ - hdr2 = elf_elfsections (abfd)[i]; /* in case it moved */ - /* We have a strtab for some random other section. */ - newsect = (asection *) hdr2->bfd_section; - if (!newsect) - break; - hdr->bfd_section = newsect; - hdr2 = &elf_section_data (newsect)->str_hdr; - *hdr2 = *hdr; - elf_elfsections (abfd)[shindex] = hdr2; -#endif - } - } - } - - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - case SHT_REL: - case SHT_RELA: - /* *These* do a lot of work -- but build no sections! */ - { - asection *target_sect; - Elf_Internal_Shdr *hdr2; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - - /* For some incomprehensible reason Oracle distributes - libraries for Solaris in which some of the objects have - bogus sh_link fields. It would be nice if we could just - reject them, but, unfortunately, some people need to use - them. We scan through the section headers; if we find only - one suitable symbol table, we clobber the sh_link to point - to it. I hope this doesn't break anything. */ - if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB - && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM) - { - int scan; - int found; - - found = 0; - for (scan = 1; scan < ehdr->e_shnum; scan++) - { - if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB - || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM) - { - if (found != 0) - { - found = 0; - break; - } - found = scan; - } - } - if (found != 0) - hdr->sh_link = found; - } - - /* Get the symbol table. */ - if (elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB - && ! bfd_section_from_shdr (abfd, hdr->sh_link)) - return false; - - /* If this reloc section does not use the main symbol table we - don't treat it as a reloc section. BFD can't adequately - represent such a section, so at least for now, we don't - try. We just present it as a normal section. */ - if (hdr->sh_link != elf_onesymtab (abfd)) - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - /* Don't allow REL relocations on a machine that uses RELA and - vice versa. */ - /* @@ Actually, the generic ABI does suggest that both might be - used in one file. But the four ABI Processor Supplements I - have access to right now all specify that only one is used on - each of those architectures. It's conceivable that, e.g., a - bunch of absolute 32-bit relocs might be more compact in REL - form even on a RELA machine... */ - BFD_ASSERT (use_rela_p - ? (hdr->sh_type == SHT_RELA - && hdr->sh_entsize == bed->s->sizeof_rela) - : (hdr->sh_type == SHT_REL - && hdr->sh_entsize == bed->s->sizeof_rel)); - - if (! bfd_section_from_shdr (abfd, hdr->sh_info)) - return false; - target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info); - if (target_sect == NULL) - return false; - - hdr2 = &elf_section_data (target_sect)->rel_hdr; - *hdr2 = *hdr; - elf_elfsections (abfd)[shindex] = hdr2; - target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize; - target_sect->flags |= SEC_RELOC; - target_sect->relocation = NULL; - target_sect->rel_filepos = hdr->sh_offset; - abfd->flags |= HAS_RELOC; - return true; - } - break; - - case SHT_SHLIB: - return true; - - default: - /* Check for any processor-specific section types. */ - { - if (bed->elf_backend_section_from_shdr) - (*bed->elf_backend_section_from_shdr) (abfd, hdr, name); - } - break; - } - - return true; -} - -/* Given an ELF section number, retrieve the corresponding BFD - section. */ - -asection * -bfd_section_from_elf_index (abfd, index) - bfd *abfd; - unsigned int index; -{ - BFD_ASSERT (index > 0 && index < SHN_LORESERVE); - if (index >= elf_elfheader (abfd)->e_shnum) - return NULL; - return elf_elfsections (abfd)[index]->bfd_section; -} - -boolean -_bfd_elf_new_section_hook (abfd, sec) - bfd *abfd; - asection *sec; -{ - struct bfd_elf_section_data *sdata; - - sdata = (struct bfd_elf_section_data *) bfd_alloc (abfd, sizeof (*sdata)); - if (!sdata) - return false; - sec->used_by_bfd = (PTR) sdata; - memset (sdata, 0, sizeof (*sdata)); - return true; -} - -/* Create a new bfd section from an ELF program header. - - Since program segments have no names, we generate a synthetic name - of the form segment, where NUM is generally the index in the - program header table. For segments that are split (see below) we - generate the names segmenta and segmentb. - - Note that some program segments may have a file size that is different than - (less than) the memory size. All this means is that at execution the - system must allocate the amount of memory specified by the memory size, - but only initialize it with the first "file size" bytes read from the - file. This would occur for example, with program segments consisting - of combined data+bss. - - To handle the above situation, this routine generates TWO bfd sections - for the single program segment. The first has the length specified by - the file size of the segment, and the second has the length specified - by the difference between the two sizes. In effect, the segment is split - into it's initialized and uninitialized parts. - - */ - -boolean -bfd_section_from_phdr (abfd, hdr, index) - bfd *abfd; - Elf_Internal_Phdr *hdr; - int index; -{ - asection *newsect; - char *name; - char namebuf[64]; - int split; - - split = ((hdr->p_memsz > 0) && - (hdr->p_filesz > 0) && - (hdr->p_memsz > hdr->p_filesz)); - sprintf (namebuf, split ? "segment%da" : "segment%d", index); - name = bfd_alloc (abfd, strlen (namebuf) + 1); - if (!name) - return false; - strcpy (name, namebuf); - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - return false; - newsect->vma = hdr->p_vaddr; - newsect->lma = hdr->p_paddr; - newsect->_raw_size = hdr->p_filesz; - newsect->filepos = hdr->p_offset; - newsect->flags |= SEC_HAS_CONTENTS; - if (hdr->p_type == PT_LOAD) - { - newsect->flags |= SEC_ALLOC; - newsect->flags |= SEC_LOAD; - if (hdr->p_flags & PF_X) - { - /* FIXME: all we known is that it has execute PERMISSION, - may be data. */ - newsect->flags |= SEC_CODE; - } - } - if (!(hdr->p_flags & PF_W)) - { - newsect->flags |= SEC_READONLY; - } - - if (split) - { - sprintf (namebuf, "segment%db", index); - name = bfd_alloc (abfd, strlen (namebuf) + 1); - if (!name) - return false; - strcpy (name, namebuf); - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - return false; - newsect->vma = hdr->p_vaddr + hdr->p_filesz; - newsect->lma = hdr->p_paddr + hdr->p_filesz; - newsect->_raw_size = hdr->p_memsz - hdr->p_filesz; - if (hdr->p_type == PT_LOAD) - { - newsect->flags |= SEC_ALLOC; - if (hdr->p_flags & PF_X) - newsect->flags |= SEC_CODE; - } - if (!(hdr->p_flags & PF_W)) - newsect->flags |= SEC_READONLY; - } - - return true; -} - -/* Set up an ELF internal section header for a section. */ - -/*ARGSUSED*/ -static void -elf_fake_sections (abfd, asect, failedptrarg) - bfd *abfd; - asection *asect; - PTR failedptrarg; -{ - struct elf_backend_data *bed = get_elf_backend_data (abfd); - boolean *failedptr = (boolean *) failedptrarg; - Elf_Internal_Shdr *this_hdr; - - if (*failedptr) - { - /* We already failed; just get out of the bfd_map_over_sections - loop. */ - return; - } - - this_hdr = &elf_section_data (asect)->this_hdr; - - this_hdr->sh_name = (unsigned long) _bfd_stringtab_add (elf_shstrtab (abfd), - asect->name, - true, false); - if (this_hdr->sh_name == (unsigned long) -1) - { - *failedptr = true; - return; - } - - this_hdr->sh_flags = 0; - - if ((asect->flags & SEC_ALLOC) != 0) - this_hdr->sh_addr = asect->vma; - else - this_hdr->sh_addr = 0; - - this_hdr->sh_offset = 0; - this_hdr->sh_size = asect->_raw_size; - this_hdr->sh_link = 0; - this_hdr->sh_addralign = 1 << asect->alignment_power; - /* The sh_entsize and sh_info fields may have been set already by - copy_private_section_data. */ - - this_hdr->bfd_section = asect; - this_hdr->contents = NULL; - - /* FIXME: This should not be based on section names. */ - if (strcmp (asect->name, ".dynstr") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if (strcmp (asect->name, ".hash") == 0) - { - this_hdr->sh_type = SHT_HASH; - this_hdr->sh_entsize = bed->s->arch_size / 8; - } - else if (strcmp (asect->name, ".dynsym") == 0) - { - this_hdr->sh_type = SHT_DYNSYM; - this_hdr->sh_entsize = bed->s->sizeof_sym; - } - else if (strcmp (asect->name, ".dynamic") == 0) - { - this_hdr->sh_type = SHT_DYNAMIC; - this_hdr->sh_entsize = bed->s->sizeof_dyn; - } - else if (strncmp (asect->name, ".rela", 5) == 0 - && get_elf_backend_data (abfd)->use_rela_p) - { - this_hdr->sh_type = SHT_RELA; - this_hdr->sh_entsize = bed->s->sizeof_rela; - } - else if (strncmp (asect->name, ".rel", 4) == 0 - && ! get_elf_backend_data (abfd)->use_rela_p) - { - this_hdr->sh_type = SHT_REL; - this_hdr->sh_entsize = bed->s->sizeof_rel; - } - else if (strcmp (asect->name, ".note") == 0) - this_hdr->sh_type = SHT_NOTE; - else if (strncmp (asect->name, ".stab", 5) == 0 - && strcmp (asect->name + strlen (asect->name) - 3, "str") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if ((asect->flags & SEC_ALLOC) != 0 - && (asect->flags & SEC_LOAD) != 0) - this_hdr->sh_type = SHT_PROGBITS; - else if ((asect->flags & SEC_ALLOC) != 0 - && ((asect->flags & SEC_LOAD) == 0)) - this_hdr->sh_type = SHT_NOBITS; - else - { - /* Who knows? */ - this_hdr->sh_type = SHT_PROGBITS; - } - - if ((asect->flags & SEC_ALLOC) != 0) - this_hdr->sh_flags |= SHF_ALLOC; - if ((asect->flags & SEC_READONLY) == 0) - this_hdr->sh_flags |= SHF_WRITE; - if ((asect->flags & SEC_CODE) != 0) - this_hdr->sh_flags |= SHF_EXECINSTR; - - /* Check for processor-specific section types. */ - { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (bed->elf_backend_fake_sections) - (*bed->elf_backend_fake_sections) (abfd, this_hdr, asect); - } - - /* If the section has relocs, set up a section header for the - SHT_REL[A] section. */ - if ((asect->flags & SEC_RELOC) != 0) - { - Elf_Internal_Shdr *rela_hdr; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - char *name; - - rela_hdr = &elf_section_data (asect)->rel_hdr; - name = bfd_alloc (abfd, sizeof ".rela" + strlen (asect->name)); - if (name == NULL) - { - *failedptr = true; - return; - } - sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name); - rela_hdr->sh_name = - (unsigned int) _bfd_stringtab_add (elf_shstrtab (abfd), name, - true, false); - if (rela_hdr->sh_name == (unsigned int) -1) - { - *failedptr = true; - return; - } - rela_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL; - rela_hdr->sh_entsize = (use_rela_p - ? bed->s->sizeof_rela - : bed->s->sizeof_rel); - rela_hdr->sh_addralign = bed->s->file_align; - rela_hdr->sh_flags = 0; - rela_hdr->sh_addr = 0; - rela_hdr->sh_size = 0; - rela_hdr->sh_offset = 0; - } -} - -/* Assign all ELF section numbers. The dummy first section is handled here - too. The link/info pointers for the standard section types are filled - in here too, while we're at it. */ - -static boolean -assign_section_numbers (abfd) - bfd *abfd; -{ - struct elf_obj_tdata *t = elf_tdata (abfd); - asection *sec; - unsigned int section_number; - Elf_Internal_Shdr **i_shdrp; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - section_number = 1; - - for (sec = abfd->sections; sec; sec = sec->next) - { - struct bfd_elf_section_data *d = elf_section_data (sec); - - d->this_idx = section_number++; - if ((sec->flags & SEC_RELOC) == 0) - d->rel_idx = 0; - else - d->rel_idx = section_number++; - } - - t->shstrtab_section = section_number++; - elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section; - t->shstrtab_hdr.sh_size = _bfd_stringtab_size (elf_shstrtab (abfd)); - - if (abfd->symcount > 0) - { - t->symtab_section = section_number++; - t->strtab_section = section_number++; - } - - elf_elfheader (abfd)->e_shnum = section_number; - - /* Set up the list of section header pointers, in agreement with the - indices. */ - i_shdrp = ((Elf_Internal_Shdr **) - bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *))); - if (i_shdrp == NULL) - return false; - - i_shdrp[0] = ((Elf_Internal_Shdr *) - bfd_alloc (abfd, sizeof (Elf_Internal_Shdr))); - if (i_shdrp[0] == NULL) - { - bfd_release (abfd, i_shdrp); - return false; - } - memset (i_shdrp[0], 0, sizeof (Elf_Internal_Shdr)); - - elf_elfsections (abfd) = i_shdrp; - - i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr; - if (abfd->symcount > 0) - { - i_shdrp[t->symtab_section] = &t->symtab_hdr; - i_shdrp[t->strtab_section] = &t->strtab_hdr; - t->symtab_hdr.sh_link = t->strtab_section; - } - for (sec = abfd->sections; sec; sec = sec->next) - { - struct bfd_elf_section_data *d = elf_section_data (sec); - asection *s; - const char *name; - - i_shdrp[d->this_idx] = &d->this_hdr; - if (d->rel_idx != 0) - i_shdrp[d->rel_idx] = &d->rel_hdr; - - /* Fill in the sh_link and sh_info fields while we're at it. */ - - /* sh_link of a reloc section is the section index of the symbol - table. sh_info is the section index of the section to which - the relocation entries apply. */ - if (d->rel_idx != 0) - { - d->rel_hdr.sh_link = t->symtab_section; - d->rel_hdr.sh_info = d->this_idx; - } - - switch (d->this_hdr.sh_type) - { - case SHT_REL: - case SHT_RELA: - /* A reloc section which we are treating as a normal BFD - section. sh_link is the section index of the symbol - table. sh_info is the section index of the section to - which the relocation entries apply. We assume that an - allocated reloc section uses the dynamic symbol table. - FIXME: How can we be sure? */ - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - - /* We look up the section the relocs apply to by name. */ - name = sec->name; - if (d->this_hdr.sh_type == SHT_REL) - name += 4; - else - name += 5; - s = bfd_get_section_by_name (abfd, name); - if (s != NULL) - d->this_hdr.sh_info = elf_section_data (s)->this_idx; - break; - - case SHT_STRTAB: - /* We assume that a section named .stab*str is a stabs - string section. We look for a section with the same name - but without the trailing ``str'', and set its sh_link - field to point to this section. */ - if (strncmp (sec->name, ".stab", sizeof ".stab" - 1) == 0 - && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0) - { - size_t len; - char *alc; - - len = strlen (sec->name); - alc = (char *) bfd_malloc (len - 2); - if (alc == NULL) - return false; - strncpy (alc, sec->name, len - 3); - alc[len - 3] = '\0'; - s = bfd_get_section_by_name (abfd, alc); - free (alc); - if (s != NULL) - { - elf_section_data (s)->this_hdr.sh_link = d->this_idx; - - /* This is a .stab section. */ - elf_section_data (s)->this_hdr.sh_entsize = - 4 + 2 * (bed->s->arch_size / 8); - } - } - break; - - case SHT_DYNAMIC: - case SHT_DYNSYM: - /* sh_link is the section header index of the string table - used for the dynamic entries or symbol table. */ - s = bfd_get_section_by_name (abfd, ".dynstr"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - break; - - case SHT_HASH: - /* sh_link is the section header index of the symbol table - this hash table is for. */ - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - break; - } - } - - return true; -} - -/* Map symbol from it's internal number to the external number, moving - all local symbols to be at the head of the list. */ - -static INLINE int -sym_is_global (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - /* If the backend has a special mapping, use it. */ - if (get_elf_backend_data (abfd)->elf_backend_sym_is_global) - return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global) - (abfd, sym)); - - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym))); -} - -static boolean -elf_map_symbols (abfd) - bfd *abfd; -{ - int symcount = bfd_get_symcount (abfd); - asymbol **syms = bfd_get_outsymbols (abfd); - asymbol **sect_syms; - int num_locals = 0; - int num_globals = 0; - int num_locals2 = 0; - int num_globals2 = 0; - int max_index = 0; - int num_sections = 0; - int idx; - asection *asect; - asymbol **new_syms; - -#ifdef DEBUG - fprintf (stderr, "elf_map_symbols\n"); - fflush (stderr); -#endif - - /* Add a section symbol for each BFD section. FIXME: Is this really - necessary? */ - for (asect = abfd->sections; asect; asect = asect->next) - { - if (max_index < asect->index) - max_index = asect->index; - } - - max_index++; - sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *)); - if (sect_syms == NULL) - return false; - elf_section_syms (abfd) = sect_syms; - - for (idx = 0; idx < symcount; idx++) - { - if ((syms[idx]->flags & BSF_SECTION_SYM) != 0 - && (syms[idx]->value + syms[idx]->section->vma) == 0) - { - asection *sec; - - sec = syms[idx]->section; - if (sec->owner != NULL) - { - if (sec->owner != abfd) - { - if (sec->output_offset != 0) - continue; - sec = sec->output_section; - BFD_ASSERT (sec->owner == abfd); - } - sect_syms[sec->index] = syms[idx]; - } - } - } - - for (asect = abfd->sections; asect; asect = asect->next) - { - asymbol *sym; - - if (sect_syms[asect->index] != NULL) - continue; - - sym = bfd_make_empty_symbol (abfd); - if (sym == NULL) - return false; - sym->the_bfd = abfd; - sym->name = asect->name; - sym->value = 0; - /* Set the flags to 0 to indicate that this one was newly added. */ - sym->flags = 0; - sym->section = asect; - sect_syms[asect->index] = sym; - num_sections++; -#ifdef DEBUG - fprintf (stderr, - "creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n", - asect->name, (long) asect->vma, asect->index, (long) asect); -#endif - } - - /* Classify all of the symbols. */ - for (idx = 0; idx < symcount; idx++) - { - if (!sym_is_global (abfd, syms[idx])) - num_locals++; - else - num_globals++; - } - for (asect = abfd->sections; asect; asect = asect->next) - { - if (sect_syms[asect->index] != NULL - && sect_syms[asect->index]->flags == 0) - { - sect_syms[asect->index]->flags = BSF_SECTION_SYM; - if (!sym_is_global (abfd, sect_syms[asect->index])) - num_locals++; - else - num_globals++; - sect_syms[asect->index]->flags = 0; - } - } - - /* Now sort the symbols so the local symbols are first. */ - new_syms = ((asymbol **) - bfd_alloc (abfd, - (num_locals + num_globals) * sizeof (asymbol *))); - if (new_syms == NULL) - return false; - - for (idx = 0; idx < symcount; idx++) - { - asymbol *sym = syms[idx]; - int i; - - if (!sym_is_global (abfd, sym)) - i = num_locals2++; - else - i = num_locals + num_globals2++; - new_syms[i] = sym; - sym->udata.i = i + 1; - } - for (asect = abfd->sections; asect; asect = asect->next) - { - if (sect_syms[asect->index] != NULL - && sect_syms[asect->index]->flags == 0) - { - asymbol *sym = sect_syms[asect->index]; - int i; - - sym->flags = BSF_SECTION_SYM; - if (!sym_is_global (abfd, sym)) - i = num_locals2++; - else - i = num_locals + num_globals2++; - new_syms[i] = sym; - sym->udata.i = i + 1; - } - } - - bfd_set_symtab (abfd, new_syms, num_locals + num_globals); - - elf_num_locals (abfd) = num_locals; - elf_num_globals (abfd) = num_globals; - return true; -} - -/* Align to the maximum file alignment that could be required for any - ELF data structure. */ - -static INLINE file_ptr align_file_position PARAMS ((file_ptr, int)); -static INLINE file_ptr -align_file_position (off, align) - file_ptr off; - int align; -{ - return (off + align - 1) & ~(align - 1); -} - -/* Assign a file position to a section, optionally aligning to the - required section alignment. */ - -INLINE file_ptr -_bfd_elf_assign_file_position_for_section (i_shdrp, offset, align) - Elf_Internal_Shdr *i_shdrp; - file_ptr offset; - boolean align; -{ - if (align) - { - unsigned int al; - - al = i_shdrp->sh_addralign; - if (al > 1) - offset = BFD_ALIGN (offset, al); - } - i_shdrp->sh_offset = offset; - if (i_shdrp->bfd_section != NULL) - i_shdrp->bfd_section->filepos = offset; - if (i_shdrp->sh_type != SHT_NOBITS) - offset += i_shdrp->sh_size; - return offset; -} - -/* Compute the file positions we are going to put the sections at, and - otherwise prepare to begin writing out the ELF file. If LINK_INFO - is not NULL, this is being called by the ELF backend linker. */ - -boolean -_bfd_elf_compute_section_file_positions (abfd, link_info) - bfd *abfd; - struct bfd_link_info *link_info; -{ - struct elf_backend_data *bed = get_elf_backend_data (abfd); - boolean failed; - struct bfd_strtab_hash *strtab; - Elf_Internal_Shdr *shstrtab_hdr; - - if (abfd->output_has_begun) - return true; - - /* Do any elf backend specific processing first. */ - if (bed->elf_backend_begin_write_processing) - (*bed->elf_backend_begin_write_processing) (abfd, link_info); - - if (! prep_headers (abfd)) - return false; - - failed = false; - bfd_map_over_sections (abfd, elf_fake_sections, &failed); - if (failed) - return false; - - if (!assign_section_numbers (abfd)) - return false; - - /* The backend linker builds symbol table information itself. */ - if (link_info == NULL && abfd->symcount > 0) - { - if (! swap_out_syms (abfd, &strtab)) - return false; - } - - shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr; - /* sh_name was set in prep_headers. */ - shstrtab_hdr->sh_type = SHT_STRTAB; - shstrtab_hdr->sh_flags = 0; - shstrtab_hdr->sh_addr = 0; - shstrtab_hdr->sh_size = _bfd_stringtab_size (elf_shstrtab (abfd)); - shstrtab_hdr->sh_entsize = 0; - shstrtab_hdr->sh_link = 0; - shstrtab_hdr->sh_info = 0; - /* sh_offset is set in assign_file_positions_except_relocs. */ - shstrtab_hdr->sh_addralign = 1; - - if (!assign_file_positions_except_relocs (abfd)) - return false; - - if (link_info == NULL && abfd->symcount > 0) - { - file_ptr off; - Elf_Internal_Shdr *hdr; - - off = elf_tdata (abfd)->next_file_pos; - - hdr = &elf_tdata (abfd)->symtab_hdr; - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); - - hdr = &elf_tdata (abfd)->strtab_hdr; - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); - - elf_tdata (abfd)->next_file_pos = off; - - /* Now that we know where the .strtab section goes, write it - out. */ - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, strtab)) - return false; - _bfd_stringtab_free (strtab); - } - - abfd->output_has_begun = true; - - return true; -} - -/* Create a mapping from a set of sections to a program segment. */ - -static INLINE struct elf_segment_map * -make_mapping (abfd, sections, from, to, phdr) - bfd *abfd; - asection **sections; - unsigned int from; - unsigned int to; - boolean phdr; -{ - struct elf_segment_map *m; - unsigned int i; - asection **hdrpp; - - m = ((struct elf_segment_map *) - bfd_zalloc (abfd, - (sizeof (struct elf_segment_map) - + (to - from - 1) * sizeof (asection *)))); - if (m == NULL) - return NULL; - m->next = NULL; - m->p_type = PT_LOAD; - for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++) - m->sections[i - from] = *hdrpp; - m->count = to - from; - - if (from == 0 && phdr) - { - /* Include the headers in the first PT_LOAD segment. */ - m->includes_filehdr = 1; - m->includes_phdrs = 1; - } - - return m; -} - -/* Set up a mapping from BFD sections to program segments. */ - -static boolean -map_sections_to_segments (abfd) - bfd *abfd; -{ - asection **sections = NULL; - asection *s; - unsigned int i; - unsigned int count; - struct elf_segment_map *mfirst; - struct elf_segment_map **pm; - struct elf_segment_map *m; - asection *last_hdr; - unsigned int phdr_index; - bfd_vma maxpagesize; - asection **hdrpp; - boolean phdr_in_section = true; - boolean writable; - asection *dynsec; - - if (elf_tdata (abfd)->segment_map != NULL) - return true; - - if (bfd_count_sections (abfd) == 0) - return true; - - /* Select the allocated sections, and sort them. */ - - sections = (asection **) bfd_malloc (bfd_count_sections (abfd) - * sizeof (asection *)); - if (sections == NULL) - goto error_return; - - i = 0; - for (s = abfd->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_ALLOC) != 0) - { - sections[i] = s; - ++i; - } - } - BFD_ASSERT (i <= bfd_count_sections (abfd)); - count = i; - - qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections); - - /* Build the mapping. */ - - mfirst = NULL; - pm = &mfirst; - - /* If we have a .interp section, then create a PT_PHDR segment for - the program headers and a PT_INTERP segment for the .interp - section. */ - s = bfd_get_section_by_name (abfd, ".interp"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - m = ((struct elf_segment_map *) - bfd_zalloc (abfd, sizeof (struct elf_segment_map))); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_PHDR; - /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */ - m->p_flags = PF_R | PF_X; - m->p_flags_valid = 1; - m->includes_phdrs = 1; - - *pm = m; - pm = &m->next; - - m = ((struct elf_segment_map *) - bfd_zalloc (abfd, sizeof (struct elf_segment_map))); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_INTERP; - m->count = 1; - m->sections[0] = s; - - *pm = m; - pm = &m->next; - } - - /* Look through the sections. We put sections in the same program - segment when the start of the second section can be placed within - a few bytes of the end of the first section. */ - last_hdr = NULL; - phdr_index = 0; - maxpagesize = get_elf_backend_data (abfd)->maxpagesize; - writable = false; - dynsec = bfd_get_section_by_name (abfd, ".dynamic"); - if (dynsec != NULL - && (dynsec->flags & SEC_LOAD) == 0) - dynsec = NULL; - - /* Deal with -Ttext or something similar such that the - first section is not adjacent to the program headers. */ - if (count - && ((sections[0]->lma % maxpagesize) < - (elf_tdata (abfd)->program_header_size % maxpagesize))) - phdr_in_section = false; - - for (i = 0, hdrpp = sections; i < count; i++, hdrpp++) - { - asection *hdr; - - hdr = *hdrpp; - - /* See if this section and the last one will fit in the same - segment. Don't put a loadable section after a non-loadable - section. If we are building a dynamic executable, don't put - a writable section in a read only segment (we don't do this - for a non-dynamic executable because some people prefer to - have only one program segment; anybody can use PHDRS in their - linker script to control what happens anyhow). */ - if (last_hdr == NULL - || ((BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize) - >= hdr->lma) - && ((last_hdr->flags & SEC_LOAD) != 0 - || (hdr->flags & SEC_LOAD) == 0) - && (dynsec == NULL - || writable - || (hdr->flags & SEC_READONLY) != 0))) - { - last_hdr = hdr; - continue; - } - - /* This section won't fit in the program segment. We must - create a new program header holding all the sections from - phdr_index until hdr. */ - - m = make_mapping (abfd, sections, phdr_index, i, phdr_in_section); - if (m == NULL) - goto error_return; - - *pm = m; - pm = &m->next; - - if ((hdr->flags & SEC_READONLY) == 0) - writable = true; - - last_hdr = hdr; - phdr_index = i; - phdr_in_section = false; - } - - /* Create a final PT_LOAD program segment. */ - if (last_hdr != NULL) - { - m = make_mapping (abfd, sections, phdr_index, i, phdr_in_section); - if (m == NULL) - goto error_return; - - *pm = m; - pm = &m->next; - } - - /* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */ - if (dynsec != NULL) - { - m = ((struct elf_segment_map *) - bfd_zalloc (abfd, sizeof (struct elf_segment_map))); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_DYNAMIC; - m->count = 1; - m->sections[0] = dynsec; - - *pm = m; - pm = &m->next; - } - - free (sections); - sections = NULL; - - elf_tdata (abfd)->segment_map = mfirst; - return true; - - error_return: - if (sections != NULL) - free (sections); - return false; -} - -/* Sort sections by VMA. */ - -static int -elf_sort_sections (arg1, arg2) - const PTR arg1; - const PTR arg2; -{ - const asection *sec1 = *(const asection **) arg1; - const asection *sec2 = *(const asection **) arg2; - - if (sec1->vma < sec2->vma) - return -1; - else if (sec1->vma > sec2->vma) - return 1; - - /* Put !SEC_LOAD sections after SEC_LOAD ones. */ - -#define TOEND(x) (((x)->flags & SEC_LOAD) == 0) - - if (TOEND (sec1)) - if (TOEND (sec2)) - return sec1->target_index - sec2->target_index; - else - return 1; - - if (TOEND (sec2)) - return -1; - -#undef TOEND - - /* Sort by size, to put zero sized sections before others at the - same address. */ - - if (sec1->_raw_size < sec2->_raw_size) - return -1; - if (sec1->_raw_size > sec2->_raw_size) - return 1; - - return sec1->target_index - sec2->target_index; -} - -/* Assign file positions to the sections based on the mapping from - sections to segments. This function also sets up some fields in - the file header, and writes out the program headers. */ - -static boolean -assign_file_positions_for_segments (abfd) - bfd *abfd; -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - unsigned int count; - struct elf_segment_map *m; - unsigned int alloc; - Elf_Internal_Phdr *phdrs; - file_ptr off; - bfd_vma filehdr_vaddr, filehdr_paddr; - bfd_vma phdrs_vaddr, phdrs_paddr; - Elf_Internal_Phdr *p; - - if (elf_tdata (abfd)->segment_map == NULL) - { - if (! map_sections_to_segments (abfd)) - return false; - } - - if (bed->elf_backend_modify_segment_map) - { - if (! (*bed->elf_backend_modify_segment_map) (abfd)) - return false; - } - - count = 0; - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - ++count; - - elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr; - elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr; - elf_elfheader (abfd)->e_phnum = count; - - if (count == 0) - return true; - - /* If we already counted the number of program segments, make sure - that we allocated enough space. This happens when SIZEOF_HEADERS - is used in a linker script. */ - alloc = elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr; - if (alloc != 0 && count > alloc) - { - ((*_bfd_error_handler) - ("%s: Not enough room for program headers (allocated %u, need %u)", - bfd_get_filename (abfd), alloc, count)); - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (alloc == 0) - alloc = count; - - phdrs = ((Elf_Internal_Phdr *) - bfd_alloc (abfd, alloc * sizeof (Elf_Internal_Phdr))); - if (phdrs == NULL) - return false; - - off = bed->s->sizeof_ehdr; - off += alloc * bed->s->sizeof_phdr; - - filehdr_vaddr = 0; - filehdr_paddr = 0; - phdrs_vaddr = 0; - phdrs_paddr = 0; - for (m = elf_tdata (abfd)->segment_map, p = phdrs; - m != NULL; - m = m->next, p++) - { - unsigned int i; - asection **secpp; - - /* If elf_segment_map is not from map_sections_to_segments, the - sections may not be correctly ordered. */ - if (m->count > 0) - qsort (m->sections, (size_t) m->count, sizeof (asection *), - elf_sort_sections); - - p->p_type = m->p_type; - - if (m->p_flags_valid) - p->p_flags = m->p_flags; - else - p->p_flags = 0; - - if (p->p_type == PT_LOAD - && m->count > 0 - && (m->sections[0]->flags & SEC_LOAD) != 0) - off += (m->sections[0]->vma - off) % bed->maxpagesize; - - if (m->count == 0) - p->p_vaddr = 0; - else - p->p_vaddr = m->sections[0]->vma; - - if (m->p_paddr_valid) - p->p_paddr = m->p_paddr; - else if (m->count == 0) - p->p_paddr = 0; - else - p->p_paddr = m->sections[0]->lma; - - if (p->p_type == PT_LOAD) - p->p_align = bed->maxpagesize; - else if (m->count == 0) - p->p_align = bed->s->file_align; - else - p->p_align = 0; - - p->p_offset = 0; - p->p_filesz = 0; - p->p_memsz = 0; - - if (m->includes_filehdr) - { - if (! m->p_flags_valid) - p->p_flags |= PF_R; - p->p_offset = 0; - p->p_filesz = bed->s->sizeof_ehdr; - p->p_memsz = bed->s->sizeof_ehdr; - if (m->count > 0) - { - BFD_ASSERT (p->p_type == PT_LOAD); - p->p_vaddr -= off; - if (! m->p_paddr_valid) - p->p_paddr -= off; - } - if (p->p_type == PT_LOAD) - { - filehdr_vaddr = p->p_vaddr; - filehdr_paddr = p->p_paddr; - } - } - - if (m->includes_phdrs) - { - if (! m->p_flags_valid) - p->p_flags |= PF_R; - if (m->includes_filehdr) - { - if (p->p_type == PT_LOAD) - { - phdrs_vaddr = p->p_vaddr + bed->s->sizeof_ehdr; - phdrs_paddr = p->p_paddr + bed->s->sizeof_ehdr; - } - } - else - { - p->p_offset = bed->s->sizeof_ehdr; - if (m->count > 0) - { - BFD_ASSERT (p->p_type == PT_LOAD); - p->p_vaddr -= off - p->p_offset; - if (! m->p_paddr_valid) - p->p_paddr -= off - p->p_offset; - } - if (p->p_type == PT_LOAD) - { - phdrs_vaddr = p->p_vaddr; - phdrs_paddr = p->p_paddr; - } - } - p->p_filesz += alloc * bed->s->sizeof_phdr; - p->p_memsz += alloc * bed->s->sizeof_phdr; - } - - if (p->p_type == PT_LOAD) - { - if (! m->includes_filehdr && ! m->includes_phdrs) - p->p_offset = off; - else - { - file_ptr adjust; - - adjust = off - (p->p_offset + p->p_filesz); - p->p_filesz += adjust; - p->p_memsz += adjust; - } - } - - for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) - { - asection *sec; - flagword flags; - bfd_size_type align; - - sec = *secpp; - flags = sec->flags; - - if (p->p_type == PT_LOAD) - { - bfd_vma adjust; - - /* The section VMA must equal the file position modulo - the page size. */ - if ((flags & SEC_ALLOC) != 0) - { - adjust = (sec->vma - off) % bed->maxpagesize; - if (adjust != 0) - { - if (i == 0) - abort (); - p->p_memsz += adjust; - off += adjust; - if ((flags & SEC_LOAD) != 0) - p->p_filesz += adjust; - } - } - - sec->filepos = off; - - if ((flags & SEC_LOAD) != 0) - off += sec->_raw_size; - } - - p->p_memsz += sec->_raw_size; - - if ((flags & SEC_LOAD) != 0) - p->p_filesz += sec->_raw_size; - - align = 1 << bfd_get_section_alignment (abfd, sec); - if (align > p->p_align) - p->p_align = align; - - if (! m->p_flags_valid) - { - p->p_flags |= PF_R; - if ((flags & SEC_CODE) != 0) - p->p_flags |= PF_X; - if ((flags & SEC_READONLY) == 0) - p->p_flags |= PF_W; - } - } - } - - /* Now that we have set the section file positions, we can set up - the file positions for the non PT_LOAD segments. */ - for (m = elf_tdata (abfd)->segment_map, p = phdrs; - m != NULL; - m = m->next, p++) - { - if (p->p_type != PT_LOAD && m->count > 0) - { - BFD_ASSERT (! m->includes_filehdr && ! m->includes_phdrs); - p->p_offset = m->sections[0]->filepos; - } - if (m->count == 0) - { - if (m->includes_filehdr) - { - p->p_vaddr = filehdr_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = filehdr_paddr; - } - else if (m->includes_phdrs) - { - p->p_vaddr = phdrs_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = phdrs_paddr; - } - } - } - - /* Clear out any program headers we allocated but did not use. */ - for (; count < alloc; count++, p++) - { - memset (p, 0, sizeof *p); - p->p_type = PT_NULL; - } - - elf_tdata (abfd)->phdr = phdrs; - - elf_tdata (abfd)->next_file_pos = off; - - /* Write out the program headers. */ - if (bfd_seek (abfd, bed->s->sizeof_ehdr, SEEK_SET) != 0 - || bed->s->write_out_phdrs (abfd, phdrs, alloc) != 0) - return false; - - return true; -} - -/* Get the size of the program header. - - If this is called by the linker before any of the section VMA's are set, it - can't calculate the correct value for a strange memory layout. This only - happens when SIZEOF_HEADERS is used in a linker script. In this case, - SORTED_HDRS is NULL and we assume the normal scenario of one text and one - data segment (exclusive of .interp and .dynamic). - - ??? User written scripts must either not use SIZEOF_HEADERS, or assume there - will be two segments. */ - -static bfd_size_type -get_program_header_size (abfd) - bfd *abfd; -{ - size_t segs; - asection *s; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* We can't return a different result each time we're called. */ - if (elf_tdata (abfd)->program_header_size != 0) - return elf_tdata (abfd)->program_header_size; - - if (elf_tdata (abfd)->segment_map != NULL) - { - struct elf_segment_map *m; - - segs = 0; - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - ++segs; - elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr; - return elf_tdata (abfd)->program_header_size; - } - - /* Assume we will need exactly two PT_LOAD segments: one for text - and one for data. */ - segs = 2; - - s = bfd_get_section_by_name (abfd, ".interp"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - /* If we have a loadable interpreter section, we need a - PT_INTERP segment. In this case, assume we also need a - PT_PHDR segment, although that may not be true for all - targets. */ - segs += 2; - } - - if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) - { - /* We need a PT_DYNAMIC segment. */ - ++segs; - } - - /* Let the backend count up any program headers it might need. */ - if (bed->elf_backend_additional_program_headers) - { - int a; - - a = (*bed->elf_backend_additional_program_headers) (abfd); - if (a == -1) - abort (); - segs += a; - } - - elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr; - return elf_tdata (abfd)->program_header_size; -} - -/* Work out the file positions of all the sections. This is called by - _bfd_elf_compute_section_file_positions. All the section sizes and - VMAs must be known before this is called. - - We do not consider reloc sections at this point, unless they form - part of the loadable image. Reloc sections are assigned file - positions in assign_file_positions_for_relocs, which is called by - write_object_contents and final_link. - - We also don't set the positions of the .symtab and .strtab here. */ - -static boolean -assign_file_positions_except_relocs (abfd) - bfd *abfd; -{ - struct elf_obj_tdata * const tdata = elf_tdata (abfd); - Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd); - Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); - file_ptr off; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) - { - Elf_Internal_Shdr **hdrpp; - unsigned int i; - - /* Start after the ELF header. */ - off = i_ehdrp->e_ehsize; - - /* We are not creating an executable, which means that we are - not creating a program header, and that the actual order of - the sections in the file is unimportant. */ - for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) - { - hdr->sh_offset = -1; - continue; - } - if (i == tdata->symtab_section - || i == tdata->strtab_section) - { - hdr->sh_offset = -1; - continue; - } - - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); - } - } - else - { - unsigned int i; - Elf_Internal_Shdr **hdrpp; - - /* Assign file positions for the loaded sections based on the - assignment of sections to segments. */ - if (! assign_file_positions_for_segments (abfd)) - return false; - - /* Assign file positions for the other sections. */ - - off = elf_tdata (abfd)->next_file_pos; - for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if (hdr->bfd_section != NULL - && hdr->bfd_section->filepos != 0) - hdr->sh_offset = hdr->bfd_section->filepos; - else if ((hdr->sh_flags & SHF_ALLOC) != 0) - { - ((*_bfd_error_handler) - ("%s: warning: allocated section `%s' not in segment", - bfd_get_filename (abfd), - (hdr->bfd_section == NULL - ? "*unknown*" - : hdr->bfd_section->name))); - off += (hdr->sh_addr - off) % bed->maxpagesize; - off = _bfd_elf_assign_file_position_for_section (hdr, off, - false); - } - else if (hdr->sh_type == SHT_REL - || hdr->sh_type == SHT_RELA - || hdr == i_shdrpp[tdata->symtab_section] - || hdr == i_shdrpp[tdata->strtab_section]) - hdr->sh_offset = -1; - else - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); - } - } - - /* Place the section headers. */ - off = align_file_position (off, bed->s->file_align); - i_ehdrp->e_shoff = off; - off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; - - elf_tdata (abfd)->next_file_pos = off; - - return true; -} - -static boolean -prep_headers (abfd) - bfd *abfd; -{ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */ - Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ - int count; - struct bfd_strtab_hash *shstrtab; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - i_ehdrp = elf_elfheader (abfd); - i_shdrp = elf_elfsections (abfd); - - shstrtab = _bfd_elf_stringtab_init (); - if (shstrtab == NULL) - return false; - - elf_shstrtab (abfd) = shstrtab; - - i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; - i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; - i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; - i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; - - i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass; - i_ehdrp->e_ident[EI_DATA] = - bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB; - i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current; - - for (count = EI_PAD; count < EI_NIDENT; count++) - i_ehdrp->e_ident[count] = 0; - - if ((abfd->flags & DYNAMIC) != 0) - i_ehdrp->e_type = ET_DYN; - else if ((abfd->flags & EXEC_P) != 0) - i_ehdrp->e_type = ET_EXEC; - else - i_ehdrp->e_type = ET_REL; - - switch (bfd_get_arch (abfd)) - { - case bfd_arch_unknown: - i_ehdrp->e_machine = EM_NONE; - break; - case bfd_arch_sparc: - if (bed->s->arch_size == 64) - i_ehdrp->e_machine = EM_SPARC64; - else - i_ehdrp->e_machine = EM_SPARC; - break; - case bfd_arch_i386: - i_ehdrp->e_machine = EM_386; - break; - case bfd_arch_m68k: - i_ehdrp->e_machine = EM_68K; - break; - case bfd_arch_m88k: - i_ehdrp->e_machine = EM_88K; - break; - case bfd_arch_i860: - i_ehdrp->e_machine = EM_860; - break; - case bfd_arch_mips: /* MIPS Rxxxx */ - i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */ - break; - case bfd_arch_hppa: - i_ehdrp->e_machine = EM_PARISC; - break; - case bfd_arch_powerpc: - i_ehdrp->e_machine = EM_PPC; - break; - /* also note that EM_M32, AT&T WE32100 is unknown to bfd */ - default: - i_ehdrp->e_machine = EM_NONE; - } - i_ehdrp->e_version = bed->s->ev_current; - i_ehdrp->e_ehsize = bed->s->sizeof_ehdr; - - /* no program header, for now. */ - i_ehdrp->e_phoff = 0; - i_ehdrp->e_phentsize = 0; - i_ehdrp->e_phnum = 0; - - /* each bfd section is section header entry */ - i_ehdrp->e_entry = bfd_get_start_address (abfd); - i_ehdrp->e_shentsize = bed->s->sizeof_shdr; - - /* if we're building an executable, we'll need a program header table */ - if (abfd->flags & EXEC_P) - { - /* it all happens later */ -#if 0 - i_ehdrp->e_phentsize = sizeof (Elf_External_Phdr); - - /* elf_build_phdrs() returns a (NULL-terminated) array of - Elf_Internal_Phdrs */ - i_phdrp = elf_build_phdrs (abfd, i_ehdrp, i_shdrp, &i_ehdrp->e_phnum); - i_ehdrp->e_phoff = outbase; - outbase += i_ehdrp->e_phentsize * i_ehdrp->e_phnum; -#endif - } - else - { - i_ehdrp->e_phentsize = 0; - i_phdrp = 0; - i_ehdrp->e_phoff = 0; - } - - elf_tdata (abfd)->symtab_hdr.sh_name = - (unsigned int) _bfd_stringtab_add (shstrtab, ".symtab", true, false); - elf_tdata (abfd)->strtab_hdr.sh_name = - (unsigned int) _bfd_stringtab_add (shstrtab, ".strtab", true, false); - elf_tdata (abfd)->shstrtab_hdr.sh_name = - (unsigned int) _bfd_stringtab_add (shstrtab, ".shstrtab", true, false); - if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 - || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 - || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1) - return false; - - return true; -} - -/* Assign file positions for all the reloc sections which are not part - of the loadable file image. */ - -void -_bfd_elf_assign_file_positions_for_relocs (abfd) - bfd *abfd; -{ - file_ptr off; - unsigned int i; - Elf_Internal_Shdr **shdrpp; - - off = elf_tdata (abfd)->next_file_pos; - - for (i = 1, shdrpp = elf_elfsections (abfd) + 1; - i < elf_elfheader (abfd)->e_shnum; - i++, shdrpp++) - { - Elf_Internal_Shdr *shdrp; - - shdrp = *shdrpp; - if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA) - && shdrp->sh_offset == -1) - off = _bfd_elf_assign_file_position_for_section (shdrp, off, true); - } - - elf_tdata (abfd)->next_file_pos = off; -} - -boolean -_bfd_elf_write_object_contents (abfd) - bfd *abfd; -{ - struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Ehdr *i_ehdrp; - Elf_Internal_Shdr **i_shdrp; - boolean failed; - unsigned int count; - - if (! abfd->output_has_begun - && ! _bfd_elf_compute_section_file_positions (abfd, - (struct bfd_link_info *) NULL)) - return false; - - i_shdrp = elf_elfsections (abfd); - i_ehdrp = elf_elfheader (abfd); - - failed = false; - bfd_map_over_sections (abfd, bed->s->write_relocs, &failed); - if (failed) - return false; - _bfd_elf_assign_file_positions_for_relocs (abfd); - - /* After writing the headers, we need to write the sections too... */ - for (count = 1; count < i_ehdrp->e_shnum; count++) - { - if (bed->elf_backend_section_processing) - (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]); - if (i_shdrp[count]->contents) - { - if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0 - || (bfd_write (i_shdrp[count]->contents, i_shdrp[count]->sh_size, - 1, abfd) - != i_shdrp[count]->sh_size)) - return false; - } - } - - /* Write out the section header names. */ - if (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, elf_shstrtab (abfd))) - return false; - - if (bed->elf_backend_final_write_processing) - (*bed->elf_backend_final_write_processing) (abfd, - elf_tdata (abfd)->linker); - - return bed->s->write_shdrs_and_ehdr (abfd); -} - -/* given a section, search the header to find them... */ -int -_bfd_elf_section_from_bfd_section (abfd, asect) - bfd *abfd; - struct sec *asect; -{ - struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd); - int index; - Elf_Internal_Shdr *hdr; - int maxindex = elf_elfheader (abfd)->e_shnum; - - for (index = 0; index < maxindex; index++) - { - hdr = i_shdrp[index]; - if (hdr->bfd_section == asect) - return index; - } - - if (bed->elf_backend_section_from_bfd_section) - { - for (index = 0; index < maxindex; index++) - { - int retval; - - hdr = i_shdrp[index]; - retval = index; - if ((*bed->elf_backend_section_from_bfd_section) - (abfd, hdr, asect, &retval)) - return retval; - } - } - - if (bfd_is_abs_section (asect)) - return SHN_ABS; - if (bfd_is_com_section (asect)) - return SHN_COMMON; - if (bfd_is_und_section (asect)) - return SHN_UNDEF; - - return -1; -} - -/* Given a BFD symbol, return the index in the ELF symbol table, or -1 - on error. */ - -int -_bfd_elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr) - bfd *abfd; - struct symbol_cache_entry **asym_ptr_ptr; -{ - struct symbol_cache_entry *asym_ptr = *asym_ptr_ptr; - int idx; - flagword flags = asym_ptr->flags; - - /* When gas creates relocations against local labels, it creates its - own symbol for the section, but does put the symbol into the - symbol chain, so udata is 0. When the linker is generating - relocatable output, this section symbol may be for one of the - input sections rather than the output section. */ - if (asym_ptr->udata.i == 0 - && (flags & BSF_SECTION_SYM) - && asym_ptr->section) - { - int indx; - - if (asym_ptr->section->output_section != NULL) - indx = asym_ptr->section->output_section->index; - else - indx = asym_ptr->section->index; - if (elf_section_syms (abfd)[indx]) - asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i; - } - - idx = asym_ptr->udata.i; - - if (idx == 0) - { - /* This case can occur when using --strip-symbol on a symbol - which is used in a relocation entry. */ - (*_bfd_error_handler) - ("%s: symbol `%s' required but not present", - bfd_get_filename (abfd), bfd_asymbol_name (asym_ptr)); - bfd_set_error (bfd_error_no_symbols); - return -1; - } - -#if DEBUG & 4 - { - fprintf (stderr, - "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n", - (long) asym_ptr, asym_ptr->name, idx, flags, - elf_symbol_flags (flags)); - fflush (stderr); - } -#endif - - return idx; -} - -/* Copy private BFD data. This copies any program header information. */ - -static boolean -copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - Elf_Internal_Ehdr *iehdr; - struct elf_segment_map *mfirst; - struct elf_segment_map **pm; - Elf_Internal_Phdr *p; - unsigned int i, c; - - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour - || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - if (elf_tdata (ibfd)->phdr == NULL) - return true; - - iehdr = elf_elfheader (ibfd); - - mfirst = NULL; - pm = &mfirst; - - c = elf_elfheader (ibfd)->e_phnum; - for (i = 0, p = elf_tdata (ibfd)->phdr; i < c; i++, p++) - { - unsigned int csecs; - asection *s; - struct elf_segment_map *m; - unsigned int isec; - - csecs = 0; - - /* The complicated case when p_vaddr is 0 is to handle the - Solaris linker, which generates a PT_INTERP section with - p_vaddr and p_memsz set to 0. */ - for (s = ibfd->sections; s != NULL; s = s->next) - if (((s->vma >= p->p_vaddr - && (s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz - || s->vma + s->_raw_size <= p->p_vaddr + p->p_filesz)) - || (p->p_vaddr == 0 - && p->p_filesz > 0 - && (s->flags & SEC_HAS_CONTENTS) != 0 - && (bfd_vma) s->filepos >= p->p_offset - && ((bfd_vma) s->filepos + s->_raw_size - <= p->p_offset + p->p_filesz))) - && (s->flags & SEC_ALLOC) != 0 - && s->output_section != NULL) - ++csecs; - - m = ((struct elf_segment_map *) - bfd_alloc (obfd, - (sizeof (struct elf_segment_map) - + (csecs - 1) * sizeof (asection *)))); - if (m == NULL) - return false; - - m->next = NULL; - m->p_type = p->p_type; - m->p_flags = p->p_flags; - m->p_flags_valid = 1; - m->p_paddr = p->p_paddr; - m->p_paddr_valid = 1; - - m->includes_filehdr = (p->p_offset == 0 - && p->p_filesz >= iehdr->e_ehsize); - - m->includes_phdrs = (p->p_offset <= (bfd_vma) iehdr->e_phoff - && (p->p_offset + p->p_filesz - >= ((bfd_vma) iehdr->e_phoff - + iehdr->e_phnum * iehdr->e_phentsize))); - - isec = 0; - for (s = ibfd->sections; s != NULL; s = s->next) - { - if (((s->vma >= p->p_vaddr - && (s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz - || s->vma + s->_raw_size <= p->p_vaddr + p->p_filesz)) - || (p->p_vaddr == 0 - && p->p_filesz > 0 - && (s->flags & SEC_HAS_CONTENTS) != 0 - && (bfd_vma) s->filepos >= p->p_offset - && ((bfd_vma) s->filepos + s->_raw_size - <= p->p_offset + p->p_filesz))) - && (s->flags & SEC_ALLOC) != 0 - && s->output_section != NULL) - { - m->sections[isec] = s->output_section; - ++isec; - } - } - BFD_ASSERT (isec == csecs); - m->count = csecs; - - *pm = m; - pm = &m->next; - } - - elf_tdata (obfd)->segment_map = mfirst; - - return true; -} - -/* Copy private section information. This copies over the entsize - field, and sometimes the info field. */ - -boolean -_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec) - bfd *ibfd; - asection *isec; - bfd *obfd; - asection *osec; -{ - Elf_Internal_Shdr *ihdr, *ohdr; - - if (ibfd->xvec->flavour != bfd_target_elf_flavour - || obfd->xvec->flavour != bfd_target_elf_flavour) - return true; - - /* Copy over private BFD data if it has not already been copied. - This must be done here, rather than in the copy_private_bfd_data - entry point, because the latter is called after the section - contents have been set, which means that the program headers have - already been worked out. */ - if (elf_tdata (obfd)->segment_map == NULL - && elf_tdata (ibfd)->phdr != NULL) - { - asection *s; - - /* Only set up the segments when all the sections have been set - up. */ - for (s = ibfd->sections; s != NULL; s = s->next) - if (s->output_section == NULL) - break; - if (s == NULL) - { - if (! copy_private_bfd_data (ibfd, obfd)) - return false; - } - } - - ihdr = &elf_section_data (isec)->this_hdr; - ohdr = &elf_section_data (osec)->this_hdr; - - ohdr->sh_entsize = ihdr->sh_entsize; - - if (ihdr->sh_type == SHT_SYMTAB - || ihdr->sh_type == SHT_DYNSYM) - ohdr->sh_info = ihdr->sh_info; - - return true; -} - -/* Copy private symbol information. If this symbol is in a section - which we did not map into a BFD section, try to map the section - index correctly. We use special macro definitions for the mapped - section indices; these definitions are interpreted by the - swap_out_syms function. */ - -#define MAP_ONESYMTAB (SHN_LORESERVE - 1) -#define MAP_DYNSYMTAB (SHN_LORESERVE - 2) -#define MAP_STRTAB (SHN_LORESERVE - 3) -#define MAP_SHSTRTAB (SHN_LORESERVE - 4) - -boolean -_bfd_elf_copy_private_symbol_data (ibfd, isymarg, obfd, osymarg) - bfd *ibfd; - asymbol *isymarg; - bfd *obfd; - asymbol *osymarg; -{ - elf_symbol_type *isym, *osym; - - isym = elf_symbol_from (ibfd, isymarg); - osym = elf_symbol_from (obfd, osymarg); - - if (isym != NULL - && osym != NULL - && bfd_is_abs_section (isym->symbol.section)) - { - unsigned int shndx; - - shndx = isym->internal_elf_sym.st_shndx; - if (shndx == elf_onesymtab (ibfd)) - shndx = MAP_ONESYMTAB; - else if (shndx == elf_dynsymtab (ibfd)) - shndx = MAP_DYNSYMTAB; - else if (shndx == elf_tdata (ibfd)->strtab_section) - shndx = MAP_STRTAB; - else if (shndx == elf_tdata (ibfd)->shstrtab_section) - shndx = MAP_SHSTRTAB; - osym->internal_elf_sym.st_shndx = shndx; - } - - return true; -} - -/* Swap out the symbols. */ - -static boolean -swap_out_syms (abfd, sttp) - bfd *abfd; - struct bfd_strtab_hash **sttp; -{ - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (!elf_map_symbols (abfd)) - return false; - - /* Dump out the symtabs. */ - { - int symcount = bfd_get_symcount (abfd); - asymbol **syms = bfd_get_outsymbols (abfd); - struct bfd_strtab_hash *stt; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - char *outbound_syms; - int idx; - - stt = _bfd_elf_stringtab_init (); - if (stt == NULL) - return false; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - symtab_hdr->sh_type = SHT_SYMTAB; - symtab_hdr->sh_entsize = bed->s->sizeof_sym; - symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1); - symtab_hdr->sh_info = elf_num_locals (abfd) + 1; - symtab_hdr->sh_addralign = bed->s->file_align; - - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - symstrtab_hdr->sh_type = SHT_STRTAB; - - outbound_syms = bfd_alloc (abfd, - (1 + symcount) * bed->s->sizeof_sym); - if (outbound_syms == NULL) - return false; - symtab_hdr->contents = (PTR) outbound_syms; - - /* now generate the data (for "contents") */ - { - /* Fill in zeroth symbol and swap it out. */ - Elf_Internal_Sym sym; - sym.st_name = 0; - sym.st_value = 0; - sym.st_size = 0; - sym.st_info = 0; - sym.st_other = 0; - sym.st_shndx = SHN_UNDEF; - bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms); - outbound_syms += bed->s->sizeof_sym; - } - for (idx = 0; idx < symcount; idx++) - { - Elf_Internal_Sym sym; - bfd_vma value = syms[idx]->value; - elf_symbol_type *type_ptr; - flagword flags = syms[idx]->flags; - int type; - - if (flags & BSF_SECTION_SYM) - /* Section symbols have no names. */ - sym.st_name = 0; - else - { - sym.st_name = (unsigned long) _bfd_stringtab_add (stt, - syms[idx]->name, - true, false); - if (sym.st_name == (unsigned long) -1) - return false; - } - - type_ptr = elf_symbol_from (abfd, syms[idx]); - - if (bfd_is_com_section (syms[idx]->section)) - { - /* ELF common symbols put the alignment into the `value' field, - and the size into the `size' field. This is backwards from - how BFD handles it, so reverse it here. */ - sym.st_size = value; - if (type_ptr == NULL - || type_ptr->internal_elf_sym.st_value == 0) - sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value)); - else - sym.st_value = type_ptr->internal_elf_sym.st_value; - sym.st_shndx = _bfd_elf_section_from_bfd_section (abfd, - syms[idx]->section); - } - else - { - asection *sec = syms[idx]->section; - int shndx; - - if (sec->output_section) - { - value += sec->output_offset; - sec = sec->output_section; - } - value += sec->vma; - sym.st_value = value; - sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0; - - if (bfd_is_abs_section (sec) - && type_ptr != NULL - && type_ptr->internal_elf_sym.st_shndx != 0) - { - /* This symbol is in a real ELF section which we did - not create as a BFD section. Undo the mapping done - by copy_private_symbol_data. */ - shndx = type_ptr->internal_elf_sym.st_shndx; - switch (shndx) - { - case MAP_ONESYMTAB: - shndx = elf_onesymtab (abfd); - break; - case MAP_DYNSYMTAB: - shndx = elf_dynsymtab (abfd); - break; - case MAP_STRTAB: - shndx = elf_tdata (abfd)->strtab_section; - break; - case MAP_SHSTRTAB: - shndx = elf_tdata (abfd)->shstrtab_section; - break; - default: - break; - } - } - else - { - shndx = _bfd_elf_section_from_bfd_section (abfd, sec); - - if (shndx == -1) - { - asection *sec2; - - /* Writing this would be a hell of a lot easier if - we had some decent documentation on bfd, and - knew what to expect of the library, and what to - demand of applications. For example, it - appears that `objcopy' might not set the - section of a symbol to be a section that is - actually in the output file. */ - sec2 = bfd_get_section_by_name (abfd, sec->name); - BFD_ASSERT (sec2 != 0); - shndx = _bfd_elf_section_from_bfd_section (abfd, sec2); - BFD_ASSERT (shndx != -1); - } - } - - sym.st_shndx = shndx; - } - - if ((flags & BSF_FUNCTION) != 0) - type = STT_FUNC; - else if ((flags & BSF_OBJECT) != 0) - type = STT_OBJECT; - else - type = STT_NOTYPE; - - if (bfd_is_com_section (syms[idx]->section)) - sym.st_info = ELF_ST_INFO (STB_GLOBAL, type); - else if (bfd_is_und_section (syms[idx]->section)) - sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK) - ? STB_WEAK - : STB_GLOBAL), - type); - else if (flags & BSF_SECTION_SYM) - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - else if (flags & BSF_FILE) - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - else - { - int bind = STB_LOCAL; - - if (flags & BSF_LOCAL) - bind = STB_LOCAL; - else if (flags & BSF_WEAK) - bind = STB_WEAK; - else if (flags & BSF_GLOBAL) - bind = STB_GLOBAL; - - sym.st_info = ELF_ST_INFO (bind, type); - } - - sym.st_other = 0; - bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms); - outbound_syms += bed->s->sizeof_sym; - } - - *sttp = stt; - symstrtab_hdr->sh_size = _bfd_stringtab_size (stt); - symstrtab_hdr->sh_type = SHT_STRTAB; - - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - symstrtab_hdr->sh_addralign = 1; - } - - return true; -} - -/* Return the number of bytes required to hold the symtab vector. - - Note that we base it on the count plus 1, since we will null terminate - the vector allocated based on this size. However, the ELF symbol table - always has a dummy entry as symbol #0, so it ends up even. */ - -long -_bfd_elf_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - long symcount; - long symtab_size; - Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; - - symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *)); - - return symtab_size; -} - -long -_bfd_elf_get_dynamic_symtab_upper_bound (abfd) - bfd *abfd; -{ - long symcount; - long symtab_size; - Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; - - if (elf_dynsymtab (abfd) == 0) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *)); - - return symtab_size; -} - -long -_bfd_elf_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -/* Canonicalize the relocs. */ - -long -_bfd_elf_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr; - unsigned int i; - - if (! get_elf_backend_data (abfd)->s->slurp_reloc_table (abfd, section, symbols)) - return -1; - - tblptr = section->relocation; - for (i = 0; i < section->reloc_count; i++) - *relptr++ = tblptr++; - - *relptr = NULL; - - return section->reloc_count; -} - -long -_bfd_elf_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - long symcount = get_elf_backend_data (abfd)->s->slurp_symbol_table (abfd, alocation, false); - - if (symcount >= 0) - bfd_get_symcount (abfd) = symcount; - return symcount; -} - -long -_bfd_elf_canonicalize_dynamic_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - return get_elf_backend_data (abfd)->s->slurp_symbol_table (abfd, alocation, true); -} - -asymbol * -_bfd_elf_make_empty_symbol (abfd) - bfd *abfd; -{ - elf_symbol_type *newsym; - - newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (elf_symbol_type)); - if (!newsym) - return NULL; - else - { - newsym->symbol.the_bfd = abfd; - return &newsym->symbol; - } -} - -void -_bfd_elf_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -alent * -_bfd_elf_get_lineno (ignore_abfd, symbol) - bfd *ignore_abfd; - asymbol *symbol; -{ - abort (); - return NULL; -} - -boolean -_bfd_elf_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - /* If this isn't the right architecture for this backend, and this - isn't the generic backend, fail. */ - if (arch != get_elf_backend_data (abfd)->arch - && arch != bfd_arch_unknown - && get_elf_backend_data (abfd)->arch != bfd_arch_unknown) - return false; - - return bfd_default_set_arch_mach (abfd, arch, machine); -} - -/* Find the nearest line to a particular section and offset, for error - reporting. */ - -boolean -_bfd_elf_find_nearest_line (abfd, - section, - symbols, - offset, - filename_ptr, - functionname_ptr, - line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - boolean found; - const char *filename; - asymbol *func; - bfd_vma low_func; - asymbol **p; - - if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, - &found, filename_ptr, - functionname_ptr, line_ptr, - &elf_tdata (abfd)->line_info)) - return false; - if (found) - return true; - - if (symbols == NULL) - return false; - - filename = NULL; - func = NULL; - low_func = 0; - - for (p = symbols; *p != NULL; p++) - { - elf_symbol_type *q; - - q = (elf_symbol_type *) *p; - - if (bfd_get_section (&q->symbol) != section) - continue; - - switch (ELF_ST_TYPE (q->internal_elf_sym.st_info)) - { - default: - break; - case STT_FILE: - filename = bfd_asymbol_name (&q->symbol); - break; - case STT_FUNC: - if (q->symbol.section == section - && q->symbol.value >= low_func - && q->symbol.value <= offset) - { - func = (asymbol *) q; - low_func = q->symbol.value; - } - break; - } - } - - if (func == NULL) - return false; - - *filename_ptr = filename; - *functionname_ptr = bfd_asymbol_name (func); - *line_ptr = 0; - return true; -} - -int -_bfd_elf_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - int ret; - - ret = get_elf_backend_data (abfd)->s->sizeof_ehdr; - if (! reloc) - ret += get_program_header_size (abfd); - return ret; -} - -boolean -_bfd_elf_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - Elf_Internal_Shdr *hdr; - - if (! abfd->output_has_begun - && ! _bfd_elf_compute_section_file_positions (abfd, - (struct bfd_link_info *) NULL)) - return false; - - hdr = &elf_section_data (section)->this_hdr; - - if (bfd_seek (abfd, hdr->sh_offset + offset, SEEK_SET) == -1) - return false; - if (bfd_write (location, 1, count, abfd) != count) - return false; - - return true; -} - -void -_bfd_elf_no_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - abort (); -} - -#if 0 -void -_bfd_elf_no_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rel *dst; -{ - abort (); -} -#endif diff --git a/contrib/gdb/bfd/elf32-gen.c b/contrib/gdb/bfd/elf32-gen.c deleted file mode 100644 index 385fda20860..00000000000 --- a/contrib/gdb/bfd/elf32-gen.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Generic support for 32-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocations, but should be good enough - for GDB to read the file. */ - -#define TARGET_LITTLE_SYM bfd_elf32_little_generic_vec -#define TARGET_LITTLE_NAME "elf32-little" -#define TARGET_BIG_SYM bfd_elf32_big_generic_vec -#define TARGET_BIG_NAME "elf32-big" -#define ELF_ARCH bfd_arch_unknown -#define ELF_MACHINE_CODE EM_NONE -#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-hppa.c b/contrib/gdb/bfd/elf32-hppa.c deleted file mode 100644 index 23867317032..00000000000 --- a/contrib/gdb/bfd/elf32-hppa.c +++ /dev/null @@ -1,2984 +0,0 @@ -/* BFD back-end for HP PA-RISC ELF files. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - - Written by - - Center for Software Science - Department of Computer Science - University of Utah - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "obstack.h" -#include "elf-bfd.h" - -/* The internal type of a symbol table extension entry. */ -typedef unsigned long symext_entryS; - -/* The external type of a symbol table extension entry. */ -#define ELF32_PARISC_SX_SIZE (4) -#define ELF32_PARISC_SX_GET(bfd, addr) bfd_h_get_32 ((bfd), (addr)) -#define ELF32_PARISC_SX_PUT(bfd, val, addr) \ - bfd_h_put_32 ((bfd), (val), (addr)) - -/* HPPA symbol table extension entry types */ -enum elf32_hppa_symextn_types -{ - PARISC_SXT_NULL, - PARISC_SXT_SYMNDX, - PARISC_SXT_ARG_RELOC, -}; - -/* These macros compose and decompose the value of a symextn entry: - - entry_type = ELF32_PARISC_SX_TYPE(word); - entry_value = ELF32_PARISC_SX_VAL(word); - word = ELF32_PARISC_SX_WORD(type,val); */ - -#define ELF32_PARISC_SX_TYPE(p) ((p) >> 24) -#define ELF32_PARISC_SX_VAL(p) ((p) & 0xFFFFFF) -#define ELF32_PARISC_SX_WORD(type,val) (((type) << 24) + (val & 0xFFFFFF)) - -/* The following was added facilitate implementation of the .hppa_symextn - section. This section is built after the symbol table is built in the - elf_write_object_contents routine (called from bfd_close). It is built - so late because it requires information that is not known until - the symbol and string table sections have been allocated, and - the symbol table has been built. */ - -#define SYMEXTN_SECTION_NAME ".PARISC.symext" - -struct symext_chain - { - symext_entryS entry; - struct symext_chain *next; - }; - -typedef struct symext_chain symext_chainS; - -/* We use three different hash tables to hold information for - linking PA ELF objects. - - The first is the elf32_hppa_link_hash_table which is derived - from the standard ELF linker hash table. We use this as a place to - attach other hash tables and static information. - - The second is the stub hash table which is derived from the - base BFD hash table. The stub hash table holds the information - necessary to build the linker stubs during a link. - - The last hash table keeps track of argument location information needed - to build hash tables. Each function with nonzero argument location - bits will have an entry in this table. */ - -/* Hash table for linker stubs. */ - -struct elf32_hppa_stub_hash_entry -{ - /* Base hash table entry structure, we can get the name of the stub - (and thus know exactly what actions it performs) from the base - hash table entry. */ - struct bfd_hash_entry root; - - /* Offset of the beginning of this stub. */ - bfd_vma offset; - - /* Given the symbol's value and its section we can determine its final - value when building the stubs (so the stub knows where to jump. */ - symvalue target_value; - asection *target_section; -}; - -struct elf32_hppa_stub_hash_table -{ - /* The hash table itself. */ - struct bfd_hash_table root; - - /* The stub BFD. */ - bfd *stub_bfd; - - /* Where to place the next stub. */ - bfd_byte *location; - - /* Current offset in the stub section. */ - unsigned int offset; - -}; - -/* Hash table for argument location information. */ - -struct elf32_hppa_args_hash_entry -{ - /* Base hash table entry structure. */ - struct bfd_hash_entry root; - - /* The argument location bits for this entry. */ - int arg_bits; -}; - -struct elf32_hppa_args_hash_table -{ - /* The hash table itself. */ - struct bfd_hash_table root; -}; - -struct elf32_hppa_link_hash_entry -{ - struct elf_link_hash_entry root; -}; - -struct elf32_hppa_link_hash_table -{ - /* The main hash table. */ - struct elf_link_hash_table root; - - /* The stub hash table. */ - struct elf32_hppa_stub_hash_table *stub_hash_table; - - /* The argument relocation bits hash table. */ - struct elf32_hppa_args_hash_table *args_hash_table; - - /* A count of the number of output symbols. */ - unsigned int output_symbol_count; - - /* Stuff so we can handle DP relative relocations. */ - long global_value; - int global_sym_defined; -}; - -/* FIXME. */ -#define ARGUMENTS 0 -#define RETURN_VALUE 1 - -/* The various argument relocations that may be performed. */ -typedef enum -{ - /* No relocation. */ - NO, - /* Relocate 32 bits from GR to FP register. */ - GF, - /* Relocate 64 bits from a GR pair to FP pair. */ - GD, - /* Relocate 32 bits from FP to GR. */ - FG, - /* Relocate 64 bits from FP pair to GR pair. */ - DG, -} arg_reloc_type; - -/* What is being relocated (eg which argument or the return value). */ -typedef enum -{ - ARG0, ARG1, ARG2, ARG3, RET, -} arg_reloc_location; - - -/* ELF32/HPPA relocation support - - This file contains ELF32/HPPA relocation support as specified - in the Stratus FTX/Golf Object File Format (SED-1762) dated - February 1994. */ - -#include "elf32-hppa.h" -#include "hppa_stubs.h" - -static bfd_reloc_status_type hppa_elf_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - -static unsigned long hppa_elf_relocate_insn - PARAMS ((bfd *, asection *, unsigned long, unsigned long, long, - long, unsigned long, unsigned long, unsigned long)); - -static bfd_reloc_status_type hppa_elf_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd*, char **)); - -static reloc_howto_type * elf_hppa_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); - -static boolean elf32_hppa_set_section_contents - PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); - -static void elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); - -static boolean elf32_hppa_backend_symbol_table_processing - PARAMS ((bfd *, elf_symbol_type *, unsigned int)); - -static void elf32_hppa_backend_begin_write_processing - PARAMS ((bfd *, struct bfd_link_info *)); - -static void elf32_hppa_backend_final_write_processing - PARAMS ((bfd *, boolean)); - -static void add_entry_to_symext_chain - PARAMS ((bfd *, unsigned int, unsigned int, symext_chainS **, - symext_chainS **)); - -static void -elf_hppa_tc_make_sections PARAMS ((bfd *, symext_chainS *)); - -static boolean hppa_elf_is_local_label PARAMS ((bfd *, asymbol *)); - -static boolean elf32_hppa_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); - -static bfd_reloc_status_type elf32_hppa_bfd_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, - bfd_byte *, bfd_vma, bfd_vma, bfd_vma, struct bfd_link_info *, - asection *, const char *, int)); - -static struct bfd_link_hash_table *elf32_hppa_link_hash_table_create - PARAMS ((bfd *)); - -static struct bfd_hash_entry * -elf32_hppa_stub_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); - -static struct bfd_hash_entry * -elf32_hppa_args_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); - -static boolean -elf32_hppa_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); - -static boolean -elf32_hppa_stub_hash_table_init - PARAMS ((struct elf32_hppa_stub_hash_table *, bfd *, - struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)))); - -static boolean -elf32_hppa_build_one_stub PARAMS ((struct bfd_hash_entry *, PTR)); - -static boolean -elf32_hppa_read_symext_info - PARAMS ((bfd *, Elf_Internal_Shdr *, struct elf32_hppa_args_hash_table *, - Elf_Internal_Sym *)); - -static unsigned int elf32_hppa_size_of_stub - PARAMS ((unsigned int, unsigned int, bfd_vma, bfd_vma, const char *)); - -static boolean elf32_hppa_arg_reloc_needed - PARAMS ((unsigned int, unsigned int, arg_reloc_type [])); - -static void elf32_hppa_name_of_stub - PARAMS ((unsigned int, unsigned int, bfd_vma, bfd_vma, char *)); - -static boolean elf32_hppa_size_symext PARAMS ((struct bfd_hash_entry *, PTR)); - -static boolean elf32_hppa_link_output_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const char *, - Elf_Internal_Sym *, asection *)); - -/* ELF/PA relocation howto entries. */ - -static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = -{ - {R_PARISC_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_NONE"}, - {R_PARISC_DIR32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR32"}, - {R_PARISC_DIR21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR21L"}, - {R_PARISC_DIR17R, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17R"}, - {R_PARISC_DIR17F, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17F"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DIR14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR14R"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PCREL21L, 0, 0, 21, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL21L"}, - {R_PARISC_PCREL17R, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17R"}, - {R_PARISC_PCREL17F, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17F"}, - {R_PARISC_PCREL17C, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17C"}, - {R_PARISC_PCREL14R, 0, 0, 14, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL14R"}, - {R_PARISC_PCREL14F, 0, 0, 14, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DPREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DPREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL14R"}, - {R_PARISC_DPREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL14R"}, - {R_PARISC_DLTREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTIND21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTIND14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND14R"}, - {R_PARISC_DLTIND14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND14F"}, - - {R_PARISC_SETBASE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_SETBASE"}, - {R_PARISC_BASEREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL32"}, - {R_PARISC_BASEREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL21L"}, - {R_PARISC_BASEREL17R, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL17R"}, - {R_PARISC_BASEREL17F, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL17F"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_BASEREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL14R"}, - {R_PARISC_BASEREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_TEXTREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_TEXTREL32"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DATAREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLABEL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL32"}, - {R_PARISC_PLABEL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLABEL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL14R"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLTIND21L, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLTIND14R, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND14R"}, - {R_PARISC_PLTIND14F, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND14F"}, - - - {R_PARISC_COPY, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_COPY"}, - {R_PARISC_GLOB_DAT, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_GLOB_DAT"}, - {R_PARISC_JMP_SLOT, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_JMP_SLOT"}, - {R_PARISC_RELATIVE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_RELATIVE"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"}, -}; - -/* Where (what register type) is an argument comming from? */ -typedef enum -{ - AR_NO, - AR_GR, - AR_FR, - AR_FU, - AR_FPDBL1, - AR_FPDBL2, -} arg_location; - -/* Horizontal represents the callee's argument location information, - vertical represents caller's argument location information. Value at a - particular X,Y location represents what (if any) argument relocation - needs to be performed to make caller and callee agree. */ - -static CONST arg_reloc_type arg_mismatches[6][6] = -{ - {NO, NO, NO, NO, NO, NO}, - {NO, NO, GF, NO, GD, NO}, - {NO, FG, NO, NO, NO, NO}, - {NO, NO, NO, NO, NO, NO}, - {NO, DG, NO, NO, NO, NO}, - {NO, DG, NO, NO, NO, NO}, -}; - -/* Likewise, but reversed for the return value. */ -static CONST arg_reloc_type ret_mismatches[6][6] = -{ - {NO, NO, NO, NO, NO, NO}, - {NO, NO, FG, NO, DG, NO}, - {NO, GF, NO, NO, NO, NO}, - {NO, NO, NO, NO, NO, NO}, - {NO, GD, NO, NO, NO, NO}, - {NO, GD, NO, NO, NO, NO}, -}; - -/* Misc static crud for symbol extension records. */ -static symext_chainS *symext_rootP; -static symext_chainS *symext_lastP; -static bfd_size_type symext_chain_size; - -/* FIXME: We should be able to try this static variable! */ -static bfd_byte *symextn_contents; - - -/* For linker stub hash tables. */ -#define elf32_hppa_stub_hash_lookup(table, string, create, copy) \ - ((struct elf32_hppa_stub_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -#define elf32_hppa_stub_hash_traverse(table, func, info) \ - (bfd_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ - (info))) - -/* For linker args hash tables. */ -#define elf32_hppa_args_hash_lookup(table, string, create, copy) \ - ((struct elf32_hppa_args_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -#define elf32_hppa_args_hash_traverse(table, func, info) \ - (bfd_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ - (info))) - -#define elf32_hppa_args_hash_table_init(table, newfunc) \ - (bfd_hash_table_init \ - (&(table)->root, \ - (struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *, \ - struct bfd_hash_table *, \ - const char *))) (newfunc))) - -/* For HPPA linker hash table. */ - -#define elf32_hppa_link_hash_lookup(table, string, create, copy, follow)\ - ((struct elf32_hppa_link_hash_entry *) \ - elf_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -#define elf32_hppa_link_hash_traverse(table, func, info) \ - (elf_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the PA ELF linker hash table from a link_info structure. */ - -#define elf32_hppa_hash_table(p) \ - ((struct elf32_hppa_link_hash_table *) ((p)->hash)) - - -/* Extract specific argument location bits for WHICH from - the full argument location in AR. */ -#define EXTRACT_ARBITS(ar, which) ((ar) >> (8 - ((which) * 2))) & 3 - -/* Assorted hash table functions. */ - -/* Initialize an entry in the stub hash table. */ - -static struct bfd_hash_entry * -elf32_hppa_stub_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct elf32_hppa_stub_hash_entry *ret; - - ret = (struct elf32_hppa_stub_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = ((struct elf32_hppa_stub_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf32_hppa_stub_hash_entry))); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct elf32_hppa_stub_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->offset = 0; - ret->target_value = 0; - ret->target_section = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a stub hash table. */ - -static boolean -elf32_hppa_stub_hash_table_init (table, stub_bfd, newfunc) - struct elf32_hppa_stub_hash_table *table; - bfd *stub_bfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - table->offset = 0; - table->location = 0; - table->stub_bfd = stub_bfd; - return (bfd_hash_table_init (&table->root, newfunc)); -} - -/* Initialize an entry in the argument location hash table. */ - -static struct bfd_hash_entry * -elf32_hppa_args_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct elf32_hppa_args_hash_entry *ret; - - ret = (struct elf32_hppa_args_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = ((struct elf32_hppa_args_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf32_hppa_args_hash_entry))); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct elf32_hppa_args_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - /* Initialize the local fields. */ - if (ret) - ret->arg_bits = 0; - - return (struct bfd_hash_entry *) ret; -} - -/* Create the derived linker hash table. The PA ELF port uses the derived - hash table to keep information specific to the PA ELF linker (without - using static variables). */ - -static struct bfd_link_hash_table * -elf32_hppa_link_hash_table_create (abfd) - bfd *abfd; -{ - struct elf32_hppa_link_hash_table *ret; - - ret = ((struct elf32_hppa_link_hash_table *) - bfd_alloc (abfd, sizeof (struct elf32_hppa_link_hash_table))); - if (ret == NULL) - return NULL; - if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, - _bfd_elf_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return NULL; - } - ret->stub_hash_table = NULL; - ret->args_hash_table = NULL; - ret->output_symbol_count = 0; - ret->global_value = 0; - ret->global_sym_defined = 0; - - return &ret->root.root; -} - -/* Relocate the given INSN given the various input parameters. - - FIXME: endianness and sizeof (long) issues abound here. */ - -static unsigned long -hppa_elf_relocate_insn (abfd, input_sect, insn, address, sym_value, - r_addend, r_format, r_field, pcrel) - bfd *abfd; - asection *input_sect; - unsigned long insn; - unsigned long address; - long sym_value; - long r_addend; - unsigned long r_format; - unsigned long r_field; - unsigned long pcrel; -{ - unsigned char opcode = get_opcode (insn); - long constant_value; - - switch (opcode) - { - case LDO: - case LDB: - case LDH: - case LDW: - case LDWM: - case STB: - case STH: - case STW: - case STWM: - case COMICLR: - case SUBI: - case ADDIT: - case ADDI: - case LDIL: - case ADDIL: - constant_value = HPPA_R_CONSTANT (r_addend); - - if (pcrel) - sym_value -= address; - - sym_value = hppa_field_adjust (sym_value, constant_value, r_field); - return hppa_rebuild_insn (abfd, insn, sym_value, r_format); - - case BL: - case BE: - case BLE: - /* XXX computing constant_value is not needed??? */ - constant_value = assemble_17 ((insn & 0x001f0000) >> 16, - (insn & 0x00001ffc) >> 2, - insn & 1); - - constant_value = (constant_value << 15) >> 15; - if (pcrel) - { - sym_value -= - address + input_sect->output_offset - + input_sect->output_section->vma; - sym_value = hppa_field_adjust (sym_value, -8, r_field); - } - else - sym_value = hppa_field_adjust (sym_value, constant_value, r_field); - - return hppa_rebuild_insn (abfd, insn, sym_value >> 2, r_format); - - default: - if (opcode == 0) - { - constant_value = HPPA_R_CONSTANT (r_addend); - - if (pcrel) - sym_value -= address; - - return hppa_field_adjust (sym_value, constant_value, r_field); - } - else - abort (); - } -} - -/* Relocate an HPPA ELF section. */ - -static boolean -elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sym_sec; - bfd_vma relocation; - bfd_reloc_status_type r; - const char *sym_name; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = elf_hppa_howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sym_sec = local_sections[r_symndx]; - rel->r_addend += sym_sec->output_offset; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sym_sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sym_sec = local_sections[r_symndx]; - relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION - ? 0 : sym->st_value) - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else - { - long indx; - - indx = r_symndx - symtab_hdr->sh_info; - h = elf_sym_hashes (input_bfd)[indx]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sym_sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else - { - if (!((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - break; - } - } - - if (h != NULL) - sym_name = h->root.root.string; - else - { - sym_name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (sym_name == NULL) - return false; - if (*sym_name == '\0') - sym_name = bfd_section_name (input_bfd, sym_sec); - } - - /* If args_hash_table is NULL, then we have encountered some - kind of link error (ex. undefined symbols). Do not try to - apply any relocations, continue the loop so we can notify - the user of several errors in a single attempted link. */ - if (elf32_hppa_hash_table (info)->args_hash_table == NULL) - continue; - - r = elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd, - input_section, contents, - rel->r_offset, relocation, - rel->r_addend, info, sym_sec, - sym_name, h == NULL); - - if (r != bfd_reloc_ok) - { - switch (r) - { - /* This can happen for DP relative relocs if $global$ is - undefined. This is a panic situation so we don't try - to continue. */ - case bfd_reloc_undefined: - case bfd_reloc_notsupported: - if (!((*info->callbacks->undefined_symbol) - (info, "$global$", input_bfd, - input_section, rel->r_offset))) - return false; - return false; - case bfd_reloc_dangerous: - { - /* We use this return value to indicate that we performed - a "dangerous" relocation. This doesn't mean we did - the wrong thing, it just means there may be some cleanup - that needs to be done here. - - In particular we had to swap the last call insn and its - delay slot. If the delay slot insn needed a relocation, - then we'll need to adjust the next relocation entry's - offset to account for the fact that the insn moved. - - This hair wouldn't be necessary if we inserted stubs - between procedures and used a "bl" to get to the stub. */ - if (rel != relend) - { - Elf_Internal_Rela *next_rel = rel + 1; - - if (rel->r_offset + 4 == next_rel->r_offset) - next_rel->r_offset -= 4; - } - break; - } - default: - case bfd_reloc_outofrange: - case bfd_reloc_overflow: - { - if (!((*info->callbacks->reloc_overflow) - (info, sym_name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Return one (or more) BFD relocations which implement the base - relocation with modifications based on format and field. */ - -elf32_hppa_reloc_type ** -hppa_elf_gen_reloc_type (abfd, base_type, format, field, ignore) - bfd *abfd; - elf32_hppa_reloc_type base_type; - int format; - int field; - int ignore; -{ - elf32_hppa_reloc_type *finaltype; - elf32_hppa_reloc_type **final_types; - - /* Allocate slots for the BFD relocation. */ - final_types = (elf32_hppa_reloc_type **) - bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2); - if (final_types == NULL) - return NULL; - - /* Allocate space for the relocation itself. */ - finaltype = (elf32_hppa_reloc_type *) - bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type)); - if (finaltype == NULL) - return NULL; - - /* Some reasonable defaults. */ - final_types[0] = finaltype; - final_types[1] = NULL; - -#define final_type finaltype[0] - - final_type = base_type; - - /* Just a tangle of nested switch statements to deal with the braindamage - that a different field selector means a completely different relocation - for PA ELF. */ - switch (base_type) - { - case R_HPPA: - case R_HPPA_ABS_CALL: - switch (format) - { - case 14: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_DIR14R; - break; - case e_rtsel: - final_type = R_PARISC_DLTREL14R; - break; - case e_tsel: - final_type = R_PARISC_DLTREL14F; - break; - case e_rpsel: - final_type = R_PARISC_PLABEL14R; - break; - default: - return NULL; - } - break; - - case 17: - switch (field) - { - case e_fsel: - final_type = R_PARISC_DIR17F; - break; - case e_rsel: - case e_rrsel: - final_type = R_PARISC_DIR17R; - break; - default: - return NULL; - } - break; - - case 21: - switch (field) - { - case e_lsel: - case e_lrsel: - final_type = R_PARISC_DIR21L; - break; - case e_ltsel: - final_type = R_PARISC_DLTREL21L; - break; - case e_lpsel: - final_type = R_PARISC_PLABEL21L; - break; - default: - return NULL; - } - break; - - case 32: - switch (field) - { - case e_fsel: - final_type = R_PARISC_DIR32; - break; - case e_psel: - final_type = R_PARISC_PLABEL32; - break; - default: - return NULL; - } - break; - - default: - return NULL; - } - break; - - - case R_HPPA_GOTOFF: - switch (format) - { - case 14: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_DPREL14R; - break; - case e_fsel: - final_type = R_PARISC_DPREL14F; - break; - default: - return NULL; - } - break; - - case 21: - switch (field) - { - case e_lrsel: - case e_lsel: - final_type = R_PARISC_DPREL21L; - break; - default: - return NULL; - } - break; - - default: - return NULL; - } - break; - - - case R_HPPA_PCREL_CALL: - switch (format) - { - case 14: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_PCREL14R; - break; - case e_fsel: - final_type = R_PARISC_PCREL14F; - break; - default: - return NULL; - } - break; - - case 17: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_PCREL17R; - break; - case e_fsel: - final_type = R_PARISC_PCREL17F; - break; - default: - return NULL; - } - break; - - case 21: - switch (field) - { - case e_lsel: - case e_lrsel: - final_type = R_PARISC_PCREL21L; - break; - default: - return NULL; - } - break; - - default: - return NULL; - } - break; - - default: - return NULL; - } - - return final_types; -} - -#undef final_type - -/* Set the contents of a particular section at a particular location. */ - -static boolean -elf32_hppa_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - /* Ignore write requests for the symbol extension section until we've - had the chance to rebuild it ourselves. */ - if (!strcmp (section->name, ".PARISC.symextn") && !symext_chain_size) - return true; - else - return _bfd_elf_set_section_contents (abfd, section, location, - offset, count); -} - -/* Translate from an elf into field into a howto relocation pointer. */ - -static void -elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_PARISC_UNIMPLEMENTED); - cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE (dst->r_info)]; -} - - -/* Actually perform a relocation. NOTE this is (mostly) superceeded - by elf32_hppa_bfd_final_link_relocate which is called by the new - fast linker. */ - -static bfd_reloc_status_type -hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* It is no longer valid to call hppa_elf_reloc when creating - a final executable. */ - if (output_bfd) - { - reloc_entry->address += input_section->output_offset; - - /* Work around lossage in generic elf code to write relocations. - (maps different section symbols into the same symbol index). */ - if ((symbol_in->flags & BSF_SECTION_SYM) - && symbol_in->section) - reloc_entry->addend += symbol_in->section->output_offset; - return bfd_reloc_ok; - } - else - { - *error_message = (char *) "Unsupported call to hppa_elf_reloc"; - return bfd_reloc_notsupported; - } -} - -/* Actually perform a relocation as part of a final link. This can get - rather hairy when linker stubs are needed. */ - -static bfd_reloc_status_type -elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd, - input_section, contents, offset, value, - addend, info, sym_sec, sym_name, is_local) - reloc_howto_type *howto; - bfd *input_bfd; - bfd *output_bfd; - asection *input_section; - bfd_byte *contents; - bfd_vma offset; - bfd_vma value; - bfd_vma addend; - struct bfd_link_info *info; - asection *sym_sec; - const char *sym_name; - int is_local; -{ - unsigned long insn; - unsigned long r_type = howto->type; - unsigned long r_format = howto->bitsize; - unsigned long r_field = e_fsel; - bfd_byte *hit_data = contents + offset; - boolean r_pcrel = howto->pc_relative; - - insn = bfd_get_32 (input_bfd, hit_data); - - /* Make sure we have a value for $global$. FIXME isn't this effectively - just like the gp pointer on MIPS? Can we use those routines for this - purpose? */ - if (!elf32_hppa_hash_table (info)->global_sym_defined) - { - struct elf_link_hash_entry *h; - asection *sec; - - h = elf_link_hash_lookup (elf_hash_table (info), "$global$", false, - false, false); - - /* If there isn't a $global$, then we're in deep trouble. */ - if (h == NULL) - return bfd_reloc_notsupported; - - /* If $global$ isn't a defined symbol, then we're still in deep - trouble. */ - if (h->root.type != bfd_link_hash_defined) - return bfd_reloc_undefined; - - sec = h->root.u.def.section; - elf32_hppa_hash_table (info)->global_value = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - elf32_hppa_hash_table (info)->global_sym_defined = 1; - } - - switch (r_type) - { - case R_PARISC_NONE: - break; - - case R_PARISC_DIR32: - case R_PARISC_DIR17F: - case R_PARISC_PCREL17C: - r_field = e_fsel; - goto do_basic_type_1; - case R_PARISC_DIR21L: - case R_PARISC_PCREL21L: - r_field = e_lrsel; - goto do_basic_type_1; - case R_PARISC_DIR17R: - case R_PARISC_PCREL17R: - case R_PARISC_DIR14R: - case R_PARISC_PCREL14R: - r_field = e_rrsel; - goto do_basic_type_1; - - /* For all the DP relative relocations, we need to examine the symbol's - section. If it's a code section, then "data pointer relative" makes - no sense. In that case we don't adjust the "value", and for 21 bit - addil instructions, we change the source addend register from %dp to - %r0. */ - case R_PARISC_DPREL21L: - r_field = e_lrsel; - if (sym_sec->flags & SEC_CODE) - { - if ((insn & 0xfc000000) >> 26 == 0xa - && (insn & 0x03e00000) >> 21 == 0x1b) - insn &= ~0x03e00000; - } - else - value -= elf32_hppa_hash_table (info)->global_value; - goto do_basic_type_1; - case R_PARISC_DPREL14R: - r_field = e_rrsel; - if ((sym_sec->flags & SEC_CODE) == 0) - value -= elf32_hppa_hash_table (info)->global_value; - goto do_basic_type_1; - case R_PARISC_DPREL14F: - r_field = e_fsel; - if ((sym_sec->flags & SEC_CODE) == 0) - value -= elf32_hppa_hash_table (info)->global_value; - goto do_basic_type_1; - - /* These cases are separate as they may involve a lot more work - to deal with linker stubs. */ - case R_PARISC_PLABEL32: - case R_PARISC_PLABEL21L: - case R_PARISC_PLABEL14R: - case R_PARISC_PCREL17F: - { - bfd_vma location; - unsigned int len, caller_args, callee_args; - arg_reloc_type arg_reloc_types[5]; - struct elf32_hppa_args_hash_table *args_hash_table; - struct elf32_hppa_args_hash_entry *args_hash; - char *new_name, *stub_name; - - /* Get the field selector right. We'll need it in a minute. */ - if (r_type == R_PARISC_PCREL17F - || r_type == R_PARISC_PLABEL32) - r_field = e_fsel; - else if (r_type == R_PARISC_PLABEL21L) - r_field = e_lrsel; - else if (r_type == R_PARISC_PLABEL14R) - r_field = e_rrsel; - - /* Find out where we are and where we're going. */ - location = (offset + - input_section->output_offset + - input_section->output_section->vma); - - /* Now look for the argument relocation bits associated with the - target. */ - len = strlen (sym_name) + 1; - if (is_local) - len += 9; - new_name = bfd_malloc (len); - if (!new_name) - return bfd_reloc_notsupported; - strcpy (new_name, sym_name); - - /* Local symbols have unique IDs. */ - if (is_local) - sprintf (new_name + len - 10, "_%08x", (int)sym_sec); - - args_hash_table = elf32_hppa_hash_table (info)->args_hash_table; - - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - new_name, false, false); - if (args_hash == NULL) - callee_args = 0; - else - callee_args = args_hash->arg_bits; - - /* If this is a CALL relocation, then get the caller's bits - from the addend. Else use the magic 0x155 value for PLABELS. - - Also we don't care about the destination (value) for PLABELS. */ - if (r_type == R_PARISC_PCREL17F) - caller_args = HPPA_R_ARG_RELOC (addend); - else - { - caller_args = 0x155; - location = value; - } - - /* Any kind of linker stub needed? */ - if (((int)(value - location) > 0x3ffff) - || ((int)(value - location) < (int)0xfffc0000) - || elf32_hppa_arg_reloc_needed (caller_args, callee_args, - arg_reloc_types)) - { - struct elf32_hppa_stub_hash_table *stub_hash_table; - struct elf32_hppa_stub_hash_entry *stub_hash; - asection *stub_section; - - /* Build a name for the stub. */ - - len = strlen (new_name); - len += 23; - stub_name = bfd_malloc (len); - if (!stub_name) - return bfd_reloc_notsupported; - elf32_hppa_name_of_stub (caller_args, callee_args, - location, value, stub_name); - strcat (stub_name, new_name); - free (new_name); - - stub_hash_table = elf32_hppa_hash_table (info)->stub_hash_table; - - stub_hash - = elf32_hppa_stub_hash_lookup (stub_hash_table, stub_name, - false, false); - - /* We're done with that name. */ - free (stub_name); - - /* The stub BFD only has one section. */ - stub_section = stub_hash_table->stub_bfd->sections; - - if (stub_hash != NULL) - { - - if (r_type == R_PARISC_PCREL17F) - { - unsigned long delay_insn; - unsigned int opcode, rtn_reg, ldo_target_reg, ldo_src_reg; - - /* We'll need to peek at the next insn. */ - delay_insn = bfd_get_32 (input_bfd, hit_data + 4); - opcode = get_opcode (delay_insn); - - /* We also need to know the return register for this - call. */ - rtn_reg = (insn & 0x03e00000) >> 21; - - ldo_src_reg = (delay_insn & 0x03e00000) >> 21; - ldo_target_reg = (delay_insn & 0x001f0000) >> 16; - - /* Munge up the value and other parameters for - hppa_elf_relocate_insn. */ - - value = (stub_hash->offset - + stub_section->output_offset - + stub_section->output_section->vma); - - r_format = 17; - r_field = e_fsel; - r_pcrel = 0; - addend = 0; - - /* We need to peek at the delay insn and determine if - we'll need to swap the branch and its delay insn. */ - if ((insn & 2) - || (opcode == LDO - && ldo_target_reg == rtn_reg) - || (delay_insn == 0x08000240)) - { - /* No need to swap the branch and its delay slot, but - we do need to make sure to jump past the return - pointer update in the stub. */ - value += 4; - - /* If the delay insn does a return pointer adjustment, - then we have to make sure it stays valid. */ - if (opcode == LDO - && ldo_target_reg == rtn_reg) - { - delay_insn &= 0xfc00ffff; - delay_insn |= ((31 << 21) | (31 << 16)); - bfd_put_32 (input_bfd, delay_insn, hit_data + 4); - } - /* Use a BLE to reach the stub. */ - insn = BLE_SR4_R0; - } - else - { - /* Wonderful, we have to swap the call insn and its - delay slot. */ - bfd_put_32 (input_bfd, delay_insn, hit_data); - /* Use a BLE,n to reach the stub. */ - insn = (BLE_SR4_R0 | 0x2); - bfd_put_32 (input_bfd, insn, hit_data + 4); - insn = hppa_elf_relocate_insn (input_bfd, - input_section, - insn, offset + 4, - value, addend, - r_format, r_field, - r_pcrel); - /* Update the instruction word. */ - bfd_put_32 (input_bfd, insn, hit_data + 4); - return bfd_reloc_dangerous; - } - } - else - { - /* PLABEL stuff is easy. */ - - value = (stub_hash->offset - + stub_section->output_offset - + stub_section->output_section->vma); - /* We don't need the RP adjustment for PLABELs. */ - value += 4; - if (r_type == R_PARISC_PLABEL32) - r_format = 32; - else if (r_type == R_PARISC_PLABEL21L) - r_format = 21; - else if (r_type == R_PARISC_PLABEL14R) - r_format = 14; - - r_pcrel = 0; - addend = 0; - } - } - else - return bfd_reloc_notsupported; - } - goto do_basic_type_1; - } - -do_basic_type_1: - insn = hppa_elf_relocate_insn (input_bfd, input_section, insn, - offset, value, addend, r_format, - r_field, r_pcrel); - break; - - /* Something we don't know how to handle. */ - default: - return bfd_reloc_notsupported; - } - - /* Update the instruction word. */ - bfd_put_32 (input_bfd, insn, hit_data); - return (bfd_reloc_ok); -} - -/* Return the address of the howto table entry to perform the CODE - relocation for an ARCH machine. */ - -static reloc_howto_type * -elf_hppa_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - if ((int) code < (int) R_PARISC_UNIMPLEMENTED) - { - BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code); - return &elf_hppa_howto_table[(int) code]; - } - return NULL; -} - -/* Return true if SYM represents a local label symbol. */ - -static boolean -hppa_elf_is_local_label (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return (sym->name[0] == 'L' && sym->name[1] == '$'); -} - -/* Do any backend specific processing when beginning to write an object - file. For PA ELF we need to determine the size of the symbol extension - section *before* any other output processing happens. */ - -static void -elf32_hppa_backend_begin_write_processing (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - unsigned int i; - asection *symextn_sec; - - /* Size up the symbol extension section. */ - if ((abfd->outsymbols == NULL - && info == NULL) - || symext_chain_size != 0) - return; - - if (info == NULL) - { - /* We were not called from the BFD ELF linker code, so we need - to examine the output BFD's outsymbols. - - Note we can not build the symbol extensions now as the symbol - map hasn't been set up. */ - for (i = 0; i < abfd->symcount; i++) - { - elf_symbol_type *symbol = (elf_symbol_type *)abfd->outsymbols[i]; - - /* Only functions ever need an entry in the symbol extension - section. */ - if (!(symbol->symbol.flags & BSF_FUNCTION)) - continue; - - /* And only if they specify the locations of their arguments. */ - if (symbol->tc_data.hppa_arg_reloc == 0) - continue; - - /* Yup. This function symbol needs an entry. */ - symext_chain_size += 2 * ELF32_PARISC_SX_SIZE; - } - } - else if (info->relocateable == true) - { - struct elf32_hppa_args_hash_table *table; - table = elf32_hppa_hash_table (info)->args_hash_table; - - /* Determine the size of the symbol extension section. */ - elf32_hppa_args_hash_traverse (table, - elf32_hppa_size_symext, - &symext_chain_size); - } - - /* Now create the section and set its size. We'll fill in the - contents later. */ - symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME); - if (symextn_sec == NULL) - symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME); - - bfd_set_section_flags (abfd, symextn_sec, - SEC_LOAD | SEC_HAS_CONTENTS | SEC_DATA); - symextn_sec->output_section = symextn_sec; - symextn_sec->output_offset = 0; - bfd_set_section_alignment (abfd, symextn_sec, 2); - bfd_set_section_size (abfd, symextn_sec, symext_chain_size); -} - -/* Called for each entry in the args location hash table. For each - entry we bump the size pointer by 2 records (16 bytes). */ - -static boolean -elf32_hppa_size_symext (gen_entry, in_args) - struct bfd_hash_entry *gen_entry; - PTR in_args; -{ - bfd_size_type *sizep = (bfd_size_type *)in_args; - - *sizep += 2 * ELF32_PARISC_SX_SIZE; - return true; -} - -/* Backend routine called by the linker for each output symbol. - - For PA ELF we use this opportunity to add an appropriate entry - to the symbol extension chain for function symbols. */ - -static boolean -elf32_hppa_link_output_symbol_hook (abfd, info, name, sym, section) - bfd *abfd; - struct bfd_link_info *info; - const char *name; - Elf_Internal_Sym *sym; - asection *section; -{ - char *new_name; - unsigned int len, index; - struct elf32_hppa_args_hash_table *args_hash_table; - struct elf32_hppa_args_hash_entry *args_hash; - - /* If the args hash table is NULL, then we've encountered an error - of some sorts (for example, an undefined symbol). In that case - we've got nothing else to do. - - NOTE: elf_link_output_symbol will abort if we return false here! */ - if (elf32_hppa_hash_table (info)->args_hash_table == NULL) - return true; - - index = elf32_hppa_hash_table (info)->output_symbol_count++; - - /* We need to look up this symbol in the args hash table to see if - it has argument relocation bits. */ - if (ELF_ST_TYPE (sym->st_info) != STT_FUNC) - return true; - - /* We know it's a function symbol of some kind. */ - len = strlen (name) + 1; - if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) - len += 9; - - new_name = bfd_malloc (len); - if (new_name == NULL) - return false; - - strcpy (new_name, name); - if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) - sprintf (new_name + len - 10, "_%08x", (int)section); - - /* Now that we have the unique name, we can look it up in the - args hash table. */ - args_hash_table = elf32_hppa_hash_table (info)->args_hash_table; - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, new_name, - false, false); - free (new_name); - if (args_hash == NULL) - return true; - - /* We know this symbol has arg reloc bits. */ - add_entry_to_symext_chain (abfd, args_hash->arg_bits, - index, &symext_rootP, &symext_lastP); - return true; -} - -/* Perform any processing needed late in the object file writing process. - For PA ELF we build and set the contents of the symbol extension - section. */ - -static void -elf32_hppa_backend_final_write_processing (abfd, linker) - bfd *abfd; - boolean linker; -{ - asection *symextn_sec; - unsigned int i; - - /* Now build the symbol extension section. */ - if (symext_chain_size == 0) - return; - - if (! linker) - { - /* We were not called from the backend linker, so we still need - to build the symbol extension chain. - - Look at each symbol, adding the appropriate information to the - symbol extension section list as necessary. */ - for (i = 0; i < abfd->symcount; i++) - { - elf_symbol_type *symbol = (elf_symbol_type *) abfd->outsymbols[i]; - - /* Only functions ever need an entry in the symbol extension - section. */ - if (!(symbol->symbol.flags & BSF_FUNCTION)) - continue; - - /* And only if they specify the locations of their arguments. */ - if (symbol->tc_data.hppa_arg_reloc == 0) - continue; - - /* Add this symbol's information to the chain. */ - add_entry_to_symext_chain (abfd, symbol->tc_data.hppa_arg_reloc, - symbol->symbol.udata.i, &symext_rootP, - &symext_lastP); - } - } - - /* Now fill in the contents of the symbol extension section. */ - elf_hppa_tc_make_sections (abfd, symext_rootP); - - /* And attach that as the section's contents. */ - symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME); - if (symextn_sec == (asection *) 0) - abort(); - - symextn_sec->contents = (void *)symextn_contents; - - bfd_set_section_contents (abfd, symextn_sec, symextn_sec->contents, - symextn_sec->output_offset, symextn_sec->_raw_size); -} - -/* Update the symbol extention chain to include the symbol pointed to - by SYMBOLP if SYMBOLP is a function symbol. Used internally and by GAS. */ - -static void -add_entry_to_symext_chain (abfd, arg_reloc, sym_idx, symext_root, symext_last) - bfd *abfd; - unsigned int arg_reloc; - unsigned int sym_idx; - symext_chainS **symext_root; - symext_chainS **symext_last; -{ - symext_chainS *symextP; - - /* Allocate memory and initialize this entry. */ - symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2); - if (!symextP) - abort(); /* FIXME */ - - symextP[0].entry = ELF32_PARISC_SX_WORD (PARISC_SXT_SYMNDX, sym_idx); - symextP[0].next = &symextP[1]; - - symextP[1].entry = ELF32_PARISC_SX_WORD (PARISC_SXT_ARG_RELOC, arg_reloc); - symextP[1].next = NULL; - - /* Now update the chain itself so it can be walked later to build - the symbol extension section. */ - if (*symext_root == NULL) - { - *symext_root = &symextP[0]; - *symext_last = &symextP[1]; - } - else - { - (*symext_last)->next = &symextP[0]; - *symext_last = &symextP[1]; - } -} - -/* Build the symbol extension section. */ - -static void -elf_hppa_tc_make_sections (abfd, symext_root) - bfd *abfd; - symext_chainS *symext_root; -{ - symext_chainS *symextP; - unsigned int i; - asection *symextn_sec; - - symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME); - - /* Grab some memory for the contents of the symbol extension section - itself. */ - symextn_contents = (bfd_byte *) bfd_zalloc (abfd, - symextn_sec->_raw_size); - if (!symextn_contents) - abort(); /* FIXME */ - - /* Fill in the contents of the symbol extension chain. */ - for (i = 0, symextP = symext_root; symextP; symextP = symextP->next, ++i) - ELF32_PARISC_SX_PUT (abfd, (bfd_vma) symextP->entry, - symextn_contents + i * ELF32_PARISC_SX_SIZE); - - return; -} - -/* Do some PA ELF specific work after reading in the symbol table. - In particular attach the argument relocation from the - symbol extension section to the appropriate symbols. */ - -static boolean -elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt) - bfd *abfd; - elf_symbol_type *esyms; - unsigned int symcnt; -{ - Elf32_Internal_Shdr *symextn_hdr = - bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME); - unsigned int i, current_sym_idx = 0; - - /* If no symbol extension existed, then all symbol extension information - is assumed to be zero. */ - if (symextn_hdr == NULL) - { - for (i = 0; i < symcnt; i++) - esyms[i].tc_data.hppa_arg_reloc = 0; - return (true); - } - - /* FIXME: Why not use bfd_get_section_contents here? Also should give - memory back when we're done. */ - /* Allocate a buffer of the appropriate size for the symextn section. */ - symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size); - if (!symextn_hdr->contents) - return false; - - /* Read in the symextn section. */ - if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1) - return false; - if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->sh_size, abfd) - != symextn_hdr->sh_size) - return false; - - /* Parse entries in the symbol extension section, updating the symtab - entries as we go */ - for (i = 0; i < symextn_hdr->sh_size / ELF32_PARISC_SX_SIZE; i++) - { - symext_entryS se = - ELF32_PARISC_SX_GET (abfd, - ((unsigned char *)symextn_hdr->contents - + i * ELF32_PARISC_SX_SIZE)); - unsigned int se_value = ELF32_PARISC_SX_VAL (se); - unsigned int se_type = ELF32_PARISC_SX_TYPE (se); - - switch (se_type) - { - case PARISC_SXT_NULL: - break; - - case PARISC_SXT_SYMNDX: - if (se_value >= symcnt) - { - bfd_set_error (bfd_error_bad_value); - return (false); - } - current_sym_idx = se_value - 1; - break; - - case PARISC_SXT_ARG_RELOC: - esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value; - break; - - default: - bfd_set_error (bfd_error_bad_value); - return (false); - } - } - return (true); -} - -/* Read and attach the symbol extension information for the symbols - in INPUT_BFD to the argument location hash table. Handle locals - if DO_LOCALS is true; likewise for globals when DO_GLOBALS is true. */ - -static boolean -elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table, local_syms) - bfd *input_bfd; - Elf_Internal_Shdr *symtab_hdr; - struct elf32_hppa_args_hash_table *args_hash_table; - Elf_Internal_Sym *local_syms; -{ - asection *symextn_sec; - bfd_byte *contents; - unsigned int i, n_entries, current_index = 0; - - /* Get the symbol extension section for this BFD. If no section exists - then there's nothing to do. Likewise if the section exists, but - has no contents. */ - symextn_sec = bfd_get_section_by_name (input_bfd, SYMEXTN_SECTION_NAME); - if (symextn_sec == NULL) - return true; - - /* Done separately so we can turn off SEC_HAS_CONTENTS (see below). */ - if (symextn_sec->_raw_size == 0) - { - symextn_sec->flags &= ~SEC_HAS_CONTENTS; - return true; - } - - contents = (bfd_byte *) bfd_malloc ((size_t) symextn_sec->_raw_size); - if (contents == NULL) - return false; - - /* How gross. We turn off SEC_HAS_CONTENTS for the input symbol extension - sections to keep the generic ELF/BFD code from trying to do anything - with them. We have to undo that hack temporarily so that we can read - in the contents with the generic code. */ - symextn_sec->flags |= SEC_HAS_CONTENTS; - if (bfd_get_section_contents (input_bfd, symextn_sec, contents, - 0, symextn_sec->_raw_size) == false) - { - symextn_sec->flags &= ~SEC_HAS_CONTENTS; - free (contents); - return false; - } - - /* Gross. Turn off SEC_HAS_CONTENTS for the input symbol extension - sections (see above). */ - symextn_sec->flags &= ~SEC_HAS_CONTENTS; - - n_entries = symextn_sec->_raw_size / ELF32_PARISC_SX_SIZE; - for (i = 0; i < n_entries; i++) - { - symext_entryS entry = - ELF32_PARISC_SX_GET (input_bfd, contents + i * ELF32_PARISC_SX_SIZE); - unsigned int value = ELF32_PARISC_SX_VAL (entry); - unsigned int type = ELF32_PARISC_SX_TYPE (entry); - struct elf32_hppa_args_hash_entry *args_hash; - - switch (type) - { - case PARISC_SXT_NULL: - break; - - case PARISC_SXT_SYMNDX: - if (value >= symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - { - bfd_set_error (bfd_error_bad_value); - free (contents); - return false; - } - current_index = value; - break; - - case PARISC_SXT_ARG_RELOC: - if (current_index < symtab_hdr->sh_info) - { - Elf_Internal_Shdr *hdr; - char *new_name; - const char *sym_name; - asection *sym_sec; - unsigned int len; - - hdr = elf_elfsections (input_bfd)[local_syms[current_index].st_shndx]; - sym_sec = hdr->bfd_section; - sym_name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - local_syms[current_index].st_name); - len = strlen (sym_name) + 10; - new_name = bfd_malloc (len); - if (new_name == NULL) - { - free (contents); - return false; - } - strcpy (new_name, sym_name); - sprintf (new_name + len - 10, "_%08x", (int)sym_sec); - - /* This is a global symbol with argument location info. - We need to enter it into the hash table. */ - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - new_name, true, - true); - free (new_name); - if (args_hash == NULL) - { - free (contents); - return false; - } - args_hash->arg_bits = value; - break; - } - else if (current_index >= symtab_hdr->sh_info) - { - struct elf_link_hash_entry *h; - - current_index -= symtab_hdr->sh_info; - h = elf_sym_hashes(input_bfd)[current_index]; - /* This is a global symbol with argument location - information. We need to enter it into the hash table. */ - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - h->root.root.string, - true, true); - if (args_hash == NULL) - { - bfd_set_error (bfd_error_bad_value); - free (contents); - return false; - } - args_hash->arg_bits = value; - break; - } - else - break; - - default: - bfd_set_error (bfd_error_bad_value); - free (contents); - return false; - } - } - free (contents); - return true; -} - -/* Undo the generic ELF code's subtraction of section->vma from the - value of each external symbol. */ - -static boolean -elf32_hppa_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp; - asection **secp; - bfd_vma *valp; -{ - *valp += (*secp)->vma; - return true; -} - -/* Determine the name of the stub needed to perform a call assuming the - argument relocation bits for caller and callee are in CALLER and CALLEE - for a call from LOCATION to DESTINATION. Copy the name into STUB_NAME. */ - -static void -elf32_hppa_name_of_stub (caller, callee, location, destination, stub_name) - unsigned int caller, callee; - bfd_vma location, destination; - char *stub_name; -{ - arg_reloc_type arg_reloc_types[5]; - - if (elf32_hppa_arg_reloc_needed (caller, callee, arg_reloc_types)) - { - arg_reloc_location i; - /* Fill in the basic template. */ - strcpy (stub_name, "__XX_XX_XX_XX_XX_stub_"); - - /* Now fix the specifics. */ - for (i = ARG0; i <= RET; i++) - switch (arg_reloc_types[i]) - { - case NO: - stub_name[3 * i + 2] = 'N'; - stub_name[3 * i + 3] = 'O'; - break; - case GF: - stub_name[3 * i + 2] = 'G'; - stub_name[3 * i + 3] = 'F'; - break; - case FG: - stub_name[3 * i + 2] = 'F'; - stub_name[3 * i + 3] = 'G'; - break; - case GD: - stub_name[3 * i + 2] = 'G'; - stub_name[3 * i + 3] = 'D'; - break; - case DG: - stub_name[3 * i + 2] = 'D'; - stub_name[3 * i + 3] = 'G'; - break; - } - } - else - strcpy (stub_name, "_____long_branch_stub_"); -} - -/* Determine if an argument relocation stub is needed to perform a - call assuming the argument relocation bits for caller and callee - are in CALLER and CALLEE. Place the type of relocations (if any) - into stub_types_p. */ - -static boolean -elf32_hppa_arg_reloc_needed (caller, callee, stub_types) - unsigned int caller, callee; - arg_reloc_type stub_types[5]; -{ - /* Special case for no relocations. */ - if (caller == 0 || callee == 0) - return 0; - else - { - arg_location caller_loc[5]; - arg_location callee_loc[5]; - - /* Extract the location information for the argument and return - value on both the caller and callee sides. */ - caller_loc[ARG0] = EXTRACT_ARBITS (caller, ARG0); - callee_loc[ARG0] = EXTRACT_ARBITS (callee, ARG0); - caller_loc[ARG1] = EXTRACT_ARBITS (caller, ARG1); - callee_loc[ARG1] = EXTRACT_ARBITS (callee, ARG1); - caller_loc[ARG2] = EXTRACT_ARBITS (caller, ARG2); - callee_loc[ARG2] = EXTRACT_ARBITS (callee, ARG2); - caller_loc[ARG3] = EXTRACT_ARBITS (caller, ARG3); - callee_loc[ARG3] = EXTRACT_ARBITS (callee, ARG3); - caller_loc[RET] = EXTRACT_ARBITS (caller, RET); - callee_loc[RET] = EXTRACT_ARBITS (callee, RET); - - /* Check some special combinations. This is necessary to - deal with double precision FP arguments. */ - if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU) - { - caller_loc[ARG0] = AR_FPDBL1; - caller_loc[ARG1] = AR_NO; - } - if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU) - { - caller_loc[ARG2] = AR_FPDBL2; - caller_loc[ARG3] = AR_NO; - } - if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU) - { - callee_loc[ARG0] = AR_FPDBL1; - callee_loc[ARG1] = AR_NO; - } - if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU) - { - callee_loc[ARG2] = AR_FPDBL2; - callee_loc[ARG3] = AR_NO; - } - - /* Now look up any relocation needed for each argument and the - return value. */ - stub_types[ARG0] = arg_mismatches[caller_loc[ARG0]][callee_loc[ARG0]]; - stub_types[ARG1] = arg_mismatches[caller_loc[ARG1]][callee_loc[ARG1]]; - stub_types[ARG2] = arg_mismatches[caller_loc[ARG2]][callee_loc[ARG2]]; - stub_types[ARG3] = arg_mismatches[caller_loc[ARG3]][callee_loc[ARG3]]; - stub_types[RET] = ret_mismatches[caller_loc[RET]][callee_loc[RET]]; - - return (stub_types[ARG0] != NO - || stub_types[ARG1] != NO - || stub_types[ARG2] != NO - || stub_types[ARG3] != NO - || stub_types[RET] != NO); - } -} - -/* Compute the size of the stub needed to call from LOCATION to DESTINATION - (a function named SYM_NAME), with argument relocation bits CALLER and - CALLEE. Return zero if no stub is needed to perform such a call. */ - -static unsigned int -elf32_hppa_size_of_stub (callee, caller, location, destination, sym_name) - unsigned int callee, caller; - bfd_vma location, destination; - const char *sym_name; -{ - arg_reloc_type arg_reloc_types[5]; - - /* Determine if a long branch or argument relocation stub is needed. - If an argument relocation stub is needed, the relocation will be - stored into arg_reloc_types. */ - if (!(((int)(location - destination) > 0x3ffff) - || ((int)(location - destination) < (int)0xfffc0000) - || elf32_hppa_arg_reloc_needed (caller, callee, arg_reloc_types))) - return 0; - - /* Some kind of stub is needed. Determine how big it needs to be. - First check for argument relocation stubs as they also handle - long calls. Then check for long calls to millicode and finally - the normal long calls. */ - if (arg_reloc_types[ARG0] != NO - || arg_reloc_types[ARG1] != NO - || arg_reloc_types[ARG2] != NO - || arg_reloc_types[ARG3] != NO - || arg_reloc_types[RET] != NO) - { - /* Some kind of argument relocation stub is needed. */ - unsigned int len = 16; - arg_reloc_location i; - - /* Each GR or FG relocation takes 2 insns, each GD or DG - relocation takes 3 insns. Plus 4 more insns for the - RP adjustment, ldil & (be | ble) and copy. */ - for (i = ARG0; i <= RET; i++) - switch (arg_reloc_types[i]) - { - case GF: - case FG: - len += 8; - break; - - case GD: - case DG: - len += 12; - break; - - default: - break; - } - - /* Extra instructions are needed if we're relocating a return value. */ - if (arg_reloc_types[RET] != NO) - len += 12; - - return len; - } - else if (!strncmp ("$$", sym_name, 2) - && strcmp ("$$dyncall", sym_name)) - return 12; - else - return 16; -} - -/* Build one linker stub as defined by the stub hash table entry GEN_ENTRY. - IN_ARGS contains the stub BFD and link info pointers. */ - -static boolean -elf32_hppa_build_one_stub (gen_entry, in_args) - struct bfd_hash_entry *gen_entry; - PTR in_args; -{ - void **args = (void **)in_args; - bfd *stub_bfd = (bfd *)args[0]; - struct bfd_link_info *info = (struct bfd_link_info *)args[1]; - struct elf32_hppa_stub_hash_entry *entry; - struct elf32_hppa_stub_hash_table *stub_hash_table; - bfd_byte *loc; - symvalue sym_value; - const char *sym_name; - - /* Initialize pointers to the stub hash table, the particular entry we - are building a stub for, and where (in memory) we should place the stub - instructions. */ - entry = (struct elf32_hppa_stub_hash_entry *)gen_entry; - stub_hash_table = elf32_hppa_hash_table(info)->stub_hash_table; - loc = stub_hash_table->location; - - /* Make a note of the offset within the stubs for this entry. */ - entry->offset = stub_hash_table->offset; - - /* The symbol's name starts at offset 22. */ - sym_name = entry->root.string + 22; - - sym_value = (entry->target_value - + entry->target_section->output_offset - + entry->target_section->output_section->vma); - - if (strncmp ("_____long_branch_stub_", entry->root.string, 22)) - { - /* This must be an argument or return value relocation stub. */ - unsigned long insn; - arg_reloc_location i; - bfd_byte *begin_loc = loc; - - /* First the return pointer adjustment. Depending on exact calling - sequence this instruction may be skipped. */ - bfd_put_32 (stub_bfd, LDO_M4_R31_R31, loc); - loc += 4; - - /* If we are relocating a return value, then we're going to have - to return into the stub. So we have to save off the user's - return pointer into the stack at RP'. */ - if (strncmp (entry->root.string + 14, "NO", 2)) - { - bfd_put_32 (stub_bfd, STW_R31_M8R30, loc); - loc += 4; - } - - /* Iterate over the argument relocations, emitting instructions - to move them around as necessary. */ - for (i = ARG0; i <= ARG3; i++) - { - if (!strncmp (entry->root.string + 3 * i + 2, "GF", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | ((26 - i) << 16), loc); - bfd_put_32 (stub_bfd, FLDW_M16R30_FARG | (4 + i), loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 3 * i + 2, "FG", 2)) - { - bfd_put_32 (stub_bfd, FSTW_FARG_M16R30 | (4 + i), loc); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | ((26 - i) << 16), loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 3 * i + 2, "GD", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M12R30 | ((26 - i) << 16), loc); - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | ((25 - i) << 16), loc + 4); - bfd_put_32 (stub_bfd, FLDD_M16R30_FARG | (5 + i), loc + 8); - loc += 12; - } - else if (!strncmp (entry->root.string + 3 * i + 2, "DG", 2)) - { - bfd_put_32 (stub_bfd, FSTD_FARG_M16R30 | (5 + i), loc); - bfd_put_32 (stub_bfd, LDW_M12R30_ARG | ((26 - i) << 16), loc + 4); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | ((25 - i) << 16), loc + 8); - loc += 12; - } - } - - /* Load the high bits of the target address into %r1. */ - insn = hppa_rebuild_insn (stub_bfd, LDIL_R1, - hppa_field_adjust (sym_value, 0, e_lrsel), 21); - bfd_put_32 (stub_bfd, insn, loc); - loc += 4; - - /* If we are relocating a return value, then we're going to have - to return into the stub, then perform the return value relocation. */ - if (strncmp (entry->root.string + 14, "NO", 2)) - { - /* To return to the stub we "ble" to the target and copy the return - pointer from %r31 into %r2. */ - insn = hppa_rebuild_insn (stub_bfd, - BLE_SR4_R1, - hppa_field_adjust (sym_value, 0, - e_rrsel) >> 2, - 17); - bfd_put_32 (stub_bfd, insn, loc); - bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 4); - - /* Reload the return pointer for our caller from the stack. */ - bfd_put_32 (stub_bfd, LDW_M8R30_R31, loc + 8); - loc += 12; - - /* Perform the return value relocation. */ - if (!strncmp (entry->root.string + 14, "GF", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | (28 << 16), loc); - bfd_put_32 (stub_bfd, FLDW_M16R30_FARG | 4, loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 14, "FG", 2)) - { - bfd_put_32 (stub_bfd, FSTW_FARG_M16R30 | 4, loc); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | (28 << 16), loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 2, "GD", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M12R30 | (28 << 16), loc); - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | (29 << 16), loc + 4); - bfd_put_32 (stub_bfd, FLDD_M16R30_FARG | 4, loc + 8); - loc += 12; - } - else if (!strncmp (entry->root.string + 2, "DG", 2)) - { - bfd_put_32 (stub_bfd, FSTD_FARG_M16R30 | 4, loc); - bfd_put_32 (stub_bfd, LDW_M12R30_ARG | (28 << 16), loc + 4); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | (29 << 16), loc + 8); - loc += 12; - } - /* Branch back to the user's code now. */ - bfd_put_32 (stub_bfd, BV_N_0_R31, loc); - loc += 4; - } - else - { - /* No return value relocation, so we can simply "be" to the - target and copy out return pointer into %r2. */ - insn = hppa_rebuild_insn (stub_bfd, BE_SR4_R1, - hppa_field_adjust (sym_value, 0, - e_rrsel) >> 2, 17); - bfd_put_32 (stub_bfd, insn, loc); - bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 4); - loc += 8; - } - - /* Update the location and offsets. */ - stub_hash_table->location += (loc - begin_loc); - stub_hash_table->offset += (loc - begin_loc); - } - else - { - /* Create one of two variant long branch stubs. One for $$dyncall and - normal calls, the other for calls to millicode. */ - unsigned long insn; - int millicode_call = 0; - - if (!strncmp ("$$", sym_name, 2) && strcmp ("$$dyncall", sym_name)) - millicode_call = 1; - - /* First the return pointer adjustment. Depending on exact calling - sequence this instruction may be skipped. */ - bfd_put_32 (stub_bfd, LDO_M4_R31_R31, loc); - - /* The next two instructions are the long branch itself. A long branch - is formed with "ldil" loading the upper bits of the target address - into a register, then branching with "be" which adds in the lower bits. - Long branches to millicode nullify the delay slot of the "be". */ - insn = hppa_rebuild_insn (stub_bfd, LDIL_R1, - hppa_field_adjust (sym_value, 0, e_lrsel), 21); - bfd_put_32 (stub_bfd, insn, loc + 4); - insn = hppa_rebuild_insn (stub_bfd, BE_SR4_R1 | (millicode_call ? 2 : 0), - hppa_field_adjust (sym_value, 0, e_rrsel) >> 2, - 17); - bfd_put_32 (stub_bfd, insn, loc + 8); - - if (!millicode_call) - { - /* The sequence to call this stub places the return pointer into %r31, - the final target expects the return pointer in %r2, so copy the - return pointer into the proper register. */ - bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 12); - - /* Update the location and offsets. */ - stub_hash_table->location += 16; - stub_hash_table->offset += 16; - } - else - { - /* Update the location and offsets. */ - stub_hash_table->location += 12; - stub_hash_table->offset += 12; - } - - } - return true; -} - -/* External entry points for sizing and building linker stubs. */ - -/* Build all the stubs associated with the current output file. The - stubs are kept in a hash table attached to the main linker hash - table. This is called via hppaelf_finish in the linker. */ - -boolean -elf32_hppa_build_stubs (stub_bfd, info) - bfd *stub_bfd; - struct bfd_link_info *info; -{ - /* The stub BFD only has one section. */ - asection *stub_sec = stub_bfd->sections; - struct elf32_hppa_stub_hash_table *table; - unsigned int size; - void *args[2]; - - /* So we can pass both the BFD for the stubs and the link info - structure to the routine which actually builds stubs. */ - args[0] = stub_bfd; - args[1] = info; - - /* Allocate memory to hold the linker stubs. */ - size = bfd_section_size (stub_bfd, stub_sec); - stub_sec->contents = (unsigned char *) bfd_zalloc (stub_bfd, size); - if (stub_sec->contents == NULL) - return false; - table = elf32_hppa_hash_table(info)->stub_hash_table; - table->location = stub_sec->contents; - - /* Build the stubs as directed by the stub hash table. */ - elf32_hppa_stub_hash_traverse (table, elf32_hppa_build_one_stub, args); - - return true; -} - -/* Determine and set the size of the stub section for a final link. - - The basic idea here is to examine all the relocations looking for - PC-relative calls to a target that is unreachable with a "bl" - instruction or calls where the caller and callee disagree on the - location of their arguments or return value. */ - -boolean -elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) - bfd *stub_bfd; - bfd *output_bfd; - struct bfd_link_info *link_info; -{ - bfd *input_bfd; - asection *section, *stub_sec = 0; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Sym *local_syms, *isym, **all_local_syms; - Elf32_External_Sym *ext_syms, *esym; - unsigned int i, index, bfd_count = 0; - struct elf32_hppa_stub_hash_table *stub_hash_table = 0; - struct elf32_hppa_args_hash_table *args_hash_table = 0; - - /* Create and initialize the stub hash table. */ - stub_hash_table = ((struct elf32_hppa_stub_hash_table *) - bfd_malloc (sizeof (struct elf32_hppa_stub_hash_table))); - if (!stub_hash_table) - goto error_return; - - if (!elf32_hppa_stub_hash_table_init (stub_hash_table, stub_bfd, - elf32_hppa_stub_hash_newfunc)) - goto error_return; - - /* Likewise for the argument location hash table. */ - args_hash_table = ((struct elf32_hppa_args_hash_table *) - bfd_malloc (sizeof (struct elf32_hppa_args_hash_table))); - if (!args_hash_table) - goto error_return; - - if (!elf32_hppa_args_hash_table_init (args_hash_table, - elf32_hppa_args_hash_newfunc)) - goto error_return; - - /* Attach the hash tables to the main hash table. */ - elf32_hppa_hash_table(link_info)->stub_hash_table = stub_hash_table; - elf32_hppa_hash_table(link_info)->args_hash_table = args_hash_table; - - /* Count the number of input BFDs. */ - for (input_bfd = link_info->input_bfds; - input_bfd != NULL; - input_bfd = input_bfd->link_next) - bfd_count++; - - /* We want to read in symbol extension records only once. To do this - we need to read in the local symbols in parallel and save them for - later use; so hold pointers to the local symbols in an array. */ - all_local_syms - = (Elf_Internal_Sym **) bfd_malloc (sizeof (Elf_Internal_Sym *) - * bfd_count); - if (all_local_syms == NULL) - goto error_return; - memset (all_local_syms, 0, sizeof (Elf_Internal_Sym *) * bfd_count); - - /* Walk over all the input BFDs adding entries to the args hash table - for all the external functions. */ - for (input_bfd = link_info->input_bfds, index = 0; - input_bfd != NULL; - input_bfd = input_bfd->link_next, index++) - { - /* We'll need the symbol table in a second. */ - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (symtab_hdr->sh_info == 0) - continue; - - /* We need an array of the local symbols attached to the input bfd. - Unfortunately, we're going to have to read & swap them in. */ - local_syms - = (Elf_Internal_Sym *) bfd_malloc (symtab_hdr->sh_info - * sizeof (Elf_Internal_Sym)); - if (local_syms == NULL) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - all_local_syms[index] = local_syms; - - ext_syms - = (Elf32_External_Sym *) bfd_malloc (symtab_hdr->sh_info - * sizeof (Elf32_External_Sym)); - if (ext_syms == NULL) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || bfd_read (ext_syms, 1, - (symtab_hdr->sh_info - * sizeof (Elf32_External_Sym)), input_bfd) - != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - free (ext_syms); - goto error_return; - } - - /* Swap the local symbols in. */ - isym = local_syms; - esym = ext_syms; - for (i = 0; i < symtab_hdr->sh_info; i++, esym++, isym++) - bfd_elf32_swap_symbol_in (input_bfd, esym, isym); - - /* Now we can free the external symbols. */ - free (ext_syms); - - if (elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table, - local_syms) == false) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - } - - /* Magic as we know the stub bfd only has one section. */ - stub_sec = stub_bfd->sections; - - /* If generating a relocateable output file, then we don't - have to examine the relocs. */ - if (link_info->relocateable) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - return true; - } - - /* Now that we have argument location information for all the global - functions we can start looking for stubs. */ - for (input_bfd = link_info->input_bfds, index = 0; - input_bfd != NULL; - input_bfd = input_bfd->link_next, index++) - { - /* We'll need the symbol table in a second. */ - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (symtab_hdr->sh_info == 0) - continue; - - local_syms = all_local_syms[index]; - - /* Walk over each section attached to the input bfd. */ - for (section = input_bfd->sections; - section != NULL; - section = section->next) - { - Elf_Internal_Shdr *input_rel_hdr; - Elf32_External_Rela *external_relocs, *erelaend, *erela; - Elf_Internal_Rela *internal_relocs, *irelaend, *irela; - - /* If there aren't any relocs, then there's nothing to do. */ - if ((section->flags & SEC_RELOC) == 0 - || section->reloc_count == 0) - continue; - - /* Allocate space for the external relocations. */ - external_relocs - = ((Elf32_External_Rela *) - bfd_malloc (section->reloc_count - * sizeof (Elf32_External_Rela))); - if (external_relocs == NULL) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Likewise for the internal relocations. */ - internal_relocs - = ((Elf_Internal_Rela *) - bfd_malloc (section->reloc_count * sizeof (Elf_Internal_Rela))); - if (internal_relocs == NULL) - { - free (external_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Read in the external relocs. */ - input_rel_hdr = &elf_section_data (section)->rel_hdr; - if (bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) != 0 - || bfd_read (external_relocs, 1, input_rel_hdr->sh_size, - input_bfd) != input_rel_hdr->sh_size) - { - free (external_relocs); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Swap in the relocs. */ - erela = external_relocs; - erelaend = erela + section->reloc_count; - irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - bfd_elf32_swap_reloca_in (input_bfd, erela, irela); - - /* We're done with the external relocs, free them. */ - free (external_relocs); - - /* Now examine each relocation. */ - irela = internal_relocs; - irelaend = irela + section->reloc_count; - for (; irela < irelaend; irela++) - { - long r_type, callee_args, caller_args, size_of_stub; - unsigned long r_index; - struct elf_link_hash_entry *hash; - struct elf32_hppa_stub_hash_entry *stub_hash; - struct elf32_hppa_args_hash_entry *args_hash; - Elf_Internal_Sym *sym; - asection *sym_sec; - const char *sym_name; - symvalue sym_value; - bfd_vma location, destination; - char *new_name = NULL; - - r_type = ELF32_R_TYPE (irela->r_info); - r_index = ELF32_R_SYM (irela->r_info); - - if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED) - { - bfd_set_error (bfd_error_bad_value); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Only look for stubs on call instructions or plabel - references. */ - if (r_type != R_PARISC_PCREL17F - && r_type != R_PARISC_PLABEL32 - && r_type != R_PARISC_PLABEL21L - && r_type != R_PARISC_PLABEL14R) - continue; - - /* Now determine the call target, its name, value, section - and argument relocation bits. */ - hash = NULL; - sym = NULL; - sym_sec = NULL; - if (r_index < symtab_hdr->sh_info) - { - /* It's a local symbol. */ - Elf_Internal_Shdr *hdr; - - sym = local_syms + r_index; - hdr = elf_elfsections (input_bfd)[sym->st_shndx]; - sym_sec = hdr->bfd_section; - sym_name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - sym_value = (ELF_ST_TYPE (sym->st_info) == STT_SECTION - ? 0 : sym->st_value); - destination = (sym_value - + sym_sec->output_offset - + sym_sec->output_section->vma); - - /* Tack on an ID so we can uniquely identify this local - symbol in the stub or arg info hash tables. */ - new_name = bfd_malloc (strlen (sym_name) + 10); - if (new_name == 0) - { - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec); - sym_name = new_name; - } - else - { - /* It's an external symbol. */ - long index; - - index = r_index - symtab_hdr->sh_info; - hash = elf_sym_hashes (input_bfd)[index]; - if (hash->root.type == bfd_link_hash_defined - || hash->root.type == bfd_link_hash_defweak) - { - sym_sec = hash->root.u.def.section; - sym_name = hash->root.root.string; - sym_value = hash->root.u.def.value; - destination = (sym_value - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else - { - bfd_set_error (bfd_error_bad_value); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - } - - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - sym_name, false, false); - - /* Get both caller and callee argument information. */ - if (args_hash == NULL) - callee_args = 0; - else - callee_args = args_hash->arg_bits; - - /* For calls get the caller's bits from the addend of - the call relocation. For PLABELS the caller's bits - are assumed to have all args & return values in general - registers (0x155). */ - if (r_type == R_PARISC_PCREL17F) - caller_args = HPPA_R_ARG_RELOC (irela->r_addend); - else - caller_args = 0x155; - - /* Now determine where the call point is. */ - location = (section->output_offset - + section->output_section->vma - + irela->r_offset); - - /* We only care about the destination for PCREL function - calls (eg. we don't care for PLABELS). */ - if (r_type != R_PARISC_PCREL17F) - location = destination; - - /* Determine what (if any) linker stub is needed and its - size (in bytes). */ - size_of_stub = elf32_hppa_size_of_stub (callee_args, - caller_args, - location, - destination, - sym_name); - if (size_of_stub != 0) - { - char *stub_name; - unsigned int len; - - /* Get the name of this stub. */ - len = strlen (sym_name); - len += 23; - - stub_name = bfd_malloc (len); - if (!stub_name) - { - /* Because sym_name was mallocd above for local - symbols. */ - if (r_index < symtab_hdr->sh_info) - free (new_name); - - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - elf32_hppa_name_of_stub (caller_args, callee_args, - location, destination, stub_name); - strcat (stub_name + 22, sym_name); - - /* Because sym_name was malloced above for local symbols. */ - if (r_index < symtab_hdr->sh_info) - free (new_name); - - stub_hash - = elf32_hppa_stub_hash_lookup (stub_hash_table, stub_name, - false, false); - if (stub_hash != NULL) - { - /* The proper stub has already been created, nothing - else to do. */ - free (stub_name); - } - else - { - bfd_set_section_size (stub_bfd, stub_sec, - (bfd_section_size (stub_bfd, - stub_sec) - + size_of_stub)); - - /* Enter this entry into the linker stub hash table. */ - stub_hash - = elf32_hppa_stub_hash_lookup (stub_hash_table, - stub_name, true, true); - if (stub_hash == NULL) - { - free (stub_name); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* We'll need these to determine the address that the - stub will branch to. */ - stub_hash->target_value = sym_value; - stub_hash->target_section = sym_sec; - } - free (stub_name); - } - } - /* We're done with the internal relocs, free them. */ - free (internal_relocs); - } - } - /* We're done with the local symbols, free them. */ - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - return true; - -error_return: - /* Return gracefully, avoiding dangling references to the hash tables. */ - if (stub_hash_table) - { - elf32_hppa_hash_table(link_info)->stub_hash_table = NULL; - free (stub_hash_table); - } - if (args_hash_table) - { - elf32_hppa_hash_table(link_info)->args_hash_table = NULL; - free (args_hash_table); - } - /* Set the size of the stub section to zero since we're never going - to create them. Avoids losing when we try to get its contents - too. */ - bfd_set_section_size (stub_bfd, stub_sec, 0); - return false; -} - -/* Misc BFD support code. */ -#define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup -#define bfd_elf32_bfd_is_local_label hppa_elf_is_local_label - -/* Symbol extension stuff. */ -#define bfd_elf32_set_section_contents elf32_hppa_set_section_contents -#define elf_backend_symbol_table_processing \ - elf32_hppa_backend_symbol_table_processing -#define elf_backend_begin_write_processing \ - elf32_hppa_backend_begin_write_processing -#define elf_backend_final_write_processing \ - elf32_hppa_backend_final_write_processing - -/* Stuff for the BFD linker. */ -#define elf_backend_relocate_section elf32_hppa_relocate_section -#define elf_backend_add_symbol_hook elf32_hppa_add_symbol_hook -#define elf_backend_link_output_symbol_hook \ - elf32_hppa_link_output_symbol_hook -#define bfd_elf32_bfd_link_hash_table_create \ - elf32_hppa_link_hash_table_create - -#define TARGET_BIG_SYM bfd_elf32_hppa_vec -#define TARGET_BIG_NAME "elf32-hppa" -#define ELF_ARCH bfd_arch_hppa -#define ELF_MACHINE_CODE EM_PARISC -#define ELF_MAXPAGESIZE 0x1000 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-hppa.h b/contrib/gdb/bfd/elf32-hppa.h deleted file mode 100644 index 63ee52200e0..00000000000 --- a/contrib/gdb/bfd/elf32-hppa.h +++ /dev/null @@ -1,152 +0,0 @@ -/* ELF32/HPPA support - - This file contains ELF32/HPPA relocation support as specified - in the Stratus FTX/Golf Object File Format (SED-1762) dated - February 1994. - - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - - Written by: - - Center for Software Science - Department of Computer Science - University of Utah - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _ELF32_HPPA_H -#define _ELF32_HPPA_H - -#include "elf-bfd.h" -#include "libhppa.h" -#include "elf/hppa.h" - -/* ELF/HPPA relocation types */ - -typedef enum - { - /* Address relocation types - These relocation types do simple base + offset relocations. */ - - R_PARISC_NONE = 0x00, - R_PARISC_DIR32 = 0x01, - R_PARISC_DIR21L = 0x02, - R_PARISC_DIR17R = 0x03, - R_PARISC_DIR17F = 0x04, - R_PARISC_DIR14R = 0x06, - - /* PC-relative relocation types - Typically used for calls. - Note PCREL17C and PCREL17F differ only in overflow handling. - PCREL17C never reports a relocation error. - - When supporting argument relocations, function calls must be - accompanied by parameter relocation information. This information is - carried in the ten high-order bits of the addend field. The remaining - 22 bits of of the addend field are sign-extended to form the Addend. - - Note the code to build argument relocations depends on the - addend being zero. A consequence of this limitation is GAS - can not perform relocation reductions for function symbols. */ - R_PARISC_PCREL21L = 0x0a, - R_PARISC_PCREL17R = 0x0b, - R_PARISC_PCREL17F = 0x0c, - R_PARISC_PCREL17C = 0x0d, - R_PARISC_PCREL14R = 0x0e, - R_PARISC_PCREL14F = 0x0f, - - /* DP-relative relocation types. */ - R_PARISC_DPREL21L = 0x12, - R_PARISC_DPREL14R = 0x16, - R_PARISC_DPREL14F = 0x17, - - /* Data linkage table (DLT) relocation types - - SOM DLT_REL fixup requests are used to for static data references - from position-independent code within shared libraries. They are - similar to the GOT relocation types in some SVR4 implementations. */ - - R_PARISC_DLTREL21L = 0x1a, - R_PARISC_DLTREL14R = 0x1e, - R_PARISC_DLTREL14F = 0x1f, - - /* DLT indirect relocation types */ - R_PARISC_DLTIND21L = 0x22, - R_PARISC_DLTIND14R = 0x26, - R_PARISC_DLTIND14F = 0x27, - - /* Base relative relocation types. Ugh. These imply lots of state */ - R_PARISC_SETBASE = 0x28, - R_PARISC_BASEREL32 = 0x29, - R_PARISC_BASEREL21L = 0x2a, - R_PARISC_BASEREL17R = 0x2b, - R_PARISC_BASEREL17F = 0x2c, - R_PARISC_BASEREL14R = 0x2e, - R_PARISC_BASEREL14F = 0x2f, - - /* Segment relative relocation types. */ - R_PARISC_TEXTREL32 = 0x31, - R_PARISC_DATAREL32 = 0x39, - - /* Plabel relocation types. */ - R_PARISC_PLABEL32 = 0x41, - R_PARISC_PLABEL21L = 0x42, - R_PARISC_PLABEL14R = 0x46, - - /* PLT relocations. */ - R_PARISC_PLTIND21L = 0x82, - R_PARISC_PLTIND14R = 0x86, - R_PARISC_PLTIND14F = 0x87, - - /* Misc relocation types. */ - R_PARISC_COPY = 0x88, - R_PARISC_GLOB_DAT = 0x89, - R_PARISC_JMP_SLOT = 0x8a, - R_PARISC_RELATIVE = 0x8b, - R_PARISC_UNIMPLEMENTED, - } -elf32_hppa_reloc_type; - -#define ELF_HOWTO_TABLE_SIZE R_PARISC_UNIMPLEMENTED + 1 -#define N_PARISC_RELOCS R_PARISC_UNIMPLEMENTED + 1 - -/* Define groups of basic relocations. FIXME: These should - be the only basic relocations created by GAS. The rest - should be internal to the BFD backend. - - The idea is both SOM and ELF define these basic relocation - types so they map into a SOM or ELF specific relocation - as appropriate. This allows GAS to share much more code - between the two target object formats. */ - -#define R_HPPA_NONE R_PARISC_NONE -#define R_HPPA R_PARISC_DIR32 -#define R_HPPA_GOTOFF R_PARISC_DPREL21L -#define R_HPPA_PCREL_CALL R_PARISC_PCREL21L -#define R_HPPA_ABS_CALL R_PARISC_DIR17F -#define R_HPPA_COMPLEX R_PARISC_UNIMPLEMENTED - -elf32_hppa_reloc_type **hppa_elf_gen_reloc_type - PARAMS ((bfd *, elf32_hppa_reloc_type, int, int, int)); - -boolean elf32_hppa_size_stubs - PARAMS ((bfd *, bfd *, struct bfd_link_info *)); - -boolean elf32_hppa_build_stubs - PARAMS ((bfd *, struct bfd_link_info *)); - -#endif /* _ELF32_HPPA_H */ diff --git a/contrib/gdb/bfd/elf32-i386.c b/contrib/gdb/bfd/elf32-i386.c deleted file mode 100644 index 3b39aac9191..00000000000 --- a/contrib/gdb/bfd/elf32-i386.c +++ /dev/null @@ -1,1546 +0,0 @@ -/* Intel 80386/80486-specific support for 32-bit ELF - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" - -static reloc_howto_type *elf_i386_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf_i386_info_to_howto - PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); -static void elf_i386_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); -static boolean elf_i386_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean elf_i386_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf_i386_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_i386_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean elf_i386_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean elf_i386_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -#define USE_REL 1 /* 386 uses REL relocations instead of RELA */ - -enum reloc_type - { - R_386_NONE = 0, - R_386_32, - R_386_PC32, - R_386_GOT32, - R_386_PLT32, - R_386_COPY, - R_386_GLOB_DAT, - R_386_JUMP_SLOT, - R_386_RELATIVE, - R_386_GOTOFF, - R_386_GOTPC, - R_386_max - }; - -#if 0 -static CONST char *CONST reloc_type_names[] = -{ - "R_386_NONE", - "R_386_32", - "R_386_PC32", - "R_386_GOT32", - "R_386_PLT32", - "R_386_COPY", - "R_386_GLOB_DAT", - "R_386_JUMP_SLOT", - "R_386_RELATIVE", - "R_386_GOTOFF", - "R_386_GOTPC", -}; -#endif - -static reloc_howto_type elf_howto_table[]= -{ - HOWTO(R_386_NONE, 0,0, 0,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_NONE", true,0x00000000,0x00000000,false), - HOWTO(R_386_32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_32", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_PC32, 0,2,32,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC32", true,0xffffffff,0xffffffff,true), - HOWTO(R_386_GOT32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOT32", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_PLT32, 0,2,32,true,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PLT32", true,0xffffffff,0xffffffff,true), - HOWTO(R_386_COPY, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_COPY", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GLOB_DAT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GLOB_DAT", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_JUMP_SLOT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_JUMP_SLOT",true,0xffffffff,0xffffffff,false), - HOWTO(R_386_RELATIVE, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_RELATIVE", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GOTOFF, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTOFF", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GOTPC, 0,2,32,true,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTPC", true,0xffffffff,0xffffffff,true), -}; - -#ifdef DEBUG_GEN_RELOC -#define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str) -#else -#define TRACE(str) -#endif - -static reloc_howto_type * -elf_i386_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_NONE: - TRACE ("BFD_RELOC_NONE"); - return &elf_howto_table[ (int)R_386_NONE ]; - - case BFD_RELOC_32: - TRACE ("BFD_RELOC_32"); - return &elf_howto_table[ (int)R_386_32 ]; - - case BFD_RELOC_32_PCREL: - TRACE ("BFD_RELOC_PC32"); - return &elf_howto_table[ (int)R_386_PC32 ]; - - case BFD_RELOC_386_GOT32: - TRACE ("BFD_RELOC_386_GOT32"); - return &elf_howto_table[ (int)R_386_GOT32 ]; - - case BFD_RELOC_386_PLT32: - TRACE ("BFD_RELOC_386_PLT32"); - return &elf_howto_table[ (int)R_386_PLT32 ]; - - case BFD_RELOC_386_COPY: - TRACE ("BFD_RELOC_386_COPY"); - return &elf_howto_table[ (int)R_386_COPY ]; - - case BFD_RELOC_386_GLOB_DAT: - TRACE ("BFD_RELOC_386_GLOB_DAT"); - return &elf_howto_table[ (int)R_386_GLOB_DAT ]; - - case BFD_RELOC_386_JUMP_SLOT: - TRACE ("BFD_RELOC_386_JUMP_SLOT"); - return &elf_howto_table[ (int)R_386_JUMP_SLOT ]; - - case BFD_RELOC_386_RELATIVE: - TRACE ("BFD_RELOC_386_RELATIVE"); - return &elf_howto_table[ (int)R_386_RELATIVE ]; - - case BFD_RELOC_386_GOTOFF: - TRACE ("BFD_RELOC_386_GOTOFF"); - return &elf_howto_table[ (int)R_386_GOTOFF ]; - - case BFD_RELOC_386_GOTPC: - TRACE ("BFD_RELOC_386_GOTPC"); - return &elf_howto_table[ (int)R_386_GOTPC ]; - - default: - break; - } - - TRACE ("Unknown"); - return 0; -} - -static void -elf_i386_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); - - cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -static void -elf_i386_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rel *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); - - cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -/* Functions for the i386 ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 16 - -/* The first entry in an absolute procedure linkage table looks like - this. See the SVR4 ABI i386 supplement to see how this works. */ - -static const bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x35, /* pushl contents of address */ - 0, 0, 0, 0, /* replaced with address of .got + 4. */ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0, /* replaced with address of .got + 8. */ - 0, 0, 0, 0 /* pad out to 16 bytes. */ -}; - -/* Subsequent entries in an absolute procedure linkage table look like - this. */ - -static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0, /* replaced with address of this symbol in .got. */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* The first entry in a PIC procedure linkage table look like this. */ - -static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */ - 0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */ - 0, 0, 0, 0 /* pad out to 16 bytes. */ -}; - -/* Subsequent entries in a PIC procedure linkage table look like this. */ - -static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0xa3, /* jmp *offset(%ebx) */ - 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -elf_i386_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *srelgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - local_got_offsets = elf_local_got_offsets (abfd); - - sgot = NULL; - srelgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - /* Some relocs require a global offset table. */ - if (dynobj == NULL) - { - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_386_GOT32: - case R_386_GOTOFF: - case R_386_GOTPC: - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) - return false; - break; - - default: - break; - } - } - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_386_GOT32: - /* This symbol requires a global offset table entry. */ - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (srelgot == NULL - && (h != NULL || info->shared)) - { - srelgot = bfd_get_section_by_name (dynobj, ".rel.got"); - if (srelgot == NULL) - { - srelgot = bfd_make_section (dynobj, ".rel.got"); - if (srelgot == NULL - || ! bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; - } - } - - if (h != NULL) - { - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - h->got_offset = sgot->_raw_size; - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - srelgot->_raw_size += sizeof (Elf32_External_Rel); - } - else - { - /* This is a global offset table entry for a local - symbol. */ - if (local_got_offsets == NULL) - { - size_t size; - register unsigned int i; - - size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); - if (local_got_offsets == NULL) - return false; - elf_local_got_offsets (abfd) = local_got_offsets; - for (i = 0; i < symtab_hdr->sh_info; i++) - local_got_offsets[i] = (bfd_vma) -1; - } - if (local_got_offsets[r_symndx] != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - local_got_offsets[r_symndx] = sgot->_raw_size; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_386_RELATIVE reloc so that the dynamic - linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf32_External_Rel); - } - } - - sgot->_raw_size += 4; - - break; - - case R_386_PLT32: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ - - /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ - if (h == NULL) - continue; - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - - break; - - case R_386_32: - case R_386_PC32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0 - && (ELF32_R_TYPE (rel->r_info) != R_386_PC32 || h != NULL)) - { - /* When creating a shared object, we must copy these - reloc types into the output file. We create a reloc - section in dynobj and make room for this reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rel", 4) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 4) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rel); - } - - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -elf_i386_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - unsigned int power_of_two; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later, - when we know the address of the .got section. */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0) - { - /* This case can occur if we saw a PLT32 reloc in an input - file, but the symbol was never referred to by a dynamic - object. In such a case, we don't actually need to build - a procedure linkage table, and we can just do a PC32 - reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); - return true; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->_raw_size == 0) - s->_raw_size += PLT_ENTRY_SIZE; - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - } - - h->plt_offset = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - - s = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += 4; - - /* We also need to make an entry in the .rel.plt section. */ - - s = bfd_get_section_by_name (dynobj, ".rel.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf32_External_Rel); - - return true; - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return true; - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); - - /* If the symbol is currently defined in the .bss section of the - dynamic object, then it is OK to simply initialize it to zero. - If the symbol is in some other section, we must generate a - R_386_COPY reloc to tell the dynamic linker to copy the initial - value out of the dynamic object and into the runtime process - image. We need to remember the offset into the .rel.bss section - we are going to use. */ - if ((h->root.u.def.section->flags & SEC_LOAD) != 0) - { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rel.bss"); - BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf32_External_Rel); - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - power_of_two = bfd_log2 (h->size); - if (power_of_two > 3) - power_of_two = 3; - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, - (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (! bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; - } - - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -elf_i386_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean plt; - boolean relocs; - boolean reltext; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - } - else - { - /* We may have created entries in the .rel.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rel.got, - which will cause it to get stripped from the output file - below. */ - s = bfd_get_section_by_name (dynobj, ".rel.got"); - if (s != NULL) - s->_raw_size = 0; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - plt = false; - relocs = false; - reltext = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - - if (strcmp (name, ".plt") == 0) - { - if (s->_raw_size == 0) - { - /* Strip this section if we don't need it; see the - comment below. */ - strip = true; - } - else - { - /* Remember whether there is a PLT. */ - plt = true; - } - } - else if (strncmp (name, ".rel", 4) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rel.bss and - .rel.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* Remember whether there are any reloc sections other - than .rel.plt. */ - if (strcmp (name, ".rel.plt") != 0) - { - relocs = true; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. The entries in the .rel.plt section - really apply to the .got section, which we - created ourselves and so know is not readonly. */ - target = bfd_get_section_by_name (output_bfd, name + 4); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - } - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else if (strncmp (name, ".got", 4) != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_i386_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (plt) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_REL) - || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (relocs) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELENT, - sizeof (Elf32_External_Rel))) - return false; - } - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - return true; -} - -/* Relocate an i386 ELF section. */ - -static boolean -elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - asection *sgot; - asection *splt; - asection *sreloc; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - - sgot = NULL; - splt = NULL; - sreloc = NULL; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_386_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = elf_howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - bfd_vma val; - - sec = local_sections[r_symndx]; - val = bfd_get_32 (input_bfd, contents + rel->r_offset); - val += sec->output_offset + sym->st_value; - bfd_put_32 (input_bfd, val, contents + rel->r_offset); - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (r_type == R_386_GOTPC - || (r_type == R_386_PLT32 - && h->plt_offset != (bfd_vma) -1) - || (r_type == R_386_GOT32 - && elf_hash_table (info)->dynamic_sections_created - && (! info->shared - || ! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (r_type == R_386_32 - || r_type == R_386_PC32) - && (input_section->flags & SEC_ALLOC) != 0)) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - switch (r_type) - { - case R_386_GOT32: - /* Relocation is to the entry for this symbol in the global - offset table. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (h != NULL) - { - bfd_vma off; - - off = h->got_offset; - BFD_ASSERT (off != (bfd_vma) -1); - - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global offset table. Since the offset must - always be a multiple of 4, we use the least - significant bit to record whether we have - initialized it already. - - When doing a dynamic link, we create a .rel.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - sgot->contents + off); - h->got_offset |= 1; - } - } - - relocation = sgot->output_offset + off; - } - else - { - bfd_vma off; - - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 4. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, sgot->contents + off); - - if (info->shared) - { - asection *srelgot; - Elf_Internal_Rel outrel; - - srelgot = bfd_get_section_by_name (dynobj, ".rel.got"); - BFD_ASSERT (srelgot != NULL); - - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + off); - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, - (((Elf32_External_Rel *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; - } - - local_got_offsets[r_symndx] |= 1; - } - - relocation = sgot->output_offset + off; - } - - break; - - case R_386_GOTOFF: - /* Relocation is relative to the start of the global offset - table. */ - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - /* Note that sgot->output_offset is not involved in this - calculation. We always want the start of .got. If we - defined _GLOBAL_OFFSET_TABLE in a different way, as is - permitted by the ABI, we might have to change this - calculation. */ - relocation -= sgot->output_section->vma; - - break; - - case R_386_GOTPC: - /* Use global offset table as symbol value. */ - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - relocation = sgot->output_section->vma; - - break; - - case R_386_PLT32: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - - /* Resolve a PLT32 reloc again a local symbol directly, - without using the procedure linkage table. */ - if (h == NULL) - break; - - if (h->plt_offset == (bfd_vma) -1) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - - break; - - case R_386_32: - case R_386_PC32: - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0 - && (r_type != R_386_PC32 - || (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) - { - Elf_Internal_Rel outrel; - boolean relocate; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rel", 4) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 4) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (r_type == R_386_PC32) - { - BFD_ASSERT (h != NULL && h->dynindx != -1); - relocate = false; - outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_PC32); - } - else - { - if (h == NULL - || (info->symbolic - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) != 0)) - { - relocate = true; - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - } - else - { - BFD_ASSERT (h->dynindx != -1); - relocate = false; - outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_32); - } - } - - bfd_elf32_swap_reloc_out (output_bfd, &outrel, - (((Elf32_External_Rel *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - /* If this reloc is against an external symbol, we do - not want to fiddle with the addend. Otherwise, we - need to include the symbol value so that it becomes - an addend for the dynamic reloc. */ - if (! relocate) - continue; - } - - break; - - default: - break; - } - - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, (bfd_vma) 0); - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - - dynobj = elf_hash_table (info)->dynobj; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *sgot; - asection *srel; - bfd_vma plt_index; - bfd_vma got_offset; - Elf_Internal_Rel rel; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - srel = bfd_get_section_by_name (dynobj, ".rel.plt"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = h->plt_offset / PLT_ENTRY_SIZE - 1; - - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; - - /* Fill in the entry in the procedure linkage table. */ - if (! info->shared) - { - memcpy (splt->contents + h->plt_offset, elf_i386_plt_entry, - PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset - + got_offset), - splt->contents + h->plt_offset + 2); - } - else - { - memcpy (splt->contents + h->plt_offset, elf_i386_pic_plt_entry, - PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, got_offset, - splt->contents + h->plt_offset + 2); - } - - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), - splt->contents + h->plt_offset + 7); - bfd_put_32 (output_bfd, - (h->plt_offset + PLT_ENTRY_SIZE), - splt->contents + h->plt_offset + 12); - - /* Fill in the entry in the global offset table. */ - bfd_put_32 (output_bfd, - (splt->output_section->vma - + splt->output_offset - + h->plt_offset - + 6), - sgot->contents + got_offset); - - /* Fill in the entry in the .rel.plt section. */ - rel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + got_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) srel->contents - + plt_index)); - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if (h->got_offset != (bfd_vma) -1) - { - asection *sgot; - asection *srel; - Elf_Internal_Rel rel; - - /* This symbol has an entry in the global offset table. Set it - up. */ - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".rel.got"); - BFD_ASSERT (sgot != NULL && srel != NULL); - - rel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + (h->got_offset &~ 1)); - - /* If this is a -Bsymbolic link, and the symbol is defined - locally, we just want to emit a RELATIVE reloc. The entry in - the global offset table will already have been initialized in - the relocate_section function. */ - if (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - else - { - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT); - } - - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) srel->contents - + srel->reloc_count)); - ++srel->reloc_count; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rel rel; - - /* This symbol needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rel.bss"); - BFD_ASSERT (s != NULL); - - rel.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -elf_i386_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sgot; - asection *sdyn; - - dynobj = elf_hash_table (info)->dynobj; - - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (sgot != NULL); - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - asection *s; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - case DT_PLTGOT: - name = ".got"; - goto get_vma; - case DT_JMPREL: - name = ".rel.plt"; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_PLTRELSZ: - s = bfd_get_section_by_name (output_bfd, ".rel.plt"); - BFD_ASSERT (s != NULL); - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_RELSZ: - /* My reading of the SVR4 ABI indicates that the - procedure linkage table relocs (DT_JMPREL) should be - included in the overall relocs (DT_REL). This is - what Solaris does. However, UnixWare can not handle - that case. Therefore, we override the DT_RELSZ entry - here to make it not include the JMPREL relocs. Since - the linker script arranges for .rel.plt to follow all - other relocation sections, we don't have to worry - about changing the DT_REL entry. */ - s = bfd_get_section_by_name (output_bfd, ".rel.plt"); - if (s != NULL) - { - if (s->_cooked_size != 0) - dyn.d_un.d_val -= s->_cooked_size; - else - dyn.d_un.d_val -= s->_raw_size; - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - } - } - - /* Fill in the first entry in the procedure linkage table. */ - if (splt->_raw_size > 0) - { - if (info->shared) - memcpy (splt->contents, elf_i386_pic_plt0_entry, PLT_ENTRY_SIZE); - else - { - memcpy (splt->contents, elf_i386_plt0_entry, PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - sgot->output_section->vma + sgot->output_offset + 4, - splt->contents + 2); - bfd_put_32 (output_bfd, - sgot->output_section->vma + sgot->output_offset + 8, - splt->contents + 8); - } - } - - /* UnixWare sets the entsize of .plt to 4, although that doesn't - really seem like the right value. */ - elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; - } - - /* Fill in the first three entries in the global offset table. */ - if (sgot->_raw_size > 0) - { - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - return true; -} - -#define TARGET_LITTLE_SYM bfd_elf32_i386_vec -#define TARGET_LITTLE_NAME "elf32-i386" -#define ELF_ARCH bfd_arch_i386 -#define ELF_MACHINE_CODE EM_386 -#define elf_info_to_howto elf_i386_info_to_howto -#define elf_info_to_howto_rel elf_i386_info_to_howto_rel -#define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup -#define ELF_MAXPAGESIZE 0x1000 -#define elf_backend_create_dynamic_sections \ - _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs elf_i386_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - elf_i386_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - elf_i386_size_dynamic_sections -#define elf_backend_relocate_section elf_i386_relocate_section -#define elf_backend_finish_dynamic_symbol \ - elf_i386_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - elf_i386_finish_dynamic_sections -#define elf_backend_want_got_plt 1 -#define elf_backend_plt_readonly 1 -#define elf_backend_want_plt_sym 0 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-i860.c b/contrib/gdb/bfd/elf32-i860.c deleted file mode 100644 index a8537a75508..00000000000 --- a/contrib/gdb/bfd/elf32-i860.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Intel 860 specific support for 32-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#define TARGET_BIG_SYM bfd_elf32_i860_vec -#define TARGET_BIG_NAME "elf32-i860" -#define ELF_ARCH bfd_arch_i860 -#define ELF_MACHINE_CODE EM_860 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-m68k.c b/contrib/gdb/bfd/elf32-m68k.c deleted file mode 100644 index 752dfaed227..00000000000 --- a/contrib/gdb/bfd/elf32-m68k.c +++ /dev/null @@ -1,1600 +0,0 @@ -/* Motorola 68k series support for 32-bit ELF - Copyright 1993, 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" - -static reloc_howto_type *reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void rtype_to_howto - PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); -static void rtype_to_howto_rel - PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); -static boolean elf_m68k_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean elf_m68k_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf_m68k_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_m68k_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean elf_m68k_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean elf_m68k_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -/* elf32 m68k code, generated by elf.el */ -enum reloc_type { - R_68K_NONE = 0, - R_68K_32 = 1, - R_68K_16 = 2, - R_68K_8 = 3, - R_68K_PC32 = 4, - R_68K_PC16 = 5, - R_68K_PC8 = 6, - R_68K_GOT32 = 7, - R_68K_GOT16 = 8, - R_68K_GOT8 = 9, - R_68K_GOT32O = 10, - R_68K_GOT16O = 11, - R_68K_GOT8O = 12, - R_68K_PLT32 = 13, - R_68K_PLT16 = 14, - R_68K_PLT8 = 15, - R_68K_PLT32O = 16, - R_68K_PLT16O = 17, - R_68K_PLT8O = 18, - R_68K_COPY = 19, - R_68K_GLOB_DAT = 20, - R_68K_JMP_SLOT = 21, - R_68K_RELATIVE = 22, - R_68K__max -}; - -static reloc_howto_type howto_table[] = { - HOWTO(R_68K_NONE, 0, 0, 0, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_NONE", false, 0, 0x00000000,false), - HOWTO(R_68K_32, 0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32", false, 0, 0xffffffff,false), - HOWTO(R_68K_16, 0, 1,16, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_16", false, 0, 0x0000ffff,false), - HOWTO(R_68K_8, 0, 0, 8, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_8", false, 0, 0x000000ff,false), - HOWTO(R_68K_PC32, 0, 2,32, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC32", false, 0, 0xffffffff,true), - HOWTO(R_68K_PC16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_PC8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC8", false, 0, 0x000000ff,true), - HOWTO(R_68K_GOT32, 0, 2,32, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT32", false, 0, 0xffffffff,true), - HOWTO(R_68K_GOT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_GOT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8", false, 0, 0x000000ff,true), - HOWTO(R_68K_GOT32O, 0, 2,32, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT32O", false, 0, 0xffffffff,false), - HOWTO(R_68K_GOT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16O", false, 0, 0x0000ffff,false), - HOWTO(R_68K_GOT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8O", false, 0, 0x000000ff,false), - HOWTO(R_68K_PLT32, 0, 2,32, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT32", false, 0, 0xffffffff,true), - HOWTO(R_68K_PLT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_PLT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8", false, 0, 0x000000ff,true), - HOWTO(R_68K_PLT32O, 0, 2,32, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT32O", false, 0, 0xffffffff,false), - HOWTO(R_68K_PLT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16O", false, 0, 0x0000ffff,false), - HOWTO(R_68K_PLT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8O", false, 0, 0x000000ff,false), - HOWTO(R_68K_COPY, 0, 0, 0, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_COPY", false, 0, 0xffffffff,false), - HOWTO(R_68K_GLOB_DAT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_GLOB_DAT", false, 0, 0xffffffff,false), - HOWTO(R_68K_JMP_SLOT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_JMP_SLOT", false, 0, 0xffffffff,false), - HOWTO(R_68K_RELATIVE, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_RELATIVE", false, 0, 0xffffffff,false), -}; - -static void -rtype_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K__max); - cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -static void -rtype_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rel *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K__max); - cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -#define elf_info_to_howto rtype_to_howto -#define elf_info_to_howto_rel rtype_to_howto_rel - -static const struct { unsigned char bfd_val, elf_val; } reloc_map[] = { - { BFD_RELOC_NONE, R_68K_NONE }, - { BFD_RELOC_32, R_68K_32 }, - { BFD_RELOC_16, R_68K_16 }, - { BFD_RELOC_8, R_68K_8 }, - { BFD_RELOC_32_PCREL, R_68K_PC32 }, - { BFD_RELOC_16_PCREL, R_68K_PC16 }, - { BFD_RELOC_8_PCREL, R_68K_PC8 }, - { BFD_RELOC_32_GOT_PCREL, R_68K_GOT32 }, - { BFD_RELOC_16_GOT_PCREL, R_68K_GOT16 }, - { BFD_RELOC_8_GOT_PCREL, R_68K_GOT8 }, - { BFD_RELOC_32_GOTOFF, R_68K_GOT32O }, - { BFD_RELOC_16_GOTOFF, R_68K_GOT16O }, - { BFD_RELOC_8_GOTOFF, R_68K_GOT8O }, - { BFD_RELOC_32_PLT_PCREL, R_68K_PLT32 }, - { BFD_RELOC_16_PLT_PCREL, R_68K_PLT16 }, - { BFD_RELOC_8_PLT_PCREL, R_68K_PLT8 }, - { BFD_RELOC_32_PLTOFF, R_68K_PLT32O }, - { BFD_RELOC_16_PLTOFF, R_68K_PLT16O }, - { BFD_RELOC_8_PLTOFF, R_68K_PLT8O }, - { BFD_RELOC_NONE, R_68K_COPY }, - { BFD_RELOC_68K_GLOB_DAT, R_68K_GLOB_DAT }, - { BFD_RELOC_68K_JMP_SLOT, R_68K_JMP_SLOT }, - { BFD_RELOC_68K_RELATIVE, R_68K_RELATIVE }, - { BFD_RELOC_CTOR, R_68K_32 }, -}; - -static reloc_howto_type * -reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++) - { - if (reloc_map[i].bfd_val == code) - return &howto_table[(int) reloc_map[i].elf_val]; - } - return 0; -} - -#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup -#define ELF_ARCH bfd_arch_m68k -/* end code generated by elf.el */ - -#define USE_RELA - - -/* Functions for the m68k ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 20 - -/* The first entry in a procedure linkage table looks like this. See - the SVR4 ABI m68k supplement to see how this works. */ - -static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */ - 0, 0, 0, 0, /* replaced with offset to .got + 4. */ - 0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */ - 0, 0, 0, 0, /* replaced with offset to .got + 8. */ - 0, 0, 0, 0 /* pad out to 20 bytes. */ -}; - -/* Subsequent entries in a procedure linkage table look like this. */ - -static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] = -{ - 0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */ - 0, 0, 0, 0, /* replaced with offset to symbol's .got entry. */ - 0x2f, 0x3c, /* move.l #offset,-(%sp) */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0x60, 0xff, /* bra.l .plt */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -elf_m68k_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *srelgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - local_got_offsets = elf_local_got_offsets (abfd); - - sgot = NULL; - srelgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_68K_GOT8: - case R_68K_GOT16: - case R_68K_GOT32: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_68K_GOT8O: - case R_68K_GOT16O: - case R_68K_GOT32O: - /* This symbol requires a global offset table entry. */ - - if (dynobj == NULL) - { - /* Create the .got section. */ - elf_hash_table (info)->dynobj = dynobj = abfd; - if (!_bfd_elf_create_got_section (dynobj, info)) - return false; - } - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (srelgot == NULL - && (h != NULL || info->shared)) - { - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - if (srelgot == NULL) - { - srelgot = bfd_make_section (dynobj, ".rela.got"); - if (srelgot == NULL - || !bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || !bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; - } - } - - if (h != NULL) - { - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - h->got_offset = sgot->_raw_size; - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - else - { - /* This is a global offset table entry for a local - symbol. */ - if (local_got_offsets == NULL) - { - size_t size; - register unsigned int i; - - size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); - if (local_got_offsets == NULL) - return false; - elf_local_got_offsets (abfd) = local_got_offsets; - for (i = 0; i < symtab_hdr->sh_info; i++) - local_got_offsets[i] = (bfd_vma) -1; - } - if (local_got_offsets[r_symndx] != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - local_got_offsets[r_symndx] = sgot->_raw_size; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_68K_RELATIVE reloc so that the dynamic - linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - } - - sgot->_raw_size += 4; - break; - - case R_68K_PLT8: - case R_68K_PLT16: - case R_68K_PLT32: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ - - /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ - if (h == NULL) - continue; - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - break; - - case R_68K_PLT8O: - case R_68K_PLT16O: - case R_68K_PLT32O: - /* This symbol requires a procedure linkage table entry. */ - - if (h == NULL) - { - /* It does not make sense to have this relocation for a - local symbol. FIXME: does it? How to handle it if - it does make sense? */ - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - break; - - case R_68K_PC8: - case R_68K_PC16: - case R_68K_PC32: - if (h == NULL) - break; - /* Fall through. */ - case R_68K_8: - case R_68K_16: - case R_68K_32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0 - && ((ELF32_R_TYPE (rel->r_info) != R_68K_PC8 - && ELF32_R_TYPE (rel->r_info) != R_68K_PC16 - && ELF32_R_TYPE (rel->r_info) != R_68K_PC32) - || (!info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))) - { - /* When creating a shared object, we must copy these - reloc types into the output file. We create a reloc - section in dynobj and make room for this reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || !bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || !bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rela); - } - - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -elf_m68k_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - unsigned int power_of_two; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later, - when we know the address of the .got section. */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 - /* We must always create the plt entry if it was referenced - by a PLTxxO relocation. In this case we already recorded - it as a dynamic symbol. */ - && h->dynindx == -1) - { - /* This case can occur if we saw a PLTxx reloc in an input - file, but the symbol was never referred to by a dynamic - object. In such a case, we don't actually need to build - a procedure linkage table, and we can just do a PCxx - reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); - return true; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->_raw_size == 0) - s->_raw_size += PLT_ENTRY_SIZE; - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (!info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - } - - h->plt_offset = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - - s = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += 4; - - /* We also need to make an entry in the .rela.plt section. */ - - s = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf32_External_Rela); - - return true; - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return true; - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); - - /* If the symbol is currently defined in the .bss section of the - dynamic object, then it is OK to simply initialize it to zero. - If the symbol is in some other section, we must generate a - R_68K_COPY reloc to tell the dynamic linker to copy the initial - value out of the dynamic object and into the runtime process - image. We need to remember the offset into the .rela.bss section - we are going to use. */ - if ((h->root.u.def.section->flags & SEC_LOAD) != 0) - { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rela.bss"); - BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf32_External_Rela); - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - power_of_two = bfd_log2 (h->size); - if (power_of_two > 3) - power_of_two = 3; - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, - (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (!bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; - } - - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -elf_m68k_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean plt; - boolean relocs; - boolean reltext; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (!info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - } - else - { - /* We may have created entries in the .rela.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rela.got, - which will cause it to get stripped from the output file - below. */ - s = bfd_get_section_by_name (dynobj, ".rela.got"); - if (s != NULL) - s->_raw_size = 0; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - plt = false; - relocs = false; - reltext = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - - if (strcmp (name, ".plt") == 0) - { - if (s->_raw_size == 0) - { - /* Strip this section if we don't need it; see the - comment below. */ - strip = true; - } - else - { - /* Remember whether there is a PLT. */ - plt = true; - } - } - else if (strncmp (name, ".rela", 5) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* Remember whether there are any reloc sections other - than .rela.plt. */ - if (strcmp (name, ".rela.plt") != 0) - { - relocs = true; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. .rela.plt is actually associated with - .got.plt, which is never readonly. */ - target = bfd_get_section_by_name (output_bfd, name + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - } - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else if (strncmp (name, ".got", 4) != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_m68k_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (!info->shared) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (plt) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || !bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (relocs) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_RELA, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return false; - } - - if (reltext) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - return true; -} - -/* Relocate an M68K ELF section. */ - -static boolean -elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - asection *sgot; - asection *splt; - asection *sreloc; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - - sgot = NULL; - splt = NULL; - sreloc = NULL; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_68K__max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (((r_type == R_68K_PLT8 - || r_type == R_68K_PLT16 - || r_type == R_68K_PLT32 - || r_type == R_68K_PLT8O - || r_type == R_68K_PLT16O - || r_type == R_68K_PLT32O) - && h->plt_offset != (bfd_vma) -1) - || ((r_type == R_68K_GOT8O - || r_type == R_68K_GOT16O - || r_type == R_68K_GOT32O - || ((r_type == R_68K_GOT8 - || r_type == R_68K_GOT16 - || r_type == R_68K_GOT32) - && strcmp (h->root.root.string, - "_GLOBAL_OFFSET_TABLE_") != 0)) - && elf_hash_table (info)->dynamic_sections_created - && (! info->shared - || ! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (input_section->flags & SEC_ALLOC) != 0 - && (r_type == R_68K_8 - || r_type == R_68K_16 - || r_type == R_68K_32 - || r_type == R_68K_PC8 - || r_type == R_68K_PC16 - || r_type == R_68K_PC32))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic) - relocation = 0; - else - { - if (!(info->callbacks->undefined_symbol - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - switch (r_type) - { - case R_68K_GOT8: - case R_68K_GOT16: - case R_68K_GOT32: - /* Relocation is to the address of the entry for this symbol - in the global offset table. */ - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_68K_GOT8O: - case R_68K_GOT16O: - case R_68K_GOT32O: - /* Relocation is the offset of the entry for this symbol in - the global offset table. */ - - { - bfd_vma off; - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (h != NULL) - { - off = h->got_offset; - BFD_ASSERT (off != (bfd_vma) -1); - - if (!elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global offset table. Since the offset must - always be a multiple of 4, we use the least - significant bit to record whether we have - initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - sgot->contents + off); - h->got_offset |= 1; - } - } - } - else - { - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 4. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, sgot->contents + off); - - if (info->shared) - { - asection *srelgot; - Elf_Internal_Rela outrel; - - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); - - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + off); - outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); - outrel.r_addend = relocation; - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; - } - - local_got_offsets[r_symndx] |= 1; - } - } - - relocation = sgot->output_offset + off; - if (r_type == R_68K_GOT8O - || r_type == R_68K_GOT16O - || r_type == R_68K_GOT32O) - { - /* This relocation does not use the addend. */ - rel->r_addend = 0; - } - else - relocation += sgot->output_section->vma; - } - break; - - case R_68K_PLT8: - case R_68K_PLT16: - case R_68K_PLT32: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - - /* Resolve a PLTxx reloc against a local symbol directly, - without using the procedure linkage table. */ - if (h == NULL) - break; - - if (h->plt_offset == (bfd_vma) -1) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - break; - - case R_68K_PLT8O: - case R_68K_PLT16O: - case R_68K_PLT32O: - /* Relocation is the offset of the entry for this symbol in - the procedure linkage table. */ - BFD_ASSERT (h != NULL && h->plt_offset == (bfd_vma) -1); - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = h->plt_offset; - - /* This relocation does not use the addend. */ - rel->r_addend = 0; - - break; - - case R_68K_PC8: - case R_68K_PC16: - case R_68K_PC32: - if (h == NULL) - break; - /* Fall through. */ - case R_68K_8: - case R_68K_16: - case R_68K_32: - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0 - && ((r_type != R_68K_PC8 - && r_type != R_68K_PC16 - && r_type != R_68K_PC32) - || (!info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))) - { - Elf_Internal_Rela outrel; - int relocate; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - BFD_ASSERT (h->dynindx != -1); - relocate = false; - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - outrel.r_addend = relocation + rel->r_addend; - } - else - { - if (r_type == R_68K_32) - { - relocate = true; - outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; - } - else - { - long indx; - - if (h == NULL) - sec = local_sections[r_symndx]; - else - { - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || (h->root.type - == bfd_link_hash_defweak)); - sec = h->root.u.def.section; - } - if (sec != NULL && bfd_is_abs_section (sec)) - indx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - asection *osec; - - osec = sec->output_section; - indx = elf_section_data (osec)->dynindx; - if (indx == 0) - abort (); - } - - relocate = false; - outrel.r_info = ELF32_R_INFO (indx, r_type); - outrel.r_addend = relocation + rel->r_addend; - } - } - - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - /* This reloc will be computed at runtime, so there's no - need to do anything now, except for R_68K_32 - relocations that have been turned into - R_68K_RELATIVE. */ - if (!relocate) - continue; - } - - break; - - default: - break; - } - - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (!(info->callbacks->reloc_overflow - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - - dynobj = elf_hash_table (info)->dynobj; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *sgot; - asection *srela; - bfd_vma plt_index; - bfd_vma got_offset; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); - - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = h->plt_offset / PLT_ENTRY_SIZE - 1; - - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; - - /* Fill in the entry in the procedure linkage table. */ - memcpy (splt->contents + h->plt_offset, elf_m68k_plt_entry, - PLT_ENTRY_SIZE); - /* The offset is relative to the first extension word. */ - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset - + got_offset - - (splt->output_section->vma - + h->plt_offset + 2)), - splt->contents + h->plt_offset + 4); - - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela), - splt->contents + h->plt_offset + 10); - bfd_put_32 (output_bfd, - (h->plt_offset + 16), - splt->contents + h->plt_offset + 16); - - /* Fill in the entry in the global offset table. */ - bfd_put_32 (output_bfd, - (splt->output_section->vma - + splt->output_offset - + h->plt_offset - + 8), - sgot->contents + got_offset); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset - + got_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_JMP_SLOT); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + plt_index)); - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if (h->got_offset != (bfd_vma) -1) - { - asection *sgot; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the global offset table. Set it - up. */ - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - srela = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (sgot != NULL && srela != NULL); - - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset - + (h->got_offset &~ 1)); - - /* If this is a -Bsymbolic link, and the symbol is defined - locally, we just want to emit a RELATIVE reloc. The entry in - the global offset table will already have been initialized in - the relocate_section function. */ - if (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - { - rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); - rela.r_addend = bfd_get_32 (output_bfd, - sgot->contents + (h->got_offset & ~1)); - } - else - { - bfd_put_32 (output_bfd, (bfd_vma) 0, - sgot->contents + (h->got_offset & ~1)); - rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT); - rela.r_addend = 0; - } - - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + srela->reloc_count)); - ++srela->reloc_count; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rela rela; - - /* This symbol needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); - BFD_ASSERT (s != NULL); - - rela.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_COPY); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -elf_m68k_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sgot; - asection *sdyn; - - dynobj = elf_hash_table (info)->dynobj; - - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (sgot != NULL); - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - asection *s; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - case DT_PLTGOT: - name = ".got"; - goto get_vma; - case DT_JMPREL: - name = ".rela.plt"; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_PLTRELSZ: - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - BFD_ASSERT (s != NULL); - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_RELASZ: - /* The procedure linkage table relocs (DT_JMPREL) should - not be included in the overall relocs (DT_RELA). - Therefore, we override the DT_RELASZ entry here to - make it not include the JMPREL relocs. Since the - linker script arranges for .rela.plt to follow all - other relocation sections, we don't have to worry - about changing the DT_RELA entry. */ - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - if (s != NULL) - { - if (s->_cooked_size != 0) - dyn.d_un.d_val -= s->_cooked_size; - else - dyn.d_un.d_val -= s->_raw_size; - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - } - } - - /* Fill in the first entry in the procedure linkage table. */ - if (splt->_raw_size > 0) - { - memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset + 4 - - (splt->output_section->vma + 2)), - splt->contents + 4); - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset + 8 - - (splt->output_section->vma + 10)), - splt->contents + 12); - } - - elf_section_data (splt->output_section)->this_hdr.sh_entsize - = PLT_ENTRY_SIZE; - } - - /* Fill in the first three entries in the global offset table. */ - if (sgot->_raw_size > 0) - { - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - return true; -} - -#define TARGET_BIG_SYM bfd_elf32_m68k_vec -#define TARGET_BIG_NAME "elf32-m68k" -#define ELF_MACHINE_CODE EM_68K -#define ELF_MAXPAGESIZE 0x2000 -#define elf_backend_create_dynamic_sections \ - _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs elf_m68k_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - elf_m68k_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - elf_m68k_size_dynamic_sections -#define elf_backend_relocate_section elf_m68k_relocate_section -#define elf_backend_finish_dynamic_symbol \ - elf_m68k_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - elf_m68k_finish_dynamic_sections -#define elf_backend_want_got_plt 1 -#define elf_backend_plt_readonly 1 -#define elf_backend_want_plt_sym 0 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-m88k.c b/contrib/gdb/bfd/elf32-m88k.c deleted file mode 100644 index f3c535e0776..00000000000 --- a/contrib/gdb/bfd/elf32-m88k.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Motorola 88k-specific support for 32-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocations, but should be good enough - for GDB. */ - -#define TARGET_BIG_SYM bfd_elf32_m88k_vec -#define TARGET_BIG_NAME "elf32-m88k" -#define ELF_ARCH bfd_arch_m88k -#define ELF_MACHINE_CODE EM_88K -#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-mips.c b/contrib/gdb/bfd/elf32-mips.c deleted file mode 100644 index ced0000e2c5..00000000000 --- a/contrib/gdb/bfd/elf32-mips.c +++ /dev/null @@ -1,5867 +0,0 @@ -/* MIPS-specific support for 32-bit ELF - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - - Most of the information added by Ian Lance Taylor, Cygnus Support, - . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file handles MIPS ELF targets. SGI Irix 5 uses a slightly - different MIPS ELF from other targets. This matters when linking. - This file supports both, switching at runtime. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "elf-bfd.h" -#include "elf/mips.h" - -/* Get the ECOFF swapping routines. */ -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/internal.h" -#include "coff/ecoff.h" -#include "coff/mips.h" -#define ECOFF_32 -#include "ecoffswap.h" - -static bfd_reloc_status_type mips_elf_hi16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_got16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_lo16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_gprel16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_gprel32_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void mips_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); -static void bfd_mips_elf32_swap_gptab_in - PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *)); -static void bfd_mips_elf32_swap_gptab_out - PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *)); -static boolean mips_elf_sym_is_global PARAMS ((bfd *, asymbol *)); -static boolean mips_elf_object_p PARAMS ((bfd *)); -static boolean mips_elf_create_procedure_table - PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *, - struct ecoff_debug_info *)); -static int mips_elf_additional_program_headers PARAMS ((bfd *)); -static boolean mips_elf_modify_segment_map PARAMS ((bfd *)); -static void mips_elf_final_write_processing - PARAMS ((bfd *, boolean)); -static boolean mips_elf_set_private_flags PARAMS ((bfd *, flagword)); -static boolean mips_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean mips_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean mips_elf_section_from_shdr - PARAMS ((bfd *, Elf32_Internal_Shdr *, char *)); -static boolean mips_elf_fake_sections - PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *)); -static boolean mips_elf_section_from_bfd_section - PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *)); -static boolean mips_elf_section_processing - PARAMS ((bfd *, Elf32_Internal_Shdr *)); -static void mips_elf_symbol_processing PARAMS ((bfd *, asymbol *)); -static boolean mips_elf_read_ecoff_info - PARAMS ((bfd *, asection *, struct ecoff_debug_info *)); -static boolean mips_elf_is_local_label - PARAMS ((bfd *, asymbol *)); -static boolean mips_elf_find_nearest_line - PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, - const char **, unsigned int *)); -static struct bfd_hash_entry *mips_elf_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *mips_elf_link_hash_table_create - PARAMS ((bfd *)); -static int gptab_compare PARAMS ((const void *, const void *)); -static boolean mips_elf_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -static void mips_elf_relocate_hi16 - PARAMS ((bfd *, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, - bfd_vma)); -static void mips_elf_relocate_got_local - PARAMS ((bfd *, bfd *, asection *, Elf_Internal_Rela *, - Elf_Internal_Rela *, bfd_byte *, bfd_vma)); -static void mips_elf_relocate_global_got - PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); -static boolean mips_elf_adjust_dynindx - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean mips_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean mips_elf_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_create_compact_rel_section - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_create_got_section - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean mips_elf_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean mips_elf_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean mips_elf_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); -static bfd_reloc_status_type mips_elf_final_gp - PARAMS ((bfd *, asymbol *, boolean, char **, bfd_vma *)); -static bfd_byte *elf32_mips_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); - -/* This is true for Irix 5 executables, false for normal MIPS ELF ABI - executables. FIXME: At the moment, we default to always generating - Irix 5 executables. */ - -#define SGI_COMPAT(abfd) (1) - -/* This structure is used to hold .got information when linking. It - is stored in the tdata field of the bfd_elf_section_data structure. */ - -struct mips_got_info -{ - /* The symbol index of the first global .got symbol. */ - unsigned long global_gotsym; - /* The number of local .got entries. */ - unsigned int local_gotno; -}; - -/* The number of local .got entries we reserve. */ -#define MIPS_RESERVED_GOTNO (2) - -/* Instructions which appear in a stub. For some reason the stub is - slightly different on an SGI system. */ -#define ELF_MIPS_GP_OFFSET(abfd) (SGI_COMPAT (abfd) ? 0x7ff0 : 0x8000) -#define STUB_LW(abfd) \ - (SGI_COMPAT (abfd) \ - ? 0x8f998010 /* lw t9,0x8010(gp) */ \ - : 0x8f998000) /* lw t9,0x8000(gp) */ -#define STUB_MOVE 0x03e07825 /* move t7,ra */ -#define STUB_JALR 0x0320f809 /* jal t9 */ -#define STUB_LI16 0x34180000 /* ori t8,zero,0 */ -#define MIPS_FUNCTION_STUB_SIZE (16) - -/* Names of sections which appear in the .dynsym section in an Irix 5 - executable. */ - -static const char * const mips_elf_dynsym_sec_names[] = -{ - ".text", - ".init", - ".fini", - ".data", - ".rodata", - ".sdata", - ".sbss", - ".bss", - NULL -}; - -#define SIZEOF_MIPS_DYNSYM_SECNAMES \ - (sizeof mips_elf_dynsym_sec_names / sizeof mips_elf_dynsym_sec_names[0]) - -/* The number of entries in mips_elf_dynsym_sec_names which go in the - text segment. */ - -#define MIPS_TEXT_DYNSYM_SECNO (3) - -/* The names of the runtime procedure table symbols used on Irix 5. */ - -static const char * const mips_elf_dynsym_rtproc_names[] = -{ - "_procedure_table", - "_procedure_string_table", - "_procedure_table_size", - NULL -}; - -/* These structures are used to generate the .compact_rel section on - Irix 5. */ - -typedef struct -{ - unsigned long id1; /* Always one? */ - unsigned long num; /* Number of compact relocation entries. */ - unsigned long id2; /* Always two? */ - unsigned long offset; /* The file offset of the first relocation. */ - unsigned long reserved0; /* Zero? */ - unsigned long reserved1; /* Zero? */ -} Elf32_compact_rel; - -typedef struct -{ - bfd_byte id1[4]; - bfd_byte num[4]; - bfd_byte id2[4]; - bfd_byte offset[4]; - bfd_byte reserved0[4]; - bfd_byte reserved1[4]; -} Elf32_External_compact_rel; - -typedef struct -{ - unsigned int ctype : 1; /* 1: long 0: short format. See below. */ - unsigned int rtype : 4; /* Relocation types. See below. */ - unsigned int dist2to : 8; - unsigned int relvaddr : 19; /* (VADDR - vaddr of the previous entry)/ 4 */ - unsigned long konst; /* KONST field. See below. */ - unsigned long vaddr; /* VADDR to be relocated. */ -} Elf32_crinfo; - -typedef struct -{ - unsigned int ctype : 1; /* 1: long 0: short format. See below. */ - unsigned int rtype : 4; /* Relocation types. See below. */ - unsigned int dist2to : 8; - unsigned int relvaddr : 19; /* (VADDR - vaddr of the previous entry)/ 4 */ - unsigned long konst; /* KONST field. See below. */ -} Elf32_crinfo2; - -typedef struct -{ - bfd_byte info[4]; - bfd_byte konst[4]; - bfd_byte vaddr[4]; -} Elf32_External_crinfo; - -typedef struct -{ - bfd_byte info[4]; - bfd_byte konst[4]; -} Elf32_External_crinfo2; - -/* These are the constants used to swap the bitfields in a crinfo. */ - -#define CRINFO_CTYPE (0x1) -#define CRINFO_CTYPE_SH (31) -#define CRINFO_RTYPE (0xf) -#define CRINFO_RTYPE_SH (27) -#define CRINFO_DIST2TO (0xff) -#define CRINFO_DIST2TO_SH (19) -#define CRINFO_RELVADDR (0x7ffff) -#define CRINFO_RELVADDR_SH (0) - -/* A compact relocation info has long (3 words) or short (2 words) - formats. A short format doesn't have VADDR field and relvaddr - fields contains ((VADDR - vaddr of the previous entry) >> 2). */ -#define CRF_MIPS_LONG 1 -#define CRF_MIPS_SHORT 0 - -/* There are 4 types of compact relocation at least. The value KONST - has different meaning for each type: - - (type) (konst) - CT_MIPS_REL32 Address in data - CT_MIPS_WORD Address in word (XXX) - CT_MIPS_GPHI_LO GP - vaddr - CT_MIPS_JMPAD Address to jump - */ - -#define CRT_MIPS_REL32 0xa -#define CRT_MIPS_WORD 0xb -#define CRT_MIPS_GPHI_LO 0xc -#define CRT_MIPS_JMPAD 0xd - -#define mips_elf_set_cr_format(x,format) ((x).ctype = (format)) -#define mips_elf_set_cr_type(x,type) ((x).rtype = (type)) -#define mips_elf_set_cr_dist2to(x,v) ((x).dist2to = (v)) -#define mips_elf_set_cr_relvaddr(x,d) ((x).relvaddr = (d)<<2) - -static void bfd_elf32_swap_compact_rel_out - PARAMS ((bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *)); -static void bfd_elf32_swap_crinfo_out - PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *)); - -#define USE_REL 1 /* MIPS uses REL relocations instead of RELA */ - -enum reloc_type -{ - R_MIPS_NONE = 0, - R_MIPS_16, R_MIPS_32, - R_MIPS_REL32, R_MIPS_26, - R_MIPS_HI16, R_MIPS_LO16, - R_MIPS_GPREL16, R_MIPS_LITERAL, - R_MIPS_GOT16, R_MIPS_PC16, - R_MIPS_CALL16, R_MIPS_GPREL32, - /* The remaining relocs are defined on Irix, although they are not - in the MIPS ELF ABI. */ - R_MIPS_UNUSED1, R_MIPS_UNUSED2, - R_MIPS_UNUSED3, - R_MIPS_SHIFT5, R_MIPS_SHIFT6, - R_MIPS_64, R_MIPS_GOT_DISP, - R_MIPS_GOT_PAGE, R_MIPS_GOT_OFST, - R_MIPS_GOT_HI16, R_MIPS_GOT_LO16, - R_MIPS_SUB, R_MIPS_INSERT_A, - R_MIPS_INSERT_B, R_MIPS_DELETE, - R_MIPS_HIGHER, R_MIPS_HIGHEST, - R_MIPS_CALL_HI16, R_MIPS_CALL_LO16, - R_MIPS_max -}; - -static reloc_howto_type elf_mips_howto_table[] = -{ - /* No relocation. */ - HOWTO (R_MIPS_NONE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_NONE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit relocation. */ - HOWTO (R_MIPS_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit relocation. */ - HOWTO (R_MIPS_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit symbol relative relocation. */ - HOWTO (R_MIPS_REL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_REL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 26 bit branch address. */ - HOWTO (R_MIPS_26, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - /* This needs complex overflow - detection, because the upper four - bits must match the PC. */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_26", /* name */ - true, /* partial_inplace */ - 0x3ffffff, /* src_mask */ - 0x3ffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* High 16 bits of symbol value. */ - HOWTO (R_MIPS_HI16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_elf_hi16_reloc, /* special_function */ - "R_MIPS_HI16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Low 16 bits of symbol value. */ - HOWTO (R_MIPS_LO16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_elf_lo16_reloc, /* special_function */ - "R_MIPS_LO16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* GP relative reference. */ - HOWTO (R_MIPS_GPREL16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_elf_gprel16_reloc, /* special_function */ - "R_MIPS_GPREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Reference to literal section. */ - HOWTO (R_MIPS_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_elf_gprel16_reloc, /* special_function */ - "R_MIPS_LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Reference to global offset table. */ - HOWTO (R_MIPS_GOT16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_elf_got16_reloc, /* special_function */ - "R_MIPS_GOT16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit PC relative reference. */ - HOWTO (R_MIPS_PC16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_PC16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit call through global offset table. */ - /* FIXME: This is not handled correctly. */ - HOWTO (R_MIPS_CALL16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_CALL16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit GP relative reference. */ - HOWTO (R_MIPS_GPREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_elf_gprel32_reloc, /* special_function */ - "R_MIPS_GPREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The remaining relocs are defined on Irix 5, although they are - not defined by the ABI. */ - { 13 }, - { 14 }, - { 15 }, - - /* A 5 bit shift field. */ - HOWTO (R_MIPS_SHIFT5, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 5, /* bitsize */ - false, /* pc_relative */ - 6, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_SHIFT5", /* name */ - true, /* partial_inplace */ - 0x000007c0, /* src_mask */ - 0x000007c0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 6 bit shift field. */ - /* FIXME: This is not handled correctly; a special function is - needed to put the most significant bit in the right place. */ - HOWTO (R_MIPS_SHIFT6, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 6, /* bitsize */ - false, /* pc_relative */ - 6, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_SHIFT6", /* name */ - true, /* partial_inplace */ - 0x000007c4, /* src_mask */ - 0x000007c4, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit relocation. Presumably not used in 32 bit ELF. */ - { R_MIPS_64 }, - - /* Displacement in the global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_DISP, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_DISP", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Displacement to page pointer in the global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_PAGE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_PAGE", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Offset from page pointer in the global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_OFST, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_OFST", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* High 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_HI16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_HI16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Low 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_LO16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_LO16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 64 bit subtraction. Presumably not used in 32 bit ELF. */ - { R_MIPS_SUB }, - - /* Used to cause the linker to insert and delete instructions? */ - { R_MIPS_INSERT_A }, - { R_MIPS_INSERT_B }, - { R_MIPS_DELETE }, - - /* Get the higher values of a 64 bit addend. Presumably not used in - 32 bit ELF. */ - { R_MIPS_HIGHER }, - { R_MIPS_HIGHEST }, - - /* High 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_CALL_HI16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_CALL_HI16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Low 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_CALL_LO16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_CALL_LO16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -/* Do a R_MIPS_HI16 relocation. This has to be done in combination - with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to - the HI16. Here we just save the information we need; we do the - actual relocation when we see the LO16. MIPS ELF requires that the - LO16 immediately follow the HI16, so this ought to work. */ - -static bfd_byte *mips_hi16_addr; -static bfd_vma mips_hi16_addend; - -static bfd_reloc_status_type -mips_elf_hi16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - - /* If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - ret = bfd_reloc_ok; - - if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - boolean relocateable; - bfd_vma gp; - - if (ret == bfd_reloc_undefined) - abort (); - - if (output_bfd != NULL) - relocateable = true; - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - } - - ret = mips_elf_final_gp (output_bfd, symbol, relocateable, - error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - - relocation = gp - reloc_entry->address; - } - else - { - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - } - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let LO16 do the actual relocation. */ - mips_hi16_addr = (bfd_byte *) data + reloc_entry->address; - mips_hi16_addend = relocation; - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit - inplace relocation; this function exists in order to do the - R_MIPS_HI16 relocation described above. */ - -static bfd_reloc_status_type -mips_elf_lo16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - arelent gp_disp_relent; - - if (mips_hi16_addr != (bfd_byte *) NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - - /* Do the HI16 relocation. Note that we actually don't need to - know anything about the LO16 itself, except where to find the - low 16 bits of the addend needed by the LO16. */ - insn = bfd_get_32 (abfd, mips_hi16_addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += mips_hi16_addend; - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the - data, and once for the bits we are putting back in to the - data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, insn, mips_hi16_addr); - - mips_hi16_addr = (bfd_byte *) NULL; - - if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - gp_disp_relent = *reloc_entry; - reloc_entry = &gp_disp_relent; - reloc_entry->addend = mips_hi16_addend; - } - } - else if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - bfd_reloc_status_type ret; - bfd_vma gp, relocation; - - /* FIXME: Does this case ever occur? */ - - ret = mips_elf_final_gp (output_bfd, symbol, true, error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - - relocation = gp - reloc_entry->address; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - gp_disp_relent = *reloc_entry; - reloc_entry = &gp_disp_relent; - reloc_entry->addend = relocation - 4; - } - - /* Now do the LO16 reloc in the usual way. */ - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset - table used for PIC code. If the symbol is an external symbol, the - instruction is modified to contain the offset of the appropriate - entry in the global offset table. If the symbol is a section - symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit - addends are combined to form the real addend against the section - symbol; the GOT16 is modified to contain the offset of an entry in - the global offset table, and the LO16 is modified to offset it - appropriately. Thus an offset larger than 16 bits requires a - modified value in the global offset table. - - This implementation suffices for the assembler, but the linker does - not yet know how to create global offset tables. */ - -static bfd_reloc_status_type -mips_elf_got16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If we're relocating, and this is a local symbol, we can handle it - just like HI16. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) != 0) - return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); - - abort (); -} - -/* We have to figure out the gp value, so that we can adjust the - symbol value correctly. We look up the symbol _gp in the output - BFD. If we can't find it, we're stuck. We cache it in the ELF - target data. We don't need to adjust the symbol value for an - external symbol if we are producing relocateable output. */ - -static bfd_reloc_status_type -mips_elf_final_gp (output_bfd, symbol, relocateable, error_message, pgp) - bfd *output_bfd; - asymbol *symbol; - boolean relocateable; - char **error_message; - bfd_vma *pgp; -{ - if (bfd_is_und_section (symbol->section) - && ! relocateable) - { - *pgp = 0; - return bfd_reloc_undefined; - } - - *pgp = _bfd_get_gp_value (output_bfd); - if (*pgp == 0 - && (! relocateable - || (symbol->flags & BSF_SECTION_SYM) != 0)) - { - if (relocateable) - { - /* Make up a value. */ - *pgp = symbol->section->output_section->vma + 0x4000; - _bfd_set_gp_value (output_bfd, *pgp); - } - else - { - unsigned int count; - asymbol **sym; - unsigned int i; - - count = bfd_get_symcount (output_bfd); - sym = bfd_get_outsymbols (output_bfd); - - if (sym == (asymbol **) NULL) - i = count; - else - { - for (i = 0; i < count; i++, sym++) - { - register CONST char *name; - - name = bfd_asymbol_name (*sym); - if (*name == '_' && strcmp (name, "_gp") == 0) - { - *pgp = bfd_asymbol_value (*sym); - _bfd_set_gp_value (output_bfd, *pgp); - break; - } - } - } - - if (i >= count) - { - /* Only get the error once. */ - *pgp = 4; - _bfd_set_gp_value (output_bfd, *pgp); - *error_message = - (char *) "GP relative relocation when _gp not defined"; - return bfd_reloc_dangerous; - } - } - } - - return bfd_reloc_ok; -} - -/* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must - become the offset from the gp register. This function also handles - R_MIPS_LITERAL relocations, although those can be handled more - cleverly because the entries in the .lit8 and .lit4 sections can be - merged. */ - -static bfd_reloc_status_type gprel16_with_gp PARAMS ((bfd *, asymbol *, - arelent *, asection *, - boolean, PTR, bfd_vma)); - -static bfd_reloc_status_type -mips_elf_gprel16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - boolean relocateable; - bfd_reloc_status_type ret; - bfd_vma gp; - - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ELF - file. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != (bfd *) NULL) - relocateable = true; - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - } - - ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message, - &gp); - if (ret != bfd_reloc_ok) - return ret; - - return gprel16_with_gp (abfd, symbol, reloc_entry, input_section, - relocateable, data, gp); -} - -static bfd_reloc_status_type -gprel16_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data, - gp) - bfd *abfd; - asymbol *symbol; - arelent *reloc_entry; - asection *input_section; - boolean relocateable; - PTR data; - bfd_vma gp; -{ - bfd_vma relocation; - unsigned long insn; - unsigned long val; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - - /* Set val to the offset into the section or symbol. */ - val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff; - if (val & 0x8000) - val -= 0x10000; - - /* Adjust val for the final section location and GP value. If we - are producing relocateable output, we don't want to do this for - an external symbol. */ - if (! relocateable - || (symbol->flags & BSF_SECTION_SYM) != 0) - val += relocation - gp; - - insn = (insn &~ 0xffff) | (val & 0xffff); - bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); - - if (relocateable) - reloc_entry->address += input_section->output_offset; - - /* Make sure it fit in 16 bits. */ - if (val >= 0x8000 && val < 0xffff8000) - return bfd_reloc_overflow; - - return bfd_reloc_ok; -} - -/* Do a R_MIPS_GPREL32 relocation. Is this 32 bit value the offset - from the gp register? XXX */ - -static bfd_reloc_status_type gprel32_with_gp PARAMS ((bfd *, asymbol *, - arelent *, asection *, - boolean, PTR, bfd_vma)); - -static bfd_reloc_status_type -mips_elf_gprel32_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - boolean relocateable; - bfd_reloc_status_type ret; - bfd_vma gp; - - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ELF - file. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - *error_message = (char *) - "32bits gp relative relocation occurs for an external symbol"; - return bfd_reloc_outofrange; - } - - if (output_bfd != (bfd *) NULL) - { - relocateable = true; - gp = _bfd_get_gp_value (output_bfd); - } - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - - ret = mips_elf_final_gp (output_bfd, symbol, relocateable, - error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - } - - return gprel32_with_gp (abfd, symbol, reloc_entry, input_section, - relocateable, data, gp); -} - -static bfd_reloc_status_type -gprel32_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data, - gp) - bfd *abfd; - asymbol *symbol; - arelent *reloc_entry; - asection *input_section; - boolean relocateable; - PTR data; - bfd_vma gp; -{ - bfd_vma relocation; - unsigned long val; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - - /* Set val to the offset into the section or symbol. */ - val += reloc_entry->addend; - - /* Adjust val for the final section location and GP value. If we - are producing relocateable output, we don't want to do this for - an external symbol. */ - if (! relocateable - || (symbol->flags & BSF_SECTION_SYM) != 0) - val += relocation - gp; - - bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address); - - if (relocateable) - reloc_entry->address += input_section->output_offset; - - return bfd_reloc_ok; -} - -/* A mapping from BFD reloc types to MIPS ELF reloc types. */ - -struct elf_reloc_map { - bfd_reloc_code_real_type bfd_reloc_val; - enum reloc_type elf_reloc_val; -}; - -static CONST struct elf_reloc_map mips_reloc_map[] = -{ - { BFD_RELOC_NONE, R_MIPS_NONE, }, - { BFD_RELOC_16, R_MIPS_16 }, - { BFD_RELOC_32, R_MIPS_32 }, - { BFD_RELOC_CTOR, R_MIPS_32 }, - { BFD_RELOC_32_PCREL, R_MIPS_REL32 }, - { BFD_RELOC_MIPS_JMP, R_MIPS_26 }, - { BFD_RELOC_HI16_S, R_MIPS_HI16 }, - { BFD_RELOC_LO16, R_MIPS_LO16 }, - { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 }, - { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL }, - { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 }, - { BFD_RELOC_16_PCREL, R_MIPS_PC16 }, - { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 }, - { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 }, - { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 }, - { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 }, - { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 }, - { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 } -}; - -/* Given a BFD reloc type, return a howto structure. */ - -static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - - for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++) - { - if (mips_reloc_map[i].bfd_reloc_val == code) - return &elf_mips_howto_table[(int) mips_reloc_map[i].elf_reloc_val]; - } - return NULL; -} - -/* Given a MIPS reloc type, fill in an arelent structure. */ - -static void -mips_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rel *dst; -{ - unsigned int r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_MIPS_max); - cache_ptr->howto = &elf_mips_howto_table[r_type]; - - /* The addend for a GPREL16 or LITERAL relocation comes from the GP - value for the object file. We get the addend now, rather than - when we do the relocation, because the symbol manipulations done - by the linker may cause us to lose track of the input BFD. */ - if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0 - && (r_type == (unsigned int) R_MIPS_GPREL16 - || r_type == (unsigned int) R_MIPS_LITERAL)) - cache_ptr->addend = elf_gp (abfd); -} - -/* A .reginfo section holds a single Elf32_RegInfo structure. These - routines swap this structure in and out. They are used outside of - BFD, so they are globally visible. */ - -void -bfd_mips_elf32_swap_reginfo_in (abfd, ex, in) - bfd *abfd; - const Elf32_External_RegInfo *ex; - Elf32_RegInfo *in; -{ - in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask); - in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]); - in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]); - in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]); - in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]); - in->ri_gp_value = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gp_value); -} - -void -bfd_mips_elf32_swap_reginfo_out (abfd, in, ex) - bfd *abfd; - const Elf32_RegInfo *in; - Elf32_External_RegInfo *ex; -{ - bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask, - (bfd_byte *) ex->ri_gprmask); - bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0], - (bfd_byte *) ex->ri_cprmask[0]); - bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1], - (bfd_byte *) ex->ri_cprmask[1]); - bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2], - (bfd_byte *) ex->ri_cprmask[2]); - bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3], - (bfd_byte *) ex->ri_cprmask[3]); - bfd_h_put_32 (abfd, (bfd_vma) in->ri_gp_value, - (bfd_byte *) ex->ri_gp_value); -} - -/* Swap an entry in a .gptab section. Note that these routines rely - on the equivalence of the two elements of the union. */ - -static void -bfd_mips_elf32_swap_gptab_in (abfd, ex, in) - bfd *abfd; - const Elf32_External_gptab *ex; - Elf32_gptab *in; -{ - in->gt_entry.gt_g_value = bfd_h_get_32 (abfd, ex->gt_entry.gt_g_value); - in->gt_entry.gt_bytes = bfd_h_get_32 (abfd, ex->gt_entry.gt_bytes); -} - -static void -bfd_mips_elf32_swap_gptab_out (abfd, in, ex) - bfd *abfd; - const Elf32_gptab *in; - Elf32_External_gptab *ex; -{ - bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_g_value, - ex->gt_entry.gt_g_value); - bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_bytes, - ex->gt_entry.gt_bytes); -} - -static void -bfd_elf32_swap_compact_rel_out (abfd, in, ex) - bfd *abfd; - const Elf32_compact_rel *in; - Elf32_External_compact_rel *ex; -{ - bfd_h_put_32 (abfd, (bfd_vma) in->id1, ex->id1); - bfd_h_put_32 (abfd, (bfd_vma) in->num, ex->num); - bfd_h_put_32 (abfd, (bfd_vma) in->id2, ex->id2); - bfd_h_put_32 (abfd, (bfd_vma) in->offset, ex->offset); - bfd_h_put_32 (abfd, (bfd_vma) in->reserved0, ex->reserved0); - bfd_h_put_32 (abfd, (bfd_vma) in->reserved1, ex->reserved1); -} - -static void -bfd_elf32_swap_crinfo_out (abfd, in, ex) - bfd *abfd; - const Elf32_crinfo *in; - Elf32_External_crinfo *ex; -{ - unsigned long l; - - l = (((in->ctype & CRINFO_CTYPE) << CRINFO_CTYPE_SH) - | ((in->rtype & CRINFO_RTYPE) << CRINFO_RTYPE_SH) - | ((in->dist2to & CRINFO_DIST2TO) << CRINFO_DIST2TO_SH) - | ((in->relvaddr & CRINFO_RELVADDR) << CRINFO_RELVADDR_SH)); - bfd_h_put_32 (abfd, (bfd_vma) l, ex->info); - bfd_h_put_32 (abfd, (bfd_vma) in->konst, ex->konst); - bfd_h_put_32 (abfd, (bfd_vma) in->vaddr, ex->vaddr); -} - -/* Determine whether a symbol is global for the purposes of splitting - the symbol table into global symbols and local symbols. At least - on Irix 5, this split must be between section symbols and all other - symbols. On most ELF targets the split is between static symbols - and externally visible symbols. */ - -/*ARGSUSED*/ -static boolean -mips_elf_sym_is_global (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false; -} - -/* Set the right machine number for a MIPS ELF file. */ - -static boolean -mips_elf_object_p (abfd) - bfd *abfd; -{ - switch (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) - { - default: - case E_MIPS_ARCH_1: - /* Just use the default, which was set in elfcode.h. */ - break; - - case E_MIPS_ARCH_2: - (void) bfd_default_set_arch_mach (abfd, bfd_arch_mips, 6000); - break; - - case E_MIPS_ARCH_3: - (void) bfd_default_set_arch_mach (abfd, bfd_arch_mips, 4000); - break; - } - - /* Irix 5 is broken. Object file symbol tables are not always - sorted correctly such that local symbols precede global symbols, - and the sh_info field in the symbol table is not always right. */ - elf_bad_symtab (abfd) = true; - - return true; -} - -/* The final processing done just before writing out a MIPS ELF object - file. This gets the MIPS architecture right based on the machine - number. */ - -/*ARGSUSED*/ -static void -mips_elf_final_write_processing (abfd, linker) - bfd *abfd; - boolean linker; -{ - unsigned long val; - unsigned int i; - Elf_Internal_Shdr **hdrpp; - - switch (bfd_get_mach (abfd)) - { - case 3000: - val = E_MIPS_ARCH_1; - break; - - case 6000: - val = E_MIPS_ARCH_2; - break; - - case 4000: - val = E_MIPS_ARCH_3; - break; - - default: - val = 0; - break; - } - - elf_elfheader (abfd)->e_flags &=~ EF_MIPS_ARCH; - elf_elfheader (abfd)->e_flags |= val; - - /* Set the sh_info field for .gptab sections. */ - for (i = 1, hdrpp = elf_elfsections (abfd) + 1; - i < elf_elfheader (abfd)->e_shnum; - i++, hdrpp++) - { - if ((*hdrpp)->sh_type == SHT_MIPS_GPTAB) - { - const char *name; - asection *sec; - - BFD_ASSERT ((*hdrpp)->bfd_section != NULL); - name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section); - BFD_ASSERT (name != NULL - && strncmp (name, ".gptab.", sizeof ".gptab." - 1) == 0); - sec = bfd_get_section_by_name (abfd, name + sizeof ".gptab" - 1); - BFD_ASSERT (sec != NULL); - (*hdrpp)->sh_info = elf_section_data (sec)->this_idx; - } - } -} - -/* Function to keep MIPS specific file flags like as EF_MIPS_PIC. */ - -static boolean -mips_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; -{ - BFD_ASSERT (!elf_flags_init (abfd) - || elf_elfheader (abfd)->e_flags == flags); - - elf_elfheader (abfd)->e_flags = flags; - elf_flags_init (abfd) = true; - return true; -} - -/* Copy backend specific data from one object module to another */ - -static boolean -mips_elf_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - BFD_ASSERT (!elf_flags_init (obfd) - || (elf_elfheader (obfd)->e_flags - == elf_elfheader (ibfd)->e_flags)); - - elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - elf_flags_init (obfd) = true; - return true; -} - -/* Merge backend specific data from an object file to the output - object file when linking. */ - -static boolean -mips_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - flagword old_flags; - flagword new_flags; - - /* Check if we have the same endianess */ - if (ibfd->xvec->byteorder != obfd->xvec->byteorder - && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) - { - (*_bfd_error_handler) - ("%s: compiled for a %s endian system and target is %s endian", - bfd_get_filename (ibfd), - bfd_big_endian (ibfd) ? "big" : "little", - bfd_big_endian (obfd) ? "big" : "little"); - - bfd_set_error (bfd_error_wrong_format); - return false; - } - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - new_flags = elf_elfheader (ibfd)->e_flags; - elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER; - old_flags = elf_elfheader (obfd)->e_flags; - - if (!elf_flags_init (obfd)) /* First call, no flags set */ - { - elf_flags_init (obfd) = true; - elf_elfheader (obfd)->e_flags = new_flags; - } - else if (((new_flags ^ old_flags) & ~EF_MIPS_NOREORDER) - == 0) /* Compatible flags are ok */ - ; - else /* Incompatible flags */ - { - /* Warn about -fPIC mismatch */ - if ((new_flags & EF_MIPS_PIC) != (old_flags & EF_MIPS_PIC)) - { - new_flags &= ~EF_MIPS_PIC; - (*_bfd_error_handler) - ("%s: needs all files compiled with -fPIC", - bfd_get_filename (ibfd)); - } - - if ((new_flags & EF_MIPS_CPIC) != (old_flags & EF_MIPS_CPIC)) - { - new_flags &= ~EF_MIPS_CPIC; - (*_bfd_error_handler) - ("%s: needs all files compiled with -mabicalls", - bfd_get_filename (ibfd)); - } - - /* Warn about any other mismatches */ - if (new_flags != old_flags) - (*_bfd_error_handler) - ("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)", - bfd_get_filename (ibfd), (unsigned long) new_flags, - (unsigned long) old_flags); - - bfd_set_error (bfd_error_bad_value); - return false; - } - - return true; -} - -/* Handle a MIPS specific section when reading an object file. This - is called when elfcode.h finds a section with an unknown type. - FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure - how to. */ - -static boolean -mips_elf_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - char *name; -{ - asection *newsect; - - /* There ought to be a place to keep ELF backend specific flags, but - at the moment there isn't one. We just keep track of the - sections by their name, instead. Fortunately, the ABI gives - suggested names for all the MIPS specific sections, so we will - probably get away with this. */ - switch (hdr->sh_type) - { - case SHT_MIPS_LIBLIST: - if (strcmp (name, ".liblist") != 0) - return false; - break; - case SHT_MIPS_MSYM: - if (strcmp (name, ".msym") != 0) - return false; - break; - case SHT_MIPS_CONFLICT: - if (strcmp (name, ".conflict") != 0) - return false; - break; - case SHT_MIPS_GPTAB: - if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) != 0) - return false; - break; - case SHT_MIPS_UCODE: - if (strcmp (name, ".ucode") != 0) - return false; - break; - case SHT_MIPS_DEBUG: - if (strcmp (name, ".mdebug") != 0) - return false; - break; - case SHT_MIPS_REGINFO: - if (strcmp (name, ".reginfo") != 0 - || hdr->sh_size != sizeof (Elf32_External_RegInfo)) - return false; - break; - case SHT_MIPS_OPTIONS: - if (strcmp (name, ".options") != 0) - return false; - break; - case SHT_MIPS_DWARF: - if (strncmp (name, ".debug_", sizeof ".debug_" - 1) != 0) - return false; - break; - case SHT_MIPS_EVENTS: - if (strncmp (name, ".MIPS.events.", sizeof ".MIPS.events." - 1) != 0) - return false; - break; - default: - return false; - } - - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; - newsect = hdr->bfd_section; - - if (hdr->sh_type == SHT_MIPS_DEBUG) - { - if (! bfd_set_section_flags (abfd, newsect, - (bfd_get_section_flags (abfd, newsect) - | SEC_DEBUGGING))) - return false; - } - - /* FIXME: We should record sh_info for a .gptab section. */ - - /* For a .reginfo section, set the gp value in the tdata information - from the contents of this section. We need the gp value while - processing relocs, so we just get it now. */ - if (hdr->sh_type == SHT_MIPS_REGINFO) - { - Elf32_External_RegInfo ext; - Elf32_RegInfo s; - - if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext, - (file_ptr) 0, sizeof ext)) - return false; - bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s); - elf_gp (abfd) = s.ri_gp_value; - } - - return true; -} - -/* Set the correct type for a MIPS ELF section. We do this by the - section name, which is a hack, but ought to work. */ - -static boolean -mips_elf_fake_sections (abfd, hdr, sec) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - asection *sec; -{ - register const char *name; - - name = bfd_get_section_name (abfd, sec); - - if (strcmp (name, ".liblist") == 0) - { - hdr->sh_type = SHT_MIPS_LIBLIST; - hdr->sh_info = sec->_raw_size / sizeof (Elf32_Lib); - /* FIXME: Set the sh_link field. */ - } - else if (strcmp (name, ".msym") == 0) - { - hdr->sh_type = SHT_MIPS_MSYM; - hdr->sh_entsize = 8; - /* FIXME: Set the sh_info field. */ - } - else if (strcmp (name, ".conflict") == 0) - hdr->sh_type = SHT_MIPS_CONFLICT; - else if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) == 0) - { - hdr->sh_type = SHT_MIPS_GPTAB; - hdr->sh_entsize = sizeof (Elf32_External_gptab); - /* The sh_info field is set in mips_elf_final_write_processing. */ - } - else if (strcmp (name, ".ucode") == 0) - hdr->sh_type = SHT_MIPS_UCODE; - else if (strcmp (name, ".mdebug") == 0) - { - hdr->sh_type = SHT_MIPS_DEBUG; - /* In a shared object on Irix 5.3, the .mdebug section has an - entsize of 0. FIXME: Does this matter? */ - if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0) - hdr->sh_entsize = 0; - else - hdr->sh_entsize = 1; - } - else if (strcmp (name, ".reginfo") == 0) - { - hdr->sh_type = SHT_MIPS_REGINFO; - /* In a shared object on Irix 5.3, the .reginfo section has an - entsize of 0x18. FIXME: Does this matter? */ - if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0) - hdr->sh_entsize = sizeof (Elf32_External_RegInfo); - else - hdr->sh_entsize = 1; - - /* Force the section size to the correct value, even if the - linker thinks it is larger. The link routine below will only - write out this much data for .reginfo. */ - hdr->sh_size = sec->_raw_size = sizeof (Elf32_External_RegInfo); - } - else if (SGI_COMPAT (abfd) - && (strcmp (name, ".hash") == 0 - || strcmp (name, ".dynamic") == 0 - || strcmp (name, ".dynstr") == 0)) - { - hdr->sh_entsize = 0; - hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES; - } - else if (strcmp (name, ".got") == 0 - || strcmp (name, ".sdata") == 0 - || strcmp (name, ".sbss") == 0 - || strcmp (name, ".lit4") == 0 - || strcmp (name, ".lit8") == 0) - hdr->sh_flags |= SHF_MIPS_GPREL; - else if (strcmp (name, ".options") == 0) - { - hdr->sh_type = SHT_MIPS_OPTIONS; - hdr->sh_entsize = 1; - } - else if (strncmp (name, ".debug_", sizeof ".debug_" - 1) == 0) - hdr->sh_type = SHT_MIPS_DWARF; - else if (strncmp (name, ".MIPS.events.", sizeof ".MIPS.events." - 1) == 0) - hdr->sh_type = SHT_MIPS_EVENTS; - - return true; -} - -/* Given a BFD section, try to locate the corresponding ELF section - index. */ - -static boolean -mips_elf_section_from_bfd_section (abfd, hdr, sec, retval) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - asection *sec; - int *retval; -{ - if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0) - { - *retval = SHN_MIPS_SCOMMON; - return true; - } - if (strcmp (bfd_get_section_name (abfd, sec), ".acommon") == 0) - { - *retval = SHN_MIPS_ACOMMON; - return true; - } - return false; -} - -/* Work over a section just before writing it out. We update the GP - value in the .reginfo section based on the value we are using. - FIXME: We recognize sections that need the SHF_MIPS_GPREL flag by - name; there has to be a better way. */ - -static boolean -mips_elf_section_processing (abfd, hdr) - bfd *abfd; - Elf32_Internal_Shdr *hdr; -{ - if (hdr->sh_type == SHT_MIPS_REGINFO) - { - bfd_byte buf[4]; - - BFD_ASSERT (hdr->sh_size == sizeof (Elf32_External_RegInfo)); - BFD_ASSERT (hdr->contents == NULL); - - if (bfd_seek (abfd, - hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4, - SEEK_SET) == -1) - return false; - bfd_h_put_32 (abfd, (bfd_vma) elf_gp (abfd), buf); - if (bfd_write (buf, (bfd_size_type) 1, (bfd_size_type) 4, abfd) != 4) - return false; - } - - if (hdr->bfd_section != NULL) - { - const char *name = bfd_get_section_name (abfd, hdr->bfd_section); - - if (strcmp (name, ".sdata") == 0) - { - hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; - hdr->sh_type = SHT_PROGBITS; - } - else if (strcmp (name, ".sbss") == 0) - { - hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; - hdr->sh_type = SHT_NOBITS; - } - else if (strcmp (name, ".lit8") == 0 - || strcmp (name, ".lit4") == 0) - { - hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; - hdr->sh_type = SHT_PROGBITS; - } - else if (strcmp (name, ".compact_rel") == 0) - { - hdr->sh_flags = 0; - hdr->sh_type = SHT_PROGBITS; - } - else if (strcmp (name, ".rtproc") == 0) - { - if (hdr->sh_addralign != 0 && hdr->sh_entsize == 0) - { - unsigned int adjust; - - adjust = hdr->sh_size % hdr->sh_addralign; - if (adjust != 0) - hdr->sh_size += hdr->sh_addralign - adjust; - } - } - } - - return true; -} - -/* MIPS ELF uses two common sections. One is the usual one, and the - other is for small objects. All the small objects are kept - together, and then referenced via the gp pointer, which yields - faster assembler code. This is what we use for the small common - section. This approach is copied from ecoff.c. */ -static asection mips_elf_scom_section; -static asymbol mips_elf_scom_symbol; -static asymbol *mips_elf_scom_symbol_ptr; - -/* MIPS ELF also uses an acommon section, which represents an - allocated common symbol which may be overridden by a - definition in a shared library. */ -static asection mips_elf_acom_section; -static asymbol mips_elf_acom_symbol; -static asymbol *mips_elf_acom_symbol_ptr; - -/* The Irix 5 support uses two virtual sections, which represent - text/data symbols defined in dynamic objects. */ -static asection mips_elf_text_section; -static asection *mips_elf_text_section_ptr; -static asymbol mips_elf_text_symbol; -static asymbol *mips_elf_text_symbol_ptr; - -static asection mips_elf_data_section; -static asection *mips_elf_data_section_ptr; -static asymbol mips_elf_data_symbol; -static asymbol *mips_elf_data_symbol_ptr; - -/* Handle the special MIPS section numbers that a symbol may use. */ - -static void -mips_elf_symbol_processing (abfd, asym) - bfd *abfd; - asymbol *asym; -{ - elf_symbol_type *elfsym; - - elfsym = (elf_symbol_type *) asym; - switch (elfsym->internal_elf_sym.st_shndx) - { - case SHN_MIPS_ACOMMON: - /* This section is used in a dynamically linked executable file. - It is an allocated common section. The dynamic linker can - either resolve these symbols to something in a shared - library, or it can just leave them here. For our purposes, - we can consider these symbols to be in a new section. */ - if (mips_elf_acom_section.name == NULL) - { - /* Initialize the acommon section. */ - mips_elf_acom_section.name = ".acommon"; - mips_elf_acom_section.flags = SEC_ALLOC; - mips_elf_acom_section.output_section = &mips_elf_acom_section; - mips_elf_acom_section.symbol = &mips_elf_acom_symbol; - mips_elf_acom_section.symbol_ptr_ptr = &mips_elf_acom_symbol_ptr; - mips_elf_acom_symbol.name = ".acommon"; - mips_elf_acom_symbol.flags = BSF_SECTION_SYM; - mips_elf_acom_symbol.section = &mips_elf_acom_section; - mips_elf_acom_symbol_ptr = &mips_elf_acom_symbol; - } - asym->section = &mips_elf_acom_section; - break; - - case SHN_COMMON: - /* Common symbols less than the GP size are automatically - treated as SHN_MIPS_SCOMMON symbols. */ - if (asym->value > elf_gp_size (abfd)) - break; - /* Fall through. */ - case SHN_MIPS_SCOMMON: - if (mips_elf_scom_section.name == NULL) - { - /* Initialize the small common section. */ - mips_elf_scom_section.name = ".scommon"; - mips_elf_scom_section.flags = SEC_IS_COMMON; - mips_elf_scom_section.output_section = &mips_elf_scom_section; - mips_elf_scom_section.symbol = &mips_elf_scom_symbol; - mips_elf_scom_section.symbol_ptr_ptr = &mips_elf_scom_symbol_ptr; - mips_elf_scom_symbol.name = ".scommon"; - mips_elf_scom_symbol.flags = BSF_SECTION_SYM; - mips_elf_scom_symbol.section = &mips_elf_scom_section; - mips_elf_scom_symbol_ptr = &mips_elf_scom_symbol; - } - asym->section = &mips_elf_scom_section; - asym->value = elfsym->internal_elf_sym.st_size; - break; - - case SHN_MIPS_SUNDEFINED: - asym->section = bfd_und_section_ptr; - break; - -#if 0 /* for SGI_COMPAT */ - case SHN_MIPS_TEXT: - asym->section = mips_elf_text_section_ptr; - break; - - case SHN_MIPS_DATA: - asym->section = mips_elf_data_section_ptr; - break; -#endif - } -} - -/* When creating an Irix 5 executable, we need REGINFO and RTPROC - segments. */ - -static int -mips_elf_additional_program_headers (abfd) - bfd *abfd; -{ - asection *s; - int ret; - - ret = 0; - - if (! SGI_COMPAT (abfd)) - return ret; - - s = bfd_get_section_by_name (abfd, ".reginfo"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - /* We need a PT_MIPS_REGINFO segment. */ - ++ret; - } - - if (bfd_get_section_by_name (abfd, ".dynamic") != NULL - && bfd_get_section_by_name (abfd, ".mdebug") != NULL) - { - /* We need a PT_MIPS_RTPROC segment. */ - ++ret; - } - - return ret; -} - -/* Modify the segment map for an Irix 5 executable. */ - -static boolean -mips_elf_modify_segment_map (abfd) - bfd *abfd; -{ - asection *s; - struct elf_segment_map *m, **pm; - - if (! SGI_COMPAT (abfd)) - return true; - - /* If there is a .reginfo section, we need a PT_MIPS_REGINFO - segment. */ - s = bfd_get_section_by_name (abfd, ".reginfo"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - if (m->p_type == PT_MIPS_REGINFO) - break; - if (m == NULL) - { - m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m); - if (m == NULL) - return false; - - m->p_type = PT_MIPS_REGINFO; - m->count = 1; - m->sections[0] = s; - - /* We want to put it after the PHDR and INTERP segments. */ - pm = &elf_tdata (abfd)->segment_map; - while (*pm != NULL - && ((*pm)->p_type == PT_PHDR - || (*pm)->p_type == PT_INTERP)) - pm = &(*pm)->next; - - m->next = *pm; - *pm = m; - } - } - - /* If there are .dynamic and .mdebug sections, we make a room for - the RTPROC header. FIXME: Rewrite without section names. */ - if (bfd_get_section_by_name (abfd, ".interp") == NULL - && bfd_get_section_by_name (abfd, ".dynamic") != NULL - && bfd_get_section_by_name (abfd, ".mdebug") != NULL) - { - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - if (m->p_type == PT_MIPS_RTPROC) - break; - if (m == NULL) - { - m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m); - if (m == NULL) - return false; - - m->p_type = PT_MIPS_RTPROC; - - s = bfd_get_section_by_name (abfd, ".rtproc"); - if (s == NULL) - { - m->count = 0; - m->p_flags = 0; - m->p_flags_valid = 1; - } - else - { - m->count = 1; - m->sections[0] = s; - } - - /* We want to put it after the DYNAMIC segment. */ - pm = &elf_tdata (abfd)->segment_map; - while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC) - pm = &(*pm)->next; - if (*pm != NULL) - pm = &(*pm)->next; - - m->next = *pm; - *pm = m; - } - } - - /* On Irix 5, the PT_DYNAMIC segment includes the .dynamic, .dynstr, - .dynsym, and .hash sections, and everything in between. */ - for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next) - if ((*pm)->p_type == PT_DYNAMIC) - break; - m = *pm; - if (m != NULL - && m->count == 1 - && strcmp (m->sections[0]->name, ".dynamic") == 0) - { - static const char *sec_names[] = - { ".dynamic", ".dynstr", ".dynsym", ".hash" }; - bfd_vma low, high; - unsigned int i, c; - struct elf_segment_map *n; - - low = 0xffffffff; - high = 0; - for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++) - { - s = bfd_get_section_by_name (abfd, sec_names[i]); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - bfd_size_type sz; - - if (low > s->vma) - low = s->vma; - sz = s->_cooked_size; - if (sz == 0) - sz = s->_raw_size; - if (high < s->vma + sz) - high = s->vma + sz; - } - } - - c = 0; - for (s = abfd->sections; s != NULL; s = s->next) - if ((s->flags & SEC_LOAD) != 0 - && s->vma >= low - && ((s->vma - + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size)) - <= high)) - ++c; - - n = ((struct elf_segment_map *) - bfd_zalloc (abfd, sizeof *n + (c - 1) * sizeof (asection *))); - if (n == NULL) - return false; - *n = *m; - n->count = c; - - i = 0; - for (s = abfd->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_LOAD) != 0 - && s->vma >= low - && ((s->vma - + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size)) - <= high)) - { - n->sections[i] = s; - ++i; - } - } - - *pm = n; - } - - return true; -} - -/* The structure of the runtime procedure descriptor created by the - loader for use by the static exception system. */ - -typedef struct runtime_pdr { - bfd_vma adr; /* memory address of start of procedure */ - long regmask; /* save register mask */ - long regoffset; /* save register offset */ - long fregmask; /* save floating point register mask */ - long fregoffset; /* save floating point register offset */ - long frameoffset; /* frame size */ - short framereg; /* frame pointer register */ - short pcreg; /* offset or reg of return pc */ - long irpss; /* index into the runtime string table */ - long reserved; - struct exception_info *exception_info;/* pointer to exception array */ -} RPDR, *pRPDR; -#define cbRPDR sizeof(RPDR) -#define rpdNil ((pRPDR) 0) - -/* Swap RPDR (runtime procedure table entry) for output. */ - -static void ecoff_swap_rpdr_out - PARAMS ((bfd *, const RPDR *, struct rpdr_ext *)); - -static void -ecoff_swap_rpdr_out (abfd, in, ex) - bfd *abfd; - const RPDR *in; - struct rpdr_ext *ex; -{ - /* ecoff_put_off was defined in ecoffswap.h. */ - ecoff_put_off (abfd, in->adr, (bfd_byte *) ex->p_adr); - bfd_h_put_32 (abfd, in->regmask, (bfd_byte *) ex->p_regmask); - bfd_h_put_32 (abfd, in->regoffset, (bfd_byte *) ex->p_regoffset); - bfd_h_put_32 (abfd, in->fregmask, (bfd_byte *) ex->p_fregmask); - bfd_h_put_32 (abfd, in->fregoffset, (bfd_byte *) ex->p_fregoffset); - bfd_h_put_32 (abfd, in->frameoffset, (bfd_byte *) ex->p_frameoffset); - - bfd_h_put_16 (abfd, in->framereg, (bfd_byte *) ex->p_framereg); - bfd_h_put_16 (abfd, in->pcreg, (bfd_byte *) ex->p_pcreg); - - bfd_h_put_32 (abfd, in->irpss, (bfd_byte *) ex->p_irpss); -#if 0 /* FIXME */ - ecoff_put_off (abfd, in->exception_info, (bfd_byte *) ex->p_exception_info); -#endif -} - -/* Read ECOFF debugging information from a .mdebug section into a - ecoff_debug_info structure. */ - -static boolean -mips_elf_read_ecoff_info (abfd, section, debug) - bfd *abfd; - asection *section; - struct ecoff_debug_info *debug; -{ - HDRR *symhdr; - const struct ecoff_debug_swap *swap; - char *ext_hdr = NULL; - - swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - - ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size); - if (ext_hdr == NULL && swap->external_hdr_size != 0) - goto error_return; - - if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, - swap->external_hdr_size) - == false) - goto error_return; - - symhdr = &debug->symbolic_header; - (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr); - - /* The symbolic header contains absolute file offsets and sizes to - read. */ -#define READ(ptr, offset, count, size, type) \ - if (symhdr->count == 0) \ - debug->ptr = NULL; \ - else \ - { \ - debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \ - if (debug->ptr == NULL) \ - goto error_return; \ - if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ - || (bfd_read (debug->ptr, size, symhdr->count, \ - abfd) != size * symhdr->count)) \ - goto error_return; \ - } - - READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); - READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); - READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); - READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); - READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); - READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), - union aux_ext *); - READ (ss, cbSsOffset, issMax, sizeof (char), char *); - READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); - READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); - READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); - READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR); -#undef READ - - debug->fdr = NULL; - debug->adjust = NULL; - - return true; - - error_return: - if (ext_hdr != NULL) - free (ext_hdr); - if (debug->line != NULL) - free (debug->line); - if (debug->external_dnr != NULL) - free (debug->external_dnr); - if (debug->external_pdr != NULL) - free (debug->external_pdr); - if (debug->external_sym != NULL) - free (debug->external_sym); - if (debug->external_opt != NULL) - free (debug->external_opt); - if (debug->external_aux != NULL) - free (debug->external_aux); - if (debug->ss != NULL) - free (debug->ss); - if (debug->ssext != NULL) - free (debug->ssext); - if (debug->external_fdr != NULL) - free (debug->external_fdr); - if (debug->external_rfd != NULL) - free (debug->external_rfd); - if (debug->external_ext != NULL) - free (debug->external_ext); - return false; -} - -/* MIPS ELF local labels start with '$', not 'L'. */ - -/*ARGSUSED*/ -static boolean -mips_elf_is_local_label (abfd, symbol) - bfd *abfd; - asymbol *symbol; -{ - return symbol->name[0] == '$'; -} - -/* MIPS ELF uses a special find_nearest_line routine in order the - handle the ECOFF debugging information. */ - -struct mips_elf_find_line -{ - struct ecoff_debug_info d; - struct ecoff_find_line i; -}; - -static boolean -mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr, - functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - const char **filename_ptr; - const char **functionname_ptr; - unsigned int *line_ptr; -{ - asection *msec; - - msec = bfd_get_section_by_name (abfd, ".mdebug"); - if (msec != NULL) - { - flagword origflags; - struct mips_elf_find_line *fi; - const struct ecoff_debug_swap * const swap = - get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - - /* If we are called during a link, mips_elf_final_link may have - cleared the SEC_HAS_CONTENTS field. We force it back on here - if appropriate (which it normally will be). */ - origflags = msec->flags; - if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS) - msec->flags |= SEC_HAS_CONTENTS; - - fi = elf_tdata (abfd)->find_line_info; - if (fi == NULL) - { - bfd_size_type external_fdr_size; - char *fraw_src; - char *fraw_end; - struct fdr *fdr_ptr; - - fi = ((struct mips_elf_find_line *) - bfd_alloc (abfd, sizeof (struct mips_elf_find_line))); - if (fi == NULL) - { - msec->flags = origflags; - return false; - } - - memset (fi, 0, sizeof (struct mips_elf_find_line)); - - if (! mips_elf_read_ecoff_info (abfd, msec, &fi->d)) - { - msec->flags = origflags; - return false; - } - - /* Swap in the FDR information. */ - fi->d.fdr = ((struct fdr *) - bfd_alloc (abfd, - (fi->d.symbolic_header.ifdMax * - sizeof (struct fdr)))); - if (fi->d.fdr == NULL) - { - msec->flags = origflags; - return false; - } - external_fdr_size = swap->external_fdr_size; - fdr_ptr = fi->d.fdr; - fraw_src = (char *) fi->d.external_fdr; - fraw_end = (fraw_src - + fi->d.symbolic_header.ifdMax * external_fdr_size); - for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) - (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); - - elf_tdata (abfd)->find_line_info = fi; - - /* Note that we don't bother to ever free this information. - find_nearest_line is either called all the time, as in - objdump -l, so the information should be saved, or it is - rarely called, as in ld error messages, so the memory - wasted is unimportant. Still, it would probably be a - good idea for free_cached_info to throw it away. */ - } - - if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap, - &fi->i, filename_ptr, functionname_ptr, - line_ptr)) - { - msec->flags = origflags; - return true; - } - - msec->flags = origflags; - } - - /* Fall back on the generic ELF find_nearest_line routine. */ - - return _bfd_elf_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, - line_ptr); -} - -/* The MIPS ELF linker needs additional information for each symbol in - the global hash table. */ - -struct mips_elf_link_hash_entry -{ - struct elf_link_hash_entry root; - - /* External symbol information. */ - EXTR esym; -}; - -/* MIPS ELF linker hash table. */ - -struct mips_elf_link_hash_table -{ - struct elf_link_hash_table root; - /* String section indices for the dynamic section symbols. */ - bfd_size_type dynsym_sec_strindex[SIZEOF_MIPS_DYNSYM_SECNAMES]; - /* The number of .rtproc entries. */ - bfd_size_type procedure_count; - /* The size of the .compact_rel section (if SGI_COMPAT). */ - bfd_size_type compact_rel_size; -}; - -/* Look up an entry in a MIPS ELF linker hash table. */ - -#define mips_elf_link_hash_lookup(table, string, create, copy, follow) \ - ((struct mips_elf_link_hash_entry *) \ - elf_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse a MIPS ELF linker hash table. */ - -#define mips_elf_link_hash_traverse(table, func, info) \ - (elf_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the MIPS ELF linker hash table from a link_info structure. */ - -#define mips_elf_hash_table(p) \ - ((struct mips_elf_link_hash_table *) ((p)->hash)) - -static boolean mips_elf_output_extsym - PARAMS ((struct mips_elf_link_hash_entry *, PTR)); - -/* Create an entry in a MIPS ELF linker hash table. */ - -static struct bfd_hash_entry * -mips_elf_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct mips_elf_link_hash_entry *ret = - (struct mips_elf_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct mips_elf_link_hash_entry *) NULL) - ret = ((struct mips_elf_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct mips_elf_link_hash_entry))); - if (ret == (struct mips_elf_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct mips_elf_link_hash_entry *) - _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct mips_elf_link_hash_entry *) NULL) - { - /* Set local fields. */ - memset (&ret->esym, 0, sizeof (EXTR)); - /* We use -2 as a marker to indicate that the information has - not been set. -1 means there is no associated ifd. */ - ret->esym.ifd = -2; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a MIPS ELF linker hash table. */ - -static struct bfd_link_hash_table * -mips_elf_link_hash_table_create (abfd) - bfd *abfd; -{ - struct mips_elf_link_hash_table *ret; - unsigned int i; - - ret = ((struct mips_elf_link_hash_table *) - bfd_alloc (abfd, sizeof (struct mips_elf_link_hash_table))); - if (ret == (struct mips_elf_link_hash_table *) NULL) - return NULL; - - if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, - mips_elf_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return NULL; - } - - for (i = 0; i < SIZEOF_MIPS_DYNSYM_SECNAMES; i++) - ret->dynsym_sec_strindex[i] = (bfd_size_type) -1; - ret->procedure_count = 0; - ret->compact_rel_size = 0; - - return &ret->root.root; -} - -/* Hook called by the linker routine which adds symbols from an object - file. We must handle the special MIPS section numbers here. */ - -/*ARGSUSED*/ -static boolean -mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp; - asection **secp; - bfd_vma *valp; -{ - if (SGI_COMPAT (abfd) - && (abfd->flags & DYNAMIC) != 0 - && strcmp (*namep, "_rld_new_interface") == 0) - { - /* Skip Irix 5 rld entry name. */ - *namep = NULL; - return true; - } - - switch (sym->st_shndx) - { - case SHN_COMMON: - /* Common symbols less than the GP size are automatically - treated as SHN_MIPS_SCOMMON symbols. */ - if (sym->st_size > elf_gp_size (abfd)) - break; - /* Fall through. */ - case SHN_MIPS_SCOMMON: - *secp = bfd_make_section_old_way (abfd, ".scommon"); - (*secp)->flags |= SEC_IS_COMMON; - *valp = sym->st_size; - break; - - case SHN_MIPS_TEXT: - /* This section is used in a shared object. */ - if (mips_elf_text_section_ptr == NULL) - { - /* Initialize the section. */ - mips_elf_text_section.name = ".text"; - mips_elf_text_section.flags = SEC_NO_FLAGS; - mips_elf_text_section.output_section = NULL; - mips_elf_text_section.owner = abfd; - mips_elf_text_section.symbol = &mips_elf_text_symbol; - mips_elf_text_section.symbol_ptr_ptr = &mips_elf_text_symbol_ptr; - mips_elf_text_symbol.name = ".text"; - mips_elf_text_symbol.flags = BSF_SECTION_SYM; - mips_elf_text_symbol.section = &mips_elf_text_section; - mips_elf_text_symbol_ptr = &mips_elf_text_symbol; - mips_elf_text_section_ptr = &mips_elf_text_section; - } - if (info->shared) - *secp = bfd_und_section_ptr; - else - *secp = mips_elf_text_section_ptr; - break; - - case SHN_MIPS_ACOMMON: - /* Fall through. XXX Can we treat this as allocated data? */ - case SHN_MIPS_DATA: - /* This section is used in a shared object. */ - if (mips_elf_data_section_ptr == NULL) - { - /* Initialize the section. */ - mips_elf_data_section.name = ".data"; - mips_elf_data_section.flags = SEC_NO_FLAGS; - mips_elf_data_section.output_section = NULL; - mips_elf_data_section.owner = abfd; - mips_elf_data_section.symbol = &mips_elf_data_symbol; - mips_elf_data_section.symbol_ptr_ptr = &mips_elf_data_symbol_ptr; - mips_elf_data_symbol.name = ".data"; - mips_elf_data_symbol.flags = BSF_SECTION_SYM; - mips_elf_data_symbol.section = &mips_elf_data_section; - mips_elf_data_symbol_ptr = &mips_elf_data_symbol; - mips_elf_data_section_ptr = &mips_elf_data_section; - } - if (info->shared) - *secp = bfd_und_section_ptr; - else - *secp = mips_elf_data_section_ptr; - break; - - case SHN_MIPS_SUNDEFINED: - *secp = bfd_und_section_ptr; - break; - } - - return true; -} - -/* Structure used to pass information to mips_elf_output_extsym. */ - -struct extsym_info -{ - bfd *abfd; - struct bfd_link_info *info; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - boolean failed; -}; - -/* This routine is used to write out ECOFF debugging external symbol - information. It is called via mips_elf_link_hash_traverse. The - ECOFF external symbol information must match the ELF external - symbol information. Unfortunately, at this point we don't know - whether a symbol is required by reloc information, so the two - tables may wind up being different. We must sort out the external - symbol information before we can set the final size of the .mdebug - section, and we must set the size of the .mdebug section before we - can relocate any sections, and we can't know which symbols are - required by relocation until we relocate the sections. - Fortunately, it is relatively unlikely that any symbol will be - stripped but required by a reloc. In particular, it can not happen - when generating a final executable. */ - -static boolean -mips_elf_output_extsym (h, data) - struct mips_elf_link_hash_entry *h; - PTR data; -{ - struct extsym_info *einfo = (struct extsym_info *) data; - boolean strip; - asection *sec, *output_section; - - if (h->root.indx == -2) - strip = false; - else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - strip = true; - else if (einfo->info->strip == strip_all - || (einfo->info->strip == strip_some - && bfd_hash_lookup (einfo->info->keep_hash, - h->root.root.root.string, - false, false) == NULL)) - strip = true; - else - strip = false; - - if (strip) - return true; - - if (h->esym.ifd == -2) - { - h->esym.jmptbl = 0; - h->esym.cobol_main = 0; - h->esym.weakext = 0; - h->esym.reserved = 0; - h->esym.ifd = ifdNil; - h->esym.asym.value = 0; - h->esym.asym.st = stGlobal; - - if (SGI_COMPAT (einfo->abfd) - && (h->root.root.type == bfd_link_hash_undefined - || h->root.root.type == bfd_link_hash_undefweak)) - { - const char *name; - - /* Use undefined class. Also, set class and type for some - special symbols. */ - name = h->root.root.root.string; - if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0 - || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0) - { - h->esym.asym.sc = scData; - h->esym.asym.st = stLabel; - h->esym.asym.value = 0; - } - else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0) - { - h->esym.asym.sc = scAbs; - h->esym.asym.st = stLabel; - h->esym.asym.value = - mips_elf_hash_table (einfo->info)->procedure_count; - } - else if (strcmp (name, "_gp_disp") == 0) - { - h->esym.asym.sc = scAbs; - h->esym.asym.st = stLabel; - h->esym.asym.value = elf_gp (einfo->abfd); - } - else - h->esym.asym.sc = scUndefined; - } - else if (h->root.root.type != bfd_link_hash_defined - && h->root.root.type != bfd_link_hash_defweak) - h->esym.asym.sc = scAbs; - else - { - const char *name; - - sec = h->root.root.u.def.section; - output_section = sec->output_section; - - /* When making a shared library and symbol h is the one from - the another shared library, OUTPUT_SECTION may be null. */ - if (output_section == NULL) - h->esym.asym.sc = scUndefined; - else - { - name = bfd_section_name (output_section->owner, output_section); - - if (strcmp (name, ".text") == 0) - h->esym.asym.sc = scText; - else if (strcmp (name, ".data") == 0) - h->esym.asym.sc = scData; - else if (strcmp (name, ".sdata") == 0) - h->esym.asym.sc = scSData; - else if (strcmp (name, ".rodata") == 0 - || strcmp (name, ".rdata") == 0) - h->esym.asym.sc = scRData; - else if (strcmp (name, ".bss") == 0) - h->esym.asym.sc = scBss; - else if (strcmp (name, ".sbss") == 0) - h->esym.asym.sc = scSBss; - else if (strcmp (name, ".init") == 0) - h->esym.asym.sc = scInit; - else if (strcmp (name, ".fini") == 0) - h->esym.asym.sc = scFini; - else - h->esym.asym.sc = scAbs; - } - } - - h->esym.asym.reserved = 0; - h->esym.asym.index = indexNil; - } - - if (h->root.root.type == bfd_link_hash_common) - h->esym.asym.value = h->root.root.u.c.size; - else if (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - { - if (h->esym.asym.sc == scCommon) - h->esym.asym.sc = scBss; - else if (h->esym.asym.sc == scSCommon) - h->esym.asym.sc = scSBss; - - sec = h->root.root.u.def.section; - output_section = sec->output_section; - if (output_section != NULL) - h->esym.asym.value = (h->root.root.u.def.value - + sec->output_offset - + output_section->vma); - else - h->esym.asym.value = 0; - } - else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - /* Set type and value for a symbol with a function stub. */ - h->esym.asym.st = stProc; - sec = h->root.root.u.def.section; - if (sec == NULL) - h->esym.asym.value = 0; - else - { - output_section = sec->output_section; - if (output_section != NULL) - h->esym.asym.value = (h->root.plt_offset - + sec->output_offset - + output_section->vma); - else - h->esym.asym.value = 0; - } -#if 0 /* FIXME? */ - h->esym.ifd = 0; -#endif - } - - if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap, - h->root.root.root.string, - &h->esym)) - { - einfo->failed = true; - return false; - } - - return true; -} - -/* Create a runtime procedure table from the .mdebug section. */ - -static boolean -mips_elf_create_procedure_table (handle, abfd, info, s, debug) - PTR handle; - bfd *abfd; - struct bfd_link_info *info; - asection *s; - struct ecoff_debug_info *debug; -{ - const struct ecoff_debug_swap *swap; - HDRR *hdr = &debug->symbolic_header; - RPDR *rpdr, *rp; - struct rpdr_ext *erp; - PTR rtproc; - struct pdr_ext *epdr; - struct sym_ext *esym; - char *ss, **sv; - char *str; - unsigned long size, count; - unsigned long sindex; - unsigned long i; - PDR pdr; - SYMR sym; - const char *no_name_func = "static procedure (no name)"; - - epdr = NULL; - rpdr = NULL; - esym = NULL; - ss = NULL; - sv = NULL; - - swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - - sindex = strlen (no_name_func) + 1; - count = hdr->ipdMax; - if (count > 0) - { - size = swap->external_pdr_size; - - epdr = (struct pdr_ext *) bfd_malloc (size * count); - if (epdr == NULL) - goto error_return; - - if (! _bfd_ecoff_get_accumulated_pdr (handle, (PTR) epdr)) - goto error_return; - - size = sizeof (RPDR); - rp = rpdr = (RPDR *) bfd_malloc (size * count); - if (rpdr == NULL) - goto error_return; - - sv = (char **) bfd_malloc (sizeof (char *) * count); - if (sv == NULL) - goto error_return; - - count = hdr->isymMax; - size = swap->external_sym_size; - esym = (struct sym_ext *) bfd_malloc (size * count); - if (esym == NULL) - goto error_return; - - if (! _bfd_ecoff_get_accumulated_sym (handle, (PTR) esym)) - goto error_return; - - count = hdr->issMax; - ss = (char *) bfd_malloc (count); - if (ss == NULL) - goto error_return; - if (! _bfd_ecoff_get_accumulated_ss (handle, (PTR) ss)) - goto error_return; - - count = hdr->ipdMax; - for (i = 0; i < count; i++, rp++) - { - (*swap->swap_pdr_in) (abfd, (PTR) (epdr + i), &pdr); - (*swap->swap_sym_in) (abfd, (PTR) &esym[pdr.isym], &sym); - rp->adr = sym.value; - rp->regmask = pdr.regmask; - rp->regoffset = pdr.regoffset; - rp->fregmask = pdr.fregmask; - rp->fregoffset = pdr.fregoffset; - rp->frameoffset = pdr.frameoffset; - rp->framereg = pdr.framereg; - rp->pcreg = pdr.pcreg; - rp->irpss = sindex; - sv[i] = ss + sym.iss; - sindex += strlen (sv[i]) + 1; - } - } - - size = sizeof (struct rpdr_ext) * (count + 2) + sindex; - size = BFD_ALIGN (size, 16); - rtproc = (PTR) bfd_alloc (abfd, size); - if (rtproc == NULL) - { - mips_elf_hash_table (info)->procedure_count = 0; - goto error_return; - } - - mips_elf_hash_table (info)->procedure_count = count + 2; - - erp = (struct rpdr_ext *) rtproc; - memset (erp, 0, sizeof (struct rpdr_ext)); - erp++; - str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2); - strcpy (str, no_name_func); - str += strlen (no_name_func) + 1; - for (i = 0; i < count; i++) - { - ecoff_swap_rpdr_out (abfd, rpdr + i, erp + i); - strcpy (str, sv[i]); - str += strlen (sv[i]) + 1; - } - ecoff_put_off (abfd, (bfd_vma) -1, (bfd_byte *) (erp + count)->p_adr); - - /* Set the size and contents of .rtproc section. */ - s->_raw_size = size; - s->contents = rtproc; - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - s->link_order_head = (struct bfd_link_order *) NULL; - - if (epdr != NULL) - free (epdr); - if (rpdr != NULL) - free (rpdr); - if (esym != NULL) - free (esym); - if (ss != NULL) - free (ss); - if (sv != NULL) - free (sv); - - return true; - - error_return: - if (epdr != NULL) - free (epdr); - if (rpdr != NULL) - free (rpdr); - if (esym != NULL) - free (esym); - if (ss != NULL) - free (ss); - if (sv != NULL) - free (sv); - return false; -} - -/* A comparison routine used to sort .gptab entries. */ - -static int -gptab_compare (p1, p2) - const PTR p1; - const PTR p2; -{ - const Elf32_gptab *a1 = (const Elf32_gptab *) p1; - const Elf32_gptab *a2 = (const Elf32_gptab *) p2; - - return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value; -} - -/* We need to use a special link routine to handle the .reginfo and - the .mdebug sections. We need to merge all instances of these - sections together, not write them all out sequentially. */ - -static boolean -mips_elf_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - asection **secpp; - asection *o; - struct bfd_link_order *p; - asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec; - asection *rtproc_sec; - Elf32_RegInfo reginfo; - struct ecoff_debug_info debug; - const struct ecoff_debug_swap *swap - = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - HDRR *symhdr = &debug.symbolic_header; - PTR mdebug_handle = NULL; - - /* Drop the .options section, since it has special semantics which I - haven't bothered to figure out. */ - for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next) - { - if (strcmp ((*secpp)->name, ".options") == 0) - { - for (p = (*secpp)->link_order_head; p != NULL; p = p->next) - if (p->type == bfd_indirect_link_order) - p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS; - (*secpp)->link_order_head = NULL; - *secpp = (*secpp)->next; - --abfd->section_count; - break; - } - } - - /* Get a value for the GP register. */ - if (elf_gp (abfd) == 0) - { - struct bfd_link_hash_entry *h; - - h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_defined) - elf_gp (abfd) = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - else if (info->relocateable) - { - bfd_vma lo; - - /* Make up a value. */ - lo = (bfd_vma) -1; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - if (o->vma < lo - && (strcmp (o->name, ".sbss") == 0 - || strcmp (o->name, ".sdata") == 0 - || strcmp (o->name, ".lit4") == 0 - || strcmp (o->name, ".lit8") == 0)) - lo = o->vma; - } - elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (abfd); - } - else - { - /* If the relocate_section function needs to do a reloc - involving the GP value, it should make a reloc_dangerous - callback to warn that GP is not defined. */ - } - } - - /* Go through the sections and collect the .reginfo and .mdebug - information. */ - reginfo_sec = NULL; - mdebug_sec = NULL; - gptab_data_sec = NULL; - gptab_bss_sec = NULL; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - if (strcmp (o->name, ".reginfo") == 0) - { - memset (®info, 0, sizeof reginfo); - - /* We have found the .reginfo section in the output file. - Look through all the link_orders comprising it and merge - the information together. */ - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - bfd *input_bfd; - Elf32_External_RegInfo ext; - Elf32_RegInfo sub; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - - /* The linker emulation code has probably clobbered the - size to be zero bytes. */ - if (input_section->_raw_size == 0) - input_section->_raw_size = sizeof (Elf32_External_RegInfo); - - if (! bfd_get_section_contents (input_bfd, input_section, - (PTR) &ext, - (file_ptr) 0, - sizeof ext)) - return false; - - bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub); - - reginfo.ri_gprmask |= sub.ri_gprmask; - reginfo.ri_cprmask[0] |= sub.ri_cprmask[0]; - reginfo.ri_cprmask[1] |= sub.ri_cprmask[1]; - reginfo.ri_cprmask[2] |= sub.ri_cprmask[2]; - reginfo.ri_cprmask[3] |= sub.ri_cprmask[3]; - - /* ri_gp_value is set by the function - mips_elf_section_processing when the section is - finally written out. */ - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - /* Force the section size to the value we want. */ - o->_raw_size = sizeof (Elf32_External_RegInfo); - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - - reginfo_sec = o; - } - - if (strcmp (o->name, ".mdebug") == 0) - { - struct extsym_info einfo; - - /* We have found the .mdebug section in the output file. - Look through all the link_orders comprising it and merge - the information together. */ - symhdr->magic = swap->sym_magic; - /* FIXME: What should the version stamp be? */ - symhdr->vstamp = 0; - symhdr->ilineMax = 0; - symhdr->cbLine = 0; - symhdr->idnMax = 0; - symhdr->ipdMax = 0; - symhdr->isymMax = 0; - symhdr->ioptMax = 0; - symhdr->iauxMax = 0; - symhdr->issMax = 0; - symhdr->issExtMax = 0; - symhdr->ifdMax = 0; - symhdr->crfd = 0; - symhdr->iextMax = 0; - - /* We accumulate the debugging information itself in the - debug_info structure. */ - debug.line = NULL; - debug.external_dnr = NULL; - debug.external_pdr = NULL; - debug.external_sym = NULL; - debug.external_opt = NULL; - debug.external_aux = NULL; - debug.ss = NULL; - debug.ssext = debug.ssext_end = NULL; - debug.external_fdr = NULL; - debug.external_rfd = NULL; - debug.external_ext = debug.external_ext_end = NULL; - - mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info); - if (mdebug_handle == (PTR) NULL) - return false; - - if (SGI_COMPAT (abfd)) - { - asection *s; - EXTR esym; - bfd_vma last; - unsigned int i; - static const char * const name[] = - { ".text", ".init", ".fini", ".data", - ".rodata", ".sdata", ".sbss", ".bss" }; - static const int sc[] = { scText, scInit, scFini, scData, - scRData, scSData, scSBss, scBss }; - - esym.jmptbl = 0; - esym.cobol_main = 0; - esym.weakext = 0; - esym.reserved = 0; - esym.ifd = ifdNil; - esym.asym.iss = issNil; - esym.asym.st = stLocal; - esym.asym.reserved = 0; - esym.asym.index = indexNil; - for (i = 0; i < 8; i++) - { - esym.asym.sc = sc[i]; - s = bfd_get_section_by_name (abfd, name[i]); - if (s != NULL) - { - esym.asym.value = s->vma; - last = s->vma + s->_raw_size; - } - else - esym.asym.value = last; - - if (! bfd_ecoff_debug_one_external (abfd, &debug, swap, - name[i], &esym)) - return false; - } - } - - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - bfd *input_bfd; - const struct ecoff_debug_swap *input_swap; - struct ecoff_debug_info input_debug; - char *eraw_src; - char *eraw_end; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - - if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour - || (get_elf_backend_data (input_bfd) - ->elf_backend_ecoff_debug_swap) == NULL) - { - /* I don't know what a non MIPS ELF bfd would be - doing with a .mdebug section, but I don't really - want to deal with it. */ - continue; - } - - input_swap = (get_elf_backend_data (input_bfd) - ->elf_backend_ecoff_debug_swap); - - BFD_ASSERT (p->size == input_section->_raw_size); - - /* The ECOFF linking code expects that we have already - read in the debugging information and set up an - ecoff_debug_info structure, so we do that now. */ - if (! mips_elf_read_ecoff_info (input_bfd, input_section, - &input_debug)) - return false; - - if (! (bfd_ecoff_debug_accumulate - (mdebug_handle, abfd, &debug, swap, input_bfd, - &input_debug, input_swap, info))) - return false; - - /* Loop through the external symbols. For each one with - interesting information, try to find the symbol in - the linker global hash table and save the information - for the output external symbols. */ - eraw_src = input_debug.external_ext; - eraw_end = (eraw_src - + (input_debug.symbolic_header.iextMax - * input_swap->external_ext_size)); - for (; - eraw_src < eraw_end; - eraw_src += input_swap->external_ext_size) - { - EXTR ext; - const char *name; - struct mips_elf_link_hash_entry *h; - - (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext); - if (ext.asym.sc == scNil - || ext.asym.sc == scUndefined - || ext.asym.sc == scSUndefined) - continue; - - name = input_debug.ssext + ext.asym.iss; - h = mips_elf_link_hash_lookup (mips_elf_hash_table (info), - name, false, false, true); - if (h == NULL || h->esym.ifd != -2) - continue; - - if (ext.ifd != -1) - { - BFD_ASSERT (ext.ifd - < input_debug.symbolic_header.ifdMax); - ext.ifd = input_debug.ifdmap[ext.ifd]; - } - - h->esym = ext; - } - - /* Free up the information we just read. */ - free (input_debug.line); - free (input_debug.external_dnr); - free (input_debug.external_pdr); - free (input_debug.external_sym); - free (input_debug.external_opt); - free (input_debug.external_aux); - free (input_debug.ss); - free (input_debug.ssext); - free (input_debug.external_fdr); - free (input_debug.external_rfd); - free (input_debug.external_ext); - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - if (SGI_COMPAT (abfd) && info->shared) - { - /* Create .rtproc section. */ - rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc"); - if (rtproc_sec == NULL) - { - flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_READONLY); - - rtproc_sec = bfd_make_section (abfd, ".rtproc"); - if (rtproc_sec == NULL - || ! bfd_set_section_flags (abfd, rtproc_sec, flags) - || ! bfd_set_section_alignment (abfd, rtproc_sec, 12)) - return false; - } - - if (! mips_elf_create_procedure_table (mdebug_handle, abfd, - info, rtproc_sec, &debug)) - return false; - } - - /* Build the external symbol information. */ - einfo.abfd = abfd; - einfo.info = info; - einfo.debug = &debug; - einfo.swap = swap; - einfo.failed = false; - mips_elf_link_hash_traverse (mips_elf_hash_table (info), - mips_elf_output_extsym, - (PTR) &einfo); - if (einfo.failed) - return false; - - /* Set the size of the .mdebug section. */ - o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap); - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - - mdebug_sec = o; - } - - if (strncmp (o->name, ".gptab.", sizeof ".gptab." - 1) == 0) - { - const char *subname; - unsigned int c; - Elf32_gptab *tab; - Elf32_External_gptab *ext_tab; - unsigned int i; - - /* The .gptab.sdata and .gptab.sbss sections hold - information describing how the small data area would - change depending upon the -G switch. These sections - not used in executables files. */ - if (! info->relocateable) - { - asection **secpp; - - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - /* Skip this section later on (I don't think this - currently matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - - /* Really remove the section. */ - for (secpp = &abfd->sections; - *secpp != o; - secpp = &(*secpp)->next) - ; - *secpp = (*secpp)->next; - --abfd->section_count; - - continue; - } - - /* There is one gptab for initialized data, and one for - uninitialized data. */ - if (strcmp (o->name, ".gptab.sdata") == 0) - gptab_data_sec = o; - else if (strcmp (o->name, ".gptab.sbss") == 0) - gptab_bss_sec = o; - else - { - (*_bfd_error_handler) - ("%s: illegal section name `%s'", - bfd_get_filename (abfd), o->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - - /* The linker script always combines .gptab.data and - .gptab.sdata into .gptab.sdata, and likewise for - .gptab.bss and .gptab.sbss. It is possible that there is - no .sdata or .sbss section in the output file, in which - case we must change the name of the output section. */ - subname = o->name + sizeof ".gptab" - 1; - if (bfd_get_section_by_name (abfd, subname) == NULL) - { - if (o == gptab_data_sec) - o->name = ".gptab.data"; - else - o->name = ".gptab.bss"; - subname = o->name + sizeof ".gptab" - 1; - BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL); - } - - /* Set up the first entry. */ - c = 1; - tab = (Elf32_gptab *) bfd_malloc (c * sizeof (Elf32_gptab)); - if (tab == NULL) - return false; - tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd); - tab[0].gt_header.gt_unused = 0; - - /* Combine the input sections. */ - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - bfd *input_bfd; - bfd_size_type size; - unsigned long last; - bfd_size_type gpentry; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - - /* Combine the gptab entries for this input section one - by one. We know that the input gptab entries are - sorted by ascending -G value. */ - size = bfd_section_size (input_bfd, input_section); - last = 0; - for (gpentry = sizeof (Elf32_External_gptab); - gpentry < size; - gpentry += sizeof (Elf32_External_gptab)) - { - Elf32_External_gptab ext_gptab; - Elf32_gptab int_gptab; - unsigned long val; - unsigned long add; - boolean exact; - unsigned int look; - - if (! (bfd_get_section_contents - (input_bfd, input_section, (PTR) &ext_gptab, - gpentry, sizeof (Elf32_External_gptab)))) - { - free (tab); - return false; - } - - bfd_mips_elf32_swap_gptab_in (input_bfd, &ext_gptab, - &int_gptab); - val = int_gptab.gt_entry.gt_g_value; - add = int_gptab.gt_entry.gt_bytes - last; - - exact = false; - for (look = 1; look < c; look++) - { - if (tab[look].gt_entry.gt_g_value >= val) - tab[look].gt_entry.gt_bytes += add; - - if (tab[look].gt_entry.gt_g_value == val) - exact = true; - } - - if (! exact) - { - Elf32_gptab *new_tab; - unsigned int max; - - /* We need a new table entry. */ - new_tab = ((Elf32_gptab *) - bfd_realloc ((PTR) tab, - (c + 1) * sizeof (Elf32_gptab))); - if (new_tab == NULL) - { - free (tab); - return false; - } - tab = new_tab; - tab[c].gt_entry.gt_g_value = val; - tab[c].gt_entry.gt_bytes = add; - - /* Merge in the size for the next smallest -G - value, since that will be implied by this new - value. */ - max = 0; - for (look = 1; look < c; look++) - { - if (tab[look].gt_entry.gt_g_value < val - && (max == 0 - || (tab[look].gt_entry.gt_g_value - > tab[max].gt_entry.gt_g_value))) - max = look; - } - if (max != 0) - tab[c].gt_entry.gt_bytes += - tab[max].gt_entry.gt_bytes; - - ++c; - } - - last = int_gptab.gt_entry.gt_bytes; - } - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - /* The table must be sorted by -G value. */ - if (c > 2) - qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare); - - /* Swap out the table. */ - ext_tab = ((Elf32_External_gptab *) - bfd_alloc (abfd, c * sizeof (Elf32_External_gptab))); - if (ext_tab == NULL) - { - free (tab); - return false; - } - - for (i = 0; i < c; i++) - bfd_mips_elf32_swap_gptab_out (abfd, tab + i, ext_tab + i); - free (tab); - - o->_raw_size = c * sizeof (Elf32_External_gptab); - o->contents = (bfd_byte *) ext_tab; - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - } - } - - /* Invoke the regular ELF backend linker to do all the work. */ - if (! bfd_elf32_bfd_final_link (abfd, info)) - return false; - - /* Now write out the computed sections. */ - - if (reginfo_sec != (asection *) NULL) - { - Elf32_External_RegInfo ext; - - bfd_mips_elf32_swap_reginfo_out (abfd, ®info, &ext); - if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext, - (file_ptr) 0, sizeof ext)) - return false; - } - - if (mdebug_sec != (asection *) NULL) - { - BFD_ASSERT (abfd->output_has_begun); - if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug, - swap, info, - mdebug_sec->filepos)) - return false; - - bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info); - } - - if (gptab_data_sec != (asection *) NULL) - { - if (! bfd_set_section_contents (abfd, gptab_data_sec, - gptab_data_sec->contents, - (file_ptr) 0, - gptab_data_sec->_raw_size)) - return false; - } - - if (gptab_bss_sec != (asection *) NULL) - { - if (! bfd_set_section_contents (abfd, gptab_bss_sec, - gptab_bss_sec->contents, - (file_ptr) 0, - gptab_bss_sec->_raw_size)) - return false; - } - - if (SGI_COMPAT (abfd)) - { - rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc"); - if (rtproc_sec != NULL) - { - if (! bfd_set_section_contents (abfd, rtproc_sec, - rtproc_sec->contents, - (file_ptr) 0, - rtproc_sec->_raw_size)) - return false; - } - } - - return true; -} - -/* Handle a MIPS ELF HI16 reloc. */ - -static void -mips_elf_relocate_hi16 (input_bfd, relhi, rello, contents, addend) - bfd *input_bfd; - Elf_Internal_Rela *relhi; - Elf_Internal_Rela *rello; - bfd_byte *contents; - bfd_vma addend; -{ - bfd_vma insn; - bfd_vma addlo; - - insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); - - addlo = bfd_get_32 (input_bfd, contents + rello->r_offset); - addlo &= 0xffff; - - addend += ((insn & 0xffff) << 16) + addlo; - - if ((addlo & 0x8000) != 0) - addend -= 0x10000; - if ((addend & 0x8000) != 0) - addend += 0x10000; - - bfd_put_32 (input_bfd, - (insn & 0xffff0000) | ((addend >> 16) & 0xffff), - contents + relhi->r_offset); -} - -/* Handle a MIPS ELF local GOT16 reloc. */ - -static void -mips_elf_relocate_got_local (output_bfd, input_bfd, sgot, relhi, rello, - contents, addend) - bfd *output_bfd; - bfd *input_bfd; - asection *sgot; - Elf_Internal_Rela *relhi; - Elf_Internal_Rela *rello; - bfd_byte *contents; - bfd_vma addend; -{ - int local_gotno; - int i; - bfd_vma insn; - bfd_vma addlo; - bfd_vma address; - bfd_vma hipage; - bfd_byte *got_contents; - struct mips_got_info *g; - - insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); - - addlo = bfd_get_32 (input_bfd, contents + rello->r_offset); - addlo &= 0xffff; - - addend += ((insn & 0xffff) << 16) + addlo; - - if ((addlo & 0x8000) != 0) - addend -= 0x10000; - if ((addend & 0x8000) != 0) - addend += 0x10000; - - /* Get a got entry representing requested hipage. */ - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - local_gotno = g->local_gotno; - got_contents = sgot->contents; - hipage = addend & 0xffff0000; - - for (i = MIPS_RESERVED_GOTNO; i < local_gotno; i++) - { - address = bfd_get_32 (input_bfd, got_contents + i * 4); - if (hipage == (address & 0xffff0000)) - break; - if (address == (bfd_vma) 0) - { - bfd_put_32 (input_bfd, hipage, got_contents + i * 4); - break; - } - } - - BFD_ASSERT (i < local_gotno); -#if 1 - if (i == local_gotno) - (*_bfd_error_handler) - ("ELF MIPS linker: more got entries are needed for hipage: %x", - hipage); -#endif - - i = - ELF_MIPS_GP_OFFSET (output_bfd) + i * 4; - bfd_put_32 (input_bfd, (insn & 0xffff0000) | (i & 0xffff), - contents + relhi->r_offset); -} - -/* Handle MIPS ELF CALL16 reloc and global GOT16 reloc. */ - -static void -mips_elf_relocate_global_got (input_bfd, rel, contents, offset) - bfd *input_bfd; - Elf_Internal_Rela *rel; - bfd_byte *contents; - bfd_vma offset; -{ - bfd_vma insn; - - insn = bfd_get_32 (input_bfd, contents + rel->r_offset); - bfd_put_32 (input_bfd, - (insn & 0xffff0000) | (offset & 0xffff), - contents + rel->r_offset); -} - -/* Relocate a MIPS ELF section. */ - -static boolean -mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr; - size_t locsymcount; - size_t extsymoff; - asection *sgot, *sreloc, *scpt; - bfd *dynobj; - bfd_vma gp; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - struct mips_got_info *g; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - - sgot = NULL; - sreloc = NULL; - if (dynobj == NULL || ! SGI_COMPAT (output_bfd)) - scpt = NULL; - else - scpt = bfd_get_section_by_name (dynobj, ".compact_rel"); - g = NULL; - - if (elf_bad_symtab (input_bfd)) - { - locsymcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym); - extsymoff = 0; - } - else - { - locsymcount = symtab_hdr->sh_info; - extsymoff = symtab_hdr->sh_info; - } - - gp = _bfd_get_gp_value (output_bfd); - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - bfd_vma addend; - struct elf_link_hash_entry *h; - asection *sec; - Elf_Internal_Sym *sym; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_MIPS_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = elf_mips_howto_table + r_type; - - if (dynobj != NULL - && (r_type == R_MIPS_CALL16 - || r_type == R_MIPS_GOT16 - || r_type == R_MIPS_CALL_HI16 - || r_type == R_MIPS_CALL_LO16 - || r_type == R_MIPS_GOT_HI16 - || r_type == R_MIPS_GOT_LO16)) - { - /* We need the .got section. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - } - } - - r_symndx = ELF32_R_SYM (rel->r_info); - - /* Mix in the change in GP address for a GP relative reloc. */ - if (r_type != R_MIPS_GPREL16 - && r_type != R_MIPS_LITERAL - && r_type != R_MIPS_GPREL32) - addend = 0; - else - { - if (gp == 0) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, - "GP relative relocation when GP not defined", - input_bfd, input_section, - rel->r_offset))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - } - - if (r_symndx < extsymoff - || (elf_bad_symtab (input_bfd) - && local_sections[r_symndx] != NULL)) - { - /* This is a relocation against a section. The current - addend in the instruction is the difference between - INPUT_SECTION->vma and the GP value of INPUT_BFD. We - must change this to be the difference between the - final definition (which will end up in RELOCATION) - and the GP value of OUTPUT_BFD (which is in GP). */ - addend = elf_gp (input_bfd) - gp; - } - else if (! info->relocateable) - { - /* We are doing a final link. The current addend in the - instruction is simply the desired offset into the - symbol (normally zero). We want the instruction to - hold the difference between the final definition of - the symbol (which will end up in RELOCATION) and the - GP value of OUTPUT_BFD (which is in GP). */ - addend = - gp; - } - else - { - /* We are generating relocateable output, and we aren't - going to define this symbol, so we just leave the - instruction alone. */ - addend = 0; - } - } - - h = NULL; - sym = NULL; - sec = NULL; - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && local_sections[r_symndx] == NULL)) - r = bfd_reloc_ok; - else - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) - r = bfd_reloc_ok; - else - { - sec = local_sections[r_symndx]; - - /* It would be logical to add sym->st_value here, - but Irix 5 sometimes generates a garbage symbol - value. */ - addend += sec->output_offset; - - /* If this is HI16 or GOT16 with an associated LO16, - adjust the addend accordingly. Otherwise, just - relocate. */ - if ((r_type != R_MIPS_HI16 && r_type != R_MIPS_GOT16) - || (rel + 1) >= relend - || ELF32_R_TYPE ((rel + 1)->r_info) != R_MIPS_LO16) - r = _bfd_relocate_contents (howto, input_bfd, - addend, - contents + rel->r_offset); - else - { - mips_elf_relocate_hi16 (input_bfd, rel, rel + 1, - contents, addend); - r = bfd_reloc_ok; - } - } - } - } - else - { - bfd_vma relocation; - boolean local; - - /* This is a final link. */ - sym = NULL; - if (r_symndx < extsymoff - || (elf_bad_symtab (input_bfd) - && local_sections[r_symndx] != NULL)) - { - local = true; - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset); - - /* It would be logical to always add sym->st_value here, - but Irix 5 sometimes generates a garbage symbol - value. */ - if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) - relocation += sym->st_value; - } - else - { - long indx; - - local = false; - indx = r_symndx - extsymoff; - h = elf_sym_hashes (input_bfd)[indx]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (strcmp (h->root.root.string, "_gp_disp") == 0) - { - if (gp == 0) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, - "_gp_disp used when GP not defined", - input_bfd, input_section, - rel->r_offset))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - relocation = 0; - } - else - { - sec = input_section; - if (sec->output_section != NULL) - relocation = (gp - - (rel->r_offset - + sec->output_section->vma - + sec->output_offset)); - else - relocation = gp - rel->r_offset; - if (r_type == R_MIPS_LO16) - relocation += 4; - } - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - relocation = 0; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && ! info->symbolic) - relocation = 0; - else if (strcmp (h->root.root.string, "_DYNAMIC_LINK") == 0) - { - /* If this is a dynamic link, we should have created - a _DYNAMIC_LINK symbol in - mips_elf_create_dynamic_sections. Otherwise, we - should define the symbol with a value of 0. - FIXME: It should probably get into the symbol - table somehow as well. */ - BFD_ASSERT (! info->shared); - BFD_ASSERT (bfd_get_section_by_name (output_bfd, - ".dynamic") == NULL); - relocation = 0; - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - if (r_type == R_MIPS_HI16 - && (rel + 1) < relend - && ELF32_R_TYPE ((rel + 1)->r_info) == R_MIPS_LO16) - { - mips_elf_relocate_hi16 (input_bfd, rel, rel + 1, - contents, relocation + addend); - r = bfd_reloc_ok; - } - else if (r_type == R_MIPS_GOT16 && local) - { - /* GOT16 must be also with associated LO16 in the local - case. In this case, the addend is extracted and the - section in which the referenced object is determined. - Then the final address of the object is computed and - the GOT entry for the hipage (an aligned 64kb chunk) - is added to .got section if needed. The offset field - of the GOT16-relocated instruction is replaced by the - index of this GOT entry for the hipage. */ - if ((rel + 1) < relend - && ELF32_R_TYPE ((rel + 1)->r_info) == R_MIPS_LO16) - { - mips_elf_relocate_got_local (output_bfd, input_bfd, sgot, - rel, rel + 1, - contents, - relocation + addend); - r = bfd_reloc_ok; - } - else - r = bfd_reloc_outofrange; - } - else if (r_type == R_MIPS_CALL16 - || r_type == R_MIPS_GOT16 - || r_type == R_MIPS_CALL_LO16 - || r_type == R_MIPS_GOT_LO16) - { - bfd_vma offset; - - /* This symbol must be registered as a global symbol - having the corresponding got entry. */ - BFD_ASSERT (h->got_offset != (bfd_vma) -1); - - offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4; - BFD_ASSERT (g->local_gotno <= offset - && offset < sgot->_raw_size); - bfd_put_32 (output_bfd, relocation + addend, - sgot->contents + offset); - offset = (sgot->output_section->vma + sgot->output_offset - + offset - gp); - mips_elf_relocate_global_got (input_bfd, rel, contents, - offset); - r = bfd_reloc_ok; - } - else if (r_type == R_MIPS_CALL_HI16 - || r_type == R_MIPS_GOT_HI16) - { - bfd_vma offset; - - /* This must be a global symbol with a got entry. The - next reloc must be the corresponding LO16 reloc. */ - BFD_ASSERT (h != NULL && h->got_offset != (bfd_vma) -1); - BFD_ASSERT ((rel + 1) < relend); - BFD_ASSERT (ELF32_R_TYPE ((rel + 1)->r_info) - == (r_type == R_MIPS_CALL_HI16 - ? R_MIPS_CALL_LO16 - : R_MIPS_GOT_LO16)); - - offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4; - BFD_ASSERT (g->local_gotno <= offset - && offset < sgot->_raw_size); - bfd_put_32 (output_bfd, relocation + addend, - sgot->contents + offset); - offset = (sgot->output_section->vma + sgot->output_offset - + offset - gp); - mips_elf_relocate_hi16 (input_bfd, rel, rel + 1, contents, - offset); - r = bfd_reloc_ok; - } - else if (r_type == R_MIPS_REL32 - || r_type == R_MIPS_32) - { - Elf_Internal_Rel outrel; - Elf32_crinfo cptrel; - bfd_byte *cr; - - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0) - { - /* When generating a shared object, these - relocations are copied into the output file to be - resolved at run time. */ - if (sreloc == NULL) - { - sreloc = bfd_get_section_by_name (dynobj, ".rel.dyn"); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - - addend = bfd_get_32 (input_bfd, contents + rel->r_offset); - - if (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - BFD_ASSERT (h->dynindx != -1); - outrel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_REL32); - sec = input_section; - } - else - { - long indx; - - if (h == NULL) - sec = local_sections[r_symndx]; - else - { - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || (h->root.type - == bfd_link_hash_defweak)); - sec = h->root.u.def.section; - } - if (sec != NULL && bfd_is_abs_section (sec)) - indx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - asection *osec; - - osec = sec->output_section; - indx = elf_section_data (osec)->dynindx; - if (indx == 0) - abort (); - } - - outrel.r_info = ELF32_R_INFO (indx, R_MIPS_REL32); - addend += relocation; - } - - bfd_put_32 (output_bfd, addend, contents + rel->r_offset); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, - (((Elf32_External_Rel *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - if (SGI_COMPAT (output_bfd)) - { - if (scpt == NULL) - continue; - - /* Make an entry of compact relocation info. */ - mips_elf_set_cr_format (cptrel, CRF_MIPS_LONG); - cptrel.vaddr = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (r_type == R_MIPS_REL32) - mips_elf_set_cr_type (cptrel, CRT_MIPS_REL32); - else - mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD); - mips_elf_set_cr_dist2to (cptrel, 0); - cptrel.konst = addend; - - cr = (scpt->contents - + sizeof (Elf32_External_compact_rel)); - bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, - ((Elf32_External_crinfo *) cr - + scpt->reloc_count)); - ++scpt->reloc_count; - } - - /* This reloc will be computed at runtime, so - there's no need to do anything now. */ - continue; - } - else - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, addend); - } - else - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, addend); - - if (SGI_COMPAT (abfd) - && scpt != NULL - && (input_section->flags & SEC_ALLOC) != 0) - { - Elf32_crinfo cptrel; - bfd_byte *cr; - - /* Make an entry of compact relocation info. */ - mips_elf_set_cr_format (cptrel, CRF_MIPS_LONG); - cptrel.vaddr = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - - switch (r_type) - { - case R_MIPS_26: - mips_elf_set_cr_type (cptrel, CRT_MIPS_JMPAD); - /* XXX How should we set dist2to in this case. */ - mips_elf_set_cr_dist2to (cptrel, 8); - cptrel.konst = addend + relocation; - cr = scpt->contents + sizeof (Elf32_External_compact_rel); - bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, - ((Elf32_External_crinfo *) cr - + scpt->reloc_count)); - ++scpt->reloc_count; - break; - - case R_MIPS_GPREL16: - case R_MIPS_LITERAL: - case R_MIPS_GPREL32: - mips_elf_set_cr_type (cptrel, CRT_MIPS_GPHI_LO); - cptrel.konst = gp - cptrel.vaddr; - mips_elf_set_cr_dist2to (cptrel, 4); - cr = scpt->contents + sizeof (Elf32_External_compact_rel); - bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, - ((Elf32_External_crinfo *) cr - + scpt->reloc_count)); - ++scpt->reloc_count; - break; - - default: - break; - } - } - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Functions for the dynamic linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* Create dynamic sections when linking against a dynamic object. */ - -static boolean -mips_elf_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - struct elf_link_hash_entry *h; - flagword flags; - register asection *s; - const char * const *namep; - - flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_READONLY); - - /* Mips ABI requests the .dynamic section to be read only. */ - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - if (! bfd_set_section_flags (abfd, s, flags)) - return false; - } - - /* We need to create .got section. */ - if (! mips_elf_create_got_section (abfd, info)) - return false; - - /* Create .stub section. */ - if (bfd_get_section_by_name (abfd, ".stub") == NULL) - { - s = bfd_make_section (abfd, ".stub"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - } - - if (SGI_COMPAT (abfd)) - { - for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++) - { - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_SECTION; - - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - /* We need to create a .compact_rel section. */ - if (! mips_elf_create_compact_rel_section (abfd, info)) - return false; - - /* Change aligments of some sections. */ - s = bfd_get_section_by_name (abfd, ".hash"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".dynstr"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".reginfo"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - } - - if (!info->shared) - { - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags ^=~ ELF_LINK_NON_ELF; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_SECTION; - - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - return true; -} - -/* Create the .compact_rel section. */ - -static boolean -mips_elf_create_compact_rel_section (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - - if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL) - { - flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY; - - s = bfd_make_section (abfd, ".compact_rel"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - s->_raw_size = sizeof (Elf32_External_compact_rel); - } - - return true; -} - -/* Create the .got section to hold the global offset table. */ - -static boolean -mips_elf_create_got_section (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - struct mips_got_info *g; - - /* This function may be called more than once. */ - if (bfd_get_section_by_name (abfd, ".got") != NULL) - return true; - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - s = bfd_make_section (abfd, ".got"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 4)) - return false; - - /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the - linker script because we don't want to define the symbol if we - are not creating a global offset table. */ - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - - /* The first several global offset table entries are reserved. */ - s->_raw_size = MIPS_RESERVED_GOTNO * 4; - - g = (struct mips_got_info *) bfd_alloc (abfd, - sizeof (struct mips_got_info)); - if (g == NULL) - return false; - g->global_gotsym = 0; - g->local_gotno = MIPS_RESERVED_GOTNO; - if (elf_section_data (s) == NULL) - { - s->used_by_bfd = - (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data)); - if (elf_section_data (s) == NULL) - return false; - } - elf_section_data (s)->tdata = (PTR) g; - - return true; -} - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table. */ - -static boolean -mips_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - struct mips_got_info *g; - size_t extsymoff; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info; - - sgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (r_symndx < extsymoff) - h = NULL; - else - h = sym_hashes[r_symndx - extsymoff]; - - /* Some relocs require a global offset table. */ - if (dynobj == NULL) - { - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_MIPS_GOT16: - case R_MIPS_CALL16: - case R_MIPS_CALL_HI16: - case R_MIPS_CALL_LO16: - case R_MIPS_GOT_HI16: - case R_MIPS_GOT_LO16: - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! mips_elf_create_got_section (dynobj, info)) - return false; - break; - - default: - break; - } - } - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_MIPS_CALL16: - case R_MIPS_CALL_HI16: - case R_MIPS_CALL_LO16: - /* This symbol requires a global offset table entry. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - } - - BFD_ASSERT (h != NULL); - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - - /* Note the index of the first global got symbol in .dynsym. */ - if (g->global_gotsym == 0 - || g->global_gotsym > (unsigned long) h->dynindx) - g->global_gotsym = h->dynindx; - - /* Make this symbol to have the corresponding got entry. */ - h->got_offset = 0; - - /* We need a stub, not a plt entry for the undefined - function. But we record it as if it needs plt. See - elf_adjust_dynamic_symbol in elflink.h. */ - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - h->type = STT_FUNC; - - break; - - case R_MIPS_GOT16: - case R_MIPS_GOT_HI16: - case R_MIPS_GOT_LO16: - /* This symbol requires a global offset table entry. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - } - - if (h != NULL) - { - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - /* Note the index of the first global got symbol in - .dynsym. */ - if (g->global_gotsym == 0 - || g->global_gotsym > (unsigned long) h->dynindx) - g->global_gotsym = h->dynindx; - - /* Make this symbol to be the global got symbol. */ - h->got_offset = 0; - } - - break; - - case R_MIPS_32: - case R_MIPS_REL32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0) - { - /* When creating a shared object, we must copy these - reloc types into the output file as R_MIPS_REL32 - relocs. We create the .rel.dyn reloc section in - dynobj and make room for this reloc. */ - if (sreloc == NULL) - { - const char *name = ".rel.dyn"; - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 4)) - return false; - - /* Add a null element. */ - sreloc->_raw_size += sizeof (Elf32_External_Rel); - ++sreloc->reloc_count; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rel); - } - - if (SGI_COMPAT (abfd)) - mips_elf_hash_table (info)->compact_rel_size += - sizeof (Elf32_External_crinfo); - - break; - - case R_MIPS_26: - case R_MIPS_GPREL16: - case R_MIPS_LITERAL: - case R_MIPS_GPREL32: - if (SGI_COMPAT (abfd)) - mips_elf_hash_table (info)->compact_rel_size += - sizeof (Elf32_External_crinfo); - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -mips_elf_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* For a function, create a stub, if needed. */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! elf_hash_table (info)->dynamic_sections_created) - return true; - - /* If this symbol is not defined in a regular file, then set - the symbol to the stub location. This is required to make - function pointers compare as equal between the normal - executable and the shared library. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* We need .stub section. */ - s = bfd_get_section_by_name (dynobj, ".stub"); - BFD_ASSERT (s != NULL); - - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* XXX Write this stub address somewhere. */ - h->plt_offset = s->_raw_size; - - /* Make room for this stub code. */ - s->_raw_size += MIPS_FUNCTION_STUB_SIZE; - - /* The last half word of the stub will be filled with the index - of this symbol in .dynsym section. */ - return true; - } - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -mips_elf_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean reltext; - asection *sgot; - struct mips_got_info *g; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - } - - /* Recompute the size of .got for local entires (reserved and - hipages) if needed. To estimate it, get the upper bound of total - size of loadable sections. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); - - if (sgot != NULL) - { - bfd_size_type loadable_size = 0; - bfd_size_type local_gotno; - struct _bfd *sub; - - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - for (sub = info->input_bfds; sub; sub = sub->link_next) - for (s = sub->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_ALLOC) == 0) - continue; - loadable_size += (s->_raw_size + 0xf) & ~0xf; - } - - loadable_size += MIPS_FUNCTION_STUB_SIZE; - - /* Assume there are two loadable segments consisting of - contiguous sections. Is 5 enough? */ - local_gotno = (loadable_size >> 16) + 5 + MIPS_RESERVED_GOTNO; - g->local_gotno = local_gotno; - sgot->_raw_size += local_gotno * 4; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - reltext = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - strip = false; - - if (strncmp (name, ".rel", 4) == 0) - { - if (s->_raw_size == 0) - strip = true; - else - { - asection *target; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. - If the relocation section is .rel.dyn, we always - assert a DT_TEXTREL entry rather than testing whether - there exists a relocation to a read only section or - not. */ - target = bfd_get_section_by_name (output_bfd, name + 4); - if ((target != NULL && (target->flags & SEC_READONLY) != 0) - || strcmp (name, ".rel.dyn") == 0) - reltext = true; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - if (strcmp (name, ".rel.dyn") != 0) - s->reloc_count = 0; - } - } - else if (strncmp (name, ".got", 4) == 0) - { - int i; - - BFD_ASSERT (elf_section_data (s) != NULL); - g = (struct mips_got_info *) elf_section_data (s)->tdata; - BFD_ASSERT (g != NULL); - - /* Fix the size of .got section for the correspondence of - global symbols and got entries. This adds some useless - got entries. Is this required by ABI really? */ - i = elf_hash_table (info)->dynsymcount - g->global_gotsym; - s->_raw_size += i * 4; - } - else if (strncmp (name, ".stub", 5) == 0) - { - /* Irix rld assumes that the function stub isn't at the end - of .text section. So put a dummy. XXX */ - s->_raw_size += MIPS_FUNCTION_STUB_SIZE; - } - else if (SGI_COMPAT (output_bfd) - && strncmp (name, ".compact_rel", 12) == 0) - s->_raw_size += mips_elf_hash_table (info)->compact_rel_size; - else if (strncmp (name, ".init", 5) != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (s->contents, 0, s->_raw_size); - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_mips_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)) - return false; - - if (bfd_get_section_by_name (dynobj, ".rel.dyn")) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELENT, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_CONFLICTNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LIBLISTNO, 0)) - return false; - - if (bfd_get_section_by_name (dynobj, ".conflict") != NULL) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_CONFLICT, 0)) - return false; - - s = bfd_get_section_by_name (dynobj, ".liblist"); - BFD_ASSERT (s != NULL); - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LIBLIST, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_RLD_VERSION, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_FLAGS, 0)) - return false; - -#if 0 - /* Time stamps in executable files are a bad idea. */ - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_TIME_STAMP, 0)) - return false; -#endif - -#if 0 /* FIXME */ - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_ICHECKSUM, 0)) - return false; -#endif - -#if 0 /* FIXME */ - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_IVERSION, 0)) - return false; -#endif - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_BASE_ADDRESS, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LOCAL_GOTNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_SYMTABNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_UNREFEXTNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_GOTSYM, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_HIPAGENO, 0)) - return false; - -#if 0 /* (SGI_COMPAT) */ - if (! bfd_get_section_by_name (dynobj, ".init")) - if (! bfd_elf32_add_dynamic_entry (info, DT_INIT, 0)) - return false; - - if (! bfd_get_section_by_name (dynobj, ".fini")) - if (! bfd_elf32_add_dynamic_entry (info, DT_FINI, 0)) - return false; -#endif - } - - /* If we use dynamic linking, we generate a section symbol for each - output section. These are local symbols, which means that they - must come first in the dynamic symbol table. - That means we must increment the dynamic symbol index of every - other dynamic symbol. */ - { - const char * const *namep; - unsigned int c, i; - bfd_size_type strindex; - struct bfd_strtab_hash *dynstr; - struct mips_got_info *g; - - if (elf_hash_table (info)->dynamic_sections_created) - { - if (SGI_COMPAT (output_bfd)) - { - c = SIZEOF_MIPS_DYNSYM_SECNAMES - 1; - elf_link_hash_traverse (elf_hash_table (info), - mips_elf_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - dynstr = elf_hash_table (info)->dynstr; - BFD_ASSERT (dynstr != NULL); - - for (i = 1, namep = mips_elf_dynsym_sec_names; - *namep != NULL; - i++, namep++) - { - s = bfd_get_section_by_name (output_bfd, *namep); - if (s != NULL) - elf_section_data (s)->dynindx = i; - - strindex = _bfd_stringtab_add (dynstr, *namep, true, false); - if (strindex == (bfd_size_type) -1) - return false; - - mips_elf_hash_table (info)->dynsym_sec_strindex[i] = strindex; - } - } - else - { - c = bfd_count_sections (output_bfd); - elf_link_hash_traverse (elf_hash_table (info), - mips_elf_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++) - { - elf_section_data (s)->dynindx = i; - /* These symbols will have no names, so we don't need to - fiddle with dynstr_index. */ - } - } - } - - s = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (elf_section_data (s) != NULL); - g = (struct mips_got_info *) elf_section_data (s)->tdata; - BFD_ASSERT (g != NULL); - - /* If there are no global got symbols, fake the last symbol so for - safety. */ - if (g->global_gotsym) - g->global_gotsym += c; - else - g->global_gotsym = elf_hash_table (info)->dynsymcount - 1; - } - - return true; -} - -/* Increment the index of a dynamic symbol by a given amount. Called - via elf_link_hash_traverse. */ - -static boolean -mips_elf_adjust_dynindx (h, cparg) - struct elf_link_hash_entry *h; - PTR cparg; -{ - unsigned int *cp = (unsigned int *) cparg; - - if (h->dynindx != -1) - h->dynindx += *cp; - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - bfd_vma gval; - asection *sgot; - struct mips_got_info *g; - const char *name; - - dynobj = elf_hash_table (info)->dynobj; - gval = sym->st_value; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *s; - bfd_byte *p; - bfd_byte stub[MIPS_FUNCTION_STUB_SIZE]; - - /* This symbol has a stub. Set it up. */ - - BFD_ASSERT (h->dynindx != -1); - - s = bfd_get_section_by_name (dynobj, ".stub"); - BFD_ASSERT (s != NULL); - - /* Fill the stub. */ - p = stub; - bfd_put_32 (output_bfd, STUB_LW(output_bfd), p); - p += 4; - bfd_put_32 (output_bfd, STUB_MOVE, p); - p += 4; - - /* FIXME: Can h->dynindex be more than 64K? */ - if (h->dynindx & 0xffff0000) - return false; - - bfd_put_32 (output_bfd, STUB_JALR, p); - p += 4; - bfd_put_32 (output_bfd, STUB_LI16 + h->dynindx, p); - - BFD_ASSERT (h->plt_offset <= s->_raw_size); - memcpy (s->contents + h->plt_offset, stub, MIPS_FUNCTION_STUB_SIZE); - - /* Mark the symbol as undefined. plt_offset != -1 occurs - only for the referenced symbol. */ - sym->st_shndx = SHN_UNDEF; - - /* The run-time linker uses the st_value field of the symbol - to reset the global offset table entry for this external - to its stub address when unlinking a shared object. */ - gval = s->output_section->vma + s->output_offset + h->plt_offset; - sym->st_value = gval; - } - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - if ((unsigned long) h->dynindx >= g->global_gotsym) - { - bfd_size_type offset; - - /* This symbol has an entry in the global offset table. Set its - value to the corresponding got entry, if needed. */ - if (h->got_offset == (bfd_vma) -1) - { - offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4; - BFD_ASSERT (g->local_gotno * 4 <= offset - && offset < sgot->_raw_size); - bfd_put_32 (output_bfd, gval, sgot->contents + offset); - } - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - name = h->root.root.string; - if (strcmp (name, "_DYNAMIC") == 0 - || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - else if (strcmp (name, "_DYNAMIC_LINK") == 0) - { - sym->st_shndx = SHN_ABS; - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_value = 1; - } - else if (SGI_COMPAT (output_bfd)) - { - if (strcmp (name, "_gp_disp") == 0) - { - sym->st_shndx = SHN_ABS; - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_value = elf_gp (output_bfd); - } - else if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0 - || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0) - { - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_other = STO_PROTECTED; - sym->st_value = 0; - sym->st_shndx = SHN_MIPS_DATA; - } - else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0) - { - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_other = STO_PROTECTED; - sym->st_value = mips_elf_hash_table (info)->procedure_count; - sym->st_shndx = SHN_ABS; - } - else if (sym->st_shndx != SHN_UNDEF) - { - if (h->type == STT_FUNC) - sym->st_shndx = SHN_MIPS_TEXT; - else if (h->type == STT_OBJECT) - sym->st_shndx = SHN_MIPS_DATA; - } - } - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -mips_elf_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sdyn; - asection *sgot; - struct mips_got_info *g; - - dynobj = elf_hash_table (info)->dynobj; - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - Elf32_External_Dyn *dyncon, *dynconend; - - BFD_ASSERT (sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - size_t elemsize; - asection *s; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - case DT_RELENT: - s = bfd_get_section_by_name (dynobj, ".rel.dyn"); - BFD_ASSERT (s != NULL); - dyn.d_un.d_val = sizeof (Elf32_External_Rel); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_STRSZ: - /* Rewrite DT_STRSZ. */ - dyn.d_un.d_val = - _bfd_stringtab_size (elf_hash_table (info)->dynstr); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_PLTGOT: - name = ".got"; - goto get_vma; - case DT_MIPS_CONFLICT: - name = ".conflict"; - goto get_vma; - case DT_MIPS_LIBLIST: - name = ".liblist"; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_RLD_VERSION: - dyn.d_un.d_val = 1; /* XXX */ - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_FLAGS: - dyn.d_un.d_val = RHF_NOTPOT; /* XXX */ - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_CONFLICTNO: - name = ".conflict"; - elemsize = sizeof (Elf32_Conflict); - goto set_elemno; - - case DT_MIPS_LIBLISTNO: - name = ".liblist"; - elemsize = sizeof (Elf32_Lib); - set_elemno: - s = bfd_get_section_by_name (output_bfd, name); - if (s != NULL) - { - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size / elemsize; - else - dyn.d_un.d_val = s->_raw_size / elemsize; - } - else - dyn.d_un.d_val = 0; - - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_TIME_STAMP: - time ((time_t *) &dyn.d_un.d_val); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_ICHECKSUM: - /* XXX FIXME: */ - break; - - case DT_MIPS_IVERSION: - /* XXX FIXME: */ - break; - - case DT_MIPS_BASE_ADDRESS: - s = output_bfd->sections; - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma & ~(0xffff); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_LOCAL_GOTNO: - dyn.d_un.d_val = g->local_gotno; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_SYMTABNO: - name = ".dynsym"; - elemsize = sizeof (Elf32_External_Sym); - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size / elemsize; - else - dyn.d_un.d_val = s->_raw_size / elemsize; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_UNREFEXTNO: - /* XXX FIXME: */ - dyn.d_un.d_val = SIZEOF_MIPS_DYNSYM_SECNAMES; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_GOTSYM: - dyn.d_un.d_val = g->global_gotsym; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_HIPAGENO: - dyn.d_un.d_val = g->local_gotno - MIPS_RESERVED_GOTNO; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - } - } - } - - /* The first entry of the global offset table will be filled at - runtime. The second entry will be used by some runtime loaders. - This isn't the case of Irix rld. */ - if (sgot->_raw_size > 0) - { - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, sgot->contents + 4); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - { - asection *sdynsym; - asection *s; - unsigned int i; - bfd_vma last; - Elf_Internal_Sym sym; - long dindx; - const char *name; - const char * const * namep = mips_elf_dynsym_sec_names; - Elf32_compact_rel cpt; - - /* Set up the section symbols for the output sections. SGI sets - the STT_NOTYPE attribute for these symbols. Should we do so? */ - - sdynsym = bfd_get_section_by_name (dynobj, ".dynsym"); - if (sdynsym != NULL) - { - if (SGI_COMPAT (output_bfd)) - { - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE); - sym.st_other = 0; - - i = 0; - while ((name = *namep++) != NULL) - { - s = bfd_get_section_by_name (output_bfd, name); - if (s != NULL) - { - sym.st_value = s->vma; - dindx = elf_section_data (s)->dynindx; - last = s->vma + s->_raw_size; - } - else - { - sym.st_value = last; - dindx++; - } - - sym.st_shndx = (i < MIPS_TEXT_DYNSYM_SECNO - ? SHN_MIPS_TEXT - : SHN_MIPS_DATA); - ++i; - sym.st_name = - mips_elf_hash_table (info)->dynsym_sec_strindex[dindx]; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (((Elf32_External_Sym *) - sdynsym->contents) - + dindx)); - } - - /* Set the sh_info field of the output .dynsym section to - the index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - SIZEOF_MIPS_DYNSYM_SECNAMES; - } - else - { - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - - for (s = output_bfd->sections; s != NULL; s = s->next) - { - int indx; - - sym.st_value = s->vma; - - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (((Elf32_External_Sym *) - sdynsym->contents) - + elf_section_data (s)->dynindx)); - } - - /* Set the sh_info field of the output .dynsym section to - the index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - bfd_count_sections (output_bfd) + 1; - } - } - - if (SGI_COMPAT (output_bfd)) - { - /* Write .compact_rel section out. */ - s = bfd_get_section_by_name (dynobj, ".compact_rel"); - if (s != NULL) - { - cpt.id1 = 1; - cpt.num = s->reloc_count; - cpt.id2 = 2; - cpt.offset = (s->output_section->filepos - + sizeof (Elf32_External_compact_rel)); - cpt.reserved0 = 0; - cpt.reserved1 = 0; - bfd_elf32_swap_compact_rel_out (output_bfd, &cpt, - ((Elf32_External_compact_rel *) - s->contents)); - - /* Clean up a dummy stub function entry in .text. */ - s = bfd_get_section_by_name (dynobj, ".stub"); - if (s != NULL) - { - file_ptr dummy_offset; - - BFD_ASSERT (s->_raw_size >= MIPS_FUNCTION_STUB_SIZE); - dummy_offset = s->_raw_size - MIPS_FUNCTION_STUB_SIZE; - memset (s->contents + dummy_offset, 0, - MIPS_FUNCTION_STUB_SIZE); - } - } - } - - /* Clean up a first relocation in .rel.dyn. */ - s = bfd_get_section_by_name (dynobj, ".rel.dyn"); - if (s != NULL) - memset (s->contents, 0, sizeof (Elf32_External_Rel)); - } - - return true; -} - -/* This is almost identical to bfd_generic_get_... except that some - MIPS relocations need to be handled specially. Sigh. */ - -static bfd_byte * -elf32_mips_get_relocated_section_contents (abfd, link_info, link_order, data, - relocateable, symbols) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - if (reloc_size < 0) - goto error_return; - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - /* read in the section */ - if (!bfd_get_section_contents (input_bfd, - input_section, - (PTR) data, - 0, - input_section->_raw_size)) - goto error_return; - - /* We're not relaxing the section, so just copy the size info */ - input_section->_cooked_size = input_section->_raw_size; - input_section->reloc_done = true; - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - goto error_return; - - if (reloc_count > 0) - { - arelent **parent; - /* for mips */ - int gp_found; - bfd_vma gp = 0x12345678; /* initialize just to shut gcc up */ - - { - struct bfd_hash_entry *h; - struct bfd_link_hash_entry *lh; - /* Skip all this stuff if we aren't mixing formats. */ - if (abfd && input_bfd - && abfd->xvec == input_bfd->xvec) - lh = 0; - else - { - h = bfd_hash_lookup (&link_info->hash->table, "_gp", false, false); - lh = (struct bfd_link_hash_entry *) h; - } - lookup: - if (lh) - { - switch (lh->type) - { - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - case bfd_link_hash_common: - gp_found = 0; - break; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - gp_found = 1; - gp = lh->u.def.value; - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - lh = lh->u.i.link; - /* @@FIXME ignoring warning for now */ - goto lookup; - case bfd_link_hash_new: - default: - abort (); - } - } - else - gp_found = 0; - } - /* end mips */ - for (parent = reloc_vector; *parent != (arelent *) NULL; - parent++) - { - char *error_message = (char *) NULL; - bfd_reloc_status_type r; - - /* Specific to MIPS: Deal with relocation types that require - knowing the gp of the output bfd. */ - asymbol *sym = *(*parent)->sym_ptr_ptr; - if (bfd_is_abs_section (sym->section) && abfd) - { - /* The special_function wouldn't get called anyways. */ - } - else if (!gp_found) - { - /* The gp isn't there; let the special function code - fall over on its own. */ - } - else if ((*parent)->howto->special_function - == mips_elf_gprel16_reloc) - { - /* bypass special_function call */ - r = gprel16_with_gp (input_bfd, sym, *parent, input_section, - relocateable, (PTR) data, gp); - goto skip_bfd_perform_relocation; - } - /* end mips specific stuff */ - - r = bfd_perform_relocation (input_bfd, - *parent, - (PTR) data, - input_section, - relocateable ? abfd : (bfd *) NULL, - &error_message); - skip_bfd_perform_relocation: - - if (relocateable) - { - asection *os = input_section->output_section; - - /* A partial link, so keep the relocs */ - os->orelocation[os->reloc_count] = *parent; - os->reloc_count++; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - case bfd_reloc_undefined: - if (!((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_dangerous: - BFD_ASSERT (error_message != (char *) NULL); - if (!((*link_info->callbacks->reloc_dangerous) - (link_info, error_message, input_bfd, input_section, - (*parent)->address))) - goto error_return; - break; - case bfd_reloc_overflow: - if (!((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - (*parent)->howto->name, (*parent)->addend, - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_outofrange: - default: - abort (); - break; - } - - } - } - } - if (reloc_vector != NULL) - free (reloc_vector); - return data; - -error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} -#define bfd_elf32_bfd_get_relocated_section_contents \ - elf32_mips_get_relocated_section_contents - -/* ECOFF swapping routines. These are used when dealing with the - .mdebug section, which is in the ECOFF debugging format. */ -static const struct ecoff_debug_swap mips_elf_ecoff_debug_swap = -{ - /* Symbol table magic number. */ - magicSym, - /* Alignment of debugging information. E.g., 4. */ - 4, - /* Sizes of external symbolic information. */ - sizeof (struct hdr_ext), - sizeof (struct dnr_ext), - sizeof (struct pdr_ext), - sizeof (struct sym_ext), - sizeof (struct opt_ext), - sizeof (struct fdr_ext), - sizeof (struct rfd_ext), - sizeof (struct ext_ext), - /* Functions to swap in external symbolic data. */ - ecoff_swap_hdr_in, - ecoff_swap_dnr_in, - ecoff_swap_pdr_in, - ecoff_swap_sym_in, - ecoff_swap_opt_in, - ecoff_swap_fdr_in, - ecoff_swap_rfd_in, - ecoff_swap_ext_in, - _bfd_ecoff_swap_tir_in, - _bfd_ecoff_swap_rndx_in, - /* Functions to swap out external symbolic data. */ - ecoff_swap_hdr_out, - ecoff_swap_dnr_out, - ecoff_swap_pdr_out, - ecoff_swap_sym_out, - ecoff_swap_opt_out, - ecoff_swap_fdr_out, - ecoff_swap_rfd_out, - ecoff_swap_ext_out, - _bfd_ecoff_swap_tir_out, - _bfd_ecoff_swap_rndx_out, - /* Function to read in symbolic data. */ - mips_elf_read_ecoff_info -}; - -#define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec -#define TARGET_LITTLE_NAME "elf32-littlemips" -#define TARGET_BIG_SYM bfd_elf32_bigmips_vec -#define TARGET_BIG_NAME "elf32-bigmips" -#define ELF_ARCH bfd_arch_mips -#define ELF_MACHINE_CODE EM_MIPS -#define ELF_MAXPAGESIZE 0x10000 -#define elf_backend_collect true -#define elf_backend_type_change_ok true -#define elf_info_to_howto 0 -#define elf_info_to_howto_rel mips_info_to_howto_rel -#define elf_backend_sym_is_global mips_elf_sym_is_global -#define elf_backend_object_p mips_elf_object_p -#define elf_backend_section_from_shdr mips_elf_section_from_shdr -#define elf_backend_fake_sections mips_elf_fake_sections -#define elf_backend_section_from_bfd_section \ - mips_elf_section_from_bfd_section -#define elf_backend_section_processing mips_elf_section_processing -#define elf_backend_symbol_processing mips_elf_symbol_processing -#define elf_backend_additional_program_headers \ - mips_elf_additional_program_headers -#define elf_backend_modify_segment_map mips_elf_modify_segment_map -#define elf_backend_final_write_processing \ - mips_elf_final_write_processing -#define elf_backend_ecoff_debug_swap &mips_elf_ecoff_debug_swap - -#define bfd_elf32_bfd_is_local_label mips_elf_is_local_label -#define bfd_elf32_find_nearest_line mips_elf_find_nearest_line - -#define bfd_elf32_bfd_link_hash_table_create \ - mips_elf_link_hash_table_create -#define bfd_elf32_bfd_final_link mips_elf_final_link -#define bfd_elf32_bfd_copy_private_bfd_data \ - mips_elf_copy_private_bfd_data -#define bfd_elf32_bfd_merge_private_bfd_data \ - mips_elf_merge_private_bfd_data -#define bfd_elf32_bfd_set_private_flags mips_elf_set_private_flags -#define elf_backend_add_symbol_hook mips_elf_add_symbol_hook -#define elf_backend_create_dynamic_sections \ - mips_elf_create_dynamic_sections -#define elf_backend_check_relocs mips_elf_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - mips_elf_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - mips_elf_size_dynamic_sections -#define elf_backend_relocate_section mips_elf_relocate_section -#define elf_backend_finish_dynamic_symbol \ - mips_elf_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - mips_elf_finish_dynamic_sections - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-ppc.c b/contrib/gdb/bfd/elf32-ppc.c deleted file mode 100644 index a8e5ad3fdb1..00000000000 --- a/contrib/gdb/bfd/elf32-ppc.c +++ /dev/null @@ -1,2554 +0,0 @@ -/* PowerPC-specific support for 32-bit ELF - Copyright 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file is based on a preliminary PowerPC ELF ABI. The - information may not match the final PowerPC ELF ABI. It includes - suggestions from the in-progress Embedded PowerPC ABI, and that - information may also not match. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf/ppc.h" - -#define USE_RELA /* we want RELA relocations, not REL */ - -/* PowerPC relocations defined by the ABIs */ -enum ppc_reloc_type -{ - R_PPC_NONE = 0, - R_PPC_ADDR32 = 1, - R_PPC_ADDR24 = 2, - R_PPC_ADDR16 = 3, - R_PPC_ADDR16_LO = 4, - R_PPC_ADDR16_HI = 5, - R_PPC_ADDR16_HA = 6, - R_PPC_ADDR14 = 7, - R_PPC_ADDR14_BRTAKEN = 8, - R_PPC_ADDR14_BRNTAKEN = 9, - R_PPC_REL24 = 10, - R_PPC_REL14 = 11, - R_PPC_REL14_BRTAKEN = 12, - R_PPC_REL14_BRNTAKEN = 13, - R_PPC_GOT16 = 14, - R_PPC_GOT16_LO = 15, - R_PPC_GOT16_HI = 16, - R_PPC_GOT16_HA = 17, - R_PPC_PLTREL24 = 18, - R_PPC_COPY = 19, - R_PPC_GLOB_DAT = 20, - R_PPC_JMP_SLOT = 21, - R_PPC_RELATIVE = 22, - R_PPC_LOCAL24PC = 23, - R_PPC_UADDR32 = 24, - R_PPC_UADDR16 = 25, - R_PPC_REL32 = 26, - R_PPC_PLT32 = 27, - R_PPC_PLTREL32 = 28, - R_PPC_PLT16_LO = 29, - R_PPC_PLT16_HI = 30, - R_PPC_PLT16_HA = 31, - R_PPC_SDAREL16 = 32, - R_PPC_SECTOFF = 33, - R_PPC_SECTOFF_LO = 34, - R_PPC_SECTOFF_HI = 35, - R_PPC_SECTOFF_HA = 36, - - /* The remaining relocs are from the Embedded ELF ABI, and are not - in the SVR4 ELF ABI. */ - R_PPC_EMB_NADDR32 = 101, - R_PPC_EMB_NADDR16 = 102, - R_PPC_EMB_NADDR16_LO = 103, - R_PPC_EMB_NADDR16_HI = 104, - R_PPC_EMB_NADDR16_HA = 105, - R_PPC_EMB_SDAI16 = 106, - R_PPC_EMB_SDA2I16 = 107, - R_PPC_EMB_SDA2REL = 108, - R_PPC_EMB_SDA21 = 109, - R_PPC_EMB_MRKREF = 110, - R_PPC_EMB_RELSEC16 = 111, - R_PPC_EMB_RELST_LO = 112, - R_PPC_EMB_RELST_HI = 113, - R_PPC_EMB_RELST_HA = 114, - R_PPC_EMB_BIT_FLD = 115, - R_PPC_EMB_RELSDA = 116, - - /* This is a phony reloc to handle any old fashioned TOC16 references - that may still be in object files. */ - R_PPC_TOC16 = 255, - - R_PPC_max -}; - -static reloc_howto_type *ppc_elf_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void ppc_elf_info_to_howto - PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst)); -static void ppc_elf_howto_init PARAMS ((void)); -static boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword)); -static boolean ppc_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); - -static int ppc_elf_additional_program_headers PARAMS ((bfd *)); -static boolean ppc_elf_modify_segment_map PARAMS ((bfd *)); - -static boolean ppc_elf_section_from_shdr PARAMS ((bfd *, - Elf32_Internal_Shdr *, - char *)); - -static elf_linker_section_t *ppc_elf_create_linker_section - PARAMS ((bfd *abfd, - struct bfd_link_info *info, - enum elf_linker_section_enum)); - -static boolean ppc_elf_check_relocs PARAMS ((bfd *, - struct bfd_link_info *, - asection *, - const Elf_Internal_Rela *)); - -static boolean ppc_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *, - struct elf_link_hash_entry *)); - -static boolean ppc_elf_adjust_dynindx PARAMS ((struct elf_link_hash_entry *, PTR)); - -static boolean ppc_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); - -static boolean ppc_elf_relocate_section PARAMS ((bfd *, - struct bfd_link_info *info, - bfd *, - asection *, - bfd_byte *, - Elf_Internal_Rela *relocs, - Elf_Internal_Sym *local_syms, - asection **)); - -static boolean ppc_elf_add_symbol_hook PARAMS ((bfd *, - struct bfd_link_info *, - const Elf_Internal_Sym *, - const char **, - flagword *, - asection **, - bfd_vma *)); - -static boolean ppc_elf_finish_dynamic_symbol PARAMS ((bfd *, - struct bfd_link_info *, - struct elf_link_hash_entry *, - Elf_Internal_Sym *)); - -static boolean ppc_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); - -#define BRANCH_PREDICT_BIT 0x200000 /* branch prediction bit for branch taken relocs */ -#define RA_REGISTER_MASK 0x001f0000 /* mask to set RA in memory instructions */ -#define RA_REGISTER_SHIFT 16 /* value to shift register by to insert RA */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" - - -static reloc_howto_type *ppc_elf_howto_table[ (int)R_PPC_max ]; - -static reloc_howto_type ppc_elf_howto_raw[] = -{ - /* This reloc does nothing. */ - HOWTO (R_PPC_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_NONE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A standard 32 bit relocation. */ - HOWTO (R_PPC_ADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 26 bit branch; the lower two bits must be zero. - FIXME: we don't check that, we just clear them. */ - HOWTO (R_PPC_ADDR24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR24", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* A standard 16 bit relocation. */ - HOWTO (R_PPC_ADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 16 bit relocation without overflow. */ - HOWTO (R_PPC_ADDR16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of an address. */ - HOWTO (R_PPC_ADDR16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of an address, plus 1 if the contents of - the low 16 bits, treated as a signed number, is negative. */ - HOWTO (R_PPC_ADDR16_HA, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 16 bit branch; the lower two bits must be zero. - FIXME: we don't check that, we just clear them. */ - HOWTO (R_PPC_ADDR14, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR14", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 16 bit branch, for which bit 10 should be set to - indicate that the branch is expected to be taken. The lower two - bits must be zero. */ - HOWTO (R_PPC_ADDR14_BRTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR14_BRTAKEN",/* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 16 bit branch, for which bit 10 should be set to - indicate that the branch is not expected to be taken. The lower - two bits must be zero. */ - HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR14_BRNTAKEN",/* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* A relative 26 bit branch; the lower two bits must be zero. */ - HOWTO (R_PPC_REL24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL24", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* A relative 16 bit branch; the lower two bits must be zero. */ - HOWTO (R_PPC_REL14, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL14", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* A relative 16 bit branch. Bit 10 should be set to indicate that - the branch is expected to be taken. The lower two bits must be - zero. */ - HOWTO (R_PPC_REL14_BRTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL14_BRTAKEN", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* A relative 16 bit branch. Bit 10 should be set to indicate that - the branch is not expected to be taken. The lower two bits must - be zero. */ - HOWTO (R_PPC_REL14_BRNTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL14_BRNTAKEN",/* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* Like R_PPC_ADDR16, but referring to the GOT table entry for the - symbol. */ - HOWTO (R_PPC_GOT16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for - the symbol. */ - HOWTO (R_PPC_GOT16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for - the symbol. */ - HOWTO (R_PPC_GOT16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for - the symbol. */ - HOWTO (R_PPC_GOT16_HA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_REL24, but referring to the procedure linkage table - entry for the symbol. FIXME: Not supported. */ - HOWTO (R_PPC_PLTREL24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLTREL24", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* This is used only by the dynamic linker. The symbol should exist - both in the object being run and in some shared library. The - dynamic linker copies the data addressed by the symbol from the - shared library into the object. I have no idea what the purpose - of this is. */ - HOWTO (R_PPC_COPY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_COPY", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR32, but used when setting global offset table - entries. */ - HOWTO (R_PPC_GLOB_DAT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GLOB_DAT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Marks a procedure linkage table entry for a symbol. */ - HOWTO (R_PPC_JMP_SLOT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_JMP_SLOT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Used only by the dynamic linker. When the object is run, this - longword is set to the load address of the object, plus the - addend. */ - HOWTO (R_PPC_RELATIVE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_RELATIVE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_REL24, but uses the value of the symbol within the - object rather than the final value. Normally used for - _GLOBAL_OFFSET_TABLE_. FIXME: Not supported. */ - HOWTO (R_PPC_LOCAL24PC, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_LOCAL24PC", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* Like R_PPC_ADDR32, but may be unaligned. */ - HOWTO (R_PPC_UADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_UADDR32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16, but may be unaligned. */ - HOWTO (R_PPC_UADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_UADDR16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32-bit PC relative */ - HOWTO (R_PPC_REL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* 32-bit relocation to the symbol's procedure linkage table. - FIXEME: not supported. */ - HOWTO (R_PPC_PLT32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32-bit PC relative relocation to the symbol's procedure linkage table. - FIXEME: not supported. */ - HOWTO (R_PPC_PLTREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLTREL32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for - the symbol. */ - HOWTO (R_PPC_PLT16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for - the symbol. */ - HOWTO (R_PPC_PLT16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for - the symbol. FIXME: Not supported. */ - HOWTO (R_PPC_PLT16_HA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A sign-extended 16 bit value relative to _SDA_BASE_, for use with - small data items. */ - HOWTO (R_PPC_SDAREL16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SDAREL16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32-bit section relative relocation. */ - HOWTO (R_PPC_SECTOFF, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ - - /* 16-bit lower half section relative relocation. */ - HOWTO (R_PPC_SECTOFF_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16-bit upper half section relative relocation. */ - HOWTO (R_PPC_SECTOFF_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16-bit upper half adjusted section relative relocation. */ - HOWTO (R_PPC_SECTOFF_HA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The remaining relocs are from the Embedded ELF ABI, and are not - in the SVR4 ELF ABI. */ - - /* 32 bit value resulting from the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_ADDR16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of the result of the addend minus the address, - plus 1 if the contents of the low 16 bits, treated as a signed number, - is negative. */ - HOWTO (R_PPC_EMB_NADDR16_HA, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from allocating a 4 byte word to hold an - address in the .sdata section, and returning the offset from - _SDA_BASE_ for that relocation */ - HOWTO (R_PPC_EMB_SDAI16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDAI16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from allocating a 4 byte word to hold an - address in the .sdata2 section, and returning the offset from - _SDA2_BASE_ for that relocation */ - HOWTO (R_PPC_EMB_SDA2I16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDA2I16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A sign-extended 16 bit value relative to _SDA2_BASE_, for use with - small data items. */ - HOWTO (R_PPC_EMB_SDA2REL, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDA2REL", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Relocate against either _SDA_BASE_ or _SDA2_BASE_, filling in the 16 bit - signed offset from the appropriate base, and filling in the register - field with the appropriate register (0, 2, or 13). */ - HOWTO (R_PPC_EMB_SDA21, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDA21", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Relocation not handled: R_PPC_EMB_MRKREF */ - /* Relocation not handled: R_PPC_EMB_RELSEC16 */ - /* Relocation not handled: R_PPC_EMB_RELST_LO */ - /* Relocation not handled: R_PPC_EMB_RELST_HI */ - /* Relocation not handled: R_PPC_EMB_RELST_HA */ - /* Relocation not handled: R_PPC_EMB_BIT_FLD */ - - /* PC relative relocation against either _SDA_BASE_ or _SDA2_BASE_, filling - in the 16 bit signed offset from the appropriate base, and filling in the - register field with the appropriate register (0, 2, or 13). */ - HOWTO (R_PPC_EMB_RELSDA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_RELSDA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Phony reloc to handle AIX style TOC entries */ - HOWTO (R_PPC_TOC16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_TOC16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ -}; - - -/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */ - -static void -ppc_elf_howto_init () -{ - unsigned int i, type; - - for (i = 0; i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); i++) - { - type = ppc_elf_howto_raw[i].type; - BFD_ASSERT (type < sizeof(ppc_elf_howto_table) / sizeof(ppc_elf_howto_table[0])); - ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i]; - } -} - - -static reloc_howto_type * -ppc_elf_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - enum ppc_reloc_type ppc_reloc = R_PPC_NONE; - - if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */ - ppc_elf_howto_init (); - - switch ((int)code) - { - default: - return (reloc_howto_type *)NULL; - - case BFD_RELOC_NONE: ppc_reloc = R_PPC_NONE; break; - case BFD_RELOC_32: ppc_reloc = R_PPC_ADDR32; break; - case BFD_RELOC_PPC_BA26: ppc_reloc = R_PPC_ADDR24; break; - case BFD_RELOC_16: ppc_reloc = R_PPC_ADDR16; break; - case BFD_RELOC_LO16: ppc_reloc = R_PPC_ADDR16_LO; break; - case BFD_RELOC_HI16: ppc_reloc = R_PPC_ADDR16_HI; break; - case BFD_RELOC_HI16_S: ppc_reloc = R_PPC_ADDR16_HA; break; - case BFD_RELOC_PPC_BA16: ppc_reloc = R_PPC_ADDR14; break; - case BFD_RELOC_PPC_BA16_BRTAKEN: ppc_reloc = R_PPC_ADDR14_BRTAKEN; break; - case BFD_RELOC_PPC_BA16_BRNTAKEN: ppc_reloc = R_PPC_ADDR14_BRNTAKEN; break; - case BFD_RELOC_PPC_B26: ppc_reloc = R_PPC_REL24; break; - case BFD_RELOC_PPC_B16: ppc_reloc = R_PPC_REL14; break; - case BFD_RELOC_PPC_B16_BRTAKEN: ppc_reloc = R_PPC_REL14_BRTAKEN; break; - case BFD_RELOC_PPC_B16_BRNTAKEN: ppc_reloc = R_PPC_REL14_BRNTAKEN; break; - case BFD_RELOC_16_GOTOFF: ppc_reloc = R_PPC_GOT16; break; - case BFD_RELOC_LO16_GOTOFF: ppc_reloc = R_PPC_GOT16_LO; break; - case BFD_RELOC_HI16_GOTOFF: ppc_reloc = R_PPC_GOT16_HI; break; - case BFD_RELOC_HI16_S_GOTOFF: ppc_reloc = R_PPC_GOT16_HA; break; - case BFD_RELOC_24_PLT_PCREL: ppc_reloc = R_PPC_PLTREL24; break; - case BFD_RELOC_PPC_COPY: ppc_reloc = R_PPC_COPY; break; - case BFD_RELOC_PPC_GLOB_DAT: ppc_reloc = R_PPC_GLOB_DAT; break; - case BFD_RELOC_PPC_LOCAL24PC: ppc_reloc = R_PPC_LOCAL24PC; break; - case BFD_RELOC_32_PCREL: ppc_reloc = R_PPC_REL32; break; - case BFD_RELOC_32_PLTOFF: ppc_reloc = R_PPC_PLT32; break; - case BFD_RELOC_32_PLT_PCREL: ppc_reloc = R_PPC_PLTREL32; break; - case BFD_RELOC_LO16_PLTOFF: ppc_reloc = R_PPC_PLT16_LO; break; - case BFD_RELOC_HI16_PLTOFF: ppc_reloc = R_PPC_PLT16_HI; break; - case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC_PLT16_HA; break; - case BFD_RELOC_GPREL16: ppc_reloc = R_PPC_SDAREL16; break; - case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC_SECTOFF; break; - case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC_SECTOFF_LO; break; - case BFD_RELOC_HI16_BASEREL: ppc_reloc = R_PPC_SECTOFF_HI; break; - case BFD_RELOC_HI16_S_BASEREL: ppc_reloc = R_PPC_SECTOFF_HA; break; - case BFD_RELOC_CTOR: ppc_reloc = R_PPC_ADDR32; break; - case BFD_RELOC_PPC_TOC16: ppc_reloc = R_PPC_TOC16; break; - case BFD_RELOC_PPC_EMB_NADDR32: ppc_reloc = R_PPC_EMB_NADDR32; break; - case BFD_RELOC_PPC_EMB_NADDR16: ppc_reloc = R_PPC_EMB_NADDR16; break; - case BFD_RELOC_PPC_EMB_NADDR16_LO: ppc_reloc = R_PPC_EMB_NADDR16_LO; break; - case BFD_RELOC_PPC_EMB_NADDR16_HI: ppc_reloc = R_PPC_EMB_NADDR16_HI; break; - case BFD_RELOC_PPC_EMB_NADDR16_HA: ppc_reloc = R_PPC_EMB_NADDR16_HA; break; - case BFD_RELOC_PPC_EMB_SDAI16: ppc_reloc = R_PPC_EMB_SDAI16; break; - case BFD_RELOC_PPC_EMB_SDA2I16: ppc_reloc = R_PPC_EMB_SDA2I16; break; - case BFD_RELOC_PPC_EMB_SDA2REL: ppc_reloc = R_PPC_EMB_SDA2REL; break; - case BFD_RELOC_PPC_EMB_SDA21: ppc_reloc = R_PPC_EMB_SDA21; break; - case BFD_RELOC_PPC_EMB_MRKREF: ppc_reloc = R_PPC_EMB_MRKREF; break; - case BFD_RELOC_PPC_EMB_RELSEC16: ppc_reloc = R_PPC_EMB_RELSEC16; break; - case BFD_RELOC_PPC_EMB_RELST_LO: ppc_reloc = R_PPC_EMB_RELST_LO; break; - case BFD_RELOC_PPC_EMB_RELST_HI: ppc_reloc = R_PPC_EMB_RELST_HI; break; - case BFD_RELOC_PPC_EMB_RELST_HA: ppc_reloc = R_PPC_EMB_RELST_HA; break; - case BFD_RELOC_PPC_EMB_BIT_FLD: ppc_reloc = R_PPC_EMB_BIT_FLD; break; - case BFD_RELOC_PPC_EMB_RELSDA: ppc_reloc = R_PPC_EMB_RELSDA; break; - } - - return ppc_elf_howto_table[ (int)ppc_reloc ]; -}; - -/* Set the howto pointer for a PowerPC ELF reloc. */ - -static void -ppc_elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rela *dst; -{ - if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */ - ppc_elf_howto_init (); - - BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max); - cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)]; -} - -/* Function to set whether a module needs the -mrelocatable bit set. */ - -static boolean -ppc_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; -{ - BFD_ASSERT (!elf_flags_init (abfd) - || elf_elfheader (abfd)->e_flags == flags); - - elf_elfheader (abfd)->e_flags = flags; - elf_flags_init (abfd) = true; - return true; -} - -/* Copy backend specific data from one object module to another */ -static boolean -ppc_elf_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - BFD_ASSERT (!elf_flags_init (obfd) - || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags); - - elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - elf_flags_init (obfd) = true; - return true; -} - -/* Merge backend specific data from an object file to the output - object file when linking */ -static boolean -ppc_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - flagword old_flags; - flagword new_flags; - boolean error; - - /* Check if we have the same endianess */ - if (ibfd->xvec->byteorder != obfd->xvec->byteorder - && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) - { - (*_bfd_error_handler) - ("%s: compiled for a %s endian system and target is %s endian", - bfd_get_filename (ibfd), - bfd_big_endian (ibfd) ? "big" : "little", - bfd_big_endian (obfd) ? "big" : "little"); - - bfd_set_error (bfd_error_wrong_format); - return false; - } - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - new_flags = elf_elfheader (ibfd)->e_flags; - old_flags = elf_elfheader (obfd)->e_flags; - if (!elf_flags_init (obfd)) /* First call, no flags set */ - { - elf_flags_init (obfd) = true; - elf_elfheader (obfd)->e_flags = new_flags; - } - - else if (new_flags == old_flags) /* Compatible flags are ok */ - ; - - else /* Incompatible flags */ - { - /* Warn about -mrelocatable mismatch. Allow -mrelocatable-lib to be linked - with either. */ - error = false; - if ((new_flags & EF_PPC_RELOCATABLE) != 0 - && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled with -mrelocatable and linked with modules compiled normally", - bfd_get_filename (ibfd)); - } - else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0 - && (old_flags & EF_PPC_RELOCATABLE) != 0) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled normally and linked with modules compiled with -mrelocatable", - bfd_get_filename (ibfd)); - } - else if ((new_flags & EF_PPC_RELOCATABLE_LIB) != 0) - elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE_LIB; - - - /* Do not warn about eabi vs. V.4 mismatch, just or in the bit if any module uses it */ - elf_elfheader (obfd)->e_flags |= (new_flags & EF_PPC_EMB); - - new_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB); - old_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB); - - /* Warn about any other mismatches */ - if (new_flags != old_flags) - { - error = true; - (*_bfd_error_handler) - ("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)", - bfd_get_filename (ibfd), (long)new_flags, (long)old_flags); - } - - if (error) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - return true; -} - - -/* Handle a PowerPC specific section when reading an object file. This - is called when elfcode.h finds a section with an unknown type. */ - -static boolean -ppc_elf_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - char *name; -{ - asection *newsect; - flagword flags; - - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; - - newsect = hdr->bfd_section; - flags = bfd_get_section_flags (abfd, newsect); - if (hdr->sh_flags & SHF_EXCLUDE) - flags |= SEC_EXCLUDE; - - if (hdr->sh_type == SHT_ORDERED) - flags |= SEC_SORT_ENTRIES; - - bfd_set_section_flags (abfd, newsect, flags); - return true; -} - - -/* Set up any other section flags and such that may be necessary. */ - -boolean -ppc_elf_fake_sections (abfd, shdr, asect) - bfd *abfd; - Elf32_Internal_Shdr *shdr; - asection *asect; -{ - if ((asect->flags & SEC_EXCLUDE) != 0) - shdr->sh_flags |= SHF_EXCLUDE; - - if ((asect->flags & SEC_SORT_ENTRIES) != 0) - shdr->sh_type = SHT_ORDERED; -} - - -/* Create a special linker section */ -static elf_linker_section_t * -ppc_elf_create_linker_section (abfd, info, which) - bfd *abfd; - struct bfd_link_info *info; - enum elf_linker_section_enum which; -{ - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *lsect; - - /* Record the first bfd section that needs the special section */ - if (!dynobj) - dynobj = elf_hash_table (info)->dynobj = abfd; - - /* If this is the first time, create the section */ - lsect = elf_linker_section (dynobj, which); - if (!lsect) - { - elf_linker_section_t defaults; - static elf_linker_section_t zero_section; - - defaults = zero_section; - defaults.which = which; - defaults.hole_written_p = false; - defaults.alignment = 2; - defaults.flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - switch (which) - { - default: - (*_bfd_error_handler) ("%s: Unknown special linker type %d", - bfd_get_filename (abfd), - (int)which); - - bfd_set_error (bfd_error_bad_value); - return (elf_linker_section_t *)0; - - case LINKER_SECTION_GOT: /* .got section */ - defaults.name = ".got"; - defaults.rel_name = ".rela.got"; - defaults.sym_name = "_GLOBAL_OFFSET_TABLE_"; - defaults.max_hole_offset = 32764; - defaults.hole_size = 16; - defaults.sym_offset = 4; - break; - - case LINKER_SECTION_SDATA: /* .sdata/.sbss section */ - defaults.name = ".sdata"; - defaults.rel_name = ".rela.sdata"; - defaults.bss_name = ".sbss"; - defaults.sym_name = "_SDA_BASE_"; - defaults.sym_offset = 32768; - break; - - case LINKER_SECTION_SDATA2: /* .sdata2/.sbss2 section */ - defaults.name = ".sdata2"; - defaults.rel_name = ".rela.sdata2"; - defaults.bss_name = ".sbss2"; - defaults.sym_name = "_SDA2_BASE_"; - defaults.sym_offset = 32768; - defaults.flags |= SEC_READONLY; - break; - } - - lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults); - } - - return lsect; -} - - -/* If we have a non-zero sized .sbss2 or .PPC.EMB.sbss0 sections, we need to bump up - the number of section headers. */ - -static int -ppc_elf_additional_program_headers (abfd) - bfd *abfd; -{ - asection *s; - int ret; - - ret = 0; - - s = bfd_get_section_by_name (abfd, ".sbss2"); - if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0) - ++ret; - - s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0"); - if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0) - ++ret; - - return ret; -} - -/* Modify the segment map if needed */ - -static boolean -ppc_elf_modify_segment_map (abfd) - bfd *abfd; -{ - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -ppc_elf_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ -#ifdef DEBUG - fprintf (stderr, "ppc_elf_adjust_dynamic_symbol called\n"); -#endif - return true; -} - - -/* Increment the index of a dynamic symbol by a given amount. Called - via elf_link_hash_traverse. */ - -static boolean -ppc_elf_adjust_dynindx (h, cparg) - struct elf_link_hash_entry *h; - PTR cparg; -{ - int *cp = (int *) cparg; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_adjust_dynindx called, h->dynindx = %d, *cp = %d\n", h->dynindx, *cp); -#endif - - if (h->dynindx != -1) - h->dynindx += *cp; - - return true; -} - - -/* Set the sizes of the dynamic sections. */ - -static boolean -ppc_elf_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean reltext; - boolean relplt; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_size_dynamic_sections called\n"); -#endif - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - - /* Make space for the trailing nop in .plt. */ - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - if (s->_raw_size > 0) - s->_raw_size += 4; - } - else - { - /* We may have created entries in the .rela.got, .rela.sdata, and - .rela.sdata2 section2. However, if we are not creating the - dynamic sections, we will not actually use these entries. Reset - the size of .rela.got, et al, which will cause it to get - stripped from the output file below. */ - static char *rela_sections[] = { ".rela.got", ".rela.sdata", ".rela.sdata", (char *)0 }; - char **p; - - for (p = rela_sections; *p != (char *)0; p++) - { - s = bfd_get_section_by_name (dynobj, *p); - if (s != NULL) - s->_raw_size = 0; - } - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - reltext = false; - relplt = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - -#if 0 - if (strncmp (name, ".rela", 5) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is to handle .rela.bss and - .rel.plt. We must create it in - create_dynamic_sections, because it must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. */ - target = bfd_get_section_by_name (output_bfd, name + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - - if (strcmp (name, ".rela.plt") == 0) - relplt = true; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else -#endif - if (strcmp (name, ".plt") != 0 - && strcmp (name, ".got") != 0 - && strcmp (name, ".sdata") != 0 - && strcmp (name, ".sdata2") != 0 - && strcmp (name, ".rela.sdata") != 0 - && strcmp (name, ".rela.sdata2") != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in ppc_elf_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)) - return false; - - if (relplt) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return false; - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - /* If we are generating a shared library, we generate a section - symbol for each output section. These are local symbols, which - means that they must come first in the dynamic symbol table. - That means we must increment the dynamic symbol index of every - other dynamic symbol. */ - if (info->shared) - { - int c, i; - - c = bfd_count_sections (output_bfd); - elf_link_hash_traverse (elf_hash_table (info), - ppc_elf_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++) - { - elf_section_data (s)->dynindx = i; - /* These symbols will have no names, so we don't need to - fiddle with dynstr_index. */ - } - } - - return true; -} - - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -ppc_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - elf_linker_section_t *got; - elf_linker_section_t *sdata; - elf_linker_section_t *sdata2; - asection *sreloc; - - if (info->relocateable) - return true; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_check_relocs called for section %s\n", - bfd_get_section_name (abfd, sec)); -#endif - - /* Create the linker generated sections all the time so that the special - symbols are created. */ - if ((got = elf_linker_section (abfd, LINKER_SECTION_GOT)) == NULL) - { - got = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_GOT); - if (!got) - return false; - } - - if ((sdata = elf_linker_section (abfd, LINKER_SECTION_SDATA)) == NULL) - { - sdata = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA); - if (!sdata) - return false; - } - - - if ((sdata2 = elf_linker_section (abfd, LINKER_SECTION_SDATA2)) == NULL) - { - sdata2 = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA2); - if (!sdata2) - return false; - } - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - switch (ELF32_R_TYPE (rel->r_info)) - { - default: - break; - - /* GOT16 relocations */ - case R_PPC_GOT16: - case R_PPC_GOT16_LO: - case R_PPC_GOT16_HI: - case R_PPC_GOT16_HA: - if (got->rel_section == NULL - && (h != NULL || info->shared) - && !_bfd_elf_make_linker_section_rela (dynobj, got, 2)) - return false; - - if (!bfd_elf32_create_pointer_linker_section (abfd, info, got, h, rel)) - return false; - - break; - - /* Indirect .sdata relocation */ - case R_PPC_EMB_SDAI16: - if (got->rel_section == NULL - && (h != NULL || info->shared) - && !_bfd_elf_make_linker_section_rela (dynobj, got, 2)) - return false; - - if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata, h, rel)) - return false; - - break; - - /* Indirect .sdata2 relocation */ - case R_PPC_EMB_SDA2I16: - if (got->rel_section == NULL - && (h != NULL || info->shared) - && !_bfd_elf_make_linker_section_rela (dynobj, got, 2)) - return false; - - if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata2, h, rel)) - return false; - - break; - -#if 0 - case R_PPC_PLT32: - case R_PPC_PLTREL24: - case R_PPC_PLT16_LO: - case R_PPC_PLT16_HI: - case R_PPC_PLT16_HA: -#ifdef DEBUG - fprintf (stderr, "Reloc requires a PLT entry\n"); -#endif - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code without - linking in any dynamic objects, in which case we don't - need to generate a procedure linkage table after all. */ - - if (h == NULL) - { - /* It does not make sense to have a procedure linkage - table entry for a local symbol. */ - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - break; - - case R_SPARC_PC10: - case R_SPARC_PC22: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_SPARC_DISP8: - case R_SPARC_DISP16: - case R_SPARC_DISP32: - case R_SPARC_WDISP30: - case R_SPARC_WDISP22: - if (h == NULL) - break; - /* Fall through. */ - case R_SPARC_8: - case R_SPARC_16: - case R_SPARC_32: - case R_SPARC_HI22: - case R_SPARC_22: - case R_SPARC_13: - case R_SPARC_LO10: - case R_SPARC_UA32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0) - { - /* When creating a shared object, we must copy these - relocs into the output file. We create a reloc - section in dynobj and make room for the reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rela); - } - - break; -#endif - } - } - - return true; -} - - -/* Hook called by the linker routine which adds symbols from an object - file. We use it to put .comm items in .sbss, and not .bss. */ - -/*ARGSUSED*/ -static boolean -ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp; - asection **secp; - bfd_vma *valp; -{ - if (sym->st_shndx == SHN_COMMON && sym->st_size <= bfd_get_gp_size (abfd)) - { - /* Common symbols less than or equal to -G nn bytes are automatically - put into .sdata. */ - elf_linker_section_t *sdata = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA); - if (!sdata->bss_section) - { - sdata->bss_section = bfd_make_section (elf_hash_table (info)->dynobj, sdata->bss_name); - sdata->bss_section->flags = (sdata->bss_section->flags & ~SEC_LOAD) | SEC_IS_COMMON; - } - - *secp = sdata->bss_section; - *valp = sym->st_size; - } - - return true; -} - - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -ppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_finish_dynamic_symbol called for %s\n", h->root.root.string); -#endif - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (splt != NULL && srela != NULL); - - /* Fill in the entry in the procedure linkage table. */ -#if 0 - bfd_put_32 (output_bfd, - PLT_ENTRY_WORD0 + h->plt_offset, - splt->contents + h->plt_offset); - bfd_put_32 (output_bfd, - (PLT_ENTRY_WORD1 - + (((- (h->plt_offset + 4)) >> 2) & 0x3fffff)), - splt->contents + h->plt_offset + 4); - bfd_put_32 (output_bfd, PLT_ENTRY_WORD2, - splt->contents + h->plt_offset + 8); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_JMP_SLOT); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + h->plt_offset / PLT_ENTRY_SIZE - 4)); -#endif - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rela rela; - - /* This symbols needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); - BFD_ASSERT (s != NULL); - - rela.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark some specially defined symbols as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 - || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - - -/* Finish up the dynamic sections. */ - -static boolean -ppc_elf_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - asection *sdyn; - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *got = elf_linker_section (dynobj, LINKER_SECTION_GOT); - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n"); -#endif - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - boolean size; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - case DT_PLTGOT: name = ".plt"; size = false; break; - case DT_PLTRELSZ: name = ".rela.plt"; size = true; break; - case DT_JMPREL: name = ".rela.plt"; size = false; break; - default: name = NULL; size = false; break; - } - - if (name != NULL) - { - asection *s; - - s = bfd_get_section_by_name (output_bfd, name); - if (s == NULL) - dyn.d_un.d_val = 0; - else - { - if (! size) - dyn.d_un.d_ptr = s->vma; - else - { - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - } - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - } - } - } - - /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4 so that a function can - easily find the address of the _GLOBAL_OFFSET_TABLE_. */ - if (got) - { - unsigned char *contents = got->section->contents + got->hole_offset; - bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, contents); - - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - contents+4); - - elf_section_data (got->section->output_section)->this_hdr.sh_entsize = 4; - } - - if (info->shared) - { - asection *sdynsym; - asection *s; - Elf_Internal_Sym sym; - - /* Set up the section symbols for the output sections. */ - - sdynsym = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (sdynsym != NULL); - - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - - for (s = output_bfd->sections; s != NULL; s = s->next) - { - int indx; - - sym.st_value = s->vma; - - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (PTR) (((Elf32_External_Sym *) - sdynsym->contents) - + elf_section_data (s)->dynindx)); - } - - /* Set the sh_info field of the output .dynsym section to the - index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - bfd_count_sections (output_bfd) + 1; - } - - return true; -} - - -/* The RELOCATE_SECTION function is called by the ELF backend linker - to handle the relocations for a section. - - The relocs are always passed as Rela structures; if the section - actually uses Rel structures, the r_addend field will always be - zero. - - This function is responsible for adjust the section contents as - necessary, and (if using Rela relocs and generating a - relocateable output file) adjusting the reloc addend as - necessary. - - This function does not have to worry about setting the reloc - address or the reloc symbol index. - - LOCAL_SYMS is a pointer to the swapped in local symbols. - - LOCAL_SECTIONS is an array giving the section in the input file - corresponding to the st_shndx field of each local symbol. - - The global hash table entry for the global symbols can be found - via elf_sym_hashes (input_bfd). - - When generating relocateable output, this function must handle - STB_LOCAL/STT_SECTION symbols specially. The output symbol is - going to be the section symbol corresponding to the output - section, which means that the addend must be adjusted - accordingly. */ - -static boolean -ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *got = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_GOT) : NULL; - elf_linker_section_t *sdata = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA) : NULL; - elf_linker_section_t *sdata2 = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA2) : NULL; - Elf_Internal_Rela *rel = relocs; - Elf_Internal_Rela *relend = relocs + input_section->reloc_count; - boolean ret = true; - long insn; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n", - bfd_get_filename (input_bfd), - bfd_section_name(input_bfd, input_section), - (long)input_section->reloc_count, - (info->relocateable) ? " (relocatable)" : ""); -#endif - - if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */ - ppc_elf_howto_init (); - - for (; rel < relend; rel++) - { - enum ppc_reloc_type r_type = (enum ppc_reloc_type)ELF32_R_TYPE (rel->r_info); - bfd_vma offset = rel->r_offset; - bfd_vma addend = rel->r_addend; - bfd_reloc_status_type r = bfd_reloc_other; - Elf_Internal_Sym *sym = (Elf_Internal_Sym *)0; - asection *sec = (asection *)0; - struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)0; - const char *sym_name = (const char *)0; - reloc_howto_type *howto; - unsigned long r_symndx; - bfd_vma relocation; - - /* Unknown relocation handling */ - if ((unsigned)r_type >= (unsigned)R_PPC_max || !ppc_elf_howto_table[(int)r_type]) - { - (*_bfd_error_handler) ("%s: unknown relocation type %d", - bfd_get_filename (input_bfd), - (int)r_type); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - - howto = ppc_elf_howto_table[(int)r_type]; - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - addend = rel->r_addend += sec->output_offset + sym->st_value; - } - } - -#ifdef DEBUG - fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n", - howto->name, - (int)r_type, - r_symndx, - (long)offset, - (long)addend); -#endif - continue; - } - - /* This is a final link. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - sym_name = ""; - - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - sym_name = h->root.root.string; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared) - relocation = 0; - else - { - (*info->callbacks->undefined_symbol)(info, - h->root.root.string, - input_bfd, - input_section, - rel->r_offset); - ret = false; - continue; - } - } - - switch ((int)r_type) - { - default: - (*_bfd_error_handler) ("%s: unknown relocation type %d for symbol %s", - bfd_get_filename (input_bfd), - (int)r_type, sym_name); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - - /* relocations that need no special processing */ - case (int)R_PPC_NONE: - case (int)R_PPC_ADDR32: - case (int)R_PPC_ADDR24: - case (int)R_PPC_ADDR16: - case (int)R_PPC_ADDR16_LO: - case (int)R_PPC_ADDR16_HI: - case (int)R_PPC_ADDR14: - case (int)R_PPC_REL24: - case (int)R_PPC_REL14: - case (int)R_PPC_UADDR32: - case (int)R_PPC_UADDR16: - case (int)R_PPC_REL32: - break; - - /* branch taken prediction relocations */ - case (int)R_PPC_ADDR14_BRTAKEN: - case (int)R_PPC_REL14_BRTAKEN: - insn = bfd_get_32 (output_bfd, contents + offset); - if ((relocation - offset) & 0x8000) - insn &= ~BRANCH_PREDICT_BIT; - else - insn |= BRANCH_PREDICT_BIT; - bfd_put_32 (output_bfd, insn, contents + offset); - break; - - /* branch not taken predicition relocations */ - case (int)R_PPC_ADDR14_BRNTAKEN: - case (int)R_PPC_REL14_BRNTAKEN: - insn = bfd_get_32 (output_bfd, contents + offset); - if ((relocation - offset) & 0x8000) - insn |= BRANCH_PREDICT_BIT; - else - insn &= ~BRANCH_PREDICT_BIT; - bfd_put_32 (output_bfd, insn, contents + offset); - break; - - /* GOT16 relocations */ - case (int)R_PPC_GOT16: - case (int)R_PPC_GOT16_LO: - case (int)R_PPC_GOT16_HI: - case (int)R_PPC_GOT16_HA: - relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info, - got, h, relocation, rel, - R_PPC_RELATIVE); - break; - - /* Indirect .sdata relocation */ - case (int)R_PPC_EMB_SDAI16: - BFD_ASSERT (sdata != NULL); - relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info, - sdata, h, relocation, rel, - R_PPC_RELATIVE); - break; - - /* Indirect .sdata2 relocation */ - case (int)R_PPC_EMB_SDA2I16: - BFD_ASSERT (sdata2 != NULL); - relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info, - sdata2, h, relocation, rel, - R_PPC_RELATIVE); - break; - - /* Handle the TOC16 reloc. We want to use the offset within the .got - section, not the actual VMA. This is appropriate when generating - an embedded ELF object, for which the .got section acts like the - AIX .toc section. */ - case (int)R_PPC_TOC16: /* phony GOT16 relocations */ - BFD_ASSERT (sec != (asection *)0); - BFD_ASSERT (bfd_is_und_section (sec) - || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0 - || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0) - - addend -= sec->output_section->vma + sec->output_offset + 0x8000; - break; - - /* arithmetic adjust relocations */ - case (int)R_PPC_ADDR16_HA: - BFD_ASSERT (sec != (asection *)0); - addend += ((relocation + addend) & 0x8000) << 1; - break; - - /* relocate against _SDA_BASE_ */ - case (int)R_PPC_SDAREL16: - BFD_ASSERT (sec != (asection *)0); - if (strcmp (bfd_get_section_name (abfd, sec), ".sdata") != 0 - && strcmp (bfd_get_section_name (abfd, sec), ".sbss") != 0) - { - (*_bfd_error_handler) ("%s: The target (%s) of a %s relocation is in the wrong section (%s)", - bfd_get_filename (input_bfd), - sym_name, - ppc_elf_howto_table[ (int)r_type ]->name, - bfd_get_section_name (abfd, sec)); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - addend -= (sdata->sym_hash->root.u.def.value - + sdata->sym_hash->root.u.def.section->output_section->vma - + sdata->sym_hash->root.u.def.section->output_offset); - break; - - - /* relocate against _SDA2_BASE_ */ - case (int)R_PPC_EMB_SDA2REL: - BFD_ASSERT (sec != (asection *)0); - if (strcmp (bfd_get_section_name (abfd, sec), ".sdata2") != 0 - && strcmp (bfd_get_section_name (abfd, sec), ".sbss2") != 0) - { - (*_bfd_error_handler) ("%s: The target (%s) of a %s relocation is in the wrong section (%s)", - bfd_get_filename (input_bfd), - sym_name, - ppc_elf_howto_table[ (int)r_type ]->name, - bfd_get_section_name (abfd, sec)); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - addend -= (sdata2->sym_hash->root.u.def.value - + sdata2->sym_hash->root.u.def.section->output_section->vma - + sdata2->sym_hash->root.u.def.section->output_offset); - break; - - - /* relocate against either _SDA_BASE_, _SDA2_BASE_, or 0 */ - case (int)R_PPC_EMB_SDA21: - case (int)R_PPC_EMB_RELSDA: - { - const char *name = bfd_get_section_name (abfd, sec); - int reg; - - BFD_ASSERT (sec != (asection *)0); - if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0) - { - reg = 13; - addend -= (sdata->sym_hash->root.u.def.value - + sdata->sym_hash->root.u.def.section->output_section->vma - + sdata->sym_hash->root.u.def.section->output_offset); - } - - else if (strcmp (name, ".sdata2") == 0 || strcmp (name, ".sbss2") == 0) - { - reg = 2; - addend -= (sdata2->sym_hash->root.u.def.value - + sdata2->sym_hash->root.u.def.section->output_section->vma - + sdata2->sym_hash->root.u.def.section->output_offset); - } - - else if (strcmp (name, ".PPC.EMB.sdata0") == 0 || strcmp (name, ".PPC.EMB.sbss0") == 0) - { - reg = 0; - } - - else - { - (*_bfd_error_handler) ("%s: The target (%s) of a %s relocation is in the wrong section (%s)", - bfd_get_filename (input_bfd), - sym_name, - ppc_elf_howto_table[ (int)r_type ]->name, - bfd_get_section_name (abfd, sec)); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - - if (r_type == R_PPC_EMB_SDA21) - { /* fill in register field */ - insn = bfd_get_32 (output_bfd, contents + offset); - insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT); - bfd_put_32 (output_bfd, insn, contents + offset); - } - } - break; - - /* Relocate against the beginning of the section */ - case (int)R_PPC_SECTOFF: - case (int)R_PPC_SECTOFF_LO: - case (int)R_PPC_SECTOFF_HI: - BFD_ASSERT (sec != (asection *)0); - addend -= sec->output_section->vma; - break; - - case (int)R_PPC_SECTOFF_HA: - BFD_ASSERT (sec != (asection *)0); - addend -= sec->output_section->vma; - addend += ((relocation + addend) & 0x8000) << 1; - break; - - /* Negative relocations */ - case (int)R_PPC_EMB_NADDR32: - case (int)R_PPC_EMB_NADDR16: - case (int)R_PPC_EMB_NADDR16_LO: - case (int)R_PPC_EMB_NADDR16_HI: - addend -= 2*relocation; - break; - - case (int)R_PPC_EMB_NADDR16_HA: - addend -= 2*relocation; - addend += ((relocation + addend) & 0x8000) << 1; - break; - - /* NOP relocation that prevents garbage collecting linkers from omitting a - reference. */ - case (int)R_PPC_EMB_MRKREF: - continue; - - case (int)R_PPC_PLTREL24: - case (int)R_PPC_COPY: - case (int)R_PPC_GLOB_DAT: - case (int)R_PPC_JMP_SLOT: - case (int)R_PPC_RELATIVE: - case (int)R_PPC_LOCAL24PC: - case (int)R_PPC_PLT32: - case (int)R_PPC_PLTREL32: - case (int)R_PPC_PLT16_LO: - case (int)R_PPC_PLT16_HI: - case (int)R_PPC_PLT16_HA: - case (int)R_PPC_EMB_RELSEC16: - case (int)R_PPC_EMB_RELST_LO: - case (int)R_PPC_EMB_RELST_HI: - case (int)R_PPC_EMB_RELST_HA: - case (int)R_PPC_EMB_BIT_FLD: - (*_bfd_error_handler) ("%s: Relocation %s is not yet supported for symbol %s.", - bfd_get_filename (input_bfd), - ppc_elf_howto_table[ (int)r_type ]->name, - sym_name); - - bfd_set_error (bfd_error_invalid_operation); - ret = false; - continue; - } - - -#ifdef DEBUG - fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n", - howto->name, - (int)r_type, - sym_name, - r_symndx, - (long)offset, - (long)addend); -#endif - - r = _bfd_final_link_relocate (howto, - input_bfd, - input_section, - contents, - offset, - relocation, - addend); - - if (r != bfd_reloc_ok) - { - ret = false; - switch (r) - { - default: - break; - - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - break; - - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - - (*info->callbacks->reloc_overflow)(info, - name, - howto->name, - (bfd_vma) 0, - input_bfd, - input_section, - offset); - } - break; - - } - } - } - - -#ifdef DEBUG - fprintf (stderr, "\n"); -#endif - - return ret; -} - - -#define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec -#define TARGET_LITTLE_NAME "elf32-powerpcle" -#define TARGET_BIG_SYM bfd_elf32_powerpc_vec -#define TARGET_BIG_NAME "elf32-powerpc" -#define ELF_ARCH bfd_arch_powerpc -#define ELF_MACHINE_CODE EM_PPC -#define ELF_MAXPAGESIZE 0x10000 -#define elf_info_to_howto ppc_elf_info_to_howto - -#ifdef EM_CYGNUS_POWERPC -#define ELF_MACHINE_ALT1 EM_CYGNUS_POWERPC -#endif - -#ifdef EM_PPC_OLD -#define ELF_MACHINE_ALT2 EM_PPC_OLD -#endif - -#define bfd_elf32_bfd_copy_private_bfd_data ppc_elf_copy_private_bfd_data -#define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data -#define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags -#define bfd_elf32_bfd_reloc_type_lookup ppc_elf_reloc_type_lookup -#define elf_backend_section_from_shdr ppc_elf_section_from_shdr -#define elf_backend_relocate_section ppc_elf_relocate_section -#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs ppc_elf_check_relocs -#define elf_backend_adjust_dynamic_symbol ppc_elf_adjust_dynamic_symbol -#define elf_backend_add_symbol_hook ppc_elf_add_symbol_hook -#define elf_backend_size_dynamic_sections ppc_elf_size_dynamic_sections -#define elf_backend_finish_dynamic_symbol ppc_elf_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections -#define elf_backend_fake_sections ppc_elf_fake_sections -#define elf_backend_additional_program_headers ppc_elf_additional_program_headers -#define elf_backend_modify_segment_map ppc_elf_modify_segment_map - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-sparc.c b/contrib/gdb/bfd/elf32-sparc.c deleted file mode 100644 index 918eb00e2a0..00000000000 --- a/contrib/gdb/bfd/elf32-sparc.c +++ /dev/null @@ -1,1795 +0,0 @@ -/* SPARC-specific support for 32-bit ELF - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf/sparc.h" - -static reloc_howto_type *elf32_sparc_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static boolean elf32_sparc_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean elf32_sparc_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf32_sparc_adjust_dynindx - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf32_sparc_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf32_sparc_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean elf32_sparc_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean elf32_sparc_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf32_sparc_merge_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean elf32_sparc_object_p - PARAMS ((bfd *)); -static void elf32_sparc_final_write_processing - PARAMS ((bfd *, boolean)); - -/* The howto table and associated functions. - ??? elf64-sparc.c has its own copy for the moment to ease transition - since some of the relocation values have changed. At some point we'll - want elf64-sparc.c to switch over and use this table. - ??? Do we want to recognize (or flag as errors) some of the 64 bit entries - if the target is elf32-sparc. -*/ - -static bfd_reloc_status_type sparc_elf_notsupported_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type sparc_elf_wdisp16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - -reloc_howto_type _bfd_sparc_elf_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UA32", false,0,0x00000000,true), - HOWTO(R_SPARC_PLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_HIPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HIPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_LOPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LOPLT10", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT10", false,0,0x00000000,true), - HOWTO(R_SPARC_10, 0,2,10,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", false,0,0x000003ff,true), - HOWTO(R_SPARC_11, 0,2,11,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", false,0,0x000007ff,true), - /* ??? If we need to handle R_SPARC_64 then we need (figuratively) - --enable-64-bit-bfd. That causes objdump to print address as 64 bits - which we really don't want on an elf32-sparc system. There may be other - consequences which we may not want (at least not until it's proven they're - necessary) so for now these are only enabled ifdef BFD64. */ -#ifdef BFD64 - HOWTO(R_SPARC_64, 0,4,00,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", false,0,~ (bfd_vma) 0, true), - /* ??? These don't make sense except in 64 bit systems so they're disabled - ifndef BFD64 too (for now). */ - HOWTO(R_SPARC_OLO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_OLO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_HH22, 42,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HM10, 32,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_LM22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HH22, 42,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HM10, 32,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC_LM22, 10,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), -#else - HOWTO(R_SPARC_64, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_64", false,0,0x00000000,true), - HOWTO(R_SPARC_OLO10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_OLO10", false,0,0x00000000,true), - HOWTO(R_SPARC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HH22", false,0,0x00000000,true), - HOWTO(R_SPARC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HM10", false,0,0x00000000,true), - HOWTO(R_SPARC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LM22", false,0,0x00000000,true), - HOWTO(R_SPARC_PC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HH22", false,0,0x00000000,true), - HOWTO(R_SPARC_PC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HM10", false,0,0x00000000,true), - HOWTO(R_SPARC_PC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_LM22", false,0,0x00000000,true), -#endif - HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true), - HOWTO(R_SPARC_WDISP19, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true), - HOWTO(R_SPARC_GLOB_JMP, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true), - HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true), - HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true), -}; - -struct elf_reloc_map { - unsigned char bfd_reloc_val; - unsigned char elf_reloc_val; -}; - -static CONST struct elf_reloc_map sparc_reloc_map[] = -{ - { BFD_RELOC_NONE, R_SPARC_NONE, }, - { BFD_RELOC_16, R_SPARC_16, }, - { BFD_RELOC_8, R_SPARC_8 }, - { BFD_RELOC_8_PCREL, R_SPARC_DISP8 }, - /* ??? This might cause us to need separate functions in elf{32,64}-sparc.c - (we could still have just one table), but is this reloc ever used? */ - { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */ - { BFD_RELOC_32, R_SPARC_32 }, - { BFD_RELOC_32_PCREL, R_SPARC_DISP32 }, - { BFD_RELOC_HI22, R_SPARC_HI22 }, - { BFD_RELOC_LO10, R_SPARC_LO10, }, - { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 }, - { BFD_RELOC_SPARC22, R_SPARC_22 }, - { BFD_RELOC_SPARC13, R_SPARC_13 }, - { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 }, - { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 }, - { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 }, - { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 }, - { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 }, - { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 }, - { BFD_RELOC_SPARC_COPY, R_SPARC_COPY }, - { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT }, - { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT }, - { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE }, - { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 }, - /* ??? Doesn't dwarf use this? */ -/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */ - {BFD_RELOC_SPARC_10, R_SPARC_10}, - {BFD_RELOC_SPARC_11, R_SPARC_11}, - {BFD_RELOC_SPARC_64, R_SPARC_64}, - {BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10}, - {BFD_RELOC_SPARC_HH22, R_SPARC_HH22}, - {BFD_RELOC_SPARC_HM10, R_SPARC_HM10}, - {BFD_RELOC_SPARC_LM22, R_SPARC_LM22}, - {BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22}, - {BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10}, - {BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22}, - {BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16}, - {BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19}, - {BFD_RELOC_SPARC_GLOB_JMP, R_SPARC_GLOB_JMP}, - {BFD_RELOC_SPARC_7, R_SPARC_7}, - {BFD_RELOC_SPARC_5, R_SPARC_5}, - {BFD_RELOC_SPARC_6, R_SPARC_6}, -}; - -static reloc_howto_type * -elf32_sparc_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++) - { - if (sparc_reloc_map[i].bfd_reloc_val == code) - return &_bfd_sparc_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val]; - } - return 0; -} - -/* We need to use ELF32_R_TYPE so we have our own copy of this function, - and elf64-sparc.c has its own copy. */ - -static void -elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_SPARC_max); - cache_ptr->howto = &_bfd_sparc_elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -/* For unsupported relocs. */ - -static bfd_reloc_status_type -sparc_elf_notsupported_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return bfd_reloc_notsupported; -} - -/* Handle the WDISP16 reloc. */ - -static bfd_reloc_status_type -sparc_elf_wdisp16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_vma x; - - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != NULL) - return bfd_reloc_continue; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - relocation = (symbol->value - + symbol->section->output_section->vma - + symbol->section->output_offset); - relocation += reloc_entry->addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= reloc_entry->address; - - x = bfd_get_32 (abfd, (char *) data + reloc_entry->address); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (abfd, x, (char *) data + reloc_entry->address); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - return bfd_reloc_overflow; - else - return bfd_reloc_ok; -} - -/* Functions for the SPARC ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" - -/* The nop opcode we use. */ - -#define SPARC_NOP 0x01000000 - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 12 - -/* The first four entries in a procedure linkage table are reserved, - and the initial contents are unimportant (we zero them out). - Subsequent entries look like this. See the SVR4 ABI SPARC - supplement to see how this works. */ - -/* sethi %hi(.-.plt0),%g1. We fill in the address later. */ -#define PLT_ENTRY_WORD0 0x03000000 -/* b,a .plt0. We fill in the offset later. */ -#define PLT_ENTRY_WORD1 0x30800000 -/* nop. */ -#define PLT_ENTRY_WORD2 SPARC_NOP - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -elf32_sparc_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *srelgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - local_got_offsets = elf_local_got_offsets (abfd); - - sgot = NULL; - srelgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_SPARC_GOT10: - case R_SPARC_GOT13: - case R_SPARC_GOT22: - /* This symbol requires a global offset table entry. */ - - if (dynobj == NULL) - { - /* Create the .got section. */ - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) - return false; - } - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (srelgot == NULL - && (h != NULL || info->shared)) - { - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - if (srelgot == NULL) - { - srelgot = bfd_make_section (dynobj, ".rela.got"); - if (srelgot == NULL - || ! bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; - } - } - - if (h != NULL) - { - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - h->got_offset = sgot->_raw_size; - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - else - { - /* This is a global offset table entry for a local - symbol. */ - if (local_got_offsets == NULL) - { - size_t size; - register unsigned int i; - - size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); - if (local_got_offsets == NULL) - return false; - elf_local_got_offsets (abfd) = local_got_offsets; - for (i = 0; i < symtab_hdr->sh_info; i++) - local_got_offsets[i] = (bfd_vma) -1; - } - if (local_got_offsets[r_symndx] != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - local_got_offsets[r_symndx] = sgot->_raw_size; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_SPARC_RELATIVE reloc so that the - dynamic linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - } - - sgot->_raw_size += 4; - - break; - - case R_SPARC_WPLT30: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code without - linking in any dynamic objects, in which case we don't - need to generate a procedure linkage table after all. */ - - if (h == NULL) - { - /* It does not make sense to have a procedure linkage - table entry for a local symbol. */ - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - - break; - - case R_SPARC_PC10: - case R_SPARC_PC22: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_SPARC_DISP8: - case R_SPARC_DISP16: - case R_SPARC_DISP32: - case R_SPARC_WDISP30: - case R_SPARC_WDISP22: - case R_SPARC_WDISP19: - case R_SPARC_WDISP16: - if (h == NULL) - break; - /* Fall through. */ - case R_SPARC_8: - case R_SPARC_16: - case R_SPARC_32: - case R_SPARC_HI22: - case R_SPARC_22: - case R_SPARC_13: - case R_SPARC_LO10: - case R_SPARC_UA32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0) - { - /* When creating a shared object, we must copy these - relocs into the output file. We create a reloc - section in dynobj and make room for the reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rela); - } - - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -elf32_sparc_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - unsigned int power_of_two; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later - (although we could actually do it here). */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! elf_hash_table (info)->dynamic_sections_created) - { - /* This case can occur if we saw a WPLT30 reloc in an input - file, but none of the input files were dynamic objects. - In such a case, we don't actually need to build a - procedure linkage table, and we can just do a WDISP30 - reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); - return true; - } - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* The first four entries in .plt are reserved. */ - if (s->_raw_size == 0) - s->_raw_size = 4 * PLT_ENTRY_SIZE; - - /* The procedure linkage table has a maximum size. */ - if (s->_raw_size >= 0x400000) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - } - - h->plt_offset = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .rela.plt section. */ - - s = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf32_External_Rela); - - return true; - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return true; - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); - - /* If the symbol is currently defined in the .bss section of the - dynamic object, then it is OK to simply initialize it to zero. - If the symbol is in some other section, we must generate a - R_SPARC_COPY reloc to tell the dynamic linker to copy the initial - value out of the dynamic object and into the runtime process - image. We need to remember the offset into the .rel.bss section - we are going to use. */ - if ((h->root.u.def.section->flags & SEC_LOAD) != 0) - { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rela.bss"); - BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf32_External_Rela); - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - power_of_two = bfd_log2 (h->size); - if (power_of_two > 3) - power_of_two = 3; - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, - (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (! bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; - } - - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -elf32_sparc_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean reltext; - boolean relplt; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - - /* Make space for the trailing nop in .plt. */ - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - if (s->_raw_size > 0) - s->_raw_size += 4; - } - else - { - /* We may have created entries in the .rela.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rela.got, - which will cause it to get stripped from the output file - below. */ - s = bfd_get_section_by_name (dynobj, ".rela.got"); - if (s != NULL) - s->_raw_size = 0; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - reltext = false; - relplt = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - - if (strncmp (name, ".rela", 5) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is to handle .rela.bss and - .rel.plt. We must create it in - create_dynamic_sections, because it must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. */ - target = bfd_get_section_by_name (output_bfd, name + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - - if (strcmp (name, ".rela.plt") == 0) - relplt = true; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else if (strcmp (name, ".plt") != 0 - && strcmp (name, ".got") != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf32_sparc_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)) - return false; - - if (relplt) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return false; - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - /* If we are generating a shared library, we generate a section - symbol for each output section. These are local symbols, which - means that they must come first in the dynamic symbol table. - That means we must increment the dynamic symbol index of every - other dynamic symbol. */ - if (info->shared) - { - int c, i; - - c = bfd_count_sections (output_bfd); - elf_link_hash_traverse (elf_hash_table (info), - elf32_sparc_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++) - { - elf_section_data (s)->dynindx = i; - /* These symbols will have no names, so we don't need to - fiddle with dynstr_index. */ - } - } - - return true; -} - -/* Increment the index of a dynamic symbol by a given amount. Called - via elf_link_hash_traverse. */ - -static boolean -elf32_sparc_adjust_dynindx (h, cparg) - struct elf_link_hash_entry *h; - PTR cparg; -{ - int *cp = (int *) cparg; - - if (h->dynindx != -1) - h->dynindx += *cp; - return true; -} - -/* Relocate a SPARC ELF section. */ - -static boolean -elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - asection *sgot; - asection *splt; - asection *sreloc; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - - sgot = NULL; - splt = NULL; - sreloc = NULL; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_SPARC_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = _bfd_sparc_elf_howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if ((r_type == R_SPARC_WPLT30 - && h->plt_offset != (bfd_vma) -1) - || ((r_type == R_SPARC_GOT10 - || r_type == R_SPARC_GOT13 - || r_type == R_SPARC_GOT22) - && elf_hash_table (info)->dynamic_sections_created - && (! info->shared - || ! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (input_section->flags & SEC_ALLOC) != 0 - && (r_type == R_SPARC_8 - || r_type == R_SPARC_16 - || r_type == R_SPARC_32 - || r_type == R_SPARC_DISP8 - || r_type == R_SPARC_DISP16 - || r_type == R_SPARC_DISP32 - || r_type == R_SPARC_WDISP30 - || r_type == R_SPARC_WDISP22 - || r_type == R_SPARC_WDISP19 - || r_type == R_SPARC_WDISP16 - || r_type == R_SPARC_HI22 - || r_type == R_SPARC_22 - || r_type == R_SPARC_13 - || r_type == R_SPARC_LO10 - || r_type == R_SPARC_UA32 - || ((r_type == R_SPARC_PC10 - || r_type == R_SPARC_PC22) - && strcmp (h->root.root.string, - "_GLOBAL_OFFSET_TABLE_") != 0)))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - switch (r_type) - { - case R_SPARC_GOT10: - case R_SPARC_GOT13: - case R_SPARC_GOT22: - /* Relocation is to the entry for this symbol in the global - offset table. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (h != NULL) - { - bfd_vma off; - - off = h->got_offset; - BFD_ASSERT (off != (bfd_vma) -1); - - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global offset table. Since the offset must - always be a multiple of 4, we use the least - significant bit to record whether we have - initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - sgot->contents + off); - h->got_offset |= 1; - } - } - - relocation = sgot->output_offset + off; - } - else - { - bfd_vma off; - - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 4. We use - the least significant bit to record whether we have - already processed this entry. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, sgot->contents + off); - - if (info->shared) - { - asection *srelgot; - Elf_Internal_Rela outrel; - - /* We need to generate a R_SPARC_RELATIVE reloc - for the dynamic linker. */ - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); - - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + off); - outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE); - outrel.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; - } - - local_got_offsets[r_symndx] |= 1; - } - - relocation = sgot->output_offset + off; - } - - break; - - case R_SPARC_WPLT30: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - BFD_ASSERT (h != NULL); - - if (h->plt_offset == (bfd_vma) -1) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - break; - - case R_SPARC_PC10: - case R_SPARC_PC22: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_SPARC_DISP8: - case R_SPARC_DISP16: - case R_SPARC_DISP32: - case R_SPARC_WDISP30: - case R_SPARC_WDISP22: - case R_SPARC_WDISP19: - case R_SPARC_WDISP16: - if (h == NULL) - break; - /* Fall through. */ - case R_SPARC_8: - case R_SPARC_16: - case R_SPARC_32: - case R_SPARC_HI22: - case R_SPARC_22: - case R_SPARC_13: - case R_SPARC_LO10: - case R_SPARC_UA32: - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0) - { - Elf_Internal_Rela outrel; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - BFD_ASSERT (h->dynindx != -1); - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - outrel.r_addend = rel->r_addend; - } - else - { - if (r_type == R_SPARC_32) - { - outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; - } - else - { - long indx; - - if (h == NULL) - sec = local_sections[r_symndx]; - else - { - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || (h->root.type - == bfd_link_hash_defweak)); - sec = h->root.u.def.section; - } - if (sec != NULL && bfd_is_abs_section (sec)) - indx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - asection *osec; - - osec = sec->output_section; - indx = elf_section_data (osec)->dynindx; - if (indx == 0) - abort (); - } - - outrel.r_info = ELF32_R_INFO (indx, r_type); - outrel.r_addend = relocation + rel->r_addend; - } - } - - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - /* This reloc will be computed at runtime, so there's no - need to do anything now. */ - continue; - } - - default: - break; - } - - if (r_type != R_SPARC_WDISP16) - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - else - { - bfd_vma x; - - relocation += rel->r_addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= rel->r_offset; - - x = bfd_get_32 (input_bfd, contents + rel->r_offset); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (input_bfd, x, contents + rel->r_offset); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - r = bfd_reloc_overflow; - else - r = bfd_reloc_ok; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - - dynobj = elf_hash_table (info)->dynobj; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (splt != NULL && srela != NULL); - - /* Fill in the entry in the procedure linkage table. */ - bfd_put_32 (output_bfd, - PLT_ENTRY_WORD0 + h->plt_offset, - splt->contents + h->plt_offset); - bfd_put_32 (output_bfd, - (PLT_ENTRY_WORD1 - + (((- (h->plt_offset + 4)) >> 2) & 0x3fffff)), - splt->contents + h->plt_offset + 4); - bfd_put_32 (output_bfd, PLT_ENTRY_WORD2, - splt->contents + h->plt_offset + 8); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_JMP_SLOT); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + h->plt_offset / PLT_ENTRY_SIZE - 4)); - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if (h->got_offset != (bfd_vma) -1) - { - asection *sgot; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the global offset table. Set it - up. */ - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - srela = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (sgot != NULL && srela != NULL); - - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset - + (h->got_offset &~ 1)); - - /* If this is a -Bsymbolic link, and the symbol is defined - locally, we just want to emit a RELATIVE reloc. The entry in - the global offset table will already have been initialized in - the relocate_section function. */ - if (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - rela.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE); - else - { - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_GLOB_DAT); - } - - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + srela->reloc_count)); - ++srela->reloc_count; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rela rela; - - /* This symbols needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); - BFD_ASSERT (s != NULL); - - rela.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_COPY); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark some specially defined symbols as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 - || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -elf32_sparc_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sdyn; - asection *sgot; - - dynobj = elf_hash_table (info)->dynobj; - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - boolean size; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - case DT_PLTGOT: name = ".plt"; size = false; break; - case DT_PLTRELSZ: name = ".rela.plt"; size = true; break; - case DT_JMPREL: name = ".rela.plt"; size = false; break; - default: name = NULL; size = false; break; - } - - if (name != NULL) - { - asection *s; - - s = bfd_get_section_by_name (output_bfd, name); - if (s == NULL) - dyn.d_un.d_val = 0; - else - { - if (! size) - dyn.d_un.d_ptr = s->vma; - else - { - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - } - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - } - } - - /* Clear the first four entries in the procedure linkage table, - and put a nop in the last four bytes. */ - if (splt->_raw_size > 0) - { - memset (splt->contents, 0, 4 * PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, SPARC_NOP, - splt->contents + splt->_raw_size - 4); - } - - elf_section_data (splt->output_section)->this_hdr.sh_entsize = - PLT_ENTRY_SIZE; - } - - /* Set the first entry in the global offset table to the address of - the dynamic section. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - if (sgot->_raw_size > 0) - { - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - if (info->shared) - { - asection *sdynsym; - asection *s; - Elf_Internal_Sym sym; - - /* Set up the section symbols for the output sections. */ - - sdynsym = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (sdynsym != NULL); - - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - - for (s = output_bfd->sections; s != NULL; s = s->next) - { - int indx; - - sym.st_value = s->vma; - - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (PTR) (((Elf32_External_Sym *) - sdynsym->contents) - + elf_section_data (s)->dynindx)); - } - - /* Set the sh_info field of the output .dynsym section to the - index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - bfd_count_sections (output_bfd) + 1; - } - - return true; -} - -/* Functions for dealing with the e_flags field. - - We don't define set_private_flags or copy_private_bfd_data because - the only currently defined values are based on the bfd mach number, - so we use the latter instead and defer setting e_flags until the - file is written out. */ - -/* Merge backend specific data from an object file to the output - object file when linking. */ - -static boolean -elf32_sparc_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - boolean error; - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - error = false; - -#if 0 - /* ??? The native linker doesn't do this so we can't (otherwise gcc would - have to know which linker is being used). Instead, the native linker - bumps up the architecture level when it has to. However, I still think - warnings like these are good, so it would be nice to have them turned on - by some option. */ - - /* If the output machine is normal sparc, we can't allow v9 input files. */ - if (bfd_get_mach (obfd) == bfd_mach_sparc - && (bfd_get_mach (ibfd) == bfd_mach_sparc_v8plus - || bfd_get_mach (ibfd) == bfd_mach_sparc_v8plusa)) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled for a v8plus system and target is v8", - bfd_get_filename (ibfd)); - } - /* If the output machine is v9, we can't allow v9+vis input files. */ - if (bfd_get_mach (obfd) == bfd_mach_sparc_v8plus - && bfd_get_mach (ibfd) == bfd_mach_sparc_v8plusa) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled for a v8plusa system and target is v8plus", - bfd_get_filename (ibfd)); - } -#else - if (bfd_get_mach (ibfd) >= bfd_mach_sparc_v9) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled for a 64 bit system and target is 32 bit", - bfd_get_filename (ibfd)); - } - else if (bfd_get_mach (obfd) < bfd_get_mach (ibfd)) - bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd)); -#endif - - if (error) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - return true; -} - -/* Set the right machine number. */ - -static boolean -elf32_sparc_object_p (abfd) - bfd *abfd; -{ - if (elf_elfheader (abfd)->e_machine == EM_SPARC32PLUS) - { - if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1) - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, - bfd_mach_sparc_v8plusa); - else if (elf_elfheader (abfd)->e_flags & EF_SPARC_32PLUS) - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, - bfd_mach_sparc_v8plus); - else - return false; - } - else - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc); -} - -/* The final processing done just before writing out the object file. - We need to set the e_machine field appropriately. */ - -static void -elf32_sparc_final_write_processing (abfd, linker) - bfd *abfd; - boolean linker; -{ - switch (bfd_get_mach (abfd)) - { - case bfd_mach_sparc : - break; /* nothing to do */ - case bfd_mach_sparc_v8plus : - elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; - elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; - elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS; - break; - case bfd_mach_sparc_v8plusa : - elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; - elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; - elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1; - break; - default : - abort (); - } -} - -#define TARGET_BIG_SYM bfd_elf32_sparc_vec -#define TARGET_BIG_NAME "elf32-sparc" -#define ELF_ARCH bfd_arch_sparc -#define ELF_MACHINE_CODE EM_SPARC -#define ELF_MACHINE_ALT1 EM_SPARC32PLUS -#define ELF_MAXPAGESIZE 0x10000 - -#define bfd_elf32_bfd_reloc_type_lookup elf32_sparc_reloc_type_lookup -#define elf_backend_create_dynamic_sections \ - _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs elf32_sparc_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - elf32_sparc_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - elf32_sparc_size_dynamic_sections -#define elf_backend_relocate_section elf32_sparc_relocate_section -#define elf_backend_finish_dynamic_symbol \ - elf32_sparc_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - elf32_sparc_finish_dynamic_sections -#define bfd_elf32_bfd_merge_private_bfd_data \ - elf32_sparc_merge_private_bfd_data -#define elf_backend_object_p elf32_sparc_object_p -#define elf_backend_final_write_processing \ - elf32_sparc_final_write_processing -#define elf_backend_want_got_plt 0 -#define elf_backend_plt_readonly 0 -#define elf_backend_want_plt_sym 1 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32.c b/contrib/gdb/bfd/elf32.c deleted file mode 100644 index f2229694406..00000000000 --- a/contrib/gdb/bfd/elf32.c +++ /dev/null @@ -1,23 +0,0 @@ -/* ELF 32-bit executable support for BFD. - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define ARCH_SIZE 32 - - -#include "elfcode.h" diff --git a/contrib/gdb/bfd/elf64-gen.c b/contrib/gdb/bfd/elf64-gen.c deleted file mode 100644 index 5daf4ee9f17..00000000000 --- a/contrib/gdb/bfd/elf64-gen.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Generic support for 64-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocations, but should be good enough - for GDB to read the file. */ - -#define TARGET_LITTLE_SYM bfd_elf64_little_generic_vec -#define TARGET_LITTLE_NAME "elf64-little" -#define TARGET_BIG_SYM bfd_elf64_big_generic_vec -#define TARGET_BIG_NAME "elf64-big" -#define ELF_ARCH bfd_arch_unknown -#define ELF_MACHINE_CODE EM_NONE -#define bfd_elf64_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#include "elf64-target.h" diff --git a/contrib/gdb/bfd/elf64-sparc.c b/contrib/gdb/bfd/elf64-sparc.c deleted file mode 100644 index 5059b803c62..00000000000 --- a/contrib/gdb/bfd/elf64-sparc.c +++ /dev/null @@ -1,421 +0,0 @@ -/* SPARC-specific support for 64-bit ELF - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* We need a published ABI spec for this. Until one comes out, don't - assume this'll remain unchanged forever. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -#define SPARC64_OLD_RELOCS -#include "elf/sparc.h" - -static reloc_howto_type *sparc64_elf_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); - -static boolean sparc64_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean sparc64_elf_object_p PARAMS ((bfd *)); - -/* The howto table and associated functions. - ??? Some of the relocation values have changed. Until we're ready - to upgrade, we have our own copy. At some point a non upward compatible - change will be made at which point this table can be deleted and we'll - use the one in elf32-sparc.c. */ - -static bfd_reloc_status_type sparc_elf_wdisp16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - -static reloc_howto_type sparc64_elf_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UA32", false,0,0x00000000,true), -#if 0 /* not used yet */ - HOWTO(R_SPARC_PLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_HIPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HIPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_LOPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LOPLT10", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT10", false,0,0x00000000,true), -#endif - HOWTO(R_SPARC_10, 0,2,10,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", false,0,0x000003ff,true), - HOWTO(R_SPARC_11, 0,2,11,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", false,0,0x000007ff,true), - HOWTO(R_SPARC_64, 0,4,00,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", false,0,~ (bfd_vma) 0, true), - HOWTO(R_SPARC_OLO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_OLO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_HH22, 42,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HM10, 32,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_LM22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HH22, 42,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HM10, 32,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC_LM22, 10,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true), - HOWTO(R_SPARC_WDISP19, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true), - HOWTO(R_SPARC_GLOB_JMP, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true), -#if 0 /* not used yet */ - HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true), - HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true), -#endif -}; - -struct elf_reloc_map { - unsigned char bfd_reloc_val; - unsigned char elf_reloc_val; -}; - -static CONST struct elf_reloc_map sparc_reloc_map[] = -{ - { BFD_RELOC_NONE, R_SPARC_NONE, }, - { BFD_RELOC_16, R_SPARC_16, }, - { BFD_RELOC_8, R_SPARC_8 }, - { BFD_RELOC_8_PCREL, R_SPARC_DISP8 }, - /* ??? This might cause us to need separate functions in elf{32,64}-sparc.c - (we could still have just one table), but is this reloc ever used? */ - { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */ - { BFD_RELOC_32, R_SPARC_32 }, - { BFD_RELOC_32_PCREL, R_SPARC_DISP32 }, - { BFD_RELOC_HI22, R_SPARC_HI22 }, - { BFD_RELOC_LO10, R_SPARC_LO10, }, - { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 }, - { BFD_RELOC_SPARC22, R_SPARC_22 }, - { BFD_RELOC_SPARC13, R_SPARC_13 }, - { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 }, - { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 }, - { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 }, - { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 }, - { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 }, - { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 }, - { BFD_RELOC_SPARC_COPY, R_SPARC_COPY }, - { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT }, - { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT }, - { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE }, - { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 }, - /* ??? Doesn't dwarf use this? */ -/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */ - {BFD_RELOC_SPARC_10, R_SPARC_10}, - {BFD_RELOC_SPARC_11, R_SPARC_11}, - {BFD_RELOC_SPARC_64, R_SPARC_64}, - {BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10}, - {BFD_RELOC_SPARC_HH22, R_SPARC_HH22}, - {BFD_RELOC_SPARC_HM10, R_SPARC_HM10}, - {BFD_RELOC_SPARC_LM22, R_SPARC_LM22}, - {BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22}, - {BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10}, - {BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22}, - {BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16}, - {BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19}, - {BFD_RELOC_SPARC_GLOB_JMP, R_SPARC_GLOB_JMP}, - {BFD_RELOC_SPARC_7, R_SPARC_7}, -#if 0 /* unused */ - {BFD_RELOC_SPARC_5, R_SPARC_5}, - {BFD_RELOC_SPARC_6, R_SPARC_6}, -#endif -}; - -static reloc_howto_type * -sparc64_elf_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++) - { - if (sparc_reloc_map[i].bfd_reloc_val == code) - return &sparc64_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val]; - } - return 0; -} - -static void -elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf64_Internal_Rela *dst; -{ - BFD_ASSERT (ELF64_R_TYPE (dst->r_info) < (unsigned int) R_SPARC_max); - cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE (dst->r_info)]; -} - -/* Handle the WDISP16 reloc. */ - -static bfd_reloc_status_type -sparc_elf_wdisp16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_vma x; - - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != NULL) - return bfd_reloc_continue; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - relocation = (symbol->value - + symbol->section->output_section->vma - + symbol->section->output_offset); - relocation += reloc_entry->addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= reloc_entry->address; - - x = bfd_get_32 (abfd, (char *) data + reloc_entry->address); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (abfd, x, (char *) data + reloc_entry->address); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - return bfd_reloc_overflow; - else - return bfd_reloc_ok; -} - -/* Relocate a SPARC64 ELF section. */ - -static boolean -sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF64_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_SPARC_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = sparc64_elf_howto_table + r_type; - - r_symndx = ELF64_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - if (r_type != R_SPARC_WDISP16) - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - else - { - bfd_vma x; - - relocation += rel->r_addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= rel->r_offset; - - x = bfd_get_32 (input_bfd, contents + rel->r_offset); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (input_bfd, x, contents + rel->r_offset); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - r = bfd_reloc_overflow; - else - r = bfd_reloc_ok; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = (bfd_elf_string_from_elf_section - (input_bfd, - symtab_hdr->sh_link, - sym->st_name)); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Set the right machine number for a SPARC64 ELF file. */ - -static boolean -sparc64_elf_object_p (abfd) - bfd *abfd; -{ - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9); -} - -#define TARGET_BIG_SYM bfd_elf64_sparc_vec -#define TARGET_BIG_NAME "elf64-sparc" -#define ELF_ARCH bfd_arch_sparc -#define ELF_MACHINE_CODE EM_SPARC64 -#define ELF_MAXPAGESIZE 0x100000 - -#define bfd_elf64_bfd_reloc_type_lookup sparc64_elf_reloc_type_lookup -#define elf_backend_relocate_section sparc64_elf_relocate_section -#define elf_backend_object_p sparc64_elf_object_p - -#include "elf64-target.h" diff --git a/contrib/gdb/bfd/elf64.c b/contrib/gdb/bfd/elf64.c deleted file mode 100644 index 69fb5b5e6e1..00000000000 --- a/contrib/gdb/bfd/elf64.c +++ /dev/null @@ -1,22 +0,0 @@ -/* ELF 64-bit executable support for BFD. - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define ARCH_SIZE 64 - -#include "elfcode.h" diff --git a/contrib/gdb/bfd/elfcode.h b/contrib/gdb/bfd/elfcode.h deleted file mode 100644 index a6199f0b0f4..00000000000 --- a/contrib/gdb/bfd/elfcode.h +++ /dev/null @@ -1,1406 +0,0 @@ -/* ELF executable support for BFD. - Copyright 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, from information published - in "UNIX System V Release 4, Programmers Guide: ANSI C and - Programming Support Tools". Sufficient support for gdb. - - Rewritten by Mark Eichin @ Cygnus Support, from information - published in "System V Application Binary Interface", chapters 4 - and 5, as well as the various "Processor Supplement" documents - derived from it. Added support for assembler and other object file - utilities. Further work done by Ken Raeburn (Cygnus Support), Michael - Meissner (Open Software Foundation), and Peter Hoogenboom (University - of Utah) to finish and extend this. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Problems and other issues to resolve. - - (1) BFD expects there to be some fixed number of "sections" in - the object file. I.E. there is a "section_count" variable in the - bfd structure which contains the number of sections. However, ELF - supports multiple "views" of a file. In particular, with current - implementations, executable files typically have two tables, a - program header table and a section header table, both of which - partition the executable. - - In ELF-speak, the "linking view" of the file uses the section header - table to access "sections" within the file, and the "execution view" - uses the program header table to access "segments" within the file. - "Segments" typically may contain all the data from one or more - "sections". - - Note that the section header table is optional in ELF executables, - but it is this information that is most useful to gdb. If the - section header table is missing, then gdb should probably try - to make do with the program header table. (FIXME) - - (2) The code in this file is compiled twice, once in 32-bit mode and - once in 64-bit mode. More of it should be made size-independent - and moved into elf.c. - - (3) ELF section symbols are handled rather sloppily now. This should - be cleaned up, and ELF section symbols reconciled with BFD section - symbols. - - (4) We need a published spec for 64-bit ELF. We've got some stuff here - that we're using for SPARC V9 64-bit chips, but don't assume that - it's cast in stone. - */ - -#include /* For strrchr and friends */ -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* Renaming structures, typedefs, macros and functions to be size-specific. */ -#define Elf_External_Ehdr NAME(Elf,External_Ehdr) -#define Elf_External_Sym NAME(Elf,External_Sym) -#define Elf_External_Shdr NAME(Elf,External_Shdr) -#define Elf_External_Phdr NAME(Elf,External_Phdr) -#define Elf_External_Rel NAME(Elf,External_Rel) -#define Elf_External_Rela NAME(Elf,External_Rela) -#define Elf_External_Dyn NAME(Elf,External_Dyn) - -#define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command) -#define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal) -#define elf_core_file_matches_executable_p \ - NAME(bfd_elf,core_file_matches_executable_p) -#define elf_object_p NAME(bfd_elf,object_p) -#define elf_core_file_p NAME(bfd_elf,core_file_p) -#define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound) -#define elf_get_dynamic_symtab_upper_bound \ - NAME(bfd_elf,get_dynamic_symtab_upper_bound) -#define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in) -#define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in) -#define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out) -#define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out) -#define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in) -#define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out) -#define elf_swap_phdr_in NAME(bfd_elf,swap_phdr_in) -#define elf_swap_phdr_out NAME(bfd_elf,swap_phdr_out) -#define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in) -#define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out) -#define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) -#define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) -#define elf_get_symtab NAME(bfd_elf,get_symtab) -#define elf_canonicalize_dynamic_symtab \ - NAME(bfd_elf,canonicalize_dynamic_symtab) -#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol) -#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info) -#define elf_get_lineno NAME(bfd_elf,get_lineno) -#define elf_set_arch_mach NAME(bfd_elf,set_arch_mach) -#define elf_find_nearest_line NAME(bfd_elf,find_nearest_line) -#define elf_sizeof_headers NAME(bfd_elf,sizeof_headers) -#define elf_set_section_contents NAME(bfd_elf,set_section_contents) -#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto) -#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel) -#define elf_find_section NAME(bfd_elf,find_section) -#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols) -#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry) -#define elf_link_create_dynamic_sections \ - NAME(bfd_elf,link_create_dynamic_sections) -#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol -#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link) -#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section) -#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section) - -#if ARCH_SIZE == 64 -#define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF64_R_SYM(X) -#define ELF_R_TYPE(X) ELF64_R_TYPE(X) -#define ELFCLASS ELFCLASS64 -#define FILE_ALIGN 8 -#define LOG_FILE_ALIGN 3 -#endif -#if ARCH_SIZE == 32 -#define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF32_R_SYM(X) -#define ELF_R_TYPE(X) ELF32_R_TYPE(X) -#define ELFCLASS ELFCLASS32 -#define FILE_ALIGN 4 -#define LOG_FILE_ALIGN 2 -#endif - -/* Forward declarations of static functions */ - -#define elf_stringtab_init _bfd_elf_stringtab_init - -extern struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void)); -#define section_from_elf_index bfd_section_from_elf_index -extern boolean bfd_section_from_phdr PARAMS ((bfd *, Elf_Internal_Phdr *, - int)); - -static long elf_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean)); - -static boolean elf_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **)); - - int _bfd_elf_symbol_from_bfd_symbol PARAMS ((bfd *, - struct symbol_cache_entry **)); - -static boolean validate_reloc PARAMS ((bfd *, arelent *)); -static void write_relocs PARAMS ((bfd *, asection *, PTR)); - - boolean bfd_section_from_shdr PARAMS ((bfd *, unsigned int shindex)); - -#ifdef DEBUG -static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *)); -static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *)); -static char *elf_symbol_flags PARAMS ((flagword)); -#endif - -/* Structure swapping routines */ - -/* Should perhaps use put_offset, put_word, etc. For now, the two versions - can be handled by explicitly specifying 32 bits or "the long type". */ -#if ARCH_SIZE == 64 -#define put_word bfd_h_put_64 -#define get_word bfd_h_get_64 -#endif -#if ARCH_SIZE == 32 -#define put_word bfd_h_put_32 -#define get_word bfd_h_get_32 -#endif - -/* Translate an ELF symbol in external format into an ELF symbol in internal - format. */ - -void -elf_swap_symbol_in (abfd, src, dst) - bfd *abfd; - Elf_External_Sym *src; - Elf_Internal_Sym *dst; -{ - dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name); - dst->st_value = get_word (abfd, (bfd_byte *) src->st_value); - dst->st_size = get_word (abfd, (bfd_byte *) src->st_size); - dst->st_info = bfd_h_get_8 (abfd, (bfd_byte *) src->st_info); - dst->st_other = bfd_h_get_8 (abfd, (bfd_byte *) src->st_other); - dst->st_shndx = bfd_h_get_16 (abfd, (bfd_byte *) src->st_shndx); -} - -/* Translate an ELF symbol in internal format into an ELF symbol in external - format. */ - -void -elf_swap_symbol_out (abfd, src, cdst) - bfd *abfd; - Elf_Internal_Sym *src; - PTR cdst; -{ - Elf_External_Sym *dst = (Elf_External_Sym *) cdst; - bfd_h_put_32 (abfd, src->st_name, dst->st_name); - put_word (abfd, src->st_value, dst->st_value); - put_word (abfd, src->st_size, dst->st_size); - bfd_h_put_8 (abfd, src->st_info, dst->st_info); - bfd_h_put_8 (abfd, src->st_other, dst->st_other); - bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx); -} - - -/* Translate an ELF file header in external format into an ELF file header in - internal format. */ - -static void -elf_swap_ehdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Ehdr *src; - Elf_Internal_Ehdr *dst; -{ - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - dst->e_type = bfd_h_get_16 (abfd, (bfd_byte *) src->e_type); - dst->e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src->e_machine); - dst->e_version = bfd_h_get_32 (abfd, (bfd_byte *) src->e_version); - dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry); - dst->e_phoff = get_word (abfd, (bfd_byte *) src->e_phoff); - dst->e_shoff = get_word (abfd, (bfd_byte *) src->e_shoff); - dst->e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->e_flags); - dst->e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_ehsize); - dst->e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phentsize); - dst->e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phnum); - dst->e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shentsize); - dst->e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shnum); - dst->e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shstrndx); -} - -/* Translate an ELF file header in internal format into an ELF file header in - external format. */ - -static void -elf_swap_ehdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Ehdr *src; - Elf_External_Ehdr *dst; -{ - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_16 (abfd, src->e_type, dst->e_type); - bfd_h_put_16 (abfd, src->e_machine, dst->e_machine); - bfd_h_put_32 (abfd, src->e_version, dst->e_version); - put_word (abfd, src->e_entry, dst->e_entry); - put_word (abfd, src->e_phoff, dst->e_phoff); - put_word (abfd, src->e_shoff, dst->e_shoff); - bfd_h_put_32 (abfd, src->e_flags, dst->e_flags); - bfd_h_put_16 (abfd, src->e_ehsize, dst->e_ehsize); - bfd_h_put_16 (abfd, src->e_phentsize, dst->e_phentsize); - bfd_h_put_16 (abfd, src->e_phnum, dst->e_phnum); - bfd_h_put_16 (abfd, src->e_shentsize, dst->e_shentsize); - bfd_h_put_16 (abfd, src->e_shnum, dst->e_shnum); - bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx); -} - - -/* Translate an ELF section header table entry in external format into an - ELF section header table entry in internal format. */ - -static void -elf_swap_shdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Shdr *src; - Elf_Internal_Shdr *dst; -{ - dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name); - dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type); - dst->sh_flags = get_word (abfd, (bfd_byte *) src->sh_flags); - dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr); - dst->sh_offset = get_word (abfd, (bfd_byte *) src->sh_offset); - dst->sh_size = get_word (abfd, (bfd_byte *) src->sh_size); - dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link); - dst->sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_info); - dst->sh_addralign = get_word (abfd, (bfd_byte *) src->sh_addralign); - dst->sh_entsize = get_word (abfd, (bfd_byte *) src->sh_entsize); - dst->bfd_section = NULL; - dst->contents = NULL; -} - -/* Translate an ELF section header table entry in internal format into an - ELF section header table entry in external format. */ - -static void -elf_swap_shdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Shdr *src; - Elf_External_Shdr *dst; -{ - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_32 (abfd, src->sh_name, dst->sh_name); - bfd_h_put_32 (abfd, src->sh_type, dst->sh_type); - put_word (abfd, src->sh_flags, dst->sh_flags); - put_word (abfd, src->sh_addr, dst->sh_addr); - put_word (abfd, src->sh_offset, dst->sh_offset); - put_word (abfd, src->sh_size, dst->sh_size); - bfd_h_put_32 (abfd, src->sh_link, dst->sh_link); - bfd_h_put_32 (abfd, src->sh_info, dst->sh_info); - put_word (abfd, src->sh_addralign, dst->sh_addralign); - put_word (abfd, src->sh_entsize, dst->sh_entsize); -} - - -/* Translate an ELF program header table entry in external format into an - ELF program header table entry in internal format. */ - -void -elf_swap_phdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Phdr *src; - Elf_Internal_Phdr *dst; -{ - dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type); - dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags); - dst->p_offset = get_word (abfd, (bfd_byte *) src->p_offset); - dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr); - dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr); - dst->p_filesz = get_word (abfd, (bfd_byte *) src->p_filesz); - dst->p_memsz = get_word (abfd, (bfd_byte *) src->p_memsz); - dst->p_align = get_word (abfd, (bfd_byte *) src->p_align); -} - -void -elf_swap_phdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Phdr *src; - Elf_External_Phdr *dst; -{ - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_32 (abfd, src->p_type, dst->p_type); - put_word (abfd, src->p_offset, dst->p_offset); - put_word (abfd, src->p_vaddr, dst->p_vaddr); - put_word (abfd, src->p_paddr, dst->p_paddr); - put_word (abfd, src->p_filesz, dst->p_filesz); - put_word (abfd, src->p_memsz, dst->p_memsz); - bfd_h_put_32 (abfd, src->p_flags, dst->p_flags); - put_word (abfd, src->p_align, dst->p_align); -} - -/* Translate an ELF reloc from external format to internal format. */ -INLINE void -elf_swap_reloc_in (abfd, src, dst) - bfd *abfd; - Elf_External_Rel *src; - Elf_Internal_Rel *dst; -{ - dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); - dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); -} - -INLINE void -elf_swap_reloca_in (abfd, src, dst) - bfd *abfd; - Elf_External_Rela *src; - Elf_Internal_Rela *dst; -{ - dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); - dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); - dst->r_addend = get_word (abfd, (bfd_byte *) src->r_addend); -} - -/* Translate an ELF reloc from internal format to external format. */ -INLINE void -elf_swap_reloc_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Rel *src; - Elf_External_Rel *dst; -{ - put_word (abfd, src->r_offset, dst->r_offset); - put_word (abfd, src->r_info, dst->r_info); -} - -INLINE void -elf_swap_reloca_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Rela *src; - Elf_External_Rela *dst; -{ - put_word (abfd, src->r_offset, dst->r_offset); - put_word (abfd, src->r_info, dst->r_info); - put_word (abfd, src->r_addend, dst->r_addend); -} - -INLINE void -elf_swap_dyn_in (abfd, p, dst) - bfd *abfd; - const PTR p; - Elf_Internal_Dyn *dst; -{ - const Elf_External_Dyn *src = (const Elf_External_Dyn *) p; - - dst->d_tag = get_word (abfd, src->d_tag); - dst->d_un.d_val = get_word (abfd, src->d_un.d_val); -} - -INLINE void -elf_swap_dyn_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Dyn *src; - Elf_External_Dyn *dst; -{ - put_word (abfd, src->d_tag, dst->d_tag); - put_word (abfd, src->d_un.d_val, dst->d_un.d_val); -} - -/* ELF .o/exec file reading */ - - -/* Begin processing a given object. - - First we validate the file by reading in the ELF header and checking - the magic number. */ - -static INLINE boolean -elf_file_p (x_ehdrp) - Elf_External_Ehdr *x_ehdrp; -{ - return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0) - && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1) - && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2) - && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); -} - -/* Check to see if the file associated with ABFD matches the target vector - that ABFD points to. - - Note that we may be called several times with the same ABFD, but different - target vectors, most of which will not match. We have to avoid leaving - any side effects in ABFD, or any data it points to (like tdata), if the - file does not match the target vector. */ - -const bfd_target * -elf_object_p (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr x_shdr; /* Section header table entry, external form */ - Elf_Internal_Shdr *i_shdrp = NULL; /* Section header table, internal form */ - unsigned int shindex; - char *shstrtab; /* Internal copy of section header stringtab */ - struct elf_backend_data *ebd; - struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd); - struct elf_obj_tdata *new_tdata = NULL; - - /* Read in the ELF header in external format. */ - - if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry, and it must have a - section header table (FIXME: See comments re sections at top of this - file). */ - - if ((elf_file_p (&x_ehdr) == false) || - (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) || - (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)) - goto got_wrong_format_error; - - /* Check that file's byte order matches xvec's */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (! bfd_header_big_endian (abfd)) - goto got_wrong_format_error; - break; - case ELFDATA2LSB: /* Little-endian */ - if (! bfd_header_little_endian (abfd)) - goto got_wrong_format_error; - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - goto got_wrong_format_error; - } - - /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - new_tdata = ((struct elf_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct elf_obj_tdata))); - if (new_tdata == NULL) - goto got_no_match; - elf_tdata (abfd) = new_tdata; - - /* Now that we know the byte order, swap in the rest of the header */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - /* If there is no section header table, we're hosed. */ - if (i_ehdrp->e_shoff == 0) - goto got_wrong_format_error; - - /* As a simple sanity check, verify that the what BFD thinks is the - size of each section header table entry actually matches the size - recorded in the file. */ - if (i_ehdrp->e_shentsize != sizeof (x_shdr)) - goto got_wrong_format_error; - - ebd = get_elf_backend_data (abfd); - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - if (ebd->elf_machine_code != i_ehdrp->e_machine - && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1) - && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2)) - { - const bfd_target * const *target_ptr; - - if (ebd->elf_machine_code != EM_NONE) - goto got_wrong_format_error; - - /* This is the generic ELF target. Let it match any ELF target - for which we do not have a specific backend. */ - for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) - { - struct elf_backend_data *back; - - if ((*target_ptr)->flavour != bfd_target_elf_flavour) - continue; - back = (struct elf_backend_data *) (*target_ptr)->backend_data; - if (back->elf_machine_code == i_ehdrp->e_machine) - { - /* target_ptr is an ELF backend which matches this - object file, so reject the generic ELF target. */ - goto got_wrong_format_error; - } - } - } - - if (i_ehdrp->e_type == ET_EXEC) - abfd->flags |= EXEC_P; - else if (i_ehdrp->e_type == ET_DYN) - abfd->flags |= DYNAMIC; - - if (i_ehdrp->e_phnum > 0) - abfd->flags |= D_PAGED; - - if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)) - goto got_no_match; - - /* Remember the entry point specified in the ELF file header. */ - bfd_get_start_address (abfd) = i_ehdrp->e_entry; - - /* Allocate space for a copy of the section header table in - internal form, seek to the section header table in the file, - read it in, and convert it to internal form. */ - i_shdrp = ((Elf_Internal_Shdr *) - bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum)); - elf_elfsections (abfd) = ((Elf_Internal_Shdr **) - bfd_alloc (abfd, - sizeof (i_shdrp) * i_ehdrp->e_shnum)); - if (!i_shdrp || !elf_elfsections (abfd)) - goto got_no_match; - if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) != 0) - goto got_no_match; - for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++) - { - if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr)) - goto got_no_match; - elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); - elf_elfsections (abfd)[shindex] = i_shdrp + shindex; - } - if (i_ehdrp->e_shstrndx) - { - if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx)) - goto got_no_match; - } - - /* Read in the program headers. */ - if (i_ehdrp->e_phnum == 0) - elf_tdata (abfd)->phdr = NULL; - else - { - Elf_Internal_Phdr *i_phdr; - unsigned int i; - - elf_tdata (abfd)->phdr = ((Elf_Internal_Phdr *) - bfd_alloc (abfd, - (i_ehdrp->e_phnum - * sizeof (Elf_Internal_Phdr)))); - if (elf_tdata (abfd)->phdr == NULL) - goto got_no_match; - if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0) - goto got_no_match; - i_phdr = elf_tdata (abfd)->phdr; - for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++) - { - Elf_External_Phdr x_phdr; - - if (bfd_read ((PTR) &x_phdr, sizeof x_phdr, 1, abfd) - != sizeof x_phdr) - goto got_no_match; - elf_swap_phdr_in (abfd, &x_phdr, i_phdr); - } - } - - /* Read in the string table containing the names of the sections. We - will need the base pointer to this table later. */ - /* We read this inline now, so that we don't have to go through - bfd_section_from_shdr with it (since this particular strtab is - used to find all of the ELF section names.) */ - - shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx); - if (!shstrtab) - goto got_no_match; - - /* Once all of the section headers have been read and converted, we - can start processing them. Note that the first section header is - a dummy placeholder entry, so we ignore it. */ - - for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) - { - if (! bfd_section_from_shdr (abfd, shindex)) - goto got_no_match; - } - - /* Let the backend double check the format and override global - information. */ - if (ebd->elf_backend_object_p) - { - if ((*ebd->elf_backend_object_p) (abfd) == false) - goto got_wrong_format_error; - } - - return (abfd->xvec); - -got_wrong_format_error: - bfd_set_error (bfd_error_wrong_format); - goto got_no_match; -got_no_match: - if (new_tdata != NULL - && new_tdata->elf_sect_ptr != NULL) - bfd_release (abfd, new_tdata->elf_sect_ptr); - if (i_shdrp != NULL) - bfd_release (abfd, i_shdrp); - if (new_tdata != NULL) - bfd_release (abfd, new_tdata); - elf_tdata (abfd) = preserved_tdata; - return (NULL); -} - -/* ELF .o/exec file writing */ - -/* Try to convert a non-ELF reloc into an ELF one. */ - -static boolean -validate_reloc (abfd, areloc) - bfd *abfd; - arelent *areloc; -{ - /* Check whether we really have an ELF howto. */ - - if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec) - { - bfd_reloc_code_real_type code; - reloc_howto_type *howto; - - /* Alien reloc: Try to determine its type to replace it with an - equivalent ELF reloc. */ - - if (areloc->howto->pc_relative) - { - switch (areloc->howto->bitsize) - { - case 8: - code = BFD_RELOC_8_PCREL; - break; - case 12: - code = BFD_RELOC_12_PCREL; - break; - case 16: - code = BFD_RELOC_16_PCREL; - break; - case 24: - code = BFD_RELOC_24_PCREL; - break; - case 32: - code = BFD_RELOC_32_PCREL; - break; - case 64: - code = BFD_RELOC_64_PCREL; - break; - default: - goto fail; - } - - howto = bfd_reloc_type_lookup (abfd, code); - - if (areloc->howto->pcrel_offset != howto->pcrel_offset) - { - if (howto->pcrel_offset) - areloc->addend += areloc->address; - else - areloc->addend -= areloc->address; /* addend is unsigned!! */ - } - } - else - { - switch (areloc->howto->bitsize) - { - case 8: - code = BFD_RELOC_8; - break; - case 14: - code = BFD_RELOC_14; - break; - case 16: - code = BFD_RELOC_16; - break; - case 26: - code = BFD_RELOC_26; - break; - case 32: - code = BFD_RELOC_32; - break; - case 64: - code = BFD_RELOC_64; - break; - default: - goto fail; - } - - howto = bfd_reloc_type_lookup (abfd, code); - } - - if (howto) - areloc->howto = howto; - else - goto fail; - } - - return true; - - fail: - (*_bfd_error_handler) - ("%s: unsupported relocation type %s", - bfd_get_filename (abfd), areloc->howto->name); - bfd_set_error (bfd_error_bad_value); - return false; -} - -/* Write out the relocs. */ - -static void -write_relocs (abfd, sec, data) - bfd *abfd; - asection *sec; - PTR data; -{ - boolean *failedp = (boolean *) data; - Elf_Internal_Shdr *rela_hdr; - Elf_External_Rela *outbound_relocas; - Elf_External_Rel *outbound_relocs; - unsigned int idx; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - asymbol *last_sym = 0; - int last_sym_idx = 0; - - /* If we have already failed, don't do anything. */ - if (*failedp) - return; - - if ((sec->flags & SEC_RELOC) == 0) - return; - - /* The linker backend writes the relocs out itself, and sets the - reloc_count field to zero to inhibit writing them here. Also, - sometimes the SEC_RELOC flag gets set even when there aren't any - relocs. */ - if (sec->reloc_count == 0) - return; - - rela_hdr = &elf_section_data (sec)->rel_hdr; - - rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; - rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size); - if (rela_hdr->contents == NULL) - { - *failedp = true; - return; - } - - /* orelocation has the data, reloc_count has the count... */ - if (use_rela_p) - { - outbound_relocas = (Elf_External_Rela *) rela_hdr->contents; - - for (idx = 0; idx < sec->reloc_count; idx++) - { - Elf_Internal_Rela dst_rela; - Elf_External_Rela *src_rela; - arelent *ptr; - asymbol *sym; - int n; - - ptr = sec->orelocation[idx]; - src_rela = outbound_relocas + idx; - - /* The address of an ELF reloc is section relative for an object - file, and absolute for an executable file or shared library. - The address of a BFD reloc is always section relative. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) - dst_rela.r_offset = ptr->address; - else - dst_rela.r_offset = ptr->address + sec->vma; - - sym = *ptr->sym_ptr_ptr; - if (sym == last_sym) - n = last_sym_idx; - else - { - last_sym = sym; - n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); - if (n < 0) - { - *failedp = true; - return; - } - last_sym_idx = n; - } - - if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec - && ! validate_reloc (abfd, ptr)) - { - *failedp = true; - return; - } - - dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type); - - dst_rela.r_addend = ptr->addend; - elf_swap_reloca_out (abfd, &dst_rela, src_rela); - } - } - else - /* REL relocations */ - { - outbound_relocs = (Elf_External_Rel *) rela_hdr->contents; - - for (idx = 0; idx < sec->reloc_count; idx++) - { - Elf_Internal_Rel dst_rel; - Elf_External_Rel *src_rel; - arelent *ptr; - int n; - asymbol *sym; - - ptr = sec->orelocation[idx]; - sym = *ptr->sym_ptr_ptr; - src_rel = outbound_relocs + idx; - - /* The address of an ELF reloc is section relative for an object - file, and absolute for an executable file or shared library. - The address of a BFD reloc is always section relative. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) - dst_rel.r_offset = ptr->address; - else - dst_rel.r_offset = ptr->address + sec->vma; - - if (sym == last_sym) - n = last_sym_idx; - else - { - last_sym = sym; - n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); - if (n < 0) - { - *failedp = true; - return; - } - last_sym_idx = n; - } - - if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec - && ! validate_reloc (abfd, ptr)) - { - *failedp = true; - return; - } - - dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type); - - elf_swap_reloc_out (abfd, &dst_rel, src_rel); - } - } -} - -static int -write_out_phdrs (abfd, phdr, count) - bfd *abfd; - Elf_Internal_Phdr *phdr; - int count; -{ - while (count--) - { - Elf_External_Phdr extphdr; - elf_swap_phdr_out (abfd, phdr, &extphdr); - if (bfd_write (&extphdr, sizeof (Elf_External_Phdr), 1, abfd) - != sizeof (Elf_External_Phdr)) - return -1; - phdr++; - } - return 0; -} - -static boolean -write_shdrs_and_ehdr (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr *x_shdrp; /* Section header table, external form */ - Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ - unsigned int count; - - i_ehdrp = elf_elfheader (abfd); - i_shdrp = elf_elfsections (abfd); - - /* swap the header before spitting it out... */ - -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) - != sizeof (x_ehdr))) - return false; - - /* at this point we've concocted all the ELF sections... */ - x_shdrp = (Elf_External_Shdr *) - bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum)); - if (!x_shdrp) - return false; - - for (count = 0; count < i_ehdrp->e_shnum; count++) - { -#if DEBUG & 2 - elf_debug_section (count, i_shdrp[count]); -#endif - elf_swap_shdr_out (abfd, i_shdrp[count], x_shdrp + count); - } - if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0 - || (bfd_write ((PTR) x_shdrp, sizeof (*x_shdrp), i_ehdrp->e_shnum, abfd) - != sizeof (*x_shdrp) * i_ehdrp->e_shnum)) - return false; - - /* need to dump the string table too... */ - - return true; -} - -static long -elf_slurp_symbol_table (abfd, symptrs, dynamic) - bfd *abfd; - asymbol **symptrs; /* Buffer for generated bfd symbols */ - boolean dynamic; -{ - Elf_Internal_Shdr *hdr; - long symcount; /* Number of external ELF symbols */ - elf_symbol_type *sym; /* Pointer to current bfd symbol */ - elf_symbol_type *symbase; /* Buffer for generated bfd symbols */ - Elf_Internal_Sym i_sym; - Elf_External_Sym *x_symp = NULL; - - /* Read each raw ELF symbol, converting from external ELF form to - internal ELF form, and then using the information to create a - canonical bfd symbol table entry. - - Note that we allocate the initial bfd canonical symbol buffer - based on a one-to-one mapping of the ELF symbols to canonical - symbols. We actually use all the ELF symbols, so there will be no - space left over at the end. When we have all the symbols, we - build the caller's pointer vector. */ - - if (dynamic) - hdr = &elf_tdata (abfd)->dynsymtab_hdr; - else - hdr = &elf_tdata (abfd)->symtab_hdr; - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return -1; - - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - - if (symcount == 0) - sym = symbase = NULL; - else - { - long i; - - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return -1; - - symbase = ((elf_symbol_type *) - bfd_zalloc (abfd, symcount * sizeof (elf_symbol_type))); - if (symbase == (elf_symbol_type *) NULL) - return -1; - sym = symbase; - - /* Temporarily allocate room for the raw ELF symbols. */ - x_symp = ((Elf_External_Sym *) - bfd_malloc (symcount * sizeof (Elf_External_Sym))); - if (x_symp == NULL && symcount != 0) - goto error_return; - - if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd) - != symcount * sizeof (Elf_External_Sym)) - goto error_return; - /* Skip first symbol, which is a null dummy. */ - for (i = 1; i < symcount; i++) - { - elf_swap_symbol_in (abfd, x_symp + i, &i_sym); - memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym)); -#ifdef ELF_KEEP_EXTSYM - memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym)); -#endif - sym->symbol.the_bfd = abfd; - - sym->symbol.name = bfd_elf_string_from_elf_section (abfd, - hdr->sh_link, - i_sym.st_name); - - sym->symbol.value = i_sym.st_value; - - if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERVE) - { - sym->symbol.section = section_from_elf_index (abfd, - i_sym.st_shndx); - if (sym->symbol.section == NULL) - { - /* This symbol is in a section for which we did not - create a BFD section. Just use bfd_abs_section, - although it is wrong. FIXME. */ - sym->symbol.section = bfd_abs_section_ptr; - } - } - else if (i_sym.st_shndx == SHN_ABS) - { - sym->symbol.section = bfd_abs_section_ptr; - } - else if (i_sym.st_shndx == SHN_COMMON) - { - sym->symbol.section = bfd_com_section_ptr; - /* Elf puts the alignment into the `value' field, and - the size into the `size' field. BFD wants to see the - size in the value field, and doesn't care (at the - moment) about the alignment. */ - sym->symbol.value = i_sym.st_size; - } - else if (i_sym.st_shndx == SHN_UNDEF) - { - sym->symbol.section = bfd_und_section_ptr; - } - else - sym->symbol.section = bfd_abs_section_ptr; - - sym->symbol.value -= sym->symbol.section->vma; - - switch (ELF_ST_BIND (i_sym.st_info)) - { - case STB_LOCAL: - sym->symbol.flags |= BSF_LOCAL; - break; - case STB_GLOBAL: - if (i_sym.st_shndx != SHN_UNDEF - && i_sym.st_shndx != SHN_COMMON) - sym->symbol.flags |= BSF_GLOBAL; - break; - case STB_WEAK: - sym->symbol.flags |= BSF_WEAK; - break; - } - - switch (ELF_ST_TYPE (i_sym.st_info)) - { - case STT_SECTION: - sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING; - break; - case STT_FILE: - sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING; - break; - case STT_FUNC: - sym->symbol.flags |= BSF_FUNCTION; - break; - case STT_OBJECT: - sym->symbol.flags |= BSF_OBJECT; - break; - } - - if (dynamic) - sym->symbol.flags |= BSF_DYNAMIC; - - /* Do some backend-specific processing on this symbol. */ - { - struct elf_backend_data *ebd = get_elf_backend_data (abfd); - if (ebd->elf_backend_symbol_processing) - (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol); - } - - sym++; - } - } - - /* Do some backend-specific processing on this symbol table. */ - { - struct elf_backend_data *ebd = get_elf_backend_data (abfd); - if (ebd->elf_backend_symbol_table_processing) - (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount); - } - - /* We rely on the zalloc to clear out the final symbol entry. */ - - symcount = sym - symbase; - - /* Fill in the user's symbol pointer vector if needed. */ - if (symptrs) - { - long l = symcount; - - sym = symbase; - while (l-- > 0) - { - *symptrs++ = &sym->symbol; - sym++; - } - *symptrs = 0; /* Final null pointer */ - } - - if (x_symp != NULL) - free (x_symp); - return symcount; -error_return: - if (x_symp != NULL) - free (x_symp); - return -1; -} - -/* Read in and swap the external relocs. */ - -static boolean -elf_slurp_reloc_table (abfd, asect, symbols) - bfd *abfd; - asection *asect; - asymbol **symbols; -{ - struct elf_backend_data * const ebd = get_elf_backend_data (abfd); - struct bfd_elf_section_data * const d = elf_section_data (asect); - PTR allocated = NULL; - bfd_byte *native_relocs; - arelent *relents; - arelent *relent; - unsigned int i; - int entsize; - - if (asect->relocation != NULL - || (asect->flags & SEC_RELOC) == 0 - || asect->reloc_count == 0) - return true; - - BFD_ASSERT (asect->rel_filepos == d->rel_hdr.sh_offset - && (asect->reloc_count - == d->rel_hdr.sh_size / d->rel_hdr.sh_entsize)); - - allocated = (PTR) bfd_malloc ((size_t) d->rel_hdr.sh_size); - if (allocated == NULL) - goto error_return; - - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0 - || (bfd_read (allocated, 1, d->rel_hdr.sh_size, abfd) - != d->rel_hdr.sh_size)) - goto error_return; - - native_relocs = (bfd_byte *) allocated; - - relents = ((arelent *) - bfd_alloc (abfd, asect->reloc_count * sizeof (arelent))); - if (relents == NULL) - goto error_return; - - entsize = d->rel_hdr.sh_entsize; - BFD_ASSERT (entsize == sizeof (Elf_External_Rel) - || entsize == sizeof (Elf_External_Rela)); - - for (i = 0, relent = relents; - i < asect->reloc_count; - i++, relent++, native_relocs += entsize) - { - Elf_Internal_Rela rela; - Elf_Internal_Rel rel; - - if (entsize == sizeof (Elf_External_Rela)) - elf_swap_reloca_in (abfd, (Elf_External_Rela *) native_relocs, &rela); - else - { - elf_swap_reloc_in (abfd, (Elf_External_Rel *) native_relocs, &rel); - rela.r_offset = rel.r_offset; - rela.r_info = rel.r_info; - rela.r_addend = 0; - } - - /* The address of an ELF reloc is section relative for an object - file, and absolute for an executable file or shared library. - The address of a BFD reloc is always section relative. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) - relent->address = rela.r_offset; - else - relent->address = rela.r_offset - asect->vma; - - if (ELF_R_SYM (rela.r_info) == 0) - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - else - { - asymbol **ps, *s; - - ps = symbols + ELF_R_SYM (rela.r_info) - 1; - s = *ps; - - /* Canonicalize ELF section symbols. FIXME: Why? */ - if ((s->flags & BSF_SECTION_SYM) == 0) - relent->sym_ptr_ptr = ps; - else - relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; - } - - relent->addend = rela.r_addend; - - if (entsize == sizeof (Elf_External_Rela)) - (*ebd->elf_info_to_howto) (abfd, relent, &rela); - else - (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel); - } - - asect->relocation = relents; - - if (allocated != NULL) - free (allocated); - - return true; - - error_return: - if (allocated != NULL) - free (allocated); - return false; -} - -#ifdef DEBUG -static void -elf_debug_section (num, hdr) - int num; - Elf_Internal_Shdr *hdr; -{ - fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num, - hdr->bfd_section != NULL ? hdr->bfd_section->name : "", - (long) hdr); - fprintf (stderr, - "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n", - (long) hdr->sh_name, - (long) hdr->sh_type, - (long) hdr->sh_flags); - fprintf (stderr, - "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n", - (long) hdr->sh_addr, - (long) hdr->sh_offset, - (long) hdr->sh_size); - fprintf (stderr, - "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n", - (long) hdr->sh_link, - (long) hdr->sh_info, - (long) hdr->sh_addralign); - fprintf (stderr, "sh_entsize = %ld\n", - (long) hdr->sh_entsize); - fflush (stderr); -} - -static void -elf_debug_file (ehdrp) - Elf_Internal_Ehdr *ehdrp; -{ - fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry); - fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff); - fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum); - fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize); - fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff); - fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum); - fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); -} - -static char * -elf_symbol_flags (flags) - flagword flags; -{ - static char buffer[1024]; - - buffer[0] = '\0'; - if (flags & BSF_LOCAL) - strcat (buffer, " local"); - - if (flags & BSF_GLOBAL) - strcat (buffer, " global"); - - if (flags & BSF_DEBUGGING) - strcat (buffer, " debug"); - - if (flags & BSF_FUNCTION) - strcat (buffer, " function"); - - if (flags & BSF_KEEP) - strcat (buffer, " keep"); - - if (flags & BSF_KEEP_G) - strcat (buffer, " keep_g"); - - if (flags & BSF_WEAK) - strcat (buffer, " weak"); - - if (flags & BSF_SECTION_SYM) - strcat (buffer, " section-sym"); - - if (flags & BSF_OLD_COMMON) - strcat (buffer, " old-common"); - - if (flags & BSF_NOT_AT_END) - strcat (buffer, " not-at-end"); - - if (flags & BSF_CONSTRUCTOR) - strcat (buffer, " constructor"); - - if (flags & BSF_WARNING) - strcat (buffer, " warning"); - - if (flags & BSF_INDIRECT) - strcat (buffer, " indirect"); - - if (flags & BSF_FILE) - strcat (buffer, " file"); - - if (flags & DYNAMIC) - strcat (buffer, " dynamic"); - - if (flags & ~(BSF_LOCAL - | BSF_GLOBAL - | BSF_DEBUGGING - | BSF_FUNCTION - | BSF_KEEP - | BSF_KEEP_G - | BSF_WEAK - | BSF_SECTION_SYM - | BSF_OLD_COMMON - | BSF_NOT_AT_END - | BSF_CONSTRUCTOR - | BSF_WARNING - | BSF_INDIRECT - | BSF_FILE - | BSF_DYNAMIC)) - strcat (buffer, " unknown-bits"); - - return buffer; -} -#endif - -#include "elfcore.h" -#include "elflink.h" - -/* Size-dependent data and functions. */ -const struct elf_size_info NAME(_bfd_elf,size_info) = { - sizeof (Elf_External_Ehdr), - sizeof (Elf_External_Phdr), - sizeof (Elf_External_Shdr), - sizeof (Elf_External_Rel), - sizeof (Elf_External_Rela), - sizeof (Elf_External_Sym), - sizeof (Elf_External_Dyn), - sizeof (Elf_External_Note), - - ARCH_SIZE, FILE_ALIGN, - ELFCLASS, EV_CURRENT, - write_out_phdrs, - write_shdrs_and_ehdr, - write_relocs, - elf_swap_symbol_out, - elf_slurp_reloc_table, - elf_slurp_symbol_table, - elf_swap_dyn_in -}; diff --git a/contrib/gdb/bfd/elfcore.h b/contrib/gdb/bfd/elfcore.h deleted file mode 100644 index 8100627c9ad..00000000000 --- a/contrib/gdb/bfd/elfcore.h +++ /dev/null @@ -1,475 +0,0 @@ -/* ELF core file support for BFD. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Core file support */ - -#ifdef HAVE_SYS_PROCFS_H /* Some core file support requires host /proc files */ -#include -#include -#else -#define bfd_prstatus(abfd, descdata, descsz, filepos) true -#define bfd_fpregset(abfd, descdata, descsz, filepos) true -#define bfd_prpsinfo(abfd, descdata, descsz, filepos) true -#endif - -#ifdef HAVE_SYS_PROCFS_H - -static boolean -bfd_prstatus (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - asection *newsect; - prstatus_t *status = (prstatus_t *) 0; - - if (descsz == sizeof (prstatus_t)) - { - newsect = bfd_make_section (abfd, ".reg"); - if (newsect == NULL) - return false; - newsect->_raw_size = sizeof (status->pr_reg); - newsect->filepos = filepos + (long) &status->pr_reg; - newsect->flags = SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - if ((core_prstatus (abfd) = bfd_alloc (abfd, descsz)) != NULL) - { - memcpy (core_prstatus (abfd), descdata, descsz); - } - } - return true; -} - -/* Stash a copy of the prpsinfo structure away for future use. */ - -static boolean -bfd_prpsinfo (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - if (descsz == sizeof (prpsinfo_t)) - { - if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL) - return false; - memcpy (core_prpsinfo (abfd), descdata, descsz); - } - return true; -} - -static boolean -bfd_fpregset (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - asection *newsect; - - newsect = bfd_make_section (abfd, ".reg2"); - if (newsect == NULL) - return false; - newsect->_raw_size = descsz; - newsect->filepos = filepos; - newsect->flags = SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - return true; -} - -#endif /* HAVE_SYS_PROCFS_H */ - -/* Return a pointer to the args (including the command name) that were - seen by the program that generated the core dump. Note that for - some reason, a spurious space is tacked onto the end of the args - in some (at least one anyway) implementations, so strip it off if - it exists. */ - -char * -elf_core_file_failing_command (abfd) - bfd *abfd; -{ -#ifdef HAVE_SYS_PROCFS_H - if (core_prpsinfo (abfd)) - { - prpsinfo_t *p = core_prpsinfo (abfd); - char *scan = p->pr_psargs; - while (*scan++) - {; - } - scan -= 2; - if ((scan > p->pr_psargs) && (*scan == ' ')) - { - *scan = '\000'; - } - return p->pr_psargs; - } -#endif - return NULL; -} - -/* Return the number of the signal that caused the core dump. Presumably, - since we have a core file, we got a signal of some kind, so don't bother - checking the other process status fields, just return the signal number. - */ - -int -elf_core_file_failing_signal (abfd) - bfd *abfd; -{ -#ifdef HAVE_SYS_PROCFS_H - if (core_prstatus (abfd)) - { - return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig; - } -#endif - return -1; -} - -/* Check to see if the core file could reasonably be expected to have - come for the current executable file. Note that by default we return - true unless we find something that indicates that there might be a - problem. - */ - -boolean -elf_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ -#ifdef HAVE_SYS_PROCFS_H - char *corename; - char *execname; -#endif - - /* First, xvecs must match since both are ELF files for the same target. */ - - if (core_bfd->xvec != exec_bfd->xvec) - { - bfd_set_error (bfd_error_system_call); - return false; - } - -#ifdef HAVE_SYS_PROCFS_H - - /* If no prpsinfo, just return true. Otherwise, grab the last component - of the exec'd pathname from the prpsinfo. */ - - if (core_prpsinfo (core_bfd)) - { - corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname); - } - else - { - return true; - } - - /* Find the last component of the executable pathname. */ - - if ((execname = strrchr (exec_bfd->filename, '/')) != NULL) - { - execname++; - } - else - { - execname = (char *) exec_bfd->filename; - } - - /* See if they match */ - - return strcmp (execname, corename) ? false : true; - -#else - - return true; - -#endif /* HAVE_SYS_PROCFS_H */ -} - -/* ELF core files contain a segment of type PT_NOTE, that holds much of - the information that would normally be available from the /proc interface - for the process, at the time the process dumped core. Currently this - includes copies of the prstatus, prpsinfo, and fpregset structures. - - Since these structures are potentially machine dependent in size and - ordering, bfd provides two levels of support for them. The first level, - available on all machines since it does not require that the host - have /proc support or the relevant include files, is to create a bfd - section for each of the prstatus, prpsinfo, and fpregset structures, - without any interpretation of their contents. With just this support, - the bfd client will have to interpret the structures itself. Even with - /proc support, it might want these full structures for it's own reasons. - - In the second level of support, where HAVE_SYS_PROCFS_H is defined, - bfd will pick apart the structures to gather some additional - information that clients may want, such as the general register - set, the name of the exec'ed file and its arguments, the signal (if - any) that caused the core dump, etc. - - */ - -static boolean -elf_corefile_note (abfd, hdr) - bfd *abfd; - Elf_Internal_Phdr *hdr; -{ - Elf_External_Note *x_note_p; /* Elf note, external form */ - Elf_Internal_Note i_note; /* Elf note, internal form */ - char *buf = NULL; /* Entire note segment contents */ - char *namedata; /* Name portion of the note */ - char *descdata; /* Descriptor portion of the note */ - char *sectname; /* Name to use for new section */ - long filepos; /* File offset to descriptor data */ - asection *newsect; - - if (hdr->p_filesz > 0 - && (buf = (char *) bfd_malloc ((size_t) hdr->p_filesz)) != NULL - && bfd_seek (abfd, hdr->p_offset, SEEK_SET) != -1 - && bfd_read ((PTR) buf, hdr->p_filesz, 1, abfd) == hdr->p_filesz) - { - x_note_p = (Elf_External_Note *) buf; - while ((char *) x_note_p < (buf + hdr->p_filesz)) - { - i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->namesz); - i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->descsz); - i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->type); - namedata = x_note_p->name; - descdata = namedata + BFD_ALIGN (i_note.namesz, 4); - filepos = hdr->p_offset + (descdata - buf); - switch (i_note.type) - { - case NT_PRSTATUS: - /* process descdata as prstatus info */ - if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".prstatus"; - break; - case NT_FPREGSET: - /* process descdata as fpregset info */ - if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".fpregset"; - break; - case NT_PRPSINFO: - /* process descdata as prpsinfo */ - if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".prpsinfo"; - break; - default: - /* Unknown descriptor, just ignore it. */ - sectname = NULL; - break; - } - if (sectname != NULL) - { - newsect = bfd_make_section (abfd, sectname); - if (newsect == NULL) - return false; - newsect->_raw_size = i_note.descsz; - newsect->filepos = filepos; - newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - } - x_note_p = (Elf_External_Note *) - (descdata + BFD_ALIGN (i_note.descsz, 4)); - } - } - if (buf != NULL) - { - free (buf); - } - else if (hdr->p_filesz > 0) - { - return false; - } - return true; - -} - -/* Core files are simply standard ELF formatted files that partition - the file using the execution view of the file (program header table) - rather than the linking view. In fact, there is no section header - table in a core file. - - The process status information (including the contents of the general - register set) and the floating point register set are stored in a - segment of type PT_NOTE. We handcraft a couple of extra bfd sections - that allow standard bfd access to the general registers (.reg) and the - floating point registers (.reg2). - - */ - -const bfd_target * -elf_core_file_p (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Phdr x_phdr; /* Program header table entry, external form */ - Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */ - unsigned int phindex; - struct elf_backend_data *ebd; - - /* Read in the ELF header in external format. */ - - if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry, and it must have a - program header table (FIXME: See comments re segments at top of this - file). */ - - if (elf_file_p (&x_ehdr) == false) - { - wrong: - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* FIXME, Check EI_VERSION here ! */ - - { -#if ARCH_SIZE == 32 - int desired_address_size = ELFCLASS32; -#endif -#if ARCH_SIZE == 64 - int desired_address_size = ELFCLASS64; -#endif - - if (x_ehdr.e_ident[EI_CLASS] != desired_address_size) - goto wrong; - } - - /* Switch xvec to match the specified byte order. */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (! bfd_big_endian (abfd)) - goto wrong; - break; - case ELFDATA2LSB: /* Little-endian */ - if (! bfd_little_endian (abfd)) - goto wrong; - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - goto wrong; - } - - /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - elf_tdata (abfd) = - (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); - if (elf_tdata (abfd) == NULL) - return NULL; - - /* FIXME, `wrong' returns from this point onward, leak memory. */ - - /* Now that we know the byte order, swap in the rest of the header */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - ebd = get_elf_backend_data (abfd); - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - if (ebd->elf_machine_code != i_ehdrp->e_machine - && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1) - && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2)) - { - const bfd_target * const *target_ptr; - - if (ebd->elf_machine_code != EM_NONE) - goto wrong; - - /* This is the generic ELF target. Let it match any ELF target - for which we do not have a specific backend. */ - for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) - { - struct elf_backend_data *back; - - if ((*target_ptr)->flavour != bfd_target_elf_flavour) - continue; - back = (struct elf_backend_data *) (*target_ptr)->backend_data; - if (back->elf_machine_code == i_ehdrp->e_machine) - { - /* target_ptr is an ELF backend which matches this - object file, so reject the generic ELF target. */ - goto wrong; - } - } - } - - /* If there is no program header, or the type is not a core file, then - we are hosed. */ - if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) - goto wrong; - - /* Allocate space for a copy of the program header table in - internal form, seek to the program header table in the file, - read it in, and convert it to internal form. As a simple sanity - check, verify that the what BFD thinks is the size of each program - header table entry actually matches the size recorded in the file. */ - - if (i_ehdrp->e_phentsize != sizeof (x_phdr)) - goto wrong; - i_phdrp = (Elf_Internal_Phdr *) - bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum); - if (!i_phdrp) - return NULL; - if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1) - return NULL; - for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) - { - if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd) - != sizeof (x_phdr)) - return NULL; - elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex); - } - - /* Once all of the program headers have been read and converted, we - can start processing them. */ - - for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) - { - bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex); - if ((i_phdrp + phindex)->p_type == PT_NOTE) - { - if (! elf_corefile_note (abfd, i_phdrp + phindex)) - return NULL; - } - } - - /* Remember the entry point specified in the ELF file header. */ - - bfd_get_start_address (abfd) = i_ehdrp->e_entry; - - return abfd->xvec; -} diff --git a/contrib/gdb/bfd/elflink.c b/contrib/gdb/bfd/elflink.c deleted file mode 100644 index 7b204f763e0..00000000000 --- a/contrib/gdb/bfd/elflink.c +++ /dev/null @@ -1,372 +0,0 @@ -/* ELF linking support for BFD. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#define ARCH_SIZE 0 -#include "elf-bfd.h" - -boolean -_bfd_elf_create_got_section (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* This function may be called more than once. */ - if (bfd_get_section_by_name (abfd, ".got") != NULL) - return true; - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - s = bfd_make_section (abfd, ".got"); - if (s == NULL - || !bfd_set_section_flags (abfd, s, flags) - || !bfd_set_section_alignment (abfd, s, 2)) - return false; - - if (bed->want_got_plt) - { - s = bfd_make_section (abfd, ".got.plt"); - if (s == NULL - || !bfd_set_section_flags (abfd, s, flags) - || !bfd_set_section_alignment (abfd, s, 2)) - return false; - } - - /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got - (or .got.plt) section. We don't do this in the linker script - because we don't want to define the symbol if we are not creating - a global offset table. */ - h = NULL; - if (!(_bfd_generic_link_add_one_symbol - (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, (bfd_vma) 0, - (const char *) NULL, false, get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - - /* The first three global offset table entries are reserved. */ - s->_raw_size += 3 * 4; - - return true; -} - - -/* Create dynamic sections when linking against a dynamic object. */ - -boolean -_bfd_elf_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and - .rel[a].bss sections. */ - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - s = bfd_make_section (abfd, ".plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, - (flags | SEC_CODE - | (bed->plt_readonly ? SEC_READONLY : 0))) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - if (bed->want_plt_sym) - { - /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the - .plt section. */ - struct elf_link_hash_entry *h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - } - - s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.plt" : ".rel.plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - if (! _bfd_elf_create_got_section (abfd, info)) - return false; - - /* The .dynbss section is a place to put symbols which are defined - by dynamic objects, are referenced by regular objects, and are - not functions. We must allocate space for them in the process - image and use a R_*_COPY reloc to tell the dynamic linker to - initialize them at run time. The linker script puts the .dynbss - section into the .bss section of the final image. */ - s = bfd_make_section (abfd, ".dynbss"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, SEC_ALLOC)) - return false; - - /* The .rel[a].bss section holds copy relocs. This section is not - normally needed. We need to create it here, though, so that the - linker will map it to an output section. We can't just create it - only if we need it, because we will not know whether we need it - until we have seen all the input files, and the first time the - main linker code calls BFD after examining all the input files - (size_dynamic_sections) the input sections have already been - mapped to the output sections. If the section turns out not to - be needed, we can discard it later. We will never need this - section when generating a shared object, since they do not use - copy relocs. */ - if (! info->shared) - { - s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.bss" : ".rel.bss"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - } - - return true; -} - - -/* Record a new dynamic symbol. We record the dynamic symbols as we - read the input files, since we need to have a list of all of them - before we can determine the final sizes of the output sections. - Note that we may actually call this function even though we are not - going to output any dynamic symbols; in some cases we know that a - symbol should be in the dynamic symbol table, but only if there is - one. */ - -boolean -_bfd_elf_link_record_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - if (h->dynindx == -1) - { - struct bfd_strtab_hash *dynstr; - - h->dynindx = elf_hash_table (info)->dynsymcount; - ++elf_hash_table (info)->dynsymcount; - - dynstr = elf_hash_table (info)->dynstr; - if (dynstr == NULL) - { - /* Create a strtab to hold the dynamic symbol names. */ - elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init (); - if (dynstr == NULL) - return false; - } - - h->dynstr_index = ((unsigned long) - _bfd_stringtab_add (dynstr, h->root.root.string, - true, false)); - if (h->dynstr_index == (unsigned long) -1) - return false; - } - - return true; -} - -/* Create a special linker section, or return a pointer to a linker section already created */ - -elf_linker_section_t * -_bfd_elf_create_linker_section (abfd, info, which, defaults) - bfd *abfd; - struct bfd_link_info *info; - enum elf_linker_section_enum which; - elf_linker_section_t *defaults; -{ - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *lsect; - - /* Record the first bfd section that needs the special section */ - if (!dynobj) - dynobj = elf_hash_table (info)->dynobj = abfd; - - /* If this is the first time, create the section */ - lsect = elf_linker_section (dynobj, which); - if (!lsect) - { - asection *s; - - lsect = (elf_linker_section_t *) - bfd_alloc (dynobj, sizeof (elf_linker_section_t)); - - *lsect = *defaults; - elf_linker_section (dynobj, which) = lsect; - lsect->which = which; - lsect->hole_written_p = false; - - /* See if the sections already exist */ - lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name); - if (!s) - { - lsect->section = s = bfd_make_section (dynobj, lsect->name); - - if (s == NULL) - return (elf_linker_section_t *)0; - - bfd_set_section_flags (dynobj, s, defaults->flags); - bfd_set_section_alignment (dynobj, s, lsect->alignment); - } - else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment) - bfd_set_section_alignment (dynobj, s, lsect->alignment); - - s->_raw_size = align_power (s->_raw_size, lsect->alignment); - - /* Is there a hole we have to provide? If so check whether the segment is - too big already */ - if (lsect->hole_size) - { - lsect->hole_offset = s->_raw_size; - s->_raw_size += lsect->hole_size; - if (lsect->hole_offset > lsect->max_hole_offset) - { - (*_bfd_error_handler) ("%s: Section %s is already to large to put hole of %ld bytes in", - bfd_get_filename (abfd), - lsect->name, - (long)lsect->hole_size); - - bfd_set_error (bfd_error_bad_value); - return (elf_linker_section_t *)0; - } - } - -#ifdef DEBUG - fprintf (stderr, "Creating section %s, current size = %ld\n", - lsect->name, (long)s->_raw_size); -#endif - - if (lsect->sym_name) - { - struct elf_link_hash_entry *h = NULL; -#ifdef DEBUG - fprintf (stderr, "Adding %s to section %s\n", - lsect->sym_name, - lsect->name); -#endif - h = (struct elf_link_hash_entry *) - bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false); - - if ((h == NULL || h->root.type == bfd_link_hash_undefined) - && !(_bfd_generic_link_add_one_symbol (info, - abfd, - lsect->sym_name, - BSF_GLOBAL, - s, - ((lsect->hole_size) - ? s->_raw_size - lsect->hole_size + lsect->sym_offset - : lsect->sym_offset), - (const char *) NULL, - false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return (elf_linker_section_t *)0; - - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC; - h->type = STT_OBJECT; - lsect->sym_hash = h; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return (elf_linker_section_t *)0; - } - } - - /* Find the related sections if they have been created */ - if (lsect->bss_name && !lsect->bss_section) - lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name); - - if (lsect->rel_name && !lsect->rel_section) - lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name); - - return lsect; -} - - -/* Find a linker generated pointer with a given addend and type. */ - -elf_linker_section_pointers_t * -_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which) - elf_linker_section_pointers_t *linker_pointers; - bfd_signed_vma addend; - elf_linker_section_enum_t which; -{ - for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next) - { - if (which == linker_pointers->which && addend == linker_pointers->addend) - return linker_pointers; - } - - return (elf_linker_section_pointers_t *)0; -} - - -/* Make the .rela section corresponding to the generated linker section. */ - -boolean -_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment) - bfd *dynobj; - elf_linker_section_t *lsect; - int alignment; -{ - if (lsect->rel_section) - return true; - - lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name); - if (lsect->rel_section == NULL) - { - lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name); - if (lsect->rel_section == NULL - || ! bfd_set_section_flags (dynobj, - lsect->rel_section, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment)) - return false; - } - - return true; -} - diff --git a/contrib/gdb/bfd/elflink.h b/contrib/gdb/bfd/elflink.h deleted file mode 100644 index 4ef3c8b3c49..00000000000 --- a/contrib/gdb/bfd/elflink.h +++ /dev/null @@ -1,3424 +0,0 @@ -/* ELF linker support. - Copyright 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* ELF linker code. */ - -static boolean elf_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static Elf_Internal_Rela *elf_link_read_relocs - PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean)); -static boolean elf_export_symbol - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf_adjust_dynamic_symbol - PARAMS ((struct elf_link_hash_entry *, PTR)); - -/* This struct is used to pass information to routines called via - elf_link_hash_traverse which must return failure. */ - -struct elf_info_failed -{ - boolean failed; - struct bfd_link_info *info; -}; - -/* Given an ELF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -elf_bfd_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return elf_link_add_object_symbols (abfd, info); - case bfd_archive: - return elf_link_add_archive_symbols (abfd, info); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - - -/* Add symbols from an ELF archive file to the linker hash table. We - don't use _bfd_generic_link_add_archive_symbols because of a - problem which arises on UnixWare. The UnixWare libc.so is an - archive which includes an entry libc.so.1 which defines a bunch of - symbols. The libc.so archive also includes a number of other - object files, which also define symbols, some of which are the same - as those defined in libc.so.1. Correct linking requires that we - consider each object file in turn, and include it if it defines any - symbols we need. _bfd_generic_link_add_archive_symbols does not do - this; it looks through the list of undefined symbols, and includes - any object file which defines them. When this algorithm is used on - UnixWare, it winds up pulling in libc.so.1 early and defining a - bunch of symbols. This means that some of the other objects in the - archive are not included in the link, which is incorrect since they - precede libc.so.1 in the archive. - - Fortunately, ELF archive handling is simpler than that done by - _bfd_generic_link_add_archive_symbols, which has to allow for a.out - oddities. In ELF, if we find a symbol in the archive map, and the - symbol is currently undefined, we know that we must pull in that - object file. - - Unfortunately, we do have to make multiple passes over the symbol - table until nothing further is resolved. */ - -static boolean -elf_link_add_archive_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - symindex c; - boolean *defined = NULL; - boolean *included = NULL; - carsym *symdefs; - boolean loop; - - if (! bfd_has_map (abfd)) - { - /* An empty archive is a special case. */ - if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL) - return true; - bfd_set_error (bfd_error_no_armap); - return false; - } - - /* Keep track of all symbols we know to be already defined, and all - files we know to be already included. This is to speed up the - second and subsequent passes. */ - c = bfd_ardata (abfd)->symdef_count; - if (c == 0) - return true; - defined = (boolean *) bfd_malloc (c * sizeof (boolean)); - included = (boolean *) bfd_malloc (c * sizeof (boolean)); - if (defined == (boolean *) NULL || included == (boolean *) NULL) - goto error_return; - memset (defined, 0, c * sizeof (boolean)); - memset (included, 0, c * sizeof (boolean)); - - symdefs = bfd_ardata (abfd)->symdefs; - - do - { - file_ptr last; - symindex i; - carsym *symdef; - carsym *symdefend; - - loop = false; - last = -1; - - symdef = symdefs; - symdefend = symdef + c; - for (i = 0; symdef < symdefend; symdef++, i++) - { - struct elf_link_hash_entry *h; - bfd *element; - struct bfd_link_hash_entry *undefs_tail; - symindex mark; - - if (defined[i] || included[i]) - continue; - if (symdef->file_offset == last) - { - included[i] = true; - continue; - } - - h = elf_link_hash_lookup (elf_hash_table (info), symdef->name, - false, false, false); - if (h == (struct elf_link_hash_entry *) NULL) - continue; - if (h->root.type != bfd_link_hash_undefined) - { - if (h->root.type != bfd_link_hash_undefweak) - defined[i] = true; - continue; - } - - /* We need to include this archive member. */ - - element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); - if (element == (bfd *) NULL) - goto error_return; - - if (! bfd_check_format (element, bfd_object)) - goto error_return; - - /* Doublecheck that we have not included this object - already--it should be impossible, but there may be - something wrong with the archive. */ - if (element->archive_pass != 0) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - element->archive_pass = 1; - - undefs_tail = info->hash->undefs_tail; - - if (! (*info->callbacks->add_archive_element) (info, element, - symdef->name)) - goto error_return; - if (! elf_link_add_object_symbols (element, info)) - goto error_return; - - /* If there are any new undefined symbols, we need to make - another pass through the archive in order to see whether - they can be defined. FIXME: This isn't perfect, because - common symbols wind up on undefs_tail and because an - undefined symbol which is defined later on in this pass - does not require another pass. This isn't a bug, but it - does make the code less efficient than it could be. */ - if (undefs_tail != info->hash->undefs_tail) - loop = true; - - /* Look backward to mark all symbols from this object file - which we have already seen in this pass. */ - mark = i; - do - { - included[mark] = true; - if (mark == 0) - break; - --mark; - } - while (symdefs[mark].file_offset == symdef->file_offset); - - /* We mark subsequent symbols from this object file as we go - on through the loop. */ - last = symdef->file_offset; - } - } - while (loop); - - free (defined); - free (included); - - return true; - - error_return: - if (defined != (boolean *) NULL) - free (defined); - if (included != (boolean *) NULL) - free (included); - return false; -} - -/* Add symbols from an ELF object file to the linker hash table. */ - -static boolean -elf_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean (*add_symbol_hook) PARAMS ((bfd *, struct bfd_link_info *, - const Elf_Internal_Sym *, - const char **, flagword *, - asection **, bfd_vma *)); - boolean (*check_relocs) PARAMS ((bfd *, struct bfd_link_info *, - asection *, const Elf_Internal_Rela *)); - boolean collect; - Elf_Internal_Shdr *hdr; - size_t symcount; - size_t extsymcount; - size_t extsymoff; - Elf_External_Sym *buf = NULL; - struct elf_link_hash_entry **sym_hash; - boolean dynamic; - Elf_External_Dyn *dynbuf = NULL; - struct elf_link_hash_entry *weaks; - Elf_External_Sym *esym; - Elf_External_Sym *esymend; - - add_symbol_hook = get_elf_backend_data (abfd)->elf_add_symbol_hook; - collect = get_elf_backend_data (abfd)->collect; - - /* As a GNU extension, any input sections which are named - .gnu.warning.SYMBOL are treated as warning symbols for the given - symbol. This differs from .gnu.warning sections, which generate - warnings when they are included in an output file. */ - if (! info->shared) - { - asection *s; - - for (s = abfd->sections; s != NULL; s = s->next) - { - const char *name; - - name = bfd_get_section_name (abfd, s); - if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0) - { - char *msg; - bfd_size_type sz; - - sz = bfd_section_size (abfd, s); - msg = (char *) bfd_alloc (abfd, sz); - if (msg == NULL) - goto error_return; - - if (! bfd_get_section_contents (abfd, s, msg, (file_ptr) 0, sz)) - goto error_return; - - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, - name + sizeof ".gnu.warning." - 1, - BSF_WARNING, s, (bfd_vma) 0, msg, false, collect, - (struct bfd_link_hash_entry **) NULL))) - goto error_return; - - if (! info->relocateable) - { - /* Clobber the section size so that the warning does - not get copied into the output file. */ - s->_raw_size = 0; - } - } - } - } - - /* A stripped shared library might only have a dynamic symbol table, - not a regular symbol table. In that case we can still go ahead - and link using the dynamic symbol table. */ - if (elf_onesymtab (abfd) == 0 - && elf_dynsymtab (abfd) != 0) - { - elf_onesymtab (abfd) = elf_dynsymtab (abfd); - elf_tdata (abfd)->symtab_hdr = elf_tdata (abfd)->dynsymtab_hdr; - } - - hdr = &elf_tdata (abfd)->symtab_hdr; - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - - /* The sh_info field of the symtab header tells us where the - external symbols start. We don't care about the local symbols at - this point. */ - if (elf_bad_symtab (abfd)) - { - extsymcount = symcount; - extsymoff = 0; - } - else - { - extsymcount = symcount - hdr->sh_info; - extsymoff = hdr->sh_info; - } - - buf = ((Elf_External_Sym *) - bfd_malloc (extsymcount * sizeof (Elf_External_Sym))); - if (buf == NULL && extsymcount != 0) - goto error_return; - - /* We store a pointer to the hash table entry for each external - symbol. */ - sym_hash = ((struct elf_link_hash_entry **) - bfd_alloc (abfd, - extsymcount * sizeof (struct elf_link_hash_entry *))); - if (sym_hash == NULL) - goto error_return; - elf_sym_hashes (abfd) = sym_hash; - - if (elf_elfheader (abfd)->e_type != ET_DYN) - { - dynamic = false; - - /* If we are creating a shared library, create all the dynamic - sections immediately. We need to attach them to something, - so we attach them to this BFD, provided it is the right - format. FIXME: If there are no input BFD's of the same - format as the output, we can't make a shared library. */ - if (info->shared - && ! elf_hash_table (info)->dynamic_sections_created - && abfd->xvec == info->hash->creator) - { - if (! elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - } - } - else - { - asection *s; - boolean add_needed; - const char *name; - bfd_size_type oldsize; - bfd_size_type strindex; - - dynamic = true; - - /* You can't use -r against a dynamic object. Also, there's no - hope of using a dynamic object which does not exactly match - the format of the output file. */ - if (info->relocateable - || info->hash->creator != abfd->xvec) - { - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - /* Find the name to use in a DT_NEEDED entry that refers to this - object. If the object has a DT_SONAME entry, we use it. - Otherwise, if the generic linker stuck something in - elf_dt_name, we use that. Otherwise, we just use the file - name. If the generic linker put a null string into - elf_dt_name, we don't make a DT_NEEDED entry at all, even if - there is a DT_SONAME entry. */ - add_needed = true; - name = bfd_get_filename (abfd); - if (elf_dt_name (abfd) != NULL) - { - name = elf_dt_name (abfd); - if (*name == '\0') - add_needed = false; - } - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - Elf_External_Dyn *extdyn; - Elf_External_Dyn *extdynend; - int elfsec; - unsigned long link; - - dynbuf = (Elf_External_Dyn *) bfd_malloc ((size_t) s->_raw_size); - if (dynbuf == NULL) - goto error_return; - - if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, - (file_ptr) 0, s->_raw_size)) - goto error_return; - - elfsec = _bfd_elf_section_from_bfd_section (abfd, s); - if (elfsec == -1) - goto error_return; - link = elf_elfsections (abfd)[elfsec]->sh_link; - - extdyn = dynbuf; - extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn); - for (; extdyn < extdynend; extdyn++) - { - Elf_Internal_Dyn dyn; - - elf_swap_dyn_in (abfd, extdyn, &dyn); - if (dyn.d_tag == DT_SONAME) - { - name = bfd_elf_string_from_elf_section (abfd, link, - dyn.d_un.d_val); - if (name == NULL) - goto error_return; - } - if (dyn.d_tag == DT_NEEDED) - { - struct bfd_link_needed_list *n, **pn; - char *fnm, *anm; - - n = ((struct bfd_link_needed_list *) - bfd_alloc (abfd, sizeof (struct bfd_link_needed_list))); - fnm = bfd_elf_string_from_elf_section (abfd, link, - dyn.d_un.d_val); - if (n == NULL || fnm == NULL) - goto error_return; - anm = bfd_alloc (abfd, strlen (fnm) + 1); - if (anm == NULL) - goto error_return; - strcpy (anm, fnm); - n->name = anm; - n->by = abfd; - n->next = NULL; - for (pn = &elf_hash_table (info)->needed; - *pn != NULL; - pn = &(*pn)->next) - ; - *pn = n; - } - } - - free (dynbuf); - dynbuf = NULL; - } - - /* We do not want to include any of the sections in a dynamic - object in the output file. We hack by simply clobbering the - list of sections in the BFD. This could be handled more - cleanly by, say, a new section flag; the existing - SEC_NEVER_LOAD flag is not the one we want, because that one - still implies that the section takes up space in the output - file. */ - abfd->sections = NULL; - abfd->section_count = 0; - - /* If this is the first dynamic object found in the link, create - the special sections required for dynamic linking. */ - if (! elf_hash_table (info)->dynamic_sections_created) - { - if (! elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - } - - if (add_needed) - { - /* Add a DT_NEEDED entry for this dynamic object. */ - oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr, name, - true, false); - if (strindex == (bfd_size_type) -1) - goto error_return; - - if (oldsize == _bfd_stringtab_size (elf_hash_table (info)->dynstr)) - { - asection *sdyn; - Elf_External_Dyn *dyncon, *dynconend; - - /* The hash table size did not change, which means that - the dynamic object name was already entered. If we - have already included this dynamic object in the - link, just ignore it. There is no reason to include - a particular dynamic object more than once. */ - sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj, - ".dynamic"); - BFD_ASSERT (sdyn != NULL); - - dyncon = (Elf_External_Dyn *) sdyn->contents; - dynconend = (Elf_External_Dyn *) (sdyn->contents + - sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - - elf_swap_dyn_in (elf_hash_table (info)->dynobj, dyncon, - &dyn); - if (dyn.d_tag == DT_NEEDED - && dyn.d_un.d_val == strindex) - { - if (buf != NULL) - free (buf); - return true; - } - } - } - - if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex)) - goto error_return; - } - - /* Save the SONAME, if there is one, because sometimes the - linker emulation code will need to know it. */ - if (*name == '\0') - name = bfd_get_filename (abfd); - elf_dt_name (abfd) = name; - } - - if (bfd_seek (abfd, - hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym), - SEEK_SET) != 0 - || (bfd_read ((PTR) buf, sizeof (Elf_External_Sym), extsymcount, abfd) - != extsymcount * sizeof (Elf_External_Sym))) - goto error_return; - - weaks = NULL; - - esymend = buf + extsymcount; - for (esym = buf; esym < esymend; esym++, sym_hash++) - { - Elf_Internal_Sym sym; - int bind; - bfd_vma value; - asection *sec; - flagword flags; - const char *name; - struct elf_link_hash_entry *h; - boolean definition; - boolean size_change_ok, type_change_ok; - boolean new_weakdef; - - elf_swap_symbol_in (abfd, esym, &sym); - - flags = BSF_NO_FLAGS; - sec = NULL; - value = sym.st_value; - *sym_hash = NULL; - - bind = ELF_ST_BIND (sym.st_info); - if (bind == STB_LOCAL) - { - /* This should be impossible, since ELF requires that all - global symbols follow all local symbols, and that sh_info - point to the first global symbol. Unfortunatealy, Irix 5 - screws this up. */ - continue; - } - else if (bind == STB_GLOBAL) - { - if (sym.st_shndx != SHN_UNDEF - && sym.st_shndx != SHN_COMMON) - flags = BSF_GLOBAL; - else - flags = 0; - } - else if (bind == STB_WEAK) - flags = BSF_WEAK; - else - { - /* Leave it up to the processor backend. */ - } - - if (sym.st_shndx == SHN_UNDEF) - sec = bfd_und_section_ptr; - else if (sym.st_shndx > 0 && sym.st_shndx < SHN_LORESERVE) - { - sec = section_from_elf_index (abfd, sym.st_shndx); - if (sec != NULL) - value -= sec->vma; - else - sec = bfd_abs_section_ptr; - } - else if (sym.st_shndx == SHN_ABS) - sec = bfd_abs_section_ptr; - else if (sym.st_shndx == SHN_COMMON) - { - sec = bfd_com_section_ptr; - /* What ELF calls the size we call the value. What ELF - calls the value we call the alignment. */ - value = sym.st_size; - } - else - { - /* Leave it up to the processor backend. */ - } - - name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, sym.st_name); - if (name == (const char *) NULL) - goto error_return; - - if (add_symbol_hook) - { - if (! (*add_symbol_hook) (abfd, info, &sym, &name, &flags, &sec, - &value)) - goto error_return; - - /* The hook function sets the name to NULL if this symbol - should be skipped for some reason. */ - if (name == (const char *) NULL) - continue; - } - - /* Sanity check that all possibilities were handled. */ - if (sec == (asection *) NULL) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (bfd_is_und_section (sec) - || bfd_is_com_section (sec)) - definition = false; - else - definition = true; - - size_change_ok = false; - type_change_ok = get_elf_backend_data (abfd)->type_change_ok; - if (info->hash->creator->flavour == bfd_target_elf_flavour) - { - /* We need to look up the symbol now in order to get some of - the dynamic object handling right. We pass the hash - table entry in to _bfd_generic_link_add_one_symbol so - that it does not have to look it up again. */ - if (! bfd_is_und_section (sec)) - h = elf_link_hash_lookup (elf_hash_table (info), name, - true, false, false); - else - h = ((struct elf_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, name, true, - false, false)); - if (h == NULL) - goto error_return; - *sym_hash = h; - - if (h->root.type == bfd_link_hash_new) - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* It's OK to change the type if it used to be a weak - definition. */ - if (h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_undefweak) - type_change_ok = true; - - /* It's OK to change the size if it used to be a weak - definition, or if it used to be undefined, or if we will - be overriding an old definition. */ - if (type_change_ok - || h->root.type == bfd_link_hash_undefined) - size_change_ok = true; - - /* If we are looking at a dynamic object, and this is a - definition, we need to see if it has already been defined - by some other object. If it has, we want to use the - existing definition, and we do not want to report a - multiple symbol definition error; we do this by - clobbering sec to be bfd_und_section_ptr. */ - if (dynamic && definition) - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || (h->root.type == bfd_link_hash_common - && bind == STB_WEAK)) - { - sec = bfd_und_section_ptr; - definition = false; - size_change_ok = true; - } - } - - /* Similarly, if we are not looking at a dynamic object, and - we have a definition, we want to override any definition - we may have from a dynamic object. Symbols from regular - files always take precedence over symbols from dynamic - objects, even if they are defined after the dynamic - object in the link. */ - if (! dynamic - && definition - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (bfd_get_flavour (h->root.u.def.section->owner) - == bfd_target_elf_flavour) - && (elf_elfheader (h->root.u.def.section->owner)->e_type - == ET_DYN)) - { - /* Change the hash table entry to undefined, and let - _bfd_generic_link_add_one_symbol do the right thing - with the new definition. */ - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = h->root.u.def.section->owner; - size_change_ok = true; - } - } - - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, flags, sec, value, (const char *) NULL, - false, collect, (struct bfd_link_hash_entry **) sym_hash))) - goto error_return; - - h = *sym_hash; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - *sym_hash = h; - - new_weakdef = false; - if (dynamic - && definition - && (flags & BSF_WEAK) != 0 - && ELF_ST_TYPE (sym.st_info) != STT_FUNC - && info->hash->creator->flavour == bfd_target_elf_flavour - && h->weakdef == NULL) - { - /* Keep a list of all weak defined non function symbols from - a dynamic object, using the weakdef field. Later in this - function we will set the weakdef field to the correct - value. We only put non-function symbols from dynamic - objects on this list, because that happens to be the only - time we need to know the normal symbol corresponding to a - weak symbol, and the information is time consuming to - figure out. If the weakdef field is not already NULL, - then this symbol was already defined by some previous - dynamic object, and we will be using that previous - definition anyhow. */ - - h->weakdef = weaks; - weaks = h; - new_weakdef = true; - } - - /* Get the alignment of a common symbol. */ - if (sym.st_shndx == SHN_COMMON - && h->root.type == bfd_link_hash_common) - h->root.u.c.p->alignment_power = bfd_log2 (sym.st_value); - - if (info->hash->creator->flavour == bfd_target_elf_flavour) - { - int old_flags; - boolean dynsym; - int new_flag; - - /* Remember the symbol size and type. */ - if (sym.st_size != 0 - && (definition || h->size == 0)) - { - if (h->size != 0 && h->size != sym.st_size && ! size_change_ok) - (*_bfd_error_handler) - ("Warning: size of symbol `%s' changed from %lu to %lu in %s", - name, (unsigned long) h->size, (unsigned long) sym.st_size, - bfd_get_filename (abfd)); - - h->size = sym.st_size; - } - if (ELF_ST_TYPE (sym.st_info) != STT_NOTYPE - && (definition || h->type == STT_NOTYPE)) - { - if (h->type != STT_NOTYPE - && h->type != ELF_ST_TYPE (sym.st_info) - && ! type_change_ok) - (*_bfd_error_handler) - ("Warning: type of symbol `%s' changed from %d to %d in %s", - name, h->type, ELF_ST_TYPE (sym.st_info), - bfd_get_filename (abfd)); - - h->type = ELF_ST_TYPE (sym.st_info); - } - - /* Set a flag in the hash table entry indicating the type of - reference or definition we just found. Keep a count of - the number of dynamic symbols we find. A dynamic symbol - is one which is referenced or defined by both a regular - object and a shared object, or one which is referenced or - defined by more than one shared object. */ - old_flags = h->elf_link_hash_flags; - dynsym = false; - if (! dynamic) - { - if (! definition) - new_flag = ELF_LINK_HASH_REF_REGULAR; - else - new_flag = ELF_LINK_HASH_DEF_REGULAR; - if (info->shared - || (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0) - dynsym = true; - } - else - { - if (! definition) - new_flag = ELF_LINK_HASH_REF_DYNAMIC; - else - new_flag = ELF_LINK_HASH_DEF_DYNAMIC; - if ((old_flags & new_flag) != 0 - || (old_flags & (ELF_LINK_HASH_DEF_REGULAR - | ELF_LINK_HASH_REF_REGULAR)) != 0 - || (h->weakdef != NULL - && (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0)) - dynsym = true; - } - - h->elf_link_hash_flags |= new_flag; - if (dynsym && h->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) - goto error_return; - if (h->weakdef != NULL - && ! new_weakdef - && h->weakdef->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, - h->weakdef)) - goto error_return; - } - } - } - } - - /* Now set the weakdefs field correctly for all the weak defined - symbols we found. The only way to do this is to search all the - symbols. Since we only need the information for non functions in - dynamic objects, that's the only time we actually put anything on - the list WEAKS. We need this information so that if a regular - object refers to a symbol defined weakly in a dynamic object, the - real symbol in the dynamic object is also put in the dynamic - symbols; we also must arrange for both symbols to point to the - same memory location. We could handle the general case of symbol - aliasing, but a general symbol alias can only be generated in - assembler code, handling it correctly would be very time - consuming, and other ELF linkers don't handle general aliasing - either. */ - while (weaks != NULL) - { - struct elf_link_hash_entry *hlook; - asection *slook; - bfd_vma vlook; - struct elf_link_hash_entry **hpp; - struct elf_link_hash_entry **hppend; - - hlook = weaks; - weaks = hlook->weakdef; - hlook->weakdef = NULL; - - BFD_ASSERT (hlook->root.type == bfd_link_hash_defined - || hlook->root.type == bfd_link_hash_defweak - || hlook->root.type == bfd_link_hash_common - || hlook->root.type == bfd_link_hash_indirect); - slook = hlook->root.u.def.section; - vlook = hlook->root.u.def.value; - - hpp = elf_sym_hashes (abfd); - hppend = hpp + extsymcount; - for (; hpp < hppend; hpp++) - { - struct elf_link_hash_entry *h; - - h = *hpp; - if (h != NULL && h != hlook - && h->root.type == bfd_link_hash_defined - && h->root.u.def.section == slook - && h->root.u.def.value == vlook) - { - hlook->weakdef = h; - - /* If the weak definition is in the list of dynamic - symbols, make sure the real definition is put there - as well. */ - if (hlook->dynindx != -1 - && h->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) - goto error_return; - } - - break; - } - } - } - - if (buf != NULL) - { - free (buf); - buf = NULL; - } - - /* If this object is the same format as the output object, and it is - not a shared library, then let the backend look through the - relocs. - - This is required to build global offset table entries and to - arrange for dynamic relocs. It is not required for the - particular common case of linking non PIC code, even when linking - against shared libraries, but unfortunately there is no way of - knowing whether an object file has been compiled PIC or not. - Looking through the relocs is not particularly time consuming. - The problem is that we must either (1) keep the relocs in memory, - which causes the linker to require additional runtime memory or - (2) read the relocs twice from the input file, which wastes time. - This would be a good case for using mmap. - - I have no idea how to handle linking PIC code into a file of a - different format. It probably can't be done. */ - check_relocs = get_elf_backend_data (abfd)->check_relocs; - if (! dynamic - && abfd->xvec == info->hash->creator - && check_relocs != NULL) - { - asection *o; - - for (o = abfd->sections; o != NULL; o = o->next) - { - Elf_Internal_Rela *internal_relocs; - boolean ok; - - if ((o->flags & SEC_RELOC) == 0 - || o->reloc_count == 0) - continue; - - /* I believe we can ignore the relocs for any section which - does not form part of the final process image, such as a - debugging section. */ - if ((o->flags & SEC_ALLOC) == 0) - continue; - - internal_relocs = elf_link_read_relocs (abfd, o, (PTR) NULL, - (Elf_Internal_Rela *) NULL, - info->keep_memory); - if (internal_relocs == NULL) - goto error_return; - - ok = (*check_relocs) (abfd, info, o, internal_relocs); - - if (! info->keep_memory) - free (internal_relocs); - - if (! ok) - goto error_return; - } - } - - return true; - - error_return: - if (buf != NULL) - free (buf); - if (dynbuf != NULL) - free (dynbuf); - return false; -} - -/* Create some sections which will be filled in with dynamic linking - information. ABFD is an input file which requires dynamic sections - to be created. The dynamic sections take up virtual memory space - when the final executable is run, so we need to create them before - addresses are assigned to the output sections. We work out the - actual contents and size of these sections later. */ - -boolean -elf_link_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - struct elf_backend_data *bed; - - if (elf_hash_table (info)->dynamic_sections_created) - return true; - - /* Make sure that all dynamic sections use the same input BFD. */ - if (elf_hash_table (info)->dynobj == NULL) - elf_hash_table (info)->dynobj = abfd; - else - abfd = elf_hash_table (info)->dynobj; - - /* Note that we set the SEC_IN_MEMORY flag for all of these - sections. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* A dynamically linked executable has a .interp section, but a - shared library does not. */ - if (! info->shared) - { - s = bfd_make_section (abfd, ".interp"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)) - return false; - } - - s = bfd_make_section (abfd, ".dynsym"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - s = bfd_make_section (abfd, ".dynstr"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)) - return false; - - /* Create a strtab to hold the dynamic symbol names. */ - if (elf_hash_table (info)->dynstr == NULL) - { - elf_hash_table (info)->dynstr = elf_stringtab_init (); - if (elf_hash_table (info)->dynstr == NULL) - return false; - } - - s = bfd_make_section (abfd, ".dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - /* The special symbol _DYNAMIC is always set to the start of the - .dynamic section. This call occurs before we have processed the - symbols for any dynamic object, so we don't have to worry about - overriding a dynamic definition. We could set _DYNAMIC in a - linker script, but we only want to define it if we are, in fact, - creating a .dynamic section. We don't want to define it if there - is no .dynamic section, since on some ELF platforms the start up - code examines it to decide how to initialize the process. */ - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, (bfd_vma) 0, - (const char *) NULL, false, get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - - s = bfd_make_section (abfd, ".hash"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - /* Let the backend create the rest of the sections. This lets the - backend set the right flags. The backend will normally create - the .got and .plt sections. */ - bed = get_elf_backend_data (abfd); - if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) - return false; - - elf_hash_table (info)->dynamic_sections_created = true; - - return true; -} - -/* Add an entry to the .dynamic table. */ - -boolean -elf_add_dynamic_entry (info, tag, val) - struct bfd_link_info *info; - bfd_vma tag; - bfd_vma val; -{ - Elf_Internal_Dyn dyn; - bfd *dynobj; - asection *s; - size_t newsize; - bfd_byte *newcontents; - - dynobj = elf_hash_table (info)->dynobj; - - s = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (s != NULL); - - newsize = s->_raw_size + sizeof (Elf_External_Dyn); - newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize); - if (newcontents == NULL) - return false; - - dyn.d_tag = tag; - dyn.d_un.d_val = val; - elf_swap_dyn_out (dynobj, &dyn, - (Elf_External_Dyn *) (newcontents + s->_raw_size)); - - s->_raw_size = newsize; - s->contents = newcontents; - - return true; -} - - -/* Read and swap the relocs for a section. They may have been cached. - If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are not NULL, - they are used as buffers to read into. They are known to be large - enough. If the INTERNAL_RELOCS relocs argument is NULL, the return - value is allocated using either malloc or bfd_alloc, according to - the KEEP_MEMORY argument. */ - -static Elf_Internal_Rela * -elf_link_read_relocs (abfd, o, external_relocs, internal_relocs, keep_memory) - bfd *abfd; - asection *o; - PTR external_relocs; - Elf_Internal_Rela *internal_relocs; - boolean keep_memory; -{ - Elf_Internal_Shdr *rel_hdr; - PTR alloc1 = NULL; - Elf_Internal_Rela *alloc2 = NULL; - - if (elf_section_data (o)->relocs != NULL) - return elf_section_data (o)->relocs; - - if (o->reloc_count == 0) - return NULL; - - rel_hdr = &elf_section_data (o)->rel_hdr; - - if (internal_relocs == NULL) - { - size_t size; - - size = o->reloc_count * sizeof (Elf_Internal_Rela); - if (keep_memory) - internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size); - else - internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size); - if (internal_relocs == NULL) - goto error_return; - } - - if (external_relocs == NULL) - { - alloc1 = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size); - if (alloc1 == NULL) - goto error_return; - external_relocs = alloc1; - } - - if ((bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0) - || (bfd_read (external_relocs, 1, rel_hdr->sh_size, abfd) - != rel_hdr->sh_size)) - goto error_return; - - /* Swap in the relocs. For convenience, we always produce an - Elf_Internal_Rela array; if the relocs are Rel, we set the addend - to 0. */ - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_External_Rel *erelend; - Elf_Internal_Rela *irela; - - erel = (Elf_External_Rel *) external_relocs; - erelend = erel + o->reloc_count; - irela = internal_relocs; - for (; erel < erelend; erel++, irela++) - { - Elf_Internal_Rel irel; - - elf_swap_reloc_in (abfd, erel, &irel); - irela->r_offset = irel.r_offset; - irela->r_info = irel.r_info; - irela->r_addend = 0; - } - } - else - { - Elf_External_Rela *erela; - Elf_External_Rela *erelaend; - Elf_Internal_Rela *irela; - - BFD_ASSERT (rel_hdr->sh_entsize == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) external_relocs; - erelaend = erela + o->reloc_count; - irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - elf_swap_reloca_in (abfd, erela, irela); - } - - /* Cache the results for next time, if we can. */ - if (keep_memory) - elf_section_data (o)->relocs = internal_relocs; - - if (alloc1 != NULL) - free (alloc1); - - /* Don't free alloc2, since if it was allocated we are passing it - back (under the name of internal_relocs). */ - - return internal_relocs; - - error_return: - if (alloc1 != NULL) - free (alloc1); - if (alloc2 != NULL) - free (alloc2); - return NULL; -} - - -/* Record an assignment to a symbol made by a linker script. We need - this in case some dynamic object refers to this symbol. */ - -/*ARGSUSED*/ -boolean -NAME(bfd_elf,record_link_assignment) (output_bfd, info, name, provide) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; - boolean provide; -{ - struct elf_link_hash_entry *h; - - if (info->hash->creator->flavour != bfd_target_elf_flavour) - return true; - - h = elf_link_hash_lookup (elf_hash_table (info), name, true, true, false); - if (h == NULL) - return false; - - if (h->root.type == bfd_link_hash_new) - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - - /* If this symbol is being provided by the linker script, and it is - currently defined by a dynamic object, but not by a regular - object, then mark it as undefined so that the generic linker will - force the correct value. */ - if (provide - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - h->root.type = bfd_link_hash_undefined; - - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (((h->elf_link_hash_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0 - || info->shared) - && h->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - - /* If this is a weak defined symbol, and we know a corresponding - real symbol from the same dynamic object, make sure the real - symbol is also made into a dynamic symbol. */ - if (h->weakdef != NULL - && h->weakdef->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h->weakdef)) - return false; - } - } - - return true; -} - - -/* Array used to determine the number of hash table buckets to use - based on the number of symbols there are. If there are fewer than - 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, - fewer than 37 we use 17 buckets, and so forth. We never use more - than 521 buckets. */ - -static const size_t elf_buckets[] = -{ - 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 0 -}; - -/* Set up the sizes and contents of the ELF dynamic sections. This is - called by the ELF linker emulation before_allocation routine. We - must set the sizes of the sections before the linker sets the - addresses of the various sections. */ - -boolean -NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, - export_dynamic, info, sinterpptr) - bfd *output_bfd; - const char *soname; - const char *rpath; - boolean export_dynamic; - struct bfd_link_info *info; - asection **sinterpptr; -{ - bfd *dynobj; - struct elf_backend_data *bed; - - *sinterpptr = NULL; - - if (info->hash->creator->flavour != bfd_target_elf_flavour) - return true; - - dynobj = elf_hash_table (info)->dynobj; - - /* If there were no dynamic objects in the link, there is nothing to - do here. */ - if (dynobj == NULL) - return true; - - /* If we are supposed to export all symbols into the dynamic symbol - table (this is not the normal case), then do so. */ - if (export_dynamic) - { - struct elf_info_failed eif; - - eif.failed = false; - eif.info = info; - elf_link_hash_traverse (elf_hash_table (info), elf_export_symbol, - (PTR) &eif); - if (eif.failed) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - struct elf_info_failed eif; - struct elf_link_hash_entry *h; - bfd_size_type strsize; - - *sinterpptr = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (*sinterpptr != NULL || info->shared); - - if (soname != NULL) - { - bfd_size_type indx; - - indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr, soname, - true, true); - if (indx == (bfd_size_type) -1 - || ! elf_add_dynamic_entry (info, DT_SONAME, indx)) - return false; - } - - if (info->symbolic) - { - if (! elf_add_dynamic_entry (info, DT_SYMBOLIC, 0)) - return false; - } - - if (rpath != NULL) - { - bfd_size_type indx; - - indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr, rpath, - true, true); - if (indx == (bfd_size_type) -1 - || ! elf_add_dynamic_entry (info, DT_RPATH, indx)) - return false; - } - - /* Find all symbols which were defined in a dynamic object and make - the backend pick a reasonable value for them. */ - eif.failed = false; - eif.info = info; - elf_link_hash_traverse (elf_hash_table (info), - elf_adjust_dynamic_symbol, - (PTR) &eif); - if (eif.failed) - return false; - - /* Add some entries to the .dynamic section. We fill in some of the - values later, in elf_bfd_final_link, but we must add the entries - now so that we know the final size of the .dynamic section. */ - h = elf_link_hash_lookup (elf_hash_table (info), "_init", false, - false, false); - if (h != NULL - && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR - | ELF_LINK_HASH_DEF_REGULAR)) != 0) - { - if (! elf_add_dynamic_entry (info, DT_INIT, 0)) - return false; - } - h = elf_link_hash_lookup (elf_hash_table (info), "_fini", false, - false, false); - if (h != NULL - && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR - | ELF_LINK_HASH_DEF_REGULAR)) != 0) - { - if (! elf_add_dynamic_entry (info, DT_FINI, 0)) - return false; - } - strsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - if (! elf_add_dynamic_entry (info, DT_HASH, 0) - || ! elf_add_dynamic_entry (info, DT_STRTAB, 0) - || ! elf_add_dynamic_entry (info, DT_SYMTAB, 0) - || ! elf_add_dynamic_entry (info, DT_STRSZ, strsize) - || ! elf_add_dynamic_entry (info, DT_SYMENT, - sizeof (Elf_External_Sym))) - return false; - } - - /* The backend must work out the sizes of all the other dynamic - sections. */ - bed = get_elf_backend_data (output_bfd); - if (! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info)) - return false; - - if (elf_hash_table (info)->dynamic_sections_created) - { - size_t dynsymcount; - asection *s; - size_t i; - size_t bucketcount = 0; - Elf_Internal_Sym isym; - - /* Set the size of the .dynsym and .hash sections. We counted - the number of dynamic symbols in elf_link_add_object_symbols. - We will build the contents of .dynsym and .hash when we build - the final symbol table, because until then we do not know the - correct value to give the symbols. We built the .dynstr - section as we went along in elf_link_add_object_symbols. */ - dynsymcount = elf_hash_table (info)->dynsymcount; - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - s->_raw_size = dynsymcount * sizeof (Elf_External_Sym); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - - /* The first entry in .dynsym is a dummy symbol. */ - isym.st_value = 0; - isym.st_size = 0; - isym.st_name = 0; - isym.st_info = 0; - isym.st_other = 0; - isym.st_shndx = 0; - elf_swap_symbol_out (output_bfd, &isym, - (PTR) (Elf_External_Sym *) s->contents); - - for (i = 0; elf_buckets[i] != 0; i++) - { - bucketcount = elf_buckets[i]; - if (dynsymcount < elf_buckets[i + 1]) - break; - } - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - s->_raw_size = (2 + bucketcount + dynsymcount) * (ARCH_SIZE / 8); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL) - return false; - memset (s->contents, 0, (size_t) s->_raw_size); - - put_word (output_bfd, bucketcount, s->contents); - put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8)); - - elf_hash_table (info)->bucketcount = bucketcount; - - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - s->_raw_size = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - - if (! elf_add_dynamic_entry (info, DT_NULL, 0)) - return false; - } - - return true; -} - - -/* This routine is used to export all defined symbols into the dynamic - symbol table. It is called via elf_link_hash_traverse. */ - -static boolean -elf_export_symbol (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct elf_info_failed *eif = (struct elf_info_failed *) data; - - if (h->dynindx == -1 - && (h->elf_link_hash_flags - & (ELF_LINK_HASH_DEF_REGULAR | ELF_LINK_HASH_REF_REGULAR)) != 0) - { - if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h)) - { - eif->failed = true; - return false; - } - } - - return true; -} - - -/* Make the backend pick a good value for a dynamic symbol. This is - called via elf_link_hash_traverse, and also calls itself - recursively. */ - -static boolean -elf_adjust_dynamic_symbol (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct elf_info_failed *eif = (struct elf_info_failed *) data; - bfd *dynobj; - struct elf_backend_data *bed; - - /* If this symbol was mentioned in a non-ELF file, try to set - DEF_REGULAR and REF_REGULAR correctly. This is the only way to - permit a non-ELF file to correctly refer to a symbol defined in - an ELF dynamic object. */ - if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0) - { - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; - else - { - if (h->root.u.def.section->owner != NULL - && (bfd_get_flavour (h->root.u.def.section->owner) - == bfd_target_elf_flavour)) - h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; - else - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - { - if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h)) - { - eif->failed = true; - return false; - } - } - } - - /* If -Bsymbolic was used (which means to bind references to global - symbols to the definition within the shared object), and this - symbol was defined in a regular object, then it actually doesn't - need a PLT entry. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0 - && eif->info->shared - && eif->info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) - h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT; - - /* If this symbol does not require a PLT entry, and it is not - defined by a dynamic object, or is not referenced by a regular - object, ignore it. We do have to handle a weak defined symbol, - even if no regular object refers to it, if we decided to add it - to the dynamic symbol table. FIXME: Do we normally need to worry - about symbols which are defined by one dynamic object and - referenced by another one? */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0 - && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - || ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 - && (h->weakdef == NULL || h->weakdef->dynindx == -1)))) - return true; - - /* If we've already adjusted this symbol, don't do it again. This - can happen via a recursive call. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0) - return true; - - /* Don't look at this symbol again. Note that we must set this - after checking the above conditions, because we may look at a - symbol once, decide not to do anything, and then get called - recursively later after REF_REGULAR is set below. */ - h->elf_link_hash_flags |= ELF_LINK_HASH_DYNAMIC_ADJUSTED; - - /* If this is a weak definition, and we know a real definition, and - the real symbol is not itself defined by a regular object file, - then get a good value for the real definition. We handle the - real symbol first, for the convenience of the backend routine. - - Note that there is a confusing case here. If the real definition - is defined by a regular object file, we don't get the real symbol - from the dynamic object, but we do get the weak symbol. If the - processor backend uses a COPY reloc, then if some routine in the - dynamic object changes the real symbol, we will not see that - change in the corresponding weak symbol. This is the way other - ELF linkers work as well, and seems to be a result of the shared - library model. - - I will clarify this issue. Most SVR4 shared libraries define the - variable _timezone and define timezone as a weak synonym. The - tzset call changes _timezone. If you write - extern int timezone; - int _timezone = 5; - int main () { tzset (); printf ("%d %d\n", timezone, _timezone); } - you might expect that, since timezone is a synonym for _timezone, - the same number will print both times. However, if the processor - backend uses a COPY reloc, then actually timezone will be copied - into your process image, and, since you define _timezone - yourself, _timezone will not. Thus timezone and _timezone will - wind up at different memory locations. The tzset call will set - _timezone, leaving timezone unchanged. */ - - if (h->weakdef != NULL) - { - struct elf_link_hash_entry *weakdef; - - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak); - weakdef = h->weakdef; - BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined - || weakdef->root.type == bfd_link_hash_defweak); - BFD_ASSERT (weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC); - if ((weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) - { - /* This symbol is defined by a regular object file, so we - will not do anything special. Clear weakdef for the - convenience of the processor backend. */ - h->weakdef = NULL; - } - else - { - /* There is an implicit reference by a regular object file - via the weak symbol. */ - weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; - if (! elf_adjust_dynamic_symbol (weakdef, (PTR) eif)) - return false; - } - } - - dynobj = elf_hash_table (eif->info)->dynobj; - bed = get_elf_backend_data (dynobj); - if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h)) - { - eif->failed = true; - return false; - } - - return true; -} - -/* Final phase of ELF linker. */ - -/* A structure we use to avoid passing large numbers of arguments. */ - -struct elf_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Symbol string table. */ - struct bfd_strtab_hash *symstrtab; - /* .dynsym section. */ - asection *dynsym_sec; - /* .hash section. */ - asection *hash_sec; - /* Buffer large enough to hold contents of any section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any section. */ - PTR external_relocs; - /* Buffer large enough to hold internal relocs of any section. */ - Elf_Internal_Rela *internal_relocs; - /* Buffer large enough to hold external local symbols of any input - BFD. */ - Elf_External_Sym *external_syms; - /* Buffer large enough to hold internal local symbols of any input - BFD. */ - Elf_Internal_Sym *internal_syms; - /* Array large enough to hold a symbol index for each local symbol - of any input BFD. */ - long *indices; - /* Array large enough to hold a section pointer for each local - symbol of any input BFD. */ - asection **sections; - /* Buffer to hold swapped out symbols. */ - Elf_External_Sym *symbuf; - /* Number of swapped out symbols in buffer. */ - size_t symbuf_count; - /* Number of symbols which fit in symbuf. */ - size_t symbuf_size; -}; - -static boolean elf_link_output_sym - PARAMS ((struct elf_final_link_info *, const char *, - Elf_Internal_Sym *, asection *)); -static boolean elf_link_flush_output_syms - PARAMS ((struct elf_final_link_info *)); -static boolean elf_link_output_extsym - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf_link_input_bfd - PARAMS ((struct elf_final_link_info *, bfd *)); -static boolean elf_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* This struct is used to pass information to routines called via - elf_link_hash_traverse which must return failure. */ - -struct elf_finfo_failed -{ - boolean failed; - struct elf_final_link_info *finfo; -}; - -/* Do the final step of an ELF link. */ - -boolean -elf_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean dynamic; - bfd *dynobj; - struct elf_final_link_info finfo; - register asection *o; - register struct bfd_link_order *p; - register bfd *sub; - size_t max_contents_size; - size_t max_external_reloc_size; - size_t max_internal_reloc_count; - size_t max_sym_count; - file_ptr off; - Elf_Internal_Sym elfsym; - unsigned int i; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_finfo_failed eif; - - if (info->shared) - abfd->flags |= DYNAMIC; - - dynamic = elf_hash_table (info)->dynamic_sections_created; - dynobj = elf_hash_table (info)->dynobj; - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.symstrtab = elf_stringtab_init (); - if (finfo.symstrtab == NULL) - return false; - if (! dynamic) - { - finfo.dynsym_sec = NULL; - finfo.hash_sec = NULL; - } - else - { - finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); - finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL); - } - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - finfo.external_syms = NULL; - finfo.internal_syms = NULL; - finfo.indices = NULL; - finfo.sections = NULL; - finfo.symbuf = NULL; - finfo.symbuf_count = 0; - - /* Count up the number of relocations we will output for each output - section, so that we know the sizes of the reloc sections. We - also figure out some maximum sizes. */ - max_contents_size = 0; - max_external_reloc_size = 0; - max_internal_reloc_count = 0; - max_sym_count = 0; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - o->reloc_count = 0; - - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - else if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->relocateable) - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->_cooked_size > max_contents_size) - max_contents_size = sec->_cooked_size; - - /* We are interested in just local symbols, not all - symbols. */ - if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour) - { - size_t sym_count; - - if (elf_bad_symtab (sec->owner)) - sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size - / sizeof (Elf_External_Sym)); - else - sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; - - if (sym_count > max_sym_count) - max_sym_count = sym_count; - - if ((sec->flags & SEC_RELOC) != 0) - { - size_t ext_size; - - ext_size = elf_section_data (sec)->rel_hdr.sh_size; - if (ext_size > max_external_reloc_size) - max_external_reloc_size = ext_size; - if (sec->reloc_count > max_internal_reloc_count) - max_internal_reloc_count = sec->reloc_count; - } - } - } - } - - if (o->reloc_count > 0) - o->flags |= SEC_RELOC; - else - { - /* Explicitly clear the SEC_RELOC flag. The linker tends to - set it (this is probably a bug) and if it is set - assign_section_numbers will create a reloc section. */ - o->flags &=~ SEC_RELOC; - } - - /* If the SEC_ALLOC flag is not set, force the section VMA to - zero. This is done in elf_fake_sections as well, but forcing - the VMA to 0 here will ensure that relocs against these - sections are handled correctly. */ - if ((o->flags & SEC_ALLOC) == 0) - o->vma = 0; - } - - /* Figure out the file positions for everything but the symbol table - and the relocs. We set symcount to force assign_section_numbers - to create a symbol table. */ - abfd->symcount = info->strip == strip_all ? 0 : 1; - BFD_ASSERT (! abfd->output_has_begun); - if (! _bfd_elf_compute_section_file_positions (abfd, info)) - goto error_return; - - /* That created the reloc sections. Set their sizes, and assign - them file positions, and allocate some buffers. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Shdr *rel_hdr; - register struct elf_link_hash_entry **p, **pend; - - rel_hdr = &elf_section_data (o)->rel_hdr; - - rel_hdr->sh_size = rel_hdr->sh_entsize * o->reloc_count; - - /* The contents field must last into write_object_contents, - so we allocate it with bfd_alloc rather than malloc. */ - rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size); - if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) - goto error_return; - - p = ((struct elf_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct elf_link_hash_entry *))); - if (p == NULL && o->reloc_count != 0) - goto error_return; - elf_section_data (o)->rel_hashes = p; - pend = p + o->reloc_count; - for (; p < pend; p++) - *p = NULL; - - /* Use the reloc_count field as an index when outputting the - relocs. */ - o->reloc_count = 0; - } - } - - _bfd_elf_assign_file_positions_for_relocs (abfd); - - /* We have now assigned file positions for all the sections except - .symtab and .strtab. We start the .symtab section at the current - file position, and write directly to it. We build the .strtab - section in memory. */ - abfd->symcount = 0; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - /* sh_name is set in prep_headers. */ - symtab_hdr->sh_type = SHT_SYMTAB; - symtab_hdr->sh_flags = 0; - symtab_hdr->sh_addr = 0; - symtab_hdr->sh_size = 0; - symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); - /* sh_link is set in assign_section_numbers. */ - /* sh_info is set below. */ - /* sh_offset is set just below. */ - symtab_hdr->sh_addralign = 4; /* FIXME: system dependent? */ - - off = elf_tdata (abfd)->next_file_pos; - off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, true); - - /* Note that at this point elf_tdata (abfd)->next_file_pos is - incorrect. We do not yet know the size of the .symtab section. - We correct next_file_pos below, after we do know the size. */ - - /* Allocate a buffer to hold swapped out symbols. This is to avoid - continuously seeking to the right position in the file. */ - if (! info->keep_memory || max_sym_count < 20) - finfo.symbuf_size = 20; - else - finfo.symbuf_size = max_sym_count; - finfo.symbuf = ((Elf_External_Sym *) - bfd_malloc (finfo.symbuf_size * sizeof (Elf_External_Sym))); - if (finfo.symbuf == NULL) - goto error_return; - - /* Start writing out the symbol table. The first symbol is always a - dummy symbol. */ - if (info->strip != strip_all || info->relocateable) - { - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = 0; - elfsym.st_other = 0; - elfsym.st_shndx = SHN_UNDEF; - if (! elf_link_output_sym (&finfo, (const char *) NULL, - &elfsym, bfd_und_section_ptr)) - goto error_return; - } - -#if 0 - /* Some standard ELF linkers do this, but we don't because it causes - bootstrap comparison failures. */ - /* Output a file symbol for the output file as the second symbol. - We output this even if we are discarding local symbols, although - I'm not sure if this is correct. */ - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - elfsym.st_other = 0; - elfsym.st_shndx = SHN_ABS; - if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd), - &elfsym, bfd_abs_section_ptr)) - goto error_return; -#endif - - /* Output a symbol for each section. We output these even if we are - discarding local symbols, since they are used for relocs. These - symbols have no names. We store the index of each one in the - index field of the section, so that we can find it again when - outputting relocs. */ - if (info->strip != strip_all || info->relocateable) - { - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - elfsym.st_other = 0; - for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++) - { - o = section_from_elf_index (abfd, i); - if (o != NULL) - o->target_index = abfd->symcount; - elfsym.st_shndx = i; - if (! elf_link_output_sym (&finfo, (const char *) NULL, - &elfsym, o)) - goto error_return; - } - } - - /* Allocate some memory to hold information read in from the input - files. */ - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (PTR) bfd_malloc (max_external_reloc_size); - finfo.internal_relocs = ((Elf_Internal_Rela *) - bfd_malloc (max_internal_reloc_count - * sizeof (Elf_Internal_Rela))); - finfo.external_syms = ((Elf_External_Sym *) - bfd_malloc (max_sym_count - * sizeof (Elf_External_Sym))); - finfo.internal_syms = ((Elf_Internal_Sym *) - bfd_malloc (max_sym_count - * sizeof (Elf_Internal_Sym))); - finfo.indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.sections = ((asection **) - bfd_malloc (max_sym_count * sizeof (asection *))); - if ((finfo.contents == NULL && max_contents_size != 0) - || (finfo.external_relocs == NULL && max_external_reloc_size != 0) - || (finfo.internal_relocs == NULL && max_internal_reloc_count != 0) - || (finfo.external_syms == NULL && max_sym_count != 0) - || (finfo.internal_syms == NULL && max_sym_count != 0) - || (finfo.indices == NULL && max_sym_count != 0) - || (finfo.sections == NULL && max_sym_count != 0)) - goto error_return; - - /* Since ELF permits relocations to be against local symbols, we - must have the local symbols available when we do the relocations. - Since we would rather only read the local symbols once, and we - would rather not keep them in memory, we handle all the - relocations for a single input file at the same time. - - Unfortunately, there is no way to know the total number of local - symbols until we have seen all of them, and the local symbol - indices precede the global symbol indices. This means that when - we are generating relocateable output, and we see a reloc against - a global symbol, we can not know the symbol index until we have - finished examining all the local symbols to see which ones we are - going to output. To deal with this, we keep the relocations in - memory, and don't output them until the end of the link. This is - an unfortunate waste of memory, but I don't see a good way around - it. Fortunately, it only happens when performing a relocateable - link, which is not the common case. FIXME: If keep_memory is set - we could write the relocs out and then read them again; I don't - know how bad the memory loss will be. */ - - for (sub = info->input_bfds; sub != NULL; sub = sub->next) - sub->output_has_begun = false; - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_elf_flavour)) - { - sub = p->u.indirect.section->owner; - if (! sub->output_has_begun) - { - if (! elf_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! elf_reloc_link_order (abfd, info, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* That wrote out all the local symbols. Finish up the symbol table - with the global symbols. */ - - /* The sh_info field records the index of the first non local - symbol. */ - symtab_hdr->sh_info = abfd->symcount; - if (dynamic) - elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1; - - /* We get the global symbols from the hash table. */ - eif.failed = false; - eif.finfo = &finfo; - elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, - (PTR) &eif); - if (eif.failed) - return false; - - /* Flush all symbols to the file. */ - if (! elf_link_flush_output_syms (&finfo)) - return false; - - /* Now we know the size of the symtab section. */ - off += symtab_hdr->sh_size; - - /* Finish up and write out the symbol string table (.strtab) - section. */ - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - /* sh_name was set in prep_headers. */ - symstrtab_hdr->sh_type = SHT_STRTAB; - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab); - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - /* sh_offset is set just below. */ - symstrtab_hdr->sh_addralign = 1; - - off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, true); - elf_tdata (abfd)->next_file_pos = off; - - if (abfd->symcount > 0) - { - if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, finfo.symstrtab)) - return false; - } - - /* Adjust the relocs to have the correct symbol indices. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - struct elf_link_hash_entry **rel_hash; - Elf_Internal_Shdr *rel_hdr; - - if ((o->flags & SEC_RELOC) == 0) - continue; - - rel_hash = elf_section_data (o)->rel_hashes; - rel_hdr = &elf_section_data (o)->rel_hdr; - for (i = 0; i < o->reloc_count; i++, rel_hash++) - { - if (*rel_hash == NULL) - continue; - - BFD_ASSERT ((*rel_hash)->indx >= 0); - - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_Internal_Rel irel; - - erel = (Elf_External_Rel *) rel_hdr->contents + i; - elf_swap_reloc_in (abfd, erel, &irel); - irel.r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irel.r_info)); - elf_swap_reloc_out (abfd, &irel, erel); - } - else - { - Elf_External_Rela *erela; - Elf_Internal_Rela irela; - - BFD_ASSERT (rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) rel_hdr->contents + i; - elf_swap_reloca_in (abfd, erela, &irela); - irela.r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irela.r_info)); - elf_swap_reloca_out (abfd, &irela, erela); - } - } - - /* Set the reloc_count field to 0 to prevent write_relocs from - trying to swap the relocs out itself. */ - o->reloc_count = 0; - } - - /* If we are linking against a dynamic object, or generating a - shared library, finish up the dynamic linking information. */ - if (dynamic) - { - Elf_External_Dyn *dyncon, *dynconend; - - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - - dyncon = (Elf_External_Dyn *) o->contents; - dynconend = (Elf_External_Dyn *) (o->contents + o->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - unsigned int type; - - elf_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - /* SVR4 linkers seem to set DT_INIT and DT_FINI based on - magic _init and _fini symbols. This is pretty ugly, - but we are compatible. */ - case DT_INIT: - name = "_init"; - goto get_sym; - case DT_FINI: - name = "_fini"; - get_sym: - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (elf_hash_table (info), name, - false, false, true); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - dyn.d_un.d_val = h->root.u.def.value; - o = h->root.u.def.section; - if (o->output_section != NULL) - dyn.d_un.d_val += (o->output_section->vma - + o->output_offset); - else - { - /* The symbol is imported from another shared - library and does not apply to this one. */ - dyn.d_un.d_val = 0; - } - - elf_swap_dyn_out (dynobj, &dyn, dyncon); - } - } - break; - - case DT_HASH: - name = ".hash"; - goto get_vma; - case DT_STRTAB: - name = ".dynstr"; - goto get_vma; - case DT_SYMTAB: - name = ".dynsym"; - get_vma: - o = bfd_get_section_by_name (abfd, name); - BFD_ASSERT (o != NULL); - dyn.d_un.d_ptr = o->vma; - elf_swap_dyn_out (dynobj, &dyn, dyncon); - break; - - case DT_REL: - case DT_RELA: - case DT_RELSZ: - case DT_RELASZ: - if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) - type = SHT_REL; - else - type = SHT_RELA; - dyn.d_un.d_val = 0; - for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++) - { - Elf_Internal_Shdr *hdr; - - hdr = elf_elfsections (abfd)[i]; - if (hdr->sh_type == type - && (hdr->sh_flags & SHF_ALLOC) != 0) - { - if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) - dyn.d_un.d_val += hdr->sh_size; - else - { - if (dyn.d_un.d_val == 0 - || hdr->sh_addr < dyn.d_un.d_val) - dyn.d_un.d_val = hdr->sh_addr; - } - } - } - elf_swap_dyn_out (dynobj, &dyn, dyncon); - break; - } - } - } - - /* If we have created any dynamic sections, then output them. */ - if (dynobj != NULL) - { - if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) - goto error_return; - - for (o = dynobj->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || o->_raw_size == 0) - continue; - if ((o->flags & SEC_IN_MEMORY) == 0) - { - /* At this point, we are only interested in sections - created by elf_link_create_dynamic_sections. FIXME: - This test is fragile. */ - continue; - } - if ((elf_section_data (o->output_section)->this_hdr.sh_type - != SHT_STRTAB) - || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0) - { - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, o->output_offset, - o->_raw_size)) - goto error_return; - } - else - { - file_ptr off; - - /* The contents of the .dynstr section are actually in a - stringtab. */ - off = elf_section_data (o->output_section)->this_hdr.sh_offset; - if (bfd_seek (abfd, off, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, - elf_hash_table (info)->dynstr)) - goto error_return; - } - } - } - - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - elf_tdata (abfd)->linker = true; - - return true; - - error_return: - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - return false; -} - -/* Add a symbol to the output symbol table. */ - -static boolean -elf_link_output_sym (finfo, name, elfsym, input_sec) - struct elf_final_link_info *finfo; - const char *name; - Elf_Internal_Sym *elfsym; - asection *input_sec; -{ - boolean (*output_symbol_hook) PARAMS ((bfd *, - struct bfd_link_info *info, - const char *, - Elf_Internal_Sym *, - asection *)); - - output_symbol_hook = get_elf_backend_data (finfo->output_bfd)-> - elf_backend_link_output_symbol_hook; - if (output_symbol_hook != NULL) - { - if (! ((*output_symbol_hook) - (finfo->output_bfd, finfo->info, name, elfsym, input_sec))) - return false; - } - - if (name == (const char *) NULL || *name == '\0') - elfsym->st_name = 0; - else - { - elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab, - name, true, - false); - if (elfsym->st_name == (unsigned long) -1) - return false; - } - - if (finfo->symbuf_count >= finfo->symbuf_size) - { - if (! elf_link_flush_output_syms (finfo)) - return false; - } - - elf_swap_symbol_out (finfo->output_bfd, elfsym, - (PTR) (finfo->symbuf + finfo->symbuf_count)); - ++finfo->symbuf_count; - - ++finfo->output_bfd->symcount; - - return true; -} - -/* Flush the output symbols to the file. */ - -static boolean -elf_link_flush_output_syms (finfo) - struct elf_final_link_info *finfo; -{ - if (finfo->symbuf_count > 0) - { - Elf_Internal_Shdr *symtab; - - symtab = &elf_tdata (finfo->output_bfd)->symtab_hdr; - - if (bfd_seek (finfo->output_bfd, symtab->sh_offset + symtab->sh_size, - SEEK_SET) != 0 - || (bfd_write ((PTR) finfo->symbuf, finfo->symbuf_count, - sizeof (Elf_External_Sym), finfo->output_bfd) - != finfo->symbuf_count * sizeof (Elf_External_Sym))) - return false; - - symtab->sh_size += finfo->symbuf_count * sizeof (Elf_External_Sym); - - finfo->symbuf_count = 0; - } - - return true; -} - -/* Add an external symbol to the symbol table. This is called from - the hash table traversal routine. */ - -static boolean -elf_link_output_extsym (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct elf_finfo_failed *eif = (struct elf_finfo_failed *) data; - struct elf_final_link_info *finfo = eif->finfo; - boolean strip; - Elf_Internal_Sym sym; - asection *input_sec; - - /* If we are not creating a shared library, and this symbol is - referenced by a shared library but is not defined anywhere, then - warn that it is undefined. If we do not do this, the runtime - linker will complain that the symbol is undefined when the - program is run. We don't have to worry about symbols that are - referenced by regular files, because we will already have issued - warnings for them. */ - if (! finfo->info->relocateable - && ! finfo->info->shared - && h->root.type == bfd_link_hash_undefined - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - { - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, h->root.root.string, h->root.u.undef.abfd, - (asection *) NULL, 0))) - { - eif->failed = true; - return false; - } - } - - /* We don't want to output symbols that have never been mentioned by - a regular file, or that we have been told to strip. However, if - h->indx is set to -2, the symbol is used by a reloc and we must - output it. */ - if (h->indx == -2) - strip = false; - else if (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - strip = true; - else if (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, - false, false) == NULL)) - strip = true; - else - strip = false; - - /* If we're stripping it, and it's not a dynamic symbol, there's - nothing else to do. */ - if (strip && h->dynindx == -1) - return true; - - sym.st_value = 0; - sym.st_size = h->size; - sym.st_other = 0; - if (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_defweak) - sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); - else - sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - return false; - - case bfd_link_hash_undefined: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_undefweak: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - input_sec = h->root.u.def.section; - if (input_sec->output_section != NULL) - { - sym.st_shndx = - _bfd_elf_section_from_bfd_section (finfo->output_bfd, - input_sec->output_section); - if (sym.st_shndx == (unsigned short) -1) - { - eif->failed = true; - return false; - } - - /* ELF symbols in relocateable files are section relative, - but in nonrelocateable files they are virtual - addresses. */ - sym.st_value = h->root.u.def.value + input_sec->output_offset; - if (! finfo->info->relocateable) - sym.st_value += input_sec->output_section->vma; - } - else - { - BFD_ASSERT ((bfd_get_flavour (input_sec->owner) - == bfd_target_elf_flavour) - && elf_elfheader (input_sec->owner)->e_type == ET_DYN); - sym.st_shndx = SHN_UNDEF; - input_sec = bfd_und_section_ptr; - } - } - break; - - case bfd_link_hash_common: - input_sec = bfd_com_section_ptr; - sym.st_shndx = SHN_COMMON; - sym.st_value = 1 << h->root.u.c.p->alignment_power; - break; - - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* We can't represent these symbols in ELF. A warning symbol - may have come from a .gnu.warning.SYMBOL section anyhow. We - just put the target symbol in the hash table. If the target - symbol does not really exist, don't do anything. */ - if (h->root.u.i.link->type == bfd_link_hash_new) - return true; - return (elf_link_output_extsym - ((struct elf_link_hash_entry *) h->root.u.i.link, data)); - } - - /* If this symbol should be put in the .dynsym section, then put it - there now. We have already know the symbol index. We also fill - in the entry in the .hash section. */ - if (h->dynindx != -1 - && elf_hash_table (finfo->info)->dynamic_sections_created) - { - struct elf_backend_data *bed; - size_t bucketcount; - size_t bucket; - bfd_byte *bucketpos; - bfd_vma chain; - - sym.st_name = h->dynstr_index; - - /* Give the processor backend a chance to tweak the symbol - value, and also to finish up anything that needs to be done - for this symbol. */ - bed = get_elf_backend_data (finfo->output_bfd); - if (! ((*bed->elf_backend_finish_dynamic_symbol) - (finfo->output_bfd, finfo->info, h, &sym))) - { - eif->failed = true; - return false; - } - - elf_swap_symbol_out (finfo->output_bfd, &sym, - (PTR) (((Elf_External_Sym *) - finfo->dynsym_sec->contents) - + h->dynindx)); - - bucketcount = elf_hash_table (finfo->info)->bucketcount; - bucket = (bfd_elf_hash ((const unsigned char *) h->root.root.string) - % bucketcount); - bucketpos = ((bfd_byte *) finfo->hash_sec->contents - + (bucket + 2) * (ARCH_SIZE / 8)); - chain = get_word (finfo->output_bfd, bucketpos); - put_word (finfo->output_bfd, h->dynindx, bucketpos); - put_word (finfo->output_bfd, chain, - ((bfd_byte *) finfo->hash_sec->contents - + (bucketcount + 2 + h->dynindx) * (ARCH_SIZE / 8))); - } - - /* If we're stripping it, then it was just a dynamic symbol, and - there's nothing else to do. */ - if (strip) - return true; - - h->indx = finfo->output_bfd->symcount; - - if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec)) - { - eif->failed = true; - return false; - } - - return true; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. - This is so that we only have to read the local symbols once, and - don't have to keep them in memory. */ - -static boolean -elf_link_input_bfd (finfo, input_bfd) - struct elf_final_link_info *finfo; - bfd *input_bfd; -{ - boolean (*relocate_section) PARAMS ((bfd *, struct bfd_link_info *, - bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, - Elf_Internal_Sym *, asection **)); - bfd *output_bfd; - Elf_Internal_Shdr *symtab_hdr; - size_t locsymcount; - size_t extsymoff; - Elf_External_Sym *esym; - Elf_External_Sym *esymend; - Elf_Internal_Sym *isym; - long *pindex; - asection **ppsection; - asection *o; - - output_bfd = finfo->output_bfd; - relocate_section = - get_elf_backend_data (output_bfd)->elf_backend_relocate_section; - - /* If this is a dynamic object, we don't want to do anything here: - we don't want the local symbols, and we don't want the section - contents. */ - if (elf_elfheader (input_bfd)->e_type == ET_DYN) - return true; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (elf_bad_symtab (input_bfd)) - { - locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym); - extsymoff = 0; - } - else - { - locsymcount = symtab_hdr->sh_info; - extsymoff = symtab_hdr->sh_info; - } - - /* Read the local symbols. */ - if (locsymcount > 0 - && (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_read (finfo->external_syms, sizeof (Elf_External_Sym), - locsymcount, input_bfd) - != locsymcount * sizeof (Elf_External_Sym)))) - return false; - - /* Swap in the local symbols and write out the ones which we know - are going into the output file. */ - esym = finfo->external_syms; - esymend = esym + locsymcount; - isym = finfo->internal_syms; - pindex = finfo->indices; - ppsection = finfo->sections; - for (; esym < esymend; esym++, isym++, pindex++, ppsection++) - { - asection *isec; - const char *name; - Elf_Internal_Sym osym; - - elf_swap_symbol_in (input_bfd, esym, isym); - *pindex = -1; - - if (elf_bad_symtab (input_bfd)) - { - if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) - { - *ppsection = NULL; - continue; - } - } - - if (isym->st_shndx == SHN_UNDEF) - isec = bfd_und_section_ptr; - else if (isym->st_shndx > 0 && isym->st_shndx < SHN_LORESERVE) - isec = section_from_elf_index (input_bfd, isym->st_shndx); - else if (isym->st_shndx == SHN_ABS) - isec = bfd_abs_section_ptr; - else if (isym->st_shndx == SHN_COMMON) - isec = bfd_com_section_ptr; - else - { - /* Who knows? */ - isec = NULL; - } - - *ppsection = isec; - - /* Don't output the first, undefined, symbol. */ - if (esym == finfo->external_syms) - continue; - - /* If we are stripping all symbols, we don't want to output this - one. */ - if (finfo->info->strip == strip_all) - continue; - - /* We never output section symbols. Instead, we use the section - symbol of the corresponding section in the output file. */ - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - continue; - - /* If we are discarding all local symbols, we don't want to - output this one. If we are generating a relocateable output - file, then some of the local symbols may be required by - relocs; we output them below as we discover that they are - needed. */ - if (finfo->info->discard == discard_all) - continue; - - /* Get the name of the symbol. */ - name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, - isym->st_name); - if (name == NULL) - return false; - - /* See if we are discarding symbols with this name. */ - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, false, false) - == NULL)) - || (finfo->info->discard == discard_l - && strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - continue; - - /* If we get here, we are going to output this symbol. */ - - osym = *isym; - - /* Adjust the section index for the output file. */ - osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, - isec->output_section); - if (osym.st_shndx == (unsigned short) -1) - return false; - - *pindex = output_bfd->symcount; - - /* ELF symbols in relocateable files are section relative, but - in executable files they are virtual addresses. Note that - this code assumes that all ELF sections have an associated - BFD section with a reasonable value for output_offset; below - we assume that they also have a reasonable value for - output_section. Any special sections must be set up to meet - these requirements. */ - osym.st_value += isec->output_offset; - if (! finfo->info->relocateable) - osym.st_value += isec->output_section->vma; - - if (! elf_link_output_sym (finfo, name, &osym, isec)) - return false; - } - - /* Relocate the contents of each section. */ - for (o = input_bfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) == 0) - continue; - - if ((o->flags & SEC_IN_MEMORY) != 0 - && input_bfd == elf_hash_table (finfo->info)->dynobj) - { - /* Section was created by elf_link_create_dynamic_sections. - FIXME: This test is fragile. */ - continue; - } - - /* Read the contents of the section. */ - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; - - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Rela *internal_relocs; - - /* Get the swapped relocs. */ - internal_relocs = elf_link_read_relocs (input_bfd, o, - finfo->external_relocs, - finfo->internal_relocs, - false); - if (internal_relocs == NULL - && o->reloc_count > 0) - return false; - - /* Relocate the section by invoking a back end routine. - - The back end routine is responsible for adjusting the - section contents as necessary, and (if using Rela relocs - and generating a relocateable output file) adjusting the - reloc addend as necessary. - - The back end routine does not have to worry about setting - the reloc address or the reloc symbol index. - - The back end routine is given a pointer to the swapped in - internal symbols, and can access the hash table entries - for the external symbols via elf_sym_hashes (input_bfd). - - When generating relocateable output, the back end routine - must handle STB_LOCAL/STT_SECTION symbols specially. The - output symbol is going to be a section symbol - corresponding to the output section, which will require - the addend to be adjusted. */ - - if (! (*relocate_section) (output_bfd, finfo->info, - input_bfd, o, - finfo->contents, - internal_relocs, - finfo->internal_syms, - finfo->sections)) - return false; - - if (finfo->info->relocateable) - { - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend; - struct elf_link_hash_entry **rel_hash; - Elf_Internal_Shdr *input_rel_hdr; - Elf_Internal_Shdr *output_rel_hdr; - - /* Adjust the reloc addresses and symbol indices. */ - - irela = internal_relocs; - irelaend = irela + o->reloc_count; - rel_hash = (elf_section_data (o->output_section)->rel_hashes - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, rel_hash++) - { - unsigned long r_symndx; - Elf_Internal_Sym *isym; - asection *sec; - - irela->r_offset += o->output_offset; - - r_symndx = ELF_R_SYM (irela->r_info); - - if (r_symndx == 0) - continue; - - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[r_symndx] == NULL)) - { - long indx; - - /* This is a reloc against a global symbol. We - have not yet output all the local symbols, so - we do not know the symbol index of any global - symbol. We set the rel_hash entry for this - reloc to point to the global hash table entry - for this symbol. The symbol index is then - set at the end of elf_bfd_final_link. */ - indx = r_symndx - extsymoff; - *rel_hash = elf_sym_hashes (input_bfd)[indx]; - - /* Setting the index to -2 tells - elf_link_output_extsym that this symbol is - used by a reloc. */ - BFD_ASSERT ((*rel_hash)->indx < 0); - (*rel_hash)->indx = -2; - - continue; - } - - /* This is a reloc against a local symbol. */ - - *rel_hash = NULL; - isym = finfo->internal_syms + r_symndx; - sec = finfo->sections[r_symndx]; - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - { - /* I suppose the backend ought to fill in the - section of any STT_SECTION symbol against a - processor specific section. */ - if (sec != NULL && bfd_is_abs_section (sec)) - r_symndx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - r_symndx = sec->output_section->target_index; - BFD_ASSERT (r_symndx != 0); - } - } - else - { - if (finfo->indices[r_symndx] == -1) - { - unsigned long link; - const char *name; - asection *osec; - - if (finfo->info->strip == strip_all) - { - /* You can't do ld -r -s. */ - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* This symbol was skipped earlier, but - since it is needed by a reloc, we - must output it now. */ - link = symtab_hdr->sh_link; - name = bfd_elf_string_from_elf_section (input_bfd, - link, - isym->st_name); - if (name == NULL) - return false; - - osec = sec->output_section; - isym->st_shndx = - _bfd_elf_section_from_bfd_section (output_bfd, - osec); - if (isym->st_shndx == (unsigned short) -1) - return false; - - isym->st_value += sec->output_offset; - if (! finfo->info->relocateable) - isym->st_value += osec->vma; - - finfo->indices[r_symndx] = output_bfd->symcount; - - if (! elf_link_output_sym (finfo, name, isym, sec)) - return false; - } - - r_symndx = finfo->indices[r_symndx]; - } - - irela->r_info = ELF_R_INFO (r_symndx, - ELF_R_TYPE (irela->r_info)); - } - - /* Swap out the relocs. */ - input_rel_hdr = &elf_section_data (o)->rel_hdr; - output_rel_hdr = &elf_section_data (o->output_section)->rel_hdr; - BFD_ASSERT (output_rel_hdr->sh_entsize - == input_rel_hdr->sh_entsize); - irela = internal_relocs; - irelaend = irela + o->reloc_count; - if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - - erel = ((Elf_External_Rel *) output_rel_hdr->contents - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, erel++) - { - Elf_Internal_Rel irel; - - irel.r_offset = irela->r_offset; - irel.r_info = irela->r_info; - BFD_ASSERT (irela->r_addend == 0); - elf_swap_reloc_out (output_bfd, &irel, erel); - } - } - else - { - Elf_External_Rela *erela; - - BFD_ASSERT (input_rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - erela = ((Elf_External_Rela *) output_rel_hdr->contents - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, erela++) - elf_swap_reloca_out (output_bfd, irela, erela); - } - - o->output_section->reloc_count += o->reloc_count; - } - } - - /* Write out the modified section contents. */ - if (! bfd_set_section_contents (output_bfd, o->output_section, - finfo->contents, o->output_offset, - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) - return false; - } - - return true; -} - -/* Generate a reloc when linking an ELF file. This is a reloc - requested by the linker, and does come from any input file. This - is used to build constructor and destructor tables when linking - with -Ur. */ - -static boolean -elf_reloc_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - reloc_howto_type *howto; - long indx; - bfd_vma offset; - bfd_vma addend; - struct elf_link_hash_entry **rel_hash_ptr; - Elf_Internal_Shdr *rel_hdr; - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - addend = link_order->u.reloc.p->addend; - - /* Figure out the symbol index. */ - rel_hash_ptr = (elf_section_data (output_section)->rel_hashes - + output_section->reloc_count); - if (link_order->type == bfd_section_reloc_link_order) - { - indx = link_order->u.reloc.p->u.section->target_index; - BFD_ASSERT (indx != 0); - *rel_hash_ptr = NULL; - } - else - { - struct elf_link_hash_entry *h; - - /* Treat a reloc against a defined symbol as though it were - actually against the section. */ - h = ((struct elf_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - asection *section; - - section = h->root.u.def.section; - indx = section->output_section->target_index; - *rel_hash_ptr = NULL; - /* It seems that we ought to add the symbol value to the - addend here, but in practice it has already been added - because it was passed to constructor_callback. */ - addend += section->output_section->vma + section->output_offset; - } - else if (h != NULL) - { - /* Setting the index to -2 tells elf_link_output_extsym that - this symbol is used by a reloc. */ - h->indx = -2; - *rel_hash_ptr = h; - indx = 0; - } - else - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - indx = 0; - } - } - - /* If this is an inplace reloc, we must write the addend into the - object file. */ - if (howto->partial_inplace && addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - return false; - rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - howto->name, addend, (bfd *) NULL, (asection *) NULL, - (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - /* The address of a reloc is relative to the section in a - relocateable file, and is a virtual address in an executable - file. */ - offset = link_order->offset; - if (! info->relocateable) - offset += output_section->vma; - - rel_hdr = &elf_section_data (output_section)->rel_hdr; - - if (rel_hdr->sh_type == SHT_REL) - { - Elf_Internal_Rel irel; - Elf_External_Rel *erel; - - irel.r_offset = offset; - irel.r_info = ELF_R_INFO (indx, howto->type); - erel = ((Elf_External_Rel *) rel_hdr->contents - + output_section->reloc_count); - elf_swap_reloc_out (output_bfd, &irel, erel); - } - else - { - Elf_Internal_Rela irela; - Elf_External_Rela *erela; - - irela.r_offset = offset; - irela.r_info = ELF_R_INFO (indx, howto->type); - irela.r_addend = addend; - erela = ((Elf_External_Rela *) rel_hdr->contents - + output_section->reloc_count); - elf_swap_reloca_out (output_bfd, &irela, erela); - } - - ++output_section->reloc_count; - - return true; -} - - -/* Allocate a pointer to live in a linker created section. */ - -boolean -elf_create_pointer_linker_section (abfd, info, lsect, h, rel) - bfd *abfd; - struct bfd_link_info *info; - elf_linker_section_t *lsect; - struct elf_link_hash_entry *h; - const Elf_Internal_Rela *rel; -{ - elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL; - elf_linker_section_pointers_t *linker_section_ptr; - unsigned long r_symndx = ELF_R_SYM (rel->r_info);; - - BFD_ASSERT (lsect != NULL); - - /* Is this a global symbol? */ - if (h != NULL) - { - /* Has this symbol already been allocated, if so, our work is done */ - if (_bfd_elf_find_pointer_linker_section (h->linker_section_pointer, - rel->r_addend, - lsect->which)) - return true; - - ptr_linker_section_ptr = &h->linker_section_pointer; - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! elf_link_record_dynamic_symbol (info, h)) - return false; - } - - if (lsect->rel_section) - lsect->rel_section->_raw_size += sizeof (Elf_External_Rela); - } - - else /* Allocation of a pointer to a local symbol */ - { - elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd); - - /* Allocate a table to hold the local symbols if first time */ - if (!ptr) - { - int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info; - register unsigned int i; - - ptr = (elf_linker_section_pointers_t **) - bfd_alloc (abfd, num_symbols * sizeof (elf_linker_section_pointers_t *)); - - if (!ptr) - return false; - - elf_local_ptr_offsets (abfd) = ptr; - for (i = 0; i < num_symbols; i++) - ptr[i] = (elf_linker_section_pointers_t *)0; - } - - /* Has this symbol already been allocated, if so, our work is done */ - if (_bfd_elf_find_pointer_linker_section (ptr[r_symndx], - rel->r_addend, - lsect->which)) - return true; - - ptr_linker_section_ptr = &ptr[r_symndx]; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R__RELATIVE reloc so that the - dynamic linker can adjust this GOT entry. */ - BFD_ASSERT (lsect->rel_section != NULL); - lsect->rel_section->_raw_size += sizeof (Elf_External_Rela); - } - } - - /* Allocate space for a pointer in the linker section, and allocate a new pointer record - from internal memory. */ - BFD_ASSERT (ptr_linker_section_ptr != NULL); - linker_section_ptr = (elf_linker_section_pointers_t *) - bfd_alloc (abfd, sizeof (elf_linker_section_pointers_t)); - - if (!linker_section_ptr) - return false; - - linker_section_ptr->next = *ptr_linker_section_ptr; - linker_section_ptr->addend = rel->r_addend; - linker_section_ptr->which = lsect->which; - linker_section_ptr->written_address_p = false; - *ptr_linker_section_ptr = linker_section_ptr; - - if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset) - { - linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size; - lsect->hole_offset += ARCH_SIZE / 8; - lsect->sym_offset += ARCH_SIZE / 8; - if (lsect->sym_hash) /* Bump up symbol value if needed */ - lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8; - } - else - linker_section_ptr->offset = lsect->section->_raw_size; - - lsect->section->_raw_size += ARCH_SIZE / 8; - -#ifdef DEBUG - fprintf (stderr, "Create pointer in linker section %s, offset = %ld, section size = %ld\n", - lsect->name, (long)linker_section_ptr->offset, (long)lsect->section->_raw_size); -#endif - - return true; -} - - -#if ARCH_SIZE==64 -#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_64 (BFD, VAL, ADDR) -#endif -#if ARCH_SIZE==32 -#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_32 (BFD, VAL, ADDR) -#endif - -/* Fill in the address for a pointer generated in alinker section. */ - -bfd_vma -elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, relocation, rel, relative_reloc) - bfd *output_bfd; - bfd *input_bfd; - struct bfd_link_info *info; - elf_linker_section_t *lsect; - struct elf_link_hash_entry *h; - bfd_vma relocation; - const Elf_Internal_Rela *rel; - int relative_reloc; -{ - elf_linker_section_pointers_t *linker_section_ptr; - - BFD_ASSERT (lsect != NULL); - - if (h != NULL) /* global symbol */ - { - linker_section_ptr = _bfd_elf_find_pointer_linker_section (h->linker_section_pointer, - rel->r_addend, - lsect->which); - - BFD_ASSERT (linker_section_ptr != NULL); - - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global section. - - When doing a dynamic link, we create a .rela. - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if (!linker_section_ptr->written_address_p) - { - linker_section_ptr->written_address_p = true; - bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend, - lsect->section->contents + linker_section_ptr->offset); - } - } - } - else /* local symbol */ - { - unsigned long r_symndx = ELF_R_SYM (rel->r_info); - BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL); - BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL); - linker_section_ptr = _bfd_elf_find_pointer_linker_section (elf_local_ptr_offsets (input_bfd)[r_symndx], - rel->r_addend, - lsect->which); - - BFD_ASSERT (linker_section_ptr != NULL); - - /* Write out pointer if it hasn't been rewritten out before */ - if (!linker_section_ptr->written_address_p) - { - linker_section_ptr->written_address_p = true; - bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend, - lsect->section->contents + linker_section_ptr->offset); - - if (info->shared) - { - asection *srel = lsect->rel_section; - Elf_Internal_Rela outrel; - - /* We need to generate a relative reloc for the dynamic linker. */ - if (!srel) - lsect->rel_section = srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj, - lsect->rel_name); - - BFD_ASSERT (srel != NULL); - - outrel.r_offset = (lsect->section->output_section->vma - + lsect->section->output_offset - + linker_section_ptr->offset); - outrel.r_info = ELF_R_INFO (0, relative_reloc); - outrel.r_addend = 0; - elf_swap_reloca_out (output_bfd, &outrel, - (((Elf_External_Rela *) - lsect->section->contents) - + lsect->section->reloc_count)); - ++lsect->section->reloc_count; - } - } - } - - relocation = (lsect->section->output_offset - + linker_section_ptr->offset - - lsect->hole_offset - - lsect->sym_offset); - -#ifdef DEBUG - fprintf (stderr, "Finish pointer in linker section %s, offset = %ld (0x%lx)\n", - lsect->name, (long)relocation, (long)relocation); -#endif - - /* Subtract out the addend, because it will get added back in by the normal - processing. */ - return relocation - linker_section_ptr->addend; -} diff --git a/contrib/gdb/bfd/elfxx-target.h b/contrib/gdb/bfd/elfxx-target.h deleted file mode 100644 index f2c0c32cf62..00000000000 --- a/contrib/gdb/bfd/elfxx-target.h +++ /dev/null @@ -1,450 +0,0 @@ -/* Target definitions for NN-bit ELF - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This structure contains everything that BFD knows about a target. - It includes things like its byte order, name, what routines to call - to do various operations, etc. Every BFD points to a target structure - with its "xvec" member. - - There are two such structures here: one for big-endian machines and - one for little-endian machines. */ - -#define bfd_elfNN_close_and_cleanup _bfd_generic_close_and_cleanup -#define bfd_elfNN_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#ifndef bfd_elfNN_get_section_contents -#define bfd_elfNN_get_section_contents _bfd_generic_get_section_contents -#endif - -#define bfd_elfNN_canonicalize_dynamic_symtab _bfd_elf_canonicalize_dynamic_symtab -#define bfd_elfNN_canonicalize_reloc _bfd_elf_canonicalize_reloc -#ifndef bfd_elfNN_find_nearest_line -#define bfd_elfNN_find_nearest_line _bfd_elf_find_nearest_line -#endif -#define bfd_elfNN_read_minisymbols _bfd_elf_read_minisymbols -#define bfd_elfNN_minisymbol_to_symbol _bfd_elf_minisymbol_to_symbol -#define bfd_elfNN_get_dynamic_symtab_upper_bound _bfd_elf_get_dynamic_symtab_upper_bound -#define bfd_elfNN_get_lineno _bfd_elf_get_lineno -#define bfd_elfNN_get_reloc_upper_bound _bfd_elf_get_reloc_upper_bound -#define bfd_elfNN_get_symbol_info _bfd_elf_get_symbol_info -#define bfd_elfNN_get_symtab _bfd_elf_get_symtab -#define bfd_elfNN_get_symtab_upper_bound _bfd_elf_get_symtab_upper_bound -#if 0 /* done in elf-bfd.h */ -#define bfd_elfNN_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol -#endif -#define bfd_elfNN_make_empty_symbol _bfd_elf_make_empty_symbol -#define bfd_elfNN_new_section_hook _bfd_elf_new_section_hook -#define bfd_elfNN_set_arch_mach _bfd_elf_set_arch_mach -#ifndef bfd_elfNN_set_section_contents -#define bfd_elfNN_set_section_contents _bfd_elf_set_section_contents -#endif -#define bfd_elfNN_sizeof_headers _bfd_elf_sizeof_headers -#define bfd_elfNN_write_object_contents _bfd_elf_write_object_contents - -#define bfd_elfNN_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#ifndef elf_backend_want_got_plt -#define elf_backend_want_got_plt 0 -#endif -#ifndef elf_backend_plt_readonly -#define elf_backend_plt_readonly 0 -#endif -#ifndef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 0 -#endif - -#define bfd_elfNN_bfd_debug_info_start bfd_void -#define bfd_elfNN_bfd_debug_info_end bfd_void -#define bfd_elfNN_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void - -#ifndef bfd_elfNN_bfd_get_relocated_section_contents -#define bfd_elfNN_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#endif - -#define bfd_elfNN_bfd_relax_section bfd_generic_relax_section -#define bfd_elfNN_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) - -#ifndef bfd_elfNN_bfd_copy_private_symbol_data -#define bfd_elfNN_bfd_copy_private_symbol_data \ - _bfd_elf_copy_private_symbol_data -#endif - -#ifndef bfd_elfNN_bfd_copy_private_section_data -#define bfd_elfNN_bfd_copy_private_section_data \ - _bfd_elf_copy_private_section_data -#endif -#ifndef bfd_elfNN_bfd_copy_private_bfd_data -#define bfd_elfNN_bfd_copy_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_print_private_bfd_data -#define bfd_elfNN_bfd_print_private_bfd_data \ - _bfd_elf_print_private_bfd_data -#endif -#ifndef bfd_elfNN_bfd_merge_private_bfd_data -#define bfd_elfNN_bfd_merge_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_set_private_flags -#define bfd_elfNN_bfd_set_private_flags \ - ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_is_local_label -#define bfd_elfNN_bfd_is_local_label bfd_generic_is_local_label -#endif - -#ifndef bfd_elfNN_get_dynamic_reloc_upper_bound -#define bfd_elfNN_get_dynamic_reloc_upper_bound \ - _bfd_nodynamic_get_dynamic_reloc_upper_bound -#endif -#ifndef bfd_elfNN_canonicalize_dynamic_reloc -#define bfd_elfNN_canonicalize_dynamic_reloc \ - _bfd_nodynamic_canonicalize_dynamic_reloc -#endif - -#ifdef elf_backend_relocate_section -#ifndef bfd_elfNN_bfd_link_hash_table_create -#define bfd_elfNN_bfd_link_hash_table_create _bfd_elf_link_hash_table_create -#endif -#else /* ! defined (elf_backend_relocate_section) */ -/* If no backend relocate_section routine, use the generic linker. */ -#ifndef bfd_elfNN_bfd_link_hash_table_create -#define bfd_elfNN_bfd_link_hash_table_create \ - _bfd_generic_link_hash_table_create -#endif -#ifndef bfd_elfNN_bfd_link_add_symbols -#define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols -#endif -#ifndef bfd_elfNN_bfd_final_link -#define bfd_elfNN_bfd_final_link _bfd_generic_final_link -#endif -#endif /* ! defined (elf_backend_relocate_section) */ -#ifndef bfd_elfNN_bfd_link_split_section -#define bfd_elfNN_bfd_link_split_section _bfd_generic_link_split_section -#endif - -#ifndef elf_symbol_leading_char -#define elf_symbol_leading_char 0 -#endif - -#ifndef elf_info_to_howto_rel -#define elf_info_to_howto_rel 0 -#endif - -#ifndef ELF_MAXPAGESIZE -#define ELF_MAXPAGESIZE 1 -#endif - -#ifndef elf_backend_collect -#define elf_backend_collect false -#endif -#ifndef elf_backend_type_change_ok -#define elf_backend_type_change_ok false -#endif - -#ifndef elf_backend_sym_is_global -#define elf_backend_sym_is_global 0 -#endif -#ifndef elf_backend_object_p -#define elf_backend_object_p 0 -#endif -#ifndef elf_backend_symbol_processing -#define elf_backend_symbol_processing 0 -#endif -#ifndef elf_backend_symbol_table_processing -#define elf_backend_symbol_table_processing 0 -#endif -#ifndef elf_backend_section_processing -#define elf_backend_section_processing 0 -#endif -#ifndef elf_backend_section_from_shdr -#define elf_backend_section_from_shdr 0 -#endif -#ifndef elf_backend_fake_sections -#define elf_backend_fake_sections 0 -#endif -#ifndef elf_backend_section_from_bfd_section -#define elf_backend_section_from_bfd_section 0 -#endif -#ifndef elf_backend_add_symbol_hook -#define elf_backend_add_symbol_hook 0 -#endif -#ifndef elf_backend_link_output_symbol_hook -#define elf_backend_link_output_symbol_hook 0 -#endif -#ifndef elf_backend_create_dynamic_sections -#define elf_backend_create_dynamic_sections 0 -#endif -#ifndef elf_backend_check_relocs -#define elf_backend_check_relocs 0 -#endif -#ifndef elf_backend_adjust_dynamic_symbol -#define elf_backend_adjust_dynamic_symbol 0 -#endif -#ifndef elf_backend_size_dynamic_sections -#define elf_backend_size_dynamic_sections 0 -#endif -#ifndef elf_backend_relocate_section -#define elf_backend_relocate_section 0 -#endif -#ifndef elf_backend_finish_dynamic_symbol -#define elf_backend_finish_dynamic_symbol 0 -#endif -#ifndef elf_backend_finish_dynamic_sections -#define elf_backend_finish_dynamic_sections 0 -#endif -#ifndef elf_backend_begin_write_processing -#define elf_backend_begin_write_processing 0 -#endif -#ifndef elf_backend_final_write_processing -#define elf_backend_final_write_processing 0 -#endif -#ifndef elf_backend_additional_program_headers -#define elf_backend_additional_program_headers 0 -#endif -#ifndef elf_backend_modify_segment_map -#define elf_backend_modify_segment_map 0 -#endif -#ifndef elf_backend_ecoff_debug_swap -#define elf_backend_ecoff_debug_swap 0 -#endif - -#ifndef ELF_MACHINE_ALT1 -#define ELF_MACHINE_ALT1 0 -#endif - -#ifndef ELF_MACHINE_ALT2 -#define ELF_MACHINE_ALT2 0 -#endif - -extern const struct elf_size_info _bfd_elfNN_size_info; - -static CONST struct elf_backend_data elfNN_bed = -{ -#ifdef USE_REL - 0, /* use_rela_p */ -#else - 1, /* use_rela_p */ -#endif - ELF_ARCH, /* arch */ - ELF_MACHINE_CODE, /* elf_machine_code */ - ELF_MAXPAGESIZE, /* maxpagesize */ - elf_backend_collect, - elf_backend_type_change_ok, - elf_info_to_howto, - elf_info_to_howto_rel, - elf_backend_sym_is_global, - elf_backend_object_p, - elf_backend_symbol_processing, - elf_backend_symbol_table_processing, - elf_backend_section_processing, - elf_backend_section_from_shdr, - elf_backend_fake_sections, - elf_backend_section_from_bfd_section, - elf_backend_add_symbol_hook, - elf_backend_link_output_symbol_hook, - elf_backend_create_dynamic_sections, - elf_backend_check_relocs, - elf_backend_adjust_dynamic_symbol, - elf_backend_size_dynamic_sections, - elf_backend_relocate_section, - elf_backend_finish_dynamic_symbol, - elf_backend_finish_dynamic_sections, - elf_backend_begin_write_processing, - elf_backend_final_write_processing, - elf_backend_additional_program_headers, - elf_backend_modify_segment_map, - elf_backend_ecoff_debug_swap, - ELF_MACHINE_ALT1, - ELF_MACHINE_ALT2, - &_bfd_elfNN_size_info, - elf_backend_want_got_plt, - elf_backend_plt_readonly, - elf_backend_want_plt_sym -}; - -#ifdef TARGET_BIG_SYM -const bfd_target TARGET_BIG_SYM = -{ - /* name: identify kind of target */ - TARGET_BIG_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder: data is big endian */ - BFD_ENDIAN_BIG, - - /* header_byteorder: header is also big endian */ - BFD_ENDIAN_BIG, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | - DYNAMIC | WP_TEXT | D_PAGED), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - elf_symbol_leading_char, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 14, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - bfd_elfNN_object_p, /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - bfd_elfNN_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - bfd_elf_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elfNN_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elfNN), - BFD_JUMP_TABLE_COPY (bfd_elfNN), - BFD_JUMP_TABLE_CORE (bfd_elfNN), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN), - BFD_JUMP_TABLE_RELOCS (bfd_elfNN), - BFD_JUMP_TABLE_WRITE (bfd_elfNN), - BFD_JUMP_TABLE_LINK (bfd_elfNN), - BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN), - - /* backend_data: */ - (PTR) &elfNN_bed, -}; -#endif - -#ifdef TARGET_LITTLE_SYM -const bfd_target TARGET_LITTLE_SYM = -{ - /* name: identify kind of target */ - TARGET_LITTLE_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder: data is little endian */ - BFD_ENDIAN_LITTLE, - - /* header_byteorder: header is also little endian */ - BFD_ENDIAN_LITTLE, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | - DYNAMIC | WP_TEXT | D_PAGED), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - elf_symbol_leading_char, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 14, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - bfd_elfNN_object_p, /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - bfd_elfNN_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - bfd_elf_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elfNN_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elfNN), - BFD_JUMP_TABLE_COPY (bfd_elfNN), - BFD_JUMP_TABLE_CORE (bfd_elfNN), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN), - BFD_JUMP_TABLE_RELOCS (bfd_elfNN), - BFD_JUMP_TABLE_WRITE (bfd_elfNN), - BFD_JUMP_TABLE_LINK (bfd_elfNN), - BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN), - - /* backend_data: */ - (PTR) &elfNN_bed, -}; -#endif diff --git a/contrib/gdb/bfd/filemode.c b/contrib/gdb/bfd/filemode.c deleted file mode 100644 index fd790b36786..00000000000 --- a/contrib/gdb/bfd/filemode.c +++ /dev/null @@ -1,193 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright (C) 1985, 1990 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include -#include - -void mode_string (); -static char ftypelet (); -static void rwx (); -static void setst (); - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -void -filemodestring (statp, str) - struct stat *statp; - char *str; -{ - mode_string (statp->st_mode, str); -} - -/* Like filemodestring, but only the relevant part of the `struct stat' - is given as an argument. */ - -void -mode_string (mode, str) - unsigned short mode; - char *str; -{ - str[0] = ftypelet (mode); - rwx ((mode & 0700) << 0, &str[1]); - rwx ((mode & 0070) << 3, &str[4]); - rwx ((mode & 0007) << 6, &str[7]); - setst (mode, str); -} - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexor files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for any other file type. */ - -static char -ftypelet (bits) - unsigned short bits; -{ - switch (bits & S_IFMT) - { - default: - return '-'; - case S_IFDIR: - return 'd'; -#ifdef S_IFLNK - case S_IFLNK: - return 'l'; -#endif -#ifdef S_IFCHR - case S_IFCHR: - return 'c'; -#endif -#ifdef S_IFBLK - case S_IFBLK: - return 'b'; -#endif -#ifdef S_IFMPC - case S_IFMPC: - case S_IFMPB: - return 'm'; -#endif -#ifdef S_IFSOCK - case S_IFSOCK: - return 's'; -#endif -#ifdef S_IFIFO -#if S_IFIFO != S_IFSOCK - case S_IFIFO: - return 'p'; -#endif -#endif -#ifdef S_IFNWK /* HP-UX */ - case S_IFNWK: - return 'n'; -#endif - } -} - -/* Look at read, write, and execute bits in BITS and set - flags in CHARS accordingly. */ - -static void -rwx (bits, chars) - unsigned short bits; - char *chars; -{ - chars[0] = (bits & S_IREAD) ? 'r' : '-'; - chars[1] = (bits & S_IWRITE) ? 'w' : '-'; - chars[2] = (bits & S_IEXEC) ? 'x' : '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (bits, chars) - unsigned short bits; - char *chars; -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} - - diff --git a/contrib/gdb/bfd/format.c b/contrib/gdb/bfd/format.c deleted file mode 100644 index 7a303424df6..00000000000 --- a/contrib/gdb/bfd/format.c +++ /dev/null @@ -1,319 +0,0 @@ -/* Generic BFD support for file formats. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - File formats - - A format is a BFD concept of high level file contents type. The - formats supported by BFD are: - - o <> - - The BFD may contain data, symbols, relocations and debug info. - - o <> - - The BFD contains other BFDs and an optional index. - - o <> - - The BFD contains the result of an executable core dump. - - -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* IMPORT from targets.c. */ -extern const size_t _bfd_target_vector_entries; - -/* -FUNCTION - bfd_check_format - -SYNOPSIS - boolean bfd_check_format(bfd *abfd, bfd_format format); - -DESCRIPTION - Verify if the file attached to the BFD @var{abfd} is compatible - with the format @var{format} (i.e., one of <>, - <> or <>). - - 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 - <>, 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. - - The function returns <> on success, otherwise <> - with one of the following error codes: - - o <> - - if <> is not one of <>, <> or - <>. - - o <> - - if an error occured during a read - even some file mismatches - can cause bfd_error_system_calls. - - o <> - - none of the backends recognised the file format. - - o <> - - more than one backend recognised the file format. -*/ - -boolean -bfd_check_format (abfd, format) - bfd *abfd; - bfd_format format; -{ - 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 <>, except when it returns false with - <> set to <>. 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 <>. - 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_set_error (bfd_error_invalid_operation); - return false; - } - - if (abfd->format != bfd_unknown) - return (abfd->format == format)? true: false; - - - /* Since the target type was defaulted, check them - all in the hope that one will be uniquely recognized. */ - - save_targ = abfd->xvec; - match_count = 0; - if (matching) - { - matching_vector = - (char **) bfd_malloc (sizeof (char *) * - (_bfd_target_vector_entries + 1)); - if (!matching_vector) - return false; - matching_vector[0] = NULL; - *matching = matching_vector; - } - right_targ = 0; - - - /* presume the answer is yes */ - abfd->format = format; - - /* If the target type was explicitly specified, just check that target. */ - - if (!abfd->target_defaulted) { - 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 = bfd_target_vector; *target != NULL; target++) { - extern const bfd_target binary_vec; - const bfd_target *temp; - - if (*target == &binary_vec) - continue; - - abfd->xvec = *target; /* Change BFD's target temporarily */ - 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_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 == bfd_default_vector[0]) - { - if (matching) - { - matching_vector[0] = temp->name; - matching_vector[1] = NULL; - } - match_count = 1; - break; - } -#ifdef GNU960 - /* Big- and little-endian b.out archives look the same, but it doesn't - * matter: there is no difference in their headers, and member file byte - * orders will (I hope) be handled appropriately by bfd. Ditto for big - * and little coff archives. And the 4 coff/b.out object formats are - * unambiguous. So accept the first match we find. - */ - break; -#endif - } else if (bfd_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 */ - 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 *abfd, bfd_format format); - -DESCRIPTION - 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 -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_set_error (bfd_error_invalid_operation); - return false; - } - - if (abfd->format != bfd_unknown) - return (abfd->format == format) ? true:false; - - /* presume the answer is yes */ - abfd->format = format; - - if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) { - abfd->format = bfd_unknown; - return false; - } - - return true; -} - - -/* -FUNCTION - bfd_format_string - -SYNOPSIS - CONST char *bfd_format_string(bfd_format format); - -DESCRIPTION - Return a pointer to a const string - <>, <>, <>, <>, or <>, - depending upon the value of @var{format}. -*/ - -CONST char * -bfd_format_string (format) - bfd_format format; -{ - if (((int)format <(int) bfd_unknown) - || ((int)format >=(int) bfd_type_end)) - return "invalid"; - - switch (format) { - case bfd_object: - return "object"; /* linker/assember/compiler output */ - case bfd_archive: - return "archive"; /* object archive file */ - case bfd_core: - return "core"; /* core dump */ - default: - return "unknown"; - } -} diff --git a/contrib/gdb/bfd/freebsd.h b/contrib/gdb/bfd/freebsd.h deleted file mode 100644 index 7e1d69d0df7..00000000000 --- a/contrib/gdb/bfd/freebsd.h +++ /dev/null @@ -1,109 +0,0 @@ -/* BFD back-end definitions used by all FreeBSD targets. - Copyright (C) 1990, 1991, 1992, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* FreeBSD ZMAGIC files never have the header in the text. */ -#define N_HEADER_IN_TEXT(x) 0 - -/* ZMAGIC files start at offset 0. Does not apply to QMAGIC files. */ -#define TEXT_START_ADDR 0 - -#define N_GETMAGIC_NET(exec) \ - (ntohl ((exec).a_info) & 0xffff) -#define N_GETMID_NET(exec) \ - ((ntohl ((exec).a_info) >> 16) & 0x3ff) -#define N_GETFLAG_NET(ex) \ - ((ntohl ((exec).a_info) >> 26) & 0x3f) - -#define N_MACHTYPE(exec) \ - ((enum machine_type) \ - ((N_GETMAGIC_NET (exec) == ZMAGIC) ? N_GETMID_NET (exec) : \ - ((exec).a_info >> 16) & 0x3ff)) -#define N_FLAGS(exec) \ - ((N_GETMAGIC_NET (exec) == ZMAGIC) ? N_GETFLAG_NET (exec) : \ - ((exec).a_info >> 26) & 0x3f) - -#define N_SET_INFO(exec, magic, type, flags) \ - ((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0x3ff) << 16) \ - | (((flags) & 0x3f) << 26)) -#define N_SET_MACHTYPE(exec, machtype) \ - ((exec).a_info = \ - ((exec).a_info & 0xfb00ffff) | ((((int)(machtype))&0x3ff) << 16)) -#define N_SET_FLAGS(exec, flags) \ - ((exec).a_info = \ - ((exec).a_info & 0x03ffffff) | ((flags & 0x03f) << 26)) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -/* On FreeBSD, the magic number is always in correct endian format */ -#define NO_SWAP_MAGIC - - -#define MY_write_object_contents MY(write_object_contents) -static boolean MY(write_object_contents) PARAMS ((bfd *abfd)); - -#include "aout-target.h" - -/* Write an object file. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -MY(write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE(abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - /* Magic number, maestro, please! */ - switch (bfd_get_arch(abfd)) { - case bfd_arch_m68k: - if (strcmp (abfd->xvec->name, "a.out-m68k4k-netbsd") == 0) - N_SET_MACHTYPE(*execp, M_68K4K_NETBSD); - else - N_SET_MACHTYPE(*execp, M_68K_NETBSD); - break; - case bfd_arch_sparc: - N_SET_MACHTYPE(*execp, M_SPARC_NETBSD); - break; - case bfd_arch_i386: - N_SET_MACHTYPE(*execp, M_386_NETBSD); - break; - case bfd_arch_ns32k: - N_SET_MACHTYPE(*execp, M_532_NETBSD); - break; - default: - N_SET_MACHTYPE(*execp, M_UNKNOWN); - break; - } - - WRITE_HEADERS(abfd, execp); - - return true; -} diff --git a/contrib/gdb/bfd/gen-aout.c b/contrib/gdb/bfd/gen-aout.c deleted file mode 100644 index d2224f762d3..00000000000 --- a/contrib/gdb/bfd/gen-aout.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Generate parameters for an a.out system. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "/usr/include/a.out.h" -#include - -int -main (argc, argv) - int argc; char** argv; -{ - struct exec my_exec; - int page_size; - char *target = "unknown", *arch = "unknown"; - FILE *file = fopen("gen-aout", "r"); - - if (file == NULL) { - fprintf(stderr, "Cannot open gen-aout!\n"); - return -1; - } - if (fread(&my_exec, sizeof(struct exec), 1, file) != 1) { - fprintf(stderr, "Cannot read gen-aout!\n"); - return -1; - } - - target = argv[1]; - if (target == NULL) { - fprintf(stderr, "Usage: gen-aout target_name\n"); - exit (1); - } - -#ifdef N_TXTOFF - page_size = N_TXTOFF(my_exec); - if (page_size == 0) - printf("#define N_HEADER_IN_TEXT(x) 1\n"); - else - printf("#define N_HEADER_IN_TEXT(x) 0\n"); -#endif - - printf("#define BYTES_IN_WORD %d\n", sizeof (int)); - if (my_exec.a_entry == 0) { - printf("#define ENTRY_CAN_BE_ZERO\n"); - printf("#define N_SHARED_LIB(x) 0 /* Avoids warning */\n"); - } - else { - printf("/*#define ENTRY_CAN_BE_ZERO*/\n"); - printf("/*#define N_SHARED_LIB(x) 0*/\n"); - } - - printf("#define TEXT_START_ADDR %d\n", my_exec.a_entry); - -#ifdef PAGSIZ - if (page_size == 0) - page_size = PAGSIZ; -#endif - if (page_size != 0) - printf("#define TARGET_PAGE_SIZE %d\n", page_size); - else - printf("/* #define TARGET_PAGE_SIZE ??? */\n"); - printf("#define SEGMENT_SIZE TARGET_PAGE_SIZE\n"); - -#ifdef vax - arch = "vax"; -#endif -#ifdef m68k - arch = "m68k"; -#endif - if (arch[0] == '1') - { - fprintf (stderr, "warning: preprocessor substituted architecture name inside string;"); - fprintf (stderr, " fix DEFAULT_ARCH in the output file yourself\n"); - arch = "unknown"; - } - printf("#define DEFAULT_ARCH bfd_arch_%s\n", arch); - - printf("\n#define MY(OP) CAT(%s_,OP)\n", target); - printf("#define TARGETNAME \"a.out-%s\"\n\n", target); - - printf("#include \"bfd.h\"\n"); - printf("#include \"sysdep.h\"\n"); - printf("#include \"libbfd.h\"\n"); - printf("#include \"libaout.h\"\n"); - printf("\n#include \"aout-target.h\"\n"); - - return 0; -} diff --git a/contrib/gdb/bfd/genlink.h b/contrib/gdb/bfd/genlink.h deleted file mode 100644 index 5f080948574..00000000000 --- a/contrib/gdb/bfd/genlink.h +++ /dev/null @@ -1,106 +0,0 @@ -/* genlink.h -- interface to the BFD generic linker - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef GENLINK_H -#define GENLINK_H - -/* This header file is internal to BFD. It describes the internal - structures and functions used by the BFD generic linker, in case - any of the more specific linkers want to use or call them. Note - that some functions, such as _bfd_generic_link_hash_table_create, - are declared in libbfd.h, because they are expected to be widely - used. The functions and structures in this file will probably only - be used by a few files besides linker.c itself. In fact, this file - is not particularly complete; I have only put in the interfaces I - actually needed. */ - -/* The generic linker uses a hash table which is a derived class of - the standard linker hash table, just as the other backend specific - linkers do. Do not confuse the generic linker hash table with the - standard BFD linker hash table it is built upon. */ - -/* Generic linker hash table entries. */ - -struct generic_link_hash_entry -{ - struct bfd_link_hash_entry root; - /* Whether this symbol has been written out. */ - boolean written; - /* Symbol from input BFD. */ - asymbol *sym; -}; - -/* Generic linker hash table. */ - -struct generic_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in an generic link hash table. */ - -#define _bfd_generic_link_hash_lookup(table, string, create, copy, follow) \ - ((struct generic_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) - -/* Traverse an generic link hash table. */ - -#define _bfd_generic_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the generic link hash table from the info structure. This is - just a cast. */ - -#define _bfd_generic_hash_table(p) \ - ((struct generic_link_hash_table *) ((p)->hash)) - -/* The generic linker reads in the asymbol structures for an input BFD - and keeps them in the outsymbol and symcount fields. */ - -#define _bfd_generic_link_get_symbols(abfd) ((abfd)->outsymbols) -#define _bfd_generic_link_get_symcount(abfd) ((abfd)->symcount) - -/* Add the symbols of input_bfd to the symbols being built for - output_bfd. */ -extern boolean _bfd_generic_link_output_symbols - PARAMS ((bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *, - size_t *psymalloc)); - -/* This structure is used to pass information to - _bfd_generic_link_write_global_symbol, which may be called via - _bfd_generic_link_hash_traverse. */ - -struct generic_write_global_symbol_info -{ - struct bfd_link_info *info; - bfd *output_bfd; - size_t *psymalloc; -}; - -/* Write out a single global symbol. This is expected to be called - via _bfd_generic_link_hash_traverse. The second argument must - actually be a struct generic_write_global_symbol_info *. */ -extern boolean _bfd_generic_link_write_global_symbol - PARAMS ((struct generic_link_hash_entry *, PTR)); - -#endif diff --git a/contrib/gdb/bfd/hash.c b/contrib/gdb/bfd/hash.c deleted file mode 100644 index 35913fcfccc..00000000000 --- a/contrib/gdb/bfd/hash.c +++ /dev/null @@ -1,734 +0,0 @@ -/* hash.c -- hash table routines for BFD - Copyright (C) 1993, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -/* -SECTION - Hash Tables - -@cindex Hash tables - BFD provides a simple set of hash table functions. Routines - are provided to initialize a hash table, to free a hash table, - to look up a string in a hash table and optionally create an - entry for it, and to traverse a hash table. There is - currently no routine to delete an string from a hash table. - - The basic hash table does not permit any data to be stored - with a string. However, a hash table is designed to present a - base class from which other types of hash tables may be - derived. These derived types may store additional information - with the string. Hash tables were implemented in this way, - rather than simply providing a data pointer in a hash table - entry, because they were designed for use by the linker back - ends. The linker may create thousands of hash table entries, - and the overhead of allocating private data and storing and - following pointers becomes noticeable. - - The basic hash table code is in <>. - -@menu -@* Creating and Freeing a Hash Table:: -@* Looking Up or Entering a String:: -@* Traversing a Hash Table:: -@* Deriving a New Hash Table Type:: -@end menu - -INODE -Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables -SUBSECTION - Creating and freeing a hash table - -@findex bfd_hash_table_init -@findex bfd_hash_table_init_n - To create a hash table, create an instance of a <> (defined in <>) and call - <> (if you know approximately how many - entries you will need, the function <>, - which takes a @var{size} argument, may be used). - <> returns <> if some sort of - error occurs. - -@findex bfd_hash_newfunc - The function <> take as an argument a - function to use to create new entries. For a basic hash - table, use the function <>. @xref{Deriving - a New Hash Table Type} for why you would want to use a - different value for this argument. - -@findex bfd_hash_allocate - <> will create an obstack which will be - used to allocate new entries. You may allocate memory on this - obstack using <>. - -@findex bfd_hash_table_free - Use <> to free up all the memory that has - been allocated for a hash table. This will not free up the - <> itself, which you must provide. - -INODE -Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables -SUBSECTION - Looking up or entering a string - -@findex bfd_hash_lookup - The function <> is used both to look up a - string in the hash table and to create a new entry. - - If the @var{create} argument is <>, <> - will look up a string. If the string is found, it will - returns a pointer to a <>. If the - string is not found in the table <> will - return <>. You should not modify any of the fields in - the returns <>. - - If the @var{create} argument is <>, the string will be - entered into the hash table if it is not already there. - Either way a pointer to a <> will be - returned, either to the existing structure or to a newly - created one. In this case, a <> return means that an - error occurred. - - If the @var{create} argument is <>, and a new entry is - created, the @var{copy} argument is used to decide whether to - copy the string onto the hash table obstack or not. If - @var{copy} is passed as <>, you must be careful not to - deallocate or modify the string as long as the hash table - exists. - -INODE -Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables -SUBSECTION - Traversing a hash table - -@findex bfd_hash_traverse - The function <> may be used to traverse a - hash table, calling a function on each element. The traversal - is done in a random order. - - <> takes as arguments a function and a - generic <> pointer. The function is called with a - hash table entry (a <>) and the - generic pointer passed to <>. The function - must return a <> value, which indicates whether to - continue traversing the hash table. If the function returns - <>, <> will stop the traversal and - return immediately. - -INODE -Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables -SUBSECTION - Deriving a new hash table type - - Many uses of hash tables want to store additional information - which each entry in the hash table. Some also find it - convenient to store additional information with the hash table - itself. This may be done using a derived hash table. - - Since C is not an object oriented language, creating a derived - hash table requires sticking together some boilerplate - routines with a few differences specific to the type of hash - table you want to create. - - An example of a derived hash table is the linker hash table. - The structures for this are defined in <>. The - functions are in <>. - - You may also derive a hash table from an already derived hash - table. For example, the a.out linker backend code uses a hash - table derived from the linker hash table. - -@menu -@* Define the Derived Structures:: -@* Write the Derived Creation Routine:: -@* Write Other Derived Routines:: -@end menu - -INODE -Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type -SUBSUBSECTION - Define the derived structures - - You must define a structure for an entry in the hash table, - and a structure for the hash table itself. - - The first field in the structure for an entry in the hash - table must be of the type used for an entry in the hash table - you are deriving from. If you are deriving from a basic hash - table this is <>, which is defined in - <>. The first field in the structure for the hash - table itself must be of the type of the hash table you are - deriving from itself. If you are deriving from a basic hash - table, this is <>. - - For example, the linker hash table defines <> (in <>). The first field, - <>, is of type <>. Similarly, - the first field in <>, <>, - is of type <>. - -INODE -Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type -SUBSUBSECTION - Write the derived creation routine - - You must write a routine which will create and initialize an - entry in the hash table. This routine is passed as the - function argument to <>. - - In order to permit other hash tables to be derived from the - hash table you are creating, this routine must be written in a - standard way. - - The first argument to the creation routine is a pointer to a - hash table entry. This may be <>, in which case the - routine should allocate the right amount of space. Otherwise - the space has already been allocated by a hash table type - derived from this one. - - After allocating space, the creation routine must call the - creation routine of the hash table type it is derived from, - passing in a pointer to the space it just allocated. This - will initialize any fields used by the base hash table. - - Finally the creation routine must initialize any local fields - for the new hash table type. - - Here is a boilerplate example of a creation routine. - @var{function_name} is the name of the routine. - @var{entry_type} is the type of an entry in the hash table you - are creating. @var{base_newfunc} is the name of the creation - routine of the hash table type your hash table is derived - from. - -EXAMPLE - -.struct bfd_hash_entry * -.@var{function_name} (entry, table, string) -. struct bfd_hash_entry *entry; -. struct bfd_hash_table *table; -. const char *string; -.{ -. struct @var{entry_type} *ret = (@var{entry_type} *) entry; -. -. {* Allocate the structure if it has not already been allocated by a -. derived class. *} -. if (ret == (@var{entry_type} *) NULL) -. { -. ret = ((@var{entry_type} *) -. bfd_hash_allocate (table, sizeof (@var{entry_type}))); -. if (ret == (@var{entry_type} *) NULL) -. return NULL; -. } -. -. {* Call the allocation method of the base class. *} -. ret = ((@var{entry_type} *) -. @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string)); -. -. {* Initialize the local fields here. *} -. -. return (struct bfd_hash_entry *) ret; -.} - -DESCRIPTION - The creation routine for the linker hash table, which is in - <>, looks just like this example. - @var{function_name} is <<_bfd_link_hash_newfunc>>. - @var{entry_type} is <>. - @var{base_newfunc} is <>, the creation - routine for a basic hash table. - - <<_bfd_link_hash_newfunc>> also initializes the local fields - in a linker hash table entry: <>, <> and - <>. - -INODE -Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type -SUBSUBSECTION - Write other derived routines - - You will want to write other routines for your new hash table, - as well. - - You will want an initialization routine which calls the - initialization routine of the hash table you are deriving from - and initializes any other local fields. For the linker hash - table, this is <<_bfd_link_hash_table_init>> in <>. - - You will want a lookup routine which calls the lookup routine - of the hash table you are deriving from and casts the result. - The linker hash table uses <> in - <> (this actually takes an additional argument which - it uses to decide how to return the looked up value). - - You may want a traversal routine. This should just call the - traversal routine of the hash table you are deriving from with - appropriate casts. The linker hash table uses - <> in <>. - - These routines may simply be defined as macros. For example, - the a.out backend linker hash table, which is derived from the - linker hash table, uses macros for the lookup and traversal - routines. These are <> and - <> in aoutx.h. -*/ - -/* Obstack allocation and deallocation routines. */ -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free - -/* The default number of entries to use when creating a hash table. */ -#define DEFAULT_SIZE (4051) - -/* Create a new hash table, given a number of entries. */ - -boolean -bfd_hash_table_init_n (table, newfunc, size) - struct bfd_hash_table *table; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); - unsigned int size; -{ - unsigned int alloc; - - alloc = size * sizeof (struct bfd_hash_entry *); - if (!obstack_begin (&table->memory, alloc)) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - table->table = ((struct bfd_hash_entry **) - obstack_alloc (&table->memory, alloc)); - if (!table->table) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset ((PTR) table->table, 0, alloc); - table->size = size; - table->newfunc = newfunc; - return true; -} - -/* Create a new hash table with the default number of entries. */ - -boolean -bfd_hash_table_init (table, newfunc) - struct bfd_hash_table *table; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return bfd_hash_table_init_n (table, newfunc, DEFAULT_SIZE); -} - -/* Free a hash table. */ - -void -bfd_hash_table_free (table) - struct bfd_hash_table *table; -{ - obstack_free (&table->memory, (PTR) NULL); -} - -/* Look up a string in a hash table. */ - -struct bfd_hash_entry * -bfd_hash_lookup (table, string, create, copy) - struct bfd_hash_table *table; - const char *string; - boolean create; - boolean copy; -{ - register const unsigned char *s; - register unsigned long hash; - register unsigned int c; - struct bfd_hash_entry *hashp; - unsigned int len; - unsigned int index; - - hash = 0; - len = 0; - s = (const unsigned char *) string; - while ((c = *s++) != '\0') - { - hash += c + (c << 17); - hash ^= hash >> 2; - ++len; - } - hash += len + (len << 17); - hash ^= hash >> 2; - - index = hash % table->size; - for (hashp = table->table[index]; - hashp != (struct bfd_hash_entry *) NULL; - hashp = hashp->next) - { - if (hashp->hash == hash - && strcmp (hashp->string, string) == 0) - return hashp; - } - - if (! create) - return (struct bfd_hash_entry *) NULL; - - hashp = (*table->newfunc) ((struct bfd_hash_entry *) NULL, table, string); - if (hashp == (struct bfd_hash_entry *) NULL) - return (struct bfd_hash_entry *) NULL; - if (copy) - { - char *new; - - new = (char *) obstack_alloc (&table->memory, len + 1); - if (!new) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_hash_entry *) NULL; - } - strcpy (new, string); - string = new; - } - hashp->string = string; - hashp->hash = hash; - hashp->next = table->table[index]; - table->table[index] = hashp; - - return hashp; -} - -/* Replace an entry in a hash table. */ - -void -bfd_hash_replace (table, old, nw) - struct bfd_hash_table *table; - struct bfd_hash_entry *old; - struct bfd_hash_entry *nw; -{ - unsigned int index; - struct bfd_hash_entry **pph; - - index = old->hash % table->size; - for (pph = &table->table[index]; - (*pph) != (struct bfd_hash_entry *) NULL; - pph = &(*pph)->next) - { - if (*pph == old) - { - *pph = nw; - return; - } - } - - abort (); -} - -/* Base method for creating a new hash table entry. */ - -/*ARGSUSED*/ -struct bfd_hash_entry * -bfd_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - if (entry == (struct bfd_hash_entry *) NULL) - entry = ((struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct bfd_hash_entry))); - return entry; -} - -/* Allocate space in a hash table. */ - -PTR -bfd_hash_allocate (table, size) - struct bfd_hash_table *table; - unsigned int size; -{ - PTR ret; - - ret = obstack_alloc (&table->memory, size); - if (ret == NULL && size != 0) - bfd_set_error (bfd_error_no_memory); - return ret; -} - -/* Traverse a hash table. */ - -void -bfd_hash_traverse (table, func, info) - struct bfd_hash_table *table; - boolean (*func) PARAMS ((struct bfd_hash_entry *, PTR)); - PTR info; -{ - unsigned int i; - - for (i = 0; i < table->size; i++) - { - struct bfd_hash_entry *p; - - for (p = table->table[i]; p != NULL; p = p->next) - { - if (! (*func) (p, info)) - return; - } - } -} - -/* A few different object file formats (a.out, COFF, ELF) use a string - table. These functions support adding strings to a string table, - returning the byte offset, and writing out the table. - - Possible improvements: - + look for strings matching trailing substrings of other strings - + better data structures? balanced trees? - + look at reducing memory use elsewhere -- maybe if we didn't have - to construct the entire symbol table at once, we could get by - with smaller amounts of VM? (What effect does that have on the - string table reductions?) */ - -/* An entry in the strtab hash table. */ - -struct strtab_hash_entry -{ - struct bfd_hash_entry root; - /* Index in string table. */ - bfd_size_type index; - /* Next string in strtab. */ - struct strtab_hash_entry *next; -}; - -/* The strtab hash table. */ - -struct bfd_strtab_hash -{ - struct bfd_hash_table table; - /* Size of strtab--also next available index. */ - bfd_size_type size; - /* First string in strtab. */ - struct strtab_hash_entry *first; - /* Last string in strtab. */ - struct strtab_hash_entry *last; - /* Whether to precede strings with a two byte length, as in the - XCOFF .debug section. */ - boolean xcoff; -}; - -static struct bfd_hash_entry *strtab_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); - -/* Routine to create an entry in a strtab. */ - -static struct bfd_hash_entry * -strtab_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct strtab_hash_entry *) NULL) - ret = ((struct strtab_hash_entry *) - bfd_hash_allocate (table, sizeof (struct strtab_hash_entry))); - if (ret == (struct strtab_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct strtab_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->index = (bfd_size_type) -1; - ret->next = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in an strtab. */ - -#define strtab_hash_lookup(t, string, create, copy) \ - ((struct strtab_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* Create a new strtab. */ - -struct bfd_strtab_hash * -_bfd_stringtab_init () -{ - struct bfd_strtab_hash *table; - - table = ((struct bfd_strtab_hash *) - bfd_malloc (sizeof (struct bfd_strtab_hash))); - if (table == NULL) - return NULL; - - if (! bfd_hash_table_init (&table->table, strtab_hash_newfunc)) - { - free (table); - return NULL; - } - - table->size = 0; - table->first = NULL; - table->last = NULL; - table->xcoff = false; - - return table; -} - -/* Create a new strtab in which the strings are output in the format - used in the XCOFF .debug section: a two byte length precedes each - string. */ - -struct bfd_strtab_hash * -_bfd_xcoff_stringtab_init () -{ - struct bfd_strtab_hash *ret; - - ret = _bfd_stringtab_init (); - if (ret != NULL) - ret->xcoff = true; - return ret; -} - -/* Free a strtab. */ - -void -_bfd_stringtab_free (table) - struct bfd_strtab_hash *table; -{ - bfd_hash_table_free (&table->table); - free (table); -} - -/* Get the index of a string in a strtab, adding it if it is not - already present. If HASH is false, we don't really use the hash - table, and we don't eliminate duplicate strings. */ - -bfd_size_type -_bfd_stringtab_add (tab, str, hash, copy) - struct bfd_strtab_hash *tab; - const char *str; - boolean hash; - boolean copy; -{ - register struct strtab_hash_entry *entry; - - if (hash) - { - entry = strtab_hash_lookup (tab, str, true, copy); - if (entry == NULL) - return (bfd_size_type) -1; - } - else - { - entry = ((struct strtab_hash_entry *) - bfd_hash_allocate (&tab->table, - sizeof (struct strtab_hash_entry))); - if (entry == NULL) - return (bfd_size_type) -1; - if (! copy) - entry->root.string = str; - else - { - char *n; - - n = (char *) bfd_hash_allocate (&tab->table, strlen (str) + 1); - if (n == NULL) - return (bfd_size_type) -1; - entry->root.string = n; - } - entry->index = (bfd_size_type) -1; - entry->next = NULL; - } - - if (entry->index == (bfd_size_type) -1) - { - entry->index = tab->size; - tab->size += strlen (str) + 1; - if (tab->xcoff) - { - entry->index += 2; - tab->size += 2; - } - if (tab->first == NULL) - tab->first = entry; - else - tab->last->next = entry; - tab->last = entry; - } - - return entry->index; -} - -/* Get the number of bytes in a strtab. */ - -bfd_size_type -_bfd_stringtab_size (tab) - struct bfd_strtab_hash *tab; -{ - return tab->size; -} - -/* Write out a strtab. ABFD must already be at the right location in - the file. */ - -boolean -_bfd_stringtab_emit (abfd, tab) - register bfd *abfd; - struct bfd_strtab_hash *tab; -{ - register boolean xcoff; - register struct strtab_hash_entry *entry; - - xcoff = tab->xcoff; - - for (entry = tab->first; entry != NULL; entry = entry->next) - { - register const char *str; - register size_t len; - - str = entry->root.string; - len = strlen (str) + 1; - - if (xcoff) - { - bfd_byte buf[2]; - - /* The output length includes the null byte. */ - bfd_put_16 (abfd, len, buf); - if (bfd_write ((PTR) buf, 1, 2, abfd) != 2) - return false; - } - - if (bfd_write ((PTR) str, 1, len, abfd) != len) - return false; - } - - return true; -} diff --git a/contrib/gdb/bfd/host-aout.c b/contrib/gdb/bfd/host-aout.c deleted file mode 100644 index 99643dcc24e..00000000000 --- a/contrib/gdb/bfd/host-aout.c +++ /dev/null @@ -1,83 +0,0 @@ -/* BFD backend for local host's a.out binaries - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. Probably John Gilmore's fault. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -/* When porting to a new system, you must supply: - - HOST_PAGE_SIZE (optional) - HOST_SEGMENT_SIZE (optional -- defaults to page size) - HOST_MACHINE_ARCH (optional) - HOST_MACHINE_MACHINE (optional) - HOST_TEXT_START_ADDR (optional) - HOST_STACK_END_ADDR (not used, except by trad-core ???) - HOST_BIG_ENDIAN_P (required -- define if big-endian) - - in the ./hosts/h-systemname.h file. */ - -#ifdef TRAD_HEADER -#include TRAD_HEADER -#endif - -#ifdef HOST_PAGE_SIZE -#define TARGET_PAGE_SIZE HOST_PAGE_SIZE -#endif - -#ifdef HOST_SEGMENT_SIZE -#define SEGMENT_SIZE HOST_SEGMENT_SIZE -#else -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#endif - -#ifdef HOST_TEXT_START_ADDR -#define TEXT_START_ADDR HOST_TEXT_START_ADDR -#endif - -#ifdef HOST_STACK_END_ADDR -#define STACK_END_ADDR HOST_STACK_END_ADDR -#endif - -#ifdef HOST_BIG_ENDIAN_P -#define TARGET_IS_BIG_ENDIAN_P -#else -#undef TARGET_IS_BIG_ENDIAN_P -#endif - -#include "libaout.h" /* BFD a.out internal data structures */ -#include "aout/aout64.h" - -#ifdef HOST_MACHINE_ARCH -#ifdef HOST_MACHINE_MACHINE -#define SET_ARCH_MACH(abfd, execp) \ - bfd_default_set_arch_mach(abfd, HOST_MACHINE_ARCH, HOST_MACHINE_MACHINE) -#else -#define SET_ARCH_MACH(abfd, execp) \ - bfd_default_set_arch_mach(abfd, HOST_MACHINE_ARCH, 0) -#endif -#endif /* HOST_MACHINE_ARCH */ - -#define MY(OP) CAT(host_aout_,OP) -#define TARGETNAME "a.out" - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/hosts/alphalinux.h b/contrib/gdb/bfd/hosts/alphalinux.h deleted file mode 100644 index d9ba1b7ec6b..00000000000 --- a/contrib/gdb/bfd/hosts/alphalinux.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Linux dumps "struct task_struct" at the end of the core-file. This - structure is currently 920 bytes long, but we allow up to 1024 - bytes to allow for some future growth. */ -#define TRAD_CORE_EXTRA_SIZE_ALLOWED 1024 -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \ - ((abfd)->tdata.trad_core_data->u.signal) diff --git a/contrib/gdb/bfd/hosts/decstation.h b/contrib/gdb/bfd/hosts/decstation.h deleted file mode 100644 index a80c143d525..00000000000 --- a/contrib/gdb/bfd/hosts/decstation.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Hopefully this should include either machine/param.h (Ultrix) or - machine/machparam.h (Mach), whichever is its name on this system. */ -#include - -#include - -#define HOST_PAGE_SIZE NBPG -/* #define HOST_SEGMENT_SIZE NBPG -- we use HOST_DATA_START_ADDR */ -#define HOST_MACHINE_ARCH bfd_arch_mips -/* #define HOST_MACHINE_MACHINE */ - -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_DATA_START_ADDR USRDATA -#define HOST_STACK_END_ADDR USRSTACK - -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \ - ((core_bfd)->tdata.trad_core_data->u.u_arg[0]) diff --git a/contrib/gdb/bfd/hosts/delta68.h b/contrib/gdb/bfd/hosts/delta68.h deleted file mode 100644 index 1a6a6e6f197..00000000000 --- a/contrib/gdb/bfd/hosts/delta68.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Definitions for a Motorola Delta 3300 box running System V R3.0. - Contributed by manfred@lts.sel.alcatel.de. */ - -#include - -/* Definitions used by trad-core.c. */ -#define NBPG NBPC -#define HOST_DATA_START_ADDR u.u_exdata.ux_datorg -#define HOST_TEXT_START_ADDR u.u_exdata.ux_txtorg -#if 0 -#define HOST_STACK_END_ADDR 0x40000000 -#else -/* User's stack, copied from sys/param.h */ -#define HOST_STACK_END_ADDR USRSTACK -#endif -#define UPAGES USIZE -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \ - abfd->tdata.trad_core_data->u.u_abort diff --git a/contrib/gdb/bfd/hosts/dpx2.h b/contrib/gdb/bfd/hosts/dpx2.h deleted file mode 100644 index ea6395f2e5d..00000000000 --- a/contrib/gdb/bfd/hosts/dpx2.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Definitions that are needed for core files. Core section sizes for - the DPX2 are in bytes. */ - -#include -#define NBPG 1 -#define UPAGES (USIZE * NBPP) -#define HOST_DATA_START_ADDR (u.u_exdata.ux_datorg) -#define HOST_STACK_END_ADDR (USERSTACK) diff --git a/contrib/gdb/bfd/hosts/hp300bsd.h b/contrib/gdb/bfd/hosts/hp300bsd.h deleted file mode 100644 index 98287178207..00000000000 --- a/contrib/gdb/bfd/hosts/hp300bsd.h +++ /dev/null @@ -1,13 +0,0 @@ -#include -#ifdef BSD4_4 -#define NO_CORE_COMMAND -#endif - -#define HOST_PAGE_SIZE NBPG -#define HOST_SEGMENT_SIZE NBPG /* Data seg start addr rounds to NBPG */ -#define HOST_MACHINE_ARCH bfd_arch_m68k -/* #define HOST_MACHINE_MACHINE */ - -#define HOST_TEXT_START_ADDR 0 -#define HOST_STACK_END_ADDR 0xfff00000 -#define HOST_BIG_ENDIAN_P diff --git a/contrib/gdb/bfd/hosts/i386bsd.h b/contrib/gdb/bfd/hosts/i386bsd.h deleted file mode 100644 index ac0d8402edb..00000000000 --- a/contrib/gdb/bfd/hosts/i386bsd.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Intel 386 running any BSD Unix */ - -#include -#include - -#define HOST_PAGE_SIZE NBPG -#define HOST_MACHINE_ARCH bfd_arch_i386 -#define HOST_TEXT_START_ADDR USRTEXT - -/* Jolitz suggested defining HOST_STACK_END_ADDR to - (u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on - both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */ - -#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 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 diff --git a/contrib/gdb/bfd/hosts/i386linux.h b/contrib/gdb/bfd/hosts/i386linux.h deleted file mode 100644 index 13a51f1bd14..00000000000 --- a/contrib/gdb/bfd/hosts/i386linux.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Linux writes the task structure at the end of the core file. Currently it - is 2912 bytes. It is possible that this should be a pickier check, but - we should probably not be too picky (the size of the task structure might - vary, and if it's not the length we expect it to be, it doesn't affect - our ability to process the core file). So allow 0-4096 extra bytes at - the end. */ - -#define TRAD_CORE_EXTRA_SIZE_ALLOWED 4096 diff --git a/contrib/gdb/bfd/hosts/i386mach3.h b/contrib/gdb/bfd/hosts/i386mach3.h deleted file mode 100644 index dcc61e3c8e8..00000000000 --- a/contrib/gdb/bfd/hosts/i386mach3.h +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -/* This is an ugly way to hack around the incorrect - * definition of UPAGES in i386/machparam.h. - * - * The definition should specify the size reserved - * for "struct user" in core files in PAGES, - * but instead it gives it in 512-byte core-clicks - * for i386 and i860. UPAGES is used only in trad-core.c. - */ -#if UPAGES == 16 -#undef UPAGES -#define UPAGES 2 -#endif - -#if UPAGES != 2 -FIXME!! UPAGES is neither 2 nor 16 -#endif - -#define HOST_PAGE_SIZE 1 -#define HOST_SEGMENT_SIZE NBPG -#define HOST_MACHINE_ARCH bfd_arch_i386 -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_STACK_END_ADDR USRSTACK diff --git a/contrib/gdb/bfd/hosts/i386sco.h b/contrib/gdb/bfd/hosts/i386sco.h deleted file mode 100644 index ec8608c61dd..00000000000 --- a/contrib/gdb/bfd/hosts/i386sco.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Core file stuff. At least some, perhaps all, of the following - defines work on many more systems than just SCO. */ - -#define NBPG NBPC -#define UPAGES USIZE -#define HOST_DATA_START_ADDR u.u_exdata.ux_datorg -#define HOST_STACK_START_ADDR u.u_sub -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \ - ((core_upage(abfd)->u_sysabort != 0) \ - ? core_upage(abfd)->u_sysabort \ - : -1) - -/* According to the manpage, a version 2 SCO corefile can contain - various additional sections (it is cleverly arranged so the u area, - data, and stack are first where we can find them). So without - writing lots of code to parse all their headers and stuff, we can't - know whether a corefile is bigger than it should be. */ - -#define TRAD_CORE_ALLOW_ANY_EXTRA_SIZE 1 diff --git a/contrib/gdb/bfd/hosts/i860mach3.h b/contrib/gdb/bfd/hosts/i860mach3.h deleted file mode 100644 index edd2aa10a7b..00000000000 --- a/contrib/gdb/bfd/hosts/i860mach3.h +++ /dev/null @@ -1,27 +0,0 @@ -/* This file was hacked from i386mach3.h [dolan@ssd.intel.com] */ - -#include -#include - -/* This is an ugly way to hack around the incorrect - * definition of UPAGES in i386/machparam.h. - * - * The definition should specify the size reserved - * for "struct user" in core files in PAGES, - * but instead it gives it in 512-byte core-clicks - * for i386 and i860. UPAGES is used only in trad-core.c. - */ -#if UPAGES == 16 -#undef UPAGES -#define UPAGES 2 -#endif - -#if UPAGES != 2 -FIXME!! UPAGES is neither 2 nor 16 -#endif - -#define HOST_PAGE_SIZE 1 -#define HOST_SEGMENT_SIZE NBPG -#define HOST_MACHINE_ARCH bfd_arch_i860 -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_STACK_END_ADDR USRSTACK diff --git a/contrib/gdb/bfd/hosts/m68kaux.h b/contrib/gdb/bfd/hosts/m68kaux.h deleted file mode 100644 index 6237755dba5..00000000000 --- a/contrib/gdb/bfd/hosts/m68kaux.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Definitions for an Apple Macintosh running A/UX 3.x. */ - -#include -#include - -/* Definitions used by trad-core.c. */ -#define NBPG NBPP - -#define HOST_DATA_START_ADDR u.u_exdata.ux_datorg -#define HOST_TEXT_START_ADDR u.u_exdata.ux_txtorg -#define HOST_STACK_END_ADDR 0x100000000 - -#define UPAGES USIZE - -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \ - (abfd->tdata.trad_core_data->u.u_arg[0]) diff --git a/contrib/gdb/bfd/hosts/m68klinux.h b/contrib/gdb/bfd/hosts/m68klinux.h deleted file mode 100644 index 0067dfa6fda..00000000000 --- a/contrib/gdb/bfd/hosts/m68klinux.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Linux dumps "struct task_struct" at the end of the core-file. This - structure is currently 2512 bytes long, but we allow up to 4096 - bytes to allow for some future growth. */ -#define TRAD_CORE_EXTRA_SIZE_ALLOWED 4096 -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \ - ((abfd)->tdata.trad_core_data->u.signal) diff --git a/contrib/gdb/bfd/hosts/m88kmach3.h b/contrib/gdb/bfd/hosts/m88kmach3.h deleted file mode 100644 index 421553893ec..00000000000 --- a/contrib/gdb/bfd/hosts/m88kmach3.h +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -#undef UPAGES -#define UPAGES 3 - -#define HOST_PAGE_SIZE NBPG -#define HOST_SEGMENT_SIZE NBPG -#define HOST_MACHINE_ARCH bfd_arch_m88k -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_STACK_END_ADDR USRSTACK diff --git a/contrib/gdb/bfd/hosts/mipsbsd.h b/contrib/gdb/bfd/hosts/mipsbsd.h deleted file mode 100644 index a2fad21fcf7..00000000000 --- a/contrib/gdb/bfd/hosts/mipsbsd.h +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#undef ALIGN - -#define HOST_PAGE_SIZE NBPG -/* #define HOST_SEGMENT_SIZE NBPG -- we use HOST_DATA_START_ADDR */ -#define HOST_MACHINE_ARCH bfd_arch_mips -/* #define HOST_MACHINE_MACHINE */ - -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_STACK_END_ADDR USRSTACK -#define NO_CORE_COMMAND diff --git a/contrib/gdb/bfd/hosts/mipsmach3.h b/contrib/gdb/bfd/hosts/mipsmach3.h deleted file mode 100644 index c5c468d3742..00000000000 --- a/contrib/gdb/bfd/hosts/mipsmach3.h +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include -#include - -#define HOST_PAGE_SIZE NBPG -/* #define HOST_SEGMENT_SIZE NBPG */ -#define HOST_MACHINE_ARCH bfd_arch_mips -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_DATA_START_ADDR USRDATA -#define HOST_STACK_END_ADDR USRSTACK diff --git a/contrib/gdb/bfd/hosts/news-mips.h b/contrib/gdb/bfd/hosts/news-mips.h deleted file mode 100644 index 9e799bed904..00000000000 --- a/contrib/gdb/bfd/hosts/news-mips.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Sony News running NewsOS 3.2. */ - -#include -#include - -#define HOST_PAGE_SIZE NBPG - -#define HOST_MACHINE_ARCH bfd_arch_mips - -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_DATA_START_ADDR USRDATA -#define HOST_STACK_END_ADDR USRSTACK diff --git a/contrib/gdb/bfd/hosts/news.h b/contrib/gdb/bfd/hosts/news.h deleted file mode 100644 index bf7946cdb99..00000000000 --- a/contrib/gdb/bfd/hosts/news.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Sony News running NewsOS 3.2. */ - -#include - -#define HOST_PAGE_SIZE NBPG -#define HOST_SEGMENT_SIZE NBPG -#define HOST_MACHINE_ARCH bfd_arch_m68k -#define HOST_TEXT_START_ADDR 0 -#define HOST_STACK_END_ADDR (KERNBASE - (UPAGES * NBPG)) diff --git a/contrib/gdb/bfd/hosts/pc532mach.h b/contrib/gdb/bfd/hosts/pc532mach.h deleted file mode 100644 index ab96f597edd..00000000000 --- a/contrib/gdb/bfd/hosts/pc532mach.h +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -/* This is an ugly way to hack around the incorrect - * definition of UPAGES in ns532/machparam.h. - * - * The definition should specify the size reserved - * for "struct user" in core files in PAGES, - * but instead it gives it in 512-byte core-clicks - * for ns532, i386 and i860. UPAGES is used only in trad-core.c. - */ -#if UPAGES == 16 -#undef UPAGES -#define UPAGES 2 -#endif - -#if UPAGES != 2 -#error UPAGES is neither 2 nor 16 -#endif - -#define HOST_PAGE_SIZE 1 -#define HOST_SEGMENT_SIZE NBPG -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_STACK_END_ADDR USRSTACK diff --git a/contrib/gdb/bfd/hosts/riscos.h b/contrib/gdb/bfd/hosts/riscos.h deleted file mode 100644 index 8ffa826bdcf..00000000000 --- a/contrib/gdb/bfd/hosts/riscos.h +++ /dev/null @@ -1,10 +0,0 @@ -/* RISC/os 4.52C, and presumably other versions. */ - -#include -#include - -#define NBPG BSD43_NBPG -#define UPAGES BSD43_UPAGES -#define HOST_TEXT_START_ADDR BSD43_USRTEXT -#define HOST_DATA_START_ADDR BSD43_USRDATA -#define HOST_STACK_END_ADDR BSD43_USRSTACK diff --git a/contrib/gdb/bfd/hosts/symmetry.h b/contrib/gdb/bfd/hosts/symmetry.h deleted file mode 100644 index 75717b31eb2..00000000000 --- a/contrib/gdb/bfd/hosts/symmetry.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Symmetry running either dynix 3.1 (bsd) or ptx (sysv). */ - -#define NBPG 4096 -#define UPAGES 1 - -#ifdef _SEQUENT_ -/* ptx */ -#define HOST_TEXT_START_ADDR 0 -#define HOST_STACK_END_ADDR 0x3fffe000 -#define TRAD_CORE_USER_OFFSET ((UPAGES * NBPG) - sizeof (struct user)) -#else -/* dynix */ -#define HOST_TEXT_START_ADDR 0x1000 -#define HOST_DATA_START_ADDR (NBPG * u.u_tsize) -#define HOST_STACK_END_ADDR 0x3ffff000 -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \ - ((core_bfd)->tdata.trad_core_data->u.u_arg[0]) -#endif - -#define TRAD_CORE_DSIZE_INCLUDES_TSIZE diff --git a/contrib/gdb/bfd/hosts/tahoe.h b/contrib/gdb/bfd/hosts/tahoe.h deleted file mode 100644 index 716cee2a171..00000000000 --- a/contrib/gdb/bfd/hosts/tahoe.h +++ /dev/null @@ -1,12 +0,0 @@ -#define NO_CORE_COMMAND - -#undef ALIGN /* They use it, we use it too */ -#include -#undef ALIGN /* They use it, we use it too */ - -#define HOST_PAGE_SIZE NBPG -#define HOST_MACHINE_ARCH bfd_arch_tahoe - -#define HOST_TEXT_START_ADDR 0 -#define HOST_STACK_END_ADDR (KERNBASE - (UPAGES * NBPG)) -#define HOST_BIG_ENDIAN_P diff --git a/contrib/gdb/bfd/hosts/vaxbsd.h b/contrib/gdb/bfd/hosts/vaxbsd.h deleted file mode 100644 index ceb9ccedfaf..00000000000 --- a/contrib/gdb/bfd/hosts/vaxbsd.h +++ /dev/null @@ -1,19 +0,0 @@ -#define NO_CORE_COMMAND /* No command name in core file */ - -#if 0 -#undef ALIGN /* They use it, we use it too */ -/* Does not exist on BSD 4.3, it uses machine/machparam.h. - Whatever it is, it's included by , which trad-core.c, - the only place that uses this (I think), already includes. */ -#include -#endif -#undef ALIGN /* They use it, we use it too */ - -/* Note that HOST_PAGE_SIZE -- the page size as far as executable files - are concerned -- is not the same as NBPG, because of page clustering. */ -#define HOST_PAGE_SIZE 1024 -#define HOST_MACHINE_ARCH bfd_arch_vax - -#define HOST_TEXT_START_ADDR 0 -#define HOST_STACK_END_ADDR (0x80000000 - (UPAGES * NBPG)) -#undef HOST_BIG_ENDIAN_P diff --git a/contrib/gdb/bfd/hosts/vaxult.h b/contrib/gdb/bfd/hosts/vaxult.h deleted file mode 100644 index 13731b7479f..00000000000 --- a/contrib/gdb/bfd/hosts/vaxult.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#define HOST_PAGE_SIZE (NBPG*CLSIZE) -#define HOST_MACHINE_ARCH bfd_arch_vax - -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_STACK_END_ADDR USRSTACK -#undef HOST_BIG_ENDIAN_P diff --git a/contrib/gdb/bfd/hosts/vaxult2.h b/contrib/gdb/bfd/hosts/vaxult2.h deleted file mode 100644 index 13731b7479f..00000000000 --- a/contrib/gdb/bfd/hosts/vaxult2.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#define HOST_PAGE_SIZE (NBPG*CLSIZE) -#define HOST_MACHINE_ARCH bfd_arch_vax - -#define HOST_TEXT_START_ADDR USRTEXT -#define HOST_STACK_END_ADDR USRSTACK -#undef HOST_BIG_ENDIAN_P diff --git a/contrib/gdb/bfd/hp300bsd.c b/contrib/gdb/bfd/hp300bsd.c deleted file mode 100644 index 5767b18c179..00000000000 --- a/contrib/gdb/bfd/hp300bsd.c +++ /dev/null @@ -1,38 +0,0 @@ -/* BFD back-end for HP 9000/300 (68000-based) machines running BSD Unix. - Copyright 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_IS_BIG_ENDIAN_P -#define N_HEADER_IN_TEXT(x) 0 -#define BYTES_IN_WORD 4 -#define ENTRY_CAN_BE_ZERO -#define N_SHARED_LIB(x) 0 /* Avoids warning */ -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_m68k - -#define MY(OP) CAT(hp300bsd_,OP) -#define TARGETNAME "a.out-hp300bsd" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/hp300hpux.c b/contrib/gdb/bfd/hp300hpux.c deleted file mode 100644 index 1d1acab8ae4..00000000000 --- a/contrib/gdb/bfd/hp300hpux.c +++ /dev/null @@ -1,865 +0,0 @@ -/* BFD backend for hp-ux 9000/300 - Copyright (C) 1990, 1991, 1994, 1995 Free Software Foundation, Inc. - Written by Glenn Engel. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - - hpux native ------------> | | - | hp300hpux bfd | ----------> hpux w/gnu ext - hpux w/gnu extension ----> | | - - - Support for the 9000/[34]00 has several limitations. - 1. Shared libraries are not supported. - 2. The output format from this bfd is not usable by native tools. - - The primary motivation for writing this bfd was to allow use of - gdb and gcc for host based debugging and not to mimic the hp-ux tools - in every detail. This leads to a significant simplification of the - code and a leap in performance. The decision to not output hp native - compatible objects was further strengthened by the fact that the richness - of the gcc compiled objects could not be represented without loss of - information. For example, while the hp format supports the concept of - secondary symbols, it does not support indirect symbols. Another - reason is to maintain backwards compatibility with older implementations - of gcc on hpux which used 'hpxt' to translate .a and .o files into a - format which could be readily understood by the gnu linker and gdb. - This allows reading hp secondary symbols and converting them into - indirect symbols but the reverse it not always possible. - - Another example of differences is that the hp format stores symbol offsets - in the object code while the gnu utilities use a field in the - relocation record for this. To support the hp native format, the object - code would need to be patched with the offsets when producing .o files. - - The basic technique taken in this implementation is to #include the code - from aoutx.h and aout-target.h with appropriate #defines to override - code where a unique implementation is needed: - - { - #define a bunch of stuff - #include - - implement a bunch of functions - - #include "aout-target.h" - } - - The hp symbol table is a bit different than other a.out targets. Instead - of having an array of nlist items and an array of strings, hp's format - has them mixed together in one structure. In addition, the strings are - not null terminated. It looks something like this: - - nlist element 1 - string1 - nlist element 2 - string2 - ... - - The whole symbol table is read as one chunk and then we march thru it - and convert it to canonical form. As we march thru the table, we copy - the nlist data into the internal form and we compact the strings and null - terminate them, using storage from the already allocated symbol table: - - string1 - null - string2 - null - */ - -/* @@ Is this really so different from normal a.out that it needs to include - aoutx.h? We should go through this file sometime and see what can be made - more dependent on aout32.o and what might need to be broken off and accessed - through the backend_data field. Or, maybe we really do need such a - completely separate implementation. I don't have time to investigate this - much further right now. [raeburn:19930428.2124EST] */ -/* @@ Also, note that there wind up being two versions of some routines, with - different names, only one of which actually gets used. For example: - slurp_symbol_table - swap_std_reloc_in - slurp_reloc_table - get_symtab - get_symtab_upper_bound - canonicalize_reloc - mkobject - This should also be fixed. */ - -#define TARGETNAME "a.out-hp300hpux" -#define MY(OP) CAT(hp300hpux_,OP) - -#define external_exec hp300hpux_exec_bytes -#define external_nlist hp300hpux_nlist_bytes - -#include "aout/hp300hpux.h" - -/* define these so we can compile unused routines in aoutx.h */ -#define e_strx e_shlib -#define e_other e_length -#define e_desc e_almod - -#define AR_PAD_CHAR '/' -#define TARGET_IS_BIG_ENDIAN_P -#define DEFAULT_ARCH bfd_arch_m68k - -#define MY_get_section_contents aout_32_get_section_contents -#define MY_slurp_armap bfd_slurp_bsd_armap_f2 - -/***********************************************/ -/* provide overrides for routines in this file */ -/***********************************************/ -/* these don't use MY because that causes problems within JUMP_TABLE - (CAT winds up being expanded recursively, which ANSI C compilers - will not do). */ -#define MY_get_symtab hp300hpux_get_symtab -#define MY_get_symtab_upper_bound hp300hpux_get_symtab_upper_bound -#define MY_canonicalize_reloc hp300hpux_canonicalize_reloc -#define MY_write_object_contents hp300hpux_write_object_contents - -#define MY_read_minisymbols _bfd_generic_read_minisymbols -#define MY_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define MY_final_link_callback unused -#define MY_bfd_final_link _bfd_generic_final_link - -/* Until and unless we convert the slurp_reloc and slurp_symtab - routines in this file, we can not use the default aout - free_cached_info routine which assumes that the relocs and symtabs - were allocated using malloc. */ -#define MY_bfd_free_cached_info bfd_true - -#define hp300hpux_write_syms aout_32_write_syms - -#define MY_callback MY(callback) - -#define MY_exec_hdr_flags 0x2 - -#define NAME_swap_exec_header_in NAME(hp300hpux_32_,swap_exec_header_in) - -#define HP_SYMTYPE_UNDEFINED 0x00 -#define HP_SYMTYPE_ABSOLUTE 0x01 -#define HP_SYMTYPE_TEXT 0x02 -#define HP_SYMTYPE_DATA 0x03 -#define HP_SYMTYPE_BSS 0x04 -#define HP_SYMTYPE_COMMON 0x05 - -#define HP_SYMTYPE_TYPE 0x0F -#define HP_SYMTYPE_FILENAME 0x1F - -#define HP_SYMTYPE_ALIGN 0x10 -#define HP_SYMTYPE_EXTERNAL 0x20 -#define HP_SECONDARY_SYMBOL 0x40 - -/* RELOCATION DEFINITIONS */ -#define HP_RSEGMENT_TEXT 0x00 -#define HP_RSEGMENT_DATA 0x01 -#define HP_RSEGMENT_BSS 0x02 -#define HP_RSEGMENT_EXTERNAL 0x03 -#define HP_RSEGMENT_PCREL 0x04 -#define HP_RSEGMENT_RDLT 0x05 -#define HP_RSEGMENT_RPLT 0x06 -#define HP_RSEGMENT_NOOP 0x3F - -#define HP_RLENGTH_BYTE 0x00 -#define HP_RLENGTH_WORD 0x01 -#define HP_RLENGTH_LONG 0x02 -#define HP_RLENGTH_ALIGN 0x03 - -#define NAME(x,y) CAT3(hp300hpux,_32_,y) -#define ARCH_SIZE 32 - -/* aoutx.h requires definitions for BMAGIC and QMAGIC. */ -#define BMAGIC HPUX_DOT_O_MAGIC -#define QMAGIC 0314 - -#include "aoutx.h" - -/* Since the hpux symbol table has nlist elements interspersed with - strings and we need to insert som strings for secondary symbols, we - give ourselves a little extra padding up front to account for - this. Note that for each non-secondary symbol we process, we gain - 9 bytes of space for the discarded nlist element (one byte used for - null). SYM_EXTRA_BYTES is the extra space. */ -#define SYM_EXTRA_BYTES 1024 - -/* Set parameters about this a.out file that are machine-dependent. - This routine is called from some_aout_object_p just before it returns. */ -static const bfd_target * -MY (callback) (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - - /* Calculate the file positions of the parts of a newly read aout header */ - obj_textsec (abfd)->_raw_size = N_TXTSIZE (*execp); - - /* The virtual memory addresses of the sections */ - obj_textsec (abfd)->vma = N_TXTADDR (*execp); - obj_datasec (abfd)->vma = N_DATADDR (*execp); - obj_bsssec (abfd)->vma = N_BSSADDR (*execp); - - obj_textsec (abfd)->lma = obj_textsec (abfd)->vma; - obj_datasec (abfd)->lma = obj_datasec (abfd)->vma; - obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma; - - /* The file offsets of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF (*execp); - obj_datasec (abfd)->filepos = N_DATOFF (*execp); - - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp); - obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp); - - /* The file offsets of the string table and symbol table. */ - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - obj_str_filepos (abfd) = N_STROFF (*execp); - - /* Determine the architecture and machine type of the object file. */ -#ifdef SET_ARCH_MACH - SET_ARCH_MACH (abfd, *execp); -#else - bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0); -#endif - - - if (obj_aout_subformat (abfd) == gnu_encap_format) - { - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp); - obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp); - - /* The file offsets of the string table and symbol table. */ - obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp); - obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms); - - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - bfd_get_symcount (abfd) = execp->a_syms / 12; - obj_symbol_entry_size (abfd) = 12; - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - } - - return abfd->xvec; -} - -extern boolean aout_32_write_syms PARAMS ((bfd * abfd)); - -static boolean -MY (write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - bfd_size_type text_size; /* dummy vars */ - file_ptr text_end; - - memset (&exec_bytes, 0, sizeof (exec_bytes)); -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE (abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - if (adata (abfd).magic == undecided_magic) - NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); - execp->a_syms = 0; - - execp->a_entry = bfd_get_start_address (abfd); - - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * - obj_reloc_entry_size (abfd)); - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * - obj_reloc_entry_size (abfd)); - - N_SET_MACHTYPE (*execp, 0xc); - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes); - - /* update fields not covered by default swap_exec_header_out */ - - /* this is really the sym table size but we store it in drelocs */ - bfd_h_put_32 (abfd, bfd_get_symcount (abfd) * 12, exec_bytes.e_drelocs); - - if (bfd_seek (abfd, 0L, false) != 0 - || (bfd_write ((PTR) & exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Write out the symbols, and then the relocs. We must write out - the symbols first so that we know the symbol indices. */ - - if (bfd_get_symcount (abfd) != 0) - { - /* Skip the relocs to where we want to put the symbols. */ - if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp) + execp->a_drsize, - SEEK_SET) != 0) - return false; - } - - if (!MY (write_syms) (abfd)) - return false; - - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (long) (N_TRELOFF (*execp)), false) != 0) - return false; - if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) - return false; - if (bfd_seek (abfd, (long) (N_DRELOFF (*execp)), false) != 0) - return false; - if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd))) - return false; - } - - return true; -} - -/* convert the hp symbol type to be the same as aout64.h usage so we */ -/* can piggyback routines in aoutx.h. */ - -static void -convert_sym_type (sym_pointer, cache_ptr, abfd) - struct external_nlist *sym_pointer; - aout_symbol_type *cache_ptr; - bfd *abfd; -{ - int name_type; - int new_type; - - name_type = (cache_ptr->type); - new_type = 0; - - if ((name_type & HP_SYMTYPE_ALIGN) != 0) - { - /* iou_error ("aligned symbol encountered: %s", name);*/ - name_type = 0; - } - - if (name_type == HP_SYMTYPE_FILENAME) - new_type = N_FN; - else - { - switch (name_type & HP_SYMTYPE_TYPE) - { - case HP_SYMTYPE_UNDEFINED: - new_type = N_UNDF; - break; - - case HP_SYMTYPE_ABSOLUTE: - new_type = N_ABS; - break; - - case HP_SYMTYPE_TEXT: - new_type = N_TEXT; - break; - - case HP_SYMTYPE_DATA: - new_type = N_DATA; - break; - - case HP_SYMTYPE_BSS: - new_type = N_BSS; - break; - - case HP_SYMTYPE_COMMON: - new_type = N_COMM; - break; - - default: - abort (); - break; - } - if (name_type & HP_SYMTYPE_EXTERNAL) - new_type |= N_EXT; - - if (name_type & HP_SECONDARY_SYMBOL) - { - switch (new_type) - { - default: - abort (); - case N_UNDF | N_EXT: - new_type = N_WEAKU; - break; - case N_ABS | N_EXT: - new_type = N_WEAKA; - break; - case N_TEXT | N_EXT: - new_type = N_WEAKT; - break; - case N_DATA | N_EXT: - new_type = N_WEAKD; - break; - case N_BSS | N_EXT: - new_type = N_WEAKB; - break; - } - } - } - cache_ptr->type = new_type; - -} - - -/* -DESCRIPTION - Swaps the information in an executable header taken from a raw - byte stream memory image, into the internal exec_header - structure. -*/ - -void -NAME (aout,swap_exec_header_in) (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *) raw_bytes; - - /* The internal_exec structure has some fields that are unused in this - configuration (IE for i960), so ensure that all such uninitialized - fields are zero'd out. There are places where two of these structs - are memcmp'd, and thus the contents do matter. */ - memset (execp, 0, sizeof (struct internal_exec)); - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); - - /***************************************************************/ - /* check the header to see if it was generated by a bfd output */ - /* this is detected rather bizarely by requiring a bunch of */ - /* header fields to be zero and an old unused field (now used) */ - /* to be set. */ - /***************************************************************/ - do - { - long syms; - struct aout_data_struct *rawptr; - if (bfd_h_get_32 (abfd, bytes->e_passize) != 0) - break; - if (bfd_h_get_32 (abfd, bytes->e_syms) != 0) - break; - if (bfd_h_get_32 (abfd, bytes->e_supsize) != 0) - break; - - syms = bfd_h_get_32 (abfd, bytes->e_drelocs); - if (syms == 0) - break; - - /* OK, we've passed the test as best as we can determine */ - execp->a_syms = syms; - - /* allocate storage for where we will store this result */ - rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (*rawptr)); - - if (rawptr == NULL) - return; - abfd->tdata.aout_data = rawptr; - obj_aout_subformat (abfd) = gnu_encap_format; - } - while (0); -} - - -/* The hp symbol table is a bit different than other a.out targets. Instead - of having an array of nlist items and an array of strings, hp's format - has them mixed together in one structure. In addition, the strings are - not null terminated. It looks something like this: - - nlist element 1 - string1 - nlist element 2 - string2 - ... - - The whole symbol table is read as one chunk and then we march thru it - and convert it to canonical form. As we march thru the table, we copy - the nlist data into the internal form and we compact the strings and null - terminate them, using storage from the already allocated symbol table: - - string1 - null - string2 - null - ... -*/ - -boolean -MY (slurp_symbol_table) (abfd) - bfd *abfd; -{ - bfd_size_type symbol_bytes; - struct external_nlist *syms; - struct external_nlist *sym_pointer; - struct external_nlist *sym_end; - char *strings; - aout_symbol_type *cached; - unsigned num_syms = 0; - - /* If there's no work to be done, don't do any */ - if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL) - return true; - symbol_bytes = exec_hdr (abfd)->a_syms; - - strings = (char *) bfd_alloc (abfd, - symbol_bytes + SYM_EXTRA_BYTES); - if (!strings) - return false; - syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES); - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || bfd_read ((PTR) syms, symbol_bytes, 1, abfd) != symbol_bytes) - { - bfd_release (abfd, syms); - return false; - } - - - sym_end = (struct external_nlist *) (((char *) syms) + symbol_bytes); - - /* first, march thru the table and figure out how many symbols there are */ - for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++, num_syms++) - { - /* skip over the embedded symbol. */ - sym_pointer = (struct external_nlist *) (((char *) sym_pointer) + - sym_pointer->e_length[0]); - } - - /* now that we know the symbol count, update the bfd header */ - bfd_get_symcount (abfd) = num_syms; - - cached = ((aout_symbol_type *) - bfd_zalloc (abfd, - bfd_get_symcount (abfd) * sizeof (aout_symbol_type))); - if (cached == NULL && bfd_get_symcount (abfd) != 0) - return false; - - /* as we march thru the hp symbol table, convert it into a list of - null terminated strings to hold the symbol names. Make sure any - assignment to the strings pointer is done after we're thru using - the nlist so we don't overwrite anything important. */ - - /* OK, now walk the new symtable, cacheing symbol properties */ - { - aout_symbol_type *cache_ptr = cached; - aout_symbol_type cache_save; - /* Run through table and copy values */ - for (sym_pointer = syms, cache_ptr = cached; - sym_pointer < sym_end; sym_pointer++, cache_ptr++) - { - unsigned int length; - cache_ptr->symbol.the_bfd = abfd; - cache_ptr->symbol.value = GET_SWORD (abfd, sym_pointer->e_value); - cache_ptr->desc = bfd_get_16 (abfd, sym_pointer->e_almod); - cache_ptr->type = bfd_get_8 (abfd, sym_pointer->e_type); - cache_ptr->symbol.udata.p = NULL; - length = bfd_get_8 (abfd, sym_pointer->e_length); - cache_ptr->other = length; /* other not used, save length here */ - - cache_save = *cache_ptr; - convert_sym_type (sym_pointer, cache_ptr, abfd); - if (!translate_from_native_sym_flags (abfd, cache_ptr)) - return false; - - /********************************************************/ - /* for hpux, the 'lenght' value indicates the length of */ - /* the symbol name which follows the nlist entry. */ - /********************************************************/ - if (length) - { - /**************************************************************/ - /* the hp string is not null terminated so we create a new one*/ - /* by copying the string to overlap the just vacated nlist */ - /* structure before it in memory. */ - /**************************************************************/ - cache_ptr->symbol.name = strings; - memcpy (strings, sym_pointer + 1, length); - strings[length] = '\0'; - strings += length + 1; - } - else - cache_ptr->symbol.name = (char *) NULL; - - /* skip over the embedded symbol. */ - sym_pointer = (struct external_nlist *) (((char *) sym_pointer) + - length); - } - } - - obj_aout_symbols (abfd) = cached; - - return true; -} - - - -void -MY (swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct hp300hpux_reloc *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern = 0; - unsigned int r_length; - int r_pcrel = 0; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - r_index = bfd_h_get_16 (abfd, bytes->r_index); - - switch (bytes->r_type[0]) - { - case HP_RSEGMENT_TEXT: - r_index = N_TEXT; - break; - case HP_RSEGMENT_DATA: - r_index = N_DATA; - break; - case HP_RSEGMENT_BSS: - r_index = N_BSS; - break; - case HP_RSEGMENT_EXTERNAL: - r_extern = 1; - break; - case HP_RSEGMENT_PCREL: - r_extern = 1; - r_pcrel = 1; - break; - case HP_RSEGMENT_RDLT: - break; - case HP_RSEGMENT_RPLT: - break; - case HP_RSEGMENT_NOOP: - break; - default: - abort (); - break; - } - - switch (bytes->r_length[0]) - { - case HP_RLENGTH_BYTE: - r_length = 0; - break; - case HP_RLENGTH_WORD: - r_length = 1; - break; - case HP_RLENGTH_LONG: - r_length = 2; - break; - default: - abort (); - break; - } - - cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel; - /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */ - - /* This macro uses the r_index value computed above */ - if (r_pcrel && r_extern) - { - /* The GNU linker assumes any offset from beginning of section */ - /* is already incorporated into the image while the HP linker */ - /* adds this in later. Add it in now... */ - MOVE_ADDRESS (-cache_ptr->address); - } - else - { - MOVE_ADDRESS (0); - } -} - -boolean -MY (slurp_reloc_table) (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - unsigned int count; - bfd_size_type reloc_size; - PTR relocs; - arelent *reloc_cache; - size_t each_size; - struct hp300hpux_reloc *rptr; - unsigned int counter; - arelent *cache_ptr; - - if (asect->relocation) - return true; - - if (asect->flags & SEC_CONSTRUCTOR) - return true; - - if (asect == obj_datasec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_drsize; - goto doit; - } - - if (asect == obj_textsec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_trsize; - goto doit; - } - - bfd_set_error (bfd_error_invalid_operation); - return false; - -doit: - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) - return false; - each_size = obj_reloc_entry_size (abfd); - - count = reloc_size / each_size; - - - reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t) (count * sizeof - (arelent))); - if (!reloc_cache && count != 0) - return false; - - relocs = (PTR) bfd_alloc (abfd, reloc_size); - if (!relocs && reloc_size != 0) - { - bfd_release (abfd, reloc_cache); - return false; - } - - if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) - { - bfd_release (abfd, relocs); - bfd_release (abfd, reloc_cache); - return false; - } - - rptr = (struct hp300hpux_reloc *) relocs; - counter = 0; - cache_ptr = reloc_cache; - - for (; counter < count; counter++, rptr++, cache_ptr++) - { - MY (swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - - - bfd_release (abfd, relocs); - asect->relocation = reloc_cache; - asect->reloc_count = count; - return true; -} - - -/************************************************************************/ -/* The following functions are identical to functions in aoutx.h except */ -/* they refer to MY(func) rather than NAME(aout,func) and they also */ -/* call aout_32 versions if the input file was generated by gcc */ -/************************************************************************/ - -long aout_32_get_symtab PARAMS ((bfd * abfd, asymbol ** location)); -long aout_32_get_symtab_upper_bound PARAMS ((bfd * abfd)); - -long aout_32_canonicalize_reloc PARAMS ((bfd * abfd, sec_ptr section, - arelent ** relptr, - asymbol ** symbols)); - -long -MY (get_symtab) (abfd, location) - bfd *abfd; - asymbol **location; -{ - unsigned int counter = 0; - aout_symbol_type *symbase; - - if (obj_aout_subformat (abfd) == gnu_encap_format) - return aout_32_get_symtab (abfd, location); - - if (!MY (slurp_symbol_table) (abfd)) - return -1; - - for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);) - *(location++) = (asymbol *) (symbase++); - *location++ = 0; - return bfd_get_symcount (abfd); -} - -long -MY (get_symtab_upper_bound) (abfd) - bfd *abfd; -{ - if (obj_aout_subformat (abfd) == gnu_encap_format) - return aout_32_get_symtab_upper_bound (abfd); - if (!MY (slurp_symbol_table) (abfd)) - return -1; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *)); -} - - - - -long -MY (canonicalize_reloc) (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count; - if (obj_aout_subformat (abfd) == gnu_encap_format) - return aout_32_canonicalize_reloc (abfd, section, relptr, symbols); - - if (!(tblptr || MY (slurp_reloc_table) (abfd, section, symbols))) - return -1; - - if (section->flags & SEC_CONSTRUCTOR) - { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - } - else - { - tblptr = section->relocation; - - for (count = 0; count++ < section->reloc_count;) - { - *relptr++ = tblptr++; - } - } - *relptr = 0; - - return section->reloc_count; -} - - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/hppa_stubs.h b/contrib/gdb/bfd/hppa_stubs.h deleted file mode 100644 index ee893e8a57b..00000000000 --- a/contrib/gdb/bfd/hppa_stubs.h +++ /dev/null @@ -1,23 +0,0 @@ -/* HPPA linker stub instructions */ - -/* These are the instructions which the linker may insert into the - code stream when building final executables to handle out-of-range - calls and argument relocations. */ - -#define LDO_M4_R31_R31 0x37ff3ff9 /* ldo -4(%r31),%r31 */ -#define LDIL_R1 0x20200000 /* ldil XXX,%r1 */ -#define BE_SR4_R1 0xe0202000 /* be XXX(%sr4,%r1) */ -#define COPY_R31_R2 0x081f0242 /* copy %r31,%r2 */ -#define BLE_SR4_R0 0xe4002000 /* ble XXX(%sr4,%r0) */ -#define BLE_SR4_R1 0xe4202000 /* ble XXX(%sr4,%r1) */ -#define BV_N_0_R31 0xebe0c002 /* bv,n 0(%r31) */ -#define STW_R31_M8R30 0x6bdf3ff1 /* stw %r31,-8(%r30) */ -#define LDW_M8R30_R31 0x4bdf3ff1 /* ldw -8(%r30),%r31 */ -#define STW_ARG_M16R30 0x6bc03fe1 /* stw %argX,-16(%r30) */ -#define LDW_M16R30_ARG 0x4bc03fe1 /* ldw -12(%r30),%argX */ -#define STW_ARG_M12R30 0x6bc03fe9 /* stw %argX,-16(%r30) */ -#define LDW_M12R30_ARG 0x4bc03fe9 /* ldw -12(%r30),%argX */ -#define FSTW_FARG_M16R30 0x27c11200 /* fstws %fargX,-16(%r30) */ -#define FLDW_M16R30_FARG 0x27c11000 /* fldws -16(%r30),%fargX */ -#define FSTD_FARG_M16R30 0x2fc11200 /* fstds %fargX,-16(%r30) */ -#define FLDD_M16R30_FARG 0x2fc11000 /* fldds -16(%r30),%fargX */ diff --git a/contrib/gdb/bfd/hppabsd-core.c b/contrib/gdb/bfd/hppabsd-core.c deleted file mode 100644 index a76ecc5aad1..00000000000 --- a/contrib/gdb/bfd/hppabsd-core.c +++ /dev/null @@ -1,305 +0,0 @@ -/* BFD back-end for HPPA BSD core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Written by the Center for Software Science at the University of Utah - and by Cygnus Support. - - The core file structure for the Utah 4.3BSD and OSF1 ports on the - PA is a mix between traditional cores and hpux cores -- just - different enough that supporting this format would tend to add - gross hacks to trad-core.c or hpux-core.c. So instead we keep any - gross hacks isolated to this file. */ - - -/* This file can only be compiled on systems which use HPPA-BSD style - core files. - - I would not expect this to be of use to any other host/target, but - you never know. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if defined (HOST_HPPABSD) - -#include "machine/vmparam.h" - -#include -#include -#include -#include -#include -#include -#include /* After a.out.h */ -#include -#include - -static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, - flagword, bfd_size_type, - file_ptr, unsigned int)); -static asymbol *hppabsd_core_make_empty_symbol PARAMS ((bfd *)); -static const bfd_target *hppabsd_core_core_file_p PARAMS ((bfd *)); -static char *hppabsd_core_core_file_failing_command PARAMS ((bfd *)); -static int hppabsd_core_core_file_failing_signal PARAMS ((bfd *)); -static boolean hppabsd_core_core_file_matches_executable_p - PARAMS ((bfd *, bfd *)); -static void swap_abort PARAMS ((void)); - -/* These are stored in the bfd's tdata. */ - -struct hppabsd_core_struct - { - int sig; - char cmd[MAXCOMLEN + 1]; - asection *data_section; - asection *stack_section; - asection *reg_section; - }; - -#define core_hdr(bfd) ((bfd)->tdata.hppabsd_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) -#define core_datasec(bfd) (core_hdr(bfd)->data_section) -#define core_stacksec(bfd) (core_hdr(bfd)->stack_section) -#define core_regsec(bfd) (core_hdr(bfd)->reg_section) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, offset, alignment_power) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - file_ptr offset; - unsigned int alignment_power; -{ - asection *asect; - - asect = bfd_make_section (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->filepos = offset; - asect->alignment_power = alignment_power; - - return asect; -} - -static asymbol * -hppabsd_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -static const bfd_target * -hppabsd_core_core_file_p (abfd) - bfd *abfd; -{ - int val; - struct user u; - struct hppabsd_core_struct *coredata; - int clicksz; - - /* Try to read in the u-area. We will need information from this - to know how to grok the rest of the core structures. */ - val = bfd_read ((void *) &u, 1, sizeof u, abfd); - if (val != sizeof u) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Get the page size out of the u structure. This will be different - for PA 1.0 machines and PA 1.1 machines. Yuk! */ - clicksz = u.u_pcb.pcb_pgsz; - - /* clicksz must be a power of two >= 2k. */ - if (clicksz < 0x800 - || clicksz != (clicksz & -clicksz)) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - - /* Sanity checks. Make sure the size of the core file matches the - the size computed from information within the core itself. */ - { - FILE *stream = bfd_cache_lookup (abfd); - struct stat statbuf; - if (stream == NULL || fstat (fileno (stream), &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size) - { - bfd_set_error (bfd_error_file_truncated); - return NULL; - } - if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size) - { - /* The file is too big. Maybe it's not a core file - or we otherwise have bad values for u_dsize and u_ssize). */ - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - coredata = (struct hppabsd_core_struct *) - bfd_zalloc (abfd, sizeof (struct hppabsd_core_struct)); - if (!coredata) - return NULL; - - /* Make the core data and available via the tdata part of the BFD. */ - abfd->tdata.hppabsd_core_data = coredata; - - /* Create the sections. */ - core_stacksec (abfd) = make_bfd_asection (abfd, ".stack", - SEC_ALLOC + SEC_HAS_CONTENTS, - clicksz * u.u_ssize, - NBPG * (USIZE + KSTAKSIZE) - + clicksz * u.u_dsize, 2); - core_stacksec (abfd)->vma = USRSTACK; - - core_datasec (abfd) = make_bfd_asection (abfd, ".data", - SEC_ALLOC + SEC_LOAD - + SEC_HAS_CONTENTS, - clicksz * u.u_dsize, - NBPG * (USIZE + KSTAKSIZE), 2); - core_datasec (abfd)->vma = UDATASEG; - - core_regsec (abfd) = make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - KSTAKSIZE * NBPG, - NBPG * USIZE, 2); - core_regsec (abfd)->vma = 0; - - strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1); - core_signal (abfd) = u.u_code; - return abfd->xvec; -} - -static char * -hppabsd_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -static int -hppabsd_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -static boolean -hppabsd_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - /* There's no way to know this... */ - return true; -} - - -#define hppabsd_core_get_symtab_upper_bound \ - _bfd_nosymbols_get_symtab_upper_bound -#define hppabsd_core_get_symtab _bfd_nosymbols_get_symtab -#define hppabsd_core_print_symbol _bfd_nosymbols_print_symbol -#define hppabsd_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define hppabsd_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define hppabsd_core_get_lineno _bfd_nosymbols_get_lineno -#define hppabsd_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define hppabsd_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define hppabsd_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define hppabsd_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -static void -swap_abort () -{ - /* This way doesn't require any declaration for ANSI to fuck up. */ - abort (); -} - -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target hppabsd_core_vec = - { - "hppabsd-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - hppabsd_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (hppabsd_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (hppabsd_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; -#endif diff --git a/contrib/gdb/bfd/hpux-core.c b/contrib/gdb/bfd/hpux-core.c deleted file mode 100644 index 675a5f8d0bd..00000000000 --- a/contrib/gdb/bfd/hpux-core.c +++ /dev/null @@ -1,270 +0,0 @@ -/* BFD back-end for HP/UX core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Stu Grossman, Cygnus Support. - Converted to back-end form by Ian Lance Taylor, Cygnus SUpport - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file can only be compiled on systems which use HP/UX style - core files. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX) - -/* FIXME: sys/core.h doesn't exist for HPUX version 7. HPUX version - 5, 6, and 7 core files seem to be standard trad-core.c type core - files; can we just use trad-core.c in addition to this file? */ - -#include -#include - -#endif /* HOST_HPPAHPUX */ - -#ifdef HOST_HPPABSD - -/* Not a very swift place to put it, but that's where the BSD port - puts them. */ -#include "/hpux/usr/include/sys/core.h" - -#endif /* HOST_HPPABSD */ - -#include -#include -#include -#include -#include -#include -#include /* After a.out.h */ -#include -#include - -/* These are stored in the bfd's tdata */ - -struct hpux_core_struct -{ - int sig; - char cmd[MAXCOMLEN + 1]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.hpux_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - unsigned int alignment_power; -{ - asection *asect; - - asect = bfd_make_section_anyway (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = bfd_tell (abfd); - asect->alignment_power = alignment_power; - - return asect; -} - -static asymbol * -hpux_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -static const bfd_target * -hpux_core_core_file_p (abfd) - bfd *abfd; -{ - core_hdr (abfd) = (struct hpux_core_struct *) - bfd_zalloc (abfd, sizeof (struct hpux_core_struct)); - if (!core_hdr (abfd)) - return NULL; - - while (1) - { - int val; - struct corehead core_header; - - val = bfd_read ((void *) &core_header, 1, sizeof core_header, abfd); - if (val <= 0) - break; - switch (core_header.type) - { - case CORE_KERNEL: - case CORE_FORMAT: - bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */ - break; - case CORE_EXEC: - { - struct proc_exec proc_exec; - if (bfd_read ((void *) &proc_exec, 1, core_header.len, abfd) - != core_header.len) - break; - strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1); - } - break; - case CORE_PROC: - { - struct proc_info proc_info; - if (!make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - core_header.len, - (int) &proc_info - (int) & proc_info.hw_regs, - 2)) - return NULL; - - if (bfd_read (&proc_info, 1, core_header.len, abfd) - != core_header.len) - break; - core_signal (abfd) = proc_info.sig; - } - break; - - case CORE_DATA: - case CORE_STACK: - case CORE_TEXT: - case CORE_MMF: - case CORE_SHM: - if (!make_bfd_asection (abfd, ".data", - SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, - core_header.len, core_header.addr, 2)) - return NULL; - - bfd_seek (abfd, core_header.len, SEEK_CUR); - break; - - default: - /* Falling into here is an error and should prevent this - target from matching. That way systems which use hpux - cores along with other formats can still work. */ - return 0; - } - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - return abfd->xvec; -} - -static char * -hpux_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -static int -hpux_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -static boolean -hpux_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -#define hpux_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define hpux_core_get_symtab _bfd_nosymbols_get_symtab -#define hpux_core_print_symbol _bfd_nosymbols_print_symbol -#define hpux_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define hpux_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define hpux_core_get_lineno _bfd_nosymbols_get_lineno -#define hpux_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define hpux_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define hpux_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define hpux_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target hpux_core_vec = - { - "hpux-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - hpux_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (hpux_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (hpux_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/i386aout.c b/contrib/gdb/bfd/i386aout.c deleted file mode 100644 index 0801832d16d..00000000000 --- a/contrib/gdb/bfd/i386aout.c +++ /dev/null @@ -1,68 +0,0 @@ -/* BFD back-end for i386 a.out binaries. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* The only 386 aout system we have here is GO32 from DJ. - These numbers make BFD work with that. If your aout 386 system - doesn't work with these, we'll have to split them into different - files. Send me (sac@cygnus.com) the runes to make it work on your - system, and I'll stick it in for the next release. */ - -#define N_HEADER_IN_TEXT(x) 0 -#define BYTES_IN_WORD 4 - -#define N_TXTOFF(x) 0x20 -#define N_TXTADDR(x) (N_MAGIC(x)==ZMAGIC ? 0x1020 : 0) - -#define N_TXTSIZE(x) ((x).a_text) -#if 0 -#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) : (SEGMENT_SIZE + ((0x1020+(x).a_text-1) & ~(SEGMENT_SIZE-1)))) -#define NOSUBEXECB - -#endif -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE 0x400000 -#define DEFAULT_ARCH bfd_arch_i386 - -#define MY(OP) CAT(i386aout_,OP) -#define TARGETNAME "a.out-i386" -#define NO_WRITE_HEADER_KLUDGE 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" -static boolean MY(set_sizes)(); -#define MY_backend_data &MY(backend_data) -static CONST struct aout_backend_data MY(backend_data) = { - 0, /* zmagic contiguous */ - 1, /* text incl header */ - 0, /* exec_hdr_flags */ - 0, /* text vma? */ - MY(set_sizes), - 1, /* exec header not counted */ - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386bsd.c b/contrib/gdb/bfd/i386bsd.c deleted file mode 100644 index 2328fe3e9e8..00000000000 --- a/contrib/gdb/bfd/i386bsd.c +++ /dev/null @@ -1,46 +0,0 @@ -/* BFD back-end for i386 a.out binaries under BSD. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This data should be correct for the format used under all the various - BSD ports for 386 machines. */ - -#define BYTES_IN_WORD 4 - -/* ZMAGIC files never have the header in the text. */ -#define N_HEADER_IN_TEXT(x) 0 - -/* ZMAGIC files start at address 0. This does not apply to QMAGIC. */ -#define TEXT_START_ADDR 0 -#define N_SHARED_LIB(x) 0 - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#define DEFAULT_ARCH bfd_arch_i386 -#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(i386bsd_,OP) -#define TARGETNAME "a.out-i386-bsd" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386dynix.c b/contrib/gdb/bfd/i386dynix.c deleted file mode 100644 index ff50a1450a1..00000000000 --- a/contrib/gdb/bfd/i386dynix.c +++ /dev/null @@ -1,80 +0,0 @@ -/* BFD back-end for i386 a.out binaries under dynix. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This BFD is currently only tested with gdb, writing object files - may not work. */ - -#define BYTES_IN_WORD 4 - -#define TEXT_START_ADDR 4096 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#include "aout/dynix3.h" - -#define DEFAULT_ARCH bfd_arch_i386 -#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(i386dynix_,OP) -#define TARGETNAME "a.out-i386-dynix" -#define NAME(x,y) CAT3(i386dynix,_32_,y) -#define ARCH_SIZE 32 -#define NAME_swap_exec_header_in NAME(i386dynix_32_,swap_exec_header_in) -#define MY_get_section_contents aout_32_get_section_contents - -/* aoutx.h requires definitions for NMAGIC, BMAGIC and QMAGIC. */ -#define NMAGIC 0 -#define BMAGIC OMAGIC -#define QMAGIC XMAGIC - -#include "aoutx.h" - -/* (Ab)use some fields in the internal exec header to be able to read - executables that contain shared data. */ - -#define a_shdata a_tload -#define a_shdrsize a_dload - -void -i386dynix_32_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* The internal_exec structure has some fields that are unused in this - configuration (IE for i960), so ensure that all such uninitialized - fields are zero'd out. There are places where two of these structs - are memcmp'd, and thus the contents do matter. */ - memset ((PTR) execp, 0, sizeof (struct internal_exec)); - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); - execp->a_shdata = GET_WORD (abfd, bytes->e_shdata); - execp->a_shdrsize = GET_WORD (abfd, bytes->e_shdrsize); -} - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386freebsd.c b/contrib/gdb/bfd/i386freebsd.c deleted file mode 100644 index 7a6371b5df6..00000000000 --- a/contrib/gdb/bfd/i386freebsd.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for FreeBSD/386 a.out-ish binaries. - Copyright (C) 1990, 1991, 1992, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#undef TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#define DEFAULT_ARCH bfd_arch_i386 -#define MACHTYPE_OK(mtype) ((mtype) == M_386_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(i386freebsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-i386-freebsd" - -#include "freebsd.h" diff --git a/contrib/gdb/bfd/i386linux.c b/contrib/gdb/bfd/i386linux.c deleted file mode 100644 index a45f97c42f8..00000000000 --- a/contrib/gdb/bfd/i386linux.c +++ /dev/null @@ -1,762 +0,0 @@ -/* BFD back-end for linux flavored i386 a.out binaries. - Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_PAGE_SIZE 4096 -#define ZMAGIC_DISK_BLOCK_SIZE 1024 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0x0 -#define N_SHARED_LIB(x) 0 -#define BYTES_IN_WORD 4 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#define DEFAULT_ARCH bfd_arch_i386 -#define MY(OP) CAT(i386linux_,OP) -#define TARGETNAME "a.out-i386-linux" - -extern const bfd_target MY(vec); - -/* We always generate QMAGIC files in preference to ZMAGIC files. It - would be possible to make this a linker option, if that ever - becomes important. */ - -static void MY_final_link_callback - PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); - -static boolean -i386linux_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - obj_aout_subformat (abfd) = q_magic_format; - return NAME(aout,final_link) (abfd, info, MY_final_link_callback); -} - -#define MY_bfd_final_link i386linux_bfd_final_link - -/* Set the machine type correctly. */ - -static boolean -i386linux_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - N_SET_MACHTYPE (*execp, M_386); - - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - WRITE_HEADERS(abfd, execp); - - return true; -} - -#define MY_write_object_contents i386linux_write_object_contents - -/* Code to link against Linux a.out shared libraries. */ - -/* See if a symbol name is a reference to the global offset table. */ - -#ifndef GOT_REF_PREFIX -#define GOT_REF_PREFIX "__GOT_" -#endif - -#define IS_GOT_SYM(name) \ - (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0) - -/* See if a symbol name is a reference to the procedure linkage table. */ - -#ifndef PLT_REF_PREFIX -#define PLT_REF_PREFIX "__PLT_" -#endif - -#define IS_PLT_SYM(name) \ - (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0) - -/* This string is used to generate specialized error messages. */ - -#ifndef NEEDS_SHRLIB -#define NEEDS_SHRLIB "__NEEDS_SHRLIB_" -#endif - -/* This special symbol is a set vector that contains a list of - pointers to fixup tables. It will be present in any dynamicly - linked file. The linker generated fixup table should also be added - to the list, and it should always appear in the second slot (the - first one is a dummy with a magic number that is defined in - crt0.o). */ - -#ifndef SHARABLE_CONFLICTS -#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__" -#endif - -/* We keep a list of fixups. The terminology is a bit strange, but - each fixup contains two 32 bit numbers. A regular fixup contains - an address and a pointer, and at runtime we should store the - address at the location pointed to by the pointer. A builtin fixup - contains two pointers, and we should read the address using one - pointer and store it at the location pointed to by the other - pointer. Builtin fixups come into play when we have duplicate - __GOT__ symbols for the same variable. The builtin fixup will copy - the GOT pointer from one over into the other. */ - -struct fixup -{ - struct fixup *next; - struct linux_link_hash_entry *h; - bfd_vma value; - - /* Nonzero if this is a jump instruction that needs to be fixed, - zero if this is just a pointer */ - char jump; - - char builtin; -}; - -/* We don't need a special hash table entry structure, but we do need - to keep some information between linker passes, so we use a special - hash table. */ - -struct linux_link_hash_entry -{ - struct aout_link_hash_entry root; -}; - -struct linux_link_hash_table -{ - struct aout_link_hash_table root; - - /* First dynamic object found in link. */ - bfd *dynobj; - - /* Number of fixups. */ - size_t fixup_count; - - /* Number of builtin fixups. */ - size_t local_builtins; - - /* List of fixups. */ - struct fixup *fixup_list; -}; - -static struct bfd_hash_entry *linux_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *linux_link_hash_table_create - PARAMS ((bfd *)); -static struct fixup *new_fixup - PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *, - bfd_vma, int)); -static boolean linux_link_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean linux_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); -static boolean linux_tally_symbols - PARAMS ((struct linux_link_hash_entry *, PTR)); -static boolean linux_finish_dynamic_link - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Routine to create an entry in an Linux link hash table. */ - -static struct bfd_hash_entry * -linux_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct linux_link_hash_entry *) NULL) - ret = ((struct linux_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry))); - if (ret == NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct linux_link_hash_entry *) - NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields; there aren't any. */ - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a Linux link hash table. */ - -static struct bfd_link_hash_table * -linux_link_hash_table_create (abfd) - bfd *abfd; -{ - struct linux_link_hash_table *ret; - - ret = ((struct linux_link_hash_table *) - bfd_alloc (abfd, sizeof (struct linux_link_hash_table))); - if (ret == (struct linux_link_hash_table *) NULL) - return (struct bfd_link_hash_table *) NULL; - if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, - linux_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->dynobj = NULL; - ret->fixup_count = 0; - ret->local_builtins = 0; - ret->fixup_list = NULL; - - return &ret->root.root; -} - -/* Look up an entry in a Linux link hash table. */ - -#define linux_link_hash_lookup(table, string, create, copy, follow) \ - ((struct linux_link_hash_entry *) \ - aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse a Linux link hash table. */ - -#define linux_link_hash_traverse(table, func, info) \ - (aout_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the Linux link hash table from the info structure. This is - just a cast. */ - -#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash)) - -/* Store the information for a new fixup. */ - -static struct fixup * -new_fixup (info, h, value, builtin) - struct bfd_link_info *info; - struct linux_link_hash_entry *h; - bfd_vma value; - int builtin; -{ - struct fixup *f; - - f = (struct fixup *) bfd_hash_allocate (&info->hash->table, - sizeof (struct fixup)); - if (f == NULL) - return f; - f->next = linux_hash_table (info)->fixup_list; - linux_hash_table (info)->fixup_list = f; - f->h = h; - f->value = value; - f->builtin = builtin; - f->jump = 0; - ++linux_hash_table (info)->fixup_count; - return f; -} - -/* We come here once we realize that we are going to link to a shared - library. We need to create a special section that contains the - fixup table, and we ultimately need to add a pointer to this into - the set vector for SHARABLE_CONFLICTS. At this point we do not - know the size of the section, but that's OK - we just need to - create it for now. */ - -static boolean -linux_link_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - - /* Note that we set the SEC_IN_MEMORY flag. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* We choose to use the name ".linux-dynamic" for the fixup table. - Why not? */ - s = bfd_make_section (abfd, ".linux-dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - s->_raw_size = 0; - s->contents = 0; - - return true; -} - -/* Function to add a single symbol to the linker hash table. This is - a wrapper around _bfd_generic_link_add_one_symbol which handles the - tweaking needed for dynamic linking support. */ - -static boolean -linux_add_one_symbol (info, abfd, name, flags, section, value, string, - copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct linux_link_hash_entry *h; - boolean insert; - - /* Look up and see if we already have this symbol in the hash table. - If we do, and the defining entry is from a shared library, we - need to create the dynamic sections. - - FIXME: What if abfd->xvec != info->hash->creator? We may want to - be able to link Linux a.out and ELF objects together, but serious - confusion is possible. */ - - insert = false; - - if (! info->relocateable - && linux_hash_table (info)->dynobj == NULL - && strcmp (name, SHARABLE_CONFLICTS) == 0 - && (flags & BSF_CONSTRUCTOR) != 0 - && abfd->xvec == info->hash->creator) - { - if (! linux_link_create_dynamic_sections (abfd, info)) - return false; - linux_hash_table (info)->dynobj = abfd; - insert = true; - } - - if (bfd_is_abs_section (section) - && abfd->xvec == info->hash->creator) - { - h = linux_link_hash_lookup (linux_hash_table (info), name, false, - false, false); - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - struct fixup *f; - - if (hashp != NULL) - *hashp = (struct bfd_link_hash_entry *) h; - - f = new_fixup (info, h, value, ! IS_PLT_SYM (name)); - if (f == NULL) - return false; - f->jump = IS_PLT_SYM (name); - - return true; - } - } - - /* Do the usual procedure for adding a symbol. */ - if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp)) - return false; - - /* Insert a pointer to our table in the set vector. The dynamic - linker requires this information */ - if (insert) - { - asection *s; - - /* Here we do our special thing to add the pointer to the - dynamic section in the SHARABLE_CONFLICTS set vector. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - - if (! (_bfd_generic_link_add_one_symbol - (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS, - BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL))) - return false; - } - - return true; -} - -/* We will crawl the hash table and come here for every global symbol. - We will examine each entry and see if there are indications that we - need to add a fixup. There are two possible cases - one is where - you have duplicate definitions of PLT or GOT symbols - these will - have already been caught and added as "builtin" fixups. If we find - that the corresponding non PLT/GOT symbol is also present, we - convert it to a regular fixup instead. - - This function is called via linux_link_hash_traverse. */ - -static boolean -linux_tally_symbols (h, data) - struct linux_link_hash_entry *h; - PTR data; -{ - struct bfd_link_info *info = (struct bfd_link_info *) data; - struct fixup *f, *f1; - int is_plt; - struct linux_link_hash_entry *h1, *h2; - boolean exists; - - if (h->root.root.type == bfd_link_hash_undefined - && strncmp (h->root.root.root.string, NEEDS_SHRLIB, - sizeof NEEDS_SHRLIB - 1) == 0) - { - const char *name; - char *p; - char *alloc = NULL; - - name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1; - p = strrchr (name, '_'); - if (p != NULL) - alloc = (char *) bfd_malloc (strlen (name) + 1); - - if (p == NULL || alloc == NULL) - (*_bfd_error_handler) ("Output file requires shared library `%s'\n", - name); - else - { - strcpy (alloc, name); - p = strrchr (alloc, '_'); - *p++ = '\0'; - (*_bfd_error_handler) - ("Output file requires shared library `%s.so.%s'\n", - alloc, p); - free (alloc); - } - - abort (); - } - - /* If this symbol is not a PLT/GOT, we do not even need to look at it */ - is_plt = IS_PLT_SYM (h->root.root.root.string); - - if (is_plt || IS_GOT_SYM (h->root.root.root.string)) - { - /* Look up this symbol twice. Once just as a regular lookup, - and then again following all of the indirect links until we - reach a real symbol. */ - h1 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, true); - /* h2 does not follow indirect symbols. */ - h2 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, false); - - /* The real symbol must exist but if it is also an ABS symbol, - there is no need to have a fixup. This is because they both - came from the same library. If on the other hand, we had to - use an indirect symbol to get to the real symbol, we add the - fixup anyway, since there are cases where these symbols come - from different shared libraries */ - if (h1 != NULL - && (((h1->root.root.type == bfd_link_hash_defined - || h1->root.root.type == bfd_link_hash_defweak) - && ! bfd_is_abs_section (h1->root.root.u.def.section)) - || h2->root.root.type == bfd_link_hash_indirect)) - { - /* See if there is a "builtin" fixup already present - involving this symbol. If so, convert it to a regular - fixup. In the end, this relaxes some of the requirements - about the order of performing fixups. */ - exists = false; - for (f1 = linux_hash_table (info)->fixup_list; - f1 != NULL; - f1 = f1->next) - { - if ((f1->h != h && f1->h != h1) - || (! f1->builtin && ! f1->jump)) - continue; - if (f1->h == h1) - exists = true; - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0); - f->jump = is_plt; - } - f1->h = h1; - f1->jump = is_plt; - f1->builtin = 0; - exists = true; - } - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, h->root.root.u.def.value, 0); - if (f == NULL) - { - /* FIXME: No way to return error. */ - abort (); - } - f->jump = is_plt; - } - } - - /* Quick and dirty way of stripping these symbols from the - symtab. */ - if (bfd_is_abs_section (h->root.root.u.def.section)) - h->root.written = true; - } - - return true; -} - -/* This is called to set the size of the .linux-dynamic section is. - It is called by the Linux linker emulation before_allocation - routine. We have finished reading all of the input files, and now - we just scan the hash tables to find out how many additional fixups - are required. */ - -boolean -bfd_i386linux_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - struct fixup *f; - asection *s; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* First find the fixups... */ - linux_link_hash_traverse (linux_hash_table (info), - linux_tally_symbols, - (PTR) info); - - /* If there are builtin fixups, leave room for a marker. This is - used by the dynamic linker so that it knows that all that follow - are builtin fixups instead of regular fixups. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - { - ++linux_hash_table (info)->fixup_count; - ++linux_hash_table (info)->local_builtins; - break; - } - } - - if (linux_hash_table (info)->dynobj == NULL) - { - if (linux_hash_table (info)->fixup_count > 0) - abort (); - return true; - } - - /* Allocate memory for our fixup table. We will fill it in later. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - if (s != NULL) - { - s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8; - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL) - return false; - memset (s->contents, 0, (size_t) s->_raw_size); - } - - return true; -} - -/* We come here once we are ready to actually write the fixup table to - the output file. Scan the fixup tables and so forth and generate - the stuff we need. */ - -static boolean -linux_finish_dynamic_link (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - asection *s, *os, *is; - bfd_byte *fixup_table; - struct linux_link_hash_entry *h; - struct fixup *f; - unsigned int new_addr; - int section_offset; - unsigned int fixups_written; - - if (linux_hash_table (info)->dynobj == NULL) - return true; - - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - os = s->output_section; - fixups_written = 0; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup table file offset: %x VMA: %x\n", - os->filepos + s->output_offset, - os->vma + s->output_offset); -#endif - - fixup_table = s->contents; - bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table); - fixup_table += 4; - - /* Fill in fixup table. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string, - new_addr, f->value); -#endif - - if (f->jump) - { - /* Relative address */ - new_addr = new_addr - (f->value + 5); - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value + 1, fixup_table); - fixup_table += 4; - } - else - { - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - } - ++fixups_written; - } - - if (linux_hash_table (info)->local_builtins != 0) - { - /* Special marker so we know to switch to the other type of fixup */ - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (! f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string, - new_addr, f->value); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - if (linux_hash_table (info)->fixup_count != fixups_written) - { - (*_bfd_error_handler) ("Warning: fixup count mismatch\n"); - while (linux_hash_table (info)->fixup_count > fixups_written) - { - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - h = linux_link_hash_lookup (linux_hash_table (info), - "__BUILTIN_FIXUPS__", - false, false, false); - - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - is = h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Builtin fixup table at %x\n", new_addr); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - } - else - bfd_put_32 (output_bfd, 0, fixup_table); - - if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0) - return false; - - if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd) - != s->_raw_size) - return false; - - return true; -} - -#define MY_bfd_link_hash_table_create linux_link_hash_table_create -#define MY_add_one_symbol linux_add_one_symbol -#define MY_finish_dynamic_link linux_finish_dynamic_link - -#define MY_zmagic_contiguous 1 - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386lynx.c b/contrib/gdb/bfd/i386lynx.c deleted file mode 100644 index 2381cff02b1..00000000000 --- a/contrib/gdb/bfd/i386lynx.c +++ /dev/null @@ -1,563 +0,0 @@ -/* BFD back-end for i386 a.out binaries under LynxOS. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#define N_SHARED_LIB(x) 0 - -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_i386 - -#define MY(OP) CAT(i386lynx_aout_,OP) -#define TARGETNAME "a.out-i386-lynx" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifndef WRITE_HEADERS -#define WRITE_HEADERS(abfd, execp) \ - { \ - bfd_size_type text_size; /* dummy vars */ \ - file_ptr text_end; \ - if (adata(abfd).magic == undecided_magic) \ - NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ - \ - execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ - execp->a_entry = bfd_get_start_address (abfd); \ - \ - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ - \ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \ - if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \ - != EXEC_BYTES_SIZE) \ - return false; \ - /* Now write out reloc info, followed by syms and strings */ \ - \ - if (bfd_get_symcount (abfd) != 0) \ - { \ - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (! NAME(aout,write_syms)(abfd)) return false; \ - \ - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \ - return false; \ - if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \ - != 0) \ - return 0; \ - \ - if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) \ - return false; \ - } \ - } -#endif - -#include "libaout.h" -#include "aout/aout64.h" - -#ifdef LYNX_CORE - -char *lynx_core_file_failing_command (); -int lynx_core_file_failing_signal (); -boolean lynx_core_file_matches_executable_p (); -const bfd_target *lynx_core_file_p (); - -#define MY_core_file_failing_command lynx_core_file_failing_command -#define MY_core_file_failing_signal lynx_core_file_failing_signal -#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p -#define MY_core_file_p lynx_core_file_p - -#endif /* LYNX_CORE */ - - -#define KEEPIT flags - -extern reloc_howto_type aout_32_ext_howto_table[]; -extern reloc_howto_type aout_32_std_howto_table[]; - -/* Standard reloc stuff */ -/* Output standard relocation information to a file in target byte order. */ - -void -NAME(lynx,swap_std_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - unsigned int r_addend; - asection *output_section = sym->section->output_section; - - PUT_WORD (abfd, g->address, natptr->r_address); - - r_length = g->howto->size; /* Size as a power of two */ - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - /* r_baserel, r_jmptable, r_relative??? FIXME-soon */ - r_baserel = 0; - r_jmptable = 0; - r_relative = 0; - - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - - if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT); - - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE); - } -} - - -/* Extended stuff */ -/* Output extended relocation information to a file in target byte order. */ - -void -NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - register struct reloc_ext_external *natptr; -{ - int r_index; - int r_extern; - unsigned int r_type; - unsigned int r_addend; - asymbol *sym = *(g->sym_ptr_ptr); - asection *output_section = sym->section->output_section; - - PUT_WORD (abfd, g->address, natptr->r_address); - - r_type = (unsigned int) g->howto->type; - - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - r_extern = 1; - r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT); - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - PUT_WORD (abfd, r_addend, natptr->r_addend); -} - -/* BFD deals internally with all things based from the section they're - in. so, something in 10 bytes into a text section with a base of - 50 would have a symbol (.text+10) and know .text vma was 50. - - Aout keeps all it's symbols based from zero, so the symbol would - contain 60. This macro subs the base of each section from the value - to give the true offset from the section */ - - -#define MOVE_ADDRESS(ad) \ - if (r_extern) { \ - /* undefined symbol */ \ - cache_ptr->sym_ptr_ptr = symbols + r_index; \ - cache_ptr->addend = ad; \ - } else { \ - /* defined, section relative. replace symbol with pointer to \ - symbol which points to section */ \ - switch (r_index) { \ - case N_TEXT: \ - case N_TEXT | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->textsec->vma; \ - break; \ - case N_DATA: \ - case N_DATA | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->datasec->vma; \ - break; \ - case N_BSS: \ - case N_BSS | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->bsssec->vma; \ - break; \ - default: \ - case N_ABS: \ - case N_ABS | N_EXT: \ - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ - cache_ptr->addend = ad; \ - break; \ - } \ - } \ - -void -NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_ext_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - unsigned int r_type; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); - - r_index = bytes->r_index[1]; - r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG; - - cache_ptr->howto = aout_32_ext_howto_table + r_type; - MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend)); -} - -void -NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - r_index = bytes->r_index[1]; - r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG)); - r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG)); - r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG)); - r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG; - - cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel; - /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */ - - MOVE_ADDRESS (0); -} - -/* Reloc hackery */ - -boolean -NAME(lynx,slurp_reloc_table) (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - unsigned int count; - bfd_size_type reloc_size; - PTR relocs; - arelent *reloc_cache; - size_t each_size; - - if (asect->relocation) - return true; - - if (asect->flags & SEC_CONSTRUCTOR) - return true; - - if (asect == obj_datasec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_drsize; - goto doit; - } - - if (asect == obj_textsec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_trsize; - goto doit; - } - - bfd_set_error (bfd_error_invalid_operation); - return false; - -doit: - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) - return false; - each_size = obj_reloc_entry_size (abfd); - - count = reloc_size / each_size; - - - reloc_cache = (arelent *) bfd_malloc (count * sizeof (arelent)); - if (!reloc_cache && count != 0) - return false; - memset (reloc_cache, 0, count * sizeof (arelent)); - - relocs = (PTR) bfd_alloc (abfd, reloc_size); - if (!relocs && reloc_size != 0) - { - free (reloc_cache); - return false; - } - - if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) - { - bfd_release (abfd, relocs); - free (reloc_cache); - return false; - } - - if (each_size == RELOC_EXT_SIZE) - { - register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs; - unsigned int counter = 0; - arelent *cache_ptr = reloc_cache; - - for (; counter < count; counter++, rptr++, cache_ptr++) - { - NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - } - else - { - register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs; - unsigned int counter = 0; - arelent *cache_ptr = reloc_cache; - - for (; counter < count; counter++, rptr++, cache_ptr++) - { - NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - - } - - bfd_release (abfd, relocs); - asect->relocation = reloc_cache; - asect->reloc_count = count; - return true; -} - - - -/* Write out a relocation section into an object file. */ - -boolean -NAME(lynx,squirt_out_relocs) (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - unsigned char *native, *natptr; - size_t each_size; - - unsigned int count = section->reloc_count; - size_t natsize; - - if (count == 0) - return true; - - each_size = obj_reloc_entry_size (abfd); - natsize = each_size * count; - native = (unsigned char *) bfd_zalloc (abfd, natsize); - if (!native) - return false; - - generic = section->orelocation; - - if (each_size == RELOC_EXT_SIZE) - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr); - } - else - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr); - } - - if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) - { - bfd_release (abfd, native); - return false; - } - bfd_release (abfd, native); - - return true; -} - -/* This is stupid. This function should be a boolean predicate */ -long -NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count; - - if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols))) - return -1; - - if (section->flags & SEC_CONSTRUCTOR) - { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - } - else - { - tblptr = section->relocation; - - for (count = 0; count++ < section->reloc_count;) - { - *relptr++ = tblptr++; - } - } - *relptr = 0; - - return section->reloc_count; -} - -#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc) - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386mach3.c b/contrib/gdb/bfd/i386mach3.c deleted file mode 100644 index 72a28f33bf0..00000000000 --- a/contrib/gdb/bfd/i386mach3.c +++ /dev/null @@ -1,65 +0,0 @@ -/* BFD back-end for i386 a.out binaries. - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This is for Mach 3, which uses a.out, not Mach-O. */ - -/* There is no magic number or anything which lets us distinguish this target - from i386aout or i386bsd. So this target is only useful if it is the - default target. */ - -#define TARGET_PAGE_SIZE 1 -#define SEGMENT_SIZE 0x1000 -#define TEXT_START_ADDR 0x10000 -#define ARCH 32 -#define BYTES_IN_WORD 4 -/* This macro is only relevant when N_MAGIC(x) == ZMAGIC. */ -#define N_HEADER_IN_TEXT(x) 1 - -#define N_TXTSIZE(x) ((x).a_text) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#define DEFAULT_ARCH bfd_arch_i386 -#define MY(OP) CAT(i386mach3_,OP) -#define TARGETNAME "a.out-mach3" - -static boolean MY(set_sizes)(); -#define MY_backend_data &MY(backend_data) -static CONST struct aout_backend_data MY(backend_data) = { - 0, /* zmagic contiguous */ - 1, /* text incl header */ - 0, /* exec_hdr_flags */ - 0, /* text vma? */ - MY(set_sizes), - 1, /* exec header not counted */ - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386msdos.c b/contrib/gdb/bfd/i386msdos.c deleted file mode 100644 index 24a456bea23..00000000000 --- a/contrib/gdb/bfd/i386msdos.c +++ /dev/null @@ -1,243 +0,0 @@ -/* BFD back-end for MS-DOS executables. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Bryan Ford of the University of Utah. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#if 0 -struct exe_header -{ - unsigned short magic; - unsigned short bytes_in_last_page; - unsigned short npages; /* number of 512-byte "pages" including this header */ - unsigned short nrelocs; - unsigned short header_paras; /* number of 16-byte paragraphs in header */ - unsigned short reserved; - unsigned short load_switch; - unsigned short ss_ofs; - unsigned short sp; - unsigned short checksum; - unsigned short ip; - unsigned short cs_ofs; - unsigned short reloc_ofs; - unsigned short reserved2; - unsigned short something1; - unsigned short something2; - unsigned short something3; -}; -#endif - -#define EXE_MAGIC 0x5a4d -#define EXE_LOAD_HIGH 0x0000 -#define EXE_LOAD_LOW 0xffff -#define EXE_PAGE_SIZE 512 - - -static int -msdos_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -static boolean -msdos_write_object_contents (abfd) - bfd *abfd; -{ - static char hdr[EXE_PAGE_SIZE]; - file_ptr outfile_size = sizeof(hdr); - bfd_vma high_vma = 0; - asection *sec; - - /* Find the total size of the program on disk and in memory. */ - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - if (bfd_get_section_size_before_reloc (sec) == 0) - continue; - if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) - { - bfd_vma sec_vma = bfd_get_section_vma (abfd, sec) - + bfd_get_section_size_before_reloc (sec); - if (sec_vma > high_vma) - high_vma = sec_vma; - } - if (bfd_get_section_flags (abfd, sec) & SEC_LOAD) - { - file_ptr sec_end = sizeof(hdr) - + bfd_get_section_vma (abfd, sec) - + bfd_get_section_size_before_reloc (sec); - if (sec_end > outfile_size) - outfile_size = sec_end; - } - } - - /* Make sure the program isn't too big. */ - if (high_vma > (bfd_vma)0xffff) - { - bfd_set_error(bfd_error_file_too_big); - return false; - } - - /* constants */ - bfd_h_put_16(abfd, EXE_MAGIC, &hdr[0]); - bfd_h_put_16(abfd, EXE_PAGE_SIZE / 16, &hdr[8]); - bfd_h_put_16(abfd, EXE_LOAD_LOW, &hdr[12]); - bfd_h_put_16(abfd, 0x3e, &hdr[24]); - bfd_h_put_16(abfd, 0x0001, &hdr[28]); /* XXX??? */ - bfd_h_put_16(abfd, 0x30fb, &hdr[30]); /* XXX??? */ - bfd_h_put_16(abfd, 0x726a, &hdr[32]); /* XXX??? */ - - /* bytes in last page (0 = full page) */ - bfd_h_put_16(abfd, outfile_size & (EXE_PAGE_SIZE - 1), &hdr[2]); - - /* number of pages */ - bfd_h_put_16(abfd, (outfile_size + EXE_PAGE_SIZE - 1) / EXE_PAGE_SIZE, - &hdr[4]); - - /* Set the initial stack pointer to the end of the bss. - The program's crt0 code must relocate it to a real stack. */ - bfd_h_put_16(abfd, high_vma, &hdr[16]); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_write (hdr, 1, sizeof(hdr), abfd) != sizeof(hdr)) - return false; - - return true; -} - -static boolean -msdos_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - - if (count == 0) - return true; - - section->filepos = EXE_PAGE_SIZE + bfd_get_section_vma (abfd, section); - - if (bfd_get_section_flags (abfd, section) & SEC_LOAD) - { - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 - || bfd_write (location, 1, count, abfd) != count) - return false; - } - - return true; -} - - - -#define msdos_mkobject aout_32_mkobject -#define msdos_make_empty_symbol aout_32_make_empty_symbol -#define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup - -#define msdos_close_and_cleanup _bfd_generic_close_and_cleanup -#define msdos_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define msdos_new_section_hook _bfd_generic_new_section_hook -#define msdos_get_section_contents _bfd_generic_get_section_contents -#define msdos_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window -#define msdos_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define msdos_bfd_relax_section bfd_generic_relax_section -#define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define msdos_bfd_final_link _bfd_generic_final_link -#define msdos_bfd_link_split_section _bfd_generic_link_split_section -#define msdos_set_arch_mach _bfd_generic_set_arch_mach - -#define msdos_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define msdos_get_symtab _bfd_nosymbols_get_symtab -#define msdos_print_symbol _bfd_nosymbols_print_symbol -#define msdos_get_symbol_info _bfd_nosymbols_get_symbol_info -#define msdos_find_nearest_line _bfd_nosymbols_find_nearest_line -#define msdos_get_lineno _bfd_nosymbols_get_lineno -#define msdos_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols -#define msdos_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -#define msdos_canonicalize_reloc _bfd_norelocs_canonicalize_reloc -#define msdos_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound -#define msdos_32_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target i386msdos_vec = -{ - "msdos", /* name */ - bfd_target_msdos_flavour, - BFD_ENDIAN_LITTLE, /* target byte order */ - BFD_ENDIAN_LITTLE, /* target headers byte order */ - (EXEC_P), /* object flags */ - (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - { - _bfd_dummy_target, - _bfd_dummy_target, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - msdos_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - msdos_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (msdos), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (msdos), - BFD_JUMP_TABLE_RELOCS (msdos), - BFD_JUMP_TABLE_WRITE (msdos), - BFD_JUMP_TABLE_LINK (msdos), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; - - diff --git a/contrib/gdb/bfd/i386netbsd.c b/contrib/gdb/bfd/i386netbsd.c deleted file mode 100644 index 32feaa70c94..00000000000 --- a/contrib/gdb/bfd/i386netbsd.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for NetBSD/386 a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#undef TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#define DEFAULT_ARCH bfd_arch_i386 -#define MACHTYPE_OK(mtype) ((mtype) == M_386_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(i386netbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-i386-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/i386os9k.c b/contrib/gdb/bfd/i386os9k.c deleted file mode 100644 index fe1a021691b..00000000000 --- a/contrib/gdb/bfd/i386os9k.c +++ /dev/null @@ -1,370 +0,0 @@ -/* BFD back-end for os9000 i386 binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "libaout.h" /* BFD a.out internal data structures */ -#include "os9k.h" - -static const bfd_target *os9k_callback PARAMS ((bfd *)); - -/* Swaps the information in an executable header taken from a raw byte - stream memory image, into the internal exec_header structure. */ -boolean -os9k_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - mh_com *raw_bytes; - struct internal_exec *execp; -{ - mh_com *bytes = (mh_com *) raw_bytes; - unsigned int dload, dmemsize, dmemstart; - - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_16 (abfd, bytes->m_sync); - execp->a_syms = 0; - execp->a_entry = bfd_h_get_32 (abfd, bytes->m_exec); - execp->a_talign = 2; - execp->a_dalign = 2; - execp->a_balign = 2; - - dload = bfd_h_get_32 (abfd, bytes->m_idata); - execp->a_data = dload + 8; - - if (bfd_seek (abfd, (file_ptr) dload, SEEK_SET) != 0 - || (bfd_read (&dmemstart, sizeof (dmemstart), 1, abfd) - != sizeof (dmemstart)) - || (bfd_read (&dmemsize, sizeof (dmemsize), 1, abfd) - != sizeof (dmemsize))) - return false; - - execp->a_tload = 0; - execp->a_dload = bfd_h_get_32 (abfd, (unsigned char *) &dmemstart); - execp->a_text = dload - execp->a_tload; - execp->a_data = bfd_h_get_32 (abfd, (unsigned char *) &dmemsize); - execp->a_bss = bfd_h_get_32 (abfd, bytes->m_data) - execp->a_data; - - execp->a_trsize = 0; - execp->a_drsize = 0; - - return true; -} - -#if 0 -/* Swaps the information in an internal exec header structure into the - supplied buffer ready for writing to disk. */ - -PROTO (void, os9k_swap_exec_header_out, - (bfd * abfd, - struct internal_exec * execp, - struct mh_com * raw_bytes)); -void -os9k_swap_exec_header_out (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - mh_com *raw_bytes; -{ - mh_com *bytes = (mh_com *) raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info, bytes->e_info); - bfd_h_put_32 (abfd, execp->a_text, bytes->e_text); - bfd_h_put_32 (abfd, execp->a_data, bytes->e_data); - bfd_h_put_32 (abfd, execp->a_bss, bytes->e_bss); - bfd_h_put_32 (abfd, execp->a_syms, bytes->e_syms); - bfd_h_put_32 (abfd, execp->a_entry, bytes->e_entry); - bfd_h_put_32 (abfd, execp->a_trsize, bytes->e_trsize); - bfd_h_put_32 (abfd, execp->a_drsize, bytes->e_drsize); - bfd_h_put_32 (abfd, execp->a_tload, bytes->e_tload); - bfd_h_put_32 (abfd, execp->a_dload, bytes->e_dload); - bytes->e_talign[0] = execp->a_talign; - bytes->e_dalign[0] = execp->a_dalign; - bytes->e_balign[0] = execp->a_balign; - bytes->e_relaxable[0] = execp->a_relaxable; -} - -#endif /* 0 */ - -static const bfd_target * -os9k_object_p (abfd) - bfd *abfd; -{ - struct internal_exec anexec; - mh_com exec_bytes; - - if (bfd_read ((PTR) & exec_bytes, MHCOM_BYTES_SIZE, 1, abfd) - != MHCOM_BYTES_SIZE) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - anexec.a_info = bfd_h_get_16 (abfd, exec_bytes.m_sync); - if (N_BADMAG (anexec)) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (! os9k_swap_exec_header_in (abfd, &exec_bytes, &anexec)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - return aout_32_some_aout_object_p (abfd, &anexec, os9k_callback); -} - - -/* Finish up the opening of a b.out file for reading. Fill in all the - fields that are not handled by common code. */ - -static const bfd_target * -os9k_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - unsigned long bss_start; - - /* Architecture and machine type */ - bfd_set_arch_mach (abfd, bfd_arch_i386, 0); - - /* The positions of the string table and symbol table. */ - obj_str_filepos (abfd) = 0; - obj_sym_filepos (abfd) = 0; - - /* The alignments of the sections */ - obj_textsec (abfd)->alignment_power = execp->a_talign; - obj_datasec (abfd)->alignment_power = execp->a_dalign; - obj_bsssec (abfd)->alignment_power = execp->a_balign; - - /* The starting addresses of the sections. */ - obj_textsec (abfd)->vma = execp->a_tload; - obj_datasec (abfd)->vma = execp->a_dload; - - /* And reload the sizes, since the aout module zaps them */ - obj_textsec (abfd)->_raw_size = execp->a_text; - - bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */ - obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); - - /* The file positions of the sections */ - obj_textsec (abfd)->filepos = execp->a_entry; - obj_datasec (abfd)->filepos = execp->a_dload; - - /* The file positions of the relocation info *** - obj_textsec (abfd)->rel_filepos = N_TROFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DROFF(*execp); - */ - - adata (abfd).page_size = 1; /* Not applicable. */ - adata (abfd).segment_size = 1;/* Not applicable. */ - adata (abfd).exec_bytes_size = MHCOM_BYTES_SIZE; - - return abfd->xvec; -} - -#if 0 -struct bout_data_struct -{ - struct aoutdata a; - struct internal_exec e; -}; - -static boolean -os9k_mkobject (abfd) - bfd *abfd; -{ - struct bout_data_struct *rawptr; - - rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct)); - if (rawptr == NULL) - return false; - - abfd->tdata.bout_data = rawptr; - exec_hdr (abfd) = &rawptr->e; - - obj_textsec (abfd) = (asection *) NULL; - obj_datasec (abfd) = (asection *) NULL; - obj_bsssec (abfd) = (asection *) NULL; - - return true; -} - -static boolean -os9k_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec swapped_hdr; - - if (! aout_32_make_sections (abfd)) - return false; - - exec_hdr (abfd)->a_info = BMAGIC; - - exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size; - exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size; - exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size; - exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist); - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - - exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power; - exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power; - exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power; - - exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma; - exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma; - - bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) & swapped_hdr, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Now write out reloc info, followed by syms and strings */ - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET) - != 0) - return false; - - if (!aout_32_write_syms (abfd)) - return false; - - if (bfd_seek (abfd, (file_ptr) (N_TROFF (*exec_hdr (abfd))), SEEK_SET) - != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) - return false; - if (bfd_seek (abfd, (file_ptr) (N_DROFF (*exec_hdr (abfd))), SEEK_SET) - != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) - return false; - } - return true; -} - -static boolean -os9k_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - unsigned char *location; - file_ptr offset; - int count; -{ - - if (abfd->output_has_begun == false) - { /* set by bfd.c handler */ - if (! aout_32_make_sections (abfd)) - return false; - - obj_textsec (abfd)->filepos = sizeof (struct internal_exec); - obj_datasec (abfd)->filepos = obj_textsec (abfd)->filepos - + obj_textsec (abfd)->_raw_size; - - } - /* regardless, once we know what we're doing, we might as well get going */ - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) - return false; - - if (count != 0) - { - return (bfd_write ((PTR) location, 1, count, abfd) == count) ? true : false; - } - return true; -} -#endif /* 0 */ - -static int -os9k_sizeof_headers (ignore_abfd, ignore) - bfd *ignore_abfd; - boolean ignore; -{ - return sizeof (struct internal_exec); -} - - -/***********************************************************************/ - -#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info - -#define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol - -#define aout_32_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define aout_32_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define os9k_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define os9k_bfd_relax_section bfd_generic_relax_section -#define os9k_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define os9k_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define os9k_bfd_final_link _bfd_generic_final_link -#define os9k_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target i386os9k_vec = -{ - "i386os9k", /* name */ - bfd_target_os9k_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* hdr byte order is little */ - (HAS_RELOC | EXEC_P | WP_TEXT), /* object flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD), /* section flags */ - 0, /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - {_bfd_dummy_target, os9k_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, bfd_false, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, bfd_false, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (aout_32), - BFD_JUMP_TABLE_WRITE (aout_32), - BFD_JUMP_TABLE_LINK (os9k), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0, -}; diff --git a/contrib/gdb/bfd/ieee.c b/contrib/gdb/bfd/ieee.c deleted file mode 100644 index 201f22515b3..00000000000 --- a/contrib/gdb/bfd/ieee.c +++ /dev/null @@ -1,3738 +0,0 @@ -/* BFD back-end for ieee-695 objects. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define KEEPMINUSPCININST 0 - -/* IEEE 695 format is a stream of records, which we parse using a simple one- - token (which is one byte in this lexicon) lookahead recursive decent - parser. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "ieee.h" -#include "libieee.h" - -static boolean ieee_write_byte PARAMS ((bfd *, bfd_byte)); -static boolean ieee_write_2bytes PARAMS ((bfd *, int)); -static boolean ieee_write_int PARAMS ((bfd *, bfd_vma)); -static boolean ieee_write_id PARAMS ((bfd *, const char *)); -static boolean ieee_write_expression - PARAMS ((bfd *, bfd_vma, asymbol *, boolean, unsigned int)); -static void ieee_write_int5 PARAMS ((bfd_byte *, bfd_vma)); -static boolean ieee_write_int5_out PARAMS ((bfd *, bfd_vma)); -static boolean ieee_write_section_part PARAMS ((bfd *)); -static boolean do_with_relocs PARAMS ((bfd *, asection *)); -static boolean do_as_repeat PARAMS ((bfd *, asection *)); -static boolean do_without_relocs PARAMS ((bfd *, asection *)); -static boolean ieee_write_external_part PARAMS ((bfd *)); -static boolean ieee_write_data_part PARAMS ((bfd *)); -static boolean ieee_write_debug_part PARAMS ((bfd *)); -static boolean ieee_write_me_part PARAMS ((bfd *)); -static boolean ieee_write_processor PARAMS ((bfd *)); - -static boolean ieee_slurp_debug PARAMS ((bfd *)); -static boolean ieee_slurp_section_data PARAMS ((bfd *)); - -/* Functions for writing to ieee files in the strange way that the - standard requires. */ - -static boolean -ieee_write_byte (abfd, byte) - bfd *abfd; - bfd_byte byte; -{ - if (bfd_write ((PTR) &byte, 1, 1, abfd) != 1) - return false; - return true; -} - -static boolean -ieee_write_2bytes (abfd, bytes) - bfd *abfd; - int bytes; -{ - bfd_byte buffer[2]; - - buffer[0] = bytes >> 8; - buffer[1] = bytes & 0xff; - if (bfd_write ((PTR) buffer, 1, 2, abfd) != 2) - return false; - return true; -} - -static boolean -ieee_write_int (abfd, value) - bfd *abfd; - bfd_vma value; -{ - if (value <= 127) - { - if (! ieee_write_byte (abfd, (bfd_byte) value)) - return false; - } - else - { - unsigned int length; - - /* How many significant bytes ? */ - /* FIXME FOR LONGER INTS */ - if (value & 0xff000000) - length = 4; - else if (value & 0x00ff0000) - length = 3; - else if (value & 0x0000ff00) - length = 2; - else - length = 1; - - if (! ieee_write_byte (abfd, - (bfd_byte) ((int) ieee_number_repeat_start_enum - + length))) - return false; - switch (length) - { - case 4: - if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24))) - return false; - /* Fall through. */ - case 3: - if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16))) - return false; - /* Fall through. */ - case 2: - if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8))) - return false; - /* Fall through. */ - case 1: - if (! ieee_write_byte (abfd, (bfd_byte) (value))) - return false; - } - } - - return true; -} - -static boolean -ieee_write_id (abfd, id) - bfd *abfd; - const char *id; -{ - size_t length = strlen (id); - - if (length <= 127) - { - if (! ieee_write_byte (abfd, (bfd_byte) length)) - return false; - } - else if (length < 255) - { - if (! ieee_write_byte (abfd, ieee_extension_length_1_enum) - || ! ieee_write_byte (abfd, (bfd_byte) length)) - return false; - } - else if (length < 65535) - { - if (! ieee_write_byte (abfd, ieee_extension_length_2_enum) - || ! ieee_write_2bytes (abfd, (int) length)) - return false; - } - else - { - (*_bfd_error_handler) - ("%s: string too long (%d chars, max 65535)", - bfd_get_filename (abfd), length); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - if (bfd_write ((PTR) id, 1, length, abfd) != length) - return false; - return true; -} - -/*************************************************************************** -Functions for reading from ieee files in the strange way that the -standard requires: -*/ - -#define this_byte(ieee) *((ieee)->input_p) -#define next_byte(ieee) ((ieee)->input_p++) -#define this_byte_and_next(ieee) (*((ieee)->input_p++)) - -static unsigned short -read_2bytes (ieee) - common_header_type *ieee; -{ - unsigned char c1 = this_byte_and_next (ieee); - unsigned char c2 = this_byte_and_next (ieee); - return (c1 << 8) | c2; -} - -static void -bfd_get_string (ieee, string, length) - common_header_type *ieee; - char *string; - size_t length; -{ - size_t i; - for (i = 0; i < length; i++) - { - string[i] = this_byte_and_next (ieee); - } -} - -static char * -read_id (ieee) - common_header_type *ieee; -{ - size_t length; - char *string; - length = this_byte_and_next (ieee); - if (length <= 0x7f) - { - /* Simple string of length 0 to 127 */ - } - else if (length == 0xde) - { - /* Length is next byte, allowing 0..255 */ - length = this_byte_and_next (ieee); - } - else if (length == 0xdf) - { - /* Length is next two bytes, allowing 0..65535 */ - length = this_byte_and_next (ieee); - length = (length * 256) + this_byte_and_next (ieee); - } - /* Buy memory and read string */ - string = bfd_alloc (ieee->abfd, length + 1); - if (!string) - return NULL; - bfd_get_string (ieee, string, length); - string[length] = 0; - return string; -} - -static boolean -ieee_write_expression (abfd, value, symbol, pcrel, index) - bfd *abfd; - bfd_vma value; - asymbol *symbol; - boolean pcrel; - unsigned int index; -{ - unsigned int term_count = 0; - - if (value != 0) - { - if (! ieee_write_int (abfd, value)) - return false; - term_count++; - } - - if (bfd_is_com_section (symbol->section) - || bfd_is_und_section (symbol->section)) - { - /* Def of a common symbol */ - if (! ieee_write_byte (abfd, ieee_variable_X_enum) - || ! ieee_write_int (abfd, symbol->value)) - return false; - term_count++; - } - else if (! bfd_is_abs_section (symbol->section)) - { - /* Ref to defined symbol - */ - - if (symbol->flags & BSF_GLOBAL) - { - if (! ieee_write_byte (abfd, ieee_variable_I_enum) - || ! ieee_write_int (abfd, symbol->value)) - return false; - term_count++; - } - else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM)) - { - /* This is a reference to a defined local symbol. We can - easily do a local as a section+offset. */ - if (! ieee_write_byte (abfd, ieee_variable_R_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (symbol->section->index - + IEEE_SECTION_NUMBER_BASE))) - return false; - term_count++; - if (symbol->value != 0) - { - if (! ieee_write_int (abfd, symbol->value)) - return false; - term_count++; - } - } - else - { - (*_bfd_error_handler) - ("%s: unrecognized symbol `%s' flags 0x%x", - bfd_get_filename (abfd), bfd_asymbol_name (symbol), - symbol->flags); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - } - - if (pcrel) - { - /* subtract the pc from here by asking for PC of this section*/ - if (! ieee_write_byte (abfd, ieee_variable_P_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (index + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_byte (abfd, ieee_function_minus_enum)) - return false; - } - - /* Handle the degenerate case of a 0 address. */ - if (term_count == 0) - { - if (! ieee_write_int (abfd, 0)) - return false; - } - - while (term_count > 1) - { - if (! ieee_write_byte (abfd, ieee_function_plus_enum)) - return false; - term_count--; - } - - return true; -} - -/*****************************************************************************/ - -/* -writes any integer into the buffer supplied and always takes 5 bytes -*/ -static void -ieee_write_int5 (buffer, value) - bfd_byte *buffer; - bfd_vma value; -{ - buffer[0] = (bfd_byte) ieee_number_repeat_4_enum; - buffer[1] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[3] = (value >> 8) & 0xff; - buffer[4] = (value >> 0) & 0xff; -} - -static boolean -ieee_write_int5_out (abfd, value) - bfd *abfd; - bfd_vma value; -{ - bfd_byte b[5]; - - ieee_write_int5 (b, value); - if (bfd_write ((PTR) b, 1, 5, abfd) != 5) - return false; - return true; -} - -static boolean -parse_int (ieee, value_ptr) - common_header_type *ieee; - bfd_vma *value_ptr; -{ - int value = this_byte (ieee); - int result; - if (value >= 0 && value <= 127) - { - *value_ptr = value; - next_byte (ieee); - return true; - } - else if (value >= 0x80 && value <= 0x88) - { - unsigned int count = value & 0xf; - result = 0; - next_byte (ieee); - while (count) - { - result = (result << 8) | this_byte_and_next (ieee); - count--; - } - *value_ptr = result; - return true; - } - return false; -} - -static int -parse_i (ieee, ok) - common_header_type *ieee; - boolean *ok; -{ - bfd_vma x; - *ok = parse_int (ieee, &x); - return x; -} - -static bfd_vma -must_parse_int (ieee) - common_header_type *ieee; -{ - bfd_vma result; - BFD_ASSERT (parse_int (ieee, &result) == true); - return result; -} - -typedef struct -{ - bfd_vma value; - asection *section; - ieee_symbol_index_type symbol; -} ieee_value_type; - - -#ifdef KEEPMINUSPCININST - -#define SRC_MASK(arg) arg -#define PCREL_OFFSET false - -#else - -#define SRC_MASK(arg) 0 -#define PCREL_OFFSET true - -#endif - -static reloc_howto_type abs32_howto = - HOWTO (1, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - 0, - "abs32", - true, - 0xffffffff, - 0xffffffff, - false); - -static reloc_howto_type abs16_howto = - HOWTO (1, - 0, - 1, - 16, - false, - 0, - complain_overflow_bitfield, - 0, - "abs16", - true, - 0x0000ffff, - 0x0000ffff, - false); - -static reloc_howto_type abs8_howto = - HOWTO (1, - 0, - 0, - 8, - false, - 0, - complain_overflow_bitfield, - 0, - "abs8", - true, - 0x000000ff, - 0x000000ff, - false); - -static reloc_howto_type rel32_howto = - HOWTO (1, - 0, - 2, - 32, - true, - 0, - complain_overflow_signed, - 0, - "rel32", - true, - SRC_MASK (0xffffffff), - 0xffffffff, - PCREL_OFFSET); - -static reloc_howto_type rel16_howto = - HOWTO (1, - 0, - 1, - 16, - true, - 0, - complain_overflow_signed, - 0, - "rel16", - true, - SRC_MASK (0x0000ffff), - 0x0000ffff, - PCREL_OFFSET); - -static reloc_howto_type rel8_howto = - HOWTO (1, - 0, - 0, - 8, - true, - 0, - complain_overflow_signed, - 0, - "rel8", - true, - SRC_MASK (0x000000ff), - 0x000000ff, - PCREL_OFFSET); - -static ieee_symbol_index_type NOSYMBOL = {0, 0}; - -static void -parse_expression (ieee, value, symbol, pcrel, extra, section) - ieee_data_type *ieee; - bfd_vma *value; - ieee_symbol_index_type *symbol; - boolean *pcrel; - unsigned int *extra; - asection **section; - -{ -#define POS sp[1] -#define TOS sp[0] -#define NOS sp[-1] -#define INC sp++; -#define DEC sp--; - - boolean loop = true; - ieee_value_type stack[10]; - - /* The stack pointer always points to the next unused location */ -#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC; -#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value; - ieee_value_type *sp = stack; - - while (loop) - { - switch (this_byte (&(ieee->h))) - { - case ieee_variable_P_enum: - /* P variable, current program counter for section n */ - { - int section_n; - next_byte (&(ieee->h)); - *pcrel = true; - section_n = must_parse_int (&(ieee->h)); - PUSH (NOSYMBOL, bfd_abs_section_ptr, 0); - break; - } - case ieee_variable_L_enum: - /* L variable address of section N */ - next_byte (&(ieee->h)); - PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); - break; - case ieee_variable_R_enum: - /* R variable, logical address of section module */ - /* FIXME, this should be different to L */ - next_byte (&(ieee->h)); - PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); - break; - case ieee_variable_S_enum: - /* S variable, size in MAUS of section module */ - next_byte (&(ieee->h)); - PUSH (NOSYMBOL, - 0, - ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size); - break; - case ieee_variable_I_enum: - /* Push the address of variable n */ - { - ieee_symbol_index_type sy; - next_byte (&(ieee->h)); - sy.index = (int) must_parse_int (&(ieee->h)); - sy.letter = 'I'; - - PUSH (sy, bfd_abs_section_ptr, 0); - } - break; - case ieee_variable_X_enum: - /* Push the address of external variable n */ - { - ieee_symbol_index_type sy; - next_byte (&(ieee->h)); - sy.index = (int) (must_parse_int (&(ieee->h))); - sy.letter = 'X'; - - PUSH (sy, bfd_und_section_ptr, 0); - } - break; - case ieee_function_minus_enum: - { - bfd_vma value1, value2; - asection *section1, *section_dummy; - ieee_symbol_index_type sy; - next_byte (&(ieee->h)); - - POP (sy, section1, value1); - POP (sy, section_dummy, value2); - PUSH (sy, section1 ? section1 : section_dummy, value2 - value1); - } - break; - case ieee_function_plus_enum: - { - bfd_vma value1, value2; - asection *section1; - asection *section2; - ieee_symbol_index_type sy1; - ieee_symbol_index_type sy2; - next_byte (&(ieee->h)); - - POP (sy1, section1, value1); - POP (sy2, section2, value2); - PUSH (sy1.letter ? sy1 : sy2, - bfd_is_abs_section (section1) ? section2 : section1, - value1 + value2); - } - break; - default: - { - bfd_vma va; - BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum - || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum); - if (parse_int (&(ieee->h), &va)) - { - PUSH (NOSYMBOL, bfd_abs_section_ptr, va); - } - else - { - /* - Thats all that we can understand. As far as I can see - there is a bug in the Microtec IEEE output which I'm - using to scan, whereby the comma operator is omitted - sometimes in an expression, giving expressions with too - many terms. We can tell if that's the case by ensuring - that sp == stack here. If not, then we've pushed - something too far, so we keep adding. */ - - while (sp != stack + 1) - { - asection *section1; - ieee_symbol_index_type sy1; - POP (sy1, section1, *extra); - } - { - asection *dummy; - - POP (*symbol, dummy, *value); - if (section) - *section = dummy; - } - - loop = false; - } - } - } - } -} - - -#define ieee_seek(abfd, offset) \ - IEEE_DATA(abfd)->h.input_p = IEEE_DATA(abfd)->h.first_byte + offset - -#define ieee_pos(abfd) \ - (IEEE_DATA(abfd)->h.input_p - IEEE_DATA(abfd)->h.first_byte) - -static unsigned int last_index; -static char last_type; /* is the index for an X or a D */ - -static ieee_symbol_type * -get_symbol (abfd, - ieee, - last_symbol, - symbol_count, - pptr, - max_index, - this_type -) - bfd *abfd; - ieee_data_type *ieee; - ieee_symbol_type *last_symbol; - unsigned int *symbol_count; - ieee_symbol_type ***pptr; - unsigned int *max_index; - char this_type - ; -{ - /* Need a new symbol */ - unsigned int new_index = must_parse_int (&(ieee->h)); - if (new_index != last_index || this_type != last_type) - { - ieee_symbol_type *new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd, - sizeof (ieee_symbol_type)); - if (!new_symbol) - return NULL; - - new_symbol->index = new_index; - last_index = new_index; - (*symbol_count)++; - **pptr = new_symbol; - *pptr = &new_symbol->next; - if (new_index > *max_index) - { - *max_index = new_index; - } - last_type = this_type; - new_symbol->symbol.section = bfd_abs_section_ptr; - return new_symbol; - } - return last_symbol; -} - -static boolean -ieee_slurp_external_symbols (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - file_ptr offset = ieee->w.r.external_part; - - ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols; - ieee_symbol_type **prev_reference_ptr = &ieee->external_reference; - ieee_symbol_type *symbol = (ieee_symbol_type *) NULL; - unsigned int symbol_count = 0; - boolean loop = true; - last_index = 0xffffff; - ieee->symbol_table_full = true; - - ieee_seek (abfd, offset); - - while (loop) - { - switch (this_byte (&(ieee->h))) - { - case ieee_nn_record: - next_byte (&(ieee->h)); - - symbol = get_symbol (abfd, ieee, symbol, &symbol_count, - &prev_symbols_ptr, - &ieee->external_symbol_max_index, 'I'); - if (symbol == NULL) - return false; - - symbol->symbol.the_bfd = abfd; - symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata.p = (PTR) NULL; - symbol->symbol.flags = BSF_NO_FLAGS; - break; - case ieee_external_symbol_enum: - next_byte (&(ieee->h)); - - symbol = get_symbol (abfd, ieee, symbol, &symbol_count, - &prev_symbols_ptr, - &ieee->external_symbol_max_index, 'D'); - if (symbol == NULL) - return false; - - BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index); - - symbol->symbol.the_bfd = abfd; - symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata.p = (PTR) NULL; - symbol->symbol.flags = BSF_NO_FLAGS; - break; - case ieee_attribute_record_enum >> 8: - { - unsigned int symbol_name_index; - unsigned int symbol_type_index; - unsigned int symbol_attribute_def; - bfd_vma value; - switch (read_2bytes (ieee)) - { - case ieee_attribute_record_enum: - symbol_name_index = must_parse_int (&(ieee->h)); - symbol_type_index = must_parse_int (&(ieee->h)); - symbol_attribute_def = must_parse_int (&(ieee->h)); - switch (symbol_attribute_def) - { - case 8: - case 19: - parse_int (&ieee->h, &value); - break; - default: - (*_bfd_error_handler) - ("%s: unimplemented ATI record %u for symbol %u", - bfd_get_filename (abfd), symbol_attribute_def, - symbol_name_index); - bfd_set_error (bfd_error_bad_value); - return false; - break; - } - break; - case ieee_external_reference_info_record_enum: - /* Skip over ATX record. */ - parse_int (&(ieee->h), &value); - parse_int (&(ieee->h), &value); - parse_int (&(ieee->h), &value); - parse_int (&(ieee->h), &value); - break; - } - } - break; - case ieee_value_record_enum >> 8: - { - unsigned int symbol_name_index; - ieee_symbol_index_type symbol_ignore; - boolean pcrel_ignore; - unsigned int extra; - next_byte (&(ieee->h)); - next_byte (&(ieee->h)); - - symbol_name_index = must_parse_int (&(ieee->h)); - parse_expression (ieee, - &symbol->symbol.value, - &symbol_ignore, - &pcrel_ignore, - &extra, - &symbol->symbol.section); - - symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT; - - } - break; - case ieee_weak_external_reference_enum: - { - bfd_vma size; - bfd_vma value; - next_byte (&(ieee->h)); - /* Throw away the external reference index */ - (void) must_parse_int (&(ieee->h)); - /* Fetch the default size if not resolved */ - size = must_parse_int (&(ieee->h)); - /* Fetch the defautlt value if available */ - if (parse_int (&(ieee->h), &value) == false) - { - value = 0; - } - /* This turns into a common */ - symbol->symbol.section = bfd_com_section_ptr; - symbol->symbol.value = size; - } - break; - - case ieee_external_reference_enum: - next_byte (&(ieee->h)); - - symbol = get_symbol (abfd, ieee, symbol, &symbol_count, - &prev_reference_ptr, - &ieee->external_reference_max_index, 'X'); - if (symbol == NULL) - return false; - - symbol->symbol.the_bfd = abfd; - symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata.p = (PTR) NULL; - symbol->symbol.section = bfd_und_section_ptr; - symbol->symbol.value = (bfd_vma) 0; - symbol->symbol.flags = 0; - - BFD_ASSERT (symbol->index >= ieee->external_reference_min_index); - break; - - default: - loop = false; - } - } - - if (ieee->external_symbol_max_index != 0) - { - ieee->external_symbol_count = - ieee->external_symbol_max_index - - ieee->external_symbol_min_index + 1; - } - else - { - ieee->external_symbol_count = 0; - } - - if (ieee->external_reference_max_index != 0) - { - ieee->external_reference_count = - ieee->external_reference_max_index - - ieee->external_reference_min_index + 1; - } - else - { - ieee->external_reference_count = 0; - } - - abfd->symcount = - ieee->external_reference_count + ieee->external_symbol_count; - - if (symbol_count != abfd->symcount) - { - /* There are gaps in the table -- */ - ieee->symbol_table_full = false; - } - - *prev_symbols_ptr = (ieee_symbol_type *) NULL; - *prev_reference_ptr = (ieee_symbol_type *) NULL; - - return true; -} - -static boolean -ieee_slurp_symbol_table (abfd) - bfd *abfd; -{ - if (IEEE_DATA (abfd)->read_symbols == false) - { - if (! ieee_slurp_external_symbols (abfd)) - return false; - IEEE_DATA (abfd)->read_symbols = true; - } - return true; -} - -long -ieee_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - if (! ieee_slurp_symbol_table (abfd)) - return -1; - - return (abfd->symcount != 0) ? - (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0; -} - -/* -Move from our internal lists to the canon table, and insert in -symbol index order -*/ - -extern const bfd_target ieee_vec; - -long -ieee_get_symtab (abfd, location) - bfd *abfd; - asymbol **location; -{ - ieee_symbol_type *symp; - static bfd dummy_bfd; - static asymbol empty_symbol = - /* the_bfd, name, value, attr, section */ - {&dummy_bfd, " ieee empty", (symvalue) 0, BSF_DEBUGGING, bfd_abs_section_ptr}; - - if (abfd->symcount) - { - ieee_data_type *ieee = IEEE_DATA (abfd); - dummy_bfd.xvec = &ieee_vec; - if (! ieee_slurp_symbol_table (abfd)) - return -1; - - if (ieee->symbol_table_full == false) - { - /* Arrgh - there are gaps in the table, run through and fill them */ - /* up with pointers to a null place */ - unsigned int i; - for (i = 0; i < abfd->symcount; i++) - { - location[i] = &empty_symbol; - } - } - - ieee->external_symbol_base_offset = -ieee->external_symbol_min_index; - for (symp = IEEE_DATA (abfd)->external_symbols; - symp != (ieee_symbol_type *) NULL; - symp = symp->next) - { - /* Place into table at correct index locations */ - location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol; - } - - /* The external refs are indexed in a bit */ - ieee->external_reference_base_offset = - -ieee->external_reference_min_index + ieee->external_symbol_count; - - for (symp = IEEE_DATA (abfd)->external_reference; - symp != (ieee_symbol_type *) NULL; - symp = symp->next) - { - location[symp->index + ieee->external_reference_base_offset] = - &symp->symbol; - - } - } - if (abfd->symcount) - { - location[abfd->symcount] = (asymbol *) NULL; - } - return abfd->symcount; -} - -static asection * -get_section_entry (abfd, ieee, index) - bfd *abfd; - ieee_data_type *ieee; - unsigned int index; -{ - if (ieee->section_table[index] == (asection *) NULL) - { - char *tmp = bfd_alloc (abfd, 11); - asection *section; - - if (!tmp) - return NULL; - sprintf (tmp, " fsec%4d", index); - section = bfd_make_section (abfd, tmp); - ieee->section_table[index] = section; - section->flags = SEC_NO_FLAGS; - section->target_index = index; - ieee->section_table[index] = section; - } - return ieee->section_table[index]; -} - -static void -ieee_slurp_sections (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - file_ptr offset = ieee->w.r.section_part; - asection *section = (asection *) NULL; - char *name; - - if (offset != 0) - { - bfd_byte section_type[3]; - ieee_seek (abfd, offset); - while (true) - { - switch (this_byte (&(ieee->h))) - { - case ieee_section_type_enum: - { - unsigned int section_index; - next_byte (&(ieee->h)); - section_index = must_parse_int (&(ieee->h)); - /* Fixme to be nice about a silly number of sections */ - BFD_ASSERT (section_index < NSECTIONS); - - section = get_section_entry (abfd, ieee, section_index); - - section_type[0] = this_byte_and_next (&(ieee->h)); - - /* Set minimal section attributes. Attributes are - extended later, based on section contents. */ - - switch (section_type[0]) - { - case 0xC1: - /* Normal attributes for absolute sections */ - section_type[1] = this_byte (&(ieee->h)); - section->flags = SEC_ALLOC; - switch (section_type[1]) - { - case 0xD3: /* AS Absolute section attributes */ - next_byte (&(ieee->h)); - section_type[2] = this_byte (&(ieee->h)); - switch (section_type[2]) - { - case 0xD0: - /* Normal code */ - next_byte (&(ieee->h)); - section->flags |= SEC_CODE; - break; - case 0xC4: - /* Normal data */ - next_byte (&(ieee->h)); - section->flags |= SEC_DATA; - break; - case 0xD2: - next_byte (&(ieee->h)); - /* Normal rom data */ - section->flags |= SEC_ROM | SEC_DATA; - break; - default: - break; - } - } - break; - case 0xC3: /* Named relocatable sections (type C) */ - section_type[1] = this_byte (&(ieee->h)); - section->flags = SEC_ALLOC; - switch (section_type[1]) - { - case 0xD0: /* Normal code (CP) */ - next_byte (&(ieee->h)); - section->flags |= SEC_CODE; - break; - case 0xC4: /* Normal data (CD) */ - next_byte (&(ieee->h)); - section->flags |= SEC_DATA; - break; - case 0xD2: /* Normal rom data (CR) */ - next_byte (&(ieee->h)); - section->flags |= SEC_ROM | SEC_DATA; - break; - default: - break; - } - } - - /* Read section name, use it if non empty. */ - name = read_id (&ieee->h); - if (name[0]) - section->name = name; - - /* Skip these fields, which we don't care about */ - { - bfd_vma parent, brother, context; - parse_int (&(ieee->h), &parent); - parse_int (&(ieee->h), &brother); - parse_int (&(ieee->h), &context); - } - } - break; - case ieee_section_alignment_enum: - { - unsigned int section_index; - bfd_vma value; - asection *section; - next_byte (&(ieee->h)); - section_index = must_parse_int (&ieee->h); - section = get_section_entry (abfd, ieee, section_index); - if (section_index > ieee->section_count) - { - ieee->section_count = section_index; - } - section->alignment_power = - bfd_log2 (must_parse_int (&ieee->h)); - (void) parse_int (&(ieee->h), &value); - } - break; - case ieee_e2_first_byte_enum: - { - ieee_record_enum_type t = (ieee_record_enum_type) (read_2bytes (&(ieee->h))); - - switch (t) - { - case ieee_section_size_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->_raw_size = must_parse_int (&(ieee->h)); - break; - case ieee_physical_region_size_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->_raw_size = must_parse_int (&(ieee->h)); - break; - case ieee_region_base_address_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->vma = must_parse_int (&(ieee->h)); - section->lma = section->vma; - break; - case ieee_mau_size_enum: - must_parse_int (&(ieee->h)); - must_parse_int (&(ieee->h)); - break; - case ieee_m_value_enum: - must_parse_int (&(ieee->h)); - must_parse_int (&(ieee->h)); - break; - case ieee_section_base_address_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->vma = must_parse_int (&(ieee->h)); - section->lma = section->vma; - break; - case ieee_section_offset_enum: - (void) must_parse_int (&(ieee->h)); - (void) must_parse_int (&(ieee->h)); - break; - default: - return; - } - } - break; - default: - return; - } - } - } -} - -/* Make a section for the debugging information, if any. We don't try - to interpret the debugging information; we just point the section - at the area in the file so that program which understand can dig it - out. */ - -static boolean -ieee_slurp_debug (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - asection *sec; - - if (ieee->w.r.debug_information_part == 0) - return true; - - sec = bfd_make_section (abfd, ".debug"); - if (sec == NULL) - return false; - sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS; - sec->filepos = ieee->w.r.debug_information_part; - sec->_raw_size = ieee->w.r.data_part - ieee->w.r.debug_information_part; - - return true; -} - -/*********************************************************************** -* archive stuff -*/ - -const bfd_target * -ieee_archive_p (abfd) - bfd *abfd; -{ - char *library; - boolean loop; - unsigned int i; - unsigned char buffer[512]; - file_ptr buffer_offset = 0; - ieee_ar_data_type *save = abfd->tdata.ieee_ar_data; - ieee_ar_data_type *ieee; - abfd->tdata.ieee_ar_data = (ieee_ar_data_type *) bfd_alloc (abfd, sizeof (ieee_ar_data_type)); - if (!abfd->tdata.ieee_ar_data) - return NULL; - ieee = IEEE_AR_DATA (abfd); - - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - - ieee->h.first_byte = buffer; - ieee->h.input_p = buffer; - - ieee->h.abfd = abfd; - - if (this_byte (&(ieee->h)) != Module_Beginning) - { - abfd->tdata.ieee_ar_data = save; - return (const bfd_target *) NULL; - } - - next_byte (&(ieee->h)); - library = read_id (&(ieee->h)); - if (strcmp (library, "LIBRARY") != 0) - { - bfd_release (abfd, ieee); - abfd->tdata.ieee_ar_data = save; - return (const bfd_target *) NULL; - } - /* Throw away the filename */ - read_id (&(ieee->h)); - - ieee->element_count = 0; - ieee->element_index = 0; - - next_byte (&(ieee->h)); /* Drop the ad part */ - must_parse_int (&(ieee->h)); /* And the two dummy numbers */ - must_parse_int (&(ieee->h)); - - loop = true; - /* Read the index of the BB table */ - while (loop) - { - ieee_ar_obstack_type t; - int rec = read_2bytes (&(ieee->h)); - if (rec == (int) ieee_assign_value_to_variable_enum) - { - must_parse_int (&(ieee->h)); - t.file_offset = must_parse_int (&(ieee->h)); - t.abfd = (bfd *) NULL; - ieee->element_count++; - - bfd_alloc_grow (abfd, (PTR) &t, sizeof t); - - /* Make sure that we don't go over the end of the buffer */ - - if ((size_t) ieee_pos (abfd) > sizeof (buffer) / 2) - { - /* Past half way, reseek and reprime */ - buffer_offset += ieee_pos (abfd); - if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0) - return NULL; - /* FIXME: Check return value. I'm not sure whether it - needs to read the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - ieee->h.first_byte = buffer; - ieee->h.input_p = buffer; - } - } - else - loop = false; - } - - ieee->elements = (ieee_ar_obstack_type *) bfd_alloc_finish (abfd); - if (!ieee->elements) - return (const bfd_target *) NULL; - - /* Now scan the area again, and replace BB offsets with file */ - /* offsets */ - - for (i = 2; i < ieee->element_count; i++) - { - if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0) - return NULL; - /* FIXME: Check return value. I'm not sure whether it needs to - read the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - ieee->h.first_byte = buffer; - ieee->h.input_p = buffer; - - next_byte (&(ieee->h)); /* Drop F8 */ - next_byte (&(ieee->h)); /* Drop 14 */ - must_parse_int (&(ieee->h)); /* Drop size of block */ - if (must_parse_int (&(ieee->h)) != 0) - { - /* This object has been deleted */ - ieee->elements[i].file_offset = 0; - } - else - { - ieee->elements[i].file_offset = must_parse_int (&(ieee->h)); - } - } - -/* abfd->has_armap = ;*/ - return abfd->xvec; -} - -static boolean -ieee_mkobject (abfd) - bfd *abfd; -{ - abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, sizeof (ieee_data_type)); - return abfd->tdata.ieee_data ? true : false; -} - -const bfd_target * -ieee_object_p (abfd) - bfd *abfd; -{ - char *processor; - unsigned int part; - ieee_data_type *ieee; - unsigned char buffer[300]; - ieee_data_type *save = IEEE_DATA (abfd); - - abfd->tdata.ieee_data = 0; - ieee_mkobject (abfd); - - ieee = IEEE_DATA (abfd); - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto fail; - /* Read the first few bytes in to see if it makes sense */ - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - - ieee->h.input_p = buffer; - if (this_byte_and_next (&(ieee->h)) != Module_Beginning) - goto got_wrong_format; - - ieee->read_symbols = false; - ieee->read_data = false; - ieee->section_count = 0; - ieee->external_symbol_max_index = 0; - ieee->external_symbol_min_index = IEEE_PUBLIC_BASE; - ieee->external_reference_min_index = IEEE_REFERENCE_BASE; - ieee->external_reference_max_index = 0; - ieee->h.abfd = abfd; - memset ((PTR) ieee->section_table, 0, sizeof (ieee->section_table)); - - processor = ieee->mb.processor = read_id (&(ieee->h)); - if (strcmp (processor, "LIBRARY") == 0) - goto got_wrong_format; - ieee->mb.module_name = read_id (&(ieee->h)); - if (abfd->filename == (CONST char *) NULL) - { - abfd->filename = ieee->mb.module_name; - } - /* Determine the architecture and machine type of the object file. - */ - { - const bfd_arch_info_type *arch = bfd_scan_arch (processor); - if (arch == 0) - goto got_wrong_format; - abfd->arch_info = arch; - } - - if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum) - { - goto fail; - } - next_byte (&(ieee->h)); - - if (parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau) == false) - { - goto fail; - } - if (parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address) == false) - { - goto fail; - } - - /* If there is a byte order info, take it */ - if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum || - this_byte (&(ieee->h)) == (int) ieee_variable_M_enum) - next_byte (&(ieee->h)); - - for (part = 0; part < N_W_VARIABLES; part++) - { - boolean ok; - if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum) - { - goto fail; - } - if (this_byte_and_next (&(ieee->h)) != part) - { - goto fail; - } - - ieee->w.offset[part] = parse_i (&(ieee->h), &ok); - if (ok == false) - { - goto fail; - } - - } - - if (ieee->w.r.external_part != 0) - abfd->flags = HAS_SYMS; - - /* By now we know that this is a real IEEE file, we're going to read - the whole thing into memory so that we can run up and down it - quickly. We can work out how big the file is from the trailer - record */ - - IEEE_DATA (abfd)->h.first_byte = - (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record + 1); - if (!IEEE_DATA (abfd)->h.first_byte) - goto fail; - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto fail; - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1, - ieee->w.r.me_record + 1, abfd); - - ieee_slurp_sections (abfd); - - if (! ieee_slurp_debug (abfd)) - goto fail; - - /* Parse section data to activate file and section flags implied by - section contents. */ - - if (! ieee_slurp_section_data (abfd)) - goto fail; - - return abfd->xvec; -got_wrong_format: - bfd_set_error (bfd_error_wrong_format); -fail: - (void) bfd_release (abfd, ieee); - abfd->tdata.ieee_data = save; - return (const bfd_target *) NULL; -} - -void -ieee_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); - if (symbol->name[0] == ' ') - ret->name = "* empty table entry "; - if (!symbol->section) - ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; -} - -void -ieee_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: -#if 0 - fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff, - aout_symbol (symbol)->other & 0xff); -#endif - BFD_FAIL (); - break; - case bfd_print_symbol_all: - { - const char *section_name = - (symbol->section == (asection *) NULL - ? "*abs" - : symbol->section->name); - if (symbol->name[0] == ' ') - { - fprintf (file, "* empty table entry "); - } - else - { - bfd_print_symbol_vandf ((PTR) file, symbol); - - fprintf (file, " %-5s %04x %02x %s", - section_name, - (unsigned) ieee_symbol (symbol)->index, - (unsigned) 0, - symbol->name); - } - } - break; - } -} - -static boolean -do_one (ieee, current_map, location_ptr, s, iterations) - ieee_data_type *ieee; - ieee_per_section_type *current_map; - unsigned char *location_ptr; - asection *s; - int iterations; -{ - switch (this_byte (&(ieee->h))) - { - case ieee_load_constant_bytes_enum: - { - unsigned int number_of_maus; - unsigned int i; - next_byte (&(ieee->h)); - number_of_maus = must_parse_int (&(ieee->h)); - - for (i = 0; i < number_of_maus; i++) - { - location_ptr[current_map->pc++] = this_byte (&(ieee->h)); - next_byte (&(ieee->h)); - } - } - break; - - case ieee_load_with_relocation_enum: - { - boolean loop = true; - next_byte (&(ieee->h)); - while (loop) - { - switch (this_byte (&(ieee->h))) - { - case ieee_variable_R_enum: - - case ieee_function_signed_open_b_enum: - case ieee_function_unsigned_open_b_enum: - case ieee_function_either_open_b_enum: - { - unsigned int extra = 4; - boolean pcrel = false; - asection *section; - ieee_reloc_type *r = - (ieee_reloc_type *) bfd_alloc (ieee->h.abfd, - sizeof (ieee_reloc_type)); - if (!r) - return false; - - *(current_map->reloc_tail_ptr) = r; - current_map->reloc_tail_ptr = &r->next; - r->next = (ieee_reloc_type *) NULL; - next_byte (&(ieee->h)); -/* abort();*/ - r->relent.sym_ptr_ptr = 0; - parse_expression (ieee, - &r->relent.addend, - &r->symbol, - &pcrel, &extra, §ion); - r->relent.address = current_map->pc; - s->flags |= SEC_RELOC; - s->owner->flags |= HAS_RELOC; - s->reloc_count++; - if (r->relent.sym_ptr_ptr == 0) - { - r->relent.sym_ptr_ptr = section->symbol_ptr_ptr; - } - - if (this_byte (&(ieee->h)) == (int) ieee_comma) - { - next_byte (&(ieee->h)); - /* Fetch number of bytes to pad */ - extra = must_parse_int (&(ieee->h)); - }; - - switch (this_byte (&(ieee->h))) - { - case ieee_function_signed_close_b_enum: - next_byte (&(ieee->h)); - break; - case ieee_function_unsigned_close_b_enum: - next_byte (&(ieee->h)); - break; - case ieee_function_either_close_b_enum: - next_byte (&(ieee->h)); - break; - default: - break; - } - /* Build a relocation entry for this type */ - /* If pc rel then stick -ve pc into instruction - and take out of reloc .. - - I've changed this. It's all too complicated. I - keep 0 in the instruction now. */ - - switch (extra) - { - case 0: - case 4: - - if (pcrel == true) - { -#if KEEPMINUSPCININST - bfd_put_32 (ieee->h.abfd, -current_map->pc, location_ptr + - current_map->pc); - r->relent.howto = &rel32_howto; - r->relent.addend -= - current_map->pc; -#else - bfd_put_32 (ieee->h.abfd, 0, location_ptr + - current_map->pc); - r->relent.howto = &rel32_howto; -#endif - } - else - { - bfd_put_32 (ieee->h.abfd, 0, location_ptr + - current_map->pc); - r->relent.howto = &abs32_howto; - } - current_map->pc += 4; - break; - case 2: - if (pcrel == true) - { -#if KEEPMINUSPCININST - bfd_put_16 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc); - r->relent.addend -= current_map->pc; - r->relent.howto = &rel16_howto; -#else - - bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &rel16_howto; -#endif - } - - else - { - bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &abs16_howto; - } - current_map->pc += 2; - break; - case 1: - if (pcrel == true) - { -#if KEEPMINUSPCININST - bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc); - r->relent.addend -= current_map->pc; - r->relent.howto = &rel8_howto; -#else - bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &rel8_howto; -#endif - } - else - { - bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &abs8_howto; - } - current_map->pc += 1; - break; - - default: - BFD_FAIL (); - return false; - } - } - break; - default: - { - bfd_vma this_size; - if (parse_int (&(ieee->h), &this_size) == true) - { - unsigned int i; - for (i = 0; i < this_size; i++) - { - location_ptr[current_map->pc++] = this_byte (&(ieee->h)); - next_byte (&(ieee->h)); - } - } - else - { - loop = false; - } - } - } - - /* Prevent more than the first load-item of an LR record - from being repeated (MRI convention). */ - if (iterations != 1) - loop = false; - } - } - } - return true; -} - -/* Read in all the section data and relocation stuff too */ -static boolean -ieee_slurp_section_data (abfd) - bfd *abfd; -{ - bfd_byte *location_ptr = (bfd_byte *) NULL; - ieee_data_type *ieee = IEEE_DATA (abfd); - unsigned int section_number; - - ieee_per_section_type *current_map = (ieee_per_section_type *) NULL; - asection *s; - /* Seek to the start of the data area */ - if (ieee->read_data == true) - return true; - ieee->read_data = true; - ieee_seek (abfd, ieee->w.r.data_part); - - /* Allocate enough space for all the section contents */ - - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd; - if ((s->flags & SEC_DEBUGGING) != 0) - continue; - per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size); - if (!per->data) - return false; - /*SUPPRESS 68*/ - per->reloc_tail_ptr = - (ieee_reloc_type **) & (s->relocation); - } - - while (true) - { - switch (this_byte (&(ieee->h))) - { - /* IF we see anything strange then quit */ - default: - return true; - - case ieee_set_current_section_enum: - next_byte (&(ieee->h)); - section_number = must_parse_int (&(ieee->h)); - s = ieee->section_table[section_number]; - s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; - current_map = (ieee_per_section_type *) s->used_by_bfd; - location_ptr = current_map->data - s->vma; - /* The document I have says that Microtec's compilers reset */ - /* this after a sec section, even though the standard says not */ - /* to. SO .. */ - current_map->pc = s->vma; - break; - - case ieee_e2_first_byte_enum: - next_byte (&(ieee->h)); - switch (this_byte (&(ieee->h))) - { - case ieee_set_current_pc_enum & 0xff: - { - bfd_vma value; - ieee_symbol_index_type symbol; - unsigned int extra; - boolean pcrel; - next_byte (&(ieee->h)); - must_parse_int (&(ieee->h)); /* Thow away section #*/ - parse_expression (ieee, &value, - &symbol, - &pcrel, &extra, - 0); - current_map->pc = value; - BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size); - } - break; - - case ieee_value_starting_address_enum & 0xff: - /* We've got to the end of the data now - */ - return true; - default: - BFD_FAIL (); - return false; - } - break; - case ieee_repeat_data_enum: - { - /* Repeat the following LD or LR n times - we do this by - remembering the stream pointer before running it and - resetting it and running it n times. We special case - the repetition of a repeat_data/load_constant - */ - - unsigned int iterations; - unsigned char *start; - next_byte (&(ieee->h)); - iterations = must_parse_int (&(ieee->h)); - start = ieee->h.input_p; - if (start[0] == (int) ieee_load_constant_bytes_enum && - start[1] == 1) - { - while (iterations != 0) - { - location_ptr[current_map->pc++] = start[2]; - iterations--; - } - next_byte (&(ieee->h)); - next_byte (&(ieee->h)); - next_byte (&(ieee->h)); - } - else - { - while (iterations != 0) - { - ieee->h.input_p = start; - if (!do_one (ieee, current_map, location_ptr, s, - iterations)) - return false; - iterations--; - } - } - } - break; - case ieee_load_constant_bytes_enum: - case ieee_load_with_relocation_enum: - { - if (!do_one (ieee, current_map, location_ptr, s, 1)) - return false; - } - } - } -} - -boolean -ieee_new_section_hook (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - newsect->used_by_bfd = (PTR) - bfd_alloc (abfd, sizeof (ieee_per_section_type)); - if (!newsect->used_by_bfd) - return false; - ieee_per_section (newsect)->data = (bfd_byte *) NULL; - ieee_per_section (newsect)->section = newsect; - return true; -} - -long -ieee_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if ((asect->flags & SEC_DEBUGGING) != 0) - return 0; - if (! ieee_slurp_section_data (abfd)) - return -1; - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -static boolean -ieee_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd; - if ((section->flags & SEC_DEBUGGING) != 0) - return _bfd_generic_get_section_contents (abfd, section, location, - offset, count); - ieee_slurp_section_data (abfd); - (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count); - return true; -} - -long -ieee_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ -/* ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/ - ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation); - ieee_data_type *ieee = IEEE_DATA (abfd); - - if ((section->flags & SEC_DEBUGGING) != 0) - return 0; - - while (src != (ieee_reloc_type *) NULL) - { - /* Work out which symbol to attach it this reloc to */ - switch (src->symbol.letter) - { - case 'I': - src->relent.sym_ptr_ptr = - symbols + src->symbol.index + ieee->external_symbol_base_offset; - break; - case 'X': - src->relent.sym_ptr_ptr = - symbols + src->symbol.index + ieee->external_reference_base_offset; - break; - case 0: - src->relent.sym_ptr_ptr = - src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr; - break; - default: - - BFD_FAIL (); - } - *relptr++ = &src->relent; - src = src->next; - } - *relptr = (arelent *) NULL; - return section->reloc_count; -} - -static int -comp (ap, bp) - CONST PTR ap; - CONST PTR bp; -{ - arelent *a = *((arelent **) ap); - arelent *b = *((arelent **) bp); - return a->address - b->address; -} - -/* Write the section headers. */ - -static boolean -ieee_write_section_part (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - asection *s; - ieee->w.r.section_part = bfd_tell (abfd); - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (! bfd_is_abs_section (s) - && (s->flags & SEC_DEBUGGING) == 0) - { - if (! ieee_write_byte (abfd, ieee_section_type_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE))) - return false; - - if (abfd->flags & EXEC_P) - { - /* This image is executable, so output absolute sections */ - if (! ieee_write_byte (abfd, ieee_variable_A_enum) - || ! ieee_write_byte (abfd, ieee_variable_S_enum)) - return false; - } - else - { - if (! ieee_write_byte (abfd, ieee_variable_C_enum)) - return false; - } - - switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM)) - { - case SEC_CODE | SEC_LOAD: - case SEC_CODE: - if (! ieee_write_byte (abfd, ieee_variable_P_enum)) - return false; - break; - case SEC_DATA: - default: - if (! ieee_write_byte (abfd, ieee_variable_D_enum)) - return false; - break; - case SEC_ROM: - case SEC_ROM | SEC_DATA: - case SEC_ROM | SEC_LOAD: - case SEC_ROM | SEC_DATA | SEC_LOAD: - if (! ieee_write_byte (abfd, ieee_variable_R_enum)) - return false; - } - - - if (! ieee_write_id (abfd, s->name)) - return false; -#if 0 - ieee_write_int (abfd, 0); /* Parent */ - ieee_write_int (abfd, 0); /* Brother */ - ieee_write_int (abfd, 0); /* Context */ -#endif - /* Alignment */ - if (! ieee_write_byte (abfd, ieee_section_alignment_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_int (abfd, 1 << s->alignment_power)) - return false; - - /* Size */ - if (! ieee_write_2bytes (abfd, ieee_section_size_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_int (abfd, s->_raw_size)) - return false; - if (abfd->flags & EXEC_P) - { - /* Relocateable sections don't have asl records */ - /* Vma */ - if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum) - || ! ieee_write_byte (abfd, - ((bfd_byte) - (s->index - + IEEE_SECTION_NUMBER_BASE))) - || ! ieee_write_int (abfd, s->vma)) - return false; - } - } - } - - return true; -} - - -static boolean -do_with_relocs (abfd, s) - bfd *abfd; - asection *s; -{ - unsigned int number_of_maus_in_address = - bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd); - unsigned int relocs_to_go = s->reloc_count; - bfd_byte *stream = ieee_per_section (s)->data; - arelent **p = s->orelocation; - bfd_size_type current_byte_index = 0; - - qsort (s->orelocation, - relocs_to_go, - sizeof (arelent **), - comp); - - /* Output the section preheader */ - if (! ieee_write_byte (abfd, ieee_set_current_section_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))) - return false; - if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0) - { - if (! ieee_write_int (abfd, s->vma)) - return false; - } - else - { - if (! ieee_write_expression (abfd, 0, s->symbol, 0, 0)) - return false; - } - - if (relocs_to_go == 0) - { - /* If there aren't any relocations then output the load constant - byte opcode rather than the load with relocation opcode */ - - while (current_byte_index < s->_raw_size) - { - bfd_size_type run; - unsigned int MAXRUN = 127; - run = MAXRUN; - if (run > s->_raw_size - current_byte_index) - { - run = s->_raw_size - current_byte_index; - } - - if (run != 0) - { - if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)) - return false; - /* Output a stream of bytes */ - if (! ieee_write_int (abfd, run)) - return false; - if (bfd_write ((PTR) (stream + current_byte_index), - 1, - run, - abfd) - != run) - return false; - current_byte_index += run; - } - } - } - else - { - if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum)) - return false; - - /* Output the data stream as the longest sequence of bytes - possible, allowing for the a reasonable packet size and - relocation stuffs. */ - - if ((PTR) stream == (PTR) NULL) - { - /* Outputting a section without data, fill it up */ - stream = (unsigned char *) (bfd_alloc (abfd, s->_raw_size)); - if (!stream) - return false; - memset ((PTR) stream, 0, (size_t) s->_raw_size); - } - while (current_byte_index < s->_raw_size) - { - bfd_size_type run; - unsigned int MAXRUN = 127; - if (relocs_to_go) - { - run = (*p)->address - current_byte_index; - if (run > MAXRUN) - run = MAXRUN; - } - else - { - run = MAXRUN; - } - if (run > s->_raw_size - current_byte_index) - { - run = s->_raw_size - current_byte_index; - } - - if (run != 0) - { - /* Output a stream of bytes */ - if (! ieee_write_int (abfd, run)) - return false; - if (bfd_write ((PTR) (stream + current_byte_index), - 1, - run, - abfd) - != run) - return false; - current_byte_index += run; - } - /* Output any relocations here */ - if (relocs_to_go && (*p) && (*p)->address == current_byte_index) - { - while (relocs_to_go - && (*p) && (*p)->address == current_byte_index) - { - arelent *r = *p; - bfd_signed_vma ov; - -#if 0 - if (r->howto->pc_relative) - { - r->addend += current_byte_index; - } -#endif - - switch (r->howto->size) - { - case 2: - - ov = bfd_get_signed_32 (abfd, - stream + current_byte_index); - current_byte_index += 4; - break; - case 1: - ov = bfd_get_signed_16 (abfd, - stream + current_byte_index); - current_byte_index += 2; - break; - case 0: - ov = bfd_get_signed_8 (abfd, - stream + current_byte_index); - current_byte_index++; - break; - default: - ov = 0; - BFD_FAIL (); - return false; - } - - ov &= r->howto->src_mask; - - if (r->howto->pc_relative - && ! r->howto->pcrel_offset) - ov += r->address; - - if (! ieee_write_byte (abfd, - ieee_function_either_open_b_enum)) - return false; - -/* abort();*/ - - if (r->sym_ptr_ptr != (asymbol **) NULL) - { - if (! ieee_write_expression (abfd, r->addend + ov, - *(r->sym_ptr_ptr), - r->howto->pc_relative, - s->index)) - return false; - } - else - { - if (! ieee_write_expression (abfd, r->addend + ov, - (asymbol *) NULL, - r->howto->pc_relative, - s->index)) - return false; - } - - if (number_of_maus_in_address - != bfd_get_reloc_size (r->howto)) - { - if (! ieee_write_int (abfd, - bfd_get_reloc_size (r->howto))) - return false; - } - if (! ieee_write_byte (abfd, - ieee_function_either_close_b_enum)) - return false; - - relocs_to_go--; - p++; - } - - } - } - } - - return true; -} - -/* If there are no relocations in the output section then we can be - clever about how we write. We block items up into a max of 127 - bytes. */ - -static boolean -do_as_repeat (abfd, s) - bfd *abfd; - asection *s; -{ - if (s->_raw_size) - { - if (! ieee_write_byte (abfd, ieee_set_current_section_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8) - || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_int (abfd, s->vma) - || ! ieee_write_byte (abfd, ieee_repeat_data_enum) - || ! ieee_write_int (abfd, s->_raw_size) - || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum) - || ! ieee_write_byte (abfd, 1) - || ! ieee_write_byte (abfd, 0)) - return false; - } - - return true; -} - -static boolean -do_without_relocs (abfd, s) - bfd *abfd; - asection *s; -{ - bfd_byte *stream = ieee_per_section (s)->data; - - if (stream == 0 || ((s->flags & SEC_LOAD) == 0)) - { - if (! do_as_repeat (abfd, s)) - return false; - } - else - { - unsigned int i; - for (i = 0; i < s->_raw_size; i++) - { - if (stream[i] != 0) - { - if (! do_with_relocs (abfd, s)) - return false; - return true; - } - } - if (! do_as_repeat (abfd, s)) - return false; - } - - return true; -} - - -static unsigned char *output_ptr_start; -static unsigned char *output_ptr; -static unsigned char *output_ptr_end; -static unsigned char *input_ptr_start; -static unsigned char *input_ptr; -static unsigned char *input_ptr_end; -static bfd *input_bfd; -static bfd *output_bfd; -static int output_buffer; - -static void -fill () -{ - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd); - input_ptr = input_ptr_start; -} -static void -flush () -{ - if (bfd_write ((PTR) (output_ptr_start), 1, output_ptr - output_ptr_start, - output_bfd) - != (bfd_size_type) (output_ptr - output_ptr_start)) - abort (); - output_ptr = output_ptr_start; - output_buffer++; -} - -#define THIS() ( *input_ptr ) -#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); } -#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end) flush(); } - -static void -write_int (value) - int value; -{ - if (value >= 0 && value <= 127) - { - OUT (value); - } - else - { - unsigned int length; - /* How many significant bytes ? */ - /* FIXME FOR LONGER INTS */ - if (value & 0xff000000) - { - length = 4; - } - else if (value & 0x00ff0000) - { - length = 3; - } - else if (value & 0x0000ff00) - { - length = 2; - } - else - length = 1; - - OUT ((int) ieee_number_repeat_start_enum + length); - switch (length) - { - case 4: - OUT (value >> 24); - case 3: - OUT (value >> 16); - case 2: - OUT (value >> 8); - case 1: - OUT (value); - } - - } -} - -static void -copy_id () -{ - int length = THIS (); - char ch; - OUT (length); - NEXT (); - while (length--) - { - ch = THIS (); - OUT (ch); - NEXT (); - } -} - -#define VAR(x) ((x | 0x80)) -static void -copy_expression () -{ - int stack[10]; - int *tos = stack; - int value = 0; - while (1) - { - switch (THIS ()) - { - case 0x84: - NEXT (); - value = THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - *tos++ = value; - break; - case 0x83: - NEXT (); - value = THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - *tos++ = value; - break; - case 0x82: - NEXT (); - value = THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - *tos++ = value; - break; - case 0x81: - NEXT (); - value = THIS (); - NEXT (); - *tos++ = value; - break; - case 0x80: - NEXT (); - *tos++ = 0; - break; - default: - if (THIS () > 0x84) - { - /* Not a number, just bug out with the answer */ - write_int (*(--tos)); - return; - } - *tos++ = THIS (); - NEXT (); - value = 0; - break; - case 0xa5: - /* PLUS anything */ - { - int value = *(--tos); - value += *(--tos); - *tos++ = value; - NEXT (); - } - break; - case VAR ('R'): - { - int section_number; - ieee_data_type *ieee; - asection *s; - NEXT (); - section_number = THIS (); - - NEXT (); - ieee = IEEE_DATA (input_bfd); - s = ieee->section_table[section_number]; - if (s->output_section) - { - value = s->output_section->vma; - } - else - { - value = 0; - } - value += s->output_offset; - *tos++ = value; - value = 0; - } - break; - case 0x90: - { - NEXT (); - write_int (*(--tos)); - OUT (0x90); - return; - - } - } - } - -} - -/* Drop the int in the buffer, and copy a null into the gap, which we - will overwrite later */ - -struct output_buffer_struct -{ - unsigned char *ptrp; - int buffer; -}; - -static void -fill_int (buf) - struct output_buffer_struct *buf; -{ - if (buf->buffer == output_buffer) - { - /* Still a chance to output the size */ - int value = output_ptr - buf->ptrp + 3; - buf->ptrp[0] = value >> 24; - buf->ptrp[1] = value >> 16; - buf->ptrp[2] = value >> 8; - buf->ptrp[3] = value >> 0; - } -} - -static void -drop_int (buf) - struct output_buffer_struct *buf; -{ - int type = THIS (); - int ch; - if (type <= 0x84) - { - NEXT (); - switch (type) - { - case 0x84: - ch = THIS (); - NEXT (); - case 0x83: - ch = THIS (); - NEXT (); - case 0x82: - ch = THIS (); - NEXT (); - case 0x81: - ch = THIS (); - NEXT (); - case 0x80: - break; - } - } - OUT (0x84); - buf->ptrp = output_ptr; - buf->buffer = output_buffer; - OUT (0); - OUT (0); - OUT (0); - OUT (0); -} - -static void -copy_int () -{ - int type = THIS (); - int ch; - if (type <= 0x84) - { - OUT (type); - NEXT (); - switch (type) - { - case 0x84: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x83: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x82: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x81: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x80: - break; - } - } -} - -#define ID copy_id() -#define INT copy_int() -#define EXP copy_expression() -static void copy_till_end (); -#define INTn(q) copy_int() -#define EXPn(q) copy_expression() - -static void -f1_record () -{ - int ch; - /* ATN record */ - NEXT (); - ch = THIS (); - switch (ch) - { - default: - OUT (0xf1); - OUT (ch); - break; - case 0xc9: - NEXT (); - OUT (0xf1); - OUT (0xc9); - INT; - INT; - ch = THIS (); - switch (ch) - { - case 0x16: - NEXT (); - break; - case 0x01: - NEXT (); - break; - case 0x00: - NEXT (); - INT; - break; - case 0x03: - NEXT (); - INT; - break; - case 0x13: - EXPn (instruction address); - break; - default: - break; - } - break; - case 0xd8: - /* EXternal ref */ - NEXT (); - OUT (0xf1); - OUT (0xd8); - EXP; - EXP; - EXP; - EXP; - break; - case 0xce: - NEXT (); - OUT (0xf1); - OUT (0xce); - INT; - INT; - ch = THIS (); - INT; - switch (ch) - { - case 0x01: - INT; - INT; - break; - case 0x02: - INT; - break; - case 0x04: - EXPn (external function); - break; - case 0x05: - break; - case 0x07: - INTn (line number); - INT; - case 0x08: - break; - case 0x0a: - INTn (locked register); - INT; - break; - case 0x3f: - copy_till_end (); - break; - case 0x3e: - copy_till_end (); - break; - case 0x40: - copy_till_end (); - break; - case 0x41: - ID; - break; - } - } - -} - -static void -f0_record () -{ - /* Attribute record */ - NEXT (); - OUT (0xf0); - INTn (Symbol name); - ID; -} - -static void -copy_till_end () -{ - int ch = THIS (); - while (1) - { - while (ch <= 0x80) - { - OUT (ch); - NEXT (); - ch = THIS (); - } - switch (ch) - { - case 0x84: - OUT (THIS ()); - NEXT (); - case 0x83: - OUT (THIS ()); - NEXT (); - case 0x82: - OUT (THIS ()); - NEXT (); - case 0x81: - OUT (THIS ()); - NEXT (); - OUT (THIS ()); - NEXT (); - - ch = THIS (); - break; - default: - return; - } - } - -} - -static void -f2_record () -{ - NEXT (); - OUT (0xf2); - INT; - NEXT (); - OUT (0xce); - INT; - copy_till_end (); -} - - -static void block (); -static void -f8_record () -{ - int ch; - NEXT (); - ch = THIS (); - switch (ch) - { - case 0x01: - case 0x02: - case 0x03: - /* Unique typedefs for module */ - /* GLobal typedefs */ - /* High level module scope beginning */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (ch); - drop_int (&ob); - ID; - - block (); - - NEXT (); - fill_int (&ob); - OUT (0xf9); - } - break; - case 0x04: - /* Global function */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x04); - drop_int (&ob); - ID; - INTn (stack size); - INTn (ret val); - EXPn (offset); - - block (); - - NEXT (); - OUT (0xf9); - EXPn (size of block); - fill_int (&ob); - } - break; - - case 0x05: - /* File name for source line numbers */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x05); - drop_int (&ob); - ID; - INTn (year); - INTn (month); - INTn (day); - INTn (hour); - INTn (monute); - INTn (second); - block (); - NEXT (); - OUT (0xf9); - fill_int (&ob); - } - break; - - case 0x06: - /* Local function */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x06); - drop_int (&ob); - ID; - INTn (stack size); - INTn (type return); - EXPn (offset); - block (); - NEXT (); - OUT (0xf9); - EXPn (size); - fill_int (&ob); - } - break; - - case 0x0a: - /* Assembler module scope beginning -*/ - { - struct output_buffer_struct ob; - - NEXT (); - OUT (0xf8); - OUT (0x0a); - drop_int (&ob); - ID; - ID; - INT; - ID; - INT; - INT; - INT; - INT; - INT; - INT; - - block (); - - NEXT (); - OUT (0xf9); - fill_int (&ob); - } - break; - case 0x0b: - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x0b); - drop_int (&ob); - ID; - INT; - INTn (section index); - EXPn (offset); - INTn (stuff); - - block (); - - OUT (0xf9); - NEXT (); - EXPn (Size in Maus); - fill_int (&ob); - } - break; - } -} - -static void -e2_record () -{ - OUT (0xe2); - NEXT (); - OUT (0xce); - NEXT (); - INT; - EXP; -} - -static void -block () -{ - int ch; - while (1) - { - ch = THIS (); - switch (ch) - { - case 0xe1: - case 0xe5: - return; - case 0xf9: - return; - case 0xf0: - f0_record (); - break; - case 0xf1: - f1_record (); - break; - case 0xf2: - f2_record (); - break; - case 0xf8: - f8_record (); - break; - case 0xe2: - e2_record (); - break; - - } - } -} - - - -/* relocate_debug, - moves all the debug information from the source bfd to the output - bfd, and relocates any expressions it finds -*/ - -static void -relocate_debug (output, input) - bfd *output; - bfd *input; -{ -#define IBS 400 -#define OBS 400 - unsigned char input_buffer[IBS]; - - input_ptr_start = input_ptr = input_buffer; - input_ptr_end = input_buffer + IBS; - input_bfd = input; - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) input_ptr_start, 1, IBS, input); - block (); -} - -/* - During linking, we we told about the bfds which made up our - contents, we have a list of them. They will still be open, so go to - the debug info in each, and copy it out, relocating it as we go. -*/ - -static boolean -ieee_write_debug_part (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - bfd_chain_type *chain = ieee->chain_root; - unsigned char output_buffer[OBS]; - boolean some_debug = false; - file_ptr here = bfd_tell (abfd); - - output_ptr_start = output_ptr = output_buffer; - output_ptr_end = output_buffer + OBS; - output_ptr = output_buffer; - output_bfd = abfd; - - if (chain == (bfd_chain_type *) NULL) - { - asection *s; - - for (s = abfd->sections; s != NULL; s = s->next) - if ((s->flags & SEC_DEBUGGING) != 0) - break; - if (s == NULL) - { - ieee->w.r.debug_information_part = 0; - return true; - } - - ieee->w.r.debug_information_part = here; - if (bfd_write (s->contents, 1, s->_raw_size, abfd) != s->_raw_size) - return false; - } - else - { - while (chain != (bfd_chain_type *) NULL) - { - bfd *entry = chain->this; - ieee_data_type *entry_ieee = IEEE_DATA (entry); - if (entry_ieee->w.r.debug_information_part) - { - if (bfd_seek (entry, entry_ieee->w.r.debug_information_part, - SEEK_SET) - != 0) - return false; - relocate_debug (abfd, entry); - } - - chain = chain->next; - } - if (some_debug) - { - ieee->w.r.debug_information_part = here; - } - else - { - ieee->w.r.debug_information_part = 0; - } - - flush (); - } - - return true; -} - -/* Write the data in an ieee way. */ - -static boolean -ieee_write_data_part (abfd) - bfd *abfd; -{ - asection *s; - ieee_data_type *ieee = IEEE_DATA (abfd); - ieee->w.r.data_part = bfd_tell (abfd); - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - /* Skip sections that have no loadable contents (.bss, - debugging, etc.) */ - if ((s->flags & SEC_LOAD) == 0) - continue; - - /* Sort the reloc records so we can insert them in the correct - places */ - if (s->reloc_count != 0) - { - if (! do_with_relocs (abfd, s)) - return false; - } - else - { - if (! do_without_relocs (abfd, s)) - return false; - } - } - - return true; -} - - -static boolean -init_for_output (abfd) - bfd *abfd; -{ - asection *s; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if ((s->flags & SEC_DEBUGGING) != 0) - continue; - if (s->_raw_size != 0) - { - ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, s->_raw_size)); - if (!ieee_per_section (s)->data) - return false; - } - } - return true; -} - -/** exec and core file sections */ - -/* set section contents is complicated with IEEE since the format is -* not a byte image, but a record stream. -*/ -boolean -ieee_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if ((section->flags & SEC_DEBUGGING) != 0) - { - if (section->contents == NULL) - { - section->contents = bfd_alloc (abfd, section->_raw_size); - if (section->contents == NULL) - return false; - } - /* bfd_set_section_contents has already checked that everything - is within range. */ - memcpy (section->contents + offset, location, count); - return true; - } - - if (ieee_per_section (section)->data == (bfd_byte *) NULL) - { - if (!init_for_output (abfd)) - return false; - } - memcpy ((PTR) (ieee_per_section (section)->data + offset), - (PTR) location, - (unsigned int) count); - return true; -} - -/* Write the external symbols of a file. IEEE considers two sorts of - external symbols, public, and referenced. It uses to internal - forms to index them as well. When we write them out we turn their - symbol values into indexes from the right base. */ - -static boolean -ieee_write_external_part (abfd) - bfd *abfd; -{ - asymbol **q; - ieee_data_type *ieee = IEEE_DATA (abfd); - - unsigned int reference_index = IEEE_REFERENCE_BASE; - unsigned int public_index = IEEE_PUBLIC_BASE + 2; - file_ptr here = bfd_tell (abfd); - boolean hadone = false; - if (abfd->outsymbols != (asymbol **) NULL) - { - - for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++) - { - asymbol *p = *q; - hadone = true; - if (bfd_is_und_section (p->section)) - { - /* This must be a symbol reference .. */ - if (! ieee_write_byte (abfd, ieee_external_reference_enum) - || ! ieee_write_int (abfd, reference_index) - || ! ieee_write_id (abfd, p->name)) - return false; - p->value = reference_index; - reference_index++; - } - else if (bfd_is_com_section (p->section)) - { - /* This is a weak reference */ - if (! ieee_write_byte (abfd, ieee_external_reference_enum) - || ! ieee_write_int (abfd, reference_index) - || ! ieee_write_id (abfd, p->name) - || ! ieee_write_byte (abfd, - ieee_weak_external_reference_enum) - || ! ieee_write_int (abfd, reference_index) - || ! ieee_write_int (abfd, p->value)) - return false; - p->value = reference_index; - reference_index++; - } - else if (p->flags & BSF_GLOBAL) - { - /* This must be a symbol definition */ - - if (! ieee_write_byte (abfd, ieee_external_symbol_enum) - || ! ieee_write_int (abfd, public_index) - || ! ieee_write_id (abfd, p->name) - || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum) - || ! ieee_write_int (abfd, public_index) - || ! ieee_write_byte (abfd, 15) /* instruction address */ - || ! ieee_write_byte (abfd, 19) /* static symbol */ - || ! ieee_write_byte (abfd, 1)) /* one of them */ - return false; - - /* Write out the value */ - if (! ieee_write_2bytes (abfd, ieee_value_record_enum) - || ! ieee_write_int (abfd, public_index)) - return false; - if (! bfd_is_abs_section (p->section)) - { - if (abfd->flags & EXEC_P) - { - /* If fully linked, then output all symbols - relocated */ - if (! (ieee_write_int - (abfd, - (p->value - + p->section->output_offset - + p->section->output_section->vma)))) - return false; - } - else - { - if (! (ieee_write_expression - (abfd, - p->value + p->section->output_offset, - p->section->output_section->symbol, - false, 0))) - return false; - } - } - else - { - if (! ieee_write_expression (abfd, - p->value, - bfd_abs_section_ptr->symbol, - false, 0)) - return false; - } - p->value = public_index; - public_index++; - } - else - { - /* This can happen - when there are gaps in the symbols read */ - /* from an input ieee file */ - } - } - } - if (hadone) - ieee->w.r.external_part = here; - - return true; -} - - -static CONST unsigned char exten[] = -{ - 0xf0, 0x20, 0x00, - 0xf1, 0xce, 0x20, 0x00, 37, 3, 3, /* Set version 3 rev 3 */ - 0xf1, 0xce, 0x20, 0x00, 39, 2,/* keep symbol in original case */ - 0xf1, 0xce, 0x20, 0x00, 38 /* set object type relocateable to x */ -}; - -static CONST unsigned char envi[] = -{ - 0xf0, 0x21, 0x00, - -/* 0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11, - 0x19, 0x2c, -*/ - 0xf1, 0xce, 0x21, 00, 52, 0x00, /* exec ok */ - - 0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */ -/* 0xf1, 0xce, 0x21, 0, 54, 2,1,1 tool & version # */ -}; - -static boolean -ieee_write_me_part (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - ieee->w.r.trailer_part = bfd_tell (abfd); - if (abfd->start_address) - { - if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum) - || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum) - || ! ieee_write_int (abfd, abfd->start_address) - || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum)) - return false; - } - ieee->w.r.me_record = bfd_tell (abfd); - if (! ieee_write_byte (abfd, ieee_module_end_enum)) - return false; - return true; -} - -/* Write out the IEEE processor ID. */ - -static boolean -ieee_write_processor (abfd) - bfd *abfd; -{ - const bfd_arch_info_type *arch; - - arch = bfd_get_arch_info (abfd); - switch (arch->arch) - { - default: - if (! ieee_write_id (abfd, bfd_printable_name (abfd))) - return false; - break; - - case bfd_arch_a29k: - if (! ieee_write_id (abfd, "29000")) - return false; - break; - - case bfd_arch_h8300: - if (! ieee_write_id (abfd, "H8/300")) - return false; - break; - - case bfd_arch_h8500: - if (! ieee_write_id (abfd, "H8/500")) - return false; - break; - - case bfd_arch_i960: - switch (arch->mach) - { - default: - case bfd_mach_i960_core: - case bfd_mach_i960_ka_sa: - if (! ieee_write_id (abfd, "80960KA")) - return false; - break; - - case bfd_mach_i960_kb_sb: - if (! ieee_write_id (abfd, "80960KB")) - return false; - break; - - case bfd_mach_i960_ca: - if (! ieee_write_id (abfd, "80960CA")) - return false; - break; - - case bfd_mach_i960_mc: - case bfd_mach_i960_xa: - if (! ieee_write_id (abfd, "80960MC")) - return false; - break; - } - break; - - case bfd_arch_m68k: - { - char ab[20]; - - sprintf (ab, "%lu", arch->mach); - if (! ieee_write_id (abfd, ab)) - return false; - } - break; - } - - return true; -} - -boolean -ieee_write_object_contents (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - unsigned int i; - file_ptr old; - - /* Fast forward over the header area */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return false; - - if (! ieee_write_byte (abfd, ieee_module_beginning_enum) - || ! ieee_write_processor (abfd) - || ! ieee_write_id (abfd, abfd->filename)) - return false; - - /* Fast forward over the variable bits */ - if (! ieee_write_byte (abfd, ieee_address_descriptor_enum)) - return false; - - /* Bits per MAU */ - if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd)))) - return false; - /* MAU's per address */ - if (! ieee_write_byte (abfd, - (bfd_byte) (bfd_arch_bits_per_address (abfd) - / bfd_arch_bits_per_byte (abfd)))) - return false; - - old = bfd_tell (abfd); - if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0) - return false; - - ieee->w.r.extension_record = bfd_tell (abfd); - if (bfd_write ((char *) exten, 1, sizeof (exten), abfd) != sizeof (exten)) - return false; - if (abfd->flags & EXEC_P) - { - if (! ieee_write_byte (abfd, 0x1)) /* Absolute */ - return false; - } - else - { - if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */ - return false; - } - - ieee->w.r.environmental_record = bfd_tell (abfd); - if (bfd_write ((char *) envi, 1, sizeof (envi), abfd) != sizeof (envi)) - return false; - output_bfd = abfd; - - flush (); - - if (! ieee_write_section_part (abfd)) - return false; - /* First write the symbols. This changes their values into table - indeces so we cant use it after this point. */ - if (! ieee_write_external_part (abfd)) - return false; - - /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/ - - /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/ - - - /* Write any debugs we have been told about. */ - if (! ieee_write_debug_part (abfd)) - return false; - - /* Can only write the data once the symbols have been written, since - the data contains relocation information which points to the - symbols. */ - if (! ieee_write_data_part (abfd)) - return false; - - /* At the end we put the end! */ - if (! ieee_write_me_part (abfd)) - return false; - - /* Generate the header */ - if (bfd_seek (abfd, old, SEEK_SET) != 0) - return false; - - for (i = 0; i < N_W_VARIABLES; i++) - { - if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum) - || ! ieee_write_byte (abfd, (bfd_byte) i) - || ! ieee_write_int5_out (abfd, ieee->w.offset[i])) - return false; - } - - return true; -} - -/* Native-level interface to symbols. */ - -/* We read the symbols into a buffer, which is discarded when this - function exits. We read the strings into a buffer large enough to - hold them all plus all the cached symbol entries. */ - -asymbol * -ieee_make_empty_symbol (abfd) - bfd *abfd; -{ - ieee_symbol_type *new = - (ieee_symbol_type *) bfd_zmalloc (sizeof (ieee_symbol_type)); - if (!new) - return NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -static bfd * -ieee_openr_next_archived_file (arch, prev) - bfd *arch; - bfd *prev; -{ - ieee_ar_data_type *ar = IEEE_AR_DATA (arch); - /* take the next one from the arch state, or reset */ - if (prev == (bfd *) NULL) - { - /* Reset the index - the first two entries are bogus*/ - ar->element_index = 2; - } - while (true) - { - ieee_ar_obstack_type *p = ar->elements + ar->element_index; - ar->element_index++; - if (ar->element_index <= ar->element_count) - { - if (p->file_offset != (file_ptr) 0) - { - if (p->abfd == (bfd *) NULL) - { - p->abfd = _bfd_create_empty_archive_element_shell (arch); - p->abfd->origin = p->file_offset; - } - return p->abfd; - } - } - else - { - bfd_set_error (bfd_error_no_more_archived_files); - return (bfd *) NULL; - } - - } -} - -static boolean -ieee_find_nearest_line (abfd, - section, - symbols, - offset, - filename_ptr, - functionname_ptr, - line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - char **filename_ptr; - char **functionname_ptr; - int *line_ptr; -{ - return false; -} - -static int -ieee_generic_stat_arch_elt (abfd, buf) - bfd *abfd; - struct stat *buf; -{ - ieee_ar_data_type *ar = abfd->my_archive->tdata.ieee_ar_data; - if (ar == (ieee_ar_data_type *) NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - else if (ieee_object_p (abfd)) - { - ieee_data_type *ieee = IEEE_DATA (abfd); - - buf->st_size = ieee->w.r.me_record + 1; - buf->st_mode = 0644; - return 0; - } - else - return -1; -} - -static int -ieee_sizeof_headers (abfd, x) - bfd *abfd; - boolean x; -{ - return 0; -} - - -/* The debug info routines are never used. */ -#if 0 - -static void -ieee_bfd_debug_info_start (abfd) - bfd *abfd; -{ - -} - -static void -ieee_bfd_debug_info_end (abfd) - bfd *abfd; -{ - -} - - -/* Add this section to the list of sections we have debug info for, to - be ready to output it at close time - */ -static void -ieee_bfd_debug_info_accumulate (abfd, section) - bfd *abfd; - asection *section; -{ - ieee_data_type *ieee = IEEE_DATA (section->owner); - ieee_data_type *output_ieee = IEEE_DATA (abfd); - /* can only accumulate data from other ieee bfds */ - if (section->owner->xvec != abfd->xvec) - return; - /* Only bother once per bfd */ - if (ieee->done_debug == true) - return; - ieee->done_debug = true; - - /* Don't bother if there is no debug info */ - if (ieee->w.r.debug_information_part == 0) - return; - - - /* Add to chain */ - { - bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, sizeof (bfd_chain_type)); - if (!n) - abort (); /* FIXME */ - n->this = section->owner; - n->next = (bfd_chain_type *) NULL; - - if (output_ieee->chain_head) - { - output_ieee->chain_head->next = n; - } - else - { - output_ieee->chain_root = n; - - } - output_ieee->chain_head = n; - } -} - -#endif - -#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup -#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info - -#define ieee_slurp_armap bfd_true -#define ieee_slurp_extended_name_table bfd_true -#define ieee_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_true) -#define ieee_truncate_arname bfd_dont_truncate_arname -#define ieee_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_true) -#define ieee_read_ar_hdr bfd_nullvoidptr -#define ieee_update_armap_timestamp bfd_true -#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index - -#define ieee_bfd_is_local_label bfd_generic_is_local_label -#define ieee_get_lineno _bfd_nosymbols_get_lineno -#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define ieee_read_minisymbols _bfd_generic_read_minisymbols -#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define ieee_set_arch_mach _bfd_generic_set_arch_mach - -#define ieee_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window -#define ieee_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define ieee_bfd_relax_section bfd_generic_relax_section -#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define ieee_bfd_final_link _bfd_generic_final_link -#define ieee_bfd_link_split_section _bfd_generic_link_split_section - -/*SUPPRESS 460 */ -const bfd_target ieee_vec = -{ - "ieee", /* name */ - bfd_target_ieee_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, - ieee_object_p, /* bfd_check_format */ - ieee_archive_p, - _bfd_dummy_target, - }, - { - bfd_false, - ieee_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { - bfd_false, - ieee_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (ieee), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (ieee), - BFD_JUMP_TABLE_SYMBOLS (ieee), - BFD_JUMP_TABLE_RELOCS (ieee), - BFD_JUMP_TABLE_WRITE (ieee), - BFD_JUMP_TABLE_LINK (ieee), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/ihex.c b/contrib/gdb/bfd/ihex.c deleted file mode 100644 index 80140da5976..00000000000 --- a/contrib/gdb/bfd/ihex.c +++ /dev/null @@ -1,1005 +0,0 @@ -/* BFD back-end for Intel Hex objects. - Copyright 1995 Free Software Foundation, Inc. - Written by Ian Lance Taylor of Cygnus Support . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This is what Intel Hex files look like: - -1. INTEL FORMATS - -A. Intel 1 - - 16-bit address-field format, for files 64k bytes in length or less. - - DATA RECORD - Byte 1 Header = colon(:) - 2..3 The number of data bytes in hex notation - 4..5 High byte of the record load address - 6..7 Low byte of the record load address - 8..9 Record type, must be "00" - 10..x Data bytes in hex notation: - x = (number of bytes - 1) * 2 + 11 - x+1..x+2 Checksum in hex notation - x+3..x+4 Carriage return, line feed - - END RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "00" - 4..7 Transfer-address (usually "0000") - the jump-to address, execution start address - 8..9 Record type, must be "01" - 10..11 Checksum, in hex notation - 12..13 Carriage return, line feed - -B. INTEL 2 - - MCS-86 format, using a 20-bit address for files larger than 64K bytes. - - DATA RECORD - Byte 1 Header = colon (:) - 2..3 The byte count of this record, hex notation - 4..5 High byte of the record load address - 6..7 Low byte of the record load address - 8..9 Record type, must be "00" - 10..x The data bytes in hex notation: - x = (number of data bytes - 1) * 2 + 11 - x+1..x+2 Checksum in hex notation - x+3..x+4 Carriage return, line feed - - EXTENDED ADDRESS RECORD - Byte 1 Header = colon(:) - 2..3 The byte count, must be "02" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "02" - 10..11 High byte of the offset address - 12..13 Low byte of the offset address - 14..15 Checksum in hex notation - 16..17 Carriage return, line feed - - The checksums are the two's complement of the 8-bit sum - without carry of the byte count, offset address, and the - record type. - - START ADDRESS RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "04" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "03" - 10..13 8086 CS value - 14..17 8086 IP value - 18..19 Checksum in hex notation - 20..21 Carriage return, line feed - -Another document reports these additional types: - - EXTENDED LINEAR ADDRESS RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "02" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "04" - 10..13 Upper 16 bits of address of subsequent records - 14..15 Checksum in hex notation - 16..17 Carriage return, line feed - - START LINEAR ADDRESS RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "02" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "05" - 10..13 Upper 16 bits of start address - 14..15 Checksum in hex notation - 16..17 Carriage return, line feed -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libiberty.h" - -#include - -static void ihex_init PARAMS ((void)); -static boolean ihex_mkobject PARAMS ((bfd *)); -static INLINE int ihex_get_byte PARAMS ((bfd *, boolean *)); -static void ihex_bad_byte PARAMS ((bfd *, unsigned int, int, boolean)); -static boolean ihex_scan PARAMS ((bfd *)); -static const bfd_target *ihex_object_p PARAMS ((bfd *)); -static boolean ihex_read_section PARAMS ((bfd *, asection *, bfd_byte *)); -static boolean ihex_get_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); -static boolean ihex_set_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); -static boolean ihex_write_record - PARAMS ((bfd *, bfd_size_type, bfd_vma, unsigned int, bfd_byte *)); -static boolean ihex_write_object_contents PARAMS ((bfd *)); -static asymbol *ihex_make_empty_symbol PARAMS ((bfd *)); -static boolean ihex_set_arch_mach - PARAMS ((bfd *, enum bfd_architecture, unsigned long)); - -/* The number of bytes we put on one line during output. */ - -#define CHUNK (21) - -/* Macros for converting between hex and binary. */ - -#define NIBBLE(x) (hex_value (x)) -#define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1])) -#define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2)) -#define ISHEX(x) (hex_p (x)) - -/* When we write out an ihex value, the values can not be output as - they are seen. Instead, we hold them in memory in this structure. */ - -struct ihex_data_list -{ - struct ihex_data_list *next; - bfd_byte *data; - bfd_vma where; - bfd_size_type size; -}; - -/* The ihex tdata information. */ - -struct ihex_data_struct -{ - struct ihex_data_list *head; - struct ihex_data_list *tail; -}; - -/* Initialize by filling in the hex conversion array. */ - -static void -ihex_init () -{ - static boolean inited; - - if (! inited) - { - inited = true; - hex_init (); - } -} - -/* Create an ihex object. */ - -static boolean -ihex_mkobject (abfd) - bfd *abfd; -{ - if (abfd->tdata.ihex_data == NULL) - { - struct ihex_data_struct *tdata; - - tdata = ((struct ihex_data_struct *) - bfd_alloc (abfd, sizeof (struct ihex_data_struct))); - if (tdata == NULL) - return false; - abfd->tdata.ihex_data = tdata; - tdata->head = NULL; - tdata->tail = NULL; - } - - return true; -} - -/* Read a byte from a BFD. Set *ERRORPTR if an error occurred. - Return EOF on error or end of file. */ - -static INLINE int -ihex_get_byte (abfd, errorptr) - bfd *abfd; - boolean *errorptr; -{ - bfd_byte c; - - if (bfd_read (&c, 1, 1, abfd) != 1) - { - if (bfd_get_error () != bfd_error_file_truncated) - *errorptr = true; - return EOF; - } - - return (int) (c & 0xff); -} - -/* Report a problem in an Intel Hex file. */ - -static void -ihex_bad_byte (abfd, lineno, c, error) - bfd *abfd; - unsigned int lineno; - int c; - boolean error; -{ - if (c == EOF) - { - if (! error) - bfd_set_error (bfd_error_file_truncated); - } - else - { - char buf[10]; - - if (! isprint (c)) - sprintf (buf, "\\%03o", (unsigned int) c); - else - { - buf[0] = c; - buf[1] = '\0'; - } - (*_bfd_error_handler) - ("%s:%d: unexpected character `%s' in Intel Hex file\n", - bfd_get_filename (abfd), lineno, buf); - bfd_set_error (bfd_error_bad_value); - } -} - -/* Read an Intel hex file and turn it into sections. We create a new - section for each contiguous set of bytes. */ - -static boolean -ihex_scan (abfd) - bfd *abfd; -{ - bfd_vma segbase; - bfd_vma extbase; - asection *sec; - int lineno; - boolean error; - bfd_byte *buf; - size_t bufsize; - int c; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto error_return; - - abfd->start_address = 0; - - extbase = 0; - segbase = 0; - sec = NULL; - lineno = 1; - error = false; - buf = NULL; - bufsize = 0; - while ((c = ihex_get_byte (abfd, &error)) != EOF) - { - if (c == '\r') - continue; - else if (c == '\n') - { - ++lineno; - continue; - } - else if (c != ':') - { - ihex_bad_byte (abfd, lineno, c, error); - goto error_return; - } - else - { - file_ptr pos; - char hdr[8]; - unsigned int i; - unsigned int len; - bfd_vma addr; - unsigned int type; - unsigned int chars; - unsigned int chksum; - - /* This is a data record. */ - - pos = bfd_tell (abfd) - 1; - - /* Read the header bytes. */ - - if (bfd_read (hdr, 1, 8, abfd) != 8) - goto error_return; - - for (i = 0; i < 8; i++) - { - if (! ISHEX (hdr[i])) - { - ihex_bad_byte (abfd, lineno, hdr[i], error); - goto error_return; - } - } - - len = HEX2 (hdr); - addr = HEX4 (hdr + 2); - type = HEX2 (hdr + 6); - - /* Read the data bytes. */ - - chars = len * 2 + 2; - if (chars >= bufsize) - { - buf = (bfd_byte *) bfd_realloc (buf, chars); - if (buf == NULL) - goto error_return; - bufsize = chars; - } - - if (bfd_read (buf, 1, chars, abfd) != chars) - goto error_return; - - for (i = 0; i < chars; i++) - { - if (! ISHEX (buf[i])) - { - ihex_bad_byte (abfd, lineno, hdr[i], error); - goto error_return; - } - } - - /* Check the checksum. */ - chksum = len + addr + (addr >> 8) + type; - for (i = 0; i < len; i++) - chksum += HEX2 (buf + 2 * i); - if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i)) - { - (*_bfd_error_handler) - ("%s:%d: bad checksum in Intel Hex file (expected %u, found %u)", - bfd_get_filename (abfd), lineno, - (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i)); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - switch (type) - { - case 0: - /* This is a data record. */ - if (sec != NULL - && sec->vma + sec->_raw_size == extbase + segbase + addr) - { - /* This data goes at the end of the section we are - currently building. */ - sec->_raw_size += len; - } - else if (len > 0) - { - char secbuf[20]; - char *secname; - - sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1); - secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1); - if (secname == NULL) - goto error_return; - strcpy (secname, secbuf); - sec = bfd_make_section (abfd, secname); - if (sec == NULL) - goto error_return; - sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - sec->vma = extbase + segbase + addr; - sec->lma = extbase + segbase + addr; - sec->_raw_size = len; - sec->filepos = pos; - } - break; - - case 1: - /* An end record. */ - if (abfd->start_address == 0) - abfd->start_address = addr; - if (buf != NULL) - free (buf); - return true; - - case 2: - /* An extended address record. */ - if (len != 2) - { - (*_bfd_error_handler) - ("%s:%d: bad extended address record length in Intel Hex file", - bfd_get_filename (abfd), lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - segbase = HEX4 (buf) << 4; - - sec = NULL; - - break; - - case 3: - /* An extended start address record. */ - if (len != 4) - { - (*_bfd_error_handler) - ("%s:%d: bad extended start address length in Intel Hex file", - bfd_get_filename (abfd), lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4); - - sec = NULL; - - break; - - case 4: - /* An extended linear address record. */ - if (len != 2) - { - (*_bfd_error_handler) - ("%s:%d: bad extended linear address record length in Intel Hex file", - bfd_get_filename (abfd), lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - segbase = HEX4 (buf) << 16; - - sec = NULL; - - break; - - case 5: - /* An extended linear start address record. */ - if (len != 2) - { - (*_bfd_error_handler) - ("%s:%d: bad extended linear start address length in Intel Hex file", - bfd_get_filename (abfd), lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - abfd->start_address += HEX4 (buf) << 16; - - sec = NULL; - - break; - - default: - (*_bfd_error_handler) - ("%s:%d: unrecognized ihex type %u in Intel Hex file\n", - bfd_get_filename (abfd), lineno, type); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - } - } - - if (error) - goto error_return; - - if (buf != NULL) - free (buf); - - return true; - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Try to recognize an Intel Hex file. */ - -static const bfd_target * -ihex_object_p (abfd) - bfd *abfd; -{ - bfd_byte b[9]; - unsigned int i; - unsigned int type; - - ihex_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return NULL; - if (bfd_read (b, 1, 9, abfd) != 9) - { - if (bfd_get_error () == bfd_error_file_truncated) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (b[0] != ':') - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - for (i = 1; i < 9; i++) - { - if (! ISHEX (b[i])) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - } - - type = HEX2 (b + 7); - if (type > 5) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* OK, it looks like it really is an Intel Hex file. */ - - if (! ihex_mkobject (abfd) - || ! ihex_scan (abfd)) - return NULL; - - return abfd->xvec; -} - -/* Read the contents of a section in an Intel Hex file. */ - -static boolean -ihex_read_section (abfd, section, contents) - bfd *abfd; - asection *section; - bfd_byte *contents; -{ - int c; - bfd_byte *p; - bfd_byte *buf; - size_t bufsize; - boolean error; - - if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0) - goto error_return; - - p = contents; - buf = NULL; - bufsize = 0; - error = false; - while ((c = ihex_get_byte (abfd, &error)) != EOF) - { - char hdr[8]; - unsigned int len; - bfd_vma addr; - unsigned int type; - unsigned int i; - - if (c == '\r' || c == '\n') - continue; - - /* This is called after ihex_scan has succeeded, so we ought to - know the exact format. */ - BFD_ASSERT (c == ':'); - - if (bfd_read (hdr, 1, 8, abfd) != 8) - goto error_return; - - len = HEX2 (hdr); - addr = HEX4 (hdr + 2); - type = HEX2 (hdr + 6); - - /* We should only see type 0 records here. */ - if (type != 0) - { - (*_bfd_error_handler) - ("%s: internal error in ihex_read_section", - bfd_get_filename (abfd)); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (len * 2 > bufsize) - { - buf = (bfd_byte *) bfd_realloc (buf, len * 2); - if (buf == NULL) - goto error_return; - bufsize = len * 2; - } - - if (bfd_read (buf, 1, len * 2, abfd) != len * 2) - goto error_return; - - for (i = 0; i < len; i++) - *p++ = HEX2 (buf + 2 * i); - if ((bfd_size_type) (p - contents) >= section->_raw_size) - { - /* We've read everything in the section. */ - if (buf != NULL) - free (buf); - return true; - } - - /* Skip the checksum. */ - if (bfd_read (buf, 1, 2, abfd) != 2) - goto error_return; - } - - if ((bfd_size_type) (p - contents) < section->_raw_size) - { - (*_bfd_error_handler) - ("%s: bad section length in ihex_read_section", - bfd_get_filename (abfd)); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (buf != NULL) - free (buf); - - return true; - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Get the contents of a section in an Intel Hex file. */ - -static boolean -ihex_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (section->used_by_bfd == NULL) - { - section->used_by_bfd = bfd_alloc (abfd, section->_raw_size); - if (section->used_by_bfd == NULL) - return false; - if (! ihex_read_section (abfd, section, section->used_by_bfd)) - return false; - } - - memcpy (location, (bfd_byte *) section->used_by_bfd + offset, - (size_t) count); - - return true; -} - -/* Set the contents of a section in an Intel Hex file. */ - -static boolean -ihex_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - struct ihex_data_list *n; - bfd_byte *data; - struct ihex_data_struct *tdata; - - if (count == 0 - || (section->flags & SEC_ALLOC) == 0 - || (section->flags & SEC_LOAD) == 0) - return true; - - n = ((struct ihex_data_list *) - bfd_alloc (abfd, sizeof (struct ihex_data_list))); - if (n == NULL) - return false; - - data = (bfd_byte *) bfd_alloc (abfd, count); - if (data == NULL) - return false; - memcpy (data, location, (size_t) count); - - n->data = data; - n->where = section->lma + offset; - n->size = count; - - /* Sort the records by address. Optimize for the common case of - adding a record to the end of the list. */ - tdata = abfd->tdata.ihex_data; - if (tdata->tail != NULL - && n->where >= tdata->tail->where) - { - tdata->tail->next = n; - n->next = NULL; - tdata->tail = n; - } - else - { - register struct ihex_data_list **pp; - - for (pp = &tdata->head; - *pp != NULL && (*pp)->where < n->where; - pp = &(*pp)->next) - ; - n->next = *pp; - *pp = n; - if (n->next == NULL) - tdata->tail = n; - } - - return true; -} - -/* Write a record out to an Intel Hex file. */ - -static boolean -ihex_write_record (abfd, count, addr, type, data) - bfd *abfd; - bfd_size_type count; - bfd_vma addr; - unsigned int type; - bfd_byte *data; -{ - static const char digs[] = "0123456789ABCDEF"; - char buf[9 + CHUNK * 2 + 4]; - char *p; - unsigned int chksum; - unsigned int i; - -#define TOHEX(buf, v) \ - ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf]) - - buf[0] = ':'; - TOHEX (buf + 1, count); - TOHEX (buf + 3, (addr >> 8) & 0xff); - TOHEX (buf + 5, addr & 0xff); - TOHEX (buf + 7, type); - - chksum = count + addr + (addr >> 8) + type; - - for (i = 0, p = buf + 9; i < count; i++, p += 2, data++) - { - TOHEX (p, *data); - chksum += *data; - } - - TOHEX (p, (- chksum) & 0xff); - p[2] = '\r'; - p[3] = '\n'; - - if (bfd_write (buf, 1, 9 + count * 2 + 4, abfd) != 9 + count * 2 + 4) - return false; - - return true; -} - -/* Write out an Intel Hex file. */ - -static boolean -ihex_write_object_contents (abfd) - bfd *abfd; -{ - bfd_vma extbase; - bfd_vma segbase; - struct ihex_data_list *l; - - extbase = 0; - segbase = 0; - for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next) - { - bfd_vma where; - bfd_byte *p; - bfd_size_type count; - - where = l->where; - p = l->data; - count = l->size; - while (count > 0) - { - bfd_size_type now; - - now = count; - if (now > CHUNK) - now = CHUNK; - - if (where > extbase + segbase + 0xffff) - { - bfd_byte addr[2]; - - /* We need a new base address. */ - if (where <= 0xfffff) - { - segbase = where & 0xf0000; - addr[0] = (segbase >> 12) & 0xff; - addr[1] = (segbase >> 4) & 0xff; - if (! ihex_write_record (abfd, 2, 0, 2, addr)) - return false; - } - else - { - extbase = where & 0xffff0000; - if (where > extbase + 0xffff) - { - char buf[20]; - - sprintf_vma (buf, where); - (*_bfd_error_handler) - ("%s: address 0x%s out of range for Intex Hex file", - bfd_get_filename (abfd), buf); - bfd_set_error (bfd_error_bad_value); - return false; - } - addr[0] = (extbase >> 24) & 0xff; - addr[1] = (extbase >> 16) & 0xff; - if (! ihex_write_record (abfd, 2, 0, 4, addr)) - return false; - } - } - - if (! ihex_write_record (abfd, now, where - (extbase + segbase), - 0, p)) - return false; - - where += now; - p += now; - count -= now; - } - } - - if (abfd->start_address != 0) - { - bfd_vma start; - bfd_byte startbuf[4]; - - start = abfd->start_address; - - if (start > 0xfffff) - { - startbuf[0] = (start >> 24) & 0xff; - startbuf[1] = (start >> 16) & 0xff; - if (! ihex_write_record (abfd, 2, 0, 5, startbuf)) - return false; - start &= 0xffff; - } - - startbuf[0] = ((start & 0xf0000) >> 12) & 0xff; - startbuf[1] = 0; - startbuf[2] = (start >> 8) & 0xff; - startbuf[3] = start & 0xff; - if (! ihex_write_record (abfd, 4, 0, 3, startbuf)) - return false; - } - - if (! ihex_write_record (abfd, 0, 0, 1, NULL)) - return false; - - return true; -} - -/* Make an empty symbol. This is required only because - bfd_make_section_anyway wants to create a symbol for the section. */ - -static asymbol * -ihex_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new; - - new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new != NULL) - new->the_bfd = abfd; - return new; -} - -/* Set the architecture for the output file. The architecture is - irrelevant, so we ignore errors about unknown architectures. */ - -static boolean -ihex_set_arch_mach (abfd, arch, mach) - bfd *abfd; - enum bfd_architecture arch; - unsigned long mach; -{ - if (! bfd_default_set_arch_mach (abfd, arch, mach)) - { - if (arch != bfd_arch_unknown) - return false; - } - return true; -} - -/* Get the size of the headers, for the linker. */ - -/*ARGSUSED*/ -static int -ihex_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -/* Some random definitions for the target vector. */ - -#define ihex_close_and_cleanup _bfd_generic_close_and_cleanup -#define ihex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define ihex_new_section_hook _bfd_generic_new_section_hook -#define ihex_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define ihex_get_symtab_upper_bound bfd_0l -#define ihex_get_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) bfd_0l) -#define ihex_print_symbol _bfd_nosymbols_print_symbol -#define ihex_get_symbol_info _bfd_nosymbols_get_symbol_info -#define ihex_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define ihex_get_lineno _bfd_nosymbols_get_lineno -#define ihex_find_nearest_line _bfd_nosymbols_find_nearest_line -#define ihex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define ihex_read_minisymbols _bfd_nosymbols_read_minisymbols -#define ihex_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -#define ihex_get_reloc_upper_bound \ - ((long (*) PARAMS ((bfd *, asection *))) bfd_0l) -#define ihex_canonicalize_reloc \ - ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l) -#define ihex_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define ihex_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define ihex_bfd_relax_section bfd_generic_relax_section -#define ihex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define ihex_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define ihex_bfd_final_link _bfd_generic_final_link -#define ihex_bfd_link_split_section _bfd_generic_link_split_section - -/* The Intel Hex target vector. */ - -const bfd_target ihex_vec = -{ - "ihex", /* name */ - bfd_target_ihex_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - 0, /* object flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - ihex_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - ihex_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - ihex_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (ihex), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (ihex), - BFD_JUMP_TABLE_RELOCS (ihex), - BFD_JUMP_TABLE_WRITE (ihex), - BFD_JUMP_TABLE_LINK (ihex), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/init.c b/contrib/gdb/bfd/init.c deleted file mode 100644 index 1fa1d505bee..00000000000 --- a/contrib/gdb/bfd/init.c +++ /dev/null @@ -1,50 +0,0 @@ -/* bfd initialization stuff - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* -SECTION - Initialization - - These are the functions that handle initializing a BFD. -*/ - -/* -FUNCTION - bfd_init - -SYNOPSIS - void bfd_init(void); - -DESCRIPTION - This routine must be called before any other BFD function to - initialize magical internal data structures. -*/ - -/* Actually, there is currently nothing for this function to do. - However, someday it may be needed, so keep it around. */ - -void -bfd_init () -{ -} diff --git a/contrib/gdb/bfd/irix-core.c b/contrib/gdb/bfd/irix-core.c deleted file mode 100644 index 3fd39772ce8..00000000000 --- a/contrib/gdb/bfd/irix-core.c +++ /dev/null @@ -1,263 +0,0 @@ -/* BFD back-end for Irix core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Stu Grossman, Cygnus Support. - Converted to back-end form by Ian Lance Taylor, Cygnus Support - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file can only be compiled on systems which use Irix style core - files (namely, Irix 4 and Irix 5, so far). */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifdef IRIX_CORE - -#include - -struct sgi_core_struct -{ - int sig; - char cmd[CORE_NAMESIZE]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - file_ptr filepos; -{ - asection *asect; - - asect = bfd_make_section_anyway (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = filepos; - asect->alignment_power = 4; - - return asect; -} - -static const bfd_target * -irix_core_core_file_p (abfd) - bfd *abfd; -{ - int val; - int i; - char *secname; - struct coreout coreout; - struct idesc *idg, *idf, *ids; - - val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd); - if (val != sizeof coreout) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (coreout.c_magic != CORE_MAGIC - || coreout.c_version != CORE_VERSION1) - return 0; - - core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct)); - if (!core_hdr (abfd)) - return NULL; - - strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE); - core_signal (abfd) = coreout.c_sigcause; - - if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0) - return NULL; - - for (i = 0; i < coreout.c_nvmap; i++) - { - struct vmap vmap; - - val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd); - if (val != sizeof vmap) - break; - - switch (vmap.v_type) - { - case VDATA: - secname = ".data"; - break; - case VSTACK: - secname = ".stack"; - break; -#ifdef VMAPFILE - case VMAPFILE: - secname = ".mapfile"; - break; -#endif - default: - continue; - } - - /* A file offset of zero means that the section is not contained - in the corefile. */ - if (vmap.v_offset == 0) - continue; - - if (!make_bfd_asection (abfd, secname, - SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS, - vmap.v_len, - vmap.v_vaddr, - vmap.v_offset, - 2)) - return NULL; - } - - /* Make sure that the regs are contiguous within the core file. */ - - idg = &coreout.c_idesc[I_GPREGS]; - idf = &coreout.c_idesc[I_FPREGS]; - ids = &coreout.c_idesc[I_SPECREGS]; - - if (idg->i_offset + idg->i_len != idf->i_offset - || idf->i_offset + idf->i_len != ids->i_offset) - return 0; /* Can't deal with non-contig regs */ - - if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0) - return NULL; - - make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - idg->i_len + idf->i_len + ids->i_len, - 0, - idg->i_offset); - - /* OK, we believe you. You're a core file (sure, sure). */ - - return abfd->xvec; -} - -static char * -irix_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -static int -irix_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -static boolean -irix_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* XXX - FIXME */ -} - -static asymbol * -irix_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -#define irix_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define irix_core_get_symtab _bfd_nosymbols_get_symtab -#define irix_core_print_symbol _bfd_nosymbols_print_symbol -#define irix_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define irix_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define irix_core_get_lineno _bfd_nosymbols_get_lineno -#define irix_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define irix_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define irix_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define irix_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target irix_core_vec = - { - "irix-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - irix_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (irix_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (irix_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; - -#endif /* IRIX_CORE */ diff --git a/contrib/gdb/bfd/libaout.h b/contrib/gdb/bfd/libaout.h deleted file mode 100644 index 76c1dff7cdb..00000000000 --- a/contrib/gdb/bfd/libaout.h +++ /dev/null @@ -1,608 +0,0 @@ -/* BFD back-end data structures for a.out (and similar) files. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 -#define GET_WORD bfd_h_get_64 -#define GET_SWORD bfd_h_get_signed_64 -#define PUT_WORD bfd_h_put_64 -#ifndef NAME -#define NAME(x,y) CAT3(x,_64_,y) -#endif -#define JNAME(x) CAT(x,_64) -#define BYTES_IN_WORD 8 -#else /* ARCH_SIZE == 32 */ -#define GET_WORD bfd_h_get_32 -#define GET_SWORD bfd_h_get_signed_32 -#define PUT_WORD bfd_h_put_32 -#ifndef NAME -#define NAME(x,y) CAT3(x,_32_,y) -#endif -#define JNAME(x) CAT(x,_32) -#define BYTES_IN_WORD 4 -#endif /* ARCH_SIZE==32 */ - -/* Declare at file level, since used in parameter lists, which have - weird scope. */ -struct external_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 -{ - /* Are ZMAGIC files mapped contiguously? If so, the text section may - need more padding, if the segment size (granularity for memory access - control) is larger than the page size. */ - unsigned char zmagic_mapped_contiguous; - /* If this flag is set, ZMAGIC/NMAGIC file headers get mapped in with the - text section, which starts immediately after the file header. - If not, the text section starts on the next page. */ - unsigned char text_includes_header; - - /* 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. */ - /* ?? Perhaps a callback would be a better choice? Will this do anything - reasonable for a format that handles multiple CPUs with different - load addresses for each? */ - bfd_vma default_text_vma; - - /* Callback for setting the page and segment sizes, if they can't be - trivially determined from the architecture. */ - boolean (*set_sizes) PARAMS ((bfd *)); - - /* zmagic files only. For go32, the length of the exec header contributes - to the size of the text section in the file for alignment purposes but - does *not* get counted in the length of the text section. */ - unsigned char exec_header_not_counted; - - /* 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 *, - struct external_nlist **, - bfd_size_type *, char **)); - - /* 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 *)); - - /* If this callback is not NULL, the linker calls it for each reloc. - RELOC is a pointer to the unswapped reloc. If *SKIP is set to - true, the reloc will be skipped. *RELOCATION may be changed to - change the effects of the relocation. */ - boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - struct aout_link_hash_entry *h, - PTR reloc, bfd_byte *contents, - boolean *skip, - bfd_vma *relocation)); - - /* 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)) - -/* This is the layout in memory of a "struct exec" while we process it. - All 'lengths' are given as a number of bytes. - All 'alignments' are for relinkable files only; an alignment of - 'n' indicates the corresponding segment must begin at an - address that is a multiple of (2**n). */ - -struct internal_exec -{ - long a_info; /* Magic number and flags, packed */ - bfd_vma a_text; /* length of text, in bytes */ - bfd_vma a_data; /* length of data, in bytes */ - bfd_vma a_bss; /* length of uninitialized data area in mem */ - bfd_vma a_syms; /* length of symbol table data in file */ - bfd_vma a_entry; /* start address */ - bfd_vma a_trsize; /* length of text's relocation info, in bytes */ - bfd_vma a_drsize; /* length of data's relocation info, in bytes */ - /* Added for i960 */ - bfd_vma a_tload; /* Text runtime load address */ - bfd_vma a_dload; /* Data runtime load address */ - unsigned char a_talign; /* Alignment of text segment */ - unsigned char a_dalign; /* Alignment of data segment */ - unsigned char a_balign; /* Alignment of bss segment */ - char a_relaxable; /* Enough info for linker relax */ -}; - -/* Magic number is written -< MSB > -3130292827262524232221201918171615141312111009080706050403020100 -< FLAGS >< MACHINE TYPE >< MAGIC NUMBER > -*/ -/* Magic number for NetBSD is - -3130292827262524232221201918171615141312111009080706050403020100 -< FLAGS >< >< MAGIC NUMBER > -*/ - -enum machine_type { - M_UNKNOWN = 0, - M_68010 = 1, - M_68020 = 2, - M_SPARC = 3, - /* skip a bunch so we don't run into any of suns numbers */ - /* 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_ARM = 103, /* Advanced Risc Machines ARM */ - M_386_NETBSD = 134, /* NetBSD/i386 binary */ - M_68K_NETBSD = 135, /* NetBSD/m68k binary */ - M_68K4K_NETBSD = 136, /* NetBSD/m68k4k binary */ - M_532_NETBSD = 137, /* NetBSD/ns32k binary */ - M_SPARC_NETBSD = 138, /* NetBSD/sparc binary */ - M_MIPS1 = 151, /* MIPS R2000/R3000 binary */ - M_MIPS2 = 152, /* MIPS R4000/R6000 binary */ - M_HP200 = 200, /* HP 200 (68010) BSD binary */ - M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */ - M_HPUX = (0x20c % 256)/* HP 200/300 HPUX binary */ -}; - -#define N_DYNAMIC(exec) ((exec).a_info & 0x80000000) - -#ifndef N_MAGIC -# define N_MAGIC(exec) ((exec).a_info & 0xffff) -#endif - -#ifndef N_MACHTYPE -# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff)) -#endif - -#ifndef N_FLAGS -# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff) -#endif - -#ifndef N_SET_INFO -# define N_SET_INFO(exec, magic, type, flags) \ -((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0xff) << 16) \ - | (((flags) & 0xff) << 24)) -#endif - -#ifndef N_SET_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))) -#endif - -#ifndef N_SET_MACHTYPE -# define N_SET_MACHTYPE(exec, machtype) \ -((exec).a_info = \ - ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16)) -#endif - -#ifndef N_SET_FLAGS -# define N_SET_FLAGS(exec, flags) \ -((exec).a_info = \ - ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24)) -#endif - -typedef struct aout_symbol { - asymbol symbol; - short desc; - char other; - unsigned char type; -} aout_symbol_type; - -/* The `tdata' struct for all a.out-like object file formats. - Various things depend on this struct being around any time an a.out - file is being handled. An example is dbxread.c in GDB. */ - -struct aoutdata { - struct internal_exec *hdr; /* exec file header */ - aout_symbol_type *symbols; /* symtab for input bfd */ - - /* For ease, we do this */ - asection *textsec; - asection *datasec; - asection *bsssec; - - /* We remember these offsets so that after check_file_format, we have - no dependencies on the particular format of the exec_hdr. */ - file_ptr sym_filepos; - file_ptr str_filepos; - - /* Size of a relocation entry in external form */ - unsigned reloc_entry_size; - - /* Size of a symbol table entry in external form */ - unsigned symbol_entry_size; - - /* Page size - needed for alignment of demand paged files. */ - unsigned long page_size; - - /* Segment size - needed for alignment of demand paged files. */ - unsigned long segment_size; - - /* 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, - /* 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; - - /* A buffer for find_nearest_line. */ - char *line_buf; - - /* The external symbol information. */ - struct external_nlist *external_syms; - bfd_size_type external_sym_count; - bfd_window sym_window; - char *external_strings; - bfd_size_type external_string_size; - bfd_window string_window; - struct aout_link_hash_entry **sym_hashes; - - /* A pointer for shared library information. */ - PTR dynamic_info; - - /* A mapping from local symbols to offsets into the global offset - table, used when linking on SunOS. This is indexed by the symbol - index. */ - bfd_vma *local_got_offsets; -}; - -struct aout_data_struct { - struct aoutdata a; - struct internal_exec e; -}; - -#define adata(bfd) ((bfd)->tdata.aout_data->a) -#define exec_hdr(bfd) (adata(bfd).hdr) -#define obj_aout_symbols(bfd) (adata(bfd).symbols) -#define obj_textsec(bfd) (adata(bfd).textsec) -#define obj_datasec(bfd) (adata(bfd).datasec) -#define obj_bsssec(bfd) (adata(bfd).bsssec) -#define obj_sym_filepos(bfd) (adata(bfd).sym_filepos) -#define obj_str_filepos(bfd) (adata(bfd).str_filepos) -#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size) -#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size) -#define obj_aout_subformat(bfd) (adata(bfd).subformat) -#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_sym_window(bfd) (adata(bfd).sym_window) -#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_string_window(bfd) (adata(bfd).string_window) -#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) - -#define set_aout_section_data(s,v) \ - ((s)->used_by_bfd = (PTR)&(v)->relocs) - -/* Prototype declarations for functions defined in aoutx.h */ - -boolean -NAME(aout,squirt_out_relocs) PARAMS ((bfd *abfd, asection *section)); - -boolean -NAME(aout,make_sections) PARAMS ((bfd *)); - -const bfd_target * -NAME(aout,some_aout_object_p) PARAMS ((bfd *abfd, - 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, - boolean *unknown)); - -boolean -NAME(aout,set_arch_mach) PARAMS ((bfd *abfd, enum bfd_architecture arch, - unsigned long machine)); - -boolean -NAME(aout,new_section_hook) PARAMS ((bfd *abfd, asection *newsect)); - -boolean -NAME(aout,set_section_contents) PARAMS ((bfd *abfd, sec_ptr section, - PTR location, file_ptr offset, bfd_size_type count)); - -asymbol * -NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd)); - -boolean -NAME(aout,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)); - -boolean -NAME(aout,write_syms) PARAMS ((bfd *abfd)); - -void -NAME(aout,reclaim_symbol_table) PARAMS ((bfd *abfd)); - -long -NAME(aout,get_symtab_upper_bound) PARAMS ((bfd *abfd)); - -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 **, bfd_size_type)); -void -NAME(aout,swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *, - arelent *, asymbol **, bfd_size_type)); - -reloc_howto_type * -NAME(aout,reloc_type_lookup) PARAMS ((bfd *abfd, - bfd_reloc_code_real_type code)); - -boolean -NAME(aout,slurp_reloc_table) PARAMS ((bfd *abfd, sec_ptr asect, - asymbol **symbols)); - -long -NAME(aout,canonicalize_reloc) PARAMS ((bfd *abfd, sec_ptr section, - arelent **relptr, asymbol **symbols)); - -long -NAME(aout,get_reloc_upper_bound) PARAMS ((bfd *abfd, sec_ptr asect)); - -void -NAME(aout,reclaim_reloc) PARAMS ((bfd *ignore_abfd, sec_ptr ignore)); - -alent * -NAME(aout,get_lineno) PARAMS ((bfd *ignore_abfd, asymbol *ignore_symbol)); - -void -NAME(aout,print_symbol) PARAMS ((bfd *ignore_abfd, PTR file, - asymbol *symbol, bfd_print_symbol_type how)); - -void -NAME(aout,get_symbol_info) PARAMS ((bfd *ignore_abfd, - asymbol *symbol, symbol_info *ret)); - -boolean -NAME(aout,find_nearest_line) PARAMS ((bfd *abfd, asection *section, - asymbol **symbols, bfd_vma offset, CONST char **filename_ptr, - CONST char **functionname_ptr, unsigned int *line_ptr)); - -long -NAME(aout,read_minisymbols) PARAMS ((bfd *, boolean, PTR *, unsigned int *)); - -asymbol * -NAME(aout,minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR, - asymbol *)); - -int -NAME(aout,sizeof_headers) PARAMS ((bfd *abfd, boolean exec)); - -boolean -NAME(aout,adjust_sizes_and_vmas) PARAMS ((bfd *abfd, - bfd_size_type *text_size, file_ptr *text_end)); - -void -NAME(aout,swap_exec_header_in) PARAMS ((bfd *abfd, - struct external_exec *raw_bytes, struct internal_exec *execp)); - -void -NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd, - struct internal_exec *execp, struct external_exec *raw_bytes)); - -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 *)); - -/* A.out uses the generic versions of these routines... */ - -#define aout_32_get_section_contents _bfd_generic_get_section_contents - -#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) \ - { \ - bfd_size_type text_size; /* dummy vars */ \ - file_ptr text_end; \ - if (adata(abfd).magic == undecided_magic) \ - NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ - \ - execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ - execp->a_entry = bfd_get_start_address (abfd); \ - \ - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ - \ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \ - if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \ - != EXEC_BYTES_SIZE) \ - return false; \ - /* Now write out reloc info, followed by syms and strings */ \ - \ - if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \ - && bfd_get_symcount (abfd) != 0) \ - { \ - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (! NAME(aout,write_syms)(abfd)) return false; \ - \ - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (!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; \ - } \ - } -#endif - -#endif /* ! defined (LIBAOUT_H) */ diff --git a/contrib/gdb/bfd/libbfd-in.h b/contrib/gdb/bfd/libbfd-in.h deleted file mode 100644 index 14935ebbeab..00000000000 --- a/contrib/gdb/bfd/libbfd-in.h +++ /dev/null @@ -1,503 +0,0 @@ -/* libbfd.h -- Declarations used by bfd library *implementation*. - (This include file is not for users of the library.) - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -** NOTE: libbfd.h is a GENERATED file. Don't change it; instead, -** change libbfd-in.h or the other BFD source files processed to -** generate this file. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Align an address upward to a boundary, expressed as a number of bytes. - E.g. align to an 8-byte boundary with argument of 8. */ -#define BFD_ALIGN(this, boundary) \ - ((( (this) + ((boundary) -1)) & (~((boundary)-1)))) - -/* If you want to read and write large blocks, you might want to do it - in quanta of this amount */ -#define DEFAULT_BUFFERSIZE 8192 - -/* Set a tdata field. Can't use the other macros for this, since they - do casts, and casting to the left of assignment isn't portable. */ -#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v)) - -/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points - to an instance of this structure. */ - -struct bfd_in_memory -{ - /* Size of buffer. */ - bfd_size_type size; - /* Buffer holding contents of BFD. */ - bfd_byte *buffer; -}; - -/* tdata for an archive. For an input archive, cache - needs to be free()'d. For an output archive, symdefs do. */ - -struct artdata { - file_ptr first_file_filepos; - /* Speed up searching the armap */ - struct ar_cache *cache; - bfd *archive_head; /* Only interesting in output routines */ - carsym *symdefs; /* the symdef entries */ - symindex symdef_count; /* how many there are */ - char *extended_names; /* clever intel extension */ - /* when more compilers are standard C, this can be a time_t */ - long armap_timestamp; /* Timestamp value written into armap. - This is used for BSD archives to check - that the timestamp is recent enough - for the BSD linker to not complain, - just before we finish writing an - archive. */ - file_ptr armap_datepos; /* Position within archive to seek to - rewrite the date field. */ - PTR tdata; /* Backend specific information. */ -}; - -#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data) - -/* Goes in bfd's arelt_data slot */ -struct areltdata { - char * arch_header; /* it's actually a string */ - unsigned int parsed_size; /* octets of filesize not including ar_hdr */ - char *filename; /* null-terminated */ -}; - -#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size) - -extern PTR bfd_malloc PARAMS ((size_t)); -extern PTR bfd_realloc PARAMS ((PTR, size_t)); -extern PTR bfd_zmalloc PARAMS ((size_t)); - -extern bfd_error_handler_type _bfd_error_handler; - -/* These routines allocate and free things on the BFD's obstack. */ - -PTR bfd_alloc PARAMS ((bfd *abfd, size_t size)); -PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size)); -void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size)); -PTR bfd_alloc_finish PARAMS ((bfd *abfd)); -PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted)); - -#define bfd_release(x,y) (void) obstack_free(&(x->memory),y) - -bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd)); -bfd * _bfd_look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index)); -boolean _bfd_add_bfd_to_archive_cache PARAMS ((bfd *, file_ptr, bfd *)); -boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd)); -const bfd_target *bfd_generic_archive_p PARAMS ((bfd *abfd)); -boolean bfd_slurp_armap PARAMS ((bfd *abfd)); -boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd)); -#define bfd_slurp_bsd_armap bfd_slurp_armap -#define bfd_slurp_coff_armap bfd_slurp_armap -boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd)); -extern boolean _bfd_construct_extended_name_table - PARAMS ((bfd *, boolean, char **, bfd_size_type *)); -boolean _bfd_write_archive_contents PARAMS ((bfd *abfd)); -boolean _bfd_compute_and_write_armap PARAMS ((bfd *, unsigned int elength)); -bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos)); -extern bfd *_bfd_generic_get_elt_at_index PARAMS ((bfd *, symindex)); -bfd * _bfd_new_bfd PARAMS ((void)); - -boolean bfd_false PARAMS ((bfd *ignore)); -boolean bfd_true PARAMS ((bfd *ignore)); -PTR bfd_nullvoidptr PARAMS ((bfd *ignore)); -int bfd_0 PARAMS ((bfd *ignore)); -unsigned int bfd_0u PARAMS ((bfd *ignore)); -long bfd_0l PARAMS ((bfd *ignore)); -long _bfd_n1 PARAMS ((bfd *ignore)); -void bfd_void PARAMS ((bfd *ignore)); - -bfd *_bfd_new_bfd_contained_in PARAMS ((bfd *)); -const bfd_target *_bfd_dummy_target PARAMS ((bfd *abfd)); - -void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); - -boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -extern PTR _bfd_generic_read_ar_hdr PARAMS ((bfd *)); - -extern PTR _bfd_generic_read_ar_hdr_mag PARAMS ((bfd *, const char *)); - -bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive, - bfd *last_file)); - -int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); - -#define _bfd_read_ar_hdr(abfd) \ - BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd)) - -/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use - BFD_JUMP_TABLE_GENERIC (_bfd_generic). */ - -#define _bfd_generic_close_and_cleanup bfd_true -#define _bfd_generic_bfd_free_cached_info bfd_true -#define _bfd_generic_new_section_hook \ - ((boolean (*) PARAMS ((bfd *, asection *))) bfd_true) -extern boolean _bfd_generic_get_section_contents - PARAMS ((bfd *, asection *, PTR location, file_ptr offset, - bfd_size_type count)); -extern boolean _bfd_generic_get_section_contents_in_window - PARAMS ((bfd *, asection *, bfd_window *, file_ptr, bfd_size_type)); - -/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use - BFD_JUMP_TABLE_COPY (_bfd_generic). */ - -#define _bfd_generic_bfd_copy_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#define _bfd_generic_bfd_merge_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#define _bfd_generic_bfd_set_private_flags \ - ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true) -#define _bfd_generic_bfd_copy_private_section_data \ - ((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true) -#define _bfd_generic_bfd_copy_private_symbol_data \ - ((boolean (*) PARAMS ((bfd *, asymbol *, bfd *, asymbol *))) bfd_true) -#define _bfd_generic_bfd_print_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, PTR))) bfd_true) - -/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file - support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */ - -extern char *_bfd_nocore_core_file_failing_command PARAMS ((bfd *)); -extern int _bfd_nocore_core_file_failing_signal PARAMS ((bfd *)); -extern boolean _bfd_nocore_core_file_matches_executable_p - PARAMS ((bfd *, bfd *)); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive - file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */ - -#define _bfd_noarchive_slurp_armap bfd_false -#define _bfd_noarchive_slurp_extended_name_table bfd_false -#define _bfd_noarchive_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_false) -#define _bfd_noarchive_truncate_arname \ - ((void (*) PARAMS ((bfd *, const char *, char *))) bfd_void) -#define _bfd_noarchive_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_false) -#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr -#define _bfd_noarchive_openr_next_archived_file \ - ((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr) -#define _bfd_noarchive_get_elt_at_index \ - ((bfd *(*) PARAMS ((bfd *, symindex))) bfd_nullvoidptr) -#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define _bfd_noarchive_update_armap_timestamp bfd_false - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */ - -#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap -#define _bfd_archive_bsd_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern boolean _bfd_archive_bsd_construct_extended_name_table - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); -#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname -#define _bfd_archive_bsd_write_armap bsd_write_armap -#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_bsd_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_bsd_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -extern boolean _bfd_archive_bsd_update_armap_timestamp PARAMS ((bfd *)); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */ - -#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap -#define _bfd_archive_coff_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern boolean _bfd_archive_coff_construct_extended_name_table - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); -#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname -#define _bfd_archive_coff_write_armap coff_write_armap -#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_coff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_coff_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -#define _bfd_archive_coff_update_armap_timestamp bfd_true - -/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol - support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */ - -#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1 -#define _bfd_nosymbols_get_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nosymbols_make_empty_symbol \ - ((asymbol *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nosymbols_print_symbol \ - ((void (*) PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void) -#define _bfd_nosymbols_get_symbol_info \ - ((void (*) PARAMS ((bfd *, asymbol *, symbol_info *))) bfd_void) -#define _bfd_nosymbols_bfd_is_local_label \ - ((boolean (*) PARAMS ((bfd *, asymbol *))) bfd_false) -#define _bfd_nosymbols_get_lineno \ - ((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr) -#define _bfd_nosymbols_find_nearest_line \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, \ - const char **, unsigned int *))) \ - bfd_false) -#define _bfd_nosymbols_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, PTR, unsigned long))) bfd_nullvoidptr) -#define _bfd_nosymbols_read_minisymbols \ - ((long (*) PARAMS ((bfd *, boolean, PTR *, unsigned int *))) _bfd_n1) -#define _bfd_nosymbols_minisymbol_to_symbol \ - ((asymbol *(*) PARAMS ((bfd *, boolean, const PTR, asymbol *))) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc - support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */ - -#define _bfd_norelocs_get_reloc_upper_bound \ - ((long (*) PARAMS ((bfd *, asection *))) _bfd_n1) -#define _bfd_norelocs_canonicalize_reloc \ - ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) _bfd_n1) -#define _bfd_norelocs_bfd_reloc_type_lookup \ - ((reloc_howto_type *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not - be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */ - -#define _bfd_nowrite_set_arch_mach \ - ((boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) \ - bfd_false) -#define _bfd_nowrite_set_section_contents \ - ((boolean (*) PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))) \ - bfd_false) - -/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use - BFD_JUMP_TABLE_WRITE (_bfd_generic). */ - -#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach -extern boolean _bfd_generic_set_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); - -/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not - support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */ - -#define _bfd_nolink_sizeof_headers ((int (*) PARAMS ((bfd *, boolean))) bfd_0) -#define _bfd_nolink_bfd_get_relocated_section_contents \ - ((bfd_byte *(*) \ - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, \ - bfd_byte *, boolean, asymbol **))) \ - bfd_nullvoidptr) -#define _bfd_nolink_bfd_relax_section \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *))) \ - bfd_false) -#define _bfd_nolink_bfd_link_hash_table_create \ - ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nolink_bfd_link_add_symbols \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) -#define _bfd_nolink_bfd_final_link \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) -#define _bfd_nolink_bfd_link_split_section \ - ((boolean (*) PARAMS ((bfd *, struct sec *))) bfd_false) - -/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not - have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC - (_bfd_nodynamic). */ - -#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_reloc \ - ((long (*) PARAMS ((bfd *, arelent **, asymbol **))) _bfd_n1) - -/* Generic routine to determine of the given symbol is a local - label. */ -extern boolean bfd_generic_is_local_label PARAMS ((bfd *, asymbol *)); - -/* Generic minisymbol routines. */ -extern long _bfd_generic_read_minisymbols - PARAMS ((bfd *, boolean, PTR *, unsigned int *)); -extern asymbol *_bfd_generic_minisymbol_to_symbol - PARAMS ((bfd *, boolean, const PTR, asymbol *)); - -/* Find the nearest line using .stab/.stabstr sections. */ -extern boolean _bfd_stab_section_find_nearest_line - PARAMS ((bfd *, asymbol **, asection *, bfd_vma, boolean *, const char **, - const char **, unsigned int *, PTR *)); - -/* A routine to create entries for a bfd_link_hash_table. */ -extern struct bfd_hash_entry *_bfd_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string)); - -/* Initialize a bfd_link_hash_table. */ -extern boolean _bfd_link_hash_table_init - PARAMS ((struct bfd_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Generic link hash table creation routine. */ -extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create - PARAMS ((bfd *)); - -/* Generic add symbol routine. */ -extern boolean _bfd_generic_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic add symbol routine. This version is used by targets for - which the linker must collect constructors and destructors by name, - as the collect2 program does. */ -extern boolean _bfd_generic_link_add_symbols_collect - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic archive add symbol routine. */ -extern boolean _bfd_generic_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *, - boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *))); - -/* Forward declaration to avoid prototype errors. */ -typedef struct bfd_link_hash_entry _bfd_link_hash_entry; - -/* Generic routine to add a single symbol. */ -extern boolean _bfd_generic_link_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword, - asection *, bfd_vma, const char *, boolean copy, - boolean constructor, struct bfd_link_hash_entry **)); - -/* Generic link routine. */ -extern boolean _bfd_generic_final_link - PARAMS ((bfd *, struct bfd_link_info *)); - -extern boolean _bfd_generic_link_split_section - PARAMS ((bfd *, struct sec *)); - -/* Generic reloc_link_order processing routine. */ -extern boolean _bfd_generic_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Default link order processing routine. */ -extern boolean _bfd_default_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Count the number of reloc entries in a link order list. */ -extern unsigned int _bfd_count_link_order_relocs - PARAMS ((struct bfd_link_order *)); - -/* Final link relocation routine. */ -extern bfd_reloc_status_type _bfd_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, - bfd_vma address, bfd_vma value, bfd_vma addend)); - -/* Relocate a particular location by a howto and a value. */ -extern bfd_reloc_status_type _bfd_relocate_contents - PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *)); - -/* Create a string table. */ -extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void)); - -/* Create an XCOFF .debug section style string table. */ -extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init PARAMS ((void)); - -/* Free a string table. */ -extern void _bfd_stringtab_free PARAMS ((struct bfd_strtab_hash *)); - -/* Get the size of a string table. */ -extern bfd_size_type _bfd_stringtab_size PARAMS ((struct bfd_strtab_hash *)); - -/* Add a string to a string table. */ -extern bfd_size_type _bfd_stringtab_add - PARAMS ((struct bfd_strtab_hash *, const char *, boolean hash, - boolean copy)); - -/* Write out a string table. */ -extern boolean _bfd_stringtab_emit PARAMS ((bfd *, struct bfd_strtab_hash *)); - -/* Macros to tell if bfds are read or write enabled. - - Note that bfds open for read may be scribbled into if the fd passed - to bfd_fdopenr is actually open both for read and write - simultaneously. However an output bfd will never be open for - read. Therefore sometimes you want to check bfd_read_p or - !bfd_read_p, and only sometimes bfd_write_p. -*/ - -#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction) -#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction) - -void bfd_assert PARAMS ((const char*,int)); - -#define BFD_ASSERT(x) \ -{ if (!(x)) bfd_assert(__FILE__,__LINE__); } - -#define BFD_FAIL() \ -{ bfd_assert(__FILE__,__LINE__); } - -FILE * bfd_cache_lookup_worker PARAMS ((bfd *)); - -extern bfd *bfd_last_cache; - -/* Now Steve, what's the story here? */ -#ifdef lint -#define itos(x) "l" -#define stoi(x) 1 -#else -#define itos(x) ((char*)(x)) -#define stoi(x) ((int)(x)) -#endif - -/* List of supported target vectors, and the default vector (if - bfd_default_vector[0] is NULL, there is no default). */ -extern const bfd_target * const bfd_target_vector[]; -extern const bfd_target * const bfd_default_vector[]; - -/* Functions shared by the ECOFF and MIPS ELF backends, which have no - other common header files. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_find_line; -#endif - -extern boolean _bfd_ecoff_locate_line - PARAMS ((bfd *, asection *, bfd_vma, struct ecoff_debug_info * const, - const struct ecoff_debug_swap * const, struct ecoff_find_line *, - const char **, const char **, unsigned int *)); -extern boolean _bfd_ecoff_get_accumulated_pdr PARAMS ((PTR, bfd_byte *)); -extern boolean _bfd_ecoff_get_accumulated_sym PARAMS ((PTR, bfd_byte *)); -extern boolean _bfd_ecoff_get_accumulated_ss PARAMS ((PTR, bfd_byte *)); - -extern bfd_vma _bfd_get_gp_value PARAMS ((bfd *)); -extern void _bfd_set_gp_value PARAMS ((bfd *, bfd_vma)); - -/* And more follows */ - diff --git a/contrib/gdb/bfd/libbfd.c b/contrib/gdb/bfd/libbfd.c deleted file mode 100644 index 1052a3a17be..00000000000 --- a/contrib/gdb/bfd/libbfd.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* Assorted BFD support routines, only used internally. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static int real_read PARAMS ((PTR, size_t, size_t, FILE *)); - -/* -SECTION - Internal functions - -DESCRIPTION - These routines are used within BFD. - They are not intended for export, but are documented here for - completeness. -*/ - -/* A routine which is used in target vectors for unsupported - operations. */ - -/*ARGSUSED*/ -boolean -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 -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 -bfd_nullvoidptr (ignore) - bfd *ignore; -{ - bfd_set_error (bfd_error_invalid_operation); - return NULL; -} - -/*ARGSUSED*/ -int -bfd_0 (ignore) - bfd *ignore; -{ - return 0; -} - -/*ARGSUSED*/ -unsigned int -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 -bfd_void (ignore) - bfd *ignore; -{ -} - -/*ARGSUSED*/ -boolean -_bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd) - bfd *ignore_core_bfd; - bfd *ignore_exec_bfd; -{ - bfd_set_error (bfd_error_invalid_operation); - return false; -} - -/* Routine to handle core_file_failing_command entry point for targets - without core file support. */ - -/*ARGSUSED*/ -char * -_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 -_bfd_nocore_core_file_failing_signal (ignore_abfd) - bfd *ignore_abfd; -{ - bfd_set_error (bfd_error_invalid_operation); - return 0; -} - -/*ARGSUSED*/ -const bfd_target * -_bfd_dummy_target (ignore_abfd) - bfd *ignore_abfd; -{ - bfd_set_error (bfd_error_wrong_format); - return 0; -} - -/* Allocate memory using malloc. */ - -PTR -bfd_malloc (size) - size_t size; -{ - PTR ptr; - - ptr = (PTR) malloc (size); - if (ptr == NULL && size != 0) - bfd_set_error (bfd_error_no_memory); - return ptr; -} - -/* Reallocate memory using realloc. */ - -PTR -bfd_realloc (ptr, size) - PTR ptr; - size_t size; -{ - PTR ret; - - if (ptr == NULL) - ret = malloc (size); - else - ret = realloc (ptr, size); - - if (ret == NULL) - bfd_set_error (bfd_error_no_memory); - - return ret; -} - -/* Allocate memory using malloc and clear it. */ - -PTR -bfd_zmalloc (size) - size_t size; -{ - PTR ptr; - - ptr = (PTR) malloc (size); - - if (size != 0) - { - if (ptr == NULL) - bfd_set_error (bfd_error_no_memory); - else - memset (ptr, 0, size); - } - - return ptr; -} - -/* Some IO code */ - - -/* Note that archive entries don't have streams; they share their parent's. - This allows someone to play with the iostream behind BFD's back. - - Also, note that the origin pointer points to the beginning of a file's - contents (0 for non-archive elements). For archive entries this is the - first octet in the file, NOT the beginning of the archive header. */ - -static int -real_read (where, a,b, file) - PTR where; - size_t a; - size_t 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 -bfd_read (ptr, size, nitems, abfd) - PTR ptr; - bfd_size_type size; - bfd_size_type nitems; - bfd *abfd; -{ - int nread; - - if ((abfd->flags & BFD_IN_MEMORY) != 0) - { - struct bfd_in_memory *bim; - bfd_size_type get; - - bim = (struct bfd_in_memory *) abfd->iostream; - get = size * nitems; - if (abfd->where + get > bim->size) - { - get = bim->size - abfd->where; - bfd_set_error (bfd_error_file_truncated); - } - memcpy (ptr, bim->buffer + abfd->where, get); - abfd->where += get; - return get; - } - - nread = real_read (ptr, 1, (size_t)(size*nitems), bfd_cache_lookup(abfd)); -#ifdef FILE_OFFSET_IS_CHAR_INDEX - 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; -} - -/* The window support stuff should probably be broken out into - another file.... */ -/* The idea behind the next and refcount fields is that one mapped - region can suffice for multiple read-only windows or multiple - non-overlapping read-write windows. It's not implemented yet - though. */ -struct _bfd_window_internal { - struct _bfd_window_internal *next; - PTR data; - bfd_size_type size; - int refcount : 31; /* should be enough... */ - unsigned mapped : 1; /* 1 = mmap, 0 = malloc */ -}; - -void -bfd_init_window (windowp) - bfd_window *windowp; -{ - windowp->data = 0; - windowp->i = 0; - windowp->size = 0; -} - -#undef HAVE_MPROTECT /* code's not tested yet */ - -#if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE -#include -#include -#endif - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -static int debug_windows; - -/* Currently, if USE_MMAP is undefined, none if the window stuff is - used. Okay, so it's mis-named. At least the command-line option - "--without-mmap" is more obvious than "--without-windows" or some - such. */ -#ifdef USE_MMAP - -void -bfd_free_window (windowp) - bfd_window *windowp; -{ - bfd_window_internal *i = windowp->i; - windowp->i = 0; - windowp->data = 0; - if (i == 0) - return; - i->refcount--; - if (debug_windows) - fprintf (stderr, "freeing window @%p<%p,%lx,%p>\n", - windowp, windowp->data, windowp->size, windowp->i); - if (i->refcount != 0) - return; - - if (i->mapped) - { -#ifdef HAVE_MMAP - munmap (i->data, i->size); - goto no_free; -#else - abort (); -#endif - } -#ifdef HAVE_MPROTECT - mprotect (i->data, i->size, PROT_READ | PROT_WRITE); -#endif - free (i->data); -#ifdef HAVE_MMAP - no_free: -#endif - i->data = 0; - /* There should be no more references to i at this point. */ - free (i); -} -#endif - -static int ok_to_map = 1; - -boolean -bfd_get_file_window (abfd, offset, size, windowp, writable) - bfd *abfd; - file_ptr offset; - bfd_size_type size; - bfd_window *windowp; - boolean writable; -{ - static size_t pagesize; - bfd_window_internal *i = windowp->i; - size_t size_to_alloc = size; - -#ifndef USE_MMAP - abort (); -#endif - - if (debug_windows) - fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)", - abfd, (long) offset, (long) size, - windowp, windowp->data, windowp->size, windowp->i, - writable); - - /* Make sure we know the page size, so we can be friendly to mmap. */ - if (pagesize == 0) - pagesize = getpagesize (); - if (pagesize == 0) - abort (); - - if (i == 0) - { - windowp->i = i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal)); - if (i == 0) - return false; - i->data = 0; - } -#ifdef HAVE_MMAP - if (ok_to_map - && (i->data == 0 || i->mapped == 1) - && (abfd->flags & BFD_IN_MEMORY) == 0) - { - file_ptr file_offset, offset2; - size_t real_size; - int fd; - FILE *f; - - /* Find the real file and the real offset into it. */ - while (abfd->my_archive != NULL) - { - offset += abfd->origin; - abfd = abfd->my_archive; - } - f = bfd_cache_lookup (abfd); - fd = fileno (f); - - /* Compute offsets and size for mmap and for the user's data. */ - offset2 = offset % pagesize; - if (offset2 < 0) - abort (); - file_offset = offset - offset2; - real_size = offset + size - file_offset; - real_size = real_size + pagesize - 1; - real_size -= real_size % pagesize; - - /* If we're re-using a memory region, make sure it's big enough. */ - if (i->data && i->size < size) - { - munmap (i->data, i->size); - i->data = 0; - } - i->data = mmap (i->data, real_size, - writable ? PROT_WRITE | PROT_READ : PROT_READ, - (writable - ? MAP_FILE | MAP_PRIVATE - : MAP_FILE | MAP_SHARED), - fd, file_offset); - if (i->data == (PTR) -1) - { - /* An error happened. Report it, or try using malloc, or - something. */ - bfd_set_error (bfd_error_system_call); - i->data = 0; - windowp->data = 0; - if (debug_windows) - fprintf (stderr, "\t\tmmap failed!\n"); - return false; - } - if (debug_windows) - fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n", - (long) real_size, i->data, (long) offset2); - i->size = real_size; - windowp->data = (PTR) ((bfd_byte *) i->data + offset2); - windowp->size = size; - i->mapped = 1; - return true; - } - else if (debug_windows) - { - if (ok_to_map) - fprintf (stderr, "not mapping: data=%lx mapped=%d\n", - (unsigned long) i->data, (int) i->mapped); - else - fprintf (stderr, "not mapping: env var not set\n"); - } -#else - ok_to_map = 0; -#endif - -#ifdef HAVE_MPROTECT - if (!writable) - { - size_to_alloc += pagesize - 1; - size_to_alloc -= size_to_alloc % pagesize; - } -#endif - if (debug_windows) - fprintf (stderr, "\n\t%s(%6ld)", - i->data ? "realloc" : " malloc", (long) size_to_alloc); - i->data = (PTR) bfd_realloc (i->data, size_to_alloc); - if (debug_windows) - fprintf (stderr, "\t-> %p\n", i->data); - i->refcount = 1; - if (i->data == NULL) - { - if (size_to_alloc == 0) - return true; - bfd_set_error (bfd_error_no_memory); - return false; - } - if (bfd_seek (abfd, offset, SEEK_SET) != 0) - return false; - i->size = bfd_read (i->data, size, 1, abfd); - if (i->size != size) - return false; - i->mapped = 0; -#ifdef HAVE_MPROTECT - if (!writable) - { - if (debug_windows) - fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data, - (long) i->size); - mprotect (i->data, i->size, PROT_READ); - } -#endif - windowp->data = i->data; - windowp->size = i->size; - return true; -} - -bfd_size_type -bfd_write (ptr, size, nitems, abfd) - CONST PTR ptr; - bfd_size_type size; - bfd_size_type nitems; - bfd *abfd; -{ - long nwrote; - - if ((abfd->flags & BFD_IN_MEMORY) != 0) - abort (); - - nwrote = fwrite (ptr, 1, (size_t) (size * nitems), - bfd_cache_lookup (abfd)); -#ifdef FILE_OFFSET_IS_CHAR_INDEX - if (nwrote > 0) - abfd->where += nwrote; -#endif - if ((bfd_size_type) nwrote != size * nitems) - { -#ifdef ENOSPC - if (nwrote >= 0) - errno = ENOSPC; -#endif - bfd_set_error (bfd_error_system_call); - } - return nwrote; -} - -/* -INTERNAL_FUNCTION - bfd_write_bigendian_4byte_int - -SYNOPSIS - void bfd_write_bigendian_4byte_int(bfd *abfd, int i); - -DESCRIPTION - 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 -bfd_write_bigendian_4byte_int (abfd, i) - bfd *abfd; - int i; -{ - bfd_byte buffer[4]; - bfd_putb32(i, buffer); - if (bfd_write((PTR)buffer, 4, 1, abfd) != 4) - abort (); -} - -long -bfd_tell (abfd) - bfd *abfd; -{ - file_ptr ptr; - - if ((abfd->flags & BFD_IN_MEMORY) != 0) - return abfd->where; - - ptr = ftell (bfd_cache_lookup(abfd)); - - if (abfd->my_archive) - ptr -= abfd->origin; - abfd->where = ptr; - return ptr; -} - -int -bfd_flush (abfd) - bfd *abfd; -{ - if ((abfd->flags & BFD_IN_MEMORY) != 0) - return 0; - return fflush (bfd_cache_lookup(abfd)); -} - -/* Returns 0 for success, negative value for failure (in which case - bfd_get_error can retrieve the error code). */ -int -bfd_stat (abfd, statbuf) - bfd *abfd; - struct stat *statbuf; -{ - FILE *f; - int result; - - if ((abfd->flags & BFD_IN_MEMORY) != 0) - abort (); - - f = bfd_cache_lookup (abfd); - if (f == NULL) - { - bfd_set_error (bfd_error_system_call); - return -1; - } - result = fstat (fileno (f), statbuf); - if (result < 0) - bfd_set_error (bfd_error_system_call); - return result; -} - -/* Returns 0 for success, nonzero for failure (in which case bfd_get_error - can retrieve the error code). */ - -int -bfd_seek (abfd, position, direction) - bfd *abfd; - file_ptr position; - int direction; -{ - int result; - FILE *f; - file_ptr file_position; - /* For the time being, a BFD may not seek to it's end. The problem - is that we don't easily have a way to recognize the end of an - element in an archive. */ - - BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR); - - if (direction == SEEK_CUR && position == 0) - return 0; - - if ((abfd->flags & BFD_IN_MEMORY) != 0) - { - if (direction == SEEK_SET) - abfd->where = position; - else - abfd->where += position; - return 0; - } - -#ifdef FILE_OFFSET_IS_CHAR_INDEX - if (abfd->format != bfd_archive && abfd->my_archive == 0) - { -#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' - that the `where' field is correct. If we can go a while without - tripping the abort, we can probably safely disable this code, - so that the real optimizations happen. */ - file_ptr where_am_i_now; - where_am_i_now = ftell (bfd_cache_lookup (abfd)); - if (abfd->my_archive) - where_am_i_now -= abfd->origin; - if (where_am_i_now != abfd->where) - abort (); -#endif - if (direction == SEEK_SET && position == abfd->where) - return 0; - } - else - { - /* We need something smarter to optimize access to archives. - Currently, anything inside an archive is read via the file - handle for the archive. Which means that a bfd_seek on one - component affects the `current position' in the archive, as - well as in any other component. - - It might be sufficient to put a spike through the cache - abstraction, and look to the archive for the file position, - but I think we should try for something cleaner. - - In the meantime, no optimization for archives. */ - } -#endif - - f = bfd_cache_lookup (abfd); - file_position = position; - if (direction == SEEK_SET && abfd->my_archive != NULL) - file_position += abfd->origin; - - result = fseek (f, file_position, direction); - - if (result != 0) - { - /* Force redetermination of `where' field. */ - bfd_tell (abfd); - bfd_set_error (bfd_error_system_call); - } - else - { -#ifdef FILE_OFFSET_IS_CHAR_INDEX - /* Adjust `where' field. */ - if (direction == SEEK_SET) - abfd->where = position; - else - abfd->where += position; -#endif - } - return result; -} - -/** The do-it-yourself (byte) sex-change kit */ - -/* The middle letter e.g. getshort indicates Big or Little endian - target machine. It doesn't matter what the byte order of the host - machine is; these routines work for either. */ - -/* FIXME: Should these take a count argument? - Answer (gnu@cygnus.com): No, but perhaps they should be inline - functions in swap.h #ifdef __GNUC__. - Gprof them later and find out. */ - -/* -FUNCTION - bfd_put_size -FUNCTION - bfd_get_size - -DESCRIPTION - These macros as used for reading and writing raw data in - sections; each access (except for bytes) is vectored through - the target format of the BFD and mangled accordingly. The - mangling performs any necessary endian translations and - removes alignment restrictions. Note that types accepted and - returned by these macros are identical so they can be swapped - around in macros---for example, @file{libaout.h} defines <> - to either <> or <>. - - In the put routines, @var{val} must be a <>. 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 <> - or <> from detecting sins such as passing a pointer. - To detect calling these with less than a <>, use - <> on a host with 64 bit <>'s. - -. -.{* Byte swapping macros for user section data. *} -. -.#define bfd_put_8(abfd, val, ptr) \ -. (*((unsigned char *)(ptr)) = (unsigned char)(val)) -.#define bfd_put_signed_8 \ -. bfd_put_8 -.#define bfd_get_8(abfd, ptr) \ -. (*(unsigned char *)(ptr)) -.#define bfd_get_signed_8(abfd, ptr) \ -. ((*(unsigned char *)(ptr) ^ 0x80) - 0x80) -. -.#define bfd_put_16(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_putx16, ((val),(ptr))) -.#define bfd_put_signed_16 \ -. bfd_put_16 -.#define bfd_get_16(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx16, (ptr)) -.#define bfd_get_signed_16(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) -. -.#define bfd_put_32(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_putx32, ((val),(ptr))) -.#define bfd_put_signed_32 \ -. bfd_put_32 -.#define bfd_get_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx32, (ptr)) -.#define bfd_get_signed_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx_signed_32, (ptr)) -. -.#define bfd_put_64(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_putx64, ((val), (ptr))) -.#define bfd_put_signed_64 \ -. bfd_put_64 -.#define bfd_get_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx64, (ptr)) -.#define bfd_get_signed_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) -. -*/ - -/* -FUNCTION - bfd_h_put_size - bfd_h_get_size - -DESCRIPTION - These macros have the same function as their <> - 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. -. -.{* Byte swapping macros for file header data. *} -. -.#define bfd_h_put_8(abfd, val, ptr) \ -. bfd_put_8 (abfd, val, ptr) -.#define bfd_h_put_signed_8(abfd, val, ptr) \ -. bfd_put_8 (abfd, val, ptr) -.#define bfd_h_get_8(abfd, ptr) \ -. bfd_get_8 (abfd, ptr) -.#define bfd_h_get_signed_8(abfd, ptr) \ -. bfd_get_signed_8 (abfd, ptr) -. -.#define bfd_h_put_16(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_h_putx16,(val,ptr)) -.#define bfd_h_put_signed_16 \ -. bfd_h_put_16 -.#define bfd_h_get_16(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx16,(ptr)) -.#define bfd_h_get_signed_16(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr)) -. -.#define bfd_h_put_32(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_h_putx32,(val,ptr)) -.#define bfd_h_put_signed_32 \ -. bfd_h_put_32 -.#define bfd_h_get_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx32,(ptr)) -.#define bfd_h_get_signed_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr)) -. -.#define bfd_h_put_64(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_h_putx64,(val, ptr)) -.#define bfd_h_put_signed_64 \ -. bfd_h_put_64 -.#define bfd_h_get_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx64,(ptr)) -.#define bfd_h_get_signed_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr)) -. -*/ - -/* Sign extension to bfd_signed_vma. */ -#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000) -#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000) -#define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32) -#define COERCE64(x) \ - (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION) - -bfd_vma -bfd_getb16 (addr) - register const bfd_byte *addr; -{ - return (addr[0] << 8) | addr[1]; -} - -bfd_vma -bfd_getl16 (addr) - register const bfd_byte *addr; -{ - return (addr[1] << 8) | addr[0]; -} - -bfd_signed_vma -bfd_getb_signed_16 (addr) - register const bfd_byte *addr; -{ - return COERCE16((addr[0] << 8) | addr[1]); -} - -bfd_signed_vma -bfd_getl_signed_16 (addr) - register const bfd_byte *addr; -{ - return COERCE16((addr[1] << 8) | addr[0]); -} - -void -bfd_putb16 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ - addr[0] = (bfd_byte)(data >> 8); - addr[1] = (bfd_byte )data; -} - -void -bfd_putl16 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ - addr[0] = (bfd_byte )data; - addr[1] = (bfd_byte)(data >> 8); -} - -bfd_vma -bfd_getb32 (addr) - register const bfd_byte *addr; -{ - return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8) - | addr[2]) << 8 | addr[3]; -} - -bfd_vma -bfd_getl32 (addr) - register const bfd_byte *addr; -{ - return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]; -} - -bfd_signed_vma -bfd_getb_signed_32 (addr) - register const bfd_byte *addr; -{ - return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8) - | addr[2]) << 8 | addr[3]); -} - -bfd_signed_vma -bfd_getl_signed_32 (addr) - register const bfd_byte *addr; -{ - return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]); -} - -bfd_vma -bfd_getb64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - - high= ((((((((addr[0]) << 8) | - addr[1]) << 8) | - addr[2]) << 8) | - addr[3]) ); - - low = (((((((((bfd_vma)addr[4]) << 8) | - addr[5]) << 8) | - addr[6]) << 8) | - addr[7])); - - return high << 32 | low; -#else - BFD_FAIL(); - return 0; -#endif -} - -bfd_vma -bfd_getl64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - high= (((((((addr[7] << 8) | - addr[6]) << 8) | - addr[5]) << 8) | - addr[4])); - - low = ((((((((bfd_vma)addr[3] << 8) | - addr[2]) << 8) | - addr[1]) << 8) | - addr[0]) ); - - return high << 32 | low; -#else - BFD_FAIL(); - return 0; -#endif - -} - -bfd_signed_vma -bfd_getb_signed_64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - - high= ((((((((addr[0]) << 8) | - addr[1]) << 8) | - addr[2]) << 8) | - addr[3]) ); - - low = (((((((((bfd_vma)addr[4]) << 8) | - addr[5]) << 8) | - addr[6]) << 8) | - addr[7])); - - return COERCE64(high << 32 | low); -#else - BFD_FAIL(); - return 0; -#endif -} - -bfd_signed_vma -bfd_getl_signed_64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - high= (((((((addr[7] << 8) | - addr[6]) << 8) | - addr[5]) << 8) | - addr[4])); - - low = ((((((((bfd_vma)addr[3] << 8) | - addr[2]) << 8) | - addr[1]) << 8) | - addr[0]) ); - - return COERCE64(high << 32 | low); -#else - BFD_FAIL(); - return 0; -#endif -} - -void -bfd_putb32 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ - addr[0] = (bfd_byte)(data >> 24); - addr[1] = (bfd_byte)(data >> 16); - addr[2] = (bfd_byte)(data >> 8); - addr[3] = (bfd_byte)data; -} - -void -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 -bfd_putb64 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ -#ifdef BFD64 - addr[0] = (bfd_byte)(data >> (7*8)); - addr[1] = (bfd_byte)(data >> (6*8)); - addr[2] = (bfd_byte)(data >> (5*8)); - addr[3] = (bfd_byte)(data >> (4*8)); - addr[4] = (bfd_byte)(data >> (3*8)); - addr[5] = (bfd_byte)(data >> (2*8)); - addr[6] = (bfd_byte)(data >> (1*8)); - addr[7] = (bfd_byte)(data >> (0*8)); -#else - BFD_FAIL(); -#endif -} - -void -bfd_putl64 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ -#ifdef BFD64 - addr[7] = (bfd_byte)(data >> (7*8)); - addr[6] = (bfd_byte)(data >> (6*8)); - addr[5] = (bfd_byte)(data >> (5*8)); - addr[4] = (bfd_byte)(data >> (4*8)); - addr[3] = (bfd_byte)(data >> (3*8)); - addr[2] = (bfd_byte)(data >> (2*8)); - addr[1] = (bfd_byte)(data >> (1*8)); - addr[0] = (bfd_byte)(data >> (0*8)); -#else - BFD_FAIL(); -#endif -} - -/* Default implementation */ - -boolean -_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; - if ((bfd_size_type)(offset+count) > section->_raw_size - || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1 - || bfd_read(location, (bfd_size_type)1, count, abfd) != count) - return (false); /* on error */ - return (true); -} - -boolean -_bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count) - bfd *abfd; - sec_ptr section; - bfd_window *w; - file_ptr offset; - bfd_size_type count; -{ -#ifdef USE_MMAP - if (count == 0) - return true; - if (abfd->xvec->_bfd_get_section_contents != _bfd_generic_get_section_contents) - { - /* We don't know what changes the bfd's get_section_contents - method may have to make. So punt trying to map the file - window, and let get_section_contents do its thing. */ - /* @@ FIXME : If the internal window has a refcount of 1 and was - allocated with malloc instead of mmap, just reuse it. */ - bfd_free_window (w); - w->i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal)); - if (w->i == NULL) - return false; - w->i->data = (PTR) bfd_malloc ((size_t) count); - if (w->i->data == NULL) - { - free (w->i); - w->i = NULL; - return false; - } - w->i->mapped = 0; - w->i->refcount = 1; - w->size = w->i->size = count; - w->data = w->i->data; - return bfd_get_section_contents (abfd, section, w->data, offset, count); - } - if ((bfd_size_type) (offset+count) > section->_raw_size - || (bfd_get_file_window (abfd, section->filepos + offset, count, w, true) - == false)) - return false; - return true; -#else - abort (); -#endif -} - -/* This generic function can only be used in implementations where creating - NEW sections is disallowed. It is useful in patching existing sections - in read-write files, though. See other set_section_contents functions - to see why it doesn't work for new sections. */ -boolean -_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_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 - -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 -bfd_log2(x) - bfd_vma x; -{ - unsigned result = 0; - while ( (bfd_vma)(1<< result) < 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); -} - diff --git a/contrib/gdb/bfd/libbfd.h b/contrib/gdb/bfd/libbfd.h deleted file mode 100644 index 5cf504cdc75..00000000000 --- a/contrib/gdb/bfd/libbfd.h +++ /dev/null @@ -1,735 +0,0 @@ -/* libbfd.h -- Declarations used by bfd library *implementation*. - (This include file is not for users of the library.) - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -** NOTE: libbfd.h is a GENERATED file. Don't change it; instead, -** change libbfd-in.h or the other BFD source files processed to -** generate this file. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Align an address upward to a boundary, expressed as a number of bytes. - E.g. align to an 8-byte boundary with argument of 8. */ -#define BFD_ALIGN(this, boundary) \ - ((( (this) + ((boundary) -1)) & (~((boundary)-1)))) - -/* If you want to read and write large blocks, you might want to do it - in quanta of this amount */ -#define DEFAULT_BUFFERSIZE 8192 - -/* Set a tdata field. Can't use the other macros for this, since they - do casts, and casting to the left of assignment isn't portable. */ -#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v)) - -/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points - to an instance of this structure. */ - -struct bfd_in_memory -{ - /* Size of buffer. */ - bfd_size_type size; - /* Buffer holding contents of BFD. */ - bfd_byte *buffer; -}; - -/* tdata for an archive. For an input archive, cache - needs to be free()'d. For an output archive, symdefs do. */ - -struct artdata { - file_ptr first_file_filepos; - /* Speed up searching the armap */ - struct ar_cache *cache; - bfd *archive_head; /* Only interesting in output routines */ - carsym *symdefs; /* the symdef entries */ - symindex symdef_count; /* how many there are */ - char *extended_names; /* clever intel extension */ - /* when more compilers are standard C, this can be a time_t */ - long armap_timestamp; /* Timestamp value written into armap. - This is used for BSD archives to check - that the timestamp is recent enough - for the BSD linker to not complain, - just before we finish writing an - archive. */ - file_ptr armap_datepos; /* Position within archive to seek to - rewrite the date field. */ - PTR tdata; /* Backend specific information. */ -}; - -#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data) - -/* Goes in bfd's arelt_data slot */ -struct areltdata { - char * arch_header; /* it's actually a string */ - unsigned int parsed_size; /* octets of filesize not including ar_hdr */ - char *filename; /* null-terminated */ -}; - -#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size) - -extern PTR bfd_malloc PARAMS ((size_t)); -extern PTR bfd_realloc PARAMS ((PTR, size_t)); -extern PTR bfd_zmalloc PARAMS ((size_t)); - -extern bfd_error_handler_type _bfd_error_handler; - -/* These routines allocate and free things on the BFD's obstack. */ - -PTR bfd_alloc PARAMS ((bfd *abfd, size_t size)); -PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size)); -void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size)); -PTR bfd_alloc_finish PARAMS ((bfd *abfd)); -PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted)); - -#define bfd_release(x,y) (void) obstack_free(&(x->memory),y) - -bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd)); -bfd * _bfd_look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index)); -boolean _bfd_add_bfd_to_archive_cache PARAMS ((bfd *, file_ptr, bfd *)); -boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd)); -const bfd_target *bfd_generic_archive_p PARAMS ((bfd *abfd)); -boolean bfd_slurp_armap PARAMS ((bfd *abfd)); -boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd)); -#define bfd_slurp_bsd_armap bfd_slurp_armap -#define bfd_slurp_coff_armap bfd_slurp_armap -boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd)); -extern boolean _bfd_construct_extended_name_table - PARAMS ((bfd *, boolean, char **, bfd_size_type *)); -boolean _bfd_write_archive_contents PARAMS ((bfd *abfd)); -boolean _bfd_compute_and_write_armap PARAMS ((bfd *, unsigned int elength)); -bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos)); -extern bfd *_bfd_generic_get_elt_at_index PARAMS ((bfd *, symindex)); -bfd * _bfd_new_bfd PARAMS ((void)); - -boolean bfd_false PARAMS ((bfd *ignore)); -boolean bfd_true PARAMS ((bfd *ignore)); -PTR bfd_nullvoidptr PARAMS ((bfd *ignore)); -int bfd_0 PARAMS ((bfd *ignore)); -unsigned int bfd_0u PARAMS ((bfd *ignore)); -long bfd_0l PARAMS ((bfd *ignore)); -long _bfd_n1 PARAMS ((bfd *ignore)); -void bfd_void PARAMS ((bfd *ignore)); - -bfd *_bfd_new_bfd_contained_in PARAMS ((bfd *)); -const bfd_target *_bfd_dummy_target PARAMS ((bfd *abfd)); - -void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); - -boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -extern PTR _bfd_generic_read_ar_hdr PARAMS ((bfd *)); - -extern PTR _bfd_generic_read_ar_hdr_mag PARAMS ((bfd *, const char *)); - -bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive, - bfd *last_file)); - -int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); - -#define _bfd_read_ar_hdr(abfd) \ - BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd)) - -/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use - BFD_JUMP_TABLE_GENERIC (_bfd_generic). */ - -#define _bfd_generic_close_and_cleanup bfd_true -#define _bfd_generic_bfd_free_cached_info bfd_true -#define _bfd_generic_new_section_hook \ - ((boolean (*) PARAMS ((bfd *, asection *))) bfd_true) -extern boolean _bfd_generic_get_section_contents - PARAMS ((bfd *, asection *, PTR location, file_ptr offset, - bfd_size_type count)); -extern boolean _bfd_generic_get_section_contents_in_window - PARAMS ((bfd *, asection *, bfd_window *, file_ptr, bfd_size_type)); - -/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use - BFD_JUMP_TABLE_COPY (_bfd_generic). */ - -#define _bfd_generic_bfd_copy_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#define _bfd_generic_bfd_merge_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#define _bfd_generic_bfd_set_private_flags \ - ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true) -#define _bfd_generic_bfd_copy_private_section_data \ - ((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true) -#define _bfd_generic_bfd_copy_private_symbol_data \ - ((boolean (*) PARAMS ((bfd *, asymbol *, bfd *, asymbol *))) bfd_true) -#define _bfd_generic_bfd_print_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, PTR))) bfd_true) - -/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file - support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */ - -extern char *_bfd_nocore_core_file_failing_command PARAMS ((bfd *)); -extern int _bfd_nocore_core_file_failing_signal PARAMS ((bfd *)); -extern boolean _bfd_nocore_core_file_matches_executable_p - PARAMS ((bfd *, bfd *)); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive - file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */ - -#define _bfd_noarchive_slurp_armap bfd_false -#define _bfd_noarchive_slurp_extended_name_table bfd_false -#define _bfd_noarchive_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_false) -#define _bfd_noarchive_truncate_arname \ - ((void (*) PARAMS ((bfd *, const char *, char *))) bfd_void) -#define _bfd_noarchive_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_false) -#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr -#define _bfd_noarchive_openr_next_archived_file \ - ((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr) -#define _bfd_noarchive_get_elt_at_index \ - ((bfd *(*) PARAMS ((bfd *, symindex))) bfd_nullvoidptr) -#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define _bfd_noarchive_update_armap_timestamp bfd_false - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */ - -#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap -#define _bfd_archive_bsd_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern boolean _bfd_archive_bsd_construct_extended_name_table - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); -#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname -#define _bfd_archive_bsd_write_armap bsd_write_armap -#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_bsd_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_bsd_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -extern boolean _bfd_archive_bsd_update_armap_timestamp PARAMS ((bfd *)); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */ - -#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap -#define _bfd_archive_coff_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern boolean _bfd_archive_coff_construct_extended_name_table - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); -#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname -#define _bfd_archive_coff_write_armap coff_write_armap -#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_coff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_coff_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -#define _bfd_archive_coff_update_armap_timestamp bfd_true - -/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol - support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */ - -#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1 -#define _bfd_nosymbols_get_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nosymbols_make_empty_symbol \ - ((asymbol *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nosymbols_print_symbol \ - ((void (*) PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void) -#define _bfd_nosymbols_get_symbol_info \ - ((void (*) PARAMS ((bfd *, asymbol *, symbol_info *))) bfd_void) -#define _bfd_nosymbols_bfd_is_local_label \ - ((boolean (*) PARAMS ((bfd *, asymbol *))) bfd_false) -#define _bfd_nosymbols_get_lineno \ - ((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr) -#define _bfd_nosymbols_find_nearest_line \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, \ - const char **, unsigned int *))) \ - bfd_false) -#define _bfd_nosymbols_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, PTR, unsigned long))) bfd_nullvoidptr) -#define _bfd_nosymbols_read_minisymbols \ - ((long (*) PARAMS ((bfd *, boolean, PTR *, unsigned int *))) _bfd_n1) -#define _bfd_nosymbols_minisymbol_to_symbol \ - ((asymbol *(*) PARAMS ((bfd *, boolean, const PTR, asymbol *))) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc - support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */ - -#define _bfd_norelocs_get_reloc_upper_bound \ - ((long (*) PARAMS ((bfd *, asection *))) _bfd_n1) -#define _bfd_norelocs_canonicalize_reloc \ - ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) _bfd_n1) -#define _bfd_norelocs_bfd_reloc_type_lookup \ - ((reloc_howto_type *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not - be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */ - -#define _bfd_nowrite_set_arch_mach \ - ((boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) \ - bfd_false) -#define _bfd_nowrite_set_section_contents \ - ((boolean (*) PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))) \ - bfd_false) - -/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use - BFD_JUMP_TABLE_WRITE (_bfd_generic). */ - -#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach -extern boolean _bfd_generic_set_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); - -/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not - support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */ - -#define _bfd_nolink_sizeof_headers ((int (*) PARAMS ((bfd *, boolean))) bfd_0) -#define _bfd_nolink_bfd_get_relocated_section_contents \ - ((bfd_byte *(*) \ - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, \ - bfd_byte *, boolean, asymbol **))) \ - bfd_nullvoidptr) -#define _bfd_nolink_bfd_relax_section \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *))) \ - bfd_false) -#define _bfd_nolink_bfd_link_hash_table_create \ - ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nolink_bfd_link_add_symbols \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) -#define _bfd_nolink_bfd_final_link \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) -#define _bfd_nolink_bfd_link_split_section \ - ((boolean (*) PARAMS ((bfd *, struct sec *))) bfd_false) - -/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not - have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC - (_bfd_nodynamic). */ - -#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_reloc \ - ((long (*) PARAMS ((bfd *, arelent **, asymbol **))) _bfd_n1) - -/* Generic routine to determine of the given symbol is a local - label. */ -extern boolean bfd_generic_is_local_label PARAMS ((bfd *, asymbol *)); - -/* Generic minisymbol routines. */ -extern long _bfd_generic_read_minisymbols - PARAMS ((bfd *, boolean, PTR *, unsigned int *)); -extern asymbol *_bfd_generic_minisymbol_to_symbol - PARAMS ((bfd *, boolean, const PTR, asymbol *)); - -/* Find the nearest line using .stab/.stabstr sections. */ -extern boolean _bfd_stab_section_find_nearest_line - PARAMS ((bfd *, asymbol **, asection *, bfd_vma, boolean *, const char **, - const char **, unsigned int *, PTR *)); - -/* A routine to create entries for a bfd_link_hash_table. */ -extern struct bfd_hash_entry *_bfd_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string)); - -/* Initialize a bfd_link_hash_table. */ -extern boolean _bfd_link_hash_table_init - PARAMS ((struct bfd_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Generic link hash table creation routine. */ -extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create - PARAMS ((bfd *)); - -/* Generic add symbol routine. */ -extern boolean _bfd_generic_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic add symbol routine. This version is used by targets for - which the linker must collect constructors and destructors by name, - as the collect2 program does. */ -extern boolean _bfd_generic_link_add_symbols_collect - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic archive add symbol routine. */ -extern boolean _bfd_generic_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *, - boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *))); - -/* Forward declaration to avoid prototype errors. */ -typedef struct bfd_link_hash_entry _bfd_link_hash_entry; - -/* Generic routine to add a single symbol. */ -extern boolean _bfd_generic_link_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword, - asection *, bfd_vma, const char *, boolean copy, - boolean constructor, struct bfd_link_hash_entry **)); - -/* Generic link routine. */ -extern boolean _bfd_generic_final_link - PARAMS ((bfd *, struct bfd_link_info *)); - -extern boolean _bfd_generic_link_split_section - PARAMS ((bfd *, struct sec *)); - -/* Generic reloc_link_order processing routine. */ -extern boolean _bfd_generic_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Default link order processing routine. */ -extern boolean _bfd_default_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Count the number of reloc entries in a link order list. */ -extern unsigned int _bfd_count_link_order_relocs - PARAMS ((struct bfd_link_order *)); - -/* Final link relocation routine. */ -extern bfd_reloc_status_type _bfd_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, - bfd_vma address, bfd_vma value, bfd_vma addend)); - -/* Relocate a particular location by a howto and a value. */ -extern bfd_reloc_status_type _bfd_relocate_contents - PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *)); - -/* Create a string table. */ -extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void)); - -/* Create an XCOFF .debug section style string table. */ -extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init PARAMS ((void)); - -/* Free a string table. */ -extern void _bfd_stringtab_free PARAMS ((struct bfd_strtab_hash *)); - -/* Get the size of a string table. */ -extern bfd_size_type _bfd_stringtab_size PARAMS ((struct bfd_strtab_hash *)); - -/* Add a string to a string table. */ -extern bfd_size_type _bfd_stringtab_add - PARAMS ((struct bfd_strtab_hash *, const char *, boolean hash, - boolean copy)); - -/* Write out a string table. */ -extern boolean _bfd_stringtab_emit PARAMS ((bfd *, struct bfd_strtab_hash *)); - -/* Macros to tell if bfds are read or write enabled. - - Note that bfds open for read may be scribbled into if the fd passed - to bfd_fdopenr is actually open both for read and write - simultaneously. However an output bfd will never be open for - read. Therefore sometimes you want to check bfd_read_p or - !bfd_read_p, and only sometimes bfd_write_p. -*/ - -#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction) -#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction) - -void bfd_assert PARAMS ((const char*,int)); - -#define BFD_ASSERT(x) \ -{ if (!(x)) bfd_assert(__FILE__,__LINE__); } - -#define BFD_FAIL() \ -{ bfd_assert(__FILE__,__LINE__); } - -FILE * bfd_cache_lookup_worker PARAMS ((bfd *)); - -extern bfd *bfd_last_cache; - -/* Now Steve, what's the story here? */ -#ifdef lint -#define itos(x) "l" -#define stoi(x) 1 -#else -#define itos(x) ((char*)(x)) -#define stoi(x) ((int)(x)) -#endif - -/* List of supported target vectors, and the default vector (if - bfd_default_vector[0] is NULL, there is no default). */ -extern const bfd_target * const bfd_target_vector[]; -extern const bfd_target * const bfd_default_vector[]; - -/* Functions shared by the ECOFF and MIPS ELF backends, which have no - other common header files. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_find_line; -#endif - -extern boolean _bfd_ecoff_locate_line - PARAMS ((bfd *, asection *, bfd_vma, struct ecoff_debug_info * const, - const struct ecoff_debug_swap * const, struct ecoff_find_line *, - const char **, const char **, unsigned int *)); -extern boolean _bfd_ecoff_get_accumulated_pdr PARAMS ((PTR, bfd_byte *)); -extern boolean _bfd_ecoff_get_accumulated_sym PARAMS ((PTR, bfd_byte *)); -extern boolean _bfd_ecoff_get_accumulated_ss PARAMS ((PTR, bfd_byte *)); - -extern bfd_vma _bfd_get_gp_value PARAMS ((bfd *)); -extern void _bfd_set_gp_value PARAMS ((bfd *, bfd_vma)); - -/* And more follows */ - -void -bfd_write_bigendian_4byte_int PARAMS ((bfd *abfd, int i)); - -unsigned int -bfd_log2 PARAMS ((bfd_vma x)); - -#define BFD_CACHE_MAX_OPEN 10 -extern bfd *bfd_last_cache; - -#define bfd_cache_lookup(x) \ - ((x)==bfd_last_cache? \ - (FILE*)(bfd_last_cache->iostream): \ - bfd_cache_lookup_worker(x)) -boolean -bfd_cache_init PARAMS ((bfd *abfd)); - -boolean -bfd_cache_close PARAMS ((bfd *abfd)); - -FILE* -bfd_open_file PARAMS ((bfd *abfd)); - -FILE * -bfd_cache_lookup_worker PARAMS ((bfd *abfd)); - -#ifdef _BFD_MAKE_TABLE_bfd_reloc_code_real - -static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", - - "BFD_RELOC_64", - "BFD_RELOC_32", - "BFD_RELOC_26", - "BFD_RELOC_16", - "BFD_RELOC_14", - "BFD_RELOC_8", - "BFD_RELOC_64_PCREL", - "BFD_RELOC_32_PCREL", - "BFD_RELOC_24_PCREL", - "BFD_RELOC_16_PCREL", - "BFD_RELOC_12_PCREL", - "BFD_RELOC_8_PCREL", - "BFD_RELOC_32_GOT_PCREL", - "BFD_RELOC_16_GOT_PCREL", - "BFD_RELOC_8_GOT_PCREL", - "BFD_RELOC_32_GOTOFF", - "BFD_RELOC_16_GOTOFF", - "BFD_RELOC_LO16_GOTOFF", - "BFD_RELOC_HI16_GOTOFF", - "BFD_RELOC_HI16_S_GOTOFF", - "BFD_RELOC_8_GOTOFF", - "BFD_RELOC_32_PLT_PCREL", - "BFD_RELOC_24_PLT_PCREL", - "BFD_RELOC_16_PLT_PCREL", - "BFD_RELOC_8_PLT_PCREL", - "BFD_RELOC_32_PLTOFF", - "BFD_RELOC_16_PLTOFF", - "BFD_RELOC_LO16_PLTOFF", - "BFD_RELOC_HI16_PLTOFF", - "BFD_RELOC_HI16_S_PLTOFF", - "BFD_RELOC_8_PLTOFF", - "BFD_RELOC_68K_GLOB_DAT", - "BFD_RELOC_68K_JMP_SLOT", - "BFD_RELOC_68K_RELATIVE", - "BFD_RELOC_32_BASEREL", - "BFD_RELOC_16_BASEREL", - "BFD_RELOC_LO16_BASEREL", - "BFD_RELOC_HI16_BASEREL", - "BFD_RELOC_HI16_S_BASEREL", - "BFD_RELOC_8_BASEREL", - "BFD_RELOC_RVA", - "BFD_RELOC_8_FFnn", - "BFD_RELOC_32_PCREL_S2", - "BFD_RELOC_16_PCREL_S2", - "BFD_RELOC_23_PCREL_S2", - "BFD_RELOC_HI22", - "BFD_RELOC_LO10", - "BFD_RELOC_GPREL16", - "BFD_RELOC_GPREL32", - "BFD_RELOC_I960_CALLJ", - "BFD_RELOC_NONE", - "BFD_RELOC_SPARC_WDISP22", - "BFD_RELOC_SPARC22", - "BFD_RELOC_SPARC13", - "BFD_RELOC_SPARC_GOT10", - "BFD_RELOC_SPARC_GOT13", - "BFD_RELOC_SPARC_GOT22", - "BFD_RELOC_SPARC_PC10", - "BFD_RELOC_SPARC_PC22", - "BFD_RELOC_SPARC_WPLT30", - "BFD_RELOC_SPARC_COPY", - "BFD_RELOC_SPARC_GLOB_DAT", - "BFD_RELOC_SPARC_JMP_SLOT", - "BFD_RELOC_SPARC_RELATIVE", - "BFD_RELOC_SPARC_UA32", - "BFD_RELOC_SPARC_BASE13", - "BFD_RELOC_SPARC_BASE22", - "BFD_RELOC_SPARC_10", - "BFD_RELOC_SPARC_11", - "BFD_RELOC_SPARC_OLO10", - "BFD_RELOC_SPARC_HH22", - "BFD_RELOC_SPARC_HM10", - "BFD_RELOC_SPARC_LM22", - "BFD_RELOC_SPARC_PC_HH22", - "BFD_RELOC_SPARC_PC_HM10", - "BFD_RELOC_SPARC_PC_LM22", - "BFD_RELOC_SPARC_WDISP16", - "BFD_RELOC_SPARC_WDISP19", - "BFD_RELOC_SPARC_GLOB_JMP", - "BFD_RELOC_SPARC_7", - "BFD_RELOC_SPARC_6", - "BFD_RELOC_SPARC_5", - "BFD_RELOC_ALPHA_GPDISP_HI16", - "BFD_RELOC_ALPHA_GPDISP_LO16", - "BFD_RELOC_ALPHA_LITERAL", - "BFD_RELOC_ALPHA_LITUSE", - "BFD_RELOC_ALPHA_HINT", - "BFD_RELOC_MIPS_JMP", - "BFD_RELOC_HI16", - "BFD_RELOC_HI16_S", - "BFD_RELOC_LO16", - "BFD_RELOC_PCREL_HI16_S", - "BFD_RELOC_PCREL_LO16", - "BFD_RELOC_MIPS_LITERAL", - "BFD_RELOC_MIPS_GOT16", - "BFD_RELOC_MIPS_CALL16", - "BFD_RELOC_MIPS_GOT_HI16", - "BFD_RELOC_MIPS_GOT_LO16", - "BFD_RELOC_MIPS_CALL_HI16", - "BFD_RELOC_MIPS_CALL_LO16", - "BFD_RELOC_386_GOT32", - "BFD_RELOC_386_PLT32", - "BFD_RELOC_386_COPY", - "BFD_RELOC_386_GLOB_DAT", - "BFD_RELOC_386_JUMP_SLOT", - "BFD_RELOC_386_RELATIVE", - "BFD_RELOC_386_GOTOFF", - "BFD_RELOC_386_GOTPC", - "BFD_RELOC_NS32K_IMM_8", - "BFD_RELOC_NS32K_IMM_16", - "BFD_RELOC_NS32K_IMM_32", - "BFD_RELOC_NS32K_IMM_8_PCREL", - "BFD_RELOC_NS32K_IMM_16_PCREL", - "BFD_RELOC_NS32K_IMM_32_PCREL", - "BFD_RELOC_NS32K_DISP_8", - "BFD_RELOC_NS32K_DISP_16", - "BFD_RELOC_NS32K_DISP_32", - "BFD_RELOC_NS32K_DISP_8_PCREL", - "BFD_RELOC_NS32K_DISP_16_PCREL", - "BFD_RELOC_NS32K_DISP_32_PCREL", - "BFD_RELOC_PPC_B26", - "BFD_RELOC_PPC_BA26", - "BFD_RELOC_PPC_TOC16", - "BFD_RELOC_PPC_B16", - "BFD_RELOC_PPC_B16_BRTAKEN", - "BFD_RELOC_PPC_B16_BRNTAKEN", - "BFD_RELOC_PPC_BA16", - "BFD_RELOC_PPC_BA16_BRTAKEN", - "BFD_RELOC_PPC_BA16_BRNTAKEN", - "BFD_RELOC_PPC_COPY", - "BFD_RELOC_PPC_GLOB_DAT", - "BFD_RELOC_PPC_JMP_SLOT", - "BFD_RELOC_PPC_RELATIVE", - "BFD_RELOC_PPC_LOCAL24PC", - "BFD_RELOC_PPC_EMB_NADDR32", - "BFD_RELOC_PPC_EMB_NADDR16", - "BFD_RELOC_PPC_EMB_NADDR16_LO", - "BFD_RELOC_PPC_EMB_NADDR16_HI", - "BFD_RELOC_PPC_EMB_NADDR16_HA", - "BFD_RELOC_PPC_EMB_SDAI16", - "BFD_RELOC_PPC_EMB_SDA2I16", - "BFD_RELOC_PPC_EMB_SDA2REL", - "BFD_RELOC_PPC_EMB_SDA21", - "BFD_RELOC_PPC_EMB_MRKREF", - "BFD_RELOC_PPC_EMB_RELSEC16", - "BFD_RELOC_PPC_EMB_RELST_LO", - "BFD_RELOC_PPC_EMB_RELST_HI", - "BFD_RELOC_PPC_EMB_RELST_HA", - "BFD_RELOC_PPC_EMB_BIT_FLD", - "BFD_RELOC_PPC_EMB_RELSDA", - "BFD_RELOC_CTOR", - "BFD_RELOC_ARM_PCREL_BRANCH", - "BFD_RELOC_ARM_IMMEDIATE", - "BFD_RELOC_ARM_OFFSET_IMM", - "BFD_RELOC_ARM_SHIFT_IMM", - "BFD_RELOC_ARM_SWI", - "BFD_RELOC_ARM_MULTI", - "BFD_RELOC_ARM_CP_OFF_IMM", - "BFD_RELOC_ARM_ADR_IMM", - "BFD_RELOC_ARM_LDR_IMM", - "BFD_RELOC_ARM_LITERAL", - "BFD_RELOC_ARM_IN_POOL", - "@@overflow: BFD_RELOC_UNUSED@@", -}; -#endif - -reloc_howto_type * -bfd_default_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); - -boolean -bfd_generic_relax_section - PARAMS ((bfd *abfd, - asection *section, - struct bfd_link_info *, - boolean *)); - -bfd_byte * - -bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - boolean relocateable, - asymbol **symbols)); - -extern const bfd_arch_info_type bfd_default_arch_struct; -boolean -bfd_default_set_arch_mach PARAMS ((bfd *abfd, - enum bfd_architecture arch, - unsigned long mach)); - -const bfd_arch_info_type * -bfd_default_compatible - PARAMS ((const bfd_arch_info_type *a, - const bfd_arch_info_type *b)); - -boolean -bfd_default_scan PARAMS ((const struct bfd_arch_info *info, const char *string)); - -struct elf_internal_shdr * -bfd_elf_find_section PARAMS ((bfd *abfd, char *name)); - diff --git a/contrib/gdb/bfd/libcoff-in.h b/contrib/gdb/bfd/libcoff-in.h deleted file mode 100644 index 648ed806638..00000000000 --- a/contrib/gdb/bfd/libcoff-in.h +++ /dev/null @@ -1,482 +0,0 @@ -/* BFD COFF object file private structure. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -** NOTE: libcoff.h is a GENERATED file. Don't change it; instead, -** change libcoff-in.h or coffcode.h. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfdlink.h" - -/* Object file tdata; access macros */ - -#define coff_data(bfd) ((bfd)->tdata.coff_obj_data) -#define exec_hdr(bfd) (coff_data(bfd)->hdr) -#define obj_pe(bfd) (coff_data(bfd)->pe) -#define obj_symbols(bfd) (coff_data(bfd)->symbols) -#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos) - -#define obj_relocbase(bfd) (coff_data(bfd)->relocbase) -#define obj_raw_syments(bfd) (coff_data(bfd)->raw_syments) -#define obj_raw_syment_count(bfd) (coff_data(bfd)->raw_syment_count) -#define obj_convert(bfd) (coff_data(bfd)->conversion_table) -#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size) - -#define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms) -#define obj_coff_keep_syms(bfd) (coff_data (bfd)->keep_syms) -#define obj_coff_strings(bfd) (coff_data (bfd)->strings) -#define obj_coff_keep_strings(bfd) (coff_data (bfd)->keep_strings) -#define obj_coff_sym_hashes(bfd) (coff_data (bfd)->sym_hashes) - -#define obj_coff_local_toc_table(bfd) (coff_data(bfd)->local_toc_sym_map) - -/* `Tdata' information kept for COFF files. */ - -typedef struct coff_tdata -{ - struct coff_symbol_struct *symbols; /* symtab for input bfd */ - unsigned int *conversion_table; - int conv_table_size; - file_ptr sym_filepos; - - struct coff_ptr_struct *raw_syments; - unsigned int raw_syment_count; - - /* These are only valid once writing has begun */ - long int relocbase; - - /* These members communicate important constants about the symbol table - to GDB's symbol-reading code. These `constants' unfortunately vary - from coff implementation to implementation... */ - unsigned local_n_btmask; - unsigned local_n_btshft; - unsigned local_n_tmask; - unsigned local_n_tshift; - unsigned local_symesz; - unsigned local_auxesz; - unsigned local_linesz; - - /* The unswapped external symbols. May be NULL. Read by - _bfd_coff_get_external_symbols. */ - PTR external_syms; - /* If this is true, the external_syms may not be freed. */ - boolean keep_syms; - - /* The string table. May be NULL. Read by - _bfd_coff_read_string_table. */ - char *strings; - /* If this is true, the strings may not be freed. */ - boolean keep_strings; - - /* is this a PE format coff file */ - int pe; - /* Used by the COFF backend linker. */ - struct coff_link_hash_entry **sym_hashes; - - /* used by the pe linker for PowerPC */ - int *local_toc_sym_map; - - struct bfd_link_info *link_info; - - /* Used by coff_find_nearest_line. */ - PTR line_info; -} coff_data_type; - -/* Tdata for pe image files. */ -typedef struct pe_tdata -{ - coff_data_type coff; - struct internal_extra_pe_aouthdr pe_opthdr; - int dll; - int has_reloc_section; - boolean (*in_reloc_p) PARAMS((bfd *, reloc_howto_type *)); - flagword real_flags; -} pe_data_type; - -#define pe_data(bfd) ((bfd)->tdata.pe_obj_data) - -/* Tdata for XCOFF files. */ - -struct xcoff_tdata -{ - /* Basic COFF information. */ - coff_data_type coff; - - /* True if a large a.out header should be generated. */ - boolean full_aouthdr; - - /* TOC value. */ - bfd_vma toc; - - /* Index of section holding TOC. */ - int sntoc; - - /* Index of section holding entry point. */ - int snentry; - - /* .text alignment from optional header. */ - int text_align_power; - - /* .data alignment from optional header. */ - int data_align_power; - - /* modtype from optional header. */ - short modtype; - - /* cputype from optional header. */ - short cputype; - - /* maxdata from optional header. */ - bfd_size_type maxdata; - - /* maxstack from optional header. */ - bfd_size_type maxstack; - - /* Used by the XCOFF backend linker. */ - asection **csects; - unsigned long *debug_indices; - unsigned int import_file_id; -}; - -#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data) - -/* We take the address of the first element of a asymbol to ensure that the - * macro is only ever applied to an asymbol. */ -#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd))) - -/* The used_by_bfd field of a section may be set to a pointer to this - structure. */ - -struct coff_section_tdata -{ - /* The relocs, swapped into COFF internal form. This may be NULL. */ - struct internal_reloc *relocs; - /* If this is true, the relocs entry may not be freed. */ - boolean keep_relocs; - /* The section contents. This may be NULL. */ - bfd_byte *contents; - /* If this is true, the contents entry may not be freed. */ - boolean keep_contents; - /* Information cached by coff_find_nearest_line. */ - bfd_vma offset; - unsigned int i; - const char *function; - int line_base; - /* Available for individual backends. */ - PTR tdata; -}; - -/* An accessor macro for the coff_section_tdata structure. */ -#define coff_section_data(abfd, sec) \ - ((struct coff_section_tdata *) (sec)->used_by_bfd) - -/* Tdata for sections in XCOFF files. This is used by the linker. */ - -struct xcoff_section_tdata -{ - /* Used for XCOFF csects created by the linker; points to the real - XCOFF section which contains this csect. */ - asection *enclosing; - /* The lineno_count field for the enclosing section, because we are - going to clobber it there. */ - unsigned int lineno_count; - /* The first and one past the last symbol indices for symbols used - by this csect. */ - unsigned long first_symndx; - unsigned long last_symndx; -}; - -/* An accessor macro the xcoff_section_tdata structure. */ -#define xcoff_section_data(abfd, sec) \ - ((struct xcoff_section_tdata *) coff_section_data ((abfd), (sec))->tdata) - -/* COFF linker hash table entries. */ - -struct coff_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ - long indx; - - /* Symbol type. */ - unsigned short type; - - /* Symbol class. */ - unsigned char class; - - /* Number of auxiliary entries. */ - char numaux; - - /* BFD to take auxiliary entries from. */ - bfd *auxbfd; - - /* Pointer to array of auxiliary entries, if any. */ - union internal_auxent *aux; -}; - -/* COFF linker hash table. */ - -struct coff_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in a COFF linker hash table. */ - -#define coff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct coff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse a COFF linker hash table. */ - -#define coff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the COFF linker hash table from a link_info structure. */ - -#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash)) - -/* Functions in coffgen.c. */ -extern const bfd_target *coff_object_p PARAMS ((bfd *)); -extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int)); -extern long coff_get_symtab_upper_bound PARAMS ((bfd *)); -extern long coff_get_symtab PARAMS ((bfd *, asymbol **)); -extern int coff_count_linenumbers PARAMS ((bfd *)); -extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *)); -extern boolean coff_renumber_symbols PARAMS ((bfd *, int *)); -extern void coff_mangle_symbols PARAMS ((bfd *)); -extern boolean coff_write_symbols PARAMS ((bfd *)); -extern boolean coff_write_linenumbers PARAMS ((bfd *)); -extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *)); -extern asymbol *coff_section_symbol PARAMS ((bfd *, char *)); -extern boolean _bfd_coff_get_external_symbols PARAMS ((bfd *)); -extern const char *_bfd_coff_read_string_table PARAMS ((bfd *)); -extern boolean _bfd_coff_free_symbols PARAMS ((bfd *)); -extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *)); -extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -extern asymbol *coff_make_empty_symbol PARAMS ((bfd *)); -extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *, - bfd_print_symbol_type how)); -extern void coff_get_symbol_info PARAMS ((bfd *, asymbol *, - symbol_info *ret)); -extern asymbol *coff_bfd_make_debug_symbol PARAMS ((bfd *, PTR, - unsigned long)); -extern boolean coff_find_nearest_line PARAMS ((bfd *, - asection *, - asymbol **, - bfd_vma offset, - CONST char **filename_ptr, - CONST char **functionname_ptr, - unsigned int *line_ptr)); -extern int coff_sizeof_headers PARAMS ((bfd *, boolean reloc)); -extern boolean bfd_coff_reloc16_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); -extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean relocateable, asymbol **)); -extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *, - struct bfd_link_info *, - asection *)); -extern void bfd_perform_slip PARAMS ((bfd *abfd, unsigned int slip, - asection *input_section, - bfd_vma val)); - -/* Functions and types in cofflink.c. */ - -#define STRING_SIZE_SIZE (4) - -/* We use a hash table to merge identical enum, struct, and union - definitions in the linker. */ - -/* Information we keep for a single element (an enum value, a - structure or union field) in the debug merge hash table. */ - -struct coff_debug_merge_element -{ - /* Next element. */ - struct coff_debug_merge_element *next; - - /* Name. */ - const char *name; - - /* Type. */ - unsigned int type; - - /* Symbol index for complex type. */ - long tagndx; -}; - -/* A linked list of debug merge entries for a given name. */ - -struct coff_debug_merge_type -{ - /* Next type with the same name. */ - struct coff_debug_merge_type *next; - - /* Class of type. */ - int class; - - /* Symbol index where this type is defined. */ - long indx; - - /* List of elements. */ - struct coff_debug_merge_element *elements; -}; - -/* Information we store in the debug merge hash table. */ - -struct coff_debug_merge_hash_entry -{ - struct bfd_hash_entry root; - - /* A list of types with this name. */ - struct coff_debug_merge_type *types; -}; - -/* The debug merge hash table. */ - -struct coff_debug_merge_hash_table -{ - struct bfd_hash_table root; -}; - -/* Initialize a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_init(table) \ - (bfd_hash_table_init (&(table)->root, _bfd_coff_debug_merge_hash_newfunc)) - -/* Free a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_free(table) \ - (bfd_hash_table_free (&(table)->root)) - -/* Look up an entry in a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_lookup(table, string, create, copy) \ - ((struct coff_debug_merge_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* Information we keep for each section in the output file when doing - a relocateable link. */ - -struct coff_link_section_info -{ - /* The relocs to be output. */ - struct internal_reloc *relocs; - /* For each reloc against a global symbol whose index was not known - when the reloc was handled, the global hash table entry. */ - struct coff_link_hash_entry **rel_hashes; -}; - -/* Information that we pass around while doing the final link step. */ - -struct coff_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Used to indicate failure in traversal routine. */ - boolean failed; - /* Hash table for long symbol names. */ - struct bfd_strtab_hash *strtab; - /* When doing a relocateable link, an array of information kept for - each output section, indexed by the target_index field. */ - struct coff_link_section_info *section_info; - /* Symbol index of last C_FILE symbol (-1 if none). */ - long last_file_index; - /* Contents of last C_FILE symbol. */ - struct internal_syment last_file; - /* Hash table used to merge debug information. */ - struct coff_debug_merge_hash_table debug_merge; - /* Buffer large enough to hold swapped symbols of any input file. */ - struct internal_syment *internal_syms; - /* Buffer large enough to hold sections of symbols of any input file. */ - asection **sec_ptrs; - /* Buffer large enough to hold output indices of symbols of any - input file. */ - long *sym_indices; - /* Buffer large enough to hold output symbols for any input file. */ - bfd_byte *outsyms; - /* Buffer large enough to hold external line numbers for any input - section. */ - bfd_byte *linenos; - /* Buffer large enough to hold any input section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any input section. */ - bfd_byte *external_relocs; - /* Buffer large enough to hold swapped relocs of any input section. */ - struct internal_reloc *internal_relocs; -}; - -extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -extern boolean _bfd_coff_link_hash_table_init - PARAMS ((struct coff_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); -extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create - PARAMS ((bfd *)); -extern const char *_bfd_coff_internal_syment_name - PARAMS ((bfd *, const struct internal_syment *, char *)); -extern boolean _bfd_coff_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_coff_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -extern struct internal_reloc *_bfd_coff_read_internal_relocs - PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean, - struct internal_reloc *)); -extern boolean _bfd_coff_generic_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); - -extern struct bfd_hash_entry *_bfd_coff_debug_merge_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -extern boolean _bfd_coff_write_global_sym - PARAMS ((struct coff_link_hash_entry *, PTR)); -extern boolean _bfd_coff_link_input_bfd - PARAMS ((struct coff_final_link_info *, bfd *)); -extern boolean _bfd_coff_reloc_link_order - PARAMS ((bfd *, struct coff_final_link_info *, asection *, - struct bfd_link_order *)); - - -#define coff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Functions in xcofflink.c. */ - -extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create - PARAMS ((bfd *)); -extern boolean _bfd_xcoff_bfd_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_xcoff_bfd_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_ppc_xcoff_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); - -/* And more taken from the source .. */ - diff --git a/contrib/gdb/bfd/libcoff.h b/contrib/gdb/bfd/libcoff.h deleted file mode 100644 index daa39b52bd4..00000000000 --- a/contrib/gdb/bfd/libcoff.h +++ /dev/null @@ -1,823 +0,0 @@ -/* BFD COFF object file private structure. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -** NOTE: libcoff.h is a GENERATED file. Don't change it; instead, -** change libcoff-in.h or coffcode.h. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfdlink.h" - -/* Object file tdata; access macros */ - -#define coff_data(bfd) ((bfd)->tdata.coff_obj_data) -#define exec_hdr(bfd) (coff_data(bfd)->hdr) -#define obj_pe(bfd) (coff_data(bfd)->pe) -#define obj_symbols(bfd) (coff_data(bfd)->symbols) -#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos) - -#define obj_relocbase(bfd) (coff_data(bfd)->relocbase) -#define obj_raw_syments(bfd) (coff_data(bfd)->raw_syments) -#define obj_raw_syment_count(bfd) (coff_data(bfd)->raw_syment_count) -#define obj_convert(bfd) (coff_data(bfd)->conversion_table) -#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size) - -#define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms) -#define obj_coff_keep_syms(bfd) (coff_data (bfd)->keep_syms) -#define obj_coff_strings(bfd) (coff_data (bfd)->strings) -#define obj_coff_keep_strings(bfd) (coff_data (bfd)->keep_strings) -#define obj_coff_sym_hashes(bfd) (coff_data (bfd)->sym_hashes) - -#define obj_coff_local_toc_table(bfd) (coff_data(bfd)->local_toc_sym_map) - -/* `Tdata' information kept for COFF files. */ - -typedef struct coff_tdata -{ - struct coff_symbol_struct *symbols; /* symtab for input bfd */ - unsigned int *conversion_table; - int conv_table_size; - file_ptr sym_filepos; - - struct coff_ptr_struct *raw_syments; - unsigned int raw_syment_count; - - /* These are only valid once writing has begun */ - long int relocbase; - - /* These members communicate important constants about the symbol table - to GDB's symbol-reading code. These `constants' unfortunately vary - from coff implementation to implementation... */ - unsigned local_n_btmask; - unsigned local_n_btshft; - unsigned local_n_tmask; - unsigned local_n_tshift; - unsigned local_symesz; - unsigned local_auxesz; - unsigned local_linesz; - - /* The unswapped external symbols. May be NULL. Read by - _bfd_coff_get_external_symbols. */ - PTR external_syms; - /* If this is true, the external_syms may not be freed. */ - boolean keep_syms; - - /* The string table. May be NULL. Read by - _bfd_coff_read_string_table. */ - char *strings; - /* If this is true, the strings may not be freed. */ - boolean keep_strings; - - /* is this a PE format coff file */ - int pe; - /* Used by the COFF backend linker. */ - struct coff_link_hash_entry **sym_hashes; - - /* used by the pe linker for PowerPC */ - int *local_toc_sym_map; - - struct bfd_link_info *link_info; - - /* Used by coff_find_nearest_line. */ - PTR line_info; -} coff_data_type; - -/* Tdata for pe image files. */ -typedef struct pe_tdata -{ - coff_data_type coff; - struct internal_extra_pe_aouthdr pe_opthdr; - int dll; - int has_reloc_section; - boolean (*in_reloc_p) PARAMS((bfd *, reloc_howto_type *)); - flagword real_flags; -} pe_data_type; - -#define pe_data(bfd) ((bfd)->tdata.pe_obj_data) - -/* Tdata for XCOFF files. */ - -struct xcoff_tdata -{ - /* Basic COFF information. */ - coff_data_type coff; - - /* True if a large a.out header should be generated. */ - boolean full_aouthdr; - - /* TOC value. */ - bfd_vma toc; - - /* Index of section holding TOC. */ - int sntoc; - - /* Index of section holding entry point. */ - int snentry; - - /* .text alignment from optional header. */ - int text_align_power; - - /* .data alignment from optional header. */ - int data_align_power; - - /* modtype from optional header. */ - short modtype; - - /* cputype from optional header. */ - short cputype; - - /* maxdata from optional header. */ - bfd_size_type maxdata; - - /* maxstack from optional header. */ - bfd_size_type maxstack; - - /* Used by the XCOFF backend linker. */ - asection **csects; - unsigned long *debug_indices; - unsigned int import_file_id; -}; - -#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data) - -/* We take the address of the first element of a asymbol to ensure that the - * macro is only ever applied to an asymbol. */ -#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd))) - -/* The used_by_bfd field of a section may be set to a pointer to this - structure. */ - -struct coff_section_tdata -{ - /* The relocs, swapped into COFF internal form. This may be NULL. */ - struct internal_reloc *relocs; - /* If this is true, the relocs entry may not be freed. */ - boolean keep_relocs; - /* The section contents. This may be NULL. */ - bfd_byte *contents; - /* If this is true, the contents entry may not be freed. */ - boolean keep_contents; - /* Information cached by coff_find_nearest_line. */ - bfd_vma offset; - unsigned int i; - const char *function; - int line_base; - /* Available for individual backends. */ - PTR tdata; -}; - -/* An accessor macro for the coff_section_tdata structure. */ -#define coff_section_data(abfd, sec) \ - ((struct coff_section_tdata *) (sec)->used_by_bfd) - -/* Tdata for sections in XCOFF files. This is used by the linker. */ - -struct xcoff_section_tdata -{ - /* Used for XCOFF csects created by the linker; points to the real - XCOFF section which contains this csect. */ - asection *enclosing; - /* The lineno_count field for the enclosing section, because we are - going to clobber it there. */ - unsigned int lineno_count; - /* The first and one past the last symbol indices for symbols used - by this csect. */ - unsigned long first_symndx; - unsigned long last_symndx; -}; - -/* An accessor macro the xcoff_section_tdata structure. */ -#define xcoff_section_data(abfd, sec) \ - ((struct xcoff_section_tdata *) coff_section_data ((abfd), (sec))->tdata) - -/* COFF linker hash table entries. */ - -struct coff_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ - long indx; - - /* Symbol type. */ - unsigned short type; - - /* Symbol class. */ - unsigned char class; - - /* Number of auxiliary entries. */ - char numaux; - - /* BFD to take auxiliary entries from. */ - bfd *auxbfd; - - /* Pointer to array of auxiliary entries, if any. */ - union internal_auxent *aux; -}; - -/* COFF linker hash table. */ - -struct coff_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in a COFF linker hash table. */ - -#define coff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct coff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse a COFF linker hash table. */ - -#define coff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the COFF linker hash table from a link_info structure. */ - -#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash)) - -/* Functions in coffgen.c. */ -extern const bfd_target *coff_object_p PARAMS ((bfd *)); -extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int)); -extern long coff_get_symtab_upper_bound PARAMS ((bfd *)); -extern long coff_get_symtab PARAMS ((bfd *, asymbol **)); -extern int coff_count_linenumbers PARAMS ((bfd *)); -extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *)); -extern boolean coff_renumber_symbols PARAMS ((bfd *, int *)); -extern void coff_mangle_symbols PARAMS ((bfd *)); -extern boolean coff_write_symbols PARAMS ((bfd *)); -extern boolean coff_write_linenumbers PARAMS ((bfd *)); -extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *)); -extern asymbol *coff_section_symbol PARAMS ((bfd *, char *)); -extern boolean _bfd_coff_get_external_symbols PARAMS ((bfd *)); -extern const char *_bfd_coff_read_string_table PARAMS ((bfd *)); -extern boolean _bfd_coff_free_symbols PARAMS ((bfd *)); -extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *)); -extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -extern asymbol *coff_make_empty_symbol PARAMS ((bfd *)); -extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *, - bfd_print_symbol_type how)); -extern void coff_get_symbol_info PARAMS ((bfd *, asymbol *, - symbol_info *ret)); -extern asymbol *coff_bfd_make_debug_symbol PARAMS ((bfd *, PTR, - unsigned long)); -extern boolean coff_find_nearest_line PARAMS ((bfd *, - asection *, - asymbol **, - bfd_vma offset, - CONST char **filename_ptr, - CONST char **functionname_ptr, - unsigned int *line_ptr)); -extern int coff_sizeof_headers PARAMS ((bfd *, boolean reloc)); -extern boolean bfd_coff_reloc16_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); -extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean relocateable, asymbol **)); -extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *, - struct bfd_link_info *, - asection *)); -extern void bfd_perform_slip PARAMS ((bfd *abfd, unsigned int slip, - asection *input_section, - bfd_vma val)); - -/* Functions and types in cofflink.c. */ - -#define STRING_SIZE_SIZE (4) - -/* We use a hash table to merge identical enum, struct, and union - definitions in the linker. */ - -/* Information we keep for a single element (an enum value, a - structure or union field) in the debug merge hash table. */ - -struct coff_debug_merge_element -{ - /* Next element. */ - struct coff_debug_merge_element *next; - - /* Name. */ - const char *name; - - /* Type. */ - unsigned int type; - - /* Symbol index for complex type. */ - long tagndx; -}; - -/* A linked list of debug merge entries for a given name. */ - -struct coff_debug_merge_type -{ - /* Next type with the same name. */ - struct coff_debug_merge_type *next; - - /* Class of type. */ - int class; - - /* Symbol index where this type is defined. */ - long indx; - - /* List of elements. */ - struct coff_debug_merge_element *elements; -}; - -/* Information we store in the debug merge hash table. */ - -struct coff_debug_merge_hash_entry -{ - struct bfd_hash_entry root; - - /* A list of types with this name. */ - struct coff_debug_merge_type *types; -}; - -/* The debug merge hash table. */ - -struct coff_debug_merge_hash_table -{ - struct bfd_hash_table root; -}; - -/* Initialize a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_init(table) \ - (bfd_hash_table_init (&(table)->root, _bfd_coff_debug_merge_hash_newfunc)) - -/* Free a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_free(table) \ - (bfd_hash_table_free (&(table)->root)) - -/* Look up an entry in a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_lookup(table, string, create, copy) \ - ((struct coff_debug_merge_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* Information we keep for each section in the output file when doing - a relocateable link. */ - -struct coff_link_section_info -{ - /* The relocs to be output. */ - struct internal_reloc *relocs; - /* For each reloc against a global symbol whose index was not known - when the reloc was handled, the global hash table entry. */ - struct coff_link_hash_entry **rel_hashes; -}; - -/* Information that we pass around while doing the final link step. */ - -struct coff_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Used to indicate failure in traversal routine. */ - boolean failed; - /* Hash table for long symbol names. */ - struct bfd_strtab_hash *strtab; - /* When doing a relocateable link, an array of information kept for - each output section, indexed by the target_index field. */ - struct coff_link_section_info *section_info; - /* Symbol index of last C_FILE symbol (-1 if none). */ - long last_file_index; - /* Contents of last C_FILE symbol. */ - struct internal_syment last_file; - /* Hash table used to merge debug information. */ - struct coff_debug_merge_hash_table debug_merge; - /* Buffer large enough to hold swapped symbols of any input file. */ - struct internal_syment *internal_syms; - /* Buffer large enough to hold sections of symbols of any input file. */ - asection **sec_ptrs; - /* Buffer large enough to hold output indices of symbols of any - input file. */ - long *sym_indices; - /* Buffer large enough to hold output symbols for any input file. */ - bfd_byte *outsyms; - /* Buffer large enough to hold external line numbers for any input - section. */ - bfd_byte *linenos; - /* Buffer large enough to hold any input section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any input section. */ - bfd_byte *external_relocs; - /* Buffer large enough to hold swapped relocs of any input section. */ - struct internal_reloc *internal_relocs; -}; - -extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -extern boolean _bfd_coff_link_hash_table_init - PARAMS ((struct coff_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); -extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create - PARAMS ((bfd *)); -extern const char *_bfd_coff_internal_syment_name - PARAMS ((bfd *, const struct internal_syment *, char *)); -extern boolean _bfd_coff_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_coff_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -extern struct internal_reloc *_bfd_coff_read_internal_relocs - PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean, - struct internal_reloc *)); -extern boolean _bfd_coff_generic_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); - -extern struct bfd_hash_entry *_bfd_coff_debug_merge_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -extern boolean _bfd_coff_write_global_sym - PARAMS ((struct coff_link_hash_entry *, PTR)); -extern boolean _bfd_coff_link_input_bfd - PARAMS ((struct coff_final_link_info *, bfd *)); -extern boolean _bfd_coff_reloc_link_order - PARAMS ((bfd *, struct coff_final_link_info *, asection *, - struct bfd_link_order *)); - - -#define coff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Functions in xcofflink.c. */ - -extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create - PARAMS ((bfd *)); -extern boolean _bfd_xcoff_bfd_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_xcoff_bfd_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_ppc_xcoff_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); - -/* And more taken from the source .. */ - -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. */ -unsigned int fix_tag : 1; - - /* Should the endidx field of this symbol be renumbered. - Created by coff_pointerize_aux. */ -unsigned int fix_end : 1; - - /* Should the x_csect.x_scnlen field be renumbered. - Created by coff_pointerize_aux. */ -unsigned int fix_scnlen : 1; - - /* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the - index into the line number entries. Set by - coff_slurp_symbol_table. */ -unsigned int fix_line : 1; - - /* The container for the symbol structure as read and translated - from the file. */ - -union { - union internal_auxent auxent; - struct internal_syment syment; - } u; -} combined_entry_type; - - - /* Each canonical asymbol really looks like this: */ - -typedef struct coff_symbol_struct -{ - /* The actual symbol which the rest of BFD works with */ -asymbol symbol; - - /* A pointer to the hidden information for this symbol */ -combined_entry_type *native; - - /* A pointer to the linenumber information for this symbol */ -struct lineno_cache_entry *lineno; - - /* Have the line numbers been relocated yet ? */ -boolean done_lineno; -} coff_symbol_type; -typedef struct -{ - void (*_bfd_coff_swap_aux_in) PARAMS (( - bfd *abfd, - PTR ext, - int type, - int class, - int indaux, - int numaux, - PTR in)); - - void (*_bfd_coff_swap_sym_in) PARAMS (( - bfd *abfd , - PTR ext, - PTR in)); - - void (*_bfd_coff_swap_lineno_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - - unsigned int (*_bfd_coff_swap_aux_out) PARAMS (( - bfd *abfd, - PTR in, - int type, - int class, - int indaux, - int numaux, - PTR ext)); - - unsigned int (*_bfd_coff_swap_sym_out) PARAMS (( - bfd *abfd, - PTR in, - PTR ext)); - - unsigned int (*_bfd_coff_swap_lineno_out) PARAMS (( - bfd *abfd, - PTR in, - PTR ext)); - - unsigned int (*_bfd_coff_swap_reloc_out) PARAMS (( - bfd *abfd, - PTR src, - PTR dst)); - - unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS (( - bfd *abfd, - PTR in, - PTR out)); - - unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS (( - bfd *abfd, - PTR in, - PTR out)); - - unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS (( - bfd *abfd, - PTR in, - PTR out)); - - unsigned int _bfd_filhsz; - unsigned int _bfd_aoutsz; - unsigned int _bfd_scnhsz; - unsigned int _bfd_symesz; - unsigned int _bfd_auxesz; - unsigned int _bfd_relsz; - unsigned int _bfd_linesz; - boolean _bfd_coff_long_filenames; - void (*_bfd_coff_swap_filehdr_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - void (*_bfd_coff_swap_aouthdr_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - void (*_bfd_coff_swap_scnhdr_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - void (*_bfd_coff_swap_reloc_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - boolean (*_bfd_coff_bad_format_hook) PARAMS (( - bfd *abfd, - PTR internal_filehdr)); - boolean (*_bfd_coff_set_arch_mach_hook) PARAMS (( - bfd *abfd, - PTR internal_filehdr)); - PTR (*_bfd_coff_mkobject_hook) PARAMS (( - bfd *abfd, - PTR internal_filehdr, - PTR internal_aouthdr)); - flagword (*_bfd_styp_to_sec_flags_hook) PARAMS (( - bfd *abfd, - PTR internal_scnhdr, - const char *name)); - void (*_bfd_set_alignment_hook) PARAMS (( - bfd *abfd, - asection *sec, - PTR internal_scnhdr)); - boolean (*_bfd_coff_slurp_symbol_table) PARAMS (( - bfd *abfd)); - boolean (*_bfd_coff_symname_in_debug) PARAMS (( - bfd *abfd, - struct internal_syment *sym)); - boolean (*_bfd_coff_pointerize_aux_hook) PARAMS (( - bfd *abfd, - combined_entry_type *table_base, - combined_entry_type *symbol, - unsigned int indaux, - combined_entry_type *aux)); - boolean (*_bfd_coff_print_aux) PARAMS (( - bfd *abfd, - FILE *file, - combined_entry_type *table_base, - combined_entry_type *symbol, - combined_entry_type *aux, - unsigned int indaux)); - void (*_bfd_coff_reloc16_extra_cases) PARAMS (( - bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - arelent *reloc, - bfd_byte *data, - unsigned int *src_ptr, - unsigned int *dst_ptr)); - int (*_bfd_coff_reloc16_estimate) PARAMS (( - bfd *abfd, - asection *input_section, - arelent *r, - unsigned int shrink, - struct bfd_link_info *link_info)); - boolean (*_bfd_coff_sym_is_global) PARAMS (( - bfd *abfd, - struct internal_syment *)); - void (*_bfd_coff_compute_section_file_positions) PARAMS (( - bfd *abfd)); - boolean (*_bfd_coff_start_final_link) PARAMS (( - bfd *output_bfd, - struct bfd_link_info *info)); - boolean (*_bfd_coff_relocate_section) PARAMS (( - bfd *output_bfd, - struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - struct internal_reloc *relocs, - struct internal_syment *syms, - asection **sections)); - reloc_howto_type *(*_bfd_coff_rtype_to_howto) PARAMS (( - bfd *abfd, - asection *sec, - struct internal_reloc *rel, - struct coff_link_hash_entry *h, - struct internal_syment *sym, - bfd_vma *addendp)); - boolean (*_bfd_coff_adjust_symndx) PARAMS (( - bfd *obfd, - struct bfd_link_info *info, - bfd *ibfd, - asection *sec, - struct internal_reloc *reloc, - boolean *adjustedp)); - boolean (*_bfd_coff_link_add_one_symbol) PARAMS (( - struct bfd_link_info *info, - bfd *abfd, - const char *name, - flagword flags, - asection *section, - bfd_vma value, - const char *string, - boolean copy, - boolean collect, - struct bfd_link_hash_entry **hashp)); - -} 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,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)) - -#define bfd_coff_swap_lineno_in(a,e,i) \ - ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) - -#define bfd_coff_swap_reloc_out(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) - -#define bfd_coff_swap_lineno_out(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) - -#define bfd_coff_swap_aux_out(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)) - -#define bfd_coff_swap_scnhdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) - -#define bfd_coff_swap_filehdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) - -#define bfd_coff_swap_aouthdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) - -#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) -#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) -#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) -#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) -#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) -#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz) -#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) -#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames) -#define bfd_coff_swap_filehdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) - -#define bfd_coff_swap_aouthdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) - -#define bfd_coff_swap_scnhdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) - -#define bfd_coff_swap_reloc_in(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o)) - -#define bfd_coff_bad_format_hook(abfd, filehdr) \ - ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) - -#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ - ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) -#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ - ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr)) - -#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name)\ - ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr, name)) - -#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ - ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) - -#define bfd_coff_slurp_symbol_table(abfd)\ - ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) - -#define bfd_coff_symname_in_debug(abfd, sym)\ - ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) - -#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\ - ((coff_backend_info (abfd)->_bfd_coff_print_aux)\ - (abfd, file, base, symbol, aux, indaux)) - -#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, link_info, link_order, reloc, data, src_ptr, dst_ptr)) - -#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ - ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ - (abfd, section, reloc, shrink, link_info)) - -#define bfd_coff_sym_is_global(abfd, sym)\ - ((coff_backend_info (abfd)->_bfd_coff_sym_is_global)\ - (abfd, sym)) - -#define bfd_coff_compute_section_file_positions(abfd)\ - ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\ - (abfd)) - -#define bfd_coff_start_final_link(obfd, info)\ - ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\ - (obfd, info)) -#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\ - ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\ - (obfd, info, ibfd, o, con, rel, isyms, secs)) -#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\ - ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\ - (abfd, sec, rel, h, sym, addendp)) -#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ - ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ - (obfd, info, ibfd, sec, rel, adjustedp)) -#define bfd_coff_link_add_one_symbol(info,abfd,name,flags,section,value,string,cp,coll,hashp)\ - ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ - (info, abfd, name, flags, section, value, string, cp, coll, hashp)) - diff --git a/contrib/gdb/bfd/libecoff.h b/contrib/gdb/bfd/libecoff.h deleted file mode 100644 index 169610d0050..00000000000 --- a/contrib/gdb/bfd/libecoff.h +++ /dev/null @@ -1,352 +0,0 @@ -/* BFD ECOFF object file private structure. - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#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 - the generic COFF code. */ - -#define ecoff_backend(abfd) \ - ((struct ecoff_backend_data *) (abfd)->xvec->backend_data) - -struct ecoff_backend_data -{ - /* COFF backend information. This must be the first field. */ - bfd_coff_backend_data coff; - /* Supported architecture. */ - enum bfd_architecture arch; - /* Initial portion of armap string. */ - const char *armap_start; - /* 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. */ - reloc_howto_type *constructor_reloc; - /* 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 (*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)); - /* Do final adjustments to filehdr and aouthdr. */ - boolean (*adjust_headers) PARAMS ((bfd *, struct internal_filehdr *, - struct internal_aouthdr *)); - /* Read an element from an archive at a given file position. This - is needed because OSF/1 3.2 uses a weird archive format. */ - bfd *(*get_elt_at_filepos) PARAMS ((bfd *, file_ptr)); -}; - -/* This is the target specific information kept for ECOFF files. */ - -#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data) - -typedef struct ecoff_tdata -{ - /* The reloc file position, set by - ecoff_compute_section_file_positions. */ - file_ptr reloc_filepos; - - /* The symbol table file position, set by _bfd_ecoff_mkobject_hook. */ - file_ptr sym_filepos; - - /* The start and end of the text segment. Only valid for an - existing file, not for one we are creating. */ - unsigned long text_start; - unsigned long text_end; - - /* The cached gp value. This is used when relocating. */ - bfd_vma gp; - - /* The maximum size of objects to optimize using gp. This is - typically set by the -G option to the compiler, assembler or - linker. */ - unsigned int gp_size; - - /* The register masks. When linking, all the masks found in the - input files are combined into the masks of the output file. - These are not all used for all targets, but that's OK, because - the relevant ones are the only ones swapped in and out. */ - unsigned long gprmask; - unsigned long fprmask; - unsigned long cprmask[4]; - - /* The ECOFF symbolic debugging information. */ - struct ecoff_debug_info debug_info; - - /* The unswapped ECOFF symbolic information. */ - PTR raw_syments; - - /* 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; - - /* True if a warning that multiple global pointer values are - needed in the output binary was issued already. */ - boolean issued_multiple_gp_warning; - - /* Used by find_nearest_line entry point. The structure could be - included directly in this one, but there's no point to wasting - the memory just for the infrequently called find_nearest_line. */ - struct ecoff_find_line *find_line_info; - -} ecoff_data_type; - -/* Each canonical asymbol really looks like this. */ - -typedef struct ecoff_symbol_struct -{ - /* The actual symbol which the rest of BFD works with */ - asymbol symbol; - - /* The fdr for this symbol. */ - FDR *fdr; - - /* true if this is a local symbol rather than an external one. */ - boolean local; - - /* A pointer to the unswapped hidden information for this symbol. - This is either a struct sym_ext or a struct ext_ext, depending on - the value of the local field above. */ - PTR native; -} ecoff_symbol_type; - -/* We take the address of the first element of a asymbol to ensure that the - macro is only ever applied to an asymbol. */ -#define ecoffsymbol(asymbol) ((ecoff_symbol_type *) (&((asymbol)->the_bfd))) - -/* We need to save the index of an external symbol when we write it - out so that can set the symbol index correctly when we write out - the relocs. */ -#define ecoff_get_sym_index(symbol) ((symbol)->udata.i) -#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata.i = (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; - - /* When producing an executable (i.e., final, non-relocatable link) - on the Alpha, we may need to use multiple global pointer values - to span the entire .lita section. In essence, we allow each - input .lita section to have its own gp value. To support this, - we need to keep track of the gp values that we picked for each - input .lita section . */ - bfd_vma gp; -}; - -/* 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 _bfd_ecoff_mkobject PARAMS ((bfd *)); - -/* Read in the ECOFF symbolic debugging information. */ -extern boolean _bfd_ecoff_slurp_symbolic_info - PARAMS ((bfd *, asection *, struct ecoff_debug_info *)); - -/* Generic ECOFF BFD backend vectors. */ - -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)); - -#define _bfd_ecoff_bfd_link_split_section _bfd_generic_link_split_section - -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 - -#define _bfd_ecoff_bfd_copy_private_symbol_data \ - _bfd_generic_bfd_copy_private_symbol_data - -#define _bfd_ecoff_bfd_print_private_bfd_data \ - _bfd_generic_bfd_print_private_bfd_data - -#define _bfd_ecoff_bfd_merge_private_bfd_data \ - _bfd_generic_bfd_merge_private_bfd_data - -#define _bfd_ecoff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags -extern boolean _bfd_ecoff_slurp_armap PARAMS ((bfd *abfd)); -#define _bfd_ecoff_slurp_extended_name_table _bfd_slurp_extended_name_table -#define _bfd_ecoff_construct_extended_name_table \ - _bfd_archive_bsd_construct_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_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_ecoff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_ecoff_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define _bfd_ecoff_update_armap_timestamp bfd_true - -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 *)); -extern boolean _bfd_ecoff_bfd_is_local_label - PARAMS ((bfd *, asymbol *)); -#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_read_minisymbols _bfd_generic_read_minisymbols -#define _bfd_ecoff_minisymbol_to_symbol _bfd_generic_minisymbol_to_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 _bfd_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr)); -#define _bfd_ecoff_set_alignment_hook \ - ((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void) -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, const char *name)); -extern boolean _bfd_ecoff_slurp_symbol_table PARAMS ((bfd *abfd)); - -/* ECOFF auxiliary information swapping routines. These are the same - for all ECOFF targets, so they are defined in ecofflink.c. */ - -extern void _bfd_ecoff_swap_tir_in - PARAMS ((int, const struct tir_ext *, TIR *)); -extern void _bfd_ecoff_swap_tir_out - PARAMS ((int, const TIR *, struct tir_ext *)); -extern void _bfd_ecoff_swap_rndx_in - PARAMS ((int, const struct rndx_ext *, RNDXR *)); -extern void _bfd_ecoff_swap_rndx_out - PARAMS ((int, const RNDXR *, struct rndx_ext *)); diff --git a/contrib/gdb/bfd/libhppa.h b/contrib/gdb/bfd/libhppa.h deleted file mode 100644 index fa97b68821f..00000000000 --- a/contrib/gdb/bfd/libhppa.h +++ /dev/null @@ -1,549 +0,0 @@ -/* HP PA-RISC SOM object file format: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _HPPA_H -#define _HPPA_H - -#define BYTES_IN_WORD 4 -#define PA_PAGESIZE 0x1000 - -#ifndef INLINE -#ifdef __GNUC__ -#define INLINE inline -#else -#define INLINE -#endif /* GNU C? */ -#endif /* INLINE */ - -/* The PA instruction set variants. */ -enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20}; - -/* HP PA-RISC relocation types */ - -enum hppa_reloc_field_selector_type - { - R_HPPA_FSEL = 0x0, - R_HPPA_LSSEL = 0x1, - R_HPPA_RSSEL = 0x2, - R_HPPA_LSEL = 0x3, - R_HPPA_RSEL = 0x4, - R_HPPA_LDSEL = 0x5, - R_HPPA_RDSEL = 0x6, - R_HPPA_LRSEL = 0x7, - R_HPPA_RRSEL = 0x8, - R_HPPA_NSEL = 0x9, - R_HPPA_NLSEL = 0xa, - R_HPPA_NLRSEL = 0xb, - R_HPPA_PSEL = 0xc, - R_HPPA_LPSEL = 0xd, - R_HPPA_RPSEL = 0xe, - R_HPPA_TSEL = 0xf, - R_HPPA_LTSEL = 0x10, - R_HPPA_RTSEL = 0x11 - }; - -/* /usr/include/reloc.h defines these to constants. We want to use - them in enums, so #undef them before we start using them. We might - be able to fix this another way by simply managing not to include - /usr/include/reloc.h, but currently GDB picks up these defines - somewhere. */ -#undef e_fsel -#undef e_lssel -#undef e_rssel -#undef e_lsel -#undef e_rsel -#undef e_ldsel -#undef e_rdsel -#undef e_lrsel -#undef e_rrsel -#undef e_nsel -#undef e_nlsel -#undef e_nlrsel -#undef e_psel -#undef e_lpsel -#undef e_rpsel -#undef e_tsel -#undef e_ltsel -#undef e_rtsel -#undef e_one -#undef e_two -#undef e_pcrel -#undef e_con -#undef e_plabel -#undef e_abs - -/* for compatibility */ -enum hppa_reloc_field_selector_type_alt - { - e_fsel = R_HPPA_FSEL, - e_lssel = R_HPPA_LSSEL, - e_rssel = R_HPPA_RSSEL, - e_lsel = R_HPPA_LSEL, - e_rsel = R_HPPA_RSEL, - e_ldsel = R_HPPA_LDSEL, - e_rdsel = R_HPPA_RDSEL, - e_lrsel = R_HPPA_LRSEL, - e_rrsel = R_HPPA_RRSEL, - e_nsel = R_HPPA_NSEL, - e_nlsel = R_HPPA_NLSEL, - e_nlrsel = R_HPPA_NLRSEL, - e_psel = R_HPPA_PSEL, - e_lpsel = R_HPPA_LPSEL, - e_rpsel = R_HPPA_RPSEL, - e_tsel = R_HPPA_TSEL, - e_ltsel = R_HPPA_LTSEL, - e_rtsel = R_HPPA_RTSEL - }; - -enum hppa_reloc_expr_type - { - R_HPPA_E_ONE = 0, - R_HPPA_E_TWO = 1, - R_HPPA_E_PCREL = 2, - R_HPPA_E_CON = 3, - R_HPPA_E_PLABEL = 7, - R_HPPA_E_ABS = 18 - }; - -/* for compatibility */ -enum hppa_reloc_expr_type_alt - { - e_one = R_HPPA_E_ONE, - e_two = R_HPPA_E_TWO, - e_pcrel = R_HPPA_E_PCREL, - e_con = R_HPPA_E_CON, - e_plabel = R_HPPA_E_PLABEL, - e_abs = R_HPPA_E_ABS - }; - - -/* Relocations for function calls must be accompanied by parameter - relocation bits. These bits describe exactly where the caller has - placed the function's arguments and where it expects to find a return - value. - - Both ELF and SOM encode this information within the addend field - of the call relocation. (Note this could break very badly if one - was to make a call like bl foo + 0x12345678). - - The high order 10 bits contain parameter relocation information, - the low order 22 bits contain the constant offset. */ - -#define HPPA_R_ARG_RELOC(a) (((a) >> 22) & 0x3FF) -#define HPPA_R_CONSTANT(a) ((((int)(a)) << 10) >> 10) -#define HPPA_R_ADDEND(r,c) (((r) << 22) + ((c) & 0x3FFFFF)) - -/* Some functions to manipulate PA instructions. */ -static INLINE unsigned int -assemble_3 (x) - unsigned int x; -{ - return (((x & 1) << 2) | ((x & 6) >> 1)) & 7; -} - -static INLINE void -dis_assemble_3 (x, r) - unsigned int x; - unsigned int *r; -{ - *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7; -} - -static INLINE unsigned int -assemble_12 (x, y) - unsigned int x, y; -{ - return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff; -} - -static INLINE void -dis_assemble_12 (as12, x, y) - unsigned int as12; - unsigned int *x, *y; -{ - *y = (as12 & 0x800) >> 11; - *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10); -} - -static INLINE unsigned long -assemble_17 (x, y, z) - unsigned int x, y, z; -{ - unsigned long temp; - - temp = ((z & 1) << 16) | - ((x & 0x1f) << 11) | - ((y & 1) << 10) | - ((y & 0x7fe) >> 1); - return temp & 0x1ffff; -} - -static INLINE void -dis_assemble_17 (as17, x, y, z) - unsigned int as17; - unsigned int *x, *y, *z; -{ - - *z = (as17 & 0x10000) >> 16; - *x = (as17 & 0x0f800) >> 11; - *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff; -} - -static INLINE unsigned long -assemble_21 (x) - unsigned int x; -{ - unsigned long temp; - - temp = ((x & 1) << 20) | - ((x & 0xffe) << 8) | - ((x & 0xc000) >> 7) | - ((x & 0x1f0000) >> 14) | - ((x & 0x003000) >> 12); - return temp & 0x1fffff; -} - -static INLINE void -dis_assemble_21 (as21, x) - unsigned int as21, *x; -{ - unsigned long temp; - - - temp = (as21 & 0x100000) >> 20; - temp |= (as21 & 0x0ffe00) >> 8; - temp |= (as21 & 0x000180) << 7; - temp |= (as21 & 0x00007c) << 14; - temp |= (as21 & 0x000003) << 12; - *x = temp; -} - -static INLINE unsigned long -sign_extend (x, len) - unsigned int x, len; -{ - return (int)(x >> (len - 1) ? (-1 << len) | x : x); -} - -static INLINE unsigned int -ones (n) - int n; -{ - unsigned int len_ones; - int i; - - i = 0; - len_ones = 0; - while (i < n) - { - len_ones = (len_ones << 1) | 1; - i++; - } - - return len_ones; -} - -static INLINE void -sign_unext (x, len, result) - unsigned int x, len; - unsigned int *result; -{ - unsigned int len_ones; - - len_ones = ones (len); - - *result = x & len_ones; -} - -static INLINE unsigned long -low_sign_extend (x, len) - unsigned int x, len; -{ - return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1); -} - -static INLINE void -low_sign_unext (x, len, result) - unsigned int x, len; - unsigned int *result; -{ - unsigned int temp; - unsigned int sign; - unsigned int rest; - unsigned int one_bit_at_len; - unsigned int len_ones; - - len_ones = ones (len); - one_bit_at_len = 1 << (len - 1); - - sign_unext (x, len, &temp); - sign = temp & one_bit_at_len; - sign >>= (len - 1); - - rest = temp & (len_ones ^ one_bit_at_len); - rest <<= 1; - - *result = rest | sign; -} - -/* Handle field selectors for PA instructions. */ - -static INLINE unsigned long -hppa_field_adjust (value, constant_value, r_field) - unsigned long value; - unsigned long constant_value; - unsigned short r_field; -{ - switch (r_field) - { - case e_fsel: /* F : no change */ - case e_nsel: /* N : no change */ - value += constant_value; - break; - - case e_lssel: /* LS : if (bit 21) then add 0x800 - arithmetic shift right 11 bits */ - value += constant_value; - if (value & 0x00000400) - value += 0x800; - value = (value & 0xfffff800) >> 11; - break; - - case e_rssel: /* RS : Sign extend from bit 21 */ - value += constant_value; - if (value & 0x00000400) - value |= 0xfffff800; - else - value &= 0x7ff; - break; - - case e_lsel: /* L : Arithmetic shift right 11 bits */ - case e_nlsel: /* NL : Arithmetic shift right 11 bits */ - value += constant_value; - value = (value & 0xfffff800) >> 11; - break; - - case e_rsel: /* R : Set bits 0-20 to zero */ - value += constant_value; - value = value & 0x7ff; - break; - - case e_ldsel: /* LD : Add 0x800, arithmetic shift - right 11 bits */ - value += constant_value; - value += 0x800; - value = (value & 0xfffff800) >> 11; - break; - - case e_rdsel: /* RD : Set bits 0-20 to one */ - value += constant_value; - value |= 0xfffff800; - break; - - case e_lrsel: /* LR : L with "rounded" constant */ - case e_nlrsel: /* NLR : NL with "rounded" constant */ - value = value + ((constant_value + 0x1000) & 0xffffe000); - value = (value & 0xfffff800) >> 11; - break; - - case e_rrsel: /* RR : R with "rounded" constant */ - value = value + ((constant_value + 0x1000) & 0xffffe000); - value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000); - break; - - default: - abort (); - } - return value; - -} - -/* PA-RISC OPCODES */ -#define get_opcode(insn) ((insn) & 0xfc000000) >> 26 - -/* FIXME: this list is incomplete. It should also be an enumerated - type rather than #defines. */ - -#define LDO 0x0d -#define LDB 0x10 -#define LDH 0x11 -#define LDW 0x12 -#define LDWM 0x13 -#define STB 0x18 -#define STH 0x19 -#define STW 0x1a -#define STWM 0x1b -#define COMICLR 0x24 -#define SUBI 0x25 -#define SUBIO 0x25 -#define ADDIT 0x2c -#define ADDITO 0x2c -#define ADDI 0x2d -#define ADDIO 0x2d -#define LDIL 0x08 -#define ADDIL 0x0a - -#define MOVB 0x32 -#define MOVIB 0x33 -#define COMBT 0x20 -#define COMBF 0x22 -#define COMIBT 0x21 -#define COMIBF 0x23 -#define ADDBT 0x28 -#define ADDBF 0x2a -#define ADDIBT 0x29 -#define ADDIBF 0x2b -#define BVB 0x30 -#define BB 0x31 - -#define BL 0x3a -#define BLE 0x39 -#define BE 0x38 - - -/* Given a machine instruction, return its format. - - FIXME: opcodes which do not map to a known format - should return an error of some sort. */ - -static INLINE char -bfd_hppa_insn2fmt (insn) - unsigned long insn; -{ - char fmt = -1; - unsigned char op = get_opcode (insn); - - switch (op) - { - case ADDI: - case ADDIT: - case SUBI: - fmt = 11; - break; - case MOVB: - case MOVIB: - case COMBT: - case COMBF: - case COMIBT: - case COMIBF: - case ADDBT: - case ADDBF: - case ADDIBT: - case ADDIBF: - case BVB: - case BB: - fmt = 12; - break; - case LDO: - case LDB: - case LDH: - case LDW: - case LDWM: - case STB: - case STH: - case STW: - case STWM: - fmt = 14; - break; - case BL: - case BE: - case BLE: - fmt = 17; - break; - case LDIL: - case ADDIL: - fmt = 21; - break; - default: - fmt = 32; - break; - } - return fmt; -} - - -/* Insert VALUE into INSN using R_FORMAT to determine exactly what - bits to change. */ - -static INLINE unsigned long -hppa_rebuild_insn (abfd, insn, value, r_format) - bfd *abfd; - unsigned long insn; - unsigned long value; - unsigned long r_format; -{ - unsigned long const_part; - unsigned long rebuilt_part; - - switch (r_format) - { - case 11: - { - unsigned w1, w; - - const_part = insn & 0xffffe002; - dis_assemble_12 (value, &w1, &w); - rebuilt_part = (w1 << 2) | w; - return const_part | rebuilt_part; - } - - case 12: - { - unsigned w1, w; - - const_part = insn & 0xffffe002; - dis_assemble_12 (value, &w1, &w); - rebuilt_part = (w1 << 2) | w; - return const_part | rebuilt_part; - } - - case 14: - const_part = insn & 0xffffc000; - low_sign_unext (value, 14, &rebuilt_part); - return const_part | rebuilt_part; - - case 17: - { - unsigned w1, w2, w; - - const_part = insn & 0xffe0e002; - dis_assemble_17 (value, &w1, &w2, &w); - rebuilt_part = (w2 << 2) | (w1 << 16) | w; - return const_part | rebuilt_part; - } - - case 21: - const_part = insn & 0xffe00000; - dis_assemble_21 (value, &rebuilt_part); - return const_part | rebuilt_part; - - case 32: - const_part = 0; - return value; - - default: - abort (); - } - return insn; -} - -#endif /* _HPPA_H */ diff --git a/contrib/gdb/bfd/libieee.h b/contrib/gdb/bfd/libieee.h deleted file mode 100644 index c3729cbf517..00000000000 --- a/contrib/gdb/bfd/libieee.h +++ /dev/null @@ -1,135 +0,0 @@ -/* IEEE-695 object file formats: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. Mostly Steve Chamberlain's fault. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -typedef struct { - unsigned int index:24; - char letter; -} ieee_symbol_index_type; - -typedef struct ct { - bfd *this; - struct ct *next; -} bfd_chain_type; - -typedef struct ieee_symbol -{ - asymbol symbol; - struct ieee_symbol *next; - - unsigned int index; -} ieee_symbol_type; - - -typedef struct ieee_reloc { - arelent relent; - struct ieee_reloc *next; - ieee_symbol_index_type symbol; - -} ieee_reloc_type; - -#define ieee_symbol(x) ((ieee_symbol_type *)(x)) - -typedef struct ieee_per_section -{ - asection *section; - bfd_byte *data; - bfd_vma offset; - bfd_vma pc; - /* For output */ - file_ptr current_pos; - unsigned int current_byte; - boolean initialized; - ieee_reloc_type **reloc_tail_ptr; -} ieee_per_section_type; - -#define ieee_per_section(x) ((ieee_per_section_type *)((x)->used_by_bfd)) -/* FIXME! There should be no limit to the number of sections! */ -#define NSECTIONS 20 - - -typedef struct { - unsigned char *input_p; - unsigned char *first_byte; - bfd *abfd; -} common_header_type ; - -typedef struct ieee_data_struct -{ - common_header_type h; - boolean read_symbols; - boolean read_data; - file_ptr output_cursor; - /* Map of section indexes to section ptrs */ - asection * section_table[NSECTIONS]; - ieee_address_descriptor_type ad; - ieee_module_begin_type mb; - ieee_w_variable_type w; - - unsigned int section_count; - - unsigned int map_idx; - /* List of GLOBAL EXPORT symbols */ - ieee_symbol_type *external_symbols; - /* List of UNDEFINED symbols */ - ieee_symbol_type *external_reference; - - /* When the symbols have been canonicalized, they are in a - * special order, we remember various bases here.. */ - unsigned int external_symbol_max_index; - unsigned int external_symbol_min_index; - unsigned int external_symbol_count; - int external_symbol_base_offset; - - unsigned int external_reference_max_index; - unsigned int external_reference_min_index; - unsigned int external_reference_count; - int external_reference_base_offset; - - - boolean symbol_table_full; - - -boolean done_debug; - - -bfd_chain_type *chain_head; -bfd_chain_type *chain_root; - -} ieee_data_type; - -typedef struct { - file_ptr file_offset; - bfd *abfd; -} ieee_ar_obstack_type; - -typedef struct ieee_ar_data_struct -{ - common_header_type h; - ieee_ar_obstack_type *elements; - - unsigned int element_index ; - unsigned int element_count; - -} ieee_ar_data_type; - -#define IEEE_DATA(abfd) ((abfd)->tdata.ieee_data) -#define IEEE_AR_DATA(abfd) ((abfd)->tdata.ieee_ar_data) - -#define ptr(abfd) (ieee_data(abfd)->input_p) diff --git a/contrib/gdb/bfd/libnlm.h b/contrib/gdb/bfd/libnlm.h deleted file mode 100644 index 12d2e4e0cf8..00000000000 --- a/contrib/gdb/bfd/libnlm.h +++ /dev/null @@ -1,264 +0,0 @@ -/* BFD back-end data structures for NLM (NetWare Loadable Modules) files. - Copyright (C) 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _LIBNLM_H_ -#define _LIBNLM_H_ 1 - -#ifdef ARCH_SIZE -# define NLM_ARCH_SIZE ARCH_SIZE -#endif -#include "nlm/common.h" -#include "nlm/internal.h" -#include "nlm/external.h" - -/* A reloc for an imported NLM symbol. Normal relocs are associated - with sections, and include a symbol. These relocs are associated - with (undefined) symbols, and include a section. */ - -struct nlm_relent -{ - /* Section of reloc. */ - asection *section; - /* Reloc info (sym_ptr_ptr field set only when canonicalized). */ - arelent reloc; -}; - -/* Information we keep for an NLM symbol. */ - -typedef struct -{ - /* BFD symbol. */ - asymbol symbol; - /* Number of reloc entries for imported symbol. */ - bfd_size_type rcnt; - /* Array of reloc information for imported symbol. */ - struct nlm_relent *relocs; -} nlmNAME(symbol_type); - -extern boolean nlm_mkobject PARAMS ((bfd *)); -extern boolean nlm_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); - -extern void nlmNAME(get_symbol_info) - PARAMS ((bfd *, asymbol *, symbol_info *)); -extern long nlmNAME(get_symtab_upper_bound) - PARAMS ((bfd *)); -extern long nlmNAME(get_symtab) - PARAMS ((bfd *, asymbol **)); -extern asymbol *nlmNAME(make_empty_symbol) - PARAMS ((bfd *)); -extern void nlmNAME(print_symbol) - PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); -extern long nlmNAME(get_reloc_upper_bound) - PARAMS ((bfd *, asection *)); -extern long nlmNAME(canonicalize_reloc) - PARAMS ((bfd *, asection *, arelent **, asymbol **)); -extern const bfd_target *nlmNAME(object_p) - PARAMS ((bfd *)); -extern boolean nlmNAME(set_arch_mach) - PARAMS ((bfd *, enum bfd_architecture, unsigned long)); -extern boolean nlmNAME(set_section_contents) - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); -extern boolean nlmNAME(write_object_contents) - PARAMS ((bfd *)); - -/* Some private data is stashed away for future use using the tdata pointer - in the bfd structure. */ - -struct nlm_obj_tdata -{ - /* Actual data, but ref like ptr */ - Nlm_Internal_Fixed_Header nlm_fixed_hdr[1]; - Nlm_Internal_Variable_Header nlm_variable_hdr[1]; - Nlm_Internal_Version_Header nlm_version_hdr[1]; - Nlm_Internal_Copyright_Header nlm_copyright_hdr[1]; - Nlm_Internal_Extended_Header nlm_extended_hdr[1]; - Nlm_Internal_Custom_Header nlm_custom_hdr[1]; - Nlm_Internal_Cygnus_Ext_Header nlm_cygnus_ext_hdr[1]; - /* BFD NLM symbols. */ - nlmNAME(symbol_type) *nlm_symbols; - /* Lowest text and data VMA values. */ - bfd_vma nlm_text_low; - bfd_vma nlm_data_low; - /* Caches for data read from object file. */ - arelent * nlm_reloc_fixups; - asection ** nlm_reloc_fixup_secs; - /* Backend specific information. This should probably be a pointer, - but that would require yet another entry point to initialize the - structure. */ - union - { - struct /* Alpha backend information. */ - { - bfd_vma gp; /* GP value. */ - bfd_vma lita_address; /* .lita section address. */ - bfd_size_type lita_size; /* .lita section size. */ - } - alpha_backend_data; - } - backend_data; -}; - -#define nlm_tdata(bfd) ((bfd) -> tdata.nlm_obj_data) -#define nlm_fixed_header(bfd) (nlm_tdata(bfd) -> nlm_fixed_hdr) -#define nlm_variable_header(bfd) (nlm_tdata(bfd) -> nlm_variable_hdr) -#define nlm_version_header(bfd) (nlm_tdata(bfd) -> nlm_version_hdr) -#define nlm_copyright_header(bfd) (nlm_tdata(bfd) -> nlm_copyright_hdr) -#define nlm_extended_header(bfd) (nlm_tdata(bfd) -> nlm_extended_hdr) -#define nlm_custom_header(bfd) (nlm_tdata(bfd) -> nlm_custom_hdr) -#define nlm_cygnus_ext_header(bfd) (nlm_tdata(bfd) -> nlm_cygnus_ext_hdr) -#define nlm_get_symbols(bfd) (nlm_tdata(bfd) -> nlm_symbols) -#define nlm_set_symbols(bfd, p) (nlm_tdata(bfd) -> nlm_symbols = (p)) -#define nlm_set_text_low(bfd, i) (nlm_tdata(bfd) -> nlm_text_low = (i)) -#define nlm_get_text_low(bfd) (nlm_tdata(bfd) -> nlm_text_low) -#define nlm_set_data_low(bfd, i) (nlm_tdata(bfd) -> nlm_data_low = (i)) -#define nlm_get_data_low(bfd) (nlm_tdata(bfd) -> nlm_data_low) -#define nlm_relocation_fixups(bfd) (nlm_tdata(bfd) -> nlm_reloc_fixups) -#define nlm_relocation_fixup_secs(bfd) (nlm_tdata(bfd)->nlm_reloc_fixup_secs) - -#define nlm_alpha_backend_data(bfd) \ - (&nlm_tdata (bfd)->backend_data.alpha_backend_data) - -/* This is used when writing out the external relocs. */ - -struct reloc_and_sec -{ - arelent *rel; - asection *sec; -}; - -/* We store some function pointer in the backend structure. This lets - different NLM targets share most of the same code, while providing - slightly different code where necessary. */ - -struct nlm_backend_data -{ - /* Signature for this backend. */ - char signature[NLM_SIGNATURE_SIZE]; - /* Size of the fixed header. */ - bfd_size_type fixed_header_size; - /* Size of optional prefix for this backend. Some backend may - require this to be a function, but so far a constant is OK. This - is for a prefix which precedes the standard NLM fixed header. */ - bfd_size_type optional_prefix_size; - /* Architecture. */ - enum bfd_architecture arch; - /* Machine. */ - long mach; - /* Some NLM formats do not use the uninitialized data section, so - all uninitialized data must be put into the regular data section - instead. */ - boolean no_uninitialized_data; - /* Some NLM formats have a prefix on the file. If this function is - not NULL, it will be called by nlm_object_p. It should return - true if this file could match this format, and it should leave - the BFD such that a bfd_read will pick up the fixed header. */ - boolean (*nlm_backend_object_p) PARAMS ((bfd *)); - /* Write out the prefix. This function may be NULL. This must - write out the same number of bytes as is in the field - optional_prefix_size. */ - boolean (*nlm_write_prefix) PARAMS ((bfd *)); - /* Read a relocation fixup from abfd. The reloc information is - machine specific. The second argument is the symbol if this is - an import, or NULL if this is a reloc fixup. This function - should set the third argument to the section which the reloc - belongs in, and the fourth argument to the reloc itself; it does - not need to fill in the sym_ptr_ptr field for a reloc against an - import symbol. */ - boolean (*nlm_read_reloc) PARAMS ((bfd *, nlmNAME(symbol_type) *, - asection **, arelent *)); - /* To make objcopy to an i386 NLM work, the i386 backend needs a - chance to work over the relocs. This is a bit icky. */ - boolean (*nlm_mangle_relocs) PARAMS ((bfd *, asection *, PTR data, - bfd_vma offset, - bfd_size_type count)); - /* Read an import record from abfd. It would be nice if this - were in a machine-dependent format, but it doesn't seem to be. */ - boolean (*nlm_read_import) PARAMS ((bfd *, nlmNAME(symbol_type) *)); - /* Write an import record to abfd. */ - boolean (*nlm_write_import) PARAMS ((bfd *, asection *, arelent *)); - /* Set the section for a public symbol. This may be NULL, in which - case a default method will be used. */ - boolean (*nlm_set_public_section) PARAMS ((bfd *, nlmNAME(symbol_type) *)); - /* Get the offset to write out for a public symbol. This may be - NULL, in which case a default method will be used. */ - bfd_vma (*nlm_get_public_offset) PARAMS ((bfd *, asymbol *)); - /* Swap the fixed header in and out */ - void (*nlm_swap_fhdr_in) PARAMS ((bfd *, - PTR, - Nlm_Internal_Fixed_Header *)); - void (*nlm_swap_fhdr_out) PARAMS ((bfd *, - struct nlm_internal_fixed_header *, - PTR)); - /* Write out an external reference. */ - boolean (*nlm_write_external) PARAMS ((bfd *, bfd_size_type, - asymbol *, - struct reloc_and_sec *)); - boolean (*nlm_write_export) PARAMS ((bfd *, asymbol *, bfd_vma)); -}; - -#define nlm_backend(bfd) \ - ((struct nlm_backend_data *)((bfd) -> xvec -> backend_data)) -#define nlm_signature(bfd) \ - (nlm_backend(bfd) -> signature) -#define nlm_fixed_header_size(bfd) \ - (nlm_backend(bfd) -> fixed_header_size) -#define nlm_optional_prefix_size(bfd) \ - (nlm_backend(bfd) -> optional_prefix_size) -#define nlm_architecture(bfd) \ - (nlm_backend(bfd) -> arch) -#define nlm_machine(bfd) \ - (nlm_backend(bfd) -> mach) -#define nlm_no_uninitialized_data(bfd) \ - (nlm_backend(bfd) -> no_uninitialized_data) -#define nlm_backend_object_p_func(bfd) \ - (nlm_backend(bfd) -> nlm_backend_object_p) -#define nlm_write_prefix_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_prefix) -#define nlm_read_reloc_func(bfd) \ - (nlm_backend(bfd) -> nlm_read_reloc) -#define nlm_mangle_relocs_func(bfd) \ - (nlm_backend(bfd) -> nlm_mangle_relocs) -#define nlm_read_import_func(bfd) \ - (nlm_backend(bfd) -> nlm_read_import) -#define nlm_write_import_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_import) -#define nlm_set_public_section_func(bfd) \ - (nlm_backend(bfd) -> nlm_set_public_section) -#define nlm_get_public_offset_func(bfd) \ - (nlm_backend(bfd) -> nlm_get_public_offset) -#define nlm_swap_fixed_header_in_func(bfd) \ - (nlm_backend(bfd) -> nlm_swap_fhdr_in) -#define nlm_swap_fixed_header_out_func(bfd) \ - (nlm_backend(bfd) -> nlm_swap_fhdr_out) -#define nlm_write_external_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_external) -#define nlm_write_export_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_export) - -/* The NLM code, data, and uninitialized sections have no names defined - in the NLM, but bfd wants to give them names, so use the traditional - UNIX names. */ - -#define NLM_CODE_NAME ".text" -#define NLM_INITIALIZED_DATA_NAME ".data" -#define NLM_UNINITIALIZED_DATA_NAME ".bss" - -#endif /* _LIBNLM_H_ */ diff --git a/contrib/gdb/bfd/liboasys.h b/contrib/gdb/bfd/liboasys.h deleted file mode 100644 index 2d158137656..00000000000 --- a/contrib/gdb/bfd/liboasys.h +++ /dev/null @@ -1,83 +0,0 @@ -/* BFD internal declarations for Oasys file format handling. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Scrawled by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -typedef struct _oasys_symbol -{ - asymbol symbol; -} oasys_symbol_type; - -typedef struct _oasys_reloc { - arelent relent; - struct _oasys_reloc *next; - unsigned int symbol; -} oasys_reloc_type; - - -#define oasys_symbol(x) ((oasys_symbol_type *)(x)) -#define oasys_per_section(x) ((oasys_per_section_type *)(x->used_by_bfd)) - -typedef struct _oasys_per_section -{ - asection *section; - bfd_byte *data; - bfd_vma offset; - boolean had_vma; - oasys_reloc_type **reloc_tail_ptr; - bfd_vma pc; - - - file_ptr current_pos; - unsigned int current_byte; - boolean initialized; -} oasys_per_section_type; - -#define NSECTIONS 10 - -typedef struct _oasys_ar_obstack { - file_ptr file_offset; - bfd *abfd; -} oasys_ar_obstack_type; - - -typedef struct _oasys_module_info { - file_ptr pos; - unsigned int size; - bfd *abfd; - char *name; -} oasys_module_info_type; - -typedef struct _oasys_ar_data { - oasys_module_info_type *module; - unsigned int module_count; - unsigned int module_index; -} oasys_ar_data_type; - -typedef struct _oasys_data { - struct obstack oasys_obstack; - char *strings; - asymbol *symbols; - unsigned int symbol_string_length; - asection *sections[OASYS_MAX_SEC_COUNT]; - file_ptr first_data_record; -} oasys_data_type; - -#define OASYS_DATA(abfd) ((abfd)->tdata.oasys_obj_data) -#define OASYS_AR_DATA(abfd) ((abfd)->tdata.oasys_ar_data) - diff --git a/contrib/gdb/bfd/linker.c b/contrib/gdb/bfd/linker.c deleted file mode 100644 index 4decc88cafa..00000000000 --- a/contrib/gdb/bfd/linker.c +++ /dev/null @@ -1,2781 +0,0 @@ -/* linker.c -- BFD linker routines - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" - -/* -SECTION - Linker Functions - -@cindex Linker - The linker uses three special entry points in the BFD target - vector. It is not necessary to write special routines for - these entry points when creating a new BFD back end, since - generic versions are provided. However, writing them can - speed up linking and make it use significantly less runtime - memory. - - The first routine creates a hash table used by the other - routines. The second routine adds the symbols from an object - file to the hash table. The third routine takes all the - object files and links them together to create the output - file. These routines are designed so that the linker proper - does not need to know anything about the symbols in the object - files that it is linking. The linker merely arranges the - sections as directed by the linker script and lets BFD handle - the details of symbols and relocs. - - The second routine and third routines are passed a pointer to - a <> structure (defined in - <>) which holds information relevant to the link, - including the linker hash table (which was created by the - first routine) and a set of callback functions to the linker - proper. - - The generic linker routines are in <>, and use the - header file <>. As of this writing, the only back - ends which have implemented versions of these routines are - a.out (in <>) and ECOFF (in <>). The a.out - routines are used as examples throughout this section. - -@menu -@* Creating a Linker Hash Table:: -@* Adding Symbols to the Hash Table:: -@* Performing the Final Link:: -@end menu - -INODE -Creating a Linker Hash Table, Adding Symbols to the Hash Table, Linker Functions, Linker Functions -SUBSECTION - Creating a linker hash table - -@cindex _bfd_link_hash_table_create in target vector -@cindex target vector (_bfd_link_hash_table_create) - The linker routines must create a hash table, which must be - derived from <> described in - <>. @xref{Hash Tables} for information on how to - create a derived hash table. This entry point is called using - the target vector of the linker output file. - - The <<_bfd_link_hash_table_create>> entry point must allocate - and initialize an instance of the desired hash table. If the - back end does not require any additional information to be - stored with the entries in the hash table, the entry point may - simply create a <>. Most likely, - however, some additional information will be needed. - - For example, with each entry in the hash table the a.out - linker keeps the index the symbol has in the final output file - (this index number is used so that when doing a relocateable - link the symbol index used in the output file can be quickly - filled in when copying over a reloc). The a.out linker code - defines the required structures and functions for a hash table - derived from <>. The a.out linker - hash table is created by the function - <>; it simply allocates - space for the hash table, initializes it, and returns a - pointer to it. - - When writing the linker routines for a new back end, you will - generally not know exactly which fields will be required until - you have finished. You should simply create a new hash table - which defines no additional fields, and then simply add fields - as they become necessary. - -INODE -Adding Symbols to the Hash Table, Performing the Final Link, Creating a Linker Hash Table, Linker Functions -SUBSECTION - Adding symbols to the hash table - -@cindex _bfd_link_add_symbols in target vector -@cindex target vector (_bfd_link_add_symbols) - The linker proper will call the <<_bfd_link_add_symbols>> - entry point for each object file or archive which is to be - linked (typically these are the files named on the command - line, but some may also come from the linker script). The - entry point is responsible for examining the file. For an - object file, BFD must add any relevant symbol information to - the hash table. For an archive, BFD must determine which - elements of the archive should be used and adding them to the - link. - - The a.out version of this entry point is - <>. - -@menu -@* Differing file formats:: -@* Adding symbols from an object file:: -@* Adding symbols from an archive:: -@end menu - -INODE -Differing file formats, Adding symbols from an object file, Adding Symbols to the Hash Table, Adding Symbols to the Hash Table -SUBSUBSECTION - Differing file formats - - Normally all the files involved in a link will be of the same - format, but it is also possible to link together different - format object files, and the back end must support that. The - <<_bfd_link_add_symbols>> entry point is called via the target - vector of the file to be added. This has an important - consequence: the function may not assume that the hash table - is the type created by the corresponding - <<_bfd_link_hash_table_create>> vector. All the - <<_bfd_link_add_symbols>> function can assume about the hash - table is that it is derived from <>. - - Sometimes the <<_bfd_link_add_symbols>> function must store - some information in the hash table entry to be used by the - <<_bfd_final_link>> function. In such a case the <> - field of the hash table must be checked to make sure that the - hash table was created by an object file of the same format. - - The <<_bfd_final_link>> routine must be prepared to handle a - hash entry without any extra information added by the - <<_bfd_link_add_symbols>> function. A hash entry without - extra information will also occur when the linker script - directs the linker to create a symbol. Note that, regardless - of how a hash table entry is added, all the fields will be - initialized to some sort of null value by the hash table entry - initialization function. - - See <> for an example of how to - check the <> field before saving information (in this - case, the ECOFF external symbol debugging information) in a - hash table entry. - -INODE -Adding symbols from an object file, Adding symbols from an archive, Differing file formats, Adding Symbols to the Hash Table -SUBSUBSECTION - Adding symbols from an object file - - When the <<_bfd_link_add_symbols>> routine is passed an object - file, it must add all externally visible symbols in that - object file to the hash table. The actual work of adding the - symbol to the hash table is normally handled by the function - <<_bfd_generic_link_add_one_symbol>>. The - <<_bfd_link_add_symbols>> routine is responsible for reading - all the symbols from the object file and passing the correct - information to <<_bfd_generic_link_add_one_symbol>>. - - The <<_bfd_link_add_symbols>> routine should not use - <> to read the symbols. The point of - providing this routine is to avoid the overhead of converting - the symbols into generic <> structures. - -@findex _bfd_generic_link_add_one_symbol - <<_bfd_generic_link_add_one_symbol>> handles the details of - combining common symbols, warning about multiple definitions, - and so forth. It takes arguments which describe the symbol to - add, notably symbol flags, a section, and an offset. The - symbol flags include such things as <> or - <>. The section is a section in the object - file, or something like <> for an undefined - symbol or <> for a common symbol. - - If the <<_bfd_final_link>> routine is also going to need to - read the symbol information, the <<_bfd_link_add_symbols>> - routine should save it somewhere attached to the object file - BFD. However, the information should only be saved if the - <> field of the <> argument is true, so - that the <<-no-keep-memory>> linker switch is effective. - - The a.out function which adds symbols from an object file is - <>, and most of the interesting - work is in <>. The latter saves - pointers to the hash tables entries created by - <<_bfd_generic_link_add_one_symbol>> indexed by symbol number, - so that the <<_bfd_final_link>> routine does not have to call - the hash table lookup routine to locate the entry. - -INODE -Adding symbols from an archive, , Adding symbols from an object file, Adding Symbols to the Hash Table -SUBSUBSECTION - Adding symbols from an archive - - When the <<_bfd_link_add_symbols>> routine is passed an - archive, it must look through the symbols defined by the - archive and decide which elements of the archive should be - included in the link. For each such element it must call the - <> linker callback, and it must add the - symbols from the object file to the linker hash table. - -@findex _bfd_generic_link_add_archive_symbols - In most cases the work of looking through the symbols in the - archive should be done by the - <<_bfd_generic_link_add_archive_symbols>> function. This - function builds a hash table from the archive symbol table and - looks through the list of undefined symbols to see which - elements should be included. - <<_bfd_generic_link_add_archive_symbols>> is passed a function - to call to make the final decision about adding an archive - element to the link and to do the actual work of adding the - symbols to the linker hash table. - - The function passed to - <<_bfd_generic_link_add_archive_symbols>> must read the - symbols of the archive element and decide whether the archive - element should be included in the link. If the element is to - be included, the <> linker callback - routine must be called with the element as an argument, and - the elements symbols must be added to the linker hash table - just as though the element had itself been passed to the - <<_bfd_link_add_symbols>> function. - - When the a.out <<_bfd_link_add_symbols>> function receives an - archive, it calls <<_bfd_generic_link_add_archive_symbols>> - passing <> as the function - argument. <> calls - <>. If the latter decides to add - the element (an element is only added if it provides a real, - non-common, definition for a previously undefined or common - symbol) it calls the <> callback and then - <> calls - <> to actually add the symbols to the - linker hash table. - - The ECOFF back end is unusual in that it does not normally - call <<_bfd_generic_link_add_archive_symbols>>, because ECOFF - archives already contain a hash table of symbols. The ECOFF - back end searches the archive itself to avoid the overhead of - creating a new hash table. - -INODE -Performing the Final Link, , Adding Symbols to the Hash Table, Linker Functions -SUBSECTION - Performing the final link - -@cindex _bfd_link_final_link in target vector -@cindex target vector (_bfd_final_link) - When all the input files have been processed, the linker calls - the <<_bfd_final_link>> entry point of the output BFD. This - routine is responsible for producing the final output file, - which has several aspects. It must relocate the contents of - the input sections and copy the data into the output sections. - It must build an output symbol table including any local - symbols from the input files and the global symbols from the - hash table. When producing relocateable output, it must - modify the input relocs and write them into the output file. - There may also be object format dependent work to be done. - - The linker will also call the <> entry - point when the BFD is closed. The two entry points must work - together in order to produce the correct output file. - - The details of how this works are inevitably dependent upon - the specific object file format. The a.out - <<_bfd_final_link>> routine is <>. - -@menu -@* Information provided by the linker:: -@* Relocating the section contents:: -@* Writing the symbol table:: -@end menu - -INODE -Information provided by the linker, Relocating the section contents, Performing the Final Link, Performing the Final Link -SUBSUBSECTION - Information provided by the linker - - Before the linker calls the <<_bfd_final_link>> entry point, - it sets up some data structures for the function to use. - - The <> field of the <> structure - will point to a list of all the input files included in the - link. These files are linked through the <> field - of the <> structure. - - Each section in the output file will have a list of - <> structures attached to the <> - field (the <> structure is defined in - <>). These structures describe how to create the - contents of the output section in terms of the contents of - various input sections, fill constants, and, eventually, other - types of information. They also describe relocs that must be - created by the BFD backend, but do not correspond to any input - file; this is used to support -Ur, which builds constructors - while generating a relocateable object file. - -INODE -Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link -SUBSUBSECTION - Relocating the section contents - - The <<_bfd_final_link>> function should look through the - <> structures attached to each section of the - output file. Each <> structure should either be - handled specially, or it should be passed to the function - <<_bfd_default_link_order>> which will do the right thing - (<<_bfd_default_link_order>> is defined in <>). - - For efficiency, a <> of type - <> whose associated section belongs - to a BFD of the same format as the output BFD must be handled - specially. This type of <> describes part of an - output section in terms of a section belonging to one of the - input files. The <<_bfd_final_link>> function should read the - contents of the section and any associated relocs, apply the - relocs to the section contents, and write out the modified - section contents. If performing a relocateable link, the - relocs themselves must also be modified and written out. - -@findex _bfd_relocate_contents -@findex _bfd_final_link_relocate - The functions <<_bfd_relocate_contents>> and - <<_bfd_final_link_relocate>> provide some general support for - performing the actual relocations, notably overflow checking. - Their arguments include information about the symbol the - relocation is against and a <> argument - which describes the relocation to perform. These functions - are defined in <>. - - The a.out function which handles reading, relocating, and - writing section contents is <>. The - actual relocation is done in <> - and <>. - -INODE -Writing the symbol table, , Relocating the section contents, Performing the Final Link -SUBSUBSECTION - Writing the symbol table - - The <<_bfd_final_link>> function must gather all the symbols - in the input files and write them out. It must also write out - all the symbols in the global hash table. This must be - controlled by the <> and <> fields of the - <> structure. - - The local symbols of the input files will not have been - entered into the linker hash table. The <<_bfd_final_link>> - routine must consider each input file and include the symbols - in the output file. It may be convenient to do this when - looking through the <> structures, or it may be - done by stepping through the <> list. - - The <<_bfd_final_link>> routine must also traverse the global - hash table to gather all the externally visible symbols. It - is possible that most of the externally visible symbols may be - written out when considering the symbols of each input file, - but it is still necessary to traverse the hash table since the - linker script may have defined some symbols that are not in - any of the input files. - - The <> field of the <> structure - controls which symbols are written out. The possible values - are listed in <>. If the value is <>, - then the <> field of the <> - structure is a hash table of symbols to keep; each symbol - should be looked up in this hash table, and only symbols which - are present should be included in the output file. - - If the <> field of the <> structure - permits local symbols to be written out, the <> field - is used to further controls which local symbols are included - in the output file. If the value is <>, then all - local symbols which begin with a certain prefix are discarded; - this prefix is described by the <> and - <> fields of the <> structure. - - The a.out backend handles symbols by calling - <> on each input BFD and then - traversing the global hash table with the function - <>. It builds a string table - while writing out the symbols, which is written to the output - file at the end of <>. -*/ - -static struct bfd_hash_entry *generic_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); -static boolean generic_link_read_symbols - PARAMS ((bfd *)); -static boolean generic_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean collect)); -static boolean generic_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean collect)); -static boolean generic_link_check_archive_element_no_collect - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean generic_link_check_archive_element_collect - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean generic_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded, boolean collect)); -static boolean generic_link_add_symbol_list - PARAMS ((bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **, - boolean collect)); -static bfd *hash_entry_bfd PARAMS ((struct bfd_link_hash_entry *)); -static void set_symbol_from_hash - PARAMS ((asymbol *, struct bfd_link_hash_entry *)); -static boolean generic_add_output_symbol - PARAMS ((bfd *, size_t *psymalloc, asymbol *)); -static boolean default_fill_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); -static boolean default_indirect_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *, boolean)); - -/* The link hash table structure is defined in bfdlink.h. It provides - a base hash table which the backend specific hash tables are built - upon. */ - -/* Routine to create an entry in the link hash table. */ - -struct bfd_hash_entry * -_bfd_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct bfd_link_hash_entry *ret = (struct bfd_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct bfd_link_hash_entry *) NULL) - ret = ((struct bfd_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry))); - if (ret == (struct bfd_link_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct bfd_link_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->type = bfd_link_hash_new; - ret->next = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a link hash table. The BFD argument is the one - responsible for creating this table. */ - -boolean -_bfd_link_hash_table_init (table, abfd, newfunc) - struct bfd_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - table->creator = abfd->xvec; - table->undefs = NULL; - table->undefs_tail = NULL; - return bfd_hash_table_init (&table->table, newfunc); -} - -/* Look up a symbol in a link hash table. If follow is true, we - follow bfd_link_hash_indirect and bfd_link_hash_warning links to - the real symbol. */ - -struct bfd_link_hash_entry * -bfd_link_hash_lookup (table, string, create, copy, follow) - struct bfd_link_hash_table *table; - const char *string; - boolean create; - boolean copy; - boolean follow; -{ - struct bfd_link_hash_entry *ret; - - ret = ((struct bfd_link_hash_entry *) - bfd_hash_lookup (&table->table, string, create, copy)); - - if (follow && ret != (struct bfd_link_hash_entry *) NULL) - { - while (ret->type == bfd_link_hash_indirect - || ret->type == bfd_link_hash_warning) - ret = ret->u.i.link; - } - - return ret; -} - -/* Look up a symbol in the main linker hash table if the symbol might - be wrapped. This should only be used for references to an - undefined symbol, not for definitions of a symbol. */ - -struct bfd_link_hash_entry * -bfd_wrapped_link_hash_lookup (abfd, info, string, create, copy, follow) - bfd *abfd; - struct bfd_link_info *info; - const char *string; - boolean create; - boolean copy; - boolean follow; -{ - if (info->wrap_hash != NULL) - { - const char *l; - - l = string; - if (*l == bfd_get_symbol_leading_char (abfd)) - ++l; - -#undef WRAP -#define WRAP "__wrap_" - - if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL) - { - char *n; - struct bfd_link_hash_entry *h; - - /* This symbol is being wrapped. We want to replace all - references to SYM with references to __wrap_SYM. */ - - n = (char *) bfd_malloc (strlen (l) + sizeof WRAP + 1); - if (n == NULL) - return NULL; - - /* Note that symbol_leading_char may be '\0'. */ - n[0] = bfd_get_symbol_leading_char (abfd); - n[1] = '\0'; - strcat (n, WRAP); - strcat (n, l); - h = bfd_link_hash_lookup (info->hash, n, create, true, follow); - free (n); - return h; - } - -#undef WRAP - -#undef REAL -#define REAL "__real_" - - if (*l == '_' - && strncmp (l, REAL, sizeof REAL - 1) == 0 - && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1, - false, false) != NULL) - { - char *n; - struct bfd_link_hash_entry *h; - - /* This is a reference to __real_SYM, where SYM is being - wrapped. We want to replace all references to __real_SYM - with references to SYM. */ - - n = (char *) bfd_malloc (strlen (l + sizeof REAL - 1) + 2); - if (n == NULL) - return NULL; - - /* Note that symbol_leading_char may be '\0'. */ - n[0] = bfd_get_symbol_leading_char (abfd); - n[1] = '\0'; - strcat (n, l + sizeof REAL - 1); - h = bfd_link_hash_lookup (info->hash, n, create, true, follow); - free (n); - return h; - } - -#undef REAL - } - - return bfd_link_hash_lookup (info->hash, string, create, copy, follow); -} - -/* Traverse a generic link hash table. The only reason this is not a - macro is to do better type checking. This code presumes that an - argument passed as a struct bfd_hash_entry * may be caught as a - struct bfd_link_hash_entry * with no explicit cast required on the - call. */ - -void -bfd_link_hash_traverse (table, func, info) - struct bfd_link_hash_table *table; - boolean (*func) PARAMS ((struct bfd_link_hash_entry *, PTR)); - PTR info; -{ - bfd_hash_traverse (&table->table, - ((boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) - func), - info); -} - -/* Add a symbol to the linker hash table undefs list. */ - -INLINE void -bfd_link_add_undef (table, h) - struct bfd_link_hash_table *table; - struct bfd_link_hash_entry *h; -{ - BFD_ASSERT (h->next == NULL); - if (table->undefs_tail != (struct bfd_link_hash_entry *) NULL) - table->undefs_tail->next = h; - if (table->undefs == (struct bfd_link_hash_entry *) NULL) - table->undefs = h; - table->undefs_tail = h; -} - -/* Routine to create an entry in an generic link hash table. */ - -static struct bfd_hash_entry * -generic_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct generic_link_hash_entry *ret = - (struct generic_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct generic_link_hash_entry *) NULL) - ret = ((struct generic_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry))); - if (ret == (struct generic_link_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct generic_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - - if (ret) - { - /* Set local fields. */ - ret->written = false; - ret->sym = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create an generic link hash table. */ - -struct bfd_link_hash_table * -_bfd_generic_link_hash_table_create (abfd) - bfd *abfd; -{ - struct generic_link_hash_table *ret; - - ret = ((struct generic_link_hash_table *) - bfd_alloc (abfd, sizeof (struct generic_link_hash_table))); - if (ret == NULL) - return (struct bfd_link_hash_table *) NULL; - if (! _bfd_link_hash_table_init (&ret->root, abfd, - generic_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Grab the symbols for an object file when doing a generic link. We - store the symbols in the outsymbols field. We need to keep them - around for the entire link to ensure that we only read them once. - If we read them multiple times, we might wind up with relocs and - the hash table pointing to different instances of the symbol - structure. */ - -static boolean -generic_link_read_symbols (abfd) - bfd *abfd; -{ - if (abfd->outsymbols == (asymbol **) NULL) - { - long symsize; - long symcount; - - symsize = bfd_get_symtab_upper_bound (abfd); - if (symsize < 0) - return false; - abfd->outsymbols = (asymbol **) bfd_alloc (abfd, symsize); - if (abfd->outsymbols == NULL && symsize != 0) - return false; - symcount = bfd_canonicalize_symtab (abfd, abfd->outsymbols); - if (symcount < 0) - return false; - abfd->symcount = symcount; - } - - return true; -} - -/* Generic function to add symbols to from an object file to the - global hash table. This version does not automatically collect - constructors by name. */ - -boolean -_bfd_generic_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - return generic_link_add_symbols (abfd, info, false); -} - -/* Generic function to add symbols from an object file to the global - hash table. This version automatically collects constructors by - name, as the collect2 program does. It should be used for any - target which does not provide some other mechanism for setting up - constructors and destructors; these are approximately those targets - for which gcc uses collect2 and do not support stabs. */ - -boolean -_bfd_generic_link_add_symbols_collect (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - return generic_link_add_symbols (abfd, info, true); -} - -/* Add symbols from an object file to the global hash table. */ - -static boolean -generic_link_add_symbols (abfd, info, collect) - bfd *abfd; - struct bfd_link_info *info; - boolean collect; -{ - boolean ret; - - switch (bfd_get_format (abfd)) - { - case bfd_object: - ret = generic_link_add_object_symbols (abfd, info, collect); - break; - case bfd_archive: - ret = (_bfd_generic_link_add_archive_symbols - (abfd, info, - (collect - ? generic_link_check_archive_element_collect - : generic_link_check_archive_element_no_collect))); - break; - default: - bfd_set_error (bfd_error_wrong_format); - ret = false; - } - - return ret; -} - -/* Add symbols from an object file to the global hash table. */ - -static boolean -generic_link_add_object_symbols (abfd, info, collect) - bfd *abfd; - struct bfd_link_info *info; - boolean collect; -{ - if (! generic_link_read_symbols (abfd)) - return false; - return generic_link_add_symbol_list (abfd, info, - _bfd_generic_link_get_symcount (abfd), - _bfd_generic_link_get_symbols (abfd), - collect); -} - -/* We build a hash table of all symbols defined in an archive. */ - -/* An archive symbol may be defined by multiple archive elements. - This linked list is used to hold the elements. */ - -struct archive_list -{ - struct archive_list *next; - int indx; -}; - -/* An entry in an archive hash table. */ - -struct archive_hash_entry -{ - struct bfd_hash_entry root; - /* Where the symbol is defined. */ - struct archive_list *defs; -}; - -/* An archive hash table itself. */ - -struct archive_hash_table -{ - struct bfd_hash_table table; -}; - -static struct bfd_hash_entry *archive_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static boolean archive_hash_table_init - PARAMS ((struct archive_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Create a new entry for an archive hash table. */ - -static struct bfd_hash_entry * -archive_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct archive_hash_entry *ret = (struct archive_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct archive_hash_entry *) NULL) - ret = ((struct archive_hash_entry *) - bfd_hash_allocate (table, sizeof (struct archive_hash_entry))); - if (ret == (struct archive_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct archive_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->defs = (struct archive_list *) NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize an archive hash table. */ - -static boolean -archive_hash_table_init (table, newfunc) - struct archive_hash_table *table; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return bfd_hash_table_init (&table->table, newfunc); -} - -/* Look up an entry in an archive hash table. */ - -#define archive_hash_lookup(t, string, create, copy) \ - ((struct archive_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* Allocate space in an archive hash table. */ - -#define archive_hash_allocate(t, size) bfd_hash_allocate (&(t)->table, (size)) - -/* Free an archive hash table. */ - -#define archive_hash_table_free(t) bfd_hash_table_free (&(t)->table) - -/* Generic function to add symbols from an archive file to the global - hash file. This function presumes that the archive symbol table - has already been read in (this is normally done by the - bfd_check_format entry point). It looks through the undefined and - common symbols and searches the archive symbol table for them. If - it finds an entry, it includes the associated object file in the - link. - - The old linker looked through the archive symbol table for - undefined symbols. We do it the other way around, looking through - undefined symbols for symbols defined in the archive. The - advantage of the newer scheme is that we only have to look through - the list of undefined symbols once, whereas the old method had to - re-search the symbol table each time a new object file was added. - - The CHECKFN argument is used to see if an object file should be - included. CHECKFN should set *PNEEDED to true if the object file - should be included, and must also call the bfd_link_info - add_archive_element callback function and handle adding the symbols - to the global hash table. CHECKFN should only return false if some - sort of error occurs. - - For some formats, such as a.out, it is possible to look through an - object file but not actually include it in the link. The - archive_pass field in a BFD is used to avoid checking the symbols - of an object files too many times. When an object is included in - the link, archive_pass is set to -1. If an object is scanned but - not included, archive_pass is set to the pass number. The pass - number is incremented each time a new object file is included. The - pass number is used because when a new object file is included it - may create new undefined symbols which cause a previously examined - object file to be included. */ - -boolean -_bfd_generic_link_add_archive_symbols (abfd, info, checkfn) - bfd *abfd; - struct bfd_link_info *info; - boolean (*checkfn) PARAMS ((bfd *, struct bfd_link_info *, - boolean *pneeded)); -{ - carsym *arsyms; - carsym *arsym_end; - register carsym *arsym; - int pass; - struct archive_hash_table arsym_hash; - int indx; - struct bfd_link_hash_entry **pundef; - - if (! bfd_has_map (abfd)) - { - /* An empty archive is a special case. */ - if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL) - return true; - bfd_set_error (bfd_error_no_armap); - return false; - } - - arsyms = bfd_ardata (abfd)->symdefs; - arsym_end = arsyms + bfd_ardata (abfd)->symdef_count; - - /* In order to quickly determine whether an symbol is defined in - this archive, we build a hash table of the symbols. */ - if (! archive_hash_table_init (&arsym_hash, archive_hash_newfunc)) - return false; - for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++) - { - struct archive_hash_entry *arh; - struct archive_list *l, **pp; - - arh = archive_hash_lookup (&arsym_hash, arsym->name, true, false); - if (arh == (struct archive_hash_entry *) NULL) - goto error_return; - l = ((struct archive_list *) - archive_hash_allocate (&arsym_hash, sizeof (struct archive_list))); - if (l == NULL) - goto error_return; - l->indx = indx; - for (pp = &arh->defs; - *pp != (struct archive_list *) NULL; - pp = &(*pp)->next) - ; - *pp = l; - l->next = NULL; - } - - /* The archive_pass field in the archive itself is used to - initialize PASS, sine we may search the same archive multiple - times. */ - pass = abfd->archive_pass + 1; - - /* New undefined symbols are added to the end of the list, so we - only need to look through it once. */ - pundef = &info->hash->undefs; - while (*pundef != (struct bfd_link_hash_entry *) NULL) - { - struct bfd_link_hash_entry *h; - struct archive_hash_entry *arh; - struct archive_list *l; - - h = *pundef; - - /* When a symbol is defined, it is not necessarily removed from - the list. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - { - /* Remove this entry from the list, for general cleanliness - and because we are going to look through the list again - if we search any more libraries. We can't remove the - entry if it is the tail, because that would lose any - entries we add to the list later on (it would also cause - us to lose track of whether the symbol has been - referenced). */ - if (*pundef != info->hash->undefs_tail) - *pundef = (*pundef)->next; - else - pundef = &(*pundef)->next; - continue; - } - - /* Look for this symbol in the archive symbol map. */ - arh = archive_hash_lookup (&arsym_hash, h->root.string, false, false); - if (arh == (struct archive_hash_entry *) NULL) - { - pundef = &(*pundef)->next; - continue; - } - - /* Look at all the objects which define this symbol. */ - for (l = arh->defs; l != (struct archive_list *) NULL; l = l->next) - { - bfd *element; - boolean needed; - - /* If the symbol has gotten defined along the way, quit. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - break; - - element = bfd_get_elt_at_index (abfd, l->indx); - if (element == (bfd *) NULL) - goto error_return; - - /* If we've already included this element, or if we've - already checked it on this pass, continue. */ - if (element->archive_pass == -1 - || element->archive_pass == pass) - continue; - - /* If we can't figure this element out, just ignore it. */ - if (! bfd_check_format (element, bfd_object)) - { - element->archive_pass = -1; - continue; - } - - /* CHECKFN will see if this element should be included, and - go ahead and include it if appropriate. */ - if (! (*checkfn) (element, info, &needed)) - goto error_return; - - if (! needed) - element->archive_pass = pass; - else - { - element->archive_pass = -1; - - /* Increment the pass count to show that we may need to - recheck object files which were already checked. */ - ++pass; - } - } - - pundef = &(*pundef)->next; - } - - archive_hash_table_free (&arsym_hash); - - /* Save PASS in case we are called again. */ - abfd->archive_pass = pass; - - return true; - - error_return: - archive_hash_table_free (&arsym_hash); - return false; -} - -/* See if we should include an archive element. This version is used - when we do not want to automatically collect constructors based on - the symbol name, presumably because we have some other mechanism - for finding them. */ - -static boolean -generic_link_check_archive_element_no_collect (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - return generic_link_check_archive_element (abfd, info, pneeded, false); -} - -/* See if we should include an archive element. This version is used - when we want to automatically collect constructors based on the - symbol name, as collect2 does. */ - -static boolean -generic_link_check_archive_element_collect (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - return generic_link_check_archive_element (abfd, info, pneeded, true); -} - -/* See if we should include an archive element. Optionally collect - constructors. */ - -static boolean -generic_link_check_archive_element (abfd, info, pneeded, collect) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; - boolean collect; -{ - asymbol **pp, **ppend; - - *pneeded = false; - - if (! generic_link_read_symbols (abfd)) - return false; - - pp = _bfd_generic_link_get_symbols (abfd); - ppend = pp + _bfd_generic_link_get_symcount (abfd); - for (; pp < ppend; pp++) - { - asymbol *p; - struct bfd_link_hash_entry *h; - - p = *pp; - - /* We are only interested in globally visible symbols. */ - if (! bfd_is_com_section (p->section) - && (p->flags & (BSF_GLOBAL | BSF_INDIRECT | BSF_WEAK)) == 0) - continue; - - /* We are only interested if we know something about this - symbol, and it is undefined or common. An undefined weak - symbol (type bfd_link_hash_undefweak) is not considered to be - a reference when pulling files out of an archive. See the - SVR4 ABI, p. 4-27. */ - h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false, - false, true); - if (h == (struct bfd_link_hash_entry *) NULL - || (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common)) - continue; - - /* P is a symbol we are looking for. */ - - if (! bfd_is_com_section (p->section)) - { - bfd_size_type symcount; - asymbol **symbols; - - /* This object file defines this symbol, so pull it in. */ - if (! (*info->callbacks->add_archive_element) (info, abfd, - bfd_asymbol_name (p))) - return false; - symcount = _bfd_generic_link_get_symcount (abfd); - symbols = _bfd_generic_link_get_symbols (abfd); - if (! generic_link_add_symbol_list (abfd, info, symcount, - symbols, collect)) - return false; - *pneeded = true; - return true; - } - - /* P is a common symbol. */ - - if (h->type == bfd_link_hash_undefined) - { - bfd *symbfd; - bfd_vma size; - unsigned int power; - - symbfd = h->u.undef.abfd; - if (symbfd == (bfd *) NULL) - { - /* This symbol was created as undefined from outside - BFD. We assume that we should link in the object - file. This is for the -u option in the linker. */ - if (! (*info->callbacks->add_archive_element) - (info, abfd, bfd_asymbol_name (p))) - return false; - *pneeded = true; - return true; - } - - /* Turn the symbol into a common symbol but do not link in - the object file. This is how a.out works. Object - formats that require different semantics must implement - this function differently. This symbol is already on the - undefs list. We add the section to a common section - attached to symbfd to ensure that it is in a BFD which - will be linked in. */ - h->type = bfd_link_hash_common; - h->u.c.p = - ((struct bfd_link_hash_common_entry *) - bfd_hash_allocate (&info->hash->table, - sizeof (struct bfd_link_hash_common_entry))); - if (h->u.c.p == NULL) - return false; - - size = bfd_asymbol_value (p); - h->u.c.size = size; - - power = bfd_log2 (size); - if (power > 4) - power = 4; - h->u.c.p->alignment_power = power; - - if (p->section == bfd_com_section_ptr) - h->u.c.p->section = bfd_make_section_old_way (symbfd, "COMMON"); - else - h->u.c.p->section = bfd_make_section_old_way (symbfd, - p->section->name); - h->u.c.p->section->flags = SEC_ALLOC; - } - else - { - /* Adjust the size of the common symbol if necessary. This - is how a.out works. Object formats that require - different semantics must implement this function - differently. */ - if (bfd_asymbol_value (p) > h->u.c.size) - h->u.c.size = bfd_asymbol_value (p); - } - } - - /* This archive element is not needed. */ - return true; -} - -/* Add the symbols from an object file to the global hash table. ABFD - is the object file. INFO is the linker information. SYMBOL_COUNT - is the number of symbols. SYMBOLS is the list of symbols. COLLECT - is true if constructors should be automatically collected by name - as is done by collect2. */ - -static boolean -generic_link_add_symbol_list (abfd, info, symbol_count, symbols, collect) - bfd *abfd; - struct bfd_link_info *info; - bfd_size_type symbol_count; - asymbol **symbols; - boolean collect; -{ - asymbol **pp, **ppend; - - pp = symbols; - ppend = symbols + symbol_count; - for (; pp < ppend; pp++) - { - asymbol *p; - - p = *pp; - - if ((p->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (p)) - || bfd_is_com_section (bfd_get_section (p)) - || bfd_is_ind_section (bfd_get_section (p))) - { - const char *name; - const char *string; - struct generic_link_hash_entry *h; - - name = bfd_asymbol_name (p); - if (((p->flags & BSF_INDIRECT) != 0 - || bfd_is_ind_section (p->section)) - && pp + 1 < ppend) - { - pp++; - string = bfd_asymbol_name (*pp); - } - else if ((p->flags & BSF_WARNING) != 0 - && pp + 1 < ppend) - { - /* The name of P is actually the warning string, and the - next symbol is the one to warn about. */ - string = name; - pp++; - name = bfd_asymbol_name (*pp); - } - else - string = NULL; - - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, p->flags, bfd_get_section (p), - p->value, string, false, collect, - (struct bfd_link_hash_entry **) &h))) - return false; - - /* If this is a constructor symbol, and the linker didn't do - anything with it, then we want to just pass the symbol - through to the output file. This will happen when - linking with -r. */ - if ((p->flags & BSF_CONSTRUCTOR) != 0 - && (h == NULL || h->root.type == bfd_link_hash_new)) - { - p->udata.p = NULL; - continue; - } - - /* Save the BFD symbol so that we don't lose any backend - specific information that may be attached to it. We only - want this one if it gives more information than the - existing one; we don't want to replace a defined symbol - with an undefined one. This routine may be called with a - hash table other than the generic hash table, so we only - do this if we are certain that the hash table is a - generic one. */ - if (info->hash->creator == abfd->xvec) - { - if (h->sym == (asymbol *) NULL - || (! bfd_is_und_section (bfd_get_section (p)) - && (! bfd_is_com_section (bfd_get_section (p)) - || bfd_is_und_section (bfd_get_section (h->sym))))) - { - h->sym = p; - /* BSF_OLD_COMMON is a hack to support COFF reloc - reading, and it should go away when the COFF - linker is switched to the new version. */ - if (bfd_is_com_section (bfd_get_section (p))) - p->flags |= BSF_OLD_COMMON; - } - - /* Store a back pointer from the symbol to the hash - table entry for the benefit of relaxation code until - it gets rewritten to not use asymbol structures. - Setting this is also used to check whether these - symbols were set up by the generic linker. */ - p->udata.p = (PTR) h; - } - } - } - - return true; -} - -/* We use a state table to deal with adding symbols from an object - file. The first index into the state table describes the symbol - from the object file. The second index into the state table is the - type of the symbol in the hash table. */ - -/* The symbol from the object file is turned into one of these row - values. */ - -enum link_row -{ - UNDEF_ROW, /* Undefined. */ - UNDEFW_ROW, /* Weak undefined. */ - DEF_ROW, /* Defined. */ - DEFW_ROW, /* Weak defined. */ - COMMON_ROW, /* Common. */ - INDR_ROW, /* Indirect. */ - WARN_ROW, /* Warning. */ - SET_ROW /* Member of set. */ -}; - -/* apparently needed for Hitachi 3050R(HI-UX/WE2)? */ -#undef FAIL - -/* The actions to take in the state table. */ - -enum link_action -{ - FAIL, /* Abort. */ - UND, /* Mark symbol undefined. */ - WEAK, /* Mark symbol weak undefined. */ - DEF, /* Mark symbol defined. */ - DEFW, /* Mark symbol weak defined. */ - COM, /* Mark symbol common. */ - REF, /* Mark defined symbol referenced. */ - CREF, /* Possibly warn about common reference to defined symbol. */ - CDEF, /* Define existing common symbol. */ - NOACT, /* No action. */ - BIG, /* Mark symbol common using largest size. */ - MDEF, /* Multiple definition error. */ - MIND, /* Multiple indirect symbols. */ - IND, /* Make indirect symbol. */ - CIND, /* Make indirect symbol from existing common symbol. */ - SET, /* Add value to set. */ - MWARN, /* Make warning symbol. */ - WARN, /* Issue warning. */ - CWARN, /* Warn if referenced, else MWARN. */ - CYCLE, /* Repeat with symbol pointed to. */ - REFC, /* Mark indirect symbol referenced and then CYCLE. */ - WARNC /* Issue warning and then CYCLE. */ -}; - -/* The state table itself. The first index is a link_row and the - second index is a bfd_link_hash_type. */ - -static const enum link_action link_action[8][8] = -{ - /* current\prev new undef undefw def defw com indr warn */ - /* UNDEF_ROW */ {UND, NOACT, UND, REF, REF, NOACT, REFC, WARNC }, - /* UNDEFW_ROW */ {WEAK, NOACT, NOACT, REF, REF, NOACT, REFC, WARNC }, - /* DEF_ROW */ {DEF, DEF, DEF, MDEF, DEF, CDEF, MDEF, CYCLE }, - /* DEFW_ROW */ {DEFW, DEFW, DEFW, NOACT, NOACT, NOACT, NOACT, CYCLE }, - /* COMMON_ROW */ {COM, COM, COM, CREF, CREF, BIG, CREF, WARNC }, - /* INDR_ROW */ {IND, IND, IND, MDEF, IND, CIND, MIND, CYCLE }, - /* WARN_ROW */ {MWARN, WARN, WARN, CWARN, CWARN, WARN, CWARN, CYCLE }, - /* SET_ROW */ {SET, SET, SET, SET, SET, SET, CYCLE, CYCLE } -}; - -/* Most of the entries in the LINK_ACTION table are straightforward, - but a few are somewhat subtle. - - A reference to an indirect symbol (UNDEF_ROW/indr or - UNDEFW_ROW/indr) is counted as a reference both to the indirect - symbol and to the symbol the indirect symbol points to. - - A reference to a warning symbol (UNDEF_ROW/warn or UNDEFW_ROW/warn) - causes the warning to be issued. - - A common definition of an indirect symbol (COMMON_ROW/indr) is - treated as a multiple definition error. Likewise for an indirect - definition of a common symbol (INDR_ROW/com). - - An indirect definition of a warning (INDR_ROW/warn) does not cause - the warning to be issued. - - If a warning is created for an indirect symbol (WARN_ROW/indr) no - warning is created for the symbol the indirect symbol points to. - - Adding an entry to a set does not count as a reference to a set, - and no warning is issued (SET_ROW/warn). */ - -/* Return the BFD in which a hash entry has been defined, if known. */ - -static bfd * -hash_entry_bfd (h) - struct bfd_link_hash_entry *h; -{ - while (h->type == bfd_link_hash_warning) - h = h->u.i.link; - switch (h->type) - { - default: - return NULL; - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - return h->u.undef.abfd; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - return h->u.def.section->owner; - case bfd_link_hash_common: - return h->u.c.p->section->owner; - } - /*NOTREACHED*/ -} - -/* Add a symbol to the global hash table. - ABFD is the BFD the symbol comes from. - NAME is the name of the symbol. - FLAGS is the BSF_* bits associated with the symbol. - SECTION is the section in which the symbol is defined; this may be - bfd_und_section_ptr or bfd_com_section_ptr. - VALUE is the value of the symbol, relative to the section. - STRING is used for either an indirect symbol, in which case it is - the name of the symbol to indirect to, or a warning symbol, in - which case it is the warning string. - COPY is true if NAME or STRING must be copied into locally - allocated memory if they need to be saved. - COLLECT is true if we should automatically collect gcc constructor - or destructor names as collect2 does. - HASHP, if not NULL, is a place to store the created hash table - entry; if *HASHP is not NULL, the caller has already looked up - the hash table entry, and stored it in *HASHP. */ - -boolean -_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, - string, copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - enum link_row row; - struct bfd_link_hash_entry *h; - boolean cycle; - - if (bfd_is_ind_section (section) - || (flags & BSF_INDIRECT) != 0) - row = INDR_ROW; - else if ((flags & BSF_WARNING) != 0) - row = WARN_ROW; - else if ((flags & BSF_CONSTRUCTOR) != 0) - row = SET_ROW; - else if (bfd_is_und_section (section)) - { - if ((flags & BSF_WEAK) != 0) - row = UNDEFW_ROW; - else - row = UNDEF_ROW; - } - else if ((flags & BSF_WEAK) != 0) - row = DEFW_ROW; - else if (bfd_is_com_section (section)) - row = COMMON_ROW; - else - row = DEF_ROW; - - if (hashp != NULL && *hashp != NULL) - h = *hashp; - else - { - if (row == UNDEF_ROW || row == UNDEFW_ROW) - h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false); - else - h = bfd_link_hash_lookup (info->hash, name, true, copy, false); - if (h == NULL) - { - if (hashp != NULL) - *hashp = NULL; - return false; - } - } - - if (info->notice_hash != (struct bfd_hash_table *) NULL - && (bfd_hash_lookup (info->notice_hash, name, false, false) - != (struct bfd_hash_entry *) NULL)) - { - if (! (*info->callbacks->notice) (info, name, abfd, section, value)) - return false; - } - - if (hashp != (struct bfd_link_hash_entry **) NULL) - *hashp = h; - - do - { - enum link_action action; - - cycle = false; - action = link_action[(int) row][(int) h->type]; - switch (action) - { - case FAIL: - abort (); - - case NOACT: - /* Do nothing. */ - break; - - case UND: - /* Make a new undefined symbol. */ - h->type = bfd_link_hash_undefined; - h->u.undef.abfd = abfd; - bfd_link_add_undef (info->hash, h); - break; - - case WEAK: - /* Make a new weak undefined symbol. */ - h->type = bfd_link_hash_undefweak; - h->u.undef.abfd = abfd; - break; - - case CDEF: - /* We have found a definition for a symbol which was - previously common. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, name, - h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_defined, (bfd_vma) 0))) - return false; - /* Fall through. */ - case DEF: - case DEFW: - { - enum bfd_link_hash_type oldtype; - - /* Define a symbol. */ - oldtype = h->type; - if (action == DEFW) - h->type = bfd_link_hash_defweak; - else - h->type = bfd_link_hash_defined; - h->u.def.section = section; - h->u.def.value = value; - - /* If we have been asked to, we act like collect2 and - identify all functions that might be global - constructors and destructors and pass them up in a - callback. We only do this for certain object file - types, since many object file types can handle this - automatically. */ - if (collect && name[0] == '_') - { - const char *s; - - /* A constructor or destructor name starts like this: - _+GLOBAL_[_.$][ID][_.$] where the first [_.$] and - the second are the same character (we accept any - character there, in case a new object file format - comes along with even worse naming restrictions). */ - -#define CONS_PREFIX "GLOBAL_" -#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1) - - s = name + 1; - while (*s == '_') - ++s; - if (s[0] == 'G' - && strncmp (s, CONS_PREFIX, CONS_PREFIX_LEN - 1) == 0) - { - char c; - - c = s[CONS_PREFIX_LEN + 1]; - if ((c == 'I' || c == 'D') - && s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2]) - { - /* If this is a definition of a symbol which - was previously weakly defined, we are in - trouble. We have already added a - constructor entry for the weak defined - symbol, and now we are trying to add one - for the new symbol. Fortunately, this case - should never arise in practice. */ - if (oldtype == bfd_link_hash_defweak) - abort (); - - if (! ((*info->callbacks->constructor) - (info, - c == 'I' ? true : false, - name, abfd, section, value))) - return false; - } - } - } - } - - break; - - case COM: - /* We have found a common definition for a symbol. */ - if (h->type == bfd_link_hash_new) - bfd_link_add_undef (info->hash, h); - h->type = bfd_link_hash_common; - h->u.c.p = - ((struct bfd_link_hash_common_entry *) - bfd_hash_allocate (&info->hash->table, - sizeof (struct bfd_link_hash_common_entry))); - if (h->u.c.p == NULL) - return false; - - h->u.c.size = value; - - /* Select a default alignment based on the size. This may - be overridden by the caller. */ - { - unsigned int power; - - power = bfd_log2 (value); - if (power > 4) - power = 4; - h->u.c.p->alignment_power = power; - } - - /* The section of a common symbol is only used if the common - symbol is actually allocated. It basically provides a - hook for the linker script to decide which output section - the common symbols should be put in. In most cases, the - section of a common symbol will be bfd_com_section_ptr, - the code here will choose a common symbol section named - "COMMON", and the linker script will contain *(COMMON) in - the appropriate place. A few targets use separate common - sections for small symbols, and they require special - handling. */ - if (section == bfd_com_section_ptr) - { - h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON"); - h->u.c.p->section->flags = SEC_ALLOC; - } - else if (section->owner != abfd) - { - h->u.c.p->section = bfd_make_section_old_way (abfd, - section->name); - h->u.c.p->section->flags = SEC_ALLOC; - } - else - h->u.c.p->section = section; - break; - - case REF: - /* A reference to a defined symbol. */ - if (h->next == NULL && info->hash->undefs_tail != h) - h->next = h; - break; - - case BIG: - /* We have found a common definition for a symbol which - already had a common definition. Use the maximum of the - two sizes. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, name, - h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_common, value))) - return false; - if (value > h->u.c.size) - { - unsigned int power; - - h->u.c.size = value; - - /* Select a default alignment based on the size. This may - be overridden by the caller. */ - power = bfd_log2 (value); - if (power > 4) - power = 4; - h->u.c.p->alignment_power = power; - } - break; - - case CREF: - { - bfd *obfd; - - /* We have found a common definition for a symbol which - was already defined. FIXME: It would nice if we could - report the BFD which defined an indirect symbol, but we - don't have anywhere to store the information. */ - if (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak) - obfd = h->u.def.section->owner; - else - obfd = NULL; - if (! ((*info->callbacks->multiple_common) - (info, name, obfd, h->type, (bfd_vma) 0, - abfd, bfd_link_hash_common, value))) - return false; - } - break; - - case MIND: - /* Multiple indirect symbols. This is OK if they both point - to the same symbol. */ - if (strcmp (h->u.i.link->root.string, string) == 0) - break; - /* Fall through. */ - case MDEF: - /* Handle a multiple definition. */ - { - asection *msec; - bfd_vma mval; - - switch (h->type) - { - case bfd_link_hash_defined: - msec = h->u.def.section; - mval = h->u.def.value; - break; - case bfd_link_hash_indirect: - msec = bfd_ind_section_ptr; - mval = 0; - break; - default: - abort (); - } - - /* Ignore a redefinition of an absolute symbol to the same - value; it's harmless. */ - if (h->type == bfd_link_hash_defined - && bfd_is_abs_section (msec) - && bfd_is_abs_section (section) - && value == mval) - break; - - if (! ((*info->callbacks->multiple_definition) - (info, name, msec->owner, msec, mval, abfd, section, - value))) - return false; - } - break; - - case CIND: - /* Create an indirect symbol from an existing common symbol. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, name, - h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_indirect, (bfd_vma) 0))) - return false; - /* Fall through. */ - case IND: - /* Create an indirect symbol. */ - { - struct bfd_link_hash_entry *inh; - - /* STRING is the name of the symbol we want to indirect - to. */ - inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true, - copy, false); - if (inh == (struct bfd_link_hash_entry *) NULL) - return false; - if (inh->type == bfd_link_hash_new) - { - inh->type = bfd_link_hash_undefined; - inh->u.undef.abfd = abfd; - bfd_link_add_undef (info->hash, inh); - } - - /* If the indirect symbol has been referenced, we need to - push the reference down to the symbol we are - referencing. */ - if (h->type != bfd_link_hash_new) - { - row = UNDEF_ROW; - cycle = true; - } - - h->type = bfd_link_hash_indirect; - h->u.i.link = inh; - } - break; - - case SET: - /* Add an entry to a set. */ - if (! (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR, - abfd, section, value)) - return false; - break; - - case WARNC: - /* Issue a warning and cycle. */ - if (h->u.i.warning != NULL) - { - if (! (*info->callbacks->warning) (info, h->u.i.warning, name, - abfd, (asection *) NULL, - (bfd_vma) 0)) - return false; - /* Only issue a warning once. */ - h->u.i.warning = NULL; - } - /* Fall through. */ - case CYCLE: - /* Try again with the referenced symbol. */ - h = h->u.i.link; - cycle = true; - break; - - case REFC: - /* A reference to an indirect symbol. */ - if (h->next == NULL && info->hash->undefs_tail != h) - h->next = h; - h = h->u.i.link; - cycle = true; - break; - - case WARN: - /* Issue a warning. */ - if (! (*info->callbacks->warning) (info, string, name, - hash_entry_bfd (h), - (asection *) NULL, (bfd_vma) 0)) - return false; - break; - - case CWARN: - /* Warn if this symbol has been referenced already, - otherwise add a warning. A symbol has been referenced if - the next field is not NULL, or it is the tail of the - undefined symbol list. The REF case above helps to - ensure this. */ - if (h->next != NULL || info->hash->undefs_tail == h) - { - if (! (*info->callbacks->warning) (info, string, name, - hash_entry_bfd (h), - (asection *) NULL, - (bfd_vma) 0)) - return false; - break; - } - /* Fall through. */ - case MWARN: - /* Make a warning symbol. */ - { - struct bfd_link_hash_entry *sub; - - /* STRING is the warning to give. */ - sub = ((struct bfd_link_hash_entry *) - ((*info->hash->table.newfunc) - ((struct bfd_hash_entry *) NULL, &info->hash->table, - h->root.string))); - if (sub == NULL) - return false; - *sub = *h; - sub->type = bfd_link_hash_warning; - sub->u.i.link = h; - if (! copy) - sub->u.i.warning = string; - else - { - char *w; - - w = bfd_hash_allocate (&info->hash->table, - strlen (string) + 1); - if (w == NULL) - return false; - strcpy (w, string); - sub->u.i.warning = w; - } - - bfd_hash_replace (&info->hash->table, - (struct bfd_hash_entry *) h, - (struct bfd_hash_entry *) sub); - if (hashp != NULL) - *hashp = sub; - } - break; - } - } - while (cycle); - - return true; -} - -/* Generic final link routine. */ - -boolean -_bfd_generic_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd *sub; - asection *o; - struct bfd_link_order *p; - size_t outsymalloc; - struct generic_write_global_symbol_info wginfo; - - abfd->outsymbols = (asymbol **) NULL; - abfd->symcount = 0; - outsymalloc = 0; - - /* Build the output symbol table. */ - for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next) - if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc)) - return false; - - /* Accumulate the global symbols. */ - wginfo.info = info; - wginfo.output_bfd = abfd; - wginfo.psymalloc = &outsymalloc; - _bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info), - _bfd_generic_link_write_global_symbol, - (PTR) &wginfo); - - if (info->relocateable) - { - /* Allocate space for the output relocs for each section. */ - for (o = abfd->sections; - o != (asection *) NULL; - o = o->next) - { - o->reloc_count = 0; - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - else if (p->type == bfd_indirect_link_order) - { - asection *input_section; - bfd *input_bfd; - long relsize; - arelent **relocs; - asymbol **symbols; - long reloc_count; - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - relsize = bfd_get_reloc_upper_bound (input_bfd, - input_section); - if (relsize < 0) - return false; - relocs = (arelent **) bfd_malloc ((size_t) relsize); - if (!relocs && relsize != 0) - return false; - symbols = _bfd_generic_link_get_symbols (input_bfd); - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - relocs, - symbols); - if (reloc_count < 0) - return false; - BFD_ASSERT ((unsigned long) reloc_count - == input_section->reloc_count); - o->reloc_count += reloc_count; - free (relocs); - } - } - if (o->reloc_count > 0) - { - o->orelocation = ((arelent **) - bfd_alloc (abfd, - (o->reloc_count - * sizeof (arelent *)))); - if (!o->orelocation) - return false; - o->flags |= SEC_RELOC; - /* Reset the count so that it can be used as an index - when putting in the output relocs. */ - o->reloc_count = 0; - } - } - } - - /* Handle all the link order information for the sections. */ - for (o = abfd->sections; - o != (asection *) NULL; - o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - switch (p->type) - { - case bfd_section_reloc_link_order: - case bfd_symbol_reloc_link_order: - if (! _bfd_generic_reloc_link_order (abfd, info, o, p)) - return false; - break; - case bfd_indirect_link_order: - if (! default_indirect_link_order (abfd, info, o, p, true)) - return false; - break; - default: - if (! _bfd_default_link_order (abfd, info, o, p)) - return false; - break; - } - } - } - - return true; -} - -/* Add an output symbol to the output BFD. */ - -static boolean -generic_add_output_symbol (output_bfd, psymalloc, sym) - bfd *output_bfd; - size_t *psymalloc; - asymbol *sym; -{ - if (output_bfd->symcount >= *psymalloc) - { - asymbol **newsyms; - - if (*psymalloc == 0) - *psymalloc = 124; - else - *psymalloc *= 2; - newsyms = (asymbol **) bfd_realloc (output_bfd->outsymbols, - *psymalloc * sizeof (asymbol *)); - if (newsyms == (asymbol **) NULL) - return false; - output_bfd->outsymbols = newsyms; - } - - output_bfd->outsymbols[output_bfd->symcount] = sym; - ++output_bfd->symcount; - - return true; -} - -/* Handle the symbols for an input BFD. */ - -boolean -_bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc) - bfd *output_bfd; - bfd *input_bfd; - struct bfd_link_info *info; - size_t *psymalloc; -{ - asymbol **sym_ptr; - asymbol **sym_end; - - if (! generic_link_read_symbols (input_bfd)) - return false; - - /* Create a filename symbol if we are supposed to. */ - if (info->create_object_symbols_section != (asection *) NULL) - { - asection *sec; - - for (sec = input_bfd->sections; - sec != (asection *) NULL; - sec = sec->next) - { - if (sec->output_section == info->create_object_symbols_section) - { - asymbol *newsym; - - newsym = bfd_make_empty_symbol (input_bfd); - if (!newsym) - return false; - newsym->name = input_bfd->filename; - newsym->value = 0; - newsym->flags = BSF_LOCAL | BSF_FILE; - newsym->section = sec; - - if (! generic_add_output_symbol (output_bfd, psymalloc, - newsym)) - return false; - - break; - } - } - } - - /* Adjust the values of the globally visible symbols, and write out - local symbols. */ - sym_ptr = _bfd_generic_link_get_symbols (input_bfd); - sym_end = sym_ptr + _bfd_generic_link_get_symcount (input_bfd); - for (; sym_ptr < sym_end; sym_ptr++) - { - asymbol *sym; - struct generic_link_hash_entry *h; - boolean output; - - h = (struct generic_link_hash_entry *) NULL; - sym = *sym_ptr; - if ((sym->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym)) - || bfd_is_ind_section (bfd_get_section (sym))) - { - if (sym->udata.p != NULL) - h = (struct generic_link_hash_entry *) sym->udata.p; - else if ((sym->flags & BSF_CONSTRUCTOR) != 0) - { - /* This case normally means that the main linker code - deliberately ignored this constructor symbol. We - should just pass it through. This will screw up if - the constructor symbol is from a different, - non-generic, object file format, but the case will - only arise when linking with -r, which will probably - fail anyhow, since there will be no way to represent - the relocs in the output format being used. */ - h = NULL; - } - else if (bfd_is_und_section (bfd_get_section (sym))) - h = ((struct generic_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, - bfd_asymbol_name (sym), - false, false, true)); - else - h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), - bfd_asymbol_name (sym), - false, false, true); - - if (h != (struct generic_link_hash_entry *) NULL) - { - /* Force all references to this symbol to point to - the same area in memory. It is possible that - this routine will be called with a hash table - other than a generic hash table, so we double - check that. */ - if (info->hash->creator == input_bfd->xvec) - { - if (h->sym != (asymbol *) NULL) - *sym_ptr = sym = h->sym; - } - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - case bfd_link_hash_undefined: - break; - case bfd_link_hash_undefweak: - sym->flags |= BSF_WEAK; - break; - case bfd_link_hash_indirect: - h = (struct generic_link_hash_entry *) h->root.u.i.link; - /* fall through */ - case bfd_link_hash_defined: - sym->flags |= BSF_GLOBAL; - sym->flags &=~ BSF_CONSTRUCTOR; - sym->value = h->root.u.def.value; - sym->section = h->root.u.def.section; - break; - case bfd_link_hash_defweak: - sym->flags |= BSF_WEAK; - sym->flags &=~ BSF_CONSTRUCTOR; - sym->value = h->root.u.def.value; - sym->section = h->root.u.def.section; - break; - case bfd_link_hash_common: - sym->value = h->root.u.c.size; - sym->flags |= BSF_GLOBAL; - if (! bfd_is_com_section (sym->section)) - { - BFD_ASSERT (bfd_is_und_section (sym->section)); - sym->section = bfd_com_section_ptr; - } - /* We do not set the section of the symbol to - h->root.u.c.p->section. That value was saved so - that we would know where to allocate the symbol - if it was defined. In this case the type is - still bfd_link_hash_common, so we did not define - it, so we do not want to use that section. */ - break; - } - } - } - - /* This switch is straight from the old code in - write_file_locals in ldsym.c. */ - if (info->strip == strip_some - && (bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), - false, false) - == (struct bfd_hash_entry *) NULL)) - output = false; - else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0) - { - /* If this symbol is marked as occurring now, rather - than at the end, output it now. This is used for - COFF C_EXT FCN symbols. FIXME: There must be a - better way. */ - if (bfd_asymbol_bfd (sym) == input_bfd - && (sym->flags & BSF_NOT_AT_END) != 0) - output = true; - else - output = false; - } - else if (bfd_is_ind_section (sym->section)) - output = false; - else if ((sym->flags & BSF_DEBUGGING) != 0) - { - if (info->strip == strip_none) - output = true; - else - output = false; - } - else if (bfd_is_und_section (sym->section) - || bfd_is_com_section (sym->section)) - output = false; - else if ((sym->flags & BSF_LOCAL) != 0) - { - if ((sym->flags & BSF_WARNING) != 0) - output = false; - else - { - switch (info->discard) - { - default: - case discard_all: - output = false; - break; - case discard_l: - if (bfd_asymbol_name (sym)[0] == info->lprefix[0] - && (info->lprefix_len == 1 - || strncmp (bfd_asymbol_name (sym), info->lprefix, - info->lprefix_len) == 0)) - output = false; - else - output = true; - break; - case discard_none: - output = true; - break; - } - } - } - else if ((sym->flags & BSF_CONSTRUCTOR)) - { - if (info->strip != strip_all) - output = true; - else - output = false; - } - else - abort (); - - if (output) - { - if (! generic_add_output_symbol (output_bfd, psymalloc, sym)) - return false; - if (h != (struct generic_link_hash_entry *) NULL) - h->written = true; - } - } - - return true; -} - -/* Set the section and value of a generic BFD symbol based on a linker - hash table entry. */ - -static void -set_symbol_from_hash (sym, h) - asymbol *sym; - struct bfd_link_hash_entry *h; -{ - switch (h->type) - { - default: - abort (); - break; - case bfd_link_hash_new: - /* This can happen when a constructor symbol is seen but we are - not building constructors. */ - if (sym->section != NULL) - { - BFD_ASSERT ((sym->flags & BSF_CONSTRUCTOR) != 0); - } - else - { - sym->flags |= BSF_CONSTRUCTOR; - sym->section = bfd_abs_section_ptr; - sym->value = 0; - } - break; - case bfd_link_hash_undefined: - sym->section = bfd_und_section_ptr; - sym->value = 0; - break; - case bfd_link_hash_undefweak: - sym->section = bfd_und_section_ptr; - sym->value = 0; - sym->flags |= BSF_WEAK; - break; - case bfd_link_hash_defined: - sym->section = h->u.def.section; - sym->value = h->u.def.value; - break; - case bfd_link_hash_defweak: - sym->flags |= BSF_WEAK; - sym->section = h->u.def.section; - sym->value = h->u.def.value; - break; - case bfd_link_hash_common: - sym->value = h->u.c.size; - if (sym->section == NULL) - sym->section = bfd_com_section_ptr; - else if (! bfd_is_com_section (sym->section)) - { - BFD_ASSERT (bfd_is_und_section (sym->section)); - sym->section = bfd_com_section_ptr; - } - /* Do not set the section; see _bfd_generic_link_output_symbols. */ - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: What should we do here? */ - break; - } -} - -/* Write out a global symbol, if it hasn't already been written out. - This is called for each symbol in the hash table. */ - -boolean -_bfd_generic_link_write_global_symbol (h, data) - struct generic_link_hash_entry *h; - PTR data; -{ - struct generic_write_global_symbol_info *wginfo = - (struct generic_write_global_symbol_info *) data; - asymbol *sym; - - if (h->written) - return true; - - h->written = true; - - if (wginfo->info->strip == strip_all - || (wginfo->info->strip == strip_some - && bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string, - false, false) == NULL)) - return true; - - if (h->sym != (asymbol *) NULL) - sym = h->sym; - else - { - sym = bfd_make_empty_symbol (wginfo->output_bfd); - if (!sym) - return false; - sym->name = h->root.root.string; - sym->flags = 0; - } - - set_symbol_from_hash (sym, &h->root); - - sym->flags |= BSF_GLOBAL; - - if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc, - sym)) - { - /* FIXME: No way to return failure. */ - abort (); - } - - return true; -} - -/* Create a relocation. */ - -boolean -_bfd_generic_reloc_link_order (abfd, info, sec, link_order) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - struct bfd_link_order *link_order; -{ - arelent *r; - - if (! info->relocateable) - abort (); - if (sec->orelocation == (arelent **) NULL) - abort (); - - r = (arelent *) bfd_alloc (abfd, sizeof (arelent)); - if (r == (arelent *) NULL) - return false; - - r->address = link_order->offset; - r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc); - if (r->howto == 0) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Get the symbol to use for the relocation. */ - if (link_order->type == bfd_section_reloc_link_order) - r->sym_ptr_ptr = link_order->u.reloc.p->u.section->symbol_ptr_ptr; - else - { - struct generic_link_hash_entry *h; - - h = ((struct generic_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h == (struct generic_link_hash_entry *) NULL - || ! h->written) - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - return false; - bfd_set_error (bfd_error_bad_value); - return false; - } - r->sym_ptr_ptr = &h->sym; - } - - /* If this is an inplace reloc, write the addend to the object file. - Otherwise, store it in the reloc addend. */ - if (! r->howto->partial_inplace) - r->addend = link_order->u.reloc.p->addend; - else - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (r->howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - return false; - rstat = _bfd_relocate_contents (r->howto, abfd, - link_order->u.reloc.p->addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (abfd, link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - r->howto->name, link_order->u.reloc.p->addend, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (abfd, sec, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - - r->addend = 0; - } - - sec->orelocation[sec->reloc_count] = r; - ++sec->reloc_count; - - return true; -} - -/* Allocate a new link_order for a section. */ - -struct bfd_link_order * -bfd_new_link_order (abfd, section) - bfd *abfd; - asection *section; -{ - struct bfd_link_order *new; - - new = ((struct bfd_link_order *) - bfd_alloc_by_size_t (abfd, sizeof (struct bfd_link_order))); - if (!new) - return NULL; - - new->type = bfd_undefined_link_order; - new->offset = 0; - new->size = 0; - new->next = (struct bfd_link_order *) NULL; - - if (section->link_order_tail != (struct bfd_link_order *) NULL) - section->link_order_tail->next = new; - else - section->link_order_head = new; - section->link_order_tail = new; - - return new; -} - -/* Default link order processing routine. Note that we can not handle - the reloc_link_order types here, since they depend upon the details - of how the particular backends generates relocs. */ - -boolean -_bfd_default_link_order (abfd, info, sec, link_order) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - struct bfd_link_order *link_order; -{ - switch (link_order->type) - { - case bfd_undefined_link_order: - case bfd_section_reloc_link_order: - case bfd_symbol_reloc_link_order: - default: - abort (); - case bfd_indirect_link_order: - return default_indirect_link_order (abfd, info, sec, link_order, - false); - case bfd_fill_link_order: - return default_fill_link_order (abfd, info, sec, link_order); - case bfd_data_link_order: - return bfd_set_section_contents (abfd, sec, - (PTR) link_order->u.data.contents, - (file_ptr) link_order->offset, - link_order->size); - } -} - -/* Default routine to handle a bfd_fill_link_order. */ - -/*ARGSUSED*/ -static boolean -default_fill_link_order (abfd, info, sec, link_order) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - struct bfd_link_order *link_order; -{ - size_t size; - char *space; - size_t i; - int fill; - boolean result; - - BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0); - - size = (size_t) link_order->size; - space = (char *) bfd_malloc (size); - if (space == NULL && size != 0) - return false; - - fill = link_order->u.fill.value; - for (i = 0; i < size; i += 2) - space[i] = fill >> 8; - for (i = 1; i < size; i += 2) - space[i] = fill; - result = bfd_set_section_contents (abfd, sec, space, - (file_ptr) link_order->offset, - link_order->size); - free (space); - return result; -} - -/* Default routine to handle a bfd_indirect_link_order. */ - -static boolean -default_indirect_link_order (output_bfd, info, output_section, link_order, - generic_linker) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; - boolean generic_linker; -{ - asection *input_section; - bfd *input_bfd; - bfd_byte *contents = NULL; - bfd_byte *new_contents; - - BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); - - if (link_order->size == 0) - return true; - - input_section = link_order->u.indirect.section; - input_bfd = input_section->owner; - - BFD_ASSERT (input_section->output_section == output_section); - BFD_ASSERT (input_section->output_offset == link_order->offset); - BFD_ASSERT (input_section->_cooked_size == link_order->size); - - if (info->relocateable - && input_section->reloc_count > 0 - && output_section->orelocation == (arelent **) NULL) - { - /* Space has not been allocated for the output relocations. - This can happen when we are called by a specific backend - because somebody is attempting to link together different - types of object files. Handling this case correctly is - difficult, and sometimes impossible. */ - abort (); - } - - if (! generic_linker) - { - asymbol **sympp; - asymbol **symppend; - - /* Get the canonical symbols. The generic linker will always - have retrieved them by this point, but we are being called by - a specific linker, presumably because we are linking - different types of object files together. */ - if (! generic_link_read_symbols (input_bfd)) - return false; - - /* Since we have been called by a specific linker, rather than - the generic linker, the values of the symbols will not be - right. They will be the values as seen in the input file, - not the values of the final link. We need to fix them up - before we can relocate the section. */ - sympp = _bfd_generic_link_get_symbols (input_bfd); - symppend = sympp + _bfd_generic_link_get_symcount (input_bfd); - for (; sympp < symppend; sympp++) - { - asymbol *sym; - struct bfd_link_hash_entry *h; - - sym = *sympp; - - if ((sym->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym)) - || bfd_is_ind_section (bfd_get_section (sym))) - { - /* sym->udata may have been set by - generic_link_add_symbol_list. */ - if (sym->udata.p != NULL) - h = (struct bfd_link_hash_entry *) sym->udata.p; - else if (bfd_is_und_section (bfd_get_section (sym))) - h = bfd_wrapped_link_hash_lookup (output_bfd, info, - bfd_asymbol_name (sym), - false, false, true); - else - h = bfd_link_hash_lookup (info->hash, - bfd_asymbol_name (sym), - false, false, true); - if (h != NULL) - set_symbol_from_hash (sym, h); - } - } - } - - /* Get and relocate the section contents. */ - contents = ((bfd_byte *) - bfd_malloc (bfd_section_size (input_bfd, input_section))); - if (contents == NULL && bfd_section_size (input_bfd, input_section) != 0) - goto error_return; - new_contents = (bfd_get_relocated_section_contents - (output_bfd, info, link_order, contents, info->relocateable, - _bfd_generic_link_get_symbols (input_bfd))); - if (!new_contents) - goto error_return; - - /* Output the section contents. */ - if (! bfd_set_section_contents (output_bfd, output_section, - (PTR) new_contents, - link_order->offset, link_order->size)) - goto error_return; - - if (contents != NULL) - free (contents); - return true; - - error_return: - if (contents != NULL) - free (contents); - return false; -} - -/* A little routine to count the number of relocs in a link_order - list. */ - -unsigned int -_bfd_count_link_order_relocs (link_order) - struct bfd_link_order *link_order; -{ - register unsigned int c; - register struct bfd_link_order *l; - - c = 0; - for (l = link_order; l != (struct bfd_link_order *) NULL; l = l->next) - { - if (l->type == bfd_section_reloc_link_order - || l->type == bfd_symbol_reloc_link_order) - ++c; - } - - return c; -} - -/* -FUNCTION - bfd_link_split_section - -SYNOPSIS - boolean bfd_link_split_section(bfd *abfd, asection *sec); - -DESCRIPTION - Return nonzero if @var{sec} should be split during a - reloceatable or final link. - -.#define bfd_link_split_section(abfd, sec) \ -. BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) -. - -*/ - - - -boolean -_bfd_generic_link_split_section (abfd, sec) - bfd *abfd; - asection *sec; -{ - return false; -} diff --git a/contrib/gdb/bfd/lynx-core.c b/contrib/gdb/bfd/lynx-core.c deleted file mode 100644 index 2358177dbc6..00000000000 --- a/contrib/gdb/bfd/lynx-core.c +++ /dev/null @@ -1,233 +0,0 @@ -/* BFD back end for Lynx core files - Copyright 1993 Free Software Foundation, Inc. - Written by Stu Grossman of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifdef LYNX_CORE - -#include -#include -/* sys/kernel.h should define this, but doesn't always, sigh. */ -#ifndef __LYNXOS -#define __LYNXOS -#endif -#include -#include -#include -#include -#include -#include -#include - -/* These are stored in the bfd's tdata */ - -struct lynx_core_struct -{ - int sig; - char cmd[PNMLEN + 1]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.lynx_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -/* Handle Lynx core dump file. */ - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - file_ptr filepos; -{ - asection *asect; - char *newname; - - newname = bfd_alloc (abfd, strlen (name) + 1); - if (!newname) - return NULL; - - strcpy (newname, name); - - asect = bfd_make_section (abfd, newname); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = filepos; - asect->alignment_power = 2; - - return asect; -} - -/* ARGSUSED */ -const bfd_target * -lynx_core_file_p (abfd) - bfd *abfd; -{ - int val; - int secnum; - struct pssentry pss; - size_t tcontext_size; - core_st_t *threadp; - int pagesize; - asection *newsect; - - pagesize = getpagesize (); /* Serious cross-target issue here... This - really needs to come from a system-specific - header file. */ - - /* Get the pss entry from the core file */ - - if (bfd_seek (abfd, 0, SEEK_SET) != 0) - return NULL; - - val = bfd_read ((void *)&pss, 1, sizeof pss, abfd); - if (val != sizeof pss) - { - /* Too small to be a core file */ - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - core_hdr (abfd) = (struct lynx_core_struct *) - bfd_zalloc (abfd, sizeof (struct lynx_core_struct)); - - if (!core_hdr (abfd)) - return NULL; - - strncpy (core_command (abfd), pss.pname, PNMLEN + 1); - - /* Compute the size of the thread contexts */ - - tcontext_size = pss.threadcnt * sizeof (core_st_t); - - /* Allocate space for the thread contexts */ - - threadp = (core_st_t *)bfd_alloc (abfd, tcontext_size); - if (!threadp) - return NULL; - - /* Save thread contexts */ - - if (bfd_seek (abfd, pagesize, SEEK_SET) != 0) - return NULL; - - val = bfd_read ((void *)threadp, pss.threadcnt, sizeof (core_st_t), abfd); - - if (val != tcontext_size) - { - /* Probably too small to be a core file */ - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - core_signal (abfd) = threadp->currsig; - - newsect = make_bfd_asection (abfd, ".stack", - SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, - pss.ssize, - pss.slimit, - pagesize + tcontext_size); - if (!newsect) - return NULL; - - newsect = make_bfd_asection (abfd, ".data", - SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, - pss.data_len + pss.bss_len, - pss.data_start, - pagesize + tcontext_size + pss.ssize -#if defined (SPARC) || defined (__SPARC__) - /* SPARC Lynx seems to start dumping - the .data section at a page - boundary. It's OK to check a - #define like SPARC here because this - file can only be compiled on a Lynx - host. */ - + pss.data_start % pagesize -#endif - ); - if (!newsect) - return NULL; - -/* And, now for the .reg/XXX pseudo sections. Each thread has it's own - .reg/XXX section, where XXX is the thread id (without leading zeros). The - currently running thread (at the time of the core dump) also has an alias - called `.reg' (just to keep GDB happy). Note that we use `.reg/XXX' as - opposed to `.regXXX' because GDB expects that .reg2 will be the floating- - point registers. */ - - newsect = make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - sizeof (core_st_t), - 0, - pagesize); - if (!newsect) - return NULL; - - for (secnum = 0; secnum < pss.threadcnt; secnum++) - { - char secname[100]; - - sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid)); - newsect = make_bfd_asection (abfd, secname, - SEC_HAS_CONTENTS, - sizeof (core_st_t), - 0, - pagesize + secnum * sizeof (core_st_t)); - if (!newsect) - return NULL; - } - - return abfd->xvec; -} - -char * -lynx_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -int -lynx_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -boolean -lynx_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -#endif /* LYNX_CORE */ diff --git a/contrib/gdb/bfd/m68k4knetbsd.c b/contrib/gdb/bfd/m68k4knetbsd.c deleted file mode 100644 index c1ecb434425..00000000000 --- a/contrib/gdb/bfd/m68k4knetbsd.c +++ /dev/null @@ -1,35 +0,0 @@ -/* BFD back-end for NetBSD/m68k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#define TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE 4096 - -#define DEFAULT_ARCH bfd_arch_m68k -#define MACHTYPE_OK(mtype) \ - ((mtype) == M_68020 || (mtype) == M_68K_NETBSD || (mtype) == M_68K4K_NETBSD \ - || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(m68k4knetbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-m68k4k-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/m68klinux.c b/contrib/gdb/bfd/m68klinux.c deleted file mode 100644 index 062165b399b..00000000000 --- a/contrib/gdb/bfd/m68klinux.c +++ /dev/null @@ -1,767 +0,0 @@ -/* BFD back-end for linux flavored m68k a.out binaries. - Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_PAGE_SIZE 4096 -#define ZMAGIC_DISK_BLOCK_SIZE 1024 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0x0 -#define N_SHARED_LIB(x) 0 -#define BYTES_IN_WORD 4 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#define TARGET_IS_BIG_ENDIAN_P -#define DEFAULT_ARCH bfd_arch_m68k -#define MY(OP) CAT(m68klinux_,OP) -#define TARGETNAME "a.out-m68k-linux" - -extern const bfd_target MY(vec); - -/* We always generate QMAGIC files in preference to ZMAGIC files. It - would be possible to make this a linker option, if that ever - becomes important. */ - -static void MY_final_link_callback - PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); - -static boolean -m68klinux_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - obj_aout_subformat (abfd) = q_magic_format; - return NAME(aout,final_link) (abfd, info, MY_final_link_callback); -} - -#define MY_bfd_final_link m68klinux_bfd_final_link - -/* Set the machine type correctly. */ - -static boolean -m68klinux_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - N_SET_MACHTYPE (*execp, M_68020); - - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - WRITE_HEADERS(abfd, execp); - - return true; -} - -#define MY_write_object_contents m68klinux_write_object_contents - -/* Code to link against Linux a.out shared libraries. */ - -/* See if a symbol name is a reference to the global offset table. */ - -#ifndef GOT_REF_PREFIX -#define GOT_REF_PREFIX "__GOT_" -#endif - -#define IS_GOT_SYM(name) \ - (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0) - -/* See if a symbol name is a reference to the procedure linkage table. */ - -#ifndef PLT_REF_PREFIX -#define PLT_REF_PREFIX "__PLT_" -#endif - -#define IS_PLT_SYM(name) \ - (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0) - -/* This string is used to generate specialized error messages. */ - -#ifndef NEEDS_SHRLIB -#define NEEDS_SHRLIB "__NEEDS_SHRLIB_" -#endif - -/* This special symbol is a set vector that contains a list of - pointers to fixup tables. It will be present in any dynamicly - linked file. The linker generated fixup table should also be added - to the list, and it should always appear in the second slot (the - first one is a dummy with a magic number that is defined in - crt0.o). */ - -#ifndef SHARABLE_CONFLICTS -#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__" -#endif - -/* We keep a list of fixups. The terminology is a bit strange, but - each fixup contains two 32 bit numbers. A regular fixup contains - an address and a pointer, and at runtime we should store the - address at the location pointed to by the pointer. A builtin fixup - contains two pointers, and we should read the address using one - pointer and store it at the location pointed to by the other - pointer. Builtin fixups come into play when we have duplicate - __GOT__ symbols for the same variable. The builtin fixup will copy - the GOT pointer from one over into the other. */ - -struct fixup -{ - struct fixup *next; - struct linux_link_hash_entry *h; - bfd_vma value; - - /* Nonzero if this is a jump instruction that needs to be fixed, - zero if this is just a pointer */ - char jump; - - char builtin; -}; - -/* We don't need a special hash table entry structure, but we do need - to keep some information between linker passes, so we use a special - hash table. */ - -struct linux_link_hash_entry -{ - struct aout_link_hash_entry root; -}; - -struct linux_link_hash_table -{ - struct aout_link_hash_table root; - - /* First dynamic object found in link. */ - bfd *dynobj; - - /* Number of fixups. */ - size_t fixup_count; - - /* Number of builtin fixups. */ - size_t local_builtins; - - /* List of fixups. */ - struct fixup *fixup_list; -}; - -static struct bfd_hash_entry *linux_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *linux_link_hash_table_create - PARAMS ((bfd *)); -static struct fixup *new_fixup - PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *, - bfd_vma, int)); -static boolean linux_link_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean linux_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); -static boolean linux_tally_symbols - PARAMS ((struct linux_link_hash_entry *, PTR)); -static boolean linux_finish_dynamic_link - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Routine to create an entry in an Linux link hash table. */ - -static struct bfd_hash_entry * -linux_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct linux_link_hash_entry *) NULL) - ret = ((struct linux_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry))); - if (ret == NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct linux_link_hash_entry *) - NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields; there aren't any. */ - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a Linux link hash table. */ - -static struct bfd_link_hash_table * -linux_link_hash_table_create (abfd) - bfd *abfd; -{ - struct linux_link_hash_table *ret; - - ret = ((struct linux_link_hash_table *) - bfd_alloc (abfd, sizeof (struct linux_link_hash_table))); - if (ret == (struct linux_link_hash_table *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_link_hash_table *) NULL; - } - if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, - linux_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->dynobj = NULL; - ret->fixup_count = 0; - ret->local_builtins = 0; - ret->fixup_list = NULL; - - return &ret->root.root; -} - -/* Look up an entry in a Linux link hash table. */ - -#define linux_link_hash_lookup(table, string, create, copy, follow) \ - ((struct linux_link_hash_entry *) \ - aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse a Linux link hash table. */ - -#define linux_link_hash_traverse(table, func, info) \ - (aout_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the Linux link hash table from the info structure. This is - just a cast. */ - -#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash)) - -/* Store the information for a new fixup. */ - -static struct fixup * -new_fixup (info, h, value, builtin) - struct bfd_link_info *info; - struct linux_link_hash_entry *h; - bfd_vma value; - int builtin; -{ - struct fixup *f; - - f = (struct fixup *) bfd_hash_allocate (&info->hash->table, - sizeof (struct fixup)); - if (f == NULL) - return f; - f->next = linux_hash_table (info)->fixup_list; - linux_hash_table (info)->fixup_list = f; - f->h = h; - f->value = value; - f->builtin = builtin; - f->jump = 0; - ++linux_hash_table (info)->fixup_count; - return f; -} - -/* We come here once we realize that we are going to link to a shared - library. We need to create a special section that contains the - fixup table, and we ultimately need to add a pointer to this into - the set vector for SHARABLE_CONFLICTS. At this point we do not - know the size of the section, but that's OK - we just need to - create it for now. */ - -static boolean -linux_link_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - - /* Note that we set the SEC_IN_MEMORY flag. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* We choose to use the name ".linux-dynamic" for the fixup table. - Why not? */ - s = bfd_make_section (abfd, ".linux-dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - s->_raw_size = 0; - s->contents = 0; - - return true; -} - -/* Function to add a single symbol to the linker hash table. This is - a wrapper around _bfd_generic_link_add_one_symbol which handles the - tweaking needed for dynamic linking support. */ - -static boolean -linux_add_one_symbol (info, abfd, name, flags, section, value, string, - copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct linux_link_hash_entry *h; - boolean insert; - - /* Look up and see if we already have this symbol in the hash table. - If we do, and the defining entry is from a shared library, we - need to create the dynamic sections. - - FIXME: What if abfd->xvec != info->hash->creator? We may want to - be able to link Linux a.out and ELF objects together, but serious - confusion is possible. */ - - insert = false; - - if (! info->relocateable - && linux_hash_table (info)->dynobj == NULL - && strcmp (name, SHARABLE_CONFLICTS) == 0 - && (flags & BSF_CONSTRUCTOR) != 0 - && abfd->xvec == info->hash->creator) - { - if (! linux_link_create_dynamic_sections (abfd, info)) - return false; - linux_hash_table (info)->dynobj = abfd; - insert = true; - } - - if (bfd_is_abs_section (section) - && abfd->xvec == info->hash->creator) - { - h = linux_link_hash_lookup (linux_hash_table (info), name, false, - false, false); - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - struct fixup *f; - - if (hashp != NULL) - *hashp = (struct bfd_link_hash_entry *) h; - - f = new_fixup (info, h, value, ! IS_PLT_SYM (name)); - if (f == NULL) - return false; - f->jump = IS_PLT_SYM (name); - - return true; - } - } - - /* Do the usual procedure for adding a symbol. */ - if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp)) - return false; - - /* Insert a pointer to our table in the set vector. The dynamic - linker requires this information */ - if (insert) - { - asection *s; - - /* Here we do our special thing to add the pointer to the - dynamic section in the SHARABLE_CONFLICTS set vector. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - - if (! (_bfd_generic_link_add_one_symbol - (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS, - BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL))) - return false; - } - - return true; -} - -/* We will crawl the hash table and come here for every global symbol. - We will examine each entry and see if there are indications that we - need to add a fixup. There are two possible cases - one is where - you have duplicate definitions of PLT or GOT symbols - these will - have already been caught and added as "builtin" fixups. If we find - that the corresponding non PLT/GOT symbol is also present, we - convert it to a regular fixup instead. - - This function is called via linux_link_hash_traverse. */ - -static boolean -linux_tally_symbols (h, data) - struct linux_link_hash_entry *h; - PTR data; -{ - struct bfd_link_info *info = (struct bfd_link_info *) data; - struct fixup *f, *f1; - int is_plt; - struct linux_link_hash_entry *h1, *h2; - boolean exists; - - if (h->root.root.type == bfd_link_hash_undefined - && strncmp (h->root.root.root.string, NEEDS_SHRLIB, - sizeof NEEDS_SHRLIB - 1) == 0) - { - const char *name; - char *p; - char *alloc = NULL; - - name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1; - p = strrchr (name, '_'); - if (p != NULL) - alloc = (char *) bfd_malloc (strlen (name) + 1); - - if (p == NULL || alloc == NULL) - (*_bfd_error_handler) ("Output file requires shared library `%s'\n", - name); - else - { - strcpy (alloc, name); - p = strrchr (alloc, '_'); - *p++ = '\0'; - (*_bfd_error_handler) - ("Output file requires shared library `%s.so.%s'\n", - alloc, p); - free (alloc); - } - - abort (); - } - - /* If this symbol is not a PLT/GOT, we do not even need to look at it */ - is_plt = IS_PLT_SYM (h->root.root.root.string); - - if (is_plt || IS_GOT_SYM (h->root.root.root.string)) - { - /* Look up this symbol twice. Once just as a regular lookup, - and then again following all of the indirect links until we - reach a real symbol. */ - h1 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, true); - /* h2 does not follow indirect symbols. */ - h2 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, false); - - /* The real symbol must exist but if it is also an ABS symbol, - there is no need to have a fixup. This is because they both - came from the same library. If on the other hand, we had to - use an indirect symbol to get to the real symbol, we add the - fixup anyway, since there are cases where these symbols come - from different shared libraries */ - if (h1 != NULL - && (((h1->root.root.type == bfd_link_hash_defined - || h1->root.root.type == bfd_link_hash_defweak) - && ! bfd_is_abs_section (h1->root.root.u.def.section)) - || h2->root.root.type == bfd_link_hash_indirect)) - { - /* See if there is a "builtin" fixup already present - involving this symbol. If so, convert it to a regular - fixup. In the end, this relaxes some of the requirements - about the order of performing fixups. */ - exists = false; - for (f1 = linux_hash_table (info)->fixup_list; - f1 != NULL; - f1 = f1->next) - { - if ((f1->h != h && f1->h != h1) - || (! f1->builtin && ! f1->jump)) - continue; - if (f1->h == h1) - exists = true; - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0); - f->jump = is_plt; - } - f1->h = h1; - f1->jump = is_plt; - f1->builtin = 0; - exists = true; - } - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, h->root.root.u.def.value, 0); - if (f == NULL) - { - /* FIXME: No way to return error. */ - abort (); - } - f->jump = is_plt; - } - } - - /* Quick and dirty way of stripping these symbols from the - symtab. */ - if (bfd_is_abs_section (h->root.root.u.def.section)) - h->root.written = true; - } - - return true; -} - -/* This is called to set the size of the .linux-dynamic section is. - It is called by the Linux linker emulation before_allocation - routine. We have finished reading all of the input files, and now - we just scan the hash tables to find out how many additional fixups - are required. */ - -boolean -bfd_m68klinux_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - struct fixup *f; - asection *s; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* First find the fixups... */ - linux_link_hash_traverse (linux_hash_table (info), - linux_tally_symbols, - (PTR) info); - - /* If there are builtin fixups, leave room for a marker. This is - used by the dynamic linker so that it knows that all that follow - are builtin fixups instead of regular fixups. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - { - ++linux_hash_table (info)->fixup_count; - ++linux_hash_table (info)->local_builtins; - break; - } - } - - if (linux_hash_table (info)->dynobj == NULL) - { - if (linux_hash_table (info)->fixup_count > 0) - abort (); - return true; - } - - /* Allocate memory for our fixup table. We will fill it in later. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - if (s != NULL) - { - s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8; - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (s->contents, 0, (size_t) s->_raw_size); - } - - return true; -} - -/* We come here once we are ready to actually write the fixup table to - the output file. Scan the fixup tables and so forth and generate - the stuff we need. */ - -static boolean -linux_finish_dynamic_link (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - asection *s, *os, *is; - bfd_byte *fixup_table; - struct linux_link_hash_entry *h; - struct fixup *f; - unsigned int new_addr; - int section_offset; - unsigned int fixups_written; - - if (linux_hash_table (info)->dynobj == NULL) - return true; - - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - os = s->output_section; - fixups_written = 0; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup table file offset: %x VMA: %x\n", - os->filepos + s->output_offset, - os->vma + s->output_offset); -#endif - - fixup_table = s->contents; - bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table); - fixup_table += 4; - - /* Fill in fixup table. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string, - new_addr, f->value); -#endif - - if (f->jump) - { - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value + 2, fixup_table); - fixup_table += 4; - } - else - { - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - } - ++fixups_written; - } - - if (linux_hash_table (info)->local_builtins != 0) - { - /* Special marker so we know to switch to the other type of fixup */ - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (! f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string, - new_addr, f->value); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - if (linux_hash_table (info)->fixup_count != fixups_written) - { - (*_bfd_error_handler) ("Warning: fixup count mismatch\n"); - while (linux_hash_table (info)->fixup_count > fixups_written) - { - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - h = linux_link_hash_lookup (linux_hash_table (info), - "__BUILTIN_FIXUPS__", - false, false, false); - - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - is = h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Builtin fixup table at %x\n", new_addr); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - } - else - bfd_put_32 (output_bfd, 0, fixup_table); - - if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0) - return false; - - if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd) - != s->_raw_size) - return false; - - return true; -} - -#define MY_bfd_link_hash_table_create linux_link_hash_table_create -#define MY_add_one_symbol linux_add_one_symbol -#define MY_finish_dynamic_link linux_finish_dynamic_link - -#define MY_zmagic_contiguous 1 - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/m68klynx.c b/contrib/gdb/bfd/m68klynx.c deleted file mode 100644 index 7acdfbcad21..00000000000 --- a/contrib/gdb/bfd/m68klynx.c +++ /dev/null @@ -1,54 +0,0 @@ -/* BFD back-end for m68k binaries under LynxOS. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#define N_SHARED_LIB(x) 0 - -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_m68k - -#define MY(OP) CAT(m68klynx_aout_,OP) -#define TARGETNAME "a.out-m68k-lynx" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "libaout.h" -#include "aout/aout64.h" - -#define TARGET_IS_BIG_ENDIAN_P - -#ifdef LYNX_CORE - -char *lynx_core_file_failing_command(); -int lynx_core_file_failing_signal(); -boolean lynx_core_file_matches_executable_p(); -const bfd_target *lynx_core_file_p(); - -#define MY_core_file_failing_command lynx_core_file_failing_command -#define MY_core_file_failing_signal lynx_core_file_failing_signal -#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p -#define MY_core_file_p lynx_core_file_p - -#endif /* LYNX_CORE */ - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/m68knetbsd.c b/contrib/gdb/bfd/m68knetbsd.c deleted file mode 100644 index 3bff530fbc7..00000000000 --- a/contrib/gdb/bfd/m68knetbsd.c +++ /dev/null @@ -1,35 +0,0 @@ -/* BFD back-end for NetBSD/m68k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#define TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 8192 -#define SEGMENT_SIZE 8192 - -#define DEFAULT_ARCH bfd_arch_m68k -#define MACHTYPE_OK(mtype) \ - ((mtype) == M_68020 || (mtype) == M_68K_NETBSD || (mtype) == M_68K4K_NETBSD \ - || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(m68knetbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-m68k-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/m88kmach3.c b/contrib/gdb/bfd/m88kmach3.c deleted file mode 100644 index 7a564087300..00000000000 --- a/contrib/gdb/bfd/m88kmach3.c +++ /dev/null @@ -1,38 +0,0 @@ -/* BFD back-end for Motorola m88k a.out (Mach 3) binaries. - Copyright (C) 1990, 1991, 1993, 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_PAGE_SIZE (4096*2) -#define SEGMENT_SIZE 0x20000 -#define TEXT_START_ADDR 0 -#define BYTES_IN_WORD 4 -#define N_HEADER_IN_TEXT(x) 1 /* (N_MAGIG(x) == ZMAGIC) */ -#define N_SHARED_LIB(x) 0 - -#define N_TXTSIZE(x) ((x).a_text) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#define DEFAULT_ARCH bfd_arch_m88k -#define MY(OP) CAT(m88kmach3_,OP) -#define TARGETNAME "a.out-m88k-mach3" - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/makefile.dos b/contrib/gdb/bfd/makefile.dos deleted file mode 100644 index 8a22c6af201..00000000000 --- a/contrib/gdb/bfd/makefile.dos +++ /dev/null @@ -1,49 +0,0 @@ -CFLAGS=-O2 - -.c.o : - gcc $(CFLAGS) -I. -I../include -c $< - -all : libbfd.a - -targets.o : targets.c - gcc $(CFLAGS) -I. -I../include -DSELECT_VECS=&go32coff_vec,&i386aout_vec -DDEFAULT_VECTOR=go32coff_vec -c $*.c - -archures.o : archures.c - gcc $(CFLAGS) -I. -I../include -DSELECT_ARCHITECTURES=bfd_i386_arch -c $*.c - -OBJS = \ - libbfd.o \ - opncls.o \ - bfd.o \ - archive.o \ - targets.o \ - cache.o \ - archures.o \ - corefile.o \ - section.o \ - format.o \ - syms.o \ - reloc.o \ - init.o \ - coffgen.o \ - srec.o \ - hash.o \ - linker.o \ - ecoff.o \ - ecofflink.o \ - elf.o \ - aout32.o \ - stab-sym.o \ - i386aout.o \ - cpu-i386.o \ - coff-go32.o \ - cofflink.o \ - elf32.o \ - binary.o \ - tekhex.o \ - $E - -libbfd.a : $(OBJS) - -rm libbfd.a - ar rvs libbfd.a $(OBJS) - ranlib libbfd.a diff --git a/contrib/gdb/bfd/mipsbsd.c b/contrib/gdb/bfd/mipsbsd.c deleted file mode 100644 index 801f3604338..00000000000 --- a/contrib/gdb/bfd/mipsbsd.c +++ /dev/null @@ -1,467 +0,0 @@ -/* BFD backend for MIPS BSD (a.out) binaries. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Ralph Campbell. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -/* #define ENTRY_CAN_BE_ZERO */ -#define N_HEADER_IN_TEXT(x) 1 -#define N_SHARED_LIB(x) 0 -#define N_TXTADDR(x) \ - (N_MAGIC(x) != ZMAGIC ? (x).a_entry : /* object file or NMAGIC */\ - TEXT_START_ADDR + EXEC_BYTES_SIZE /* no padding */\ - ) -#define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x)) -#define TEXT_START_ADDR 4096 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_mips -#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \ - || (mtype) == M_MIPS1 || (mtype) == M_MIPS2) -#define MY_symbol_leading_char '\0' - -#define MY(OP) CAT(mipsbsd_,OP) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#define SET_ARCH_MACH(ABFD, EXEC) \ - MY(set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ - MY(choose_reloc_size)(ABFD); -void MY(set_arch_mach) PARAMS ((bfd *abfd, int machtype)); -static void MY(choose_reloc_size) PARAMS ((bfd *abfd)); - -#define MY_write_object_contents MY(write_object_contents) -static boolean MY(write_object_contents) PARAMS ((bfd *abfd)); - -/* We can't use MY(x) here because it leads to a recursive call to CAT - when expanded inside JUMP_TABLE. */ -#define MY_bfd_reloc_type_lookup mipsbsd_reloc_howto_type_lookup -#define MY_canonicalize_reloc mipsbsd_canonicalize_reloc - -#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define MY_final_link_callback unused -#define MY_bfd_final_link _bfd_generic_final_link - -#define MY_backend_data &MY(backend_data) -#define MY_BFD_TARGET - -#include "aout-target.h" - -void -MY(set_arch_mach) (abfd, machtype) - bfd *abfd; - int machtype; -{ - enum bfd_architecture arch; - long machine; - - /* Determine the architecture and machine type of the object file. */ - switch (machtype) { - - case M_MIPS1: - arch = bfd_arch_mips; - machine = 3000; - break; - - case M_MIPS2: - arch = bfd_arch_mips; - machine = 4000; - break; - - default: - arch = bfd_arch_obscure; - machine = 0; - break; - } - bfd_set_arch_mach(abfd, arch, machine); -} - -/* Determine the size of a relocation entry, based on the architecture */ -static void -MY(choose_reloc_size) (abfd) - bfd *abfd; -{ - switch (bfd_get_arch(abfd)) { - case bfd_arch_sparc: - case bfd_arch_a29k: - case bfd_arch_mips: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } -} - -/* Write an object file in BSD a.out format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -MY(write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - /* Magic number, maestro, please! */ - switch (bfd_get_arch(abfd)) { - case bfd_arch_m68k: - switch (bfd_get_mach(abfd)) { - case 68010: - N_SET_MACHTYPE(*execp, M_68010); - break; - default: - case 68020: - N_SET_MACHTYPE(*execp, M_68020); - break; - } - break; - case bfd_arch_sparc: - N_SET_MACHTYPE(*execp, M_SPARC); - break; - case bfd_arch_i386: - N_SET_MACHTYPE(*execp, M_386); - break; - case bfd_arch_a29k: - N_SET_MACHTYPE(*execp, M_29K); - break; - case bfd_arch_mips: - switch (bfd_get_mach(abfd)) { - case 4000: - case 6000: - N_SET_MACHTYPE(*execp, M_MIPS2); - break; - default: - N_SET_MACHTYPE(*execp, M_MIPS1); - break; - } - break; - default: - N_SET_MACHTYPE(*execp, M_UNKNOWN); - } - - MY(choose_reloc_size)(abfd); - - WRITE_HEADERS(abfd, execp); - - return true; -} - -/* - * MIPS relocation types. - */ -#define MIPS_RELOC_32 0 -#define MIPS_RELOC_JMP 1 -#define MIPS_RELOC_WDISP16 2 -#define MIPS_RELOC_HI16 3 -#define MIPS_RELOC_HI16_S 4 -#define MIPS_RELOC_LO16 5 - -/* - * This is only called when performing a BFD_RELOC_MIPS_JMP relocation. - * The jump destination address is formed from the upper 4 bits of the - * "current" program counter concatenated with the jump instruction's - * 26 bit field and two trailing zeros. - * If the destination address is not in the same segment as the "current" - * program counter, then we need to signal an error. - */ -static bfd_reloc_status_type -mips_fix_jmp_addr (abfd,reloc_entry,symbol,data,input_section,output_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; -{ - bfd_vma relocation, pc; - - /* If this is a partial relocation, just continue. */ - if (output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - /* If this is an undefined symbol, return error */ - if (bfd_is_und_section (symbol->section) - && (symbol->flags & BSF_WEAK) == 0) - return bfd_reloc_undefined; - - /* - * Work out which section the relocation is targetted at and the - * initial relocation command value. - */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - pc = input_section->output_section->vma + input_section->output_offset + - reloc_entry->address + 4; - - if ((relocation & 0xF0000000) != (pc & 0xF0000000)) - return bfd_reloc_overflow; - - return bfd_reloc_continue; -} - -/* - * This is only called when performing a BFD_RELOC_HI16_S relocation. - * We need to see if bit 15 is set in the result. If it is, we add - * 0x10000 and continue normally. This will compensate for the sign extension - * when the low bits are added at run time. - */ -static bfd_reloc_status_type -mips_fix_hi16_s PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - - /* If this is a partial relocation, just continue. */ - if (output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - /* If this is an undefined symbol, return error */ - if (bfd_is_und_section (symbol->section) - && (symbol->flags & BSF_WEAK) == 0) - return bfd_reloc_undefined; - - /* - * Work out which section the relocation is targetted at and the - * initial relocation command value. - */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (relocation & 0x8000) - reloc_entry->addend += 0x10000; - - return bfd_reloc_continue; -} - -static reloc_howto_type mips_howto_table_ext[] = { - {MIPS_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, - "32", false, 0, 0xffffffff, false}, - {MIPS_RELOC_JMP, 2, 2, 26, false, 0, complain_overflow_dont, - mips_fix_jmp_addr, - "MIPS_JMP", false, 0, 0x03ffffff, false}, - {MIPS_RELOC_WDISP16, 2, 2, 16, true, 0, complain_overflow_signed, 0, - "WDISP16", false, 0, 0x0000ffff, false}, - {MIPS_RELOC_HI16, 16, 2, 16, false, 0, complain_overflow_bitfield, 0, - "HI16", false, 0, 0x0000ffff, false}, - {MIPS_RELOC_HI16_S, 16, 2, 16, false, 0, complain_overflow_bitfield, - mips_fix_hi16_s, - "HI16_S", false, 0, 0x0000ffff, false}, - {MIPS_RELOC_LO16, 0, 2, 16, false, 0, complain_overflow_dont, 0, - "LO16", false, 0, 0x0000ffff, false}, -}; - -static reloc_howto_type * -MY(reloc_howto_type_lookup) (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - - if (bfd_get_arch (abfd) != bfd_arch_mips) - return 0; - - switch (code) - { - case BFD_RELOC_CTOR: - case BFD_RELOC_32: - return (&mips_howto_table_ext[MIPS_RELOC_32]); - case BFD_RELOC_MIPS_JMP: - return (&mips_howto_table_ext[MIPS_RELOC_JMP]); - case BFD_RELOC_16_PCREL_S2: - return (&mips_howto_table_ext[MIPS_RELOC_WDISP16]); - case BFD_RELOC_HI16: - return (&mips_howto_table_ext[MIPS_RELOC_HI16]); - case BFD_RELOC_HI16_S: - return (&mips_howto_table_ext[MIPS_RELOC_HI16_S]); - case BFD_RELOC_LO16: - return (&mips_howto_table_ext[MIPS_RELOC_LO16]); - default: - return 0; - } -} - -/* - * This is just like the standard aoutx.h version but we need to do our - * own mapping of external reloc type values to howto entries. - */ -long -MY(canonicalize_reloc)(abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count, c; - extern reloc_howto_type NAME(aout,ext_howto_table)[]; - - /* If we have already read in the relocation table, return the values. */ - if (section->flags & SEC_CONSTRUCTOR) { - arelent_chain *chain = section->constructor_chain; - - for (count = 0; count < section->reloc_count; count++) { - *relptr++ = &chain->relent; - chain = chain->next; - } - *relptr = 0; - return section->reloc_count; - } - if (tblptr && section->reloc_count) { - for (count = 0; count++ < section->reloc_count;) - *relptr++ = tblptr++; - *relptr = 0; - return section->reloc_count; - } - - if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols)) - return -1; - tblptr = section->relocation; - - /* fix up howto entries */ - for (count = 0; count++ < section->reloc_count;) - { - c = tblptr->howto - NAME(aout,ext_howto_table); - tblptr->howto = &mips_howto_table_ext[c]; - - *relptr++ = tblptr++; - } - *relptr = 0; - return section->reloc_count; -} - -static CONST struct aout_backend_data MY(backend_data) = { - 0, /* zmagic contiguous */ - 1, /* text incl header */ - 0, /* exec_hdr_flags */ - TARGET_PAGE_SIZE, /* text vma */ - MY_set_sizes, - 0, /* text size includes exec header */ - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - -const bfd_target aout_mips_little_vec = -{ - "a.out-mips-little", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* target byte order (little) */ - BFD_ENDIAN_LITTLE, /* target headers byte order (little) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) MY_backend_data, -}; - -const bfd_target aout_mips_big_vec = -{ - "a.out-mips-big", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_BIG, /* target byte order (big) */ - BFD_ENDIAN_BIG, /* target headers byte order (big) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) MY_backend_data, -}; diff --git a/contrib/gdb/bfd/mpw-config.in b/contrib/gdb/bfd/mpw-config.in deleted file mode 100644 index 9195d0e6454..00000000000 --- a/contrib/gdb/bfd/mpw-config.in +++ /dev/null @@ -1,73 +0,0 @@ -# Configuration fragment for BFD. - -# This is almost always correct. - -Set selarchs "&bfd_{target_cpu}_arch" -Set defvec "" -Set selvecs "" - -If "{target_canonical}" =~ /m68k-apple-macos/ - Set BFD_BACKENDS '"{o}"coff-m68k.c.o "{o}"cofflink.c.o' - Set defvec m68kcoff_vec - Set selvecs '&m68kcoff_vec' - -Else If "{target_canonical}" =~ /powerpc-apple-macos/ - Set BFD_BACKENDS '"{o}"coff-pmac.c.o "{o}"xcofflink.c.o' - Set defvec pmac_xcoff_vec - Set selvecs '&pmac_xcoff_vec' - Set selarchs "&bfd_powerpc_arch" - -Else If "{target_canonical}" =~ /i386-unknown-go32/ - Set BFD_BACKENDS '"{o}"coff-i386.c.o' - Set defvec i386coff_vec - Set selvecs '&i386coff_vec' - -Else If "{target_canonical}" =~ /mips-\Option-x-\Option-x/ - Set BFD_BACKENDS '"{o}"coff-mips.c.o "{o}"ecoff.c.o "{o}"ecofflink.c.o' - Set defvec ecoff_big_vec - Set selvecs '&ecoff_big_vec,&ecoff_little_vec' - -Else If "{target_canonical}" =~ /sh-hitachi-hms/ - Set BFD_BACKENDS '"{o}"coff-sh.c.o "{o}"cofflink.c.o' - Set defvec shcoff_vec - Set selvecs '&shcoff_vec,&shlcoff_vec' -End If - -Set ta `echo {selarchs} | sed -e 's/&bfd_/{o}cpu-/g' -e 's/_arch/.c.o/g'` - -Set tdefaults "-d DEFAULT_VECTOR={defvec} -d SELECT_VECS={selvecs} -d SELECT_ARCHITECTURES={selarchs}" - -Echo '# From mpw-config.in' > "{o}"mk.tmp -Echo 'WORDSIZE = 32' >> "{o}"mk.tmp -Echo 'BFD_MACHINES = ' {ta} >> "{o}"mk.tmp -Echo 'BFD_BACKENDS = ' {BFD_BACKENDS} >> "{o}"mk.tmp -Echo 'TDEFAULTS = ' {tdefaults} >> "{o}"mk.tmp -Echo 'HDEPFILES = ' >> "{o}"mk.tmp -Echo 'TDEPFILES = ' >> "{o}"mk.tmp -Echo '# End from mpw-config.in' >> "{o}"mk.tmp - -Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new -Echo '#include "mpw.h"' >> "{o}"config.new - -MoveIfChange "{o}"config.new "{o}"config.h - -# We can only handle 32-bit targets right now. - -sed -e 's/@WORDSIZE@/32/' \Option-d - -e "s/@VERSION@/`Catenate {srcdir}VERSION`/" \Option-d - -e 's/@BFD_HOST_64BIT_LONG@/0/' \Option-d - "{srcdir}"bfd-in2.h >"{o}"bfd.h-new - -MoveIfChange "{o}"bfd.h-new "{o}"bfd.h - -# Pre-expand some macros in coffswap.h, so MPW C doesn't choke. - -sed -e 's/^ PUT_AOUTHDR_TSIZE (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_DSIZE (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_BSIZE (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_ENTRY (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_TEXT_START (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_DATA_START (/ bfd_h_put_32 (/' \Option-d - "{srcdir}"coffswap.h >"{o}"coffswap.h-new - -MoveIfChange "{o}"coffswap.h-new "{o}"coffswap.h diff --git a/contrib/gdb/bfd/mpw-make.sed b/contrib/gdb/bfd/mpw-make.sed deleted file mode 100644 index a989ef005ff..00000000000 --- a/contrib/gdb/bfd/mpw-make.sed +++ /dev/null @@ -1,70 +0,0 @@ -# Sed commands to finish translating the Unix BFD Makefile into MPW syntax. - -# Whack out unused host and target define bits. -/HDEFINES/s/@HDEFINES@// -/TDEFINES/s/@TDEFINES@// - -/INCDIR=/s/"{srcdir}":/"{topsrcdir}"/ -/^CSEARCH = .*$/s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/ - -/WORDSIZE/s/^WORDSIZE = /#WORDSIZE = / -/BFD_MACHINES/s/^BFD_MACHINES = /#BFD_MACHINES = / -/BFD_BACKENDS/s/^BFD_BACKENDS = /#BFD_BACKENDS = / -/TDEFAULTS/s/^TDEFAULTS = /#TDEFAULTS = / - -# Remove extra, useless, "all". -/^all \\Option-f _oldest/,/^$/d - -# Remove the Makefile rebuild rule. -/^Makefile /,/--recheck/d - -# Don't do any recursive subdir stuff. -/ subdir_do/s/{MAKE}/null-command/ - -/BFD_H/s/^{BFD_H}/#{BFD_H}/ - -# Point at include files that are always in the objdir. -/bfd/s/"{s}"bfd\.h/"{o}"bfd.h/g -/config/s/"{s}"config\.h/"{o}"config.h/g -/elf32-target/s/"{s}"elf32-target\.h/"{o}"elf32-target.h/g -/elf64-target/s/"{s}"elf64-target\.h/"{o}"elf64-target.h/g - -/"{s}"{INCDIR}/s/"{s}"{INCDIR}/"{INCDIR}"/g - -/dep/s/\.dep/__dep/g - -# Removing duplicates is cool but presently unnecessary, -# so whack this out. -/^ofiles \\Option-f/,/^$/d -/ofiles/s/{OFILES} ofiles/{OFILES}/ -/echo ofiles = /d -/cat ofiles/s/`cat ofiles`/{OFILES}/ - -# No corefile support. -/COREFILE/s/@COREFILE@// -/COREFLAG/s/@COREFLAG@// - -# No PIC foolery in this environment. -/@ALLLIBS@/s/@ALLLIBS@/{TARGETLIB}/ -/@PICLIST@/s/@PICLIST@// -/@PICFLAG@/s/@PICFLAG@// -/^{OFILES} \\Option-f stamp-picdir/,/^$/d - -# Remove the pic trickery from the default build rule. -/^\.c\.o \\Option-f /,/End If/c\ -.c.o \\Option-f .c - -# MPW Make doesn't know about $<. -/"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile/,/^$/c\ -"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile\ - {CC} {ALL_CFLAGS} {TDEFAULTS} "{s}"targets.c -o "{o}"targets.c.o - -/"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile/,/^$/c\ -"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile\ - {CC} {ALL_CFLAGS} {TDEFAULTS} "{s}"archures.c -o "{o}"archures.c.o - -# Remove the .h rebuilding rules, we don't currently have a doc subdir, -# or a way to build the prototype-hacking tool that's in it. -/^"{srcdir}"bfd-in2.h \\Option-f /,/^$/d -/^"{srcdir}"libbfd.h \\Option-f /,/^$/d -/^"{srcdir}"libcoff.h \\Option-f /,/^$/d diff --git a/contrib/gdb/bfd/netbsd-core.c b/contrib/gdb/bfd/netbsd-core.c deleted file mode 100644 index 4e828679796..00000000000 --- a/contrib/gdb/bfd/netbsd-core.c +++ /dev/null @@ -1,310 +0,0 @@ -/* BFD back end for NetBSD style core files - Copyright 1988, 1989, 1991, 1992, 1993, 1996 Free Software Foundation, Inc. - Written by Paul Kranenburg, EUR - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * FIXME: On NetBSD/sparc CORE_FPU_OFFSET should be (sizeof(struct trapframe)) - */ - -struct netbsd_core_struct { - struct core core; -} *rawptr; - -/* forward declarations */ - -static const bfd_target * netbsd_core_core_file_p PARAMS ((bfd *abfd)); -static char * netbsd_core_core_file_failing_command PARAMS ((bfd *abfd)); -static int netbsd_core_core_file_failing_signal PARAMS ((bfd *abfd)); -static boolean netbsd_core_core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -/* Handle NetBSD-style core dump file. */ - -/* ARGSUSED */ -static const bfd_target * -netbsd_core_core_file_p (abfd) - bfd *abfd; - -{ - int i, val, offset; - asection *asect, *asect2; - struct core core; - struct coreseg coreseg; - - val = bfd_read ((void *)&core, 1, sizeof core, abfd); - if (val != sizeof core) { - /* Too small to be a core file */ - bfd_set_error(bfd_error_wrong_format); - return 0; - } - - if (CORE_GETMAGIC(core) != COREMAGIC) { - bfd_set_error(bfd_error_wrong_format); - return 0; - } - - rawptr = (struct netbsd_core_struct *) - bfd_zalloc (abfd, sizeof (struct netbsd_core_struct)); - if (rawptr == NULL) { - bfd_set_error(bfd_error_no_memory); - return 0; - } - - rawptr->core = core; - abfd->tdata.netbsd_core_data = rawptr; - - offset = core.c_hdrsize; - for (i = 0; i < core.c_nseg; i++) { - - if (bfd_seek (abfd, offset, SEEK_SET) != 0) - goto punt; - - val = bfd_read ((void *)&coreseg, 1, sizeof coreseg, abfd); - if (val != sizeof coreseg) { - bfd_set_error(bfd_error_file_truncated); - goto punt; - } - if (CORE_GETMAGIC(coreseg) != CORESEGMAGIC) { - bfd_set_error(bfd_error_wrong_format); - goto punt; - } - - offset += core.c_seghdrsize; - - asect = (asection *) bfd_zalloc (abfd, sizeof(asection)); - if (asect == NULL) { - bfd_set_error(bfd_error_no_memory); - } - - asect->_raw_size = coreseg.c_size; - asect->vma = coreseg.c_addr; - asect->filepos = offset; - asect->alignment_power = 2; - asect->next = abfd->sections; - abfd->sections = asect; - abfd->section_count++; - offset += coreseg.c_size; - - switch (CORE_GETFLAG(coreseg)) { - case CORE_CPU: - asect->name = ".reg"; - asect->flags = SEC_ALLOC + SEC_HAS_CONTENTS; -#ifdef CORE_FPU_OFFSET - /* Hackish... */ - asect->_raw_size = CORE_FPU_OFFSET; - asect2 = (asection *)bfd_zalloc (abfd, - sizeof (asection)); - if (asect2 == NULL) { - bfd_set_error(bfd_error_no_memory); - goto punt; - } - asect2->_raw_size = coreseg.c_size - CORE_FPU_OFFSET; - asect2->vma = 0; - asect2->filepos = asect->filepos + CORE_FPU_OFFSET; - asect2->alignment_power = 2; - asect2->next = abfd->sections; - asect2->name = ".reg2"; - asect2->flags = SEC_ALLOC + SEC_HAS_CONTENTS; - abfd->sections = asect2; - abfd->section_count++; -#endif - - break; - case CORE_DATA: - asect->name = ".data"; - asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS; - break; - case CORE_STACK: - asect->name = ".stack"; - asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS; - break; - } - } - - /* OK, we believe you. You're a core file (sure, sure). */ - return abfd->xvec; - -punt: { - asection *anext; - for (asect = abfd->sections; asect; asect = anext) { - anext = asect->next; - free((void *)asect); - } - } - free ((void *)rawptr); - abfd->tdata.netbsd_core_data = NULL; - abfd->sections = NULL; - abfd->section_count = 0; - return 0; -} - -static char* -netbsd_core_core_file_failing_command (abfd) - bfd *abfd; -{ - /*return core_command (abfd);*/ - return abfd->tdata.netbsd_core_data->core.c_name; -} - -/* ARGSUSED */ -static int -netbsd_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - /*return core_signal (abfd);*/ - return abfd->tdata.netbsd_core_data->core.c_signo; -} - -/* ARGSUSED */ -static boolean -netbsd_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -/* No archive file support via this BFD */ -#define netbsd_openr_next_archived_file bfd_generic_openr_next_archived_file -#define netbsd_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define netbsd_slurp_armap bfd_false -#define netbsd_slurp_extended_name_table bfd_true -#define netbsd_write_armap (boolean (*) PARAMS \ - ((bfd *arch, unsigned int elength, struct orl *map, \ - unsigned int orl_count, int stridx))) bfd_false -#define netbsd_truncate_arname bfd_dont_truncate_arname -#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file - -#define netbsd_close_and_cleanup bfd_generic_close_and_cleanup -#define netbsd_set_section_contents (boolean (*) PARAMS \ - ((bfd *abfd, asection *section, PTR data, file_ptr offset, \ - bfd_size_type count))) bfd_false -#define netbsd_get_section_contents bfd_generic_get_section_contents -#define netbsd_new_section_hook (boolean (*) PARAMS \ - ((bfd *, sec_ptr))) bfd_true -#define netbsd_get_symtab_upper_bound bfd_0u -#define netbsd_get_symtab (unsigned int (*) PARAMS \ - ((bfd *, struct symbol_cache_entry **))) bfd_0u -#define netbsd_get_reloc_upper_bound (unsigned int (*) PARAMS \ - ((bfd *, sec_ptr))) bfd_0u -#define netbsd_canonicalize_reloc (unsigned int (*) PARAMS \ - ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u -#define netbsd_make_empty_symbol (struct symbol_cache_entry * \ - (*) PARAMS ((bfd *))) bfd_false -#define netbsd_print_symbol (void (*) PARAMS \ - ((bfd *, PTR, struct symbol_cache_entry *, \ - bfd_print_symbol_type))) bfd_false -#define netbsd_get_symbol_info (void (*) PARAMS \ - ((bfd *, struct symbol_cache_entry *, \ - symbol_info *))) bfd_false -#define netbsd_get_lineno (alent * (*) PARAMS \ - ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr -#define netbsd_set_arch_mach (boolean (*) PARAMS \ - ((bfd *, enum bfd_architecture, unsigned long))) bfd_false -#define netbsd_find_nearest_line (boolean (*) PARAMS \ - ((bfd *abfd, struct sec *section, \ - struct symbol_cache_entry **symbols,bfd_vma offset, \ - CONST char **file, CONST char **func, unsigned int *line))) bfd_false -#define netbsd_sizeof_headers (int (*) PARAMS \ - ((bfd *, boolean))) bfd_0 - -#define netbsd_bfd_debug_info_start bfd_void -#define netbsd_bfd_debug_info_end bfd_void -#define netbsd_bfd_debug_info_accumulate (void (*) PARAMS \ - ((bfd *, struct sec *))) bfd_void -#define netbsd_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define netbsd_bfd_relax_section bfd_generic_relax_section -#define netbsd_bfd_seclet_link \ - ((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false) -#define netbsd_bfd_reloc_type_lookup \ - ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr) -#define netbsd_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) - -/* If somebody calls any byte-swapping routines, shoot them. */ -static void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) - -const bfd_target netbsd_core_vec = - { - "netbsd-core", - bfd_target_unknown_flavour, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 3, /* minimum alignment power */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - netbsd_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (netbsd_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/netbsd.h b/contrib/gdb/bfd/netbsd.h deleted file mode 100644 index dd73d37e789..00000000000 --- a/contrib/gdb/bfd/netbsd.h +++ /dev/null @@ -1,108 +0,0 @@ -/* BFD back-end definitions used by all NetBSD targets. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* NetBSD fits its header into the start of its text segment */ -#define N_HEADER_IN_TEXT(x) 1 -#define TEXT_START_ADDR TARGET_PAGE_SIZE - -#define N_MACHTYPE(exec) \ - ((enum machine_type)(((exec).a_info >> 16) & 0x03ff)) -#define N_FLAGS(exec) \ - (((exec).a_info >> 26) & 0x3f) - -#define N_SET_INFO(exec, magic, type, flags) \ - ((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0x3ff) << 16) \ - | (((flags) & 0x3f) << 24)) -#define N_SET_MACHTYPE(exec, machtype) \ - ((exec).a_info = \ - ((exec).a_info & 0xfb00ffff) | ((((int)(machtype))&0x3ff) << 16)) -#define N_SET_FLAGS(exec, flags) \ - ((exec).a_info = \ - ((exec).a_info & 0x03ffffff) | ((flags & 0x03f) << 26)) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -/* On NetBSD, the magic number is always in ntohl's "network" (big-endian) - format. */ -#define SWAP_MAGIC(ext) bfd_getb32 (ext) - - -#define MY_write_object_contents MY(write_object_contents) -static boolean MY(write_object_contents) PARAMS ((bfd *abfd)); -#define MY_text_includes_header 1 - -#include "aout-target.h" - -/* Write an object file. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -MY(write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE(abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - /* Magic number, maestro, please! */ - switch (bfd_get_arch(abfd)) { - case bfd_arch_m68k: - if (strcmp (abfd->xvec->name, "a.out-m68k4k-netbsd") == 0) - N_SET_MACHTYPE(*execp, M_68K4K_NETBSD); - else - N_SET_MACHTYPE(*execp, M_68K_NETBSD); - break; - case bfd_arch_sparc: - N_SET_MACHTYPE(*execp, M_SPARC_NETBSD); - break; - case bfd_arch_i386: - N_SET_MACHTYPE(*execp, M_386_NETBSD); - break; - case bfd_arch_ns32k: - N_SET_MACHTYPE(*execp, M_532_NETBSD); - break; - default: - N_SET_MACHTYPE(*execp, M_UNKNOWN); - break; - } - - /* The NetBSD magic number is always big-endian */ -#ifndef TARGET_IS_BIG_ENDIAN_P - /* XXX aren't there any macro to change byteorder of a word independent of - the host's or target's endianesses? */ - execp->a_info - = (execp->a_info & 0xff) << 24 | (execp->a_info & 0xff00) << 8 - | (execp->a_info & 0xff0000) >> 8 | (execp->a_info & 0xff000000) >> 24; -#endif - - WRITE_HEADERS(abfd, execp); - - return true; -} diff --git a/contrib/gdb/bfd/newsos3.c b/contrib/gdb/bfd/newsos3.c deleted file mode 100644 index 7ec7a75a87c..00000000000 --- a/contrib/gdb/bfd/newsos3.c +++ /dev/null @@ -1,40 +0,0 @@ -/* BFD back-end for NewsOS3 (Sony, 68k) binaries. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0 -#define BYTES_IN_WORD 4 -#define MY(OP) CAT(newsos3_,OP) -#define TARGETNAME "a.out-newsos3" -#define ENTRY_CAN_BE_ZERO -#define N_SHARED_LIB(x) 0 /* Avoids warning when compiled with -Wall. */ -#define DEFAULT_ARCH bfd_arch_m68k -#define TARGET_IS_BIG_ENDIAN_P -#define N_HEADER_IN_TEXT(x) 0 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/nlm-target.h b/contrib/gdb/bfd/nlm-target.h deleted file mode 100644 index cdd3fa8b22e..00000000000 --- a/contrib/gdb/bfd/nlm-target.h +++ /dev/null @@ -1,228 +0,0 @@ -/* Target definitions for 32/64-bit NLM (NetWare Loadable Module) - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define nlm_core_file_p _bfd_dummy_target - -#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound) -#define nlm_get_symtab nlmNAME(get_symtab) -#define nlm_make_empty_symbol nlmNAME(make_empty_symbol) -#define nlm_print_symbol nlmNAME(print_symbol) -#define nlm_get_symbol_info nlmNAME(get_symbol_info) -#define nlm_bfd_is_local_label bfd_generic_is_local_label -#define nlm_get_lineno _bfd_nosymbols_get_lineno -#define nlm_find_nearest_line _bfd_nosymbols_find_nearest_line -#define nlm_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define nlm_read_minisymbols _bfd_generic_read_minisymbols -#define nlm_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound) -#define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc) -#define nlm_bfd_reloc_type_lookup bfd_default_reloc_type_lookup - -#define nlm_set_section_contents nlmNAME(set_section_contents) - -#define nlm_sizeof_headers _bfd_nolink_sizeof_headers -#define nlm_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define nlm_bfd_relax_section bfd_generic_relax_section -#define nlm_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define nlm_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define nlm_bfd_final_link _bfd_generic_final_link -#define nlm_bfd_link_split_section _bfd_generic_link_split_section - -/* This structure contains everything that BFD knows about a target. - It includes things like its byte order, name, what routines to call - to do various operations, etc. Every BFD points to a target structure - with its "xvec" member. - - There are two such structures here: one for big-endian machines and - one for little-endian machines. */ - - -#ifdef TARGET_BIG_SYM -const bfd_target TARGET_BIG_SYM = -{ - /* name: identify kind of target */ - TARGET_BIG_NAME, - - /* flavour: general indication about file */ - bfd_target_nlm_flavour, - - /* byteorder: data is big endian */ - BFD_ENDIAN_BIG, - - /* header_byteorder: header is also big endian */ - BFD_ENDIAN_BIG, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS - | WP_TEXT), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 15, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - nlmNAME(object_p), /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - nlm_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - nlm_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - nlmNAME(write_object_contents), - _bfd_write_archive_contents, - bfd_false - }, - - /* Initialize a jump table with the standard macro. All names start with - "nlm" */ - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (nlm), - BFD_JUMP_TABLE_RELOCS (nlm), - BFD_JUMP_TABLE_WRITE (nlm), - BFD_JUMP_TABLE_LINK (nlm), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - /* backend_data: */ - (PTR) TARGET_BACKEND_DATA -}; -#endif - -#ifdef TARGET_LITTLE_SYM -const bfd_target TARGET_LITTLE_SYM = -{ - /* name: identify kind of target */ - TARGET_LITTLE_NAME, - - /* flavour: general indication about file */ - bfd_target_nlm_flavour, - - /* byteorder: data is little endian */ - BFD_ENDIAN_LITTLE, - - /* header_byteorder: header is also little endian */ - BFD_ENDIAN_LITTLE, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS - | WP_TEXT), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_DATA), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 15, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - nlmNAME(object_p), /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - nlm_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - nlm_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - nlmNAME(write_object_contents), - _bfd_write_archive_contents, - bfd_false - }, - - /* Initialize a jump table with the standard macro. All names start with - "nlm" */ - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (nlm), - BFD_JUMP_TABLE_RELOCS (nlm), - BFD_JUMP_TABLE_WRITE (nlm), - BFD_JUMP_TABLE_LINK (nlm), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - /* backend_data: */ - (PTR) TARGET_BACKEND_DATA -}; -#endif diff --git a/contrib/gdb/bfd/nlm.c b/contrib/gdb/bfd/nlm.c deleted file mode 100644 index 89c6baa64ef..00000000000 --- a/contrib/gdb/bfd/nlm.c +++ /dev/null @@ -1,55 +0,0 @@ -/* NLM (NetWare Loadable Module) executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libnlm.h" - -/* Make an NLM object. We just need to allocate the backend - information. */ - -boolean -nlm_mkobject (abfd) - bfd * abfd; -{ - nlm_tdata (abfd) = - (struct nlm_obj_tdata *) bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)); - if (nlm_tdata (abfd) == NULL) - return (false); - - if (nlm_architecture (abfd) != bfd_arch_unknown) - bfd_default_set_arch_mach (abfd, nlm_architecture (abfd), - nlm_machine (abfd)); - - /* since everything is done at close time, do we need any initialization? */ - return (true); -} - -/* Set the architecture and machine for an NLM object. */ - -boolean -nlm_set_arch_mach (abfd, arch, machine) - bfd * abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - bfd_default_set_arch_mach (abfd, arch, machine); - return arch == nlm_architecture (abfd); -} diff --git a/contrib/gdb/bfd/nlm32-alpha.c b/contrib/gdb/bfd/nlm32-alpha.c deleted file mode 100644 index 24c8e516762..00000000000 --- a/contrib/gdb/bfd/nlm32-alpha.c +++ /dev/null @@ -1,892 +0,0 @@ -/* Support for 32-bit Alpha NLM (NetWare Loadable Module) - Copyright (C) 1993 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file describes the 32 bit Alpha NLM format. You might think - that an Alpha chip would use a 64 bit format, but, for some reason, - it doesn't. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -#include "nlm/alpha-ext.h" -#define Nlm_External_Fixed_Header Nlm32_alpha_External_Fixed_Header - -#include "libnlm.h" - -static boolean nlm_alpha_backend_object_p - PARAMS ((bfd *)); -static boolean nlm_alpha_write_prefix - PARAMS ((bfd *)); -static boolean nlm_alpha_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_alpha_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_alpha_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static boolean nlm_alpha_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_alpha_set_public_section - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static bfd_vma nlm_alpha_get_public_offset - PARAMS ((bfd *, asymbol *)); -static boolean nlm_alpha_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -/* Alpha NLM's have a prefix header before the standard NLM. This - function reads it in, verifies the version, and seeks the bfd to - the location before the regular NLM header. */ - -static boolean -nlm_alpha_backend_object_p (abfd) - bfd *abfd; -{ - struct nlm32_alpha_external_prefix_header s; - bfd_size_type size; - - if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - - if (bfd_h_get_32 (abfd, s.magic) != NLM32_ALPHA_MAGIC) - return false; - - /* FIXME: Should we check the format number? */ - - /* Skip to the end of the header. */ - size = bfd_h_get_32 (abfd, s.size); - if (bfd_seek (abfd, size, SEEK_SET) != 0) - return false; - - return true; -} - -/* Write out the prefix. */ - -static boolean -nlm_alpha_write_prefix (abfd) - bfd *abfd; -{ - struct nlm32_alpha_external_prefix_header s; - - memset (&s, 0, sizeof s); - bfd_h_put_32 (abfd, (bfd_vma) NLM32_ALPHA_MAGIC, s.magic); - bfd_h_put_32 (abfd, (bfd_vma) 2, s.format); - bfd_h_put_32 (abfd, (bfd_vma) sizeof s, s.size); - if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - return true; -} - -/* How to process the various reloc types. */ - -static reloc_howto_type nlm32_alpha_howto_table[] = -{ - /* Reloc type 0 is ignored by itself. However, it appears after a - GPDISP reloc to identify the location where the low order 16 bits - of the gp register are loaded. */ - HOWTO (ALPHA_R_IGNORE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "IGNORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFLONG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFQUAD, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFQUAD", /* name */ - true, /* partial_inplace */ - 0xffffffffffffffff, /* src_mask */ - 0xffffffffffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit GP relative offset. This is just like REFLONG except - that when the value is used the value of the gp register will be - added in. */ - HOWTO (ALPHA_R_GPREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "GPREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Used for an instruction that refers to memory off the GP - register. The offset is 16 bits of the 32 bit instruction. This - reloc always seems to be against the .lita section. */ - HOWTO (ALPHA_R_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* This reloc only appears immediately following a LITERAL reloc. - It identifies a use of the literal. It seems that the linker can - use this to eliminate a portion of the .lita section. The symbol - index is special: 1 means the literal address is in the base - register of a memory format instruction; 2 means the literal - address is in the byte offset register of a byte-manipulation - instruction; 3 means the literal address is in the target - register of a jsr instruction. This does not actually do any - relocation. */ - HOWTO (ALPHA_R_LITUSE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "LITUSE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load the gp register. This is always used for a ldah instruction - which loads the upper 16 bits of the gp register. The next reloc - will be an IGNORE reloc which identifies the location of the lda - instruction which loads the lower 16 bits. The symbol index of - the GPDISP instruction appears to actually be the number of bytes - between the ldah and lda instructions. This gives two different - ways to determine where the lda instruction is; I don't know why - both are used. The value to use for the relocation is the - difference between the GP value and the current location; the - load will always be done against a register holding the current - address. */ - HOWTO (ALPHA_R_GPDISP, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "GPDISP", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* A 21 bit branch. The native assembler generates these for - branches within the text segment, and also fills in the PC - relative offset in the instruction. It seems to me that this - reloc, unlike the others, is not partial_inplace. */ - HOWTO (ALPHA_R_BRADDR, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 21, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "BRADDR", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x1fffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A hint for a jump to a register. */ - HOWTO (ALPHA_R_HINT, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 14, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "HINT", /* name */ - true, /* partial_inplace */ - 0x3fff, /* src_mask */ - 0x3fff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL64, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL64", /* name */ - true, /* partial_inplace */ - 0xffffffffffffffff, /* src_mask */ - 0xffffffffffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Push a value on the reloc evaluation stack. */ - HOWTO (ALPHA_R_OP_PUSH, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PUSH", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Store the value from the stack at the given address. Store it in - a bitfield of size r_size starting at bit position r_offset. */ - HOWTO (ALPHA_R_OP_STORE, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_STORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffffffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Subtract the reloc address from the value on the top of the - relocation stack. */ - HOWTO (ALPHA_R_OP_PSUB, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PSUB", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Shift the value on the top of the relocation stack right by the - given value. */ - HOWTO (ALPHA_R_OP_PRSHIFT, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PRSHIFT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Adjust the GP value for a new range in the object file. */ - HOWTO (ALPHA_R_GPVALUE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "GPVALUE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false) /* pcrel_offset */ -}; - -static reloc_howto_type nlm32_alpha_nw_howto = - HOWTO (ALPHA_R_NW_RELOC, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "NW_RELOC", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false); /* pcrel_offset */ - -/* Read an Alpha NLM reloc. This routine keeps some static data which - it uses when handling local relocs. This only works correctly - because all the local relocs are read at once. */ - -static boolean -nlm_alpha_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - static bfd_vma gp_value; - static bfd_vma lita_address; - struct nlm32_alpha_external_reloc ext; - bfd_vma r_vaddr; - long r_symndx; - int r_type, r_extern, r_offset, r_size; - asection *code_sec, *data_sec; - - /* Read the reloc from the file. */ - if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - /* Swap in the reloc information. */ - r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext.r_vaddr); - r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext.r_symndx); - - BFD_ASSERT (bfd_little_endian (abfd)); - - r_type = ((ext.r_bits[0] & RELOC_BITS0_TYPE_LITTLE) - >> RELOC_BITS0_TYPE_SH_LITTLE); - r_extern = (ext.r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; - r_offset = ((ext.r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) - >> RELOC_BITS1_OFFSET_SH_LITTLE); - /* Ignore the reserved bits. */ - r_size = ((ext.r_bits[3] & RELOC_BITS3_SIZE_LITTLE) - >> RELOC_BITS3_SIZE_SH_LITTLE); - - /* Fill in the BFD arelent structure. */ - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - if (r_extern) - { - /* External relocations are only used for imports. */ - BFD_ASSERT (sym != NULL); - /* We don't need to set sym_ptr_ptr for this case. It is set in - nlm_canonicalize_reloc. */ - rel->sym_ptr_ptr = NULL; - rel->addend = 0; - } - else - { - /* Internal relocations are only used for local relocation - fixups. If they are not NW_RELOC or GPDISP or IGNORE, they - must be against .text or .data. */ - BFD_ASSERT (r_type == ALPHA_R_NW_RELOC || sym == NULL); - if (r_type == ALPHA_R_NW_RELOC - || r_type == ALPHA_R_GPDISP - || r_type == ALPHA_R_IGNORE) - { - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rel->addend = 0; - } - else if (r_symndx == ALPHA_RELOC_SECTION_TEXT) - { - rel->sym_ptr_ptr = code_sec->symbol_ptr_ptr; - BFD_ASSERT (bfd_get_section_vma (abfd, code_sec) == 0); - rel->addend = 0; - } - else if (r_symndx == ALPHA_RELOC_SECTION_DATA) - { - rel->sym_ptr_ptr = data_sec->symbol_ptr_ptr; - rel->addend = - bfd_get_section_vma (abfd, data_sec); - } - else - { - BFD_ASSERT (0); - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rel->addend = 0; - } - } - - /* We use the address to determine whether the reloc is in the .text - or .data section. R_NW_RELOC relocs don't really have a section, - so we put them in .text. */ - if (r_type == ALPHA_R_NW_RELOC - || r_vaddr < bfd_section_size (abfd, code_sec)) - { - *secp = code_sec; - rel->address = r_vaddr; - } - else - { - *secp = data_sec; - rel->address = r_vaddr - bfd_section_size (abfd, code_sec); - } - - /* We must adjust the addend based on the type. */ - BFD_ASSERT ((r_type >= 0 && r_type <= ALPHA_R_GPVALUE) - || r_type == ALPHA_R_NW_RELOC); - - switch (r_type) - { - case ALPHA_R_BRADDR: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - /* The PC relative relocs do not seem to use the section VMA as - a negative addend. */ - rel->addend = 0; - break; - - case ALPHA_R_GPREL32: - /* Copy the gp value for this object file into the addend, to - ensure that we are not confused by the linker. */ - if (! r_extern) - rel->addend += gp_value; - break; - - case ALPHA_R_LITERAL: - BFD_ASSERT (! r_extern); - rel->addend += lita_address; - break; - - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - /* The LITUSE and GPDISP relocs do not use a symbol, or an - addend, but they do use a special code. Put this code in the - addend field. */ - rel->addend = r_symndx; - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - break; - - case ALPHA_R_OP_STORE: - /* The STORE reloc needs the size and offset fields. We store - them in the addend. */ - BFD_ASSERT (r_offset < 256 && r_size < 256); - rel->addend = (r_offset << 8) + r_size; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - /* The PUSH, PSUB and PRSHIFT relocs do not actually use an - address. I believe that the address supplied is really an - addend. */ - rel->addend = r_vaddr; - break; - - case ALPHA_R_GPVALUE: - /* Record the new gp value. */ - gp_value += r_symndx; - rel->addend = gp_value; - break; - - case ALPHA_R_IGNORE: - /* If the type is ALPHA_R_IGNORE, make sure this is a reference - to the absolute section so that the reloc is ignored. For - some reason the address of this reloc type is not adjusted by - the section vma. We record the gp value for this object file - here, for convenience when doing the GPDISP relocation. */ - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rel->address = r_vaddr; - rel->addend = gp_value; - break; - - case ALPHA_R_NW_RELOC: - /* If this is SETGP, we set the addend to 0. Otherwise we set - the addend to the size of the .lita section (this is - r_symndx) plus 1. We have already set the address of the - reloc to r_vaddr. */ - if (r_size == ALPHA_R_NW_RELOC_SETGP) - { - gp_value = r_vaddr; - rel->addend = 0; - } - else if (r_size == ALPHA_R_NW_RELOC_LITA) - { - lita_address = r_vaddr; - rel->addend = r_symndx + 1; - } - else - BFD_ASSERT (0); - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - break; - - default: - break; - } - - if (r_type == ALPHA_R_NW_RELOC) - rel->howto = &nlm32_alpha_nw_howto; - else - rel->howto = &nlm32_alpha_howto_table[r_type]; - - return true; -} - -/* Mangle Alpha NLM relocs for output. */ - -static boolean -nlm_alpha_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - return true; -} - -/* Read an ALPHA NLM import record */ - -static boolean -nlm_alpha_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return false; - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - if (bfd_read (name, symlength, 1, abfd) != symlength) - return false; - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - rcount = bfd_h_get_32 (abfd, temp); - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (!nlm_relocs) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_alpha_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - - return true; -} - -/* Write an Alpha NLM reloc. */ - -static boolean -nlm_alpha_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - asymbol *sym; - bfd_vma r_vaddr; - long r_symndx; - int r_type, r_extern, r_offset, r_size; - struct nlm32_alpha_external_reloc ext; - - sym = *rel->sym_ptr_ptr; - - /* Get values for the relocation fields. */ - r_type = rel->howto->type; - if (r_type != ALPHA_R_NW_RELOC) - { - r_vaddr = bfd_get_section_vma (abfd, sec) + rel->address; - if ((sec->flags & SEC_CODE) == 0) - r_vaddr += bfd_section_size (abfd, - bfd_get_section_by_name (abfd, - NLM_CODE_NAME)); - if (bfd_is_und_section (bfd_get_section (sym))) - { - r_extern = 1; - r_symndx = 0; - } - else - { - r_extern = 0; - if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE) - r_symndx = ALPHA_RELOC_SECTION_TEXT; - else - r_symndx = ALPHA_RELOC_SECTION_DATA; - } - r_offset = 0; - r_size = 0; - - switch (r_type) - { - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - r_symndx = rel->addend; - break; - - case ALPHA_R_OP_STORE: - r_size = rel->addend & 0xff; - r_offset = (rel->addend >> 8) & 0xff; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - r_vaddr = rel->addend; - break; - - case ALPHA_R_IGNORE: - r_vaddr = rel->address; - break; - - default: - break; - } - } - else - { - /* r_type == ALPHA_R_NW_RELOC */ - r_vaddr = rel->address; - if (rel->addend == 0) - { - r_symndx = 0; - r_size = ALPHA_R_NW_RELOC_SETGP; - } - else - { - r_symndx = rel->addend - 1; - r_size = ALPHA_R_NW_RELOC_LITA; - } - r_extern = 0; - r_offset = 0; - } - - /* Swap out the relocation fields. */ - bfd_h_put_64 (abfd, r_vaddr, (bfd_byte *) ext.r_vaddr); - bfd_h_put_32 (abfd, r_symndx, (bfd_byte *) ext.r_symndx); - - BFD_ASSERT (bfd_little_endian (abfd)); - - ext.r_bits[0] = ((r_type << RELOC_BITS0_TYPE_SH_LITTLE) - & RELOC_BITS0_TYPE_LITTLE); - ext.r_bits[1] = ((r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0) - | ((r_offset << RELOC_BITS1_OFFSET_SH_LITTLE) - & RELOC_BITS1_OFFSET_LITTLE)); - ext.r_bits[2] = 0; - ext.r_bits[3] = ((r_size << RELOC_BITS3_SIZE_SH_LITTLE) - & RELOC_BITS3_SIZE_LITTLE); - - /* Write out the relocation. */ - if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - return true; -} - -/* Alpha NetWare does not use the high bit to determine whether a - public symbol is in the code segment or the data segment. Instead, - it just uses the address. The set_public_section and - get_public_offset routines override the default code which uses the - high bit. */ - -/* Set the section for a public symbol. */ - -static boolean -nlm_alpha_set_public_section (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - asection *code_sec, *data_sec; - - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - if (sym->symbol.value < bfd_section_size (abfd, code_sec)) - { - sym->symbol.section = code_sec; - sym->symbol.flags |= BSF_FUNCTION; - } - else - { - sym->symbol.section = data_sec; - sym->symbol.value -= bfd_section_size (abfd, code_sec); - /* The data segment had better be aligned. */ - BFD_ASSERT ((bfd_section_size (abfd, code_sec) & 0xf) == 0); - } - return true; -} - -/* Get the offset to write out for a public symbol. */ - -static bfd_vma -nlm_alpha_get_public_offset (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return bfd_asymbol_value (sym); -} - -/* Write an Alpha NLM external symbol. */ - -static boolean -nlm_alpha_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; - arelent r; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - bfd_put_32 (abfd, count + 2, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - /* The first two relocs for each external symbol are the .lita - address and the GP value. */ - r.sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - r.howto = &nlm32_alpha_nw_howto; - - r.address = nlm_alpha_backend_data (abfd)->lita_address; - r.addend = nlm_alpha_backend_data (abfd)->lita_size + 1; - if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false) - return false; - - r.address = nlm_alpha_backend_data (abfd)->gp; - r.addend = 0; - if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false) - return false; - - for (i = 0; i < count; i++) - { - if (nlm_alpha_write_import (abfd, relocs[i].sec, - relocs[i].rel) == false) - return false; - } - - return true; -} - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_alpha_backend = -{ - "NetWare Alpha Module \032", - sizeof (Nlm32_alpha_External_Fixed_Header), - sizeof (struct nlm32_alpha_external_prefix_header), - bfd_arch_alpha, - 0, - true, /* no uninitialized data permitted by Alpha NetWare. */ - nlm_alpha_backend_object_p, - nlm_alpha_write_prefix, - nlm_alpha_read_reloc, - nlm_alpha_mangle_relocs, - nlm_alpha_read_import, - nlm_alpha_write_import, - nlm_alpha_set_public_section, - nlm_alpha_get_public_offset, - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_alpha_write_external, - 0, /* write_export */ -}; - -#define TARGET_LITTLE_NAME "nlm32-alpha" -#define TARGET_LITTLE_SYM nlmNAME(alpha_vec) -#define TARGET_BACKEND_DATA &nlm32_alpha_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32-i386.c b/contrib/gdb/bfd/nlm32-i386.c deleted file mode 100644 index f16c74d985e..00000000000 --- a/contrib/gdb/bfd/nlm32-i386.c +++ /dev/null @@ -1,451 +0,0 @@ -/* Support for 32-bit i386 NLM (NetWare Loadable Module) - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -#include "nlm/i386-ext.h" -#define Nlm_External_Fixed_Header Nlm32_i386_External_Fixed_Header - -#include "libnlm.h" - -static boolean nlm_i386_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_i386_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_i386_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_i386_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static boolean nlm_i386_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -/* Adjust the reloc location by an absolute value. */ - -static reloc_howto_type nlm_i386_abs_howto = - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false); /* pcrel_offset */ - -/* Adjust the reloc location by a PC relative displacement. */ - -static reloc_howto_type nlm_i386_pcrel_howto = - HOWTO (1, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "DISP32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true); /* pcrel_offset */ - -/* Read a NetWare i386 reloc. */ - -static boolean -nlm_i386_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - bfd_byte temp[4]; - bfd_vma val; - const char *name; - - if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - val = bfd_get_32 (abfd, temp); - - /* The value is an offset into either the code or data segment. - This is the location which needs to be adjusted. - - If this is a relocation fixup rather than an imported symbol (the - sym argument is NULL) then the high bit is 0 if the location - needs to be adjusted by the address of the data segment, or 1 if - the location needs to be adjusted by the address of the code - segment. If this is an imported symbol, then the high bit is 0 - if the location is 0 if the location should be adjusted by the - offset to the symbol, or 1 if the location should adjusted by the - absolute value of the symbol. - - The second most significant bit is 0 if the value is an offset - into the data segment, or 1 if the value is an offset into the - code segment. - - All this translates fairly easily into a BFD reloc. */ - - if (sym == NULL) - { - if ((val & NLM_HIBIT) == 0) - name = NLM_INITIALIZED_DATA_NAME; - else - { - name = NLM_CODE_NAME; - val &=~ NLM_HIBIT; - } - rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr; - rel->howto = &nlm_i386_abs_howto; - } - else - { - /* In this case we do not need to set the sym_ptr_ptr field. */ - rel->sym_ptr_ptr = NULL; - if ((val & NLM_HIBIT) == 0) - rel->howto = &nlm_i386_pcrel_howto; - else - { - rel->howto = &nlm_i386_abs_howto; - val &=~ NLM_HIBIT; - } - } - - if ((val & (NLM_HIBIT >> 1)) == 0) - *secp = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - else - { - *secp = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - val &=~ (NLM_HIBIT >> 1); - } - - rel->address = val; - rel->addend = 0; - - return true; -} - -/* Write a NetWare i386 reloc. */ - -static boolean -nlm_i386_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - asymbol *sym; - bfd_vma val; - bfd_byte temp[4]; - - /* NetWare only supports two kinds of relocs. We should check - special_function here, as well, but at the moment coff-i386 - relocs uses a special_function which does not affect what we do - here. */ - if (rel->addend != 0 - || rel->howto == NULL - || rel->howto->rightshift != 0 - || rel->howto->size != 2 - || rel->howto->bitsize != 32 - || rel->howto->bitpos != 0 - || rel->howto->src_mask != 0xffffffff - || rel->howto->dst_mask != 0xffffffff) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - sym = *rel->sym_ptr_ptr; - - /* The value we write out is the offset into the appropriate - segment. This offset is the section vma, adjusted by the vma of - the lowest section in that segment, plus the address of the - relocation. */ - val = bfd_get_section_vma (abfd, sec) + rel->address; - - /* The second most significant bit is 0 if the value is an offset - into the data segment, or 1 if the value is an offset into the - code segment. */ - if (bfd_get_section_flags (abfd, sec) & SEC_CODE) - { - val -= nlm_get_text_low (abfd); - val |= NLM_HIBIT >> 1; - } - else - val -= nlm_get_data_low (abfd); - - if (! bfd_is_und_section (bfd_get_section (sym))) - { - /* NetWare only supports absolute internal relocs. */ - if (rel->howto->pc_relative) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* The high bit is 1 if the reloc is against the code section, 0 - if against the data section. */ - if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE) - val |= NLM_HIBIT; - } - else - { - /* The high bit is 1 if this is an absolute reloc, 0 if it is PC - relative. */ - if (! rel->howto->pc_relative) - val |= NLM_HIBIT; - else - { - /* PC relative relocs on NetWare must be pcrel_offset. */ - if (! rel->howto->pcrel_offset) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - } - } - - bfd_put_32 (abfd, val, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - return true; -} - -/* I want to be able to use objcopy to turn a i386 a.out or COFF file - into a NetWare i386 module. That means that the relocs from the - source file have to be mapped into relocs that apply to the target - file. This function is called by nlm_set_section_contents to give - it a chance to rework the relocs. - - This is actually a fairly general concept. However, this is not a - general implementation. */ - -static boolean -nlm_i386_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - arelent **rel_ptr_ptr, **rel_end; - - rel_ptr_ptr = sec->orelocation; - rel_end = rel_ptr_ptr + sec->reloc_count; - for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++) - { - arelent *rel; - asymbol *sym; - bfd_vma addend; - - rel = *rel_ptr_ptr; - sym = *rel->sym_ptr_ptr; - - /* Note that no serious harm will ensue if we fail to change a - reloc. We will wind up failing in nlm_i386_write_import. */ - - /* Make sure this reloc is within the data we have. We only 4 - byte relocs here, so we insist on having 4 bytes. */ - if (rel->address < offset - || rel->address + 4 > offset + count) - continue; - - /* NetWare doesn't support reloc addends, so we get rid of them - here by simply adding them into the object data. We handle - the symbol value, if any, the same way. */ - addend = rel->addend + sym->value; - - /* The value of a symbol is the offset into the section. If the - symbol is in the .bss segment, we need to include the size of - the data segment in the offset as well. Fortunately, we know - that at this point the size of the data section is in the NLM - header. */ - if (((bfd_get_section_flags (abfd, bfd_get_section (sym)) - & SEC_LOAD) == 0) - && ((bfd_get_section_flags (abfd, bfd_get_section (sym)) - & SEC_ALLOC) != 0)) - addend += nlm_fixed_header (abfd)->dataImageSize; - - if (addend != 0 - && rel->howto != NULL - && rel->howto->rightshift == 0 - && rel->howto->size == 2 - && rel->howto->bitsize == 32 - && rel->howto->bitpos == 0 - && rel->howto->src_mask == 0xffffffff - && rel->howto->dst_mask == 0xffffffff) - { - bfd_vma val; - - val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset); - val += addend; - bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset); - rel->addend = 0; - } - - /* NetWare uses a reloc with pcrel_offset set. We adjust - pc_relative relocs accordingly. We are going to change the - howto field, so we can only do this if the current one is - compatible. We should check special_function here, but at - the moment coff-i386 uses a special_function which does not - affect what we are doing here. */ - if (rel->howto != NULL - && rel->howto->pc_relative - && ! rel->howto->pcrel_offset - && rel->howto->rightshift == 0 - && rel->howto->size == 2 - && rel->howto->bitsize == 32 - && rel->howto->bitpos == 0 - && rel->howto->src_mask == 0xffffffff - && rel->howto->dst_mask == 0xffffffff) - { - bfd_vma val; - - /* When pcrel_offset is not set, it means that the negative - of the address of the memory location is stored in the - memory location. We must add it back in. */ - val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset); - val += rel->address; - bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset); - - rel->howto = &nlm_i386_pcrel_howto; - } - } - - return true; -} - -/* Read a NetWare i386 import record */ -static boolean -nlm_i386_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return false; - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - if (bfd_read (name, symlength, 1, abfd) != symlength) - return false; - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - rcount = bfd_h_get_32 (abfd, temp); - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (!nlm_relocs) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_i386_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - return true; -} - -/* Write out an external reference. */ - -static boolean -nlm_i386_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - unsigned int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - bfd_put_32 (abfd, count, temp); - if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp)) - return false; - - for (i = 0; i < count; i++) - { - if (nlm_i386_write_import (abfd, relocs[i].sec, - relocs[i].rel) == false) - return false; - } - - return true; -} - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_i386_backend = -{ - "NetWare Loadable Module\032", - sizeof (Nlm32_i386_External_Fixed_Header), - 0, /* optional_prefix_size */ - bfd_arch_i386, - 0, - false, - 0, /* backend_object_p */ - 0, /* write_prefix_func */ - nlm_i386_read_reloc, - nlm_i386_mangle_relocs, - nlm_i386_read_import, - nlm_i386_write_import, - 0, /* set_public_section */ - 0, /* get_public_offset */ - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_i386_write_external, - 0, /* write_export */ -}; - -#define TARGET_LITTLE_NAME "nlm32-i386" -#define TARGET_LITTLE_SYM nlmNAME(i386_vec) -#define TARGET_BACKEND_DATA &nlm32_i386_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32-ppc.c b/contrib/gdb/bfd/nlm32-ppc.c deleted file mode 100644 index ecf2de8f10b..00000000000 --- a/contrib/gdb/bfd/nlm32-ppc.c +++ /dev/null @@ -1,1045 +0,0 @@ -/* Support for 32-bit PowerPC NLM (NetWare Loadable Module) - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* The format of a PowerPC NLM changed. Define OLDFORMAT to get the - old format. */ - -#define ARCH_SIZE 32 - -#include "nlm/ppc-ext.h" -#define Nlm_External_Fixed_Header Nlm32_powerpc_External_Fixed_Header - -#include "libnlm.h" - -#ifdef OLDFORMAT -static boolean nlm_powerpc_backend_object_p - PARAMS ((bfd *)); -static boolean nlm_powerpc_write_prefix - PARAMS ((bfd *)); -#endif - -static boolean nlm_powerpc_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_powerpc_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_powerpc_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); - -#ifdef OLDFORMAT -static boolean nlm_powerpc_write_reloc - PARAMS ((bfd *, asection *, arelent *, int)); -#endif - -static boolean nlm_powerpc_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_powerpc_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -#ifndef OLDFORMAT -static boolean nlm_powerpc_set_public_section - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static bfd_vma nlm_powerpc_get_public_offset - PARAMS ((bfd *, asymbol *)); -#endif - -#ifdef OLDFORMAT - -/* The prefix header is only used in the old format. */ - -/* PowerPC NLM's have a prefix header before the standard NLM. This - function reads it in, verifies the version, and seeks the bfd to - the location before the regular NLM header. */ - -static boolean -nlm_powerpc_backend_object_p (abfd) - bfd *abfd; -{ - struct nlm32_powerpc_external_prefix_header s; - - if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - - if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0 - || bfd_h_get_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION) - return false; - - return true; -} - -/* Write out the prefix. */ - -static boolean -nlm_powerpc_write_prefix (abfd) - bfd *abfd; -{ - struct nlm32_powerpc_external_prefix_header s; - - memset (&s, 0, sizeof s); - memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature); - bfd_h_put_32 (abfd, (bfd_vma) NLM32_POWERPC_HEADER_VERSION, s.headerVersion); - bfd_h_put_32 (abfd, (bfd_vma) 0, s.origins); - - /* FIXME: What should we do about the date? */ - - if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - - return true; -} - -#endif /* OLDFORMAT */ - -#ifndef OLDFORMAT - -/* There is only one type of reloc in a PowerPC NLM. */ - -static reloc_howto_type nlm_powerpc_howto = - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false); /* pcrel_offset */ - -/* Read a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - bfd_byte temp[4]; - bfd_vma val; - const char *name; - - if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - val = bfd_get_32 (abfd, temp); - - /* The value is a word offset into either the code or data segment. - This is the location which needs to be adjusted. - - The high bit is 0 if the value is an offset into the data - segment, or 1 if the value is an offset into the text segment. - - If this is a relocation fixup rather than an imported symbol (the - sym argument is NULL), then the second most significant bit is 0 - if the address of the data segment should be added to the - location addressed by the value, or 1 if the address of the text - segment should be added. - - If this is an imported symbol, the second most significant bit is - not used and must be 0. */ - - if ((val & NLM_HIBIT) == 0) - name = NLM_INITIALIZED_DATA_NAME; - else - { - name = NLM_CODE_NAME; - val &=~ NLM_HIBIT; - } - *secp = bfd_get_section_by_name (abfd, name); - - if (sym == NULL) - { - if ((val & (NLM_HIBIT >> 1)) == 0) - name = NLM_INITIALIZED_DATA_NAME; - else - { - name = NLM_CODE_NAME; - val &=~ (NLM_HIBIT >> 1); - } - rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr; - } - - rel->howto = &nlm_powerpc_howto; - - rel->address = val << 2; - rel->addend = 0; - - return true; -} - -#else /* OLDFORMAT */ - -/* This reloc handling is only applicable to the old format. */ - -/* How to process the various reloc types. PowerPC NLMs use XCOFF - reloc types, and I have just copied the XCOFF reloc table here. */ - -static reloc_howto_type nlm_powerpc_howto_table[] = -{ - /* Standard 32 bit relocation. */ - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_POS", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit relocation, but store negative value. */ - HOWTO (1, /* type */ - 0, /* rightshift */ - -2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_NEG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative relocation. */ - HOWTO (2, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit TOC relative relocation. */ - HOWTO (3, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_TOC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* I don't really know what this is. */ - HOWTO (4, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RTB", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* External TOC relative symbol. */ - HOWTO (5, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_GL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Local TOC relative symbol. */ - HOWTO (6, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TCL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 7 }, - - /* Non modifiable absolute branch. */ - HOWTO (8, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_BA", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 9 }, - - /* Non modifiable relative branch. */ - HOWTO (0xa, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_BR", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xb }, - - /* Indirect load. */ - HOWTO (0xc, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load address. */ - HOWTO (0xd, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xe }, - - /* Non-relocating reference. */ - HOWTO (0xf, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REF", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - { 0x10 }, - { 0x11 }, - - /* TOC relative indirect load. */ - HOWTO (0x12, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* TOC relative load address. */ - HOWTO (0x13, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable relative branch. */ - HOWTO (0x14, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBI", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable absolute branch. */ - HOWTO (0x15, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBA", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call absolute indirect. */ - HOWTO (0x16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_CAI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call relative. */ - HOWTO (0x17, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x18, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x19, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBAC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch relative. */ - HOWTO (0x1a, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x1b, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -#define HOWTO_COUNT (sizeof nlm_powerpc_howto_table \ - / sizeof nlm_powerpc_howto_table[0]) - -/* Read a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - struct nlm32_powerpc_external_reloc ext; - bfd_vma l_vaddr; - unsigned long l_symndx; - int l_rtype; - int l_rsecnm; - asection *code_sec, *data_sec, *bss_sec; - - /* Read the reloc from the file. */ - if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - /* Swap in the fields. */ - l_vaddr = bfd_h_get_32 (abfd, ext.l_vaddr); - l_symndx = bfd_h_get_32 (abfd, ext.l_symndx); - l_rtype = bfd_h_get_16 (abfd, ext.l_rtype); - l_rsecnm = bfd_h_get_16 (abfd, ext.l_rsecnm); - - /* Get the sections now, for convenience. */ - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - - /* Work out the arelent fields. */ - if (sym != NULL) - { - /* This is an import. sym_ptr_ptr is filled in by - nlm_canonicalize_reloc. */ - rel->sym_ptr_ptr = NULL; - } - else - { - asection *sec; - - if (l_symndx == 0) - sec = code_sec; - else if (l_symndx == 1) - sec = data_sec; - else if (l_symndx == 2) - sec = bss_sec; - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - rel->sym_ptr_ptr = sec->symbol_ptr_ptr; - } - - rel->addend = 0; - - BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT); - - rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff); - - BFD_ASSERT (rel->howto->name != NULL - && ((l_rtype & 0x8000) != 0 - ? (rel->howto->complain_on_overflow - == complain_overflow_signed) - : (rel->howto->complain_on_overflow - == complain_overflow_bitfield)) - && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1); - - if (l_rsecnm == 0) - *secp = code_sec; - else if (l_rsecnm == 1) - { - *secp = data_sec; - l_vaddr -= bfd_section_size (abfd, code_sec); - } - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - rel->address = l_vaddr; - - return true; -} - -#endif /* OLDFORMAT */ - -/* Mangle PowerPC NLM relocs for output. */ - -static boolean -nlm_powerpc_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - return true; -} - -/* Read a PowerPC NLM import record */ - -static boolean -nlm_powerpc_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return (false); - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - if (bfd_read (name, symlength, 1, abfd) != symlength) - return (false); - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - rcount = bfd_h_get_32 (abfd, temp); - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (nlm_relocs == (struct nlm_relent *) NULL) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_powerpc_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - return true; -} - -#ifndef OLDFORMAT - -/* Write a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - asymbol *sym; - bfd_vma val; - bfd_byte temp[4]; - - /* PowerPC NetWare only supports one kind of reloc. */ - if (rel->addend != 0 - || rel->howto == NULL - || rel->howto->rightshift != 0 - || rel->howto->size != 2 - || rel->howto->bitsize != 32 - || rel->howto->bitpos != 0 - || rel->howto->pc_relative - || (rel->howto->src_mask != 0xffffffff && rel->addend != 0) - || rel->howto->dst_mask != 0xffffffff) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - sym = *rel->sym_ptr_ptr; - - /* The value we write out is the offset into the appropriate - segment, rightshifted by two. This offset is the section vma, - adjusted by the vma of the lowest section in that segment, plus - the address of the relocation. */ - val = bfd_get_section_vma (abfd, sec) + rel->address; - if ((val & 3) != 0) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - val >>= 2; - - /* The high bit is 0 if the reloc is in the data section, or 1 if - the reloc is in the code section. */ - if (bfd_get_section_flags (abfd, sec) & SEC_DATA) - val -= nlm_get_data_low (abfd); - else - { - val -= nlm_get_text_low (abfd); - val |= NLM_HIBIT; - } - - if (! bfd_is_und_section (bfd_get_section (sym))) - { - /* This is an internal relocation fixup. The second most - significant bit is 0 if this is a reloc against the data - segment, or 1 if it is a reloc against the text segment. */ - if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE) - val |= NLM_HIBIT >> 1; - } - - bfd_put_32 (abfd, val, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - return true; -} - -#else /* OLDFORMAT */ - -/* This is used for the reloc handling in the old format. */ - -/* Write a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_write_reloc (abfd, sec, rel, indx) - bfd *abfd; - asection *sec; - arelent *rel; - int indx; -{ - struct nlm32_powerpc_external_reloc ext; - asection *code_sec, *data_sec, *bss_sec; - asymbol *sym; - asection *symsec; - unsigned long l_symndx; - int l_rtype; - int l_rsecnm; - reloc_howto_type *howto; - bfd_size_type address; - - /* Get the sections now, for convenience. */ - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - - sym = *rel->sym_ptr_ptr; - symsec = bfd_get_section (sym); - if (indx != -1) - { - BFD_ASSERT (bfd_is_und_section (symsec)); - l_symndx = indx + 3; - } - else - { - if (symsec == code_sec) - l_symndx = 0; - else if (symsec == data_sec) - l_symndx = 1; - else if (symsec == bss_sec) - l_symndx = 2; - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - bfd_h_put_32 (abfd, (bfd_vma) l_symndx, ext.l_symndx); - - for (howto = nlm_powerpc_howto_table; - howto < nlm_powerpc_howto_table + HOWTO_COUNT; - howto++) - { - if (howto->rightshift == rel->howto->rightshift - && howto->size == rel->howto->size - && howto->bitsize == rel->howto->bitsize - && howto->pc_relative == rel->howto->pc_relative - && howto->bitpos == rel->howto->bitpos - && (howto->partial_inplace == rel->howto->partial_inplace - || (! rel->howto->partial_inplace - && rel->addend == 0)) - && (howto->src_mask == rel->howto->src_mask - || (rel->howto->src_mask == 0 - && rel->addend == 0)) - && howto->dst_mask == rel->howto->dst_mask - && howto->pcrel_offset == rel->howto->pcrel_offset) - break; - } - if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - l_rtype = howto->type; - if (howto->complain_on_overflow == complain_overflow_signed) - l_rtype |= 0x8000; - l_rtype |= (howto->bitsize - 1) << 8; - bfd_h_put_16 (abfd, (bfd_vma) l_rtype, ext.l_rtype); - - address = rel->address; - - if (sec == code_sec) - l_rsecnm = 0; - else if (sec == data_sec) - { - l_rsecnm = 1; - address += bfd_section_size (abfd, code_sec); - } - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - bfd_h_put_16 (abfd, (bfd_vma) l_rsecnm, ext.l_rsecnm); - bfd_h_put_32 (abfd, (bfd_vma) address, ext.l_vaddr); - - if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - return true; -} - -/* Write a PowerPC NLM import. */ - -static boolean -nlm_powerpc_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - return nlm_powerpc_write_reloc (abfd, sec, rel, -1); -} - -#endif /* OLDFORMAT */ - -/* Write a PowerPC NLM external symbol. This routine keeps a static - count of the symbol index. FIXME: I don't know if this is - necessary, and the index never gets reset. */ - -static boolean -nlm_powerpc_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - unsigned int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; -#ifdef OLDFORMAT - static int indx; -#endif - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - bfd_put_32 (abfd, count, temp); - if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp)) - return false; - - for (i = 0; i < count; i++) - { -#ifndef OLDFORMAT - if (! nlm_powerpc_write_import (abfd, relocs[i].sec, relocs[i].rel)) - return false; -#else - if (! nlm_powerpc_write_reloc (abfd, relocs[i].sec, - relocs[i].rel, indx)) - return false; -#endif - } - -#ifdef OLDFORMAT - ++indx; -#endif - - return true; -} - -#ifndef OLDFORMAT - -/* PowerPC Netware uses a word offset, not a byte offset, for public - symbols. */ - -/* Set the section for a public symbol. */ - -static boolean -nlm_powerpc_set_public_section (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - if (sym->symbol.value & NLM_HIBIT) - { - sym->symbol.value &= ~NLM_HIBIT; - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_CODE_NAME); - } - else - { - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - } - - sym->symbol.value <<= 2; - - return true; -} - -/* Get the offset to write out for a public symbol. */ - -static bfd_vma -nlm_powerpc_get_public_offset (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - bfd_vma offset; - asection *sec; - - offset = bfd_asymbol_value (sym); - sec = bfd_get_section (sym); - if (sec->flags & SEC_CODE) - { - offset -= nlm_get_text_low (abfd); - offset |= NLM_HIBIT; - } - else if (sec->flags & (SEC_DATA | SEC_ALLOC)) - { - /* SEC_ALLOC is for the .bss section. */ - offset -= nlm_get_data_low (abfd); - } - else - { - /* We can't handle an exported symbol that is not in the code or - data segment. */ - bfd_set_error (bfd_error_invalid_operation); - /* FIXME: No way to return error. */ - abort (); - } - - return offset; -} - -#endif /* ! defined (OLDFORMAT) */ - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_powerpc_backend = -{ - "NetWare PowerPC Module \032", - sizeof (Nlm32_powerpc_External_Fixed_Header), -#ifndef OLDFORMAT - 0, /* optional_prefix_size */ -#else - sizeof (struct nlm32_powerpc_external_prefix_header), -#endif - bfd_arch_powerpc, - 0, - false, -#ifndef OLDFORMAT - 0, /* backend_object_p */ - 0, /* write_prefix */ -#else - nlm_powerpc_backend_object_p, - nlm_powerpc_write_prefix, -#endif - nlm_powerpc_read_reloc, - nlm_powerpc_mangle_relocs, - nlm_powerpc_read_import, - nlm_powerpc_write_import, -#ifndef OLDFORMAT - nlm_powerpc_set_public_section, - nlm_powerpc_get_public_offset, -#else - 0, /* set_public_section */ - 0, /* get_public_offset */ -#endif - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_powerpc_write_external, - 0, /* write_export */ -}; - -#define TARGET_BIG_NAME "nlm32-powerpc" -#define TARGET_BIG_SYM nlmNAME(powerpc_vec) -#define TARGET_BACKEND_DATA &nlm32_powerpc_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32-sparc.c b/contrib/gdb/bfd/nlm32-sparc.c deleted file mode 100644 index 5963adbc70b..00000000000 --- a/contrib/gdb/bfd/nlm32-sparc.c +++ /dev/null @@ -1,440 +0,0 @@ -/* Support for 32-bit SPARC NLM (NetWare Loadable Module) - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -#include "nlm/sparc32-ext.h" -#define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header - -#include "libnlm.h" - -static boolean nlm_sparc_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_sparc_write_reloc - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_sparc_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_sparc_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static boolean nlm_sparc_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_sparc_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -enum reloc_type - { - R_SPARC_NONE = 0, - R_SPARC_8, R_SPARC_16, R_SPARC_32, - R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32, - R_SPARC_WDISP30, R_SPARC_WDISP22, - R_SPARC_HI22, R_SPARC_22, - R_SPARC_13, R_SPARC_LO10, - R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22, - R_SPARC_PC10, R_SPARC_PC22, - R_SPARC_WPLT30, - R_SPARC_COPY, - R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT, - R_SPARC_RELATIVE, - R_SPARC_UA32, - R_SPARC_max - }; - -#if 0 -static CONST char *CONST reloc_type_names[] = -{ - "R_SPARC_NONE", - "R_SPARC_8", "R_SPARC_16", "R_SPARC_32", - "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32", - "R_SPARC_WDISP30", "R_SPARC_WDISP22", - "R_SPARC_HI22", "R_SPARC_22", - "R_SPARC_13", "R_SPARC_LO10", - "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", - "R_SPARC_PC10", "R_SPARC_PC22", - "R_SPARC_WPLT30", - "R_SPARC_COPY", - "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", - "R_SPARC_RELATIVE", - "R_SPARC_UA32", -}; -#endif - -static reloc_howto_type nlm32_sparc_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, 0,"R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, 0,"R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, 0,"R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_WPLT30", false,0,0x00000000,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_UA32", false,0,0x00000000,true), -}; - -/* Read a NetWare sparc reloc. */ - -struct nlm32_sparc_reloc_ext { - unsigned char offset[4]; - unsigned char addend[4]; - unsigned char type[1]; - unsigned char pad1[3]; -}; - -static boolean -nlm_sparc_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - bfd_vma val, addend; - unsigned int index; - unsigned int type; - struct nlm32_sparc_reloc_ext tmp_reloc; - asection *code_sec, *data_sec; - - if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12) - return false; - - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - - *secp = code_sec; - - val = bfd_get_32 (abfd, tmp_reloc.offset); - addend = bfd_get_32 (abfd, tmp_reloc.addend); - type = bfd_get_8 (abfd, tmp_reloc.type); - - rel->address = val; - rel->addend = addend; - rel->howto = NULL; - - for (index = 0; - index < sizeof(nlm32_sparc_howto_table) / sizeof(reloc_howto_type); - index++) - if (nlm32_sparc_howto_table[index].type == type) { - rel->howto = &nlm32_sparc_howto_table[index]; - break; - } - -#ifdef DEBUG - fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n", - __FUNCTION__, rel->address, rel->addend, type, rel->howto); -#endif - return true; - -} - -/* Write a NetWare sparc reloc. */ - -static boolean -nlm_sparc_write_reloc (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - bfd_vma val; - struct nlm32_sparc_reloc_ext tmp_reloc; - unsigned int index; - int type = -1; - reloc_howto_type *tmp; - - - for (index = 0; - index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type); - index++) { - tmp = &nlm32_sparc_howto_table[index]; - - if (tmp->rightshift == rel->howto->rightshift - && tmp->size == rel->howto->size - && tmp->bitsize == rel->howto->bitsize - && tmp->pc_relative == rel->howto->pc_relative - && tmp->bitpos == rel->howto->bitpos - && tmp->src_mask == rel->howto->src_mask - && tmp->dst_mask == rel->howto->dst_mask) { - type = tmp->type; - break; - } - } - if (type == -1) - abort(); - - /* - * Netware wants a list of relocs for each address. - * Format is: - * long offset - * long addend - * char type - * That should be it. - */ - - /* The value we write out is the offset into the appropriate - segment. This offset is the section vma, adjusted by the vma of - the lowest section in that segment, plus the address of the - relocation. */ -#if 0 - val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address; -#else - val = bfd_get_section_vma (abfd, sec) + rel->address; -#endif - -#ifdef DEBUG - fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n", - __FUNCTION__, val, rel->addend, rel->howto->type); -#endif - bfd_put_32 (abfd, val, tmp_reloc.offset); - bfd_put_32 (abfd, rel->addend, tmp_reloc.addend); - bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type); - - if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12) - return false; - - return true; -} - -/* Mangle relocs for SPARC NetWare. We can just use the standard - SPARC relocs. */ - -static boolean -nlm_sparc_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - return true; -} - -/* Read a NetWare sparc import record */ -static boolean -nlm_sparc_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - /* - * First, read in the number of relocation - * entries for this symbol - */ - if (bfd_read ((PTR) temp, 4, 1, abfd) != 4) - return false; - - rcount = bfd_get_32 (abfd, temp); - - /* - * Next, read in the length of the symbol - */ - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return false; - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - - /* - * Then read in the symbol - */ - - if (bfd_read (name, symlength, 1, abfd) != symlength) - return false; - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - - /* - * Next, start reading in the relocs. - */ - - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (!nlm_relocs) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_sparc_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - return true; -} - -static boolean -nlm_sparc_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - char temp[4]; - asection *code, *data, *bss, *symsec; - bfd_vma base; - - code = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - symsec = (*rel->sym_ptr_ptr)->section; - - if (symsec == code) { - base = 0; - } else if (symsec == data) { - base = bfd_section_size (abfd, code); - } else if (symsec == bss) { - base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data); - } else - base = 0; - -#ifdef DEBUG - fprintf (stderr, "%s: <%x, 1>\n\t", - __FUNCTION__, base + (*rel->sym_ptr_ptr)->value); -#endif - bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp); - if (bfd_write ((PTR)temp, 4, 1, abfd) != 4) - return false; - bfd_put_32 (abfd, 1, temp); - if (bfd_write ((PTR)temp, 4, 1, abfd) != 4) - return false; - if (nlm_sparc_write_reloc (abfd, sec, rel) == false) - return false; - return true; -} - -/* Write out an external reference. */ - -static boolean -nlm_sparc_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - unsigned int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - bfd_put_32 (abfd, count, temp); - if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp)) - return false; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - for (i = 0; i < count; i++) - { - if (nlm_sparc_write_reloc (abfd, relocs[i].sec, - relocs[i].rel) == false) - return false; - } - - return true; -} - -static boolean -nlm_sparc_write_export (abfd, sym, value) - bfd *abfd; - asymbol *sym; - bfd_vma value; -{ - bfd_byte len; - bfd_byte temp[4]; - -#ifdef DEBUG - fprintf (stderr, "%s: <%x, %d, %s>\n", - __FUNCTION__, value, strlen (sym->name), sym->name); -#endif - bfd_put_32 (abfd, value, temp); - len = strlen (sym->name); - - if (bfd_write (temp, 4, 1, abfd) != 4 - || bfd_write (&len, 1, 1, abfd) != 1 - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - return true; -} - -#undef nlm_swap_fixed_header_in -#undef nlm_swap_fixed_header_out - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_sparc_backend = -{ - "NetWare SPARC Module \032", - sizeof (Nlm32_sparc_External_Fixed_Header), - 0, /* optional_prefix_size */ - bfd_arch_sparc, - 0, - false, - 0, /* backend_object_p */ - 0, /* write_prefix_func */ - nlm_sparc_read_reloc, - nlm_sparc_mangle_relocs, - nlm_sparc_read_import, - nlm_sparc_write_import, - 0, /* set_public_section */ - 0, /* get_public_offset */ - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_sparc_write_external, - nlm_sparc_write_export -}; - -#define TARGET_BIG_NAME "nlm32-sparc" -#define TARGET_BIG_SYM nlmNAME(sparc_vec) -#define TARGET_BACKEND_DATA &nlm32_sparc_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32.c b/contrib/gdb/bfd/nlm32.c deleted file mode 100644 index 4730e4fd349..00000000000 --- a/contrib/gdb/bfd/nlm32.c +++ /dev/null @@ -1,21 +0,0 @@ -/* NLM (NetWare Loadable Module) 32-bit executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define ARCH_SIZE 32 -#include "nlmcode.h" diff --git a/contrib/gdb/bfd/nlm64.c b/contrib/gdb/bfd/nlm64.c deleted file mode 100644 index 5dcd96a2b3c..00000000000 --- a/contrib/gdb/bfd/nlm64.c +++ /dev/null @@ -1,21 +0,0 @@ -/* NLM (NetWare Loadable Module) 64-bit executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define ARCH_SIZE 64 -#include "nlmcode.h" diff --git a/contrib/gdb/bfd/nlmcode.h b/contrib/gdb/bfd/nlmcode.h deleted file mode 100644 index 7f828b46b60..00000000000 --- a/contrib/gdb/bfd/nlmcode.h +++ /dev/null @@ -1,2057 +0,0 @@ -/* NLM (NetWare Loadable Module) executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, using ELF support as the - template. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include /* For strrchr and friends */ -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libnlm.h" - -/* The functions in this file do not use the names they appear to use. - This file is actually compiled multiple times, once for each size - of NLM target we are using. At each size we use a different name, - constructed by the macro nlmNAME. For example, the function which - is named nlm_symbol_type below is actually named nlm32_symbol_type - in the final executable. */ - -#define Nlm_External_Fixed_Header NlmNAME(External_Fixed_Header) -#define Nlm_External_Version_Header NlmNAME(External_Version_Header) -#define Nlm_External_Copyright_Header NlmNAME(External_Copyright_Header) -#define Nlm_External_Extended_Header NlmNAME(External_Extended_Header) -#define Nlm_External_Custom_Header NlmNAME(External_Custom_Header) -#define Nlm_External_Cygnus_Ext_Header NlmNAME(External_Cygnus_Ext_Header) - -#define nlm_symbol_type nlmNAME(symbol_type) -#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound) -#define nlm_get_symtab nlmNAME(get_symtab) -#define nlm_make_empty_symbol nlmNAME(make_empty_symbol) -#define nlm_print_symbol nlmNAME(print_symbol) -#define nlm_get_symbol_info nlmNAME(get_symbol_info) -#define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound) -#define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc) -#define nlm_object_p nlmNAME(object_p) -#define nlm_set_section_contents nlmNAME(set_section_contents) -#define nlm_write_object_contents nlmNAME(write_object_contents) - -#define nlm_swap_fixed_header_in(abfd,src,dst) \ - (nlm_swap_fixed_header_in_func(abfd))(abfd,src,dst) -#define nlm_swap_fixed_header_out(abfd,src,dst) \ - (nlm_swap_fixed_header_out_func(abfd))(abfd,src,dst) - -/* Forward declarations of static functions */ - -static boolean add_bfd_section - PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword)); -static boolean nlm_swap_variable_header_in - PARAMS ((bfd *)); -static boolean nlm_swap_variable_header_out - PARAMS ((bfd *)); -static boolean find_nonzero - PARAMS ((PTR, size_t)); -static boolean nlm_swap_auxiliary_headers_in - PARAMS ((bfd *)); -static boolean nlm_swap_auxiliary_headers_out - PARAMS ((bfd *)); -static boolean nlm_slurp_symbol_table - PARAMS ((bfd *)); -static boolean nlm_slurp_reloc_fixups - PARAMS ((bfd *)); -static boolean nlm_compute_section_file_positions - PARAMS ((bfd *)); -static int nlm_external_reloc_compare - PARAMS ((const void *, const void *)); - -/* Should perhaps use put_offset, put_word, etc. For now, the two versions - can be handled by explicitly specifying 32 bits or "the long type". */ -#if ARCH_SIZE == 64 -#define put_word bfd_h_put_64 -#define get_word bfd_h_get_64 -#endif -#if ARCH_SIZE == 32 -#define put_word bfd_h_put_32 -#define get_word bfd_h_get_32 -#endif - -const bfd_target * -nlm_object_p (abfd) - bfd *abfd; -{ - struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd); - boolean (*backend_object_p) PARAMS ((bfd *)); - PTR x_fxdhdr = NULL; - Nlm_Internal_Fixed_Header *i_fxdhdrp; - struct nlm_obj_tdata *new_tdata = NULL; - const char *signature; - enum bfd_architecture arch; - - /* Some NLM formats have a prefix before the standard NLM fixed - header. */ - backend_object_p = nlm_backend_object_p_func (abfd); - if (backend_object_p) - { - if (!(*backend_object_p) (abfd)) - goto got_wrong_format_error; - } - - /* Read in the fixed length portion of the NLM header in external format. */ - - x_fxdhdr = (PTR) bfd_malloc ((size_t) nlm_fixed_header_size (abfd)); - if (x_fxdhdr == NULL) - goto got_no_match; - - if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) != - nlm_fixed_header_size (abfd)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Allocate an instance of the nlm_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - new_tdata = ((struct nlm_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata))); - if (new_tdata == NULL) - goto got_no_match; - - nlm_tdata (abfd) = new_tdata; - - i_fxdhdrp = nlm_fixed_header (abfd); - nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp); - free (x_fxdhdr); - x_fxdhdr = NULL; - - /* Check to see if we have an NLM file for this backend by matching - the NLM signature. */ - - signature = nlm_signature (abfd); - if (signature != NULL - && *signature != '\0' - && strncmp ((char *) i_fxdhdrp->signature, signature, - NLM_SIGNATURE_SIZE) != 0) - goto got_wrong_format_error; - - /* There's no supported way to discover the endianess of an NLM, so test for - a sane version number after doing byte swapping appropriate for this - XVEC. (Hack alert!) */ - - if (i_fxdhdrp->version > 0xFFFF) - goto got_wrong_format_error; - - /* There's no supported way to check for 32 bit versus 64 bit addresses, - so ignore this distinction for now. (FIXME) */ - - /* Swap in the rest of the required header. */ - if (!nlm_swap_variable_header_in (abfd)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Add the sections supplied by all NLM's, and then read in the - auxiliary headers. Reading the auxiliary headers may create - additional sections described in the cygnus_ext header. - From this point on we assume that we have an NLM, and do not - treat errors as indicating the wrong format. */ - - if (!add_bfd_section (abfd, NLM_CODE_NAME, - i_fxdhdrp->codeImageOffset, - i_fxdhdrp->codeImageSize, - (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS - | SEC_RELOC)) - || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME, - i_fxdhdrp->dataImageOffset, - i_fxdhdrp->dataImageSize, - (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS - | SEC_RELOC)) - || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, - (file_ptr) 0, - i_fxdhdrp->uninitializedDataSize, - SEC_ALLOC)) - goto got_no_match; - - if (!nlm_swap_auxiliary_headers_in (abfd)) - goto got_no_match; - - if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0 - || nlm_fixed_header (abfd)->numberOfExternalReferences != 0) - abfd->flags |= HAS_RELOC; - if (nlm_fixed_header (abfd)->numberOfPublics != 0 - || nlm_fixed_header (abfd)->numberOfDebugRecords != 0 - || nlm_fixed_header (abfd)->numberOfExternalReferences != 0) - abfd->flags |= HAS_SYMS; - - arch = nlm_architecture (abfd); - if (arch != bfd_arch_unknown) - bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0); - - abfd->flags |= EXEC_P; - bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset; - - return (abfd->xvec); - -got_wrong_format_error: - bfd_set_error (bfd_error_wrong_format); -got_no_match: - nlm_tdata (abfd) = preserved_tdata; - if (new_tdata != NULL) - bfd_release (abfd, new_tdata); - if (x_fxdhdr != NULL) - free (x_fxdhdr); - return (NULL); -} - -/* Add a section to the bfd. */ - -static boolean -add_bfd_section (abfd, name, offset, size, flags) - bfd *abfd; - char *name; - file_ptr offset; - bfd_size_type size; - flagword flags; -{ - asection *newsect; - - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - { - return (false); - } - newsect->vma = 0; /* NLM's are relocatable. */ - newsect->_raw_size = size; - newsect->filepos = offset; - newsect->flags = flags; - newsect->alignment_power = bfd_log2 (0); /* FIXME */ - return (true); -} - -/* Read and swap in the variable length header. All the fields must - exist in the NLM, and must exist in the order they are read here. */ - -static boolean -nlm_swap_variable_header_in (abfd) - bfd *abfd; -{ - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - /* Read the description length and text members. */ - - if (bfd_read ((PTR) & nlm_variable_header (abfd)->descriptionLength, - sizeof (nlm_variable_header (abfd)->descriptionLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->descriptionLength)) - return (false); - if (bfd_read ((PTR) nlm_variable_header (abfd)->descriptionText, - nlm_variable_header (abfd)->descriptionLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1) - return (false); - - /* Read and convert the stackSize field. */ - - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp); - - /* Read and convert the reserved field. */ - - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp); - - /* Read the oldThreadName field. This field is a fixed length string. */ - - if (bfd_read ((PTR) nlm_variable_header (abfd)->oldThreadName, - sizeof (nlm_variable_header (abfd)->oldThreadName), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->oldThreadName)) - return (false); - - /* Read the screen name length and text members. */ - - if (bfd_read ((PTR) & nlm_variable_header (abfd)->screenNameLength, - sizeof (nlm_variable_header (abfd)->screenNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->screenNameLength)) - return (false); - if (bfd_read ((PTR) nlm_variable_header (abfd)->screenName, - nlm_variable_header (abfd)->screenNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1) - return (false); - - /* Read the thread name length and text members. */ - - if (bfd_read ((PTR) & nlm_variable_header (abfd)->threadNameLength, - sizeof (nlm_variable_header (abfd)->threadNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->threadNameLength)) - return (false); - if (bfd_read ((PTR) nlm_variable_header (abfd)->threadName, - nlm_variable_header (abfd)->threadNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1) - return (false); - return (true); -} - -/* Swap and write out the variable length header. All the fields must - exist in the NLM, and must exist in this order. */ - -static boolean -nlm_swap_variable_header_out (abfd) - bfd *abfd; -{ - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - /* Write the description length and text members. */ - - if (bfd_write ((PTR) & nlm_variable_header (abfd)->descriptionLength, - sizeof (nlm_variable_header (abfd)->descriptionLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->descriptionLength)) - return (false); - if (bfd_write ((PTR) nlm_variable_header (abfd)->descriptionText, - nlm_variable_header (abfd)->descriptionLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1) - return (false); - - /* Convert and write the stackSize field. */ - - put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize, - (bfd_byte *) temp); - if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - - /* Convert and write the reserved field. */ - - put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved, - (bfd_byte *) temp); - if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - - /* Write the oldThreadName field. This field is a fixed length string. */ - - if (bfd_write ((PTR) nlm_variable_header (abfd)->oldThreadName, - sizeof (nlm_variable_header (abfd)->oldThreadName), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->oldThreadName)) - return (false); - - /* Write the screen name length and text members. */ - - if (bfd_write ((PTR) & nlm_variable_header (abfd)->screenNameLength, - sizeof (nlm_variable_header (abfd)->screenNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->screenNameLength)) - return (false); - if (bfd_write ((PTR) nlm_variable_header (abfd)->screenName, - nlm_variable_header (abfd)->screenNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1) - return (false); - - /* Write the thread name length and text members. */ - - if (bfd_write ((PTR) & nlm_variable_header (abfd)->threadNameLength, - sizeof (nlm_variable_header (abfd)->threadNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->threadNameLength)) - return (false); - if (bfd_write ((PTR) nlm_variable_header (abfd)->threadName, - nlm_variable_header (abfd)->threadNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1) - return (false); - return (true); -} - -/* Read and swap in the contents of all the auxiliary headers. Because of - the braindead design, we have to do strcmps on strings of indeterminate - length to figure out what each auxiliary header is. Even worse, we have - no way of knowing how many auxiliary headers there are or where the end - of the auxiliary headers are, except by finding something that doesn't - look like a known auxiliary header. This means that the first new type - of auxiliary header added will break all existing tools that don't - recognize it. */ - -static boolean -nlm_swap_auxiliary_headers_in (abfd) - bfd *abfd; -{ - char tempstr[16]; - long position; - - for (;;) - { - position = bfd_tell (abfd); - if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) != - sizeof (tempstr)) - return (false); - if (bfd_seek (abfd, position, SEEK_SET) == -1) - return (false); - if (strncmp (tempstr, "VeRsIoN#", 8) == 0) - { - Nlm_External_Version_Header thdr; - if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return (false); - memcpy (nlm_version_header (abfd)->stamp, thdr.stamp, - sizeof (thdr.stamp)); - nlm_version_header (abfd)->majorVersion = - get_word (abfd, (bfd_byte *) thdr.majorVersion); - nlm_version_header (abfd)->minorVersion = - get_word (abfd, (bfd_byte *) thdr.minorVersion); - nlm_version_header (abfd)->revision = - get_word (abfd, (bfd_byte *) thdr.revision); - nlm_version_header (abfd)->year = - get_word (abfd, (bfd_byte *) thdr.year); - nlm_version_header (abfd)->month = - get_word (abfd, (bfd_byte *) thdr.month); - nlm_version_header (abfd)->day = - get_word (abfd, (bfd_byte *) thdr.day); - } - else if (strncmp (tempstr, "MeSsAgEs", 8) == 0) - { - Nlm_External_Extended_Header thdr; - if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return (false); - memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp, - sizeof (thdr.stamp)); - nlm_extended_header (abfd)->languageID = - get_word (abfd, (bfd_byte *) thdr.languageID); - nlm_extended_header (abfd)->messageFileOffset = - get_word (abfd, (bfd_byte *) thdr.messageFileOffset); - nlm_extended_header (abfd)->messageFileLength = - get_word (abfd, (bfd_byte *) thdr.messageFileLength); - nlm_extended_header (abfd)->messageCount = - get_word (abfd, (bfd_byte *) thdr.messageCount); - nlm_extended_header (abfd)->helpFileOffset = - get_word (abfd, (bfd_byte *) thdr.helpFileOffset); - nlm_extended_header (abfd)->helpFileLength = - get_word (abfd, (bfd_byte *) thdr.helpFileLength); - nlm_extended_header (abfd)->RPCDataOffset = - get_word (abfd, (bfd_byte *) thdr.RPCDataOffset); - nlm_extended_header (abfd)->RPCDataLength = - get_word (abfd, (bfd_byte *) thdr.RPCDataLength); - nlm_extended_header (abfd)->sharedCodeOffset = - get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset); - nlm_extended_header (abfd)->sharedCodeLength = - get_word (abfd, (bfd_byte *) thdr.sharedCodeLength); - nlm_extended_header (abfd)->sharedDataOffset = - get_word (abfd, (bfd_byte *) thdr.sharedDataOffset); - nlm_extended_header (abfd)->sharedDataLength = - get_word (abfd, (bfd_byte *) thdr.sharedDataLength); - nlm_extended_header (abfd)->sharedRelocationFixupOffset = - get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset); - nlm_extended_header (abfd)->sharedRelocationFixupCount = - get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount); - nlm_extended_header (abfd)->sharedExternalReferenceOffset = - get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset); - nlm_extended_header (abfd)->sharedExternalReferenceCount = - get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount); - nlm_extended_header (abfd)->sharedPublicsOffset = - get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset); - nlm_extended_header (abfd)->sharedPublicsCount = - get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount); - nlm_extended_header (abfd)->sharedDebugRecordOffset = - get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset); - nlm_extended_header (abfd)->sharedDebugRecordCount = - get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount); - nlm_extended_header (abfd)->SharedInitializationOffset = - get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset); - nlm_extended_header (abfd)->SharedExitProcedureOffset = - get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset); - nlm_extended_header (abfd)->productID = - get_word (abfd, (bfd_byte *) thdr.productID); - nlm_extended_header (abfd)->reserved0 = - get_word (abfd, (bfd_byte *) thdr.reserved0); - nlm_extended_header (abfd)->reserved1 = - get_word (abfd, (bfd_byte *) thdr.reserved1); - nlm_extended_header (abfd)->reserved2 = - get_word (abfd, (bfd_byte *) thdr.reserved2); - nlm_extended_header (abfd)->reserved3 = - get_word (abfd, (bfd_byte *) thdr.reserved3); - nlm_extended_header (abfd)->reserved4 = - get_word (abfd, (bfd_byte *) thdr.reserved4); - nlm_extended_header (abfd)->reserved5 = - get_word (abfd, (bfd_byte *) thdr.reserved5); - } - else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0) - { - if (bfd_read ((PTR) nlm_copyright_header (abfd)->stamp, - sizeof (nlm_copyright_header (abfd)->stamp), - 1, abfd) - != sizeof (nlm_copyright_header (abfd)->stamp)) - return (false); - if (bfd_read ((PTR) & (nlm_copyright_header (abfd) - ->copyrightMessageLength), - 1, 1, abfd) != 1) - return (false); - /* The copyright message is a variable length string. */ - if (bfd_read ((PTR) nlm_copyright_header (abfd)->copyrightMessage, - nlm_copyright_header (abfd)->copyrightMessageLength + 1, - 1, abfd) != - ((bfd_size_type) - nlm_copyright_header (abfd)->copyrightMessageLength + 1)) - return (false); - } - else if (strncmp (tempstr, "CuStHeAd", 8) == 0) - { - Nlm_External_Custom_Header thdr; - bfd_size_type hdrLength; - file_ptr dataOffset; - bfd_size_type dataLength; - char dataStamp[8]; - PTR hdr; - - /* Read the stamp ("CuStHeAd"). */ - if (bfd_read ((PTR) thdr.stamp, 1, sizeof (thdr.stamp), abfd) - != sizeof (thdr.stamp)) - return false; - /* Read the length of this custom header. */ - if (bfd_read ((PTR) thdr.length, 1, sizeof (thdr.length), abfd) - != sizeof (thdr.length)) - return false; - hdrLength = get_word (abfd, (bfd_byte *) thdr.length); - /* Read further fields if we have them. */ - if (hdrLength < NLM_TARGET_LONG_SIZE) - dataOffset = 0; - else - { - if (bfd_read ((PTR) thdr.dataOffset, 1, - sizeof (thdr.dataOffset), abfd) - != sizeof (thdr.dataOffset)) - return false; - dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset); - } - if (hdrLength < 2 * NLM_TARGET_LONG_SIZE) - dataLength = 0; - else - { - if (bfd_read ((PTR) thdr.dataLength, 1, - sizeof (thdr.dataLength), abfd) - != sizeof (thdr.dataLength)) - return false; - dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength); - } - if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8) - memset (dataStamp, 0, sizeof (dataStamp)); - else - { - if (bfd_read ((PTR) dataStamp, 1, sizeof (dataStamp), abfd) - != sizeof (dataStamp)) - return false; - } - - /* Read the rest of the header, if any. */ - if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8) - { - hdr = NULL; - hdrLength = 0; - } - else - { - hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8; - hdr = bfd_alloc (abfd, hdrLength); - if (hdr == NULL) - return false; - if (bfd_read (hdr, 1, hdrLength, abfd) != hdrLength) - return false; - } - - /* If we have found a Cygnus header, process it. Otherwise, - just save the associated data without trying to interpret - it. */ - if (strncmp (dataStamp, "CyGnUsEx", 8) == 0) - { - file_ptr pos; - bfd_byte *contents; - bfd_byte *p, *pend; - - BFD_ASSERT (hdrLength == 0 && hdr == NULL); - - pos = bfd_tell (abfd); - if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0) - return false; - contents = (bfd_byte *) bfd_alloc (abfd, dataLength); - if (contents == NULL) - return false; - if (bfd_read (contents, 1, dataLength, abfd) != dataLength) - return false; - if (bfd_seek (abfd, pos, SEEK_SET) != 0) - return false; - - memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8); - nlm_cygnus_ext_header (abfd)->offset = dataOffset; - nlm_cygnus_ext_header (abfd)->length = dataLength; - - /* This data this header points to provides a list of - the sections which were in the original object file - which was converted to become an NLM. We locate - those sections and add them to the BFD. Note that - this is likely to create a second .text, .data and - .bss section; retrieving the sections by name will - get the actual NLM sections, which is what we want to - happen. The sections from the original file, which - may be subsets of the NLM section, can only be found - using bfd_map_over_sections. */ - p = contents; - pend = p + dataLength; - while (p < pend) - { - char *name; - size_t l; - file_ptr filepos; - bfd_size_type size; - asection *newsec; - - /* The format of this information is - null terminated section name - zeroes to adjust to 4 byte boundary - 4 byte section data file pointer - 4 byte section size - */ - - name = (char *) p; - l = strlen (name) + 1; - l = (l + 3) &~ 3; - p += l; - filepos = bfd_h_get_32 (abfd, p); - p += 4; - size = bfd_h_get_32 (abfd, p); - p += 4; - - newsec = bfd_make_section_anyway (abfd, name); - if (newsec == (asection *) NULL) - return false; - newsec->_raw_size = size; - if (filepos != 0) - { - newsec->filepos = filepos; - newsec->flags |= SEC_HAS_CONTENTS; - } - } - } - else - { - memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp, - sizeof (thdr.stamp)); - nlm_custom_header (abfd)->hdrLength = hdrLength; - nlm_custom_header (abfd)->dataOffset = dataOffset; - nlm_custom_header (abfd)->dataLength = dataLength; - memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp, - sizeof (dataStamp)); - nlm_custom_header (abfd)->hdr = hdr; - } - } - else - { - break; - } - } - return (true); -} - -/* Return whether there is a non-zero byte in a memory block. */ - -static boolean -find_nonzero (buf, size) - PTR buf; - size_t size; -{ - char *p = (char *) buf; - - while (size-- != 0) - if (*p++ != 0) - return true; - return false; -} - -/* Swap out the contents of the auxiliary headers. We create those - auxiliary headers which have been set non-zero. We do not require - the caller to set up the stamp fields. */ - -static boolean -nlm_swap_auxiliary_headers_out (abfd) - bfd *abfd; -{ - /* Write out the version header if there is one. */ - if (find_nonzero ((PTR) nlm_version_header (abfd), - sizeof (Nlm_Internal_Version_Header))) - { - Nlm_External_Version_Header thdr; - - memcpy (thdr.stamp, "VeRsIoN#", 8); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion, - (bfd_byte *) thdr.majorVersion); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion, - (bfd_byte *) thdr.minorVersion); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision, - (bfd_byte *) thdr.revision); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year, - (bfd_byte *) thdr.year); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month, - (bfd_byte *) thdr.month); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day, - (bfd_byte *) thdr.day); - if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - } - - /* Write out the extended header if there is one. */ - if (find_nonzero ((PTR) nlm_extended_header (abfd), - sizeof (Nlm_Internal_Extended_Header))) - { - Nlm_External_Extended_Header thdr; - - memcpy (thdr.stamp, "MeSsAgEs", 8); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->languageID, - (bfd_byte *) thdr.languageID); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->messageFileOffset, - (bfd_byte *) thdr.messageFileOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->messageFileLength, - (bfd_byte *) thdr.messageFileLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->messageCount, - (bfd_byte *) thdr.messageCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->helpFileOffset, - (bfd_byte *) thdr.helpFileOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->helpFileLength, - (bfd_byte *) thdr.helpFileLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset, - (bfd_byte *) thdr.RPCDataOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->RPCDataLength, - (bfd_byte *) thdr.RPCDataLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset, - (bfd_byte *) thdr.sharedCodeOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength, - (bfd_byte *) thdr.sharedCodeLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset, - (bfd_byte *) thdr.sharedDataOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDataLength, - (bfd_byte *) thdr.sharedDataLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset, - (bfd_byte *) thdr.sharedRelocationFixupOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount, - (bfd_byte *) thdr.sharedRelocationFixupCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset, - (bfd_byte *) thdr.sharedExternalReferenceOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount, - (bfd_byte *) thdr.sharedExternalReferenceCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset, - (bfd_byte *) thdr.sharedPublicsOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount, - (bfd_byte *) thdr.sharedPublicsCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset, - (bfd_byte *) thdr.sharedDebugRecordOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount, - (bfd_byte *) thdr.sharedDebugRecordCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset, - (bfd_byte *) thdr.sharedInitializationOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset, - (bfd_byte *) thdr.SharedExitProcedureOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->productID, - (bfd_byte *) thdr.productID); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved0, - (bfd_byte *) thdr.reserved0); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved1, - (bfd_byte *) thdr.reserved1); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved2, - (bfd_byte *) thdr.reserved2); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved3, - (bfd_byte *) thdr.reserved3); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved4, - (bfd_byte *) thdr.reserved4); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved5, - (bfd_byte *) thdr.reserved5); - if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - } - - - /* Write out the copyright header if there is one. */ - if (find_nonzero ((PTR) nlm_copyright_header (abfd), - sizeof (Nlm_Internal_Copyright_Header))) - { - Nlm_External_Copyright_Header thdr; - - memcpy (thdr.stamp, "CoPyRiGhT=", 10); - if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd) - != sizeof (thdr.stamp)) - return false; - thdr.copyrightMessageLength[0] = - nlm_copyright_header (abfd)->copyrightMessageLength; - if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1) - return false; - /* The copyright message is a variable length string. */ - if (bfd_write ((PTR) nlm_copyright_header (abfd)->copyrightMessage, - nlm_copyright_header (abfd)->copyrightMessageLength + 1, - 1, abfd) != - ((bfd_size_type) - nlm_copyright_header (abfd)->copyrightMessageLength + 1)) - return false; - } - - /* Write out the custom header if there is one. */ - if (find_nonzero ((PTR) nlm_custom_header (abfd), - sizeof (Nlm_Internal_Custom_Header))) - { - Nlm_External_Custom_Header thdr; - boolean ds; - bfd_size_type hdrLength; - - ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp, - sizeof (nlm_custom_header (abfd)->dataStamp)); - memcpy (thdr.stamp, "CuStHeAd", 8); - hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0) - + nlm_custom_header (abfd)->hdrLength); - put_word (abfd, hdrLength, thdr.length); - put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset, - thdr.dataOffset); - put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength, - thdr.dataLength); - if (! ds) - { - BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0); - if (bfd_write ((PTR) &thdr, 1, - sizeof (thdr) - sizeof (thdr.dataStamp), abfd) - != sizeof (thdr) - sizeof (thdr.dataStamp)) - return false; - } - else - { - memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp, - sizeof (thdr.dataStamp)); - if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - if (bfd_write (nlm_custom_header (abfd)->hdr, 1, - nlm_custom_header (abfd)->hdrLength, abfd) - != nlm_custom_header (abfd)->hdrLength) - return false; - } - } - - /* Write out the Cygnus debugging header if there is one. */ - if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd), - sizeof (Nlm_Internal_Cygnus_Ext_Header))) - { - Nlm_External_Custom_Header thdr; - - memcpy (thdr.stamp, "CuStHeAd", 8); - put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8, - (bfd_byte *) thdr.length); - put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset, - (bfd_byte *) thdr.dataOffset); - put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length, - (bfd_byte *) thdr.dataLength); - memcpy (thdr.dataStamp, "CyGnUsEx", 8); - if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - } - - return true; -} - -/* We read the NLM's public symbols and use it to generate a bfd symbol - table (hey, it's better than nothing) on a one-for-one basis. Thus - use the number of public symbols as the number of bfd symbols we will - have once we actually get around to reading them in. - - Return the number of bytes required to hold the symtab vector, based on - the count plus 1, since we will NULL terminate the vector allocated based - on this size. */ - -long -nlm_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */ - long symcount; - long symtab_size = 0; - - i_fxdhdrp = nlm_fixed_header (abfd); - symcount = (i_fxdhdrp->numberOfPublics - + i_fxdhdrp->numberOfDebugRecords - + i_fxdhdrp->numberOfExternalReferences); - symtab_size = (symcount + 1) * (sizeof (asymbol)); - return (symtab_size); -} - -/* Note that bfd_get_symcount is guaranteed to be zero if slurping the - symbol table fails. */ - -long -nlm_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - nlm_symbol_type *symbase; - bfd_size_type counter = 0; - - if (nlm_slurp_symbol_table (abfd) == false) - return -1; - symbase = nlm_get_symbols (abfd); - while (counter < bfd_get_symcount (abfd)) - { - *alocation++ = &symbase->symbol; - symbase++; - counter++; - } - *alocation = (asymbol *) NULL; - return bfd_get_symcount (abfd); -} - -/* Make an NLM symbol. There is nothing special to do here. */ - -asymbol * -nlm_make_empty_symbol (abfd) - bfd *abfd; -{ - nlm_symbol_type *new; - - new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type)); - if (new) - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/* Get symbol information. */ - -void -nlm_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/* Print symbol information. */ - -void -nlm_print_symbol (abfd, afile, symbol, how) - bfd *abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - - switch (how) - { - case bfd_print_symbol_name: - case bfd_print_symbol_more: - if (symbol->name) - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_all: - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s", symbol->section->name); - if (symbol->name) - fprintf (file, " %s", symbol->name); - break; - } -} - -/* Slurp in nlm symbol table. - - In the external (in-file) form, NLM export records are variable length, - with the following form: - - 1 byte length of the symbol name (N) - N bytes the symbol name - 4 bytes the symbol offset from start of it's section - - We also read in the debugging symbols and import records. Import - records are treated as undefined symbols. As we read the import - records we also read in the associated reloc information, which is - attached to the symbol. - - The bfd symbols are copied to SYMPTRS. - - When we return, the bfd symcount is either zero or contains the correct - number of symbols. -*/ - -static boolean -nlm_slurp_symbol_table (abfd) - bfd *abfd; -{ - Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */ - bfd_size_type totsymcount; /* Number of NLM symbols */ - bfd_size_type symcount; /* Counter of NLM symbols */ - nlm_symbol_type *sym; /* Pointer to current bfd symbol */ - unsigned char symlength; /* Symbol length read into here */ - unsigned char symtype; /* Type of debugging symbol */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */ - boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *)); - boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *)); - - if (nlm_get_symbols (abfd) != NULL) - return (true); - - /* Read each raw NLM symbol, using the information to create a canonical bfd - symbol table entry. - - Note that we allocate the initial bfd canonical symbol buffer based on a - one-to-one mapping of the NLM symbols to canonical symbols. We actually - use all the NLM symbols, so there will be no space left over at the end. - When we have all the symbols, we build the caller's pointer vector. */ - - abfd->symcount = 0; - i_fxdhdrp = nlm_fixed_header (abfd); - totsymcount = (i_fxdhdrp->numberOfPublics - + i_fxdhdrp->numberOfDebugRecords - + i_fxdhdrp->numberOfExternalReferences); - if (totsymcount == 0) - { - return (true); - } - - if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) == -1) - return (false); - - sym = ((nlm_symbol_type *) - bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type))); - if (!sym) - return false; - nlm_set_symbols (abfd, sym); - - /* We use the bfd's symcount directly as the control count, so that early - termination of the loop leaves the symcount correct for the symbols that - were read. */ - - set_public_section_func = nlm_set_public_section_func (abfd); - symcount = i_fxdhdrp->numberOfPublics; - while (abfd->symcount < symcount) - { - if (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return (false); - sym->symbol.the_bfd = abfd; - sym->symbol.name = bfd_alloc (abfd, symlength + 1); - if (!sym->symbol.name) - return false; - if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd) - != symlength) - return (false); - /* Cast away const. */ - ((char *) (sym->symbol.name))[symlength] = '\0'; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT; - sym->symbol.value = get_word (abfd, temp); - if (set_public_section_func) - { - /* Most backends can use the code below, but unfortunately - some use a different scheme. */ - if ((*set_public_section_func) (abfd, sym) == false) - return false; - } - else - { - if (sym->symbol.value & NLM_HIBIT) - { - sym->symbol.value &= ~NLM_HIBIT; - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_CODE_NAME); - } - else - { - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - } - } - sym->rcnt = 0; - abfd->symcount++; - sym++; - } - - /* Read the debugging records. */ - - if (i_fxdhdrp->numberOfDebugRecords > 0) - { - if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) == -1) - return (false); - - symcount += i_fxdhdrp->numberOfDebugRecords; - while (abfd->symcount < symcount) - { - if ((bfd_read ((PTR) & symtype, sizeof (symtype), 1, abfd) - != sizeof (symtype)) - || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp) - || (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength))) - return false; - sym->symbol.the_bfd = abfd; - sym->symbol.name = bfd_alloc (abfd, symlength + 1); - if (!sym->symbol.name) - return false; - if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd) - != symlength) - return (false); - /* Cast away const. */ - ((char *) (sym->symbol.name))[symlength] = '\0'; - sym->symbol.flags = BSF_LOCAL; - sym->symbol.value = get_word (abfd, temp); - if (symtype == 0) - { - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - } - else if (symtype == 1) - { - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_CODE_NAME); - } - else - { - sym->symbol.section = bfd_abs_section_ptr; - } - sym->rcnt = 0; - abfd->symcount++; - sym++; - } - } - - /* Read in the import records. We can only do this if we know how - to read relocs for this target. */ - - read_import_func = nlm_read_import_func (abfd); - if (read_import_func != NULL) - { - if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) - == -1) - return (false); - - symcount += i_fxdhdrp->numberOfExternalReferences; - while (abfd->symcount < symcount) - { - if ((*read_import_func) (abfd, sym) == false) - return false; - sym++; - abfd->symcount++; - } - } - - return (true); -} - -/* Get the relocs for an NLM file. There are two types of relocs. - Imports are relocs against symbols defined in other NLM files. We - treat these as relocs against global symbols. Relocation fixups - are internal relocs. - - The actual format used to store the relocs is machine specific. */ - -/* Read in the relocation fixup information. This is stored in - nlm_relocation_fixups, an array of arelent structures, and - nlm_relocation_fixup_secs, an array of section pointers. The - section pointers are needed because the relocs are not sorted by - section. */ - -static boolean -nlm_slurp_reloc_fixups (abfd) - bfd *abfd; -{ - boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **, - arelent *)); - bfd_size_type count; - arelent *rels; - asection **secs; - - if (nlm_relocation_fixups (abfd) != NULL) - return true; - read_func = nlm_read_reloc_func (abfd); - if (read_func == NULL) - return true; - - if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset, - SEEK_SET) != 0) - return false; - - count = nlm_fixed_header (abfd)->numberOfRelocationFixups; - rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent)); - secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *)); - if ((rels == NULL || secs == NULL) && count != 0) - return false; - nlm_relocation_fixups (abfd) = rels; - nlm_relocation_fixup_secs (abfd) = secs; - - /* We have to read piece by piece, because we don't know how large - the machine specific reloc information is. */ - while (count-- != 0) - { - if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false) - { - nlm_relocation_fixups (abfd) = NULL; - nlm_relocation_fixup_secs (abfd) = NULL; - return false; - } - ++secs; - ++rels; - } - - return true; -} - -/* Get the number of relocs. This really just returns an upper bound, - since it does not attempt to distinguish them based on the section. - That will be handled when they are actually read. */ - -long -nlm_get_reloc_upper_bound (abfd, sec) - bfd *abfd; - asection *sec; -{ - nlm_symbol_type *syms; - bfd_size_type count; - unsigned int ret; - - /* If we don't know how to read relocs, just return 0. */ - if (nlm_read_reloc_func (abfd) == NULL) - return -1; - /* Make sure we have either the code or the data section. */ - if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0) - return 0; - - syms = nlm_get_symbols (abfd); - if (syms == NULL) - { - if (nlm_slurp_symbol_table (abfd) == false) - return -1; - syms = nlm_get_symbols (abfd); - } - - ret = nlm_fixed_header (abfd)->numberOfRelocationFixups; - - count = bfd_get_symcount (abfd); - while (count-- != 0) - { - ret += syms->rcnt; - ++syms; - } - - return (ret + 1) * sizeof (arelent *); -} - -/* Get the relocs themselves. */ - -long -nlm_canonicalize_reloc (abfd, sec, relptr, symbols) - bfd *abfd; - asection *sec; - arelent **relptr; - asymbol **symbols; -{ - arelent *rels; - asection **secs; - bfd_size_type count, i; - unsigned int ret; - - /* Get the relocation fixups. */ - rels = nlm_relocation_fixups (abfd); - if (rels == NULL) - { - if (nlm_slurp_reloc_fixups (abfd) == false) - return -1; - rels = nlm_relocation_fixups (abfd); - } - secs = nlm_relocation_fixup_secs (abfd); - - ret = 0; - count = nlm_fixed_header (abfd)->numberOfRelocationFixups; - for (i = 0; i < count; i++, rels++, secs++) - { - if (*secs == sec) - { - *relptr++ = rels; - ++ret; - } - } - - /* Get the import symbols. */ - count = bfd_get_symcount (abfd); - for (i = 0; i < count; i++, symbols++) - { - asymbol *sym; - - sym = *symbols; - if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour) - { - nlm_symbol_type *nlm_sym; - bfd_size_type j; - - nlm_sym = (nlm_symbol_type *) sym; - for (j = 0; j < nlm_sym->rcnt; j++) - { - if (nlm_sym->relocs[j].section == sec) - { - *relptr = &nlm_sym->relocs[j].reloc; - (*relptr)->sym_ptr_ptr = symbols; - ++relptr; - ++ret; - } - } - } - } - - *relptr = NULL; - - return ret; -} - -/* Compute the section file positions for an NLM file. All variable - length data in the file headers must be set before this function is - called. If the variable length data is changed later, the - resulting object file will be incorrect. Unfortunately, there is - no way to check this. - - This routine also sets the Size and Offset fields in the fixed - header. - - It also looks over the symbols and moves any common symbols into - the .bss section; NLM has no way to represent a common symbol. - This approach means that either the symbols must already have been - set at this point, or there must be no common symbols. We need to - move the symbols at this point so that mangle_relocs can see the - final values. */ - -static boolean -nlm_compute_section_file_positions (abfd) - bfd *abfd; -{ - file_ptr sofar; - asection *sec; - bfd_vma text, data, bss; - bfd_vma text_low, data_low; - unsigned int text_align, data_align, other_align; - file_ptr text_ptr, data_ptr, other_ptr; - asection *bss_sec; - asymbol **sym_ptr_ptr; - - if (abfd->output_has_begun == true) - return true; - - /* Make sure we have a section to hold uninitialized data. */ - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - if (bss_sec == NULL) - { - if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, - (file_ptr) 0, (bfd_size_type) 0, - SEC_ALLOC)) - return false; - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - } - - abfd->output_has_begun = true; - - /* The fixed header. */ - sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd); - - /* The variable header. */ - sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength) - + nlm_variable_header (abfd)->descriptionLength + 1 - + NLM_TARGET_LONG_SIZE /* stackSize */ - + NLM_TARGET_LONG_SIZE /* reserved */ - + sizeof (nlm_variable_header (abfd)->oldThreadName) - + sizeof (nlm_variable_header (abfd)->screenNameLength) - + nlm_variable_header (abfd)->screenNameLength + 1 - + sizeof (nlm_variable_header (abfd)->threadNameLength) - + nlm_variable_header (abfd)->threadNameLength + 1); - - /* The auxiliary headers. */ - if (find_nonzero ((PTR) nlm_version_header (abfd), - sizeof (Nlm_Internal_Version_Header))) - sofar += sizeof (Nlm_External_Version_Header); - if (find_nonzero ((PTR) nlm_extended_header (abfd), - sizeof (Nlm_Internal_Extended_Header))) - sofar += sizeof (Nlm_External_Extended_Header); - if (find_nonzero ((PTR) nlm_copyright_header (abfd), - sizeof (Nlm_Internal_Copyright_Header))) - sofar += (sizeof (Nlm_External_Copyright_Header) - + nlm_copyright_header (abfd)->copyrightMessageLength + 1); - if (find_nonzero ((PTR) nlm_custom_header (abfd), - sizeof (Nlm_Internal_Custom_Header))) - sofar += (sizeof (Nlm_External_Custom_Header) - + nlm_custom_header (abfd)->hdrLength); - if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd), - sizeof (Nlm_Internal_Cygnus_Ext_Header))) - sofar += sizeof (Nlm_External_Custom_Header); - - /* Compute the section file positions in two passes. First get the - sizes of the text and data sections, and then set the file - positions. This code aligns the sections in the file using the - same alignment restrictions that apply to the sections in memory; - this may not be necessary. */ - text = 0; - text_low = (bfd_vma) - 1; - text_align = 0; - data = 0; - data_low = (bfd_vma) - 1; - data_align = 0; - bss = 0; - other_align = 0; - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - flagword f; - - sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power); - - f = bfd_get_section_flags (abfd, sec); - if (f & SEC_CODE) - { - text += sec->_raw_size; - if (bfd_get_section_vma (abfd, sec) < text_low) - text_low = bfd_get_section_vma (abfd, sec); - if (sec->alignment_power > text_align) - text_align = sec->alignment_power; - } - else if (f & SEC_DATA) - { - data += sec->_raw_size; - if (bfd_get_section_vma (abfd, sec) < data_low) - data_low = bfd_get_section_vma (abfd, sec); - if (sec->alignment_power > data_align) - data_align = sec->alignment_power; - } - else if (f & SEC_HAS_CONTENTS) - { - if (sec->alignment_power > other_align) - other_align = sec->alignment_power; - } - else if (f & SEC_ALLOC) - bss += sec->_raw_size; - } - - nlm_set_text_low (abfd, text_low); - nlm_set_data_low (abfd, data_low); - - if (nlm_no_uninitialized_data (abfd)) - { - /* This NetWare format does not use uninitialized data. We must - increase the size of the data section. We will never wind up - writing those file locations, so they will remain zero. */ - data += bss; - bss = 0; - } - - text_ptr = BFD_ALIGN (sofar, 1 << text_align); - data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align); - other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align); - - /* Fill in some fields in the header for which we now have the - information. */ - nlm_fixed_header (abfd)->codeImageOffset = text_ptr; - nlm_fixed_header (abfd)->codeImageSize = text; - nlm_fixed_header (abfd)->dataImageOffset = data_ptr; - nlm_fixed_header (abfd)->dataImageSize = data; - nlm_fixed_header (abfd)->uninitializedDataSize = bss; - - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - flagword f; - - f = bfd_get_section_flags (abfd, sec); - - if (f & SEC_CODE) - { - sec->filepos = text_ptr; - text_ptr += sec->_raw_size; - } - else if (f & SEC_DATA) - { - sec->filepos = data_ptr; - data_ptr += sec->_raw_size; - } - else if (f & SEC_HAS_CONTENTS) - { - sec->filepos = other_ptr; - other_ptr += sec->_raw_size; - } - } - - nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr; - - /* Move all common symbols into the .bss section. */ - - sym_ptr_ptr = bfd_get_outsymbols (abfd); - if (sym_ptr_ptr != NULL) - { - asymbol **sym_end; - bfd_vma add; - - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); - add = 0; - for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) - { - asymbol *sym; - bfd_vma size; - - sym = *sym_ptr_ptr; - - if (!bfd_is_com_section (bfd_get_section (sym))) - continue; - - /* Put the common symbol in the .bss section, and increase - the size of the .bss section by the size of the common - symbol (which is the old value of the symbol). */ - sym->section = bss_sec; - size = sym->value; - sym->value = bss_sec->_raw_size + add; - add += size; - add = BFD_ALIGN (add, 1 << bss_sec->alignment_power); - } - if (add != 0) - { - if (nlm_no_uninitialized_data (abfd)) - { - /* We could handle this case, but so far it hasn't been - necessary. */ - abort (); - } - nlm_fixed_header (abfd)->uninitializedDataSize += add; - bss_sec->_raw_size += add; - } - } - - return true; -} - -/* Set the contents of a section. To do this we need to know where - the section is going to be located in the output file. That means - that the sizes of all the sections must be set, and all the - variable size header information must be known. */ - -boolean -nlm_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (abfd->output_has_begun == false - && nlm_compute_section_file_positions (abfd) == false) - return false; - - if (count == 0) - return true; - - /* i386 NetWare has a very restricted set of relocs. In order for - objcopy to work, the NLM i386 backend needs a chance to rework - the section contents so that its set of relocs will work. If all - the relocs are already acceptable, this will not do anything. */ - if (section->reloc_count != 0) - { - boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR, - bfd_vma, bfd_size_type)); - - mangle_relocs_func = nlm_mangle_relocs_func (abfd); - if (mangle_relocs_func != NULL) - { - if (!(*mangle_relocs_func) (abfd, section, location, - (bfd_vma) offset, count)) - return false; - } - } - - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 - || bfd_write (location, 1, count, abfd) != count) - return false; - - return true; -} - -/* We need to sort a list of relocs associated with sections when we - write out the external relocs. */ - -static int -nlm_external_reloc_compare (p1, p2) - const void *p1; - const void *p2; -{ - const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1; - const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2; - int cmp; - - cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name, - (*r2->rel->sym_ptr_ptr)->name); - if (cmp != 0) - return cmp; - - /* We sort by address within symbol to make the sort more stable and - increase the chances that different hosts will generate bit for - bit equivalent results. */ - return (int) (r1->rel->address - r2->rel->address); -} - -/* Write out an NLM file. We write out the information in this order: - fixed header - variable header - auxiliary headers - code sections - data sections - other sections (custom data, messages, help, shared NLM, RPC, - module dependencies) - relocation fixups - external references (imports) - public symbols (exports) - debugging records - This is similar to the order used by the NetWare tools; the - difference is that NetWare puts the sections other than code, data - and custom data at the end of the NLM. It is convenient for us to - know where the sections are going to be before worrying about the - size of the other information. - - By the time this function is called, all the section data should - have been output using set_section_contents. Note that custom - data, the message file, the help file, the shared NLM file, the RPC - data, and the module dependencies are all considered to be - sections; the caller is responsible for filling in the offset and - length fields in the NLM headers. The relocation fixups and - imports are both obtained from the list of relocs attached to each - section. The exports and debugging records are obtained from the - list of outsymbols. */ - -boolean -nlm_write_object_contents (abfd) - bfd *abfd; -{ - asection *sec; - boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *)); - bfd_size_type external_reloc_count, internal_reloc_count, i, c; - struct reloc_and_sec *external_relocs; - asymbol **sym_ptr_ptr; - file_ptr last; - boolean (*write_prefix_func) PARAMS ((bfd *)); - unsigned char *fixed_header = NULL; - - fixed_header = ((unsigned char *) - bfd_malloc ((size_t) nlm_fixed_header_size (abfd))); - if (fixed_header == NULL) - goto error_return; - - if (abfd->output_has_begun == false - && nlm_compute_section_file_positions (abfd) == false) - goto error_return; - - /* Write out the variable length headers. */ - if (bfd_seek (abfd, - nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd), - SEEK_SET) != 0) - goto error_return; - if (nlm_swap_variable_header_out (abfd) == false - || nlm_swap_auxiliary_headers_out (abfd) == false) - { - bfd_set_error (bfd_error_system_call); - goto error_return; - } - - /* A weak check on whether the section file positions were - reasonable. */ - if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset) - { - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - /* Advance to the relocs. */ - if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset, - SEEK_SET) != 0) - goto error_return; - - /* The format of the relocation entries is dependent upon the - particular target. We use an external routine to write the reloc - out. */ - write_import_func = nlm_write_import_func (abfd); - - /* Write out the internal relocation fixups. While we're looping - over the relocs, we also count the external relocs, which is - needed when they are written out below. */ - internal_reloc_count = 0; - external_reloc_count = 0; - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - arelent **rel_ptr_ptr, **rel_end; - - if (sec->reloc_count == 0) - continue; - - /* We can only represent relocs within a code or data - section. We ignore them for a debugging section. */ - if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0) - continue; - - /* We need to know how to write out imports */ - if (write_import_func == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - rel_ptr_ptr = sec->orelocation; - rel_end = rel_ptr_ptr + sec->reloc_count; - for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++) - { - arelent *rel; - asymbol *sym; - - rel = *rel_ptr_ptr; - sym = *rel->sym_ptr_ptr; - - if (! bfd_is_und_section (bfd_get_section (sym))) - { - ++internal_reloc_count; - if ((*write_import_func) (abfd, sec, rel) == false) - goto error_return; - } - else - ++external_reloc_count; - } - } - nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count; - - /* Write out the imports (relocs against external symbols). These - are output as a symbol name followed by all the relocs for that - symbol, so we must first gather together all the relocs against - external symbols and sort them. */ - external_relocs = - (struct reloc_and_sec *) bfd_alloc (abfd, - (external_reloc_count - * sizeof (struct reloc_and_sec))); - if (external_relocs == (struct reloc_and_sec *) NULL) - goto error_return; - i = 0; - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - arelent **rel_ptr_ptr, **rel_end; - - if (sec->reloc_count == 0) - continue; - - rel_ptr_ptr = sec->orelocation; - rel_end = rel_ptr_ptr + sec->reloc_count; - for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++) - { - arelent *rel; - asymbol *sym; - - rel = *rel_ptr_ptr; - sym = *rel->sym_ptr_ptr; - - if (! bfd_is_und_section (bfd_get_section (sym))) - continue; - - external_relocs[i].rel = rel; - external_relocs[i].sec = sec; - ++i; - } - } - - BFD_ASSERT (i == external_reloc_count); - - /* Sort the external relocs by name. */ - qsort ((PTR) external_relocs, (size_t) external_reloc_count, - sizeof (struct reloc_and_sec), nlm_external_reloc_compare); - - /* Write out the external relocs. */ - nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd); - c = 0; - i = 0; - while (i < external_reloc_count) - { - arelent *rel; - asymbol *sym; - bfd_size_type j, cnt; - - ++c; - - rel = external_relocs[i].rel; - sym = *rel->sym_ptr_ptr; - - cnt = 0; - for (j = i; - (j < external_reloc_count - && *external_relocs[j].rel->sym_ptr_ptr == sym); - j++) - ++cnt; - - if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym, - &external_relocs[i]) - == false) - goto error_return; - - i += cnt; - } - - nlm_fixed_header (abfd)->numberOfExternalReferences = c; - - /* Write out the public symbols (exports). */ - sym_ptr_ptr = bfd_get_outsymbols (abfd); - if (sym_ptr_ptr != (asymbol **) NULL) - { - bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *)); - boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma)); - - asymbol **sym_end; - - nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd); - get_public_offset_func = nlm_get_public_offset_func (abfd); - write_export_func = nlm_write_export_func (abfd); - c = 0; - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); - for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) - { - asymbol *sym; - bfd_byte len; - bfd_vma offset; - bfd_byte temp[NLM_TARGET_LONG_SIZE]; - - sym = *sym_ptr_ptr; - - if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0 - || bfd_is_und_section (bfd_get_section (sym))) - continue; - - ++c; - - if (get_public_offset_func) - { - /* Most backends can use the code below, but - unfortunately some use a different scheme. */ - offset = (*get_public_offset_func) (abfd, sym); - } - else - { - offset = bfd_asymbol_value (sym); - sec = sym->section; - if (sec->flags & SEC_CODE) - { - offset -= nlm_get_text_low (abfd); - offset |= NLM_HIBIT; - } - else if (sec->flags & (SEC_DATA | SEC_ALLOC)) - { - /* SEC_ALLOC is for the .bss section. */ - offset -= nlm_get_data_low (abfd); - } - else - { - /* We can't handle an exported symbol that is not in - the code or data segment. */ - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - } - - if (write_export_func) - { - if ((*write_export_func) (abfd, sym, offset) == false) - goto error_return; - } - else - { - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - goto error_return; - - put_word (abfd, offset, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - goto error_return; - } - } - nlm_fixed_header (abfd)->numberOfPublics = c; - - /* Write out the debugging records. The NLM conversion program - wants to be able to inhibit this, so as a special hack if - debugInfoOffset is set to -1 we don't write any debugging - information. This can not be handled by fiddling with the - symbol table, because exported symbols appear in both the - exported symbol list and the debugging information. */ - if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1) - { - nlm_fixed_header (abfd)->debugInfoOffset = 0; - nlm_fixed_header (abfd)->numberOfDebugRecords = 0; - } - else - { - nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd); - c = 0; - sym_ptr_ptr = bfd_get_outsymbols (abfd); - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); - for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) - { - asymbol *sym; - bfd_byte type, len; - bfd_vma offset; - bfd_byte temp[NLM_TARGET_LONG_SIZE]; - - sym = *sym_ptr_ptr; - - /* The NLM notion of a debugging symbol is actually what - BFD calls a local or global symbol. What BFD calls a - debugging symbol NLM does not understand at all. */ - if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0 - || (sym->flags & BSF_DEBUGGING) != 0 - || bfd_is_und_section (bfd_get_section (sym))) - continue; - - ++c; - - offset = bfd_asymbol_value (sym); - sec = sym->section; - if (sec->flags & SEC_CODE) - { - offset -= nlm_get_text_low (abfd); - type = 1; - } - else if (sec->flags & (SEC_DATA | SEC_ALLOC)) - { - /* SEC_ALLOC is for the .bss section. */ - offset -= nlm_get_data_low (abfd); - type = 0; - } - else - type = 2; - - /* The type is 0 for data, 1 for code, 2 for absolute. */ - if (bfd_write (&type, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - goto error_return; - - put_word (abfd, offset, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - goto error_return; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - goto error_return; - } - nlm_fixed_header (abfd)->numberOfDebugRecords = c; - } - } - - /* NLMLINK fills in offset values even if there is no data, so we do - the same. */ - last = bfd_tell (abfd); - if (nlm_fixed_header (abfd)->codeImageOffset == 0) - nlm_fixed_header (abfd)->codeImageOffset = last; - if (nlm_fixed_header (abfd)->dataImageOffset == 0) - nlm_fixed_header (abfd)->dataImageOffset = last; - if (nlm_fixed_header (abfd)->customDataOffset == 0) - nlm_fixed_header (abfd)->customDataOffset = last; - if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0) - nlm_fixed_header (abfd)->moduleDependencyOffset = last; - if (nlm_fixed_header (abfd)->relocationFixupOffset == 0) - nlm_fixed_header (abfd)->relocationFixupOffset = last; - if (nlm_fixed_header (abfd)->externalReferencesOffset == 0) - nlm_fixed_header (abfd)->externalReferencesOffset = last; - if (nlm_fixed_header (abfd)->publicsOffset == 0) - nlm_fixed_header (abfd)->publicsOffset = last; - if (nlm_fixed_header (abfd)->debugInfoOffset == 0) - nlm_fixed_header (abfd)->debugInfoOffset = last; - - /* At this point everything has been written out except the fixed - header. */ - memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd), - NLM_SIGNATURE_SIZE); - nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION; - nlm_fixed_header (abfd)->codeStartOffset = - (bfd_get_start_address (abfd) - - nlm_get_text_low (abfd)); - - /* We have no convenient way for the caller to pass in the exit - procedure or the check unload procedure, so the caller must set - the values in the header to the values of the symbols. */ - nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd); - if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0) - nlm_fixed_header (abfd)->checkUnloadProcedureOffset -= - nlm_get_text_low (abfd); - - if (bfd_seek (abfd, 0, SEEK_SET) != 0) - goto error_return; - - write_prefix_func = nlm_write_prefix_func (abfd); - if (write_prefix_func) - { - if ((*write_prefix_func) (abfd) == false) - goto error_return; - } - - BFD_ASSERT ((bfd_size_type) bfd_tell (abfd) - == nlm_optional_prefix_size (abfd)); - - nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header); - if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd) - != nlm_fixed_header_size (abfd)) - goto error_return; - - if (fixed_header != NULL) - free (fixed_header); - return true; - -error_return: - if (fixed_header != NULL) - free (fixed_header); - return false; -} diff --git a/contrib/gdb/bfd/nlmswap.h b/contrib/gdb/bfd/nlmswap.h deleted file mode 100644 index 5a9ce7268d0..00000000000 --- a/contrib/gdb/bfd/nlmswap.h +++ /dev/null @@ -1,157 +0,0 @@ -/* NLM (NetWare Loadable Module) swapping routines for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, using ELF support as the - template. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Although this is a header file, it defines functions. It is - included by NLM backends to define swapping functions that vary - from one NLM to another. The backend code must arrange for - Nlm_External_xxxx to be defined appropriately, and can then include - this file to get the swapping routines. - - At the moment this is only needed for one structure, the fixed NLM - file header. */ - -static void nlm_swap_fixed_header_in PARAMS ((bfd *, PTR, - Nlm_Internal_Fixed_Header *)); -static void nlm_swap_fixed_header_out PARAMS ((bfd *, - Nlm_Internal_Fixed_Header *, - PTR)); - -/* Translate an NLM fixed length file header in external format into an NLM - file header in internal format. */ - -static void -nlm_swap_fixed_header_in (abfd, realsrc, dst) - bfd *abfd; - PTR realsrc; - Nlm_Internal_Fixed_Header *dst; -{ - Nlm_External_Fixed_Header *src = (Nlm_External_Fixed_Header *) realsrc; - memcpy (dst->signature, src->signature, NLM_SIGNATURE_SIZE); - memcpy (dst->moduleName, src->moduleName, NLM_MODULE_NAME_SIZE); - dst->version = - bfd_h_get_32 (abfd, (bfd_byte *) src->version); - dst->codeImageOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->codeImageOffset); - dst->codeImageSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->codeImageSize); - dst->dataImageOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->dataImageOffset); - dst->dataImageSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->dataImageSize); - dst->uninitializedDataSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->uninitializedDataSize); - dst->customDataOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->customDataOffset); - dst->customDataSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->customDataSize); - dst->moduleDependencyOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->moduleDependencyOffset); - dst->numberOfModuleDependencies = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfModuleDependencies); - dst->relocationFixupOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->relocationFixupOffset); - dst->numberOfRelocationFixups = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfRelocationFixups); - dst->externalReferencesOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->externalReferencesOffset); - dst->numberOfExternalReferences = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfExternalReferences); - dst->publicsOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->publicsOffset); - dst->numberOfPublics = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfPublics); - dst->debugInfoOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->debugInfoOffset); - dst->numberOfDebugRecords = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfDebugRecords); - dst->codeStartOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->codeStartOffset); - dst->exitProcedureOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->exitProcedureOffset); - dst->checkUnloadProcedureOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->checkUnloadProcedureOffset); - dst->moduleType = - bfd_h_get_32 (abfd, (bfd_byte *) src->moduleType); - dst->flags = - bfd_h_get_32 (abfd, (bfd_byte *) src->flags); -} - -/* Translate an NLM fixed length file header in internal format into - an NLM file header in external format. */ - -static void -nlm_swap_fixed_header_out (abfd, src, realdst) - bfd *abfd; - Nlm_Internal_Fixed_Header *src; - PTR realdst; -{ - Nlm_External_Fixed_Header *dst = (Nlm_External_Fixed_Header *) realdst; - memset (dst, 0, sizeof *dst); - memcpy (dst->signature, src->signature, NLM_SIGNATURE_SIZE); - memcpy (dst->moduleName, src->moduleName, NLM_MODULE_NAME_SIZE); - bfd_h_put_32 (abfd, (bfd_vma) src->version, - (bfd_byte *) dst->version); - bfd_h_put_32 (abfd, (bfd_vma) src->codeImageOffset, - (bfd_byte *) dst->codeImageOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->codeImageSize, - (bfd_byte *) dst->codeImageSize); - bfd_h_put_32 (abfd, (bfd_vma) src->dataImageOffset, - (bfd_byte *) dst->dataImageOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->dataImageSize, - (bfd_byte *) dst->dataImageSize); - bfd_h_put_32 (abfd, (bfd_vma) src->uninitializedDataSize, - (bfd_byte *) dst->uninitializedDataSize); - bfd_h_put_32 (abfd, (bfd_vma) src->customDataOffset, - (bfd_byte *) dst->customDataOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->customDataSize, - (bfd_byte *) dst->customDataSize); - bfd_h_put_32 (abfd, (bfd_vma) src->moduleDependencyOffset, - (bfd_byte *) dst->moduleDependencyOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfModuleDependencies, - (bfd_byte *) dst->numberOfModuleDependencies); - bfd_h_put_32 (abfd, (bfd_vma) src->relocationFixupOffset, - (bfd_byte *) dst->relocationFixupOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfRelocationFixups, - (bfd_byte *) dst->numberOfRelocationFixups); - bfd_h_put_32 (abfd, (bfd_vma) src->externalReferencesOffset, - (bfd_byte *) dst->externalReferencesOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfExternalReferences, - (bfd_byte *) dst->numberOfExternalReferences); - bfd_h_put_32 (abfd, (bfd_vma) src->publicsOffset, - (bfd_byte *) dst->publicsOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfPublics, - (bfd_byte *) dst->numberOfPublics); - bfd_h_put_32 (abfd, (bfd_vma) src->debugInfoOffset, - (bfd_byte *) dst->debugInfoOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfDebugRecords, - (bfd_byte *) dst->numberOfDebugRecords); - bfd_h_put_32 (abfd, (bfd_vma) src->codeStartOffset, - (bfd_byte *) dst->codeStartOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->exitProcedureOffset, - (bfd_byte *) dst->exitProcedureOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->checkUnloadProcedureOffset, - (bfd_byte *) dst->checkUnloadProcedureOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->moduleType, - (bfd_byte *) dst->moduleType); - bfd_h_put_32 (abfd, (bfd_vma) src->flags, - (bfd_byte *) dst->flags); -} diff --git a/contrib/gdb/bfd/ns32knetbsd.c b/contrib/gdb/bfd/ns32knetbsd.c deleted file mode 100644 index 3e3f08a9e58..00000000000 --- a/contrib/gdb/bfd/ns32knetbsd.c +++ /dev/null @@ -1,53 +0,0 @@ -/* BFD back-end for NetBSD/ns32k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#undef TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE 4096 - -#define DEFAULT_ARCH bfd_arch_ns32k -#define MACHTYPE_OK(mtype) ((mtype) == M_532_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(pc532netbsd_,OP) - -#define NAME(x,y) CAT3(ns32kaout,_32_,y) - -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-ns32k-netbsd" - -#define ns32kaout_32_get_section_contents aout_32_get_section_contents - -#define MY_text_includes_header 1 - -/* We can`t use the MYNS macro here for cpp reasons too subtle - * for me -- IWD - */ -#define MY_bfd_reloc_type_lookup ns32kaout_bfd_reloc_type_lookup - -#include "bfd.h" /* To ensure following declaration is OK */ - -CONST struct reloc_howto_struct * -MY_bfd_reloc_type_lookup - PARAMS((bfd *abfd AND - bfd_reloc_code_real_type code)); - - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/oasys.c b/contrib/gdb/bfd/oasys.c deleted file mode 100644 index c72147288af..00000000000 --- a/contrib/gdb/bfd/oasys.c +++ /dev/null @@ -1,1533 +0,0 @@ -/* BFD back-end for oasys objects. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define UNDERSCORE_HACK 1 -#include "bfd.h" -#include "sysdep.h" -#include -#include "libbfd.h" -#include "oasys.h" -#include "liboasys.h" - -/* XXX - FIXME. offsetof belongs in the system-specific files in - ../include/sys. */ -/* Define offsetof for those systems which lack it */ - -#ifndef offsetof -#define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier) -#endif - -static boolean oasys_read_record PARAMS ((bfd *, - oasys_record_union_type *)); -static boolean oasys_write_sections PARAMS ((bfd *)); -static boolean oasys_write_record PARAMS ((bfd *, - oasys_record_enum_type, - oasys_record_union_type *, - size_t)); -static boolean oasys_write_syms PARAMS ((bfd *)); -static boolean oasys_write_header PARAMS ((bfd *)); -static boolean oasys_write_end PARAMS ((bfd *)); -static boolean oasys_write_data PARAMS ((bfd *)); - -/* Read in all the section data and relocation stuff too */ -PROTO (static boolean, oasys_slurp_section_data, (bfd * CONST abfd)); - -static boolean -oasys_read_record (abfd, record) - bfd *abfd; - oasys_record_union_type *record; -{ - if (bfd_read ((PTR) record, 1, sizeof (record->header), abfd) - != sizeof (record->header)) - return false; - - if ((size_t) record->header.length <= (size_t) sizeof (record->header)) - return true; - if (bfd_read ((PTR) (((char *) record) + sizeof (record->header)), - 1, record->header.length - sizeof (record->header), - abfd) - != record->header.length - sizeof (record->header)) - return false; - return true; -} -static size_t -oasys_string_length (record) - oasys_record_union_type *record; -{ - return record->header.length - - ((char *) record->symbol.name - (char *) record); -} - -/*****************************************************************************/ - -/* - -Slurp the symbol table by reading in all the records at the start file -till we get to the first section record. - -We'll sort the symbolss into two lists, defined and undefined. The -undefined symbols will be placed into the table according to their -refno. - -We do this by placing all undefined symbols at the front of the table -moving in, and the defined symbols at the end of the table moving back. - -*/ - -static boolean -oasys_slurp_symbol_table (abfd) - bfd *CONST abfd; -{ - oasys_record_union_type record; - oasys_data_type *data = OASYS_DATA (abfd); - boolean loop = true; - asymbol *dest_defined; - asymbol *dest; - char *string_ptr; - - - if (data->symbols != (asymbol *) NULL) - { - return true; - } - /* Buy enough memory for all the symbols and all the names */ - data->symbols = - (asymbol *) bfd_alloc (abfd, sizeof (asymbol) * abfd->symcount); -#ifdef UNDERSCORE_HACK - /* buy 1 more char for each symbol to keep the underscore in*/ - data->strings = bfd_alloc (abfd, data->symbol_string_length + - abfd->symcount); -#else - data->strings = bfd_alloc (abfd, data->symbol_string_length); -#endif - if (!data->symbols || !data->strings) - return false; - - dest_defined = data->symbols + abfd->symcount - 1; - - string_ptr = data->strings; - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return false; - while (loop) - { - - if (! oasys_read_record (abfd, &record)) - return false; - switch (record.header.type) - { - case oasys_record_is_header_enum: - break; - case oasys_record_is_local_enum: - case oasys_record_is_symbol_enum: - { - int flag = record.header.type == (int) oasys_record_is_local_enum ? - (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT); - - - size_t length = oasys_string_length (&record); - switch (record.symbol.relb & RELOCATION_TYPE_BITS) - { - case RELOCATION_TYPE_ABS: - dest = dest_defined--; - dest->section = bfd_abs_section_ptr; - dest->flags = 0; - - break; - case RELOCATION_TYPE_REL: - dest = dest_defined--; - dest->section = - OASYS_DATA (abfd)->sections[record.symbol.relb & - RELOCATION_SECT_BITS]; - if (record.header.type == (int) oasys_record_is_local_enum) - { - dest->flags = BSF_LOCAL; - if (dest->section == (asection *) (~0)) - { - /* It seems that sometimes internal symbols are tied up, but - still get output, even though there is no - section */ - dest->section = 0; - } - } - else - { - - dest->flags = flag; - } - break; - case RELOCATION_TYPE_UND: - dest = data->symbols + bfd_h_get_16 (abfd, record.symbol.refno); - dest->section = bfd_und_section_ptr; - break; - case RELOCATION_TYPE_COM: - dest = dest_defined--; - dest->name = string_ptr; - dest->the_bfd = abfd; - - dest->section = bfd_com_section_ptr; - - break; - default: - dest = dest_defined--; - BFD_ASSERT (0); - break; - } - dest->name = string_ptr; - dest->the_bfd = abfd; - dest->udata.p = (PTR) NULL; - dest->value = bfd_h_get_32 (abfd, record.symbol.value); - -#ifdef UNDERSCORE_HACK - if (record.symbol.name[0] != '_') - { - string_ptr[0] = '_'; - string_ptr++; - } -#endif - memcpy (string_ptr, record.symbol.name, length); - - - string_ptr[length] = 0; - string_ptr += length + 1; - } - break; - default: - loop = false; - } - } - return true; -} - -static long -oasys_get_symtab_upper_bound (abfd) - bfd *CONST abfd; -{ - if (! oasys_slurp_symbol_table (abfd)) - return -1; - - return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *)); -} - -/* -*/ - -extern const bfd_target oasys_vec; - -long -oasys_get_symtab (abfd, location) - bfd *abfd; - asymbol **location; -{ - asymbol *symbase; - unsigned int counter; - if (oasys_slurp_symbol_table (abfd) == false) - { - return -1; - } - symbase = OASYS_DATA (abfd)->symbols; - for (counter = 0; counter < abfd->symcount; counter++) - { - *(location++) = symbase++; - } - *location = 0; - return abfd->symcount; -} - -/*********************************************************************** -* archive stuff -*/ - -static const bfd_target * -oasys_archive_p (abfd) - bfd *abfd; -{ - oasys_archive_header_type header; - oasys_extarchive_header_type header_ext; - unsigned int i; - file_ptr filepos; - - if (bfd_seek (abfd, (file_ptr) 0, false) != 0 - || (bfd_read ((PTR) & header_ext, 1, sizeof (header_ext), abfd) - != sizeof (header_ext))) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - header.version = bfd_h_get_32 (abfd, header_ext.version); - header.mod_count = bfd_h_get_32 (abfd, header_ext.mod_count); - header.mod_tbl_offset = bfd_h_get_32 (abfd, header_ext.mod_tbl_offset); - header.sym_tbl_size = bfd_h_get_32 (abfd, header_ext.sym_tbl_size); - header.sym_count = bfd_h_get_32 (abfd, header_ext.sym_count); - header.sym_tbl_offset = bfd_h_get_32 (abfd, header_ext.sym_tbl_offset); - header.xref_count = bfd_h_get_32 (abfd, header_ext.xref_count); - header.xref_lst_offset = bfd_h_get_32 (abfd, header_ext.xref_lst_offset); - - /* - There isn't a magic number in an Oasys archive, so the best we - can do to verify reasnableness is to make sure that the values in - the header are too weird - */ - - if (header.version > 10000 || - header.mod_count > 10000 || - header.sym_count > 100000 || - header.xref_count > 100000) - return (const bfd_target *) NULL; - - /* - That all worked, let's buy the space for the header and read in - the headers. - */ - { - oasys_ar_data_type *ar = - (oasys_ar_data_type *) bfd_alloc (abfd, sizeof (oasys_ar_data_type)); - - oasys_module_info_type *module = - (oasys_module_info_type *) - bfd_alloc (abfd, sizeof (oasys_module_info_type) * header.mod_count); - oasys_module_table_type record; - - if (!ar || !module) - return NULL; - - abfd->tdata.oasys_ar_data = ar; - ar->module = module; - ar->module_count = header.mod_count; - - filepos = header.mod_tbl_offset; - for (i = 0; i < header.mod_count; i++) - { - if (bfd_seek (abfd, filepos, SEEK_SET) != 0) - return NULL; - - /* There are two ways of specifying the archive header */ - - if (0) - { - oasys_extmodule_table_type_a_type record_ext; - if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd) - != sizeof (record_ext)) - return NULL; - - record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size); - record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset); - - record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count); - record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count); - record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count); - - module[i].name = bfd_alloc (abfd, 33); - if (!module[i].name) - return NULL; - - memcpy (module[i].name, record_ext.mod_name, 33); - filepos += - sizeof (record_ext) + - record.dep_count * 4 + - record.depee_count * 4 + - record.sect_count * 8 + 187; - } - else - { - oasys_extmodule_table_type_b_type record_ext; - if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd) - != sizeof (record_ext)) - return NULL; - - record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size); - record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset); - - record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count); - record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count); - record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count); - record.module_name_size = bfd_h_get_32 (abfd, record_ext.mod_name_length); - - module[i].name = bfd_alloc (abfd, record.module_name_size + 1); - if (!module[i].name) - return NULL; - if (bfd_read ((PTR) module[i].name, 1, record.module_name_size, - abfd) - != record.module_name_size) - return NULL; - module[i].name[record.module_name_size] = 0; - filepos += - sizeof (record_ext) + - record.dep_count * 4 + - record.module_name_size + 1; - - } - - - module[i].size = record.mod_size; - module[i].pos = record.file_offset; - module[i].abfd = 0; - } - - } - return abfd->xvec; -} - -static boolean -oasys_mkobject (abfd) - bfd *abfd; -{ - - abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, sizeof (oasys_data_type)); - return abfd->tdata.oasys_obj_data ? true : false; -} - -#define MAX_SECS 16 -static const bfd_target * -oasys_object_p (abfd) - bfd *abfd; -{ - oasys_data_type *oasys; - oasys_data_type *save = OASYS_DATA (abfd); - boolean loop = true; - boolean had_usefull = false; - - abfd->tdata.oasys_obj_data = 0; - oasys_mkobject (abfd); - oasys = OASYS_DATA (abfd); - memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections)); - - /* Point to the start of the file */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto fail; - oasys->symbol_string_length = 0; - /* Inspect the records, but only keep the section info - - remember the size of the symbols - */ - oasys->first_data_record = 0; - while (loop) - { - oasys_record_union_type record; - if (! oasys_read_record (abfd, &record)) - goto fail; - if ((size_t) record.header.length < (size_t) sizeof (record.header)) - goto fail; - - - switch ((oasys_record_enum_type) (record.header.type)) - { - case oasys_record_is_header_enum: - had_usefull = true; - break; - case oasys_record_is_symbol_enum: - case oasys_record_is_local_enum: - /* Count symbols and remember their size for a future malloc */ - abfd->symcount++; - oasys->symbol_string_length += 1 + oasys_string_length (&record); - had_usefull = true; - break; - case oasys_record_is_section_enum: - { - asection *s; - char *buffer; - unsigned int section_number; - if (record.section.header.length != sizeof (record.section)) - { - goto fail; - } - buffer = bfd_alloc (abfd, 3); - if (!buffer) - goto fail; - section_number = record.section.relb & RELOCATION_SECT_BITS; - sprintf (buffer, "%u", section_number); - s = bfd_make_section (abfd, buffer); - oasys->sections[section_number] = s; - switch (record.section.relb & RELOCATION_TYPE_BITS) - { - case RELOCATION_TYPE_ABS: - case RELOCATION_TYPE_REL: - break; - case RELOCATION_TYPE_UND: - case RELOCATION_TYPE_COM: - BFD_FAIL (); - } - - s->_raw_size = bfd_h_get_32 (abfd, record.section.value); - s->vma = bfd_h_get_32 (abfd, record.section.vma); - s->flags = 0; - had_usefull = true; - } - break; - case oasys_record_is_data_enum: - oasys->first_data_record = bfd_tell (abfd) - record.header.length; - case oasys_record_is_debug_enum: - case oasys_record_is_module_enum: - case oasys_record_is_named_section_enum: - case oasys_record_is_end_enum: - if (had_usefull == false) - goto fail; - loop = false; - break; - default: - goto fail; - } - } - oasys->symbols = (asymbol *) NULL; - /* - Oasys support several architectures, but I can't see a simple way - to discover which one is in a particular file - we'll guess - */ - bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); - if (abfd->symcount != 0) - { - abfd->flags |= HAS_SYMS; - } - - /* - We don't know if a section has data until we've read it.. - */ - - oasys_slurp_section_data (abfd); - - - return abfd->xvec; - -fail: - (void) bfd_release (abfd, oasys); - abfd->tdata.oasys_obj_data = save; - return (const bfd_target *) NULL; -} - - -static void -oasys_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); - if (!symbol->section) - ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; -} - -static void -oasys_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - - switch (how) - { - case bfd_print_symbol_name: - case bfd_print_symbol_more: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_all: - { - CONST char *section_name = symbol->section == (asection *) NULL ? - (CONST char *) "*abs" : symbol->section->name; - - bfd_print_symbol_vandf ((PTR) file, symbol); - - fprintf (file, " %-5s %s", - section_name, - symbol->name); - } - break; - } -} -/* - The howto table is build using the top two bits of a reloc byte to - index into it. The bits are PCREL,WORD/LONG -*/ -static reloc_howto_type howto_table[] = -{ - - HOWTO (0, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (0, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs32", true, 0xffffffff, 0xffffffff, false), - HOWTO (0, 0, 1, 16, true, 0, complain_overflow_signed, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (0, 0, 2, 32, true, 0, complain_overflow_signed, 0, "pcrel32", true, 0xffffffff, 0xffffffff, false) -}; - -/* Read in all the section data and relocation stuff too */ -static boolean -oasys_slurp_section_data (abfd) - bfd *CONST abfd; -{ - oasys_record_union_type record; - oasys_data_type *data = OASYS_DATA (abfd); - boolean loop = true; - - oasys_per_section_type *per; - - asection *s; - - /* See if the data has been slurped already .. */ - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - per = oasys_per_section (s); - if (per->initialized == true) - return true; - } - - if (data->first_data_record == 0) - return true; - - if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0) - return false; - while (loop) - { - if (! oasys_read_record (abfd, &record)) - return false; - switch (record.header.type) - { - case oasys_record_is_header_enum: - break; - case oasys_record_is_data_enum: - { - - bfd_byte *src = record.data.data; - bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length; - bfd_byte *dst_ptr; - bfd_byte *dst_base_ptr; - unsigned int relbit; - unsigned int count; - asection *section = - data->sections[record.data.relb & RELOCATION_SECT_BITS]; - bfd_vma dst_offset; - - per = oasys_per_section (section); - - if (per->initialized == false) - { - per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size); - if (!per->data) - return false; - per->reloc_tail_ptr = (oasys_reloc_type **) & (section->relocation); - per->had_vma = false; - per->initialized = true; - section->reloc_count = 0; - section->flags = SEC_ALLOC; - } - - dst_offset = bfd_h_get_32 (abfd, record.data.addr); - if (per->had_vma == false) - { - /* Take the first vma we see as the base */ - section->vma = dst_offset; - per->had_vma = true; - } - - dst_offset -= section->vma; - - dst_base_ptr = oasys_per_section (section)->data; - dst_ptr = oasys_per_section (section)->data + - dst_offset; - - if (src < end_src) - { - section->flags |= SEC_LOAD | SEC_HAS_CONTENTS; - } - while (src < end_src) - { - unsigned char mod_byte = *src++; - size_t gap = end_src - src; - - count = 8; - if (mod_byte == 0 && gap >= 8) - { - dst_ptr[0] = src[0]; - dst_ptr[1] = src[1]; - dst_ptr[2] = src[2]; - dst_ptr[3] = src[3]; - dst_ptr[4] = src[4]; - dst_ptr[5] = src[5]; - dst_ptr[6] = src[6]; - dst_ptr[7] = src[7]; - dst_ptr += 8; - src += 8; - } - else - { - for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1) - { - if (relbit & mod_byte) - { - unsigned char reloc = *src; - /* This item needs to be relocated */ - switch (reloc & RELOCATION_TYPE_BITS) - { - case RELOCATION_TYPE_ABS: - - break; - - case RELOCATION_TYPE_REL: - { - /* Relocate the item relative to the section */ - oasys_reloc_type *r = - (oasys_reloc_type *) - bfd_alloc (abfd, - sizeof (oasys_reloc_type)); - if (!r) - return false; - *(per->reloc_tail_ptr) = r; - per->reloc_tail_ptr = &r->next; - r->next = (oasys_reloc_type *) NULL; - /* Reference to undefined symbol */ - src++; - /* There is no symbol */ - r->symbol = 0; - /* Work out the howto */ - abort (); -#if 0 - r->relent.section = - data->sections[reloc & - RELOCATION_SECT_BITS]; - - r->relent.addend = - - r->relent.section->vma; -#endif - r->relent.address = dst_ptr - dst_base_ptr; - r->relent.howto = &howto_table[reloc >> 6]; - r->relent.sym_ptr_ptr = (asymbol **) NULL; - section->reloc_count++; - - /* Fake up the data to look like it's got the -ve pc in it, this makes - it much easier to convert into other formats. This is done by - hitting the addend. - */ - if (r->relent.howto->pc_relative == true) - { - r->relent.addend -= dst_ptr - dst_base_ptr; - } - - - } - break; - - - case RELOCATION_TYPE_UND: - { - oasys_reloc_type *r = - (oasys_reloc_type *) - bfd_alloc (abfd, - sizeof (oasys_reloc_type)); - if (!r) - return false; - *(per->reloc_tail_ptr) = r; - per->reloc_tail_ptr = &r->next; - r->next = (oasys_reloc_type *) NULL; - /* Reference to undefined symbol */ - src++; - /* Get symbol number */ - r->symbol = (src[0] << 8) | src[1]; - /* Work out the howto */ - abort (); - -#if 0 - r->relent.section = (asection - *) NULL; -#endif - r->relent.addend = 0; - r->relent.address = dst_ptr - dst_base_ptr; - r->relent.howto = &howto_table[reloc >> 6]; - r->relent.sym_ptr_ptr = (asymbol **) NULL; - section->reloc_count++; - - src += 2; - /* Fake up the data to look like it's got the -ve pc in it, this makes - it much easier to convert into other formats. This is done by - hitting the addend. - */ - if (r->relent.howto->pc_relative == true) - { - r->relent.addend -= dst_ptr - dst_base_ptr; - } - - - - } - break; - case RELOCATION_TYPE_COM: - BFD_FAIL (); - } - } - *dst_ptr++ = *src++; - } - } - } - } - break; - case oasys_record_is_local_enum: - case oasys_record_is_symbol_enum: - case oasys_record_is_section_enum: - break; - default: - loop = false; - } - } - - return true; - -} - -static boolean -oasys_new_section_hook (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - newsect->used_by_bfd = (PTR) - bfd_alloc (abfd, sizeof (oasys_per_section_type)); - if (!newsect->used_by_bfd) - return false; - oasys_per_section (newsect)->data = (bfd_byte *) NULL; - oasys_per_section (newsect)->section = newsect; - oasys_per_section (newsect)->offset = 0; - oasys_per_section (newsect)->initialized = false; - newsect->alignment_power = 1; - /* Turn the section string into an index */ - - sscanf (newsect->name, "%u", &newsect->target_index); - - return true; -} - - -static long -oasys_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (! oasys_slurp_section_data (abfd)) - return -1; - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -static boolean -oasys_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd; - oasys_slurp_section_data (abfd); - if (p->initialized == false) - { - (void) memset (location, 0, (int) count); - } - else - { - (void) memcpy (location, (PTR) (p->data + offset), (int) count); - } - return true; -} - - -long -oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols) - bfd *ignore_abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - unsigned int reloc_count = 0; - oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation); - while (src != (oasys_reloc_type *) NULL) - { - abort (); - -#if 0 - if (src->relent.section == (asection *) NULL) - { - src->relent.sym_ptr_ptr = symbols + src->symbol; - } -#endif - - *relptr++ = &src->relent; - src = src->next; - reloc_count++; - } - *relptr = (arelent *) NULL; - return section->reloc_count = reloc_count; -} - - - - -/* Writing */ - - -/* Calculate the checksum and write one record */ -static boolean -oasys_write_record (abfd, type, record, size) - bfd *abfd; - oasys_record_enum_type type; - oasys_record_union_type *record; - size_t size; -{ - int checksum; - size_t i; - unsigned char *ptr; - - record->header.length = size; - record->header.type = (int) type; - record->header.check_sum = 0; - record->header.fill = 0; - ptr = (unsigned char *) &record->pad[0]; - checksum = 0; - for (i = 0; i < size; i++) - { - checksum += *ptr++; - } - record->header.check_sum = 0xff & (-checksum); - if (bfd_write ((PTR) record, 1, size, abfd) != size) - return false; - return true; -} - - -/* Write out all the symbols */ -static boolean -oasys_write_syms (abfd) - bfd *abfd; -{ - unsigned int count; - asymbol **generic = bfd_get_outsymbols (abfd); - unsigned int index = 0; - for (count = 0; count < bfd_get_symcount (abfd); count++) - { - - oasys_symbol_record_type symbol; - asymbol *CONST g = generic[count]; - - CONST char *src = g->name; - char *dst = symbol.name; - unsigned int l = 0; - - if (bfd_is_com_section (g->section)) - { - symbol.relb = RELOCATION_TYPE_COM; - bfd_h_put_16 (abfd, index, symbol.refno); - index++; - } - else if (bfd_is_abs_section (g->section)) - { - symbol.relb = RELOCATION_TYPE_ABS; - bfd_h_put_16 (abfd, 0, symbol.refno); - - } - else if (bfd_is_und_section (g->section)) - { - symbol.relb = RELOCATION_TYPE_UND; - bfd_h_put_16 (abfd, index, symbol.refno); - /* Overload the value field with the output index number */ - index++; - } - else if (g->flags & BSF_DEBUGGING) - { - /* throw it away */ - continue; - } - else - { - if (g->section == (asection *) NULL) - { - /* Sometime, the oasys tools give out a symbol with illegal - bits in it, we'll output it in the same broken way */ - - symbol.relb = RELOCATION_TYPE_REL | 0; - } - else - { - symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index; - } - bfd_h_put_16 (abfd, 0, symbol.refno); - } -#ifdef UNDERSCORE_HACK - if (src[l] == '_') - dst[l++] = '.'; -#endif - while (src[l]) - { - dst[l] = src[l]; - l++; - } - - bfd_h_put_32 (abfd, g->value, symbol.value); - - - if (g->flags & BSF_LOCAL) - { - if (! oasys_write_record (abfd, - oasys_record_is_local_enum, - (oasys_record_union_type *) & symbol, - offsetof (oasys_symbol_record_type, - name[0]) + l)) - return false; - } - else - { - if (! oasys_write_record (abfd, - oasys_record_is_symbol_enum, - (oasys_record_union_type *) & symbol, - offsetof (oasys_symbol_record_type, - name[0]) + l)) - return false; - } - g->value = index - 1; - } - - return true; -} - - - /* Write a section header for each section */ -static boolean -oasys_write_sections (abfd) - bfd *abfd; -{ - asection *s; - static oasys_section_record_type out; - - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (!isdigit (s->name[0])) - { - (*_bfd_error_handler) - ("%s: can not represent section `%s' in oasys", - bfd_get_filename (abfd), s->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - out.relb = RELOCATION_TYPE_REL | s->target_index; - bfd_h_put_32 (abfd, s->_cooked_size, out.value); - bfd_h_put_32 (abfd, s->vma, out.vma); - - if (! oasys_write_record (abfd, - oasys_record_is_section_enum, - (oasys_record_union_type *) & out, - sizeof (out))) - return false; - } - return true; -} - -static boolean -oasys_write_header (abfd) - bfd *abfd; -{ - /* Create and write the header */ - oasys_header_record_type r; - size_t length = strlen (abfd->filename); - if (length > (size_t) sizeof (r.module_name)) - { - length = sizeof (r.module_name); - } - - (void) memcpy (r.module_name, - abfd->filename, - length); - (void) memset (r.module_name + length, - ' ', - sizeof (r.module_name) - length); - - r.version_number = OASYS_VERSION_NUMBER; - r.rev_number = OASYS_REV_NUMBER; - if (! oasys_write_record (abfd, - oasys_record_is_header_enum, - (oasys_record_union_type *) & r, - offsetof (oasys_header_record_type, - description[0]))) - return false; - - return true; -} - -static boolean -oasys_write_end (abfd) - bfd *abfd; -{ - oasys_end_record_type end; - unsigned char null = 0; - end.relb = RELOCATION_TYPE_ABS; - bfd_h_put_32 (abfd, abfd->start_address, end.entry); - bfd_h_put_16 (abfd, 0, end.fill); - end.zero = 0; - if (! oasys_write_record (abfd, - oasys_record_is_end_enum, - (oasys_record_union_type *) & end, - sizeof (end))) - return false; - if (bfd_write ((PTR) & null, 1, 1, abfd) != 1) - return false; - return true; -} - -static int -comp (ap, bp) - CONST PTR ap; - CONST PTR bp; -{ - arelent *a = *((arelent **) ap); - arelent *b = *((arelent **) bp); - return a->address - b->address; -} - -/* - Writing data.. - -*/ -static boolean -oasys_write_data (abfd) - bfd *abfd; -{ - asection *s; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (s->flags & SEC_LOAD) - { - bfd_byte *raw_data = oasys_per_section (s)->data; - oasys_data_record_type processed_data; - bfd_size_type current_byte_index = 0; - unsigned int relocs_to_go = s->reloc_count; - arelent **p = s->orelocation; - if (s->reloc_count != 0) - { -/* Sort the reloc records so it's easy to insert the relocs into the - data */ - - qsort (s->orelocation, - s->reloc_count, - sizeof (arelent **), - comp); - } - current_byte_index = 0; - processed_data.relb = s->target_index | RELOCATION_TYPE_REL; - - while (current_byte_index < s->_cooked_size) - { - /* Scan forwards by eight bytes or however much is left and see if - there are any relocations going on */ - bfd_byte *mod = &processed_data.data[0]; - bfd_byte *dst = &processed_data.data[1]; - - unsigned int i = 0; - *mod = 0; - - - bfd_h_put_32 (abfd, s->vma + current_byte_index, - processed_data.addr); - - /* Don't start a relocation unless you're sure you can finish it - within the same data record. The worst case relocation is a - 4-byte relocatable value which is split across two modification - bytes (1 relocation byte + 2 symbol reference bytes + 2 data + - 1 modification byte + 2 data = 8 bytes total). That's where - the magic number 8 comes from. - */ - while (current_byte_index < s->_raw_size && dst <= - &processed_data.data[sizeof (processed_data.data) - 8]) - { - - - if (relocs_to_go != 0) - { - arelent *r = *p; - reloc_howto_type *const how = r->howto; - /* There is a relocation, is it for this byte ? */ - if (r->address == current_byte_index) - { - unsigned char rel_byte; - - p++; - relocs_to_go--; - - *mod |= (1 << i); - if (how->pc_relative) - { - rel_byte = RELOCATION_PCREL_BIT; - - /* Also patch the raw data so that it doesn't have - the -ve stuff any more */ - if (how->size != 2) - { - bfd_put_16 (abfd, - bfd_get_16 (abfd, raw_data) + - current_byte_index, raw_data); - } - - else - { - bfd_put_32 (abfd, - bfd_get_32 (abfd, raw_data) + - current_byte_index, raw_data); - } - } - else - { - rel_byte = 0; - } - if (how->size == 2) - { - rel_byte |= RELOCATION_32BIT_BIT; - } - - /* Is this a section relative relocation, or a symbol - relative relocation ? */ - abort (); - -#if 0 - if (r->section != (asection *) NULL) - { - /* The relent has a section attached, so it must be section - relative */ - rel_byte |= RELOCATION_TYPE_REL; - rel_byte |= r->section->output_section->target_index; - *dst++ = rel_byte; - } - else -#endif - { - asymbol *p = *(r->sym_ptr_ptr); - - /* If this symbol has a section attached, then it - has already been resolved. Change from a symbol - ref to a section ref */ - if (p->section != (asection *) NULL) - { - rel_byte |= RELOCATION_TYPE_REL; - rel_byte |= - p->section->output_section->target_index; - *dst++ = rel_byte; - } - else - { - rel_byte |= RELOCATION_TYPE_UND; - *dst++ = rel_byte; - /* Next two bytes are a symbol index - we can get - this from the symbol value which has been zapped - into the symbol index in the table when the - symbol table was written - */ - *dst++ = p->value >> 8; - *dst++ = p->value; - } - } -#define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; } - /* relocations never occur from an unloadable section, - so we can assume that raw_data is not NULL - */ - *dst++ = *raw_data++; - ADVANCE - * dst++ = *raw_data++; - ADVANCE - if (how->size == 2) - { - *dst++ = *raw_data++; - ADVANCE - * dst++ = *raw_data++; - ADVANCE - } - continue; - } - } - /* If this is coming from an unloadable section then copy - zeros */ - if (raw_data == NULL) - { - *dst++ = 0; - } - else - { - *dst++ = *raw_data++; - } - ADVANCE - } - - /* Don't write a useless null modification byte */ - if (dst == mod + 1) - { - --dst; - } - - if (! oasys_write_record (abfd, - oasys_record_is_data_enum, - ((oasys_record_union_type *) - & processed_data), - dst - (bfd_byte *) & processed_data)) - return false; - } - } - } - - return true; -} - -static boolean -oasys_write_object_contents (abfd) - bfd *abfd; -{ - if (! oasys_write_header (abfd)) - return false; - if (! oasys_write_syms (abfd)) - return false; - if (! oasys_write_sections (abfd)) - return false; - if (! oasys_write_data (abfd)) - return false; - if (! oasys_write_end (abfd)) - return false; - return true; -} - - - - -/** exec and core file sections */ - -/* set section contents is complicated with OASYS since the format is -* not a byte image, but a record stream. -*/ -static boolean -oasys_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (count != 0) - { - if (oasys_per_section (section)->data == (bfd_byte *) NULL) - { - oasys_per_section (section)->data = - (bfd_byte *) (bfd_alloc (abfd, section->_cooked_size)); - if (!oasys_per_section (section)->data) - return false; - } - (void) memcpy ((PTR) (oasys_per_section (section)->data + offset), - location, - (size_t) count); - } - return true; -} - - - -/* Native-level interface to symbols. */ - -/* We read the symbols into a buffer, which is discarded when this -function exits. We read the strings into a buffer large enough to -hold them all plus all the cached symbol entries. */ - -static asymbol * -oasys_make_empty_symbol (abfd) - bfd *abfd; -{ - - oasys_symbol_type *new = - (oasys_symbol_type *) bfd_zalloc (abfd, sizeof (oasys_symbol_type)); - if (!new) - return NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - - - - -/* User should have checked the file flags; perhaps we should return -BFD_NO_MORE_SYMBOLS if there are none? */ - -static bfd * -oasys_openr_next_archived_file (arch, prev) - bfd *arch; - bfd *prev; -{ - oasys_ar_data_type *ar = OASYS_AR_DATA (arch); - oasys_module_info_type *p; - /* take the next one from the arch state, or reset */ - if (prev == (bfd *) NULL) - { - /* Reset the index - the first two entries are bogus*/ - ar->module_index = 0; - } - - p = ar->module + ar->module_index; - ar->module_index++; - - if (ar->module_index <= ar->module_count) - { - if (p->abfd == (bfd *) NULL) - { - p->abfd = _bfd_create_empty_archive_element_shell (arch); - p->abfd->origin = p->pos; - p->abfd->filename = p->name; - - /* Fixup a pointer to this element for the member */ - p->abfd->arelt_data = (PTR) p; - } - return p->abfd; - } - else - { - bfd_set_error (bfd_error_no_more_archived_files); - return (bfd *) NULL; - } -} - -static boolean -oasys_find_nearest_line (abfd, - section, - symbols, - offset, - filename_ptr, - functionname_ptr, - line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - char **filename_ptr; - char **functionname_ptr; - unsigned int *line_ptr; -{ - return false; - -} - -static int -oasys_generic_stat_arch_elt (abfd, buf) - bfd *abfd; - struct stat *buf; -{ - oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data; - if (mod == (oasys_module_info_type *) NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - else - { - buf->st_size = mod->size; - buf->st_mode = 0666; - return 0; - } -} - -static int -oasys_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -#define oasys_close_and_cleanup _bfd_generic_close_and_cleanup -#define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info - -#define oasys_slurp_armap bfd_true -#define oasys_slurp_extended_name_table bfd_true -#define oasys_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_true) -#define oasys_truncate_arname bfd_dont_truncate_arname -#define oasys_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_true) -#define oasys_read_ar_hdr bfd_nullvoidptr -#define oasys_get_elt_at_index _bfd_generic_get_elt_at_index -#define oasys_update_armap_timestamp bfd_true - -#define oasys_bfd_is_local_label bfd_generic_is_local_label -#define oasys_get_lineno _bfd_nosymbols_get_lineno -#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define oasys_read_minisymbols _bfd_generic_read_minisymbols -#define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define oasys_set_arch_mach bfd_default_set_arch_mach - -#define oasys_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define oasys_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define oasys_bfd_relax_section bfd_generic_relax_section -#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define oasys_bfd_final_link _bfd_generic_final_link -#define oasys_bfd_link_split_section _bfd_generic_link_split_section - -/*SUPPRESS 460 */ -const bfd_target oasys_vec = -{ - "oasys", /* name */ - bfd_target_oasys_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, - oasys_object_p, /* bfd_check_format */ - oasys_archive_p, - _bfd_dummy_target, - }, - { /* bfd_set_format */ - bfd_false, - oasys_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { /* bfd_write_contents */ - bfd_false, - oasys_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (oasys), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (oasys), - BFD_JUMP_TABLE_SYMBOLS (oasys), - BFD_JUMP_TABLE_RELOCS (oasys), - BFD_JUMP_TABLE_WRITE (oasys), - BFD_JUMP_TABLE_LINK (oasys), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/opncls.c b/contrib/gdb/bfd/opncls.c deleted file mode 100644 index 54528dbf48f..00000000000 --- a/contrib/gdb/bfd/opncls.c +++ /dev/null @@ -1,604 +0,0 @@ -/* opncls.c -- open and close a BFD. - Copyright (C) 1990 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -#ifndef S_IXUSR -#define S_IXUSR 0100 /* Execute by owner. */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 /* Execute by group. */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 /* Execute by others. */ -#endif - -/* fdopen is a loser -- we should use stdio exclusively. Unfortunately - if we do that we can't use fcntl. */ - - -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free - -#ifndef HAVE_GETPAGESIZE -#define getpagesize() 2048 -#endif - -long _bfd_chunksize = -1; - -/* Return a new BFD. All BFD's are allocated through this routine. */ - -bfd * -_bfd_new_bfd () -{ - bfd *nbfd; - - nbfd = (bfd *)bfd_zmalloc (sizeof (bfd)); - if (!nbfd) - return 0; - - if (_bfd_chunksize <= 0) - { - _bfd_chunksize = getpagesize (); - if (_bfd_chunksize <= 0) - _bfd_chunksize = 2048; - /* Leave some slush space, since many malloc implementations - prepend a header, and may wind up wasting another page - because of it. */ - _bfd_chunksize -= 32; - } - - if (!obstack_begin(&nbfd->memory, _bfd_chunksize)) - { - bfd_set_error (bfd_error_no_memory); - return 0; - } - - nbfd->arch_info = &bfd_default_arch_struct; - - nbfd->direction = no_direction; - nbfd->iostream = NULL; - nbfd->where = 0; - nbfd->sections = (asection *)NULL; - nbfd->format = bfd_unknown; - nbfd->my_archive = (bfd *)NULL; - nbfd->origin = 0; - nbfd->opened_once = false; - nbfd->output_has_begun = false; - nbfd->section_count = 0; - nbfd->usrdata = (PTR)NULL; - nbfd->cacheable = false; - nbfd->flags = NO_FLAGS; - nbfd->mtime_set = false; - - return nbfd; -} - -/* Allocate a new BFD as a member of archive OBFD. */ - -bfd * -_bfd_new_bfd_contained_in (obfd) - bfd *obfd; -{ - bfd *nbfd; - - nbfd = _bfd_new_bfd(); - nbfd->xvec = obfd->xvec; - nbfd->my_archive = obfd; - nbfd->direction = read_direction; - nbfd->target_defaulted = obfd->target_defaulted; - return nbfd; -} - -/* -SECTION - Opening and closing BFDs - -*/ - -/* -FUNCTION - bfd_openr - -SYNOPSIS - bfd *bfd_openr(CONST char *filename, CONST char *target); - -DESCRIPTION - Open the file @var{filename} (using <>) with the target - @var{target}. Return a pointer to the created BFD. - - Calls <>, so @var{target} is interpreted as by - that function. - - If <> is returned then an error has occured. Possible errors - are <>, <> or <> error. -*/ - -bfd * -bfd_openr (filename, target) - CONST char *filename; - CONST char *target; -{ - bfd *nbfd; - const bfd_target *target_vec; - - nbfd = _bfd_new_bfd(); - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) { - bfd_set_error (bfd_error_invalid_target); - return NULL; - } - - nbfd->filename = filename; - nbfd->direction = read_direction; - - if (bfd_open_file (nbfd) == NULL) { - bfd_set_error (bfd_error_system_call); /* File didn't exist, or some such */ - bfd_release(nbfd,0); - return NULL; - } - return nbfd; -} - - -/* Don't try to `optimize' this function: - - o - We lock using stack space so that interrupting the locking - won't cause a storage leak. - o - We open the file stream last, since we don't want to have to - close it if anything goes wrong. Closing the stream means closing - the file descriptor too, even though we didn't open it. - */ -/* -FUNCTION - bfd_fdopenr - -SYNOPSIS - bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd); - -DESCRIPTION - <> is to <> much like <> is to <>. - It opens a BFD on a file already described by the @var{fd} - supplied. - - When the file is later <>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), call - bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to - assume no cacheing; the file descriptor will remain open until - <>, and will not be affected by BFD operations on other - files. - - Possible errors are <>, <> and <>. -*/ - -bfd * -bfd_fdopenr (filename, target, fd) - CONST char *filename; - CONST char *target; - int fd; -{ - bfd *nbfd; - const bfd_target *target_vec; - int fdflags; - - bfd_set_error (bfd_error_system_call); -#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL) - fdflags = O_RDWR; /* Assume full access */ -#else - fdflags = fcntl (fd, F_GETFL, NULL); -#endif - if (fdflags == -1) return NULL; - - nbfd = _bfd_new_bfd(); - - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) { - bfd_set_error (bfd_error_invalid_target); - return NULL; - } -#if defined(VMS) || defined(__GO32__) || defined (WINGDB) - nbfd->iostream = (PTR)fopen(filename, FOPEN_RB); -#else - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ - switch (fdflags & (O_ACCMODE)) { - case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break; - case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break; - case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break; - default: abort (); - } -#endif - if (nbfd->iostream == NULL) { - (void) obstack_free (&nbfd->memory, (PTR)0); - return NULL; - } - - /* OK, put everything where it belongs */ - - nbfd->filename = filename; - - /* As a special case we allow a FD open for read/write to - be written through, although doing so requires that we end - the previous clause with a preposition. */ - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ - switch (fdflags & (O_ACCMODE)) { - case O_RDONLY: nbfd->direction = read_direction; break; - case O_WRONLY: nbfd->direction = write_direction; break; - case O_RDWR: nbfd->direction = both_direction; break; - default: abort (); - } - - if (! bfd_cache_init (nbfd)) - return NULL; - - return nbfd; -} - -/* -FUNCTION - bfd_openstreamr - -SYNOPSIS - bfd *bfd_openstreamr(); - -DESCRIPTION - - Open a BFD for read access on an existing stdio stream. When - the BFD is passed to <>, the stream will be closed. -*/ - -bfd * -bfd_openstreamr (filename, target, stream) - const char *filename; - const char *target; - FILE *stream; -{ - bfd *nbfd; - const bfd_target *target_vec; - - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) - { - bfd_set_error (bfd_error_invalid_target); - return NULL; - } - - nbfd->iostream = (PTR) stream; - nbfd->filename = filename; - nbfd->direction = read_direction; - - if (! bfd_cache_init (nbfd)) - return NULL; - - return nbfd; -} - -/** bfd_openw -- open for writing. - Returns a pointer to a freshly-allocated BFD on success, or NULL. - - See comment by bfd_fdopenr before you try to modify this function. */ - -/* -FUNCTION - bfd_openw - -SYNOPSIS - bfd *bfd_openw(CONST char *filename, CONST char *target); - -DESCRIPTION - Create a BFD, associated with file @var{filename}, using the - file format @var{target}, and return a pointer to it. - - Possible errors are <>, <>, - <>. -*/ - -bfd * -bfd_openw (filename, target) - CONST char *filename; - CONST char *target; -{ - bfd *nbfd; - const bfd_target *target_vec; - - 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 = _bfd_new_bfd(); - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) return NULL; - - nbfd->filename = filename; - nbfd->direction = write_direction; - - if (bfd_open_file (nbfd) == NULL) { - bfd_set_error (bfd_error_system_call); /* File not writeable, etc */ - (void) obstack_free (&nbfd->memory, (PTR)0); - return NULL; - } - return nbfd; -} - -/* - -FUNCTION - bfd_close - -SYNOPSIS - boolean bfd_close(bfd *abfd); - -DESCRIPTION - - 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 - <> is called to mark it as such. - - All memory attached to the BFD's obstacks is released. - - The file descriptor associated with the BFD is closed (even - if it was passed in to BFD by <>). - -RETURNS - <> is returned if all is ok, otherwise <>. -*/ - - -boolean -bfd_close (abfd) - bfd *abfd; -{ - boolean ret; - - if (!bfd_read_p (abfd)) - { - if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd))) - return false; - } - - if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) - return false; - - ret = bfd_cache_close (abfd); - - /* If the file was open for writing and is now executable, - make it so */ - if (ret - && abfd->direction == write_direction - && abfd->flags & EXEC_P) - { - struct stat buf; - - if (stat (abfd->filename, &buf) == 0) - { - int mask = umask (0); - umask (mask); - chmod (abfd->filename, - (0777 - & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask)))); - } - } - - (void) obstack_free (&abfd->memory, (PTR)0); - (void) free (abfd); - - return ret; -} - -/* -FUNCTION - bfd_close_all_done - -SYNOPSIS - boolean bfd_close_all_done(bfd *); - -DESCRIPTION - Close a BFD. Differs from <> - since it does not complete any pending operations. This - routine would be used if the application had just used BFD for - swapping and didn't want to use any of the writing code. - - If the created file is executable, then <> is called - to mark it as such. - - All memory attached to the BFD's obstacks is released. - -RETURNS - <> is returned if all is ok, otherwise <>. - -*/ - -boolean -bfd_close_all_done (abfd) - bfd *abfd; -{ - boolean ret; - - ret = bfd_cache_close (abfd); - - /* If the file was open for writing and is now executable, - make it so */ - if (ret - && abfd->direction == write_direction - && abfd->flags & EXEC_P) - { - struct stat buf; - - if (stat (abfd->filename, &buf) == 0) - { - int mask = umask (0); - umask (mask); - chmod (abfd->filename, - (0x777 - & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask)))); - } - } - (void) obstack_free (&abfd->memory, (PTR)0); - (void) free(abfd); - return ret; -} - - -/* -FUNCTION - bfd_alloc_size - -SYNOPSIS - bfd_size_type bfd_alloc_size(bfd *abfd); - -DESCRIPTION - Return the number of bytes in the obstacks connected to @var{abfd}. - -*/ - -bfd_size_type -bfd_alloc_size (abfd) - bfd *abfd; -{ - struct _obstack_chunk *chunk = abfd->memory.chunk; - size_t size = 0; - while (chunk) { - size += chunk->limit - &(chunk->contents[0]); - chunk = chunk->prev; - } - return size; -} - - - -/* -FUNCTION - bfd_create - -SYNOPSIS - bfd *bfd_create(CONST char *filename, bfd *templ); - -DESCRIPTION - Create a new BFD in the manner of - <>, 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 * -bfd_create (filename, templ) - CONST char *filename; - bfd *templ; -{ - bfd *nbfd = _bfd_new_bfd(); - if (nbfd == (bfd *)NULL) - return (bfd *)NULL; - nbfd->filename = filename; - if(templ) { - nbfd->xvec = templ->xvec; - } - nbfd->direction = no_direction; - bfd_set_format(nbfd, bfd_object); - return nbfd; -} - -/* -INTERNAL_FUNCTION - bfd_alloc_by_size_t - -SYNOPSIS - PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted); - -DESCRIPTION - Allocate a block of @var{wanted} bytes of memory in the obstack - attatched to <> and return a pointer to it. -*/ - - -PTR -bfd_alloc_by_size_t (abfd, size) - bfd *abfd; - size_t size; -{ - PTR ret; - - ret = obstack_alloc (&(abfd->memory), size); - if (ret == NULL) - bfd_set_error (bfd_error_no_memory); - return ret; -} - -void -bfd_alloc_grow (abfd, ptr, size) - bfd *abfd; - PTR ptr; - size_t size; -{ - (void) obstack_grow(&(abfd->memory), ptr, size); -} - -PTR -bfd_alloc_finish (abfd) - bfd *abfd; -{ - PTR ret; - - ret = obstack_finish (&(abfd->memory)); - if (ret == NULL) - bfd_set_error (bfd_error_no_memory); - return ret; -} - -PTR -bfd_alloc (abfd, size) - bfd *abfd; - size_t size; -{ - return bfd_alloc_by_size_t(abfd, (size_t)size); -} - -PTR -bfd_zalloc (abfd, size) - bfd *abfd; - size_t size; -{ - PTR res; - res = bfd_alloc(abfd, size); - if (res) - memset(res, 0, (size_t)size); - return res; -} diff --git a/contrib/gdb/bfd/osf-core.c b/contrib/gdb/bfd/osf-core.c deleted file mode 100644 index 6d1df9b3709..00000000000 --- a/contrib/gdb/bfd/osf-core.c +++ /dev/null @@ -1,256 +0,0 @@ -/* BFD back-end for OSF/1 core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file can only be compiled on systems which use OSF/1 style - core files. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include -#include -#include -#include - -/* forward declarations */ - -static asection * -make_bfd_asection PARAMS ((bfd *, CONST char *, flagword, bfd_size_type, - bfd_vma, file_ptr)); -static asymbol * -osf_core_make_empty_symbol PARAMS ((bfd *)); -static const bfd_target * -osf_core_core_file_p PARAMS ((bfd *)); -static char * -osf_core_core_file_failing_command PARAMS ((bfd *)); -static int -osf_core_core_file_failing_signal PARAMS ((bfd *)); -static boolean -osf_core_core_file_matches_executable_p PARAMS ((bfd *, bfd *)); -static void -swap_abort PARAMS ((void)); - -/* These are stored in the bfd's tdata */ - -struct osf_core_struct -{ - int sig; - char cmd[MAXCOMLEN + 1]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.osf_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - file_ptr filepos; -{ - asection *asect; - - asect = bfd_make_section_anyway (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = filepos; - asect->alignment_power = 8; - - return asect; -} - -static asymbol * -osf_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -static const bfd_target * -osf_core_core_file_p (abfd) - bfd *abfd; -{ - int val; - int i; - char *secname; - struct core_filehdr core_header; - - val = bfd_read ((PTR)&core_header, 1, sizeof core_header, abfd); - if (val != sizeof core_header) - return NULL; - - if (strncmp (core_header.magic, "Core", 4) != 0) - return NULL; - - core_hdr (abfd) = (struct osf_core_struct *) - bfd_zalloc (abfd, sizeof (struct osf_core_struct)); - if (!core_hdr (abfd)) - return NULL; - - strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1); - core_signal (abfd) = core_header.signo; - - for (i = 0; i < core_header.nscns; i++) - { - struct core_scnhdr core_scnhdr; - flagword flags; - - val = bfd_read ((PTR)&core_scnhdr, 1, sizeof core_scnhdr, abfd); - if (val != sizeof core_scnhdr) - break; - - /* Skip empty sections. */ - if (core_scnhdr.size == 0 || core_scnhdr.scnptr == 0) - continue; - - switch (core_scnhdr.scntype) - { - case SCNRGN: - secname = ".data"; - flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - break; - case SCNSTACK: - secname = ".stack"; - flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - break; - case SCNREGS: - secname = ".reg"; - flags = SEC_HAS_CONTENTS; - break; - default: - (*_bfd_error_handler) ("Unhandled OSF/1 core file section type %d\n", - core_scnhdr.scntype); - continue; - } - - if (!make_bfd_asection (abfd, secname, flags, - (bfd_size_type) core_scnhdr.size, - (bfd_vma) core_scnhdr.vaddr, - (file_ptr) core_scnhdr.scnptr)) - return NULL; - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - return abfd->xvec; -} - -static char * -osf_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -static int -osf_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -static boolean -osf_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -#define osf_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define osf_core_get_symtab _bfd_nosymbols_get_symtab -#define osf_core_print_symbol _bfd_nosymbols_print_symbol -#define osf_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define osf_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define osf_core_get_lineno _bfd_nosymbols_get_lineno -#define osf_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define osf_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define osf_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define osf_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -static void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target osf_core_vec = - { - "osf-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - osf_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (osf_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (osf_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/pc532-mach.c b/contrib/gdb/bfd/pc532-mach.c deleted file mode 100644 index 73f4ac49e82..00000000000 --- a/contrib/gdb/bfd/pc532-mach.c +++ /dev/null @@ -1,121 +0,0 @@ -/* BFD back-end for Mach3/532 a.out-ish binaries. - Copyright (C) 1990, 1991, 1992, 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Ian Dall - * 19-Apr-94 - * - * Formerly part of aout-pc532-mach.c. Split out to allow more - * flexibility with multiple formats. - * - */ -/* This architecture has N_TXTOFF and N_TXTADDR defined as if - * N_HEADER_IN_TEXT, but the a_text entry (text size) does not include the - * space for the header. So we have N_HEADER_IN_TEXT defined to - * 1 and specially define our own N_TXTSIZE - */ - -#define N_HEADER_IN_TEXT(x) 1 -#define N_TXTSIZE(x) ((x).a_text) - - -#define TEXT_START_ADDR 0x10000 /* from old ld */ -#define TARGET_PAGE_SIZE 0x1000 /* from old ld, 032 & 532 are really 512/4k */ - -/* Use a_entry of 0 to distinguish object files from OMAGIC executables */ -#define N_TXTADDR(x) \ - (N_MAGIC(x) == OMAGIC ? \ - ((x).a_entry < TEXT_START_ADDR? 0: TEXT_START_ADDR): \ - (N_MAGIC(x) == NMAGIC? TEXT_START_ADDR: \ - TEXT_START_ADDR + EXEC_BYTES_SIZE)) - -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#define N_SHARED_LIB(x) 0 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_ns32k - -#define MY(OP) CAT(pc532machaout_,OP) - -/* Must be the same as aout-ns32k.c */ -#define NAME(x,y) CAT3(ns32kaout,_32_,y) - -#define TARGETNAME "a.out-pc532-mach" - -#include "bfd.h" -#include "sysdep.h" -#include "libaout.h" -#include "libbfd.h" -#include "aout/aout64.h" - -/* We can`t use the MYNS macro here for cpp reasons too subtle for me -- IWD */ - -#define MY_bfd_reloc_type_lookup ns32kaout_bfd_reloc_type_lookup - -/* libaout doesn't use NAME for these ... */ - -#define MY_get_section_contents aout_32_get_section_contents - -#define MY_text_includes_header 1 - -#define MY_exec_header_not_counted 1 - -#define MYNSX(OP) CAT(ns32kaout_,OP) -reloc_howto_type * -MYNSX(bfd_reloc_type_lookup) - PARAMS((bfd *abfd AND - bfd_reloc_code_real_type code)); - -boolean -MYNSX(write_object_contents) - PARAMS((bfd *abfd)); - -static boolean -MY(write_object_contents) (abfd) -bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE(abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_ns32k); - switch (bfd_get_mach (abfd)) - { - case 32032: - N_SET_MACHTYPE (*execp, M_NS32032); - break; - case 32532: - default: - N_SET_MACHTYPE (*execp, M_NS32532); - break; - } - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - WRITE_HEADERS(abfd, execp); - - return true; -} - -#define MY_write_object_contents MY(write_object_contents) - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/pe-arm.c b/contrib/gdb/bfd/pe-arm.c deleted file mode 100644 index fa97e2e8413..00000000000 --- a/contrib/gdb/bfd/pe-arm.c +++ /dev/null @@ -1,32 +0,0 @@ -/* BFD back-end for ARM PECOFF files. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_LITTLE_SYM armpe_little_vec -#define TARGET_LITTLE_NAME "pe-arm-little" -#define TARGET_BIG_SYM armpe_big_vec -#define TARGET_BIG_NAME "pe-arm-big" - -#define COFF_OBJ_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true - -#include "coff-arm.c" diff --git a/contrib/gdb/bfd/pe-i386.c b/contrib/gdb/bfd/pe-i386.c deleted file mode 100644 index 878993e510c..00000000000 --- a/contrib/gdb/bfd/pe-i386.c +++ /dev/null @@ -1,30 +0,0 @@ -/* BFD back-end for Intel 386 PECOFF files. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" - - -#define TARGET_SYM i386pe_vec -#define TARGET_NAME "pe-i386" -#define COFF_OBJ_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true -#define TARGET_UNDERSCORE '_' -#include "coff-i386.c" diff --git a/contrib/gdb/bfd/pe-ppc.c b/contrib/gdb/bfd/pe-ppc.c deleted file mode 100644 index 67fdda04e6c..00000000000 --- a/contrib/gdb/bfd/pe-ppc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* BFD back-end for Intel 386 PECOFF files. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" - - -#define E_FILENMLEN 18 - -#define PPC - -#define TARGET_LITTLE_SYM bfd_powerpcle_pe_vec -#define TARGET_LITTLE_NAME "pe-powerpcle" - -#define TARGET_BIG_SYM bfd_powerpc_pe_vec -#define TARGET_BIG_NAME "pe-powerpc" - -#define COFF_OBJ_WITH_PE -#define COFF_WITH_PE - -/* FIXME: verify PCRELOFFSET is always false */ - -#include "coff-ppc.c" diff --git a/contrib/gdb/bfd/pei-arm.c b/contrib/gdb/bfd/pei-arm.c deleted file mode 100644 index fd9d398432d..00000000000 --- a/contrib/gdb/bfd/pei-arm.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for arm PE IMAGE COFF files. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_LITTLE_SYM armpei_little_vec -#define TARGET_LITTLE_NAME "pei-arm-little" -#define TARGET_BIG_SYM armpei_big_vec -#define TARGET_BIG_NAME "pei-arm-big" - -#define IMAGE_BASE NT_IMAGE_BASE -#define COFF_IMAGE_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true - -#include "coff-arm.c" diff --git a/contrib/gdb/bfd/pei-i386.c b/contrib/gdb/bfd/pei-i386.c deleted file mode 100644 index 8754e7c55e3..00000000000 --- a/contrib/gdb/bfd/pei-i386.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for Intel 386 PE IMAGE COFF files. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_SYM i386pei_vec -#define TARGET_NAME "pei-i386" -#define IMAGE_BASE NT_IMAGE_BASE -#define COFF_IMAGE_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true -#define TARGET_UNDERSCORE '_' -#include "coff-i386.c" - - - diff --git a/contrib/gdb/bfd/pei-ppc.c b/contrib/gdb/bfd/pei-ppc.c deleted file mode 100644 index fc8f89fddb6..00000000000 --- a/contrib/gdb/bfd/pei-ppc.c +++ /dev/null @@ -1,44 +0,0 @@ -/* BFD back-end for Intel 386 PE IMAGE COFF files. - Copyright 1995 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" - -/* setting up for a PE environment stolen directly from the i386 structure */ -#define E_FILNMLEN 18 /* # characters in a file name */ - -#define PPC - -#define TARGET_LITTLE_SYM bfd_powerpcle_pei_vec -#define TARGET_LITTLE_NAME "pei-powerpcle" - -#define TARGET_BIG_SYM bfd_powerpc_pei_vec -#define TARGET_BIG_NAME "pei-powerpc" - -#define IMAGE_BASE NT_IMAGE_BASE - -#define COFF_IMAGE_WITH_PE -#define COFF_WITH_PE - -/* FIXME: Verify PCRELOFFSET is always false */ - -#include "coff-ppc.c" - - - diff --git a/contrib/gdb/bfd/peicode.h b/contrib/gdb/bfd/peicode.h deleted file mode 100644 index a7a47469e3d..00000000000 --- a/contrib/gdb/bfd/peicode.h +++ /dev/null @@ -1,1861 +0,0 @@ -/* Support for the generic parts of most COFF variants, for BFD. - Copyright 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -Most of this hacked by Steve Chamberlain, - sac@cygnus.com -*/ - - - -#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data -#define coff_mkobject pe_mkobject -#define coff_mkobject_hook pe_mkobject_hook - -#ifndef GET_FCN_LNNOPTR -#define GET_FCN_LNNOPTR(abfd, ext) \ - bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif - -#ifndef GET_FCN_ENDNDX -#define GET_FCN_ENDNDX(abfd, ext) \ - bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif - -#ifndef PUT_FCN_LNNOPTR -#define PUT_FCN_LNNOPTR(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif -#ifndef PUT_FCN_ENDNDX -#define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif -#ifndef GET_LNSZ_LNNO -#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef GET_LNSZ_SIZE -#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef PUT_LNSZ_LNNO -#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef PUT_LNSZ_SIZE -#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef GET_SCN_SCNLEN -#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef GET_SCN_NRELOC -#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef GET_SCN_NLINNO -#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno) -#endif -#ifndef PUT_SCN_SCNLEN -#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef PUT_SCN_NRELOC -#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef PUT_SCN_NLINNO -#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno) -#endif -#ifndef GET_LINENO_LNNO -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno)); -#endif -#ifndef PUT_LINENO_LNNO -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno)); -#endif - -/* The f_symptr field in the filehdr is sometimes 64 bits. */ -#ifndef GET_FILEHDR_SYMPTR -#define GET_FILEHDR_SYMPTR bfd_h_get_32 -#endif -#ifndef PUT_FILEHDR_SYMPTR -#define PUT_FILEHDR_SYMPTR bfd_h_put_32 -#endif - -/* Some fields in the aouthdr are sometimes 64 bits. */ -#ifndef GET_AOUTHDR_TSIZE -#define GET_AOUTHDR_TSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TSIZE -#define PUT_AOUTHDR_TSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DSIZE -#define GET_AOUTHDR_DSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DSIZE -#define PUT_AOUTHDR_DSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_BSIZE -#define GET_AOUTHDR_BSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_BSIZE -#define PUT_AOUTHDR_BSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_ENTRY -#define GET_AOUTHDR_ENTRY bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_ENTRY -#define PUT_AOUTHDR_ENTRY bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_TEXT_START -#define GET_AOUTHDR_TEXT_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TEXT_START -#define PUT_AOUTHDR_TEXT_START bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DATA_START -#define GET_AOUTHDR_DATA_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DATA_START -#define PUT_AOUTHDR_DATA_START bfd_h_put_32 -#endif - -/* Some fields in the scnhdr are sometimes 64 bits. */ -#ifndef GET_SCNHDR_PADDR -#define GET_SCNHDR_PADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_PADDR -#define PUT_SCNHDR_PADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_VADDR -#define GET_SCNHDR_VADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_VADDR -#define PUT_SCNHDR_VADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SIZE -#define GET_SCNHDR_SIZE bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SIZE -#define PUT_SCNHDR_SIZE bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SCNPTR -#define GET_SCNHDR_SCNPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SCNPTR -#define PUT_SCNHDR_SCNPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_RELPTR -#define GET_SCNHDR_RELPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_RELPTR -#define PUT_SCNHDR_RELPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_LNNOPTR -#define GET_SCNHDR_LNNOPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_LNNOPTR -#define PUT_SCNHDR_LNNOPTR bfd_h_put_32 -#endif - - - -/**********************************************************************/ - -static void -coff_swap_reloc_in (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - RELOC *reloc_src = (RELOC *) src; - struct internal_reloc *reloc_dst = (struct internal_reloc *) dst; - - reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr); - reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx); - - reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type); - -#ifdef SWAP_IN_RELOC_OFFSET - reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd, - (bfd_byte *) reloc_src->r_offset); -#endif -} - - -static unsigned int -coff_swap_reloc_out (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - struct internal_reloc *reloc_src = (struct internal_reloc *)src; - struct external_reloc *reloc_dst = (struct external_reloc *)dst; - bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr); - bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx); - - bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *) - reloc_dst->r_type); - -#ifdef SWAP_OUT_RELOC_OFFSET - SWAP_OUT_RELOC_OFFSET(abfd, - reloc_src->r_offset, - (bfd_byte *) reloc_dst->r_offset); -#endif -#ifdef SWAP_OUT_RELOC_EXTRA - SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst); -#endif - return sizeof(struct external_reloc); -} - - -static void -coff_swap_filehdr_in (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - FILHDR *filehdr_src = (FILHDR *) src; - struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; - filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic); - filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns); - filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat); - - filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms); - filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags); - filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr); - - /* Other people's tools sometimes generate headers - with an nsyms but a zero symptr. */ - if (filehdr_dst->f_nsyms && filehdr_dst->f_symptr) - { - filehdr_dst->f_flags |= HAS_SYMS; - } - else - { - filehdr_dst->f_symptr = 0; - filehdr_dst->f_nsyms = 0; - filehdr_dst->f_flags &= ~HAS_SYMS; - } - - filehdr_dst->f_opthdr = bfd_h_get_16(abfd, - (bfd_byte *)filehdr_src-> f_opthdr); -} - -#ifdef COFF_IMAGE_WITH_PE - -static unsigned int -coff_swap_filehdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - int idx; - struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in; - FILHDR *filehdr_out = (FILHDR *)out; - - if (pe_data (abfd)->has_reloc_section) - filehdr_in->f_flags &= ~F_RELFLG; - - if (pe_data (abfd)->dll) - filehdr_in->f_flags |= F_DLL; - - filehdr_in->pe.e_magic = DOSMAGIC; - filehdr_in->pe.e_cblp = 0x90; - filehdr_in->pe.e_cp = 0x3; - filehdr_in->pe.e_crlc = 0x0; - filehdr_in->pe.e_cparhdr = 0x4; - filehdr_in->pe.e_minalloc = 0x0; - filehdr_in->pe.e_maxalloc = 0xffff; - filehdr_in->pe.e_ss = 0x0; - filehdr_in->pe.e_sp = 0xb8; - filehdr_in->pe.e_csum = 0x0; - filehdr_in->pe.e_ip = 0x0; - filehdr_in->pe.e_cs = 0x0; - filehdr_in->pe.e_lfarlc = 0x40; - filehdr_in->pe.e_ovno = 0x0; - - for (idx=0; idx < 4; idx++) - filehdr_in->pe.e_res[idx] = 0x0; - - filehdr_in->pe.e_oemid = 0x0; - filehdr_in->pe.e_oeminfo = 0x0; - - for (idx=0; idx < 10; idx++) - filehdr_in->pe.e_res2[idx] = 0x0; - - filehdr_in->pe.e_lfanew = 0x80; - - /* this next collection of data are mostly just characters. It appears - to be constant within the headers put on NT exes */ - filehdr_in->pe.dos_message[0] = 0x0eba1f0e; - filehdr_in->pe.dos_message[1] = 0xcd09b400; - filehdr_in->pe.dos_message[2] = 0x4c01b821; - filehdr_in->pe.dos_message[3] = 0x685421cd; - filehdr_in->pe.dos_message[4] = 0x70207369; - filehdr_in->pe.dos_message[5] = 0x72676f72; - filehdr_in->pe.dos_message[6] = 0x63206d61; - filehdr_in->pe.dos_message[7] = 0x6f6e6e61; - filehdr_in->pe.dos_message[8] = 0x65622074; - filehdr_in->pe.dos_message[9] = 0x6e757220; - filehdr_in->pe.dos_message[10] = 0x206e6920; - filehdr_in->pe.dos_message[11] = 0x20534f44; - filehdr_in->pe.dos_message[12] = 0x65646f6d; - filehdr_in->pe.dos_message[13] = 0x0a0d0d2e; - filehdr_in->pe.dos_message[14] = 0x24; - filehdr_in->pe.dos_message[15] = 0x0; - filehdr_in->pe.nt_signature = NT_SIGNATURE; - - - - bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic); - bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns); - - bfd_h_put_32(abfd, time (0), (bfd_byte *) filehdr_out->f_timdat); - PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr, - (bfd_byte *) filehdr_out->f_symptr); - bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms); - bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr); - bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags); - - /* put in extra dos header stuff. This data remains essentially - constant, it just has to be tacked on to the beginning of all exes - for NT */ - bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic); - bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp); - bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp); - bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc); - bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr, - (bfd_byte *) filehdr_out->e_cparhdr); - bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc, - (bfd_byte *) filehdr_out->e_minalloc); - bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc, - (bfd_byte *) filehdr_out->e_maxalloc); - bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss); - bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp); - bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum); - bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip); - bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs); - bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc); - bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno); - { - int idx; - for (idx=0; idx < 4; idx++) - bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx], - (bfd_byte *) filehdr_out->e_res[idx]); - } - bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid); - bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo, - (bfd_byte *) filehdr_out->e_oeminfo); - { - int idx; - for (idx=0; idx < 10; idx++) - bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx], - (bfd_byte *) filehdr_out->e_res2[idx]); - } - bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew); - - { - int idx; - for (idx=0; idx < 16; idx++) - bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx], - (bfd_byte *) filehdr_out->dos_message[idx]); - } - - /* also put in the NT signature */ - bfd_h_put_32(abfd, filehdr_in->pe.nt_signature, - (bfd_byte *) filehdr_out->nt_signature); - - - - - return sizeof(FILHDR); -} -#else - -static unsigned int -coff_swap_filehdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in; - FILHDR *filehdr_out = (FILHDR *)out; - - bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic); - bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns); - bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat); - PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr, - (bfd_byte *) filehdr_out->f_symptr); - bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms); - bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr); - bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags); - - return sizeof(FILHDR); -} - -#endif - - -static void -coff_swap_sym_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - SYMENT *ext = (SYMENT *)ext1; - struct internal_syment *in = (struct internal_syment *)in1; - - if( ext->e.e_name[0] == 0) { - in->_n._n_n._n_zeroes = 0; - in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN); -#endif - } - - in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); - in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2){ - in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type); - } - else { - in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type); - } - in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass); - in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux); - - /* The section symbols for the .idata$ sections have class 68, which MS - documentation indicates is a section symbol. The problem is that the - value field in the symbol is simply a copy of the .idata section's flags - rather than something useful. When these symbols are encountered, change - the value to 0 and the section number to 1 so that they will be handled - somewhat correctly in the bfd code. */ - if (in->n_sclass == 0x68) { - in->n_value = 0x0; - in->n_scnum = 1; - /* I have tried setting the class to 3 and using the following to set - the section number. This will put the address of the pointer to the - string kernel32.dll at addresses 0 and 0x10 off start of idata section - which is not correct */ - /* if (strcmp (in->_n._n_name, ".idata$4") == 0) */ - /* in->n_scnum = 3; */ - /* else */ - /* in->n_scnum = 2; */ - } - -#ifdef coff_swap_sym_in_hook - coff_swap_sym_in_hook(abfd, ext1, in1); -#endif -} - -static unsigned int -coff_swap_sym_out (abfd, inp, extp) - bfd *abfd; - PTR inp; - PTR extp; -{ - struct internal_syment *in = (struct internal_syment *)inp; - SYMENT *ext =(SYMENT *)extp; - if(in->_n._n_name[0] == 0) { - bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes); - bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN); -#endif - } - - bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value); - bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2) - { - bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - else - { - bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass); - bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux); - - return sizeof(SYMENT); -} - -static void -coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) - bfd *abfd; - PTR ext1; - int type; - int class; - int indx; - int numaux; - PTR in1; -{ - AUXENT *ext = (AUXENT *)ext1; - union internal_auxent *in = (union internal_auxent *)in1; - - switch (class) { - case C_FILE: - if (ext->x_file.x_fname[0] == 0) { - in->x_file.x_n.x_zeroes = 0; - in->x_file.x_n.x_offset = - bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset); - } else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); -#endif - } - return; - - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext); - in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext); - in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext); - return; - } - break; - } - - in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) - { - in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext); - in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext); - } - else - { -#if DIMNUM != E_DIMNUM - #error we need to cope with truncating or extending DIMNUM -#endif - in->x_sym.x_fcnary.x_ary.x_dimen[0] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - in->x_sym.x_fcnary.x_ary.x_dimen[1] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - in->x_sym.x_fcnary.x_ary.x_dimen[2] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - in->x_sym.x_fcnary.x_ary.x_dimen[3] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } - - if (ISFCN(type)) { - in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize); - } - else { - in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext); - in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext); - } -} - -static unsigned int -coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) - bfd *abfd; - PTR inp; - int type; - int class; - int indx; - int numaux; - PTR extp; -{ - union internal_auxent *in = (union internal_auxent *)inp; - AUXENT *ext = (AUXENT *)extp; - - memset((PTR)ext, 0, AUXESZ); - switch (class) { - case C_FILE: - if (in->x_file.x_fname[0] == 0) { - bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes); - bfd_h_put_32(abfd, - in->x_file.x_n.x_offset, - (bfd_byte *) ext->x_file.x_n.x_offset); - } - else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); -#endif - } - return sizeof (AUXENT); - - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext); - PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext); - PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext); - return sizeof (AUXENT); - } - break; - } - - bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) - { - PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); - PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); - } - else - { -#if DIMNUM != E_DIMNUM - #error we need to cope with truncating or extending DIMNUM -#endif - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } - - if (ISFCN (type)) - bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize, - (bfd_byte *) ext->x_sym.x_misc.x_fsize); - else - { - PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext); - PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext); - } - - return sizeof(AUXENT); -} - - -static void -coff_swap_lineno_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - LINENO *ext = (LINENO *)ext1; - struct internal_lineno *in = (struct internal_lineno *)in1; - - in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx); - in->l_lnno = GET_LINENO_LNNO(abfd, ext); -} - -static unsigned int -coff_swap_lineno_out (abfd, inp, outp) - bfd *abfd; - PTR inp; - PTR outp; -{ - struct internal_lineno *in = (struct internal_lineno *)inp; - struct external_lineno *ext = (struct external_lineno *)outp; - bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *) - ext->l_addr.l_symndx); - - PUT_LINENO_LNNO (abfd, in->l_lnno, ext); - return sizeof(struct external_lineno); -} - - - -static void -coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) - bfd *abfd; - PTR aouthdr_ext1; - PTR aouthdr_int1; -{ - struct internal_extra_pe_aouthdr *a; - PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1); - AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1; - struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1; - - aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic); - aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp); - aouthdr_int->tsize = - GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize); - aouthdr_int->dsize = - GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize); - aouthdr_int->bsize = - GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize); - aouthdr_int->entry = - GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry); - aouthdr_int->text_start = - GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start); - aouthdr_int->data_start = - GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start); - - a = &aouthdr_int->pe; - a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase); - a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment); - a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment); - a->MajorOperatingSystemVersion = - bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion); - a->MinorOperatingSystemVersion = - bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion); - a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion); - a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion); - a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion); - a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion); - a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1); - a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage); - a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders); - a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum); - a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem); - a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics); - a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve); - a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit); - a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve); - a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit); - a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags); - a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes); - - { - int idx; - for (idx=0; idx < 16; idx++) - { - a->DataDirectory[idx].VirtualAddress = - bfd_h_get_32 (abfd, src->DataDirectory[idx][0]); - a->DataDirectory[idx].Size = - bfd_h_get_32 (abfd, src->DataDirectory[idx][1]); - } - } - - if (aouthdr_int->entry) - aouthdr_int->entry += a->ImageBase; - if (aouthdr_int->tsize) - aouthdr_int->text_start += a->ImageBase; - if (aouthdr_int->dsize) - aouthdr_int->data_start += a->ImageBase; -} - - -static void add_data_entry (abfd, aout, idx, name, base) - bfd *abfd; - struct internal_extra_pe_aouthdr *aout; - int idx; - char *name; - bfd_vma base; -{ - asection *sec = bfd_get_section_by_name (abfd, name); - - /* add import directory information if it exists */ - if (sec != NULL) - { - aout->DataDirectory[idx].VirtualAddress = sec->vma - base; - aout->DataDirectory[idx].Size = sec->_cooked_size; - sec->flags |= SEC_DATA; - } -} - -static unsigned int -coff_swap_aouthdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in; - struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr; - PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out; - - bfd_vma sa = extra->SectionAlignment; - bfd_vma fa = extra->FileAlignment; - bfd_vma ib = extra->ImageBase ; - - if (aouthdr_in->tsize) - aouthdr_in->text_start -= ib; - if (aouthdr_in->dsize) - aouthdr_in->data_start -= ib; - if (aouthdr_in->entry) - aouthdr_in->entry -= ib; - -#define FA(x) (((x) + fa -1 ) & (- fa)) -#define SA(x) (((x) + sa -1 ) & (- sa)) - - /* We like to have the sizes aligned */ - - aouthdr_in->bsize = FA (aouthdr_in->bsize); - - - extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; - - /* first null out all data directory entries .. */ - memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0); - - add_data_entry (abfd, extra, 0, ".edata", ib); - add_data_entry (abfd, extra, 1, ".idata", ib); - add_data_entry (abfd, extra, 2, ".rsrc" ,ib); - -#ifdef POWERPC_LE_PE - /* FIXME: do other PE platforms use this? */ - add_data_entry (abfd, extra, 3, ".pdata" ,ib); -#endif - - add_data_entry (abfd, extra, 5, ".reloc", ib); - -#ifdef POWERPC_LE_PE - /* On the PPC NT system, this field is set up as follows. It is - not an "officially" reserved field, so it currently has no title. - first_thunk_address is idata$5, and the thunk_size is the size - of the idata$5 chunk of the idata section. - */ - extra->DataDirectory[12].VirtualAddress = first_thunk_address; - extra->DataDirectory[12].Size = thunk_size; - - /* On the PPC NT system, the size of the directory entry is not the - size of the entire section. It's actually offset to the end of - the idata$3 component of the idata section. This is the size of - the entire import table. (also known as the start of idata$4) - */ - extra->DataDirectory[1].Size = import_table_size; -#endif - - { - asection *sec; - bfd_vma dsize= 0; - bfd_vma isize = SA(abfd->sections->filepos); - bfd_vma tsize= 0; - - for (sec = abfd->sections; sec; sec = sec->next) - { - int rounded = FA(sec->_raw_size); - - if (strcmp(sec->name,".junk") == 0) - { - continue; - } - - if (sec->flags & SEC_DATA) - dsize += rounded; - if (sec->flags & SEC_CODE) - tsize += rounded; - isize += SA(rounded); - } - - aouthdr_in->dsize = dsize; - aouthdr_in->tsize = tsize; - extra->SizeOfImage = isize; - } - - extra->SizeOfHeaders = abfd->sections->filepos; - bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic); - -#ifdef POWERPC_LE_PE - /* this little piece of magic sets the "linker version" field to 2.60 */ - bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp); -#else - /* this little piece of magic sets the "linker version" field to 2.55 */ - bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp); -#endif - - PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize); - PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize); - PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize); - PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry); - PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start, - (bfd_byte *) aouthdr_out->standard.text_start); - - PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, - (bfd_byte *) aouthdr_out->standard.data_start); - - - bfd_h_put_32 (abfd, extra->ImageBase, - (bfd_byte *) aouthdr_out->ImageBase); - bfd_h_put_32 (abfd, extra->SectionAlignment, - (bfd_byte *) aouthdr_out->SectionAlignment); - bfd_h_put_32 (abfd, extra->FileAlignment, - (bfd_byte *) aouthdr_out->FileAlignment); - bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion, - (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion); - bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion, - (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion); - bfd_h_put_16 (abfd, extra->MajorImageVersion, - (bfd_byte *) aouthdr_out->MajorImageVersion); - bfd_h_put_16 (abfd, extra->MinorImageVersion, - (bfd_byte *) aouthdr_out->MinorImageVersion); - bfd_h_put_16 (abfd, extra->MajorSubsystemVersion, - (bfd_byte *) aouthdr_out->MajorSubsystemVersion); - bfd_h_put_16 (abfd, extra->MinorSubsystemVersion, - (bfd_byte *) aouthdr_out->MinorSubsystemVersion); - bfd_h_put_32 (abfd, extra->Reserved1, - (bfd_byte *) aouthdr_out->Reserved1); - bfd_h_put_32 (abfd, extra->SizeOfImage, - (bfd_byte *) aouthdr_out->SizeOfImage); - bfd_h_put_32 (abfd, extra->SizeOfHeaders, - (bfd_byte *) aouthdr_out->SizeOfHeaders); - bfd_h_put_32 (abfd, extra->CheckSum, - (bfd_byte *) aouthdr_out->CheckSum); - bfd_h_put_16 (abfd, extra->Subsystem, - (bfd_byte *) aouthdr_out->Subsystem); - bfd_h_put_16 (abfd, extra->DllCharacteristics, - (bfd_byte *) aouthdr_out->DllCharacteristics); - bfd_h_put_32 (abfd, extra->SizeOfStackReserve, - (bfd_byte *) aouthdr_out->SizeOfStackReserve); - bfd_h_put_32 (abfd, extra->SizeOfStackCommit, - (bfd_byte *) aouthdr_out->SizeOfStackCommit); - bfd_h_put_32 (abfd, extra->SizeOfHeapReserve, - (bfd_byte *) aouthdr_out->SizeOfHeapReserve); - bfd_h_put_32 (abfd, extra->SizeOfHeapCommit, - (bfd_byte *) aouthdr_out->SizeOfHeapCommit); - bfd_h_put_32 (abfd, extra->LoaderFlags, - (bfd_byte *) aouthdr_out->LoaderFlags); - bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes, - (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes); - { - int idx; - for (idx=0; idx < 16; idx++) - { - bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress, - (bfd_byte *) aouthdr_out->DataDirectory[idx][0]); - bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size, - (bfd_byte *) aouthdr_out->DataDirectory[idx][1]); - } - } - - return sizeof(AOUTHDR); -} - -static void - coff_swap_scnhdr_in (abfd, ext, in) - bfd *abfd; - PTR ext; - PTR in; -{ - SCNHDR *scnhdr_ext = (SCNHDR *) ext; - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; - - memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name)); - scnhdr_int->s_vaddr = - GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr); - scnhdr_int->s_paddr = - GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr); - scnhdr_int->s_size = - GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size); - scnhdr_int->s_scnptr = - GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr); - scnhdr_int->s_relptr = - GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr); - scnhdr_int->s_lnnoptr = - GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr); - scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags); - - scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc); - scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno); - - if (scnhdr_int->s_vaddr != 0) - { - scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase; - } - if (strcmp (scnhdr_int->s_name, _BSS) == 0) - { - scnhdr_int->s_size = scnhdr_int->s_paddr; - scnhdr_int->s_paddr = 0; - } -} - -static unsigned int -coff_swap_scnhdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in; - SCNHDR *scnhdr_ext = (SCNHDR *)out; - unsigned int ret = sizeof (SCNHDR); - bfd_vma ps; - bfd_vma ss; - - memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name)); - - PUT_SCNHDR_VADDR (abfd, - (scnhdr_int->s_vaddr - - pe_data(abfd)->pe_opthdr.ImageBase), - (bfd_byte *) scnhdr_ext->s_vaddr); - - /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT - value except for the BSS section, its s_size should be 0 */ - - - if (strcmp (scnhdr_int->s_name, _BSS) == 0) - { - ps = scnhdr_int->s_size; - ss = 0; - } - else - { - ps = scnhdr_int->s_paddr; - ss = scnhdr_int->s_size; - } - - PUT_SCNHDR_SIZE (abfd, ss, - (bfd_byte *) scnhdr_ext->s_size); - - - PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr); - - PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, - (bfd_byte *) scnhdr_ext->s_scnptr); - PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, - (bfd_byte *) scnhdr_ext->s_relptr); - PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, - (bfd_byte *) scnhdr_ext->s_lnnoptr); - - /* Extra flags must be set when dealing with NT. All sections should also - have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the - .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data - sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set - (this is especially important when dealing with the .idata section since - the addresses for routines from .dlls must be overwritten). If .reloc - section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE - (0x02000000). Also, the resource data should also be read and - writable. */ - - /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */ - /* FIXME: even worse, I don't see how to get the original alignment field*/ - /* back... */ - - { - int flags = scnhdr_int->s_flags; - if (strcmp (scnhdr_int->s_name, ".data") == 0 || - strcmp (scnhdr_int->s_name, ".CRT") == 0 || - strcmp (scnhdr_int->s_name, ".rsrc") == 0 || - strcmp (scnhdr_int->s_name, ".bss") == 0) - flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; - else if (strcmp (scnhdr_int->s_name, ".text") == 0) - flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE; - else if (strcmp (scnhdr_int->s_name, ".reloc") == 0) - flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE; - else if (strcmp (scnhdr_int->s_name, ".idata") == 0) - flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA; - else if (strcmp (scnhdr_int->s_name, ".rdata") == 0 - || strcmp (scnhdr_int->s_name, ".edata") == 0) - flags = IMAGE_SCN_MEM_READ | SEC_DATA; - /* ppc-nt additions */ - else if (strcmp (scnhdr_int->s_name, ".pdata") == 0) - flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | - IMAGE_SCN_MEM_READ ; - /* Remember this field is a max of 8 chars, so the null is _not_ there - for an 8 character name like ".reldata". (yep. Stupid bug) */ - else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0) - flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES | - IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ; - else if (strcmp (scnhdr_int->s_name, ".ydata") == 0) - flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES | - IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ; - else if (strcmp (scnhdr_int->s_name, ".drectve") == 0) - flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ; - /* end of ppc-nt additions */ -#ifdef POWERPC_LE_PE - else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0) - { - flags = IMAGE_SCN_LNK_INFO; - } - else if (strcmp (scnhdr_int->s_name, ".stab") == 0) - { - flags = IMAGE_SCN_LNK_INFO; - } -#endif - - bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags); - } - - if (scnhdr_int->s_nlnno <= 0xffff) - bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); - else - { - (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff", - bfd_get_filename (abfd), - scnhdr_int->s_nlnno); - bfd_set_error (bfd_error_file_truncated); - bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno); - ret = 0; - } - if (scnhdr_int->s_nreloc <= 0xffff) - bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); - else - { - (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff", - bfd_get_filename (abfd), - scnhdr_int->s_nreloc); - bfd_set_error (bfd_error_file_truncated); - bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc); - ret = 0; - } - return ret; -} - -static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = -{ - "Export Directory [.edata]", - "Import Directory [parts of .idata]", - "Resource Directory [.rsrc]", - "Exception Directory [.pdata]", - "Security Directory", - "Base Relocation Directory [.reloc]", - "Debug Directory", - "Description Directory", - "Special Directory", - "Thread Storage Directory [.tls]", - "Load Configuration Directory", - "Bound Import Directory", - "Import Address Table Directory", - "Reserved", - "Reserved", - "Reserved" -}; - -/**********************************************************************/ -static boolean -pe_print_idata(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".idata"); - -#ifdef POWERPC_LE_PE - asection *rel_section = bfd_get_section_by_name (abfd, ".reldata"); -#endif - - bfd_size_type datasize = 0; - bfd_size_type i; - bfd_size_type start, stop; - int onaline = 20; - bfd_vma addr_value; - bfd_vma loadable_toc_address; - bfd_vma toc_address; - bfd_vma start_address; - - pe_data_type *pe = pe_data (abfd); - struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; - - if (section == 0) - return true; - -#ifdef POWERPC_LE_PE - if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0) - { - /* The toc address can be found by taking the starting address, - which on the PPC locates a function descriptor. The descriptor - consists of the function code starting address followed by the - address of the toc. The starting address we get from the bfd, - and the descriptor is supposed to be in the .reldata section. - */ - - bfd_byte *data = 0; - int offset; - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, - rel_section)); - if (data == NULL && bfd_section_size (abfd, rel_section) != 0) - return false; - - datasize = bfd_section_size (abfd, rel_section); - - bfd_get_section_contents (abfd, - rel_section, - (PTR) data, 0, - bfd_section_size (abfd, rel_section)); - - offset = abfd->start_address - rel_section->vma; - - start_address = bfd_get_32(abfd, data+offset); - loadable_toc_address = bfd_get_32(abfd, data+offset+4); - toc_address = loadable_toc_address - 32768; - - fprintf(file, - "\nFunction descriptor located at the start address: %04lx\n", - (unsigned long int) (abfd->start_address)); - fprintf (file, - "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n", - start_address, loadable_toc_address, toc_address); - } - else - { - loadable_toc_address = 0; - toc_address = 0; - start_address = 0; - } -#endif - - fprintf(file, - "\nThe Import Tables (interpreted .idata section contents)\n"); - fprintf(file, - " vma: Hint Time Forward DLL First\n"); - fprintf(file, - " Table Stamp Chain Name Thunk\n"); - - if (bfd_section_size (abfd, section) == 0) - return true; - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); - datasize = bfd_section_size (abfd, section); - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - start = 0; - - stop = bfd_section_size (abfd, section); - - for (i = start; i < stop; i += onaline) - { - bfd_vma hint_addr; - bfd_vma time_stamp; - bfd_vma forward_chain; - bfd_vma dll_name; - bfd_vma first_thunk; - int idx; - int j; - char *dll; - int adj = extra->ImageBase - section->vma; - - fprintf (file, - " %04lx\t", - (unsigned long int) (i + section->vma)); - - if (i+20 > stop) - { - /* check stuff */ - ; - } - - hint_addr = bfd_get_32(abfd, data+i); - time_stamp = bfd_get_32(abfd, data+i+4); - forward_chain = bfd_get_32(abfd, data+i+8); - dll_name = bfd_get_32(abfd, data+i+12); - first_thunk = bfd_get_32(abfd, data+i+16); - - fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n", - hint_addr, - time_stamp, - forward_chain, - dll_name, - first_thunk); - - if (hint_addr ==0) - { - break; - } - - /* the image base is present in the section->vma */ - dll = data + dll_name + adj; - fprintf(file, "\n\tDLL Name: %s\n", dll); - fprintf(file, "\tvma: Ordinal Member-Name\n"); - - idx = hint_addr + adj; - - for (j=0;j>> Ran out of IAT members!\n"); - } - else - { - ordinal = bfd_get_16(abfd, - data + iat_member + adj); - member_name = data + iat_member + adj + 2; - fprintf(file, "\t%04lx\t %4d %s\n", - iat_member, ordinal, member_name); - } - break; - } - if (hint_member == 0) - break; - } - if (differ == 0) - { - fprintf(file, - "\tThe Import Address Table is identical\n"); - } - } - - fprintf(file, "\n"); - - } - - free (data); -} - -static boolean -pe_print_edata(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".edata"); - - bfd_size_type datasize = 0; - bfd_size_type i; - - int adj; - struct EDT_type - { - long export_flags; /* reserved - should be zero */ - long time_stamp; - short major_ver; - short minor_ver; - bfd_vma name; /* rva - relative to image base */ - long base; /* ordinal base */ - long num_functions; /* Number in the export address table */ - long num_names; /* Number in the name pointer table */ - bfd_vma eat_addr; /* rva to the export address table */ - bfd_vma npt_addr; /* rva to the Export Name Pointer Table */ - bfd_vma ot_addr; /* rva to the Ordinal Table */ - } edt; - - pe_data_type *pe = pe_data (abfd); - struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; - - if (section == 0) - return true; - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, - section)); - datasize = bfd_section_size (abfd, section); - - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - /* Go get Export Directory Table */ - edt.export_flags = bfd_get_32(abfd, data+0); - edt.time_stamp = bfd_get_32(abfd, data+4); - edt.major_ver = bfd_get_16(abfd, data+8); - edt.minor_ver = bfd_get_16(abfd, data+10); - edt.name = bfd_get_32(abfd, data+12); - edt.base = bfd_get_32(abfd, data+16); - edt.num_functions = bfd_get_32(abfd, data+20); - edt.num_names = bfd_get_32(abfd, data+24); - edt.eat_addr = bfd_get_32(abfd, data+28); - edt.npt_addr = bfd_get_32(abfd, data+32); - edt.ot_addr = bfd_get_32(abfd, data+36); - - adj = extra->ImageBase - section->vma; - - - /* Dump the EDT first first */ - fprintf(file, - "\nThe Export Tables (interpreted .edata section contents)\n\n"); - - fprintf(file, - "Export Flags \t\t\t%x\n",edt.export_flags); - - fprintf(file, - "Time/Date stamp \t\t%x\n",edt.time_stamp); - - fprintf(file, - "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver); - - fprintf(file, - "Name \t\t\t\t%x %s\n", edt.name, data + edt.name + adj); - - fprintf(file, - "Ordinal Base \t\t\t%d\n", edt.base); - - fprintf(file, - "Number in:\n"); - - fprintf(file, - "\tExport Address Table \t\t%x\n", edt.num_functions); - - fprintf(file, - "\t[Name Pointer/Ordinal] Table\t%d\n", edt.num_names); - - fprintf(file, - "Table Addresses\n"); - - fprintf(file, - "\tExport Address Table \t\t%x\n", - edt.eat_addr); - - fprintf(file, - "\tName Pointer Table \t\t%x\n", - edt.npt_addr); - - fprintf(file, - "\tOrdinal Table \t\t\t%x\n", - edt.ot_addr); - - - /* The next table to find si the Export Address Table. It's basically - a list of pointers that either locate a function in this dll, or - forward the call to another dll. Something like: - typedef union - { - long export_rva; - long forwarder_rva; - } export_address_table_entry; - */ - - fprintf(file, - "\nExport Address Table -- Ordinal Base %d\n", - edt.base); - - for (i = 0; i < edt.num_functions; ++i) - { - bfd_vma eat_member = bfd_get_32(abfd, - data + edt.eat_addr + (i*4) + adj); - bfd_vma eat_actual = extra->ImageBase + eat_member; - bfd_vma edata_start = bfd_get_section_vma(abfd,section); - bfd_vma edata_end = edata_start + bfd_section_size (abfd, section); - - - if (eat_member == 0) - continue; - - if (edata_start < eat_actual && eat_actual < edata_end) - { - /* this rva is to a name (forwarding function) in our section */ - /* Should locate a function descriptor */ - fprintf(file, - "\t[%4d] +base[%4d] %04lx %s -- %s\n", - i, i+edt.base, eat_member, "Forwarder RVA", - data + eat_member + adj); - } - else - { - /* Should locate a function descriptor in the reldata section */ - fprintf(file, - "\t[%4d] +base[%4d] %04lx %s\n", - i, i+edt.base, eat_member, "Export RVA"); - } - } - - /* The Export Name Pointer Table is paired with the Export Ordinal Table */ - /* Dump them in parallel for clarity */ - fprintf(file, - "\n[Ordinal/Name Pointer] Table\n"); - - for (i = 0; i < edt.num_names; ++i) - { - bfd_vma name_ptr = bfd_get_32(abfd, - data + - edt.npt_addr - + (i*4) + adj); - - char *name = data + name_ptr + adj; - - bfd_vma ord = bfd_get_16(abfd, - data + - edt.ot_addr - + (i*2) + adj); - fprintf(file, - "\t[%4d] %s\n", ord, name); - - } - - free (data); -} - -static boolean -pe_print_pdata(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".pdata"); - bfd_size_type datasize = 0; - bfd_size_type i; - bfd_size_type start, stop; - int onaline = 20; - bfd_vma addr_value; - - if (section == 0) - return true; - - fprintf(file, - "\nThe Function Table (interpreted .pdata section contents)\n"); - fprintf(file, - " vma:\t\tBegin End EH EH PrologEnd\n"); - fprintf(file, - " \t\tAddress Address Handler Data Address\n"); - - if (bfd_section_size (abfd, section) == 0) - return true; - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); - datasize = bfd_section_size (abfd, section); - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - start = 0; - - stop = bfd_section_size (abfd, section); - - for (i = start; i < stop; i += onaline) - { - bfd_vma begin_addr; - bfd_vma end_addr; - bfd_vma eh_handler; - bfd_vma eh_data; - bfd_vma prolog_end_addr; - - if (i+20 > stop) - break; - - begin_addr = bfd_get_32(abfd, data+i); - end_addr = bfd_get_32(abfd, data+i+4); - eh_handler = bfd_get_32(abfd, data+i+8); - eh_data = bfd_get_32(abfd, data+i+12); - prolog_end_addr = bfd_get_32(abfd, data+i+16); - - if (begin_addr == 0 && end_addr == 0 && eh_handler == 0 - && eh_data == 0 && prolog_end_addr == 0) - { - /* We are probably into the padding of the - section now */ - break; - } - - fprintf (file, - " %08lx\t", - (unsigned long int) (i + section->vma)); - - fprintf(file, "%08lx %08lx %08lx %08lx %08lx", - begin_addr, - end_addr, - eh_handler, - eh_data, - prolog_end_addr); - -#ifdef POWERPC_LE_PE - if (eh_handler == 0 && eh_data != 0) - { - /* Special bits here, although the meaning may */ - /* be a little mysterious. The only one I know */ - /* for sure is 0x03. */ - /* Code Significance */ - /* 0x00 None */ - /* 0x01 Register Save Millicode */ - /* 0x02 Register Restore Millicode */ - /* 0x03 Glue Code Sequence */ - switch (eh_data) - { - case 0x01: - fprintf(file, " Register save millicode"); - break; - case 0x02: - fprintf(file, " Register restore millicode"); - break; - case 0x03: - fprintf(file, " Glue code sequence"); - break; - default: - break; - } - } -#endif - fprintf(file, "\n"); - } - - free (data); -} - -static const char *tbl[6] = -{ -"ABSOLUTE", -"HIGH", -"LOW", -"HIGHLOW", -"HIGHADJ", -"unknown" -}; - -static boolean -pe_print_reloc(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".reloc"); - bfd_size_type datasize = 0; - bfd_size_type i; - bfd_size_type start, stop; - int onaline = 20; - bfd_vma addr_value; - - if (section == 0) - return true; - - if (bfd_section_size (abfd, section) == 0) - return true; - - fprintf(file, - "\n\nPE File Base Relocations (interpreted .reloc" - " section contents)\n"); - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); - datasize = bfd_section_size (abfd, section); - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - start = 0; - - stop = bfd_section_size (abfd, section); - - for (i = start; i < stop;) - { - int j; - bfd_vma virtual_address; - long number, size; - - /* The .reloc section is a sequence of blocks, with a header consisting - of two 32 bit quantities, followed by a number of 16 bit entries */ - - virtual_address = bfd_get_32(abfd, data+i); - size = bfd_get_32(abfd, data+i+4); - number = (size - 8) / 2; - - if (size == 0) - { - break; - } - - fprintf (file, - "\nVirtual Address: %08lx Chunk size %d (0x%x) " - "Number of fixups %d\n", - virtual_address, size, size, number); - - for (j = 0; j < number; ++j) - { - unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2); - int t = (e & 0xF000) >> 12; - int off = e & 0x0FFF; - - if (t > 5) - abort(); - - fprintf(file, - "\treloc %4d offset %4x [%4x] %s\n", - j, off, off+virtual_address, tbl[t]); - - } - i += size; - } - - free (data); -} - -static boolean -pe_print_private_bfd_data (abfd, vfile) - bfd *abfd; - PTR vfile; -{ - FILE *file = (FILE *) vfile; - int j; - pe_data_type *pe = pe_data (abfd); - struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr; - - fprintf (file,"\nImageBase\t\t"); - fprintf_vma (file, i->ImageBase); - fprintf (file,"\nSectionAlignment\t"); - fprintf_vma (file, i->SectionAlignment); - fprintf (file,"\nFileAlignment\t\t"); - fprintf_vma (file, i->FileAlignment); - fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion); - fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion); - fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion); - fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion); - fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion); - fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion); - fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1); - fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage); - fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders); - fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum); - fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem); - fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics); - fprintf (file,"SizeOfStackReserve\t"); - fprintf_vma (file, i->SizeOfStackReserve); - fprintf (file,"\nSizeOfStackCommit\t"); - fprintf_vma (file, i->SizeOfStackCommit); - fprintf (file,"\nSizeOfHeapReserve\t"); - fprintf_vma (file, i->SizeOfHeapReserve); - fprintf (file,"\nSizeOfHeapCommit\t"); - fprintf_vma (file, i->SizeOfHeapCommit); - fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags); - fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes); - - fprintf (file,"\nThe Data Directory\n"); - for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) - { - fprintf (file, "Entry %1x ", j); - fprintf_vma (file, i->DataDirectory[j].VirtualAddress); - fprintf (file, " %08lx ", i->DataDirectory[j].Size); - fprintf (file, "%s\n", dir_names[j]); - } - - pe_print_idata(abfd, vfile); - pe_print_edata(abfd, vfile); - pe_print_pdata(abfd, vfile); - pe_print_reloc(abfd, vfile); - - return true; -} - -static boolean -pe_mkobject (abfd) - bfd * abfd; -{ - pe_data_type *pe; - abfd->tdata.pe_obj_data = - (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type)); - - if (abfd->tdata.pe_obj_data == 0) - return false; - - pe = pe_data (abfd); - - pe->coff.pe = 1; - pe->in_reloc_p = in_reloc_p; - return true; -} - -/* Create the COFF backend specific information. */ -static PTR -pe_mkobject_hook (abfd, filehdr, aouthdr) - bfd * abfd; - PTR filehdr; - PTR aouthdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - pe_data_type *pe; - - if (pe_mkobject (abfd) == false) - return NULL; - - pe = pe_data (abfd); - pe->coff.sym_filepos = internal_f->f_symptr; - /* These members communicate important constants about the symbol - table to GDB's symbol-reading code. These `constants' - unfortunately vary among coff implementations... */ - pe->coff.local_n_btmask = N_BTMASK; - pe->coff.local_n_btshft = N_BTSHFT; - pe->coff.local_n_tmask = N_TMASK; - pe->coff.local_n_tshift = N_TSHIFT; - pe->coff.local_symesz = SYMESZ; - pe->coff.local_auxesz = AUXESZ; - pe->coff.local_linesz = LINESZ; - - obj_raw_syment_count (abfd) = - obj_conv_table_size (abfd) = - internal_f->f_nsyms; - - pe->real_flags = internal_f->f_flags; - -#ifdef COFF_IMAGE_WITH_PE - if (aouthdr) - { - pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe; - } -#endif - - return (PTR) pe; -} - - - -/* Copy any private info we understand from the input bfd - to the output bfd. */ - -#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data - -static boolean -pe_bfd_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd, *obfd; -{ - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_coff_flavour - || obfd->xvec->flavour != bfd_target_coff_flavour) - return true; - - pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr; - - return true; -} diff --git a/contrib/gdb/bfd/ptrace-core.c b/contrib/gdb/bfd/ptrace-core.c deleted file mode 100644 index e356457e8fb..00000000000 --- a/contrib/gdb/bfd/ptrace-core.c +++ /dev/null @@ -1,233 +0,0 @@ -/* BFD backend for core files which use the ptrace_user structure - Copyright 1993, 1994 Free Software Foundation, Inc. - The structure of this file is based on trad-core.c written by John Gilmore - of Cygnus Support. - Modified to work with the ptrace_user structure by Kevin A. Buettner. - (Longterm it may be better to merge this file with trad-core.c) - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef PTRACE_CORE - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include -#include -#include -#include -#include -#include -#include -#include - - -struct trad_core_struct - { - asection *data_section; - asection *stack_section; - asection *reg_section; - struct ptrace_user u; - }; - -#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u)) -#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section) -#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section) -#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section) - -/* forward declarations */ - -const bfd_target *ptrace_unix_core_file_p PARAMS ((bfd *abfd)); -char * ptrace_unix_core_file_failing_command PARAMS ((bfd *abfd)); -int ptrace_unix_core_file_failing_signal PARAMS ((bfd *abfd)); -boolean ptrace_unix_core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -/* ARGSUSED */ -const bfd_target * -ptrace_unix_core_file_p (abfd) - bfd *abfd; - -{ - int val; - struct ptrace_user u; - struct trad_core_struct *rawptr; - - val = bfd_read ((void *)&u, 1, sizeof u, abfd); - if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC - || u.pt_rev != _BCS_PTRACE_REV) - { - /* Too small to be a core file */ - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - /* Allocate both the upage and the struct core_data at once, so - a single free() will free them both. */ - rawptr = (struct trad_core_struct *) - bfd_zalloc (abfd, sizeof (struct trad_core_struct)); - - if (rawptr == NULL) - return 0; - - abfd->tdata.trad_core_data = rawptr; - - rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */ - - /* Create the sections. This is raunchy, but bfd_close wants to free - them separately. */ - - core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_stacksec (abfd) == NULL) - return NULL; - core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_datasec (abfd) == NULL) - return NULL; - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) - return NULL; - - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - - /* FIXME: Need to worry about shared memory, library data, and library - text. I don't think that any of these things are supported on the - system on which I am developing this for though. */ - - - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - - core_datasec (abfd)->_raw_size = u.pt_dsize; - core_stacksec (abfd)->_raw_size = u.pt_ssize; - core_regsec (abfd)->_raw_size = sizeof(u); - - core_datasec (abfd)->vma = u.pt_o_data_start; - core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize; - core_regsec (abfd)->vma = 0 - sizeof(u); /* see trad-core.c */ - - core_datasec (abfd)->filepos = (int) u.pt_dataptr; - core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize); - core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */ - - /* Align to word at least */ - core_stacksec (abfd)->alignment_power = 2; - core_datasec (abfd)->alignment_power = 2; - core_regsec (abfd)->alignment_power = 2; - - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_datasec (abfd); - core_datasec (abfd)->next = core_regsec (abfd); - abfd->section_count = 3; - - return abfd->xvec; -} - -char * -ptrace_unix_core_file_failing_command (abfd) - bfd *abfd; -{ - char *com = abfd->tdata.trad_core_data->u.pt_comm; - if (*com) - return com; - else - return 0; -} - -/* ARGSUSED */ -int -ptrace_unix_core_file_failing_signal (abfd) - bfd *abfd; -{ - return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num; -} - -/* ARGSUSED */ -boolean -ptrace_unix_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - /* FIXME: Use pt_timdat field of the ptrace_user structure to match - the date of the executable */ - return true; -} - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target ptrace_core_vec = - { - "trad-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - ptrace_unix_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (ptrace_unix), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; - -#endif /* PTRACE_CORE */ diff --git a/contrib/gdb/bfd/reloc.c b/contrib/gdb/bfd/reloc.c deleted file mode 100644 index 46ed5c2d922..00000000000 --- a/contrib/gdb/bfd/reloc.c +++ /dev/null @@ -1,2391 +0,0 @@ -/* BFD support for handling relocation entries. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - Relocations - - BFD maintains relocations in much the same way it maintains - symbols: they are left alone until required, then read in - en-mass and translated into an internal form. A common - routine <> acts upon the - canonical form to do the fixup. - - Relocations are maintained on a per section basis, - while symbols are maintained on a per BFD basis. - - All that a back end has to do to fit the BFD interface is to create - a <> for each relocation - in a particular section, and fill in the right bits of the structures. - -@menu -@* typedef arelent:: -@* howto manager:: -@end menu - -*/ - -/* DO compile in the reloc_code name table from libbfd.h. */ -#define _BFD_MAKE_TABLE_bfd_reloc_code_real - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -/* -DOCDD -INODE - typedef arelent, howto manager, Relocations, Relocations - -SUBSECTION - typedef arelent - - This is the structure of a relocation entry: - -CODE_FRAGMENT -. -.typedef enum bfd_reloc_status -.{ -. {* No errors detected *} -. bfd_reloc_ok, -. -. {* The relocation was performed, but there was an overflow. *} -. bfd_reloc_overflow, -. -. {* The address to relocate was not within the section supplied. *} -. bfd_reloc_outofrange, -. -. {* Used by special functions *} -. bfd_reloc_continue, -. -. {* Unsupported relocation size requested. *} -. bfd_reloc_notsupported, -. -. {* Unused *} -. bfd_reloc_other, -. -. {* The symbol to relocate against was undefined. *} -. bfd_reloc_undefined, -. -. {* The relocation was performed, but may not be ok - presently -. generated only when linking i960 coff files with i960 b.out -. symbols. If this type is returned, the error_message argument -. to bfd_perform_relocation will be set. *} -. bfd_reloc_dangerous -. } -. bfd_reloc_status_type; -. -. -.typedef struct reloc_cache_entry -.{ -. {* A pointer into the canonical table of pointers *} -. struct symbol_cache_entry **sym_ptr_ptr; -. -. {* offset in section *} -. bfd_size_type address; -. -. {* addend for relocation value *} -. bfd_vma addend; -. -. {* Pointer to how to perform the required relocation *} -. reloc_howto_type *howto; -. -.} arelent; - -*/ - -/* -DESCRIPTION - - Here is a description of each of the fields within an <>: - - o <> - - The symbol table pointer points to a pointer to the symbol - associated with the relocation request. It is - the pointer into the table returned by the back end's - <> action. @xref{Symbols}. The symbol is referenced - through a pointer to a pointer so that tools like the linker - can fix up all the symbols of the same name by modifying only - one pointer. The relocation routine looks in the symbol and - uses the base of the section the symbol is attached to and the - value of the symbol as the initial relocation offset. If the - symbol pointer is zero, then the section provided is looked up. - - o <
> - - The <
> field gives the offset in bytes from the base of - the section data which owns the relocation record to the first - byte of relocatable information. The actual data relocated - will be relative to this point; for example, a relocation - type which modifies the bottom two bytes of a four byte word - would not touch the first byte pointed to in a big endian - world. - - o <> - - The <> is a value provided by the back end to be added (!) - to the relocation offset. Its interpretation is dependent upon - the howto. For example, on the 68k the code: - - -| char foo[]; -| main() -| { -| return foo[0x12345678]; -| } - - Could be compiled into: - -| linkw fp,#-4 -| moveb @@#12345678,d0 -| extbl d0 -| unlk fp -| rts - - - This could create a reloc pointing to <>, but leave the - offset in the data, something like: - - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000006 32 _foo -| -|00000000 4e56 fffc ; linkw fp,#-4 -|00000004 1039 1234 5678 ; moveb @@#12345678,d0 -|0000000a 49c0 ; extbl d0 -|0000000c 4e5e ; unlk fp -|0000000e 4e75 ; rts - - - Using coff and an 88k, some instructions don't have enough - space in them to represent the full address range, and - pointers have to be loaded in two parts. So you'd get something like: - - -| or.u r13,r0,hi16(_foo+0x12345678) -| ld.b r2,r13,lo16(_foo+0x12345678) -| jmp r1 - - - This should create two relocs, both pointing to <<_foo>>, and with - 0x12340000 in their addend field. The data would consist of: - - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000002 HVRT16 _foo+0x12340000 -|00000006 LVRT16 _foo+0x12340000 -| -|00000000 5da05678 ; or.u r13,r0,0x5678 -|00000004 1c4d5678 ; ld.b r2,r13,0x5678 -|00000008 f400c001 ; jmp r1 - - - The relocation routine digs out the value from the data, adds - it to the addend to get the original offset, and then adds the - value of <<_foo>>. Note that all 32 bits have to be kept around - somewhere, to cope with carry from bit 15 to bit 16. - - One further example is the sparc and the a.out format. The - sparc has a similar problem to the 88k, in that some - instructions don't have room for an entire offset, but on the - sparc the parts are created in odd sized lumps. The designers of - the a.out format chose to not use the data within the section - for storing part of the offset; all the offset is kept within - the reloc. Anything in the data should be ignored. - -| save %sp,-112,%sp -| sethi %hi(_foo+0x12345678),%g2 -| ldsb [%g2+%lo(_foo+0x12345678)],%i0 -| ret -| restore - - Both relocs contain a pointer to <>, and the offsets - contain junk. - - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000004 HI22 _foo+0x12345678 -|00000008 LO10 _foo+0x12345678 -| -|00000000 9de3bf90 ; save %sp,-112,%sp -|00000004 05000000 ; sethi %hi(_foo+0),%g2 -|00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0 -|0000000c 81c7e008 ; ret -|00000010 81e80000 ; restore - - - o <> - - The <> field can be imagined as a - relocation instruction. It is a pointer to a structure which - contains information on what to do with all of the other - information in the reloc record and data section. A back end - would normally have a relocation instruction set and turn - relocations into pointers to the correct structure on input - - but it would be possible to create each howto field on demand. - -*/ - -/* -SUBSUBSECTION - <> - - Indicates what sort of overflow checking should be done when - performing a relocation. - -CODE_FRAGMENT -. -.enum complain_overflow -.{ -. {* Do not complain on overflow. *} -. complain_overflow_dont, -. -. {* Complain if the bitfield overflows, whether it is considered -. as signed or unsigned. *} -. complain_overflow_bitfield, -. -. {* Complain if the value overflows when considered as signed -. number. *} -. complain_overflow_signed, -. -. {* Complain if the value overflows when considered as an -. unsigned number. *} -. complain_overflow_unsigned -.}; - -*/ - -/* -SUBSUBSECTION - <> - - The <> is a structure which contains all the - information that libbfd needs to know to tie up a back end's data. - -CODE_FRAGMENT -.struct symbol_cache_entry; {* Forward declaration *} -. -.struct reloc_howto_struct -.{ -. {* The type field has mainly a documetary use - the back end can -. do what it wants with it, though normally the back end's -. external idea of what a reloc number is stored -. in this field. For example, a PC relative word relocation -. in a coff environment has the type 023 - because that's -. what the outside world calls a R_PCRWORD reloc. *} -. unsigned int type; -. -. {* The value the final relocation is shifted right by. This drops -. unwanted data from the relocation. *} -. unsigned int rightshift; -. -. {* The size of the item to be relocated. This is *not* a -. power-of-two measure. To get the number of bytes operated -. on by a type of relocation, use bfd_get_reloc_size. *} -. int size; -. -. {* The number of bits in the item to be relocated. This is used -. when doing overflow checking. *} -. unsigned int bitsize; -. -. {* Notes that the relocation is relative to the location in the -. data section of the addend. The relocation function will -. subtract from the relocation value the address of the location -. being relocated. *} -. boolean pc_relative; -. -. {* The bit position of the reloc value in the destination. -. The relocated value is left shifted by this amount. *} -. unsigned int bitpos; -. -. {* What type of overflow error should be checked for when -. relocating. *} -. enum complain_overflow complain_on_overflow; -. -. {* If this field is non null, then the supplied function is -. called rather than the normal function. This allows really -. strange relocation methods to be accomodated (e.g., i960 callj -. instructions). *} -. bfd_reloc_status_type (*special_function) -. PARAMS ((bfd *abfd, -. arelent *reloc_entry, -. struct symbol_cache_entry *symbol, -. PTR data, -. asection *input_section, -. bfd *output_bfd, -. char **error_message)); -. -. {* The textual name of the relocation type. *} -. char *name; -. -. {* When performing a partial link, some formats must modify the -. relocations rather than the data - this flag signals this.*} -. boolean partial_inplace; -. -. {* The src_mask selects which parts of the read in data -. are to be used in the relocation sum. E.g., if this was an 8 bit -. bit of data which we read and relocated, this would be -. 0x000000ff. When we have relocs which have an addend, such as -. sun4 extended relocs, the value in the offset part of a -. relocating field is garbage so we never use it. In this case -. the mask would be 0x00000000. *} -. bfd_vma src_mask; -. -. {* The dst_mask selects which parts of the instruction are replaced -. into the instruction. In most cases src_mask == dst_mask, -. except in the above special case, where dst_mask would be -. 0x000000ff, and src_mask would be 0x00000000. *} -. bfd_vma dst_mask; -. -. {* When some formats create PC relative instructions, they leave -. the value of the pc of the place being relocated in the offset -. slot of the instruction, so that a PC relative relocation can -. be made just by adding in an ordinary offset (e.g., sun3 a.out). -. Some formats leave the displacement part of an instruction -. empty (e.g., m88k bcs); this flag signals the fact.*} -. boolean pcrel_offset; -. -.}; - -*/ - -/* -FUNCTION - The HOWTO Macro - -DESCRIPTION - The HOWTO define is horrible and will go away. - - -.#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ -. {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC} - -DESCRIPTION - And will be replaced with the totally magic way. But for the - moment, we are compatible, so do it this way. - - -.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN) -. -DESCRIPTION - Helper routine to turn a symbol into a relocation value. - -.#define HOWTO_PREPARE(relocation, symbol) \ -. { \ -. if (symbol != (asymbol *)NULL) { \ -. if (bfd_is_com_section (symbol->section)) { \ -. relocation = 0; \ -. } \ -. else { \ -. relocation = symbol->value; \ -. } \ -. } \ -.} - -*/ - -/* -FUNCTION - bfd_get_reloc_size - -SYNOPSIS - int bfd_get_reloc_size (reloc_howto_type *); - -DESCRIPTION - For a reloc_howto_type that operates on a fixed number of bytes, - this returns the number of bytes operated on. - */ - -int -bfd_get_reloc_size (howto) - reloc_howto_type *howto; -{ - switch (howto->size) - { - case 0: return 1; - case 1: return 2; - case 2: return 4; - case 3: return 0; - case 4: return 8; - case -2: return 4; - default: abort (); - } -} - -/* -TYPEDEF - arelent_chain - -DESCRIPTION - - How relocs are tied together in an <>: - -.typedef struct relent_chain { -. arelent relent; -. struct relent_chain *next; -.} arelent_chain; - -*/ - - - -/* -FUNCTION - bfd_perform_relocation - -SYNOPSIS - bfd_reloc_status_type - bfd_perform_relocation - (bfd *abfd, - arelent *reloc_entry, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message); - -DESCRIPTION - If @var{output_bfd} is supplied to this function, the - generated image will be relocatable; the relocations are - copied to the output file after they have been changed to - reflect the new state of the world. There are two ways of - reflecting the results of partial linkage in an output file: - by modifying the output data in place, and by modifying the - relocation record. Some native formats (e.g., basic a.out and - basic coff) have no way of specifying an addend in the - relocation type, so the addend has to go in the output data. - This is no big deal since in these formats the output data - slot will always be big enough for the addend. Complex reloc - types with addends were invented to solve just this problem. - The @var{error_message} argument is set to an error message if - this return @code{bfd_reloc_dangerous}. - -*/ - - -bfd_reloc_status_type -bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type addr = reloc_entry->address; - bfd_vma output_base = 0; - reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - asymbol *symbol; - - symbol = *(reloc_entry->sym_ptr_ptr); - if (bfd_is_abs_section (symbol->section) - && output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If we are not producing relocateable output, return an error if - the symbol is not defined. An undefined weak symbol is - considered to have a value of zero (SVR4 ABI, p. 4-27). */ - if (bfd_is_und_section (symbol->section) - && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == (bfd *) NULL) - flag = bfd_reloc_undefined; - - /* If there is a function supplied to handle this relocation type, - call it. It'll return `bfd_reloc_continue' if further processing - can be done. */ - if (howto->special_function) - { - bfd_reloc_status_type cont; - cont = howto->special_function (abfd, reloc_entry, symbol, data, - input_section, output_bfd, - error_message); - if (cont != bfd_reloc_continue) - return cont; - } - - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Work out which section the relocation is targetted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (output_bfd && howto->partial_inplace == false) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += reloc_entry->addend; - - /* Here the variable relocation holds the final address of the - symbol we are relocating against, plus any addend. */ - - if (howto->pc_relative == true) - { - /* This is a PC relative relocation. We want to set RELOCATION - to the distance between the address of the symbol and the - location. RELOCATION is already the address of the symbol. - - We start by subtracting the address of the section containing - the location. - - If pcrel_offset is set, we must further subtract the position - of the location within the section. Some targets arrange for - the addend to be the negative of the position of the location - within the section; for example, i386-aout does this. For - i386-aout, pcrel_offset is false. Some other targets do not - include the position of the location; for example, m88kbcs, - or ELF. For those targets, pcrel_offset is true. - - If we are producing relocateable output, then we must ensure - that this reloc will be correctly computed when the final - relocation is done. If pcrel_offset is false we want to wind - up with the negative of the location within the section, - which means we must adjust the existing addend by the change - in the location within the section. If pcrel_offset is true - we do not want to adjust the existing addend at all. - - FIXME: This seems logical to me, but for the case of - producing relocateable output it is not what the code - actually does. I don't want to change it, because it seems - far too likely that something will break. */ - - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset == true) - relocation -= reloc_entry->address; - } - - if (output_bfd != (bfd *) NULL) - { - if (howto->partial_inplace == false) - { - /* This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. */ - reloc_entry->addend = relocation; - reloc_entry->address += input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol. */ - - reloc_entry->address += input_section->output_offset; - - /* WTF?? */ - if (abfd->xvec->flavour == bfd_target_coff_flavour - && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-little") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-big") != 0) - { -#if 1 - /* For m68k-coff, the addend was being subtracted twice during - relocation with -r. Removing the line below this comment - fixes that problem; see PR 2953. - -However, Ian wrote the following, regarding removing the line below, -which explains why it is still enabled: --djm - -If you put a patch like that into BFD you need to check all the COFF -linkers. I am fairly certain that patch will break coff-i386 (e.g., -SCO); see coff_i386_reloc in coff-i386.c where I worked around the -problem in a different way. There may very well be a reason that the -code works as it does. - -Hmmm. The first obvious point is that bfd_perform_relocation should -not have any tests that depend upon the flavour. It's seem like -entirely the wrong place for such a thing. The second obvious point -is that the current code ignores the reloc addend when producing -relocateable output for COFF. That's peculiar. In fact, I really -have no idea what the point of the line you want to remove is. - -A typical COFF reloc subtracts the old value of the symbol and adds in -the new value to the location in the object file (if it's a pc -relative reloc it adds the difference between the symbol value and the -location). When relocating we need to preserve that property. - -BFD handles this by setting the addend to the negative of the old -value of the symbol. Unfortunately it handles common symbols in a -non-standard way (it doesn't subtract the old value) but that's a -different story (we can't change it without losing backward -compatibility with old object files) (coff-i386 does subtract the old -value, to be compatible with existing coff-i386 targets, like SCO). - -So everything works fine when not producing relocateable output. When -we are producing relocateable output, logically we should do exactly -what we do when not producing relocateable output. Therefore, your -patch is correct. In fact, it should probably always just set -reloc_entry->addend to 0 for all cases, since it is, in fact, going to -add the value into the object file. This won't hurt the COFF code, -which doesn't use the addend; I'm not sure what it will do to other -formats (the thing to check for would be whether any formats both use -the addend and set partial_inplace). - -When I wanted to make coff-i386 produce relocateable output, I ran -into the problem that you are running into: I wanted to remove that -line. Rather than risk it, I made the coff-i386 relocs use a special -function; it's coff_i386_reloc in coff-i386.c. The function -specifically adds the addend field into the object file, knowing that -bfd_perform_relocation is not going to. If you remove that line, then -coff-i386.c will wind up adding the addend field in twice. It's -trivial to fix; it just needs to be done. - -The problem with removing the line is just that it may break some -working code. With BFD it's hard to be sure of anything. The right -way to deal with this is simply to build and test at least all the -supported COFF targets. It should be straightforward if time and disk -space consuming. For each target: - 1) build the linker - 2) generate some executable, and link it using -r (I would - probably use paranoia.o and link against newlib/libc.a, which - for all the supported targets would be available in - /usr/cygnus/progressive/H-host/target/lib/libc.a). - 3) make the change to reloc.c - 4) rebuild the linker - 5) repeat step 2 - 6) if the resulting object files are the same, you have at least - made it no worse - 7) if they are different you have to figure out which version is - right -*/ - relocation -= reloc_entry->addend; -#endif - reloc_entry->addend = 0; - } - else - { - reloc_entry->addend = relocation; - } - } - } - else - { - reloc_entry->addend = 0; - } - - /* FIXME: This overflow checking is incomplete, because the value - might have overflowed before we get here. For a correct check we - need to compute the value in a size larger than bitsize, but we - can't reasonably do that for a reloc the same size as a host - machine word. - FIXME: We should also do overflow checking on the result after - adding in the value contained in the object file. */ - if (howto->complain_on_overflow != complain_overflow_dont - && flag == bfd_reloc_ok) - { - bfd_vma check; - - /* Get the value that will be used for the relocation, but - starting at bit position zero. */ - check = relocation >> howto->rightshift; - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - /* The above right shift is incorrect for a signed value. - Fix it up by forcing on the upper bits. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if ((bfd_signed_vma) check > reloc_signed_max - || (bfd_signed_vma) check < reloc_signed_min) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((bfd_vma) check > reloc_unsigned_max) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - { - /* The above right shift is incorrect for a signed - value. See if turning on the upper bits fixes the - overflow. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - flag = bfd_reloc_overflow; - } - else - flag = bfd_reloc_overflow; - } - } - break; - default: - abort (); - } - } - - /* - Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs) - */ - - /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler - (OSF version 1.3, compiler version 3.11). It miscompiles the - following program: - - struct str - { - unsigned int i0; - } s = { 0 }; - - int - main () - { - unsigned long x; - - x = 0x100000000; - x <<= (unsigned long) s.i0; - if (x == 0) - printf ("failed\n"); - else - printf ("succeeded (%lx)\n", x); - } - */ - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= (bfd_vma) howto->bitpos; - - /* Wait for the day when all have the mask in them */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - i i i i i o o o o o from bfd_get - and S S S S S to get the size offset we want - + r r r r r r r r r r to get the final value to place - and D D D D D to chop to right size - ----------------------- - A A A A A - And this: - ... i i i i i o o o o o from bfd_get - and N N N N N get instruction - ----------------------- - ... B B B B B - - And then: - B B B B B - or A A A A A - ----------------------- - R R R R R R R R R R put into bfd_put - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, (char *) data + addr); - DOIT (x); - bfd_put_8 (abfd, x, (unsigned char *) data + addr); - } - break; - - case 1: - if (relocation) - { - short x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - DOIT (x); - bfd_put_16 (abfd, x, (unsigned char *) data + addr); - } - break; - case 2: - if (relocation) - { - long x = bfd_get_32 (abfd, (bfd_byte *) data + addr); - DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data + addr); - } - break; - case -2: - { - long x = bfd_get_32 (abfd, (bfd_byte *) data + addr); - relocation = -relocation; - DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data + addr); - } - break; - - case -1: - { - long x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - relocation = -relocation; - DOIT (x); - bfd_put_16 (abfd, x, (bfd_byte *) data + addr); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: -#ifdef BFD64 - if (relocation) - { - bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr); - DOIT (x); - bfd_put_64 (abfd, x, (bfd_byte *) data + addr); - } -#else - abort (); -#endif - break; - default: - return bfd_reloc_other; - } - - return flag; -} - -/* -FUNCTION - bfd_install_relocation - -SYNOPSIS - bfd_reloc_status_type - bfd_install_relocation - (bfd *abfd, - arelent *reloc_entry, - PTR data, bfd_vma data_start, - asection *input_section, - char **error_message); - -DESCRIPTION - This looks remarkably like <>, except it - does not expect that the section contents have been filled in. - I.e., it's suitable for use when creating, rather than applying - a relocation. - - For now, this function should be considered reserved for the - assembler. - -*/ - - -bfd_reloc_status_type -bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset, - input_section, error_message) - bfd *abfd; - arelent *reloc_entry; - PTR data_start; - bfd_vma data_start_offset; - asection *input_section; - char **error_message; -{ - bfd_vma relocation; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type addr = reloc_entry->address; - bfd_vma output_base = 0; - reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - asymbol *symbol; - bfd_byte *data; - - symbol = *(reloc_entry->sym_ptr_ptr); - if (bfd_is_abs_section (symbol->section)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If there is a function supplied to handle this relocation type, - call it. It'll return `bfd_reloc_continue' if further processing - can be done. */ - if (howto->special_function) - { - bfd_reloc_status_type cont; - /* XXX - The special_function calls haven't been fixed up to deal - with creating new relocations and section contents. */ - cont = howto->special_function (abfd, reloc_entry, symbol, - /* XXX - Non-portable! */ - ((bfd_byte *) data_start - - data_start_offset), - input_section, abfd, error_message); - if (cont != bfd_reloc_continue) - return cont; - } - - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Work out which section the relocation is targetted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (howto->partial_inplace == false) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += reloc_entry->addend; - - /* Here the variable relocation holds the final address of the - symbol we are relocating against, plus any addend. */ - - if (howto->pc_relative == true) - { - /* This is a PC relative relocation. We want to set RELOCATION - to the distance between the address of the symbol and the - location. RELOCATION is already the address of the symbol. - - We start by subtracting the address of the section containing - the location. - - If pcrel_offset is set, we must further subtract the position - of the location within the section. Some targets arrange for - the addend to be the negative of the position of the location - within the section; for example, i386-aout does this. For - i386-aout, pcrel_offset is false. Some other targets do not - include the position of the location; for example, m88kbcs, - or ELF. For those targets, pcrel_offset is true. - - If we are producing relocateable output, then we must ensure - that this reloc will be correctly computed when the final - relocation is done. If pcrel_offset is false we want to wind - up with the negative of the location within the section, - which means we must adjust the existing addend by the change - in the location within the section. If pcrel_offset is true - we do not want to adjust the existing addend at all. - - FIXME: This seems logical to me, but for the case of - producing relocateable output it is not what the code - actually does. I don't want to change it, because it seems - far too likely that something will break. */ - - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset == true && howto->partial_inplace == true) - relocation -= reloc_entry->address; - } - - if (howto->partial_inplace == false) - { - /* This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. */ - reloc_entry->addend = relocation; - reloc_entry->address += input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol. */ - - reloc_entry->address += input_section->output_offset; - - /* WTF?? */ - if (abfd->xvec->flavour == bfd_target_coff_flavour - && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-little") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-big") != 0) - { -#if 1 -/* For m68k-coff, the addend was being subtracted twice during - relocation with -r. Removing the line below this comment - fixes that problem; see PR 2953. - -However, Ian wrote the following, regarding removing the line below, -which explains why it is still enabled: --djm - -If you put a patch like that into BFD you need to check all the COFF -linkers. I am fairly certain that patch will break coff-i386 (e.g., -SCO); see coff_i386_reloc in coff-i386.c where I worked around the -problem in a different way. There may very well be a reason that the -code works as it does. - -Hmmm. The first obvious point is that bfd_install_relocation should -not have any tests that depend upon the flavour. It's seem like -entirely the wrong place for such a thing. The second obvious point -is that the current code ignores the reloc addend when producing -relocateable output for COFF. That's peculiar. In fact, I really -have no idea what the point of the line you want to remove is. - -A typical COFF reloc subtracts the old value of the symbol and adds in -the new value to the location in the object file (if it's a pc -relative reloc it adds the difference between the symbol value and the -location). When relocating we need to preserve that property. - -BFD handles this by setting the addend to the negative of the old -value of the symbol. Unfortunately it handles common symbols in a -non-standard way (it doesn't subtract the old value) but that's a -different story (we can't change it without losing backward -compatibility with old object files) (coff-i386 does subtract the old -value, to be compatible with existing coff-i386 targets, like SCO). - -So everything works fine when not producing relocateable output. When -we are producing relocateable output, logically we should do exactly -what we do when not producing relocateable output. Therefore, your -patch is correct. In fact, it should probably always just set -reloc_entry->addend to 0 for all cases, since it is, in fact, going to -add the value into the object file. This won't hurt the COFF code, -which doesn't use the addend; I'm not sure what it will do to other -formats (the thing to check for would be whether any formats both use -the addend and set partial_inplace). - -When I wanted to make coff-i386 produce relocateable output, I ran -into the problem that you are running into: I wanted to remove that -line. Rather than risk it, I made the coff-i386 relocs use a special -function; it's coff_i386_reloc in coff-i386.c. The function -specifically adds the addend field into the object file, knowing that -bfd_install_relocation is not going to. If you remove that line, then -coff-i386.c will wind up adding the addend field in twice. It's -trivial to fix; it just needs to be done. - -The problem with removing the line is just that it may break some -working code. With BFD it's hard to be sure of anything. The right -way to deal with this is simply to build and test at least all the -supported COFF targets. It should be straightforward if time and disk -space consuming. For each target: - 1) build the linker - 2) generate some executable, and link it using -r (I would - probably use paranoia.o and link against newlib/libc.a, which - for all the supported targets would be available in - /usr/cygnus/progressive/H-host/target/lib/libc.a). - 3) make the change to reloc.c - 4) rebuild the linker - 5) repeat step 2 - 6) if the resulting object files are the same, you have at least - made it no worse - 7) if they are different you have to figure out which version is - right -*/ - relocation -= reloc_entry->addend; -#endif - reloc_entry->addend = 0; - } - else - { - reloc_entry->addend = relocation; - } - } - - /* FIXME: This overflow checking is incomplete, because the value - might have overflowed before we get here. For a correct check we - need to compute the value in a size larger than bitsize, but we - can't reasonably do that for a reloc the same size as a host - machine word. - - FIXME: We should also do overflow checking on the result after - adding in the value contained in the object file. */ - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - - /* Get the value that will be used for the relocation, but - starting at bit position zero. */ - check = relocation >> howto->rightshift; - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - /* The above right shift is incorrect for a signed value. - Fix it up by forcing on the upper bits. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if ((bfd_signed_vma) check > reloc_signed_max - || (bfd_signed_vma) check < reloc_signed_min) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((bfd_vma) check > reloc_unsigned_max) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - { - /* The above right shift is incorrect for a signed - value. See if turning on the upper bits fixes the - overflow. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - flag = bfd_reloc_overflow; - } - else - flag = bfd_reloc_overflow; - } - } - break; - default: - abort (); - } - } - - /* - Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs) - */ - - /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler - (OSF version 1.3, compiler version 3.11). It miscompiles the - following program: - - struct str - { - unsigned int i0; - } s = { 0 }; - - int - main () - { - unsigned long x; - - x = 0x100000000; - x <<= (unsigned long) s.i0; - if (x == 0) - printf ("failed\n"); - else - printf ("succeeded (%lx)\n", x); - } - */ - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= (bfd_vma) howto->bitpos; - - /* Wait for the day when all have the mask in them */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - i i i i i o o o o o from bfd_get - and S S S S S to get the size offset we want - + r r r r r r r r r r to get the final value to place - and D D D D D to chop to right size - ----------------------- - A A A A A - And this: - ... i i i i i o o o o o from bfd_get - and N N N N N get instruction - ----------------------- - ... B B B B B - - And then: - B B B B B - or A A A A A - ----------------------- - R R R R R R R R R R put into bfd_put - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - data = (bfd_byte *) data_start + (addr - data_start_offset); - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, (char *) data); - DOIT (x); - bfd_put_8 (abfd, x, (unsigned char *) data); - } - break; - - case 1: - if (relocation) - { - short x = bfd_get_16 (abfd, (bfd_byte *) data); - DOIT (x); - bfd_put_16 (abfd, x, (unsigned char *) data); - } - break; - case 2: - if (relocation) - { - long x = bfd_get_32 (abfd, (bfd_byte *) data); - DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data); - } - break; - case -2: - { - long x = bfd_get_32 (abfd, (bfd_byte *) data); - relocation = -relocation; - DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: - if (relocation) - { - bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data); - DOIT (x); - bfd_put_64 (abfd, x, (bfd_byte *) data); - } - break; - default: - return bfd_reloc_other; - } - - return flag; -} - -/* This relocation routine is used by some of the backend linkers. - They do not construct asymbol or arelent structures, so there is no - reason for them to use bfd_perform_relocation. Also, - bfd_perform_relocation is so hacked up it is easier to write a new - function than to try to deal with it. - - This routine does a final relocation. It should not be used when - generating relocateable output. - - FIXME: This routine ignores any special_function in the HOWTO, - since the existing special_function values have been written for - bfd_perform_relocation. - - HOWTO is the reloc howto information. - INPUT_BFD is the BFD which the reloc applies to. - INPUT_SECTION is the section which the reloc applies to. - CONTENTS is the contents of the section. - ADDRESS is the address of the reloc within INPUT_SECTION. - VALUE is the value of the symbol the reloc refers to. - ADDEND is the addend of the reloc. */ - -bfd_reloc_status_type -_bfd_final_link_relocate (howto, input_bfd, input_section, contents, address, - value, addend) - reloc_howto_type *howto; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - bfd_vma address; - bfd_vma value; - bfd_vma addend; -{ - bfd_vma relocation; - - /* Sanity check the address. */ - if (address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* This function assumes that we are dealing with a basic relocation - against a symbol. We want to compute the value of the symbol to - relocate to. This is just VALUE, the value of the symbol, plus - ADDEND, any addend associated with the reloc. */ - relocation = value + addend; - - /* If the relocation is PC relative, we want to set RELOCATION to - the distance between the symbol (currently in RELOCATION) and the - location we are relocating. Some targets (e.g., i386-aout) - arrange for the contents of the section to be the negative of the - offset of the location within the section; for such targets - pcrel_offset is false. Other targets (e.g., m88kbcs or ELF) - simply leave the contents of the section as zero; for such - targets pcrel_offset is true. If pcrel_offset is false we do not - need to subtract out the offset of the location within the - section (which is just ADDRESS). */ - if (howto->pc_relative) - { - relocation -= (input_section->output_section->vma - + input_section->output_offset); - if (howto->pcrel_offset) - relocation -= address; - } - - return _bfd_relocate_contents (howto, input_bfd, relocation, - contents + address); -} - -/* Relocate a given location using a given value and howto. */ - -bfd_reloc_status_type -_bfd_relocate_contents (howto, input_bfd, relocation, location) - reloc_howto_type *howto; - bfd *input_bfd; - bfd_vma relocation; - bfd_byte *location; -{ - int size; - bfd_vma x; - boolean overflow; - - /* If the size is negative, negate RELOCATION. This isn't very - general. */ - if (howto->size < 0) - relocation = -relocation; - - /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - case 0: - abort (); - case 1: - x = bfd_get_8 (input_bfd, location); - break; - case 2: - x = bfd_get_16 (input_bfd, location); - break; - case 4: - x = bfd_get_32 (input_bfd, location); - break; - case 8: -#ifdef BFD64 - x = bfd_get_64 (input_bfd, location); -#else - abort (); -#endif - break; - } - - /* Check for overflow. FIXME: We may drop bits during the addition - which we don't check for. We must either check at every single - operation, which would be tedious, or we must do the computations - in a type larger than bfd_vma, which would be inefficient. */ - overflow = false; - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - bfd_signed_vma signed_check; - bfd_vma add; - bfd_signed_vma signed_add; - - if (howto->rightshift == 0) - { - check = relocation; - signed_check = (bfd_signed_vma) relocation; - } - else - { - /* Drop unwanted bits from the value we are relocating to. */ - check = relocation >> howto->rightshift; - - /* If this is a signed value, the rightshift just dropped - leading 1 bits (assuming twos complement). */ - if ((bfd_signed_vma) relocation >= 0) - signed_check = check; - else - signed_check = (check - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->rightshift))); - } - - /* Get the value from the object file. */ - add = x & howto->src_mask; - - /* Get the value from the object file with an appropriate sign. - The expression involving howto->src_mask isolates the upper - bit of src_mask. If that bit is set in the value we are - adding, it is negative, and we subtract out that number times - two. If src_mask includes the highest possible bit, then we - can not get the upper bit, but that does not matter since - signed_add needs no adjustment to become negative in that - case. */ - signed_add = add; - if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0) - signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1; - - /* Add the value from the object file, shifted so that it is a - straight number. */ - if (howto->bitpos == 0) - { - check += add; - signed_check += signed_add; - } - else - { - check += add >> howto->bitpos; - - /* For the signed case we use ADD, rather than SIGNED_ADD, - to avoid warnings from SVR4 cc. This is OK since we - explictly handle the sign bits. */ - if (signed_add >= 0) - signed_check += add >> howto->bitpos; - else - signed_check += ((add >> howto->bitpos) - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->bitpos))); - } - - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - if (signed_check > reloc_signed_max - || signed_check < reloc_signed_min) - overflow = true; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (check > reloc_unsigned_max) - overflow = true; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((check & ~reloc_bits) != 0 - && (((bfd_vma) signed_check & ~reloc_bits) - != (-1 & ~reloc_bits))) - overflow = true; - } - break; - default: - abort (); - } - } - - /* Put RELOCATION in the right bits. */ - relocation >>= (bfd_vma) howto->rightshift; - relocation <<= (bfd_vma) howto->bitpos; - - /* Add RELOCATION to the right bits of X. */ - x = ((x & ~howto->dst_mask) - | (((x & howto->src_mask) + relocation) & howto->dst_mask)); - - /* Put the relocated value back in the object file. */ - switch (size) - { - default: - case 0: - abort (); - case 1: - bfd_put_8 (input_bfd, x, location); - break; - case 2: - bfd_put_16 (input_bfd, x, location); - break; - case 4: - bfd_put_32 (input_bfd, x, location); - break; - case 8: -#ifdef BFD64 - bfd_put_64 (input_bfd, x, location); -#else - abort (); -#endif - break; - } - - return overflow ? bfd_reloc_overflow : bfd_reloc_ok; -} - -/* -DOCDD -INODE - howto manager, , typedef arelent, Relocations - -SECTION - The howto manager - - When an application wants to create a relocation, but doesn't - know what the target machine might call it, it can find out by - using this bit of code. - -*/ - -/* -TYPEDEF - bfd_reloc_code_type - -DESCRIPTION - The insides of a reloc code. The idea is that, eventually, there - will be one enumerator for every type of relocation we ever do. - Pass one of these values to <>, and it'll - return a howto pointer. - - This does mean that the application must determine the correct - enumerator value; you can't get a howto pointer from a random set - of attributes. - -SENUM - bfd_reloc_code_real - -ENUM - BFD_RELOC_64 -ENUMX - BFD_RELOC_32 -ENUMX - BFD_RELOC_26 -ENUMX - BFD_RELOC_16 -ENUMX - BFD_RELOC_14 -ENUMX - BFD_RELOC_8 -ENUMDOC - Basic absolute relocations of N bits. - -ENUM - BFD_RELOC_64_PCREL -ENUMX - BFD_RELOC_32_PCREL -ENUMX - BFD_RELOC_24_PCREL -ENUMX - BFD_RELOC_16_PCREL -ENUMX - BFD_RELOC_12_PCREL -ENUMX - BFD_RELOC_8_PCREL -ENUMDOC - PC-relative relocations. Sometimes these are relative to the address -of the relocation itself; sometimes they are relative to the start of -the section containing the relocation. It depends on the specific target. - -The 24-bit relocation is used in some Intel 960 configurations. - -ENUM - BFD_RELOC_32_GOT_PCREL -ENUMX - BFD_RELOC_16_GOT_PCREL -ENUMX - BFD_RELOC_8_GOT_PCREL -ENUMX - BFD_RELOC_32_GOTOFF -ENUMX - BFD_RELOC_16_GOTOFF -ENUMX - BFD_RELOC_LO16_GOTOFF -ENUMX - BFD_RELOC_HI16_GOTOFF -ENUMX - BFD_RELOC_HI16_S_GOTOFF -ENUMX - BFD_RELOC_8_GOTOFF -ENUMX - BFD_RELOC_32_PLT_PCREL -ENUMX - BFD_RELOC_24_PLT_PCREL -ENUMX - BFD_RELOC_16_PLT_PCREL -ENUMX - BFD_RELOC_8_PLT_PCREL -ENUMX - BFD_RELOC_32_PLTOFF -ENUMX - BFD_RELOC_16_PLTOFF -ENUMX - BFD_RELOC_LO16_PLTOFF -ENUMX - BFD_RELOC_HI16_PLTOFF -ENUMX - BFD_RELOC_HI16_S_PLTOFF -ENUMX - BFD_RELOC_8_PLTOFF -ENUMDOC - For ELF. - -ENUM - BFD_RELOC_68K_GLOB_DAT -ENUMX - BFD_RELOC_68K_JMP_SLOT -ENUMX - BFD_RELOC_68K_RELATIVE -ENUMDOC - Relocations used by 68K ELF. - -ENUM - BFD_RELOC_32_BASEREL -ENUMX - BFD_RELOC_16_BASEREL -ENUMX - BFD_RELOC_LO16_BASEREL -ENUMX - BFD_RELOC_HI16_BASEREL -ENUMX - BFD_RELOC_HI16_S_BASEREL -ENUMX - BFD_RELOC_8_BASEREL -ENUMX - BFD_RELOC_RVA -ENUMDOC - Linkage-table relative. - -ENUM - BFD_RELOC_8_FFnn -ENUMDOC - Absolute 8-bit relocation, but used to form an address like 0xFFnn. - -ENUM - BFD_RELOC_32_PCREL_S2 -ENUMX - BFD_RELOC_16_PCREL_S2 -ENUMX - BFD_RELOC_23_PCREL_S2 -ENUMDOC - These PC-relative relocations are stored as word displacements -- -i.e., byte displacements shifted right two bits. The 30-bit word -displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the -SPARC. (SPARC tools generally refer to this as <>.) The -signed 16-bit displacement is used on the MIPS, and the 23-bit -displacement is used on the Alpha. - -ENUM - BFD_RELOC_HI22 -ENUMX - BFD_RELOC_LO10 -ENUMDOC - High 22 bits and low 10 bits of 32-bit value, placed into lower bits of -the target word. These are used on the SPARC. - -ENUM - BFD_RELOC_GPREL16 -ENUMX - BFD_RELOC_GPREL32 -ENUMDOC - For systems that allocate a Global Pointer register, these are -displacements off that register. These relocation types are -handled specially, because the value the register will have is -decided relatively late. - - -ENUM - BFD_RELOC_I960_CALLJ -ENUMDOC - Reloc types used for i960/b.out. - -ENUM - BFD_RELOC_NONE -ENUMX - BFD_RELOC_SPARC_WDISP22 -ENUMX - BFD_RELOC_SPARC22 -ENUMX - BFD_RELOC_SPARC13 -ENUMX - BFD_RELOC_SPARC_GOT10 -ENUMX - BFD_RELOC_SPARC_GOT13 -ENUMX - BFD_RELOC_SPARC_GOT22 -ENUMX - BFD_RELOC_SPARC_PC10 -ENUMX - BFD_RELOC_SPARC_PC22 -ENUMX - BFD_RELOC_SPARC_WPLT30 -ENUMX - BFD_RELOC_SPARC_COPY -ENUMX - BFD_RELOC_SPARC_GLOB_DAT -ENUMX - BFD_RELOC_SPARC_JMP_SLOT -ENUMX - BFD_RELOC_SPARC_RELATIVE -ENUMX - BFD_RELOC_SPARC_UA32 -ENUMDOC - SPARC ELF relocations. There is probably some overlap with other - relocation types already defined. - -ENUM - BFD_RELOC_SPARC_BASE13 -ENUMX - BFD_RELOC_SPARC_BASE22 -ENUMDOC - I think these are specific to SPARC a.out (e.g., Sun 4). - -ENUMEQ - BFD_RELOC_SPARC_64 - BFD_RELOC_64 -ENUMX - BFD_RELOC_SPARC_10 -ENUMX - BFD_RELOC_SPARC_11 -ENUMX - BFD_RELOC_SPARC_OLO10 -ENUMX - BFD_RELOC_SPARC_HH22 -ENUMX - BFD_RELOC_SPARC_HM10 -ENUMX - BFD_RELOC_SPARC_LM22 -ENUMX - BFD_RELOC_SPARC_PC_HH22 -ENUMX - BFD_RELOC_SPARC_PC_HM10 -ENUMX - BFD_RELOC_SPARC_PC_LM22 -ENUMX - BFD_RELOC_SPARC_WDISP16 -ENUMX - BFD_RELOC_SPARC_WDISP19 -ENUMX - BFD_RELOC_SPARC_GLOB_JMP -ENUMX - BFD_RELOC_SPARC_7 -ENUMX - BFD_RELOC_SPARC_6 -ENUMX - BFD_RELOC_SPARC_5 -ENUMDOC - Some relocations we're using for SPARC V9 -- subject to change. - -ENUM - BFD_RELOC_ALPHA_GPDISP_HI16 -ENUMDOC - Alpha ECOFF relocations. Some of these treat the symbol or "addend" - in some special way. - For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when - writing; when reading, it will be the absolute section symbol. The - addend is the displacement in bytes of the "lda" instruction from - the "ldah" instruction (which is at the address of this reloc). -ENUM - BFD_RELOC_ALPHA_GPDISP_LO16 -ENUMDOC - For GPDISP_LO16 ("ignore") relocations, the symbol is handled as - with GPDISP_HI16 relocs. The addend is ignored when writing the - relocations out, and is filled in with the file's GP value on - reading, for convenience. - -ENUM - BFD_RELOC_ALPHA_LITERAL -ENUMX - BFD_RELOC_ALPHA_LITUSE -ENUMDOC - The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; - the assembler turns it into a LDQ instruction to load the address of - the symbol, and then fills in a register in the real instruction. - - The LITERAL reloc, at the LDQ instruction, refers to the .lita - section symbol. The addend is ignored when writing, but is filled - in with the file's GP value on reading, for convenience, as with the - GPDISP_LO16 reloc. - - The LITUSE reloc, on the instruction using the loaded address, gives - information to the linker that it might be able to use to optimize - away some literal section references. The symbol is ignored (read - as the absolute section symbol), and the "addend" indicates the type - of instruction using the register: - 1 - "memory" fmt insn - 2 - byte-manipulation (byte offset reg) - 3 - jsr (target of branch) - - The GNU linker currently doesn't do any of this optimizing. - -ENUM - BFD_RELOC_ALPHA_HINT -ENUMDOC - The HINT relocation indicates a value that should be filled into the - "hint" field of a jmp/jsr/ret instruction, for possible branch- - prediction logic which may be provided on some processors. - -ENUM - BFD_RELOC_MIPS_JMP -ENUMDOC - Bits 27..2 of the relocation address shifted right 2 bits; - simple reloc otherwise. - -ENUM - BFD_RELOC_HI16 -ENUMDOC - High 16 bits of 32-bit value; simple reloc. -ENUM - BFD_RELOC_HI16_S -ENUMDOC - High 16 bits of 32-bit value but the low 16 bits will be sign - extended and added to form the final result. If the low 16 - bits form a negative number, we need to add one to the high value - to compensate for the borrow when the low bits are added. -ENUM - BFD_RELOC_LO16 -ENUMDOC - Low 16 bits. -ENUM - BFD_RELOC_PCREL_HI16_S -ENUMDOC - Like BFD_RELOC_HI16_S, but PC relative. -ENUM - BFD_RELOC_PCREL_LO16 -ENUMDOC - Like BFD_RELOC_LO16, but PC relative. - -ENUMEQ - BFD_RELOC_MIPS_GPREL - BFD_RELOC_GPREL16 -ENUMDOC - Relocation relative to the global pointer. - -ENUM - BFD_RELOC_MIPS_LITERAL -ENUMDOC - Relocation against a MIPS literal section. - -ENUM - BFD_RELOC_MIPS_GOT16 -ENUMX - BFD_RELOC_MIPS_CALL16 -ENUMEQX - BFD_RELOC_MIPS_GPREL32 - BFD_RELOC_GPREL32 -ENUMX - BFD_RELOC_MIPS_GOT_HI16 -ENUMX - BFD_RELOC_MIPS_GOT_LO16 -ENUMX - BFD_RELOC_MIPS_CALL_HI16 -ENUMX - BFD_RELOC_MIPS_CALL_LO16 -ENUMDOC - MIPS ELF relocations. - -ENUM - BFD_RELOC_386_GOT32 -ENUMX - BFD_RELOC_386_PLT32 -ENUMX - BFD_RELOC_386_COPY -ENUMX - BFD_RELOC_386_GLOB_DAT -ENUMX - BFD_RELOC_386_JUMP_SLOT -ENUMX - BFD_RELOC_386_RELATIVE -ENUMX - BFD_RELOC_386_GOTOFF -ENUMX - BFD_RELOC_386_GOTPC -ENUMDOC - i386/elf relocations - -ENUM - BFD_RELOC_NS32K_IMM_8 -ENUMX - BFD_RELOC_NS32K_IMM_16 -ENUMX - BFD_RELOC_NS32K_IMM_32 -ENUMX - BFD_RELOC_NS32K_IMM_8_PCREL -ENUMX - BFD_RELOC_NS32K_IMM_16_PCREL -ENUMX - BFD_RELOC_NS32K_IMM_32_PCREL -ENUMX - BFD_RELOC_NS32K_DISP_8 -ENUMX - BFD_RELOC_NS32K_DISP_16 -ENUMX - BFD_RELOC_NS32K_DISP_32 -ENUMX - BFD_RELOC_NS32K_DISP_8_PCREL -ENUMX - BFD_RELOC_NS32K_DISP_16_PCREL -ENUMX - BFD_RELOC_NS32K_DISP_32_PCREL -ENUMDOC - ns32k relocations - -ENUM - BFD_RELOC_PPC_B26 -ENUMX - BFD_RELOC_PPC_BA26 -ENUMX - BFD_RELOC_PPC_TOC16 -ENUMX - BFD_RELOC_PPC_B16 -ENUMX - BFD_RELOC_PPC_B16_BRTAKEN -ENUMX - BFD_RELOC_PPC_B16_BRNTAKEN -ENUMX - BFD_RELOC_PPC_BA16 -ENUMX - BFD_RELOC_PPC_BA16_BRTAKEN -ENUMX - BFD_RELOC_PPC_BA16_BRNTAKEN -ENUMX - BFD_RELOC_PPC_COPY -ENUMX - BFD_RELOC_PPC_GLOB_DAT -ENUMX - BFD_RELOC_PPC_JMP_SLOT -ENUMX - BFD_RELOC_PPC_RELATIVE -ENUMX - BFD_RELOC_PPC_LOCAL24PC -ENUMX - BFD_RELOC_PPC_EMB_NADDR32 -ENUMX - BFD_RELOC_PPC_EMB_NADDR16 -ENUMX - BFD_RELOC_PPC_EMB_NADDR16_LO -ENUMX - BFD_RELOC_PPC_EMB_NADDR16_HI -ENUMX - BFD_RELOC_PPC_EMB_NADDR16_HA -ENUMX - BFD_RELOC_PPC_EMB_SDAI16 -ENUMX - BFD_RELOC_PPC_EMB_SDA2I16 -ENUMX - BFD_RELOC_PPC_EMB_SDA2REL -ENUMX - BFD_RELOC_PPC_EMB_SDA21 -ENUMX - BFD_RELOC_PPC_EMB_MRKREF -ENUMX - BFD_RELOC_PPC_EMB_RELSEC16 -ENUMX - BFD_RELOC_PPC_EMB_RELST_LO -ENUMX - BFD_RELOC_PPC_EMB_RELST_HI -ENUMX - BFD_RELOC_PPC_EMB_RELST_HA -ENUMX - BFD_RELOC_PPC_EMB_BIT_FLD -ENUMX - BFD_RELOC_PPC_EMB_RELSDA -ENUMDOC - Power(rs6000) and PowerPC relocations. - -ENUM - BFD_RELOC_CTOR -ENUMDOC - The type of reloc used to build a contructor table - at the moment - probably a 32 bit wide absolute relocation, but the target can choose. - It generally does map to one of the other relocation types. - -ENUM - BFD_RELOC_ARM_PCREL_BRANCH -ENUMDOC - ARM 26 bit pc-relative branch. The lowest two bits must be zero and are - not stored in the instruction. -ENUM - BFD_RELOC_ARM_IMMEDIATE -ENUMX - BFD_RELOC_ARM_OFFSET_IMM -ENUMX - BFD_RELOC_ARM_SHIFT_IMM -ENUMX - BFD_RELOC_ARM_SWI -ENUMX - BFD_RELOC_ARM_MULTI -ENUMX - BFD_RELOC_ARM_CP_OFF_IMM -ENUMX - BFD_RELOC_ARM_ADR_IMM -ENUMX - BFD_RELOC_ARM_LDR_IMM -ENUMX - BFD_RELOC_ARM_LITERAL -ENUMX - BFD_RELOC_ARM_IN_POOL -ENUMDOC - These relocs are only used within the ARM assembler. They are not - (at present) written to any object files. - -COMMENT -ENDSENUM - BFD_RELOC_UNUSED -CODE_FRAGMENT -. -.typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; -*/ - - -/* -FUNCTION - bfd_reloc_type_lookup - -SYNOPSIS - reloc_howto_type * - bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code); - -DESCRIPTION - Return a pointer to a howto structure which, when - invoked, will perform the relocation @var{code} on data from the - architecture noted. - -*/ - - -reloc_howto_type * -bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - return BFD_SEND (abfd, reloc_type_lookup, (abfd, code)); -} - -static reloc_howto_type bfd_howto_32 = -HOWTO (0, 00, 2, 32, false, 0, complain_overflow_bitfield, 0, "VRT32", false, 0xffffffff, 0xffffffff, true); - - -/* -INTERNAL_FUNCTION - bfd_default_reloc_type_lookup - -SYNOPSIS - reloc_howto_type *bfd_default_reloc_type_lookup - (bfd *abfd, bfd_reloc_code_real_type code); - -DESCRIPTION - Provides a default relocation lookup routine for any architecture. - - -*/ - -reloc_howto_type * -bfd_default_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_CTOR: - /* The type of reloc used in a ctor, which will be as wide as the - address - so either a 64, 32, or 16 bitter. */ - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 64: - BFD_FAIL (); - case 32: - return &bfd_howto_32; - case 16: - BFD_FAIL (); - default: - BFD_FAIL (); - } - default: - BFD_FAIL (); - } - return (reloc_howto_type *) NULL; -} - -/* -FUNCTION - bfd_get_reloc_code_name - -SYNOPSIS - const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); - -DESCRIPTION - Provides a printable name for the supplied relocation code. - Useful mainly for printing error messages. -*/ - -const char * -bfd_get_reloc_code_name (code) - bfd_reloc_code_real_type code; -{ - if (code > BFD_RELOC_UNUSED) - return 0; - return bfd_reloc_code_real_names[(int)code]; -} - -/* -INTERNAL_FUNCTION - bfd_generic_relax_section - -SYNOPSIS - boolean bfd_generic_relax_section - (bfd *abfd, - asection *section, - struct bfd_link_info *, - boolean *); - -DESCRIPTION - Provides default handling for relaxing for back ends which - don't do relaxing -- i.e., does nothing. -*/ - -/*ARGSUSED*/ -boolean -bfd_generic_relax_section (abfd, section, link_info, again) - bfd *abfd; - asection *section; - struct bfd_link_info *link_info; - boolean *again; -{ - *again = false; - return true; -} - -/* -INTERNAL_FUNCTION - bfd_generic_get_relocated_section_contents - -SYNOPSIS - bfd_byte * - bfd_generic_get_relocated_section_contents (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - boolean relocateable, - asymbol **symbols); - -DESCRIPTION - Provides default handling of relocation effort for back ends - which can't be bothered to do it efficiently. - -*/ - -bfd_byte * -bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data, - relocateable, symbols) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - if (reloc_size < 0) - goto error_return; - - reloc_vector = (arelent **) bfd_malloc ((size_t) reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - /* read in the section */ - if (!bfd_get_section_contents (input_bfd, - input_section, - (PTR) data, - 0, - input_section->_raw_size)) - goto error_return; - - /* We're not relaxing the section, so just copy the size info */ - input_section->_cooked_size = input_section->_raw_size; - input_section->reloc_done = true; - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - goto error_return; - - if (reloc_count > 0) - { - arelent **parent; - for (parent = reloc_vector; *parent != (arelent *) NULL; - parent++) - { - char *error_message = (char *) NULL; - bfd_reloc_status_type r = - bfd_perform_relocation (input_bfd, - *parent, - (PTR) data, - input_section, - relocateable ? abfd : (bfd *) NULL, - &error_message); - - if (relocateable) - { - asection *os = input_section->output_section; - - /* A partial link, so keep the relocs */ - os->orelocation[os->reloc_count] = *parent; - os->reloc_count++; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - case bfd_reloc_undefined: - if (!((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_dangerous: - BFD_ASSERT (error_message != (char *) NULL); - if (!((*link_info->callbacks->reloc_dangerous) - (link_info, error_message, input_bfd, input_section, - (*parent)->address))) - goto error_return; - break; - case bfd_reloc_overflow: - if (!((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - (*parent)->howto->name, (*parent)->addend, - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_outofrange: - default: - abort (); - break; - } - - } - } - } - if (reloc_vector != NULL) - free (reloc_vector); - return data; - -error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} diff --git a/contrib/gdb/bfd/reloc16.c b/contrib/gdb/bfd/reloc16.c deleted file mode 100644 index e88d50fb903..00000000000 --- a/contrib/gdb/bfd/reloc16.c +++ /dev/null @@ -1,289 +0,0 @@ -/* 8 and 16 bit COFF relocation functions, for BFD. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -Most of this hacked by Steve Chamberlain, - sac@cygnus.com -*/ - -/* These routines are used by coff-h8300 and coff-z8k to do - relocation. - - FIXME: This code should be rewritten to support the new COFF - linker. Basically, they need to deal with COFF relocs rather than - BFD generic relocs. They should store the relocs in some location - where coff_link_input_bfd can find them (and coff_link_input_bfd - should be changed to use this location rather than rereading the - file) (unless info->keep_memory is false, in which case they should - free up the relocs after dealing with them). */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "coff/internal.h" -#include "libcoff.h" - -bfd_vma -bfd_coff_reloc16_get_value (reloc, link_info, input_section) - arelent *reloc; - struct bfd_link_info *link_info; - asection *input_section; -{ - bfd_vma value; - asymbol *symbol = *(reloc->sym_ptr_ptr); - /* A symbol holds a pointer to a section, and an offset from the - base of the section. To relocate, we find where the section will - live in the output and add that in */ - - if (bfd_is_und_section (symbol->section)) - { - struct bfd_link_hash_entry *h; - - /* The symbol is undefined in this BFD. Look it up in the - global linker hash table. FIXME: This should be changed when - we convert this stuff to use a specific final_link function - and change the interface to bfd_relax_section to not require - the generic symbols. */ - h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, - bfd_asymbol_name (symbol), - false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) - value = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - else if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_common) - value = h->u.c.size; - else - { - if (! ((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (symbol), - input_section->owner, input_section, reloc->address))) - abort (); - value = 0; - } - } - else - { - value = symbol->value + - symbol->section->output_offset + - symbol->section->output_section->vma; - } - - /* Add the value contained in the relocation */ - value += reloc->addend; - - return value; -} - -void -bfd_perform_slip(abfd, slip, input_section, value) - bfd *abfd; - unsigned int slip; - asection *input_section; - bfd_vma value; -{ - asymbol **s; - - s = _bfd_generic_link_get_symbols (abfd); - BFD_ASSERT (s != (asymbol **) NULL); - - /* Find all symbols past this point, and make them know - what's happened */ - while (*s) - { - asymbol *p = *s; - if (p->section == input_section) - { - /* This was pointing into this section, so mangle it */ - if (p->value > value) - { - p->value -= slip; - if (p->udata.p != NULL) - { - struct generic_link_hash_entry *h; - - h = (struct generic_link_hash_entry *) p->udata.p; - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak); - h->root.u.def.value -= slip; - BFD_ASSERT (h->root.u.def.value == p->value); - } - } - } - s++; - } -} - -boolean -bfd_coff_reloc16_relax_section (abfd, i, link_info, again) - bfd *abfd; - asection *i; - struct bfd_link_info *link_info; - boolean *again; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = i->owner; - asection *input_section = i; - int shrink = 0 ; - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - /* We only run this relaxation once. It might work to run it more - often, but it hasn't been tested. */ - *again = false; - - if (reloc_size < 0) - return false; - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (!reloc_vector && reloc_size > 0) - return false; - - /* Get the relocs and think about them */ - reloc_count = - bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, - _bfd_generic_link_get_symbols (input_bfd)); - if (reloc_count < 0) - { - free (reloc_vector); - return false; - } - - if (reloc_count > 0) - { - arelent **parent; - for (parent = reloc_vector; *parent; parent++) - { - shrink = bfd_coff_reloc16_estimate (abfd, input_section, - *parent, shrink, link_info); - } - } - - input_section->_cooked_size -= shrink; - free((char *)reloc_vector); - return true; -} - -bfd_byte * -bfd_coff_reloc16_get_relocated_section_contents(in_abfd, - link_info, - link_order, - data, - relocateable, - symbols) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector; - long reloc_count; - - if (reloc_size < 0) - return NULL; - - /* If producing relocateable output, don't bother to relax. */ - if (relocateable) - return bfd_generic_get_relocated_section_contents (in_abfd, link_info, - link_order, - data, relocateable, - symbols); - - /* read in the section */ - if (! bfd_get_section_contents(input_bfd, - input_section, - data, - 0, - input_section->_raw_size)) - return NULL; - - - reloc_vector = (arelent **) bfd_malloc((size_t) reloc_size); - if (!reloc_vector && reloc_size != 0) - return NULL; - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - { - free (reloc_vector); - return NULL; - } - - if (reloc_count > 0) - { - arelent **parent = reloc_vector; - arelent *reloc ; - unsigned int dst_address = 0; - unsigned int src_address = 0; - unsigned int run; - unsigned int idx; - - /* Find how long a run we can do */ - while (dst_address < link_order->size) - { - reloc = *parent; - if (reloc) - { - /* Note that the relaxing didn't tie up the addresses in the - relocation, so we use the original address to work out the - run of non-relocated data */ - run = reloc->address - src_address; - parent++; - } - else - { - run = link_order->size - dst_address; - } - /* Copy the bytes */ - for (idx = 0; idx < run; idx++) - { - data[dst_address++] = data[src_address++]; - } - - /* Now do the relocation */ - - if (reloc) - { - bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order, - reloc, data, &src_address, - &dst_address); - } - } - } - free((char *)reloc_vector); - return data; -} - diff --git a/contrib/gdb/bfd/riscix.c b/contrib/gdb/bfd/riscix.c deleted file mode 100644 index 21a86d5e102..00000000000 --- a/contrib/gdb/bfd/riscix.c +++ /dev/null @@ -1,644 +0,0 @@ -/* BFD back-end for RISC iX (Acorn, arm) binaries. - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. - Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* RISC iX overloads the MAGIC field to indicate more than just the usual - [ZNO]MAGIC values. Also included are squeezing information and - shared library usage. */ - -/* The following come from the man page. */ -#define SHLIBLEN 60 - -#define MF_IMPURE 00200 -#define MF_SQUEEZED 01000 -#define MF_USES_SL 02000 -#define MF_IS_SL 04000 - -/* Common combinations. */ -#define IMAGIC (MF_IMPURE|ZMAGIC) /* Demand load (impure text) */ -#define SPOMAGIC (MF_USES_SL|OMAGIC) /* OMAGIC with large header */ - /* -- may contain a ref to a */ - /* shared lib required by the */ - /* object. */ -#define SLOMAGIC (MF_IS_SL|OMAGIC) /* A reference to a shared library */ - /* The text portion of the object */ - /* contains "overflow text" from */ - /* the shared library to be linked */ - /* in with an object */ -#define QMAGIC (MF_SQUEEZED|ZMAGIC) /* Sqeezed demand paged. */ - /* NOTE: This interpretation of */ - /* QMAGIC seems to be at variance */ - /* With that used on other */ - /* architectures. */ -#define SPZMAGIC (MF_USES_SL|ZMAGIC) /* program which uses sl */ -#define SPQMAGIC (MF_USES_SL|QMAGIC) /* sqeezed ditto */ -#define SLZMAGIC (MF_IS_SL|ZMAGIC) /* shared lib part of prog */ -#define SLPZMAGIC (MF_USES_SL|SLZMAGIC) /* sl which uses another */ - -#define N_SHARED_LIB(x) ((x).a_info & MF_USES_SL) - -/* Only a pure OMAGIC file has the minimal header */ -#define N_TXTOFF(x) \ - ((x).a_info == OMAGIC ? 32 \ - : (N_MAGIC(x) == ZMAGIC) ? TARGET_PAGE_SIZE \ - : 999) - -#define N_TXTADDR(x) \ - (N_MAGIC(x) != ZMAGIC ? 0 /* object file or NMAGIC */ \ - /* Programs with shared libs are loaded at the first page after all the \ - text segments of the shared library programs. Without looking this \ - up we can't know exactly what the address will be. A reasonable guess \ - is that a_entry will be in the first page of the executable. */ \ - : N_SHARED_LIB(x) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) \ - : TEXT_START_ADDR) - -#define N_SYMOFF(x) \ - (N_TXTOFF (x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize) - -#define N_STROFF(x) (N_SYMOFF (x) + (x).a_syms) - -#define TEXT_START_ADDR 32768 -#define TARGET_PAGE_SIZE 32768 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_arm - -#define MY(OP) CAT(riscix_,OP) -#define TARGETNAME "a.out-riscix" -#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \ - (((x).a_info & ~006000) != OMAGIC) && \ - ((x).a_info != NMAGIC)) -#define N_MAGIC(x) ((x).a_info & ~07200) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "assert.h" - -#define WRITE_HEADERS(abfd, execp) \ - { \ - bfd_size_type text_size; /* dummy vars */ \ - file_ptr text_end; \ - if (adata(abfd).magic == undecided_magic) \ - NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ - \ - execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ - execp->a_entry = bfd_get_start_address (abfd); \ - \ - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ - \ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \ - if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \ - != EXEC_BYTES_SIZE) \ - return false; \ - /* Now write out reloc info, followed by syms and strings */ \ - \ - if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \ - && bfd_get_symcount (abfd) != 0) \ - { \ - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) != 0) \ - return false; \ - \ - if (! NAME(aout,write_syms)(abfd)) return false; \ - \ - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) != 0) \ - return false; \ - \ - if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd))) \ - return false; \ - if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) != 0) \ - return false; \ - \ - if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) \ - return false; \ - } \ - } - -#include "libaout.h" -#include "aout/aout64.h" - -static bfd_reloc_status_type -riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static reloc_howto_type riscix_std_reloc_howto[] = { - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ - HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false), - HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false), - HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false), - HOWTO( 3, 2, 3, 26, true, 0, complain_overflow_signed, riscix_fix_pcrel_26 , "ARM26", true, 0x00ffffff,0x00ffffff, false), - HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, true), - HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, true), - HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, true), - HOWTO( 7, 2, 3, 26, false, 0, complain_overflow_signed, riscix_fix_pcrel_26_done, "ARM26D",true,0x00ffffff,0x00ffffff, false), - {-1}, - HOWTO( 9, 0, -1, 16, false, 0, complain_overflow_bitfield,0,"NEG16", true, 0x0000ffff,0x0000ffff, false), - HOWTO( 10, 0, -2, 32, false, 0, complain_overflow_bitfield,0,"NEG32", true, 0xffffffff,0xffffffff, false) -}; - -#define RISCIX_TABLE_SIZE \ - (sizeof (riscix_std_reloc_howto) / sizeof (reloc_howto_type)) - - -static bfd_reloc_status_type -riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* This is dead simple at present. */ - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -riscix_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_size_type addr = reloc_entry->address; - long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); - bfd_reloc_status_type flag = bfd_reloc_ok; - - /* If this is an undefined symbol, return error */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0) - return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; - - /* If the sections are different, and we are doing a partial relocation, - just ignore it for now. */ - if (symbol->section->name != input_section->name - && output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - relocation = (target & 0x00ffffff) << 2; - relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ - relocation += symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - relocation -= input_section->output_section->vma; - relocation -= input_section->output_offset; - relocation -= addr; - if (relocation & 3) - return bfd_reloc_overflow; - - /* Check for overflow */ - if (relocation & 0x02000000) - { - if ((relocation & ~0x03ffffff) != ~0x03ffffff) - flag = bfd_reloc_overflow; - } - else if (relocation & ~0x03ffffff) - flag = bfd_reloc_overflow; - - target &= ~0x00ffffff; - target |= (relocation >> 2) & 0x00ffffff; - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); - - /* Now the ARM magic... Change the reloc type so that it is marked as done. - Strictly this is only necessary if we are doing a partial relocation. */ - reloc_entry->howto = &riscix_std_reloc_howto[7]; - - return flag; -} - -reloc_howto_type * -DEFUN(riscix_reloc_type_lookup,(abfd,code), - bfd *abfd AND - bfd_reloc_code_real_type code) -{ -#define ASTD(i,j) case i: return &riscix_std_reloc_howto[j] - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - default: return (reloc_howto_type *) NULL; - } - - switch (code) - { - ASTD (BFD_RELOC_16, 1); - ASTD (BFD_RELOC_32, 2); - ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); - ASTD (BFD_RELOC_8_PCREL, 4); - ASTD (BFD_RELOC_16_PCREL, 5); - ASTD (BFD_RELOC_32_PCREL, 6); - default: return (reloc_howto_type *) NULL; - } -} - -#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define MY_bfd_final_link _bfd_generic_final_link - -#define MY_bfd_reloc_type_lookup riscix_reloc_type_lookup -#define MY_canonicalize_reloc riscix_canonicalize_reloc -#define MY_object_p riscix_object_p - -static const bfd_target *riscix_callback PARAMS ((bfd *)); - -void -riscix_swap_std_reloc_out (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - int r_length; - int r_pcrel; - int r_neg = 0; /* Negative relocs use the BASEREL bit. */ - asection *output_section = sym->section->output_section; - - PUT_WORD(abfd, g->address, natptr->r_address); - - r_length = g->howto->size ; /* Size as a power of two */ - if (r_length < 0) - { - r_length = -r_length; - r_neg = 1; - } - - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - - /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the - relocation has been done already (Only for the 26-bit one I think)???!!! - */ - - if (r_length == 3) - r_pcrel = r_pcrel ? 0 : 1; - - -#if 0 - /* For a standard reloc, the addend is in the object file. */ - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; -#endif - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - if (bfd_is_com_section (output_section) - || output_section == &bfd_abs_section - || output_section == &bfd_und_section) - { - if (bfd_abs_section.symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = stoi((*(g->sym_ptr_ptr))->flags); - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0) - | (r_neg ? RELOC_STD_BITS_BASEREL_BIG: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_neg ? RELOC_STD_BITS_BASEREL_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } -} - -boolean -riscix_squirt_out_relocs (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - unsigned char *native, *natptr; - size_t each_size; - - unsigned int count = section->reloc_count; - size_t natsize; - - if (count == 0) return true; - - each_size = obj_reloc_entry_size (abfd); - natsize = each_size * count; - native = (unsigned char *) bfd_zalloc (abfd, natsize); - if (!native) - return false; - - generic = section->orelocation; - - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - riscix_swap_std_reloc_out (abfd, *generic, - (struct reloc_std_external *) natptr); - - if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) - { - bfd_release(abfd, native); - return false; - } - - bfd_release (abfd, native); - return true; -} - - -/* - * This is just like the standard aoutx.h version but we need to do our - * own mapping of external reloc type values to howto entries. - */ -long -MY(canonicalize_reloc)(abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count, c; - extern reloc_howto_type NAME(aout,std_howto_table)[]; - - /* If we have already read in the relocation table, return the values. */ - if (section->flags & SEC_CONSTRUCTOR) { - arelent_chain *chain = section->constructor_chain; - - for (count = 0; count < section->reloc_count; count++) { - *relptr++ = &chain->relent; - chain = chain->next; - } - *relptr = 0; - return section->reloc_count; - } - if (tblptr && section->reloc_count) { - for (count = 0; count++ < section->reloc_count;) - *relptr++ = tblptr++; - *relptr = 0; - return section->reloc_count; - } - - if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols)) - return -1; - tblptr = section->relocation; - - /* fix up howto entries */ - for (count = 0; count++ < section->reloc_count;) - { - c = tblptr->howto - NAME(aout,std_howto_table); - assert (c < RISCIX_TABLE_SIZE); - tblptr->howto = &riscix_std_reloc_howto[c]; - - *relptr++ = tblptr++; - } - *relptr = 0; - return section->reloc_count; -} - -/* This is the same as NAME(aout,some_aout_object_p), but has different - expansions of the macro definitions. */ - -const bfd_target * -riscix_some_aout_object_p (abfd, execp, callback_to_real_object_p) - bfd *abfd; - struct internal_exec *execp; - const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)); -{ - struct aout_data_struct *rawptr, *oldrawptr; - const bfd_target *result; - - rawptr = ((struct aout_data_struct *) - bfd_zalloc (abfd, sizeof (struct aout_data_struct ))); - - if (rawptr == NULL) - return 0; - - oldrawptr = abfd->tdata.aout_data; - abfd->tdata.aout_data = rawptr; - - /* Copy the contents of the old tdata struct. - In particular, we want the subformat, since for hpux it was set in - hp300hpux.c:swap_exec_header_in and will be used in - hp300hpux.c:callback. */ - if (oldrawptr != NULL) - *abfd->tdata.aout_data = *oldrawptr; - - abfd->tdata.aout_data->a.hdr = &rawptr->e; - *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec - struct */ - execp = abfd->tdata.aout_data->a.hdr; - - /* Set the file flags */ - abfd->flags = NO_FLAGS; - if (execp->a_drsize || execp->a_trsize) - abfd->flags |= HAS_RELOC; - /* Setting of EXEC_P has been deferred to the bottom of this function */ - if (execp->a_syms) - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - if (N_DYNAMIC(*execp)) - abfd->flags |= DYNAMIC; - - - if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported - (yet)! */ - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - else if ((execp->a_info & MF_IS_SL) != 0) /* Nor are shared libraries */ - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - else if (N_MAGIC (*execp) == ZMAGIC) - { - abfd->flags |= D_PAGED | WP_TEXT; - adata (abfd).magic = z_magic; - } - else if (N_MAGIC (*execp) == NMAGIC) - { - abfd->flags |= WP_TEXT; - adata (abfd).magic = n_magic; - } - else if (N_MAGIC (*execp) == OMAGIC) - adata (abfd).magic = o_magic; - else - { - /* Should have been checked with N_BADMAG before this routine - was called. */ - abort (); - } - - bfd_get_start_address (abfd) = execp->a_entry; - - obj_aout_symbols (abfd) = (aout_symbol_type *)NULL; - bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist); - - /* The default relocation entry size is that of traditional V7 Unix. */ - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - /* The default symbol entry size is that of traditional Unix. */ - obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE; - - obj_aout_external_syms (abfd) = NULL; - obj_aout_external_strings (abfd) = NULL; - obj_aout_sym_hashes (abfd) = NULL; - - if (! NAME(aout,make_sections) (abfd)) - return NULL; - - obj_datasec (abfd)->_raw_size = execp->a_data; - obj_bsssec (abfd)->_raw_size = execp->a_bss; - - obj_textsec (abfd)->flags = - (execp->a_trsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)); - obj_datasec (abfd)->flags = - (execp->a_drsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)); - obj_bsssec (abfd)->flags = SEC_ALLOC; - - result = (*callback_to_real_object_p)(abfd); - -#if defined(MACH) || defined(STAT_FOR_EXEC) - /* The original heuristic doesn't work in some important cases. The - * a.out file has no information about the text start address. For - * files (like kernels) linked to non-standard addresses (ld -Ttext - * nnn) the entry point may not be between the default text start - * (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size - * This is not just a mach issue. Many kernels are loaded at non - * standard addresses. - */ - { - struct stat stat_buf; - if (abfd->iostream != NULL - && (abfd->flags & BFD_IN_MEMORY) == 0 - && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0) - && ((stat_buf.st_mode & 0111) != 0)) - abfd->flags |= EXEC_P; - } -#else /* ! MACH */ - /* Now that the segment addresses have been worked out, take a better - guess at whether the file is executable. If the entry point - is within the text segment, assume it is. (This makes files - executable even if their entry point address is 0, as long as - their text starts at zero.) - - At some point we should probably break down and stat the file and - declare it executable if (one of) its 'x' bits are on... */ - if ((execp->a_entry >= obj_textsec(abfd)->vma) && - (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size)) - abfd->flags |= EXEC_P; -#endif /* MACH */ - if (result) - { - } - else - { - free (rawptr); - abfd->tdata.aout_data = oldrawptr; - } - return result; -} - - -static const bfd_target * -MY(object_p) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; /* Raw exec header from file */ - struct internal_exec exec; /* Cleaned-up exec header */ - const bfd_target *target; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info); - - if (N_BADMAG (exec)) return 0; -#ifdef MACHTYPE_OK - if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0; -#endif - - NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec); - - target = riscix_some_aout_object_p (abfd, &exec, MY(callback)); - - return target; -} - - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/rs6000-core.c b/contrib/gdb/bfd/rs6000-core.c deleted file mode 100644 index 4889f72f6dd..00000000000 --- a/contrib/gdb/bfd/rs6000-core.c +++ /dev/null @@ -1,396 +0,0 @@ -/* IBM RS/6000 "XCOFF" back-end for BFD. - Copyright (C) 1990, 1991, 1995 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, - and John Gilmore. - Archive support from Damon A. Permezel. - Contributed by IBM Corporation and Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This port currently only handles reading object files, except when - compiled on an RS/6000 host. -- no archive support, no core files. - In all cases, it does not support writing. - - FIXMEmgo comments are left from Metin Ozisik's original port. - - This is in a separate file from coff-rs6000.c, because it includes - system include files that conflict with coff/rs6000.h. - */ - -/* Internalcoff.h and coffcode.h modify themselves based on this flag. */ -#define RS6000COFF_C 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifdef AIX_CORE - -/* AOUTHDR is defined by the above. We need another defn of it, from the - system include files. Punt the old one and get us a new name for the - typedef in the system include files. */ -#ifdef AOUTHDR -#undef AOUTHDR -#endif -#define AOUTHDR second_AOUTHDR - -#undef SCNHDR - - -/* ------------------------------------------------------------------------ */ -/* Support for core file stuff.. */ -/* ------------------------------------------------------------------------ */ - -#include -#include -#include - - -/* Number of special purpose registers supported by gdb. This value - should match `tm.h' in gdb directory. Clean this mess up and use - the macros in sys/reg.h. FIXMEmgo. */ - -#define NUM_OF_SPEC_REGS 7 - -#define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr) -#define core_datasec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->data_section) -#define core_stacksec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->stack_section) -#define core_regsec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg_section) -#define core_reg2sec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg2_section) - -/* AIX 4.1 Changed the names and locations of a few items in the core file, - this seems to be the quickest easiet way to deal with it. - - Note however that encoding magic addresses (STACK_END_ADDR) is going - to be _very_ fragile. But I don't see any easy way to get that info - right now. */ -#ifdef CORE_VERSION_1 -#define CORE_DATA_SIZE_FIELD c_u.U_dsize -#define CORE_COMM_FIELD c_u.U_comm -#define SAVE_FIELD c_mst -#define STACK_END_ADDR 0x2ff23000 -#else -#define CORE_DATA_SIZE_FIELD c_u.u_dsize -#define CORE_COMM_FIELD c_u.u_comm -#define SAVE_FIELD c_u.u_save -#define STACK_END_ADDR 0x2ff80000 -#endif - -/* These are stored in the bfd's tdata */ -typedef struct { - struct core_dump hdr; /* core file header */ - asection *data_section, - *stack_section, - *reg_section, /* section for GPRs and special registers. */ - *reg2_section; /* section for FPRs. */ - - /* This tells us where everything is mapped (shared libraries and so on). - GDB needs it. */ - asection *ldinfo_section; -#define core_ldinfosec(bfd) (((Rs6kCorData *)(bfd->tdata.any))->ldinfo_section) -} Rs6kCorData; - - -/* Decide if a given bfd represents a `core' file or not. There really is no - magic number or anything like, in rs6000coff. */ - -const bfd_target * -rs6000coff_core_p (abfd) - bfd *abfd; -{ - int fd; - struct core_dump coredata; - struct stat statbuf; - char *tmpptr; - - /* Use bfd_xxx routines, rather than O/S primitives to read coredata. FIXMEmgo */ - fd = open (abfd->filename, O_RDONLY); - if (fd < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - if (fstat (fd, &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - close (fd); - return NULL; - } - if (read (fd, &coredata, sizeof (struct core_dump)) - != sizeof (struct core_dump)) - { - bfd_set_error (bfd_error_wrong_format); - close (fd); - return NULL; - } - - if (close (fd) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - /* If the core file ulimit is too small, the system will first - omit the data segment, then omit the stack, then decline to - dump core altogether (as far as I know UBLOCK_VALID and LE_VALID - are always set) (this is based on experimentation on AIX 3.2). - Now, the thing is that GDB users will be surprised - if segments just silently don't appear (well, maybe they would - think to check "info files", I don't know), but we have no way of - returning warnings (as opposed to errors). - - For the data segment, we have no choice but to keep going if it's - not there, since the default behavior is not to dump it (regardless - of the ulimit, it's based on SA_FULLDUMP). But for the stack segment, - if it's not there, we refuse to have anything to do with this core - file. The usefulness of a core dump without a stack segment is pretty - limited anyway. */ - - if (!(coredata.c_flag & UBLOCK_VALID) - || !(coredata.c_flag & LE_VALID)) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if ((coredata.c_flag & CORE_TRUNC) - || !(coredata.c_flag & USTACK_VALID)) - { - bfd_set_error (bfd_error_file_truncated); - return NULL; - } - - /* Don't check the core file size for a full core, AIX 4.1 includes - additional shared library sections in a full core. */ - if (!(coredata.c_flag & FULL_CORE) - && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size) - { - /* If the size is wrong, it means we're misinterpreting something. */ - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Sanity check on the c_tab field. */ - if ((u_long) coredata.c_tab < sizeof coredata || - (u_long) coredata.c_tab >= statbuf.st_size || - (long) coredata.c_tab >= (long)coredata.c_stack) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* maybe you should alloc space for the whole core chunk over here!! FIXMEmgo */ - tmpptr = (char*)bfd_zalloc (abfd, sizeof (Rs6kCorData)); - if (!tmpptr) - return NULL; - - set_tdata (abfd, tmpptr); - - /* Copy core file header. */ - core_hdr (abfd) = coredata; - - /* .stack section. */ - if ((core_stacksec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_stacksec (abfd)->name = ".stack"; - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_stacksec (abfd)->_raw_size = coredata.c_size; - core_stacksec (abfd)->vma = STACK_END_ADDR - coredata.c_size; - core_stacksec (abfd)->filepos = (int)coredata.c_stack; /*???? */ - - /* .reg section for GPRs and special registers. */ - if ((core_regsec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_regsec (abfd)->name = ".reg"; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - core_regsec (abfd)->_raw_size = (32 + NUM_OF_SPEC_REGS) * 4; - core_regsec (abfd)->vma = 0; /* not used?? */ - core_regsec (abfd)->filepos = - (char*)&coredata.SAVE_FIELD - (char*)&coredata; - - /* .reg2 section for FPRs (floating point registers). */ - if ((core_reg2sec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_reg2sec (abfd)->name = ".reg2"; - core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; - core_reg2sec (abfd)->_raw_size = 8 * 32; /* 32 FPRs. */ - core_reg2sec (abfd)->vma = 0; /* not used?? */ - core_reg2sec (abfd)->filepos = - (char*)&coredata.SAVE_FIELD.fpr[0] - (char*)&coredata; - - if ((core_ldinfosec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_ldinfosec (abfd)->name = ".ldinfo"; - core_ldinfosec (abfd)->flags = SEC_HAS_CONTENTS; - /* To actually find out how long this section is in this particular - core dump would require going down the whole list of struct ld_info's. - See if we can just fake it. */ - core_ldinfosec (abfd)->_raw_size = 0x7fffffff; - /* Not relevant for ldinfo section. */ - core_ldinfosec (abfd)->vma = 0; - core_ldinfosec (abfd)->filepos = (file_ptr) coredata.c_tab; - - /* set up section chain here. */ - abfd->section_count = 4; - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_regsec(abfd); - core_regsec (abfd)->next = core_reg2sec (abfd); - core_reg2sec (abfd)->next = core_ldinfosec (abfd); - core_ldinfosec (abfd)->next = NULL; - - if (coredata.c_flag & FULL_CORE) - { - asection *sec = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (sec == NULL) - return NULL; - sec->name = ".data"; - sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; - sec->_raw_size = coredata.CORE_DATA_SIZE_FIELD; - sec->vma = CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD); - sec->filepos = (int)coredata.c_stack + coredata.c_size; - - sec->next = abfd->sections; - abfd->sections = sec; - ++abfd->section_count; - } - - return abfd->xvec; /* this is garbage for now. */ -} - - - -/* return `true' if given core is from the given executable.. */ -boolean -rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - FILE *fd; - struct core_dump coredata; - struct ld_info ldinfo; - char pathname [1024]; - const char *str1, *str2; - - /* Use bfd_xxx routines, rather than O/S primitives, do error checking!! - FIXMEmgo */ - /* Actually should be able to use bfd_get_section_contents now that - we have a .ldinfo section. */ - fd = fopen (core_bfd->filename, FOPEN_RB); - - fread (&coredata, sizeof (struct core_dump), 1, fd); - fseek (fd, (long)coredata.c_tab, 0); - fread (&ldinfo, (char*)&ldinfo.ldinfo_filename[0] - (char*)&ldinfo.ldinfo_next, - 1, fd); - fscanf (fd, "%s", pathname); - - str1 = strrchr (pathname, '/'); - str2 = strrchr (exec_bfd->filename, '/'); - - /* step over character '/' */ - str1 = str1 ? str1+1 : &pathname[0]; - str2 = str2 ? str2+1 : exec_bfd->filename; - - fclose (fd); - return strcmp (str1, str2) == 0; -} - -char * -rs6000coff_core_file_failing_command (abfd) - bfd *abfd; -{ - char *com = core_hdr (abfd).CORE_COMM_FIELD; - if (*com) - return com; - else - return 0; -} - -int -rs6000coff_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_hdr (abfd).c_signo; -} - - -boolean -rs6000coff_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - int count; -{ - if (count == 0) - return true; - - /* Reading a core file's sections will be slightly different. For the - rest of them we can use bfd_generic_get_section_contents () I suppose. */ - /* Make sure this routine works for any bfd and any section. FIXMEmgo. */ - - if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) { - - struct mstsave mstatus; - int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus; - - /* Assert that the only way this code will be executed is reading the - whole section. */ - if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS))) - (*_bfd_error_handler) - ("ERROR! in rs6000coff_get_section_contents()\n"); - - /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure - in the core file. */ - - /* read GPR's into the location. */ - if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1 - || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr)) - return (false); /* on error */ - - /* increment location to the beginning of special registers in the section, - reset register offset value to the beginning of first special register - in mstsave structure, and read special registers. */ - - location = (PTR) ((char*)location + sizeof (mstatus.gpr)); - regoffset = (char*)&mstatus.iar - (char*)&mstatus; - - if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1 - || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) != - 4 * NUM_OF_SPEC_REGS) - return (false); /* on error */ - - /* increment location address, and read the special registers.. */ - /* FIXMEmgo */ - return (true); - } - - /* else, use default bfd section content transfer. */ - else - return _bfd_generic_get_section_contents - (abfd, section, location, offset, count); -} - -#endif /* AIX_CORE */ diff --git a/contrib/gdb/bfd/section.c b/contrib/gdb/bfd/section.c deleted file mode 100644 index ac9a4491210..00000000000 --- a/contrib/gdb/bfd/section.c +++ /dev/null @@ -1,976 +0,0 @@ -/* Object file "section" support for the BFD library. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - Sections - - The raw data contained within a BFD is maintained through the - section abstraction. A single BFD may have any number of - sections. It keeps hold of them by pointing to the first; - each one points to the next in the list. - - Sections are supported in BFD in <>. - -@menu -@* Section Input:: -@* Section Output:: -@* typedef asection:: -@* section prototypes:: -@end menu - -INODE -Section Input, Section Output, Sections, Sections -SUBSECTION - Section input - - When a BFD is opened for reading, the section structures are - created and attached to the BFD. - - Each section has a name which describes the section in the - outside world---for example, <> would contain at least - three sections, called <<.text>>, <<.data>> and <<.bss>>. - - Names need not be unique; for example a COFF file may have several - sections named <<.data>>. - - Sometimes a BFD will contain more than the ``natural'' number of - sections. A back end may attach other sections containing - constructor data, or an application may add a section (using - <>) to the sections attached to an already open - BFD. For example, the linker creates an extra section - <> for each input file's BFD to hold information about - common storage. - - The raw data is not necessarily read in when - the section descriptor is created. Some targets may leave the - data in place until a <> call is - made. Other back ends may read in all the data at once. For - example, an S-record file has to be read once to determine the - size of the data. An IEEE-695 file doesn't contain raw data in - sections, but data and relocation expressions intermixed, so - the data area has to be parsed to get out the data and - relocations. - -INODE -Section Output, typedef asection, Section Input, Sections - -SUBSECTION - Section output - - To write a new object style BFD, the various sections to be - written have to be created. They are attached to the BFD in - the same way as input sections; data is written to the - sections using <>. - - Any program that creates or combines sections (e.g., the assembler - and linker) must use the <> fields <> and - <> to indicate the file sections to which each - section must be written. (If the section is being created from - scratch, <> should probably point to the section - itself and <> should probably be zero.) - - The data to be written comes from input sections attached - (via <> pointers) to - the output sections. The output section structure can be - considered a filter for the input section: the output section - determines the vma of the output data and the name, but the - input section determines the offset into the output section of - the data to be written. - - E.g., to create a section "O", starting at 0x100, 0x123 long, - containing two subsections, "A" at offset 0x0 (i.e., at vma - 0x100) and "B" at offset 0x20 (i.e., at vma 0x120) the <> - structures would look like: - -| section name "A" -| output_offset 0x00 -| size 0x20 -| output_section -----------> section name "O" -| | vma 0x100 -| section name "B" | size 0x123 -| output_offset 0x20 | -| size 0x103 | -| output_section --------| - - -SUBSECTION - Link orders - - The data within a section is stored in a @dfn{link_order}. - These are much like the fixups in <>. The link_order - abstraction allows a section to grow and shrink within itself. - - A link_order knows how big it is, and which is the next - link_order and where the raw data for it is; it also points to - a list of relocations which apply to it. - - The link_order is used by the linker to perform relaxing on - final code. The compiler creates code which is as big as - necessary to make it work without relaxing, and the user can - select whether to relax. Sometimes relaxing takes a lot of - time. The linker runs around the relocations to see if any - are attached to data which can be shrunk, if so it does it on - a link_order by link_order basis. - -*/ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -/* -DOCDD -INODE -typedef asection, section prototypes, Section Output, Sections -SUBSECTION - typedef asection - - Here is the section structure: - -CODE_FRAGMENT -. -.typedef struct sec -.{ -. {* The name of the section; the name isn't a copy, the pointer is -. the same as that passed to bfd_make_section. *} -. -. CONST char *name; -. -. {* Which section is it; 0..nth. *} -. -. int index; -. -. {* The next section in the list belonging to the BFD, or NULL. *} -. -. struct sec *next; -. -. {* The field flags contains attributes of the section. Some -. flags are read in from the object file, and some are -. synthesized from other information. *} -. -. flagword flags; -. -.#define SEC_NO_FLAGS 0x000 -. -. {* Tells the OS to allocate space for this section when loading. -. This is clear for a section containing debug information -. only. *} -.#define SEC_ALLOC 0x001 -. -. {* Tells the OS to load the section from the file when loading. -. This is clear for a .bss section. *} -.#define SEC_LOAD 0x002 -. -. {* The section contains data still to be relocated, so there is -. some relocation information too. *} -.#define SEC_RELOC 0x004 -. -.#if 0 {* Obsolete ? *} -.#define SEC_BALIGN 0x008 -.#endif -. -. {* A signal to the OS that the section contains read only -. data. *} -.#define SEC_READONLY 0x010 -. -. {* The section contains code only. *} -.#define SEC_CODE 0x020 -. -. {* The section contains data only. *} -.#define SEC_DATA 0x040 -. -. {* The section will reside in ROM. *} -.#define SEC_ROM 0x080 -. -. {* The section contains constructor information. This section -. type is used by the linker to create lists of constructors and -. destructors used by <>. When a back end sees a symbol -. which should be used in a constructor list, it creates a new -. section for the type of name (e.g., <<__CTOR_LIST__>>), attaches -. the symbol to it, and builds a relocation. To build the lists -. of constructors, all the linker has to do is catenate all the -. sections called <<__CTOR_LIST__>> and relocate the data -. contained within - exactly the operations it would peform on -. standard data. *} -.#define SEC_CONSTRUCTOR 0x100 -. -. {* The section is a constuctor, and should be placed at the -. end of the text, data, or bss section(?). *} -.#define SEC_CONSTRUCTOR_TEXT 0x1100 -.#define SEC_CONSTRUCTOR_DATA 0x2100 -.#define SEC_CONSTRUCTOR_BSS 0x3100 -. -. {* The section has contents - a data section could be -. <> | <>; a debug section could be -. <> *} -.#define SEC_HAS_CONTENTS 0x200 -. -. {* An instruction to the linker to not output the section -. even if it has information which would normally be written. *} -.#define SEC_NEVER_LOAD 0x400 -. -. {* The section is a COFF shared library section. This flag is -. only for the linker. If this type of section appears in -. the input file, the linker must copy it to the output file -. without changing the vma or size. FIXME: Although this -. was originally intended to be general, it really is COFF -. specific (and the flag was renamed to indicate this). It -. might be cleaner to have some more general mechanism to -. allow the back end to control what the linker does with -. sections. *} -.#define SEC_COFF_SHARED_LIBRARY 0x800 -. -. {* The section is a common section (symbols may be defined -. multiple times, the value of a symbol is the amount of -. space it requires, and the largest symbol value is the one -. used). Most targets have exactly one of these (which we -. translate to bfd_com_section_ptr), but ECOFF has two. *} -.#define SEC_IS_COMMON 0x8000 -. -. {* The section contains only debugging information. For -. example, this is set for ELF .debug and .stab sections. -. strip tests this flag to see if a section can be -. discarded. *} -.#define SEC_DEBUGGING 0x10000 -. -. {* The contents of this section are held in memory pointed to -. by the contents field. This is checked by -. bfd_get_section_contents, and the data is retrieved from -. memory if appropriate. *} -.#define SEC_IN_MEMORY 0x20000 -. -. {* The contents of this section are to be excluded by the -. linker for executable and shared objects unless those -. objects are to be further relocated. *} -.#define SEC_EXCLUDE 0x40000 -. -. {* The contents of this section are to be sorted by the -. based on the address specified in the associated symbol -. table. *} -.#define SEC_SORT_ENTRIES 0x80000 -. -. {* End of section flags. *} -. -. {* The virtual memory address of the section - where it will be -. at run time. The symbols are relocated against this. The -. user_set_vma flag is maintained by bfd; if it's not set, the -. backend can assign addresses (for example, in <>, where -. the default address for <<.data>> is dependent on the specific -. target and various flags). *} -. -. bfd_vma vma; -. boolean user_set_vma; -. -. {* The load address of the section - where it would be in a -. rom image; really only used for writing section header -. information. *} -. -. bfd_vma lma; -. -. {* The size of the section in bytes, as it will be output. -. contains a value even if the section has no contents (e.g., the -. size of <<.bss>>). This will be filled in after relocation *} -. -. bfd_size_type _cooked_size; -. -. {* The original size on disk of the section, in bytes. Normally this -. value is the same as the size, but if some relaxing has -. been done, then this value will be bigger. *} -. -. bfd_size_type _raw_size; -. -. {* If this section is going to be output, then this value is the -. offset into the output section of the first byte in the input -. section. E.g., if this was going to start at the 100th byte in -. the output section, this value would be 100. *} -. -. bfd_vma output_offset; -. -. {* The output section through which to map on output. *} -. -. struct sec *output_section; -. -. {* The alignment requirement of the section, as an exponent of 2 - -. e.g., 3 aligns to 2^3 (or 8). *} -. -. unsigned int alignment_power; -. -. {* If an input section, a pointer to a vector of relocation -. records for the data in this section. *} -. -. struct reloc_cache_entry *relocation; -. -. {* If an output section, a pointer to a vector of pointers to -. relocation records for the data in this section. *} -. -. struct reloc_cache_entry **orelocation; -. -. {* The number of relocation records in one of the above *} -. -. unsigned reloc_count; -. -. {* Information below is back end specific - and not always used -. or updated. *} -. -. {* File position of section data *} -. -. file_ptr filepos; -. -. {* File position of relocation info *} -. -. file_ptr rel_filepos; -. -. {* File position of line data *} -. -. file_ptr line_filepos; -. -. {* Pointer to data for applications *} -. -. PTR userdata; -. -. {* If the SEC_IN_MEMORY flag is set, this points to the actual -. contents. *} -. unsigned char *contents; -. -. {* Attached line number information *} -. -. alent *lineno; -. -. {* Number of line number records *} -. -. unsigned int lineno_count; -. -. {* When a section is being output, this value changes as more -. linenumbers are written out *} -. -. file_ptr moving_line_filepos; -. -. {* What the section number is in the target world *} -. -. int target_index; -. -. PTR used_by_bfd; -. -. {* If this is a constructor section then here is a list of the -. relocations created to relocate items within it. *} -. -. struct relent_chain *constructor_chain; -. -. {* The BFD which owns the section. *} -. -. bfd *owner; -. -. boolean reloc_done; -. {* A symbol which points at this section only *} -. struct symbol_cache_entry *symbol; -. struct symbol_cache_entry **symbol_ptr_ptr; -. -. struct bfd_link_order *link_order_head; -. struct bfd_link_order *link_order_tail; -.} asection ; -. -. {* These sections are global, and are managed by BFD. The application -. and target back end are not permitted to change the values in -. these sections. New code should use the section_ptr macros rather -. than referring directly to the const sections. The const sections -. may eventually vanish. *} -.#define BFD_ABS_SECTION_NAME "*ABS*" -.#define BFD_UND_SECTION_NAME "*UND*" -.#define BFD_COM_SECTION_NAME "*COM*" -.#define BFD_IND_SECTION_NAME "*IND*" -. -. {* the absolute section *} -.extern const asection bfd_abs_section; -.#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) -.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) -. {* Pointer to the undefined section *} -.extern const asection bfd_und_section; -.#define bfd_und_section_ptr ((asection *) &bfd_und_section) -.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) -. {* Pointer to the common section *} -.extern const asection bfd_com_section; -.#define bfd_com_section_ptr ((asection *) &bfd_com_section) -. {* Pointer to the indirect section *} -.extern const asection bfd_ind_section; -.#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) -.#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) -. -.extern const struct symbol_cache_entry * const bfd_abs_symbol; -.extern const struct symbol_cache_entry * const bfd_com_symbol; -.extern const struct symbol_cache_entry * const bfd_und_symbol; -.extern const struct symbol_cache_entry * const bfd_ind_symbol; -.#define bfd_get_section_size_before_reloc(section) \ -. (section->reloc_done ? (abort(),1): (section)->_raw_size) -.#define bfd_get_section_size_after_reloc(section) \ -. ((section->reloc_done) ? (section)->_cooked_size: (abort(),1)) -*/ - -/* These symbols are global, not specific to any BFD. Therefore, anything - that tries to change them is broken, and should be repaired. */ -static const asymbol global_syms[] = -{ - /* the_bfd, name, value, attr, section [, udata] */ - {0, BFD_COM_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_com_section}, - {0, BFD_UND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_und_section}, - {0, BFD_ABS_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_abs_section}, - {0, BFD_IND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_ind_section}, -}; - -#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ - const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \ - const asection SEC = \ - { NAME, 0, 0, FLAGS, 0, false, 0, 0, 0, 0, (asection *) &SEC, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (boolean) 0, \ - (asymbol *) &global_syms[IDX], (asymbol **) &SYM, } - -STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol, - BFD_COM_SECTION_NAME, 0); -STD_SECTION (bfd_und_section, 0, bfd_und_symbol, BFD_UND_SECTION_NAME, 1); -STD_SECTION (bfd_abs_section, 0, bfd_abs_symbol, BFD_ABS_SECTION_NAME, 2); -STD_SECTION (bfd_ind_section, 0, bfd_ind_symbol, BFD_IND_SECTION_NAME, 3); -#undef STD_SECTION - -/* -DOCDD -INODE -section prototypes, , typedef asection, Sections -SUBSECTION - Section prototypes - -These are the functions exported by the section handling part of BFD. -*/ - -/* -FUNCTION - bfd_get_section_by_name - -SYNOPSIS - asection *bfd_get_section_by_name(bfd *abfd, CONST char *name); - -DESCRIPTION - Run through @var{abfd} and return the one of the - <>s whose name matches @var{name}, otherwise <>. - @xref{Sections}, for more information. - - This should only be used in special cases; the normal way to process - all sections of a given name is to use <> and - <> on the name (or better yet, base it on the section flags - or something else) for each section. -*/ - -asection * -bfd_get_section_by_name (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *sect; - - for (sect = abfd->sections; sect != NULL; sect = sect->next) - if (!strcmp (sect->name, name)) - return sect; - return NULL; -} - - -/* -FUNCTION - bfd_make_section_old_way - -SYNOPSIS - asection *bfd_make_section_old_way(bfd *abfd, CONST char *name); - -DESCRIPTION - Create a new empty section called @var{name} - and attach it to the end of the chain of sections for the - BFD @var{abfd}. An attempt to create a section with a name which - is already in use returns its pointer without changing the - section chain. - - It has the funny name since this is the way it used to be - before it was rewritten.... - - Possible errors are: - o <> - - If output has already started for this BFD. - o <> - - If obstack alloc fails. - -*/ - - -asection * -bfd_make_section_old_way (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *sec = bfd_get_section_by_name (abfd, name); - if (sec == (asection *) NULL) - { - sec = bfd_make_section (abfd, name); - } - return sec; -} - -/* -FUNCTION - bfd_make_section_anyway - -SYNOPSIS - asection *bfd_make_section_anyway(bfd *abfd, CONST char *name); - -DESCRIPTION - Create a new empty section called @var{name} and attach it to the end of - the chain of sections for @var{abfd}. Create a new section even if there - is already a section with that name. - - Return <> and set <> on error; possible errors are: - o <> - If output has already started for @var{abfd}. - o <> - If obstack alloc fails. -*/ - -sec_ptr -bfd_make_section_anyway (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *newsect; - asection **prev = &abfd->sections; - asection *sect = abfd->sections; - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - while (sect) - { - prev = §->next; - sect = sect->next; - } - - newsect = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (newsect == NULL) - return NULL; - - newsect->name = name; - newsect->index = abfd->section_count++; - newsect->flags = SEC_NO_FLAGS; - - newsect->userdata = NULL; - newsect->contents = NULL; - newsect->next = (asection *) NULL; - newsect->relocation = (arelent *) NULL; - newsect->reloc_count = 0; - newsect->line_filepos = 0; - newsect->owner = abfd; - - /* Create a symbol whos only job is to point to this section. This is - useful for things like relocs which are relative to the base of a - section. */ - newsect->symbol = bfd_make_empty_symbol (abfd); - if (newsect->symbol == NULL) - return NULL; - newsect->symbol->name = name; - newsect->symbol->value = 0; - newsect->symbol->section = newsect; - newsect->symbol->flags = BSF_SECTION_SYM; - - newsect->symbol_ptr_ptr = &newsect->symbol; - - if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) - { - free (newsect); - return NULL; - } - - *prev = newsect; - return newsect; -} - -/* -FUNCTION - bfd_make_section - -SYNOPSIS - asection *bfd_make_section(bfd *, CONST char *name); - -DESCRIPTION - Like <>, but return <> (without calling - bfd_set_error ()) without changing the section chain if there is already a - section named @var{name}. If there is an error, return <> and set - <>. -*/ - -asection * -bfd_make_section (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *sect = abfd->sections; - - if (strcmp (name, BFD_ABS_SECTION_NAME) == 0) - { - return bfd_abs_section_ptr; - } - if (strcmp (name, BFD_COM_SECTION_NAME) == 0) - { - return bfd_com_section_ptr; - } - if (strcmp (name, BFD_UND_SECTION_NAME) == 0) - { - return bfd_und_section_ptr; - } - - if (strcmp (name, BFD_IND_SECTION_NAME) == 0) - { - return bfd_ind_section_ptr; - } - - while (sect) - { - if (!strcmp (sect->name, name)) - return NULL; - sect = sect->next; - } - - /* The name is not already used; go ahead and make a new section. */ - return bfd_make_section_anyway (abfd, name); -} - - -/* -FUNCTION - bfd_set_section_flags - -SYNOPSIS - boolean bfd_set_section_flags(bfd *abfd, asection *sec, flagword flags); - -DESCRIPTION - Set the attributes of the section @var{sec} in the BFD - @var{abfd} to the value @var{flags}. Return <> on success, - <> on error. Possible error returns are: - - o <> - - The section cannot have one or more of the attributes - requested. For example, a .bss section in <> may not - have the <> field set. - -*/ - -/*ARGSUSED*/ -boolean -bfd_set_section_flags (abfd, section, flags) - bfd *abfd; - sec_ptr section; - flagword flags; -{ -#if 0 - /* If you try to copy a text section from an input file (where it - has the SEC_CODE flag set) to an output file, this loses big if - the bfd_applicable_section_flags (abfd) doesn't have the SEC_CODE - set - which it doesn't, at least not for a.out. FIXME */ - - if ((flags & bfd_applicable_section_flags (abfd)) != flags) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } -#endif - - section->flags = flags; - return true; -} - - -/* -FUNCTION - bfd_map_over_sections - -SYNOPSIS - void bfd_map_over_sections(bfd *abfd, - void (*func)(bfd *abfd, - asection *sect, - PTR obj), - PTR obj); - -DESCRIPTION - Call the provided function @var{func} for each section - attached to the BFD @var{abfd}, passing @var{obj} as an - argument. The function will be called as if by - -| func(abfd, the_section, obj); - - This is the prefered method for iterating over sections; an - alternative would be to use a loop: - -| section *p; -| for (p = abfd->sections; p != NULL; p = p->next) -| func(abfd, p, ...) - - -*/ - -/*VARARGS2*/ -void -bfd_map_over_sections (abfd, operation, user_storage) - bfd *abfd; - void (*operation) PARAMS ((bfd * abfd, asection * sect, PTR obj)); - PTR user_storage; -{ - asection *sect; - unsigned int i = 0; - - for (sect = abfd->sections; sect != NULL; i++, sect = sect->next) - (*operation) (abfd, sect, user_storage); - - if (i != abfd->section_count) /* Debugging */ - abort (); -} - - -/* -FUNCTION - bfd_set_section_size - -SYNOPSIS - boolean bfd_set_section_size(bfd *abfd, asection *sec, bfd_size_type val); - -DESCRIPTION - Set @var{sec} to the size @var{val}. If the operation is - ok, then <> is returned, else <>. - - Possible error returns: - o <> - - Writing has started to the BFD, so setting the size is invalid. - -*/ - -boolean -bfd_set_section_size (abfd, ptr, val) - bfd *abfd; - sec_ptr ptr; - bfd_size_type val; -{ - /* Once you've started writing to any section you cannot create or change - the size of any others. */ - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - ptr->_cooked_size = val; - ptr->_raw_size = val; - - return true; -} - -/* -FUNCTION - bfd_set_section_contents - -SYNOPSIS - boolean bfd_set_section_contents - (bfd *abfd, - asection *section, - PTR data, - file_ptr offset, - bfd_size_type count); - - -DESCRIPTION - Sets the contents of the section @var{section} in BFD - @var{abfd} to the data starting in memory at @var{data}. The - data is written to the output section starting at offset - @var{offset} for @var{count} bytes. - - - - Normally <> is returned, else <>. Possible error - returns are: - o <> - - The output section does not have the <> - attribute, so nothing can be written to it. - o and some more too - - This routine is front end to the back end function - <<_bfd_set_section_contents>>. - - -*/ - -#define bfd_get_section_size_now(abfd,sec) \ -(sec->reloc_done \ - ? bfd_get_section_size_after_reloc (sec) \ - : bfd_get_section_size_before_reloc (sec)) - -boolean -bfd_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - bfd_size_type sz; - - if (!(bfd_get_section_flags (abfd, section) & SEC_HAS_CONTENTS)) - { - bfd_set_error (bfd_error_no_contents); - return (false); - } - - if (offset < 0) - { - bad_val: - bfd_set_error (bfd_error_bad_value); - return false; - } - sz = bfd_get_section_size_now (abfd, section); - if ((bfd_size_type) offset > sz - || count > sz - || offset + count > sz) - goto bad_val; - - switch (abfd->direction) - { - case read_direction: - case no_direction: - bfd_set_error (bfd_error_invalid_operation); - return false; - - case write_direction: - break; - - case both_direction: - /* File is opened for update. `output_has_begun' some time ago when - the file was created. Do not recompute sections sizes or alignments - in _bfd_set_section_content. */ - abfd->output_has_begun = true; - break; - } - - if (BFD_SEND (abfd, _bfd_set_section_contents, - (abfd, section, location, offset, count))) - { - abfd->output_has_begun = true; - return true; - } - - return false; -} - -/* -FUNCTION - bfd_get_section_contents - -SYNOPSIS - boolean bfd_get_section_contents - (bfd *abfd, asection *section, PTR location, - file_ptr offset, bfd_size_type count); - -DESCRIPTION - Read data from @var{section} in BFD @var{abfd} - into memory starting at @var{location}. The data is read at an - offset of @var{offset} from the start of the input section, - and is read for @var{count} bytes. - - If the contents of a constructor with the <> - flag set are requested or if the section does not have the - <> flag set, then the @var{location} is filled - with zeroes. If no errors occur, <> is returned, else - <>. - - - -*/ -boolean -bfd_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - bfd_size_type sz; - - if (section->flags & SEC_CONSTRUCTOR) - { - memset (location, 0, (unsigned) count); - return true; - } - - if (offset < 0) - { - bad_val: - bfd_set_error (bfd_error_bad_value); - return false; - } - /* Even if reloc_done is true, this function reads unrelocated - contents, so we want the raw size. */ - sz = section->_raw_size; - if ((bfd_size_type) offset > sz || count > sz || offset + count > sz) - goto bad_val; - - if (count == 0) - /* Don't bother. */ - return true; - - if ((section->flags & SEC_HAS_CONTENTS) == 0) - { - memset (location, 0, (unsigned) count); - return true; - } - - if ((section->flags & SEC_IN_MEMORY) != 0) - { - memcpy (location, section->contents + offset, (size_t) count); - return true; - } - - return BFD_SEND (abfd, _bfd_get_section_contents, - (abfd, section, location, offset, count)); -} - -/* -FUNCTION - bfd_copy_private_section_data - -SYNOPSIS - boolean bfd_copy_private_section_data(bfd *ibfd, asection *isec, bfd *obfd, asection *osec); - -DESCRIPTION - Copy private section information from @var{isec} in the BFD - @var{ibfd} to the section @var{osec} in the BFD @var{obfd}. - Return <> on success, <> on error. Possible error - returns are: - - o <> - - Not enough memory exists to create private data for @var{osec}. - -.#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ -. BFD_SEND (ibfd, _bfd_copy_private_section_data, \ -. (ibfd, isection, obfd, osection)) -*/ diff --git a/contrib/gdb/bfd/som.c b/contrib/gdb/bfd/som.c deleted file mode 100644 index dd03d99ee19..00000000000 --- a/contrib/gdb/bfd/som.c +++ /dev/null @@ -1,5999 +0,0 @@ -/* bfd back-end for HP PA-RISC SOM objects. - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996 - Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" - -#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) - -#include "libbfd.h" -#include "som.h" - -#include -#include -#include -#include -#include -#include -#include - -/* Magic not defined in standard HP-UX header files until 8.0 */ - -#ifndef CPU_PA_RISC1_0 -#define CPU_PA_RISC1_0 0x20B -#endif /* CPU_PA_RISC1_0 */ - -#ifndef CPU_PA_RISC1_1 -#define CPU_PA_RISC1_1 0x210 -#endif /* CPU_PA_RISC1_1 */ - -#ifndef _PA_RISC1_0_ID -#define _PA_RISC1_0_ID CPU_PA_RISC1_0 -#endif /* _PA_RISC1_0_ID */ - -#ifndef _PA_RISC1_1_ID -#define _PA_RISC1_1_ID CPU_PA_RISC1_1 -#endif /* _PA_RISC1_1_ID */ - -#ifndef _PA_RISC_MAXID -#define _PA_RISC_MAXID 0x2FF -#endif /* _PA_RISC_MAXID */ - -#ifndef _PA_RISC_ID -#define _PA_RISC_ID(__m_num) \ - (((__m_num) == _PA_RISC1_0_ID) || \ - ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID)) -#endif /* _PA_RISC_ID */ - - -/* HIUX in it's infinite stupidity changed the names for several "well - known" constants. Work around such braindamage. Try the HPUX version - first, then the HIUX version, and finally provide a default. */ -#ifdef HPUX_AUX_ID -#define EXEC_AUX_ID HPUX_AUX_ID -#endif - -#if !defined (EXEC_AUX_ID) && defined (HIUX_AUX_ID) -#define EXEC_AUX_ID HIUX_AUX_ID -#endif - -#ifndef EXEC_AUX_ID -#define EXEC_AUX_ID 0 -#endif - -/* Size (in chars) of the temporary buffers used during fixup and string - table writes. */ - -#define SOM_TMP_BUFSIZE 8192 - -/* Size of the hash table in archives. */ -#define SOM_LST_HASH_SIZE 31 - -/* Max number of SOMs to be found in an archive. */ -#define SOM_LST_MODULE_LIMIT 1024 - -/* Generic alignment macro. */ -#define SOM_ALIGN(val, alignment) \ - (((val) + (alignment) - 1) & ~((alignment) - 1)) - -/* SOM allows any one of the four previous relocations to be reused - with a "R_PREV_FIXUP" relocation entry. Since R_PREV_FIXUP - relocations are always a single byte, using a R_PREV_FIXUP instead - of some multi-byte relocation makes object files smaller. - - Note one side effect of using a R_PREV_FIXUP is the relocation that - is being repeated moves to the front of the queue. */ -struct reloc_queue - { - unsigned char *reloc; - unsigned int size; - } reloc_queue[4]; - -/* This fully describes the symbol types which may be attached to - an EXPORT or IMPORT directive. Only SOM uses this formation - (ELF has no need for it). */ -typedef enum -{ - SYMBOL_TYPE_UNKNOWN, - SYMBOL_TYPE_ABSOLUTE, - SYMBOL_TYPE_CODE, - SYMBOL_TYPE_DATA, - SYMBOL_TYPE_ENTRY, - SYMBOL_TYPE_MILLICODE, - SYMBOL_TYPE_PLABEL, - SYMBOL_TYPE_PRI_PROG, - SYMBOL_TYPE_SEC_PROG, -} pa_symbol_type; - -struct section_to_type -{ - char *section; - char type; -}; - -/* Assorted symbol information that needs to be derived from the BFD symbol - and/or the BFD backend private symbol data. */ -struct som_misc_symbol_info -{ - unsigned int symbol_type; - unsigned int symbol_scope; - unsigned int arg_reloc; - unsigned int symbol_info; - unsigned int symbol_value; -}; - -/* Forward declarations */ - -static boolean som_mkobject PARAMS ((bfd *)); -static const bfd_target * som_object_setup PARAMS ((bfd *, - struct header *, - struct som_exec_auxhdr *)); -static boolean setup_sections PARAMS ((bfd *, struct header *)); -static const bfd_target * som_object_p PARAMS ((bfd *)); -static boolean som_write_object_contents PARAMS ((bfd *)); -static boolean som_slurp_string_table PARAMS ((bfd *)); -static unsigned int som_slurp_symbol_table PARAMS ((bfd *)); -static long som_get_symtab_upper_bound PARAMS ((bfd *)); -static long som_canonicalize_reloc PARAMS ((bfd *, sec_ptr, - arelent **, asymbol **)); -static long som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -static unsigned int som_set_reloc_info PARAMS ((unsigned char *, unsigned int, - arelent *, asection *, - asymbol **, boolean)); -static boolean som_slurp_reloc_table PARAMS ((bfd *, asection *, - asymbol **, boolean)); -static long som_get_symtab PARAMS ((bfd *, asymbol **)); -static asymbol * som_make_empty_symbol PARAMS ((bfd *)); -static void som_print_symbol PARAMS ((bfd *, PTR, - asymbol *, bfd_print_symbol_type)); -static boolean som_new_section_hook PARAMS ((bfd *, asection *)); -static boolean som_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *, - bfd *, asymbol *)); -static boolean som_bfd_copy_private_section_data PARAMS ((bfd *, asection *, - bfd *, asection *)); -static boolean som_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -#define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data -#define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags -static boolean som_bfd_is_local_label PARAMS ((bfd *, asymbol *)); -static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); -static boolean som_get_section_contents PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); -static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); -static boolean som_find_nearest_line PARAMS ((bfd *, asection *, - asymbol **, bfd_vma, - CONST char **, - CONST char **, - unsigned int *)); -static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); -static asection * bfd_section_from_som_symbol PARAMS ((bfd *, - struct symbol_dictionary_record *)); -static int log2 PARAMS ((unsigned int)); -static bfd_reloc_status_type hppa_som_reloc PARAMS ((bfd *, arelent *, - asymbol *, PTR, - asection *, bfd *, - char **)); -static void som_initialize_reloc_queue PARAMS ((struct reloc_queue *)); -static void som_reloc_queue_insert PARAMS ((unsigned char *, unsigned int, - struct reloc_queue *)); -static void som_reloc_queue_fix PARAMS ((struct reloc_queue *, unsigned int)); -static int som_reloc_queue_find PARAMS ((unsigned char *, unsigned int, - struct reloc_queue *)); -static unsigned char * try_prev_fixup PARAMS ((bfd *, int *, unsigned char *, - unsigned int, - struct reloc_queue *)); - -static unsigned char * som_reloc_skip PARAMS ((bfd *, unsigned int, - unsigned char *, unsigned int *, - struct reloc_queue *)); -static unsigned char * som_reloc_addend PARAMS ((bfd *, int, unsigned char *, - unsigned int *, - struct reloc_queue *)); -static unsigned char * som_reloc_call PARAMS ((bfd *, unsigned char *, - unsigned int *, - arelent *, int, - struct reloc_queue *)); -static unsigned long som_count_spaces PARAMS ((bfd *)); -static unsigned long som_count_subspaces PARAMS ((bfd *)); -static int compare_syms PARAMS ((const void *, const void *)); -static int compare_subspaces PARAMS ((const void *, const void *)); -static unsigned long som_compute_checksum PARAMS ((bfd *)); -static boolean som_prep_headers PARAMS ((bfd *)); -static int som_sizeof_headers PARAMS ((bfd *, boolean)); -static boolean som_finish_writing PARAMS ((bfd *)); -static boolean som_build_and_write_symbol_table PARAMS ((bfd *)); -static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long)); -static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *)); -static boolean som_write_space_strings PARAMS ((bfd *, unsigned long, - unsigned int *)); -static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long, - asymbol **, unsigned int, - unsigned *)); -static boolean som_begin_writing PARAMS ((bfd *)); -static reloc_howto_type * som_bfd_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static char som_section_type PARAMS ((const char *)); -static int som_decode_symclass PARAMS ((asymbol *)); -static boolean som_bfd_count_ar_symbols PARAMS ((bfd *, struct lst_header *, - symindex *)); - -static boolean som_bfd_fill_in_ar_symbols PARAMS ((bfd *, struct lst_header *, - carsym **syms)); -static boolean som_slurp_armap PARAMS ((bfd *)); -static boolean som_write_armap PARAMS ((bfd *, unsigned int, struct orl *, - unsigned int, int)); -static void som_bfd_derive_misc_symbol_info PARAMS ((bfd *, asymbol *, - struct som_misc_symbol_info *)); -static boolean som_bfd_prep_for_ar_write PARAMS ((bfd *, unsigned int *, - unsigned int *)); -static unsigned int som_bfd_ar_symbol_hash PARAMS ((asymbol *)); -static boolean som_bfd_ar_write_symbol_stuff PARAMS ((bfd *, unsigned int, - unsigned int, - struct lst_header)); -static CONST char *normalize PARAMS ((CONST char *file)); -static boolean som_is_space PARAMS ((asection *)); -static boolean som_is_subspace PARAMS ((asection *)); -static boolean som_is_container PARAMS ((asection *, asection *)); -static boolean som_bfd_free_cached_info PARAMS ((bfd *)); -static boolean som_bfd_link_split_section PARAMS ((bfd *, asection *)); - -/* Map SOM section names to POSIX/BSD single-character symbol types. - - This table includes all the standard subspaces as defined in the - current "PRO ABI for PA-RISC Systems", $UNWIND$ which for - some reason was left out, and sections specific to embedded stabs. */ - -static const struct section_to_type stt[] = { - {"$TEXT$", 't'}, - {"$SHLIB_INFO$", 't'}, - {"$MILLICODE$", 't'}, - {"$LIT$", 't'}, - {"$CODE$", 't'}, - {"$UNWIND_START$", 't'}, - {"$UNWIND$", 't'}, - {"$PRIVATE$", 'd'}, - {"$PLT$", 'd'}, - {"$SHLIB_DATA$", 'd'}, - {"$DATA$", 'd'}, - {"$SHORTDATA$", 'g'}, - {"$DLT$", 'd'}, - {"$GLOBAL$", 'g'}, - {"$SHORTBSS$", 's'}, - {"$BSS$", 'b'}, - {"$GDB_STRINGS$", 'N'}, - {"$GDB_SYMBOLS$", 'N'}, - {0, 0} -}; - -/* About the relocation formatting table... - - There are 256 entries in the table, one for each possible - relocation opcode available in SOM. We index the table by - the relocation opcode. The names and operations are those - defined by a.out_800 (4). - - Right now this table is only used to count and perform minimal - processing on relocation streams so that they can be internalized - into BFD and symbolically printed by utilities. To make actual use - of them would be much more difficult, BFD's concept of relocations - is far too simple to handle SOM relocations. The basic assumption - that a relocation can be completely processed independent of other - relocations before an object file is written is invalid for SOM. - - The SOM relocations are meant to be processed as a stream, they - specify copying of data from the input section to the output section - while possibly modifying the data in some manner. They also can - specify that a variable number of zeros or uninitialized data be - inserted on in the output segment at the current offset. Some - relocations specify that some previous relocation be re-applied at - the current location in the input/output sections. And finally a number - of relocations have effects on other sections (R_ENTRY, R_EXIT, - R_UNWIND_AUX and a variety of others). There isn't even enough room - in the BFD relocation data structure to store enough information to - perform all the relocations. - - Each entry in the table has three fields. - - The first entry is an index into this "class" of relocations. This - index can then be used as a variable within the relocation itself. - - The second field is a format string which actually controls processing - of the relocation. It uses a simple postfix machine to do calculations - based on variables/constants found in the string and the relocation - stream. - - The third field specifys whether or not this relocation may use - a constant (V) from the previous R_DATA_OVERRIDE rather than a constant - stored in the instruction. - - Variables: - - L = input space byte count - D = index into class of relocations - M = output space byte count - N = statement number (unused?) - O = stack operation - R = parameter relocation bits - S = symbol index - T = first 32 bits of stack unwind information - U = second 32 bits of stack unwind information - V = a literal constant (usually used in the next relocation) - P = a previous relocation - - Lower case letters (starting with 'b') refer to following - bytes in the relocation stream. 'b' is the next 1 byte, - c is the next 2 bytes, d is the next 3 bytes, etc... - This is the variable part of the relocation entries that - makes our life a living hell. - - numerical constants are also used in the format string. Note - the constants are represented in decimal. - - '+', "*" and "=" represents the obvious postfix operators. - '<' represents a left shift. - - Stack Operations: - - Parameter Relocation Bits: - - Unwind Entries: - - Previous Relocations: The index field represents which in the queue - of 4 previous fixups should be re-applied. - - Literal Constants: These are generally used to represent addend - parts of relocations when these constants are not stored in the - fields of the instructions themselves. For example the instruction - addil foo-$global$-0x1234 would use an override for "0x1234" rather - than storing it into the addil itself. */ - -struct fixup_format -{ - int D; - char *format; -}; - -static const struct fixup_format som_fixup_formats[256] = -{ - /* R_NO_RELOCATION */ - 0, "LD1+4*=", /* 0x00 */ - 1, "LD1+4*=", /* 0x01 */ - 2, "LD1+4*=", /* 0x02 */ - 3, "LD1+4*=", /* 0x03 */ - 4, "LD1+4*=", /* 0x04 */ - 5, "LD1+4*=", /* 0x05 */ - 6, "LD1+4*=", /* 0x06 */ - 7, "LD1+4*=", /* 0x07 */ - 8, "LD1+4*=", /* 0x08 */ - 9, "LD1+4*=", /* 0x09 */ - 10, "LD1+4*=", /* 0x0a */ - 11, "LD1+4*=", /* 0x0b */ - 12, "LD1+4*=", /* 0x0c */ - 13, "LD1+4*=", /* 0x0d */ - 14, "LD1+4*=", /* 0x0e */ - 15, "LD1+4*=", /* 0x0f */ - 16, "LD1+4*=", /* 0x10 */ - 17, "LD1+4*=", /* 0x11 */ - 18, "LD1+4*=", /* 0x12 */ - 19, "LD1+4*=", /* 0x13 */ - 20, "LD1+4*=", /* 0x14 */ - 21, "LD1+4*=", /* 0x15 */ - 22, "LD1+4*=", /* 0x16 */ - 23, "LD1+4*=", /* 0x17 */ - 0, "LD8= 0x1000000) - { - skip -= 0x1000000; - bfd_put_8 (abfd, R_NO_RELOCATION + 31, p); - bfd_put_8 (abfd, 0xff, p + 1); - bfd_put_16 (abfd, 0xffff, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue); - while (skip >= 0x1000000) - { - skip -= 0x1000000; - bfd_put_8 (abfd, R_PREV_FIXUP, p); - p++; - *subspace_reloc_sizep += 1; - /* No need to adjust queue here since we are repeating the - most recent fixup. */ - } - } - - /* The difference must be less than 0x1000000. Use one - more R_NO_RELOCATION entry to get to the right difference. */ - if ((skip & 3) == 0 && skip <= 0xc0000 && skip > 0) - { - /* Difference can be handled in a simple single-byte - R_NO_RELOCATION entry. */ - if (skip <= 0x60) - { - bfd_put_8 (abfd, R_NO_RELOCATION + (skip >> 2) - 1, p); - *subspace_reloc_sizep += 1; - p++; - } - /* Handle it with a two byte R_NO_RELOCATION entry. */ - else if (skip <= 0x1000) - { - bfd_put_8 (abfd, R_NO_RELOCATION + 24 + (((skip >> 2) - 1) >> 8), p); - bfd_put_8 (abfd, (skip >> 2) - 1, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue); - } - /* Handle it with a three byte R_NO_RELOCATION entry. */ - else - { - bfd_put_8 (abfd, R_NO_RELOCATION + 28 + (((skip >> 2) - 1) >> 16), p); - bfd_put_16 (abfd, (skip >> 2) - 1, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue); - } - } - /* Ugh. Punt and use a 4 byte entry. */ - else if (skip > 0) - { - bfd_put_8 (abfd, R_NO_RELOCATION + 31, p); - bfd_put_8 (abfd, (skip - 1) >> 16, p + 1); - bfd_put_16 (abfd, skip - 1, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue); - } - return p; -} - -/* Emit the proper R_DATA_OVERRIDE fixups to handle a nonzero addend - from a BFD relocation. Update the size of the subspace relocation - stream via SUBSPACE_RELOC_SIZE_P; also return the current pointer - into the relocation stream. */ - -static unsigned char * -som_reloc_addend (abfd, addend, p, subspace_reloc_sizep, queue) - bfd *abfd; - int addend; - unsigned char *p; - unsigned int *subspace_reloc_sizep; - struct reloc_queue *queue; -{ - if ((unsigned)(addend) + 0x80 < 0x100) - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 1, p); - bfd_put_8 (abfd, addend, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue); - } - else if ((unsigned) (addend) + 0x8000 < 0x10000) - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 2, p); - bfd_put_16 (abfd, addend, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue); - } - else if ((unsigned) (addend) + 0x800000 < 0x1000000) - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 3, p); - bfd_put_8 (abfd, addend >> 16, p + 1); - bfd_put_16 (abfd, addend, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue); - } - else - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 4, p); - bfd_put_32 (abfd, addend, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue); - } - return p; -} - -/* Handle a single function call relocation. */ - -static unsigned char * -som_reloc_call (abfd, p, subspace_reloc_sizep, bfd_reloc, sym_num, queue) - bfd *abfd; - unsigned char *p; - unsigned int *subspace_reloc_sizep; - arelent *bfd_reloc; - int sym_num; - struct reloc_queue *queue; -{ - int arg_bits = HPPA_R_ARG_RELOC (bfd_reloc->addend); - int rtn_bits = arg_bits & 0x3; - int type, done = 0; - - /* You'll never believe all this is necessary to handle relocations - for function calls. Having to compute and pack the argument - relocation bits is the real nightmare. - - If you're interested in how this works, just forget it. You really - do not want to know about this braindamage. */ - - /* First see if this can be done with a "simple" relocation. Simple - relocations have a symbol number < 0x100 and have simple encodings - of argument relocations. */ - - if (sym_num < 0x100) - { - switch (arg_bits) - { - case 0: - case 1: - type = 0; - break; - case 1 << 8: - case 1 << 8 | 1: - type = 1; - break; - case 1 << 8 | 1 << 6: - case 1 << 8 | 1 << 6 | 1: - type = 2; - break; - case 1 << 8 | 1 << 6 | 1 << 4: - case 1 << 8 | 1 << 6 | 1 << 4 | 1: - type = 3; - break; - case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2: - case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2 | 1: - type = 4; - break; - default: - /* Not one of the easy encodings. This will have to be - handled by the more complex code below. */ - type = -1; - break; - } - if (type != -1) - { - /* Account for the return value too. */ - if (rtn_bits) - type += 5; - - /* Emit a 2 byte relocation. Then see if it can be handled - with a relocation which is already in the relocation queue. */ - bfd_put_8 (abfd, bfd_reloc->howto->type + type, p); - bfd_put_8 (abfd, sym_num, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue); - done = 1; - } - } - - /* If this could not be handled with a simple relocation, then do a hard - one. Hard relocations occur if the symbol number was too high or if - the encoding of argument relocation bits is too complex. */ - if (! done) - { - /* Don't ask about these magic sequences. I took them straight - from gas-1.36 which took them from the a.out man page. */ - type = rtn_bits; - if ((arg_bits >> 6 & 0xf) == 0xe) - type += 9 * 40; - else - type += (3 * (arg_bits >> 8 & 3) + (arg_bits >> 6 & 3)) * 40; - if ((arg_bits >> 2 & 0xf) == 0xe) - type += 9 * 4; - else - type += (3 * (arg_bits >> 4 & 3) + (arg_bits >> 2 & 3)) * 4; - - /* Output the first two bytes of the relocation. These describe - the length of the relocation and encoding style. */ - bfd_put_8 (abfd, bfd_reloc->howto->type + 10 - + 2 * (sym_num >= 0x100) + (type >= 0x100), - p); - bfd_put_8 (abfd, type, p + 1); - - /* Now output the symbol index and see if this bizarre relocation - just happened to be in the relocation queue. */ - if (sym_num < 0x100) - { - bfd_put_8 (abfd, sym_num, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue); - } - else - { - bfd_put_8 (abfd, sym_num >> 16, p + 2); - bfd_put_16 (abfd, sym_num, p + 3); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue); - } - } - return p; -} - - -/* Return the logarithm of X, base 2, considering X unsigned. - Abort -1 if X is not a power or two or is zero. */ - -static int -log2 (x) - unsigned int x; -{ - int log = 0; - - /* Test for 0 or a power of 2. */ - if (x == 0 || x != (x & -x)) - return -1; - - while ((x >>= 1) != 0) - log++; - return log; -} - -static bfd_reloc_status_type -hppa_som_reloc (abfd, reloc_entry, symbol_in, data, - input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - return bfd_reloc_ok; -} - -/* Given a generic HPPA relocation type, the instruction format, - and a field selector, return one or more appropriate SOM relocations. */ - -int ** -hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff) - bfd *abfd; - int base_type; - int format; - enum hppa_reloc_field_selector_type_alt field; - int sym_diff; -{ - int *final_type, **final_types; - - final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 6); - final_type = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types || !final_type) - return NULL; - - /* The field selector may require additional relocations to be - generated. It's impossible to know at this moment if additional - relocations will be needed, so we make them. The code to actually - write the relocation/fixup stream is responsible for removing - any redundant relocations. */ - switch (field) - { - case e_fsel: - case e_psel: - case e_lpsel: - case e_rpsel: - final_types[0] = final_type; - final_types[1] = NULL; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_tsel: - case e_ltsel: - case e_rtsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - if (field == e_tsel) - *final_types[0] = R_FSEL; - else if (field == e_ltsel) - *final_types[0] = R_LSEL; - else - *final_types[0] = R_RSEL; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_lssel: - case e_rssel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_S_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_lsel: - case e_rsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_N_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_ldsel: - case e_rdsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_D_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_lrsel: - case e_rrsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_R_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_nsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_N1SEL; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_nlsel: - case e_nlrsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_N0SEL; - final_types[1] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[1]) - return NULL; - if (field == e_nlsel) - *final_types[1] = R_N_MODE; - else - *final_types[1] = R_R_MODE; - final_types[2] = final_type; - final_types[3] = NULL; - *final_type = base_type; - break; - } - - switch (base_type) - { - case R_HPPA: - /* The difference of two symbols needs *very* special handling. */ - if (sym_diff) - { - final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0] || !final_types[1] || !final_types[2]) - return NULL; - if (field == e_fsel) - *final_types[0] = R_FSEL; - else if (field == e_rsel) - *final_types[0] = R_RSEL; - else if (field == e_lsel) - *final_types[0] = R_LSEL; - *final_types[1] = R_COMP2; - *final_types[2] = R_COMP2; - *final_types[3] = R_COMP1; - final_types[4] = final_type; - *final_types[4] = R_CODE_EXPR; - final_types[5] = NULL; - break; - } - /* PLABELs get their own relocation type. */ - else if (field == e_psel - || field == e_lpsel - || field == e_rpsel) - { - /* A PLABEL relocation that has a size of 32 bits must - be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */ - if (format == 32) - *final_type = R_DATA_PLABEL; - else - *final_type = R_CODE_PLABEL; - } - /* PIC stuff. */ - else if (field == e_tsel - || field == e_ltsel - || field == e_rtsel) - *final_type = R_DLT_REL; - /* A relocation in the data space is always a full 32bits. */ - else if (format == 32) - *final_type = R_DATA_ONE_SYMBOL; - - break; - - case R_HPPA_GOTOFF: - /* More PLABEL special cases. */ - if (field == e_psel - || field == e_lpsel - || field == e_rpsel) - *final_type = R_DATA_PLABEL; - break; - - case R_HPPA_COMPLEX: - /* The difference of two symbols needs *very* special handling. */ - if (sym_diff) - { - final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0] || !final_types[1] || !final_types[2]) - return NULL; - if (field == e_fsel) - *final_types[0] = R_FSEL; - else if (field == e_rsel) - *final_types[0] = R_RSEL; - else if (field == e_lsel) - *final_types[0] = R_LSEL; - *final_types[1] = R_COMP2; - *final_types[2] = R_COMP2; - *final_types[3] = R_COMP1; - final_types[4] = final_type; - *final_types[4] = R_CODE_EXPR; - final_types[5] = NULL; - break; - } - else - break; - - case R_HPPA_NONE: - case R_HPPA_ABS_CALL: - case R_HPPA_PCREL_CALL: - /* Right now we can default all these. */ - break; - } - return final_types; -} - -/* Return the address of the correct entry in the PA SOM relocation - howto table. */ - -/*ARGSUSED*/ -static reloc_howto_type * -som_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - if ((int) code < (int) R_NO_RELOCATION + 255) - { - BFD_ASSERT ((int) som_hppa_howto_table[(int) code].type == (int) code); - return &som_hppa_howto_table[(int) code]; - } - - return (reloc_howto_type *) 0; -} - -/* Perform some initialization for an object. Save results of this - initialization in the BFD. */ - -static const bfd_target * -som_object_setup (abfd, file_hdrp, aux_hdrp) - bfd *abfd; - struct header *file_hdrp; - struct som_exec_auxhdr *aux_hdrp; -{ - asection *section; - int found; - - /* som_mkobject will set bfd_error if som_mkobject fails. */ - if (som_mkobject (abfd) != true) - return 0; - - /* Set BFD flags based on what information is available in the SOM. */ - abfd->flags = NO_FLAGS; - if (file_hdrp->symbol_total) - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - - switch (file_hdrp->a_magic) - { - case DEMAND_MAGIC: - abfd->flags |= (D_PAGED | WP_TEXT | EXEC_P); - break; - case SHARE_MAGIC: - abfd->flags |= (WP_TEXT | EXEC_P); - break; - case EXEC_MAGIC: - abfd->flags |= (EXEC_P); - break; - case RELOC_MAGIC: - abfd->flags |= HAS_RELOC; - break; -#ifdef SHL_MAGIC - case SHL_MAGIC: -#endif -#ifdef DL_MAGIC - case DL_MAGIC: -#endif - abfd->flags |= DYNAMIC; - break; - - default: - break; - } - - /* Allocate space to hold the saved exec header information. */ - obj_som_exec_data (abfd) = (struct som_exec_data *) - bfd_zalloc (abfd, sizeof (struct som_exec_data )); - if (obj_som_exec_data (abfd) == NULL) - return NULL; - - /* The braindamaged OSF1 linker switched exec_flags and exec_entry! - - We used to identify OSF1 binaries based on NEW_VERSION_ID, but - apparently the latest HPUX linker is using NEW_VERSION_ID now. - - It's about time, OSF has used the new id since at least 1992; - HPUX didn't start till nearly 1995!. - - The new approach examines the entry field. If it's zero or not 4 - byte aligned then it's not a proper code address and we guess it's - really the executable flags. */ - found = 0; - for (section = abfd->sections; section; section = section->next) - { - if ((section->flags & SEC_CODE) == 0) - continue; - if (aux_hdrp->exec_entry >= section->vma - && aux_hdrp->exec_entry < section->vma + section->_cooked_size) - found = 1; - } - if (aux_hdrp->exec_entry == 0 - || (aux_hdrp->exec_entry & 0x3) != 0 - || ! found) - { - bfd_get_start_address (abfd) = aux_hdrp->exec_flags; - obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry; - } - else - { - bfd_get_start_address (abfd) = aux_hdrp->exec_entry; - obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags; - } - - bfd_default_set_arch_mach (abfd, bfd_arch_hppa, pa10); - bfd_get_symcount (abfd) = file_hdrp->symbol_total; - - /* Initialize the saved symbol table and string table to NULL. - Save important offsets and sizes from the SOM header into - the BFD. */ - obj_som_stringtab (abfd) = (char *) NULL; - obj_som_symtab (abfd) = (som_symbol_type *) NULL; - obj_som_sorted_syms (abfd) = NULL; - obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size; - obj_som_sym_filepos (abfd) = file_hdrp->symbol_location; - obj_som_str_filepos (abfd) = file_hdrp->symbol_strings_location; - obj_som_reloc_filepos (abfd) = file_hdrp->fixup_request_location; - obj_som_exec_data (abfd)->system_id = file_hdrp->system_id; - - return abfd->xvec; -} - -/* Convert all of the space and subspace info into BFD sections. Each space - contains a number of subspaces, which in turn describe the mapping between - regions of the exec file, and the address space that the program runs in. - BFD sections which correspond to spaces will overlap the sections for the - associated subspaces. */ - -static boolean -setup_sections (abfd, file_hdr) - bfd *abfd; - struct header *file_hdr; -{ - char *space_strings; - unsigned int space_index, i; - unsigned int total_subspaces = 0; - asection **subspace_sections, *section; - - /* First, read in space names */ - - space_strings = bfd_malloc (file_hdr->space_strings_size); - if (!space_strings && file_hdr->space_strings_size != 0) - goto error_return; - - if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0) - goto error_return; - if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd) - != file_hdr->space_strings_size) - goto error_return; - - /* Loop over all of the space dictionaries, building up sections */ - for (space_index = 0; space_index < file_hdr->space_total; space_index++) - { - struct space_dictionary_record space; - struct subspace_dictionary_record subspace, save_subspace; - int subspace_index; - asection *space_asect; - char *newname; - - /* Read the space dictionary element */ - if (bfd_seek (abfd, file_hdr->space_location - + space_index * sizeof space, SEEK_SET) < 0) - goto error_return; - if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space) - goto error_return; - - /* Setup the space name string */ - space.name.n_name = space.name.n_strx + space_strings; - - /* Make a section out of it */ - newname = bfd_alloc (abfd, strlen (space.name.n_name) + 1); - if (!newname) - goto error_return; - strcpy (newname, space.name.n_name); - - space_asect = bfd_make_section_anyway (abfd, newname); - if (!space_asect) - goto error_return; - - if (space.is_loadable == 0) - space_asect->flags |= SEC_DEBUGGING; - - /* Set up all the attributes for the space. */ - if (bfd_som_set_section_attributes (space_asect, space.is_defined, - space.is_private, space.sort_key, - space.space_number) == false) - goto error_return; - - /* If the space has no subspaces, then we're done. */ - if (space.subspace_quantity == 0) - continue; - - /* Now, read in the first subspace for this space */ - if (bfd_seek (abfd, file_hdr->subspace_location - + space.subspace_index * sizeof subspace, - SEEK_SET) < 0) - goto error_return; - if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace) - goto error_return; - /* Seek back to the start of the subspaces for loop below */ - if (bfd_seek (abfd, file_hdr->subspace_location - + space.subspace_index * sizeof subspace, - SEEK_SET) < 0) - goto error_return; - - /* Setup the start address and file loc from the first subspace record */ - space_asect->vma = subspace.subspace_start; - space_asect->filepos = subspace.file_loc_init_value; - space_asect->alignment_power = log2 (subspace.alignment); - if (space_asect->alignment_power == -1) - goto error_return; - - /* Initialize save_subspace so we can reliably determine if this - loop placed any useful values into it. */ - memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record)); - - /* Loop over the rest of the subspaces, building up more sections */ - for (subspace_index = 0; subspace_index < space.subspace_quantity; - subspace_index++) - { - asection *subspace_asect; - - /* Read in the next subspace */ - if (bfd_read (&subspace, 1, sizeof subspace, abfd) - != sizeof subspace) - goto error_return; - - /* Setup the subspace name string */ - subspace.name.n_name = subspace.name.n_strx + space_strings; - - newname = bfd_alloc (abfd, strlen (subspace.name.n_name) + 1); - if (!newname) - goto error_return; - strcpy (newname, subspace.name.n_name); - - /* Make a section out of this subspace */ - subspace_asect = bfd_make_section_anyway (abfd, newname); - if (!subspace_asect) - goto error_return; - - /* Store private information about the section. */ - if (bfd_som_set_subsection_attributes (subspace_asect, space_asect, - subspace.access_control_bits, - subspace.sort_key, - subspace.quadrant) == false) - goto error_return; - - /* Keep an easy mapping between subspaces and sections. - Note we do not necessarily read the subspaces in the - same order in which they appear in the object file. - - So to make the target index come out correctly, we - store the location of the subspace header in target - index, then sort using the location of the subspace - header as the key. Then we can assign correct - subspace indices. */ - total_subspaces++; - subspace_asect->target_index = bfd_tell (abfd) - sizeof (subspace); - - /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified - by the access_control_bits in the subspace header. */ - switch (subspace.access_control_bits >> 4) - { - /* Readonly data. */ - case 0x0: - subspace_asect->flags |= SEC_DATA | SEC_READONLY; - break; - - /* Normal data. */ - case 0x1: - subspace_asect->flags |= SEC_DATA; - break; - - /* Readonly code and the gateways. - Gateways have other attributes which do not map - into anything BFD knows about. */ - case 0x2: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - subspace_asect->flags |= SEC_CODE | SEC_READONLY; - break; - - /* dynamic (writable) code. */ - case 0x3: - subspace_asect->flags |= SEC_CODE; - break; - } - - if (subspace.dup_common || subspace.is_common) - subspace_asect->flags |= SEC_IS_COMMON; - else if (subspace.subspace_length > 0) - subspace_asect->flags |= SEC_HAS_CONTENTS; - - if (subspace.is_loadable) - subspace_asect->flags |= SEC_ALLOC | SEC_LOAD; - else - subspace_asect->flags |= SEC_DEBUGGING; - - if (subspace.code_only) - subspace_asect->flags |= SEC_CODE; - - /* Both file_loc_init_value and initialization_length will - be zero for a BSS like subspace. */ - if (subspace.file_loc_init_value == 0 - && subspace.initialization_length == 0) - subspace_asect->flags &= ~(SEC_DATA | SEC_LOAD | SEC_HAS_CONTENTS); - - /* This subspace has relocations. - The fixup_request_quantity is a byte count for the number of - entries in the relocation stream; it is not the actual number - of relocations in the subspace. */ - if (subspace.fixup_request_quantity != 0) - { - subspace_asect->flags |= SEC_RELOC; - subspace_asect->rel_filepos = subspace.fixup_request_index; - som_section_data (subspace_asect)->reloc_size - = subspace.fixup_request_quantity; - /* We can not determine this yet. When we read in the - relocation table the correct value will be filled in. */ - subspace_asect->reloc_count = -1; - } - - /* Update save_subspace if appropriate. */ - if (subspace.file_loc_init_value > save_subspace.file_loc_init_value) - save_subspace = subspace; - - subspace_asect->vma = subspace.subspace_start; - subspace_asect->_cooked_size = subspace.subspace_length; - subspace_asect->_raw_size = subspace.subspace_length; - subspace_asect->filepos = subspace.file_loc_init_value; - subspace_asect->alignment_power = log2 (subspace.alignment); - if (subspace_asect->alignment_power == -1) - goto error_return; - } - - /* Yow! there is no subspace within the space which actually - has initialized information in it; this should never happen - as far as I know. */ - if (!save_subspace.file_loc_init_value) - goto error_return; - - /* Setup the sizes for the space section based upon the info in the - last subspace of the space. */ - space_asect->_cooked_size = save_subspace.subspace_start - - space_asect->vma + save_subspace.subspace_length; - space_asect->_raw_size = save_subspace.file_loc_init_value - - space_asect->filepos + save_subspace.initialization_length; - } - /* Now that we've read in all the subspace records, we need to assign - a target index to each subspace. */ - subspace_sections = (asection **) bfd_malloc (total_subspaces - * sizeof (asection *)); - if (subspace_sections == NULL) - goto error_return; - - for (i = 0, section = abfd->sections; section; section = section->next) - { - if (!som_is_subspace (section)) - continue; - - subspace_sections[i] = section; - i++; - } - qsort (subspace_sections, total_subspaces, - sizeof (asection *), compare_subspaces); - - /* subspace_sections is now sorted in the order in which the subspaces - appear in the object file. Assign an index to each one now. */ - for (i = 0; i < total_subspaces; i++) - subspace_sections[i]->target_index = i; - - if (space_strings != NULL) - free (space_strings); - - if (subspace_sections != NULL) - free (subspace_sections); - - return true; - - error_return: - if (space_strings != NULL) - free (space_strings); - - if (subspace_sections != NULL) - free (subspace_sections); - return false; -} - -/* Read in a SOM object and make it into a BFD. */ - -static const bfd_target * -som_object_p (abfd) - bfd *abfd; -{ - struct header file_hdr; - struct som_exec_auxhdr aux_hdr; - - if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (!_PA_RISC_ID (file_hdr.system_id)) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - switch (file_hdr.a_magic) - { - case RELOC_MAGIC: - case EXEC_MAGIC: - case SHARE_MAGIC: - case DEMAND_MAGIC: -#ifdef DL_MAGIC - case DL_MAGIC: -#endif -#ifdef SHL_MAGIC - case SHL_MAGIC: -#endif -#ifdef EXECLIBMAGIC - case EXECLIBMAGIC: -#endif -#ifdef SHARED_MAGIC_CNX - case SHARED_MAGIC_CNX: -#endif - break; - default: - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (file_hdr.version_id != VERSION_ID - && file_hdr.version_id != NEW_VERSION_ID) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* If the aux_header_size field in the file header is zero, then this - object is an incomplete executable (a .o file). Do not try to read - a non-existant auxiliary header. */ - memset (&aux_hdr, 0, sizeof (struct som_exec_auxhdr)); - if (file_hdr.aux_header_size != 0) - { - if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - } - - if (!setup_sections (abfd, &file_hdr)) - { - /* setup_sections does not bubble up a bfd error code. */ - bfd_set_error (bfd_error_bad_value); - return 0; - } - - /* This appears to be a valid SOM object. Do some initialization. */ - return som_object_setup (abfd, &file_hdr, &aux_hdr); -} - -/* Create a SOM object. */ - -static boolean -som_mkobject (abfd) - bfd *abfd; -{ - /* Allocate memory to hold backend information. */ - abfd->tdata.som_data = (struct som_data_struct *) - bfd_zalloc (abfd, sizeof (struct som_data_struct)); - if (abfd->tdata.som_data == NULL) - return false; - return true; -} - -/* Initialize some information in the file header. This routine makes - not attempt at doing the right thing for a full executable; it - is only meant to handle relocatable objects. */ - -static boolean -som_prep_headers (abfd) - bfd *abfd; -{ - struct header *file_hdr; - asection *section; - - /* Make and attach a file header to the BFD. */ - file_hdr = (struct header *) bfd_zalloc (abfd, sizeof (struct header)); - if (file_hdr == NULL) - return false; - obj_som_file_hdr (abfd) = file_hdr; - - if (abfd->flags & (EXEC_P | DYNAMIC)) - { - - /* Make and attach an exec header to the BFD. */ - obj_som_exec_hdr (abfd) = (struct som_exec_auxhdr *) - bfd_zalloc (abfd, sizeof (struct som_exec_auxhdr)); - if (obj_som_exec_hdr (abfd) == NULL) - return false; - - if (abfd->flags & D_PAGED) - file_hdr->a_magic = DEMAND_MAGIC; - else if (abfd->flags & WP_TEXT) - file_hdr->a_magic = SHARE_MAGIC; -#ifdef SHL_MAGIC - else if (abfd->flags & DYNAMIC) - file_hdr->a_magic = SHL_MAGIC; -#endif - else - file_hdr->a_magic = EXEC_MAGIC; - } - else - file_hdr->a_magic = RELOC_MAGIC; - - /* Only new format SOM is supported. */ - file_hdr->version_id = NEW_VERSION_ID; - - /* These fields are optional, and embedding timestamps is not always - a wise thing to do, it makes comparing objects during a multi-stage - bootstrap difficult. */ - file_hdr->file_time.secs = 0; - file_hdr->file_time.nanosecs = 0; - - file_hdr->entry_space = 0; - file_hdr->entry_subspace = 0; - file_hdr->entry_offset = 0; - file_hdr->presumed_dp = 0; - - /* Now iterate over the sections translating information from - BFD sections to SOM spaces/subspaces. */ - - for (section = abfd->sections; section != NULL; section = section->next) - { - /* Ignore anything which has not been marked as a space or - subspace. */ - if (!som_is_space (section) && !som_is_subspace (section)) - continue; - - if (som_is_space (section)) - { - /* Allocate space for the space dictionary. */ - som_section_data (section)->space_dict - = (struct space_dictionary_record *) - bfd_zalloc (abfd, sizeof (struct space_dictionary_record)); - if (som_section_data (section)->space_dict == NULL) - return false; - /* Set space attributes. Note most attributes of SOM spaces - are set based on the subspaces it contains. */ - som_section_data (section)->space_dict->loader_fix_index = -1; - som_section_data (section)->space_dict->init_pointer_index = -1; - - /* Set more attributes that were stuffed away in private data. */ - som_section_data (section)->space_dict->sort_key = - som_section_data (section)->copy_data->sort_key; - som_section_data (section)->space_dict->is_defined = - som_section_data (section)->copy_data->is_defined; - som_section_data (section)->space_dict->is_private = - som_section_data (section)->copy_data->is_private; - som_section_data (section)->space_dict->space_number = - som_section_data (section)->copy_data->space_number; - } - else - { - /* Allocate space for the subspace dictionary. */ - som_section_data (section)->subspace_dict - = (struct subspace_dictionary_record *) - bfd_zalloc (abfd, sizeof (struct subspace_dictionary_record)); - if (som_section_data (section)->subspace_dict == NULL) - return false; - - /* Set subspace attributes. Basic stuff is done here, additional - attributes are filled in later as more information becomes - available. */ - if (section->flags & SEC_IS_COMMON) - { - som_section_data (section)->subspace_dict->dup_common = 1; - som_section_data (section)->subspace_dict->is_common = 1; - } - - if (section->flags & SEC_ALLOC) - som_section_data (section)->subspace_dict->is_loadable = 1; - - if (section->flags & SEC_CODE) - som_section_data (section)->subspace_dict->code_only = 1; - - som_section_data (section)->subspace_dict->subspace_start = - section->vma; - som_section_data (section)->subspace_dict->subspace_length = - bfd_section_size (abfd, section); - som_section_data (section)->subspace_dict->initialization_length = - bfd_section_size (abfd, section); - som_section_data (section)->subspace_dict->alignment = - 1 << section->alignment_power; - - /* Set more attributes that were stuffed away in private data. */ - som_section_data (section)->subspace_dict->sort_key = - som_section_data (section)->copy_data->sort_key; - som_section_data (section)->subspace_dict->access_control_bits = - som_section_data (section)->copy_data->access_control_bits; - som_section_data (section)->subspace_dict->quadrant = - som_section_data (section)->copy_data->quadrant; - } - } - return true; -} - -/* Return true if the given section is a SOM space, false otherwise. */ - -static boolean -som_is_space (section) - asection *section; -{ - /* If no copy data is available, then it's neither a space nor a - subspace. */ - if (som_section_data (section)->copy_data == NULL) - return false; - - /* If the containing space isn't the same as the given section, - then this isn't a space. */ - if (som_section_data (section)->copy_data->container != section - && (som_section_data (section)->copy_data->container->output_section - != section)) - return false; - - /* OK. Must be a space. */ - return true; -} - -/* Return true if the given section is a SOM subspace, false otherwise. */ - -static boolean -som_is_subspace (section) - asection *section; -{ - /* If no copy data is available, then it's neither a space nor a - subspace. */ - if (som_section_data (section)->copy_data == NULL) - return false; - - /* If the containing space is the same as the given section, - then this isn't a subspace. */ - if (som_section_data (section)->copy_data->container == section - || (som_section_data (section)->copy_data->container->output_section - == section)) - return false; - - /* OK. Must be a subspace. */ - return true; -} - -/* Return true if the given space containins the given subspace. It - is safe to assume space really is a space, and subspace really - is a subspace. */ - -static boolean -som_is_container (space, subspace) - asection *space, *subspace; -{ - return (som_section_data (subspace)->copy_data->container == space - || (som_section_data (subspace)->copy_data->container->output_section - == space)); -} - -/* Count and return the number of spaces attached to the given BFD. */ - -static unsigned long -som_count_spaces (abfd) - bfd *abfd; -{ - int count = 0; - asection *section; - - for (section = abfd->sections; section != NULL; section = section->next) - count += som_is_space (section); - - return count; -} - -/* Count the number of subspaces attached to the given BFD. */ - -static unsigned long -som_count_subspaces (abfd) - bfd *abfd; -{ - int count = 0; - asection *section; - - for (section = abfd->sections; section != NULL; section = section->next) - count += som_is_subspace (section); - - return count; -} - -/* Return -1, 0, 1 indicating the relative ordering of sym1 and sym2. - - We desire symbols to be ordered starting with the symbol with the - highest relocation count down to the symbol with the lowest relocation - count. Doing so compacts the relocation stream. */ - -static int -compare_syms (arg1, arg2) - const PTR arg1; - const PTR arg2; - -{ - asymbol **sym1 = (asymbol **) arg1; - asymbol **sym2 = (asymbol **) arg2; - unsigned int count1, count2; - - /* Get relocation count for each symbol. Note that the count - is stored in the udata pointer for section symbols! */ - if ((*sym1)->flags & BSF_SECTION_SYM) - count1 = (*sym1)->udata.i; - else - count1 = som_symbol_data (*sym1)->reloc_count; - - if ((*sym2)->flags & BSF_SECTION_SYM) - count2 = (*sym2)->udata.i; - else - count2 = som_symbol_data (*sym2)->reloc_count; - - /* Return the appropriate value. */ - if (count1 < count2) - return 1; - else if (count1 > count2) - return -1; - return 0; -} - -/* Return -1, 0, 1 indicating the relative ordering of subspace1 - and subspace. */ - -static int -compare_subspaces (arg1, arg2) - const PTR arg1; - const PTR arg2; - -{ - asection **subspace1 = (asection **) arg1; - asection **subspace2 = (asection **) arg2; - unsigned int count1, count2; - - if ((*subspace1)->target_index < (*subspace2)->target_index) - return -1; - else if ((*subspace2)->target_index < (*subspace1)->target_index) - return 1; - else - return 0; -} - -/* Perform various work in preparation for emitting the fixup stream. */ - -static void -som_prep_for_fixups (abfd, syms, num_syms) - bfd *abfd; - asymbol **syms; - unsigned long num_syms; -{ - int i; - asection *section; - asymbol **sorted_syms; - - /* Most SOM relocations involving a symbol have a length which is - dependent on the index of the symbol. So symbols which are - used often in relocations should have a small index. */ - - /* First initialize the counters for each symbol. */ - for (i = 0; i < num_syms; i++) - { - /* Handle a section symbol; these have no pointers back to the - SOM symbol info. So we just use the udata field to hold the - relocation count. */ - if (som_symbol_data (syms[i]) == NULL - || syms[i]->flags & BSF_SECTION_SYM) - { - syms[i]->flags |= BSF_SECTION_SYM; - syms[i]->udata.i = 0; - } - else - som_symbol_data (syms[i])->reloc_count = 0; - } - - /* Now that the counters are initialized, make a weighted count - of how often a given symbol is used in a relocation. */ - for (section = abfd->sections; section != NULL; section = section->next) - { - int i; - - /* Does this section have any relocations? */ - if (section->reloc_count <= 0) - continue; - - /* Walk through each relocation for this section. */ - for (i = 1; i < section->reloc_count; i++) - { - arelent *reloc = section->orelocation[i]; - int scale; - - /* A relocation against a symbol in the *ABS* section really - does not have a symbol. Likewise if the symbol isn't associated - with any section. */ - if (reloc->sym_ptr_ptr == NULL - || bfd_is_abs_section ((*reloc->sym_ptr_ptr)->section)) - continue; - - /* Scaling to encourage symbols involved in R_DP_RELATIVE - and R_CODE_ONE_SYMBOL relocations to come first. These - two relocations have single byte versions if the symbol - index is very small. */ - if (reloc->howto->type == R_DP_RELATIVE - || reloc->howto->type == R_CODE_ONE_SYMBOL) - scale = 2; - else - scale = 1; - - /* Handle section symbols by storing the count in the udata - field. It will not be used and the count is very important - for these symbols. */ - if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM) - { - (*reloc->sym_ptr_ptr)->udata.i = - (*reloc->sym_ptr_ptr)->udata.i + scale; - continue; - } - - /* A normal symbol. Increment the count. */ - som_symbol_data (*reloc->sym_ptr_ptr)->reloc_count += scale; - } - } - - /* Sort a copy of the symbol table, rather than the canonical - output symbol table. */ - sorted_syms = (asymbol **) bfd_zalloc (abfd, num_syms * sizeof (asymbol *)); - memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *)); - qsort (sorted_syms, num_syms, sizeof (asymbol *), compare_syms); - obj_som_sorted_syms (abfd) = sorted_syms; - - /* Compute the symbol indexes, they will be needed by the relocation - code. */ - for (i = 0; i < num_syms; i++) - { - /* A section symbol. Again, there is no pointer to backend symbol - information, so we reuse the udata field again. */ - if (sorted_syms[i]->flags & BSF_SECTION_SYM) - sorted_syms[i]->udata.i = i; - else - som_symbol_data (sorted_syms[i])->index = i; - } -} - -static boolean -som_write_fixups (abfd, current_offset, total_reloc_sizep) - bfd *abfd; - unsigned long current_offset; - unsigned int *total_reloc_sizep; -{ - unsigned int i, j; - /* Chunk of memory that we can use as buffer space, then throw - away. */ - unsigned char tmp_space[SOM_TMP_BUFSIZE]; - unsigned char *p; - unsigned int total_reloc_size = 0; - unsigned int subspace_reloc_size = 0; - unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total; - asection *section = abfd->sections; - - memset (tmp_space, 0, SOM_TMP_BUFSIZE); - p = tmp_space; - - /* All the fixups for a particular subspace are emitted in a single - stream. All the subspaces for a particular space are emitted - as a single stream. - - So, to get all the locations correct one must iterate through all the - spaces, for each space iterate through its subspaces and output a - fixups stream. */ - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Now iterate through each of its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - int reloc_offset, current_rounding_mode; - - /* Find a subspace of this space. */ - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection)) - continue; - - /* If this subspace does not have real data, then we are - finised with it. */ - if ((subsection->flags & SEC_HAS_CONTENTS) == 0) - { - som_section_data (subsection)->subspace_dict->fixup_request_index - = -1; - continue; - } - - /* This subspace has some relocations. Put the relocation stream - index into the subspace record. */ - som_section_data (subsection)->subspace_dict->fixup_request_index - = total_reloc_size; - - /* To make life easier start over with a clean slate for - each subspace. Seek to the start of the relocation stream - for this subspace in preparation for writing out its fixup - stream. */ - if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) < 0) - return false; - - /* Buffer space has already been allocated. Just perform some - initialization here. */ - p = tmp_space; - subspace_reloc_size = 0; - reloc_offset = 0; - som_initialize_reloc_queue (reloc_queue); - current_rounding_mode = R_N_MODE; - - /* Translate each BFD relocation into one or more SOM - relocations. */ - for (j = 0; j < subsection->reloc_count; j++) - { - arelent *bfd_reloc = subsection->orelocation[j]; - unsigned int skip; - int sym_num; - - /* Get the symbol number. Remember it's stored in a - special place for section symbols. */ - if ((*bfd_reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM) - sym_num = (*bfd_reloc->sym_ptr_ptr)->udata.i; - else - sym_num = som_symbol_data (*bfd_reloc->sym_ptr_ptr)->index; - - /* If there is not enough room for the next couple relocations, - then dump the current buffer contents now. Also reinitialize - the relocation queue. - - No single BFD relocation could ever translate into more - than 100 bytes of SOM relocations (20bytes is probably the - upper limit, but leave lots of space for growth). */ - if (p - tmp_space + 100 > SOM_TMP_BUFSIZE) - { - if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - - p = tmp_space; - som_initialize_reloc_queue (reloc_queue); - } - - /* Emit R_NO_RELOCATION fixups to map any bytes which were - skipped. */ - skip = bfd_reloc->address - reloc_offset; - p = som_reloc_skip (abfd, skip, p, - &subspace_reloc_size, reloc_queue); - - /* Update reloc_offset for the next iteration. - - Many relocations do not consume input bytes. They - are markers, or set state necessary to perform some - later relocation. */ - switch (bfd_reloc->howto->type) - { - /* This only needs to handle relocations that may be - made by hppa_som_gen_reloc. */ - case R_ENTRY: - case R_ALT_ENTRY: - case R_EXIT: - case R_N_MODE: - case R_S_MODE: - case R_D_MODE: - case R_R_MODE: - case R_FSEL: - case R_LSEL: - case R_RSEL: - case R_COMP1: - case R_COMP2: - case R_BEGIN_BRTAB: - case R_END_BRTAB: - case R_N0SEL: - case R_N1SEL: - reloc_offset = bfd_reloc->address; - break; - - default: - reloc_offset = bfd_reloc->address + 4; - break; - } - - /* Now the actual relocation we care about. */ - switch (bfd_reloc->howto->type) - { - case R_PCREL_CALL: - case R_ABS_CALL: - p = som_reloc_call (abfd, p, &subspace_reloc_size, - bfd_reloc, sym_num, reloc_queue); - break; - - case R_CODE_ONE_SYMBOL: - case R_DP_RELATIVE: - /* Account for any addend. */ - if (bfd_reloc->addend) - p = som_reloc_addend (abfd, bfd_reloc->addend, p, - &subspace_reloc_size, reloc_queue); - - if (sym_num < 0x20) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + sym_num, p); - subspace_reloc_size += 1; - p += 1; - } - else if (sym_num < 0x100) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + 32, p); - bfd_put_8 (abfd, sym_num, p + 1); - p = try_prev_fixup (abfd, &subspace_reloc_size, p, - 2, reloc_queue); - } - else if (sym_num < 0x10000000) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + 33, p); - bfd_put_8 (abfd, sym_num >> 16, p + 1); - bfd_put_16 (abfd, sym_num, p + 2); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 4, reloc_queue); - } - else - abort (); - break; - - case R_DATA_ONE_SYMBOL: - case R_DATA_PLABEL: - case R_CODE_PLABEL: - case R_DLT_REL: - /* Account for any addend using R_DATA_OVERRIDE. */ - if (bfd_reloc->howto->type != R_DATA_ONE_SYMBOL - && bfd_reloc->addend) - p = som_reloc_addend (abfd, bfd_reloc->addend, p, - &subspace_reloc_size, reloc_queue); - - if (sym_num < 0x100) - { - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - bfd_put_8 (abfd, sym_num, p + 1); - p = try_prev_fixup (abfd, &subspace_reloc_size, p, - 2, reloc_queue); - } - else if (sym_num < 0x10000000) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p); - bfd_put_8 (abfd, sym_num >> 16, p + 1); - bfd_put_16 (abfd, sym_num, p + 2); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 4, reloc_queue); - } - else - abort (); - break; - - case R_ENTRY: - { - int tmp; - arelent *tmp_reloc = NULL; - bfd_put_8 (abfd, R_ENTRY, p); - - /* R_ENTRY relocations have 64 bits of associated - data. Unfortunately the addend field of a bfd - relocation is only 32 bits. So, we split up - the 64bit unwind information and store part in - the R_ENTRY relocation, and the rest in the R_EXIT - relocation. */ - bfd_put_32 (abfd, bfd_reloc->addend, p + 1); - - /* Find the next R_EXIT relocation. */ - for (tmp = j; tmp < subsection->reloc_count; tmp++) - { - tmp_reloc = subsection->orelocation[tmp]; - if (tmp_reloc->howto->type == R_EXIT) - break; - } - - if (tmp == subsection->reloc_count) - abort (); - - bfd_put_32 (abfd, tmp_reloc->addend, p + 5); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 9, reloc_queue); - break; - } - - case R_N_MODE: - case R_S_MODE: - case R_D_MODE: - case R_R_MODE: - /* If this relocation requests the current rounding - mode, then it is redundant. */ - if (bfd_reloc->howto->type != current_rounding_mode) - { - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - subspace_reloc_size += 1; - p += 1; - current_rounding_mode = bfd_reloc->howto->type; - } - break; - - case R_EXIT: - case R_ALT_ENTRY: - case R_FSEL: - case R_LSEL: - case R_RSEL: - case R_BEGIN_BRTAB: - case R_END_BRTAB: - case R_N0SEL: - case R_N1SEL: - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - subspace_reloc_size += 1; - p += 1; - break; - - case R_COMP1: - /* The only time we generate R_COMP1, R_COMP2 and - R_CODE_EXPR relocs is for the difference of two - symbols. Hence we can cheat here. */ - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - bfd_put_8 (abfd, 0x44, p + 1); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 2, reloc_queue); - break; - - case R_COMP2: - /* The only time we generate R_COMP1, R_COMP2 and - R_CODE_EXPR relocs is for the difference of two - symbols. Hence we can cheat here. */ - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - bfd_put_8 (abfd, 0x80, p + 1); - bfd_put_8 (abfd, sym_num >> 16, p + 2); - bfd_put_16 (abfd, sym_num, p + 3); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 5, reloc_queue); - break; - - case R_CODE_EXPR: - /* The only time we generate R_COMP1, R_COMP2 and - R_CODE_EXPR relocs is for the difference of two - symbols. Hence we can cheat here. */ - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - subspace_reloc_size += 1; - p += 1; - break; - - /* Put a "R_RESERVED" relocation in the stream if - we hit something we do not understand. The linker - will complain loudly if this ever happens. */ - default: - bfd_put_8 (abfd, 0xff, p); - subspace_reloc_size += 1; - p += 1; - break; - } - } - - /* Last BFD relocation for a subspace has been processed. - Map the rest of the subspace with R_NO_RELOCATION fixups. */ - p = som_reloc_skip (abfd, bfd_section_size (abfd, subsection) - - reloc_offset, - p, &subspace_reloc_size, reloc_queue); - - /* Scribble out the relocations. */ - if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - p = tmp_space; - - total_reloc_size += subspace_reloc_size; - som_section_data (subsection)->subspace_dict->fixup_request_quantity - = subspace_reloc_size; - } - section = section->next; - } - *total_reloc_sizep = total_reloc_size; - return true; -} - -/* Write out the space/subspace string table. */ - -static boolean -som_write_space_strings (abfd, current_offset, string_sizep) - bfd *abfd; - unsigned long current_offset; - unsigned int *string_sizep; -{ - /* Chunk of memory that we can use as buffer space, then throw - away. */ - unsigned char tmp_space[SOM_TMP_BUFSIZE]; - unsigned char *p; - unsigned int strings_size = 0; - asection *section; - - memset (tmp_space, 0, SOM_TMP_BUFSIZE); - p = tmp_space; - - /* Seek to the start of the space strings in preparation for writing - them out. */ - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - /* Walk through all the spaces and subspaces (order is not important) - building up and writing string table entries for their names. */ - for (section = abfd->sections; section != NULL; section = section->next) - { - int length; - - /* Only work with space/subspaces; avoid any other sections - which might have been made (.text for example). */ - if (!som_is_space (section) && !som_is_subspace (section)) - continue; - - /* Get the length of the space/subspace name. */ - length = strlen (section->name); - - /* If there is not enough room for the next entry, then dump the - current buffer contents now. Each entry will take 4 bytes to - hold the string length + the string itself + null terminator. */ - if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE) - { - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - /* Reset to beginning of the buffer space. */ - p = tmp_space; - } - - /* First element in a string table entry is the length of the - string. Alignment issues are already handled. */ - bfd_put_32 (abfd, length, p); - p += 4; - strings_size += 4; - - /* Record the index in the space/subspace records. */ - if (som_is_space (section)) - som_section_data (section)->space_dict->name.n_strx = strings_size; - else - som_section_data (section)->subspace_dict->name.n_strx = strings_size; - - /* Next comes the string itself + a null terminator. */ - strcpy (p, section->name); - p += length + 1; - strings_size += length + 1; - - /* Always align up to the next word boundary. */ - while (strings_size % 4) - { - bfd_put_8 (abfd, 0, p); - p++; - strings_size++; - } - } - - /* Done with the space/subspace strings. Write out any information - contained in a partial block. */ - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space) - return false; - *string_sizep = strings_size; - return true; -} - -/* Write out the symbol string table. */ - -static boolean -som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep) - bfd *abfd; - unsigned long current_offset; - asymbol **syms; - unsigned int num_syms; - unsigned int *string_sizep; -{ - unsigned int i; - - /* Chunk of memory that we can use as buffer space, then throw - away. */ - unsigned char tmp_space[SOM_TMP_BUFSIZE]; - unsigned char *p; - unsigned int strings_size = 0; - - memset (tmp_space, 0, SOM_TMP_BUFSIZE); - p = tmp_space; - - /* Seek to the start of the space strings in preparation for writing - them out. */ - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - for (i = 0; i < num_syms; i++) - { - int length = strlen (syms[i]->name); - - /* If there is not enough room for the next entry, then dump the - current buffer contents now. */ - if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE) - { - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - /* Reset to beginning of the buffer space. */ - p = tmp_space; - } - - /* First element in a string table entry is the length of the - string. This must always be 4 byte aligned. This is also - an appropriate time to fill in the string index field in the - symbol table entry. */ - bfd_put_32 (abfd, length, p); - strings_size += 4; - p += 4; - - /* Next comes the string itself + a null terminator. */ - strcpy (p, syms[i]->name); - - som_symbol_data(syms[i])->stringtab_offset = strings_size; - p += length + 1; - strings_size += length + 1; - - /* Always align up to the next word boundary. */ - while (strings_size % 4) - { - bfd_put_8 (abfd, 0, p); - strings_size++; - p++; - } - } - - /* Scribble out any partial block. */ - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space) - return false; - - *string_sizep = strings_size; - return true; -} - -/* Compute variable information to be placed in the SOM headers, - space/subspace dictionaries, relocation streams, etc. Begin - writing parts of the object file. */ - -static boolean -som_begin_writing (abfd) - bfd *abfd; -{ - unsigned long current_offset = 0; - int strings_size = 0; - unsigned int total_reloc_size = 0; - unsigned long num_spaces, num_subspaces, i; - asection *section; - unsigned int total_subspaces = 0; - struct som_exec_auxhdr *exec_header = NULL; - - /* The file header will always be first in an object file, - everything else can be in random locations. To keep things - "simple" BFD will lay out the object file in the manner suggested - by the PRO ABI for PA-RISC Systems. */ - - /* Before any output can really begin offsets for all the major - portions of the object file must be computed. So, starting - with the initial file header compute (and sometimes write) - each portion of the object file. */ - - /* Make room for the file header, it's contents are not complete - yet, so it can not be written at this time. */ - current_offset += sizeof (struct header); - - /* Any auxiliary headers will follow the file header. Right now - we support only the copyright and version headers. */ - obj_som_file_hdr (abfd)->aux_header_location = current_offset; - obj_som_file_hdr (abfd)->aux_header_size = 0; - if (abfd->flags & (EXEC_P | DYNAMIC)) - { - /* Parts of the exec header will be filled in later, so - delay writing the header itself. Fill in the defaults, - and write it later. */ - current_offset += sizeof (struct som_exec_auxhdr); - obj_som_file_hdr (abfd)->aux_header_size - += sizeof (struct som_exec_auxhdr); - exec_header = obj_som_exec_hdr (abfd); - exec_header->som_auxhdr.type = EXEC_AUX_ID; - exec_header->som_auxhdr.length = 40; - } - if (obj_som_version_hdr (abfd) != NULL) - { - unsigned int len; - - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - /* Write the aux_id structure and the string length. */ - len = sizeof (struct aux_id) + sizeof (unsigned int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_version_hdr (abfd), len, 1, abfd) != len) - return false; - - /* Write the version string. */ - len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_version_hdr (abfd)->user_string, - len, 1, abfd) != len) - return false; - } - - if (obj_som_copyright_hdr (abfd) != NULL) - { - unsigned int len; - - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - /* Write the aux_id structure and the string length. */ - len = sizeof (struct aux_id) + sizeof (unsigned int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_copyright_hdr (abfd), len, 1, abfd) != len) - return false; - - /* Write the copyright string. */ - len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_copyright_hdr (abfd)->copyright, - len, 1, abfd) != len) - return false; - } - - /* Next comes the initialization pointers; we have no initialization - pointers, so current offset does not change. */ - obj_som_file_hdr (abfd)->init_array_location = current_offset; - obj_som_file_hdr (abfd)->init_array_total = 0; - - /* Next are the space records. These are fixed length records. - - Count the number of spaces to determine how much room is needed - in the object file for the space records. - - The names of the spaces are stored in a separate string table, - and the index for each space into the string table is computed - below. Therefore, it is not possible to write the space headers - at this time. */ - num_spaces = som_count_spaces (abfd); - obj_som_file_hdr (abfd)->space_location = current_offset; - obj_som_file_hdr (abfd)->space_total = num_spaces; - current_offset += num_spaces * sizeof (struct space_dictionary_record); - - /* Next are the subspace records. These are fixed length records. - - Count the number of subspaes to determine how much room is needed - in the object file for the subspace records. - - A variety if fields in the subspace record are still unknown at - this time (index into string table, fixup stream location/size, etc). */ - num_subspaces = som_count_subspaces (abfd); - obj_som_file_hdr (abfd)->subspace_location = current_offset; - obj_som_file_hdr (abfd)->subspace_total = num_subspaces; - current_offset += num_subspaces * sizeof (struct subspace_dictionary_record); - - /* Next is the string table for the space/subspace names. We will - build and write the string table on the fly. At the same time - we will fill in the space/subspace name index fields. */ - - /* The string table needs to be aligned on a word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - - /* Mark the offset of the space/subspace string table in the - file header. */ - obj_som_file_hdr (abfd)->space_strings_location = current_offset; - - /* Scribble out the space strings. */ - if (som_write_space_strings (abfd, current_offset, &strings_size) == false) - return false; - - /* Record total string table size in the header and update the - current offset. */ - obj_som_file_hdr (abfd)->space_strings_size = strings_size; - current_offset += strings_size; - - /* Next is the compiler records. We do not use these. */ - obj_som_file_hdr (abfd)->compiler_location = current_offset; - obj_som_file_hdr (abfd)->compiler_total = 0; - - /* Now compute the file positions for the loadable subspaces, taking - care to make sure everything stays properly aligned. */ - - section = abfd->sections; - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - int first_subspace; - unsigned int subspace_offset = 0; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - first_subspace = 1; - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) == 0) - continue; - - /* If this is the first subspace in the space, and we are - building an executable, then take care to make sure all - the alignments are correct and update the exec header. */ - if (first_subspace - && (abfd->flags & (EXEC_P | DYNAMIC))) - { - /* Demand paged executables have each space aligned to a - page boundary. Sharable executables (write-protected - text) have just the private (aka data & bss) space aligned - to a page boundary. Ugh. Not true for HPUX. - - The HPUX kernel requires the text to always be page aligned - within the file regardless of the executable's type. */ - if (abfd->flags & (D_PAGED | DYNAMIC) - || (subsection->flags & SEC_CODE) - || ((abfd->flags & WP_TEXT) - && (subsection->flags & SEC_DATA))) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - - /* Update the exec header. */ - if (subsection->flags & SEC_CODE && exec_header->exec_tfile == 0) - { - exec_header->exec_tmem = section->vma; - exec_header->exec_tfile = current_offset; - } - if (subsection->flags & SEC_DATA && exec_header->exec_dfile == 0) - { - exec_header->exec_dmem = section->vma; - exec_header->exec_dfile = current_offset; - } - - /* Keep track of exactly where we are within a particular - space. This is necessary as the braindamaged HPUX - loader will create holes between subspaces *and* - subspace alignments are *NOT* preserved. What a crock. */ - subspace_offset = subsection->vma; - - /* Only do this for the first subspace within each space. */ - first_subspace = 0; - } - else if (abfd->flags & (EXEC_P | DYNAMIC)) - { - /* The braindamaged HPUX loader may have created a hole - between two subspaces. It is *not* sufficient to use - the alignment specifications within the subspaces to - account for these holes -- I've run into at least one - case where the loader left one code subspace unaligned - in a final executable. - - To combat this we keep a current offset within each space, - and use the subspace vma fields to detect and preserve - holes. What a crock! - - ps. This is not necessary for unloadable space/subspaces. */ - current_offset += subsection->vma - subspace_offset; - if (subsection->flags & SEC_CODE) - exec_header->exec_tsize += subsection->vma - subspace_offset; - else - exec_header->exec_dsize += subsection->vma - subspace_offset; - subspace_offset += subsection->vma - subspace_offset; - } - - - subsection->target_index = total_subspaces++; - /* This is real data to be loaded from the file. */ - if (subsection->flags & SEC_LOAD) - { - /* Update the size of the code & data. */ - if (abfd->flags & (EXEC_P | DYNAMIC) - && subsection->flags & SEC_CODE) - exec_header->exec_tsize += subsection->_cooked_size; - else if (abfd->flags & (EXEC_P | DYNAMIC) - && subsection->flags & SEC_DATA) - exec_header->exec_dsize += subsection->_cooked_size; - som_section_data (subsection)->subspace_dict->file_loc_init_value - = current_offset; - subsection->filepos = current_offset; - current_offset += bfd_section_size (abfd, subsection); - subspace_offset += bfd_section_size (abfd, subsection); - } - /* Looks like uninitialized data. */ - else - { - /* Update the size of the bss section. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - exec_header->exec_bsize += subsection->_cooked_size; - - som_section_data (subsection)->subspace_dict->file_loc_init_value - = 0; - som_section_data (subsection)->subspace_dict-> - initialization_length = 0; - } - } - /* Goto the next section. */ - section = section->next; - } - - /* Finally compute the file positions for unloadable subspaces. - If building an executable, start the unloadable stuff on its - own page. */ - - if (abfd->flags & (EXEC_P | DYNAMIC)) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - - obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset; - section = abfd->sections; - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - if (abfd->flags & (EXEC_P | DYNAMIC)) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) != 0) - continue; - - subsection->target_index = total_subspaces++; - /* This is real data to be loaded from the file. */ - if ((subsection->flags & SEC_LOAD) == 0) - { - som_section_data (subsection)->subspace_dict->file_loc_init_value - = current_offset; - subsection->filepos = current_offset; - current_offset += bfd_section_size (abfd, subsection); - } - /* Looks like uninitialized data. */ - else - { - som_section_data (subsection)->subspace_dict->file_loc_init_value - = 0; - som_section_data (subsection)->subspace_dict-> - initialization_length = bfd_section_size (abfd, subsection); - } - } - /* Goto the next section. */ - section = section->next; - } - - /* If building an executable, then make sure to seek to and write - one byte at the end of the file to make sure any necessary - zeros are filled in. Ugh. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - if (bfd_seek (abfd, current_offset - 1, SEEK_SET) < 0) - return false; - if (bfd_write ((PTR) "", 1, 1, abfd) != 1) - return false; - - obj_som_file_hdr (abfd)->unloadable_sp_size - = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location; - - /* Loader fixups are not supported in any way shape or form. */ - obj_som_file_hdr (abfd)->loader_fixup_location = 0; - obj_som_file_hdr (abfd)->loader_fixup_total = 0; - - /* Done. Store the total size of the SOM so far. */ - obj_som_file_hdr (abfd)->som_length = current_offset; - - return true; -} - -/* Finally, scribble out the various headers to the disk. */ - -static boolean -som_finish_writing (abfd) - bfd *abfd; -{ - int num_spaces = som_count_spaces (abfd); - asymbol **syms = bfd_get_outsymbols (abfd); - int i, num_syms, strings_size; - int subspace_index = 0; - file_ptr location; - asection *section; - unsigned long current_offset; - unsigned int total_reloc_size; - - /* Next is the symbol table. These are fixed length records. - - Count the number of symbols to determine how much room is needed - in the object file for the symbol table. - - The names of the symbols are stored in a separate string table, - and the index for each symbol name into the string table is computed - below. Therefore, it is not possible to write the symbol table - at this time. - - These used to be output before the subspace contents, but they - were moved here to work around a stupid bug in the hpux linker - (fixed in hpux10). */ - current_offset = obj_som_file_hdr (abfd)->som_length; - - /* Make sure we're on a word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - - num_syms = bfd_get_symcount (abfd); - obj_som_file_hdr (abfd)->symbol_location = current_offset; - obj_som_file_hdr (abfd)->symbol_total = num_syms; - current_offset += num_syms * sizeof (struct symbol_dictionary_record); - - /* Next are the symbol strings. - Align them to a word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - obj_som_file_hdr (abfd)->symbol_strings_location = current_offset; - - /* Scribble out the symbol strings. */ - if (som_write_symbol_strings (abfd, current_offset, syms, - num_syms, &strings_size) - == false) - return false; - - /* Record total string table size in header and update the - current offset. */ - obj_som_file_hdr (abfd)->symbol_strings_size = strings_size; - current_offset += strings_size; - - /* Do prep work before handling fixups. */ - som_prep_for_fixups (abfd, - bfd_get_outsymbols (abfd), - bfd_get_symcount (abfd)); - - /* At the end of the file is the fixup stream which starts on a - word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - obj_som_file_hdr (abfd)->fixup_request_location = current_offset; - - /* Write the fixups and update fields in subspace headers which - relate to the fixup stream. */ - if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false) - return false; - - /* Record the total size of the fixup stream in the file header. */ - obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size; - - /* Done. Store the total size of the SOM. */ - obj_som_file_hdr (abfd)->som_length = current_offset + total_reloc_size; - - /* Now that the symbol table information is complete, build and - write the symbol table. */ - if (som_build_and_write_symbol_table (abfd) == false) - return false; - - /* Subspaces are written first so that we can set up information - about them in their containing spaces as the subspace is written. */ - - /* Seek to the start of the subspace dictionary records. */ - location = obj_som_file_hdr (abfd)->subspace_location; - if (bfd_seek (abfd, location, SEEK_SET) < 0) - return false; - - section = abfd->sections; - /* Now for each loadable space write out records for its subspaces. */ - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - /* Skip any section which does not correspond to a space - or subspace. Or does not have SEC_ALLOC set (and therefore - has no real bits on the disk). */ - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) == 0) - continue; - - /* If this is the first subspace for this space, then save - the index of the subspace in its containing space. Also - set "is_loadable" in the containing space. */ - - if (som_section_data (section)->space_dict->subspace_quantity == 0) - { - som_section_data (section)->space_dict->is_loadable = 1; - som_section_data (section)->space_dict->subspace_index - = subspace_index; - } - - /* Increment the number of subspaces seen and the number of - subspaces contained within the current space. */ - subspace_index++; - som_section_data (section)->space_dict->subspace_quantity++; - - /* Mark the index of the current space within the subspace's - dictionary record. */ - som_section_data (subsection)->subspace_dict->space_index = i; - - /* Dump the current subspace header. */ - if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict, - sizeof (struct subspace_dictionary_record), 1, abfd) - != sizeof (struct subspace_dictionary_record)) - return false; - } - /* Goto the next section. */ - section = section->next; - } - - /* Now repeat the process for unloadable subspaces. */ - section = abfd->sections; - /* Now for each space write out records for its subspaces. */ - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - /* Skip any section which does not correspond to a space or - subspace, or which SEC_ALLOC set (and therefore handled - in the loadable spaces/subspaces code above). */ - - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) != 0) - continue; - - /* If this is the first subspace for this space, then save - the index of the subspace in its containing space. Clear - "is_loadable". */ - - if (som_section_data (section)->space_dict->subspace_quantity == 0) - { - som_section_data (section)->space_dict->is_loadable = 0; - som_section_data (section)->space_dict->subspace_index - = subspace_index; - } - - /* Increment the number of subspaces seen and the number of - subspaces contained within the current space. */ - som_section_data (section)->space_dict->subspace_quantity++; - subspace_index++; - - /* Mark the index of the current space within the subspace's - dictionary record. */ - som_section_data (subsection)->subspace_dict->space_index = i; - - /* Dump this subspace header. */ - if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict, - sizeof (struct subspace_dictionary_record), 1, abfd) - != sizeof (struct subspace_dictionary_record)) - return false; - } - /* Goto the next section. */ - section = section->next; - } - - /* All the subspace dictiondary records are written, and all the - fields are set up in the space dictionary records. - - Seek to the right location and start writing the space - dictionary records. */ - location = obj_som_file_hdr (abfd)->space_location; - if (bfd_seek (abfd, location, SEEK_SET) < 0) - return false; - - section = abfd->sections; - for (i = 0; i < num_spaces; i++) - { - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Dump its header */ - if (bfd_write ((PTR) som_section_data (section)->space_dict, - sizeof (struct space_dictionary_record), 1, abfd) - != sizeof (struct space_dictionary_record)) - return false; - - /* Goto the next section. */ - section = section->next; - } - - /* Setting of the system_id has to happen very late now that copying of - BFD private data happens *after* section contents are set. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - obj_som_file_hdr(abfd)->system_id = obj_som_exec_data (abfd)->system_id; - else if (bfd_get_mach (abfd) == pa11) - obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC1_1; - else - obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC1_0; - - /* Compute the checksum for the file header just before writing - the header to disk. */ - obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd); - - /* Only thing left to do is write out the file header. It is always - at location zero. Seek there and write it. */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0) - return false; - if (bfd_write ((PTR) obj_som_file_hdr (abfd), - sizeof (struct header), 1, abfd) - != sizeof (struct header)) - return false; - - /* Now write the exec header. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - { - long tmp; - struct som_exec_auxhdr *exec_header; - - exec_header = obj_som_exec_hdr (abfd); - exec_header->exec_entry = bfd_get_start_address (abfd); - exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags; - - /* Oh joys. Ram some of the BSS data into the DATA section - to be compatable with how the hp linker makes objects - (saves memory space). */ - tmp = exec_header->exec_dsize; - tmp = SOM_ALIGN (tmp, PA_PAGESIZE); - exec_header->exec_bsize -= (tmp - exec_header->exec_dsize); - if (exec_header->exec_bsize < 0) - exec_header->exec_bsize = 0; - exec_header->exec_dsize = tmp; - - if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location, - SEEK_SET) < 0) - return false; - - if (bfd_write ((PTR) exec_header, AUX_HDR_SIZE, 1, abfd) - != AUX_HDR_SIZE) - return false; - } - return true; -} - -/* Compute and return the checksum for a SOM file header. */ - -static unsigned long -som_compute_checksum (abfd) - bfd *abfd; -{ - unsigned long checksum, count, i; - unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd); - - checksum = 0; - count = sizeof (struct header) / sizeof (unsigned long); - for (i = 0; i < count; i++) - checksum ^= *(buffer + i); - - return checksum; -} - -static void -som_bfd_derive_misc_symbol_info (abfd, sym, info) - bfd *abfd; - asymbol *sym; - struct som_misc_symbol_info *info; -{ - /* Initialize. */ - memset (info, 0, sizeof (struct som_misc_symbol_info)); - - /* The HP SOM linker requires detailed type information about - all symbols (including undefined symbols!). Unfortunately, - the type specified in an import/export statement does not - always match what the linker wants. Severe braindamage. */ - - /* Section symbols will not have a SOM symbol type assigned to - them yet. Assign all section symbols type ST_DATA. */ - if (sym->flags & BSF_SECTION_SYM) - info->symbol_type = ST_DATA; - else - { - /* Common symbols must have scope SS_UNSAT and type - ST_STORAGE or the linker will choke. */ - if (bfd_is_com_section (sym->section)) - { - info->symbol_scope = SS_UNSAT; - info->symbol_type = ST_STORAGE; - } - - /* It is possible to have a symbol without an associated - type. This happens if the user imported the symbol - without a type and the symbol was never defined - locally. If BSF_FUNCTION is set for this symbol, then - assign it type ST_CODE (the HP linker requires undefined - external functions to have type ST_CODE rather than ST_ENTRY). */ - else if ((som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN - || som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE) - && bfd_is_und_section (sym->section) - && sym->flags & BSF_FUNCTION) - info->symbol_type = ST_CODE; - - /* Handle function symbols which were defined in this file. - They should have type ST_ENTRY. Also retrieve the argument - relocation bits from the SOM backend information. */ - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY - || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE - && (sym->flags & BSF_FUNCTION)) - || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN - && (sym->flags & BSF_FUNCTION))) - { - info->symbol_type = ST_ENTRY; - info->arg_reloc = som_symbol_data (sym)->tc_data.hppa_arg_reloc; - } - - /* If the type is unknown at this point, it should be ST_DATA or - ST_CODE (function/ST_ENTRY symbols were handled as special - cases above). */ - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN) - { - if (sym->section->flags & SEC_CODE) - info->symbol_type = ST_CODE; - else - info->symbol_type = ST_DATA; - } - - /* From now on it's a very simple mapping. */ - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE) - info->symbol_type = ST_ABSOLUTE; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE) - info->symbol_type = ST_CODE; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_DATA) - info->symbol_type = ST_DATA; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_MILLICODE) - info->symbol_type = ST_MILLICODE; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PLABEL) - info->symbol_type = ST_PLABEL; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PRI_PROG) - info->symbol_type = ST_PRI_PROG; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_SEC_PROG) - info->symbol_type = ST_SEC_PROG; - } - - /* Now handle the symbol's scope. Exported data which is not - in the common section has scope SS_UNIVERSAL. Note scope - of common symbols was handled earlier! */ - if (bfd_is_und_section (sym->section)) - info->symbol_scope = SS_UNSAT; - else if (sym->flags & BSF_EXPORT && ! bfd_is_com_section (sym->section)) - info->symbol_scope = SS_UNIVERSAL; - /* Anything else which is not in the common section has scope - SS_LOCAL. */ - else if (! bfd_is_com_section (sym->section)) - info->symbol_scope = SS_LOCAL; - - /* Now set the symbol_info field. It has no real meaning - for undefined or common symbols, but the HP linker will - choke if it's not set to some "reasonable" value. We - use zero as a reasonable value. */ - if (bfd_is_com_section (sym->section) - || bfd_is_und_section (sym->section) - || bfd_is_abs_section (sym->section)) - info->symbol_info = 0; - /* For all other symbols, the symbol_info field contains the - subspace index of the space this symbol is contained in. */ - else - info->symbol_info = sym->section->target_index; - - /* Set the symbol's value. */ - info->symbol_value = sym->value + sym->section->vma; -} - -/* Build and write, in one big chunk, the entire symbol table for - this BFD. */ - -static boolean -som_build_and_write_symbol_table (abfd) - bfd *abfd; -{ - unsigned int num_syms = bfd_get_symcount (abfd); - file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location; - asymbol **bfd_syms = obj_som_sorted_syms (abfd); - struct symbol_dictionary_record *som_symtab = NULL; - int i, symtab_size; - - /* Compute total symbol table size and allocate a chunk of memory - to hold the symbol table as we build it. */ - symtab_size = num_syms * sizeof (struct symbol_dictionary_record); - som_symtab = (struct symbol_dictionary_record *) bfd_malloc (symtab_size); - if (som_symtab == NULL && symtab_size != 0) - goto error_return; - memset (som_symtab, 0, symtab_size); - - /* Walk over each symbol. */ - for (i = 0; i < num_syms; i++) - { - struct som_misc_symbol_info info; - - /* This is really an index into the symbol strings table. - By the time we get here, the index has already been - computed and stored into the name field in the BFD symbol. */ - som_symtab[i].name.n_strx = som_symbol_data(bfd_syms[i])->stringtab_offset; - - /* Derive SOM information from the BFD symbol. */ - som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info); - - /* Now use it. */ - som_symtab[i].symbol_type = info.symbol_type; - som_symtab[i].symbol_scope = info.symbol_scope; - som_symtab[i].arg_reloc = info.arg_reloc; - som_symtab[i].symbol_info = info.symbol_info; - som_symtab[i].symbol_value = info.symbol_value; - } - - /* Everything is ready, seek to the right location and - scribble out the symbol table. */ - if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0) - return false; - - if (bfd_write ((PTR) som_symtab, symtab_size, 1, abfd) != symtab_size) - goto error_return; - - if (som_symtab != NULL) - free (som_symtab); - return true; - error_return: - if (som_symtab != NULL) - free (som_symtab); - return false; -} - -/* Write an object in SOM format. */ - -static boolean -som_write_object_contents (abfd) - bfd *abfd; -{ - if (abfd->output_has_begun == false) - { - /* Set up fixed parts of the file, space, and subspace headers. - Notify the world that output has begun. */ - som_prep_headers (abfd); - abfd->output_has_begun = true; - /* Start writing the object file. This include all the string - tables, fixup streams, and other portions of the object file. */ - som_begin_writing (abfd); - } - - return (som_finish_writing (abfd)); -} - - -/* Read and save the string table associated with the given BFD. */ - -static boolean -som_slurp_string_table (abfd) - bfd *abfd; -{ - char *stringtab; - - /* Use the saved version if its available. */ - if (obj_som_stringtab (abfd) != NULL) - return true; - - /* I don't think this can currently happen, and I'm not sure it should - really be an error, but it's better than getting unpredictable results - from the host's malloc when passed a size of zero. */ - if (obj_som_stringtab_size (abfd) == 0) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - /* Allocate and read in the string table. */ - stringtab = bfd_malloc (obj_som_stringtab_size (abfd)); - if (stringtab == NULL) - return false; - memset (stringtab, 0, obj_som_stringtab_size (abfd)); - - if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0) - return false; - - if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd) - != obj_som_stringtab_size (abfd)) - return false; - - /* Save our results and return success. */ - obj_som_stringtab (abfd) = stringtab; - return true; -} - -/* Return the amount of data (in bytes) required to hold the symbol - table for this object. */ - -static long -som_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - if (!som_slurp_symbol_table (abfd)) - return -1; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *)); -} - -/* Convert from a SOM subspace index to a BFD section. */ - -static asection * -bfd_section_from_som_symbol (abfd, symbol) - bfd *abfd; - struct symbol_dictionary_record *symbol; -{ - asection *section; - - /* The meaning of the symbol_info field changes for functions - within executables. So only use the quick symbol_info mapping for - incomplete objects and non-function symbols in executables. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 - || (symbol->symbol_type != ST_ENTRY - && symbol->symbol_type != ST_PRI_PROG - && symbol->symbol_type != ST_SEC_PROG - && symbol->symbol_type != ST_MILLICODE)) - { - unsigned int index = symbol->symbol_info; - for (section = abfd->sections; section != NULL; section = section->next) - if (section->target_index == index && som_is_subspace (section)) - return section; - - /* Could be a symbol from an external library (such as an OMOS - shared library). Don't abort. */ - return bfd_abs_section_ptr; - - } - else - { - unsigned int value = symbol->symbol_value; - - /* For executables we will have to use the symbol's address and - find out what section would contain that address. Yuk. */ - for (section = abfd->sections; section; section = section->next) - { - if (value >= section->vma - && value <= section->vma + section->_cooked_size - && som_is_subspace (section)) - return section; - } - - /* Could be a symbol from an external library (such as an OMOS - shared library). Don't abort. */ - return bfd_abs_section_ptr; - - } -} - -/* Read and save the symbol table associated with the given BFD. */ - -static unsigned int -som_slurp_symbol_table (abfd) - bfd *abfd; -{ - int symbol_count = bfd_get_symcount (abfd); - int symsize = sizeof (struct symbol_dictionary_record); - char *stringtab; - struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp; - som_symbol_type *sym, *symbase; - - /* Return saved value if it exists. */ - if (obj_som_symtab (abfd) != NULL) - goto successful_return; - - /* Special case. This is *not* an error. */ - if (symbol_count == 0) - goto successful_return; - - if (!som_slurp_string_table (abfd)) - goto error_return; - - stringtab = obj_som_stringtab (abfd); - - symbase = ((som_symbol_type *) - bfd_malloc (symbol_count * sizeof (som_symbol_type))); - if (symbase == NULL) - goto error_return; - memset (symbase, 0, symbol_count * sizeof (som_symbol_type)); - - /* Read in the external SOM representation. */ - buf = bfd_malloc (symbol_count * symsize); - if (buf == NULL && symbol_count * symsize != 0) - goto error_return; - if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0) - goto error_return; - if (bfd_read (buf, symbol_count * symsize, 1, abfd) - != symbol_count * symsize) - goto error_return; - - /* Iterate over all the symbols and internalize them. */ - endbufp = buf + symbol_count; - for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp) - { - - /* I don't think we care about these. */ - if (bufp->symbol_type == ST_SYM_EXT - || bufp->symbol_type == ST_ARG_EXT) - continue; - - /* Set some private data we care about. */ - if (bufp->symbol_type == ST_NULL) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN; - else if (bufp->symbol_type == ST_ABSOLUTE) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE; - else if (bufp->symbol_type == ST_DATA) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA; - else if (bufp->symbol_type == ST_CODE) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE; - else if (bufp->symbol_type == ST_PRI_PROG) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG; - else if (bufp->symbol_type == ST_SEC_PROG) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG; - else if (bufp->symbol_type == ST_ENTRY) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY; - else if (bufp->symbol_type == ST_MILLICODE) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE; - else if (bufp->symbol_type == ST_PLABEL) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL; - else - som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN; - som_symbol_data (sym)->tc_data.hppa_arg_reloc = bufp->arg_reloc; - - /* Some reasonable defaults. */ - sym->symbol.the_bfd = abfd; - sym->symbol.name = bufp->name.n_strx + stringtab; - sym->symbol.value = bufp->symbol_value; - sym->symbol.section = 0; - sym->symbol.flags = 0; - - switch (bufp->symbol_type) - { - case ST_ENTRY: - case ST_MILLICODE: - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.value &= ~0x3; - break; - - case ST_STUB: - case ST_CODE: - case ST_PRI_PROG: - case ST_SEC_PROG: - sym->symbol.value &= ~0x3; - /* If the symbol's scope is ST_UNSAT, then these are - undefined function symbols. */ - if (bufp->symbol_scope == SS_UNSAT) - sym->symbol.flags |= BSF_FUNCTION; - - - default: - break; - } - - /* Handle scoping and section information. */ - switch (bufp->symbol_scope) - { - /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols, - so the section associated with this symbol can't be known. */ - case SS_EXTERNAL: - if (bufp->symbol_type != ST_STORAGE) - sym->symbol.section = bfd_und_section_ptr; - else - sym->symbol.section = bfd_com_section_ptr; - sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL); - break; - - case SS_UNSAT: - if (bufp->symbol_type != ST_STORAGE) - sym->symbol.section = bfd_und_section_ptr; - else - sym->symbol.section = bfd_com_section_ptr; - break; - - case SS_UNIVERSAL: - sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL); - sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp); - sym->symbol.value -= sym->symbol.section->vma; - break; - -#if 0 - /* SS_GLOBAL and SS_LOCAL are two names for the same thing. - Sound dumb? It is. */ - case SS_GLOBAL: -#endif - case SS_LOCAL: - sym->symbol.flags |= BSF_LOCAL; - sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp); - sym->symbol.value -= sym->symbol.section->vma; - break; - } - - /* Mark section symbols and symbols used by the debugger. - Note $START$ is a magic code symbol, NOT a section symbol. */ - if (sym->symbol.name[0] == '$' - && sym->symbol.name[strlen (sym->symbol.name) - 1] == '$' - && !strcmp (sym->symbol.name, sym->symbol.section->name)) - sym->symbol.flags |= BSF_SECTION_SYM; - else if (!strncmp (sym->symbol.name, "L$0\002", 4)) - { - sym->symbol.flags |= BSF_SECTION_SYM; - sym->symbol.name = sym->symbol.section->name; - } - else if (!strncmp (sym->symbol.name, "L$0\001", 4)) - sym->symbol.flags |= BSF_DEBUGGING; - - /* Note increment at bottom of loop, since we skip some symbols - we can not include it as part of the for statement. */ - sym++; - } - - /* Save our results and return success. */ - obj_som_symtab (abfd) = symbase; - successful_return: - if (buf != NULL) - free (buf); - return (true); - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Canonicalize a SOM symbol table. Return the number of entries - in the symbol table. */ - -static long -som_get_symtab (abfd, location) - bfd *abfd; - asymbol **location; -{ - int i; - som_symbol_type *symbase; - - if (!som_slurp_symbol_table (abfd)) - return -1; - - i = bfd_get_symcount (abfd); - symbase = obj_som_symtab (abfd); - - for (; i > 0; i--, location++, symbase++) - *location = &symbase->symbol; - - /* Final null pointer. */ - *location = 0; - return (bfd_get_symcount (abfd)); -} - -/* Make a SOM symbol. There is nothing special to do here. */ - -static asymbol * -som_make_empty_symbol (abfd) - bfd *abfd; -{ - som_symbol_type *new = - (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type)); - if (new == NULL) - return 0; - new->symbol.the_bfd = abfd; - - return &new->symbol; -} - -/* Print symbol information. */ - -static void -som_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - fprintf (file, "som "); - fprintf_vma (file, symbol->value); - fprintf (file, " %lx", (long) symbol->flags); - break; - case bfd_print_symbol_all: - { - CONST char *section_name; - section_name = symbol->section ? symbol->section->name : "(*none*)"; - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %s\t%s", section_name, symbol->name); - break; - } - } -} - -static boolean -som_bfd_is_local_label (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return (sym->name[0] == 'L' && sym->name[1] == '$'); -} - -/* Count or process variable-length SOM fixup records. - - To avoid code duplication we use this code both to compute the number - of relocations requested by a stream, and to internalize the stream. - - When computing the number of relocations requested by a stream the - variables rptr, section, and symbols have no meaning. - - Return the number of relocations requested by the fixup stream. When - not just counting - - This needs at least two or three more passes to get it cleaned up. */ - -static unsigned int -som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count) - unsigned char *fixup; - unsigned int end; - arelent *internal_relocs; - asection *section; - asymbol **symbols; - boolean just_count; -{ - unsigned int op, varname, deallocate_contents = 0; - unsigned char *end_fixups = &fixup[end]; - const struct fixup_format *fp; - char *cp; - unsigned char *save_fixup; - int variables[26], stack[20], c, v, count, prev_fixup, *sp, saved_unwind_bits; - const int *subop; - arelent *rptr= internal_relocs; - unsigned int offset = 0; - -#define var(c) variables[(c) - 'A'] -#define push(v) (*sp++ = (v)) -#define pop() (*--sp) -#define emptystack() (sp == stack) - - som_initialize_reloc_queue (reloc_queue); - memset (variables, 0, sizeof (variables)); - memset (stack, 0, sizeof (stack)); - count = 0; - prev_fixup = 0; - saved_unwind_bits = 0; - sp = stack; - - while (fixup < end_fixups) - { - - /* Save pointer to the start of this fixup. We'll use - it later to determine if it is necessary to put this fixup - on the queue. */ - save_fixup = fixup; - - /* Get the fixup code and its associated format. */ - op = *fixup++; - fp = &som_fixup_formats[op]; - - /* Handle a request for a previous fixup. */ - if (*fp->format == 'P') - { - /* Get pointer to the beginning of the prev fixup, move - the repeated fixup to the head of the queue. */ - fixup = reloc_queue[fp->D].reloc; - som_reloc_queue_fix (reloc_queue, fp->D); - prev_fixup = 1; - - /* Get the fixup code and its associated format. */ - op = *fixup++; - fp = &som_fixup_formats[op]; - } - - /* If this fixup will be passed to BFD, set some reasonable defaults. */ - if (! just_count - && som_hppa_howto_table[op].type != R_NO_RELOCATION - && som_hppa_howto_table[op].type != R_DATA_OVERRIDE) - { - rptr->address = offset; - rptr->howto = &som_hppa_howto_table[op]; - rptr->addend = 0; - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - /* Set default input length to 0. Get the opcode class index - into D. */ - var ('L') = 0; - var ('D') = fp->D; - var ('U') = saved_unwind_bits; - - /* Get the opcode format. */ - cp = fp->format; - - /* Process the format string. Parsing happens in two phases, - parse RHS, then assign to LHS. Repeat until no more - characters in the format string. */ - while (*cp) - { - /* The variable this pass is going to compute a value for. */ - varname = *cp++; - - /* Start processing RHS. Continue until a NULL or '=' is found. */ - do - { - c = *cp++; - - /* If this is a variable, push it on the stack. */ - if (isupper (c)) - push (var (c)); - - /* If this is a lower case letter, then it represents - additional data from the fixup stream to be pushed onto - the stack. */ - else if (islower (c)) - { - int bits = (c - 'a') * 8; - for (v = 0; c > 'a'; --c) - v = (v << 8) | *fixup++; - if (varname == 'V') - v = sign_extend (v, bits); - push (v); - } - - /* A decimal constant. Push it on the stack. */ - else if (isdigit (c)) - { - v = c - '0'; - while (isdigit (*cp)) - v = (v * 10) + (*cp++ - '0'); - push (v); - } - else - - /* An operator. Pop two two values from the stack and - use them as operands to the given operation. Push - the result of the operation back on the stack. */ - switch (c) - { - case '+': - v = pop (); - v += pop (); - push (v); - break; - case '*': - v = pop (); - v *= pop (); - push (v); - break; - case '<': - v = pop (); - v = pop () << v; - push (v); - break; - default: - abort (); - } - } - while (*cp && *cp != '='); - - /* Move over the equal operator. */ - cp++; - - /* Pop the RHS off the stack. */ - c = pop (); - - /* Perform the assignment. */ - var (varname) = c; - - /* Handle side effects. and special 'O' stack cases. */ - switch (varname) - { - /* Consume some bytes from the input space. */ - case 'L': - offset += c; - break; - /* A symbol to use in the relocation. Make a note - of this if we are not just counting. */ - case 'S': - if (! just_count) - rptr->sym_ptr_ptr = &symbols[c]; - break; - /* Argument relocation bits for a function call. */ - case 'R': - if (! just_count) - { - unsigned int tmp = var ('R'); - rptr->addend = 0; - - if ((som_hppa_howto_table[op].type == R_PCREL_CALL - && R_PCREL_CALL + 10 > op) - || (som_hppa_howto_table[op].type == R_ABS_CALL - && R_ABS_CALL + 10 > op)) - { - /* Simple encoding. */ - if (tmp > 4) - { - tmp -= 5; - rptr->addend |= 1; - } - if (tmp == 4) - rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2; - else if (tmp == 3) - rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4; - else if (tmp == 2) - rptr->addend |= 1 << 8 | 1 << 6; - else if (tmp == 1) - rptr->addend |= 1 << 8; - } - else - { - unsigned int tmp1, tmp2; - - /* First part is easy -- low order two bits are - directly copied, then shifted away. */ - rptr->addend = tmp & 0x3; - tmp >>= 2; - - /* Diving the result by 10 gives us the second - part. If it is 9, then the first two words - are a double precision paramater, else it is - 3 * the first arg bits + the 2nd arg bits. */ - tmp1 = tmp / 10; - tmp -= tmp1 * 10; - if (tmp1 == 9) - rptr->addend += (0xe << 6); - else - { - /* Get the two pieces. */ - tmp2 = tmp1 / 3; - tmp1 -= tmp2 * 3; - /* Put them in the addend. */ - rptr->addend += (tmp2 << 8) + (tmp1 << 6); - } - - /* What's left is the third part. It's unpacked - just like the second. */ - if (tmp == 9) - rptr->addend += (0xe << 2); - else - { - tmp2 = tmp / 3; - tmp -= tmp2 * 3; - rptr->addend += (tmp2 << 4) + (tmp << 2); - } - } - rptr->addend = HPPA_R_ADDEND (rptr->addend, 0); - } - break; - /* Handle the linker expression stack. */ - case 'O': - switch (op) - { - case R_COMP1: - subop = comp1_opcodes; - break; - case R_COMP2: - subop = comp2_opcodes; - break; - case R_COMP3: - subop = comp3_opcodes; - break; - default: - abort (); - } - while (*subop <= (unsigned char) c) - ++subop; - --subop; - break; - /* The lower 32unwind bits must be persistent. */ - case 'U': - saved_unwind_bits = var ('U'); - break; - - default: - break; - } - } - - /* If we used a previous fixup, clean up after it. */ - if (prev_fixup) - { - fixup = save_fixup + 1; - prev_fixup = 0; - } - /* Queue it. */ - else if (fixup > save_fixup + 1) - som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue); - - /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION - fixups to BFD. */ - if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE - && som_hppa_howto_table[op].type != R_NO_RELOCATION) - { - /* Done with a single reloction. Loop back to the top. */ - if (! just_count) - { - if (som_hppa_howto_table[op].type == R_ENTRY) - rptr->addend = var ('T'); - else if (som_hppa_howto_table[op].type == R_EXIT) - rptr->addend = var ('U'); - else if (som_hppa_howto_table[op].type == R_PCREL_CALL - || som_hppa_howto_table[op].type == R_ABS_CALL) - ; - else if (som_hppa_howto_table[op].type == R_DATA_ONE_SYMBOL) - { - unsigned addend = var ('V'); - - /* Try what was specified in R_DATA_OVERRIDE first - (if anything). Then the hard way using the - section contents. */ - rptr->addend = var ('V'); - - if (rptr->addend == 0 && !section->contents) - { - /* Got to read the damn contents first. We don't - bother saving the contents (yet). Add it one - day if the need arises. */ - section->contents = bfd_malloc (section->_raw_size); - if (section->contents == NULL) - return -1; - - deallocate_contents = 1; - bfd_get_section_contents (section->owner, - section, - section->contents, - 0, - section->_raw_size); - } - else if (rptr->addend == 0) - rptr->addend = bfd_get_32 (section->owner, - (section->contents - + offset - var ('L'))); - - } - else - rptr->addend = var ('V'); - rptr++; - } - count++; - /* Now that we've handled a "full" relocation, reset - some state. */ - memset (variables, 0, sizeof (variables)); - memset (stack, 0, sizeof (stack)); - } - } - if (deallocate_contents) - free (section->contents); - - return count; - -#undef var -#undef push -#undef pop -#undef emptystack -} - -/* Read in the relocs (aka fixups in SOM terms) for a section. - - som_get_reloc_upper_bound calls this routine with JUST_COUNT - set to true to indicate it only needs a count of the number - of actual relocations. */ - -static boolean -som_slurp_reloc_table (abfd, section, symbols, just_count) - bfd *abfd; - asection *section; - asymbol **symbols; - boolean just_count; -{ - char *external_relocs; - unsigned int fixup_stream_size; - arelent *internal_relocs; - unsigned int num_relocs; - - fixup_stream_size = som_section_data (section)->reloc_size; - /* If there were no relocations, then there is nothing to do. */ - if (section->reloc_count == 0) - return true; - - /* If reloc_count is -1, then the relocation stream has not been - parsed. We must do so now to know how many relocations exist. */ - if (section->reloc_count == -1) - { - external_relocs = (char *) bfd_malloc (fixup_stream_size); - if (external_relocs == (char *) NULL) - return false; - /* Read in the external forms. */ - if (bfd_seek (abfd, - obj_som_reloc_filepos (abfd) + section->rel_filepos, - SEEK_SET) - != 0) - return false; - if (bfd_read (external_relocs, 1, fixup_stream_size, abfd) - != fixup_stream_size) - return false; - - /* Let callers know how many relocations found. - also save the relocation stream as we will - need it again. */ - section->reloc_count = som_set_reloc_info (external_relocs, - fixup_stream_size, - NULL, NULL, NULL, true); - - som_section_data (section)->reloc_stream = external_relocs; - } - - /* If the caller only wanted a count, then return now. */ - if (just_count) - return true; - - num_relocs = section->reloc_count; - external_relocs = som_section_data (section)->reloc_stream; - /* Return saved information about the relocations if it is available. */ - if (section->relocation != (arelent *) NULL) - return true; - - internal_relocs = (arelent *) - bfd_zalloc (abfd, (num_relocs * sizeof (arelent))); - if (internal_relocs == (arelent *) NULL) - return false; - - /* Process and internalize the relocations. */ - som_set_reloc_info (external_relocs, fixup_stream_size, - internal_relocs, section, symbols, false); - - /* We're done with the external relocations. Free them. */ - free (external_relocs); - - /* Save our results and return success. */ - section->relocation = internal_relocs; - return (true); -} - -/* Return the number of bytes required to store the relocation - information associated with the given section. */ - -static long -som_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - /* If section has relocations, then read in the relocation stream - and parse it to determine how many relocations exist. */ - if (asect->flags & SEC_RELOC) - { - if (! som_slurp_reloc_table (abfd, asect, NULL, true)) - return -1; - return (asect->reloc_count + 1) * sizeof (arelent *); - } - /* There are no relocations. */ - return 0; -} - -/* Convert relocations from SOM (external) form into BFD internal - form. Return the number of relocations. */ - -static long -som_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr; - int count; - - if (som_slurp_reloc_table (abfd, section, symbols, false) == false) - return -1; - - count = section->reloc_count; - tblptr = section->relocation; - - while (count--) - *relptr++ = tblptr++; - - *relptr = (arelent *) NULL; - return section->reloc_count; -} - -extern const bfd_target som_vec; - -/* A hook to set up object file dependent section information. */ - -static boolean -som_new_section_hook (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - newsect->used_by_bfd = - (PTR) bfd_zalloc (abfd, sizeof (struct som_section_data_struct)); - if (!newsect->used_by_bfd) - return false; - newsect->alignment_power = 3; - - /* We allow more than three sections internally */ - return true; -} - -/* Copy any private info we understand from the input symbol - to the output symbol. */ - -static boolean -som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol) - bfd *ibfd; - asymbol *isymbol; - bfd *obfd; - asymbol *osymbol; -{ - struct som_symbol *input_symbol = (struct som_symbol *) isymbol; - struct som_symbol *output_symbol = (struct som_symbol *) osymbol; - - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_som_flavour - || obfd->xvec->flavour != bfd_target_som_flavour) - return false; - - /* The only private information we need to copy is the argument relocation - bits. */ - output_symbol->tc_data.hppa_arg_reloc = input_symbol->tc_data.hppa_arg_reloc; - - return true; -} - -/* Copy any private info we understand from the input section - to the output section. */ -static boolean -som_bfd_copy_private_section_data (ibfd, isection, obfd, osection) - bfd *ibfd; - asection *isection; - bfd *obfd; - asection *osection; -{ - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_som_flavour - || obfd->xvec->flavour != bfd_target_som_flavour - || (!som_is_space (isection) && !som_is_subspace (isection))) - return true; - - som_section_data (osection)->copy_data - = (struct som_copyable_section_data_struct *) - bfd_zalloc (obfd, sizeof (struct som_copyable_section_data_struct)); - if (som_section_data (osection)->copy_data == NULL) - return false; - - memcpy (som_section_data (osection)->copy_data, - som_section_data (isection)->copy_data, - sizeof (struct som_copyable_section_data_struct)); - - /* Reparent if necessary. */ - if (som_section_data (osection)->copy_data->container) - som_section_data (osection)->copy_data->container = - som_section_data (osection)->copy_data->container->output_section; - - return true; -} - -/* Copy any private info we understand from the input bfd - to the output bfd. */ - -static boolean -som_bfd_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd, *obfd; -{ - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_som_flavour - || obfd->xvec->flavour != bfd_target_som_flavour) - return true; - - /* Allocate some memory to hold the data we need. */ - obj_som_exec_data (obfd) = (struct som_exec_data *) - bfd_zalloc (obfd, sizeof (struct som_exec_data)); - if (obj_som_exec_data (obfd) == NULL) - return false; - - /* Now copy the data. */ - memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd), - sizeof (struct som_exec_data)); - - return true; -} - -/* Set backend info for sections which can not be described - in the BFD data structures. */ - -boolean -bfd_som_set_section_attributes (section, defined, private, sort_key, spnum) - asection *section; - int defined; - int private; - unsigned int sort_key; - int spnum; -{ - /* Allocate memory to hold the magic information. */ - if (som_section_data (section)->copy_data == NULL) - { - som_section_data (section)->copy_data - = (struct som_copyable_section_data_struct *) - bfd_zalloc (section->owner, - sizeof (struct som_copyable_section_data_struct)); - if (som_section_data (section)->copy_data == NULL) - return false; - } - som_section_data (section)->copy_data->sort_key = sort_key; - som_section_data (section)->copy_data->is_defined = defined; - som_section_data (section)->copy_data->is_private = private; - som_section_data (section)->copy_data->container = section; - som_section_data (section)->copy_data->space_number = spnum; - return true; -} - -/* Set backend info for subsections which can not be described - in the BFD data structures. */ - -boolean -bfd_som_set_subsection_attributes (section, container, access, - sort_key, quadrant) - asection *section; - asection *container; - int access; - unsigned int sort_key; - int quadrant; -{ - /* Allocate memory to hold the magic information. */ - if (som_section_data (section)->copy_data == NULL) - { - som_section_data (section)->copy_data - = (struct som_copyable_section_data_struct *) - bfd_zalloc (section->owner, - sizeof (struct som_copyable_section_data_struct)); - if (som_section_data (section)->copy_data == NULL) - return false; - } - som_section_data (section)->copy_data->sort_key = sort_key; - som_section_data (section)->copy_data->access_control_bits = access; - som_section_data (section)->copy_data->quadrant = quadrant; - som_section_data (section)->copy_data->container = container; - return true; -} - -/* Set the full SOM symbol type. SOM needs far more symbol information - than any other object file format I'm aware of. It is mandatory - to be able to know if a symbol is an entry point, millicode, data, - code, absolute, storage request, or procedure label. If you get - the symbol type wrong your program will not link. */ - -void -bfd_som_set_symbol_type (symbol, type) - asymbol *symbol; - unsigned int type; -{ - som_symbol_data (symbol)->som_type = type; -} - -/* Attach an auxiliary header to the BFD backend so that it may be - written into the object file. */ -boolean -bfd_som_attach_aux_hdr (abfd, type, string) - bfd *abfd; - int type; - char *string; -{ - if (type == VERSION_AUX_ID) - { - int len = strlen (string); - int pad = 0; - - if (len % 4) - pad = (4 - (len % 4)); - obj_som_version_hdr (abfd) = (struct user_string_aux_hdr *) - bfd_zalloc (abfd, sizeof (struct aux_id) - + sizeof (unsigned int) + len + pad); - if (!obj_som_version_hdr (abfd)) - return false; - obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID; - obj_som_version_hdr (abfd)->header_id.length = len + pad; - obj_som_version_hdr (abfd)->header_id.length += sizeof (int); - obj_som_version_hdr (abfd)->string_length = len; - strncpy (obj_som_version_hdr (abfd)->user_string, string, len); - } - else if (type == COPYRIGHT_AUX_ID) - { - int len = strlen (string); - int pad = 0; - - if (len % 4) - pad = (4 - (len % 4)); - obj_som_copyright_hdr (abfd) = (struct copyright_aux_hdr *) - bfd_zalloc (abfd, sizeof (struct aux_id) - + sizeof (unsigned int) + len + pad); - if (!obj_som_copyright_hdr (abfd)) - return false; - obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID; - obj_som_copyright_hdr (abfd)->header_id.length = len + pad; - obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int); - obj_som_copyright_hdr (abfd)->string_length = len; - strcpy (obj_som_copyright_hdr (abfd)->copyright, string); - } - return true; -} - -static boolean -som_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0)) - return true; - if ((bfd_size_type)(offset+count) > section->_raw_size - || bfd_seek (abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1 - || bfd_read (location, (bfd_size_type)1, count, abfd) != count) - return (false); /* on error */ - return (true); -} - -static boolean -som_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (abfd->output_has_begun == false) - { - /* Set up fixed parts of the file, space, and subspace headers. - Notify the world that output has begun. */ - som_prep_headers (abfd); - abfd->output_has_begun = true; - /* Start writing the object file. This include all the string - tables, fixup streams, and other portions of the object file. */ - som_begin_writing (abfd); - } - - /* Only write subspaces which have "real" contents (eg. the contents - are not generated at run time by the OS). */ - if (!som_is_subspace (section) - || ((section->flags & SEC_HAS_CONTENTS) == 0)) - return true; - - /* Seek to the proper offset within the object file and write the - data. */ - offset += som_section_data (section)->subspace_dict->file_loc_init_value; - if (bfd_seek (abfd, offset, SEEK_SET) == -1) - return false; - - if (bfd_write ((PTR) location, 1, count, abfd) != count) - return false; - return true; -} - -static boolean -som_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - /* Allow any architecture to be supported by the SOM backend */ - return bfd_default_set_arch_mach (abfd, arch, machine); -} - -static boolean -som_find_nearest_line (abfd, section, symbols, offset, filename_ptr, - functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - return (false); -} - -static int -som_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - (*_bfd_error_handler) ("som_sizeof_headers unimplemented"); - fflush (stderr); - abort (); - return (0); -} - -/* Return the single-character symbol type corresponding to - SOM section S, or '?' for an unknown SOM section. */ - -static char -som_section_type (s) - const char *s; -{ - const struct section_to_type *t; - - for (t = &stt[0]; t->section; t++) - if (!strcmp (s, t->section)) - return t->type; - return '?'; -} - -static int -som_decode_symclass (symbol) - asymbol *symbol; -{ - char c; - - if (bfd_is_com_section (symbol->section)) - return 'C'; - if (bfd_is_und_section (symbol->section)) - return 'U'; - if (bfd_is_ind_section (symbol->section)) - return 'I'; - if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL))) - return '?'; - - if (bfd_is_abs_section (symbol->section) - || (som_symbol_data (symbol) != NULL - && som_symbol_data (symbol)->som_type == SYMBOL_TYPE_ABSOLUTE)) - c = 'a'; - else if (symbol->section) - c = som_section_type (symbol->section->name); - else - return '?'; - if (symbol->flags & BSF_GLOBAL) - c = toupper (c); - return c; -} - -/* Return information about SOM symbol SYMBOL in RET. */ - -static void -som_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - ret->type = som_decode_symclass (symbol); - if (ret->type != 'U') - ret->value = symbol->value+symbol->section->vma; - else - ret->value = 0; - ret->name = symbol->name; -} - -/* Count the number of symbols in the archive symbol table. Necessary - so that we can allocate space for all the carsyms at once. */ - -static boolean -som_bfd_count_ar_symbols (abfd, lst_header, count) - bfd *abfd; - struct lst_header *lst_header; - symindex *count; -{ - unsigned int i; - unsigned int *hash_table = NULL; - file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header); - - hash_table = - (unsigned int *) bfd_malloc (lst_header->hash_size - * sizeof (unsigned int)); - if (hash_table == NULL && lst_header->hash_size != 0) - goto error_return; - - /* Don't forget to initialize the counter! */ - *count = 0; - - /* Read in the hash table. The has table is an array of 32bit file offsets - which point to the hash chains. */ - if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd) - != lst_header->hash_size * 4) - goto error_return; - - /* Walk each chain counting the number of symbols found on that particular - chain. */ - for (i = 0; i < lst_header->hash_size; i++) - { - struct lst_symbol_record lst_symbol; - - /* An empty chain has zero as it's file offset. */ - if (hash_table[i] == 0) - continue; - - /* Seek to the first symbol in this hash chain. */ - if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0) - goto error_return; - - /* Read in this symbol and update the counter. */ - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - (*count)++; - - /* Now iterate through the rest of the symbols on this chain. */ - while (lst_symbol.next_entry) - { - - /* Seek to the next symbol. */ - if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET) - < 0) - goto error_return; - - /* Read the symbol in and update the counter. */ - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - (*count)++; - } - } - if (hash_table != NULL) - free (hash_table); - return true; - - error_return: - if (hash_table != NULL) - free (hash_table); - return false; -} - -/* Fill in the canonical archive symbols (SYMS) from the archive described - by ABFD and LST_HEADER. */ - -static boolean -som_bfd_fill_in_ar_symbols (abfd, lst_header, syms) - bfd *abfd; - struct lst_header *lst_header; - carsym **syms; -{ - unsigned int i, len; - carsym *set = syms[0]; - unsigned int *hash_table = NULL; - struct som_entry *som_dict = NULL; - file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header); - - hash_table = - (unsigned int *) bfd_malloc (lst_header->hash_size - * sizeof (unsigned int)); - if (hash_table == NULL && lst_header->hash_size != 0) - goto error_return; - - som_dict = - (struct som_entry *) bfd_malloc (lst_header->module_count - * sizeof (struct som_entry)); - if (som_dict == NULL && lst_header->module_count != 0) - goto error_return; - - /* Read in the hash table. The has table is an array of 32bit file offsets - which point to the hash chains. */ - if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd) - != lst_header->hash_size * 4) - goto error_return; - - /* Seek to and read in the SOM dictionary. We will need this to fill - in the carsym's filepos field. */ - if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) < 0) - goto error_return; - - if (bfd_read ((PTR) som_dict, lst_header->module_count, - sizeof (struct som_entry), abfd) - != lst_header->module_count * sizeof (struct som_entry)) - goto error_return; - - /* Walk each chain filling in the carsyms as we go along. */ - for (i = 0; i < lst_header->hash_size; i++) - { - struct lst_symbol_record lst_symbol; - - /* An empty chain has zero as it's file offset. */ - if (hash_table[i] == 0) - continue; - - /* Seek to and read the first symbol on the chain. */ - if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0) - goto error_return; - - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - /* Get the name of the symbol, first get the length which is stored - as a 32bit integer just before the symbol. - - One might ask why we don't just read in the entire string table - and index into it. Well, according to the SOM ABI the string - index can point *anywhere* in the archive to save space, so just - using the string table would not be safe. */ - if (bfd_seek (abfd, lst_filepos + lst_header->string_loc - + lst_symbol.name.n_strx - 4, SEEK_SET) < 0) - goto error_return; - - if (bfd_read (&len, 1, 4, abfd) != 4) - goto error_return; - - /* Allocate space for the name and null terminate it too. */ - set->name = bfd_zalloc (abfd, len + 1); - if (!set->name) - goto error_return; - if (bfd_read (set->name, 1, len, abfd) != len) - goto error_return; - - set->name[len] = 0; - - /* Fill in the file offset. Note that the "location" field points - to the SOM itself, not the ar_hdr in front of it. */ - set->file_offset = som_dict[lst_symbol.som_index].location - - sizeof (struct ar_hdr); - - /* Go to the next symbol. */ - set++; - - /* Iterate through the rest of the chain. */ - while (lst_symbol.next_entry) - { - /* Seek to the next symbol and read it in. */ - if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET) <0) - goto error_return; - - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - /* Seek to the name length & string and read them in. */ - if (bfd_seek (abfd, lst_filepos + lst_header->string_loc - + lst_symbol.name.n_strx - 4, SEEK_SET) < 0) - goto error_return; - - if (bfd_read (&len, 1, 4, abfd) != 4) - goto error_return; - - /* Allocate space for the name and null terminate it too. */ - set->name = bfd_zalloc (abfd, len + 1); - if (!set->name) - goto error_return; - - if (bfd_read (set->name, 1, len, abfd) != len) - goto error_return; - set->name[len] = 0; - - /* Fill in the file offset. Note that the "location" field points - to the SOM itself, not the ar_hdr in front of it. */ - set->file_offset = som_dict[lst_symbol.som_index].location - - sizeof (struct ar_hdr); - - /* Go on to the next symbol. */ - set++; - } - } - /* If we haven't died by now, then we successfully read the entire - archive symbol table. */ - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - return true; - - error_return: - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - return false; -} - -/* Read in the LST from the archive. */ -static boolean -som_slurp_armap (abfd) - bfd *abfd; -{ - struct lst_header lst_header; - struct ar_hdr ar_header; - unsigned int parsed_size; - struct artdata *ardata = bfd_ardata (abfd); - char nextname[17]; - int i = bfd_read ((PTR) nextname, 1, 16, abfd); - - /* Special cases. */ - if (i == 0) - return true; - if (i != 16) - return false; - - if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) < 0) - return false; - - /* For archives without .o files there is no symbol table. */ - if (strncmp (nextname, "/ ", 16)) - { - bfd_has_map (abfd) = false; - return true; - } - - /* Read in and sanity check the archive header. */ - if (bfd_read ((PTR) &ar_header, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - return false; - - if (strncmp (ar_header.ar_fmag, ARFMAG, 2)) - { - bfd_set_error (bfd_error_malformed_archive); - return false; - } - - /* How big is the archive symbol table entry? */ - errno = 0; - parsed_size = strtol (ar_header.ar_size, NULL, 10); - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return false; - } - - /* Save off the file offset of the first real user data. */ - ardata->first_file_filepos = bfd_tell (abfd) + parsed_size; - - /* Read in the library symbol table. We'll make heavy use of this - in just a minute. */ - if (bfd_read ((PTR) & lst_header, 1, sizeof (struct lst_header), abfd) - != sizeof (struct lst_header)) - return false; - - /* Sanity check. */ - if (lst_header.a_magic != LIBMAGIC) - { - bfd_set_error (bfd_error_malformed_archive); - return false; - } - - /* Count the number of symbols in the library symbol table. */ - if (som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count) - == false) - return false; - - /* Get back to the start of the library symbol table. */ - if (bfd_seek (abfd, ardata->first_file_filepos - parsed_size - + sizeof (struct lst_header), SEEK_SET) < 0) - return false; - - /* Initializae the cache and allocate space for the library symbols. */ - ardata->cache = 0; - ardata->symdefs = (carsym *) bfd_alloc (abfd, - (ardata->symdef_count - * sizeof (carsym))); - if (!ardata->symdefs) - return false; - - /* Now fill in the canonical archive symbols. */ - if (som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs) - == false) - return false; - - /* Seek back to the "first" file in the archive. Note the "first" - file may be the extended name table. */ - if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) < 0) - return false; - - /* Notify the generic archive code that we have a symbol map. */ - bfd_has_map (abfd) = true; - return true; -} - -/* Begin preparing to write a SOM library symbol table. - - As part of the prep work we need to determine the number of symbols - and the size of the associated string section. */ - -static boolean -som_bfd_prep_for_ar_write (abfd, num_syms, stringsize) - bfd *abfd; - unsigned int *num_syms, *stringsize; -{ - bfd *curr_bfd = abfd->archive_head; - - /* Some initialization. */ - *num_syms = 0; - *stringsize = 0; - - /* Iterate over each BFD within this archive. */ - while (curr_bfd != NULL) - { - unsigned int curr_count, i; - som_symbol_type *sym; - - /* Don't bother for non-SOM objects. */ - if (curr_bfd->format != bfd_object - || curr_bfd->xvec->flavour != bfd_target_som_flavour) - { - curr_bfd = curr_bfd->next; - continue; - } - - /* Make sure the symbol table has been read, then snag a pointer - to it. It's a little slimey to grab the symbols via obj_som_symtab, - but doing so avoids allocating lots of extra memory. */ - if (som_slurp_symbol_table (curr_bfd) == false) - return false; - - sym = obj_som_symtab (curr_bfd); - curr_count = bfd_get_symcount (curr_bfd); - - /* Examine each symbol to determine if it belongs in the - library symbol table. */ - for (i = 0; i < curr_count; i++, sym++) - { - struct som_misc_symbol_info info; - - /* Derive SOM information from the BFD symbol. */ - som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info); - - /* Should we include this symbol? */ - if (info.symbol_type == ST_NULL - || info.symbol_type == ST_SYM_EXT - || info.symbol_type == ST_ARG_EXT) - continue; - - /* Only global symbols and unsatisfied commons. */ - if (info.symbol_scope != SS_UNIVERSAL - && info.symbol_type != ST_STORAGE) - continue; - - /* Do no include undefined symbols. */ - if (bfd_is_und_section (sym->symbol.section)) - continue; - - /* Bump the various counters, being careful to honor - alignment considerations in the string table. */ - (*num_syms)++; - *stringsize = *stringsize + strlen (sym->symbol.name) + 5; - while (*stringsize % 4) - (*stringsize)++; - } - - curr_bfd = curr_bfd->next; - } - return true; -} - -/* Hash a symbol name based on the hashing algorithm presented in the - SOM ABI. */ -static unsigned int -som_bfd_ar_symbol_hash (symbol) - asymbol *symbol; -{ - unsigned int len = strlen (symbol->name); - - /* Names with length 1 are special. */ - if (len == 1) - return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0]; - - return ((len & 0x7f) << 24) | (symbol->name[1] << 16) - | (symbol->name[len-2] << 8) | symbol->name[len-1]; -} - -static CONST char * -normalize (file) - CONST char *file; -{ - CONST char *filename = strrchr (file, '/'); - - if (filename != NULL) - filename++; - else - filename = file; - return filename; -} - -/* Do the bulk of the work required to write the SOM library - symbol table. */ - -static boolean -som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst) - bfd *abfd; - unsigned int nsyms, string_size; - struct lst_header lst; -{ - file_ptr lst_filepos; - char *strings = NULL, *p; - struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym; - bfd *curr_bfd; - unsigned int *hash_table = NULL; - struct som_entry *som_dict = NULL; - struct lst_symbol_record **last_hash_entry = NULL; - unsigned int curr_som_offset, som_index, extended_name_length = 0; - unsigned int maxname = abfd->xvec->ar_max_namelen; - - hash_table = - (unsigned int *) bfd_malloc (lst.hash_size * sizeof (unsigned int)); - if (hash_table == NULL && lst.hash_size != 0) - goto error_return; - som_dict = - (struct som_entry *) bfd_malloc (lst.module_count - * sizeof (struct som_entry)); - if (som_dict == NULL && lst.module_count != 0) - goto error_return; - - last_hash_entry = - ((struct lst_symbol_record **) - bfd_malloc (lst.hash_size * sizeof (struct lst_symbol_record *))); - if (last_hash_entry == NULL && lst.hash_size != 0) - goto error_return; - - /* Lots of fields are file positions relative to the start - of the lst record. So save its location. */ - lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header); - - /* Some initialization. */ - memset (hash_table, 0, 4 * lst.hash_size); - memset (som_dict, 0, lst.module_count * sizeof (struct som_entry)); - memset (last_hash_entry, 0, - lst.hash_size * sizeof (struct lst_symbol_record *)); - - /* Symbols have som_index fields, so we have to keep track of the - index of each SOM in the archive. - - The SOM dictionary has (among other things) the absolute file - position for the SOM which a particular dictionary entry - describes. We have to compute that information as we iterate - through the SOMs/symbols. */ - som_index = 0; - curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end; - - /* Yow! We have to know the size of the extended name table - too. */ - for (curr_bfd = abfd->archive_head; - curr_bfd != NULL; - curr_bfd = curr_bfd->next) - { - CONST char *normal = normalize (curr_bfd->filename); - unsigned int thislen; - - if (!normal) - return false; - thislen = strlen (normal); - if (thislen > maxname) - extended_name_length += thislen + 1; - } - - /* Make room for the archive header and the contents of the - extended string table. */ - if (extended_name_length) - curr_som_offset += extended_name_length + sizeof (struct ar_hdr); - - /* Make sure we're properly aligned. */ - curr_som_offset = (curr_som_offset + 0x1) & ~0x1; - - /* FIXME should be done with buffers just like everything else... */ - lst_syms = bfd_malloc (nsyms * sizeof (struct lst_symbol_record)); - if (lst_syms == NULL && nsyms != 0) - goto error_return; - strings = bfd_malloc (string_size); - if (strings == NULL && string_size != 0) - goto error_return; - - p = strings; - curr_lst_sym = lst_syms; - - curr_bfd = abfd->archive_head; - while (curr_bfd != NULL) - { - unsigned int curr_count, i; - som_symbol_type *sym; - - /* Don't bother for non-SOM objects. */ - if (curr_bfd->format != bfd_object - || curr_bfd->xvec->flavour != bfd_target_som_flavour) - { - curr_bfd = curr_bfd->next; - continue; - } - - /* Make sure the symbol table has been read, then snag a pointer - to it. It's a little slimey to grab the symbols via obj_som_symtab, - but doing so avoids allocating lots of extra memory. */ - if (som_slurp_symbol_table (curr_bfd) == false) - goto error_return; - - sym = obj_som_symtab (curr_bfd); - curr_count = bfd_get_symcount (curr_bfd); - - for (i = 0; i < curr_count; i++, sym++) - { - struct som_misc_symbol_info info; - - /* Derive SOM information from the BFD symbol. */ - som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info); - - /* Should we include this symbol? */ - if (info.symbol_type == ST_NULL - || info.symbol_type == ST_SYM_EXT - || info.symbol_type == ST_ARG_EXT) - continue; - - /* Only global symbols and unsatisfied commons. */ - if (info.symbol_scope != SS_UNIVERSAL - && info.symbol_type != ST_STORAGE) - continue; - - /* Do no include undefined symbols. */ - if (bfd_is_und_section (sym->symbol.section)) - continue; - - /* If this is the first symbol from this SOM, then update - the SOM dictionary too. */ - if (som_dict[som_index].location == 0) - { - som_dict[som_index].location = curr_som_offset; - som_dict[som_index].length = arelt_size (curr_bfd); - } - - /* Fill in the lst symbol record. */ - curr_lst_sym->hidden = 0; - curr_lst_sym->secondary_def = 0; - curr_lst_sym->symbol_type = info.symbol_type; - curr_lst_sym->symbol_scope = info.symbol_scope; - curr_lst_sym->check_level = 0; - curr_lst_sym->must_qualify = 0; - curr_lst_sym->initially_frozen = 0; - curr_lst_sym->memory_resident = 0; - curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section); - curr_lst_sym->dup_common = 0; - curr_lst_sym->xleast = 0; - curr_lst_sym->arg_reloc = info.arg_reloc; - curr_lst_sym->name.n_strx = p - strings + 4; - curr_lst_sym->qualifier_name.n_strx = 0; - curr_lst_sym->symbol_info = info.symbol_info; - curr_lst_sym->symbol_value = info.symbol_value; - curr_lst_sym->symbol_descriptor = 0; - curr_lst_sym->reserved = 0; - curr_lst_sym->som_index = som_index; - curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol); - curr_lst_sym->next_entry = 0; - - /* Insert into the hash table. */ - if (hash_table[curr_lst_sym->symbol_key % lst.hash_size]) - { - struct lst_symbol_record *tmp; - - /* There is already something at the head of this hash chain, - so tack this symbol onto the end of the chain. */ - tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]; - tmp->next_entry - = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record) - + lst.hash_size * 4 - + lst.module_count * sizeof (struct som_entry) - + sizeof (struct lst_header); - } - else - { - /* First entry in this hash chain. */ - hash_table[curr_lst_sym->symbol_key % lst.hash_size] - = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record) - + lst.hash_size * 4 - + lst.module_count * sizeof (struct som_entry) - + sizeof (struct lst_header); - } - - /* Keep track of the last symbol we added to this chain so we can - easily update its next_entry pointer. */ - last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size] - = curr_lst_sym; - - - /* Update the string table. */ - bfd_put_32 (abfd, strlen (sym->symbol.name), p); - p += 4; - strcpy (p, sym->symbol.name); - p += strlen (sym->symbol.name) + 1; - while ((int)p % 4) - { - bfd_put_8 (abfd, 0, p); - p++; - } - - /* Head to the next symbol. */ - curr_lst_sym++; - } - - /* Keep track of where each SOM will finally reside; then look - at the next BFD. */ - curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr); - - /* A particular object in the archive may have an odd length; the - linker requires objects begin on an even boundary. So round - up the current offset as necessary. */ - curr_som_offset = (curr_som_offset + 0x1) & ~0x1; - curr_bfd = curr_bfd->next; - som_index++; - } - - /* Now scribble out the hash table. */ - if (bfd_write ((PTR) hash_table, lst.hash_size, 4, abfd) - != lst.hash_size * 4) - goto error_return; - - /* Then the SOM dictionary. */ - if (bfd_write ((PTR) som_dict, lst.module_count, - sizeof (struct som_entry), abfd) - != lst.module_count * sizeof (struct som_entry)) - goto error_return; - - /* The library symbols. */ - if (bfd_write ((PTR) lst_syms, nsyms, sizeof (struct lst_symbol_record), abfd) - != nsyms * sizeof (struct lst_symbol_record)) - goto error_return; - - /* And finally the strings. */ - if (bfd_write ((PTR) strings, string_size, 1, abfd) != string_size) - goto error_return; - - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - if (last_hash_entry != NULL) - free (last_hash_entry); - if (lst_syms != NULL) - free (lst_syms); - if (strings != NULL) - free (strings); - return true; - - error_return: - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - if (last_hash_entry != NULL) - free (last_hash_entry); - if (lst_syms != NULL) - free (lst_syms); - if (strings != NULL) - free (strings); - - return false; -} - -/* SOM almost uses the SVR4 style extended name support, but not - quite. */ - -static boolean -som_construct_extended_name_table (abfd, tabloc, tablen, name) - bfd *abfd; - char **tabloc; - bfd_size_type *tablen; - const char **name; -{ - *name = "//"; - return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen); -} - -/* Write out the LST for the archive. - - You'll never believe this is really how armaps are handled in SOM... */ - -/*ARGSUSED*/ -static boolean -som_write_armap (abfd, elength, map, orl_count, stridx) - bfd *abfd; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - bfd *curr_bfd; - struct stat statbuf; - unsigned int i, lst_size, nsyms, stringsize; - struct ar_hdr hdr; - struct lst_header lst; - int *p; - - /* We'll use this for the archive's date and mode later. */ - if (stat (abfd->filename, &statbuf) != 0) - { - bfd_set_error (bfd_error_system_call); - return false; - } - /* Fudge factor. */ - bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60; - - /* Account for the lst header first. */ - lst_size = sizeof (struct lst_header); - - /* Start building the LST header. */ - /* FIXME: Do we need to examine each element to determine the - largest id number? */ - lst.system_id = CPU_PA_RISC1_0; - lst.a_magic = LIBMAGIC; - lst.version_id = VERSION_ID; - lst.file_time.secs = 0; - lst.file_time.nanosecs = 0; - - lst.hash_loc = lst_size; - lst.hash_size = SOM_LST_HASH_SIZE; - - /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets. */ - lst_size += 4 * SOM_LST_HASH_SIZE; - - /* We need to count the number of SOMs in this archive. */ - curr_bfd = abfd->archive_head; - lst.module_count = 0; - while (curr_bfd != NULL) - { - /* Only true SOM objects count. */ - if (curr_bfd->format == bfd_object - && curr_bfd->xvec->flavour == bfd_target_som_flavour) - lst.module_count++; - curr_bfd = curr_bfd->next; - } - lst.module_limit = lst.module_count; - lst.dir_loc = lst_size; - lst_size += sizeof (struct som_entry) * lst.module_count; - - /* We don't support import/export tables, auxiliary headers, - or free lists yet. Make the linker work a little harder - to make our life easier. */ - - lst.export_loc = 0; - lst.export_count = 0; - lst.import_loc = 0; - lst.aux_loc = 0; - lst.aux_size = 0; - - /* Count how many symbols we will have on the hash chains and the - size of the associated string table. */ - if (som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize) == false) - return false; - - lst_size += sizeof (struct lst_symbol_record) * nsyms; - - /* For the string table. One day we might actually use this info - to avoid small seeks/reads when reading archives. */ - lst.string_loc = lst_size; - lst.string_size = stringsize; - lst_size += stringsize; - - /* SOM ABI says this must be zero. */ - lst.free_list = 0; - lst.file_end = lst_size; - - /* Compute the checksum. Must happen after the entire lst header - has filled in. */ - p = (int *)&lst; - lst.checksum = 0; - for (i = 0; i < sizeof (struct lst_header)/sizeof (int) - 1; i++) - lst.checksum ^= *p++; - - sprintf (hdr.ar_name, "/ "); - sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp); - sprintf (hdr.ar_uid, "%ld", (long) getuid ()); - sprintf (hdr.ar_gid, "%ld", (long) getgid ()); - sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode); - sprintf (hdr.ar_size, "%-10d", (int) lst_size); - hdr.ar_fmag[0] = '`'; - hdr.ar_fmag[1] = '\012'; - - /* Turn any nulls into spaces. */ - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - - /* Scribble out the ar header. */ - if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - return false; - - /* Now scribble out the lst header. */ - if (bfd_write ((PTR) &lst, 1, sizeof (struct lst_header), abfd) - != sizeof (struct lst_header)) - return false; - - /* Build and write the armap. */ - if (som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst) == false) - return false; - - /* Done. */ - return true; -} - -/* Free all information we have cached for this BFD. We can always - read it again later if we need it. */ - -static boolean -som_bfd_free_cached_info (abfd) - bfd *abfd; -{ - asection *o; - - if (bfd_get_format (abfd) != bfd_object) - return true; - -#define FREE(x) if (x != NULL) { free (x); x = NULL; } - /* Free the native string and symbol tables. */ - FREE (obj_som_symtab (abfd)); - FREE (obj_som_stringtab (abfd)); - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - /* Free the native relocations. */ - o->reloc_count = -1; - FREE (som_section_data (o)->reloc_stream); - /* Free the generic relocations. */ - FREE (o->relocation); - } -#undef FREE - - return true; -} - -/* End of miscellaneous support functions. */ - -/* Linker support functions. */ -static boolean -som_bfd_link_split_section (abfd, sec) - bfd *abfd; - asection *sec; -{ - return (som_is_subspace (sec) && sec->_raw_size > 240000); -} - -#define som_close_and_cleanup som_bfd_free_cached_info - -#define som_read_ar_hdr _bfd_generic_read_ar_hdr -#define som_openr_next_archived_file bfd_generic_openr_next_archived_file -#define som_get_elt_at_index _bfd_generic_get_elt_at_index -#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define som_truncate_arname bfd_bsd_truncate_arname -#define som_slurp_extended_name_table _bfd_slurp_extended_name_table -#define som_update_armap_timestamp bfd_true -#define som_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data - -#define som_get_lineno _bfd_nosymbols_get_lineno -#define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define som_read_minisymbols _bfd_generic_read_minisymbols -#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define som_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define som_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define som_bfd_relax_section bfd_generic_relax_section -#define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define som_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define som_bfd_final_link _bfd_generic_final_link - - -const bfd_target som_vec = -{ - "som", /* name */ - bfd_target_som_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - -/* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - '/', /* ar_pad_char */ - 14, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, - som_object_p, /* bfd_check_format */ - bfd_generic_archive_p, - _bfd_dummy_target - }, - { - bfd_false, - som_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { - bfd_false, - som_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, -#undef som - - BFD_JUMP_TABLE_GENERIC (som), - BFD_JUMP_TABLE_COPY (som), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (som), - BFD_JUMP_TABLE_SYMBOLS (som), - BFD_JUMP_TABLE_RELOCS (som), - BFD_JUMP_TABLE_WRITE (som), - BFD_JUMP_TABLE_LINK (som), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; - -#endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */ diff --git a/contrib/gdb/bfd/som.h b/contrib/gdb/bfd/som.h deleted file mode 100644 index 6290e88f948..00000000000 --- a/contrib/gdb/bfd/som.h +++ /dev/null @@ -1,224 +0,0 @@ -/* HP PA-RISC SOM object file format: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _SOM_H -#define _SOM_H - -#include "../bfd/sysdep.h" -#include "libhppa.h" - -#include -#include -#include - -/* The SOM BFD backend doesn't currently use anything from these - two include files, but it's likely to need them in the future. */ -#ifdef R_DLT_REL -#include -#include -#endif - -#if defined(HOST_HPPABSD) || defined (HOST_HPPAOSF) -/* BSD uses a completely different scheme for object file identification. - so for now, define _PA_RISC_ID to accept any random value for a model - number. */ -#undef _PA_RISC_ID -#define _PA_RISC_ID(__m_num) 1 -#endif /* HOST_HPPABSD */ - -#define FILE_HDR_SIZE sizeof(struct header) -#define AUX_HDR_SIZE sizeof(struct som_exec_auxhdr) - -typedef struct som_symbol - { - asymbol symbol; - unsigned int som_type; - - /* Structured like the ELF tc_data union. Allows more code sharing - in GAS this way. */ - union - { - unsigned int hppa_arg_reloc; - PTR any; - } - tc_data; - - /* Index of this symbol in the symbol table. Only used when - building relocation streams for incomplete objects. */ - int index; - - /* How many times this symbol is used in a relocation. By sorting - the symbols from most used to least used we can significantly - reduce the size of the relocation stream for incomplete objects. */ - int reloc_count; - - /* During object file writing, the offset of the name of this symbol - in the SOM string table. */ - int stringtab_offset; - } -som_symbol_type; - -/* A structure containing all the magic information stored in a BFD's - private data which needs to be copied during an objcopy/strip run. */ -struct som_exec_data - { - /* Sort-of a magic number. BSD uses it to distinguish between - native executables and hpux executables. */ - short system_id; - - /* Magic exec flags. These control things like whether or not - null pointer dereferencing is allowed and the like. */ - long exec_flags; - - /* Add more stuff here as needed. Good examples of information - we might want to pass would be presumed_dp, entry_* and maybe - others from the file header. */ - }; - -struct somdata - { - /* All the magic information about an executable which lives - in the private BFD structure and needs to be copied from - the input bfd to the output bfd during a objcopy/strip. */ - struct som_exec_data *exec_data; - - /* These three fields are only used when writing files and are - generated from scratch. They need not be copied for objcopy - or strip to work. */ - struct header *file_hdr; - struct copyright_aux_hdr *copyright_aux_hdr; - struct user_string_aux_hdr *version_aux_hdr; - struct som_exec_auxhdr *exec_hdr; - - /* Pointers to a saved copy of the symbol and string tables. These - need not be copied for objcopy or strip to work. */ - som_symbol_type *symtab; - char *stringtab; - asymbol **sorted_syms; - - /* We remember these offsets so that after check_file_format, we have - no dependencies on the particular format of the exec_hdr. - These offsets need not be copied for objcopy or strip to work. */ - - file_ptr sym_filepos; - file_ptr str_filepos; - file_ptr reloc_filepos; - unsigned stringtab_size; - }; - -struct som_data_struct - { - struct somdata a; - }; - -/* Substructure of som_section_data_struct used to hold information - which can't be represented by the generic BFD section structure, - but which must be copied during objcopy or strip. */ -struct som_copyable_section_data_struct - { - /* Various fields in space and subspace headers that we need - to pass around. */ - unsigned int sort_key : 8; - unsigned int access_control_bits : 7; - unsigned int is_defined : 1; - unsigned int is_private : 1; - unsigned int quadrant : 2; - - /* For subspaces, this points to the section which represents the - space in which the subspace is contained. For spaces it points - back to the section for this space. */ - asection *container; - - /* The user-specified space number. It is wrong to use this as - an index since duplicates and holes are allowed. */ - int space_number; - - /* Add more stuff here as needed. Good examples of information - we might want to pass would be initialization pointers, - and the many subspace flags we do not represent yet. */ - }; - -/* Used to keep extra SOM specific information for a given section. - - reloc_size holds the size of the relocation stream, note this - is very different from the number of relocations as SOM relocations - are variable length. - - reloc_stream is the actual stream of relocation entries. */ - -struct som_section_data_struct - { - struct som_copyable_section_data_struct *copy_data; - unsigned int reloc_size; - char *reloc_stream; - struct space_dictionary_record *space_dict; - struct subspace_dictionary_record *subspace_dict; - }; - -#define somdata(bfd) ((bfd)->tdata.som_data->a) -#define obj_som_exec_data(bfd) (somdata(bfd).exec_data) -#define obj_som_file_hdr(bfd) (somdata(bfd).file_hdr) -#define obj_som_exec_hdr(bfd) (somdata(bfd).exec_hdr) -#define obj_som_copyright_hdr(bfd) (somdata(bfd).copyright_aux_hdr) -#define obj_som_version_hdr(bfd) (somdata(bfd).version_aux_hdr) -#define obj_som_symtab(bfd) (somdata(bfd).symtab) -#define obj_som_stringtab(bfd) (somdata(bfd).stringtab) -#define obj_som_sym_filepos(bfd) (somdata(bfd).sym_filepos) -#define obj_som_str_filepos(bfd) (somdata(bfd).str_filepos) -#define obj_som_stringtab_size(bfd) (somdata(bfd).stringtab_size) -#define obj_som_reloc_filepos(bfd) (somdata(bfd).reloc_filepos) -#define obj_som_sorted_syms(bfd) (somdata(bfd).sorted_syms) -#define som_section_data(sec) \ - ((struct som_section_data_struct *)sec->used_by_bfd) -#define som_symbol_data(symbol) ((som_symbol_type *) symbol) - - -/* Defines groups of basic relocations. FIXME: These should - be the only basic relocations created by GAS. The rest - should be internal to the BFD backend. - - The idea is both SOM and ELF define these basic relocation - types so they map into a SOM or ELF specific reloation as - appropriate. This allows GAS to share much more code - between the two object formats. */ - -#define R_HPPA_NONE R_NO_RELOCATION -#define R_HPPA R_CODE_ONE_SYMBOL -#define R_HPPA_PCREL_CALL R_PCREL_CALL -#define R_HPPA_ABS_CALL R_ABS_CALL -#define R_HPPA_GOTOFF R_DP_RELATIVE -#define R_HPPA_ENTRY R_ENTRY -#define R_HPPA_EXIT R_EXIT -#define R_HPPA_COMPLEX R_COMP1 -#define R_HPPA_BEGIN_BRTAB R_BEGIN_BRTAB -#define R_HPPA_END_BRTAB R_END_BRTAB - -/* Exported functions, mostly for use by GAS. */ -boolean bfd_som_set_section_attributes PARAMS ((asection *, int, int, - unsigned int, int)); -boolean bfd_som_set_subsection_attributes PARAMS ((asection *, asection *, - int, unsigned int, int)); -void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int)); -boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *)); -int ** hppa_som_gen_reloc_type - PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt, int)); -#endif /* _SOM_H */ diff --git a/contrib/gdb/bfd/sparclynx.c b/contrib/gdb/bfd/sparclynx.c deleted file mode 100644 index 0885620283e..00000000000 --- a/contrib/gdb/bfd/sparclynx.c +++ /dev/null @@ -1,265 +0,0 @@ -/* BFD support for Sparc binaries under LynxOS. - Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if 0 -#define BYTES_IN_WORD 4 -#define N_SHARED_LIB(x) 0 - -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_sparc - -#endif - -#define MY(OP) CAT(sparclynx_aout_,OP) -#define TARGETNAME "a.out-sparc-lynx" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "aout/sun4.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" - -/* This is needed to reject a NewsOS file, e.g. in - gdb/testsuite/gdb.t10/crossload.exp. - I needed to add M_UNKNOWN to recognize a 68000 object, so this will - probably no longer reject a NewsOS object. . */ -#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \ - || (mtype) == M_68010 \ - || (mtype) == M_68020 \ - || (mtype) == M_SPARC) - -/* -The file @code{aoutf1.h} contains the code for BFD's -a.out back end. Control over the generated back end is given by these -two preprocessor names: -@table @code -@item ARCH_SIZE -This value should be either 32 or 64, depending upon the size of an -int in the target format. It changes the sizes of the structs which -perform the memory/disk mapping of structures. - -The 64 bit backend may only be used if the host compiler supports 64 -ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. -With this name defined, @emph{all} bfd operations are performed with 64bit -arithmetic, not just those to a 64bit target. - -@item TARGETNAME -The name put into the target vector. -@item -@end table - -*/ - -/*SUPPRESS558*/ -/*SUPPRESS529*/ - -void -NAME(lynx,set_arch_mach) (abfd, machtype) - bfd *abfd; - int machtype; -{ - /* Determine the architecture and machine type of the object file. */ - enum bfd_architecture arch; - long machine; - switch (machtype) - { - - case M_UNKNOWN: - /* Some Sun3s make magic numbers without cpu types in them, so - we'll default to the 68000. */ - arch = bfd_arch_m68k; - machine = 68000; - break; - - case M_68010: - case M_HP200: - arch = bfd_arch_m68k; - machine = 68010; - break; - - case M_68020: - case M_HP300: - arch = bfd_arch_m68k; - machine = 68020; - break; - - case M_SPARC: - arch = bfd_arch_sparc; - machine = 0; - break; - - case M_386: - case M_386_DYNIX: - arch = bfd_arch_i386; - machine = 0; - break; - - case M_29K: - arch = bfd_arch_a29k; - machine = 0; - break; - - case M_HPUX: - arch = bfd_arch_m68k; - machine = 0; - break; - - default: - arch = bfd_arch_obscure; - machine = 0; - break; - } - bfd_set_arch_mach (abfd, arch, machine); -} - -#define SET_ARCH_MACH(ABFD, EXEC) \ - NAME(lynx,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ - choose_reloc_size(ABFD); - -/* Determine the size of a relocation entry, based on the architecture */ -static void -choose_reloc_size (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_sparc: - case bfd_arch_a29k: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } -} - -/* Write an object file in LynxOS format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -NAME(aout,sparclynx_write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - /* Magic number, maestro, please! */ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - switch (bfd_get_mach (abfd)) - { - case 68010: - N_SET_MACHTYPE (*execp, M_68010); - break; - default: - case 68020: - N_SET_MACHTYPE (*execp, M_68020); - break; - } - break; - case bfd_arch_sparc: - N_SET_MACHTYPE (*execp, M_SPARC); - break; - case bfd_arch_i386: - N_SET_MACHTYPE (*execp, M_386); - break; - case bfd_arch_a29k: - N_SET_MACHTYPE (*execp, M_29K); - break; - default: - N_SET_MACHTYPE (*execp, M_UNKNOWN); - } - - choose_reloc_size (abfd); - - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - WRITE_HEADERS (abfd, execp); - - return true; -} - -#define MY_set_sizes sparclynx_set_sizes -static boolean -sparclynx_set_sizes (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - default: - return false; - case bfd_arch_sparc: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x2000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - case bfd_arch_m68k: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x20000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - } -} - -static CONST struct aout_backend_data sparclynx_aout_backend = -{ - 0, 1, 1, 0, sparclynx_set_sizes, 0, - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - - -#define MY_bfd_debug_info_start bfd_void -#define MY_bfd_debug_info_end bfd_void -#define MY_bfd_debug_info_accumulate \ - (void (*) PARAMS ((bfd *, struct sec *))) bfd_void - -#define MY_write_object_contents NAME(aout,sparclynx_write_object_contents) -#define MY_backend_data &sparclynx_aout_backend - -#define TARGET_IS_BIG_ENDIAN_P - -#ifdef LYNX_CORE - -char *lynx_core_file_failing_command (); -int lynx_core_file_failing_signal (); -boolean lynx_core_file_matches_executable_p (); -const bfd_target *lynx_core_file_p (); - -#define MY_core_file_failing_command lynx_core_file_failing_command -#define MY_core_file_failing_signal lynx_core_file_failing_signal -#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p -#define MY_core_file_p lynx_core_file_p - -#endif /* LYNX_CORE */ - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/sparcnetbsd.c b/contrib/gdb/bfd/sparcnetbsd.c deleted file mode 100644 index 69240f5d158..00000000000 --- a/contrib/gdb/bfd/sparcnetbsd.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for NetBSD/sparc a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define BYTES_IN_WORD 4 -#define TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE 4096 - -#define DEFAULT_ARCH bfd_arch_sparc -#define MACHTYPE_OK(mtype) ((mtype) == M_SPARC_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(sparcnetbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-sparc-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/srec.c b/contrib/gdb/bfd/srec.c deleted file mode 100644 index 33d28d5eab8..00000000000 --- a/contrib/gdb/bfd/srec.c +++ /dev/null @@ -1,1324 +0,0 @@ -/* BFD back-end for s-record objects. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SUBSECTION - S-Record handling - -DESCRIPTION - - Ordinary S-Records cannot hold anything but addresses and - data, so that's all that we implement. - - The only interesting thing is that S-Records may come out of - order and there is no header, so an initial scan is required - to discover the minimum and maximum addresses used to create - the vma and size of the only section we create. We - arbitrarily call this section ".text". - - When bfd_get_section_contents is called the file is read - again, and this time the data is placed into a bfd_alloc'd - area. - - Any number of sections may be created for output, we save them - up and output them when it's time to close the bfd. - - An s record looks like: - -EXAMPLE - S
- -DESCRIPTION - Where - o length - is the number of bytes following upto the checksum. Note that - this is not the number of chars following, since it takes two - chars to represent a byte. - o type - is one of: - 0) header record - 1) two byte address data record - 2) three byte address data record - 3) four byte address data record - 7) four byte address termination record - 8) three byte address termination record - 9) two byte address termination record - - o address - is the start address of the data following, or in the case of - a termination record, the start address of the image - o data - is the data. - o checksum - is the sum of all the raw byte data in the record, from the length - upwards, modulo 256 and subtracted from 255. - - -SUBSECTION - Symbol S-Record handling - -DESCRIPTION - Some ICE equipment understands an addition to the standard - S-Record format; symbols and their addresses can be sent - before the data. - - The format of this is: - ($$ - (
)*) - $$ - - so a short symbol table could look like: - -EXAMPLE - $$ flash.x - $$ flash.c - _port6 $0 - _delay $4 - _start $14 - _etext $8036 - _edata $8036 - _end $8036 - $$ - -DESCRIPTION - We allow symbols to be anywhere in the data stream - the module names - are always ignored. - -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libiberty.h" -#include - -static void srec_init PARAMS ((void)); -static boolean srec_mkobject PARAMS ((bfd *)); -static int srec_get_byte PARAMS ((bfd *, boolean *)); -static void srec_bad_byte PARAMS ((bfd *, unsigned int, int, boolean)); -static boolean srec_scan PARAMS ((bfd *)); -static const bfd_target *srec_object_p PARAMS ((bfd *)); -static const bfd_target *symbolsrec_object_p PARAMS ((bfd *)); -static boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *)); - -static boolean srec_write_record PARAMS ((bfd *, int, bfd_vma, - const bfd_byte *, - const bfd_byte *)); -static boolean srec_write_header PARAMS ((bfd *)); -static boolean srec_write_symbols PARAMS ((bfd *)); - -/* Macros for converting between hex and binary. */ - -static CONST char digs[] = "0123456789ABCDEF"; - -#define NIBBLE(x) hex_value(x) -#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1])) -#define TOHEX(d, x, ch) \ - d[1] = digs[(x) & 0xf]; \ - d[0] = digs[((x)>>4)&0xf]; \ - ch += ((x) & 0xff); -#define ISHEX(x) hex_p(x) - -/* Initialize by filling in the hex conversion array. */ - -static void -srec_init () -{ - static boolean inited = false; - - if (inited == false) - { - inited = true; - hex_init (); - } -} - -/* The maximum number of bytes on a line is FF */ -#define MAXCHUNK 0xff -/* The number of bytes we fit onto a line on output */ -#define CHUNK 21 - -/* When writing an S-record file, the S-records can not be output as - they are seen. This structure is used to hold them in memory. */ - -struct srec_data_list_struct -{ - struct srec_data_list_struct *next; - bfd_byte *data; - bfd_vma where; - bfd_size_type size; -}; - -typedef struct srec_data_list_struct srec_data_list_type; - -/* When scanning the S-record file, a linked list of srec_symbol - structures is built to represent the symbol table (if there is - one). */ - -struct srec_symbol -{ - struct srec_symbol *next; - const char *name; - bfd_vma val; -}; - -/* The S-record tdata information. */ - -typedef struct srec_data_struct - { - srec_data_list_type *head; - srec_data_list_type *tail; - unsigned int type; - struct srec_symbol *symbols; - struct srec_symbol *symtail; - asymbol *csymbols; - } -tdata_type; - -static boolean srec_write_section PARAMS ((bfd *, tdata_type *, - srec_data_list_type *)); -static boolean srec_write_terminator PARAMS ((bfd *, tdata_type *)); - -/* Set up the S-record tdata information. */ - -static boolean -srec_mkobject (abfd) - bfd *abfd; -{ - srec_init (); - - if (abfd->tdata.srec_data == NULL) - { - tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - if (tdata == NULL) - return false; - abfd->tdata.srec_data = tdata; - tdata->type = 1; - tdata->head = NULL; - tdata->tail = NULL; - tdata->symbols = NULL; - tdata->symtail = NULL; - tdata->csymbols = NULL; - } - - return true; -} - -/* Read a byte from an S record file. Set *ERRORPTR if an error - occurred. Return EOF on error or end of file. */ - -static int -srec_get_byte (abfd, errorptr) - bfd *abfd; - boolean *errorptr; -{ - bfd_byte c; - - if (bfd_read (&c, 1, 1, abfd) != 1) - { - if (bfd_get_error () != bfd_error_file_truncated) - *errorptr = true; - return EOF; - } - - return (int) (c & 0xff); -} - -/* Report a problem in an S record file. FIXME: This probably should - not call fprintf, but we really do need some mechanism for printing - error messages. */ - -static void -srec_bad_byte (abfd, lineno, c, error) - bfd *abfd; - unsigned int lineno; - int c; - boolean error; -{ - if (c == EOF) - { - if (! error) - bfd_set_error (bfd_error_file_truncated); - } - else - { - char buf[10]; - - if (! isprint (c)) - sprintf (buf, "\\%03o", (unsigned int) c); - else - { - buf[0] = c; - buf[1] = '\0'; - } - (*_bfd_error_handler) - ("%s:%d: Unexpected character `%s' in S-record file\n", - bfd_get_filename (abfd), lineno, buf); - bfd_set_error (bfd_error_bad_value); - } -} - -/* Add a new symbol found in an S-record file. */ - -static boolean -srec_new_symbol (abfd, name, val) - bfd *abfd; - const char *name; - bfd_vma val; -{ - struct srec_symbol *n; - - n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (struct srec_symbol)); - if (n == NULL) - return false; - - n->name = name; - n->val = val; - - if (abfd->tdata.srec_data->symbols == NULL) - abfd->tdata.srec_data->symbols = n; - else - abfd->tdata.srec_data->symtail->next = n; - abfd->tdata.srec_data->symtail = n; - n->next = NULL; - - ++abfd->symcount; - - return true; -} - -/* Read the S record file and turn it into sections. We create a new - section for each contiguous set of bytes. */ - -static boolean -srec_scan (abfd) - bfd *abfd; -{ - int c; - unsigned int lineno = 1; - boolean error = false; - bfd_byte *buf = NULL; - size_t bufsize = 0; - asection *sec = NULL; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto error_return; - - while ((c = srec_get_byte (abfd, &error)) != EOF) - { - /* We only build sections from contiguous S-records, so if this - is not an S-record, then stop building a section. */ - if (c != 'S' && c != '\r' && c != '\n') - sec = NULL; - - switch (c) - { - default: - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - - case '\n': - ++lineno; - break; - - case '\r': - break; - - case '$': - /* Starting a module name, which we ignore. */ - while ((c = srec_get_byte (abfd, &error)) != '\n' - && c != EOF) - ; - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - ++lineno; - - break; - - case ' ': - { - char *symname; - bfd_vma symval; - - /* Starting a symbol definition. */ - while ((c = srec_get_byte (abfd, &error)) != EOF - && (c == ' ' || c == '\t')) - ; - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - obstack_1grow (&abfd->memory, c); - while ((c = srec_get_byte (abfd, &error)) != EOF - && ! isspace (c)) - obstack_1grow (&abfd->memory, c); - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - symname = obstack_finish (&abfd->memory); - if (symname == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - while ((c = srec_get_byte (abfd, &error)) != EOF - && (c == ' ' || c == '\t')) - ; - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - /* Skip a dollar sign before the hex value. */ - if (c == '$') - { - c = srec_get_byte (abfd, &error); - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - } - - symval = 0; - while (ISHEX (c)) - { - symval <<= 4; - symval += NIBBLE (c); - c = srec_get_byte (abfd, &error); - } - - if (c == EOF || ! isspace (c)) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - if (! srec_new_symbol (abfd, symname, symval)) - goto error_return; - - if (c == '\n') - ++lineno; - - } - break; - - case 'S': - { - file_ptr pos; - char hdr[3]; - unsigned int bytes; - bfd_vma address; - bfd_byte *data; - - /* Starting an S-record. */ - - pos = bfd_tell (abfd) - 1; - - if (bfd_read (hdr, 1, 3, abfd) != 3) - goto error_return; - - if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2])) - { - if (! ISHEX (hdr[1])) - c = hdr[1]; - else - c = hdr[2]; - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - bytes = HEX (hdr + 1); - if (bytes * 2 > bufsize) - { - if (buf != NULL) - free (buf); - buf = (bfd_byte *) bfd_malloc (bytes * 2); - if (buf == NULL) - goto error_return; - bufsize = bytes * 2; - } - - if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2) - goto error_return; - - /* Ignore the checksum byte. */ - --bytes; - - address = 0; - data = buf; - switch (hdr[0]) - { - case '0': - case '5': - /* Prologue--ignore the file name, but stop building a - section at this point. */ - sec = NULL; - break; - - case '3': - address = HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '2': - address = (address << 8) | HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '1': - address = (address << 8) | HEX (data); - data += 2; - address = (address << 8) | HEX (data); - data += 2; - bytes -= 2; - - if (sec != NULL - && sec->vma + sec->_raw_size == address) - { - /* This data goes at the end of the section we are - currently building. */ - sec->_raw_size += bytes; - } - else - { - char secbuf[20]; - char *secname; - - sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1); - secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1); - strcpy (secname, secbuf); - sec = bfd_make_section (abfd, secname); - if (sec == NULL) - goto error_return; - sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - sec->vma = address; - sec->lma = address; - sec->_raw_size = bytes; - sec->filepos = pos; - } - - break; - - case '7': - address = HEX (data); - data += 2; - /* Fall through. */ - case '8': - address = (address << 8) | HEX (data); - data += 2; - /* Fall through. */ - case '9': - address = (address << 8) | HEX (data); - data += 2; - address = (address << 8) | HEX (data); - data += 2; - - /* This is a termination record. */ - abfd->start_address = address; - - if (buf != NULL) - free (buf); - - return true; - } - } - break; - } - } - - if (error) - goto error_return; - - if (buf != NULL) - free (buf); - - return true; - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Check whether an existing file is an S-record file. */ - -static const bfd_target * -srec_object_p (abfd) - bfd *abfd; -{ - bfd_byte b[4]; - - srec_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_read (b, 1, 4, abfd) != 4) - return NULL; - - if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3])) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (! srec_mkobject (abfd) - || ! srec_scan (abfd)) - return NULL; - - return abfd->xvec; -} - -/* Check whether an existing file is an S-record file with symbols. */ - -static const bfd_target * -symbolsrec_object_p (abfd) - bfd *abfd; -{ - char b[2]; - - srec_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_read (b, 1, 2, abfd) != 2) - return NULL; - - if (b[0] != '$' || b[1] != '$') - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (! srec_mkobject (abfd) - || ! srec_scan (abfd)) - return NULL; - - return abfd->xvec; -} - -/* Read in the contents of a section in an S-record file. */ - -static boolean -srec_read_section (abfd, section, contents) - bfd *abfd; - asection *section; - bfd_byte *contents; -{ - int c; - bfd_size_type sofar = 0; - boolean error = false; - bfd_byte *buf = NULL; - size_t bufsize = 0; - - if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0) - goto error_return; - - while ((c = srec_get_byte (abfd, &error)) != EOF) - { - bfd_byte hdr[3]; - unsigned int bytes; - bfd_vma address; - bfd_byte *data; - - if (c == '\r' || c == '\n') - continue; - - /* This is called after srec_scan has already been called, so we - ought to know the exact format. */ - BFD_ASSERT (c == 'S'); - - if (bfd_read (hdr, 1, 3, abfd) != 3) - goto error_return; - - BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2])); - - bytes = HEX (hdr + 1); - - if (bytes * 2 > bufsize) - { - if (buf != NULL) - free (buf); - buf = (bfd_byte *) bfd_malloc (bytes * 2); - if (buf == NULL) - goto error_return; - bufsize = bytes * 2; - } - - if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2) - goto error_return; - - address = 0; - data = buf; - switch (hdr[0]) - { - default: - BFD_ASSERT (sofar == section->_raw_size); - if (buf != NULL) - free (buf); - return true; - - case '3': - address = HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '2': - address = (address << 8) | HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '1': - address = (address << 8) | HEX (data); - data += 2; - address = (address << 8) | HEX (data); - data += 2; - bytes -= 2; - - if (address != section->vma + sofar) - { - /* We've come to the end of this section. */ - BFD_ASSERT (sofar == section->_raw_size); - if (buf != NULL) - free (buf); - return true; - } - - /* Don't consider checksum. */ - --bytes; - - while (bytes-- != 0) - { - contents[sofar] = HEX (data); - data += 2; - ++sofar; - } - - break; - } - } - - if (error) - goto error_return; - - BFD_ASSERT (sofar == section->_raw_size); - - if (buf != NULL) - free (buf); - - return true; - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Get the contents of a section in an S-record file. */ - -static boolean -srec_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (section->used_by_bfd == NULL) - { - section->used_by_bfd = bfd_alloc (abfd, section->_raw_size); - if (section->used_by_bfd == NULL - && section->_raw_size != 0) - return false; - - if (! srec_read_section (abfd, section, section->used_by_bfd)) - return false; - } - - memcpy (location, (bfd_byte *) section->used_by_bfd + offset, - (size_t) count); - - return true; -} - -/* we have to save up all the Srecords for a splurge before output */ - -static boolean -srec_set_section_contents (abfd, section, location, offset, bytes_to_do) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type bytes_to_do; -{ - tdata_type *tdata = abfd->tdata.srec_data; - register srec_data_list_type *entry; - - entry = ((srec_data_list_type *) - bfd_alloc (abfd, sizeof (srec_data_list_type))); - if (entry == NULL) - return false; - - if (bytes_to_do - && (section->flags & SEC_ALLOC) - && (section->flags & SEC_LOAD)) - { - bfd_byte *data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do); - if (data == NULL) - return false; - memcpy ((PTR) data, location, (size_t) bytes_to_do); - - if ((section->lma + offset + bytes_to_do - 1) <= 0xffff) - { - - } - else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff - && tdata->type < 2) - { - tdata->type = 2; - } - else - { - tdata->type = 3; - } - - entry->data = data; - entry->where = section->lma + offset; - entry->size = bytes_to_do; - - /* Sort the records by address. Optimize for the common case of - adding a record to the end of the list. */ - if (tdata->tail != NULL - && entry->where >= tdata->tail->where) - { - tdata->tail->next = entry; - entry->next = NULL; - tdata->tail = entry; - } - else - { - register srec_data_list_type **look; - - for (look = &tdata->head; - *look != NULL && (*look)->where < entry->where; - look = &(*look)->next) - ; - entry->next = *look; - *look = entry; - if (entry->next == NULL) - tdata->tail = entry; - } - } - return true; -} - -/* Write a record of type, of the supplied number of bytes. The - supplied bytes and length don't have a checksum. That's worked out - here -*/ -static boolean -srec_write_record (abfd, type, address, data, end) - bfd *abfd; - int type; - bfd_vma address; - const bfd_byte *data; - const bfd_byte *end; -{ - char buffer[MAXCHUNK]; - unsigned int check_sum = 0; - CONST bfd_byte *src = data; - char *dst = buffer; - char *length; - bfd_size_type wrlen; - - *dst++ = 'S'; - *dst++ = '0' + type; - - length = dst; - dst += 2; /* leave room for dst*/ - - switch (type) - { - case 3: - case 7: - TOHEX (dst, (address >> 24), check_sum); - dst += 2; - case 8: - case 2: - TOHEX (dst, (address >> 16), check_sum); - dst += 2; - case 9: - case 1: - case 0: - TOHEX (dst, (address >> 8), check_sum); - dst += 2; - TOHEX (dst, (address), check_sum); - dst += 2; - break; - - } - for (src = data; src < end; src++) - { - TOHEX (dst, *src, check_sum); - dst += 2; - } - - /* Fill in the length */ - TOHEX (length, (dst - length) / 2, check_sum); - check_sum &= 0xff; - check_sum = 255 - check_sum; - TOHEX (dst, check_sum, check_sum); - dst += 2; - - *dst++ = '\r'; - *dst++ = '\n'; - wrlen = dst - buffer; - if (bfd_write ((PTR) buffer, 1, wrlen, abfd) != wrlen) - return false; - return true; -} - - - -static boolean -srec_write_header (abfd) - bfd *abfd; -{ - bfd_byte buffer[MAXCHUNK]; - bfd_byte *dst = buffer; - unsigned int i; - - /* I'll put an arbitary 40 char limit on header size */ - for (i = 0; i < 40 && abfd->filename[i]; i++) - { - *dst++ = abfd->filename[i]; - } - return srec_write_record (abfd, 0, 0, buffer, dst); -} - -static boolean -srec_write_section (abfd, tdata, list) - bfd *abfd; - tdata_type *tdata; - srec_data_list_type *list; -{ - unsigned int bytes_written = 0; - bfd_byte *location = list->data; - - while (bytes_written < list->size) - { - bfd_vma address; - - unsigned int bytes_this_chunk = list->size - bytes_written; - - if (bytes_this_chunk > CHUNK) - { - bytes_this_chunk = CHUNK; - } - - address = list->where + bytes_written; - - if (! srec_write_record (abfd, - tdata->type, - address, - location, - location + bytes_this_chunk)) - return false; - - bytes_written += bytes_this_chunk; - location += bytes_this_chunk; - } - - return true; -} - -static boolean -srec_write_terminator (abfd, tdata) - bfd *abfd; - tdata_type *tdata; -{ - bfd_byte buffer[2]; - - return srec_write_record (abfd, 10 - tdata->type, - abfd->start_address, buffer, buffer); -} - - - -static boolean -srec_write_symbols (abfd) - bfd *abfd; -{ - char buffer[MAXCHUNK]; - /* Dump out the symbols of a bfd */ - int i; - int count = bfd_get_symcount (abfd); - - if (count) - { - size_t len; - asymbol **table = bfd_get_outsymbols (abfd); - sprintf (buffer, "$$ %s\r\n", abfd->filename); - - len = strlen (buffer); - if (bfd_write (buffer, len, 1, abfd) != len) - return false; - - for (i = 0; i < count; i++) - { - asymbol *s = table[i]; -#if 0 - int len = strlen (s->name); - - /* If this symbol has a .[ocs] in it, it's probably a file name - and we'll output that as the module name */ - - if (len > 3 && s->name[len - 2] == '.') - { - int l; - sprintf (buffer, "$$ %s\r\n", s->name); - l = strlen (buffer); - if (bfd_write (buffer, l, 1, abfd) != l) - return false; - } - else -#endif - if (s->flags & (BSF_GLOBAL | BSF_LOCAL) - && (s->flags & BSF_DEBUGGING) == 0 - && s->name[0] != '.' - && s->name[0] != 't') - { - /* Just dump out non debug symbols */ - bfd_size_type l; - char buf2[40], *p; - - sprintf_vma (buf2, - s->value + s->section->output_section->lma - + s->section->output_offset); - p = buf2; - while (p[0] == '0' && p[1] != 0) - p++; - sprintf (buffer, " %s $%s\r\n", s->name, p); - l = strlen (buffer); - if (bfd_write (buffer, l, 1, abfd) != l) - return false; - } - } - sprintf (buffer, "$$ \r\n"); - len = strlen (buffer); - if (bfd_write (buffer, len, 1, abfd) != len) - return false; - } - - return true; -} - -static boolean -internal_srec_write_object_contents (abfd, symbols) - bfd *abfd; - int symbols; -{ - tdata_type *tdata = abfd->tdata.srec_data; - srec_data_list_type *list; - - if (symbols) - { - if (! srec_write_symbols (abfd)) - return false; - } - - if (! srec_write_header (abfd)) - return false; - - /* Now wander though all the sections provided and output them */ - list = tdata->head; - - while (list != (srec_data_list_type *) NULL) - { - if (! srec_write_section (abfd, tdata, list)) - return false; - list = list->next; - } - return srec_write_terminator (abfd, tdata); -} - -static boolean -srec_write_object_contents (abfd) - bfd *abfd; -{ - return internal_srec_write_object_contents (abfd, 0); -} - -static boolean -symbolsrec_write_object_contents (abfd) - bfd *abfd; -{ - return internal_srec_write_object_contents (abfd, 1); -} - -/*ARGSUSED*/ -static int -srec_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -static asymbol * -srec_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -/* Return the amount of memory needed to read the symbol table. */ - -static long -srec_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *); -} - -/* Return the symbol table. */ - -static long -srec_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - unsigned int symcount = bfd_get_symcount (abfd); - asymbol *csymbols; - unsigned int i; - - csymbols = abfd->tdata.srec_data->csymbols; - if (csymbols == NULL) - { - asymbol *c; - struct srec_symbol *s; - - csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol)); - if (csymbols == NULL && symcount != 0) - return false; - abfd->tdata.srec_data->csymbols = csymbols; - - for (s = abfd->tdata.srec_data->symbols, c = csymbols; - s != NULL; - s = s->next, ++c) - { - c->the_bfd = abfd; - c->name = s->name; - c->value = s->val; - c->flags = BSF_GLOBAL; - c->section = bfd_abs_section_ptr; - c->udata.p = NULL; - } - } - - for (i = 0; i < symcount; i++) - *alocation++ = csymbols++; - *alocation = NULL; - - return symcount; -} - -/*ARGSUSED*/ -void -srec_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/*ARGSUSED*/ -void -srec_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - default: - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s %s", - symbol->section->name, - symbol->name); - - } -} - -#define srec_close_and_cleanup _bfd_generic_close_and_cleanup -#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define srec_new_section_hook _bfd_generic_new_section_hook - -#define srec_bfd_is_local_label bfd_generic_is_local_label -#define srec_get_lineno _bfd_nosymbols_get_lineno -#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line -#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define srec_read_minisymbols _bfd_generic_read_minisymbols -#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define srec_get_reloc_upper_bound \ - ((long (*) PARAMS ((bfd *, asection *))) bfd_0l) -#define srec_canonicalize_reloc \ - ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l) -#define srec_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define srec_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define srec_set_arch_mach bfd_default_set_arch_mach - -#define srec_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define srec_bfd_relax_section bfd_generic_relax_section -#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define srec_bfd_final_link _bfd_generic_final_link -#define srec_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target srec_vec = -{ - "srec", /* name */ - bfd_target_srec_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - srec_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - srec_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - srec_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (srec), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (srec), - BFD_JUMP_TABLE_RELOCS (srec), - BFD_JUMP_TABLE_WRITE (srec), - BFD_JUMP_TABLE_LINK (srec), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; - - - -const bfd_target symbolsrec_vec = -{ - "symbolsrec", /* name */ - bfd_target_srec_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - symbolsrec_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - srec_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - symbolsrec_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (srec), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (srec), - BFD_JUMP_TABLE_RELOCS (srec), - BFD_JUMP_TABLE_WRITE (srec), - BFD_JUMP_TABLE_LINK (srec), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/stab-syms.c b/contrib/gdb/bfd/stab-syms.c deleted file mode 100644 index f4fe6c8ba3c..00000000000 --- a/contrib/gdb/bfd/stab-syms.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Table of stab names for the BFD library. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" - -#define ARCH_SIZE 32 /* Value doesn't matter. */ -#include "libaout.h" -#include "aout/aout64.h" - -/* Ignore duplicate stab codes; just return the string for the first - one. */ -#define __define_stab(NAME, CODE, STRING) __define_name(CODE, STRING) -#define __define_stab_duplicate(NAME, CODE, STRING) - -/* 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 EXTRA_SYMBOLS \ - __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") - -const char * -bfd_get_stab_name (code) - int code; -{ - switch (code) - { -#define __define_name(val, str) case val: return str; -#include "aout/stab.def" - EXTRA_SYMBOLS - } - - return (const char *) 0; -} diff --git a/contrib/gdb/bfd/sunos.c b/contrib/gdb/bfd/sunos.c deleted file mode 100644 index 77bf319bcd6..00000000000 --- a/contrib/gdb/bfd/sunos.c +++ /dev/null @@ -1,2767 +0,0 @@ -/* BFD backend for SunOS binaries. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGETNAME "a.out-sunos-big" -#define MY(OP) CAT(sunos_big_,OP) - -#include "bfd.h" -#include "bfdlink.h" -#include "libaout.h" - -/* Static routines defined in this file. */ - -static boolean sunos_read_dynamic_info PARAMS ((bfd *)); -static long sunos_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); -static boolean sunos_slurp_dynamic_symtab PARAMS ((bfd *)); -static long sunos_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); -static long sunos_get_dynamic_reloc_upper_bound PARAMS ((bfd *)); -static long sunos_canonicalize_dynamic_reloc - PARAMS ((bfd *, arelent **, asymbol **)); -static struct bfd_hash_entry *sunos_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *sunos_link_hash_table_create - PARAMS ((bfd *)); -static boolean sunos_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, boolean)); -static boolean sunos_add_dynamic_symbols - PARAMS ((bfd *, struct bfd_link_info *, struct external_nlist **, - bfd_size_type *, char **)); -static boolean sunos_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); -static boolean sunos_scan_relocs - PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_size_type)); -static boolean sunos_scan_std_relocs - PARAMS ((struct bfd_link_info *, bfd *, asection *, - const struct reloc_std_external *, bfd_size_type)); -static boolean sunos_scan_ext_relocs - PARAMS ((struct bfd_link_info *, bfd *, asection *, - const struct reloc_ext_external *, bfd_size_type)); -static boolean sunos_link_dynamic_object - PARAMS ((struct bfd_link_info *, bfd *)); -static boolean sunos_write_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct aout_link_hash_entry *)); -static boolean sunos_check_dynamic_reloc - PARAMS ((struct bfd_link_info *, bfd *, asection *, - struct aout_link_hash_entry *, PTR, bfd_byte *, boolean *, - bfd_vma *)); -static boolean sunos_finish_dynamic_link - PARAMS ((bfd *, struct bfd_link_info *)); - -#define MY_get_dynamic_symtab_upper_bound sunos_get_dynamic_symtab_upper_bound -#define MY_canonicalize_dynamic_symtab sunos_canonicalize_dynamic_symtab -#define MY_get_dynamic_reloc_upper_bound sunos_get_dynamic_reloc_upper_bound -#define MY_canonicalize_dynamic_reloc sunos_canonicalize_dynamic_reloc -#define MY_bfd_link_hash_table_create sunos_link_hash_table_create -#define MY_add_dynamic_symbols sunos_add_dynamic_symbols -#define MY_add_one_symbol sunos_add_one_symbol -#define MY_link_dynamic_object sunos_link_dynamic_object -#define MY_write_dynamic_symbol sunos_write_dynamic_symbol -#define MY_check_dynamic_reloc sunos_check_dynamic_reloc -#define MY_finish_dynamic_link sunos_finish_dynamic_link - -/* Include the usual a.out support. */ -#include "aoutf1.h" - -/* SunOS shared library support. We store a pointer to this structure - in obj_aout_dynamic_info (abfd). */ - -struct sunos_dynamic_info -{ - /* Whether we found any dynamic information. */ - boolean valid; - /* Dynamic information. */ - struct internal_sun4_dynamic_link dyninfo; - /* Number of dynamic symbols. */ - unsigned long dynsym_count; - /* Read in nlists for dynamic symbols. */ - struct external_nlist *dynsym; - /* asymbol structures for dynamic symbols. */ - aout_symbol_type *canonical_dynsym; - /* Read in dynamic string table. */ - char *dynstr; - /* Number of dynamic relocs. */ - unsigned long dynrel_count; - /* Read in dynamic relocs. This may be reloc_std_external or - reloc_ext_external. */ - PTR dynrel; - /* arelent structures for dynamic relocs. */ - arelent *canonical_dynrel; -}; - -/* The hash table of dynamic symbols is composed of two word entries. - See include/aout/sun4.h for details. */ - -#define HASH_ENTRY_SIZE (2 * BYTES_IN_WORD) - -/* Read in the basic dynamic information. This locates the __DYNAMIC - structure and uses it to find the dynamic_link structure. It - creates and saves a sunos_dynamic_info structure. If it can't find - __DYNAMIC, it sets the valid field of the sunos_dynamic_info - structure to false to avoid doing this work again. */ - -static boolean -sunos_read_dynamic_info (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - asection *dynsec; - bfd_vma dynoff; - struct external_sun4_dynamic dyninfo; - unsigned long dynver; - struct external_sun4_dynamic_link linkinfo; - - if (obj_aout_dynamic_info (abfd) != (PTR) NULL) - return true; - - if ((abfd->flags & DYNAMIC) == 0) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - info = ((struct sunos_dynamic_info *) - bfd_zalloc (abfd, sizeof (struct sunos_dynamic_info))); - if (!info) - return false; - info->valid = false; - info->dynsym = NULL; - info->dynstr = NULL; - info->canonical_dynsym = NULL; - info->dynrel = NULL; - info->canonical_dynrel = NULL; - obj_aout_dynamic_info (abfd) = (PTR) info; - - /* This code used to look for the __DYNAMIC symbol to locate the dynamic - linking information. - However this inhibits recovering the dynamic symbols from a - stripped object file, so blindly assume that the dynamic linking - information is located at the start of the data section. - We could verify this assumption later by looking through the dynamic - symbols for the __DYNAMIC symbol. */ - if ((abfd->flags & DYNAMIC) == 0) - return true; - if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (PTR) &dyninfo, - (file_ptr) 0, sizeof dyninfo)) - return true; - - dynver = GET_WORD (abfd, dyninfo.ld_version); - if (dynver != 2 && dynver != 3) - return true; - - dynoff = GET_WORD (abfd, dyninfo.ld); - - /* dynoff is a virtual address. It is probably always in the .data - section, but this code should work even if it moves. */ - if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd))) - dynsec = obj_textsec (abfd); - else - dynsec = obj_datasec (abfd); - dynoff -= bfd_get_section_vma (abfd, dynsec); - if (dynoff > bfd_section_size (abfd, dynsec)) - return true; - - /* This executable appears to be dynamically linked in a way that we - can understand. */ - if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo, dynoff, - (bfd_size_type) sizeof linkinfo)) - return true; - - /* Swap in the dynamic link information. */ - info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded); - info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need); - info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules); - info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got); - info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt); - info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel); - info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash); - info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab); - info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash); - info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets); - info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols); - info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size); - info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text); - info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz); - - /* Reportedly the addresses need to be offset by the size of the - exec header in an NMAGIC file. */ - if (adata (abfd).magic == n_magic) - { - unsigned long exec_bytes_size = adata (abfd).exec_bytes_size; - - info->dyninfo.ld_need += exec_bytes_size; - info->dyninfo.ld_rules += exec_bytes_size; - info->dyninfo.ld_rel += exec_bytes_size; - info->dyninfo.ld_hash += exec_bytes_size; - info->dyninfo.ld_stab += exec_bytes_size; - info->dyninfo.ld_symbols += exec_bytes_size; - } - - /* The only way to get the size of the symbol information appears to - be to determine the distance between it and the string table. */ - info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab) - / EXTERNAL_NLIST_SIZE); - BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE - == (unsigned long) (info->dyninfo.ld_symbols - - info->dyninfo.ld_stab)); - - /* Similarly, the relocs end at the hash table. */ - info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel) - / obj_reloc_entry_size (abfd)); - BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd) - == (unsigned long) (info->dyninfo.ld_hash - - info->dyninfo.ld_rel)); - - info->valid = true; - - return true; -} - -/* Return the amount of memory required for the dynamic symbols. */ - -static long -sunos_get_dynamic_symtab_upper_bound (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - - if (! sunos_read_dynamic_info (abfd)) - return -1; - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return -1; - } - - return (info->dynsym_count + 1) * sizeof (asymbol *); -} - -/* Read the external dynamic symbols. */ - -static boolean -sunos_slurp_dynamic_symtab (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - - /* Get the general dynamic information. */ - if (obj_aout_dynamic_info (abfd) == NULL) - { - if (! sunos_read_dynamic_info (abfd)) - return false; - } - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - /* Get the dynamic nlist structures. */ - if (info->dynsym == (struct external_nlist *) NULL) - { - info->dynsym = ((struct external_nlist *) - bfd_alloc (abfd, - (info->dynsym_count - * EXTERNAL_NLIST_SIZE))); - if (info->dynsym == NULL && info->dynsym_count != 0) - return false; - if (bfd_seek (abfd, info->dyninfo.ld_stab, SEEK_SET) != 0 - || (bfd_read ((PTR) info->dynsym, info->dynsym_count, - EXTERNAL_NLIST_SIZE, abfd) - != info->dynsym_count * EXTERNAL_NLIST_SIZE)) - { - if (info->dynsym != NULL) - { - bfd_release (abfd, info->dynsym); - info->dynsym = NULL; - } - return false; - } - } - - /* Get the dynamic strings. */ - if (info->dynstr == (char *) NULL) - { - info->dynstr = (char *) bfd_alloc (abfd, info->dyninfo.ld_symb_size); - if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0) - return false; - if (bfd_seek (abfd, info->dyninfo.ld_symbols, SEEK_SET) != 0 - || (bfd_read ((PTR) info->dynstr, 1, info->dyninfo.ld_symb_size, - abfd) - != info->dyninfo.ld_symb_size)) - { - if (info->dynstr != NULL) - { - bfd_release (abfd, info->dynstr); - info->dynstr = NULL; - } - return false; - } - } - - return true; -} - -/* Read in the dynamic symbols. */ - -static long -sunos_canonicalize_dynamic_symtab (abfd, storage) - bfd *abfd; - asymbol **storage; -{ - struct sunos_dynamic_info *info; - unsigned long i; - - if (! sunos_slurp_dynamic_symtab (abfd)) - return -1; - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - -#ifdef CHECK_DYNAMIC_HASH - /* Check my understanding of the dynamic hash table by making sure - that each symbol can be located in the hash table. */ - { - bfd_size_type table_size; - bfd_byte *table; - bfd_size_type i; - - if (info->dyninfo.ld_buckets > info->dynsym_count) - abort (); - table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash; - table = (bfd_byte *) bfd_malloc (table_size); - if (table == NULL && table_size != 0) - abort (); - if (bfd_seek (abfd, info->dyninfo.ld_hash, SEEK_SET) != 0 - || bfd_read ((PTR) table, 1, table_size, abfd) != table_size) - abort (); - for (i = 0; i < info->dynsym_count; i++) - { - unsigned char *name; - unsigned long hash; - - name = ((unsigned char *) info->dynstr - + GET_WORD (abfd, info->dynsym[i].e_strx)); - hash = 0; - while (*name != '\0') - hash = (hash << 1) + *name++; - hash &= 0x7fffffff; - hash %= info->dyninfo.ld_buckets; - while (GET_WORD (abfd, table + hash * HASH_ENTRY_SIZE) != i) - { - hash = GET_WORD (abfd, - table + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD); - if (hash == 0 || hash >= table_size / HASH_ENTRY_SIZE) - abort (); - } - } - free (table); - } -#endif /* CHECK_DYNAMIC_HASH */ - - /* Get the asymbol structures corresponding to the dynamic nlist - structures. */ - if (info->canonical_dynsym == (aout_symbol_type *) NULL) - { - info->canonical_dynsym = ((aout_symbol_type *) - bfd_alloc (abfd, - (info->dynsym_count - * sizeof (aout_symbol_type)))); - if (info->canonical_dynsym == NULL && info->dynsym_count != 0) - return -1; - - if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym, - info->dynsym, info->dynsym_count, - info->dynstr, - info->dyninfo.ld_symb_size, - true)) - { - if (info->canonical_dynsym != NULL) - { - bfd_release (abfd, info->canonical_dynsym); - info->canonical_dynsym = NULL; - } - return -1; - } - } - - /* Return pointers to the dynamic asymbol structures. */ - for (i = 0; i < info->dynsym_count; i++) - *storage++ = (asymbol *) (info->canonical_dynsym + i); - *storage = NULL; - - return info->dynsym_count; -} - -/* Return the amount of memory required for the dynamic relocs. */ - -static long -sunos_get_dynamic_reloc_upper_bound (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - - if (! sunos_read_dynamic_info (abfd)) - return -1; - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return -1; - } - - return (info->dynrel_count + 1) * sizeof (arelent *); -} - -/* Read in the dynamic relocs. */ - -static long -sunos_canonicalize_dynamic_reloc (abfd, storage, syms) - bfd *abfd; - arelent **storage; - asymbol **syms; -{ - struct sunos_dynamic_info *info; - unsigned long i; - - /* Get the general dynamic information. */ - if (obj_aout_dynamic_info (abfd) == (PTR) NULL) - { - if (! sunos_read_dynamic_info (abfd)) - return -1; - } - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return -1; - } - - /* Get the dynamic reloc information. */ - if (info->dynrel == NULL) - { - info->dynrel = (PTR) bfd_alloc (abfd, - (info->dynrel_count - * obj_reloc_entry_size (abfd))); - if (info->dynrel == NULL && info->dynrel_count != 0) - return -1; - if (bfd_seek (abfd, info->dyninfo.ld_rel, SEEK_SET) != 0 - || (bfd_read ((PTR) info->dynrel, info->dynrel_count, - obj_reloc_entry_size (abfd), abfd) - != info->dynrel_count * obj_reloc_entry_size (abfd))) - { - if (info->dynrel != NULL) - { - bfd_release (abfd, info->dynrel); - info->dynrel = NULL; - } - return -1; - } - } - - /* Get the arelent structures corresponding to the dynamic reloc - information. */ - if (info->canonical_dynrel == (arelent *) NULL) - { - arelent *to; - - info->canonical_dynrel = ((arelent *) - bfd_alloc (abfd, - (info->dynrel_count - * sizeof (arelent)))); - if (info->canonical_dynrel == NULL && info->dynrel_count != 0) - return -1; - - to = info->canonical_dynrel; - - if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE) - { - register struct reloc_ext_external *p; - struct reloc_ext_external *pend; - - p = (struct reloc_ext_external *) info->dynrel; - pend = p + info->dynrel_count; - for (; p < pend; p++, to++) - NAME(aout,swap_ext_reloc_in) (abfd, p, to, syms, - info->dynsym_count); - } - else - { - register struct reloc_std_external *p; - struct reloc_std_external *pend; - - p = (struct reloc_std_external *) info->dynrel; - pend = p + info->dynrel_count; - for (; p < pend; p++, to++) - NAME(aout,swap_std_reloc_in) (abfd, p, to, syms, - info->dynsym_count); - } - } - - /* Return pointers to the dynamic arelent structures. */ - for (i = 0; i < info->dynrel_count; i++) - *storage++ = info->canonical_dynrel + i; - *storage = NULL; - - return info->dynrel_count; -} - -/* Code to handle linking of SunOS shared libraries. */ - -/* A SPARC procedure linkage table entry is 12 bytes. The first entry - in the table is a jump which is filled in by the runtime linker. - The remaining entries are branches back to the first entry, - followed by an index into the relocation table encoded to look like - a sethi of %g0. */ - -#define SPARC_PLT_ENTRY_SIZE (12) - -static const bfd_byte sparc_plt_first_entry[SPARC_PLT_ENTRY_SIZE] = -{ - /* sethi %hi(0),%g1; address filled in by runtime linker. */ - 0x3, 0, 0, 0, - /* jmp %g1; offset filled in by runtime linker. */ - 0x81, 0xc0, 0x60, 0, - /* nop */ - 0x1, 0, 0, 0 -}; - -/* save %sp, -96, %sp */ -#define SPARC_PLT_ENTRY_WORD0 0x9de3bfa0 -/* call; address filled in later. */ -#define SPARC_PLT_ENTRY_WORD1 0x40000000 -/* sethi; reloc index filled in later. */ -#define SPARC_PLT_ENTRY_WORD2 0x01000000 - -/* This sequence is used when for the jump table entry to a defined - symbol in a complete executable. It is used when linking PIC - compiled code which is not being put into a shared library. */ -/* sethi
, %g1 */ -#define SPARC_PLT_PIC_WORD0 0x03000000 -/* jmp %g1 +
*/ -#define SPARC_PLT_PIC_WORD1 0x81c06000 -/* nop */ -#define SPARC_PLT_PIC_WORD2 0x01000000 - -/* An m68k procedure linkage table entry is 8 bytes. The first entry - in the table is a jump which is filled in the by the runtime - linker. The remaining entries are branches back to the first - entry, followed by a two byte index into the relocation table. */ - -#define M68K_PLT_ENTRY_SIZE (8) - -static const bfd_byte m68k_plt_first_entry[M68K_PLT_ENTRY_SIZE] = -{ - /* jmps @# */ - 0x4e, 0xf9, - /* Filled in by runtime linker with a magic address. */ - 0, 0, 0, 0, - /* Not used? */ - 0, 0 -}; - -/* bsrl */ -#define M68K_PLT_ENTRY_WORD0 (0x61ff) -/* Remaining words filled in later. */ - -/* An entry in the SunOS linker hash table. */ - -struct sunos_link_hash_entry -{ - struct aout_link_hash_entry root; - - /* If this is a dynamic symbol, this is its index into the dynamic - symbol table. This is initialized to -1. As the linker looks at - the input files, it changes this to -2 if it will be added to the - dynamic symbol table. After all the input files have been seen, - the linker will know whether to build a dynamic symbol table; if - it does build one, this becomes the index into the table. */ - long dynindx; - - /* If this is a dynamic symbol, this is the index of the name in the - dynamic symbol string table. */ - long dynstr_index; - - /* The offset into the global offset table used for this symbol. If - the symbol does not require a GOT entry, this is 0. */ - bfd_vma got_offset; - - /* The offset into the procedure linkage table used for this symbol. - If the symbol does not require a PLT entry, this is 0. */ - bfd_vma plt_offset; - - /* Some linker flags. */ - unsigned char flags; - /* Symbol is referenced by a regular object. */ -#define SUNOS_REF_REGULAR 01 - /* Symbol is defined by a regular object. */ -#define SUNOS_DEF_REGULAR 02 - /* Symbol is referenced by a dynamic object. */ -#define SUNOS_REF_DYNAMIC 04 - /* Symbol is defined by a dynamic object. */ -#define SUNOS_DEF_DYNAMIC 010 - /* Symbol is a constructor symbol in a regular object. */ -#define SUNOS_CONSTRUCTOR 020 -}; - -/* The SunOS linker hash table. */ - -struct sunos_link_hash_table -{ - struct aout_link_hash_table root; - - /* The object which holds the dynamic sections. */ - bfd *dynobj; - - /* Whether we have created the dynamic sections. */ - boolean dynamic_sections_created; - - /* Whether we need the dynamic sections. */ - boolean dynamic_sections_needed; - - /* The number of dynamic symbols. */ - size_t dynsymcount; - - /* The number of buckets in the hash table. */ - size_t bucketcount; - - /* The list of dynamic objects needed by dynamic objects included in - the link. */ - struct bfd_link_needed_list *needed; -}; - -/* Routine to create an entry in an SunOS link hash table. */ - -static struct bfd_hash_entry * -sunos_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct sunos_link_hash_entry *ret = (struct sunos_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct sunos_link_hash_entry *) NULL) - ret = ((struct sunos_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct sunos_link_hash_entry))); - if (ret == (struct sunos_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct sunos_link_hash_entry *) - NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields. */ - ret->dynindx = -1; - ret->dynstr_index = -1; - ret->got_offset = 0; - ret->plt_offset = 0; - ret->flags = 0; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a SunOS link hash table. */ - -static struct bfd_link_hash_table * -sunos_link_hash_table_create (abfd) - bfd *abfd; -{ - struct sunos_link_hash_table *ret; - - ret = ((struct sunos_link_hash_table *) - bfd_alloc (abfd, sizeof (struct sunos_link_hash_table))); - if (ret == (struct sunos_link_hash_table *) NULL) - return (struct bfd_link_hash_table *) NULL; - if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, - sunos_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->dynobj = NULL; - ret->dynamic_sections_created = false; - ret->dynamic_sections_needed = false; - ret->dynsymcount = 0; - ret->bucketcount = 0; - ret->needed = NULL; - - return &ret->root.root; -} - -/* Look up an entry in an SunOS link hash table. */ - -#define sunos_link_hash_lookup(table, string, create, copy, follow) \ - ((struct sunos_link_hash_entry *) \ - aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse a SunOS link hash table. */ - -#define sunos_link_hash_traverse(table, func, info) \ - (aout_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the SunOS link hash table from the info structure. This is - just a cast. */ - -#define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash)) - -static boolean sunos_scan_dynamic_symbol - PARAMS ((struct sunos_link_hash_entry *, PTR)); - -/* Create the dynamic sections needed if we are linking against a - dynamic object, or if we are linking PIC compiled code. ABFD is a - bfd we can attach the dynamic sections to. The linker script will - look for these special sections names and put them in the right - place in the output file. See include/aout/sun4.h for more details - of the dynamic linking information. */ - -static boolean -sunos_create_dynamic_sections (abfd, info, needed) - bfd *abfd; - struct bfd_link_info *info; - boolean needed; -{ - asection *s; - - if (! sunos_hash_table (info)->dynamic_sections_created) - { - flagword flags; - - sunos_hash_table (info)->dynobj = abfd; - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* The .dynamic section holds the basic dynamic information: the - sun4_dynamic structure, the dynamic debugger information, and - the sun4_dynamic_link structure. */ - s = bfd_make_section (abfd, ".dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .got section holds the global offset table. The address - is put in the ld_got field. */ - s = bfd_make_section (abfd, ".got"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .plt section holds the procedure linkage table. The - address is put in the ld_plt field. */ - s = bfd_make_section (abfd, ".plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_CODE) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .dynrel section holds the dynamic relocs. The address is - put in the ld_rel field. */ - s = bfd_make_section (abfd, ".dynrel"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .hash section holds the dynamic hash table. The address - is put in the ld_hash field. */ - s = bfd_make_section (abfd, ".hash"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .dynsym section holds the dynamic symbols. The address - is put in the ld_stab field. */ - s = bfd_make_section (abfd, ".dynsym"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .dynstr section holds the dynamic symbol string table. - The address is put in the ld_symbols field. */ - s = bfd_make_section (abfd, ".dynstr"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - sunos_hash_table (info)->dynamic_sections_created = true; - } - - if (needed && ! sunos_hash_table (info)->dynamic_sections_needed) - { - bfd *dynobj; - - dynobj = sunos_hash_table (info)->dynobj; - - s = bfd_get_section_by_name (dynobj, ".got"); - s->_raw_size = BYTES_IN_WORD; - - sunos_hash_table (info)->dynamic_sections_needed = true; - } - - return true; -} - -/* Add dynamic symbols during a link. This is called by the a.out - backend linker when it encounters an object with the DYNAMIC flag - set. */ - -static boolean -sunos_add_dynamic_symbols (abfd, info, symsp, sym_countp, stringsp) - bfd *abfd; - struct bfd_link_info *info; - struct external_nlist **symsp; - bfd_size_type *sym_countp; - char **stringsp; -{ - asection *s; - bfd *dynobj; - struct sunos_dynamic_info *dinfo; - unsigned long need; - - /* We do not want to include the sections in a dynamic object in the - output file. We hack by simply clobbering the list of sections - in the BFD. This could be handled more cleanly by, say, a new - section flag; the existing SEC_NEVER_LOAD flag is not the one we - want, because that one still implies that the section takes up - space in the output file. */ - abfd->sections = NULL; - - /* The native linker seems to just ignore dynamic objects when -r is - used. */ - if (info->relocateable) - return true; - - /* There's no hope of using a dynamic object which does not exactly - match the format of the output file. */ - if (info->hash->creator != abfd->xvec) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* Make sure we have all the required information. */ - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - - /* Make sure we have a .need and a .rules sections. These are only - needed if there really is a dynamic object in the link, so they - are not added by sunos_create_dynamic_sections. */ - dynobj = sunos_hash_table (info)->dynobj; - if (bfd_get_section_by_name (dynobj, ".need") == NULL) - { - /* The .need section holds the list of names of shared objets - which must be included at runtime. The address of this - section is put in the ld_need field. */ - s = bfd_make_section (dynobj, ".need"); - if (s == NULL - || ! bfd_set_section_flags (dynobj, s, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, s, 2)) - return false; - } - - if (bfd_get_section_by_name (dynobj, ".rules") == NULL) - { - /* The .rules section holds the path to search for shared - objects. The address of this section is put in the ld_rules - field. */ - s = bfd_make_section (dynobj, ".rules"); - if (s == NULL - || ! bfd_set_section_flags (dynobj, s, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, s, 2)) - return false; - } - - /* Pick up the dynamic symbols and return them to the caller. */ - if (! sunos_slurp_dynamic_symtab (abfd)) - return false; - - dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - *symsp = dinfo->dynsym; - *sym_countp = dinfo->dynsym_count; - *stringsp = dinfo->dynstr; - - /* Record information about any other objects needed by this one. */ - need = dinfo->dyninfo.ld_need; - while (need != 0) - { - bfd_byte buf[16]; - unsigned long name, flags; - unsigned short major_vno, minor_vno; - struct bfd_link_needed_list *needed, **pp; - bfd_byte b; - - if (bfd_seek (abfd, need, SEEK_SET) != 0 - || bfd_read (buf, 1, 16, abfd) != 16) - return false; - - /* For the format of an ld_need entry, see aout/sun4.h. We - should probably define structs for this manipulation. */ - - name = bfd_get_32 (abfd, buf); - flags = bfd_get_32 (abfd, buf + 4); - major_vno = bfd_get_16 (abfd, buf + 8); - minor_vno = bfd_get_16 (abfd, buf + 10); - need = bfd_get_32 (abfd, buf + 12); - - needed = (struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof (struct bfd_link_needed_list)); - if (needed == NULL) - return false; - needed->by = abfd; - - /* We return the name as [-l]name[.maj][.min]. */ - - if ((flags & 0x80000000) != 0) - bfd_alloc_grow (abfd, "-l", 2); - if (bfd_seek (abfd, name, SEEK_SET) != 0) - return false; - do - { - if (bfd_read (&b, 1, 1, abfd) != 1) - return false; - bfd_alloc_grow (abfd, &b, 1); - } - while (b != '\0'); - if (major_vno != 0) - { - char verbuf[30]; - - sprintf (verbuf, ".%d", major_vno); - bfd_alloc_grow (abfd, verbuf, strlen (verbuf)); - if (minor_vno != 0) - { - sprintf (verbuf, ".%d", minor_vno); - bfd_alloc_grow (abfd, verbuf, strlen (verbuf)); - } - } - needed->name = bfd_alloc_finish (abfd); - if (needed->name == NULL) - return false; - - needed->next = NULL; - - for (pp = &sunos_hash_table (info)->needed; - *pp != NULL; - pp = &(*pp)->next) - ; - *pp = needed; - } - - return true; -} - -/* Function to add a single symbol to the linker hash table. This is - a wrapper around _bfd_generic_link_add_one_symbol which handles the - tweaking needed for dynamic linking support. */ - -static boolean -sunos_add_one_symbol (info, abfd, name, flags, section, value, string, - copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct sunos_link_hash_entry *h; - int new_flag; - - if (! sunos_hash_table (info)->dynamic_sections_created) - { - /* We must create the dynamic sections while reading the input - files, even though at this point we don't know if any of the - sections will be needed. This will ensure that the dynamic - sections are mapped to the right output section. It does no - harm to create these sections if they are not needed. */ - if (! sunos_create_dynamic_sections (abfd, info, false)) - return false; - } - - if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0 - || ! bfd_is_und_section (section)) - h = sunos_link_hash_lookup (sunos_hash_table (info), name, true, copy, - false); - else - h = ((struct sunos_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false)); - if (h == NULL) - return false; - - if (hashp != NULL) - *hashp = (struct bfd_link_hash_entry *) h; - - /* Treat a common symbol in a dynamic object as defined in the .bss - section of the dynamic object. We don't want to allocate space - for it in our process image. */ - if ((abfd->flags & DYNAMIC) != 0 - && bfd_is_com_section (section)) - section = obj_bsssec (abfd); - - if (! bfd_is_und_section (section) - && h->root.root.type != bfd_link_hash_new - && h->root.root.type != bfd_link_hash_undefined - && h->root.root.type != bfd_link_hash_defweak) - { - /* We are defining the symbol, and it is already defined. This - is a potential multiple definition error. */ - if ((abfd->flags & DYNAMIC) != 0) - { - /* The definition we are adding is from a dynamic object. - We do not want this new definition to override the - existing definition, so we pretend it is just a - reference. */ - section = bfd_und_section_ptr; - } - else if (h->root.root.type == bfd_link_hash_defined - && h->root.root.u.def.section->owner != NULL - && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) - { - /* The existing definition is from a dynamic object. We - want to override it with the definition we just found. - Clobber the existing definition. */ - h->root.root.type = bfd_link_hash_new; - } - else if (h->root.root.type == bfd_link_hash_common - && (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0) - { - /* The existing definition is from a dynamic object. We - want to override it with the definition we just found. - Clobber the existing definition. We can't set it to new, - because it is on the undefined list. */ - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner; - } - } - - if ((abfd->flags & DYNAMIC) != 0 - && abfd->xvec == info->hash->creator - && (h->flags & SUNOS_CONSTRUCTOR) != 0) - { - /* The existing symbol is a constructor symbol, and this symbol - is from a dynamic object. A constructor symbol is actually a - definition, although the type will be bfd_link_hash_undefined - at this point. We want to ignore the definition from the - dynamic object. */ - section = bfd_und_section_ptr; - } - else if ((flags & BSF_CONSTRUCTOR) != 0 - && (abfd->flags & DYNAMIC) == 0 - && h->root.root.type == bfd_link_hash_defined - && h->root.root.u.def.section->owner != NULL - && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) - { - /* The existing symbol is defined by a dynamic object, and this - is a constructor symbol. As above, we want to force the use - of the constructor symbol from the regular object. */ - h->root.root.type = bfd_link_hash_new; - } - - /* Do the usual procedure for adding a symbol. */ - if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp)) - return false; - - if (abfd->xvec == info->hash->creator) - { - /* Set a flag in the hash table entry indicating the type of - reference or definition we just found. Keep a count of the - number of dynamic symbols we find. A dynamic symbol is one - which is referenced or defined by both a regular object and a - shared object. */ - if ((abfd->flags & DYNAMIC) == 0) - { - if (bfd_is_und_section (section)) - new_flag = SUNOS_REF_REGULAR; - else - new_flag = SUNOS_DEF_REGULAR; - } - else - { - if (bfd_is_und_section (section)) - new_flag = SUNOS_REF_DYNAMIC; - else - new_flag = SUNOS_DEF_DYNAMIC; - } - h->flags |= new_flag; - - if (h->dynindx == -1 - && (h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0) - { - ++sunos_hash_table (info)->dynsymcount; - h->dynindx = -2; - } - - if ((flags & BSF_CONSTRUCTOR) != 0 - && (abfd->flags & DYNAMIC) == 0) - h->flags |= SUNOS_CONSTRUCTOR; - } - - return true; -} - -/* Return the list of objects needed by BFD. */ - -/*ARGSUSED*/ -struct bfd_link_needed_list * -bfd_sunos_get_needed_list (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (info->hash->creator != &MY(vec)) - return NULL; - return sunos_hash_table (info)->needed; -} - -/* Record an assignment made to a symbol by a linker script. We need - this in case some dynamic object refers to this symbol. */ - -boolean -bfd_sunos_record_link_assignment (output_bfd, info, name) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; -{ - struct sunos_link_hash_entry *h; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* This is called after we have examined all the input objects. If - the symbol does not exist, it merely means that no object refers - to it, and we can just ignore it at this point. */ - h = sunos_link_hash_lookup (sunos_hash_table (info), name, - false, false, false); - if (h == NULL) - return true; - - /* In a shared library, the __DYNAMIC symbol does not appear in the - dynamic symbol table. */ - if (! info->shared || strcmp (name, "__DYNAMIC") != 0) - { - h->flags |= SUNOS_DEF_REGULAR; - - if (h->dynindx == -1) - { - ++sunos_hash_table (info)->dynsymcount; - h->dynindx = -2; - } - } - - return true; -} - -/* Set up the sizes and contents of the dynamic sections created in - sunos_add_dynamic_symbols. This is called by the SunOS linker - emulation before_allocation routine. We must set the sizes of the - sections before the linker sets the addresses of the various - sections. This unfortunately requires reading all the relocs so - that we can work out which ones need to become dynamic relocs. If - info->keep_memory is true, we keep the relocs in memory; otherwise, - we discard them, and will read them again later. */ - -boolean -bfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr, - srulesptr) - bfd *output_bfd; - struct bfd_link_info *info; - asection **sdynptr; - asection **sneedptr; - asection **srulesptr; -{ - bfd *dynobj; - size_t dynsymcount; - struct sunos_link_hash_entry *h; - asection *s; - size_t bucketcount; - size_t hashalloc; - size_t i; - bfd *sub; - - *sdynptr = NULL; - *sneedptr = NULL; - *srulesptr = NULL; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* Look through all the input BFD's and read their relocs. It would - be better if we didn't have to do this, but there is no other way - to determine the number of dynamic relocs we need, and, more - importantly, there is no other way to know which symbols should - get an entry in the procedure linkage table. */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - if ((sub->flags & DYNAMIC) == 0 - && sub->xvec == output_bfd->xvec) - { - if (! sunos_scan_relocs (info, sub, obj_textsec (sub), - exec_hdr (sub)->a_trsize) - || ! sunos_scan_relocs (info, sub, obj_datasec (sub), - exec_hdr (sub)->a_drsize)) - return false; - } - } - - dynobj = sunos_hash_table (info)->dynobj; - dynsymcount = sunos_hash_table (info)->dynsymcount; - - /* If there were no dynamic objects in the link, and we don't need - to build a global offset table, there is nothing to do here. */ - if (! sunos_hash_table (info)->dynamic_sections_needed) - return true; - - /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it. */ - h = sunos_link_hash_lookup (sunos_hash_table (info), - "__GLOBAL_OFFSET_TABLE_", false, false, false); - if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0) - { - h->flags |= SUNOS_DEF_REGULAR; - if (h->dynindx == -1) - { - ++sunos_hash_table (info)->dynsymcount; - h->dynindx = -2; - } - h->root.root.type = bfd_link_hash_defined; - h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got"); - h->root.root.u.def.value = 0; - } - - /* The .dynamic section is always the same size. */ - s = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (s != NULL); - s->_raw_size = (sizeof (struct external_sun4_dynamic) - + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE - + sizeof (struct external_sun4_dynamic_link)); - - /* Set the size of the .dynsym and .hash sections. We counted the - number of dynamic symbols as we read the input files. We will - build the dynamic symbol table (.dynsym) and the hash table - (.hash) when we build the final symbol table, because until then - we do not know the correct value to give the symbols. We build - the dynamic symbol string table (.dynstr) in a traversal of the - symbol table using sunos_scan_dynamic_symbol. */ - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - s->_raw_size = dynsymcount * sizeof (struct external_nlist); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - - /* The number of buckets is just the number of symbols divided by - four. To compute the final size of the hash table, we must - actually compute the hash table. Normally we need exactly as - many entries in the hash table as there are dynamic symbols, but - if some of the buckets are not used we will need additional - entries. In the worst case, every symbol will hash to the same - bucket, and we will need BUCKETCOUNT - 1 extra entries. */ - if (dynsymcount >= 4) - bucketcount = dynsymcount / 4; - else if (dynsymcount > 0) - bucketcount = dynsymcount; - else - bucketcount = 1; - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE; - s->contents = (bfd_byte *) bfd_alloc (dynobj, hashalloc); - if (s->contents == NULL && dynsymcount > 0) - return false; - memset (s->contents, 0, hashalloc); - for (i = 0; i < bucketcount; i++) - PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE); - s->_raw_size = bucketcount * HASH_ENTRY_SIZE; - - sunos_hash_table (info)->bucketcount = bucketcount; - - /* Scan all the symbols, place them in the dynamic symbol table, and - build the dynamic hash table. We reuse dynsymcount as a counter - for the number of symbols we have added so far. */ - sunos_hash_table (info)->dynsymcount = 0; - sunos_link_hash_traverse (sunos_hash_table (info), - sunos_scan_dynamic_symbol, - (PTR) info); - BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount); - - /* The SunOS native linker seems to align the total size of the - symbol strings to a multiple of 8. I don't know if this is - important, but it can't hurt much. */ - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - if ((s->_raw_size & 7) != 0) - { - bfd_size_type add; - bfd_byte *contents; - - add = 8 - (s->_raw_size & 7); - contents = (bfd_byte *) bfd_realloc (s->contents, - (size_t) (s->_raw_size + add)); - if (contents == NULL) - return false; - memset (contents + s->_raw_size, 0, (size_t) add); - s->contents = contents; - s->_raw_size += add; - } - - /* Now that we have worked out the sizes of the procedure linkage - table and the dynamic relocs, allocate storage for them. */ - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - if (s->_raw_size != 0) - { - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL) - return false; - - /* Fill in the first entry in the table. */ - switch (bfd_get_arch (dynobj)) - { - case bfd_arch_sparc: - memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE); - break; - - case bfd_arch_m68k: - memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE); - break; - - default: - abort (); - } - } - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - if (s->_raw_size != 0) - { - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL) - return false; - } - /* We use the reloc_count field to keep track of how many of the - relocs we have output so far. */ - s->reloc_count = 0; - - /* Make space for the global offset table. */ - s = bfd_get_section_by_name (dynobj, ".got"); - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL) - return false; - - *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic"); - *sneedptr = bfd_get_section_by_name (dynobj, ".need"); - *srulesptr = bfd_get_section_by_name (dynobj, ".rules"); - - return true; -} - -/* Scan the relocs for an input section. */ - -static boolean -sunos_scan_relocs (info, abfd, sec, rel_size) - struct bfd_link_info *info; - bfd *abfd; - asection *sec; - bfd_size_type rel_size; -{ - PTR relocs; - PTR free_relocs = NULL; - - if (rel_size == 0) - return true; - - if (! info->keep_memory) - relocs = free_relocs = bfd_malloc ((size_t) rel_size); - else - { - struct aout_section_data_struct *n; - - n = ((struct aout_section_data_struct *) - bfd_alloc (abfd, sizeof (struct aout_section_data_struct))); - if (n == NULL) - relocs = NULL; - else - { - set_aout_section_data (sec, n); - relocs = bfd_malloc ((size_t) rel_size); - aout_section_data (sec)->relocs = relocs; - } - } - if (relocs == NULL) - return false; - - if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 - || bfd_read (relocs, 1, rel_size, abfd) != rel_size) - goto error_return; - - if (obj_reloc_entry_size (abfd) == RELOC_STD_SIZE) - { - if (! sunos_scan_std_relocs (info, abfd, sec, - (struct reloc_std_external *) relocs, - rel_size)) - goto error_return; - } - else - { - if (! sunos_scan_ext_relocs (info, abfd, sec, - (struct reloc_ext_external *) relocs, - rel_size)) - goto error_return; - } - - if (free_relocs != NULL) - free (free_relocs); - - return true; - - error_return: - if (free_relocs != NULL) - free (free_relocs); - return false; -} - -/* Scan the relocs for an input section using standard relocs. We - need to figure out what to do for each reloc against a dynamic - symbol. If the symbol is in the .text section, an entry is made in - the procedure linkage table. Note that this will do the wrong - thing if the symbol is actually data; I don't think the Sun 3 - native linker handles this case correctly either. If the symbol is - not in the .text section, we must preserve the reloc as a dynamic - reloc. FIXME: We should also handle the PIC relocs here by - building global offset table entries. */ - -static boolean -sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size) - struct bfd_link_info *info; - bfd *abfd; - asection *sec; - const struct reloc_std_external *relocs; - bfd_size_type rel_size; -{ - bfd *dynobj; - asection *splt = NULL; - asection *srel = NULL; - struct sunos_link_hash_entry **sym_hashes; - const struct reloc_std_external *rel, *relend; - - /* We only know how to handle m68k plt entries. */ - if (bfd_get_arch (abfd) != bfd_arch_m68k) - { - bfd_set_error (bfd_error_invalid_target); - return false; - } - - dynobj = NULL; - - sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd); - - relend = relocs + rel_size / RELOC_STD_SIZE; - for (rel = relocs; rel < relend; rel++) - { - int r_index; - struct sunos_link_hash_entry *h; - - /* We only want relocs against external symbols. */ - if (bfd_header_big_endian (abfd)) - { - if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG) == 0) - continue; - } - else - { - if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE) == 0) - continue; - } - - /* Get the symbol index. */ - if (bfd_header_big_endian (abfd)) - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - else - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - - /* Get the hash table entry. */ - h = sym_hashes[r_index]; - if (h == NULL) - { - /* This should not normally happen, but it will in any case - be caught in the relocation phase. */ - continue; - } - - /* At this point common symbols have already been allocated, so - we don't have to worry about them. We need to consider that - we may have already seen this symbol and marked it undefined; - if the symbol is really undefined, then SUNOS_DEF_DYNAMIC - will be zero. */ - if (h->root.root.type != bfd_link_hash_defined - && h->root.root.type != bfd_link_hash_defweak - && h->root.root.type != bfd_link_hash_undefined) - continue; - - if ((h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->flags & SUNOS_DEF_REGULAR) != 0) - continue; - - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && srel != NULL); - } - - BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0); - BFD_ASSERT (h->plt_offset != 0 - || ((h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - ? (h->root.root.u.def.section->owner->flags - & DYNAMIC) != 0 - : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0)); - - /* This reloc is against a symbol defined only by a dynamic - object. */ - - if (h->root.root.type == bfd_link_hash_undefined) - { - /* Presumably this symbol was marked as being undefined by - an earlier reloc. */ - srel->_raw_size += RELOC_STD_SIZE; - } - else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0) - { - bfd *sub; - - /* This reloc is not in the .text section. It must be - copied into the dynamic relocs. We mark the symbol as - being undefined. */ - srel->_raw_size += RELOC_STD_SIZE; - sub = h->root.root.u.def.section->owner; - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = sub; - } - else - { - /* This symbol is in the .text section. We must give it an - entry in the procedure linkage table, if we have not - already done so. We change the definition of the symbol - to the .plt section; this will cause relocs against it to - be handled correctly. */ - if (h->plt_offset == 0) - { - if (splt->_raw_size == 0) - splt->_raw_size = M68K_PLT_ENTRY_SIZE; - h->plt_offset = splt->_raw_size; - - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - { - h->root.root.u.def.section = splt; - h->root.root.u.def.value = splt->_raw_size; - } - - splt->_raw_size += M68K_PLT_ENTRY_SIZE; - - /* We may also need a dynamic reloc entry. */ - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - srel->_raw_size += RELOC_STD_SIZE; - } - } - } - - return true; -} - -/* Scan the relocs for an input section using extended relocs. We - need to figure out what to do for each reloc against a dynamic - symbol. If the reloc is a WDISP30, and the symbol is in the .text - section, an entry is made in the procedure linkage table. - Otherwise, we must preserve the reloc as a dynamic reloc. */ - -static boolean -sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size) - struct bfd_link_info *info; - bfd *abfd; - asection *sec; - const struct reloc_ext_external *relocs; - bfd_size_type rel_size; -{ - bfd *dynobj; - struct sunos_link_hash_entry **sym_hashes; - const struct reloc_ext_external *rel, *relend; - asection *splt = NULL; - asection *sgot = NULL; - asection *srel = NULL; - - /* We only know how to handle SPARC plt entries. */ - if (bfd_get_arch (abfd) != bfd_arch_sparc) - { - bfd_set_error (bfd_error_invalid_target); - return false; - } - - dynobj = NULL; - - sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd); - - relend = relocs + rel_size / RELOC_EXT_SIZE; - for (rel = relocs; rel < relend; rel++) - { - unsigned int r_index; - int r_extern; - int r_type; - struct sunos_link_hash_entry *h = NULL; - - /* Swap in the reloc information. */ - if (bfd_header_big_endian (abfd)) - { - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG); - } - else - { - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - if (r_extern) - { - h = sym_hashes[r_index]; - if (h == NULL) - { - /* This should not normally happen, but it will in any - case be caught in the relocation phase. */ - continue; - } - } - - /* If this is a base relative reloc, we need to make an entry in - the .got section. */ - if (r_type == RELOC_BASE10 - || r_type == RELOC_BASE13 - || r_type == RELOC_BASE22) - { - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - } - - if (r_extern) - { - if (h->got_offset != 0) - continue; - - h->got_offset = sgot->_raw_size; - } - else - { - if (r_index >= bfd_get_symcount (abfd)) - { - /* This is abnormal, but should be caught in the - relocation phase. */ - continue; - } - - if (adata (abfd).local_got_offsets == NULL) - { - adata (abfd).local_got_offsets = - (bfd_vma *) bfd_zalloc (abfd, - (bfd_get_symcount (abfd) - * sizeof (bfd_vma))); - if (adata (abfd).local_got_offsets == NULL) - return false; - } - - if (adata (abfd).local_got_offsets[r_index] != 0) - continue; - - adata (abfd).local_got_offsets[r_index] = sgot->_raw_size; - } - - sgot->_raw_size += BYTES_IN_WORD; - - /* If we are making a shared library, or if the symbol is - defined by a dynamic object, we will need a dynamic reloc - entry. */ - if (info->shared - || (h != NULL - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0)) - srel->_raw_size += RELOC_EXT_SIZE; - - continue; - } - - /* Otherwise, we are only interested in relocs against symbols - defined in dynamic objects but not in regular objects. We - only need to consider relocs against external symbols. */ - if (! r_extern) - { - /* But, if we are creating a shared library, we need to - generate an absolute reloc. */ - if (info->shared) - { - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - } - - srel->_raw_size += RELOC_EXT_SIZE; - } - - continue; - } - - /* At this point common symbols have already been allocated, so - we don't have to worry about them. We need to consider that - we may have already seen this symbol and marked it undefined; - if the symbol is really undefined, then SUNOS_DEF_DYNAMIC - will be zero. */ - if (h->root.root.type != bfd_link_hash_defined - && h->root.root.type != bfd_link_hash_defweak - && h->root.root.type != bfd_link_hash_undefined) - continue; - - if (r_type != RELOC_JMP_TBL - && ! info->shared - && ((h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->flags & SUNOS_DEF_REGULAR) != 0)) - continue; - - if (r_type == RELOC_JMP_TBL - && ! info->shared - && (h->flags & SUNOS_DEF_DYNAMIC) == 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0) - { - /* This symbol is apparently undefined. Don't do anything - here; just let the relocation routine report an undefined - symbol. */ - continue; - } - - if (strcmp (h->root.root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0) - continue; - - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - } - - BFD_ASSERT (r_type == RELOC_JMP_TBL - || info->shared - || (h->flags & SUNOS_REF_REGULAR) != 0); - BFD_ASSERT (r_type == RELOC_JMP_TBL - || info->shared - || h->plt_offset != 0 - || ((h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - ? (h->root.root.u.def.section->owner->flags - & DYNAMIC) != 0 - : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0)); - - /* This reloc is against a symbol defined only by a dynamic - object, or it is a jump table reloc from PIC compiled code. */ - - if (r_type != RELOC_JMP_TBL - && h->root.root.type == bfd_link_hash_undefined) - { - /* Presumably this symbol was marked as being undefined by - an earlier reloc. */ - srel->_raw_size += RELOC_EXT_SIZE; - } - else if (r_type != RELOC_JMP_TBL - && (h->root.root.u.def.section->flags & SEC_CODE) == 0) - { - bfd *sub; - - /* This reloc is not in the .text section. It must be - copied into the dynamic relocs. We mark the symbol as - being undefined. */ - srel->_raw_size += RELOC_EXT_SIZE; - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - { - sub = h->root.root.u.def.section->owner; - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = sub; - } - } - else - { - /* This symbol is in the .text section. We must give it an - entry in the procedure linkage table, if we have not - already done so. We change the definition of the symbol - to the .plt section; this will cause relocs against it to - be handled correctly. */ - if (h->plt_offset == 0) - { - if (splt->_raw_size == 0) - splt->_raw_size = SPARC_PLT_ENTRY_SIZE; - h->plt_offset = splt->_raw_size; - - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - { - if (h->root.root.type == bfd_link_hash_undefined) - h->root.root.type = bfd_link_hash_defined; - h->root.root.u.def.section = splt; - h->root.root.u.def.value = splt->_raw_size; - } - - splt->_raw_size += SPARC_PLT_ENTRY_SIZE; - - /* We will also need a dynamic reloc entry, unless this - is a JMP_TBL reloc produced by linking PIC compiled - code, and we are not making a shared library. */ - if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) - srel->_raw_size += RELOC_EXT_SIZE; - } - - /* If we are creating a shared library, we need to copy over - any reloc other than a jump table reloc. */ - if (info->shared && r_type != RELOC_JMP_TBL) - srel->_raw_size += RELOC_EXT_SIZE; - } - } - - return true; -} - -/* Build the hash table of dynamic symbols, and to mark as written all - symbols from dynamic objects which we do not plan to write out. */ - -static boolean -sunos_scan_dynamic_symbol (h, data) - struct sunos_link_hash_entry *h; - PTR data; -{ - struct bfd_link_info *info = (struct bfd_link_info *) data; - - /* Set the written flag for symbols we do not want to write out as - part of the regular symbol table. This is all symbols which are - not defined in a regular object file. For some reason symbols - which are referenced by a regular object and defined by a dynamic - object do not seem to show up in the regular symbol table. It is - possible for a symbol to have only SUNOS_REF_REGULAR set here, it - is an undefined symbol which was turned into a common symbol - because it was found in an archive object which was not included - in the link. */ - if ((h->flags & SUNOS_DEF_REGULAR) == 0 - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && strcmp (h->root.root.root.string, "__DYNAMIC") != 0) - h->root.written = true; - - /* If this symbol is defined by a dynamic object and referenced by a - regular object, see whether we gave it a reasonable value while - scanning the relocs. */ - - if ((h->flags & SUNOS_DEF_REGULAR) == 0 - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && (h->flags & SUNOS_REF_REGULAR) != 0) - { - if ((h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - && ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) - && h->root.root.u.def.section->output_section == NULL) - { - bfd *sub; - - /* This symbol is currently defined in a dynamic section - which is not being put into the output file. This - implies that there is no reloc against the symbol. I'm - not sure why this case would ever occur. In any case, we - change the symbol to be undefined. */ - sub = h->root.root.u.def.section->owner; - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = sub; - } - } - - /* If this symbol is defined or referenced by a regular file, add it - to the dynamic symbols. */ - if ((h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0) - { - asection *s; - size_t len; - bfd_byte *contents; - unsigned char *name; - unsigned long hash; - bfd *dynobj; - - BFD_ASSERT (h->dynindx == -2); - - dynobj = sunos_hash_table (info)->dynobj; - - h->dynindx = sunos_hash_table (info)->dynsymcount; - ++sunos_hash_table (info)->dynsymcount; - - len = strlen (h->root.root.root.string); - - /* We don't bother to construct a BFD hash table for the strings - which are the names of the dynamic symbols. Using a hash - table for the regular symbols is beneficial, because the - regular symbols includes the debugging symbols, which have - long names and are often duplicated in several object files. - There are no debugging symbols in the dynamic symbols. */ - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - contents = (bfd_byte *) bfd_realloc (s->contents, - s->_raw_size + len + 1); - if (contents == NULL) - return false; - s->contents = contents; - - h->dynstr_index = s->_raw_size; - strcpy (contents + s->_raw_size, h->root.root.root.string); - s->_raw_size += len + 1; - - /* Add it to the dynamic hash table. */ - name = (unsigned char *) h->root.root.root.string; - hash = 0; - while (*name != '\0') - hash = (hash << 1) + *name++; - hash &= 0x7fffffff; - hash %= sunos_hash_table (info)->bucketcount; - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - - if (GET_SWORD (dynobj, s->contents + hash * HASH_ENTRY_SIZE) == -1) - PUT_WORD (dynobj, h->dynindx, s->contents + hash * HASH_ENTRY_SIZE); - else - { - bfd_vma next; - - next = GET_WORD (dynobj, - (s->contents - + hash * HASH_ENTRY_SIZE - + BYTES_IN_WORD)); - PUT_WORD (dynobj, s->_raw_size / HASH_ENTRY_SIZE, - s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD); - PUT_WORD (dynobj, h->dynindx, s->contents + s->_raw_size); - PUT_WORD (dynobj, next, s->contents + s->_raw_size + BYTES_IN_WORD); - s->_raw_size += HASH_ENTRY_SIZE; - } - } - - return true; -} - -/* Link a dynamic object. We actually don't have anything to do at - this point. This entry point exists to prevent the regular linker - code from doing anything with the object. */ - -/*ARGSUSED*/ -static boolean -sunos_link_dynamic_object (info, abfd) - struct bfd_link_info *info; - bfd *abfd; -{ - return true; -} - -/* Write out a dynamic symbol. This is called by the final traversal - over the symbol table. */ - -static boolean -sunos_write_dynamic_symbol (output_bfd, info, harg) - bfd *output_bfd; - struct bfd_link_info *info; - struct aout_link_hash_entry *harg; -{ - struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg; - int type; - bfd_vma val; - asection *s; - struct external_nlist *outsym; - - if (h->dynindx < 0) - return true; - - switch (h->root.root.type) - { - default: - case bfd_link_hash_new: - abort (); - /* Avoid variable not initialized warnings. */ - return true; - case bfd_link_hash_undefined: - type = N_UNDF | N_EXT; - val = 0; - break; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - asection *sec; - asection *output_section; - - sec = h->root.root.u.def.section; - output_section = sec->output_section; - BFD_ASSERT (bfd_is_abs_section (output_section) - || output_section->owner == output_bfd); - if (h->plt_offset != 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0) - { - type = N_UNDF | N_EXT; - val = 0; - } - else - { - if (output_section == obj_textsec (output_bfd)) - type = (h->root.root.type == bfd_link_hash_defined - ? N_TEXT - : N_WEAKT); - else if (output_section == obj_datasec (output_bfd)) - type = (h->root.root.type == bfd_link_hash_defined - ? N_DATA - : N_WEAKD); - else if (output_section == obj_bsssec (output_bfd)) - type = (h->root.root.type == bfd_link_hash_defined - ? N_BSS - : N_WEAKB); - else - type = (h->root.root.type == bfd_link_hash_defined - ? N_ABS - : N_WEAKA); - type |= N_EXT; - val = (h->root.root.u.def.value - + output_section->vma - + sec->output_offset); - } - } - break; - case bfd_link_hash_common: - type = N_UNDF | N_EXT; - val = h->root.root.u.c.size; - break; - case bfd_link_hash_undefweak: - type = N_WEAKU; - val = 0; - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: Ignore these for now. The circumstances under which - they should be written out are not clear to me. */ - return true; - } - - s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - outsym = ((struct external_nlist *) - (s->contents + h->dynindx * EXTERNAL_NLIST_SIZE)); - - bfd_h_put_8 (output_bfd, type, outsym->e_type); - bfd_h_put_8 (output_bfd, 0, outsym->e_other); - - /* FIXME: The native linker doesn't use 0 for desc. It seems to use - one less than the desc value in the shared library, although that - seems unlikely. */ - bfd_h_put_16 (output_bfd, 0, outsym->e_desc); - - PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx); - PUT_WORD (output_bfd, val, outsym->e_value); - - /* If this symbol is in the procedure linkage table, fill in the - table entry. */ - if (h->plt_offset != 0) - { - bfd *dynobj; - asection *splt; - bfd_byte *p; - asection *s; - bfd_vma r_address; - - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - p = splt->contents + h->plt_offset; - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - - r_address = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - - switch (bfd_get_arch (output_bfd)) - { - case bfd_arch_sparc: - if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) - { - bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD0, p); - bfd_put_32 (output_bfd, - (SPARC_PLT_ENTRY_WORD1 - + (((- (h->plt_offset + 4) >> 2) - & 0x3fffffff))), - p + 4); - bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD2 + s->reloc_count, - p + 8); - } - else - { - bfd_vma val; - - val = (h->root.root.u.def.section->output_section->vma - + h->root.root.u.def.section->output_offset - + h->root.root.u.def.value); - bfd_put_32 (output_bfd, - SPARC_PLT_PIC_WORD0 + ((val >> 10) & 0x3fffff), - p); - bfd_put_32 (output_bfd, - SPARC_PLT_PIC_WORD1 + (val & 0x3ff), - p + 4); - bfd_put_32 (output_bfd, SPARC_PLT_PIC_WORD2, p + 8); - } - break; - - case bfd_arch_m68k: - if (! info->shared && (h->flags & SUNOS_DEF_REGULAR) != 0) - abort (); - bfd_put_16 (output_bfd, M68K_PLT_ENTRY_WORD0, p); - bfd_put_32 (output_bfd, (- (h->plt_offset + 2)), p + 2); - bfd_put_16 (output_bfd, s->reloc_count, p + 6); - r_address += 2; - break; - - default: - abort (); - } - - /* We also need to add a jump table reloc, unless this is the - result of a JMP_TBL reloc from PIC compiled code. */ - if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) - { - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) - < s->_raw_size); - p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd); - if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) p; - PUT_WORD (output_bfd, r_address, srel->r_address); - if (bfd_header_big_endian (output_bfd)) - { - srel->r_index[0] = h->dynindx >> 16; - srel->r_index[1] = h->dynindx >> 8; - srel->r_index[2] = h->dynindx; - srel->r_type[0] = (RELOC_STD_BITS_EXTERN_BIG - | RELOC_STD_BITS_JMPTABLE_BIG); - } - else - { - srel->r_index[2] = h->dynindx >> 16; - srel->r_index[1] = h->dynindx >> 8; - srel->r_index[0] = h->dynindx; - srel->r_type[0] = (RELOC_STD_BITS_EXTERN_LITTLE - | RELOC_STD_BITS_JMPTABLE_LITTLE); - } - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) p; - PUT_WORD (output_bfd, r_address, erel->r_address); - if (bfd_header_big_endian (output_bfd)) - { - erel->r_index[0] = h->dynindx >> 16; - erel->r_index[1] = h->dynindx >> 8; - erel->r_index[2] = h->dynindx; - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_BIG - | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_BIG)); - } - else - { - erel->r_index[2] = h->dynindx >> 16; - erel->r_index[1] = h->dynindx >> 8; - erel->r_index[0] = h->dynindx; - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_LITTLE - | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_LITTLE)); - } - PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend); - } - - ++s->reloc_count; - } - } - - return true; -} - -/* This is called for each reloc against an external symbol. If this - is a reloc which are are going to copy as a dynamic reloc, then - copy it over, and tell the caller to not bother processing this - reloc. */ - -/*ARGSUSED*/ -static boolean -sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc, - contents, skip, relocationp) - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - struct aout_link_hash_entry *harg; - PTR reloc; - bfd_byte *contents; - boolean *skip; - bfd_vma *relocationp; -{ - struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg; - bfd *dynobj; - boolean baserel; - boolean jmptbl; - asection *s; - bfd_byte *p; - long indx; - - *skip = false; - - dynobj = sunos_hash_table (info)->dynobj; - - if (h != NULL && h->plt_offset != 0) - { - asection *splt; - - /* Redirect the relocation to the PLT entry. */ - splt = bfd_get_section_by_name (dynobj, ".plt"); - *relocationp = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - } - - if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) reloc; - if (bfd_header_big_endian (input_bfd)) - { - baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); - jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - } - else - { - baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE)); - jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE)); - } - } - else - { - struct reloc_ext_external *erel; - int r_type; - - erel = (struct reloc_ext_external *) reloc; - if (bfd_header_big_endian (input_bfd)) - r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG); - else - r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE); - baserel = (r_type == RELOC_BASE10 - || r_type == RELOC_BASE13 - || r_type == RELOC_BASE22); - jmptbl = r_type == RELOC_JMP_TBL; - } - - if (baserel) - { - bfd_vma *got_offsetp; - asection *sgot; - - if (h != NULL) - got_offsetp = &h->got_offset; - else if (adata (input_bfd).local_got_offsets == NULL) - got_offsetp = NULL; - else - { - struct reloc_std_external *srel; - int r_index; - - srel = (struct reloc_std_external *) reloc; - if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE) - { - if (bfd_header_big_endian (input_bfd)) - r_index = ((srel->r_index[0] << 16) - | (srel->r_index[1] << 8) - | srel->r_index[2]); - else - r_index = ((srel->r_index[2] << 16) - | (srel->r_index[1] << 8) - | srel->r_index[0]); - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) reloc; - if (bfd_header_big_endian (input_bfd)) - r_index = ((erel->r_index[0] << 16) - | (erel->r_index[1] << 8) - | erel->r_index[2]); - else - r_index = ((erel->r_index[2] << 16) - | (erel->r_index[1] << 8) - | erel->r_index[0]); - } - - got_offsetp = adata (input_bfd).local_got_offsets + r_index; - } - - BFD_ASSERT (got_offsetp != NULL && *got_offsetp != 0); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - - /* We set the least significant bit to indicate whether we have - already initialized the GOT entry. */ - if ((*got_offsetp & 1) == 0) - { - if (h == NULL - || (! info->shared - && ((h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->flags & SUNOS_DEF_REGULAR) != 0))) - PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp); - else - PUT_WORD (dynobj, 0, sgot->contents + *got_offsetp); - - if (info->shared - || (h != NULL - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0)) - { - /* We need to create a GLOB_DAT or 32 reloc to tell the - dynamic linker to fill in this entry in the table. */ - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) - < s->_raw_size); - - p = (s->contents - + s->reloc_count * obj_reloc_entry_size (dynobj)); - - if (h != NULL) - indx = h->dynindx; - else - indx = 0; - - if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) p; - PUT_WORD (dynobj, - (*got_offsetp - + sgot->output_section->vma - + sgot->output_offset), - srel->r_address); - if (bfd_header_big_endian (dynobj)) - { - srel->r_index[0] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[2] = indx; - if (h == NULL) - srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_BIG; - else - srel->r_type[0] = - (RELOC_STD_BITS_EXTERN_BIG - | RELOC_STD_BITS_BASEREL_BIG - | RELOC_STD_BITS_RELATIVE_BIG - | (2 << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - srel->r_index[2] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[0] = indx; - if (h == NULL) - srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_LITTLE; - else - srel->r_type[0] = - (RELOC_STD_BITS_EXTERN_LITTLE - | RELOC_STD_BITS_BASEREL_LITTLE - | RELOC_STD_BITS_RELATIVE_LITTLE - | (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) p; - PUT_WORD (dynobj, - (*got_offsetp - + sgot->output_section->vma - + sgot->output_offset), - erel->r_address); - if (bfd_header_big_endian (dynobj)) - { - erel->r_index[0] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[2] = indx; - if (h == NULL) - erel->r_type[0] = - RELOC_32 << RELOC_EXT_BITS_TYPE_SH_BIG; - else - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_BIG - | (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG)); - } - else - { - erel->r_index[2] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[0] = indx; - if (h == NULL) - erel->r_type[0] = - RELOC_32 << RELOC_EXT_BITS_TYPE_SH_LITTLE; - else - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_LITTLE - | (RELOC_GLOB_DAT - << RELOC_EXT_BITS_TYPE_SH_LITTLE)); - } - PUT_WORD (dynobj, 0, erel->r_addend); - } - - ++s->reloc_count; - } - - *got_offsetp |= 1; - } - - *relocationp = sgot->vma + (*got_offsetp &~ 1); - - /* There is nothing else to do for a base relative reloc. */ - return true; - } - - if (! sunos_hash_table (info)->dynamic_sections_needed) - return true; - if (! info->shared) - { - if (h == NULL - || h->dynindx == -1 - || h->root.root.type != bfd_link_hash_undefined - || (h->flags & SUNOS_DEF_REGULAR) != 0 - || (h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0) - return true; - } - else - { - if (h != NULL - && (h->dynindx == -1 - || jmptbl - || strcmp (h->root.root.root.string, - "__GLOBAL_OFFSET_TABLE_") == 0)) - return true; - } - - /* It looks like this is a reloc we are supposed to copy. */ - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->_raw_size); - - p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj); - - /* Copy the reloc over. */ - memcpy (p, reloc, obj_reloc_entry_size (dynobj)); - - if (h != NULL) - indx = h->dynindx; - else - indx = 0; - - /* Adjust the address and symbol index. */ - if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) p; - PUT_WORD (dynobj, - (GET_WORD (dynobj, srel->r_address) - + input_section->output_section->vma - + input_section->output_offset), - srel->r_address); - if (bfd_header_big_endian (dynobj)) - { - srel->r_index[0] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[2] = indx; - } - else - { - srel->r_index[2] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[0] = indx; - } - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) p; - PUT_WORD (dynobj, - (GET_WORD (dynobj, erel->r_address) - + input_section->output_section->vma - + input_section->output_offset), - erel->r_address); - if (bfd_header_big_endian (dynobj)) - { - erel->r_index[0] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[2] = indx; - } - else - { - erel->r_index[2] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[0] = indx; - } - } - - ++s->reloc_count; - - if (h != NULL) - *skip = true; - - return true; -} - -/* Finish up the dynamic linking information. */ - -static boolean -sunos_finish_dynamic_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *o; - asection *s; - asection *sdyn; - struct external_sun4_dynamic esd; - struct external_sun4_dynamic_link esdl; - - if (! sunos_hash_table (info)->dynamic_sections_needed) - return true; - - dynobj = sunos_hash_table (info)->dynobj; - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (sdyn != NULL); - - /* Finish up the .need section. The linker emulation code filled it - in, but with offsets from the start of the section instead of - real addresses. Now that we know the section location, we can - fill in the final values. */ - s = bfd_get_section_by_name (dynobj, ".need"); - if (s != NULL && s->_raw_size != 0) - { - file_ptr filepos; - bfd_byte *p; - - filepos = s->output_section->filepos + s->output_offset; - p = s->contents; - while (1) - { - bfd_vma val; - - PUT_WORD (dynobj, GET_WORD (dynobj, p) + filepos, p); - val = GET_WORD (dynobj, p + 12); - if (val == 0) - break; - PUT_WORD (dynobj, val + filepos, p + 12); - p += 16; - } - } - - /* The first entry in the .got section is the address of the - dynamic information, unless this is a shared library. */ - s = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (s != NULL); - if (info->shared) - PUT_WORD (dynobj, 0, s->contents); - else - PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset, - s->contents); - - for (o = dynobj->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) != 0 - && o->contents != NULL) - { - BFD_ASSERT (o->output_section != NULL - && o->output_section->owner == abfd); - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, o->output_offset, - o->_raw_size)) - return false; - } - } - - /* Finish up the dynamic link information. */ - PUT_WORD (dynobj, (bfd_vma) 3, esd.ld_version); - PUT_WORD (dynobj, - sdyn->output_section->vma + sdyn->output_offset + sizeof esd, - esd.ldd); - PUT_WORD (dynobj, - (sdyn->output_section->vma - + sdyn->output_offset - + sizeof esd - + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE), - esd.ld); - - if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd, - sdyn->output_offset, sizeof esd)) - return false; - - - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded); - - s = bfd_get_section_by_name (dynobj, ".need"); - if (s == NULL || s->_raw_size == 0) - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need); - else - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_need); - - s = bfd_get_section_by_name (dynobj, ".rules"); - if (s == NULL || s->_raw_size == 0) - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules); - else - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_rules); - - s = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->vma + s->output_offset, esdl.ld_got); - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->vma + s->output_offset, esdl.ld_plt); - PUT_WORD (dynobj, s->_raw_size, esdl.ld_plt_sz); - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) == s->_raw_size); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_rel); - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_hash); - - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_stab); - - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_stab_hash); - - PUT_WORD (dynobj, (bfd_vma) sunos_hash_table (info)->bucketcount, - esdl.ld_buckets); - - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_symbols); - PUT_WORD (dynobj, s->_raw_size, esdl.ld_symb_size); - - /* The size of the text area is the size of the .text section - rounded up to a page boundary. FIXME: Should the page size be - conditional on something? */ - PUT_WORD (dynobj, - BFD_ALIGN (obj_textsec (abfd)->_raw_size, 0x2000), - esdl.ld_text); - - if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl, - (sdyn->output_offset - + sizeof esd - + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE), - sizeof esdl)) - return false; - - abfd->flags |= DYNAMIC; - - return true; -} diff --git a/contrib/gdb/bfd/syms.c b/contrib/gdb/bfd/syms.c deleted file mode 100644 index e3007e4c5f0..00000000000 --- a/contrib/gdb/bfd/syms.c +++ /dev/null @@ -1,1084 +0,0 @@ -/* Generic symbol-table support for the BFD library. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SECTION - Symbols - - 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 <> 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 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 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 - made. Then the BFD back end fills in a table provided by the - application with pointers to the canonical information. To - output symbols, the application provides BFD with a table of - pointers to pointers to <>s. This allows applications - 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:: -@* Mini Symbols:: -@* typedef asymbol:: -@* symbol handling functions:: -@end menu - -INODE -Reading Symbols, Writing Symbols, Symbols, Symbols -SUBSECTION - Reading symbols - - There are two stages to reading a symbol table from a BFD: - allocating storage, and the actual reading process. This is an - excerpt from an application which reads the symbol table: - -| long storage_needed; -| asymbol **symbol_table; -| 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 **) xmalloc (storage_needed); -| ... -| 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; it is freed when the BFD is closed. - - -INODE -Writing Symbols, Mini Symbols, Reading Symbols, Symbols -SUBSECTION - Writing symbols - - Writing of a symbol table is automatic when a BFD open for - writing is closed. The application attaches a vector of - pointers to pointers to symbols to the BFD being written, and - fills in the symbol count. The close and cleanup code reads - through the table provided and performs all the necessary - operations. The 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 <>. Here is an - example showing the creation of a symbol table with only one element: - -| #include "bfd.h" -| main() -| { -| bfd *abfd; -| asymbol *ptrs[2]; -| asymbol *new; -| -| abfd = bfd_openw("foo","a.out-sunos-big"); -| bfd_set_format(abfd, bfd_object); -| new = bfd_make_empty_symbol(abfd); -| new->name = "dummy_symbol"; -| new->section = bfd_make_section_old_way(abfd, ".text"); -| new->flags = BSF_GLOBAL; -| new->value = 0x12345; -| -| ptrs[0] = new; -| ptrs[1] = (asymbol *)0; -| -| bfd_set_symtab(abfd, ptrs, 1); -| bfd_close(abfd); -| } -| -| ./makesym -| nm foo -| 00012345 A dummy_symbol - - Many formats cannot represent arbitary symbol information; for - instance, the <> 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. - -INODE -Mini Symbols, typedef asymbol, Writing Symbols, Symbols -SUBSECTION - Mini Symbols - - Mini symbols provide read-only access to the symbol table. - They use less memory space, but require more time to access. - They can be useful for tools like nm or objdump, which may - have to handle symbol tables of extremely large executables. - - The <> function will read the symbols - into memory in an internal form. It will return a <> - pointer to a block of memory, a symbol count, and the size of - each symbol. The pointer is allocated using <>, and - should be freed by the caller when it is no longer needed. - - The function <> will take a pointer - to a minisymbol, and a pointer to a structure returned by - <>, and return a <> structure. - The return value may or may not be the same as the value from - <> which was passed in. - -*/ - - - -/* -DOCDD -INODE -typedef asymbol, symbol handling functions, Mini Symbols, Symbols - -*/ -/* -SUBSECTION - typedef asymbol - - An <> has the form: - -*/ - -/* -CODE_FRAGMENT - -. -.typedef struct symbol_cache_entry -.{ -. {* A pointer to the BFD which owns the symbol. This information -. is necessary so that a back end can work out what additional -. information (invisible to the application writer) is carried -. with the symbol. -. -. This field is *almost* redundant, since you can use section->owner -. instead, except that some symbols point to the global sections -. bfd_{abs,com,und}_section. This could be fixed by making -. these globals be per-bfd (or per-target-flavor). FIXME. *} -. -. struct _bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *} -. -. {* The text of the symbol. The name is left alone, and not copied; the -. application may not alter it. *} -. CONST char *name; -. -. {* The value of the symbol. This really should be a union of a -. numeric value with a pointer, since some flags indicate that -. a pointer to another symbol is stored here. *} -. symvalue value; -. -. {* Attributes of a symbol: *} -. -.#define BSF_NO_FLAGS 0x00 -. -. {* The symbol has local scope; <> in <>. The value -. is the offset into the section of the data. *} -.#define BSF_LOCAL 0x01 -. -. {* The symbol has global scope; initialized data in <>. The -. value is the offset into the section of the data. *} -.#define BSF_GLOBAL 0x02 -. -. {* The symbol has global scope and is exported. The value is -. the offset into the section of the data. *} -.#define BSF_EXPORT BSF_GLOBAL {* no real difference *} -. -. {* A normal C symbol would be one of: -. <>, <>, <> or -. <> *} -. -. {* The symbol is a debugging record. The value has an arbitary -. meaning. *} -.#define BSF_DEBUGGING 0x08 -. -. {* The symbol denotes a function entry point. Used in ELF, -. perhaps others someday. *} -.#define BSF_FUNCTION 0x10 -. -. {* Used by the linker. *} -.#define BSF_KEEP 0x20 -.#define BSF_KEEP_G 0x40 -. -. {* A weak global symbol, overridable without warnings by -. a regular global symbol of the same name. *} -.#define BSF_WEAK 0x80 -. -. {* This symbol was created to point to a section, e.g. ELF's -. STT_SECTION symbols. *} -.#define BSF_SECTION_SYM 0x100 -. -. {* The symbol used to be a common symbol, but now it is -. allocated. *} -.#define BSF_OLD_COMMON 0x200 -. -. {* The default value for common data. *} -.#define BFD_FORT_COMM_DEFAULT_VALUE 0 -. -. {* In some files the type of a symbol sometimes alters its -. location in an output file - ie in coff a <> symbol -. which is also <> symbol appears where it was -. declared and not at the end of a section. This bit is set -. by the target BFD part to convey this information. *} -. -.#define BSF_NOT_AT_END 0x400 -. -. {* Signal that the symbol is the label of constructor section. *} -.#define BSF_CONSTRUCTOR 0x800 -. -. {* Signal that the symbol is a warning symbol. The name is a -. warning. The name of the next symbol is the one to warn about; -. if a reference is made to a symbol with the same name as the next -. symbol, a warning is issued by the linker. *} -.#define BSF_WARNING 0x1000 -. -. {* Signal that the symbol is indirect. This symbol is an indirect -. pointer to the symbol with the same name as the next symbol. *} -.#define BSF_INDIRECT 0x2000 -. -. {* BSF_FILE marks symbols that contain a file name. This is used -. for ELF STT_FILE symbols. *} -.#define BSF_FILE 0x4000 -. -. {* Symbol is from dynamic linking information. *} -.#define BSF_DYNAMIC 0x8000 -. -. {* The symbol denotes a data object. Used in ELF, and perhaps -. others someday. *} -.#define BSF_OBJECT 0x10000 -. -. flagword flags; -. -. {* A pointer to the section to which this symbol is -. relative. This will always be non NULL, there are special -. sections for undefined and absolute symbols. *} -. struct sec *section; -. -. {* Back end special data. *} -. union -. { -. PTR p; -. bfd_vma i; -. } udata; -. -.} asymbol; -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "aout/stab_gnu.h" - -/* -DOCDD -INODE -symbol handling functions, , typedef asymbol, Symbols -SUBSECTION - Symbol handling functions -*/ - -/* -FUNCTION - bfd_get_symtab_upper_bound - -DESCRIPTION - Return the number of bytes required to store a vector of pointers - to <> for all the symbols in the BFD @var{abfd}, - including a terminal NULL pointer. If there are no symbols in - the BFD, then return 0. If an error occurs, return -1. - -.#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 - 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. - - -.#define bfd_canonicalize_symtab(abfd, location) \ -. BFD_SEND (abfd, _bfd_canonicalize_symtab,\ -. (abfd, location)) - -*/ - - -/* -FUNCTION - bfd_set_symtab - -SYNOPSIS - 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 -bfd_set_symtab (abfd, location, symcount) - bfd *abfd; - asymbol **location; - unsigned int symcount; -{ - 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; - return true; -} - -/* -FUNCTION - bfd_print_symbol_vandf - -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 -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); - } - - /* This presumes that a symbol can not be both BSF_DEBUGGING and - BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and - BSF_OBJECT. */ - fprintf (file, " %c%c%c%c%c%c%c", - ((type & BSF_LOCAL) - ? (type & BSF_GLOBAL) ? '!' : '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' : ' ', - ((type & BSF_FUNCTION) - ? 'F' - : ((type & BSF_FILE) - ? 'f' - : ((type & BSF_OBJECT) ? 'O' : ' ')))); -} - - -/* -FUNCTION - bfd_make_empty_symbol - -DESCRIPTION - Create a new <> structure for the BFD @var{abfd} - and return a pointer to it. - - This routine is necessary because each back end has private - information surrounding the <>. Building your own - <> and pointing to it will not create the private - information, and will cause problems later on. - -.#define bfd_make_empty_symbol(abfd) \ -. BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) -*/ - -/* -FUNCTION - bfd_make_debug_symbol - -DESCRIPTION - Create a new <> structure for the BFD @var{abfd}, - to be used as a debugging symbol. Further details of its use have - yet to be worked out. - -.#define bfd_make_debug_symbol(abfd,ptr,size) \ -. BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) -*/ - -struct section_to_type -{ - CONST char *section; - char type; -}; - -/* Map section names to POSIX/BSD single-character symbol types. - This table is probably incomplete. It is sorted for convenience of - adding entries. Since it is so short, a linear search is used. */ -static CONST struct section_to_type stt[] = -{ - {"*DEBUG*", 'N'}, - {".bss", 'b'}, - {"zerovars", 'b'}, /* MRI .bss */ - {".data", 'd'}, - {"vars", 'd'}, /* MRI .data */ - {".rdata", 'r'}, /* Read only data. */ - {".rodata", 'r'}, /* Read only data. */ - {".sbss", 's'}, /* Small BSS (uninitialized data). */ - {".scommon", 'c'}, /* Small common. */ - {".sdata", 'g'}, /* Small initialized data. */ - {".text", 't'}, - {"code", 't'}, /* MRI .text */ - {0, 0} -}; - -/* Return the single-character symbol type corresponding to - section S, or '?' for an unknown COFF section. - - Check for any leading string which matches, so .text5 returns - 't' as well as .text */ - -static char -coff_section_type (s) - char *s; -{ - CONST struct section_to_type *t; - - for (t = &stt[0]; t->section; t++) - if (!strncmp (s, t->section, strlen (t->section))) - return t->type; - - return '?'; -} - -#ifndef islower -#define islower(c) ((c) >= 'a' && (c) <= 'z') -#endif -#ifndef toupper -#define toupper(c) (islower(c) ? ((c) & ~0x20) : (c)) -#endif - -/* -FUNCTION - bfd_decode_symclass - -DESCRIPTION - Return a character corresponding to the symbol - class of @var{symbol}, or '?' for an unknown class. - -SYNOPSIS - int bfd_decode_symclass(asymbol *symbol); -*/ -int -bfd_decode_symclass (symbol) - asymbol *symbol; -{ - char c; - - if (bfd_is_com_section (symbol->section)) - return 'C'; - if (bfd_is_und_section (symbol->section)) - return 'U'; - if (bfd_is_ind_section (symbol->section)) - return 'I'; - if (symbol->flags & BSF_WEAK) - return 'W'; - if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) - return '?'; - - if (bfd_is_abs_section (symbol->section)) - c = 'a'; - else if (symbol->section) - c = coff_section_type (symbol->section->name); - else - return '?'; - if (symbol->flags & BSF_GLOBAL) - c = toupper (c); - return c; - - /* We don't have to handle these cases just yet, but we will soon: - N_SETV: 'v'; - N_SETA: 'l'; - N_SETT: 'x'; - N_SETD: 'z'; - N_SETB: 's'; - N_INDR: 'i'; - */ -} - -/* -FUNCTION - bfd_symbol_info - -DESCRIPTION - Fill in the basic info about symbol that nm needs. - Additional info may be added by the back-ends after - calling this function. - -SYNOPSIS - void bfd_symbol_info(asymbol *symbol, symbol_info *ret); -*/ - -void -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; - else - ret->value = 0; - ret->name = symbol->name; -} - -void -bfd_symbol_is_absolute () -{ - abort (); -} - -/* -FUNCTION - bfd_copy_private_symbol_data - -SYNOPSIS - boolean bfd_copy_private_symbol_data(bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); - -DESCRIPTION - Copy private symbol information from @var{isym} in the BFD - @var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}. - Return <> on success, <> on error. Possible error - returns are: - - o <> - - Not enough memory exists to create private data for @var{osec}. - -.#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ -. BFD_SEND (ibfd, _bfd_copy_private_symbol_data, \ -. (ibfd, isymbol, obfd, osymbol)) - -*/ - -/* The generic version of the function which returns mini symbols. - This is used when the backend does not provide a more efficient - version. It just uses BFD asymbol structures as mini symbols. */ - -long -_bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep) - bfd *abfd; - boolean dynamic; - PTR *minisymsp; - unsigned int *sizep; -{ - long storage; - asymbol **syms = NULL; - long symcount; - - if (dynamic) - storage = bfd_get_dynamic_symtab_upper_bound (abfd); - else - storage = bfd_get_symtab_upper_bound (abfd); - if (storage < 0) - goto error_return; - - syms = (asymbol **) bfd_malloc ((size_t) storage); - if (syms == NULL) - goto error_return; - - if (dynamic) - symcount = bfd_canonicalize_dynamic_symtab (abfd, syms); - else - symcount = bfd_canonicalize_symtab (abfd, syms); - if (symcount < 0) - goto error_return; - - *minisymsp = (PTR) syms; - *sizep = sizeof (asymbol *); - return symcount; - - error_return: - if (syms != NULL) - free (syms); - return -1; -} - -/* The generic version of the function which converts a minisymbol to - an asymbol. We don't worry about the sym argument we are passed; - we just return the asymbol the minisymbol points to. */ - -/*ARGSUSED*/ -asymbol * -_bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym) - bfd *abfd; - boolean dynamic; - const PTR minisym; - asymbol *sym; -{ - return *(asymbol **) minisym; -} - -/* Look through stabs debugging information in .stab and .stabstr - sections to find the source file and line closest to a desired - location. This is used by COFF and ELF targets. It sets *pfound - to true if it finds some information. The *pinfo field is used to - pass cached information in and out of this routine; this first time - the routine is called for a BFD, *pinfo should be NULL. The value - placed in *pinfo should be saved with the BFD, and passed back each - time this function is called. */ - -/* A pointer to this structure is stored in *pinfo. */ - -struct stab_find_info -{ - /* The .stab section. */ - asection *stabsec; - /* The .stabstr section. */ - asection *strsec; - /* The contents of the .stab section. */ - bfd_byte *stabs; - /* The contents of the .stabstr section. */ - bfd_byte *strs; - /* An malloc buffer to hold the file name. */ - char *filename; - /* Cached values to restart quickly. */ - bfd_vma cached_offset; - bfd_byte *cached_stab; - bfd_byte *cached_str; - bfd_size_type cached_stroff; -}; - -boolean -_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound, - pfilename, pfnname, pline, pinfo) - bfd *abfd; - asymbol **symbols; - asection *section; - bfd_vma offset; - boolean *pfound; - const char **pfilename; - const char **pfnname; - unsigned int *pline; - PTR *pinfo; -{ - struct stab_find_info *info; - bfd_size_type stabsize, strsize; - bfd_byte *stab, *stabend, *str; - bfd_size_type stroff; - bfd_vma fnaddr; - char *directory_name, *main_file_name, *current_file_name, *line_file_name; - char *fnname; - bfd_vma low_func_vma, low_line_vma; - - *pfound = false; - *pfilename = bfd_get_filename (abfd); - *pfnname = NULL; - *pline = 0; - - info = (struct stab_find_info *) *pinfo; - if (info != NULL) - { - if (info->stabsec == NULL || info->strsec == NULL) - { - /* No stabs debugging information. */ - return true; - } - - stabsize = info->stabsec->_raw_size; - strsize = info->strsec->_raw_size; - } - else - { - long reloc_size, reloc_count; - arelent **reloc_vector; - - info = (struct stab_find_info *) bfd_zalloc (abfd, sizeof *info); - if (info == NULL) - return false; - - /* FIXME: When using the linker --split-by-file or - --split-by-reloc options, it is possible for the .stab and - .stabstr sections to be split. We should handle that. */ - - info->stabsec = bfd_get_section_by_name (abfd, ".stab"); - info->strsec = bfd_get_section_by_name (abfd, ".stabstr"); - - if (info->stabsec == NULL || info->strsec == NULL) - { - /* No stabs debugging information. Set *pinfo so that we - can return quickly in the info != NULL case above. */ - *pinfo = (PTR) info; - return true; - } - - stabsize = info->stabsec->_raw_size; - strsize = info->strsec->_raw_size; - - info->stabs = (bfd_byte *) bfd_alloc (abfd, stabsize); - info->strs = (bfd_byte *) bfd_alloc (abfd, strsize); - if (info->stabs == NULL || info->strs == NULL) - return false; - - if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs, 0, - stabsize) - || ! bfd_get_section_contents (abfd, info->strsec, info->strs, 0, - strsize)) - return false; - - /* If this is a relocateable object file, we have to relocate - the entries in .stab. This should always be simple 32 bit - relocations against symbols defined in this object file, so - this should be no big deal. */ - reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec); - if (reloc_size < 0) - return false; - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - return false; - reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector, - symbols); - if (reloc_count < 0) - { - if (reloc_vector != NULL) - free (reloc_vector); - return false; - } - if (reloc_count > 0) - { - arelent **pr; - - for (pr = reloc_vector; *pr != NULL; pr++) - { - arelent *r; - unsigned long val; - asymbol *sym; - - r = *pr; - if (r->howto->rightshift != 0 - || r->howto->size != 2 - || r->howto->bitsize != 32 - || r->howto->pc_relative - || r->howto->bitpos != 0 - || r->howto->dst_mask != 0xffffffff) - { - (*_bfd_error_handler) - ("Unsupported .stab relocation"); - bfd_set_error (bfd_error_invalid_operation); - if (reloc_vector != NULL) - free (reloc_vector); - return false; - } - - val = bfd_get_32 (abfd, info->stabs + r->address); - val &= r->howto->src_mask; - sym = *r->sym_ptr_ptr; - val += sym->value + sym->section->vma + r->addend; - bfd_put_32 (abfd, val, info->stabs + r->address); - } - } - - if (reloc_vector != NULL) - free (reloc_vector); - - *pinfo = (PTR) info; - } - - /* We are passed a section relative offset. The offsets in the - stabs information are absolute. */ - offset += bfd_get_section_vma (abfd, section); - - /* Stabs entries use a 12 byte format: - 4 byte string table index - 1 byte stab type - 1 byte stab other field - 2 byte stab desc field - 4 byte stab value - FIXME: This will have to change for a 64 bit object format. - - The stabs symbols are divided into compilation units. For the - first entry in each unit, the type of 0, the value is the length - of the string table for this unit, and the desc field is the - number of stabs symbols for this unit. */ - -#define STRDXOFF (0) -#define TYPEOFF (4) -#define OTHEROFF (5) -#define DESCOFF (6) -#define VALOFF (8) -#define STABSIZE (12) - - /* It would be nice if we could skip ahead to the stabs symbols for - the next compilation unit to quickly scan through the compilation - units. Unfortunately, since each line number gets a separate - stabs entry, it is entirely plausible that a large source file - will overflow the 16 bit count of stabs entries. */ - fnaddr = 0; - directory_name = NULL; - main_file_name = NULL; - current_file_name = NULL; - line_file_name = NULL; - fnname = NULL; - low_func_vma = 0; - low_line_vma = 0; - - stabend = info->stabs + stabsize; - - if (info->cached_stab == NULL || offset < info->cached_offset) - { - stab = info->stabs; - str = info->strs; - stroff = 0; - } - else - { - stab = info->cached_stab; - str = info->cached_str; - stroff = info->cached_stroff; - } - - info->cached_offset = offset; - - for (; stab < stabend; stab += STABSIZE) - { - boolean done; - bfd_vma val; - char *name; - - done = false; - - switch (stab[TYPEOFF]) - { - case 0: - /* This is the first entry in a compilation unit. */ - if ((bfd_size_type) ((info->strs + strsize) - str) < stroff) - { - done = true; - break; - } - str += stroff; - stroff = bfd_get_32 (abfd, stab + VALOFF); - break; - - case N_SO: - /* The main file name. */ - - val = bfd_get_32 (abfd, stab + VALOFF); - if (val > offset) - { - done = true; - break; - } - - name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); - - /* An empty string indicates the end of the compilation - unit. */ - if (*name == '\0') - { - /* If there are functions in different sections, they - may have addresses larger than val, but we don't want - to forget the file name. When there are functions in - different cases, there is supposed to be an N_FUN at - the end of the function indicating where it ends. */ - if (low_func_vma < val || fnname == NULL) - main_file_name = NULL; - break; - } - - /* We know that we have to get to at least this point in the - stabs entries for this offset. */ - info->cached_stab = stab; - info->cached_str = str; - info->cached_stroff = stroff; - - current_file_name = name; - - /* Look ahead to the next symbol. Two consecutive N_SO - symbols are a directory and a file name. */ - if (stab + STABSIZE >= stabend - || *(stab + STABSIZE + TYPEOFF) != N_SO) - directory_name = NULL; - else - { - stab += STABSIZE; - directory_name = current_file_name; - current_file_name = ((char *) str - + bfd_get_32 (abfd, stab + STRDXOFF)); - } - - main_file_name = current_file_name; - - break; - - case N_SOL: - /* The name of an include file. */ - current_file_name = ((char *) str - + bfd_get_32 (abfd, stab + STRDXOFF)); - break; - - case N_SLINE: - case N_DSLINE: - case N_BSLINE: - /* A line number. The value is relative to the start of the - current function. */ - val = fnaddr + bfd_get_32 (abfd, stab + VALOFF); - if (val >= low_line_vma && val <= offset) - { - *pline = bfd_get_16 (abfd, stab + DESCOFF); - low_line_vma = val; - line_file_name = current_file_name; - } - break; - - case N_FUN: - /* A function name. */ - val = bfd_get_32 (abfd, stab + VALOFF); - name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); - - /* An empty string here indicates the end of a function, and - the value is relative to fnaddr. */ - - if (*name == '\0') - { - val += fnaddr; - if (val >= low_func_vma && val < offset) - fnname = NULL; - } - else - { - if (val >= low_func_vma && val <= offset) - { - fnname = name; - low_func_vma = val; - } - - fnaddr = val; - } - - break; - } - - if (done) - break; - } - - if (main_file_name == NULL) - { - /* No information found. */ - return true; - } - - *pfound = true; - - if (*pline != 0) - main_file_name = line_file_name; - - if (main_file_name != NULL) - { - if (main_file_name[0] == '/' || directory_name == NULL) - *pfilename = main_file_name; - else - { - size_t dirlen; - - dirlen = strlen (directory_name); - if (info->filename == NULL - || strncmp (info->filename, directory_name, dirlen) != 0 - || strcmp (info->filename + dirlen, main_file_name) != 0) - { - if (info->filename != NULL) - free (info->filename); - info->filename = (char *) bfd_malloc (dirlen + - strlen (main_file_name) - + 1); - if (info->filename == NULL) - return false; - strcpy (info->filename, directory_name); - strcpy (info->filename + dirlen, main_file_name); - } - - *pfilename = info->filename; - } - } - - if (fnname != NULL) - { - char *s; - - /* This will typically be something like main:F(0,1), so we want - to clobber the colon. It's OK to change the name, since the - string is in our own local storage anyhow. */ - - s = strchr (fnname, ':'); - if (s != NULL) - *s = '\0'; - - *pfnname = fnname; - } - - return true; -} diff --git a/contrib/gdb/bfd/sysdep.h b/contrib/gdb/bfd/sysdep.h deleted file mode 100644 index dd8146a961a..00000000000 --- a/contrib/gdb/bfd/sysdep.h +++ /dev/null @@ -1,114 +0,0 @@ -/* sysdep.h -- handle host dependencies for the BFD library - Copyright 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef BFD_SYSDEP_H -#define BFD_SYSDEP_H - -#include "ansidecl.h" - -#include "config.h" - -#ifdef HAVE_STDDEF_H -#include -#endif - -#include -#include -#include - -#include -#ifndef errno -extern int errno; -#endif - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#else -extern char *strchr (); -extern char *strrchr (); -extern char *strstr (); -#endif -#endif - -#ifdef HAVE_STDLIB_H -#include -#endif - -#if TIME_WITH_SYS_TIME -#include -#include -#else -#if HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef USE_BINARY_FOPEN -#include "fopen-bin.h" -#else -#include "fopen-same.h" -#endif - -#ifdef HAVE_FCNTL_H -#include -#else -#ifdef HAVE_SYS_FILE_H -#include -#endif -#endif - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif -#ifndef O_WRONLY -#define O_WRONLY 1 -#endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifdef NEED_DECLARATION_MALLOC -extern PTR malloc (); -#endif - -#ifdef NEED_DECLARATION_FREE -extern void free (); -#endif - -#endif /* ! defined (BFD_SYSDEP_H) */ diff --git a/contrib/gdb/bfd/targets.c b/contrib/gdb/bfd/targets.c deleted file mode 100644 index e1e6468a18e..00000000000 --- a/contrib/gdb/bfd/targets.c +++ /dev/null @@ -1,886 +0,0 @@ -/* Generic target-file-type support for the BFD library. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* -SECTION - Targets - -DESCRIPTION - Each port of BFD to a different machine requries the creation - of a target back end. All the back end provides to the root - part of BFD is a structure containing pointers to functions - which perform certain low level operations on files. BFD - translates the applications's requests through a pointer into - calls to the back end routines. - - When a file is opened with <>, its format and - target are unknown. BFD uses various mechanisms to determine - how to interpret the file. The operations performed are: - - o Create a BFD by calling the internal routine - <<_bfd_new_bfd>>, then call <> with the - target string supplied to <> and the new BFD pointer. - - o If a null target string was provided to <>, - look up the environment variable <> and use - that as the target string. - - o If the target string is still <>, or the target string is - <>, then use the first item in the target vector - as the target type, and set <> in the BFD to - cause <> to loop through all the targets. - @xref{bfd_target}. @xref{Formats}. - - o Otherwise, inspect the elements in the target vector - one by one, until a match on target name is found. When found, - use it. - - o Otherwise return the error <> to - <>. - - o <> attempts to open the file using - <>, and returns the BFD. - - Once the BFD has been opened and the target selected, the file - format may be determined. This is done by calling - <> on the BFD with a suggested format. - If <> has been set, each possible target - type is tried to see if it recognizes the specified format. - <> returns <> when the caller guesses right. -@menu -@* bfd_target:: -@end menu -*/ - - -/* - -INODE - bfd_target, , Targets, Targets -DOCDD -SUBSECTION - bfd_target - -DESCRIPTION - This structure contains everything that BFD knows about a - target. It includes things like its byte order, name, and which - routines to call to do various operations. - - Every BFD points to a target structure with its <> - member. - - The macros below are used to dispatch to functions through the - <> 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 @var{arglist} - argument must be parenthesized; it contains all the arguments - to the called function. - - They make the documentation (more) unpleasant to read, so if - someone wants to fix this and not break the above, please do. - -.#define BFD_SEND(bfd, message, arglist) \ -. ((*((bfd)->xvec->message)) arglist) -. -.#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: - -.#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 structure which defines the type of BFD this is. The - <> member of the struct <> itself points here. Each - module that implements access to a different target under BFD, - defines one of these. - - - FIXME, these names should be rationalised with the names of - the entry points which call them. Too bad we can't have one - macro to define them both! - -.enum bfd_flavour { -. bfd_target_unknown_flavour, -. bfd_target_aout_flavour, -. bfd_target_coff_flavour, -. bfd_target_ecoff_flavour, -. bfd_target_elf_flavour, -. bfd_target_ieee_flavour, -. bfd_target_nlm_flavour, -. bfd_target_oasys_flavour, -. bfd_target_tekhex_flavour, -. bfd_target_srec_flavour, -. bfd_target_ihex_flavour, -. bfd_target_som_flavour, -. bfd_target_os9k_flavour, -. bfd_target_versados_flavour, -. bfd_target_msdos_flavour -.}; -. -.enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; -. -.{* Forward declaration. *} -.typedef struct bfd_link_info _bfd_link_info; -. -.typedef struct bfd_target -.{ - -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 bfd_flavour flavour; - -The order of bytes within the data area of a file. - -. enum bfd_endian byteorder; - -The order of bytes within the header parts of a file. - -. enum bfd_endian header_byteorder; - -A mask of all the flags which an executable may have set - -from the set <>, <>, ...<>. - -. flagword object_flags; - -A mask of all the flags which a section may have set - from -the set <>, <>, ...<>. - -. flagword section_flags; - -The character normally found at the front of a symbol -(if any), perhaps `_'. - -. char symbol_leading_char; - -The pad character for file names within an archive header. - -. char ar_pad_char; - -The maximum number of characters in an archive header. - -. unsigned short ar_max_namelen; - -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 ((const bfd_byte *)); -. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *)); -. void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_getx32) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *)); -. void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_getx16) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *)); -. void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *)); - -Byte swapping for the headers - -. bfd_vma (*bfd_h_getx64) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *)); -. void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_h_getx32) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *)); -. void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_h_getx16) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *)); -. void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *)); - -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 a <> or zero. - -. 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 <>. - -. boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *)); - -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),\ -.CAT(NAME,_get_section_contents_in_window) -. -. {* Called when the BFD is being closed to do any necessary cleanup. *} -. boolean (*_close_and_cleanup) PARAMS ((bfd *)); -. {* Ask the BFD to free all cached information. *} -. boolean (*_bfd_free_cached_info) PARAMS ((bfd *)); -. {* Called when a new section is created. *} -. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr)); -. {* Read the contents of a section. *} -. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, -. file_ptr, bfd_size_type)); -. boolean (*_bfd_get_section_contents_in_window) -. PARAMS ((bfd *, sec_ptr, bfd_window *, -. file_ptr, bfd_size_type)); -. -. {* Entry points to copy private data. *} -.#define BFD_JUMP_TABLE_COPY(NAME)\ -.CAT(NAME,_bfd_copy_private_bfd_data),\ -.CAT(NAME,_bfd_merge_private_bfd_data),\ -.CAT(NAME,_bfd_copy_private_section_data),\ -.CAT(NAME,_bfd_copy_private_symbol_data),\ -.CAT(NAME,_bfd_set_private_flags),\ -.CAT(NAME,_bfd_print_private_bfd_data)\ -. {* Called to copy BFD general private data from one object file -. to another. *} -. boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *)); -. {* Called to merge BFD general private data from one object file -. to a common output file when linking. *} -. boolean (*_bfd_merge_private_bfd_data) PARAMS ((bfd *, bfd *)); -. {* Called to copy BFD private section data from one object file -. to another. *} -. boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr, -. bfd *, sec_ptr)); -. {* Called to copy BFD private symbol data from one symbol -. to another. *} -. boolean (*_bfd_copy_private_symbol_data) PARAMS ((bfd *, asymbol *, -. bfd *, asymbol *)); -. {* Called to set private backend flags *} -. boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword)); -. -. {* Called to print private BFD data *} -. boolean (*_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR)); -. -. {* Core file entry points. *} -.#define BFD_JUMP_TABLE_CORE(NAME)\ -.CAT(NAME,_core_file_failing_command),\ -.CAT(NAME,_core_file_failing_signal),\ -.CAT(NAME,_core_file_matches_executable_p) -. char * (*_core_file_failing_command) PARAMS ((bfd *)); -. int (*_core_file_failing_signal) PARAMS ((bfd *)); -. boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *)); -. -. {* Archive entry points. *} -.#define BFD_JUMP_TABLE_ARCHIVE(NAME)\ -.CAT(NAME,_slurp_armap),\ -.CAT(NAME,_slurp_extended_name_table),\ -.CAT(NAME,_construct_extended_name_table),\ -.CAT(NAME,_truncate_arname),\ -.CAT(NAME,_write_armap),\ -.CAT(NAME,_read_ar_hdr),\ -.CAT(NAME,_openr_next_archived_file),\ -.CAT(NAME,_get_elt_at_index),\ -.CAT(NAME,_generic_stat_arch_elt),\ -.CAT(NAME,_update_armap_timestamp) -. boolean (*_bfd_slurp_armap) PARAMS ((bfd *)); -. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *)); -. boolean (*_bfd_construct_extended_name_table) -. PARAMS ((bfd *, char **, bfd_size_type *, const char **)); -. void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *)); -. boolean (*write_armap) PARAMS ((bfd *arch, -. unsigned int elength, -. struct orl *map, -. unsigned int orl_count, -. int stridx)); -. PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *)); -. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); -.#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i)) -. bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex)); -. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); -. boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *)); -. -. {* Entry points used for symbols. *} -.#define BFD_JUMP_TABLE_SYMBOLS(NAME)\ -.CAT(NAME,_get_symtab_upper_bound),\ -.CAT(NAME,_get_symtab),\ -.CAT(NAME,_make_empty_symbol),\ -.CAT(NAME,_print_symbol),\ -.CAT(NAME,_get_symbol_info),\ -.CAT(NAME,_bfd_is_local_label),\ -.CAT(NAME,_get_lineno),\ -.CAT(NAME,_find_nearest_line),\ -.CAT(NAME,_bfd_make_debug_symbol),\ -.CAT(NAME,_read_minisymbols),\ -.CAT(NAME,_minisymbol_to_symbol) -. long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *)); -. long (*_bfd_canonicalize_symtab) PARAMS ((bfd *, -. struct symbol_cache_entry **)); -. struct symbol_cache_entry * -. (*_bfd_make_empty_symbol) PARAMS ((bfd *)); -. void (*_bfd_print_symbol) PARAMS ((bfd *, PTR, -. struct symbol_cache_entry *, -. bfd_print_symbol_type)); -.#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e)) -. void (*_bfd_get_symbol_info) PARAMS ((bfd *, -. struct symbol_cache_entry *, -. symbol_info *)); -.#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e)) -. boolean (*_bfd_is_local_label) PARAMS ((bfd *, asymbol *)); -. -. alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *)); -. boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd, -. struct sec *section, struct symbol_cache_entry **symbols, -. bfd_vma offset, CONST char **file, CONST char **func, -. unsigned int *line)); -. {* Back-door to allow format-aware applications to create debug symbols -. while using BFD for everything else. Currently used by the assembler -. when creating COFF files. *} -. asymbol * (*_bfd_make_debug_symbol) PARAMS (( -. bfd *abfd, -. void *ptr, -. unsigned long size)); -.#define bfd_read_minisymbols(b, d, m, s) \ -. BFD_SEND (b, _read_minisymbols, (b, d, m, s)) -. long (*_read_minisymbols) PARAMS ((bfd *, boolean, PTR *, -. unsigned int *)); -.#define bfd_minisymbol_to_symbol(b, d, m, f) \ -. BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) -. asymbol *(*_minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR, -. asymbol *)); -. -. {* Routines for relocs. *} -.#define BFD_JUMP_TABLE_RELOCS(NAME)\ -.CAT(NAME,_get_reloc_upper_bound),\ -.CAT(NAME,_canonicalize_reloc),\ -.CAT(NAME,_bfd_reloc_type_lookup) -. long (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr)); -. long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, -. struct symbol_cache_entry **)); -. {* See documentation on reloc types. *} -. reloc_howto_type * -. (*reloc_type_lookup) PARAMS ((bfd *abfd, -. bfd_reloc_code_real_type code)); -. -. {* Routines used when writing an object file. *} -.#define BFD_JUMP_TABLE_WRITE(NAME)\ -.CAT(NAME,_set_arch_mach),\ -.CAT(NAME,_set_section_contents) -. boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture, -. unsigned long)); -. boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR, -. file_ptr, bfd_size_type)); -. -. {* Routines used by the linker. *} -.#define BFD_JUMP_TABLE_LINK(NAME)\ -.CAT(NAME,_sizeof_headers),\ -.CAT(NAME,_bfd_get_relocated_section_contents),\ -.CAT(NAME,_bfd_relax_section),\ -.CAT(NAME,_bfd_link_hash_table_create),\ -.CAT(NAME,_bfd_link_add_symbols),\ -.CAT(NAME,_bfd_final_link),\ -.CAT(NAME,_bfd_link_split_section) -. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean)); -. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *, -. struct bfd_link_info *, struct bfd_link_order *, -. bfd_byte *data, boolean relocateable, -. struct symbol_cache_entry **)); -. -. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *, -. struct bfd_link_info *, boolean *again)); -. -. {* Create a hash table for the linker. Different backends store -. different information in this table. *} -. struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *)); -. -. {* Add symbols from this object file into the hash table. *} -. boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *)); -. -. {* Do a link based on the link_order structures attached to each -. section of the BFD. *} -. boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *)); -. -. {* Should this section be split up into smaller pieces during linking. *} -. boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *)); -. -. {* Routines to handle dynamic symbols and relocs. *} -.#define BFD_JUMP_TABLE_DYNAMIC(NAME)\ -.CAT(NAME,_get_dynamic_symtab_upper_bound),\ -.CAT(NAME,_canonicalize_dynamic_symtab),\ -.CAT(NAME,_get_dynamic_reloc_upper_bound),\ -.CAT(NAME,_canonicalize_dynamic_reloc) -. {* Get the amount of memory required to hold the dynamic symbols. *} -. long (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *)); -. {* Read in the dynamic symbols. *} -. long (*_bfd_canonicalize_dynamic_symtab) -. PARAMS ((bfd *, struct symbol_cache_entry **)); -. {* Get the amount of memory required to hold the dynamic relocs. *} -. long (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *)); -. {* Read in the dynamic relocs. *} -. long (*_bfd_canonicalize_dynamic_reloc) -. PARAMS ((bfd *, arelent **, struct symbol_cache_entry **)); -. - -Data for use by back-end routines, which isn't generic enough to belong -in this structure. - -. PTR backend_data; -.} bfd_target; - -*/ - -/* All known xvecs (even those that don't compile on all systems). - Alphabetized for easy reference. - They are listed a second time below, since - we can't intermix extern's and initializers. */ -extern const bfd_target a29kcoff_big_vec; -extern const bfd_target a_out_adobe_vec; -extern const bfd_target aout_arm_big_vec; -extern const bfd_target aout_arm_little_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 armcoff_little_vec; -extern const bfd_target armcoff_big_vec; -extern const bfd_target armpe_little_vec; -extern const bfd_target armpe_big_vec; -extern const bfd_target armpei_little_vec; -extern const bfd_target armpei_big_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_powerpcle_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 i386freebsd_vec; -extern const bfd_target i386os9k_vec; -extern const bfd_target i386coff_vec; -extern const bfd_target bfd_powerpc_pe_vec; -extern const bfd_target bfd_powerpcle_pe_vec; -extern const bfd_target bfd_powerpc_pei_vec; -extern const bfd_target bfd_powerpcle_pei_vec; -extern const bfd_target i386pe_vec; -extern const bfd_target i386pei_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 i386msdos_vec; -extern const bfd_target i386netbsd_vec; -extern const bfd_target i860coff_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 m68kaux_coff_vec; -extern const bfd_target m68kcoff_vec; -extern const bfd_target m68kcoffun_vec; -extern const bfd_target m68klinux_vec; -extern const bfd_target m68klynx_aout_vec; -extern const bfd_target m68klynx_coff_vec; -extern const bfd_target m68knetbsd_vec; -extern const bfd_target m68k4knetbsd_vec; -extern const bfd_target m88kbcs_vec; -extern const bfd_target m88kmach3_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 pc532netbsd_vec; -extern const bfd_target oasys_vec; -extern const bfd_target pc532machaout_vec; -extern const bfd_target riscix_vec; -extern const bfd_target pmac_xcoff_vec; -extern const bfd_target rs6000coff_vec; -extern const bfd_target shcoff_vec; -extern const bfd_target shlcoff_vec; -extern const bfd_target sparclynx_aout_vec; -extern const bfd_target sparclynx_coff_vec; -extern const bfd_target sparcnetbsd_vec; -extern const bfd_target sparccoff_vec; -extern const bfd_target sunos_big_vec; -extern const bfd_target tekhex_vec; -extern const bfd_target versados_vec; -extern const bfd_target we32kcoff_vec; -extern const bfd_target w65_vec; -extern const bfd_target z8kcoff_vec; - -/* srec is always included. */ -extern const bfd_target srec_vec; -extern const bfd_target symbolsrec_vec; - -/* binary is always included. */ -extern const bfd_target binary_vec; - -/* ihex is always included. */ -extern const bfd_target ihex_vec; - -/* All of the xvecs for core files. */ -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; - -const bfd_target * const bfd_target_vector[] = { - -#ifdef SELECT_VECS - - SELECT_VECS, - -#else /* not SELECT_VECS */ - -#ifdef DEFAULT_VECTOR - &DEFAULT_VECTOR, -#endif - /* This list is alphabetized to make it easy to compare - with other vector lists -- the decls above and - the case statement in configure.in. - Vectors that don't compile on all systems, or aren't finished, - should have an entry here with #if 0 around it, to show that - it wasn't omitted by mistake. */ - &a29kcoff_big_vec, - &a_out_adobe_vec, -#if 0 /* No one seems to use this. */ - &aout_mips_big_vec, -#endif - &aout_mips_little_vec, - &b_out_vec_big_host, - &b_out_vec_little_host, - - /* 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, - &bfd_elf32_hppa_vec, - &bfd_elf32_i386_vec, - &bfd_elf32_i860_vec, - &bfd_elf32_little_generic_vec, - &bfd_elf32_littlemips_vec, - &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 - &ecoff_big_vec, - &ecoff_little_vec, -#if 0 - &ecoffalpha_little_vec, -#endif - &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) || defined (HOST_HPPAOSF) - &som_vec, -#endif - &i386aout_vec, - &i386bsd_vec, - &i386coff_vec, - &i386freebsd_vec, - &i860coff_vec, - &bfd_powerpc_pe_vec, - &bfd_powerpcle_pe_vec, - &bfd_powerpc_pei_vec, - &bfd_powerpcle_pei_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 - &i386msdos_vec, - &i386netbsd_vec, - &i386os9k_vec, - &i386pe_vec, - &i386pei_vec, - &armcoff_little_vec, - &armcoff_big_vec, - &armpe_little_vec, - &armpe_big_vec, - &armpei_little_vec, - &armpei_big_vec, - &icoff_big_vec, - &icoff_little_vec, - &ieee_vec, - &m68kcoff_vec, - &m68kcoffun_vec, -#if 0 - /* Since a.out files lack decent magic numbers, no way to recognize - which kind of a.out file it is. */ - &m68klinux_vec, -#endif - &m68klynx_aout_vec, - &m68klynx_coff_vec, - &m68knetbsd_vec, - &m88kbcs_vec, - &m88kmach3_vec, - &newsos3_vec, - &nlm32_i386_vec, - &nlm32_sparc_vec, -#ifdef BFD64 - &nlm32_alpha_vec, -#endif - &pc532netbsd_vec, -#if 0 - /* We have no oasys tools anymore, so we can't test any of this - anymore. If you want to test the stuff yourself, go ahead... - steve@cygnus.com - Worse, since there is no magic number for archives, there - can be annoying target mis-matches. */ - &oasys_vec, -#endif - &pc532machaout_vec, -#if 0 - /* We have no way of distinguishing these from other a.out variants */ - &aout_arm_big_vec, - &aout_arm_little_vec, - &riscix_vec, -#endif -#if 0 - /* This has the same magic number as RS/6000. */ - &pmac_xcoff_vec, -#endif - &rs6000coff_vec, - &shcoff_vec, - &shlcoff_vec, - &sparclynx_aout_vec, - &sparclynx_coff_vec, - &sparcnetbsd_vec, - &sunos_big_vec, - &aout0_big_vec, - &tekhex_vec, - &we32kcoff_vec, - &versados_vec, - &z8kcoff_vec, - -#endif /* not SELECT_VECS */ - -/* Always support S-records, for convenience. */ - &srec_vec, - &symbolsrec_vec, -/* And tekhex */ - &tekhex_vec, -/* Likewise for binary output. */ - &binary_vec, -/* Likewise for ihex. */ - &ihex_vec, - -/* Add any required traditional-core-file-handler. */ - -#ifdef AIX386_CORE - &aix386_core_vec, -#endif -#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 TRAD_CORE - &trad_core_vec, -#endif - -#ifdef PTRACE_CORE - &ptrace_core_vec, -#endif - - NULL /* end of list marker */ -}; - -/* bfd_default_vector[0] contains either the address of the default vector, - if there is one, or zero if there isn't. */ - -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 - Return a pointer to the transfer vector for the object target - named @var{target_name}. If @var{target_name} is <>, choose the - one in the environment variable <>; 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 <> to loop over all the - targets to find the one that matches the file being read. -*/ - -const bfd_target * -bfd_find_target (target_name, abfd) - CONST char *target_name; - bfd *abfd; -{ - const bfd_target * const *target; - extern char *getenv (); - CONST char *targname = (target_name ? target_name : - (CONST char *) getenv ("GNUTARGET")); - - /* This is safe; the vector cannot be null */ - if (targname == NULL || !strcmp (targname, "default")) { - abfd->target_defaulted = true; - return abfd->xvec = bfd_target_vector[0]; - } - - abfd->target_defaulted = false; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) { - if (!strcmp (targname, (*target)->name)) - return abfd->xvec = *target; - } - - bfd_set_error (bfd_error_invalid_target); - return NULL; -} - - -/* -FUNCTION - bfd_target_list - -SYNOPSIS - 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 ** -bfd_target_list () -{ - int vec_length= 0; -#if defined (HOST_HPPAHPUX) && ! defined (__STDC__) - /* The native compiler on the HP9000/700 has a bug which causes it - to loop endlessly when compiling this file. This avoids it. */ - volatile -#endif - const bfd_target * const *target; - CONST char **name_list, **name_ptr; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) - vec_length++; - - name_ptr = name_list = (CONST char **) - bfd_zmalloc ((vec_length + 1) * sizeof (char **)); - - if (name_list == NULL) - return NULL; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) - *(name_ptr++) = (*target)->name; - - return name_list; -} diff --git a/contrib/gdb/bfd/tekhex.c b/contrib/gdb/bfd/tekhex.c deleted file mode 100644 index bf7957e673a..00000000000 --- a/contrib/gdb/bfd/tekhex.c +++ /dev/null @@ -1,1031 +0,0 @@ -/* BFD backend for Extended Tektronix Hex Format objects. - Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - - Written by Steve Chamberlain of Cygnus Support . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -SUBSECTION - Tektronix Hex Format handling - -DESCRIPTION - - Tek Hex records can hold symbols and data, but not - relocations. Their main application is communication with - devices like PROM programmers and ICE equipment. - - It seems that the sections are descibed as being really big, - the example I have says that the text section is 0..ffffffff. - BFD would barf with this, many apps would try to alloc 4GB to - read in the file. - - Tex Hex may contain many sections, but the data which comes in - has no tag saying which section it belongs to, so we create - one section for each block of data, called "blknnnn" which we - stick all the data into. - - TekHex may come out of order and there is no header, so an - initial scan is required to discover the minimum and maximum - addresses used to create the vma and size of the sections we - create. - We read in the data into pages of CHUNK_MASK+1 size and read - them out from that whenever we need to. - - Any number of sections may be created for output, we save them - up and output them when it's time to close the bfd. - - - A TekHex record looks like: -EXAMPLE - % - -DESCRIPTION - Where - o length - is the number of bytes in the record not including the % sign. - o type - is one of: - 3) symbol record - 6) data record - 8) termination record - - -The data can come out of order, and may be discontigous. This is a -serial protocol, so big files are unlikely, so we keep a list of 8k chunks -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libiberty.h" - -typedef struct - { - bfd_vma low; - bfd_vma high; - } addr_range_type; - -typedef struct tekhex_symbol_struct - { - - asymbol symbol; - struct tekhex_symbol_struct *prev; - - } tekhex_symbol_type; - -static const char digs[] = "0123456789ABCDEF"; - -static char sum_block[256]; - -#define NOT_HEX 20 -#define NIBBLE(x) hex_value(x) -#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1])) -#define TOHEX(d,x) \ -(d)[1] = digs[(x) & 0xf]; \ -(d)[0] = digs[((x)>>4)&0xf]; -#define ISHEX(x) hex_p(x) - -/* -Here's an example -%3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75 -%1B3709T_SEGMENT1108FFFFFFFF -%2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10 -%373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710 -%373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10 -%373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10 -%373049T_SEGMENT80long$long$int$t71080short$unsigned$i10 -%373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10 -%373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010 -%373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10 -%2734D9T_SEGMENT8Bvoid$t15$151035_main10 -%2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110 -%2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214 -%07 8 10 10 - -explanation: -%3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75 - ^ ^^ ^ ^-data - | || +------ 4 char integer 0x8000 - | |+-------- checksum - | +--------- type 6 (data record) - +----------- length 3a chars - <---------------------- 3a (58 chars) -------------------> - -%1B3709T_SEGMENT1108FFFFFFFF - ^ ^^ ^- 8 character integer 0xffffffff - | |+- 1 character integer 0 - | +-- type 1 symbol (section definition) - +------------ 9 char symbol T_SEGMENT - -%2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10 -%373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710 -%373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10 -%373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10 -%373049T_SEGMENT80long$long$int$t71080short$unsigned$i10 -%373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10 -%373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010 -%373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10 -%2734D9T_SEGMENT8Bvoid$t15$151035_main10 -%2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110 -%2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214 -%0781010 - -Turns into -sac@thepub$ ./objdump -dx -m m68k f - -f: file format tekhex ------x--- 9/55728 -134219416 Sep 29 15:13 1995 f -architecture: UNKNOWN!, flags 0x00000010: -HAS_SYMS -start address 0x00000000 -SECTION 0 [D00000000] : size 00020000 vma 00000000 align 2**0 - ALLOC, LOAD -SECTION 1 [D00008000] : size 00002001 vma 00008000 align 2**0 - -SECTION 2 [T_SEGMENT] : size ffffffff vma 00000000 align 2**0 - -SYMBOL TABLE: -00000000 g T_SEGMENT gcc_compiled$ -00000000 g T_SEGMENT hello$c -00000000 g T_SEGMENT int$t1$r1$$21474 -00000000 g T_SEGMENT char$t2$r2$0$127 -00000000 g T_SEGMENT long$int$t3$r1$$ -00000000 g T_SEGMENT unsigned$int$t4$ -00000000 g T_SEGMENT long$unsigned$in -00000000 g T_SEGMENT short$int$t6$r1$ -00000000 g T_SEGMENT long$long$int$t7 -00000000 g T_SEGMENT short$unsigned$i -00000000 g T_SEGMENT long$long$unsign -00000000 g T_SEGMENT signed$char$t10$ -00000000 g T_SEGMENT unsigned$char$t1 -00000000 g T_SEGMENT float$t12$r1$4$0 -00000000 g T_SEGMENT double$t13$r1$8$ -00000000 g T_SEGMENT long$double$t14$ -00000000 g T_SEGMENT void$t15$15 -00000000 g T_SEGMENT _main -00000000 g T_SEGMENT $ -00000000 g T_SEGMENT $ -00000000 g T_SEGMENT $ -00000010 g T_SEGMENT $ -00000000 g T_SEGMENT main$F1 -fcffffff g T_SEGMENT i$1 -00000000 g T_SEGMENT $ -00000010 g T_SEGMENT $ - - -RELOCATION RECORDS FOR [D00000000]: (none) - -RELOCATION RECORDS FOR [D00008000]: (none) - -RELOCATION RECORDS FOR [T_SEGMENT]: (none) - -Disassembly of section D00000000: -... -00008000 ($+)7ff0 linkw fp,#-4 -00008004 ($+)7ff4 nop -00008006 ($+)7ff6 movel #99,d0 -00008008 ($+)7ff8 cmpl fp@(-4),d0 -0000800c ($+)7ffc blts 00008014 ($+)8004 -0000800e ($+)7ffe addql #1,fp@(-4) -00008012 ($+)8002 bras 00008006 ($+)7ff6 -00008014 ($+)8004 unlk fp -00008016 ($+)8006 rts -... - -*/ - -static void -tekhex_init () -{ - unsigned int i; - static boolean inited = false; - int val; - - if (inited == false) - { - inited = true; - hex_init (); - val = 0; - for (i = 0; i < 10; i++) - { - sum_block[i + '0'] = val++; - } - for (i = 'A'; i <= 'Z'; i++) - { - sum_block[i] = val++; - } - sum_block['$'] = val++; - sum_block['%'] = val++; - sum_block['.'] = val++; - sum_block['_'] = val++; - for (i = 'a'; i <= 'z'; i++) - { - sum_block[i] = val++; - } - } -} - -/* The maximum number of bytes on a line is FF */ -#define MAXCHUNK 0xff -/* The number of bytes we fit onto a line on output */ -#define CHUNK 21 - -/* We cannot output our tekhexords as we see them, we have to glue them - together, this is done in this structure : */ - -struct tekhex_data_list_struct -{ - unsigned char *data; - bfd_vma where; - bfd_size_type size; - struct tekhex_data_list_struct *next; - -}; -typedef struct tekhex_data_list_struct tekhex_data_list_type; - -#define CHUNK_MASK 0x1fff - -struct data_struct - { - char chunk_data[CHUNK_MASK + 1]; - char chunk_init[CHUNK_MASK + 1]; - bfd_vma vma; - struct data_struct *next; - }; - -typedef struct tekhex_data_struct -{ - tekhex_data_list_type *head; - unsigned int type; - struct tekhex_symbol_struct *symbols; - struct data_struct *data; -} tdata_type; - -#define enda(x) (x->vma + x->size) - -static bfd_vma -getvalue (srcp) - char **srcp; -{ - char *src = *srcp; - bfd_vma value = 0; - unsigned int len = hex_value(*src++); - - if (len == 0) - len = 16; - while (len--) - { - value = value << 4 | hex_value(*src++); - } - *srcp = src; - return value; -} - -static unsigned int -getsym (dstp, srcp) - char *dstp; - char **srcp; -{ - char *src = *srcp; - unsigned int i; - unsigned int len = hex_value(*src++); - - if (len == 0) - len = 16; - for (i = 0; i < len; i++) - dstp[i] = src[i]; - dstp[i] = 0; - *srcp = src + i; - return len; -} - -struct data_struct * -find_chunk (abfd, vma) - bfd *abfd; - bfd_vma vma; -{ - struct data_struct *d = abfd->tdata.tekhex_data->data; - - vma &= ~CHUNK_MASK; - while (d && (d->vma) != vma) - { - d = d->next; - } - if (!d) - { - char *sname = bfd_alloc (abfd, 12); - - /* No chunk for this address, so make one up */ - d = (struct data_struct *) - bfd_alloc (abfd, sizeof (struct data_struct)); - - if (!sname || !d) - return NULL; - - memset (d->chunk_init, 0, CHUNK_MASK + 1); - memset (d->chunk_data, 0, CHUNK_MASK + 1); - d->next = abfd->tdata.tekhex_data->data; - d->vma = vma; - abfd->tdata.tekhex_data->data = d; - } - return d; -} - -static void -insert_byte (abfd, value, addr) - bfd *abfd; - int value; - bfd_vma addr; -{ - /* Find the chunk that this byte needs and put it in */ - struct data_struct *d = find_chunk (abfd, addr); - - d->chunk_data[addr & CHUNK_MASK] = value; - d->chunk_init[addr & CHUNK_MASK] = 1; -} - -/* The first pass is to find the names of all the sections, and see - how big the data is */ -static void -first_phase (abfd, type, src) - bfd *abfd; - char type; - char *src; -{ - asection *section = bfd_abs_section_ptr; - int len; - char sym[17]; /* A symbol can only be 16chars long */ - - switch (type) - { - case '6': - /* Data record - read it and store it */ - { - bfd_vma addr = getvalue (&src); - - while (*src) - { - insert_byte (abfd, HEX (src), addr); - src += 2; - addr++; - } - } - - return; - case '3': - /* Symbol record, read the segment */ - len = getsym (sym, &src); - section = bfd_get_section_by_name (abfd, sym); - if (section == (asection *) NULL) - { - char *n = bfd_alloc (abfd, len + 1); - - if (!n) - abort(); /* FIXME */ - memcpy (n, sym, len + 1); - section = bfd_make_section (abfd, n); - } - while (*src) - { - switch (*src) - { - case '1': /* section range */ - src++; - section->vma = getvalue (&src); - section->_raw_size = getvalue (&src) - section->vma; - section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - break; - case '0': - case '2': - case '3': - case '4': - case '6': - case '7': - case '8': - /* Symbols, add to section */ - { - tekhex_symbol_type *new = - (tekhex_symbol_type *) bfd_alloc (abfd, - sizeof (tekhex_symbol_type)); - char type = (*src); - - if (!new) - abort(); /* FIXME */ - new->symbol.the_bfd = abfd; - src++; - abfd->symcount++; - abfd->flags |= HAS_SYMS; - new->prev = abfd->tdata.tekhex_data->symbols; - abfd->tdata.tekhex_data->symbols = new; - len = getsym (sym, &src); - new->symbol.name = bfd_alloc (abfd, len + 1); - if (!new->symbol.name) - abort(); /* FIXME */ - memcpy ((char *) (new->symbol.name), sym, len + 1); - new->symbol.section = section; - if (type <= '4') - new->symbol.flags = (BSF_GLOBAL | BSF_EXPORT); - else - new->symbol.flags = BSF_LOCAL; - new->symbol.value = getvalue (&src) - section->vma; - } - } - } - } -} - -/* Pass over an tekhex, calling one of the above functions on each - record. */ - -static void - pass_over (abfd, func) - bfd *abfd; - void (*func) (); -{ - unsigned int chars_on_line; - boolean eof = false; - - /* To the front of the file */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - abort (); - while (eof == false) - { - char buffer[MAXCHUNK]; - char *src = buffer; - char type; - - /* Find first '%' */ - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - while (*src != '%' && !eof) - { - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - } - if (eof) - break; - src++; - - /* Fetch the type and the length and the checksum */ - if (bfd_read (src, 1, 5, abfd) != 5) - abort (); /* FIXME */ - - type = src[2]; - - if (!ISHEX (src[0]) || !ISHEX (src[1])) - break; - - chars_on_line = HEX (src) - 5; /* Already read five char */ - - if (bfd_read (src, 1, chars_on_line, abfd) != chars_on_line) - abort (); /* FIXME */ - src[chars_on_line] = 0; /* put a null at the end */ - - func (abfd, type, src); - } - -} - -long -tekhex_get_symtab (abfd, table) - bfd *abfd; - asymbol **table; - -{ - tekhex_symbol_type *p = abfd->tdata.tekhex_data->symbols; - unsigned int c = bfd_get_symcount (abfd); - - table[c] = 0; - while (p) - { - table[--c] = &(p->symbol); - p = p->prev; - } - - return bfd_get_symcount (abfd); -} - -long -tekhex_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *)); - -} - -static boolean -tekhex_mkobject (abfd) - bfd *abfd; -{ - tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - - if (!tdata) - return false; - abfd->tdata.tekhex_data = tdata; - tdata->type = 1; - tdata->head = (tekhex_data_list_type *) NULL; - tdata->symbols = (struct tekhex_symbol_struct *) NULL; - tdata->data = (struct data_struct *) NULL; - return true; -} - -/* - Return true if the file looks like it's in TekHex format. Just look - for a percent sign and some hex digits */ - -static const bfd_target * -tekhex_object_p (abfd) - bfd *abfd; -{ - char b[4]; - - tekhex_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_read (b, 1, 4, abfd) != 4) - return NULL; - - if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3])) - return (const bfd_target *) NULL; - - tekhex_mkobject (abfd); - - pass_over (abfd, first_phase); - return abfd->xvec; -} - -static void -move_section_contents (abfd, section, locationp, offset, count, get) - bfd *abfd; - asection *section; - PTR locationp; - file_ptr offset; - bfd_size_type count; - boolean get; -{ - bfd_vma addr; - char *location = (char *) locationp; - bfd_vma prev_number = 1; /* Nothing can have this as a high bit*/ - struct data_struct *d = (struct data_struct *) NULL; - - for (addr = section->vma; count != 0; count--, addr++) - { - - bfd_vma chunk_number = addr & ~CHUNK_MASK; /* Get high bits of address */ - bfd_vma low_bits = addr & CHUNK_MASK; - - if (chunk_number != prev_number) - { - /* Different chunk, so move pointer */ - d = find_chunk (abfd, chunk_number); - } - - if (get) - { - if (d->chunk_init[low_bits]) - { - *location = d->chunk_data[low_bits]; - } - else - { - *location = 0; - } - } - else - { - d->chunk_data[low_bits] = *location; - d->chunk_init[low_bits] = (*location != 0); - } - - location++; - - } - -} -static boolean -tekhex_get_section_contents (abfd, section, locationp, offset, count) - bfd *abfd; - asection *section; - PTR locationp; - file_ptr offset; - bfd_size_type count; -{ - if (section->flags & (SEC_LOAD | SEC_ALLOC)) - { - move_section_contents (abfd, section, locationp, offset, count, true); - return true; - } - else - return false; -} - -boolean -tekhex_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - return bfd_default_set_arch_mach (abfd, arch, machine); -} - -/* we have to save up all the Tekhexords for a splurge before output, - */ - -static boolean -tekhex_set_section_contents (abfd, section, locationp, offset, bytes_to_do) - bfd *abfd; - sec_ptr section; - PTR locationp; - file_ptr offset; - bfd_size_type bytes_to_do; -{ - - if (abfd->output_has_begun == false) - { - /* The first time around, allocate enough sections to hold all the chunks */ - asection *s = abfd->sections; - bfd_vma vma; - - for (s = abfd->sections; s; s = s->next) - { - if (s->flags & SEC_LOAD) - { - for (vma = s->vma & ~CHUNK_MASK; - vma < s->vma + s->_raw_size; - vma += CHUNK_MASK) - find_chunk (abfd, vma); - } - } - - } - if (section->flags & (SEC_LOAD | SEC_ALLOC)) - { - move_section_contents (abfd, section, locationp, offset, bytes_to_do, false); - return true; - } - else - return false; - -} - -static void -writevalue (dst, value) - char **dst; - bfd_vma value; -{ - char *p = *dst; - int len; - int shift; - - for (len = 8, shift = 28; shift; shift -= 4, len--) - { - if ((value >> shift) & 0xf) - { - *p++ = len + '0'; - while (len) - { - *p++ = digs[(value >> shift) & 0xf]; - shift -= 4; - len--; - } - *dst = p; - return; - - } - } - *p++ = '1'; - *p++ = '0'; - *dst = p; -} - -static void -writesym (dst, sym) - char **dst; - CONST char *sym; -{ - char *p = *dst; - int len = (sym ? strlen (sym) : 0); - - if (len >= 16) - { - *p++ = '0'; - len = 16; - } - - else - { - if (len == 0) - { - *p++ = '1'; - sym = "$"; - len = 1; - } - else - { - *p++ = digs[len]; - } - } - - while (len--) - { - *p++ = *sym++; - } - *dst = p; -} - -static void -out (abfd, type, start, end) - bfd *abfd; - char type; - char *start; - char *end; -{ - int sum = 0; - char *s; - char front[6]; - bfd_size_type wrlen; - - front[0] = '%'; - TOHEX (front + 1, end - start + 5); - front[3] = type; - - for (s = start; s < end; s++) - { - sum += sum_block[(unsigned char) *s]; - } - - sum += sum_block[(unsigned char) front[1]]; /* length */ - sum += sum_block[(unsigned char) front[2]]; - sum += sum_block[(unsigned char) front[3]]; /* type */ - TOHEX (front + 4, sum); - if (bfd_write (front, 1, 6, abfd) != 6) - abort (); - end[0] = '\n'; - wrlen = end - start + 1; - if (bfd_write (start, 1, wrlen, abfd) != wrlen) - abort (); -} - -static boolean -tekhex_write_object_contents (abfd) - bfd *abfd; -{ - int bytes_written; - char buffer[100]; - asymbol **p; - asection *s; - struct data_struct *d; - - bytes_written = 0; - - /* And the raw data */ - for (d = abfd->tdata.tekhex_data->data; - d != (struct data_struct *) NULL; - d = d->next) - { - int low; - - CONST int span = 32; - int addr; - - /* Write it in blocks of 32 bytes */ - - for (addr = 0; addr < CHUNK_MASK + 1; addr += span) - { - int need = 0; - - /* Check to see if necessary */ - for (low = 0; !need && low < span; low++) - { - if (d->chunk_init[addr + low]) - need = 1; - } - if (need) - { - char *dst = buffer; - - writevalue (&dst, addr + d->vma); - for (low = 0; low < span; low++) - { - TOHEX (dst, d->chunk_data[addr + low]); - dst += 2; - } - out (abfd, '6', buffer, dst); - } - } - } - /* write all the section headers for the sections */ - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - char *dst = buffer; - - writesym (&dst, s->name); - *dst++ = '1'; - writevalue (&dst, s->vma); - writevalue (&dst, s->vma + s->_raw_size); - out (abfd, '3', buffer, dst); - } - - /* And the symbols */ - for (p = abfd->outsymbols; *p; p++) - { - int section_code = bfd_decode_symclass (*p); - - if (section_code != '?') - { /* do not include debug symbols */ - asymbol *s = *p; - char *dst = buffer; - - writesym (&dst, s->section->name); - - switch (section_code) - { - case 'A': - *dst++ = '2'; - break; - case 'a': - *dst++ = '6'; - break; - case 'D': - case 'B': - case 'O': - *dst++ = '4'; - break; - case 'd': - case 'b': - case 'o': - *dst++ = '8'; - break; - case 'T': - *dst++ = '3'; - break; - case 't': - *dst++ = '7'; - break; - case 'C': - case 'U': - bfd_set_error (bfd_error_wrong_format); - return false; - } - - writesym (&dst, s->name); - writevalue (&dst, s->value + s->section->vma); - out (abfd, '3', buffer, dst); - } - } - - /* And the terminator */ - if (bfd_write ("%0781010\n", 1, 9, abfd) != 9) - abort (); - return true; -} - -static int - tekhex_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; - -{ - return 0; -} - -static asymbol * -tekhex_make_empty_symbol (abfd) - bfd *abfd; -{ - tekhex_symbol_type *new = - (tekhex_symbol_type *) bfd_zalloc (abfd, sizeof (struct tekhex_symbol_struct)); - - if (!new) - return NULL; - new->symbol.the_bfd = abfd; - new->prev = (struct tekhex_symbol_struct *) NULL; - return &(new->symbol); -} - -static void -tekhex_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -static void -tekhex_print_symbol (ignore_abfd, filep, symbol, how) - bfd *ignore_abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) filep; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - break; - - case bfd_print_symbol_all: - { - CONST char *section_name = symbol->section->name; - - bfd_print_symbol_vandf ((PTR) file, symbol); - - fprintf (file, " %-5s %s", - section_name, - symbol->name); - } - } -} - -#define tekhex_close_and_cleanup _bfd_generic_close_and_cleanup -#define tekhex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define tekhex_new_section_hook _bfd_generic_new_section_hook - -#define tekhex_bfd_is_local_label bfd_generic_is_local_label -#define tekhex_get_lineno _bfd_nosymbols_get_lineno -#define tekhex_find_nearest_line _bfd_nosymbols_find_nearest_line -#define tekhex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define tekhex_read_minisymbols _bfd_generic_read_minisymbols -#define tekhex_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define tekhex_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define tekhex_bfd_relax_section bfd_generic_relax_section -#define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define tekhex_bfd_final_link _bfd_generic_final_link -#define tekhex_bfd_link_split_section _bfd_generic_link_split_section - -#define tekhex_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -const bfd_target tekhex_vec = -{ - "tekhex", /* name */ - bfd_target_tekhex_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (EXEC_P | /* object flags */ - HAS_SYMS | HAS_LINENO | HAS_DEBUG | HAS_RELOC | HAS_LOCALS | - WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - tekhex_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - tekhex_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - tekhex_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (tekhex), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (tekhex), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (tekhex), - BFD_JUMP_TABLE_LINK (tekhex), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/trad-core.c b/contrib/gdb/bfd/trad-core.c deleted file mode 100644 index 09c74ae481c..00000000000 --- a/contrib/gdb/bfd/trad-core.c +++ /dev/null @@ -1,316 +0,0 @@ -/* BFD back end for traditional Unix core files (U-area and raw sections) - 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. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include -#include -#include -#include -#include - -#include /* After a.out.h */ - -#ifdef TRAD_HEADER -#include TRAD_HEADER -#endif - - struct trad_core_struct - { - asection *data_section; - asection *stack_section; - asection *reg_section; - struct user u; - }; - -#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u)) -#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section) -#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section) -#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section) - -/* forward declarations */ - -const bfd_target *trad_unix_core_file_p PARAMS ((bfd *abfd)); -char * trad_unix_core_file_failing_command PARAMS ((bfd *abfd)); -int trad_unix_core_file_failing_signal PARAMS ((bfd *abfd)); -boolean trad_unix_core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */ - -/* ARGSUSED */ -const bfd_target * -trad_unix_core_file_p (abfd) - bfd *abfd; - -{ - int val; - struct user u; - struct trad_core_struct *rawptr; - -#ifdef TRAD_CORE_USER_OFFSET - /* If defined, this macro is the file position of the user struct. */ - if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) != 0) - return 0; -#endif - - val = bfd_read ((void *)&u, 1, sizeof u, abfd); - if (val != sizeof u) - { - /* Too small to be a core file */ - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* Sanity check perhaps??? */ - if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */ - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - if (u.u_ssize > 0x1000000) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* Check that the size claimed is no greater than the file size. */ - { - FILE *stream = bfd_cache_lookup (abfd); - struct stat statbuf; - if (stream == NULL) - return 0; - if (fstat (fileno (stream), &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return 0; - } - if (NBPG * (UPAGES + u.u_dsize -#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE - - u.u_tsize -#endif - + u.u_ssize) > statbuf.st_size) - { - 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. */ - + TRAD_CORE_EXTRA_SIZE_ALLOWED -#endif - < statbuf.st_size) - { - /* The file is too big. Maybe it's not a core file - or we otherwise have bad values for u_dsize and u_ssize). */ - bfd_set_error (bfd_error_wrong_format); - return 0; - } -#endif - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - /* Allocate both the upage and the struct core_data at once, so - a single free() will free them both. */ - rawptr = (struct trad_core_struct *) - bfd_zmalloc (sizeof (struct trad_core_struct)); - if (rawptr == NULL) - return 0; - - abfd->tdata.trad_core_data = rawptr; - - rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */ - - /* Create the sections. This is raunchy, but bfd_close wants to free - them separately. */ - - core_stacksec(abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_stacksec (abfd) == NULL) - return NULL; - core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_datasec (abfd) == NULL) - return NULL; - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) - return NULL; - - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - - core_datasec (abfd)->_raw_size = 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 */ - - /* What a hack... we'd like to steal it from the exec file, - since the upage does not seem to provide it. FIXME. */ -#ifdef HOST_DATA_START_ADDR - core_datasec (abfd)->vma = HOST_DATA_START_ADDR; -#else - core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize); -#endif - -#ifdef HOST_STACK_START_ADDR - core_stacksec (abfd)->vma = HOST_STACK_START_ADDR; -#else - core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize); -#endif - - /* This is tricky. As the "register section", we give them the entire - upage and stack. u.u_ar0 points to where "register 0" is stored. - There are two tricks with this, though. One is that the rest of the - registers might be at positive or negative (or both) displacements - from *u_ar0. The other is that u_ar0 is sometimes an absolute address - in kernel memory, and on other systems it is an offset from the beginning - of the `struct user'. - - As a practical matter, we don't know where the registers actually are, - so we have to pass the whole area to GDB. We encode the value of u_ar0 - by setting the .regs section up so that its virtual memory address - 0 is at the place pointed to by u_ar0 (by setting the vma of the start - of the section to -u_ar0). GDB uses this info to locate the regs, - using minor trickery to get around the offset-or-absolute-addr problem. */ - core_regsec (abfd)->vma = 0 - (bfd_vma) u.u_ar0; - - core_datasec (abfd)->filepos = NBPG * UPAGES; - 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 */ - core_stacksec (abfd)->alignment_power = 2; - core_datasec (abfd)->alignment_power = 2; - core_regsec (abfd)->alignment_power = 2; - - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_datasec (abfd); - core_datasec (abfd)->next = core_regsec (abfd); - abfd->section_count = 3; - - return abfd->xvec; -} - -char * -trad_unix_core_file_failing_command (abfd) - bfd *abfd; -{ -#ifndef NO_CORE_COMMAND - char *com = abfd->tdata.trad_core_data->u.u_comm; - if (*com) - return com; - else -#endif - return 0; -} - -/* ARGSUSED */ -int -trad_unix_core_file_failing_signal (ignore_abfd) - bfd *ignore_abfd; -{ -#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL - return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd); -#else - return -1; /* FIXME, where is it? */ -#endif -} - -/* ARGSUSED */ -boolean -trad_unix_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target trad_core_vec = - { - "trad-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - trad_unix_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - 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 */ -}; diff --git a/contrib/gdb/bfd/versados.c b/contrib/gdb/bfd/versados.c deleted file mode 100644 index 84ad114e90a..00000000000 --- a/contrib/gdb/bfd/versados.c +++ /dev/null @@ -1,906 +0,0 @@ -/* BFD back-end for VERSAdos-E objects. - - Versados is a Motorola trademark. - - Copyright 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support . - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - SUBSECTION - VERSAdos-E relocateable object file format - - DESCRIPTION - - This module supports reading of VERSAdos relocateable - object files. - - A VERSAdos file looks like contains - - o Indentification Record - o External Symbol Definition Record - o Object Text Recrod - o End Record - - - */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libiberty.h" - - -static boolean versados_mkobject PARAMS ((bfd *)); -static boolean versados_scan PARAMS ((bfd *)); -static const bfd_target *versados_object_p PARAMS ((bfd *)); - - -#define VHEADER '1' -#define VESTDEF '2' -#define VOTR '3' -#define VEND '4' - - -#define ES_BASE 17 /* first symbol has esdid 17 */ - -/* Per file target dependent information */ - -/* one for each section */ -struct esdid - { - asection *section; /* ptr to bfd version */ - unsigned char *contents; /* used to build image */ - int pc; - int relocs; /* reloc count, valid end of pass 1 */ - int donerel; /* have relocs been translated */ - }; - -typedef struct versados_data_struct - { - int es_done; /* count of symbol index, starts at ES_BASE */ - asymbol *symbols; /* pointer to local symbols */ - char *strings; /* strings of all the above */ - int stringlen; /* len of string table (valid end of pass1) */ - int nsecsyms; /* number of sections */ - - int ndefs; /* number of exported symbols (they dont get esdids) */ - int nrefs; /* number of imported symbols (valid end of pass1) */ - - int ref_idx; /* current processed value of the above */ - int def_idx; - - int pass_2_done; - - struct esdid e[16]; /* per section info */ - int alert; /* to see if we're trampling */ - asymbol *rest[256 - 16]; /* per symbol info */ - - } -tdata_type; - -#define VDATA(abfd) (abfd->tdata.versados_data) -#define EDATA(abfd, n) (abfd->tdata.versados_data->e[n]) -#define RDATA(abfd, n) (abfd->tdata.versados_data->rest[n]) - -struct ext_otr - { - unsigned char size; - char type; - unsigned char map[4]; - unsigned char esdid; - unsigned char data[200]; - }; - -struct ext_vheader - { - unsigned char size; - char type; /* record type */ - char name[10]; /* module name */ - char rev; /* module rev number */ - char lang; - char vol[4]; - char user[2]; - char cat[8]; - char fname[8]; - char ext[2]; - char time[3]; - char date[3]; - char rest[211]; - }; - -struct ext_esd - { - unsigned char size; - char type; - unsigned char esd_entries[1]; - }; -#define ESD_ABS 0 -#define ESD_COMMON 1 -#define ESD_STD_REL_SEC 2 -#define ESD_SHRT_REL_SEC 3 -#define ESD_XDEF_IN_SEC 4 -#define ESD_XREF_SYM 7 -#define ESD_XREF_SEC 6 -#define ESD_XDEF_IN_ABS 5 -union ext_any - { - unsigned char size; - struct ext_vheader header; - struct ext_esd esd; - struct ext_otr otr; - }; - -/* Initialize by filling in the hex conversion array. */ - - - - - -/* Set up the tdata information. */ - -static boolean -versados_mkobject (abfd) - bfd *abfd; -{ - if (abfd->tdata.versados_data == NULL) - { - tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - if (tdata == NULL) - return false; - abfd->tdata.versados_data = tdata; - tdata->symbols = NULL; - VDATA (abfd)->alert = 0x12345678; - } - - bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); - return true; -} - - -/* Report a problem in an S record file. FIXME: This probably should - not call fprintf, but we really do need some mechanism for printing - error messages. */ - - - -static asymbol * -versados_new_symbol (abfd, snum, name, val, sec) - bfd *abfd; - int snum; - const char *name; - bfd_vma val; - asection *sec; -{ - asymbol *n = VDATA (abfd)->symbols + snum; - n->name = name; - n->value = val; - n->section = sec; - n->the_bfd = abfd; - n->flags = 0; - return n; -} - - -static int -get_record (abfd, ptr) - bfd *abfd; - union ext_any *ptr; -{ - bfd_read (&ptr->size, 1, 1, abfd); - if (bfd_read ((char *) ptr + 1, 1, ptr->size, abfd) != ptr->size) - return 0; - return 1; -} - -int -get_4 (pp) - unsigned char **pp; -{ - unsigned char *p = *pp; - *pp += 4; - return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); -} - -void -get_10 (pp, name) - unsigned char **pp; - char *name; -{ - char *p = (char *) *pp; - int len = 10; - *pp += len; - while (*p != ' ' - && len) - { - *name++ = *p++; - len--; - } - *name = 0; -} - -static char * -new_symbol_string (abfd, name) - bfd *abfd; - char *name; -{ - char *n = VDATA (abfd)->strings; - strcpy (VDATA (abfd)->strings, name); - VDATA (abfd)->strings += strlen (VDATA (abfd)->strings) + 1; - return n; -} - - -static void -process_esd (abfd, esd, pass) - bfd *abfd; - struct ext_esd *esd; - int pass; -{ - /* Read through the ext def for the est entries */ - int togo = esd->size - 2; - bfd_vma size; - bfd_vma start; - asection *sec; - char name[11]; - unsigned char *ptr = esd->esd_entries; - unsigned char *end = ptr + togo; - while (ptr < end) - { - int scn = *ptr & 0xf; - int typ = (*ptr >> 4) & 0xf; - - /* Declare this section */ - sprintf (name, "%d", scn); - sec = bfd_make_section_old_way (abfd, strdup (name)); - sec->target_index = scn; - EDATA (abfd, scn).section = sec; - ptr++; - switch (typ) - { - default: - abort (); - case ESD_XREF_SEC: - case ESD_XREF_SYM: - { - int snum = VDATA (abfd)->ref_idx++; - get_10 (&ptr, name); - if (pass == 1) - { - VDATA (abfd)->stringlen += strlen (name) + 1; - } - else - { - int esidx; - asymbol *s; - char *n = new_symbol_string (abfd, name); - s = versados_new_symbol (abfd, snum, n, 0, - &bfd_und_section, scn); - esidx = VDATA (abfd)->es_done++; - RDATA (abfd, esidx - ES_BASE) = s; - } - } - break; - - - case ESD_ABS: - size = get_4 (&ptr); - start = get_4 (&ptr); - break; - case ESD_STD_REL_SEC: - case ESD_SHRT_REL_SEC: - { - sec->_raw_size = get_4 (&ptr); - sec->flags |= SEC_ALLOC; - } - break; - case ESD_XDEF_IN_ABS: - sec = (asection *) & bfd_abs_section; - case ESD_XDEF_IN_SEC: - { - int snum = VDATA (abfd)->def_idx++; - long val; - get_10 (&ptr, name); - val = get_4 (&ptr); - if (pass == 1) - { - /* Just remember the symbol */ - VDATA (abfd)->stringlen += strlen (name) + 1; - } - else - { - asymbol *s; - char *n = new_symbol_string (abfd, name); - s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n, val, sec, scn); - s->flags |= BSF_GLOBAL; - } - } - break; - } - } -} - -#define R_RELWORD 1 -#define R_RELLONG 2 -#define R_RELWORD_NEG 3 -#define R_RELLONG_NEG 4 - -reloc_howto_type versados_howto_table[] = -{ - HOWTO (R_RELWORD, 0, 1, 16, false, - 0, complain_overflow_dont, 0, - "+v16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_RELLONG, 0, 2, 32, false, - 0, complain_overflow_dont, 0, - "+v32", true, 0xffffffff, 0xffffffff, false), - - HOWTO (R_RELWORD_NEG, 0, -1, 16, false, - 0, complain_overflow_dont, 0, - "-v16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_RELLONG_NEG, 0, -2, 32, false, - 0, complain_overflow_dont, 0, - "-v32", true, 0xffffffff, 0xffffffff, false), -}; - - -static int -get_offset (len, ptr) - int len; - unsigned char *ptr; -{ - int val = 0; - if (len) - { - int i; - val = *ptr++; - if (val & 0x80) - val |= ~0xff; - for (i = 1; i < len; i++) - val = (val << 8) | *ptr++; - } - - return val; -} - -static void -process_otr (abfd, otr, pass) - bfd *abfd; - struct ext_otr *otr; - int pass; -{ - unsigned long shift; - unsigned char *srcp = otr->data; - unsigned char *endp = (unsigned char *) otr + otr->size; - unsigned int bits = (otr->map[0] << 24) - | (otr->map[1] << 16) - | (otr->map[2] << 8) - | (otr->map[3] << 0); - - struct esdid *esdid = &EDATA (abfd, otr->esdid - 1); - unsigned char *contents = esdid->contents; - int need_contents = 0; - unsigned int dst_idx = esdid->pc; - - for (shift = (1 << 31); shift && srcp < endp; shift >>= 1) - { - if (bits & shift) - { - int flag = *srcp++; - int esdids = (flag >> 5) & 0x7; - int sizeinwords = ((flag >> 3) & 1) ? 2 : 1; - int offsetlen = flag & 0x7; - int j; - - - if (esdids == 0) - { - /* A zero esdid means the new pc is the offset given */ - dst_idx += get_offset (offsetlen, srcp); - srcp += offsetlen; - } - else - { - int val = get_offset (offsetlen, srcp + esdids); - if (pass == 1) - need_contents = 1; - else - for (j = 0; j < sizeinwords * 2; j++) - { - contents[dst_idx + (sizeinwords * 2) - j - 1] = val; - val >>= 8; - } - - for (j = 0; j < esdids; j++) - { - int esdid = *srcp++; - - if (esdid) - { - int rn = EDATA (abfd, otr->esdid - 1).relocs++; - if (pass == 1) - { - /* this is the first pass over the data, - just remember that we need a reloc */ - } - else - { - arelent *n = - EDATA (abfd, otr->esdid - 1).section->relocation + rn; - n->address = dst_idx; - - n->sym_ptr_ptr = (asymbol **) esdid; - n->addend = 0; - n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); - } - } - } - srcp += offsetlen; - dst_idx += sizeinwords * 2; - } - } - else - { - need_contents = 1; - if (dst_idx < esdid->section->_raw_size) - if (pass == 2) - { - /* absolute code, comes in 16 bit lumps */ - contents[dst_idx] = srcp[0]; - contents[dst_idx + 1] = srcp[1]; - } - dst_idx += 2; - srcp += 2; - } - } - EDATA (abfd, otr->esdid - 1).pc = dst_idx; - - if (!contents && need_contents) - esdid->contents = (unsigned char *) bfd_alloc (abfd, esdid->section->_raw_size); - - -} - -static boolean -versados_scan (abfd) - bfd *abfd; -{ - int loop = 1; - int i; - int j; - int nsecs = 0; - - VDATA (abfd)->nrefs = 0; - VDATA (abfd)->ndefs = 0; - VDATA (abfd)->ref_idx = 0; - VDATA (abfd)->def_idx = 0; - - while (loop) - { - union ext_any any; - if (!get_record (abfd, &any)) - return true; - switch (any.header.type) - { - case VHEADER: - break; - case VEND: - loop = 0; - break; - case VESTDEF: - process_esd (abfd, &any.esd, 1); - break; - case VOTR: - process_otr (abfd, &any.otr, 1); - break; - } - } - - /* Now allocate space for the relocs and sections */ - - VDATA (abfd)->nrefs = VDATA (abfd)->ref_idx; - VDATA (abfd)->ndefs = VDATA (abfd)->def_idx; - VDATA (abfd)->ref_idx = 0; - VDATA (abfd)->def_idx = 0; - - abfd->symcount = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs; - - for (i = 0; i < 16; i++) - { - struct esdid *esdid = &EDATA (abfd, i); - if (esdid->section) - { - esdid->section->relocation - = (arelent *) bfd_alloc (abfd, sizeof (arelent) * esdid->relocs); - - esdid->pc = 0; - - if (esdid->contents) - esdid->section->flags |= SEC_HAS_CONTENTS | SEC_LOAD; - - esdid->section->reloc_count = esdid->relocs; - if (esdid->relocs) - esdid->section->flags |= SEC_RELOC; - - esdid->relocs = 0; - - /* Add an entry into the symbol table for it */ - nsecs++; - VDATA (abfd)->stringlen += strlen (esdid->section->name) + 1; - } - } - - abfd->symcount += nsecs; - - VDATA (abfd)->symbols = (asymbol *) bfd_alloc (abfd, - sizeof (asymbol) * (abfd->symcount)); - - VDATA (abfd)->strings = bfd_alloc (abfd, VDATA (abfd)->stringlen); - - - /* Actually fill in the section symbols, - we stick them at the end of the table */ - - for (j = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs, i = 0; i < 16; i++) - { - struct esdid *esdid = &EDATA (abfd, i); - asection *sec = esdid->section; - if (sec) - { - asymbol *s = VDATA (abfd)->symbols + j; - s->name = new_symbol_string (abfd, sec->name); - s->section = sec; - s->flags = BSF_LOCAL; - s->value = 0; - s->the_bfd = abfd; - j++; - } - } - if (abfd->symcount) - abfd->flags |= HAS_SYMS; - - /* Set this to nsecs - since we've already planted the section - symbols */ - VDATA (abfd)->nsecsyms = nsecs; - - VDATA (abfd)->ref_idx = 0; - - return 1; -} - - - -/* Check whether an existing file is a versados file. */ - -static const bfd_target * -versados_object_p (abfd) - bfd *abfd; -{ - struct ext_vheader ext; - unsigned char len; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)) - return NULL; - - - bfd_read (&len, 1, 1, abfd); - if (bfd_read (&ext.type, 1, len, abfd) != len - || ext.type != '1') - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* ok, looks like a record, build the tdata and read - in.. */ - - if (!versados_mkobject (abfd) - || !versados_scan (abfd)) - return NULL; - - return abfd->xvec; -} - - -static boolean -versados_pass_2 (abfd) - bfd *abfd; -{ - union ext_any any; - - if (VDATA (abfd)->pass_2_done) - return 1; - - if (bfd_seek (abfd, 0, SEEK_SET) != 0) - return 0; - - VDATA (abfd)->es_done = ES_BASE; - - - /* read records till we get to where we want to be */ - - while (1) - { - get_record (abfd, &any); - switch (any.header.type) - { - case VEND: - VDATA (abfd)->pass_2_done = 1; - return 1; - case VESTDEF: - process_esd (abfd, &any.esd, 2); - break; - case VOTR: - process_otr (abfd, &any.otr, 2); - break; - } - } -} - -static boolean -versados_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (!versados_pass_2 (abfd)) - return false; - - memcpy (location, - EDATA (abfd, section->target_index).contents + offset, - (size_t) count); - - return true; -} - -#define versados_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -static boolean -versados_set_section_contents (abfd, section, location, offset, bytes_to_do) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type bytes_to_do; -{ - return false; -} - - -/*ARGSUSED */ -static int -versados_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -static asymbol * -versados_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -/* Return the amount of memory needed to read the symbol table. */ - -static long -versados_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *); -} - -/* Return the symbol table. */ - -static long -versados_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - unsigned int symcount = bfd_get_symcount (abfd); - unsigned int i; - asymbol *s; - - versados_pass_2 (abfd); - - for (i = 0, s = VDATA (abfd)->symbols; - i < symcount; - s++, i++) - { - *alocation++ = s; - } - - *alocation = NULL; - - return symcount; -} - -/*ARGSUSED */ -void -versados_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/*ARGSUSED */ -void -versados_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - default: - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s %s", - symbol->section->name, - symbol->name); - - } -} - -long -versados_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - return (asect->reloc_count + 1) * sizeof (arelent *); -} - - -long -versados_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - unsigned int count; - arelent *src; - - versados_pass_2 (abfd); - src = section->relocation; - if (!EDATA (abfd, section->target_index).donerel) - { - EDATA (abfd, section->target_index).donerel = 1; - /* translate from indexes to symptr ptrs */ - for (count = 0; count < section->reloc_count; count++) - { - int esdid = (int) src[count].sym_ptr_ptr; - - if (esdid == 0) - { - src[count].sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; - } - else if (esdid < ES_BASE) /* Section relative thing */ - { - struct esdid *e = &EDATA (abfd, esdid - 1); - if (!section) - { - /** relocation relative to section which was - never declared ! */ - } - src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr; - } - else - { - src[count].sym_ptr_ptr = symbols + esdid - ES_BASE; - } - - } - } - - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = src++; - } - *relptr = 0; - return section->reloc_count; -} - -#define versados_close_and_cleanup _bfd_generic_close_and_cleanup -#define versados_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define versados_new_section_hook _bfd_generic_new_section_hook - -#define versados_bfd_is_local_label bfd_generic_is_local_label -#define versados_get_lineno _bfd_nosymbols_get_lineno -#define versados_find_nearest_line _bfd_nosymbols_find_nearest_line -#define versados_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define versados_read_minisymbols _bfd_generic_read_minisymbols -#define versados_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define versados_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define versados_set_arch_mach bfd_default_set_arch_mach - -#define versados_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define versados_bfd_relax_section bfd_generic_relax_section -#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define versados_bfd_final_link _bfd_generic_final_link -#define versados_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target versados_vec = -{ - "versados", /* name */ - bfd_target_versados_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - versados_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - versados_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - bfd_false, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (versados), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (versados), - BFD_JUMP_TABLE_RELOCS (versados), - BFD_JUMP_TABLE_WRITE (versados), - BFD_JUMP_TABLE_LINK (versados), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/xcofflink.c b/contrib/gdb/bfd/xcofflink.c deleted file mode 100644 index 16a76cc7ca5..00000000000 --- a/contrib/gdb/bfd/xcofflink.c +++ /dev/null @@ -1,5798 +0,0 @@ -/* POWER/PowerPC XCOFF linker support. - Copyright 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor , Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -/* This file holds the XCOFF linker code. */ - -#define STRING_SIZE_SIZE (4) - -/* In order to support linking different object file formats into an - XCOFF format, we need to be able to determine whether a particular - bfd_target is an XCOFF vector. FIXME: We need to rethink this - whole approach. */ -#define XCOFF_XVECP(xv) \ - (strcmp ((xv)->name, "aixcoff-rs6000") == 0 \ - || strcmp ((xv)->name, "xcoff-powermac") == 0) - -/* Get the XCOFF hash table entries for a BFD. */ -#define obj_xcoff_sym_hashes(bfd) \ - ((struct xcoff_link_hash_entry **) obj_coff_sym_hashes (bfd)) - -/* XCOFF relocation types. These probably belong in a header file - somewhere. The relocations are described in the function - _bfd_ppc_xcoff_relocate_section in this file. */ - -#define R_POS (0x00) -#define R_NEG (0x01) -#define R_REL (0x02) -#define R_TOC (0x03) -#define R_RTB (0x04) -#define R_GL (0x05) -#define R_TCL (0x06) -#define R_BA (0x08) -#define R_BR (0x0a) -#define R_RL (0x0c) -#define R_RLA (0x0d) -#define R_REF (0x0f) -#define R_TRL (0x12) -#define R_TRLA (0x13) -#define R_RRTBI (0x14) -#define R_RRTBA (0x15) -#define R_CAI (0x16) -#define R_CREL (0x17) -#define R_RBA (0x18) -#define R_RBAC (0x19) -#define R_RBR (0x1a) -#define R_RBRC (0x1b) - -/* The first word of global linkage code. This must be modified by - filling in the correct TOC offset. */ - -#define XCOFF_GLINK_FIRST (0x81820000) /* lwz r12,0(r2) */ - -/* The remaining words of global linkage code. */ - -static unsigned long xcoff_glink_code[] = -{ - 0x90410014, /* stw r2,20(r1) */ - 0x800c0000, /* lwz r0,0(r12) */ - 0x804c0004, /* lwz r2,4(r12) */ - 0x7c0903a6, /* mtctr r0 */ - 0x4e800420, /* bctr */ - 0x0, /* start of traceback table */ - 0x000c8000, /* traceback table */ - 0x0 /* traceback table */ -}; - -#define XCOFF_GLINK_SIZE \ - (((sizeof xcoff_glink_code / sizeof xcoff_glink_code[0]) * 4) + 4) - -/* We reuse the SEC_ROM flag as a mark flag for garbage collection. - This flag will only be used on input sections. */ - -#define SEC_MARK (SEC_ROM) - -/* The ldhdr structure. This appears at the start of the .loader - section. */ - -struct internal_ldhdr -{ - /* The version number: currently always 1. */ - unsigned long l_version; - /* The number of symbol table entries. */ - bfd_size_type l_nsyms; - /* The number of relocation table entries. */ - bfd_size_type l_nreloc; - /* The length of the import file string table. */ - bfd_size_type l_istlen; - /* The number of import files. */ - bfd_size_type l_nimpid; - /* The offset from the start of the .loader section to the first - entry in the import file table. */ - bfd_size_type l_impoff; - /* The length of the string table. */ - bfd_size_type l_stlen; - /* The offset from the start of the .loader section to the first - entry in the string table. */ - bfd_size_type l_stoff; -}; - -struct external_ldhdr -{ - bfd_byte l_version[4]; - bfd_byte l_nsyms[4]; - bfd_byte l_nreloc[4]; - bfd_byte l_istlen[4]; - bfd_byte l_nimpid[4]; - bfd_byte l_impoff[4]; - bfd_byte l_stlen[4]; - bfd_byte l_stoff[4]; -}; - -#define LDHDRSZ (8 * 4) - -/* The ldsym structure. This is used to represent a symbol in the - .loader section. */ - -struct internal_ldsym -{ - union - { - /* The symbol name if <= SYMNMLEN characters. */ - char _l_name[SYMNMLEN]; - struct - { - /* Zero if the symbol name is more than SYMNMLEN characters. */ - long _l_zeroes; - /* The offset in the string table if the symbol name is more - than SYMNMLEN characters. */ - long _l_offset; - } _l_l; - } _l; - /* The symbol value. */ - bfd_vma l_value; - /* The symbol section number. */ - short l_scnum; - /* The symbol type and flags. */ - char l_smtype; - /* The symbol storage class. */ - char l_smclas; - /* The import file ID. */ - bfd_size_type l_ifile; - /* Offset to the parameter type check string. */ - bfd_size_type l_parm; -}; - -struct external_ldsym -{ - union - { - bfd_byte _l_name[SYMNMLEN]; - struct - { - bfd_byte _l_zeroes[4]; - bfd_byte _l_offset[4]; - } _l_l; - } _l; - bfd_byte l_value[4]; - bfd_byte l_scnum[2]; - bfd_byte l_smtype[1]; - bfd_byte l_smclas[1]; - bfd_byte l_ifile[4]; - bfd_byte l_parm[4]; -}; - -#define LDSYMSZ (8 + 3 * 4 + 2 + 2) - -/* These flags are for the l_smtype field (the lower three bits are an - XTY_* value). */ - -/* Imported symbol. */ -#define L_IMPORT (0x40) -/* Entry point. */ -#define L_ENTRY (0x20) -/* Exported symbol. */ -#define L_EXPORT (0x10) - -/* The ldrel structure. This is used to represent a reloc in the - .loader section. */ - -struct internal_ldrel -{ - /* The reloc address. */ - bfd_vma l_vaddr; - /* The symbol table index in the .loader section symbol table. */ - bfd_size_type l_symndx; - /* The relocation type and size. */ - short l_rtype; - /* The section number this relocation applies to. */ - short l_rsecnm; -}; - -struct external_ldrel -{ - bfd_byte l_vaddr[4]; - bfd_byte l_symndx[4]; - bfd_byte l_rtype[2]; - bfd_byte l_rsecnm[2]; -}; - -#define LDRELSZ (2 * 4 + 2 * 2) - -/* The list of import files. */ - -struct xcoff_import_file -{ - /* The next entry in the list. */ - struct xcoff_import_file *next; - /* The path. */ - const char *path; - /* The file name. */ - const char *file; - /* The member name. */ - const char *member; -}; - -/* An entry in the XCOFF linker hash table. */ - -struct xcoff_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ - long indx; - - /* If we have created a TOC entry for this symbol, this is the .tc - section which holds it. */ - asection *toc_section; - - union - { - /* If we have created a TOC entry (the XCOFF_SET_TOC flag is - set), this is the offset in toc_section. */ - bfd_vma toc_offset; - /* If the TOC entry comes from an input file, this is set to the - symbo lindex of the C_HIDEXT XMC_TC symbol. */ - long toc_indx; - } u; - - /* If this symbol is a function entry point which is called, this - field holds a pointer to the function descriptor. If this symbol - is a function descriptor, this field holds a pointer to the - function entry point. */ - struct xcoff_link_hash_entry *descriptor; - - /* The .loader symbol table entry, if there is one. */ - struct internal_ldsym *ldsym; - - /* The .loader symbol table index. */ - long ldindx; - - /* Some linker flags. */ - unsigned short flags; - /* Symbol is referenced by a regular object. */ -#define XCOFF_REF_REGULAR (01) - /* Symbol is defined by a regular object. */ -#define XCOFF_DEF_REGULAR (02) - /* Symbol is defined by a dynamic object. */ -#define XCOFF_DEF_DYNAMIC (04) - /* Symbol is used in a reloc being copied into the .loader section. */ -#define XCOFF_LDREL (010) - /* Symbol is the entry point. */ -#define XCOFF_ENTRY (020) - /* Symbol is called; this is, it appears in a R_BR reloc. */ -#define XCOFF_CALLED (040) - /* Symbol needs the TOC entry filled in. */ -#define XCOFF_SET_TOC (0100) - /* Symbol is explicitly imported. */ -#define XCOFF_IMPORT (0200) - /* Symbol is explicitly exported. */ -#define XCOFF_EXPORT (0400) - /* Symbol has been processed by xcoff_build_ldsyms. */ -#define XCOFF_BUILT_LDSYM (01000) - /* Symbol is mentioned by a section which was not garbage collected. */ -#define XCOFF_MARK (02000) - /* Symbol size is recorded in size_list list from hash table. */ -#define XCOFF_HAS_SIZE (04000) - /* Symbol is a function descriptor. */ -#define XCOFF_DESCRIPTOR (010000) - - /* The storage mapping class. */ - unsigned char smclas; -}; - -/* The XCOFF linker hash table. */ - -struct xcoff_link_hash_table -{ - struct bfd_link_hash_table root; - - /* The .debug string hash table. We need to compute this while - reading the input files, so that we know how large the .debug - section will be before we assign section positions. */ - struct bfd_strtab_hash *debug_strtab; - - /* The .debug section we will use for the final output. */ - asection *debug_section; - - /* The .loader section we will use for the final output. */ - asection *loader_section; - - /* A count of non TOC relative relocs which will need to be - allocated in the .loader section. */ - size_t ldrel_count; - - /* The .loader section header. */ - struct internal_ldhdr ldhdr; - - /* The .gl section we use to hold global linkage code. */ - asection *linkage_section; - - /* The .tc section we use to hold toc entries we build for global - linkage code. */ - asection *toc_section; - - /* The .ds section we use to hold function descriptors which we - create for exported symbols. */ - asection *descriptor_section; - - /* The list of import files. */ - struct xcoff_import_file *imports; - - /* Required alignment of sections within the output file. */ - unsigned long file_align; - - /* Whether the .text section must be read-only. */ - boolean textro; - - /* Whether garbage collection was done. */ - boolean gc; - - /* A linked list of symbols for which we have size information. */ - struct xcoff_link_size_list - { - struct xcoff_link_size_list *next; - struct xcoff_link_hash_entry *h; - bfd_size_type size; - } *size_list; - - /* Magic sections: _text, _etext, _data, _edata, _end, end. */ - asection *special_sections[6]; -}; - -/* Information we keep for each section in the output file during the - final link phase. */ - -struct xcoff_link_section_info -{ - /* The relocs to be output. */ - struct internal_reloc *relocs; - /* For each reloc against a global symbol whose index was not known - when the reloc was handled, the global hash table entry. */ - struct xcoff_link_hash_entry **rel_hashes; - /* If there is a TOC relative reloc against a global symbol, and the - index of the TOC symbol is not known when the reloc was handled, - an entry is added to this linked list. This is not an array, - like rel_hashes, because this case is quite uncommon. */ - struct xcoff_toc_rel_hash - { - struct xcoff_toc_rel_hash *next; - struct xcoff_link_hash_entry *h; - struct internal_reloc *rel; - } *toc_rel_hashes; -}; - -/* Information that we pass around while doing the final link step. */ - -struct xcoff_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Hash table for long symbol names. */ - struct bfd_strtab_hash *strtab; - /* Array of information kept for each output section, indexed by the - target_index field. */ - struct xcoff_link_section_info *section_info; - /* Symbol index of last C_FILE symbol (-1 if none). */ - long last_file_index; - /* Contents of last C_FILE symbol. */ - struct internal_syment last_file; - /* Symbol index of TOC symbol. */ - long toc_symindx; - /* Start of .loader symbols. */ - struct external_ldsym *ldsym; - /* Next .loader reloc to swap out. */ - struct external_ldrel *ldrel; - /* File position of start of line numbers. */ - file_ptr line_filepos; - /* Buffer large enough to hold swapped symbols of any input file. */ - struct internal_syment *internal_syms; - /* Buffer large enough to hold output indices of symbols of any - input file. */ - long *sym_indices; - /* Buffer large enough to hold output symbols for any input file. */ - bfd_byte *outsyms; - /* Buffer large enough to hold external line numbers for any input - section. */ - bfd_byte *linenos; - /* Buffer large enough to hold any input section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any input section. */ - bfd_byte *external_relocs; -}; - -static void xcoff_swap_ldhdr_in - PARAMS ((bfd *, const struct external_ldhdr *, struct internal_ldhdr *)); -static void xcoff_swap_ldhdr_out - PARAMS ((bfd *, const struct internal_ldhdr *, struct external_ldhdr *)); -static void xcoff_swap_ldsym_in - PARAMS ((bfd *, const struct external_ldsym *, struct internal_ldsym *)); -static void xcoff_swap_ldsym_out - PARAMS ((bfd *, const struct internal_ldsym *, struct external_ldsym *)); -static void xcoff_swap_ldrel_out - PARAMS ((bfd *, const struct internal_ldrel *, struct external_ldrel *)); -static struct bfd_hash_entry *xcoff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct internal_reloc *xcoff_read_internal_relocs - PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean, - struct internal_reloc *)); -static boolean xcoff_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean xcoff_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean xcoff_link_check_ar_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static bfd_size_type xcoff_find_reloc - PARAMS ((struct internal_reloc *, bfd_size_type, bfd_vma)); -static boolean xcoff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *)); -static boolean xcoff_link_add_dynamic_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean xcoff_mark PARAMS ((struct bfd_link_info *, asection *)); -static void xcoff_sweep PARAMS ((struct bfd_link_info *)); -static boolean xcoff_build_ldsyms - PARAMS ((struct xcoff_link_hash_entry *, PTR)); -static boolean xcoff_link_input_bfd - PARAMS ((struct xcoff_final_link_info *, bfd *)); -static boolean xcoff_write_global_symbol - PARAMS ((struct xcoff_link_hash_entry *, PTR)); -static boolean xcoff_reloc_link_order - PARAMS ((bfd *, struct xcoff_final_link_info *, asection *, - struct bfd_link_order *)); -static int xcoff_sort_relocs PARAMS ((const PTR, const PTR)); - -/* Routines to swap information in the XCOFF .loader section. If we - ever need to write an XCOFF loader, this stuff will need to be - moved to another file shared by the linker (which XCOFF calls the - ``binder'') and the loader. */ - -/* Swap in the ldhdr structure. */ - -static void -xcoff_swap_ldhdr_in (abfd, src, dst) - bfd *abfd; - const struct external_ldhdr *src; - struct internal_ldhdr *dst; -{ - dst->l_version = bfd_get_32 (abfd, src->l_version); - dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms); - dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc); - dst->l_istlen = bfd_get_32 (abfd, src->l_istlen); - dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid); - dst->l_impoff = bfd_get_32 (abfd, src->l_impoff); - dst->l_stlen = bfd_get_32 (abfd, src->l_stlen); - dst->l_stoff = bfd_get_32 (abfd, src->l_stoff); -} - -/* Swap out the ldhdr structure. */ - -static void -xcoff_swap_ldhdr_out (abfd, src, dst) - bfd *abfd; - const struct internal_ldhdr *src; - struct external_ldhdr *dst; -{ - bfd_put_32 (abfd, src->l_version, dst->l_version); - bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms); - bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc); - bfd_put_32 (abfd, src->l_istlen, dst->l_istlen); - bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid); - bfd_put_32 (abfd, src->l_impoff, dst->l_impoff); - bfd_put_32 (abfd, src->l_stlen, dst->l_stlen); - bfd_put_32 (abfd, src->l_stoff, dst->l_stoff); -} - -/* Swap in the ldsym structure. */ - -static void -xcoff_swap_ldsym_in (abfd, src, dst) - bfd *abfd; - const struct external_ldsym *src; - struct internal_ldsym *dst; -{ - if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) - memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN); - else - { - dst->_l._l_l._l_zeroes = 0; - dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset); - } - dst->l_value = bfd_get_32 (abfd, src->l_value); - dst->l_scnum = bfd_get_16 (abfd, src->l_scnum); - dst->l_smtype = bfd_get_8 (abfd, src->l_smtype); - dst->l_smclas = bfd_get_8 (abfd, src->l_smclas); - dst->l_ifile = bfd_get_32 (abfd, src->l_ifile); - dst->l_parm = bfd_get_32 (abfd, src->l_parm); -} - -/* Swap out the ldsym structure. */ - -static void -xcoff_swap_ldsym_out (abfd, src, dst) - bfd *abfd; - const struct internal_ldsym *src; - struct external_ldsym *dst; -{ - if (src->_l._l_l._l_zeroes != 0) - memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN); - else - { - bfd_put_32 (abfd, 0, dst->_l._l_l._l_zeroes); - bfd_put_32 (abfd, src->_l._l_l._l_offset, dst->_l._l_l._l_offset); - } - bfd_put_32 (abfd, src->l_value, dst->l_value); - bfd_put_16 (abfd, src->l_scnum, dst->l_scnum); - bfd_put_8 (abfd, src->l_smtype, dst->l_smtype); - bfd_put_8 (abfd, src->l_smclas, dst->l_smclas); - bfd_put_32 (abfd, src->l_ifile, dst->l_ifile); - bfd_put_32 (abfd, src->l_parm, dst->l_parm); -} - -/* As it happens, we never need to swap in the ldrel structure. */ - -/* Swap out the ldrel structure. */ - -static void -xcoff_swap_ldrel_out (abfd, src, dst) - bfd *abfd; - const struct internal_ldrel *src; - struct external_ldrel *dst; -{ - bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr); - bfd_put_32 (abfd, src->l_symndx, dst->l_symndx); - bfd_put_16 (abfd, src->l_rtype, dst->l_rtype); - bfd_put_16 (abfd, src->l_rsecnm, dst->l_rsecnm); -} - -/* Routine to create an entry in an XCOFF link hash table. */ - -static struct bfd_hash_entry * -xcoff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct xcoff_link_hash_entry *ret = (struct xcoff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct xcoff_link_hash_entry *) NULL) - ret = ((struct xcoff_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct xcoff_link_hash_entry))); - if (ret == (struct xcoff_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct xcoff_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields. */ - ret->indx = -1; - ret->toc_section = NULL; - ret->u.toc_indx = -1; - ret->descriptor = NULL; - ret->ldsym = NULL; - ret->ldindx = -1; - ret->flags = 0; - ret->smclas = XMC_UA; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a XCOFF link hash table. */ - -struct bfd_link_hash_table * -_bfd_xcoff_bfd_link_hash_table_create (abfd) - bfd *abfd; -{ - struct xcoff_link_hash_table *ret; - - ret = ((struct xcoff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct xcoff_link_hash_table))); - if (ret == (struct xcoff_link_hash_table *) NULL) - return (struct bfd_link_hash_table *) NULL; - if (! _bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->debug_strtab = _bfd_xcoff_stringtab_init (); - ret->debug_section = NULL; - ret->loader_section = NULL; - ret->ldrel_count = 0; - memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr)); - ret->linkage_section = NULL; - ret->toc_section = NULL; - ret->descriptor_section = NULL; - ret->imports = NULL; - ret->file_align = 0; - ret->textro = false; - ret->gc = false; - memset (ret->special_sections, 0, sizeof ret->special_sections); - - /* The linker will always generate a full a.out header. We need to - record that fact now, before the sizeof_headers routine could be - called. */ - xcoff_data (abfd)->full_aouthdr = true; - - return &ret->root; -} - -/* Look up an entry in an XCOFF link hash table. */ - -#define xcoff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct xcoff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse an XCOFF link hash table. */ - -#define xcoff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the XCOFF link hash table from the info structure. This is - just a cast. */ - -#define xcoff_hash_table(p) ((struct xcoff_link_hash_table *) ((p)->hash)) - -/* Read internal relocs for an XCOFF csect. This is a wrapper around - _bfd_coff_read_internal_relocs which tries to take advantage of any - relocs which may have been cached for the enclosing section. */ - -static struct internal_reloc * -xcoff_read_internal_relocs (abfd, sec, cache, external_relocs, - require_internal, internal_relocs) - bfd *abfd; - asection *sec; - boolean cache; - bfd_byte *external_relocs; - boolean require_internal; - struct internal_reloc *internal_relocs; -{ - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->relocs == NULL - && xcoff_section_data (abfd, sec) != NULL) - { - asection *enclosing; - - enclosing = xcoff_section_data (abfd, sec)->enclosing; - - if (enclosing != NULL - && (coff_section_data (abfd, enclosing) == NULL - || coff_section_data (abfd, enclosing)->relocs == NULL) - && cache - && enclosing->reloc_count > 0) - { - if (_bfd_coff_read_internal_relocs (abfd, enclosing, true, - external_relocs, false, - (struct internal_reloc *) NULL) - == NULL) - return NULL; - } - - if (enclosing != NULL - && coff_section_data (abfd, enclosing) != NULL - && coff_section_data (abfd, enclosing)->relocs != NULL) - { - size_t off; - - off = ((sec->rel_filepos - enclosing->rel_filepos) - / bfd_coff_relsz (abfd)); - if (! require_internal) - return coff_section_data (abfd, enclosing)->relocs + off; - memcpy (internal_relocs, - coff_section_data (abfd, enclosing)->relocs + off, - sec->reloc_count * sizeof (struct internal_reloc)); - return internal_relocs; - } - } - - return _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, - require_internal, internal_relocs); -} - -/* Given an XCOFF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -_bfd_xcoff_bfd_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return xcoff_link_add_object_symbols (abfd, info); - case bfd_archive: - return (_bfd_generic_link_add_archive_symbols - (abfd, info, xcoff_link_check_archive_element)); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add symbols from an XCOFF object file. */ - -static boolean -xcoff_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - if (! xcoff_link_add_symbols (abfd, info)) - return false; - if (! info->keep_memory) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - return true; -} - -/* Check a single archive element to see if we need to include it in - the link. *PNEEDED is set according to whether this element is - needed in the link or not. This is called via - _bfd_generic_link_add_archive_symbols. */ - -static boolean -xcoff_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - - if (! xcoff_link_check_ar_symbols (abfd, info, pneeded)) - return false; - - if (*pneeded) - { - if (! xcoff_link_add_symbols (abfd, info)) - return false; - } - - if (! info->keep_memory || ! *pneeded) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - - return true; -} - -/* Look through the symbols to see if this object file should be - included in the link. */ - -static boolean -xcoff_link_check_ar_symbols (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - - *pneeded = false; - - symesz = bfd_coff_symesz (abfd); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + obj_raw_syment_count (abfd) * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - if (sym.n_sclass == C_EXT && sym.n_scnum != N_UNDEF) - { - const char *name; - char buf[SYMNMLEN + 1]; - struct bfd_link_hash_entry *h; - - /* This symbol is externally visible, and is defined by this - object file. */ - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - return false; - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* We are only interested in symbols that are currently - undefined. If a symbol is currently known to be common, - XCOFF linkers do not bring in an object file which - defines it. We also don't bring in symbols to satisfy - undefined references in shared objects. */ - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_undefined) - { - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - } - - esym += (sym.n_numaux + 1) * symesz; - } - - /* We do not need this object file. */ - return true; -} - -/* Returns the index of reloc in RELOCS with the least address greater - than or equal to ADDRESS. The relocs are sorted by address. */ - -static bfd_size_type -xcoff_find_reloc (relocs, count, address) - struct internal_reloc *relocs; - bfd_size_type count; - bfd_vma address; -{ - bfd_size_type min, max, this; - - if (count < 2) - { - if (count == 1 && relocs[0].r_vaddr < address) - return 1; - else - return 0; - } - - min = 0; - max = count; - - /* Do a binary search over (min,max]. */ - while (min + 1 < max) - { - bfd_vma raddr; - - this = (max + min) / 2; - raddr = relocs[this].r_vaddr; - if (raddr > address) - max = this; - else if (raddr < address) - min = this; - else - { - min = this; - break; - } - } - - if (relocs[min].r_vaddr < address) - return min + 1; - - while (min > 0 - && relocs[min - 1].r_vaddr == address) - --min; - - return min; -} - -/* Add all the symbols from an object file to the hash table. - - XCOFF is a weird format. A normal XCOFF .o files will have three - COFF sections--.text, .data, and .bss--but each COFF section will - contain many csects. These csects are described in the symbol - table. From the linker's point of view, each csect must be - considered a section in its own right. For example, a TOC entry is - handled as a small XMC_TC csect. The linker must be able to merge - different TOC entries together, which means that it must be able to - extract the XMC_TC csects from the .data section of the input .o - file. - - From the point of view of our linker, this is, of course, a hideous - nightmare. We cope by actually creating sections for each csect, - and discarding the original sections. We then have to handle the - relocation entries carefully, since the only way to tell which - csect they belong to is to examine the address. */ - -static boolean -xcoff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - unsigned int n_tmask; - unsigned int n_btshft; - boolean default_copy; - bfd_size_type symcount; - struct xcoff_link_hash_entry **sym_hash; - asection **csect_cache; - bfd_size_type linesz; - asection *o; - asection *last_real; - boolean keep_syms; - asection *csect; - unsigned int csect_index; - asection *first_csect; - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - struct reloc_info_struct - { - struct internal_reloc *relocs; - asection **csects; - bfd_byte *linenos; - } *reloc_info = NULL; - - if ((abfd->flags & DYNAMIC) != 0 - && ! info->static_link) - { - if (! xcoff_link_add_dynamic_symbols (abfd, info)) - return false; - } - - /* We need to build a .loader section, so we do it here. This won't - work if we're producing an XCOFF output file with no XCOFF input - files. FIXME. */ - if (xcoff_hash_table (info)->loader_section == NULL) - { - asection *lsec; - - lsec = bfd_make_section_anyway (abfd, ".loader"); - if (lsec == NULL) - goto error_return; - xcoff_hash_table (info)->loader_section = lsec; - lsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY; - } - /* Likewise for the linkage section. */ - if (xcoff_hash_table (info)->linkage_section == NULL) - { - asection *lsec; - - lsec = bfd_make_section_anyway (abfd, ".gl"); - if (lsec == NULL) - goto error_return; - xcoff_hash_table (info)->linkage_section = lsec; - lsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - lsec->alignment_power = 2; - } - /* Likewise for the TOC section. */ - if (xcoff_hash_table (info)->toc_section == NULL) - { - asection *tsec; - - tsec = bfd_make_section_anyway (abfd, ".tc"); - if (tsec == NULL) - goto error_return; - xcoff_hash_table (info)->toc_section = tsec; - tsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - tsec->alignment_power = 2; - } - /* Likewise for the descriptor section. */ - if (xcoff_hash_table (info)->descriptor_section == NULL) - { - asection *dsec; - - dsec = bfd_make_section_anyway (abfd, ".ds"); - if (dsec == NULL) - goto error_return; - xcoff_hash_table (info)->descriptor_section = dsec; - dsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - dsec->alignment_power = 2; - } - /* Likewise for the .debug section. */ - if (xcoff_hash_table (info)->debug_section == NULL) - { - asection *dsec; - - dsec = bfd_make_section_anyway (abfd, ".debug"); - if (dsec == NULL) - goto error_return; - xcoff_hash_table (info)->debug_section = dsec; - dsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY; - } - - if ((abfd->flags & DYNAMIC) != 0 - && ! info->static_link) - return true; - - n_tmask = coff_data (abfd)->local_n_tmask; - n_btshft = coff_data (abfd)->local_n_btshft; - - /* Define macros so that ISFCN, et. al., macros work correctly. */ -#define N_TMASK n_tmask -#define N_BTSHFT n_btshft - - if (info->keep_memory) - default_copy = false; - else - default_copy = true; - - symcount = obj_raw_syment_count (abfd); - - /* We keep a list of the linker hash table entries that correspond - to each external symbol. */ - sym_hash = ((struct xcoff_link_hash_entry **) - bfd_alloc (abfd, - (symcount - * sizeof (struct xcoff_link_hash_entry *)))); - if (sym_hash == NULL && symcount != 0) - goto error_return; - coff_data (abfd)->sym_hashes = (struct coff_link_hash_entry **) sym_hash; - memset (sym_hash, 0, - (size_t) symcount * sizeof (struct xcoff_link_hash_entry *)); - - /* Because of the weird stuff we are doing with XCOFF csects, we can - not easily determine which section a symbol is in, so we store - the information in the tdata for the input file. */ - csect_cache = ((asection **) - bfd_alloc (abfd, symcount * sizeof (asection *))); - if (csect_cache == NULL && symcount != 0) - goto error_return; - xcoff_data (abfd)->csects = csect_cache; - memset (csect_cache, 0, (size_t) symcount * sizeof (asection *)); - - /* While splitting sections into csects, we need to assign the - relocs correctly. The relocs and the csects must both be in - order by VMA within a given section, so we handle this by - scanning along the relocs as we process the csects. We index - into reloc_info using the section target_index. */ - reloc_info = ((struct reloc_info_struct *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct reloc_info_struct))); - if (reloc_info == NULL) - goto error_return; - memset ((PTR) reloc_info, 0, - (abfd->section_count + 1) * sizeof (struct reloc_info_struct)); - - /* Read in the relocs and line numbers for each section. */ - linesz = bfd_coff_linesz (abfd); - last_real = NULL; - for (o = abfd->sections; o != NULL; o = o->next) - { - last_real = o; - if ((o->flags & SEC_RELOC) != 0) - { - reloc_info[o->target_index].relocs = - xcoff_read_internal_relocs (abfd, o, true, (bfd_byte *) NULL, - false, (struct internal_reloc *) NULL); - reloc_info[o->target_index].csects = - (asection **) bfd_malloc (o->reloc_count * sizeof (asection *)); - if (reloc_info[o->target_index].csects == NULL) - goto error_return; - memset (reloc_info[o->target_index].csects, 0, - o->reloc_count * sizeof (asection *)); - } - - if ((info->strip == strip_none || info->strip == strip_some) - && o->lineno_count > 0) - { - bfd_byte *linenos; - - linenos = (bfd_byte *) bfd_malloc (o->lineno_count * linesz); - if (linenos == NULL) - goto error_return; - reloc_info[o->target_index].linenos = linenos; - if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0 - || (bfd_read (linenos, linesz, o->lineno_count, abfd) - != linesz * o->lineno_count)) - goto error_return; - } - } - - /* Don't let the linker relocation routines discard the symbols. */ - keep_syms = obj_coff_keep_syms (abfd); - obj_coff_keep_syms (abfd) = true; - - csect = NULL; - csect_index = 0; - first_csect = NULL; - - symesz = bfd_coff_symesz (abfd); - BFD_ASSERT (symesz == bfd_coff_auxesz (abfd)); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + symcount * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - union internal_auxent aux; - const char *name; - char buf[SYMNMLEN + 1]; - int smtyp; - flagword flags; - asection *section; - bfd_vma value; - struct xcoff_link_hash_entry *set_toc; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - /* In this pass we are only interested in symbols with csect - information. */ - if (sym.n_sclass != C_EXT && sym.n_sclass != C_HIDEXT) - { - if (sym.n_sclass == C_FILE && csect != NULL) - { - xcoff_section_data (abfd, csect)->last_symndx = - ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - csect = NULL; - } - - if (csect != NULL) - *csect_cache = csect; - else if (first_csect == NULL || sym.n_sclass == C_FILE) - *csect_cache = coff_section_from_bfd_index (abfd, sym.n_scnum); - else - *csect_cache = NULL; - esym += (sym.n_numaux + 1) * symesz; - sym_hash += sym.n_numaux + 1; - csect_cache += sym.n_numaux + 1; - continue; - } - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - goto error_return; - - /* If this symbol has line number information attached to it, - and we're not stripping it, count the number of entries and - add them to the count for this csect. In the final link pass - we are going to attach line number information by symbol, - rather than by section, in order to more easily handle - garbage collection. */ - if ((info->strip == strip_none || info->strip == strip_some) - && sym.n_numaux > 1 - && csect != NULL - && ISFCN (sym.n_type)) - { - union internal_auxent auxlin; - - bfd_coff_swap_aux_in (abfd, (PTR) (esym + symesz), - sym.n_type, sym.n_sclass, - 0, sym.n_numaux, (PTR) &auxlin); - if (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0) - { - asection *enclosing; - bfd_size_type linoff; - - enclosing = xcoff_section_data (abfd, csect)->enclosing; - if (enclosing == NULL) - { - (*_bfd_error_handler) - ("%s: `%s' has line numbers but no enclosing section", - bfd_get_filename (abfd), name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - linoff = (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr - - enclosing->line_filepos); - if (linoff < enclosing->lineno_count * linesz) - { - struct internal_lineno lin; - bfd_byte *linpstart; - - linpstart = (reloc_info[enclosing->target_index].linenos - + linoff); - bfd_coff_swap_lineno_in (abfd, (PTR) linpstart, (PTR) &lin); - if (lin.l_lnno == 0 - && ((bfd_size_type) lin.l_addr.l_symndx - == ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz))) - { - bfd_byte *linpend, *linp; - - linpend = (reloc_info[enclosing->target_index].linenos - + enclosing->lineno_count * linesz); - for (linp = linpstart + linesz; - linp < linpend; - linp += linesz) - { - bfd_coff_swap_lineno_in (abfd, (PTR) linp, - (PTR) &lin); - if (lin.l_lnno == 0) - break; - } - csect->lineno_count += (linp - linpstart) / linesz; - /* The setting of line_filepos will only be - useful if all the line number entries for a - csect are contiguous; this only matters for - error reporting. */ - if (csect->line_filepos == 0) - csect->line_filepos = - auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr; - } - } - } - } - - /* Pick up the csect auxiliary information. */ - - if (sym.n_numaux == 0) - { - (*_bfd_error_handler) - ("%s: class %d symbol `%s' has no aux entries", - bfd_get_filename (abfd), sym.n_sclass, name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - bfd_coff_swap_aux_in (abfd, - (PTR) (esym + symesz * sym.n_numaux), - sym.n_type, sym.n_sclass, - sym.n_numaux - 1, sym.n_numaux, - (PTR) &aux); - - smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp); - - flags = BSF_GLOBAL; - section = NULL; - value = 0; - set_toc = NULL; - - switch (smtyp) - { - default: - (*_bfd_error_handler) - ("%s: symbol `%s' has unrecognized csect type %d", - bfd_get_filename (abfd), name, smtyp); - bfd_set_error (bfd_error_bad_value); - goto error_return; - - case XTY_ER: - /* This is an external reference. */ - if (sym.n_sclass == C_HIDEXT - || sym.n_scnum != N_UNDEF - || aux.x_csect.x_scnlen.l != 0) - { - (*_bfd_error_handler) - ("%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d", - bfd_get_filename (abfd), name, sym.n_sclass, sym.n_scnum, - aux.x_csect.x_scnlen.l); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - /* An XMC_XO external reference is actually a reference to - an absolute location. */ - if (aux.x_csect.x_smclas != XMC_XO) - section = bfd_und_section_ptr; - else - { - section = bfd_abs_section_ptr; - value = sym.n_value; - } - break; - - case XTY_SD: - /* This is a csect definition. */ - - if (csect != NULL) - { - xcoff_section_data (abfd, csect)->last_symndx = - ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - } - - csect = NULL; - csect_index = -1; - - /* When we see a TOC anchor, we record the TOC value. */ - if (aux.x_csect.x_smclas == XMC_TC0) - { - if (sym.n_sclass != C_HIDEXT - || aux.x_csect.x_scnlen.l != 0) - { - (*_bfd_error_handler) - ("%s: XMC_TC0 symbol `%s' is class %d scnlen %d", - bfd_get_filename (abfd), name, sym.n_sclass, - aux.x_csect.x_scnlen.l); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - xcoff_data (abfd)->toc = sym.n_value; - } - - /* We must merge TOC entries for the same symbol. We can - merge two TOC entries if they are both C_HIDEXT, they - both have the same name, they are both 4 bytes long, and - they both have a relocation table entry for an external - symbol with the same name. Unfortunately, this means - that we must look through the relocations. Ick. */ - if (aux.x_csect.x_smclas == XMC_TC - && sym.n_sclass == C_HIDEXT - && aux.x_csect.x_scnlen.l == 4 - && info->hash->creator == abfd->xvec) - { - asection *enclosing; - struct internal_reloc *relocs; - bfd_size_type relindx; - struct internal_reloc *rel; - - enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum); - if (enclosing == NULL) - goto error_return; - - relocs = reloc_info[enclosing->target_index].relocs; - relindx = xcoff_find_reloc (relocs, enclosing->reloc_count, - sym.n_value); - rel = relocs + relindx; - if (relindx < enclosing->reloc_count - && rel->r_vaddr == (bfd_vma) sym.n_value - && rel->r_size == 31 - && rel->r_type == R_POS) - { - bfd_byte *erelsym; - struct internal_syment relsym; - - erelsym = ((bfd_byte *) obj_coff_external_syms (abfd) - + rel->r_symndx * symesz); - bfd_coff_swap_sym_in (abfd, (PTR) erelsym, (PTR) &relsym); - if (relsym.n_sclass == C_EXT) - { - const char *relname; - char relbuf[SYMNMLEN + 1]; - boolean copy; - struct xcoff_link_hash_entry *h; - - /* At this point we know that the TOC entry is - for an externally visible symbol. */ - relname = _bfd_coff_internal_syment_name (abfd, &relsym, - relbuf); - if (relname == NULL) - goto error_return; - - /* We only merge TOC entries if the TC name is - the same as the symbol name. This handles - the normal case, but not common cases like - SYM.P4 which gcc generates to store SYM + 4 - in the TOC. FIXME. */ - if (strcmp (name, relname) == 0) - { - copy = (! info->keep_memory - || relsym._n._n_n._n_zeroes != 0 - || relsym._n._n_n._n_offset == 0); - h = xcoff_link_hash_lookup (xcoff_hash_table (info), - relname, true, copy, - false); - if (h == NULL) - goto error_return; - - /* At this point h->root.type could be - bfd_link_hash_new. That should be OK, - since we know for sure that we will come - across this symbol as we step through the - file. */ - - /* We store h in *sym_hash for the - convenience of the relocate_section - function. */ - *sym_hash = h; - - if (h->toc_section != NULL) - { - asection **rel_csects; - - /* We already have a TOC entry for this - symbol, so we can just ignore this - one. */ - rel_csects = - reloc_info[enclosing->target_index].csects; - rel_csects[relindx] = bfd_und_section_ptr; - break; - } - - /* We are about to create a TOC entry for - this symbol. */ - set_toc = h; - } - } - } - } - - /* We need to create a new section. We get the name from - the csect storage mapping class, so that the linker can - accumulate similar csects together. */ - { - static const char *csect_name_by_class[] = - { - ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo", - ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0", - ".td" - }; - const char *csect_name; - asection *enclosing; - - if ((aux.x_csect.x_smclas >= - sizeof csect_name_by_class / sizeof csect_name_by_class[0]) - || csect_name_by_class[aux.x_csect.x_smclas] == NULL) - { - (*_bfd_error_handler) - ("%s: symbol `%s' has unrecognized smclas %d", - bfd_get_filename (abfd), name, aux.x_csect.x_smclas); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - csect_name = csect_name_by_class[aux.x_csect.x_smclas]; - csect = bfd_make_section_anyway (abfd, csect_name); - if (csect == NULL) - goto error_return; - enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum); - if (enclosing == NULL) - goto error_return; - if (! bfd_is_abs_section (enclosing) - && ((bfd_vma) sym.n_value < enclosing->vma - || ((bfd_vma) sym.n_value + aux.x_csect.x_scnlen.l - > enclosing->vma + enclosing->_raw_size))) - { - (*_bfd_error_handler) - ("%s: csect `%s' not in enclosing section", - bfd_get_filename (abfd), name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - csect->vma = sym.n_value; - csect->filepos = (enclosing->filepos - + sym.n_value - - enclosing->vma); - csect->_raw_size = aux.x_csect.x_scnlen.l; - csect->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; - csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp); - - /* Record the enclosing section in the tdata for this new - section. */ - csect->used_by_bfd = - ((struct coff_section_tdata *) - bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (csect->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, csect)->tdata = - bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata)); - if (coff_section_data (abfd, csect)->tdata == NULL) - goto error_return; - xcoff_section_data (abfd, csect)->enclosing = enclosing; - xcoff_section_data (abfd, csect)->lineno_count = - enclosing->lineno_count; - - if (enclosing->owner == abfd) - { - struct internal_reloc *relocs; - bfd_size_type relindx; - struct internal_reloc *rel; - asection **rel_csect; - - relocs = reloc_info[enclosing->target_index].relocs; - relindx = xcoff_find_reloc (relocs, enclosing->reloc_count, - csect->vma); - rel = relocs + relindx; - rel_csect = (reloc_info[enclosing->target_index].csects - + relindx); - csect->rel_filepos = (enclosing->rel_filepos - + relindx * bfd_coff_relsz (abfd)); - while (relindx < enclosing->reloc_count - && *rel_csect == NULL - && rel->r_vaddr < csect->vma + csect->_raw_size) - { - *rel_csect = csect; - csect->flags |= SEC_RELOC; - ++csect->reloc_count; - ++relindx; - ++rel; - ++rel_csect; - } - } - - /* There are a number of other fields and section flags - which we do not bother to set. */ - - csect_index = ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - - xcoff_section_data (abfd, csect)->first_symndx = csect_index; - - if (first_csect == NULL) - first_csect = csect; - - /* If this symbol is C_EXT, we treat it as starting at the - beginning of the newly created section. */ - if (sym.n_sclass == C_EXT) - { - section = csect; - value = 0; - } - - /* If this is a TOC section for a symbol, record it. */ - if (set_toc != NULL) - set_toc->toc_section = csect; - } - break; - - case XTY_LD: - /* This is a label definition. The x_scnlen field is the - symbol index of the csect. I believe that this must - always follow the appropriate XTY_SD symbol, so I will - insist on it. */ - { - boolean bad; - - bad = false; - if (aux.x_csect.x_scnlen.l < 0 - || (aux.x_csect.x_scnlen.l - >= esym - (bfd_byte *) obj_coff_external_syms (abfd))) - bad = true; - if (! bad) - { - section = xcoff_data (abfd)->csects[aux.x_csect.x_scnlen.l]; - if (section == NULL - || (section->flags & SEC_HAS_CONTENTS) == 0) - bad = true; - } - if (bad) - { - (*_bfd_error_handler) - ("%s: misplaced XTY_LD `%s'", - bfd_get_filename (abfd), name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - value = sym.n_value - csect->vma; - } - break; - - case XTY_CM: - /* This is an unitialized csect. We could base the name on - the storage mapping class, but we don't bother. If this - csect is externally visible, it is a common symbol. */ - - if (csect != NULL) - { - xcoff_section_data (abfd, csect)->last_symndx = - ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - } - - csect = bfd_make_section_anyway (abfd, ".bss"); - if (csect == NULL) - goto error_return; - csect->vma = sym.n_value; - csect->_raw_size = aux.x_csect.x_scnlen.l; - csect->flags |= SEC_ALLOC; - csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp); - /* There are a number of other fields and section flags - which we do not bother to set. */ - - csect_index = ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - - csect->used_by_bfd = - ((struct coff_section_tdata *) - bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (csect->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, csect)->tdata = - bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata)); - if (coff_section_data (abfd, csect)->tdata == NULL) - goto error_return; - xcoff_section_data (abfd, csect)->first_symndx = csect_index; - - if (first_csect == NULL) - first_csect = csect; - - if (sym.n_sclass == C_EXT) - { - csect->flags |= SEC_IS_COMMON; - csect->_raw_size = 0; - section = csect; - value = aux.x_csect.x_scnlen.l; - } - - break; - } - - /* Check for magic symbol names. */ - if ((smtyp == XTY_SD || smtyp == XTY_CM) - && aux.x_csect.x_smclas != XMC_TC) - { - int i; - - i = -1; - if (name[0] == '_') - { - if (strcmp (name, "_text") == 0) - i = 0; - else if (strcmp (name, "_etext") == 0) - i = 1; - else if (strcmp (name, "_data") == 0) - i = 2; - else if (strcmp (name, "_edata") == 0) - i = 3; - else if (strcmp (name, "_end") == 0) - i = 4; - } - else if (name[0] == 'e' && strcmp (name, "end") == 0) - i = 5; - - if (i != -1) - xcoff_hash_table (info)->special_sections[i] = csect; - } - - /* Now we have enough information to add the symbol to the - linker hash table. */ - - if (sym.n_sclass == C_EXT) - { - boolean copy; - - BFD_ASSERT (section != NULL); - - /* We must copy the name into memory if we got it from the - syment itself, rather than the string table. */ - copy = default_copy; - if (sym._n._n_n._n_zeroes != 0 - || sym._n._n_n._n_offset == 0) - copy = true; - - if (info->hash->creator == abfd->xvec) - { - /* If we are statically linking a shared object, it is - OK for symbol redefinitions to occur. I can't figure - out just what the XCOFF linker is doing, but - something like this is required for -bnso to work. */ - if (! bfd_is_und_section (section)) - *sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info), - name, true, copy, false); - else - *sym_hash = ((struct xcoff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, name, - true, copy, false)); - if (*sym_hash == NULL) - goto error_return; - if (((*sym_hash)->root.type == bfd_link_hash_defined - || (*sym_hash)->root.type == bfd_link_hash_defweak) - && ! bfd_is_und_section (section) - && ! bfd_is_com_section (section)) - { - if ((abfd->flags & DYNAMIC) != 0) - { - section = bfd_und_section_ptr; - value = 0; - } - else if (((*sym_hash)->root.u.def.section->owner->flags - & DYNAMIC) != 0) - { - (*sym_hash)->root.type = bfd_link_hash_undefined; - (*sym_hash)->root.u.undef.abfd = - (*sym_hash)->root.u.def.section->owner; - } - } - } - - /* _bfd_generic_link_add_one_symbol may call the linker to - generate an error message, and the linker may try to read - the symbol table to give a good error. Right now, the - line numbers are in an inconsistent state, since they are - counted both in the real sections and in the new csects. - We need to leave the count in the real sections so that - the linker can report the line number of the error - correctly, so temporarily clobber the link to the csects - so that the linker will not try to read the line numbers - a second time from the csects. */ - BFD_ASSERT (last_real->next == first_csect); - last_real->next = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, flags, section, value, - (const char *) NULL, copy, true, - (struct bfd_link_hash_entry **) sym_hash))) - goto error_return; - last_real->next = first_csect; - - if (smtyp == XTY_CM) - { - if ((*sym_hash)->root.type != bfd_link_hash_common - || (*sym_hash)->root.u.c.p->section != csect) - { - /* We don't need the common csect we just created. */ - csect->_raw_size = 0; - } - else - { - (*sym_hash)->root.u.c.p->alignment_power - = csect->alignment_power; - } - } - - if (info->hash->creator == abfd->xvec) - { - int flag; - - if (smtyp == XTY_ER || smtyp == XTY_CM) - flag = XCOFF_REF_REGULAR; - else - flag = XCOFF_DEF_REGULAR; - (*sym_hash)->flags |= flag; - - if ((*sym_hash)->smclas == XMC_UA - || flag == XCOFF_DEF_REGULAR) - (*sym_hash)->smclas = aux.x_csect.x_smclas; - } - } - - *csect_cache = csect; - - esym += (sym.n_numaux + 1) * symesz; - sym_hash += sym.n_numaux + 1; - csect_cache += sym.n_numaux + 1; - } - - BFD_ASSERT (last_real == NULL || last_real->next == first_csect); - - /* Make sure that we have seen all the relocs. */ - for (o = abfd->sections; o != first_csect; o = o->next) - { - /* Reset the section size and the line numebr count, since the - data is now attached to the csects. Don't reset the size of - the .debug section, since we need to read it below in - bfd_xcoff_size_dynamic_sections. */ - if (strcmp (bfd_get_section_name (abfd, o), ".debug") != 0) - o->_raw_size = 0; - o->lineno_count = 0; - - if ((o->flags & SEC_RELOC) != 0) - { - bfd_size_type i; - struct internal_reloc *rel; - asection **rel_csect; - - rel = reloc_info[o->target_index].relocs; - rel_csect = reloc_info[o->target_index].csects; - for (i = 0; i < o->reloc_count; i++, rel++, rel_csect++) - { - if (*rel_csect == NULL) - { - (*_bfd_error_handler) - ("%s: reloc %s:%d not in csect", - bfd_get_filename (abfd), o->name, i); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - /* We identify all symbols which are called, so that we - can create glue code for calls to functions imported - from dynamic objects. */ - if (info->hash->creator == abfd->xvec - && *rel_csect != bfd_und_section_ptr - && (rel->r_type == R_BR - || rel->r_type == R_RBR) - && obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL) - { - struct xcoff_link_hash_entry *h; - - h = obj_xcoff_sym_hashes (abfd)[rel->r_symndx]; - h->flags |= XCOFF_CALLED; - /* If the symbol name starts with a period, it is - the code of a function. If the symbol is - currently undefined, then add an undefined symbol - for the function descriptor. This should do no - harm, because any regular object that defines the - function should also define the function - descriptor. It helps, because it means that we - will identify the function descriptor with a - dynamic object if a dynamic object defines it. */ - if (h->root.root.string[0] == '.' - && h->descriptor == NULL) - { - struct xcoff_link_hash_entry *hds; - - hds = xcoff_link_hash_lookup (xcoff_hash_table (info), - h->root.root.string + 1, - true, false, true); - if (hds == NULL) - goto error_return; - if (hds->root.type == bfd_link_hash_new) - { - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, hds->root.root.string, - (flagword) 0, bfd_und_section_ptr, - (bfd_vma) 0, (const char *) NULL, false, - true, - (struct bfd_link_hash_entry **) &hds))) - goto error_return; - } - hds->flags |= XCOFF_DESCRIPTOR; - BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0 - && (h->flags & XCOFF_DESCRIPTOR) == 0); - hds->descriptor = h; - h->descriptor = hds; - } - } - } - - free (reloc_info[o->target_index].csects); - reloc_info[o->target_index].csects = NULL; - - /* Reset SEC_RELOC and the reloc_count, since the reloc - information is now attached to the csects. */ - o->flags &=~ SEC_RELOC; - o->reloc_count = 0; - - /* If we are not keeping memory, free the reloc information. */ - if (! info->keep_memory - && coff_section_data (abfd, o) != NULL - && coff_section_data (abfd, o)->relocs != NULL - && ! coff_section_data (abfd, o)->keep_relocs) - { - free (coff_section_data (abfd, o)->relocs); - coff_section_data (abfd, o)->relocs = NULL; - } - } - - /* Free up the line numbers. FIXME: We could cache these - somewhere for the final link, to avoid reading them again. */ - if (reloc_info[o->target_index].linenos != NULL) - { - free (reloc_info[o->target_index].linenos); - reloc_info[o->target_index].linenos = NULL; - } - } - - free (reloc_info); - - obj_coff_keep_syms (abfd) = keep_syms; - - return true; - - error_return: - if (reloc_info != NULL) - { - for (o = abfd->sections; o != NULL; o = o->next) - { - if (reloc_info[o->target_index].csects != NULL) - free (reloc_info[o->target_index].csects); - if (reloc_info[o->target_index].linenos != NULL) - free (reloc_info[o->target_index].linenos); - } - free (reloc_info); - } - obj_coff_keep_syms (abfd) = keep_syms; - return false; -} - -#undef N_TMASK -#undef N_BTSHFT - -/* This function is used to add symbols from a dynamic object to the - global symbol table. */ - -static boolean -xcoff_link_add_dynamic_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - asection *lsec; - bfd_byte *buf = NULL; - struct internal_ldhdr ldhdr; - const char *strings; - struct external_ldsym *elsym, *elsymend; - struct xcoff_import_file *n; - const char *bname; - const char *mname; - const char *s; - unsigned int c; - struct xcoff_import_file **pp; - - /* We can only handle a dynamic object if we are generating an XCOFF - output file. */ - if (info->hash->creator != abfd->xvec) - { - (*_bfd_error_handler) - ("%s: XCOFF shared object when not producing XCOFF output", - bfd_get_filename (abfd)); - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - /* The symbols we use from a dynamic object are not the symbols in - the normal symbol table, but, rather, the symbols in the export - table. If there is a global symbol in a dynamic object which is - not in the export table, the loader will not be able to find it, - so we don't want to find it either. Also, on AIX 4.1.3, shr.o in - libc.a has symbols in the export table which are not in the - symbol table. */ - - /* Read in the .loader section. FIXME: We should really use the - o_snloader field in the a.out header, rather than grabbing the - section by name. */ - lsec = bfd_get_section_by_name (abfd, ".loader"); - if (lsec == NULL) - { - (*_bfd_error_handler) - ("%s: dynamic object with no .loader section", - bfd_get_filename (abfd)); - bfd_set_error (bfd_error_no_symbols); - goto error_return; - } - - buf = (bfd_byte *) bfd_malloc (lsec->_raw_size); - if (buf == NULL && lsec->_raw_size > 0) - goto error_return; - - if (! bfd_get_section_contents (abfd, lsec, (PTR) buf, (file_ptr) 0, - lsec->_raw_size)) - goto error_return; - - /* Remove the sections from this object, so that they do not get - included in the link. */ - abfd->sections = NULL; - - xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) buf, &ldhdr); - - strings = (char *) buf + ldhdr.l_stoff; - - elsym = (struct external_ldsym *) (buf + LDHDRSZ); - elsymend = elsym + ldhdr.l_nsyms; - BFD_ASSERT (sizeof (struct external_ldsym) == LDSYMSZ); - for (; elsym < elsymend; elsym++) - { - struct internal_ldsym ldsym; - char nambuf[SYMNMLEN + 1]; - const char *name; - struct xcoff_link_hash_entry *h; - - xcoff_swap_ldsym_in (abfd, elsym, &ldsym); - - /* We are only interested in exported symbols. */ - if ((ldsym.l_smtype & L_EXPORT) == 0) - continue; - - if (ldsym._l._l_l._l_zeroes == 0) - name = strings + ldsym._l._l_l._l_offset; - else - { - memcpy (nambuf, ldsym._l._l_name, SYMNMLEN); - nambuf[SYMNMLEN] = '\0'; - name = nambuf; - } - - /* Normally we could not call xcoff_link_hash_lookup in an add - symbols routine, since we might not be using an XCOFF hash - table. However, we verified above that we are using an XCOFF - hash table. */ - - h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true, - true, true); - if (h == NULL) - goto error_return; - - h->flags |= XCOFF_DEF_DYNAMIC; - - /* If the symbol is undefined, and the BFD it was found in is - not a dynamic object, change the BFD to this dynamic object, - so that we can get the correct import file ID. */ - if ((h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && (h->root.u.undef.abfd == NULL - || (h->root.u.undef.abfd->flags & DYNAMIC) == 0)) - h->root.u.undef.abfd = abfd; - - if (h->root.type == bfd_link_hash_new) - { - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = abfd; - /* We do not want to add this to the undefined symbol list. */ - } - - if (h->smclas == XMC_UA - || h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - h->smclas = ldsym.l_smclas; - - /* Unless this is an XMC_XO symbol, we don't bother to actually - define it, since we don't have a section to put it in anyhow. - Instead, the relocation routines handle the DEF_DYNAMIC flag - correctly. */ - - if (h->smclas == XMC_XO - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak)) - { - /* This symbol has an absolute value. */ - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = bfd_abs_section_ptr; - h->root.u.def.value = ldsym.l_value; - } - } - - if (buf != NULL) - { - free (buf); - buf = NULL; - } - - /* Record this file in the import files. */ - - n = ((struct xcoff_import_file *) - bfd_alloc (abfd, sizeof (struct xcoff_import_file))); - if (n == NULL) - goto error_return; - n->next = NULL; - - /* For some reason, the path entry in the import file list for a - shared object appears to always be empty. The file name is the - base name. */ - n->path = ""; - if (abfd->my_archive == NULL) - { - bname = bfd_get_filename (abfd); - mname = ""; - } - else - { - bname = bfd_get_filename (abfd->my_archive); - mname = bfd_get_filename (abfd); - } - s = strrchr (bname, '/'); - if (s != NULL) - bname = s + 1; - n->file = bname; - n->member = mname; - - /* We start c at 1 because the first import file number is reserved - for LIBPATH. */ - for (pp = &xcoff_hash_table (info)->imports, c = 1; - *pp != NULL; - pp = &(*pp)->next, ++c) - ; - *pp = n; - - xcoff_data (abfd)->import_file_id = c; - - return true; - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Routines that are called after all the input files have been - handled, but before the sections are laid out in memory. */ - -/* Mark a symbol as not being garbage, including the section in which - it is defined. */ - -static INLINE boolean -xcoff_mark_symbol (info, h) - struct bfd_link_info *info; - struct xcoff_link_hash_entry *h; -{ - if ((h->flags & XCOFF_MARK) != 0) - return true; - - h->flags |= XCOFF_MARK; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - - hsec = h->root.u.def.section; - if ((hsec->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, hsec)) - return false; - } - } - - if (h->toc_section != NULL - && (h->toc_section->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, h->toc_section)) - return false; - } - - return true; -} - -/* The mark phase of garbage collection. For a given section, mark - it, and all the sections which define symbols to which it refers. - Because this function needs to look at the relocs, we also count - the number of relocs which need to be copied into the .loader - section. */ - -static boolean -xcoff_mark (info, sec) - struct bfd_link_info *info; - asection *sec; -{ - if ((sec->flags & SEC_MARK) != 0) - return true; - - sec->flags |= SEC_MARK; - - if (sec->owner->xvec == info->hash->creator - && coff_section_data (sec->owner, sec) != NULL - && xcoff_section_data (sec->owner, sec) != NULL) - { - register struct xcoff_link_hash_entry **hp, **hpend; - struct internal_reloc *rel, *relend; - - /* Mark all the symbols in this section. */ - - hp = (obj_xcoff_sym_hashes (sec->owner) - + xcoff_section_data (sec->owner, sec)->first_symndx); - hpend = (obj_xcoff_sym_hashes (sec->owner) - + xcoff_section_data (sec->owner, sec)->last_symndx); - for (; hp < hpend; hp++) - { - register struct xcoff_link_hash_entry *h; - - h = *hp; - if (h != NULL - && (h->flags & XCOFF_MARK) == 0) - { - if (! xcoff_mark_symbol (info, h)) - return false; - } - } - - /* Look through the section relocs. */ - - if ((sec->flags & SEC_RELOC) != 0 - && sec->reloc_count > 0) - { - rel = xcoff_read_internal_relocs (sec->owner, sec, true, - (bfd_byte *) NULL, false, - (struct internal_reloc *) NULL); - if (rel == NULL) - return false; - relend = rel + sec->reloc_count; - for (; rel < relend; rel++) - { - asection *rsec; - struct xcoff_link_hash_entry *h; - - if ((unsigned int) rel->r_symndx - > obj_raw_syment_count (sec->owner)) - continue; - - h = obj_xcoff_sym_hashes (sec->owner)[rel->r_symndx]; - if (h != NULL - && (h->flags & XCOFF_MARK) == 0) - { - if (! xcoff_mark_symbol (info, h)) - return false; - } - - rsec = xcoff_data (sec->owner)->csects[rel->r_symndx]; - if (rsec != NULL - && (rsec->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, rsec)) - return false; - } - - /* See if this reloc needs to be copied into the .loader - section. */ - switch (rel->r_type) - { - default: - if (h == NULL - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common - || ((h->flags & XCOFF_CALLED) != 0 - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && h->root.root.string[0] == '.' - && h->descriptor != NULL - && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0 - || info->shared - || ((h->descriptor->flags & XCOFF_IMPORT) != 0 - && (h->descriptor->flags - & XCOFF_DEF_REGULAR) == 0)))) - break; - /* Fall through. */ - case R_POS: - case R_NEG: - case R_RL: - case R_RLA: - ++xcoff_hash_table (info)->ldrel_count; - if (h != NULL) - h->flags |= XCOFF_LDREL; - break; - case R_TOC: - case R_GL: - case R_TCL: - case R_TRL: - case R_TRLA: - /* We should never need a .loader reloc for a TOC - relative reloc. */ - break; - } - } - - if (! info->keep_memory - && coff_section_data (sec->owner, sec) != NULL - && coff_section_data (sec->owner, sec)->relocs != NULL - && ! coff_section_data (sec->owner, sec)->keep_relocs) - { - free (coff_section_data (sec->owner, sec)->relocs); - coff_section_data (sec->owner, sec)->relocs = NULL; - } - } - } - - return true; -} - -/* The sweep phase of garbage collection. Remove all garbage - sections. */ - -static void -xcoff_sweep (info) - struct bfd_link_info *info; -{ - bfd *sub; - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - for (o = sub->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_MARK) == 0) - { - /* Keep all sections from non-XCOFF input files. Keep - special sections. Keep .debug sections for the - moment. */ - if (sub->xvec != info->hash->creator - || o == xcoff_hash_table (info)->debug_section - || o == xcoff_hash_table (info)->loader_section - || o == xcoff_hash_table (info)->linkage_section - || o == xcoff_hash_table (info)->toc_section - || o == xcoff_hash_table (info)->descriptor_section - || strcmp (o->name, ".debug") == 0) - o->flags |= SEC_MARK; - else - { - o->_raw_size = 0; - o->reloc_count = 0; - o->lineno_count = 0; - } - } - } - } -} - -/* Record the number of elements in a set. This is used to output the - correct csect length. */ - -boolean -bfd_xcoff_link_record_set (output_bfd, info, harg, size) - bfd *output_bfd; - struct bfd_link_info *info; - struct bfd_link_hash_entry *harg; - bfd_size_type size; -{ - struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; - struct xcoff_link_size_list *n; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - /* This will hardly ever be called. I don't want to burn four bytes - per global symbol, so instead the size is kept on a linked list - attached to the hash table. */ - - n = ((struct xcoff_link_size_list *) - bfd_alloc (output_bfd, sizeof (struct xcoff_link_size_list))); - if (n == NULL) - return false; - n->next = xcoff_hash_table (info)->size_list; - n->h = h; - n->size = size; - xcoff_hash_table (info)->size_list = n; - - h->flags |= XCOFF_HAS_SIZE; - - return true; -} - -/* Import a symbol. */ - -boolean -bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile, - impmember) - bfd *output_bfd; - struct bfd_link_info *info; - struct bfd_link_hash_entry *harg; - bfd_vma val; - const char *imppath; - const char *impfile; - const char *impmember; -{ - struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h->flags |= XCOFF_IMPORT; - - if (val != (bfd_vma) -1) - { - if (h->root.type == bfd_link_hash_defined - && (! bfd_is_abs_section (h->root.u.def.section) - || h->root.u.def.value != val)) - { - if (! ((*info->callbacks->multiple_definition) - (info, h->root.root.string, h->root.u.def.section->owner, - h->root.u.def.section, h->root.u.def.value, - output_bfd, bfd_abs_section_ptr, val))) - return false; - } - - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = bfd_abs_section_ptr; - h->root.u.def.value = val; - } - - if (h->ldsym == NULL) - { - h->ldsym = ((struct internal_ldsym *) - bfd_zalloc (output_bfd, sizeof (struct internal_ldsym))); - if (h->ldsym == NULL) - return false; - } - - if (imppath == NULL) - h->ldsym->l_ifile = (bfd_size_type) -1; - else - { - unsigned int c; - struct xcoff_import_file **pp; - - /* We start c at 1 because the first entry in the import list is - reserved for the library search path. */ - for (pp = &xcoff_hash_table (info)->imports, c = 1; - *pp != NULL; - pp = &(*pp)->next, ++c) - { - if (strcmp ((*pp)->path, imppath) == 0 - && strcmp ((*pp)->file, impfile) == 0 - && strcmp ((*pp)->member, impmember) == 0) - break; - } - - if (*pp == NULL) - { - struct xcoff_import_file *n; - - n = ((struct xcoff_import_file *) - bfd_alloc (output_bfd, sizeof (struct xcoff_import_file))); - if (n == NULL) - return false; - n->next = NULL; - n->path = imppath; - n->file = impfile; - n->member = impmember; - *pp = n; - } - - h->ldsym->l_ifile = c; - } - - return true; -} - -/* Export a symbol. */ - -boolean -bfd_xcoff_export_symbol (output_bfd, info, harg, syscall) - bfd *output_bfd; - struct bfd_link_info *info; - struct bfd_link_hash_entry *harg; - boolean syscall; -{ - struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h->flags |= XCOFF_EXPORT; - - /* FIXME: I'm not at all sure what syscall is supposed to mean, so - I'm just going to ignore it until somebody explains it. */ - - /* See if this is a function descriptor. It may be one even though - it is not so marked. */ - if ((h->flags & XCOFF_DESCRIPTOR) == 0 - && h->root.root.string[0] != '.') - { - char *fnname; - struct xcoff_link_hash_entry *hfn; - - fnname = (char *) bfd_malloc (strlen (h->root.root.string) + 2); - if (fnname == NULL) - return false; - fnname[0] = '.'; - strcpy (fnname + 1, h->root.root.string); - hfn = xcoff_link_hash_lookup (xcoff_hash_table (info), - fnname, false, false, true); - free (fnname); - if (hfn != NULL - && hfn->smclas == XMC_PR - && (hfn->root.type == bfd_link_hash_defined - || hfn->root.type == bfd_link_hash_defweak)) - { - h->flags |= XCOFF_DESCRIPTOR; - h->descriptor = hfn; - hfn->descriptor = h; - } - } - - /* Make sure we don't garbage collect this symbol. */ - if (! xcoff_mark_symbol (info, h)) - return false; - - /* If this is a function descriptor, make sure we don't garbage - collect the associated function code. We normally don't have to - worry about this, because the descriptor will be attached to a - section with relocs, but if we are creating the descriptor - ourselves those relocs will not be visible to the mark code. */ - if ((h->flags & XCOFF_DESCRIPTOR) != 0) - { - if (! xcoff_mark_symbol (info, h->descriptor)) - return false; - } - - return true; -} - -/* Count a reloc against a symbol. This is called for relocs - generated by the linker script, typically for global constructors - and destructors. */ - -boolean -bfd_xcoff_link_count_reloc (output_bfd, info, name) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; -{ - struct xcoff_link_hash_entry *h; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h = ((struct xcoff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, name, false, false, - false)); - if (h == NULL) - { - (*_bfd_error_handler) ("%s: no such symbol", name); - bfd_set_error (bfd_error_no_symbols); - return false; - } - - h->flags |= XCOFF_REF_REGULAR | XCOFF_LDREL; - ++xcoff_hash_table (info)->ldrel_count; - - /* Mark the symbol to avoid garbage collection. */ - if (! xcoff_mark_symbol (info, h)) - return false; - - return true; -} - -/* This function is called for each symbol to which the linker script - assigns a value. */ - -boolean -bfd_xcoff_record_link_assignment (output_bfd, info, name) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; -{ - struct xcoff_link_hash_entry *h; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true, true, - false); - if (h == NULL) - return false; - - h->flags |= XCOFF_DEF_REGULAR; - - return true; -} - -/* This structure is used to pass information through - xcoff_link_hash_traverse. */ - -struct xcoff_loader_info -{ - /* Set if a problem occurred. */ - boolean failed; - /* Output BFD. */ - bfd *output_bfd; - /* Link information structure. */ - struct bfd_link_info *info; - /* Whether all defined symbols should be exported. */ - boolean export_defineds; - /* Number of ldsym structures. */ - size_t ldsym_count; - /* Size of string table. */ - size_t string_size; - /* String table. */ - bfd_byte *strings; - /* Allocated size of string table. */ - size_t string_alc; -}; - -/* Build the .loader section. This is called by the XCOFF linker - emulation before_allocation routine. We must set the size of the - .loader section before the linker lays out the output file. - LIBPATH is the library path to search for shared objects; this is - normally built from the -L arguments passed to the linker. ENTRY - is the name of the entry point symbol (the -e linker option). - FILE_ALIGN is the alignment to use for sections within the file - (the -H linker option). MAXSTACK is the maximum stack size (the - -bmaxstack linker option). MAXDATA is the maximum data size (the - -bmaxdata linker option). GC is whether to do garbage collection - (the -bgc linker option). MODTYPE is the module type (the - -bmodtype linker option). TEXTRO is whether the text section must - be read only (the -btextro linker option). EXPORT_DEFINEDS is - whether all defined symbols should be exported (the -unix linker - option). SPECIAL_SECTIONS is set by this routine to csects with - magic names like _end. */ - -boolean -bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, - file_align, maxstack, maxdata, gc, - modtype, textro, export_defineds, - special_sections) - bfd *output_bfd; - struct bfd_link_info *info; - const char *libpath; - const char *entry; - unsigned long file_align; - unsigned long maxstack; - unsigned long maxdata; - boolean gc; - int modtype; - boolean textro; - boolean export_defineds; - asection **special_sections; -{ - struct xcoff_link_hash_entry *hentry; - asection *lsec; - struct xcoff_loader_info ldinfo; - int i; - size_t impsize, impcount; - struct xcoff_import_file *fl; - struct internal_ldhdr *ldhdr; - bfd_size_type stoff; - register char *out; - asection *sec; - bfd *sub; - struct bfd_strtab_hash *debug_strtab; - bfd_byte *debug_contents = NULL; - - if (! XCOFF_XVECP (output_bfd->xvec)) - { - for (i = 0; i < 6; i++) - special_sections[i] = NULL; - return true; - } - - ldinfo.failed = false; - ldinfo.output_bfd = output_bfd; - ldinfo.info = info; - ldinfo.export_defineds = export_defineds; - ldinfo.ldsym_count = 0; - ldinfo.string_size = 0; - ldinfo.strings = NULL; - ldinfo.string_alc = 0; - - xcoff_data (output_bfd)->maxstack = maxstack; - xcoff_data (output_bfd)->maxdata = maxdata; - xcoff_data (output_bfd)->modtype = modtype; - - xcoff_hash_table (info)->file_align = file_align; - xcoff_hash_table (info)->textro = textro; - - hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry, - false, false, true); - if (hentry != NULL) - hentry->flags |= XCOFF_ENTRY; - - /* Garbage collect unused sections. */ - if (info->relocateable - || ! gc - || hentry == NULL - || (hentry->root.type != bfd_link_hash_defined - && hentry->root.type != bfd_link_hash_defweak)) - { - gc = false; - xcoff_hash_table (info)->gc = false; - - /* We still need to call xcoff_mark, in order to set ldrel_count - correctly. */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - for (o = sub->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, o)) - goto error_return; - } - } - } - } - else - { - if (! xcoff_mark (info, hentry->root.u.def.section)) - goto error_return; - xcoff_sweep (info); - xcoff_hash_table (info)->gc = true; - } - - /* Return special sections to the caller. */ - for (i = 0; i < 6; i++) - { - asection *sec; - - sec = xcoff_hash_table (info)->special_sections[i]; - if (sec != NULL - && gc - && (sec->flags & SEC_MARK) == 0) - sec = NULL; - special_sections[i] = sec; - } - - if (info->input_bfds == NULL) - { - /* I'm not sure what to do in this bizarre case. */ - return true; - } - - xcoff_link_hash_traverse (xcoff_hash_table (info), xcoff_build_ldsyms, - (PTR) &ldinfo); - if (ldinfo.failed) - goto error_return; - - /* Work out the size of the import file names. Each import file ID - consists of three null terminated strings: the path, the file - name, and the archive member name. The first entry in the list - of names is the path to use to find objects, which the linker has - passed in as the libpath argument. For some reason, the path - entry in the other import file names appears to always be empty. */ - impsize = strlen (libpath) + 3; - impcount = 1; - for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next) - { - ++impcount; - impsize += (strlen (fl->path) - + strlen (fl->file) - + strlen (fl->member) - + 3); - } - - /* Set up the .loader section header. */ - ldhdr = &xcoff_hash_table (info)->ldhdr; - ldhdr->l_version = 1; - ldhdr->l_nsyms = ldinfo.ldsym_count; - ldhdr->l_nreloc = xcoff_hash_table (info)->ldrel_count; - ldhdr->l_istlen = impsize; - ldhdr->l_nimpid = impcount; - ldhdr->l_impoff = (LDHDRSZ - + ldhdr->l_nsyms * LDSYMSZ - + ldhdr->l_nreloc * LDRELSZ); - ldhdr->l_stlen = ldinfo.string_size; - stoff = ldhdr->l_impoff + impsize; - if (ldinfo.string_size == 0) - ldhdr->l_stoff = 0; - else - ldhdr->l_stoff = stoff; - - /* We now know the final size of the .loader section. Allocate - space for it. */ - lsec = xcoff_hash_table (info)->loader_section; - lsec->_raw_size = stoff + ldhdr->l_stlen; - lsec->contents = (bfd_byte *) bfd_zalloc (output_bfd, lsec->_raw_size); - if (lsec->contents == NULL) - goto error_return; - - /* Set up the header. */ - xcoff_swap_ldhdr_out (output_bfd, ldhdr, - (struct external_ldhdr *) lsec->contents); - - /* Set up the import file names. */ - out = (char *) lsec->contents + ldhdr->l_impoff; - strcpy (out, libpath); - out += strlen (libpath) + 1; - *out++ = '\0'; - *out++ = '\0'; - for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next) - { - register const char *s; - - s = fl->path; - while ((*out++ = *s++) != '\0') - ; - s = fl->file; - while ((*out++ = *s++) != '\0') - ; - s = fl->member; - while ((*out++ = *s++) != '\0') - ; - } - - BFD_ASSERT ((bfd_size_type) ((bfd_byte *) out - lsec->contents) == stoff); - - /* Set up the symbol string table. */ - if (ldinfo.string_size > 0) - { - memcpy (out, ldinfo.strings, ldinfo.string_size); - free (ldinfo.strings); - ldinfo.strings = NULL; - } - - /* We can't set up the symbol table or the relocs yet, because we - don't yet know the final position of the various sections. The - .loader symbols are written out when the corresponding normal - symbols are written out in xcoff_link_input_bfd or - xcoff_write_global_symbol. The .loader relocs are written out - when the corresponding normal relocs are handled in - xcoff_link_input_bfd. */ - - /* Allocate space for the magic sections. */ - sec = xcoff_hash_table (info)->linkage_section; - if (sec->_raw_size > 0) - { - sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); - if (sec->contents == NULL) - goto error_return; - } - sec = xcoff_hash_table (info)->toc_section; - if (sec->_raw_size > 0) - { - sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); - if (sec->contents == NULL) - goto error_return; - } - sec = xcoff_hash_table (info)->descriptor_section; - if (sec->_raw_size > 0) - { - sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); - if (sec->contents == NULL) - goto error_return; - } - - /* Now that we've done garbage collection, figure out the contents - of the .debug section. */ - debug_strtab = xcoff_hash_table (info)->debug_strtab; - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *subdeb; - bfd_size_type symcount; - unsigned long *debug_index; - asection **csectpp; - bfd_byte *esym, *esymend; - bfd_size_type symesz; - - if (sub->xvec != info->hash->creator) - continue; - subdeb = bfd_get_section_by_name (sub, ".debug"); - if (subdeb == NULL || subdeb->_raw_size == 0) - continue; - - if (info->strip == strip_all - || info->strip == strip_debugger - || info->discard == discard_all) - { - subdeb->_raw_size = 0; - continue; - } - - if (! _bfd_coff_get_external_symbols (sub)) - goto error_return; - - symcount = obj_raw_syment_count (sub); - debug_index = ((unsigned long *) - bfd_zalloc (sub, symcount * sizeof (unsigned long))); - if (debug_index == NULL) - goto error_return; - xcoff_data (sub)->debug_indices = debug_index; - - /* Grab the contents of the .debug section. We use malloc and - copy the neams into the debug stringtab, rather than - bfd_alloc, because I expect that, when linking many files - together, many of the strings will be the same. Storing the - strings in the hash table should save space in this case. */ - debug_contents = (bfd_byte *) bfd_malloc (subdeb->_raw_size); - if (debug_contents == NULL) - goto error_return; - if (! bfd_get_section_contents (sub, subdeb, (PTR) debug_contents, - (file_ptr) 0, subdeb->_raw_size)) - goto error_return; - - csectpp = xcoff_data (sub)->csects; - - symesz = bfd_coff_symesz (sub); - esym = (bfd_byte *) obj_coff_external_syms (sub); - esymend = esym + symcount * symesz; - while (esym < esymend) - { - struct internal_syment sym; - - bfd_coff_swap_sym_in (sub, (PTR) esym, (PTR) &sym); - - *debug_index = (unsigned long) -1; - - if (sym._n._n_n._n_zeroes == 0 - && *csectpp != NULL - && (! gc - || ((*csectpp)->flags & SEC_MARK) != 0 - || *csectpp == bfd_abs_section_ptr) - && bfd_coff_symname_in_debug (sub, &sym)) - { - char *name; - bfd_size_type indx; - - name = (char *) debug_contents + sym._n._n_n._n_offset; - indx = _bfd_stringtab_add (debug_strtab, name, true, true); - if (indx == (bfd_size_type) -1) - goto error_return; - *debug_index = indx; - } - - esym += (sym.n_numaux + 1) * symesz; - csectpp += sym.n_numaux + 1; - debug_index += sym.n_numaux + 1; - } - - free (debug_contents); - debug_contents = NULL; - - /* Clear the size of subdeb, so that it is not included directly - in the output file. */ - subdeb->_raw_size = 0; - - if (! info->keep_memory) - { - if (! _bfd_coff_free_symbols (sub)) - goto error_return; - } - } - - xcoff_hash_table (info)->debug_section->_raw_size = - _bfd_stringtab_size (debug_strtab); - - return true; - - error_return: - if (ldinfo.strings != NULL) - free (ldinfo.strings); - if (debug_contents != NULL) - free (debug_contents); - return false; -} - -/* Add a symbol to the .loader symbols, if necessary. */ - -static boolean -xcoff_build_ldsyms (h, p) - struct xcoff_link_hash_entry *h; - PTR p; -{ - struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p; - size_t len; - - /* If all defined symbols should be exported, mark them now. */ - if (ldinfo->export_defineds - && (h->flags & XCOFF_DEF_REGULAR) != 0) - h->flags |= XCOFF_EXPORT; - - /* We don't want to garbage collect symbols which are not defined in - XCOFF files. This is a convenient place to mark them. */ - if (xcoff_hash_table (ldinfo->info)->gc - && (h->flags & XCOFF_MARK) == 0 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && (h->root.u.def.section->owner == NULL - || (h->root.u.def.section->owner->xvec - != ldinfo->info->hash->creator))) - h->flags |= XCOFF_MARK; - - /* If this symbol is called and defined in a dynamic object, or not - defined at all when building a shared object, or imported, then - we need to set up global linkage code for it. (Unless we did - garbage collection and we didn't need this symbol.) */ - if ((h->flags & XCOFF_CALLED) != 0 - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && h->root.root.string[0] == '.' - && h->descriptor != NULL - && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0 - || ldinfo->info->shared - || ((h->descriptor->flags & XCOFF_IMPORT) != 0 - && (h->descriptor->flags & XCOFF_DEF_REGULAR) == 0)) - && (! xcoff_hash_table (ldinfo->info)->gc - || (h->flags & XCOFF_MARK) != 0)) - { - asection *sec; - struct xcoff_link_hash_entry *hds; - - sec = xcoff_hash_table (ldinfo->info)->linkage_section; - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = sec; - h->root.u.def.value = sec->_raw_size; - h->smclas = XMC_GL; - h->flags |= XCOFF_DEF_REGULAR; - sec->_raw_size += XCOFF_GLINK_SIZE; - - /* The global linkage code requires a TOC entry for the - descriptor. */ - hds = h->descriptor; - BFD_ASSERT ((hds->root.type == bfd_link_hash_undefined - || hds->root.type == bfd_link_hash_undefweak) - && (hds->flags & XCOFF_DEF_REGULAR) == 0); - hds->flags |= XCOFF_MARK; - if (hds->toc_section == NULL) - { - hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section; - hds->u.toc_offset = hds->toc_section->_raw_size; - hds->toc_section->_raw_size += 4; - ++xcoff_hash_table (ldinfo->info)->ldrel_count; - ++hds->toc_section->reloc_count; - hds->indx = -2; - hds->flags |= XCOFF_SET_TOC | XCOFF_LDREL; - - /* We need to call xcoff_build_ldsyms recursively here, - because we may already have passed hds on the traversal. */ - xcoff_build_ldsyms (hds, p); - } - } - - /* If this symbol is exported, but not defined, we need to try to - define it. */ - if ((h->flags & XCOFF_EXPORT) != 0 - && (h->flags & XCOFF_IMPORT) == 0 - && (h->flags & XCOFF_DEF_REGULAR) == 0 - && (h->flags & XCOFF_DEF_DYNAMIC) == 0 - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak)) - { - if ((h->flags & XCOFF_DESCRIPTOR) != 0 - && (h->descriptor->root.type == bfd_link_hash_defined - || h->descriptor->root.type == bfd_link_hash_defweak)) - { - asection *sec; - - /* This is an undefined function descriptor associated with - a defined entry point. We can build up a function - descriptor ourselves. Believe it or not, the AIX linker - actually does this, and there are cases where we need to - do it as well. */ - sec = xcoff_hash_table (ldinfo->info)->descriptor_section; - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = sec; - h->root.u.def.value = sec->_raw_size; - h->smclas = XMC_DS; - h->flags |= XCOFF_DEF_REGULAR; - sec->_raw_size += 12; - - /* A function descriptor uses two relocs: one for the - associated code, and one for the TOC address. */ - xcoff_hash_table (ldinfo->info)->ldrel_count += 2; - sec->reloc_count += 2; - - /* We handle writing out the contents of the descriptor in - xcoff_write_global_symbol. */ - } - else - { - (*_bfd_error_handler) - ("attempt to export undefined symbol `%s'", - h->root.root.string); - ldinfo->failed = true; - bfd_set_error (bfd_error_invalid_operation); - return false; - } - } - - /* If this is still a common symbol, and it wasn't garbage - collected, we need to actually allocate space for it in the .bss - section. */ - if (h->root.type == bfd_link_hash_common - && (! xcoff_hash_table (ldinfo->info)->gc - || (h->flags & XCOFF_MARK) != 0) - && h->root.u.c.p->section->_raw_size == 0) - { - BFD_ASSERT (bfd_is_com_section (h->root.u.c.p->section)); - h->root.u.c.p->section->_raw_size = h->root.u.c.size; - } - - /* We need to add a symbol to the .loader section if it is mentioned - in a reloc which we are copying to the .loader section and it was - not defined or common, or if it is the entry point, or if it is - being exported. */ - - if (((h->flags & XCOFF_LDREL) == 0 - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common) - && (h->flags & XCOFF_ENTRY) == 0 - && (h->flags & XCOFF_EXPORT) == 0) - { - h->ldsym = NULL; - return true; - } - - /* We don't need to add this symbol if we did garbage collection and - we did not mark this symbol. */ - if (xcoff_hash_table (ldinfo->info)->gc - && (h->flags & XCOFF_MARK) == 0) - { - h->ldsym = NULL; - return true; - } - - /* We may have already processed this symbol due to the recursive - call above. */ - if ((h->flags & XCOFF_BUILT_LDSYM) != 0) - return true; - - /* We need to add this symbol to the .loader symbols. */ - - /* h->ldsym will already have been allocated for an explicitly - imported symbol. */ - if (h->ldsym == NULL) - { - h->ldsym = ((struct internal_ldsym *) - bfd_zalloc (ldinfo->output_bfd, - sizeof (struct internal_ldsym))); - if (h->ldsym == NULL) - { - ldinfo->failed = true; - return false; - } - } - - /* The first 3 symbol table indices are reserved to indicate the - sections. */ - h->ldindx = ldinfo->ldsym_count + 3; - - ++ldinfo->ldsym_count; - - len = strlen (h->root.root.string); - if (len <= SYMNMLEN) - strncpy (h->ldsym->_l._l_name, h->root.root.string, SYMNMLEN); - else - { - if (ldinfo->string_size + len + 3 > ldinfo->string_alc) - { - size_t newalc; - bfd_byte *newstrings; - - newalc = ldinfo->string_alc * 2; - if (newalc == 0) - newalc = 32; - while (ldinfo->string_size + len + 3 > newalc) - newalc *= 2; - - newstrings = ((bfd_byte *) - bfd_realloc ((PTR) ldinfo->strings, newalc)); - if (newstrings == NULL) - { - ldinfo->failed = true; - return false; - } - ldinfo->string_alc = newalc; - ldinfo->strings = newstrings; - } - - bfd_put_16 (ldinfo->output_bfd, len + 1, - ldinfo->strings + ldinfo->string_size); - strcpy (ldinfo->strings + ldinfo->string_size + 2, h->root.root.string); - h->ldsym->_l._l_l._l_zeroes = 0; - h->ldsym->_l._l_l._l_offset = ldinfo->string_size + 2; - ldinfo->string_size += len + 3; - } - - h->flags |= XCOFF_BUILT_LDSYM; - - return true; -} - -/* Do the final link step. */ - -boolean -_bfd_xcoff_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz; - struct xcoff_final_link_info finfo; - asection *o; - struct bfd_link_order *p; - size_t max_contents_size; - size_t max_sym_count; - size_t max_lineno_count; - size_t max_reloc_count; - size_t max_output_reloc_count; - file_ptr rel_filepos; - unsigned int relsz; - file_ptr line_filepos; - unsigned int linesz; - bfd *sub; - bfd_byte *external_relocs = NULL; - char strbuf[STRING_SIZE_SIZE]; - - if (info->shared) - abfd->flags |= DYNAMIC; - - symesz = bfd_coff_symesz (abfd); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.strtab = NULL; - finfo.section_info = NULL; - finfo.last_file_index = -1; - finfo.toc_symindx = -1; - finfo.internal_syms = NULL; - finfo.sym_indices = NULL; - finfo.outsyms = NULL; - finfo.linenos = NULL; - finfo.contents = NULL; - finfo.external_relocs = NULL; - - finfo.ldsym = ((struct external_ldsym *) - (xcoff_hash_table (info)->loader_section->contents - + LDHDRSZ)); - finfo.ldrel = ((struct external_ldrel *) - (xcoff_hash_table (info)->loader_section->contents - + LDHDRSZ - + xcoff_hash_table (info)->ldhdr.l_nsyms * LDSYMSZ)); - - xcoff_data (abfd)->coff.link_info = info; - - finfo.strtab = _bfd_stringtab_init (); - if (finfo.strtab == NULL) - goto error_return; - - /* Count the line number and relocation entries required for the - output file. Determine a few maximum sizes. */ - max_contents_size = 0; - max_lineno_count = 0; - max_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - o->reloc_count = 0; - o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->strip == strip_none - || info->strip == strip_some) - o->lineno_count += sec->lineno_count; - - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->lineno_count > max_lineno_count) - max_lineno_count = sec->lineno_count; - if (coff_section_data (sec->owner, sec) != NULL - && xcoff_section_data (sec->owner, sec) != NULL - && (xcoff_section_data (sec->owner, sec)->lineno_count - > max_lineno_count)) - max_lineno_count = - xcoff_section_data (sec->owner, sec)->lineno_count; - if (sec->reloc_count > max_reloc_count) - max_reloc_count = sec->reloc_count; - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - } - } - - /* Compute the file positions for all the sections. */ - if (abfd->output_has_begun) - { - if (xcoff_hash_table (info)->file_align != 0) - abort (); - } - else - { - bfd_vma file_align; - - file_align = xcoff_hash_table (info)->file_align; - if (file_align != 0) - { - boolean saw_contents; - int indx; - asection **op; - file_ptr sofar; - - /* Insert .pad sections before every section which has - contents and is loaded, if it is preceded by some other - section which has contents and is loaded. */ - saw_contents = true; - for (op = &abfd->sections; *op != NULL; op = &(*op)->next) - { - (*op)->target_index = indx; - if (strcmp ((*op)->name, ".pad") == 0) - saw_contents = false; - else if (((*op)->flags & SEC_HAS_CONTENTS) != 0 - && ((*op)->flags & SEC_LOAD) != 0) - { - if (! saw_contents) - saw_contents = true; - else - { - asection *n, *hold; - - hold = *op; - *op = NULL; - n = bfd_make_section_anyway (abfd, ".pad"); - BFD_ASSERT (*op == n); - n->next = hold; - n->flags = SEC_HAS_CONTENTS; - n->alignment_power = 0; - saw_contents = false; - } - } - } - - /* Reset the section indices after inserting the new - sections. */ - indx = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - ++indx; - o->target_index = indx; - } - BFD_ASSERT ((unsigned int) indx == abfd->section_count); - - /* Work out appropriate sizes for the .pad sections to force - each section to land on a page boundary. This bit of - code knows what compute_section_file_positions is going - to do. */ - sofar = bfd_coff_filhsz (abfd); - sofar += bfd_coff_aoutsz (abfd); - sofar += abfd->section_count * bfd_coff_scnhsz (abfd); - for (o = abfd->sections; o != NULL; o = o->next) - if (o->reloc_count >= 0xffff || o->lineno_count >= 0xffff) - sofar += bfd_coff_scnhsz (abfd); - - for (o = abfd->sections; o != NULL; o = o->next) - { - if (strcmp (o->name, ".pad") == 0) - { - bfd_vma pageoff; - - BFD_ASSERT (o->_raw_size == 0); - pageoff = sofar & (file_align - 1); - if (pageoff != 0) - { - o->_raw_size = file_align - pageoff; - sofar += file_align - pageoff; - o->flags |= SEC_HAS_CONTENTS; - } - } - else - { - if ((o->flags & SEC_HAS_CONTENTS) != 0) - sofar += BFD_ALIGN (o->_raw_size, - 1 << o->alignment_power); - } - } - } - - bfd_coff_compute_section_file_positions (abfd); - } - - /* Allocate space for the pointers we need to keep for the relocs. */ - { - unsigned int i; - - /* We use section_count + 1, rather than section_count, because - the target_index fields are 1 based. */ - finfo.section_info = - ((struct xcoff_link_section_info *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct xcoff_link_section_info))); - if (finfo.section_info == NULL) - goto error_return; - for (i = 0; i <= abfd->section_count; i++) - { - finfo.section_info[i].relocs = NULL; - finfo.section_info[i].rel_hashes = NULL; - finfo.section_info[i].toc_rel_hashes = NULL; - } - } - - /* Set the file positions for the relocs. */ - rel_filepos = obj_relocbase (abfd); - relsz = bfd_coff_relsz (abfd); - max_output_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->reloc_count == 0) - o->rel_filepos = 0; - else - { - o->flags |= SEC_RELOC; - o->rel_filepos = rel_filepos; - rel_filepos += o->reloc_count * relsz; - - /* We don't know the indices of global symbols until we have - written out all the local symbols. For each section in - the output file, we keep an array of pointers to hash - table entries. Each entry in the array corresponds to a - reloc. When we find a reloc against a global symbol, we - set the corresponding entry in this array so that we can - fix up the symbol index after we have written out all the - local symbols. - - Because of this problem, we also keep the relocs in - memory until the end of the link. This wastes memory. - We could backpatch the file later, I suppose, although it - would be slow. */ - finfo.section_info[o->target_index].relocs = - ((struct internal_reloc *) - bfd_malloc (o->reloc_count * sizeof (struct internal_reloc))); - finfo.section_info[o->target_index].rel_hashes = - ((struct xcoff_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct xcoff_link_hash_entry *))); - if (finfo.section_info[o->target_index].relocs == NULL - || finfo.section_info[o->target_index].rel_hashes == NULL) - goto error_return; - - if (o->reloc_count > max_output_reloc_count) - max_output_reloc_count = o->reloc_count; - } - } - - /* We now know the size of the relocs, so we can determine the file - positions of the line numbers. */ - line_filepos = rel_filepos; - finfo.line_filepos = line_filepos; - linesz = bfd_coff_linesz (abfd); - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->lineno_count == 0) - o->line_filepos = 0; - else - { - o->line_filepos = line_filepos; - line_filepos += o->lineno_count * linesz; - } - - /* Reset the reloc and lineno counts, so that we can use them to - count the number of entries we have output so far. */ - o->reloc_count = 0; - o->lineno_count = 0; - } - - obj_sym_filepos (abfd) = line_filepos; - - /* Figure out the largest number of symbols in an input BFD. Take - the opportunity to clear the output_has_begun fields of all the - input BFD's. We want at least 4 symbols, since that is the - number which xcoff_write_global_symbol may need. */ - max_sym_count = 4; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - size_t sz; - - sub->output_has_begun = false; - sz = obj_raw_syment_count (sub); - if (sz > max_sym_count) - max_sym_count = sz; - } - - /* Allocate some buffers used while linking. */ - finfo.internal_syms = ((struct internal_syment *) - bfd_malloc (max_sym_count - * sizeof (struct internal_syment))); - finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.outsyms = ((bfd_byte *) - bfd_malloc ((size_t) ((max_sym_count + 1) * symesz))); - finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count - * bfd_coff_linesz (abfd)); - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz); - if ((finfo.internal_syms == NULL && max_sym_count > 0) - || (finfo.sym_indices == NULL && max_sym_count > 0) - || finfo.outsyms == NULL - || (finfo.linenos == NULL && max_lineno_count > 0) - || (finfo.contents == NULL && max_contents_size > 0) - || (finfo.external_relocs == NULL && max_reloc_count > 0)) - goto error_return; - - obj_raw_syment_count (abfd) = 0; - xcoff_data (abfd)->toc = (bfd_vma) -1; - - /* We now know the position of everything in the file, except that - we don't know the size of the symbol table and therefore we don't - know where the string table starts. We just build the string - table in memory as we go along. We process all the relocations - for a single input file at once. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && p->u.indirect.section->owner->xvec == abfd->xvec) - { - sub = p->u.indirect.section->owner; - if (! sub->output_has_begun) - { - if (! xcoff_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! xcoff_reloc_link_order (abfd, &finfo, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* Free up the buffers used by xcoff_link_input_bfd. */ - - if (finfo.internal_syms != NULL) - { - free (finfo.internal_syms); - finfo.internal_syms = NULL; - } - if (finfo.sym_indices != NULL) - { - free (finfo.sym_indices); - finfo.sym_indices = NULL; - } - if (finfo.linenos != NULL) - { - free (finfo.linenos); - finfo.linenos = NULL; - } - if (finfo.contents != NULL) - { - free (finfo.contents); - finfo.contents = NULL; - } - if (finfo.external_relocs != NULL) - { - free (finfo.external_relocs); - finfo.external_relocs = NULL; - } - - /* The value of the last C_FILE symbol is supposed to be -1. Write - it out again. */ - if (finfo.last_file_index != -1) - { - finfo.last_file.n_value = -1; - bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, - (PTR) finfo.outsyms); - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + finfo.last_file_index * symesz), - SEEK_SET) != 0 - || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz) - goto error_return; - } - - /* Write out all the global symbols which do not come from XCOFF - input files. */ - xcoff_link_hash_traverse (xcoff_hash_table (info), - xcoff_write_global_symbol, - (PTR) &finfo); - - if (finfo.outsyms != NULL) - { - free (finfo.outsyms); - finfo.outsyms = NULL; - } - - /* Now that we have written out all the global symbols, we know the - symbol indices to use for relocs against them, and we can finally - write out the relocs. */ - external_relocs = (bfd_byte *) malloc (max_output_reloc_count * relsz); - if (external_relocs == NULL && max_output_reloc_count != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *irel; - struct internal_reloc *irelend; - struct xcoff_link_hash_entry **rel_hash; - struct xcoff_toc_rel_hash *toc_rel_hash; - bfd_byte *erel; - - if (o->reloc_count == 0) - continue; - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - rel_hash = finfo.section_info[o->target_index].rel_hashes; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - { - if (*rel_hash != NULL) - { - if ((*rel_hash)->indx < 0) - { - if (! ((*info->callbacks->unattached_reloc) - (info, (*rel_hash)->root.root.string, - (bfd *) NULL, o, irel->r_vaddr))) - goto error_return; - (*rel_hash)->indx = 0; - } - irel->r_symndx = (*rel_hash)->indx; - } - } - - for (toc_rel_hash = finfo.section_info[o->target_index].toc_rel_hashes; - toc_rel_hash != NULL; - toc_rel_hash = toc_rel_hash->next) - { - if (toc_rel_hash->h->u.toc_indx < 0) - { - if (! ((*info->callbacks->unattached_reloc) - (info, toc_rel_hash->h->root.root.string, - (bfd *) NULL, o, toc_rel_hash->rel->r_vaddr))) - goto error_return; - toc_rel_hash->h->u.toc_indx = 0; - } - toc_rel_hash->rel->r_symndx = toc_rel_hash->h->u.toc_indx; - } - - /* XCOFF requires that the relocs be sorted by address. We tend - to produce them in the order in which their containing csects - appear in the symbol table, which is not necessarily by - address. So we sort them here. There may be a better way to - do this. */ - qsort ((PTR) finfo.section_info[o->target_index].relocs, - o->reloc_count, sizeof (struct internal_reloc), - xcoff_sort_relocs); - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - erel = external_relocs; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); - - if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || bfd_write ((PTR) external_relocs, relsz, o->reloc_count, - abfd) != relsz * o->reloc_count) - goto error_return; - } - - if (external_relocs != NULL) - { - free (external_relocs); - external_relocs = NULL; - } - - /* Free up the section information. */ - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - finfo.section_info = NULL; - } - - /* Write out the loader section contents. */ - BFD_ASSERT ((bfd_byte *) finfo.ldrel - == (xcoff_hash_table (info)->loader_section->contents - + xcoff_hash_table (info)->ldhdr.l_impoff)); - o = xcoff_hash_table (info)->loader_section; - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, o->output_offset, - o->_raw_size)) - goto error_return; - - /* Write out the magic sections. */ - o = xcoff_hash_table (info)->linkage_section; - if (o->_raw_size > 0 - && ! bfd_set_section_contents (abfd, o->output_section, o->contents, - o->output_offset, o->_raw_size)) - goto error_return; - o = xcoff_hash_table (info)->toc_section; - if (o->_raw_size > 0 - && ! bfd_set_section_contents (abfd, o->output_section, o->contents, - o->output_offset, o->_raw_size)) - goto error_return; - o = xcoff_hash_table (info)->descriptor_section; - if (o->_raw_size > 0 - && ! bfd_set_section_contents (abfd, o->output_section, o->contents, - o->output_offset, o->_raw_size)) - goto error_return; - - /* Write out the string table. */ - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * symesz), - SEEK_SET) != 0) - goto error_return; - bfd_h_put_32 (abfd, - _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, - (bfd_byte *) strbuf); - if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) - goto error_return; - if (! _bfd_stringtab_emit (abfd, finfo.strtab)) - goto error_return; - - _bfd_stringtab_free (finfo.strtab); - - /* Write out the debugging string table. */ - o = xcoff_hash_table (info)->debug_section; - if (o != NULL) - { - struct bfd_strtab_hash *debug_strtab; - - debug_strtab = xcoff_hash_table (info)->debug_strtab; - BFD_ASSERT (o->output_section->_raw_size - o->output_offset - >= _bfd_stringtab_size (debug_strtab)); - if (bfd_seek (abfd, - o->output_section->filepos + o->output_offset, - SEEK_SET) != 0) - goto error_return; - if (! _bfd_stringtab_emit (abfd, debug_strtab)) - goto error_return; - } - - /* Setting bfd_get_symcount to 0 will cause write_object_contents to - not try to write out the symbols. */ - bfd_get_symcount (abfd) = 0; - - return true; - - error_return: - if (finfo.strtab != NULL) - _bfd_stringtab_free (finfo.strtab); - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - } - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.sym_indices != NULL) - free (finfo.sym_indices); - if (finfo.outsyms != NULL) - free (finfo.outsyms); - if (finfo.linenos != NULL) - free (finfo.linenos); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (external_relocs != NULL) - free (external_relocs); - return false; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. */ - -static boolean -xcoff_link_input_bfd (finfo, input_bfd) - struct xcoff_final_link_info *finfo; - bfd *input_bfd; -{ - bfd *output_bfd; - const char *strings; - bfd_size_type syment_base; - unsigned int n_tmask; - unsigned int n_btshft; - boolean copy, hash; - bfd_size_type isymesz; - bfd_size_type osymesz; - bfd_size_type linesz; - bfd_byte *esym; - bfd_byte *esym_end; - struct xcoff_link_hash_entry **sym_hash; - struct internal_syment *isymp; - asection **csectpp; - unsigned long *debug_index; - long *indexp; - unsigned long output_index; - bfd_byte *outsym; - unsigned int incls; - asection *oline; - boolean keep_syms; - asection *o; - - /* We can just skip DYNAMIC files, unless this is a static link. */ - if ((input_bfd->flags & DYNAMIC) != 0 - && ! finfo->info->static_link) - return true; - - /* Move all the symbols to the output file. */ - - output_bfd = finfo->output_bfd; - strings = NULL; - syment_base = obj_raw_syment_count (output_bfd); - isymesz = bfd_coff_symesz (input_bfd); - osymesz = bfd_coff_symesz (output_bfd); - linesz = bfd_coff_linesz (input_bfd); - BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd)); - - n_tmask = coff_data (input_bfd)->local_n_tmask; - n_btshft = coff_data (input_bfd)->local_n_btshft; - - /* Define macros so that ISFCN, et. al., macros work correctly. */ -#define N_TMASK n_tmask -#define N_BTSHFT n_btshft - - copy = false; - if (! finfo->info->keep_memory) - copy = true; - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - - if (! _bfd_coff_get_external_symbols (input_bfd)) - return false; - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - sym_hash = obj_xcoff_sym_hashes (input_bfd); - csectpp = xcoff_data (input_bfd)->csects; - debug_index = xcoff_data (input_bfd)->debug_indices; - isymp = finfo->internal_syms; - indexp = finfo->sym_indices; - output_index = syment_base; - outsym = finfo->outsyms; - incls = 0; - oline = NULL; - - while (esym < esym_end) - { - struct internal_syment isym; - union internal_auxent aux; - int smtyp = 0; - boolean skip; - boolean require; - int add; - - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); - - /* If this is a C_EXT or C_HIDEXT symbol, we need the csect - information. */ - if (isymp->n_sclass == C_EXT || isymp->n_sclass == C_HIDEXT) - { - BFD_ASSERT (isymp->n_numaux > 0); - bfd_coff_swap_aux_in (input_bfd, - (PTR) (esym + isymesz * isymp->n_numaux), - isymp->n_type, isymp->n_sclass, - isymp->n_numaux - 1, isymp->n_numaux, - (PTR) &aux); - smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp); - } - - /* Make a copy of *isymp so that the relocate_section function - always sees the original values. This is more reliable than - always recomputing the symbol value even if we are stripping - the symbol. */ - isym = *isymp; - - /* If this symbol is in the .loader section, swap out the - .loader symbol information. If this is an external symbol - reference to a defined symbol, though, then wait until we get - to the definition. */ - if (isym.n_sclass == C_EXT - && *sym_hash != NULL - && (*sym_hash)->ldsym != NULL - && (smtyp != XTY_ER - || (*sym_hash)->root.type == bfd_link_hash_undefined)) - { - struct xcoff_link_hash_entry *h; - struct internal_ldsym *ldsym; - - h = *sym_hash; - ldsym = h->ldsym; - if (isym.n_scnum > 0) - { - ldsym->l_scnum = (*csectpp)->output_section->target_index; - ldsym->l_value = (isym.n_value - + (*csectpp)->output_section->vma - + (*csectpp)->output_offset - - (*csectpp)->vma); - } - else - { - ldsym->l_scnum = isym.n_scnum; - ldsym->l_value = isym.n_value; - } - - ldsym->l_smtype = smtyp; - if (((h->flags & XCOFF_DEF_REGULAR) == 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_IMPORT) != 0) - ldsym->l_smtype |= L_IMPORT; - if (((h->flags & XCOFF_DEF_REGULAR) != 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_EXPORT) != 0) - ldsym->l_smtype |= L_EXPORT; - if ((h->flags & XCOFF_ENTRY) != 0) - ldsym->l_smtype |= L_ENTRY; - - ldsym->l_smclas = aux.x_csect.x_smclas; - - if (ldsym->l_ifile == (bfd_size_type) -1) - ldsym->l_ifile = 0; - else if (ldsym->l_ifile == 0) - { - if ((ldsym->l_smtype & L_IMPORT) == 0) - ldsym->l_ifile = 0; - else - { - bfd *impbfd; - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - impbfd = h->root.u.def.section->owner; - else if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - impbfd = h->root.u.undef.abfd; - else - impbfd = NULL; - - if (impbfd == NULL) - ldsym->l_ifile = 0; - else - { - BFD_ASSERT (impbfd->xvec == finfo->output_bfd->xvec); - ldsym->l_ifile = xcoff_data (impbfd)->import_file_id; - } - } - } - - ldsym->l_parm = 0; - - BFD_ASSERT (h->ldindx >= 0); - BFD_ASSERT (LDSYMSZ == sizeof (struct external_ldsym)); - xcoff_swap_ldsym_out (finfo->output_bfd, ldsym, - finfo->ldsym + h->ldindx - 3); - h->ldsym = NULL; - - /* Fill in snentry now that we know the target_index. */ - if ((h->flags & XCOFF_ENTRY) != 0 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - xcoff_data (output_bfd)->snentry = - h->root.u.def.section->output_section->target_index; - } - - *indexp = -1; - - skip = false; - require = false; - add = 1 + isym.n_numaux; - - /* If we are skipping this csect, we want to skip this symbol. */ - if (*csectpp == NULL) - skip = true; - - /* If we garbage collected this csect, we want to skip this - symbol. */ - if (! skip - && xcoff_hash_table (finfo->info)->gc - && ((*csectpp)->flags & SEC_MARK) == 0 - && *csectpp != bfd_abs_section_ptr) - skip = true; - - /* An XCOFF linker always skips C_STAT symbols. */ - if (! skip - && isymp->n_sclass == C_STAT) - skip = true; - - /* We skip all but the first TOC anchor. */ - if (! skip - && isymp->n_sclass == C_HIDEXT - && aux.x_csect.x_smclas == XMC_TC0) - { - if (finfo->toc_symindx != -1) - skip = true; - else - { - bfd_vma tocval, tocend; - - tocval = ((*csectpp)->output_section->vma - + (*csectpp)->output_offset - + isym.n_value - - (*csectpp)->vma); - /* We want to find out if tocval is a good value to use - as the TOC anchor--that is, whether we can access all - of the TOC using a 16 bit offset from tocval. This - test assumes that the TOC comes at the end of the - output section, as it does in the default linker - script. If the TOC anchor is too far into the .toc - section, the relocation routine will report - overflows. */ - tocend = ((*csectpp)->output_section->vma - + (*csectpp)->output_section->_raw_size); - if (tocval + 0x8000 < tocend) - { - bfd_vma tocadd; - - tocadd = tocend - (tocval + 0x8000); - tocval += tocadd; - isym.n_value += tocadd; - } - - finfo->toc_symindx = output_index; - xcoff_data (finfo->output_bfd)->toc = tocval; - xcoff_data (finfo->output_bfd)->sntoc = - (*csectpp)->output_section->target_index; - require = true; - } - } - - /* If we are stripping all symbols, we want to skip this one. */ - if (! skip - && finfo->info->strip == strip_all) - skip = true; - - /* We can skip resolved external references. */ - if (! skip - && isym.n_sclass == C_EXT - && smtyp == XTY_ER - && (*sym_hash)->root.type != bfd_link_hash_undefined) - skip = true; - - /* We can skip common symbols if they got defined somewhere - else. */ - if (! skip - && isym.n_sclass == C_EXT - && smtyp == XTY_CM - && ((*sym_hash)->root.type != bfd_link_hash_common - || (*sym_hash)->root.u.c.p->section != *csectpp) - && ((*sym_hash)->root.type != bfd_link_hash_defined - || (*sym_hash)->root.u.def.section != *csectpp)) - skip = true; - - /* Skip local symbols if we are discarding them. */ - if (! skip - && finfo->info->discard == discard_all - && isym.n_sclass != C_EXT - && (isym.n_sclass != C_HIDEXT - || smtyp != XTY_SD)) - skip = true; - - /* If we stripping debugging symbols, and this is a debugging - symbol, then skip it. */ - if (! skip - && finfo->info->strip == strip_debugger - && isym.n_scnum == N_DEBUG) - skip = true; - - /* If some symbols are stripped based on the name, work out the - name and decide whether to skip this symbol. We don't handle - this correctly for symbols whose names are in the .debug - section; to get it right we would need a new bfd_strtab_hash - function to return the string given the index. */ - if (! skip - && (finfo->info->strip == strip_some - || finfo->info->discard == discard_l) - && (debug_index == NULL || *debug_index == (unsigned long) -1)) - { - const char *name; - char buf[SYMNMLEN + 1]; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); - if (name == NULL) - return false; - - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, false, - false) == NULL)) - || (finfo->info->discard == discard_l - && (isym.n_sclass != C_EXT - && (isym.n_sclass != C_HIDEXT - || smtyp != XTY_SD)) - && strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - skip = true; - } - - /* We can not skip the first TOC anchor. */ - if (skip - && require - && finfo->info->strip != strip_all) - skip = false; - - /* We now know whether we are to skip this symbol or not. */ - if (! skip) - { - /* Adjust the symbol in order to output it. */ - - if (isym._n._n_n._n_zeroes == 0 - && isym._n._n_n._n_offset != 0) - { - /* This symbol has a long name. Enter it in the string - table we are building. If *debug_index != -1, the - name has already been entered in the .debug section. */ - if (debug_index != NULL && *debug_index != (unsigned long) -1) - isym._n._n_n._n_offset = *debug_index; - else - { - const char *name; - bfd_size_type indx; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, - (char *) NULL); - if (name == NULL) - return false; - indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy); - if (indx == (bfd_size_type) -1) - return false; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - } - - if (isym.n_sclass != C_BSTAT - && isym.n_sclass != C_ESTAT - && isym.n_sclass != C_DECL - && isym.n_scnum > 0) - { - isym.n_scnum = (*csectpp)->output_section->target_index; - isym.n_value += ((*csectpp)->output_section->vma - + (*csectpp)->output_offset - - (*csectpp)->vma); - } - - /* The value of a C_FILE symbol is the symbol index of the - next C_FILE symbol. The value of the last C_FILE symbol - is -1. We try to get this right, below, just before we - write the symbols out, but in the general case we may - have to write the symbol out twice. */ - if (isym.n_sclass == C_FILE) - { - if (finfo->last_file_index != -1 - && finfo->last_file.n_value != (long) output_index) - { - /* We must correct the value of the last C_FILE entry. */ - finfo->last_file.n_value = output_index; - if ((bfd_size_type) finfo->last_file_index >= syment_base) - { - /* The last C_FILE symbol is in this input file. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - - syment_base) - * osymesz))); - } - else - { - /* We have already written out the last C_FILE - symbol. We need to write it out again. We - borrow *outsym temporarily. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) outsym); - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + finfo->last_file_index * osymesz), - SEEK_SET) != 0 - || (bfd_write (outsym, osymesz, 1, output_bfd) - != osymesz)) - return false; - } - } - - finfo->last_file_index = output_index; - finfo->last_file = isym; - } - - /* The value of a C_BINCL or C_EINCL symbol is a file offset - into the line numbers. We update the symbol values when - we handle the line numbers. */ - if (isym.n_sclass == C_BINCL - || isym.n_sclass == C_EINCL) - { - isym.n_value = finfo->line_filepos; - ++incls; - } - - /* Output the symbol. */ - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - - *indexp = output_index; - - if (isym.n_sclass == C_EXT) - { - long indx; - struct xcoff_link_hash_entry *h; - - indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd)) - / isymesz); - h = obj_xcoff_sym_hashes (input_bfd)[indx]; - BFD_ASSERT (h != NULL); - h->indx = output_index; - } - - /* If this is a symbol in the TOC which we may have merged - (class XMC_TC), remember the symbol index of the TOC - symbol. */ - if (isym.n_sclass == C_HIDEXT - && aux.x_csect.x_smclas == XMC_TC - && *sym_hash != NULL) - { - BFD_ASSERT (((*sym_hash)->flags & XCOFF_SET_TOC) == 0); - BFD_ASSERT ((*sym_hash)->toc_section != NULL); - (*sym_hash)->u.toc_indx = output_index; - } - - output_index += add; - outsym += add * osymesz; - } - - esym += add * isymesz; - isymp += add; - csectpp += add; - sym_hash += add; - if (debug_index != NULL) - debug_index += add; - ++indexp; - for (--add; add > 0; --add) - *indexp++ = -1; - } - - /* Fix up the aux entries and the C_BSTAT symbols. This must be - done in a separate pass, because we don't know the correct symbol - indices until we have already decided which symbols we are going - to keep. */ - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - isymp = finfo->internal_syms; - indexp = finfo->sym_indices; - csectpp = xcoff_data (input_bfd)->csects; - outsym = finfo->outsyms; - while (esym < esym_end) - { - int add; - - add = 1 + isymp->n_numaux; - - if (*indexp < 0) - esym += add * isymesz; - else - { - int i; - - if (isymp->n_sclass == C_BSTAT) - { - struct internal_syment isym; - unsigned long indx; - - /* The value of a C_BSTAT symbol is the symbol table - index of the containing csect. */ - bfd_coff_swap_sym_in (output_bfd, (PTR) outsym, (PTR) &isym); - indx = isym.n_value; - if (indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - isym.n_value = 0; - else - isym.n_value = symindx; - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, - (PTR) outsym); - } - } - - esym += isymesz; - outsym += osymesz; - - for (i = 0; i < isymp->n_numaux && esym < esym_end; i++) - { - union internal_auxent aux; - - bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) &aux); - - if (isymp->n_sclass == C_FILE) - { - /* This is the file name (or some comment put in by - the compiler). If it is long, we must put it in - the string table. */ - if (aux.x_file.x_n.x_zeroes == 0 - && aux.x_file.x_n.x_offset != 0) - { - const char *filename; - bfd_size_type indx; - - BFD_ASSERT (aux.x_file.x_n.x_offset - >= STRING_SIZE_SIZE); - if (strings == NULL) - { - strings = _bfd_coff_read_string_table (input_bfd); - if (strings == NULL) - return false; - } - filename = strings + aux.x_file.x_n.x_offset; - indx = _bfd_stringtab_add (finfo->strtab, filename, - hash, copy); - if (indx == (bfd_size_type) -1) - return false; - aux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; - } - } - else if ((isymp->n_sclass == C_EXT - || isymp->n_sclass == C_HIDEXT) - && i + 1 == isymp->n_numaux) - { - /* We don't support type checking. I don't know if - anybody does. */ - aux.x_csect.x_parmhash = 0; - /* I don't think anybody uses these fields, but we'd - better clobber them just in case. */ - aux.x_csect.x_stab = 0; - aux.x_csect.x_snstab = 0; - if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_LD) - { - unsigned long indx; - - indx = aux.x_csect.x_scnlen.l; - if (indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - aux.x_sym.x_tagndx.l = 0; - else - aux.x_sym.x_tagndx.l = symindx; - } - } - } - else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) - { - unsigned long indx; - - if (ISFCN (isymp->n_type) - || ISTAG (isymp->n_sclass) - || isymp->n_sclass == C_BLOCK) - { - indx = aux.x_sym.x_fcnary.x_fcn.x_endndx.l; - if (indx > 0 - && indx < obj_raw_syment_count (input_bfd)) - { - /* We look forward through the symbol for - the index of the next symbol we are going - to include. I don't know if this is - entirely right. */ - while (finfo->sym_indices[indx] < 0 - && indx < obj_raw_syment_count (input_bfd)) - ++indx; - if (indx >= obj_raw_syment_count (input_bfd)) - indx = output_index; - else - indx = finfo->sym_indices[indx]; - aux.x_sym.x_fcnary.x_fcn.x_endndx.l = indx; - } - } - - indx = aux.x_sym.x_tagndx.l; - if (indx > 0 && indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - aux.x_sym.x_tagndx.l = 0; - else - aux.x_sym.x_tagndx.l = symindx; - } - } - - /* Copy over the line numbers, unless we are stripping - them. We do this on a symbol by symbol basis in - order to more easily handle garbage collection. */ - if ((isymp->n_sclass == C_EXT - || isymp->n_sclass == C_HIDEXT) - && i == 0 - && isymp->n_numaux > 1 - && ISFCN (isymp->n_type) - && aux.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0) - { - if (finfo->info->strip != strip_none - && finfo->info->strip != strip_some) - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0; - else - { - asection *enclosing; - unsigned int enc_count; - bfd_size_type linoff; - struct internal_lineno lin; - - o = *csectpp; - enclosing = xcoff_section_data (abfd, o)->enclosing; - enc_count = xcoff_section_data (abfd, o)->lineno_count; - if (oline != enclosing) - { - if (bfd_seek (input_bfd, - enclosing->line_filepos, - SEEK_SET) != 0 - || (bfd_read (finfo->linenos, linesz, - enc_count, input_bfd) - != linesz * enc_count)) - return false; - oline = enclosing; - } - - linoff = (aux.x_sym.x_fcnary.x_fcn.x_lnnoptr - - enclosing->line_filepos); - - bfd_coff_swap_lineno_in (input_bfd, - (PTR) (finfo->linenos + linoff), - (PTR) &lin); - if (lin.l_lnno != 0 - || ((bfd_size_type) lin.l_addr.l_symndx - != ((esym - - isymesz - - ((bfd_byte *) - obj_coff_external_syms (input_bfd))) - / isymesz))) - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0; - else - { - bfd_byte *linpend, *linp; - bfd_vma offset; - bfd_size_type count; - - lin.l_addr.l_symndx = *indexp; - bfd_coff_swap_lineno_out (output_bfd, (PTR) &lin, - (PTR) (finfo->linenos - + linoff)); - - linpend = (finfo->linenos - + enc_count * linesz); - offset = (o->output_section->vma - + o->output_offset - - o->vma); - for (linp = finfo->linenos + linoff + linesz; - linp < linpend; - linp += linesz) - { - bfd_coff_swap_lineno_in (input_bfd, (PTR) linp, - (PTR) &lin); - if (lin.l_lnno == 0) - break; - lin.l_addr.l_paddr += offset; - bfd_coff_swap_lineno_out (output_bfd, - (PTR) &lin, - (PTR) linp); - } - - count = (linp - (finfo->linenos + linoff)) / linesz; - - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = - (o->output_section->line_filepos - + o->output_section->lineno_count * linesz); - - if (bfd_seek (output_bfd, - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr, - SEEK_SET) != 0 - || (bfd_write (finfo->linenos + linoff, - linesz, count, output_bfd) - != linesz * count)) - return false; - - o->output_section->lineno_count += count; - - if (incls > 0) - { - struct internal_syment *iisp, *iispend; - long *iindp; - bfd_byte *oos; - - /* Update any C_BINCL or C_EINCL symbols - that refer to a line number in the - range we just output. */ - iisp = finfo->internal_syms; - iispend = (iisp - + obj_raw_syment_count (input_bfd)); - iindp = finfo->sym_indices; - oos = finfo->outsyms; - while (iisp < iispend) - { - if ((iisp->n_sclass == C_BINCL - || iisp->n_sclass == C_EINCL) - && ((bfd_size_type) iisp->n_value - >= enclosing->line_filepos + linoff) - && ((bfd_size_type) iisp->n_value - < (enclosing->line_filepos - + enc_count * linesz))) - { - struct internal_syment iis; - - bfd_coff_swap_sym_in (output_bfd, - (PTR) oos, - (PTR) &iis); - iis.n_value = - (iisp->n_value - - enclosing->line_filepos - - linoff - + aux.x_sym.x_fcnary.x_fcn.x_lnnoptr); - bfd_coff_swap_sym_out (output_bfd, - (PTR) &iis, - (PTR) oos); - --incls; - } - - iisp += iisp->n_numaux + 1; - iindp += iisp->n_numaux + 1; - oos += (iisp->n_numaux + 1) * osymesz; - } - } - } - } - } - - bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) outsym); - outsym += osymesz; - esym += isymesz; - } - } - - indexp += add; - isymp += add; - csectpp += add; - } - - /* If we swapped out a C_FILE symbol, guess that the next C_FILE - symbol will be the first symbol in the next input file. In the - normal case, this will save us from writing out the C_FILE symbol - again. */ - if (finfo->last_file_index != -1 - && (bfd_size_type) finfo->last_file_index >= syment_base) - { - finfo->last_file.n_value = output_index; - bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - syment_base) - * osymesz))); - } - - /* Write the modified symbols to the output file. */ - if (outsym > finfo->outsyms) - { - if (bfd_seek (output_bfd, - obj_sym_filepos (output_bfd) + syment_base * osymesz, - SEEK_SET) != 0 - || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, - output_bfd) - != (bfd_size_type) (outsym - finfo->outsyms))) - return false; - - BFD_ASSERT ((obj_raw_syment_count (output_bfd) - + (outsym - finfo->outsyms) / osymesz) - == output_index); - - obj_raw_syment_count (output_bfd) = output_index; - } - - /* Don't let the linker relocation routines discard the symbols. */ - keep_syms = obj_coff_keep_syms (input_bfd); - obj_coff_keep_syms (input_bfd) = true; - - /* Relocate the contents of each section. */ - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_byte *contents; - - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || o->_raw_size == 0 - || (o->flags & SEC_IN_MEMORY) != 0) - continue; - - /* We have set filepos correctly for the sections we created to - represent csects, so bfd_get_section_contents should work. */ - if (coff_section_data (input_bfd, o) != NULL - && coff_section_data (input_bfd, o)->contents != NULL) - contents = coff_section_data (input_bfd, o)->contents; - else - { - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; - contents = finfo->contents; - } - - if ((o->flags & SEC_RELOC) != 0) - { - int target_index; - struct internal_reloc *internal_relocs; - struct internal_reloc *irel; - bfd_vma offset; - struct internal_reloc *irelend; - struct xcoff_link_hash_entry **rel_hash; - long r_symndx; - - /* Read in the relocs. */ - target_index = o->output_section->target_index; - internal_relocs = (xcoff_read_internal_relocs - (input_bfd, o, false, finfo->external_relocs, - true, - (finfo->section_info[target_index].relocs - + o->output_section->reloc_count))); - if (internal_relocs == NULL) - return false; - - /* Call processor specific code to relocate the section - contents. */ - if (! bfd_coff_relocate_section (output_bfd, finfo->info, - input_bfd, o, - contents, - internal_relocs, - finfo->internal_syms, - xcoff_data (input_bfd)->csects)) - return false; - - offset = o->output_section->vma + o->output_offset - o->vma; - irel = internal_relocs; - irelend = irel + o->reloc_count; - rel_hash = (finfo->section_info[target_index].rel_hashes - + o->output_section->reloc_count); - for (; irel < irelend; irel++, rel_hash++) - { - struct xcoff_link_hash_entry *h = NULL; - struct internal_ldrel ldrel; - - *rel_hash = NULL; - - /* Adjust the reloc address and symbol index. */ - - irel->r_vaddr += offset; - - r_symndx = irel->r_symndx; - - if (r_symndx != -1) - { - h = obj_xcoff_sym_hashes (input_bfd)[r_symndx]; - if (h != NULL - && (irel->r_type == R_TOC - || irel->r_type == R_GL - || irel->r_type == R_TCL - || irel->r_type == R_TRL - || irel->r_type == R_TRLA)) - { - /* This is a TOC relative reloc with a symbol - attached. The symbol should be the one which - this reloc is for. We want to make this - reloc against the TOC address of the symbol, - not the symbol itself. */ - BFD_ASSERT (h->toc_section != NULL); - BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0); - if (h->u.toc_indx != -1) - irel->r_symndx = h->u.toc_indx; - else - { - struct xcoff_toc_rel_hash *n; - struct xcoff_link_section_info *si; - - n = ((struct xcoff_toc_rel_hash *) - bfd_alloc (finfo->output_bfd, - sizeof (struct xcoff_toc_rel_hash))); - if (n == NULL) - return false; - si = finfo->section_info + target_index; - n->next = si->toc_rel_hashes; - n->h = h; - n->rel = irel; - si->toc_rel_hashes = n; - } - } - else if (h != NULL) - { - /* This is a global symbol. */ - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* This symbol is being written at the end - of the file, and we do not yet know the - symbol index. We save the pointer to the - hash table entry in the rel_hash list. - We set the indx field to -2 to indicate - that this symbol must not be stripped. */ - *rel_hash = h; - h->indx = -2; - } - } - else - { - long indx; - - indx = finfo->sym_indices[r_symndx]; - - if (indx == -1) - { - struct internal_syment *is; - - /* Relocations against a TC0 TOC anchor are - automatically transformed to be against - the TOC anchor in the output file. */ - is = finfo->internal_syms + r_symndx; - if (is->n_sclass == C_HIDEXT - && is->n_numaux > 0) - { - PTR auxptr; - union internal_auxent aux; - - auxptr = ((PTR) - (((bfd_byte *) - obj_coff_external_syms (input_bfd)) - + ((r_symndx + is->n_numaux) - * isymesz))); - bfd_coff_swap_aux_in (input_bfd, auxptr, - is->n_type, is->n_sclass, - is->n_numaux - 1, - is->n_numaux, - (PTR) &aux); - if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_SD - && aux.x_csect.x_smclas == XMC_TC0) - indx = finfo->toc_symindx; - } - } - - if (indx != -1) - irel->r_symndx = indx; - else - { - struct internal_syment *is; - const char *name; - char buf[SYMNMLEN + 1]; - - /* This reloc is against a symbol we are - stripping. It would be possible to handle - this case, but I don't think it's worth it. */ - is = finfo->internal_syms + r_symndx; - - name = (_bfd_coff_internal_syment_name - (input_bfd, is, buf)); - if (name == NULL) - return false; - - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, o, - irel->r_vaddr))) - return false; - } - } - } - - switch (irel->r_type) - { - default: - if (h == NULL - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common) - break; - /* Fall through. */ - case R_POS: - case R_NEG: - case R_RL: - case R_RLA: - /* This reloc needs to be copied into the .loader - section. */ - ldrel.l_vaddr = irel->r_vaddr; - if (r_symndx == -1) - ldrel.l_symndx = -1; - else if (h == NULL - || (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common)) - { - asection *sec; - - if (h == NULL) - sec = xcoff_data (input_bfd)->csects[r_symndx]; - else if (h->root.type == bfd_link_hash_common) - sec = h->root.u.c.p->section; - else - sec = h->root.u.def.section; - sec = sec->output_section; - - if (strcmp (sec->name, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (sec->name, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (sec->name, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (input_bfd), - sec->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - } - else - { - if (h->ldindx < 0) - { - (*_bfd_error_handler) - ("%s: `%s' in loader reloc but not loader sym", - bfd_get_filename (input_bfd), - h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return false; - } - ldrel.l_symndx = h->ldindx; - } - ldrel.l_rtype = (irel->r_size << 8) | irel->r_type; - ldrel.l_rsecnm = o->output_section->target_index; - if (xcoff_hash_table (finfo->info)->textro - && strcmp (o->output_section->name, ".text") == 0) - { - (*_bfd_error_handler) - ("%s: loader reloc in read-only section %s", - bfd_get_filename (input_bfd), - bfd_get_section_name (finfo->output_bfd, - o->output_section)); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - xcoff_swap_ldrel_out (output_bfd, &ldrel, - finfo->ldrel); - BFD_ASSERT (sizeof (struct external_ldrel) == LDRELSZ); - ++finfo->ldrel; - break; - - case R_TOC: - case R_GL: - case R_TCL: - case R_TRL: - case R_TRLA: - /* We should never need a .loader reloc for a TOC - relative reloc. */ - break; - } - } - - o->output_section->reloc_count += o->reloc_count; - } - - /* Write out the modified section contents. */ - if (! bfd_set_section_contents (output_bfd, o->output_section, - contents, o->output_offset, - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) - return false; - } - - obj_coff_keep_syms (input_bfd) = keep_syms; - - if (! finfo->info->keep_memory) - { - if (! _bfd_coff_free_symbols (input_bfd)) - return false; - } - - return true; -} - -#undef N_TMASK -#undef N_BTSHFT - -/* Write out a non-XCOFF global symbol. */ - -static boolean -xcoff_write_global_symbol (h, p) - struct xcoff_link_hash_entry *h; - PTR p; -{ - struct xcoff_final_link_info *finfo = (struct xcoff_final_link_info *) p; - bfd *output_bfd; - bfd_byte *outsym; - struct internal_syment isym; - union internal_auxent aux; - - output_bfd = finfo->output_bfd; - - /* If this symbol was garbage collected, just skip it. */ - if (xcoff_hash_table (finfo->info)->gc - && (h->flags & XCOFF_MARK) == 0) - return true; - - /* If we need a .loader section entry, write it out. */ - if (h->ldsym != NULL) - { - struct internal_ldsym *ldsym; - bfd *impbfd; - - ldsym = h->ldsym; - - if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - { - ldsym->l_value = 0; - ldsym->l_scnum = N_UNDEF; - ldsym->l_smtype = XTY_ER; - impbfd = h->root.u.undef.abfd; - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - ldsym->l_value = (sec->output_section->vma - + sec->output_offset - + h->root.u.def.value); - ldsym->l_scnum = sec->output_section->target_index; - ldsym->l_smtype = XTY_SD; - impbfd = sec->owner; - } - else - abort (); - - if (((h->flags & XCOFF_DEF_REGULAR) == 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_IMPORT) != 0) - ldsym->l_smtype |= L_IMPORT; - if (((h->flags & XCOFF_DEF_REGULAR) != 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_EXPORT) != 0) - ldsym->l_smtype |= L_EXPORT; - if ((h->flags & XCOFF_ENTRY) != 0) - ldsym->l_smtype |= L_ENTRY; - - ldsym->l_smclas = h->smclas; - - if (ldsym->l_ifile == (bfd_size_type) -1) - ldsym->l_ifile = 0; - else if (ldsym->l_ifile == 0) - { - if ((ldsym->l_smtype & L_IMPORT) == 0) - ldsym->l_ifile = 0; - else if (impbfd == NULL) - ldsym->l_ifile = 0; - else - { - BFD_ASSERT (impbfd->xvec == output_bfd->xvec); - ldsym->l_ifile = xcoff_data (impbfd)->import_file_id; - } - } - - ldsym->l_parm = 0; - - BFD_ASSERT (h->ldindx >= 0); - BFD_ASSERT (LDSYMSZ == sizeof (struct external_ldsym)); - xcoff_swap_ldsym_out (output_bfd, ldsym, finfo->ldsym + h->ldindx - 3); - h->ldsym = NULL; - } - - /* If this symbol needs global linkage code, write it out. */ - if (h->root.type == bfd_link_hash_defined - && (h->root.u.def.section - == xcoff_hash_table (finfo->info)->linkage_section)) - { - bfd_byte *p; - bfd_vma tocoff; - unsigned int i; - - p = h->root.u.def.section->contents + h->root.u.def.value; - - /* The first instruction in the global linkage code loads a - specific TOC element. */ - tocoff = (h->descriptor->toc_section->output_section->vma - + h->descriptor->toc_section->output_offset - - xcoff_data (output_bfd)->toc); - if ((h->descriptor->flags & XCOFF_SET_TOC) != 0) - tocoff += h->descriptor->u.toc_offset; - bfd_put_32 (output_bfd, XCOFF_GLINK_FIRST | (tocoff & 0xffff), p); - for (i = 0, p += 4; - i < sizeof xcoff_glink_code / sizeof xcoff_glink_code[0]; - i++, p += 4) - bfd_put_32 (output_bfd, xcoff_glink_code[i], p); - } - - /* If we created a TOC entry for this symbol, write out the required - relocs. */ - if ((h->flags & XCOFF_SET_TOC) != 0) - { - asection *tocsec; - asection *osec; - int oindx; - struct internal_reloc *irel; - struct internal_ldrel ldrel; - - tocsec = h->toc_section; - osec = tocsec->output_section; - oindx = osec->target_index; - irel = finfo->section_info[oindx].relocs + osec->reloc_count; - irel->r_vaddr = (osec->vma - + tocsec->output_offset - + h->u.toc_offset); - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - h->indx = -2; - irel->r_symndx = obj_raw_syment_count (output_bfd); - } - irel->r_type = R_POS; - irel->r_size = 31; - finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; - ++osec->reloc_count; - - BFD_ASSERT (h->ldindx >= 0); - ldrel.l_vaddr = irel->r_vaddr; - ldrel.l_symndx = h->ldindx; - ldrel.l_rtype = (31 << 8) | R_POS; - ldrel.l_rsecnm = oindx; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - } - - /* If this symbol is a specially defined function descriptor, write - it out. The first word is the address of the function code - itself, the second word is the address of the TOC, and the third - word is zero. */ - if ((h->flags & XCOFF_DESCRIPTOR) != 0 - && h->root.type == bfd_link_hash_defined - && (h->root.u.def.section - == xcoff_hash_table (finfo->info)->descriptor_section)) - { - asection *sec; - asection *osec; - int oindx; - bfd_byte *p; - struct xcoff_link_hash_entry *hentry; - asection *esec; - struct internal_reloc *irel; - struct internal_ldrel ldrel; - asection *tsec; - - sec = h->root.u.def.section; - osec = sec->output_section; - oindx = osec->target_index; - p = sec->contents + h->root.u.def.value; - - hentry = h->descriptor; - BFD_ASSERT (hentry != NULL - && (hentry->root.type == bfd_link_hash_defined - || hentry->root.type == bfd_link_hash_defweak)); - esec = hentry->root.u.def.section; - bfd_put_32 (output_bfd, - (esec->output_section->vma - + esec->output_offset - + hentry->root.u.def.value), - p); - - irel = finfo->section_info[oindx].relocs + osec->reloc_count; - irel->r_vaddr = (osec->vma - + sec->output_offset - + h->root.u.def.value); - irel->r_symndx = esec->output_section->target_index; - irel->r_type = R_POS; - irel->r_size = 31; - finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; - ++osec->reloc_count; - - ldrel.l_vaddr = irel->r_vaddr; - if (strcmp (esec->output_section->name, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (esec->output_section->name, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (esec->output_section->name, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (output_bfd), - esec->output_section->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - ldrel.l_rtype = (31 << 8) | R_POS; - ldrel.l_rsecnm = oindx; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - - bfd_put_32 (output_bfd, xcoff_data (output_bfd)->toc, p + 4); - - tsec = coff_section_from_bfd_index (output_bfd, - xcoff_data (output_bfd)->sntoc); - - ++irel; - irel->r_vaddr = (osec->vma - + sec->output_offset - + h->root.u.def.value - + 4); - irel->r_symndx = tsec->output_section->target_index; - irel->r_type = R_POS; - irel->r_size = 31; - finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; - ++osec->reloc_count; - - ldrel.l_vaddr = irel->r_vaddr; - if (strcmp (tsec->output_section->name, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (tsec->output_section->name, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (tsec->output_section->name, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (output_bfd), - tsec->output_section->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - ldrel.l_rtype = (31 << 8) | R_POS; - ldrel.l_rsecnm = oindx; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - } - - if (h->indx >= 0) - return true; - - if (h->indx != -2 - && (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, false, false) - == NULL)))) - return true; - - if (h->indx != -2 - && (h->flags & (XCOFF_REF_REGULAR | XCOFF_DEF_REGULAR)) == 0) - return true; - - outsym = finfo->outsyms; - - memset (&aux, 0, sizeof aux); - - h->indx = obj_raw_syment_count (output_bfd); - - if (strlen (h->root.root.string) <= SYMNMLEN) - strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN); - else - { - boolean hash; - bfd_size_type indx; - - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash, - false); - if (indx == (bfd_size_type) -1) - return false; - isym._n._n_n._n_zeroes = 0; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - - if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - { - isym.n_value = 0; - isym.n_scnum = N_UNDEF; - isym.n_sclass = C_EXT; - aux.x_csect.x_smtyp = XTY_ER; - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - struct xcoff_link_size_list *l; - - isym.n_value = (h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset - + h->root.u.def.value); - isym.n_scnum = h->root.u.def.section->output_section->target_index; - isym.n_sclass = C_HIDEXT; - aux.x_csect.x_smtyp = XTY_SD; - - if ((h->flags & XCOFF_HAS_SIZE) != 0) - { - for (l = xcoff_hash_table (finfo->info)->size_list; - l != NULL; - l = l->next) - { - if (l->h == h) - { - aux.x_csect.x_scnlen.l = l->size; - break; - } - } - } - } - else if (h->root.type == bfd_link_hash_common) - { - isym.n_value = (h->root.u.c.p->section->output_section->vma - + h->root.u.c.p->section->output_offset); - isym.n_scnum = h->root.u.c.p->section->output_section->target_index; - isym.n_sclass = C_EXT; - aux.x_csect.x_smtyp = XTY_CM; - aux.x_csect.x_scnlen.l = h->root.u.c.size; - } - else - abort (); - - isym.n_type = T_NULL; - isym.n_numaux = 1; - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - outsym += bfd_coff_symesz (output_bfd); - - aux.x_csect.x_smclas = h->smclas; - - bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, isym.n_sclass, 0, 1, - (PTR) outsym); - outsym += bfd_coff_auxesz (output_bfd); - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - /* We just output an SD symbol. Now output an LD symbol. */ - - h->indx += 2; - - isym.n_sclass = C_EXT; - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - outsym += bfd_coff_symesz (output_bfd); - - aux.x_csect.x_smtyp = XTY_LD; - aux.x_csect.x_scnlen.l = obj_raw_syment_count (output_bfd); - - bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, C_EXT, 0, 1, - (PTR) outsym); - outsym += bfd_coff_auxesz (output_bfd); - } - - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + (obj_raw_syment_count (output_bfd) - * bfd_coff_symesz (output_bfd))), - SEEK_SET) != 0 - || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, output_bfd) - != (bfd_size_type) (outsym - finfo->outsyms))) - return false; - obj_raw_syment_count (output_bfd) += - (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd); - - return true; -} - -/* Handle a link order which is supposed to generate a reloc. */ - -static boolean -xcoff_reloc_link_order (output_bfd, finfo, output_section, link_order) - bfd *output_bfd; - struct xcoff_final_link_info *finfo; - asection *output_section; - struct bfd_link_order *link_order; -{ - reloc_howto_type *howto; - struct xcoff_link_hash_entry *h; - asection *hsec; - bfd_vma hval; - bfd_vma addend; - struct internal_reloc *irel; - struct xcoff_link_hash_entry **rel_hash_ptr; - struct internal_ldrel ldrel; - - if (link_order->type == bfd_section_reloc_link_order) - { - /* We need to somehow locate a symbol in the right section. The - symbol must either have a value of zero, or we must adjust - the addend by the value of the symbol. FIXME: Write this - when we need it. The old linker couldn't handle this anyhow. */ - abort (); - } - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - h = ((struct xcoff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, finfo->info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h == NULL) - { - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - return true; - } - - if (h->root.type == bfd_link_hash_common) - { - hsec = h->root.u.c.p->section; - hval = 0; - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - hsec = h->root.u.def.section; - hval = h->root.u.def.value; - } - else - { - hsec = NULL; - hval = 0; - } - - addend = link_order->u.reloc.p->addend; - if (hsec != NULL) - addend += (hsec->output_section->vma - + hsec->output_offset - + hval); - - if (addend != 0) - { - bfd_size_type size; - bfd_byte *buf; - bfd_reloc_status_type rstat; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == NULL) - return false; - - rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, link_order->u.reloc.p->u.name, - howto->name, addend, (bfd *) NULL, (asection *) NULL, - (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - /* Store the reloc information in the right place. It will get - swapped and written out at the end of the final_link routine. */ - - irel = (finfo->section_info[output_section->target_index].relocs - + output_section->reloc_count); - rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes - + output_section->reloc_count); - - memset (irel, 0, sizeof (struct internal_reloc)); - *rel_hash_ptr = NULL; - - irel->r_vaddr = output_section->vma + link_order->offset; - - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* Set the index to -2 to force this symbol to get written out. */ - h->indx = -2; - *rel_hash_ptr = h; - irel->r_symndx = 0; - } - - irel->r_type = howto->type; - irel->r_size = howto->bitsize - 1; - if (howto->complain_on_overflow == complain_overflow_signed) - irel->r_size |= 0x80; - - ++output_section->reloc_count; - - /* Now output the reloc to the .loader section. */ - - ldrel.l_vaddr = irel->r_vaddr; - - if (hsec != NULL) - { - const char *secname; - - secname = hsec->output_section->name; - - if (strcmp (secname, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (secname, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (secname, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (output_bfd), secname); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - } - else - { - if (h->ldindx < 0) - { - (*_bfd_error_handler) - ("%s: `%s' in loader reloc but not loader sym", - bfd_get_filename (output_bfd), - h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return false; - } - ldrel.l_symndx = h->ldindx; - } - - ldrel.l_rtype = (irel->r_size << 8) | irel->r_type; - ldrel.l_rsecnm = output_section->target_index; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - - return true; -} - -/* Sort relocs by VMA. This is called via qsort. */ - -static int -xcoff_sort_relocs (p1, p2) - const PTR p1; - const PTR p2; -{ - const struct internal_reloc *r1 = (const struct internal_reloc *) p1; - const struct internal_reloc *r2 = (const struct internal_reloc *) p2; - - if (r1->r_vaddr > r2->r_vaddr) - return 1; - else if (r1->r_vaddr < r2->r_vaddr) - return -1; - else - return 0; -} - -/* This is the relocation function for the RS/6000/POWER/PowerPC. - This is currently the only processor which uses XCOFF; I hope that - will never change. */ - -boolean -_bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd, - input_section, contents, relocs, syms, - sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct xcoff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - struct reloc_howto_struct howto; - bfd_reloc_status_type rstat; - - /* Relocation type R_REF is a special relocation type which is - merely used to prevent garbage collection from occurring for - the csect including the symbol which it references. */ - if (rel->r_type == R_REF) - continue; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - addend = 0; - } - else - { - h = obj_xcoff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - addend = - sym->n_value; - } - - /* We build the howto information on the fly. */ - - howto.type = rel->r_type; - howto.rightshift = 0; - howto.size = 2; - howto.bitsize = (rel->r_size & 0x1f) + 1; - howto.pc_relative = false; - howto.bitpos = 0; - if ((rel->r_size & 0x80) != 0) - howto.complain_on_overflow = complain_overflow_signed; - else - howto.complain_on_overflow = complain_overflow_bitfield; - howto.special_function = NULL; - howto.name = "internal"; - howto.partial_inplace = true; - if (howto.bitsize == 32) - howto.src_mask = howto.dst_mask = 0xffffffff; - else - { - howto.src_mask = howto.dst_mask = (1 << howto.bitsize) - 1; - if (howto.bitsize == 16) - howto.size = 1; - } - howto.pcrel_offset = false; - - val = 0; - - if (h == NULL) - { - asection *sec; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - /* Hack to make sure we use the right TOC anchor value - if this reloc is against the TOC anchor. */ - if (sec->name[3] == '0' - && strcmp (sec->name, ".tc0") == 0) - val = xcoff_data (output_bfd)->toc; - else - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_common) - { - asection *sec; - - sec = h->root.u.c.p->section; - val = (sec->output_section->vma - + sec->output_offset); - } - else if ((h->flags & XCOFF_DEF_DYNAMIC) != 0 - || (h->flags & XCOFF_IMPORT) != 0) - { - /* Every symbol in a shared object is defined somewhere. */ - val = 0; - } - else if (! info->relocateable - && ! info->shared) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - /* I took the relocation type definitions from two documents: - the PowerPC AIX Version 4 Application Binary Interface, First - Edition (April 1992), and the PowerOpen ABI, Big-Endian - 32-Bit Hardware Implementation (June 30, 1994). Differences - between the documents are noted below. */ - - switch (rel->r_type) - { - case R_RTB: - case R_RRTBI: - case R_RRTBA: - /* These relocs are defined by the PowerPC ABI to be - relative branches which use half of the difference - between the symbol and the program counter. I can't - quite figure out when this is useful. These relocs are - not defined by the PowerOpen ABI. */ - default: - (*_bfd_error_handler) - ("%s: unsupported relocation type 0x%02x", - bfd_get_filename (input_bfd), (unsigned int) rel->r_type); - bfd_set_error (bfd_error_bad_value); - return false; - case R_POS: - /* Simple positive relocation. */ - break; - case R_NEG: - /* Simple negative relocation. */ - val = - val; - break; - case R_REL: - /* Simple PC relative relocation. */ - howto.pc_relative = true; - break; - case R_TOC: - /* TOC relative relocation. The value in the instruction in - the input file is the offset from the input file TOC to - the desired location. We want the offset from the final - TOC to the desired location. We have: - isym = iTOC + in - iinsn = in + o - osym = oTOC + on - oinsn = on + o - so we must change insn by on - in. - */ - case R_GL: - /* Global linkage relocation. The value of this relocation - is the address of the entry in the TOC section. */ - case R_TCL: - /* Local object TOC address. I can't figure out the - difference between this and case R_GL. */ - case R_TRL: - /* TOC relative relocation. A TOC relative load instruction - which may be changed to a load address instruction. - FIXME: We don't currently implement this optimization. */ - case R_TRLA: - /* TOC relative relocation. This is a TOC relative load - address instruction which may be changed to a load - instruction. FIXME: I don't know if this is the correct - implementation. */ - if (h != NULL && h->toc_section == NULL) - { - (*_bfd_error_handler) - ("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry", - bfd_get_filename (input_bfd), rel->r_vaddr, - h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return false; - } - if (h != NULL) - { - BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0); - val = (h->toc_section->output_section->vma - + h->toc_section->output_offset); - } - val = ((val - xcoff_data (output_bfd)->toc) - - (sym->n_value - xcoff_data (input_bfd)->toc)); - addend = 0; - break; - case R_BA: - /* Absolute branch. We don't want to mess with the lower - two bits of the instruction. */ - case R_CAI: - /* The PowerPC ABI defines this as an absolute call which - may be modified to become a relative call. The PowerOpen - ABI does not define this relocation type. */ - case R_RBA: - /* Absolute branch which may be modified to become a - relative branch. */ - case R_RBAC: - /* The PowerPC ABI defines this as an absolute branch to a - fixed address which may be modified to an absolute branch - to a symbol. The PowerOpen ABI does not define this - relocation type. */ - case R_RBRC: - /* The PowerPC ABI defines this as an absolute branch to a - fixed address which may be modified to a relative branch. - The PowerOpen ABI does not define this relocation type. */ - howto.src_mask &= ~3; - howto.dst_mask = howto.src_mask; - break; - case R_BR: - /* Relative branch. We don't want to mess with the lower - two bits of the instruction. */ - case R_CREL: - /* The PowerPC ABI defines this as a relative call which may - be modified to become an absolute call. The PowerOpen - ABI does not define this relocation type. */ - case R_RBR: - /* A relative branch which may be modified to become an - absolute branch. FIXME: We don't implement this, - although we should for symbols of storage mapping class - XMC_XO. */ - howto.pc_relative = true; - howto.src_mask &= ~3; - howto.dst_mask = howto.src_mask; - break; - case R_RL: - /* The PowerPC AIX ABI describes this as a load which may be - changed to a load address. The PowerOpen ABI says this - is the same as case R_POS. */ - break; - case R_RLA: - /* The PowerPC AIX ABI describes this as a load address - which may be changed to a load. The PowerOpen ABI says - this is the same as R_POS. */ - break; - } - - /* If we see an R_BR or R_RBR reloc which is jumping to global - linkage code, and it is followed by an appropriate cror nop - instruction, we replace the cror with lwz r2,20(r1). This - restores the TOC after the glink code. Contrariwise, if the - call is followed by a lwz r2,20(r1), but the call is not - going to global linkage code, we can replace the load with a - cror. */ - if ((rel->r_type == R_BR || rel->r_type == R_RBR) - && h != NULL - && h->root.type == bfd_link_hash_defined - && (rel->r_vaddr - input_section->vma + 8 - <= input_section->_cooked_size)) - { - bfd_byte *pnext; - unsigned long next; - - pnext = contents + (rel->r_vaddr - input_section->vma) + 4; - next = bfd_get_32 (input_bfd, pnext); - if (h->smclas == XMC_GL) - { - if (next == 0x4def7b82 /* cror 15,15,15 */ - || next == 0x4ffffb82) /* cror 31,31,31 */ - bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */ - } - else - { - if (next == 0x80410014) /* lwz r1,20(r1) */ - bfd_put_32 (input_bfd, 0x4ffffb82, pnext); /* cror 31,31,31 */ - } - } - - /* A PC relative reloc includes the section address. */ - if (howto.pc_relative) - addend += input_section->vma; - - rstat = _bfd_final_link_relocate (&howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - char howto_name[10]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } - sprintf (howto_name, "0x%02x", rel->r_type); - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto_name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - - return true; -} diff --git a/contrib/gdb/install.sh b/contrib/gdb/install.sh deleted file mode 100755 index c92d510dd11..00000000000 --- a/contrib/gdb/install.sh +++ /dev/null @@ -1,236 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/contrib/gdb/move-if-change b/contrib/gdb/move-if-change deleted file mode 100755 index ee1b348beeb..00000000000 --- a/contrib/gdb/move-if-change +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -# Copyright (C) 1996 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -if -test -r $2 -then -if -cmp $1 $2 > /dev/null -then -echo $2 is unchanged -rm -f $1 -else -mv -f $1 $2 -fi -else -mv -f $1 $2 -fi From 4d359ceaf0173107f8a897b4f930b8fce29a46ed Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 20 Jun 2004 01:55:44 +0000 Subject: [PATCH 3/5] This file was not part of the GDB 5.2.1 import and should have been deleted from the vendor branch. --- contrib/gdb/gdb/.gdbinit | 16 - contrib/gdb/gdb/ChangeLog-93 | 7597 --------------------- contrib/gdb/gdb/ChangeLog-94 | 5705 ---------------- contrib/gdb/gdb/ChangeLog-95 | 4915 ------------- contrib/gdb/gdb/ChangeLog-96 | 5116 -------------- contrib/gdb/gdb/ChangeLog-97 | 2855 -------- contrib/gdb/gdb/ChangeLog-98 | 7122 ------------------- contrib/gdb/gdb/arm-convert.s | 16 - contrib/gdb/gdb/arm-xdep.c | 575 -- contrib/gdb/gdb/c-exp.tab.c | 2865 -------- contrib/gdb/gdb/callback.c | 349 - contrib/gdb/gdb/callback.h | 41 - contrib/gdb/gdb/command.c | 1564 ----- contrib/gdb/gdb/config/i386/cygwin32.mh | 6 - contrib/gdb/gdb/config/i386/cygwin32.mt | 6 - contrib/gdb/gdb/config/i386/nm-sun386.h | 27 - contrib/gdb/gdb/config/i386/sun386.mh | 5 - contrib/gdb/gdb/config/i386/sun386.mt | 3 - contrib/gdb/gdb/config/i386/tm-cygwin32.h | 125 - contrib/gdb/gdb/config/i386/tm-sun386.h | 205 - contrib/gdb/gdb/config/i386/windows.mh | 17 - contrib/gdb/gdb/config/i386/xm-cygwin32.h | 41 - contrib/gdb/gdb/config/i386/xm-i386lynx.h | 24 - contrib/gdb/gdb/config/i386/xm-linux.h | 36 - contrib/gdb/gdb/config/i386/xm-sun386.h | 20 - contrib/gdb/gdb/config/i386/xm-windows.h | 35 - contrib/gdb/gdb/config/nm-empty.h | 2 - contrib/gdb/gdb/config/nm-gnu.h | 43 - contrib/gdb/gdb/config/nm-lynx.h | 85 - contrib/gdb/gdb/config/nm-m3.h | 126 - contrib/gdb/gdb/config/nm-nbsd.h | 87 - contrib/gdb/gdb/config/nm-sysv4.h | 34 - contrib/gdb/gdb/config/tm-lynx.h | 35 - contrib/gdb/gdb/config/tm-nbsd.h | 29 - contrib/gdb/gdb/config/tm-sunos.h | 32 - contrib/gdb/gdb/config/tm-sysv4.h | 47 - contrib/gdb/gdb/config/xm-aix4.h | 91 - contrib/gdb/gdb/config/xm-lynx.h | 22 - contrib/gdb/gdb/config/xm-mpw.h | 81 - contrib/gdb/gdb/config/xm-nbsd.h | 26 - contrib/gdb/gdb/config/xm-sysv4.h | 29 - contrib/gdb/gdb/cpu32bug-rom.c | 165 - contrib/gdb/gdb/cxux-nat.c | 537 -- contrib/gdb/gdb/doc/HPPA-cfg.texi | 114 - contrib/gdb/gdb/doc/h8-cfg.texi | 47 - contrib/gdb/gdb/doc/libgdb.texinfo | 878 --- contrib/gdb/gdb/doc/refcard.dvi | Bin 21732 -> 0 bytes contrib/gdb/gdb/doc/remote.texi | 1708 ----- contrib/gdb/gdb/f-exp.tab.c | 2155 ------ contrib/gdb/gdb/gdba.el | 2607 ------- contrib/gdb/gdb/gdbserver/low-linux.c | 451 -- contrib/gdb/gdb/gnu-nat.c | 3357 --------- contrib/gdb/gdb/gnu-nat.h | 101 - contrib/gdb/gdb/gnu-regex.c | 5797 ---------------- contrib/gdb/gdb/gnu-regex.h | 576 -- contrib/gdb/gdb/go32-xdep.c | 35 - contrib/gdb/gdb/hp-psymtab-read.c | 2381 ------- contrib/gdb/gdb/hp-symtab-read.c | 3988 ----------- contrib/gdb/gdb/hpread.h | 150 - contrib/gdb/gdb/i386gnu-nat.c | 271 - contrib/gdb/gdb/irix4-nat.c | 207 - contrib/gdb/gdb/irix5-nat.c | 1320 ---- contrib/gdb/gdb/isi-xdep.c | 20 - contrib/gdb/gdb/jv-exp.tab.c | 2351 ------- contrib/gdb/gdb/kdb-start.c | 38 - contrib/gdb/gdb/lynx-nat.c | 829 --- contrib/gdb/gdb/m2-exp.tab.c | 2162 ------ contrib/gdb/gdb/m32r-rom.c | 626 -- contrib/gdb/gdb/m32r-stub.c | 1711 ----- contrib/gdb/gdb/m32r-tdep.c | 705 -- contrib/gdb/gdb/m68k-stub.c | 1098 --- contrib/gdb/gdb/m68k-tdep.c | 685 -- contrib/gdb/gdb/m68klinux-nat.c | 710 -- contrib/gdb/gdb/m68knbsd-nat.c | 103 - contrib/gdb/gdb/m88k-nat.c | 290 - contrib/gdb/gdb/m88k-tdep.c | 634 -- contrib/gdb/gdb/mon960-rom.c | 260 - contrib/gdb/gdb/mpw-config.in | 81 - contrib/gdb/gdb/mpw-make.sed | 178 - contrib/gdb/gdb/news-xdep.c | 65 - contrib/gdb/gdb/nindy-tdep.c | 78 - contrib/gdb/gdb/ns32k-tdep.c | 190 - contrib/gdb/gdb/ns32km3-nat.c | 183 - contrib/gdb/gdb/ns32knbsd-nat.c | 364 - contrib/gdb/gdb/op50-rom.c | 142 - contrib/gdb/gdb/os9kread.c | 1621 ----- contrib/gdb/gdb/partial-stab.h | 812 --- contrib/gdb/gdb/ptx4-nat.c | 211 - contrib/gdb/gdb/pyr-tdep.c | 452 -- contrib/gdb/gdb/pyr-xdep.c | 370 - contrib/gdb/gdb/remote-adapt.c | 1524 ----- contrib/gdb/gdb/remote-array.c | 1457 ---- contrib/gdb/gdb/remote-bug.c | 1027 --- contrib/gdb/gdb/remote-d10v.c | 228 - contrib/gdb/gdb/remote-e7000.c | 2227 ------ contrib/gdb/gdb/remote-eb.c | 1088 --- contrib/gdb/gdb/remote-es.c | 2127 ------ contrib/gdb/gdb/remote-est.c | 169 - contrib/gdb/gdb/remote-hms.c | 157 - contrib/gdb/gdb/remote-mm.c | 1848 ----- contrib/gdb/gdb/remote-nindy.c | 762 --- contrib/gdb/gdb/remote-nrom.c | 351 - contrib/gdb/gdb/remote-os9k.c | 1230 ---- contrib/gdb/gdb/remote-pa.c | 1540 ----- contrib/gdb/gdb/remote-sds.c | 1145 ---- contrib/gdb/gdb/remote-sim.h | 142 - contrib/gdb/gdb/remote-udi.c | 1722 ----- contrib/gdb/gdb/remote-vx.c | 1410 ---- contrib/gdb/gdb/remote-vx29k.c | 182 - contrib/gdb/gdb/remote-vx68.c | 156 - contrib/gdb/gdb/remote-vx960.c | 160 - contrib/gdb/gdb/remote-vxmips.c | 199 - contrib/gdb/gdb/remote-vxsparc.c | 194 - contrib/gdb/gdb/ser-e7kpc.c | 438 -- contrib/gdb/gdb/ser-go32.c | 964 --- contrib/gdb/gdb/ser-mac.c | 362 - contrib/gdb/gdb/ser-ocd.c | 209 - contrib/gdb/gdb/signals.h | 27 - contrib/gdb/gdb/somread.c | 743 -- contrib/gdb/gdb/somsolib.c | 1616 ----- contrib/gdb/gdb/somsolib.h | 165 - contrib/gdb/gdb/stop-gdb.c | 109 - contrib/gdb/gdb/stuff.c | 178 - contrib/gdb/gdb/symm-nat.c | 902 --- contrib/gdb/gdb/symm-tdep.c | 102 - contrib/gdb/gdb/thread.h | 46 - contrib/gdb/gdb/tui/ChangeLog | 121 - contrib/gdb/gdb/tui/Makefile | 182 - contrib/gdb/gdb/tui/Makefile.in | 168 - contrib/gdb/gdb/tui/tui.c | 830 --- contrib/gdb/gdb/tui/tui.h | 120 - contrib/gdb/gdb/tui/tuiCommand.c | 215 - contrib/gdb/gdb/tui/tuiCommand.h | 24 - contrib/gdb/gdb/tui/tuiData.c | 1624 ----- contrib/gdb/gdb/tui/tuiData.h | 302 - contrib/gdb/gdb/tui/tuiDataWin.c | 400 -- contrib/gdb/gdb/tui/tuiDataWin.h | 29 - contrib/gdb/gdb/tui/tuiDisassem.c | 343 - contrib/gdb/gdb/tui/tuiDisassem.h | 22 - contrib/gdb/gdb/tui/tuiGeneralWin.c | 469 -- contrib/gdb/gdb/tui/tuiGeneralWin.h | 31 - contrib/gdb/gdb/tui/tuiIO.c | 734 -- contrib/gdb/gdb/tui/tuiIO.h | 43 - contrib/gdb/gdb/tui/tuiLayout.c | 1410 ---- contrib/gdb/gdb/tui/tuiLayout.h | 15 - contrib/gdb/gdb/tui/tuiRegs.c | 1210 ---- contrib/gdb/gdb/tui/tuiRegs.h | 28 - contrib/gdb/gdb/tui/tuiSource.c | 465 -- contrib/gdb/gdb/tui/tuiSource.h | 27 - contrib/gdb/gdb/tui/tuiSourceWin.c | 1098 --- contrib/gdb/gdb/tui/tuiSourceWin.h | 74 - contrib/gdb/gdb/tui/tuiStack.c | 554 -- contrib/gdb/gdb/tui/tuiStack.h | 22 - contrib/gdb/gdb/tui/tuiWin.c | 1650 ----- contrib/gdb/gdb/tui/tuiWin.h | 28 - contrib/gdb/gdb/umax-xdep.c | 133 - contrib/gdb/gdb/v850-tdep.c | 862 --- contrib/gdb/gdb/xmodem.c | 275 - contrib/gdb/gdb/xmodem.h | 30 - contrib/gdb/include/COPYING | 339 - contrib/gdb/include/ChangeLog | 973 --- contrib/gdb/include/ansidecl.h | 141 - contrib/gdb/include/aout/ChangeLog | 174 - contrib/gdb/include/aout/adobe.h | 297 - contrib/gdb/include/aout/aout64.h | 475 -- contrib/gdb/include/aout/ar.h | 36 - contrib/gdb/include/aout/dynix3.h | 71 - contrib/gdb/include/aout/encap.h | 135 - contrib/gdb/include/aout/host.h | 22 - contrib/gdb/include/aout/hp.h | 82 - contrib/gdb/include/aout/hp300hpux.h | 119 - contrib/gdb/include/aout/hppa.h | 7 - contrib/gdb/include/aout/ranlib.h | 62 - contrib/gdb/include/aout/reloc.h | 66 - contrib/gdb/include/aout/stab.def | 264 - contrib/gdb/include/aout/stab_gnu.h | 37 - contrib/gdb/include/aout/sun4.h | 219 - contrib/gdb/include/bfdlink.h | 452 -- contrib/gdb/include/bout.h | 182 - contrib/gdb/include/coff/ChangeLog | 622 -- contrib/gdb/include/coff/a29k.h | 305 - contrib/gdb/include/coff/alpha.h | 342 - contrib/gdb/include/coff/apollo.h | 248 - contrib/gdb/include/coff/arm.h | 215 - contrib/gdb/include/coff/aux-coff.h | 31 - contrib/gdb/include/coff/ecoff.h | 408 -- contrib/gdb/include/coff/h8300.h | 203 - contrib/gdb/include/coff/h8500.h | 201 - contrib/gdb/include/coff/i386.h | 224 - contrib/gdb/include/coff/i860.h | 204 - contrib/gdb/include/coff/i960.h | 251 - contrib/gdb/include/coff/internal.h | 648 -- contrib/gdb/include/coff/m68k.h | 221 - contrib/gdb/include/coff/m88k.h | 218 - contrib/gdb/include/coff/mips.h | 368 - contrib/gdb/include/coff/pe.h | 161 - contrib/gdb/include/coff/powerpc.h | 196 - contrib/gdb/include/coff/rs6000.h | 242 - contrib/gdb/include/coff/sh.h | 253 - contrib/gdb/include/coff/sparc.h | 209 - contrib/gdb/include/coff/sym.h | 484 -- contrib/gdb/include/coff/symconst.h | 177 - contrib/gdb/include/coff/w65.h | 201 - contrib/gdb/include/coff/we32k.h | 206 - contrib/gdb/include/coff/z8k.h | 201 - contrib/gdb/include/demangle.h | 108 - contrib/gdb/include/dis-asm.h | 175 - contrib/gdb/include/elf/ChangeLog | 195 - contrib/gdb/include/elf/common.h | 239 - contrib/gdb/include/elf/dwarf.h | 319 - contrib/gdb/include/elf/external.h | 195 - contrib/gdb/include/elf/hppa.h | 94 - contrib/gdb/include/elf/internal.h | 207 - contrib/gdb/include/elf/mips.h | 298 - contrib/gdb/include/elf/ppc.h | 54 - contrib/gdb/include/elf/sparc.h | 73 - contrib/gdb/include/floatformat.h | 88 - contrib/gdb/include/fopen-bin.h | 27 - contrib/gdb/include/fopen-same.h | 27 - contrib/gdb/include/gdbm.h | 91 - contrib/gdb/include/getopt.h | 129 - contrib/gdb/include/hp-symtab.h | 983 --- contrib/gdb/include/ieee.h | 139 - contrib/gdb/include/libiberty.h | 133 - contrib/gdb/include/mpw/ChangeLog | 61 - contrib/gdb/include/mpw/README | 1 - contrib/gdb/include/mpw/dir.h | 23 - contrib/gdb/include/mpw/dirent.h | 31 - contrib/gdb/include/mpw/fcntl.h | 124 - contrib/gdb/include/mpw/grp.h | 10 - contrib/gdb/include/mpw/mpw.h | 130 - contrib/gdb/include/mpw/pwd.h | 15 - contrib/gdb/include/mpw/spin.h | 64 - contrib/gdb/include/mpw/stat.h | 75 - contrib/gdb/include/mpw/sys/file.h | 1 - contrib/gdb/include/mpw/sys/param.h | 1 - contrib/gdb/include/mpw/sys/resource.h | 9 - contrib/gdb/include/mpw/sys/stat.h | 44 - contrib/gdb/include/mpw/sys/time.h | 13 - contrib/gdb/include/mpw/sys/types.h | 15 - contrib/gdb/include/mpw/utime.h | 7 - contrib/gdb/include/mpw/varargs.h | 9 - contrib/gdb/include/nlm/ChangeLog | 83 - contrib/gdb/include/nlm/alpha-ext.h | 166 - contrib/gdb/include/nlm/common.h | 124 - contrib/gdb/include/nlm/external.h | 174 - contrib/gdb/include/nlm/i386-ext.h | 116 - contrib/gdb/include/nlm/internal.h | 309 - contrib/gdb/include/nlm/ppc-ext.h | 163 - contrib/gdb/include/nlm/sparc32-ext.h | 120 - contrib/gdb/include/oasys.h | 152 - contrib/gdb/include/obstack.h | 518 -- contrib/gdb/include/opcode/ChangeLog | 812 --- contrib/gdb/include/opcode/a29k.h | 285 - contrib/gdb/include/opcode/arm.h | 294 - contrib/gdb/include/opcode/convex.h | 1711 ----- contrib/gdb/include/opcode/h8300.h | 550 -- contrib/gdb/include/opcode/hppa.h | 471 -- contrib/gdb/include/opcode/i386.h | 898 --- contrib/gdb/include/opcode/i860.h | 491 -- contrib/gdb/include/opcode/i960.h | 509 -- contrib/gdb/include/opcode/m68k.h | 297 - contrib/gdb/include/opcode/m88k.h | 923 --- contrib/gdb/include/opcode/mips.h | 481 -- contrib/gdb/include/opcode/np1.h | 422 -- contrib/gdb/include/opcode/ns32k.h | 491 -- contrib/gdb/include/opcode/pn.h | 282 - contrib/gdb/include/opcode/ppc.h | 248 - contrib/gdb/include/opcode/pyr.h | 287 - contrib/gdb/include/opcode/rs6k.h | 254 - contrib/gdb/include/opcode/sparc.h | 220 - contrib/gdb/include/opcode/tahoe.h | 213 - contrib/gdb/include/opcode/vax.h | 382 -- contrib/gdb/include/os9k.h | 169 - contrib/gdb/include/progress.h | 37 - contrib/gdb/include/wait.h | 63 - contrib/gdb/libiberty/COPYING.LIB | 481 -- contrib/gdb/libiberty/ChangeLog | 1815 ----- contrib/gdb/libiberty/Makefile.in | 321 - contrib/gdb/libiberty/README | 129 - contrib/gdb/libiberty/alloca-botch.h | 5 - contrib/gdb/libiberty/alloca-norm.h | 16 - contrib/gdb/libiberty/alloca.c | 475 -- contrib/gdb/libiberty/argv.c | 328 - contrib/gdb/libiberty/atexit.c | 14 - contrib/gdb/libiberty/basename.c | 43 - contrib/gdb/libiberty/bcmp.c | 49 - contrib/gdb/libiberty/bcopy.c | 35 - contrib/gdb/libiberty/bzero.c | 31 - contrib/gdb/libiberty/clock.c | 73 - contrib/gdb/libiberty/concat.c | 167 - contrib/gdb/libiberty/config.table | 63 - contrib/gdb/libiberty/config/mh-a68bsd | 2 - contrib/gdb/libiberty/config/mh-aix | 10 - contrib/gdb/libiberty/config/mh-apollo68 | 2 - contrib/gdb/libiberty/config/mh-cxux7 | 3 - contrib/gdb/libiberty/config/mh-go32 | 4 - contrib/gdb/libiberty/config/mh-hpbsd | 2 - contrib/gdb/libiberty/config/mh-irix4 | 4 - contrib/gdb/libiberty/config/mh-lynxos | 1 - contrib/gdb/libiberty/config/mh-ncr3000 | 19 - contrib/gdb/libiberty/config/mh-riscix | 6 - contrib/gdb/libiberty/config/mh-sysv | 1 - contrib/gdb/libiberty/config/mh-sysv4 | 3 - contrib/gdb/libiberty/config/mt-sunos4 | 2 - contrib/gdb/libiberty/config/mt-vxworks5 | 27 - contrib/gdb/libiberty/configure.bat | 15 - contrib/gdb/libiberty/configure.in | 77 - contrib/gdb/libiberty/copysign.c | 140 - contrib/gdb/libiberty/cplus-dem.c | 3019 -------- contrib/gdb/libiberty/dummy.c | 49 - contrib/gdb/libiberty/fdmatch.c | 73 - contrib/gdb/libiberty/floatformat.c | 385 -- contrib/gdb/libiberty/functions.def | 67 - contrib/gdb/libiberty/getcwd.c | 52 - contrib/gdb/libiberty/getopt.c | 757 -- contrib/gdb/libiberty/getopt1.c | 190 - contrib/gdb/libiberty/getpagesize.c | 89 - contrib/gdb/libiberty/getruntime.c | 82 - contrib/gdb/libiberty/hex.c | 33 - contrib/gdb/libiberty/index.c | 11 - contrib/gdb/libiberty/insque.c | 50 - contrib/gdb/libiberty/makefile.dos | 29 - contrib/gdb/libiberty/memchr.c | 60 - contrib/gdb/libiberty/memcmp.c | 38 - contrib/gdb/libiberty/memcpy.c | 28 - contrib/gdb/libiberty/memmove.c | 18 - contrib/gdb/libiberty/memset.c | 19 - contrib/gdb/libiberty/mpw-config.in | 9 - contrib/gdb/libiberty/mpw-make.sed | 49 - contrib/gdb/libiberty/mpw.c | 1010 --- contrib/gdb/libiberty/msdos.c | 15 - contrib/gdb/libiberty/obstack.c | 507 -- contrib/gdb/libiberty/random.c | 373 - contrib/gdb/libiberty/rename.c | 22 - contrib/gdb/libiberty/rindex.c | 11 - contrib/gdb/libiberty/sigsetmask.c | 30 - contrib/gdb/libiberty/spaces.c | 71 - contrib/gdb/libiberty/strcasecmp.c | 81 - contrib/gdb/libiberty/strchr.c | 34 - contrib/gdb/libiberty/strdup.c | 10 - contrib/gdb/libiberty/strerror.c | 829 --- contrib/gdb/libiberty/strncasecmp.c | 82 - contrib/gdb/libiberty/strrchr.c | 34 - contrib/gdb/libiberty/strsignal.c | 627 -- contrib/gdb/libiberty/strstr.c | 51 - contrib/gdb/libiberty/strtod.c | 122 - contrib/gdb/libiberty/strtol.c | 143 - contrib/gdb/libiberty/strtoul.c | 110 - contrib/gdb/libiberty/tmpnam.c | 39 - contrib/gdb/libiberty/vasprintf.c | 165 - contrib/gdb/libiberty/vfork.c | 8 - contrib/gdb/libiberty/vfprintf.c | 13 - contrib/gdb/libiberty/vmsbuild.com | 142 - contrib/gdb/libiberty/vprintf.c | 11 - contrib/gdb/libiberty/vsprintf.c | 55 - contrib/gdb/libiberty/waitpid.c | 11 - contrib/gdb/libiberty/xatexit.c | 82 - contrib/gdb/libiberty/xexit.c | 36 - contrib/gdb/libiberty/xmalloc.c | 106 - contrib/gdb/libiberty/xstrdup.c | 17 - contrib/gdb/libiberty/xstrerror.c | 54 - 362 files changed, 166798 deletions(-) delete mode 100644 contrib/gdb/gdb/.gdbinit delete mode 100644 contrib/gdb/gdb/ChangeLog-93 delete mode 100644 contrib/gdb/gdb/ChangeLog-94 delete mode 100644 contrib/gdb/gdb/ChangeLog-95 delete mode 100644 contrib/gdb/gdb/ChangeLog-96 delete mode 100644 contrib/gdb/gdb/ChangeLog-97 delete mode 100644 contrib/gdb/gdb/ChangeLog-98 delete mode 100644 contrib/gdb/gdb/arm-convert.s delete mode 100644 contrib/gdb/gdb/arm-xdep.c delete mode 100644 contrib/gdb/gdb/c-exp.tab.c delete mode 100644 contrib/gdb/gdb/callback.c delete mode 100644 contrib/gdb/gdb/callback.h delete mode 100644 contrib/gdb/gdb/command.c delete mode 100644 contrib/gdb/gdb/config/i386/cygwin32.mh delete mode 100644 contrib/gdb/gdb/config/i386/cygwin32.mt delete mode 100644 contrib/gdb/gdb/config/i386/nm-sun386.h delete mode 100644 contrib/gdb/gdb/config/i386/sun386.mh delete mode 100644 contrib/gdb/gdb/config/i386/sun386.mt delete mode 100644 contrib/gdb/gdb/config/i386/tm-cygwin32.h delete mode 100644 contrib/gdb/gdb/config/i386/tm-sun386.h delete mode 100644 contrib/gdb/gdb/config/i386/windows.mh delete mode 100644 contrib/gdb/gdb/config/i386/xm-cygwin32.h delete mode 100644 contrib/gdb/gdb/config/i386/xm-i386lynx.h delete mode 100644 contrib/gdb/gdb/config/i386/xm-linux.h delete mode 100644 contrib/gdb/gdb/config/i386/xm-sun386.h delete mode 100644 contrib/gdb/gdb/config/i386/xm-windows.h delete mode 100644 contrib/gdb/gdb/config/nm-empty.h delete mode 100644 contrib/gdb/gdb/config/nm-gnu.h delete mode 100644 contrib/gdb/gdb/config/nm-lynx.h delete mode 100644 contrib/gdb/gdb/config/nm-m3.h delete mode 100644 contrib/gdb/gdb/config/nm-nbsd.h delete mode 100644 contrib/gdb/gdb/config/nm-sysv4.h delete mode 100644 contrib/gdb/gdb/config/tm-lynx.h delete mode 100644 contrib/gdb/gdb/config/tm-nbsd.h delete mode 100644 contrib/gdb/gdb/config/tm-sunos.h delete mode 100644 contrib/gdb/gdb/config/tm-sysv4.h delete mode 100644 contrib/gdb/gdb/config/xm-aix4.h delete mode 100644 contrib/gdb/gdb/config/xm-lynx.h delete mode 100644 contrib/gdb/gdb/config/xm-mpw.h delete mode 100644 contrib/gdb/gdb/config/xm-nbsd.h delete mode 100644 contrib/gdb/gdb/config/xm-sysv4.h delete mode 100644 contrib/gdb/gdb/cpu32bug-rom.c delete mode 100644 contrib/gdb/gdb/cxux-nat.c delete mode 100644 contrib/gdb/gdb/doc/HPPA-cfg.texi delete mode 100644 contrib/gdb/gdb/doc/h8-cfg.texi delete mode 100644 contrib/gdb/gdb/doc/libgdb.texinfo delete mode 100644 contrib/gdb/gdb/doc/refcard.dvi delete mode 100644 contrib/gdb/gdb/doc/remote.texi delete mode 100644 contrib/gdb/gdb/f-exp.tab.c delete mode 100644 contrib/gdb/gdb/gdba.el delete mode 100644 contrib/gdb/gdb/gdbserver/low-linux.c delete mode 100644 contrib/gdb/gdb/gnu-nat.c delete mode 100644 contrib/gdb/gdb/gnu-nat.h delete mode 100644 contrib/gdb/gdb/gnu-regex.c delete mode 100644 contrib/gdb/gdb/gnu-regex.h delete mode 100644 contrib/gdb/gdb/go32-xdep.c delete mode 100644 contrib/gdb/gdb/hp-psymtab-read.c delete mode 100644 contrib/gdb/gdb/hp-symtab-read.c delete mode 100644 contrib/gdb/gdb/hpread.h delete mode 100644 contrib/gdb/gdb/i386gnu-nat.c delete mode 100644 contrib/gdb/gdb/irix4-nat.c delete mode 100644 contrib/gdb/gdb/irix5-nat.c delete mode 100644 contrib/gdb/gdb/isi-xdep.c delete mode 100644 contrib/gdb/gdb/jv-exp.tab.c delete mode 100644 contrib/gdb/gdb/kdb-start.c delete mode 100644 contrib/gdb/gdb/lynx-nat.c delete mode 100644 contrib/gdb/gdb/m2-exp.tab.c delete mode 100644 contrib/gdb/gdb/m32r-rom.c delete mode 100644 contrib/gdb/gdb/m32r-stub.c delete mode 100644 contrib/gdb/gdb/m32r-tdep.c delete mode 100644 contrib/gdb/gdb/m68k-stub.c delete mode 100644 contrib/gdb/gdb/m68k-tdep.c delete mode 100644 contrib/gdb/gdb/m68klinux-nat.c delete mode 100644 contrib/gdb/gdb/m68knbsd-nat.c delete mode 100644 contrib/gdb/gdb/m88k-nat.c delete mode 100644 contrib/gdb/gdb/m88k-tdep.c delete mode 100644 contrib/gdb/gdb/mon960-rom.c delete mode 100644 contrib/gdb/gdb/mpw-config.in delete mode 100644 contrib/gdb/gdb/mpw-make.sed delete mode 100644 contrib/gdb/gdb/news-xdep.c delete mode 100644 contrib/gdb/gdb/nindy-tdep.c delete mode 100644 contrib/gdb/gdb/ns32k-tdep.c delete mode 100644 contrib/gdb/gdb/ns32km3-nat.c delete mode 100644 contrib/gdb/gdb/ns32knbsd-nat.c delete mode 100644 contrib/gdb/gdb/op50-rom.c delete mode 100644 contrib/gdb/gdb/os9kread.c delete mode 100644 contrib/gdb/gdb/partial-stab.h delete mode 100644 contrib/gdb/gdb/ptx4-nat.c delete mode 100644 contrib/gdb/gdb/pyr-tdep.c delete mode 100644 contrib/gdb/gdb/pyr-xdep.c delete mode 100644 contrib/gdb/gdb/remote-adapt.c delete mode 100644 contrib/gdb/gdb/remote-array.c delete mode 100644 contrib/gdb/gdb/remote-bug.c delete mode 100644 contrib/gdb/gdb/remote-d10v.c delete mode 100644 contrib/gdb/gdb/remote-e7000.c delete mode 100644 contrib/gdb/gdb/remote-eb.c delete mode 100644 contrib/gdb/gdb/remote-es.c delete mode 100644 contrib/gdb/gdb/remote-est.c delete mode 100644 contrib/gdb/gdb/remote-hms.c delete mode 100644 contrib/gdb/gdb/remote-mm.c delete mode 100644 contrib/gdb/gdb/remote-nindy.c delete mode 100644 contrib/gdb/gdb/remote-nrom.c delete mode 100644 contrib/gdb/gdb/remote-os9k.c delete mode 100644 contrib/gdb/gdb/remote-pa.c delete mode 100644 contrib/gdb/gdb/remote-sds.c delete mode 100644 contrib/gdb/gdb/remote-sim.h delete mode 100644 contrib/gdb/gdb/remote-udi.c delete mode 100644 contrib/gdb/gdb/remote-vx.c delete mode 100644 contrib/gdb/gdb/remote-vx29k.c delete mode 100644 contrib/gdb/gdb/remote-vx68.c delete mode 100644 contrib/gdb/gdb/remote-vx960.c delete mode 100644 contrib/gdb/gdb/remote-vxmips.c delete mode 100644 contrib/gdb/gdb/remote-vxsparc.c delete mode 100644 contrib/gdb/gdb/ser-e7kpc.c delete mode 100644 contrib/gdb/gdb/ser-go32.c delete mode 100644 contrib/gdb/gdb/ser-mac.c delete mode 100644 contrib/gdb/gdb/ser-ocd.c delete mode 100644 contrib/gdb/gdb/signals.h delete mode 100644 contrib/gdb/gdb/somread.c delete mode 100644 contrib/gdb/gdb/somsolib.c delete mode 100644 contrib/gdb/gdb/somsolib.h delete mode 100644 contrib/gdb/gdb/stop-gdb.c delete mode 100644 contrib/gdb/gdb/stuff.c delete mode 100644 contrib/gdb/gdb/symm-nat.c delete mode 100644 contrib/gdb/gdb/symm-tdep.c delete mode 100644 contrib/gdb/gdb/thread.h delete mode 100644 contrib/gdb/gdb/tui/ChangeLog delete mode 100644 contrib/gdb/gdb/tui/Makefile delete mode 100644 contrib/gdb/gdb/tui/Makefile.in delete mode 100644 contrib/gdb/gdb/tui/tui.c delete mode 100644 contrib/gdb/gdb/tui/tui.h delete mode 100644 contrib/gdb/gdb/tui/tuiCommand.c delete mode 100644 contrib/gdb/gdb/tui/tuiCommand.h delete mode 100644 contrib/gdb/gdb/tui/tuiData.c delete mode 100644 contrib/gdb/gdb/tui/tuiData.h delete mode 100644 contrib/gdb/gdb/tui/tuiDataWin.c delete mode 100644 contrib/gdb/gdb/tui/tuiDataWin.h delete mode 100644 contrib/gdb/gdb/tui/tuiDisassem.c delete mode 100644 contrib/gdb/gdb/tui/tuiDisassem.h delete mode 100644 contrib/gdb/gdb/tui/tuiGeneralWin.c delete mode 100644 contrib/gdb/gdb/tui/tuiGeneralWin.h delete mode 100644 contrib/gdb/gdb/tui/tuiIO.c delete mode 100644 contrib/gdb/gdb/tui/tuiIO.h delete mode 100644 contrib/gdb/gdb/tui/tuiLayout.c delete mode 100644 contrib/gdb/gdb/tui/tuiLayout.h delete mode 100644 contrib/gdb/gdb/tui/tuiRegs.c delete mode 100644 contrib/gdb/gdb/tui/tuiRegs.h delete mode 100644 contrib/gdb/gdb/tui/tuiSource.c delete mode 100644 contrib/gdb/gdb/tui/tuiSource.h delete mode 100644 contrib/gdb/gdb/tui/tuiSourceWin.c delete mode 100644 contrib/gdb/gdb/tui/tuiSourceWin.h delete mode 100644 contrib/gdb/gdb/tui/tuiStack.c delete mode 100644 contrib/gdb/gdb/tui/tuiStack.h delete mode 100644 contrib/gdb/gdb/tui/tuiWin.c delete mode 100644 contrib/gdb/gdb/tui/tuiWin.h delete mode 100644 contrib/gdb/gdb/umax-xdep.c delete mode 100644 contrib/gdb/gdb/v850-tdep.c delete mode 100644 contrib/gdb/gdb/xmodem.c delete mode 100644 contrib/gdb/gdb/xmodem.h delete mode 100644 contrib/gdb/include/COPYING delete mode 100644 contrib/gdb/include/ChangeLog delete mode 100644 contrib/gdb/include/ansidecl.h delete mode 100644 contrib/gdb/include/aout/ChangeLog delete mode 100644 contrib/gdb/include/aout/adobe.h delete mode 100644 contrib/gdb/include/aout/aout64.h delete mode 100644 contrib/gdb/include/aout/ar.h delete mode 100644 contrib/gdb/include/aout/dynix3.h delete mode 100644 contrib/gdb/include/aout/encap.h delete mode 100644 contrib/gdb/include/aout/host.h delete mode 100644 contrib/gdb/include/aout/hp.h delete mode 100644 contrib/gdb/include/aout/hp300hpux.h delete mode 100644 contrib/gdb/include/aout/hppa.h delete mode 100644 contrib/gdb/include/aout/ranlib.h delete mode 100644 contrib/gdb/include/aout/reloc.h delete mode 100644 contrib/gdb/include/aout/stab.def delete mode 100644 contrib/gdb/include/aout/stab_gnu.h delete mode 100644 contrib/gdb/include/aout/sun4.h delete mode 100644 contrib/gdb/include/bfdlink.h delete mode 100644 contrib/gdb/include/bout.h delete mode 100644 contrib/gdb/include/coff/ChangeLog delete mode 100644 contrib/gdb/include/coff/a29k.h delete mode 100644 contrib/gdb/include/coff/alpha.h delete mode 100644 contrib/gdb/include/coff/apollo.h delete mode 100644 contrib/gdb/include/coff/arm.h delete mode 100644 contrib/gdb/include/coff/aux-coff.h delete mode 100644 contrib/gdb/include/coff/ecoff.h delete mode 100644 contrib/gdb/include/coff/h8300.h delete mode 100644 contrib/gdb/include/coff/h8500.h delete mode 100644 contrib/gdb/include/coff/i386.h delete mode 100644 contrib/gdb/include/coff/i860.h delete mode 100644 contrib/gdb/include/coff/i960.h delete mode 100644 contrib/gdb/include/coff/internal.h delete mode 100644 contrib/gdb/include/coff/m68k.h delete mode 100644 contrib/gdb/include/coff/m88k.h delete mode 100644 contrib/gdb/include/coff/mips.h delete mode 100644 contrib/gdb/include/coff/pe.h delete mode 100644 contrib/gdb/include/coff/powerpc.h delete mode 100644 contrib/gdb/include/coff/rs6000.h delete mode 100644 contrib/gdb/include/coff/sh.h delete mode 100644 contrib/gdb/include/coff/sparc.h delete mode 100644 contrib/gdb/include/coff/sym.h delete mode 100644 contrib/gdb/include/coff/symconst.h delete mode 100644 contrib/gdb/include/coff/w65.h delete mode 100644 contrib/gdb/include/coff/we32k.h delete mode 100644 contrib/gdb/include/coff/z8k.h delete mode 100644 contrib/gdb/include/demangle.h delete mode 100644 contrib/gdb/include/dis-asm.h delete mode 100644 contrib/gdb/include/elf/ChangeLog delete mode 100644 contrib/gdb/include/elf/common.h delete mode 100644 contrib/gdb/include/elf/dwarf.h delete mode 100644 contrib/gdb/include/elf/external.h delete mode 100644 contrib/gdb/include/elf/hppa.h delete mode 100644 contrib/gdb/include/elf/internal.h delete mode 100644 contrib/gdb/include/elf/mips.h delete mode 100644 contrib/gdb/include/elf/ppc.h delete mode 100644 contrib/gdb/include/elf/sparc.h delete mode 100644 contrib/gdb/include/floatformat.h delete mode 100644 contrib/gdb/include/fopen-bin.h delete mode 100644 contrib/gdb/include/fopen-same.h delete mode 100644 contrib/gdb/include/gdbm.h delete mode 100644 contrib/gdb/include/getopt.h delete mode 100644 contrib/gdb/include/hp-symtab.h delete mode 100644 contrib/gdb/include/ieee.h delete mode 100644 contrib/gdb/include/libiberty.h delete mode 100644 contrib/gdb/include/mpw/ChangeLog delete mode 100644 contrib/gdb/include/mpw/README delete mode 100644 contrib/gdb/include/mpw/dir.h delete mode 100644 contrib/gdb/include/mpw/dirent.h delete mode 100644 contrib/gdb/include/mpw/fcntl.h delete mode 100644 contrib/gdb/include/mpw/grp.h delete mode 100644 contrib/gdb/include/mpw/mpw.h delete mode 100644 contrib/gdb/include/mpw/pwd.h delete mode 100644 contrib/gdb/include/mpw/spin.h delete mode 100644 contrib/gdb/include/mpw/stat.h delete mode 100644 contrib/gdb/include/mpw/sys/file.h delete mode 100644 contrib/gdb/include/mpw/sys/param.h delete mode 100644 contrib/gdb/include/mpw/sys/resource.h delete mode 100644 contrib/gdb/include/mpw/sys/stat.h delete mode 100644 contrib/gdb/include/mpw/sys/time.h delete mode 100644 contrib/gdb/include/mpw/sys/types.h delete mode 100644 contrib/gdb/include/mpw/utime.h delete mode 100644 contrib/gdb/include/mpw/varargs.h delete mode 100644 contrib/gdb/include/nlm/ChangeLog delete mode 100644 contrib/gdb/include/nlm/alpha-ext.h delete mode 100644 contrib/gdb/include/nlm/common.h delete mode 100644 contrib/gdb/include/nlm/external.h delete mode 100644 contrib/gdb/include/nlm/i386-ext.h delete mode 100644 contrib/gdb/include/nlm/internal.h delete mode 100644 contrib/gdb/include/nlm/ppc-ext.h delete mode 100644 contrib/gdb/include/nlm/sparc32-ext.h delete mode 100644 contrib/gdb/include/oasys.h delete mode 100644 contrib/gdb/include/obstack.h delete mode 100644 contrib/gdb/include/opcode/ChangeLog delete mode 100644 contrib/gdb/include/opcode/a29k.h delete mode 100644 contrib/gdb/include/opcode/arm.h delete mode 100644 contrib/gdb/include/opcode/convex.h delete mode 100644 contrib/gdb/include/opcode/h8300.h delete mode 100644 contrib/gdb/include/opcode/hppa.h delete mode 100644 contrib/gdb/include/opcode/i386.h delete mode 100644 contrib/gdb/include/opcode/i860.h delete mode 100644 contrib/gdb/include/opcode/i960.h delete mode 100644 contrib/gdb/include/opcode/m68k.h delete mode 100644 contrib/gdb/include/opcode/m88k.h delete mode 100644 contrib/gdb/include/opcode/mips.h delete mode 100644 contrib/gdb/include/opcode/np1.h delete mode 100644 contrib/gdb/include/opcode/ns32k.h delete mode 100644 contrib/gdb/include/opcode/pn.h delete mode 100644 contrib/gdb/include/opcode/ppc.h delete mode 100644 contrib/gdb/include/opcode/pyr.h delete mode 100644 contrib/gdb/include/opcode/rs6k.h delete mode 100644 contrib/gdb/include/opcode/sparc.h delete mode 100644 contrib/gdb/include/opcode/tahoe.h delete mode 100644 contrib/gdb/include/opcode/vax.h delete mode 100644 contrib/gdb/include/os9k.h delete mode 100644 contrib/gdb/include/progress.h delete mode 100644 contrib/gdb/include/wait.h delete mode 100644 contrib/gdb/libiberty/COPYING.LIB delete mode 100644 contrib/gdb/libiberty/ChangeLog delete mode 100644 contrib/gdb/libiberty/Makefile.in delete mode 100644 contrib/gdb/libiberty/README delete mode 100644 contrib/gdb/libiberty/alloca-botch.h delete mode 100644 contrib/gdb/libiberty/alloca-norm.h delete mode 100644 contrib/gdb/libiberty/alloca.c delete mode 100644 contrib/gdb/libiberty/argv.c delete mode 100644 contrib/gdb/libiberty/atexit.c delete mode 100644 contrib/gdb/libiberty/basename.c delete mode 100644 contrib/gdb/libiberty/bcmp.c delete mode 100644 contrib/gdb/libiberty/bcopy.c delete mode 100644 contrib/gdb/libiberty/bzero.c delete mode 100644 contrib/gdb/libiberty/clock.c delete mode 100644 contrib/gdb/libiberty/concat.c delete mode 100644 contrib/gdb/libiberty/config.table delete mode 100644 contrib/gdb/libiberty/config/mh-a68bsd delete mode 100644 contrib/gdb/libiberty/config/mh-aix delete mode 100644 contrib/gdb/libiberty/config/mh-apollo68 delete mode 100644 contrib/gdb/libiberty/config/mh-cxux7 delete mode 100644 contrib/gdb/libiberty/config/mh-go32 delete mode 100644 contrib/gdb/libiberty/config/mh-hpbsd delete mode 100644 contrib/gdb/libiberty/config/mh-irix4 delete mode 100644 contrib/gdb/libiberty/config/mh-lynxos delete mode 100644 contrib/gdb/libiberty/config/mh-ncr3000 delete mode 100644 contrib/gdb/libiberty/config/mh-riscix delete mode 100644 contrib/gdb/libiberty/config/mh-sysv delete mode 100644 contrib/gdb/libiberty/config/mh-sysv4 delete mode 100644 contrib/gdb/libiberty/config/mt-sunos4 delete mode 100644 contrib/gdb/libiberty/config/mt-vxworks5 delete mode 100644 contrib/gdb/libiberty/configure.bat delete mode 100644 contrib/gdb/libiberty/configure.in delete mode 100644 contrib/gdb/libiberty/copysign.c delete mode 100644 contrib/gdb/libiberty/cplus-dem.c delete mode 100644 contrib/gdb/libiberty/dummy.c delete mode 100644 contrib/gdb/libiberty/fdmatch.c delete mode 100644 contrib/gdb/libiberty/floatformat.c delete mode 100644 contrib/gdb/libiberty/functions.def delete mode 100644 contrib/gdb/libiberty/getcwd.c delete mode 100644 contrib/gdb/libiberty/getopt.c delete mode 100644 contrib/gdb/libiberty/getopt1.c delete mode 100644 contrib/gdb/libiberty/getpagesize.c delete mode 100644 contrib/gdb/libiberty/getruntime.c delete mode 100644 contrib/gdb/libiberty/hex.c delete mode 100644 contrib/gdb/libiberty/index.c delete mode 100644 contrib/gdb/libiberty/insque.c delete mode 100644 contrib/gdb/libiberty/makefile.dos delete mode 100644 contrib/gdb/libiberty/memchr.c delete mode 100644 contrib/gdb/libiberty/memcmp.c delete mode 100644 contrib/gdb/libiberty/memcpy.c delete mode 100644 contrib/gdb/libiberty/memmove.c delete mode 100644 contrib/gdb/libiberty/memset.c delete mode 100644 contrib/gdb/libiberty/mpw-config.in delete mode 100644 contrib/gdb/libiberty/mpw-make.sed delete mode 100644 contrib/gdb/libiberty/mpw.c delete mode 100644 contrib/gdb/libiberty/msdos.c delete mode 100644 contrib/gdb/libiberty/obstack.c delete mode 100644 contrib/gdb/libiberty/random.c delete mode 100644 contrib/gdb/libiberty/rename.c delete mode 100644 contrib/gdb/libiberty/rindex.c delete mode 100644 contrib/gdb/libiberty/sigsetmask.c delete mode 100644 contrib/gdb/libiberty/spaces.c delete mode 100644 contrib/gdb/libiberty/strcasecmp.c delete mode 100644 contrib/gdb/libiberty/strchr.c delete mode 100644 contrib/gdb/libiberty/strdup.c delete mode 100644 contrib/gdb/libiberty/strerror.c delete mode 100644 contrib/gdb/libiberty/strncasecmp.c delete mode 100644 contrib/gdb/libiberty/strrchr.c delete mode 100644 contrib/gdb/libiberty/strsignal.c delete mode 100644 contrib/gdb/libiberty/strstr.c delete mode 100644 contrib/gdb/libiberty/strtod.c delete mode 100644 contrib/gdb/libiberty/strtol.c delete mode 100644 contrib/gdb/libiberty/strtoul.c delete mode 100644 contrib/gdb/libiberty/tmpnam.c delete mode 100644 contrib/gdb/libiberty/vasprintf.c delete mode 100644 contrib/gdb/libiberty/vfork.c delete mode 100644 contrib/gdb/libiberty/vfprintf.c delete mode 100644 contrib/gdb/libiberty/vmsbuild.com delete mode 100644 contrib/gdb/libiberty/vprintf.c delete mode 100644 contrib/gdb/libiberty/vsprintf.c delete mode 100644 contrib/gdb/libiberty/waitpid.c delete mode 100644 contrib/gdb/libiberty/xatexit.c delete mode 100644 contrib/gdb/libiberty/xexit.c delete mode 100644 contrib/gdb/libiberty/xmalloc.c delete mode 100644 contrib/gdb/libiberty/xstrdup.c delete mode 100644 contrib/gdb/libiberty/xstrerror.c diff --git a/contrib/gdb/gdb/.gdbinit b/contrib/gdb/gdb/.gdbinit deleted file mode 100644 index f60802e5009..00000000000 --- a/contrib/gdb/gdb/.gdbinit +++ /dev/null @@ -1,16 +0,0 @@ -echo Setting up the environment for debugging gdb.\n - -set complaints 1 - -b fatal - -b info_command -commands - silent - return -end - -dir ../mmalloc -dir ../libiberty -dir ../bfd -set prompt (top-gdb) diff --git a/contrib/gdb/gdb/ChangeLog-93 b/contrib/gdb/gdb/ChangeLog-93 deleted file mode 100644 index 463154d9ce8..00000000000 --- a/contrib/gdb/gdb/ChangeLog-93 +++ /dev/null @@ -1,7597 +0,0 @@ -Fri Dec 31 14:33:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * nindy-share/nindy.c: Fix order of arguments to store_unsigned_integer - (second and third arguments were reversed). - (say): Use varargs. - -Fri Dec 31 12:13:47 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * remote-mips.c: Add timeout parameter to mips_request and - mips_receive_packet. - (callers): pass in mips_receive_wait except mips_initialize (where - we use it to clean up the kludge where we had been changing - mips_receive_wait temporarily) and mips_wait (where we pass in - -1 for no timeout). - -Fri Dec 31 14:33:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stack.c (print_block_frame_locals): Also print LOC_BASEREG variables. - -Fri Dec 31 06:55:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symtab.c (find_methods): Call fprintf_symbol_filtered with DMGL_ANSI. - -Thu Dec 30 10:16:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * values.c (unpack_long): Fix garbled error message. - - * remote-mips.c (mips_error): New function. - * remote-mips.c: Use it instead of error() most places. - * remote-mips.c (mips_receive_packet): New arg throw_error. - (mips_initialize): Use it not catch_errors. - * defs.h: Declare error_pre_print and warning_pre_print here... - * main.c: ...not here. - - * breakpoint.c (breakpoint_chain): Make static. - * breakpoint.c, breakpoint.h (frame_in_dummy): New function. - * stack.c (print_frame_info): Use it. - -Thu Dec 30 07:41:36 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * exec.c (add_to_section_table): Check for SEC_ALLOC instead of - SEC_LOAD to handle .bss segments properly. - -Thu Dec 30 10:16:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (wait_for_inferior): Enable code which assumes that if - we jump into the prologue from another function, then it was a - subroutine call. #if 0 AT_FUNCTION_START; the above code should - take care of this case. - -Wed Dec 29 12:32:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valprint.c (val_print_string): Change chunksize from 200 - to 8. - - * symfile.c (generic_load): If no arguments, get file name - from get_exec_file. - - * c-exp.y: Revert Kung's change. "..." is not a type, and the - change caused "p (...)0" to dump core. - * gdbtypes.c (check_stub_method): Don't pass "..." to - parse_and_eval_type. This should fix the bug which Kung was - trying to fix. - - * stabsread.c (define_symbol): If we choose not to combine - two symbols, don't just ignore the second (LOC_REGISTER) one. - * printcmd.c (print_frame_args): If we have a LOC_ARG and a - LOC_REGISTER, use the LOC_ARG not the LOC_REGISTER. - -Tue Dec 28 15:08:00 1993 Fred Fish (fnf@deneb.cygnus.com) - - * solib.c (DEBUG_BASE): Remove macro and all references. - * solib.c (debug_base_symbols): Add array of symbols to lookup. - * solib.c (IGNORE_FIRST_LINK_MAP_ENTRY): Add macro. - * solib.c (look_for_base, locate_base): Use debug_base_symbols. - * solib.c (find_solib): Use IGNORE_FIRST_LINK_MAP_ENTRY. - -Tue Dec 28 12:06:57 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * c-exp.y : fix grammar to parse ellipsis (...) - -Mon Dec 27 18:42:14 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * stabsread.c (read_type): fix problem when reading static member - of a class. caused by change to allow :: inside template - instantiated name. - -Mon Dec 27 11:07:05 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbtypes.h: Expand on comments for TYPE_CODE_BITSTRING and - TYPE_CODE_STRING a bit. - - * m68k-tdep.c (m68k_skip_prologue, m68k_find_saved_regs): - Allow pea %fp; move.l %sp, %fp instead of link instruction to - set up the new frame. - - * main.c (init_main): Change "set remotedebug" back to var_zinteger - from var_boolean. - - * c-exp.y (yylex): Don't try to deal with nested types. - - * cp-valprint.c (cplus_print_value): Call check_stub_type on - TYPE_BASECLASS (type, i) before we look at its name. - - * dbxread.c: Move default definition of GCC_COMPILED_FLAG_SYMBOL - from here . . . - * symtab.h: . . . to here. - * dbxread.c (record_minimal_symbol): Move check for gcc{,2}_compiled. - and __gnu_compiled* from here . . . - * minsyms.c (prim_record_minimal_symbol_and_info): . . . to here. - * minsyms.c (prim_record_minimal_symbol): Call - prim_record_minimal_symbol_and_info rather than duplicating code. - * minsyms.c, symtab.h (prim_record_minimal_symbol{,_and_info}), - coffread.c (record_minimal_symbol), - xcoffread.c (RECORD_MINIMAL_SYMBOL), callers: Add objfile parameter. - -Sun Dec 26 20:44:02 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * dbxread.c (process_one_symbol): Handle stabs-in-som just like - stabs-in-elf. - (pastab_build_psymtabs): Likewise. - - * hppa-tdep.c: Change all comments to reference %r3 or frame - pointer rather than %r4. - (frame_chain, skip_prologue, dig_rp_from_stack): Handle %r3 as the - frame pointer. - - * config/pa/tm-hppa.h (FP_REGNUM): Define as %r3. - (FIND_FRAME_SAVED_REGS): Handle %r3 as frame pointer. - (CALL_DUMMY): Likewise. - -Sun Dec 26 16:59:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * exec.c (exec_file_command): If error occurs after we have opened - exec_bfd but before we call push_target, make sure to close exec_bfd. - - * infrun.c (wait_for_inferior): Remove confusing and inaccurate - stuff about subroutine calls, return, etc., from comment which - says "We've wandered out of the step range.". - -Sun Dec 26 09:18:10 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): When checking whether the line has - changed, check the symtab as well. - -Sun Dec 26 09:18:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbtypes.c (force_to_range_type): Use switch statement. - complain() not warning() if the TYPE_CODE isn't one we know how to - deal with gracefully. Use builtin_type_int not - lookup_fundamental_type (the objfile we passed to - lookup_fundamental_type was sometimes NULL). - - * valops.c (call_function_by_hand, push_word), defs.h (push_word), - convex-xdep.c, m88k-nat.c, i386m3-nat.c, mips-tdep.c, mipsm3-nat.c, - ns32km3-nat.c, remote-bug.c, m88k-tdep.c, remote-hms.c, remote-mips.c, - config/gould/tm-np1.h, hppa-tdep.c (hppa_fix_call_dummy), remote-vx.c: - Use REGISTER_SIZE, unsigned LONGEST, and - {store,extract}_unsigned_integer, instead of sizeof - (REGISTER_TYPE) and REGISTER_TYPE. - * All tm.h files: Change REGISTER_TYPE to REGISTER_SIZE. - * hppa-tdep.c (pa_print_fp_reg): Remove unused variable val. - - * Makefile.in (ALLDEPFILES): Remove i386ly-nat.c and m68kly-nat.c. - Add lynx-nat.c. - -Sat Dec 25 20:05:41 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (init_extra_frame_info): Correctly adjust the base - of the current frame when "fromleaf" is true. Do not adjust the - frame base of the innermost frame if it is a leaf function. - -Sat Dec 25 13:39:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (define_symbol): Only combine a p/r pair into a - LOC_REGPARM if REG_STRUCT_HAS_ADDR. - -Sat Dec 25 09:50:29 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * valops.c (value_struct_elt): Check for (value)-1 return from - search_struct_method. - -Sat Dec 25 09:50:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * defs.h: Move definitions of TARGET_*_BIT after include of tm.h. - The old way (using #undef in tm.h) was ugly and asking for - trouble, because it makes it possible for some file to use the - wrong definition. Move definition of HOST_CHAR_BIT after definition - of TARGET_CHAR_BIT. - * config/alpha/tm-alpha.h, config/h8300/tm-h8300.h, - config/h8500/tm-h8500.h, config/z8k/tm-z8k.h: Don't undef TARGET_*_BIT - before defining them. - - * mdebugread.c: Change the builtin_type_* in this file to - mdebug_type_* and make them static. Use TYPE_CODE_ERROR for - complex and float decimal. - - * printcmd.c (disassemble_command): Call wrap_here between printing - address and printing instruction. - -Fri Dec 24 14:23:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (read_type): Don't fall through 'S' case (the case it - was falling though happened to do the right thing ("break;") but that - is hardly a good thing to assume). - -Tue Dec 21 13:32:02 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * ch-exp.y (match_dollar_tokens): Fix off-by-one bug. - * ch-lang.c (chill_is_varying_struct), ch-lang.h: New function. - * ch-lang.c (chill_printstr): Use double quotes, not single quotes. - * ch-typeprint.c (chill_type_print_base): Handle TYPE_CODE_BITSTRING. - Improve printing of TYPE_CODE_STRING, TYPE_CODE_SET, and - TYPE_CODE_STRUCT (including checking chill_is_varying_struct). - Print TYPE_DUMMY_RANGE by printing its TYPE_TARGET_TYPE. - Handle TYPE_CODE_ENUM. - * ch-valprint.c (chill_val_print): Handle TYPE_CODE_BITSTRING. - For TYPE_CODE_STRING, never print address. Handle VARYING strings. - * gdbtypes.c (force_to_range_type): New. - * gdbtypes.c (create_set_type): Make work, following Chill layout. - * gdbtypes.h (TYPE_LOW_BOUND, TYPE_HIGH_BOUND, TYPE_DUMMY_RANGE): New. - * stabsread.c (read_type): Distinguish string and bitstring from - char-array and set. - * valarith.c (value_subscript), valops.c (value_coerce_array): - Handle STRINGs as well as ARRAYs. - * valarith.c (value_bit_index): Fix think. Use new macros. - - -Fri Dec 17 10:45:32 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * symtab (decode_line_1): fix a bug when position char is not - set correctly. - * c-valprint (c_val_print): handle vtbl printing when vtbl is not - set up yet. - -Thu Dec 16 16:46:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-tdep.c (read_next_frame_reg): If SIGFRAME_REG_SIZE is not - defined, define it as 4. - -Thu Dec 16 13:08:01 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * config/m68k/nm-hp300bsd.h: Correctly identify 4.3BSD vs 4.4BSD. - - * config/m68k/tm-hp300bsd.h (REMOTE_BPT_VECTOR): Define. - - * config/m68k/tm-m68k.h (REMOTE_BPT_VECTOR): Allow targets to - override. - (REMOTE_BREAKPOINT): Likewise. - -Thu Dec 16 09:14:58 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (read_hp_function_type): Correctly handle - pass-by-value structures > 64bits in size. - (process_one_debug_symbol): Likewise. - -Mon Dec 13 20:17:39 1993 Per Bothner (bothner@kalessin.cygnus.com) - - Implement support for Chill POWERSETs. - * ch-exp.y (operand_2): Implement 'Element IN PowerSet'. - * ch-typeprint.c (chill_type_print_base): Handle POWERSETs. - * ch-valprint.c (chill_val_print): Handle TYPE_CODE_SET. - * eval.c (evaluate_subexp): Implement BINOP_IN. - * expression.h (enum exp_opcode): Added BINOP_IN. - * gdbtypes.c (create_set_type), gdbtypes.h: New function. - * stabsread.c (read_type): If 'S', create a set type. - * valarith.c (value_bit_index, value_in), value.h: New functions, - for indexing in SETs. - -Mon Dec 13 06:42:37 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * paread.c (pa_symfile_init): Check for the existance of stabs - after DBX_TEXT_SECT has been initialized. - -Tue Nov 23 17:29:28 1993 Steve Chamberlain (sac@jonny.cygnus.com) - - * config/h8300/tm-h8300.h (BREAKPOINT): Insn changed to sleep. - (DECP_PC_AFTER_BREAK): Now is 0. - * config/h8500/tm-h8500.h (REGISTER_BYTES, REGISTER_BYTE, - REGISTER_NAMES): update to new view. (INIT_EXTRA_FRAME_INFO): No - extra frame info now. - * config/sh/sh.h (NOP): Define NOP insn. - * config/z8k/tm-z8k.h (BIG): is now sim_z8001_mode. - * config/z8k/z8ksim.mt (TDEPFILES): Add remote-sim.o to list. - * ser-go32.c: Lint. (strncasecmp): Removed, now in libiberty. - (go32_readchar): Special handling for faster polling. (async - structure): Volatile. - * h8300-tdep.c (print_register_hook): Allocate and use the right - number bytes for the raw register. - * h8500-tdep.c (regoff, frame_find_saved_reg, examine_prologue): - deleted. (h8500_register_size, h8500_register_virtual_type, ): - Use new way of counting registers. - * remote-e7000.c (echo_index): deleted. (expect): Better handling - of user interrupts. (expect_prompt): Remove never used log file - support. (want, want_nopc): Add support for H8/300H. - (fetch_regs_from_dump): Treat \r and \n as whitespace. - (e7000_drain): Send an "end" command before waiting for output to - stop. (e7000_wait): Cope with H8/300H, better handling of user - interrupts. (why_stop, expect_n, sub2_from_pc): New function. - * remote-utils.c (gr_load_image): call fflush and QUIT more regularly. - * utils.c (notice_quit): New function for polling for user interrupts. - -Fri Dec 10 15:53:56 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * stabsread.c (read_array_type): Allow negative array bounds, - without interpreting that to mean "adjustable." - * ch-valprint.c (chill_val_print): Handle RANGE types. - * ch-typeprint.c (chill_type_print_base): Handle BOOL. - Handle variant records. Handle RANGE types. - -Tue Dec 7 15:41:32 1993 Ian Lance Taylor (ian@cygnus.com) - - * config/mips/idt.mt: Use tm-idt.h instead of tm-bigmips.h. - * config/mips/idtl.mt: Use tm-idtl.h instead of tm-mips.h. - * config/mips/tm-idt.h, config/mips/tm-idtl.h: New files; use - different BREAKPOINT value for IDT. - - * mipsread.c: Include bfd.h and coff/sym.h. - -Mon Dec 6 16:34:10 1993 K. Richard Pixley (rich@cygnus.com) - - * ser-unix.c (set_tty_state): set the rest of the terminal state - pieces. - -Mon Dec 6 12:01:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Recognize mips* for all mips targets. - (mips*el-*-elf*, mips*-*-elf*): New targets; use idt and idtl. - - Added Irix 5 support. - * configure.in (mips-sgi-irix5*): New host and target. Use irix5 - for both. - * config/mips/irix5.mh, config/mips/irix5.mt, - config/mips/xm-irix5.h, config/mips/nm-irix5.h, - config/mips/tm-irix5.h, irix5-nat.c: New files for Irix 5 support. - * mdebugread.c: New file, split out of mipsread.c. Added - elfmdebug_build_psymtabs routine. Added some checks on external - symbols. Changed code to keep ecoff_debug_info and - ecoff_debug_swap structs in the psymtab and in global pointers - rather than retrieving them from the bfd. Also changed to keep - the pending list with the psymtab rather than the objfile (each - psymtab for a single objfile points to the same pending list). - * mipsread.c: Bulk of file moved into mdebugread.c, leaving just - the sym_fns. - * Makefile.in (SFILES): Added mdebugread.c. - (OBS): Added mdebugread.o. - (mdebugread.o): New target. - * symfile.h: Declare mdebug_build_psymtabs and - elfmdebug_build_psymtabs. - * elfread.c (struct elfinfo): Added mdebugsect field. - (elf_locate_sections): Remember location of .mdebug section. - (elf_symfile_read): Call elfmdebug_build_psymtabs on .mdebug - section. - * infrun.c (AT_FUNCTION_START): Set to 0 if not already defined. - (wait_for_inferior): Use AT_FUNCTION_START if it is defined to see - if PC is at the start of a function. - * mips-tdep.c (read_next_frame_reg): Use SIGFRAME_REG_SIZE, and - give it a default definition. - (mips_skip_prologue): Skip instructions which initialize $gp - register. - (in_sigtramp): New procedure, moved in from mipsread.c. - * config/mips/tm-mips.h: Declare in_sigtramp. - - * serial.h (serial_fdopen): Make parameter const to match - function definition. - -Fri Dec 3 14:20:43 1993 Stu Grossman (grossman at cygnus.com) - - * config/mips/irix4.mh: Enable ser-tcp.o. - -Tue Nov 30 15:24:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * Makefile.in (check): Do not use subdir_do, so that - TARGET_FLAGS_TO_PASS is used correctly. - -Mon Nov 29 16:10:38 1993 Stu Grossman (grossman at cygnus.com) - - * i386-nlmstub.c: Undo I/O redirection changes by Tom Lord. - These definitely won't work under Netware. - -Mon Nov 29 15:34:58 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * stabsread.c(read_struct_field): Fix the check when getting to - member functions. - -Mon Nov 29 16:48:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - gcc -Wall -O lint: - * mips-tdep.c (heuristic_proc_desc): Initialize reg30 to avoid - warning. Unnest comment. - (init_extra_frame_info): Remove unused variable mask. - (MASK): Fully parenthesize. - (mips_push_dummy_frame): Remove unused variable val. - (mips_skip_prologue): Remove unused variables f and b. - -Mon Nov 29 12:23:25 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_symbol, parse_partial_symbols): Do not create - (partial) symbols for opaque struct definitions. - -Mon Nov 29 11:36:57 1993 Stu Grossman (grossman at cygnus.com) - - * i386ly-tdep.c (i386lynx_saved_pc_after_call): Change call_inst - to unsigned char to avoid domain warning for some values. - -Mon Nov 22 23:42:59 1993 Steve Chamberlain (sac@jonny.cygnus.com) - - * remote-e7000.c (e7000_wait): Cope with H8/300 register dump. - * config/h8300/h8300hms.mt: Add remote-e7000. - -Mon Nov 22 11:03:45 1993 Fred Fish (fnf@cygnus.com) - - Merged changes from kev@spuds.geg.mot.com (Kevin A. Buettner): - * gdb/config/m88k/delta88.mh (NATDEPFILES): Added corelow.o and - coredep.o to this list. - * gdb/m88k-nat.c (m88k_register_u_addr): Avoid error when passed - the number for an M88110 extended register by just returning the - address of r0. - -Sat Nov 20 09:20:51 1993 Fred Fish (fnf@rtl.cygnus.com) - - * go32-xdep.c (re_comp, re_exec): Remove stubs now that gdb - always uses it's own version of regex. - -Fri Nov 19 18:23:19 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * valops.c(value_struct_elt_for_reference): enhance search operator in - c++. - * symtab.c(decode_line_1): same as above. - -Fri Nov 19 15:08:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c (decode_line_1): Add comment about use of - return_to_top_level directly instead of error. Add comment saying - that the '' should not be needed--that the completer should be fixed. - -Fri Nov 19 11:00:33 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * symtab.c(decode_line_1): fix the inconsistency of setting - breakpoint with '' or without them. The '' is needed when you - want name completion. - -Thu Nov 18 08:25:50 1993 Fred Fish (fnf@cygnus.com) - - * valprint.c (val_print_string): When looking for a null - terminator compare current bufsize to fetchlimit to determine - when to stop, instead of computing buffer+fetchlimit which - may overflow for very large limits (like "unlimited"). - -Wed Nov 17 18:23:09 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * eval.c(evaluate_subexp): to use unified search so type conversion - operator works in calling method. - * valarith.c(value_x_binop, value_x_unop): same as above. - * valops.c(search_struct_method): same as above. - -Wed Nov 17 18:47:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mipsread.c: Change use of ECOFF information to correspond to - changes in bfd/libecoff.h. - (mipscoff_symfile_offsets): Made static. - -Wed Nov 17 09:43:31 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * valops.c (typecmp): improve prototype matching when calling - a method. Make 'p (*(ostream *) &cout) << "lll" ' to work. - * eval.c(evalute_subexp): fix operator search problem when call - like p x.'operator+'(i). - -Tue Nov 16 17:15:03 1993 Stu Grossman (grossman at cygnus.com) - - * i386ly-nat.c, i386lynx-nat.c, m68kly-nat.c: Remove. Move - common code into lynx-nat.c. - * lynx-nat.c: New module. Contains portable code for Lynx native - stuff (mostly ptrace related). - * config/i386/i386lynx.mh (NATDEPFILES): i386ly-nat.o -> lynx-nat.o - * config/m68k/m68klynx.mh (NATDEPFILES): i386ly-nat.o -> lynx-nat.o - - * config/nm-lynx.h, config/tm-lynx.h: New files to contain - non-architecture specific native and target defs. - * config/i386/nm-i386lynx.h, config/i386/tm-i386lynx.h, - config/m68k/nm-m68klynx.h, config/m68k/tm-m68klynx.h: Move all - (arch) portable stuff into ../{tm nm}-lynx.h. - -Tue Nov 16 13:33:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c (gdb_mangle_name): Only assume that the physname is - the entire mangled name if it looks like the mangled name of a - constructor. Needed for testsuite to work with GCC 2.4.5. - - * a68v-nat.c: Replace with new version from Troy Rollo. The - version I am replacing appears to be an old copy of sun3-nat.c. - * dstread.c (dst_symfile_read): Replace sort_all_symtab_syms call - with loop. - - * Makefile.in (TAGS): Depend on TAGFILES_{NO,WITH}_SRCDIR. - - * Makefile.in: (HFILES,TAGFILES): Split into _WITH_SRCDIR and - _NO_SRCDIR versions. - (TAGS): Only add srcdir to TAGFILES_NO_SRCDIR. - (This is part of a long saga involving me putting srcdir on - everything (perhaps for now-obsolete reasons, I forget), Rich - removing the srcdir from everything, Stu putting it back some - places for Sun make, and me just now getting around to fixing - `make TAGS' again). - -Mon Nov 15 12:29:10 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * stack.c(print_frame_info): print demangled function name - ansi style. - -Mon Nov 15 14:32:29 1993 Steve Chamberlain (sac@jonny.cygnus.com) - - * remote-e7000.c: New file to cope with the Hitachi E7000 ICE. - * remote-utils.c, remote-utils.h (gr_load_image): New function to - download to target. - * h8300-tdep.c, h8500-tdep.c, remote-z8k.c, sh-tdep.c z8k-tdep.c - (sim_load): delete. - * remote-sim.c (gdbsim_load): Use gr_load_image, rather than - sim_load. - * config/sh/sh.mt: Add remote-e7000 - -Mon Nov 15 11:38:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/i386/linux.mh: Remove XM_CLIBS, TERMLIB, SYSV_DEFINE, and - REGEX. - * config/i386/xm-linux.h: Don't include xm-i386v.h. Define - HOST_BYTE_ORDER ourselves. Define HAVE_TERMIOS not HAVE_TERMIO. - Define NEED_POSIX_SETPGID. Include unistd.h. - -Mon Nov 15 12:29:10 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * symtab.c(gdb_mangle_name): fix the problem with constructor - name mangling. - -Mon Nov 15 11:38:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbtypes.h: Add TYPE_FLAG_TARGET_STUB. - * gdbtypes.c (check_stub_type): On TYPE_FLAG_TARGET_STUB, do - what cleanup_undefined_types does for arrays, except we clear - TYPE_FLAG_TARGET_STUB if we fix up the type. - * stabsread.c (cleanup_undefined_types): Add comments about how - doing arrays here is no longer the clean way to do it. - (read_array_type): Set TYPE_FLAG_TARGET_STUB as well as calling - add_undefined_type. - * c-typeprint.c, ch-typeprint.c: Move call to check_stub_type - outside switch so it happens for all type codes. - * cp-valprint.c (cp_print_value_fields): Recurse to val_print, - instead of c_val_print, so that check_stub_type gets called. - - * gdbtypes.h, gdbtypes.c, m2-lang.c, ch-lang.c, c-lang.c: Remove - TYPE_FLAG_SIGNED. It was inconsistently set, never checked - (except in recursive_dump_type), and is pointless. - -Mon Nov 15 00:40:38 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * paread.c (pa_symfile_init): Look for the $TEXT$ section rather - than the .text section. - -Sun Nov 14 00:28:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c: Remove #if 0'd dbx_class_complaint. We now handle - this (more or less) gracefully, and complain() was never a good - way of dealing with this. - - * stabsread.c (read_type): Skip the colon when reading a - cross-reference. Only complain, not error_type, on unrecognized - cross-reference types. error_type, not dump core, if the colon is - missing. - -Fri Nov 12 16:23:08 1993 Stu Grossman (grossman at cygnus.com) - - * config/m68k/tm-sun3.h: Disable use of alternate breakpoint insn - when doing remote stuff. - -Fri Nov 12 16:22:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * c-exp.y (yylex): Call lookup_symtab not lookup_partial_symtab. - - * partial-stab.h: Ignore ':' symbol descriptors. Same case as - Kung's stabsread.c change. - -Fri Nov 12 11:18:02 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * stabsread.c (patch_block_stabs, define_symbol, read_type): in - g++ template instantiation, nested class can be part of the - params, and '::' can gets into symbol or type names. This is - to fix the problem. - - * gdbtypes.c (lookup_struct_elt_type): Handle type ref or pointer - to struct/union case. - -Fri Nov 12 10:39:31 1993 Stu Grossman (grossman at cygnus.com) - - * coff-solib.c (coff_solib_add): Cast result of alloca(). - * m68k-tdep.c (m68k_saved_pc_after_call): Get rid of - GDB_TARGET_IS_SUN3. Use more general SYSCALL_TRAP macro. - * config/m68k/m68klynx.mh (NATDEPFILES): Remove exec.o (it's - already in TDEPFILES). - * config/m68k/tm-m68k.h (SAVED_PC_AFTER_CALL): Use - m68k_saved_pc_after_call. - * Remove all Sun3 specific stuff. - * (FIX_CALL_DUMMY): Cast arg to bfd_putb32 to unsigned char *. - * config/m68k/tm-m68klynx.h: Define SYSCALL_TRAP as trap #10. - Disable REMOTE_BREAKPOINT mechanism. - * config/m68k/tm-sun3.h: Get rid of GDB_TARGET_IS_SUN3. - * Protect from multiple includion. - * Move Sun3 specific stuff from tm-m68k.h to here. - * Define SYSCALL_TRAP as trap #0. - * Remove def of SAVED_PC_AFTER_CALL (now in tm-m68k.h). - * gdbserver/low-lynx.c: Redo all register store/fetch stuff to - make it portable for 386 and 68k. - -Fri Nov 12 09:53:26 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mips-tdep.c (init_extra_frame_info): Check to see whether the - registers mentioned in the proc_desc have been saved. This - generalizes mips_in_lenient_prologue in the sense that we keep - searching until we've found saves for all the registers, not just - look for a "lenient prologue" pattern. - * mips-tdep.c: #if 0 lenient prologue code. - - * mips-tdep.c (heuristic_proc_desc): Don't assume a host short - is 16 bits. - -Thu Nov 11 19:58:05 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/i386/i386sol2.mh: Comment out corelow.o. - - * printcmd.c (address_info): Use filtered, not unfiltered functions. - We should be able to deal with a QUIT here. - -Thu Nov 11 15:22:20 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * printcmd.c (address_info): Use fprintf_symbol_filtered - to print the symbol name. - - * stabsread.c (define_symbol): Handle cfront lossage for - struct/union/enums and typedefs. - - * partial-stab.h (case N_BINCL): Update psymtab_language - as appropriate when changing subfiles. - (case N_SOL): Update psymtab_language as appropriate when - changing subfiles. Add typedef for structs, unions, and enums - when processing C++ files. - -Thu Nov 11 13:18:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * README: Remove information on languages and just cite the (newly - updated) information in doc/gdb.texinfo instead. - - * delta68-nat.c: Fix typos (add missing ");" and stuct -> struct). - -Wed Nov 10 09:31:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c (process_one_symbol, N_RBRAC): Don't clear - within_function just because local_symbols is NULL. It appears - that this bug has existed since the 10 Apr 89 change which started - clearing within_function here. - - * config/m68k/tm-m68k.h: Clean up CALL_DUMMY comment. - * config/m68k/{tm-hp300bsd.h,tm-hp300hpux.h,tm-m68k-em.h, - tm-monitor.h,tm-sun3.h,tm-vx68.h}, config/sparc/tm-sparc.h: - Define BELIEVE_PCC_PROMOTION. - * dbxread.c: Remove BELIEVE_PCC_PROMOTION define. The code which - used this was moved to stabsread.c a long time ago. - - * dstread.c (dst_sym_fns): Update for flavours. - * symfile.c (find_sym_fns): Add kludge for apollo like for rs/6000. - * dstread.c (dst_symfile_offsets): Set objfile->num_sections. - - gcc -Wall lint: - * thread.c: Include "gdbcmd.h" and . - * Makefile.in: Update dependency. - * thread.c (thread_command): Remove unused variable p. - * values.c (unpack_double): Use len instead of TYPE_LENGTH (type). - * valprint.c (print_floating): Correctly check sign bit now that - we are using unsigned arithmetic. - * symtab.c (find_pc_line_range): Remove unused variables exact_match, - ind, and l. - -Tue Nov 9 17:42:25 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * valarith.c (value_x_binop): fix search operator in class bug - * valarith.c (value_x_unop): fix search operator in class bug - -Tue Nov 9 19:20:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (init.c): Add udi2go32.o to list of files that we - should not try to search for _initialize_* functions. - - * remote-udi.c (udi_wait): Change UDIGdb_StdoutReady back to - UDIStdoutReady. It accidentally got changed on 24 Oct 93 when - stdout was changed to gdb_stdout. Likewise for UDIGetStdout, - UDIStderrReady, and UDIGetStderr. - -Tue Nov 9 12:48:06 1993 Tom Lord (lord@cygnus.com) - - * remote-hms.c (hms_wait): fixed too many arguments to putc_unfiltered. - -Tue Nov 9 12:20:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c (quit): Also call gdb_flush on standard output and error. - - * .gdbinit: Remove "source /.gdbinit". It causes a spurious error - if /.gdbinit doesn't exist (and I know of no convention of putting - something in /.gdbinit). - -Mon Nov 8 18:17:11 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cp-valprint.c (cp_print_value_fields): change output from to - -Mon Nov 08 17:05:30 1993 Jeffrey Wheat (cassidy@cygnus.com) - - * Makefile.in: Change RUNTEST_FLAGS back to RUNTESTFLAGS - Change RUNTEST = runtest to test for existance of - a runtest in the source tree first. - -Mon Nov 8 10:42:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Remove unused variable GCC. Remove "#CC=cc" line - which doesn't really relate to anything. - - * Makefile.in (CC_FOR_TARGET): Test for existence of gcc/xgcc, not - for existence of gcc/Makefile. - - * inflow.c (terminal_init_inferior), infptrace.c (child_resume): - Add comments about use of Lynx PIDGET and how we will want to - clean it up. - - * stabsread.c: Remove long_kludge_name code (it was already #if 0). - * stabsread.c (read_one_struct_field): Clean up comments to reflect - Kung's change of 5 Nov 93. - * stabsread.c (read_one_struct_field): Don't give up on unknown - visibility character, just shove it in fip->list->visibility. - (read_baseclasses): Don't give up on unknown virtual or visibility - characters, just assume a reasonable default, complain, and keep - going. - (attach_fields_to_type): Complain on unrecognized visibility. - One result of all this is that '9' (VISIBILITY_IGNORE) can be used - in a stab as well as being something which GDB uses internally. - -Mon Nov 8 07:57:30 1993 Doug Evans (dje@canuck.cygnus.com) - - * configure.in: Remove h8300h, we have multilib now. - -Mon Nov 8 06:11:24 1993 D. V. Henkel-Wallace (gumby@cirdan.cygnus.com) - - * configure.in: Add unixware as a configuration alias for x86 - sysv4 - - * config/i386/i386nw.mt: add i387-tdep.o, exec.o to TDEPFILES - -Sun Nov 7 23:49:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symtab.c (decode_line_1, decode_line_2): Do not adjust pc by - FUNCTION_START_OFFSET if funfirstline is not set. - -Fri Nov 5 17:19:30 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * gdbtypes.h : add a field 'ignore_field_bits in cplus_specific, - and macros to handle the bits. - * stabsread.c (read_one_struct_field): add VISIBILITY_IGNORE, and - for field of length 0, set this bit on. - * cp-valprint.c (cp_print_value_fields): for VISIBILITY_IGNORE - field, print . - -Fri Nov 5 14:43:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Version 4.11.2. - -Fri Nov 5 09:49:22 1993 Stu Grossman (grossman at cygnus.com) - - * inflow.c (terminal_init_inferior): Temporarily use Lynx PIDGET - macro to set process groups. - * infptrace.c (child_resume): Temporarily use Lynx PIDGET to - specify resumption of all threads. - * infrun.c (wait_for_inferior): Fix handling of thread-specific - breakpoints for systems where DECR_PC_AFTER_BREAK > 0 (ie: backup - PC by the right amount when continuing the thread). - * thread.c (thread_apply_command): Add the `thread apply' - command to apply a given GDB command to a list of threads. - -Fri Nov 5 05:58:03 1993 Jim Kingdon (kingdon@cygnus.com) - - * Makefile.in (init.c): Don't call sed if filename is empty. - -Thu Nov 4 08:27:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c (unknown_symchar_complaint): Make message refer to - "symbol descriptor" not "symbol type character" for consistency - with stabs.texinfo terminology. - - * stabsread.c (read_struct_fields): Accept either '$' or '.' as - the character which introduces a cpp_abbrev or anonymous type. - - * c-lang.c (c_printstr): Print "" to stream (like all the other - output from this function), not gdb_stdout. - - * dbxread.c (process_one_symbol): Do relocate 'S' symbols by - the text offset (revert 12 Oct 93 change). - - * configure.in: Make hppa*-*-hiux* use hppahpux, - not non-existent hppahiux. - -Wed Nov 3 16:24:09 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * values.c (value_fn_field): when physical name not found, do not - error, but return null. - * valops.c (value_struct_elt): when name and args match does not - mean it is the one, some times a typedef class can have the same - member method and args. This probably will not happen with new - version of g++, but it does happen in old g++ and cause gdb error. - -Wed Nov 3 09:20:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - Merge changes for dos x udi: - * Makefile.in (udi2go32.o): add rule to build this file - * 29k-share/udi/udi2go32.c: new file - * config/a29k/a29k-udi.mt: add udi2go32.o - * 29k-share/udi/{udr.c, udip2soc.c}: #ifdef out the entire file - if __GO32__ is defined. What a hack. - -Wed Nov 3 09:20:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote.c (putpkt, getpkt): Don't call interrupt_query. - - * findvar.c (value_of_register): Rename val to reg_val to avoid - name conflict with some (e.g. tm-m68k.h) REGISTER_CONVERT_TO_VIRTUAL. - - * main.c: Add variables source_line_number, source_file_name, - source_error, source_error_allocated, and source_pre_error. - (command_line_input): If source_file_name set, increment - source_line_number and set error_pre_print with them. - (source_command): Set source_* and make a cleanup so they get - set back. - -Tue Nov 2 16:28:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stack.c (down_silently_command): Add comment about PR 1913. - - * breakpoint.c (insert_breakpoints, delete_breakpoint): Call - target_terminal_ours_for_output before attempting output. - - * fork-child.c (fork_inferior): Fix comment so that it suggests - "set shell" rather than having "set env SHELL" affect GDB's - operation. - -Tue Nov 2 15:03:08 1993 Tom Lord (lord@rtl.cygnus.com) - - * utils.c (vfprintf_unfiltered): don't use maybe_filtered - since it involves a fixed size buffer. - -Tue Nov 2 13:42:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * findvar.c (value_of_register, value_from_register), - hppa-tdep.c (pa_print_fp_reg), infcmd.c (do_registers_info), - valops.c (value_assign): Use REGISTER_CONVERT_TO_* only if - REGISTER_CONVERTIBLE is defined, otherwise just copy the content. - Pass desired type to REGISTER_CONVERT_TO_*. - - * config/m68k/tm-m68k.h, config/i960/tm-i960.h (REGISTER_CONVERT_*): - Pass length of desired type to store/extract_floating. - * config/i386/tm-arm.h, config/i386/tm-i386aix.h, - config/i386/tm-sun386.h, config/i386/tm-symmetry.h, - config/m88k/tm-m88k.h config/rs6000/tm-rs6000.h (REGISTER_CONVERT_*): - Use extract_floating and store_floating with length of desired type. - * config/m68k/tm-news.h (STORE,EXTRACT_RETURN_VALUE): Add type - parameter to REGISTER_CONVERT_*. - - * config/a29k/tm-a29k.h, config/convex/tm-convex.h, - config/gould/tm-np1.h, config/gould/tm-pn.h, config/h8300/tm-h8300.h, - config/h8500/tm-h8500.h, config/i386/tm-i386v.h, - config/mips/tm-mips.h, config/ns32k/tm-merlin.h, - config/ns32k/tm-umax.h, config/pa/tm-hppa.h, config/pyr/tm-pyr.h, - config/sh/tm-sh.h, config/sparc/tm-sparc.h, config/tahoe/tm-tahoe.h, - config/vax/tm-vax.h, config/z8k/tm-z8k.h (REGISTER_CONVERTIBLE, - REGISTER_CONVERT_TO_RAW, REGISTER_CONVERT_TO_VIRTUAL): Remove - versions for which REGISTER_CONVERTIBLE is always false. - * z8k-tdep.c (register_convert_to_virtual, register_convert_to_raw): - Remove, no longer used. - - * alpha-tdep.c (alpha_register_convert_to_raw, - alpha_register_convert_to_virtual): New routines to handle - the different raw formats in alpha floating point registers. - * config/alpha/tm-alpha.h (REGISTER_CONVERTIBLE, - REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Use them. - -Tue Nov 2 12:45:23 1993 Stan Shebs (shebs@rtl.cygnus.com) - - * gdbserver/configure.in: Recognize *-*-lynxos* instead of - *-*-lynx*, recognize sparc-*-lynxos*. - * gdbserver/Makefile.in (install, install_only): Add. - * gdbserver/gdbserver.1: New file, man page for gdbserver. - -Tue Nov 2 03:01:01 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Include and . Change include - of "libhppa.h" to "som.h". - (BYTES_IN_WORD): Define. - (hppa_sym_fns): "hppa" is 4 characters, not 5. - -Mon Nov 1 09:40:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c, symtab.h, source.c: Change find_line_pc_range to take - a struct symtab_and_line argument, rather than a symtab and a line. - Re-write it to be based on the address rather than bogusly adding - one to the line number and hoping that has something to do with the - end of the line. - - * config/m88k/m88k.mh (NATDEPFILES): Remove exec.o. - - * paread.c (pa_symtab_read): Change comments to say ignoring - labels really should be handled by the assembler/compiler. - - * Makefile.in: Add -O to CXXFLAGS. - - * TODO: Expand comments on fast watchpoints. - -Sun Oct 31 19:45:06 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * paread.c (pa_symtab_read): Also filter out local symbols - starting with "L$". - -Sun Oct 31 09:28:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symfile.h (sym_fns), symfile.c (find_sym_fns), xcoffread.c, - coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c, paread.c: - Change from using bfd target name to using the flavour. - - * objfiles.h, infcmd.c, symfile.c: Add comments about how various - objfiles get created and when we should blow them away. - -Sat Oct 30 08:32:53 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symfile.c (reread_symbols): When re-reading symbols, do all the - right operations ourself, rather than calling symbol_file_command. - If we re-read something, call clear_symtab_users not just - breakpoint_re_set. - * objfiles.h, objfiles.c (build_objfile_section_table): No longer - static. - * symfile.c (clear_symtab_users): Call clear_pc_function_cache. - * coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c, paread.c - (*_symfile_offsets): Set objfile->num_sections. - * remote.c (remote_wait), symfile.c (syms_from_objfile): - Don't muck with objfile->num_sections now that all the symbol - readers set it. - * elfread.c: Clean up obsolete comment about handling only DWARF. - * paread.c: Remove comment about how we should use an "ordinary" - file format with an hppa suffix. There is nothing ordinary about SOM. - - * config/i386/{i386m3.mh,i386mk.mh}, config/mips/mipsm3.mh, - config/ns32k/ns32km3.mh: Change MMALLOC_LIB to MMALLOC. - * TODO: Update Mach stuff. - -Fri Oct 29 16:30:36 1993 Stan Shebs (shebs@rtl.cygnus.com) - - LynxOS support: - * configure.in: Change *-*-lynx* to *-*-lynxos*, add - sparc-*-lynxos*. - * Makefile.in (ALLDEPFILES): Add m68kly-nat.c, sparcly-nat.c. - Rename i386lynx-nat.[co] to i386ly-nat.[co]. - (ALLCONFIG): Add config/{m68k,sparc}/{m68k,sparc}lynx.m[ht]. - (m68kly-nat.o, sparcly-nat.o): Add rules. - * i386ly-tdep.c: Cosmetics. - * i386lynx-nat.c: Removed. - * i386ly-nat.c: New file, was i386lynx-nat.c. - * m68kly-nat.c: New file. - * sparcly-nat.c: New file. - * config/xm-lynx.h: New file, cpu-independent host info. - * config/i386/i386lynx.mh: Changes for consistency. - * config/i386/i386lynx.mt: Ditto. - * config/i386/tm-i386lynx.h: Ditto. - * config/i386/nm-i386lynx.h: Ditto. - * config/i386/xm-i386lynx.h: Include config/xm-lynx.h. - * config/m68k/m68klynx.mh, config/m68k/m68klynx.mt, - config/m68k/tm-m68klynx.h, config/m68k/nm-m68klynx.h, - config/m68k/xm-m68klynx.h: New files, M68K LynxOS support. - * config/sparc/sparclynx.mh, config/sparc/sparclynx.mt, - config/sparc/tm-sparclynx.h, config/sparc/nm-sparclynx.h, - config/sparc/xm-sparclynx.h: New files, Sparc LynxOS support. - -Fri Oct 29 08:11:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * defs.h, findvar.c (extract_floating, store_floating): New functions. - * Move SWAP_TARGET_AND_HOST from defs.h to findvar.c because it is - now used only by extract_floating and store_floating. - * valprint.c (print_floating): Use unsigned arithmetic. Use - extract_unsigned_integer instead of SWAP_TARGET_AND_HOST. - Change sizeof (float) to 4 and sizeof (double) to 8 (those are always - the relevant sizes for this code, which is in #ifdef IEEE_FLOAT). - * values.c (unpack_long, unpack_double, value_from_double), - valarith.c (value_binop), stabsread.c (define_symbol): - Use extract_floating and store_floating instead of - SWAP_TARGET_AND_HOST. - * config/m68k/tm-m68k.h, config/i960/tm-i960.h (REGISTER_CONVERT_*): - Use extract_floating and store_floating. - * config/m88k/tm-m88k.h: Add comments (it should be doing the same). - * i386-tdep.c (i386_extract_return_value), - * remote-nindy.c (nindy_store_registers): Use store_floating. - -Fri Oct 29 09:31:38 1993 Steve Chamberlain (sac@rtl.cygnus.com) - - * remote-sim.c (gdbsim_store_register): Change var name so - it compiles with non-ANSI compilers. - -Fri Oct 29 08:11:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Add idea for "disassemble" with source. - -Fri Oct 29 00:41:01 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.11.1 after release and cvs - tagging. - -Thu Oct 28 09:14:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Add section on Mach. Stop calling it a "bug list". - Remove John's name and email address. Remove item on "always" - ("hook-stop" takes care of this). Remove item on executables with - no symbols (this works on some machines, at least). Remove item - about calling error() during symbol reading (I think all the important - ones have been cleaned up). Revise items about signals and remote - systems. Remove section on ^Z requiring several continues to make - it go (this now works. Perhaps the item is based on confusion over - programs (like GDB itself) which catch SIGTSTP and then re-send - themselves the signal. PR 2575 might contain relevant info). - -Thu Oct 28 16:55:34 1993 Fred Fish (fnf@cygnus.com) - - * NEWS: Note improvements in C++ support, preliminary thread - implementation, and LynxOS native and target support for 386. - -Thu Oct 28 16:55:34 1993 Fred Fish (fnf@cygnus.com) - - * README: Add note from Peter Schauer about OSF/1 shared - libraries. Add note from Pace Willisson about configuring on BSDI - BSD/386 release 1.0. Update gdb references to gdb 4.11. - -Thu Oct 28 09:14:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * NEWS: Add notes about Alpha and "set remotedebug" for UDI. - - * valops.c (value_assign): Change bitfield code to use a buffer of - the correct size, rather than an int. - -Wed Oct 27 13:43:07 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/i386/{i386m3.mt,i386m3.mh}, - config/mips/{mipsm3.mt,mipsm3.mh}, - config/ns32k/{ns32km3.mt,ns32km3.mh}: Use correct names for TM_FILE - and XM_FILE. Replace host files *mach3-xdep.o with native - files *m3-nat.o. Replace host file os-mach3.o with native - file m3-nat.o. - - * remote-udi.c: Remove LOG_FILE stuff; superceded by "set remotedebug". - * remote-mon.c: Remove commented out "set remotedebug" command. - * remote-nindy.c: Clean up comment about wanting alternative to - options specified on the GDB command line. - - * fork-child.c (fork_inferior): Set inferior_pid before calling - init_trace_fun. Move the code which gets us through the shell - to new function startup_inferior. - * inferior.h: Declare startup_inferior. - * procfs.c (procfs_init_inferior), inftarg.c (ptrace_him): - Call startup_inferior. - * m3-nat.c (m3_trace_him): Call intercept_exec_calls. - * config/nm-m3.h: Don't define STARTUP_INFERIOR. - * config/i386/tm-i386m3.h, config/ns32k/tm-ns32k.h, - config/mips/tm-mipsm3.h: Don't define START_INFERIOR_TRAPS_EXPECTED. - - * m68k-stub.c: Change vector 13 from SIGFPE to SIGBUS. - -Tue Oct 26 22:05:03 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * mips-tdep.c (mips_pop_frame): If proc_desc is NULL, don't dump core. - -Tue Oct 26 15:07:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - gcc -Wall lint: - * nlmread.c: Include stabsread.h. - * Makefile.in: Update dependencies. - - * remote.c: Change PBUFSIZ back to 400. John's 28 Feb 1992 change - to increase it broke the ability to write large chunks of memory - with m68k-stub and i386-stub. Now we only use more than 400 on - machines where we need that much to write the registers. - * remote.c (remote_write_bytes): Eliminate possible abort(). The - check for when to abort was off by a few bytes and besides which, - it is handled by MAXBUFBYTES, which the caller uses. - * m68k-stub.c: Add comments about trap #1 and trap #8 instructions. - -Tue Oct 26 08:36:07 1993 Doug Evans (dje@canuck.cygnus.com) - - * remote-sim.h (SIM_ADDR): New type (same as CORE_ADDR). - (sim_set_pc): Update prototype. - (sim_read, sim_write): Ditto, and use unsigned char *buf. - (sim_fetch_register, sim_store_register): Use unsigned char *buf. - (sim_info): Pass printf function as argument, add verbose argument. - (sim_stop_reason): Renamed from sim_stop_signal, fix prototype. - * remote-sim.c (gdbsim_wait): Update call to sim_stop_reason. - (gdbsim_files_info): Update call to sim_info. - -Tue Oct 26 10:41:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valops.c (value_assign): Call reinit_frame_cache when assigning - to a register. - -Mon Oct 25 11:08:59 1993 Stu Grossman (grossman at cygnus.com) - - * infrun.c (wait_for_inferior): Fix PC out of objfile bounds - check to just use stop_func_name == 0. - * remote-udi.c (store_register): Invalidate NPC/PC_REGNUM after - changing PC. - -Mon Oct 25 14:57:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbserver/{low-lynx.c,low-sparc.c,low-sun3.c}, standalone.c, - m3-nat.c, i386m3-nat.c, mipsm3-nat.c, ns32km3-nat.c: bcopy -> memcpy. - - gcc -Wall lint: - * breakpoint.c: Include thread.h. - * coffread.c: Include stabsread.h. - * Makefile.in: Update dependencies. - * breakpoint.c (mention): Add bp_call_dummy to switch. - * symmisc.c (dump_symtab): Use %d not %ld for line number. - -Sun Oct 24 18:29:32 1993 Tom Lord (lord@rtl.cygnus.com) - - * every non-obsolete file except utils.c: - Change the stream argument to _filtered to GDB_FILE *. - Change all references to stdout/stderr to gdb_stdout/gdb_stderr. - Replace all calls to stdio output functions with - calls to corresponding _unfiltered functions. - Replaced calls to fopen for output to gdb_fopen. - Added sufficient goo to utils.c and defs.h to make the above - work. - - The net effect is that stdio output functions are only directly - used in utils.c. Elsewhere, the _unfiltered and _filtered - functions and GDB_FILE type are used. - - In the near future, GDB_FILE will stop being equivalant to - FILE. - - The semantics of some commands has changed in a very subtle way: - called in the right context, they may cause new occurences of - prompt_for_continue() behavior. - - Please respect this change by not reintroducing stdio output - dependencies in the main body of gdb code. All output from - commands should go to a GDB_FILE. - -Sun Oct 24 20:16:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * parse.c, parser-defs.h (write_exp_msymbol): New function to write - the appropriate expression for a minimal symbol. Taken from c-exp.y - and m2-exp.y but handles mst_file_*. - * c-exp.y, m2-exp.y: Use it. - -Sun Oct 24 09:31:05 1993 Fred Fish (fnf@lisa.cygnus.com) - - * elfread.c (elf_symtab_read): Use bfd convention that both - initialized and uninitialized data sections have the SEC_ALLOC - flag bit set, but only initialized sections have SEC_LOAD set. - SEC_DATA is ignored since it only gets set for initialized - data. - -Sat Oct 23 14:48:18 1993 Doug Evans (dje@canuck.cygnus.com) - - * remote-sim.h (sim_stop): New enum. - (sim_stop_signal): Change prototype, result is enum sim_stop. - * remote-sim.c (gdbsim_wait): Update call to sim_stop_signal. - -Fri Oct 22 07:49:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (define_symbol): Skip the whole thing about "pcc - promotion" on little-endian machines. - - * remote-vx.c (vx_wait): Rename pid parameter to pid_to_wait_for. - Some compilers (legitimately) don't like variables in the - function's outermost block whose name is the the same as the name of - a parameter. - - Merge Apollo patches from Troy Rollo (troy@cbme.unsw.edu.au): - * dst.h, dstread.c, config/m68k/{apollo68b.mt,tm-apollo68b.h}: - New files. - * config/m68k/nm-apollo68b.h: Add more defines. - * configure.in: Recognize apollo target, not just host. - - * configure.in: Add * to end of all OS names. - -Fri Oct 22 06:14:01 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (ALLPARAM): Add config/m88k/xm-delta88v4.h - -Thu Oct 21 12:23:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (init.c): Generate using the source, not munch. This - cleans up all kinds of hassles (which nm to use in munch, etc). The - new formatting conventions (mostly already followed) are that - the name of the _initialize_* routines must start in column zero, - and must not be inside #if. - * munch: Removed. - * Makefile.in: Remove references to munch. - * serial.c, remote.c, infptrace.c, maint.c, convex-tdep.c, - alpha-tdep.c, hp300ux-nat.c, hppab-nat.c, osfsolib.c, remote-es.c, - procfs.c, remote-udi.c, ser-go32.c, ultra3-xdep.c, sh-tdep.c, - i960-tdep.c, hppa-tdep.c, h8500-tdep.c, dpx2-nat.c, delta68-nat.c, - z8k-tdep.c: Make sure the above conventions are followed. Make - sure they are all declared as returning void. Clean up - miscellaneous comments and such. - - * sh-tdep.c (sim_load): Add function. - -Thu Oct 21 15:58:48 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * remote-mips.c (mips_wait): add pid argument. - -Thu Oct 21 12:23:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (c-exp.tab.o): Remove notice about shift/reduce conflicts - which no longer occur. - - gcc -Wall lint: - * findvar.c (symbol_read_needs_frame), corelow.c (ignore), - inflow.c (gdb_has_a_terminal): Make sure to return a value. - * regex.h: Declare re_set_syntax. - * printcmd.c: Include valprint.h. - * infcmd.c, exec.c, maint.c, core.c: Include language.h. - * maint.c: Include expression.h. - * infrun.c, fork-child.c, corelow.c, inflow.c: Include thread.h. - * inftarg.c: Include command.h. - * coredep.c: Include value.h. - * c-exp.y, m2-exp.y, ch-exp.y: Include bfd.h, symfile.h and objfiles.h. - * ch-typeprint.c: Include typeprint.h. - * ch-valprint.c: Include c-lang.h. - * nlmread.c: Include buildsym.h. - * environ.c: Include gdbcore.h. Only include defs.h once. - (set_in_environ): Cast const char * to char * when passing to - set_gnutarget. - * Makefile.in: Update dependencies to reflect all these new includes. - Remove unused variables: - * printcmd.c (printf_command): args_to_vprintf. - * coffread.c (coff_symfile_init): strsection. - Move variables to within the #ifdefs where they are used: - * symtab.c (gdb_mangle_name): opname. - * inftarg.c (child_attach): pid and exec_file. - * inftarg.c (child_detach): siggnal. - * objfiles.c (allocate_objfile): mapto, md, and fd. - * objfiles.c (free_objfile): mmfd. - * infrun.c (wait_for_inferior): Include BPSTAT_WHAT_LAST in switch. - * infrun.c (wait_for_inferior): Remove unused same_pid label. - * inferior.h: Declare set_sigint_trap and clear_sigint_trap. - * parser-defs.h: Declare write_exp_elt_block. - * stabsread.h: Declare elfstab_offset_sections and - coffstab_build_psymtabs. - -Thu Oct 21 12:05:08 1993 Ken Raeburn (raeburn@cygnus.com) - - Patch from Jeff Law: - * paread.c: Fix references to "hppa" that should now be "som". - -Thu Oct 21 12:23:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c (decode_line_1): Don't use SYMBOL_LINE for functions. - -Thu Oct 21 02:59:07 1993 Stu Grossman (grossman at cygnus.com) - - * remote-udi.c (udi_store_registers, store_register): Use - UDI29KPC address space when modifying PC. It seems that you can't - modify the PC directly (at least in the isstip simulator). - -Wed Oct 20 11:35:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * target.h: Put remote_debug declaration back here. Add baud_rate. - * remote.c, remote-udi.c, remote-utils.h: Let target.h take care of - declaring these. Those random externs all over are error prone. - * Move "set remotebaud" from remote-utils.c to main.c to it applies - to remote.c as well. - - * xcoffread.c (xcoff_symfile_read), coffread.c (coff_symfile_read): - Sort symtabs for this objfile only, not for all objfiles. - * symfile.c, symfile.h (sort_all_symtab_syms): Remove; no longer used. - - * mipsread.c (parse_symbol): In third-eye, a function has a block - within it which represents the whole function. Create only one - GDB block for both. - -Wed Oct 20 17:47:42 1993 Stu Grossman (grossman at cygnus.com) - - * main.c: Make baud_rate and remote_debug be global variables, - remove #include "remote-utils.h". This makes it possible to build - GDB without remote-utils.c. Also, move setting of remote_debug - into main, so that all remote*.c files can use it (not just the - serial line ones). And, make baud_rate be an int. - * remote-udi.c: Change kiodebug to remote_debug. - * remote-utils.c: Move setting of baud rate and debug into main.c. - * remote-utils.h: Redefine sr_{get set}_debug and sr_{get set}_baud - to use baud_rate and remote_debug globals for compatibility. - * remote.c: Use remote_debug and baud_rate globals directly, - instead of sr_ functions, so that we don't need to load - remote-utils.c. - * config/a29k/a29k-udi.mt: Define REMOTE_O as null so that we don't - get the default remote* modules. - -Wed Oct 20 11:35:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (define_symbol): When combining a LOC_ARG and a - LOC_REGISTER, use the type from the LOC_REGISTER, not from the - LOC_ARG. - -Wed Oct 20 14:34:38 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * config/i386/xm-go32.h: define some signals if they aren't - already defined. - -Wed Oct 20 11:35:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (INTERNAL_LDFLAGS): New macro. The new part is - that we use CFLAGS and PROFILE_CFLAGS to link. - (gdb, rapp, kdb): Use INTERNAL_LDFLAGS instead of - LDFLAGS and/or GLOBAL_CFLAGS. - -Wed Oct 20 09:29:55 1993 Stu Grossman (grossman at cygnus.com) - - * Makefile.in: Add $(srcdir) to all refs to 29k-share - directories. - -Tue Oct 19 17:23:34 1993 Fred Fish (fnf@deneb.cygnus.com) - - * Makefile.in (ALLCONFIG): Add config/i386/{i386m3.mh, i386m3.mt, - i386/i386mk.mh i386/i386mk.mt}, config/mips/{mipsm3.mh, - mipsm3.mt}, config/ns32k/{ns32km3.mh, ns32m3.mt} - * Makefile.in (remote_utils_h): Add remote-sim.h - * Makefile.in (NONSRC): Add i386-nlmstub.c - * Makefile.in (HFILES): Add coff-solib.h - -Tue Oct 19 14:15:40 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * values.c (value_virtual_fn_field): Fix the offset calculation - when calling virtual functions. (gdb.t22/virtfunc.exp). - * eval.c (evaluate_subexp): same as above. - -Tue Oct 19 10:43:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/rs6000/rs6000.mh (TERMCAP): Define to -lcurses. - - * Makefile.in: Define CXXFLAGS. - -Tue Oct 19 09:28:52 1993 Stu Grossman (grossman@cygnus.com) - - * sparclite/Makefile.in: Fixup so that this works with Sun make - and VPATH. - -Tue Oct 19 10:43:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.h (struct bpstat_what): Don't use bitfields. - - * typeprint.c: Add "class CLASS-NAME" to docstring for ptype. - -Tue Oct 19 06:17:10 1993 Fred Fish (fnf@cirdan.cygnus.com) - - * Makefile.in (ALLPARAM): Add config/m88k/{nm-delta88v4.h, - tm-delta88v4.h, xm-dgux.h}. - * Makefile.in (ALLCONFIG): Add config/m88k/{delta88v4.mh, - delta88v4.mt}. - - * README: Remove comment about SunOS 5.x programs leaving - coredumps. Info from Sun is that this was not in customer - releases. - -Mon Oct 18 10:28:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * hppa-tdep.c (restore_pc_queue): Call target_terminal_ours after - done stepping the inferior. - - * c-exp.y: Remove never-used (because of shift/reduce conflicts) - rules for pointers to members. - * Makefile.in: Remove notice about expected shift/reduce conflicts. - - * buildsym.c (finish_block): If we pop the context stack and it is - not empty, complain () instead of abort (). - -Sun Oct 17 19:42:31 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * parse.c, parser-defs.h (follow_types): New function. - * c-exp.y (ptype : typebase abs_decl): Use it. - * c-exp.y (ptype): Add support for type qualifiers after the - typebase. The typebase rule already has support for them before - the typebase. - * Makefile.in: Change the expected number of shift/reduce - conflicts to 6. This is OK--the 2 new conflicts are basically the - same as one of the old ones. - -Sun Oct 17 13:04:49 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.10.3. - -Sun Oct 17 09:18:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (wait_for_inferior): Clean up comments which were at - the top of the file, making them more concise and moving them with - the code (Sorry, Randy, but these stream-of-consciousness comments - really have to go). Switch the order of the "&&", which makes - things clearer and turns out to be an improvement with respect to - side effects and speed. - -Sun Oct 17 02:06:01 1993 Stu Grossman (grossman at cygnus.com) - - * procfs.c: Handle process exits more elegantly by trapping on - entry to _exit. Also, cleanup procinfo list when process dies of - it's own accord (as opposed to being killed). - -Sat Oct 16 20:47:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m88k/xm-dgux.h: Define NO_PTRACE_H. - - * corelow.c (add_to_thread_list): Need a cast to go from PTR to - asection *. - - * infrun.c: Add comment about signals. - - * fork-child.c (fork_inferior): Remove CREATE_INFERIOR_HOOK again. - Stu reinstated it (accidently I assume). - -Sat Oct 16 15:27:10 1993 Stu Grossman (grossman at cygnus.com) - - * procfs.c (procfs_wait): Losing Unixware can't do poll on /proc - files. Use PIOCWSTOP instead. - * corelow.c (add_to_thread_list): Fix arg to match prototype. - - * procfs.c (procfs_set_sproc_trap): Don't use this if sproc - isn't available. - * (procfs_notice_signals): Fix prototype. - -Fri Oct 15 22:46:07 1993 Stu Grossman (grossman at cygnus.com) - - * breakpoint.c (breakpoint_thread_match break_command_1): - Thread-specific breakpoint support. - * breakpoint.h (struct breakpoint): Add thread id field. - * fork-child.c (fork_inferior): Move call to init_thread_list() - back a bit so that init_trace_fun can do thread functions. - * hppa-tdep.c (restore_pc_queue): Add pid to call to target_wait. - * hppab-nat.c (child_resume): Handle default pid. - * hppah-nat.c (child_resume): Handle default pid. - * i386lynx-nat.c (child_wait): New arg pid. - * inflow.c (kill_command): Reset thread list. - * infptrace.c (child_resume): Handle default pid. - * infrun.c: Thread-specific breakpoint support. - * inftarg.c (child_wait): Add pid arg. - * osfsolib.c (solib_create_inferior_hook): Add pid to call to - target_resume. - * procfs.c: Multi-thread support. - * remote-bug.c (bug_wait): Add pid arg. - * remote-hms.c (hms_wait): Add pid arg. - * remote-mips.c (mips_wait): Add pid arg. - * remote-mon.c (monitor_wait): Add pid arg. - * remote-nindy.c (nindy_wait): Add pid arg. - * remote-sim.c (gdbsim_wait): Add pid arg. - * remote-udi.c (udi_wait): Add pid arg. - * remote-vx.c (vx_wait): Add pid arg. - * remote-z8k.c (sim_wait): Add pid arg. - * remote.c (remote_wait): Add pid arg. - * solib.c (solib_create_inferior_hook): Add pid to call to - target_resume. - * target.h (struct target_ops): Add pid arg to to_wait and - to_notice_signals. - * thread.c (valid_thread_id): New func to validate thread #s. - * (pid_to_thread_id): New func to do the obvious. - * thread.h: Prototypes for above. - - * coff-solib.c (coff_solib_add): Use nameoffset field to locate - filename. - -Fri Oct 15 21:29:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * h8300-tdep.c, h8500-tdep.c: Define sim_load only, but not - sim_kill, sim_open, or sim_set_args. - - * stack.c (print_stack_frame): Put catch_errors around - print_frame_info so (for example) error printing source doesn't - cause auto-displays to get skipped in normal_stop. - - * findvar.c (value_from_register): When preparing to cast a value - from REGISTER_VIRTUAL_TYPE to type, copy the REGISTER_VIRTUAL_SIZE; - the old code didn't copy the whole thing. - * valops.c (value_assign): Add comment. - -Fri Oct 15 12:57:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (upgrade_type): Replace bitsize sanity checks and - complaint by a comment explaining why they were useless. - -Fri Oct 15 14:30:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Move comments on bypassing call dummy breakpoint from stack.c - to breakpoint.h. - -Fri Oct 15 11:52:56 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symtab.c (lookup_partial_symtab): If filename is not found and - contains no slashes, try again and compare without leading path - components. - * symtab.c (lookup_symtab_1): Replace open coded version of - lookup_partial_symtab with a function call. - -Thu Oct 14 20:34:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * fork-child.c (fork_inferior), remote-eb.c (eb_create_inferior), - remote-mon.c (monitor_create_inferior), remote-nindy.c - (nindy_create_inferior), remote-st.c (st2000_create_inferior), - remote-vx.c (vx_create_inferior): Remove CREATE_INFERIOR_HOOK; it - is replaced by init_trace_fun. - * config/convex/xm-convex.h, convex-xdep.c: Add comments explaining - how to do without CREATE_INFERIOR_HOOK for whoever fixes the Convex - port. - - * Makefile.in: Add Mach files to ALLDEPFILES, etc. - * m3-nat.c: Clean up more hair--message(), cprocs. - * configure.in: Recognize Mach targets and hosts. - * config/ns32k/tm-umax.h: Add some #ifndef's so tm-ns32km3.h can - include this file. - * Mach headers in config/*/tm-*.h: Fix includes to match correct - locations of files. - -Thu Oct 14 21:35:55 1993 Rob Savoye (rob@darkstar.cygnus.com) - - * remote-mon.c (general_open): Set dev_name. Minor tweaking to get - it working again. - * config/m68k/tm-monitor.h: Remove floating point register names - as there aren't any on any of the monitors that use this code. - -Wed Oct 13 11:47:23 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * inflow.c: Pass pointer to process group, not process group itself, - to TIOCSPGRP ioctl. - - * inflow.c (terminal_ours_1): Don't print warning on failure to - set process group. - - * printcmd.c (printf_command): Instead of using makeva* and - calling vprintf, just make the appropriate calls to printf. - * printcmd.c, config/pa/xm-pa.h, config/mips/xm-makeva.h, - config/alpha/xm-alpha.h, config/m88k/xm-m88k.h: Remove all - traces of makeva*. My apologies to everyone (including me!) - who spent so much time getting it to work on various machines, - but look at the bright side, at least you won't have to do it - again in the future. - - * printcmd.c (printf_command): Make a cleanup for val_args (fixes - a memory leak). - -Tue Oct 12 22:54:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/xm-mips.h: Remove comment about HAVE_SGTTY vs. usleep. - -Tue Oct 12 12:01:29 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in: only configure gdbserver for native environments - -Tue Oct 12 08:59:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (read_type): Treat a negative type number at the start - of a type as a type reference, not as a definition of a type with - "50=" omitted. This makes things work on the RS/6000 again (the - 14 Sep 1993 change broke it). - - * inflow.c: Use 0 (standard input) not scb->fd. - (terminal_ours_1): If printing warning, don't claim it happened in - terminal_inferior. - - * blockframe.c (get_prev_frame_info): Don't error() if there are no - frames; just return NULL. - - * xcoffsolib.h, xcoffexec.c: Undo the part of Fred's bfd->abfd - change which involved structure elements. It was unnecessary and - was not consistently done. - - * stabsread.h, stabsread.c, dbxread.c (common_block*, copy_pending): - Move common block handling from dbxread.c to stabsread.c. - Use the name from the BCOMM instead of the ECOMM. - Allocate things on the symbol_obstack. - * xcoffread.c (process_xcoff_symbol): Process C_BCOMM, C_ECOMM, - and C_ECOML. On unrecognized storage classes, go ahead and call - define_symbol (after the complaint). - - * dbxread.c (process_one_symbol): Don't relocate 'S' symbols by - the text offset. - -Tue Oct 12 12:33:09 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * osfsolib.c (solib_create_inferior_hook): Reset stop_soon_quietly - after shared library symbol reading to get rid of warning from - heuristic_proc_start. - -Tue Oct 12 12:01:29 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * remote-sim.c: fix unterminated character string - -Tue Oct 12 08:59:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c: Fix comment about gcc 2.3.3 stab for long long int. - -Mon Oct 11 14:27:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m3-nat.c, config/nm-m3.h: Add a target_ops struct and other - various things to try to get this to work. - - * symtab.h: Fix comments re headers, sharing blockvectors, etc. - -Mon Oct 11 11:46:06 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * config/i960/vxworks960.mt (REMOTE_O): add dcache.o and remote-utils.o - -Mon Oct 11 02:48:57 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_partial_symbols): Do not add undefined - symbols to the partial symbol table. - * alpha-tdep.c (init_extra_frame_info): Remove kludge for gcc, - gcc has to be compatible with the native tools. - * alpha-tdep.c (alpha_push_arguments): Rename NUM_ARG_REGS to - ALPHA_NUM_ARG_REGS and move its definition to tm-alpha.h. - * config/alpha/tm-alpha.h (FRAME_ARGS_ADDRESS): Change it to the - way the native tools define it, update comment. - -Fri Oct 8 15:54:06 1993 Fred Fish (fnf@deneb.cygnus.com) - - * osfsolib.c, remote-sim.c, remote.c, solib.c, xcoffexec.c, - xcoffsolib.h: Use 'abfd' for bfd variables instead of 'bfd'. - Sun cc doesn't like variable names that match their typedef'd type. - -Fri Oct 8 14:56:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * inflow.c: Remove unused includes of sys/param.h and sys/types.h. - - * inflow.c, ser-unix.c, ser-go32.c, ser-tcp.c, serial.h, - terminal.h, fork-child.c, main.c, utils.c: Move all the process - group stuff back to inflow.c and terminal.h; that's a better place - for it and fixes problems with trying to get/set the process group - of a tty we're doing remote debugging on. - * terminal.h: Skip the redefines and includes if HAVE_TERMIOS. - - * findvar.c, value.h (symbol_read_needs_frame): New function. - * c-exp.y, m2-exp.y: Call it instead of having our own switch on - the symbol's class. - * valops.c (value_of_variable): Use symbol_read_needs_frame to - decide whether we care about finding a frame. - -Fri Oct 8 02:34:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * blockframe.c (get_frame_block): Do not adjust pc if the frame - function was interrupted by a signal. - -Thu Oct 7 19:20:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/h8300/tm-h8300.h: Don't define sr_get_debug. - * remote-sim.c: Include remote-utils.h. - * target.h: Add comment about target_has_execution. - -Thu Oct 7 16:14:19 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * h8300-tdep.c (sim_load, sim_kill, sim_open, sim_set_args): - New functions. - * infrun.c (normal_stop): Don't try and set the pc in the current - frame coredump if there isn't one. - * remote-sim.c (gdbsim_store_register): Don't - SWAP_TARGET_AND_HOST, sim_store_register takes bytes in raw order. - (gdbsim_wait): Set status with WSETSTOP. - * config/h8300/tm-h8300.h (sr_get_debug): Define - -Thu Oct 7 12:56:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - New Mach stuff: - * config/i386/i386mach.c: Explain this is for the old (probably - non-functional and/or obsolete) Mach stuff. - * m3-nat.c, config/nm-m3.h, - i386m3-nat.c, mipsm3-nat.c, ns32km3-nat.c, - config/i386/{i386m3.mh,i386m3.mt,tm-i386m3.h,xm-i386m3.h}, - config/i386/{i386mk.mh,i386mk.mt,tm-i386mk.h,xm-i386mk.h}, - config/mips/{mipsm3.mh,mipsm3.mt,tm-mipsm3.h,xm-mipsm3.h}, - config/ns32k/{ns32km3.mh,ns32km3.mt,tm-ns32km3.h,xm-ns32km3.h}: - New files. - - * blockframe.c (find_pc_partial_function): If we call - PSYMTAB_TO_SYMTAB, call target_terminal_ours_for_output first. - This is needed now that wait_for_inferior passes in endaddr. - * infrun.c: Move call to target_terminal_inferior from proceed - to resume. - -Thu Oct 7 09:22:04 1993 Stu Grossman (grossman at cygnus.com) - - * blockframe.c (find_pc_partial_function): Fix handling for PCs - beyond the end of the last function in an objfile. - * coff-solib.c (coff_solib_add): Use BFD to get fields from .lib - section. - * infrun.c (wait_for_inferior): Modify test for subroutine entry - to include pc out of bounds of the previous function. - * remote.c (remote_wait): Use strtoul for parsing 'N' message. - Add code to relocate symfile_objfile->sections. - -Thu Oct 7 06:22:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/sparc/sun4os4.mh: Add comment saying why we don't use - -lresolv. - -Thu Oct 7 09:29:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function - that clears the `inserted' flag for all breakpoints and deletes - any breakpoints which should go away between runs of programs. - * inflow.c (generic_mourn_inferior), infrun.c (init_wait_for_inferior), - remote-es.c (es1800_load), comments in exec.c and corelow.c: - Use it instead of mark_breakpoints_out. - * breakpoint.c (mark_breakpoints_out): Update comment, tm-rs6000.h - uses it in a completely different context. - * breakpoint.c (breakpoint_re_set_one): Add bp_call_dummy case. - -Thu Oct 7 09:29:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * Makefile.in (REGEX, REGEX1): Always use our own version of - regex.c to be consistent across hosts. - * source.c (_initialize_source): Initialize regex to use grep - style syntax as an approximation to POSIX basic regex syntax. - -Wed Oct 6 12:43:47 1993 Jeffrey A Law (law@snake.cs.utah.edu) - Jim Kingdon (kingdon@lioth.cygnus.com) - - * hppa-tdep.c (frame_chain): Rework so that it correctly - handles boundaries where code with a frame pointer calls code - without a frame pointer. - (dig_fp_from_stack): New function. - -Wed Oct 6 12:43:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (delete_breakpoint): Don't insert a disabled breakpoint. - - * README: Add Alpha notes from Schauer. - -Tue Oct 5 15:26:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (install, uninstall): Remove $$n.1 stuff; I don't - understand what it is trying to do, but I suspect it's not doing - it. - - * config/ns32k/merlin.mh: Add comment about M_INSTALL. - * config/m88k/{delta88.mh,delta88v4.mh}: Remove M_INSTALL and - M_UNINSTALL; it tries to install a non-existent file gdb.z. - * Makefile.in: Remove M_INSTALL stuff; the above were the only uses. - - * stabsread.c (read_range_type): Remove comment which recommends - distinguishing float from complex by the name. - -Tue Oct 5 12:17:40 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - Jim Kingdon (kingdon@cygnus.com) - Stu Grossman (grossman@cygnus.com) - - Changes to support alpha OSF/1 in native mode. - * alpha-nat.c, alpha-tdep.c, config/alpha/alpha-osf1.mt, - config/alpha/nm-alpha.h, config/alpha/tm-alpha.h, osfsolib.c: - New files. - * Makefile.in: Add new files and dependencies. - * configure.in: Add alpha target. - * config/alpha/alpha-osf1.mh (NATDEPFILES): Add osfsolib.o - * config/alpha/alpha-osf1.mh (MH_CFLAGS): Remove, we can handle - shared libraries now. - * config/alpha/xm-alpha.h: Cleanup, get MAKEVA_* defines right. - - * defs.h (CORE_ADDR): Make its type overridable via CORE_ADDR_TYPE, - provide `unsigned int' default. - * breakpoint.c (breakpoint_auto_delete): Delete only if we really - stopped for the breakpoint. - * stabsread.c, stabsread.h (define_symbol): Change valu parameter - to a CORE_ADDR. - * stabsread.c (read_range_type): Handle the case where the lower - bound overflows and the upper doesn't and the range is legal. - * infrun.c (resume): Do not step a breakpoint instruction if - CANNOT_STEP_BREAKPOINT is defined. - - * inferior.h (CALL_DUMMY_LOCATION): New variant AT_ENTRY_POINT. - Now that we have the bp_call_dummy breakpoint the call dummy code - is no longer needed. PUSH_DUMMY_FRAME, PUSH_ARGUMENTS and - FIX_CALL_DUMMY can be used to set up everything for the dummy. - The breakpoint for the dummy is set at the entry point and thats it. - * blockframe.c (inside_entry_file, inside_entry_func): Do not stop - backtraces if pc is in the call dummy at the entry point. - * infcmd.c (run_stack_dummy): Handle AT_ENTRY_POINT case. Use - the expected breakpoint pc when setting up the frame for - set_momentary_breakpoint. - * symfile.c (entry_point_address): New function for AT_ENTRY_POINT - support. - * valops.c (call_function_by_hand): Handle AT_ENTRY_POINT case. - -Tue Oct 5 11:37:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Recognize hppa*-*-hiux* (currently synonym for hpux). - Change other hppa host entries to use -*- not -hp-. - -Mon Oct 4 19:16:14 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * i386-nlmstub.c: New file; debugging stub for i386 NetWare. Must - be compiled with NetWare header files and turned into an NLM with - nlmconv. - -Mon Oct 4 11:02:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * minsyms.c (lookup_minimal_symbol_by_pc): Don't use mst_abs symbols. - - * dbxread.c (process_one_symbol): Make n_opt_found static. - - * Rename i386lynx-tdep.c to i386ly-tdep.c for 14 character file names. - * Makefile.in, config/i386/i386lynx.mt: Change accordingly. - - * values.c (record_latest_value): Fetch lazy values and set VALUE_LVAL - to not_lval. - -Sun Oct 3 15:54:51 1993 Stan Shebs (shebs@rtl.cygnus.com) - - * objfiles.h (objfile): New slot sym_stab_info, use by most - stab-reading formats. - * gdb-stabs.h (DBX_SYMFILE_INFO): Access sym_stab_info instead of - sym_private. - * coffread.c (coff_symfile_init): Alloc struct for sym_stab_info. - * dbxread.c, elfread.c, paread.c: Change sym_private references to - sym_stab_info references. - -Sat Oct 2 19:28:35 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mipsread.c, objfiles.c, utils.c: Use PTR not void *. RISC/OS - 4.02 lacks void *. - * elfread.c: Use void * not PTR inside PARAMS. - - * config/mips/news-mips.mh: Remove coredep.o; mips-nat.o does it. - * config/mips/news-mips.mh: Define NAT_FILE not NM_FILE. - * config/mips/nm-news-mips.h: Include mips/nm-mips.h not nm-mips.h. - -Sat Oct 2 16:05:22 1993 Stu Grossman (grossman at cygnus.com) - - * Makefile.in, coff-solib.c, coff-solib.h, i386lynx.mt, - tm-i386lynx.h: Add support for SVR3 COFF shared libraries. - -Sat Oct 2 15:50:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m88k-nat.c (store_inferior_registers): When writing all registers, - don't try to write EXIP_REGNUM or ENIP_REGNUM (not needed for this - case, and they cause trouble). - - * TODO: Don't suggest doing fast watchpoints by stepping a line - at a time. That would be really hairy and still not fast enough. - Do suggest debug registers and page table diddling. - -Fri Oct 1 14:54:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (do_examine): Make meaning of 'h', 'w', and 'g' not - depend on builtin_type_*. Instead, it is always 2, 4, and 8 bytes - like the documentation says. - * printcmd.c (decode_format) [CC_HAS_LONG_LONG]: Remove 'l' as - synonym for 'g'. This was never documented, it shouldn't depend on - CC_HAS_LONG_LONG, and I don't see what's wrong with 'g'. - -Fri Oct 1 10:06:35 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * symtab.c: fix a bug in testsuite (virtfunc.exp) - -Thu Sep 30 11:30:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m88k-nat.c (fill_gregset): Fix typo (R_SFIP -> R_FIP). - - * c-typeprint.c (c_type_print_base, TYPE_FN_FIELD_STUB code): - If demangled name lacks a colon, don't dump core. - - * blockframe.c (find_pc_partial_function): If pst->readin is - set, don't try to get symbols from pst. - - * inflow.c (generic_mourn_inferior): Call reinit_frame_cache - instead of doing it ourself. - * blockframe.c (reinit_frame_cache): Use code which was in - generic_mourn_inferior so we can use this function even when - we have switched targets. - * corelow.c (core_detach): Call reinit_frame_cache. - * target.c (target_detach): Don't call generic_mourn_inferior - (revert yesterday's change, now handled by core_detach). - * objfiles.c (free_objfile): Detach any core file if we call - SOLIB_CLEAR. #include target.h. - - * fork-child.c (fork_inferior): Don't call target_terminal_init - and target_terminal_inferior until we are sure that the inferior - has called gdb_setpgid. This fixes PR 2900 (Schauer tracked it - down and was able to reliably reproduce it by putting a sleep() - before the gdb_setpgid()). - -Thu Sep 30 12:00:49 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-exp.y, m2-exp.y: Change type of address for msymbol to - builtin_type_long. - * infptrace.c (fetch_register, store_inferior_register, - child_xfer_memory): Use PTRACE_XFER_TYPE for the type of ptrace - transfers. Provide an `int' default for PTRACE_XFER_TYPE. - -Thu Sep 30 11:30:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * defs.h (TARGET_*_BIT): Don't use host information (sizeof) in - picking defaults. - - * cp-valprint.c (cp_is_vtbl_ptr_type): Continue to accept old form. - -Thu Sep 30 11:25:55 1993 Kung Hsu (kung@cygnus.com) - - * cp-valprint.c (cp_is_vtbl_ptr_type): - change vtable field name to __vtbl (pr2695). - - * symtab.c (gdb_mangle_name): fix a bug, to get mangled name right. - -Wed Sep 29 18:34:22 1993 Stu Grossman (grossman at cygnus.com) - - * Makefile.in: Add deps for i386lynx-nat.o and i386lynx-tdep.o to - keep non-gnu makes happy. - -Wed Sep 29 17:20:54 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (read_hpux_symtab): When a K_END is found for a - K_MODULE, clear the have_module and have_name flags. - -Wed Sep 29 10:52:19 1993 Kung Hsu (kung@cygnus.com) - - * c-valprint.c: to fix virtual table print bug (pr2695). - -Wed Sep 29 10:52:19 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * target.c (target_detach): Call generic_mourn_inferior. - * inflow.c (generic_mourn_inferior): Call flush_cached_frames. - -Tue Sep 28 23:08:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c, coffread.c, elfread.c: A few changes to comments. - -Tue Sep 28 18:39:37 1993 Stan Shebs (shebs@rtl.cygnus.com) - - * configure.in: Rename ...-lynx* to ...-lynxos*. - Add m68*-*-lynxos* configuration. - * dbxread.c (coffstab_build_psymtabs): New function, - interfaces coffread.c to dbxread functions. - * coffread.c (coff_symfile_info): Expand to include - dbx_symfile_info slots. - (coff_symfile_init): Init coff_symfile_info struct. - (coff_locate_sections): New functions, finds the stab and stabstr - sections. - (coff_symfile_read): Call coffstab_build_psymtabs if a stab - section is present. - (coff_section_offsets): Replace fake version with real offsets. - -Tue Sep 28 18:00:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infcmd.c (run_stack_dummy): Set the frame in the bp_call_dummy - breakpoint. - -Tue Sep 28 17:53:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * config/nm-sysv4.h: Include solib.h. Define SVR4_SHARED_LIBS. - * config/tm-sysv4.h: Don't include solib.h. - * config/xm-sysv4.h: Don't define SVR4_SHARED_LIBS. - * config/i386/i386v4.mt (TDEPFILES): Move solib.o from here... - * config/i386/i386v4.mh (NATDEPFILES): ...to here. - * config/i386/nm-i386v4.h: Include nm-sysv4.h. - * config/m68k/amix.mt (TDEPFILES): Move solib.o from here... - * config/m68k/amix.mh (NATDEPFILES): ...to here. - -Tue Sep 28 09:45:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symmisc.c (print_symbol): Use %02x not %2x for LOC_CONST_BYTES. - - Clean up problems with targets and hosts that have 64 bit longs - and pointers and 32 bit ints. - * breakpoint.c, buildsym.c, c-lang.c, c-valprint.c, ch-lang.c, - ch-valprint.c, core.c, cp-valprint.c, dbxread.c, exec.c, - expprint.c, gdbtypes.c, infcmd.c, language.c, language.h, - m2-lang.c, maint.c, mips-tdep.c, mipsread.c, partial-stab.h, - printcmd.c, remote-vx.c, solib.c, source.c, stack.c, symfile.c, - symmisc.c, symtab.c, valops.c, valprint.c, xcoffexec.c: - Change all printf formats from %x to %lx if outputting an address. - Change la_*_format to use long format. - local_hex_string, local_hex_string_custom now take an unsigned long - argument, change all callers. - * coffread.c (read_coff_symtab): Remove superfluous cast for - complaint output. - * dbxread.c (end_psymtab): Cast MSYMBOL_INFO to long, not int. - * findvar.c, value.h (write_register): Change val to LONGEST. - * gdbtypes.h (struct type): Change `bitsize' to long as - TYPE_FIELD_STATIC_PHYSNAME uses this field as a pointer. - * inferior.h (struct inferior_status): Change type of stop_pc to - CORE_ADDR. - * language.h (local_octal_string, local_octal_string_custom): - Remove prototype, the functions are neither defined nor used. - * mipsread.c (parse_symbol): Use temporary variable for bitsize as - f->bitsize is a long now. - * objfiles.c (add_to_objfile_sections, build_objfile_section_table): - Use unsigned long casts instead of int for abusing sections_end - pointer as integer. - * stack.c (parse_frame_specification): Change type of `args' to - CORE_ADDR for SETUP_ARBITRARY_FRAME. - - * printcmd.c (make_vasize): Allow redefinition via MAKEVA_SIZE. - * mipsread.c (parse_type): Alpha cc now supports the t->continued - bit, update algorithm to match the way the compiler uses it. - -Tue Sep 28 12:05:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c (fprintfi_filtered): Fix comments. - -Mon Sep 27 18:10:08 1993 Stu Grossman (grossman at cygnus.com) - - * coffread.c (read_coff_symtab): Don't call getfilename if there - are no auxents. - -Mon Sep 27 10:22:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c (find_pc_line): Fix comments. - - * remote-udi.c (udi_mourn): Don't pop target. - -Fri Sep 24 17:25:41 1993 Stu Grossman (grossman at cygnus.com) - - * corelow.c: Add multi thread/process support for core files with - .reg/XXX pseudo-sections. - * i386lynx-nat.c thread.h thread.c: Remove unnecessary core file - support. - -Thu Sep 23 10:49:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-udi.c (download): Skip zero length sections. - - * valops.c (search_struct_method, value_struct_elt): - Use (value)-1, not -1, for error. - - * infcmd.c (step_1), infrun.c (wait_for_inferior): Add comments - about SHIFT_INST_REGS. - - * exec.c (exec_file_command): Set text_end based on all code readonly - sections, not just ".text". - - * defs.h, infcmd.c, config/z8k/tm-z8k.h, config/m88k/tm-m88k.h, - config/sh/tm-sh.h, config/h8300/tm-h8300.h, config/h8500/tm-h8500.h, - z8k-tdep.c: Remove all references to ADDR_BITS_SET. - * config/m88k/tm-m88k.h: Define TARGET_WRITE_PC. - - * config/m88k/tm-m88k.h, m88k-tdep.c: Add call function stuff. - -Thu Sep 23 00:13:06 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/tm-mips.h (STORE_STRUCT_RETURN): Define as noop as - the pushing of the struct return address is already handled in - mips_push_arguments. - * mips-tdep.c (reinit_frame_cache_sfunc): Fix typo in prototype - declaration. - * mipsread.c (parse_symbol, parse_type, upgrade_type): Add more - sanity checks for corrupt symbol entries to avoid core dumps - reported by benson@odi.com. Obviously Ultrix 4.3A cc now has - the same problems as the OSF/1 alpha cc. - * mipsread.c (parse_lines): Iterate over the range of the compressed - line number entries, the old iteration sometimes failed to stop - and wrote past the end of the LINETABLE. Add sanity check to avoid - the same problem in case the line number info is corrupt. - * mipsread.c (parse_procedure): Adjust pdr for alpha __sigtramp. - * mipsread.c (parse_external, parse_partial_symbols): Ignore stNil - symbols that are produced for statics in .o files and stLocal symbols - that are produced for every section in OSF/1 dynamically linked - executables. - * mipsread.c (psymtab_to_symtab_1): Put out `undefined symbols' - warning only under `verbose on' as there are many undefined symbols - in a dynamically linked executable. - -Wed Sep 22 10:28:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/i960/nindy960.mt: Don't define REMOTE_O; REMOTE_O was - intended only for VxWorks. Remove dcache.o from TDEPFILES now - that we pick it up from the default REMOTE_O. - - * breakpoint.c (bpstat_what): Initialize retval.call_dummy and - retval.step_resume. - - * mips-tdep.c (mips_frame_chain): If frame size zero, return zero. - * rs6000-tdep.c: Add comment about framelessness. - - * remote-nindy.c: Declare ninMemGet and ninMemPut. - -Wed Sep 22 08:02:57 1993 Stu Grossman (grossman at cygnus.com) - - * Makefile.in: Add i386lynx-tdep to the right places. - (TARDIRS): Add gdbserver. - - * exec.c (print_section_info): Print entry point. - * i386lynx-nat.c (i386lynx_saved_pc_after_call): Move into - i386lynx-tdep.c. Add core file support. - * i386lynx-tdep.c: New module for Lynx/386 target dependant code. - * maint.c: Add `maint info sections' command to print info about all - sections that BFD knows about for exec and core files. - * sparc-tdep.c (sparc_push_dummy_frame): Update stack pointer - before putting frame on the stack. Consolidate writes to reduce - traffic for remote debugging. - * config/i386/i386lynx.mh (NATDEPFILES): Remove exec.o. - * config/i386/i386lynx.mt (TDEPFILES): Add exec.o, i386lynx-tdep.o. - * config/i386/nm-i386lynx.h: Add target_pid_to_str(). - * config/i386/tm-i386lynx.h: Remove target_pid_to_str(). - * sparclite/Makefile.in: Add deps to keep Sun make happy. - -Tue Sep 21 17:48:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.h, breakpoint.c (bpstat_stop_status): Add new argument - not_a_breakpoint. - * infrun.c (wait_for_inferior): Pass it. Also consolidate the - test of whether we are stepping into a CURRENTLY_STEPPING macro. - -Tue Sep 21 17:22:34 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * breakpoint.c (bpstat_stop_status), - infcmd.c (step_1), - infrun.c (wait_for_inferior): collapse SHIFT_INST_REGS ifdef - and insert macro. - - * m88k-tdep.c: include ieee-float.h. new global target_is_m88110. - new const struct ext_format_m88110 for float format. - (pic_prologue_code): add braces. - (next_insn): remove unused variable buf. - (frame_find_saved_regs): remove unused variables next_addr, - saved_regs, regnum. - (frame_locals_address): remove unused variables frame, ap. - (frame_args_address): remove unused variables frame, ap. - (push_parameters): add some breaks and a default case. - - * remote-bug.c: remove redundant includes of value.h, target.h, - serial.h. - (bug_open): corrected typo, sr_multi_scan -> gr_multi_scan. - (bug_fetch_register): special case sfip register for m88110. - remove flag bit masking of pc registers. This should be handled - by the ADDR_BITS_* macros. - (bug_store_register): special case sfip register for m88110. - Corrected sprint format for extended registers. - - * config/m88k/tm-m88k.h: white space and comment changes. include - ieee-float.h. expanded to cope with m88110 extended registers. - (R0_REGNUM, XFP_REGNUM, X0_REGNUM): new macros. - (SHIFT_INST_REGS): becomes a real macro. - -Tue Sep 21 17:48:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (breakpoint_1): Support bp_call_dummy. - -Tue Sep 21 17:06:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * elfread.c (record_minimal_symbol_and_info): Guess the section to - use from the type. - * objfiles.c: Include gdb-stabs.h for SECT_* macros. - (objfile_relocate): Relocate textlow and texthigh in psymtabs. - Relocate partial symbols. Check that minimal SYMBOL_SECTION is - nonnegative before using it. - * symtab.h: Adjust section field comment. - - * remote.c (interrupt_query): New function. - (remote_interrupt_twice): Call interrupt_query. - (putpkt, getpkt): If quit_flag is set, call interrupt_query. - (remote_wait): Don't bother with objfile_relocate if the addresses - haven't changed. - (remote_fetch_registers): If we see a packet that doesn't start - with a hex character, fetch a new one. - -Tue Sep 21 11:44:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote.c, remote-utils.c: Use SERIAL_FLUSH_INPUT after opening it. - - * printcmd.c (print_scalar_formatted): When truncating value we are - going to print as unsigned, handle it generally for any length - less than sizeof (LONGEST), rather than special-casing sizeof (char), - sizeof (short), and sizeof (long). Clarify comment on what this - is for. - - * symfile.c (deduce_language_from_filename): Accept .cxx for C++. - * buildsym.c (start_subfile): Use deduce_language_from_filename - rather than checking for .C or .cc ourself. - -Mon Sep 20 14:53:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * defs.h: Declare argument of re_comp as const char *. - - * remote.c, remote-mips.c: Use sr_get_debug not remote_debug. - - * README: Say using bfd from another release doesn't generally work. - -Sat Sep 18 10:13:18 1993 Jim Kingdon (kingdon@poseidon.cygnus.com) - - * mipsread.c (parse_type): Don't complain() if we guessed struct - and it was a union, or vice versa. - - * defs.h (make_cleanup): Change PTR to void * when inside PARAMS. - - Some of the following is in #ifdef CALL_DUMMY_BREAKPOINT_OFFSET. - * breakpoint.h (enum bptype): Add bp_call_dummy. - (struct bpstat_what): Add call_dummy field. - * infrun.c (wait_for_inferior): Deal with it. - * breakpoint.c (bpstat_what): Deal with call dummy breakpoint. - * infcmd.c (run_stack_dummy): Set the call dummy breakpoint. - * config/sparc/tm-sparc.h: Define CALL_DUMMY_BREAKPOINT_OFFSET. - - * remote-sim.h: New file. - * remote-sim.c: Add remote debug feature. Rename stuff to distinguish - interface to simulator from gdb-specific stuff. Other changes. - * remote-sp64sim.c: Renamed to remote-sim.c. - Use sr_get_debug instead of our own sim_verbose/simif_snoop. - Use gnutarget in call to bfd_openr. - Rename simif_* to gdbsim_*. - * config/sparc/sp64sim.mt: Change remote-sp64sim.c to remote-sim.c. - -Fri Sep 17 04:41:17 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * findvar.c (extract_signed_integer): Cast *p to LONGEST before doing - the xor and subtract. Otherwise it will not sign extend if the type - of LONGEST is larger than int. - * cp-valprint.c (cp_print_class_method): Inhibit core dump if - domain is an undefined cross reference. - * valops.c (call_function_by_hand): Set real_pc to correct - value if CALL_DUMMY_LOCATION != ON_STACK. - -Thu Sep 16 20:37:06 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * config/a29k/tm-a29k.h (FRAME_CHAIN): If rsize is zero, return zero. - -Thu Sep 16 13:16:22 1993 Stu Grossman (grossman at cygnus.com) - - * infrun.c (wait_for_inferior): Allow user to single step within - a stack dummy. - -Thu Sep 16 12:34:01 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * dbxread.c (copy_pending): Deal with END NULL. - (process_one_symbol): Add comments about what common_block NULL means. - -Wed Sep 15 14:50:26 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * remote-udi.c, remote-adapt.c, remote-mm.c: Move processor_type - to tm-a29k.h and a29k-tdep.c and make it an enum. - * a29k-tdep.c (a29k_get_processor_type): New function. Fix many - aspects of how we detected the processor type. - * remote-udi.c, remote-adapt.c, remote-mm.c (*_open): Call it - rather than figuring out the type ourselves. - -Thu Sep 16 12:12:59 1993 Stu Grossman (grossman at cygnus.com) - - * sparc-stub.c (_trap_low): Do restore/save sequence after - setting sp to ensure that we load the previous window from the - right place on the stack. - -Thu Sep 16 00:36:32 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c: Many changes for alpha ecoff format: - Correct sizeof(int) == sizeof(long) assumptions. - Replace stParsed hack by putting the parsed types on the pending chain. - Replace mips specific ecoff mapping by ECOFF_REG_TO_REGNUM macro, - provide default for cross debugging. - Swapping the symbol back is no longer needed as the symbol is not - modified anymore. - Add new alpha basic types, handle btTypedef, handle stStaticProc - external symbols . - Update and clean up cross_ref for alpha cc cross ref variations. - Allocate types on the type_obstack to inhibit storage leaks. - * config/mips/tm-mips.h (ECOFF_REG_TO_REGNUM): Define. - * gdbtypes.c (recursive_dump_type): Dump TYPE_TAG_NAME if it is set. - -Tue Sep 14 09:12:17 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * stabsread.c (read_type): Process "s" (size) type attribute. - If type is defined to another type, copy the type. - -Tue Sep 14 18:37:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * config/i386/i386v4.mh (NATDEPFILES): Move exec.o from here... - * config/i386/i386v4.mt (TDEPFILES): ...to here. - -Tue Sep 14 12:21:49 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * Makefile.in (remote_utils_h): add serial.h and target.h. - (main.o, remote-es.o, remote-nindy.o, remote.o): remove target.h - (already in remote_utils_h). - (remote-utils.o): new rule. - - * remote-utils.h: include serial.h. - - * serial.h: ifdef protect from multiple inclusion. - - * remote.c, remote-nindy.c, remote-mon.c, remote-es.c: include - remote-utils.h. - - * remote.c (remote_open), remote-nindy.c (nindy_open, - nindy_files_info), remote-mon.c (general_open), remote-es.c - (es1800_open): use remote-utils facilities for baud rate. - -Tue Sep 14 09:12:17 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * paread.c, coffread.c, elfread.c, dwarfread.c: - Include and before libbfd.h. - - * paread.c: Define BYTES_IN_WORD before including aout/aout64.h. - - * Makefile.in (a29k-tdep.o): Depend on $(defs_h). - * config/a29k/tm-a29k.h (SAVED_PC_AFTER_CALL): Use gr122 not lr0 - if this is a transparent procedure. - -Mon Sep 13 16:06:43 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * remote.c: Define remote_debug to 0 and #if 0 baud_rate. Temporary - hack so this file compiles again. - - * remote-utils.c (gr_multi_scan): Cast return value from alloca. - (gr_multi_scan): #if 0 never-reached return(-1). - - * remote-udi.c (udi_wait): Return inferior_pid not 0. - -Mon Sep 13 14:14:35 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - Collect some remote things into remote-utils. - * remote-utils.[ch]: new files of functions collected from several - different remote targets. - * Makefile.in (REMOTE_O): add remote-utils.o. - (dcache_h, remote_utils_h): new macros. - (HFILES): add $(remote_utils_h). - (ALLDEPFILES): add $(remote_utils_h). - (dcache.o): new rule. - (main.o, remote-bug.o): also depend on $(remote_utils_h). - * target.h (remote_debug): extern moved to remote-utils.h. - * target.c (find_default_run_target, find_core_target): initialize - runable. - (remote_debug): moved to remote-utils.c. - (_initialize_targets): move declaration of user variable - remotedebug to remote-utils.c. - * remote-bug.c: include remote-utils.h rather than dcache.h. - (bug_close, bug_write, bug_write_cr, desc, bug_dcache, timeout, - dev_name, check_open, is_open, readchar, readchar_nofail, - pollchar, expect, expect_prompt, get_hex_digit, get_hex_byte, - get_hex_word, bug_kill, bug_detach, bug_create_inferior, - multi-scan, bug_prepare_to_store, bug_fetch_word, - bug_store_word, bug_files_info, bug_mourn, bug_com, bug_device, - bug_speed): removed and replaced with facilities from - remote-utils.[ch]. - (bug_read_inferior_memory): renamed to bug_read_memory. - (bug_write_inferior_memory): renamed to bug_write_memory. - (bug_xfer_inferior_memory): renamed to bug_xfer_memory. - (get_word): comment out this unused function for now. - (bug_settings, cpu_check_strings): new statics. - (bug_open): rewritten to use gr_open. - (_initialize_remote_bug): remove declarations of commands bug, - device, speed. - * main.c: include remote-utils.h. - (baud_rate): removed to remote-utils.c. - (main): handle baud rate settings using new facilities from - remote-utils. - * defs.h (baud_rate): removed extern. - - m88110 support via bug-197 monitor. - * remote-bug.c (get_reg_name, bug_fetch_register, - bug_store_register): added m88110 extended register support. - (wait_strings): added bug-197 prompt. - (bug_wait): cope with bug-197 prompt. - (start_load): cope with either bug-197 or bug-187 prompt. - -Mon Sep 13 12:53:09 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * inferior.h, infrun.c, thread.c, infcmd.c: Remove all uses of - pc_changed. If it was ever set to a non-zero value, it was before - GDB 2.8. It doesn't seem to have any useful function. - - * defs.h: Don't define NORETURN (see comment). - -Sat Sep 11 10:46:09 1993 Jim Kingdon (kingdon@poseidon.cygnus.com) - - * m88k-nat.c (fill_gregset): Set r31 and sfip. - -Thu Sep 9 10:18:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-udi.c (udi_wait, case UDIStdinNeeded): Use a loop calling - getchar() (terminated only on '\n') instead of scanf. Send the - '\n' which terminates it to the remote system. - - More gcc lint: - * exec.c (ignore): Return 0. - * stack.c (return_command): Fetch lazy value directly, not via - VALUE_CONTENTS, to avoid "value computed is not used". - * inflow.c (new_tty): Move osigttou inside #if. - - * remote.c (remote_fetch_registers): If remote reply is short, just - note that fact and keep going (reading extra registers as all bits 0). - (remote_store_registers): Send number of registers that were found - by remote_fetch_registers. - * m68k-tdep.c, config/m68k/tm-m68k.h, config/m68k/tm-*.h: Remove - HAVE_68881. Define CANNOT_STORE_REGISTER if ptrace() can't write - floating registers. - * config/m68k/{tm-m68k-nofp.h,m68k-nofp.mt,tm-m68k-fp.h,m68k-fp.mt}: - Remove, replaced by {tm-m68k-em.h,m68k-em.mt}. - * Makefile.in, configure.in: Change accordingly. - -Thu Sep 9 04:59:03 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (cross_ref): Allow SGI extended symbol types as cross - reference targets. - * symmisc.c (print_symbol): Use TYPE_TAG_NAME not TYPE_NAME to avoid - printing of identities. - -Wed Sep 8 19:18:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (breakpoint_1): Deal with step resume breakpoint. - -Wed Sep 8 13:01:10 1993 K. Richard Pixley (rich@cygnus.com) - - Gcc lint. - * config/m88k/tm-m88k.h (frame_find_saved_regs): prototype. - * config/h8300/tm-h8300.h (NUM_REGS): rewrite to avoid nested comment. - * blockframe.c (get_prev_frame_info): initialize address. - * breakpoint.c (bpstat_copy): initialize retval. - (bpstat_stop_status): initialize value_is_zero. - (bpstat_what): initialize bs_class. - (breakpoint_1, mention): add do-nothing case for bp_step_resume. - (break_command_1): initialize cond_end, addr_end, & - canonical_strings_chain. - (enable_breakpoint): initialize save_selected_frame. - * buildsym.c (end_symtab): initialize symtab & linetablesize. - * c-exp.y (parse_number): initialize i. - * c-typeprint.c (c_type_print_varspec_prefix): include - TYPE_CODE_BITSTRING in switch statements and do nothing. - * c-valprint.c (c_val_print): removed unused variable c. - * ch-valprint.c (chill_val_print): removed unused variable eltlen. - * cp-valprint.c (cp_print_class_method): initialize f & j. - * eval.c (evaluate_subexp): initialize pc2, arg1, arg2. - * expprint.c (print_subexp): initialize myprec, assoc, & tempstr. - * findvar.c (value_from_register): initialize first_addr. - * gdbtypes.c (lookup_struct_elt_type): localize use of temporary - variable typename. - * infcmd.c (run_stack_dummy): return zero rather than simple - return. - * infrun.c (wait_for_inferior): initialize stop_sp, prologue_pc. - remove symtab, appears unused. - (restore_selected_frame): return 1. - * mipsread.c (psymtab_to_symtab_1): initialize first_off. - (fixup_sigtramp): initialize b0. - * printcmd.c (do_examine): initialize val_type. - (print_frame_args): initialize b. - * ser-tcp.c (tcp_restore): comment out declaration. Appears - unused. - * ser-unix.c (hardwire_restore): comment out declaration. Appears - unused. - (hardwire_send_break): moved variable status into ifdef - HAVE_SGTTY. - (wait_for): moved variable numfds into ifdef HAVE_SGTTY. - * serial.h: comment change only. - * stabsread.c (rs6000_builtin_type): initialize rettype. - (read_range_type): initialize nbits. - * stack.c (print_frame_info): remove unused variable numargs. - (parse_frame_specification): remove unused variables arg1, arg2, - arg3. - (return_command): initialize return_value. - * symfile.c (cashier_psymtab): initialize pprev. - * symtab.c (find_pc_psymbol): initialize best. - (lookup_symbol): initialize s. - (make_symbol_completion_list): initialize quote_pos. - * thread.c: include command.h. - (thread_info): static declaration removed; unused. - (info_threads_command): fix == vs = typo. - * typeprint.c (whatis_exp): initialize old_chain. - * valprint.c (val_print_string): remove unused variable - first_addr_err. Initialize old_chain. - (_initialize_valprint): white space comment change. - * values.c (show_values): rewrite if statement to avoid empty - body. - (vb_match): remove unused variable fieldtype_target_type. - -Wed Sep 8 10:21:33 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (mipsread.o): Depend on $(bfd_h). - -Tue Sep 7 13:06:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbserver/Makefile.in (TAGS): config files are in - $(srcdir)/../config, not $(srcdir)/config. - - * config/pa/tm-hppa.h: Declare target_read_pc and target_write_pc. - (STORE_RETURN_VALUE): Pass the correct offset of the return - register to write_register_bytes. - * hppa-tdep.c: Use target_write_pc if PCOQ_TAIL_REGNUM was not saved. - -Tue Sep 7 14:30:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * remote.c (remote_wait): Don't call error. Instead, call warning - inside a loop. User can ^C to get out. - - * config/m68k/tm-m68k.h (FIX_CALL_DUMMY): Changed name of swapping - routine to match BFD name change. - * config/z8k/tm-z8k.h (FIX_CALL_DUMMY): Likewise. - -Mon Sep 6 15:01:57 1993 Jeffrey Wheat (cassidy@cygnus.com) - - * elfread.c: change elf32_symbol_type to elf_symbol_type - -Mon Sep 6 15:43:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * remote.c (remote_wait): Added 'W' and 'N' responses. - -Fri Sep 3 08:57:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c, utils.c: Add comments about immediate_quit. - - * elfread.c (elf_symtab_read): Don't add symbols starting with ".L" - to minimal symbols. - - * target.c (pop_target): Don't try to deal with the stack becoming - empty. Shouldn't happen and the code that tried was broken. - - * dcache.c: Cast return value from xmalloc. - - * remote.c: Move setting of immediate_quit from remote_open to - remote_start_dummy and set it back to zero when done. - -Thu Sep 2 00:07:36 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m88k-tdep.c: Remove a bunch of unused #includes. - - * language.h: Add comment about current_language. - - * mips-tdep.c (_initialize_mips_tdep): Change heuristic-fence-post - from var_uinteger to var_zinteger. - - * configure.in: Fix typo (delta88r4 -> delta88v4). - - * config/m88k/xm-delta88.h: Don't include sys/siginfo.h. It was - to make this work on SVR4 before SVR4 had its own configuration, - and it breaks SVR3. - - * config/m88k/tm-delta88v4.h: Define FRAME_CHAIN_VALID_ALTERNATE. - - * config/m88k/delta88v4.h (NATDEPFILES): Remove infptrace.o inftarg.o. - - * config/m88k/xm-dgux.h: Renamed from config/m88k/xm-m88k.h. - * config/m88k/m88k.mh: Use xm-dgux.h. - * config/m88k/xm-m88k.h: New file, with HOST_BYTE_ORDER, - MAKEVA_END and MAKEVA_ARG. - * config/m88k/xm-*.h: Include m88k/xm-m88k.h. - * printcmd.c: Remove __INT_VARARGS_H code; now in xm-m88k.h. - -Wed Sep 1 19:31:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-udi.c (udi_wait): Call `warning' not `error'. - - * symtab.c (COMPLETION_LIST_ADD_SYMBOL): If the symbol has a - demangling, don't put the mangled form in the completion list. - - * symtab.c, symfile.c, c-exp.y, ch-exp.y, m2-exp.y, buildsym.c, - symfile.h, stabsread.c, minsyms.c, solib.c, nlmread.c, dwarfread.c - partial-stab.h, symmisc.c, gdbtypes.c: Lint. Remove (or put - inside #if) unused variables and labels. Fix unclosed comment. - Deal with enumeration values unhandled in switch statements. Make - sure non-void functions return values. Include appropriate - headers. - * dbxread.c (elfstab_build_psymtabs): Don't check for unsigned - value < 0. - -Wed Sep 1 14:36:00 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * i960-tdep.c, ns32k-pinsn.c, remote-adapt.c, xcoffread.c: - index -> strchr. - -Wed Sep 1 11:35:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote.c: Add comment explaining why dcache is disabled. - (remote_fetch_word, remote_store_word): Make static and #if 0. - They are not called from anywhere. - -Wed Sep 1 14:41:28 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * arm-tdep.c, convex-tdep.c, convex-xdep.c, dbxread.c, - h8300-tdep.c, h8500-tdep.c, i960-pinsn.c, i960-tdep.c, - infptrace.c, m88k-tdep.c, mips-tdep.c, regex.c, remote-vx.c, - rs6000-tdep.c, xcoffexec.c, xcoffread.c, z8k-tdep.c, - config/arm/tm-arm.h, config/convex/tm-convex.h, - config/gould/tm-np1.h, config/gould/tm-pn.h, - config/m68k/tm-isi.h, config/ns32k/tm-umax.h, - config/pa/tm-hppa.h, config/pyr/tm-pyr.h, - config/rs6000/tm-rs6000.h, config/tahoe/tm-tahoe.h, - config/vax/tm-vax.h: bzero -> memset. - - * regex.c: bcmp -> memcmp. - -Wed Sep 1 11:35:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c (find_pc_line, find_line_common), - symtab.h (struct linetable), xcoffread.c (arrange_linetable): - Revise comments re linetable sorting. - * buildsym.c (compare_line_numbers): Sort by pc, not by line. - * coffread.c: Tell end_symtab to sort the line table. - - * coffread.c: Re-work a lot of the coff-specific stuff to use stuff - in buildsym.c. This includes coff_finish_block, coff_context_stack, - coff_local_symbols, coff_file_symbols, coff_global_symbols, - coff_end_symtab and coff_add_symbol_to_list. - (read_enum_type): Deal with it now that we have a "struct pending" - not a "struct coff_pending". - - * buildsym.c (end_symtab): Don't realloc subfile->linetable. - -Wed Sep 1 13:12:43 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * a68v-nat.c, altos-xdep.c, convex-tdep.c, convex-xdep.c, - findvar.c, hppab-nat.c, hppah-nat.c, i386mach-nat.c, - irix4-nat.c, m68k-tdep.c, m88k-tdep.c, mipsread.c, regex.c, - remote-bug.c, remote-hms.c, rs6000-nat.c, rs6000-tdep.c, - sparc-nat.c, stabsread.c, sun3-nat.c, sun386-nat.c, symfile.c, - umax-xdep.c, xcoffread.c, 29k-share/udi/udip2soc.c, - 29k-share/udi/udr.c, config/a29k/tm-a29k.h, config/arm/tm-arm.h, - config/convex/tm-convex.h, config/gould/tm-np1.h, - config/gould/tm-pn.h, config/h8300/tm-h8300.h, - config/h8500/tm-h8500.h, config/i386/tm-i386aix.h, - config/i386/tm-sun386.h, config/i386/tm-symmetry.h, - config/i960/tm-i960.h, config/m68k/tm-news.h, - config/m88k/tm-m88k.h, config/mips/tm-mips.h, - config/ns32k/tm-merlin.h, config/ns32k/tm-umax.h, - config/pa/tm-hppa.h, config/pyr/tm-pyr.h, - config/rs6000/tm-rs6000.h, config/sh/tm-sh.h, - config/tahoe/tm-tahoe.h, config/vax/tm-vax.h, - config/z8k/tm-z8k.h, nindy-share/nindy.c: bcopy -> memcpy. - -Wed Sep 1 05:05:53 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_partial_symbols): Use language from FDR if it - is unambigous. Patch from ptf@delcam.co.uk (Paul Flinders). - * mipsread.c (ecoff_symfile_info): New struct to hold the global - pending_list. - * mipsread.c (mipscoff_symfile_init, parse_partial_symbols): - Allocate the global pending list and link it to the objfile. - * mipsread.c (is_pending_symbol, add_pending): Use global pending - list from objfile. Allocate pending list entries from the - psymbol_obstack. - * mipsread.c (free_pending): Remove. The pending list is now - freed when the psymbol_obstack is freed. - * mipsread.c (psymtab_to_symtab1): Remove pending list allocation, - the global pending list is used now. - * mipsread.c (parse_partial_symbols): Skip only the first - file indirect entry when building the dependency list. - -Tue Aug 31 15:01:27 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - Break dcache code out of remote.c. - * dcache.h: white space changes only. - * dcache.c: add user settable variable to set whether data caching - is in use. - * remote.c: include dcache.h. removed data caching code which is - now in dcache.c. Compile in data caching again. (data caching - is currently off by default.) - (remote_read_bytes, remote_write_bytes): change second arg to - unsigned char. - (remote_dcache): new static variable. - * Makefile.in (REMOTE_O): add dcache.o. - * config/m88k/m88k.mt (TDEPFILES): removed dcache.o. - - Break dcache code out of remote-nindy.c. - * remote-nindy.c: removed dcache code. Changed callers to use new - conventions. include dcache.h. - (nindy_dcache): new static variable. - * config/i960/nindy960.mt (TDEPFILES): added dcache.o. - - Break dcache code out of remote-bug.c into dcache.[hc]. - * Makefile.in (dcache_h): new macro. - (HFILES): added $(dcache_h). - (ALLDEPFILES): added dcache.c. - (dcache.o): new rule. - (remote-bug.o): now depends on $(dcache_h). - * remote-bug.c: include dcache.h. remove externs for insque and - remque, add extern for bcopy. Prototype bug_close, - bug_clear_breakpoints, bug_write_cr. dcache code moved to - dcache.[hc]. Changed dcache calling convention to include an - initial DCACHE argument. - (bug_dcache): new static variable. - (bug_read_inferior_memory): change second arg to - unsigned char. - * dcache.[ch]: new files. - * config/m88k/m88k.mt (TDEPFILES): add dcache.o. - -Tue Aug 31 10:33:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * c-typeprint.c (c_print_type_base): Treat show = 0 just like - show < 0. The only case where we had been distinguishing is that - show = 0 used to print "struct " or "enum " instead of - "struct {...}" or "enum {...}" which seems clearly wrong. - -Mon Aug 30 17:51:32 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * configure.in: recognize m88110 as an m88k. - -Mon Aug 30 16:07:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valops.c (call_function_by_hand): If we discard cleanups, call - bpstat_clear (&inf_status.stop_bpstat). - -Mon Aug 30 12:47:46 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * stabsread.h, dbxread.c (end_psymtab): Return NULL if the psymtab - was empty and thrown away. - * mipsread.c (parse_partial_symbols): Do not add empty psymtabs to - dependency list, skip self dependencies. - * mipsread.c (parse_fdr): Removed, obsolete. - * mipsread.c (parse_lines): Check for cbLine being zero, not - cbLineOffset. - * mipsread.c (struct symloc): Add pst_language. - * mipsread.c (parse_partial_symbols): Set up proper language for - header files, save it in pst_language for psymtab_to_symtab_1. - * mipsread.c (psymtab_to_symtab_1): Use pst_language. - -Mon Aug 30 10:48:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Fix typo m88*-motorola-svr4* -> sysv4*. - -Fri Aug 27 17:09:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * paread.c: Include som.h instead of libhppa.h. (From Utah.) - -Fri Aug 27 09:30:40 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * symmisc.c (dump_symtab): Use catch_errors around print_symbol. - Change calling sequence of print_symbol to fit catch_errors. - - * mips-tdep.c: Call reinit_frame_cache every time the user does - "set heuristic-fence-post". - - * gdbserver/low-sun3.c: New file. - * gdbserver/Makefile.in, config/m68k/sun3.mh: Change accordingly. - - * Rename files for 14-character limits: - gdbserver/remote-gutils.c -> gdbserver/utils.c - gdbserver/remote-inflow.c -> gdbserver/low-lynx.c - gdbserver/remote-inflow-sparc.c -> gdbserver/low-sparc.c - gdbserver/remote-server.c -> gdbserver/server.c - remote-monitor.c -> remote-mon.c - * Makefile.in, gdbserver/Makefile.in, gdbserver/configure.in, - config/m68k/monitor.mt, config/i386/i386lynx.mh, - config/sparc/sun4os4.mh: Change accordingly. - * gdbserver/Makefile.in: Remove more junk inherited from gdb Makefile. - -Thu Aug 26 14:32:51 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infcmd.c, inferior.h (run_stack_dummy): If we stop somewhere - besides the dummy, return 1 rather than calling error(). - Let caller print the error message. Remove name argument. - * valops.c (call_function_by_hand): Deal with changes to calling - sequence of run_stack_dummy. Discard restore_inferior_status cleanup - if run_stack_dummy returns 1. - - * Version 4.10.2. - - * config/mips/tm-mips.h (EXTRACT_STRUCT_VALUE_ADDRESS): - Get struct return address from v0, not a0. - - * infrun.c (restore_inferior_status): Use catch_errors when - restoring selected frame. - -Wed Aug 25 21:52:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (save_inferior_status, restore_inferior_status): - Save and restore the registers too. - * inferior.h (struct inferior_status): Add "registers". - -Tue Aug 24 00:36:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c (end_psymtab): Clean up comment. - - * frame.h, symtab.h, findvar.c (read_var_value): Change basereg - support to use LOC_BASEREG rather than SYMBOL_BASEREG_VALID. - * dwarfread.c: Use LOC_BASEREG where appropriate. - * Various: Support LOC_BASEREG and LOC_BASEREG_ARG. - - * coffread.c (init_lineno, init_stringtab): Don't check whether - xmalloc returned NULL. - - * config/vax/xm-vaxult.h: Define NO_PTRACE_H. - - * target.c, target.h: Add "set remotedebug" command. - * remote-bug.c, remote.c, remote-mips.c: Remove "set remotedebug" and - "set m88ksnoop" options and use generic "set remotedebug" instead. - * NEWS: Describe this change. - -Mon Aug 23 20:26:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * buildsym.h: Remove declaration of dbxread.c functions. - * stabsread.h: Group together dbxread.c functions. - Move elfstab_build_psymtabs here from symfile.h. - Declare pastab_build_psymtabs. - * elfread.c, paread.c: Include stabsread.h (for stabsread_new_init - declaration, etc). - -Mon Aug 23 17:16:23 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * remote-bug.c: rename quiet to bug88k_snoop. - (double_scan, multi_scan): generalize double_scan into a scan - for multiple patterns. Rename to multi_scan. - (bug_wait, bug_write_inferior_memory): adapt to use the new - multi_scan in order to catch and represent target bus errors. - (bug_scan): currently unused, so comment out. - (bug_quiet): removed. Replaced with a standard user settable boolean. - - * m88k-tdep.c: remove include of sys/dir.h. Appears unnecessary - and isn't available on solaris. - -Mon Aug 23 14:56:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m88k/{delta88v4.mt,delta88v4.mh}: New files - * config/m88k/delta88.mh: Fix comment. - * config/m88k/tm-delta88.h: Remove unused BCS define. - * config/m88k/{tm-delta88v4.h,xm-delta88v4.h,nm-delta88v4.h}: - New files. - * configure.in: Recognize m88*-motorola-sysv4*. - * m88k-nat.c: Always include sys/types.h; don't depend on USG. - -Mon Aug 23 12:57:42 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_symbol, parse_type, cross_ref): Pass name of - symbol as an argument and use it in complaints. - * symmisc.c (dump_psymtab): Dump filenames of dependencies. - -Mon Aug 23 1993 Sean Fagan (sef@cygnus.com) - and Jim Kingdon (kingdon@cygnus.com) - - Add NetBSD support: - * configure.in: Recognize netbsd. - -Sun Aug 22 22:50:32 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (get_textlow): Don't go past a K_END when looking for a - K_FUNCTION. Avoids losing on source files with no functions. - -Fri Aug 20 14:01:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-nindy.c: Remove unused include of sys/ioctl.h. - - * frame.h, symtab.h: Revise comments regarding baseregs. - -Fri Aug 20 15:07:05 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_partial_symbols, psymtab_to_symtab_1): - Set language for psymtab and symtab. - * mipsread.c (new_symbol): Set language and initialize demangled - name for symbol. - * symmisc.c (print_symbol): Use SYMBOL_SOURCE_NAME when printing - the symbol type. - * symtab.c (decode_line_1): Inhibit coredumps with cfront executables. - -Fri Aug 20 14:01:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Move KERNEL_U_ADDR from xm-hp300bsd.h to nm-hp300bsd.h and make - it conditionalized on 4.3 vs. 4.4. - * config/m68k/nm-hp300bsd.h: Move REGISTER_U_ADDR out of 4.3 and - 4.4 sections; it was identical and now works for 4.4. - - * mips-tdep.c (is_delayed): Use INSN*BRANCH* not ANY_DELAY. - - * printcmd.c (MAKEVA_END): Update this version to use "aligner". - -Thu Aug 19 22:08:09 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/vax/tm-vax.h (BELIEVE_PCC_PROMOTION): Define. - * mipsread.c (parse_symbol, parse_type, cross_ref): Handle corrupt - file indirect entries with complaints instead of core dumps. Remove - complaint for stTypedef within aggregates. - -Thu Aug 19 17:58:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * coffread.c (process_coff_symbol): Ignore tagnames like .0fake. - - * coffread.c (coff_read_enum_type): #if 0 out code which changes - enum {FALSE, TRUE} into boolean. - - * config/m68k/delta68.m{t,h}: Use nm-delta68.h, etc. not - non-existent files nm-delta.h, etc. - * config/m68k/tm-delta68.h: Define CANNOT_STORE_REGISTER. - * delta68-nat.c: Add "[0]" in offsetof argument. - * delta68-nat.c (_initialize_kernel_u_addr): Don't try to set up - nl with initializer, just assign to it. Check n_scnum field on - return. - -Wed Aug 18 21:42:52 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (read_hpux_symtab): Call SET_NAMESTRING for K_MODULE - debug symbols. - -Wed Aug 18 12:03:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (print_address), values.c (value_as_pointer): Don't - use ADDR_BITS_REMOVE. - * defs.h: Try to clarify comment about ADDR_BITS_REMOVE. - - * blockframe.c (block_innermost_frame): Uncomment. - Return NULL if passed NULL. - * frame.h: Declare it. - * expression.h (union exp_element): Add field block. - * parse.c (write_exp_elt_block): New function. - * expression.h (OP_VAR_VALUE): Now takes additional struct block *. - * *-exp.y: Write block for OP_VAR_VALUE. - * eval.c, expprint.c, parse.c: Deal with block for OP_VAR_VALUE. - * valops.c, value.h (value_of_variable), callers: - Add second argument, for block. - - * main.c (gdb_readline): If we read some characters followed by EOF, - return them rather than returning NULL. - -Tue Aug 17 11:14:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mips-tdep.c: Remove unused #ifndef NUMERIC_REG_NAMES and add comment. - -Tue Aug 17 15:10:04 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * config/m88k/tm-m88k.h: Fix typo in comment. - (FP_REGNUM): define in terms of SP_REGNUM - rather than by absolute number. Also clearly comment that this - is a convenient lie in order to decrease future confusion. - (ACTUAL_FP_REGNUM): new macro for FP. - (FRAME_CHAIN_VALID): removed. Standard default works fine. - * m88k-tdep.c (frame_chain_valid): redundant, so removed. - (NEXT_PROLOGUE_INSN): removed unused fourth arg, fixed all - callers. - (read_next_frame_reg): declare static. - (examine_prologue): removed unused variabel insn2, rename insn1 - to insn, rewrote comment about finding fp, sp, etc. set frame_fp - based on ACTUAL_FP_REGNUM rather than FP_REGNUM which is - actually a scammed alias for SP_REGNUM on m88k. - - * frame.h: fixed typo in comment. - -Tue Aug 17 11:14:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * 29k-share/udi/udiphcfg.h: Always include udiphunix.h not udiphdos.h. - - * complaints.c (complain): fflush (stdout) after output. - -Tue Aug 17 01:43:55 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * blockframe.c, frame.h (sigtramp_saved_pc): New routine to fetch - the saved pc from sigcontext on the stack for BSD signal handling. - * config/i386/tm-i386bsd.h (SIGTRAMP_START, SIGTRAMP_END, FRAME_CHAIN, - FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC, SIGCONTEXT_PC_OFFSET): - Define to make backtracing through sigtramp work. - * config/vax/tm-vax.h (SIGTRAMP_START, SIGTRAMP_END, TARGET_UPAGES, - FRAME_SAVED_PC, SIGCONTEXT_PC_OFFSET): Ditto. - -Mon Aug 16 13:52:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (cd_command): If current_directory on entry is "/", then - don't append an extra slash. - Don't assume that /../.. means /. - - * target.c (target_xfer_memory): Clear errno before calling - to_xfer_memory. - - * stack.c (frame_info, print_frame_info): Add comment about using - the starting source line number on a line boundary if backtracing - through sigtramp. - -Mon Aug 16 09:52:33 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Add U Utah contribution notice. Add TODO list. - (hp_type_lookup): Use TYPE_NAME and TYPE_TAG_NAME. - (process_one_debug_symbol): Likewise. - -Mon Aug 16 02:56:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * blockframe.c (create_new_frame, get_prev_frame_info): - Use the function name when calling IN_SIGTRAMP. - * config/m68k/tm-m68k.h (SIG_PC_FP_OFFSET, SIG_SP_FP_OFFSET): - Define for correct handling of bachtraces through _sigtramp. - * m68k-tdep.c (m68k_find_saved_regs): Adjust saved sp for fake - sigtramp frames. - * mipsread.c (parse_type): Handle corrupt TIR info with complaint - instead of core dump. - * mipsread.c (parse_partial_symbols): Put static symbols into the - mimimal symbol table, use proper mst_types for all minimal symbols. - * stack.c (frame_info, print_frame_info): Use the starting source - line number on a line boundary if backtracing through sigtramp. - -Fri Aug 13 14:37:05 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * remote-bug.c: include gdbcmd.h. - (sleep, remque, insque): forward decls added. - (bug_fetch_registers, bug_store_registers): forward decls - removed. - (bug_read_inferior_memory, bug_write_inferior_memory): forward - decls added. - (srec_frame, srec_max_retries, srec_bytes, srec_echo_pace, - srec_sleep, srec_noise): new static variables for user settable - options. Mostly these are for debugging and tuning. I don't - expect them to stay user settable options for long. - (timeout): change default to 4 seconds. - (check_open): declare funtion static, force return value. - (readchar_nofail): if timeout, then say so if not being quiet. - (pollchar, double_scan, bug_scan, bug_srec_write_cr, - start_load): new functions. - (bug_wait): rewritten to use double scan. - (expect): while (1) -> for (;;) - (get_hex_digit): rewrite if condition to avoid gcc complaints. - (bug_load, bug_create_inferior, bug_open, bug_store_register): - removed unused variables. - (bug_load): replaced DELTA macro with user settable srec_frame - variable. Other minor lint. - (find_end_of_word, is_baudrate_right, set_rate, not_bug_wait, - gethex, timed_read, translate_addr, bug_before_main_loop): - unsused and removed. - (bug_resume): add missing first arg, pid. - (get_reg_name): use ip rather than cr04. - (bug_write, bug_write_cr, but_clear_breakpoints, bug_quiet): - declare type, args, and explicitly return. - (bug_store_register): straighten out the ip vs cr04 confusion. - (bug_write_inferior_memory): rewrite to cope with errors while - downloading s-records. - (bug_read_inferior_memory): declare static. - (bug_clear_breakpoints): expect nobr before prompt. - (_initialize_remote_bug): add initializations for srec-bytes, - srec-max-retries, srec-frame, srec-noise, srec-sleep, - srec-echo-pace. - - * Makefile.in (remote-bug.o): new rule. - (ALLDEPFILES): added remote-bug.c - - * remote-hms.c (hms_wait): use -1 for timeout's which means block - forever rather than 99999. - - * ser-unix.c (get_tty_state): if a descriptor is not a tty, then - simply save encode this fact as the process group and return - success rather than an error. - (set_tty_state): if process group is -1, do not reset the - process group. - (hardwire_reachar): comment change. - - * serial.h: comment change. - - * config/m88k/tm-m88k.h: comment change to remove embedded - comment. - (SKIP_PROLOGUE): skip_prologue returns a value which is expected - to reset the pc argument. So reset it. - -Fri Aug 13 10:15:24 1993 Fred Fish (fnf@deneb.cygnus.com) - - * Makefile.in (VERSION): Bump to 4.10.1 after release and cvs - tagging. - -Thu Aug 12 20:40:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbserver/Makefile.in: Use GDBSERVER_LIBS and - GDBSERVER_DEPFILES. Also remove much (but not all that could be - removed) crud inherited from gdb Makefile.in. - * config/i386/i386lynx.mh, config/sparc/sun4os4.mh: Define GDBSERVER_*. - * gdbserver/README: Say it works on Sun and change configuration - instructions slightly. - -Wed Aug 11 18:56:59 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * config/i386/i386v4.mh: use -lsocket and -lnsl, for remote - targets that use BSD style network connections - -Wed Aug 11 17:54:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-{monitor,bug}.c: Make bug_ops not static (forward declaration - of statics doesn't work with SunOS4 /bin/cc). - Rename the occurrence in remote-monitor.c to monitor_bug_ops. - -Tue Aug 10 13:07:14 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * blockframe.c (find_pc_partial_function), - mips-tdep.c (find_proc_desc): Deal with "pathological" case. - -Tue Aug 10 14:50:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c (wrap_here): Allow indent to be NULL. - (fputs_filtered): Don't check for null wrap_indent (wrap_here now - guarantees that it isn't, and anyway we were only checking one out - of the two places we dereferenced it). - - * objfiles.h (struct objfile): Clean up comments for - {obj,sym}_private to clarify what they are private to. - -Mon Aug 9 16:45:00 1993 Stan Shebs (shebs@rtl.cygnus.com) - - * stabsread.c, buildsym.c (hashname): Moved function to - buildsym.c, as suggested in the sources. - -Mon Aug 9 09:53:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-udi.c: Make udi_ops extern rather than trying forward - declaration of a static variable. - - * hppab-nat.c: Define ptrace to call_ptrace and pass the 5th arg - there, rather than using an ANSI C specific macro. - - * 29k-share/udi/udr.c: Include fcntl.h not sys/fcntl.h. Also put - sys/types.h near the top (just on general principles). - - * environ.c (set_in_environ): Remove G960BASE and G960BIN; they are - no longer used. - - * gdbcore.h: New variable gnutarget. - * core.c: Add commands to set and show it. - * Callers to bfd_*open*: Pass gnutarget instead of NULL as target. - * environ.c (set_in_environ): For GNUTARGET, use set_gnutarget not - putenv. - - * symtab.c (decode_line_1): Give error on unmatched single quote. - -Sun Aug 8 13:59:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * ser-unix.c (hardwire_send_break) [HAVE_SGTTY]: Use select not usleep. - - * remote.c: Add comments about 'd', 'r', and unrecognized requests. - - * inflow.c (terminal_init_inferior): Don't muck with tty state if - gdb_has_a_terminal() is false. - -Sun Aug 8 10:07:47 1993 Fred Fish (fnf@cygnus.com) - - * dwarfread.c (record_minimal_symbol): Remove prototype and - function. - * dwarfread.c (add_partial_symbol): Remove code to add minimal - symbols and remove comment about limitations. Experiments show - that now that gdb handles the ELF symtab better for creating - minimal symbols, that no additional information is added by - examining the DWARF information, and in fact, given the - limitations, the DWARF code was actually making things worse. - -Sat Aug 7 10:59:03 1993 Fred Fish (fnf@deneb.cygnus.com) - - * elfread.c (elf_symtab_read): Properly sort out the bss symbols - from the data symbols and give them the correct minimal_symbol_type. - Add file static symbols to the minimal symbol table, not just - global symbols. Add absolute symbols as well (like _edata, _end). - Redo stabs-in-elf special symbol handling now that file static - symbols are entered into the into the minimal symbol table. - * dwarfread.c (add_partial_symbol): Add comment about limitations - of DWARF symbols for distinquishing data from bss when adding - minimal symbols. Add file local symbols to minimal symbols. - -Thu Aug 5 08:58:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * ser-go32.c: Define job_control variable. - -Thu Aug 5 15:56:13 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * configure.in: z8k-coff is the same as z8k-sim - -Thu Aug 5 08:58:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * 29k-share/udi/udip2soc.c: Include sys/types.h before sys/file.h. - - * config/i386/tm-i386bsd.h (NUM_REGS): There are only 10, not 11. - - * inflow.c: Put all uses of F_GETFL and F_SETFL in #ifdef F_GETFL. - - * 29k-share/udi/udip2soc.c: Include fcntl.h not sys/fcntl.h. - -Wed Aug 4 18:32:12 1993 Fred Fish (fnf@cygnus.com) - - * inflow.c (pass_signal): Signal handlers take one int arg; - supply an unused one to make it type compatible as an arg to - signal(). - -Tue Aug 3 18:34:14 1993 Ian Lance Taylor (ian@cygnus.com) - - * config/mips/tm-mips.h: Include bfd.h before coff/sym.h. - -Tue Aug 3 15:34:57 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (ALLCONFIG): Add config/i386/i386nw.mt, - config/m68k/delta68.mh, config/m68k/delta68.mt, - config/m68k/dpx2.mh, config/m68k/dpx2.mt, config/mips/riscos.mh, - config/mips/news-mips.mh. - * Makefile.in (ALLPARAM): Add config/i386/nm-symmetry.h, - config/i386/tm-i386nw.h, config/m68k/nm-delta68.h, - config/m68k/tm-delta68.h, config/m68k/xm-delta68.h, - config/m68k/nm-dpx2.h, config/m68k/tm-dpx2.h, - config/m68k/xm-dpx2.h, config/mips/xm-makeva.h. - * Makefile.in (ALLDEPFILES): Add dpx2-nat.c. - -Tue Aug 3 12:02:09 1993 Ian Lance Taylor (ian@cygnus.com) - - * mipsread.c: Updated for BFD ECOFF changes. Now gets the - swapping routines and external structure sizes via the - ecoff_backend information. No longer includes coff/mips.h. - -Tue Aug 3 10:58:04 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (SFILES): Add thread.c - -Tue Aug 3 10:21:58 1993 Doug Evans (dje@canuck.cygnus.com) - - * remote-sp64sim.c (simif_create_inferior): Add FIXME regarding - sim_set_args return code. - -Mon Aug 2 16:35:31 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * Makefile.in (VERSION): bumped to 4.9.4. - - * remote-monitor.c: updated copyright. - (bug_ops, monitor_desc): now static. - (monitor_desc): in several places, check and/or set to NULL. - - * remote-hms.c (hms_files_info): Add the appropriate items where - missing in the printf call. - - * remote-bug.c: new file for m88k bug support. - - * config/m88k/m88k.mt (TDEPFILES): added remote-bug.o. - -Mon Aug 2 14:22:09 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * h8300-tdep.c: Use new variable h8300hmode. - -Mon Aug 2 12:06:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valops.c (typecmp): If we are passing a non-reference to a function - which takes a reference, pass the address. - (value_arg_coerce): Don't use COERCE_ENUM; we don't want to dereference - references here. - - * thread.c (thread_switch): Define as static. - (add_thread): Cast return value from xmalloc. - - * gdbtypes.c (fill_in_vptr_fieldno): Call check_stub_type. - * gdbtypes.{c,h}: Improve comments on vptr_fieldno. - -Mon Aug 2 11:58:52 1993 Fred Fish (fnf@deneb.cygnus.com) - - * README: Elaborate on gdb C++ support and cfront support. - -Mon Aug 2 11:30:57 1993 Stu Grossman (grossman at cygnus.com) - - * i386lynx-nat.c, thread.c, thread.h: Update copyrights. - -Mon Aug 2 12:06:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (ALLDEPFILES): Add i386lynx-nat.c. - -Mon Aug 2 08:42:50 1993 Stu Grossman (grossman at cygnus.com) - - * gdbserver/remote-inflow.c (create_inferior): Fix comments, and - error msg. Setup seperate process group for child. - * (write_inferior_memory): Sleep for 1 second and retry on ptrace - failure. - -Sun Aug 1 22:58:18 1993 Stu Grossman (grossman at cygnus.com) - - * config/i386/i386lynx.mh (NATDEPFILES): Drop coredep (for now). - * config/i386/nm-i386bsd.h: Protect from multiple inclusion. - * config/i386/nm-i386lynx.h: Lotsa new host porting stuff. - * config/i386/tm-i386lynx.h: Define SAVED_PC_AFTER_CALL and - target_pid_to_str. - - * Makefile.in (CLIBS): Reorder to make Lynx ld happy. - * (HFILES): New file thread.h. - * (OBS): New file thread.c. - * configure.in: Host config for Lynx/386. - * fork-child.c (fork_inferior): Call init_thread_list(). - * infrun.c (resume): Add pid to invocation of target_resume(). - * (wait_for_inferior): Pay attention to pid from target_wait(). - Multi-threading code now uses this to determine what to do. - * inftarg.c (child_wait): Conditionalize based on CHILD_WAIT macro. - Use target_pid_to_str() macro throughout when printing pid. - * inferior.h (child_resume): Add pid to prototype. - * hppab-nat.c hppah-nat.c infptrace.c (child_resume): Pass in pid as - argument, instead of using inferior_pid. - * procfs.c (procfs_resume): Pass in pid as argument. Ignored for - now. Use target_pid_to_str() macro throughout for printing process id. - * remote-adapt.c (adapt_resume): Pass in pid as argument. - * remote-eb.c (eb_resume): Pass in pid as argument. - * remote-es.c (es1800_resume): Pass in pid as argument. - * remote-hms.c (hms_resume): Pass in pid as argument. - * remote-mips.c (mips_resume): Pass in pid as argument. - * remote-mm.c (mm_resume): Pass in pid as argument. - * remote-monitor.c (monitor_resume): Pass in pid as argument. - * remote-nindy.c (nindy_resume): Pass in pid as argument. - * remote-sa.sparc.c (remote_resume): Pass in pid as argument. - * remote-sim.c (rem_resume): Pass in pid as argument. - * remote-sp64sim.c (simif_resume): Pass in pid as argument. - * remote-st.c (st2000_resume): Pass in pid as argument. - * remote-udi.c (udi_resume): Pass in pid as argument. - * remote-vx.c (vx_resume): Pass in pid as argument. - * remote-z8k.c (rem_resume): Pass in pid as argument. - * remote.c (remote_resume): Pass in pid as argument. - * solib.c (solid_create_inferior_hook): Pass inferior_pid to - target_resume(). - * target.c (normal_pid_to_str): New routine to print out process - ID normally. - * target.h (struct target_ops): Add pid to prototype at - to_resume(). (target_resume): Add pid argument. - * (target_pid_to_str): Default definition for normal type pids. - * thread.h, thread.c: New modules for multi thread/process control. - -Sun Aug 1 13:02:42 1993 John Gilmore (gnu@cygnus.com) - - * README: Say that bug-gdb is also the place to send requests - for help with GDB. - -Sun Aug 1 09:42:13 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (make-proto-gdb-1): Use -f opt on rm of Makefile. - * h8500-tdep.c: Add parens around a few macro args. - -Fri Jul 30 15:43:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Remove items about unix-to-unix/rapp debugging (now we - have gdbserver), moving xm files to subdirectory, ptype yylval, - and file-local symbols. - - * gdbtypes.h: Improve comments about C++ methods. - -Fri Jul 30 14:16:32 1993 Fred Fish (fnf@deneb.cygnus.com) - - * c-exp.y: Add missing 5th arg for one call to lookup_symbol, cast - NULL in all other calls to correct pointer types. - -Fri Jul 30 15:43:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - From Jeffrey Law: - * tm-hppa.h (TARGET_WRITE_PC): Define. - * hppa-tdep.c (hppa_fix_call_dummy): If in a syscall, - then return the address of the dummy itself rather than - the address of $$dyncall. - (target_write_pc): New function to store a new PC. - -Fri Jul 30 12:51:27 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - and Jim Kingdon (kingdon@cygnus.com) - - * breakpoint.c (breakpoint_re_set_one): Always reparse breakpoint - conditions, they might contain symbol table references. - -Fri Jul 30 12:51:27 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_symbol): Handle opaque struct definitions and - type naming for stTypedef symbols. - -Fri Jul 30 14:44:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * c-exp.y (yylex): Detect C++ nested types. - -Fri Jul 30 11:07:37 1993 Doug Evans (dje@canuck.cygnus.com) - - * sp64-tdep.c (sparc64_frame_chain, sparc64_frame_saved_pc): Deleted. - (dump_ccreg, sparc_print_register_hook): New fns. - * remote-sim.h: New file. - * remote-sp64sim.h (sim_*): External fns. (simif_*): Internal fns. - - * config/sparc/sp64.mt: New file. - * config/sparc/tm-sp64.h (FRAME_CHAIN, FRAME_SAVED_PC): Deleted. - (PRINT_REGISTER_HOOK): Call new fn sparc_print_register_hook. - -Fri Jul 30 10:15:01 1993 Fred Fish (fnf@deneb.cygnus.com) - - * Makefile.in (ALLCONFIG): Add config/i386/ptx.mh - -Fri Jul 30 08:58:01 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - From J. Law: - * infcmd.c (read_pc): Remove PA specific code. - * tm-hppa.h (TARGET_READ_PC): Define. - * hppa-tdep.c (target_read_pc): New function. - - * symtab.c (gdb_mangle_name): Deal with it if type lacks a name. - -Fri Jul 30 07:36:53 1993 Fred Fish (fnf@deneb.cygnus.com) - - * NEWS: Add note that DEC alpha support is host only, not native. - * README: Emphasize that C++ support works best with GNU C++ and - stabs debugging format. - * delta68-nat.c: Add missing FSF copyright. - -Fri Jul 30 08:58:01 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * paread.c (pa_symtab_read): Put file-local symbols in minimal symbols. - * hppa-tdep.c (frame_chain_valid): Check that our function has the - same address as _start, not that it must be the same symbol. - -Fri Jul 30 00:18:40 1993 Fred Fish (fnf@deneb.cygnus.com) - - * Makefile.in (ALLDEPFILES): Add delta68-nat.c - * Makefile.in (delta68-nat.o): Add dependency. - -Thu Jul 29 12:09:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * value.h (COERCE_ENUM): Use COERCE_REF to coerce refs; value_ind - was adequate in gdb 3.5 but not now. - - * valops.c (typecmp): An array in t2 matches a pointer in t1. - - * valops.c (typecmp): When comparing type1& to type2, compare - type1 and type2 as leniently as if we were comparing type1 to - type2. - - * cp-valprint.c (cplus_print_value): Don't dump core if the - baseclass doesn't have a name. - * values.c (vb_match): New function, which finds the virtual - base class pointer even if the types are nameless. - (baseclass_{addr,offset}): Use it. - - * hppa-tdep.c: Make "maintenance print unwind" command from old - "unwind" command. - - * remote-udi.c: Remove udi_timer, call to siginterrupt, and associated - obsolete junk which apparently had been copied from the - pre-serial.h remote.c, but which is no longer used. - -Thu Jul 29 12:36:20 1993 Fred Fish (fnf@deneb.cygnus.com) - - * Makefile.in (NONSRC): Need 29k-share/README, not - 29k-share/udi/README. - -Thu Jul 29 12:09:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * paread.c (pa_symfile_init): If error reading string table, don't - use errno in cases where it hasn't been set. - - * ser-unix.c (gdb_setpgid): Pass our pid, not 0, to setpgid. - - * remote-monitor.c (_initialize_monitor): Comment out use of - connect_command, since connect_command itself is commented out. - - * remote-monitor.c (generic_open): Parse arguments the same way - as remote.c. - - * hppa-tdep.c (pc_in_linker_stub): Fix unclosed comments. - -Wed Jul 28 13:19:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/xm-mips.h: Define HAVE_TERMIOS. - - * dbxread.c (record_minimal_symbol): Don't put gcc_compiled or - __gnu_compiled* symbols into the minimal symbols. - -Wed Jul 28 08:26:58 1993 Ian Lance Taylor (ian@cygnus.com) - - * remote-mips.c (_initialize_remote_mips): Added "timeout" and - "retransmit-timeout" variables to set mips_receive_wait and - mips_retransmit_wait, respectively. - -Wed Jul 28 03:58:58 1993 (pes@regent.e-technik.tu-muenchen.de) - - * symmisc.c (dump_msymbols): Handle new mst_file_* types. - -Tue Jul 27 12:07:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-udi.c: Remove old comment about download not implemented. - - * serial.h, ser-{unix,go32,tcp}.c: Add flush_input and send_break. - * nindy-share/*, remote-nindy.c: Extensive hacking to make it - conform to GDB conventions like using memcpy not bcopy, serial.h, - etc. This is to make it host on Solaris, AIX, etc. - * Makefile.in: Reflect removed nindy-share files. - * config/i960/nindy960.mt (TDEPFILES): Remove ttybreak.o. - - * stack.c (print_frame_info): Revise comment about `pathological' - case (there was a wrong FIXME about text labels; also asm() can - trigger this as well as versions of ar which truncate .o names). - - * buildsym.c (start_subfile): If a .c file includes a .C file, set - the language of both of them to C++. - - * config/sparc/xm-sun4os4.h: Define MEM_FNS_DECLARED and include - . - Include rather than declaring malloc functions ourself. - - * ser-unix.c (set_tty_state): Don't ignore errors setting process - group. - * inflow.c (terminal_inferior): If attach_flag set, ignore errors - from set_tty_state. - - * fork-child.c (fork_inferior): Only quote exec file if needed. - - * mipsread.c (parse_symbol): Remove 21 Jul 93 change with - stTypedef inside an stBlock. - -Tue Jul 27 12:36:49 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * breakpoint.c (breakpoint_1): Walk the breakpoint chain to decide if - we have breakpoints or watchpoints as we might have to ignore internal - breakpoints. - - Fix gdb core dumps after `file newfile' commands. - * symtab.h, symfile.c (clear_symtab_users): New routine which - unconditionally clears symtab users. clear_symtab_users_once - commented out as it was a noop anyway. - * objfiles.c (free_objfile): Don't call clear_symtab_users_once. - * objfiles.c (free_all_objfiles), symfile.c (new_symfile_objfile), - xcoffexec.c (exec_close): Call clear_symtab_users if necessary. - * symfile.c (syms_from_objfile): Install cleanups for errors during - symbol reading. - * coffread.c, dbxread.c, mipsread.c, xcoffread.c (*_symfile_read): - Lint cleanup code, call do_cleanups explicitly. - * symfile.c (symbol_file_add): Call new_symfile_objfile and - reinit_frame_cache _after_ the new symbols are read in. - -Tue Jul 27 01:57:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_type): Do not set tag name for compiler - generated fake tag names. - -Mon Jul 26 17:31:49 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * config/m88k/m88k.mt (TDEPFILES): add exec.o. - -Mon Jul 26 13:17:36 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * hppa-tdep.c: Remove all uses of use_unwind and `set use_unwind' - command. Now we use unwind info by default if we can find it. - - * config/sparc: Move VARIABLES_INSIDE_BLOCK and SUN_FIXED_LBRAC_BUG - to tm-sparc.h so they are shared between Solaris and SunOS4. - * dbxread.c (process_one_symbol): Deal with SunOS4 acc N_STSYM and - N_GSYM functions. - - * config/pa/tm-hppa.h (REGISTER_NAMES): Use "fr" rather than "fp" - for floating point registers. - - * mipsread.c (parse_symbol): Put stStaticProc symbols in minimal - symbols as mst_file_text. - - * hppa-tdep.c (pc_in_linker_stub): Return 0 if can't read memory. - - * stabsread.c (rs6000_builtin_type): Make logical types be - TYPE_CODE_BOOL. - -Sun Jul 25 23:41:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.{c,h} (struct breakpoint): Replace symtab field with - source_file field. - -Fri Jul 23 09:57:25 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * remote.c: Don't error() on errors xferring memory. - * target.h: Clean up comments about *xfer_memory. - - * exec.c, corelow.c (target_ops struct): Don't allow - {insert,remove}_breakpoints to be defaulted to - memory_{insert_remove}_breakpoint. - - * demangle.c: Make it so `help set dem' tells you how to get the - list of demangling styles. - -Thu Jul 22 15:41:09 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * Makefile.in: Use REMOTE_O macro not remote.o. - * config/i960/{nindy960,vxworks960}: Don't use remote.o. - -Thu Jul 22 12:43:25 1993 Ian Lance Taylor (ian@cygnus.com) - - * coredep.c: If NEED_SYS_CORE_H defined, include - (can't include it in nm-*.h file because it causes conflicts with - a.out symbol definitions). - * hp300ux-nat.c (fetch_core_registers): Commented out; obsolete. - * config/m68k/hp300hpux.mh (NATDEPFILES): Added coredep.o and - corelow.o. - * config/m68k/nm-hp300hpux.h (NEED_SYS_CORE_H): Defined. - (REGISTER_U_ADDR): Defined. - * config/m68k/xm-hp300hpux.h (HAVE_TERMIOS): Define instead of - HAVE_TERMIO. - * config/pa/xm-hppah.h: Likewise. - -Wed Jul 21 11:37:30 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * mipsread.c (parse_symbol): when stTypedef and friends occur within - an stBlock, skip over the fields of the inner one. - - * mips-tdep.c (init_extra_frame_info): If in lenient prologue, call - heuristic_proc_desc rather than just assuming registers not saved. - - * Makefile.in (regex.o): Add dependency. - - * hppa{b,h}-nat.c: Warning, not error, if can't access registers. - - * config/pa/hppa{b,h}.h: Define ATTACH_DETACH. - -Wed Jul 21 03:07:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/xm-makeva.h: New file implements va_list alignment - restrictions for mips hosts. - * config/mips/{xm-irix3.h, xm-mips.h, xm-news-mips.h, xm-riscos.h}: - Use it. - -Wed Jul 21 00:11:05 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-tdep.c (init_extra_frame_info): Do not check for - mips_in_lenient_prologue if it is a dummy frame. - * mipsread.c (fixup_sigtramp): Initialize pdr.adr, it is used by - mips_in_lenient_prologue. - -Tue Jul 20 14:14:59 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (read_hp_array_type): Handle "char foo[]". - -Tue Jul 20 12:53:47 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * mips-tdep.c (heuristic_proc_start): First time we print the - warning, elaborate. - (_initialize_mips_tdep): Improve docstring for `set heur'. - - * config/rs6000/tm-rs6000.h: Remove call to insert_step_breakpoint. - - * symtab.c (find_line_symtab): New function, to deal with multiple - symtabs with the same name. - (find_line_pc{,_range}): Use it. - (find_pc_symtab): Add comment about overlapping symtabs. - -Mon Jul 19 21:29:14 1993 Fred Fish (fnf@deneb.cygnus.com) - - * Makefile.in (SFILES): Add nlmread.c. - * Makefile.in (OBS): Add nlmread.o. - * Makefile.in (nlmread.o): Add new target. - * configure.in (i[34]86-*-netware): New configuration. - * nlmread.c, config/i386/{i386nw.mt, tm-i386nw.h}: New files - for NLM/NetWare support. - -Mon Jul 19 11:48:57 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * symtab.h (enum minimal_symbol_type): Add mst_file_*. - * partial-stab.h [DBXREAD_ONLY]: Record statics in miminal symbols. - * dbxread.c (record_minimal_symbol): Deal with statics. - * minsyms.c (lookup_minimal_symbol): Prefer externals to statics. - - * config/i386/xm-i386sco.h: Define HAVE_TERMIOS. - - * printcmd.c, config/pa/xm-pa.h, config/alpha/xm-alpha.h: Make it so - arg_bytes field of makeva_list is always aligned. - * config/pa/xm-pa.h: Make arglist_address a char *. - - * ser-unix.c: Don't try to use job control with termio. - -Sun Jul 18 23:11:28 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - and Jim Kingdon (kingdon@cygnus.com) - - Make breakpoint_re_set_one work with overloaded member functions, - `b 123' and `b foo' if foo is a static function. - * symtab.c (decode_line_1, decode_line_2): New argument `canonical' - to return canonical line specs if requested by the caller. - * breakpoint.c, source.c, symtab.c, symtab.h: Change prototypes and - callers accordingly. - * symtab.c (build_canonical_line_spec): New helper function which - constructs the canonical line spec. - * breakpoint.c (break_command_1): Use canonical line spec instead - of command string as addr_string if necessary. - * source.c (line_info): Fix storage leak. - -Sun Jul 18 15:22:45 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * infptrace.c: Split out define of PT_KILL; Sequent defines PT_KILL - but not the others. - * symm-tdep.c: Remove exec_file_command. - [_SEQUENT_] (ptx_coff_regno_to_gdb, register_addr): New functions. - A few miscellaneous cleanups. - * symm-nat.c: Renamed from symm-xdep.c. - * All symmetry dependent files: Many changes. - - * mips-tdep.c (mips_skip_prologue): New argument lenient. - Use read_memory_nobpt. - (is_delayed, mips_in_lenient_prologue): New functions. - (init_extra_frame_info): If in the prologue, don't use saved registers. - * config/mips/tm-mips.h: Declare mips_skip_prologue. - - * partial-stab.h (N_SO): Add the text offset to valu before, not after, - passing it to END_PSYMTAB. - -Fri Jul 16 18:48:52 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * symtab.c (find_pc_symtab): Call warning, not printf directly. - - * solib.c (solib_add): Use x{re,m}alloc, not {re,m}alloc. - -Fri Jul 16 09:56:42 1993 Ian Lance Taylor (ian@cygnus.com) - - * mipsread.c: No longer need to undefine ZMAGIC. - -Thu Jul 15 18:03:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m88k-pinsn.c: Moved code into opcodes/m88k-dis.c. - (print_insn): Now just calls print_insn_m88k. - -Thu Jul 15 14:54:05 1993 Doug Evans (dje@canuck.cygnus.com) - - * h8300-tdep.c (examine_prologue): Make prototype match definition. - -Thu Jul 15 08:34:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * NEWS: Mention that remote.c now has a `load' operation. - - * hppa-tdep.c (pc_in_linker_stub): New function. - (find_proc_framesize): Return 0 for linker stubs. - (rp_saved): Tell the caller where rp is saved. - (frame_chain_valid): Return 1 for linker stubs. - (frame_saved_pc): Use return value from rp_saved. - - * stack.c (print_frame_info): When checking PC_IN_CALL_DUMMY, - pass the sp relative to the frame in question, not the sp in the - innermost frame. - -Wed Jul 14 17:37:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mipsread.c (parse_procedure): Take as argument the symtab to look - the name up in. Look it up with mylookup_symbol, not lookup_symbol. - (psymtab_to_symtab_1): For stabs, pass the symtab to parse_procedure. - - * mipsread.c (mylookup_symbol): Use strcmp, not STREQ, as we have - already checked the first characters. - - Changes from Jeffrey Law: - * printcmd.c (makeva_list): Use MAKEVA_EXTRA_INFO to define - machine dependent fields in the makeva_list structure. - (makeva_size): Allocate extra space to handle gaps made by - alignment restrictions. - * config/pa/xm-pa.h (MAKEVA_EXTRA_INFO): Define. - (MAKEVA_START): Initialize arglist_address field. - (MAKEVA_ARG): Always store arguments on natural alignment - boundaries. Set arglist_address to the address right after - the args. - (MAKEVA_END): Simply return the value stored in arglist_address. - -Wed Jul 14 13:51:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * ch-valprint.c (chill_val_print, case TYPE_CODE_STRING): Print - address, not addr. - - * hppah-nat.c (store_inferior_registers): Don't print i in cases - where we aren't using it. - - * a29k-tdep.c (get_saved_register): Fix typo. - -Wed Jul 14 09:45:52 1993 Doug Evans (dje@canuck.cygnus.com) - - * configure.in: Recognize h8300h (variant of h8300). - -Wed Jul 14 09:45:52 1993 Doug Evans (dje@canuck.cygnus.com) - - * configure.in: Recognize sparc64-*-*. - -Tue Jul 13 14:03:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (define_symbol): Make the caddr_t hack apply to `function - returning foo' as well as `pointer to foo'. - - * remote.c [REMOTE_BREAKPOINT]: Use for breakpoint insn if defined. - * config/m68k/tm-m68k.h: Define it. - * mem-break.c, breakpoint.c: Improve comments. - -Tue Jul 13 13:35:31 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr) - - * config/m68k/tm-dpx2.h: Replace "tm-68k.h" with "m68k/tm-m68k.h". - * config/m68k/xm-dpx2.h: Define HAVE_TERMIOS not HAVE_TERMIO. - -Tue Jul 13 11:50:38 1993 Doug Evans (dje@canuck.cygnus.com) - - * gdbcore.h (read_memory_integer, read_memory_unsigned_integer): - Make prototype match definition. - -Tue Jul 13 11:15:15 1993 Fred Fish (fnf@cygnus.com) - - * elfread.c: Remove notice about file still being under - construction. - * Makefile.in (ultra3-xdep.o, umax-xdep.o): Add missing ')'. - -Mon Jul 12 17:46:35 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * a29k-tdep.c (read_register_stack): Make val static. - -Mon Jul 12 14:10:48 1993 Doug Evans (dje@canuck.cygnus.com) - - * config/h8300/tm-h8300.h (REGISTER_CONVERTIBLE): Change value to 0. - (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Move def'n to - usual spot. - -Mon Jul 12 11:29:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * c-valprint.c (c_val_print): Fix thinko with unspecified length - arrays. - - * hppa-tdep.c (find_proc_framesize): If there is a frame pointer, - use it. - -Sun Jul 11 19:35:05 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c (decode_line_1): Use end of block to figure out whether - val.end is in the same function, not minimal symbols. - - * source.c (line_info): Add a few more wrap_here's. - - * i386-tdep.c (i386_follow_jump): Do byteswapping where needed and - don't make assumptions about sizes of host data types. - - * blockframe.c, symtab.h (find_pc_partial_function): New arg endaddr. - * infrun.c, breakpoint.c, printcmd.c: Change callers. - * printcmd.c (containing_function_bounds): Remove. - * printcmd.c (disassemble_command): Use find_pc_partial_function, - not containing_function_bounds. - * infcmd.c (step_1): Use find_pc_partial_function rather than - trying to roll our own. Move check for a pc between SIGTRAMP_START and - SIGTRAMP_END in find_pc_partial_function, not step_1. - - * sparc-tdep.c (sparc_frame_chain, frame_saved_pc): - Keep unswapped value in array of char, not REGISTER_TYPE. - Use REGISTER_RAW_SIZE not sizeof (REGISTER_TYPE). - (sparc_extract_struct_value_address): Use TARGET_PTR_BIT not - sizeof (CORE_ADDR). - -Thu Jul 1 15:50:05 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr) - - * configure.in (m68*-bull-sysv*): added support for Bull dpx2. - * config/m68k/{t,x,n}m-dpx2.h, dpx2-nat.c: New files. - * config/m68k/dpx2.m{h,t}: New files. - -Thu Jul 1 15:46:10 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Run through gnu-indent. - -Sun Jul 11 12:32:08 1993 Doug Evans (dje@canuck.cygnus.com) - - * config/sparc/tm-sparc.h (PRINT_REGISTER_HOOK): Fix typo, add - more parens around macro arg. - -Sat Jul 10 09:54:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c: Remove step_resume_{duplicate,shadow}. Replace - step_resume_break_address with step_resume_breakpoint (now local - to wait_for_inferior). - ({insert,remove}_step_breakpoint): Remove. - (wait_for_inferior): Set step resume break with - set_momentary_breakpoint. Test hitting it with bpstat_stop_status - and bpstat_what (stop_step_resume_break removed). - * breakpoint.{h,c}, infrun.c: Return value from bpstat_what now struct - which includes previous return value as main_action, and a step_resume - bit. - * breakpoint.c (delete_breakpoint): If breakpoint was inserted, and - there is another breakpoint there, insert it. - * infrun.c (wait_for_inferior): Rearrange the spaghetti a bit. Use - a few more gotos. - Various: Clean up and add comments. - - * infrun.c [TDESC]: Remove remaining tdesc code (see ChangeLog - for Wed Nov 13 16:45:13 1991). - -Fri Jul 9 12:36:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * values.c, value.h (modify_field), callers: Make fieldval a LONGEST. - - * h8300-tdep.c (NEXT_PROLOGUE_INSN): Make pword1 an INSN_WORD * - not short *. - - * findvar.c, defs.h - ({extract,store}_{signed_integer,unsigned_integer,address}): - New routines to replace SWAP_TARGET_AND_HOST. - All over: All uses of SWAP_TARGET_AND_HOST on integers replaced. - - * config/sparc/tm-sparc.h: Add comment suggesting that removing - ins and locals from the registers array might clean things up. - - * utils.c: Clean up comments about wrap buffer and wrap_here. - * printcmd.c (printf_command): Call wrap_here before vprintf. - - * mipsread.c (cross_ref): Set the name to unknown for "struct *" case. - Patch from ptf@delcam.co.uk (Paul Flinders). - - * a29k-tdep.c, findvar.c (get_saved_register): Fix byteswapping sins. - -Fri Jul 9 09:47:02 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * defs.h, remote-eb.c (TM_FILE_OVERRIDE): Remove it. - * mips-tdep.c (init_extra_frame_info): Set proper fci->frame if pc - is at the start of the dummy code. - -Thu Jul 8 14:48:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * sparc-tdep.c (sparc_push_dummy_frame): Skip all the do_save_insn - stuff, just write the sp and fp. - (sparc_pop_frame): Skip the do_restore_insn; we already restore - the sp with the other out registers. - - * hppa-tdep.c (hppa_push_arguments): Allocate enough space for - arguments. - - * hppa-tdep.c: Change _initialize_hppab_tdep to _initialize_hppa_tdep. - -Thu Jul 8 14:47:00 1993 Doug Evans (dje@canuck.cygnus.com) - - * sparc-tdep.c (sparc_frame_chain): Handle sizeof (CORE_ADDR) - != sizeof (REGISTER_TYPE). - (frame_saved_pc): Ditto. - -Thu Jul 8 08:22:05 1993 Doug Evans (dje@canuck.cygnus.com) - - * config/h8300/tm-h8300.h: (REGISTER_TYPES): Adjust for h8/300h. - (REGISTER_RAW_SIZE): Ditto. - (REGISTER_VIRTUAL_TYPE): Use builtin_type_unsigned_long for regs - on the h8/300h (ints may still be 16 bits). - (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE, - EXTRACT_STRUCT_VALUE_ADDRESS): Add FIXME's for h8/300h. Some - thought needed here. - - * h8300-tdep.c (print_insn): Call print_insn_h8300h if h8/300h. - (examine_prologue): reg_save_depth is 4 if h8/300h. - - * findvar.c (read_register): Provide some support for 64 bit regs. - (write_register): Ditto. - -Wed Jul 7 14:30:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/nm-riscos.h: machine/machparam.h is always the right - place to look for BSD43_NBPG, not machine/vmparam.h - - * infcmd.c (run_stack_dummy): New argument name. - Change error message in (another) attempt to make it comprehensible. - * valops.c (call_function_by_hand): Pass name to run_stack_dummy. - * symtab.h: Declare demangle and asm_demangle since macros use them. - - * eval.c (evaluate_subexp): Add comment about calling a member - function of a variable in a register. - - * expression.h: Clean up comment about string in STRUCT_STRUCT etc. - - * config/{rs6000/tm-rs6000.h,sparc/tm-sparc.h,pyr/tm-pyr.h}, - inferior.h (PC_IN_CALL_DUMMY) [ON_STACK]: Add comments about stack - frame tops and bottoms. - - * frame.h, blockframe.c, stack.c, a29k-tdep.c, - config/gould/tmp-{pn,np1}.h, - config/{sparc/tm-sparc.h,pyr/tm-pyr.h,vax/tm-vax.h}: Remove field - next_frame from struct frame_info. It has no purpose beyond - ->next->frame and is an artifact from GDB 2.8. - -Tue Jul 6 11:51:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Remove gdb before creating a new one. - Update init.c atomically. - - * Makefile.in (ALLPARAM): Add config/{alpha/xm-alpha.h,pa/xm-pa.h}. - (ALLCONFIG): Add config/alpha/alpha-osf1.mh. - - * infcmd.c (_initialize_infcmd): In docstring for "continue", - describe argument as setting ignore count. - -Sun Jul 4 15:04:47 1993 Doug Evans (dje@cygnus.com) - - * h8300-tdep.c (examine_prologue): Fix call to - read_memory_unsigned_integer. - -Fri Jul 2 18:22:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/{x,n}m-irix{3,4}.h: Make some definitions here - rather than including xm-bigmips.h. - - * eval.c (evaluate_subexp): Improve error messages for OP_TYPE and - default cases. - - * Makefile.in (distclean): Remove y.tab.h. - -Fri Jul 2 14:55:48 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * exec.c (exec_file_command): Remove Mar 28 hack as BFD handles - file updates properly now. - * mipsread.c (mips_coff_new_init): Force reevaluation of sigtramp - addresses if switching to a new symbol file. - * dbxread.c (process_one_symbol): Avoid dereferencing NULL - symbols that might be returned from define_symbol. - -Fri Jul 2 13:33:12 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - New target macros for getting at the pc, sp and fp. - * infcmd.c (read_pc, write_pc): Modify to use new macros. - (read_sp, write_sp, read_fp, write_fp): New functions. - * blockframe.c (reinit_frame_cache, get_prev_frame_info): - Use new functions. - * breakpoint.c (bpstat_alloc): ditto. - * infrun.c (wait_for_inferior): ditto. - * stack.c (print_frame_info): ditto. - * valops (call_function_by_hand): ditto. - * corelow.c (core_open): ditto. - * h8500-tdep.c: (target_read_sp, target_write_sp, target_read_pc, - target_write_pc, target_read_fp, target_write_fp): New functions. - * inferior.h (read_sp, write_sp, read_fp, write_fp): Prototypes. - - * config/alpha/xm-alpha.h: Add MAKEVA_END. - * config/h8500/tm-h8500.h: Define new macros. - -Fri Jul 2 13:51:04 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure.in (mipos-*-riscos*): New host and target; use riscos. - * config/mips/nm-riscos.h: If BSD43_NBPG is not defined by - vmparam.h, include machparam.h. - (KERNEL_U_ADDR): Define to be BSD43_UADDR. - -Fri Jul 2 13:39:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * c-exp.y (yylex): Give error if unmatched single quote. - - * configure.in, config/m68k/*delta68*, delta68-nat.c: New port. - - * Remove unused STACK_END_ADDR in the following files (in other - files it is used for something): tm-mips.h, tm-sun2.h, tm-news.h, - tm-a29k, tm-i386v.h, tm-hppa.h, tm-nindy960.h, tm-amix.h, - tm-hp300hpux.h, tm-isi.h. - -Thu Jul 1 09:51:27 1993 Jim Kingdon (kingdon@cygnus.com) - - * config/mips/nm-riscos.h: Define NBPG and UPAGES. - config/mips/xm-riscos.h: Include . - - * ser-unix.c (hardwire_noflush_set_tty_state): Use an assignment, - not an initializer, to copy the structure. - - * gdbtypes.h (struct type): Add field tag_name. - * gdbtypes.c (type_name_no_tag), c-typeprint.c (c_type_print_base): - Use it. - * {coff,dwarf,mips,stabs}read.c: Set it. - - * xm-sysv4.h: Undefine HAVE_TERMIO. - - * config/mips/nm-riscos.h: Remove unmatched #endif. - Define FETCH_INFERIOR_REGISTERS. - * config/mips/riscos.mh: Don't include coredep.o; mips-nat.o is enough. - Fix misspelling of NAT_FILE. - * mips-nat.c (fetch_core_registers): If KERNEL_U_ADDR is not defined, - we can still process "modern" core files. - - * ser-unix.c (hardwire_print_tty_state) [HAVE_TERMIOS]: Don't - print c_line. - (_initialize_ser_hardwire): Just check whether _POSIX_JOB_CONTROL - is defined; don't care what it is defined to. - -Wed Jun 30 20:06:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/vax/xm-vaxult2.h: Define FD_SET and FD_ZERO. - -Tue Jun 29 11:02:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * inftarg.c: Remove unused include of terminal.h. - * signals.h: Don't undefine signals anymore. - * main.c: Use job_control from serial.h. - * fork-child.c (fork_inferior): Use gdb_setpgid. - * serial.h, ser-unix.c, ser-go32.c: Provide gdb_setpgid. - * utils.c (quit): Use current_target->to_terminal_ours to figure - out whether we care about lack of job control, rather than __GO32__. - * utils.c: Include serial.h not terminal.h - (quit): Use job_control not TIOCGPGRP. - * terminal.h: Don't undefine TIOCGPGRP. - * serial.h, ser-unix.c, ser-go32.c, ser-tcp.c: Add SERIAL_FLUSH_OUTPUT. - * utils.c (quit): Use it. - * serial.h: Add SERIAL_UN_FDOPEN. - * utils.c (quit): Use it. - * ser-unix.c: Add process group to ttystate. - [HAVE_SGTTY]: Add tchars, ltchars, and lmode to ttystate. - * inflow.c: Include serial.h not terminal.h. - Use serial.h stuff to replace most of the maze of #ifdef's. - * inflow.c, main.c, inferior.h: make gdb_has_a_terminal a function. - * serial.h: Document SERIAL_SET_TTY_STATE as being immediate. - * ser-unix.c: Use TIOCSETN not TIOCSETP so it is true. - * serial.h, ser-unix.c, ser-go32.c, ser-tcp.c: - Add SERIAL_PRINT_TTY_STATE, SERIAL_NOFLUSH_SET_TTY_STATE, and - SERIAL_SET_PROCESS_GROUP. - * inflow.c: Use them. - * config/xm-svr4.h, config/rs6000/xm-rs6000.h, config/sparc/sun4os4.h: - Define HAVE_TERMIOS. - * Various: Remove all use of TIOC*_BROKEN. - -Wed Jun 30 12:20:51 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/m68k/tm-sun3.h (BELIEVE_PCC_PROMOTION_TYPE): Define. - -Tue Jun 29 13:44:41 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * target.h (target_detach): Turn macro into function. - * target.c (target_detach): Define it, do deferred register stores - before calling the real target function. - -Tue Jun 29 13:15:42 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - and Jim Kingdon (kingdon@cygnus.com) - - * symtab.h (BLOCK_SHOULD_SORT): Do not sort blocks corresponding to - a function to avoid printing of function arguments in wrong order - due to sorting. - * symfile.c (compare_symbols): Remove code for sorting arguments - as blocks containing arguments are no longer sorted. - * symtab.c (lookup_block_symbol): Update comment accordingly. - -Tue Jun 29 11:02:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/pa/tm-hppa.h: Remove unused ARGS_GROW_DOC. - (REG_STRUCT_HAS_ADDR): Add comment. - - * infrun.c (wait_for_inferior): Use find_pc_line not find_pc_symtab - to check whether there is line number information. - -Tue Jun 29 08:29:17 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * remote-udi.c: Fix docstring so that it compiles. - - * remote-mips.c, remote-nindy.c: move bfd.h before symfile.h - (for file_ptr). - -Tue Jun 29 09:11:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c (process_one_symbol): If we find a LOC_BLOCK where we - don't expect it, change it to LOC_STATIC so at least we don't coredump. - - * c-typeprint.c (c_type_print_base): Don't error() on invalid type. - - * symtab.h: Add comments about line numbers. - * source.c (identify_source_line): Fix off by one bug with line. - -Mon Jun 28 19:00:21 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Do not include libhppax. Instead include libhppa.h - and hpux-symtab.h. Misc indention fixes. - (find_unwind_entry): Add PARAM prototype. - (read_hpux_symtab): More fixes for names and sizes of structs, - unions, enums, typedefs, and tagdefs. - (read_hp_enum_type, read_hp_struct_type): Likewise. - (read_hp_set_type, read_hp_subrange_type): Likewise. - (hp_type_lookup, process_one_debug_symbol): Likewise. - (process_one_debug_symbol): Search forward from the K_FUNCTION for - the first K_BEGIN when setting the line number associated with a - function. Avoid unnecessary calls to savestring. - (hp_alloc_type): Initialize TYPE_CPLUS_SPECIFIC here. Remove - most cases where we set it elsewhere. - (hppa_sym_fns): Use "hppa" instead of hppax since hpread.c and - paread.c use the same BFD backend now. All references changed. - (hpux_symfile_init): Allocate space to hold the debugging section - contents on the symbol obstack. - -Mon Jun 28 10:09:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (makeva*): New interface, for making a va_list. - (printf_command): Use it. - * config/m88k/xm-delta88.h: Remove VPRINTF define, not needed. - * config/pa/xm-pa.h: New file. - * config/pa/xm-hppa{b,h}.h: Include it. - - * xcoffread.c: Remove obsolete NO_TYPEDEFS comment. - -Sun Jun 27 08:54:55 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * valprint.c (val_print_type_code_int): Fix off by one error with - eliminating leading zeroes for large little endian integers. - -Sun Jun 27 08:58:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/riscos.mh (CC): Use -systype sysv. - - * ser-unix.c: Move #include of to HAVE_SGTTY section. - - * Makefile.in (ALLPARAM): Add config/mips/{x,n}-{news-mips,riscos}.h. - -Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m68k/tm-m68k.h: Remove obsolete comment about duplicating - CALL_DUMMY between different 68k machines. - -Fri Jun 25 17:02:45 1993 Stu Grossman (grossman at cygnus.com) - - * gdbserver/Makefile.in: Add dependancies on server.h. - * gdbserver/remote-gutils.c: Remove lots of unused functions and - variables. - * gdbserver/remote-inflow.c: Remove lots of unused variables and - #includes. Also, use PTRACE_* symbols instead of constants. - (mywait): Surround calls to wait() with enable/disable_async_io() - so that we can be interrupted from GDB while waiting for the - child. Also, handle child exit more gracefully. - * gdbserver/remote-server.c: Remove lots of unused variables. - Move all extern defs into server.h. Redo main loop so that - failure from getpkt() causes communications to be re-established. - Fix 'k' command so that it restarts the child. - * gdbserver/remote-utils.c: Remove lots of unloved vars and - subrs. Move many extern decls into server.h. (remote_open): For - tcp, seperate usage of proto fd from connected fd. Close proto - fd after getting connection. (putpkt/getpkt): Pay attention to - errors when reading/writing. Report these to the caller. New - routines input_interrupt/enable_async_io/disable_async_io to make - it possible to get an I/O interrupt when data arrives from the - comm link. - * serial.h: New file to contain common defs for all remote files. - -Fri Jun 25 17:02:45 1993 Stu Grossman (grossman at cygnus.com) - - * remote.c: Add arg names to prototypes, in a modest effort at - clarification. Also add prototypes for some new functions. - * (remote_wait): Better error reporting for 'T' responses. - * ser-go32.c (strncasecmp): Make str1 & str2 be const. - * (dos_async_init): Make usage message reflect requested port #. - * ser-tcp.c (tcp_open): Terminate hostname properly to prevent - random hostname lookup failures. Add nicer message for unknown - host error. (wait_for): Wake up in case of exceptions. Also, - restart select() if we got EINTR. - * ser-unix.c (wait_for): Restart select() if we got EINTR. - * serial.c: (serial_close): Clean up code. - -Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m68k/tm-m68k.h: Remove obsolete comment about duplicating - CALL_DUMMY between different 68k machines. - -Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (*.tab.c): Use ./c-exp.tab.c not just c-exp.tab.c. - Make comment explaining this comprehensible. - (TAGFILES): Include ALLDEPFILES. - (ALLDEPFILES): udi2soc.c and udr.c are in 29k-share/udi, not - 29k-share/udi/udi. - (update-alldeps): Remove; obsolete. - - * remote.c: Move comments regarding packets to top of file with the - rest of the protocol comments. - Fix incorrect description of 'T' response. - - * README (Reporting Bugs): Refer people to the GDB manual. - - * c-valprint.c (c_val_print): Handle TYPE_CODE_BOOLEAN. - * stabsread.c: Type -16 is 4 bytes. - - * remote-udi.c: Improve docstring. - -Fri Jun 25 11:16:31 1993 Fred Fish (fnf@cygnus.com) - - * elfread.c (elf_symfile_read): Call bfd_elf_find_section, not - bfd_elf32_find_section, to track bfd changes. - -Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/riscos.mh (REGEX{,1}, MUNCH_DEFINE, MH_CFLAGS): Define. - * config/mips/xm-riscos.h: Define USG. - -Thu Jun 24 14:52:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (filename_completer): Don't complete to files ending in ~. - - * NEWS: Mention filename completion and "info line" enhancements. - - * main.c (symbol_completion_function): On "info t foo", return NULL, - don't error(). - - * main.c (symbol_completion_function): Don't use readline word - breaking. Use new calling convention for c->completer and - complete_on_cmdlist. - * command.h (struct command): Change arguments; now the text passed - to completer does not have any word breaking done. New arg word. - * symtab.{c,h} (make_symbol_completion_list): Do word breaking. Take - word argument. - * {main.c,gdbcmd.h} ({filename,noop}_completer): Take word argument. - * command.{c,h} (complete_on_cmdlist): Take word argument. - - * command.c (lookup_cmd_1): Doc fix. - -Thu Jun 24 13:26:04 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * Makefile.in (OP_INCLUDE): define. - (OPCODE_CFLAGS): use OP_INCLUDE. - - * config/i386/ncr3000.mh, config/i386/i386v4.mh, - config/i386/i386sol2.mh, config/m68k/hp300hpux.mh, - config/m68k/amix.mh, config/mips/irix[34].mh, - config/m88k/delta88.mh, config/sparc/sun4sol2.mh (ALLOCA, - ALLOCA1): macros removed. - - * config/mips/decstation.mh, config/rs6000/rs6000.mh - (MMALLOC_LIB): renamed to MMALLOC. - -Wed Jun 23 00:25:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * partial-stab.h: Consolidate case statements for N_LSYM and N_FUN. - * dbxread.c: Change comment regarding acc. - -Wed Jun 23 16:33:36 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Document a few functions, misc cleanups. Update - copyright to reflect the first "release" of this file. - (struct hpux_symfile_info): Delete unneeded fields. Keep pointers - to the contents of the debug sections rather than offsets within - the file itself. Corresponding changes to the accessor macros. - (sl_symbol_size, slt_symbuf): Delete unneeded global variables. - (slt_symbuf_start, slt_symbuf_end, lntt_symbuf): Likewise. - (lntt_symbuf_start, lntt_symbuf_end, gntt_symbuf): Likewise. - (gntt_symbuf_start, gntt_symbuf_end): Likewise. - (fill_slt_symbuf, fill_lntt_symbuf): Delete unneeded functions. - (fill_gntt_symbuf): Likewise. - (get_lntt, get_gntt, get_slt): Simplify. - (hpux_symfile_init): Read and store the contents of the debugging - sections. Do error checking on memory allocation and BFD calls. - (read_hpux_symtab): Delete KERNELDEBUG crud. Ignore debug symbols - which are not needed for building partial symbol tables. Handle - K_CONST, K_TYPEDEF, and K_TAGDEF just like K_SVAR and K_DVAR. - (read_ofile_symtab): Delete useless processing_gcc_compilation stuff. - (read_hp_struct_type): Initialize TYPE_CPLUS_SPECIFIC. - (read_hp_set_type, read_hp_array_type): Likewise. - (read_hp_subrange_type, hp_type_lookup): Likewise. - -Wed Jun 23 15:04:54 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - Makefile overhaul dropping autodepend features. - * Makefile.in: many comment changes. forced consistent use of $() - for makefile variables references. dropped leading ./ in file - references. Drop $(srcdir)/ prefix on all dependencies. - Inserted contents of alldeps.mak and depend. - (INCLUDE_CFLAGS): defined as new macro for getting libiberty's - include directory into the compilation line. - (GDB_CFLAGS): new macro to take up the semantic previously held - by INCLUDE_CFLAGS. - (LIBIBERTY): dropped ancient subdir macro. I last removed this - macro in feb of '92. How does it keep coming back? - (MMALLOC_LIB): renamed to MMALLOC. - (BFD_SRC_DIR): renamed to BFD_SRC. - (BFD_OBJ_DIR): renamed to BFD_DIR. - (BFD_LIB): renamed to BFD. - (BFD_INCLUDES): renamed to BFD_CFLAGS. - (READLINE_DIR): now represents object directory. - (RL_LIB): renamed to READLINE. - (READLINE_SRC, READLINE_CFLAGS, OPCODES, OPCODES_CFLAGS): new - macros. - (INTERNAL_CFLAGS): added GDB_CFLAGS, OPCODES_CFLAGS, - READLINE_CFLAGS, BFD_CFLAGS. Dropped USER_CFLAGS. - (LDFLAGS): removed default assignment. - (TEXIDIR, INCLUDE_DEP, MMALLOC_DIR, MMALLOC_DEP, BFD_DEP, - READLINE_DEP, LIBIBERTY_DIR, TESTS, depend, STAGESTUFF): unused, so removed. - (ALLOCA1, ALLOCA): removed all references. alloca is now in - libiberty. - (VERSION): unilaterally and arbitrarily bumped to 4.9.3. - (SFILES, NONSRC, HFILES, ALLDEPFILES, ALLPARAM, ALLCONFIG): - removed all $(srcdir) prefixes. - (getopt_h, ieee-float_h, bfd_h, wait_h, dis-asm_h): new macros - for potential dependencies. commented out by default. - (readline_headers, udiheaders): convenient abbreviations. - (gdbcore_h, frame_h, symtab_h, gdbtypes_h, expression_h, - value_h, breakpoint_h, command_h, gdbcmd_h, defs_h, inferior_h): - new macros used for header file dependencies. - (install-info, clean-info): collapse into the info rule. - (install): now depends on all. - (install-only): new target for installing without depending on - all. - (uninstall): new target. - (config-check, config-check-hosts, config-check-targets): added - fixme comments. - (ch-exp.tab.c, m2-exp.tab.c): added artificial dependencies in - order to force parallel makes into keeping these rules separate. - * configure.in: omit cat'ing depend file onto generated Makefile. - * alldeps.mak, depend: removed. - - * inferior.h: remove redundant include of symtab.h which is - included in value.h via breakpoint.h. - - * alloca.c: removed. alloca is now in libiberty. - - * config/m88k/delta88.mh, config/ns32k/merlin.mh (M_UNINSTALL): - new macro to undo what M_INSTALL does. - -Wed Jun 23 00:25:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/ns32k/{merlin.mh,xm-merlin.h}: Be consistent about name - of gdb-sh. - - * dbxread.c (copy_pending): Change name and function of begi argument - to endi, since that is what the caller needs. - - * Makefile.in (TAGFILES): Don't include YYFILES. - - * Makefile.in (HFILES): Include monitor.h. - - * Makefile.in: Include text that used to be in alldeps.mak. - Remove config/mips/{bigmips.mh,xm-bigmips} from it. - * Makefile.in, configure.in: Remove all traces of alldeps.mak. - - * main.c (main): Print help message on stdout not stderr - per standards.texi. - New option --version per standards.texi. - In help message, show long options with "--" not "-". - Don't try to print help message or version until after we have - called initialize_all_files. - -Tue Jun 22 11:03:13 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Delete useless #if 1 statements. - (hp_type_translate): Use T_LONG, T_UNS_LONG, and T_DOUBLE instead - of magic integers. Fix handling for T_UNS_INT. Abort if the type - passed in is not an "immediate" type. - (read_hp_enum_type): Properly compute the size of the type. - (read_hp_array_type): Likewise. - (hp_type_lookup): Prefix the names of structs, unions and enums - with "struct", "union", and "enum" as appropriate. - -Tue Jun 22 03:15:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * solib.c (solib_add_common_symbols): Don't call lookup_minimal_symbol. - (solib_add): Call special_symbol_handling once, not once per library. - - * procfs.c (procfs_resume): Don't pass a SIGTSTP whose action - is SIG_DFL. - - * procfs.c (procfs_resume): Skip the unnecessary PRSVADDR on all - systems, not just Solaris. - - * stabsread.c: Include . - -Mon Jun 21 16:09:46 1993 Jim Kingdon (kingdon@cygnus.com) - - * fork-child.c (fork_inferior): Quote exec_file so it can contain - funky characters. - -Mon Jun 21 16:56:47 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (INCLUDE_CFLAGS): Add BFD_INCLUDES for now, since - bfd.h is included by target.h, which most of gdb includes. - * depend: Hand remove BFD_INCLUDES from ${CC} lines, now that - it's in INCLUDE_CFLAGS. - -Mon Jun 21 16:09:46 1993 Jim Kingdon (kingdon@cygnus.com) - - * config/i386/*aix*, i386aix-nat.c: New files. - * configure.in: Use them. - * alldeps.mak: List them. - * coffread.c (decode_base_type): Deal with anonymous enum type. - * i387-tdep.c (print_387_status_word): Add comment re "top". - * i386-tdep.c [I386_AIX_TARGET] (i386_extract_return_value): New func. - * dbxread.c: Use SEEK_SET and SEEK_CUR, not L_*. Define them if and - only if not defined by a header file. - * mipsread.c: Don't define L_SET or L_INCR. - -Mon Jun 21 15:10:07 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (BFD_INCLUDES): Bfd.h is now back in bfd build dir. - * depend: Hand updated to match. - -Mon Jun 21 10:13:42 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Include "demangle.h". - (process_one_debug_symbol): Set the SYMBOL_LANGUAGE and - SYMBOL_INIT_DEMANGLED_NAME for the current symbol. Adjust - SYMBOL_VALUE for local variables in the stack by the size of the - current function's stack (found in unwind descriptor). Keep - better track of the current unwind descriptor. - -Sun Jun 20 13:11:11 1993 Jim Kingdon (kingdon@cygnus.com) - - * stabsread.c (read_struct_fields): Don't call read_cpp_abbrev on $_. - (read_cpp_abbrev): Don't complain specially for $_. Also return 0 if - we don't recognize the abbrev. - -Sun Jun 20 00:24:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * solib.c (solib_add_common_symbols): Add comment about performance. - -Fri Jun 18 12:37:36 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/{{x,n}m-riscos.h,riscos.mh}: New files. - * configure.in (mips-*-sysv*): Use riscos for host, bigmips for target. - - * config/mips/{{x,n}m-news-mips.h,news-mips.mh}: New files. - * config/mips/{bigmips.mh,xm-bigmips.h}: Remove. - * configure.in (mips-sony-*): Use news-mips for host. - - * buildsym.h: Doc fix for processing_acc_compilation. - -Thu Jun 17 19:57:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (print_formatted): Don't use tab in wrap_here arg. - -Thu Jun 17 17:29:30 1993 Jim Kingdon (kingdon@lisa.cygnus.com) - - * Makefile.in (INTERNAL_CFLAGS): Include ../include as well as - ${srcdir}/../include. - - * config/m88k/xm-delta88.h: Comment out unused defines which conflict - with system headers. - * printcmd.c (printf_command): Cast second arg to vprintf to PTR. - Use VPRINTF macro if defined. - * config/m88k/xm-delta88.h: Define VPRINTF. Include . - Define TIOC{GETC,GLTC}_BROKEN. - * m88k-nat.c: Uncomment include of . - * main.c: Rename initialize_{main,cmd_lists,history} to init_* to - make things easier on munch (apparently this matters on - the delta88 with svr3). - -Thu Jun 17 16:53:56 1993 david d `zoo' zuhn (zoo@cygnus.com) - - * Makefile.in: canonicalize install.sh; for use within - this directory (and subdirs) - -Tue Jun 15 17:01:23 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: remove parentdir support; use INSTALL_XFORM - -Thu Jun 17 15:08:35 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * configure.in (alpha-*-osf*), config/alpha/alpha-osf.mh: New - host. - * sh-tdep.c (frame_find_saved_regs): Use NUM_REGS rather than hard - wired (and wrong) constant. - * values.c (unpack_long): Add case to unpack when target object is - sizeof(int). - * config/sh/tm-sh.h (REGISTER_NAMES): Know about the news ones the - simulator defines. - -Wed Jun 16 16:08:18 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * NEWS: tracking user visible changes starting with - vxworks-timeout. - - * remote-vx.c (_initialize_vx): rename user settable option from - rpcTimeout to vxworks-timeout. - -Wed Jun 16 14:34:10 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (hp_type_translate): Fix promotion bugs from - char to short and short to int. - -Wed Jun 16 12:21:49 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (depend): More makefile diddling. - * alldeps.mak, depend: Update to latest automatically built - versions. - - * Makefile.in (depend): Bfd.h keeps moving, keep up with it. - * alldeps.mak, depend: Update to latest automatically built - versions. - -Tue Jun 15 12:26:05 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * remote-vx.c: include gdbcmd.h for setlist. - (_initialize_vx): make rpcTimeout user settable. - -Mon Jun 14 09:23:51 1993 Jim Kingdon (kingdon@cygnus.com) - - * main.c, gdbcmd.h: Add function filename_completer. - * main.c, symfile.c, source.c, exec.c, core.c: Use it for - "directory", "source", "cd", "symbol-file" "add-symbol-file", - "load", "file", "exec-file", "core-file" commands. - (But '/' is a word break, limiting usefulness; see comments). - - * source.c (mod_path): Warning not error if can't find directory. - - * isi-xdep.c: New file. - * config/m68k/isi.mh (XDEPFILES): Add isi-xdep.o - -Sun Jun 13 09:17:48 1993 Jim Kingdon (kingdon@cygnus.com) - - * config/m68k/xm-news.h: Include . - - * m88k-tdep.c (IEEE_isNAN): Remove. - config/m88k/tm-m88k.h (INVALID_FLOAT): Return 0. This was the same - broken isNAN as on the mips. - - * valprint.c (_initialize_valprint): Use c->function.sfunc not just - c->function. - - * dbxread.c (process_one_symbol): If SUN_FIXED_LBRAC_BUG is not - defined, don't worry about Sun's silly LBRAC bug. - * config/m68k/tm-sun3.h: Define SUN_FIXED_LBRAC_BUG to 0. - - * dbxread.c (process_one_symbol): If there's a symbol before an - N_SO, don't error(). - (case N_BCOMM): complain () not error (). - - * defs.h, main.c (catch_errors): Add return_mask arg. - stack.c (print_frame_info): Pass RETURN_MASK_ERROR. - other callers: Pass RETURN_MASK_ALL. - (return_to_top_level), callers: Add return_reason arg. - * utils.c (quit): - Use return_to_top_level (RETURN_QUIT) instead of error (). - * main.c (main), tm-nindy960.h (ADDITIONAL_OPTION_HANDLER): - Use SET_TOP_LEVEL not setjmp (to_top_level). - * remote-nindy.c: Use catch_errors not setjmp (to_top_level). - -Sat Jun 12 14:40:54 1993 Jim Kingdon (kingdon@cygnus.com) - - * solib.c (solib_create_inferior_hook) [SVR4_SHARED_LIBS]: - Don't try to get the debug base yet. - - * dbxread.c (process_one_symbol): Set n_opt_found based on whether - a non-gcc N_OPT symbol is found. Make SUN_FIXED_LBRAC_BUG a macro - which returns 0 or 1 to say whether to do it. - * config/sparc/sun4{sol2,os4}.h - (SUN_FIXED_LBRAC_BUG,VARIABLES_INSIDE_BLOCK): Use n_opt_found so - the right thing happens for both acc and SunOS4 /bin/cc. - - * valprint.c (print_hex_chars): Use local_hex_format_{pre,suf}fix. - * printcmd.c (print_scalar_formatted): Use val_print_type_code_int. - - * mips-tdep.c: Remove isa_NAN; it assumed sizeof(host int) == 4 and - probably contained byte-order sins too. - config/mips/tm-mips.h (INVALID_FLOAT): Define to 0 like most machines. - The IEEE_FLOAT code in print_floating takes care of it. - -Sat Jun 12 14:47:04 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.9.2. - * c-valprint.c (c_val_print): For array of chars printed with - string syntax, don't print the address of the array. From - bothner@cygnus.com. - * c-exp.y (yylex): Recognize '.' as indicating a floating point - number regardless of the radix. From wilson@cygnus.com. - * valprint.c (set_input_radix_1, set_output_radix_1): New - prototypes and functions that do the actual radix setting work. - * valprint.c (set_radix, set_output_radix, set_input_radix): - Rewrite to use set_input_radix_1 and set_output_radix_1. - * valprint.c (initialize_valprint): Enable commands to - independently set and show input and output radices. - * valprint.c (show_radix): New prototype and function that - handles separate input and output radices. - -Fri Jun 11 18:39:38 1993 Ken Raeburn (raeburn@cygnus.com) - - Patches from Jeff Law, law@cs.utah.edu: - * hppa-pinsn.c: Now uses disassembler from opcode library, - this contains only the stub function print_insn. - -Fri Jun 11 15:19:59 1993 K. Richard Pixley (rich@cygnus.com) - - * main.c (main): back to two periods for elipse. - (print_gdb_version): revised format for configuration info. - -Fri Jun 11 10:24:35 1993 Fred Fish (fnf@cygnus.com) - - * defs.h (INT_MAX): Cast unsigned shift result to int. - -Fri Jun 11 10:17:41 1993 Jim Kingdon (kingdon@cygnus.com) - - * dbxread.c (process_one_symbol): Rather than having - BLOCK_ADDRESS_FUNCTION_RELATIVE a macro, make it a variable which - is true if we are doing stabs-in-elf, false otherwise. - config/sparc/tm-sun4sol2.h: Don't define it. - -Fri Jun 11 13:33:40 1993 Ian Lance Taylor (ian@cygnus.com) - - * remote-mips.c (mips_send_packet): Don't print garbage character - in debugging info. - (mips_request): Don't check that remote pid is 0, because - sometimes it isn't. - (mips_fetch_registers): Pass a pointer to SWAP_TARGET_AND_HOST, - not an integer. - -Fri Jun 11 10:17:41 1993 Jim Kingdon (kingdon@cygnus.com) - - * stack.c (print_frame_info): Use catch_errors around print_frame_args. - - * Makefile.in (install): Don't depend on gdb. - - * Rename remote-es1800.c to remote-es.c - and remote-st2000.c to remote-st.c for 14-char filenames. - config/m68k/{es1800,st2000}: Use the new names. - - * mips-tdep.c (isa_NAN): Don't return true on -0. - -Fri Jun 11 10:24:35 1993 Fred Fish (fnf@cygnus.com) - - * defs.h (INT_MAX): Cast unsigned shift result to int. - -Thu Jun 10 13:26:41 1993 Fred Fish (fnf@cygnus.com) - - * elfread.c (elf_symtab_read): Add bfd section address to bfd - symbols, now that they are section relative. - * solib.c (bfd_lookup_symbol): Ditto. - -Thu Jun 10 11:27:34 1993 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (read_hp_function_type): Adjust SYMBOL_VALUE for - arguments in the stack by the size of the current function's stack - (found in the unwind descriptor). - (process_one_debug_symbol): Likewise. Keep track of the current - function's unwind descriptor. - -Thu Jun 10 10:56:56 1993 Jim Kingdon (kingdon@cygnus.com) - - * Makefile.in (depend): Add bfd -I's for paread.c and xcoffexec.c - depend: Updated accordingly. - -Wed Jun 9 16:08:44 1993 Jim Kingdon (kingdon@cygnus.com) - - * Makefile.in (*.tab.c): Use mv for atomic update. - - * Makefile.in ({dist,real}clean): Also remove nm.h. - (realclean): Also remove ${TESTS}, y.output, yacc.{acts,tmp}. - (distclean): Don't rebuild *.tab.c or TAGS. - -Wed Jun 9 12:56:58 1993 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in (version.c): add host and target names to version.c. - * main.c (main): print three periods for the elipse. - (print_gdb_version): also print configuration. - - * udi/udiids.h, udi/udip2soc.c, udi/udiphcfg.h, udi/udiphunix.h, - udi/udiproc.h, udi/udipt29k.h, udi/udiptcfg.h, udi/udisoc.h, - udi/udr.c: Change AMD copyrights to FSF copyleft '93. - - * remote-eb.c (get_hex_regs, eb_fetch_registers), remote-adapt.c - (get_hex_regs, adapt_fetch_registers): cast args to - supply_register to avoid gcc warning. - - * config/a29k/a29k.mt (TDEPFILES): drop minimon support. It - doesn't compile on solaris and is now obsolete. - - * config/sparc/sun4os4.mh (XM_CLIBS): remove -lresolv. This - breaks stock sunos installations. - -Wed Jun 9 06:14:33 1993 Jim Kingdon (kingdon@cygnus.com) - - * m68k-stub.c: Add comment about frame cache. - - * target.h (target_store_registers): Doc fix re error handling. - - * findvar.c (write_register): Call SWAP_TARGET_AND_HOST regardless - of register_valid[regno]. - -Tue Jun 8 14:42:10 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * symtab.h, dwarfread.c: Doc fix re dependencies. - -Tue Jun 8 17:54:09 1993 Rob Savoye (rob@rtl.cygnus.com) - - * serial.c (serial_close): If scb is NULL, don't try to close - it. - * configure.in: Add support for rom68k and bug boot monitors. - -Tue Jun 8 17:39:12 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * coffread.c (init_stringtab): Fix bug where sizeof(long) != 4. - * gdbcore.h, core.c (read_memory_unsigned_integer): New function. - * findvar.c (read_register, write_register): Fix thinko where - sizeof(host long) != sizeof(target int). - * h8300-tdep.c: Use new read_memory_unsigned_integer call. - * sh-tdep.c (_initialize_sh_tdep): Add memory_size command. - -Tue Jun 8 14:42:10 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * Move config/m68k/tm-m68k.h (FRAME_FIND_SAVED_REGS) to - m68k-tdep.c (m68k_find_saved_regs). Don't duplicate code between - 68881 and non-68881 cases. Check for a pair of movel instructions. - -Tue Jun 8 14:52:55 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - First cut at sparc-vxworks targetting. - * config/sparc/tm-vxsparc.h, config/sparc/vxsparc.mt: new files. - * configure.in: sparc-vxworks gdb_target now vxsparc. - - * remote-eb.c, remote.c: symfile.h requires bfd.h so include it. - -Tue Jun 8 14:42:10 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * config/m68k/xm-news.h: add "extern int errno". - -Tue Jun 8 13:45:07 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * remove-vx.c (vx_read_register, vx_write_register): collapse - ifdef I80960 else (assumes) m68k into parameterizable macros - VX_NUM_REGS and VX_SIZE_FPREGS. - * config/m68k/tm-vx68.h, config/i960/tm-vx960.h (VX_NUM_REGS, - VX_SIZE_FPREGS): new definitions. - -Tue Jun 8 11:08:29 1993 Jim Kingdon (kingdon@cygnus.com) - - * symfile.{c,h} (generic_load): New function. - remote{,-nindy,-eb,-mips}.c: Use it. - -Mon Jun 7 20:07:30 1993 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (depend): More sed gubbish to deal with - ../bfd/bfd.h being generated during the build. - * depend: Re-done with corrected makefile. - -Mon Jun 7 16:32:05 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (BFD_SRC_DIR): Renamed def and usages from BFD_DIR. - * Makefile.in (BFD_OBJ_DIR): New definition for the bfd build - directory to find automatically generated header files and library. - * Makefile.in (BFD_LIB): Use BFD_OBJ_DIR. - * Makefile.in (LINTFLAGS): Include BFD_OBJ_DIR. - * Makefile.in (saber_gdb): Include BFD_OBJ_DIR. - * Makefile.in (depend): Include BFD_OBJ_DIR in gcc args. - * Makefile.in (paread.o, xcoffexec.o): Remove, now in depend. - * depend, alldeps.mak: Rebuild after Makefile.in changes. - -Fri Jun 4 10:18:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: change lynx support to CPU-*-lynxos* - - * Makefile.in (subdir_do): change test from existence of directory - to existence of Makefile (the directory may exist but not be configured) - -Thu Jun 3 01:18:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * config/sparc/xm-sun4sol2.h: define MEM_FNS_DECLARED - -Fri Jun 4 10:43:33 1993 Ian Lance Taylor (ian@cygnus.com) - - * configure.in (mips-idt-ecoffl*): New target; use idtl. - (mips-idt-ecoff*): Added trailing '*'. - * config/mips/idtl.mt: New file; like idt.mt, but little endian. - -Thu Jun 3 17:36:56 1993 Stu Grossman (grossman@cygnus.com) - - * ser-go32.c: Clean up lots of compilation nits. - -Thu Jun 3 14:44:57 1993 Stu Grossman (grossman@cygnus.com) - - * Patches from Jeffrey Law . - * hppab-nat.c: Eliminate unnecessary ifdefs for - FETCH_INFERIOR_REGISTERS, CANNOT_FETCH_REGISTER, and - CANNOT_STORE_REGISTER. - (fetch_register): Delete code to handle CANNOT_FETCH_REGISTER. - * hppa-pinsn.c: Support 'I', 'J', and 'K' in output - templates for 1.1 FP computational instructions. - -Thu Jun 3 03:34:49 1993 Stu Grossman (grossman@cygnus.com) - - * Makefile.in: Remove ser-tcp.[co]. (Use XDEPFILES instead.) - * alldeps.mak, depend: Rebuild to account for ser-tcp. - * config/sparc/sun4os4.mh: Add ser-tcp to XDEPFILES. - * gdbserver/Makefile.in (gdbserver): Use -lbsd. - * gdbserver/remote-inflow{-sparc}.c (create_inferior): Don't use a - shell when running the child, as args have been expanded by the - time we get here. Simplify calling convention. - * gdbserver/remote-server.c (main): Use new calling convention - for create_inferior, remove defunct code for coalescing argv. - Remove extra calls to mywait(), as we no longer have to wade - through a shell. - - * target.c (target_read_memory_partial): Don't deref errnoptr - when checking for null pointer. - -Wed Jun 2 19:58:46 1993 John Gilmore (gnu@cygnus.com) - - * remote-es1800.c: Fix typo. - -Tue Jun 1 21:22:39 1993 Fred Fish (fnf@cygnus.com) - - * target.c (target_read_memory_partial): Like target_read_memory, - but does partial reads, such as reads that bump into the end of - the address space. - * target.h (target_read_memory_partial): Add prototype. - * valprint.c (PRINT_MAX_DEFAULT): New define, initial value 200. - * valprint.c (val_print_string): Complete rewrite to fix bug with - bumping into end of memory, avoiding unnecessarily long reads, and - fixing bug when print_max is set to 0 (unlimited print length). - * valprint.c (_initialize_valprint): Use PRINT_MAX_DEFAULT to - initialize print_max. - -Tue Jun 1 18:11:35 1993 Rob Savoye (rob at darkstar.cygnus.com) - - * configure.in: Add support for rom68k and bug boot monitors. - -Mon May 31 10:37:04 1993 Jim Kingdon (kingdon@cygnus.com) - - * printcmd.c (print_scalar_formatted): Print integers bigger than - LONGEST in hex no matter how big, and no matter what the format - and size. - - * stabsread.c (read_type): Skip type attributes if present. - - * stabsread.c (read_huge_number): Don't accept '0' + radix as part - of number, just through '0' + radix - 1. - -Sun May 30 15:35:21 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (SER_HARDWIRE): Temporarily comment out ser-tcp.o. - - * {dbxread.c, dwarfread.c} (read_ofile_symtab): Rewrite to take - single parameter, the pointer to the partial symtab, rather than - a bunch of args that are derived from the partial symtab. Change - prototypes and callers to match. - - * dbxread.c (read_ofile_symtab): Remove "#if 1" around code to - set demangling style automatically. - * defs.h (CPLUS_MARKER): Clarify comment that this is only for - GNU C++, not C++ in general. - * symtab.h (general_symbol_info): Simplify by eliminating one - structure level for the language dependent info. - -Sat May 29 15:59:29 1993 Fred Fish (fnf@cygnus.com) - - * c-typeprint.c (c_type_print_base): Avoid dereferencing NULL - names for TYPE_CODE_STRUCT and TYPE_CODE_UNION types. - TYPE_CODE_ENUM was already testing for this. - -Fri May 28 17:18:05 1993 Stu Grossman (grossman@cygnus.com) - - * Makefile.in: Add new file ser-tcp.c. - * defs.h (memcmp): Add decl for memcmp to #ifndef MEM_FNS_DECLARED. - * findvar.c (write_register): See if we are writing back the same - value that's already in the register. If so, don't bother. - * remote.c (putpkt, getpkt): Improve handling of communication - problems. - * ser-go32.c: Prototype it to death. Update serial_ops and add - dummy routines where appropriate. - * ser-tcp.c: New module to implement serial I/O via TCP - connections. - * ser-unix.c: Clean up getting/setting of tty state. Get rid of - SERIAL_RESTORE, add SERIAL_{GET|SET}_TTY_STATE interfaces. - * serial.c: Add start of support for connect command. - (serial_open): Distinguish between tcp and local devices. - * serial.h (struct serial_ops): Get rid of restore, add - get_tty_state and set_tty_state. Define protoypes and macros for - this mess. - * gdbserver/remote-utils.c: Add tcp support. (readchar): Do - some real buffering. Handle error conditions gracefully. - * gdbserver/remote-inflow-sparc.c: Update to remote-inflow.c - (Lynx), remove lots of cruft. - -Fri May 28 17:24:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * printcmd.c (print_address_symbolic): turn this into an assigment - instead of an initialization (many compilers don't accept - structure initialization). - -Thu May 27 16:56:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (read_xcoff_symtab): If several program csects in one - source file, give them all the name of the source file, rather than - the 2nd and subsequent ones having NULL names. - -Thu May 27 06:16:56 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * printcmd.c (print_address_symbolic): Append source filename and - linenumber of the symbol if print symbol-filename is on. - (initialize_printcmd): `set print symbol-filename'. - -Wed May 26 13:46:16 1993 Stu Grossman (grossman@cygnus.com) - - * configure.in: Add config for Lynx target. Configure gdbserver - only for Lynx. Re-do selective configuration of sparclite. - - * gdbserver/{remote-gutils.c remote-server.c Makefile.in - configure.in remote-inflow.c remote-utils.c}: New files to - support GDB remote server. Currently only works for Lynx. - -Wed May 26 10:28:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (define_symbol, case 't'): Only set the name if it - is not a pointer type. - - * stabsread.c (define_symbol): Clean up logic; move the read_type - calls to inside the switch statement (this improves the error - handling). - - * mipsread.c (parse_symbol, parse_partial_symbols): Deal with Fortran - common blocks. - -Tue May 25 20:44:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (print_formatted, case 'i'): Pass a tab to wrap_here. - - * source.c (line_info): Change "pc" to "address" in messages and - use print_address for addresses. - - * source.c (line_info): If we don't find a symtab, print more useful - output, including the symbolic address. - - * source.c (line_info): If --fullname, display the source. - (identify_source_line), callers: Take pc as argument, rather than - assuming innermost frame (emacs doesn't use this, so no one ever - noticed). - * symtab.h: Declare frame_file_full_name. - * main.c: Don't. - -Tue May 25 15:30:43 1993 Brendan Kehoe (brendan@lisa.cygnus.com) - - * breakpoint.c (catch_command_1): Fix typo in error msg. - -Tue May 25 16:05:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * elfread.c (elf_symfile_read): Update ELF structure and routine - names to specify 32-bit versions. - (elf_symtab_read): Retrieve size field directly from symbol, - instead of using old kludge. - - * mips-pinsn.c (print_insn): Cast address to bfd_vma before - calling opcodes library. - * z8k-tdep.c (print_insn): Likewise. - -Tue May 25 13:06:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c: Remove all uses of error(). Make error_type and - read_type_number static. - (define_symbol): Don't try to deal with a missing symbol - descriptor which isn't followed by digit, '(', or '-'. - * stabsread.h: Don't declare read_type_number here. - * gdbtypes.h: Don't declare error_type here. - * xcoffread.c: Remove NO_TYPEDEFS code. - -Tue May 25 09:33:16 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips-tdep.c: Removed #include of many header files, and #define - of MIPSMAGIC; no longer used. - -Tue May 25 09:36:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Many places: replace "the inferior" in messages with "the program" - or "the program being debugged". - * inflow.c (try_writing_regs): Remove; it's been #if 0'd forever - and I'm getting sick of maintaining it. - - * config/i386/linux.mh: Don't use \ newline; the awk scripts don't - support it. - - * config/i386/go32.mh: Define SER_HARDWIRE. - * Makefile.in: Define SER_HARDWIRE. - (DEPFILES): Use it. - (alldeps.mak): Add SER_HARDWIRE. - Remove all references to ser-hardwire.{c,o}. - * configure.in: Remove all ser_hardwire and gdb_serial_driver stuff. - -Mon May 24 23:50:05 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * sparc-nat.c (store_inferior_registers): Fill in all members of - inferior_fp_registers by reading them from the inferior before - modifying and writing them back. - Fixes unexplainable inferior FP exceptions after calls to the inferior - or setting of floating point registers. - * mips-tdep.c (mips_skip_prologue): Skip move of argument register - to register which is generated by gcc-2.4. - -Tue May 25 00:42:39 1993 Ken Raeburn (raeburn@cygnus.com) - - * hppa-pinsn.c: Define OLD_TABLE before including opcode/hppa.h. - -Mon May 24 13:55:14 1993 Stu Grossman (grossman@cygnus.com) - - * config/i386/{i386lynx.mh i386lynx.mt nm-i386lynx.h tm-i386lynx.h - xm-i386lynx.h}: New configuration for Lynx. - -Mon May 24 10:01:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mipsread.c (parse_symbol): Deal with scVar and scVarRegister. - * symtab.h: Comment that LOC_REGPARM_ADDR can be call by reference. - - * c-typeprint.c (c_type_print_base): Don't print typedef'd names - as struct, union, or enum tags. - -Mon May 24 01:10:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symmisc.c (dump_msymbols): Avoid gdb coredump with stripped - executable. - -Sat May 22 10:03:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (wait_for_inferior), - infcmd.c (program_info, signal_command): Use symbolic signal names. - - * inftarg.c (child_wait): Deal with EINTR and include message from - strerror if printing an error message. - - * main.c (command_line_input): Use STOP_SIGNAL not SIGTSTP. - - * stabsread.c: Remove most uses of lookup_fundamental_type. - (define_symbol): Use read_type for type of enum constant, - not just read_type_number. Also don't call error(). - (define_symbol): For unrecognized constant type, one complaint (the - one from error_type) is enough. Don't make our own in addition. - (define_symbol): Don't treat an N_FUN 'R' as a prototype. - * gdbtypes.h: Doc fixes. - -Sat May 22 03:33:07 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - Fix stack unwinding through _sigtramp on Irix. These patches are from - Paul Flinders . - * mipsread.c (fixup_sigtramp): Find _sigtramp on Irix even when the - executable uses sigvec. - * mips-tdep.c (read_next_frame_reg): Allow tm-file to override - sigcontext offsets. - * config/mips/tm-irix3.h: Add sigcontext offsets for Irix. - -Sat May 22 00:39:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): Clear stop_signal if it should not - be passed to the inferior to make "handle nopass nostop" work. - -Sat May 22 00:21:41 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/tm-irix3.h: Clean up, use tm-bigmips.h and redefine - the necessary bits. - * findvar.c (value_from_register): Fix uninitialized first_addr - which caused problems with assignment of doubles to register variables - on some targets. - * mipsread.c: Remove TM_FILE_OVERRIDE, include tm.h and provide the - missing mips definitions if necessary. - - Fix handling of double register variables for mips targets and big - endian hosts. These patches are from Paul Flinders . - * config/mips/tm-mips.h: Increase MAX_REGISTER_{RAW,VIRTUAL}_SIZE to - 8 bytes for doubles. - * config/mips/tm-mips.h (REGISTER_CONVERT_TO_TYPE): New macro for - conversion of type held in multiple registers to host format. - * config/mips/tm-mips.h (REGISTER_CONVERT_FROM_TYPE): New macro, - companion to REGISTER_CONVERT_TO_TYPE. - * config/mips/tm-mips.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): - Convert to function calls. - * config/mips/tm-mips.h (FIX_CALL_DUMMY): New code for big endian - mips targets. - * mips-tdep.c (mips_print_register): Raw buffer now needs just - MAX_REGISTER_RAW_SIZE bytes. - * mips-tdep.c (mips_print_register): Use REGISTER_CONVERT_TO_TYPE - (if defined) for doubles. - * mips-tdep.c: (mips_extract_return_value, mips_store_return_value): - New functions, take care of REGISTER_CONVERT_TO/FROM_TYPE. - * valops.c (value_assign): Use REGISTER_CONVERT_TO_TYPE if - defined. - * findvar.c (value_from_register): Use REGISTER_CONVERT_TO_TYPE if - defined. - -Fri May 21 09:04:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Add i[34]86-*-isc*. - - * stabsread.c: Make sure all complain() pass the address of the struct. - - * xcoffread.c: Make sure all struct complaints are static not auto. - - * Makefile.in: Add rule for xcoffexec.o like that for paread.o. - - * xcoffread.c (process_xcoff_symbol, case C_LSYM): Use define_symbol. - -Wed May 19 12:33:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/i386/linux.mh: Re-enable coredumps now that they should work. - -Wed May 19 15:44:20 1993 K. Richard Pixley (rich@cygnus.com) - - * config/m68k/tm-m68k.h (FRAME_CHAIN): add missing close paren. - -Wed May 19 15:33:57 1993 Stu Grossman (grossman@cygnus.com) - - * config/pa/nm-hppab.h: Comment PTRACE_ARG3_TYPE. - -Wed May 19 12:33:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (INSTALLED_LIBS): New variable. - -Tue May 18 14:08:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (quit_command): In the "quit anyway?" message, tell the user - whether we are planning to detach or kill the program. - - * config/vax/vaxbsd.mh: Add "NAT_FILE= nm-vax.h". - * config/vax/xm-vaxbsd.h: Use not - - * infcmd.c (read_pc): Doc fix. - - * printcmd.c (print_address_symbolic): Use %u not %d for offset. - - * blockframe.c (get_prev_frame_info): If pc in sigtramp, set - signal_handler_caller. - * tm-68k.h (FRAME_{CHAIN,SAVED_PC}): Deal with sigtramp. - * tm-hp300bsd.h: Define SIGTRAMP_{START,END} not IN_SIGTRAMP. - * inferior.h (IN_SIGTRAMP): Definition moved from infrun.c. - Use SIGTRAMP_START if defined. - * infcmd.c (step_1): Use SIGTRAMP_{START,END} if needed. - * infrun.c (wait_for_inferior): Check IN_SIGTRAMP before SKIP_PROLOGUE. - - * infptrace.c: Remove unused KERNEL_U_ADDR_HPUX code. - - * infcmd.c (step_1): Fix poorly worded error message. - - * config/{i386/linux.mh,m68k/isi.mh} (NATDEPFILES): - Comment out corelow.c because core dumps are broken on these machines. - - * Makefile.in (depend): Put "${srcdir}" in generated dependencies - if srcdir is not ".". - Also put in -I${BFD_DIR} or -I${READLINE_DIR} for files which need it. - (INCLUDE_CFLAGS): Remove BFD_DIR and READLINE_DIR. - * depend: Update to latest automatically built version. - -Tue May 18 08:10:45 1993 Fred Fish (fnf@cygnus.com) - - * ChangeLog, ChangeLog-92: Split ChangeLog at 1993. - * Makefile.in (NONSRC): Add ChangeLog-92 - -Tue May 18 08:03:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * findvar.c ({read,write}_register): Use REGISTER_RAW_SIZE - not typo RAW_REGISTER_SIZE. - - * frame.h, inferior.h: Doc fixes. - -Mon May 17 15:43:03 1993 Stu Grossman (grossman@cygnus.com) - - * findvar.c (write_register): Add sanity check for register size. - (read_register): Fixup sanity check for register size to be - consistent with write_register(). - -Mon May 17 07:36:20 1993 Ian Lance Taylor (ian@cygnus.com) - - * sparclite/Makefile.in: Add dummy info, install and install-info - targets. - -Thu May 13 07:30:22 1993 Ian Lance Taylor (ian@cygnus.com) - - * remote-nindy.c: Removed declaration of coffstrip. - * nindy-share/nindy.c: #if 0 coffstrip routine; no longer used. - -Wed May 12 00:35:19 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.9.1 after release and cvs - tagging. - - * Makefile.in (VERSION): GDB 4.9 release. - -Tue May 11 08:04:41 1993 Fred Fish (fnf@cygnus.com) - - * README: Update known bugs to include the Solaris bug that - leaves core dumps in the current directory when restarting the - inferior with "run". Expand on the testsuite information. - - * Makefile.in (VERSION): Bump to 4.8.96 for what should hopefully - be the last 4.9 prerelease test archive. - -Mon May 10 22:13:23 1993 Jim Kingdon (kingdon@cygnus.com) - - * config/m68k/xm-hp300bsd.h: Include to avoid INT_MAX - redefined warnings. - -Mon May 10 20:00:43 1993 Fred Fish (fnf@cygnus.com) - - * README, NEWS: Update for gdb 4.9 release. - -Mon May 10 19:38:34 1993 John Gilmore (gnu@cygnus.com) - - * ch-exp.y (MAX, MIN): Rename to MAX_TOKEN, MIN_TOKEN. - * target.c (MIN): #undef before defining. - -Mon May 10 16:03:03 1993 Jim Kingdon (kingdon@cygnus.com) - - Patch from Jeffrey Law: - * gdb/config/pa/nm-hppab.h (PTRACE_ARG3_TYPE): Define as caddr_t. - -Mon May 10 15:28:27 1993 Ian Lance Taylor (ian@cygnus.com) - - * hppa-tdep.c (hppa_push_arguments): Allocate correct amount of - memory. - -Mon May 10 13:14:46 1993 Fred Fish (fnf@cygnus.com) - - * ch-exp.y (start): Apply work-around to avoid bison warning. - -Sun May 9 07:25:02 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (BISON): Remove double quotes around BISON - definition when bison is used. - - * configure.in (hppa*-hp-bsd): Change to hppa*-hp-bsd* - * configure.in (hppa*-hp-hpux): Change to hppa*-hp-hpux* - * configure.in (m68*-hp-bsd): Change to m68*-hp-bsd* - * configure.in (m68*-hp-hpux): Change to m68*-hp-hpux* - * configure.in (hppa*-*-bsd): Change to hppa*-*-bsd* - * configure.in (hppa*-*-hpux): Change to hppa*-*-hpux* - * configure.in (m68*-hp-bsd): Change to m68*-hp-bsd* - * configure.in (m68*-hp-hpux): Change to m68*-hp-hpux* - - * Makefile.in (VERSION): Bump to 4.8.6. - -Sat May 8 12:36:03 1993 Fred Fish (fnf@cygnus.com) - - * config/pa/xm-hppah.h (MALLOC_INCOMPATIBLE): Define it, and - include declarations for malloc/realloc/free. Both malloc and - realloc return 'void *' for non-ANSI compilations. - -Sat May 8 01:39:30 1993 (pes@regent.e-technik.tu-muenchen.de) - - * coffread.c (read_coff_symtab): Don't fclose stream as it is no - longer opened twice. - -Thu May 6 21:08:55 1993 Jim Kingdon (kingdon@cygnus.com) - - * solib.c (clear_solib): Don't close bfd if it is NULL. - -Thu May 6 20:55:35 1993 Fred Fish (fnf@cygnus.com) - - * core.c (dis_asm_read_memory): Cast second arg of - target_read_memory to "char *". - * breakpoint.c (watchpoint_check): Change arg type from PTR to - "char *", to match other functions called by catch_errors(). - -Thu May 6 15:47:45 1993 Stu Grossman (grossman@cygnus.com) - - * More patches from Jeffrey Law (law@cs.utah.edu). - * gdb/config/nm-hppab.h (PTRACE_ARG3_TYPE): Define as caddr_t. - * gdb/config/pa/tm-hppah.h (millicode_start, millicode_end): - Delete unnecessary declarations. - -Thu May 6 15:15:46 1993 Stu Grossman (grossman@cygnus.com) - - * ser-unix.c (wait_for): Use VTIME to do timeouts instead of - poll() for termio{s}. - -Thu May 6 10:03:41 1993 Jim Kingdon (kingdon@cygnus.com) - - * i386-tdep.c (i386_frame_num_args): Always return -1. - -Wed May 5 15:16:33 1993 Stu Grossman (grossman@cygnus.com) - - * Patches from Jeffrey Law . - * gdb/hppa-tdep.c: Declare frame_saved_pc. - (frameless_function_invocation): New function. - (frame_saved_pc, init_extra_frame_info): Use - frameless_function_invocation. - * gdb/config/pa/tm-hppa.h (SAVED_PC_AFTER_CALL): Use saved_pc_after - call instead of just grabbing the value currently in %r2. - (FRAMELESS_FUNCTION_INVOCATION): Use frameless_function_invocation. - * gdb/config/pa/tm-hppah.h (SAVED_PC_AFTER_CALL): Delete private - definition and use the common one in tm-hppa.h. - * gdb/hppa-tdep.c (frame_chain_valid): If "use_unwind" is true, then - use unwind descriptors to determine if the frame chain is valid. - * gdb/hppa-tdep.c (find_dummy_frame_regs): Rework so that - it does not assume %r4 is the frame pointer. - * gdb/hppa-pinsn.c (print_insn): Handle 'r' and 'R' for break, rsm, - and ssm instructions. - * gdb/hppa-tdep.c (extract_5r_store, extract_5R_store): New - helper functions for print_insn. - * gdb/hppa-tdep.c (gcc_p, hpux_cc_p): Delete unused functions. - * gdb/config/pa/tm-hppa.h (ABOUT_TO_RETURN): Handle a return - which nullifies the following instruction. - -Tue May 4 12:11:38 1993 Jim Kingdon (kingdon@cygnus.com) - - * infptrace.c [FIVE_ARG_PTRACE]: Define ptrace to call_ptrace and - pass the 5th arg there, rather than using an ANSI C-specific macro. - - * Makefile.in (depend): Don't include ${CC} command for *.tab.c. - -Tue May 4 19:33:12 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.8.5 - * Makefile.in (INCLUDE_CFLAGS): Add BFD_DIR and READLINE_DIR - directories to include search path. - * Makefile.in (CLIBS, CDEPS, ADD_FILES, ADD_DEPS): Clean up - whitespace. - * Makefile.in (depend): For gcc -MM line, use INTERNAL_CFLAGS - * Makefile.in (main.o, dbxread.o, coffread.o, mipsread.o, - elfread.o, dwarfread.o, stabsread.o, xcoffread.o, xcoffexec.o, - xdr_ld.o, xdr_rdb.o, nindy.o, Onindy.o, ttybreak.o, ttyflush.o, - udr.o, udip2soc.o): Remove explicit rules, use the ones that - are automatically generated in "depend". - * Makefile.in (paread.o): Document why a dependency doesn't get - automatically generated in "depend" and leave this explicit rule - in for now (FIXME). - * depend: Update to latest automatically generated version. - -Tue May 4 12:11:38 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c: Doc fix. - - * Makefile.in (depend): Include $(CC) command in generated output. - -Mon May 3 22:51:05 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (NONSRC): Remove ${srcdir}/putenv.c. - * Makefile.in (SFILES): Add ${srcdir}/putenv.c. - * depend: Update to latest automatically built version. - -Mon May 3 19:20:20 1993 Stu Grossman (grossman@cygnus.com) - - * sparclite/Makefile.in: Create default target that does nothing - in order to force user to build by hand. - - * sparclite/Makefile: Remove. It's not necessary anymore. - - * ser-unix.c (wait_for): New routine to handle read timeouts, - etc. Uses poll() if HAVE_TERMIO[S] is defined, select() otherwise. - -Mon May 3 13:52:08 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips-pinsn.c (print_insn): Return value. - -Sun May 2 11:43:57 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (SFILES): Remove ser-hardwire.c; it is a link made - at configuration time and doesn't belong in the distribution archive. - - * Makefile.in (NONSRC): Add 29k-share/README. - * Makefile.in (HFILES): Add 29k-share/udi/udiids.h. - - * defs.h (UINT_MAX, LONG_MAX, INT_MAX, INT_MIN): Replace hex - constants with slightly more portable definitions (still depends - on 2's complement arithmetic though). - * config/i386/nm-linux.h: Define NO_SYS_REG_H for no . - * i386v-nat.c (sys/reg.h): Conditionalize include on - NO_SYS_REG_H. Linux doesn't have . - * ser-unix.c (termio.h): Include like other files that - include termio.h, not which may not exist (on - linux for example). - -Sat May 1 16:05:24 1993 Fred Fish (fnf@cygnus.com) - - * valprint.c (print_longest): Change format parameter from a - 'char' to an 'int'. We can't have 'char' parameters with the - current coding style, where we mix prototypes with pre-ANSI - style declarations. - * value.h (print_longest): Change format parameter in prototype - from a 'char' to an 'int'. - -Sat May 1 02:47:20 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/tm-mips.h (STAB_REG_TO_REGNUM): Match it with the gcc - definition. - * config/mips/tm-irix3.h (STAB_REG_TO_REGNUM): Add. - * irix4-nat.c (fill_fpregset): Fix bug with indexing into fpregsetp. - -Fri Apr 30 17:45:32 1993 Stu Grossman (grossman@cygnus.com) - - * The following patches are from Jeffrey Law . - * config/pa/hppabsd.mh: Add more files to NATDEPFILES. - * config/pa/xm-hppa[bh].h: Define FIVE_ARG_PTRACE. - * hppab-nat.c: Delete WANT_NATIVE_TARGET ifdefs. - ptrace needs 5 arguments, #define ptrace to always - pass zero as the 5th argument. - -Fri Apr 30 15:54:13 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * configure.in: Match z8k-*-sim for z8000. - * config/h8500/tm-h8500.h, h8500-tdep.c: Lint. - * remote-hms.c: Update to use new serial protocol. - -Fri Apr 30 16:50:38 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * mips-tdep.c: remove include of sys/dir.h. Doesn't seem - necessary and Solaris doesn't have it. - - * Makefile.in (clean-info, install, install-info, info, dvi, - check, all): do not echo recursion lines. - - * 29k-share/udip2soc.c (UDIConnect): replace union wait with int. - - * config/sparc/sun4sol2.mh (XM_CLIBS): add -lsocket which is - required target ports which use sockets (like a29k-udi). - - * remote-udi.c (udi_wait): Use SIGURG, as Solaris doesn't have SIGLOST. - -Fri Apr 30 11:05:42 1993 Jim Kingdon (kingdon@cygnus.com) - - * ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with - systems lacking select(). - - * Makefile.in (TAGS): Doc fix. Deal with empty DEPFILES. - -Fri Apr 30 10:06:46 1993 Fred Fish (fnf@cygnus.com) - - * alldeps.mak, depend: Update with latest automatically built - versions. - -Thu Apr 29 12:03:23 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (SFILES): Add ser-unix.c and ser-go32.c. - - * Makefile.in (make-proto-testsuite.dir): New target to make - prototype testsuite tree. - - * Makefile.in (VERSION): Bump to 4.8.4. - -Thu Apr 29 08:46:22 1993 Jim Kingdon (kingdon@cygnus.com) - - * stabsread.c (define_symbol): If unrecognized constant type, - complain() not error(). - -Thu Apr 29 00:03:59 1993 Fred Fish (fnf@cygnus.com) - - * infptrace.c: Add missing close paren to test for - FIVE_ARG_PTRACE defined. - - * defs.h (CC_HAS_LONG_LONG): Set up to define CC_HAS_LONG_LONG - when compiling with gcc, but disable it for now. See comment. - * defs.h (LONGEST): Define as either "long" or "long long" - based on CC_HAS_LONG_LONG. - * defs.h (longest_to_int): Use CC_HAS_LONG_LONG to control - how longest_to_int is defined. - * c-valprint.c (c_val_print): Call print_longest. - * expprint.c (dump_expression): Use PRINTF_HAS_LONG_LONG - instead of LONG_LONG. - * {printcmd.c, gdbtypes.h} (LONG_LONG): Replace usages with - CC_HAS_LONG_LONG. - * printcmd.c (print_scalar_formatted): Call print_longest - and let it figure out what to do for PRINTF_HAS_LONG_LONG. - * typeprint.c (print_type_scalar): Call print_longest and let - it figure out what to do for PRINTF_HAS_LONG_LONG. - * valprint.c (val_print_type_code_int): Call print_longest - and let it figure out what to do for PRINTF_HAS_LONG_LONG. - * stabsread.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG. - * value.h (struct value): Replace usage of LONG_LONG with - CC_HAS_LONG_LONG. - * value.h (print_longest): Add prototype. - * values.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG. - * values.c (unpack_double): Collapse code that was unnecessarily - dependent on CC_HAS_LONG_LONG. Use LONGEST instead of direct types. - * values.c (value_from_longest): Remove dependency on - CC_HAS_LONG_LONG and just use LONGEST. - * solib.c (solib_map_sections): Use bfd_get_filename - to access filename field. - * solib.c (clear_solib): Save filename and free it later, after - bfd_close, since bfd_close may reference it. Use bfd_get_filename - to access the field. - * config/convex/xm-convex.h (LONG_LONG): Replace with - CC_HAS_LONG_LONG. Add define for PRINTF_HAS_LONG_LONG. - * doc/gdbint.texinfo (LONG_LONG): Replace with CC_HAS_LONG_LONG. - Add PRINTF_HAS_LONG_LONG references. - -Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com) - - * inflow.c (kill_command), infcmd.c (attach_command), - remote.c (remote_interrupt_twice): In messages for the user, call it - "the program" or "the program being debugged" not "the inferior". - - * hp300ux-nat.c: Cast second arg to supply_register calls. - (_initialize_kernel_u_addr, getpagesize): New functions. - (store_inferior_register_1): Change arg name from value to val. - (fetch_core_registers): Make arg core_reg_size unsigned. - Pass 5 args to ptrace. - * config/m68k/xm-hp300hpux.h: Define FIVE_ARG_PTRACE. - Remove KERNEL_U_ADDR stuff. - * infptrace.c [FIVE_ARG_PTRACE]: Pass 5th arg to ptrace. - * config/m68k/hp300hpux.m{t,h}: - Move exec.o from NATDEPFILES to TDEPFILES - * config/m68k/hp300hpux.mt: Mention GAS requirement. Remove - hp-include stuff. Add m68k-tdep.o to TDEPFILES. - -Wed Apr 28 13:27:54 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * ch-exp.y (yylex): Don't STREQ with simplename if it is NULL. - -Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com) - - * config/sparc/xm-sun4os4.h [__STDC__]: Don't use MALLOC_INCOMPATIBLE. - -Wed Apr 28 11:39:18 1993 Roland H. Pesch (pesch@fowanton.cygnus.com) - - * doc/gdb.texinfo: make node "Shell Commands" unconditional; - describe `set demangle-style arm' (not cfront); - mention can type `q' to discard output, when gdb pages - -Wed Apr 28 11:32:39 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * valops.c (search_struct_field): Fix gdb core dump with incomplete - stabs info. - -Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com) - - * remote.c: Change timeout to 2. - (remote_open): Use unpush_target not remote_close. - (remote_resume): If siggnal != 0, give warning not error(). - (remote_wait, remote_interrupt, remote_interrupt_twice): - If we get two interrupts, let the user get out if they want. - (remote_{kill,mourn}): New functions. - i386-stub.c (handle_exception, case 'k'): Don't BREAKPOINT. - -Wed Apr 28 09:20:55 1993 Ian Lance Taylor (ian@rtl.cygnus.com) - - * config/sparc/sun4sol2.mh (XM_CLIBS): Define to be -lnsl. - -Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com) - - * Remote targets (mourn): Call unpush_target. - - * config/sparc/xm-sun4os4.h: Declare free() to return int. - Remove twisted use of PARAMS. - - * config/rs6000/xm-rs6000.h: Don't define MALLOC_INCOMPATIBLE now - that ansidecl.h assumes ANSI on AIX. - -Tue Apr 27 10:01:33 1993 Jim Kingdon (kingdon@cygnus.com) - - * README: Move most stuff about hacking GDB to doc/gdbint.texinfo. - (Known bugs): Remove AIX bugs, revise SPARC struct bug description. - -Tue Apr 27 13:44:19 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * expprint.c (print_subexp): Fix bug with OP_SCOPE operator output. - -Tue Apr 27 10:01:33 1993 Jim Kingdon (kingdon@cygnus.com) - - * remote-vx.c (net_connect): Allow numeric IP address for host. - -Mon Apr 26 17:59:38 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * config/sh/sh.mt, config/sh/tm-sh.h, sh-tdep.c: New files. - -Mon Apr 26 07:13:32 1993 Jim Kingdon (kingdon@cygnus.com) - - * rs6000-tdep.c (branch_dest): Deal with stepping through system call. - - * symtab.h, xcoffread.c: Revise linetable sorting comments. - -Sun Apr 25 02:32:16 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * valops.c (value_cast): A cast might also change the object - representation in C++. - * dbxread.c (end_psymtab): Copy subpst read_symtab function from pst - to get the proper read_symtab function when called from mipsread.c. - * mipsread.c (mipscoff_psymtab_to_symtab, psymtab_to_symtab_1): - Set cur_bfd in psymtab_to_symtab_1 as CURBFD(pst) is invalid - for dummy psymtabs, inhibit processing of dummy psymtabs. - -Sat Apr 24 19:59:54 1993 Jim Kingdon (kingdon@cygnus.com) - - * Changes from (or inspired by) AMD: - * remote-udi.c (udi_attach): Assignments to Space and Offset were - switched, fix it. - (udi_wait): Make error message (UDIGetStdout) match error. - (udi_wait): Handle UDIStdinNeeded. - * command.c [CANT_FORK]: Use system(). - * utils.c (prompt_for_continue): Allow quit with 'q'. - - * solib.c (solib_add): Don't call special_symbol_handling if there - were errors in symbol_add_stub. Also set so->from_tty before - calling symbol_add_stub. - -Fri Apr 23 16:17:00 1993 Stu Grossman (grossman@cygnus.com) - - * Merge in HPPA/BSD patches from Utah: - * defs.h: Add const to 2nd arg of psignal prototype. - * hppah-tdep.c: Renamed to hppa-tdep.c 'cuz it's common code with - BSD now. - * hppab-core.c: Deleted. No longer useful. - * hppab-nat.c: #include more files. Use PT_WUREGS, not - PT_WRITE_U. - * hppab-tdep.c: Deleted. Supplanted by hppa-tdep.c. - * config/pa/hppabsd.mh (NATDEPFILES): Remove hppab-core.o. - * config/pa/hppabsd.mt (TDEPFILES): hppab-tdep.o => hppa-tdep.o - * config/pa/hppahpux.mt (TDEPFILES): hppab-tdep.o => hppa-tdep.o - * config/pa/xm-hppab.h: #define SET_STACK_LIMIT_HUGE. - -Fri Apr 23 10:34:02 1993 Stu Grossman (grossman@cygnus.com) - - * Fix two bugs found by deja-gnu. One is the incorrect reporting - of the PC being in a stack dummy when looking at a core file - without symbols. The other is the incorrect passing of char - arguments during expression evaluation (ie: p foo('a','b') would - mess up the passing of it's args because it wasn't coercing the - char's to ints). - * hppah-tdep.c: Rename global functions to have consistent hppa_ - prefix. Make more functions static. Drop hp_ prefix from static - functions. (hppa_push_arguments): Call value_arg_coerce to cast - char to int args if necessary. (hppa_fix_call_dummy): Create - this routine from FIX_CALL_DUMMY macro in tm-hppa.h. - * inferior.h (PC_IN_CALL_DUMMY): Check for frame_address being - valid (ie: != 0) before doing comparison against PC. - * valops.c (call_function_by_hand): Adjust call to FIX_CALL_DUMMY - to reflect new arguments. - * config/pa/tm-hppa.h (POP_FRAME, PUSH_ARGUMENTS): Use new hppa_ - prefix for func name. (FIX_CALL_DUMMY): Move code into - hppah-tdep.c. - - * testsuite/gdb.t16/gdbme.c, testsuite/gdb.t17/gdbme.c: Add calls - to malloc() so that we can test GDB eval of dynamically created - arrays (like char strings in `print "foo"'). - -Fri Apr 23 01:28:14 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * printcmd.c (print_address_symbolic): Search symtabs as well as the - minimal symbols for a nearby symbol. - -Thu Apr 22 19:44:21 1993 John Gilmore (gnu@cacophony.cygnus.com) - - * coffread.c: Comment changes around minimal symbol recording. - -Thu Apr 22 16:24:36 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * command.c: comment changes only. - - * mips-tdep.c (heuristic_fence_post): new static variable. - (heuristic_proc_start): use heuristic_fence_post, print better - warnings, but only if not stop_soon_quietly. - (_initialize_mips_tdep): add_set_cmd for heuristic-fence-post. - -Thu Apr 22 14:50:05 1993 Jim Kingdon (kingdon@cygnus.com) - - * symtab.h: Fix LOC_REF_ARG comment. - -Wed Apr 22 20:21:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - and Jim Kingdon (kingdon@cygnus.com) - - * stabsread.c (define_symbol): Combine a 'p', 'r' arg pair to a - LOC_REGPARM symbol. - * config/sparc/tm-sparc.h (REG_STRUCT_HAS_ADDR): Revise comments. - symfile.c (compare_symbols): Don't check first character; STRCMP - does that. - - * stabsread.c (define_symbol): Generate a LOC_REGPARM_ADDR for - structures that are passed by address in a register. - * symtab.h (enum address_class): Add LOC_REGPARM_ADDR. - * findvar.c (read_var_value), - printcmd.c (address_info, print_frame_args), - stack.c (print_frame_arg_vars), symmisc.c (print_{,partial_}symbol), - * symtab.c (lookup_block_symbol): Deal with it. - -Thu Apr 22 09:07:24 1993 Jim Kingdon (kingdon@cygnus.com) - - * objfiles.h (obj_section), objfiles.c (build_objfile_section_table): - Add objfile field. - * objfiles.c (find_pc_section): Return a struct obj_section *. - * sparc-tdep.c (in_solib_trampoline): Deal with find_pc_section return. - * symfile.c (syms_from_objfile) [IBM6000_TARGET]: - Don't use obj_section hack. - * xcoffexec (vmap_symtab): Relocate obj_sections. - * printcmd.c (containing_function_bounds): Use find_pc_section. - - * symtab.h: Clean up SYMBOL_VALUE comments. - -Wed Apr 21 14:29:57 1993 Jim Kingdon (kingdon@cygnus.com) - - * stack.c (print_frame_arg_vars), printcmd.c (print_frame_args): - Expand comments about LOC_ARG/LOC_LOCAL pairs. - - * coffread.c (read_coff_symtab): Use rewind before fseek. - -Wed Apr 21 14:24:19 1993 Per Bothner (bothner@cygnus.com) - - * ch-exp.y: Removed unused structure_primitive_value and FIXME_23. - * Makefile.in: Add $(YFLAGS) when using $(YACC). - * Makefile.in: Remove message to expect conflicts and unused - rules in ch-exp.y, since there no longer are any such. - -Wed Apr 21 13:27:50 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * stabs.texinfo: fixed bad xrefs (un-initialized statics) - -Tue Apr 20 08:55:11 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffexec.c (xcoff_relocate_core): If no exec file, error() - rather than dumping core. - - * Makefile.in: Add ${srcdir}/ to all source files. - (alldeps.mak): Add "${srcdir}/" to files when generating alldeps.mak. - (TAGS): Deal with srcdir and new config directory scheme. - createtags: Remove. - Makefile.in (NONSRC): Remove createtags. - alldeps.mak: Updated. - - * rs6000-tdep.c: Delete unused function print_frame. - - * frame.h (struct frame_info): Doc fix for next_frame. - New field signal_handler_caller. - blockframe.c (create_new_frame, get_prev_frame_info), - config/rs6000/tm-rs6000.h (INIT_EXTRA_FRAME_INFO): Set it (needs - INIT_FRAME_PC_FIRST). - stack.c (print_frame_info), rs6000-tdep.c (rs6000_frame_chain): - Check it. - -Mon Apr 19 22:52:33 1993 Stu Grossman (grossman@cygnus.com) - - * irix4-nat.c (fetch_core_registers): Special version of this for - Irix 4.x, which stores regs a bit differently from other /proc - based systems. - * procfs.c, core-svr4.c: Move fetch_core_registers from procfs.c - to new file core-svr4.c. - * config/i386/i386sol2.mh, config/i386/i386v4.mh, config/m68k/amix.mh, - config/i386/ncr3000.mh, config/sparc/sun4sol2.mh: Add core-svr4.o - to NATDEPFILES. - * config/mips/irix4.mh: Add corelow.o to NATDEPFILES. - -Mon Apr 19 11:13:34 1993 Jim Kingdon (kingdon@cygnus.com) - - * i387-tdep.c: Remove unused #includes. - - * configure.in: Match i[34]86-*-sysv3.2 not i[34]86-*-sysv32. - - * config/i386/nm-i386v.h: Define NO_PTRACE_H. - -Sun Apr 18 10:39:35 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c: Nuke NO_DEFINE_SYMBOL code. There is no going back. - - * stabsread.c (define_symbol): 'R' is synonym for 'P', not 'r'. - xcoffread.c (process_xcoff_symbol, case C_RPSYM): - Don't muck with SYMBOL_CLASS. - -Fri Apr 16 17:38:33 1993 Stu Grossman (grossman@cygnus.com) - - * munch: Don't use head command. It doesn't exist everywhere. - -Fri Apr 16 15:07:57 1993 Fred Fish (fnf@cygnus.com) - - * inflow.c (new_tty): Remove spurious 'o' character at end - of #endif line. - -Fri Apr 16 12:27:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-tdep.c (mips_skip_prologue): Always skip the typical prologue - instructions and nothing more. - * mipsread.c (add_line): Add comment why we have to combine line number - entries for the same line number. - -Fri Apr 16 09:42:03 1993 Jim Kingdon (kingdon@cygnus.com) - - * symtab.{c,h}: Doc fixes (remove symseg references, last relevant - in gdb 2.8!). - -Thu Apr 15 21:16:58 1993 Fred Fish (fnf@cygnus.com) - - * depend, alldeps.mak: Update, now that gcc -MM bug is fixed. - -Thu Apr 15 12:38:39 1993 Jim Kingdon (kingdon@cygnus.com) - - * source.c (select_source_symtab): Clean up comment. Also, if - we have a current_source_symtab, and s is NULL, return without - doing anything. - xcoffread.c (xcoff_symfile_read): Don't call select_source_symtab. - breakpoint.c (breakpoint_re_set): Don't call select_source_symtab. - -Thu Apr 15 02:37:48 1993 John Gilmore (gnu@cacophony.cygnus.com) - - * dbxread.c (unknown_symchar_complaint): Add new complaint. - * stabsread.h: Declare it. - * partial-stab.h: Use it. - - * utils.c (malloc_botch): Don't forward-declare if NO_MMALLOC. - -Wed Apr 14 17:12:51 1993 Jim Kingdon (kingdon@cygnus.com) - - * stack.c (print_frame_info): Print specially if dummy frame. - - * breakpoint.c: Add comments regarding within_scope future direction. - - * Version 4.8.3. - - * xcoffread.c (record_include_{begin,end}): Change fatal to complain. - -Wed Apr 14 14:03:18 1993 Per Bothner (bothner@cygnus.com) - - * ch-exp.y: Fix thinko that broke parsing of FALSE. - -Wed Apr 14 12:49:29 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * stabsread.c (read_member_functions): Initialize domain for stubbed - member functions to avoid gdb core dumps when printing pointers - to member functions. - * cp-valprint.c (cp_print_class_method): Check for stubbed member - functions. - -Tue Apr 13 08:28:26 1993 Jim Kingdon (kingdon@cygnus.com) - - * expprint.c (print_subexp): If opcode not found in op_print_tab, - stop with an error(). - eval.c (evaluate_subexp): Change error message. - - * objfiles.c (build_objfile_section_table): Cast return value - from obstack_finish. - -Mon Apr 12 10:53:50 1993 Jim Kingdon (kingdon@cygnus.com) - - * config/rs6000/tm-rs6000.h, rs6000-tdep.c: Move FRAME_CHAIN - to rs6000_frame_chain and deal with it if we're in a signal handler. - (FRAME_SAVED_PC): Use rs6000_frame_chain. - - * breakpoint.c (within_scope): New function. - (enable_breakpoint, watchpoint_check): Use it. - - * source.c (openp): Handle "exec-file ./ls" correctly. - - * breakpoint.c (breakpoint_1): Use wrap_here before "at". - -Sat Apr 10 01:32:43 1993 Per Bothner (bothner@rtl.cygnus.com) - - * ch-exp.y: Clean up lexing of identifiers and - reserved words. (E.g. don't recognize FALSEXXX as the - keyword FALSE followed by the identifier XXX.) - Also, convert identifiers to lower case. - -Fri Apr 9 15:53:19 1993 Stu Grossman (grossman@cygnus.com) - - * remote-mips.c, remote-monitor.c, remote-st2000.c: Convert to - new serial interface. - -Fri Apr 9 15:01:12 1993 Stu Grossman (grossman@cygnus.com) - - * remote.c (remote_open): Use SERIAL_OPEN instead of serial_open. - (putpkt, getpkt): Use new return codes for SERIAL_READCHAR. - * ser-go32.c: Return -1 on most failures, 0 on most successes, - and use new return codes for go32_readchar(). - * ser-unix.c: Ditto. Also, move error handling up to caller for - SERIAL_SETBAUDRATE(). - * serial.c (serial_open): Internal call, not SERIAL_OPEN to get - to specific routine. - (serial_close): New routine to wrap around device close routine. - serial.h: Clean & document return values more clearly. - -Fri Apr 9 10:20:55 1993 Jim Kingdon (kingdon@cygnus.com) - - * rs6000-pinsn.c (print_operand): Deal with no operand instructions. - - * rs6000-pinsn.c (print_operand, case LI): Print condition register - operand in decimal rather than wrong textual versions. - - * printcmd.c (_initialize_printcmd): Clean up docstring for "x" - (mention 't', remove false thing about 'g' only good with 'f'). - - * breakpoint.h: move "struct breakpoint" and friends to top of - file so that bpstat_find_breakpoint prototype works. - - * solib.c (struct so_list): Add bfd field. - (solib_map_sections): Leave bfd open and scratch_pathname allocated. - Put the bfd in bfd field of the so_list. - (clear_solib): Free bfd name and close_bfd on the bfd. - -Fri Apr 9 00:45:41 1993 Per Bothner (bothner@rtl.cygnus.com) - - * valarith.c (value_subscript): Add COERCE_REF. - * ch-exp.y (operand_5): We can generalize the 2nd operand - of a string repetition ot 'literal' without ambiguity. - -Thu Apr 8 10:15:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.h (struct bpstat): Remove momentary field. - Remove bpstat_momentary_breakpoint. This was always kludgy - and is no longer used. - - * breakpoint.h: Add enum bpstat_what. - breakpoint.h (struct bpstat), breakpoint.c (bpstat_stop_status): - stop and print fields of bpstat now per-breakpoint, not just - one for the whole chain. - breakpoint.{c,h} (bpstat_what): New function. - breakpoint.h: Remove bpstat_stop and bpstat_should_print. - infrun.c: Replace switch (stop_bpstat->breakpoint_at->type) - with call to bpstat_what. - README: Remove watchpoint/breakpoint bug from known bugs. - - * breakpoint.h: Prototype bpstat_find_breakpoint. - -Thu Apr 8 16:01:21 1993 Fred Fish (fnf@cygnus.com) - - * symtab.c (find_methods, gdb_mangle_name): Note that functions - are g++ specific. - * symtab.h (VTBL_FNADDR_OFFSET, OPNAME_PREFIX_P, VTBL_PREFIX_P, - DESTRUCTOR_PREFIX_P): Note that macros are g++ specific. - -Thu Apr 8 12:45:32 1993 Ian Lance Taylor (ian@cygnus.com) - - * i960-pinsn.c (tabent): Copied struct definition from - opcodes/i960-dis.c. - -Thu Apr 8 10:34:37 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symtab.h (DESTRUCTOR_PREFIX_P): New macro to check if physname - is a C++ destructor. - * symtab.c (gdb_mangle_name): Use it. - * symtab.c (find_methods): Do not add destructors to choice list - for constructors. - * symtab.c (decode_line_1): Make breakpoints on destructors work - for gcc-2.x again. - -Wed Apr 7 18:43:09 1993 Stu Grossman (grossman@cygnus.com) - - * ser-go32.c: Make it use serial port name. - * go32-xdep.c: Put in def for strlwr, needed by dir.o in go32 libc. - - * infcmd.c (read_pc): Make sure that we read PC_REGNUM when not - in a system call! - -Wed Apr 7 15:52:11 1993 Stu Grossman (grossman@cygnus.com) - - * configure.in: Only configure sparclite subdir when target_cpu - is sparclite. - -Wed Apr 7 10:11:22 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c (struct coff_symbol): Change c_sclass to unsigned char. - Remove FIXME comment regarding this. - - * symfile.h: Change NULL->'\0' in comment (that wasn't a typo). - - * xcoffread.c (read_xcoff_symtab): Use E_SYMNMLEN. - -Tue Apr 6 22:30:58 1993 K. Richard Pixley (rich@cygnus.com) - - Add section table to objfile struct. Use it for find_pc_section. - * objfiles.c (add_to_objfile_sections, - build_objfile_section_table, find_pc_section): new functions. - (allocate_objfile): build section table. - * objfiles.h (struct obj_section): new structure. - (struct objfile): add section table. - (find_pc_section): new prototype. - * solib.[ch] (find_pc_section_from_so_list): removed. - * sparc-tdep.c: include objfiles.h for find_pc_section. include - symfile.h for objfiles.h. - (in_solib_trampoline): adjusted for new find_pc_section - prototype. Removed BAD_RICH_HACK ifdefs. - * symfile.c (syms_from_objfile): offset objfile sections. - (find_pc_section): removed. Also removed BAD_RICH_HACK ifdefs. - * symfile.h (find_pc_section): prototype removed. Also fixed - comment typo NUL -> NULL. - * target.[ch] (find_pc_section_from_targets): removed. - * config/sparc/tm-sun4sol2.h (BAD_RICHH_HACK): removed. - -Tue Apr 6 21:41:13 1993 Stu Grossman (grossman@cygnus.com) - - * ser-go32.c: Format. (go32_open): Use proper return value. - - * configure.in: Undo conditional configdirs hack for sparclite. - -Tue Apr 6 17:07:37 1993 Jim Wilson (wilson@sphagnum.cygnus.com) - - * symtab.c (list_symbols): When call break_command, pass both - filename and function name not just function name. - -Tue Apr 6 15:00:09 1993 Fred Fish (fnf@cygnus.com) - - (Changes and new files to make "none" a full fledged configuration) - * config/none/{nm-none.h, tm-none.h, xm-none.h}: New files. - Currently only tm-none.h has any meaningful contents. - * config/none/none.mh (NAT_FILE): Use nm-none.h - * config/none/none.mh (XM_FILE): Use xm-none.h - * config/none/none.mt (TM_FILE): Use tm-none.h - * Makefile.in (depend): Remove comment about parse errors in - valops.c, it now parses correctly and generates a correct depend - line. Remove line that touches xm.h, tm.h, and nm.h; they are - now linked to config/none/{xm-none.h, tm-none.h, nm-none.h}. - -Tue Apr 6 09:54:29 1993 Jim Kingdon (kingdon@cygnus.com) - - * values.c (USE_STRUCT_RETURN): Only use gcc wierdness for gcc1. - - * xcoffread.c (read_xcoff_symtab): Deal correctly with symbols of - exactly 8 characters. - -Tue Apr 6 10:31:26 1993 Stu Grossman (grossman@cygnus.com) - - * configure.in: Sparclite uses sparc config dir. Also has it's - own tm- & .mt files now. Also add sparclite to configdirs. - * go32-xdep.c: Dummy routines for sigsetmask & strlwr. - * config/i386/go32.mh: Nullify def of TERMCAP. - * config/i386/xm-go32.h: Get rid of redef of EIO. - * config/sparc/{sparclite.mh tm-sparclite.h}: New sparclite - specific configs. Very similar to sun4os4, but without solib. - * sparclite/{Makefile.in configure.in}: First cut at making this - dir configgable. - -Tue Apr 6 03:10:44 1993 Stu Grossman (grossman@cygnus.com) - - * ser-go32.c: First cut at adapting to new serial interface. - -Mon Apr 5 22:29:43 1993 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (SFILES OBS): Add serial.[co] & ser-hardwire.[co]. - These implement a new serial line interface for talking to remote - targets. - * configure.in: Link ser-hardwire.c to ser-unix.c for all hosts, - EXCEPT go32, which gets ser-go32.c. - * remote.c: Use new serial interface. More remote-xxx's to be - converted later. - * ser-bsd.c, ser-termios.c: Removed. - * serial.c: New. Implements common operations for all serial - types. - * ser-unix.c: New. Unix specific serial operations for various - flavors of Unix (Posix, SysV, BSD). - * serial.h: Generic serial interface defs. - * config/i386/go32.mh, config/i386/i386bsd.h, - config/m68k/apollo68b.mh, config/sparc/sun4os4.mh: Remove - ser-bsd.o from XDEPFILES. All the magic is now handled in - configure.in. - -Mon Apr 5 20:48:54 1993 Stu Grossman (grossman@cygnus.com) - - * config/h8500/tm-h8500.h: Clean up brain damage found by GCC. - -Fri Apr 2 08:23:14 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c (xcoff_symfile_offsets): Use 0 not addr for offsets. - - * rs6000-tdep.c (frameless_function_invocation): Don't even think - about framelessness except on the innermost frame. - - * xcoffexec.c: Call fatal() not abort(). - - * stabsread.c (patch_block_stabs): If stab & no symbol, make - a LOC_OPTIMIZED_OUT symbol. - symtab.h (enum address_class): Add LOC_OPTIMIZED_OUT. - findvar.c (read_var_value), printcmd.c (address_info), - symmisc.c (print_{,partial_}symbol), c-exp.y (variable), - m2-exp.y (yylex): Deal with it. - ch-exp.y (yylex): Deal with it. - -Thu Apr 1 18:43:02 1993 Stu Grossman (grossman@cygnus.com) - - * findvar.c (value_from_register): H8500 specific, check to see - if we are looking at short pointer. If so, skip crock. - * h8500-tdep.c (h8500_frame_chain): Mask down value from - read_memory_integer() to avoid getting messed up by sign extension. - -Thu Apr 1 16:44:41 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * sparc-tdep.c (in_solib_trampoline), symfile.c (find_pc_section): - ifdef protect using BAD_RICH_HACK. This should be removed soon. - * config/sparc/tm-sun4sol2.h (BAD_RICH_HACK): define. - -Thu Apr 1 09:01:38 1993 Jim Kingdon (kingdon@cygnus.com) - - * i960-pinsn.c, a29k-pinsn.c: Much abridged, just use libopcodes.a. - - * core.c (dis_asm_print_address): New function. - - * core.c (dis_asm_read_memory): Reinstate 4th arg. The prototype - has been fixed. - -Thu Apr 1 09:34:43 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * breakpoint.c (bpstat_print, bpstat_stop_status): Change to walk the - entire breakpoint chain and print only the first entry that needs to - be printed and needs to be stopped for. Fixes problems with printing - of multiple breakpoints with different conditions. - * breakpoint.c (print_it_done): Renamed from print_it_noop as it - effectively stops printing of the breakpoint chain. - * breakpoint.c (print_it_noop): New routine to print nothing - for this breakpoint entry and dont stop printing. - * breakpoint.c (breakpoint_re_set_one): mention the reevaluated - watchpoint only if it is enabled. - * mipsread.c (parse_procedure): Correct incorrect setjmp procedure - descriptor from the library to make backtraces through setjmp work. - * mipsread.c (fixup_sigtramp): Correct pcreg and fregoffset for - sigtramp. - * mips-tdep.c (read_next_frame_reg): Provide correct values for - all registers saved within sigtramp, cleanup. - -Wed Mar 31 12:52:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * sparc-pinsn.c: Much abridged, just calls version in libopcodes.a. - -Wed Mar 31 21:23:41 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * core.c (dis_asm_read_memory): drop fourth arg which conflicts - with prototype in ../include/dis-asm.h. - -Wed Mar 31 12:52:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * core.c (dis_asm_{read_memory,memory_error}): New functions. - m68k-pinsn.c, h8500-tdep.c, i386-pinsn.c, mips-pinsn.c, z8k-tdep.c: - Use read_memory_func interface to disassembler. - -Tue Mar 30 15:46:14 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - Teach sparc solaris to next over shared library functions. - * solib.[hc] (find_pc_section_from_so_list): new function and - prototype. - * sparc-tdep.c (in_solib_trampoline): new function. - * symfile.[hc] (find_pc_section): new function and prototypes. - * target.[hc] (find_pc_section_from_targets): new function and - prototypes. - * config/sparc/tm-sun4sol2.h (IN_SOLIB_TRAMPOLINE): redefine to - in_solib_trampoline. - -Tue Mar 30 08:06:24 1993 Jim Kingdon (kingdon@cygnus.com) - - * infrun.c (wait_for_inferior): Revise comment. - - * command.c (do_setshow_command): Use %u with var_{u,z}integer. - - * command.{c,h}: New var_type var_integer. - main.c: Use it for history_size. - - * rs6000-tdep.c, xcoffexec.c, config/rs6000/xm-rs6000.h, breakpoint.c: - Lint and byte-order fixups. - - * breakpoint.c (print_it_normal): Return 0 after hitting watchpoint. - - * breakpoint.h (bpstat): New field print_it. - breakpoint.c (bpstat_print): Use it. - (print_it_normal): New function (from old bpstat_print code). - (bpstat_{alloc,stop_status}): Set print_it field. - - * breakpoint.c (bpstat_stop_status): Use catch_errors when - evaluating watchpoint condition, via new function watchpoint_check. - Also stop if watchpoint disabled due to leaving its block. - - * findvar.c [REG_STRUCT_HAS_ADDR]: Add comment. - -Tue Mar 30 00:14:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-pinsn.c: Add missing include of dis-asm.h. - -Mon Mar 29 15:03:25 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (clean, distclean, realclean): Recursively apply - to subdirs first, rather than last. This avoids, for example, - Makefile being removed in a parent directory before the recursive - make is run. - - * alldeps.mak, depend: Update for below changes. - - * config/m68k/tm-m68k.h: Renamed from config/m68k/tm-68k.h. - * m68k/{tm-3b1.h, tm-altos.h, tm-amix.h, tm-es1800.h, - tm-hp300bsd.h, tm-hp300hpux.h, tm-isi.h, tm-news.h, tm-os68k.h, - tm-st2000.h, tm-sun2.h, tm-sun3.h, tm-vx68.h}: Include tm-m68k.h - instead of tm-68k.h. - * Makefile.in (HFILES): tm-68k.h renamed to tm-m68k.h. - * README, a29k-pinsn.c, m68k-pinsn.c, m68k-stub.c, remote-vx.c, - m68k/{altos.mh, altos.mt, apollo68b.mh, nm-apollo68b.h, - nm-hp300bsd.h, config/m68k/xm-apollo68b.h}: Map '68k' to 'm68k'. - * a29k/tm-a29k.h, doc/gdbint.texinfo: Account for renaming of - tm-68k.h to tm-m68k.h. - * m68k/m68k-fp.mt (TM_FILE): tm-68k-fp.h renamed to tm-m68k-fp.h. - * m68k/m68k-nofp.mt (TM_FILE): tm-68k-nofp.h renamed to - tm-m68k-nofp.h. - - * config/a29k/tm-a29k.h: Renamed from config/a29k/tm-29k.h. - * a29k-pinsn.c: Renamed from am29k-pinsn.c. - * a29k-tdep.c: Renamed from am29k-tdep.c. - * remote-eb.c, config/a29k/tm-ultra3.h: Include renamed tm-a29k.h. - * remote-monitor.c, remote-st2000.c, config/a29k/{nm-ultra3.h, - tm-a29k.h, xm-ultra3.h}, config/romp/rtbsd.mh, doc/gdbinv-s.texi, - testsuite/gdb.t15/funcargs.exp, testsuite/gdb.t17/callfuncs.exp: - Map '29k' to 'a29k'. - * config/a29k/{a29k-kern.mt, a29k-udi.mt, a29k.mt, ultra3.mt} - (TDEPFILES): Use renamed a29k-pinsn.o and a29k-tdep.o. - * config/a29k/{a29k-udi.mt, a29k.mt} (TM_FILE): Use renamed - tm-a29k.h. - * config/a29k/a29k-udi.mt (MT_CFLAGS): Remove TARGET_AM29K - define that does not appear anywhere else in the gdb source tree. - * doc/gdbinit.texinfo: Document renaming of tm-29k.h to tm-a29k.h. - -Mon Mar 29 13:55:29 1993 Jim Kingdon (kingdon@cygnus.com) - - * breakpoint.c: Add comments regarding breakpoint_re_set. - - * xcoffread.c (sort_syms, compare_symbols): Remove. - (xcoff_symfile_read): Use sort_all_symtab_syms from symfile.c - not our own sort_syms (it is identical). - - * xcoffread.c: Nuke NAMES_HAVE_DOT define (not used). - -Sun Mar 28 11:24:37 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * breakpoint.c (breakpoint_re_set_one): Fix storage leak. - * breakpoint.c (enable_breakpoint): Don't enable watchpoint if it - went out of scope. - * exec.c (exec_close): Fix storage leak. - * exec.c (exec_file_command): Make sure that bfd doesn't realign the - output sections when patching an executable. - * mips-nat.c (store_inferior_registers): Use REGISTER_PTRACE_ADDR - when writing all registers. - * mips-tdep.c (mips_push_dummy_frame): Save floating point registers - at the right offset in the dummy frame. - * mipsread.c (psymtab_to_symtab_1): Do not complain for stProc, - stStaticProc and stEnd symbols as they are generated by gcc-2.x. - * mipsread.c (mipscoff_new_init): Initialize stabsread and buildsym. - -Fri Mar 26 15:25:05 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (TARFILES): Avoid trailing backslash. - -Fri Mar 26 11:29:30 1993 Jim Kingdon (kingdon@cygnus.com) - - * breakpoint.{c,h}: Add exp_string to struct breakpoint and use - it in breakpoint_re_set. - * breakpoint.c (watch_command, enable_breakpoint): Fetch lazy values. - - * rs6000-tdep.c (single_step): Misc cleanups (CORE_ADDR not int, - don't use sizeof(int) for target stuff, etc). - -Thu Mar 25 15:03:53 1993 Fred Fish (fnf@cygnus.com) - - * alldeps.mak, configure.in, i860-break.h, i860-opcode.h, - i860-pinsn.c, i860-tdep.c, config/i860/*: Remove incomplete i860 - support that can't be integrated anyway due to lack of clear - authorship. - -Thu Mar 25 12:26:50 1993 Stu Grossman (grossman@cygnus.com) - - * findvar.c (read_register, write_register): Make these capable - of reading/writing registers that are shorter than REGISTER_TYPE. - * (value_from_register): Install H8500 specific code to return - proper value when register is being used as a pointer. - * h8500-tdep.c: Remove extra defines of NUM_REGS. - (h8500_skip_prologue): Use correct lengths for LINK instructions. - (FRAME_CHAIN): Change name to h8500_frame_chain. Rewrite code to - chain frames properly by combining frame pointer with T reg. - (init_extra_frame_info): Delete. It's now a macro. - (frame_args_address): Don't add PTR_SIZE. Stack args are already - offset by the correct amount off of the frame pointer. - (register_byte): Delete. It's now a macro. - (register_raw_size, register_virtual_size): Delete. Replaced by - common routine h8500_register_size, cuz there's no difference - between the raw & virtual sizes on this machine. - (register_convert_to_raw, register_convert_to_virtual): Delete, - cuz there's no difference between the raw & virtual forms. - Replaced by memcpy in tm file. - (register_virtual_type): Rename to h8500_register_virtual_type. - Get rid of pointer pseudo-regs, use _REGNUM with all reg names. - (_initialize_h8500_tdep): Get rid of crock to ensure that GDB & - emulator have same reg offsets. This is all handled in the - simulator code now. - (h8500_trapped_internalvar): New routine to detect references to - convenience vars acting as pointer pseudo-regs. - (h8500_value_trapped_internalvar): Conjure up value of pointer - pseudo-regs. - (h8500_set_trapped_internalvar): Convert set value in real - register references. - infcmd.c (read_pc, write_pc): Add h8500 specific code to handle - code segment register. - infrun.c (proceed): Simplify. Call write_pc instead of doing it - by hand. - (wait_for_inferior): Add h8500 specific code to add stack segment - when reading SP register. - remote-sim.c (fetch_register): Spacing. - tm-h8500.h: #define GDB_TARGET_IS_H8500 to make it easier to - detect cruft. Redo all register manipulation stuff. Get rid of - pointer pseudo-regs. (INIT_EXTRA_FRAME_INFO): Adds stack segment - to frame pointer. (IS_TRAPPED_INTERNALVAL, - VALUE_OF_TRAPPED_INTERNALVAR, SET_TRAPPED_INTERNALVAR): Use these - to create internal vars for pointer pseudo-regs. - -Thu Mar 25 10:10:28 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in: Numerous small changes to macro definitions - and rules for building gdb distribution tree. Many macros - eliminated or merged, and rules simplified. - * alldeps.mak: Update. - * depend: Update. - -Wed Mar 24 13:52:29 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com) - - * Makefile.in: recurse through SUBDIRS for dvi target too - -Wed Mar 24 08:48:30 1993 Jim Kingdon (kingdon@cygnus.com) - - * Clean up xcoff relocation. - objfiles.h (struct objfiles): Add section_offsets, num_sections. - symfile.c (syms_from_objfile), xcoffread.c (xcoff_symfile_offsets): - Set them. - symtab.h (struct general_symbol_info): Add section field. - minsyms.c (prim_record_minimal_symbol{,_and_info}): Set it. - xcoffread.c: Set section for symbols and msymbols. - (struct symtab): Add block_line_section field. - buildsym.c (end_symtab): Set it. - (end_symtab and callers): Add section parameter. - objfiles.c (objfile_relocate): New funciton. - xcoffexec.c (vmap_symtab): Use it. - xcoffsolib.h (struct vmap): Remove unused fields. - config/rs6000/tm-rs6000.h, stack.c, xcoffexec.c: Remove - CORE_NEEDS_RELOCATION, symtab_relocated. - config/rs6000/tm-rs6000.h: Remove use of loadinfotext. - rs6000-tdep.c: Make loadinfotext static. - breakpoint.c (fixup_breakpoints): Doc fix. - symtab.h (struct symtab), config/rs6000/tm-rs6000.h, buildsym.c - (end_symtab): primary field replaces nonreloc. - -Tue Mar 23 00:10:53 1993 John Gilmore (gnu@cygnus.com) - - * symtab.h (struct linetable_entry): Remove confusing comment. - -Tue Mar 23 00:01:23 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: add installcheck target - -Mon Mar 22 16:17:58 1993 Fred Fish (fnf@cygnus.com) - - * config/{a29k, arm, convex, gould, h8300, i386, i860, i960, m68k, - m88k, mips, none, ns32k, pa, pyr, romp, rs6000, sparc, tahoe, vax, - z8k}: New directories to hold cpu specific configuration files. - Naming follows gcc convention. - * config/{*.mt, *.mh}: All target and host makefile fragment - config files moved to an appropriate config/ subdirectory. - * nm-*, xm-*, tm-*: All native, host, and target files, which - get linked to nm.h, xm.h, and tm.h respectively by configure, - moved to appropriate config/ subdirectory. - * nm-sysv4.h, xm-sysv4.h, tm-sysv4.h, tm-sunos.h, nm-trash.h: - Native, host, and target files that are common across more than - one cpu architecture and included by one of the configured - native, host, or target files, get moved to config directory. - * Makefile.in (INCLUDE_CFLAGS): Add -I${srcdir}/config to - pick up native, host, or target include files moved to one of - the config subdirectories, and that are included by other files. - * Makefile.in (alldeps.mak): Modify to account for new config - directory structure. - * alldeps.mak, depend: Update for new config directory structure. - * config/*/[ntx]m-*.h: Modify all files that include other - [ntx]m-*.h files to use path relative to gdb/config. I.E. - "a29k/tm-ultra3.h" includes "a29k/tm-29k.h" rather than just - "tm-29k.h". - * remote-eb.c (tm-29k.h): Include a29k/tm-29k.h. - * mipsread.c (tm-mips.h): Include mips/tm-mips.h. - * i860-pinsn.c (tm-i860.h): Include i860/tm-i860.h. - * configure.in: Default gdb_host_cpu to host_cpu, and remap - the ones where the default is not unique or different than the - config subdirectory name. Similarly, handle gdb_target_cpu. - Modify configure.in as appropriate to make use of gdb_host_cpu - and gdb_target_cpu to find makefile fragments and make links. - -Mon Mar 22 12:36:24 1993 Ian Lance Taylor (ian@cygnus.com) - - * mipsread.c (compare_blocks): Sort blocks with the same start - address by decreasing ending address. - -Mon Mar 22 20:36:04 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (parse_procedure): Save cur_fdr accross call to - lookup_symbol as it might get clobbered by the call. - - * mipsread.c (parse_partial_symbols): Use ADD_PSYMBOL_ADDR_TO_LIST. - The previous code did not initialize the language field for the psymtab - entry. - -Sat Mar 20 00:33:39 1993 John Gilmore (gnu@cygnus.com) - - * c-exp.y (parse_number): Avoid shift warning. - * serial.h (struct ttystate): Declare empty one on DOS. - -Fri Mar 19 12:59:50 1993 Stu Grossman (grossman@cygnus.com) - - * xm-sun4os4.h: Return type of free() should be void, not int. - - * vx-share/vxWorks.h: Remove #def of NULL. - -Fri Mar 19 11:28:18 1993 Jim Kingdon (kingdon@cygnus.com) - - * tm-rs6000.h: Nuke no-op STAB_REG_TO_REGNUM. - -Fri Mar 19 07:40:09 1993 Steve Chamberlain (sac@cygnus.com) - - * z8k-tdep.c (print_insn): Include the new dis-asm header file. - -Thu Mar 18 14:26:57 1993 Per Bothner (bothner@rtl.cygnus.com) - - * ieee-float.c: Moved to ../libiberty. - * ieee-float.h: Moved to ../include. - * Makefile.in: Update accordingly. - * i386-pinsn.c (print_insn), m68k-pinsn.c (print_insn): - Convert to stubs that call disassemblers in ../opcodes/*-dis.c. - * m68k-tdep.c: Removed definition of ext_format ext_format_68881; - it is now in ../opcodes/m68881-ext.c. - * mips-tdep.c (mips_skip_prologue): Try to skip more of the - prologue (some callers _do_ care). - * mips-pinsn.c (print_insn), z8k-tdep.c (print_insn): Convert to - new interface of ../opcodes/*-dis.c. - * ch-exp.y: Add #include . - -Thu Mar 18 11:57:49 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffexec.c (exec_close): Don't close exec_bfd twice. - - * xcoffread.c (enter_line_range): endaddr is exclusive, not inclusive. - -Wed Mar 17 09:46:31 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c (arrange_linetable): Use x{m,re}alloc not {m,re}alloc. - -Wed Mar 17 11:28:11 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * z8k-tdep.c (extract_return_value, write_return_value, - store_struct_return): New functions from macros in tm-z8k.h. - -Wed Mar 17 11:23:06 1993 Fred Fish (fnf@cygnus.com) - - * valops.c (value_arg_coerce): Apply temporary patch to - fix problem with coercion of array and function types when - passed as arguments to C functions, pending a more complete - review of when and how coercion should be done, depending - upon context and language. - -Wed Mar 17 09:46:31 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c (MIN_TBTABSIZ): Change to 12. - - * xcoffread.c (xcoff_symfile_read): Only read stringtab and - debugsec if there are a non-zero number of symbols. - -Tue Mar 16 18:08:45 1993 John Gilmore (gnu@cygnus.com) - - * command.c (show_user): Avoid fprintf_filtered botch (AGAIN!). - -Tue Mar 16 15:18:17 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffexec.c (add_vmap): Wrap symbol read in catch_errors. - - * xcoffread.c (read_symbol_lineno): Look to end of symbols for .bf, - not just 50 symbols. - (symtbl_num_syms): New variable. - (read_xcoff_symtab): Set it. - (read_symbol_nvalue): Check for bad symno. - (read_symbol_{lineno,nvalue}, callers): Don't pass symtable; it's - always symtbl. - -Tue Mar 16 10:09:05 1993 Stu Grossman (grossman@cygnus.com) - - * config/rs6000.mh: Get rid of -Dfd_set=int crock. - This is defined in defs.h if necessary. - * vx-share/vxWorks.h: Remove #defs of min and max. - * vx-share/xdr_ld.c, vx-share/xdr_ptrace.c, - vx-share/xdr_rdb.c: include defs.h. - -Fri Mar 12 09:33:23 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c (retrieve_tracebackinfo): Move assignment out - of while condition. - - * xcoffread.c (enter_line_range): complain() on bad endoffset. - xcoffread.c: Doc fixes. - -Tue Mar 9 09:56:12 1993 Jim Kingdon (kingdon@cygnus.com) - - * tm-rs6000.h (CORE_NEEDS_RELOCATION): Just call xcoff_relocate_core. - xcoffexec.c (xcoff_relocate_core): New function. - (text_adjustment): Removed. - (add_vmap): Return the vmap. - rs6000-tdep.c (add_text_to_loadinfo): No longer static. - -Fri Mar 5 05:22:46 1993 Jim Kingdon (kingdon@cygnus.com) - - * xcoffsolib.h: Add objfile member to struct vmap. - xcoff{exec,solib}.c: Use it, not lookup_objfile_bfd. - xcoffexec.c (add_vmap): Allocate objfiles here. - -Sun Mar 14 02:54:15 1993 John Gilmore (gnu@cygnus.com) - - Support 68000 series without floating point. - - * configure.in (m68000-*-{aout,elf,coff}): New configs. - * tm-68k-nofp.h: New file, lacks 68881 support. - * config/m68k-nofp.mt: New file. - -Sun Mar 14 02:30:08 1993 John Gilmore (gnu@cygnus.com) - - Remove a few remaining underscore/no-underscore remnants from - config files. - - * config/{m68k-un.mt, sparc-un.mt}: Remove. - * config/m68k-noun.mt: Rename to m68k-fp.mt. - * config/sparc-noun.mt: Rename to sparc-em.mt. - * tm-68k-noun.h, tm-spc-noun.h: Remove. - * tm-68k-un.h: Rename to tm-68k-fp.h. - * tm-spc-un.h: Rename to tm-spc-em.h. - * tm-sun4sol2.h: Cleanup. - * configure.in (m68k-*, sparc-* targets): Corresponding changes. - -Sat Mar 13 14:58:22 1993 John Gilmore (gnu@cygnus.com) - - * symmisc.c (std_in, std_out, std_err): Move initializations - to runtime code, in case they aren't constant. - -Fri Mar 12 16:23:54 1993 K. Richard Pixley (rich@cygnus.com) - - * symtab.c (find_pc_symtab): some object file formats, notably - mips, have holes in the address ranges of symtabs. Change - this algorithm from first hit to tightest fit. - - * mips-tdep.c (heuristic_proc_start): if we walk the pc into the - fence post without finding the enclosing function, then print a - warning. - -Thu Mar 11 09:33:01 1993 Fred Fish (fnf@cygnus.com) - - * utils.c (fputs_demangled, fprint_symbol): Remove. - * utils.c (fprintf_symbol_filtered): New function which combines - the functionality of fputs_demangled and fprint_symbol. Uses a - caller provided language parameter to select the appropriate - demangler, and caller provided args to pass to the demangler. - * defs.h (enum language): Move further up in file so enum can - be used in prototypes. - * defs.h (fputs_demangled, fprint_symbol): Remove prototypes. - * defs.h (fprintf_symbol_filtered): Add prototype. - * c-typeprint.c (cp_type_print_method_args): Replace calls to - fputs_demangled with call to fprintf_symbol_filtered. - * cp-valprint.c (demangle.h): Include - * cp-valprint.c (cp_print_value_fields): Replace calls to - fprint_symbol with calls to fprintf_symbol_filtered. - * printcmd.c (print_frame_args): Replace call to fprint_symbol - with call to fprintf_symbol_filtered. - * stack.c (print_frame_info): Remove obsolete code so we don't - have to update fputs_demangled usage in it. - * stack.c (print_frame_info, frame_info): Add language variable - to pass to fprintf_symbol_demangled and initialize it from the - symbol's language. Replace calls to fputs_demangled with calls - to fprintf_symbol_filtered. - * symtab.c (find_methods): Replace call to fputs_demangled with - call to fprintf_symbol_filtered. - * ch-valprint.c (demangle.h): Include. - * ch-valprint.c (chill_print_value_fields): Replace call to - fprint_symbol with call to new fprintf_symbol_filtered. - -Wed Mar 10 17:37:11 1993 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump version to 4.8.2. - - * main.c (source_command): Require an explicit pathname of file - to source, since previous behavior of defaulting to gdb init file - was troublesome and undocumented. - * printcmd.c (disassemble_command): Add missing '{}' pair to - else with two statements. Bug reported by Stephane Tsacas - . - * symtab.c (find_pc_line): Don't complain about zero length or - negative length line numbers for the moment, since we may not own - the terminal when called, such as when single stepping. (FIXME) - * language.h (CAST_IS_CONVERSION): True if current language is - C++ as well as C. Fix from Peter Schauer. - * environ.c (get_in_environ, set_in_environ, unset_in_environ): - Use STREQN macro rather than bare '!strncmp()'. - * environ.c (unset_in_environ): Avoid use of memcpy on - overlapping memory regions, as suggested by Paul Eggert - . - * c-exp.y (%union struct): Remove unused ulval as suggested - by Paul Eggert . - -Mon Mar 8 19:03:06 1993 Fred Fish (fnf@cygnus.com) - - * main.c (gdbinit): Make static. - * main.c (inhibit_gdbinit): Move to file scope. - * main.c (main): Remove local inhibit_gdbinit. - * main.c (source_command): Don't source '.gdbinit' file by - default if gdb has been told to ignore it. - -Sun Mar 7 21:58:53 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (MAKEOVERRIDES): Define to be empty for GNU Make - 3.63. - -Fri Mar 5 17:39:45 1993 John Gilmore (gnu@cacophony.cygnus.com) - - * printcmd.c (print_address_symbolic): Only print if offset - is shorter than max_symbolic_offset. - (initialize_printcmd): `set print max-symbolic-offset'. - - * am29k-tdep.c (TAGWORD_ZERO_MASK): New #define. - (examine_tag): Use it. - (read_register_stack): Only look in the local registers for a - memory address if it's between rfb and rsp; go to memory otherwise. - (initialize_29k): Fix call_scratch_address doc. Remove reginv_com. - (reginv_com): Remove ancient kludge command. - -Fri Mar 5 17:16:26 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * tm-irix3.h (ZERO_REGNUM): copy this macro from tm-mips.h so that - irix4 will again compile. - - * tm-mips.h (GDB_TARGET_IS_MIPS): no longer used, now removed. - - * configure.in: accept mips-sgi-irix4* for irix4. - -Fri Mar 5 07:49:48 1993 Steve Chamberlain (sac@lisa.cygnus.com) - - * z8k-tdep.c (print_register_hook): Lint. - -Thu Mar 4 17:42:03 1993 John Gilmore (gnu@cygnus.com) - - Lint fixes from Paul Eggert (eggert@twinsun.com): - - * command.c (do_setshow_command): var_uintegers are unsigned. - * sparc-tdep.c (save_insn_opcodes, restore_insn_opcodes): - unsigned, since they use hex values with the high bit set. - -Thu Mar 4 08:22:55 1993 Fred Fish (fnf@cygnus.com) - - Fixes submitted by Karl Berry (karl@nermal.hq.ileaf.com): - * m88k-pinsn.c (sprint_address): Use SYMBOL_NAME macro to - access symbol name. - * m88k-nat-c (SXIP_OFFSET, SNIP_OFFSET, SFIP_OFFSET): Enclose - macro definitions in parenthesis. - - * dbxread.c (dbx_symfile_init): Catch the case where there is - no string table, but the only way we find out is by reading zero - bytes from EOF. - -Wed Mar 3 15:51:28 1993 Fred Fish (fnf@cygnus.com) - - * dbxread.c (dbx_symfile_init): Make size of the string table - size field a define (DBX_STRINGTAB_SIZE_SIZE). Ensure that the - offset to the string table is nonzero and handle the nonexistant - string table case, should it occur. Ensure that the string table - size read from the file is reasonable, with a minimum lower bound - of DBX_STRINGTAB_SIZE_SIZE instead of zero. - -Wed Mar 3 07:23:03 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: Changes to build testsuite correctly. - (FLAGS_TO_PASS): Added CXX and CXXFLAGS. - (CC_FOR_TARGET, CXX, CXX_FOR_TARGET): New variables. - (TARGET_FLAGS_TO_PASS): New variable. - (SUBDIRS): Added testsuite. - (all): Build testsuite using TARGET_FLAGS_TO_PASS, so that - testsuite is compiled with CC_FOR_TARGET rather than CC. - -Tue Mar 2 17:57:56 1993 Fred Fish (fnf@cygnus.com) - - * dbxread.c (dbx_symfile_init): Fix for nonexistant string table, - reported by mycroft@gnu.ai.mit.edu. - - (Ultrix 2.2 support from Michael Rendell ) - * configure.in (vax-*-ultrix2*): New triplet. - * config/vaxult2.mh: New file. - * xm-vaxult2.h: New file. - - * c-exp.y (parse_number): Change high_bit to unsigned. - * demangle.c: Change all references to cfront to ARM, since the - actual algorithm is the one specified in the Annotated Reference - Manual. This was confusing users into thinking that full cfront - support was implemented. - * dwarfread.c (CFRONT_PRODUCER): Remove, was never really used. - * eval.c (evaluate_subexp): For STRUCTOP_PTR pass the arg type - directly to lookup_struct_elt_type, which will do the - dereferencing itself. - * gdbtypes.c (lookup_struct_elt_type): Expand comments. Fix - NULL dereferencing bug for unnamed structs, comment out - questionable code. - -Mon Mar 1 17:54:41 1993 John Gilmore (gnu@cygnus.com) - - * coffread.c (process_coff_symbol): Change PCC argument correction - so that it only happens on big-endian targets; so that it only - happens if the short or char argument is aligned on an int - boundary; and so that it changes the location, rather than the - type, of the argument. These changes tend to parallel similar - (old) changes in stabsread.c. - - * coffread.c (coff_read_enum_type): Use the specified size for - enums, don't assume that they are int-sized. - - * c-valprint.c (c_val_print): Don't assume enums are the same as - ints. - - * coredep.c: Handle NO_PTRACE_H in coredep.c. Fix by Michael - Rendell, . - -Mon Mar 1 09:25:57 1993 Fred Fish (fnf@cygnus.com) - - * language.h (local_decimal_format_custom): Add prototype. - * language.c (local_decimal_format_custom): Add function, bug - reported by Robert R. Henry (rrh@tera.com). - -Fri Feb 26 18:33:18 1993 John Gilmore (gnu@cacophony.cygnus.com) - - * xcoffexec.c (vmap_ldinfo): Fix "/" for '/' typo, reported - by Josef Leherbauer, joe@takeFive.co.at. - -Wed Feb 24 19:17:11 1993 John Gilmore (gnu@cacophony.cygnus.com) - - * symfile.c (syms_from_objfile), tm-29k.h, tm-3b1.h, tm-68k-un.h, - tm-altos.h, tm-arm.h, tm-convex.h, tm-es1800.h, tm-h8300.h, - tm-hp300bsd.h, tm-hp300hpux.h, tm-hppa.h, tm-i386bsd.h, - tm-i386v.h, tm-i960.h, tm-irix3.h, tm-isi.h, tm-linux.h, - tm-m88k.h, tm-merlin.h, tm-mips.h, tm-news.h, tm-np1.h, tm-pn.h, - tm-pyr.h, tm-rs6000.h, tm-spc-un.h, tm-sun386.h, tm-sunos.h, - tm-symmetry.h, tm-sysv4.h, tm-tahoe.h, tm-umax.h, tm-vax.h, - tm-vx68.h, tm-z8k.h: Remove remnants of NAMES_HAVE_UNDERSCORE. - -Wed Feb 24 07:41:15 1993 Fred Fish (fnf@cygnus.com) - - * symtab.h (SYMBOL_INIT_DEMANGLED_NAME): Initialize contents - of demangled name fields to NULL if no demangling exists for - a symbol. SYMBOL_INIT_LANGUAGE_SPECIFIC does this for new - symbols if their language is known at the time they are created, - but sometimes the language is not known until later. - - * ch-typeprint.c (chill_print_type_base): Name changed to - chill_type_print_base to match pattern for C and C++ names. - * ch-typeprint.c (chill_print_type): Change "char" to "CHAR" - to be consistent with other usages. - * ch-typeprint.c (chill_type_print_base): Add support for - printing Chill STRUCT types. - * ch-valprint.c: Include values.h. - * ch-valprint.c (chill_print_value_fields): New function and - prototype for printing Chill STRUCT values. - * ch-valprint.c (chill_val_print): Fix call to val_print_string - that was being called with two args instead of three. - * ch-valprint.c (chill_val_print): Call chill_print_value_fields - to print Chill STRUCT values. - -Tue Feb 23 18:58:11 1993 Mike Werner (mtw@poseidon.cygnus.com) - - * configure.in: added testsuite to configdirs. - -Tue Feb 23 11:46:11 1993 Mike Stump (mrs@cygnus.com) - - * doc/stabs.texi: The `this' pointer is now known by the name - `this' instead of `$t'. - -Tue Feb 23 11:21:33 1993 Fred Fish (fnf@cygnus.com) - - * dwarfread.c (read_tag_string_type): Rewrite to allow forward - references of TAG_string_type DIEs in user defined types. - * ch-lang.c (chill_create_fundamental_type): Track compiler - change that now emits debugging info with the type long for Chill - longs. - -Mon Feb 22 15:21:54 1993 Ian Lance Taylor (ian@cygnus.com) - - * remote-mips.c: New file; implements MIPS remote debugging - protocol. - * config/idt.mt: New file; uses remote-mips.c - * configure.in (mips-idt-ecoff): New target; uses idt.mt. - - * mips-tdep.c (mips_fpu): New variable; controls use of MIPS - floating point coprocessor. - (mips_push_dummy_frame): If not mips_fpu, don't save floating - point registers. - (mips_pop_frame): If not mips_fpu, don't restore floating point - registers. - (_initialize_mips_tdep): New function; let the user reset mips_fpu - variable. - * tm-mips.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): If not - mips_fpu, don't use fp0 as floating point return register. - (FIX_CALL_DUMMY): If not mips_fpu, don't save floating point - registers. - -Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com) - - * gdb/testsuite: made modifications to testcases, etc., to allow - them to work properly given the reorganization of deja-gnu and the - relocation of the testcases from deja-gnu to a "tool" subdirectory. - -Sun Feb 21 10:55:55 1993 Mike Werner (mtw@poseidon.cygnus.com) - - * gdb/testsuite: Initial creation of gdb/testsuite. - Migrated dejagnu testcases and support files for testing nm to - gdb/testsuite from deja-gnu. These files were moved "as is" - with no modifications. This migration is part of a major overhaul - of dejagnu. The modifications to these testcases, etc., which - will allow them to work with the new version of dejagnu will be - made in a future update. - -Fri Feb 19 18:36:55 1993 John Gilmore (gnu@cygnus.com) - - * NEWS: Add reminders for next release. - -Fri Feb 19 10:01:39 1993 Ian Lance Taylor (ian@cygnus.com) - - * mipsread.c (parse_lines): Correct check for files compiled with - -g1. - -Fri Feb 19 05:56:15 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (VERSION): 4.8.1 to distinguish local versions. - -Fri Feb 19 01:32:58 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (VERSION): GDB-4.8 release! - * README, NEWS: Update for release. - -Thu Feb 18 22:44:40 1993 Stu Grossman (grossman@cygnus.com) - - * am29k-pinsn.c (print_insn): Minor nits with const. - * am29k-tdep.c: More minor nits with arg types for - supply_register, NULL vs. 0, read_register_gen, & reginv_com. - -Thu Feb 18 22:38:03 1993 John Gilmore (gnu@cygnus.com) - - * gcc.patch: Update for a different GCC (G++) bug. - * main.c (print_gdb_version): Update copyright year to 1993. - * nm-hp300bsd.h: Decide whether this is BSD 4.3 or 4.4, - conditionalize this file on it. FIXME, right way is to split - these into two config files. - (ATTACH_DETACH): Define for BSD 4.4 - (PTRACE_ARG_TYPE): caddr_t for BSD 4.4, unset for 4.3. - (U_REGS_OFFSET): Revise for 4.4. - (REGISTER_U_ADDR): Separate for 4.4, but it doesn't work yet. - * xm-hp300bsd.h: Move definitions of UINT_MAX, INT_MAX, INT_MIN, - LONG_MAX into this file to avoid cpp "redefinition" warnings. - -Thu Feb 18 16:13:28 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * nm-hp300bsd.h (PTRACE_ARG3_TYPE): FSF's hp300's have int* not - caddr_t. - -Thu Feb 18 04:10:06 1993 John Gilmore (gnu@cygnus.com) - - * c-lang.c (c_printstr): Bugfix for length==0 case. - - * c-lang.c (c_printstr): If a C string ends in a null, don't - print the null. - -Thu Feb 18 02:39:21 1993 Stu Grossman (grossman at cygnus.com) - - * defs.h (STRCMP): Make it work for unsigned chars. - -Thu Feb 18 01:56:06 1993 John Gilmore (gnu@cygnus.com) - - * nm-hp300bsd.h (ATTACH_DETACH, PTRACE_ATTACH, PTRACE_DETACH): define. - * config/hp300bsd.mh (REGEX, REGEX1): Define. - * m68k-pinsn.c (BREAK_UP_BIG_DECL, AND_OTHER_PART): #if __GNUC__, - define to kludge the large opcode table into two smaller tables, - since GCC take exponential space to build the table. Lint. - (NOPCODES): Remove, use "numopcodes" from opcode/m68k.h instead. - -Wed Feb 17 19:24:40 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (VERSION): Roll to 4.7.9. - * xm-hp300bsd.h: Define PSIGNAL_IN_SIGNAL_H and put a compatible - definition here, to handle both BSD 4.3 and 4.4 systems. - * mipsread.c (ZMAGIC): #undef to avoid duplicate define. - * remote.c (alarm): Move declaration to global level, before - first reference to it. - * tm-i386bsd.h (NUM_REGS): There are only eleven, not twelve. - * dbxread.c (process_one_symbol): Cast to unsigned char, not int. - -Wed Feb 17 13:40:29 1993 K. Richard Pixley (rich@cygnus.com) - - * remote.c (readchar): forward declare alarm which otherwise looks - like an undeclared variable to gcc. - - * dbxread.c (process_one_symbol): cast enum value N_SO into int - when comparing against an int. Avoids superfluous warning from - vax ultrix 4.2 cc. - - * inflow.c (set_sigint_trap): add cast to assignment from signal. - Avoids superfluous warnings from some systems and/or compilers - (like vax ultrix 4.2.) - - * language.c (struct op_print unk_op_print_tab): use the enum - values rather naked zeros as initializers. Avoids warnings from - ultrix type compilers. - -Tue Feb 16 00:53:20 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (VERSION): Roll to 4.7.6. - (SFILES_SUBDIR): Add 29k-share/udi_soc. - (SFILES_SUBSUBDIR): Move 29k-share/udi files to this macro. - (alldeps.mak): Make ALLDEPFILES_SUBSUBDIR for files in sub sub dirs. - (ALLDEPFILES_SUBSUBDIR): Depend on this for deeper dep files. - (HFILES): Remove all nm-* except nm-trash.h. Add ns32k-opcode.h. - (depend): Fix bug where nm-files in config files weren't noticed. - (make-proto-gdb-1): Avoid changing directories while building new - prototype. Build SFILES_SUBSUBDIR with longer symlinks. - -Mon Feb 15 20:48:09 1993 John Gilmore (gnu@cygnus.com) - - * remote.c: Improve error recovery. Allow user to break out - of initial connection attempt with INTERRUPT. Treat a timeout - while waiting for remote packet like a retry, unless the remote - side is actively running user code. Fix a few long printf_filtered's. - - * xcoffread.c (read_xcoff_symtab): Don't use null symbol name for - trampoline symbols. - - * buildsym.c (start_subfile): Allow null file name. - -Fri Feb 12 15:46:49 1993 K. Richard Pixley (rich@cygnus.com) - - * xcoffread.c (process_xcoff_symbol, read_symbol_lineno): complain - expects a pointer to complaint rather than a complaint - structure. - (process_linenos): free the previously allocated subfile name, - then allocate the new one from the heap. - -Fri Feb 12 08:06:05 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * h8300-tdep.c, tm-h8300.h: turn off some experimental features - -Thu Feb 11 00:59:07 1993 John Gilmore (gnu@cygnus.com) - - * stabsread.c (dbx_lookup_type): Handle negative type numbers. - Previously, would bogusly index off the bottom of type_vector. - (rs6000_builtin_type): Accept type number as argument. - (read_type, case '-'): Handle negatives like any other type number. - - * symfile.c (deduce_language_from_filename): Handle null name. - - * mips-tdep.c (isa_NAN): Fix byte order dependency. - Reported by Nobuyuki Hikichi , - fixed by sato@sm.sony.co.jp. - - * xcoffread.c (parmsym): Don't use an initializer to set up - this struct symbol. Set it up in initialize_xcoffread. - (read_xcoff_symtab, xcoff_symfile_read): Surround code that only - works on real rs/6000 target with #ifndef FAKING_RS6000. - -Wed Feb 10 23:42:37 1993 John Gilmore (gnu@cygnus.com) - - * stabsread.c (rs6000_builtin_type): Move function from - xcoffread.c:builtin_type. - * xcoffread.c (builtin_type): Move to stabsread. Remove - IBM6000_HOST dependency. Move misplaced comments. - (various): Change printf's to complaints. - (patch_block_stabs, process_xcoff_symbol case C_DECL): Add - objfile argument to read_type calls under #if 0. - (process_xcoff_symbol case C_RSYM): Fix typo in #ifdef. - * xcoffexec.c (map_vmap): Don't allocate an objfile for the exec_file. - * Makefile.in: xcoffread.o is not built by default. - * xm-rs6000.h (IBM6000_HOST): Remove. - * config/rs6000.mh (NATDEPFILES): xcoffread.o is native only. - * doc/gdbint.texinfo: Eliminate IBM6000_HOST, document - IBM6000_TARGET. - -Wed Feb 10 18:31:20 1993 Stu Grossman (grossman at cygnus.com) - - * findvar.c (read_var_value): If REG_STRUCT_HAS_ADDR, then set - VALUE_LVAL to be lval_memory so that we don't try to modify wild - register numbers when user tries to modify elements in structs - passed as arguments. - * inflow.c (child_terminal_info): Move banner outside of system - specific #ifdefs. - * tm-hppa.h (REG_STRUCT_HAS_ADDR): Define this for HPPA, which - passes struct/union arguments by address. - -Wed Feb 10 15:34:46 1993 Ian Lance Taylor (ian@cygnus.com) - - * Based on patch from Kean Johnston : - * nm-i386sco4.h: New file. Like nm-i386sco.h, but define - ATTACH_DETACH, PTRACE_ATTACH and PTRACE_DETACH. - * config/i386sco4.mh (NAT_FILE): Use nm-i386sco4.h. - -Tue Feb 9 20:07:18 1993 John Gilmore (gnu@cygnus.com) - - * remote-udi.c (FREEZE_MODE): Fix && for & typo. Found and - fixed by Lynn D. Shumaker, shumaker@saifr00.cfsat.honeywell.com. - -Tue Feb 9 08:18:07 1993 Ian Lance Taylor (ian@cygnus.com) - - * config/i386sco4.mh (MUNCH_DEFINE): Pass -p to nm to avoid bug in - cc debugging output. - -Tue Feb 9 00:19:28 1993 John Gilmore (gnu@cygnus.com) - - * stabsread.c (define_symbol): Complain about unrecognized names - that begin with CPLUS_MARKER (often '$'), but don't die. Fix - suggested by gb@cs.purdue.edu (Gerald Baumgartner). - (read_cpp_abbrev): Don't use the class name as part of the - vtable pointer member name (_vptr$) in $vf abbrevs or unrecognized - abbrevs. Inspired by Mike Tiemann. - (read_tilde_fields): Comment. Remove ancient dead code. - Remove erroneous but non-dead code. Simplify. Add complaints. - (in general): Remove extraneous (parentheses) in return - statements. - -Fri Feb 5 14:01:22 1993 John Gilmore (gnu@cygnus.com) - - * coffread.c (coff_lookup_type): Fix fencepost error reported - by Art Berggreen, . - - Fix long file name bug reported on SCO Open Desktop 2.0 by Ulf Lunde - and Dag H. Wanvik : - - * coffread.c (getfilename): Eliminate COFF_NO_LONG_FILE_NAMES - test, which is apparently left over from when we used native - include files and couldn't depend on the member names being there. - * tm-3b1.h, tm-altos.h, tm-i386v.h: Don't set it. - -Thu Feb 4 12:23:15 1993 Ian Lance Taylor (ian@cygnus.com) - - * mipsread.c: Major overhaul to use new BFD symbol table reading - routines. Now swaps information as it is needed, rather than - swapping everything when the file is read. - -Thu Feb 4 01:52:36 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (TARDIRS): Add sparclite demo dir. - (*.tab.c): Change dependency on Makefile to depend on - Makefile.in, otherwise it always rebuilds after configuring. - Force output *.tab.c file into current directory even in "make" - versions that rewrite dependent file names used in command lines. - - * TODO: Remove some things we did. - * am29k-opcode.h, convx-opcode: Remove; now in ../include/opcode. - * os68k-xdep.c: Remove; useless file (os68k is a target only). - * convex-pinsn.c: Use ../include/opcode/convex.h. Add CONST. - * symtab.h: Eliminate unnamed unions and structs. - -Wed Feb 3 14:48:08 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in (VERSION): Roll to 4.7.5. - -Tue Feb 2 20:47:42 1993 John Gilmore (gnu@cygnus.com) - - * breakpoint.c (breakpoint_re_set_one): Handle watchpoints when - re-evaluating symbol pointers. - -Tue Feb 2 16:10:31 1993 Fred Fish (fnf@cygnus.com) - - * c-exp.y (lcurly, rcurly): New nonterminals. - * c-exp.y (exp): Use lcurly and rcurly for arrays and UNOP_MEMVAL - constructs. - * parse.c (free_funcalls): Moved prototype from parser-defs.h, - made function static. - * parse.c (struct funcall): Moved struct def from parser-defs.h. - * parse.c (funcall_chain): Moved from parser-defs.h, made static. - * parse.c (start_arglist): - * parser-defs.h (free_funcalls): Moved prototype to parse.c. - * parser-defs.h (struct funcall): Moved struct def to parse.c. - * parser-defs.h (funcall_chain): Moved to parse.c. - * printcmd.c (print_frame_nameless_args): Fix prototype. - * tm-mips.h (setup_arbitrary_frame): Fix prototype. - * tm-sparc.h (setup_arbitrary_frame): Fix prototype. - * valops.c (typecmp): Moved prototype from values.h. - * value.h (typecmp): Moved prototype to valops.c, made static. - * ch-exp.y (yylex): Change way control sequences are disabled. - -Tue Feb 2 16:11:43 1993 John Gilmore (gnu@cygnus.com) - - * tm-mips.h, tm-sparc.h: Fix thinko in SETUP_ARBITRARY_FRAME. - -Tue Feb 2 15:30:33 1993 Ian Lance Taylor (ian@cygnus.com) - - * mipsread.c (upgrade_type): Build array types correctly, using - create_range_type and create_array_type. - -Tue Feb 2 00:19:08 1993 John Gilmore (gnu@cygnus.com) - - * remote-nindy.c: Cleanup. - - * infrun.c (wait_for_inferior): When rolling back the PC after - a breakpoint, call write_pc so that NPC gets rolled back as well - (for the 29K). - - * blockframe.c (inside_entry_file, inside_main_func, - inside_entry_func): PC of zero is always "bottom of stack". - - * printcmd.c (print_frame_args, print_frame_nameless_args): - Let print_frame_nameless_args decide whether there are any, - laying groundwork for possibly later printing 29K args for - functions where we have tag words but no symbols. - -Mon Feb 1 18:09:58 1993 Roland H. Pesch (pesch@fowanton.cygnus.com) - - * Makefile.in: fix GDB doc targets for new doc subdir structure - -Mon Feb 1 17:56:47 1993 John Gilmore (gnu@cygnus.com) - - * stack.c (parse_frame_specification): Parse as many arguments - as there are (up to MAXARGS). Pass all of them in argc, argv - format to SETUP_ARBITRARY_FRAME. Put the burden of checking how - many there were, onto SETUP_ARBITRARY_FRAME. - * tm-mips.h, tm-sparc.h: Corresponding changes. - * mips-tdep.c, sparc-tdep.c: Ditto. - -Mon Feb 1 17:19:37 1993 John Gilmore (gnu@cygnus.com) - - * hp300ux-nat.c: Update copyrights. - * mipsread.c (parse_partial_symbols): Complain about block - indexes that go backwards. Fix from Peter Schauer. - * symfile.c (syms_from_objfile, symbol_file_add): Allow a - symbol-file that has no linkage symbols to be read. - * tm-rs6000.h, xm-rs6000.h: (SIGWINCH_HANDLER and friends): Move - from tm- file to xm-file, since they're host dependent. - * valarith.c (value_binop): Typo. - -Mon Feb 1 16:16:59 1993 Stu Grossman (grossman at cygnus.com) - - * sparclite/aload.c: Add copyleft. - * sparclite/crt0.s: Add comment at beginning. - -Mon Feb 1 14:36:11 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * remote-z8k.c, z8k-tdep.c: support for the Z8001 and Z8002. - * parse.c (std_regs): Only declare if NO_STD_REGS is defined. - -Sun Jan 31 04:32:48 1993 Michael Tiemann (tiemann@rtl.cygnus.com) - - * values.c (value_headof): Fix typo in which VTBL and ARG were - being confused for one another. - - * valops.c (typecmp): Now static. - - * gdbtypes.c (fill_in_vptr_fieldno): Don't ignore the first - baseclass--we don't always inherit its virtual function table - pointer. - - * eval.c (evaluate_subexp): In OP_FUNCALL case, adjust `this' - pointer correctly in case value_struct_elt moves it around. - - * valops.c (typecmp): Now static. Also, now groks references - better. - - * gdbtypes.c (lookup_struct_elt_type): Pass NOERR instead of - zero on recursive call. If NAME is the name of TYPE, return TYPE. - -Sat Jan 30 19:55:52 1993 John Gilmore (gnu@cygnus.com) - - * hppah-nat.c: Eliminate and other unnecessary stuff, - to avoid "too much defining" error from native C compiler (!). - - * Makefile.in (HFILES): Add typeprint.h. - * typeprint.[ch]: Update copyrights. - -Thu Jan 28 19:09:02 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in: Update to match doc/ subdir changes. - - * config/hp300hpux.mh: No cross-host file needed, just native. - * config/go32.mh: Remove nonexistent "native" support. - - M88K fixes reported by Carl Greco, : - * tm-m88k.h (REGISTER_CONVERT_TO_RAW): Fix typo. - * m88k-tdep.c (next_insn): Lint, cleanup. - (store_parm_word): Lint. - - * README: Fix typo (reported by karl@hq.ileaf.com). - -Wed Jan 27 21:34:21 1993 Fred Fish (fnf@cygnus.com) - - * expression.h (BINOP_CONCAT): Document use for self concatenation - an integral number of times. - * language.c (binop_type_check): Extend BINOP_CONCAT for self - concatenation case. - * valarith.c (value_concat): Rewrite to support self - concatenation an integral number of times. - * Makefile.in (ch-exp.tab.c): Change "expect" message. - * ch-exp.y (FIXME's): Make all FIXME tokens distinct, to - eliminate hundreds of spurious shift/reduce and reduce/reduce - conflicts that mask the 5 real ones. - * ch-exp.y (STRING, CONSTANT, SC): Remove unused tokens. - * ch-exp.y (integer_literal_expression): Remove production, - no longer used. - -Thu Jan 21 09:58:36 1993 Fred Fish (fnf@cygnus.com) - - * eval.c (evaluate_subexp): Fix OP_ARRAY, remove code that - implied that "no side effects" was nonfunctional. - * eval.c (evaluate_subexp): Add BINOP_CONCAT case to deal with - character string and bitstring concatenation. - * expprint.c (dump_expression): Add case for BINOP_CONCAT. - * expression.h (exp_opcode): Add BINOP_CONCAT. - * gdbtypes.h (type_code): Add TYPE_CODE_BITSTRING. - * language.c (string_type): Add function to determine if a type - is a string type. - * language.c (binop_type_check): Add case for BINOP_CONCAT. - * valarith.c (value_concat): New function to concatenate two - values, such as character strings or bitstrings. - * valops.c (value_string): Remove error stub and implement - function body. - * value.h (value_concat): Add prototype. - * ch-exp.y (operand_3): Add actions for SLASH_SLASH (//). - * ch-exp.y (yylex): Recognize SLASH_SLASH. - * ch-lang.c (chill_op_print_tab): Add SLASH_SLASH (//) as - BINOP_CONCAT. - -Tue Jan 19 14:26:15 1993 Fred Fish (fnf@cygnus.com) - - * c-exp.y (exp): Add production to support direct creation - of array constants using the obvious syntax. - * c-valprint.c (c_val_print): Set printed string length. - * dwarfread.c (read_tag_string_type): New prototype and - function that handles TAG_string_type DIEs. - * dwarfread.c (process_dies): Add case for TAG_string_type - that calls new read_tag_string_type function. - * expprint.c (print_subexp): Add support for OP_ARRAY. - * gdbtypes.c (create_range_type, create_array_type): Inherit - objfile from the index type. - * ch-typeprint.c (chill_print_type): Add case for - TYPE_CODE_STRING. - * ch-valprint.c (chill_val_print): Fix case for - TYPE_CODE_STRING. - -Mon Jan 18 11:58:45 1993 Ian Lance Taylor (ian@cygnus.com) - - * mipsread.c (CODE_MASK, MIPS_IS_STAB, MIPS_MARK_STAB, - MIPS_UNMARK_STAB, STABS_SYMBOLS): Removed; now in - include/coff/mips.h. - -Fri Jan 15 20:26:50 1993 Fred Fish (fnf@cygnus.com) - - * c-exp.y (exp:STRING): Convert C strings into array-of-char - constants with an explicit null byte terminator. OP_STRING is - now used for real string types. - * c-lang.c (builtin_type_*): Move declarations to lang.c since - they are used by all languages. - * c-lang.c (_initialize_c_language): Move initializations of - builtin_type_* to lang.c. - * c-typeprint.c (c_type_print_varspec_prefix, - c_type_print_varspec_suffix): TYPE_CODE_PASCAL_ARRAY renamed - to TYPE_CODE_STRING. - * c-valprint.c (c_val_print): Change the way character arrays - are printed as strings to be consistent with the way strings - are printed when pointer-to-char types are dereferenced. - Remove test of print_max before calling val_print_string, which - now does it's own test. - * eval.c (evaluate_subexp): Add case for OP_ARRAY. - * expprint.c (print_subexp, dump_expression): Add case for OP_ARRAY. - * expression.h (enum exp_opcode): Add OP_ARRAY and document. - * gdbtypes.c (builtin_type_*): Add declarations moved from - c-lang.c. - * gdbtypes.c (create_string_type): New function to create real - string types. - * gdbtypes.c (recursive_dump_type): TYPE_CODE_PASCAL_ARRAY - renamed to TYPE_CODE_STRING. - * gdbtypes.c (_initialize_gdbtypes): Add initializations of - builtin_type_* types moved from c-lang.c. - * gdbtypes.h (enum type_code): TYPE_CODE_PASCAL_ARRAY renamed - to TYPE_CODE_STRING. - * gdbtypes.h (builtin_type_string): Add extern declaration. - * gdbtypes.h (create_string_type): Add prototype. - * m2-lang.c (m2_create_fundamental_type): TYPE_CODE_PASCAL_ARRAY - renamed to TYPE_CODE_STRING. - * m88k-tdep.c (pushed_size): TYPE_CODE_PASCAL_ARRAY renamed to - TYPE_CODE_STRING. - * mipsread.c (_initialize_mipsread): TYPE_CODE_PASCAL_ARRAY - renamed to TYPE_CODE_STRING. - * parse.c (length_of_subexp, prefixify_subexp): Add case for - OP_ARRAY. - * printcmd.c (print_formatted): Recognize TYPE_CODE_STRING. - * typeprint.c (print_type_scalar): TYPE_CODE_PASCAL_ARRAY renamed - to TYPE_CODE_STRING. - * valops.c (allocate_space_in_inferior): New function and - prototype, using code ripped out of value_string. - * valops.c (value_string): Rewritten to use new function - allocate_space_in_inferior, but temporarily disabled until some - other support is in place. - * valops.c (value_array): New function to create array constants. - * valprint.c (val_print_string): Add comment to document use, - complete rewrite to fix several small buglets. - * value.h (value_array): Add prototype. - * value.h (val_print_string): Change prototype to match rewrite. - * ch-valprint.c (chill_val_print): Add case for TYPE_CODE_STRING. - * ch-exp.y (match_character_literal): Disable recognition of - control sequence form of character literals and document why. - -Thu Jan 14 15:48:12 1993 Stu Grossman (grossman at cygnus.com) - - * nindy-share/nindy.c: Add comments to #endif's to clarify - grouping. - - * hppa-pinsn.c (print_insn): Use read_memory_integer, instead of - read_memory to get byte order right. - * hppah-tdep.c (find_unwind_info): Don't read in unwind info - anymore. This is done in paread.c now. We expect unwind info - to hang off of objfiles, and search all of the objfiles when until - we find a match. - * (skip_trampoline_code): Cast arg to target_read_memory. - * objfiles.h (struct objfile): Add new field obj_private to hold - per object file private data (unwind info in this case). - * paread.c (read_unwind_info): New routine to read unwind info - for the objfile. This data is hung off of obj_private. - * tm-hppa.h: Define struct obj_unwind_info, to hold pointers to - the unwind info for this objfile. Also define OBJ_UNWIND_INFO to - make this easier to access. - -Wed Jan 13 20:49:59 1993 Fred Fish (fnf@cygnus.com) - - * c-valprint.c (cp_print_class_member): Add extern decl. - * c-valprint.c (c_val_print): Extract code for printing methods - and move it to cp_print_class_method in cp-valprint.c. - * c-valprint.c (c_val_print): Extract code to print strings and - move it to val_print_string in valprint.c. - * cp-valprint.c (cp_print_class_method): New function using - code extracted from c_val_print. - * valprint.c (val_print_string): New function using code - extracted from c_val_print. - * value.h (val_print_string): Add prototype. - * ch-exp.y (CHARACTER_STRING_LITERAL): Set correct token type. - * ch-exp.y (literal): Add action for CHARACTER_STRING_LITERAL. - * ch-exp.y (tempbuf, tempbufsize, tempbufindex, GROWBY_MIN_SIZE, - CHECKBUF, growbuf_by_size): New variables, macros, and support - functions for implementing a dynamically expandable temp buffer. - * ch-exp.y (match_string_literal): New lexer function. - * ch-exp.y (match_bitstring_literal): Dynamic buffer code - removed and replaced with new CHECKBUF macro. - * ch-exp.y (yylex): Call match_string_literal when appropriate. - * ch-valprint.c (ch_val_print): Add code for TYPE_CODE_PTR. - -Sat Jan 9 19:59:33 1993 Stu Grossman (grossman at cygnus.com) - - * Makefile.in: Add info for paread.o. - * config/hppahpux.mh: Add paread.o to NATDEPFILES. - - * blockframe.c (frameless_look_for_prologue): Correct the - comment. - * gdbtypes.h, gdbtypes.c: Use const in decl of - cplus_struct_default, now that pa-gas assembler has been fixed. - * hppah-nat.c: Formatting. - * hppah-tdep.c: Remove lots of useless externs for variables we - don't use. - * (find_unwind_entry): Speed up by using binary search, and a one - entry cache. - * (rp_saved): New routine to see what unwind info says about RP - being saved on the stack frame. - * (frame_saved_pc): Look for prologue to see if we need to - examine the stack for the saved RP or not. - * (init_extra_frame_info): Check for prologue, instead of - framesize to determine if we are frameless or not. - * (frame_chain_valid): Stop backtraces when we run into _start. - * (push_dummy_frame): Reformat to make more readable. - * (find_dummy_frame_regs): ditto. - * (hp_pop_frame): ditto. - * (hp_restore_pc_queue): small cleanup. - * (hp_push_arguments): ditto. - * (pa_do_registers_info): ditto. - * (skip_prologue): New routine created from SKIP_PROLOGUE macro. - * tm-hppa.h: Move contents of SKIP_PROLOGUE into hppah-tdep.c. - * Define FRAME_CHAIN_VALID. - * Turn on BELIEVE_PCC_PROMOTION so that we can access char args - passed to functions. - - * paread.c (pa_symtab_read): Use new bfd conventions for - accessing linker symbol table. - * (pa_symfile_init): Access embedded STAB info via BFD section - mechanism and related macros. - - -Sat Jan 9 19:31:43 1993 Stu Grossman (grossman at cygnus.com) - - * sparc-stub.c: Use a seperate stack for our traps. - * Handle recursive traps. - * Remove all trap init code. This needs to be done by the - environment. - * (set_mem_fault_trap): Call exceptionHandler() to setup this - trap. - * (handle_exception): See if we are at breakinst, if so, then - advance PC sp that users can just step out of breakpoint(). - * (case 'G'): Don't let GDB hack CWP. Also, copy saved regs to - new place if SP has changed. - * (case 's'): Get rid of this, we can't do it yet. - * (case 't'): New command to test any old random feature. - * (case 'r'): New command to reset the system. - * (breakpoint): Add label to breakpoint trap instruction so that - handle_exception() can detect where we are and get past the - breakpoint trivially. - -Thu Jan 7 13:33:06 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips-pinsn.c: Actual work now done by opcodes/mips-dis.c. - -Thu Jan 7 09:21:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: recognise all sparclite variants - -Wed Jan 6 10:14:51 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * symfile.c: If O_BINARY isn't defined, set it to 0, call openp for - binary files oring in the right bit. - - * main.c, source.c, state.c, symmisc.c: use macros defined in - fopen-{bin|both} when fopening files. - -Wed Jan 6 08:19:11 1993 Fred Fish (fnf@cygnus.com) - - * defs.h (HOST_CHAR_BIT): New macro, defaults to either CHAR_BIT - from a configuration file (typically including ), or to - TARGET_CHAR_BIT if CHAR_BIT is not defined. - * eval.c (evaluate_subexp): Use new BYTES_TO_EXP_ELEM macro. - * eval.c (evaluate_subexp): Add case for OP_BITSTRING. - * expprint.c (print_subexp): Use new BYTES_TO_EXP_ELEM macro. - * exppritn.c (print_subexp, dump_expression): Add case for - OP_BITSTRING. - * expression.h (OP_BITSTRING): New expression element type for - packed bitstrings. - * expression.h (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): New - macros to convert between number of expression elements and bytes - to store that many elements. - * i960-tdep.c (leafproc_return): Use new macros to access - minimal symbol name and address fields. - * m88k-pinsn.c (sprint_address): Use new macros to access - minimal symbol name and address fields. - * nindy-tdep.c (nindy_frame_chain_valid): Use new macro to access - minimal symbol address field. - * parse.c (write_exp_elt, write_exp_string, prefixify_expression, - parse_exp_1): Use new EXP_ELEM_TO_BYTES macro. - * parse.c (write_exp_string, length_of_subexp, prefixify_expression): - Use new BYTES_TO_EXP_ELEM macro. - * parse.c (write_exp_bitstring): New function to write packed - bitstrings into the expression element vector. - * parse.c (length_of_subexp, prefixify_subexp): Add case for - OP_BITSTRING. - * parser-defs.h (struct stoken): Document that it is used for - OP_BITSTRING as well as OP_STRING. - * parser-defs.h (write_exp_bitstring): Add prototype. - * ch-exp.y (BIT_STRING_LITERAL): Change token type to sval. - * ch-exp.y (NUM, PRED, SUCC, ABS, CARD, MAX, MIN, SIZE, UPPER, - LOWER, LENGTH): New tokens for keywords. - * ch-exp.y (chill_value_built_in_routine_call, mode_argument, - upper_lower_argument, length_argument, array_mode_name, - string_mode_name, variant_structure_mode_name): New non-terminals - and productions. - * ch-exp.y (literal): Useful production for BIT_STRING_LITERAL. - * ch-exp.y (match_bitstring_literal): New lexer support function - to recognize bitstring literals. - * ch-exp.y (tokentab6): New token table for 6 character keywords. - * ch-exp.y (tokentab5): Add LOWER, UPPER. - * ch-exp.y (tokentab4): Add PRED, SUCC, CARD, SIZE. - * ch-exp.y (tokentab3): Add NUM, ABS, MIN, MAX. - * ch-exp.y (yylex): Check tokentab6. - * ch-exp.y (yylex): Call match_bitstring_literal. - -Mon Jan 4 16:54:18 1993 Fred Fish (fnf@cygnus.com) - - * xcoffexec.c (vmap_symtab): Use new macros to access minimal - symbol name and value fields. - - * c-exp.y (yylex): Make static, to match prototype and other - -exp.y files. - - * expression.h (exp_opcode): Add BINOP_MOD. - * eval.c (evaluate_subexp): Handle new BINOP_MOD. - * expprint.c (dump_expression): Handle new BINOP_MOD. - * language.c (binop_type_check): Handle new BINOP_MOD. - * main.c (float_handler): Re-enable float handler when hit. - * valarith.c (language.h): Include, need current_language. - * valarith.c (TRUNCATION_TOWARDS_ZERO): Define default macro - for integer divide truncates towards zero for negative results. - * valarith.c (value_x_binop): Handle BINOP_MOD if seen. - * valarith.c (value_binop): Allow arithmetic operations on - TYPE_CODE_CHAR variables. Add case to handle new BINOP_MOD. - * ch-exp.y (operand_4): Add useful actions for MOD and REM. - * ch-exp.y (tokentab3): Add MOD and REM. - * ch-exp.y (yylex): Set innermost_block for symbols found - in local scopes. Return LOCATION_NAME for local symbols. - * ch-lang.c (chill_op_print_tab): Fix MOD entry to use - BINOP_MOD instead of BINOP_REM. Add REM entry, using BINOP_REM. - -Mon Jan 4 07:35:31 1993 Steve Chamberlain (sac@wahini.cygnus.com) - - * command.c (shell_escape, make_command, _initialize_command): - don't create or use fork if CANT_FORK is defined. - * serial.h, ser-go32.c: now compiles, but "the obvious problems of - code written for the IBM PC" remain. - * xm-go32.h: define CANT_FORK - -Sun Jan 3 14:24:56 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * remote-sim.c: first attempt at general simulator interface - * remote-hms.c: whitespace - * h8300-tdep.c: (h8300_skip_prologue, examine_prologue): - understand new stack layout. (print_register_hook): print ccr - register in a fancy way. - -Sun Jan 3 14:16:10 1993 Fred Fish (fnf@cygnus.com) - - * eval.c (language.h): Include. - * eval.c (evaluate_subexp_with_coercion): Only coerce arrays - to pointer types when the current language is C. It loses for - other languages when the lower index bound is nonzero. - * valarith.c (value_subscript): Take array lower bounds into - account when performing subscripting operations. - * valops.c (value_coerce_array): Add comment describing why - arrays with nonzero lower bounds are dealt with in value_subscript, - rather than in value_coerce_array. - -Sat Jan 2 12:16:41 1993 Fred Fish (fnf@cygnus.com) - - * ch-exp.y (FLOAT_LITERAL): Add token. - * ch-exp.y (literal): Add FLOAT_LITERAL. - * ch-exp.y (match_float_literal): New lexer routine. - * ch-exp.y (convert_float): Remove. - * ch-exp.y (yylex): Call match_float_literal. - * ch-exp.y (yylex): Match single '.' after trying - to match floating point literals. - - * eval.c (evaluate_subexp): Add case MULTI_SUBSCRIPT. - * expprint.c (print_subexp): Rename BINOP_MULTI_SUBSCRIPT to - MULTI_SUBSCRIPT. - * expprint.c (dump_expression): New function for dumping - expression vectors during gdb debugging. - * expression.h (BINOP_MULTI_SUBSCRIPT): Name changed to - MULTI_SUBSCRIPT and moved out of BINOP range. - * expression.h (DUMP_EXPRESSION): New macro that calls - dump_expression if DEBUG_EXPRESSIONS is defined. - * m2-exp.y (BINOP_MULTI_SUBSCRIPT): Changed to MULTI_SUBSCRIPT. - * parse.c (length_of_subexp, prefixify_subexp): Change - BINOP_MULTI_SUBSCRIPT to MULTI_SUBSCRIPT. - * parse.c (parse_exp_1): Call DUMP_EXPRESSION before and after - prefixify'ing the expression. - * printcmd.c (print_command_1): Add comment. - * ch-exp.y (expression_list): Add useful actions. - * ch-exp.y (value_array_element): Add useful actions. - * ch-exp.y (array_primitive_value): Add production. - * ch-exp.y (yylex): Recognize ',' as a token. - -Fri Jan 1 18:22:02 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: pass prefix and exec_prefix via FLAGS_TO_PASS, - POSIXize the recursive makes (make [variable assignments] target{s}) - -Fri Jan 1 11:56:23 1993 Fred Fish (fnf@cygnus.com) - - * tm-sun4sol2.h (CPLUS_MARKER): Remove, now set in tm-sysv4.h. - * tm-sysv4.h (CPLUS_MARKER): By default, g++ uses '.' as the - CPLUS_MARKER for all SVR4 systems, so follow suit. - * defs.h (strdup_demangled): Remove prototype. - * dwarfread.c (enum_type, synthesize_typedef): Use new macro - SYMBOL_INIT_LANGUAGE_SPECIFIC. - * dwarfread.c (new_symbol): Use SYMBOL_INIT_DEMANGLED_NAME. - * minsyms.c (install_minimal_symbols, prim_record_minimal_symbol, - prim_record_minimal_symbol_and_info): Use new macro - SYMBOL_INIT_LANGUAGE_SPECIFIC. - * minsyms.c (install_minimal_symbols): Use new macro - SYMBOL_INIT_DEMANGLED_NAME. - * stabsread.c (define_symbol): Use new macro - SYMBOL_INIT_DEMANGLED_NAME. - * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list): - Use new macro SYMBOL_INIT_DEMANGLED_NAME. - * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Use new macro - SYMBOL_INIT_DEMANGLED_NAME. - * symmisc.c (dump_msymbols, dump_symtab, print_partial_symbol): - SYMBOL_DEMANGLED_NAME now tests language itself. - * symtab.c (COMPLETION_LIST_ADD_SYMBOL): SYMBOL_DEMANGLED_NAME - now tests language itself. - * symtab.h (SYMBOL_CPLUS_DEMANGLED_NAME): New macro that does - what SYMBOL_DEMANGLED_NAME used to do, directly access the C++ - mangled name member in the language dependent portion of a symbol. - * symtab.h (SYMBOL_DEMANGLED_NAME): New macro that returns the - mangled name member appropriate for a symbol's language. - * symtab.h (SYMBOL_SOURCE_NAME, SYMBOL_LINKAGE_NAME, - SYMBOL_MATCHES_NAME, SYMBOL_MATCHES_REGEXP): - SYMBOL_DEMANGLED_NAME now tests language itself. - * symtab.h (SYMBOL_INIT_LANGUAGE_SPECIFIC): New macro that - initializes language dependent portion of symbol. - * symtab.h (SYMBOL_INIT_DEMANGLED_NAME): New macro that - demangles and caches the demangled form of symbol names. - * utils.c (fputs_demangled, fprint_symbol): Use current language - to select an appropriate demangling algorithm. - * utils.c (strdup_demangled): Remove, no longer used. - * symtab.h (SYMBOL_CHILL_DEMANGLED_NAME): New macro that directly - access the Chill mangled name member in the language dependent - portion of a symbol. - * ch-lang.c (chill_demangle): New function, simple demangler. - * defs.h (chill_demangle): Add prototype. - * symtab.h (language_dependent_info): Add struct for Chill. - -For older changes see ChangeLog-92 - -Local Variables: -mode: indented-text -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/contrib/gdb/gdb/ChangeLog-94 b/contrib/gdb/gdb/ChangeLog-94 deleted file mode 100644 index a691ace1003..00000000000 --- a/contrib/gdb/gdb/ChangeLog-94 +++ /dev/null @@ -1,5705 +0,0 @@ -Fri Dec 30 17:58:55 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * config/m68k/tm-est.h: Remove cruft. - - -Thu Dec 29 22:40:00 1994 Jeff Law (law@snake.cs.utah.edu) - - * Allow up to 10 whitespace separated arguments to user defined - commands. - * top.c (struct user_args): Structure for holding arguments to - user defined commands. - (print_command_line): Delete unused "tmp_chain" variable. Clean - up flow control by having cases exit in the same manner. - Before executing a command or evaluating an expression, substitute - the current $arg0..$arg9 values if the command/expression uses them. - (arg_cleanup): New function. - (setup_user_args, locate_arg, insert_args): Likewise. - (execute_user_command): Allow arguments to user defined commands. - - * Allow if/while commands to be used within a breakpoint command - list. - * breakpoint.c (bpstat_do_actions): Call execute_control_command - rather than execute_command (passes entire command structure rather - than just the command line text). - (breakpoint_1): Use "print_command_line" to print a breakpoint - command line (including control structures). - * gdbcmd.h (execute_control_command): Provide extern decl. - (print_command_line): Likewise. - * top.c (execute_control_command): No longer static. - (print_command_line): New function to recursively print a command - line, including control structures. - -Thu Dec 29 18:18:31 1994 Rob Savoye - - * hppa-tdep.c (pa_print_registers): Extract register values stored - in big endian format on big and little endian hosts. - - * array-rom.c: Support for Array Tech LSI33k based RAID disk - controller board. - * configure.in: Recognize "mips*-*-ecoff*" rather than - "mips*-idt-ecoff*" so it'll work for the LSI33k. - - * monitor.[ch], op50-rom.c, rom68k-rom.c, w89k-rom.c: Add support - to monitor config structure for supported baud rates for a target - and variable stop bits. - * monitor.c (monitor_fetch_register): Store register values in big - endian format on any host. - -Wed Dec 28 19:27:22 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (hppa_fix_call_dummy): Prefer import stubs over - export stubs and actual shared library functions so that lazy - binding works correctly. Try both __d_plt_call and __gcc_plt_call - trampolines for calling import stubs. - -Wed Dec 28 15:29:02 1994 Stan Shebs - - * a29k-tdep.c (pop_frame): Fix a variable name. - -Wed Dec 28 12:21:39 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (push_dummy_frame): Refine code to determine what - space ID to place in the stack & inf_status structure. - (hppa_pop_frame): Don't walk through trampoline code if popping a - call dummy frame. - (hppa_fix_call_dummy): Call the stack dummy directly if the - current PC is in a shared library. - - * hppa-tdep.c (push_dummy_frame): Return type is void. Clear - in_syscall bit in flags. Don't depend on the PC queue registers - when in_syscall is set, they're not valid. - * config/pa/tm-hppa.h (PUSH_DUMMY_FRAME): Pass inf_status down to - push_dummy_frame. - (SR4_REGNUM): Define. - - * hppa-tdep.c: Misc. lint changes. - -Tue Dec 27 12:32:43 1994 Jeff Law (law@snake.cs.utah.edu) - - * breakpoint.c (watchpoint_check): Don't bother restoring the - "selected" frame anymore, it's not necessary. Initialize the - frame cache before trying to find the current frame in the frame - chain. - - * somsolib.c (som_solib_add): Return without loading any shared - libraries if symfile_objfile is NULL. - (som_solib_create_inferior_hook): Likewise. - -Fri Dec 23 17:03:13 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * remote-est.c: New file supports EST-300 CPU32 background - mode ICE. - * remote-utils.c (sr_com): Call registers_changed. - * configure.in (m68*-*-est*): New configuration. - * config/m68k/tm-est.h: New file. - -Fri Dec 23 16:18:50 1994 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (CLIBS): Put LIBIBERTY last. - -Thu Dec 22 09:27:16 1994 Jim Kingdon - - * ser-tcp.c (tcp_open): Cast to struct sockaddr when passing to - function which expects that. - -Thu Dec 22 13:25:33 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * nlm/gdbserve.c, nlm/ppc.c, nlm/ppc.h: Don't try to use - ALTERNATE_MEM_FUNCS. - -Wed Dec 21 14:00:26 1994 Rob Savoye - - * monitor.c: Now supports xmodem as a remoteloadprotocol. - -Tue Dec 20 23:01:17 1994 Stu Grossman (grossman@cygnus.com) - - * config/mips/xm-irix4.h, config/mips/xm-irix5.h: #define - _BSD_COMPAT to get reliable signal handling. - -Tue Dec 20 11:44:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * sparc-tdep.c, a29k-tdep.c, findvar.c (get_saved_register): - if !target_has_registers, call error(). - - * value.h: Remove obsolete comments about FRAME vs struct - frame_info *. - - -Sun Dec 18 11:52:58 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * sparc-tdep.c (sparc_pop_frame): Remove erroneous extra argument - to write_register. - -Sat Dec 17 13:23:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * tm-sparc.c (EXTRA_FRAME_INFO): New field sp_offset. - * sparc-tdep.c (sparc_init_extra_frame_info): Set it. - (examine_prologue, sparc_init_extra_frame_info): Use ->frame plus - ->sp_offset to compute the address something is saved at, not - ->bottom. - - * sparc-tdep.c (get_saved_register): New function. - * tm-sparc.h: Define GET_SAVED_REGISTER; don't define - FRAME_FIND_SAVED_REGS, HAVE_REGISTER_WINDOWS or REGISTER_IN_WINDOW_P. - * stack.c (frame_info): Add comment about what to do if - FRAME_FIND_SAVED_REGS is not defined. - - * sparc-tdep.c (sparc_init_extra_frame_info): Set ->frame field - here. Get it right for flat frames. - * sparc-tdep.c (sparc_frame_chain): Instead of returning - meaningful value for ->frame field, just return dummy value. - This change is needed because the old code didn't deal with mixed - flat and non-flat frames. - - * sparc-tdep.c (sparc_pop_frame): Write SP_REGNUM from - frame->frame, don't go through saved regs for this. - - * sparc-tdep.c: Move guts of skip_prologue to new function - examine_prologue. Check for flat prologue and set is_flat. - Provide the caller with the information about what is saved where - if desired. - (skip_prologue, sparc_frame_find_saved_regs): Call examine_prologue. - - * sparc-tdep.c: Replace union sparc_insn_layout and anonymous - union in isannulled, which won't work on a little-endian host, - with X_* macros. - - * sparc-tdep.c (sparc_frame_saved_pc): If addr == 0, the saved PC - is still in %o7. - - * config/sparc/tm-sparc.h: Define INIT_FRAME_PC and - INIT_FRAME_PC_FIRST. - * blockframe.c (get_prev_frame_info): Modify comments regarding - INIT_FRAME_PC_FIRST and the sparc. - - * sparc-tdep.c (single_step): Use 4 not sizeof (long) for size of - instruction. - -Sat Dec 17 02:33:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-typeprint.c (c_type_print_base): Use `show' of -1 to print - the return type of methods to avoid infinite loops with anonymous - types. - * valops.c (search_struct_field): Handle anonymous unions. - - * sparc-tdep.c (sunos4_skip_trampoline_code): New function - to correctly handle steps into -g compiled PIC objects in the - main executable. - * config/sparc/tm-sun4os4.h (SKIP_TRAMPOLINE_CODE): - Redefine to use sunos4_skip_trampoline_code. - - * dwarfread.c (DWARF_REG_TO_REGNUM): Provide a default mapping - from DWARF to GDB register numbering. - * dwarfread.c (locval): Use DWARF_REG_TO_REGNUM to map the - register value. - * config/mips/tm-mipsv4.h (DWARF_REG_TO_REGNUM): Define. - -Fri Dec 16 10:56:29 1994 J.T. Conklin - - * Makefile.in (uninstall): transform file names. - -Thu Dec 15 16:55:35 1994 Stan Shebs - - * defs.h: Include progress.h. - (QUIT): Call PROGRESS. - * main.c (main): Call START_PROGRESS and END_PROGRESS, break - usage message into shorter strings. - * source.c: Change long command help strings into concats of - shorter ones, for picky ANSI compilers. - - * top.c (command_loop): For space usage display, show both - absolute size and the change from before command execution. - -Thu Dec 15 16:40:10 1994 Stu Grossman (grossman@cygnus.com) - - * defs.h, main.c (gdb_fputs), top.c: Add stream arg to - fputs_unfiltered_hook. - * defs.h, top.c, utils.c (error): Add error_hook. - -Tue Dec 13 15:15:33 1994 Stan Shebs - - * breakpoint.c, infrun.c, printcmd.c: Change long command help - strings into concats of shorter ones, for picky ANSI compilers. - -Mon Dec 12 17:08:02 1994 Stan Shebs - - Sparc flat register window support. - * sparc-tdep.c (sparc_insn_layout): New union, defines layout of - instructions symbolically (used to be local to skip_prologue). - (sparc_init_extra_frame_info): New function. - (sparc_frame_chain): Add flat cases throughout. - (skip_prologue): Add recognition of flat prologues. - (sparc_frame_find_saved_regs): Add flat cases. - (sparc_pop_frame): Ditto. - * config/sparc/tm-sparc.h (EXTRA_FRAME_INFO): New slots. - (INIT_EXTRA_FRAME_INFO): Call sparc_init_extra_frame_info. - (PRINT_EXTRA_FRAME_INFO): Define. - - -Mon Dec 12 13:06:59 1994 Jim Kingdon - - * f-lang.c: Remove duplicate declaration of - builtin_type_f_integer, and only include it in the f_builtin_types - once. - - * somread.c (som_symfile_read): Just assign to objfile->obj_private, - not OBJ_UNWIND_INFO. Assigning to a cast is a GCC-ism which - the HP compiler doesn't like. - - -Fri Dec 9 15:50:05 1994 Stan Shebs - - * remote.c (remote_wait): Pass string instead of char to strcpy. - -Fri Dec 9 04:43:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbserver/low-lynx.c (mywait): Remove debugging printf. - -Thu Dec 8 15:07:29 1994 Jim Kingdon - - * frame.h: Restore pre-Nov 3 comments about FRAME_FP with minor - changes. They are correct, unlike the post-Nov 3 comment - (FRAME_FP doesn't have any machine-independent relationship with - FP_REGNUM or any other such notion of a "frame pointer"). - -Wed Dec 7 14:50:54 1994 Jim Kingdon - - * gdbserver/remote-utils.c (write_ok): Write "OK", not "Ok", to - match stubs and protocol spec. - * gdbserver/remote-utils.c (remote_open): Cast to struct sockaddr - when passing to function which expects that. - - The following changes aren't quite enough to make things work with - LynxOS (apprently kernel problems). - * infrun.c (wait_for_inferior): When resuming new thread, pass pid - not -1 for remote case. - * thread.c (info_threads_command): Give error if !target_has_stack. - * infrun.c (start_remote): Call init_thread_list. - * thread.c (info_threads_command): Don't call kill for remote - debugging target. - * target.c (normal_pid_to_str): Print "thread" not "process" for - remote. - * remote.c, gdbserver/*: Add 'H', 'S', and 'C' requests, 'X' - response, and `thread' part of 'T' response. - * gdbserver/*: If program exits, send packet to GDB before - exiting. Handle termination with a signal the same as exiting - with an exitstatus. - * remote.c: Don't try to kill program after getting an 'X' - response. - * infrun.c (wait_for_inferior): Add comment about kill versus mourn. - -Thu Dec 8 12:37:38 1994 Rob Savoye - - * config/pa/tm-pro.h tm-hppap.h, hppapro.mt: Rename tm-hppap.h to - tm-pro.h. - -Wed Dec 7 18:22:59 1994 Stan Shebs - - * source.c: Various cosmetic changes. - (forward_search_command): Handle very long source lines correctly. - -Wed Dec 7 13:21:47 1994 Rob Savoye - - * hppa-tdep.c: Use GDB_TARGET_IS_PA_ELF so SOM target support will - stop being linked in. - - * config/pa/tm-hppap.h: New file. Set GDB_TARGET_IS_PA_ELF, - otherwise it looks like BSD-ELF. - -Mon Dec 5 21:43:52 1994 Stu Grossman (grossman@cygnus.com) - - * inftarg.c: include to get def of pid_t. - -Fri Dec 2 15:03:07 1994 Stan Shebs - - * solib.c (auto_solib_add_at_startup): New global. - (solib_create_inferior_hook): Call solib_add only if - auto_solib_add_at_startup is nonzero. - (_initialize_solib): New command "set auto-solib-add". - -Fri Dec 2 12:52:04 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * parse.c (msymbol_addr_type): Replaced by - lookup_pointer_type (builtin_type_void). - - * printcmd.c (_initialize_printcmd): Give examine_*_type - a name for `ptype $_'. - -Fri Dec 2 12:52:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (print_formatted): Call val_print_string directly, - rather than via value_print. - -Wed Nov 30 22:27:27 1994 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c (som_solib_get_got_by_pc): New function. - * somsolib.h (som_solib_get_got_by_pc): Add extern decl. - * hppa-tdep.c (hppa_fix_call_dummy): Handle case where FUN is the - function's export stub or real address in a shared library. - -Tue Nov 29 13:40:25 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * config/i386/nbsd.mh (REGEX, REGEX1): No longer define. - - * configure.in (i[345]86-*-freebsd*): New configuration. - * config/i386/{fbsd.mh,fbsd.mt,nm-fbsd.h}: New files. - -Tue Nov 29 12:23:25 1994 Stan Shebs (shebs@andros.cygnus.com) - - * top.c (read_next_line): Pass annotation suffix "commands" - instead of "command", matches documentation. - -Mon Nov 28 14:53:21 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config/a29k/tm-a29k.h (setup_arbitrary_frame): Replace - FRAME_ADDR with CORE_ADDR in prototype. - - * top.c (command_line_input): If annotation suffix is NULL, - replace it with an empty string. - (read_next_line): Pass "command" as annotation suffix to - command_line_input. - -Mon Nov 28 11:03:14 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * config/rs6000/tm-rs6000.h (setpgrp): move defn from here... - * config/rs6000/xm-rs6000.h: ...to here. - - -Fri Nov 25 21:26:02 1994 Jeff Law (law@snake.cs.utah.edu) - - * tm-hppa.h (skip_trampoline_code): Add extern decl. - * hppa-tdep.c (hppa_pop_frame): Silently restart the inferior and - allow it to execute any return path trampoline code. Stop the - inferior and give the user control when the trampoline has - finished executing. - (in_solib_call_trampoline): Handle export stubs which also perform - parameter relocations. - (in_solib_return_trampoline): Likewise. - -Fri Nov 25 13:37:10 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * coffread.c, symfile.h (coff_getfilename): Make it static again. - * xcoffread.c (coff_getfilename): Use a static copy from - coffread.c, modified for accessing the static xcoff strtbl. - -Fri Nov 25 00:51:05 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (in_solib_call_trampoline): Recognize calls through - _sr4export and $$dyncall as trampolines. Likewise for long-call - stubs and parameter relocation stubs. - (in_solib_return_trampoline): Recognize a return trampoline for - return value relocation stubs. - - * hpread.c: Include hp-symtab.h instead of hpux-symtab.h. - Various name changes to match those used by hp-symtab.h. - -Thu Nov 24 00:39:27 1994 Jeff Law (law@snake.cs.utah.edu) - - * blockframe.c (find_pc_partial_function): Inhibit mst_trampoline - symbol special handling when INHIBIT_SUNSOLIB_TRANSFER_TABLE_HACK - is defined. - * infrun.c (IN_SOLIB_CALL_TRAMPOLINE): Renamed from - IN_SOLIB_TRAMPOLINE. All callers changed. - (IN_SOLIB_RETURN_TRAMPOLINE): Provide default definition. - (wait_for_inferior): Handle single stepping through trampolines on - return paths from shared libraries. - * config/pa/tm-hppa.h (IN_SOLIB_CALL_TRAMPOLINE): Use - in_solib_call_trampoline. - (IN_SOLIB_RETURN_TRAMPOLINE): Use in_solib_return_trampoline. - (INHIBIT_SUNSOLIB_TRANSFER_TABLE_HACK): Define. - * hppa-tdep.c (in_solib_call_trampoline): New function. - (in_solib_return_trampoline): New function. - -Wed Nov 23 21:43:03 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * tm-h8300.h (REMOTE_BREAKPOINT): Define. - * h8300-tdep.c (h8300_pop_frame): Remove redundant call. - - * remote-e7000.c (HARD_BREAKPOINTS): Reenable. - (BC_BREAKPOINTS): Disable. - * sh-tdep.c (print_insn): Cope with big and little endian machines. - * sh/sh.mt: Use libsim.a - * sh/tm-sh.h (TARGET_BYTE_ORDER_SELECTABLE): New - (BREAKPOINT): Changed to be byteorder independent. - -Tue Nov 22 19:13:39 1994 Stan Shebs (shebs@andros.cygnus.com) - - Maintenance commands to report time and space usage. - * main.c (display_time, display_space): New globals. - (main): Add argument --statistics to enable reporting, display - time and space after startup is done. - * maint.c (maintenance_time_display, maintenance_space_display): - New commands. - * top.c (command_loop): Display time and space after command - execution. - - * top.c (pre_init_ui_hook): New global. - (gdb_init): If pre_init_ui_hook set, call before all other init. - -Tue Nov 22 10:25:59 1994 Kung Hsu (kung@mexican.cygnus.com) - - * a29k-tdep.c (examine_tag): Fix a bug in stack frame size. - -Sat Nov 19 03:10:51 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/i386/i386sol2.mh: Reenable core file support. - - * symfile.c (deduce_language_from_filename): Treat .c++ as a - C++ extension. - - * valops.c (destructor_name_p): Do not compare the template - part for template classes. - -Fri Nov 18 14:55:59 1994 Stan Shebs (shebs@andros.cygnus.com) - - * defs.h, infcmd.c (reg_names): Don't declare as constant. - * remote-mips.c (mips_open): Read and set the processor type. - * mips-tdep.c (mips_set_processor_type): Always return an int. - -Fri Nov 18 10:38:12 1994 J.T. Conklin - - * nlm/alpha.c (strtol): Remove, it is provided by NetWare C library. - * nlm/gdbserve.def (strtol): Add to import list. - * nlm/fake_aio.c: Remove file, no longer used. - - * Makefile.in (LD_FOR_TARGET, NLMCONV_FOR_TARGET): Remove. - * nlm/Makefile.in (gdbserve.O): Link with ${CC_FOR_TARGET}. - (LD_FOR_TARGET): Remove. - -Thu Nov 17 22:09:50 1994 Rob Savoye - - * monitor.h, monitor.c, w89k-rom.c, op50n-rom.c, idp-rom.c: Add - support for two variables used to control the load protocol and - conversion type. - -Thu Nov 17 17:51:12 1994 Stan Shebs (shebs@andros.cygnus.com) - - Support for different MIPS IDT processor models. - * mips-tdep.c (mips_processor_type, tmp_mips_processor_type, - mips_generic_reg_names, mips_r3041_reg_names, - mips_r3051_reg_names, mips_r3081_reg_names, - mips_processor_type_table): New globals. - (mips_do_registers_info): Don't display register if name is empty. - (mips_set_processor_type_command): New command. - (mips_show_processor_type_command): New command. - (mips_set_processor_type): New function. - (mips_read_processor_type): New function. - * config/mips/tm-idt.h (DEFAULT_MIPS_TYPE): New macro. - * config/mips/tm-mips.h (DEFAULT_MIPS_TYPE): New macro. - (NUM_REGS): Increase to account for all CP0 registers. - (REGISTER_NAMES): Add empty names for CP0 registers. - (FIRST_EMBED_REGNUM, LAST_EMBED_REGNUM): Adjust. - (PRID_REGNUM): New macro. - -Wed Nov 16 16:41:52 1994 Stan Shebs (shebs@andros.cygnus.com) - - * README: Add warning about termcap in Ultrix and OSF/1. - -Wed Nov 16 15:28:29 1994 Rob Savoye (rob@cygnus.com) - - - * hppa-tdep.c: Remove including sys/dir.h from a target file. - -Wed Nov 16 10:31:27 1994 J.T. Conklin (jtc@cygnus.com) - - * config/powerpc/gdbserve.mt (TDEPFILES): Remove fake_aio.o. - - * nlm/gdbserve.c: Include before other NetWare headers. - * nlm/ppc.c: Likewise. - - * nlm/ppc.c (strtol): Remove, it is provided by NetWare C Library. - (StopBell): New function (stubbed out). - -Wed Nov 16 00:12:21 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (skip_trampoline_code): Handle shared library import - trampolines. - -Tue Nov 15 16:18:52 1994 Kung Hsu (kung@mexican.cygnus.com) - - * c-exp.y (yylex): Fix a bug in template scanning. - -Tue Nov 15 14:25:47 1994 Stan Shebs (shebs@andros.cygnus.com) - - * i386-stub.c, m68k-stub.c, sparc-stub.c, sparcl-stub.c: Mask out - the top bit returned by getDebugChar. - -Tue Nov 15 01:03:56 1994 Rob Savoye (rob@slipknot.cygnus.com) - - * op50-rom.c, w89k-rom.c, monitor.c: Modify to usr two variables - to set remote load type and protocol. - * rom68k-rom.c: Add to_stop in target_ops. - - -Sat Nov 12 21:55:47 1994 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c: Add TODO list. - (som_solib_add): Immediately return if $SHLIB_INFO$ sections does - not exist or has size zero. Slightly simplify error handling. - Keep an internal list of all the loaded shared libraries and - various tidbits of information about the loaded shared libraries. - Build section tables for each loaded shared library and add those - tables to the core target if necessary. - (som_solib_create_inferior_hook): Force re-reading of shared - libraries at exec time. - (som_sharedlibrary_info_command): New function for dumping - information about the currently loaded shared libraries. - (_initialize_som_solib): New function. - -Sat Nov 12 02:26:50 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * Makefile.in (copying.o, f-exp.tab.o, dpx2-nat.o, dstread.o, - i386aix-nat.o, i386m3-nat.o, irix5-nat.o, lynx-nat.o, m3-nat.o, - mipsm3-nat.o, ns32km3-nat.o, remote-e7000.o, remote-os9k.o): - Add dependencies. - (copying.o, os9kread.o, remote.o): Update dependencies. - - * valarith.c (value_sub): When subtracting pointers, only - check for a match of the pointed to element lengths. - Cast element length to LONGEST to obtain a signed result for - pointer subtractions. - -Fri Nov 11 10:51:07 1994 Jeff Law (law@snake.cs.utah.edu) - - * ch-exp.y (yylex): Fix off-by-one error when converting string to - lowercase. Null terminate new string. - - * hppa-tdep.c (rp_saved): Handle IMPORT stubs too. - - * somsolib.c (som_solib_add): Check the value of __dld_flags, if - it indicates __dld_list is not valid return an error. If it - indicates that libraries were not mapped privately, issue a - warning. - -Thu Nov 10 23:17:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symfile.c (syms_from_objfile): Only call find_lowest_section if - no ".text" section exists. - -Thu Nov 10 15:16:21 1994 Rob Savoye - - * rom68k-rom.c: New file. Replaces the old remote-mon.c and uses - the new generic ROM interface in monitor.c. - * config/m68k/monitor.mt: Use new ROM support. - * monitor.c: Add support for xmodem download protocol. - -Wed Nov 9 18:46:24 1994 Stan Shebs (shebs@andros.cygnus.com) - - * findvar.c (find_saved_register): Fix a frame variable name. - * infcmd.c (finish_command): Ditto. - -Tue Nov 8 13:20:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Remove "Watchpoints seem not entirely reliable, though - they haven't failed me recently." item--this old (4.6 at least) - item is too vague to be useful (some watchpoint bugs have been - fixed since then). - * TODO: Add explanation of "RPC interface" item. - -Mon Nov 7 22:25:21 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (read_unwind_info): Use "text_offset" for linker - stub unwind descriptors too. - - * Enable backtracing from inside a SOM shared library back into - user code. - * hppa-tdep.c (internalize_unwinds): Accept and use new - "text_offset" argument for dynamic relocation of - region_{start,end} fields in the unwind descriptor. - (read_unwind_info): Pass text_offset to internalize unwinds. - -Mon Nov 7 14:34:42 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m3-nat.c: Remove comments about arbitrary limit in - printf_filtered; that limit is gone. - -Mon Nov 7 00:27:16 1994 Jeff Law (law@snake.cs.utah.edu) - - * Beginnings of SOM shared library support. Breakpoints and - single frame backtracing within the library only. Only works when - using the HPUX 9 dynamic linker. More functionality to be added - soon. - - * somsolib.c, somsolib.h: New files. - * Makefile.in (HFILES_NO_SRCDIR): Add somsolib.h - (ALLDEPFILES): Add somsolib.c. - (somsolib.o): Add some dependencies. - * somread.c (som_symtab_read): Accept multiple section offsets. - All callers changed. Adjust all text symbols with the first - section offset. - * symfile.c (find_lowest_section): Enable this function. Add some - tie-breaking logic when sections have the same vma. - (syms_from_objfile): Use find_lowest_section rather than looking - for ".text" by name. Relax warning to only warn if the lowest - section is not a code section. - * config/pa/{hppabsd.mh, hppahpux.mh} (NATDEPFILES): Add somsolib.o - * config/pa/{nm-hppab.h, nm-hppah.h}: Include somsolib.h. - -Sun Nov 6 12:54:54 1994 Jeff Law (law@snake.cs.utah.edu) - - * partial-stab.h (N_TEXT): Put back GDB_TARGET_IS_HPPA kludge, - it is still needed for GCC-2.6 compiled code. - * TODO (GDB_TARGET_IS_HPPA): Note this kludge can be nuked - sometime after GCC-2.7 has been released. - - * hppa-tdep.c (frame_saved_pc): Mask off low two bits when - retrieving the PC from a signal handler caller. Fix thinko - in Stan's last change ("frame", should have been "frame->next"). - If the next frame is a signal handler caller and it's a system - call which has entered the kernel ((PSW & 0x2) != 0), then the - saved pc is in %r2 instead of %r31. - -Fri Nov 4 23:47:07 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (hppa_frame_find_saved_regs): Change "frame" to - "frame_info" throughout. - -Fri Nov 4 16:26:59 1994 Kung Hsu (kung@mexican.cygnus.com) - - * sparcl-stub.c: get rid of defs.h. - -Fri Nov 4 13:11:54 1994 Jim Kingdon - - * gdbserver/Makefile.in (MMALLOC_CFLAGS): Add -I${MMALLOC_DIR}. - Correct definition of MMALLOC_DIR to reflect fact this is - gdb/gdbserver/Makefile.in, not gdb/Makefile.in. - - * gdbserver/server.c (main): After we kill the inferior in - response to a 'k' request, exit. - - * remote.c (remote_kill): Use catch_errors when calling putpkt. - (putpkt): Return int, not void, to match catch_errors calling - convention. - -Fri Nov 4 10:52:38 1994 Stan Shebs (shebs@andros.cygnus.com) - - * rs6000-tdep.c (pop_frame): Correct a variable name. - -Fri Nov 4 05:43:35 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Re-write item about SIGINT handling to reflect the fact - that target_stop now exists. - -Thu Nov 3 15:19:17 1994 Stan Shebs (shebs@andros.cygnus.com) - - Replace useless FRAME, FRAME_ADDR types with struct frame_info * - and CORE_ADDR, respectively. - * frame.h (FRAME, FRAME_INFO_ID, FRAME_ADDR): Remove. - * blockframe.c (get_frame_info): Remove. - * a29k-tdep.c, alpha-tdep.c, blockframe.c, breakpoint.c, - breakpoint.h, energize.c, findvar.c, gould-pinsn.c, - h8300-tdep.c, h8500-tdep.c, hppa-tdep.c, i386-tdep.c, i960-tdep.c, - infcmd.c, inferior.h, infrun.c, m68k-tdep.c, m88k-tdep.c, - mips-tdep.c, nindy-tdep.c, printcmd.c, pyr-tdep.c, rs6000-tdep.c, - sh-tdep.c, sparc-tdep.c, stack.c, valops.c, z8k-tdep.c, - config/a29k/tm-a29k.h, config/alpha/tm-alpha.h, - config/gould/tm-pn.h, config/h8300/tm-h8300.h, - config/h8500/tm-h8500.h, config/mips/tm-mips.h, - config/ns32k/tm-merlin.h, config/ns32k/tm-umax.h, - config/pyr/tm-pyr.h, config/sparc/tm-sparc.h): Replace FRAME with - struct frame_info * everywhere, replace FRAME_ADDR with CORE_ADDR, - rename variables consistently (using `frame' or `fi'), remove - calls to get_frame_info and FRAME_INFO_ID, remove comments about - FRAME and FRAME_ADDR cruftiness. - -Thu Nov 3 14:25:24 1994 Stu Grossman (grossman@cygnus.com) - - * corelow.c, exec.c, inftarg.c, m3-nat.c, op50-rom.c, procfs.c, - remote-adapt.c, remote-e7000.c, remote-eb.c, remote-es.c, - remote-hms.c, remote-mips.c, remote-mm.c, remote-mon.c, - remote-nindy.c, remote-os9k.c, remote-pa.c, remote-sim.c, - remote-st.c, remote-udi.c, remote-vx.c, remote-z8k.c, remote.c, - w89k-rom.c, target.c, target.h: Add support for target_stop(). - -Thu Nov 3 01:23:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * osfsolib.c (solib_map_sections, first_link_map_member, - next_link_map_member, xfer_link_map_member): Retrieve and use - shared library relocation offset from runtime loader structures. - Use libxproc.a routines to get a working version if - USE_LDR_ROUTINES is defined. - * README: Remove item about shared library relocation for - Alpha OSF/1. - -Wed Nov 2 15:05:39 1994 Kung Hsu (kung@mexican.cygnus.com) - - * c-exp.y (yylex): scan template names, and scan nested class - names. - -Wed Nov 2 11:01:55 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * nlm/Makefile.in: install gdbserve.nlm. - - -Tue Nov 1 13:00:46 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-valprint.c (c_value_print): Check for plain literal `char' - target type when suppressing `(char *)' output for strings. - -Mon Oct 31 19:19:51 1994 Stan Shebs (shebs@andros.cygnus.com) - - * coffread.c (coff_symfile_init): Remove unused local abfd. - * utils.c [NO_MMALLOC] (mmalloc, mrealloc): Define and use size_t - instead of long, for compatibility with mmalloc.h. - -Sat Oct 29 02:40:40 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * top.c (line_completion_function): Renamed from - symbol_completion_function, takes the line buffer and the - point in the line buffer as additional arguments. - (readline_line_completion_function): New function, interface - between readline and line_completion_function. - (init_main): Use it. - (complete_command): Use line_completion_function instead of - abusing rl_line_buffer. Free completion strings after printing - them. - * symtab.c (completion_list_add_name): Recheck for duplicates - if we intend to add a modified symbol. - - * gdbtypes.h (cplus_struct_type): nfn_fields_total no longer - includes the number of methods from the baseclasses. - * stabsread.c (attach_fn_fields_to_type): No longer add the - number of methods from the baseclasses to TYPE_NFN_FIELDS_TOTAL, - the baseclass type might not have been completely filled in yet. - * symtab.c (total_number_of_methods): New function to compute - the total number of methods for a type, including the methods - from baseclasses. - (decode_line_1): Use it instead of TYPE_NFN_FIELDS_TOTAL to - allocate the symbol array for find_methods. - - * stabsread.c (scan_file_globals): Add default case to minimal - symbol type switch, to avoid gcc -Wall warnings. - - * config/rs6000/tm-rs6000.h (INIT_EXTRA_FRAME_INFO): - Don't test for zero backchain pointer to recognize a signal - handler frame, if read() gets interrupted by a signal, the - backchain will be non zero. - (SIG_FRAME_FP_OFFSET): Move to here from rs6000-tdep.c, - improve comment. - (SIG_FRAME_PC_OFFSET): New definition. - (FRAME_SAVED_PC): Return saved pc from sigcontext if this - is a signal handler frame. - * rs6000-tdep.c (function_frame_info): Do not error out - if we can't access the instructions. - - * config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR): - New definition to get the function address from a function pointer. - * valops.c (find_function_addr): Use it when calling a user - function through a function pointer. - -Fri Oct 28 16:16:52 1994 Stan Shebs (shebs@andros.cygnus.com) - - * Makefile.in (MMALLOC_DIR): New definition. - (MMALLOC): Use MMALLOC_DIR. - (MMALLOC_CFLAGS): Look in MMALLOC_DIR for mmalloc.h. - (OPCODES): Remove gratuitous "./". - * defs.h (mmalloc.h): Include. - (mmalloc, mrealloc, etc): Remove decls. - (cplus_demangle, cplus_demangle_opname): Remove decls. - -Wed Oct 26 15:41:07 1994 Stu Grossman (grossman@cygnus.com) - - * defs.h, main.c, top.c: Change sense and name of - no_windows variable. Now called use_windows, and defaults to off - (for compatibility). - -Wed Oct 26 12:20:53 1994 Jim Kingdon - - * coffread.c (coff_symtab_read): If we get the address from - target_lookup_symbol, set the section to -2 not SECT_OFF_BSS. - (coff_symtab_read): Set value and section of symbol that - process_coff_symbol returns. - -Tue Oct 25 09:53:04 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * config/i386/tm-nbsd.h: Enable longjmp support. - -Sat Oct 22 03:41:13 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * valarith.c (value_binop): Take care of ANSI `value preserving' - rule, which was not addressed by the previous change. - - * rs6000-tdep.c (skip_prologue): Handle `mr r31,r1', which is - generated by gcc-2.6, as a synonym for `oril r31,r1,0'. - - * TODO: Remove item about RS/6000 shared libraries. - -Thu Oct 20 17:35:45 1994 Stu Grossman (grossman@cygnus.com) - - * defs.h, infrun.c (wait_for_inferior), top.c: Call - target_wait_hook to allow GUI to handle blocking for inferior. Call - call_command_hook in execute_command to provide means for wrapping - commands with GUI state change updates. - - * infrun.c (wait_for_inferior): Make sure - through_sigtramp_breakpoint is non-null before deleting. - -Thu Oct 20 10:26:43 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * config/powerpc/ppc-nw.mt (TDEPFILES): Removed exec.o. - -Thu Oct 20 06:56:07 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (coffread.o): Depend on target.h. - (remote-vx.o): Depend on gdb-stabs.h objfiles.h symfile.h $(bfd_h). - -Wed Oct 19 22:49:31 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Fix typo. - -Wed Oct 19 11:32:15 1994 Jim Kingdon - - * objfiles.c (objfile_relocate): When relocating ->sections, use - objfile not symfile_objfile. - - * symtab.h, minsyms.c (minsyms_sort): New function. - * objfiles.c (objfile_relocate): Call it. - - * remote-vx.c (vx_add_symbols): Call breakpoint_re_set. - - * objfiles.c, objfiles.h (objfile_to_front): New function. - * remote-vx.c (vx_add_symbols): Call it. - - * coffread.c (coff_symtab_read): Handle common symbols the same - way that partial-stab.h does. - -Wed Oct 19 21:06:12 1994 Rob Savoye (rob@cirdan.cygnus.com) - - * hppa-tdep.c: Remove include files a.out.h, ioctl.h, and - machine/psl.h. These are host files. - -Wed Oct 19 15:13:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * objfiles.h (struct objfile): Fix comment--minimal_symbol_count - does *not* include the terminating NULL msymbol. - -Tue Oct 18 20:53:29 1994 Rob Savoye - - * monitor.c (monitor_load_srec,monitor_make_srec): Add an asrecord - loader that reads files using BFD and converts it on the fly. - -Mon Oct 17 18:52:06 1994 Rob Savoye - - * monitor.c (set_loadtype_command): Fixed so it doesn't core dump. - * monitor.c (monitor_load): check the load type and load the file - accordingly. Default to gr_load_image(). - * monitor.c (monitor_load_ascii_srec): Load an ascii file in - srecord format by downloading to the monitor. - * w89k-rom.c, op50n-rom.c: set supported load types. - -Mon Oct 17 10:29:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (ALLDEPFILES): Remove xcoffexec.c. - * Makefile.in: Remove xcoffexec.o rule. - - * exec.c (exec_file_command): Add comment. - - Fix data and bss relocation for VxWorks 5.1: - * remote-vx.c (vx_add_symbols): New function. - (vx_load_command, add_symbol_stub): Call it instead of - symbol_file_add. - (vx_wait): Remove comment which was wrong to useless. - * remote-vx.c: Reindent much of file. - * coffread.c (cs_to_section, find_targ_sec): New functions. - (process_coff_symbol): Set SYMBOL_SECTION to result - from cs_to_section. - (coff_symtab_read): Call cs_to_section and deal with result - rather than assuming sections are in a certain order. Deal with - BSS. - * coffread.c: Remove text_bfd_scnum variable. - -Sat Oct 15 16:55:48 1994 Stan Shebs (shebs@andros.cygnus.com) - - * corelow.c: Format to standard. - (core_close): Use name instead of bfd_filename. - -Fri Oct 14 10:29:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * exec.c (map_vmap): Cast return from xmalloc to its proper type, - not to PTR. - - * symfile.c (reread_symbols): Include bfd_errmsg string in error - message if bfd_close fails. - * exec.c (exec_close), solib.c (clear_solib), corelow.c - (core_close), objfiles.c (free_objfile), irix5-nat.c - (clear_solib), osfsolib.c (clear_solib), remote-utils.c - (gr_load_image): Check for errors from bfd_close. - * solib.c (look_for_base), remote-utils.c (gr_load_image), - remote-udi.c (download), corelow.c (core_open), symfile.c - (symfile_bfd_open), symfile.c (generic_load): Add comment - regarding error from bfd_close. - * remote-udi.c (download), remote-utils.c (gr_load_image): Add - comment about bogus handling of errors from bfd_openr. - * exec.c (exec_close): Add comment regarding memory leak and - dangling reference to vp->name. - -Sat Oct 15 03:43:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * eval.c (evaluate_subexp): Make fnptr a LONGEST instead - of using longest_to_int. - - * infcmd.c (run_stack_dummy): Reinstate set_current_frame call, - mips and alpha targets need the real breakpoint pc for - creating the breakpoint frame. - - * stack.c (return_command): Cast return value to the return - type of the function from which we return. - * values.c (set_return_value): Pass VALUE_CONTENTS unmodified - to STORE_RETURN_VALUE. - - * symtab.c (lookup_symbol): Remove search for `static mangled - symbols', the search for `static symbols' already looks for - mangled and demangled symbols via lookup_block_symbol. - - * valarith.c (value_binop): Use ANSI C arithmetic conversions - when performing integral evaluations, implement BINOP_EQUAL and - BINOP_LESS. - (value_equal, value_less): Use value_binop to perform the - comparison if both operands have TYPE_CODE_INT. - - * rs6000-tdep.c (pop_frame): Make sure all registers are valid, - as they are written back later. Handle sp restore for frameless - functions. Use fdata.nosavedpc instead of fdata.frameless to - determine if the pc has been saved. - (function_frame_info): Handle `mr r31,r1', which is generated by - gcc-2.6, as a synonym for `oril r31,r1,0'. - (skip_trampoline_code): Handle shared library trampolines. - * xcoffread.c (read_xcoff_symtabs): Record XMC_GL symbols with - their real name. Enables setting of breakpoints in shared libraries - before the executable is run. - -Fri Oct 14 19:39:47 1994 Rob Savoye - - * monitor.h, remote-mon.c: Hack up to so the old ROM monitor - interface code still works with the new ROM monitor - structures. Fake out a couple of fields. - -Fri Oct 14 14:54:37 1994 Stan Shebs (shebs@andros.cygnus.com) - - * h8500-tdep.c (target_read_sp, target_write_sp, target_read_pc, - target_write_pc, target_read_fp, target_write_fp): Rename to - h8500_read_sp, etc. - (h8500_read_pc, h8500_write_pc): Add pid argument. - * config/h8500/tm-h8500.h (TARGET_READ_SP, TARGET_WRITE_SP, - TARGET_READ_PC, TARGET_WRITE_PC, TARGET_READ_FP, TARGET_WRITE_FP): - Change to match functions above. - -Thu Oct 13 13:24:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * NEWS: Add item about if and while. - - * .gdbinit: Restore `end'; it was not excess. Reindent - list-objfiles to make this clear. Comment out all of - list-objfiles because old gdb's choke on it. - -Wed Oct 12 23:19:08 1994 Ian Lance Taylor - - * config/mips/tm-bigmips64.h: Just define TARGET_BYTE_ORDER and - include tm-mips64.h. - -Wed Oct 12 18:02:17 1994 Stan Shebs (shebs@andros.cygnus.com) - - * Makefile.in (ANNOTATE_OBS): New definition. - (COMMON_OBS): Add exec.o. - (annotate.o): Remove extra compile rule. - * config/*/*.mh, config/*/*.mt: Remove exec.o from *DEPFILES lists - everywhere. - - * .gdbinit: Remove excess `end'. - - * exec.c: Merge in RS6000 support from xcoffexec.c. - (symfile.h, objfiles.h, xcoffsolib.h): Include. - (vmap): New global variable. - (exec_close): Close and free objects in vmap chain. - (exec_file_command) [IBM6000_TARGET]: Set up initial vmap. - (bfdsec_to_vmap, map_vmap): Moved here from xcoffexec.c. - (exec_files_info): Print vmap information. - * xcoffexec.c: Remove. - * config/rs6000/rs6000.mt, config/rs6000/rs6000lynx.mt - (TDEPFILES): Use exec.o instead of xcoffexec.o. - * TODO: Remove pertinent items. - -Wed Oct 12 10:08:19 1994 Jeff Law (law@snake.cs.utah.edu) - - * partial-stab.h (N_TEXT): Delete GDB_TARGET_IS_HPPA kludge; they - are no longer needed as of gcc-2.6.0. - -Tue Oct 11 15:51:01 1994 Ian Lance Taylor - - * lynx-nat.c (child_wait): Correct handling of byte reversed SPARC - Lynx wait status. - (fetch_core_registers): Don't try to fetch a register if - regmap maps it to -1. - * sparc-tdep.c (sparc_frame_find_saved_regs): Use FRAME_SAVED_I0 - and FRAME_SAVED_L0 when setting saved_regs_addr. SPARC Lynx - stores the registers in a weird order. - -Sat Oct 8 20:59:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * blockframe.c (reinit_frame_cache): Reinstate select_frame call - if inferior_pid is nonzero. - -Sat Oct 8 04:27:21 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - Speed up GDB startup time by not demangling partial symbols. - * symfile.h (ADD_PSYMBOL_VT_TO_LIST), - symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list): - No longer demangle partial symbols. - * symtab.c (lookup_symbol, list_symbols): Handle mangled - variables, e.g. C++ static members, via the minimal symbols. - - Handle reordered functions in an objfile, for Irix 5.2 shared - libraries. - * objfiles.h (OBJF_REORDERED): New bit in the objfile flags, - set if the functions in an objfile are reordered. - * mdebugread.c (parse_partial_symbols): Detect reordered - functions in an objfile. - * symtab.c (find_pc_psymtab, find_pc_symtab): Use expensive - lookup algorithm if the functions in the objfile are reordered. - - * xcoffexec.c (exec_close): If the current target has a copy - of the exec_ops sections, reflect the freeing of the sections - in current_target. - - * valops.c (call_function_by_hand): Use `sizeof dummy1', not - `sizeof dummy', for constructing the call dummy code. - - * config/sparc/tm-sparc.h: Add PARAMS declarations to all - function declarations. - * sparc-tdep.c (sparc_pop_frame): Cast result of - read_memory_integer to CORE_ADDR when passing it to PC_ADJUST. - - * irix5-nat.c (enable_break): Set breakpoint at the entry point - of the executable, to handle the case where main resides in a - shared library. - * irix5-nat.c (solib_create_inferior_hook): Reset stop_soon_quietly - after shared library symbol reading, to get rid of a warning from - heuristic_proc_start if the startup code has no symbolic debug info. - - * breakpoint.h (struct breakpoint): Add new fields language - and input_radix, to enable breakpoint resetting with the - proper language and radix. - * breakpoint.c (set_raw_breakpoint): Initialize them. - (breakpoint_re_set_one): Use them when resetting the breakpoint. - (breakpoint_re_set): Preserve current language and input_radix - across breakpoint_re_set_one calls. - - * symtab.c (decode_line_1): Do not build a canonical line - specification for `*expr' line specifications. - - * breakpoint.h (bpstat_stop_status): Fix prototype declaration. - -Fri Oct 7 08:48:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - The point of these changes is to avoid reading the frame pointer - and stack pointer during stepping, to speed things up. - A. Changes to not select a frame until we need a selected frame: - * blockframe.c (flush_cached_frames): Call select_frame (NULL, -1). - * infrun.c (wait_for_inferior): Move call to select_frame back to - normal_stop. This reverts a change of 13 Apr 94 (it says Jeff - Law, but the change was my idea); the only reason for that change - was so we could save and restore the selected frame in - wait_for_inferior, and now that flush_cached frames clears the - selected frame, that should work OK now. - B. Changes to not create a current_frame until we need one: - * blockframe.c (get_current_frame): If current_frame is NULL, try - to create an innermost frame. - * sparc-tdep.c (sparc_pop_frame), infcmd.c (run-stack_dummy), - infrun.c (wait_for_inferior), thread.c (thread_switch), - convex-tdep.c (set_thread_command), a29k-tdep.c (pop_frame), - alpha-tdep.c (alpha_pop_frame), convex-xdep.c (core_file_command), - h8300-tdep.c (h8300_pop_frame), h8500-tdep.c (h8300_pop_frame), - hppa-tdep.c (hppa_pop_frame), i386-tdep.c (i386_pop_frame), - i960-tdep.c (pop_frame), m68k-tdep.c - (m68k_pop_frame), mips-tdep.c (mips_pop_frame), rs6000-tdep.c - (push_dummy_frame, pop_dummy_frame, pop_frame), sh-tdep.c - (pop_frame), config/arm/tm-arm.h (POP_FRAME), - config/convex/tm-convex.h (POP_FRAME), config/gould/tm-pn.h - (POP_FRAME), config/ns32k/tm-merlin.h (POP_FRAME), - config/ns32k/tm-umax.h (POP_FRAME), config/tahoe/tm-tahoe.h - (POP_FRAME), config/vax/tm-vax.h (POP_FRAME): Don't - call create_new_frame. - * corelow.c (core_open), altos-xdep.c (core_file_command), - arm-xdep.c (core_file_command), gould-xdep.c (core_file_command), - m3-nat.c (select_thread), sun386-nat.c (core_file_command), - umax-xdep.c (core_file_command): Don't call create_new_frame; do - call flush_cached_frames. - * blockframe.c (reinit_frame_cache): Don't call create_new_frame - or select_frame. - C. Changes to get rid of stop_frame_address and instead only - fetch the frame pointer when we need it. - * breakpoint.c (bpstat_stop_status): Remove argument - frame_address; use FRAME_FP (get_current_frame ()). - * infrun.c (wait_for_inferior): Don't pass frame pointer to - bpstat_stop_status. - * infrun.c (wait_for_inferior): Use FRAME_FP (get_current_frame - ()) instead of stop_frame_address. - * infrun.c (save_inferior_status, restore_inferior_status), - inferior.h (struct inferior_status): Don't save and restore - stop_frame_address. - * inferior.h, infcmd.c, thread.c (thread_switch), m3-nat.c - (select_thread): Remove stop_frame_address and uses thereof. - D. Same thing for the stack pointer. - * infrun.c (wait_for_inferior): Remove stop_sp and replace - uses thereof with read_sp (). - E. Change to eliminate one nasty little spot where we were - wanting to know the frame pointer from before the current step - (idea from GDB 3.5, which saved my ass, because my other ideas of - how to fix it were very baroque). - * infrun.c: Remove prev_frame_address. - * infrun.c (wait_for_inferior, step_over_function): Use - step_frame_address instead of prev_frame_address. - F. Same basic idea for the stack pointer. - * inferior.h, infcmd.c: New variable step_sp. - * infcmd.c (step_1, until_next_command): Set it. - * infrun.c: Remove prev_sp and replace uses by step_sp. - * infrun.c (wait_for_inferior): If we get out of the step - range, then set step_sp to the current stack pointer before we - start going again. - -Fri Oct 7 12:17:17 1994 Ian Lance Taylor - - * top.c (target_byte_order_auto): New static variable. - (set_endian): Mention that ``auto'' is permitted. - (set_endian_auto): New static function. - (show_endian): Change message based on target_byte_order_auto. - (set_endian_from_file): New function. - (init_main): Add command ``auto'' to endianlist. - * exec.c (exec_file_command): Call set_endian_from_file. - * defs.h (set_endian_from_file): Declare. - -Thu Oct 6 18:10:41 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * nlm/i386.c (flush_i_cache): New function, does nothing. - (frame_to_registers, registers_to_frame, set_step_traps, - clear_step_traps, do_status): Make non-static. - -Thu Oct 6 12:26:42 1994 Ian Lance Taylor - - * config/mips/tm-mips.h (GDB_TARGET_IS_MIPS64): If not already - defined, define as 0. - (FIX_CALL_DUMMY): Rewrite to remove presumption that host and - target are similar. - * config/mips/tm-idt.h (TARGET_BYTE_ORDER_SELECTABLE): Define. - * config/mips/tm-idtl.h (TARGET_BYTE_ORDER_SELECTABLE): Define. - * config/mips/tm-idt64.h (TARGET_BYTE_ORDER_SELECTABLE): Define. - (BREAKPOINT): Remove definition. - * config/mips/tm-idtl64.h (TARGET_BYTE_ORDER_SELECTABLE): Define. - (BREAKPOINT): Remove definition. - * config/mips/tm-mips64.h (GDB_TARGET_IS_MIPS64): Define with a - value of 1, rather than without a value. - * config/mips/tm-bigmips64.h (GDB_TARGET_IS_MIPS64): Likewise. - * mips-tdep.c: Rewrite uses of GDB_TARGET_IS_MIPS64 to switch at - run time rather than at compile time. - - * remote-mips.c (break_insn): Remove. - (BREAK_INSN, BREAK_INSN_SIZE): Define. - (mips_insert_breakpoint): Use BREAK_INSN, not break_insn. - (mips_remove_breakpoint): Likewise. - - * defs.h: If TARGET_BYTE_ORDER_SELECTABLE is defined by tm.h, - define TARGET_BYTE_ORDER as target_byte_order, and declare - target_byte_order as an extern int, and define BITS_BIG_ENDIAN as - a test of TARGET_BYTE_ORDER. - * top.c: Several additions if TARGET_BYTE_ORDER_SELECTABLE is - defined: - (endianlist, target_byte_order): New variables. - (set_endian, set_endian_big, set_endian_little): New functions. - (show_endian): New function. - (init_cmd_lists): Initialize endianlist. - (init_main): Add commands ``set endian big'', ``set endian - little'', and ``show endian''. - * a29k-pinsn.c: Rewrite uses of TARGET_BYTE_ORDER and - BITS_BIG_ENDIAN to switch at run time rather than at compile time. - * coffread.c, dwarfread.c, findvar.c, mips-tdep.c: Likewise. - * remote-os9k.c, stabsread.c, valarith.c, valprint.c: Likewise. - * values.c: Likewise. - -Wed Oct 5 11:41:24 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * nlm/configure.in: ${gdb_host_cpu} defaults to ${host_cpu}. - - * nlm/Makefile.in: Get rid of NWINCLUDES. - * config/{alpha,powerpc}/gdbserve.mt: Remove NWINCLUDES. - User should now configure with --with-headers. - -Mon Oct 3 07:48:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbserver/server.c (main): Silently accept all unrecognized - requests and send back a zero length acknowledge. That is what - *-stub.c do and is what remote.c expects. - -Mon Oct 3 05:11:47 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * corelow.c (core_open): Copy the modified to_sections_end - vector from current_target to core_ops too. - - * gdbserver/server.c (main): Silently accept query requests - and send back a zero length acknowledge. - -Fri Sep 30 17:17:21 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * nlm/Makefile.in: Don't define NWINCLUDES. - * config/{alpha,powerpc}/gdbserve.mt: define NWINCLUDES. - -Fri Sep 30 15:59:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbserver/low-lynx.c (create_inferior): Pass all 4 args to ptrace. - -Fri Sep 30 06:42:42 1994 Ian Lance Taylor (ian@cygnus.com) - - * lynx-nat.c (child_wait): Use status.w_status, not status, in - arithmetic. status is a `union wait'. - - * config/nm-lynx.h (PTRACE_ARG3_TYPE): Define to int, not char *. - - * lynx-nat.c (child_wait): Pass fourth argument to ptrace. - -Thu Sep 29 08:22:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (read_xcoff_symtab): Fix comment for yesterday's change. - -Wed Sep 28 17:48:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * coffread.c (complete_symtab): If last_source_file is set upon - entry, free it. - -Wed Sep 28 08:59:14 1994 Jim Kingdon (kingdon@cygnus.com) - - * xcoffread.c (read_xcoff_symtab, case C_FILE): - Set main_aux before using it. - - * xcoffexec.c (exec_close): If quitting, don't call clear_symtab_users. - - * xcoffread.c (read_xcoff_symtab): Process XTY_LD symbols we were - ignoring before. But continue to ignore XMC_DS. - -Wed Sep 28 00:35:23 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (hpread_read_array_type): Do not change the type code - to TYPE_CODE_PTR for "char foo[]". Just make it a zero length - array type. - - * hpread.c (hpread_type_translate): Handle T_UNS_LONG types with - lengths other than 32bits (HP C 9.69 represents an "unsigned char" - as an T_UNS_LONG with length 8). - - * hpread.c (struct hpread_symfile_info): Delete have_module field - and accessor macro. Minor indentation fix. - (hpread_build_psymtabs, case K_MODULE): Only start a new psymtab - and reset state variables have_name & texthigh if pst is NULL. - (hpread_build_psymtabs, case K_SRCFILE): Only reset the name of a - partial symbol table if pst is non-NULL. If pst is NULL, then - start a new psymtab. - (hpread_process_one_debug_symbol, case K_MODULE): Now empty. - (hpread_process_one_debug_symbol, case K_SRCFILE): Simplify and - correct handling of subfiles. - -Mon Sep 26 02:59:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * defs.h (misc_command_type): Remove trailing comma from - enumerator list. - -Sun Sep 25 23:19:58 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (frame_saved_pc): Fix thinko in code to dig saved pc - out of an interrupt frame. - -Sun Sep 25 12:50:17 1994 Stan Shebs (shebs@andros.cygnus.com) - - * infcmd.c (do_registers_info) [INVALID_FLOAT]: Only use if - defined. - * values.c (unpack_double) [INVALID_FLOAT]: Ditto. - * mips-tdep.c (mips_print_register): Don't test float validity. - * config/a29k/tm-a29k.h, config/alpha/tm-alpha.h, - config/arm/tm-arm.h, config/convex/tm-convex.h, - config/h8300/tm-h8300.h, config/h8500/tm-h8500.h, - config/i386/tm-i386v.h, config/i386/tm-sun386.h, - config/i960/tm-i960.h, config/m68k/tm-m68k.h, - config/m88k/tm-m88k.h, config/mips/tm-mips.h, - config/ns32k/tm-merlin.h, config/ns32k/tm-nbsd.h, - config/ns32k/tm-ns32km3.h, config/ns32k/tm-umax.h, - config/pa/tm-hppa.h, config/pyr/tm-pyr.h, - config/rs6000/tm-rs6000.h, config/sh/tm-sh.h, - config/sparc/tm-sparc.h, config/z8k/tm-z8k.h (INVALID_FLOAT): - Remove definition. - -Sun Sep 25 06:07:37 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Remove item about adding general multi-threaded stuff; - this is done. - Remove item about specifying arbitrary locations of stack frames - (this works on some machines). - Remove item about debugging functions without a frame pointer - (this works on some machines). - Remove item about re-writing macros which handle frame chaining and - frameless functions. They have been re-written at least once - since that item was written. - Remove item about gdb catching SIGINT when attached; this is done. - Remove item about having list_command not read symbols--why bother? - -Sat Sep 24 17:40:10 1994 Stan Shebs (shebs@andros.cygnus.com) - - * TODO: Append contents of Projects file. - * Projects: Remove. - -Sat Sep 24 01:47:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * corelow.c (add_solib_stub): Remove copying of to_sections, - pass current_target to SOLIB_ADD. The Sep 10 change failed - if SOLIB_ADD errored out, or if SOLIB_ADD was trying to access - target memory. - * corelow.c (core_open): After reading the shared libraries, - copy the modified to_sections vector from current_target to - core_ops, so that core_close can free it later. - * config/rs6000/nm-rs6000.h, rs6000-nat.c (xcoff_relocate_core): - Pass down target parameter from SOLIB_ADD and use it instead of - directly accessing core_ops. - -Fri Sep 23 14:58:49 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * solib.c: *BSD systems need to be included before - . - - * i386b-nat.c: Add i386_float_info(), etc. - * config/i386/nm-nbsd.h: #define FLOAT_INFO. - - * config/nm-nbsd.h: New file, for generic NetBSD native support. - * config/i386/nm-nbsd.h: Use it. - * config/sparc/nm-nbsd.h: Use it. - * config/ns32k/nm-nbsd.h: Use it. - - * configure.in (i386-*-netbsd): Use config/i386/nbsd.m[ht]. - (ns32k-*-netbsd): Use config/ns32k/nbsd.m[ht]. - * config/i386/{nbsd.mh,nbsd.mt,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h}: - New files, support for NetBSD/i386. - * config/ns32k/{nbsd.mh,nbsd.mh,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h}: - New files, support for NetBSD/ns32k. - -Tue Sep 20 11:34:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * .gdbinit: Add list-objfiles command. - - * TODO: Reword item regarding NO_STD_REGS. - - * coffread.c (record_minimal_symbol, coff_read_enum_type, - coff_read_struct_type): Allocate on symbol_obstack, not directly - via malloc/savestring. - -Tue Sep 20 15:42:02 1994 Stan Shebs (shebs@andros.cygnus.com) - - * TODO: Add more items. - * tests: Remove the directory and all of its (obsolete) contents. - -Tue Sep 20 11:34:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * coffread.c (init_stringtab): When copying length to stringtab, - use target format, not host format, since that is what the rest of - the code assumes. - -Mon Sep 19 15:48:10 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * Makefile.in: Removed prelude.o, i386-nlmstub.o, nlmstub.o, - nlmstub.nlm, and nlmstub targets. Removed NWSOURCE and - NWINCLUDES definitions. - * i386-nlmstub.c: Removed. - -Mon Sep 19 07:48:36 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dbxread.c (read_dbx_dynamic_symtab): Cast bfd_asymbol_name to - char * (from const char *) before assigning. Don't save string we - pass to record_minimal_symbol (it already saves it). - - -Sat Sep 17 02:26:58 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * cp-valprint.c (static_field_print): New variable, controls - printing of static members. - (_initialize_cp_valprint): New print set subcommand - "static-members". Turn on printing of static members by default. - (cp_print_value_fields): Print static members if necessary. - - * solib.c: Remove inclusion of libelf.h and elf/mips.h. - (elf_locate_base): Use only standard BFD functions to collect - information about the .dynamic section. Check for DT_MIPS_RLD_MAP - tag only if it got defined via the inclusion of . - - * f-exp.y: Write block for OP_VAR_VALUE. - * f-valprint.c (info_common_command): Handle `info common' - without an argument correctly. - - * c-typeprint.c (c_type_print_base): Handle template constructors. - * symtab.c (gdb_mangle_name): Handle template method mangling, - get rid of GCC_MANGLE_BUG code, which only applied to gcc-2.2.2. - -Fri Sep 16 16:06:08 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * gdbtypes.h (TYPE_INDEX_TYPE): New macro. - * ch-typeprint.c, ch-valprint.c: Use TYPE_INDEX_TYPE. - * ch-valprint.c (chill_val_print): Pass index type directly - (instead of its TYPE_TARGET_TYPE) to print_type_scalar. - * stabsread.c (read_type): Don't set TYPE_FLAG_TARGET_STUB - if the index type is a stub. - -Fri Sep 16 17:18:44 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config/i386/{i386aix.mh, i386bsd.mh, i386lynx.mh, i386sco.mh, - i386sco4.mh, i386sol2.mh, i386v.mh, i386v32.mh, i386v4.mh, - ncr3000.mh, ptx.mh, ptx4.mh}, config/m68k/{altos.mh, apollo68v.mh, - delta68.mh, dpx2.mh, hp300bsd.mh, hp300hpux.mh, m68klynx.mh, - m68kv4.mh}, config/m88k/{delta88.mh, delta88v4.mh}, - config/mips/riscos.mh, config/pa/hppahpux.mh, - config/rs6000/rs6000lynx.mh, config/sparc/{sparclynx.mh, - sun4sol2.mh}, config/tahoe/tahoe.mh, config/vax/{vaxbsd.mh, - vaxult.mh, vaxult2.mh} (REGEX, REGEX1, SYSV_DEFINE): No longer - define. - * config/i386/i386sco4.mh (MUNCH_DEFINE): No longer define. - -Fri Sep 16 15:40:34 1994 Stu Grossman (grossman@cygnus.com) - - * defs.h (QUIT): Call interactive_hook to allow GUI to interrupt. - Also, add decl for symtab_to_filename. - * source.c (symtab_to_filename): New. Returns the file - associated with a symtab. - * top.c: Define interactive_hook. Called during QUIT to animate - the GUI. - -Fri Sep 16 00:14:40 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * stabsread.c (read_type): Handle stub types for bitstrings. - * stabsread.c (read_array_type): Check for stub domain type - using TYPE_FLAG_STUB, not its length. - * gdbtypes.c (create_set_type): Handle a stub domain type. - - * ch-exp.y: Get rid of some extra non-terminals, and move - their rules into primitive_value. - * parser-defs.h: Add comment about unary postfix operators. - * ch-lang.c (chill_op_print_tab): Add '->', postfix and prefix. - * expprint.c (print_subexp): Recognize unary postfix operator. - -Wed Sep 14 18:27:42 1994 Jason Molenda (crash@phydeaux.cygnus.com) - - * remote-hms.c: use remote_debug instead of hms_silent toggle. - Add warnings about depreciation of `snoop' cmd. - -Wed Sep 14 18:18:58 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * remote-hms.c (hms_read_inferior_memory): Cope when - target sends both \r and \n. - -Wed Sep 14 17:14:57 1994 Stan Shebs (shebs@andros.cygnus.com) - - * remote-mips.c (mips_error): Place NORETURN macro correctly. - * TODO: Add item about START_INFERIOR_TRAPS_EXPECTED. - -Wed Sep 14 14:26:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (read_xcoff_symtab): Fix obsolete comment about - mst_solib_trampoline. - - * f-valprint.c (f_val_print): Change cast of valaddr from - CORE_ADDR * to char **, since that is how it is used. - - * dbxread.c (read_dbx_dynamic_symtab): Save copy of symbol names - using obsavestring, and pass that to prim_record_minimal_symbol. - Having the objfile point to bfd_asymbol_name directly doesn't work - if we save and restore a mapped symbol file. - - -Tue Sep 13 18:23:26 1994 Rob Savoye (rob@darkstar.cygnus.com) - - * w89k-rom.c, op50-rom.c, monitor.c, config/pa/hppapro.mt: New files - to add a generic ROM monitor interface, and support file for the - WinBond W89K and the Oki OP50N PA based target boards. - - -Sun Sep 11 22:34:57 1994 Jeff Law (law@snake.cs.utah.edu) - - * config/pa/tm-hppa.h (REGISTER_NAMES): Use r26-r23 for arg0-arg3. - -Sun Sep 11 04:36:47 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * irix5-nat.c, osfsolib.c, solib.c (solib_add): Simplify last - change by replacing `symbols_added' with `so_last'. - * mdebugread.c (parse_external, parse_partial_symbols): Ignore - global common symbols, they will be resolved by the runtime loader. - * mdebugread.c (parse_symbol, parse_partial_symbols, cross_ref): - Handle scSCommon like scCommon symbols. - -Sat Sep 10 01:43:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * corelow.c (add_solib_stub): Copy to_sections changes from - core_ops to current_target after adding the shared libraries. - * partial-stab.h (N_EXCL), dbxread.c (add_old_header_file, - find_corresponding_bincl_psymtab): Change `repeated header not seen' - error to a complaint, simplify complaint. - * procfs.c (signalname, errnoname): Make `name' const. - * symfile.c (reread_symbols): Use filename from old BFD to - reopen the objfile. - * values.c (record_latest_value): Don't record value in the - history chain until we are sure there won't be an error. - -Fri Sep 9 15:52:09 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * nlm/Makefile.in: remove MMALLOC, READLINE, TERMCAP, and other - cruft. - - * config/i386/gdbserve.mt: New file, defs for i386 nlm stub. - -Thu Sep 8 17:14:43 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * remote.c (fromhex): Make error more explicit. - (read_frame): Don't print bad checksum information unless - remote_debugging. Don't use repeat count unless it's > 0. - * remote-e7000.c (expect): When echoing, ignore multiple newlines. - (e7000_insert_breakpoint, e7000_remove_breakpoint, target_ops): - Optionally cope with BC style breakpoints. - (e7000_command): After command send directly to the E7000 mark - registers as changed. - (why_stop, e7000_wait: Understand BC style stop condition. - * sh-tdep.c (sh_skip_prologue): Understand more complicated - sequences. (frame_find_saved_regs): Likewise. - * config/h8500/tm-h8500.h (target_write_pc, TARGET_WRITE_PC): - Handle extra arg. - * config/i386/xm-go32.h (GDBINIT_FILENAME): Set to gdb.ini. - (more work here to come) - * config/sh/tm-sh.h (EXTRA_FRAME_INFO): Add f_offset and leaf_function - fields. - -Thu Sep 8 16:15:34 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * sparclite/Makefile.in: Assorted stuff needed for eload. - - * sparclite/eload.c: Merge in command line argument parsing and - error message handling improvements orignally made to aload.c. - -Wed Sep 7 23:24:50 1994 Jeff Law (law@snake.cs.utah.edu) - - * defs.h (enum misc_command_type, command_control_type): Enums - for describing the command and control types. - (struct command_line): Add new fields to keep track of the command - type and body associated with the command. - * top.c: Include value.h. Delete whitespace at the end of lines. - (build_command_line, get_command_line): New functions. - (execute_control_command, while_command, if_command): Likewise. - (realloc_body_list, read_next_line): Likewise. - (recurse_read_control_structure): Likewise. - (execute_user_command): Call execute_control_command. - (read_command_lines): Simplify by calling read_next_line, call - read_control_structure for "if" and "while" commands. - (free_command_lines): Free new fields in the command structure. - (define_command): Reset control_level to zero. - (init_main): Install command handlers for "if" and "while" commands. - -Tue Sep 6 16:24:07 1994 Stan Shebs (shebs@andros.cygnus.com) - - * c-typeprint.c (c_type_print_varspec_prefix, - c_type_print_varspec_suffix): Add cases for Fortran type codes. - * eval.c (evaluate_subexp): For OP_ARRAY expressions in Fortran, - call f77_value_literal_string instead. - * f_exp.y: Include , move include of parser-defs.h. - (parse_number): Translate 'd' floats to 'e' so atof() works. - (yylex): Remove unused variables. - * f-lang.c: Include . - (get_bf_for_fcn): Remove unused variable. - * f-typeprint.c (f_type_print_varspec_prefix, - f_type_print_varspec_suffix): Remove unused - variables, add cases to switch statements. - (f_type_print_base): Remove unused variables. - * f-valprint.c (gdbcore.h, command.h): Include. - (f77_get_dynamic_lowerbound, f77_get_dynamic_upperbound): - Call read_memory_integer with correct number of arguments. - (f77_get_dynamic_upperbound): Call f77_get_dynamic_lowerbound - with correct argument type. - (f77_print_array): Removed unused array array_size_array. - (f_val_print): Don't use a CORE_ADDR as a char *. - * valops.c (value_cast): Handle COMPLEX and BOOL types. - (value_assign): Handle Fortran literal string and complex values. - (f77_cast_into_complex, f77_assign_from_literal_string, - f77_assign_from_literal_complex): New functions. - -Mon Sep 5 14:46:41 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * ch-typeprint.c (chill_type_print_base): Make TYPE_CODE_RANGE - case more robust. - -Sun Sep 4 16:06:34 1994 Stan Shebs (shebs@andros.cygnus.com) - - * i960-tdep.c (signal.h): Don't include. - - * cxux-nat.c (target_is_m88110): Remove definition. - - * configure.in (config/nm-empty.h): If cross only, use instead - of config/nm-trash.h. - * config/nm-trash.h: Remove. - * config/nm-empty.h: New file. - * config/i386/nm-m3.h: New file, includes config/nm-m3.h. - * config/mips/nm-m3.h: New file, includes config/nm-m3.h. - * config/m68k/nm-sysv4.h: New file, includes config/nm-sysv4.h. - * config/mips/nm-sysv4.h: New file, includes config/nm-sysv4.h. - * config/sparc/nm-sysv4.h: New file, includes config/nm-sysv4.h. - - -Fri Sep 2 17:35:55 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * configure.in: No longer look for nm, tm, and xm headers in - config/
; they are always in config//
. - -Fri Sep 2 16:40:03 1994 Stan Shebs (shebs@andros.cygnus.com) - - * objfiles.c (allocate_objfile): Add the newly-created objfile to - the end of the list of objfiles, instead of at the beginning. - - * xcoffread.c (allocate_include_entry): New function, abstracted - from code in record_include_begin. - (record_include_begin, record_include_end): Call it. - - * blockframe.c (reinit_frame_cache): Test inferior_pid instead of - target_has_stack to decide whether to create a real stack frame - for the cache. - - * coffread.c (process_coff_symbol) [CXUX_TARGET]: Ignore vendor - section. - * config/m88k/tm-cxux.h (CXUX_TARGET): Define. - - * h8300-tdep.c: Include "dis-asm.h" instead of . - -Fri Sep 2 09:51:46 1994 J.T. Conklin (jtc@cygnus.com) - - * config/sparc/tm-nbsd.h: Add #defines to map NetBSD struct and - field names into what is expected by sparc-nat.c. - -Thu Sep 1 17:32:54 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * c-typeprint.c (c_typedef_print): Add missing Chill support. - -Thu Sep 1 15:41:21 1994 Stu Grossman (grossman@cygnus.com) - - * rs6000-pinsn.c (print_insn): Use powerpc disassembler when - doing Power PC. - * config/powerpc/tm-ppc-nw.h: Define GDB_TARGET_POWERPC. - - * config/i386/i386lynx.mh, config/m68k/m68klynx.mh, - config/rs6000/rs6000lynx.mh, config/sparc/sparclynx.mh: Enable - ser-tcp. - - * nlm/Makefile.in: Get rid of NWSOURCE. - * nlm/alpha-io.S (inVti, outVti): Remove extraneous ldha's. - * nlm/gdbserve.o: Add dummy __main routine. - * nlm/gdbserve.def: Turn on debug. - -Thu Sep 1 12:36:39 1994 Jim Kingdon (kingdon@cygnus.com) - - * config/xm-nbsd.h: Don't define SET_STACK_LIMIT_HUGE; it is obsolete. - -Thu Sep 1 11:01:40 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * config/tm-nbsd.h: New file, support for all NetBSD targets. - * config/xm-nbsd.h: fix typo. - * config/sparc/{nm,tm,xm}-nbsd.h: New files, renamed from - {nm,tm,xm}-sparcnbsd.h to conform to prefered file naming - conventions. - * configure.in: (sparc-*-netbsd): use config/sparc/nbsd.m[ht]. - -Wed Aug 31 14:40:33 1994 Jason Molenda (crash@phydeaux.cygnus.com) - - * remote-udi.c (udi_read_inferior_memory,udi_write_inferior_memory): - change typeo in error msg (`inferrior' -> `inferior'). - -Wed Aug 31 09:17:02 1994 Jim Kingdon (kingdon@cygnus.com) - - * inflow.c (set_sigint_trap, clear_sigint_trap): Check for - attach_flag (this check was performed by the callers). Also check - inferior_thisrun_terminal. - * inftarg.c (child_wait), lynx-nat.c (child_wait), - procfs.c (wait_fd), symm-nat.c (child_wait): Don't check - attach_flag in deciding whether to call set_sigint_trap and - clear_sigint_trap. - - * value.h (struct value): Change literal_data from PTR to char *, - since that is the way it is used. - -Tue Aug 30 21:56:54 1994 Jeff Law (law@snake.cs.utah.edu) - - * somread.c (som_symfile_read): Force unwinds to be re-read after - reading in a new partial symbol table. - -Tue Aug 30 13:14:16 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config/h8500/tm-8500.h (DONT_USE_REMOTE): Remove definition, - an obsolete conditional. - * config/pa/tm-hppa.h (BREAKPOINT) [KERNELDEBUG]: Remove use, - an obsolete conditional. - * config/rs6000/rs6000.mh, config/rs6000/rs6000.mt: Clean up - comments. - -Mon Aug 29 14:39:42 1994 Stan Shebs (shebs@andros.cygnus.com) - - * Makefile.in (ns32k-opcode.h): Remove reference. - (ns32k-pinsn.o): Update dependencies. - * ns32k-opcode.h: Remove file. - * ns32k-pinsn.c (print_insn): Call version in libopcodes, remove - all other code in this file. - -Mon Aug 29 12:04:07 1994 Stu Grossman (grossman@cygnus.com) - - * nlm/configure.in: Stop using cpu.c. Put it in TDEPFILES instead. - * config/alpha/gdbserve.mt (TDEPFILES): Remove alpha-patch.o. - - * nlm/Makefile.in: Add rule for .S.o. - * nlm/aio.h: Protect from multiple inclusions. - * nlm/alpha-io.S: Remove everything we don't need. - * nlm/{alpha-patch.c, alpha-patch.h, alpha-uart.c, alpha-uart.h}: - Remove, no longer needed. - * nlm/alpha.c: Merge in lots of stuff from previous files. - * nlm/alpha.h: Don't #include alpha-patch.h. Make - breakpoint_insn extern. - * Move stuff from alpha-patch.h into here. - - * config/alpha/gdbserve.mt (TDEPFILES): Get rid of alpha-uart.o. - -Mon Aug 29 11:34:34 1994 Jim Kingdon (kingdon@cygnus.com) - - * annotate.c (annotate_starting): Flush output. - -Sat Aug 27 23:32:43 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symfile.c (symbol_file_add): Move reinit_frame_cache call to - the callers of symbol_file_add. Gets rid of heuristic fence-post - warnings on mips and alpha targets when the PC resides in a shared - library which is not yet read in. - * coff-solib.c (coff_solib_add), cxux-nat.c (add_shared_symbol_files), - irix5-nat.c (solib_add), osfsolib.c (solib_add), - remote-vx.c (vx_open), solib.c (solib_add): - Add call to reinit_frame_cache after all shared libraries are read in. - * remote-udi.c (udi_load), remote-vx.c (vx_load_command), - symfile.c (symbol_file_command, add_symbol_file_command): - Add call to reinit_frame_cache after symbol_file_add. - -Wed Aug 24 17:45:14 1994 J.T. Conklin (jtc@cygnus.com) - - * config/xm-nbsd.h: New file, support for all NetBSD ports. - * config/sparc/{nm-sparcnbsd.h,tm-sparcnbsd.h,xm-sparcnbsd.h, - sparcnbsd.mh,sparcnbsd.mt}: New files, support for NetBSD/sparc. - * configure.in: Add sparc-*-netbsd target. - -Wed Aug 24 13:17:34 1994 Stan Shebs (shebs@andros.cygnus.com) - - * remote-vx.c (vx_attach): Interpret the command argument as an - unsigned long. - -Wed Aug 24 13:08:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure.in: Change i[34]86 to i[345]86. - * nlm/configure.in: Likewise. - * gdbserver/configure.in: Likewise. - -Wed Aug 24 09:41:09 1994 J.T. Conklin (jtc@cygnus.com) - - * configure.in (i386-*-netware): Automatically configure nlm - subdir. - -Tue Aug 23 17:51:13 1994 J.T. Conklin (jtc@cygnus.com) - - * nlm/gdbserve.c: conditionalize header file inclusion for either - NetWare 4.0 or PIN targets. - * nlm/i386.c: include appropriate header files. - * nlm/prelude.c: define TERMINATE_BY_UNLOAD for NetWare 4.0 - targets. - -Tue Aug 23 16:54:16 1994 Stu Grossman (grossman@cygnus.com) - - * nlm/ppc.c (set_step_traps clear_step_traps): Cleanups. - * nlm/gdbserve.def: Autoload clib. - -Tue Aug 23 12:05:19 1994 Jim Kingdon (kingdon@cygnus.com) - - * breakpoint.c (condition_command): Call breakpoints_changed. - - * gdbtypes.h: Declare f77_create_literal_string_type and - f77_create_literal_complex_type. - * valops.c (f77_value_literal_string, f77_value_substring, - f77_value_literal_complex): Use xmalloc not malloc. - * valops.c (f77_value_literal_string, f77_value_substring): - Make addr char * not CORE_ADDR. - * value.h (struct value): Add new field literal_data of aligner union. - (VALUE_LITERAL_DATA): Use it. - * f-lang.h: Declare find_common_for_function. - * value.h, valops.c: Split VALUE_SUBSTRING_START into memaddr and - myaddr fields of a union. Don't overload it with the frame field - (not sure this is necessary; I'm not sure what lval_* codes - VALUE_SUBSTRING_* can be used with). - -Mon Aug 22 11:45:01 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config/a29k/{a29k-kern.mt,a29k-udi.mt,a29k.mt,ultra3.mh, - ultra3.mt}: Clean up comments, remove no-longer-used definitions. - - * rs6000-nat.c: Include libbfd.h again, needed until reference - to bfd_cache_lookup is cleaned out. - - * config/i386/linux.mh (XM_CLIBS): Add -lm. - -Mon Aug 22 10:42:15 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - Work to reduce the interrupts-off duration when running in DOS. - * ser-go32.c: (dos_async_ready): See if anything is in the buffer. - (dos_async_rx): rewrite to unpack as many characters from the - asynctsr as possible into a local buffer. - -Fri Aug 19 14:55:45 1994 Stan Shebs (shebs@andros.cygnus.com) - - Initial Fortran language support, adapted from work by Farooq Butt - (fmbutt@engage.sps.mot.com). - * Makefile.in: Add Fortran-related files and dependencies. - * defs.h (language_fortran): New language enum. - * language.h (_LANG_fortran): Define. - (MAX_FORTRAN_DIMS): Define. - * expression.h: Reformat to standard. - (MULTI_F77_SUBSCRIPT, OP_F77_UNDETERMINED_ARGLIST, - OP_F77_LITERAL_COMPLEX, OP_F77_SUBSTR): New expression opcodes. - * gdbtypes.h (TYPE_CODE_COMPLEX, TYPE_CODE_LITERAL_COMPLEX, - TYPE_CODE_LITERAL_STRING): New type codes. - (type): New fields upper_bound_type and lower_bound_type. - (TYPE_ARRAY_UPPER_BOUND_TYPE, TYPE_ARRAY_LOWER_BOUND_TYPE, - TYPE_ARRAY_UPPER_BOUND_VALUE, TYPE_ARRAY_LOWER_BOUND_VALUE): New - macros. - (builtin_type_f_character, etc): Declare. - * value.h (VALUE_LITERAL_DATA, VALUE_SUBSTRING_START): Define. - * f-exp.y: New file, Fortran expression grammar. - * f-lang.c: New file, Fortran language support functions. - * f-lang.h: New file, Fortran language support declarations. - * f-typeprint.c: New file, Fortran type printing. - * f-valprint.c: New file, Fortran value printing. - * eval.c (evaluate_subexp): Add code for new expression opcodes, - fix wording of error message. - * gdbtypes.c (f77_create_literal_complex_type, - f77_create_literal_string_type): New functions. - * language.c (set_language_command): Add Fortran info. - (calc_f77_array_dims): New function. - * parse.c (length_of_subexp, prefixify_subexp): Add cases for new - expression opcodes. - * symfile.c (deduce_language_from_filename): Recognize .f and .F - as Fortran source files. - * valops.c (f77_value_literal_string, f77_value_substring, - f77_value_literal_complex): New functions. - -Fri Aug 19 13:35:01 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-typeprint.c (c_print_type): Assume demangled arguments - if a '(' is found in varstring, looking for ')' at the end of - varstring did fail with demangled const member functions, which - have a trailing `const'. - * remote.c (get_offsets, putpkt): Change to `char' buffers, - to avoid errors when compiling with DEC c89. - (remote_wait): Cast to `char *' before passing buffer to - fputs_filtered, to avoid errors when compiling with DEC c89. - (remote_wait): Do not return inferior_pid by default, this - statement is never reached, which causes warnings from some - compilers. - * stabsread.c (scan_file_globals): Ignore static minimal symbols. - * symfile.c (load_command): If called with no argument, try - to get the filename from the executable file. - (generic_load): Remove check for NULL filename, it is done - in load_command now. - -Fri Aug 19 10:36:15 1994 Jeff Law (law@snake.cs.utah.edu) - - * Makefile.in (ALLDEPFILES): Add hpread.c. - (hpread.o): Add dependencies. - - * somread.c: Do not include "aout/aout64.h". SOM has nothing to - do with a.out. - (BYTES_IN_WORD): Delete. - (som_symfile_read): Call hpread_build_psymtabs to build any - minimal symbols based on the HP C native debug symbols. - (som_symfile_finish): Call hpread_symfile_finish. - (som_symfile_init): Call hpread_symfile_init. - * config/pa/tm-hppa.h (HPREAD_ADJUST_STACK_ADDRESS): Define. - * hppa-tdep.c (hpread_adjust_stack_address): New function. - - * config/pa/hppabsd.mh (NATDEPFILES): Add hpread.o - * config/pa/hppahpux.mh (NATDEPFILES): Likewise. - * hpread.c: New file. - -Fri Aug 19 00:40:55 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (skip_trampoline_code): Revert incorrect change - from June 2, 1994 (what was I thinking?!?). Fix it right this - time. - -Thu Aug 18 17:01:35 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * nlm/i386.c, nlm/i386.h: New files that contain i386 specific code. - -Thu Aug 18 14:39:46 1994 Stan Shebs (shebs@andros.cygnus.com) - - * README: Grammar improvements, clarifications, updates. - -Wed Aug 17 23:08:53 1994 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (TARGET_FLAGS_TO_PASS): Pass down LD_FOR_TARGET and - NLMCONV_FOR_TARGET. (SUBDIRS): Add nlm target. - * configure.in (powerpc-*-netware*): Automatically configure nlm - subdir. - * nlm/Makefile.in: Add {CC NLMCONV LD}_FOR_TARGET. Remove alpha - specific stuff. Make things more configurable. - * nlm/configure.in: Add powerpc-*-netware* target. Use - gdbserve.mt/cpu.c/cpu.h for target stuff. Get rid of tm/xm/nm.h - files. - * nlm/gdbserve.c: Move Alpha specific stuff into other files. - Remove lots of architecture-specific stuff. - * nlm/gdbserve.def: Add new imports. - * nlm/ppc.c, nlm/ppc.h: New files that contain PowerPC specific code. - * nlm/prelude.c: Don't include libhooks.h, get rid of call to - register library. - * nlm/prelude.o: What was this doing here? - * config/alpha/gdbserve.mt: Defs for alpha nlm stub. - * config/powerpc/gdbserve.mt: Defs for PowerPC nlm stub. - * config/powerpc/ppc-nw.mt: Defs for PowerPC target for GDB. - * config/powerpc/tm-ppc-nw.h: Ditto. - - * nlmstub.def: New file, contains imports for 386 nlm stub. - -Wed Aug 17 23:17:33 1994 Rob Savoye (rob@darkstar.cygnus.com) - - * remote-pa.c: New file for HPPA embedded support. Currently it's - a copy of remote.c. - * config/pa/hppabsd.mt,hppahpux.mt,hppaosf.mt: User remote-pa.c. - -Wed Aug 17 13:19:52 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config/m68k/tm-delta68.h (EXTRACT_RETURN_VALUE, - STORE_RETURN_VALUE): Define to use %a0 for pointers. - -Wed Aug 17 07:43:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-mips.c: Remove unused declaration of mips_load. - -Tue Aug 16 16:45:34 1994 Stan Shebs (shebs@andros.cygnus.com) - - * coffread.c: General cleanup, and support for section offsets. - (time.h, sys/types.h, libbfd.h): Don't include. - (cur_src_start_addr, cur_src_end_addr): Rename to - current_source_start_addr, current_source_end_addr. - (nlist_stream_global): Remove. - (nlist_bfd_global): New global variable. - (coff_symfile_read): Remove code that gets and uses fileno() - directly. - (read_coff_symtab, enter_linenos, process_coff_symbol): Add - section_offsets parameter, add text/data section offset to - appropriate symbols' values. - (read_one_sym): Use bfd_read instead of fread. - (init_stringtab, init_lineno): Change first parameter to a bfd, - use bfd routines instead of raw I/O. - -Tue Aug 16 15:24:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.c (decode_line_1): If funfirstline and we get a - non-LOC_BLOCK symbol (e.g. variable or type), then error(). - - * Makefile.in (TARFILES, NONSRC, SFILES_STAND, SFILES_KGDB): - Remove; unused. - (TAGFILES_NO_SRCDIR): Remove ALLPARAM. - (HFILES_NO_SRCDIR): Remove all files in config sub-directory. - (TAGS): Also pass result of find on config sub-directory to etags. - (ALLPARAM): Remove; now unused. - -Sun Aug 14 13:05:26 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.13.1 - * NEWS, README: Update to match gdb 4.13 release version. - -Sat Aug 13 08:22:50 1994 Fred Fish (fnf@cygnus.com) - - Harris CX/UX support, from Bob Rusk (rrusk@mail.csd.harris.com). - * cxux-nat.c: Remove dangling #else block. - (m88k_harris_core_register_addr): New function. - - * environ.c (init_environ): If no environment, do nothing. - -Fri Aug 12 19:30:53 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Delete rest of TODO list. Do not include "libbfd.h", - , , "demangle.h", , - "expression.h", "language.h", "gdbtypes.h", "demangleh". - Move all global variables into the private symbol table structure - and add accessor macros. Update some comments. - (hpread_build_psymtabs): Delete dbsubc_addr, we don't need it. - (hpread_end_psymtab): New function to end a partial symbol table, - all callers changed (no more bogus sharing with dbxread.c). - -Fri Aug 12 15:52:37 1994 Stu Grossman (grossman@cygnus.com) - - * remote.c (remote_wait): Return inferior_pid instead of 0 for - `W` message. - -Fri Aug 12 11:47:10 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * sparclite/aload.c (sys_error, error): Use vfprintf for variable - argument lists. - -Thu Aug 11 04:06:42 1994 Doug Evans (dje@canuck.cygnus.com) - - * defs.h (concat, basename, buildargv, freeargv, strerrno, strsigno, - errno_max, signo_max, strtoerrno, strtosigno): Delete. - Include "libiberty.h" instead. - -Wed Aug 10 13:23:47 1994 Rick Sladkey (jrs@world.std.com) - - * i386v-nat.c (i386_insert_nonaligned_watchpoint): - add additional argument specifying raw address to permit - proper release of debug registers. - (i386_insert_watchpoint, i386_insert_aligned_watchpoint): - change all callers. - -Wed Aug 10 16:13:45 1994 Stu Grossman (grossman@cygnus.com) - - * defs.h, top.c: Use `extern' in declarations of GUI hooks, and - define them in top.c. Add comments to the hooks. - -Wed Aug 10 15:57:43 1994 Doug Evans (dje@canuck.cygnus.com) - - * remote-sim.c (gdbsim_ops): Set `to_insert_breakpoint' and - `to_remove_breakpoint' fields. - -Wed Aug 10 15:46:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infcmd.c (run_command): Remove comment suggesting using - target_has_execution instead of inferior_pid. - -Wed Aug 10 10:33:20 1994 Kung Hsu (kung@mexican.cygnus.com) - - * remote-mips.c (mips_open): add code to handle baud rate. - -Tue Aug 9 09:44:42 1994 Stu Grossman (grossman@cygnus.com) - - * infrun.c (wait_for_inferior): Call target_resume() upon - detection of new processes. - - * procfs.c (create_procinfo): Return pointer to new procinfo - structure. - * (do_detach): Spacing & formatting cleanup. - * (procfs_wait): Move wait_again label to ensure that we really - wait again. On exit from fork, release new child from gdbs' - clutches. - * (procfs_set_sproc_trap): Enable trapping of fork and vfork. - -Mon Aug 08 15:34:13 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (hpread_process_one_debug_symbol): Fix block scoping - problem (losing localvars on the close-brace instead of after - the close brace). - -Mon Aug 8 15:09:32 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * i386-nlmstub.c (handle_exception): Wait until the thread has - been started before killing the NLM by pointing the PC at - _exit(). - -Sat Aug 6 22:27:30 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/tm-irix5.h (IN_SIGTRAMP): Redefine for Irix 5, - Irix 5 has a standard _sigtramp signal handler. - * irix5-nat.c (solib_add): Get rid of sigtramp_address handling, - it is not needed for a standard _sigtramp signal handler. - Add shared library sections to the section table of the target - before adding the symbols. - * mips-tdep.c (mips_skip_prologue): Do not skip load immediate - instructions that do not prepare a stack adjustment. - * regex.c (SIGN_EXTEND_CHAR): Update to emacs-19.25 definition, - which does the right thing on machines where `char' is unsigned. - -Fri Aug 5 17:50:59 1994 Stu Grossman (grossman@cygnus.com) - - * remote.c (remote_open): Move setting of inferior_pid prior to - call to remote_start_remote. Also use unique value for pid to - avoid confusion with read_register_pid & friends. - * (remote_wait): Return inferior_pid instead of 0 in all cases. - -Fri Aug 5 12:23:02 1994 Stan Shebs (shebs@andros.cygnus.com) - - * dwarfread.c (bfd.h): Don't include. - -Fri Aug 5 09:08:34 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * i386-nlmstub.c (handle_exception): Point the PC at _exit() to - kill the program being debugged. KillMe(), the undocumented - call intended for this purpose, causes the server to hang. - -Thu Aug 4 16:26:06 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * remote.c (read_frame): Calculate run length encoded checksum - correctly. - * config/sh/stub.c: New file. - -Thu Aug 4 14:34:12 1994 Stu Grossman (grossman@cygnus.com) - - * target.c (find_default_run_target): Make sure to_can_run is set - before calling it. - -Thu Aug 4 11:46:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * TODO: Remove note about fast watchpoints and remove obsolete - Mach stuff. - -Thu Aug 4 11:08:03 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config/i386/xm-i386v4.h, config/m68k/xm-m68kv4.h, - config/sparc/xm-sun4sol2.h (NORETURN): Don't define. - * config/m88k/tm-cxux.h (ARCH_NUM_REGS): Undefine before defining. - -Thu Aug 4 10:26:36 1994 Stu Grossman (grossman@rtl.cygnus.com) - - * target.c (add_target): Don't call clean_target on target - vectors anymore. - * (unpush_target): Test for to_close being set before calling. - * (target_xfer_memory, target_info): Check for to_has_memory - before playing with memory. - - * remote.c (remote_open): Set inferior_pid to make kill command - happy. - * inflow.c (kill_command): Revert change of Aug 2. Use - inferior_pid to determine whether to print out "The program is not - being run." message. - -Thu Aug 4 07:55:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/i386/i386m3.mh (NAT_CLIBS): Add -lmachid and -lnetname. - * m3-nat.c, config/nm-m3.h: #if 0 REQUEST_QUIT stuff. - * m3-nat.c: Pass argument to return_to_top_level. - Declare m3_kill_inferior before use. - (port_chain_insert): In "can't happen" case, abort rather than - setting `mid' to large decimal constant (which gcc warns about). - (get_thread_name): Use cast to convert const char * to char *. - (add_mach_specific_commands): #if 0 "thread break" command. - (m3_trace_him): Call push_target. - (mach_really_wait): New argument pid; remove unused - variable pid. - (intercept_exec_calls): Call target_terminal_init and - target_terminal_inferior once the child execs. - * infrun.c (proceed): Pass argument to PREPARE_TO_PROCEED. - -Wed Aug 3 22:41:13 1994 Tom Lord (lord@x1.cygnus.com) - - * procfs.c (procfs_mourn_inferior): don't dereference the - procinfo pointer after it has been freed. - -Wed Aug 3 12:05:13 1994 Stan Shebs (shebs@andros.cygnus.com) - - * breakpoint.c (breakpoint_1): Improve pluralization in display - of breakpoint hit counts. - - * language.h (struct language_defn): Remove unused field - la_longest_float. - (longest_float): Remove, no longer used. - * language.c (unknown_language_defn, auto_language_defn, - local_language_defn): Remove init of la_longest_float field. - * c-lang.c (c_language_defn, cplus_language_defn, - asm_language_defn): Ditto. - * ch-lang.c (chill_language_defn): Ditto. - * m2-lang.c (m2_language_defn): Ditto. - -Tue Aug 2 10:58:34 1994 Stan Shebs (shebs@andros.cygnus.com) - - * defs.h (bfd_read, bfd_seek): Remove declarations. - * os9kread.c, rs6000-nat.c (libbfd.h): Don't include. - -Tue Aug 2 09:50:50 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * inflow.c (kill_command): Fix a bug which prevented target - programs to be killed. - -Mon Aug 1 18:48:47 1994 Stan Shebs (shebs@andros.cygnus.com) - - * defs.h: Change two-line declarations to one-line form. - (NORETURN): Define as "volatile" only for older GCCs. - (ATTR_NORETURN): Define for newer GCCs. - * procfs.c (proc_init_failed): Add ATTR_NORETURN to declaration. - -Mon Aug 1 16:43:24 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (mention), main.c (fputs_unfiltered): Add comments. - * breakpoint.c (delete_breakpoint, enable_breakpoint, - disable_breakpoint): Don't call breakpoints_changed; it is now - called via the *_breakpoint_hook functions. - * annotate.c (_initialize_annotate, breakpoint_changed): New functions. - -Mon Aug 1 13:38:04 1994 Kung Hsu (kung@mexican.cygnus.com) - - * stabsread.c (read_type): Fix a bug in enum size calculation. - -Mon Aug 1 01:36:13 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (compare_unwind_entries): Add "const" to both - argument types to shut up GCC. - - * hppa-tdep.c (saved_pc_after_call): If the saved PC is in a - linker stub, then return the address the stub will return to. - (frame_saved_pc): Correctly restart the search for the saved - pc when a linker stub is encountered. - - * hppa-tdep.c (inst_saves_gr): Handle 16 and 8 bit instruction - register stores emitted by the version 9 HP compilers. - (inst_saves_fr): Relax test for a specific base register (%r1); - this avoids losing with the version 9 HP compilers. - (skip_prologue): Try to skip argument stores emitted by the HP - compilers. It's not perfect, but it's better than before. - -Fri Jul 29 23:20:30 1994 Stu Grossman (grossman@cygnus.com) - - * findvar.c (write_pc write_pc_pid): Remove casts to long when - calling write_register_pid. - * (write_register_pid): Add prototype. - -Fri Jul 29 21:56:23 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * remote.c (read_frame): Split readchar/checksum calculation into - two parts since evaluation order is undefined. - -Fri Jul 29 13:46:08 1994 Fred Fish (fnf@cygnus.com) - - From Kevin A. Buettner (kev@cujo.geg.mot.com). - * Makefile.in (coredep.o): Add inferior.h as dependency. - * inflow.c: Add F_SETOWN to list of defines to check - around code that uses F_SETOWN. - -Fri Jul 29 09:59:05 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): If using newlib, - set the -L and -B directory prefixes so we can link with it. - -Thu Jul 28 14:37:36 1994 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (INSTALLED_LIBS, CLIBS, DEPFILES): Add support for - --enable-xxx configure option by adding ENABLE_{CLIBS DEPFILES} - where appropriate. - - * General hackery to support alternate user-interface. - * breakpoint.c (mention, delete_breakpoint, enable_breakpoint, - disable_breakpoint): Call hooks for alternate user-interface. - * defs.h: Add declarations for alternate user-interface hooks. - * main.c (main): Add --nw (and --nowindows) options to disable - the GUI. - * (near call to command_loop): Call command_loop_hook if set. - * (fputs_unfiltered): Call fputs_unfiltered_hook if set. - * stack.c: Call print_frame_info_listing_hook if set. - * top.c (gdb_init): Initialize targets.c and utils.c prior to - other files to make sure that calls to error and warning will - work. Call init_ui_hook after everything else. - * utils.c (query): Call query_hook if set. - * (gdb_flush): Call flush_hook if set. - * Change _initialize_utils to initialize_utils cuz we don't use - automatic initialization of utils.c anymore. - - - * remote.c: Get rid of #ifdef DONT_USE_REMOTE. It's no longer - necessary. - -Thu Jul 28 14:52:01 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Use newlib if it is - there and we are using the gcc from the tree. - (LD_FOR_TARGET): Look for ld in ../ld/ld.new. - -Thu Jul 28 10:43:36 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (annotate.o): Add dependencies. - -Wed Jul 27 14:34:42 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * sparclite/aload.c: Added new -q (quiet) option. - return 0 exit status if file was successfully downloaded. - - * nlm/gdbserve.c: merge in command line argument parsing changes - and bug fixes made to i386-nlmstub.c. - - * i386-nlmstub.c: The returnLength field must be initialized - before portConfig is passed to AIOGetPortConfiguration. - Compare command line arguments with strnicmp(); args are - case insensitive on netware. - -Wed Jul 27 09:24:19 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (DISTSTUFF): Add definition. - (diststuff): Add for new distribution support. - (gdb.tar.Z, make-proto-gdb.dir, setup-to-dist, - gdb-$(VERSION).tar.Z, make-proto-gdb-1, make-proto-testsuite.dir): - Remove old distribution building rules, now uses standard - distribution support in parent directory Makefile.in. - -Tue Jul 26 14:15:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * target.c (push_target): Cast result from xmalloc. - -Tue Jul 26 18:20:46 1994 Paul Flinders (ptf@smee) - - * elfread.c (elf_symtab_read): Discard compiler labels generated - by the Solaris 2.1/Intel SunPro compiler. - -Mon Jul 25 18:19:24 1994 Stu Grossman (grossman@cygnus.com) - - * target.c (nomemory): Fix prototype and routine to take correct - args. - -Mon Jul 25 15:38:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (clean): Remove libgdb-files. - -Mon Jul 25 11:50:57 1994 Stan Shebs (shebs@andros.cygnus.com) - - * coredep.c: Include inferior.h. - -Mon Jul 25 11:36:02 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * i386-nlmstub.c: Add support for NODE, PORT and BAUD command - line arguments. - -Sat Jul 23 14:36:09 1994 Stan Shebs (shebs@andros.cygnus.com) - - * symfile.c (deduce_language_from_filename): Recognize .S as asm, - .cp as C++, alphabetize better. - - * breakpoint.c (ignore, condition): Move usage note into body of - help text, so first line can be one-line summary. - -Sat Jul 23 00:58:15 1994 Stu Grossman (grossman@cygnus.com) - - * target.c (unpush_target): Fix handling of removal of top target. - -Fri Jul 22 17:30:39 1994 Stu Grossman (grossman@cygnus.com) - - * Makefile.in: Add stuff to build nlmstub. - * Add rule for annotate.o to keep Sun make happy. - * configure.in: Add config for powerpc/Netware. - - * partial-stab.h (near N_SO): Don't call START_PSYMTAB with null - filename. This speeds up handling of trailing N_SO stabs (they - mark the end of a .o file). - - * target.c, target.h: Change the way pushing and popping of - targets work to support target overlays and inheritance. - * corelow.c, hppa-tdep.c, inflow.c, remote-nindy.c, utils.c: - Fixup references to current_target, due to previous changes. - - * config/i386/tm-i386nw.h: Enable longjmp support. More work is - needed to get the address of longjmp out of the target. - -Tue Jul 19 13:25:06 1994 Stan Shebs (shebs@andros.cygnus.com) - - * main.c: Include . - -Mon Jul 18 15:32:17 1994 Kung Hsu (kung@mexican.cygnus.com) - - * remote-mips.c (mips_readchar): Fix a bug in checking - prompt. - -Mon Jul 18 14:26:35 1994 Stan Shebs (shebs@andros.cygnus.com) - - * solib.c (look_for_base): Don't deref exec_bfd if NULL. - -Sun Jul 17 15:38:36 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.12.4. - -Sun Jul 17 12:20:35 1994 Stan Shebs (shebs@andros.cygnus.com) - - Harris CX/UX support, from Bob Rusk (rrusk@mail.csd.harris.com). - * configure.in (m88*-harris-cxux*): New configuration. - * cxux-nat.c, config/m88k/cxux.mh, config/m88k/cxux.mt, - config/m88k/xm-cxux.h, config/m88k/tm-cxux.h, config/m88k/nm-cxux.h: - New files. - * config/m88k/tm-m88k.h: Add comment about Harris OS. - (TARGET_WRITE_PC): Pass pid through to register writers. - - * configure.in (m68*): Put vendor-only-specified host configs - after vendor-and-os-specified configs. - (m68*-atari-sysv4*, m68*-cbm-sysv4*): Replace with m68*-*-sysv4. - - * config/m88k/delta88.mh (MUNCH_DEFINE): Remove. - * config/m88k/delta88.mt, config/m88k/delta88v4.mh: Format - consistently. - -Sat Jul 16 23:39:17 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * elfread.c (elf_symtab_read): Handle error return from - bfd_get_dynamic_symtab_upper_bound gracefully. - -Sat Jul 16 14:43:17 1994 Stan Shebs (shebs@andros.cygnus.com) - - * inferior.h (ARCH_NUM_REGS): New macro, actual number of - registers in use by the inferior. - * coredep.c (fetch_core_registers, register_addr): Use it. - * findvar.c (registers_changed, registers_fetched, - read_register_bytes): Ditto. - * infcmd.c (do_registers_info, registers_info): Ditto. - * infptrace.c (fetch_inferior_registers, - store_inferior_registers): Ditto. - * stack.c (frame_info): Ditto. - - * coredep.c (CORE_REGISTER_ADDR): New macro. - (fetch_core_registers): Use it. - - * breakpoint.c (ignore, condition): Add usage notes to help strings. - * symfile.c (add-symbol-file): Add usage note to help string. - (add_shared_symbol_files_command): New command. - - gcc -Wall lint. - * inferior.h (read_pc_pid): Declare. - * breakpoint.c (watchpoint_check): Cache breakpoint in local - variable b, remove unused variable other_type_used. - * main.c (inferior.h, call-cmds.h): Include. - (gdb_init): Declare. - * remote.c (remote_wait): Return 0 by default. - -Fri Jul 15 16:43:33 1994 Stan Shebs (shebs@andros.cygnus.com) - - Stop printing at null char option, from Oliver Meyer - (omeyer@i3.informatik.rwth-aachen.de). - * valprint.h, valprint.c (stop_print_at_null): New global. - * valprint.c (_initialize_valprint): New print set subcommand - "null-stop". - * c-valprint.c (c_val_print): If stop_print_at_null is on, and - printing a char array, adjust the number of chars to print. - -Fri Jul 15 14:33:40 1994 Stan Shebs (shebs@andros.cygnus.com) - - From Kevin A. Buettner (kev@cujo.geg.mot.com). - * m88k-tdep.c (examine_prologue): Modified to handle prologues for - pic code in addition to prologues where an instruction from the - prologue gets moved into the delay slot of a branch instruction - immediately following the prologue. A table of potential prologue - instructions (prologue_insn_tbl) is now used for picking apart a - function prologue. - (frame_find_saved_regs): Changed the way in which limit gets set - so that the delay slot of branch instructions immediately - following the prologue gets examined. - (pushed_size, store_parm_word, store_parm, push_parameters, - collect_returned_value): Deleted. - -Fri Jul 15 01:06:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): Handle stepping into leaf - functions whose prologue consists of gp loading code only. - -Thu Jul 14 14:22:12 1994 Stan Shebs (shebs@andros.cygnus.com) - - * dbxread.c: Don't include libbfd.h. - * dwarfread.c, elfread.c somread.c: Don't include libbfd.h, - , or . - * elfread.c (elf_symfile_read): Use only standard BFD functions to - collect information about the stab and stab string sections. - -Thu Jul 14 13:17:39 1994 Kung Hsu (kung@x1.cygnus.com) - - * stabsread.c (read_huge_number): handle large unsigned number - for stabs generated by os9k C compiler. - -Wed Jul 13 18:58:15 1994 Stan Shebs (shebs@andros.cygnus.com) - - Breakpoint hit counts, from Bob Rusk (rrusk@mail.csd.harris.com). - * breakpoint.h (hit_count): New breakpoint field. - * breakpoint.c (show_breakpoint_hit_counts): New variable. - (clear_breakpoint_hit_counts): New function. - (bpstat_stop_status): Increment the hit count. - (breakpoint_1): Display the hit count. - * infcmd.c (run_command): Reset breakpoint hit counts. - * target.c (generic_mourn_inferior): Don't clear ignore counts if - displaying hit counts. - -Tue Jul 12 12:23:15 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * elfread.c (elf_symfile_read): Unconditionally add dynamic - symbols for all symbol files. Makes skipping over the - trampoline code work when stepping from a function in a shared - library into a function in a different shared library for Irix 5. - Other ELF targets do not have enough information in their - dynamic symbol tables to make this work. - (elf_symtab_read): Relocate mst_solib_trampoline address. - -Mon Jul 11 16:38:49 1994 Stan Shebs (shebs@andros.cygnus.com) - - Atari support, from Uwe Seimet (seimet@chemie.uni-kl.de). - * configure.in (m68*-atari-sysv4*): New configuration. - (m68*-cbm-sysv4*): Use m68kv4 instead of amix. - * m68k-tdep.c (R_PS): Define as R_SR if necessary. - * config/m68k/m68kv4.mh, config/m68k/m68kv4.mt, - config/m68k/tm-m68kv4.h, config/m68k/xm-m68kv4.h: New files. - * config/m68k/amix.mh, config/m68k/amix.mt, - config/m68k/tm-amix.h, config/m68k/xm-amix.h: Removed, superseded - by m68kv4 files. - -Sat Jul 9 16:28:43 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symtab.c (find_function_start_sal): New function to find - the start of a function from a function symbol. - (decode_line_1, decode_line_2): Use it instead of open coded - partial copies of the code. - (list_symbols): Quote symbol name before passing it to - break_command to enable proper handling of mangled symbols. - -Wed Jul 6 20:22:07 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * ch-exp.y (match_simple_name_string): Don't lower-case here. - * ch-exp.y (yylex): First try name lookup using exact name - typed by user; if that fails, try lower-cased name. - -Wed Jul 06 12:39:07 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: More cleanups. Delete lots of trailing whitespace. - Remove some items from the TODO list and notes throughout code - for things which need fixing. Add more comments. - Document bogus struct symloc sharing with dbxread.c. Delete more - useless variables. Add more PARAM prototypes. Fixup more - indention problems that have crept in. - (SET_NAMESTRING): Accept new namep and objfile arguments so that - it doesn't depend on the variable names on the procedures it's - used from. - (hpread_symfile_init): Delete incorrect checks for bogus sizes of - the debug sections. - -Wed Jul 6 00:48:57 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dbxread.c, elfread.c, mipsread.c, nlmread.c, os9kread.c: - Move "no debugging symbols found" test to symfile.c. - * symfile.c (syms_from_objfile, reread_symbols): Add - "no debugging symbols found" test. - * coffread.c (init_stringtab): Handle stripped files with a - stringtab offset of zero gracefully. - * osfsolib.c (solib_create_inferior_hook): Use DYNAMIC flag from - BFD instead of stop_pc heuristic to determine if it is a dynamically - linked object file. - * procfs.c (wait_fd): Handle ENOENT error return from PIOCWSTOP - ioctl, it indicates that the process has exited. - -Mon Jul 04 19:48:03 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (hpread_symfile_init): Make sure to initialize all the - private data to zero. Not having any HP C debug symbols is not an - error. Just return. - -Mon Jul 4 19:28:56 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (read_unwind_info): ELF unwind information is in the - .PARISC.unwind section now. - -Mon Jul 4 17:06:26 1994 Stan Shebs (shebs@andros.cygnus.com) - - * breakpoint.c (mention): Always show breakpoint address if no - source file. - -Sat Jul 2 01:51:33 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * solib.c (bfd_lookup_symbol, look_for_base): Reinstate to reenable - handling of shared libraries for non-ELF executables, but only if - HANDLE_SVR4_EXEC_EMULATORS is defined. - (locate_base): Try to find debug_base in the dynamic linker - for non-ELF executables if HANDLE_SVR4_EXEC_EMULATORS is defined. - * config/sparc/tm-sun4sol2.h (HANDLE_SVR4_EXEC_EMULATORS): - Define to enable handling of shared libraries for a.out executables, - run under Solaris BCP. - -Fri Jul 01 19:50:21 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c: Change contribution notice to the Cygnus/Utah agreed - upon notice. Delete some stuff from the TODO list. Rework - many comments to be clearer. Major cleanups. Consistently - use "hpread_" prefix. Delete unnecessary macros, structures - variables, fiels, functions and #if 0 code. Mark code which - still needs to be cleaned up. PARAMize and make most functions - static. Fix error checking when reading in the debug section - contents. No more minimal symbol table handling in this code! - -Thu Jun 30 13:59:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (wait_for_inferior): Print "Program exited normally" - regardless of batch_mode. - * defs.h, top.c (batch_mode): Removed. - -Wed Jun 29 18:53:36 1994 Stan Shebs (shebs@andros.cygnus.com) - - * Makefile.in (dcache_h): Remove redundant definition. - (init.c): Add a comment. - (top.c): Remove explicit compile action. - * breakpoint.c (mention): Share code indicating location of - break/watchpoints, don't print address if addressprint is off. - * breakpoint.c, c-typeprint.c, c-valprint.c, energize.c, symtab.h - (demangle): Remove redundant declarations. - * eval.c: Remove redundant function declarations. - * objfiles.h: Cosmetic and grammatical improvements. - * TODO: Various updates. - - * remote-mips.c: Replace all \r chars with \015. - (mips_receive_header): Display control characters readably. - (mips_xfer_memory): Add a simple progress display. - -Wed Jun 29 13:11:45 1994 Steve Chamberlain (sac@cirdan.cygnus.com) - - * remote-e7000.c (e7000_open): Don't try a tcp open if we're - using go32. - * remote-hms.c (flush): New function. - (expect): Get edge case right. - (hms_read_inferior_memory): Be more tolerant of line noise. - -Tue Jun 28 14:17:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Use i386m3.mh and i386m3.mt as names of host and - target files, not non-existent mach3.mh and mach3.mt. - -Wed Jun 29 00:26:17 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dbxread.c (dbx_symfile_read): Unconditionally add dynamic - symbols for all symbol files. Makes skipping over the - trampoline code work when stepping from a function in a shared - library into a function in a different shared library. - (read_dbx_dynamic_symtab): Relocate mst_solib_trampoline address. - -Tue Jun 28 15:28:01 1994 Stu Grossman (grossman@cygnus.com) - - * dbxread.c, partial-stab.h (near N_SO): SO stabs with blank - names mean end of .o file. - * infrun.c (wait_for_inferior): Clean up multi-thread logic near - top of routine. Handle new thread notification cleanly. - * lynx-nat.c (child_wait): General cleanups, handle new LynxOS - thread notification scheme. - * (child_resume): General cleanups, handle resumption of all - threads properly. - -Mon Jun 27 09:57:23 1994 Steve Chamberlain (sac@cirdan.cygnus.com) - - * ser-go32.c: Rewrite to run under windows. - * ser-e7kpc.c: New file to support the E7000 with the PC ISA - bus interface. - * serial.c (serial_open): Notice device "pc". - * remote-e7000.c: Fix copyright date. - (expect): Compare \n and \r the same. - (e7000_open): Allow pc as a serial port - * sh/sh.mt: Add ser-e7kpc. - * h8300/h8300hms.mt: Add ser-e7kpc. - * main.c (proc_wait): Don't wait if using go32. - -Mon Jun 27 00:35:51 1994 Jeff Law (law@snake.cs.utah.edu) - - * somread.c: Simplify by using stabsect_build_psymtabs. - * dbxread.c (stabsect_build_psymtabs): New argument "text_name" - corresponding to the name of the text section. All references - changed. - (somstab_build_psymtabs): Delete function, no longer needed. - -Sun Jun 26 23:54:08 1994 Jeff Law (law@snake.cs.utah.edu) - - * somread.c: Renamed from paread.c. Changed function names and - comments to reflect that this file deals with SOM (an object file - format), rather than the PA (a cpu). - (Makefile.in): Chaned appropriately. - (config/pa/hppabsd.mh, config/pa/hppahpux.mh): Likewise. - * dbxread.c (somstab_build_psymtabs): Renamed from - pastab_build_psymtabs. - -Fri Jun 24 08:15:42 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * core-sol2.c: New file to handle ELF and BCP core file flavours. - * config/sparc/sun4sol2.mh (NATDEPFILES): Use it instead of - core-svr4. - * Makefile.in: Updated for core-sol2.c. - * README: Add notes about SPARCworks cc under Solaris 2.x, - from Casper H.S. Dik (casper@fwi.uva.nl). - * config/mips/xm-makeva.h: Removed, no longer necessary. - * Makefile.in, config/mips/xm-irix3.h, config/mips/xm-irix5.h, - config/mips/xm-mips.h, config/mips/xm-news-mips.h, - config/mips/xm-riscos.h: Remove references to xm-makeva.h - -Wed Jun 22 17:48:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdba.el: Put program input and output in a separate buffer. - -Wed Jun 22 16:54:15 1994 Fred Fish (fnf@cygnus.com) - - * energize-patches, main.c (main), top.c (gdb_init, pwd_command), - top.h: Change all occurances of dirbuf to gdb_dirbuf. Collides - with global variable of same name in libnsl.so on UnixWare. - -Wed Jun 22 14:40:52 1994 Kung Hsu (kung@mexican.cygnus.com) - - * symtab.c (decode_line_1): fix a bug in dealing with '<>' - embedded in template name. - -Tue Jun 21 14:06:46 1994 Kung Hsu (kung@mexican.cygnus.com) - - * config/i386/nm-linux.h: change calling convention of - TARGET_CAN_USE_HARDWARE_WATCHPOINT() and - target_insert_watchpoint() and - target_remove_watchpoint(). - - * config/mips/tm-mips64.h: define FORCE_LONG_LONG to force LONGEST - to be long long in gdb. - * config/mips/tm-bigmips.h: ditto. - -Mon Jun 20 23:54:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-lang.c (asm_language_defn): New definitions for language_asm, - mostly copied from c_language_defn, to avoid warnings when - switching between c and asm stack frames. - -Mon Jun 20 13:51:55 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * mdebugread.c (parse_symbol): Don't call ecoff_swap_tir_in or - ecoff_swap_rndx_in directly; use the debug_swap pointer instead. - (upgrade_type, handle_psymbol_enumerators): Likewise. - (has_opaque_xref, cross_ref): Likewise. - (elfmdebug_build_psymtabs): Call swap->read_debug_info to read - debugging information, rather than doing it here. - * mipsread.c (mipscoff_symfile_read): Call read_debug_info entry - point in ecoff_debug_swap backend structure, rather than calling - ecoff_slurp_symbolic_info directly. - -Fri Jun 17 20:58:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c: Include annotate.h. Call annotate_field rather - than printing annotation directly. - - * main.c: Include string.h. - -Thu Jun 16 14:41:37 1994 Stan Shebs (shebs@andros.cygnus.com) - - * fork-child.c (startup_inferior) [STARTUP_INFERIOR]: If defined, - call it instead of doing normal loop. - * infcmd.c (attach_command): Don't call wait_for_inferior if - running Mach 3. - * infrun.c (proceed) [PREPARE_TO_PROCEED]: If defined, call - hook that can decide whether to step over the next breakpoint. - * utils.c (wrap_here): Abort if wrap_buffer not allocated. - (request_quit) [REQUEST_QUIT]: If defined, call it instead of - doing normal quit. - - * configure.in: Improve sorting/formatting of hosts and targets. - (i[34]86-*-mach3*, i[34]86-*-osf1mk*, mips-*-mach3*, - m88*-*-mach3*, ns32k-*-mach3*): Recognize. - * Makefile.in (stop-gdb): New target. - * stop-gdb.c: New file, utility to get attention of waiting GDBs - in Mach 3. - -Wed Jun 15 00:41:03 1994 Tom Lord (lord@rtl.cygnus.com) - - * top.c (gdb_init): Init current_directory in gdb_init. Probably - the identical initialization can be deleted from main.c, but i - haven't done so just in case. - -Tue Jun 14 17:24:41 1994 Tom Lord (lord@x1.cygnus.com) - - * gdba.el: Added menu windows and slightly improved window - handling to gdba.el. Fixed numerous minor bugs that were causing - emacs and gdb to fall out of sync. - -Tue Jun 14 16:18:44 1994 Kung Hsu (kung@mexican.cygnus.com) - - * breakpoint.c: annotate changes lost at merge, put back in. - -Mon Jun 13 17:28:50 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config/i386/i386sco.mh, i386sco4.mh (XDEPFILES): Remove - i387-tdep.o. - -Sun Jun 12 03:51:52 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/m68k/dpx2.mh (NATDEPFILES): Remove duplicate inclusion - of inftarg.o. - * config/m68k/tm-dpx2.h (CANNOT_STORE_REGISTER): Define to inhibit - writing of floating registers, the dpx2 kernel disallows it. - * irix5-nat.c (LM_ADDR): The loaded address of the shared library - is contained in o_praw. - * irix5-nat.c (solib_map_sections): Adjust sections by the - difference between the loaded address and the prelinked address. - * irix5-nat.c (solib_address): Use LM_ADDR for the loaded start - address. - * mdebugread.c (parse_symbol): Do not relocate stEnd/scText - symbols, their value is absolute. - * mdebugread.c (parse_partial_symbols): Handle Irix 5.2 shared - libraries fh->adr fields of zero. Relocate minimal symbol values - upon readin. Relocate non-stabs symbols upon readin. - * mdebugread.c (psymtab_to_symtab_1): Use pst->textlow for the - start address of the outermost block. - * mdebugread.c (parse_lines, parse_procedure): Pass in pst - instead of section_offsets and use relocated pst->textlow for - line number and procedure address relocations. - - From gmo@MicroUnity.com (Guillermo A. Loyola): - * mdebugread.c (parse_symbol, parse_partial_symbols, cross_ref): - Handle SGI Irix5 stIndirect symbol type. - -Fri Jun 10 14:52:56 1994 Kung Hsu (kung@mexican.cygnus.com) - - * breakpoint.c: fix a syntax error native cc does not like. - - * Makefile.in: change sparclite-tdep.c to sparcl-tdep.c. - * sparclite/Makefile.in: ditto. - * sparcl-tdpe.c: change file name because first 8 chars has to be - unique. - * sparcl-stub.c: ditto. - - * sparclite/Makefile.in: fix INCLUDE_CFLAGS to have {srcdir}/../config. - -Fri Jun 10 10:38:15 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (target_read_pc, target_write_pc): Accept (and - ignore) a PID argument. - (hppa_pop_frame): Pass a PID to target_write_pc. - * config/pa/tm-hppa.h (TARGET_READ_PC, TARGET_WRITE_PC): Accept - and pass through a PID argument. - (target_read_pc, target_write_pc): Update prototypes. - -Thu Jun 9 18:10:44 1994 Kung Hsu (kung@mexican.cygnus.com) - - * Makefile.in: add new file sparclite-tdep.c. - * sparclite/Makefile.in: add new file sparclite-stub.c. - * sparclite/hw_breakpoint.note: note for SPARClite hardware breapoint - support. - * config/sparc/sparclite.mt: add sparclite-tdep.o. - * config/sparc/tm-sparclite.h: add hardware breakpoints support - defiines and code. - * sparclite-tdep.c: new file, contains hardware breakpoint support - code. - * sparclite-stub.c: new file, stub code that add support hardware - breakpoint support. - * breakpoint.c: add hardware breakpoint support. - * breakpoint.h: add new breakpoint type to support hardware - breakpoint. - * config/mips/nm-irix4.h: change interface for target dependent - code supporting watch point. - * config/pa/nm-hppab.h: change interface for target dependent - code supporting watch point. - -Thu Jun 9 14:59:58 1994 Kung Hsu (kung@mexican.cygnus.com) - - * remote-os9k.c (rombuf_command): fix a bug accepting rombug - output. - * stabsread.c (read_struct_fields): os9k nested structure does not - have terminating ';', instead it just get to ',' and bit position - and length. - -Wed Jun 8 23:20:45 1994 Stu Grossman (grossman@cygnus.com) - - * nlmread.c (nlm_symtab_read): Clean up a bit. - * (nlm_symfile_read): Record bounds of main() so that backtrace - command will know where to stop. - * objfiles.c (objfile_relocate): Relocate entry point/func info - for backtrace as well. - * objfiles.h: Define values for invalid PCs for entry point info. - * symfile.c (init_entry_point_info): Initialize invalid values - with aforementioned macros. - * config/alpha/tm-alphanw.h: Turn on FRAME_CHAIN_VALID_ALTERNATE - to cause backtrace to stop when it gets back to main(). - * config/i386/tm-i386nw.h: Ditto. - -Sat Jun 4 18:17:03 1994 Per Bothner (bothner@kalessin.cygnus.com) - - Fix value_print, which used to be ostensibly language-independent, - but would print pointers and arrays in C syntax. Instead, call - a language-specific function. - * language.h (struct language_defn): New functional field - la_value_print. - (LA_VALUE_PRINT): New macro. - * language.c (unk_lang_value_print): New stub/dummy function. - (unknown_language_defn, auto_language_defn, local_language_defn): - Use it. - * c-valprint.c (c_value_print): New function, with code moved from: - * valprint.c (value_print): ... here. Now just invoke - LA_VALUE_PRINT to do language-specific stuff. - * valprint.c (value_print_array_elements): Make non-static. - * c-lang.c (c_language_defn, cplus_language_defn): Add - c_value_print in the la_value_print field. - * m2-lang.c (m2_language_defn): Likewise. - * ch-lang.c (chill_language_defn): But here use chill_value_print. - * ch-valprint.c (chill_val_print): Print null pointer as NULL. - * ch-valprint.c (chill_value_print): New function, based on - c_value_print, but use Chill "look and feel." - * c-lang.h (c_value_print): New prototype. - * ch-lang.h (chill_value_print): New prototype. - * value.h (value_print_array_elements): New prototype. - - * ch-valprint.c (chill_val_print, case TYPE_CODE_BITSTRING - and case TYPE_CODE_SET): Check that the element type isn't a stub. - -Fri Jun 3 09:15:00 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c: Move entire file except for #ifndef MAIN_OVERRIDE code - to new file top.c. Make things extern instead of static and - similar rearrangements to deal with this. - * top.h: New file. - * utils.c: Move fputs_unfiltered to main.c. Remove - FPUTS_UNFILTERED_OVERRIDE ifndef. - * Makefile.in: Change so that gdb uses main.c, utils.c, and top.c, - and libgdb uses utils.c and top.c. - -Thu Jun 2 23:19:10 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (skip_trampoline_code): Fix typo. - -Thu Jun 2 18:09:59 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * ch-valprint.c (chill_val_print_array_elements): New function. - A Chill version of val_print_array_elements, it prints the - array index labels, in additions ot the array element values. - (chill_val_print): Use the new function. - -Thu Jun 2 08:50:00 1994 Stu Grossman (grossman@cygnus.com) - - * configure.in: Add nlm subdir to configdirs for alpha-*-netware - target. - * defs.h (enum language): Add language_asm. - * findvar.c (read_register_bytes read_register_gen - write_register_bytes read_register read_register_pid - write_register write_register_pid supply_register): Move multi- - thread handling down into these routines. Create XXX_pid routines - that allow register references to specify the pid. - * findvar.c infcmd.c (read_pc read_pc_pid write_pc write_pc_pid - read_sp write_sp read_fp write_fp): Move these routines from - infcmd to findvar to centralize the whole mess. - * i386-nlmstub.c: Portability fixes. - * infptrace.c (child_resume): Conditionalize to allow other natives - to override it. Remove PIDGET gubbish, it's no longer necessary. - * infrun.c (wait_for_inferior): Put registers_changed() before - target_wait() to speed up remote debugging. - * Replace code that reads registers from other threads with much - nicer looking new function calls (see changes to findvar.c). - * Don't skip prologues if debugging assembly source. - * lynx-nat.c (child_resume): Lynx now needs it's own version of - child_resume to handle multi-thread debugging properly. - * remote.c: Add O response to get console output from target. - * (readchar): Add timeout parameter. Handle SERIAL_EOF and - SERIAL_ERROR here to simplify callers. - * Change static var timeout to remote_timeout. - * (fromhex): Remove unnecessary return -1 at end of routine. - * (remote_wait): Turn this into a big switch statement. Add - support for O response. - * (putpkt): Remove unnecessary handling of SERIAL_EOF/ERROR. - * (getpkt): Split getpkt into two parts. read_frame deals with - all formatting issues, run-length encoding, and framing. getpkt - now handles error recovery, and frame detection. - * ser-tcp.c (tcp_readchar): Handle EINTR from read(). - * ser-unix.c (hardwire_raw): Set CLOCAL so that we ignore modem - control. (hardwire_readchar): Handle EINTR from read(). - * symfile.c (deduce_language_from_filename): Add support for .s - files. - * config/nm-lynx.h: Define CHILD_WAIT so that lynx-nat.c can - override infptrace's child_wait. - * config/rs6000/rs6000lynx.mh: Use xm-rs6000ly.h & nm-rs6000ly.h - instead of XXXlynx.h. - * config/rs6000/rs6000lynx.mt: Use tm-rs6000ly.h instead of - tm-rs6000lynx.h. - * nlm/gdbserve.c: Portability fixes. - -Tue May 31 20:35:44 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * inftarg.c (child_wait): Call proc_wait, not wait. - (child_mourn_inferior): Call proc_remove_foreign. - * main.c (gdb_init): Call init_proc. - * main.c: Provide dummy versions of init_proc, proc_wait, and - proc_remove_foreign for the gdb case (the libgdb case provides its - own versions of these functions). - * Makefile.in (libgdb-files): Add libproc.a. - -Wed Jun 1 11:08:52 1994 Stan Shebs (shebs@andros.cygnus.com) - - Hardware watchpoints for Linux, from Rick Sladkey - (jrs@world.std.com). - * infrun.c (wait_for_inferior) [HAVE_CONTINUABLE_WATCHPOINT]: Add - new hardware breakpoint recovery method. - * i386v-nat.c (i386_insert_watchpoint, - i386_insert_nonaligned_watchpoint, i386_remove_watchpoint, - i386_stopped_by_watchpoint) [TARGET_CAN_USE_HARWARE_WATCHPOINT]: - New functions to support the 386 hardware debugging registers. - * config/i386/nm-linux.h (TARGET_CAN_USE_HARDWARE_WATCHPOINT, - HAVE_CONTINUABLE_WATCHPOINT, STOPPED_BY_WATCHPOINT, - target_insert_watchpoint, target_remove_watchpoint): Define these - macros to use the hardware debugging functions in i386v-nat.c. - -Wed May 25 17:06:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Replace libgdb.a with libgdb-files. Make "all" - build it. - -Thu May 19 09:56:20 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * target.c, target.h: New variables target_activity_function and - target_activity_fd. - * inflow.c, inferior.h: New functions set_sigio_trap and - clear_sigio_trap. - * inftarg.c (child_wait), procfs.c (wait_fd): Call them. - -Wed May 18 13:01:55 1994 Doug Evans (dje@canuck.cygnus.com) - - * remote-sim.h (sim_verbose): Delete. - Document callbacks needed. - (sim_*): Change result to void where there isn't one. - (sim_open): Clarify argument and error response. - (sim_close): Declare. - (sim_load): Change bfd_handle argument to file name. Clarify result. - (sim_create_inferior): Renamed from sim_set_args. - (sim_set_pc): Delete. - (sim_info): Delete printf_fn argument. - * remote-sim.c (gdbsim_kill): Add comment describing purpose. - (gdbsim_load): Try sim_load first. - (gdbsim_create_inferior): Call sim_create_inferior. - (gdbsim_open): Handle args == NULL. Update call to sim_open. - (gdbsim_close): Call sim_close. - (gdbsim_files_info): Update call to sim_info. - (gdbsim_ops): Realign comments. - - * printcmd.c (decode_format): Allow TARGET_PTR_BIT to be non-constant. - -Tue May 17 16:45:20 1994 Stan Shebs (shebs@andros.cygnus.com) - - * xcoffread.c (read_xcoff_symtab): For C_FILE symbols, only use - the auxent if the symbol's name is ".file". From David Edelsohn - . - -Tue May 17 11:08:22 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (breakpoint_1): Fix typo. - - * annotate.c (annotate_field_end): Fix typo. - - * Makefile.in: Move annotate.o from COMMON_OBS to OBS. - - * Makefile.in (TSSTART): Remove; no longer used. - - * utils.c (vfprintf_maybe_filtered, vfprintf_unfiltered): Call - fputs_unfiltered and exit directly, rather than fatal. The latter - calls vfprintf_unfiltered! - - * gdbtypes.h, gdbtypes.c (can_dereference): New function. - * value.h, printcmd.c (print_value_flags): Move from here... - * annotate.c: ...to here, and make it use can_dereference. - -Sat May 14 15:13:52 1994 Stan Shebs (shebs@andros.cygnus.com) - - * inflow.c (job_control, attach_flag, generic_mourn_inferior): - Remove, needed for both native and cross. - * target.c (attach_flag, generic_mourn_inferior): Put here. - * utils.c (job_control): Put here. - (terminal.h): Don't include anymore. - -Sat May 14 09:11:44 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * source.c (find_source_lines): Always use code that was #ifdef - BROKEN_LARGE_ALLOCA. Do the cleanup before returning, rather than - leaving it on the chain. Reindent much of this function. - * config/sparc/{xm-sun4sol2.h,xm-sun4os4.h}, - config/i386/{xm-sun386.h,xm-i386m3.h,xm-i386mach.h}, - config/m68k/{sun3os4.h,xm-news.h,xm-hp300hpux.h}, - config/ns32k/xm-ns32km3.h: Remove all references to - BROKEN_LARGE_ALLOCA; with the above change it is no longer needed. - * main.c, fork-child.c, many config files: Remove all - SET_STACK_LIMIT_HUGE code; with the above changes it should no - longer be needed. - - * symtab.c (lookup_partial_symbol): Use if and abort, not assert. - This avoids __eprintf troubles. - -Fri May 13 08:10:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (main): Surround in #ifndef MAIN_OVERRIDE. Move - initialization code which needs to be called even if we bypass the - command line stuff into gdb_init. - * utils.c (fputs_unfiltered): Surround in #ifndef - FPUTS_UNFILTERED_OVERRIDE. - * Makefile.in (libgdb.a): New target. - - * utils.c: Rearrange I/O stuff a bit so that all output goes - through fputs_unfiltered. Use vasprintf; removes arbitrary limit - which made %s not work with arbitrarily large strings. - * printcmd.c (printf_command): Use printf_filtered, not - printf_unfiltered and printf, now that arbitrary limit is gone. - - gcc -Wall lint: - * breakpoint.c (watchpoint_check): Remove unused variable b. - * stack.c (print_frame_info): Move sp and buf inside #if. - * eval.c (evaluate_subexp): Remove unused variables pp, - mangle_ptr, ptr, and mangle_tstr. - * valarith.c (value_x_binop): Remove unused variables mangle_tstr - and mangle_ptr. - * symtab.c (lookup_symtab): Put variable copy inside #if. - (decode_line_1): Put variable q1 inside #if 0. - * target.h: Declare target_link. - * infrun.c (wait_for_inferior): Remove unused variables signame. - * remote.c (remote_resume): Remove unused variable name. - * c-exp.y (parse_number): Parenthesize operand of shift. - * dbxread.c (record_minimal_symbol): Parenthesize operand of && - (this is a semantic change, the warning seems to have detected a bug). - * dbxread.c (end_psymtab): Move variable p1 inside #if. - * coffread.c: Move variable temptype inside #if. - * ch-typeprint.c (chill_type_print_base): Remove unused variable - name. - * ch-valprint.c: #include typeprint.h and ch-lang.h. - (chill_val_print): Remove unused variable in_range. - (chill_val_print): Remove statement "length > TYPE_LENGTH (type);". - (chill_val_print): Add default case for switch. - * stabsread.h: Declare stabsect_build_psymtabs. - * os9kread.c (read_minimal_symbols): Make this return void. - (os9k_symfile_read): Remove unused variables stb_exist and val. - (os9k_symfile_init): Remove unused variable val. - (fill_sym): Remove unused variable id. - (read_os9k_psymtab): Put variable back_to inside #if 0. Remove - unused variable nsl. - Remove unused variable symfile_bfd. - #if 0 unused variables lbrac_unmatched_complaint and - lbrac_mismatch_complaint. - Remove declaration for non-existent function os9k_next_symbol_text. - - * annotate.c, annotate.h: New files, containing a function for - each annotation which outputs it. - * Move breakpoints_changed from breakpoint.c to annotate.c. - * breakpoint.c, blockframe.c, infrun.c, cp-valprint.c, main.c, - printcmd.c, source.c, stack.c, utils.c, valprint.c: - Use annotate.c functions to output annotations. - * Makefile.in (OBS): Add annotate.o. - -Thu May 12 10:46:27 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (read_unwind_info): Make sure elf_unwind_size and - elf_unwind_entries are always initialized. - - * hppa-tdep.c (skip_trampoline_code): Handle argument relocation - stubs which return directly to the caller rather than to the stub - itself. - -Wed May 11 20:11:51 1994 Stan Shebs (shebs@andros.cygnus.com) - - * c-exp.y (yyerror): Display a more informative error message. - * ch-exp.y (yyerror): Ditto, don't use global yychar. - * m2-exp.y (yyerror): Ditto. - -Tue May 10 11:57:53 1994 Stan Shebs (shebs@andros.cygnus.com) - - * inflow.c (job_control): Move definition to front of file. - -Tue May 10 14:42:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * maint.c (print_section_table): Rename SEC_SHARED_LIBRARY to - SEC_COFF_SHARED_LIBRARY to match corresponding change in bfd. - -Fri May 6 13:30:22 1994 Stan Shebs (shebs@andros.cygnus.com) - - * Makefile.in (kdb): Remove old init.c creation commands. - * configure.in (sparclite): Match on sparclite*. - * sparclite/aload.c (main): Only change section addresses for - a.out format object files. - -Fri May 6 13:24:04 1994 Steve Chamberlain (sac@cygnus.com) - - * config/i386/go32.mh: Define CC. - -Fri May 6 11:56:54 1994 Stan Shebs (shebs@andros.cygnus.com) - - * gdbserver/Makefile.in: Remove irrelevant definitions and - comments inherited from the gdb Makefile. - (BFD_DIR, BFD, BFD_SRC, BFD_CFLAGS): Add from gdb Makefile. - (VERSION): Update to 4.12.3. - (gdbserver): Remove any existing executable first. - (distclean, realclean): Remove nm.h. - * gdbserver/low-lynx.c: Add Sparc Lynx support. - * gdbserver/low-sparc.c, gdbserver/low-sun3.c (sys/wait.h): - Don't use absolute pathname. - -Thu May 5 12:00:22 1994 Stan Shebs (shebs@andros.cygnus.com) - - * rs6000-nat.c (vmap_ldinfo): Don't fail if fstat returns an - error. - -Wed May 4 06:56:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (proceed, normal_stop, wait_for_inferior), breakpoint.c - (print_it_normal): Add annotations for the inferior starting and - stopping, and for all the various messages related to how it - stopped. - - * printcmd.c (do_one_display): Annotate. - * stack.c (print_frame_info): Annotate printing of stack frames. - -Wed May 4 18:15:51 1994 Stu Grossman (grossman@cygnus.com) - - * remote.c (get_offsets): Handle case where stub doesn't support - qOffsets message. - -Wed May 4 15:30:39 1994 Per Bothner (bothner@kalessin.cygnus.com) - - Add partial support for g++ code compiled with -fvtable-thunks. - * c-valprint.c (c_val_print): Add vtblprint support - when using thunks. - * cp-valprint.c (cp_is_vtbl_member): A vtable can be an array of - pointers (if using thunks) as well as array of structs (otherwise). - * cp-valprint.c (vtbl_ptr_name_old, vtbl_ptr_name): Move to global - level, and make the latter non-static (so define_symbol can use it). - * stabsread.c (define_symbol): If the type being defined is a - pointer type named "__vtbl_ptr_type", set the TYPE_NAME to that name. - * symtab.h (VTBL_PREFIX_P): Allow "_VT" as well as "_vt". - * values.c (value_virtual_fn_field): Handle thunks. - * values.c (value_headof): Minor efficiency hack. - * values.c (value_headof): Incomplete thunk support. FIXME. - -Wed May 4 06:56:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valprint.c (print_longest): Clarify comment about use_local. - * printcmd.c, defs.h (print_address_numeric), callers in - symmisc.c, symfile.c, stack.c, source.c, remote.c, infcmd.c, - cp-valprint.c, core.c, ch-valprint.c, c-valprint.c, breakpoint.c, - exec.c: New argument use_local. - * source.c (identify_source_line): Use filtered output. Use - print_address_numeric. - - * core.c (memory_error), symtab.c (cplusplus_hint, decode_line_1), - language.c (type_error, range_error): Use filtered output. - * utils.c (error_begin): Update comment to tell people to use - filtered output. - - * Makefile.in (HFILES_WITH_SRCDIR): List bfd.h. - (HFILES_NO_SRCDIR): List gdbcore.h not gdbcore_h, so as not to get - bfd.h. - -Tue May 3 07:41:33 1994 Jim Kingdon (kingdon@cygnus.com) - - * procfs.c (procfs_wait): Reinstate code which deduces the signal - from the fault, #ifndef FAULTED_USE_SIGINFO. - * config/sparc/tm-sun4sol2.h: Define FAULTED_USE_SIGINFO. - -Fri Apr 29 18:15:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (breakpoint_1): Annotate each field of the headers. - Explicitly annotate each record. - -Fri Apr 29 15:56:18 1994 Stan Shebs (shebs@andros.cygnus.com) - - * xcoffexec.c: Reformat to standards and lint. - (language.h): Include. - (exec_close): Declare arg "quitting". - (file_command): Declare arg "from_tty". - (map_vmap): Cast xmalloc result to PTR. - * rs6000-nat.c: Reformat to standards and lint. - (exec_one_dummy_insn): Use char array for saved instruction. - (fixup_breakpoints): Declare. - (vmap_ldinfo): Be more informative in fatal error messages. - (xcoff_relocate_symtab): Define to return void. - * xcoffsolib.h: Reformat to standards, improve comments. - * config/rs6000/nm-rs6000.h (xcoff_relocate_symtab): Declare. - -Thu Apr 28 08:40:56 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c, defs.h (error_begin): New function. - (quit): Print annotation before printing the error message. - * main.c (return_to_top_level): Print annotation before doing the - longjmp. - * symtab.c (decode_line_1): Call error not warning and then - return_to_top_level. Call error_begin and printf_unfiltered - rather calling warning (before calls to return_to_top_level). - * core.c (memory_error): Use error_begin, printf_unfiltered, - print_address_numeric and return_to_top_level instead of error. - Cleans up a FIXME-32x64. - * language.c (type_error, range_error): Call error_begin - not just target_terminal_ours. - - * dbxread.c (stabsect_build_psymtabs): Assign to sym_stab_info - directly, rather than via DBX_SYMFILE_INFO. A cast on the left - side of an assignment is non-portable. - - * utils.c (query): Change syntax of query annotations to be - consistent with other input annotations. - (prompt_for_continue): Likewise for prompt-for-continue annotation. - -Thu Apr 28 01:20:39 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (psymtab_to_symtab_1): Do not call sort_blocks - for stabs symtabs. - * mips-tdep.c (mips_skip_prologue): Handle prologues for functions - that have a stack frame size of 32k or larger (from Paul Flinders). - Remove #if 0'd code. - -Wed Apr 27 16:33:51 1994 Stan Shebs (shebs@andros.cygnus.com) - - * lynx-nat.c (CANNOT_STORE_REGISTER): Add a fallback definition - for Lynx platforms that need it. - * config/nm-lynx.h (__LYNXOS): Define if not already defined. - -Wed Apr 27 16:01:37 1994 Jim Kingdon (kingdon@cygnus.com) - - * procfs.c (procfs_wait): Use the signal from the pr_info rather - than trying to deduce it from the fault. - -Wed Apr 27 12:22:46 1994 Steve Chamberlain (sac@cygnus.com) - - * printcmd.c (print_address_symbolic): Initialize name to empty - string to avoid core dump if lookup fails. - * remote-e7000.c (printf_e7000debug): Error if target not open. - -Tue Apr 26 22:45:24 1994 Stu Grossman (grossman at cygnus.com) - - * i386-nlmstub.c: Update to be more in line with PIN stub. - * nlm/gdbserve.c (putDebugChar): Install bug fix from i386-nlmstub. - * (hex2mem): Init ptr. - * General cleanups to use ConsolePrintf, standard prologues, etc... - -Tue Apr 26 10:23:04 1994 Stu Grossman (grossman at cygnus.com) - - * i386-nlmstub.c: More changes to be compatible with remote.c. - - * dbxread.c: Move a bunch of strncmps out of process_one_symbol - into (the far less frequently called) dbx_symfile_read. - - * i386-nlmstub.c: An interim version till we get PIN for the x86. - -Tue Apr 26 09:50:45 1994 Stu Grossman (grossman at cygnus.com) - - * dbxread.c (record_minimal_symbol): Record the section - associated with the symbol to make dynmaic relocation work. - * (dbx_symfile_read, process_one_symbol): Fixes to work around - Solaris brain-damage which don't apply to relocatable object - files. - * (stabsect_build_psymtabs): New routine to read stabs out of an - arbitrarily named section. - * nlmread.c (nlm_symtab_read): Read ALL syms from the NLM, not just - globals. - * (nlm_symfile_read): Call stabsect_build_psymtabs to read the - stabs out of the nlm. - * partial-stabs.h (cases 'f' & 'F'): Fixes to work around Solaris - brain-damage which don't apply to relocatable object files. - * remote.c (putpkt): Improve error reporting and error handling. - * (get_offsets): Temporary kludge to force data & bss sections to - have the same relocation. - * stabsread.c (define_symbol, scan_file_globals): Record section - info in sym. - -Sat Apr 23 19:05:52 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (breakpoint_1): Annotate each field of output. Add - FIXME-32x64 comment. - -Fri Apr 22 16:43:54 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (wait_for_inferior): Move call to flush_cached_frames - to after call to target_wait. This means that flush_cached_frames - can call target_terminal_ours if it wants to. - * infrun.c (wait_for_inferior) [HAVE_NONSTEPPABLE_WATCHPOINT]: Add - comment about why the code is dubious. - - * stabsread.c (read_type): Call read_type, not nonexistent - os9k_read_type. - -Fri Apr 22 14:25:36 1994 Kung Hsu (kung@mexican.cygnus.com) - - * remote-os9k.c (rombug_fetch_registers): set trace mode - correctly. - * remote-os9k.c (rombug_read_inferior_memory): cache data in - buffer. - * os9kread,c (read_os9k_psymtab): process file symbol to truncate - extra info. - * os9kread.c (os9k_read_ofile_symtab): proper casting of args - passed to process_one_symbol. - * stabsread.c (read_type): process os9k functio prototype. - -Fri Apr 22 11:27:39 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * solib.c (symbol_add_stub): If so->textsection is NULL, don't - dump core. - -Thu Apr 21 07:45:49 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c (prompt_for_continue): Annotate prompt. - (query): Annotate query. - * printcmd.c (print_frame_args): Change syntax of argument - annotation to make name and value part of a single group of - annotations, not two separate groups. - * cp-valprint.c (cp_print_value_fields): Likewise for fields. - * valprint.c (val_print_array_elements): Change syntax of - annotation to be more concise. - * main.c, defs.h (command_line_input): New argument tells what - string to include in the annotations. - * symtab.c (decode_line_2), main.c (read_command_lines, - command_loop): Change callers. - - * breakpoint.c (watch_command): Use (CORE_ADDR)0, not NULL, for - target null pointer. - * blockframe.c (find_frame_addr_in_frame_chain): Likewise. - - * printcmd.c (output_command): Annotate things we print here too. - * printcmd.c (print_command_1): Add "value-history-value" annotation. - * Move declaration of print_value_flags from defs.h to value.h. - * main.c (command_line_input): Call wrap_here as well as gdb_flush. - -Thu Apr 21 09:29:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dbxread.c (read_dbx_dynamic_symtab): Reinstall support for sun3, - BFD handles sun3 dynamic relocations now. - * elfread.c (elf_symtab_read, elf_symfile_read): Handle dynamic - symbol table. - -Wed Apr 20 19:41:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (print_command_1): Annotate the top-level expressions - that we print. - (print_frame_args): Annotate each argument. - * printcmd.c, defs.h (print_value_flags): New function. - * cp-valprint.c (cp_print_value_fields): Annotate each field. - * valprint.c (val_print_array_elements): Annotate each array element. - -Wed Apr 20 13:18:41 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * findvar.c (read_var_value): Handle LOC_REPARM_ADDR case correctly, - the register contains a pointer to the type, not the type itself. - -Mon Apr 11 10:44:35 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * main.c (main): Accept --annotate=N option and make --fullname - the same as --annotate=1. - (command_line_input): Print annotatation before and after prompt. - * blockframe.c (flush_cached_frames): Print annotation. - * Rename frame_file_full_name to annotation_level and move it from - symtab.h to defs.h. - * source.c (identify_source_line): If annotation_level > 1, - change output format. - * breakpoint.c: Print annotation whenever a breakpoint changes. - * main.c: New variable server_command. - (command_line_input): Parse "server " and set server_command. - (dont_repeat): Check server_command. - -Wed Apr 20 08:37:16 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (xcoff_next_symbol_text): Don't return before - updating raw_symbol and symnum. Return a value in the case where - we complained. - - * dstread.c, coffread.c: Don't define pending_blocks; buildsym.c - takes care of it. - * parse.c: Don't define block_found; it is defined in symtab.c. - * parser-defs.h: Add comment regarding block_found. - -Tue Apr 19 09:46:05 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (internalize_unwind_info): Delete unused indexp - argument. - -Mon Apr 18 13:18:56 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dbxread.c (read_dbx_dynamic_symtab): Relocate BFD symbols by - section vma. Do not read dynamic relocs for sun3 executables to - avoid BFD assertion message. - -Mon Apr 18 10:08:07 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * nm-hppab.h (KERNEL_U_ADDR): Define. - (FIVE_ARG_PTRACE): Likewise. - (CANNOT_STORE_REGISTER): Likewise. - * nm-hppah.h (KERNEL_U_ADDR): Define. - (FIVE_ARG_PTRACE): Likewise. - (CANNOT_STORE_REGISTER): Likewise. - (NEED_TEXT_START_END): Likewise. - - * tm-hppah.h (NEED_TEXT_START_END): Delete definition. - * xm-hppah.h (KERNEL_U_ADDR): Delete definition. - (FIVE_ARG_PTRACE): Likewise. - * xm-hppab.h (KERNEL_U_ADDR): Delete definition. - (FIVE_ARG_PTRACE): Likewise. - - * hppa-tdep.c (read_unwind_info): Make static. - (restore_pc_queue): Indirect through the target vector to - reload the register state. - -Sat Apr 16 22:20:51 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * paread.c (compare_unwind_entries): Delete function. It's been - moved into hppa-tdep.c. - (read_unwind_info): Likewise. - (pa_symfile_read): No longer call read_unwind_info. The unwind - tables will be read in as they are needed. - - * hppa-tdep.c (compare_unwind_entries): New function. - (read_unwind_info, internalize_unwinds): Likewise. - (find_unwind_entry): Read in unwind information on demand. - -Fri Apr 15 11:53:46 1994 Stan Shebs (shebs@andros.cygnus.com) - - * source.c (DIRNAME_SEPARATOR): New macro, replaces all references - to : in search path processing. - * defs.h (qsort): Rename argument in prototype. - * symtab.h (SAYMBOL_VALUE): Rename value field, avoids bugs in - some compilers. - * breakpoint.c, exec.c, mdebugread.c, mipsread.c, xcoffexec.c - (false): Eliminate usages. - -Fri Apr 15 11:35:19 1994 Steve Chamberlain (sac@cygnus.com) - - * h8500-tdep.c (initialize_h8500_tdep, large_command): - All references to value changed to value_ptrlage_command is now - called big_command. - All references to value changed to value_ptr. - * remote-e7000.c (e7000_wait): Use target_waitstatus and SETSTOP - * remote-hms.c (hms_wait): Timeout after five seconds. - * ser-go32.c (dosasync_read): Poll if timeout < 0. - * config/tm/tm-h8500.h (BEFORE_MAIN_LOOP_HOOK): Deleted. - * config/sh/tm-sh.h (BREAKPOINT): Is now sleep opcode. - -Thu Apr 14 07:01:56 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * procfs.c (procfs_wait): Protect watchpoint code with appropriate - #ifdefs. - (procfs_set_watchpoint, procfs_stopped_by_watchpoint): Likewise. - -Wed Apr 13 14:52:46 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * breakpoint.h (enum bptype): Add bp_hardware_watchpoint and - bp_watchpoint_scope breakpoints. - (struct breakpoint): Add val_chain and related_breakpoint fields - for use by watchpoints. - - * breakpoint.c (within_scope): Delete. No longer used. - (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Provide default definition. - (target_{remove,insert}_watchpoint): Likewise. - (can_use_hardware_watchpoint): New function. - (remove_breakpoint): New function to remove a single breakpoint - or hardware watchpoint. - (insert_breakpoints): Handle insertion of hardware watchpoints. - Store a copy of the value chain derived from the watchpoint - expression. - (remove_breakpoints): Simplify by using remove_breakpoint. - (delete_breakpoint): Likewise. - (watchpoint_check): Delete the watchpoint and watchpoint scope - breakpoints when the watchpoint goes out of scope. Save & restore - the current frame after checking watchpoints. - (breakpoint_init_inferior): Likewise (restarting the program - makes all local watchpoints go out of scope). - (bpstat_stop_status): Handle hardware watchpoints much like normal - watchpoints. Delete the watchpoint and watchpoint scope breakpoint - when the watchpoint goes out of scope. Remove and reinsert all - breakpoints before returning if we stopped when a hardware watchpoint - fired. - (watch_command): Use a hardware watchpoint when possible. If - watching a local expression, build a scope breakpoint too. - (map_breakpoint_numbers): Also call given function for any - related breakpoints. - (disable_breakpoint): Never disable a scope breakpoint. - (enable_breakpoint): Handle hardware breakpoints much like normal - breakpoints, but recompute the watchpoint_scope breakpoint's - frame and address (if we have an associated scope breakpoint). - (read_memory_nobpt): Handle hardware watchpoints like normal - watchpoints. When necessary handle watchpoint_scope breakpoints. - (print_it_normal, bpstat_what, breakpoint_1, mention): Likewise. - (clear_command, breakpoint_re_set_one, enable_command): Likewise. - (disable_command): Likewise. - - * blockframe.c (find_frame_addr_in_frame_chain): New function. - Extern prototype added to frame.h - - * infrun.c (wait_for_inferior): Set current_frame and select - a frame before checking if we stopped due to a hardare watchpoint - firing. Handle stepping over hardware watchpoints. - (normal_stop): Remove unnecessary call to select_frame. - - * value.h (value_release_to_mark): Declare. - * values.c (value_release_to_mark): New function. - - * procfs.c (procfs_wait): Add cases for hardware watchpoints. - (procfs_set_watchpoint, procfs_stopped_by_watchpoint): New functions. - - * hppab-nat.c (hppa_set_watchpoint): New function. - - * config/pa/nm-hppab.h (STOPPED_BY_WATCHPOINT): Define. - (HAVE_STEPPABLE_WATCHPOINT): Define. - (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Define. - (target_{insert,delete}_watchpoint): Define. - - * config/mips/nm-irix4.h (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Define. - (STOPPED_BY_WATCHPOINT, HAVE_NONSTEPPABLE_WATCHPOINT): Likewise. - (target_{insert,remove}_watchpoint): Likewise. - -Mon Apr 11 19:21:27 1994 Stu Grossman (grossman at cygnus.com) - - * xcoffread.c (read_xcoff_symtab): Ignore symbols of class C_EXT, - smtyp XTY_LD, sclass XMC_DS (external data segment label). They - often have the same names as debug symbols for functions, and - confuse lookup_symbol(). - -Mon Apr 11 10:44:35 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * remote.c: Around redefinition of PBUFSIZE, adjust whitespace. - * config/pa/tm-hppa.h (REGISTER_BYTES): Use 4 rather than - REGISTER_RAW_SIZE (1). - Together these changes work around a bug in HP's compiler. Both - seem to be necessary. - -Mon Apr 11 09:18:24 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * paread.c (pa_symtab_read): Handle ST_STUB symbols and symbols - with scope SS_EXTERNAL. ST_ENTRY symbols in dynamic executables - are type mst_solib_trampoline. - -Fri Apr 8 17:14:37 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * config/m68k/es1800.mt: Change comments. - -Fri Apr 8 17:14:37 1994 Rob Savoye (rob@darkstar.cygnus.com) - - * config/m68k/monitor.mt (TDEPFILES): Don't include remote-es.o. - -Fri Apr 8 15:35:30 1994 Stu Grossman (grossman at cygnus.com) - - * lynx-nat.c: Restore regmap structure for SPARC. It's needed - for core files. - -Fri Apr 8 14:53:35 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * values.c (unpack_long): Remove obsolete comment about using a - switch statement. - - * symfile.c (symbol_file_command): Add comments about command syntax. - -Thu Apr 7 17:25:21 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - Jim Kingdon (kingdon@cygnus.com) - - * infrun.c (IN_SOLIB_TRAMPOLINE): Correct comment, trampolines - are in the .plt section. - * minsyms.c (lookup_solib_trampoline_symbol_by_pc, - find_solib_trampoline_target): New functions for handling - stepping into -g compiled shared libraries. - * symtab.h (lookup_solib_trampoline_symbol_by_pc, - find_solib_trampoline_target): Add prototypes. - * config/tm-sunos.h (IN_SOLIB_TRAMPOLINE, SKIP_TRAMPOLINE_CODE): - Define to handle stepping into -g compiled shared libraries. - * config/tm-sysv4.h (SKIP_TRAMPOLINE_CODE): Define to handle - stepping into -g compiled shared libraries. - -Thu Apr 7 17:22:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * configure.in: Add mips-*-sysv4* support. - * config/mips/mipsv4.mh, config/mips/mipsv4.mt, - config/mips/tm-mipsv4.h, config/mips/xm-mipsv4.h, mipsv4-nat.c: - New files for MIPS SVR4 support. - * Makefile.in: Update for new mipsv4 files. - * alpha-tdep.c (heuristic_proc_desc, find_proc_desc): Use - read_next_frame_reg to obtain the frame relative stack pointer. - * mips-tdep.c (heuristic_proc_desc): Use read_next_frame_reg to - obtain the frame relative stack pointer. - * mdebugread.c (parse_partial_symbols, psymtab_to_symtab1): - Handle stStatic and stStaticProc symbols in stabs-in-ecoff output - by entering them into the minimal symbol table. - * printcmd.c (print_scalar_formatted): Do not try to unpack to - a long for float formats. - * solib.c: Include "elf/mips.h" only if DT_MIPS_RLD_MAP does not - get defined in . - * solib.c (solib_add): Add shared library sections to the section - table of the target before adding the symbols. - * partial-stab.h: Relocate static and global functions. - * dbxread.c (read_dbx_symtab): Remove unused variable - end_of_text_address. Relocate text_addr when passing it - to end_psymtab. - - For Alpha OSF/1 targets, enable gdb to set breakpoints in shared - library functions before the executable is run. Retrieve dynamic - symbols from stripped executables. - * mipsread.c (read_alphacoff_dynamic_symtab): New function. - * mipsread.c (mipscoff_symfile_read): Use it. Issue warning message - if no debugging symbols were found. - * alpha-tdep.c (alpha_skip_prologue): Silently return the unaltered - pc if memory at the pc is not accessible and GDB_TARGET_HAS_SHARED_LIBS - is defined. - * config/alpha/nm-alpha.h (GDB_TARGET_HAS_SHARED_LIBS): Define, - OSF/1 has shared libraries. - -Thu Apr 7 15:11:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * dbxread.c (read_dbx_dynamic_symtab): Adjust for recent changes - to BFD handling of dynamic symbols. - -Tue Apr 5 15:29:25 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (hppa_fix_call_dummy): If FUN is a procedure label, - then gets its real address into FUN and its GOT/DP value into %r19. - - * tm-hppa.h (CALL_DUMMY): Use %r20, not %r19 as a temporary. - - * hppa-tdep.c (frameless_function_invocation): If no unwind - descriptor was found, then assume this was not a frameless - function invocation. - (frame_saved_pc): If the saved PC is in a linker stub, then - return the return address which the linker stub will return to. - - * xm-hppab.h: Never define USG. - * xm-hppah.h: Always define USG. - -Tue Apr 5 12:58:47 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * values.c (unpack_long, value_from_longest), - valarith.c (value_binop): Allow TYPE_CODE_RANGE. - -Fri Apr 1 14:04:34 1994 Jason Merrill (jason@deneb.cygnus.com) - - * symfile.c (deduce_language_from_filename): .cpp is a C++ extension. - -Fri Apr 1 00:44:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - For SVR4 targets, enable gdb to set breakpoints in shared - library functions before the executable is run. - * elfread.c (elf_symtab_read): Handle symbols for shared library - functions. - * sparc-tdep.c (in_solib_trampoline): Renamed to in_plt_section - and moved to objfiles.c. - * objfiles.c (in_plt_section): Moved to here from sparc-tdep. - * config/tm-sysv4.h (IN_SOLIB_TRAMPOLINE): Use new in_plt_section. - * config/sparc/tm-sun4sol2.h (IN_SOLIB_TRAMPOLINE): Removed, - the new generic definition from tm-sysv4.h works for Solaris. - -Wed Mar 30 16:14:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * elfread.c (elf_symtab_read): Change storage_needed, - number_of_symbols and i to long. Rename get_symtab_upper_bound to - bfd_get_symtab_upper_bound. Check for errors from - bfd_get_symtab_upper_bound and bfd_canonicalize_symtab. - * nlmread.c (nlm_symtab_read): Same changes. - -Wed Mar 30 11:43:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (xcoff_next_symbol_text): New function. - (read_xcoff_symtab): Set next_symbol_text_func to it. - Move raw_symbol outside of read_xcoff_symtab. - - * remote.c (getpkt): Remove unused "out" label. - -Wed Mar 30 09:15:42 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * breakpoint.c (print_it_normal): Allow GDB to notify the user - about more than one watchpoint being triggered. - -Wed Mar 30 08:24:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m68k/tm-dpx2.h: Include tm-m68k.h not nonexistent tm-68k.h. - -Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * blockframe.c (find_pc_partial_function): mst_file_text - symbols do not live in the shared library transfer table. - * ch-exp.y (decode_integer_value, match_character_literal, - match_bitstring_literal): Guard tolower calls with isupper, - tolower on old BSD systems blindly subtracts a constant. - * dbxread.c (read_ofile_symtab): Check for __gnu_compiled_* as - well when determining the producer of the object file. - * mdebugread.c (has_opaque_xref): New function to check for - cross reference to an opaque aggregate. - * mdebugread.c (parse_symbol, parse_partial_symbols): Do not - enter typedefs to opaque aggregates into the symbol tables. - * mdebugread.c (parse_external): Remove skip_procedures argument, - it has always been 1. Remove code that handled stProc symbols, - it was never executed and was wrong, as the index of a - stProc symbol points to the local symbol table and not to the - auxiliary symbol info. Update caller. - * mdebugread.c (parse_partial_symbols): Do not enter external - stProc symbols into the partial symbol table, they are already - entered into the minimal symbol table. - * config/i386/tm-symmetry.h: Clean up, it is now only used for Dynix. - Remove all conditionals and definitions for ptx. - I386_REGNO_TO_SYMMETRY moved to here from symm-tdep.c. - Fix addresses of floating point registers in REGISTER_U_ADDR. - STORE_STRUCT_RETURN now handles cc and gcc conventions. - FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC, - IN_SIGTRAMP, SIGCONTEXT_PC_OFFSET defined to make backtracing through - signal trampoline code work. - * config/i386/xm-symmetry.h: Clean up, it is now only used for Dynix. - Remove all conditionals and definitions for ptx. - Remove KDB definitions. - * symm-nat.c (store_inferior_registers): Fetch registers before - storing them to obtain valid floating point control registers. - Store fpu registers. - * symm-nat.c (print_1167_control_word): Dynix 3.1.1 defines - FPA_PCR_CC_C0 and FPA_PCR_CC_C1, avoid duplicate case value. - * symm-nat.c (fetch_inferior_registers, child_xfer_memory): - Fix typos. - * symm-nat.c (child_resume): Update type of `signal' parameter. - * symm-tdep.c (I386_REGNO_TO_SYMMETRY): Moved to tm-symmetry.h. - -Tue Mar 29 23:01:33 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (hppa_fix_call_dummy): Use an alternate method for - calling import stubs for functions in shared libraries. - -Tue Mar 29 21:14:04 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * ch-exp.y: Implement SIZE(mode_name) and SIZE(expression). - - * ch-lang.c (chill_is_varying_struct): Magic string is - was "" is now "__var_length" (more portable). - -Tue Mar 29 19:41:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote.c (getpkt): If we get a timeout, actually retry rather - than just giving up the first time it happens. - * remote.c: Document sequence numbers. - (remote_store_registers): Change syntax of 'P' request so that it - never looks like a sequence number. - -Tue Mar 29 16:06:01 1994 Kung Hsu (kung@mexican.cygnus.com) - - * os9kread.c (record_minimal_symbol): add section_offset to - relocate minimal symbol table. - * os9kread.c (read_minimal_symbols): ditto. - * os9kread.c (os9k_symfile_init): increase size of dbg and stb - file names. - * os9kread.c (read_os9k_psymtab): if there's no dbg file, just - return. Also if file addr is 0 leave it 0, not to relocate. - * remote-os9k.c (_initialize_remote_os9k): add 'set remotexon', - 'set remotexoff' and 'set remotelog' commands. - -Tue Mar 29 12:38:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote.c (remote_store_registers): Add 'P' request to set an - individual register. - (remote_write_bytes, remote_read_bytes): Use %lx, not %x, to print - a target address. - -Sat Mar 26 07:05:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/sparc/tm-sparc.h: Define USE_REGISTER_NOT_ARG. - * stabsread (define_symbol): If USE_REGISTER_NOT_ARG, go back to - combining all 'p' and 'r' pairs into a LOC_REGPARM. - - * command.c (do_setshow_command, case var_string): Never add a - space to the end of the string. - * NEWS: Document this change. - * .gdbinit: Add a space to the "set prompt" command. - -Fri Mar 25 12:40:41 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m3-nat.c, i386m3-nat.c, config/i386/i386m3.mh: Many minor - changes to make it compile (it doesn't link yet). - - * buildsym.c (start_subfile, patch_subfile_names), demangle.c - (set_demangling_style, set_demangling_command): Use savestring not - strdup. We were not dealing properly with a NULL return from - strdup, and were not declaring strdup (the system header may or - may not have it). - - * valprint.c (val_print): Remove inaccurate comment about what - types can be stub types. - - * config/i386/ptx.mh (XDEPFILES): Add coredep.o. Delete infptrace.o. - * symm-nat.c (child_wait, _initialize_symm_nat, kill_inferior): - Supply alternate version if ATTACH_DETACH is not defined. - * ptx4-nat.c, config/i386/{nm-ptx4.h, ptx4.mh, ptx.mt, ptx4.mt, - tm-ptx.h, tm-ptx4.h, xm-ptx.h, xm-ptx4.h}: New files. - * configure.in: Recognize i[34]86-sequent-sysv4* host. - -Fri Mar 25 10:14:03 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (skip_prologue): Do nothing if not at the beginning - of a function. - (skip_trampoline_code): Rewrite and add support for argument - relocation stubs stubs, import/export stubs, calls through - "_sr4export" and cascaded trampolines. - - * hppa-tdep.c (skip_prologue): Return "pc" not zero - if no unwind descriptor is found. - - * tm-hppa.h (NUM_REGS): Bump to 128 registers. - (REGISTER_NAMES): Add entries for "right-half" of FP registers. - (REGISTER_RAW_SIZE, MAX_REGISTER_RAW_SIZE): Do not treat FP regs - differently. All registers are four bytes. - (REGISTER_BYTES, REGISTER_BYTE): Simplify now that all registers are - the same size. - (REGISTER_VIRTUAL_TYPE): Use builtin_type_float for all FP regs. - - * hppa-tdep.c (pa_print_fp_reg): Update to print even numbered FP - registers as both single and double values (fetching 2nd 32bit half - as necessary). Annotate each register printed with its precision. - - * paread.c (read_unwind_info): Fix off-by-one error. - -Fri Mar 25 08:33:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (complete_command): Deal with it if arg is NULL. - -Thu Mar 24 07:12:09 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/mips/tm-mips.h (SETUP_ARBITRARY_FRAME): Revise comment - regarding using the PC--using the PC is necessary and all the - FIXME comments in the world won't make it go away. - - * valops.c (value_at, value_at_lazy): Give error if we dereference - a pointer to void. - * gdbtypes.h: Fix comments regarding TYPE_CODE_VOID. - * stabsread.c: Use 1, not 0, for TYPE_LENGTH of void types. - - * stabsread.c (patch_block_stabs): Add comment about what happens - if the definition is in another compilation unit from the stab. - - * dbxread.c (end_psymtab): Add comment about empty psymtabs. - -Wed Mar 23 07:50:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (complete_command): New command, from Rick Sladkey - . - (symbol_completion_function): Don't declare rl_point and - rl_line_buffer; they are now declared in readline.h. - (show_commands): Don't declare history_base; it is declared in - history.h. - * command.c (lookup_cmd): Don't delete trailing whitespace. - Reverts change of 14 May 1989. - -Wed Mar 23 16:14:52 1994 Stu Grossman (grossman at cygnus.com) - - * minsyms.c (prim_record_minimal_symbol): Move section deduction - code from prim_record_minimal_symbol_and_info() to here. Callers - of the latter can legitimately supply a section number of -1. - -Wed Mar 23 07:50:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbtypes.h, gdbtypes.c: Add comments regarding whether static - member functions have an element in args for a (nonexistent) this - pointer. - -Tue Mar 22 20:12:53 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * config/pa/tm-hppao.h (NO_PC_SPACE_QUEUE_RESTORE): Define. - - * hppa-tdep.c (hppa_pop_frame): Do not restore the PC space - queue if NO_PC_SPACE_QUEUE_RESTORE is defined. - - * stabsread.c (REG_STRUCT_HAS_ADDR): Accept additional argument - for the structure's type. All callers changed. - - * valops.c (call_function_by_hand): Check REG_STRUCT_HAS_ADDR - for each structure argument rather than assuming it's either - true or false for all structure arguments. - - * config/pa/tm-hppa.h (REG_STRUCT_HAS_ADDR): Depend only - on the length structure passed, not the compiler used. - - * config/sparc/tm-sparc.h (REG_STRUCT_HAS_ADDR): Accept additional - argument for the structure's type. - -Tue Mar 22 15:28:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * values.c (set_internalvar): Don't set var->value until we are - sure there won't be an error(). - - * remote.c (get_offsets): Reinstate comment which was in - remote_wait about use of SECT_OFF_TEXT and so on. - -Mon Mar 21 13:11:30 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symmisc.c (maintenance_check_symtabs): New function to check - consistency of psymtabs and symtabs. - * symtab.h (maintenance_check_symtabs): Add prototype. - * maint.c: Add new `maint check-symtabs' command. - * config/i386/tm-i386aix.h, config/i386/tm-sun386.h, - config/i386/tm-symmetry.h (REGISTER_CONVERT_TO_RAW): Fix typo. - * config/i386/tm-symmetry.h: Make comment inside #if 0 a real - comment. - * config/i386/tm-symmetry.h (STORE_STRUCT_RETURN): Cast argument - to write_memory to avoid warnings from gcc. - * config/i386/xm-symmetry.h: Add missing #endif. - * config/i386/nm-symmetry.h (NO_PTRACE_H): Add for Dynix. - * config/i386/symmetry.mt (TDEPFILES): Add i386-tdep.o. - * config/i386/symmetry.mh (NAT_FILE, NATDEPFILES): Add. - -Mon Mar 21 11:50:28 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (hppa_fix_call_dummy): Use value_ptr. - (hppa_push_arguments): Likewise. - -Mon Mar 21 11:02:51 1994 Stu Grossman (grossman at cygnus.com) - - * alpha-tdep.c: Gobs of changes (many imported from mips-tdep) to - improve remote debugging efficiency. Also fixed problems with - doing function calls for programs with no entry points. - * infcmd.c (run_stack_dummy): Use CALL_DUMMY_ADDRESS instead of - entry_point_address. - * inferior.h (PC_IN_CALL_DUMMY): ditto. - * mdebugread.c (parse_symbol, parse_procedure, parse_external, - parse_lines): Pass section_offsets info to these routines so that - we can relocate symbol table entries upon readin. - * (psymtab_to_symtab_1): Set symtab->primary to tell - objfile_relocate to do relocations for our symbols. - * (ecoff_relocate_efi): New routine to relocate adr field of PDRs - (which hang off of the symbol table). - * Use prim_record_minimal_symbols_and_info instead of - prim_record_minimal_symbols to supply section info to make minimal - symbol relocations work. - * minsyms.c (prim_record_minimal_symbols_and_info): If section is - -1, try to deduce it from ms_type. - * objfiles.c (objfile_relocate): Use ALL_OBJFILE_SYMTABS where - appropriate. Handle relocation of MIPS_EFI symbols special. Also, - add code to relocate objfile->sections data structure. - * remote.c (get_offsets): Use new protocol message to acquire - section offsets from the target. - * (remote_wait): Get rid of relocation stuff. That's all handled - by objfile_relocate now. - * config/alpha/alpha-nw.mt (TM_FILE): Use tm-alphanw.h. - * config/alpha/tm-alpha.h: Define CALL_DUMMY_ADDRESS, and - VM_MIN_ADDRESS. - * config/alpha/tm-alphanw.h: DECR_PC_AFTER_BREAK=0, VM_MIN_ADDRESS=0. - -Mon Mar 21 10:09:06 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (_initialize_hpuxread): Don't call add_symtab_fns if - HPREAD is not defined. - -Sun Mar 20 15:21:57 1994 Doug Evans (dje@cygnus.com) - - * sparc-tdep.c (sparc_frame_find_save_regs): Use REGISTER_RAW_SIZE - instead of 4. - * sp64-tdep.c (target_ptr_bit, set_target_ptr_bit): Deleted, - can no longer set this at run time. - * config/sparc/sp64.mt (SIMFILES): Use remote-sim.o now. - (TM_CLIBS): Define to -lm, the simulator uses the sqrt() function. - * config/sparc/tm-sp64.h (FPS_REGNUM, CPS_REGNUM): Define (so - sparc-tdep.c compiles). - (TARGET_PTR_BIT): Must be a constant now, fix at 64. - -Sat Mar 19 08:51:12 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m68k/{cisco.mt,tm-cisco.h}: New files. - * Makefile.in (ALLPARAM, ALLCONFIG): Add them. - * configure.in: Recognize m68*-cisco*-*. - - * Makefile.in (TAGS): Use variables directly, rather than using - find, to locate TM_FILE, XM_FILE, and NAT_FILE. This is faster - and means that these filenames no longer need be unique across all - the config/* directories. - * configure.in: Put the config/*/ into TM_FILE, etc. - - * m68k-stub.c (computeSignal): Return SIGFPE, not SIGURG, for chk - and trapv exceptions. - - * target.h (struct section_table), objfiles.h (struct obj_section): - Change name of field sec_ptr to the_bfd_section. More mnemonic - and avoids the (sort of, for the ptx compiler) name clash with - the name of the typedef. - * exec.c, xcoffexec.c, sparc-tdep.c, rs6000-nat.c, osfsolib.c, - solib.c, irix5-nat.c, objfiles.c, remote.c: Change users. - - * utils.c: Include readline.h. - * Makefile.in (utils.o): Add dependency. - - * remote.c (getpkt): Add support for run-length encoding. - -Fri Mar 18 19:11:15 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * utils.c (prompt_for_continue): Call readline, not gdb_readline. - -Fri Mar 18 10:25:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dstread.c (record_minimal_symbol): New arg objfile. Pass it to - prim_record_minimal_symbol. - Callers: Pass it. - - * regex.c (EXTEND_BUFFER): Adjust pointers within buffer by - computing their offset from the start of the old buffer and adding - to the new buffer, rather than by assuming we can add the - difference between the old buffer and the new buffer (it might not - fit in an int). Merge in cosmetic differences from emacs regex.c - version of this macro. - -Wed Mar 16 15:28:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * Makefile.in (install-only): Fix use of program_transform_name. - -Wed Mar 16 07:18:43 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c: Remove "set print fast-symbolic-addr off" command. - The bug which it worked around was fixed on 25 Feb 94 in coffread.c, - so I'm nuking the command. - * symtab.c (find_addr_symbol): Comment out, no longer used. - - * main.c (main): Don't init_source_path for the -cd argument. Now - that source_path doesn't contain the current_directory from when - GDB started up, init_source_path is no longer useful (and is - harmful because it clobbers a source_path set in $HOME/.gdbinit). - - * TODO: Remove item about line numbers being off. It is useless - and confusing without a reproducible test case (it mentions - proceed(), but I was able to step through proceed without trouble). - -Tue Mar 15 13:39:23 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - For Sunos 4.x targets, enable gdb to set breakpoints in shared - library functions before the executable is run. Retrieve dynamic - symbols from stripped executables. - * symtab.h (minimal_symbol_type): Add mst_solib_trampoline type. - * parse.c (write_exp_msymbol), symmisc.c (dump_msymbols), - symtab.c (list_symbols): Handle mst_solib_trampoline. - * minsyms.c (lookup_minimal_symbol): Handle mst_solib_trampoline - for all targets, remove IBM6000_TARGET dependencies. - * dbxread.c (read_dbx_dynamic_symtab): New function. - * dbxread.c (dbx_symfile_read): Use it. - * dbxread.c (SET_NAMESTRING): Set namestring to - "" instead of "foo" if the string index is - corrupt. - * xcoffread.c (read_xcoff_symtab): Use mst_solib_trampoline instead - of mst_unknown. - * symtab.c (list_symbols): Take from_tty as parameter and pass it - to break_command. Handle mst_file_* minimal symbol types. - * config/i386/tm-i386bsd.h: Give just macro name, not args, to #undef. - -Tue Mar 15 11:40:43 1994 Kung Hsu (kung@mexican.cygnus.com) - - * c-exp.y(yylex): fix potential memory overflow. - -Tue Mar 15 10:33:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * environ.c (set_in_environ): Eliminate special handling of PATH and - GNUTARGET. - * putenv.c: Removed, conflicts with system declaration of - putenv on RS/6000 running AIX 3.2.5, and above change makes it - unnecessary. - * Makefile.in: Change accordingly. - * procfs.c (procfs_create_inferior): Change comment accordingly. - -Tue Mar 15 10:05:27 1994 Jim Kingdon (kingdon@cygnus.com) - - * rs6000-tdep.c: Change value to value_ptr. - -Sun Mar 13 17:19:03 1994 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (read_hpux_symtab: Correctly determine the namespace - and address class of SVAR, DVAR, TYPEDEF, TAGDEF, CONST, and - MEMENUM symbols. Do not include function-scoped variables in - the partial symbol table. - -Sun Mar 13 09:45:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * i386m3-nat.c: Include floatformat.h. - (get_i387_state): Use memset not bzero. - - * Version 4.12.3. - - * Makefile.in: Enable commented out getopt_h, bfd_h, etc. Change - ieee-float.h to floatformat.h. - - * valprint.c (val_print_string): Ignore error if the error - happened after a terminating '\0'. - - * c-valprint.c (c_val_print): Never add 1 to return value from - val_print_string; just return what it returns. - - * target.h (enum target_signal): Add TARGET_SIGNAL_FIRST, for - looping through all of the enums. - * infrun.c (signals_info): Use it. - -Fri Mar 11 08:08:50 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (main): When printing warning about bad baud rate, don't - use warning(); it relies on current_target which isn't set up yet. - - * breakpoint.c (_initialize_breakpoint): Update docstring for - tbreak to match what the code actually does. Don't mention tbreak - in docstrings for "enable once" or "enable breakpoints once". - -Thu Mar 10 08:52:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Don't put a semicolon after - while (0). That defeats the whole purpose of using do . . . while (0). - * mdebugread.c (parse_partial_symbols): Don't use ?: expression as - list for ADD_PSYMBOL_TO_LIST; the macro takes its address and - using a ?: expression as an lvalue is not portable. - - * stabsread.c (define_symbol): If REG_STRUCT_HAS_ADDR, also - convert a LOC_ARG to a LOC_REF_ARG. Update code which combines - 'p' and 'r' symbol descriptors into a single symbol to look for a - LOC_REF_ARG. - * README, config/sparc/tm-sparc.h: Update comments. - -Wed Mar 9 21:43:24 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_type): Do not complain for types with - an `indexNil' aux index, these are simply undefined types. - Remove indexNil check from caller of parse_type. - * mdebugread.c (parse_partial_symbols): Do not enter - stGlobal, scCommon symbols into the minimal symbol table, their - value is the size of the common, not its address. - Handle scInit, scFini, scPData and scXData sections. - Use minimal symbol type mst_file_* for stLabel symbols, instead of - mst_*. - Enter stProc symbols into the global_psymbols list once, not into - the static_psymbols_list. - Get rid of dummy psymtab if it is empty, to allow proper detection - of stripped executables. - * mdebugread.c (cross_ref): Allow cross references to Fortran - common blocks. - -Wed Mar 9 15:23:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (common_block_end, fix_common_block): Stash the - struct pending * in the SYMBOL_TYPE, not the SYMBOL_NAMESPACE, so - as to not assume that a pointer fits in an enum. - -Wed Mar 9 18:56:36 1994 Kung Hsu (kung@mexican.cygnus.com) - - * os9kread.c (fill_sym): check compiler verion number for pre- - UltraC compiler. - * os9kread.c (os9k_process_one_symbol): address of symbol is - relative to section not module. - * stabsread.c (define_symbol): add symbol type 's' as local - symbol for os9k. - * remote-os9k.c: add command 'set monitor_log' to turn on or off - monitor logging. - * remote-os9k.c: fix bug in delete breakpoint, single step trace. - * remote-os9k.c: fix bug in 'set remotebaud' function. - * remote-os9k.c (rombug_link): minimize checking so to improve - speed. - * symfile.c (symbol_file_command): check if failed to link, also make - the command be able to accept more than one filenames. - * target.c (target_link): check if failed to link with rombug. - * config/i386/tm-i386os9k.h : add #define DECR_PC_AFTER_BREAK 0. - -Wed Mar 9 15:23:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-es.c (es1800_child_ops): Don't declare it static. - -Tue Mar 8 11:42:39 1994 Jim Kingdon (kingdon@cygnus.com) - - * config/i386/tm-i386v4.h: Give just macro name, not args, to #undef. - -Tue Mar 8 06:56:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c: New variable lowest_text_address. - (record_minimal_symbol, read_dbx_symtab): Set it. - (read_dbx_symtab): Use lowest_text_address + text_size instead of - end_of_text_address. - * config/gould/tm-pn.h: Add comment regarding END_OF_TEXT_DEFAULT. - - * dbxread.c (end_psymtab): Remove old and commented out - capping_global and capping_static. Fix comments regarding - N_SO_ADDRESS_MAYBE_MISSING to match the real name of the macro. - - * parser-defs.h: Add "extern" to start of variable declarations so - we don't end up with commons. - * parse.c: Define these variables. - - * irix5-nat.c (find_solib): Cast o_path to CORE_ADDR when using it - as one. - -Mon Mar 7 13:00:50 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * alpha-tdep.c: Change value to value_ptr. - -Sun Mar 6 17:36:53 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * solib.c (elf_locate_base): New function to locate the address - of the dynamic linker's runtime structure in the dynamic info section. - * solib.c (locate_base): Use it instead of iterating over the list - of mapped address segments. - * solib.c (look_for_base, bfd_lookup_symbol): Removed, no longer - necessary. - -Fri Mar 4 09:50:47 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (pc_in_linker_stub): Move decl to beginning of file. - (pc_in_interrupt_handler): New function. Also add PARAM decl. - (find_proc_framesize): Deal with HPUX setting SAVE_SP bit for - signal trampoline and interrupt routines. - (frame_saved_pc): Handle signal trampolines and interrupt routines. - (frame_chain, frame_chain_valid): Likewise. - (hppa_frame_find_saved_regs): Likewise. Also deal with special - saved regs convention for SP. - - * tm-hppa[bho].h: FRAME_FIND_SAVED_PC_IN_SIGTRAMP): Define. - (FRAME_BASE_BEFORE_SIGTRAMP): Define. - (FRAME_FIND_SAVED_REGS_IN_SIGTRAMP): Define. - - * tm-hppah.h (IN_SIGTRAMP): Define. - -Thu Mar 3 12:41:16 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * ch-exp.y (match_simple_name_string): Accept '_' as well as an - alphabetic character as the start of a name. - - * sparclite/Makefile.in (all install): Build and install aload. - - * configure.in: Accept i[34]86-*-*sysv32 because that is what - config.guess and config.sub produce. - - * mips-tdep.c: Change value to value_ptr. - -Wed Mar 2 09:17:55 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * breakpoint.c, breakpoint.h, c-valprint.c, ch-valprint.c, - cp-valprint.c, eval.c, expprint.c, findvar.c, language.c, - objfiles.h, infcmd.c, printcmd.c, stack.c, typeprint.c, - valarith.c, valops.c, valprint.c, value.h, values.c: Replace - value with value_ptr. This is for the ptx compiler. - * objfiles.h, target.h: Don't declare a "sec_ptr" field using a - "sec_ptr" typedef. - * symm-nat.c: Add a bunch of stuff for symmetry's ptrace stuff. - #if 0 i386_float_info. - * symm-tdep.c (round): Remove. Also remove sgttyb. - * symm-tdep.c: Remove lots of stuff which duplicates stuff from - i386-tdep.c. Remove register_addr and ptx_coff_regno_to_gdb. - * i386-tdep.c (i386_frame_find_saved_regs): Put in - I386_REGNO_TO_SYMMETRY check in case it is needed for Dynix - someday. - * config/i386/nm-symmetry.h: Change KERNEL_U_ADDR. Move - stuff from PTRACE_READ_REGS, PTRACE_WRITE_REGS macros to - symm-nat.c. Define CHILD_WAIT and declare child_wait(). - * config/i386/tm-symmetry.h: Remove call function stuff; stuff in - tm-i386v.h is apparently OK. - * config/i386/xm-symmetry.h [_SEQUENT_]: Define HAVE_TERMIOS not - HAVE_TERMIO. Define MEM_FNS_DECLARED, NEED_POSIX_SETPGID, and - USE_O_NOCTTY. - -Wed Mar 2 11:31:08 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * osfsolib.c (xfer_link_map_member): Update to use new - target_read_string interface. - -Wed Mar 2 09:17:55 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * infrun.c (wait_for_inferior): In checking - remove_breakpoints_on_following_step, check - through_sigtramp_breakpoint as well as step_resume_breakpoint. - -Tue Mar 1 16:22:56 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * os9kread.c (os9k_process_one_symbol): Rename - VARIABLES_INSIDE_BLOCK to OS9K_VARIABLES_INSIDE_BLOCK. - * symfile.c (symbol_file_command): Check for (CORE_ADDR)-1, not - (CORE_ADDR)0, from target_link, since that is what it uses. - Process name at end, not during parsing (like we did before Kung's - change), so that -readnow and -mapped can appear anywhere. - Make text_relocation a local variable. - * config/i386/i386os9k.mt: Fix comment. - * Makefile.in (ALLDEPFILES): Add remote-os9k.c. - * os9kread.c: Put "comments" after #endif inside /* */. - * stabsread.h: Add os9k_stabs variable. - * stabsread.c (start_stabs), os9kread.c (os9k_process_one_symbol): - Set it. - * stabsread.c (define_symbol): If os9k_stabs, put a 'V' symbol - descriptor in global_symbols not local_symbols. - (read_type): If os9k_stabs, accept 'c', 'i', and 'b' type - descriptors. - (read_type): If os9k_stabs, accept function parameters after 'f' - type descriptor. - (read_array_type): If os9k_stabs, don't expect index type and - expect lower and upper to be separated by ',' not ';'. - (read_enum_type): If os9k_stabs, read a number before the first - enumeration constant. - (os9k_init_type_vector): New function. - (dbx_lookup_type): Call it when starting new type vector. - * config/i386/tm-i386os9k.h: Define BELIEVE_PCC_PROMOTION. - * (os9k_process_one_symbol): Call define_symbol not os9k_define_symbol. - * os9kstab.c: Removed. - * Makefile.in: Update accordingly. - * objfiles.c (objfile_relocate_data): Removed. - * remote-os9k.c (rombug_wait): Call objfile_relocate - not objfile_relocate_data. - * objfiles.h, objfiles.c: Remove find_pc_objfile. - * remote-os9k.c (rombug_wait): Call find_pc_section not - find_pc_objfile. - * main.c (quit_command): Check inferior_pid; revert Kung change. - * remote-os9k.c (rombug_create_inferior): Set inferior_pid. - -Tue Mar 1 14:56:14 1994 Kung Hsu (kung@mexican.cygnus.com) - - * os9kread.c: New file to read os9000 style symbo table. - * os9kstab.c: new file to read os9000 style stabs. - * remote-os9k.c: remote protocol talking to os9000 rombug monitor. - * objfiles.c (find_pc_objfile): new function to search objfile - from pc. - * objfiles.c (objfile_relocate_data): new function to relocate - data symbols in symbol table. - * objfiles.h: Add two aux fields in struct objfile to handle - multiple symbol table files situation like in os9000. - * symfile.c: Change so 'symbol-file' command can handle multiple - files. Also call target_link() to get relocation infos. - * target.c (target_link): new function to get relocation info when - a symbol file is requested to load. - * main.c (quit_command): take out 'inferior_pid != 0' condition, - because in cross mode there's no inferior pid, bit they need to - be detached. - Makefile.in: add os9kread.c os9kstab.c and .o's. - configure.in: add i386os9k target. - config/i386/i386os9k.mt: new add. - config/i386/tm-i386os9k.h: new add. - -Tue Mar 1 13:16:10 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/sparc/tm-sun4sol2.h (IN_SIGTRAMP): Handle ucbsigvechandler. - * sparc-tdep.c (sparc_frame_saved_pc): Handle ucbsigvechandler. - -Tue Mar 1 11:54:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * target.c, target.h (target_read_string): Provide error detection to - caller. Put string in malloc'd space, so caller need not impose - arbitrary limits. - * solib.c (find_solib): Update to use new interface. - * irix5-nat.c (find_solib): Read o_path from inferior - (clear_solib): Free storage for o_path. - * valprint.c (val_print_string): Add comments. - -Mon Feb 28 23:54:39 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symtab.c (decode_line_1): Handle the case when skip_quoted does not - advance `p'. - -Mon Feb 28 12:40:46 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * value.h (struct value): Add modifiable field. - * values.c (allocate_value, record_latest_value, value_copy): Set it. - (record_latest_value): Don't mess with VALUE_LVAL of value. - * valops.c (value_assign): Check it. Reword existing error - message on not_lval. - - * mips-tdep.c (mips_step_skips_delay), config/mips/tm-mips.h - (STEP_SKIPS_DELAY): Added. - * infrun.c (proceed) [STEP_SKIPS_DELAY]: Check for a breakpoint in - the delay slot. - - * valprint.c (val_print_string): If errcode is set, always print - an error, regardless of force_ellipsis. In the non-EIO case, - just print the error message rather than calling error(). Don't - access *(bufptr-1) if bufptr points to the start of the buffer. - When looking for '\0', don't increment bufptr and addr if bufptr - started out already at limit. If an error happens on fetching the - first character, don't print the string. - -Sun Feb 27 21:05:06 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * config/m68k/tm-apollo68b.h: Remove HAVE_68881 define; it is - obsolete. - - * i387-tdep.c, i386-tdep.c i386v-nat.c, i386aix-nat.c, - i386m3-nat.c, config/m68k/tm-m68k.h, i960-tdep.c - config/i960/tm-i960.h, remote-nindy.c, config/m88k/tm-m88k.h, - m88k-tdep.c: Use floatformat.h instead of ieee-float.h. - * sparc-tdep.c: Remove now-obsolete ieee-float.h stuff - * findvar.c: Update comment regarding ieee-float.h. - -Sun Feb 27 21:39:48 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/i386/tm-i386v4.h (I386V4_SIGTRAMP_SAVED_PC, IN_SIGTRAMP, - FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC): - Define to make backtracing through the various sigtramp handlers - work. - * i386-tdep.c (i386v4_sigtramp_saved_pc): New routine to fetch - the saved pc from ucontext on the stack for SVR4 signal handling. - -Fri Feb 25 09:41:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * remote.c, remote-mon.c, remote-utils.c, remote-utils.h, - target.h, remote-es.c, remote-nindy.c: Don't set baud rate if - baud_rate is -1. Remove sr_get_baud_rate and sr_set_baud_rate; - just use the global variable itself. When printing baud rate, - don't print a baud rate if baud_rate is -1. - - * coffread.c (read_coff_symtab): Pass mst_file_* to - record_minimal_symbol for C_STAT symbols. Put C_EXT and C_STAT - symbols in the minimal symbols regardless of SDB_TYPE. - -Thu Feb 24 08:30:33 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * breakpoint.h (enum bptype): New type bp_through_sigtramp. - (bpstat_what_main_action): New code BPSTAT_WHAT_THROUGH_SIGTRAMP. - * breakpoint.c (bpstat_what): Return BPSTAT_WHAT_THROUGH_SIGTRAMP - if we hit a bp_through_sigtramp breakpoint. Remove kludge which - ignored bs->stop for a bp_step_resume breakpoint. - * infrun.c (wait_for_inferior): Make a through_sigtramp_breakpoint - which performs one (the check_sigtramp2 one) of the functions - which had been handled by the step_resume_breakpoint. For each - use of the step_resume_breakpoint, make it still use the - step_resume_breakpoint, use the through_sigtramp_breakpoint, or - operate on both. - Deal with BPSTAT_WHAT_THROUGH_SIGTRAMP return from bpstat_what. - When setting the frame address of the step resume breakpoint, set - it to the address for frame *before* the call instruction is - executed, not after. - - * mips-tdep.c (mips_print_register): Print integers using - print_scalar_formatted rather than duplicating all the - CC_HAS_LONG_LONG and so on. - (mips_push_dummy_frame): Use read_register_gen rather than using - read_register and then putting it back in target format with - store_unsigned_integer. If registers are more than 4 bytes, give - an error rather than have some registers overwrite other - registers. - #if 0 unused include of opcode/mips.h. - - * symfile.h: Don't declare arguments for coff_getfilename. - - * defs.h: Revert Kung change regarding FORCE_LONG_LONG. - -Thu Feb 24 08:06:52 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * configure.in (hppa*-*-osf*): New configuration. - * config/pa/hppaosf.mt: New target makefile fragment. - * config/pa/tm-hppao.h: New target include file. - -Thu Feb 24 04:29:19 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * exec.c (print_section_info): Print entry point for exec_bfd only. - * ser-unix.c (wait_for): Fix typo in HAVE_TERMIO case. - * dwarfread.c: Remove second inclusion of , which - causes problems if has no multiple inclusion protection. - -Wed Feb 23 16:28:55 1994 Jeffrey A. Law (law@cygnus.com) - - * tm-hppa.h (CALL_DUMMY): Add two NOP instructions to the end of - the call dummy to avoid kernel bugs in HPUX, BSD, and OSF1. - (CALL_DUMMY_LENGTH): Changed accordingly. - -Wed Feb 23 16:21:25 1994 Stu Grossman (grossman at cygnus.com) - - * sparc-stub.c (trap_low): Make trap handler work for arbitrary - numbers of register windows. - - * sparclite/hello.c: Add factorial function for testing. - * salib.c: Use macros instead of constants for I/O addresses to - make 931 support easier. - * sparclite.h: Change constraint for LOC to "rJ" to force use of - register in sta/lda instructions. - -Wed Feb 23 10:39:18 1994 Jim Kingdon (kingdon@rtl.cygnus.com) - - * dbxread.c (process_one_symbol): Set - block_address_function_relative for COFF like we do for ELF and SOM. - -Sat Feb 19 03:17:32 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (new_psymtab): Pass in section_offsets and set - them in the pst. - * mdebugread.c (handle_psymbol_enumerators): New function to enter - the enumerators of an ecoff enum into the partial symbol table. - * mdebugread.c (parse_partial_symbols): Call it. - * symfile.c (reread_symbols): Initialize objfile->*_psymbols.next. - * symmisc.c (dump_psymtab): Fix typo, clean up output of section - offsets. Cast psymtab->read_symtab to PTR before passing it to - gdb_print_address. - * i386-tdep.c (i386_skip_prologue): Skip over instructions that - set up the global offset table pointer in pic compiled code. - * config/mips/tm-mips.h (FIX_CALL_DUMMY): For big endian targets, - error() on TYPE_CODE_FLT arguments whose size is greater than 8, - swap all other TYPE_CODE_FLT arguments as mips_push_arguments - ensures that floats are promoted to doubles before they are pushed - on the stack. - -Fri Feb 18 23:12:59 1994 Stu Grossman (grossman at cygnus.com) - - * sparclite/Makefile.in, sparclite/salib.c, sparclite/sparclite.h: - Fixup cache_on and flush_i_cache so that they work for both the - 930 and 932 processors. Rewrite most low level funcs (uart - access & cache stuff) to use new ASI access macros in sparclite.h. - Also make it easy to access second serial port. - -Fri Feb 18 22:17:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * hp300ux-nat.c: Don't incloude , , or - ; not needed. - -Fri Feb 18 08:26:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stack.c (print_frame_info): In "pathological" case, don't - distrust the line number information. - -Fri Feb 18 16:51:14 1994 Kung Hsu (kung@mexican.cygnus.com) - - * mips-tdep.c (mips_print_register): handle 64 bits register. - * valprint.c (print_longest): fix a bug in printing 64 bits value. - -Fri Feb 18 08:26:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Version 4.12.2. - - * Makefile.in (install): Do the sed for program_transform_name - ourselves instead of worrying about INSTALL_XFORM. This enables - users to override INSTALL_PROGRAM in the standard way. - - * Makefile.in (c-exp.tab.o, ch-exp.tab.o, m2-exp.tab.o): Don't - depend on Makefile.in. - - * defs.h, valprint.c: Make longest_to_int a function not a macro. - Only test against INT_MIN if a LONGEST is bigger than an int. - - * README: Change GhostScript to Ghostscript. - -Fri Feb 18 07:30:55 1994 Jim Kingdon (kingdon@cygnus.com) - - * config/rs6000/{tm-rs6000lynx.h,nm-rs6000lynx.h,xm-rs6000lynx.h}: - Rename to tm-rs6000ly.h, nm-rs6000ly.h, xm-rs6000ly.h for 14 - character file names. - * Makefile.in (ALLPARAM): Add these files. - - * config/mips/littlemips64.mt: Rename to mipsel64.mt for 14 - character file names. - * Makefile.in: Add Kung's new mips64 files. - -Thu Feb 17 17:25:47 1994 Kung Hsu (kung@mexican.cygnus.com) - - * configure.in: add mips64-*-elf, mips64-*-ecoff, mips64el-*-elf, - mips64el-*-ecoff and mips64-big-*. - * defs.h: get rid of FORCE_LONG_LONG. - * mips-tdep.c (mips_find_saved_regs): add sd and sdc1 instruction - parsing. Change register size to be MIPS_REGSIZE. - -Thu Feb 17 09:30:22 1994 David J. Mackenzie (djm@thepub.cygnus.com) - - * corelow.c, exec.c, irix5-nat.c, mipsread.c, objfiles.c, - osfsolib.c, rs6000-nat.c, solib.c, symfile.c, utils.c, - xcoffexec.c: Use bfd_get_error and bfd_set_error and new error names. - -Fri Feb 11 21:47:24 1994 Steve Chamberlain (sac@sphagnum.cygnus.com) - - * remote-hms.c (readchar, hms_open, hms_fetch_register): Made more robust. - (remove_commands, add_commands): Add/remove hms-drain when target - is connected. - -Fri Feb 11 16:11:38 1994 Stu Grossman (grossman at cygnus.com) - - * configure.in: Add Lynx/rs6000 support. - * lynx-nat.c: Clean up some Sparc stuff. Clean up ptrace error - messages. Add rs6000 support. Don't try to modify unwritable - registers. - * rs6000-nat.c: Move lots of native dependent stuff (like core - file support) from rs6000-tdep.c & xcoffexec.c to here. - * rs6000-tdep.c: Move native dependent stuff to nat.c. - * xcoffexec.c: Move native dependent stuff to nat.c. - * config/rs6000/nm-rs6000.h: Move defs of SOLIB_* macros to here - from tm file. - * config/rs6000/tm-rs6000.h: Remove defs of SOLIB_* funcs, cuz they're - really native. - * config/rs6000/tm-rs6000lynx.h, config/rs6000/xm-rs6000lynx.h: - New files to support Lynx/rs6000. - -Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * README: Remove note about gcc warnings on alpha, these should be - gone now. - * c-exp.y, ch-exp.y, core.c, corelow.c, eval.c, fork-child.c, - m2-exp.y, minsyms.c, nlmread.c, parse.c, putenv.c, regex.c - remote-utils.c, stabsread.c: Include . - * regex.c: Include "defs.h", change re_comp argument to const char *. - * infptrace.c (fetch_register, store_inferior_registers): Change - regaddr to type CORE_ADDR. - * config/alpha/alpha-nw.mt, config/alpha/alpha-osf1.mt (MT_CFLAGS): - Remove, no longer necessary now that we use bfd_vma for a CORE_ADDR. - -Mon Feb 7 09:21:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * symtab.h: Always define BYTE_BITFIELD to nothing. - -Mon Feb 7 08:44:17 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * config/m68k/{m68k-em.mt,tm-m68k-em.h}: Remove; no longer used. - * configure.in: Remove comment about m68k-em.mt. - * Makefile.in: Remove references. - -Mon Feb 7 08:22:42 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * defs.h [BFD64]: Use BFD_HOST_64_BIT, not nonexistent - BFD_HOST_64_TYPE. - -Sun Feb 6 15:56:09 1994 Jeff Law (law@wild.cs.utah.edu) - - * hpread.c (hpux_symfile_init): Use obj_som_* rather than obj_* to - access BFD private data. Search for the "$TEXT$" space rather - than ".text". - (hppa_sym_fns): Add bfd target flavour to initializer. - -Sun Feb 6 06:55:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * target.c (target_preopen): If target_kill doesn't remove the - target from the stack, use pop_target to do it. - - * coffread.c (process_coff_symbol, case C_TPDEF): Don't set name - of TYPE_CODE_PTR or TYPE_CODE_FUNC types. This parallels similar - changes to stabsread.c from summer 1993. - - * remote-udi.c (udi_files_info): If prog_name is NULL, just skip - printing the program, rather than passing NULL to printf. - (udi_detach): Set udi_session_id to -1 so that udi_close doesn't - try to call UDIDisconnect again. Print better message. - (udi_kill): Just call UDIDisconnect ourselves, rather than doing - it via udi_close. - (udi_create_inferior): If udi_session_id is negative, open a new - TIP rather than giving an error. - - * config/mips/mipsm3.mh, config/i386/i386m3.mh, - config/ns32k/ns32km3.mh: Define NAT_FILE. - * config/nm-m3.h: Change guard from _OS_MACH3_H_ and _OS_MACH3_H - (it was inconsistent and namespace-wrong) to NM_M3_H. - * m3-nat.c (mach_really_wait): Change parameter name to ourstatus. - (m3_open): New function. - (m3_ops): Use it. - * TODO: Update Mach section. - - * Makefile.in: Remove "rapp" stuff; it is superseded by gdbserver. - -Sun Feb 6 13:26:21 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * printcmd.c (printf_command): Add missing single-letter - backslash-escape sequences, and improve error message. - -Sun Feb 6 06:55:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * corelow.c (solib_add_stub, core_open): Pass address of from_tty - rather than trying to shove an int into a pointer and back out - again. This avoids compiler warnings. - - * defs.h (alloca): Declare as void *, not char *, on hpux. - Don't prototype it, just declare the return type. - -Sun Feb 6 03:25:41 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/i386/tm-sun386.h, config/i386/tm-symmetry.h - (REGISTER_CONVERT_TO_RAW): Add missing backslash. - -Sat Feb 5 08:03:41 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-mips.c (mips_fetch_registers): If regno is FP_REGNUM or - ZERO_REGNUM, just read it as zero without talking to the board. - - * config/i386/tm-i386aix.h (REGISTER_CONVERT_TO_RAW): Add missing - backslash. - * i386-tdep.c (i386_extract_return_value): Pass TYPE_LENGTH (type) - to store_floating, not nonexistent variable len. - - * remote-mips.c (mips_insert_breakpoint, mips_remove_breakpoint): - New functions. - (mips_store_word): Change calling convention to return errors, and - to provide old contents if the caller wants it. - (mips_xfer_memory): Deal with errors from mips_store_word. - * config/mips/tm-idt.h, config/mips/tm-idtl.h: Remove BREAKPOINT - define now that remote-mips.c doesn't use BREAKPOINT. - - * remote-mips.c (mips_create_inferior): Call warning if arguments - specified, and then execute "set args" command. Call error, not - mips_error, if executable file not specified. - - * remote-e7000.c: Replace "snoop" command (e7000_noecho) with - remote_debug. - - * config/rs6000/tm-rs6000.h (STORE_STRUCT_RETURN): Don't cast - to unsigned int. - -Sat Feb 5 05:27:05 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * value.h (print_longest): Rename "value" to "val" in prototype - declaration because some compilers don't like arguments whose - names are the same as types. - * remote.c (remote_xfer_memory): Cast "myaddr" to unsigned char * - before passing it to remote_*_bytes. - -Fri Feb 4 15:53:18 1994 Steve Chamberlain (sac@cygnus.com) - - * h8500-tdep.c (saved_pc_after_call): The size of the - pc is memory model dependent. (segmented_command, - unsegmented_command, _initialize_h8500_tdep): New commands to - change memory model. - * remote-e7000.c (_initialize_remote_e7000): Change name of snoop - command. - * remote-hms.c (hms_load): Remove breakpoints when loaded. - (hms_wait): Use new status structure - (hms_open): Push the target here. (hms_before_main_loop): Not - here. (supply_val, hms_fetch_register, hms_store_register): Cope - with H8/500 names too. (hms_fetch_register): Take out REGISTER_TYPE. - * sh-tdep.c (show_regs, initialize_sh_tdep): New command to print - all registers in a compact way. - -Fri Feb 4 07:41:13 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * config/rs6000/tm-rs6000.h: Declare rs6000_struct_return_address - as CORE_ADDR to match definition in rs6000-tdep.c. - -Fri Feb 4 01:14:20 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dwarfread.c (process_dies): Skip nested TAG_compile_unit DIEs. - * dwarfread.c (add_partial_symbol): Do not enter opaque aggregate - definitions into the psymtab. - -Thu Feb 3 12:38:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m68k-stub.c: Treat mc68332 like mc68020 most places. Provide - a special exceptionSize for the 68332. - - * remote-udi.c (udi_attach): If no arguments, print error. - -Thu Feb 3 17:34:05 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (VERSION): Bump to 4.12.1 - * NEWS, README: Update to match 4.12 release. - -Thu Feb 3 12:38:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * command.c (empty_sfunc): New function. - (add_set_cmd): Use it instead of not_just_help_class_command. - (not_just_help_class_command): Change calling convention back to - what it was before yesterday's change. - - * stabsread.c (read_sun_builtin_type): Skip the semicolon at the end - of the type if present. - -Wed Feb 2 11:16:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (decode_format): Don't blithely set the size for - an address to 'w'. Make it 'g' or 'h', depending on TARGET_PTR_BIT. - - * defs.h: Just typedef CORE_ADDR to bfd_vma. Include bfd.h. - If BFD64, make a LONGEST a BFD_HOST_64_BIT. - * defs.h (longest_to_int): Don't depend on CC_HAS_LONG_LONG; instead - always just check against INT_MIN and INT_MAX (this also fixes things - if sizeof (long) > sizeof (int), e.g. Alpha). - * config/pa/tm-hppa.h, config/i386/sun386.h, config/rs6000/tm-rs6000.h: - Don't define LONGEST or BUILTIN_TYPE_LONGEST. - * gdbtypes.h: Remove BUILTIN_TYPE_LONGEST and - BUILTIN_TYPE_UNSIGNED_LONGEST. - * language.h, c-lang.c, ch-lang.c, m2-lang.c, language.c: Remove - longest_int and longest_unsigned_int. - * value.h (struct value): Just align to LONGEST, rather than worrying - about CC_HAS_LONG_LONG. - * valarith.c (value_binop): Figure out type ourself based on - sizeof (LONGEST) rather than relying on BUILTIN_TYPE_LONGEST. The - point is that we don't depend on CC_HAS_LONG_LONG anymore. - * valprint.c (val_print_type_code_int): Just call - extract_unsigned_integer directly, rather than going through - unpack_long. - * printcmd.c (decode_format): Remove code which would sometimes - change 'g' size to 'w' for integers. print_scalar_formatted handles - printing huge integers well enough, thank you. - - * command.c (add_set_cmd, not_just_help_class_command): Change - to make this the sfunc, not cfunc, since that is how we call it. - * command.h: Comment difference between sfunc and cfunc. - * demangle.c (set_demangling_command): Add third arg since that - is how it is called. - (_initialize_demangler): Use sfunc, not cfunc, for - set_demangling_command, since that is how it is called. - Remove show_demangling_command; it has no effect. - - * command.c (shell_escape): Report errors correctly (with error - message from strerror). - -Wed Feb 2 14:35:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * xcoffread.c (read_xcoff_symtab): Change CSECT_LEN to use - x_scnlen.l rather than x_scnlen to match corresponding change in - coff/internal.h. - -Wed Feb 2 11:16:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbtypes.h, ch-typeprint.c, ch-valprint.c: - Change comments regarding TYPE_CODE_BOOL. - * language.c (boolean_type): Always return 1 for TYPE_CODE_BOOL, - regardless of the language. - (value_true): Just call value_logical_not regardless of language. - * coffread.c (coff_read_enum_type), stabsread.c (read_enum_type): - Remove #if 0'd code which makes some enums TYPE_CODE_BOOL. - * language.h: Improve comment for la_builtin_type_vector. - * m2-lang.c (_initialize_m2_language): Don't add any fields to - builtin_type_m2_bool. - -Tue Feb 1 17:13:32 1994 Kevin Buettner (kev@cujo.geg.mot.com) - - * config/m88k/{tm-delta88.h,tm-delta88v4.h}, m88k-tdep.c: - Define IN_SIGTRAMP and backtrace correctly through signal handlers. - -Tue Feb 1 22:13:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * procfs.c (wait_fd): Handle EINTR error return from PIOCWSTOP ioctl - by restarting the ioctl. - -Tue Feb 1 16:16:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * target.h (target_wait): Add comment about calling - return_to_top_level. - -Tue Feb 1 12:21:00 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * coffread.c (read_one_sym): bfd_coff_swap_aux_in now takes - additional arguments. - * xcoffread.c (read_xcoff_symtab, read_symbol_lineno): Likewise. - -Mon Jan 31 16:10:41 1994 Stu Grossman (grossman at cygnus.com) - - * sparc-stub.c: Remove unnecessary #include of memory.h. - -Mon Jan 31 12:12:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mips-tdep.c: Remove code which sets saved_regs from - init_extra_frame_info and put it in new function mips_find_saved_regs. - (READ_FRAME_REG): Remove macro and replace uses with the expansion. - * mips-tdep.c, config/mips/tm-mips.h: When examining ->saved_regs, - check if it is NULL and call mips_find_saved_regs if so. - - * remote-mips.c: Use unfiltered, not filtered, output most places. - - * blockframe.c (get_prev_frame_info): Detect and stop an infinite - backtrace. Revise comments. - -Mon Jan 31 09:40:33 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_procedure): Remove _sigtramp kludges for - alpha and irix. The _sigtramp case has to be handled properly - in the tdep files if we have no ecoff debugging info. - * alpha-tdep.c (alpha_frame_saved_pc, alpha_frame_chain), - mips-tdep.c (mips_frame_saved_pc): Handle signal handler frames - without PC_REGNUM kludge. - * mdebugread.c (fixup_sigtramp), mips-tdep.c (read_next_frame_reg): - Clean up handling of mips sigtramp frames, improve comments. - -Sat Jan 29 23:25:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * paread.c (read_unwind_info): Fix typo. - - * paread.c (pa_symtab_read): Update the "check_strange_names" - filter to match GCC's current output. Filter out section symbols - (which the HP linker sometimes puts in the wrong place). - -Sat Jan 29 07:44:59 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * serial.h (SERIAL_SET_TTY_STATE): Comment return value. - - * Makefile.in (TAGS): Just echo one line, rather than the whole thing. - - * Makefile.in: Remove all references to sparcly-nat.c. - - * Makefile.in (HFILES_NO_SRCDIR): Include dcache.h remote-utils.h - remote-sim.h directly, rather than via $(remote_utils_h). This avoids - duplicating serial.h and target.h. - - * Makefile.in: Don't set M_INSTALL and M_UNINSTALL. These variables - are not used anywhere (a 5 Oct 1993 change removed the uses). - - * config/m68k/monitor.mt (TDEPFILE): Add remote-es.o. - * config/m68k/es1800.mt: Add comment. - * remote-es.c: Extensive changes to update to current conventions. - - * ser-unix.c (wait_for, hardwire_readchar) [HAVE_TERMIO, HAVE_TERMIOS]: - If the timeout is too big to fit in c_cc[VTIME], then do multiple reads - to achieve the desired timeout. - * serial.h (serial_t): Add field timeout_remaining. - -Fri Jan 28 08:45:02 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * c-exp.y (yylex): Reenable nested type code. - -Fri Jan 28 15:40:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * a29k-tdep.c (examine_tag): Add comment regarding argcount. - - * remote-mips.c (mips_ops): Fix docstring. - - * remote-bug.c (bug_ops): Remove spurious newline from docstring. - - * config/m68k/tm-monitor.h: Changes to bring this into accordance - with the old tm-m68k-em.h: - (GDBINIT_FILENAME, DEFAULT_PROMPT): Remove. - (HAVE_68881): Don't undefine; HAVE_68881 is obsolete. - (REGISTER_NAMES): Don't muck with it; what tm-m68k.h has is fine. - Add FIXME regarding GET_LONGJMP_TARGET. - - * remote-udi.c (udi_close, udi_detach, udi_kill): Add comments. - * infptrace.c (kill_inferior): Add comments. - * main.c (quit_command): Call target_close after we kill or - detach. - * remote-udi.c (udi_close): Don't error() if QUITTING. - -Fri Jan 28 11:55:52 1994 Rob Savoye (rob@darkstar.cygnus.com) - - * configure.in: Make m68k-coff and aout add monitor support in - addition to the standard serial support. - -Fri Jan 28 08:45:02 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * mdebugread.c (psymtab_to_symtab_1): Don't complain on stLabel with - index indexNil. - -Fri Jan 28 10:40:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/pa/tm-hppa.h: Define macro SMASH_TEXT_ADDRESS. - * elfread.c (record_minimal_symbol_and_info), - dwarfread.c (process_dies), paread.c (pa_symtab_read): Use it. - -Thu Jan 27 15:12:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * i386-stub.c: Add ".text" right before "mem_fault:". - - * main.c (baud_rate): Add FIXME comment about printing -1 value. - - * remote-utils.c (usage): Fix message to be accurate and conform - more closely to normal conventions. - - * remote-utils.c (gr_files_info): Have the exec_bfd test control - whether to show information about exec_bfd, and not control whether - to show information about device and speed. - - * remote-utils.c (gr_open): If sr_get_device returns NULL, give - usage message, don't dump core. - - * remote-bug.c (bug_write_memory): Use alloca, not GCC extension - for variable size array. - (bug_fetch_register, bug_store_register): Rename "value" to - "fpreg_buf" because some compilers don't like variables whose - names are the same as types. - (bug_store_register): Use a cast when converting char * to - unsigned char *. - - * symmisc.c (maintenance_print_symbols): Don't refer to the name - of the command in error message (the text was referring to the old - name of the command). - - * symmisc.c (dump_symtab): Fix args to fprintf_filtered. - - * c-typeprint.c (c_type_print_base): Have SHOW == 0 mean to print - full details on structure elements without names. This partially - reverts the changes of 1 Jul 1993 and 31 Aug 1993; I think this aspect - of those changes was accidental. - - * stack.c (parse_frame_specification): If SETUP_ARBITRARY_FRAME is - defined, make it an error to specify a single argument which is not - a frame number. - - * Makefile.in (version.c), main.c (print_gdb_version): Use - host_alias and target_alias, not host_canonical and - target_canonical, to print configuration. - -Wed Jan 26 10:57:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * parse.c (write_exp_msymbol): Use new type msymbol_addr_type instead - of builtin_type_long. It is necessary to get a type which is - TARGET_PTR_BIT bits in size; builtin_type_long might not be big enough. - - Fix many sins which will come up in 32 bit x 64 bit GDB, and - various miscellaneous things discovered in the process: - * printcmd.c, defs.h (print_address_numeric): New function. - * c-valprint.c (c_val_print), ch-valprint.c (chill_val_print) - breakpoint.c (describe_other_breakpoints, breakpoint_1, mention), - cp-valprint.c (cplus_print_value), infcmd.c (jump_command), - printcmd.c, stack.c, symfile.c, symmisc.c, valprint.c: - Use it. - * utils.c, defs.h (gdb_print_address): New function. - * expprint (dump_expression), gdbtypes.h: Use it. - * breakpoint.c (describe_other_breakpoints), - symmisc.c (dump_symtab, print_symbol): - Use filtered not unfiltered I/O. - (remove_breakpoints): Remove BREAKPOINT_DEBUG code. Might as well - just run gdb under a debugger for this (and it had problems with - printing addresses, how to print b->shadow, etc.). - * buildsym.c (make_blockvector), core.c (memory_error), - exec.c (print_section_info), maint.c (print_section_table), - mdebugread.c (parse_procedure), solib.c, source.c, symfile.c, - symmisc.c, symtab.c, valops.c, valprint.c, xcoffexec.c: - Add comments saying code is broken. Marked with "FIXME-32x64". - * dbxread.c (process_one_symbol), partial-stab.h (default), - remote-vx.c (vx_run_files_info): - Don't cast int being passed to local_hex_string. - * symmisc.c (print_symbol): Don't cast long being passed to %lx. - * symtab.h (general_symbol_info): Add comment about SYMBOL_VALUE - only being a long. - * symmisc.c (print_symbol): Print "offset" in message for LOC_ARG - and LOC_LOCAL. - * printcmd.c (print_address): Remove #if 0 code with ADDR_BITS_REMOVE. - * source.c: Include regardless of USG. - -Tue Jan 25 12:58:26 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * valops.c (value_assign): Set `type' after coercing toval. - * c-valprint.c (c_val_print), ch-valprint.c (chill_val_print): - Use extract_unsigned_integer to get the address of a reference. - -Tue Jan 25 11:31:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (STABS_CONTINUE, error_type), partial-stab.h: - AIX can use ? instead of \ for continuation. Deal with it. - - * paread.c (read_unwind_info): Just assign to objfile->obj_private, - not OBJ_UNWIND_INFO. Assigning to a cast is a GCC-ism which - the HP compiler in ANSI mode doesn't like. - - * main.c: When defaulting HAVE_SIGSETMASK based on USG, just do it - based on USG, rather than defining HAVE_SIGSETMASK to an - expression containing defined. Having a macro used in #if expand - to an expression containing "defined" is undefined according to - ANSI, and the HP compiler in ANSI mode doesn't do what we wanted - it to. - -Mon Jan 24 20:51:29 1994 John Gilmore (gnu@cygnus.com) - - * sparc-nat.c (fetch_inferior_registers, store_inferior_registers): - Clean up the changes of 11 Jan, as recommended by Peter Schauer. - -Fri Jan 21 19:10:44 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * ch-exp.y (match_string_literal): Allow a zero-length string. - * ch-lang.c (chill_printstr): Don't print zero-length string funny. - -Sat Jan 22 17:08:48 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * i386aix-nat.c (i386_float_info): Reverse order of registers before - passing them to print_387_status. - (print_387_status): Don't subtract top from 7 before using it. - * i387-tdep.c: Remove comment about AIX wanting "top" subtracted - from 7; the above explains it. - -Sat Jan 22 20:25:11 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-tdep.c (init_extra_frame_info): Use frame relative stack - pointer value when fixing up the frame at the start of a function. - -Sat Jan 22 12:29:13 1994 Stu Grossman (grossman at cygnus.com) - - * lynx-nat.c (fetch_core_registers): Load the I & L regs for the - Sparc from the stack. - -Sat Jan 22 08:30:42 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * remote-mips.c (mips_initialize): Clear mips_initializing via - cleanup chain, not directly. - - * ser-unix.c (wait_for) [HAVE_TERMIO, HAVE_TERMIOS]: Make a timeout - of -1 mean forever, like in the HAVE_SGTTY case. Warn if we are - munging the timeout due to the limited range of c_cc[VTIME]. - - * fork-child.c, inferior.h (fork_inferior): New argument shell_file. - * procfs.c (procfs_create_inferior), inftarg.c (child_create_inferior), - m3-nat.c (m3_create_inferior): Pass it. - * procfs.c: Remove ptrace function. It was declared in a way which - conflicted with the prototype in unistd.h on Solaris. - -Sat Jan 22 01:37:40 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * sparc-tdep.c (frame_saved_pc): Get the pc from the saved pc - in the sigcontext if it is a signal trampoline frame. - * config/sparc/tm-sun4sol2.h (IN_SIGTRAMP, SIGCONTEXT_PC_OFFSET): - Define for Solaris2. - -Sat Jan 22 00:34:47 1994 Stu Grossman (grossman at cygnus.com) - - * sparc-tdep.c, lynx-nat.c, config/sparc/tm-sparc.h, - config/sparc/tm-sparclynx.h: Move defs of FRAME_SAVED_I0/L0 to - tm-sparc.h so they can be overridden if necessary. - -Fri Jan 21 17:49:28 1994 Stu Grossman (grossman at cygnus.com) - - * lynx-nat.c: Add Sparc support. - * sparcly-nat.c: Remove. It's useless. - * config/sparc/nm-sparclynx.h: Rewrite. - * config/sparc/sparclynx.mh (NATDEPFILES): Replace sparcly-nat.o - with lynx-nat.o - * config/sparc/tm-sparclynx.h: Rewrite. - -Fri Jan 21 19:08:48 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * rs6000-pinsn.c: Use the new disassembler in the opcodes - directory. Old code was discarded, since the new opcode table has - a different format. - -Fri Jan 21 14:28:30 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (realclean): Remove info files per make-stds.texi. - -Fri Jan 21 12:47:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c (end_psymtab): Only patch psymtab textlow and texthigh - if N_SO_ADDRESS_MAYBE_MISSING is defined. - * config/sparc/tm-sun4sol2.h: Define it. - -Thu Jan 20 15:04:24 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * printcmd.c (print_address_symbolic): Unconditionally use msymbol - if we did not find a symbol. - -Fri Jan 21 08:20:18 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * infptrace.c (child_xfer_memory): Only use if CHILD_XFER_MEMORY - is not defined. - - * hppab-nat.c (call_ptrace): Delete redundant function. - (kill_inferior, attach, detach, child_resume): Likewise. - (child_xfer_memory): Likewise. - - * hppah-nat.c (call_ptrace): Delete redundant function. - (kill_inferior, attach, detach, child_resume): Likewise. - - * config/pa/hppabsd.mh (NATDEPFILES): Add infptrace.o. - - * config/pa/hppahpux.mh (NATDEPFILES): Add infptrace.o. - - * config/pa/nm-hppab.h (FETCH_INFERIOR_REGISTERS): Define. - - * config/pa/nm-hppah.h (FETCH_INFERIOR_REGISTERS): define. - (CHILD_XFER_MEMORY): Define. - (PT_*): Define so that generic infptrace.c code can be used. - -Fri Jan 21 09:23:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (xcoff_symfile_read): Make second parameter a - struct section_offsets *, not a (nonexistent) struct section_offset *. - - * xcoffread.c (read_xcoff_symtab): Make main_aux just a union - internal_xcoff_symtab, not an array of one of them. Change lots of - "main_aux" to "&main_aux" and so on. - - * coffread.c, xcoffread.c: Include - before "symfile.h". - -Thu Jan 20 17:30:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * coffread.c (coff_getfilename): Make it not static. - - * xcoffread.c (read_xcoff_symtab): complain() not abort(). - - * xcoffread.c (struct coff_symbol): Rename c_nsyms to c_naux (removes - a completely gratuitous difference between xcoffread.c and coffread.c). - -Wed Jan 19 15:09:44 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (wait_for_inferior): Don't set frame for - step_resume_breakpoint for IN_SIGTRAMP cases. - - * infrun.c (wait_for_inferior), breakpoint.h (struct bpstat_what), - breakpoint.c (bpstat_what): Move step_resume from its own field of - the struct bpstat_what into the main_action. Make it override - other breakpoints. This is a conservative change in the sense - that before the step resume breakpoint was a breakpoint.c - breakpoint, hitting the step resume breakpoint overrode even - calling bpstat_stop_status. - -Wed Jan 19 12:40:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (normal_stop): Set stop_pc after popping the dummy frame - in case execution was stopped in the called function. - * stack.c (print_frame_info, frame_info): If backtracing through - a call dummy, handle the starting source line number on a line - boundary like backtracing through sigtramp. - * sparc-tdep.c (sparc_frame_find_saved_regs): Get frame address - for call dummy frame right. Remove old test for dummy frame, - it has been unused at least since gdb-3.5. - * sparc-tdep.c (sparc_push_dummy_frame): Set return address register - of the dummy frame. - -Tue Jan 18 16:16:35 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infcmd.c (signal_command): Accept 0 as legitimate signal number. - -Tue Jan 18 14:09:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (signals_info), target.c (target_signal_from_name): - Use ugly casts to avoid enumvar < enumvar or enumvar++. - -Mon Jan 17 22:00:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * ser-unix.c (hardwire_noflush_set_tty_state): Don't muck with ICANON. - * inflow.c (terminal_ours_1): When discussing how to deal with the - tty state, make note of query() as well as readline. - - * infrun.c (_initialize_infrun): Add TARGET_SIGNAL_POLL to list of - signals for which stop and print are cleared by default. - -Mon Jan 17 20:00:51 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * config/pa/tm-hppa.h (unwind_table_entry): Use one of the - reserved fields to hold a stub unwind entry type. Fix typo. - (stub_unwind_entry): New structure for raw stub unwind entries. - (stub_unwind_types): The types of stubs we may encounter. - (UNWIND_ENTRY_SIZE, STUB_UNWIND_ENTRY_SIZE): New defines. - * hppa-tdep.c (rp_saved): Use additional information provided - by linker stub unwind descriptors. - (frameless_function_invocation): Likewise. - (frame_chain_valid): Likewise. - * paread.c (compare_unwind_entries): New function for sorting - unwind table entries. - (read_unwind_info): Rewrite to remove dependency on host endianness. - Read in data from the $UNWIND_END$ subspace which contains linker - stub unwind descriptors. Merge that data into the basic unwind - table. - - * hppab-nat.c (_initialize_kernel_u_addr): Delete unwanted functions. - -Mon Jan 17 22:00:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (read_xcoff_symtab, case C_FILE): Accept the name - from either the symbol name or the auxent. - * coffread.c, symfile.h (coff_getfilename): Renamed from getfilename, - no longer static. - -Mon Jan 17 13:35:01 1994 Fred Fish (fnf@cygnus.com) - - * Makefile.in (ALLPARAM): Change irix5.h to nm-irix5.h. - -Mon Jan 17 12:35:42 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * README: Update notes for alpha port. - -Mon Jan 17 11:15:57 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * i960-tdep.c (i960_fault_to_signal): Return TARGET_SIGNAL_ILL - for operation fault, constraint fault, and type fault. - -Sun Jan 16 12:46:01 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (init.c): Add comment explaining formatting conventions. - - * c-exp.y (parse_number): Assign to temporary between the right - shifts, to work around a bug in the SCO compiler. - - * Makefile.in (ALLCONFIG, ALLPARAM, ALLDEPFILES, HFILES_NO_SRCDIR): - Add various files which were added to GDB recently. - - * xcoffread.c (process_xcoff_symbol): Only change 'V' to 'S' if not - within_function. - - * Makefile.in: Add mostlyclean target. - -Sat Jan 15 10:20:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Version 4.11.4. - -Sat Jan 15 18:27:34 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * main.c (show_commands): Make return type of extern - history_get be HIST_ENTRY, rather than struct _hist_entry. - (The latter loses with the upcoming merged readline.) - -Sat Jan 15 10:20:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * minsyms.c (prim_record_minimal_symbol_and_info): Make tempstring - const char *, not char *. - - * symtab.h (struct symbol): Make section short, not unsigned short. - - * symtab.c (lookup_symbol): Add comment about QUIT here. - - * utils.c (fputs_unfiltered): Call fputs, not fputs_maybe_filtered. - - * c-exp.y (parse_number): Check for overflow regardless of range - checking. Fix overflow check to use unsigned LONGEST, not - unsigned int. - - * c-exp.y (parse_number): Make it so that integer constants are - builtin_type_long_long if builtin_type_long isn't big enough or if - an "LL" suffix is used. Properly handle "UL" or "LU" suffixes. - - * c-typeprint.c (c_type_print_varspec_suffix, case TYPE_CODE_FUNC): - Print our "()" first, then recurse for the target type. - -Fri Jan 14 21:55:39 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-udi.c (udi_create_inferior): Quote empty execfile argument. - - * gdbserver/low-lynx.c: Include not "/usr/include/wait.h". - -Fri Jan 14 14:17:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c (request_quit): Re-establish signal handler regardless - of USG. - - * config/mips/xm-irix4.h: Define HAVE_TERMIOS. - -Fri Jan 14 21:55:39 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * i960-tdep.c: Include target.h. - -Fri Jan 14 17:12:28 1994 Stan Shebs (shebs@andros.cygnus.com) - - * lynx-nat.c (sys/wait.h): Don't use absolute pathname. - -Fri Jan 14 11:06:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * lynx-nat.c (child_wait): Fix thinkos in struct target_waitstatus - changes (status -> ourstatus; declare status, etc.). - * config/nm-lynx.h: Fix child_wait prototype and include target.h. - -Fri Jan 14 14:17:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (ALLPARAM): Add config/nm-lynx.h. - -Fri Jan 14 11:49:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * remote-mips.c (mips_request, mips_wait): Correct prototypes. - -Fri Jan 14 11:37:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/i386/xm-linux.h: Define HAVE_TERMIOS. - -Fri Jan 14 01:04:36 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/alpha/tm-alpha.h (CALL_DUMMY): Improve comment. - -Thu Jan 13 10:32:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote-vx.c (vx_wait): Only call i960_fault_to_signal if I80960 - is defined. Otherwise just report TARGET_SIGNAL_UNKNOWN. - - * mips-tdep.c (mips_push_arguments): Byteswap struct_addr before - writing it. - - Add search to target vector (#if 0'd until after 4.12): - * target.h (to_search, target_search): Add. - * gdbcore.h, core.c (generic_search): Add. - * remote.c (remote_search): Add. - * a29k-tdep.c (init_frame_info): Use target_search to find traceback - tag. - - * printcmd.c (print_address_symbolic): If set print fast-symbolic-addr - is on, call find_pc_function rather than relying just on the minimal - symbols (probably only matters for symbol readers which don't put - statics in the minimal symbols, but changing this strikes me as - not conservative enough). - Initialize name_location in all cases. - If no symbol and no msymbol, don't print anything symbolic. - - * a29k-tdep.c (push_dummy_frame): Add comment about saving lr0. - -Wed Jan 12 20:53:16 1994 John Gilmore (gnu@cygnus.com) - - * printcmd.c (print_address_symbolic): Make it search the - symtabs for variables as well as functions. Add `set print - fast-symbolic-addr' and default it to fast (the old way). - Print line numbers for data items as well as functions. - - * symtab.c (find_addr_symbol): Return the symtab and the symbol - address, if a symbol is found (take two more args pointing to - where to store these results). - - * symtab.h (find_addr_symbol): Add prototype. - -Wed Jan 12 19:32:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * objfiles.h: Fix comments to reflect the fact that the phrase - "top of stack" always refers to where the pushing and popping takes - place, regardless of whether it is at the highest or lowest address. - -Wed Jan 12 13:23:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_symbol): Do not set TYPE_TAG_NAME for - compiler generated tag names. - * mdebugread.c (parse_type): Handle cross references to qualified - aggregate types. - * valops.c (value_struct_elt): Improve error message if the - address of a method is requested from an object instance. - * valops.c (search_struct_method): Make name_matched non-static - to get it initialized correctly. - * config/i386/nm-i386sco.h (CANNOT_STORE_REGISTER): Define to - exclude segment register which are not writable on newer SCO versions. - -Wed Jan 12 14:44:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * go32-xdep.c: Remove unused function uerror. - (sigsetmask): Declare return type. Declare argument (to match the - way it is called). Explicitly return 0. - -Wed Jan 12 01:44:25 1994 John Gilmore (gnu@cygnus.com) - - * symtab.h (struct symbol, general_symbol_info, minimal_symbol, - partial_symbol): Shrink the storage sizes of symbols, by making - enums into 1-byte bitfields when compiled __GNUC__, moving all the - enums and small ints to the end of each struct to improve - alignment, and switching the section number from int to unsigned - short. - -Wed Jan 12 00:16:26 1994 John Gilmore (gnu@cygnus.com) - - * symtab.c (find_addr_symbol): New routine that will find the nearest - symbol associated with an address. It does so by exhaustive - search of the symtabs, so it's slow but complete. - -Tue Jan 11 23:57:30 1994 John Gilmore (gnu@cygnus.com) - - * coffread.c (read_coff_symtab): Set PC bounds of _globals_ symtab - to [0,0] rather than [0, end of first source file]. This avoids - problems with other parts of GDB looking for linetables in the - _globals_ symtab. Eliminate variables num_object_files and - first_object_file_end. - -Tue Jan 11 00:53:46 1994 John Gilmore (gnu@cygnus.com) - - * a29k-tdep.c (init_frame_info): Cast null arg to examine_tag. - (pop_frame): Restore PC2 and LR0 from dummy frames. - (push_dummy_frame): Save PC2 and LR0 into dummy frames. - (setup_arbitrary_frame): Handle 3 args and set up real frames. - * config/a29k/tm-a29k.h (FRAME_NUM_ARGS): Update comments. - (DUMMY_FRAME_RSIZE): Add 2 longwords for PC2 and LR0. - (SETUP_ARBITRARY_FRAME): Define. - -Tue Jan 11 06:59:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * infrun.c, config/mips/tm-irix5.h: Remove #if 0'd AT_FUNCTION_START. - -Tue Jan 11 14:27:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * remote-udi.c (udi_resume): Correct prototype. - -Tue Jan 11 11:10:30 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * config/pa/tm-hppa.h (FRAME_FIND_SAVED_REGS): Call - hppa_frame_find_saved_regs. - * hppa-tdep.c (dig_fp_from_stack): Delete function. - (prologue_inst_adjust_sp): New function. - (is_branch, inst_saves_gr, inst_saves_fr): New functions. - (skip_prologue): Completely rewrite to use unwind information. - (hppa_frame_find_saved_regs): Likewise. - -Tue Jan 11 06:59:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * remote-mips.c (mips_wait): Use new function mips_signal_from_protocol - to convert a signal number with appropriate bounds checking. - - * remote-mips.c (mips_wait): Fix typos (0x177 -> 0177, 0x377 -> 0377). - -Tue Jan 11 00:53:46 1994 John Gilmore (gnu@cygnus.com) - - * stack.c (frame_info): If FRAME_FIND_SAVED_REGS isn't defined, - print a newline to end the display anyway. - - * sparc-tdep.c (sparc_pop_frame): Pop the fsr and csr (float and - coprocessor status regs) when popping a frame. This fixes - float exceptions that occur after calling inferior functions. - - * sparc-nat.c (fetch_inferior_registers, store_inferior_registers): - Read and write the fsr (float status register) to/from the child - process along with the float regs. Remove Peter Schauer's change - of May 24 '93, which has higher overhead and doesn't solve the - real problem (which was that FSR wasn't being set). - -Mon Jan 10 23:16:42 1994 John Gilmore (gnu@cygnus.com) - - * a29k-tdep.c (examine_prologue): Don't worry if the ASGEQ - stack overflow check isn't right after the register stack - adjustment instruction. Metaware R2.3u compiler moves other - things in front of it. This fix isn't perfect but is what's - running. - -Mon Jan 10 20:08:23 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * c-valprint.c (c_val_print): Treat TYPE_CODE_RANGE like TYPE_CODE_INT. - - * config/alpha/alpha-netware.mt: Rename to alpha-nw.mt for 14 - character filenames. - * configure.in: Change accordingly. - -Mon Jan 10 15:48:36 1994 Tom Lord (lord@rtl.cygnus.com) - - * m68k-stub.c, sparc-stub.c: removed spurious introduction of - _filtered io routines from these two files. - -Fri Jan 7 12:42:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/i386/tm-i386v.h, config/m68k/tm-m68k.h, config/mips/tm-mips.h, - config/vax/tm-vax.h (CALL_DUMMY_BREAKPOINT_OFFSET): Define. - * mdebugread.c (parse_symbol): Handle enum sh.type produced by - DEC c89. - * mdebugread.c (add_line): Handle zero linenos produced by DEC c89. - -Fri Jan 7 12:55:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c (print_sys_errmsg): Call gdb_flush (gdb_stdout) before - printing to gdb_stderr. - - * remote-udi.c (udi_kill): Don't close the connection, just set - inferior_pid to zero. - (udi_mourn): Call remove_breakpoints. - - * remote-udi.c: Remove obsolete need_artificial_traps comment. - - * i386b-nat.c (sregmap): If sEAX, etc., not defined, use tEAX, etc. - -Thu Jan 6 07:17:53 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * symtab.c (lookup_symbol): Don't try adding .c to the name. - - * remote-bug.c: At the start of each section, reset srec_frame - back to 160. - - * target.h: Add TARGET_WAITKIND_LOADED and TARGET_WAITKIND_SPURIOUS. - * target.c (store_waitstatus): Add CHILD_SPECIAL_WAITSTATUS hook. - * infrun.c (wait_for_inferior): Replace SIGTRAP_STOP_AFTER_LOAD with - code which looks for those two waitkinds. Use switch statement. - * config/rs6000/tm-rs6000.h: Replace SIGTRAP_STOP_AFTER_LOAD with - CHILD_SPECIAL_WAITSTATUS. - - * procfs.c (procfs_wait): Fix argument name to match 4 Jan changes. - * Move target_signal_from_host, target_signal_to_host, and - store_waitstatus from inftarg.c to target.c. procfs needs them. - * target.c: Include "wait.h" and . - * target.h, infrun.c (proceed), proceed callers: Pass new code - TARGET_SIGNAL_DEFAULT instead of -1. This avoids problems with - enums being treated as unsigned and is cleaner. - * infrun.c (signals_info): Don't print TARGET_SIGNAL_DEFAULT or - TARGET_SIGNAL_0. - * infcmd.c (signal_command), infrun.c (signals_info): - Don't allow user to specify numeric equivalent of - TARGET_SIGNAL_DEFAULT. - -Tue Jan 4 15:34:36 1994 Stu Grossman (grossman@cygnus.com) - - * config/alpha/alpha-netware.mt: New target support for Alpha - running Netware. - * configure.in: Add alpha-*-netware* target. - -Tue Jan 4 14:51:35 1994 Stan Shebs (shebs@andros.cygnus.com) - - * remote-mips.c (mips_wait): Fix ref to TARGET_WAITKIND_STOPPED. - -Tue Jan 4 09:47:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * target.h: Add enum target_waitkind, enum target_signal, and - struct target_waitstatus. Change status argument to target_wait to - be struct target_waitstatus * instead of int *. - * target.h, infrun.c, all targets: Change type of signal arguments - to resume(), proceed(), and target_resume() from int to enum - target_signal. - * All targets (*_wait, *_resume): Change accordingly. - * infcmd.c (program_info, signal_command), throughout infrun.c, - * fork-child.c, solib.c, hppa-tdep.c, osfsolib.c: Use this stuff. - * convex-xdep.c, convex-tdep.c: Add FIXME's (getting the Convex - signal code stuff right with the new signals would be non-trivial). - * inferior.h (stop_signal): Make it enum target_signal not int. - * target.c, target.h (target_signal_to_string, target_signal_to_name, - target_signal_from_name): New functions. - * inftarg.c, target.h (target_signal_to_host, target_signal_from_host, - store_waitstatus): New functions. - * procfs.c (procfs_notice_signals): Use them. - * i960-tdep.c (i960_fault_to_signal): New function, to replace - print_fault. - * config/i960/tm-i960.h: Don't define PRINT_RANDOM_SIGNAL. - - * objfiles.c (build_objfile_section_table): Don't abort() if - objfile->sections is already set. - - * objfiles.c (add_to_objfile_sections): Check SEC_ALLOC not SEC_LOAD - to match recent change to exec.c. - - * Version 4.11.3. - - * main.c (print_gdb_version): Change year to 1994. - - * ChangeLog, ChangeLog-93: Split ChangeLog at 1994. - * Makefile.in (NONSRC): Add ChangeLog-93. - -Mon Jan 3 11:57:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stabsread.c (read_type): Allow defining several type numbers - at once (e.g. "(1,2)=(3,4)="...). - - * stabsread.c (read_enum_type): Use TARGET_INT_BIT not sizeof (int). - - * breakpoint.c (frame_in_dummy): Check PC as well as frame. - -Mon Jan 3 02:47:03 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (psymtab_to_symtab_1): Only pass N_STAB symbols - to process_one_symbol. - * symtab.c (find_pc_psymbol): Search global_psymbols as well to - avoid caching a bad endaddr in find_pc_partial_function. - -Sun Jan 2 21:41:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m68k/tm-sun3.h: Don't define BELIEVE_PCC_PROMOTION. - -Sat Jan 1 04:35:23 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): Do not step or step resume past - the end of a one-line function we just stepped into. - -For older changes see ChangeLog-93 - -Local Variables: -mode: indented-text -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/contrib/gdb/gdb/ChangeLog-95 b/contrib/gdb/gdb/ChangeLog-95 deleted file mode 100644 index 2265be880ad..00000000000 --- a/contrib/gdb/gdb/ChangeLog-95 +++ /dev/null @@ -1,4915 +0,0 @@ -Fri Dec 29 16:30:58 1995 Stan Shebs - - * symfile.c (find_sym_fns): Add PowerMac to xcoff file recognition - kludge. - -Fri Dec 22 11:05:59 1995 Michael Meissner - - * configure.in (gdb_host): Add support for DG/UX running on x86 as - a host. - (all x86 targets and hosts): Add support for pentium-pro machines. - - * configure: Rebuild. - - * config/i386/i386dgux.mh: New file for DG/UX running on x86 host. - -Thu Dec 21 19:09:20 1995 Rob Savoye - - * remote-array.c (array_wait): Poll the keyboard along with the - serial port so users can tpye at the target while their - application is running. - -Thu Dec 21 11:58:52 1995 Michael Meissner - - * Makefile.in (ppcbug-rom.o, srec.o): Add dependencies. - - * monitor.c (monitor_debug): Take prefix, and suffix arguments. - Print trailing newline after the suffix. - (monitor_printf{,_noecho}): Change monitor_debug calls. - (monitor_printf): Call monitor_expect instead of trying to do the - expect processing locally so that if there is extra junk, it - doesn't hang things up. - (readchar): If MO_HANDLE_NL is set, handle \r\n pairs and convert - them to a single \r. Use monitor_debug to print out byte read. - - * monitor.h (MO_HANDLE_NL): Add new flag. - - * ppcbug-rom.c (ppcbug_ops{1,2}): Split into two ops, one that - uses lo 0 to load, and the other that uses lo 1. Set flag - MO_HANDLE_NL. - (ppcbug_open{0,1}): Clone and split to handle ppcbug_ops{1,2}. - (_initialize_ppcbug_rom): Set up both ppcbug_open{0,1}. - -Wed Dec 20 10:54:41 1995 Fred Fish - - * defs.h: Delete extraneous whitespace at end of file. - * symfile.h: Move #include of demangle.h outside conditional. - * objfiles.h (struct objstats, OBJSTAT, OBJSTATS): New struct and - macros to hold per-objfile statistics for internal - instrumentation. - (struct objfile): Add OBJSTATS member, which is optional. - * buildsym.h (next_symbol_text_func): Now takes objfile argument. - Also update copyright to 1995. - * dbxread.c (dbx_next_symbol_text): Now takes objfile argument. - (dbx_symfile_init, coffstab_build_psymtabs, elfstab_build_psymtabs, - stabsect_build_psymtabs): Accumulate string table size. - (dbx_next_symbol_text, read_dbx_symtab, read_ofile_symtab): - Accumulate number of stabs symbols read. - * dwarfread.c (new_symbol, symthesize_typedef): - Accumulate number of full symbols created. - * gdbtypes.c (alloc_type): Accumulate number of types. - * maint.c (maintenance_print_statistics): New function. - * mdebugread.c (mdebug_next_symbol_text): Now takes objfile - argument. - * minsyms.c (prim_record_minimal_symbol_and_info): Accumulate - number of minimal symbols read. - * os9kread.c (read_os9k_psymtab): next_symbol_text takes objfile - arg. - * partial-stab.h: next_symbol_text takes objfile arg. - * stabsread.c (error_type, STABS_CONTINUE): Now takes objfile arg - and uses it to call next_symbol_text. - * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list): - Accumulate number of partial symbols created. - * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Accumulate number of partial - symbols created. - * symmisc.c (print_objfile_statistics): Print the per-objfile - internal instrumentation statistics gathered. - * xcoffread.c (xcoff_next_symbol_text): Now takes objfile argument. - -Fri Dec 15 16:15:55 1995 Ian Lance Taylor - - * top.c (set_endian_from_file): Use new bfd_big_endian macro. - -Fri Dec 15 12:21:10 1995 Raymond Jou - - * mpw-make.sed: Add quotes to RIncludes reference. - -Fri Dec 15 13:18:55 1995 Rob Savoye - - * remote-array.c: Remove bogus setting of baudrate to 4800. Their - hardware has real UARTS now. - -Mon Dec 11 18:19:16 1995 Stan Shebs - - * configure.in (powerpc-*-macos*): New target configuration. - * configure: Update. - * config/powerpc/macos.mh, config/powerpc/macos.mt, - config/powerpc/nm-macos.h, config/powerpc/tm-macos.h, mac-nat.c: - New files, native PowerMac debugging support. - * Makefile.in (mac-nat.o): Add build rule. - * mpw-config.in (enable_cflags): Add support. - (m68k-apple-macos, powerpc-apple-macos): Fix natdepfiles to - list object file instead of source file. - * mpw-make.sed (@ENABLE_CFLAGS@): Don't edit out, replace with - value of variable. - (install, install-only): Edit MPW-specific installation into - place of Unix shell code. - * mac-gdb.r: Fix version resources to use symbolic version strings. - (cfrg): New resource, code fragment for PowerMac. - -Mon Dec 11 14:13:03 1995 Fred Fish - - * dbxread.c (process_one_symbol): When looking at the next - minimal symbol, check for end of the minimal symbol array - (symbol with NULL pointer for name) before dereferencing it. - -Mon Dec 11 15:56:55 1995 Per Bothner - - * eval.c (evaluate_struct_tuple): Fix thinko. - -Mon Dec 11 06:52:02 1995 Wilfried Moser - - * ch-typeprint.c (chill_type_print_base): Slightly change of printing - of variant structures. - -Mon Dec 11 00:36:01 1995 Per Bothner - - * valops.c (value_cast): Handle casts to and from TYPE_CODE_CHAR. - * ch-exp.c (match_integer_literal): Fix long long support. - * gdbtypes.c (get_discrete_bounds): Make TYPE_LENGTH (type) == - sizeof (LONGEST) case work OK. - -Fri Dec 8 21:02:24 1995 Fred Fish - - * coffread.c, dbxread.c, dstread.c, objfiles.c, os9kread.c, - symfile.c, symtab.c: Use "obstack.h" rather than . - -Wed Dec 6 16:16:18 1995 Stu Grossman (grossman@cirdan.cygnus.com) - - * remote-mips.c (mips_receive_header): Allow mips_syn_garbage to be - user-settable (via set syn-garbage-limit). Setting it to -1 makes - it unlimited. - -Tue Dec 5 18:33:43 1995 Brendan Kehoe - - * gdbtypes.c (check_stub_method): Make sure we get back a function - string in the demangled name before we try to use it. - -Tue Dec 5 18:08:29 1995 Stu Grossman (grossman@cygnus.com) - - * monitor.c (monitor_expect_regexp): Make static, add prototype. - * (monitor_read_memory_single): Call monitor_expect_regexp with - pointer to getmem_resp_delim_pattern, not entire struct. - -Tue Dec 5 15:51:25 1995 Stan Shebs - - * c-lang.h (c_op_print_tab): Don't declare, some compilers - consider illegal if structure not defined, and only used - in c-lang.c anyway. - -Sun Dec 3 12:31:03 1995 Per Bothner - - * eval.c (evaluate_subexp_standard case): Fix typo. - -Sun Dec 3 11:59:21 1995 Jeffrey A. Law - - * ch-exp.c (parse_named_record_element): Avoid aggregrate - initializations for automatic variables. - - * hppa-tdep.c (hppa_alignof): Fix typo in last change. - -Sat Dec 2 19:32:57 1995 Fred Fish - - * symfile.c (global_psymbols, static_psymbols): Remove, unused. - -Sat Dec 2 03:02:21 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-tdep.c (heuristic_proc_desc): Add heuristic to - determine the return address register, needed for OSF/1-3.2C. - * config/alpha/tm-alpha.h (T7_REGNUM, T9_REGNUM): Define. - -Fri Dec 1 07:23:57 1995 Michael Meissner - - * ppcbug-rom.c (ppcbug_cmds): Turn on MO_GETMEM_READ_SINGLE - because PPCbug displays the memory as characters as well as hex. - Fix getmem/setmem commands. - - * srec.c (load_srec): Fix off by one typo in last submission. - - * rs6000-tdep.c (push_arguments): Fix typo. - -Thu Nov 30 23:54:17 1995 Per Bothner - - * language.c (lang_bool_type), language.h: New function. - * language.h (LA_BOOL_TYPE): New macro. - * eval.c (evaluate_subexp_standard) Use LA_BOOL_TYPE instead - of builtin_type_int where appropriate, - * valarith.c (value_subscript): Likewise. - - * valops.c (value_slice): Implement (value) bitstring slices. - * valprint.c (val_print): If TYPE_LENGTH is zero, don't automatically - print "" - Chill has zero-length (string) types. - - * gdbtypes.c (check_stub_type): Removed; no longes needed. - * ch-exp.c (expect, parse_call): Tweak error messages. - -Wed Nov 29 13:35:18 1995 Per Bothner - - * scm-valprint.c (scm_isymnames): Remove "#@" prefix. - (scm_scmval_print): Do not print "#@" prefix. - - * gdbtypes.h (enum type_code): Added TYPE_CODE_TYPEDEF. - (check_typedef): New prototype. - (CHECK_TYPEDEF): New macro. - (TYPE_DUMMY_RANGE): Removed. - * gdbtypes.c (get_discrete_bounds): Fix paren error; make more robust. - (create_array_type): Don't force_to_range_type; users of the - array are responsible for handling non-range index types. - (create_set_type): Likewise. - (force_to_range_type): Removed. - (check_typedef): New function handles stub types and typedefs. - (check_stub_type): Just call check_typedef. (To be removed.) - (recursive_dump_type): Handle TYPE_CODE_TYPEDEF. - * ch-lang.c (type_lower_upper): Use get_discrete_bounds. - (evaluate_subexp_chill): Handle string repetition. - Re-arrange to handle EVAL_AVOID_SIDE_EFFECTS better. - * ch-typeprint.c (chill_type_print_base): Handle TYPE_CODE_TYPEDEF. - Pass show=0 in recursive calls various places. - (case TYPE_CODE_ARRAY): Don't require index type to have - TYPE_CODE_RANGE. - (case TYPE_CODE_RANGE): Don't need to support TYPE_DUMMY_RANGE. - * gdbtypes.c, ch-lang.c, ch-typeprint.c (numerous places): - Add check_typedef/CHECK_TYPEDEF as needed. - - * ch-exp.y: Replaced by ... - * ch-exp.c: New file. Use recursive-descent. - Recognize labelled array tuples and powerset ranges. - * Makefile.in: Update for no longer using yacc for ch-exp. - - * c-lang.c: Make various functions non-static. - * c-lang.h: Add bunches of prototypes. - * cp-valprint.c (cp_print_value_fields): Also take address. - (cp_print_value): Likewise. Use baselcass_offset. - * stabsread.c (current_symbol): New static variable. - (type_synonym_name): Remove. - (read_type): If copying, make copy be a TYPE_CODE_TYPEDEF. - (read_array_type): Don't need to handle undefined element type here. - (cleanup_undefined_types): Ditto. - (read_range_type): Look for Chill ranges. - * valops.c (value_assign): Fix case lval_internalvar - don't try - to assign into old value (which might be too small!). - (value_coerce_array): No longer need special VALUE_REPEATED handling. - (value_arg_coerce): Cleaner array->pointer decay mechanism. - (search_struct_field): Use baseclass_offset rather than - baseclass_addr. - (value_slice): Use get_discrete_bounds. - * value.h (COERCE_VARYING_ARRAY): Take type argumnt as well. - * values.c (baseclass_offset): Change parameter interface. - (baseclass_addr): Removed. - * c-typeprint.c, c-valprint.c, ch-valprint.c, values.c, valops.c: - Add check_typedef/CHECK_TYPEDEF as needed. - - * alpha-tdep.c, c-exp.y, h8500-tdep.c, f-exp.y, f-valprint.c, - findvar.c, hppa-tdep.c, infcmd.c, language.c, printcmd.c, - rs6000-tdep.c, symmisc.c, symtab.c, mdebugread.c: - Add check_typedef/CHECK_TYPEDEF as needed. - - * f-typeprint.c, valarith.c, valprint.c, typeprint.c, eval.c: - Add check_typedef/CHECK_TYPEDEF as needed. - * f-typeprint.c: Various cleaning up. - * valarith.c (value_subscript): Also subscript bitstrings (for Chill). - * typeprint.c (print_type_scalar): Also support TYPE_CODE_RANGE. - * eval.c (evaluate_subexp_standard case OP_ARRAY): Implement - support for labelled array tuples and ranges in powerset tuples. - (init_array_element): New function. - - * top.c (command_line_input): Only strip out an initial #-comment. - Looking for internal comments is language-specific (breaks Scheme). - - * expression.h (enum exp_opcode): Add BINOP_RANGE. - * expprint.c (dump_expression): Support BINOP_RANGE. - * eval.c (evaluate_subexp_standard): Handle BINOP_RANGE (as error). - (case MULTI_SUBSCRIPT): Fix broken f77 value->int ad hoc conversion. - * ch-lang.c (chill_op_print_tab): Support BINOP_RANGE. - (evaluate_subexp_chill): Error on BINOP_COMMA. - - * Makefile.in: Clean up so doc stuff stays in doc sub-dir. - -Wed Nov 29 16:39:50 1995 Michael Meissner - - * monitor.c (monitor_debug): New function to print monitor debug - output in printable fashion. - (monitor_printf{,_noecho}): Call monitor_debug instead of - fputs_unfiltered. - - * srec.c (load_srec): When printing srec debug information, do not - print the carriage return directly, instead print \\r followed by - a newline. - -Tue Nov 28 15:25:28 1995 Doug Evans - - * Makefile.in (target_subdir): Define. - (CC_FOR_TARGET, CXX_FOR_TARGET): Use it to find target libraries. - * configure.in (X_CFLAGS): Fix typo. - (target_subdir): Set to "${target_alias}/" if cross. - * configure: Regenerated. - - * dbxread.c (dbx_symfile_read): Set block_address_function_relative - for `pe' format files. - -Tue Nov 28 11:17:47 1995 Fred Fish - - * magic.h: Renamed to gmagic.h to avoid conflict. - * magic.c: Renamed to gmagic.c in sympathy. - * eval.c, gmagic.c, config/tm-magic.h: - Include "gmagic.h" rather than "magic.h". - -Sat Nov 25 02:56:38 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (handle_psymbol_enumerators, parse_symbol): - Recognize enums from alpha cc -migrate. - (upgrade_type): Pass correct fd to parse_symbol when parsing - the index type of an array. - (parse_procedure, parse_lines, psymtab_to_symtab_1): Handle - unsorted procedure descriptors from Irix 5.x and Alpha OSF/1-3.x - shared libraries. Use CORE_ADDR instead of `unsigned long' in - procedure descriptor address computations. - - * symtab.c (decode_line_1): Prevent accidental strchr match - of a null character with the terminating null character of - gdb_completer_quote_characters. - (cplusplus_hint): Make sure that only a single quote is printed - in the hint message. - -Fri Nov 24 16:17:01 1995 Jeffrey A Law (law@cygnus.com) - - * top.c (recurse_read_control_structure): Don't make cleanups - here. Callers handle that correctly. - -Tue Nov 21 15:16:34 1995 Fred Fish - - * config/m68k/xm-hp300hpux.h: Define MMAP_BASE_ADDRESS and MMAP_INCREMENT. - Also force HAVE_MMAP to be defined since autoconf is currently broken - for detecting a working mmap under hpux. - * config/pa/xm-hppah.h (MMAP_BASE_ADDRESS): Tweak MMAP_BASE_ADDRESS - to a better value suggested by Jeffrey A Law (law@cygnus.com). - -Tue Nov 21 08:48:58 1995 Fred Fish - - * config/pa/xm-hppah.h: Define MMAP_BASE_ADDRESS and MMAP_INCREMENT. - Also force HAVE_MMAP to be defined since autoconf is currently broken - for detecting a working mmap under hpux. - * objfiles.c (map_to_address): Have gdb print a warning when it - is compiled with HAVE_MMAP but without both MMAP_BASE_ADDRESS and - MMAP_INCREMENT defined (thus making it appear mmap doesn't work). - -Mon Nov 20 14:13:53 1995 Stu Grossman (grossman@cygnus.com) - - * infrun.c (wait_for_inferior): Add support for dynamic function - trampolines. These are pieces of code between the caller and the - callee that figure out the address of the callee's code at run - time. Upon entry, we can't figure out the callee's address, so we - set a breakpoint within the trampoline where the address will be - known, and continue the target. Once we hit the breakpoint, we - break at the callee's address and proceed as usual. - -Mon Nov 20 11:12:34 1995 Fred Fish - - * objfiles.c (allocate_objfile): Change warning message about mapped - symbol tables so that it is obvious that they are not supported on - this particular machine rather than implying they are not supported - at all in this version of gdb. - -Sun Nov 19 05:20:53 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * irix5-nat.c, osfsolib.c (solib_address): Return the name of the - containing solib. - * stack.c (print_frame_info): Use minimal symbol only if - fi->pc is in a known section. - -Sat Nov 18 11:19:35 1995 Roland McGrath - - * solib.c (solib_address): Return the name of the containing solib. - * solib.h (PC_SOLIB): New macro; define using solib_address. - * stack.c (print_frame_info) [PC_SOLIB]: If no function name, try - PC_SOLIB on the PC value. - -Sat Nov 18 04:09:31 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * annotate.c (annotate_source, annotate_frame_begin): Issue - `0x' prefix for the pc value, to remain consistent with previous - GDB versions. - - * blockframe.c (find_pc_partial_function), config/pa/tm-hppa.h: - Remove Sun shared library transfer hack and - INHIBIT_SUNSOLIB_TRANSFER_TABLE_HACK, it is obsoleted by the - mst_solib_trampoline minimal symbols. - - * blockframe.c (inside_main_func): Check main_func_*pc against - INVALID_ENTRY_*PC, not zero. - * symfile.c (init_entry_point_info): Initialize ei.*pc with - INVALID_ENTRY_*PC. - * mipsread.c (mipscoff_symfile_read): If the entry_file bounds - are still unknown after processing the partial symbols, then try - to set them from the minimal symbols. - - * infcmd.c (registers_info): Error out if selected_frame is NULL. - * stack.c (return_command): Select new current frame silently if - not interactive. - - * mipsread.c (read_alphacoff_dynamic_symtab): Ignore additional - DT_MIPS_LOCAL_GOTNO and DT_MIPS_GOTSYM entries. - - * irix5-nat.c (solib_create_inferior_hook): Call solib_add only - if auto_solib_add_at_startup is nonzero. - (_initialize_solib): Add "set auto-solib-add" command. - * osfsolib.c (solib_create_inferior_hook): Call solib_add only - if auto_solib_add_at_startup is nonzero. - (_initialize_solib): Add "set auto-solib-add" command. - -Wed Nov 15 17:12:04 1995 Stan Shebs - - * utils.c: Don't include sys/ioctl.h etc if MPW is host. - -Tue Nov 14 17:16:46 1995 Doug Evans - - * config/arm/tm-arm.h (ADDITIONAL_REGISTER_NAMES): Fix r5. - (FRAME_SAVED_PC): Minor clean up. - -Tue Nov 14 14:51:05 1995 Stu Grossman (grossman@cygnus.com) - - * monitor.c (monitor_load_srec monitor_make_srec): Move all - S-record download code into srec.c. - * srec.c srec.h: New files. Contain S-record loading routines - formerly in monitor.c. - * serial.c serial.h: New routine just like fprintf, but uses - serial_t instead of FILE *. - * sh-tdep.c (frame_find_saved_regs init_extra_frame_info): - Don't add four to saved pc (makes things match manual). Also, fix - bug where we didn't get pc from stack frame correctly. - * config/sh/tm-sh.h (SAVED_PC_AFTER_CALL): Don't add four to - saved pc. Real hardware does this for you. - * sh3-rom.c (sh3_load): New routine. Sets up for download then - calls generic S-record loader. - * config/h8300/h8300.mt, config/h8500/h8500.mt, - config/m68k/monitor.mt, config/pa/hppapro.mt, config/sh/sh.mt: - Add srec.o to TDEPFILES. - -Tue Nov 14 15:57:36 1995 Michael Meissner - - * ppcbug-rom.c: New file to support the Motorola PPCBUG monitor - for PowerPC's. - - * config/powerpc/ppc{,le}-{eabi,sim}.mt (TDEPFILES): Include - ppcbug-rom.o, monitor.o, and srec.o - - * config/i386/linux.mt (XDEPFILES): Include ser-tcp.o. - -Mon Nov 13 13:12:46 1995 Jeffrey A Law (law@cygnus.com) - - * partial-stab.h: Remove GDB_TARGET_IS_HPPA kludge. - -Fri Nov 10 13:08:54 1995 Jeff Law (law@kahlua.cs.utah.edu) - - * terminal.h (HAVE_SGTTY): Fix typo. - -Thu Nov 9 17:34:01 1995 Michael Meissner - - * configure.in (gdb_target): Build in the simulator for all - PowerPC eabi targets, not just eabisim, providing - --enable-sim-powerpc is used, or the host compiler is GCC. - -Thu Nov 9 14:04:05 1995 Raymond Jou (rjou@mexican.cygnus.com) - - * mpw-config.in: Add variable with names of SIOW libraries. - * mpw-make.sed: Add an action to build SIOWgdb. - -Wed Nov 8 19:25:22 1995 Stan Shebs - - * mpw-make.sed: Edit @ENABLE_CFLAGS@ out, mpw-configure can - add back in if necessary. - -Wed Nov 8 15:59:52 1995 James G. Smith - - * config/mips/vr4300.mt: Added simulator to default VR4300 build. - -Tue Nov 7 16:02:25 1995 Stu Grossman (grossman@cygnus.com) - - * remote-mips.c (mips_initialize): Fix brain damage found by - Jamie. Basically had case statement in the wrong place... - * (mips_load): Remove unnecessary `db tty0' command. It's all - handled by mips_initialize now. - -Tue Nov 7 12:59:14 1995 Raymond Jou - - * mac-gdb.r: Added #ifdef Macgdb. - -Tue Nov 7 14:59:51 1995 James G. Smith - - * remote-mips.c (mips_initialize): Updated to talk to VR4300 RISQ - monitor board. - -Mon Nov 6 11:44:11 1995 James G. Smith - - * config/mips/{tm-vr4300.h tm-vr4300el.h} (TARGET_MONITOR_PROMPT): - Change into real strings. - - * remote-sim.c (gdbsim_open): Moved sim_open() call to after - callback initialisation. - -Sun Nov 5 00:07:52 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in (AC_CHECK_HEADERS): add stddef.h. - -Fri Nov 3 12:30:43 1995 Fred Fish - - * Makefile.in (COMMON_OBS): Use corefile.o rather than core.o - * core.c: Rename to corefile.c. - * config/pyr/tm-pyr.h, umax-xdep.c, sun386-nat.c, pyr-xdep.c, - Makefile.in (SFILES), gould-xdep.c, coredep.c, armtdep.c, - arm-xdep.c, altos-xdep.c: Change core.c references to corefile.c. - - From Graham Stoney . - * Makefile.in (remote-array.o): Add rule to build. - (ALLDEPFILES): Add remote-array.c - * remote-array.c (baud_rate): Remove unnecessary declaration. - (baudrate): Remove. - (array_files_info): Print global baud_rate not baudrate. - -Sat Nov 4 10:21:58 1995 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (INTERNAL_CFLAGS): Add ENABLE_CFLAGS. - * fork-child.c (fork_inferior): Add call to - TARGET_CREATE_INFERIOR_HOOK to allow target specific code to get - control just before the new process executes it's first instruction. - * remote-mips.c (mips_initialize): Cleanup a bit. Don't try to - receive a packet at first. This speeds up initialization a lot. - Use TARGET_MONITOR_PROMPT instead of "". - (common_breakpoint): Use rresponse instead of rerrflg to inspect - error code. - * symfile.c (syms_from_objfile reread_symbols): Call - TARGET_SYMFILE_POSTREAD to allow target specific code to get - control after reading new symbols. - * target.h: New macros TARGET_SYMFILE_POSTREAD, and - TARGET_CREATE_INFERIOR_HOOK. See above for descriptions. - * config/mips/{irix5.mh nm-irix5.h}: Delete nm-irix5.h. Make - NAT_FILE point directly at ../nm-sysv4.h. - * config/mips/{mipsm3.mh nm-m3.h}: Delete nm-m3.h. Make - NAT_FILE point directly at ../nm-m3.h. - * config/mips/{mipsv4.mh nm-sysv4.h}: Delete nm-sysv4.h. Make - NAT_FILE point directly at ../nm-sysv4.h. - * config/mips/nm-mips.h: Improve comment at top of file. - * config/mips/tm-mips.h (TARGET_MONITOR_PROMPT): Change - definition into a proper string. - -Wed Nov 1 20:18:08 1995 Fred Fish - - * config/i386/tm-i386.h: New file containing generic i*86 target - definitions. - (TARGET_BYTE_ORDER): Moved here from tm-i386v.h. - (IEEE_FLOAT): Moved here from tm-i386v.h. - (START_INFERIOR_TRAPS_EXPECTED): Define default as 2. - (FUNCTION_START_OFFSET): Moved here from tm-i386v.h. - (SKIP_PROLOGUE): Moved here from tm-i386v.h. - (SAVED_PC_AFTER_CALL): Moved here from tm-i386v.h. - (INNER_THAN): Moved here from tm-i386v.h. - (BREAKPOINT): Moved here from tm-i386v.h. - (DECR_PC_AFTER_BREAK): Moved here from tm-i386v.h. - (ABOUT_TO_RETURN): Moved here from tm-i386v.h. - (REGISTER_SIZE): Moved here from tm-i386v.h. - (NUM_REGS): Moved here from tm-i386v.h. - (REGISTER_NAMES): Moved here from tm-i386v.h. - (EXTRACT_STRUCT_VALUE_ADDRESS): Moved here from tm-i386v.h. - (FP_REGNUM): Moved here from tm-i386v.h. - (SP_REGNUM): Moved here from tm-i386v.h. - (PC_REGNUM): Moved here from tm-i386v.h. - (PS_REGNUM): Moved here from tm-i386v.h. - (FP0_REGNUM): Moved here from tm-i386aix.h. - (FPC_REGNUM): Moved here from tm-sun386.h. - (REGISTER_BYTES): Moved here from tm-i386aix.h. - (REGISTER_BYTE): Moved here from tm-i386aix.h. - (REGISTER_RAW_SIZE): Moved here from tm-i386aix.h. - (MAX_REGISTER_RAW_SIZE): Moved here from tm-i386aix.h. - (REGISTER_VIRTUAL_SIZE): Moved here from tm-i386aix.h. - (MAX_REGISTER_VIRTUAL_SIZE): Moved here from tm-i386aix.h. - (EXTRACT_RETURN_VALUE): Moved here from tm-i386aix.h. - (STORE_RETURN_VALUE): Moved here from tm-i386aix.h. - (REGISTER_VIRTUAL_TYPE): Moved here from tm-i386v.h. - (STORE_STRUCT_RETURN): Moved here from tm-i386v.h. - (FRAME_CHAIN): Moved here from tm-i386v4.h. - (FRAMELESS_FUNCTION_INVOCATION): Moved here from tm-i386v4.h. - (FRAME_SAVED_PC): Moved here from tm-i386os9k.h - (FRAME_ARGS_ADDRESS): Moved here from tm-i386v.h. - (FRAME_LOCALS_ADDRESS): Moved here from tm-i386v.h. - (FRAME_NUM_ARGS): Moved here from tm-i386sun.h. - (FRAME_ARGS_SKIP): Moved here from tm-i386v.h. - (FRAME_FIND_SAVED_REGS): Moved here from tm-i386v.h. - (PUSH_DUMMY_FRAME): Moved here from tm-i386v.h. - (POP_FRAME): Moved here from tm-i386v.h. - (CALL_DUMMY, CALL_DUMMY_LENGTH, CALL_DUMMY_START_OFFSET, - CALL_DUMMY_BREAKPOINT_OFFSET, FIX_CALL_DUMMY): Moved here from - tm-i386v.h - (print_387_control_word, print_387_status_word): Declare prototypes. - (struct frame_info, struct frame_saved_regs): Forward decls for - prototypes. - (SP_ARG0): Moved here from tm-i386v.h. - - * config/i386/tm-i386v.h: - (i386/tm-i386.h): Include. - (TARGET_BYTE_ORDER): Remove. - (IEEE_FLOAT): Remove. - (START_INFERIOR_TRAPS_EXPECTED): Undef before redefine to 4. - (FUNCTION_START_OFFSET): Remove. - (SKIP_PROLOGUE): Remove. - (i386_skip_prologue): Remove prototype. - (SAVED_PC_AFTER_CALL): Remove. - (INNER_THAN): Remove. - (BREAKPOINT): Remove. - (DECR_PC_AFTER_BREAK): Remove. - (ABOUT_TO_RETURN): Remove. - (REGISTER_SIZE): Remove. - (NUM_REGS): Undef before redefine to 16 (no FP support). - (REGISTER_NAMES): Undef before redefine. - (FP_REGNUM, SP_REGNUM, PC_REGNUM, PS_REGNUM): Remove. - (REGISTER_BYTES): Undef before redefine. - (REGISTER_BYTE): Undef before redefine. - (REGISTER_RAW_SIZE): Undef before redefine. - (REGISTER_VIRTUAL_SIZE): Undef before redefine. - (MAX_REGISTER_RAW_SIZE): Undef before redefine. - (MAX_REGISTER_VIRTUAL_SIZE): Undef before redefine. - (REGISTER_VIRTUAL_TYPE): Undef before redefine. - (STORE_STRUCT_RETURN): Undef before redefine. - (EXTRACT_RETURN_VALUE): Undef before redefine. - (STORE_RETURN_VALUE): Undef before redefine. - (EXTRACT_STRUCT_VALUE_ADDRESS): Remove. - (FRAME_CHAIN): Undef before redefine. - (FRAMELESS_FUNCTION_INVOCATION): Undef before redefine. - (FRAME_SAVED_PC): Undef before redefine. - (FRAME_ARGS_ADDRESS): Remove. - (FRAME_LOCALS_ADDRESS): Remove. - (FRAME_NUM_ARGS): Undef before redefine. - (FRAME_ARGS_SKIP): Remove. - (FRAME_FIND_SAVED_REGS): Remove. - (PUSH_DUMMY_FRAME): Remove. - (POP_FRAME): Remove. - (CALL_DUMMY): Remove. - (CALL_DUMMY_LENGTH): Remove. - (CALL_DUMMY_START_OFFSET): Remove. - (CALL_DUMMY_BREAKPOINT_OFFSET): Remove - (FIX_CALL_DUMMY): Remove. - (print_387_control_word): Remove. - (print_387_status_word): Remove. - (SP_ARG0): Remove. - - * config/i386/tm-symmetry.h: - (TM_SYMMETRY_H): Enclose file in test for define & define if needed. - (START_INFERIOR_TRAPS_EXPECTED): Move to after inclusion of - tm-i386v4.h or tm-i386v.h, #undef, and #define back to 2. - (DECR_PC_AFTER_BREAK): Move to after inclusion of tm-i386v4.h - or tm-i386v.h, #undef, and #define to 0. - (MAX_REGISTER_RAW_SIZE): Remove. - (FRAME_CHAIN): Remove. - (FRAMELESS_FUNCTION_INVOCATION): Remove. - (FRAME_SAVED_PC): Remove. - (print_387_control_word, print_387_status_word): Remove prototypes. - - * config/i386/tm-ptx.h: - (TM_PTX_H): Enclose file in test for define & define if needed. - (START_INFERIOR_TRAPS_EXPECTED): Move to after inclusion of - tm-i386v4.h or tm-i386v.h, #undef, and #define back to 2. - (DECR_PC_AFTER_BREAK): Move to after inclusion of tm-i386v4.h - or tm-i386v.h, #undef, and #define to 0. - (SDB_REG_TO_REGNUM): Remove obsolete commented out define. - (print_387_control_word, print_387_status_word): Remove prototypes. - - * config/i386/tm-linux.h: - (TM_LINUX_H): Enclose file in test for define & define if needed. - (i386/tm-i386.h): Include instead of tm-i386v.h. - (START_INFERIOR_TRAPS_EXPECTED): Remove. - - * config/i386/tm-i386v4.h: - (TM_I386V4_H): Enclose file in test for define & define if needed. - (i386/tm-i386.h): Include instead of tm-i386v.h. - (START_INFERIOR_TRAPS_EXPECTED): Remove. - (FRAME_CHAIN): Moved to tm-i386.h. - (FRAMELESS_FUNCTION_INVOCATION): Moved to tm-i386.h. - (FRAME_SAVED_PC): Remove. - (sigtramp_saved_pc): Define as i386v4_sigtramp_saved_pc. - (FRAME_NUM_ARGS): Remove. - - * config/i386/tm-i386os9k.h: - (TM_I386OS9K_H): Enclose file in test for define & define if needed. - (i386/tm-i386.h): Include instead of tm-i386v.h. - (START_INFERIOR_TRAPS_EXPECTED): Remove. - (NUM_REGS): Undefine before redefining. - (FRAME_CHAIN): Remove. - (FRAMELESS_FUNCTION_INVOCATION): Remove. - (FRAME_SAVED_PC): Move to tm-i386.h. - - * config/i386/tm-i386nw.h: - (TM_I386NW_H): Enclose file in test for define & define if needed. - (i386/tm-i386.h): Include instead of tm-i386v.h. - (START_INFERIOR_TRAPS_EXPECTED): Remove. - - * config/i386/tm-i386bsd.h: - (TM_I386BSD_H): Enclose file in test for define & define if needed. - (i386/tm-i386.h): Include instead of tm-i386v.h. - (START_INFERIOR_TRAPS_EXPECTED): Remove. - (FRAMELESS_FUNCTION_INVOCATION): Remove. - (FRAME_SAVED_PC): Remove. - - * config/i386/tm-i386aix.h: - (i386/tm-i386.h): Include instead of tm-i386v.h. - (START_INFERIOR_TRAPS_EXPECTED): Remove. - (FP_REGNUM): Remove. - (SP_REGNUM): Remove. - (PC_REGNUM): Remove. - (PS_REGNUM): Remove. - (FP0_REGNUM): Moved to tm-i386.h. - (NUM_REGS): Remove. - (REGISTER_NAMES): Remove. - (REGISTER_BYTES): Moved to tm-i386.h. - (REGISTER_BYTE): Moved to tm-i386.h. - (REGISTER_RAW_SIZE): Moved to tm-i386.h. - (MAX_REGISTER_RAW_SIZE): Moved to tm-i386.h. - (REGISTER_VIRTUAL_SIZE): Moved to tm-i386.h. - (REGISTER_VIRTUAL_TYPE): Removed. - (EXTRACT_RETURN_VALUE): Moved to tm-i386.h. - (STORE_RETURN_VALUE): Moved to tm-i386.h. - - * config/i386/tm-sun386.h: - (TM_SUN386_H): Enclose file in test for define & define if needed. - (i386/tm-i386.h): Include. - (TARGET_BYTE_ORDER): Remove. - (FUNCTION_START_OFFSET): Remove. - (SKIP_PROLOGUE): Remove. - (SAVED_PC_AFTER_CALL): Remove. - (INNER_THAN): Remove. - (BREAKPOINT): Remove. - (DECR_PC_AFTER_BREAK): Remove. - (ABOUT_TO_RETURN): Remove. - (REGISTER_SIZE): Remove. - (NUM_REGS): Undefine before defining. - (REGISTER_NAMES): Undefine before redefining. - (REGISTER_BYTES): Undefine before redefining. - (REGISTER_BYTE): Undefine before defining. - (FP_REGNUM): Undefine before defining. - (PC_REGNUM): Undefine before defining. - (FPC_REGNUM): Undefine before defining. - (REGISTER_RAW_SIZE): Undefine before defining. - (FRAME_CHAIN): Undefine before defining. - (FRAMELESS_FUNCTION_INVOCATION): Undefine before defining. - (FRAME_SAVED_PC): Undefine before defining. - (FRAME_NUM_ARGS): Moved to tm-i386.h. - (MAX_REGISTER_RAW_SIZE): Remove. - (MAX_REGISTER_VIRTUAL_SIZE): Remove. - (STORE_STRUCT_RETURN): Remove. - (EXTRACT_STRUCT_VALUE_ADDRESS): Remove. - (FRAME_ARGS_ADDRESS): Remove. - (FRAME_LOCALS_ADDRESS): Remove. - (FRAME_NUM_ARGS): Undefine before defining. - (FRAME_ARGS_SKIP): Remove. - (FRAME_FIND_SAVED_REGS): Remove. - (PUSH_DUMMY_FRAME): Remove. - (POP_FRAME): Remove. - (CALL_DUMMY, CALL_DUMMY_LENGTH, CALL_DUMMY_START_OFFSET): Remove. - (struct frame_info, struct frame_saved_regs): Remove forward decls - for prototypes. - - * config/i386/tm-i386lynx.h (i386/tm-i386.h): Include instead of - tm-i386v.h. - * config/i386/tm-i386m3.h (i386/tm-i386.h): Include instead of - tm-i386v.h. - - * i386-tdep.c (i386_extract_return_value): Make function visible - for all i386 targets, but only assume floating point values returned - in floating point registers for I386_AIX_TARGET. - - * i386v-nat.c (i386_register_u_addr): Enable code to locate - floating point regs in user struct. - -Wed Nov 1 15:32:57 1995 Fred Fish - - * breakpoint.c (breakpoint_re_set): Fix typo in comment. - * symtab.c (in_prologue): Document func_start and when it is zero - don't call SKIP_PROLOGUE (which typically leads unconditionally to - an error when we try to access a prologue at address 0). - -Tue Oct 31 13:01:15 1995 Fred Fish - - * elfread.c: Include elf-bfd.h rather than libelf.h. - -Tue Oct 31 10:42:42 1995 steve chamberlain - - * win32-nat.c (xlate_exception): Treat a stack overflow like a SEGV. - -Sun Oct 29 11:22:05 1995 Fred Fish - - * monitor.c: Include gnu-regex.h rather than system regex.h. - -Sat Oct 28 23:51:48 1995 steve chamberlain - - * defs.h: Test on name __WIN32__ rather than WIN32. - * inflow.c (new_tty): Likewise - * terminal.h: Likewise. - * utils.c (initialize_utils): Likewise. - * win32-nat.c (child_create_inferiror): Print error code when failing. - * config/i386/win32.mh (XM_CLIBS): Need -lkernel32. - -Sat Oct 28 04:52:36 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symtab.h (enum address_class): Add LOC_UNRESOLVED for - a location whose address has to be resolved via the minimal - symbol table. - * buildsym.c (finish_block), findvar.c (symbol_read_needs_frame, - read_var_value), printcmd.c (address_info), - symmisc.c (print_symbol, print_partial_symbol): Handle - LOC_UNRESOLVED. - * stabsread.c (scan_file_globals): Change unresolved LOC_STATIC - symbols to LOC_UNRESOLVED. Remove rt_common_objfile lookup - kludge, global common symbols are now handled by LOC_UNRESOLVED. - (scan_file_globals_1): Move code back to scan_file_globals, - delete. - -Fri Oct 27 09:54:07 1995 Stu Grossman (grossman@cygnus.com) - - * breakpoint.c (breakpoint_re_set): #ifdef GET_LONGJMP_TARGET - around calls to create_longjmp_breakpoint. Why install the - breakpoints if we can't find the longjmp target? - * infrun.c (wait_for_inferior): Cleanup comments near call test. - * remote-mips.c: Fixed a bunch of prototypes to avoid char/int - complaint from picky compilers. Add comment to mips_expect. - Replace all instances of sr_get_debug with remote_debug. - * (mips_readchar): Don't jam init string to monitor. - mips_initialize() handles that. - * (mips_receive_header): Print better message when we get too - much garbage. - * (mips_request): Allow caller to pass in buff to allow them to - analyze the returned message. - * (mips_initialize): Re-do initialization to try sending a BREAK, - a ^C, and then a download escape sequence. Cleanup protocol - startup. Eliminate sleeps. Clear breakpoints (if using monitor - breakpoints). Re-init frame. - * (mips_detach): Close down target. - * (mips_wait): Handle return status with registers, or breakpoint - * stuff. - * (mips_kill): Add ^C handling. - * (mips_insert_breakpoint mips_remove_breakpoint): Call new - breakpoint stuff if enabled. - * (calculate_mask remote_mips_set_watchpoint - remote_mips_remove_watchpoint remote_mips_stopped_by_watchpoint): - Hardware watchpoint/breakpoint stuff. - * (common_breakpoint): Common code for new monitor breakpoint commands. - * (mips_load): Don't use `prompt'. It's a global variable. - * top.c (dont_repeat_command): New command for use in - user-defined commands to suppress auto-repeat (by hittin return key). - * valops.c: Add start of auto function-call abandonment capability. - -Thu Oct 26 22:02:27 1995 Stan Shebs - - * mpw-config.in: Add support for PowerMac host, add beginnings - of native support. - * mpw-make.sed: Disable subdir recursion, edit out useless rule. - * mac-xdep.c (Values.h): Don't include. - (GestaltEqu.h): Include Gestalt.h instead. - (do_mouse_down): Comment out control tracking, needs to be - updated to use UPP before will work on PowerMac. - * config/xm-mpw.h: New file, all-Mac host support. - * config/m68k/xm-mpw.h: Move most definitions into generic Mac - support. - * config/powerpc/xm-mpw.h: New file, PowerMac host support. - -Thu Oct 26 15:21:32 1995 Brendan Kehoe - - * regex.h: Renamed to gnu-regex.h. - * regex.c: Renamed to gnu-regex.c. - * Makefile.in (POSSLIBS): Refer to gnu-regex.h and gnu-regex.c. - (REGEX, REGEX1): Change to gnu-regex.o instead of regex.o. - (regex.o): Renamed to gnu-regex.o; refer to gnu-regex.c. - (irix5-nat.o, osfsolib.o, gnu-regex.o, solib.o, source.o, symtab.o): - Likewise. - * irix5-nat.c, osfsolib.c, gnu-regex.c, solib.c, source.c, symtab.c): - Include "gnu-regex.h" instead of "regex.h". - * alpha-tdep.c (in_prologue): Rename to alpha_in_prologue, to - avoid conflicts with symtab.h. - -Tue Oct 24 18:30:18 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * config/pa/hppahpux.mh: Remove hardcoding of X locations. - * Makefile.in: Use X11_CFLAGS, X11_LDFLAGS and X11_LIBS. - * configure.in: Link X statically on Solaris, SunOS and HPUX. - -Tue Oct 24 12:26:14 1995 Stu Grossman (grossman@cygnus.com) - - * monitor.c (monitor_expect_regexp): Same as monitor_expect, but - with the obvious extension. - (monitor_read_memory_single): Use regexp for getmem.resp_delim - because of parsing ambiguities caused by certain monitors. - (monitor_read_memory): Use new regexp stuff to parse - getmem.resp_delim. - * monitor.h (struct memrw_cmd->resp_delim): Document this as a - regexp. - * sh3-rom.c: Finish off table. Use new regexp capability for - getmem commands. - - * infrun.c (wait_for_inferior): Disable questionable code near - the step range test. Replace call detection test with much - simpler (and more efficient) test that doesn't require prologue - examination (as often). - * symtab.c symtab.h (in_prologue): New function that indicates - whether or not we are in a function prologue. This uses the - symbol table, and then falls back to prologue examination if that - fails. It's much more efficient for remote debugging because it - avoids examining memory, which is very slow. This is used in - wait_for_inferior to determine if we've made a function call that - needs to be skipped over (for next/nexti). - * mips-tdep.c (after_prologue): New function, returns the PC - after the prologue. Uses PDRs and the symbol table. - (mips_find_saved_regs): Use in_prologue() to avoid costly - prologue examination if possible. - (mips_skip_prologue): Use after_prologue() if possible to avoid - costly prologue examination. - -Mon Oct 23 16:03:33 1995 James G. Smith - - * configure.in (configdirs): Added support for the VR4300 default - builds (mips64*vr4300*el-*-elf*, mips64*vr4300*-*-elf*). - - * configure: Regenerated. - - * remote-mips.c (mips_load): Updated the prompt spotting code to - make use of the TARGET_MONITOR_PROMPT manifest. - -Sat Oct 21 06:11:49 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-tdep.c, mips-tdep.c (init_extra_frame_info): - Do not set saved registers from heuristics for a sigtramp frame. - - * dwarfread.c (enum_type): Determine signedness of enum type - from enumerators. - - * mips-tdep.c: Include gdb_string.h, gcc -Wall lint. - - * rs6000-nat.c (xcoff_relocate_core): Fix typo. - - * valops.c (value_repeat): Fix length of memory transfer to - match recent allocate_repeat_value change. - -Thu Oct 19 19:04:35 1995 Per Bothner - - * gdbtypes.c (get_discrete_bounds): Fix typo. - -Thu Oct 19 12:15:37 1995 Stan Shebs - - * defs.h (SEEK_SET, SEEK_CUR): Add default definitions. - * dbxread.c, mdebugread.c, os9kread.c (SEEK_SET, SEEK_CUR): - Remove default definitions. - - * Makefile.in (CC-LD): Rename to CC_LD, so MPW xform works. - (MMALLOC_SRC): Define. - (MMALLOC_CFLAGS): Use. - (ser-mac.o): Add rule. - * dwarfread.c, somread.c, ultra3-nat.c, xcoffread.c: Replace L_SET - with SEEK_SET in all calls to bfd_seek. - * scm-tags.h (scm_tags): Remove excess comma. - - * mpw-config.in: Adapt to work with autoconf'ed configury; - build config.h, add empty definitions to mk.tmp. - (powerpc-apple-macos): Make it work. - * mpw-make.sed: New file, sed commands to translate Unix makefile - into MPW syntax. - * mpw-make.in: Remove. - * mac-gdb.r: New file, was macgdb.r, renamed for consistency - with other tools, now includes cfrg resource. - * macgdb.r: Remove. - * config/m68k/xm-mpw.h: Remove most of contents, replace with - include of include/mpw/mpw.h. - -Tue Oct 17 10:38:53 1995 Jeffrey A Law (law@cygnus.com) - - * hppa-tdep.c (frame_chain): Fix more obscure problems caused - by system calls that core dump processes without saving all - the register state. - - * config/pa/hppahpux.mt (XDEPFILES): Remove bogus definition. - * config/pa/hppapro.mt (XDEPFILES): Likewise. - -Tue Oct 17 08:04:26 1995 Fred Fish - - * NEWS: Fix typo. - -Mon Oct 16 18:24:03 1995 Jim Wilson - - * config/sh/tm-sh.h (REGISTER_VIRTUAL_TYPE): Return builtin_type_float - for FP registers. - (REGISTER_NAMES): Add FP register names. Remove ticks, stalls, cycles, - insts, plr, and tlr. - (NUM_REGS, NUM_REALREGS): Increase from 23 to 41. - (FPUL_REGNUM, FP0_REGNUM): New macros. - -Mon Oct 16 11:27:06 1995 Stu Grossman (grossman@cygnus.com) - - * remote-mips.c: Add support for speedy (about 10x faster) - downloads. - - * remote-array.c: Move baud_rate initialization from - _initialize_array to array_open. It was forcing the baud rate of - all targets to be 4800 baud! Seems like I've fixed this before... - * config/mips/idt.mt (TDEPFILES): Remove remote-array.o. This - has *nothing* to do with IDT!!! - - - * Makefile.in sh3-rom.c config/sh/sh.mt config/sh/tm-sh.h: Add - sh3 monitor support. - * monitor.c: Cleanup regexp compilation stuff to make it easier - to use several regexps. - * monitor.h: Get rid of struct rom_cmd_data. It's no longer used. - * config/m68k/tm-monitor.h: Don't redefine NUM_REGS here. It just - causes GDB to crash. - - * sparcl-tdep.c: Cleanup serial error handling. - -Sun Oct 15 16:19:27 1995 Stan Shebs - - * rs6000-tdep.c: Don't include a.out.h, improve some formatting. - -Fri Oct 13 15:27:49 1995 Stu Grossman (grossman@cygnus.com) - - * dcache.c: Change default value of remotecache to off. It just - screws up too many targets. - * sparcl-stub.c: Add prototypes to many forward decls. - * Create private copies of strlen, strcpy, and memcpy to prevent - chaos when user steps into them. - * (trap_low handle_exception): Clean up DSU support code - (hardware breakpoints). Move lots of stuff from asm-land to - C-land (make it much easier to #ifdef if necessary). Also, use - trap 255 to get into break mode instead of doing a DSU register - write, which may trash the register. - * (putpacket): Don't check return value of putDebugChar. It - returns void... - -Fri Oct 13 14:16:17 1995 steve chamberlain - - * remote-sim.h: Always include callback.h. - (sim_set_callbacks): New declaration. - -Fri Oct 13 10:57:40 1995 Jeffrey A Law (law@cygnus.com) - - * somsolib.c (som_solib_add): Just give a warning if a file - mentioned in the dld_list can't be found. - * config/pa/tm-hppah.h (FRAME_SAVED_PC_IN_SIGTRAMP): Dig out - the PC from the PC queues rather than %r31. - -Thu Oct 12 13:36:15 1995 Jeffrey A Law (law@cygnus.com) - - * corelow.c (core_open): Don't update the to_sections and - to_sections_end fields in core_ops here. It's too late. - * irix5-nat.c (solib_add): Update the to_sections and - to_sections_end fields in core_ops here if needed. - * osfsolib.c (solib_add): Likewise. - * rs6000-nat.c (xcoff_relocate_core): Likewise. - * solib.c (solib_add): Likewise. - * somsolib.c (solib_add): Likewise. - -Wed Oct 11 17:25:59 1995 Fred Fish - - * Makefile.in (VERSION): Bump version to 4.15.1 - -Tue Oct 10 15:26:39 1995 Fred Fish - - * Makefile.in (VERSION): Version 4.15 released. - * README: Updated for version 4.15. - * NEWS: Updated for 4.15 release. - -Tue Oct 10 13:18:50 1995 Fred Fish - - * configure.in: Add AC_PROG_YACC - * configure: Regenerate - * Makefile.in (BISON): Remove macro definition. - (YACC): Set from autoconfig. - (FLAGS_TO_PASS): Remove BISON. - (TARGET_FLAGS_TO_PASS): Remove BISON. - -Tue Oct 10 12:25:11 1995 steve chamberlain - - * win32-nat.c (child_create_inferior): Pass argv correctly. - * Makefile.in (win32-nat.o): Add dependencies. - -Mon Oct 9 14:36:29 1995 steve chamberlain - - * NEWS: Add information about win32 and arm code. - * win32-nat.c: Renamed from win32.c. - * config/i386/win32.mh: Renamed from config/i386/i386win32.mh. - * config/i386/win32.mt: Renamed from config/i386/i386win32.mt. - * config/i386/tm-win32.h: Renamed from config/i386/tm-i386win32.h. - * config/i386/xm-win32.h: Renamed from config/i386/xm-i386win32.h. - * configure.in (i[345]86-*-win32): Updated to cope with filename - changes. - * configure: Regenerated. - -Sun Oct 8 18:01:04 1995 Per Bothner - - * ch-exp.y (yylex): Also look for '$' following '$'. - -Sat Oct 7 22:52:42 1995 Michael Meissner - - * ch-exp.y (yylex): Fix typo. - -Fri Oct 6 11:56:49 1995 Jim Wilson - - * remote-sim.c (gdbsim_open): Put callback initializations here. - (_initalize_remote_sim): Not here. - -Fri Oct 6 17:08:49 1995 Stan Shebs - - * top.c (execute_control_command): Use 0/1 instead of BFD's - true/false. - -Fri Oct 6 14:43:19 1995 Stu Grossman (grossman@cygnus.com) - - * sparcl-stub.c: Include sparclite.h to get access to register - fondling macros. - * (trap_low): Save and restore FP regs if necessary. Also, clean - up save and restore of debug unit regs. - * (hard_trap_info): Add more architecturally defined traps. - * (set_debug_traps): Only set FP disabled trap if FP is disabled. - * (get_in_break_mode): Clean up. Get rid of calls to - set_hw_breakpoint_trap(). Also, use write_asi macro. - * (handle_exception): Clean up `g' and `G' commands. Add `P' - command. - * (hw_breakpoint): Why was this here!? It's gone now... - -Fri Oct 6 11:56:49 1995 Jim Wilson - - * callback.c (fdbad): Fix typo in comment. - (os_close, os_isatty, os_lseek, os_read, os_write): Use if - statements rather than || to get correct return value. - (os_write_stdout): Pass missing first argument to os_write. - * remote-sim.c: Include callback.h. - (_initialize_remote_sim): Call sim_set_callbacks and then - initialize the callbacks. - -Thu Oct 5 17:28:09 1995 Per Bothner - - * values.c (allocate_repeat_value): Allocate an array type, and - a value of that type; use that instead of setting VALUE_REPEATED. - * value.h (struct value): Remove fields repetitions and repeated. - (VALUE_REPEATED, VALUE_REPETITIONS): Removed, no longer used. - * c-valprint.c, ch-valprint.c, eval.c, printcmd.c, valops.c, - value.h, values.c: Simplify, since now VALUE_REPEATED is never - used. - * valprint.c (value_print_array_elemen): Removed never-used - function. - -Thu Oct 5 15:14:36 1995 Per Bothner - - * parse.c (write_dollar_variable): New function. - - * c-exp.y (yylex): Replace code for recognizing '$' - pseudo-variables with a call to write_dollar_variable. - Simplify grammar correspondingly. - * f-exp.y: Likewise. - * m2-exp.y: Likewise. - * ch-exp.y: Likewise. (Remove function match_dollar_tokens.) - * scm-exp.c (scm_lreadr): Call write_dollar_variable to handle '$'. - -Thu Oct 5 13:27:30 1995 steve chamberlain - - * win32.c: New file; support for debugging on windows NT. - * configure.in: (i[345]86-*-win32): New target. - * configure: Regnerated. - * eval.c (evaluate_subexp_standard): Remove unused name. - * serial.c (gdb_string.h): Include. - * source.c (value.h): Include. - * config/i386/i386win32.mh (XDEPFILES): Add win32.o - * config/i386/i386win32.mt: New. - * config/i386/tm-i386win32.h: New. - -Wed Oct 4 18:41:34 1995 Per Bothner - - * expression.h (enum exp_code): Added OP_NAME. - * expprint.c (print_subexp): Add OP_NAME support. - * parse.c (length_of_subexp, prefixify_subexp): Likewise. - * scm-lang.c (scm_unpack, in_eval_c, scm_lookup_name): new function. - * scm-lang.h: Declare builtin_type_scm; other minor tweaks. - * values.c (unpack_long): If type is SCM, call scm_unpack. - * scm-valprint.c (scm_val_print): Use extract_signed_integer, - instead unpack_long - * scm-lang.c: More Scheme expression parsing from here ... - * scm-exp.c: ... to here. New file. - Also, provide for gdb to evaluate simple constants and names.. - * Makefile.in: Note new scm-exp.{c,o}. - -Wed Oct 4 17:23:03 1995 Per Bothner - - * gdbtypes.c (get_discrete_bounds): New function. - (force_to_range_type): Use get_discrete_bounds. - * gdbtypes.h (get_discrete_bounds): Add declaration. - * valarith.c (value_bit_index): Generalize to use get_discrete_bounds. - * ch-valprint.c (chill_val_print): Make (power)sets and bitstring - support use get_discrete_bounds and generally be more robust. - -Tue Oct 3 16:54:56 1995 Stan Shebs - - * remote-nrom.c (nrom_ops): Add value for to_thread_alive, - add comments naming slots. - -Mon Oct 2 21:45:44 1995 Jeff Law (law@hurl) - - * top.c (build_command_line): Demand arguments for if/while - commands. - -Mon Oct 2 13:08:01 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * Makefile.in (X11_CFLAGS): Set only to @X_INCDIR@. - -Sat Sep 30 16:13:36 1995 Per Bothner - - * scm-lang.c: Moved Scheme value printing code to ... - * scm-valprint.c: ... this new file. - Also major improvements in support for printing SCM values. - * scm-lang.h: New file. - * scm-tags.h: New file. - * Makefile.in: Note new scm-valprint.{c,o}. - -Sat Sep 30 09:35:02 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in: X_INCDIR and X_LIBDIR added. - * Makefile.in: @X_INCDIR@ and @X_LIBDIR@ added. - * configure: Regnerated. - -Fri Sep 29 02:10:05 1995 steve chamberlain - - * config/arm/tm-arm.h (FRAME_CHAIN, FRAME_CHAIN_VALID): - Any pc > LOWESTPC is ok. - - * remote-rdp.c (rdp_init): Take out variable baud rate stuff. - (remote_rdp_detatch): Delete. - * breakpoint.c (ctype.h): Don't include twice. - - * Makefile.in (remote-rdp.o): Doesn't need remote-rdp.h - * callback.c (os_printf_filtered): fix protos. - * defs.h (puts_filtered, puts_unfiltered - [v|f|]printf_[un]filtered): Make format arg const. - * remote-rdp.c (rdp_init): Attept to sync at different - baudrates. - * utils.c (puts_filtered, puts_unfiltered - [v|f|]printf_[un]filtered): Define prototypes with - const in the right place. - -Thu Sep 28 17:43:39 1995 Per Bothner - - * defs.h (enum language): Add language_scm. - * expression.h (enum exp_code): Added OP_EXPRSTRING. - * scm-lang.c: Preliminary support for Guile /SCM dialect of Scheme. - * expprint.c (print_subexp): Add OP_EXPRSTRING support. - * parse.c (length_of_subexp, prefixify_subexp): Likewise. - * valops.c (find_function_in_inferior): New function. - (value_allocate_space_in_inferior): New function. - (allocate_space_in_inferior): Redefine using previous function. - * Makefile.in (SFILES): Add scm-lang.c. - (COMMON_OBS): Add scm-lang.o - -Thu Sep 28 14:32:11 1995 steve chamberlain - - * callback.[ch]: New files. - * remote-rdp.c: Support for the ARM RDP monitor. - * Makefile: Update. - * arm-tdep.c (arm_othernames): New. - (_initialize_arm_tdep): install 'othernames' command. - (arm_nullified_insn, shifted_reg_val, arm_get_next_pc): New. - * configure.in: Check for termios.h, termio.h and sgtty.h. - (i[345]86-*-win32*): New host. - * configure: Regenerated. - * inflow.c: Clean up inclusions. - * main.c (main): Check for WINGDB, not WIN32. - * printcmd.c (do_examine): Put QUIT test in loop. - * remote-hms.c (e7000_load): Delete. - (hms_ops): Point to generic_load instead. - * remote-hms.c (hms_ops): Point to generic_load. - * remote-sim.c (sim_callback_write_stdout): Becomes - gdbsim_write_stdout. - (gdbsim_load): Call generic_load. - * remote-utils.c (gr_load_image): Delete. - * ser-unix.c (terminal.h): Include instead of havig - own #if tree. - (hardwire_flush_input): Reset input buffer too. - * source.c (openp): If WIN32 then open file in binary mode. - * terminal.h: Configure IO mechanism using autoconf defines if - available and not overriden. - * utils.c (quit, pollquit, notice_quit): WIN32 check becomes - WINGDB check. - - * config/arm/arm.mt (TDEPFILES): Add remote-rdp.o. - * config/arm/tm-arm.h (TARGET_BYTE_ORDER): becomes - TARGET_BYTE_ORDER_SELECTABLE. - (ADDR_BITS_REMOVE): New. - (ORIGINAL_REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): New. - (INST_xx): New. - (FRAME_FIND_SAVED_REGS): Pass the right argument. - (arm_get_next_pc): Declare. - -Wed Sep 27 10:14:36 1995 Per Bothner - - * valops.c (search_struct_field): Also allow "else" as a variant - name. - * eval.c (evaluate_struct_tuple): New function. Used to evaluate - structure tuples. Now also handles Chill variant records. - (get_label): New function, used by evaluate_struct_tuple. - (evaluate_subexp_standard case OP_ARRAY): Use evaluate_struct_tuple. - (evaluate_labeled_field_init): Removed. - - * valops.c (search_struct_field): Generalize to work with Chill - variant records. - -Sat Sep 23 01:22:23 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_partial_symbols): Reset includes_used - and dependencies_used after finishing the partial symbol table. - - * rs6000-tdep.c (push_dummy_frame): Handle lr_offset of zero - correctly. - - * rs6000-nat.c (xcoff_relocate_core): Don't relocate data - addresses for the main objfile if DONT_RELOCATE_SYMFILE_OBJFILE - is defined. - * xcoffread.c: gcc -Wall lint. Remove traceback table reading - code. The existing code tried to add parameter information for - functions compiled without -g, which cannot be done properly - for optimized code and produced misleading parameter displays. - (ef_complaint, eb_complaint): Make a local static copy to avoid - dependency on coffread.c. - (read_xcoff_symtab, process_xcoff_symbol, scan_xcoff_symtab): - Enter C_EXT/C_HIDEXT symbols into the minimal symbol table only. - (read_xcoff_symtab): Ignore C_STAT section auxiliary entry - symbols. Complain about unmatched .ef and .eb symbols instead of - segfaulting. - (process_xcoff_symbol): Determine value of C_GSYM symbols via - the global_sym_chain mechanism in stabsread.c. - (xcoff_new_init): Call stabsread_new_init and buildsym_new_init. - (init_string_tab): Initialize length field bytes in the strtbl. - (scan_xcoff_symtab): Skip symbols that start with `$' or `.$'. - Set first_fun_line_offset for symbols with two auxents only. - -Wed Sep 20 21:06:35 1995 Jeff Law (law@snake.cs.utah.edu) - - * op50-rom.c (op50n_cmds): Send ".\r" after the interrupt - character. - -Wed Sep 20 13:12:56 1995 Ian Lance Taylor - - * Makefile.in (maintainer-clean): New target, synonym for - realclean. Add GNU standard maintainer-clean echos. - * gdbserver/Makefile.in (maintainer-clean): New target, synonym - for realclean. - * nlm/Makefile.in (maintainer-clean): Likewise. - -Wed Sep 20 08:16:03 1995 steve chamberlain - - * defs.h (xmalloc, xrealloc): Delete, they're declared in libiberty.h. - (GETENV_PROVIDED, FCLOSE_PROVIDED): New. - * doc/gdbint.texinfo (GETENV_PROVIDED, FCLOSE_PROVIDED): Document. - * remote-sim.[ch] (sim_callback_write_stdout): New. - -Tue Sep 19 15:28:58 1995 Per Bothner - - * gdbtypes.c (create_set_type): Set TYPE_LENGTH in bytes, not bits. - * valops.c (value_bitstring): TYPE_LENGTH is bytes, not bits. - - * gdbtypes.c (force_to_range_type): Calculate upper limit of - TYPE_CODE_CHAR depending on TYPE_LENGTH (instead of just using 255). - -Mon Sep 18 01:43:42 1995 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c (auto_solib_add_at_startup): Delete definition. No - longer needed. - -Sat Sep 16 13:23:36 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/tm-mips.h (UNUSED_REGNUM): Define. - * mipsv4-nat.c (supply_gregset): Fill UNUSED_REGNUM register - with zero. - -Thu Sep 14 17:35:24 1995 Stu Grossman (grossman@cygnus.com) - - * remote-sim.c (gdbsim_create_inferior): Back out change that - broke all simulator configurations except the rs6000. - -Thu Sep 14 14:44:59 1995 Jeffrey A. Law - - * monitor.c (monitor_expect): Discard NULL characters. - -Thu Sep 14 14:12:30 1995 Kung Hsu - - * infcmd.c: Add extern declaration for auto_solib_add_at_startup. - -Wed Sep 13 13:33:58 1995 Kung Hsu - - * symfile.c: Move global variable auto_solib_add_at_startup from - solib.c to symfile.c. - * solib.c: ditto. - * symfile.h: Add extern declaration of the above mentioned variable. - * infcmd.c: Take out extern declaration, since it's in symfile.h. - -Thu Sep 14 12:39:35 1995 Stu Grossman (grossman@cygnus.com) - - * coffread.c (coff_symtab_read): Complain about unmatched .ef and - .eb symbols instead of segfaulting. - -Wed Sep 13 13:33:58 1995 Kung Hsu - - * stabsread.c (read_one_struct_field): Use subfile language instead of - global language. Improve efficiency. - -Wed Sep 13 08:45:02 1995 Jeff Law (law@fast.cs.utah.edu) - - * somsolib.c (auto_solib_add_at_startup): Define new global variable. - (som_solib_create_inferior_hook): Don't add libraries if - auto_solib_add_at_startup is zero. - (_initialize_som_solib): Add command to toggle - auto_solib_add_at_startup. - -Tue Sep 12 19:37:24 1995 Jeff Law (law@snake.cs.utah.edu) - - * monitor.c (monitor_make_srec): Fix thinkos in computation - of addr_size. - -Tue Sep 12 15:46:18 1995 Kung Hsu - - * stabsread.c (read_one_struct_field): Add a patch to handle cfront - generated stabs that each field is in full mangled name. - - * stabsread.c: To include language.h and expression.h for the reason - above. - - * infcmd.c (attach_command): Add solibs only when - auto_solib_add_at_startup is set. - -Mon Sep 11 17:22:35 1995 Fred Fish - - * NEWS: Add information about remote target caching. - -Sun Sep 10 15:36:21 1995 Fred Fish - - * defs.h: Only include mmalloc.h if NO_MMALLOC is not - defined. - -Sun Sep 10 10:24:48 1995 Michael Tiemann - - * tm-ppc-eabi.h (PC_IN_CALL_DUMMY): Redefine this to work with the - simulator. FIXME. - - * rs6000-tdep.c (push_dummy_frame): Calculate the correct link - register offset from the current frame (don't assume it is always 8). - (push_dummy_frame): Add comment about having only 4096 bytes of - stack space in the simulator (by default). - - * remote-sim.c (gdbsim_create_inferior): Call - `add_text_to_loadinfo' so that gdb can find TOC entries when - calling functions in the inferior. - -Sun Sep 10 09:00:28 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * sparc-tdep.c (fill_fpregset): Fix incorrect FP_MAX_REGNUM - substitution. - (supply_fpregset): Use FP_MAX_REGNUM. - -Sat Sep 9 08:21:52 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * stabsread.c (read_enum_type): Exit loop for putting pending - enum symbols into the enum type correctly if we had no pending - symbols on entry to read_enum_type. - -Fri Sep 8 12:57:41 1995 Kung Hsu - - * inferior.h: Add extern declaration of inferior_environ. - * solib.c (solib_map_sections): To get inferior's env instead of - gdb's for LD_LIBRARY_PATH, same for PATH. - - * solib.c (solib_map_sections): Copy full path name into so_list - structure so that symbol_file_add can find it. - -Tue Sep 5 17:47:53 1995 Doug Evans - - * config/sparc/tm-sp64.h (REGISTER_RAW_SIZE): Lower 32 fp regs - have size 4. - (REGISTER_VIRTUAL_SIZE): Likewise. - (REGISTER_VIRTUAL_TYPE): Lower 32 fp regs have type float. - Upper 32 fp regs have type double. - * sparc-tdep.c (NUM_SPARC_FPREGS): Replace with - (FP_REGISTER_BYTES): this, and update all uses. - (FP_MAX_REGNUM): Define if not already. - (get_saved_register): Handle new sparc64 fp regs. - (sparc_frame_find_saved_regs): Likewise. - (sparc_print_register_hook): Only print fp regs < 32 as doubles. - Add code to handle long doubles when gdb does. - (_initialize_sparc_tdep): Use print_insn_sparc64 if sparc64. - -Sat Sep 2 06:41:26 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * configure.in: Explicitly `exit 0' for broken shells. - * configure: Rebuilt. - - * symtab.c (list_symbols): Add missing blank after - `' output. - - * valops.c (value_assign): Handle truncation when assigning - to bitfields. Use value_copy to construct the return value - from toval. - * values.c (value_copy): Copy VALUE_FRAME and VALUE_OPTIMIZED_OUT. - -Fri Sep 1 08:25:50 1995 James G. Smith - - * configure (mips64*vr4300*-*-elf): Support added. - * remote-mips.c (mips_readchar): Change to allow build-time prompt - string. - * config/mips/tm-mips.h: Added TARGET_MONITOR_PROMPT. - * config/mips/{vr4300.mt, vr4300el.mt, tm-vr4300.h, - tm-vr4300el.h}: Added. - -Thu Aug 31 12:48:04 1995 Jim Wilson - - * config/sh/sh.mt (SIM): Add -lm. - -Wed Aug 30 18:10:57 1995 Kung Hsu - - * rmote-nindy.c (non_dle, nidy_resume, nindy_wait): Changes to - conform to GNU coding standards. - - * solib.c (match_main): Modify to follow GNU coding conventions. - -Mon Aug 28 17:07:26 1995 Kung Hsu - - * remote.c (remote_wait): Revert 19 July my change which should be - customer specific. - -Sat Aug 26 00:26:11 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_symbol): Handle sh.value of zero for enums. - Determine signedness of enum type from enumerators. - (parse_type): Handle btIndirect types, handle fBitfield for - some non-member types. - (upgrade_type): Use TYPE_FLAG_TARGET_STUB for arrays with - unknown length. - (cross_ref): Handle stIndirect forward reference to btTypedef. - - * stabsread.c (read_enum_type): Determine signedness of enum - type from enumerators. - - * top.c (execute_command): Remove trailing whitespace from - command arguments, except for `set' and `complete' commands. - (validate_comname): Allow underscores in user defined command - names. - - * values.c (modify_field): Change `Value does not fit in %d bits' - error to a warning. Exclude sign extension bits of negative field - values from fit check. - -Fri Aug 25 11:31:29 1995 Michael Meissner - - * configure.in (powerpc*-*-eabisim*): Only link in the simulator - if the target is powerpc{,le}-*-eabisim*, since the simulator - needs GCC to build. - * config/powerpc/ppc{,le}-sim.mt: Cloned from ppc{,le}-eabi.mt. - * config/powerpc/ppc{,le}-eabi.mt: Remove simulator support. - * config/powerpc/tm-ppc{,le}-sim.mt: Include tm-ppc{,le}-sim.h. - -Wed Aug 23 16:55:35 1995 Michael Meissner - - * config/powerpc/ppc{,le}-eabi.mt (SIM_OBJS, SIM): Link in the - PowerPC simulator. - -Tue Aug 22 02:00:47 1995 Jeff Law (law@snake.cs.utah.edu) - - * tm-hppa.h (EXTRACT_RETURN_VALUE): Fix for FP values. - - * tm-hppa.h (STORE_RETURN_VALUE): Fix to work with -msoft-float - calling conventions too. Use the TYPE of the return value, not - its length to determine if it should also be copied into the - floating point registers. - - * tm-hppa.h (PROLOGUE_FIRSTLINE_OVERLAP): Delete. Causes more - problems than it fixes. - * hppa-tdep.c (skip_prologue): If we exit the main loop without - finding all the register saves, retry again without looking for - the registers we could not find the first time. - -Mon Aug 21 23:39:56 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (frame_chain_valid): Handle systems where "$START$" - calls "main" directly. - (skip_prologue): Always assume arguments were saved into the stack - since GCC will do so without setting the magic Args_Saved bit in - the unwind descriptor. - -Mon Aug 21 11:49:17 1995 Kung Hsu - - * remote-udi.c (udi_wait): Mask off high bits of stop reason. - * remote-udi.c (fetch_register): For unfetchable regs, pretend it's - done. Fix a bug. - -Mon Aug 21 00:45:17 1995 Jeff Law (law@snake.cs.utah.edu) - - * Makefile.in (install): Remove "brokensed" hack, unnecessary now - that we're using autoconf. - (uninstall): Likewise. - - -Sat Aug 19 01:19:34 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * gdbtypes.c (recursive_dump_type): Add dont_print_type_obstack - to inhibit infinite recursion when printing aggregate types. - -Fri Aug 18 17:48:55 1995 steve chamberlain - - * dcache.c (dcache_write_line): Write dirty lines right. - -Fri Aug 18 06:26:56 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * sparc-tdep.c (isbranch): Fix typo which caused wrong - target addresses for annulled branches. - -Wed Aug 16 21:54:39 1995 Jeff Law (law@snake.cs.utah.edu) - - * config/pa/tm-hppa.h (PROLOGUE_FIRSTLINE_OVERLAP): Define. - -Tue Aug 15 07:51:21 1995 steve chamberlain - - * remote.c (remote_write_bytes): Chop up large transfers. - -Mon Aug 14 17:56:36 1995 Stan Shebs - - * gcc.patch: Remove, relevant only to long-ago versions of GCC. - -Mon Aug 14 13:43:01 1995 Kung Hsu - - * config/sparc/tm-sparclite.h: Define FRAME_CHAIN_VALID_ALTERNATE. - * blockframe.c (inside_main_func): If main func addr range not set, - try to set it now. - -Sat Aug 12 15:34:54 1995 Jeffrey A. Law - - * config/powerpc/xm-aix.h (FIVE_ARG_PTRACE): Define. - * config/rs6000/xm-rs6000.h (FIVE_ARG_PTRACE): Likewise. - - * configure.in: Recognize aix4 specially as some aspects - of aix4 need different handling than aix3. - * configure: Updated. - * config/powerpc/{aix4.mh,aix4.mt,tm-ppc-aix4.h}: New files - specific to aix4 support on the power pc. - * config/powerpc/tm-ppc-aix.h (DONT_RELOCATE_SYMFILE_OBJFILE): Do - not defined. The aix4 specific target files will do that. - * config/rs6000/{aix4,mh,aix4,mt,tm-rs6000-aix4.h}: New files - specific to aix4 support on the rs6000. - - * config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR): Don't - do the conversion if the pointer is not a magic aix function - pointer. - * rs6000-tdep.c: Include objfiles.h and symtab.h. - (is_magic_function_pointer): New function. - - * rs6000-tdep.c (skip_prologue): Refine check for frameless - functions. Handle b .+4 emitted by aix4 compilers. Only - allow one load of a minimal toc pointer. Handle aix4 compiler's - code for alloca. - - * rs6000-tdep.c (find_toc_address): Report an error if no toc was - found rather than possibly core dumping. - - * partial-stab.h: Handle extra field generated by the aix4 compiler - for enumerations. - * stabsread.c (read_enum_type): Likewise. - -Sat Aug 12 03:18:04 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * rs6000-tdep.c (extract_return_value): Fix returning of values - whose length is less than the register size for big endian targets. - -Fri Aug 11 13:04:32 1995 Kung Hsu - - * symtab.c (list_symbols): if break command set breakpoint on - matched symbol. - -Wed Aug 9 18:59:05 1995 Fred Fish - - * defs.h (strchr, strrchr, strstr, strtok, strerror): Enclose in - #ifndefs to protect against previous definitions as macros. - -Wed Aug 9 14:51:36 1995 Kung Hsu - - * xcoffread.c (xcoff_symfile_offset): Revert an unwanted change - that got in accidentally with Aug 1 change. - -Sat Aug 5 09:07:28 1995 steve chamberlain - - * remote-hms.c (hms_cmds): Get reg term right. - * monitor.c (monitor_fetch_register): If we see - a non-hex digit, just stop reading. - * remote.c (remote_wait): Change way $O is handled. - -Wed Aug 9 11:42:36 1995 Jeffrey A. Law - - * configure.in (powerpc-*-aix*): Recognize as a new gdb host - and target. - (powerpc-*-eabi*): Don't set configdirs. - (powerpcle-*-eabi*): Likewise. - * configure: Updated. - * rs6000-nat.c (vmap_ldinfo): Don't relocate data addresses - for the main objfile if DONT_RELOCATE_SYMFILE_OBJFILE is - defined. - * config/powerpc/{aix.mh,aix.mh}: Host and target makefile fragments - for powerpc running aix4. - * config/powerpc/{nm-aix.h, tm-ppc-aix.h, xm-aix.h}: Native, target - and host include files for powerpc running aix4. - -Wed Aug 9 08:11:45 1995 Stan Shebs - - * top.c (target_output_hook): Really make it match defs.h (char * - is not the same as unsigned char *). - -Tue Aug 8 15:13:05 1995 J.T. Conklin - - * Makefile.in (CXX_FOR_TARGET): Don't use ${rootme}/../gcc/xgcc - unless it is present. - -Tue Aug 8 10:50:15 1995 Jeffrey A. Law - - * top.c (target_output_hook): Make declaration match the one - in defs.h. - - * symfile.c (add_psymbol_to_list): Initialize SYMBOL_SECTION. - (add_psymbol_addr_to_list): Likewise. - * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Likewise. - -Mon Aug 7 15:34:29 1995 steve chamberlain - - * top.c (target_output_hook): New definition. - * stack.c (gdb_string.h): Include after defs.h - * defs.h (target_output_hook): New declaration. - * source.c (mod_path): Fix Win32 \ handling. - -Sun Aug 6 22:14:25 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (frame_saved_pc): Don't try to dig a return pointer - out of a long branch stub. - -Fri Aug 4 13:37:31 1995 Jeffrey A. Law - - * xcoffread.c (process_linenos): Fix typo in last change. - -Thu Aug 3 22:01:26 1995 Fred Fish - - * ch-exp.y (write_lower_upper_value): Add prototype so bison - generated parser will insert prototype before first func usage. - Bison and byacc order the output sections differently. Also - make function static. - -Thu Aug 3 10:45:37 1995 Fred Fish - - * Update all FSF addresses except those in COPYING* files. - -Thu Aug 3 01:38:45 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/alpha/tm-alpha.h (EXTRA_FRAME_INFO): Add pc_reg field. - (SKIP_TRAMPOLINE_CODE): Define. - * alpha-tdep.c (alpha_frame_saved_pc): Use pc_reg field from - frame to find the saved pc register. - (alpha_saved_pc_after_call): Skip over shared library trampoline - before trying to find the saved pc register. - (find_proc_desc): Copy PROC_PC_REG from found proc_desc - to heuristic proc_desc. - (init_extra_frame_info): Initialize pc_reg field in frame. - -Wed Aug 2 18:00:36 1995 Stan Shebs - - * configure.in (m68*-est-*): Use monitor target config. - * configure: Update. - * config/m68k/est.mt, config/m68k/tm-est.h: Delete. - * config/m68k/monitor.mt, config/m68k/tm-monitor.h: Fix comments. - -Tue Aug 1 22:52:53 1995 Fred Fish - - * Makefile.in (VERSION): Bump to 4.14.2 - -Tue Aug 1 16:04:36 1995 Kung Hsu - - * xcoffread.c (process_linenos): The value in include file symbol - should point to line number table. Currently this value is not - set correctly by AIX ld. A fix to get around this bug. - -Tue Aug 1 11:44:53 1995 J.T. Conklin - - * configure.in: Check for working mmap, ansi headers, string.h, - strings.h, and memory.h. - * configure: Regenerated. - - * gdb_stat.h: New file, "portable" . - * gdb_string.h: New file, "portable" . - - * altos-xdep.c, arm-tdep.c, arm-xdep.c, convex-tdep.c, - convex-xdep.c, coredep.c, cxux-nat.c, dbxread.c, exec.c, - gould-xdep.c, hppa-tdep.c, i386aix-nat.c, i386b-nat.c, - i386mach-nat.c, i386v-nat.c, infptrace.c, m88k-nat.c, main.c, - mdebugread.c, objfiles.c, os9kread.c, procfs.c, pyr-xdep.c, - rs6000-nat.c, source.c, standalone.c, stuff.c, sun386-nat.c, - symfile.c, symm-nat.c, symm-tdep.c, symtab.c, top.c, ultra3-nat.c, - ultra3-xdep.c, umax-xdep.c, xcoffread.c: Include "gdb_stat.h" - instead of . - - * alpha-tdep.c, breakpoint.c, buildsym.c, c-typeprint.c, - ch-typeprint.c, coffread.c, command.c, core-sol2.c, core-svr4.c, - core.c, corelow.c, cp-valprint.c, dbxread.c, dcache.c, demangle.c, - dpx2-nat.c, dstread.c, dwarfread.c, elfread.c, environ.c, eval.c, - exec.c, f-lang.c, f-typeprint.c, f-valprint.c, findvar.c, - fork-child.c, gdbtypes.c, hpread.c, i386-tdep.c, infcmd.c, - inflow.c, infptrace.c, infrun.c, irix5-nat.c, language.c, - m2-typeprint.c, main.c, mdebugread.c, minsyms.c, mipsread.c, - monitor.c, nlmread.c, objfiles.c, os9kread.c, osfsolib.c, parse.c, - printcmd.c, procfs.c, regex.c, remote-adapt.c, - remote-array.c, remote-bug.c, remote-e7000.c, remote-eb.c, - remote-es.c, remote-hms.c, remote-mm.c, remote-os9k.c, - remote-pa.c, remote-sim.c, remote-st.c, remote-udi.c, - remote-utils.c, remote-vx.c, remote-vx29k.c, remote-vx68.c, - remote-vx960.c, remote-vxmips.c, remote-vxsparc.c, remote.c, - solib.c, somread.c, source.c, stabsread.c, stack.c, symfile.c, - symmisc.c, symtab.c, target.c, top.c, typeprint.c, utils.c, - valarith.c, valops.c, valprint.c, values.c, xcoffread.c: Include - "gdb_string.h" instead of . - - * config/xm-sysv4.h, i386/xm-ptx.h, m68k/xm-sun3os4.h, - sparc/xm-sun4os4.h (HAVE_MMAP): Removed. - - * config/xm-lynx.h, config/i386/xm-ptx.h, - config/m68k/nm-apollo68b.h, config/m68k/xm-hp300hpux.h, - config/mips/xm-irix3.h, config/mips/xm-mips.h, - config/mips/xm-news-mips.h, config/mips/xm-riscos.h, - config/pa/hppah.h, config/rs6000/xm-rs6000.h, - config/sparc/xm-sun4os4.h, config/sparc/xm-sun4sol2.h, - config/vax/xm-vaxbsd.h, config/vax/xm-vaxult.h, - config/vax/xm-vaxult2.h (MEM_FNS_DECLARED): Removed. - * config/mips/xm-irix3.h, config/mips/xm-mips.h, - config/pa/xm-hppah.h (memcpy, memset): Removed declarations. - -Tue Aug 1 02:08:30 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-tdep.c (mips_extract_return_value): Fix returning of - values whose length is less than the register size for big endian - targets. - * alpha-tdep.c (alpha_extract_return_value, - alpha_store_return_value): Use alpha_convert_register_to_* - to handle functions returning "float" correctly. - -Mon Jul 31 19:12:48 1995 Stan Shebs - - * h8500-tdep.c: General linting and cleanup. - (opcodes/h8500-opc.h): Don't include. - (code_size, data_size): Make static. - (frame_locals_address, frame_args_address): Remove. - (h8300_pop_frame): Rename to h8500_pop_frame. - (big_command, medium_command, compact_command, small_command): - Define as regular functions rather than with macro trickery. - (tm_print_insn): Set to correct disassembler function. - * config/h8500/tm-h8500.h: Minor cleanup, add prototypes. - (ABOUT_TO_RETURN): #if 0 out. - (FRAME_ARGS_ADDRESS, FRAME_LOCALS_ADDRESS): Use usual define. - (GDB_TARGET_IS_H8500): Remove duplicate definition. - (regoff): Remove, never used. - * config/h8500/h8500.mt (TDEPFILES): Add monitor.o. - -Mon Jul 31 14:32:30 1995 J.T. Conklin - - * configure.in: Check for unistd.h. - * configure: Regenerated. - - * command.c, cp-valprint.c, fork-child.c, i386-tdep.c, - i386b-nat.c, inflow.c, main.c, maint.c, objfiles.c, solib.c, - source.c, stack.c, symfile.c, top.c, utils.c: Include strings.h - and/or unistd.h to bring prototypes into scope. - -Sun Jul 30 01:40:11 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * rs6000-tdep.c (frame_saved_pc): Check for signal handler caller - before trying to determine the start of the function. - (skip_prologue): Skip subroutine call which might save the - floating point registers only if it is within the first three - instructions. - Reinstate setting of alloca_reg if setup of a gcc frame pointer - is found. - (frame_get_cache_fsr): Use new fields in rs6000_framedata. - -Sat Jul 29 14:43:35 1995 Stan Shebs - - * sparclite: Removed subdirectory. aload and eload are now in - utils/sparclite, low-level library is in libgloss. - * configure.in (sparclite*): Don't configure sparclite subdir. - * configure: Update. - * Makefile.in (TARDIRS): Remove, no longer used. - -Sat Jul 29 01:45:56 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * procfs.c (unconditionally_kill_inferior): Clear current signal - if PROCFS_NEED_CLEAR_CURSIG_FOR_KILL is defined. - * config/alpha/nm-osf3.h (PROCFS_NEED_CLEAR_CURSIG_FOR_KILL): Define. - - * alpha-tdep.c: Move sigtramp handling of saved registers from - read_next_frame_reg to alpha_find_saved_regs, handle saved - floating point registers. - * mips-tdep.c: Move sigtramp handling of saved registers from - read_next_frame_reg to mips_find_saved_regs, handle saved - floating point registers. - * config/mips/tm-irix3.h, config/mips/tm-irix5.h, - config/mips/tm-mipsv4.h (SIGFRAME_FPREGSAVE_OFF): Define. - - * sparc-tdep.c (sparc_pc_adjust): Fix check for `unimp' - instruction to handle functions returning structures with - large sizes properly. - -Fri Jul 28 11:50:17 1995 steve chamberlain - - * configure, configure.in (z8k-*-sim): deleted. - -Thu Jul 27 12:49:28 1995 Jeffrey A. Law - - * lynx-nat.c (child_wait): Handle threads exiting. - -Thu Jul 27 07:47:50 1995 Michael Meissner - - * rs6000-tdep.c (skip_prologue): Don't assume the update stack - instruction is the last in the prologue, since xlc stores the lr - after the stack update. Make sure offset is correct sign for - large frames. - (frame_saved_pc): Move test for signal before frameless. - - * config/rs6000/tm-rs6000.h (DEFAULT_LR_SAVE): Define. - * config/powerpc/tm-ppc-eabi.h (DEFAULT_LR_SAVE): Redefine. - -Thu Jul 27 01:22:08 1995 Jeffrey A. Law - - * hppa-tdep.c (hppa_fix_call_dummy): Rewrite code for calling - into shared libraries. - -Wed Jul 26 23:33:34 1995 Michael Meissner - - * config/rs6000/tm-rs6000.h (rs6000_framedata): Add offsets the - gprs, fprs, lr, and cr is stored at. - (FRAME_FIND_SAVED_REGS): Use new fields in rs6000_framedata. - (function_frame_info): Delete declaration. - (SKIP_PROLOGUE): Skip_prologue is now passed a rs6000_framedata - structure to fill in. - (FRAMELESS_FUNCTION_INVOCATION): Function now longer takes a - second argument. - (FRAME_SAVED_PC): Call frame_saved_pc. - - * rs6000-tdep.c (skip_prologue): Recognize V.4 prologues as well - as AIX style. Fill in rs6000_framedata structure. Remember where - the gprs, fprs, cr, and lr are saved. - (pop_frame): Use skip_prologue, not function_frame_info, and use - new rs6000_framedata fields. - (function_frame_info): Function deleted. - (frameless_function_invocation): Separate frame_saved_pc support - to new function. Recognize V.4 frames. - (frame_saved_pc): New function. - (frame_get_cache_fsr): Use skip_prologue, not function_frame_info. - (frame_initial_stack_address): Ditto. - -Wed Jul 26 01:00:37 1995 Jeff Law (law@snake.cs.utah.edu) - - * remote.c: Add documentation for extended protocol operations - and for thread_alive change from a couple weeks ago. - (extended_remote_ops): Declare and define a new target vector - for the extended remote protocol. - (extended_remote_restart): New function to restart the remote - server & process. - (remote_open): Just a stub routine. - (extended_remote_open): New function to start a remote session - using the extended gdb remote protocol. - (remote_open_1): New function containing code common to both - remote_open and extended_remote_open. - (remote_mourn, extended_remote_mourn, remote_mourn_1): Similarly. - (extended_remote_create_inferior): New function for the extended - remote target. - (initialize_remote): Add the extended_remote_ops target vector. - * gdbserver/server.c (main, case '!'): Set extended_protocol. - (main, case 'k'): If the extended protocol is in use, kill the - inferior then start a new one. - (main, case 'R'): New command to restart the remote server and - inferior process. Only supported when using the extended - protocol. - (main, server loop): If the inferior terminates while using the - extended protocol then start a new one. If getpkt fails when - using the extended protocol then exit. - -Tue Jul 25 11:43:44 1995 Stan Shebs - - * mdebugread.c (psymtab_to_symtab_1): Relocate encoded stab - line numbers using the psymtab's section offsets. - -Tue Jul 25 10:43:27 1995 Michael Meissner - - * config/rs6000/tm-rs6000.h (rs6000_framedata): Rename from - aix_framedata. Change all uses. - * rs6000-tdep.c: Change all aix_framedata -> rs6000_framedata. - -Sat Jul 22 23:44:18 1995 Jeff Law (law@snake.cs.utah.edu) - - * defs.h (ATTR_FORMAT): Disable if ANSI_PROTOTYPES is not defined. - -Fri Jul 21 16:50:28 1995 Jeffrey A. Law - - * lynx-nat.c (child_thread_alive): New function. Somehow I - forgot to check this in with all the other thread_alive changes. - -Thu Jul 20 22:22:34 1995 Jeff Law (law@snake.cs.utah.edu) - - * somread.c (som_symtab_read): Add unsatisfied common symbols to - the minimal symbol table. All common symbols are "unsatisfied" - when -E is passed to the linker. - -Thu Jul 20 15:04:57 1995 Fred Fish - - * top.c (show_endian): Cast first arg of printf_unfiltered to - correct type of "char *". - -Thu Jul 20 14:18:51 1995 Jeffrey A. Law - - * lynx-nat.c (child_wait): A thread_id of zero from wait apparently - means the process is single threaded, so there's no need to add - it to the thread list. Handle case where multi-threaded process - reverts back to a single-threaded process. - - * gdbserver/low-hppabsd.c: Remove error declaration. - * gdbserver/low-sparc.c: Likewise. - * gdbserver/low-sun3.c: Likewise. - * gdbserver/server.h: Remove error and fatal declaration. - * gdbserver/utils.c (error): Update to be compatable with recent - changes in defs.h. - (fatal): Likewise. - -Wed Jul 19 22:42:43 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/m68k/tm-m68kv4.h (DWARF_REG_TO_REGNUM): Define to - correctly map floating point registers numbers. - - * dwarfread.c (locval, new_symbol): Handle variables that are - optimized out. - - * mdebugread.c: Replace all uses of builtin_type_* with - mdebug_type_*. Define and initialize mdebug_type_*. - - * serial.h (serial_close): Add additional argument `really_close'. - (SERIAL_CLOSE): Update serial_close call accordingly. - (SERIAL_UN_FDOPEN): Use serial_close to handle refcnt properly. - * serial.c (serial_close): Handle `really_close'. - * serial.h (scb_base): Moved to serial.c, made static. - - * valops.c (value_addr): Don't coerce arrays. - (typecmp): Coerce arrays instead of calling value_addr if necessary. - -Wed Jul 19 18:19:28 1995 Stan Shebs - - From Richard Earnshaw (rearnsha@armltd.co.uk): - * infrun.c (wait_for_inferior): Set the convenience variable - $_exitcode to the termination code of the inferior. - * top.c (quit_command): Accept optional expression to use - as parameter to exit(). - -Wed Jul 19 13:15:32 1995 Kung Hsu - - * remote.c (remote_wait): When getting registers, check endianess and - do conversion if necessary. - -Tue Jul 18 00:41:31 1995 Jeff Law (law@snake.cs.utah.edu) - - * gdbserver/low-hppabsd.c: New file. - * gdbserver/Makefile.in (SFILES): Add low-hppabsd.c. - * config/pa/hppabsd.mh (XDEPFILES): Add ser-tcp.o. - (GDBSERVER_DEPFILES): Add low-hppabsd.o. - * config/pa/hppaosf.mh: Likewise. - -Mon Jul 17 21:35:18 1995 Fred Fish - - * dache.c (struct dcache_block): Change data member from unsigned - char to char, since everything passed in and out of dcache is char - or casted to appropriate type anyway. - (dcache_alloc): Move assignment of db out of test and combine - separate tests into if-else. - (dcache_peek_byte): Change ptr from unsigned char* to char*. - (dcache_peek_byte): Remove now unnecessary cast in read_memory call. - (dcache_peek): Change cast of incoming data arg. - (dcache_poke): Change cast of addr of incoming data arg. - (dcache_info): Mask data passed to printf_filtered to lsbyte only. - (dcache_info): Change printf_filtered arg from "% 2x" to " %2x". - * target.c (debug_to_thread_alive): Change return type to int and - return zero, for type compatibility with other *_thread_alive - funcs. - (cleanup_target): Change cast of ignore function to match type of the - to_thread_alive member. - * defs.h (error_hook): Add ATTR_NORETURN. - * defs.h (NORETURN, ATTR_NORETURN): Switch from volatile to - __attribute__ method with gcc 2.7, to avoid gcc 2.6.3 bug. - * remote.c (remote_wait): Cast first arg to strtol, strchr, and - strncmp to "const char *" from "unsigned char *". - (remote_wait): Cast arg to putpkt and strcpy from "unsigned char *" - to "char *". - (remote_wait): Change printf format for long arg from "%d" to "%ld". - (getpkt): Remove unused variable "bp". - (remote_fetch_word, remote_store_word): Ifdef out apparently unused - functions. - * breakpoint.c (watchpoint_check): Removed unused variables - "saved_level" and "saved_frame". - * valops.c (value_arg_coerce): Add other enum TYPE_CODE_* and - default cases to switch for completeness. - * infrun.c (wait_for_inferior): Enclose "have_waited" label - in #ifdef that matches the one in which it is referenced. - * ser-unix.c (hardwire_noflush_set_tty_state): Enclose otherwise - unused variable "state" in #ifdef that matches one in which it is - referenced. - * eval.c (evaluate_subexp_standard): Remove unused variable "var". - * eval.c (evaluate_subexp_standard): Remove unused variable - "tmp_symbol". - * valarith.c (value_subscript): Remove unused variable - "lowerbound", which is redeclared in a nested scope prior to use. - * printcmd.c (print_frame_nameless_args): Use "%ld" to print long - arg, not "%d". - * {mem-break.c, remote-pa.c, remote.c, saber.suppress}: - Remove unused static var "check_break_insn_size". - * buildsym.c (finish_block): Add other enum LOC_* and default - cases to switch for completeness. - ch-lang.c (type_lower_upper): Removed unused label "retry". - Add other enum TYPE_* and default cases to switch for completeness. - * f-typeprint.c (f_type_print_args): Ifdef out unused function - that may be used someday when Fortran support is complete. - * ch-valprint.c (chill_print_type_scalar): Add other enum - TYPE_* and default cases to switch for completeness. - (chill_val_print): Remove unused local var "high_bound" that - is redeclared in a nested scope prior to use. - (chill_var_print): Use "%ld" to print long arg, not "%d". - * regex.c (re_compile_fastmap, re_match_2): Add remaining enum - types and default to switches for completeness. - * minsyms.c (lookup_minimal_symbol_text): Delete unused variable - "trampoline_symbol". - (prim_record_minimal_symbol_and_info): Return NULL rather than - trash. - * elfread.c (elf_symtab_read): Don't dereference NULL returns from - record_minimal_symbol_and_info. - * f-lang.c (saved_function_list_end): Ifdef out unused variable - that may be used someday. - * f-valprint.c (f_val_print): Remove unused local "straddr". - -Mon Jul 17 13:08:00 1995 Ian Lance Taylor - - * stabsread.h (struct stab_section_list): Define. - (coffstab_build_psymtabs): Remove staboff and stabsize parameters. - Add textaddr, textsize, and stabs parameters. - * gdb-stabs.h (struct dbx_symfile_info): Remove text_sect field. - Add text_addr and text_size fields. - (DBX_TEXT_SECT): Don't define. - (DBX_TEXT_ADDR, DBX_TEXT_SIZE): Define. - * coffread.c: Include . - (struct coff_symfile_info): Remove stabsect and stabindexsect - fields. Add textaddr, textsize, and stabsects fields. - (coff_locate_sections): Record the address of the .text section, - and total the sizes of all sections with names beginning with - ".text". Don't bother to record a .stab.index section (COFF - doesn't use them). Make a linked list of all sections with names - beginning with ".stab". - (coff_symfile_read): Adjust call to coffstab_build_psymtabs for - new parameters. - * dbxread.c (dbx_symfile_read): Use DBX_TEXT_ADDR and - DBX_TEXT_SIZE, rather than getting both from DBX_TEXT_SECT. - (dbx_symfile_init): Set DBX_TEXT_ADDR and DBX_TEXT_SIZE, not - DBX_TEXT_SECT. - (elfstab_build_psymtabs): Likewise. - (stabsect_build_psymtabs): Likewise. - (symbuf_sections, symbuf_left, symbuf_read): New static variables. - (fill_symbuf): If symbuf_sections is not NULL, read symbols from - multiple sections. - (coffstab_build_psymtabs): Remove staboffset and stabsize - parameters. Add textaddr, textsize, and stabsects parameters. - Set DBX_TEXT_ADDR and DBX_TEXT_SIZE, not DBX_TEXT_SECT. Handle - multiple stabs sections. - * os9kread.c (os9k_symfile_read): Use DBX_TEXT_ADDR and - DBX_TEXT_SIZE, rather than getting both from DBX_TEXT_SECT. - (os9k_symfile_init): Set DBX_TEXT_ADDR and DBX_TEXT_SIZE, not - DBX_TEXT_SECT. - - * remote-vx.c (vx_ops, vx_run_ops): Initialize new to_thread_alive - field. - -Sat Jul 15 01:02:53 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/alpha/alpha-osf3.mh, config/alpha/nm-osf3.h: New files - for OSF/1-3.x procfs support. - * configure.in (alpha-dec-osf): Use them when configuring - for OSF/1-3.x. - * configure: Updated. - * target.c: Include . - -Fri Jul 14 16:16:56 1995 J.T. Conklin - - * Makefile.in, configure.in: Use one variable, frags, to hold - pathnames of makefile fragments. - * configure: regenerated. - -Fri Jul 14 09:49:47 1995 Jeff Law (law@snake.cs.utah.edu) - - * procfs.c (procfs_ops): Fix typo in last change. - -Thu Jul 13 13:42:38 1995 Jeffrey A. Law - - * inftarg.c (child_thread_alive): New function to see if a - particular thread is still running. - (child_ops): Add child_thread_alive entry. - * remote.c (remote_thread_alive): New function to see if a - particular thread is still alive. - (remote_ops): Add remote_thread_alive. - * target.c (dummy_target): Add dummy entry for thread_alive. - (cleanup_target): de_fault thread_alive too. - (update_current_target): INHERIT thread_alive too. - (debug_to_thread_alive): New function. - (setup_target_debug): Add debug_to_thread_alive. - * target.h (struct target_ops): Add to_thread_alive. - (target_thread_alive): Define. - * thread.c (info_threads_command): Don't call kill; use - target_thread_alive instead. - * config/nm-lynx.h (CHILD_THREAD_ALIVE): Define. - * gdbserver/low-lynx.c (mythread_alive): New function. - (mywait): Don't restart any threads after a new thread notification, - let the generic code handle it. - * gdbserver/low-sparc.c (mythread_alive): Dummy version. - * gdbserver/low-sun3.c (mythread_alive): Likewise. - * gdbserver/server.c (main): Handle thread_alive requests. - * gdbserver/server.h (mythread_alive): Declare. - * corelow.c (core_ops): Add dummy entry for thread_alive. - * exec.c (exec_ops): Likewise. - * m3-nat.c (m3_ops): Likewise. - * monitor.c (monitor_ops): Likewise. - * procfs.c (procfs_ops): Likewise. - * remote-array.c (array_ops): Likewise. - * remote-e7000.c (e7000_ops): Likewise. - * remote-es.c (es1800_ops, es1800_child_ops): Likewise. - * remote-mips.c (mips_ops): Likewise. - * remote-pa.c (remote_hppro_ops): Likewise. - * remote-sim.c (gdbsim_ops): Likewise. - * sparcl-tdep.c (sparclite_ops): Likewise. - -Tue Jul 11 11:15:55 1995 Kung Hsu - - * solib.c: Add _DYNAMIC__MGC base symbol for Mentor Graphics Inc. - * solib.c (match_main): New function for checking name of main. - * solib.c (solib_add): Not to add if solib match main. - -Fri Jul 7 14:41:56 1995 Kung Hsu - - * elfread.c (elf_symtab_read): Fix a bug ignoring compiler - generated internal labels ($LM...). - -Wed Jul 5 11:38:36 1995 Kung Hsu - - * defs.h: if __GO32__ or WIN32 the directory separating symbol should - be '\' not '/'. - - * remote-nindy (nindy_wait): Use infinite timeout reading after - esacpe character. - -Tue Jul 4 10:30:22 1995 Jeffrey A. Law - - * infrun.c (wait_for_inferior): When switching from one thread to - another, save infrun's state for the old thread and load infrun's - previous state for the new thread. - * thread.c (struct thread_info): Add new fields for thread specific - state saved/restored in infrun.c. - (add_thread): Initialize new fields. - (load_infrun_state): New function. - (save_infrun_state): New function. - * thread.h (load_infrun_state): Provide external decl. - (save_infrun_state): Likewise. - - * infrun.c (wait_for_inferior): When we hit a breakpoint for the - wrong thread, make sure to write the fixed PC value into the thread - that stopped. Restart all threads after single stepping over a - breakpoint for a different thread. - * breakpoint.c (set_momentary_breakpoint): Make momentary - breakpoints thread specific in a multi-threaded program. - * lynx-nat.c (child_resume): Add some comments. Correctly - choose between the single and multi-threaded step and continue - ptrace calls. - -Fri Jun 30 16:15:36 1995 Stan Shebs - - * config/h8300/h8300.mt: Renamed from h8300hms.mt. - * config/h8500/h8500.mt: Renamed from h8500hms.mt. - * config/z8k/z8k.mt: Renamed from z8ksim.mt. - * configure, configure.in: Update to reflect renamings. - - * remote-sim.c (sim): New command, passes commands to simulator. - (simulator_command): New function. - (gdbsim_ops): Clean up. - * remote-sim.h (sim_do_command): Declare. - * sh-tdep.c (memory_size): Remove command. - - * Makefile.in (SIM, SIM_OBS): New variables. - (CLIBS, CDEPS): Add value of SIM. - (DEPFILES): Add value of SIM_OBS - - * config/arm/arm.mt, config/h8300/h8300.mt, config/h8500/h8500.mt, - config/sh/sh.mt, config/sparc/sp64sim.mt, config/w65/w65.mt, - config/z8k/z8k.mt: Remove simulator files from TDEPFILES, - define in SIM_OBS and SIM. - config/sparc/sp64sim.mt (SIMFILES): Remove. - - * remote-z8k.c: Remove, was superseded by remote-sim.c - * Makefile.in, mpw-make.in: Remove references to remote-z8k.c. - -Sun Jun 25 15:30:43 1995 Stan Shebs - - * remote.c (remote_read_bytes, remote_write_bytes): Second arg - should be char *, not unsigned char *. - * dcache.h (memxferfunc): Ditto. - * monitor.c (monitor_write_memory, monitor_read_memory_single): - Ditto. - (monitor_make_srec): Let compiler figure size of hextab. - -Sat Jun 24 19:27:37 1995 Jeffrey A. Law - - * lynx-nat.c (child_wait): Don't restart new threads and loop - to the top of child_wait; let the machine independent code in - wait_for_inferior deal with new thread notifications. - -Fri Jun 23 11:51:58 1995 Kung Hsu - - * remote-nindy (nindy_load): Put in target specific load, it's - 20 times faster. - -Thu Jun 22 20:21:59 1995 Stan Shebs - - * utils.c (error): Move local `args' outside conditional, - move local `string1' inside, declare function as void if - non-ANSI compiler, dereference error_hook when calling. - - * mac-xdep.c (stdarg.h): Don't include. - -Thu Jun 22 13:12:33 1995 Kung Hsu - - * remote-nindy.c (nindy_wait): Change timeout in SERIAL_READCHAR. - -Wed Jun 21 13:24:41 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppam3-nat.c: Change HP800_THREAD_STATE to TRACE_FLAVOR and - HP800_THREAD_STATE_COUNT to TRACE_FLAVOR_SIZE. - -Wed Jun 21 05:57:56 1995 Steve Chamberlain - - * monitor.c: Turn on caching. - (monitor_printf): If a ^C was sent, don't expect to see its - echo. - (monitor_open): Enable caching. - (monitor_resume, monitor_load): Flush cache. - (monitor_xfer_memory): Call cache routine. - (monitor_dump_regs): New. - (monitor_fetch_registers): If monitor_dump_regs available - then use it. - (monitor_load): Don't ref exec_bfd if it's NULL. - (monitor_load_srec): Use new monitor_make_srec calling convention. - (monitor_make_srec): Rewrite to cope with two, three and four byte - addresses. - * remote-hms.c (hms_cmds): Initialze end-of-command delim. - * dcache.h, dcache.h: Rewritten. - * remote.c: Reenable caching. - (getpkt): Reduce MAX_TRIES to 3. - (remote_xfer_memory): Use dcache_xfer_memory. - * defs.h (error_hook): New. - * top.c (error_hook): New definition. - * utils.c (error): Use error_hook if initialized. - * sparcl-tdep.c (HAVE_SOCKETS): Don't define if GO32 or WIN32. Use - HAVE_SOCKETS in place of #ifndef GO32. - -Tue Jun 20 22:17:44 1995 Jeff Law (law@snake.cs.utah.edu) - - * config/pa/tm-hppa.h (PSW_*): Define processor status word masks. - (INSTRUCTION_NULLIFIED): Allow specific targets to override. - * config/pa/tm-hppao.h (INSTRUCTION_NULLIFIED): Define to work - around losing mach kernel behavior. - -Tue Jun 20 12:03:36 1995 Stan Shebs - - * monitor.c (monitor_wait): Don't use the watchdog timeout - if its value is 0. - * w89k-rom.c (w89k_open): Define to be static. - - -Sat Jun 17 10:17:16 1995 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c (som_solib_add): Validate regexp argument. - Don't assume the first entry on dld's library list is the main - program. Don't load the same library more than once and don't - consider the main program a shared library. - (som_solib_sharedlibrary_command): New function - (_initialize_som_solib): Add "sharedlibrary" command. - -Thu Jun 15 14:54:58 1995 Stan Shebs - - * array-rom.c: Remove, no longer used. - - * remote-hms.c (hms_open): Make static. - - * mpw-config.in (MacSerial.h): Copy from version in {CIncludes}, - not {MPW}Interfaces:CIncludes. - * ser-mac.c (mac_baud_rate_table): Fix value for 38400 baud. - -Wed Jun 14 14:27:07 1995 Per Bothner - - * ch-exp.y: Remove lots of unsupported productions and names. - Add support for IF-expressions, ORIF, ANDIF, NUM, and ADDR. - -Tue Jun 13 21:40:11 1995 Per Bothner - - * parser-defs.h (enum precedence): Added PREC_BUILTIN_FUNCTION. - * expression.h (enum exp_opcode): Added UNOP_LOWER, UNOP_UPPER, - UNUP_LENGTH. - * expprint.c (dump_expression): Handle the new exp_opcodes. - (print_subexp): Handle PREC_BUILTIN_FUNCTION. - (print_simple_m2_func): Removed. - (print_subexp): Remove support for Modula2 builtin functions. - * m2-lang.c (m2_op_print_tab): Add support for builtin functions. - * ch-exp.y: Parse LOWER, UPPER, and LENGTH builtins. - (write_lower_upper_value): Convenience function for LOWER and UPPER. - (upper_lower_argument, length_argument): Removed non-terminals. - * ch-lang.c (chill_op_print_tab): Entries for UPPER, LOWER, LENGTH. - (type_lower_upper): New function. Calculate LOWER/UPPER of type. - (value_chill_length): New function. Calcalate LENGTH of ARRAY/STRING. - (evaluate_subexp_chill): Handle UNOP_LOWER, UNOP_UPPER, UNOP_LENGTH. - -Mon Jun 12 12:48:13 1995 Stan Shebs - - Windows support bits from Steve Chamberlain . - * defs.h: Don't declare strchr and friends if WIN32. - (DIRNAME_SEPARATOR): Move here from source.c. - (SLASH_P, SLASH_CHAR, SLASH_STRING, ROOTED_P): New macros, - symbolic definitions for filename bits. - * top.c (cd_command): Use these. - * source.c (mod_path, openp): Ditto. - * terminal.h: Disable termio/sgtty definitions if WIN32. - * findvar.c (registers_changed): Call registers_changed_hook - if it is defined. - -Mon Jun 12 12:22:05 1995 J.T. Conklin - - * Makefile.in (distclean, realclean): Remove config.cache and - config.log. - -Mon Jun 12 00:21:59 1995 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c: Include gdb-stabs.h. - (som_solib_section_offsets): Use SECT_OFF_XXX rather than 0, 1, - etc. Initialize offsets for RODATA & BSS too. - -Sat Jun 10 17:59:11 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa-tdep.c (frame_chain): Try to compensate for incomplete - register information in core files when backtracing. - -Fri Jun 9 14:51:38 1995 Stu Grossman (grossman@cygnus.com) - - * remote-nrom.c: Remove everything but download code. More - cleanups. - -Thu Jun 8 15:06:00 1995 Stu Grossman (grossman@cygnus.com) - - * defs.h maint.c monitor.c remote-mips.c remote.c: Add support - for `watchdog' variable. This allows the user to put an upper - limit on the amount of time that GDB will wait for the target to - return from a step or continue operation. This will primarily be - used for the testsuite, where it is difficult to come up with a - reasonable timeout for things like function calls, which can take - as long as three minutes under some circumstances. If the - watchdog timer expires, GDB will generate an error that looks like - `Watchdog has expired.', and will detach from the target. - - * remote-mips.c (mips_open): Setup initial frame from target. - Print it out so that user is told where the program is stopped - when they attach. - - * remote-nrom.c: Loads of cleanups. Use serial code to open - network connections. Use expect() to wait for response to - download command. - - * ser-tcp.c (tcp_open): Retry connection if we get ECONNREFUSED. - - * serial.c serial.h (serial_open serial_fdopen serial_close): - Allow users to open the same device multiple times. They all get - to share the same serial_t. This is about the only way to have - multiple active targets use the same device (for download and - debug). - - * sparcl-tdep.c: Keep #include away from GO32. - - * target.c: Add `targetdebug' variable. If this is non-zero, - then a special target is put at the top of the target stack which - will cause all calls through the target vector to have their args - and results printed out. - -Wed Jun 7 17:40:37 1995 Per Bothner - - * ch-exp.y: Handle "->" . - -Wed Jun 7 17:46:33 1995 Michael Meissner - - * mem-break.c (LITTLE_BREAKPOINT): If BREAKPOINT and - {LITTLE,BIG}_BREAKPOINT are all defined, don't redefine. - (BIG_BREAKPOINT): Ditto. - - * config/rs6000/tm-rs6000.h (BREAKPOINT): Define as either - BIG_BREAKPOINT or LITTLE_BREAKPOINT depending on the target byte - order. - -Wed Jun 7 12:41:42 1995 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c (som_solib_section_offsets): Handle relative pathnames. - - * hppa-tdep.c (frame_saved_pc): Handle backtracing through signal - handler in dynamically linked executables. - -Tue Jun 6 10:44:25 1995 Michael Meissner - - From Andrew Cagney - * rs6000-tdep.c (single_step): Handle both little and big endian - breakpoints. - (gdb_print_insn_powerpc): Deal with disassembling both little and - big endian PowerPC systems. - (_initialize_rs6000_tdep): Use gdb_print_insn_powerpc to handle - disassembly, rather that assuming big endian order. - - * config/rs6000/tm-rs6000.h (BREAKPOINT): Delete. - (BIG_BREAKPOINT): Define, big endian breakpoint instruction. - (LITTLE_BREAKPOINT): Define, little endian breakpoint instruction. - -Sat Jun 3 01:54:56 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * README: Add note about Unixware 2.x. - - * dbxread.c (process_one_symbol): Check for exact symbol name - match when fixing up N_GSYM and N_STSYM symbols from Sun acc. - - * valprint.c (value_print_array_elements): Use - fprintf_filtered to put out `', - from schwab@issan.informatik.uni-dortmund.de (Andreas Schwab). - - * value.h (struct value): Change `repetitions' field from - `short' to `int' type. - -Fri Jun 2 11:17:23 1995 Doug Evans - - * arc-tdep.c (arc_bfd_mach_type): New static global. - (codestream_fill): Handle byte order differences. - (setup_prologue_scan): Don't read stdarg function's "sub sp,sp,N". - (arc_get_frame_setup): Read it here. - (arc_frame_saved_pc): And here. - (arc_print_insn): New function. - (arc_set_cpu_type): Set arc_bfd_mach_type. Don't set tm_print_insn. - (_initialize_arc_tdep): Set tm_print_insn to arc_print_insn. - -Wed May 31 12:04:01 1995 J.T. Conklin - - * nlm/{configure.in, Makefile.in}: Converted to use autoconf. - * nlm/configure: New file, generated with autoconf 2.3. - - * nlm/configure.in: Use sed instead of awk to get the value of - cpufile. Awk is not a utility required by the GNU coding - standards. This change also fixes the rigid whitespace - requirements that were required for awk. - - * sparclite/aload.c: Use a file descriptor instead of a stdio - stream for i/o with target board. - Use #error if HAVE_TERMIOS is not defined. - - * sparclite/{Makefile.in, configure.in}: Converted to use - autoconf. - * sparclite/configure: New file, generated with autoconf 2.3. - -Sun May 28 23:10:07 1995 Jeff Law (law@snake.cs.utah.edu) - - * defs.h: Include either varargs.h or stdarg.h (for va_list). - Fix stupid thinko in last change ("..." -> "va_list"). - - * defs.h (vprintf_filtered declaration): Add PARAMS prototype; - gcc-2.5 chokes on format attributes for unprototyped functions. - (vfprintf_filtered declaration): Likewise. - (vprintf_unfiltered declaration): Likewise. - (vfprintf_unfiltered). Likewise. - -Sat May 27 23:54:17 1995 J.T. Conklin - - * configure.in: Use sed instead of awk to get the values of - hostfile, targetfile and nativefile. Awk is not a utility - required by the GNU coding standards. This change also - fixes the rigid whitespace requirements that were required - for awk. - * configure: regenerated. - -Sat May 27 16:24:04 1995 Angela Marie Thomas - - * sparclite/{Makefile,configure}.in: Add hooks for building with - -lsocket & -lnsl for solaris2. Don't build aload/eload for DOS. - -Thu May 25 12:46:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdbserver/remote-utils.c (prepare_resume_reply): Add FIXME - comment regarding signal numbering. - -Wed May 24 15:49:47 1995 Steve Chamberlain - - * arm-tdep.c (_initialize_arm_tdep): Use print_insn_little_arm - now. - - * arm-tdep.c (convert_from_extended, convert_to_extended): - New. - * coffread.c (enter_linenos): Return if linetab 0. - * config/arm/arm.mt (TDEPFILES): Add simulator support. - * config/arm/tm-arm.h (FRAME_FIND_SAVED_REGS): Fix prototypes. - -Mon May 22 19:37:21 1995 Rob Savoye - - * config/idt.mt: replace monitor and array-rom with the new - remote-array. - -Mon May 22 15:38:25 1995 Stu Grossman (grossman@cygnus.com) - - * remote-nindy.c: Install Kung patch for PR 6820. I have no idea - what this does... - - * breakpoint.c: Move defaults of watchpoint related macros into - target.h. - * target.h: Macros from breakpoint.c. Conditionalize based on - TARGET_HAS_HARDWARE_WATCHPOINTS. - * i386v-nat.c procfs.c: Use TARGET_HAS_HARDWARE_WATCHPOINTS - instead of TARGET_CAN_USE_HARDWARE_WATCHPOINT to enable watchpoint - code. - * config/i386/nm-linux.h, config/mips/nm-irix4.h, - config/pa/nm-hppab.h, config/sparc/tm-sparclite.h: #define - TARGET_HAS_HARDWARE_WATCHPOINTS to enable watchpoint code. - -Mon May 22 06:47:30 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c, target.h: Move defaults of watchpoint related - macros back to breakpoint.c. Required to get GDB compiling - on Solaris again. - -Fri May 19 14:49:37 1995 J.T. Conklin - - * defs.h (ATTR_FORMAT): New macro, expands to gcc's format - attribute when compiled by gcc. - * defs.h, language.h, monitor.h: Changed many function - declarations to use ATTR_FORMAT. - - * breakpoint.c (delete_command); source.c (directory_command); - top.c (define_command): Changed call to query() that had too - many arguments. - * printcmd.c (address_info): Changed call to printf_filtered() - that had too many arguments. - -Fri May 19 09:52:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (wait_for_inferior): Move assignments to stop_signal - and stop_pc, and STOPPED_BY_WATCHPOINT code, back where they - were--after the switch statement on w.kind. You can't read the - registers of an inferior which has exited. Use a goto in the - STOPPED_BY_WATCHPOINT code. - * infrun.c (wait_for_inferior): Reinstate - HAVE_STEPPABLE_WATCHPOINT and HAVE_CONTINUABLE_WATCHPOINT code. - -Fri May 19 06:15:40 1995 Jim Kingdon - - * utils.c, complaints.c, language.c, monitor.c, remote-array.c, - remote-mips.c, remote-os9k.c, remote-st.c: Conditionalize use of - stdarg rather than varargs on ANSI_PROTOTYPES not __STDC__; it - must match the definition of PARAMS. - -Thu May 18 15:58:46 1995 J.T. Conklin - - * utils.c (fprintf_filtered, fprintf_unfiltered, fprintfi_filtered, - printf_filtered, printf_unfiltered, printfi_filtered, query, warning, - error, fatal, fatal_dump_core): Use stdarg.h macros when compiling - with an ANSI compiler. - * complaints.c (complain): Likewise. - * language.c (type_error, range_error): Likewise. - * monitor.c (monitor_printf, monitor_printf_noecho): Likewise. - * remote-array.c (printf_monitor, debuglogs): Likewise. - * remote-mips.c (mips_error): Likewise. - * remote-os9k.c (printf_monitor): Likewise. - * remote-st.c (printf_stdebug): Likewise. - - * defs.h, complaints.h, language.h, monitor.h: Add prototypes to - match above changes. - - * printcmd.c: Remove uneeded #include . - * remote-e7000.c: Likewise. - - * f-typeprint.c (f_type_print_base): Fix typo found by above - changes. - -Wed May 17 11:21:32 1995 Jim Kingdon - - * Makefile.in (xcoffread.o): Depend on partial-stab.h. - - * xcoffsolib.c (sharedlibrary_command): New command. - * xcoffsolib.c (solib_info): Call xcoff_relocate_symtab. - * xcoffsolib.c: Miscellaneous cleanups. - - * partial-stab.h: Ignore symbol descriptor '-' (for local - variables with negative type numbers) without complaint. - - * rs6000-nat.c (vmap_ldinfo): Use bfd_stat rather than our own - local emulation thereof. Remove unused variable ostart. - -Wed May 17 15:55:53 1995 J.T. Conklin - - * Makefile.in (config.status): changed target so that - config.status --recheck is executed if configure script changes. - - * monitor.c (monitor_printf): Changed format specification in - error message to work with pre-ansi compilers. - (monitor_load_srec): reduced length of s-records from 128 to 32 - bytes so download is more reliable with the rom68k monitor. - - * rom68k-rom.c: Added trailing space to prompt string. - - * config/i386/xm-i386sco.h (HAVE_STRSTR): Removed. - * config/i386/xm-go32.h, mswin/xm.h (SYS_SIGLIST_MISSING): - Removed. - * defs.h, config/{xm-lynx.h, xm-nbsd.h}, - config/i386/{xm-i386bsd.h, xm-linux.h}, - config/m68k/xm-hp300bsd.h, config/mips/xm-irix4.h, - config/ns32k/xm-ns32km3.h, doc/gdbint.texinfo - (PSIGNAL_IN_SIGNAL_H): Removed. - -Tue May 16 13:16:06 1995 J.T. Conklin - - * Makefile.in (Makefile): Added config.status to dependency list. - - * configure.in: Added INIT-CMDS argument to AC_OUTPUT which sets - gdb_host_cpu, gdb_target_cpu and nativefile. - * configure: regenerated. - -Mon May 15 23:50:51 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_symbol): Do not relocate stBlock/scText - symbols, their value is the displacement from the procedure address. - * top.c (init_main): Add missing newlines to help strings for - `if' and `while' commands, fix help string for `show commands'. - -Mon May 15 18:37:56 1995 Stu Grossman (grossman@cygnus.com) - - * breakpoint.c: Move defaults of watchpoint related macros into - target.h. Use BP_TEMPFLAG and BP_HARDWAREFLAG instead of - constants. - * infrun.c (wait_for_inferior): Enhance comment near - STOPPED_BY_WATCHPOINT. - * target.h: Macros from breakpoint.c. - -Mon May 15 17:11:38 1995 J.T. Conklin - - * config/i386/{i386sol2.mh, i386v4.mh, ncr3000.mh}, - config/m68k/m68kv4.mh, config/mips/{irix4.mh, irix5.mh, - mipsv4.mh}, config/sparc/sun4so2.mh (INSTALL): Removed, figured - out by autoconf. - * config/apollo68v.mh (RANLIB): Removed, figured out by autoconf. - - * Makefile.in, configure.in: Converted to use autoconf - * aclocal.m4: New file, local autoconf macro definitions. - * configure: New file, generated with autoconf 2.3. - -Mon May 15 14:46:41 1995 Stan Shebs - - * remote.c (remote_kill): Add prototype. - * cpu32bug-rom.c (cpu32bug_open): Properly define as static. - * config/h8300/h8300hms.mt (TDEPFILES): Add monitor.o. - -Mon May 15 12:12:34 1995 Stu Grossman (grossman@cygnus.com) - - * sparclite/salib.c (win_ovf win_unf): Make window size constant - into a variable (__WINSIZE) so that it can be controlled via the - .h file. - * sparclite/sparclite.h: Add SL933 #ifdef to set __WINSIZE to 6 - for the 933 board. - - * infrun.c: Add #ifdef HP_OS_BUG to all references to - trap_expected_after_continue. - * (wait_for_inferior): Fix for remote watchpoints. Don't try to - insert breakpoints while target is running (this only works on - *some* native targets). This may also speed up native watchpoints - considerably. - -Sat May 13 13:55:04 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dwarfread.c (struct dwfinfo), dbxread.c (struct symloc), - mdebugread.c (struct symloc), hpread.c (struct symloc), - xcoffread.c (struct symloc): Fix inaccurate comment introduced - 20 Apr 1995. - -Sat May 13 13:34:18 1995 Jim Kingdon - - * rs6000-tdep.c (find_toc_address): Revise comment. - * symfile.c, symfile.h (init_psymbol_list): New function; - consolidate duplicated copies from os9kread.c, dbxread.c - and dwarfread.c. - * defs.h: Declare info_verbose. - * xcoffread.c: Extensive changes to support psymtabs. - -Fri May 12 13:48:41 1995 Stu Grossman (grossman@andros.cygnus.com) - - * cpu32bug-rom.c remote-est.c rom68k-rom.c: Update line_term element. - -Fri May 12 06:39:30 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * partial-stab.h: Expand comments. - -Thu May 11 19:01:37 1995 Jeff Law (law@snake.cs.utah.edu) - - * Support debugging using native MACH primitives on hppa*-*-osf*. - * configure.in: hppa*-*-osf* != hppa*-*-bsd* anymore. - * config/pa/hppaosf.mh: New file. - * config/pa/nm-hppao.h: Likewise. - * hppam3-nat.c: Likewise. - * config/pa/tm-hppao.h (PSW_SS): Define for single-stepping. - (MACHINE_CPROC_*_OFFSET): Define. - (TRACE_*): Define. - (START_INFERIOR_TRAPS_EXPECTED): Delete definition. - -Wed May 10 18:59:26 1995 Stu Grossman (grossman@andros.cygnus.com) - - * hppa-tdep.c (read_unwind_info): Cosmetic cleanup. - * (unwind_command): Clean it up and make it print things out - nicer. - * monitor.c: Add ^C handling capability (mostly ripped off from - remote.c). - * (monitor_printf): Make it check the command echo. - * (monitor_printf_noecho): Similar to above, but doesn't check - for echo. - * (monitor_stop): No longer waits for prompt. That is the job of - the caller. This makes things work much better for monitor_wait, - which waits for the prompt itself. - * (monitor_open): Deal with new monitor_stop semantics. Also, - flush input after sending init strings to get rid of junk that may - be output. Also, don't always send \r to remote. Use - monitor_ops->line_term cuz proper character isn't always \r. - * (monitor_fetch_register): Switch to completely different - algorithm to deal with lame-ass monitors which put spaces in the - middle of numbers, and prompt with a space!!!!! - * (monitor_read_memory_single): New routine to be used with - monitors that can only return one byte/short/long at a time. This - is selected via MO_GETMEM_READ_SINGLE. - * (monitor_load_srec): Use monitor_printf_noecho for sending S - records. Most targets don't echo them. - * (monitor.h): Get rid of cmd_delim. Add line_delim. - * op50n-rom.c (op50n_cmds): Fill it up. Make it work. - * w89k-rom.c: Change all eols from \r to \n. Change load_resp to - ^Q to prevent error message. - * config/pa/tm-hppa.h (CALL_DUMMY (for hppro)): Add special - instruction sequence at end to make restore_pc_queue happy. - -Wed May 10 15:59:00 1995 Torbjorn Granlund - - * remote-est.c (est_open): Make static to match prototype. - -Tue May 9 16:58:50 1995 Michael Meissner - - * configure.in: Add little endian PowerPC support. - * config/powerpc/ppcle-eabi.mt: New file for little endian PowerPC - support. - * config/powerpc/tm-ppcle-eabi.h: ditto. - -Mon May 8 12:11:38 1995 J.T. Conklin - - * nlm/configure.in (gdb_host, gdb_host_cpu, gdb_target): Removed. - These variables not used. - - * config/m68k/monitor.mt (TDEPFILES): Added cpu32bug-rom.o. - -Wed May 3 17:54:47 1995 Stan Shebs - - * monitor.c (monitor_command): Don't use PROMPT until monitor - target is known to be open. - (monitor_make_srec): Don't define size of hextab. - -Tue May 2 18:32:24 1995 Stan Shebs - - * configure.in (--enable-netrom): New configuration option. - * Makefile.in (REMOTE_OBS): Rename from REMOTE_O, append - value of NETROM_OBS. - (NETROM_OBS): New variable. - * remote-nrom.c: New file, NetROM target support. - * config/a29k/a29k-udi.mt, config/i960/vxworks960.mt: Use - REMOTE_OBS instead of REMOTE_O. - * config/arc/arc.mt: Ditto. - -Fri Apr 28 23:30:00 1995 Stu Grossman (grossman@cygnus.com) - - * array-rom.c (_initialize_array array_open): Move baud_rate - initialization from _initxxx to array_open to fix bug with - overriding -b command line option. - -Thu Apr 27 20:29:34 1995 Doug Evans - - * Makefile.in (RUNTEST): Fix reference of `srcdir'. - -Wed Apr 26 19:01:08 1995 Steve Chamberlain - - * remote-hms.c: Rewrite to use new monitor conventions. - -Tue Apr 25 11:27:14 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dbxread.c: Add comment explaining lowest_text_address. - Add comment regarding stringtab_global and psymtabs. - -Sat Apr 22 01:26:29 1995 Jeff Law (law@snake.cs.utah.edu) - - * config/pa/tm-hppa.h (EXTRACT_STRUCT_VALUE_ADDRESS): Fix. - - * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Rewrite to correctly - handle "short", "int" and small structures returned in registers. - -Fri Apr 21 12:57:53 1995 Kung Hsu - - * minsyms.c: add new function lookup_minimal_symbol_text, to look - for text symbol only. - * breakpoint.c (create_longjmp_breakpoint): call - lookup_minimal_symbol_text instead of lookup_minimal_symbol. - * symtab.h: add lookup_minimal_symbol_text prototype. - -Fri Apr 21 12:03:44 1995 Stan Shebs - - * sh-tdep.c (sh-opc.h): Don't include. - (gdbcore.h): Include. - (frame_find_saved_regs): Remove unused local. - -Thu Apr 20 10:12:21 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dwarfread.c (struct dwfinfo), dbxread.c (struct symloc), - mdebugread.c (struct symloc), hpread.c (struct symloc): Clean - up comments. - -Wed Apr 19 16:58:11 1995 Stu Grossman (grossman@andros.cygnus.com) - - * hppa-tdep.c (deposit_17): New routine to deposit 17 bit - constants into PA instructions. - * Put #ifdefs around all signal handling code. Not generally - needed for embedded boards. - * (hppa_fix_call_dummy): Parameterize offsets into call dummy to - allow different dummys to be used by this code. Use - INSTRUCTION_SIZE instead of REGISTER_SIZE for things. - Conditionalize setup of _sr4export fixup. Improve comments. - * config/pa/tm-hppa.h: Define INSTRUCTION_SIZE. Use a different - call dummy if PA_LEVEL_0 is defined. Better comments for call - dummys. Define offsets for LDIL/LDO instructions which load - function addresses. - * config/pa/tm-pro.h: Get rid of signal handling stuff. Define - PA_LEVEL_0 to disable mucking with space regs and such. - -Mon Apr 17 15:37:08 1995 Stu Grossman (grossman@andros.cygnus.com) - - * cpu32bug-rom.c monitor.h op50-rom.c remote-est.c rom68k-rom.c - w89k-rom.c: Remove loadtypes, loadprotos and baudrates. - * op50-rom.c: Fix copyrights and add load routine to op50n_cmds. - * rom68k-rom.c (_initialize_rom68k): Don't set baud rate. - * w89k-rom.c: Fix copyrights. - -Sun Apr 16 14:00:55 1995 Stu Grossman (grossman@andros.cygnus.com) - - * monitor.c: Move all xmodem stuff into xmodem.[ch]. Remove - unnecessary remoteloadprotocol and remoteloadtype support. - * (expect expect_prompt): Change names to monitor_expect and - monitor_expect_prompt. Make them global. - * (printf_monitor): Change name to monitor_printf. Make global. - * (monitor_read_memory): Flush command echo to avoid parsing - ambiguity with CPU32Bug monitor. - * (monitor_load): Remove remoteloadprotocol and remoteloadtype - support. Call target_ops->load_routine, default to - monitor_load_srec. - * (monitor_load_srec): Remove everything but S-record support. - * monitor.h (monitor_ops): Add load_routine to provide monitor - specific download capability. - * remote-est.c: Clean up copyrights and comments. - * w89k-rom.c: Use new xmodem support. - * xmodem.c xmodem.h: New files to support xmodem downloads. - * rom68k-rom.c remote-est.c: Fix copyrights, add load_routine - entry to monitor_ops. - * cpu32bug-rom.c: New file to support Moto BCC debuggers. - * config/m68k/est.mt (TDEPFILES): Add cpu32bug.o. - * config/pa/hppapro.mt (TDEPFILES): Add xmodem.o. - -Sat Apr 15 18:00:15 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * rem-multi.shar: Removed; superceded by gdbserver. - -Fri Apr 14 12:10:24 1995 Jim Kingdon - - * xcoffread.c (xcoff_sym_fns): Revise comment about merging this - with coffread.c. - - * breakpoint.c (fixup_breakpoints): Removed. - * rs6000-nat.c (vmap_symtab): Don't call fixup_breakpoints. - (vmap_ldinfo, xcoff_relocate_core): Call breakpoint_re_set. - - * coffread.c (coff_symfile_offsets): Allocate SECT_OFF_MAX - sections, not just SECT_OFF_MAX-1. - - * rs6000-nat.c (vmap_symtab), xcoffread.c: Re-do section offsets - to be indexed by SECT_OFF_* instead of xcoff section numbers. - * objfiles.c, remote.c: Remove comments regarding SECT_OFF_*. - * symtab.h: Revise comment about block_line_section. - * rs6000-nat.c (vmap_symtab): Don't relocate objfile->sections. - -Sat Apr 15 14:15:14 1995 Stan Shebs - - * mpw-make.in (init.c): Don't try to do symbolic {o} in sed - command, not allowed by some version of MPW Make. - * ser-mac.c (mac-setbaudrate): Make it actually set baud rates. - -Sat Apr 15 14:05:09 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * alpha-tdep.c (alpha_push_arguments): Fix typo (TYPE_VALUE -> - VALUE_TYPE). Do the cast for TYPE_CODE_BOOL, TYPE_CODE_CHAR, - TYPE_CODE_ENUM, and TYPE_CODE_RANGE as well as TYPE_CODE_INT. - -Sat Apr 15 14:04:32 1995 Per Bothner - - * alpha-tdep.c (alpha_push_arguments): Only cast to long for - TYPE_CODE_INT. - - -Thu Apr 13 16:17:04 1995 Rob Savoye - - * remote-array.c: New file for Array Tech LSI33k based controller - board. - -Thu Apr 13 12:23:31 1995 Kung Hsu - - * a29k-tdep.c (get_longjmp_target): Replace SWAP_TARGET_AND_HOST with - extract_address. - * remote-vxsparc.c: New file, preliminary check in, this configuration - not supported yet. - * remote-vxmips.c: ditto. - -Thu Apr 13 12:10:14 1995 Michael Meissner - - * rs6000-tdep.c (xcoff_add_toc_to_loadinfo): Don't use a prototype - to declare the function. - -Wed Apr 12 16:40:20 1995 Stan Shebs - - * monitor.h (init_monitor_ops): Declare. - * rom68k-rom.c: Clarify some comments. - (rom68k_open): Define as static, to match decl. - -Wed Apr 12 16:36:44 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * gdb.gdb: New file. - * .gdbinit: Move list-objfiles to gdb.gdb. - - * values.c (set_internalvar): Set modifiable flag of newval. - -Wed Apr 12 14:34:31 1995 Jim Kingdon - - * xcoffread.c: Call complain() rather than error() or printing a - warning. - -Wed Apr 12 08:15:27 1995 Doug Evans - - * arc-tdep.c: #include "gdbcmd.h". - (codestream_seek): Pass CORE_ADDR. - (arc_cpu_type, tmp_arc_cpu_type, arc_cpu_type_table): New globals. - (debug_pipeline_p): Likewise. - (X_...): Instruction field access macros. - (BUILD_INSN): Define. - (codestream_tell): Allow for stream elements > 1 byte. - (codestream_fill): Likewise. - (setup_prologue_scan): New function. - (arc_get_frame_setup): Call it. Update to current spec - regarding prologues. Use BUILD_INSN. - (skip_prologue): New argument `frameless_p'. Use BUILD_INSN. - (arc_frame_saved_pc): New function. - (frame_find_saved_regs): Use BUILD_INSN. - (get_insn_type, single_step): New functions. - (one_stepped): New global. - (arc_set_cpu_type_command, arc_show_cpu_type_command): New functions. - (arc_set_cpu_type): New function. - (_initialize_arc_tdep): Define new `set' commands `cpu', - `displaypipeline', and `debugpipeline'. - * arc/tm-arc.h (TARGET_BYTE_ORDER): Delete. - (TARGET_BYTE_ORDER_SELECTABLE): Define. - (DEFAULT_ARC_CPU_TYPE): Define. - (SKIP_PROLOGUE_FRAMELESS_P): Define. - (BREAKPOINT): Delete. - (BIG_BREAKPOINT, LITTLE_BREAKPOINT): Define. - (DECR_PC_AFTER_BREAK): Change to 8. - (NO_SINGLE_STEP): Define. - (ARC_PC_TO_REAL_ADDRESS): Define. - (SAVED_PC_AFTER_CALL): Use it. - (NUM_REGS, REGISTER_BYTES): Fix. - (FRAME_SAVED_PC): Call arc_frame_saved_pc. - (FRAME_LOCALS_ADDRESS): Fix. - -Tue Apr 11 16:42:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * top.c, utils.c, defs.h: Remove error_hook. It is currently - unused and would need to hook into error_begin()/return_to_top_level(), - instead of error(), if it were to be used. - -Tue Apr 11 13:46:25 1995 Jim Kingdon - - * utils.c, defs.h (warning_begin): Renamed from warning_setup, for - consistency with error_begin. Also print warning_pre_print. - Document it better. - * utils.c (warning): Use it. - * utils.c (error_begin): Doc fix. - * rs6000-nat.c (vmap_ldinfo): If we don't find ldinfo for the - symfile_objfile, nuke it. - -Tue Apr 11 09:35:20 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * printcmd.c (print_address_numeric): Pass use_local to - print_longest, rather than always passing 1. - - * nlm/Makefile.in: Remove comments discussing munch. - - -Mon Apr 10 18:31:57 1995 Stan Shebs - - Merge in support for Mac MPW as a host. - (Old change descriptions retained for informational value.) - - * mpw-config.in (i386-unknown-go32): Change from aout. - (sh-hitachi-hms): New target. - * mpw-make.in (BISON): Use byacc instead of bison. - (VERSION): Bump to 4.14.1. - (*-pinsn.*): Remove mentions everywhere. - (all): Don't build MacGDB. - (gdb, SiowGDB): Depend on Version.r. - (Version.r): Generate from version info. - * main.c (main): Pass program name to START_PROGRESS, END_PROGRESS. - (main) [MPW]: Remove debugging hook. - * mac-xdep.c (debug_openp): New flag. - (mac_init): Set flag if env variable defined. - * ser-mac.c (mac_open): Clarify error message. - (mac_readchar): Call PROGRESS while looping. - (mac_write): Call sleep instead of sec_sleep. - (sec_sleep): Remove. - * source.c (openp) [MPW]: Only print debugging info if debugging. - * utils.c (query) [MPW]: Clarify that behavior is a bug. - - * mpw-make.in (init.c): Use open-brace instead of mpw-open-brace. - - * main.c, source.c: Remove hacks that replace long strings - with shorter ones, now solved portably. - - * config/m68k/xm-mpw.h (spin.h): Include. - (ALMOST_STDC): Only define if MPW_C. - * config/m68k/tm-mac.h: New file, Mac target definitions. - - * mpw-config.in (m68k-apple-macos, ppc-apple-macos, - i386-unknown-aout): New targets. - (mk.tmp): Add *DEPFILES definitions. - * mpw-make.in: Remove gC rules, clean up definitions for other - include files, bump version, fix bogus \ that should be \Option-d. - (init.c): Build correctly. - - * mpw-make.in (HFILES_NO_SRCDIR): Add somsolib.h - (ALLDEPFILES): Add somsolib.c. - (somsolib.o): Add some dependencies. - - * mpw-config.in: Use nm-empty.h if host is not target. - (xdepfiles): Add mac-xdep.c.o. - (xm_file): Remove. - * mpw-make.in: Add Fortran files. - (XDEPFILES): Remove. - - * mpw-config.in (MacSerial.h): Duplicate from standard Serial.h. - * ser-mac.c (MacSerial.h): Include instead of Serial.h. - - * mpw-make.in: Use {s} instead of {srcdir} everywhere. - (bindir, libdir): Remove extra colon. - (source.c): Compile with C instead of gC. - (c-exp.tab.c, ch-exp.tab.c, m2-exp.tab.c): Add {o}. - (install-only): Don't install MacGDB. - * source.c (openp) [MPW]: Add a debugging display. - (open_source_file) [MPW]: Use MPW basename finders. - [MPW_C]: Briefer versions of help for line and list commands. - - * mpw-make.in: Change references from paread.c to somread.c - - * mpw-make.in (VERSION): Update to 4.12.3. - (SiowGDB): New target, GDB using SIOW library. - (init-new.c): New target, attempt to generate init.c from sources. - (main.c.o, top.c.o): Put each in its own segment. - * main.c (main) [MPW]: Always call mac_init. - * utils.c (query) [MPW]: Always return "yes" if in MacGDB, output - an extra newline otherwise. - * mac-xdep.c: More comments in various places, remove junk. - (mac_init): Add tests for MPW and SIOW. - (use_wne, has_color_qd): Renamed. - (use_color_qd): New variable. - (grow_window): Only do console resizing to console window, - call resize_console_window. - (zoom_window): Call resize_console_window. - (resize_console_window, scroll_text): New functions. - (adjust_console_sizes): Always align viewrect to even multiples of - text lines. - (adjust_console_text): Always scroll by whole lines. - (hacked_vfprintf, hacked_puts, hacked_fputc, hacked_putc): Force a - recalculation of scroll positions if a newline was output. - (hacked_fflush): Similarly, for flushing. - (hacked_fgetc): New function, aborts if called in MacGDB. - * ser-mac.c (mac_readchar): Rename starttime to start_time, - remove debugging printf. - (mac_write): Sleep on first 4 writes. - (sec_sleep): New function, works like standard sleep. - * macgdb.r: Adjust positioning and contents of About box. - Set minimum size to 2000K, preferred size to 5000K. - * config/m68k/xm-mpw.h (fgetc): Define as a macro. - - * mpw-make.in (.c.o, .gc.o): Prefix segment names with gdb_. - (top.c.o, annotate.c.o): Add build rules. - * macgdb.r (SysTypes.r): Include. - ('vers'): New resource, version info. - (mFile, mEdit, mDebug): Enable all menu items. - (mDebug): Add key equivalents for continue, step, next. - (wConsole): Add zoom and close boxes to window. - * mac-xdep.c (new_console_window): New function, code taken from - mac_init. - (mac_command_loop): Use GetCaretTime for wait interval, call - do_idle on null events. - (do_idle): New function. - (zoom_window): Implement zooming. - (v_scroll_proc): New function, handles vertical scrolling. - (activate_window): Do activation of console window. - (do_menu_command): Implement items of file, edit, and debug menus. - (do_keyboard_command): Fix command extraction. - (adjust_console_sizes, adjust_console_text): New functions. - (hacked_fprintf, hacked_vfprintf, hacked_fputs, hacked_fputc, - hacked_putc): Don't call draw_console. - * ser-mac.c (mac_open): Add an error message for invalid ports. - (first_mac_write): New global. - (mac_write): Use first_mac_write to sleep on first several writes. - - * mpw-make.in (INCLUDE_CFLAGS): Add readline source dir. - (READLINE_CFLAGS, READLINE_SRC, READLINE_DIR): Uncomment. - (TSOBS): Don't compile inflow.c. - (all, install): Add MacGDB. - * main.c (main): Do Mac-specific init and command loop if a - standalone app, skip full option help message if compiling - with MPW C. - (gdb_readline): If MPW, add a newline after the (gdb) prompt. - * utils.c (_initialize_utils): If MPW, don't try to use termcap to - compute the window size. - * config/m68k/xm-mpw.h (printf, fprintf, fputs, fputc, putc, - fflush): Define as macros that expand into hacked_... versions. - (StandAlone, mac_app): Declare. - * macgdb.r (SIZE): Set the default partition to 4000K. - * mac-xdep.c (readline.h, history.h): Include. - (terminal.h): Don't include. - (mac_app): Define. - (gdb_has_a_terminal): Define Mac-specific version. - (do_keyboard_command): Simplify search for command string. - (readline): Define as gdb_readline. - Add other history/readline stubs to make main gdb link. - (hacked_fprintf, hacked_printf, hacked_vfprintf, hacked_fputs, - hacked_fputc, hacked_fflush): New functions, intercept output to - stdout and stderr, send to console window. - - * mpw-make.in (MacGDB): New target, standalone Mac-hosted gdb. - (XDEPFILES): Define. - (main.c.o): Compile with gC instead of C. - * mac-defs.h: New file, menu etc definitions shared between - C and Rez files. - * macgdb.r: New file, Rez (resource compiler) resource - definitions. - * mac-xdep.c: New file, Mac host interface code. - * config/m68k/xm-mpw.h (PATHNAME_SEPARATOR): Rename to - DIRNAME_SEPARATOR. - (PATHNAME_SEPARATOR_STRING): Remove. - (SIGQUIT, SIGHUP): Define. - (fileno, R_OK): Define. - - * mpw-config.in: New file, MPW configuration fragment. - * mpw-make.in: New file, MPW makefile fragment. - * config/m68k/xm-mpw.h: New file, MPW host definitions. - * ser-mac.c: New file, Mac serial interface. - -Mon Apr 10 16:47:57 1995 Kung Hsu - - * valprint.c (print_longest): Fix a syntax error in #ifdef - PRINTF_HAS_LONG_LONG. - - * config/mips/xm-irix5.h: turn on CC_HAS_LONG_LONG and - PRINTF_HAS_LONG_LONG. - * config/mips/tm-irix5.h: turn on FORCE_LONG_LONG. - -Sat Apr 8 02:47:45 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_symbol): Use new variable - nodebug_var_symbol_type as type of variables which don't have any - ecoff debug info associated with them. - (parse_symbol, parse_procedure): Use heuristics to determine if - functions were compiled without debugging info and change their - type to nodebug_function_symbol_type. - (_initialize_mdebugread): Initialize nodebug_*_symbol_type. - - * source.c (line_info): Clear sal.pc for `info line' without - arguments. - -Fri Apr 7 17:43:01 1995 Stu Grossman (grossman@andros.cygnus.com) - - * monitor.c: make_xmodem_packet and print_xmodem_packet go away. - send_xmodem_packet shows up to do the obvious. Lots of fixes to - xmodem downloads including resetting of block number at start of - new transfers, fix for buffer overrun problem, addition of CRC - generation code. - * (monitor_open): loadtype_str and loadproto_str now default to - first entry in monitor_ops->loadtypes. - * (monitor_wait): Lengthen register dump buf, because of verbose - Winbond monitor. - * (monitor_fetch_register): Report unimplemented registers as 0. - * (monitor_read_memory): Only do 16 byte aligned transfers - because of formatting weirdness with the Winbond monitor. Also, - ignore non-hex, non-whitespace formatting between bytes (same - monitor). - * (monitor_load): Clean up logic. - * (monitor_load_srec): Re-do xmodem support. Move lots of it - into send_xmodem_packet. - * (getacknak): Get rid of polls and timeouts. Handle CRC - requests from receiver. - * (monitor_make_srec): Efficiency improvements. Don't call - sprintf to output two digit hex numbers. - * (crcinit, docrc): New, CRC-16 support routines. - * (send_xmodem_packet): New routine to generate either CRC-16 or - checksummed xmodem packets. - - * remote-est.c (est_loadtypes), rom68k-rom.c (rom68k_loadtypes): - Reduce tables down to only the load types supported by each - monitor. - - * w89k-rom.c (w89k_supply_register): Parses output of Winbond - register dumps. - * (w89k_loadtypes, w89k_loadprotos): Reduce to just srec/xmodem. - * (w89k_cmds): Add clear all breakpoints, memory fill, and dump - registers commands. - - * config/pa/tm-hppa.h: Define lots register offsets needed by - w89k-rom.c. - - -Thu Apr 6 17:00:46 1995 Michael Meissner - - * Makefile.in (X11_INCLUDES): Define as empty. - (X11_CFLAGS): Define as including $(X11_INCLUDES). - (X11_LIB_SWITCHES): Define as empty. - (X11_LIBS): Define as -lX11. - - -Wed Apr 5 19:57:38 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mips-tdep.c (mips_print_register): Remove unused variable - our_type and call to init_type. Fixes memory leak. Reindent function. - - * mips-tdep.c (mips_print_register), findvar.c - (write_register_bytes): Make buffer char[] instead of unsigned - char[]. - -Mon Apr 3 19:28:14 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * top.c, utils.c, main.c, defs.h: Replace error_pre_print with two - variables: error_pre_print (for RETURN_ERROR) and quit_pre_print - (for RETURN_QUIT). Fixes a bug whereby typing ^C (e.g. in "maint - print sym") could output extraneous stuff. - * objfiles.c: Don't declare error_pre_print; defs.h does it. - -Mon Apr 3 13:48:28 1995 Stu Grossman (grossman@andros.cygnus.com) - - * monitor.h: Add MO_GETMEM_NEEDS_RANGE flag. - * monitor.c (monitor_read_memory): Use previously mentioned flag - to send proper format memory examine commands to the w89k monitor. - Also, try to handle bizarre format of memory dump... - - * op50-rom.c w89k-rom.c: Update to new monitor.[ch] conventions. - -Sat Apr 1 03:22:20 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dbxread.c (process_one_symbol) [SOFUN_ADDRESS_MAYBE_MISSING]: - Handle relocated symbol address. - * partial-stab.h, case N_SO, SOFUN_ADDRESS_MAYBE_MISSING: - Do not relocate a zero address. - -Thu Mar 30 19:46:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/a29k/tm-a29k.h: Nuke obsolete define CONTROL_END_ADDR; it - is nowhere used. - - * stabsread.c (read_range_type): Remove FIXME comment about - type-id (I presume this meant a number followed by = followed by a - type) versus type number; Per fixed it. - -Wed Mar 29 09:56:04 1995 Jason Molenda (crash@phydeaux.cygnus.com) - - * configure.in: sparc-*-sunos5* is same as sparc-*-solaris2*. - -Wed Mar 29 18:30:03 1995 Stan Shebs - - * remote-e7000.c (why_stop): Add new kinds of strings to expect - from the emulator. - (e7000_wait): Add interpretations for more stop reasons, - including warnings for write protect and cycle address errors. - -Wed Mar 29 17:09:29 1995 Stu Grossman (grossman@cygnus.com) - - * monitor.c monitor.h remote-est.c rom68k-rom.c: Add start of - support for interrupting target. - * monitor.c (monitor_open): Send stop command before doing - anything else. - * (monitor_load_srec): Fix record size calculation to prevent end - of segment from getting trashed. - * rom68k-rom.c: Update to latest version of struct monitor_ops. - * config/sparc/tm-sparc.h (FIX_CALL_DUMMY): Fix byte-order - problems. Makes DOS hosted function calling work. - * sparclite/crt0.s: Define _start to make COFF happy. - -Wed Mar 29 09:11:51 1995 Michael Meissner - - * defs.h (atof): Don't provide an external declaration if atof is - a macro. - -Wed Mar 29 00:01:07 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * rs6000-tdep.c (skip_prologue): Skip saving of LR and CR in - the stack frame, fix typos in `st rx,NUM(r1)' and `stu r1,NUM(r1)' - tests. - -Tue Mar 28 17:04:04 1995 Per Bothner - - * gdbtypes.c (create_range_type): If indextype has TYPE_FLAG_STUB - set, set TYPE_FLAG_TARGET_STUB. - (check_stub_type): Recalculate TYPE_LENGTH for range type. - * stabsread.c (read_range_type): If index type number is followed - by '=', back up, call read_type. and assume we have a true range. - * gdbtypes.h (TYPE_FLAG_TARGET_STUB): Update comment. - -Mon Mar 27 22:51:54 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-nat.c, irix4-nat.c, irix5-nat.c, mipsv4-nat.c, - sparc-tdep.c (supply_gregset, supply_fpregset): Fill inaccessible - registers with zero to handle recent read_register_bytes change. - * irix4-nat.c, irix5-nat.c, mipsv4-nat.c (supply_gregset, - fill_gregset): Fix handling of CAUSE_REGNUM. - * mips-nat.c (store_inferior_registers): Handle unwritable - registers when storing a single register. - * config/mips/tm-irix3.h (CAUSE_REGNUM, BADVADDR_REGNUM): - Fix definitions. - - * mdebugread.c (parse_symbol, psymtab_to_symtab_1): Clear - allocated mips_extra_func_info, if the debug info is corrupt, - the PDR to fill it in might be missing. - -Mon Mar 27 14:43:00 1995 Kung Hsu - - * vx-share/regPacket.h: a new file interfacing with vxworks. - -Sun Mar 26 13:22:47 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (bpstat_do_actions): Once we've executed the - commands, set bs->commands to NULL. - -Sat Mar 25 01:16:10 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * buildsym.c (patch_subfile_name): Update last_source_file - with the real source file name. - * dbxread.c (end_psymtab): Handle static functions in the - SOFUN_ADDRESS_MAYBE_MISSING case by passing pst->filename - to lookup_minimal_symbol. - (process_one_symbol): Ignore extra outermost context from - SunPRO cc and acc. - * stabsread.c (define_symbol): Do not complain for SunPRO - static variable encoding if STATIC_TRANSFORM_NAME is defined. - * sparc-tdep.c, config/sparc/tm-sun4sol2.h - (sunpro_static_transform_name): Renamed from - solaris_static_transform_name. - * config/sparc/tm-sun4os4.h (STATIC_TRANSFORM_NAME): - Define to sunpro_static_transform_name for acc 3.0 compiled - executables. - * procfs.c, config/alpha/nm-osf2.h (PROCFS_DONT_TRACE_FAULTS): - Renamed from PROCFS_DONT_TRACE_IFAULT, don't trace any faults - if defined. - * procfs.c (info_proc_siginfo): Cast sip->si_addr to - `unsigned long' and use `lx' format for printing it. - -Fri Mar 24 15:45:42 1995 Stu Grossman (grossman@cygnus.com) - - * configure.in: Move test for m68*-est-* before m68*-*-coff*. - * findvar.c: Move default def of CANNOT_STORE_REGISTER closer to - the beginning of the code. - * (write_register_gen): New routine. Analogous to - read_register_gen. - * (write_register_bytes): Another rewrite! Make it smarter about - not updating regs with the same value. - * monitor.c (printf_monitor readchar): Use stderr instead of - stdout to output debug info. Also cleanup readchar a little. - * (expect): Make sure that excessive responses are null - terminated. - * (monitor_open): Check for magic number in monitor_ops struct. - Allow multiple commands as init strings. Also, clear all - breakpoints. - * (monitor_resume monitor_wait): Send a command to dump all the - regs for those targets which don't do so when waking up after a - continue command. - * (monitor_wait): Handle excessive response output better. - * (monitor_write_memory): Use block fill, word, and long word - commands (if they exist) to write memory more efficiently. - * General cleanups to use flag bits instead of individual flag - words in monitor_ops struct. - * (monitor_command): Return output from command. - * (monitor_load_srec): Allocate buffer only once. Use alloca. - Wait for load response string instead of using a timeout to start - sending S-records. Fix bug where value of srec_frame shrinks. If - hashmark is set, print `-' for retransmissions. General cleanups. - * (monitor_make_srec): Get rid of S-record default type kludge. - * monitor.h: Use seperate struct for memory and register - read/write commands. Memory commands can come in byte, word, - long, and longlong forms. - * (monitor_ops): Change lots of fields. Generalize some stuff. - Put all flags into flags word. Allow init to be a list of commands. - Add command for clearing all breakpoints, block fill, dumping all - registers. - * remote-est.c: Rewrite to use new monitor conventions. - * config/m68k/est.mt (TDEPFILES): Add monitor.o. - * config/m68k/tm-est.h: Set NUM_REGS to 18. - * testsuite/gdb.base/break.exp: Lots of cleanups. Use gdb_test - more thoroughly. - -Thu Mar 23 23:20:00 1995 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c (som_solib_add): Handle case where a shared library - referenced by a core file has sections without the SEC_ALLOC bit - set (eg stabs sections). - -Thu Mar 23 15:07:08 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * breakpoint.c (bpstat_do_actions): For each element in the bpstat - chain, do all the commands regardless of whether they run the - inferior. - -Wed Mar 22 19:17:06 1995 Doug Evans - - * mem-break.c (LITTLE_BREAKPOINT, BIG_BREAKPOINT): Define as - BREAKPOINT if mono-endian. - (break_insn): Deleted. - (big_break_insn, little_break_insn): Define. - (memory_insert_breakpoint): Handle bi-endian cpus. - (BREAKPOINT_LEN): Define. - (memory_remove_breakpoint): Use it. - (memory_breakpoint_size): Likewise. - -Tue Mar 21 17:03:17 1995 Kung Hsu - - * sparc-stub.c: add nop after 'bg good_wim'. - * sparcl-stub.c: ditto. - -Tue Mar 21 13:34:12 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (handle_command): Don't print TARGET_SIGNAL_0, - TARGET_SIGNAL_UNKNOWN, or TARGET_SIGNAL_DEFAULT. - -Mon Mar 20 10:09:59 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppab-nat.c (store_inferior_registers): Sync with HPUX version. - -Mon Mar 20 07:34:48 1995 Stu Grossman (grossman@cygnus.com) - - * hppah-nat.c (store_inferior_registers): Move check for - CANNOT_STORE_REGISTER to a better place. Fixes ptrace I/O errors - found by test suite during function calls, which attempts to write - unwritable registers. - -Sat Mar 18 02:02:24 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_symbol): If finishing a function without - known parameter type info, set that from parameter symbols. - Remove commented-out add_param_to_type support. - -Thu Mar 16 16:38:03 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (process_linenos): Make sure filename we pass to - start_subfile will cause deduce_language_from_filename to return - the correct thing. Reindent function to GNU standards. - -Thu Mar 16 15:54:00 1995 J.T. Conklin - - * nlm/gdbserve.c (handle_exception): #if out call to StopBell, - as it is not available on NetWare 3 or PIN. - * nlm/ppc.c (StopBell): Removed. - -Thu Mar 16 12:14:41 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (read_xcoff_symtab): When creating a dummy parameter - inferred from the traceback tags, give its type the name - "". - - * stabsread.c (rs6000_builtin_type): Recognize types -31 to -34. - -Wed Mar 15 15:09:29 1995 Stu Grossman (grossman@cygnus.com) - - * findvar.c (read_register_bytes write_register_bytes): Make - these routines much smarter about updating registers from the - target, only doing so when absolutely necessary. This really - speeds up register modification on some remote targets. - - * monitor.c: More cleanups. Get rid of monitor_load_ascii_srec. - BFD makes this unnecessary. Lots of debugging speedups. - * (expect): NULL terminate return string. - * (monitor_open monitor_supply_register parse_register_dump - monitor_wait monitor_fetch_register): Switch to using GNU regexp - library to parse multi-register displays. - * (monitor_read_memory): Read multiple bytes (up to 16) at once. - * (monitor_create_inferior): Call clear_proceed_status to make run - command notice first breakpoint. - * (monitor_load): Clean up. Reset inferior_pid, set pc to start - address and reset symbol table stuff to make loads put things into - a fresh state. - * (monitor_load_srec): Lower sleep time to 1 second. - - * monitor.h (struct monitor_ops): Add register_pattern and - supply_register to monitor_ops. - - * rom68k-rom.c: Add new support for handling register dumps. - * config/m68k/tm-m68k.h: Define D0_REGNUM and A0_REGNUM for register - dump handling. - -Wed Mar 15 15:18:27 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * utils.c, defs.h (putchar_unfiltered, fputc_unfiltered): Make - argument be an int, not a char. Using a prototype followed by an - old-style function definition in a case where an argument is - widened is a GCC-ism not supported by the native AIX compiler. - -Wed Mar 15 12:22:35 1995 J.T. Conklin - - * nlmstub.def: Removed, this was moved to nlm/gdbserve.def - long ago. - - * configure.in (alpha-*-netware*): Removed configuration. - * config/alpha/{alpha-nw.mt, gdbserve.mt, tm-alphanw.h}: Removed. - * nlm/{README-ALPHA-NETWARE, aio.h, alpha-io.S, alpha-regdef.h, - alpha.c, alpha.h, altdebug.h}: Removed. - - * nlm/gdbserve.c (main): Add support for processing BOARD= - argument, deprecate NODE=. - -Wed Mar 15 10:58:26 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * c-exp.y (yylex): Make an empty character constant an error. - -Tue Mar 14 15:00:54 1995 Per Bothner - - * valops.c (value_arg_coerce): Do possible value_coerce_array - before determining type argument to value_cast. - -Tue Mar 14 10:41:41 1995 Kung Hsu - - * remote-es.c: Replace ignore with 0. - -Tue Mar 14 05:52:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valops.c (value_repeat), eval.c (evaluate_subexp_standard): - If VALUE_REPEATED is already set, just error out. - - * valops.c (value_cast, value_slice), parse.c (follow_types): Add - FIXME-type-allocation comments. - - * gdbtypes.h (struct type): Fix comment about what units the - TYPE_LENGTH is in. - -Mon Mar 13 18:27:25 1995 Stan Shebs - - * ch-valprint.c (annotate.h): Include. - * eval.c (evaluate_subexp_standard): Remove unused variable. - (calc_f77_array_dims): Add parens to expression. - * f-exp.y (yylex): Add parens to expression, remove unused label. - * f-lang.h (calc_f77_array_dims): Declare. - * f-valprint.c (f_val_print): Remove unused variables. - -Mon Mar 13 15:25:47 1995 Jim Kingdon - - * alpha-tdep.c (find_proc_desc): If pdr.framereg field is -1, don't - use the PDR, just examine prologues instead. - -Fri Mar 10 16:13:18 1995 Kung Hsu - - * config/arc/tm-arc.h: Change arc register names. - -Fri Mar 10 02:49:40 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - Fix problems with infinite recursion when printing a class - that contains a static instance of the class. - * cp-valprint.c (dont_print_vb_obstack): Renamed from - dont_print_obstack, made static. - (dont_print_statmem_obstack): New obstack, controls printing - of static member classes. - (_initialize_cp_valprint): Initialize it. - (cp_print_static_field): New function, handles printing of - static members. - (cp_print_value_fields): New parameter dont_print_statmem to - handle recursive printing of static member classes, use - cp_print_static_field to handle printing of static members. - * c-valprint.c (cp_print_value_fields): Update prototype and - call to include additional dont_print_statmem parameter. - * c-valprint.c, f-valprint.c (dont_print_obstack): Remove unused - extern declaration. - - * alpha-tdep.c, findvar.c, infptrace.c: Include . - - * config/alpha/tm-alpha.h (FRAME_FIND_SAVED_REGS): Call - alpha_find_saved_regs if fi->saved_regs is still NULL. - - * elfread.c (elf_symtab_read): Ensure that the filename field - of a minsym is nonempty. Ignore solib trampoline symbols from - the main symbol table, they might have a bogus value. - - * procfs.c (set_proc_siginfo), config/alpha/alpha-osf2.mh: - Fix typos in comments. - -Thu Mar 9 17:19:47 1995 Jim Kingdon - - * mdebugread.c (parse_symbol, psymtab_to_symtab_1): Initialize - pdr.framereg field of MIPS_EFI_SYMBOL_NAME symbol to -1. That way - we know whether the PDR ever got set. - * mips-tdep.c (find_proc_desc): If pdr.framereg field is -1, don't - use the PDR, just examine prologues instead. - -Wed Mar 8 23:35:10 1995 Jeff Law (law@snake.cs.utah.edu) - - * somsolib.c (som_solib_section_offsets): Get offset of text - section right. - -Wed Mar 8 16:12:21 1995 Stu Grossman (grossman@cygnus.com) - - - * source.c (forward_search_command reverse_search_command): Set - convenience variable $_ to be the line # of the match. - * symtab.c (decode_line_1): Allow convenience variables to be - used in line specs (for breakpoints and such). - -Wed Mar 8 12:51:00 1995 Stan Shebs - - * Makefile.in (VERSION): Bump to 4.14.1. - * NEWS, README: Update for 4.14. - * i386v-nat.c (i386_insert_aligned_watchpoint): Fix declaration. - (i386_insert_nonaligned_watchpoint): Call aligned instead of - generic watchpoint insertion. - -Tue Mar 7 19:26:10 1995 Per Bothner - - * valops.c (value_slice): Do COERCE_VARYING_ARRAY. - -Tue Mar 7 00:23:47 1995 Stu Grossman (grossman@cygnus.com) - - * monitor.c, array-rom.c, monitor.h, rom68k-rom.c: Move target_ops - into monitor.c. - * monitor.c (monitor_create_inferior): Allow run command to start - program. - - * monitor.c (monitor_load): Set PC to start address when done - loading. - - * array-rom.c, monitor.h, rom68k-rom.c: Clean up target_ops. - Remove ref to monitor_create_inferior. - - * monitor.c: More general cleanups. Add prototypes, remove - unused routines. Fix bug with wrong number of args to error(). - - * main.c (main): Don't start up GUI when running under gdb mode - in emacs. - - * Makefile.in: Add rules for monitor.o and rom68k-rom.o to make - Sun make (with VPATH) work... - - * monitor.c, monitor.h, rom68k-rom.c: Serious cleanup to make IDP - (rom68k) target work right. - * array-rom.c, op50-rom.c, w89k-rom.c: Partial updates to new - monitor.c interface. More work needs to be done here. - * config/m68k/tm-monitor.h: Change DECR_PC_AFTER_BREAK to 0 to - match the IDP monitor. Also, set NUM_REGS to 18 cuz there's no - floating-point for this card. - - * serial.h, ser-go32.c, ser-mac.c, ser-tcp.c, ser-unix.c: Add - SERIAL_SETSTOPBITS to set the number of stopbits (needed for IDP - board?!?!?). - - * defs.h, utils.c, remote-hms.c, remote-pa.c, remote.c: Fix defs - and usage of fputc_unfiltered and putchar_unfiltered. Eliminate - putc_unfiltered (it's superfluous). - - * command.h, command.c, top.c: Add var_enum command type. It's - like var_string but allows only only one of the specified strings. - -Mon Mar 6 15:03:59 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valops.c (value_cast): Don't use backslash newline--pre-ANSI - compilers (such as SunOS4 /bin/cc) don't generally support it - except in some contexts. - -Fri Mar 3 17:42:48 1995 Per Bothner - - * valops.c (value_cast): Check for cast to array type *before* - we coerce array to pointer (in case arg2 is already array). - - * valops.c (call_function_by_hand): Set using_gcc to 2 if using - gcc2. Needed for REG_STRUCT_HAS_ADDR to work on sparc. - Also check REG_STRUCT_HAS_ADDR for union, array and string types. - - * valops.c (call_function_by_hand): Re-arrange code for pushing - paramaters on the stack so we can do better STACK_ALIGN. - - * valops.c (call_function_by_hand): Call error if the number - of arguments is fewer than parameter types in function type. - -Fri Mar 3 17:13:05 1995 Doug Evans - - * sparc-tdep.c (sparc_extract_struct_value_address): Move - sparc64 support to here. - (sparc64_extract_struct_value_address): Deleted. - (dump_ccreg): Add a prototype so long long arg -> int. - * sparc/tm-sp64.h (USE_STRUCT_CONVENTION): Define. - (EXTRACT_STRUCT_VALUE_ADDRESS): Delete. - -Fri Mar 3 15:12:12 1995 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (hpread_record_lines): New argument "offset". All - callers changed. Use it to handle dynamic address relocation. - (hpread_build_psymtabs): Adjust texthigh as we read each function - debug symbol. Fix computation of texthigh. - (hpread_read_subrange_type): Work around macro bugs in HP's - compilers. - (hpread_process_one_debug_symbol): Correctly map source lines. - - * somread.c (check_strange_names): Filter names emitted by the HP - compiler when generating PIC code. - - * valops.c (value_struct_elt_for_reference): Work around macro - bugs in HP's compilers. - * c-exp.y (block): Likewise. - -Fri Mar 3 12:27:28 1995 Jim Kingdon - - * rs6000-tdep.c (push_dummy_frame): Fix order of arguments to - store_address. - - * utils.c [_AIX]: Include stddef.h instead of #defining size_t. - -Fri Mar 3 12:33:24 1995 Michael Meissner - - * rs6000-tdep.c (skip_prologue): Skip multiple stores of the saved - registers that GCC emits on the PowerPC by default in addition to - the store multiple instruction used on the Power series. - -Fri Mar 3 00:54:58 1995 Doug Evans - - * sparc-tdep.c (decode_asi): New function. - (sparc_print_register_hook): Pretty print more v9 registers. - * sparc/tm-sp64.h (REGISTER_NAMES): Fix some typos. - -Thu Mar 2 22:20:22 1995 Doug Evans - - * dwarfread.c (struct dieinfo): Use CORE_ADDR for at_{low,high}_pc. - (target_to_host): Change result type to CORE_ADDR. - -Thu Mar 2 15:13:04 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * rs6000-tdep.c: Fix byte-swapping sins. - -Thu Mar 2 16:48:45 1995 Michael Meissner - - * rs6000-tdep.c (branch_dest): Minor code cleanup, don't share - code between branch unconditional and branch conditional cases. - -Wed Mar 1 09:41:26 1995 Doug Evans - - Various changes for sparc64. - * sparc-tdep.c (NUM_SPARC_FPREGS): Define. - (SPARC_INTREG_SIZE): Define. - (*): Use SPARC_INTREG_SIZE instead of REGISTER_RAW_SIZE (intreg) - where appropriate. - (enum branch_type): New value `done_retry'. - (isbranch): Renamed from isannulled. All callers changed. - Support new sparc64 branch insns. - (single_step): Handle done_retry. - (sparc_extract_struct_value_address): Don't assume 4 byte regs. - (get_saved_register): Likewise. - (sparc_push_dummy_frame): Likewise. - (sparc_frame_find_saved_regs): Likewise. - (sparc_pop_frame): Likewise. Don't refer to FPS_REGNUM, CPS_REGNUM, - or PS_REGNUM if not sparc64. sparc64 has 64 fp regs. - (sparc64_extract_struct_value_address): New function. - (dump_ccreg, sparc_print_register_hook): Likewise. - * sp64-tdep.c: Deleted. - * sparc/tm-sp64.h (GDB_TARGET_IS_SPARC64): Define. - (NUM_REGS): Reduce by 2, cle/tle are in the pstate reg. - (CC_HAS_LONG_LONG): Define. - (REGISTER_NAMES): Delete cle/tle and reorganize. - (PS_REGNUM, FPS_REGNUM, CPS_REGNUM): Delete, they're ifdef'd out of - sparc-tdep.c now. - (REGISTER_BYTES): Update. - (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Delete. - (EXTRACT_RETURN_VALUE): Delete. Use definition in tm-sparc.h. - (NO_SINGLE_STEP): Likewise. - * sparc/tm-sparc.h (EXTRACT_VALUE_RETURN): Don't assume 4 byte regs. - * sparc/sp64.mt: Move simulator support ... - * sparc/sp64sim.mt: ... to here. - -Wed Mar 1 13:14:42 1995 Kung Hsu - - * remote-vx960.c: new file for target specific register packaging. - * remote-vx68.c: ditto. - * config/i960/vxworks960.mt: add remote-vx960.o. - * config/m68k/vxworks68.mt: add remote-vx68.o. - -Wed Mar 1 13:42:49 1995 Michael Meissner - - * remote.c (remote_wait): Make calls to strtol be type correct by - passing the address of a char * pointer instead of an unsigned - char *. - - * rs6000-tdep.c (push_dummy_frame): Cast sp to char * when calling - write_memory to make things type correct. - -Wed Mar 1 12:17:31 1995 Michael Meissner - - * ch-exp.y, c-exp.y, f-exp.y, m2-exp.y (yy defines): Support the - standard Linux yacc by adding more names to be redefined with a - prefix. - -Tue Feb 28 22:55:47 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * hppa-tdep.c (pa_print_registers), monitor.c: Use - extract_unsigned_integer and friends, not SWAP_TARGET_AND_HOST. - * defs.h, findvar.c: Move SWAP_TARGET_AND_HOST back to findvar.c. - Rename it to SWAP_FLOATING to make it clear it is no longer for - integers. - -Tue Feb 28 14:38:39 1995 Kung Hsu - - * defs.h (SWAP_TARGET_AND_HOST): check endianess at runtime not - compile time. - * arc-tdep.c (_initialize_arc_tdep): set tm_print_insn according to - processor. - - * vx-share/ptrace.h: merge in WRS new ptrace requests. - - * defs.h: fix a syntax error. - - * a29k-tdep.c (get_longjmp_target): add this function, from WRS. - * remote-vx.c: move read_register and write_register out to - target specific files. - * remote-vx29k.c (get_fp_contnets): add this function, from WRS. - - * defs.h: define SWAP_TARGET_AND_HOST macro. - * findvar.c, monitor.c, hppa-tdep.c: remove definition of - SWAP_TARGET_AND_HOST. - -Tue Feb 28 08:31:40 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * alpha-tdep.c (find_proc_desc): Only attempt to set - PROC_LOCALOFF (found_heuristic) if found_heuristic is non-NULL. - -Mon Feb 27 11:56:32 1995 Stan Shebs - - * monitor.c: General gcc -Wall lint cleanup and reformat. - (monitor_command): If no args, send an empty command. - -Thu Feb 23 21:07:25 1995 Stu Grossman (grossman@cygnus.com) - - * monitor.c (monitor_load_ascii_srec): Add a one second sleep - after send LOAD_CMD to prevent loss of first S-record. - -Tue Feb 21 20:48:42 1995 Per Bothner - - * valops.c (call_function_by_hand): Set using_gcc to 2 if gcc-2. - Call error if too few arguments. - If REG_STRUCT_HAS_ADDR (structs passed by invisible reference), - copy and convert to reference *before* we calculate alignment. - Also, make sure structs allocated for return values and invisible - reference don't violate STACK_ALIGN. - -Tue Feb 21 23:29:59 1995 Per Bothner - - * ch-exp.y (expression_conversion): Recognize 'ARRAY () TYPE (EXPR)' - (same as C's '(TYPE[])EXPR') - -Tue Feb 21 11:47:26 1995 Stan Shebs - - * top.c (print_gdb_version): Update the year. - -Sun Feb 19 14:31:57 1995 Jim Kingdon - - * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Look for newlib in - `..' not in `../..'. - -Sun Feb 19 11:05:28 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * procfs.c (unconditionally_kill_inferior): Don't issue a PIOCKILL - in addition to a PIOCSSIG to kill the inferior. - -Thu Feb 16 15:06:12 1995 Per Bothner - - * parse.c (follow_types): Given (TYPE[]) (i.e. with no length), - create a 0-length array type, and set BOUND_CANNOT_BE_DETERMINED. - * valops.c (value_cast): If a cast like (TYPE[])VALUE (i.e. array - of unknown length) use sizeof(VALUE)/sizeof(TYPE) as the length. - * c-typeprint.c (c_type_print_varspec_suffix): If array length - is 0, print it, but not if upper_bound is BOUND_CANNOT_BE_DETERMINED. - -Thu Feb 16 16:06:50 1995 Michael Meissner - - * dcache.c (insque, remque): Rewrite Linux support. - -Wed Feb 15 12:33:20 1995 Michael Meissner - - * config/powerpc/tm-ppc-eabi.h (TEXT_SEGMENT_BASE): Define as 1. - - * dcache.c (insque, remque): If compiling in standard C on Linux, - protect insque and remque with macros to cast the pointer - arguments to the proper type. - -Tue Feb 14 17:16:41 1995 Stu Grossman (grossman@cygnus.com) - - * annotate.c, breakpoint.c, defs.h, top.c: Replace - enable/disable_breakpoint_hook with modify_breakpoint_hook. - -Tue Feb 14 16:58:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * expression.h: Move declaration of evaluate_subexp_with_coercion - from here... - * value.h: ...to here. - * expression.h: Don't include value.h - -Tue Feb 14 11:46:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * expression.h: Move include of value.h until after declaration of - enum exp_opcode. - -Sun Feb 12 13:47:30 1995 Stan Shebs - - * remote-e7000.c: Comprehensive cleanup; removal of dead code, - simplify code, declare things, format to standards. - (inferior.h, value.h, command.h, remote-utils.h): Include. - (e7000_login): Rename to e7000_login_command. - (e7000_ftp): Rename to e7000_ftp_command. - (e7000_drain): Rename to e7000_drain_command. - - * irix5-nat.c (string.h): Include near beginning of file. - -Sun Feb 12 12:36:38 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * valops.c (value_arg_coerce): Use VALUE_TYPE not SYMBOL_TYPE on - arg, it is a value not a symbol. - - gcc -Wall lint: - * eval.c: Move declaration of evaluate_subexp_with_coercion from here.. - * expression.h: ..to here. - * expression.h: Include value.h. - * ch-lang.c (evaluate_subexp_chill): Add default case in switch. - -Sun Feb 12 11:03:47 1995 Per Bothner - - * language.h (struct language_defn): New field evaluate_exp. - * c-lang.c (c_language_defn, cplus_language_defn, asm_langauge_defn), - f-lang.c (f_language_defn), language.c (unknown_language_defn, - auto_language_defn, local_language_defn), m2-lang.c (m2_language_defn): - Set evaluate_exp to evaluate_subexp_standard. - * ch-lang.c (evaluate_subexp_chill): New function. Chill-specific - support for MULTI_SUBSCRIPT. - (chill_language_defn): Set evaluate_exp to evaluate_subexp_chill. - * eval.c (enum noside): Move from here .... - * expression.h (enum noside): ... to here. - (evaluate_subexp_standard): New prototype. - * eval.c (evaluate_subexp): Renamed to evaluate_subexp_standard. - Removed lo-longer-needed test for chill_varying_type. - (evaluate_subexp): New. Calls exp->language_defn->evaluate_exp. - - * ch-exp.y (maybe_expression_list): New non-terminal. - (primitive_value): Allow empty parameter list. - -Sun Feb 12 10:02:16 1995 Per Bothner - - * buildsym.c (finish_block): If finishing a function without known - parameter type info, set that from parameter symbols. - * c-typeprint.c (c_type_print_varspec_suffix): For TYPE_CODE_FUNC, - print parameter types, if available. - * ch-typeprint.c (chill_type_print_base): Likewise. - - * gdbtypes.h (struct type): Remove function type field. - (TYPE_FUNCTION_TYPE): Remove macro. We can't as simply re-use - function types now that we're also storing parameter types. - And the payoff is much less. - * gdbtypes.c (make_function_type): Don't use/set TYPE_FUNCTION_TYPE. - (recursive_dump_type): Don't print TYPE_FUNCTION_TYPE. - * dwarfread.c (read_subroutine_type): Don't set TYPE_FUNCTION_TYPE. - - * valops.c (value_arg_coerce): Now takes param_type argument. - (call_function_by_hand): Convert arguments with value_arg_coerce - early, and overwrite original args with converted args. - No longer need multiple calls to value_arg_coerce. - (value_arg_push): Removed. - * hppa-tdep.c (hppa_push_arguments): No longer call value_arg_coerce. - * mips-tdep.c (mips_push_arguments): Likewise. - * alpha-tdep.c (alpha_push_arguments): Likewise. - * rs6000-tdep.c (push_arguments, ran_out_of_registers_for_arguments): - Likewise. - * value.h (value_arg_coerce): Remove declaration. (It's now static.) - - * valops.c (value_cast): Do COERCE_VARYING_ARRAY after COERCE_REF. - - * symtab.c (add_param_to_type): Remove (commented-out) function, - since that functionality has been re-written. - * coffread.c: Remove commented-out add_param_to_type support. - * mdebugread.c (parse_symbol): Likewise. - * stabsread.c (define_symbol): Likewise. - -Sun Feb 12 09:03:47 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * buildsym.c (start_subfile): Set language for f2c like for cfront. - -Thu Feb 9 20:20:11 1995 Rob Savoye - - * op50n-rom.c: Add the control registers. - -Thu Feb 9 15:46:39 1995 Stan Shebs - - * Makefile.in (CLIBS): Add $(LIBIBERTY) before, in addition to - after, any host/target/native libraries. - * dcache.c (insque, remque): Remove declarations. - * gdbtypes.h (type_code): Remove trailing comma. - - From Peter Schauer: - * xcoffread.c (read_xcoff_symtab) [C_HIDEXT]: Move #ifdef - STATIC_NODEBUG_VARS inside case. - -Thu Feb 9 07:43:41 1995 Jim Kingdon - - * config/sparc/tm-sun4sol2.h: Define STATIC_TRANSFORM_NAME. - * partial-stab.h: Call it. - * stabsread.c (define_symbol) [STATIC_TRANSFORM_NAME]: Call - STATIC_TRANSFORM_NAME to get the name and use minimal symbols to - get the address. - * sparc-tdep.c (solaris_static_transform_name): New function. - -Thu Feb 9 12:09:09 1995 Jeff Law (law@snake.cs.utah.edu) - - * somread.c (som_symtab_read): Handle dynamic relocation for both - text and data symbols. - (som_symfile_offsets): If objfile is a shared library, then get - text and data offsets from the shared library structures. - * somsolib.c (som_solib_add): Copy the bfd pointer from the - objfile rather than reopening the file again. - (som_solib_section_offsets): New function. - * somsolib.h (som_solib_section_offsets): Declare. - -Wed Feb 8 20:32:18 1995 Jim Kingdon - - * config/sparc/tm-sun4sol2.h, dbxread.c: Rename - N_SO_ADDRESS_MAYBE_MISSING to SOFUN_ADDRESS_MAYBE_MISSING. - * symtab.h (minimal_symbol) [SOFUN_ADDRESS_MAYBE_MISSING]: Add - filename field. - * elfread.c (record_minimal_symbol_and_info), - minsyms.c, symtab.h (prim_record_minimal_symbol_and_info): Return - newly created symbol. - * elfread.c (elf_symtab_read) [SOFUN_ADDRESS_MAYBE_MISSING]: - Set filename field of minimal symbol. - * symmisc.c (dump_msymbols) [SOFUN_ADDRESS_MAYBE_MISSING]: - Print filename field. - * minsyms.c, symtab.h (lookup_minimal_symbol): New arg sfile. - * symm-tdep.c, somsolib.c, hppa-tdep.c, c-exp.y, f-exp.y, - m2-exp.y, nindy-tdep.c, m3-nat.c, irix5-nat.c, hpread.c, - os9kread.c, breakpoint.c, alpha-tdep.c, valops.c, symtab.c, - printcmd.c, dbxread.c: Change callers to pass NULL for sfile. - * dbxread.c (process_one_symbol) [SOFUN_ADDRESS_MAYBE_MISSING]: - Find address of function from minimal symbols. - * partial-stab.h, case 'f', 'F': Call find_stab_function_addr - instead of getting pst->textlow from the stab. - * minsyms.c (find_stab_function_addr): New function. - -Wed Feb 8 19:19:56 1995 Rob Savoye - - * monitor.c: Fix so all the output shows up in the GUI command - window. - -Mon Feb 6 18:50:59 1995 Stan Shebs - - * i386-tdep.c (_initialize_i386_tdep): Put void decl on separate - line, so init.c generation works correctly. - * arc-tdep.c (_initialize_arc_tdep): Ditto. - -Mon Feb 6 14:44:36 1995 Rob Savoye - - * config/mips/idt.mt: Add support for the lsi33k target. - * config/sparc/sun4sol2.mh: Add support for ser-tcp. - * array-rom.c: Finish the rest of the support commands needed by - GDB. - * mips-tdep.c: Add LSI33k register names and processor type. - -Sat Feb 4 13:29:52 1995 Stan Shebs - - * config/m68k/est.mt (TDEPFILES): Remove m68k-pinsn.o. - -Fri Feb 3 11:19:20 1995 Stu Grossman (grossman@cygnus.com) - - * core.c (dis_asm_read_memory), defs.h, top.c: Get rid of - dis_asm_read_memory_hook. We can now call the disassemblers - directly and have no need for this hook anymore. - * defs.h, printcmd.c: Make print_insn be static. - - * ser-go32.c (dos_comisr): Make this 8 bit clean. - * (dos_open dos_close): Allow multiple opens to the same device. - Use a ref count to prevent unwanted deallocations. - * sparcl-tdep.c: Put #ifdefs around all socket stuff to make GO32 - happy. - * (sparclite_ops): Switch to download_stratum. - * target.h (enum strata): Move download_stratum before - process_stratum so that executable targets get pushed on top of - download targets. - -Thu Feb 2 19:02:45 1995 Rob Savoye - - * array-rom.c: Remove the non GDB remote protocol config stuff. - - * monitor.c: All reading/writing functions for memory and - registers work. - -Thu Feb 2 16:11:04 1995 Kung Hsu - - * config/arc/arc.mt: new target makefile for arc processor. - * config/arc/tm-arc.h: new target header for arc processor. - * config/arc/go32.mh: new go32 host makefile for arc processor. - * config/arc/xm-go32.h: new go32 host header for arc processor. - * arc-tdep.c: new target dependent codes for arc processor. - -Thu Feb 2 13:58:40 1995 Stan Shebs - - * Makefile.in (VERSION): Bump to 4.13.2. - -Thu Feb 2 07:27:56 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - Fix compiler warnings: - * remote-e7000.c (printf_e7000debug): Rename to puts_e7000debug - and have the caller do the sprintf. Saves us from varargs hell. - (normal): Define before use. - * remote-e7000.c: Reindent a few things. - -Wed Feb 1 21:16:42 1995 Per Bothner - - * f-typeprint.c (f_type_print_varspec_suffix): Print array index - ranges in reverse order. - * f-valprint.c (f77_create_arrayprint_offset_tbl): Fix calculation. - - * eval.c (evaluate_subscript): Don't call value_subscript, since - it adjusts for lower bound and enforces ranges. - - * expression.h (exp_code): Remove MULTI_F77_SUBSCRIPT, OP_F77_SUBSTR. - * eval.c, parse.c: Removed uses of removed opcodes. - * eval.c (evaluate_subexp): Clean up handling of - OP_UNDETERMINED_ARGLIST (no backtracking, more general). - - * f-valprint.c (f_val_print): Print TYPE_CODE_STRING using - LA_PRINT_STRING, and not val_print_string (which reads from inferior). - - * ch-lang.c (chill_is_varying_struct), ch-lang.h: Remve function - duplicate function made redundant by chill_varying_type. - - Re-write of f77 string and complex number support: - - * language.h (struct language_defn): New fields string_lower_bound - and string_char_type. - * c-lang.c (c_language_defn, cplus_language_defn, asm_language_defn), - language.c (unknown_language_defn, auto_language_defn, - local_language_defn), m2-lang.c (m2_language_defn), f-lang.c - (f_language_defn), ch-lang.c (chill_language_defn): Set new fields. - * gdbtypes.c (create_string_type): Use new string_char_type field. - * valops.c (value_string): Use new string_lower_bound field. - - * defs.h (TARGET_COMPLEX_BIT, TARGET_DOUBLE_COMPLEX_BIT): Removed. - * f-lang.c (f_create_fundamental_type, _initialize_f_language), - m2-lang.c (m2_create_fundamental_type), - gdbtypes.c (_initialize_gdbtypes): Set TYPE_TARGET_TYPE of complex - types. Set their TYPE_CODEs to TYPE_CODE_COMPLEX. - * mdebugread.c (mdebug_type_complex, mdebug_type_double_complex): - Removed. Use builtin_type_complex and builtin_type_double_complex. - - * gdbtypes.h (enum type_code): Removed TYPE_CODE_LITERAL_STRING - and TYPE_CODE_LITERAL_COMPLEX. - * c-typeprint.c, f-typeprint.c, f-valprint.c, eval.c: Removed uses of - TYPE_CODE_LITERAL_STRING and TYPE_CODE_LITERAL_COMPLEX. - * gdbtypes.c, gdbtypes.h (f77_create_literal_complex_type, - f77_create_literal_string_type): Removed. - * value.h (VALUE_LITERAL_DATA, VALUE_SUBSTRING_MEMADDR, - VALUE_SUBSTRING_MYADDR): Removed. - - * expression.h (enum exp_opcode): Rename OP_F77_LITERAL_COMPLEX to - OP_COMPLEX. - * parse.c: Update accordingly. - - * f-valprint.c (f77_print_cmplx): Removed. - (f_val_print case TYPE_CODE_COMPLEX): Re-write to use print_floating. - - * f-exp.y (STRING_LITERAL): Use OP_STRING instead of OP_ARRAY. - * eval.c (evaluate_subexp): For case OP_ARRAY, don't call - f77_value_literal_string. - * valops.c, value.h (f77_value_literal_string, f77_value_substring, - f77_assign_from_literal_string, f77_assign_from_literal_complex): - Removed. - (value_assign): No longer need to handle literal types. - * valops.c (f77_value_literal_complex), value.h: Re-written and - renamed to value_literal_complex. Last arg is now a (complex) type. - * valops.c (f77_cast_into_complex): Re-written and renamed to - cast_into_complex. - * eval.c (evaluate_subexp): Update accordingly. - - * ch-valprint.c (chill_val_print): On TYPE_CODE_STRING, don't - print address for non-'s'-formats. - * ch-typeprint.c, ch-valprint.c: Use chill_varying_type instead - of chill_is_varying_struct. - -Wed Feb 1 13:27:33 1995 Stan Shebs - - gcc -Wall lint. - * alpha-tdep.c (alpha_in_lenient_prologue): Comment out. - (after_prologue): Remove unused local b. - * procfs.c (thread.h): Include. - (pr_flag_table, pr_why_table, faults_table, siginfo_table): Use - nested braces in initializer. - * top.c (initialize_targets, initialize_utils): Declare. - (locate_arg, insert_args): Add parens around tested assignments. - * remote-utils.c (sr_scan_args): Remove decl of strtol. - * remote.c (thread.h): Include. - (remote_wait): Remove unused local p2. - * sparc-tdep.c (fill_gregset, fill_fpregset): Remove decls of - registers array. - - defs.h (stdlib.h): Include. - (exit, perror, atoi, qsort, memcpy, memcmp): Don't declare. - (fclose, atof, malloc, realloc, free, strchr, strrchr, strstr, - strtok, strerror): Don't specify parameter types in declaration. - -Wed Feb 1 12:23:57 1995 Per Bothner - - * ch-exp.y (value_string_element, string_primitive_value, - start_element, left_element, right_element, slice_size, - lower_element, upper_element, first_element): Removed. - (value_string_slice, value_array_slice): Replaced by ... - (slice): New non-terminal, with working slice support. - (primitive_value_lparen, rparen): New non-terminals. - (maybe_tuple_elements): New non-terminal, to allow empty tuples. - (idtokentab): Added "up". - - * value.h (COERCE_VARYING_ARRAY): New macro. - * valarith.c (value_subscript): Use it. - * valops.c (value_cast): Likewise. Also, do nothing if already - correct type, and allow converting from/to range to/from scalar. - - * valops.c, value.h (varying_to_slice, value_slice): New functions. - * eval.c (OP_ARRAY): Add cast for array element. - * expression.h (TERNOP_SLICE, TERNOP_SLICE_COUNT): New exp_opcodes. - * valops.c (chill_varying_type): Moved function frp, here ... - * gdbtypes.c (chill_varying_type), gdbtypes.h: ... to here. - * parse.c (length_of_subexp, prefixify_subexp): Add support - for TERNOP_SLICE, TERNOP_SLICE_COUNT. - * expprint.c (print_subexp, dump_expression): Likewise. - * eval.c (evaluate_subexp): Likewise. - - * eval.c (evaluate_subexp case MULTI_SUBSCRIPT): Don't call - value_x_binop on a Chill varying string. - -Tue Jan 31 13:51:53 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config/m68k/monitor.mt, - config/pa/{hppabsd.mt,hppahpux.mt,hppaosf.mt,hppapro.mt}: Put - depfiles in TDEPFILES not REMOTE_O. - -Tue Jan 31 11:14:44 1995 Steve Chamberlain - - From nigel@algor.co.uk. - * ser-go32.c (dos_close): Don't crash if scb null. - (dos_sendbreak): New function. - (dos_ops): Point to dos_sendbreak. - (dos_info): Calculate COM number correctly. - -Tue Jan 31 09:40:11 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * xcoffread.c (process_xcoff_symbol): Use new variables - func_symbol_type and var_symbol_type as type of functions and - variables which don't have any stabs associated with them. - Reindent most of function. - (_initialize_xcoffread): Initialize *_symbol_type. - - * xcoffread.c (read_xcoff_symtab): Reindent most of function. - Put C_HIDEXT symbols in the minimal symbols, rather than ignoring - them (this part commented out as I didn't quite get it to work). - (cs_to_section, find_targ_sec): New functions, to support above code. - * xcoffread.c (RECORD_MINIMAL_SYMBOL): Only skip '.' if it is - actually present. - -Mon Jan 30 17:34:24 1995 Stu Grossman (grossman@cygnus.com) - * sparcl-tdep.c: Add `sparclite' target for doing serial and udp - downloads to SPARClite demo boards. - -Sun Jan 29 09:43:22 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remote.c, remote-pa.c: Remove #if 0'd icache code. It has had - no hope of working as is for a long time (in particular, shebs' 27 - Jan 95 change confuses the issue further--target_read_memory and - xfer_core_file do *not* do the same thing in this context). - Revise comment. - -Sat Jan 28 13:40:46 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * elfread.c (elf_symtab_read): Do not test BSF_GLOBAL for - procedure linkage table symbols, it is no longer set due to the - Jan 6 BFD change in bfd/elfcode.h. - -Fri Jan 27 17:08:06 1995 Stan Shebs - - * top.c (use_windows): Clarify comments. - - * convex-tdep.c (xfer_core_file): Comment out. - * config/convex/tm-convex.h (XFER_CORE_FILE): Remove. - * remote.c, remote-pa.c (remote_fetch_word): Change xfer_core_file - references to target_read_memory. - * gdbcore.h (xfer_core_file, core_open, core_detach): Remove - declarations. - * corelow.c (core_open, core_detach): Make static. - - * arm-tdep.c: Make it compile. - (exec_file_command, xfer_core_file): Comment out. - (arm_print_insn): Remove, now in libopcodes. - (skip_prologue): Comment out most of body. - (arm_frame_find_saved_regs): Move here from tm-arm.h. - (_initialize_arm_tdep): Set tm_print_insn. - * config/arm/tm-arm.h: Remove old refs to first_object_file_end. - (XFER_CORE_FILE): Remove. - (FRAME_FIND_SAVED_REGS): Call arm_frame_find_saved_regs. - -Fri Jan 27 08:48:28 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (CHILL_LIB): Define as in testsuite/Makefile.in. - -Thu Jan 26 18:24:41 1995 Jim Kingdon - - * symtab.c (find_pc_line): When subtracting one to get a line - number, make sure not to end up with zero. - - * remote-vx.c: Revert all of Kung's changes of 16 Jan. The - problems with those changes were (a) the file didn't compile, (b) - they changed memset to bzero--memset is correct, (c) they took out - code to deal with boards lacking floating point, (d) who knows - what I didn't discover in a quick read. - -Thu Jan 26 17:32:54 1995 Stu Grossman (grossman@cygnus.com) - - * sparcl-tdep.c: Clean up formatting and indentation. - -Thu Jan 26 10:49:59 1995 Steve Chamberlain - - * remote-hms.c (hms_ops): Change ref of hr_load_image - to gr_load_image. - (dcache_flush, dcache_hit, dcache_value, dcache_fetch, - dcache_poke, dcache_init): Deleted. - (hms_open, hms_resume, hms_fetch_word, hms_store_word): - Use dcache routines provided by remote-util.h - -Thu Jan 26 12:08:31 1995 Michael Meissner - - * configure.in: Add support for powerpc-*-eabi. - - * powerpc/tm-ppc-eabi.h, powerpc/pcc-eabi.mt: New files for - PowerPC support. - -Wed Jan 25 18:13:14 1995 Per Bothner - - * language.h (struct language_defn): New field c_style_arrays. - * language.c (unknown_language_defn, auto_language_defn, - local_language_defn), c-lang.c (c_language_defn, cplus_language_defn, - asm_language_defn): Set c_style_arrays to true. - * m2-lang.c (m2_language_defn), ch-lang.c (chill_language_defn), - f-lang.c (f_language_defn): Set c_style_arrays to false. - * valops.c (value_string): If c_style_array is not set, - allocate string in gdb (not inferior) using allocate_value. - - * value.h (COERCE_ARRAY), valops.c (value_addr, value_arg_coerce): - Only call value_coerce_array if current_language->c_style_arrays. - * values.c: Add #include "language.h". (Needed for COERCE_ARRAY.) - - * valops.c (chill_varying_type): New predicate. - * valops.c (value_cast): Support assigning a fixed string or array - to a variable string/array structure. - - * valarith.c (value_subscripted_rvalue): Extra parameter lowerbound. - Check index>=lowerbound, and then add lowerbound to index here, - instead of in caller. Generalize to arbitrary lval_types. - (value_subscript): Use enhanced value_subscripted_rvalue if - c_style_arrays is false (and index is in range). - - -Wed Jan 25 18:13:14 1995 Per Bothner - - * eval.c (evaluate_subexp case OP_ARRAY): Fix calls to memset: - TYPE_LENGTH is length in bytes, not bits. - -Wed Jan 25 08:19:35 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * infrun.c (proceed): Flush stdout before resuming inferior. - * infcmd.c (step_1), annotate.c (annotate_starting): - Don't bother to flush here. - -Wed Jan 25 01:11:21 1995 Jeff Law (law@snake.cs.utah.edu) - - * hpread.c (hpread_process_one_debug_symbol): Fix lines garbled - by an ill-advised global search and replace. - -Mon Jan 23 13:11:46 1995 Per Bothner - - Add support for Chill bitstring literals (e.h. H'FF00'). - * ch-exp.y (match_bitstring_literal): Fix for proper endianness. - * expprint.c (print_subexp): Don't call error on OP_BITSTRING, - just print B''. - * gdbtypes.c (create_set_type): Fix bug in length calculation. - * valops.c, value.h (value_bitstring): New function. - * eval.c (evaluate_subexp): Implement support for OP_BITSTRING. - - * ch-typeprint.c (chill_type_print_base): For TYPE_CODE_FUNC, - check that return type is non-void, and print in proper Chill syntax. - -Mon Jan 23 12:20:34 1995 Rob Savoye - - * Makefile.in: Remove references to remote-mon.c. - * remote-mon.c: remove. Replaced by rom68k-rom.c. - * rom68k-rom.c: Support for Rom68k monitor. - -Mon Jan 23 10:50:57 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (CHILL_FOR_TARGET): Update -L argument to point to - gcc/ch/runtime not chillrt, since that is where the chill runtime - lives now. - -Mon Jan 23 00:06:57 1995 Steve Chamberlain - - * remote-hms.c (hms_load): Delete. - (target_ops): Use hr_load_image. - - * remote-e7000.c, remote-z8k.c, remote-nindy.c (target_ops): - Define memory_insert/remove_breakpoint. - * xm-go32.h: Remove redundant SIGs. - -Thu Jan 19 20:26:58 1995 Steve Chamberlain - - * ser-go32.c: Rewritten by nigel@algor.co.uk. - -Fri Jan 20 15:23:55 1995 Per Bothner - - * expression.h (OP_LABELED): New operator, for Chill - labeled structre tuples. - * ch-exp.y (tuple_element, named_record_element, tuple_elements): - New non-terminals, to handle labeled structure tuples. - (tuple): Re-define using tuple_elements. - * eval.c (evaluate_labeled_field_init): New function, to handle - initialization of structure fields, possibly using OP_LABELED. - (evaluate_subexp): Use it. - * expprint.c (print_subexp case): For OP_ARRAY, use Chill syntax - for Chill. Handled OP_LABELED. - * parse.c (length_of_subexp, prefixify_subexp): Handle OP_LABELED. - - * eval.c (evaluate_subexp): Handle Chill Powerset tuples. - * valarith.c (value_bit_index): Just treat bitstring as represented - by an array of bytes. Alignment is handled by compiler. - -Wed Jan 18 19:00:29 1995 Stan Shebs - - * h8300-tdep.c (gdb_print_insn_h8300): Fix typo (&info -> info). - * sh-tdep.c (gdb_print_insn_sh): Ditto. - -Wed Jan 18 11:25:43 1995 Kung Hsu - - * remote-os9k.c (rombug_open): Fix a bug in exception handling - command. - * remote-os9k.c (rombug_write_inferior_memory): reset buffer after - write. - -Tue Jan 17 09:48:38 1995 Jim Kingdon - - * parse.c (_initialize_parse): Improve wording of names of - msym_*_symbol_type. - -Tue Jan 17 14:00:58 1995 Ian Lance Taylor - - * config/mips/tm-mips.h (enum mips_fpu_type): New enum. - (mips_fpu): Change type to enum mips_fpu_type. - (FIX_CALL_DUMMY): Handle mips_fpu == MIPS_FPU_SINGLE. - * mips-tdep.c (mips_fpu): Change type to enum mips_fpu_type. - Don't initialize. - (mips_fpu_string): New static variable. - (mips_push_dummy_frame): Handle mips_fpu == MIPS_FPU_SINGLE. - (mips_pop_frame): Likewise. - (mips_extract_return_value): Likewise. - (mips_store_return_value): Likewise. - (mips_set_fpu_command): New static function. - (mips_show_fpu_command): New static function. - (_initialize_mips_tdep): Change handling of set/show mipsfpu. - -Tue Jan 17 09:48:38 1995 Jim Kingdon - - * a29k-tdep.c (gdb_print_insn_a29k): Fix typo (&info -> info). - - * parse.c (write_exp_msymbol): Use new variables - msym_*_symbol_type as type of msymbol expression. - (_initialize_parse): Initialize them. - -Mon Jan 16 18:11:03 1995 Stan Shebs - - General cleanup and simplication of disassembler interface. - * a29k-pinsn.c, arm-pinsn.c, convex-pinsn.c, gould-pinsn.c, - hppa-pinsn.c, i386-pinsn.c, i960-pinsn.c, m68k-pinsn.c, - m88k-pinsn.c, mips-pinsn.c, ns32k-pinsn.c, pyr-pinsn.c, - rs6000-pinsn.c, sparc-pinsn.c, tahoe-pinsn.c, vax-pinsn.c: Remove. - * gould-tdep.c, ns32k-tdep.c, tahoe-tdep.c, vax-tdep.c: New files, - had been -pinsn.c files. - * Makefile.in (ALLDEPFILES): Remove removed files. - (a29k-pinsn.o, arm-pinsn.o, convex-pinsn.o, gould-pinsn.o, - hppa-pinsn.o, i386-pinsn.o, i960-pinsn.o, m68k-pinsn.o, - m88k-pinsn.o, mips-pinsn.o, ns32k-pinsn.o, pyr-pinsn.o, - rs6000-pinsn.o, sparc-pinsn.o, tahoe-pinsn.o, vax-pinsn.o): - Remove compile actions. - * arm-tdep.o, gould-tdep.o, ns32k-tdep.o, tahoe-tdep.o, - vax-tdep.o: Add compile actions. - * defs.h (tm_print_insn): New global. - * a29k-tdep.c (gdb_print_insn_a29k): New function. - (_initialize_a29k_tdep): Rename from _initialize_29k, - set tm_print_insn. - * alpha-tdep.c (print_insn): Remove. - (_initialize_alpha_tdep): Set tm_print_insn. - * arm-tdep.c (arm_print_insn): New function, was print_insn - in arm-pinsn.c. - * convex-tdep.c (convex_print_insn): New function, was print_insn - in convex-pinsn.c. - * h8300-tdep.c (print_insn): Remove. - (gdb_print_insn_h8300): New function. - (_initialize_h8300_tdep): New function. - * h8500-tdep.c (print_insn): Remove. - (_initialize_h8500_tdep): New function. - * hppa-tdep.c (_initialize_hppa_tdep): Set tm_print_insn. - * i386-tdep.c (_initialize_i386_tdep): New function. - * i960-tdep.c (mem, next_insn): New functions, were in - i960-pinsn.c. - (_initialize_i960_tdep): Set tm_print_insn. - * m68k-tdep.c (_initialize_m68k_tdep): New function. - * m88k-tdep.c (_initialize_m88k_tdep): New function. - * mips-tdep.c (gdb_print_insn_mips): New function. - (_initialize_mips_tdep): Set tm_print_insn. - * pyr-tdep.c (pyr_print_insn): New function, was print_insn - in pyr-pinsn.c. - * rs6000-tdep.c (_initialize_rs6000_tdep): New function. - * sh-tdep.c (print_insn): Remove. - (gdb_print_insn_sh): New function. - (_initialize_sh_tdep): Set tm_print_insn. - * sparc-tdep.c (_initialize_sparc_tdep): New function. - * w65-tdep.c (print_insn): Remove. - (_initialize_w65_tdep): New function. - * z8k-tdep.c (print_insn): Remove. - (gdb_print_insn_z8k): New function. - (_initialize_z8k_tdep): Set tm_print_insn. - * printcmd.c (print_insn): New function, generic disassembler. - * config/*/*.mt (TDEPFILES): Remove refs to *-pinsn.o. - -Mon Jan 16 15:43:29 1995 Kung Hsu - - * Makefile.in: add new files remote-vx29k.c, config/a29k/tm-vx29k.h, - and config/a29k/vx29k.mt. - * configure.in: add new configuration a29k-*-vxworks. - * remote-vx29k.c: new file merged from WRS. - * remote-vx.c: merge changes from WRS. - * config/a29k/vx29k.mt: new file for new configuration. - * config/a29k/tm-vx29k.h: new header file for newconfiguration. - -Sun Jan 15 14:36:19 1995 Steve Chamberlain - - * breakpoint.h (disable_breakpoint, enable_breakpoint): - New declarations. - (enum bpdisp): Change name of 'delete' member to 'del'. - (struct bpstat): Changed name to 'bpstats'. - * breakpoint.c (disable_breakpoint, enable_breakpoint, - breakpoint_chain): Made globally visible. - (bpstat_stop_status): Use new name for bpstat. - (break_command_1, watch_command_1, catch_command_1, - breakpoint_auto_delete, denable_delete_breakpoint): Use 'del' - instead of 'delete'. - (set_breakpoint_sal): New function. - * defs.h (registers_changed_hook): New declaration. - * infcmd.c (run_stack_dummy): 'delete' is now 'del'. - * inflow.c (new_tty): Treat WIN32 in same way as __GO32__ - * main.c (main): Don't scan options when in WIN32 and exit - without entering main loop. - * m2-exp.y (m2_elx): Member 'class' is now 'aclass'. - * symtab.h (struct symbol, struct partial_symbol): Changed name of - member 'class' to 'aclass'. - (SYMBOL_CLASS, PSYMBOL_CLASS): Reflect change. - * top.c (registers_changed_hook): New definition. - * utils.c (quit, notice_quit, initialize_utils): Treate WIN32 - in same way as __GO32__. - * value.h (c_typedef_print): Rename 'new' argument. - - * w65-tdep.c, config/tm-w65.h, config/w65.mt: New files. - * configure.in: Suppprt for w65, - - -Sat Jan 14 11:18:11 1995 Jim Kingdon - - * infcmd.c (signal_command): For "signal 0", pass (CORE_ADDR)-1, - not stop_pc, to proceed. - - * eval.c (evaluate_subexp): Clear expect_type except for C++ and CHILL. - -Fri Jan 13 17:52:57 1995 Jim Kingdon - - * infcmd.c (signal_command): Accept "signal 0"; the change to not - accept it was accidental. "handle 0" and "info signal 0" remain - illegal, though. - -Fri Jan 13 15:19:01 1995 Stan Shebs - - * Makefile.in (all): Don't make libgdb-files. - (libgdb): New action, makes libgdb-files. - -Thu Jan 12 21:23:25 1995 Per Bothner - - * stabsread.c (read_enum_type): When pending enum symbols are - put into the enum type, they must be inserted in "backwards - order, in case we've overflowed a struct pending buffer. - - -Thu Jan 12 09:33:24 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * README: Add note about SPARCworks cc release 3.0 and higher. - - Add procfs support for Alpha OSF/1-2.x. - * config/alpha/nm-osf.h: Renamed from nm-alpha.h, generic - OSF/1 native support. - * config/alpha/alpha-osf1.mh (NAT_FILE): Changed accordingly. - (MUNCH_DEFINE): Removed. - * config/alpha/alpha-osf2.mh, config/alpha/nm-osf2.h: New files - for procfs support. - * configure.in (alpha-dec-osf*): Use alpha-osf2.mh for OSF/1 - release 2.x and higher, else alpha-osf1.mh, as the procfs support - in release 1.x is incomplete. - * Makefile.in (ALLCONFIG): Add config/alpha/alpha-osf2.mh. - * alpha-nat.c (supply_gregset, fill_gregset, supply_fpgregset, - fill_fpgregset): New routines for procfs support. - * inftarg.c (_initialize_inftarg): Don't add ptrace support - if we have an optional procfs and /proc is accessible. - * procfs.c: Include sys/fault.h and sys/syscall.h before - including sys/procfs.h. - (unconditionally_kill_inferior): If PROCFS_NEED_PIOCSSIG_FOR_KILL - is defined, additionally perform a PIOCSSIG to really terminate - the inferior. - (create_procinfo): Always return a result. - (create_procinfo, do_attach): Don't trace T_IFAULT faults if - PROCFS_DONT_TRACE_IFAULT is defined. - (procfs_init_inferior): Use START_INFERIOR_TRAPS_EXPECTED as - argument to startup_inferior if it is defined. - (proc_set_exec_trap): If PIOCSSPCACT is defined, use it instead - of tracing exits from exec system calls. Needed for the user level - loader under Alpha OSF/1. - (do_detach): Clear any pending signal if we want to detach from - a process without a signal. - (set_proc_siginfo): If PROCFS_DONT_PIOCSSIG_CURSIG is defined, - don't issue a PIOCSSIG if pr_cursig already contains the signal we - intend to set. - (info_proc_signals): If PROCFS_SIGPEND_OFFSET is defined, the - pending signals are numbered from 1 instead of 0. - (info_proc_mappings): Increase size of output format for addresses - if BFD_HOST_64_BIT is defined. - (procfs_stop): Renamed from child_stop. - (_initialize_procfs): Don't add procfs support if we have an - optional procfs and /proc is not accessible. - - -Wed Jan 11 17:53:26 1995 Rob Savoye - - * array-rom.c: Add support for most commands. - - * monitor.c: Add GDB remote protocol for the hybrid environment on - the Array board. - -Wed Jan 11 00:44:01 1995 Jeff Law (law@snake.cs.utah.edu) - - * command.c (show_user_1): Use print_command_line to show a user - defined command (including control structures). - - * top.c (init_main): Change documentation for user defined - commands to indicate they may accept up to ten arguments. - -Tue Jan 10 16:22:41 1995 Jim Kingdon - - * mips-tdep.c (mips_skip_prologue): Accept or as well as addu for - `move $s8, $sp' instruction. - -Sun Jan 8 12:45:34 1995 Jim Kingdon - - * target.c, target.h (target_signal_from_command): New function. - * infrun.c (handle_command, signals_info), infcmd.c - (signal_command): Use it. - * infrun.c, infcmd.c: Update docstrings for these commands. - - * target.h (enum target_signal), target.c (signals), target.c - (target_signal_from_host, target_signal_to_host): Add - TARGET_SIGNAL_REALTIME_* and TARGET_SIGNAL_PRIO for lynx. - * config/tm-lynx.h: Define signal numbers for realtime events. - -Sat Jan 7 07:23:53 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dbxread.c (process_one_symbol): Handle N_FUN symbols - for Sun acc 3.0 under SunOS4. - - Changes to improve handling of runtime common symbols - under SunOS4. - * minsyms.c (get_symbol_leading_char): New routine to determine - the leading symbol character for an objfile. - (prim_record_minimal_symbol_and_info, install_minimal_symbols): - Use it. - * objfiles.h (rt_common_objfile): New global, points to objfile - containing the runtime common minimal symbols. - * objfiles.c (free_objfile): Mark rt_common_objfile as - unallocated before freeing it. - * solib.c (allocate_rt_common_objfile): New routine to allocate - an objfile for the runtime common minimal symbols. - (solib_add_common_symbols): Allocate an objfile for the runtime - common symbols if necessary and put common symbols into it. - Clean up code and comments. - (solib_add, special_symbol_handling): Cleanup comments regarding - runtime common symbols. - * stabsread.c (scan_file_globals_1): New routine, contains - old scan_file_globals code. Checks if there are any unresolved - global symbols before starting the expensive minimal symbol table - search. - (scan_file_globals): Now calls scan_file_globals_1 for the passed - objfile and eventually for the runtime common objfile. Complains - about any unresolved global symbols and removes them from the - global symbol chain to avoid dangling pointers into the symbol - table if the symbol table is reread. - -Thu Jan 5 17:38:29 1995 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (install_only uninstall): Indent for clarity. - - * core.c (dis_asm_read_memory): Add call to - dis_asm_read_memory_hook to provide alternate way for disassembler - to read memory. - - * defs.h: Protect from multiple inclusion. Add decl for - dis_asm_read_memory_hook. - - * top.c: Make window startup be the default. - * Add dis_asm_read_memory_hook. - - -Thu Jan 5 01:16:40 1995 Jeff Law (law@snake.cs.utah.edu) - - * stabsread.c (define_symbol): Handle `a' symbol type used for - reference parameter passed in a register. - - -Wed Jan 4 12:27:29 1995 Kung Hsu - - * defs.h: move include tm.h up, so that the type LONGEST can - also based on the target requirement to determine. In this case - target mips64. - - * remote-os9k.c (rombug_open): catch exception e in rombug. - * remote-os9k.c (rombug_wait): print message before register display - from rombug. - -Wed Jan 4 09:18:27 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * top.c (locate_arg): Call strchr not index. - -Tue Jan 3 16:52:03 1995 Per Bothner - - * ch-exp.y (literal): Recognize NULL. - (tuple): Parse simple unlabelled tuples. - * eval.c (evaluate_subexp case OP_ARRAY): Use expect_type to - evaluate brace-initializer-expressions depending on context. - (evaluate_subexp case UNOP_CAST): Pass the target type as - expected type when evaluating the expression. - - * ch-typeprint.c (chill_type_print_base): Get names of PTR and - BOOL from TYPE_NAME. - * ch-valprint.c (chill_print_type_scalar): New function, to handle - TYPE_CODE_RANGE better than print_type_scalar does. - (chill_val_print_array_elements): Use above new function. - -Mon Jan 2 15:02:51 1995 Stan Shebs - - * remote-udi.c (udi_load): Tell symbol_file_add that the - program being loaded is the main program. - -For older changes see ChangeLog-94 - -Local Variables: -mode: indented-text -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/contrib/gdb/gdb/ChangeLog-96 b/contrib/gdb/gdb/ChangeLog-96 deleted file mode 100644 index 760b425f759..00000000000 --- a/contrib/gdb/gdb/ChangeLog-96 +++ /dev/null @@ -1,5116 +0,0 @@ -Tue Dec 31 15:19:32 1996 Geoffrey Noer - - * config/mn10300/tm-mn10300.h: more small register fixes - -Tue Dec 31 06:51:43 1996 Mark Alexander - - * config/i386/xm-windows.h: Undo previous change to SIGTRAP - and SIGQUIT values; it messed up non-MIPS targets. - * config/mips/tm-mips.h: Undefine BREAKPOINT, replace - with separate LITTLE_BREAKPOINT and BIG_BREAKPOINT definitions; - this fixes problem with setting breakpoints in little-endian - programs in the simulator. - -Mon Dec 30 00:14:06 1996 Doug Evans - - * remote-sim.c (gdbsim_open_p): New static local. - (gdbsim_open): Call unpush_target if sim open. Set gdbsim_open_p. - (gdbsim_close): Only call sim_close if sim open. Reset gdbsim_open_p. - -Sun Dec 29 09:15:03 1996 Mark Alexander - - * config/i386/xm-windows.h: Make SIGTRAP and SIGQUIT consistent - with sim/mips/support.h. - -Fri Dec 27 14:53:40 1996 Michael Meissner - - * v850-tdep.c (struct pifsr): Add cur_frameoffset field. - (v850_scan_prologue): Add debug code #ifdef'ed DEBUG. Support new - compiler prologues using register save functions and short store - instructions. Add support for functions with large stack frames. - - * config/v850/tm-vm850.h ({R0,R1,R12,EP}_REGNUMS): New register - number defintiions for r0, r1, r12, ep. - (SAVE{1,2,3}_{START,END}_REGNUM): Register number definitions for - the 3 sets of saved registers. - -Thu Dec 26 19:56:55 1996 Mark Alexander - - * valprint.c (print_longest): Don't lose upper bits - of 64-bit values on Windows. - * config/i386/xm-windows.h: Leave CC_HAS_LONG_LONG defined, - undefine PRINTF_HAS_LONG_LONG, so that 64-bit values will - be printed without loss of upper bits. - -Thu Dec 26 15:15:21 1996 Michael Snyder - - * config/sparc/tm-sparclet.h: make registers ASR15, ASR19 invisible - (they're not useful, you can't change, write or even read them) - -Thu Dec 26 15:20:48 1996 Fred Fish - - * config/pa/hppahpux.mh (TERMCAP): Always link to libc before - libcurses, to avoid picking up broken select() from libcurses - on some versions of HPUX. - -Thu Dec 26 15:14:41 1996 Michael Snyder - - * sparclet-rom.c: Remove includes of Unix system files. - Add function "sparclet_supply_register" so that parse_register_dump - will not seg-fault by calling a null function pointer. - Remove XMODEM support (unfinished work?). - Remove flag "MO_HANDLE_NL", so monitor's output can be read by humans. - Add fill command. - Remove colon from getreg.resp_delim so PSR register will work. - Remove pointer to sparclet_load (downloading SREC's doesn't work). - Null out local register names for %g0, all %cc and all %asr regs, - since the monitor can't report them. Will return zero instead. - * sparclet-stub.c: New -- remote protocol support for sparclet CPU. - * config/sparc/tm-sparclet.h: Re-arrange REGISTER_NAMES: - Add back %g0 and %psr, add %cc coprocessor regs, add %asr regs. - Adjust NUM_REGS and REGISTER_BYTES accordingly - -Tue Dec 24 10:27:37 1996 Jeffrey A Law (law@cygnus.com) - - * remote-e7000.c (want_h8300h, want_nopc_h8300h): Renamed - from want and want_nopc. - (want_h8300s, want_nopc_h8300s): New variables for H8/S register - lists. - (e7000_fetch_registers): Use H8/300H or H8/S register list string - as needed. - (e7000_wait): Likewise. - -Mon Dec 23 02:25:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-tdep.c (mips_find_saved_regs): If a frame has been - interrupted by a signal, figure out whether the registers that - the proc_desc claims are saved have been saved yet. - (mips_push_dummy_frame): Write dummy frame register after all - registers have been saved in the dummy frame. Update comments - to reflect the fact that we are now using an AT_ENTRY_POINT - call dummy. - -Sun Dec 22 15:52:25 1996 Martin M. Hunt - - * d10v-tdep.c (d10v_skip_prologue): PR11287. Fix problem where - some breakpoints weren't being set. - -Sat Dec 21 12:57:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/tm-mips.h (PC_IN_CALL_DUMMY): Removed, the default - definition in inferior.h is sufficient. - * mips-tdep.c (mips_pc_in_call_dummy): Ditto. - (mips_push_arguments): Make sure that the stack is aligned to a - multiple of 8 after the arguments are pushed. - Structures are always passed by value in the old ABI. - Adjust argument register value on big endian targets when passing - a value whose length is less than the register size. - Write stack arguments with a single write_memory call. - (mips_pop_frame): Use frame_saved_regs instead of proc_desc to - decide which registers have to be restored. - - * irix5-nat.c (fill_gregset): Sign extend registers before - filling in the gregset structure. - -Fri Dec 20 11:06:03 1996 Stu Grossman (grossman@critters.cygnus.com) - - * mswin/genmakes: Don't define _DEBUG. This breaks wingdb. - -Thu Dec 19 19:42:44 1996 Michael Meissner - - * v850-tdep.c (v850_scan_prologue): Deal with -mep shorting - register saves by using the ep register. - -Thu Dec 19 15:57:16 1996 Doug Evans - - * m32r-tdep.c (m32r_frame_find_saved_regs): Fix thinko in arg def. - -Thu Dec 19 09:38:56 1996 Mark Alexander - - * values.c (unpack_double): Make it compile with MSVC++ 2.x. - * remote-mips.c (S_IROTH): Define if not defined by stat.h, e.g. - when using MSVC++. - (common_open): Fix help string. - -Wed Dec 18 23:01:32 1996 Stan Shebs - - * mpw-make.sed: Use NewFolderRecursive for installation. - -Sat Dec 14 20:50:01 1996 Mark Alexander - - * mips-tdep.c (mips_push_arguments): Handle floating point args. - * config/mips/tm-mips.h (FIX_CALL_DUMMY): Define to set up $25 - correctly for PIC on Irix 5. - -Sat Dec 14 09:52:30 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * i386-tdep.c (i386_frame_find_saved_regs): Handle zero return - from get_pc_function_start gracefully. - -Sat Dec 14 00:43:57 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-exp.y (qualified_name): Replace explicit check for valid - destructor name with call to destructor_name_p. - - * c-lang.h, c-typeprint.c (cp_type_print_method_args): Removed, - no longer needed. - - * c-typeprint.c (c_type_print_varspec_prefix, c_type_print_base): - Replace remaining fprintf_unfiltered calls with their filtered variant. - (c_type_print_base): Do not print return type for destructors from - template classes. - Replace cp_type_print_method_args with cplus_demangle call to get - consistent type output for stubbed and unstubbed methods. - - * cp-valprint.c (cp_print_class_method): Replace - cp_type_print_method_args with cplus_demangle call to get consistent - type output for stubbed and unstubbed methods. - - * gdbtypes.c, gdbtypes.h (get_destructor_fn_field): New function - to find the destructor field indices for a type. - - * gdbtypes.h (struct type): Clarify comments for vptr_basetype - and arg_types fields. - (struct fn_field): Remove args field, no longer used. - - * symtab.c (decode_line_1), valops.c (value_struct_elt, - check_field_in): Use get_destructor_fn_field to find the destructor - field indices instead of assuming that the compiler passes the member - function fields in a specific order. - - * symtab.c (find_methods): Pass NULL instead of SYMBOL_BLOCK_VALUE - to lookup_symbol. - (list_symbol): Replace cp_type_print_method_args with cplus_demangle - call in zapped out code and explain why this code is zapped out. - -Thu Dec 12 13:29:14 1996 Michael Meissner - - * config/powerpc/ppc{,le}-sim.mt (SIM): Add the simulator common - library ../sim/common/libcommon.a. - -Wed Dec 11 11:15:08 1996 Doug Evans - - * monitor.c (monitor_load): Add support for load address argument. - * dsrec.c: #include . - (load_srec): New argument load_offset. Print download stats. - * srec.h (load_srec): Update prototype. - * sh3-rom.c (sh3_load): Update call to load_srec. - -Mon Dec 9 17:34:05 1996 Geoffrey Noer - - * config/mn10300/tm-mn10300.h: more small register fixes - * mn10300-tdep.c: filled in from another target - -Mon Dec 9 17:12:19 1996 Doug Evans - - * monitor.c (monitor_insert_breakpoint): Handle bi-endian machines. - -Mon Dec 9 15:58:51 1996 Mark Alexander - - * config/mips/tm-mips.h: Get rid of call-dummy code. - Minor changes to make pre-ANSI compilers happy. - * mips-tdep.c: Minor changes to make pre-ANSI compilers happy. - (mips_push_arguments): Rewrite to partially support EABI. - (mips_pc_in_call_dummy): New function. - * infcmd.c: Include symfile.h to get prototype of entry_point_address, - which fixes 64-bit sign extension bug on MIPS. - -Mon Dec 9 00:14:49 1996 Geoffrey Noer - - * config/mn10300/tm-mn10300.h: fix register names - * mn10300-tdep.c: new skeleton tdep for mn10300 - -Sun Dec 8 18:02:57 1996 Doug Evans - - * remote-sim.h: Update some comments. - * remote-sim.c (gdb_os_error): New function. - (init_callbacks): Fix initializing of gdb_callback. Add gdb_os_error. - (gdb_os_printf_filtered): Use gdb_stdout, not stdout. - -Sun Dec 8 00:36:31 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * irix5-nat.c (supply_gregset, fill_gregset): Handle gregsets - from O32 and N32 ABI. - (xfer_link_map_member): Work around problem with alignments - in struct obj when compiling GDB under N32 ABI. - -Thu Dec 5 23:30:44 1996 Stan Shebs - - * d10v-tdep.c: Add support for examination and interpretation - of instruction trace buffer. - (trace, untrace, info trace, tdisassemble): New commands. - -Thu Dec 5 14:06:23 1996 Doug Evans - - * config/sparc/tm-sparclet.h (TARGET_BYTE_ORDER): Undef. - (TARGET_BYTE_ORDER_SELECTABLE): Define. - (BREAKPOINT): Undef. - ({BIG,LITTLE}_BREAKPOINT): Define. - (TM_PRINT_INSN_MACH): Redefine for sparclet. - -Wed Dec 4 16:34:05 1996 Geoffrey Noer - - * config/mn10300/mn10300.mt, config/mn10300/tm-mn10300.h: New. - -Tue Dec 3 13:02:08 1996 Fred Fish - - * infptrace.c (store_inferior_registers): Move some common code out - to store_register, like fetch_inferior_registers & fetch_register. - (store_register): New function, from store_inferior_registers. - (fetch_inferior_registers, fetch_register): Minor code tweaks to - make {fetch,store}_inferior_registers and {fetch,store}_register - routines as similar in structure as possible. - (fetch_inferior_registers, store_inferior_registers): Eliminate - local variable numregs and just use ARCH_NUM_REGS directly. - -Tue Dec 3 11:38:14 1996 Michael Snyder - - * blockframe.c: add macro USE_GENERIC_DUMMY_FRAMES to enable/disable - code for generic call_dummy frames. - * config/h8300/tm-h8300.h: turn on USE_GENERIC_DUMMY_FRAMES - * config/m32r/tm-m32r.h: Ditto. - * config/sh/tm-sh.h: Ditto. - * config/v850/tm-v850.h: Ditto. - -Sun Dec 1 00:41:47 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * vax-tdep.c (vax_print_insn, print_insn_arg): Use info functions - for printing. From Valeriy Ushakov . - -Sun Dec 1 00:40:46 1996 Geoffrey Noer - - * configure.tgt: Add new mn10300 entry. - -Sun Dec 1 00:18:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - Add support for Irix 6.2 native O32 and N32 ABI. - - * config.in, configure.in, configure: Check for . - * configure.tgt: Handle mips*-sgi-irix6* like irix5 for now. - - * cp-valprint.c (cp_print_value_fields): Use SYMBOL_VALUE_ADDRESS - instead of SYMBOL_BLOCK_VALUE to get the address of a static member. - - * dwarf2read.c: Turn warnings and recoverable errors into complaints, - add new complaints where appropriate. - gcc -Wall cleanup. - (struct line_head): Change line_base from char to int to avoid - problems with compilers whose plain char is represented by an - unsigned char. - (struct partial_die_info): Add is_declaration field. - (dwarf2_tmp_obstack): New obstack for allocating temporary storage - used during symbol reading. - (cu_header_offset): New variable for resolving relative reference - dies. - (optimized_out, basereg, islocal, frame_base_reg, frame_base_offset): - New interface variables for decode_locdesc. - (struct dwarf2_pinfo): New structure for communication between - psymtab and symtab reading, passed via pst->read_symtab_private. - (dwarf2_has_info, dwarf2_build_psymtabs): Accept objects files - without line number sections. - (dwarf2_build_psymtabs_hard): Initialize temporary obstack - for symbol reading. - Allocate and initialize pst->read_symtab_private. - Relocate pst->textlow and pst->texthigh with baseaddr. - (scan_partial_symbols): Do not add DW_AT_declaration symbols - to the partial symbol table. - Add file scope enumerator symbols to the partial symbol table. - Fix typo in highpc computation. - If we didn't find a lowpc, set it to highpc to avoid complaints - from `maint check. - (add_partial_symbol): Relocate symbol values with baseaddr. - Add static DW_TAG_subprogram and DW_TAG_variable symbols to the - minimal symbol table. - Obtain symbol values for DW_TAG_variable symbols from the location - descriptor, skip symbols with missing location desciptors. - Skip symbols for aggregate types without children. - Handle enumerator symbols. - (dwarf2_psymtab_to_symtab): Issue symbol reading message if verbose. - (psymtab_to_symtab_1): Set local variables from - pst->read_symtab_private, set cu_header_offset and baseaddr. - Initialize temporary obstack for symbol reading, initialize - buildsym and add a cleanup to really_free_pendings. - Relocate highpc with baseaddr when calling end_symtab. - If the compilation is from a C file generated by language - preprocessors, do not set the symtab language if it was already - deduced by start_subfile. - Removed verbose sorting symbol table message. - (process_die): Handle DW_TAG_ptr_to_member_type and - DW_TAG_reference_type. - Use read_subroutine_type to get the function type for - DW_TAG_subprogram before calling read_func_scope. - (read_file_scope): Initialize file name to , start_subfile - expects a non-NULL name. - If we didn't find a lowpc, set it to highpc to avoid complaints - from finish_symbol. - Relocate lowpc and highpc with baseaddr. - Get rid of Irix6.2 native cc compile machine prefix in comp_dir. - Zero out ftypes for each new compilation unit (may be different - language or different objfile). - Accept compilation units without line number information, pass - comp_dir to decode_lines. - (read_func_scope): Initialize function name to to avoid - core dumps when DW_AT_name is missing. - Relocate lowpc and highpc with baseaddr. - Handle DW_AT_frame_base, keep result for DW_OP_fbreg operations. - Pass function type to new_symbol. - (read_lexical_block_scope): Relocate lowpc and highpc with baseaddr. - (read_structure_scope): Set TYPE_TAG_NAME, not TYPE_NAME. - Handle DW_TAG_class_type. - Copy fields to type_obstack, release temporary storage for fields. - Don't add symbol if die is a stub die and has no children. - Handle C++ static member fields. - (read_enumeration): Set TYPE_TAG_NAME, not TYPE_NAME. - Copy fields to type_obstack, release temporary storage for fields. - Let new_symbol handle the symbol creation for enumerators - instead of handcrafting a symbol. - Determine signedness of enum type from enumerators. - (dwarf_read_array_type): Handle variable length arrays. - Use lookup_pointer_type instead of handcrafting a type. - Create array type only if a DW_TAG_subrange_type was found. - (read_tag_pointer_type, read_tag_reference_type): - Use lookup_pointer_type and lookup_reference_type instead - of handcrafting a type. - (read_tag_ptr_to_member_type): New function to handle - DW_TAG_ptr_to_member_type. - (read_subroutine_type): Handle parameter dies. - Use lookup_function_type instead of handcrafting a type. - (read_typedef): Allocate a TYPE_CODE_TYPEDEF type for the typedef. - (read_base_type): If the type has a name, use init_type to create - a new type instead of second guessing a fundamental type. - (read_comp_unit): Reset die reference table before building - a new one. - (dwarf2_read_section): Read section contents into psymbol_obstack. - (dwarf2_read_abbrevs): Handle unterminated abbreviations - for a compile unit gracefully. - (read_partial_die): Zero partial die before reading its info. - Handle DW_AT_declaration. - Fix typo in handling of DW_FORM_block4. - (read_full_die): Fix typo in handling of DW_FORM_block4. - (read_1_signed_byte, read_2_signed_bytes, read_4_signed_bytes): - New routines to get signed values from a buffer. - (read_n_bytes, read_string): Allocate storage from the temporary - obstack. If the host char size permits it, return pointer - to buffer instead of allocating storage. - (set_cu_language): Handle DW_LANG_Mips_Assembler. - (dwarf_attr): Return NULL if reference die for DW_AT_specification - or DW_AT_abstract_origin die is not found. - (record_minimal_symbol): Removed, replaced with a direct call to - prim_record_minimal_symbol, it now handles saving the string itself. - (convert_locdesc): Removed, partial symtab reading now uses - decode_locdesc. - (dwarf_attr): Use dwarf2_get_ref_die_offset to get the absolute - offset for the die reference. - (dwarf_decode_lines): Complain if the line section info is missing. - Use read_1_signed_byte to extract lh.line_base to avoid - problems with compilers whose plain char is represented by an - unsigned char. - Add cleanups for allocated temporary storage. - Start a subfile for the first file in the state machine. - Fix off by one problem with dirs.dirs access. - Use comp_dir when directory index is 0. - Support multiple sequences (from Jason Merrill ). - (dwarf2_start_subfile): Try to keep line numbers from identical - absolute and relative file names in a common subfile. - (new_symbol): Allocate symbol and symbol name on the symbol_obstack. - Set SYMBOL_LINE from DW_AT_decl_line if present. - Set SYMBOL_TYPE from passed type if not NULL. - Change DW_TAG_variable symbol types with missing type entries - to a sensible type. - Handle optimized_out, offreg and islocal storage classes. - Add external symbols with type information whose address isn't - known as LOC_UNRESOLVED symbols. - Synthesize typedefs for C++ classes, structs, unions and enumerations. - Handle DW_TAG_enumerator symbols, complain for unrecognized - symbol tags. - (die_type): A missing DW_AT_type represents a void type. - Use dwarf2_get_ref_die_offset to get the absolute offset for - the die reference. - (die_containing_type): New function to build type from - DW_AT_containing_type attribut. - (read_type_die): Handle DW_TAG_ptr_to_member_type. - Treat DW_TAG_subprogram like DW_TAG_subroutine_type. - (dwarf_base_type): Fix typo with creation of FT_UNSIGNED_SHORT - fundamental type. - (create_name): Removed, symbol name allocation is now done - in new_symbol. - (dump_die): Use print_address_numeric to print a CORE_ADDR. - (dwarf2_empty_die_ref_table): New function to clear the die - reference table. - (dwarf2_get_ref_die_offset): New function to get the absolute - die offset from a die reference attribute. - (decode_locdesc): Complete rewrite using a stack, code mostly - borrowed from dwarfread.c:locval. - (dwarf_alloc_type): Removed, replaced by direct calls to alloc_type. - (dwarf_alloc_block): Allocate block on temporary obstack. - - * elfread.c (elf_symtab_read): When handling Irix dynamic symbols, - skip section name symbols and relocate all others. - (elf_symfile_read): Build dwarf2 psymtab even if offset is non-zero. - - * irix5-nat.c (fetch_core_registers): Handle core_reg_sect - from N32 executables. Call registers_fetched after extracting - the registers. - (obj_list_variant, struct link_map, LM_OFFSET, LM_ADDR): New - definitions to enable support of O32 and N32 format objlists. - (struct so_list): New members offset, so_name and lmstart to - eliminate dependencies from the objlist format used. - (solib_map_sections, symbol_add_stub, solib_add, - info_sharedlibrary_command, solib_address, clear_solib): Use - so_name and LM_OFFSET. - (first_link_map_member): Rewrite to enable support of O32 and N32 - format objlists. - (next_link_map_member, xfer_link_map_member): New functions to - support O32 and N32 format objlists. - (find_solib): Use first_link_map_member, next_link_map_member and - xfer_link_map_member. - (solib_create_inferior_hook): Use TARGET_SIGNAL_* instead of - host signal numbers. - - * mdebugread.c (parse_partial_symbols, handle_psymbol_enumerators): - Pass CORE_ADDR variant to add_psymbol_to_list. - - * mips-tdep.c (heuristic_proc_desc): Stop examining the prologue - if we encounter a positive stack adjustment. Handle `move $30,$sp'. - Handle `sd reg,offset($sp)' for 32 bit ABIs. - - * symmisc.c (dump_msymbols, print_partial_symbols): Use - print_address_numeric to print a SYMBOL_VALUE_ADDRESS. - (dump_symtab): Print compilation directory if it is not NULL. - - * valops.c (search_struct_field, value_struct_elt_for_reference): - Use SYMBOL_VALUE_ADDRESS instead of SYMBOL_BLOCK_VALUE to get the - address of a static member. - -Thu Nov 28 00:46:24 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * vax-tdep.c (vax_print_insn): Made static, modified to take - disassemble_info as parameter. - (_initialize_vax_tdep): New function to initialize tm_print_insn - to vax_print_insn. - -Wed Nov 27 11:29:06 1996 Michael Snyder - - * blockframe.c: Remove old-style CALL_DUMMY code. - * h8300-tdep.c, config/h8300/tm-h8300.h: Ditto. - * m32r-tdep.c, config/m32r/tm-m32r.h: Ditto. - * sh-tdep.c, config/sh/tm-sh.h: Ditto. - * v850-tdep.c, config/v850/tm-v850.h: Ditto. - -Wed Nov 27 10:32:14 1996 Michael Snyder - - * breakpoint.c: DELETE command will not delete CALL_DUMMY breakpoint. - * blockframe.c: Add target-independant support for managing - CALL_DUMMY frames on the host side. - * frame.h: Declarations for generic CALL_DUMMY frame support. - * h8300-tdep.c: Add target function calls using generic frame support. - * config/h8300/tm-h8300.h: config for generic target function calls. - * m32r-tdep.c: Add target function calls using generic frame support. - * config/m32r/tm-m32r.h: config for generic target function calls. - * sh-tdep.c: Add target function calls using generic frame support. - * config/sh/tm-sh.h: config for generic target function calls. - * v850-tdep.c: Add target function calls using generic frame support. - * config/v850/tm-v850.h: config for generic target function calls. - * valops.c: ADD PUSH_RETURN_ADDRESS so that it doesn't have to be - done by PUSH_ARGUMENTS when there's no CALL_DUMMY. - -Tue Nov 26 19:21:35 1996 Mark Alexander - - * config/mips/tm-mips.h (ADDR_BITS_REMOVE, TARGET_READ_SP): Define. - (mips_addr_bits_remove): Declare. - * mips-tdep.c (mips_push_dummy_frame): Fix heuristic-fence-post - errors when hitting breakpoints during inferior function calls - in 64-bit programs. - (fix_sign_extension): Make public, rename to mips_addr_bits_remove. - * utils.c (paddr_nz, preg_nz): New functions, similar to - paddr and preg but don't print leading zeroes. - * defs.h (paddr_nz, preg_nz): Declare. - * remote-mips.c: Use paddr_nz instead of paddr throughout - to reduce packet size. - (pmon_end_download): Improve timeout error handling. - -Tue Nov 26 17:21:37 1996 Ian Lance Taylor - - * configure: Rebuild with autoconf 2.12. - -Mon Nov 25 13:17:16 1996 Fred Fish - - From: Paul Eggert - * remote-bug.c (wait_strings): Avoid creating a trigraph. - -Fri Nov 22 15:55:22 1996 Martin M. Hunt - - * valops.c (value_at, value_fetch_lazy): Put in D10V call - to fix up address pointers. - * values.c (value_from_longest): Removed previous d10v changes. - * config/d10v/tm-d10v.h (TARGET_PTR_BIT): Change to 4 bytes. - -Fri Nov 22 10:06:19 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/i386/nm-i386v4.h (LOSING_POLL): Define, needed for - Unixware 1.1.2. - -Thu Nov 21 19:13:58 1996 Mark Alexander - - * mips-tdep.c: Replace hard-coded constants with MIPS_INSTLEN. - (common_breakpoint): Use paddr instead of %x to print 64-bit values. - (heuristic_proc_desc): Add tests for 64-bit instructions. - (init_extra_frame_info, mips_push_arguments): Recognize additional - registers for EABI. - * remote-mips.c: Extend DDB target to allow TFTP downloads. - * config/mips/tm-mips.h (MIPS_LAST_ARG_REGNUM, MIPS_NUM_ARG_REGS): - Define. - -Wed Nov 20 19:09:16 1996 Martin M. Hunt - - * infcmd.c (do_registers_info): Call val_print with the - virtual buf instead of the raw buf. Needed for REGISTER_CONVERT - to work with non-floating point regs. - - * d10v-tdep.c (d10v_skip_prologue): If we have line debugging - information, then the end of the prologue should the first - assembly instruction of the first source line. - - * values.c (value_from_longest): Put in D10V call to - fix up address pointers. - - * config/d10v/tm-d10v.h (REGISTER_VIRTUAL_SIZE): Modified. - (REGISTER_VIRTUAL_TYPE): Modified for PC_REGNUM and SP_REGNUM. - (REGISTER_CONVERTIBLE): Make PC and SP convertible. - (REGISTER_CONVERT_TO_VIRTUAL): Define. - (REGISTER_CONVERT_TO_RAW): Define. - (D10V_MAKE_DADDR): Define. - (D10V_MAKE_IADDR): Define. - -Wed Nov 20 16:15:15 1996 Geoffrey Noer - - * config/i386/cygwin32.mh: add MMALLOC_CFLAGS = -I$(MMALLOC_SRC) - -DMMCHECK_FORCE=1 so memory checks are loaded for cygwin32 gdb - -Wed Nov 20 00:43:09 1996 Doug Evans - - * callback.h: Delete, moved to ../include. - * callback.c: Delete, moved to ../sim/common. - * Makefile.in (SFILES,COMMON_OBJS): Delete callback.[co]. - (callback.o): Delete rule. - * remote-sim.h: No longer include callback.h. - (sim_callback_write_stdout): Delete prototype. - * remote-sim.c (init_callbacks,end_callbacks): New functions. - (gdb_os_write_stdout, gdb_os_printf_filtered): New functions. - (gdb_callback, callbacks_initialized): New static globals. - (gdbsim_open): Call init_callbacks. - (gdbsim_close): Call end_callbacks. - (simulator_command): Call init_callbacks. - - * config/h8300/h8300.mt (SIM): Change to ../sim/h8300/libsim.a. - * config/h8500/h8500.mt (SIM): Change to ../sim/h8500/libsim.a. - -Mon Nov 18 15:58:05 1996 Jim Wilson - - * config/mips/tm-mips.h (FIX_CALL_DUMMY): Change unsigned LONGEST - to ULONGEST. - -Fri Nov 15 15:34:18 1996 Fred Fish - - From Peter Schauer - * procfs.c (wait_fd): Handle EINTR error return from poll - by restarting the poll. - * defs.h (PIDGET): Define a default version that just - returns its argument unchanged. - * inflow.c (terminal_init_inferior): Eliminate #ifdef - of PIDGET and fold both alternatives into common code. - (pass_signal): Use PIDGET for pid passed to kill(). - -Thu Nov 14 15:54:20 1996 Michael Meissner - - * utils.c (paddr,preg): Use a static variable initialized to 32 - instead of doing addr>>32 to eliminate a warning produced by GCC - on 32-bit systems. - - * config/d10v/tm-d10v.h (ULONGEST): Define. - -Tue Nov 12 12:25:27 1996 Jim Wilson - - * c-typeprint.c (cp_type_print_method_args): Pass -1 for show in - recursive call to type_print. - -Tue Nov 12 12:18:29 1996 Jim Wilson - - * defs.h (ULONGEST): New macro. - * alpha-tdep.c, breakpoint.c, c-exp.y, ch-exp.c, convex-xdep.c, - corefile.c, defs.h, f-exp.y, findvar.c, gdbcore.h, m2-exp.y, - m88k-tdep.c, printcmd.c, remote-hms.c, remote-mips.c, sparc-tdep.c, - valarith.c, valops.c, values.c, config/gould/tm-np1.h, - config/mips/tm-mips.h, mswin/prebuilt/gdb/cexptab.c, - mswin/prebuilt/gdb/fexptab.c, mswin/prebuilt/gdb/m2exptab.c: - Change all occurances of unsigned LONGEST to ULONGEST. - - * configure.host (mips-sgi-irix6): Add. - -Tue Nov 12 12:16:40 1996 Michael Snyder - - * sh-tdep.c: Add functionality for target function calls. - * config/sh/tm-sh.h: Add support for target function calls. - -Tue Nov 12 12:06:58 1996 Michael Snyder - - * m32r-tdep.c: Add functionality for target function calls. - * valops.c: Small change to support target function calls. - * config/m32r/tm-m32r.h: Add support for target function calls. - -Mon Nov 11 17:15:59 1996 Geoffrey Noer - - * defs.h: Modify Nov 11 12:59:00 change so _MSC_VER is checked - instead of _WIN32. - * win32-nat.c: Fix Nov 11 12:59:00 change (windows.h should - be included instead of windefs.h for compilers other than - VC++). - * mswin/windefs.h: Remove ^Ms and change C++ style comments - to C style comments. - -Mon Nov 11 14:32:38 1996 Mark Alexander - - * utils.c (get_cell): Fix off-by-one bug. - * mips-tdep.c (get_frame_pointer, fix_sign_extension): - New functions to consolidate common code. - (mips_frame_chain, init_extra_frame_info): Use new functions - to fix problems with backtrace and finish commands on ddb board. - -Mon Nov 11 12:59:00 1996 Dawn Perchik - - * mips-tdep.c, remote-mips.c, values.c, mdebugread.c, - config/mips/tm-mips.h: Add/fix bugs for 64-bit mips support. - * defs.h: Cleanup; add prototypes. - * corefile.c: Change FIXME #ifdef - * win32-nat.c: Include windefs instead of windows.h. - * utils.c: Add routines for printing addresses and registers - based on type size. - -Sat Nov 9 01:05:10 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-tdep.c (heuristic_proc_desc): Stop examining the prologue - if we encounter a positive stack adjustment. - (find_proc_desc): If heuristic_fence_post is non-zero, use - heuristic_proc_start to determine the start of a function before - calling heuristic_proc_desc. - - * coffread.c (coff_symtab_read): Change minimal symbol types - for C_LABEL symbols from mst_* to mst_file_*. - - * config/m68k/sun3os4.mh (MMALLOC_CFLAGS): Define MMCHECK_FORCE to 1. - - * configure.in: Handle error message from sun3 native ld when - configuring HLDFLAGS. - * configure: Regenerated with autoconf. - - * c-valprint.c (c_value_print): Adjust value address by VALUE_OFFSET. - * cp-valprint.c (cp_print_value): Prevent gdb crashes by making sure - that the virtual base pointer from an user object still points to - accessible memory. - - * dbxread.c (dbx_symfile_init): Initialize sym_stab_info to - clear the recently added header_files fields. - (dbx_symfile_finish): Free hfiles[i].vector to avoid storage leak. - -Fri Nov 8 14:30:23 1996 Michael Snyder - - * config/tm-sh.h: Added a missing comma in middle of - REGISTER_NAMES list. - -Fri Nov 8 12:29:51 1996 Stan Shebs - - * monitor.c: Fix some formatting and comments. - - * remote-sim.c (simulator_command): Set up callbacks before - entering the simulator. - -Thu Nov 7 15:19:08 1996 Martin M. Hunt - - * d10v-tdep.c: Fix some problems with inferior function calls. - * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Change dummy to be - a pointer to the dummy's stack instead of just a flag. - -Tue Nov 5 10:21:02 1996 Michael Snyder - - * m32r-tdep.c: Improved frame_chain and fn prologue analysis. - * config/tm-m32r.h: Add framesize and register to extra_frame_info. - -Tue Nov 5 10:08:07 1996 Stu Grossman (grossman@critters.cygnus.com) - - * mswin/gdbwin.h: Remove bogus definition of CORE_ADDR. - * mswin/srcwin.cpp (CSrcScroll1::CSrcScroll1): Initialize depth - to fix divide-by-zero problem with clicking on source window. - -Mon Nov 4 00:48:37 1996 Stu Grossman (grossman@critters.cygnus.com) - - * mswin/recordit: Fix problem with absolute paths. - * mswin/recordit: Fix problem with relative paths. - -Sun Nov 3 18:06:42 1996 Stu Grossman (grossman@critters.cygnus.com) - - * mswin/{Makefile.in configure configure.in}: New files for - configuring wingdb under Unix. - -Sat Nov 2 03:54:13 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * irix5-nat.c, osfsolib.c, solib.c (symbol_add_stub): Handle - missing or zero-sized .text sections properly. - * mdebugread.c: Handle scRConst and scSUndefined storage classes. - * stabsread.c (scan_file_globals): Try to resolve symbols - for shared libraries from the minimal symbol table of the main - executable first. - -Fri Nov 1 13:59:28 1996 Martin M. Hunt - - * d10v-tdep.c, config/d10v/tm-d10v.h: Major fixes to support - inferior function calls and proper stack backtracing on D10V-EVA - board. - -Fri Nov 1 10:50:51 1996 Michael Meissner - - * config/powerpc/linux.mh (NATDEPFILES): Fix up things so that it - links. - (GDBSERVER_DEPFILES,TERMCAP): Ditto. - - * monitor.c (dev_name,targ_ops): Move static variables before - first use, to avoid compiler warnings. - -Thu Oct 31 16:37:17 1996 Michael Snyder - - * m32r-tdep.c: Improved frame_chain and fn prologue analysis. - * configure.tgt: Add entry for m32r target. - * monitor.h: Add a flag to tell monitor_store_register to use - (val, regno) instead of (regno, val). - * monitor.c: Make monitor_store_register honor the above flag. - Make monitor_exp ignore DC1/DC3 for m32r. - Increase buf size in monitor_dump_regs. - -Wed Oct 30 18:14:14 1996 Michael Snyder - - * m32r-tdep.c, m32r-rom.c: New files. - * config/m32r/m32r.mt: New file. - * config/m32r/tm-m32r.h: New file. - -Tue Oct 29 16:56:01 1996 Geoffrey Noer - - * config/i386/xm-cygwin32.h: - * config/powerpc/xm-cygwin32.h: - add #define LSEEK_NOT_LINEAR so source lines aren't unexpectedly - truncated. - -Tue Oct 29 18:36:43 1996 Michael Meissner - - * config/powerpc/tm-ppc-eabi.h (TARGET_BYTE_ORDER_SELECTABLE): - Define. - -Tue Oct 29 14:59:20 1996 Stan Shebs - - * TODO: Add item suggesting an "info bfd" command. - -Tue Oct 29 12:48:04 1996 Martin M. Hunt - - * d10v-tdep.c: Snapshot that supports D10V-EVA board. - - * config/d10v/tm-d10v.h (REGISTER_NAMES): Add imap0,imap1,dmap. - (TARGET_READ_FP,TARGET_WRITE_FP): Define. - -Mon Oct 28 17:34:24 1996 Stu Grossman (grossman@critters.cygnus.com) - - * mswin/genmakes mswin/recordit: New scripts to generate make - files for MSVC. - -Sun Oct 27 20:18:04 1996 Mark Alexander - - * config/mips/{tm-vr5000.h,tm-vr5000el.h,vr5000.mt,vr5000el.mt}: - New files. - * configure.tgt: Modify cases for vr5000 to use new files. - -Sat Oct 26 07:15:14 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/alpha/alpha-osf3.mh (XM_CLIBS): Add -lm for OSF/1-4.0. - - * procfs.c (proc_set_exec_trap): Under Alpha OSF/1-4.0, tracing - the entry to the exit system call to detect termination of the - inferior stopped working. Trace termination of the inferior via - PRFS_STOPTERM instead. - (procfs_init_inferior): Do not trace entry to exit system call - if PIOCSSPCACT is defined. - (procfs_wait): Handle PR_DEAD event, which signals the termination - of the inferior if PRFS_STOPTERM is set. - - * mdebugread.c (parse_partial_symbols): Ignore stNil section - start address symbols. - - * sparc-tdep.c (get_saved_register): Get saved PC from the - frame info if not in innermost frame. - -Thu Oct 24 10:51:45 1996 Mark Alexander - - * dbxread.c (process_one_symbol): Interpret end-of-function - markers correctly; this fixes problem on Vr5000 where all - functions in a module had the same address. - * configure.in, configure.tgt, configure.host, gdbserver/configure.in: - Correct for pc-linux-gnu problem in config.guess. - * configure: Regenerate. - -Thu Oct 24 10:06:58 1996 Stu Grossman (grossman@critters.cygnus.com) - - * dbxread.c: Don't swap symbols in place, since internal and - external forms may have different sizes. Don't assume that an - internal_nlist has the same layout as an external_nlist. Create - symbol for n_strx element so to hide specifics of nlist from - partial-stab.h. - * partial-stab.h: Don't reference dbxread symbols directly. Use - CUR_SYMBOL_STRX instead. - * config/i386/xm-windows.h: Define SIGQUIT and SIGTRAP. - - * config/v850/tm-v850.h: Define PS_REGNUM and TARGET_V850 for - MSVC builds. - * mswin/gdbwin.c (reg_order): Define register order for V850. - * mswin/gui.cpp (CGuiApp::InitInstance): Define target name for - V850. - * mswin/regdoc.h: Define MAXREGS for V850. - -Tue Oct 22 16:28:20 1996 Stu Grossman (grossman@critters.cygnus.com) - - * v850-tdep.c (scan_prologue): Changes to deal with scheduled - prologues correctly. First, prologue end is now defined by - presence of a branch, jump or call insn. Second, can no longer - fix frame offsets because we may not know the offset until after a - register has been saved. - * (v850_init_extra_frame_info): Fixup frame offsets here because - we have all the info at this time. - * (v850_frame_chain): Use new calling convention for scan_prologue. - -Tue Oct 22 10:25:29 1996 Martin M. Hunt - - * d10v-tdep.c, config/d10v/tm-d10v.h: Changes to allow stack - backtraces and inferior function calls. - -Tue Oct 22 10:32:46 1996 Stan Shebs - - * mpw-make.sed: Update init.c editing to work with Oct 8 change. - (@HLDFLAGS@): Always edit out. - -Mon Oct 21 18:17:08 1996 Mark Alexander - - * mdebugread.c (parse_partial_symbols): Fix 64-bit - sign-extension problems in calculating psymtab addresses. - * buildsym.c (end_symtab): Use macro to pop context. - -Mon Oct 21 14:40:50 1996 Stu Grossman (grossman@critters.cygnus.com) - - * v850-tdep.c: Cleanup lots of things. Add many comments. - - * v850-tdep.c (v850_init_extra_frame_info v850_frame_chain): Fix - sign bugs with scanning prologues. Get a little smarter about - calculating the length of uninteresting instructions. - -Mon Oct 21 14:01:38 1996 Michael Snyder - - * top.c: Add new commands "set annotate" and "show annotate". - -Sun Oct 20 04:38:39 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * corelow.c (core_close): Clear inferior_pid only if there is - an open core_bfd. - - * cp-valprint.c (cp_print_value_fields): Pass correct address - to val_print, not 0. - - From Andreas Schwab (schwab@issan.informatik.uni-dortmund.de): - * eval.c (evaluate_subexp_standard) [case BINOP_REPEAT]: Chase - typedefs before checking for integral type of right operand. - -Fri Oct 18 17:26:22 1996 Mark Alexander - - * mdebugread.c (parse_symbol): Fix crash when malloc has - no type info and void type has no associated pointer type. - -Thu Oct 17 18:18:20 1996 Stan Shebs - - * configure.host: New file, host configuration mapping. - * configure.tgt: New file, target configuration mapping. - * configure.in: Remove host and target mapping. - * configure: Rebuild. - -Wed Oct 16 17:46:03 1996 Stan Shebs - - * breakpoint.c (must_shift_inst_regs): New global. - (bpstat_stop_status): Change #if uses of DECR_PC_AFTER_BREAK into - equivalent expression uses. - * infrun.c (wait_for_inferior): Ditto. - -Wed Oct 16 01:53:43 1996 Stu Grossman (grossman@critters.cygnus.com) - - * v850-tdep.c (v850_push_arguments): Use symbolic names for arg - registers. - * config/v850/tm-v850.h: Change FP to 29. Define arg regs. - -Tue Oct 15 16:30:07 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (init.c): Don't use -s option with grep. It means - something different under Digital Unix. - - * buildsym.c (finish_block): Treat LOC_BASEREG_ARG and - LOC_LOCAL_ARG as arguments so that GDB will know about function - args declared this way. Mostly affects dwarf. - * dwarfread.c (decode_die_type): Change default type from int to - void. This allows GDB to recognize void functions. - * (new_symbol): If AT_PROTOTYPED is present, set a flag in the - type structure. - * findvar.c (extract_floating store_floating): Clean up comments - to reflect reality. - * gdbtypes.h: Add TYPE_FLAG_PROTOTYPED so that we can tell if a - function has a prototype. Currently, only dwarf supports this. - * utils.c (floatformat_from_doublest): Fix logic error with - converting from double to float. (It wasn't shifting mant_long if - it had a hidden bit.) - * v850-tdep.c: Add support for function calling. Fix some - problems with debugging code w/o debug symbols. - * config/v850/tm-v850.h: Ditto. - -Tue Oct 15 18:19:42 1996 Ian Lance Taylor - - * utils.c: Always ensure that size_t is defined. Check - HAVE_STDDEF_H rather than __STDC__ - (xmalloc, xrealloc): Use size_t rather than long. - -Tue Oct 15 14:24:19 1996 Martin M. Hunt - - * config/powerpc/tm-ppc-eabi.h: Undefine NO_SINGLE_STEP so targets - can use single-step commands. - -Sun Oct 13 11:38:25 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * stabsread.c (define_symbol): If REG_STRUCT_HAS_ADDR is non-zero, - follow typedefs before checking TYPE_CODE for structures and unions. - -Fri Oct 11 15:43:54 1996 Stu Grossman (grossman@critters.cygnus.com) - - * frame.h: Move definition of struct frame_saved_regs to before - struct frame to make it possible to use frame_saved_regs in - EXTRA_FRAME_INFO macro. - - * v850-tdep.c config/v850/tm-v850.h: Lotsa new functions and - macros to make frame operations (such as backtrace) work. - -Fri Oct 11 14:23:50 1996 Fred Fish - - * dbxread.c (process_one_symbol): Check for null string directly - rather than using strcmp against "". - * partial-stab.h: Ditto. - -Fri Oct 11 12:18:32 1996 Mark Alexander - - * gdbserver/{gdbreplay.c,low-linux.c,remote-utils.c,utils.c}: - Make it compile on Linux and eliminate some warnings. - -Thu Oct 10 16:32:08 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (init.c): Fixup final sed script to work around - Linux bug with `p' operator. - -Wed Oct 9 18:02:48 1996 Stan Shebs - - * remote-mips.c: Use the correct name everywhere (DDB) for NEC's - VR4300 target. - (ddb_ops, pmon_ops): Fix the documentation strings. - -Wed Oct 9 07:42:44 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (init.c): Retro HPUX grep lacks -h option. Strip - filenames with sed instead. - -Tue Oct 8 15:59:44 1996 Stu Grossman (grossman@critters.cygnus.com) - - * defs.h: Remove decls of xmalloc and xrealloc. There is a - conflicting definition in libiberty.h. - -Tue Oct 8 11:47:13 1996 Fred Fish - - * dbxread.c (dbx_symfile_read): Call free_pending_blocks rather - than poking global variable (which is now static). - * hpread.c (hpread_build_psymtabs): Ditto. - * os9kread.c (os9k_symfile_read): Ditto. - * xcoffread.c (xcoff_initial_scan): Ditto. - - * buildsym.h (free_pending_blocks): Declare here. - (pending_blocks): Remove declaration of global symbol. - (free_pendings): Remove declaration of global symbol. - (make_blockvector): Declare here. - (record_pending_block): Declare here. - - * dstread.c (make_blockvector): Remove static copy that was old - clone of version in buildsym.c. - (process_dst_block): Call record_pending_block rather than doing - it by hand. - (read_dst_symtab): Ditto. - - * buildsym.c (make_blockvector): Make global rather than static, - (record_pending_block): New function, code moved from finish_block. - (finish_block): Use record_pending_block. - (free_pending_blocks): New function. - (really_free_pendings): Call free_pending_blocks. - (pending_blocks): Make static instead of global. - (free_pendings): Make static instead of global. - -Tue Oct 8 09:03:22 1996 Stu Grossman (grossman@critters.cygnus.com) - - * config/i386/windows.mh config/i386/xm-windows.h:: New config - files to support building Wingdb (built under Microsoft build - environment). - - * Makefile.in: Add rule for hpux-thread.o (needs special header - files). - * (SUBDIRS): Remove mswin. - * Change procedure for creating init.c. Speeds things up quite a - bit. - * config.in configure configure.in: Check for select, poll. - * Check for OSF header files before including hpux-thread.o. - * Don't configure doc or testsuite when building under MSVC. - * findvar.c value.h (read_register_pid write_register_pid): Make - global. Needed for hppa-tdep.c. - * (supply_register): Don't set pid to inferior_pid when supplying - registers. - * hppa-tdep.c (saved_pc_after_call): frame_saved_pc -> - FRAME_SAVED_PC. - * (frame_saved_pc): Change name to hppa_frame_saved_pc. - * (hppa_pop_frame): Don't use a pid of 0 with target_write_pc. - Use write_pc instead, which uses the correct pid. - * (target_read_pc target_write_pc): Use read/write_register_pid - instead of read/write_register to preserve the pid passed in. - * inftarg.c (child_can_run): Add flag child_suppress_run to allow - hpux-threads.c to override this as a runnable target. - * config/pa/nm-hppah.h: Define target_new_objfile and - target_pid_to_str. - * config/pa/tm-hppa.h (FRAME_SAVED_PC): Use hppa_frame_saved_pc - instead of frame_saved_pc. - * config/m68k/tm-m68k.h: Define TARGET_M68K for Wingdb. - * config/m68k/tm-monitor.h: Use FRAME_CHAIN_VALID_ALTERNATE, since - we can't easily determine the start file bounds with ELF. - * config/mips/tm-mips.h: Define TARGET_MIPS for Wingdb. - * hpux-thread.c: New file for HPUX/OSF thread support. - * osf-share/{README AT386/cma_thread_io.h HP800/cma_thread_io.h - RIOS/cma_thread_io.h cma_attr.h cma_deb_core.h cma_debug_client.h - cma_errors.h cma_handle.h cma_init.h cma_list.h cma_mutex.h - cma_sched.h cma_semaphore_defs.h cma_sequence.h cma_stack.h - cma_stack_int.h cma_tcb_defs.h cma_util.h}: New files for OSF - thread support. - -Sun Oct 6 15:48:09 1996 Fred Fish - - * buildsym.c (finish_block): Change innerblock_anon_complaint to - print the addresses as part of the complaint. Add a complaint for - cases where the block end address is smaller than the block start - address, in case any such conditions slip through our fixup mechanism. - * symmisc.c (dump_symtab): Only print blockvector for primary - symtabs, to avoid massive duplication of output due to secondary - symtabs that point to same blockvector. Also do some minor - formatting tweaks. - -Mon Oct 7 10:42:32 1996 Per Bothner - - Replace header_files global by per-objfile field. - * gdb-stabs.h (struct dbx_symfile_info): Add fields header_files, - n_header_files, n_allocated_header_files. - * stabsread.h (header_files, n_header_files, n_allocated_header_files): - Replace externs by macros HEADER_FILES, N_HEADER_FILES, and - N_ALLOCATED_HEADER_FILES. - * dbxread.c (dbx_symfile_finish): Free HEADER_FILES. - (free_header_files, init_header-files): Don't free/init headerfiles. - (various functions): Use macros instead of header_files globals. - * stabsread.c (various functions): Likewise. - -Sun Oct 6 22:43:06 1996 Jason Merrill - - * dwarf2read.c (read_tag_reference_type): New fn. - (read_type_die): Call it. - (dwarf_attr): Also look in the DIEs referred to by specification - or abstract_origin attributes. - -Wed Oct 2 22:07:16 1996 Fred Fish - - * inferior.h (IN_SIGTRAMP): Pass pc to SIGTRAMP_START and - SIGTRAMP_END. - * config/i386/tm-i386os9k.h (SIGTRAMP_START, SIGTRAMP_END): - Define with dummy pc arg. - * config/m68k/tm-nbsd.h: Ditto. - * doc/gdbint.texinfo: Document that SIGTRAMP_START and - SIGTRAMP_END are macros that take an single argument. - -Mon Sep 30 20:02:45 1996 Fred Fish - - * defs.h: Remove define of PRIVATE_XMALLOC. - -Mon Sep 30 15:39:28 1996 Stu Grossman (grossman@critters.cygnus.com) - - * config/v850/tm-v850.h: Use distinct register for PC, not EIPC. - -Mon Sep 30 11:16:34 1996 Jeffrey A Law (law@cygnus.com) - - * top.c (execute_control_command): Free values from while_control - and if_control conditions after evaluation to avoid storage leaks. - From Peter Schauer. - -Fri Sep 27 17:43:06 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure configure.in: Recognize v850 target. - * v850-tdep.c: New file, NEC V850 target support. - * config/v850/{v850.mt tm-v850.h}: New files for NEC V850 support. - -Fri Sep 27 14:48:15 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): Update current_line and - current_symtab when stepping continues in the middle of a new line. - -Fri Sep 27 10:25:30 1996 Fred Fish - - * top.c (print_gdb_version): Rewrote to comply with new GNU coding - standards for the --version option. - (print_gnu_advertisement): Remove, now part of print_gdb_version. - (show_version): Remove call to print_gnu_advertisement. - * top.h (print_gnu_advertisement): Remove prototype. - * main.c (print_gdb_help): Move help to static function and - add prototype. - (main): Call print_gdb_help rather than inlining it. - (main): Remove call to print_gnu_advertisement. - -Fri Sep 27 13:32:53 1996 Michael Meissner - - * config/d10v/tm-d10v.h (TARGET_{INT,PTR}_BIT): Define. - (TARGET_{,LONG_}DOUBLE_BIT): Ditto. - -Thu Sep 26 23:10:26 1996 Mark Alexander - - * configure.in, config/i386/tm-linux.h: Fix configure - problem on older Linux systems that prevented core files - from being recognized. - -Wed Sep 25 18:31:33 1996 Stan Shebs - - * dbug-rom.c: New file, support for Motorola's dBUG monitor. - * config/m68k/monitor.mt (TDEPFILES): Add it. - * NEWS: Mention it. - -Mon Sep 23 16:13:50 1996 Martin M. Hunt - - * config/d10v/tm-d10v.h (SAVED_PC_AFTER_CALL): Fixed. - Now single-steps correctly. - * d10v-tdep.c (d10v_pop_frame): Fixed. - -Fri Sep 20 16:10:58 1996 Stan Shebs - - * config/sh/tm-sh.h (REGISTER_NAMES): Move fp registers to - be consistent with GCC. - (FPUL_REGNUM, etc): Renumber to match list changes. - (ADDR_BITS_REMOVE): Delete. - * sh-tdep.c (sh_reg_names, sh3_reg_names, sh3e_reg_names): - Rearrange to match REGISTER_NAMES. - * sh3-rom.c (sh3_regnames, sh3e_regnames): Ditto. - -Thu Sep 19 16:19:01 1996 Martin M. Hunt - - * d10v-tdep.c: Stack chain should work now. - -Tue Sep 17 18:46:57 1996 Martin M. Hunt - - * d10v-tdep.c, config/d10v/tm-d10v.h: Snapshot. - -Tue Sep 17 12:20:50 1996 Ian Lance Taylor - - * configure.in: Add cases for MIPS 5000 like MIPS 4300. - * configure: Rebuild. - -Tue Sep 17 12:09:00 1996 Dawn Perchik - - * ser-e7kpc.c: Added wingdb support for target e7000pc. - -Tue Sep 17 10:56:52 1996 James G. Smith - - * remote-mips.c (pmon_wait): DDB PMON does not require forced - re-entry back into debug mode. - -Mon Sep 16 14:32:58 1996 James G. Smith - - * remote-mips.c (mips_load): Ensure that the PC is explicitly - loaded after a load to a DDB PMON system. - -Fri Sep 13 12:02:39 1996 Fred Fish - - * Makefile.in (INTERNAL_LDFLAGS): Add @HLDFLAGS@ to list. - (HLDENV): Set to @HLDENV@. - (gdb): Prefix link command line with $(HLDENV). - * configure.in: Add support to test for --enable-shared and - generate appropriate values for HLDFLAGS and HLDENV. - * configure: Regenerated with autoconf. - -Sun Sep 8 15:26:27 1996 Fred Fish - - * alpha-nat.c (fetch_core_registers): Match Sep 4 gdbcore.h prototype - change for core_read_registers in struct core_fns. - * core-regset.c (fetch_core_registers): Ditto & add prototype. - * core-sol2.c (fetch_core_registers): Ditto & add prototype. - * i386aix-nat.c (fetch_core_registers): Ditto & add prototype. - * i386b-nat.c (fetch_core_registers): Ditto. - * i386mach-nat.c (fetch_core_registers): Ditto & add prototype. - * irix4-nat.c (fetch_core_registers): Ditto. - * irix5-nat.c (fetch_core_registers): Ditto. - * lynx-nat.c (fetch_core_registers): Ditto & add prototype. - * m68knbsd-nat.c (fetch_core_registers): Ditto. - * mips-nat.c (fetch_core_registers): Ditto & add prototype. - * rs6000-nat.c (fetch_core_registers): Ditto. - * sparc-nat.c (fetch_core_registers): Ditto. - * sun3-nat.c (fetch_core_registers): Ditto & add prototype. - * ultra3-nat.c (fetch_core_registers): Ditto & add prototype. - - * alpha-nat.c (register_addr): Match Sep 4 gdbcore.h prototype change. - * delta68-nat.c (register_addr): Ditto. - * gdbserver/low-linux.c (register_addr): Ditto. - * gdbserver/low-hppabsd.c (register_addr): Ditto. - * i386m3-nat.c (register_addr): Ditto. - * mips-nat.c (register_addr): Ditto. - * ultra3-nat.c (register_addr): Ditto. - -Sun Sep 8 15:14:00 1996 Stu Grossman (grossman@critters.cygnus.com) - - * blockframe.c (inside_main_func): Cleanup slightly. Move - mainsym def into the block it's used in. - * configure.in configure: Allow NATDEPFILES to be recognized in - .mh files regardless of whitespace. - - * cpu32bug-rom.c (cpu32bug_cmds): Change load_response string to - keep downloads from hanging. - - * remote-wiggler.c: Add support for flash upgrades. - * (wiggler_error): Fix message format. Add new error code. - * (wiggler_write_byets): Error code is hex. Report errors with - proper routine name. - * (wiggler_read_byets): Report errors with proper routine name. - * (get_packet): Add support for new flash commands. - * (wiggler_load): Call clear_symtab_users() to reset things - properly after download. - * (flash_xfer_memory bdm_update_flash_command): New funxtions to - support flash upgrades for Wiggler. - * (_initialize_remote_wiggler): Add `bdm update-flash' command. - -Fri Sep 6 13:14:13 1996 Geoffrey Noer - - * ser-tcp.c: don't include netinet/tcp.h if __CYGWIN32__ - -Thu Sep 5 17:05:13 1996 Geoffrey Noer - - * config/i386/cygwin32.mh: - * config/powerpc/cygwin32.mh: build ser-tcp.o for both hosts - -Thu Sep 5 12:09:13 1996 Per Bothner - - * value.h (COERCE_REF): Fix previous change. - (COERCE_ENUM): Add a check_typedef (this is the real fix). - -Thu Sep 5 03:28:30 1996 Wilfried Moser - - * eval.c (evaluate_subexp_standard): In case of OP_ARRAY: make a - better check of array boundaries. - -Thu Sep 5 01:29:42 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure: Update aclocal.m4 and re-run autoconf to get correct - defs for BFD stuff. - * remote-wiggler.c (wiggler_error): Error codes are hex. Also, - fix default message generation. - -Wed Sep 4 17:28:40 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in: Add mswin to SUBDIRS. Add rules for - mswin/libwingdb.a and remote-wiggler.o. - * breakpoint.c (breakpoint_here_p): Clean up bp enabled test. - * (breakpoint_inserted_here_p): New func, just like - breakpoint_here_p, except it's honest. Honestly. - * breakpoint.h: Proto for above. - * configure configure.in: Add mswin to configdirs if host is - i[3456]86-*-windows. - * core-aout.c (fetch_core_registers register_addr) gdbcore.h: - Change all vars that can contain addresses to type CORE_ADDR. - * findvar.c (supply_register): Allow val to be NULL. This means - that regno is unsupported. - * (read_pc read_pc_pid write_pc write_pc_pid): Make non-pid forms - just call pid forms with inferior_pid so that there's only once - place to hack PC's and such. - * infrun.c (proceed): Don't skip breakpoints if user changed PC. - * remote-wiggler.c: New file. Support for BDM interface from - Macraigor Systems. - * serial.c: Enhance serial logging capability. Add hex and octal - output modes (set remotelogbase {hex|octal|ascii}. Also log - breaks, timeouts, errors, and eofs. - * serial.h: Redefine SERIAL_SEND_BREAK to go through a wrapper - function so that we can log breaks. Don't export serial_logfile - or serial_logfp. - * top.c (execute_command): Don't test for serial_logfp here. - Just call serial_log_comand, and let serial.c sort it out. - * valops.c (value_of_variable): Don't attempt to establish frames - for static and global variables. This makes things work a bit - better if the stack or frame pointer is trashed. - * config/m68k/monitor.mt (TDEPFILES): Add remote-wiggler.o. - * config/m68k/tm-m68k.h: Define STACK_ALIGN. CPU32 can't hack - misaligned stacks during function calls. - -Wed Sep 4 13:06:26 1996 Ian Lance Taylor - - * terminal.h: Don't use #elif. - -Wed Sep 4 06:49:35 1996 Wilfried Moser - - * ch-exp.c (parse_tuple_element): Allow (*): for array tuples - if we have a type. - - * eval.c (evaluate_subexp_standard): In case of OP_ARRAY: - check number of args against bounds of array to avoid - memory corruption. - - * value.h (COERCE_REF): Do a CHECK_TYPEDEF in case we get - a TYPE_CODE_TYPEDEF. - -Fri Aug 30 15:07:14 1996 James G. Smith - - * remote-mips.c: Provide support for DDBVR4300 target board. - (ddb_open, ddb_ops): Added. - (mips_monitor_type): MON_DDB Added. - (mips_enter_debug, mips_exit_debug, mips_initialize, - mips_fetch_registers, common_breakpoint, mips_load, - _initialize_remote_mips): Updated. - -Thu Aug 29 17:00:18 1996 Michael Meissner - - * nlm/configure.in (i[345]86-*-*): Recognize i686 for pentium pro. - * nlm/configure: Regenerate. - - * gdbserver/configure.in (i[345]86-*-*): Recognize i686 for - pentium pro. - -Wed Aug 28 13:11:15 1996 Ian Lance Taylor - - * configure.in: If CY_AC_PATH_TCLCONFIG can't find TCL, don't run - CY_AC_LOAD_TCLCONFIG. - * configure: Rebuild. - -Tue Aug 27 12:40:40 1996 Fred Fish - - * infrun.c (wait_for_inferior): Initialize stop_func_end before calling - find_pc_partial_function. - -Tue Aug 27 10:17:34 1996 Michael Meissner - - * configure: Regenerate again. - -Tue Aug 27 04:25:08 1996 Geoffrey Noer - - * configure.in: work around host_alias configure bug. - AC_CANONICAL_HOST is called twice (first by AC_CHECK_TOOL - and second by AC_CANONICAL_SYSTEM). The second clobbers the - previous setting. Circumventing by moving the second check - to before the first. - * configure: regenerated - -Mon Aug 26 18:36:54 1996 Martin M. Hunt - - * config/d10v/d10v.mt: New file. - * config/d10v/tm-d10v.h: New file. - * configure.in: New target D10V. - * d10v-tdep.c: New file. - -Sun Aug 25 00:09:47 1996 Fred Fish - - * rs6000-tdep.c: Fix typo in comment. - * valops.c (call_function_by_hand): Set using_gcc to 2 - for code compiled without -g, per comment in code. - * config/a29k/tm-a29k.h (STACK_ALIGN): Add comment. - * config/sparc/tm-sparc.h (STACK_ALIGN): Add comment. - * config/sparc/tm-sp64.h (STACK_ALIGN): Add comment. - * config/pyr/tm-pyr.h (STACK_ALIGN): Add comment. - * config/m88k/tm-m88k.h (STACK_ALIGN): Add comment. - * config/pa/tm-hppa.h (PUSH_ARGUMENTS): Enclose args in ()'s. - (STACK_ALIGN): Add comment, move to be with other associated - macros, and document. - * config/mips/tm-mips.h (PUSH_ARGUMENTS): Enclose args in ()'s. - (STACK_ALIGN): Remove completely, handled by PUSH_ARGUMENTS. - * config/alpha/tm-alpha.h (PUSH_ARGUMENTS): Enclose args in ()'s. - * config/rs6000/tm-rs6000.h (STACK_ALIGN): Remove completely, - handled by PUSH_ARGUMENTS. - (PUSH_ARGUMENTS): Enclose args in ()'s. - -Fri Aug 23 13:55:05 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): Try to reenable shared library - breakpoints even if auto_solib_load is not set. - -Wed Aug 21 16:31:27 1996 Fred Fish - - * valprint.c (print_longest): Test for CC_HAS_LONG_LONG as well as - PRINTF_HAS_LONG_LONG. - * expprint.c (dump_expression): Ditto. - * configure.in: Fix check for long long support in compiler to - use a function body, not a nested function. - * configure: Rebuild with autoconf. - -Tue Aug 20 17:59:42 1996 Ian Lance Taylor - - * aclocal.m4: Include ../bfd/aclocal.m4. - * configure.in: Add stdlib.h to AC_CHECK_HEADERS. Call - BFD_NEED_DECLARATION on malloc, realloc, and free. - * acconfig.h: Add NEED_DECLARATION_MALLOC, - NEED_DECLARATION_REALLOC, and NEED_DECLARATION_FREE. - * configure, config.in: Rebuild. - * defs.h: Include and based on HAVE_*_H - rather than __STDC__. Only declare malloc, realloc, and free if - NEED_DECLARATION_* is defined. - -Tue Aug 20 15:37:03 1996 Fred Fish - - * solib.c (_initialize_solib): Add missing '\' chars at ends of - strings that continue on next line. - (enable_break): Replace "return 0" with setting success to zero - and letting normal return handle the return. - -Sat Aug 17 14:16:23 1996 Fred Fish - - * mips-tdep.c (mips_push_arguments): Make sure sp and struct_addr - are properly aligned. - -Fri Aug 16 17:54:26 1996 Stan Shebs - - * rs6000-tdep.c (rs6000_fix_call_dummy): Add full set of arguments. - * config/rs6000/tm-rs6000.h (FIX_CALL_DUMMY): Pass all arguments - to function, declare function correctly. - -Fri Aug 16 17:24:35 1996 Dawn Perchik - - * symtab.h: changed namespace to _namespace for compiling under - MFC v4.0. - -Fri Aug 16 13:52:21 1996 Stan Shebs - - * mpw-make.sed: Update for various recent changes, add some - comments. - -Fri Aug 16 15:47:36 1996 Michael Meissner - - * config/rs6000/tm-rs6000.h (FIX_CALL_DUMMY): Cast args to be an - integer for type correctness. - -Fri Aug 16 15:15:37 1996 James G. Smith - - * config/mips/{vr4300.mt, vr4300el.mt} (SIM): Add -lm when - simulator is included. - -Thu Aug 15 13:44:13 1996 Fred Fish - - * findvar.c (write_register_pid): Only needed when TARGET_WRITE_PC - is not defined. - (read_register_pid): Only needed when TARGET_READ_PC is not - defined. - * hppa-tdep.c (frame_saved_pc): Remove prototype. - * infptrace.c (udot_info): Prototype when CHILD_XFER_MEMORY is - not defined. - * config/xm-aix4.h (aix_resizewindow): Convert old style decl - to prototype. - * xcoffsolib.c (command.h): Include for needed prototypes. - -Wed Aug 14 17:54:19 1996 Stu Grossman (grossman@critters.cygnus.com) - - * config/i386/cygwin32.mh: Set NAT_FILE to nm-empty.h to make - native work. - -Wed Aug 14 02:03:42 1996 Fred Fish - - From Blair MacIntyre : - * hppa-tdep.c (hppa_fix_call_dummy): Use MSYMBOL_TYPE rather - than SYMBOL_TYPE on msymbols. - * somsolib.c (som_solib_create_inferior_hook): Ditto. - - * Makefile.in (init.c): Generate with prototypes. - - * config/pa/tm-hppa.h (frame_saved_pc): Add prototype. - * config/rs6000/xm-rs6000.h (aix_resizewindow): Ditto. - * config/rs6000/tm-rs6000.h (frame_initial_stack_address): Ditto. - (pc_load_segment_name): Ditto. - (pop_frame): Ditto. - (extract_return_value): Ditto. - (is_magic_function_pointer): Ditto. - (push_dummy_frame): Ditto. - (fix_call_dummy): Ditto. - (push_arguments): Ditto. - (skip_trampoline_code): Ditto. - (aix_process_linenos): Ditto. - - * config/m68k/tm-cisco.h (get_longjmp_target): Add prototype. - * config/m68k/tm-es1800.h: Ditto. - * config/m68k/tm-vx68.h: Ditto. - * config/m68k/tm-sun3.h: Ditto. - * config/m68k/tm-m68kv4.h: Ditto. - -Tue Aug 13 23:04:36 1996 Fred Fish - - * config/mips/nm-mips.h (get_longjmp_target): Add prototype. - * config/mips/nm-irix3.h (get_longjmp_target): Add prototype. - * remote-mips.c (mips_read_processor_type): Remove prototype. - * mips-tdep.c (gdb_print_insn_mips): Add prototype and make static. - * irix5-nat.c (fetch_core_registers): Add prototype. - -Mon Aug 12 21:23:44 1996 Fred Fish - - * remote-pa.c (boot_board): Add dummy params to make type compatible - for passing to add_com. - * scm-exp.c (scm_lreadr): Ensure svalue is not used uninitialized. - * buildsym.c (compare_line_numbers): Change function to match - prototype and also what qsort expects. - -Mon Aug 12 19:19:00 1996 Mark Alexander - - * remote.c: Make remote_write_size public. - * sh-tdep.c (_initialize_sh_tdep): Set remote_write_size to 300 - to prevent packet errors with some versions of CMON. - -Mon Aug 12 16:20:58 1996 Stu Grossman (grossman@critters.cygnus.com) - - * defs.h: Define CONST_PTR as blank if compiling with Microsoft - C, else it's `const'. - * c-lang.c c-lang.h ch-lang.c f-lang.c language.c m2-lang.c - scm-lang.c: Microsoft C can't hack const pointers. Use CONST_PTR - macro instead. - * configure configure.in defs.h: Use AC_C_CONST to figure out if - the compiler supports const. Gets rid of some cruft in defs.h. - * dwarf2read.c: -> "gdb_string.h" - * remote-sim.c: Add prototypes. Fix call to gdbsim_kill. - * sparcl-tdep.c (download): Add prototypes to write_routine and - start_routine args. - - * mswin/gdbwin.c: Don't include both varargs.h AND stdarg.h. Get - rid of varargs.h Include string.h. - * (gdbwin_update gdbwin_fputs regs_changed_f bpt_changed_f - update): Fix prototypes, fix calls. - * (update): Return value for catch_errors. - * (run_execute_command togdb_command_from_tty togdb_command): - Cleanup catching of errors from calls to execute_command. Also, - dup command string to avoid modifying const strings. - * (togdb_breakinfo_i_init togdb_breakinfo_i_next): Use 0 instead - of NULL when see if b->address isn't set. - * (bi_disable_bpt bi_enable_bpt bi_delete_all - bi_delete_breakpoint): Add arg to calls to update. - * (gui_command): Add prototype. - * (mswin_query): Fix prototype. - * (_initialize_gdbwin): Dup string to avoid modifying const. - * (info_path togdb_get_info_path): Remove const from decls cuz - this can't be const (it points at malloc'ed memory). - * (togdb_searchpath): Remove const from path. Dup string to - avoid modifying const strings. - * rindex -> strrchr. - * (gdbwin_list_symbols): Regexp param is const. - * Fix lots of refs to psymtabs to deref correct pointers. - * (togdb_set_breakpoint_sal): Call set_breakpoint_sal with sal, - not &sal. - * mswin/gdbwin.h (togdb_searchpath togdb_get_info_path - toget_set_info_path): Fix prototypes to match reality. - * mswin/gui.cpp: Define _beginthreadex and _endthreadex routines - with proper prototypes. - * mswin/iface.cpp (gdbwin_fputs): Define with correct number of args. - * mswin/ser-win32s.c: Fix defs of min and max. - * mswin/serdll32.c (OpenComm16): Make cbInQueue and cbOutQueue be - USHORT. - * (WriteComm16): Change lpBug from LPVOID to LPCSTR. - * mswin/serdll32.h: Fix prototypes for OpenComm16 and WriteComm16. - -Sun Aug 11 20:54:16 1996 Stu Grossman (grossman@critters.cygnus.com) - - * main.c (main): Make sure command loop is used with cygwin32. - * terminal.h: Allow cygwin32 to use termios.h. - -Fri Aug 9 12:42:49 1996 Jeffrey A Law (law@cygnus.com) - - * somread.c (som_symtab_read): Handle secondary definition - symbols (aka weak symbols). - - * config/tm-hppa.h (EXTRACT_RETURN_VALUE): Fix thinko in - last change. - -Thu Aug 8 10:12:36 1996 Stu Grossman (grossman@critters.cygnus.com) - - * symfile.c (symfile_bfd_open): Change ifdef from __WIN32__ to - _WIN32. - - * somread.c: Rearrange order of includes to fix warnings under - hpux-10.10. Also don't include sys/file.h. - -Wed Aug 7 21:45:52 1996 Stu Grossman (grossman@critters.cygnus.com) - - * dbxread.c: Don't include param.h or sys/file.h. - * (dbx_symfile_read): Determine symfile_relocatable from bfd - flags instead of file extension. Also clean up a little bit. - -Wed Aug 7 17:18:37 1996 Stu Grossman (grossman@critters.cygnus.com) - - * dwarf2read.c dwarfread.c exec.c infcmd.c infrun.c main.c - mdebugread.c os9kread.c source.c top.c utils.c: Don't - include param.h or sys/file.h (or unistd.h in some cases). - * defs.h exec.c inflow.c remote-array.c remote-e7000.c - sparcl-tdep.c terminal.h utils.c: Replace all occurances of - __WIN32__, WINGDB, WIN32, etc... with _WIN32. - * main.c: Remove #ifndef WINGDB around option processing. Fix - bug with passing argc==0 and argv==NULL to getopt. - * (main) Remove calls to access() before source_command. Let - soure_command handle access errors. - * maint.c (maintenance_dump_me): #ifdef out for _WIN32. - * symtab.c (operator_chars): Make this global for wingdb. - * top.c (disconnect): #ifdef out for _WIN32. - * (source_command): If got an error and from_tty, then call print - error, else just return quietly. - * utils.c (fatal_dump_core): Can't kill ourselves under windows. - Just exit. - * (pollquit notice_quit): #ifdef out stuff that doesn't exist - under windows. - -Wed Aug 7 09:59:19 1996 Jeffrey A Law (law@cygnus.com) - - * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Tweak for - structures > 4 bytes in size. - - * valops.c (call_function_by_hand): Handle aligning stacks that - grow up correctly. - * config/pa/tm-hppa.h (USE_STRUCT_CONVENTION): Define. - (STACK_ALIGN): Define. - * hppa-tdep.c (hppa_alignof): Don't demand a minumim two byte - alignment on structs/unions. - -Sun Aug 4 16:22:42 1996 Fred Fish - - * config/powerpc/nm-aix.h (PTRACE_ARG3_TYPE): Define to "int *", - which is the documented type under at least AIX 3 and AIX 4. - -Sat Aug 3 04:02:46 1996 Fred Fish - - * config/alpha/alpha-osf3.mh (XM_FILE): Change from xm-alpha.h to - xm-alphaosf.h. - (MMALLOC_CFLAGS): Define NO_MMCHECK to not install consistency - checks. - -Thu Aug 1 10:11:34 1996 Fred Fish - - * config/mips/tm-mips.h (TM_MIPS_H): Enclose file contents in - this, define when contents are included. - (mips_read_processor_type): Add prototype. - * config/mips/xm-mips.h: Remove strdup decl, now in gdb_string.h - * mdebugread.c (ecoff_relocate_efi): Add prototype. - (fixup_sigtramp): Only needed when TM_MIPS_H is defined. - -Wed Jul 31 20:21:24 1996 Fred Fish - - * rs6000-nat.c (add_vmap): Return 0 to caller rather than random value. - (vmap_ldinfo): Ensure got_exec_file is not used uninitialized. - (fetch_core_registers): Add prototype. - (vmap_symtab): Ditto. - (objfile_symbol_add): Ditto. - (add_vmap): Ditto. - (vmap_ldinfo): Ditto. - (vmap_exec): Ditto. - -Tue Jul 30 17:57:46 1996 Stan Shebs - - * stabsread.c (get_substring): Declare second arg as int. - - * remote-es.c: Include gdb_string.h after defs.h. - -Mon Jul 29 21:13:20 1996 Fred Fish - - * rs6000-tdep.c (push_arguments): Remove unused variable "pc". - (branch_dest): Remove unused variable "offset". - (pop_dummy_frame): Add prototype and make static. - (push_arguments): Guard against using len uninitialized. - (push_arguments): Guard against using arg uninitialized. - (frame_saved_pc): Remove unused variable "frameless". - (free_loadinfo): Ifdef out unused function. - - * xcoffread.c (compare_lte): Change prototype and function to - be correct type for passing to qsort. - (add_stab_to_list): Ifdef out unused function and prototype. - (compare_lte): Add prototype - (arrange_linetable): Ditto. - (record_include_begin): Ditto. - (record_include_end): Ditto. - (process_linenos): Ditto. - (xcoff_next_symbol_text): Ditto. - (scan_xcoff_symtab): Ditto. - (xcoff_initial_scan): Ditto. - - * mips-tdep.c (mips_read_processor_type): Add parens around - bitwise-and operands in comparison; previous expression always - evaluated to 0 because of equality comparison of two constants. - - * rs6000-tdep.c (skip_prologue): Add missing parens around - operands of logical-or so that first operand does not bind - to previous logical-and. - - * configure.in: Expand "long long" test to include code that triggers - known problem on HPUX with native compiler. - (configure): Regenerated. - -Mon Jul 29 18:12:27 1996 Jeffrey A Law (law@cygnus.com) - - * somsolib.c (som_solib_create_inferior_hook): Don't - warn if __d_pid can't be found. - -Sun Jul 28 10:46:39 1996 Fred Fish - - * config/mips/tm-mips.h (struct frame_info): Forward decl. - (struct type): Ditto. - (struct value): Ditto. - - * config/mips/tm-mips.h (sigtramp_address): Move extern decl - from mips-tdep.c to here. - (sigtramp_end): Ditto. - (fixup_sigtramp): Ditto. - - * config/mips/tm-mips.h (init_extra_frame_info): Add prototype. - (mips_frame_chain): Ditto. - (mips_step_skips_delay): Ditto. - (mips_frame_saved_pc): Ditto. - (mips_find_saved_regs): Ditto. - (mips_frame_num_args): Ditto. - (mips_pop_frame): Ditto. - (mips_extract_return_value): Ditto. - (mips_store_return_value): Ditto. - (mips_push_dummy_frame): Ditto. - (mips_push_arguments): Ditto. - (mips_do_registers_info): Ditto. - (ecoff_relocate_efi): Ditto. - (ecoff_relocate_efi): Ditto. - * irix4-nat.c (fetch_core_registers): Add prototype. - * mips-tdep.c (read_next_frame_reg): Add prototype - (heuristic_proc_start): Ditto. - (heuristic_proc_desc): Ditto. - (mips_print_register): Ditto. - * config/mips/nm-irix5.h (procfs_set_watchpoint): Add prototype. - (procfs_stopped_by_watchpoint): Ditto. - * config/mips/nm-irix4.h (procfs_set_watchpoint): Add prototype. - (procfs_stopped_by_watchpoint): Ditto. - * config/alpha/tm-alpha.h (ecoff_relocate_efi): Add prototype. - (struct symbol): Add forward decl for prototype. - - * breakpoint.c (internal_breakpoint_number): Only needed if - GET_LONGJMP_TARGET or SOLIB_ADD is defined. - - * objfiles.c (ecoff_relocate_efi): Remove prototype. - -Sat Jul 27 17:47:35 1996 Fred Fish - - * configure.in: Add test for "long long" support. - * configure: Regenerate with autoconf. - * acconfig.h: Add CC_HAS_LONG_LONG - * config.in: Regenerate with autoheader. - * config/mips/tm-mips64.h (FORCE_LONG_LONG): Remove - * config/sparc/tm-sp64.h (CC_HAS_LONG_LONG): Remove. - * config/mips/tm-vr4300el.h (CC_HAS_LONG_LONG): Remove. - * config/mips/tm-vr4300.h (CC_HAS_LONG_LONG): Remove. - * config/mips/xm-irix5.h (CC_HAS_LONG_LONG): Remove - (PRINTF_HAS_LONG_LONG): Remove. - (FORCE_LONG_LONG): Remove. - * config/powerpc/xm-aix.h (UINT_MAX): Undef and use gdb's version. - * config/convex/xm-convex.h (CC_HAS_LONG_LONG): Remove - (PRINTF_HAS_LONG_LONG): Remove. - * config/xm-nbsd.h (CC_HAS_LONG_LONG): Remove. - (PRINTF_HAS_LONG_LONG): Remove. - * config/pa/tm-hppa.h (GET_FIELD): Put parens around - subtraction inside shift. Put parens around subtraction - in operand of bitwise and. - (struct frame_info): Forward declare - if __STDC__ defined. - (frame_saved_regs): Ditto. - (struct value): Ditto. - (struct type): Ditto. - (struct inferior_status): Ditto. - (init_extra_frame_info): Add prototype. - (skip_prologue): Ditto. - (frameless_function_invocation): Ditto. - (frame_chain): Ditto. - (frame_chain_valid): Ditto. - (saved_pc_after_call): Ditto. - (hppa_fix_call_dummy): Ditto. - (hppa_push_arguments): Ditto. - (pa_do_registers_info): Ditto. - (in_solib_call_trampoline): Ditto. - (in_solib_return_trampoline): Ditto. - (push_dummy_frame): Ditto. - * convex-tdep.c (decout): Use print_longest rather than - fprintf_filtered. - * defs.h: Remove use of FORCE_LONG_LONG and __GNUC__ to set - CC_HAS_LONG_LONG. - (INT_MIN): Fix so it works correctly when assigned to a long long. - * valprint.c (longest_to_int): Rewrite to remove dependence - on INT_MIN and INT_MAX. - (print_longest): Rewrite the code that falls back to synthesized - hex output when LONGEST value is not representable as in a long and - printf doesn't support printing long longs. - * ch-valprint.c (chill_val_print): Cast 2nd arg of - chill_print_type_scalar to LONGEST. - chill_print_type_scalar): Make static and add prototype. - * hppa-tdep.c (get_field): Ifdef out unused function. - (set_field): Ditto. - (extract_3): Ditto. - (extract_5_store): Ditto. - (extract_11): Ditto. - (extract_12): Ditto. - (deposit_17): Ditto. - (extract_14): Convert to static and add prototype. - (deposit_14): Ditto. - (extract_21): Ditto. - (deposit_21): Ditto. - (extract_17): Ditto. - (extract_5r_store): Ditto. - (extract_5R_store): Ditto. - (extract_5_load): Ditto. - (find_proc_framesize): Ditto. - (find_dummy_frame_regs): Ditto. - (sign_extend): Ditto. - (find_unwind_entry): Add prototype. - (find_return_regnum): Ditto. - (unwind_command): Ditto. - (find_dummy_frame_regs): Add parens around subtraction in operand - of bitwise-and. - (skip_prologue): Add parens around operands of logical-and inside - operand of logical-or. - (sign_extend): Add parens around operands of subtraction inside - operand of shift. - (low_sign_extend): Ditto. - * top.c (filename_completer): Convert old style decl of - filename_completion_function into prototype. - * f-lang.c (patch_common_entries): Ifdef out unused function. - * stabsread.c (read_cfront_baseclasses): Remove unused local - variable "msg_noterm". - (resolve_cfront_continuation): Remove unused local variable "fip". - (read_type): Remove unused variable xtypenums. - (read_cfront_static_fields): Remove unused variable "i". - (read_cfront_static_fields): Remove unused variable "nfields". - (read_cfront_member_functions): Add missing comment terminator. - (read_cfront_static_fields): Return 1 rather than random value. - (read_cfront_baseclasses): Ditto. - (read_cfront_baseclasses): Ditto. - (read_cfront_baseclasses): Ditto. - * somsolib.c (som_solib_create_inferior_hook): Remove unused - variable "u". - (som_solib_create_inferior_hook): Remove unused variable - shadow_contents. - (language.h): Add for needed prototypes. - (som_solib_sharedlibrary_command): Add prototype. - * hpread.c: (hpread_read_array_type): Add prototype. - * somread.c (hpread_build_pysmtabs): Add prototype. - (hpread_symfile_finish): Ditto. - (hpread_symfile_init): Ditto. - * hppah-nat.c (fetch_register): Convert old style decl - to prototype. - (gdbcore.h): Include for needed prototypes. - (fetch_register): Remove unused variable "mess". - * remote-pa.c (get_offsets): Ifdef out unused function. - (remote_start_remote): Remove unused variable "timeout". - (boot_board): Add prototype. - (reaad_frame): Add prototype. - (getpkt): Remove unused variable "bp". - (remote_kill): Add prototype. - (remote_mourn): Add prototype. - (remote_insert_breakpoint): Add prototype. - (remote_remove_breakpoint): Add prototype. - * valops.c (value_push): Only use if PUSH_ARGUMENTS is not defined. - * infcmd.c (do_registers_info): Only need prototype if - DO_REGISTERS_INFO is not defined. - (breakpoint_auto_delete_contents): Only need if - CALL_DUMMY_BREAKPOINT_OFFSET is defined. - -Sat Jul 27 08:49:49 1996 Fred Fish - - * xcoffread.c (xcoff_end_psymtab): Add textlow_not_set parameter. - (END_PSYMTAB): Ditto. - (scan_xcoff_symtab): Call xcoff_end_psymtab with textlow_not_set. - -Fri Jul 26 14:07:37 1996 Ian Lance Taylor - - * printcmd.c (_initialize_printcmd): Initialize - tm_print_insn_info.flavour. - -Thu Jul 25 19:41:31 1996 Fred Fish - - * Makefile.in (scm-valprint.o): Depends upon gdbcore_h. - (arm-tdep.o): Ditto. - (dcache.o): Ditto. - (i386ly-tdep.o): Ditto. - (i960-tdep.o): Ditto. - (m68k-tdep.o): Ditto. - (nindy-tdep.o): Ditto. - (scm-lang.o): Ditto. - (w65-tdep.o): Ditto. - (z8k-tdep.o): Ditto. - (m68k-tdep.o): Depends upon value_h and gdb_string.h - (m2-valprint.o): Depends upon m2-lang.h. - (sparc-tdep.o): Depends upon gdb_string.h - (valprint.o): Depends upon valprint.h - - * remote-e7000.c (notice_quit): Remove prototype. - * top.c (initialize_targets): Remove prototype, now in target.h. - * stabsread.c (resolve_cfront_continuation): Remove prototype. - * dbxread.c (resolve_cfront_continuation): Remove prototype. - * symfile.h (set_demangling_style): Remove prototype. - * config/tm-sysv4.h (in_plt_section): Remove prototype, in objfiles.h. - * config/sparc/tm-sparc.h (single_step): Remove extern decl, now in - target.h. - * config/arc/tm-arc.h (one_stepped, single_step): Remove extern decls, - now in target.h. - * ser-unix.c (hardwire_restore): Remove obsolete prototype. - * sparc-tdep.c (single_step): Remove forward decl of isbranch. - * scm-lang.c (find_function_in_inferior): Remove prototype. - (value_allocate_space_in_inferior): Ditto. - * infrun.c (write_pc_pid): Remove prototype, now in inferior.h. - * defs.h (strchr): Remove declarations, they are declared in - gdb_string.h also. - (strrchr): Ditto. - (strstr): Ditto. - (strtok): Ditto. - (strerror): Ditto. - * f-valprint.c (f77_print_array_1): Remove extra arg that was being - passed to f77_print_array_1. - * gdbtypes.c (add_name): Remove unused variables lenstrlen and lenstr. - * scm-exp.c (scm_istr2int): Remove unused variable "j". - (scm_parse): Remove unused variable "str". - * hp300ux-nat.c (store_inferior_register): Remove unused variable - "buf". - (store_inferior_registers): Remove unnecessary decl "registers". - * m68k-tdep.c (m68k_pop_frame): Remove unused variable "fi". - * scm-lang.c (scm_get_field): Remove unused variable "val". - (scm_lookup_name): Remove unused variable "symval". - * objfiles.c (map_to_file): Remove unused local variable "tempfd". - * procfs.c (do_attach, do_detach): Remove unused variable "result". - (last_resume_pid): Remove unused static variable. - * alpha-tdep.c (alpha_linux_sigtramp_offset): Remove unused variable - "res". - * objfiles.c (map_to_address): Remove unused function. - * f-valprint.c (print_max): Remove extraneous extern decl, - in valprint.h. - (calc_f77_array_dims): Remove extraneous prototype, in f-lang.h. - * ch-exp.c (write_lower_upper_value): Remove prototype for - type_lower_upper. - - * gdbtypes.c (cfront_mangle_name): #ifdef out unused function. - * ch-exp.c (parse_mode_call): Ditto. - * f-valprint.c (there_is_a_visible_common_named): Ditto. - * f-lang.c (clear_function_list): Ditto. - (get_bf_for_fcn): Ditto. - (clear_bf_list): Ditto. - (add_common_block): Ditto. - (patch_all_commons_by_name): Ditto. - (find_first_common_named): Ditto. - (add_common_entry): Ditto. - (allocate_saved_function_node): Ditto. - (allocate_saved_bf_node): Ditto. - (allocate_common_entry_node): Ditto. - (allocate_saved_f77_common_node): Ditto. - - * arm-tdep.c (gdbcore.h): Include for necessary prototypes. - * dcache.c (gdbcore.h): Ditto. - * i386ly-tdep.c (gdbcore.h): Ditto. - * i960-tdep.c (gdbcore.h): Ditto. - * m2-valprint.c (m2-lang.h): Ditto. - * m68k-tdep.c (gdbcore.h): Ditto. - (value.h): Ditto. - (gdb_string.h): Ditto. - * nindy-tdep.c (gdbcore.h): Ditto. - * scm-lang.c (gdbcore.h): Ditto. - * scm-valprint.c (gdbcore.h): Ditto. - * w65-tdep.c (gdbcore.h): Ditto. - * z8k-tdep.c (gdbcore.h): Ditto. - * sparc-tdep.c (gdb_string.h): Include. - * valprint.c (valprint.h): Include. - - * config/xm-lynx.h: Remove part of comment about INT_MIN - redefined warnings from defs.h, since INT_MIN define in - defs.h is now protected by #ifndef INT_MIN. - * config/i386/xm-i386bsd.h: Ditto. - * config/m68k/xm-hp300bsd.h: Ditto. - * config/m68k/xm-news.h: Ditto. - - * config/pa/xm-hppah.h (INT_MIN): Remove bogus INT_MIN - definition as 0x80000000. The macro in defs.h is better. - * config/i386/xm-i386m3.h (INT_MIN): Ditto. - * config/i386/xm-i386mach.h (INT_MIN): Ditto. - * config/ns32k/xm-ns32km3.h (INT_MIN): Ditto. - * config/pa/xm-hppab.h: Ditto. - - * core-aout.c (fetch_core_registers): Add prototype. - * hp300ux-nat.c (fetch_inferior_register): Ditto. - (store_inferior_register_1): Ditto. - (store_inferior_register): Ditto. - * config/m68k/tm-m68k.h (find_saved_regs): Ditto. - *scm-valprint.c (c_val_print): Ditto. - * procfs.c (add_fd): Ditto. - (remove_fd): Ditto. - (wait_fd): Ditto. - (sigcodename): Ditto. - (sigcodedesc): Ditto. - (procfs_kill_inferior): Ditto. - (procfs_xfer_memory): Ditto. - (procfs_store_registers): Ditto. - (create_procinfo): Ditto. - (procfs_init_inferior): Ditto. - (proc_set_exec_trap): Ditto. - (procfs_attach): Ditto. - (procfs_detach): Ditto. - (procfs_prepare_to_store): Ditto. - (procfs_files_info): Ditto. - (procfs_open): Ditto. - (procfs_wait): Ditto. - (procfs_fetch_registers): Ditto. - (procfs_mourn_inferior): Ditto. - (procfs_can_run): Ditto. - (procfs_thread_alive): Ditto. - (procfs_stop): Ditto. - * alpha-nat.c (fetch_core_registers): Ditto. - * config/alpha/tm-alpha.h (alpha_osf_skip_sigtramp_frame): Ditto. - * objfiles.c (ecoff_relocate_efi): Ditto. - * inflow.c (pass_signal): Ditto. - (handle_sigio): Ditto. - * annotate.c (breakpoint_changed): Ditto. - * callback.c (wrap): Ditto. - (fdbad): Ditto. - (fdmap): Ditto. - * utils.c (malloc_botch): Ditto. - (fputs_maybe_filtered): Ditto. - (vfprintf_maybe_filtered): Ditto. - * defs.h (notice_quit): Ditto. - * defs.h (xmalloc, xrealloc): Ditto. - * top.c (stop_sig): Ditto. - (init_signals): Ditto. - (user_defined_command): Ditto. - (source_cleanup_lines): Ditto. - (dont_repeat_command): Ditto. - (serial_log_command): Ditto. - (disconnect): Ditto. - * target.h (initialize_targets): Ditto. - * os9kread.c (read_minimal_symbols): Ditto. - * mdebugread.c (mdebug_psymtab_to_symtab): Ditto. - (fdr_name): Ditto. - (push_parse_stack): Ditto. - (pop_parse_stack): Ditto. - (is_pending_symbol): Ditto. - (add_pending): Ditto. - * serial.c (serial_logchar): Ditto. - (serial_interface_lookup): Ditto. - * serial.h (serial_log_command): Ditto. - * f-valprint.c (info_common_command): Ditto. - * gdbtypes.h (print_type_scalar): Ditto. - * scm-valprint.c (scm_scmlist_print): Ditto. - (scm_ipruk): Ditto. - * scm-lang.c (scm_printstr): Ditto. - (in_eval_c): Ditto. - (evaluate_subexp_scm): Ditto. - * scm-exp.c (scm_read_token): Ditto. - (scm_skip_ws): Ditto. - (scm_lreadparen): Ditto. - * m2-lang.c (emit_char): Ditto. - (m2_printchar): Ditto. - (m2_printstr): Ditto. - (m2_create_fundamental_type): Ditto. - * f-lang.c (emit_char): Ditto. - (f_printchar): Ditto. - (f_printstr): Ditto. - (f_create_fundamental_type): Ditto. - * ch-lang.c (chill_printchar): Ditto. - (chill_printstr): Ditto. - (chill_create_fundamental_type): Ditto. - (value_chill_length): Ditto. - (value_chill_card): Ditto. - (value_chill_max_min): Ditto. - (evaluate_subexp_chill): Ditto. - * ch-exp.c (PEEK_TOKEN): Ditto. - (peek_token_): Ditto. - (forward_token_): Ditto. - (parse_case_label): Ditto. - (parse_opt_untyped_expr): Ditto. - (parse_unary_call): Ditto. - (parse_call): Ditto. - (parse_named_record_element): Ditto. - (parse_tuple_element): Ditto. - (parse_opt_element_list): Ditto. - (parse_tuple): Ditto. - (parse_primval): Ditto. - (parse_operand6): Ditto. - (parse_operand5): Ditto. - (parse_operand4): Ditto. - (parse_operand3): Ditto. - (parse_operand2): Ditto. - (parse_operand1): Ditto. - (parse_operand0): Ditto. - (parse_expr): Ditto. - (parse_then_alternative): Ditto. - (parse_else_alternative): Ditto. - (parse_if_expression): Ditto. - (parse_untyped_expr): Ditto. - (growbuf_by_size): Ditto. - (match_simple_name_string): Ditto. - (decode_integer_value): Ditto. - (decode_integer_literal): Ditto. - (match_float_literal): Ditto. - (match_float_literal): Ditto. - (match_string_literal): Ditto. - (match_character_literal): Ditto. - (match_integer_literal): Ditto. - (match_bitstring_literal): Ditto. - (write_lower_upper_value): Ditto. - * ch-lang.h (type_lower_upper): Ditto. - * c-lang.c (emit_char): Ditto. - * dwarfread.c (free_utypes): Ditto. - * stabsread.h (resolve_cfront_continuation): Ditto. - * stabsread.c (get_substring): Ditto. - (read_one_struct_field): Ditto. - * stabsread.h (process_later): Ditto. - * demangle.c (set_demangling_command): Ditto. - * defs.h (set_demangling_style): Ditto. - * maint.c (maintenance_info_command): Ditto. - (print_section_table): Ditto. - (maintenance_info_sections): Ditto. - (maintenance_print_command): Ditto. - * symtab.h (maintenance_print_statistics): Ditto. - * objfiles.h (in_plt_section): Ditto. - * objfiles.c (add_to_objfile_sections): Ditto. - * bcache.c (hash): Ditto. - (lookup_cache): Ditto. - * exec.c (bfdsec_to_vmap): Ditto. - (ignore): Ditto. - * f-exp.y (growbuf_by_size, match_string_literal): Ditto. - * language.c (unk_lang_printchar): Ditto. - (unk_lang_printstr): Ditto. - (unk_lang_create_fundamental_type): Ditto. - (unk_lang_print_type): Ditto. - (unk_lang_val_print): Ditto. - (unk_lang_value_print): Ditto. - * target.c (update_current_target): Ditto. - (debug_to_open): Ditto. - (debug_to_close): Ditto. - (debug_to_attach): Ditto. - (debug_to_detach): Ditto. - (debug_to_resume): Ditto. - (debug_to_wait): Ditto. - (debug_to_fetch_registers): Ditto. - (debug_to_store_registers): Ditto. - (debug_to_prepare_to_store): Ditto. - (debug_to_xfer_memory): Ditto. - (debug_to_files_info): Ditto. - (debug_to_insert_breakpoint): Ditto. - (debug_to_remove_breakpoint): Ditto. - (debug_to_terminal_init): Ditto. - (debug_to_terminal_inferior): Ditto. - (debug_to_terminal_ours_for_output): Ditto. - (debug_to_terminal_ours): Ditto. - (debug_to_terminal_info): Ditto. - (debug_to_kill): Ditto. - (debug_to_load): Ditto. - (debug_to_lookup_symbol): Ditto. - (debug_to_create_inferior): Ditto. - (debug_to_mourn_inferior): Ditto. - (debug_to_can_run): Ditto. - (debug_to_notice_signals): Ditto. - (debug_to_thread_alive): Ditto. - (debug_to_stop): Ditto. - * breakpoint.h (set_breakpoint_sal): Ditto. - * remote-utils.c (usage): Ditto. - * remote.c (set_thread): Ditto. - (remote_thread_alive): Ditto. - (get_offsets): Ditto. - (read_frame): Ditto. - (remote_insert_breakpoint): Ditto. - (remote_remove_breakpoint): Ditto. - * sparc-nat.c (fetch_core_registers): Ditto. - * corelow.c (add_to_thread_list): Ditto. - (ignore): Ditto. - * inftarg.c (proc_wait): Ditto. - * infptrace.c (udot_info): Ditto. - (fetch_register): Ditto. - * ser-unix.c (hardwire_noflush_set_tty_state): Ditto. - (hardwire_print_tty_state): Ditto. - (hardwire_flush_output): Ditto. - (hardwire_flush_input): Ditto. - (hardwire_send_break): Ditto. - (hardwire_setstopbits): Ditto. - * ser-tcp.c (tcp_return_0): Ditto. - (tcp_noflush_set_tty_state): Ditto. - (tcp_print_tty_state): Ditto. - * solib.c (match_main): Ditto. - * gdbtypes.c (print_bit_vector): Ditto. - (print_arg_types): Ditto. - (dump_fn_fieldlists): Ditto. - (print_cplus_stuff): Ditto. - * symfile.h (entry_point_address): Ditto. - * symfile.c (decrement_reading_symtab): Ditto. - * valops.c (value_arg_coerce): Ditto. - * value.h (find_function_in_inferior): Ditto. - (value_allocate_space_in_inferior): Ditto. - * values.c (vb_match): Ditto. - * thread.c (info_thread_command): Ditto. - (restore_current_thread): Ditto. - (thread_apply_all_command): Ditto. - (thread_apply_command): Ditto. - * inferior.h (write_pc_pid): Ditto. - * infrun.c (delete_breakpoint_current_contents): Ditto. - * breakpoint.c (print_it_normal): Ditto. - (watchpoint_check): Ditto. - (print_it_done): Ditto. - (print_it_noop): Ditto. - (maintenance_info_breakpoints): Ditto. - (create_longjmp_breakpoint): Ditto. - (hbreak_command): Ditto. - (thbreak_command): Ditto. - (watch_commnd_1): Ditto. - (rwatch_command): Ditto. - (awatch_command): Ditto. - (do_enable_breakpoint): Ditto. - * ch-valprint.c (chill_val_print_array_elements): Ditto. - * eval.c (evaluate_subexp): Ditto. - (get_label): Ditto. - (evaluate_struct_tuple): Ditto. - * eval.c (init_array_element): Ditto. - - * alpha-tdep.c (push_sigtramp_desc): Add prototype and make static. - * breakpoint.c (hw_breakpoint_used_count): Ditto. - (hw_watchpoint_used_count): Ditto. - * findvar.c (write_register_gen): Ditto. - (read_register_pid): Ditto. - * symtab.c (cplusplus_hint): Ditto. - * infcmd.c (breakpoint_auto_delete_contents): Ditto. - * ch-valprint.c (chill_print_type_scalar): Ditto. - * gdbtypes.c (add_name): Ditto. - (add_mangled_type): Ditto. - (cfront_mangle_name): Ditto. - * sparc-tdep.c (isbranch): Ditto. - * inftarg.c (child_stop): Ditto. - * win32-nat.c (child_stop): Ditto. - * mac-nat.c (child_stop): Ditto. - * remote-utils.c (sr_com): Ditto. - * dbxread.c (process_now): Ditto. - * ch-exp.c (require): Ditto. - (check_token): Ditto. - (expect): Ditto. - (parse_mode_call): Ditto. - (parse_mode_or_normal_call): Ditto. - * scm-lang.c (scm_lookup_name): Ditto - * f-lang.c (allocate_saved_bf_node): Ditto. - (allocate_saved_function_node): Ditto. - (allocate_saved_f77_common_node): Ditto. - (allocate_common_entry_node): Ditto. - (add_common_block): Ditto. - (add_common_entry): Ditto. - (find_first_common_named): Ditto. - (patch_common_entries): Ditto. - (patch_all_commons_by_name): Ditto. - (clear_bf_list): Ditto. - (get_bf_for_fcn): Ditto. - (clear_function_list): Ditto. - * scm-exp.c (scm_istr2int): Ditto. - (scm_istring2number): Ditto. - * scm-valprint.c (scm_inferior_print): Ditto. - * f-typeprint.c (print_equivalent_f77_float_type): Ditto. - * f-valprint.c (f77_get_dynamic_length_of_aggregate): Ditto. - (f77_create_arrayprint_offset_tbl): Ditto. - (f77_print_array_1): Ditto. - (f77_print_array): Ditto. - (list_all_visible_commons): Ditto. - (there_is_a_visible_common_named): Ditto. - * mdebugread.c (ecoff_relocate_efi): Ditto. - * callback.c (os_close): Ditto. - (os_get_errno): Ditto. - (os_isatty): Ditto. - (os_lseek): Ditto. - (os_open): Ditto. - (os_read): Ditto. - (os_read_stdin): Ditto. - (os_write): Ditto. - (os_write_stdout): Ditto. - (os_rename): Ditto. - (os_system): Ditto. - (os_time): Ditto. - (os_unlink): Ditto. - (os_shutdown): Ditto. - (os_init): Ditto. - (os_printf_filtered): Ditto. - - * scm-lang.h (scm_parse): Change old style decl to prototype. - * config/alpha/tm-alphalinux.h (alpha_linux_sigtramp_offset): Ditto. - * top.c (init_proc): Ditto. - (query_hook): Ditto. - (error_hook): Ditto. - * f-lang.c (c_value_print): Ditto. - * ch-exp.c (parse_expression): Ditto. - (parse_primval): Ditto. - (parse_untyped_expr): Ditto. - (parse_opt_untyped_expr): Ditto. - (ch_lex): Ditto. - * config/sparc/tm-sparc.h (sparc_init_extra_frame_info): Ditto. - (sparc_frame_saved_pc): Ditto. - (sparc_push_dummy_frame): Ditto. - (sparc_pop_frame): Ditto. - * defs.h (fclose): Ditto. - (atof): Ditto. - (error_hook): Ditto. - - * arc-tdep.c (single_step): Change arg to type "enum target_signal". - * rs6000-tdep.c (single_step): Ditto. - * sparc-tdep.c (single_step): Ditto. - - * breakpoint.c (cleanup_executing_breakpoints): Change unused arg type - to PTR which is what make_cleanup expects. - * utils.c (null_cleanup): Change arg type to PTR. - * defs.h (null_cleanup): Change prototype to match actual function. - * config/sparc/tm-sparc.h (struct frame_info): Move forward decl. - * ch-valprint.c (chill_val_print): Cast 2nd arg of - chill_print_type_scalar to LONGEST. - * infrun.c (wait_for_inferior): Have empty switch case for - BPSTAT_WHAT_CHECK_SHLIBS when SOLIB_ADD is not defined. - (stop_on_solib_events): Only needed if SOLIB_ADD is defined. - * infcmd.c (attach_command): Only need auto_solib_add if SOLIB_ADD - is defined. - * symfile.c (generic_load): Scan long int using a long int spec, - not an int spec. - * infptrace.c (udot_info): Only need local variables if KERNEL_U_SIZE - is defined. - (fetch_register): Only need function if FETCH_INFERIOR_REGISTERS is - not defined. - * inflow.c (handle_sigio): Only need prototype when the actual - function is compiled in. - * valprint.c (longest_to_int): Expand error message to be - separate messages for args larger than largest signed int - and args smaller than smallest signed int. - * valprint.c (print_longest): Fix problems with support for case - where compiler supports type "long long" but the runtime doesn't - support printing them with "%ll". - * scm-valprint.c (scm_scmlist_print, scm_scmval_print): Change - return types to void since we don't actually return anything - meaningful and callees ignore the values anyway. - * procfs.c (modify_inherit_on_fork_flag): Enclose pr_flags in PIOCSET - ifdef. - (modify_run_on_last_close_flag): Ditto. - (wait_fd): Enclose local variables "num_fds" and "i" LOSING_POLL - ifdef - * alpha-tdep.c (push_sigtramp_desc): Return proc_desc rather than - random value. - * infrun.c (wait_for_inferior): Ensure random_signal is not used - uninitialized. - * valops.c (call_function_by_hand): Ensure struct_addr is not used - uninitialized. - * breakpoint.c (watch_command_1): Ensure prev_frame is not used - uninitialized. - * utils.c (vfprintf_maybe_filtered): Change second arg from "char *" - to "const char *". - * infptrace.c (udot_info): Add two dummy args so that the type is - correct for passing to add_info. - * f-lang.c (saved_fcn): Move decl to head of file so it can be used - in prototypes. - (saved_bf_symnum): Ditto. - (SAVED_FUNCTION): Ditto. - (SAVED_FUNCTION_PTR): Ditto. - (SAVED_BF): Ditto. - (SAVED_BF_PTR): Ditto. - * ch-exp.c (parse_named_record_element): Build error message in - temporary buffer before passing it to expect, rather than passing - wrong number of args to expect. - * demangle.c (set_demangling_style): Call set_demangling_command with - correct number of arguments. - * inferior.h (terminal_init_inferior_with_pgrp): Change arg type to - int to match actual function. - (os_isatty): Call fdmap with right number of arguments, was missing - the host_callback* arg. - * target.c (cleanup_target): Prototype all functions casts. - * target.h (one_stepped, single_step): Declare here and convert - single_step to prototype. - * infrun.c (one_stepped, single_step): Don't declare externs - here, they have moved to target.h. - * eval.c (init_array_element): Declare previously undeclared - last two args as LONGEST. - * dcache.c (dcache_xfer_memory): Change xfunc decls to prototype form. - -Thu Jul 25 16:11:54 1996 Doug Evans - - * dsrec.c (load_srec): Protect ANSI style function parms with PARAMS. - -Mon Jul 22 18:13:27 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (os9kread.o): Remove dependency on partial-stab.h. - * dbxread.c (read_dbx_symtab end_psymtab), partial-stab.h: Don't - use partial_symtab->textlow==0 as a flag, as 0 is a legitimate - text address. Use a seperate flag (textlow_not_set) instead. - This makes stabs in ELF .o files work a lot better. - * mdebugread.c xcoffread.c: Define textlow_not_set for - partial-stab.h. - * stabsread.h (end_psymtab): Add textlow_not_set arg to prototype. - -Sat Jul 20 10:41:06 1996 Fred Fish - - * dwarf2read.c (struct filenames): Change internal "struct file" - to "struct fileinfo" to avoid conflict with "struct file" in - on HPUX and Solaris. - -Fri Jul 19 14:05:57 1996 Stan Shebs - - * dwarf2read.c: New file, DWARF 2 reader originally contributed by - Brent Benson, with additions by Gary Funck and Jerry Kreuscher. - * Makefile.in (COMMON_OBS): Add dwarf2read.o. - (SFILES): Add dwarf2read.c. - (dwarf2read.o): Add build rule. - * symfile.h (dwarf2_has_info, dwarf2_build_psymtabs): Declare - exported functions. - * elfread.c (elf_symfile_read): Call them. - (elf_symtab_read) [HARRIS_TARGET]: Skip some special symbols. - -Thu Jul 18 01:22:01 1996 Geoffrey Noer - - * symfile.c (symfile_bfd_open): - * exec.c (exec_file_command): for __GO32__ and __WIN32__ systems, - free the user from having to type the .exe extension. - -Wed Jul 17 06:54:50 1996 Mark Alexander - - * mon960-rom.c: Shorten the mon960_inits string to a single - carriage return; this prevents a hang on connecting immediately - after powerup, when MON960 is attempting autobaud detection. - -Tue Jul 16 23:47:04 1996 Mark Alexander - - * a29k-tdep.c (get_saved_register): Allow PC to be modified - when innermost frame is selected, but not in outer frames. - -Tue Jul 16 23:37:25 1996 Stu Grossman (grossman@critters.cygnus.com) - - * command.c (do_setshow_command): Don't segfault when showing - var_string and var_string_noescape vars that are NULL. - -Mon Jul 15 16:55:48 1996 Doug Evans - - * win32-nat.c (handle_load_dll): dos_path_to_unix_path renamed to - cygwin32_conv_to_posix_path. - (child_create_inferior): unix_path_to_dos_path renamed to - cygwin32_conv_to_win32_path. Rewrite code to translate PATH. - -Mon Jul 15 16:44:05 1996 Stu Grossman (grossman@critters.cygnus.com) - - * defs.h printcmd.c: Create global disassemble_info structure - tm_print_insn_info. - * i386-tdep.c (set_assembly_language_command): set - tm_print_insn_info.mach to the appropriate value for 386 or 8086 - disassembly. - * printcmd.c (print_insn): Move init of disassembler_info to - _initialize_printcmd. Set endian for disassembler here. - * sparc-tdep.c: Set tm_print_insn_info.mach as appropriate to - select sparc/sparclite. - * config/sparc/{tm-sparc.h tm-sparclite.h}: Get rid of - TM_PRINT_INSN. Set TM_PRINT_INSN_MACH to - bfd_mach_sparc/bfd_mach_sparc_sparclite. - -Fri Jul 12 19:04:32 1996 Fred Fish - - * hpread.c (hpread_lookup_type): Use xmmalloc/xmrealloc rather - than xmalloc/xrealloc. - -Fri Jul 12 17:59:47 1996 Fred Fish - - * objfiles.c (map_to_file): Error return from mmalloc_findbase is - a NULL pointer, not a -1. - -Fri Jul 12 10:16:24 1996 Stu Grossman (grossman@critters.cygnus.com) - - * i386-tdep.c (set_assembly_language_command): New routine to - select between i386 and i8086 instruction sets for disassembly. - New command `set assembly-language {i386 i8086}'. - -Thu Jul 11 21:13:21 1996 Mark Alexander - - * monitor.c (monitor_write_memory, monitor_read_memory_single): - Disable use of "long long" memory read/write commands; can't - use them because we hold the values to read/write in an int - variable, and because strtoul fails on values that exceed the - size of a long. This fixes breakpoint problems on MON960. - -Thu Jul 11 11:39:31 1996 Fred Fish - - * config/m68k/xm-hp300hpux.h (HAVE_MMAP): Remove definition. - * config/pa/xm-hppah.h (HAVE_MMAP): Ditto. - -Wed Jul 10 16:54:41 1996 Fred Fish - - * Makefile.in (MMALLOC_CFLAGS): Eliminate intermediate MMALLOC_DISABLE - and MMALLOC_CHECK macros, and add comment indicating how host dependent - makefile fragment should modify MMALLOC_CFLAGS to not use mmalloc, or - to use it but to not do heap corruption checking. - * gdbserver/Makefile.in: Ditto. - * utils.c (init_malloc): Replace warning() use with direct call of - fprintf_unfiltered, since current_target has not yet been set and thus - we cannot use warning(). If we try to use mmcheck and it fails, - suggest that this configuration needs NO_MMCHECK or MMCHECK_FORCE - defined. Other small mmalloc related cleanups. - * config/sparc/sun4os4.mh (MMALLOC_CFLAGS): Define MMCHECK_FORCE to 1. - * config/alpha/alpha-osf2.mh (MMALLOC_CFLAGS): Set to -DNO_MMCHECK. - - * config/sparc/xm-sun4os4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - * config/i386/xm-i386v4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - * config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - * config/m68k/xm-hp300hpux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - * config/m68k/xm-m68kv4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT); - * config/m68k/xm-sun3os4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - * config/pa/xm-hppah.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - * config/sparc/xm-sun4sol2.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - Remove obsolete defines. - - * config/alpha/alpha-linux.mh (MMALLOC_DISABLE): - * config/alpha/alpha-osf1.mh (MMALLOC_DISABLE): - * config/rs6000/rs6000.mh (MMALLOC_DISABLE): - * config/rs6000/aix4.mh (MMALLOC_DISABLE): - * config/powerpc/aix4.mh (MMALLOC_DISABLE): - * config/powerpc/aix.mh (MMALLOC_DISABLE): - * config/ns32k/ns32km3.mh (MMALLOC_DISABLE): - * config/mips/mipsm3.mh (MMALLOC_DISABLE): - * config/mips/decstation.mh (MMALLOC_DISABLE): - * config/m88k/cxux.mh (MMALLOC_DISABLE): - * config/i386/i386mk.mh (MMALLOC_DISABLE): - * config/i386/i386m3.mh (MMALLOC_DISABLE): - * config/i386/i386gnu.mh (MMALLOC_DISABLE): - Use MMALLOC_CFLAGS instead. - -Tue Jul 9 22:41:12 1996 Jeffrey A Law (law@cygnus.com) - - * h8300-tdep.c: Remove some outdated comments. - (h8300_skip_prologue): Rework to be more correct for the H8/300H. - Handle stm.l insns for the H8/S. - (examine_prologue): Likewise. - -Tue Jul 9 16:48:55 1996 Raymond Jou - - * ser-mac.c (mac_close): Change a typo SetSetBuf to SerSetBuf. - -Mon Jul 08 08:50:39 1996 Mark Alexander - - * mon960-rom.c (mon960_open): Add floating point detection to - prevent hang on non-FPU processors (PR 9775). - (mon960_cmds): Swap setmem.cmdw and setmem.cmdl to fix problem - setting breakpoints and improve loading speed. - -Sun Jul 7 14:57:34 1996 Fred Fish - - * coffread.c (record_minimal_symbol): Don't presave name string - on symbol_obstack before passing to prim_record_minimal_symbol. - It now handles saving the string itself. - * dbxread.c (read_dbx_dynamic_symtab): Ditto. - * mipsread.c (read_alphacoff_dynamic_symtab): Ditto. - * os9kread.c (record_minimal_symbol): Ditto. - * solib.c (solib_add_common_symbols): Ditto. - - * coffread.c (coff_symtab_read): Don't presave name string on - symbol_obstack before passing to prim_record_minimal_symbol_and_info. - It now handles saving the string itself. - * dbxread.c (record_minimal_symbol): Ditto. - * elfread.c (record_minimal_symbol_and_info): Ditto. - - * dstread.c (record_minimal_symbol): Remove static function that just - called prim_record_minimal_symbol with the same args (after change to - prim_record_minimal_symbol to do it's own name string saves). - * nlmread.c (record_minimal_symbol): Ditto. - * somread.c (record_minimal_symbol): Ditto. - - * hpread.c (hpread_read_enum_type): Save symbol name on symbol obstack. - (hpread_read_function_type): Ditto. - (hpread_process_one_debug_symbol): Ditto. - * mdebugread.c (parse_symbol): Ditto. - (new_symbol): Ditto. - * minsyms.c (prim_record_minimal_symbol_and_info): Ditto. - - * coffread.c (process_coff_symbol): Use obsavestring to save - SYMBOL_NAME, rather than obstack_copy0. - * dstread.c (create_new_symbol): Ditto - * symfile.c (obconcat): Ditto. - * stabsread.c (patch_block_stabs): Ditto. - * xcoffread.c (SYMNAME_ALLOC): Ditto. - - * symfile.c (obsavestring): Update comments - * solib.c (solib_add_common_symbols): Remove local var origname. - -Wed Jul 3 15:56:08 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure: Re-build with autoconf-2.10. - - * sparcl-tdep.c (_initialize_sparc_tdep) config/sparc/tm-sparc.h, - config/sparc/tm-sparclite.h: Initialize tm_print_insn from - TM_PRINT_INSN, which comes from the tm file. - -Tue Jul 02 21:41:20 1996 Mark Alexander - - * coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c, - os9kread.c: Replace identical sym_offsets functions with - default_symfile_offsets. - * somread.c (som_symfile_offsets): Use new SIZEOF_SECTION_OFFSETS - macro to allocate section_offsets. - * symfile.c (default_symfile_offsets): New function. - * symfile.h: Declare default_symfile_offsets. - * symtab.h: Define SIZEOF_SECTION_OFFSETS macro to - simplify allocation of section_offsets. - -Tue Jun 11 12:02:55 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (INTERNAL_LDFLAGS): Add in flags from configure. - * configure configure.in: Only make sol-thread.o for native. - Also, switch to dlopened libthread_db.so.1. - * sol-thread.c: Switch to using dlopen to get the thread_db - library. - -Thu Jun 13 16:53:25 1996 Stu Grossman (grossman@critters.cygnus.com) - - * configure, configure.in: Change test for libthread_db to only - work for configs where build/host/target are the same. - -Tue Jul 2 15:04:20 1996 Michael Meissner - - * config/powerpc/{linux.mh,xm-linux.h}: New files, for Linux on - PowerPC. - - * configure.in (powerpc-*-linux): Add Linux, System V, and ELF - support. - * configure: Regenerate. - -Mon Jul 1 13:00:43 1996 Stan Shebs - - From Raymond Jou : - * mpw-make.sed: Add lines to whack out autoconf hook - @CONFIG_LDFLAGS@. - -Mon Jul 01 11:07:15 1996 Mark Alexander - - * remote-e7000.c (e7000_stop): New function. - -Fri Jun 28 06:34:19 1996 Dawn Perchik - - * configure, configure.in: Add target sparclet. - * monitor.h, monitor.c: Added monitor flags MO_NO_ECHO_ON_SETMEM - (don't expect echo on setmem command), MO_RUN_FIRST_TIME (if - command to start process running on target is different from one - to continue execution), MO_HEX_PREFIX (if addresses from monitor - have a "0x" prefix). - * monitor.c, parse.c, sparc-tdep.c: Don't require strings in the - registers array. This is to allow NULLs to be place holders in - the tm-*.h file so that only minor changes are needed when a new - processor is introduced (eg, one without floating point). - * sparc-tdep.c: Conditionally remove dependancies on floating - point. - * sparclet-rom.c, config/sparc/sparclet.mt, - config/sparc/tm-sparclet.h: New files for target sparclet. - * symfile.c (load_command): Add option for 2nd parameter; a load - offset added to the vma of each section. - -Fri Jun 28 05:39:19 1996 Dawn Perchik - - * main.c (main): Add option "l" for setting remote_timeout. - -Fri Jun 28 05:25:18 1996 Dawn Perchik - - * remote-e7000.c, remote.c, target.h, top.c: Add set option - "remote_timeout" for setting remote_timeout. Add set option - "use_hard_breakpoints" for setting hardware .vs. memory - breakpoints. - -Fri Jun 28 04:32:18 1996 Dawn Perchik - - * remote-e7000.c (e7000_parse_device): New function. - Add option "tcp_remote" to target command if using - tcp to connect to a remote host which is then connected - via serial port to the e7000 (for exampole, a port master). - (e7000_open): Change to call e7000_parse_device. - -Fri Jun 28 03:47:17 1996 Dawn Perchik - - * monitor.c (monitor_debug): Fix remotedebug buffering. - -Thu Jun 27 18:24:17 1996 Stan Shebs - - * config/i386/cygwin32.mh, config/powerpc/cygwin32.mh - (NATDEPFILES): Add a space. - -Wed Jun 26 06:05:39 1996 Wilfried Moser - - * gdbtypes.c (create_array_type): If TYPE_LENGTH (result_type) - is zero, set TYPE_FLAG_TARGET_STUB to force reevaluation of the type. - - * ch-exp.c (calculate_array_length): Function removed. - -Tue Jun 25 17:41:06 1996 Martin M. Hunt - - * remote-e7000.c (e7000_read_inferior_memory_large): New function. - (e7000_xfer_inferior_memory): Call it. - -Tue Jun 25 23:14:07 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) - - * gdb/gdbserver/Makefile.in (docdir): Removed. - -Tue Jun 25 22:05:38 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) - - * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir): - Use autoconf set values. - (docdir): Removed. - * configure.in (AC_PREREQ): autoconf 2.5 or higher. - * nlm/Makefile.in (bindir, libdir, datadir, mandir, infodir, - includedir): Use autoconf set values. - (docdir): Removed. - * nlm/configure.in (AC_PREREQ): autoconf 2.5 or higher. - * nlm/configure: Rebuilt. - * gdb/gdbserver/Makefile.in (datadir): Set to $(prefix)/share. - -Mon Jun 24 09:56:14 1996 Angela Marie Thomas (angela@cygnus.com) - - * stabsread.c (read_cfront_member_functions): add type - -Sun Jun 23 23:40:48 1996 Doug Evans - - * win32-nat.c: #include . - (unix_paths_to_dos_paths, dos_paths_to_unix_paths): Delete. - (child_create_inferior): Convert only env var PATH to win32 style. - (set_pathstyle_dos): Delete. - (_initialize_inftarg): Delete dos-path-style command. - -Thu Jun 20 13:42:23 1996 Doug Evans - - * configure.in: Revise sol-thread.o test. - * configure: Regenerated. - - * source.c (find_source_lines): Reassign size to result of read. - -Tue Jun 18 16:25:54 1996 Jeffrey A. Law - - * h8300-dep.c (gdb_print_insn_h8300): Handle the H8/S. - (h8300_command): Likewise. - (set_machine): Likewise. - (set_machine_hook): Likewise. - (_initialize_h8300m): Likewise. - - * config/h8300/tm-h8300.h (h8300smode): Declare. - -Sun Jun 16 15:21:51 1996 Jeffrey A. Law - - * somsolib.c (som_solib_create_inferior_hook): Handle tracking - of shl_load calls for hpux10. - -Thu Jun 13 11:16:10 1996 Tom Tromey - - * config.in: Regenerated. - * acconfig.h (HAVE_THREAD_DB_LIB): Added entry. - - * configure: Regenerated. - * aclocal.m4 (CY_AC_PATH_TCLH, CY_AC_PATH_TKH): Use odd names to - avoid name clashes with SunOS headers. - -Tue Jun 11 19:52:50 1996 Fred Fish - - From Michael Snyder : - * bcache.c (print_bcache_statistics): Avoid divide-by-zero - exception if one or more objfile has no symbols, such as when - a dynamic library has been stripped. - -Tue Jun 11 12:02:55 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (INTERNAL_LDFLAGS): Add in flags from configure. - * configure configure.in: Only make sol-thread.o for native. - Also, switch to dlopened libthread_db.so.1. - * sol-thread.c: Switch to using dlopen to get the thread_db - library. - -Mon Jun 10 14:17:19 1996 Fred Fish - - * config/sparc/{xm-sun4sol2.h,xm-sun4os4.h} (MMAP_BASE_ADDRESS): - Change from 0xE0000000 to 0xC0000000. - -Thu Jun 6 17:10:32 1996 Michael Meissner - - * config/powerpc/xm-solaris.h: Initial version of support for - Solaris on PowerPC. - -Wed Jun 5 01:52:57 1996 James G. Smith - - * configure.in (configdirs): Force 4100 builds to use 4300 GDB - target. - * configure: Rebuild. - - * config/mips/vr4300el.mt (SIM_OBS): Include simulator in - little-endian builds. - -Mon Jun 3 11:48:29 1996 Jeffrey A Law (law@cygnus.com) - - * inftarg.c (child_thread_alive): Protect declaration with - #ifndef CHILD_THREAD_ALIVE. - - * source.c (find_source_lines): Check the time on the symtab's bfd if - it exists, else check the time on the exec_bfd. - -Thu May 30 09:43:17 1996 Mark Alexander - - * dsrec.c (make_srec): Fix calculation of address size - to allow addresses less than 0x100. - -Thu May 30 04:24:09 1996 Wilfried Moser - - * ch-exp.c (ch_lex): In case of LOC_TYPEDEF call calculate_array_length. - -Tue May 28 16:15:47 1996 Geoffrey Noer - - * remote-mips.c: cannot use EINVAL for breakpoint test since - its value varies for different hosts (e.g. go32's is 19, while - sunos is 22). Changed to hardcoded 22 since that is what the - mips boards return. - -Tue May 28 11:14:58 1996 Tom Tromey - - * configure: Regenerated. - * aclocal.m4 (CY_AC_PATH_TCLH): Don't use AC_TRY_RUN. - (CY_AC_PATH_TKH): Don't use AC_TRY_RUN. - -Sun May 26 16:56:35 1996 Miles Bader - - * solib.c (solib_absolute_prefix, solib_search_path): New variables. - (_initialize_solib): Add set/show commands for those variables. - (solib_map_sections): Implement searching using them. - -Sun May 26 14:14:49 1996 Fred Fish - - Changes from: David Mosberger-Tang - - * NEWS: Add Alpha Linux as a new native configuration. - - * mdebugread.c (parse_symbol): When we find a malloc() symbol with - return type VOID, assume no debugging info is available for that - object file and patch the return value into VOID *. Otherwise, - operations requiring an implicit call to malloc() will fail. - - * infrun.c (wait_for_inferior): The criterion to detect entering a - sigtramp handler is now: (a) the current pc is inside a sigtramp - handler, (b) the previous pc is not in a sigtramp handler, and (c) - the current stack pointer is "inner" than the old one. Condition - (c) is new to avoid mistaking a return from a signal handler into - sigtramp as a new sigtramp invocation. - - * dcache.c (struct dcache_block): Declare addr as CORE_ADDR. An - int may not be big enough to hold an address. - (dcache_hit): Ditto. - (dcache_peek_byte): Fix indentation. - - * configure.in (alpha-*-linux*): Add target. - * configure: Rebuild - - * config/alpha/tm-alpha.h (PROC_DESC_IS_DYN_SIGTRAMP): New macro. - (SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto. - (DYNAMIC_SIGTRAMP_OFFSET): Ditto. - (SIGCONTEXT_ADDR): Ditto. - (FRAME_PAST_SIGTRAMP_FRAME): Ditto. - - * config/alpha/alpha-linux.mh: New file. - * config/alpha/alpha-linux.mt: Ditto. - * config/alpha/nm-linux.h: Ditto. - * config/alpha/tm-alphalinux.h: Ditto. - * config/alpha/xm-alphalinux.h: Ditto. - * config/alpha/xm-alphaosf.h: Renamed from xm-alpha.h. - * config/alpha/alpha-osf1.mh (XM_FILE): Change from xm-alpha.h to - xm-alphaosf.h. - * config/alpha/alpha-osf2.mh: Ditto. - - * blockframe.c (find_pc_partial_function): Pass PC to - SIGTRAMP_START and SIGTRAMP_END macros for the benefit of systems - that detect sigtramp code via designated code sequences (as is the - case for Linux/Alpha, for example). - - * config/i386/tm-i386bsd.h: Change SIGTRAMP_START and SIGTRAMP_END - to ignore new PC argument. - * config/m68k/tm-hp300bsd.h: Ditto. - * config/vax/tm-vax.h: Ditto. - - * alpha-tdep.c (alpha_linux_sigtramp_offset): New function. - (alpha_osf_skip_sigtramp_frame): Ditto. - (push_sigtramp_desc): Ditto. - (alpha_find_saved_regs): Use SIGCONTEXT_ADDR macro to extract - sigcontext address from frame. - (alpha_saved_pc_after_call): When in sigtramp, use - alpha_frame_saved_pc() instead of read-register(). - (after_prologue): When inside a dynamically generated sigtramp - function, there is no prologue, so return address of first - instruction. - (alpha_in_prologue): Fix typo in comment. - (find_proc_desc): Use macro DYNAMIC_SIGTRAMP_OFFSET to determine - whether we're inside a dynamicaly generated sigtramp function. If - so, create and push and appropriate procedure descriptor. - (alpha_frame_chain): Use macro FRAME_PAST_SIGTRAMP_FRAME to obtain - the frame past a sigtramp frame (if the current frame is indeed a - sigtramp function). - (init_extra_frame_info): Don't read next frame register off of - stack-pointer when inside a dynamiccaly generated sigtramp. - (alpha_pop_frame): Also unlink and destroy procedure descriptors - created for dynamically generated sigtramp functions. - - * alpha-nat.c: When compiling under Linux, include and - instead of - -Tue Jul 2 13:58:10 1996 Miles Bader - - * gnu-nat.c (inf_validate_task_sc): - Give terminal to gdb while asking question. - (inf_resume): Don't validate the task suspend-count while execing. - -Thu Jun 13 11:04:52 1996 Miles Bader - - * gnu-nat.c (inf_validate_task_sc): Query user before clearing any - additional suspend count. - (S_proc_wait_reply, gnu_attach): Don't call inf_validate_task_sc. - (inf_resume): Call inf_validate_task_sc here. - (gnu_resume): Call inf_update_procs to ensure noticing new threads. - -Fri Jun 7 17:00:43 1996 Miles Bader - - * gnu-nat.c (gnu_create_inferior: attach_to_child): Return PID. - -Thu May 23 15:13:56 1996 Jeffrey A Law (law@cygnus.com) - - * h8300-tdep.c (IS_PUSH): Refine. - (IS_MOVE_FP, IS_MOV_SP_FP): Accept H8/300H varaints. - (IS_SUB4_SP, IS_SUBL_SP): New macros. - (h8300_skip_prologue): Handle H8/300H prologue code sequences. - (examine_prologue): Handle addresses from 0x010000 to 0xffffff - when in H8/300H mode. Get the return pointer's address correctly - for the H8/300H. Handle H8/300H prolouge code sequences. - - * symfile.c (generic_load): Print the starting address - of the file just loaded. - -Thu May 23 12:09:52 1996 Stan Shebs - - * mpw-make.sed: Edit @THREAD_DB_OBS@ out of makefile. - -Tue May 21 11:53:56 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * breakpoint.c (bpstat_do_actions): Avoid endless recursion - if a `source' command is contained in bs->commands. - - * infrun.c (wait_for_inferior): Update step_frame_address when - stepping into a new line. - - From schwab@issan.informatik.uni-dortmund.de (Andreas Schwab): - * breakpoint.c (breakpoint_1): Add shlib_disabled case to - bpenables array. - -Mon May 20 22:52:00 1996 Mark Alexander - - * dsrec.c (load_srec): Add WAITACK parameter, for machines - like EST visionICE that send back an ACK after each S-record. - * monitor.c (monitor_wait_srec_ack): New function. - (monitor_load): Pass monitor_wait_srec_ack to load_srec - if the monitor's MO_SREC_ACK flag is set. - * monitor.h: Define MO_SREC_ACK flag. - * remote-est.c (est_cmds): Add MO_SREC_ACK flag. - * sh3-rom.c (sh3_load): Accomodate change in load_srec prototype. - * srec.h: Add WAITACK parameter to load_srec prototype. - -Sun May 19 21:22:00 1996 Rob Savoye - - * config/sparc/sparclite.mt: Add the sparc simulator. - -Sun May 19 16:49:37 1996 Fred Fish - - * defs.h (read_command_lines, query_hook): Update prototypes. - (readline_begin_hook, readline_hook, readline_end_hook): Declare. - * breakpoint.c (commands_command): Build message in temporary buffer - and pass that, as well as tty control flag, to read_command_lines. - * top.c (readline_begin_hook, readline_hook, readline_end_hook): - Define here. - (command_loop): Check for non-NULL instream before looping. - (command_line_input): Use readline_hook when appropriate, to get - user input from a GUI window. - (read_next_line): Also build prompt if getting user input from a GUI. - (recurse_read_control_structure): Fix typo in comment. - (read_command_lines): Use passed in prompt and tty flag to decide how - to build message. Use readline_begin_hook when appropriate, to set - up a GUI interaction window. Just return head, whether NULL or not, - after using readline_end_hook to complete GUI interaction. - (define_command, document_command): Build message in a temporary - buffer and pass it to read_command_lines, along with tty flag. - - -Sat May 18 02:43:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * blockframe.c (frameless_look_for_prologue): - Add FUNCTION_START_OFFSET only if func_start is non-zero. - * minsyms.c (lookup_minimal_symbol_by_pc): Return NULL if - pc is not in a known section. - * stack.c (print_frame_info): Remove check for fi->pc in known - section, now handled by lookup_minimal_symbol_by_pc. - - -Fri May 17 13:31:04 1996 Stan Shebs - - * sh-stub.c: New file, was config/sh/stub.c. - - -Wed May 15 08:25:12 1996 Jeffrey A Law (law@cygnus.com) - - * top.c (read_next_line): Fix thinkos. From Donn Seeley. - - * coffread.c (coff_symtab_read): Handle C_LABEL symbols like - C_STAT symbols. - * h8300-tdep.c (h8300_pop_frame): Reset $sp and $pc correctly. - Flush cached frames just before exiting. - * remote-sim.c (gdbsim_resume): Complain if the program isn't - being run. - * config/h8300/tm-h8300.h (BELIEVE_PCC_PROMOTION): Define. - -Tue May 14 18:05:16 1996 Stu Grossman (grossman@critters.cygnus.com) - - * procfs.c (procfs_thread_alive procfs_stop): Make static. - (procfs_pid_to_str): New routine to print out thread id's in an - intelligible manner. - * sol-thread.c (sol_thread_fetch_registers): Re-order manner in - which supply_register is called to fix bug with writing - individual regs. - * config/sparc/tm-sun4sol2.h: Define default for - target_pid_to_str in case host lacks libthread_db. - -Mon May 13 23:53:30 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in config.in configure configure.in - config/sparc/nm-sun4sol2.h config/sparc/sun4sol2.mh - config/sparc/tm-sun4sol2.h: Use autoconf to config Solaris thread - and pthread support, since pre-2.5 systems don't come with - libthread_db.so.1. - - * procfs.c (info_proc): Use int instead of id_t. Old versions of - Irix don't seem to define this. - -Mon May 13 17:40:58 1996 Jeffrey A Law (law@cygnus.com) - - * top.c (execute_control_command, case while_control): Allow - a while command to be interrupted. - -Mon May 13 16:17:36 1996 Stu Grossman (grossman@critters.cygnus.com) - - * sol-thread.c: More cleanup, add comments. - (sol_thread_resume): Prevent people from trying to step - inactive threads. - (sol_thread_wait sol_thread_fetch_registers - sol_thread_store_registers): Remove unnecessary check for - sol_thread_active. These routines won't get called unless threads - are active. - -Mon May 13 11:29:37 1996 Stan Shebs - - SH3-E support from Allan Tajii : - * sh-tdep.c (sh_reg_names, sh3_reg_names): Add empty names for - float registers. - (sh3e_reg_names): New register name array. - (sh_processor_type_table): Add sh3e processor type. - * config/sh/tm-sh.h (REGISTER_VIRTUAL_TYPE): Fix test. - (REGISTER_NAMES, NUM_REGS, NUM_REALREGS, etc): Adjust for - full set of registers. - * remote-e7000.c (want_sh3, want_sh3_nopc): New globals. - (e7000_fetch_registers, e7000_wait): Use them. - * sh3-rom.c (sh3_regnames): Add float registers. - (sh3e_cmds, sh3e_ops): New globals. - (sh3e_open): New function. - (_initialize_sh3_rom): Rename from _initialize_sh3, set up - sh3e target vector. - -Fri May 10 15:53:38 1996 Stu Grossman (grossman@lisa.cygnus.com) - - * sol-thread.c: Cleanup. gcc -Wall fixes. Add prototypes. - Print out messages instead of codes for thread_db errors. Make - access macros for thread and lwp manipulation. Make cleanups to - fixup inferior_pid in case of errors. - -Thu May 9 19:06:02 1996 Fred Fish - - * aclocal.m4: Remove unused definition of AC_C_CROSS. - * configure.in: Add powerpcle-*-solaris* host and target config - so April 30th change does not get lost next time configure is - rebuilt. - -Thu May 9 14:13:08 1996 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in, breakpoint.c, corelow.c, fork-child.c, inflow.c, - infrun.c, mac-nat.c, procfs.c, remote.c, sol-thread.c, thread.c, - win32-nat.c, config/nm-lynx.h: Rename thread.h to gdbthread.h to - avoid conflict with Solaris /usr/include/thread.h. - -Thu May 9 12:33:32 1996 Rob Savoye - - * abug-rom.c: Config file for the older style ABug monitor that - runs on the mvme13x boards. - * config/m68k/monitor.mt: Add abug support for m68k cross - debugging. - -Wed May 8 20:33:24 1996 Fred Fish - - * infcmd.c (do_registers_info): Always print the raw floating - point value's bytes in big endian order, so the the leftmost bit - is the most significant. - * breakpoint.c (clear_momentary_breakpoints): Remove dead code - that is referenced nowhere else. - (set_breakpoint): Ditto. - (do_enable_breakpoint): Created from enable_once_breakpoint - with a couple of changes. - (enable_breakpoint): Call do_enable_breakpoint with an appropriate - bpdisp enum value to set disposition of breakpoint. - (enable_once_breakpoint): Ditto. - (enable_delete_breakpoint): Ditto. - * breakpoint.h (clear_momentary_breakpoints): Remove prototype. - * symtab.c (find_pc_line): Improve comments. - * xcoffread.c: Ditto. - -Tue May 7 18:37:06 1996 Stan Shebs - - * target.c (debug_to_xfer_memory): Insert line breaks when - dumping the memory block. - -Mon May 6 13:52:52 1996 Stu Grossman (grossman@critters.cygnus.com) - - * fork-child.c (fork_inferior), inferior.h: init_trace_fun now - returns a possibly modified pid. - * inftarg.c (ptrace_him): Now returns pid; - * m3-nat.c (m3_trace_him): Now returns pid; - * infcmd.c (run_command): Minor cleanup. - * infrun.c (wait_for_inferior): Add another check for one_stepped - near where we read the pc to avoid erroneously setting - random_signal for multi-threaded support. - * procfs.c: Add support for Solaris LWPs. Remove def of - LOSING_POLL. Many cleanups... Several workarounds for Solaris - lossage. System call entry and exit are now handled by - dynamically registered handlers. - * (syscallname): Don't barf when handed an unknown syscall - number. - * (info_proc_syscalls): Ditto. - * sol-thread.c: New file. Implements Solaris thread support. - * symfile.c (symbol_file_add): Add call to target_new_objfile to - notify target-dependent code about new symbol tables. - * (clear_symtab_users): Call target_new_objfile to notify it of - the removal of all symbol tables. - * target.c (push_target): Make sure that to_close is non-zero - before calling it. - * target.h (target_new_objfile): Provide default. - * config/alpha/nm-osf2.h: Define LOSING_POLL because this version - of OSF can't hack using poll with /proc. - * config/sparc/nm-sun4sol2.h (target_new_objfile): Define to be - sol-thread-new-objfile. - * config/sparc/sun4sol2.mh: Add sol-thread.o to NATDEFFILES, and - add libthread_db.so.1 to NAT_CLIBS. - * config/sparc/tm-sun4sol2.h: Define PIDGET, TIDGET, and - target_pid_to_str. - -Sat May 4 02:13:34 1996 N Srin Kumar - - * procfs.c (remove_fd): Fix copy of fds to fill hole left after - removal of the requested fd. - -Mon May 6 07:52:48 1996 Michael Meissner - - * rs6000-tdep.c (_initialize_rs6000_tdep): Don't do XCOFF specific - hooks under ELF. - - * config/powerpc/tm-ppc-eabi.h: Define ELF_OBJECT_FORMAT. - -Thu May 2 12:46:14 1996 Jeffrey A Law (law@cygnus.com) - - From Peter Schauer: - * breakpoint.h (enum bpdisp): Add del_at_next_stop. - * breakpoint.c (insert_breakpoints, watchpoint_check, - bpstat_stop_status): Avoid bad references to memory freed via - delete_breakpoint on watchpoints going out of scope. - Do not delete these watchpoints, disable them and change their - disposition to del_at_next_stop instead. - (breakpoint_auto_delete): Delete all breakpoints whose disposition - is del_at_next_stop. - (breakpoint_init_inferior): Use switch to avoid reference to - already deleted breakpoint. - -Wed May 1 17:29:18 1996 Fred Fish - - * Makefile.in (rs6000-nat.o): Depend on xcoffsolib.h. - * config/rs6000/rs6000.mh (NATDEPFILES): Move xcoffread.o ... - * config/rs6000/rs6000.mt (TDEPFILES): ... to here. - * xcoffsolib.c (xcoff_relocate_symtab_hook): Define and initialize. - (solib_info): Call xcoff_relocate_symtab via the hook. - (sharedlibrary_command): Ditto. - * xcoffread.c: Remove all FAKING_RS6000 comments and defines. - (xcoff_add_toc_to_loadinfo_hook): Define and initialize here. - (xcoff_init_loadinfo_hook): Define and initialize here. - (scan_xcoff_symtab): Call xcoff_add_toc_to_loadinfo via the hook. - (xcoff_initial_scan): Call xcoff_init_loadinfo via the hook. - * xcoffsolib.h (xcoff_relocate_symtab_hook): Declare extern func. - * rs6000-tdep.c (_initialize_rs6000_tdep): Add initializations - of xcoff_add_toc_to_loadinfo_hook and xcoff_init_loadinfo_hook. - * rs6000-nat.c (_initialize_core_rs6000): Add initialization - of xcoff_relocate_symtab_hook. - -Tue Apr 30 13:22:02 1996 Michael Meissner - - * configure (powerpcle-*-solaris*): Add Solaris support. - - * config/powerpc/{solaris.m[ht],tm-solaris.h}: New files for - Solaris support. - -Mon Apr 29 16:17:31 1996 Dawn Perchik - - * c-valprint.c (c_val_print): Fix printing for arrays defined - with 0 length. - -Sun Apr 28 15:08:05 1996 Stan Shebs - - Support for bi-endian remote breakpoints. - * remote.c (big_break_insn, little_break_insn): New globals. - (break_insn): Remove. - (remote_insert_breakpoint, remote_remove_breakpoint): Use own - code if REMOTE_BREAKPOINT defined, otherwise call memory - breakpoint functions. - * config/sh/tm-sh.h (REMOTE_BREAKPOINT): Remove. - (BIG_REMOTE_BREAKPOINT, LITTLE_REMOTE_BREAKPOINT): Define. - - * mon960-rom.c (mon960_cmds): Remove forward decl. - (mon960_load): Use current_monitor instead of mon960_cmds. - (mon960_regnames): Remove backslashes from line ends. - (_initialize_mon960): Fix documentation string. - -Sun Apr 28 12:10:35 1996 Fred Fish - - * symfile.h (psymbol_allocation_list): Expand comments which - describe the psymbol allocation list and how each field is - used. - -Sun Apr 28 03:44:30 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * breakpoint.c (delete_breakpoint): Fix bpt->val, bpt->exp - storage leaks. - (breakpoint_re_set_one): Fix b->exp, b->val, b->cond storage leaks. - - * infcmd.c (run_command), solib.c (locate_base): Check for - target_has_execution in addition to inferior_pid, a core file - from a threaded program is yielding a non-zero inferior_pid. - - * sparc-tdep.c (get_saved_register): Handle window registers - in a dummy frame correctly. - -Sat Apr 27 20:38:32 1996 Fred Fish - - * Makefile.in (CLIBS): Move $(MMALLOC) past all other libs, - so that anything that wants an allocation function not yet pulled - in, will get it from mmalloc rather than a system library. - * Makefile.in (INSTALLED_LIBS): Reorder to match order of CLIBS, - to avoid surprising results when used. - -Sat Apr 27 00:12:05 1996 Dawn Perchik (dawn@cygnus.com) - - * stabsread.c: Changes and bug fixes for cfront support. - Fix bug for class data members. - Fix parsing bug when no base classes exist. - Fix memory bug - allocate space for cplusplus specific info. - Add support for static data. - Add prototypes for static functions. - Enhance comments to show what each function expects to parse. - Cleanup code. - * stabsread.c(resolve_cont),dbxread.c(resolve_cont): Rename - function to resolve_cfront_continuation. - -Fri Apr 26 23:58:26 1996 Jeffrey A Law (law@cygnus.com) - - * infrun.c (wait_for_inferior): Call registers_changed when - restarting the inferior to get over a nullified instruction. - -Tue Apr 24 12:12:55 1996 Dawn Perchik (dawn@cygnus.com) - - * dbxread.c,stabsread.c,gdbtypes.c,partial-stab.h,valops.c: - Add new support for parsing cfront stabs. - -Wed Apr 24 00:32:55 1996 Jeffrey A Law (law@cygnus.com) - - * infrun.c (wait_for_inferior): Move "have_waited" label - outside of #ifdef conditionals. Don't trash the wait status - if we get a signal and the current instruction is nullified. - -Mon Apr 22 20:17:01 1996 Fred Fish - - * Makefile.in (VERSION): Bump version number to 4.16.1. - * NEWS: Update for 4.16 release. - -Mon Apr 22 16:32:29 1996 Stan Shebs - - * monitor.h: Clean up comment formatting. - (current_monitor): Remove decl. - (LOADTYPES, LOADPROTOS, INIT_CMD, etc): Remove definitions. - (push_monitor, SREC_SIZE): Remove. - * monitor.c: Expand old macro into current_monitor derefs - everywhere. - * remote-os9k.c (current_monitor): Remove definition. - -Mon Apr 22 14:54:45 1996 Mark Alexander - - * corefile.c (specify_exec_file_hook): Allow arbitrary number of - hooks. - (call_extra_exec_file_hooks): New function. - * h8300-tdep.c: Lint; add .h files to provide missing declarations, - remove unused variables. - (set_machine_hook): New function. - (_initialize_h8300m): Initialize it. - -Fri Apr 19 15:03:49 1996 Ian Lance Taylor - - * remote-mips.c (encoding): Don't specify size, to avoid bug in - SunOS native compiler. - -Thu Apr 18 18:46:57 1996 Stan Shebs - - * monitor.c: Use int rather than LONGEST for values, since - the formatting strings are not prepared to accept long longs. - -Wed Apr 17 20:17:27 1996 Doug Evans - - * arm-tdep.c (initialize_arm_tdep): Make apcs32 a `zinteger'. - -Tue Apr 16 17:38:23 1996 Stu Grossman (grossman@critters.cygnus.com) - - * corelow.c (add_to_thread_list): Make sure reg_sect is non-null - before de-referencing it. Prevents deref of NULL pointer if core - file lacks .reg section. - * defs.h: Rename floatformat_{to from}_long_double to - floatformat_{to from}_doublest. Get rid of FLOATFORMAT_{TO - FROM}... macros. - * findvar.c (extract_floating store_floating): Change all refs to - FLOATFORMAT_{FROM TO}... to floatformat_{from to}_doublest. - * utils.c: Change floatformat_{to from}_long_double to - floatformat_{to from}_doublest cuz the new routines will use - whatever size (double or long double) is appropriate. - * config/i960/tm-i960.h (REGISTER_CONVERT_TO_VIRTUAL - REGISTER_CONVERT_TO_RAW): Change FLOATFORMAT... macros to - floatformat... routine calls. - -Mon Apr 15 16:34:11 1996 Per Bothner - - * stabsread.c (read_type): Move handling of '@' from type - number handling to handling of types proper (as emitted by gcc!). - For typedefs, allocate the typedef type before reading its - definition, to properly handling recursive types. - -Mon Apr 15 11:19:26 1996 Jeffrey A Law (law@cygnus.com) - - * ch-exp.c (calculate_array_length): Fix prototype. - -Sat Apr 13 14:21:16 1996 Stu Grossman (grossman@critters.cygnus.com) - - * remote-nindy.c (nindy_open): Acquire more target state so that - user can attach to a previously running program. - * (nindy_fetch_registers nindy_store_registers): Get rid of fp - conversion code. That's all handled in {extract store}_floating - now. - * utils.c (floatformat_to_double): Don't bias exponent when - handling zero's, denorms or NaNs. - * config/i960/tm-i960.h (REGISTER_CONVERT_TO_VIRTUAL - REGISTER_CONVERT_TO_RAW): Change to using DOUBLST and - FLOATFORMAT_TO/FROM_DOUBLEST macros. - * config/i960/tm-nindy960.h: Undefine - REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW, and - REGISTER_CONVERTIBLE. These are no longer necessary now that all - the magic happens in extract/store_floating. - -Sat Apr 13 02:58:02 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * eval.c (evaluate_subexp_standard): Report error when attempting to - evaluate subscripts for types which cannot be subscripted. - - * valarith.c (value_x_binop, value_x_unop): Add noside parameter. - Return a zero value with the return type of the member function - if noside is EVAL_AVOID_SIDE_EFFECTS instead of calling the member - function. - * values.h (value_x_binop, value_x_unop): Update prototypes - accordingly. - * eval.c (evaluate_subexp_standard): Update all callers of - value_x_binop, value_x_unop accordingly. - - * valarith.c (value_neg, value_complement): Perform ANSI C/C++ - integral promotion on operands. - -Fri Apr 12 13:19:27 1996 Fred Fish - - * README: Update for 4.16 release. - * configure.in (AC_CHECK_FUNCS): Also check for sbrk. - * configure: Regenerate with autoconf. - * config.in: Regenerate with autoheader. - * main.c (main): Only use sbrk() when HAVE_SBRK is defined. - * top.c (command_loop): Ditto. - -Fri Apr 12 09:45:29 1996 Stu Grossman (grossman@critters.cygnus.com) - - * defs.h: Define TARGET_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT - defaults for bi-endian targets. Replace function pointers for - floatformat routines with macros. No need for these to be runtime - selectable. - * findvar.c: Get rid of floatformat function pointers. Use - macros in extract_floating and store_floating. - * remote-nindy.c (nindy_fetch_registers nindy_store_registers): - Use floatformat macros. - -Thu Apr 11 21:28:02 1996 Fred Fish - - From: Miles Bader - * configure.in (AC_CHECK_HEADERS): check for endian.h. - Use AC_CHECK_TOOL to find AR & RANLIB. Add AC_PROG_AWK. - Add host & target cases for i[345]86-*-gnu*. - * config.in: Regenerate with autoheader. - * configure: Regenerate with autoconf. - * Makefile.in (AR, AWK): Set from corresponding autoconf substs. - (init.c): Don't scan mig-generated files. - * defs.h (endian.h): Include if HAVE_ENDIAN_H defined. - * config/nm-m3.h (ATTACH_NO_WAIT): Define. - * infcmd.c (attach_command): Use "#ifndef ATTACH_NO_WAIT" - rather than "#ifndef MACH". - -Thu Apr 11 18:49:42 1996 Stan Shebs - - * remote.c (remotewritesize): New GDB variable, controls size - of memory packets sent to the target. - -Thu Apr 11 13:47:52 1996 Stu Grossman (grossman@critters.cygnus.com) - - * dcache.c: Add prototypes. Make many functions static. - * (dcache_peek dcache_fetch dcache_poke): Make dcache_fetch and - dcache_poke call dcache_xfer_memory directly in order to fix - problems with turning off dcache. dcache_peek is now unnecessary, - so it goes away. - - * defs.h: Define new macros HOST_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT - and TARGET_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT to specify a pointer - to a struct floatformat. This allows for better handling of - targets whose floating point formats differ from the host by more - than just byte order. - * (floatformat_to_long_double floatformat_from_long_double): - Prototypes for new functions in utils.c. - * (floatformat_to_doublest floatformat_from_doublest): Prototypes - for pointers to floating point conversion functions. The actual - function uses either double or long double if the host supports it. - * findvar.c (floatformat_to_doublest floatformat_from_doublest): - Initialize to point at correct function depending on HAVE_LONG_DOUBLE. - * (extract_floating store_floating): Rewrite. Now, if host fp - format is the same as the target, we just do a copy. Otherwise, - we call floatformat_{to from}_doublest. - * remote-nindy.c (nindy_xfer_inferior_memory): Change param - `write' to `should_write'. - * utils.c (floatformat_to_long_double - floatformat_from_long_double): New routines that implement long - double versions of functions in libiberty/floatformat.c. - * config/i960/tm-i960.h (TARGET_LONG_DOUBLE_FORMAT): Define this for - i960 extended real (80 bit) numbers. - * nindy-share/nindy.c (ninMemGet ninMemPut): Return number of bytes - actually read or written. - -Wed Apr 10 02:56:06 1996 Wilfried Moser - - * ch-valprint.c (chill_val_print): Remove call to calculate_array_length. - (calculate_array_length): Move function from here ... - - * ch-exp.c (calculate_array_length): ... to here. - (parse_primval): If we have a symbol with an array type - and the length is 0, call calculate_array_length. - -Tue Apr 9 01:23:05 1996 Wilfried Moser - - * eval.c (evaluate_subexp_standard): In case of TYPE_CODE_SET: - Add some checks for powerset compatibility. - - * valops.c (value_slice): Use lowbound instead of lowerbound for - call to slice_range_type to get correct bounds. - -Mon Apr 8 12:53:56 1996 Fred Fish - - * Makefile.in (scm-exp.o, scm-lang.o, scm-valprint.o): Add targets and - dependencies. - * scm-lang.c (gdb_string.h): Include. - * objfiles.c (add_to_objfile_sections): Cast second arg of obstack_grow - call to correct type (char *). - * cp-valprint.c (cp_print_static_field): Ditto. - * somsolib.c (som_solib_create_inferior_hook): Add a declaration - for external find_unwind_entry function (from hppa-tdep.c). - * remote-pa.c (remote_write_bytes, remote_read_bytes): Change - type of second arg to "char *" to be type compatible with - dcache. - (remote_wait): Cast second arg to strtol to correct type. - * hppa-tdep.c (compare_unwind_entries): Change argument types to - "const void *" to be type compatible with qsort, and then - assign to local args prior to use. - -Mon Apr 8 15:35:52 1996 Jeffrey A Law (law@cygnus.com) - - * infptrace.c (kill_inferior): Remove call to "kill"; update - comments. - -Mon Apr 8 14:05:07 1996 Geoffrey Noer - - * remote-e7000.c: don't append :23 to target port if __WIN32__ - is defined (it's WinGDB). - -Sun Apr 7 22:34:29 1996 Fred Fish - - From: Miles Bader - * gnu-nat.c, gnu-nat.h, msg.defs, exc_request.defs, i386gnu-nat.c, - msg_reply.defs, notify.defs, process_reply.defs, reply_mig_hack.awk, - config/nm-gnu.h, config/i386/{i386gnu.mh, i386gnu.mt, nm-gnu.h, - m-i386gnu.h, xm-i386gnu.h}: New files for GNU hurd. - -Sun Apr 7 13:32:41 1996 Fred Fish - - * configure.in (case host): Add i386sco5 host. - * configure: Regenerate. - - From: Robert Lipe - Add support for SCO OpenServer 5 (a.k.a. 3.2v5*) This - target is an SVR3.2 with COFF, ELF, and shared libes, but - no /proc. - * config/i386/i386sco5.mh: New file. - * config/i386/nm-i386sco5.h: New file. - -Sat Apr 6 08:55:22 1996 Fred Fish - - * bcache.c (bcache): When size of chunk to cache is exactly equal to - BCACHE_MAXLENGTH, stash chunk as unique copy. - -Sat Apr 6 00:46:26 1996 Fred Fish - - * symfile.c (INLINE_ADD_PSYMBOL): Remove ifdef. - (add_psymbol_to_list): Add an arg for passing CORE_ADDR values and - use it, rather than calling add_psymbol_addr_to_list. - (add_psymbol_addr_to_list): Delete. - (add_psymbol_to_list): Make psymbol static to avoid random data in - gaps due to alignment of structure members. - * symfile.h (INLINE_ADD_PSYMBOL, ADD_PSYMBOL_TO_LIST, - ADD_PSYMBOL_ADDR_TO_LIST): Remove. Real world tests show no - performance improvements by inlining via complicated macros and - they just make gdb larger and harder to maintain. - * dwarfread.c (add_enum_psymbol): Replace ADD_PSYMBOL_TO_LIST - and/or ADD_PSYMBOL_ADDR_TO_LIST macro(s) with call to - add_psymbol_to_list with appropriate long or CORE_ADDR args. - (add_partial_symbol): Ditto. - * partial-stab.h: Ditto. - * os9kread.c (read_os9k_psymtab): Ditto - * mdebugread.c (parse_partial_symbols): Ditto. - (handle_psymbol_enumerators): Ditto. - (demangle.h): Include. - * hpread.c (hpread_build_psymtabs): Ditto. - (hpread_build_psymtabs): Ditto. - (demangle.h): Include - -Thu Apr 4 20:16:55 1996 Fred Fish - - * configure.in: Check for setpgid function. - * config.in: Regenerate with autoheader. - * configure: Regenerate with autoconf. - * inflow.c (_initialize_inflow): Only try to use _SC_JOB_CONTROL - if it is actually defined. - (gdb_setpgid): Use HAVE_SETPGID. - * ch-exp.c: Change include of to "gdb_string.h". - * c-exp.y, f-exp.y, m2-exp.y: Ditto. - * c-exp.y, serial.c: Include . - * config/m68k/nm-news.h: Add typedef for pid_t which is - apparently missing from . Enclose entire - file in NM_NEWS_H ifndef and define when included. - * config/mips/nm-news-mips.h: Ditto. - * config/m68k/tm-m68k.h (REGISTER_CONVERT_TO_VIRTUAL, - REGISTER_CONVERT_TO_RAW): Change name of temporary variable. - -Thu Apr 4 19:04:18 1996 Stan Shebs - - * arm-xdep.c: Move native-specific code to here from arm-tdep.c. - * arm-tdep.c (arm_apcs_32): New global. - (arm_addr_bits_remove, arm_saved_pc_after_call, - arm_push_dummy_frame, arm_pop_frame): New functions. - (arm_skip_prologue): Updated version from Richard Earnshaw. - (_initialize_arm_tdep): Add set/show "apcs32". - * config/arm/tm-arm.h (ADDR_BITS_REMOVE): Call - arm_addr_bits_remove. - (SAVED_PC_AFTER_CALL): Call arm_saved_pc_after_call. - (frame_find_saved_regs): Declare properly. - (PUSH_DUMMY_FRAME): Call arm_push_dummy_frame. - (POP_FRAME): Call arm_pop_frame, use ADDR_BITS_REMOVE instead of - explicit mask. - * config/arm/nm-arm.h: New file. - * config/arm/xm-arm.h (KERNEL_U_ADDR, FETCH_INFERIOR_REGISTERS): - Move definitions to nm-arm.h. - * config/arm/arm.mh (NAT_FILE): Define. - - * symfile.c (generic_load): Initialize data_count properly. - -Thu Apr 4 17:17:53 1996 Fred Fish - - * symmisc.c (print_objfile_statistics): Print memory used by - psymbol cache obstack. - -Thu Apr 4 15:43:07 1996 Stan Shebs - - * symfile.c (report_transfer_performance): New function. - (generic_load): Call it to report transfer rate. - * remote-e7000.c (e7000_load): Ditto. - -Mon Apr 1 16:31:00 1996 Stan Shebs - - * mpw-make.sed: Change references to config.h to be in objdir, - edit out rules to rebuild config.h. - -Mon Apr 1 08:32:23 1996 Fred Fish - - * hppa-tdep.c (hppa_pop_frame): Call clear_proceed_status before - proceeding. - -Sun Mar 31 16:15:43 1996 Fred Fish - - * hppah-nat.c (store_inferior_registers, store_inferior_registers, - fetch_register, child_xfer_memory): Use call_ptrace function supplied - by infptrace.c rather than calling ptrace directly. - -Sun Mar 31 15:39:00 1996 Stan Shebs - - * mon960-rom.c: Cleanups and elimination of unused code, - clarify documentation string. - (mon960_serial, mon960_ttyname): Remove. - * config/i960/tm-mon960.h (ADDITIONAL_OPTIONS, - ADDITIONAL_OPTION_CASES, ADDITIONAL_OPTION_HELP): Remove. - -Sat Mar 30 11:00:22 1996 Fred Fish - - * configure.in: Check whether printf family supports printing - long doubles or not and define PRINTF_HAS_LONG_DOUBLE if so. - * acconfig.h: Provide default undef for PRINTF_HAS_LONG_DOUBLE. - * configure: Regenerate. - * valprint.c (print_floating): Use PRINTF_HAS_LONG_DOUBLE. - * c-exp.y (parse_number): Use PRINTF_HAS_LONG_DOUBLE. - * configure.in: Fix have_gregset and have_fpregset autoconf - variable names so that they match the pattern required to - cache them. - -Fri Mar 29 21:39:56 1996 Fred Fish - - * core-aout.c (fetch_core_registers): Cast core_reg_size to int - before testing against reg_ptr. - * eval.c (evaluate_subexp_standard): Cast type of - TYPE_FN_FIELD_VOFFSET to int. - * findvar.c (extract_signed_integer, extract_unsigned_integer, - extract_long_unsigned_integer): Cast type of sizeof to int. - * values.c (unpack_field_as_long, modify_field): Ditto. - * valops.c (value_assign, call_function_by_hand): Ditto. - * infcmd.c (do_registers_info): Ditto. - * ser-tcp.c (tcp_open): Ditto. - * remote.c (putpkt): Ditto. - * dcache.c (dcache_peek): Ditto. - * dcache.c (dcache_poke): Ditto. - * m2-exp.y (yylex): Ditto. - * gnu-regex.c (re_match_2): Ditto. - * f-lang.c (ADD_BF_SYMNUM, saved_bf_list_end, tmp_bf_ptr): Ifdef - out unused macro definition and variables. - * inftarg.c (proc_wait): Move from main.c to here, and make static. - * valprint.c (val_print_string): Change bufsize from int to unsigned. - * main.c (wait.h): Include. - * top.c (command_line_input): Remove unused variable "c". - * f-typeprint.c (f_type_print_varspec_prefix): Add missing enum - value TYPE_CODE_TYPEDEF to switch statement. - (f_type_print_varspec_suffix): Add missing enum value - TYPE_CODE_TYPEDEF to switch statement. - * ch-exp.c (parse_primval): Add remaining enumeration values to - switch statement, with no specific action. - (ch_lex): Add LOC_UNRESOLVED in switch statement. - (pushback_token): Ifdef out, since code using it is ifdef'd out. - * stabsread.c (cleanup_undefined_types): Remove unused label - "badtype". - * objfiles.h (print_symbol_bcache_statistics): Add prototype. - * maint.c (objfiles.h): Include. - (maintenance_print_statistics): Remove unused variable "temp". - * minsyms.c (lookup_minimal_symbol_solib_trampoline): Remove - unused variable "found_file_symbol". - * m2-exp.y (yylex): Add LOC_UNRESOLVED case to switch. - * language.c (lang_bool_type): Use existing function local type - variable rather than create block local variables. - * solib.c (disable_break): Enclose in ifndef SVR4_SHARED_LIBS. - * infptrace.c (wait.h, command.h): Include. - * ser-tcp.c (gdb_string.h): Include - * i386-tdep.c (codestream_seek): Change "place" to CORE_ADDR. - (i386_get_frame_setup): Change "pc" from int to CORE_ADDR. - * command.c (complete_on_enum): Make assignment used as truth value - explictly check against NULL. - (wait.h): Include. - * infrun.c (wait_for_inferior): Ifdef out prologue_pc since code - that uses it is ifdef'd out. - * parser-defs.h: Add prototype for write_dollar_variable. - * infrun.c: Add prototype for write_pc_pid. - * breakpoint.h: Add prototype for re_enable_breakpoints_in_shlibs. - * symmisc.c (bcache.h): Include. - * bcache.h: Add prototype for print_bcache_statistics. - * symfile.c: Include . - * printcmd.c (print_scalar_formatted): Change len to unsigned int. - * valarith.c (value_equal): Cast result of TYPE_LENGTH to int. - * valarith.c (value_binop): Change result_len, promoted_len1, - and promoted_len2 to unsigned int. - * valarith.c (value_subscripted_rvalue): Change elt_offs and - elt_size to unsigned int. - * valops.c (value_array): Change typelength to unsigned int. - (destructor_name_p): Change len to unsigned int. - * scm-lang.h (scm_parse): Add prototype for scm_unpack. - * symfile.c (decrement_reading_symtab): Change return type to void. - * valarith.c (value_subscript): Remove unused variable "word". - (value_subscript): Remove unused variable "tint". - * valops.c (auto_abandon): Ifdef out, since code using it is also - ifdef'd out. - * eval.c (init_array_element): Remove unused variable "val". - * Makefile.in (values.o): Depends on scm-lang.h. - (command.o): Depends upon wait_h. - (ser-tcp.o): Depends upon gdb_string.h. - (infptrace.o): Depends upon wait_h and command_h. - (maint.o): Depends on objfiles.h and symfile.h. - * values.c (allocate_repeat_value): Remove unused variable - "element_type". - (scm-lang.h): Include. - * breakpoint.c (create_longjmp_breakpoint): Enclose in - GET_LONGJMP_TARGET define, unused otherwise. - * config/i386/nm-linux.h: Add prototypes for i386_insert_watchpoint, - i386_remove_watchpoint and i386_stopped_by_watchpoint. - -Thu Mar 28 12:53:19 1996 Doug Evans - - * configure.in (sparc64-*-solaris2*): Delete. - Stick with sparc-*-solaris2*. - * configure: Regenerated. - -Thu Mar 28 06:51:26 1996 Fred Fish - - * valops.c (value_assign): Make copy of internal variable value - before returning it as a new value, since it is owned by the - internal variable and will be freed along with it. - -Wed Mar 27 08:36:17 1996 Jeffrey A Law (law@cygnus.com) - - * From Peter Schauer. - * breakpoint.c (breakpoint_re_set_one): Keep temporary - breakpoints bp_until, bp_finish, bp_watchpoint_cope, bp_call_dummy - and bp_step_resume in case breakpoint_re_set_one is called due - to a step over a dlopen call. - * infrun.c (wait_for_inferior): Always remove breakpoints from - inferior in BPSTAT_WHAT_CHECK_SHLIBS case. - -Tue Mar 26 13:15:32 1996 Fred Fish - - * config/mips/tm-mips.h (COERCE_FLOAT_TO_DOUBLE): Only prefer - non-prototyped case over prototyped case for C. - * config/pa/tm-hppa.h (COERCE_FLOAT_TO_DOUBLE): Ditto. - -Sat Mar 23 17:24:28 1996 Fred Fish - - * os9kread.c (os9k_process_one_symbol): Note nonportable - assumption that an int can hold a char *. - - * bcache.h (struct hashlink): Wrap data[] inside union with - double to force longest alignment. - (BCACHE_DATA): New macro to access data[]. - (BCACHE_ALIGNMENT): New macro to get offset to data[]. - * bcache.c (lookup_cache, bcache): Use BCACHE_DATA to get - address of cached data. Use BCACHE_ALIGNMENT to compute - amount of space to allocate for each hashlink struct. - -Sat Mar 23 12:14:02 1996 Fred Fish - - * ch-lang.c (evaluate_subexp_chill): Fix typo. - -Thu Mar 21 08:27:19 1996 Fred Fish - - * Makefile.in (VERSION): Bump version to 4.15.3 - -Thu Mar 21 10:56:41 1996 Ian Lance Taylor - - * config.in: Rename from config.h.in. - * configure.in: Call AC_CONFIG_HEADER with config.h:config.in. - Change CONFIG_HEADERS test in AC_OUTPUT accordingly. - * configure: Rebuild. - * Makefile.in (stamp-h): Depend upon config.in, not config.h.in. - Set CONFIG_HEADERS to config.h:config.in. - -Tue Mar 19 12:47:51 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * partial-stab.h (case N_ENDM): Finish current partial symbol - table for Solaris 2 cc. - -Tue Mar 19 10:39:15 1996 Jeffrey A Law (law@cygnus.com) - - * rs6000-nat.c (exec_one_dummy_insn): Don't clobber the - PC in the registers array. From Peter Schauer. - -Mon Mar 18 13:47:09 1996 Fred Fish - - * symfile.c (reread_symbols): Reinitialize bcache struct - members to zero using memset. Also use memset to reinit - global_psymbols and static_psymbols, rather than explicitly - resetting each structure member. - -Sat Mar 16 19:47:36 1996 Fred Fish - - * configure.in: Add fragment to create stamp-h. - - From Peter Schauer - * configure.in (AC_CHECK_HEADERS): Check for link.h. - * configure: Regenerate with autoconf. - * config.h.in: Regenerate with autoheader. - * config/i386/nm-linux.h: Include solib.h only if HAVE_LINK_H - is defined. - * solib.c: Exclude most of the code if HAVE_LINK_H is not defined. - * config/i386/linux.mh: Reinstate XM_CLIBS, it is needed for - older a.out based systems. - -Sat Mar 16 16:45:43 1996 Fred Fish - - * config.h.in: New file. - * acconfig.h: New file, for autoheader. - * configure.in (AC_CONFIG_HEADER): Add, generate config.h. - * configure: Regenerate. - * Makefile.in (defs_h): Add config.h - (distclean): Remove config.h and stamp-h during distclean. - (config.h, stamp-h): New targets to remake config.h when necessary. - * defs.h (config.h): Include before any other includes or defines. - * i386-tdep.c (gdb_string.h): Move include after include of defs.h. - * i386v4-nat.c (defs.h): Include before testing HAVE_SYS_PROCFS_H. - -Sat Mar 16 14:55:27 1996 Fred Fish - - From Peter Schauer - * Makefile.in (INSTALLED_LIBS): Make sure that @LIBS@ will not - result in an empty line, to work around a bug in native Ultrix 4.4 - and OSF/1-3.2C make. - -Sat Mar 16 13:33:17 1996 Fred Fish - - * configure.in: Add gdbserver to configdirs under linux. - * configure: Regenerate. - -Fri Mar 15 12:06:58 1996 J.T. Conklin - - * config/i386/nm-nbsd.h (FLOAT_INFO): Comment out. - * config/i386/tm-nbsd.h (NUM_REGS): Define. - -Thu Mar 14 10:31:18 1996 Jeffrey A Law (law@cygnus.com) - - * solib.c (solib_break_names): Add _r_debug_state for - vanilla SVR4 implementations. From Peter Schauer. - -Mon Mar 11 14:24:57 1996 Dawn Perchik - - * mon960-rom.c: New file; support mon960 rom monitor on i960. - * monitor.c (monitor_debug): Change remotedebug to buffer strings. - * monitor.c (monitor_open): Add test for flag MO_NO_ECHO_ON_OPEN before - epecting prompt and echo during open. - * monitor.c (monitor_stop): Add test for flag MO_SEND_BREAK_ON_OPEN to - determine if break should be sent as stop command. - * monitor.h: Add flags MO_NO_ECHO_ON_OPEN and MO_SEND_BREAK_ON_OPEN. - * i960-tdep.c (mon960_frame_chain_valid): New function for getting - stack frame on mon960. - * Makefile.in: Add mon960 files. - * configure.in: Changed i960-*-coff* and i960-*-elf* to target mon960; - added i960-nindy-coff* and i960-nindy-elf* for target nindy. - * configure: Regenerated. - * config/i960/mon960.mt, config/i960/tm-mon960.h: New files; - support mon960 rom monitor on i960. - -Mon Mar 11 11:02:47 1996 Steve Chamberlain - - With Michael Snyder: - * i386-tdep.c (skip_trampoline_code): Fix strncmp length. - * win32-nat.c (CHECK, DEBUG*, debug_*): New. - (handle_load_dll): Don't reload symbols. - (handle_exception): Use the DEBUG_* names. - (child_wait): Add DEBUG_* code. - (_initialize_inftarg): Add new commands to set debug_ names. - -Mon Mar 11 09:19:58 1996 Jeffrey A Law (law@cygnus.com) - - * From Peter Schauer: - * breakpoint.c (insert_breakpoints): Use ALL_BREAKPOINTS_SAFE. - (bpstat_stop_status): Likewise. - (remove_solib_event_breakpoints): Likewise. - (clear_momentary_breakpoints): Likewise. - (re_enable_breakpoints_in_shlibs): Don't reenable a breakpoint - if we still can't read the memory for that breakpoint. - (mention): Add bp_shlib_event case to keep gcc quiet. - -Fri Mar 8 12:08:12 1996 Jeffrey A Law (law@cygnus.com) - - * breakpoint.h (enum enable): New enum shlib_disabled for - shared library breakpoints that have been temporarily disabled. - * breakpoint.c: Handle temporarily disabled shared library - breakpoints like disabled breakpoints in most places. - (insert_breakpoints): Use shlib_disabled to indicate - that an unsettable breakpoint is only temporarily disabled. - (re_enable_breakpoints_in_shlibs): New function. - * corelow.c (solib_add_stub): After adding shared libraries, - try to reenable any temporarily disabled breakpoints. - * infcmd.c (attach_command): Likewise. - * infrun.c (wait_for_inferior): Likewise. - -Fri Mar 8 11:41:25 1996 Ian Lance Taylor - - * defs.h (extract_long_unsigned_integer): Declare. - * findvar.c (extract_long_unsigned_integer): New function. - * printcmd.c (print_scalar_formatted): Use it. - * valprint.c (val_print_type_code_int): Likewise. - -Thu Mar 7 17:40:50 1996 Stan Shebs - - * infcmd.c (do_registers_info): Ignore anonymous registers. - * sh-tdep.c (set processor): New command to set specific - processor type. - (sh_reg_names, sh3_reg_names): Arrays of register names for - SH and SH3 processors. - (sh_set_processor_type): New function. - * sh3-rom.c (sh3_open): Call it. - (sh3_regname): Add names of all the bank registers. - (sh3_supply_register): Clean up formatting. - * config/sh/tm-sh.h (NUM_REGS, NUM_REALREGS): Increase to include - bank registers. - (REGISTER_NAMES): Add names of bank registers. - (FP15_REGNUM): Define. - (REGISTER_VIRTUAL_TYPE): Use it. - * monitor.c: Clean up some comments. - -Thu Mar 7 12:09:51 1996 J.T. Conklin - - * i386b-nat.c: Revert part of Mar 5 change. FreeBSD collapsed the - s* and t* symbols too. - -Thu Mar 7 15:18:51 1996 James G. Smith - - * symfile.c (generic_load): Avoid division by zero. - -Wed Mar 6 17:57:59 1996 Jeffrey A Law (law@cygnus.com) - - * breakpoint.c (bfd_lookup_symbol): Provide for all SVR4 systems, - not just those with HANDLE_SVR4_EXEC_EMULATORS. - - From Peter Schauer: - * breakpoint.c (internal_breakpoint_number): Move to file scope. - (create_solib_event_breakpoint): Use an internal breakpoint number. - -Wed Mar 6 00:32:44 1996 Wilfried Moser - - * valarith.c (value_in): Change builtin_type_chill_bool to - LA_BOOL_TYPE. - -Tue Mar 5 23:48:36 1996 Wilfried Moser - - * ch-exp.c (parse_primval): Handle CARD, MAX, MIN. - (match_string_literal): Handle control sequence. - (match_character_literal): Deto. - - * ch-lang.c (chill_printchar): Change formating of nonprintable - characters from C'xx' to ^(num). - (chill_printstr): Deto. - (value_chill_card, value_chill_max_min): New functions to process - Chill's CARD, MAX, MIN. - (evaluate_subexp_chill): Process UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN. - - * expression.h (exp_opcode): Add UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN - for Chill's CARD, MAX, MIN. - - * valarith.c (value_in): Add processing of TYPE_CODE_RANGE - and change return type from builtin_type_int to - builtin_type_chill_bool. - -Tue Mar 5 18:54:04 1996 Stan Shebs - - * config/nm-nbsd.h (link_object, lo_name, etc): Move to here - from config/nm-nbsd.h. - * config/sparc/nm-nbsd.h (regs, fp_status, etc): Move to here - from config/sparc/tm-nbsd.h. - - * config/m68k/nm-hp300hpux.h (FIVE_ARG_PTRACE): Define here - instead of in config/m68k/xm-hp300hpux.h. - -Tue Mar 5 12:05:35 1996 J.T. Conklin - - * i386b-nat.c, m68knbsd-nat.c (fetch_core_registers): Provide - implementation for NetBSD systems. - -Mon Mar 4 23:44:16 1996 Per Bothner - - * valarith.c (binop_user_defined_p): Return 0 for BINOP_CONCAT. - (value_concat): Handle varying strings (add COERCE_VARYING_ARRAY). - - * ch-lang.c (evaluate_subexp_chill case MULTI_SUBSCRIPT): Error - if "function" is pointer to non-function. - -Mon Mar 4 17:47:03 1996 Stan Shebs - - * top.c (print_gdb_version): Update copyright year. - -Mon Mar 4 14:44:54 1996 Jeffrey A Law (law@cygnus.com) - - From Peter Schauer: - * infrun.c (wait_for_inferior): Remove breakpoints and - switch terminal settings before calling SOLIB_ADD. - * solib.c (enable_break, SVR4 variant): Don't map in symbols - for the dynamic linker, the namespace pollution causes real - problems. - -Sun Mar 3 17:18:57 1996 James G. Smith - - * remote-mips.c (common_breakpoint): Explicitly terminate the - returned buffer. - -Wed Feb 28 22:32:18 1996 Stan Shebs - - From Wilfried Moser : - * remote.c (remote_detach): Send a command 'D' to the target - when detaching, update the function's comments. - -Thu Jun 6 16:11:38 1996 Miles Bader - - * gnu-nat.c (thread_cmd_list): New declaration. - (parse_int_arg): New function. - -Wed Jun 5 17:28:04 1996 Miles Bader - - * gnu-nat.h (struct proc): Add DETACH_SC field. - * gnu-nat.c (make_proc): Set DETACH_SC. - (struct inf): Add DETACH_SC & DEFAULT_THREAD_DETACH_SC fields. - (make_inf): Set DETACH_SC & DEFAULT_THREAD_DETACH_SC fields. - (add_thread_commands): Add set/show for detach-suspend-count. - Add takeover-suspend-count cmd. - (inf_detach): Set suspend counts to the detach SC, not 0. - (set_thread_detach_sc_cmd, show_thread_detach_sc_cmd, - set_task_detach_sc_cmd, show_task_detach_sc_cmd, - set_thread_default_thread_detach_sc_cmd, - show_thread_default_thread_detach_sc_cmd): New functions. - (show_task_cmd): Also show detach-suspend-count values. - (thread_takeover_sc_cmd): New function. - -Fri May 31 16:49:24 1996 Miles Bader - - * gnu-nat.c (show_thread_run_cmd): Actually print state. - -Thu May 30 10:47:56 1996 Miles Bader - - * gnu-nat.c (inf_signal): Make unforwardable exceptions an error. - -Tue May 28 17:06:36 1996 Miles Bader - - * gnu-nat.c (inf_validate_stopped): proc_getprocinfo takes a - pointer to the flags now, not the flags themselves. - -Mon May 27 13:31:17 1996 Miles Bader - - * gnu-nat.c (gnu_wait): Print debugging msgs for pending execs. - (gnu_create_inferior): Check return from ptrace. - -Sun May 26 16:56:35 1996 Miles Bader - - * gnu-nat.h (struct proc): Add DEAD field. - * gnu-nat.c (make_proc): Initialize DEAD. - (inf_set_traced, inf_validate_task_sc, inf_validate_procs: Frob it. - (gnu_wait): Only abort for 0 threads if the task isn't dead. - -Sat May 25 17:06:05 1996 Miles Bader - - * gnu-nat.c (inf_signal): Pass SIGCODE when posting a signal. - -Wed May 22 18:44:28 1996 Miles Bader - - * gnu-nat.c (S_proc_wait_reply): Add SIGCODE argument. - (inf_set_traced): Only give no-signal-thread error message if - turning *on* tracing. - -Wed May 15 13:03:16 1996 Miles Bader - - * gnu-nat.c (inf_validate_procs): If INF has no threads, always - set inf->threads_up_to_date to 0. - (inf_signal): Pass in new SIGCODE argument to msg_sig_post_untraced. - (gnu_wait): Pass in new TIMEOUT arg to interrupt_operation. - (proc_update_sc): Cast thread state arg to thread_set_state. - (proc_get_state): Cast thread state arg to thread_get_state. - (inf_validate_task_sc): Cast task_basic_info arg to task_info. - * i386gnu-nat.c (gnu_fetch_registers, gnu_store_registers): Call - inf_update_procs before we lookup the thread. - * config/i386/i386gnu.mh (MH_CFLAGS): New variable. - -Tue May 7 17:52:33 1996 Miles Bader - - * gnu-nat.c (gnu_kill_inferior): Use inf_set_task to clear the task. - -Mon May 6 19:06:49 1996 Miles Bader - - * gnu-nat.c (inf_set_traced): Use msg_set_init_int with - INIT_TRACEMASK instead of setting the exec flags. - -Fri May 3 19:10:57 1996 Miles Bader - - * gnu-nat.c (inf_validate_procs): Don't clear INF->task if we find - the task's died, so others have a chance at it. - (gnu_resume): When single-stepping a single thread, given an error - if there is no such thread. When single-stepping one but running - the others, just given a warning and still run all the threads. - (gnu_wait): If there seem to be no threads, look harder, and - signal an error if there really aren't any. - (gnu_attach): Reset thread numbering to 0. - - * i386gnu-nat.c (gnu_fetch_registers, gnu_store_registers): Give - thread name in warning messages. - - * gnu-nat.c (active_inf): New function. - (show_sig_thread_cmd, show_stopped_cmd): Use it. - (info_port_rights, info_send_rights_cmd, info_port_sets_cmd, - info_recv_rights_cmd, info_port_rights_cmd, info_port_rights_cmd): - New functions. - (add_task_commands): Add new port-right info commands. - -Fri Apr 26 20:42:16 1996 Miles Bader - - * gnu-nat.c (gnu_wait): Instead of _hurd_intr_rpc_mach_msg, just - use mach_msg with MACH_RCV_INTERRUPT. - (set_noninvasive_cmd): New function. - (add_task_commands): Add command entry for `set noninvasive'. - -Mon Mar 4 14:12:02 1996 Miles Bader - - * gnu-nat.c (gnu_read_inferior): Use hurd_safe_memmove, not safe_bcopy. - (safe_bcopy): Function removed. - -Mon Dec 4 14:18:26 1995 Miles Bader - - * gnu-nat.c (proc_update_sc): Assert only threads can have state. - (make_proc): Initialize state_valid & state_changed fields. - -Tue Nov 28 17:51:21 1995 Miles Bader - - * reply_mig_hack.awk: New file. - -Tue Nov 14 14:31:03 1995 Miles Bader - - * breakpoint.c (breakpoint_1): Print breakpoint thread field. - - * lynx-nat.c (child_wait): Return TARGET_WAITKIND_SPURIOUS for new - threads. - -Mon Nov 13 18:30:53 1995 Miles Bader - - * target.c (debug_to_check_threads): New function. - - * inflow.c (terminal_init_inferior_with_pgrp): New function. - (terminal_init_inferior): Call terminal_init_inferior_with_pgrp. - * inferior.h (terminal_init_inferior_with_pgrp): New declaration, - but only if PROCESS_GROUP_TYPE is defined. - -Mon Nov 6 16:42:09 1995 Miles Bader - - * target.c (debug_to_thread_alive): Pass through the return value. - -Thu Nov 2 18:05:00 1995 Miles Bader - - * target.c (signals, target_signal_from_host, target_signal_to_host): - Add mach exceptions. - * target.h (enum target_signal): Add mach exceptions. - -Mon Oct 30 16:41:04 1995 Miles Bader - - * gnu-nat.c: New file: gnu native backend. - * i386gnu-nat.c: New file: i386-specific part of gnu native backend. - * gnu-nat.h: New file. - * config/nm-gnu.h: New file. - * config/tm-i386gnu.h: New file. - * config/xm-i386gnu.h: New file. - * config/i386/i386gnu.mh: New file. - * config/i386/i386gnu.mt: New file. - -Wed Feb 28 15:50:12 1996 Fred Fish - - * Makefile.in (VERSION): Bump version to 4.15.2 to establish - baseline for gdb 4.16 rerelease testing. - -Wed Feb 28 13:32:05 1996 Jeffrey A Law (law@cygnus.com) - - * somsolib.c (som_solib_create_inferior_hook): Before returning - call clear_symtab_users. - -Tue Feb 27 00:04:46 1996 Stu Grossman (grossman@critters.cygnus.com) - - * remote-e7000.c (e7000_open): Delete all breakpoints when - connecting to e7000. Change connect message to allow use of - monitor.exp in test suite. - * (e7000_load): Print transfer rate of download. - * symfile.c (generic_load): Print transfer rate of download. - -Sun Feb 25 13:58:33 1996 Stan Shebs - - * configure.in (mips*-*-vxworks*): New config. - * configure: Regenerated. - - * config/mips/vxmips.mt, config/mips/tm-vxmips.h: New files. - * remote-vxmips.c (vx_convert_to_virtual, vx_convert_from_virtual): - Remove, never used. - -Sat Feb 24 12:30:28 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * partial-stab.h (case N_FUN): Function symbols generated - by SPARCworks cc have a meaningless zero value, do not update - pst->textlow if the function symbol value is zero. - - * stabsread.c (define_symbol): Initialize SYMBOL_TYPE field - for function prototype declaration symbols. - -Fri Feb 23 22:33:04 1996 Stu Grossman (grossman@critters.cygnus.com) - - * remote-e7000.c (e7000_load): New routine to download via the - network. - * (e7000_wait): Don't backup PC when we hit a breakpoint. - Apparantly new sh2 pods get this right... - * (e7000_ops): Add call to e7000_load. - -Thu Feb 22 00:52:42 1996 J.T. Conklin - - * config/m68k/{nbsd.mh,nbsd.mt,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h}, - m68knbsd-nat.c: New files, support for NetBSD/m68k. - - * configure.in (m68k-*-netbsd*): New config. - * configure: Regenerated. - -Wed Feb 21 19:00:21 1996 Fred Fish - - * standalone.c (open, _initialize_standalone): Fix obvious typos - reported by Martin Pool . - -Wed Feb 21 14:24:04 1996 Jeffrey A Law (law@cygnus.com) - - * solib.c (solib_create_inferior_hook): Fix thinko. - -Tue Feb 20 23:59:19 1996 Jeffrey A Law (law@cygnus.com) - - * solib.c (solib_break_names): Define for Solaris and Linux. - (enable_break): For SVR4 systems, first try to use the debugger - interfaces in the dynamic linker to track shared library events - as they happen, then fall back to BKPT_AT_SYMBOL code. Convert - BKPT_AT_SYMBOL code to use shared library event breakpoints. - (solib_create_inferior_hook): Simplify BKPT_AT_SYMBOL code, - it no longer needs to restart/wait on the inferior. - * symfile.c (find_lowest_section): No longer static. - * symfile.h (find_lowest_section): Corresponding changes. - -Tue Feb 20 18:54:08 1996 Fred Fish - - * valops.c (COERCE_FLOAT_TO_DOUBLE): Define default value. - (value_arg_coerce): Use COERCE_FLOAT_TO_DOUBLE. - * config/alpha/tm-alpha.h (COERCE_FLOAT_TO_DOUBLE): Define to 1. - * config/mips/tm-mips.h: Ditto. - * config/pa/tm-hppa.h: Ditto. - * config/rs6000/tm-rs6000.h: Ditto. - * config/sparc/tm-sparc.h: Ditto. - -Tue Feb 20 17:32:05 1996 J.T. Conklin - - * config/{i386,ns32k}/nbsd.mh (NATDEPFILES): Remove core-aout.o. - - * config/nm-nbsd.h (FETCH_INFERIOR_REGISTERS): Defined. - * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG): - #ifdef'd out definitions --- Causes serious gdb failures on - the i386. Need to investigate further before enabling. - - * i386b-nat.c (fetch_inferior_registers, store_inferior_registers, - fetch_core_registers): New functions. These functions are defined - if FETCH_INFERIOR_REGISTERS is set. Registers are fetched/stored - with ptrace PT_GETREGS/PT_SETREGS. - -Tue Feb 20 16:55:06 1996 Stu Grossman (grossman@critters.cygnus.com) - - * findvar.c (extract_floating store_floating): Replace `long - double' with `DOUBLEST'. - -Mon Feb 19 15:25:51 1996 J.T. Conklin - - * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG): - Define. - -Mon Feb 19 10:32:05 1996 Jeffrey A Law (law@cygnus.com) - - * symtab.h (looup_minimal_symbol_solib_trampoline): Declare. - - * breakpoint.h (remove_solib_event_breakpoints): Declare. - * breakpoint.c (remove_solib_event_breakpoints): New function. - * somsolib.c (solib_create_inferior_hook): Remove all solib event - breakpoints before inserting any new ones. Use a solib event - breakpoint for the breakpoint at "_start". - Remove extraneous "\n" from calls to warning. - - * breakpoint.c (breakpoint_1): Add missing "sigtramp" to bptypes - name array. - -Mon Feb 19 01:09:32 1996 Doug Evans - - * dwarfread.c (add_partial_symbol): Use ADD_PSYMBOL_ADDR_TO_LIST - for CORE_ADDR values. - (new_symbol): Use SYMBOL_VALUE_ADDRESS for CORE_ADDR values. - * symfile.h (add_psymbol_{,addr}to_list): Add prototypes. - -Sun Feb 18 14:37:13 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mipsread.c (mipscoff_symfile_read): Unconditionally add - alpha coff dynamic symbols for all symbol files. Makes skipping - over the trampoline code work when stepping from a function in a - shared library into a function in a different shared library. - -Sun Feb 18 09:27:10 1996 Stu Grossman (grossman@cygnus.com) - - * config/sparc/tm-sparc.h: Define PS_FLAG_CARRY. Define - RETURN_VALUE_ON_STACK to return long doubles on the stack. - -Sat Feb 17 16:33:11 1996 Fred Fish - - * Makefile.in (ch-exp.o): Add dependencies. - (various): Add gdb_string.h to dependencies that need it. - -Sat Feb 17 08:57:50 1996 Fred Fish - - * symmisc.c (print_symbol_bcache_statistics): Update description for - printing byte cache statistics. - -Thu Feb 16 16:02:03 1996 Stu Grossman (grossman@cygnus.com) - - * Add native support for long double data type. - * c-exp.y (%union): Change dval to typed_val_float. Use DOUBLEST - to store actual data. Change types of INT and FLOAT tokens to - typed_val_int and typed_val_float respectively. Create new token - DOUBLE_KEYWORD to specify the string `double'. Make production - for FLOAT use type determined by parse_number. Add production for - "long double" data type. - * (parse_number): Use sscanf to parse numbers as float, double or - long double depending upon the type of typed_val_float.dval. Also - allow user to specify `f' or `l' suffix to explicitly specify - float or long double constants. Change typed_val to - typed_val_int. - * (yylex): Change typed_val to typed_val_int. Also, scan for - "double" keyword. - * coffread.c (decode_base_type): Add support for T_LNGDBL basic - type. - * configure, configure.in: Add check for long double support in - the host compiler. - * defs.h: Define DOUBLEST appropriatly depending on whether - HAVE_LONG_DOUBLE (from autoconf) is defined. Also, fix prototypes - for functions that handle this type. - * expression.h (union exp_element): doubleconst is now type - DOUBLEST. - * m2-exp.y f-exp.y (%union): dval becomes type DOUBLEST. - * findvar.c (extract_floating): Make return value be DOUBLEST. - Also, add support for numbers with size of long double. - * (store_floating): Arg `val' is now type DOUBLEST. Handle all - floating types. - * parser-defs.h parse.c (write_exp_elt_dblcst): Arg expelt is now - DOUBLEST. - * valarith.c (value_binop): Change temp variables v1, v2 and v to - type DOUBLEST. Coerce type of result to long double if either op - was of that type. - * valops.c (value_arg_coerce): If argument type is bigger than - double, coerce to long double. - * (call_function_by_hand): If REG_STRUCT_HAS_ADDR is defined, and - arg type is float and > 8 bytes, then use pointer-to-object - calling conventions. - * valprint.c (print_floating): Arg doub is now type DOUBLEST. - Use appropriate format and precision to print out floating point - values. - * value.h: Fixup prototypes for value_as_double, - value_from_double, and unpack_double to use DOUBLEST. - * values.c (record_latest_value): Remove check for invalid - floats. Allow history to store them so that people may examine - them in hex if they want. - * (value_as_double unpack_double): Change return value to DOUBLEST. - * (value_from_double): Arg `num' is now DOUBLEST. - * (using_struct_return): Use RETURN_VALUE_ON_STACK macro (target - specific) to expect certain types to always be returned on the stack. - -Fri Feb 16 14:00:54 1996 Fred Fish - - * bcache.c, bcache.h: New files to implement a byte cache. - * Makefile.in (SFILES): Add bcache.c. - (symtab_h): Add bcache.h. - (HFILES_NO_SRCDIR): add bcache.h - (COMMON_OBJS): Add bcache.o - (bcache.o): New target. - * dbxread.c (start_psymtab): Make global_syms & static_syms - type "partial_symbol **". - * hpread.c (hpread_start_symtab): Ditto. - * os9kread.c (os9k_start_psymtab): Ditto. - * stabsread.h (start_psymtab): Ditto. - * {symfile.c, symfile.h} (start_psymtab_common): Ditto. - * maint.c (maintenance_print_statistics): Call - print_symbol_bcache_statistics. - * objfiles.c (allocate_objfile): Initialize psymbol bcache malloc - and free pointers. - * solib.c (allocate_rt_common_objfile): Ditto. - * symfile.c (reread_symbols): Ditto. - (free_objfile): Free psymbol bcache when objfile is freed. - (objfile_relocate): Use new indirect psymbol pointers. - * objfiles.h (struct objfile): Add psymbol cache. - * symfile.c (compare_psymbols): Now passed pointers to pointers to - psymbols. - (reread_symbols): Free psymbol bcache when freeing other objfile - resources. - (add_psymbol_to_list, add_psymbol_addr_to_list): Initialize new - psymbol using the psymbol bcache. - (init_psymbol_list): Psymbol lists now contain pointers rather than - the actual psymbols. - * symfile.h (psymbol_allocation_list): Psymbol lists now dynamically - grown arrays of pointers. - (ADD_PSYMBOL_VT_TO_LIST): Initialize new symbol using the psymbol - bcache. - * symmisc.c (print_partial_symbols): Now takes pointer to pointer - to partial symbol. - (print_symbol_bcache_statistics): New function to print per objfile - bcache statistics. - (print_partial_symbol, print_partial_symbols, - maintenance_check_symtabs, extend_psymbol_list): - Account for change to pointer to pointer to partial symbol. - * symtab.c (find_pc_psymbol, lookup_partial_symbol, decode_line_2, - make_symbol_completion_list): - Account for change to pointer to pointer to partial symbol. - * symtab.h (bcache.h): Include. - * xcoffread.c (xcoff_start_psymtab): Make global_syms & static_syms - type "partial_symbol **". - -Fri Feb 16 10:02:34 1996 Fred Fish - - * dwarfread.c (free_utypes): New function. - (read_file_scope): Call free_utypes as cleanup, rather than just - freeing the utypes pointer. - -Thu Feb 15 21:40:52 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * demangle.c (is_cplus_marker): New function, checks if a - character is one of the commonly used C++ marker characters. - * defs.h (is_cplus_marker): Add prototype. - * c-typeprint.c (c_type_print_base), ch-lang.c (chill_demangle), - cp-valprint.c (cp_print_class_method), mdebugread.c (parse_symbol), - stabsread.c (define_symbol, read_member_functions, read_struct_fields), - symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P), - values.c (vb_match): Use is_cplus_marker instead of comparison - with CPLUS_MARKER. - -Thu Feb 15 18:08:13 1996 Fred Fish - - * symfile.h (INLINE_ADD_PSYMBOL): Default this to 0 and possibly - delete entirely someday. - -Thu Feb 15 15:25:34 1996 Stan Shebs - - * mpw-make.sed: Edit out makefile rebuild rule. - (host_alias, target_alias): Comment out instead of deleting. - (@LIBS@): Edit out references. - -Tue Feb 13 22:56:46 1996 Fred Fish - - * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list): - Use n_psyms in OBJSTAT, not psyms. - -Mon Feb 12 15:59:31 1996 Doug Evans - - * configure.in (sparclet-*-aout*): New config. - * configure: Regenerated. - -Mon Feb 12 14:17:52 1996 Fred Fish - - * somsolib.c (som_solib_add): Use xmalloc rather than bare - unchecked call to malloc. - * remote-mips.c (pmon_load_fast): ditto. - * remote-mm.c (mm_open): ditto. - * hpread.c (hpread_lookup_type): ditto. - * remote-adapt.c (adapt_open): ditto. - -Mon Feb 12 13:11:32 1996 Fred Fish - - * f-lang.c (allocate_saved_bf_node, allocate_saved_function_node, - allocate_saved_f77_common_node, allocate_common_entry_node, - add_common_block): Use xmalloc rather than malloc, some of which - were unchecked. - * gnu-regex.c: At same point as other gdb specific changes - #undef malloc and then #define it to xmalloc. - * ch-exp.c (growbuf_by_size): Use xmalloc/xrealloc rather than - bare unchecked calls to malloc/realloc. - * stabsread.c (dbx_lookup_type): Use xmalloc rather than bare - unchecked call to malloc. - -Wed Feb 7 11:31:26 1996 Stu Grossman (grossman@cygnus.com) - - * symtab.c (gdb_mangle_name): Change opname var to be const to - match return val of cplus_mangle_name. - * i960-tdep.c: Change arg types of next_insn to match callers. - -Wed Feb 7 07:34:24 1996 Fred Fish - - * config/i386/linux.mh (XM_CLIBS, GDBSERVER_LIBS): Remove. These - apparently aren't needed in any reasonably recent version of - linux. - -Tue Feb 6 21:37:03 1996 Per Bothner - - * stabsread.c (read_range_type): If !self-subrange and language - is Chill, assume a true range. If a true_range is a sub_subrange, - use builtin_type_int for index_type. - -Tue Feb 6 18:38:51 1996 J.T. Conklin - - * nindy-share/nindy.c (say): Use stdarg.h macros when compiling - with an ANSI compiler. - -Mon Feb 5 18:24:28 1996 Steve Chamberlain - - From Michael_Snyder@NeXT.COM (Michael Snyder): - * valops.c (value_arg_coerce): Coerce float to double, unless the - function prototype specifies float. - -Mon Feb 5 09:51:55 1996 Tom Tromey - - * language.c (set_language_command): Use languages table when - printing available languages. - -Sat Feb 3 12:22:05 1996 Fred Fish - - Fix problems reported by Hans Verkuil (hans@wyst.hobby.nl): - * command.c (add_cmd): Add missing initialization for enums member. - Reorder members to match structure declaration to make it easier to - tell when one is missing. - * exec.c (exec_file_command): Fix problem where filename in malloc'd - memory is referenced after being freed. - -Sat Feb 3 03:26:21 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dwarfread.c (read_func_scope): Avoid GDB core dumps if - AT_name tag is missing. - - * procfs.c (procfs_stopped_by_watchpoint): Fix logic when - FLTWATCH and FLTKWATCH are defined. - - * remote.c (remote_read_bytes): Advance memaddr for transfers, - return number of bytes transferred for partial reads. - - * top.c (init_signals): Reset SIGTRAP to SIG_DFL. - -Fri Feb 2 13:40:50 1996 Steve Chamberlain - - * win32-nat.c (mappings): Add ppc registers. - (child_resume): Turn off step for ppc. - -Thu Feb 1 10:29:31 1996 Steve Chamberlain - - * config/powerpc/(cygwin32.mh, cygwin32.mt, tm-cygwin32.h, - xm-cygwin32.h): New. - * config/i386/(*win32*): Becomes *cygwin32*. - * configure.in (i[3456]86-*-win32*): Becomes i[3456]86-*-cygwin32. - (powerpcle-*-cygwin32): New. - * configure: Regenerate. - * win32-nat.c (child_create_inferior): Call CreateProcess - with the right program arg. - -Thu Feb 1 11:01:10 1996 Jeffrey A Law (law@cygnus.com) - - * config/pa/tm-hppa.h (SOFT_FLOAT): Provide a default definition. - -Wed Jan 31 19:01:28 1996 Fred Fish - - * serial.c: Change fputc/fputs/fprintf to _unfiltered forms. - -Wed Jan 31 18:36:27 1996 Stan Shebs - - * config/sparc/xm-sun4os4.h (HAVE_TERMIOS): Remove. - - * config/sparc/xm-sparc.h (HAVE_WAIT_STRUCT): Remove, never used. - - * config/i386/nm-i386mach.h (CHILD_PREPARE_TO_STORE): Move to - here from config/i386/xm-i386mach.h, fix name. - * config/i386/nm-sun386.h: Ditto, from config/i386/xm-sun386.h. - * config/i386/nm-ptx4.h (CHILD_PREPARE_TO_STORE): Move to - here from config/i386/xm-ptx4.h. - * config/i386/nm-ptx4.h: Ditto, from config/i386/xm-ptx.h. - * config/i386/nm-symmetry.h: Ditto, from config/i386/xm-symmetry.h. - * config/m68k/nm-sun3.h: Ditto, from config/m68k/xm-sun3.h. - * config/sparc/nm-nbsd.h: Ditto, from config/sparc/xm-nbsd.h. - * config/sparc/nm-sun4os4: Ditto, from config/sparc/xm-sparc.h. - - * config/sparc/nm-sun4sol2.h: New file, renamed from nm-sysv4.h. - (PRSVADDR_BROKEN): Move here from xm-sun4sol2.h. - * config/sparc/sun4sol2.mh (NAT_FILE): Update. - -Wed Jan 31 17:20:26 1996 Jeffrey A Law (law@cygnus.com) - - * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Handle software - floating point correctly. - (STORE_RETURN_VALUE): Likewise. - * config/pa/tm-pro.h (SOFT_FLOAT): define. - -Wed Jan 31 13:34:52 1996 Fred Fish - - * config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT): - Define to what should be reasonable values. However, apparently - a bug in linux mmap prevents mapped symbol tables from working. - -Tue Jan 30 18:26:19 1996 Fred Fish - - * defs.h (errno.h>: Move #include closer to head of file to solve - obscure problem with systems that declare perror with const arg, in - both errno.h and stdio.h, and const is defined away by intervening - local include. - -Tue Jan 30 15:41:10 1996 Fred Fish - - From Jon Reeves : - * i386-stub.c (getpacket): Change fprintf stream from "gdb" to stderr. - (mem_fault_routine): Fix misplaced volatile type qualifier in decl. - -Mon Jan 29 19:05:58 1996 Fred Fish - - * Makefile.in (diststuff): Make all-doc; diststuff target does not - exist in doc/Makefile.in. - -Mon Jan 29 18:44:57 1996 Stan Shebs - - * config/m88k/xm-cxux.h (BP_HIT_COUNT): Remove, never used. - -Mon Jan 29 00:10:35 1996 Wilfried Moser - - * ch-valprint.c (calculate_array_length): New function to - determine the length of an array type. - (chill_val_print (case TYPE_CODE_ARRAY)): If the length of an - array type is zero, call calculate_array_length. - - * gdbtypes.c (get_discrete_bounds (case TYPE_CODE_ENUM)): The - values may not be sorted. Scan all entries and set the real lower - and upper bound. - -Sun Jan 28 15:50:42 1996 Fred Fish - - * config/xm-linux.h: Move include of solib.h and #define of - SVR4_SHARED_LIBS from here ... - * config/nm-linux.h: ...to here. - -Sat Jan 27 10:34:05 1996 Fred Fish - - * configure.in (AC_CHECK_HEADERS): Check for sys/procfs.h. - Also check for gregset_t and fpregset_t types. - * configure: Regenerate. - * core-regset.c (sys/procfs.h): Only include if HAVE_SYS_PROCFS_H - is defined. - (fetch_core_registers): Turn into stub unless both HAVE_GREGSET_T - and HAVE_FPREGSET_T are defined. These changes allow systems - like linux that are migrating to /proc support to use a single - configuration for both new and old versions. - - * config/i386/linux.mt: Note that this is now for both a.out and - ELF systems. - * config/i386/linux.mh (NATDEPFILES): Add solib.o, core-regset.o, - i386v4-nat.o - * config/i386/tm-linux.h (tm-sysv4.h): Include. - * config/i386/xm-linux.h (solib.h): Include - (SVR4_SHARED_LIBS): Define. - * i386v4-nat.c: Only compile if HAVE_SYS_PROCFS_H is defined. - (supply_gregset, fill_gregset): Compile if HAVE_GREGSET_T defined. - (supply_fpregset, fill_fpregset): Compile if HAVE_FPREGSET_T - defined. - -Fri Jan 26 13:48:14 1996 Stan Shebs - - * config/sparc/xm-sparc.h (NEW_SUN_CORE): Remove, never used. - * config/i386/xm-sun386.h: Ditto. - * config/m68k/xm-sun2.h, config/m68k/xm-sun3.h: Ditto. - -Thu Jan 25 16:05:53 1996 Tom Tromey - - * Makefile.in (INSTALLED_LIBS, CLIBS): Include @LIBS@. - -Thu Jan 25 09:22:15 1996 Steve Chamberlain - - From Greg McGary : - * dcache.c (dcache_peek, dcache_poke): Advance addr for - multi-byte I/O. - -Thu Jan 25 13:08:51 1996 Doug Evans (dje@cygnus.com) - - * infrun.c (normal_stop): Fix test for shared library event. - -Thu Jan 25 03:26:38 1996 Doug Evans - - * configure.in (sparc64-*-*): Add default host configuration. - (sparc64-*-solaris2*): Add target configuration. - (sparc64-*-solaris2* host): Link statically if GCC used. - * configure: Regenerated. - * sparc/sp64sol2.mt: New file. - -Wed Jan 24 22:31:37 1996 Doug Evans - - * Makefile.in (RUNTEST): srcdir renamed to rootsrc. - -Wed Jan 24 15:42:24 1996 Tom Tromey - - * Makefile.in (lint): Close backquotes. - -Wed Jan 24 13:19:10 1996 Fred Fish - - * NEWS: Make note of new record and replay feature for - remote debug sessions. - * serial.c (gdbcmd.h): Include. - (serial_logfile, serial_logfp, serial_reading, serial_writing): - Define here, for remote debug session logging. - (serial_log_command, serial_logchar, serial_write, serial_readchar): - New functions for remote debug session logging. - (serial_open): Open remote debug session log file when needed. - (serial_close): Close remote debug session log file when needed. - (_initialize_serial): Add set/show commands for name of remote - debug session log file. - * serial.h (serial_readchar): Declare - (SERIAL_READCHAR): Call serial_readchar(). - (SERIAL_WRITE): Call serial_write(). - (serial_close): Declare as extern. - (serial_logfile, serial_logfp): Declare. - * top.c (execute_command): Declare serial_logfp. Log user command - in remote debug session log if log file is open. - * remote-array.c (array_wait): #ifdef out echo to gdb_stdout. - (array_read_inferior_memory): Rewrite to fix memory overwrite bug. - * remote-array.c (SREC_SIZE): Remove, duplicates define in - monitor.h. - * remote-array.c (hexchars, hex2mem): Remove, unused. - * gdbserver/low-linux.c (store_inferior_registers): Remove - unnecessary extern declaration of registers[]. - * gdbserver/Makefile.in (all): Add gdbreplay. - * gdbserver/gdbreplay.c: New file. - * gdbserver/README: Give example of recording a remote - debug session with gdb and then replaying it with gdbreplay. - -Tue Jan 23 18:02:35 1996 Per Bothner - - * stabsread.c (rs6000_builtin_type): Make bool type unsigned. - (read_one_struct_field): Support boolean bitfields. - * c-valprint.c (c_val_print): Print booleans properly. - -Tue Jan 23 18:54:09 1996 Stan Shebs - - * remote-vxsparc.c (vx_convert_to_virtual, vx_convert_from_virtual): - Remove, never used. - * config/sparc/vxsparc.mt (TDEPFILES): Add remote-vxsparc.o. - -Tue Jan 23 14:36:05 1996 Per Bothner - - * ch-exp.c (parse_tuple): Error if invalid mode. - - * value.h (COERCE_ARRAY): Don't coerce enums. - (COERCE_ENUM): Don't COERCE_REF. - (COERCE_NUMBER): New macro (same as COERCE_ARRAY then COERCE_ENUM). - * valops.c (value_assign): Only do COERCE_ARRAY if internalvar (let - value_cast handle it otherwise); do *not* COERCE_ENUM either way. - * valarith.c: Use COERCE_NUMBER instead od COEREC_ARRAY. - Add COERCE_REF before COERCE_ENUM. - * values.c (value_as_long): Simplify. - - * valops.c (value_array): Create internalvar if !c_style_arrays. - - * language.c (lang_bool_type): Add Fortran support. - * eval.c (OP_BOOL): Use LA_BOOL_TYPE. - -Tue Jan 23 13:08:26 1996 Jeffrey A Law (law@cygnus.com) - - * symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup. - All references changed. - * breakpoint.c (bpstat_what): Add shlib_event to the class types. - Update state table. Reformat so that it's still readable. - When we hit the shlib_event breakpoint, set the calss of shlib_event. - (breakpoint_1): Add "shlib events" as a breakpoint type. - Print the shlib_event breakpoint like other breakpoints. - (create_solib_event_breakpoint): New function. - (breakpoint_re_set_one): Handle solib_event breakpoints. - * breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type. - (enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS - action. - (create_solib_event_breakpoint): Declare. - * infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat. - (normal_stop): Inform the user when the inferior stoped due - to a shared library event. - (_initialize_infrun): Add new set/show variable "stop-on-solib-events" - to control whether or not gdb continues the inferior or stops it when - a shared library event occurs. - * minsyms.c (lookup_minimal_symbol_solib_trampoline): New function. - * somsolib.c (TODO list): Update. - (som_solib_create_inferior_hook): Arrange for gdb to be notified - when significant shared library events occur. - * hppa-tdep.c (find_unwind_entry): No longer static. - -Tue Jan 23 09:00:48 1996 Doug Evans - - * printcmd.c (print_insn): Pass fprintf_unfiltered to - INIT_DISASSEMBLE_INFO. - -Mon Jan 22 16:59:40 1996 Stan Shebs - - * remote.c (remotebreak): New GDB variable. - (remote_break): New global. - (remote_interrupt): Send a break instead of ^C if remote_break. - * NEWS: Describe the new variable. - -Mon Jan 22 16:24:11 1996 Doug Evans - - * sparc-tdep.c (_initialize_sparc_tdep): Always use print_insn_sparc. - -Fri Jan 19 07:19:38 1996 Fred Fish - - * hp300ux-nat.c (getpagesize): Remove unused function - fetch_core_registers. - (hp300ux_core_fns): Remove, is unused. - (_initialize_core_hp300ux): Remove, is unused. - (gdbcore.h): Remove #include, no longer needed. - -Fri Jan 19 00:59:53 1996 Jeffrey A Law (law@cygnus.com) - - * rs6000-nat.c (exec_one_dummy_insn): Rework to avoid - ptrace bug in aix4.1.3 on the rs6000. - -Wed Jan 17 13:22:27 1996 Stan Shebs - - * remote-hms.c (hms_ops): Add value for to_thread_alive. - * remote-nindy.c (nindy_ops): Ditto. - * remote-udi.c (udi_ops): Ditto. - -Tue Jan 16 18:00:35 1996 James G. Smith - - * remote-mips.c (pmon_opn, pmon_wait, pmon_makeb64, pmon_zeroset, - pmon_checkset, pmon_make_fastrec, pmon_check_ack, - pmon_load_fast): New functions. Support for the PMON monitor world. - (common_open): New function to merge support for different monitors. - (mips_open): Use common_open(). - (mips_send_command): New function. - (mips_send_packet): Scan out-of-sequence packets. - (mips_enter_debug, mips_exit_debug): New functions. - (pmon_ops): New target definition structure. - -Tue Jan 16 11:22:58 1996 Stu Grossman (grossman@cygnus.com) - - * Makefile.in (CLIBS): Add LIBS to allow libraries to be - specified on the make command line (via make LIBS=xxx). - - -Fri Jan 12 21:41:58 1996 Jeffrey A Law (law@cygnus.com) - - * symtab.c (find_pc_symtab): Don't lose if OBJF_REORDERED - is set but there are no psymtabs. - -Fri Jan 12 15:56:12 1996 Steve Chamberlain - - * dsrec.c (load_srec): Remove unused variable. - * monitor.c (monitor_expect): Don't expect a ^C to echo. - * serial.c (serial_open): Add parallel interface. - * sh3-rom.c (parallel, parallel_in_use): New. - (sh3_load): If parallel_in_use, download though the - parallel port. - (sh3_open): Open parallel port if specified. - (sh3_close): New function. - (_inititalize_sh3): Add sh3_close hook and documentation. - * monitor.c (monitor_close): Export. - * monitor.h (monitor_close): Add prototype. - -Fri Jan 12 13:11:42 1996 Stan Shebs - - From Wilfried Moser : - * remote.c (remotetimeout): New GDB variable, use to set the - remote timeout for reading. - -Fri Jan 12 07:14:27 1996 Fred Fish - - * lynx-nat.c, irix4-nat.c, sparc-nat.c: Include gdbcore.h - to get "struct core_fns" defined. - * Makefile.in (lynx-nat.o, irix4-nat.o, sparc-nat.o): - Are dependent upon gdbcore_h. - -Thu Jan 11 23:13:24 1996 Per Bothner - - * symfile.c (decrement_reading_symtab): New function. - * symfile.c, symtab.h (currently_reading_symtab): New variable. - * symfile.c (psymtab_to_symtab): Adjust currently_reading_symtab. - * gdbtypes.c (check_typedef): Don't call lookup_symbol if - currently_reading_symtab (since that could infinitely recurse). - -Thu Jan 11 17:21:25 1996 Per Bothner - - * stabsread.c (read_struct_type): Trivial simplification. - - * stabsread.c (define-symbol): Use invisible references - for TYPE_CODE_SET and TYPE_CODE_BITSTRING too. - * valops.c (call_function_by_hand): Likewise. - * eval.c (evaluate_subexp_standard): When known, use the formal - parameter type as the expected type when evaluating arg expressions. - * ch-lang.c (evaluate_subexp_chill): Likewise (for MULTI_SUBSCRIPT). - -Thu Jan 11 10:08:14 1996 Tom Tromey - - * main.c (main): Disable window interface if --help or --version - specified. - -Wed Jan 10 16:08:49 1996 Brendan Kehoe - - * configure.in, configure: Recognize rs6000-*-aix4*. - * config/powerpc/xm-aix.h: Reduce to include "xm-aix4.h". - * config/rs6000/aix4.mh (XM_FILE): Point to xm-aix4.h. - * config/rs6000/xm-aix4.h: New file. - * config/xm-aix4.h: New file. - -Wed Jan 10 11:25:37 1996 Fred Fish - - From Wilfried Moser : - * gdbserver/low-linux.c: New file. - * remote.c (remote_read_bytes): Fix aborts on larger packets. - - * config/i386/linux.mh (GDBSERVER_DEPFILES, GDBSERVER_LIBS): - Define. - * stabsread.c (define_symbol): If register value is too large, - tell what it is and what max is. - -Tue Jan 9 09:33:53 1996 Jeffrey A Law (law@cygnus.com) - - * hpread.c (hpread_build_psymtabs): Finish Jan 4th - enum namespace -> enum_namespace change. - -Tue Jan 9 04:44:47 1996 Wilfried Moser - - * ch-exp.c (parse_primval): In case ARRAY, add missing - FORWARD_TOKEN (). - -Mon Jan 8 13:29:34 1996 Stan Shebs - - * remote-mips.c (mips_receive_header): Recognize \012 instead - of \n, but write \n when program sends a \012. - * ser-mac.c (mac_input_buffer): Increase size of buffer. - -Mon Jan 8 12:00:40 1996 Jeffrey A Law (law@cygnus.com) - - * infptrace.c (initialize_infptrace): Move function out of - #ifdef conditional; put code within the function inside an - #ifdef conditional. - - * buildsym.c (end_symtab): Remove sort_pending and sort_linevec - arguments. Sorting is now dependent on OBJF_REORDERED. All - callers/references changed. - * dbxread.c (read_ofile_symtab): Correctly determine value for - last_source_start_addr for reordered executables. - (process_one_symbol): Handle N_FUN with no name as an end of - function marker. - * partial-stab.h (case N_FN, N_TEXT): Don't assume CUR_SYMBOL_VALUE - is the high text address for a psymtab. - (case N_SO): Likewise. - (case N_FUN): Handle N_FUN with no name as an end of function - marker. - * minsyms.c (lookup_minimal_symbol_by_pc): Examine all symbols - at the same address rather than a random subset of them. - * coffread.c (coff_symfile_init): Set OBJF_REORDERED. - * elfread.c (elf_symfile_init): Similarly. - * somread.c (som_symfile_init): Similarly. - * xcoffread.c (xcoff_symfile_init): Similarly. - -Fri Jan 5 17:46:01 1996 Stu Grossman (grossman@cygnus.com) - - * stack.c (print_stack_frame print_frame_info) symmisc.c - (dump_symtab): Change RETURN_MASK_ERROR to RETURN_MASK_ALL so - that catch_errors doesn't get blindsided by QUIT and lose the - cleanup chain. This fixes a problem where ^C while in a - user-defined command sometimes leaves instream NULL and causes a - segfault in command_loop. - -Fri Jan 5 13:59:16 1996 Brendan Kehoe - - * configure.in, configure: Add `-ldl -lw' for Solaris linking. - -Fri Jan 5 12:02:00 1996 Steve Chamberlain - - * config/sh/sh.mt, config/powerpc/*.mt, config/pa/hppapro.mt, - config/m68k/monitor.mt, config/h8500/h8500.mt, config/h8300/h8300.mt: - srec.o renamed to dsrec.o. - -Thu Jan 4 16:04:54 1996 Stu Grossman (grossman@cygnus.com) - - * breakpoint.c (remove_breakpoint): Change error to warning so - that hardware watchpoint removal problems won't leave breakpoint - traps in the target. - * remote-e7000.c (e7000_insert_breakpoint, - e7000_remove_breakpoint): Use e7000 based breakpoints, not memory - breakpoints. - * (e7000_wait): Adjust PC back by two when we see a breakpoint to - compensate for e7000 maladjustment. - * sparcl-tdep.c (sparclite_check_watch_resources): Fix logic bug - which prevented hardware watchpoints from working. - -Thu Jan 4 10:44:17 1996 Fred Fish - - * infptrace.c (udot_info): New function. - (PT_*): Define each individually if that one is not defined. - * rs6000-nat.c (kernel_u_size): New function - Include for "struct user" - * alpha-nat.c (kernel_u_size): New function. - Include for "struct user" - * sparc-nat.c (kernel_u_size): New function. - Include for "struct user" - * i386b-nat.c (kernel_u_size): New function. - * i386v-nat.c (kernel_u_size): New function. - * config/i386/nm-fbsd.h (KERNEL_U_SIZE): Define. - (kernel_u_size): Declare. - * config/i386/nm-linux.h (KERNEL_U_SIZE): Define. - (kernel_u_size): Declare. - * config/sparc/nm-sun4os4.h (KERNEL_U_SIZE): Define. - (kernel_u_size): Declare. - * config/alpha/nm-osf2.h (KERNEL_U_SIZE): Define. - (kernel_u_size): Declare. - * config/rs6000/nm-rs6000.h (KERNEL_U_SIZE): Define. - (kernel_u_size): Declare. - -Thu Jan 4 11:00:01 1996 steve chamberlain - - * mdebugread.c (mylookup_symbol): enum namespace becomes - enum_namespace type. - * symfile.c (add_psymbol_to_list) - (add_psymbol_addr_to_list): Ditto. - * symtab.c (lookup_partial_symbol): Ditto. - (lookup_symbol): Ditto. - (lookup_block_symbol): Ditto. - * win32-nat.c (handle_load_dll): Use incoming dll base. - (child_wait): Catch DLL load errors. - (create_child_inferior): Translated between paths correctly. - -Wed Jan 3 23:13:53 1996 Fred Fish - - * i386v4-nat.c (supply_gregset, fill_gregset): Subtract NUM_FREGS - from NUM_REGS to get number of general registers that we care about. - * config/i386/tm-i386.h (REGISTER_BYTES): Define in terms - of number of general regs and number of floating point regs. - -Wed Jan 3 19:49:54 1996 steve chamberlain - - * config/i386/tm-win32.h (IN_SOLIB_CALL_TRAMPOLINE): New. - (SKIP_TRAMPOLINE_CODE): New. - * config/i386/xm-win32.h (CANT_FORK): Deleted. - (SLASH*) Changed to use unix style slash. - * symtab.h (namespace enum): becomes typedef to avoid namespace - collision in C++. - * infcmd.c (path_command): Use empty string if PATH name not set. - * i386-tdep.c (skip_trampoline_code): New function. - * srec.c: Renamed dsrec.c to avoid filename collision. - * Makefile.in: Cope with renaming. - -Wed Jan 3 13:09:04 1996 Fred Fish - - * symmisc.c (print_objfile_statistics): Print memory use statistics - for objfile psymbol, symbol, and type obstacks. - -Tue Jan 2 13:41:14 1996 Stan Shebs - - * config/mips/nm-irix5.h: Restore. - (TARGET_HAS_HARDWARE_WATCHPOINTS, etc): Define as for Irix 4; - from Lee Iverson . - * config/mips/irix5.mh (NAT_FILE): Use nm-irix5.h. - * config/mips/irix[345].mh (MUNCH_DEFINE): Remove. - -For older changes see ChangeLog-95 - -Local Variables: -mode: change-log -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/contrib/gdb/gdb/ChangeLog-97 b/contrib/gdb/gdb/ChangeLog-97 deleted file mode 100644 index 4f9a949c048..00000000000 --- a/contrib/gdb/gdb/ChangeLog-97 +++ /dev/null @@ -1,2855 +0,0 @@ -Wed Dec 31 11:43:53 1997 Mark Alexander - - * dsrec.c (load_srec): Check remotedebug flag when printing - debug info. - -Wed Dec 31 10:33:15 1997 David Taylor - - * breakpoint.c (breakpoint_re_set): add _siglongjmp to list of - longjmp breakpoints. - -Mon Dec 29 21:25:34 1997 Mark Alexander - - * dve3900-rom.c: New file to support Densan DVE-R3900/20 board. - * monitor.c (monitor_debug): Move to utils.c, rename to puts_debug. - (monitor_write_memory, monitor_read_memory, monitor_insert_breakpoint, - monitor_remove_breakpoint): Remove useless address bits if current - monitor has MO_ADDR_BITS_REMOVE flag. - * monitor.h (MO_ADDR_BITS_REMOVE): Define. - * utils.c (puts_debug): Formerly monitor_debug from monitor.c; - move here and make public. Add better support for carriage returns. - * defs.h (puts_debug): Declare. - * dsrec.c (load_srec): Use puts_debug to print remotedebug information. - Output header record correctly. - (make_srec): Output a header record instead of a termination record - if sect is non-NULL (value is ignored), but abfd is NULL. - * config/mips/tm-tx39.h (DEFAULT_MIPS_TYPE): Remove definition. - (REGISTER_NAMES): Define to add R3900-specific registers. - * config/mips/tm-tx39l.h: Ditto. - * config/mips/tx39.mt (TDEPFILES): Add dve3900-rom.o and support files. - * config/mips/tx39l.mt: Ditto. - -Wed Dec 24 12:48:48 1997 Stan Shebs - - * dsrec.c: Cosmetic improvements. - (make-srec): Change indexing of format and code tables to - remove confusing empty entries. - -Mon Dec 22 21:51:53 1997 Mark Alexander - - * remote-mips.c (_initialize_remote_mips): Fix DDB doc string. - -Sun Dec 21 17:00:06 1997 David Taylor - - * d30v-tdep.c (d30v_frame_find_saved_regs): split most of - function off into d30v_frame_find_saved_regs_offsets; - (d30v_frame_find_saved_regs_offsets): new function. Got - backtrace working when calling from framefull (unoptimized) - routines (.e.g, main) into frameless (optimized) routines - (e.g., printf). - -Fri Dec 19 09:49:49 1997 David Taylor - - * d30v-tdep.c (d30v_frame_chain): test end_of_stack - (d30v_frame_find_saved_regs): set it. - * config/d30v/tm-d30v.h: improved FRAME_CHAIN_VALID - -Thu Dec 18 12:34:28 1997 Andrew Cagney - - From Gavin Koch : mips-tdep.c - * (mips_push_arguments): For big-endian shorts and char's store at - * the correct location. - -Thu Dec 18 00:26:46 1997 Andrew Cagney - - * mdebugread.c (parse_partial_symbols): Delete check that symbols - for file not already loaded. Did not work when an include file - was involved. - -Wed Dec 17 10:43:04 1997 Andrew Cagney - - * elfread.c (elf_symfile_read): Since the partial symbol table is - searched last in first, insert mdebug or XCOFF info into the - partial symbol table before any DWARF2 info. - -Thu Dec 18 00:00:48 1997 Andrew Cagney - - * symfile.c (init_psymbol_list): Handle init with zero elements. - - * elfread.c (elf_symfile_read): If `mainline', clear psymbol table - using init_psymbol_list 0. For build_psymtabs functions, pass - mainline==0 so that psymbol_list isn't re-initialized. - - * symfile.c (discard_psymtab): New function, correctly unlink an - empty psymtab from an object file. - * dbxread.c (end_psymtab): Call discard_psymtab. - * xcoffread.c (xcoff_end_psymtab): Ditto. - * hpread.c (hpread_end_psymtab): Ditto. - * os9kread.c (os9k_end_psymtab): Ditto. - -Wed Dec 17 10:47:05 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c (set_raw_tracepoint): initialize addr_string - to NULL; (trace_actions_command): call readline_begin_hook only - if from_tty is true. - -Tue Dec 16 20:05:48 1997 Mark Alexander - - * configure.tgt: Change little-endian tx39 target name to tx39l. - -Tue Dec 16 11:24:30 1997 Jeffrey A Law (law@cygnus.com) - - * remote-sim.c (gdbsim_open): Use "--architecture" instead of - ambigious short form. - -Tue Dec 16 10:29:16 1997 David Taylor - - * d30v-tdep.c (d30v_frame_chain): don't or in DMEM_START to - FP_REGNUM value before return; (prologue_find_regs): two sets - of offsets -- frame pointer and stack pointer, not just one that - tries to do double duty; (d30v_frame_find_saved_regs): stop once - we hit pc (in case we're stopped in the middle of the prologue) - and improve handling of frameless prologues; (d30v_push_arguments): - *ALL* arguments go on the stack until we run out of args registers, - force sp to be 8 byte aligned. - - * config/tm-d30v.h (EXTRACT_STRUCT_VALUE_ADDRESS): fix, it's r2, - not r0; (FRAME_CHAIN_VALID): handle use of external memory; - (STACK_ALIGN): define. - -Mon Dec 15 15:13:57 1997 Andrew Cagney - - * remote-sim.c (gdbsim_wait): When HAVE_SIGACTION and SA_RESTART - intall cntrl-c handler with SA_RESTART clear. On BSD systems this - stops read syscalls's being restarted. - - * configure.in (configdirs): Check for sigaction. - * configure: Re-generate. - -Mon Dec 15 11:38:52 1997 Andrew Cagney - - * dwarf2read.c: From change proposed by Gavin Koch. - (address_significant_size): New static variable. - (dwarf2_build_psymtabs_hard): Check consistency between - `address_size' and `address_significant_size'. - (read_address): MASK out all but the significant bits, as - determined by `address_significant_size', of any addresses. - (elf-bfd.h): Include. - (dwarf2_build_psymtabs_hard): Set `address_significant_size' - according to the arch_size of the elf object file. - -Thu Dec 11 13:40:46 1997 Andrew Cagney - - * dwarf2read.c (dwarf_decode_lines): Change type of address to - CORE_ADDR. - -Thu Dec 11 14:28:01 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c (trace_find_command): don't error if going - backwards thru the trace buffer in a loop. - * (struct tracepoint): delete unused field. - -Wed Dec 10 17:57:00 1997 David Taylor - - * d30v-tdep.c : don't bury lots of magic numbers in the code - instead use defines for the opcodes and opcode masks; update - to use actual d30v patterns; fix register sizes to be 4 bytes - not 2 bytes; improve prologue testing now that we have a C - compiler; fix stack frame handling enough to get backtraces - working; initial changes to push and pop frames (so that gdb - can call functions in the inferior). - - * config/d30v/tm-d30v.h: update DMEM_START, IMEM_START, and - STACK_START; change FR_REGNUM to 61 (was 11). Reformat comment - about DUMMY FRAMES so that it is readable. Fix SAVED_PC_AFTER_FRAME - macro. - -Wed Dec 10 17:41:07 1997 Jim Blandy - - * ch-valprint.c (chill_val_print): To avoid segfaults, don't print - a string whose dynamic length is longer than its static length. - -Wed Dec 10 15:54:00 1997 Andrew Cagney - - * dwarf2read.c (dwarf2_build_psymtabs_hard): Check - cu_header.length is within dwarf_info_buffer not - dwarf_abbrev_buffer. - -Mon Dec 8 14:28:49 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c (memrange_sortmerge): allow for memranges - that overlap. (collect_pseudocommand etc.) cleanup decls. - -Fri Dec 5 09:22:35 1997 Nick Clifton - - * config/v850/tm-v850.h (BREAKPOINT): Reverted back to old value... - -Thu Dec 4 09:30:22 1997 Nick Clifton - - * config/v850/tm-v850.h (BREAKPOINT): Changed to match new value. - -Wed Dec 3 12:44:15 1997 Keith Seitz - - * tracepoint.c: Add declaration for x_command. - - * printcmd.c (x_command): Remove static declaration. - -Wed Dec 3 12:00:42 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c (finish_tfind_command): call do_display so that - auto-displays are updated by tfind. Also, keep track of frame - and current-function so that tfind behaves like stepping (only - show the stack frame if we step into a new function or return). - -Wed Dec 3 14:14:58 1997 David Taylor - - * sol-thread.c: additional support for debugging threaded core - files on solaris; previously only kernel threads were found -- - user threads generated errors. - * corelow.c: don't register core_ops as a target if - coreops_suppress_target is true (set by sol-thread.c). - -Tue Dec 2 14:53:09 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c: make "tdump" command handle literal memranges. - -Tue Dec 2 11:34:48 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c: use "lookup_cmd" to parse actions commands - (thus allowing unambiguous prefixes and aliases). - -Tue Dec 2 10:15:57 1997 Nick Clifton - - * configure.tgt: Add support for Thumb target. - -Tue Dec 2 10:14:15 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c: move prototype of validate_actionline(), and - make it consistent with the function declaration. - -Thu Nov 27 09:07:18 1997 Michael Meissner - - * Makefile.in (tracepoint_h): New macro for tracepoint.h - includes. - (tracepoint.o): Add rule to build. - -Wed Nov 26 22:59:04 1997 Jeffrey A Law (law@cygnus.com) - - * remote-sim.c (gdbsim_cntrl_c): Lose ANSI prototype. - - * tracepoint.c (set_raw_tracepoint): fix typo - -Wed Nov 26 11:33:09 1997 Keith Seitz - - * tracepoint.c (set_raw_tracepoint): Make sure there's a trailing - slash on the directory name. - - * top.c (get_prompt): New function. - * top.h: Declare it. - -Wed Nov 26 09:59:47 1997 Andrew Cagney - - * dwarf2read.c (struct comp_unit_head): Change length and - abbrev_offset fields to unsigned int. - (dwarf2_build_psymtabs_hard): Verify length and offset read from - .debug_info section. - -Mon Nov 24 19:36:34 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c, tracepoint.h: new module, implements tracing, - which is a new functionality somewhat like breakpoints except - that a tracepoint stops the inferior only long enough to collect - and cache selected buffers and memory locations, then allows - the inferior to continue; the cached trace data can then be - examined later. - -Mon Nov 24 14:17:02 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * infcmd.c: export registers_info, for use by other modules. - * printcmd.c: export output_command, for use by other modules. - * stack.c: export locals_info and args_info, for use by other modules. - * remote.c: export getpkt, putpkt, and fromhex for external use. - Make fromhex case-insensative. New function "remote_console_output" - abstracts the acceptance of "O" packets from target. - Make all "remotedebug" output go to stdout, not stderr. - -Mon Nov 24 08:59:28 1997 Andrew Cagney - - * valprint.c (print_longest): When CC has long long but printf - doesn't, print decimal value as three parts. - - * config/i386/tm-fbsd.h: New file. - * config/i386/fbsd.mt (TM_FILE): Change to tm-fbsd.h. - - * config/i386/nm-fbsd.h (FLOAT_INFO): Move definition from here. - * config/i386/tm-fbsd.h (FLOAT_INFO): To here. - - * configure.in (PRINTF_HAS_LONG_LONG): Check full functionality of - %ll format specifier. - (SCANF_HAS_LONG_DOUBLE): Check the scanf family for support of - long double using %Lg. - * acconfig.h: Provide default undef for SCANF_HAS_LONG_DOUBLE. - * configure: Re-generate. - - * c-exp.y (parse_number): Use sscanf %Lg when host has - SCANF_HAS_LONG_DOUBLE not PRINTF_HAS_LONG_DOUBLE - -Sun Nov 23 17:12:58 1997 Andrew Cagney - - * printcmd.c (print_insn): Set the machine type if known. - - * i386-tdep.c (_initialize_i386_tdep): Delete "set - assembly-language" command. Replaced by generic "set - architecture". Set initial machine using bfd_lookup_arch. - -Fri Nov 21 19:43:23 1997 Jim Blandy - - * valops.c (call_function_by_hand): If the function has a - prototype, convert its arguments as if by assignment. Otherwise, - do the usual promotions. - * stabsread.c (define_symbol): Set the TYPE_FLAG_PROTOTYPED flag - on functions' types when we can; all C++ functions should get it, - and if the Sun-style prototype notation is in the stabs, we can - notice that. - -Fri Nov 21 12:20:16 1997 Ian Lance Taylor - - * aclocal.m4 (AM_CYGWIN32, AM_EXEEXT): Remove. They are already - defined by the inclusion of ../bfd/aclocal.m4. - * configure: Rebuild. - -Fri Nov 21 10:52:39 1997 Michael Meissner - - * Makefile.in (SHELL): Really do the change. - -Fri Nov 21 02:19:57 1997 Geoffrey Noer - - * Makefile.in: also revert SHELL change until configury - changes work - -Thu Nov 20 16:35:13 1997 Doug Evans - - * sparc-tdep.c (sparc_pc_adjust): Don't assume sizeof (long) == 4. - -Thu Nov 20 04:11:27 1997 Geoffrey Noer - - * aclocal.m4: add EXEEXT setting rule - * configure.in: call it - * configure: regenerate - * Makefile.in: pepper with EXEEXTs in appropriate places, - set SHELL = @SHELL@ for those lame hosts that don't have a /bin/sh - For some reason, EXEEXT isn't getting substututed in correctly - so for now, set EXEEXT to empty string - -Mon Nov 17 15:35:06 1997 Doug Evans - - * Makefile.in (remote-sim.o): Depend on $(INCLUDE_DIR)/callback.h. - -Fri Nov 14 13:04:34 1997 Jeffrey A Law (law@cygnus.com) - - * jv-exp.y (copy_exp, insert_exp): Avoid ANSI prototypes. - -Thu Nov 13 09:47:35 1997 Michael Meissner - - * d30v-tdep.c (d30v_print_flags): Function to print the d30v flags - in a human readable format. - (print_flags_command): Command wrapper to call d30v_print_flags. - (d30v_do_registers_info): When printing out all of the registers, - print out the flag values in a human readable fashion. - (_initialize_d30v_tdep): Add info flags command to print the - flags. - - * config/d30v/tm-d30v.h (PSW_*): Add macros for each of the PSW - bits that are defined. - -Wed Nov 12 14:58:39 1997 Jeff Holcomb - - * symfile.c (generic_load): Handle cancel from the - ui_load_progress_hook routine. - * dsrec.c (load_srec): Handle cancel from the - ui_load_progress_hook routine. - -Mon Nov 10 15:13:13 1997 Ian Lance Taylor - - * valprint.c (print_longest): The b, h, w, and g format specifiers - print unsigned values. - -Mon Nov 10 02:02:49 1997 Martin M. Hunt - - * top.c (quit_confirm): Change exit message. - -Tue Nov 4 16:52:50 1997 Geoffrey Noer - - * config/i386/cygwin32.mh: because cygwin.dll calls malloc/realloc - to allocate memory for environ space, gdb cannot use memory - checks -- set -DNO_MMCHECK - -Tue Nov 4 13:50:59 1997 Jim Blandy - - * jv-exp.y (ArrayAccess): Implement Name [ Expression ]; check the - code to see why this is not trivial. - (copy_exp, insert_exp): New functions. - -Fri Oct 24 17:24:00 1997 Dawn Perchik - - * dwarf2read.c (dwarf2_build_psymtabs_hard): Handle the case - where a compilation unit die has no children (DW_TAG_compile_unit - has DW_children_no). - (scan_partial_symbols): Add comment for nesting_level. - -Wed Oct 29 15:53:24 1997 David Taylor - - * solib.c (solib_break_names): add entry for Solaris 2.6 run - time linker. From Casper Dik via Peter Schauer. - -Tue Oct 28 17:31:47 1997 Martin M. Hunt - - * configure.in (configdir): Add -lcomdlg32 and -ladvapi32 - to WIN32LIBS. - - * configure: Rebuild - -Fri Oct 24 16:48:21 1997 David Taylor - - * sol-thread.c (sol_find_new_threads_callback, - sol_find_new_threads): New functions. - * config/sparc/nm-sun4sol2.h (FIND_NEW_THREADS): New macro, invoke - sol_find_new_threads. - * thread.c (info_threads_command): invoke FIND_NEW_THREADS if it - is defined. - -Thu Oct 23 16:16:04 1997 Jeff Law (law@fast.cs.utah.edu) - - * dbxread.c (process_one_symbol): Put back initialization - of a variable lost during last change. Don't perform - assignment inside conditionals. - * stabsread.c (symbol_reference_defined): Return -1 for error/not - found. All callers changed appropriately. - (define_symbol): Don't perform assignment inside conditionals. - -Wed Oct 22 13:04:52 1997 Jeffrey A Law (law@cygnus.com) - - * mdebugread.c (psymtab_to_symtab_1): Handle new live range stabs - entries. - - * dbxread.c: More comment cleanups. - * stabsread.c: Fix various violations of the GNU coding and - formatting standards. Update/add comments to make code clearer. - (resolve_reference): Delete unused function. - (ref_search_val): Remove function. It didn't belong in stabsread.c - (resolve_live_range): No longer returns a value. Do not add it - to the live range list until the entire range stab has been parsed. - (get_substring): Remove duplicate declaration. - (resolve_symbol_reference): Now static. Remove unnecessary code - to deal with cleanups. - (ref_add): Use xrealloc instea of realloc. - (process_reference): Reorganize slightly to make clearer. - * stabsread.h (resolve_symbol_reference): Remove declaration. - (resolve_reference): Likewise. - * symtab.c (find_active_alias): New function. - (lookup_block_symbol): Use find_active_alias. - * symtab.h (struct range_list): Fix dangling struct live_range - reference. - (ref_search_val): Remove decl. - - * symtab.h (struct range_list): Renamed from struct live_range. - (struct symbol): Remove struct live_range_info substruct. - Bring the alias list and range list fields up to the toplevel - as "aliases" and "ranges". - (SYMBOL_ALIASES, SYMBOL_RANGES): Corresponding changes. - (SYMBOL_RANGE_START, SYMBOL_RANGE_END, SYMBOL_RANGE_NEXT): Delete. - * stabsread.c: Corresponding changes. - - * dbxread.c: Fix various violations of the GNU coding and - formatting standards. Update/add comments to make code - clearer. - (process_later): Use xrealloc instead of realloc. - - * symtab.c: Include inferior.h. - -Tue Oct 21 14:15:26 1997 Per Bothner - - * ch-exp.c: Rename FIELD_NAME to DOT_FIELD_NAME (to avoid conflict). - -Fri Oct 17 13:22:02 1997 Stan Shebs - - * infcmd.c: Improve grammar of "set args" help. - -Thu Oct 16 15:03:58 1997 Michael Meissner - - * remote-sds.c (sds_load): Properly declare as static. - -Wed Oct 15 10:27:14 1997 Doug Evans - - * config/sparc/tm-sparc.h (FIX_CALL_DUMMY): Mask off displacement - to 30 bits in call insn to handle --enable-64-bit-bfd. - (STORE_STRUCT_RETURN): Change to handle --enable-64-bit-bfd. - -Tue Oct 14 22:13:27 1997 Dawn Perchik - - * stabsread.c: Make ref_map entries dynamically allocated. - -Thu Oct 9 12:37:57 1997 Frank Ch. Eigler - - * printcmd.c (print_address_symbolic, address_info): Mask - target-specific flag bits from PC, for more aesthetic disassembly. - * config/mips/tm-mips.h: Added PC masking for MIPS family - (especially the MIPS16). - -Sat Oct 4 18:45:44 1997 Mark Alexander - - * remote-mips.c (mips-initialize): Work around flakiness in - some versions of PMON after loading a program. - -Fri Oct 3 15:49:18 1997 Per Bothner - - * c-lang.h, cp-valprint.c (static_field_print): Make non-static. - * parse.c, parser-defs.h (length_of_subexp): Make non-static. - * jv-exp.y (FieldAccess): Handle dollar-VARIABLE as primary. - (ArrayAccess): Likewise. Also remove warnings. - (CastExpression): Implement (typename) UnaryExpression. - (push_qualified_expression_name): Fix small bug. - * jv-lang.c: Use TYPE_TAG_NAME, not TYPE_NAME for class names. - (_initialize_jave_language): Fix typo (jave -> java). - (java_language): Java does *not* have C-style arrays. - (java_class_from_object): Make more general (and complicated). - (java_link_class_type): Fix typo "super" -> "class". Handle arrays. - (java_emit_char, java_printchar): New function. - (evaluate_subexp_java case BINOP_SUBSCRIPT): Handle Java arrays. - * jv-valprint.c (java_value_print): Implement printing of Java arrays. - (java_print_value_fields): New function. - (java_val_print): Better printing of TYPE_CODE_CHAR, TYPE_CODE_STRUCT. - -Fri Oct 3 09:52:26 1997 Mark Alexander - - * config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16 - addresses to be odd. - (MIPS_FPU_SINGLE_REGSIZE, MIPS_FPU_DOUBLE_REGSIZE): Define. - * mips-tdep.c (mips_extract_return_value): Doubles aren't - returned in FP0 if FP registers are single-precision only. - -Mon Sep 29 23:03:03 1997 Mark Alexander - - * mips-tdep.c (set_reg_offset): New function. - (mips16_heuristic_proc_desc): Calculate offsets of registers - saved by entry pseudo-op after rest of prologue has been read. - Use set_reg_offset to ignore all but the first save of a given - register. - (mips32_heuristic_proc_desc): Initialize frame adjustment value. - * remote-sim.c (gdbsim_store_register): Don't update registers - that have a null or empty name. - * findvar.c (read_register_bytes): Don't fetch registers - that have a null or empty name. - -Tue Sep 30 13:35:54 1997 Andrew Cagney - - * config/mips/tm-mips.h (NUM_REGS): Define conditionally. - (REGISTER_NAMES): Ditto. - -Fri Sep 26 21:08:22 1997 Keith Seitz - - * dsrec.c (load_srec): add ui_load_progress_hook to - display some feedback to user - - * symfile.c (generic_load): add ui_load_progress_hook to - display some feedback to user - -Fri Sep 26 17:32:22 1997 Jason Molenda (crash@pern.cygnus.com) - - * command.c (add_cmd, add_show_from_set): Insert new commands in - alphabetical order. - -Fri Sep 26 12:22:00 1997 Mark Alexander - - * config/mips-tm-mips.h (mips_extra_func_info): New frame_adjust - member for storing offset of MIPS16 frame pointer from SP. - * mips-tdep.c: Use RA_REGNUM instead of hardcoded 31 throughout. - (PROC_FRAME_ADJUST): Define. - (mips16_heuristic_proc_desc): Store frame pointer adjustment value. - (get_frame_pointer): Use frame pointer adjustment value when - calculating frame address. - * remote-sim.c (gdbsim_fetch_register): Don't fetch registers - that have a null or empty name. - -Fri Sep 26 12:40:51 1997 Jeffrey A Law (law@cygnus.com) - - * mips-tdep.c (_initialize_mips_tdep): Allow target files to - override default FPU type. - -Fri Sep 26 10:33:54 1997 Felix Lee - - * configure.tgt (v850-*-*): necmsg.lib instead of v850.lib. - -Wed Sep 24 14:02:09 1997 Andrew Cagney - - * config/v850/tm-v850.h (BREAKPOINT): Use 1 word DIVH insn with - RRRRR=0 for simulator breakpoint. Previous breakpoint insn was two - words. - -Thu Sep 18 15:07:46 1997 Andrew Cagney - - * ser-e7kpc.c (get_ds_base): Only use under Windows. - (windows.h): Include when any _WIN32 host. - -Wed Sep 24 18:12:47 1997 Stu Grossman - - * The following block of changes add support for debugging assembly - source files. - * breakpoint.c (resolve_sal_pc): Prevent crash when pc isn't - associated with a function. - * buildsym.c (record_line start_symtab end_symtab): Don't delete - symtabs which only have line numbers (but no other debug symbols). - * dbxread.c (read_dbx_symtab end_psymtab): Ditto. - - * remote-sim.c: New functions gdbsim_insert/remove_breakpoint. Use - intrinsic simulator breakpoints if available, otherwise do it the - hard way. - - * configure.tgt: Add d30v. - * d30v-tdep.c: New file. - * config/d30v/d30v.mt, config/d30v/tm-d30v.h: New files. - -Tue Sep 23 11:24:13 1997 Stan Shebs - - * Makefile.in (ALLCONFIG): Remove, inaccurate and never used. - -Tue Sep 23 00:08:18 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-tdep.c (mips_push_arguments): Tweak alignment of register - value if the remaining length of a non-integral argument is smaller - than the register size for big-endian non-EABI mode. - - * rs6000-tdep.c (branch_dest): Handle return from signal - handler function via sigreturn kernel call. - -Mon Sep 22 15:32:06 1997 Dawn Perchik - - * stabsread.h, symtab.h, dbxread.c, symtab.c, stabsread.c: - Fix prototypes. Remove function scoped function declarations. - -Fri Sep 19 18:51:26 1997 Felix Lee - - * config/i386/windows.mh (XDEPFILES): need to list some files - explicitly, for odd reasons. - -Tue Sep 16 20:00:05 1997 Per Bothner - - * jv-exp.y (push_fieldnames): New, to handle EXP.FIELD1....FIELDN. - (push_expression_name): New, to handle expression names. - (push_qualified_expression_name): New, for qualified expression names. - (parse_number): Fix bugs in parsing of non-decimal integers. - * jv-lang.h, jv-lang.c (java_demangle_type_signature): New. - * jv-lang.c (type_from_class): Just use name with java_lookup_class. - (java_link_class_type): Add dummy "class" field. - (java_lookup_type): New. - (evaluate_subexp_java case STRUCTOP_STRUCT): Force to address. - * jv-typeprint.c (java_type_print_base): Don't print "class" field. - Use java_demangle_type_signature to print array class types. - * jv-valprint.c (java_value_print): Preliminary array support. - Print pointer as TYPE@HEXADDR, instead of (TYPE)0xHEXADDR. - (java_val_print): Move check for object type to java_value_print. - Check for null. Print pointer as @HEXADDR, not 0xHEXADDR. - - * valops.c (search_struct_field): Search basesclasses in - ascending, not descending order. Hack to avoid virtual baseclass - botch for Java interfaces. - -Tue Sep 16 19:56:23 1997 Per Bothner - - * util.c (run_cleanup_chain, make_run_cleanup, do_run_cleanups): - New cleanup clean for cleanups to be run when at each 'run' command. - * infcmd.c (run_command): Call do_run_cleanups. - - * solib.c (find_solib): Register cleanup to call clear_solib - on a new 'run' command. - (symbol_add_stub): First look for existing objfile with same name. - -Tue Sep 16 16:00:01 1997 Stan Shebs - - * remote-sds.c (sds_load): New function. - (sds_ops): Use it. - (sds_open): Don't set inferior_pid yet. - (sds_kill): Remove contents. - (sds_create_inferior): Rewrite to work more like monitor - interfaces. - (sds_restart): Remove, no longer used. - - * monitor.h (MO_SREC_ACK_PLUS, MO_SREC_ACK_ROTATE): New flags. - * monitor.c (monitor_wait_srec_ack): Add DINK32-specific ack code. - * dsrec.c (load_srec): Always write a header S-record. - * dink32-rom.c (dink32_regnames): Fix the names of float registers. - (dink32_cmds): Set to use S-record downloading with acks. - * remote-est.c (est_cmds): Add MO_SREC_ACK_PLUS flag. - -Tue Sep 16 10:08:27 1997 Andrew Cagney - - * config/v850/tm-v850.h (BREAKPOINT): Set to a truely illegal - instruction. - - * exec.c (exec_file_command): Call set_architecture_from_file. - -Mon Sep 15 13:01:22 1997 Mark Alexander - - * dbxread.c (MSYMBOL_SIZE): New macro. - (end_psymtab): Use MSYMBOL_SIZE to extract size from minimal symbol. - * elfread.c (elf_symtab_read): If ELF symbol is "special", - such as a MIPS16 function, mark minimal symbol as special too. - * mips-tdep.c (pc_is_mips16): New function to check whether - a function is MIPS16 by looking at the minimal symbol. Use - pc_is_mips16 throughout instead of IS_MIPS16_ADDR macro. - * config/mips/tm-mips.h (SYMBOL_IS_SPECIAL, MAKE_MSYMBOL_SPECIAL, - MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): New functions for setting/testing - "special" MIPS16 bit in ELF and minimal symbols. - * mdebugread.c (parse_partial_symbols): Don't construct a partial - symbol table for a file that already has one. - -Sat Sep 13 08:32:13 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mdebugread.c (parse_symbol, handle_psymbol_enumerators): Handle - yet another variant of enumerator debugging info, used by DU 4.0 - native cc. - -Tue Sep 9 20:47:23 1997 Felix Lee - - * config/i386/windows.mh (XDEPFILES): reduce to libwingdb.a. - otherwise link command line is too long. - -Tue Sep 9 17:41:41 1997 Jeffrey A Law (law@cygnus.com) - - * symtab.c, dbxread.c, stabsread.c: Fix up ANSI-C isms. Fix - some formatting problems. - -Mon Sep 8 16:45:51 1997 Stu Grossman - - * ser-e7kpc.c: Don't include w32sut.h. We no longer use the UT - mechanism. Remove prototypes for dos_async_* functions. They don't - exist anymore. - -Mon Sep 8 12:48:50 1997 Ian Lance Taylor - - * top.c (quit_confirm, quit_force): New functions, broken out of - quit_command. - (quit_command): Just call quit_confirm and quit_force. - * top.h (quit_confirm, quit_force): Declare. - -Sun Sep 7 17:26:30 1997 Dawn Perchik - - * dbxread.c, buildsym.c, symtab.c, stabsread.c: Add support for - reading stabs extensions for live range information. - * stabsread.h, partial-stab.h: Add prototypes for new functions. - * symtab.h: Add structure for storing live range information. - -Wed Sep 3 16:39:39 1997 Andrew Cagney - - * top.c (set_arch): New function, update target_architecture. - - * defs.h, top.c (set_architecture_from_arch_mach): Replace - set_architecture, takes the arch and machine as arguments. - - * sh3-rom.c (sh3e_open): Update. - (sh3_open): Ditto. - -Tue Sep 2 12:00:46 1997 Andrew Cagney - - * remote-e7000.c (e7000_fetch_registers): Fix typo, stray paren. - (e7000_wait): Ditto. - -Mon Sep 1 11:21:03 1997 Andrew Cagney - - * top.c (init_main): Add ``set processor'' as an alias for ``set - architecture''. - -Sat Aug 30 13:44:48 1997 Bob Manson - - * config/sparc/sparclite.mt: Removed simulator references (erc32 - has been disabled). - -Thu Aug 28 10:20:04 1997 Andrew Cagney - - * remote-e7000.c (e7000_fetch_registers): Check - target_architecture instead of sh_processor_type. - (e7000_wait): Ditto. - - * config/sh/tm-sh.h (sh_set_processor_type): Delete prototype. - - * sh3-rom.c (sh3_open): Call set_architecture not - sh_set_processor_type. - (sh3e_open): Ditto. - - * sh-tdep.c (sh_show_processor_type_command): Delete. - (sh_set_processor_type_command): Delete. - (sh_target_architecture_hook): Rename from sh_set_processor_type, - use AP to determine architecture. - (sh_show_regs): Use bfd_mach_sh* types. - - * remote-sim.c (gdbsim_open): Pass --arch=XXX to simulator when - architecture was specified explicitly. - - * defs.h (target_architecture, target_architecture_auto, - set_architecture, set_architecture_from_file): Declare. - (target_architecture_hook): Allow targets to be notified of set - arch commands. - - * top.c (init_main): Add set/show/info architecture commands. - (set_architecture, show_architecture, info_architecture): New - functions, parse same. - (set_architecture_from_file): New function, determine arch from - BFD. - -Tue Aug 26 17:13:43 1997 Andrew Cagney - - * remote-sim.c (gdbsim_open): Only pass endianness to sim_open - when set explicitly. Prepend endianness arg so that it can be - overridden. - - * defs.h, top.c (target_byte_order_auto): Make global when - byteorder is selectable. - -Tue Aug 26 15:19:56 1997 Andrew Cagney - - * remote-sim.c (gdbsim_create_inferior): Pass exec_bfd into - sim_create_inferior. - (gdbsim_create_inferior): Pass -1 to proceed, sim_create_inferior - has already set the PC. - (gdbsim_create_inferior): Allow exec_file to be NULL, make "No - exec file" a warning. Ditto for "No program loaded". - -Mon Aug 25 17:08:01 1997 Geoffrey Noer - - * ocd.c: revert Sun change -- enable log file handling - -Mon Aug 25 12:21:46 1997 Andrew Cagney - - * remote-sim.c (gdbsim_open): Pass exec_bfd to sim_open call. - -Sun Aug 24 21:16:59 1997 Geoffrey Noer - - * ocd.c: comment out sections that create and flush wigglers.log - log file when using the wiggler. - -Thu Aug 21 16:18:08 1997 Geoffrey Noer - - * config/powerpc/ppc-eabi.mt: - * config/powerpc/ppc-sim.mt: - * config/powerpc/ppcle-eabi.mt: - * config/powerpc/ppcle-sim.mt: ser-ocd.c needs to be before - other ocd-related files in TDEPFILES - -Thu Aug 21 14:56:04 1997 Geoffrey Noer - - * ppc-bdm.c (bdm_ppc_wait): stop printfing ecr, der - * ocd.c: initialize remote_timeout - (ocd_wait): while looping, call ocd_do_command with OCD_AYT - (ocd_get_packet): remove find_packet goto. If there isn't - an 0x55 at the start, something is quite wrong so error out - instead of advancing in the packet and trying again. If checksum - is invalid, print error message instead of trying again. - * ser-ocd.c (ocd_readchar): error if we attempt to read past - the end of the from_wiggler_buffer. - - -Wed Aug 20 14:08:39 1997 Stan Shebs - - * dink32-rom.c: Don't use "mf" command to fill, is too picky - about alignment. - - -Tue Aug 19 08:41:36 1997 Fred Fish - - * objfiles.c (objfile_relocate): Add call to breakpoint_re_set - after relocations are complete. - * remote-vx.c (vx_add_symbols): Remove call to breakpoint_re_set, - this is now done in objfile_relocate. - -Mon Aug 18 17:29:54 1997 Ian Lance Taylor - - * win32-nat.c (handle_exception): Return a value indicating - whether the exception was handled. Don't handle random exceptions - the first time around, so that structured exception handling - works. - (child_wait): Check the return value of handle_exception. Set the - continue_status argument to ContinueDebugEvent accordingly. - -Mon Aug 18 11:14:15 1997 Nick Clifton - - * configure.tgt: Add support for v850ea target. - -Sun Aug 17 20:31:57 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * m32r-stub.c: fix typo - -Sun Aug 17 17:33:34 1997 Stan Shebs - - * remote-sds.c: Remove unused remnants of remote.c. - (tob64): Return the result length. - (sds_interrupt): Send a stop message. - (sds_wait): Add debug output for signal interpretation, flag - that signal was due to a trap. - (sds_fetch_registers): Fill the registers array correctly for - PowerPC. - (sds_store_registers): Get the right values from registers array. - (putmessage): Tweak length handling so checksum comes out right. - (sds_insert_breakpoint, sds_remove_breakpoint): Do correctly. - -Fri Aug 15 20:53:13 1997 Ian Lance Taylor - - * Makefile.in (init.c): Don't use xargs. - -Fri Aug 15 13:59:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): Add the symbols for any - newly loaded objects upon a TARGET_WAITKIND_LOADED event. - - Rewrite code which determines the TOC address for calling functions - in the inferior under AIX. - * rs6000-nat.c (find_toc_address): New function to determine - the required TOC address from a function address. - (_initialize_core_rs6000): Set up find_toc_address_hook to point - to find_toc_address. - (xcoff_relocate_symtab, xcoff_relocate_core): Remove - add_text_to_loadinfo calls. - (exec_one_dummy_insn): Change pid and status to int to get rid of - compiler warnings. - (xcoff_relocate_symtab): Cast ldi to `int *' when passing it to - ptrace to get rid of compiler warnings. - * rs6000-tdep.c: Add definition for find_toc_address_hook. - (rs6000_fix_call_dummy): If find_toc_address_hook is non zero, - patch TOC address load code in the call dummy with the value - returned from find_toc_address_hook. - (struct loadinfo, loadinfo, loadinfolen, - loadinfotextindex, xcoff_init_loadinfo, free_loadinfo, - xcoff_add_toc_to_loadinfo, add_text_to_loadinfo, find_toc_address): - Remove. - (_initialize_rs6000_tdep): Remove initialization of - coff_add_toc_to_loadinfo_hook and xcoff_init_loadinfo_hook. - * xcoffread.c (coff_add_toc_to_loadinfo_hook, - xcoff_init_loadinfo_hook): Remove. - (struct coff_symfile_info): Add toc_offset field. - (scan_xcoff_symtab): Record toc_offset value in toc_offset field - instead of calling xcoff_add_toc_to_loadinfo_hook. - (get_toc_offset): New function to return the value of the - toc_offset field for an object file. - (xcoff_initial_scan): Remove call of xcoff_init_loadinfo_hook. - * xcoffsolib.h (add_text_to_loadinfo): Remove declaration. - * config/rs6000/tm-rs6000.h: Add declarations for - find_toc_address_hook and get_toc_offset. - -Wed Aug 13 19:31:28 1997 Stan Shebs - - * remote-sds.c: New file, interface to SDS-compatible monitors. - * Makefile.in (remote-sds.o): Add build rule. - * config/powerpc/ppc-eabi.mt, config/powerpc/ppc-sim.mt - (TDEPFILES): Add remote-sds.o. - -Tue Aug 12 14:37:18 1997 Geoffrey Noer - - * ocd.c (ocd_wait): loop until we're in BDM mode instead of - assuming control has returned to GDB. - -Mon Aug 11 19:16:04 1997 Stan Shebs - - * dink32-rom.c: New file, support for DINK32 monitor. - * Makefile.in (dink32-rom.o): Add build rule. - * config/powerpc/ppc-eabi.mt, config/powerpc/ppc-sim.mt - (TDEPFILES): Add dink32-rom.o. - * monitor.h (MO_32_REGS_PAIRED, MO_SETREG_INTERACTIVE, - MO_SETMEM_INTERACTIVE, MO_GETMEM_16_BOUNDARY, - MO_CLR_BREAK_1_BASED): New monitor interface flags. - * monitor.c: Use them. - (monitor_store_register): Use setreg.term if defined. - (monitor_insert_breakpoint, monitor_remove_breakpoint): Notice - if set_break and clr_break fields are empty. - -Mon Aug 11 16:22:36 1997 Geoffrey Noer - - * ocd.c (ocd_insert_breakpoint, ocd_remove_breakpoint): Macro - BDM_BREAKPOINT already has braces around it, remove erroneous ones. - * ser-ocd.c (ocd_write): Conditionalize on _WIN32 instead of - __CYGWIN32__. - * config/powerpc/tm-ppc-eabi.h: Remove BDM_NUM_REGS, BDM_REGMAP - * ppc-bdm.c: move BDM_NUM_REGS, BDM_REGMAP here from tm.h file, - fill in doc fields of bdm_ppc_ops. - (bdm_ppc_fetch_registers): Don't ask for invalid registers such - as the MQ or floating point regs not present on ppc 8xx boards. - (bdm_ppc_store_registers): Don't write those same invalid registers. - * config/i386/cygwin32.mh: Stop including ocd.o ser-ocd.o. - * config/powerpc/ppc-eabi.mt: - * config/powerpc/ppcle-eabi.mt: - * config/powerpc/ppc-sim.mt: - * config/powerpc/ppcle-sim.mt: Include ser-ocd.o. - -Mon Aug 11 16:08:52 1997 Fred Fish - - * frame.h (enum lval_type): Conditionalize on __GNUC__ - instead of __STDC__. - -Sun Aug 10 19:08:26 1997 Jeffrey A Law (law@cygnus.com) - - * utils.c (error): Fix return type for !ANSI_PROTOTYPES. - -Sun Aug 10 16:49:09 1997 Geoffrey Noer - - * ocd.c: move ocd_write_bytes proto to ocd.h since it is used - by ppc-bdm.c, use OCD_LOG_FILE to help debugging, define - BDM_BREAKPOINT if not defined in tm.h - (ocd_error): add new error cases - (ocd_start_remote): send the OCD_INIT command before - OCD_AYT and OCD_GET_VERSION calls, 80 was correct speed after all - (ocd_write_bytes): no longer static - (ocd_insert_breakpoint): no longer static - (ocd_remove_breakpoint): new - * ocd.h: add protos for ocd_write_bytes, ocd_insert_breakpoint, - and ocd_remove_breakpoint - * ppc-bdm.c: change bdm_ppc_ops so we call ocd_insert_breakpoint - and ocd_remove_breakpoint instead of memory_insert_breakpoint - and memory_remove_breakpoint. - (bdm_ppc_open): after calling ocd_open, modify DER - register so interrupts will drop us into debugging mode, finally - disable the watchdog timer on the board so we don't leave BDM - mode unexpectedly. - -Sat Aug 9 01:50:14 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * values.c (value_primitive_field): Account for offset when - extracting the value of a bitfield. - From Paul Hilfinger . - -Fri Aug 8 21:35:44 1997 Mark Alexander - - * gdbserver/utils.c (error): Change prototype to match defs.h. - * gdbserver/low-sim.c: Change simulator calls to use new interface. - * remote.c (remote_write_bytes): Include '$' at start of packet - and checksum at end of packet in overhead calculation. - -Fri Aug 8 15:59:24 1997 Ian Lance Taylor - - * ser-ocd.c: If _WIN32, include . - (dll_do_command): New static variable if _WIN32. - (ocd_open): Set dll_do_command if _WIN32. - (ocd_write): Use dll_do_command rather than do_command. - * config/i386/cygwin32.mh (XDEPFILES): Remove libwigglers.a. - (BDM_DLLNAME, BDM_LIBNAME, BDM_DEFFILE): Don't define. - ($(BDM_LIBNAME)): Remove target. - * wigglers.def: Remove. - - * config/i386/cygwin32.mh ($(BDM_LIBNAME)): Rename target from - libwigglers.def. - (libwigglers.a): Remove target. - -Fri Aug 8 13:11:01 1997 Mike Meissner - - * config/powerpc/ppc{,le}-{eabi,sim}.mt (TDEPFILES): Make sure - ppc-bdm.o and ocd.o are used for all powerpc-eabi targets. - -Thu Aug 7 19:40:52 1997 Geoffrey Noer - - Changes to OCD support to support wiggler box as well as - target boxes: - * ocd.c: change speed in init command to 0 from 80, - add (temporary) logging commands to help debugging, - (ocd_open): if "target ocd wiggler lpt" then use special - ser-ocd.c serial interface which communicates with Wigglers.dll, - otherwise ("target ocd ") do as we did before - (ocd_get_packet): add OCD_LOG_FILE and OCD_SET_CONNECTION to - switch of known commands of len 0 - * ocd.h: add OCD_LOG_FILE - * serial.c (serial_open): do serial_interface_lookup on ocd - in the case of ocd - * ser-ocd.c: add buffer to contain responses from sending a - command to the Wigglers.dll. - (ocd_readchar): return curr char from buffer and increment ptr - (ocd_write): send buffer to Wigglers.dll, storing response in - return buffer and initializing curr location ptr to start of - buffer. - -Thu Aug 7 13:39:31 1997 Geoffrey Noer - - * ocd.h: add OCD_SET_CONNECTION - * ocd.c: rename "do_command" to "ocd_do_command" - -Thu Aug 7 13:09:17 1997 Geoffrey Noer - - Nomenclature change. BDM is a specific type of OCD - (On Chip Debugging). Wiggler is the parallel port box controlled - by Wigglers.dll. The faster target box from Macraigor Systems - is not a wiggler. - * ocd.c: - * ocd.h: - * ppc-bdm.c: - * ser-ocd.c: - Replace all instances of "wiggler_" with "ocd_" and change most other - instances of "wiggler" to "ocd" or "ocd device" depending on context. - * config/m68k/monitor.mt: remove remote-wiggler.o from TDEPFILES - until OCD with that target is supported again. - -Wed Aug 6 16:15:31 1997 Geoffrey Noer - - * Makefile.in: add DLLTOOL = @DLLTOOL@, pass on DLLTOOL to - sub makes, change clean rule to also remove *.a to remove - libwigglers.a, in dependencies: add ppc-bdm.o ocd.o ser-ocd.o and - remove remote-wiggler.o - * configure.in: add DLLTOOL support - * configure: regenerate - * wigglers.def: new file for imports for wigglers.dll - * ser-ocd.c: new file which is layer between ocd.c and either the - wigglers.dll or the target box, only stub so far - * config/powerpc/ppc-eabi.mt: add ppc-bdm.o to TDEPFILES - * config/powerpc/ppc-sim.mt: add ppc-bdm.o to TDEPFILES - * config/i386/cygwin32.mh: add ocd.o ser-ocd.o libwigglers.a - to XDEPFILES, add rules to build libwigglers.a - - checking in changes of Stu Grossman : - * remote-wiggler.c: delete - * ocd.c: new, was remote-wiggler.c - always include sys/types.h, include ocd.h, move WIGGLER - commands and many wiggler prototypes to ocd.h, make wiggler_desc - static, stop making local wiggler functions static, - define write_mem_command for wiggler_write_bytes - (wiggler_start_remote): stop hardcoding the target type, - instead set and use a target_type variable. - (wiggler_open): add new target_type and ops args - (wiggler_wait): now no longer takes pid and target_status as args, - stop trying to set target_status struct, remove BGND insn - checks - (read_bdm_registers): renamed to wiggler_read_bdm_registers - (wiggler_read_bdm_registers): numregs arg changed to reglen arg, - remove pktlen check, set reglen instead of numregs - (dump_all_bdm_regs): delete - (wiggler_fetch_registers): delete - (wiggler_prepare_to_store): now just an empty function - (wiggler_store_registers): delete - (wiggler_read_bdm_register): new - (wiggler_write_bdm_registers): new - (wiggler_write_bdm_register): new - (wiggler_write_bytes): use write_mem_command variable instead of - WIGGLER_WRITE_MEM - (get_packet): renamed to wiggler_get_packet, change refs throughout - (put_packet): renamed to wiggler_put_packet, change refs throughout - (wiggler_get_packet): add break to default case of switch, - change length of WIGGLER_GET_VERSION len to 10 from 4 to match - specs - (wiggler_mourn): unpush_target with current_ops, not &wiggler_ops - (flash_xfer_memory): delete - (noop_store_registers): new placeholder replacement for - target_store_registers() which prevents generic_load from trying to - set up the PC. - (bdm_update_flash_command): add store_registers_tmp variable, - make handling of wiggler_ops more generic -- define wiggler_ops - in a target-specific file instead (such as ppc-bdm.c in the case - of the ppc), use current_target to deal with registers again - making this file less target-specific. - (bdm_read_register_command): new - (_initialize_remote_wiggler): stop doing add_target (&wiggler_ops), - comment out add_cmd ("read-register", ...) - * ocd.h: new, contains common wiggler prototypes, command definitions - * ppc-bdm.c: file for ppc-specific OCD code, including target_ops - structure for ppc bdm - (bdm_ppc_open): new - (bdm_ppc_wait): new - (bdm_ppc_fetch_registers): new - (bdm_ppc_store_registers_: new - (_initialize_bdm_ppc): new - * config/powerpc/tm-ppc-eabi.h: add necessary CPU32 BDM defines - -Wed Aug 6 00:24:08 1997 Jeffrey A Law (law@cygnus.com) - - * hpread.c (hpread_read_struct_type): Use accessor macros rather - than directly mucking around with data structures. - -Tue Aug 5 13:37:14 1997 Per Bothner - - * gdbtypes.h: Re-interpret struct field. Suppport address of static. - Add a bunch of macros. - * coffread.c, dwarf2read.c, dwarfread.c, mdebugread.c, stabsread.c: - Update to use new macros. - * coffread.c, hpread.c, stabsread.c: Remove bugus TYPE_FIELD_VALUE. - * value.h, values.c (value_static_field): New function. - * cp-valprint.c, valops.c: Modify to use value_static_field. - - * jv-lang.c (get_java_utf8_name): Re-write so it works with - implied (missing) data field, as defined by cc1java. - (java_link_class_type): Type length and field offset (in interior) - now includes object header. Get static fields working. - * jv-lang.h (JAVA_OBJECT_SIZE): Update for change in Kaffe. - * jv-typeprint.c (java_type_print_derivation_info, - java_type_print_base): New functions, for better Java output. - * jv-valprint.c: Start to support Java-specific output. - -Sun Aug 3 08:18:09 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-valprint.c (c_val_print): Use extract_address to retrieve - the address of the virtual function. - From Peter Bloecher (Peter.Bloecher@eedn.ericsson.se). - - * eval.c (evaluate_subexp_standard), valarith.c (value_x_unop): - Handle C++ operator *. - -Fri Aug 1 15:21:44 1997 Ian Lance Taylor - - * configure.in: Check for cygwin32 environment. Define and - substitute WIN32LIBS and WIN32LDAPP. Always set configdir to - unix; setting it to win was for an old Tcl/Tk configuration - scheme. - * Makefile.in (TK_CFLAGS): Add @TK_BUILD_INCLUDES@. - (WIN32LDAPP, WIN32LIBS): Define. - (CLIBS): Add $(WIN32LIBS). - (gdb): Use $(WIN32LDAPP). - * configure: Rebuild. - -Thu Jul 31 15:40:19 1997 Per Bothner - - * symtab.h (SYMBOL_INIT_LANGUAGE_SPECIFIC, SYMBOL_INIT_DEMANGLED_NAME, - SYMBOL_DEMANGLED_NAME): Add demangling support for Java. - * utils.c (fprintf_symbol_filtered): Handle language_java. - - * symtab.c (decode_line_1): Handle Java-style package.class.method. - -Wed Jul 30 14:04:18 1997 Per Bothner - - * java-*: Renamed to jv-*, to make fit within 14 characters. - * jv-lang.h (java_type_print): Added declaration. - * jv-typeprint.c: New file. Provides java_print_type. - * jv-lang.c (java_link_class_type): New function. - (java_language_defn): Replace c_print_type by java_print_type. - * Makefile.in: Update accordingly. - -Tue Jul 29 10:12:44 1997 Felix Lee - - * Makefile.in (init.c): except some mswin files do need to be - scanned. oh well. - -Mon Jul 28 14:04:39 1997 Felix Lee - - * Makefile.in (init.c): don't try to scan mswin for _initialize - funcs. (generates misleading error message because files have - .cpp suffix, not .c suffix) - -Mon Jul 28 13:27:21 1997 Felix Lee - - * ser-e7kpc.c: -> "mswin/w32sut.h" - -Mon Jul 28 02:54:31 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * xcoffread.c (coff_getfilename): Do not strip directory component - of filename. - -Fri Jul 25 15:16:15 1997 Felix Lee - - * mon960-rom.c: removed unused #includes; no ioctl.h in Windows. - * nindy-share/ttyflush.c: find sleep() for _MSC_VER. - * remote-array.c: #include for isascii(). - * utils.c (notice_quit,pollquit): cleanup. _WIN32 -> _MSC_VER. - -Fri Jul 25 16:48:18 1997 Jeffrey A Law (law@cygnus.com) - - * top.c (execute_command): Force cleanup of alloca areas. - * findvar.c (registers_changed): Likewise. - -Fri Jul 25 15:37:15 1997 Stu Grossman - - * v850ice.c: Include . Support new v850 DLL interface. - * Add defs for target status. - -Tue Jul 22 12:11:48 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * config/mips/tm-mips64.h: longs, long longs, and pointers - are all 64 bits on EABI mips targets. - -Thu Jul 17 11:38:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * partial-stab.h (case N_BINCL): detect missing partial symtab. - * dbxread.c: Add a complaint for N_BINCL without a corresponding - partial symtab. Remove earlier change of 5/27/97. - -Wed Jul 16 10:38:03 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * sol-thread.c (sol_thread_[store, fetch]_registers): if - inferior_pid is an LWP rather than a Solaris thread, let - procfs handle the request. - (rw_common, sol_thread_xfer_memory): procfs_xfer_memory will - only work if inferior_pid points to an LWP (rather than a - Solaris thread). Use procfs_first_available to find a good LWP. - (info_solthreads): added a maintenance command to list all - known Solaris threads and their attributes. - * mips-tdep.c (mips_do_registers_info): Completely changed the - output format to be neat and columnar. Added the helper funcs - do_fp_register_row and do_gp_register_row. Also small mods to - mips_print_register, which is still used to print a single reg. - -Mon Jul 14 18:02:53 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * procfs.c (wait_fd): Handle an fd that has "hung up" or - otherwise terminated (Solaris threads). - -Thu Jul 10 00:02:41 1997 Martin M. Hunt - - * defs.h (init_ui_hook): Change prototype to accept one arg. - * main.c (gdb_init): Change prototype to accept one arg. - * top.c (gdb_init): Accepts one argument which it uses to - call (*init_ui_hook). - -Fri Jul 4 14:49:33 1997 Ian Lance Taylor - - * source.c (OPEN_MODE, FDOPEN_MODE): Define; value depends upon - whether CRLF_SOURCE_FILES is defined. - (open_source_file): Use OPEN_MODE with open and openp. - (print_source_lines): Use FDOPEN_MODE with fdopen. If - CRLF_SOURCE_FILES is defined, ignore \r characters. - (forward_search_command): Use FDOPEN_MODE with fdopen. - (reverse_search_command): Likewise. - * config/i386/xm-cygwin32.h (CRLF_SOURCE_FILES): Define. - (LSEEK_NOT_LINEAR): Don't define. - -Thu Jul 3 17:41:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * mips-tdep.c (mips_extract_return_value): align 4-byte float - return values within the 8-byte FP register. - -Thu Jul 3 13:48:11 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * mips-tdep.c (mips_push_arguments): don't left-adjust 32-bit - integers in 64-bit register parameters before function calls. - -Mon Jun 30 17:54:51 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * mips-tdep.c (mips_push_arguments): special-case handling for - odd-sized struct parameters passed in registers / on stack. - -Mon Jun 30 15:30:38 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * mips-tdep.c (mips_push_arguments): tweak alignment of small - structs passed in registers for little-endian non-EABI mode. - -Mon Jun 30 13:05:39 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * breakpoint.c (frame_in_dummy): use generic dummy if available. - (check_duplicates, clear_command): compare sections only if - doing overlay debugging. - -Fri Jun 27 23:03:53 1997 Fred Fish - - * buildsym.h (struct subfile): Add debugformat member. - (record_debugformat): Declare global function. - * buildsym.c (start_subfile): Initialize debugformat member - to NULL. - (record_debugformat): New function to record the format. - (end_symtab): Copy format into symtab debugformat member. - (end_symtab): Free subfile debugformat member. - * symmisc.c (free_symtab): Free debugformat when freeing - symtab. - * symfile.c (allocate_symtab): Initialize the new debugformat - member for new symtabs. - * symtab.h (struct symtab): Add debugformat member. - * source.c (source_info): Print the debug format. - - * os9kread.c (os9k_process_one_symbol): Call record_debugformat - with "OS9". - * hpread.c (hpread_expand_symtab): Call record_debugformat - with "HP". - (hpread_process_one_debug_symbol): Ditto. - * dbxread.c (process_one_symbol): Call record_debugformat - with "stabs". - * coffread.c (coff_start_symtab): Call record_debugformat - with "COFF". - * xcoffread.c (read_xcoff_symtab): Call record_debugformat - with "XCOFF". - * dwarfread.c (read_file_scope): Call record_debugformat - with "DWARF 1". - * dwarf2read.c (read_file_scope): Call record_debugformat - with "DWARF 2". - * dstread.c (dst_end_symtab): Set debugformat to be - "Apollo DST". - * mdebugread.c (new_symtab): Set debugformat to be "ECOFF". - -Fri Jun 27 21:05:45 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * mips-tdep.c (mips_push_arguments): handle alignment of - integer and struct args on stack for mips64 big-endian. - -Fri Jun 27 19:19:12 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * config/mips/tm-mips.h (USE_STRUCT_CONVENTION): MIPS_EABI returns - structs in a register wherever possible. - * mips-tdep.c (mips_extract_return_value): handle structs. - (mips_store_return_value): handle values smaller than MIPS_REGSIZE - (including structs, if gdb ever allows it). - -Fri Jun 20 17:58:34 1997 Fred Fish - - * sh-tdep.c (sh_skip_prologue): Also recognize fmov insns. - (sh_frame_find_saved_regs): Recognize fmov insns and adjust - stack push count accordingly. - * sh-tdep.c (IS_FMOV, FPSCR_SZ): New defines - -Thu Jun 19 08:18:48 1997 Mark Alexander - - * utils.c (floatformat_from_doublest): Improve test for infinity. - -Wed Jun 18 13:47:52 1997 Fred Fish - - * dwarfread.c (isreg, optimized_out, offreg, basereg): Move - global variables into the struct dieinfo structure. - (locval): Pass pointer to a dieinfo struct rather than a - pointer to the raw location information. Change prototype. - Set isreg, optimized_out, offreg and basereg as appropriate. - (struct_type): Call locval with dieinfo struct pointer. - (new_symbol): Ditto. - (new_symbol): Call locval and save location before testing - the values of the new dieinfo struct flags, set by locval. - -Tue Jun 17 13:30:12 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * procfs.c (proc_set_exec_trap, procfs_init_inferior, procfs_wait, - unconditionally_kill_inferior): Undo Oct 26 1996 and Apr 26 1997 - changes to trace PRFS_STOPTERM and handle PR_DEAD. - These changes tried to work around a problem with an early DU 4.0 - release, but they trigger subtle timing dependent kernel bugs - in older OSF/1 releases. - -Tue Jun 17 06:52:47 1997 Fred Fish - - * dwarfread.c (new_symbol): Use SYMBOL_VALUE_ADDRESS, instead of - SYMBOL_VALUE, to set the value of LOC_STATIC symbols. - -Mon Jun 16 18:38:28 1997 Mark Alexander - - * infrun.c (wait_for_inferior): Mark registers as invalid when - stepping over an instruction that triggered a watchpoint. - * remote-mips.c: Numerous changes to support hardware breakpoints - and watchpoints on LSI MiniRISC and TinyRISC boards. - * mips-tdep.c: Move MIPS16-related macros to config/mips/tm-mips.h. - (mips_breakpoint_from_pc): Account for different breakpoint - instructions used by PMON and IDT monitor. - * config/mips/tm-embed.h: Enable hardware breakpoints on embedded - MIPS targets. - * config/mips/tm-mips.h: Define breakpoint instructions for - PMON and IDT monitor. Move MIPS16-related macros here from - mips-tdep.c. - -Fri Jun 13 13:44:47 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * config/mips/tm-tx39[l].h, tx39[l].mt: change r3900 target to tx39. - -Fri Jun 13 14:14:10 1997 Jeffrey A Law (law@cygnus.com) - - * mn10300-tdep.c (mn10300_analyze_prologue): Fix some comments. - Add missing return statements after finding an "add imm{16,32},sp" - instruction. - (mn10300_frame_chain): Add in size of our register save area to find - our caller's frame if our caller does not have a frame pointer. - -Fri Jun 13 12:55:49 1997 Doug Evans - - * symfile.c (generic_load): Check return code of target_write_memory. - -Fri Jun 13 10:28:09 1997 Fred Fish - - * config/i386/nm-linux.h: Enable prototypes that were #ifdef out. - * config/tm-sysv4.h (in_plt_section): Add prototype. - - * maint.c (maintenance_translate_address): Avoid assignment - inside if, per GNU coding standards. - * symfile.c (simple_read_overlay_table): Avoid assignments inside if, - per GNU coding standards. - - * monitor.c (parse_register_dump): Is really a void function. - Add prototype. - (monitor_read_memory): Remove unused variable "name". - (monitor_read_memory): Remove unused variable "regbuf". - (monitor_open): Remove unused variable "i". - (get_hex_word): Apparently unused, #if away for now. - (from_hex): Ditto. - - * i386v4-nat.c (supply_fpregset): Remove unused variable "regi". - (fill_fpregset): Remove unused variables "regi", "to", "from" and - "registers". - - * remote-e7000.c (ctype.h): Include. - (e7000_insert_breakpoint): #if away unused arg used by unused expr. - * frame.h (generic_get_saved_register): Add prototype. - (enum lval_type): Add partial forward decl. - * dsrec.c (make_srec): Remove unused variable "type_code". - * remote-sim.c (gdbsim_wait): Handle sim_running and sim_polling - cases by just ignoring them. - (command.h): Include. - - * java-exp.y (parse_number): Remove unused variable "unsigned_p". - * java-lang.c (gdbcore.h): Include for prototypes. - (type_from_class): Remove unused variable "ftype". - (type_from_class): Remove unused variable "name_length". - (evaluate_subexp_java): Add default case to handle remaining - enumerations. - * java-valprint.c (c-lang.h): Include for prototypes. - - * symfile.c (simple_read_overlay_region_table): #if away - unused function. - (simple_free_overlay_region_table): Ditto. - (overlay_is_mapped): Add default case to switch. - (simple_read_overlay_region_table): Ditto. - (simple_read_overlay_region_table): Add prototype. - - * symtab.c (fixup_symbol_section): Remove unused msym variable. - (fixup_psymbol_section): Ditto. - (find_pc_sect_symtab): Make distance a CORE_ADDR. - - * utils.c: Add comment about t_addr being either unsigned long or - unsigned long long. - (paddr): Change formats to match actual types args are cast to. - (preg): Ditto. - (paddr_nz): Ditto. - (preg_nz): Ditto. - - * defs.h (perror_with_name): Is a NORETURN function. - * utils.c (perror_with_name): Is a NORETURN function. - (error): Is NORETURN independently of ANSI_PROTOTYPES. - - * symtab.c (fixup_symbol_section): Remove prototype. - * symtab.h: (fixup_symbol_section): Add prototype. - * m32r-rom.c (report_transfer_performance): Add prototype. - * sparclet-rom.c: Ditto. - * dsrec.c: Ditto. - - * c-exp.y (parse_number): Cast args to float* or double* as - appropriate for conversion format. - * java-exp.y (parse_number): Ditto. - - * Makefile.in (c-exp.tab.c): Remove #line lines that refer - to nonexistant y.tab.c file. - (java-exp.tab.c): Ditto. - (f-exp.tab.c): Ditto. - (m2-exp.tab.c): Ditto. - - * sh-tdep.c (symfile.h): Include. - (gdb_string.h): Include. - (sh_fix_call_dummy): Ifdef away, currently unused. - * config/sh/tm-sh.h (pop_frame): Add prototype. - * config/sh/tm-sh.h (sh_set_processor_type): Add prototype. - -Sat Jun 7 02:34:19 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * eval.c (evaluate_subexp_for_sizeof): Handle dereferencing - of non-pointer values. - - * symtab.c (gdb_mangle_name): Improve mangling of nested types, - their physical names already include the class name. - - * valops.c (value_cast): Handle upcast of a class pointer. - - From Andreas Schwab (schwab@issan.informatik.uni-dortmund.de): - * corelow.c (get_core_registers): Make secname big enough. - -Fri Jun 6 14:43:23 1997 Keith Seitz - - * config/sh/tm-sh.h: add define for FPSCR_REGNUM - * sh-tdep.c (sh_show_regs): print out all registers for - the current processor - -Fri Jun 6 13:01:55 1997 Andrew Cagney - - * remote-sim.c (gdbsim_kill): Remove call to depreciated function - sim_kill. - -Thu Jun 5 11:39:03 1997 Ian Lance Taylor - - Fixes for recent correction to PE format: - * coffread.c (pe_file): New static variable. - (struct find_targ_sec_arg): Change resultp from pointer to int to - pointer to pointer to asection. - (find_targ_sec): Just store the section in args->resultp, not the - section offset value. - (cs_to_section): Compute the section offset value from the - section. - (cs_section_address): New static function. - (coff_symfile_read): Set pe_file. - (read_one_sym): When reading a PE file, adjust the symbol value to - include the section address if the symbol has an appropriate - storage class. - -Tue Jun 3 16:24:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com) - - * configure.tgt: add mipsr3900-elf target - * config/mips/r3900.mt r3900l.mt tm-r3900.h tm-r3900l.h: ditto - -Tue May 27 10:34:11 1997 Michael Snyder - - * dbxread.c: Check malloc's return for null, prevent segv. - -Fri May 23 14:45:02 1997 Bob Manson - - * infcmd.c (jump_command): Don't try to dereference sfn if it's - NULL. - -Fri May 23 13:51:57 1997 Andrew Cagney - - * top.c (init_cmd_lists): Always initialize endianlist. - (init_main): Always define endian commands. - (set_endian_big): Issue warning if endian not selectable. - (set_endian_little): Ditto. - (set_endian_auto): Ditto. - -Thu May 22 11:53:21 1997 Andrew Cagney - - * remote-sim.c (simulator_command): Restrict access to the - simulator to periods when the simulator is open. - -Wed May 21 16:03:25 1997 Michael Snyder - - * procfs.c (init_procinfo): new function, abstracts some code - shared by create_procinfo and do_attach; - (procfs_set_inferior_syscall_traps): new function, abstracts - some code needed by procfs_init_inferior, do_attach, and - procfs_lwp_creation_handler; (procfs_first_available): new - function, find any LWP that's runnable; (procfs_thread_alive): - replace stub function with real implementation; - (procfs_lwp_creation_handler): fix bug starting new child - threads; (info_proc): bug fixes and enhancements for the - "INFO PROCESSES" command; (close_procinfo_file): call new - function "delete_thread" to cleanup GDB's thread database; - (proc_init_failed): add new argument "kill", to control whether - process is killed (so this function can be shared by - create_procinfo and do_attach); (procfs_exit_handler): handle - exit from an attached process, and cleanup procinfo handles - when the process exits; (procfs_resume, procfs_wait): cleanup - after a thread when it exits; (do_attach, do_detach): handle - attached processes with multiple threads; plus some general - improvements in the diagnostic output. - * sol-thread.c (sol_thread_alive): replace stub with real - implementation; (thread_to_lwp, lwp_to_thread): enhance to - handle threads that may have exited; (sol_thread_attach): add - startup setup stuff; (sol_thread_detach): add unpush_target - call; (sol_thread_mourn_inferior): add unpush_target call; - (sol_thread_wait, sol_thread_resume): enhance to deal with - thread exit cleanly; (sol_thread_new_objfile, - sol_thread_pid_to_str): detect unsuccessful startup and - don't crash; plus some general cleanup. - * thread.c (delete_thread): new function, allows targets to - notify gdb when a thread is no longer valid. - * infrun.c (wait_for_inferior): don't try to detect a new - thread on receiving a TARGET_EXITED event. - -Tue May 20 09:32:02 1997 Andrew Cagney - - * remote-sim.c (gdbsim_open): Pass callback struct. - (init_callbacks): Remove call to sim_set_callbacks. - -Thu May 15 07:56:50 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/rs6000/tm-rs6000.h (SIG_FRAME_LR_OFFSET): Define. - * rs6000-tdep.c (frameless_function_invocation): Mark frames - with a zero PC as frameless to improve backtraces from core dumps - caused by dereferencing a NULL function pointer. - (frameless_function_invocation, frame_saved_pc, rs6000_frame_chain): - Handle frameless functions interrupted by a signal. - - * sparc-tdep.c (sparc_init_extra_frame_info, sparc_frame_saved_pc): - Handle frameless functions interrupted by a signal. - -Wed May 14 08:58:55 1997 Jeffrey A Law (law@cygnus.com) - - * mn10200-tdep.c (mn10200_analyze_prologue): Update prologue comments - to reflect current reality. Gross attempt at handling out of - line prologues. - - * mn10200-tdep.c (mn10200_skip_prologue): Don't look at the debug - symbols to find the end of the prologue. - * mn10300-tdep.c (mn10300_skip_prologue): Likewise. - -Thu May 8 08:42:47 1997 Andrew Cagney - - * configure.in (AC_TYPE_SIGNAL): Add - * configure: Re-generate. - * remote-sim.c: Signal returns RETSIGTYPE. - -Wed May 7 20:05:07 1997 Andrew Cagney - - * target.h (target_stop): Drop argument so it can be tested for - NULL. - -Sat May 3 20:51:48 1997 Mark Alexander - - * utils.c (floatformat_from_doublest): Handle infinity properly. - -Thu May 1 11:44:46 1997 Michael Snyder - - * Finalize merge from Hurd folk. - Mon Oct 30 16:41:04 1995 Miles Bader - * thread.c (thread_apply_command, thread_apply_all_command, - thread_command): Make sure TP is alive. - (thread_alive): New function. - Tue Nov 14 14:31:03 1995 Miles Bader - * infrun.c (sig_print_info): Deal better with long signal names. - Wed Nov 22 15:23:35 1995 Miles Bader - * thread.c (thread_id_to_pid): New function. - Fri Dec 1 13:25:25 1995 Miles Bader - * gnu-nat.c: (set_thread_cmd_list, show_thread_cmd_list, - set_thread_default_cmd_list, show_thread_default_cmd_list): - New variables. (set_thread_cmd, show_thread_cmd, - set_thread_default_cmd, show_thread_default_cmd): New functions. - Fri Apr 18 15:20:16 1997 Miles Bader - * gnu-nat.c (inf_startup): remove TASK parameter. - (inf_set_task): replace with new function (inf_set_pid). - * gdbthread.h: Add extern decl for thread_cmd_list. - -Thu May 1 02:28:21 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * printcmd.c (disassemble_command): Adjust low function bound - by FUNCTION_START_OFFSET. - -Mon Apr 28 21:25:32 1997 Michael Snyder - - * Makefile.in: Add rule for gnu-nat.o and i386gnu-nat.o (Gnu Hurd) - * config/i386/i386gnu.mh: remove rules for [i386]gnu-nat.o, now - in Makefile.in (as for other targets); add NATDEPFILE corelow.o to - satisfy symbol dependancy in solib.c (core_ops). - * target.[ch] conditionalize Mach-specific signals so that they - won't show up in non-Mach gdb's! - * thread.c: change name of static function "thread_switch" to - "switch_to_thread", to avoid conflict with Mach global symbol; - move thread_cmd_list to global scope so targets can add their - own thread commands. - * infrun.c: sig_print_info: allow for long signal names. - * gnu-nat.[ch]: tidying up comments. - * gnu-nat.c: remove calls to prune_threads and renumber_threads; - gnu_wait must not return -1 when inferior exits; - attach_to_child will modify inferior_pid in a way that allows - fork_inferior to remain unchanged; remove extra arg from - startup_inferior; move Mach thread commands here from thread.c. - -Mon Apr 28 18:21:20 1997 Michael Snyder - - * symtab.c: decode_line_1, replace the assignment to - values.sals[0].pc which I accidentally left out on 4/3/97. - -Mon Apr 28 17:27:40 1997 Michael Snyder - - * c-exp.y: make parse_number reject "123DEADBEEF". - (fix by Bob Manson). - * java-exp.y: Ditto. - * top.c: change "to enable to enable" to "to enable" in a couple - of help strings. - -Mon Apr 28 09:01:59 1997 Mark Alexander - - * breakpoint.c (remove_breakpoint): Pass correct type to - target_remove_watchpoint. - * target.h: Improve comment for target_{remove,insert}_breakpoint. - -Sat Apr 26 03:38:02 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-tdep.c (heuristic_proc_desc): Increase search limit - for return address register, handle `ret' instruction. - - * corelow.c (get_core_registers): Initialize cf. - - * procfs.c: Minor changes to make pre-ANSI compilers happy. - (procfs_notice_signals): Copy traced signal set back to - pi->prrun.pr_trace. - (unconditionally_kill_inferior): If PR_DEAD is defined, - rerun inferior after killing it. - -Fri Apr 25 00:10:18 1997 Jeffrey A Law (law@cygnus.com) - - * config/mn10300/tm-mn10300.h (EXTRACT_STRUCT_VALUE_ADDRESS): The - structure value address is found in $a0 now. - * config/mn10200/tm-mn10200.h (EXTRACT_STRUCT_VALUE_ADDRESS): Likewise. - -Thu Apr 24 13:31:10 1997 Jeffrey A Law (law@cygnus.com) - - * config/mn10300/tm-mn10300.h (STORE_RETURN_VALUE): Pointers are - returned in $a0. - (EXTRACT_RETURN_VALUE): Likewise. - - * mn10300-tdep.c (mn10300_analyze_prologue): Check for a return - insn at "pc", not "fi->pc". - -Wed Apr 23 11:18:45 1997 Jeffrey A Law (law@cygnus.com) - - * config/mn10200/tm-mn10200.h (STORE_RETURN_VALUE): Pointers are - returned in $a0. - (EXTRACT_RETURN_VALUE): Likewise. - -Tue Apr 22 11:58:15 1997 Fred Fish - - * config/arm/tm-arm.h (TARGET_DOUBLE_FORMAT): Define to use - floatformat_ieee_double_littlebyte_bigword for little endian - target byte order. - * utils.c (floatformat_to_doublest): Create local preswapped - copy of input for floatformat_littlebyte_bigword formats. - (get_field, put_field): Treat floatformat_littlebyte_bigword - the same as floatformat_little. - (floatformat_from_doublest): Postswap output words for - the floatformat_littlebyte_bigwords format. - -Tue Apr 22 09:02:10 1997 Stu Grossman (grossman@critters.cygnus.com) - - * config/alpha/alpha-osf3.mh config/i386/{i386gnu linux}.mh - config/mips/{embed embed64 embedl embedl64 vr4300 vr4300el vr5000 - vr5000el}.mt config/powerpc/{aix aix4}.mh config/rs6000/{aix - aix4}.mh config/sh/sh.mt config/sparc/sp64sim.mt: - config/v850/v850.mt: - Remove -lm. That's now handled by configure. - - * Makefile.in (maintainer-clean): Add distclean to dependencies. - Remove duplicate rm's of files. - -Mon Apr 21 09:49:25 1997 Stu Grossman (grossman@critters.cygnus.com) - - * remote-pa.c: Remove. It's broken and no longer necessary. - - Sat Apr 19 11:56:10 1997 Per Bothner - - * java-exp.y: Combine TRUE and FALSE into BOOLEAN_LITERAL. - (Avoids name clash with broken AIX header files.) - -Sat Apr 19 01:49:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * serial.c (serial_log_command): Fix fputs_unfiltered calls. - - * config/powerpc/tm-ppc-aix4.h, config/rs6000/tm-rs6000-aix4.h - (DONT_RELOCATE_SYMFILE_OBJFILE): Removed. - * xcoffsolib.h (struct vmap): Add new members tvma, toffs and dvma, - remove tadj. - * exec.c (bfdsec_to_vmap): Initialize new vmap members, initialize - tstart and dstart with section VMA. - * rs6000-nat.c (vmap_symtab): Relocate relative to the VMA in the - object file. - (vmap_ldinfo, xcoff_relocate_core): Adjust tstart by section offset - of the text section, remove DONT_RELOCATE_SYMFILE_OBJFILE hack. - (vmap_exec): Relocate relative to the VMA in the object file, - relocate .bss section as well. - (xcoff_relocate_core): No longer adjust section addresses by VMA. - * rs6000-tdep.c (find_toc_address): Change type of tocbase - to CORE_ADDR. - * xcoffread.c (secnum_to_bfd_section): New routine to get - BFD section from CS section number. - (scan_xcoff_symtab): Make toc_offset section relative. - - * symtab.c (total_number_of_methods): Avoid core dump if - baseclass type is still undefined. - -Fri Apr 18 17:25:10 1997 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in (SUBDIRS): Add mswin so that make cleanup cleans up - that directory. - * defs.h utils.c (error warning): Make message be const. - * main.c (fputs_unfiltered): Only send gdb_stdout and gdb_stderr - to hook. Otherwise send it to fputs. - * monitor.c monitor.h (monitor_get_dev_name): New function. Does - the obvious. - * remote-e7000.c: Remove debugify stuff. Change printf, fprintf - to _filtered forms to make output appear in GUIs. Replace all - uses of SERIAL_READCHAR with readchar, which has better error - checking. - * (e7000_parse_device): Add prototype. - (readchar): Improve doc. Handle random serial errors. - (expect): Disable notice_quit code. It's busted. Remove - serial error handling (it's now handled in readchar). Remove - remote_debug echoing. That's handled in readchar as well. - (e7000_parse_device): Remove serial_flag arg. It's not - necessary. - (e7000_open): Split into two pieces. Second part is - e7000_start_remote, and is error protected. Now, when we connect - to the target, we setup the initial frame and registers so that - the user gets an immediate indication of where the target is. - (gch): Remove debug output. That's handled by readchar. - (e7000_read_inferior_memory): Handle errors better. - (_initialize_remote_e7000): Get rid of `' things from - command names. They show up when doing completion and confuse - things horribly. - * ser-e7kpc.c: Get rid of the DLL's since we can access the device - directly from Win32s and Win95. Get rid of debugify crud. - * serial.c: Remove debugify cruft. - * (serial_logchar serial_log_command serial_write serial_readchar - serial_send_break serial_close): Merge common functionality into - serial_logchar. Clean up rest of routines. - * sparclet-rom.c: Disembowel. Leave only download routine. - Download routine now switches to remote target automatically. - * top.c (disconnect): Only define if SIGHUP is defined. Cleans - up MSVC/Win32 problem. - * utils.c (gdb_flush): Don't call hook unless it's for gdb_stdout - or gdb_stderr. - * config/sh/tm-sh.h: Define TARGET_SH for WinGDB. - * config/sparc/tm-sparclet.h: Remove override for prompt. - -Fri Apr 18 13:38:19 1997 Doug Evans - - * remote-sim.c (gdbsim_open): Only pass -E to sim_open if - TARGET_BYTE ORDER_SELECTABLE. - -Fri Apr 18 16:52:41 1997 Andrew Cagney - - * remote-sim.c (init_callbacks): Initialize poll_quit and magic - fields of gdb_callback. - (gdbsim_stop): Add gdbsim_stop to list of supported client - operations. - (gdbsim_wait, gdbsim_resume): Move call to sim_resume into - sim_wait where gdb is in a position to handle a long running - function. - (gdbsim_cntrl_c): New function. Wrap the sim_resume call in a - SIGINT handler. - (gdb_os_poll_quit): New function. Check for a quit pending on the - console. - -Thu Apr 17 14:30:04 1997 Per Bothner - - * objfiles.c (allocate_objfile): Allow NULL bfd argument. - * defs.h (enum language): Add language_java. - * java-exp.y, java-lang.c, java-lang.h, java-valprint.c: New files. - * Makefile.in: Update for new files. - * symfile.c (deduce_language_from_filename): Recognize .java. - -Thu Apr 17 02:20:23 1997 Doug Evans - - * m32r-stub.c (stash_registers): Rewrite. - (restore_registers): Renamed to restore_and_return. - (cleanup_stash): New function. - (process_exception): New function. - (_catchException*): Rewrite. - - * remote-sim.c (gdbsim_load): Update call to sim_load. - (gdbsim_create_inferior): No longer pass start_address to - sim_create_inferior. - (gdbsim_open): Pass endian indicator as arg. - -Tue Apr 15 15:31:09 1997 Stan Shebs - - * remote.c (get_offsets): Don't use scanf for interpreting - response to qOffsets. - -Tue Apr 15 14:51:04 1997 Ian Lance Taylor - - * gdbserver/Makefile.in (INSTALL_XFORM): Remove. - (INSTALL_XFORM1): Remove. - (install-only): Use $(program_transform_name) directly, rather - than using $(INSTALL_XFORM) and $(INSTALL_XFORM1). - (uninstall): Transform name. - -Mon Apr 14 17:06:27 1997 Mark Alexander - - * remote-mips.c (mips_load): Ensure that PC gets updated - after a load on LSI target. - -Mon Apr 14 15:54:51 1997 Geoffrey Noer - - * procfs.c (notice_signals): fix typo - -Mon Apr 14 16:25:10 1997 Ian Lance Taylor - - * gdbserver/Makefile.in (INSTALL): Change install.sh to - install-sh. - -Mon Apr 14 11:55:27 1997 Geoffrey Noer - - * config/i386/cygwin32.mh: remove -lkernel32 from XM_CLIBS - since gcc automatically includes it - -Thu Apr 10 13:20:53 1997 Geoffrey Noer - - * procfs.c: Substantial (but incomplete) changes to support - sysv4.2mp procfs as implemented in UnixWare 2.1. The procinfo - struct now has substructs like struct flt_ctl instead of - just a fltset_t and has a ctl_fd, status_fd, as_fd, and - map_fd instead of a single fd. Non-sysv4.2mp procfs models - still have the structs and multiple fds, but don't use the - entire struct and the four fds all point to the same thing. - We use PROCFS_USE_READ_WRITE to decide whether to talk to - procfs with reads/writes or use ioctl instead. We use - HAVE_MULTIPLE_PROC_FDS to determine whether procfs really has - multiple fds or not. PROC_NAME_FMT is split out into - CTL_PROC_NAME_FMT, AS_PROC_NAME_FMT, MAP_PROC_NAME_FMT, - STATUS_PROC_NAME_FMT. - - (procfs_notice_signals): now a necessary wrapper around - (notice_signals): which are the new guts for noticing signals - (open_proc_file): gets a new flag arg used in sysv4.2mp to - determine whether or not to attempt to open the ctl_fd. - (procfs_read_status): new local function, reads procfs status - (procfs_write_pcwstop): new local function, writes a PCWSTOP - (procfs_write_pckill): new local function, writes a PCKILL - (unconditionally_kill_inferior): remove signo since we now - just call procfs_write_pckill(). - (procfs_xfer_memory): call lseek with SEEK_SET rather than 0 - (proc_iterate_over_mappings): the whole function is ifdefed - on UNIXWARE to keep things readable. - - Expanded the syscall_table to include new potential sysv4.2mp - members. Note that all ifdefs of UNIXWARE should be eliminated - if possible or renamed to describe what's being selected for a - bit better. Sysv4.2mp and IRIX both have SYS_sproc so the - IRIX specific code now also checks it's not UNIXWARE. - - * config/i386/tm-i386v42mp.h: also define HAVE_PSTATUS_T, - HAVE_NO_PRRUN_T, PROCFS_USE_READ_WRITE, and UNIXWARE - * config/mips/nm-irix4.h: set CTL_PROC_NAME_FMT et al to - "/debug/%d" as PROC_NAME_FMT used to be - -Wed Apr 9 11:36:14 1997 Jeffrey A Law (law@cygnus.com) - - * mn10300-tdep.c: Almost completely rewritten based on mn10200 - port. - * config/mn10300/tm-mn10300.h: Likewise. - -Tue Apr 8 10:45:24 1997 Stu Grossman (grossman@critters.cygnus.com) - - * config/pa/{hppabsd.mt hppahpux.mt hppaosf.mt}: Remove - remote-pa.o from TDEPFILES. Nobody uses it, and besides, it's a - lousy out-of-date clone of remote.c. - -Fri Apr 4 08:21:21 1997 Stu Grossman (grossman@critters.cygnus.com) - - * remote.c: Fix problems realized while showering. - * (hexnumlen): Add prototype. Use max, not min. - * (remote_write_bytes remote_read_bytes): Fix max packet size - calculations to properly account for packet overhead. Also handle - (probably rare) case where remote_register_buf_size isn't set. - - * remote.c: Fix doc for `C' and `S' commands to indicate full - address. - * (remote_ops extended_remote_ops remote_desc remote_write_size): - Make static. - * (remote_fetch_registers remote_write_bytes remote_read_bytes): - Record size of response to fetch registers command, use this to - limit size of memory read and write commands. - * (push_remote_target): New function to make it possible to have - another target switch to the remote target. - * target.h: Add prototype for push_remote_target. - * sh-tdep.c (sh_frame_find_saved_regs): Fix sign extension bugs - for hosts which default to unsigned chars (such as SGI's). - * (_initialize_sh_tdep): Don't set remote_write_size. It's now - handled automatically in remote.c. - -Thu Apr 3 15:10:30 1997 Michael Snyder - - * blockframe.c: blockvector_for_pc_sect(), block_for_pc_sect(), - find_pc_sect_function(), find_pc_sect_partial_function(): new - functions for debugging overlays; pc without section is ambiguous. - * breakpoint.[ch]: add section pointer to breakpoint struct; - add section argument to check_duplicates(); check section as well - as pc in [breakpoint_here_p(), breakpoint_inserted_here_p(), - breakpoint_thread_match(), bpstat_stop_status()]; - add section argument to describe_other_breakpoints(); - use INIT_SAL() macro to zero-out new sal structures; - make resolve_sal_pc() fix up the sal's section as well as its pc; - match on section + pc in clear_command() and delete_breakpoint(); - account for overlay sections in insert_breakpoints(), - remove_breakpoint() and breakpoint_re_set_one(); - all this to support overlays where a PC is not unique. - * exec.c: change xfer_memory() to handle overlay sections. - * findvar.c: change read_var_value() to handle overlay sections. - * frame.h: declaration for block_for_pc_sect() [blockframe.c]. - * infcmd.c: jump_command() warns against jumping into an overlay - that's not in memory. Also use INIT_SAL() to initialize sals. - * infrun.c: wait_for_inferior() sets a flag to invalidate cached - overlay state information; Also use INIT_SAL() to init sals. - * m32r-rom.c: modify load routines to use LMA instead of VMA. - * m32r-stub.c: mask exit value down to 8 bits; screen out any - memory read/writes in the range 600000 to a00000, and ff680000 - to ff800000 (hangs because nothing is mapped there); fix strcpy(). - * maint.c: maintenance command "translate-address" supports overlays. - * minsyms.c: lookup_minimal_symbol_by_pc_sect() supports overlays. - * objfiles.[ch]: add ovly_mapped field to the obj_section struct; - this constitutes gdb's internal overlay mapping table. Add macro - ALL_OBJSECTIONS() to loop thru the obj_structs and look at overlays. - Add function find_pc_sect_section(). - * printcmd.c: modify print_address_symbolic() with overlay smarts; - modify address_info() with overlay smarts; add function sym_info() - to support the INFO SYMBOL command (translate address to symbol(s)); - modify disassemble_command() to work on unmapped overlays. - * source.c: use INIT_SAL() to initialize sals. - * symfile.[ch]: change generic_load() to use section's LMA address - instead of VMA address, for overlay sections. - Add numerous functions for finding a PC's section / overlay, - translating between VMA and LMA address ranges, determining if an - overlay section is mapped, etc. Add several user commands for - overlay debugging. Add support for a "generic" form of automatically - reading overlay mapping info from the inferior (based on the default - (simple) overlay manager which Cygnus provides as an example). - * symtab.[ch]: add functions find_pc_sect_symtab(), - find_pc_sect_psymtab(), find_pc_sect_psymbol(), find_pc_sect_line() - for lookup; modify lookup_symbol and decode_line_1() to use them; - modify find_function_start_sal() to account for overlay sections; - add macro INIT_SAL() for initializing struct symtab_and_line. - * target.c: fix a comment in the declaration of target_ops. - -Thu Apr 3 10:31:12 1997 Mark Alexander - - * mips-tdep.c (mips_in_call_stub, mips_in_return_stub, - mips_skip_stub, mips_ignore_helper): New functions for dealing - with MIPS16 call/return thunks. - (mips_init_frame_pc_first): New function to implement - INIT_FRAME_PC_FIRST macro; includes code from old macro plus - new code to skip over MIPS16 thunks. - (mips_frame_chain): Skip over MIPS16 thunks. - * config/mips/tm-mips.h (mips_in_call_stub, mips_in_return_stub, - mips_skip_stub, mips_ignore_helper): Declare. - (IN_SOLIB_CALL_TRAMPOLINE, IN_SOLIB_RETURN_TRAMPOLINE, - SKIP_TRAMPOLINE_CODE, IGNORE_HELPER_CALL): New macros that invoke - the above functions. - (INIT_FRAME_PC_FIRST): Change to invoke mips_init_frame_pc. - (mips_init_frame_pc): Declare. - * infrun.c (wait_for_inferior): Use new IGNORE_HELPER_CALL macro - to decide if certain library function calls should be ignored. - -Wed Apr 2 14:16:51 1997 Doug Evans - - * remote-sim.c (gdbsim_open): Check return code from sim_open. - Update call to sim_open (new arg SIM_OPEN_DEBUG). - -Mon Mar 31 14:55:53 1997 Ian Lance Taylor - - * gdbinit.in: New file. - * .gdbinit: Remove. - * configure.in: Generate .gdbinit from gdbinit.in. - * configure: Rebuild. - -Sat Mar 29 13:57:20 1997 Fred Fish - - * COPYING: Install new version of file from FSF. - * copying.c (show_copying_command): Update FSF address. - -Fri Mar 28 18:33:41 1997 Ian Lance Taylor - - * Makefile.in (distclean): Remove .gdbinit. - -Fri Mar 28 15:38:04 1997 Mike Meissner - - * remote-sim.c (gdb_os_{,e}vprintf_filtered): Change stdarg type - to va_list from void *, since va_list might not be a pointer - type. - -Thu Mar 27 14:21:46 1997 Mark Alexander - - * remote-mips.c: Clean up comment and extraneous semicolon - for mips_monitor_prompt variable. - -Thu Mar 27 12:46:58 1997 Mark Alexander - - * remote-mips.c: Add `set monitor-prompt' command. - -Wed Mar 26 06:47:44 1997 Mark Alexander - - Fix from Peter Schauer: - * mdebugread.c (parse_procedure): Set address of procedure to - block start; this fixes problems with shared libraries introduced - by change of Mar 21. - -Mon Mar 24 19:43:16 1997 Geoffrey Noer - - * symtab.c (find_pc_symtab): change to support the case - where the objfile is reordered and contains both coff and - stabs debugging info (continue on if a psymtab isn't found). - -Sun Mar 23 16:19:20 1997 Mark Alexander - - Fixes from Peter Schauer: - * config/mips/tm-mips.h (REGISTER_CONVERT_TO_TYPE, - REGISTER_CONVERT_FROM_TYPE): Swap words if target, not host, - is big-endian and if registers are 32 bits. - * mips-tdep.c (mips_print_register, mips_extract_return_value, - mips_store_return_value): Fix floating-point word-order problems on - little-endian targets introduced by changes of Mar 21. - -Sun Mar 23 15:43:27 1997 Stan Shebs - - * remote.c (target_resume_hook, target_wait_loop_hook): New - globals. - (remote_resume, remote_wait): Use them. - * d10v-tdep.c: Set the above hooks. - (tracesource): New GDB variable, controls source display in - traces. - (display_trace): Find and display source line if requested. - (trace_info): Mention empty trace buffer if appropriate. - (tdisassemble_command): Robustify argument handling. - - * configure.host: Remove extra bogus Linux case. - -Sat Mar 22 16:41:35 1997 Fred Fish - - * remote-sim.c (simulator_command): Add comment about dealing with - NULL or empty args. - -Sat Mar 22 02:48:11 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * c-exp.y (yylex): Handle nested template parameter lists. - * symtab.c (decode_line_2): Fix test for valid choice number. - -Fri Mar 21 19:10:05 1997 Mark Alexander - - * mips-tdep.c (mips_push_arguments): On non-EABI architectures, - copy first two floating point arguments to general registers, so that - MIPS16 functions will receive the arguments correctly. - (mips_print_register): Print double registers correctly on - little-endian hosts. - (mips_extract_return_value): Return double values correctly - on little-endian hosts. - - * mdebugread.c (parse_procedure): Adjust address of procedure relative - to address in file descriptor record; this accounts for constant - strings that may precede functions in the text section. Remove - now-useless lowest_pdr_addr from argument list and all calls. - -Fri Mar 21 15:36:25 1997 Michael Meissner - - * configure.tgt (powerpc*-{eabi,linux,sysv,elf}*): Determine - whether the simulator will be built by whether the Makefile in the - simulator directory was built. - - * configure.in (--enable-sim-powerpc): Delete switch. - * configure: Regenerate. - -Thu Mar 20 20:52:04 1997 Jeffrey A Law (law@cygnus.com) - - * mn10200-tdep.c (mn10200_analyze_prologue): Look for save of "a1" - in the prologue too. - - * remote-sim.c (gdb_os_vprintf_filtered): Fix to work with non-ANSI - compilers. - (gdb_os_evprintf_filtered): Similarly. - -Wed Mar 19 16:13:22 1997 Geoffrey Noer - - New UnixWare 2.1 configuration - * config/i386/i386v42mp.mt: new - * config/i386/i386v42mp.mh: new - * config/i386/tm-i386v42mp.h: new - * config/i386/nm-i386v42mp.h: new - * configure.tgt: added new entries - * configure.host: added new entries - -Mon Mar 17 17:52:00 1997 J.T. Conklin - - * dsrec.c (load_srec): Print leading zeroes when printing section - addresses. - -Mon Mar 17 15:00:16 1997 Andrew Cagney - - * remote-sim.h: Delete - moved to ../include/remote-sim.h. - - * Makefile.in (remote_utils_h): Update path to remote-sim.h. - -Fri Mar 7 20:55:28 1997 Andrew Cagney - - * remote-sim.c (flush_stdout, write_stderr, flush_stderr, - vprintf_filtered, evprintf_filtered): Callbacks that accept - varargs. - -Sat Mar 15 00:50:46 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * breakpoint.c (insert_breakpoints, watchpoint_check, - bpstat_stop_status): Do not disable watchpoints going out of scope. - (insert_breakpoints): Make sure that the current frame is valid - before calling find_frame_addr_in_frame_chain. - - * top.c (setup_user_args): Handle quotes and backslashes. - (print_gdb_version): Update copyright year. - -Fri Mar 14 15:44:03 1997 Ian Lance Taylor - - * Makefile.in (elfread.o): Depend upon elf-bfd.h and elf/mips.h. - -Thu Mar 13 22:51:00 1997 Dawn Perchik - - * utils.c (pollquit, notice_quit): If _WIN32, limit test for - cntl-C to wingdb. - (initialize_utils): If _WIN32, don't call ScreenRows and ScreenCols - except under wingdb. (Contributed by Martin Hunt). - -Thu Mar 13 12:40:49 1997 Tom Tromey - - * configure: Regenerated. - * configure.in: Run AC_CONFIG_AUX_DIR before AC_CANONICAL_SYSTEM. - -Thu Mar 13 11:00:22 1997 Doug Evans - - * remote-sim.h (sim_state, SIM_DESC): New types. - (sim_open): Return a `descriptor' as result. - (*): New argument of descriptor result from sim_open. - * remote-sim.c (gdbsim_desc): Renamed from gdbsim_open_p. - (gdbsim_open): Record result of sim_open in gdbsim_desc. - Pass argv list to sim_open, argv[0] = pseudo program name. - (*): Pass gdbsim_desc to sim_foo fns. - -Wed Mar 12 14:40:06 1997 Tom Tromey - - * config.in: Regenerated. - - * acconfig.h (START_INFERIOR_TRAPS_EXPECTED, sys_quotactl, - HAVE_HPUX_THREAD_SUPPORT): Define. - -Tue Mar 11 07:25:27 1997 Mark Alexander - - First cut at supporting simulators in gdbserver: - - * configure, configure.in: Allow gdbserver to be configured - for cross-target environments. - * gdbserver/Makefile.in: Add simulator support. - * gdbserver/configure.in: Eliminate assumption that host == target. - Simplify using gdb/configure.tgt and gdb/configure.host. - Fix other minor configuration errors. - * gdbserver/low-sparc.c: Fix compile error. - * gdbserver/remote-utils.c: Eliminate assumption that registers - and addresses are four bytes. Fix minor compile errors and warnings. - * gdbserver/server.c: Rewrite numerous instances of identical code - for starting inferior processes to call new function start_inferior. - Eliminate assumption that registers and addresses are four bytes. - * gdbserver/server.h: Add missing prototypes to eliminate compiler - warnings. - * gdbserver/low-sim.c: New file to mate gdbserver with simulators. - * config/mips/vr5000.mt: Add Vr5000 simulator support to gdbserver. - * config/i386/linux.mh: Eliminate gdbserver support as a first step - in moving such support from host to target makefile fragments. - * config/i386/linux.mt: Move gdbserver support here from linux.mh. - -Mon Mar 10 12:27:47 1997 Michael Snyder - - * symtab.h (INIT_SAL): New macro to initialize symtab_and_line, - to insure consistant initialization of unused fields to zero. - * symtab.c: replace initializations of sals with new macro INIT_SAL. - * breakpoint.c: ditto. - * infrun.c: ditto. - * infcmd.c: ditto. - * source.c: add call to INIT_SAL macro. - -Sat Mar 8 00:16:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * sparc-tdep.c (isbranch): Always handle v9 branch instructions, - they might get used on 32 bit targets as well. - -Wed Mar 5 19:34:09 1997 Bob Manson - - * remote-mips.c (mips_exit_debug): Some IDT boards don't - send the full exit string. - -Wed Mar 5 12:59:27 1997 Jeffrey A Law (law@cygnus.com) - - * mn10200-tdep.c (mn10200_push_arguments): Handle new calling - conventions. - (mn10200_store_struct_return): Likewise. - -Tue Mar 4 10:31:02 1997 Mark Alexander - - * mips-tdep.c (mips_fetch_instruction): New function; replace - common code throughout with calls to it. - (mips_find_saved_regs): Examine MIPS16 entry instruction to determine - correct saved addresses of $s0 and $s1. - (mips_find_saved_regs, mips16_heuristic_proc_desc): Use MIPS_REGSIZE - instead of hardcoded 4. - (mips16_skip_prologue): Handle extended instructions correctly. - -Mon Mar 3 12:29:20 1997 Doug Evans - - * defs.h (LONGEST): Move #ifndef LONGEST to outside. - Try BFD_HOST_64_BIT if ! CC_HAS_LONG_LONG. - -Thu Feb 27 18:54:11 1997 Mark Alexander - - * mips-tdep.c (IS_MIPS16_ADDR, MAKE_MIPS16_ADDR, UNMAKE_MIPS16_ADDR): - New macros for testing, setting, and clearing bit 0 of addresses. - Change numerous bits of code where bit 0 was being manipulated - to use these macros. - -Thu Feb 27 14:12:41 1997 Mark Alexander - - * remote-mips.c: Put back the form feeds. - -Thu Feb 27 12:04:24 1997 Mark Alexander - - * remote-mips.c: Remove form feeds (^L) from source. - (mips_initialize): LSI PMON doesn't support 'set regsize' command. - (pmon_wait): Don't need to exit and re-enter debug mode on LSI - PMON after a continue; it causes target program misbehavior. - (mips_fetch_register): Don't fetch unsupported registers; this - cuts down on wasted serial traffic. - -Thu Feb 27 09:38:16 1997 Stu Grossman (grossman@critters.cygnus.com) - - * configure.in configure (HPUX/OSF thread support): Enable this - only when running GCC, since HP's thread header files use ANSI C - which is not supported by their default compiler. - - * configure.host (i[3456]86-*-windows): Disable long long - support for WinGDB. Add mswin to configdirs. - * configure.in configure: Move calls to configure.host and - configure.tgt to the top of configure.in to allow them to set - config variables before they are referenced. - -Tue Feb 25 20:21:52 1997 Stan Shebs - - * configure.tgt (mips*-*-lnews*): New target. - -Mon Feb 24 16:35:00 1997 Jeffrey A Law (law@cygnus.com) - - * mn10200-tdep.c (mn10200_analyze_prologue): Don't fix fi->frame - if we're not the innermost frame. Fix minor typos. - -Sat Feb 22 03:39:50 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * stabsread.c (read_type): Fix handling of template names - with template parameters containing `::'. - - * valops.c (search_struct_field, search_struct_method): - Pass correct valaddr parameter to baseclass_offset. - Prevent gdb crashes by making sure that the virtual base pointer - from an user object still points to accessible memory. - -Tue Feb 18 13:36:34 1997 Mark Alexander - - * maint.c: Eliminate -Wall warnings by including some header files. - -Tue Feb 18 13:06:30 1997 Mark Alexander - - * remote-sim.c (init_callbacks): Undo previous change. - -Tue Feb 18 11:13:00 1997 Dawn Perchik - - * maint.c: Fix dereference of pointer. - * remote-sim.c: Fix reference of structure member "last_error". - * debugify.c: Include config.h to get ANSI definitions. - -Sat Feb 15 17:43:46 1997 Stu Grossman (grossman@critters.cygnus.com) - - * remote-vx.c (vx_attach): Remove code added by kung. It made no - sense. - -Fri Feb 14 13:00:07 1997 Ian Lance Taylor - - * main.c (print_gdb_help): Make static to match declaration. - -Thu Feb 13 18:18:18 1997 Dawn Perchik - - * remote-e7000.c, ser-e7kpc.c, serial.c: Remove // comments. - -Wed Feb 12 15:58:00 1997 Dawn Perchik - - * debugify.c, debugify.h: Make safe for non-ansi compilers. - -Wed Feb 12 15:30:00 1997 Dawn Perchik - - * defs.h: Fix prototypes for new cleanup functions. - -Wed Feb 12 15:08:47 1997 Dawn Perchik - - * debugify.c, debugify.h: Fix for general gnu use. Remove C++ - comment, add PARAMS, add license info and fix indentation. - -Wed Feb 12 14:42:47 1997 Dawn Perchik - - * debugify.c, debugify.h: New files. Provide common macros - for writing debug info to a log file or stdio. - -Wed Feb 12 02:44:39 1997 Dawn Perchik - - * c-valprint.c (c_val_print): Fix printing for arrays defined - with 0 length. - -Tue Feb 11 22:24:39 1997 Dawn Perchik - - * defs.h: Fix cntl-C to read from the Windows message queue. - Add prototypes for make_final_cleanup (and the other cleanup - routines. - * remote-e7000.c: Fix sync code to timeout if unable to sync. - Change sync code to report status while trying to sync-up - with hardware. Add debugging output and document. - * ser-e7kpc.c: Swap order of len & offset to match implementation. - Add debugging output and document. - * serial.c: Add debugging output. - * top.c: Add call to do_final_cleanups. - Remove conditionals preventing Win32 from getting SIGQUIT. - * utils.c: (*_cleanup): Modify cleanup routines to accept a cleanup - chain as a parameter. Extract this generic code from the cleanup - routines into separate funtions (*_my_cleanup). Keep old - functionality by passing "cleanup_chain" to the new funtions. - Define the cleanup chain "final_cleanup_chain" to be a cleanup - chain which will be executed only when gdb exits. Add functions - (*_final_cleanup) to match the original (*_cleanup) functions. - (pollquit, quit, notice_quit): Fix to read cntl-C from the - Windows message queue. - -Tue Feb 11 15:36:31 1997 Doug Evans - - * m32r-rom.c: #include . - #ifdef out new load support if wingdb. - * m32r/tm-m32r.h (TARGET_M32R): Define, for wingdb. - -Tue Feb 11 12:28:09 1997 Jeffrey A Law (law@cygnus.com) - - - * config/mn10200/tm-mn10200.h (STORE_STRUCT_RETURN): Fix. - * mn10200-tdep.c (mn10200_store_struct_return): New function. - - * config/mn10200/tm-mn10200.h (EXTRACT_RETURN_VALUE): Fix case when - extracting a return value from a register pair. - - * mn10200-tdep.c (mn10200_push_arguments): Stack only needs to - be two byte aligned. Round argument sizes up to two byte boundary. - Write out args in two byte hunks. - (mn10200_push_return_address): Implement. - * config/mn10200/tm-mn10200.h (EXTRACT_RETURN_VALUE): Abort for - structures > 8 bytes (temporary). - (STORE_RETURN_VALUE): Likewise. - (CALL_DUMMY): No longer undefine. - (USE_STRUCT_CONVENTION): Use for args > 8 bytes. - (REG_STRUCT_HAS_ADDR): Define. - -Mon Feb 10 18:35:55 1997 Mark Alexander - - * mips-tdep.c (non_heuristic_proc_desc): New function. - (find_proc_desc): Move non-heuristic proc search code into separate - function. - (gdb_print_insn_mips): Use non-heuristic method to find procedure - descriptor, to avoid prologue examination when disassembling. - * remote-mips.c: Add support for new "lsi" target (LSI MiniRISC - aka MicroMeteor board). - (mips_exit_debug): Prevent protocol reinitialization if an error - occurs while exiting debug mode. - -Mon Feb 10 16:11:57 1997 Jeffrey A Law (law@cygnus.com) - - * mn10200-tdep.c: Remove lots of debugging printfs, update/improve - comments, formatting, etc. Plus other minor fixes for problems - I found during my first pass over the mn10200 port. - (mn10200_analyze_prologue): New function. - (mn10200_frame_chain, mn10200_init_extra_frame_info): Use it. - * config/mn10200/tm-mn10200.h: Lots of updates/improvements to - comments, formatting, etc. Minor fixes for problems I found during - my first pass over the mn10200 port. - (TARGET_*_BIT): Define appropriately for ints, long longs, doubles and - pointers. - (REGISTER_VIRTUAL_TYPE): Define as a long. - (EXTRACT_RETURN_VALUE): Rework to deal with long ints living - in register pairs. - (STORE_RETURN_VALUE): Similarly. - - * blockframe.c (generic_get_saved_regs): Remove unused variable - "addr". - * breakpoint.c (frame_in_dummy): Move struct breakpoint *b decl - inside #ifdef CALL_DUMMY. - (watch_command_1): Initialize target_resources_ok. - * command.c (do_setshow_command): Provide dummy initialization - for "match". - * valops.c (find_function_addr): Move function & prototype inside - #ifdef CALL_DUMMY. - (value_arg_coerce): Similarly. - (value_of_variable): Provide dummy initialization of "frame". - -Mon Feb 10 07:54:26 1997 Fred Fish - - * xcoffread.c (RECORD_MINIMAL_SYMBOL): Add NULL asection* parameter - to prim_record_minimal_symbol_and_info call that was missed in Jan 3 - change. - (scan_xcoff_symtab): Ditto. - -Sun Feb 09 09:23:26 1997 Mark Alexander - - * remote-mips.c (common_breakpoint): Prevent 64-bit addresses - from being sent to 32-bit targets by masking off upper bits. - * mips-tdep.c (heuristic_proc_start): Mask off upper 32 bits - of PC on 32-bit targets. - (mips16_heuristic_proc_desc): Recognize 'addiu s1,sp,n' as a - frame setup instruction. - (mips32_heuristic_proc_desc): Fix warning found by gcc -Wall. - (mips16_skip_prologue): Recognize 'addiu s1,sp,n' as a valid - prologue instruction. Fix warnings and bugs found by gcc -Wall. - * buildsym.c (finish_block): Improve handling of overlapping blocks; - fixes problem on MIPS16 printing function arguments. - -Sat Feb 8 01:14:43 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dwarf2read.c (dwarf2_linkage_name): New function to get - the linkage name of a die from DW_AT_MIPS_linkage_name or - DW_AT_name. - (read_func_scope, dwarf2_add_field, dwarf2_add_member_fn, - new_symbol): Use it instead of accessing DW_AT_name. - (read_partial_die): Use DW_AT_MIPS_linkage name as name of the - partial die if present. - (dwarf2_add_member_fn): Make a copy of physname on the type obstack. - -Fri Feb 7 10:06:22 1997 Jeffrey A Law (law@cygnus.com) - - * blockframe.c (generic_frame_chain_valid): If the new frame - is not INNER_THAN the old frame, then it's not valid. - -Tue Feb 04 09:04:37 1997 Mark Alexander - - * mips-tdep.c (mips16_get_imm): Fix calculation of extended immediate. - (mips16_heuristic_proc_desc): Recognize jal(x) instruction. - -Mon Feb 03 17:57:58 1997 Mark Alexander - - * mips-tdep.c (mips16_decode_reg_save): Distinguish between - sd and sw instructions correctly. - (heuristic_proc_start): Add support for MIPS16. - (mips16_get_imm, mips16_heuristic_proc_desc, - mips32_heuristic_proc_desc): New helper functions for - heuristic_proc_desc. - (heuristic_proc_desc): Rewrite and reorganize to support MIPS16. - (mips_push_arguments): Don't align small arguments in EABI. - (mips32_skip_prologue): Attempt to shrink code size a little. - -Mon Feb 3 11:06:05 1997 Michael Snyder - - * m32r-stub.c: New -- remote protocol support for M32R cpu. - * m32r-rom.c: Several experiments with improved download time. - -Fri Jan 31 08:26:39 1997 Mark Alexander - - * mips-tdep.c (MIPS16_INSTLEN): Define. - (mips_find_saved_regs): Replace hardcoded 2's with MIPS16_INSTLEN. - (heuristic_proc_start): Recognize 'entry' pseudo-op as a start - of function on MIPS16. - (mips32_skip_prologue, mips16_skip_prologue): New helper functions - for mips_skip_prologue. - (mips_skip_prologue): Recognize both 16- and 32-bit prologues. - -Wed Jan 29 12:45:54 1997 Michael Meissner - - * config/powerpc/ppc{,le}-sim.mt (SIM): Remove the library - ../sim/common/libcommon.a. - -Tue Jan 28 15:54:13 1997 Michael Snyder - - * blockframe.c: fix a null pointer ref in generic_get_saved_register - -Tue Jan 28 15:39:50 1997 Geoffrey Noer - - * mn10200-tdep.c (mn10200_frame_chain): Get basic backtracing - working. - -Mon Jan 27 14:31:52 1997 Mark Alexander - -First set of changes for mips16: - * config/mips/tm-mips.h (MIPS16_BIG_BREAKPOINT, - MIPS16_LITTLE_BREAKPOINT, BREAKPOINT_FROM_PC): Define. - (ABOUT_TO_RETURN): Call new function mips_about_to_return. - (mips_breakpoint_from_pc, mips_about_to_return): Declare. - * mem-break.c (memory_breakpoint_from_pc): New function. - (memory_insert_breakpoint, memory_remove_breakpoint): Use - memory_breakpoint_from_pc to determine breakpoint contents and size. - * target.h (memory_breakpoint_from_pc): Declare. - * monitor.c (monitor_insert_breakpoint): Use memory_breakpoint_from_pc - to determine size of breakpoint instruction. - * mips-tdep.c (mips32_decode_reg_save, mips16_decode_reg_save): - New helper functions for mips_find_saved_regs. - (mips_find_saved_regs): Recognize mips16 prologues. - (mips_addr_bits_remove): Strip off upper 32 bits of address - when target CPU is 32 bits but CORE_ADDR is 64 bits. - (mips_step_skips_delay): No branch delay slot on mips16. - (gdb_print_insn_mips): Disassemble mips16 code. - (mips_breakpoint_from_pc, mips_about_to_return): New functions. - -Mon Jan 27 10:34:03 1997 Jeffrey A Law (law@cygnus.com) - - * tm-mn10200.h (NUM_REGS): Decrease to 12. - (REGISTER_NAMES): Elimination registers not found on the mn10200. - (PC_REGNUM, MDR_REGNUM, PSW_REGNUM): Corresponding changes. - (LIR_REGNUM, LAR_REGNUM): Delete. They don't exist on the mn10200. - -Sat Jan 25 00:07:59 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dwarf2read.c: Replace integral tag, name and form fields in - internal structure definitions with the corresponding enumeration - types from dwarf2.h. Add default cases to switches on enumerations - where appropriate. - Make quoting of string arguments in complaint messages consistent. - Check for NULL returns from DW_STRING. - (struct partial_die_info): Add sibling and has_type fields, remove - unused value field. - (DW_*): Move access macro definitions near the definition of the - attribute structure. - (struct field_info): New structure to pass information about fields - and member functions between die processing routines. - (dwarf2_build_psymtabs_hard): Set cu_header_offset. - (scan_partial_symbols): Do not enter DW_TAG_subprogram dies into - the partial symbol table if the DW_AT_*_pc attributes are missing. - Add file scope base type definitions to the partial symbol table. - Skip over child dies if the die has a sibling attribute. - (add_partial_symbol): Enter global variables with type attributes - and without location descriptors into the partial symbol table. - Store value of DW_TAG_variable dies in the partial symbol table. - Do not enter global variables into the minimal symbol table. - Add base type definitions to the partial symbol table. - (psymtab_to_symtab_1): Use dwarf2_get_pc_bounds to determine highpc. - (process_die): Move check for DW_AT_low_pc to read_func_scope. - Add a typedef symbol for base type definitions to the symbol table. - Ignore DW_TAG_inlined_subroutine tags for now. - (read_file_scope): Use dwarf2_get_pc_bounds to determine pc bounds. - (read_func_scope, read_lexical_block_scope): Use dwarf2_get_pc_bounds - to determine pc bounds, ignore dies with invalid bounds. - (dwarf2_get_pc_bounds): New routine to extract and validate the - DW_AT_*_pc attributes of a die. - (dwarf2_add_field, dwarf2_attach_fields_to_type, skip_member_fn_name, - dwarf2_add_member_fn, dwarf2_attach_fn_fields_to_type): - New functions to handle fields and member functions. - (read_structure_scope): Rewritten to use them. - (read_array_type): Renamed from dwarf_read_array_type. - Default upper array bound to describe an array with unspecified - length. - Create array types in backwards order, as dwarf2 puts out the array - dimensions from left to right. - (read_subroutine_type): Handle DW_TAG_unspecified_parameters, - DW_AT_artificial and DW_AT_prototyped. - (read_base_type): Make an unsigned type for DW_ATE_boolean. - Pass objfile to dwarf_base_type. - (read_partial_die): Use read_attribute to read in the attributes. - Handle DW_AT_sibling and DW_AT_type. - Follow references when determining DW_AT_name and DW_AT_external - attributes of the die. - Validate DW_AT_*_pc attributes. - (read_full_die): Use read_attribute to read in the attributes. - (read_attribute): New function to read an attribute described - by an abbreviated attribute. - (new_symbol): Relocate symbol value for DW_TAG_label with baseaddr. - Do not set SYMBOL_VALUE_ADDRESS for DW_TAG_subprogram, - SYMBOL_BLOCK_VALUE for the symbol will be set later by finish_block. - Change symbol class for global variables with a zero valued location - descriptor to LOC_UNRESOLVED. - Handle DW_AT_const_value attributes for DW_TAG_variable, - DW_TAG_formal_parameter and DW_TAG_enumerator. - Build a typedef symbol for DW_TAG_base_type. - (dwarf2_const_value): New routine to copy a constant value from an - attribute to a symbol. - (dwarf_base_type): Use passed in objfile, not current_objfile - when calling dwarf2_fundamental_type. - (dump_die): Use DW_* accessor macros to access values of attributes. - (decode_locdesc): Handle DW_OP_plus_uconst. - -Wed Jan 22 01:31:16 1997 Geoffrey Noer - - * mn10200-tdep.c: New file. - * config/mn10200/tm-mn10200.h: New, REGISTER_SIZE is 24 bits not 32, - SP_REGNUM and FP_REGNUM are different, also no lar or lir. - * config/mn10200/mn10200.mt: New file. - * configure.tgt: add mn10200 entry. - -Tue Jan 21 18:32:23 1997 Stu Grossman (grossman@lisa.cygnus.com) - - * configure.in configure: Check if host has libdl if doing - Solaris threads. - -Tue Jan 21 17:03:26 1997 Geoffrey Noer - - * mn10300-tdep.c: Wrote/fixed implementations of - mn10300_frame_chain, mn10300_init_extra_frame_info, - mn10300_frame_saved_pc - * config/mn10300/tm-mn10300.h: Redefine INIT_EXTRA_FRAME_INFO - and INIT_FRAME_PC macros. - -Tue Jan 21 17:01:20 1997 Stu Grossman (grossman@lisa.cygnus.com) - - * configure.in configure: Check if host has libm. Make sure we - are using gcc when using the -export-dynamic option. Fixes a - problem with building under Solaris/SunPro cc. - -Mon Jan 20 13:52:13 1997 Mark Alexander - - * config/mips/{embed,embed64,embedl,embedl64}.mt: - Link in simulator on MIPS embedded targets. - -Sat Jan 18 02:31:29 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * blockframe.c (frameless_look_for_prologue): Mark frames - with a zero PC as frameless to improve backtraces from core dumps - caused by dereferencing a NULL function pointer. - -Thu Jan 16 14:10:41 1997 Geoffrey Noer - - * config/mn10300/tm-mn10300.h: fix BREAKPOINT definition. - -Tue Jan 14 16:01:06 1997 Geoffrey Noer - - * mn10300-tdep.c: made a lot more generic, ripping out code - from copied target (no more mn10300_scan_prologue, - init_extra_frame_info, and mn10300_fix_call_dummy calls) - * config/mn10300/tm-mn10300.h: undefine INIT_EXTRA_FRAME_INFO - and INIT_FRAME_PC macros - -Thu Jan 9 11:44:40 1997 Michael Snyder - - * sparc-tdep.c (sparc_frame_find_saved_regs): Don't use - FP_REGISTER_BYTES to compute offsets into the saved frame, - since it fails for SPARC targets configured without any - FP regs. Instead, use DUMMY_STACK_REG_BUF_SIZE. - -Mon Jan 6 11:15:14 1997 Stu Grossman (grossman@critters.cygnus.com) - - * symtab.c (fixup_symbol_section): Handle NULL symbols without - crashing. - -Fri Jan 3 12:08:16 1997 Stu Grossman (grossman@critters.cygnus.com) - - * Makefile.in configure configure.in: Remove ENABLE_CLIBS, - ENABLE_OBS, and THREAD_DB_OBS. These are consolidated into LIBS - and CONFIG_OBS. - * configure configure.in: Clean up test cases around thread support. - * configure.tgt (v850-*-*): Include v850ice.o and v850.lib if - host is Windows. - * c-valprint.c ch-valprint.c cp-valprint.c eval.c expprint.c - printcmd.c valops.c value.h values.c: Add bfd_section arg to - value_at and value_at_lazy. - * coffread.c dbxread.c elfread.c mdebugread.c minsyms.c symtab.h: - Add bfd_section arg to prim_record_minimal_symbol_and_info. - * corefile.c gdbcore.h printcmd.c valops.c: Use read_memory_section - instead of read_memory. It takes a bfd_section arg. - * coffread.c dbxread.c elfread.c gdb-stabs.h objfiles.h: Remove - unnecessary cast for assignment of struct dbx_symfile_info. - Struct objfile now uses a real pointer instead of PTR for this - element. - * dbxread.c (dbx_symfile_init): Stash bfd section pointers for - text, data and bss into dbx_symfile_info. - * exec.c (xfer_memory): Handle transfers for user-specified - sections. - * findvar.c (read_var_value locate_var_value): Copy bfd section - from the symbol to the value. - * gdb-stabs.h: Add section pointers for text, data and bss - sections. - * maint.c (translate address command): Add test code for overlay - address translation. - * printcmd.c (do_examine do_one_display): Now takes a bfd section - arg. - * (print_formatted x_command): Record current section along with - current address for repeated commands. - * sparc-nat.c (fetch_inferior_registers): Change - target_xfer_memory to target_{read write}_memory to allow changes - to target_xfer_memory interface for section info. - * symmisc.c (dump_msymbols print_symbol): Print section - assocaited with symbol. - * symtab.c (fixup_symbol_section): New routine to - add section info to symbols returned by lookup_symbol. - * symtab.h (struct general_symbol_info): Add bfd section to - symbols. - * target.c target.h (target_xfer_memory): Add bfd section to - args. - * (target_read_memory_section): New routine to read data from a - specific section. - * (target_memory_bfd_section): New global variable to pass bfd - section in to targets. - * valarith.c (value_add value_addr value_array): Preserve bfd - section when computing new value. - * value.h (struct value): Add bfd section to values. - * values.c (allocate_value value_copy): Initialize/preserve bfd - section. - * (unpack_double): Clean up _MSC_VER conditionals to remove - duplicate code. - * v850ice.c: New module to support communication with NEC's - PC-based ICE. - * config/v850/tm-v850.h (REGISTER_NAMES): Replace sp, gp, fp, and - ep names with rxx names. sp and fp are renamed via a different - mechanism. - -Fri Jan 3 14:20:05 1997 Geoffrey Noer - - * mn10300-tdep.c (mn10300_push_arguments): rewrote, - also removed code elsewhere that made use of RP_REGNUM. - * config/mn10300/tm-mn10300.h: ripped out RP_REGNUM, V0_REGNUM, - ARG0_REGNUM, ARGLAST_REGNUM (all not appropriate for mn10300 - arch.), redefined SAVED_PC_AFTER_CALL, EXTRACT_RETURN_VALUE, - EXTRACT_STRUCT_VALUE_ADDRESS, STORE_RETURN_VALUE. - -For older changes see ChangeLog-96 - -Local Variables: -mode: indented-text -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/contrib/gdb/gdb/ChangeLog-98 b/contrib/gdb/gdb/ChangeLog-98 deleted file mode 100644 index bd19b49066a..00000000000 --- a/contrib/gdb/gdb/ChangeLog-98 +++ /dev/null @@ -1,7122 +0,0 @@ -Thu Dec 31 15:26:13 1998 Stan Shebs - - * corelow.c (core_ops): Don't initialize statically. - (init_core_ops): New function, fills in core_ops. - (_initialize_corelow): Use it. - -Thu Dec 31 16:54:30 1998 David Taylor - - The following changes were made by - Elena Zannoni - Edith Epstein - David Taylor - - * config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Change to read - nullify instruction bit from IPSW only when we are not in a system - call. - (STRCAT_REGISTER, pa_do_strcat_registers_info): Additional - parameter -- precision. - - * Makefile.in (BUILD_TUI): To build the tui, only when configured - with --enable-tui. - (YLWRAP): Use ylwrap to avoid problems on systems w/o bison. - (gdb$(EXEEXT)): Make it dependent on BUILD_TUI. - (all-tui): Remove dependency from phony target. - (c-exp.tab.c): Use ylwrap instead of bison. - (jv-exp.tab.c): Ditto. - (f-exp.tab.c): Ditto. - (m2-exp.tab.c): Ditto. - - * configure.in (ENABLE_CFLAGS): Define and export BUILD_TUI. - - * configure: Regenerated. - - * c-typeprint.c (c_type_print_base): Get to the method name by - skipping over all the namespaces, classes and '::'. - - * infcmd.c (run_command): Only call SOLIB_RESTART if it's - defined. - (detach_command): Ditto. - - * infptrace.c (call_ptrace): Add some debugging code. - - * infrun.c (follow_inferior_fork): Only define on HP. - (wait_for_inferior): Only call SOLIB_IN_DYNAMIC_LINKER if we have - shared libraries; restore test of IN_SOLIB_DYNSYM_RESOLVE_CODE - removed by HP. - - * Makefile.in (ALLDEPFILES): Add somread.c, hp-psymtab-read.c, - hp-symtab-read.c. - (SFILES): Remove the above files - (COMMON_OBS): Remove somread.o - (SFILES): Add the tui files to this, so they get - included in etags tables. - (all-tui): New rule, which does a recursive make in the tui - subdir. - (gdb$(EXEEXT)): Add tui-all to the list of - dependencies, and add tui/libtui.a to the link list. - (tui/libtui.a): When recursing, pass down - ${FLAGS_TO_PASS}. And don't echo the make command. This is - closer to what the other recursions do. - (HFILES_NO_SRCDIR) add hpread.h. - (COMMON_OBS): Add hp-psymtab-read.o, hp-symtab-read.o - Allow the TUI code to be conditionally enabled. - (TUI_TARGET, TUI_LIBRARY): New variables, whose values are set by - the configuration script. They're set to the empty string when - the TUI isn't enabled. - (gdb$(GDBEXT)): Use those, instead of referring to tui-all and - tui/libtui.a directly. - - * Makefile.in: Avoid spurious relinking. - (gdb$(EXEEXT)): Depend on the actual tui library, not on a - fictitious target. Since the fictitious target never existed, make - would always relink. - (tui/libtui.a): Renamed from all-tui. Always recurse to make sure - the library is up to date. - (TUI_TARGET): Variable removed; there's no need for it any more. - - * Makefile.in: Look for tui include files in the tui source dir. - - * Use automake's `aclocal' program to generate aclocal.m4, to allow - us to use automake macros in configure.in with impunity. - - * acconfig.h: Add an entry for the `TUI' symbol. - - * acinclude.m4: New file, containing the code from the old - aclocal.m4. Incorporate (by reference) ../bfd/acinclude.m4, not - ../bfd/aclocal.m4, since we only want bfd's local macros. - - * aclocal.m4: Now automagically generated. Just run aclocal! - - * annotate.c (annotate_catchpoint): New function. - - * annotate.h: Taking the new includes (symtab.h and gdbtypes.h). - not taking the ansic C build fix. - (annotate_catchpoint): Declare. - - * blockframe.c (blockvector_for_pc_sect): Check that the end of - the block is >= to the pc, not just >. - - * breakpoint.c (create_temp_exception_breakpoint): #If it out -- - nothing calls it. - (bpstat_stop_status): Don't call SOLIB_HAVE_LOAD_EVENT if it's not - defined; don't call SOLIB_HAVE_UNLOAD_EVENT if it's not defined. - (bpstat_get_triggered_catchpoints): If we don't have shared - library support, then don't call SOLIB_LOADED_LIBRARY_PATHNAME nor - SOLIB_UNLOADED_LIBRARY_PATHNAME. - (watch_command_1): Don't require a run before a watch command - unless we're on HP [it's an HP OS bug, not a generic limitation] - (catch_load_command_1): Don't define if no shared libraries. - (catch_command_1): Don't claim to support fork catchpoints unless - CHILD_INSERT_FORK_CATCHPOINT is defined, don't claim to support - vfork catchpoints unless CHILD_INSERT_VFORK_CATCHPOINT is defined, - don't clain to support shared library load catchpoints if shared - libraries aren't supported, and don't claim to support exec - catchpoints unless CHILD_INSERT_EXEC_CATCHPOINT is defined - - (bpstat_do_actions): If we just set cmd to NULL, don't then try to - set it to cmd->next as we'll SEGV. - (bpstat_do_actions): Simplify significantly. It's - now almost as simple as before the merge and it no longer has the - HP bug that breakpoint commands are executed repeatedly. - - (break_at_finish_command_1): Rewrite and make sure - selected_frame points to a frame before using it. Fix string - termination error. - (break_at_finish_at_depth_command_1): Ditto. - - (can_use_hw_watchpoints): New static variable. - (read_memory_nobpt): Test for breakpoint type bp_none. - (insert_breakpoints): Test for breakpoint type bp_catch_exec; - insure have a current frame before getting the frame address. - (remove_breakpoints): Check for breakpoints of types bp_none, - bp_catch_fork, bp_catch_vfork, and bp_catch_exec. - (bpstat_stop_status): Fix updates of b->hit_count. - (bpstat_have_active_hw_watchpoints): New function. - (create_exec_event_watchpoint): New function. - (watch_command_1): Use can_use_hw_watchpoints. - (catch_fork_command_1): Change name of function to call from - target_create_catch_(v)fork_hook to create_(v)fork_even_catchpoint. - (delete_breakpoint): Test for already deleted breakpoints; add - support for bp_catch_fork, bp_catch_vfork, and bp_catch_exec - breakpoints. - (_initialize_breakpoint): Add can-use-hw-watchpoints to list of - user settable debugger variables. - - (clear_command): When there is no argument - to the clear command, delete all breakpoints that are hit at - default line. This will include a breakpoint whose line number - does not correspond to the default line, but has been set at - the default address. - - (delete_breakpoint): Don't call bpstat_clear_actions, instead - clear things explicitly; if clearing breakpoint_at, then also - clear any associated actions so that bpstat_do_actions won't try - to execute them. - (_initialize_breakpoint): Fix function name for bx command. - - (tbreak_command): Remove static from declaration. - (maintenance_info_breakpoints): Ditto. - - (reattach_breakpoints): New funct definition, used with with - hardware watchpoints - (breakpoint_1): Change format and add entries to bptypes[] - (maintenance_info_breakpoints): Function is no longer static - - (_initialize_breakpoint): Removed a comment. - (exception_catchpoints_are_fragile, - exception_support_initialized): Define. - (breakpoint_here_p): Fixed syntax error in conditional - (disable_watchpoints_before_interactive_call_start): Fixed call to - check_duplicates. Need a section parameter. - (enable_watchpoints_after_interactive_call_stop): Fixed call to - check_duplicates. Need a section parameter. - (breakpoint_re_set_one): Fixed call to check_duplicates. Need a - section parameter. - (delete_command): Fixed syntax error in conditional - (breakpoint_re_set): Fixed some typos. - - (args_for_catchpoint_enable): New type for handling exceptions. - (current_exception_event): New variable for handling exceptions. - (insert_breakpoints): Check for additional breakpoint types -- - bp_catch_throw, bp_catch_catch, call_disabled. Also, do some - additional work to handle an exception catchpoint. - (remove_breakpoint): There are additional breakpoint types to - check for: Bp_catch_throw, bp_catch_catch, call_disabled. Also do - some additional work to remove the exception catchpoints - (breakpoint_init_inferior): New input parameter. If there are - exception catchpoints delete them. - (breakpoint_here_p): There are additional breakpoint enable - settings to check for: Shlib_disabled, call_disabled - (breakpoint_thread_match): There are additional breakpoint enable - settings to check for: Call_disabled - (ep_is_catchpoint): There are additional breakpoint types to check - for: Bp_catch_throw, bp_catch_catch - (ep_is_exception_catchpoint): New function - (bpstat_find_step_resume_breakpoint): New function - (bpstat_do_actions): Introduce a local copy of the bpstat - structure. - (print_it_normal): There are additional breakpoint types to check - for: Bp_catch_throw, bp_catch_catch Changeing the control - structure a bit (adding else ifs) Add code to print out info about - exceptions. - (bpstat_stop_status): There are additional breakpoint enable - settings to check for: Call_disabled. there are additional - breakpoint types to chack for: Bp_catch_catch and bp_catch_throw. - Check to see if stopped due to an exception. Minor fixes to the - catch_errors calls. Make sure to count all encountered - breakpoints. There was something funky going on previously with - the counting. - (bpstat_what): Add cases for new breakpoint types: - bp_catch_catch, bp_catch_throw. - (bpstat_get_triggered_catchpoints): Check for new breakpoint types - : Bp_catch_catch, bp _catch_throw. - (breakpoint_1): Account for new breakpoint types. - (describe_other_breakpoints): Account for new breakpoint enable - setting (call_disabled) - (check_duplicates): Account for new breakpoint enable setting - (call_disabled) - (disable_breakpoints_in_shlibs): New function - (disable_watchpoints_before_interactive_call_start): New function - (mention): Account for new breakpoint types. - (break_command_1): Some additional checking for a valid PC. - (watch_command_1): Some dditional checking to prevent a watch - before a run command. - (ep_parse_optional_filename): Simplified for loop. - (create_exception_catchpoint): New function - (cover_target_enable_exception_callback): New function - (handle_gnu_4_16_catch_command): This used to be thcatch_command_1 - function.e - (create_temp_exception_breakpoint): New function - (catch_command_1): Differs from gdb 4.16 and gdb 4.17. Is now - calling catch_exception_command_1 using the EX_EVENT_CATCH and - EX_EVENT_THROW values as parameters. - (clear_command): Additional comments - (delete_breakpoint): Handle exceptions. Check for additional - breakpoint enable settings: Shlib_disabled, call_disabled. - (delete_command): Hp folks are claiming that we should not delete - shlib_event breakpoints - (breakpoint_re_set_one): Moved call to check_duplicates. Add new - breakpoint types to switch statement. - (breakpoint_re_set_thread): New function - (enable_command): Account for new breakpoint types. - - (insertion_state_t): New enumerated type. - (remove_breakpoint): New param in funct prototype. - (insert_breakpoints): Check for bp_catch_fork and bp_catch_vfork. - (remove_breakpoints): Changed call to remove_breakpoint. - (detach_breakpoints): New function. - (remove_breakpoint): New parameter, is. Also changed the - way b->inserted is set. - (ep_is_catchpoint): New function. - (ep_is_shlib_catchpoint): New function. - (print_it_normal): Check for bp_catch_load, bp_catch_unload, - bp_catch_fork, bp_catch_vfork, bp_catch_exec. Also new code - to print out catchpoints properly. - (bpstat_stop_status): Check for bp_catch_fork, bp_catch_vfork, - and bp_catch_exec. Also, some code to check for catching a - shared library load/unload. - (bpstat_what): Added catch_shlib_event to class enumeration. - Defined new macro, shlr. Expanded the bpstat_what_main_action - table. Add cases for bp_catch_load, bp_catch_unload, - bp_catch_fork, bp_catch_vfork, and bp_catch_exec. - (bpstat_get_triggered_catchpoints): New function. - (breakpoint_1): Changes to bptypes definition. Also check for - bp_catch_load, bp_catch_unload, bp_catch_fork, bp_catch_vfork, - bp_catch_exec. Similar changes to the switch statement. - (set_raw_breakpoint): Initialize new breakpoint structure fields. - dll_pathname, triggered_dll_pathname, forked_inferior_pid, - exec_pathname. - (create_solib_load_unload_event_breakpoint): New function. - (create_solib_load_event_breakpoint): New function. - (create_solib_unload_event_breakpoint): New function. - (create_fork_vfork_event_catchpoint): New function. - (create_fork_event_catchpoint): New function. - (create_vfork_event_catchpoint): New function. - (mention): New cases for bp_catch_load, bp_catch_unload, - bp_catch_fork, bp_catch_vfork, bp_catch_exec. - (ep_skip_leading_whitespace): New function. - (ep_find_event_name_end): New function. - (ep_parse_optional_if_clause): New function. - (ep_parse_optional_filename): New function. - (catch_fork_kind): New enumerated type. - (catch_fork_command_1): New function. - (catch_exec_command_1): New function. - (catch_load_command_1): New function. - (catch_unload_command_1): New function. - (catch_throw_command_1): New function. - (catch_command_1): Now calls catch_throw_command_1. - (tcatch_command): New function. - (delete_breakpoint): Changed call to remove_breakpoint. - Also free the new fields in the breakpoint structure. - (breakpoint_re_set_one): Handle bp_catch_load, bp_catch_unload, - bp_catch_fork, bp_catch_vfork, bp_catch_exec. - (disable_command): Handle bp_catch_load, bp_catch_unload, - bp_catch_fork, bp_catch_vfork, bp_catch_exec. - (enable_command): Handle bp_catch_load, bp_catch_unload, - bp_catch_fork, bp_catch_vfork, bp_catch_exec. - (_initialize_breakpoint): Alter add_com call for catchpoints, - add add_com call for watchpoints. - - * breakpoint.h (enum bptype): New entries bp_catch_catch, - bp_catch_throw, and bp_none, bp_catch_load, bp_catch_unload, - bp_catch_fork, bp_catch_vfork,bp_catch_exec. Add declarations for - new functions bpstat_have_active_hw_watchpoints and - create_exec_event_catchpoint. - (tbreak_command): Add prototype. - (update_breakpoints_after_exec): Add prototype; update comments. - (reattach_breakpoints): New funct prototype declaration. - (enable): New enumerated value call_disabled. - (bpstat_find_step_resume_breakpoint): New funct decl. - (inf_context): New enumerated type. - (breakpoint_re_set_thread): New funct decl. - (breakpoint_init_inferior): New parameter. - (disable_watchpoints_before_interactive_call_start): New funct decl. - (enable_watchpoints_after_interactive_call_stop): New funct decl. - (disable_breakpoints_in_shlibs): New funct decl. - (struct breakpoint): New fields, dll_pathname,triggered_dll_pathname, - forked_inferior_pid,exec_pathname BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK. - (bpstat_get_triggered_catchpoints): New function. - (detach_breakpoints): New function. - (create_solib_load_event_breakpoint): New function. - (create_solib_unload_event_breakpoint) New function. - (create_fork_event_catchpoint): New function. - (create_vfork_event_catchpoint): New function. - (ep_is_catchpoint): New function. - (ep_is_shlib_catchpoint) New function. - (enum bpstat_what_main_action): New entry. - - * buildsym.c (finish_block): Get rid of processing_hp_compilation; - handle LOC_INDIRECT case. Set the BLOCK_GCC_COMPILED to the right - compiler. - (push_context): Add symbols for parameters to the context_stack. - (merge_symbol_lists): New function. Merges two symbol lists. - (struct context_stack): Add new field param. - - (processing_hp_compilation): New external var. - - * c-exp.y: Use external flag hp_som_som_object_present to decide - whether code was compiled by HP's compilers. Add two new C++ - tokens for true and false. - (yylex): Check for template name is done differently for the - HP/aCC compiler case; change some of the template processing code - for handling HP aCC templates. - - * c-lang.c (c_create_fundamental_type): Added case to handle - template args. Handle FT_BOOLEAN type. Set no sign flag for - FT_CHAR. - (cplus_builtin_types): New structure for c++ builtin types. - (cplus_language_defn): Use cplus_builtin_types instead of - c_builtin_types. - - * c-typeprint.c (c_type_print_base): Don't print 'privete' label - for a class if all members are private, similarly don't print - 'public' for a struct. Add support for sized enums (HP/aCC). get - rid of the 'static' keyword printed by the demangler for member - function, when printing the type of a class. 'static' will be - added by this function. If the demangled name is null, and the - method is not stubbed, get the signature by looking at the - information stored in the symbol structure. Remove printing of - 'const' and 'volatile' keywords for methods. This is now taken - care as part of the demangled member names. - (cp_type_print_method_args): New function. To print a C++ method - arguments and name to the output stream. - - (c_type_print_cv_qualifier): New function. Print out "const" and - "volatile" attributes. - (c_type_print_varspec_prefix): Print const or volatile qualifiers. - (c_type_print_args): Print 'void' for c++. - (c_type_print_varspec_suffix): Print 'void' for a no argument - function. - (c_type_print_base): Print const or volatile qualifiers. Do not - print 'unnamed union' if HP aCC compiler used. Distinguish - between struct and class based on the DECLARED_TYPE. Handle - HP/aCC compiler case for not printing vtable. Add Template - support. - - (cp_type_print_derivation_info): Print out 'protected' when - appropriate. This applies only to HP's compilers, not gcc. - - (c_val_print): Added parameter embedded_offset. Add - embedded_offset to valaddr in function calls; fix calls to - val_print and cp_print_value_fields. process TYPE_CODE_METHOD as - well. moved call to check_typedef out of conditional. added - embedded offset param to val_print call. - - (c_value_print): Add new parameter to call to val_print. - handle pointer to class case. Attempt to - determine the real type of the object to be printed. - ensure that const char *, const unsigned char * - come out without the type but the volatile variants - and the signed variants don't. - - * coff-solib.c (coff_solib_add): Add parameters to call - to symbol_file_add. - - * coff-solib.h: (Solib_REMOVE_INFERIOR_HOOK): New macro. defined - to 0. functionality not implemented for coff. - (SOLIB_CREATE_CATCH_LOAD_HOOK): New macro, generate error message - for coff. - (SOLIB_CREATE_CATCH_UNLOAD_HOOK): Ditto. - (SOLIB_HAVE_LOAD_EVENT): Ditto. - (SOLIB_LOADED_LIBRARY_PATHNAME): Ditto. - (SOLIB_HAVE_UNLOAD_EVENT): Ditto. - (SOLIB_UNLOADED_LIBRARY_PATHNAME): Ditto. - (SOLIB_IN_DYNAMIC_LINKER): Ditto. - (SOLIB_RESTART): Ditto. - - * command.c (find_cmd): New function. (lookup_cmd_1): Call it, - change parsing if tui_version or xdb_commands is set. - (_initialize_command): Install new alias if xdb_commands is set. - - * complaints.h: Add ifdef...endif pair at beginning and end of file. - - * config.in, configure: Regenerated. - - * config/pa/hppabsd.mh (NATDEPFILES): Added new files - hp-psymtab-read.o and hp-symtab-read.o. - * config/pa/hppahpux.mh (NATDEPFILES): Ditto. - - * config/pa/hppahpux.mh (TERMCAP): Use -lHcurses. - * config/pa/hppaosf.mh (NATDEPFILES): Ditto. - - * config/pa/hpux1020.mh (TERMCAP): Use -lHcurses. - (MH_CFLAGS): New flag, -D__HP_CURSES, this define - is used by HP's linker to find the correct curses library. - - * config/pa/hpux1020.mh: New file. - - * config/pa/hpux1020.mt: New file. - - * config/pa/hpux1100.mh (TERMCAP): Link against -lcurses, not - -lHcurses. The latter does not contain mvwaddstr, wscrl, or - wstbwlmkfzz. - - * config/pa/hpux1100.mh (TERMCAP): Use -lHcurses. - (MH_CFLAGS): New flag, -D__HP_CURSES, this define - is used by HP's linker to find the correct curses library. - - * config/pa/hpux1100.mh (TERMCAP): When hosting on hpux 11.00, use - -lHcurses rather than -lcurses. - - * config/pa/hpux1100.mh: New file. - - * config/pa/hpux1100.mt: New file. - - * config/pa/nm-hppah.h (CHILD_HAS_SYSCALL_EVENT): New macro - (CHILD_THREAD_ALIVE): New macro - (STOPPED_BY_WATCHPOINT): Add a condition to the macro, - ! stepped_after_stopped_by_watchpoint - (TARGET_ENABLE_HW_WATCHPOINTS): New macro - (hppa_enable_hw_watchpoints): New funct decl - (TARGET_DISABLE_HW_WATCHPOINTS): New macro - ( hppa_disable_hw_watchpoints): New funct decl - these are for HP's implementation of fast - watchpoints (via page protection). - (target_pid_to_str): New macro, calls hppa_pid_to_str - (target_tid_to_str): New macro, calls hppa_tid_to_str - - * config/pa/nm-hppah.h (CHILD_POST_WAIT): Delete; - (CHILD_CREATE_CATCH_FORK_HOOK): Replace with - CHILD_INSERT_FORK_CATCHPOINT and CHILD_REMOVE_FORK_CATCHPOINT. - (CHILD_CREATE_CATCH_VFORK_HOOK): Replace with - CHILD_INSERT_VFORK_CATCHPOINT and CHILD_REMOVE_VFORK_CATCHPOINT. - (CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC, - CHILD_INSERT_EXEC_CATCHPOINT, CHILD_REMOVE_EXEC_CATCHPOINT, - CHILD_HAS_EXECD, CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL, - CHILD_POST_ATTACH, TARGET_HAS_HARDWARE_WATCHPOINTS, - TARGET_CAN_USE_HARDWARE_WATCHPOINT, - TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT, - TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT, STOPPED_BY_WATCHPOINT, - HAVE_NONSTEPPABLE_WATCHPOINT, target_insert_watchpoint, - target_remote_watchpoint): New macros. - - * config/pa/nm-hppah.h (CHILD_XFER_MEMORY): Reinsert accidentally - deleted define. - - * config/pa/nm-hppah.h: - (PREPARE_TO_PROCEED): Defined macro to use - hppa_prepare_to_proceed. - (hppa_pid_to_str): Extern decl. - (hppa_tid_to_str): Extern decl. - (target_pid_or_tid_to_str): New macro definition. - (hppa_pid_or_tid_to_str): Extern decl. - (ENSURE_VFORKING_PARENT_REMAINS_STOPPED): New macro - for - handling events caused by a call to vfork. - (hppa_ensure_vforking_parent_remains_stopped): Extern decl. - (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK): New macro - - for handling events caused by a call to vfork. - (hppa_resume_execd_vforking_child_to_get_parent_vfork): Extern decl. - - * config/pa/nm-hppah.h: Fix PREPARE_TO_PROCEED macro. - - * config/pa/nm-hppah.h: Fix for gcc compile on HPUX, change - PT_RDUAREA to PT_RUAREA. - - * config/pa/nm-hppah.h: Introduced an HPUXHPPA define. - A bit of a hack so that I can ifdef some code that - only works for the HP wildebeest debugger. - - * config/pa/nm-hppah.h: Lots of new CHILD_ defines; - process_event_kind enum. - - * config/pa/tm-hppa.h (BREAKPOINT32): New define. - (CALL_DUMMY_HAS_COMPLETED): New define. - - * config/pa/tm-hppa.h (STACK_ALIGN): New macro. - (NO_EXTRA_ALIGNMENT_NEEDED): New macro. - (PC_REQUIRES_RUN_BEFORE_USE): New macro. - (REGISTER_NAMES): Formatting in file changed. - (CR27_REGNUM): Base register for thread local storage. - (USE_STRUCT_CONVENTION): New macro used to decide whether - a function returning a value of type type will - put it on the stack or into registers (based on the - PA risc calling conventions). - (EXTRACT_RETURN_VALUE): Fixed calculation for extracting return value. - (VALUE_RETURNED_FROM_STACK): New macro. - (TARGET_READ_PC): Declared the function used in the definition. - (SKIP_TRAMPOLINE_CODE): Declared the function used in the definition. - (TARGET_WRITE_PC): Declared the function used in the definition. - (TARGET_READ_FP): Declared the function used in the definition. - - * config/pa/tm-hppa.h (STRCAT_REGISTER): Define macro for - future use. - (pa_do_strcat_registers_info): Moved function decl from - defs.h to this HPUX specific .h file. - - * config/pa/tm-hppa.h (USE_STRUCT_CONVENTION): Type_LENGTH returns - bytes, not bits; fix off by 8 error. - - * config/pa/tm-hppa.h: - New comment for obj_unwind_info definition - New typedef, obj_private_struct - - * config/pa/tm-hppa.h: Delete most target_ macros -- use default - versions instead; remove extraneous comma from proc_wait macro. - - * config/pa/tm-hppa.h: Get rid of macro HP_COMPILED_TARGET. - - * config/pa/tm-hppa.h: Removed redefinitions of - USE_STRUCT_CONVENTION and STACK_ALIGN macros. - - * config/pa/tm-hppa.h: Some new definitions - New macros: Arg0_REGNUM, ARG1_REGNUM, ARG2_REGNUM, ARG3_REGNUM. - target_pid_to_exec_file, target_acknowledge_forked_child, - target_create_catch_fork_hook, target_create_catch_vfork_hook, - target_has_forked, target_has_vforked, require_attach, - require_detach, proc_wait - New funct decls: Hppa_pid_to_exec_file, - hppa_acknowledge_forked_child, hppa_create_catch_fork_hook, - hppa_create_catch_vfork_hook, hppa_target_has_forked, - hppa_target_has_vforked, hppa_require_attach, - hppa_require_detach, process_wait - (unwind_table_entry): Added comments to describe struct fields. - - * config/pa/tm-hppah.h (somsolib.h): Include it. - - * config/pa/tm-hppah.h: - (CHILD_ENABLE_EXCEPTION_CALLBACK): New define - (CHILD_GET_CURRENT_EXCEPTION_EVENT): New define - - * configure.host (hppa-*-hpux10.20, hppa-*-hpux11.0*): New configs. - - * configure.in (AC_CHECK_HEADERS): Add check for term.h. - - * configure.in: Add an --enable-tui argument. - - * configure.in: Construct tui/Makefile from tui/Makefile.in. - - * configure.in: Use AM_PROG_CC_STDC. If we have the GUI, then we - need this to process libgui.h. - - * convex-tdep.c (decout): Change FILE to GDB_FILE. - - * corefile.c: Include objfiles.h, symfile.h. - (core_file_command): Attempt to determine the name of the symbol - file from the core file. - (read_memory_string): New function. - - * corefile.c (core_file_command): Temporary hack to make non-hpux - work. For, non-hpux, t->to_core_file_to_sym_file does not have a - reasonable value. No target_ops vector on the stack gives it a - non-zero value. fix later. - - * corelow.c (core_file_to_sym_file): Added new local variable, - failing command, and do some explicit type castings. - (core_ops): Add three new fields: to_has_syscall_event, - to_enable_exception_callback, to_get_current_exception_event. - Necessary since we still have oldstyle initialization in - this file - - * corelow.c: Include unistd.h - (core_file_to_sym_file): New function - (core_file_thread_alive): New function - (core_ops): Added new target ops vector fields. see below. And - yes we definitiely need to initialize them here, as long as - we're using static initialization. - - * cxux-nat.c (add_shared_symbol_files): Additonal params for calls - to symbol_file_add. - - * defs.h (gdb_file_isatty): New function decl. - - * defs.h (GDB_FILE): If TUI is defined, define a structure rather - than making this an alias for FILE. - (gdb_stdout, gdb_stderr): If TUI is defined, then define these - as pointers to variables of type GDB_FILE rather than making them - be aliases for stdout and stderr. - - * defs.h (TUIDO): Add definition conditionalized on definition - (or lack thereof) of TUI. - - * defs.h (command_class): Add two additional values. - (precision_type): New enum. - - * defs.h (gdb_fclose): Add declaration. - - * defs.h (store_address): Change prototype to match function. - - * defs.h (tui_version, xdb_commands, dbx_commands): Add decl's. - - * defs.h (gdb_file_deallocate): New function declaration - - * defs.h: - (streamtype): New enumerated type to distinguish between - output to a FILE and output to a buffer. - (tui_stream): New struct type, named GDB_FILE. Contains, - streamtype, FILE, buffer, and bufferlength fields. - (gdb_stdout): Of type GDB_FILE, will pass this around gdb - rather than stdout. - (gdb_stderr): Of type GDB_FILE, will pass this around gdb - rather than stderr. - (fputs_unfiltered_hook): Change stream parameter from FILE to - GDB_FILE - (flush_hook): Change stream parameter from FILE to GDB_FILE - (gdb_fclose): Fix declaration for gdb_fclose; parameter is now of - type GDB_FILE ** - (gdb_file_adjust_strbuf): New function declaration. function lives in - utils.c. - (gdb_file_init_astring): New function declaration. function lives - in utils.c - (gdb_file_get_strbuf): New function declaration. function lives - in utils.c - - * defs.h: Additional include files included when TUI is defined. - - * defs.h: Funct decl source_full_path_of. - - * demangle.c: Add HP_DEMANGLING_STYLE_STRING. - - * demangle.c: Added new demangling style, EDG_DEMANGLING_STYLE_STRING, - to the demanglers structure. This is for support of - Kuck & Assoc.'s changes for demangling. - - * eval.c (evaluate_subexp_standard): C++ member function changes. - - * eval.c (evaluate_subexp_standard): Verify TYPE_TARGET_TYPE is - non NULL before dereferencing it. - - * eval.c (evaluate_subexp_standard): With HP/aCC compiler it is not possible - to perform inferior calls via function pointers. - Resolve calls to overloaded functions using find_overload_match. - We cannot handle HP/aCC pointers to member functions. - Deal with HP/aCC pointers to members in various kind of expressions. - - * f-lang.c (f_printchar): Change FILE to GDB_FILE. - (f_printstr): Ditto. - (emit_char): Ditto. - - * f-lang.c (f_printstr): Change stdout to gdb_stdout. - - * f-typeprint.c (f_print_type): Change FILE to GDB_FILE. - (f_type_print_varspec_prefix): Ditto. - (f_type_print_args): Ditto. - (f_type_print_varspec_suffix): Ditto. - (print_equivalent_f77_float_type): Ditto. - (f_type_print_base): Ditto. - - * findvar.c (): Hp snapshot 3 changes. (extract_address): Coerce - return value from extract_unsigned_integer to CORE_ADDR. - (store_address): Change val from CORE_ADDR to LONGEST; changes to - support machines where CORE_ADDR and LONGEST are different sizes. - (get_saved_register): Coerce arg to store_address to LONGEST. - (read_relative_register_raw_bytes): Cast last arg to - store_address to LONGEST. (read_register): Cast return from - extract_address to a CORE_ADDR. (write_register_pid): Change val - from LONGEST to CORE_ADDR. (read_pc_pid): Save and restore - inferior_pid if necessary. (write_pc_pid): Ditto. - (read_var_value): Cast arg to store_address. - - * findvar.c (read_relative_register_raw_bytes_for_frame): New - function. - (read_relative_register_raw_bytes): Call it. - - * findvar.c (symbol_read_needs_frame): Handle LOC_THREAD_LOCAL_STATIC and - LOC_INDIRECT. - - * fork-child.c (fork_inferior): Chenge fifth parameter to be a - function returning void. - - * fork-child.c (fork_inferior): Delete unused variable f. - - * fork-child.c: - (Startup_WITH_SHELL): New macro -- interim fix for a bug - (breakup_args): New function -- breaks up an argument string into - an argument suitable for passing into execvp(). - (fork_inferior): Handling problems with starting up gdb with a shell. - -- again, this appears to be an interim fix. - - * fork-child.c: - (fork_inferior): Added a comment - (clone_and_follow_inferior): New function. - (startup_inferior): Minor formatting changes. - - * fork-child.c: - (fork_inferior): Hp change is problematic. The -f option has - different meanings for different shells. It is particularly - inappropriate for bourne shells. - - * fork-child.c: - (fork_inferior): Added new parameter, pre_trace_fun. - pre_trace_fun is a function pointer. For some targets, - like HPUX, this function gets called to prepare for forking - a child. - - * fork-child.c: - (fork_inferior): Fixed call to init_trace_fun - - * fork-child.c: - Moved definition of STARTUP_WITH_SHELL to inferior.h - Added a DEBUGGING macro. Currently set to 0. May remove - later. - breakup_args: Add DEBUGGING ifdefs. more sophisticated - parsing to break up args. - (fork_inferior): Rename kshell variable to shell. new local - variable, tryname. Make use of STARTUP_WITH_SHELL macro. - More error processing if starting up with a shell. - (startup_inferior): Distinguish between starting up with a shell - and not doing so. - - * gdbthread.h: - Declarations for load_infrun_state and save_infrun_state take - an additional parameter. - - * gdbthread.h: Note that sometime between gdb 4.16 and 4.17, - thread.h was renamed gdbthread.h - (load_infrun_state): Additional parameters - (store_infrun_state): Additional parameters - - * gdbthread.h: Include breakpoint.h - - * hp-psymtab-read.c (QUICK_LOOK_UP): Redefine to be 0. - (hpread_build_psymtabs): Deal with enums. - (hpread_start_psymtab): Include section offset. - (hpread_end_psymtab): Take care of offset. - - * hp-psymtab-read.c (TRUE): Define. - (FALSE): Define. - (file_exists): New function. Checks for existance of file. - (hpread_pxdb_needed): Rewrite. - (hpread_quick_traverse): Use correct demangling style. - Handle F77 case. - (hpread_get_header): Rewrite. - (hpread_get_textlow): Add support for DOC_FUNCTION. - (hpread_build_psymtabs): Make sure we do the right thing - for pxdb and F77. - - * hp-psymtab-read.c (hpread_pxdb_check): Change parenthesis positions. - - * hp-psymtab-read.c (hpread_quick_traverse): Compare CORE_ADDR - variable end_addr to 0 instaed of NULL to get rif of gcc warning. - - * hp-psymtab-read.c: - (Hpread_get_textlow): Added param to function - Defined convennience macros and some datatypes and variables for - processing the quick lookup-tables. Looks like the code existed - before, but has been munged. - (hpread_pxdb_needed): Major rearrangements of code. Additional local - variables. Also, more extensive checking for various scenarios: - debug info for optimized code vs. unoptimized code, pxdb has been - run vs. pxdb has not been run. - (VALID_FILE): New macro - (VALID_MODULE): New macro - (VALID_PROC): New macro - (VALID_CLASS): New macro - (FILE_START): New macro - (MODULE_START): New macro - (PROC_START): New macro - (FILE_END): New macro - (MODULE_END): New macro - (PROC_END): New macro - (FILE_ISYM): New macro - (MODULE_ISYM): New macro - (PROC_ISYM): New macro - (VALID_CURR_FILE): New macro - (VALID_CURR_MODULE): New macro - (VALID_CURR_PROC): New macro - (VALID_CURR_CLASS): New macro - (CURR_FILE_START): New macro - (CURR_MODULE_START): New macro - (CURR_PROC_END): New macro - (CURR_FILE_ISYM): New macro - (CURR_MODULE_ISYM): New macro - (CURR_PROC_ISYM): New macro - (TELL_OBJFILE): New macro - (pst_syms_struct): New typedef to keep track of the start/end symbol - table (LNTT) indices of psymtabs created so far. - (pst_syms_count): New variable - (pst_syms_size): New variable - (told_objfile): New variable - (init_pst_syms): New function. sets up psymtab symbol index stuff. - (clear_pst_syms): New function. clean up psymtab symbol index stuff. - (record_pst_syms): New function. add info about newest psymtab to symbol - index table. - (find_next_pst_start): New function. Find a suitable symbol table index. - (find_next_file_isym): New function - (find_next_proc_isym): New function - (find_next_module_isym): New function - (scan_procs): New function. Scan and record partial symbols for all - functions starting from specified index and in a specified code range. - (hpread_quick_traverse: Major rearrangement of code. The function - now uses all the nifty macros. There are some new local variables. - Check for EDG_DEMANGLING style. ifdef out some code for handling F77. - Previously, the function looped over all the modules in the table. - Now, the function loops over all the files, modules, and procedures. - With HP aCC and CTTI, it is possible for a compiled object to have a - file and no module. - (hpread_build_psymtabs): Added a section of code ifdefed by - QUICK_LOOK_UP. It check to see whether or not there are any globals - in the executable. Fix number of params to hpread_start_psymtab call. - Some changes to the way DNTT_TYPE_MODULE is handled. - (hpread_get_textlow): Change in signature, minor code changes. The - function finds the low address associated with a specified symbol. - In looking for the address for the symbol avoid going of the end of - the LNTT file. - - * hp-psymtab-read.c: Change TRUE to 1 and FALSE to 0. Do some - reformatting. - - * hp-psymtab-read.c: Include demangle.h - (trans_lang): New function to let gdb know the correct language. - (hpread_quick_traverse): Use ARM style demangling. - Demangle procedures names. - Use gdb language names instead of hp language names. - Add symbol to list using its demangled name. - - * hp-psymtab-read.c: New file. - (hpread_call_pxdb): New function. Call PXDB to process our file. - (hpread_pxdb_check): New function. Return TRUE if the file needs - pre-processing by PXDB and we have thus called PXDB to do this - processing and the file needs to be re-loaded. - (hpread_quick_traverse): New function. Traverse the quick look-up - tables, building a set of psymtabs. - (hpread_get_header): New function. Get appropriate header from obj - file, based on pxdb type - (hpread_symfile_init): No change from hpread.c - (hpread_build_psymtabs): If there are quick lookup tables, read those, - then scan the global section LNTT. Otherwise, just scan the whole LNTT. - Changed: Add a global function entry to the global partial symbol list. - Handle end of symbols, for QLT case. - In case of TAGDEF, if it is a class or a template, add the name to the - var_namespace, so that it is known as a type by gdb. - In case of CONSTANT, and it is global, add it to the globals. - (hpread_symfile_finish): No change from hpread.c - (hpread_get_lntt): Make it not static - (hpread_get_gntt): No change from hpread.c - (hpread_get_slt): Make it not static - (hpread_get_textlow): No change from hpread.c - (hpread_start_psymtab): No change from hpread.c - (hpread_end_psymtab): No change from hpread.c - - * hp-symtab-read.c (hpread_get_scope_start): Renamed. It was - hpread_get_depth. - (hpread_type_translate): Distinguish between signed and unsigned char - types. - (hpread_psymtab_to_symtab): Set flag for hp compilation. - (hpread_read_function_type): Append symbols for parameters to local - list as well as to the global list. Get the parameters types from the - local list instead of the global list. - (hpread_read_struct_type): Add new field num_fn_fields to next_fn_field - structure. Rewrite handling of templates - (hpread_type_lookup): Change handling of dntt_type_modifier. - (hpread_process_one_debug_symbol): Call hpread_get_scope_start instea - of hpread_get_depth. Handle enum as well. - (hpread_get_scope_depth): New function. Get nesting depth for a - DNTT entry. - - * hp-symtab-read.c (hpread_psymtab_to_symtab): Set - processing_gcc_compilation to 0. - - * hp-symtab-read.c (hpread_psymtab_to_symtab_1): Change stdout to - gdb_stdout; change fflush to gdb_flush. - (hpread_psymtab_to_symtab): Change fflush to gdb_flush. - - * hp-symtab-read.c (hpread_read_enum_type): Declare variable. - (hpread_read_struct_type): Eliminate references - to 'args' member of fn_field. - - * hp-symtab-read.c (hpread_read_struct_type): A static member - is now indicated by the bitsize field, not the bitpos. - Initialize physname to empty. - (fix_static_member_physnames): Use new macros to deal with - physnames. - - * hp-symtab-read.c (hpread_read_struct_type): Change references - to bitpos member of struct field to use the FIELD_BITPOS macro. - - * hp-symtab-read.c (hpread_read_struct_type): Comment out reference to - obsolete field fn_field.args. - Add struct complaint definitions for complaints. - (hpread_read_struct_type): Change call to complain. - (hpread_read_array_type): Change call to complain. - (hpread_type_lookup): Change call to complain. - (hpread_process_one_debug_symbol): Change calls to complain. - (hpread_type_translate): Change calls to complain. - - * hp-symtab-read.c (hpread_read_struct_type): Make sure bitvector - has been allocated before calling has_vtable. - - * hp-symtab-read.c (hpread_read_struct_type): Revert change, - just check for vtable without checking for bitvectors too. - - * hp-symtab-read.c: - (Hpread_expand_symtab): Change name of local variable from - at_end_of_module to at_module_boundary. - Also, if demangling style is already EDG, do not reset it - to the HP demangling style. - Change at_end_of_module param to hpread_process_one_debug_symbol - call to at_module_boundary. - No longer break out of loop when reach end of module. With CTTI, - the compiler can generate function symbols which are not in - any module. Typically they show up after the end of one - module and before the start of the next module. - (hpread_read_struct_type): Check that the debug info for - a TEMPLATE_ARG is correct. - (hpread_process_one_debug_symbol): Change name of at_end_of_module_p - param to at_module_boundary_p. - Also set *at_module_boundary_p = -1 if missing a module end and set - it to 1 when finished expanding the debug info. - Handle TLS variable. - - * hp-symtab-read.c: Include defs.h, symtab.h, gdbtypes.h, complaints.h. - (fixup_class): New static variable. - (fixup_method): New static variable. - (hpread_get_location): Rewrite. - (hpread_has_name): Add cases for DNTT_TYPE_DOC_FUNCTION and - DNTT_TYPE_DOC_MEMFUNC - (hpread_expand_symtab): Use HP demangling style. - Set hp_som_som_object_present to 1. - (hpread_type_translate): Error out if not immediate. Issue warning - if there is an unhandled type code. - (error_in_hpread_type_translate_complaint): Remove this structure. - (hpread_read_enum_type): Don't assume size of enum is always 4 bytes. - (hpread_read_function_type): Add new parameter to indicate a new block. - Do not add the parameters to the symbol list. - If the type was read in earlier, do not modify the type structure. - If we are creating a new block, set the local symbol list to be the - param list. - Need to mark this type as preprocessed. - (hpread_read_doc_function_type): New function. Read and internalize - a native DOC function debug symbol. - (hpread_read_struct_type): A method can be of type doc_function and - doc_memfunc too. - Handle case in which a method is read before its class. Deal with - incomplete method types. - Handle cases in which HP/aCC compiler creates operator names w/o - the 'operator' keyword. Rewrite the loop over the fileds. - (fix_static_member_physnames): New function. Adjust the physnames for - each static member. - (fixup_class_method_type): New function. Fix-up the type structure for a - class. - (hpread_read_array_type): Change complaint to warning. - (hpread_type_lookup): Add case for DNTT_TYPE_DOC_FUNCTION. - For structures/classes set static member to point to strings with full - names. - Change calls to hpread_read_function_type to pass extra parameter. - (hpread_record_lines): Handle case for SLT_NORMAL_OFFSET. - (class_of): New function. Given a function "f" which is a member of a class, - find the classname that it is a member of. - (hpread_process_one_debug_symbol): Deal with possible alias field from the - som record for the Function or Entry type. - Do the demangling ourselves if the gdb demangler failed. - Add support for DOC functions. - For function types, add parameters to local list. - (hpread_get_scope_depth): Make this function a no-op. - (hpread_adjust_bitoffsets): New function. Adjust the bitoffsets for all - fields of an anonymous union. - (hpread_get_next_skip_over_anon_unions): New function. Skip over anonymous - unions. - - * hp-symtab-read.c: Include demangle.h - (hpread_expand_symtab): Ensure we are using ARM-style demangling. - (hpread_process_one_debug_symbol): Set the mangled and demangled - names for functions. - Record the class name to generate the demangled names of member - functions. - - * hp-symtab-read.c: New file. - (hpread_get_depth): No change from hpread.c - (hpread_get_line): No change from hpread.c - (hpread_get_location): No change from hpread.c - (hpread_has_name): Make it not static. Return 1 for DNTT_TYPE_BLOCKDATA - and DNTT_TYPE_MEMFUNC. Return 0 for CLASS_SCOPE, REFERENCE,PTRMEM, - PTRMEMFUNC, CLASS, GENFIELD, VFUNC, MEMACCESS, INHERITANCE, - FRIEND_CLASS, FRIEND_FUNC, MODIFIER, OBJECT_ID, TEMPLATE, TEMPLATE_ARG, - FUNC_TEMPLATE, LINK. - (hpread_psymtab_to_symtab_1): No changes from hpread.c - (hpread_psymtab_to_symtab): Make it a static function - (hpread_expand_symtab): Modified - (hpread_type_translate): If not typep.dntti.immediate do not abort, - but complain and return. Same for default action. Handle more HP_TYPEs. - (hpread_lookup_type): Initially allocate a correct-size type-vector. - (hpread_alloc_type): Reset type_addr only if a type was allocated. - (hpread_read_enum_type): If this has already a type associated, return. - (hpread_read_function_type): Do different things depending on whether - function is a MEMFUNC, a TEMPLATE, a FUNCTION som record. - Do not use the LOC_REGPARM_ADDR symbol class. - (hpread_read_struct_type): Handle classes and templates too. Major - rewrite. - (hpread_get_nth_template_arg): New function. - (hpread_read_templ_arg_type): New function. - (hpread_read_set_type): No change from hpread.c - (hpread_read_array_type): Modified - (hpread_read_subrange_type): Add handling of more DNTT entries. - added support for templates, classes, references, virtual functions. - (hpread_type_lookup): Handle DNNT_TYPE_MODULE. - (hpread_record_lines): No changes from hpread.c - (hpread_process_one_debug_symbol): Handle WITH, COMMON, - CLASS_SCOPE. Expand TAGDEF case to handle classes and templates. - - * hppa-tdep.c (pa_do_strcat_registers_info): Has a new parameter, - precision, which is passed into the call to pa_strcat_fp_reg to - indicate whether to display the floating point registers using - single or double preceision. - (pa_strcat_registers): Introduce local variable, precision, and - pass it into call to pa_strcat_fp_reg. - (pa_strcat_fp_reg): Modified function. New parameter, precision, - used by function to decide whether to use single or double - precision. Also added the code to put a double precision value - into a buffer. - - * hppa-tdep.c: Add'l includes , - , declare pa_register_look_aside, define is_pa_2. - (rp_saved): Check for where to read the return pointer from. - (pa_do_registers_info): Handle is_pa_2. (pa_register_look_aside): - new function. (pa_print_registers): Handle is_pa_2. - (in_solib_call_trampoline): Handle a compiler/linker error. - (skip_trampoline_code): Changes to some masks used in examining - instructions. (inst_saves_fr): Test for FSTWS instruction. - (skip_prologue): Renamed to skip_prologue_hard_way. - (after_prologue): New function. (skip_prologue): New function. - - * hppa-tdep.c (after_prologue): If f is NULL, don't dereference - it. - - * hppa-tdep.c (after_prologue): If no debug info, return zero - telling caller that we need to find the end of the prologue via - the hard way (instruction examination). - - * hppa-tdep.c (find_unwind_entry): Avoid dereferencing a null - pointer. - - * hppa-tdep.c (hppa_pid_to_exec_file): Deleted -- no longer used. - - * hppa-tdep.c (hppa_prepare_to_proceeed): Add prototype. - (read_unwind_info): Purecov comments, bug fixes. - (find_unwind_entry): Purecov comments, bug fixes. - (find_stub_with_shl_get): Purecov comments. - (frame_chain): Additional parens. - (hppa_push_arguments): Changes to commented out version of routine. - (hppa_fix_call_dummy): Purecov comments, fix location of end.o. - (in_solib_call_trampoline): Purecov comments. - (in_solib_return_trampoline): Purecov comments. - (setup_d_pid_in_inferior): Fix location of end.o. - (initialize_hp_cxx_exception_support): Fix location of end.o. - (child_enable_exception_callback): Purecov comments. - - * hppa-tdep.c: - (Pa_do_strcat_registers_info): New routine. called by - tui/tuiRegs.c:_tuiRegisterFormat to place a register name - and value into a string buffer. Interface may change in - future. Checking this in so that we have something - functional for HP. - (pa_strcat_registers): New routine, called by - pa_do_strcat_registers_info. Does same thing as - pa_print_registers except it takes a stream parameter. - This routine should disappear in future. Checking in - so that we have something functional to give HP - (pa_strcat_fp_reg): New routine, called by - pa_do_strcat_registers_info and pa_strvat_registers - to place a floating point register name and value into - a buffer. This interface may change in future. - Checking in so that we have something functional to give HP. - - * hppa-tdep.c: (Pa_print_fp_reg): Change prototype to match def'n. - (pa_register_look_aside): Fix comment immediately before function. - - * hppa-tdep.c: Changes to better support stack unwinding, - reading and writing registers for HPUX. The HP folks had - an advantage ... access to a runtime architecture spec ;-}. - New includes: Ptrace.h - (internalize_unwinds): Initialize new fields in table. - (read_unwind_info): Entries in the table are now more complex - structures. References of the form ...->table[index].stub_type - are now ...->table[index].stub_unwind.stub_type. - (find_proc_framesize): Added a check for pc == 0. - (rp_saved): Entries in the table are now more complex - structures. References of the form ...->table[index].stub_type - are now ...->table[index].stub_unwind.stub_type. - (frameless_function_invocation): Stub_type becomes - stub_unwind.stub_type - (saved_pc_after_call): Stub_type becomes stub_unwind.stub_type - (hppa_frame_saved_pc): Stub_type becomes stub_unwind.stub_type - (frame_chain_valid): Stub_type becomes stub_unwind.stub_type - (hppa_call_dummy): Stub_type becomes stub_unwind.stub_type - (pa_print_fp_reg): Additional params to call val_print - (in_solib_call_trampoline): Stub_type becomes stub_unwind.stub_type - (in_solib_return_trampoline): Stub_type becomes stub_unwind.stub_typ - (skip_trampoline_code): Additional code to handle external - dyncalls. Also stub_type becomes stub_unwind.stub_type - (hppa_pid_to_exec_file): New funct. FOr HPUX 10.0 and beyond there - is an explicit ptrace request for getting the pathname associated - with a process id (pid). - - * hppa-tdep.c: Fix for gcc compile on HPUX - (hppa_pid_to_exec_file): Remove unwanted param from - call to call_ptrace. Note, hppa_pid_to_exec_file goes - away in subsequent hp snapshots. - - * hppa-tdep.c: Include bfd.h. - include dl.h - (args_for_find_stub): New structure. - (find_unwind_entry): Deal with null input pc value. - (rp_saved): Ditto. - For the import stub, return -24 always. - (hppa_frame_saved_pc): Save old pc value, to detect we are in a loop. - (init_extra_frame_info): Use TARGET_READ_FP. - (frame_chain): Include thread support. - If the caller's pc is zero, we loose and return, just like stack bottom. - Disable warning about being unable to find unwind info. - (hppa_push_arguments): Rewrite. - (hppa_value_returned_from_stack): New function. Handles returning a value - larger that 64 bits, stored on the stack. - (find_stub_with_shl_get): New function. To look up symbols in shlibs. - (cover_find_stub_with_shl_get): New function. Cover routine for - find_stub_with_shl_get to pass to catch_errors. - (hppa_fix_call_dummy): Comment out old stub mechanism. Rewrite using dyncall. - (target_read_fp): New function. - (pa_do_registers_info): Floating point registers start at FP4. - (pa_print_registers): Use FP4_REGNUM instead of 72. - (skip_trampoline_code): Do machine instruction matching for PA2.0. - (setup_d_pid_in_inferior): New function. Exception handling support. - (initialize_hp_cxx_exception_support): Ditto. - (child_enable_exception_callback): Ditto. - (child_get_current_exception_event): Ditto. - - * hppah-nat.c (child_post_wait, child_post_follow_vfork, - child_post_follow_inferior_by_clone): New functions. - - * hppah-nat.c (child_xfer_memory): Make sure the call to ptrace really - fails before we give up. - (hppa_pid_to_str): New function. Format a process id. - (hppa_tid_to_str): New function. Format a thread id. - - * hppah-nat.c (child_xfer_memory): Use xmalloc, not alloca. - (child_post_wait): Delete. - (child_post_follow_vfork): Delete decl of child_ops; delete - large chunks of function -- let it be handled by the normal - mechanism that notices and handles exec events, in resume(). - - * hppah-nat.c (require_notification_of_exec_events): New function; - just notify of exec events, not all events, and just the specified - pid, don't include it's children (10.20 version). - (child_acknowledge_created_inferior): Call new function - require_notification_of_exec_events instead of - require_notification_of_events. - - * hppah-nat.c [!GDB_NATIVE_HPUX_11]: Move HPUX 10.x-specific - support code here from infptrace.c. - - * hppah-nat.c: Removed #define ptrace call_ptrace - replaced all calls to ptrace with calls to call_ptrace - (parent_attach_all): Removed call to ptrace - - * hpread.c (hpread_psymtab_to_symtab_1): Change fflush to - gdb_flush; change stdout to gdb_stdout. - (hpread_psymtab_to_symtab): Change fflush to gdb_flush. - - * hpread.h: New file. Includes all includes, struct defs, defines - from hpread.c. - - * infcmd.c - (attach_command): New local variable, exec_file, added code to - determine exec_file from pid if exec_file is not already known, - call new target operation, target_post_attach -- a no-op unless - on HPUXHPPA - (detach_command): After detaching, do a SOLIB_RESTART - - * infcmd.c (objfiles.h): Fix typo on include line. - - * infcmd.c (run_command): Only call SOLIB_RESTART if it's - defined. - (detach_command): Ditto. - - * infcmd.c: - (run_stack_dummy): Add calls to - disable_watchpoints_before_interactive_call_start and - enable_watchpoints_after_interactive_call_stops - (finish_command): Alter code handling the evaluation and printing - of the target function's return value. - (attach_command): When given a pid, but no exec file, try to determine - the exec file from the process. If the process does not record a - full path name, try to qualify the filename against the source path. - (_initialize_infcmd): Add some verbiage about how to use the attach command - - * infcmd.c: - Include objfiles.h - (run_command): If program has already been started, and decide - to restart it, then kill the target, flush the caches, - call init_wait_for_inferior. Also purge old solib objfiles. - - * infcmd.c: Changed calls to val_print, using a new macro, - SOLIB_RESTART - (run_command): Calls SOLIB_RESTART - (do_registers_info): Changed calls to val_print - - * infcmd.c: Made the symfile.h include preceed the - objfiles.h include. The other ordering caused a - compile problem (incompletely defined types). - - * inferior.h (REQUIRE_DETACH): Fix default definition. - * inftarg.c (child_post_attach): Fix declaration, make static. - (proc_wait): Make globally visible. - (child_insert_fork_catchpoint, etc): Fix return type. - - * inferior.h (STARTUP_WITH_SHELL): New define. - (START_INFERIOR_TRAPS_EXPECTED): New define - - * inferior.h (fork_inferior): Change fifth parameter to be a function - returning void. - - * inferior.h (proc_wait): Declare. - - * inferior.h: - (Require_ATTACH): New macro - (REQUIRE_DETACH): New macro - (detach): Definition is now an extern - (clone_and_follow_inferior): New definition, it's also an extern - - * inferior.h: - (Require_attach): Default definition for require_attach funct - (require_detach): Default definition for require_detach funct - (pre_fork_inferior): New funct decl for function defined in - infptrace.c - (fork_inferior): New parameter in funct decl. - - * inferior.h: - New variable decls: Inferior_ignoring_startup_exec_events, - inferior_ignoring_leading_exec_events -- these variables - are used when processing an exec call. - (CALL_DUMMY_HAS_COMPLETED): New default macro -- for targets - where PC in call dummy implies that call dummy has - completed. Note, that on HPUX this inference does not hold. - - * infptrace.c - (require_notification_of_events): New function - (child_acknowledge_created_inferior): Previously named - hppa_acknowledge_forked_child. Also calling - require_notification_of_events and clearing some semaphore - variables - (child_post_startup_inferior): New function - (child_create_catch_fork_hook): Previously named - hppa_create_catch_fork_hook - (child_create_catch_vfork_hook): Previously named - hppa_create_catch_vfork_hook - (child_has_forked): Previously named hppa_target_has_forked - (child_has_vforked): Previously named hppa_target_has_vforked - (process_wait): Changed to call target_post_wait - (attach): Add call to require_notification_of_events - (child_pid_to_exec_file): New function - (hppa_require_attach): New local variable, pt_status - (hppa_get_process_events): New function - - * infptrace.c (call_ptrace): Simplify control flow. - (proc_wait): Move here from inftarg.c, add target_post_wait call. - - * infptrace.c (call_ptrace): Add some debugging code. - - * infptrace.c (child_pid_to_exec_file): Declare variable. - - * infptrace.c (kill_inferior): Clean up call to proc_wait. - - * infptrace.c: - (Call_ptrace): When the ptrace request is PT_SETTRC, - call ptrace and then call parent_attach_all. - - * infptrace.c: - (Child_has_syscall_event): New function. only applicable - (for now) on HPUX 10.30 and beyond via the ttrace call. - In infptrace.c there is a default operation. - With ttrace, it is possible to tell the kernel to - notify the debugger that the target program is about to make - or return from a syscall. - (child_thread_alive): New function. a default function. - ptrace doesn't support kernel threads. - (hppa_enable_page_protection_events): Defualt function - (hppa_disable_page_protection_events): Default function - - * infptrace.c (child_pid_to_exec_file): Fix number of params to - cal_ptrace call. - - * infptrace.c (hppa_pid_or_tid_to_str): New function. - (hppa_switched_threads): New function. - (hppa_ensure_vforking_parent_remains_stopped): New function. - (hppa_resume_execd_vforking_child_to_get_parent_vfork): New function. - - * infptrace.c: Most of the changes found in infptrace.c should - be moved to hppah-nat.c - (PT_VERSION): A new define - (startup_semaphore_t): A new struct type. it is used to - coordinate the parent and child processes after a fork and - before an exec on HPUX. - (call_ptrace): Changes to determine whether the ptrace - request is for starting the tracing of the target process. - (parent_attach_all): New funct. used on HPUX for coordinating - the parent and child processes after a fork and before and exec. - (hppa_acknowledge_forked_child): New funct. prabably belongs - in hppah-nat.c - (hppa_enable_catch_fork): New funct. probably belongs in - hppah-nat.c - (hppa_disable_catch_fork): New funct. probably belongs in - hppah-nat.c - (hppa_create_catch_fork_hook): New funct. probably belongs in - hppah-nat.c - (hppa_enable_catch_vfork): New funct. probably belongs in - hppah-nat.c - (hppa_disable_catch_vfork): New funct. probably belongs in - hppah-nat.c - (hppa_create_catch_vfork_hook): New funct. probably belongs to - hppah-nat.c - (hppa_target_has_forked): New funct. probably belongs in - hppah-nat.c - (hppa_target_has_vforked): New funct. probably belongs in - hppah-nat.c - (process_wait): New funct. also ifdefed for proc_wait. - (kill_inferior): Call proc_wait rather than wait. this is - pretty hacky. - (pre_fork_inferior): New function. used only by HPUX. - probably should be defined elsewhere. - - * infrun.c (follow_inferior_fork): Only define on HP. - (wait_for_inferior): Only call SOLIB_IN_DYNAMIC_LINKER if we have - shared libraries; restore test of IN_SOLIB_DYNSYM_RESOLVE_CODE - removed by HP. - - * infrun.c (normal_stop): Add a call to the TUIDO - macro just before the annotate_stopped label. This - updates the windows after each program stop. - - * infrun.c (normal_stop): Verify stop_command is non-zero before - dereferencing it (it won't be set if dbx_commands is set). - - * infrun.c (resume): Add #ifdef HPPAHPUX around HPUX-specific - code. - - * infrun.c (resume): Add missing semicolon. - - * infrun.c (wait_for_inferior): Fix syntax error. - - * infrun.c (follow_fork_mode_kind_names): Removed "both" option. - (follow_fork): Added parameters. additional code for handling - following of parent, following of child - (resume): Added code for deciding how to resume in presence of - fork. Additional params to follow_fork call. - - * infrun.c (follow_exec): Ifdef for HPUXHPPA for the moment, the - code in here assumes the existance of the child_ops target - vector. This is incorrect for Solaris. - - * infrun.c (resume): Fixed ifdefs, HPPAHPUX -> HPUXHPPA. - - * infrun.c (wait_for_inferior): Fixed a matching parens problem -- - matching curly brace inside ifdefed code which is not being - compiled. Change local validFlag to be an 'int' rather than a - 'bool' and fixed the corresponding assignment statements. - - * infrun.c: - Two new global variables: Inferior_ignoring_startup_exec_events and - inferior_ignoring_leading_exec_events. - New static variables: Parent_of_vfork_trap_expected_and_ignorable, - step_resume_breakpoint, through_sigtramp_breakpoint, pending_follow, - follow_vfork_when_exec - (follow_inferior_fork): Does what follow_fork did! - (follow_fork): Is now a wrapper function for follow_inferior_fork - (follow_vfork): Is now a wrapper function for follow_inferior_fork - (follow_exec): New function, handles an exec event. - (resume): Remove 3 local variables: Child_pid, has_forked, has_vforked. - move and expand code that tries to follow a fork (i.e. also check - for vfork and exec - (init_wait_for_inferior): Initialize the new structure, pending_follow - (delete_breakpoint_current_contents): When deleting all the breakpoints also - set the breakpoint struct pointer to NULL. - (wait_for_inferior): A number of changes. - The step_resume_breakpoint and through_sigtramp_breakpoint local - variables are now visible in entire module. - Changed name of variable from child_inferior_pid to saved_inferior_pid. - Added several cases to the event processing switch statement: - Target_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED, TARGET_WAITKIND_EXECD. - Also, for TARGET_WAITKIND_STOPPED, check to see if expecting a trap - from the parent of a vfork (ignorable) otherwise break as usual. - When determining the value of 'random_signal' (0 or 1), no longer check for - catchpoints. - When determining how to handle unexpected signals, must now take into - account fork, vfork, and exec. - Change call to PC_IN_CALL_DUMMY to a call to CALL_DUMMY_HAS_COMPLETED - At stop_stepping label, check to see if stopped for fork or - vfork event. - - * infrun.c: New code is related to threads and fork/vfork/exec. - New static variable: Thread_step_needed - Deleted static variable: Parent_of_vfork_trap_expected_and_ignorable - Altered the pending_follow and fork_event structs - (follow_inferior_fork): Before detaching from child and removing - all breakpoints form it -- but only if forking or following - vforks as soon as they happen. Also reset the solib inferior hook. - The same kind of logic applies to hitting step_resume_breakpoints - (calling breakpoint_re_set_thread) and to resetting and inserting - breakpoints. - (follow_exec): Forward decl - (follow_vfork): Check to see if gdb followed the child. If - the child exec'd before gdb saw the parent's vfork event - then call follow_exec. - (follow_exec): If the exec occured after a vfork, then follow - the vfork as well. Do it before following the exec. - Make sure to update breakpoints after and exec - (resume): New local variable, should_resume. - Change parameters in calls to follow_fork, follow_vfork, and - follow_exec. Some changes to the way various pending_follow.kind - situations are handled (there's TARGET_WAITKIND_FORKED, - TARGET_WAITKIND_VFORKED, ARGET_WAITKIND_EXECD. Some additional - conditions to check before deciding to resume the target (i.e. - should_resume=1, stepping?, thread_step_needed?i, regular - resume?) - (proceed): When proceeded at location that does not have a breakpoint - set thread_step_needed=0 to indicate that it is not necessary to - single step thread over breakpoint. SOme additional checks to see - if it is necessary to step thread over breakpoint. - (start_remote): Remove call to clear_proceed_status. - (init_wait_for_inferior): Initialize new fields in fork_event - structure and add a call to clear_proceed_status. - (wait_for_inferior): New local variable: New_thread_event. - Initialize thread_step_needed = 0. - Minor massaging of conditions for adding a new thread to the thread list. - No longer resuming execution after adding a new thread. Let user play with thread first. - Some changes in the way TARGET_WAITKIND_FORKED, ARGET_WAITKIND_VFORKED, - TARGET_WAITKIND_EXECD are handled -- this is all HPUX related. - Simplified TARGET_WAITKIND_STOPPED -- HP previously had some - more complicated code in here. - Moved the code to resume threads to after the large case statement that processes the events. - Additional processing for stop_signal=TARGET_SIGNAL_TRAP. - Cleanup code at process_event_stop_test label. - Set thread_step_needed when processing a BPSTAT_WHAT_SINGLE. - Minor massaging of fork/vfork/exec part of stop_stepping code. - (normal_stop): Minor changes. calling show_and_print_stack_frame. - (xdb_handle_command): New function - (_initialize_infrun): Handle xdb_commands. also handle dbx commands - - * infrun.c: Changes to support following forks, and handling - catchpoints. - (follow_fork_mode_kind_names): New array - (follow_fork): New function. implements the follow parent, - or child functionality. - (resume): Additions to check whether the target process - just forked and decide which process to follow. - (wait_for_inferior): Additional variables (child_inferior_pid, - stepping_through_solib_after_catch, - - stepping_through_solib_catchpoints. - - Altered CURRENTLY_STEPPING macro to check for stepping through - a shared library after hitting a catchpoint. - - Add parameters to save_infrun_state call - - Check for fork and vfork when deciding if event is a random - signal - - When considering stops due to breakpoints, check for - BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK - - Check for stop due to an explicit catchpoint - - When checking for single stepping event, also check for - stepping to get out of dynamic linker's hook after catching - a shlib event - (is_internal_shlib_eventpoint): New funct. check to see if - event type is bp_shlib_event. - (stopped_for_internal_shlib_event): New funct. check for shlib - events - (stopped_for_shlib_catchpoint): New funct. check for catchpoints. - (normal_stop): Additions to check for shlib event - (set_follow_fork_mode_command): New funct. handles the new follow - fork command. - (_initialize_infrun): Additions for follow-fork-mode command. - - * infrun.c: Ifdefing references to - switched_from_inferior_pid for HPUXHPPA. They don't seem - useful for Solaris (i.e. non-HPUX) - - * infrun.c: Included tuiData.h and tuiDataWin.h, ifdefed for TUI. - Included top.h. New static variables: Switched_from_inferior_pid, - number_of_threads_in_syscalls. - (follow_inferior_fork): If there is a step_resume breakpoint - explicitly reset the thread number. - (resume): For TARGET_WAITKIND_VFORKED, removed a check for getting - the vfork event to soon. - (init_wait_for_inferior): Added parameter to call to - breakpoint_init_inferior. Initialize number_of_threads_in_syscalls. - (wait_for_inferior): New local variables: Prev_sal, - enable_hw_watchpoints_after_wait, stepping_through_sigtramp, - stepped_after_stopped_by_watchpoint. Enable watchpoints after a wait. - Added cases for TARGET_WAITKIND_SYSCALL_ENTRY and - TARGET_WAITKIND_SYSCALL_RETURN. - Do additional processing if stop due to breakpoint, but breakpoint is - only valid for a thread other than the one currently running. Additional - parameters to save_infrun_state and load_infrun_state. Some additional - processing for BPSTAT_WHAT_STEP_RESUME. Some additional processing to - handle stepping over a function. - (normal_stop): Added notification of switching threads. ifdefing some - TUI changes and leaving out non-essential TUI changes. - (restore_selected_frame): Ifdefing some TUI changes - (restore_inferior_status): Ifdefing some TUI changes - - * infrun.c: Removed the TUI ifdefs and TUI code. Also removed - include for top.h. HP introduced this. I'm taking it out. - - * inftarg.c (child_detach_from_process): Declare. - (child_attach_to_process): Declare. - (child_stop): Make static to match declaration. - - * inftarg.c (ptrace_him): Change prototype back to return int. - - * inftarg.c (ptrace_me): Remove debug output, pass NULL to - fork_inferior if not HPUX. - - * inftarg.c: - (child_require_attach): New funct prototype and definition - (child_require_detach): New funct prototype and definition - (proc_wait): Funct prototype and definition are enclosed by - proc_wait ifndef - (child_attach_to_process): New function, does most of the - work that child_attach used to do and some additional - work to determine whether gdb is already attached to the - target how to react. - (child_attach): Altered. It's now a wrapper for - child_attach_to_process. - (child_require_attach): New function, called if should attach - even when gdb is already attached to target. - (child_detach_from_process): New function, does most of the - work that child_detach used to do and some additional work - to determine whether gdb is currently attached to the target. - (child_detach): Altered. It's now a wrapper for - child_detach_from_process. - (child_require_detach): New function, called if should try to - detach even when gdb is not attached to target. - (ptrace_him): Calls a new function, target_acknowledge_forked_child. - Currently, target_acknowledge_forked_child, is only defined to - do something for HPUX. - (child_create_inferior): Changed call to fork_inferior. - (child_ops): Added to_require_attach and to_require_detach fields - to the child_ops target ops vector. - - * inftarg.c: - Some hacks for ttrace work - (child_wait): Additional local variables, additional code in - while loop to check for: Process exited, process forked, - process vforked, process execd - (child_thread_alive): John B. seems to think that the kill - call is inapproapriate for HPUX. - (child_attach_to_process): Using strtol rather than atoi. - no longer check for case where there is no known exec file. - (child_post_attach): New function, a default, a no-op - (child_insert_fork_catchpoint): New function, a default, a no-op - (child_remove_fork_catchpoint): New function, a default, a no-op - (child_create_catch_fork_hook): Deleted - (child_create_catch_vfork_hook): Deleted - (child_insert_vfork_catchpoint): New function, a default, a no-op - (child_remove_vfork_catchpoint): New function, a default, a no-op - (child_can_follow_vfork_prior_to_exec ):new function, a default, - a no-op - (child_insert_exec_catchpoint): New function, a default, a no-op - (child_remove_exec_catchpoint): New function, a default, a no-op - (child_has_execd): New function, a default, returns 0 - (child_reported_exec_events_per_exec_call): New function, a - default, returns 1 - (child_has_exited): New function, a default. - (child_core_file_to_sym_file): New function, a default, returns NULL. - (child_ops): Initialize new target_ops vector fields to the - child* functions. - * infptrace.c: - (Call_ptrace): For HPUX, handle additional requests: Pt_CONTIN1, - PT_STEP1. - (require_notification_of_events): Add several signals to the - set of events requiring notification: Ptrace_SIGNAL, - PTRACE_EXEC, PTRACE_FORK, PTRACE_VFORK - (child_acknowledge_created_inferior): This function is only - defined if CHILD_ACKNOWLEDGE_CREATED_INFERIOR is defined. - (child_post_startup_inferior): Function is only defined if - CHILD_POST_STARTUP_INFERIOR is defiend. Also, now call - require_notification_of_events. - (child_create_catch_fork_hook): Deleted - (child_create_catch_vfork_hook): Deleted - (child_insert_fork_catchpoint): New function - (child_remove_fork_catchpoint): New function - (child_insert_vfork_catchpoint): New function - (child_remove_vfork_catchpoint): New function - (child_has_forked): Now enclosed by a CHILD_HAS_FORKED ifdef - (child_has_vforked): Now enclosed by CHILD_HAS_VFORKED ifdef - (child_can_follow_vfork_prior_to_exec): New function - (child_insert_exec_catchpoint): New function - (attach): Removed call to require_notification_of_events - (child_post_attach): New function, call to - require_notification_of_events moved here. - (child_pid_to_exec_file): New enclosed by CHILD_PID_TO_EXEC_FILE ifdef - introduced the concept of a saved_inferior_pid - (hppa_require_attach): Add some code to decide if gdb is already - attached to process. Can not figure this out via a ptrace call. - (hppa_insert_hw_watchpoint): New function - (hppa_remove_hw_watchpoint): New function - - * inftarg.c: - (child_attach_to_process): Change position in file - (child_detach_from_process): Change position in file - - * inftarg.c: - (child_attach_to_process): Changed parameter to child_wait call - - * inftarg.c: - (child_post_wait): New function declaration and definition - (ptrace_him): - - change return value to a void. - - change target_acknowledge_forked_child call to - target_acknowledge_created_inferior - - call target_post_startup_inferior rather than returning pid. - (child_attach_to_process): Change param name, fail_if_already_attached - -> after_fork. - Invert a couple of if-then-else statments. - Use REQUIRE_ATTACH macro - (child_attach): Change params in child_attach_to_process call - (child_require_attach): Change params in child_attach_to_process call - (child_detach_to_process): Change param name, - fail_if_already_attached -> after_fork. - Invert a couple of if-then-else statments. - Use REQUIRE_DETACH macro - (child_detach): Change params in child_detach_from_process call - (child_require_detach): Change params in child_detach_from_process - call - (child_post_startup_inferior): New function - (child_acknowledge_created_inferior): New function - (child_clone_and_follow_inferior): New function - (child_post_follow_inferior_by_clone): New function - (child_create_catch_fork_hook): New function - (child_create_catch_vfork_hook): New function - (child_has_forked): New function - (child_has_vforked): New function - (child_post_follow_vfork): New function - (child_stop): No longer a static function - (child_pid_to_exec_file): New function - - * inftarg.c: - (child_wait): Child_pid becomes related pid. return pid - rather than inferior_pid. Changes are in code handling fork - and vfork - - * inftarg.c: - Include gdb_stat.h and sys/unistd.h - (child_wait): New local variables. Check for live threads. - Check for syscall events - (child_thread_alive): No longer a static funct. - (ptrace_him): Remove some code inserted in snap3 - (child_create_inferior): Added a bunch of code to handle a - bad interaction between start-up-with-shell and the HP - catch-fork/catch-exec logic. I am ifdefing this for - HPUXHPPA for now. - (child_has_syscall_event): New default target_ops function - (child_enable_exception_callback): New default target_ops function - (child_get_current_exception_event): New default target_ops function - (child_ops): 3 new fields - - * inftarg.c: Remove HPUX_SNAP1 and HPUX_SNAP2 ifdefs - - * inftarg.c: Reverted previous change. - - * infttrace.c (hppa_remove_hw_watchpoint): Fix check for write - access hardware watchpoint. - - * infttrace.c (proc_wait): Rename from proc_wait. - - * infttrace.c (require_notification_of_exec_events): New function; - just notify of exec events, not all events, and just the specified - pid, don't include it's children. - (child_acknowledge_created_inferior): Call new function - require_notification_of_exec_events instead of - require_notification_of_events. - (child_post_startup_inferior): Call require_notification_of_events - - * infttrace.c: Changed all references to boolean to int. - Changed all references to TRUE and FALSE to 1 and 0. - - * irix5-nat.c (symbol_add_stub): Add params to call to - symbol_file_add. - - * jv-lang.c (get_dynamics_objfile): Add 2 more parameters to call - to allocate_objfile. - - * main.c (fputs_unfiltered): Changes to prevent cursor form - jumping around in the TUI. Altered where tuiTermUnsetup and - tuiTermSetup are called - - * main.c (fputs_unfiltered): Changed function so that it - checks to see if output is to a string buffer or to a - FILE stream and does the correct action (i.e. strcat or - fputs). Fixed params for fputs call. - - * main.c (fputs_unfiltered): Don't try to call the TUI's - CommandCharCount functions when the TUI isn't enabled. - - * main.c (fputs_unfiltered): Change FILE to GDB_FILE. - - * main.c (main): If the user gives the --version or --help flags, - disable the TUI. - - * main.c (tui_version, xdb_commands, dbx_commands): New variables. - (main): New command line arguments --tui, --xdb, --dbx; add call - to tyiCleanUp via tuiDo to main loop. - (fputs_unfiltered): Tui related changes. - - * main.c: Define 2 new global variables, gdb_stdout and gdb_stderr - of type GDB_FILE. - (main): Allocate space for and initialize gdb_stdout and gdb_stdin. - - * objfiles.c (find_pc_sect_section): Make end condition be less - than s->endaddr, not less than or equal to s->endaddr. - - * objfiles.c: - (allocate_objfile): 2 new parameters: User_loaded and is_solib. - When appropriate, record in the object file that it is user loaded. - The run command can use this information to purge object file - entries associated with the old inferior and keep user loaded - object files loaded via the add-symbol-file command. - (objfile_purge_solibs): New function. deletes all objectfile entries - that are not explicitly loaded by the user. - - * objfiles.c: - (objfile_relocate): Check for LOC_INDIRECT - (find_pc_sect_section): Change condition from - pc < s->endaddr to pc <= s->endaddr - - * objfiles.h: - New variables: User_loaded and is_solib - (OBJF_SHARED): New macro. used to distinguish objfile for - shared library from "vanilla" objfile. - (allocate_objfile): Add new parameters to function decl. - (objfile_purge_solibs): New function decl. - - * objfiles.h: Add some typedefs: Importentry, ExportEntry. - Add some new variables: Import_list, import_list_size, - export_list, export_list_size - - * osfsolib.c: - (symbol_add_stub): Added params to call to symbol_file_add - - * pa/hpux1020.mh (NATDEPFILES): Add corelow.o, symbol table and - solib files. - - * pa/hpux1100.mh (NAT_FILE): Use nm-hppah11.h. - (NATDEPFILES): Add symbol table and solib files. - - * pa/nm-hppah11.h: New file, HPUX11-only definitions. - - * pa/tm-hppa.h (proc_wait): Remove decl and macro. - - * parse.c (write_dollar_variable): Handle cases in which variables - besides the debugger ones start with $ and $$. - (parse_nested_classes_for_hpacc): New function. Parse a string that - is possibly a namespace / nested class specification. - (find_template_name_end): New function. - - * procfs.c: - (procfs_init_inferior): Return value is now a void. - - * procfs.c (procfs_ops): Initializing new target ops vector fields. see list below. - - * procfs.c: - (procfs_ops): Adding new target_ops vector fields and - removing a few. see list below - - * procfs.c: Added new fields to procfs_ops. - Necessary since we still have oldstyle initialization in - this file - - * pyr-tdep.c (pyr_do_registers_info): Change stdout to gdb_stdout. - (frame_locals_address): Change stderr to gdb_stderr. - (frame_args_addr): Ditto. - - * pyr-xdep.c (fetch_inferior_registers): Change stderr to - gdb_stderr. - - * serial.c (serial_close): Call gdb_fclose, not fclose on a - GDB_FILE. - - * serial.c (serial_logchar): Change chtype to ch_type. sigh. - - * solib.c (look_for_base): The parameter to file must be - of type FILE *. So cast exec_bfd -> iostream in the call - to fileno as a FILE *, not a GDB_FILE *. This will work because - exec_bfd -> iostream is declared and given a value in bdf and - bfd will continue to use FILE rather than GDB_FILE. - - * solib.c: - (solib_add): Remove references to exec_ops. - - * solib.c: - (solib_add): Update exec_ops.to_sections - - * solib.c: - (symbol_add_stub): Added params to call to symbol_file_add - - * solib.h: - (SOLIB_REMOVE_INFERIOR_HOOK): New macro. defined to 0. - functionality not implemented for this target. - - * solib.h: Added macro definitions. These macros generate - error messages for solaris?? - (SOLIB_CREATE_CATCH_LOAD_HOOK) - (SOLIB_CREATE_CATCH_UNLOAD_HOOK) - (SOLIB_HAVE_LOAD_EVENT) - (SOLIB_LOADED_LIBRARY_PATHNAME) - (SOLIB_HAVE_UNLOAD_EVENT) - (SOLIB_UNLOADED_LIBRARY_PATHNAME) - (SOLIB_IN_DYNAMIC_LINKER) - (SOLIB_RESTART) - - * somread.c (is_in_import_list): Ditto. - - * somread.c (som_symfile_read): Added some comments - - * somread.c (som_symfile_read): Read in import and export lists. - (som_symtab_read): Change test for dynamic executable. - (is_in_import_list): New function. Check if a given symbol name - is in the import list. - (init_import_symbols): New function. Read in and initialize the - som import list. - (init_export_symbols): New function. Read in and initialize the - som export list. - - * somread.c: - (som_symfile_read): Fix missing comment delimiters - - * somsolib.c (DLD_FLAGS_MAPPRIVATE): New macro. - Define bit of __dld_flags in HP-UX a.out files. - (DLD_FLAGS_HOOKVALID): Ditto. - (DLD_FLAGS_LISTVALID): Ditto. - (DLD_FLAGS_BOR_ENABLE): Ditto. - (som_solib_total_st_size): Cumulative size in bytes of the - symbol tables of all shared objects on the so_list_head list. - (som_solib_st_size_threshhold_exceeded): Threshold for adding symbols - for shlibs. - (som_solib_sizeof_symbol_table): New function. Computes size of - symbol table for a shlib. - (som_solib_load_symbols): New function. Load symbols from shlib. - (som_solib_add): Detect if __dld_list is not valid. - Record main program's symbol table size. - Load symbols if called from command line. - Keep threshold into account when loading shlib symbols. - (som_solib_create_inferior_hook): Use dld_flags macros. - (som_sharedlibrary_info_command): Let user know if symbols were - not loaded. - (som_solib_restart): Discard all the shlibs descriptors. - (_initialize_som_solib): Chenge help message for auto-solib-add - command. - Set threshold for symbol table to 50 megabytes. - - * somsolib.c (_initialize_som_solib): Added call to som_solib_restart. - (som_solib_restart): New function - (som_solib_in_dynamic_linker): New function - (som_solib_desire_dynamic_linker_symbols): New function - (som_solib_unloaded_library_pathname): New function - (som_solib_loaded_library_pathname): New function - (som_solib_library_pathname): New function - (som_solib_have_unload_event): New function - (som_solib_have_load_event): New function - (som_solib_create_catch_unload_hook): New function - (som_solib_create_catch_load_hook): New function - (som_solib_create_inferior_hook): Rewritten - dld_cache: New struct - addr_and_unwind_t: New struct - (find_unwind_entry) added prototype - - * somsolib.c (som_solib_create_inferior_hook): Introduce new local - msymbol2 and change some msymbol's to msymbol2's -- was clobbering - msymbol, passing a NULL to lookup_minimal_symbol_solib_trampoline, - and ultimately core dumping with a SEGV. - - * somsolib.c: - Include assert.h - (som_solib_mapped_entry): Additional comments for text_addr, - text_link_addr, text_end, and tsd_start_addr fields. Commenting - out 2 tsd fields, __data_start and __data_end. - (som_solib_add_solib_objfile): Add params to calls to symbol_file_add. - Add some code for distinguishing between a shared library and other - objfiles. This appears to be a prelude to thread local storage. - (som_solib_load_symbols): Changes to printf statement - enclosed by SOLIB_DEBUG ifdef. - (som_solib_add): Change comment to correctly specify path - to end.o -- /opt/langtools/lib/end.o. changes to printf statement - enclosed by SOLIB_DEBUG ifdef. - Removed several SOLIB_DEBUG ifdefs and the associated printfs. - Add code to find the start address for the object file's thread - local storage - (som_solib_create_inferior_hook): Fix warning messages use correct - path to end.o -- /opt/langtools/lib/end.o. Change control flow. - No longer user early returns from function is cases of error. - (reset_inferior_pid): New function - (som_solib_remove_inferior_hook): New function - (so_lib_thread_start_addr): New function. used for tsd. - - * somsolib.c: Removed references to ASSERT macro. - - * somsolib.c: Add debugging macro. - (struct som_solib_mapped_entry): Add new field tsd_start_addr. - (struct so_list): Added new field solib_addr. - (som_solib_add_solib_objfile): New function. - (som_solib_load_symbols): Rewritten. - (som_solib_add): Make sure we don't load the symbols in if the - threshold was exceeded. - (som_solib_get_solib_by_pc): New function. Return the address of - handle of the shared library. - (som_solib_restart): Disable breakpoints at restart. - (_initialize_som_solib): Set threshold to 100 megabytes. - - * somsolib.c: Add include of fcntl.h so that O_RDONLY is defined. - - * somsolib.h (DISABLE_UNSETTABLE_BREAK): New macro. - (PC_SOLIB): New macro. - - * somsolib.h: - (SOLIB_CREATE_CATCH_LOAD_HOOK): Define - (SOLIB_CREATE_CATCH_UNLOAD_HOOK): Define - (SOLIB_HAVE_LOAD_EVENT): Define - (SOLIB_LOADED_LIBRARY_PATHNAME): Define - (SOLIB_HAVE_UNLOAD_EVENT): Define - (SOLIB_UNLOADED_LIBRARY_PATHNAME): Define - (SOLIB_IN_DYNAMIC_LINKER): Define - (SOLIB_RESTART): Define - - * somsolib.h: - (SOLIB_REMOVE_INFERIOR_HOOK): New macro. defined to use - som_solib_remove_inferior_hook. - - * somsolib.h: - (som_solib_create_catch_load_hook) - (som_solib_create_catch_unload_hook) - (som_solib_have_load_event) - (som_solib_loaded_library_pathname) - (som_solib_have_unload_event) - (som_solib_unloaded_library_pathname) - (som_solib_in_dynamic_linker) - Fix prototypes to use type names, not parameter names. - - * source.c (find_source_lines): Make non static. - (open_source_file): Ditto. - (source_full_path_of): New function. - (print_source_lines): Rename to print_source_lines_base and make - static; formatting. - (print_source_lines): New function. - (forward_search_command): Tui changes. - (reverse_search_command): Tui changes. - (_initialize_source): Add xdb and dbx compatibility commands. - - * source.c (list_command): Handle case of odd number of source - lines to display. - - * source.c: - (source_full_path_of): New function. file was overlooked - in merge ;-/. - - * stack.c (func_command): Make high bound be <, not <=. - - * stack.c (_initialize_stack): For the backtrace command, delete - the help line about usage, since this has to be a valid help - message for the 'where' command too. - - * stack.c (current_frame_command): Add a check for the - existance of a stack. If there is no stack produce an - error message and exit. - - * stack.c (down_silently_base, up_silently_base, - args_plus_locals_info, print_frame_info_base, - print_stack_frame_base, print_stack_frame_base_stub): Declare. - (print_frame_local_vars): Add'l parameter. - (print_stack_frame_stub): New version created, old version renamed - to show_and_print_stack_frame_base_stub. - (print_stack_frame_base_stub, print_only_stack_frame_stub, - show_and_print_stack_frame, print_only_stack_frame, - stack_publish_stopped_with_no_frame, print_frame_info, - show_stack_frame, backtrace_full_command, args_plus_locals_info, - select_and_print_frame, select_and_maybe_print_frame, - current_frame_command, func_command): New functions. - (backtrace_command): New function, old renamed to - backtrace_command_1. - (print_block_frame_locals, print_frame_local_vars): Additional - parameter, number of tabs. - (up_silently_command): New function, old renamed to - up_silently_command_base. - (down_silently_command): New function, old renamed to - down_silently_base. - (_initialize_stack): Register new commands based on values of - xdb_commands and dbx_commands variables. - - * stack.c (func_command): Make high bound be <, not <=. - - * stack.c (parse_frame_specification): Fix prototype to match - function definition. - (show_and_print_stack_frame_stub): Fix name. - (select_and_print_frame): Change uncaught tuiDO call. - - * stack.c (up_silent_base): Rename from up_silently_command_base. - - * symfile.c (symbol_file_command): Only call SOLIB_RESTART if it's - defined. - - * symfile.c (add_psymbol_with_dem_name_to_list): New function. - Adds a symbol with a long value to a psymtab. Differs from - add_psymbol_to_list in taking both a mangled and a demangled name. - - * symfile.c (compare_psymbols): Call strcmp directly, instead of - using macro. - - * symfile.c (symbol_file_add): Reindent portions. - (symbol_file_command): Add call to tuiDo. - - * symfile.c (symbol_file_command): Only call SOLIB_RESTART if it's - defined. - - * symfile.c (symfile_bfd_open): Add code to call PXDB on hpux, if - the file has not already been processed by pxdb. - Added define USE_PXDB. - - * symfile.c (symfile_bfd_open): Change parenthesis positioning - around call to hpread_pxdb_check. - - * symfile.c (symfile_bfd_open): Make not static. - (RESET_HP_UX_GLOBALS): New macro. Resets globals when new symbol - file loaded. - (USE_PXDB): Not needed. Removed. - (symbol_file_add): Add HP specific code to deal with pxdb. - (symbol_file_command): Reset HP specific globals if new symbol file - loaded. - (symfile_bfd_open): Comment out checking for pxdb. - (reread_symbols): Reset HP specific globals. - - * symfile.c (symfile_bfd_open): Uncomment hpus specific code. - - * symfile.c: - (symbol_file_add): Add user_loaded and is_solib parameters. - fixed number of parameters in call to allocate_objfile - (symbol_file_command): Added call to SOLIB_RESTART macro. - fixed number of parameters in calls to symbol_file_add. - (add_symbol_file_command): Fixed number of parameters in calls to - symbol_file_add. - - * symfile.c: Added prototype for hpread_pxdb_check. - - * symfile.c: Changed HPUX_SNAP1 ifdef to HPUXHPPA. enclosed calls to - RESET_HP_UX_GLOBALS with an HPUXHPPA ifdef - - * symfile.h (symfile_bfd_open): Add protptype. - - * symfile.h: Add prototype for add_psymbol_with_dem_name_to_list. - - * symfile.h: Clarify purpose of auto_solib_add. - - * symmisc.c (maintenance_print_symbols): Call gdb_fclose, not - fclose on a GDB_FILE* during cleanup. - (maintenance_print_psymbols): Call gdb_fclose, not fclose on a - GDB_FILE* during cleanup. - (maintenance_print_msymbols): Call gdb_fclose, not fclose on a - GDB_FILE* during cleanup. - - * symmisc.c (maintenance_print_symbols): Gdb_fclose now takes a - GDB_FILE ** parameter. Fix the local GDB_FILE variables and the - call to make_cleanup. - (maintenance_print_psymbols): Ditto - (maintenance_print_msymbols): Ditto - - * symmisc.c (print_objfile_statistics): Close quotes in - output strings. - - * symmisc.c: - (Print_symbol): Add LOC_INDIRECT to switch statement - (print_partial_symbols): Add LOC_INDIRECT to switch statement - - * symtab.c (find_pc_sect_psymtab): High bounds should be <, not <=. - (find_pc_sect_symtab): Ditto. - - * symtab.c (hp_som_som_object_present): New flag to indicate HP - compiled code. - (find_pc_sect_psymtab): Change tests to make sure we are checking - the texthigh adress as well. - (lookup_transparent_type): New function. Look up a type name - in the struct_namespace. The type returned must not be opaque. - (find_pc_sect_symtab): Make sure we check the address 'pc' itself, - too. - (find_addr_symbol): Prepare to handle LOC_INDIRECT address class, but - leave it commented out. - (find_pc_sect_line): Return correct information if pc is in import - or export stub (trampoline). - (decode_line_1): Skip two chars, if they are '$$'. Like for HP's - $$dyncall. Handle cases in which varaible and function names can start - with $. - (overload_list_add_symbol): If cannot demangle name, use it as is. - Free string after use. - (make_symbol_overload_list): Initialize oload_name to NULL and - oload_name_len to 0. If demangle not successful, use name as it is. - Free string after use. - - * symtab.c (lookup_symbol): Changed call to find_pc_sect_symtab, - to the original find_pc_symtab, in HP added fragment. - - * symtab.c (lookup_symbol): Change HPUX_SNAP1 ifdef to a HPUXHPPA ifdef - - * symtab.c (lookup_symbol): Ifdef the searching of symbol in the - minimal symbol tables, for hpux we move this check at the end - of the function. - Before we error out if symbol is not found in the symtab, look - in the statics. - Before erroring out if static symbol not found look in the globals. - - * symtab.c (lookup_symbol): Return symbol as soon as found. - (decode_line_1): Check whether we have a conditional break. Temporarily - remove it from the line, to not confure perenthesis checking. - Handle namespaces. - (overload_list_add_symbol): New function. Overload - resolution support. - (make_symbol_overload_list): Ditto. - - * symtab.c: - (find_template_name_end): New prototype decl. - (lookup_symbol): When a global or static symbol shows up in the - psymtab table, but not the symtab table, tell the user that - the symbol may be an inlined function or a template function and - provide some guidance to the user about how to more fully - specify the symbol. - (lookup_transparent_type): When a global or static symbol shows up - in the psymtab table, but not the symtab table, tell the user that - the symbol may be an inlined function or a template function and - provide some guidance to the user about how to more fully - specify the symbol. - (decode_line_1): Handle template function specification when decoding a - line. May need to be ifdefed for HP's aCC? - (_initialize_symtab): Handle dbx commands. - - * symtab.h (address_class): Add new address calss for - LOC_THREAD_LOCAL_STATIC and LOC_INDIRECT. - (lookup_transparent_type): Add prototype. - (exception_event_kind): New enum for exception catchpoints. - (exception_event_record): New structure for exception catchpoints. - (CURRENT_EXCEPTION_KIND): New macro. - (CURRENT_EXCEPTION_CATCH_SAL): New macro. - (CURRENT_EXCEPTION_CATCH_LINE): New macro. - (CURRENT_EXCEPTION_CATCH_FILE): New macro. - (CURRENT_EXCEPTION_CATCH_PC): New macro. - (CURRENT_EXCEPTION_THROW_SAL): New macro. - (CURRENT_EXCEPTION_THROW_LINE): New macro. - (CURRENT_EXCEPTION_THROW_FILE) new macro.: - (Current_EXCEPTION_THROW_PC): New macro. - - * symtab.h(make_symbol_overload_list): Add prototype. - - * symtab.h: - (symbol_file_add): Add new params to function decl. - - * target.c (cleanup_target): Changed casting of default functions for - to_has_forked, to_has_vforked, to_pid_to_exec_file to get rid of - warnings. - - * target.c (cleanup_target): Changed the default functions for - to_pid_to_exec_file and to_core_file_to_sym_file - - * target.c (cleanup_target): Fixed PARAMS for to_has_syscall_event - - * target.c (cleanup_target): Syntax error, mismatched paranthesis. - - * target.c: - (Default_clone_and_follow_inferior): New funct prototype declaration - and function definition - (dummy_target): More target_ops vector changes for HPUX - new fields. ifdefed for HPUX_SNAP2. New fields are - to_post_wait, to_post_startup_inferior - to_acknowledge_created_inferior, to_clone_and_follow_inferior, - to_post_follow_inferior_by_clone, to_create_catch_fork_hook, - to_create_catch_vfork_hook, to_has_forked, to_has_vforked, - to_post_follow_vfork, to_pid_to_exec_file - (de_fault): Add new HPUX specific target_ops operations to - the de_fault macro - (INHERIT): Add new HPUX specific target_ops operations to the - INHERIT macro - (find_default_clone_and_follow_inferior): New funct definition - (debug_to_post_wait): New funct - (debug_to_post_startup_inferior): New funct - (debug_to_acknowledge_created_inferior): New funct - (debug_to_clone_and_follow_inferior): New funct - (debug_to_post_follow_inferior_by_clone): New funct - (debug_to_create_catch_fork_hook): New funct - (debug_to_create_catch_vfork_hook): New funct - (debug_to_has_forked): New funct - (debug_to_has_vforked): New funct - (debug_to_post_follow_vfork): New funct - (setup_target_debug): Initialize new target_ops vector fields. - - * target.c: - (Cleanup_target): Fixed the return type on a few of the - default function values. - - * target.c: - (Dummy_target): Add 3 new fields - (nosupport_runtime): New function, used in cleanup_target - (cleanup_target): Changes in the de_fault macro, both to - accomodate the new target_ops vector fields and to use - more accurate default functions. - (update_current_target): Add new target_ops vector fields to the - INHERIT macro - (generic_mourn_inferior): The call to breakpoint_init_inferior now takes a - parameter - (normal_pid_to_str): Adding a \0 to the end of buf. - (debug_to_has_syscall_event): New func - (debug_to_enable_exception_callback): New func - (debug_to_get_current_exception_event): New func - (setup_target_debug): Initialize the 3 new target_ops vector fields - - * target.c: - (Struct signals): Fix message associated with SIGRETRACT. - - * target.c: - (Dummy_target): Fix syntax error - (cleanup_target): Changed the default values for the new - target_ops vector fields. HP folks inappropriately set - most of them to noprocess(). They should be a mixture - of ignore() and return_zero(). - - * target.c: - (Dummy_target): Add new target_ops vector fields and their initializations - (cleanup_target): Added new new target_ops vector fields to the de_fault - macro definition. - (update_current_target): Added new new target_ops vector fields to the INHERIT - macro definition - (return_one): New function, used by the de_fault macro - (debug_to_post_attach): New function - (debug_to_wait): Added new cases: Target_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED, - TARGET_WAITKIND_EXECD - (debug_to_insert_fork_catchpoint): New function - (debug_to_remove_fork_catchpoint): New function - (debug_to_insert_vfork_catchpoint): New function - (debug_to_remove_vfork_catchpoint): New function - (debug_to_can_follow_vfork_prior_to_exec): New function - (debug_to_insert_exec_catchpoint): New function - (debug_to_remove_exec_catchpoint): New function - (debug_to_core_file_to_sym_file): New function - (setup_target_debug): Give new fields in current_target target_ops vector values. - - * target.c: Hp merge, 4/15/98 snapshot - There are new target_ops fields that pertain only - to HPUX. All the changes relate to this. First, - new fields are added to the dummy_target target_ops - vector: To_require_attach, to_require_detach. - - * target.c: Remove HPUX_SNAP1 and HPUX_SNAP2 ifdefs - - * thread.c (info_threads_command): Call print_only_stack_frame - instead of print_stack_frame. - (_initialize_thread): Make t an alias for thread only if - xdb_commands is not set. - - * thread.c (thread_command): If no arguments, don't generate an - error, instead tell the user which thread is current. - (info_threads_commands): Don't lose the users position within the - current thread -- remember it and then restore it. - - * thread.c: - (struct thread_info): Add stepping_through_sigtramp field - (add_thread): Initialize stepping_through_sigtramp field - (load_infrun_state): Add stepping_through_sigtramp param and - make sure it gets assigned a value. - (save_infrun_state): Add stepping_through_sigtramp param and - make sure that the value gets saved. - (info_threads_command): Ifdefing some local variables and - code for HPUXHPPA. HP folks want print the tid rather than pid? - Also, looks like the HP folks solved the same thread switching - problem that 4.17 solves. Taking 4.17. - (restore_current_thread): Print out the current frame after - switching threads. - (thread_apply_all_command): Ifdefing a print statement for - HPUXHPPA. The HP folks want to print out a tid rather than pid? - (thread_apply_command): Ifdefing a print statement for - HPUXHPPA. The HP folks want to print out a tid rather than pid? - (thread_command): Decided not to take HP change. - - * thread.c: Fixing gdb core dump problem causing many testsuite - failures. - (add_thread): Remove call to bpstat_clear, initialize - tp->stepping_through_solib_catchpoints = NULL; - - * thread.c: Changes for catchpoints, shared libaries, - (thread_info): Additional fields in the thread_info struct - for stepping_through_solib_after_catch and - stepping_through_solib_catchpoints. - (add_thread): Initialize the new thread_info fields. - (load_infrun_state): Additional parameters for handling - catchpoints and shared libraries. - (save_infrun_state): Additional parameters for handling - catchpoints and shared libraries. - - * top.c (command_loop): Initialize space_at_cmd_start to 0. - (set_prompt): New function. - (togglelist, stoplist): New command lists. - (command_loop): Tui changes -- paranoia to make sure - insert mode is off when not editing. - (quit_force): Clean up tui on exit. - (init_main): Make definition of info status command dependent upon - dbx mode not being set. - (fputs_unfiltered_hook): Changed stream parameter from FILE - to GDB_FILE - (flush_hook): Changed stream parameter from FILE to GDB_FILE - - * top.h (set_prompt): Declare. - - * typeprint.c (whatis_exp): Decide real runtime type. For the vtable - case. - - * utils.c (query): Changes to prevent cursor from jumping around in the - TUI. Call tuiBufferGetc explicitly, rather than passing it - into tuiDo. The tuiDo function does some additional work - that is inappropriate when handling queries. - (GDB_FILE_ISATTY): New macro that takes a GDB_FILE param and - determines whether or not it's using a tty. - (gdb_file_isatty); called by the GDB_FILE_ISATTY macro. Does - the actual work - (init_page_info): Call GDB_FILE_ISATTY rather than ISATTY - (print_spaces): Fix parameter to fputc. fix call to - gdb_file_adjust_strbuf. - (gdb_file_init_astring): Fix parameter to xmalloc - (gdb_file_deallocate): New function to deallocate - a GDB_FILE object and possibly a string buffer - (gdb_file_init_astring): Initialize buffer as the empty - string. Indent GNU style. - (gdb_fopen): Gdb_fopen is called if the GDB_FILE object is - actually afile rather than astring. The routine now allocates space - for a GDB_FILE object and initializes its fields in addition to - performing an fopen. - (gdb_flush): Fix the parameter passed into fflush. It's now - stream->ts_filestream. - (gdb_fclose): Pass in an object of type GDB_FILE **. Fix parameter - to fclose. It's now tmpstream->ts_filestream. Make sure to free - the GDB_FILE object and set the GDB_FILE * object to NULL. - (gdb_adjust_strbuf): New function. Determine if the current - ts_strbuf field contains sufficient space to concatenate a string - of length n on the end. If not, then reallocate the ts_strbuf. - (print_spaces): Check to see if the GDB_FILE is afile or - astring. If it is astring, then adjust the size of the ts_strbuf - field and concatenate the correct number of spaces onto the end of - the buffer. Otherwise continue to use fputc. - (gdb_file_get_strbuf): New function. return a ptr to the ts_strbuf - field in a GDB_FILE object. - (gdb_file_init_astring): New function to allocate space for and - initialize a GDB_FILE object when it is an astring. - (set_width): Declare it. - (pagination_enabled): Define it. - (query): Tui changes. - (init_page_info, set_width): New functions. - (set_width_command): Call set_width. - (_initialize_utils): Replace termcap stuff with call to - init_page_info; if xdb_commands set, define am and sm commands; - define pagination as a set/show command. - (vfprintf_maybe_filtered): Change FILE to GDB_FILE. - (fputs_maybe_filtered): Ditto. - (print_spaces): Ditto. - (gdb_printchar): Ditto. - (gdb_flush): Ditto. - (fputs_filtered): Ditto. - (vfprintf_filtered): Ditto. - (vfprintf_unfiltered): Ditto. - (fprintf_filtered): Ditto. - (fprintf_unfiltered): Ditto. - (fprintfi_filtered): Ditto. - (print_spaces_filtered): Ditto. - (fprintf_symbol_filtered): Ditto. - (gdb_fclose): New function. - - * valops.c (call_function_by_hand): Assign to param_type only - if function has parameters. - - * valops.c (call_function_by_hand): Ifdef the - HP_COMPILED_TARGET stuff. - (value_arg_coerce): Ditto. - - * valops.c (call_function_by_hand): Make sure param_type is - initialized to NULL. - - * valops.c (find_rt_vbase_offset): Add parameter to value_at. - (value_rtti_type): Ditto. - (value_full_object): Ditto. - - * valops.c (search_struct_field_aux): Fixed mismatching parenths - - * valops.c (search_struct_field_aux): Make sure TYPE_TAG_NAME - is not null before copying it. - - - * valops.c (search_struct_field_aux): Set found_class_name to null - if class has no name (anon unions case). Adjust base_addr - computation. - - * valops.c (value_arg_coerce): Change final arg to int. - - * valops.c (value_arg_coerce): Remove the conditional on HP - compiled target, for doing coercion of float to double. Removed - third parameter, using_gcc. - (call_function_by_hand): Do not use HP_COMPILED_TARGET, just - use the gcc_compiled variable. - - * valops.c (value_cast): Take case of the enclosing_type and - pointer_to_offset fields. - (value_at): Use VALUE_CONTENTS_ALL_RAW - (value_fetch_lazy): Ditto - (value_assign): Handle enclosing_type, embedded_offset and - pointed_to_offset fields. - (value_repeat): Use VALUE_CONTENTS_ALL_RAW and VALUE_ENCLOSING_TYPE. - (value_ind): Set enclosing_type and embedded_offset correctly, - for a pointer value being dereferenced. Target memory bytes - corresponding to the size of the enclosing type are retreived. - (value_addr): Handle enclosing_type and pointed_to_offset. - (value_push): Use VALUE_CONTENTS_ALL and VALUE_ENCLOSING_TYPE. - (value_arg_coerce): Coerce floats to doubles only if gcc was not - used to compile the target. - (call_function_by_hand): Handle pointers to functions as paramters. - (value_array): Use VALUE_CONTENTS_ALL and VALUE_ENCLOSING_TYPE. - (search_struct_method): Produce more informative error message. - (find_rt_vbase_offset): Deal with negative offsets. - (value_find_oload_method_list): New function. Return the list of - overloaded methods of a specified name. - (find_method_list): New function. Search through the methods of an - object (and its bases) to find a specified method. - (value_full_object): New function. Given a value, check its real - run-time type. - (value_rtti_target_type): New function. Given a pointer value V, find - the real (RTTI) type of the object it points to. - (value_rtti_type): New function. Find the real run-time type of a - value using RTTI. - - * valops.c: Include gdbcmd.h - Set global overload_resolution to 0. - (find_function_in_inferior): Modify error message. - (value_allocate_space_in_inferior): Modify error message. - (value_cast): Deal with HP/aCC peculiarities. - (value_of_variable): Use SYMBOL_SOURCE_NAME instead of SYMBOL_NAME. - (value_addr): Modify address value by adding the embedded offset. - (value_ind): Modify the address of the object by the pointed_to_offset. - (call_function_by_hand): Do not do any extra alignment if not needed. - Fetch the return value from the stack rather then from the register, - for the hppa architecture. - (search_struct_field): Rewritten. Now this function uses - search_struct_field_aux to do all the work. - (search_struct_field_aux): New function. This is the old - search_struct_field rewritten. - (find_rt_vbase_offset): Give error if virtual table pointer is not good. - (find_overload_match): New function. Find the best function that - matches on the argument types according to the overload resolution - rules. - (_initialize_valops): Add new set/show command for overload-resolution. - - * value.h (VALUE_POINTED_TO_OFFSET): New macro. - Add field pointed_to_offset to value structure. - Add prototypes for new functions in valops.c. - - * value.h (write_register_pid): Change prototype to match - function. - - * value.h: Hp merge, 4/15/98 snapshot - Added parameter to val_print func decl. - Added new macro, VALUE_EMBEDDED_OFFSET, and - new func decl, find_rt_vbase_offset, for C++ - support. - - * values.c (allocate_value): Allocate also for value_embedded_offset - and value_enclosing_type. - (value_copy): Copy value_embedded_offset and value_enclosing_type too. - Use all_raw in copying the value itself. - (value_primitive_field): Add handling of base subobjects. - - * values.c (value_copy): Copy the pointed_to_offset as well. - (allocate_value): Allocate the pointed_to_offset as well. - (value_virtual_fn_field): Rewrite. - - * values.c (value_primitive_field): Adjust embedded offset and - offset calculation. - - * values.c (value_static_field): Take into consideration that static - data members can be minimal symbols too. - - * values.c (value_virtual_fn_field): Fix call to value_at. - - * win32-nat.c (handle_load_dll): Added params to call to symbol_file_add. - - Other changes have to do with XDB compatability. Leave oout - for now. - - defs.h (vfprintf_filtered): Change FILE to GDB_FILE in decl. - (fprintf_filtered): Ditto. - (fprintfi_filtered): Ditto. - (vfprintf_unfiltered): Ditto. - (fprintf_unfiltered): Ditto. - - infcmd.c (_initialize_infcmd): If xdb_commands is set, make S an - alias for next and define R, lr, g. Define go. - - pyr-tdep.c (pyr_print_insn): Change FILE to GDB_FILE. - - - * breakpoint.c (create_temp_exception_breakpoint): #If it out -- - nothing calls it. - (bpstat_stop_status): Don't call SOLIB_HAVE_LOAD_EVENT if it's not - defined; don't call SOLIB_HAVE_UNLOAD_EVENT if it's not defined. - (bpstat_get_triggered_catchpoints): If we don't have shared - library support, then don't call SOLIB_LOADED_LIBRARY_PATHNAME nor - SOLIB_UNLOADED_LIBRARY_PATHNAME. - (watch_command_1): Don't require a run before a watch command - unless we're on HP [it's an HP OS bug, not a generic limitation] - (catch_load_command_1): Don't define if no shared libraries. - (catch_command_1): Don't claim to support fork catchpoints unless - CHILD_INSERT_FORK_CATCHPOINT is defined, don't claim to support - vfork catchpoints unless CHILD_INSERT_VFORK_CATCHPOINT is defined, - don't clain to support shared library load catchpoints if shared - libraries aren't supported, and don't claim to support exec - catchpoints unless CHILD_INSERT_EXEC_CATCHPOINT is defined - - There are new target_ops vector fields that pertain - only to HPUX. Added the to_require_attach and - to_require_detach fields to exec_ops. These new - fields are ifdef'ed for HPUX_SNAP1. - - * breakpoint.h: - Fix compile error in enum bptype. - - * coff-solib.h: - Fixed a number of macro definitions. SOLIB_LOADED_LIBRARY_PATHNAME, - SOLIB_HAVE_LOAD_EVENT, SOLIB_HAVE_UNLOAD_EVENT, - SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_IN_DYNAMIC_LINKER. These - macros are only meaningful (for now) for SOM. So, all - the macros were defined as error(...), but were used in - conditions. This caused the compile to crap out. I redefined - these (for now) to be 0. - - * procfs.c: - (procfs_create_inferior): Fix call to fork_inferior -- need another - parameter. - - * solib.h: - Fixed a number of macro definitions. SOLIB_LOADED_LIBRARY_PATHNAME, - SOLIB_HAVE_LOAD_EVENT, SOLIB_HAVE_UNLOAD_EVENT, - SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_IN_DYNAMIC_LINKER. These - macros are only meaningful (for now) for SOM. So, all - the macros were defined as error(...), but were used in - conditions. This caused the compile to crap out. I redefined - these (for now) to be 0. - - * valops.c: - (search_struct_field): Undeclared local variable, "assigned". - (find_rt_vbase_offset): Fixed call to value_at - - * value.h: Fix signature for find_rt_vbase_offset funct decl - (missing a param) - -Wed Dec 30 17:48:12 1998 Stan Shebs - - From J.T. Conklin : - * i386-stub.c: Fix error string in last change. - -1998-12-30 Jason Molenda (jsm@bugshack.cygnus.com) - - * utils.c: instead of "readline/readline.h". - - * configure.in (TERM_LIB): Search for the appropriate term library - on the host system. - * configure: Regenerated. - * Makefile.in (TERMCAP): Set based on autoconf check. - * config/*/*.mh: Don't override TERMCAP setting. - -Wed Dec 30 17:23:14 1998 Mark Alexander - - * value.c (value_virtual_fn_field): Handle the situation where - vtbl is a pointer to a structure instead of a pointer to an array. - -Mon Dec 28 17:43:36 1998 David Taylor - - The following changes were made by Jim Blandy , - Edith Epstein , Elena Zannoni - Stan Shebs , and David - Taylor , as part of the project to merge in - changes originally made by HP; HP did not create ChangeLog - entries. - - * c-lang.h (cp_print_value_fields): Update prototype; fixed - prototype decl for c_val_print function -- it needed an - embedded_offset param; fixed prototype of cp_print_value_fields. - Include value.h. - (C_LANG_H): Define. - - * c-valprint.c (c_val_print): Add new parameter embedded_offset. - Add embedded_offset to valaddr in function calls. fix calls to - val_print, and cp_print_value_fields. Attempt to determine the - real type of the object to be printed. fixed call to - cp_print_value_fields. process TYPE_CODE_METHOD as well. moved - call to check_typedef out of conditional. add embedded offset - param to val_print call. - - (c_value_print): Add new parameter to call to val_print. Handle - pointer to class case. Ensure that const char *, const unsigned - char * come out without the type but the volatile variants and the - signed variants don't. - - * ch-lang.h (chill_val_print): Add parameter to decl. - - * ch-valprint.c: The various print routines have an additional - parameter. Currently, the new parameter is only used when printing - C++ expressions. So, in ch-valprint.c, the new parameter is always - 0. Changes in calls to val_print, chill_val_print, c_val_print - Affected functions are chill_val_print_array_elements, - chill_val_print, chill_print_value_fields, chill_value_print. - - * cp-valprint.c add vtable pointers names for aCC (HP) compiler. - (cp_print_class_method): Print message for HP/aCC case. - (cp_print_class_member): Add comments. - (cp_print_value): Adjust address computations for virtual base - classes. add new parameter 'offset'. Find correct offset for - base class in HP/aCC case. Change call to cp_print_value_fields - to have extra par. - (cp_print_value_fields): Do not print also if the only field is - the vtable pointer. Print out vtable ptr, for HP/aCC compiled - case. do not print leading '=' in case of anonymous union, or - struct. add new parameter 'offset'. Do not print the vtable - pointer as a member, in the HP aCC case. Changed calls to - val_print to have extra parameter. - (cp_print_hpacc_virtual_table_entries): New function. Print vtable - entries, in HP/aCC compiled case. - (cp_print_static_field): Change call to cp_print_value_fields, and - val_print. - - * d30v-tdep.c (d30v_print_register): Add embedded_offset param - to val_print call. - - * defs.h: Additional include files included when TUI is defined. - (gdb_file_isatty): New function decl. - (GDB_FILE): If TUI is defined, define a structure rather - than making this an alias for FILE. - (gdb_stdout, gdb_stderr): If TUI is defined, then define these - as pointers to variables of type GDB_FILE rather than making them - be aliases for stdout and stderr. - (TUIDO): Add definition conditionalized on definition - (or lack thereof) of TUI. - (command_class): Add two additional values. - (precision_type): New enum. - (gdb_fclose): Add decl. - (store_address): Change prototype to match function. - (tui_version, xdb_commands, dbx_commands): Add decls. - (gdb_file_deallocate): New function decl - (pa_do_strcat_registers_info): New function decl. - (streamtype): New enumerated type to distinguish between output to - a FILE and output to a buffer. - (tui_stream): New struct type, named GDB_FILE. - (gdb_stdout): Of type GDB_FILE, will pass this around gdb rather - than stdout. - (gdb_stderr): Of type GDB_FILE, will pass this around gdb rather - than stderr. - (fputs_unfiltered_hook): Change stream parameter from FILE to - GDB_FILE. - (flush_hook): Change stream parameter from FILE to GDB_FILE. - (gdb_fclose): Fix decl for gdb_fclose; parameter is now of - type GDB_FILE **. - (gdb_file_adjust_strbuf): New function decl. function lives - in utils.c. - (gdb_file_init_astring): New function decl. function lives - in utils.c. - (gdb_file_get_strbuf): New function decl. function lives in - utils.c. - (source_full_path_of): Declare. - - * exec.c (_initialize_exec): Make definition of file command be - dependent upon dbx_commands not being set. - (exec_file_attach): New function. - (exec_file_command): Call it. - (exec_ops): Add new target vector fields. - - * f-lang.h (f_print_type): Change FILE to GDB_FILE in decl. - (f_val_print): Ditto. - (f_val_print): Add parameter to the function decl. - - * f-valprint.c (_initialize_f_valprint): If xdb_commands is set, - define lc command. - (f77_create_arrayprint_offset_tbl): Change FILE to GDB_FILE. - (f77_print_array): Ditto. - (f77_print_array_1): Ditto. - (f_val_print): Ditto. - (f_val_print): Add a parameter; this new parameter is currently - only non-zero when handling C++ expressions. In this file its - value is always 0. changed fflush to gdb_flush. - - * gnu-nat.c: (init_gnu_ops): Add new target vector fields. - (gnu_create_inferior): Add param to fork_inferior call. - - * hppa-tdep.c (after_prologue): If f is NULL, don't dereference - it. if no debug info, return zero telling caller that we need to - find the end of the prologue via the hard way (instruction - examination). - (find_unwind_entry): Avoid dereferencing a null - pointer. - (hppa_pid_to_exec_file): Deleted -- no longer used. - (hppa_prepare_to_proceeed): Add prototype. - (read_unwind_info): Purecov comments, bug fixes. - (find_unwind_entry): Purecov comments, bug fixes. - (find_stub_with_shl_get): Purecov comments. - (frame_chain): Additional parens. - (hppa_push_arguments): Changes to commented out version of routine. - (hppa_fix_call_dummy): Purecov comments, fix location of end.o. - (in_solib_call_trampoline): Purecov comments. - (in_solib_return_trampoline): Purecov comments. - (setup_d_pid_in_inferior): Fix location of end.o. - (initialize_hp_cxx_exception_support): Fix location of end.o. - (child_enable_exception_callback): Purecov comments. - (pa_do_strcat_registers_info): Has a new parameter, precision, - which is passed into the call to pa_strcat_fp_reg to indicate - whether to display the floating point registers using - single or double preceision. - (pa_strcat_registers): Introduce local variable, precision, and - pass it into call to pa_strcat_fp_reg. - (pa_strcat_fp_reg): Modified function. New parameter, precision, - used by function to decide whether to use single or double - precision. Also add the code to put a double precision value - into a buffer. - (pa_do_strcat_registers_info): New routine. called by - tui/tuiRegs.c:_tuiRegisterFormat to place a register name - and value into a string buffer. Interface may change in - future. Checking this in so that we have something - functional for HP. - (pa_strcat_registers): New routine, called by - pa_do_strcat_registers_info. Does same thing as - pa_print_registers except it takes a stream parameter. - This routine should disappear in future. Checking in - so that we have something functional to give HP - (pa_strcat_fp_reg): New routine, called by - pa_do_strcat_registers_info and pa_strvat_registers - to place a floating point register name and value into - a buffer. This interface may change in future. - Checking in so that we have something functional to give HP. - (pa_print_fp_reg): Change prototype to match def'n. - (pa_register_look_aside): Fix comment immediately before function. - Changes to better support stack unwinding, reading and writing - registers for HPUX. New includes ptrace.h, bfd.h, dl.h. - (internalize_unwinds): Initialize new fields in table. - (read_unwind_info): Entries in the table are now more complex - structures. References of the form ...->table[index].stub_type are - now ...->table[index].stub_unwind.stub_type. - (find_proc_framesize): Add a check for pc == 0. - (rp_saved): Entries in the table are now more complex - structures. References of the form ...->table[index].stub_type are - now ...->table[index].stub_unwind.stub_type. - (frameless_function_invocation): Stub_type becomes - stub_unwind.stub_type - (saved_pc_after_call): Stub_type becomes stub_unwind.stub_type - (hppa_frame_saved_pc): Stub_type becomes stub_unwind.stub_type - (frame_chain_valid): Stub_type becomes stub_unwind.stub_type - (hppa_call_dummy): Stub_type becomes stub_unwind.stub_type - (pa_print_fp_reg): Additional params to call val_print - (in_solib_call_trampoline): Stub_type becomes - stub_unwind.stub_type - (in_solib_return_trampoline): Stub_type becomes - stub_unwind.stub_typ - (skip_trampoline_code): Additional code to handle external - dyncalls. Also stub_type becomes stub_unwind.stub_type - (hppa_pid_to_exec_file): New funct. FOr HPUX 10.0 and beyond there - is an explicit ptrace request for getting the pathname associated - with a process id (pid). - (hppa_pid_to_exec_file): Remove unwanted param from call to - call_ptrace. - (args_for_find_stub): New structure. - (find_unwind_entry): Deal with null input pc value. - (rp_saved): Ditto. - For the import stub, return -24 always. - (hppa_frame_saved_pc): Save old pc value, to detect we are in a loop. - (init_extra_frame_info): Use TARGET_READ_FP. - (frame_chain): Include thread support. - If the caller's pc is zero, we lose and return, just like stack - bottom. - Disable warning about being unable to find unwind info. - (hppa_push_arguments): Rewrite. - (hppa_value_returned_from_stack): New function. Handles returning - a value larger than 64 bits, stored on the stack. - (find_stub_with_shl_get): New function. To look up symbols in shlibs. - (cover_find_stub_with_shl_get): New function. Cover routine for - find_stub_with_shl_get to pass to catch_errors. - (hppa_fix_call_dummy): Comment out old stub mechanism. - Rewrite using dyncall. - (target_read_fp): New function. - (pa_do_registers_info): Floating point registers start at FP4. - (pa_print_registers): Use FP4_REGNUM instead of 72. - (skip_trampoline_code): Do machine instruction matching for PA2.0. - (setup_d_pid_in_inferior): New function. Exception handling support. - (initialize_hp_cxx_exception_support): Ditto. - (child_enable_exception_callback): Ditto. - (child_get_current_exception_event): Ditto. - - * hpux-thread.c (hpux_thread_ops): Add new target vector fields. - - * infcmd.c: Include objfiles.h. - (attach_command): New local variable, exec_file, add code to - determine exec_file from pid if exec_file is not already known, - call new target operation, target_post_attach -- a no-op unless - on HPUXHPPA. - (detach_command): After detaching, do a SOLIB_RESTART. - (objfiles.h): Fix typo on include line. - (run_command): Only call SOLIB_RESTART if it's defined. - (detach_command): Ditto. - (run_command): If program has already been started, and decide - to restart it, the kill the target, flush the caches, - call init_wait_for_inferior. Also purge old solib objfiles. - (run_stack_dummy): Add calls to - disable_watchpoints_before_interactive_call_start and - enable_watchpoints_after_interactive_call_stops. - (finish_command): Alter code handling the evaluation and printing - of the target function's return value. - (attach_command): When given a pid, but no exec file, try to - determine the exec file from the process. If the process does not - record a full path name, try to qualify the filename against the - source path. - (_initialize_infcmd): Add some verbiage about how to use the - attach command. - (do_registers_info): Changed calls to val_print - made the symfile.h include preceed the - objfiles.h include. The other ordering caused a - compile problem (incompletely defined types). - - * inftarg.c (child_post_attach): Fix decl, make static. - (proc_wait): Make globally visible. - (child_insert_fork_catchpoint, etc): Fix return type. - (child_detach_from_process): Declare. - (child_attach_to_process): Declare. - (child_stop): Make static to match decl. - (ptrace_him): Change prototype back to return int. - (ptrace_me): Remove debug output, pass NULL to fork_inferior if - not HPUX. - (proc_wait): function prototype and definition are enclosed by - proc_wait ifndef - (child_attach_to_process): New function, does most of the work - that child_attach used to do and some additional work to determine - whether gdb is already attached to the target how to react. - (child_attach): Altered. It's now a wrapper for - child_attach_to_process. - (child_require_attach): New function, called if should attach even - when gdb is already attached to target. - (child_detach_from_process): New function, does most of the work - that child_detach used to do and some additional work to determine - whether gdb is currently attached to the target. - (child_detach): Altered. It's now a wrapper for - child_detach_from_process. - (child_require_detach): New function, called if should try to - detach even when gdb is not attached to target. - (ptrace_him): Calls a new function, - target_acknowledge_forked_child. Currently, - target_acknowledge_forked_child, is only defined to do something - for HPUX. - (child_create_inferior): Changed call to fork_inferior. - (child_ops): Add to_require_attach and to_require_detach fields - to the child_ops target ops vector. - Some hacks for ttrace work: - (child_wait): Additional local variables, additional code in - while loop to check for process exited, process forked, - process vforked, process execd. - (child_thread_alive): John B. seems to think that the kill - call is inapproapriate for HPUX. - (child_attach_to_process): Using strtol rather than atoi. - no longer check for case where there is no known exec file. - (child_post_attach): New function, a default, a no-op. - (child_insert_fork_catchpoint): New function, a default, a no-op. - (child_remove_fork_catchpoint): New function, a default, a no-op. - (child_insert_vfork_catchpoint): New function, a default, a no-op. - (child_remove_vfork_catchpoint): New function, a default, a no-op. - (child_can_follow_vfork_prior_to_exec ):new function, a default, - a no-op. - (child_insert_exec_catchpoint): New function, a default, a no-op. - (child_remove_exec_catchpoint): New function, a default, a no-op. - (child_has_execd): New function, a default, returns 0. - (child_reported_exec_events_per_exec_call): New function, a - default, returns 1. - (child_has_exited): New function, a default. - (child_core_file_to_sym_file): New function, a default, returns NULL. - (child_ops): Initialize new target vector fields. - - * jv-lang.h: (Java_val_print): Add embedded_offset param to func - decl. - - * jv-valprint.c: Changing calls to val_print to accomodate new param. - (java_value_print): Add embedded_offset param to val_print call - (java_print_value_fields): Add embedded_offset param to val_print - call. - (java_val_print): Add embedded_offset param. alter call to - c_val_print to accomodate embedded_offset param. - - * language.c (lang_bool_type): Return builtin_type_bool in c++ - case. - (unk_lang_val_print): Add embedded_offset param to - prototype decl and definition. - - * language.h (LA_VAL_PRINT macro, la_val_print function decl): - altered to accomodate the new parameter to the various print - functions. - - * m2-lang.h (m2_val_print): Add a parameter to the function decl. - - * m2-valprint.c (m2_val_print): Add a parameter. - This parameter is currently only used when evaluating C++ - expressions. So, it is always 0 in this file. - - * m3-nat.c (m3_create_inferior): Add param to fork_inferior call - (m3_pid_to_exec_file): New function - (m3_ops): Add new target vector fields. - - * mac-nat.c (init_child_ops): Add new target vector fields. - - * mips-tdep.c: Chnages to accomodate additional parameter - to val_print. - (mips_print_register): Alter calls to val_print - - * monitor.c (monitor_write): Change stderr to gdb_stderr. - (monitor_remove_breakpoint): Ditto. - (init_base_monitor_ops): Add new target vector fields. - - * ppc-bdm.c (init_bdm_ppc_ops): Add new target vector fields. - - * printcmd.c (do_examine): When saving a value_ptr, remove it from - the list of value_ptr's to be freed automatically; when discarding - a previously saved value_ptr, free it. - (print_formatted): Update comments; add new comments. - (printf_command, print_insn): Purecov comments. - (_initialize_printcmd): Add assign as a command if dbx_commands is - set; create va as an alias for disassemble if xdb_commands is set. - (address_info): New cases LOC_INDIRECT and - LOC_THREAD_LOCAL_STATIC. - (display_command): If tui_version and exp starts with a '$', then - don't display it unless tui_vSetLayoutTo fails. - (disassemble_command): Add tuiDo calls. - (print_scalar_formatted): For integers that are long long, check - the print format and print out in binary octal, decimal, or - hex. Call the new print_*_chars functions in valprint.c - (print_frame_args): Altered calls to val_print, to reflect - additional parameter to val_print (case LOC_BASEREG_ARG). - - * procfs.c: (Procfs_init_inferior): Return value is now a void. - (procfs_ops): Add new target vector fields. - (procfs_create_inferior): Fix call to fork_inferior -- need another - parameter. - - * remote-adapt.c (adapt_open): Change stderr to gdb_stderr. - (adpat_insert_breakpoint): Ditto. - (init_adapt_ops): Add new target vector fields. - - * remote-array.c (array_wait): Change fflush to gdb_flush and - stdout to gdb_stdout. - (init_array_ops): Add new target vector fields. - - * remote-bug.c (bug_load): Change fflush to gdb_flush; stdout to - gdb_stdout. - (bug_wait): Change stderr to gdb_stderr. - (bug_insert_breakpoint): Ditto. - (init_bug_ops): Add new target vector fields. - - * remote-e7000.c - (init_e7000_ops): Add new target vector fields. - * remote-eb.c (init_eb_ops): Ditto. - * remote-es.c (init_es1800_ops): Ditto. - (init_es1800_child_ops): Ditto. - * remote-es.c (init_es1800_ops): Ditto. - (init_es1800_child_ops): Ditto. - * remote-hms.c (init_hms_ops): Ditto. - * remote-hms.c (init_hms_ops): Ditto. - * remote-nindy.c (init_nindy_ops): Ditto. - * remote-nrom.c (init_nrom_ops): Ditto. - * remote-os9k.c (init_rombug_ops): Ditto. - * remote-rdp.c (init_remote_rdp_ops): Ditto. - * remote-sds.c (init_sds_ops): Ditto. - * remote-sim.c (init_gdbsim_ops): Ditto. - * remote-st.c (init_st2000_ops): Ditto. - * remote-udi.c (init_udi_ops): Ditto. - * remote-vx.c (init_vx_ops): Ditto. - (init_vx_run_ops): Ditto. - * remote-vx.c: (Init_vx_ops): Ditto. - (init_vx_run_ops): Ditto. - - * remote-mips.c (mips_getstring): Change stderr to gdb_stderr. - (pmon_insert_breakpoint): Ditto. - (pmon_remove_breakpoint): Ditto. - (check_lsi_error): Ditto. - (common_breakpoint): Ditto. - (pmon_makeb64): Ditto. - - * remote-mips.c (mips_xfer_memory): Change fflush to gdb_flush; - change stdout to gdb_stdout. - - * remote-mm.c (mm_open): Change stderr to gdb_stderr. - (init_mm_ops): Add new target vector fields. - (mm_load): Fixed params in commented out call to symbol_file_add. - - * remote-nindy.c (instream): Change decl to FILE. - - * remote-udi.c (udi_load): Fixed params in call to symbol_file_add. - - * remote-vx.c (vx_add_symbols): Fixed params in call to - symbol_file_add. - - * remote.c (init_remote_ops): Cosmetic change to match expected - test output. - - * rs6000-nat.c (add_vmap): Add params to call to allocate_objfile. - - * scm-lang.h: Add parameter to scm_val_print function decl. - - * scm-valprint.c (scm_scmval_print): Cast svalue to (int); new - parameter. This parameter is currently only used when evaluating - C++ expressions. So, it is always 0 in this file. - (c_val_print): Fixed prototype decl; it needed an embedded_offset - param. - - * sol-thread.c (sol_core_ops): Add new target vector fields. - (sol_thread_ops): Ditto. - - * somsolib.c (DLD_FLAGS_MAPPRIVATE): New macro. - Define bit of __dld_flags in HP-UX a.out files. - (DLD_FLAGS_HOOKVALID): Ditto. - (DLD_FLAGS_LISTVALID): Ditto. - (DLD_FLAGS_BOR_ENABLE): Ditto. - (som_solib_total_st_size): Cumulative size in bytes of the - symbol tables of all shared objects on the so_list_head list. - (som_solib_st_size_threshhold_exceeded): Threshold for adding symbols - for shlibs. - (som_solib_sizeof_symbol_table): New function. Computes size of - symbol table for a shlib. - (som_solib_load_symbols): New function. Load symbols from shlib. - (som_solib_add): Detect if __dld_list is not valid. - Record main program's symbol table size. - Load symbols if called from command line. - Keep threshold into account when loading shlib symbols. - (som_solib_create_inferior_hook): Use dld_flags macros. - (som_sharedlibrary_info_command): Let user know if symbols were - not loaded. - (som_solib_restart): Discard all the shlibs descriptors. - (_initialize_som_solib): Chenge help message for auto-solib-add - command. - Set threshold for symbol table to 50 megabytes. - (_initialize_som_solib): Add call to som_solib_restart. - (som_solib_restart): New function - (som_solib_in_dynamic_linker): New function - (som_solib_desire_dynamic_linker_symbols): New function - (som_solib_unloaded_library_pathname): New function - (som_solib_loaded_library_pathname): New function - (som_solib_library_pathname): New function - (som_solib_have_unload_event): New function - (som_solib_have_load_event): New function - (som_solib_create_catch_unload_hook): New function - (som_solib_create_catch_load_hook): New function - (som_solib_create_inferior_hook): Rewritten - dld_cache: New struct - addr_and_unwind_t: New struct - (find_unwind_entry) add prototype - Include assert.h, remove references to ASSERT macro, - add include of fcntl.h so that O_RDONLY is defined. - (som_solib_create_inferior_hook): Introduce new local - msymbol2 and change some msymbol's to msymbol2's -- was clobbering - msymbol, passing a NULL to lookup_minimal_symbol_solib_trampoline, - and ultimately core dumping with a SEGV. - (som_solib_mapped_entry): Additional comments for text_addr, - text_link_addr, text_end, and tsd_start_addr fields. Commenting - out 2 tsd fields, __data_start and __data_end. - (som_solib_add_solib_objfile): Add params to calls to symbol_file_add. - Add some code for distinguishing between a shared library and other - objfiles. This appears to be a prelude to thread local storage. - (som_solib_load_symbols): Changes to printf statement - enclosed by SOLIB_DEBUG ifdef. - (som_solib_add): Change comment to correctly specify path - to end.o -- /opt/langtools/lib/end.o. changes to printf statement - enclosed by SOLIB_DEBUG ifdef. - Removed several SOLIB_DEBUG ifdefs and the associated printfs. - Add code to find the start address for the object file's thread - local storage - (som_solib_create_inferior_hook): Fix warning messages use correct - path to end.o -- /opt/langtools/lib/end.o. Change control flow. - No longer user early returns from function is cases of error. - (reset_inferior_pid): New function - (som_solib_remove_inferior_hook): New function - (so_lib_thread_start_addr): New function. used for tsd. - (struct som_solib_mapped_entry): Add new field tsd_start_addr. - (struct so_list): Add new field solib_addr. - (som_solib_add_solib_objfile): New function. - (som_solib_load_symbols): Rewritten. - (som_solib_add): Make sure we don't load the symbols in if the - threshold was exceeded. - (som_solib_get_solib_by_pc): New function. Return the address of - handle of the shared library. - (som_solib_restart): Disable breakpoints at restart. - - * sparcl-tdep.c (init_sparclite_ops): Add new target vector fields. - - * target.c (cleanup_target): Changed casting of default functions - for to_has_forked, to_has_vforked, to_pid_to_exec_file to get rid - of warnings. Fixed PARAMS for to_has_syscall_event. Fixed the - return type on a few of the default function values. - (cleanup_target): Changes in the de_fault macro, both to - accomodate the new target_ops vector fields and to use - more accurate default functions. - (debug_to_open): Change stderr to gdb_stderr. - (debug_to_close): Ditto. - (debug_to_attach): Ditto. - (debug_to_post_attach): Ditto. - (debug_to_require_attach): Ditto. - (debug_to_detach): Ditto. - (debug_to_require_detach): Ditto. - (debug_to_resume): Ditto. - (debug_to_wait): Ditto. - (debug_to_post_wait): Ditto. - (debug_to_fetch_registers): Ditto. - (debug_to_store_registers): Ditto. - (debug_to_prepare_to_store): Ditto. - (debug_to_xfer_memory): Ditto. - (debug_to_files_info): Ditto. - (debug_to_insert_breakpoint): Ditto. - (debug_to_remove_breakpoint): Ditto. - (debug_to_terminal_init): Ditto. - (debug_to_terminal_inferior): Ditto. - (debug_to_terminal_ours_for_output): Ditto. - (debug_to_terminal_ours): Ditto. - (debug_to_terminal_info): Ditto. - (debug_to_kill): Ditto. - (debug_to_load): Ditto. - (debug_to_lookup_symbol): Ditto. - (debug_to_create_inferior): Ditto. - (debug_to_post_startup_inferior): Ditto. - (debug_to_acknowledge_created_inferior): Ditto. - (debug_to_clone_and_follow_inferior): Ditto. - (debug_to_post_follow_inferior_by_clone): Ditto. - (debug_to_insert_fork_catchpoint): Ditto. - (debug_to_remove_fork_catchpoint): Ditto. - (debug_to_insert_vfork_catchpoint): Ditto. - (debug_to_remove_vfork_catchpoint): Ditto. - (debug_to_has_forked): Ditto. - (debug_to_has_vforked): Ditto. - (debug_to_can_follow_vfork_prior_to_exec): Ditto. - (debug_to_post_follow_vfork): Ditto. - (debug_to_insert_exec_catchpoint): Ditto. - (debug_to_remove_exec_catchpoint): Ditto. - (debug_to_has_execd): Ditto. - (debug_to_reported_exec_events_per_exec_call): Ditto. - (debug_to_has_syscall_event): Ditto. - (debug_to_has_exited): Ditto. - (debug_to_mourn_inferior): Ditto. - (debug_to_can_run): Ditto. - (debug_to_notice_signals): Ditto. - (debug_to_thread_alive): Ditto. - (debug_to_stop): Ditto. - (debug_to_enable_exception_callback): Ditto. - (debug_to_get_current_exception_event): Ditto. - (debug_to_pid_to_exec_file): Ditto. - (debug_to_core_file_to_sym_file): Ditto. - (default_clone_and_follow_inferior): New function prototype - decl and function definition. - (dummy_target): Add new target_ops vector fields and their - initializations. More target_ops vector changes for HPUX new - fields. - (de_fault): Add new HPUX specific target_ops operations to the - de_fault macro - (INHERIT): Add new HPUX specific target_ops operations. - (debug_to_post_wait): New function. - (debug_to_post_startup_inferior): Ditto. - (debug_to_acknowledge_created_inferior): Ditto. - (debug_to_clone_and_follow_inferior): Ditto. - (debug_to_post_follow_inferior_by_clone): Ditto. - (debug_to_create_catch_fork_hook): Ditto. - (debug_to_create_catch_vfork_hook): Ditto. - (debug_to_has_forked): Ditto. - (debug_to_has_vforked): Ditto. - (debug_to_post_follow_vfork): Ditto. - (setup_target_debug): Initialize new target_ops vector fields. - (nosupport_runtime): New function, used in cleanup_target - (update_current_target): Add new new target_ops vector fields to - the INHERIT macro definition. - (generic_mourn_inferior): The call to breakpoint_init_inferior now - takes a parameter. - (normal_pid_to_str): Add a \0 to the end of buf. - (debug_to_has_syscall_event): New function. - (debug_to_enable_exception_callback): New function. - (debug_to_get_current_exception_event): New function. - (setup_target_debug): Initialize the 3 new target_ops vector fields - (struct signals): Fix message associated with SIGRETRACT. - (return_one): New function, used by the de_fault macro - (debug_to_post_attach): New function. - (debug_to_wait): Add new cases TARGET_WAITKIND_FORKED, - TARGET_WAITKIND_VFORKED, TARGET_WAITKIND_EXECD. - (debug_to_insert_fork_catchpoint): New function. - (debug_to_remove_fork_catchpoint): Ditto. - (debug_to_insert_vfork_catchpoint): Ditto. - (debug_to_remove_vfork_catchpoint): Ditto. - (debug_to_can_follow_vfork_prior_to_exec): Ditto. - (debug_to_insert_exec_catchpoint): Ditto. - (debug_to_remove_exec_catchpoint): Ditto. - (debug_to_core_file_to_sym_file): Ditto. - (setup_target_debug): Give new fields in current_target target_ops - vector values. - - * target.h: Include symtab.h. - (target_waitkind): New enumerated values - TARGET_WAITKIND_SYSCALL_ENTRY, TARGET_WAITKIND_SYSCALL_RETURN, - TARGET_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED, - TARGET_WAITKIND_EXECD. - (target_waitstatus): Add a syscall_id field to structure. - (child_has_syscall_event): New decl. - (child_thread_alive): New decl. - (target_ops): Add 3 new fields: To_has_syscall_event, - to_enable_exception_callback, to_get_current_exception_event - (target_enable_exception_callback): New macro. - (target_has_syscall_event): New macro. - (target_get_current_exception_event): New macro. - (TARGET_DISABLE_HW_WATCHPOINTS): New macro. - (TARGET_ENABLE_HW_WATCHPOINTS): New macro. - (PC_REQUIRES_RUN_BEFORE_USE): New macro. - (target_tid_to_str): New macro. - (target_waitstatus): Additional fields in struct to keep track - of child pid and pathname to execd file. - (target_ops): Add in the new target_ops function pointer fields. - New macros to go along with new target_ops fields. - In target_waitstatus.value, change name of child_pid field to - related_pid. - (target_pid_or_tid_to_str): Define default macro. - Add missing #endif after PC_REQUIRES_RUN_BEFORE_USE definition - (ENSURE_VFORKING_PARENT_REMAINS_STOPPED): Define default macro. - (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK): Define default - macro. - There are new function decls for to_require_attach - and to_require_detach. There are also new macros, - target_require_attach and target_require_detach. There are - also new function decls for find_default_require_detach - and find_default_require_attach. - (target_ops): New fields to_post_wait, to_post_startup_inferior - to_acknowledge_created_inferior, to_clone_and_follow_inferior, - to_post_follow_inferior_by_clone, to_create_catch_fork_hook, - to_create_catch_vfork_hook, to_has_forked, to_has_vforked, - to_post_follow_vfork, to_pid_to_exec_file. - New function definitions child_pid_to_exec_file, child_post_wait, - child_post_startup_inferior, child_acknowledge_created_inferior, - child_clone_and_follow_inferior, - child_post_follow_inferior_by_clone, child_create_catch_fork_hook, - child_create_catch_vfork_hook, child_has_forked, - child_has_vforked, child_acknowledge_created_inferior, - child_post_follow_vfork. - New macros target_post_startup_inferior, - target_acknowledge_created_inferior, - target_clone_and_follow_inferior, - target_post_follow_inferior_by_clone, - target_create_catch_fork_hook, target_create_catch_vfork_hook, - target_pid_to_exec_file. - (find_default_clone_and_follow_inferior): New function prototype. - - - * v850ice.c (init_850ice_ops): Init new target vector fields. - - * valprint.c (print_binary_chars): Print out long long as - a binary number. - (print_octal_chars): Print out long long as an octal number - (print_decimal_chars): Print out long long as a decimal number - (strcat_longest): Define it. - * valprint.c: Hp merge, 4/15/98 snapshot - Add parameter to val_print. This is used for - evaluating C++ expressions. - - * value.h (VALUE_POINTED_TO_OFFSET): New macro. - Add field pointed_to_offset to value structure. - Add prototypes for new functions in valops.c. - (write_register_pid): Change prototype to match - function. - (val_print function decl): Additional parameter. - (VALUE_EMBEDDED_OFFSET): New macro. - (find_rt_vbase_offset): New function decl -- for C++ support. - -Wed Dec 23 15:03:42 1998 Per Bothner - - * Makefile.in (READLINE_CFLAGS): Search $(READLINE_SRC)/.. rather - than $(READLINE_SRC) so #include will work. - * top.c: #include instead of "history.h". - * tracepoint.c: Likewise. - * mac-xdep.c: Likewise. - -Wed Dec 23 12:32:00 1998 Andrew Cagney - - * defs.h (TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT): Define using - TARGET_BYTE_ORDER and not target_byte_order. - -Tue Dec 22 10:51:33 1998 Elena Zannoni - - * config/i386/cygwin.mh (TERMCAP): define. - (from Chris Faylor, cgf@cygnus.com) - - * top.c: specify directory name for including readline.h - - * tracepoint.c: ditto. - - * utils.c: ditto. - -Mon Dec 21 13:30:34 1998 Mark Alexander - - * value.c (value_virtual_fn_field): Handle the situation where - vtbl is a pointer to a structure instead of a pointer to an array. - -Mon Dec 21 10:38:11 1998 Andrew Cagney - - * mips-tdep.c: (MIPS_DEFAULT_FPU_TYPE): Default to - MIPS_FPU_DOUBLE. - -1998-12-17 J.T. Conklin - - * blockframe.c (get_frame_saved_regs): If the saved_regs_addr ptr - is null, ensure that saved registers are copied from the local - variable that was used to obtain them. - -Sat Dec 19 09:55:09 1998 Stu Grossman - - * mips-tdep.c (mips32_heuristic_proc_desc): Clear temp_saved_regs - on restart. Fixes problem with backtracing through functions that - use virtual frame pointers. - -Fri Dec 18 14:23:34 1998 Andrew Cagney - - * mips-tdep.c (mips_push_arguments): Don't left-shift small - structs being passed in a register when an O64 target. - - * config/mips/tm-mips.h (enum mips_fpu_type, mips_fpu): Move to - mips-tdep.c. - - * mips-tdep.c (mips_fpu_string): Delete variable. - (mips_fpu_type_auto): New variable. - (mips_fpu_type): Rename mips_fpu. - (_initialize_mips_tdep): Delete initialization of mips_fpu et.al. - Rewrite ``set mipsfpu'' command set. - (set_mipsfpu_command, show_mipsfpu_command, - set_mipsfpu_single_command, set_mipsfpu_double_command, - set_mipsfpu_none_command, set_mipsfpu_auto_command): New - functions, handle commands. - (mips_push_arguments, mips_push_dummy_frame, mips_pop_frame, - mips_extract_return_value): Update. - -Thu Dec 17 02:15:40 1998 Andrew Cagney - - * configure.tgt (gdb_target): Identify mips64*vr4100*-*-elf* as - vr4100. - -Thu Dec 17 01:34:36 1998 Andrew Cagney - - * gdbtypes.c (build_gdbtypes): New function. - (_initialize_gdbtypes): Call. - -Wed Dec 16 11:47:00 1998 Andrew Cagney - - * gdbarch.c (show_architecture): Use TARGET_ARCHITECTURE. - * gdbarch.h, gdbarch.c: Fix typo's. Use struct's in preference to - types. - * gdbarch.h, gdbarch.c (gdbarch_debug): Add ``set archdebug'' to - command set. - -Tue Dec 15 23:46:40 1998 Andrew Cagney - - * config/mips/tm-*.h: (TARGET_BYTE_ORDER_DEFAULT, - TARGET_BYTE_ORDER_SELECTABLE_P): Replace TARGET_BYTE_ORDER and - TARGET_BYTE_ORDER_SELECTABLE. - -1998-12-14 Anthony Thompson (athompso@cambridge.arm.com) - - * remote-rdp.c (rdp_init): Don't discard first character on reset. - (translate_open_mode): Define table. - (exec_swi): Handle SWI_Clock. SWI_Open now handles stdin/stdout. - SWI_Write returns number of bytes not written. SWI_Read does the - same. SWI_Seek should return success/failure flag. Fix SWI_Flen. - -1998-12-14 J.T. Conklin - - * config/i386/nbsd.mh, config/m68k/nbsd.mh, config/ns32k/nbsd.mh - (XDEPFILES): Add ser-tcp.o. - -Mon Dec 14 14:46:13 1998 Andrew Cagney - - * monitor.c (monitor_expect, monitor_printf_noecho, - monitor_printf): Always compile EXTRA_RDEBUG code. - (RDEBUG): Ditto. - - From Michael Meissner : - * ppcbug-rom.c (init_ppc_cmds): Cleanup formatting. - -1998-12-08 Michael Meissner - - * monitor.c (monitor_printable_string): New function to convert a - string into a printable representation. - (monitor_error): Call error after converting string into printable - format. - (monitor_printf{,_noecho}): If EXTRA_RDEBUG is defined, convert - string into printable form before printing. - (monitor_expect): Ditto. - (monitor_read_memory{,_single}): Call monitor_error, not error. - (monitor_read_memory): Return immediately if length is 0. - - * ppcbug-rom.c (init_ppc_cmds): Fill in dump_registers field, - which is now required. - -Mon Dec 14 11:01:39 1998 Andrew Cagney - - * gdbarch.h, gdbarch.c: Consolidate the semi-dynamic target system - dependant GDB parameters. - (set_gdbarch_from_file): Combine set_architecture_from_file and - set_byte_order_from_file. - * top.c, defs.h, printcmd.c: Delete them from here. - * Makefile.in: Add gdbarch.[ch]. - * exec.c (exec_file_command): Call set_gdbarch_from_file. - -Sun Dec 13 09:52:51 1998 Andrew Cagney - - * defs.h (TARGET_PRINT_INSN_INFO, TARGET_PRINT_INSN): Define. - (TARGET_ARCHITECTURE, TARGET_ARCHITECTURE_AUTO): Define. - (TARGET_BYTE_ORDER_AUTO): Define. - (TARGET_BYTE_ORDER_SELECTABLE_P): Provide default. Replaces - TARGET_BYTE_ORDER_SELECTABLE. Handle compat issues. - (BITS_BIG_ENDIAN): Simplify. - (TARGET_FLOAT_FORMAT): Ditto. - (TARGET_DOUBLE_FORMAT): - - * remote-e7000.c, sh-tdep.c, printcmd.c, remote-sim.c, - remote-rdi.c, sparc-tdep.c: Update. - - * config/powerpc/tm-ppcle-eabi.h, config/rs6000/tm-rs6000.h, - config/powerpc/tm-ppc-eabi.h, config/mn10300/tm-mn10300.h: - Convert. - -Sat Dec 12 09:28:13 1998 Andrew Cagney - - * frame.h (struct frame_info): Add CORE_ADDR *saved_regs and - struct frame_extra_info *extra_info. - (frame_obstack_alloc, frame_saved_regs_zalloc): Prototype. - (SIZEOF_FRAME_SAVED_REGS): Provide default. - (FRAME_INIT_SAVED_REGS): Provide default. - (struct frame_saved_regs): Deprecate. - (EXTRA_FRAME_INFO): Deprecate. - - * blockframe.c (frame_obstack_alloc, frame_saved_regs_zalloc): New - function. - (generic_get_saved_register): Use FRAME_INIT_SAVED_REGS and - frame->saved_regs. - (frame_cache_obstack): Make static. - (get_frame_saved_regs): Deprecate. Copy the saved regs into the - frame buffer. - - * stack.c (frame_info): Rewrite using frame->saved_regs and - FRAME_INIT_SAVED_REGS. - * findvar.c (find_saved_register): Ditto. - - * config/mn10300/tm-mn10300.h (EXTRA_FRAME_INFO): Delete. - (FRAME_FIND_SAVED_REGS): Replace with FRAME_INIT_SAVED_REGS. No-op. - * mn10300-tdep.c: Update. - (analyze_dummy_frame): New function. - (struct frame_extra_info): Define. - (mn10300_init_extra_frame_info): Update. - - * config/rs6000/tm-rs6000.h: (EXTRA_FRAME_INFO): Delete. - (FRAME_FIND_SAVED_REGS): Replace with FRAME_INIT_SAVED_REGS. - (FRAME_ARGS_ADDRESS): Replace with function. - - * rs6000-tdep.c (frame_get_saved_regs): Rename from - frame_get_cache_fsr. - (rs6000_init_extra_frame_info): New function. - (rs6000_frame_init_saved_regs): Call frame_get_saved_regs. - (FUNCTION_START_OFFSET): Delete references, was ZERO. - (rs6000_frame_args_address): New function. - (frame_initial_stack_address): Update - - * config/mips/tm-mips.h (EXTRA_FRAME_INFO): Remove saved_regs. - (FRAME_INIT_SAVED_REGS): Rename FRAME_FIND_SAVED_REGS, update. - * mips-tdep.c (mips_find_saved_regs, read_next_frame_reg, - init_extra_frame_info, mips_pop_frame): Update. - * config/alpha/tm-alpha.h (FRAME_INIT_SAVED_REGS, - EXTRA_FRAME_INFO), alpha-tdep.c (alpha_find_saved_regs, - alpha_pop_frame, init_extra_frame_info): Ditto. - - * i960-tdep.c, m88k-tdep.c, h8300-tdep.c: Update. - * config/sparc/tm-sparc.h, config/a29k/tm-a29k.h: Define - FRAME_INIT_SAVED_REGS as no-op. - - * z8k-tdep.c (z8k_init_frame_saved_regs): Rename - get_frame_saved_regs. - (examine_frame, z8k_skip_prologue): Update. - * config/z8k/tm-z8k.h (FRAME_INIT_SAVED_REGS): Define. - -1998-12-11 Fernando Nasser - - From J.T. Conklin : - * i386-stub.c (handle_exception): Add support for 'P' command. - (NUMREGS): New macro. - -Fri Dec 11 09:07:05 1998 Andrew Cagney - - * i386b-nat.c: Include "expression.h". - - * symtab.h: Don't include "gnu-regex.h". - - * solib.c (solib_add_common_symbols): Cast parameters passed to - make_cleanup to use the new make_cleanup_func typedef. - - * inftarg.c: Include "wait.h" after, rather than before, . - "wait.h" was defining all WIF* macro's instead of filling in those - that missed. - -Fri Dec 11 09:52:04 1998 Andrew Cagney - - * mipsm3-nat.c, hppah-nat.c, infptrace.c, i386gnu-nat.c, - hppab-nat.c, core-aout.c, arm-xdep.c, alpha-nat.c, altos-xdep.c, - pyr-xdep.c, remote-st.c, remote-os9k.c, tahoe-tdep.c, pyr-tdep.c, - vax-tdep.c: Replace reg_name with REGISTER_NAME. - -Thu Dec 10 15:19:40 1998 David Taylor - - The following changes were made by Jim Blandy , - Edith Epstein , Elena Zannoni - Stan Shebs , and David - Taylor , as part of the project to merge in - changes originally made by HP; HP did not create ChangeLog - entries. - - * annotate.c (annotate_catchpoint): New function. - - * annotate.h (annotate_catchpoint): declare it; add new includes - (symtab.h and gdbtypes.h). - - * buildsym.h: add external var processing_hp_compilation. - - * coff-solib.h: - (SOLIB_REMOVE_INFERIOR_HOOK): new macro. defined to 0. - functionality not implemented for coff. - (SOLIB_CREATE_CATCH_LOAD_HOOK): New macro; generate error msg for coff. - (SOLIB_CREATE_CATCH_UNLOAD_HOOK): ditto. - (SOLIB_HAVE_LOAD_EVENT): ditto. - (SOLIB_LOADED_LIBRARY_PATHNAME): ditto. - (SOLIB_HAVE_UNLOAD_EVENT): ditto. - (SOLIB_UNLOADED_LIBRARY_PATHNAME): ditto. - (SOLIB_IN_DYNAMIC_LINKER): ditto. - (SOLIB_RESTART): ditto. - - * complaints.h: add ifdef...endif pair at beginning and end of file. - - * dstread.c (dst_symfile_read): the parameter to fileno - must be of type FILE *. So cast abfd->iostream in the - call to fileno must be cast as a FILE *, not a GDB_FILE *. - This will work because abfd->iostream is declared and - given a value in bdf and bfd will continue to use FILE - rather than GDB_FILE. - - * dwarf2read.c (dwarf_bool_name): change parameter from bool - to mybool. sigh. - - * expression.h: include symtab.h - - * frame.h (print_only_stack_frame, show_stack_frame, - show_frame_info): add prototypes. - - * gdbcmd.h (togglelist, stoplist): declare. - - * gdbcore.h (read_memory_string): declare it. - (exec_file_attach): add prototype. - - * inflow.c (terminal_is_ours): make non static. - - * minsyms.c: minor spacing change. - - * parser-defs.h (parse_nested_classes_for_hpacc): add prototype. - (find_template_name_end): add prototype. - - * scm-lang.c (scm_unpack): cast svalue to (int). - - * top.h: declare it. - - * valprint.h (print_binary_chars): new prototype definition. - (print_octal_chars): new prototype definition. - (print_decimal_chars): new prototype definition. - -Thu Dec 10 07:14:56 1998 Andrew Cagney - - * config/arm/tm-arm.h, arm-tdep.c: Replace REGISTER_NAMES with - REGISTER_NAME. - * mn10300-tdep.c, config/mn10300/tm-mn10300.h: Ditto. - * sh-tdep.c, config/sh/tm-sh.h: Ditto. - - * defs.h (REGISTER_NAME): Provide default for old targets. - * defs.h, infcmd.c: Rename reg_names to gdb_register_names. - - * tracepoint.c, target.c, parse.c, infcmd.c, remote-udi.c, - expprint.c, infcmd.c, printcmd.c, eval.c, stack.c, findvar.c, - remote-udi.c, config/alpha/tm-alpha.h, remote-sim.c, d30v-tdep.c, - config/mips/tm-mips.h, hppa-tdep.c: Use REGISTER_NAME. - -1998-12-08 James E Wilson - - * config/i960/mon960.mt (SIM_OBJS, SIM): Define. - -Tue Dec 8 16:49:24 1998 Stan Shebs - - * NEWS: Add mentions of newly-added configurations. - -1998-12-08 Philippe De Muyter - - * config/xm-aix4.h (SIGWINCH_HANDLER): Function `aix_resize_window' - must accept a signal number as parameter. - * config/rs6000/xm-rs6000.h (SIGWINCH_HANDLER): Ditto. - * utils.c (initialize_utils): Give a parameter to `SIGWINCH_HANDLER'. - - * inferior.h (register_valid): Variable's type is `SIGNED char', not - `char'. - * findvar.c (register_valid): Ditto. - - * defs.h (make_cleanup_func): Protect parameter list by `PARAMS'. - * gdbthread.h (unbind_target_thread_vector): Likewise. - -Tue Dec 8 15:09:44 1998 Edith Epstein - - Merged in m68k-linux patch from Andreas Schwab - - 1998-12-01 Andreas Schwab - - * Makefile.in, configure.host, configure.tgt: Add support for - m68k-linux. - * config/m68k/linux.mh: New file. - * config/m68k/linux.mt: New file. - * config/m68k/nm-linux.h: New file. - * config/m68k/tm-linux.h: New file. - * config/m68k/xm-linux.h: New file. - * gdb/m68klinux-nat.c: New file. - * gdbserver/low-linux.c: Add support for m68k-linux. - * gdb/config/m68k/tm-m68k.h (NUM_FREGS): New macro. - -1998-12-07 Jason Molenda (jsm@bugshack.cygnus.com) - - * config/i386/xm-cygwin.h: Remove REQUEST_QUIT definition. - * config/powerpc/xm-cygwin.h: Ditto. - -1998-12-07 Jim Blandy - - * rs6000-tdep.c (pop_frame): Correctly find the registers saved in - the stack frame. Their offset from the previous stack frame is in - fdata.gpr_offset and fdata.fpr_offset, not fdata.offset. - (gdb.base/return.exp) - * config/rs6000/tm-rs6000.h: Doc fixes. - -1998-12-03 Jason Molenda (jsm@bugshack.cygnus.com) - - * monitor.c (monitor_read_memory): Zero out pattern buffers - before calling re_search. - (parse_register_dump): Ditto. - -Thu Dec 3 10:37:22 EST 1998 Zdenek Radouch (radouch@cygnus.com) - - FR30 updates - still very preliminary. - * configure.tgt - * fr30-tdep.c - * config/fr30/tm-fr30.h - -Thu Dec 3 16:30:35 1998 Andrew Cagney - - * ax-gdb.c: Include target.h. - -Tue Dec 3 10:59:00 1998 Andrew Cagney - - * ax-gdb.c (_initialize_ax_gdb), i960-tdep.c (pop_frame), - monitor.c (flush_monitor_dcache, longlongendswap), remote-array.c - (hexword2ascii), w89k-rom.c (init_w89k_cmds), z8k-tdep.c - (init_frame_pc, extract_return_value): Make return type void. - * monitor.c (monitor_write_even_block): Make return type explicit. - (monotor_read_memory_block): Delete function. - * monitor.h: Update. - * remote.c (remote_get_threadlist, remote_update_threads), - remote-array.c (array_get_packet), remote-rdi.c (Fail): Always - return a value. - * m32r-tdep.c (m32r_fix_call_dummy): From Michael Snyder, void - function. - * jv-valprint.c (java_val_print): From Stu Grossman. Return 0 by - default. - -Wed Dec 2 15:11:38 1998 Michael Snyder - - * tracepoint.c: Move default definition of - TARGET_VIRTUAL_FRAME_POINTER from here to target.h. - * target.h: Add default definition of TARGET_VIRTUAL_FRAME_POINTER. - * ax-gdb.c (gen_frame_args_address, gen_frame_locals_address): - use TARGET_VIRTUAL_FRAME_POINTER to determine frame pointer. - (gen_trace_for_expr): new argument, address of tracepoint, - gets passed to new_agent_expr and added to struct agent_expr. - (is_nontrivial_conversion): call to new_agent_expr now requires - a dummy argument. (agent_command): use get_current_frame() to - get current PC scope; pass it to gen_trace_for_expr. - * ax-general.c (new_agent_expr): new argument, address of - tracepoint; store it in new field of struct agent_expr. - * ax.h (struct agent_expr): add new field for tracepoint address. - * ax-gdb.h: change prototypes to match above changes. - - * m32r-tdep.c (decode_prologue): If no branch or push fp is found, - but there's a stack adjust, then use that as the end of prologue. - (m32r_skip_prologue): don't skip past the first line if there is - line info. (m32r_virtual_frame_pointer): new function. - (m32r_fix_call_dummy): no return value needed. - -Tue Dec 1 10:59:00 1998 Andrew Cagney - - * ocd.c (remote_timeout), (BDM_BREAKPOINT), monitor.c (readchar), - remote.c: Cleanup closing of open comments. - -Mon Nov 30 16:04:03 1998 Doug Evans - - * config/fr30/tm-fr30.h (INNER_THAN): Add parameters. - -Mon Nov 30 11:18:48 1998 Andrew Cagney - - * frame.h (FRAME_CHAIN_VALID): Default to - default_frame_chain_valid. - * blockframe.c (default_frame_chain_valid): New function. - - * frame.h (FRAME_CHAIN_VALID_ALTERNATIVE): Delete references - * blockframe.c (alternate_frame_chain_valid): New function. - * config/mips/tm-mipsv4.h, config/m88k/tm-delta88v4.h, - config/m68k/tm-monitor.h, config/m68k/tm-m68kv4.h, - config/i386/tm-i386v4.h, config/i386/tm-i386nw.h, - config/h8300/tm-h8300.h: Update. - - * blockframe.c (nonnull_frame_chain_valid): New function. - * config/m68k/tm-os68k.h, config/m68k/tm-vx68.h, - config/m68k/tm-apollo68b.h, config/i960/tm-vx960.h, - config/arc/tm-arc.h: Update FRAME_CHAIN_VALID. - - * hppa-tdep.c (frame_chain_valid, hppa_frame_chain_valid), - remote-vx29k.c (get_fp_contents, vx29k_frame_chain_valid), - arm-tdep.c (frame_chain_valid, arm_frame_chain_valid): Rename - functions so that they are name space clean. - * config/pa/tm-hppa.h, config/a29k/tm-vx29k.h, - config/arm/tm-arm.h: Update FRAME_CHAIN_VALID. - - * gould-tdep.c (gould_frame_chain_valid), d30v-tdep.c - (d30v_frame_chain_valid), d10v-tdep.c (d10v_frame_chain_valid): - New functions. - * config/gould/tm-np1.h, config/gould/tm-pn.h, - config/d30v/tm-d30v.h, config/d10v/tm-d10v.h: Update - FRAME_CHAIN_VALID. - -Sun Nov 29 11:18:37 1998 Andrew Cagney - - * z8k-tdep.c (z8k_addr_bits_remove), w65-tdep.c - (w65_addr_bits_remove), h8500-tdep.c (h8500_addr_bits_remove), - m88k-tdep.c (m88k_addr_bits_remove): Function to clean up an - address. - * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/m88k/tm-m88k.h, - config/h8500/tm-h8500.h: Define ADDR_BITS_REMOVE to call targets - corresponding function. - * z8k-tdep.c (saved_pc_after_call): Update. - -Sat Nov 28 12:24:31 1998 Andrew Cagney - - * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/vax/tm-vax.h, - config/v850/tm-v850.h, config/tahoe/tm-tahoe.h, - config/sparc/tm-sparc.h, config/sh/tm-sh.h, - config/rs6000/tm-rs6000.h, config/pyr/tm-pyr.h, - config/pa/tm-hppa.h, config/ns32k/tm-umax.h, - config/ns32k/tm-merlin.h, config/none/tm-none.h, - config/mn10300/tm-mn10300.h, config/mn10200/tm-mn10200.h, - config/mips/tm-mips.h, config/m88k/tm-m88k.h, - config/m68k/tm-m68k.h, config/m32r/tm-m32r.h, - config/i960/tm-i960.h, config/i386/tm-i386.h, - config/h8500/tm-h8500.h, config/h8300/tm-h8300.h, - config/gould/tm-pn.h, config/gould/tm-np1.h, config/arm/tm-arm.h, - config/convex/tm-convex.h, config/d10v/tm-d10v.h, - config/alpha/tm-alpha.h, config/a29k/tm-a29k.h: Add parameters to - macro INNER_THAN. - - * valops.c (push_word, value_push, call_function_by_hand), - breakpoint.c (bpstat_stop_status), blockframe.c - (generic_push_dummy_frame, generic_frame_chain_valid), inferior.h - (PC_IN_CALL_DUMMY), infrun.c (wait_for_inferior): Update use of - INNER_THAN. - -Fri Nov 27 11:00:25 1998 Andrew Cagney - - * target.h (one_stepped): Move global from here. - * infrun.c (singlestep_breakpoints_inserted_p): To here. Rename. - Make static. - (wait_for_inferior): Update. - (resume): Update. Set variable after call to SOFTWARE_SINGLE_STEP. - - * target.h (NO_SINGLE_STEP): Replace with SOFTWARE_SINGLE_STEP_P - and SOFTWARE_SINGLE_STEP. - * config/sparc/tm-sparc.h, config/rs6000/tm-rs6000.h, - config/arc/tm-arc.h: Update. - * rs6000-tdep.c (rs6000_software_single_step), sparc-tdep.c - (sparc_software_single_step), arc-tdep.c (arc_single_step): New - functions. Replace function single_step. - - * config/mips/tm-mips.h (STEP_SKIPS_DELAY_P): Define. - * infrun.c (proceed): Cleanup. - -Thu Nov 26 11:19:15 1998 Andrew Cagney - - * config/alpha/tm-alpha.h (ABOUT_TO_RETURN): Replace macro. - * alpha-tdep.c (alpha_about_to_return): With new function. - (heuristic_proc_start): Update. - * config/mips/tm-mips.h (ABOUT_TO_RETURN), mips-tdep.c - (heuristic_proc_start, mips_about_to_return): Ditto. - * config/ns32k/tm-merlin.h (ABOUT_TO_RETURN), - config/ns32k/tm-umax.h (ABOUT_TO_RETURN), ns32k-tdep.c - (ns32k_about_to_return, ns32k_get_enter_addr): Ditto. - - * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/vax/tm-vax.h, - config/tahoe/tm-tahoe.h, config/sparc/tm-sparc.h, - config/sh/tm-sh.h, config/rs6000/tm-rs6000.h, config/pyr/tm-pyr.h, - config/pa/tm-hppa.h, config/m88k/tm-m88k.h, config/m68k/tm-m68k.h, - config/i960/tm-i960.h, config/i386/tm-i386.h, - config/h8500/tm-h8500.h, config/h8300/tm-h8300.h, - config/gould/tm-pn.h, config/gould/tm-np1.h, - config/convex/tm-convex.h, config/arm/tm-arm.h, - config/arc/tm-arc.h, config/a29k/tm-a29k.h: Delete macro - ABOUT_TO_RETURN. - * config/w65/tm-w65.h (RTL, RTS): Delete macros. - * h8500-tdep.c (about_to_return): Delete function. - -Thu Nov 26 11:19:15 1998 Andrew Cagney - - * rs6000-tdep.c (rs6000_breakpoint_from_pc): Change big_breakpoint - and little_breakpoint to char[] from char*. - * remote-array.c (array_insert_breakpoint): Change bp_addr to - CORE_ADDR type. - -Wed Nov 25 00:13:06 1998 Andrew Cagney - - * vx-share/xdr_ld.c (xdr_ldtabl): Cast second arg to char** - instead of char*. - - * configure.tgt (v850): Only build v850ice when cygwin and gui. - * configure.in: Add parameter to --enable-build-warnings. - * configure: Re-build. - - * c-exp.y (parse_number): Rewrite shift to pacify GCC. - - * config/i960/tm-i960.h (BREAKPOINT): Delete definition - simply - wrong. - - * monitor.c (compile_pattern): Make val const char*. - (monitor_wait_cleanup): Make old_timeout void*, pointing at - old_timeout. - (monitor_wait): Update. - - * remote-udi.c, remote-sim.c, remote-e7000.c, hppa-tdep.c, - remote-mips.c, sparcl-tdep.c, xcoffread.c: Cast parameters passed - to make_cleanup to use the new make_cleanup_func typedef. - - * alpha-tdep.c (MASK): Use LONGEST to avoid arithmetic overflow. - - * config/a29k/tm-a29k.h (TRANSPARENT): Rename macro to - TRANSPARENT_FRAME. Avoid name-space clash. - * a29k-tdep.c (init_frame_info): Update. - -Wed Nov 25 20:37:00 1998 Andrew Cagney - - * rs6000-tdep.c (rs6000_breakpoint_from_pc): Change big_breakpoint - and little_breakpoint to char[] from char*. - * mem-break.c (memory_insert_breakpoint, - memory_remove_breakpoint): Pass address of bplen. - * remote-array.c (array_insert_breakpoint): Change bp_addr to - CORE_ADDR type. - -Tue Nov 24 15:46:33 1998 Michael Snyder - - * config/mn10300/tm-mn10300.h (TARGET_VIRTUAL_FRAME_POINTER): - new target macro. - * mn10300-tdep.c (mn10300_virtual_frame_pointer): new function. - * tracepoint.c (encode_actions): Use the new target macro to - determine the virtual frame pointer, for collecting locals/args. - (add_local_symbols, collect_symbol): add a register/offset pair of - arguments so that the virtual frame pointer can be passed in. - -1998-11-24 Felix Lee - - * procfs.c (procfs_wait): handle syscall events first. - - * procfs.c (GDB_GREGSET_TYPE, GDB_FPREGSET_TYPE): new macros. - * config/sparc/xm-sun4sol2.h: use them. - * core-sol2.c: don't #undef gregset_t and fpregset_t. - * sol-thread.c: ditto. - * sparc-tdep.c: ditto. - -Tue Nov 24 14:13:10 1998 Andrew Cagney - - * breakpoint.c (memory_breakpoint_size): Delete global. - (read_memory_nobpt): Determine real breakpoint address and size - using BREAKPOINT_FROM_PC. - - * defs.h (breakpoint_from_pc_fn): BREAKPOINT_FROM_PC function - template. - * target.h, mem-break.c (memory_breakpoint_from_pc): - Rewrite. Always define. Return NULL when memory breakpoints are - not supported. - (memory_insert_breakpoint, memory_remove_breakpoint): Call - BREAKPOINT_FROM_PC. - * target.h (BREAKPOINT_FROM_PC): Provide default. - * gdbint.texinfo (BREAKPOINT_FROM_PC): Document. - - * config/rs6000/tm-rs6000.h (BREAKPOINT): Delete macro. - (BREAKPOINT_FROM_PC): Define. - ({BIG,LITTLE}_BREAKPOINT): Move macros from here. - * rs6000-tdep.c: To here. - (rs6000_breakpoint_from_pc): New function. - - * config/mn10300/tm-mn10300.h (BREAKPOINT): Delete macro. - (BREAKPOINT_FROM_PC): Define, call. - * mn10300-tdep.c (mn10300_breakpoint_from_pc): New function. - - * config/mips/tm-mips.h ({BIG,LITTLE}_BREAKPOINT, - IDT_{BIG,LITTLE}_BREAKPOINT, PMON_{BIG,LITTLE}_BREAKPOINT, - MIPS16_{BIG,LITTLE}_BREAKPOINT): Move macros from here. - * mips-tdep.c: To here. - - * config/arm/tm-arm.h ({BIG,LITTLE}_BREAKPOINT): Delete macros. - ({ARM,THUMB}_{BE,LE}_BREAKPOINT): Move macros from here. - * arm-tdep.c: To here. - - * remote-array.c (memory_breakpoint_size): Delete variable. - (array_insert_breakpoint): Obtain breakpoint size using - BREAKPOINT_FROM_PC. - * remote-st.c (memory_breakpoint_size, st2000_insert_breakpoint): - Ditto. - * remote-os9k.c (memory_breakpoint_size, - rombug_insert_breakpoint): Ditto. - * remote-e7000.c (memory_breakpoint_size): Ditto. - -Mon Nov 23 11:38:40 1998 Michael Snyder - - * symfile.c (deduce_language_from_filename): rewrite so as to - work from a table of filename extensions, modifiable by the user. - (filename_language_table): new data structure. - (set_ext_lang_command): new function for new command, "set - extension-language". (info_extension_language_command): new - function for new command "info extension-languages". - (add_filename_language, init_filename_language_table): new - support functions for the above. - * language.c (language_enum): new function. Support for above. - -Mon Nov 23 10:47:54 1998 Andrew Cagney - - * config/sh/tm-sh.h, config/mn10200/tm-mn10200.h, - config/m32r/tm-m32r.h, config/arm/tm-arm.h, config/i960/tm-i960.h, - config/gould/tm-np1.h, config/d10v/tm-d10v.h, - config/v850/tm-v850.h, config/pa/tm-hppa.h, config/a29k/tm-a29k.h, - config/mn10300/tm-mn10300.h, config/mips/tm-mips.h - (USE_STRUCT_CONVENTION): Cleanup, define macro as function. - - * sh-tdep.c (sh_use_struct_convention), mn10200-tdep.c - (mn10200_use_struct_convention), i960-tdep.c - (i960_use_struct_convention), gould-tdep.c - (gould_use_struct_convention), d10v-tdep.c - (d10v_use_struct_convention), v850-tdep.c - (v850_use_struct_convention), hppa-tdep.c - (hpha_use_struct_convention), m32r-tdep.c - (m32r_use_struct_convention), arm-tdep.c - (arm_use_struct_convention), mn10300-tdep.c - (mn10300_use_struct_convention), a29k-tdep.c - (a29k_use_struct_convention), mips-tdep.c - (mips_use_struct_convention): New functions - - * value.h, values.c (generic_use_struct_convention): New function, - replace macro. - * values.c (USE_STRUCT_CONVENTION): Macro defaults to function - generic_use_struct_convention. - -Sat Nov 21 17:15:40 1998 Philippe De Muyter - - * breakpoint.c (bpstat_stop_status): Do not increment hit_count - of breakpoint if condition is not true. - - * coffread.c (coff_symtab_read): Discard C_LABEL's that are not - function entry points, to avoid getting them in the stack dump - instead of the actual function. - - * config/m68k/delta68.mh (NAT_FILE): Undo 1998-08-18 change; - without NAT_FILE definition, configure will assume that GDB cannot - run native. - * config/m68k/nm-delta68.h (KERNEL_U_SIZE): New macro. - * delta68-nat.c (kernel_u_size): New function. - -Fri Nov 20 10:13:03 1998 Andrew Cagney - - * buildsym.c (end_symtab): Cleanup PROCESS_LINENUMBER_HOOK. - -Thu Nov 19 15:21:04 1998 Geoffrey Noer - - * rdi-share/host.h: if compiling under Cygwin, make sure new - preprocessor define is defined. Define it if not. - * rdi-share/hostchan.h: ditto - * rdi-share/aclocal.m4: regenerate - * rdi-share/configure: regenerate - -Thu Nov 19 14:43:44 1998 Geoffrey Noer - - * configure.in: switch back to checking __CYGWIN32__ - * configure: regenerate - -Thu Nov 19 09:53:00 1998 Andrew Cagney - - * exec.c (exec_file_command): Cleanup. Replace #if - NEED_TEXT_START_END with if(). - * config/pa/nm-hppah.h (NEED_TEXT_START_END): Redefine to be 1. - * config/convex/tm-convex.h (NEED_TEXT_START_END): Ditto. - * config/gould/tm-np1.h (NEED_TEXT_START_END): Ditto. - * config/a29k/tm-a29k.h (NEED_TEXT_START_END): Ditto. - -Thu Nov 19 13:06:22 1998 Geoffrey Noer - - * main.c: Wait until more time has passed before calling - new cygwin_ funcs, revert back to the cygwin32_ ones for now. - * win32-nat.c: Ditto. - -Wed Nov 18 15:03:17 1998 Andrew Cagney - - * 29k-share/udi/udip2soc.c (UDIConnect): Replace sys_errlist with - strerror. - -Mon Nov 16 14:17:05 1998 Geoffrey Noer - - * defs.h: if compiling under Cygwin, define __CYGWIN__ if - __CYGWIN32__ is defined and __CYGWIN__ isn't for backwards - compatibility. - -Fri Nov 13 00:15:08 1998 Geoffrey Noer - - Changes to account for name change from cygwin32 to cygwin and - clean up Win32-related ifdefs. - - * configure.tgt: check for cygwin* instead of cygwin32. - New cygwin gdb_target variable loses the "32". - * configure.host: check for cygwin* instead of cygwin32. - New cygwin gdb_host variable loses the "32". - * configure.in: test __CYGWIN__ instead of __CYGWIN32__, - rename gdb_cv_os_cygwin32 variable to drop the "32". Call - AM_EXEEXT instead of AC_EXEEXT since that isn't in a released - autoconf yet. - * configure: regenerate. - - * main.c: drop "32" from cygwin_ funcs, include sys/cygwin.h where - cygwin path conv protos live, instead of adding a proto here for - them here. - * {main.c, ser-tcp.c, ser-unix.c, top.c}: check __CYGWIN__ - instead of __CYGWIN32__. - * source.c: thoughout, check _WIN32 instead of WIN32. - - * config/i386/cygwin32.mh: delete. - * config/i386/cygwin.mh: new file, was cygwin32.mh. - * config/i386/cygwin32.mt: delete. - * config/i386/cygwin.mt: new file, was cygwin32.mt. - * config/i386/tm-cygwin32.h: delete. - * config/i386/tm-cygwin.h: new file, was tm-cygwin32.h. - * config/i386/xm-cygwin32.h: delete. - * config/i386/xm-cygwin.h: new file, was xm-cygwin32.h. - * config/i386/xm-windows.h: #include xm-cygwin.h now. - * config/powerpc/cygwin32.mh: delete. - * config/powerpc/cygwin.mh: new file, was cygwin32.mh. - * config/powerpc/cygwin32.mt: delete. - * config/powerpc/cygwin.mt: new file, was cygwin32.mt. - * config/powerpc/tm-cygwin32.h: delete. - * config/powerpc/tm-cygwin.h: new file, was tm-cygwin32.h. - * config/powerpc/xm-cygwin32.h: delete. - * config/powerpc/xm-cygwin.h: new file, was xm-cygwin32.h. - - * rdi-share/aclocal.m4: regenerate with aclocal. - * rdi-share/configure: regenerate with autoconf. - * rdi-share/{host.h, hostchan.c, hostchan.h, serdrv.c, serpardr.c, - unixcomm.c}: check __CYGWIN__ instead of __CYGWIN32__. - -Thu Nov 12 17:19:43 1998 John Metzler - - * remote.c (remote_get_threadinfo): Support for remote - multithread debugging. - (remote_get_threadlist): get a partial list of threads - (remote_threadlist_iterator): Step through all the threads - (init_remote_threadtests): Optional builtin unit test commands. - - * thread.c (bind_target_thread_vector): Implementa a more dynamic - way of accessing target specific thread info functions than - FIND_NEW_THREADS. - (target_thread_info): Function to get extended thread information. - - * gdbthread.h: Export internal data structures corresponding to - external detailed thread info response. This is more like a 'ps' - command than what might be expected of host based threads. This - is for embedded systems. - -Wed Nov 11 15:47:00 1998 Michael Snyder - - * procfs.c (proc_set_exec_trap): don't set PR_ASYNC or PR_FORK - in the child process for UnixWare (causes processes forked by - the debuggee to hang). - -Mon Nov 9 12:00:36 1998 Dave Brolley - - * config/fr30/fr30.mt: New file. - * config/fr30/tm-fr30.h: New file. - -1998-11-05 Jim Wilson - - * remote-vx.c (net_read_registers, net_write_registers, - vx_xver_memory, vx_resume, vx_attach, vx_detach, vx_kill): - Change errno to errno_num. - * vx-share/xdr_ptrace.c (xdr_ptrace_return): Likewise. - * vx-share/xdr_ptrace.h (struct ptrace_return): Likewise. - -Thu Nov 5 08:41:33 1998 Christopher Faylor - - * top.c (gdb_readline): Allow CRLF line termination on systems - which define CRLF_SOURCE_FILES. - * win32-nat.c: 1) Add thread support, 2) fix ability to attach to - a running process, and 3) implement limited support for cygwin - signals. - (thread_rec): New function. - (child_add_thread): Ditto. - (child_init_thread_list): Ditto. - (child_delete_thread): Ditto. - (do_child_fetch_inferior_registers): Ditto. - (do_child_store_inferior_registers): Ditto. - (handle_output_debug_string): Ditto. - (child_fetch_inferior_registers): Use do_* function to perform - operation. - (child_store_inferior_registers): Ditto. - (child_continue): Ditto. - (child_thread_alive): Ditto. - (cygwin_pid_to_str): Ditto. - (handle_load_dll): Reorganize, add first attempt at reading - dll names from attached processes. Change info messages to provide - more information when dll is already loaded. - (handle_exception): Changes mandated by new thread-aware structures. - (child_wait): Track thread creation/destruction. Handle cygwin - signals. - (child_create_inferior): Ditto. - (child_resume): Ditto. - (child_kill_inferior): Ditto. Close child process handle to avoid a - handle leak. - (child_ops): Fill out child_ops fields that deal with threads. - * config/i386/tm-cygwin32.h: Declare function and macro needed - for converting a cygwin "pid" to a string. - * config/i386/xm-cygwin32.h: define HAVE_SIGSETMASK as 0 since - sigsetmask is not defined in cygwin. - -Thu Nov 5 08:38:18 1998 Christopher Faylor - - * win32-nat.c: Remove obsolete PPC conditionals. - -Wed Nov 4 18:44:31 1998 Dave Brolley - - * configure.tgt: Add fr30-*-elf*. - -1998-11-03 Jim Wilson - - * c-exp.y (parse_number): Check TARGET_LONG_LONG_BIT when setting - high_bit to avoid undefined negative shift. - -Mon Nov 2 15:26:33 1998 Geoffrey Noer - - * configure.in: Check cygwin* instead of cygwin32*. - * configure: regenerate - -Thu Oct 29 10:04:20 1998 Michael Snyder - - [Support for trace debugging: registers that were not collected.] - * remote.c (remote_fetch_registers): accept 'xxxx' in the register - packet, with the meaning "register value is not available". - Set register_valid to -1, which will connote "no value available". - * findvar.c (read_relative_register_raw_bytes): return failure if - register_valid == -1. (value_of_register): return failure if - register_valid == -1. (read_var_value): return error if - value_of_register fails for a register variable. - (value_from_register): return failure if register_valid == -1. - * eval.c (evaluate_subexp_standard): return error if - value_of_register fails for a register used in an expression. - * infcmd.c (do_registers_info): display "value not available" - for registers for which register_valid == -1. - - * tracepoint.c (set_raw_tracepoint): just save the filename as is - from the symbol table, rather than trying to prepend the dir name. - Also save the bfd section. (tracepoints_info): use the section - when looking up the function name. - * tracepoint.h: add section field to tracepoint struct. - -Wed Oct 28 08:01:38 1998 Mark Alexander - - * sparcl-tdep.c (send_resp, sparclite_serial_start, - sparclite_serial_write): Use remote_timeout instead of hardcoded - two second timeout. - (download): Fix adjustment of a.out load addresses. - -Wed Oct 28 12:32:58 1998 Andrew Cagney - - * configure.in (--enable-build-warnings): Finish rename from - --enable-warnings. - (enable-build-warnings): Add -Wpointer-arth, allow =* for - sim/common compatibility. - * configure: Re-generate. - -Wed Oct 21 08:44:30 1998 Andrew Cagney - - * 29k-share/udi/udip2soc.c: Replace sys_errlist with strerror(). - -Thu Oct 22 09:56:55 1998 Andrew Cagney - - * config/rs6000/aix4.mh (NATDEPFILES): Move xcoffread.o from here. - * config/rs6000/aix4.mt (TDEPFILES): To here. - -Wed Oct 21 10:02:31 1998 Andrew Cagney - - * rdi-share/unixcomm.c: Provide definitions of SERPORT and PARPORT - on BSD hosts. - -1998-10-19 Jason Molenda (jsm@bugshack.cygnus.com) - - * configure.in (AM_EXEEXT): Use AC_EXEEXT instead. - * configure: Regenerated. - -Sat Oct 17 17:39:23 1998 Felix Lee - - * core-sol2.c: #include , for sol2.7 weirdness. - -Fri Oct 16 15:31:38 1998 Michael Snyder - - * m32r-tdep.c (decode_prologue): Return failure if we reach - the end of the function without finding the end of the prologue. - -1998-10-16 Jason Molenda (jsm@bugshack.cygnus.com) - - * command.c copying.c copying.awk core-aout.c core-regset.c - corelow.c dcache.c i386-tdep.c i386v4-nat.c i387-tdep.c - infcmd.c infptrace.c infrun.c remote.c solib.c symfile.c - symmisc.c valarith.c: Add prototypes. - - * defs.h: Add prototype for utils.c::do_run_cleanups. - - * gdbtypes.c: Add prototypes. - (make_pointer_type): Add braces to remove nested if-else ambiguity. - (make_reference_type): Ditto. - - * printcmd.c (printf_command): Initialize 'f' and 'string' at - function startup to suppress possibly-used-before-initialized warning. - - * remote-utils.c: Add prototypes. - (sr_pollchar): Add braces to remove nested if-else ambiguity. - - * ser-tcp.c: Add prototypes. - (wait_for): Add braces to remove nested if-else ambiguity. - (tcp_readchar): Ditto. - - * ser-unix.c: Add prototypes. - (get_tty_state): Don't define errno here. - (hardwire_readchar): Only define 't' if we are compiling in a Cygwin - environment. - - * symtab.c: Add prototypes. - (find_methods): Add braces to remove nested if-else ambiguity. - (search_symbols): Set 'i' to an initial value to suppress a - possibly-used-before-initialized warning. - - * valops.c: Add prototypes. - (value_cast): Set 'eltype2' to an initial value to suppress a - possibly-used-before-initialized warning. - (value_of_variable): Add braces to remove nested if-else ambiguity. - (value_of_this): Ditto. - - * valprint.c: Add prototypes. - (print_floating): Add braces to remove nested if-else ambiguity. - -Thu Oct 15 19:50:48 1998 Stan Shebs - - * tm-sp64.h (SETUP_ARBITRARY_FRAME, FRAME_SPECIFICATION_DYADIC): - Remove, nevermore used. - -Thu Oct 15 16:55:00 1998 Andrew Cagney - - * command.c: Include "wait.h" after, rather than before, . - "wait.h" was defining all WIF* macro's instead of filling in those - that missed. - -1998-10-14 Jason Molenda (jsm@bugshack.cygnus.com) - - * defs.h: Move _initialize_printcmd, _initialize_stack, - _initialize_blockframe out of here and in to their respective .c - files. - * blockframe.c: Move _initialize_blockframe prototype to here. - * printcmd.c: Move _initialize_printcmd prototype to here. - * stack.c: Move _initialize_stack prototype to here. - - * source.c, symtab.h: Move _initialize_source prototype to the .c - file. - * values.c, value.h: Move _initialize_values prototype to the .c file. - * gdbthread.h, thread.c: Move _initialize_thread prototype to the .c - file. - * breakpoint.c, breakpoint.h: Move _initialize_breakpoint prototype - to the .c file. - - * abug-rom.c alpha-nat.c alpha-tdep.c annotate.c ax-gdb.c bcache.c: - Standardize comments for the prototype section of these files. - - * configure.in: Look in libc for wctype before looking for it in libc. - -Tue Oct 13 18:56:51 1998 Felix Lee - - * sol-thread.c (ps_pstop, etc): simple test for proc_service.h - version didn't work for sol2.6; pushed it to autoconf. - * configure.in (gdb_cv_proc_service_is_old): new test. - * acconfig.h (PROC_SERVICE_IS_OLD): new define. - * configure, config.in: regenerate. - -1998-10-13 Jason Molenda (jsm@bugshack.cygnus.com) - - * blockframe.c (find_pc_sect_partial_function): Add braces to avoid - possible nested-if confusion. - * breakpoint.c (breakpoint_here_p): Ditto. - (breakpoint_inserted_here_p): Ditto. - (breakpoint_thread_match): Ditto. - - * gnu-regex.c: Define _REGEX_RE_COMP only if it isn't already defined. - * gnu-regex.h: Define _REGEX_RE_COMP to pick up old compatability - prototypes. - - * symtab.h: Add prototype for _initialize_source. - * value.h: Add prototype for _initialize_value. - - * defs.h: Include sys/types.h or stddef.h to get size_t. - (make_cleanup): Add make_cleanup_func typedef and switch to using - a prototype for this function. - (mfree): Add prototypes for mmalloc, mrealloc, mfree if we aren't - using mmalloc. - - * ax-gdb.c breakpoint.c coffread.c corelow.c dbxread.c - dwarf2read.c dwarfread.c elfread.c eval.c exec.c infcmd.c infrun.c - mipsread.c nlmread.c os9kread.c parse.c printcmd.c symfile.c - symmisc.c symtab.c thread.c top.c tracepoint.c typeprint.c - valops.c: Cast parameters passed to make_cleanup to use the new - make_cleanup_func typedef. - -Tue Oct 13 00:51:48 1998 Felix Lee - - * sol-thread.c (ps_pstop, etc): different solaris versions have - slightly different prototypes in proc_service.h; compensate. - -1998-10-12 Jason Molenda (jsm@bugshack.cygnus.com) - - * Makefile.in (AWK): Unused; remove. - * configure.in: Remove unused autoconf checks for MINIX, memcpy, - poll, select, strings.h. - * config.in: Regenerated. - * configure: Regenerated. - -1998-10-12 Jason Molenda (jsm@bugshack.cygnus.com) - - * configure.in: Check for sys/debugreg.h, asm/debugreg.h. - * i386v-nat.c: Include asm/debugreg.h, sys/debugreg.h if it is not - present. - -Sun Oct 11 12:08:07 1998 Peter Schauer - - * dwarf2read.c (dwarf2_build_psymtabs_hard): Do not adjust the - address range of a compilation unit without children. - - * mdebugread.c (parse_partial_symbols): Fix handling of stabs - continuations, use xmalloc and xrealloc. - -Fri Oct 9 18:14:43 1998 Mark Alexander - - * rs6000-tdep.c: Don't include tm.h twice. - -1998-10-08 Keith Seitz - - * main.c (main): Remove calls to {pre,post}_add_symbol_hooks. - There should be sufficient information/hooks now to eliminate - this hack. - - * exec.c (file_command): Add a new hook here to inform ui's - when the exec file has changed. Adding it here allows the - ui to be informed after symbol reading. - - * gdbcore.h: Add declaration of file_changed_hook. - -Thu Oct 8 08:40:42 1998 Mark Alexander - - * rs6000-tdep.c (get_saved_register): Define only if - USE_GENERIC_DUMMY_FRAMES is defined. - -1998-10-06 Jason Molenda (jsm@bugshack.cygnus.com) - - Eliminate a few warnings from the compiler. - * breakpoint.h: Add prototype. - * breakpoint.c (do_enable_breakpoint): cast mem_cnt, i to (void). - * configure.in: Check if strdup declaration is necessary. - * configure: Regenerated. - * defs.h: Add prototypes. - * gdb_string.h: Only define strdup if necessary. - * gdbthread.h: Add prototypes. - * printcmd.c: Add prototyptes. - (disassemble_command): Remove unused variable 'section'. - * symtab.c: Add prototypes. - * symtab.h: Include gnu-regex.h, add prototype. - * thread.c: Add prototype. - -Mon Oct 5 19:44:39 1998 Stan Shebs - - From David Purves : - * stabsread.c (rs6000_builtin_type): Create a complex float instead - of an error. - (read_sun_floating_type): Similarly. - (read_range_type): Create a complex float if self_subrange is - true. - -Fri Oct 2 19:42:31 1998 Stu Grossman - - * c-lang.c (emit_char c_printchar c_printstr), c-lang.h (c_printstr) - ch-lang.c (chill_printstr chill_printchar) c-valprint.c (c_val_print) - ch-valprint.c (chill_val_print) expprint.c (print_subexp) f-lang.c - (f_printstr f_printchar emit_char) f-valprint.c (f_val_print) - jv-lang.c (java_printchar java_emit_char) jv-valprint.c - (java_value_print java_val_print) language.c (unk_lang_printchar - unk_lang_printstr unk_lang_emit_char) language.h (struct - language_defn LA_PRINT_STRING LA_EMIT_CHAR) m2-lang.c (m2_printstr - m2_printchar emit_char) printcmd.c (print_formatted) scm-lang.c - (scm_printstr) valprint.c (val_print_string) value.h - (val_print_string): Add emit_char routines to language_desc struct - to allow finer control over language specific character output issues. - Add character width arg to printstr routines to allow handling of - wchar_t/Unicode strings. Fix c_printstr to handle wide characters. - Supply width argument to LA_PRINT_STRING and val_print_string. - - * jv-lang.c (java_object_type dynamics_objfile java_link_class_type - get_dynamics_objfile get_java_object_type) jv-lang.h - (get_java_object_type): Make lots of things static. - - * expprint.c (dump_prefix_expression dump_subexp): Move opcode name - printing to common routine (op_name). - * (dump_subexp): Add support for OP_SCOPE. - -Fri Oct 2 16:25:54 1998 Stan Shebs - - * configure.host (i[3456]86-*-windows): Remove, no longer used. - * mswin: Remove directory, no longer used. - -Fri Oct 2 18:52:20 1998 Fernando Nasser - - * sol-thread.c: Fixed prototypes and calls to supply_fpregset and - fill_fpregset - -1998-10-02 Keith Seitz - - * remote.c (remote_interrupt): Rewrite to use remote_stop. - (remote_interrupt_twice): Remove. remote_stop now handles it. - (remote_stop): New function which handles interrupting the - remote target so that CLUI and GUI use the same core functions - to achieve the same goal. - (remote_wait): Change to handle remote_stop properly. - [interrupted_already]: New static global to help remote_stop. - [remote_ops, extended_remote_ops]: Add remote_stop for to_stop member. - - * target.c: Rename static function "ignore" to "target_ignore" and - export it so that gdb can determin if some target vector member is - actually not defined. Replace all occurances of ignore. - - * target.h: Export target_ignore. - -Fri Oct 2 03:51:48 1998 Peter Schauer - - * target.c (target_xfer_memory): Handle requests with zero - transfer length right away. - - * values.c (unpack_double): Set up code, length and signedness of - type _after_ checking for typedef. - -Thu Oct 1 15:39:27 EDT 1998 Frank Ch. Eigler - - * breakpoint.c (bpstat_stop_status): Do not consider an - untripped watchpoint as a "hit". - -Thu Oct 1 20:52:39 1998 Andrew Cagney - - * exec.c (exec_file_command), convex-tdep.c (exec_file_command), - arm-xdep.c (exec_file_command), remote-rdp.c - (remote_rdp_create_inferior), remote-os9k.c - (rombug_create_inferior), remote-mm.c (mm_create_inferior), - remote-eb.c (eb_create_inferior), remote-es.c - (es1800_create_inferior), remote-rdi.c (arm_rdi_create_inferior), - remote-sim.c (gdbsim_create_inferior), remote-utils.c - (gr_create_inferior), remote-st.c (st2000_create_inferior), - remote-nindy.c (nindy_create_inferior), remote-hms.c - (hms_create_inferior), remote-e7000.c (e7000_create_inferior), - remote-array.c (array_create_inferior), remote-adapt.c - (adapt_create_inferior): Replace "exec" with "executable" in - messages. - -1998-09-25 Keith Seitz - - * rdi-share/unixcomm.c: If using cygwin32, also use the SERPORT and - PARPORT defines for win32. - (Unix_MatchValidSerialDevice): For cygwin32, valid serial port names - start with "com", not "/dev/tty". - (Unix_OpenSerial): Do not use O_NONBLOCK on cygwin32. - - * rdi-share/devsw.c (DevSW_Close): Free the device's state - (SwitcherState) so that the device may be reopened. - - * remote-rdi.c (mywritec): Send all output through gdb's *_unfiltered - functions, ignoring non-ASCII chars, so that non-tty UI's can snarf - the output from fputs_hook. - (mywrite): Ditto. - (arm_rdi_open): Set inferior_pid. - (arm_rdi_detach): Pop the target off the target stack so that - users can attach and detach multiple times. - (arm_rdi_close): Close the opened device and reset inferior_pid, too. - -1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com) - - * configure.in: Change --enable-warnings to --enable-build-warnings. - * configure: Updated. - -1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com) - - * configure.in (WARN_CFLAGS): Add -Wmissing-prototypes. - * configure: Regenerated. - -1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com) - - * configure.in: Add --enable-warnings. - Adjust whitespace of other --with and --enable options so that - configure --help lines up correctly. - * aclocal.m4: Ditto. - * Makefile.in (WARN_CFLAGS): Add. Set by configure. - * configure: Regenerated. - -Thu Sep 24 15:44:34 1998 Stan Shebs - - * remote-rdi.c: Fix formatting, remove some commented-out code. - (init_rdi_ops): Omit needless initializations. - -Wed Sep 23 18:21:03 1998 Andrew Cagney - - * remote.c (remote_address_masked): New function - mask address - according to REMOTE_ADDRESS_SIZE. - (remote_address_size): New global. - (hexnumstr): New function - convert arbitrary unsigned to hex. - (remote_write_bytes, remote_read_bytes): Use hexnumstr to - construct packet address. Mask address when necessary. - (_initialize_remote): Add "set remoteaddresssize" command, set - REMOTE_ADDRESS_SIZE variable. - - * NEWS: Update. - -Wed Sep 23 18:08:52 1998 Andrew Cagney - - * remote.c (_initialize_remote, packet_command, print_packet): - Pretty print code. - -Wed Sep 23 12:32:54 1998 - - * remote.c (packet_command): Test REMOTE_DESC to determine if - remote connection is open. - -Tue Sep 22 22:27:24 1998 Mark Alexander - - Patch from Dawn Perchik : - * rs6000-tdep.c (pop_frame): Handle generic dummy frames. - (push_arguments): Likewise. - (frame_saved_pc): Likewise. - (rs6000_frame_chain): Likewise. - (ppc_push_return_address): New function. - (get_saved_register): New function. - * config/powerpc/tm-ppc-eabi.h: Add generic dummy frame macros. - -Mon Sep 21 19:29:32 1998 Stu Grossman - - * defs.h utils.c (fputc_filtered): New function. Does the obvious... - * jv-lang.c (java_printchar): Fix output of chars > 0xff. Fold - java_emit_char into java_printchar. - * language.h (PRINT_LITERAL_FORM): Reformat for readability. - -Mon Sep 21 14:38:03 1998 Catherine Moore - - * config/arm/tm-arm.h (*_BREAKPOINT): Define both little endian - and big endian breakpoint patterns. - - * arm-tdep.c (arm_break_point_from_pc): Insert either big endian - or little endian breakpoints depending upon target byte order. - -Fri Sep 18 07:53:08 1998 Peter Schauer - - * sol-thread.c (sol_thread_notice_signals): Use PIDGET when - passing pid down to procfs_notice_signals. - -Wed Sep 16 14:57:14 1998 Stu Grossman - - * stabsread.c (resolve_symbol_reference): Return 1 on success, 0 on - failure. - * (define_symbol): Check return value from resolve_symbol_reference, - and drop symbol if it fails. - -Tue Sep 15 15:24:16 1998 Stu Grossman - - * stabsread.c: Make all complaints static. - * Fix formatting of live range splitting code. - * (resolve_symbol_reference define_symbol resolve_live_range): Change - errors to complaints so that bad live range symbols won't abort the - entire symbol table. Handle errors by aborting just the current - symbol. - * (ref_init): Goes away. Folded into ref_add(). - * (REF_MAP_SIZE): Put parens around parameter so that args like - `1 + 2' get handled correctly (yes, this was a real bug). - * (ref_add): Remove check for allocation failures. Not necessary - when using xrealloc(). Fix pointer arithmetic problem when clearing - memory. This and the previous patch prevent random SEGV's when there - are lots of live range symbols. - -Tue Sep 15 14:02:01 1998 Nick Clifton - - * remote-rdi.c: Prevent multiple attempts to close the remote - connection. - -Tue Sep 15 10:24:17 1998 Andrew Cagney - - * printcmd.c (examine_i_type): New static - type for instructions. - (do_examine): For "i" format, specify examine_i_type. - (do_examine): Call value_at_lazy instead of value_at so that - examine data is only fetched if it is used. - (x_command): If examine data was not fetched, set convenience - variable "__" to void. - (_initialize_printcmd): Initialize examine_i_type. - -Sun Sep 13 01:34:59 1998 Michael Snyder - - * blockframe.c (find_pc_sect_partial_function): use bfd section - of msymbol for end of section comparison. - -Fri Sep 11 14:02:49 1998 Michael Snyder - - * tracepoint.c: clean up several unused variables and such. - -Fri Sep 11 12:38:34 EDT 1998 Zdenek Radouch (radouch@cygnus.com) - - * arm-tdep.c (arm_push_arguments): fixed frame construction - -Thu Sep 10 20:51:23 1998 Michael Snyder - - * mn10300-tdep.c (mn10300_analyze_prologue): guard against NULL. - -Wed Sep 9 19:37:36 1998 Stan Shebs - - * dbxread.c (IGNORE_SYMBOL): Remove definition, is never used. - * os9kread.c: Remove comment mentioning IGNORE_SYMBOL. - -Wed Sep 9 11:39:05 1998 Ron Unrau - - * blockframe.c(find_pc_sect_partial_function): look for min syms in - the same section when trying to guess the end of a function. - * symfile.c(list_overlays_command): use print_address_numeric - * remote-sim.c: export simulator_command - -1998-09-08 Jason Molenda (jsm@bugshack.cygnus.com) - - * breakpoint.c (bpstat_stop_status): Declare a bp match if the - current fp matches the bp->fp OR if the current fp is less than - the bp->fp if we're looking at a bp_step_resume breakpoint. - -Tue Sep 8 19:42:58 1998 Stan Shebs - - * symtab.h (struct symtab): Remove EXTRA_SYMTAB_INFO hook, - not currently used. - * symfile.c (allocate_symtab): Deprecate use of - INIT_EXTRA_SYMTAB_INFO here. - -Fri Sep 4 15:33:25 1998 Stan Shebs - - * README: Update remote debugging and testsuite info. - -Thu Sep 3 13:50:20 1998 Mark Alexander - - * config/mn10300/tm-mn10300.h (FP_REGNUM): Redefine to be a - pseudo-register, not the same as a3. - (D2_REGNUM, D3_REGNUM, A2_REGNUM, A3_REGNUM): Define. - * mn10300-tdep.c (fix_frame_pointer): New function. - (set_movm_offsets): Use register number macros instead of - hard-coded constants. - (mn10300_analyze_prologue): Fix to handle redefinition of FP_REGNUM. - (mn10300_frame_chain): Fix to handle redefinition of FP_REGNUM; - use register number macros instead of hard-coded constants; - add missing parameter to call of mn10300_analyze_prologue. - (mn10300_frame_saved_pc): Use register number macros instead of - hard-coded constants. - -Tue Sep 1 12:04:57 EDT 1998 Zdenek Radouch (radouch@cygnus.com) - - Changes to support/fix ARM/ELF port. Use MAKE_MSYMBOL_SPECIAL for - both ELF and COFF; - * elfread.c (elf_symtab_read): use ELF specific macro - * coffread.c (coff_symtab_read): use COFF_MAKE_MSYMBOL_SPECIAL() - * arm-tdep.c: separate COFF and ELF thumb processing - disable --mapcs-float processing - * dwarf2read.c: Disabled building of minimal symbols - * config/arm/tm-arm.h: new macros for distinguishing arm/thumb - * config/mips/tm-mips.h: use ELF specific macro - -Mon Aug 31 15:42:10 1998 Tom Tromey - - * top.c (context_hook): Define. - -Tue Aug 25 13:21:58 1998 Michael Snyder - - * ax-gdb.c (gen_var_ref): Allow for typedef types. - (gen_cast, gen_bitfield_ref, gen_expr, gen_deref): ditto. - -Mon Aug 24 18:29:03 1998 Michael Snyder - - * tracepoint.c (collect_symbol): Handle register doubles that - are stored in two registers. - -Mon Aug 24 14:39:08 1998 Mark Alexander - - * sh-stub.c (undoSStep): Improve comment. - * sparc-tdep.c (sparc_extract_struct_value_address): Simplify to use - same method on both 32-bit and 64-bit machines. - * sparcl-tdep.c (sparclite_check_watch_resources): Simulator doesn't - support hardware breakpoints. - * config/sparc/tm-sparc.h (CALL_DUMMY): Improve comments. - -1998-08-20 Jason Molenda (jsm@bugshack.cygnus.com) - - * rdi-share/Makefile.am (INCLUDES): Fix typeo. - * rdi-share/Makefile.in: Regenerated. - -1998-08-19 Jason Molenda (jsm@bugshack.cygnus.com) - - * rdi-share/Makefile.am: Use just `INCLUDES' not `libname_INCLUDES'. - * rdi-share/Makefile.in: Regenerated. - -1998-08-19 Keith Seitz - - * v850ice.c (v850ice_stop): New function to stop the ICE. - (v850ice_load) Pass filename to ICE DLL. - (ice_stepi, ice_nexti, ice_cont): Do not directly call the gdb - commands -- let the GUI do it so that it can retain control - of the display. - -Wed Aug 19 15:53:52 1998 Anthony Green - - * i386v4-nat.c: Include sys/reg.h if present. - -Wed Aug 19 03:07:53 1998 Richard Henderson - - * config/alpha/alpha-linux (XDEPFILES): Build ser-tcp. - -1998-08-18 Fernando Nasser - - * symtab.c (decode_line_1): For minimal symbol, SKIP_PROLOG to - make sure we stop after the frame pointer is locaded and backtrace - prints an accurate stack. Complements changes made on Mon Jul 27 - 10:45:56 1998 - (decode_line_2): Replaced the whitespace after ">" in a prompt - which has been taken away by changes made on Sun Jul 19 02:11:45 - 1998 - -1998-08-18 Keith Seitz - - * stack.c: Define new hook, selected_frame_level_changed_hook, which - will be called whenever the selected stack level changes. - (select_frame): Call the selected_frame_level_changed_hook. - -Tue Aug 18 18:03:42 1998 Stan Shebs - - * remote-rdi.c (arm_rdi_open): Pass serial device name to - Adp_OpenDevice, and include it in error reports. - -1998-08-18 Jason Molenda (jsm@bugshack.cygnus.com) - - * configure.in: Add more header files to AC_CHECK_HEADERS. - * configure: Regenerated. - - * command.c: Include wait.h or sys/wait.h if present. - * inftarg.c: Ditto. - * core-aout.c: Include ptrace.h or sys/ptrace.h if present, based - on autoconf test. - * infptrace.c: Ditto. - - * expprint.c: Include ctype.h for isprint prototype. - * i386aix-nat.c: Include sys/reg.h if autoconf says it is present. - * i386v-nat.c: Include ptrace.h, sys/ptrace.h, and sys/reg.h if - present, based on autoconf test. - - * utils.c: Include curses.h and term.h if present. - (puts_debug): Change 'carriage_return' local variable to return_p - to avoid name clash. - - * config/m68k/nm-apollo68b.h: Don't define PTRACE_IN_WRONG_PLACE, - determine it with autoconf. - * config/i386/nm-linux.h: Don't define NO_SYS_REG_H, determine it - with autoconf. - * config/i386/nm-i386sco.h: Don't define NO_PTRACE_H, determine it - with autoconf. - * config/i386/nm-i386v.h: Ditto. - * config/i386/nm-symmetry.h: Ditto. - * config/m88k/xm-cxux.h: Ditto. - * config/m88k/xm-dgux.h: Ditto. - - * config/m68k/delta68.mh (NAT_FILE): nm-delta68.h no longer necessary. - * config/m68k/nm-delta68.h: Removed. - -Fri Aug 14 11:14:03 1998 Jeffrey A Law (law@cygnus.com) - - * mn10300-tdep.c (set_movm_offsets): Change second argument to - be the actual args to movm itself. All callers changed. Only set - fi->fsr.regs[x] if reg X is saved by the movm instruction. - -Fri Aug 14 04:18:23 1998 Peter Schauer - - * sol-thread.c (lwp_to_thread): Fix error message for failing - td_ta_map_lwp2thr call. - (ps_lgetLDT): Mask off upper bits in GS register when comparing - with selector. - -Wed Aug 12 16:30:01 1998 Frank Ch. Eigler - - * remote-sim.c (simulator_command): Reset register cache after - simulator command. - -Wed Aug 12 09:00:26 1998 Stu Grossman - - * expprint.c (dump_prefix/postfix_expression): Don't try to print - type expressions. - -Tue Aug 11 11:33:25 1998 Stu Grossman - - * c-typeprint.c (c_print_type): Don't crash if varstring is null. - * expprint.c expression.h (dump_expression): Rename to - dump_prefix_expression. - * Print out the expression in normal form. Call print_longest - instead of trying to do it ourselves. - * (dump_postfix_expression): New function, prints out the expression - with indentation and better formatting and interpretation. - * parse.c (parse_exp_1): Put calls to dump expressions under ifdef - MAINTENANCE_CMDS and expressiondebug variable. - -Thu Aug 6 13:20:02 1998 Ron Unrau - - * infrun.c (wait_for_inferior): use stop_func_name instead of - stop_func_start to decide that no debug info exists. - -Thu Jul 30 13:53:50 1998 Mark Alexander - - * mips-tdep.c (mask_address_p): New variable. - (mips_addr_bits_remove): Test mask_address_p to decide whether - to mask off the upper 32 bits of addresses. - (_initialize_mips_tdep): Add command to set mask_address_p. - (mips_call_dummy_address): New function. - * config/mips/tm-mips.h (CALL_DUMMY_ADDRESS): Redefine to - call mips_call_dummy_address. - -1998-07-29 Fernando Nasser - - * symfile.c (add_symbol_file_command): Test for the from_tty - parameter and avoid query when not interactive. - -Mon Jul 27 16:11:42 1998 Michael Snyder - - * tracepoint.c (remote_set_transparent_ranges): new function. - Send the start and end addresses of all loadable read-only - sections down to the trace target, so that it can treat them - as "transparent" (ie. don't care if they were collected or not). - -Mon Jul 27 15:38:07 1998 Mark Alexander - - * mn10300-tdep.c (mn10300_analyze_prologue): Undo previous fix - for setting frame address in optimized code; made unnecessary - by compiler fixes. - -Mon Jul 27 10:45:56 1998 Martin M. Hunt - - * symtab.c (decode_line_1): For minimal symbol, call - find_pc_sect_line() to make sure the line number gets set - properly. - (print_symbol_info): Redeclare function void. - -1998-07-27 Jason Molenda (jsm@bugshack.cygnus.com) - - * config/d10v/tm-d10v.h (REGISTER_NAMES): sp -> r15. The - stack pointer et al are synthesized from the SP_REGNUM (etc) - defines and should not be mentioned in REGISTER_NAMES. - -Fri Jul 24 14:41:19 1998 Michael Snyder - - * tracepoint.c (encode_actions): Treat register names and simple - variable names as special cases and don't convert them to byte- - codes: these things can be collected far more efficiently - without invoking the bytecode interpreter. - -Fri Jul 24 13:32:46 1998 Mark Alexander - - * config/i386/tm-i386.h (STORE_STRUCT_RETURN): Make it - work on hosts of any endianness. - * config/i386/tm-i386v.h: Ditto. - -Fri Jul 24 07:41:12 1998 Mark Alexander - - * mn10300-tdep.c (set_movm_offsets): New helper function - for mn10300_analyze_prologue. - (mn10300_analyze_prologue): Simplify by factoring out common code. - Fix bugs in setting frame address for optimized code. - Use read_memory_nobpt instead of target_read_memory. - -Thu Jul 23 17:01:17 1998 Michael Snyder - - * tracepoint.c (collect_symbol): handle LOC_ARG case. - -Thu Jul 23 15:07:40 1998 Dawn Perchik - - * sparc-tdep.c (sparc_init_extra_frame_info): Recognize when we're - in a function prologue before the SAVE instruction. - (sparc_frame_saved_pc): Ditto. - * config/sparc/tm-sparc.h (EXTRA_FRAME_INFO): Add in_prologue flag. - -Thu Jul 23 14:58:09 1998 Dawn Perchik - - * i386-tdep.c (i386_get_frame_setup): Recognize function - prologues in code compiled with -fcheck-stack. - -Thu Jul 23 14:49:27 1998 Dawn Perchik - - * remote-mips.c (remote_mips_insert_hw_breakpoint, - remote_mips_remove_hw_breakpoint): New functions for hardware - breakpoints on LSI targets. - * config/mips/tm-embed.h (target_remove_hw_breakpoint, - target_insert_hw_breakpoint): Define to call - remote_mips_insert_hw_breakpoint and remote_mips_remove_hw_breakpoint, - respectively. - -1998-07-21 Fernando Nasser - - * source.c (print_source_lines): Print "No such file or directory" - just once. - (directory_command): same as above; resets if user issues dir. - -Sun Jul 19 02:11:45 1998 Martin M. Hunt - - * symtab.c (decode_line_2): Instead of printing a prompt - and calling command_line_input() without a prompt, just - call it with the proper args. This makes the GUI work too. - -Fri Jul 17 9:26:50 1998 Ron Unrau - - * blockframe.c (find_pc_sect_partial_function): allow for the possi- - bility of multiple symbols at the same address when finding high. - * breakpoint.c (resolve_sal_pc): if the function based section lookup - fails, try getting the section from the minimal symbol table. - * parse.c (write_exp_msymbol): use symbol_overlayed_address to get - the LMA of a minimal symbol if unmapped. - * symtab.c (find_line_symtab): change interface to return symtab - containing the best linetable found. - (decode_line_1): use find_line_symtab to set val.symtab. This should - improve support for source files with multiple symtabs. - -Wed Jul 15 11:51:33 1998 Keith Seitz - - * main.c (main): Fix violations of GNU coding standard. - - * breakpoint.c: Export delete_command. - - * infcmd.c: Export continue_command, stepi_command, and nexti_command. - - * Makefile.in: Add target for v850ice.o. - - * configure.tgt: Add cygwin32 dependencies for v850 ice. - -Wed Jul 15 10:58:29 1998 Nick Clifton - - * tracepoint.c (set_raw_tracepoint): Cope with symbols that do not - have an associated directory. - -Mon Jul 13 15:21:04 1998 Mark Alexander - - * utils.c (puts_debug): Display non-printable characters in hex - instead of octal. - -Thu Jul 9 16:16:47 1998 Jeffrey A Law (law@cygnus.com) - - * mn10300-tdep.c (mn10300_generic_register_names): New variable. - (set_machine_hook): New function. Copy the appropriate register - names into reg_names. - (_initialize_mn10300_tdep): Set up to call set_machine_hook. - * tm-mn10300 (NUM_REGS): Bump to 32. - (REGISTER_NAMES): Updated accordingly. - - -Tue Jul 7 7:40:13 1998 Ron Unrau - - * symtab.c (find_pc_sect_psymbol): allow case where textlow is 0 - -Thu Jul 2 15:57:58 1998 Frank Ch. Eigler - - * breakpoint.c (resolve_sal_pc): Accept absence of innermost - Lexical block for breakpoint resolution. - -Thu Jul 2 10:22:00 1998 Dawn Perchik - - * mdebugread.c (parse_partial_symbols): Go ahead and read the .mdebug - section, but just don't add a 2nd minimal symbol if this is an .mdebug - section in an ELF file. - -1998-07-01 Jim Blandy - - * Makefile.in (ax-general.o): Depend on $(defs_h) too. - (ax_h): Bother to define this. - -Mon Jun 29 19:01:18 1998 Jim Wilson - - * gnu-regex.c (re_comp): Add cast to char * before gettext calls. - -Sun Jun 28 11:35:48 1998 Peter Schauer - - Improve support for SunPro F77. - * dbxread.c (end_psymtab, process_one_symbol): Handle minimal - symbols with trailing underscore names. - * minsyms.c (find_stab_function_addr): Ditto. - * dbxread.c (process_one_symbol): Ignore N_ALIAS for now. - * partial-stab.h (case N_ALIAS): Ditto. - * stabsread.c (read_sun_builtin_type): Handle boolean types. - -Fri Jun 26 14:03:01 1998 Keith Seitz - - * symtab.h (enum namespace): Add new namespaces FUNCTIONS_NAMESPACE, - TYPES_NAMESPACE, METHODS_NAMESPACE, and VARIABLES_NAMESPACE used by - new search_symbols. - Add prototype for search_symbols and free_search_symbols. - - * symtab.c (list_symbols): Rewrite to use new search_symbols. - (file_matches): New helper function for search_symbols. - (free_search_symbols): New function which frees data returned from - search_symbols. - (print_symbol_info): New helper function which prints info about a - matched symbol to stdout. Extracted from old list_symbols. - (print_msymbol_info): New helper function which prints info about - a matched msymbol to stdout. Extracted from old list_symbols. - (symtab_symbol_info): Extracted from old list_symbols. - (variables_info): Use symtab_symbol_info. - (functions_info): Use symtab_symbol_info. - (types_info): Use symtab_symbol_info. - (rbreak_command): Rewrite to use new search_symbols. - -Thu Jun 25 22:38:32 1998 Frank Ch. Eigler - - * mips-tdep.c (mips_push_arguments): Use 128-bit stack frame - alignment for inferior calls. - -Wed Jun 24 23:17:12 1998 Mark Alexander - - * mn10200-tdep.c (mn10200_analyze_prologue): Fix calculation - of jsr target address. - -Tue Jun 23 19:37:46 1998 Mark Alexander - - * config/mn10200/tm-mn10200.h (SAVED_PC_AFTER_CALL): Don't - zero upper byte of address. - -Tue Jun 23 17:32:26 1998 Michael Snyder - - * rs6000-tdep.c (pop_dummy_frame): use memcpy. - (push_arguments): use memset. - (various other places): fix up indentation and long lines. - -Tue Jun 23 11:58:35 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * configure.in: s/lXext/-lXext/ for Jillian's change. - -Tue Jun 23 11:14:04 1998 Michael Snyder - - * source.c (find_source_lines): fix indentation. - - * config/mips/tm-irix5.h: Modify to work better on irix 6, by - making FP registers 8 bytes instead of 4. - REGISTER_BYTES: redefine. REGISTER_BYTE(): redefine. - REGISTER_VIRTUAL_TYPE: redefine. MIPS_LAST_ARG_REGNUM: redefine. - * irix5-nat.c (fetch_core_registers): read 8 bytes per FP register. - * mips-tdep.c (FP_REGISTER_DOUBLE): new macro to distinguish - targets with 8-byte FP registers (don't use TARGET_MIPS64). - (STACK_ARGSIZE): new macro, how much space is taken up on the - stack for each function argument (don't use TARGET_MIPS64). - (mips_push_arguments): modify logic to work better on Irix 6 - (n32 ABI). - -Tue Jun 23 12:29:53 1998 Jillian Ye - - * configure.in: Add -lXext to mips_extra_libs - * configure: Regenerated. - -Sun Jun 21 09:31:12 1998 Ron Unrau (runrau@cygnus.com) - - * symtab.c (find_line_pc): assumed that a PC of 0 is illegal. - Changed to pass PC as arg and return 1 if valid (0 otherwise). - * symtab.h: Change prototype to match. - * symtab.c (find_line_pc_range): Use new interface. - * breakpoint.c (resolve_sal_pc): Ditto. - -Wed Jun 17 15:50:00 1998 Ron Unrau (runrau@cygnus.com) - - * parse.c (target_map_name_to_register): Check target specific - aliases *first* so that it can over-ride architectural names - -Wed Jun 17 17:13:38 1998 Said Ziouani (saidz@park-street.cygnus.com) - - * remote-sds.c (sds_start_remote): Fix printf call. - -Tue Jun 16 16:32:08 1998 Mark Alexander - - * mn10200-tdep.c (mn10200_analyze_prologue): Fix null pointer - crash when in "start". - -Tue Jun 16 14:38:40 1998 Ron Unrau (runrau@cygnus.com) - - * dbxread.c: reset function_start_offset after a finishing N_FUN - is seen. - * remote-sim.c: allow TARGET_REDEFINE_DEFAULT_OPS to override - target vectors as needed. - -Sun Jun 14 08:46:25 1998 Ron Unrau (runrau@cygnus.com) - - * partial-stab.h: 'F' and 'f' type N_FUN psymbols should pass - CUR_SYMBOL_VALUE as CORE_ADDR instead of long - * buildsym.[ch]: export pending_blocks list - -Sat Jun 13 13:02:32 1998 Dawn Perchik (dawn@cygnus.com) - - * remote.c: Fix remote help string to match that of help.exp. - -Fri Jun 12 14:22:55 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * configure.in (LIBS): Add -lw to the list of libraries if needed. - -Thu Jun 11 15:05:10 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * btowc.c: Removed. - * configure.in: Don't see if we need to replace btowc(). - * Makefile.in: Don't include LIBOBJS. - * configure: Regenerated. - * gnu-regex.c (regex_compile): Only support i18n [:foo:] if - we have btowc(). - -Wed Jun 10 15:39:14 1998 Stu Grossman - - * c-exp.y: Fix problems with parsing "'foo.bar'::func". - Some languages allow symbols with dots. - - * gdbtypes.c (check_stub_method): Cosmetic. Use more descriptive - names for parameters. - - * jv-exp.y: Parser now accepts primitive types. - * (parse_number): Use correct ifdef for scanf long double support. - * jv-lang.c (java_array_type): Initial cut at array support. - - * language.c language.h (set_language): Now returns previous language. - - * symtab.c (find_methods): Make static. Cosmetic changes, including - indentation, and adding descriptive comments. Move local variable - defs into the block they are used in. - * Don't call check_stub_method any more. Use gdb_mangle_name to - generate the full method name. find_method doesn't need all the other - goobldegook that check_stub_method does. - * (gdb_mangle_name): Use more descriptive names for parameters. Fix - comment. - * (lookup_partial_symbol lookup_block_symbol): Check for java to - ensure we can find mangled names. - * (decode_line_1): Move local variable defs into the block they are - used in. (Improves code readability.) - -Wed Jun 10 18:04:35 1998 Frank Ch. Eigler - - * gdbtypes.c (get_discrete_bounds): Assign unsigned type flag for - all-positive enum. - (create_set_type): Ditto for all-positive set values. - * values.c (unpack_field_as_long): Check for typedef in struct - field unpacking. - -Wed Jun 10 14:06:05 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * configure.in: Add some tests for gnu-regex.c's benefit. - See if btowc() function is provided in C library. - * configure, config.in: Regenerated. - * Makefile.in (CLIBS, CDEPS): Add @LIBOBJS@ to build btowc.c - if necessary. - * btowc.c: New file. - - * gnu-regex.c: Reorder wchar.h and wctype.h includes for Solaris' - benefit. - Drop namespace preserving defines for now. - -Wed Jun 10 11:53:42 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * gnu-regex.c: Include "gnu-regex.h", not "regex.h". - -Wed Jun 10 11:34:07 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * gnu-regex.c, gnu-regex.h: Change LGPL license to GPL license - to stay consistent with the rest of GDB. - -Wed Jun 10 11:27:39 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * gnu-regex.c, gnu-regex.h: Update to current FSF (glibc) versions. - -Wed Jun 10 10:58:18 1998 Michael Snyder - - * printcmd.c (disassemble_command): move overlay mapping code - "up" into find_pc_partial_function. - * blockframe.c (find_pc_partial_function): adjust start address - and end address for overlays (mapped vs. unmapped addresses), - so that all callers of this function may benefit. - * m32r-tdep.c (m32r_skip_prologue): adjust indentation. - -Mon Jun 8 16:08:10 1998 Ron Unrau - - * objfiles.c (add_to_objfile_sections): All targets to define - TARGET_KEEP_SECTION to permit them to retain bfd sections that - GDB would otherwise have discarded. - -Fri Jun 5 13:56:19 1998 Doug Evans - - * dbxread.c (read_dbx_symtab): Don't lower texthigh for last psymtab. - -Thu Jun 4 18:35:04 1998 Stan Shebs - - * remote.c (init_extended_remote_ops): Make extended_remote_ops - by copying from remote_ops, move it and init_remote_ops to - usual place at end of file, remove "void" from arg lists. - -Thu Jun 4 17:51:06 1998 Mark Alexander - - * sparc-tdep.c (sparc_fix_call_dummy): Byte-swap the call dummy - on bi-endian machines. - (sparc_extract_return_value): Handle values smaller than int on - machines with little-endian data. - (sparc_target_architecture_hook): Set bi_endian flag. - -Thu Jun 4 12:14:48 1998 Michael Snyder - - * printcmd.c (disassemble_command): Fix off-by-one error for - disassembling functions in unmapped overlay sections. - -Thu Jun 4 10:15:03 1998 Elena Zannoni - - * remote.c: merged. - - - Jim Blandy - (print_packet, remote_packet_command): New functions. - (_initialize_remote): Register the remote-packet command. - - David Taylor - (_initialize_remote): remote-compare is now - compare-sections. - - Elena Zannoni - (remote_compare_command): added warning, issued in case - of mismatch only. - -Thu Jun 4 08:25:38 1998 Michael Snyder - - * remote.c (remote_compare_command): New function, new command. - Compare object file binary image with corresponding memory on - remote target. Report differences. - -Tue Jun 2 19:05:04 1998 Mark Alexander - - * sparc-tdep.c (sparc_target_architecture_hook): Set target - byte order only when it's selectable. - -Tue Jun 2 02:01:56 1998 Mark Alexander - - * sparc-tdep.c (sparc_target_architecture_hook): New function to - set endianness based on machine type. - (_initialize_sparc_tdep): Initialize target_architecture_hook. - (sparc_print_register_hook): Print PSR and FPSR in fancy format - on 32-bit machines. - * config/sparc/tm-sparc.h (PRINT_REGISTER_HOOK): Redefine to - call sparc_print_register_hook instead of using inline code. - * config/sparc/tm-sp64.h (PRINT_REGISTER_HOOK): Remove. - -Thu May 28 17:19:14 1998 Keith Seitz - - * main.c (main): Check for NULL from getenv on CYGWIN32. - -Thu May 28 09:41:44 1998 Nick Clifton - - * monitor.c (monitor_vsprintf): Handle %%. Patch courtesy of - Felix Lee (flee@cygnus.com) - -Thu May 28 00:27:35 1998 Peter Schauer - - * mips-tdep.c (mips_push_dummy_frame): Fix calculation of - PROC_REG_OFFSET and PROC_FREG_OFFSET. - -Mon Apr 27 14:37:49 1998 Andrew Cagney - - * config/v850/tm-v850.h (REGISTER_BYTE): FP_REGNUM and - FP_RAW_REGNUM use the same register location. - - * v850-tdep.c (v850_scan_prologue): Use FP_RAW_REGNUM instead of - FP_REGNUM. - (v850_frame_chain): Ditto. - - * config/v850/tm-v850.h (REGISTER_NAMES): Add "fp". - (NUM_REGS): Update. - (FP_REGNUM): Update. - (FP_RAW_REGNUM): Define. - -Wed May 27 14:22:31 1998 Keith Seitz - - * main.c (main): Convert the path returned from getenv to a posix - path on cygwin32 hosts. - -Mon May 25 13:31:27 1998 Keith Seitz - - * remote.c (remote_open_1): If an error occurs starting the remote, - pop the target AND return. - -Sat May 23 02:23:09 1998 Peter Schauer - - * dwarf2read.c (read_subroutine_type): Set TYPE_FLAG_PROTOTYPED - on C++ functions. - * valops.c (value_arg_coerce): Add new argument to indicate whether - the function has a prototype, handle integer and float promotions - accordingly. - (call_function_by_hand): Always call value_arg_coerce, pass down - prototype information. - -Fri May 22 10:56:36 1998 John Metzler - - * remote.c (_initialize_remote): Typo extended__remote - -Thu May 21 13:14:25 1998 John Metzler - - * gnu-nat.c (init_gnu_ops): Initialization of target ops by assignment. - (_initialize_gnu_nat): Call new init - * mac-nat.c (init_child_ops): Ditto. - (_initialize_mac_nat): Ditto. - * monitor.c (init_base_monitor_ops): Ditto. - (_initialize_remote_monitors): Ditto. - * ppc-bdm.c (init_bdm_ppc_ops): Ditto. - (_initialize_bdm_ppc): Ditto. - * remote-adapt.c (init_adapt_ops): Ditto. - (_initialize_remote_adapt): Ditto. - * remote-array.c (init_array_ops): Ditto. - (_initialize_array): Ditto. - * remote-bug (init_bug_ops): Ditto. - (_initialize_remote_bug): Ditto. - * remote-e7000.c (init_e7000_ops): Ditto. - (_initialize_remote_e7000): Ditto. - * remote-eb.c (init_eb_ops): Ditto. - (_initialize_remote_eb): Ditto. - * remote-es.c (init_es1800_ops): Ditto. - (init_es1800_child_ops): Ditto. - (_initialize_es1800): Ditto. - * remote-hms.c (init_hms_ops): Ditto. - (_initialize_remote_hms): Ditto. - * remote-mm.c (init_mm_ops): Ditto. - (_initialize_remote_mm): Ditto. - * remote-nindy.c (init_nindy_ops): Ditto. - (_initialize_nindy): Ditto. - * remote_nrom.c (init_nrom_ops): Ditto. - (_initialize_remote_nrom): Ditto. - * remote-os9k (init_rombug_ops): Ditto. - (_initialize_remote_os9k): Ditto. - * remote-rdi.c (init_rdi_ops): Ditto. - (_initialize_remote_rdi): Ditto. - * remote-rdp.c (init_remote_rdp_ops): Ditto. - (_initialize_remote_rdp): Ditto. - * remote-sds.c (init_sds_ops): Ditto. - (_initialize_remote_sds): Ditto. - * remote-sim.c (init_gdbsim_ops): Ditto. - (_initialize_remote_sim): Ditto. - * remote-st.c (init_st2000_ops): Ditto. - (_initialize_remote_st2000): Ditto. - * remote-udi.c (init_udi_ops): Ditto. - (_initialize_remote_udi): Ditto. - * remote-vx.c (init_vx_ops): Ditto. - (init_vx_run_ops): Ditto. - (_initialize_vx): Ditto. - * remote.c (init_remote_ops): Ditto. - (init_extended_remote_ops): Ditto. - (_initialize_remote): Ditto. - * sparcl-tdep.c (init_sparclite_ops): Ditto. - (_initialize_sparcl_tdep): Ditto. - * v850ice.c (init_850ice_ops): Ditto. - (_initialize_v850ice): Ditto. - * win32-nat.c (init_child_ops): Ditto. - (_initialize_inftarg): Ditto. - -1998-05-21 Jim Blandy - - * ax-gdb.c (const_var_ref): Don't handle function names. I don't - want to implement all the "usual unary conversion" rules for - constants. - (gen_usual_unary): Turn "function" values into "pointer to - function" values, in accordance with ANSI. - (gen_deref): Don't do the usual unary conversions here. Let the - caller do it. Note that dereferencing a function pointer yields - a function designator, which we call an rvalue, not an lvalue. - (gen_address_of): Handle functions specially. - (gen_struct_ref): Perform the usual unary conversions before - calling gen_deref. - (gen_expr): In case for the prefix '*' operator, call - gen_usual_unary manually. - -Wed May 20 15:29:41 1998 Gavin Koch - - * mips/tm-tx39.h (MIPS_DEFAULT_FPU_TYPE): Defined as MIPS_FPU_NONE. - * mips/tm-tx39l.h: Same. - -Wed May 20 10:12:11 1998 John Metzler - - * m32r-tdep.c (decode_prologue): Handle frames compiled with -Os. - Split out as separate function called by skip prologue and scan - prologue. new formula handles optimization in which the prologue - is interleaved with the body of the function. Also recognizes new - variations of prologue encoding. Use of frame pointer is - essential to debugging, -fno-omit-frame-pointer - (m32r_skip_prologue): Call decode prologue, ignore line info - (m32r_scan_prologue): Call decode prologue, ignore line info. - -Tue May 19 17:23:54 1998 John Metzler - - * w89k-rom.c (_initialize_w89k): Call new init function - (init_w89k_cmds): Convert to dynamic initialization of monitor_ops - data structure for forward compatability with additions to the - data structure. - * dbug-rom.c (_initialize_dbug_rom): ditto - (init_dbug_cmds): ditto - * m32r-rom.c (_initialize_m32r_rom): ditto - (init_m32r_cmds): ditto - -Tue May 19 14:54:11 1998 Michael Snyder - - * tracepoint.c (memrange_cmp): use const void * args to avoid - ANSI compiler warnings. - -1998-05-19 Jim Blandy - - * ax-gdb.c (gen_fetch, gen_var_ref, gen_deref, find_field, - gen_bitfield_ref, gen_expr): Call error, not abort. - * ax-general.c (read_const, generic_ext, ax_trace_quick, - ax_label, ax_const_d, ax_reg, ax_print): Same. - - * tracepoint.c: Remove the $(...) syntax for memranges. - (validate_actionline, encode_actions, trace_dump_command): Remove - clauses for the $(...) syntax. - (parse_and_eval_memrange): Function deleted. - (_initialize_tracepoint): Update function description. - - * ax-gdb.c (_initialize_ax_gdb): Make the "agent" command a - subcommand of "maintenance", as it should have been from the - beginning. #include "gdbcmd.h", to get the declaration for - maintenancelist. - * Makefile.in: Document that dependency. - -Tue May 19 12:00:58 1998 Elena Zannoni - - * tracepoint.c (get_tracepoint_by_number): new function, to access - traceframe_number for use of the GUI. - - * tracepoint.h: added prototype for get_traceframe_number. - -Mon May 18 13:34:27 1998 Keith Seitz - - * dbxread.c (process_one_symbol): If block addresses are relative to - function start addresses, reset function_start_address whenever a new - source file is seen. - -Mon May 18 13:04:27 1998 Michael Snyder - - * tracepoint.c (get_tracepoint_by_number): make sure to advance - arg pointer even if we fail to parse a useful number. Otherwise, - since this function is called in a loop, it may loop forever! - Also change strtol call to allow arbitrary radix. - (map_args_over_tracepoints (and other places)): add QUIT; call - to loop, to allow breakout using control-C. Not all loops were - analyzed to make sure they could terminate cleanly, but even - terminating with a messed-up tracepoint list would be better - than not terminating at all! - (tdump_command): check to see if we're connected to a trace- - capable target (currently only "remote") before doing anything - else. - -Sat May 16 22:21:48 1998 Frank Ch. Eigler - - * config/d30v/tm-d30v.h (INIT_FRAME_PC_FIRST): Fill in PC into - frame struct before extracting saved register offsets. - -Fri May 15 22:47:45 1998 Michael Snyder - - * tracepoint.c (encode_actions): fix typo in printf format string. - -1998-05-15 Jim Blandy - - Implement a few more tracing operators: ^ | & ~ ! - * ax-gdb.c (gen_integral_promotions, gen_logical_not, - gen_complement): New functions. - (gen_binop): New argument MAY_CARRY, indicating whether we need to - correct the upper bits of the value after performing the - operation. Callers changed. - (gen_expr): Handle BINOP_BITWISE_AND, BINOP_BITWISE_IOR, and - BINOP_BITWISE_XOR here as well, by calling gen_binop. Handle - UNOP_LOGICAL_NOT, UNOP_COMPLEMENT. - - * ax-gdb.c (gen_conversion): Reworked to avoid some unnecessary - sign extension. - - * ax-gdb.c (gen_usual_arithmetic): Renamed from gen_usual_binary, - to match the ANSI C standard better. Callers changed. - - * ax-gdb.c (gen_traced_pop): Add prototyped declaration. - -Fri May 15 18:18:38 1998 David Taylor - - * tracepoint.c (stringify_collections_list): return a collection - of strings rather than a single string. - (free_actions_list): new function. - (encode_actions): process collection of strings returned by - stringify_collections_list. - -1998-05-15 Jim Blandy - - * ax-gdb.c (gen_traced_pop): New function. - (gen_expr): Call it for comma operator. - (gen_trace_for_expr): Call it, instead of writing it out. - - Add facilities for sending arbitrary packets to the remote agent. - There are a bunch of improvements to make (make it generic; handle - 'O' replies properly), but I just want to get this onto the branch. - * remote.c (print_packet, remote_packet_command): New functions. - (_initialize_remote): Register the remote-packet command. - -Thu May 14 17:52:31 1998 Elena Zannoni - - * tracepoint.c: move actionline_type definition to tracepoint.h. - (validate_actionline): make non static. - - * tracepoint.h: move actioline_type definition from tracepoint.c. - (validate_actionline) moved prototype from tracepoint.c. - -Thu May 14 11:49:18 1998 David Taylor - - * tracepoint.c (validate_actionline): add additional error - checking, remove some dead code. - (encode_actions): additional cleanups. - (trace_find_command): remove some dead code. - (trace_find_pc_command): ditto. - (trace_find_tracepoint_command): ditto. - (trace_find_line_command): ditto. - (trace_find_range_command): ditto. - (trace_find_outside_command): ditto. - -Thu May 14 5:51:00 1998 Ron Unrau - - * symtab.c (decode_line_1): set section for "break *" - -Wed May 13 20:58:02 1998 Mark Alexander - - * corefile.c (reopen_exec_file): Reopen the exec file if - it has changed. - -Wed May 13 15:22:02 1998 Mark Alexander - - * sparc-tdep.c (fetch_instruction): New function. - (single_step, sparc_init_extra_frame_info, examine_prologue): - Use fetch_instruction instead of read_memory_integer - to ensure that instructions are always read as big-endian. - -Wed May 13 14:42:21 1998 Ian Lance Taylor - - * configure.in: Add AC_FUNC_ALLOCA. - * defs.h: Check HAVE_ALLOCA_H rather than sparc. Add _AIX pragma - alloca. - * configure: Rebuild. - * Makefile.in (jv-lang.o, jv-typeprint.o, jv-valprint.o): New - targets. - -Wed May 13 11:19:08 1998 Michael Snyder - - * tracepoint.c (trace_command): Remove old diagnostic code that was - preventing tracepoints from being defined with a full-path filename. - -Tue May 12 13:17:35 1998 Frank Ch. Eigler - - * stabsread.c (read_one_struct_field): Check for typedef in type - tree before clearing bitfield information. - -1998-05-11 Jim Blandy - - * ax-gdb.c (gen_binop): New function, based on gen_mul, to replace - gen_mul and gen_div, and handle `%' op as well. Correctly tests - type of arguments. - (gen_expr): Factor out common code in binary arithmetic operators. - Add support for `%'. - (gen_mul, gen_div): Removed. - -Thu May 7 14:49:38 1998 Bob Manson - - * config/sparc/tm-sp64.h (CALL_DUMMY): Store and retrieve - %o0-%o5 as 64-bit values; compensate for stack bias. - (USE_STRUCT_CONVENTION): We only pass pointers to structs - if they're larger than 32 bytes. - (REG_STRUCT_HAS_ADDR): Ditto. - - * sparc-tdep.c (sparc_init_extra_frame_info): Use read_sp() - instead of read_register. If the target is a sparc64 and the frame - pointer is odd, compensate for the stack bias. - (get_saved_register): Use read_sp(). - (DUMMY_STACK_REG_BUF_SIZE): Use FP_REGISTER_BYTES. - (sparc_push_dummy_frame): Use read_sp()/write_sp(). On sparc64, - save the PC, NPC, CCR, FSR, FPRS, Y and ASI registers. - (sparc_frame_find_saved_regs): Use read_sp(). Read the PC, NPC, - CCR, FSR, FPRS, Y and ASI registers from the frame, if it's a - dummy frame. - (sparc_pop_frame): Use write_sp(). If the target is a sparc64 and - the FP is odd, compensate for stack bias. - (sparc_store_return_value): Right-justify the return value before - writing it to %o0. - (sparc_fix_call_dummy): Don't NOP out part of the call dummy on - sparc64. - (sparc64_read_sp, sparc64_read_fp, sparc64_write_sp, - sparc64_write_fp, sp64_push_arguments, - sparc64_extract_return_value): New functions to support the - sparc64 ABI. - - * dwarfread.c (handle_producer): Set processing_gcc_compilation to - the right version number. - - * dwarf2read.c (read_file_scope): Assume we're processing - GCC2 output. - -Wed May 6 16:34:03 1998 Jeffrey A Law (law@cygnus.com) - - * somsolib.c: Include gdb_stat.h. - -Mon May 4 18:34:01 1998 David Taylor - - * ax-gdb.c (gen_mul): new function; (gen_div): new function; - (gen_expr): add support for * and / operators, call gen_mul and - gen_div as appropriate. - -Mon May 4 16:24:22 1998 Mark Alexander - - * defs.h (make_run_cleanup): Declare. - * solib.c (find_solib): Pass correct number of arguments to - make_run_cleanup. - -Mon May 4 07:08:25 1998 Michael Snyder - - * tracepoint.c (trace_actions_command): actions command must set - step_count to zero (in case previous actions have set it but the - new set does not). - -Sat May 2 09:35:07 1998 Stu Grossman - - * ocd.h: Add new flags, function codes, and processor types to - support new Wiggler capabilities. - * (ocd_write_bytes_size): New function to allow atomic writes of - memory in sizes larger than a byte. - - * ser-unix.c (baudtab): Add 57600, 115200, 230400, and 460800 baud. - -Fri May 1 19:51:32 1998 Frank Ch. Eigler - - * stabsread.c (read_one_struct_field): Do not override supplied - bitfield size for a range type value. - - * gdbtypes.c (create_range_type): For a range with positive - lower limit, declare range type as unsigned. - -Fri May 1 10:58:34 1998 John Metzler - - * monitor.c: Turn off debug - -Fri May 1 09:29:56 1998 Peter Schauer - - * breakpoint.c (delete_command): Skip internal breakpoints when - all breakpoints are requested. - - * stabsread.c (define_symbol): Record parameter types from Sunpro - function stabs in the TYPE_FIELDS of the function type. - -Thu Apr 30 15:59:54 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in (config-check-targets, config-check-hosts): Removed. - -1998-04-30 Paul Eggert - - * Makefile.in (maintainer-clean): - Don't get ahead of yourself and delete Makefile - before running `make'. - (local-maintainer-clean, do-maintainer-clean): New rules. - -Wed Apr 29 14:02:59 1998 David Taylor - - * ax-gdb.c (gen_add): when adding a pointer and an int, use - the size of the pointer, not the int (typo) to decide how - to extend the result. - -Wed Apr 29 10:20:40 1998 John Metzler - - * monitor.h: Defined additional hooks for dmpregs, configure_hooks - and wait_filter. These additions require that all ROM monitor - interfaces be recoded to initialize monitor ops using assignments - rather than static structure initialization. Added new bits to - flags MO_EXACT_DUMPADDR, MO_HAS_BLOCKWRITES. - - * monitor.c (RDEBUG): Conditional tracing throughout the file. - (fromhex): Now recognized upper cse hex digits - (monitor_printf_noecho): - (monitor_readchar): Tracing interferes with input timing. - (monitor_open): Register different memory write functions with - dcache_init if MO_HAS_BLOCKWRITES. - (flush_monior_dcache): Added as an additional utilty. - (monitor-resume): Call continue hook if one has been supplied. - (monitor_wait_filter): New function Factored out of monitor wait - and used if alternate wait-filter has not been provided. - (monitor_wait): call alternate wait filter if provided. Call - monitor_dump_regs, a new function factored out from inline code. - (monitor_dump_block): A new function used as a utility when - monitors must dump several blocks of registers using different - commands. - (monitor_dump_regs): Call alternate function if provided. Uses new - hook in monitor.h. - (monitor_write_memory): Engage previouly added hook - MO_FILL_USES_ADDR. - (monitor_write_even_block): new function supports writing long - blocks of 4byte words. - (longlongendswap): new internal function - (monitor_write_memory_longlongs): new function writes large blocks - using command to enter a long long. - (monitor_write-memory_block): new Function figures out which block - mod to use. - (monitor_read_memory): Can now handle dump formats in which the bytes - preceeding the requested data is not printed. - -Tue Apr 28 19:41:33 1998 Tom Tromey - - * tracepoint.c (memrange_cmp): Another typo fix; `memrbnge' -> - `memrange'. - - * tracepoint.c (memrange_cmp): Fixed typo in function intro. - -Tue Apr 28 17:41:20 1998 Philippe De Muyter - - * symfile.c (overlay_auto_command): Add forgotten parameter - definitions. - (overlay_manual_command, overlay_off_command): Likewise. - (overlay_load_command): Likewise. - * tracepoint.c (memrange_cmp): Parameters have type void *, not - struct memrange *. - -Tue Apr 28 11:08:25 1998 John Metzler - - * rom68k-rom.c (_initialize_rom68k): Fix unresolved init_rom_68kcmds. - -Mon Apr 27 14:32:21 1998 Mark Alexander - - * config/sparc/tm-sparc.h (CALL_DUMMY): Shorten it drastically, - make it work on the simulator. - (FIX_CALL_DUMMY): Convert to function call instead of inline code. - (sparc_fix_call_dummy): Declare. - * sparc-tdep.c (sparc_fix_call_dummy): New function, taken from - old FIX_CALL_DUMMY macro, with additional fixes for simulator. - (sparc_push_dummy_frame): Set registers differently on simulator - to prevent corrupted register window save areas. - -Mon Apr 27 13:46:40 1998 John Metzler - - * rom68k-rom.c (_initialize_rom68k, init_rom68k_cmds): - Convert all static initializations of monitor ops structures to - executable initializations in order that additions to the data - structure definition can me made without repeating this editing - exercise. - * abug-rom.c (_initialize_abug_rom, init_abug-cmds): Ditto. - * cpu32bug-rom.c (_initialize_cpu32bug_rom, init_cpu32bug_cmds): Ditto. - * mon960-rom.c (initialize_mon960, init_mon960_cmds): Ditto. - * op50-rom.c (initialize_op50n, init_op50n_cmds): Ditto. - * ppcbug-rom.c (_initialize_ppcbug_rom, init_ppc_cmds): Ditto. - * sh3-rom.c (_initialize_sh3_rom, init_sh3_cmds): Ditto. - * sparclet-rom.c (_initialize_sparclet, init_sparclet_cmds): Ditto. - * remote-est.c (_initialize_est, init_est_cmds): Ditto. - * remote-hms.c ( _initialize_remote_hms, init_hms_cmds): Ditto. - -Mon Apr 27 10:43:04 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * gdb_string.h (strdup): Don't specify arguments in prototype. - -Sun Apr 26 07:57:21 1998 Peter Schauer - - * rs6000-nat.c (vmap_ldinfo): Issue warning instead of error if - fstat on ldinfo_fd fails. Use objfile->obfd instead of vp->bfd - to check for reference to the same file. - - * target.c (target_read_string): Handle string transfers at the - end of a memory section gracefully. - -Fri Apr 24 17:18:56 1998 Geoffrey Noer - - * Makefile.in: enable EXEEXT setting - -Fri Apr 24 11:53:49 1998 David Taylor - - * tracepoint.c (add_local_symbols): change type of type from - char to int so that type shows up as 'A' or 'L' not 0. - -Thu Apr 23 16:37:20 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * README: Minor changes for 4.17 release. - -Thu Apr 23 15:44:39 1998 Per Bothner - - * symfile.c (deduce_language_from_filename): .class implies java. - -Thu Apr 23 12:52:21 1998 Philippe De Muyter - - * configure.in (strerror): Check if function must be declared. - * acconfig.h (NEED_DECLARATION_STRERROR): New define slot. - * gdb_string.h (strerror): Function declaration issued if - NEED_DECLARATION_STRERROR. - * configure, config.in: Files regenerated. - -Thu Apr 23 12:27:43 1998 Philippe De Muyter - - * symfile.c (simple_overlay_update_1): Do not prefix array address - by `&'. - * bcache.h (BCACHE_DATA_ALIGNMENT): Ditto. - * tracepoint.c (encode_actions): Ditto. - * language.c, complaints.c, utils.c (varargs.h): Do not include that - file here, it is already included indirectly by defs.h. - * dbxread.c (dbx_symfile_init, process_one_symbol): Cast xmalloc return - value to the appropriate pointer type. - * utils.c (floatformat_from_doublest): Ditto. - * tracepoint.c (read_actions, _initialize_tracepoint): Ditto. - (add_memrange): Likewise with xrealloc return value. - * stabsread.c (ref_add): Ditto. - * coffread.c (coff_symfile_init): Likewise for xmmalloc return value. - * elfread.c (elf_symfile_read): Ditto. - * os9kread.c (os9k_symfile_init): Ditto. - -Thu Apr 23 00:32:08 1998 Tom Tromey - - * config.in: Rebuilt. - * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_STPCPY, HAVE_GETTEXT, - HAVE_LC_MESSAGES): Define. - -Wed Apr 22 15:38:56 1998 Tom Tromey - - * configure: Rebuilt. - * configure.in: Call CY_GNU_GETTEXT. - * Makefile.in (top_builddir): New macro. - (INTL): Define to @INTLLIBS@. - (INTL_DEPS): New macro. - (CDEPS): Reference INTL_DEPS, not INTL. - -Wed Apr 22 12:58:23 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - Handle missing shared libraries during the examination of a core - dump gracefully. - * solib.c (find_solib): Use catch_errors around call to - solib_map_sections. Use warning instead of error if reading of - the shared library name fails. - (solib_map_sections): Change return and argument types to make - it callable from catch_errors. - (symbol_add_stub): Avoid GDB core dump if solib->abfd is NULL. - * irix5-nat.c, osfsolib.c (xfer_link_map_member, solib_map_sections, - symbol_add_stub): Ditto. - -Wed Apr 22 14:34:49 1998 Michael Meissner - - * Makefile.in (INTL*): Add support to link in the intl library, - and to add -I options to its source and object directories. - (INTERNAL_CFLAGS): Ditto. - (C{LIBS,DEPS}): Ditto. - -Tue Apr 21 11:20:54 1998 Frank Ch. Eigler - - * mips-tdep.c (gdb_print_insn_mips): Disassemble MIPS instructions - with subtarget-specific `mach', rather than fixed default. - * config/mips/tm-mips.h (TM_PRINT_INSN_MACH): New macro, default - disassembly `mach'. - -Mon Apr 20 15:35:03 1998 Philippe De Muyter - - * coffread.c (decode_base_type): Treat a long field with size greater - than TARGET_LONG_BIT as long long. - * values.c (value_from_longest): Print code value in error message. - -Mon Apr 20 15:32:21 1998 Mark Kettenis - - * gdb/gdb_string.h (strdup): Declare only if not defined as a - macro. - -Mon Apr 20 14:18:45 1998 J. Kean Johnston - - * procfs.c: Added replacement macros for LWP stuff. Fixed support - for UnixWare / SVR4.2MP targets and any targets which use - multi-file /proc entries. Fixed support for hardware watchpoints. - * solib.c: SCO needs some of the same code as SunOS. Change - preprocessor conditionals. - - * config/i386/i386sco5.mt: New file. - * config/i386/tm-i386sco5.h: New file. - * config/i386/i386sco5.mh (NATDEPFILES): add i386v-nat.o. - * config/i386/nm-i386v42mp.h - (TARGET_HAS_HARDWARE_WATCHPOINTS): define. - Add other macros for hardware assisted watchpoints. - * config/i386/nm-i386sco5.h: Correct attributions. - (TARGET_HAS_HARDWARE_WATCHPOINTS): define. - * config/i386/nm-linux.h (target_remote_watchpoint): Pass - 'type' through to i386_insert_watchpoint. - -Mon Apr 20 14:12:30 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * infrun.c (wait_for_inferior): Don't add signalled processes - as new threads. - * procfs.c (wait_fd): Note if LWP has exited. - (procfs_wait): use GETPID to get process ID. - -Sat Apr 18 15:21:04 1998 Stan Cox - - * configure.tgt: Added sparc86x support. - -Thu Apr 16 13:13:24 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * rdi-share/etherdrv.c (EthernetWrite): Use strerror to get - error string if in an ANSI C-ish environment. - -Wed Apr 15 18:59:48 1998 Mark Alexander - - * sparc-tdep.c (SPARC_HAS_FPU): Define. - (sparc_extract_return_value): New function, required to handle - machines without floating point. - (sparc_store_return_value): Ditto. - * config/sparc/tm-sparc.h (EXTRACT_RETURN_VALUE): Call - sparc_extract_return_value instead of using inline code. - (sparc_extract_return_value): Declare. - (STORE_RETURN_VALUE): Call sparc_store_return_value instead - of using inline code. - (sparc_store_return_value): Declare. - -Wed Apr 15 12:19:42 1998 Martin M. Hunt - - * solib.c (enable_break): Only call warning once - instead of three times. - -Tue Apr 14 16:52:59 1998 Mark Alexander - - * sparc-tdep.c (sparc_extract_struct_value_address): Make it - work correctly on little-endian hosts. - (sparc_push_arguments): New function. - (gdb_print_insn_sparc): New function. - (_initialize_sparc_tdep): Make gdb_print_insn_sparc the default - disassembler, so that SPARClite-specific instructions will - be recognized. - * sparcl-tdep.c (readchar): Print debugging information. - (debug_serial_write): New function, a replacement for SERIAL_WRITE - that prints debugging information. - * config/sparc/tm-sparc.h (PUSH_ARGUMENTS): Define. - (sparc_push_arguments): Declare. - -Tue Apr 14 15:43:49 1998 John Metzler - - * gdbcfgxref (xref_menu): Call new regex and wild card searches - Now you can type in a specific triple like mips64-vr4300-elf or - somthing like mips*.h - (triple_search, wildcardsearch): The new functions - -Mon Apr 13 16:28:07 1998 Elena Zannoni - - * utils.c (warning): added call to warning_hook - - * source.c (find_source_lines): modified to call warning in case - of source vs. executable time stamp mismatch. Simplified object - file check. Initialized mtime to 0. - - * defs.h: added warning_hook prototype - - * top.c: added warning_hook prototype. - -Mon Apr 13 09:54:08 1998 Keith Seitz - - * config/sparc/tm-sun4os4.h (IS_STATIC_TRANSFORM_NAME): Add missing - definition. - -Fri Apr 10 22:36:28 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - Update support for x86 Solaris 2. - * config/i386/tm-i386sol2.h, nm-i386sol2.h: New configuration - files for x86 Solaris 2. - * config/i386/i386sol2.mt, i386sol2.mh: Use them. - * config/sparc/tm-sun4sol2.h (PROCFS_GET_CARRY): New macro, extract - carry flag from a given regset. - (IS_STATIC_TRANSFORM_NAME): New macro, check if a symbol name - is a SunPro transformed name. - * i386-tdep.c (sunpro_static_transform_name): New function to - extract the source name from a SunPro transformed name. - * inferior.h (procfs_first_available, procfs_get_pid_fd): - Add prototypes. - * infrun.c (wait_for_inferior): Handle breakpoint hit in - signal handler without intervening stop in sigtramp. - * procfs.c (procfs_lwp_creation_handler): Use PROCFS_GET_CARRY - instead of direct access to the status register. - (procfs_get_pid_fd): New function, returns procfs fd for a given pid. - * sol-thread.c (ps_lgetLDT): New function, returns LDT for a given - lwpid. - (sol_find_new_threads): Handle failed libthread_db initialization - gracefully. - * stabsread.c (define_symbol): Use IS_STATIC_TRANSFORM_NAME - to check for a SunPro transformed symbol name. - -Fri Apr 10 10:35:35 1998 John Metzler - - * utils.c (fmthex): A formatting function for hexdumps - - * mips-tdep.c (unpack_mips16): Fixed instruction decoding, lots of - bit pattern interpretations. mips_fetch_instruction does not work - for 16 bit instructions. Some confusion remains about sign - extension in backward branches. - (mips32_relative_offset): Sign extension - (mips32_next_pc): Major debugging, bit pattern interpretation - (print_unpack): debugging printf - (fetch_mips_16): new funtion, key on PC low bit, not symbol table - (mips16_next_16): Initial major debugging of this function. Lots - of bit pattern mistakes. - (mips_next_pc): key on low bit of PC, not symbol table. - * symfile.c (generic_load): Added a download verification which - reads back the loaded code. Download chunk size is now a defined - macro. Fixed a bug in which downloading slips into loading one - byte at a time. Lower level functions in monitor.c can load long - sequences of bytes and make use of these fixups. Referencing - bfd-start_address directly was incorrectly getting zero for start. - -Thu Apr 9 19:20:32 1998 Ian Lance Taylor - - * mips-tdep.c (do_fp_register_row): Use alloca rather than arrays - with dynamic size. - -Wed Apr 8 19:21:42 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * top.c (print_gdb_version): Print 1998 now. - -Wed Apr 8 16:57:22 1998 Philippe De Muyter - - * source.c: Remove obsolete decl of strstr(). - -Wed Apr 8 16:47:33 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * solib.c (solib_create_inferior_hook): Remove Ulrich Drepper's - patch of March 23 1998. - * breakpoint.c (breakpoint_re_set_one): Remove Ulrich Drepper's - patch of March 23 1998. - -Sat Apr 4 10:05:00 1998 Dawn Perchik - - * mdebugread.c (parse_partial_symbols): If this is an .mdebug - section in an ELF file, override a symbol's ECOFF section with its - ELF section. Also, fix stabs continuation where a stabs string - continues for more than one continuation. - -Mon Apr 6 09:17:48 1998 Andrew Cagney - - * mips-tdep.c (mips_push_arguments): Specify dimention of valbuf - using MAX_REGISTER_RAW_SIZE. - -Sat Apr 4 10:05:00 1998 Dawn Perchik - - * infrun.c: Fix prototype of signals_info to match static funtion. - -Thu Apr 2 12:47:41 1998 Frank Ch. Eigler - - * sol-thread.c (sol_thread_store_registers): Save & restore new - value of single updated register to prevent accidental clobbering. - -Wed Apr 1 22:01:09 1998 Mark Alexander - - * config/sparc/tm-sparclite.h (TARGET_BYTE_ORDER_SELECTABLE): Define. - * config/sparc/sparclite.mt: Link in the erc32 simulator. - -Wed Apr 1 16:30:49 1998 Ian Dall - - * ns32k-tdep.c (flip_bytes, ns32k_localcount, - ns32k_get_enter_addr, sign_extend): Restore functions mysteriously - deleted. - - * ns32knbsd-nat.c: New (?) file to support fetching and storing - registers on NetBSD hosts. - - * nbsd.mh (NATDEPFILES): put ns32knbsd-nat.o instead of - ns32k-nat.o - - * ns32km3-nat.c (reg_offset): Get order of floating point - registers correct. Add extra 32382 register offsets. - (REG_ADDRESS): define to point at correct part of thread - state. Use calls to "warning" instead of "message". - - * tm-nbsd.h, tm-ns32km3.h (REGISTER_NAMES, NUM_REGS, - REGISTER_BYTES, REGISTER_BYTE): redefine allowing for 32382 - fpu registers. - -Wed Apr 1 13:43:07 1998 Philippe De Muyter - - * NEWS: m68k-motorola-sysv host support added. - * coffread.c (coff_start_symtab): Accept the filename as an argument, - set it here. Callers updated. - -Wed Apr 1 23:13:23 1998 Andrew Cagney - - * config/mips/tm-mips.h (REGISTER_VIRTUAL_TYPE): Handle 32 bit SR, - FSR and FIR registers. - (REGISTER_VIRTUAL_SIZE): Compute using REGISTER_VIRTUAL_TYPE. - (REGISTER_RAW_SIZE): Define using REGISTER_VIRTUAL_SIZE. - - * config/mips/tm-mips64.h: Ditto. - -Tue Mar 31 21:30:39 1998 Nick Clifton - - * arm-tdep.c (gdb_print_insn_arm): Attach a fake Thumb symbol - vector to the info structure when disassembling thumb - instructions. - - * coffread.c (coff_symtab_read, read_one_sym, - process_coff_symbol): Support Thumb symbol types. - - * dbxread.c (process_one_symbol): Call SMASH_TEXT_ADDRESS (if it - is defined) for function symbols. - -Tue Mar 31 16:39:28 1998 Michael Snyder - - * tracepoint.c (get_tracepoint_by_number): change warning to note. - (delete_trace_command): suppress y/n query if no tracepoints, or - if not from_tty. (trace_pass_command): reject junk at end of args. - (read_actions): an action list consisting only of "end" is discarded. - (validate_actionline (for collect command)): an argument beginning - with a dollar_sign but not recognized as a special argument is - parsed like any other expression -- if it isn't a register name, - it's rejected. Also reject an empty argument to while-stepping. - (trace_find_command): reject a negative frame number argument. - (_initialize_tracepoint): set $traceframe initially to -1. - -Mon Mar 30 16:42:12 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * rdi-share/Makefile.am, rdi-share/aclocal.m4, - rdi-share/configure: New files. - * rdi-share/configure.in: Rewritten to be an autoconf input file. - * rdi-share/Makefile.in, rdi-share/configure: Generated by - automake/autoconf. - * rdi-share/dbg_hif.h, etherdrv.c, hostchan.c: Use autoconf tests - to check environment. - -Sun Mar 29 15:17:16 1998 Keith Seitz - - * tracepoint.c (trace_start_command): Set trace_running_p. - (trace_stop_command): Clear trace_running_p. - -Sat Mar 28 15:19:48 1998 Stan Shebs - - * NEWS: Update for 4.17 release. - -Fri Mar 27 10:15:50 1998 David Taylor - - * tracepoint.c (parse_and_eval_memrange): Fix memory leaks. - (encode_actions): Use the new gen_trace_for_expr function - instead of expr_to_address_and_size; collect registers when - using expressions. (clear_collection_list): Fix memory leak. - -1998-03-26 Jim Blandy - - * ax-gdb.h (gen_trace_for_expr): Add prototype. - -Thu Mar 26 17:24:23 1998 David Taylor - - * tracepoint.c (validate_actionline): Fix memory leak. - (encode_actions): Fix memory leak. - -Thu Mar 26 16:16:55 1998 David Taylor - - * tracepoint.c (trace_mention): New function. - (trace_command): Call it. - -1998-03-26 Jim Blandy - - * ax-general.c (ax_reqs): New function. - * ax.h (enum agent_flaws, struct agent_reqs): New types. - (agent_reqs): New extern prototype. Well, actually, this was - there before, due to a premature checkin. - (struct aop_map): Add new `data_size' member. - * ax-general.c (aop_map): Supply its value. - * ax-gdb.c (agent_command): Call ax_reqs, for testing. - - * ax-general.c (ax_print): If we encounter an invalid or - incomplete opcode, don't abort; just print an error message. - - * ax-gdb.c: Generate trace bytecodes, as appropriate. - (trace_kludge): New variable. - (gen_fetch, gen_bitfield_ref): Emit trace bytecodes, if asked - nicely. - (expr_to_agent): Ask for no trace bytecodes. - (gen_trace_for_expr): New function. - (agent_command): Call it, and display the result appropriately --- - no struct axs_value, so no type or kind information. - - * ax-gdb.c: Use TARGET_CHAR_BIT throughout, not HOST_CHAR_BIT. - -Thu Mar 26 22:29:28 1998 Elena Zannoni - - * tracepoint.c (trace_status_command): Recognize a boolean return - value from the stub to indicate whether trace experiment is - running. Export this value as a global state variable. - (trace_running_p) for use by the GUI. (from Michael Snyder) - (trace_pass_command) added call to modify_tracepoint_hook. - - * tracepoint.h export trace_running_p. - -Thu Mar 26 13:08:01 1998 David Taylor - - * tracepoint.c (validate_actionline): do not error out if - exp->elts[0].opcode is not on short line -- let - expr_to_address_and_size handle it. - -1998-03-26 Jim Blandy - - * tracepoint.c: Include "ax.h", not "agentexpr.h". - - * tracepoint.c (encode_actions): Call expr_to_address_and_size, - not simply expr_to_agent. - - * ax-general.c: Comment out code in progress, so everyone else can - at least compile. - - * gdbtypes.c: Doc fix. - - * ax.h, ax-gdb.h, ax-general.c, ax-gdb.c: New files. - * Makefile.in (REMOTE_OBJS): Add ax-general.o and ax-gdb.o. - (SFILES): Add ax-general.c, ax-gdb.c. - (ax_h): New variable. - (ax-general.o, ax-gdb.o): New rules. - - -Tue Mar 24 16:22:40 1998 Stu Grossman - - * Makefile.in: Derive SHELL from configure. - * config/d10v/d10v.mt config/m32r/m32r.mt - config/mn10200/mn10200.mt config/mn10300/mn10300.mt - config/d30v/d30v.mt: Remove -lm from SIM. This prevents - dependency checking of -lm (under NT native builds). (It is - automatically added by configure if it exists.) - * doc/configure mswin/configure nlm/configure - testsuite/gdb.base/configure testsuite/gdb.c++/configure - testsuite/gdb.chill/configure testsuite/gdb.disasm/configure - testsuite/gdb.stabs/configure testsuite/gdb.threads/configure: - Regenerate with autoconf 2.12.1 to fix shell issues for NT native - builds. - -Mon Mar 23 18:10:57 1998 Ulrich Drepper (drepper@cygnus.com) - - * solib.c (solib_create_inferior_hook): Rewrite previous - change to check the type of file via BFD. - -Mon Mar 23 13:52:28 1998 Ulrich Drepper (drepper@cygnus.com) - - * breakpoint.c (breakpoint_re_set_one): Treat bp_shlib_events - like bp_breakpoints. - * solib.c (solib_create_inferior_hook): Relocate section addresses - if the alleged start address doesn't agree with the PC. - -Sat Mar 21 19:34:49 1998 Elena Zannoni - - merged changes from Foundry (list follows by file/author): - - - Tom Tromey - * Makefile.in (gdbres.o): New target. - (WINDRES): New define. - * configure: Rebuilt. - * configure.in (WINDRES): Define. - (CONFIG_OBS): Include gdbres.o on Windows. - * gdbtool.ico: New file. - * gdb.rc: New file. - - * ser-unix.c - - Keith Seitz - (wait_for): Don't reset the timeout_remaining for CYGWIN32, - since we now effectively poll the serial port. - Don't reset the current_timeout, either, since this member is used - by hardwire_readchar to track the timeout and call the ui_loop_hook. - (hardwire_readchar): Poll the serial port for Cygwin32. We timeout - every second, update the UI, and loop around doing this until we - have hit the real timeout or we get data or an error. This will - allow the UI to stay active while gdb is "blocked" talking to the - target. - - Martin M. Hunt - (wait_for): Do reset current_timeout because it is only used to - keep track of what the current timeout for the scb is. - - * top.c - - Martin M. Hunt - (quit_confirm): Change exit message again - for GUI. - (pc_changed_hook): Add prototype. - - Tom Tromey - (quit_confirm): Added missing `else'. - (quit_confirm): Special-case message if init_ui_hook is - set. - - * symtab.c - - Martin M. Hunt - (find_pc_sect_line): If no symbol information - is found, return correct pc anyway. - (find_methods): Comment out an apparently - bogus error message because it messes up Foundry. - - * serial.c - - Martin M. Hunt - (_initialize_serial): Add a description of - "set remotelogbase". - - * findvar.c - - Martin M. Hunt - (write_register_gen): Add call to - pc_changed_hook if the PC is being changed. - - * defs.h - - Martin M. Hunt - (pc_changed_hook): Define. - - * command.c - - Martin M. Hunt - (do_setshow_command): If no arguments are supplied, - don't dump core, instead print out an error message. - - * breakpoint.c - - Martin M. Hunt - Make set_raw_breakpoint, set_breakpoint_count, - and breakpoint_count non-static so they are accessible from - elsewhere. - (enable_breakpoint): Enable breakpoint - with same disposition instead of changing all breakpoints - to donttouch. - - * annotate.h - - Keith Seitz - Add declarations for annotation hooks. - - * annotate.c - - Keith Seitz - Add hooks: annotate_starting_hook, annotate_stopped_hook, - annotate_signalled_hook, annotate_exited_hook. - (annotate_starting): If hook exists, call it instead. - (annotate_stopped): If hook exists, call it instead. - (annotate_exited): If hook exists, call it instead. - (annotate_signalled): If hook exists, call it instead. - -Fri Mar 20 14:45:36 1998 Michael Snyder - - * gdbserver/Makefile.in: add dependency on XM_CLIBS. - * gdbserver/low-sim.c (registers) force into alignment. - (create_inferior): Fix typo on new_argv; add abfd arg to - sim_open, sim_create_inferior. Add reg_size arg to - sim_fetch_register, sim_store_register. Make simulator - take a single-step to get into a known running state. - * gdbserver/gdbreplay.c: include fcntl.h for def'n of F_SETFL. - * gdbserver/server.c: Add remote_debug variable to control - debug output. - * gdbserver/server.h: Add prototypes for enable/disable_async_io. - * gdbserver/remote-utils.c: add verbose debugging output controlled - by "remote_debug" variable. Add call to "disable_async_io()" - to avoid being killed by async SIGIO signals. - * config/m32r/m32r.mt: define GDBSERVER_(LIBS and DEPFILES), - so that gdbserver can be built with the m32r simulator. - -Fri Mar 20 09:04:06 1998 Andrew Cagney - - * gdbtypes.h (builtin_type_{,u}int{8,16,32,64}): New gdb builtin - types. - - * gdbtypes.c (_initialize_gdbtypes): Initialize new types. - - * mips-tdep.c (do_gp_register_row): Pad register value when GP - register is smaller than MIPS_REGSIZE. - - * findvar.c (value_of_register): When raw and virtual register - values identical, check that sizes are consistent. - -Thu Mar 19 11:32:15 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * minsyms.c (compare_minimal_symbols): If addresses are identical, - then compare on names. Sorted list should have symbols with - identical addresses AND names adjacent, so dups can be discarded. - -Wed Mar 18 12:50:17 1998 Jeff Law (law@cygnus.com) - - * stabsread.c (define_symbol): Don't look for ',' as a LRS - indicator. - -Wed Mar 18 10:34:51 1998 Nick Clifton - - * rdi-share/etherdrv.c: Set sys_errlist[] as char * not const char *. - -Fri Mar 13 15:43:53 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/mips/xm-mips.h (CC_HAS_LONG_LONG): Undefine for Ultrix - when compiling with native cc, the compiler has broken long long - support. - -Fri Mar 13 15:37:02 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * config/m68k/xm-sun3os4.h: Remove malloc declarations, they - are handled via autoconf now. - * remote.c (remote_ops, extended_remote_ops): Replace static - forward declaration by moving the static definition to the top of - the file, for old K&R compilers. - * tracepoint.c (collect_symbol, trace_start_command): - Replace ANSI string concatenation with K&R compatible simple string. - -1998-03-11 Fred Fish - - * source.c (select_source_symtab): Don't reach error if we have - a current_source_symtab from reading in partial symbol table. - -Fri Mar 6 13:10:27 1998 Fred Fish - - * utils.c (quit): Call SERIAL_DRAIN_OUTPUT rather than - SERIAL_FLUSH_OUTPUT. - * serial.h (struct serial_ops): Add drain_output, pointer to - function that waits for output to drain. - (SERIAL_DRAIN_OUTPUT): Macro to wait for output to drain. - * ser-unix.c (hardwire_drain_output): New function and prototype. - - * ser-unix.c (hardwire_ops): Add entry for drain_output function. - * ser-tcp.c (tcp_ops): Ditto. - * ser-ocd.c (ocd_ops): Ditto. - * ser-mac.c (mac_ops): Ditto. - * ser-go32.c (dos_ops): Ditto. - * ser-e7kpc.c (e7000pc_ops): Ditto. - -Thu Mar 5 16:07:41 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * sparcl-tdep.c: fix #endif comments - -Thu Mar 5 15:10:35 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in (BISON): Configure substitutes in @YACC@, not @BISON@. - -Thu Mar 5 14:42:41 1998 Keith Seitz - - * ocd.c (ocd_open): If we fail ocd_start_remote, make sure we - error () so that we abort out of bdm_ppc_open. - -Wed Mar 4 16:53:52 1998 Martin M. Hunt - - * serial.c (_initialize_serial): Add a description of - "set remotelogbase". - - * command.c (do_setshow_command): If no arguments are supplied, - don't dump core, instead print out an error message. - -Wed Mar 4 01:39:08 1998 Ron Unrau - - * elfread.c (elf_symtab_read): merge SYMBOL_IS_SPECIAL into - MAKE_MSYMBOL_SPECIAL - * config/mips/tm-mips.h: ditto - -Tue Mar 3 17:19:08 1998 John Metzler - - * dwarfread.c (read_tag_pointer_type): Pointer sizes now come from - TARGET_PTR_BIT rather from sizeof(char *) on host. - -Tue Mar 3 14:37:02 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-nat.c (fetch_osf_core_registers): Renamed from - fetch_aout_core_registers. - (alpha_osf_core_fns): Renamed from alpha_aout_core_fns, change - flavour to bfd_target_unknown_flavour for OSF core files. - -Mon Mar 2 17:44:13 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * breakpoint.c (_initialize_breakpoint): Make "en" an alias - for "enable" (so that it doesn't conflict with "end"). - -Mon Mar 2 17:04:25 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile (VERSION): Bump to 4.17.1. - -Mon Mar 2 16:59:15 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * rdi-share/etherdrv.c (sys_errlist): Add correct decl for Linux. - -Mon Mar 2 16:51:44 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in (YYFILES): Remove in maintainer-clean, not distclean. - -Mon Mar 2 16:47:11 1998 Philippe De Muyter - - * Makefile.in (distclean): Add `rm $(YYFILES)'. - -Mon Mar 2 16:45:48 1998 Philippe De Muyter - - * coffread.c (coff_read_enum_type): Set TYPE_FLAG_UNSIGNED if enum - is unsigned. - -Sun Mar 2 15:16:13 1998 Richard Henderson - - * configure.host, configure.tgt: Add sparc-linux. - * sparc-nat.c: Include not for Linux. - * config/sparc/*linux*: New files. - -Mon Mar 2 12:12:41 1998 Anthony Thompson (athompso@cambridge.arm.com) - - * arm-tdep.c (gdb_print_insn_arm): Call print_insn_big_arm - if we're big endian; else call print_insn_little_arm. - -Mon Feb 24 11:24:57 1998 Richard Henderson - - * Makefile.in (BISON): Don't even pretend to use yacc. - (c-exp.tab.o): Use bison -o to use a unique intermediate file. - (f-exp.tab.o, m2-exp.tab.o): Likewise. - (jv-exp.tab.o): Likewise. - -Tue Feb 24 03:32:59 1998 Andrew Cagney - - * remote-sim.c (gdbsim_fetch_register): Don't abort when the - register size is wrong. - -Thu Feb 19 16:49:48 1998 John Metzler - - * target.c (debug_to_fetch_registers,debug_to_store_registers, - debug-to_insert_breakpoint,debug_to_remove_breakpoint): tracing - 64 bit targets crashed long long printfs. - -Tue Feb 17 16:36:22 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * symfile.c (read_target_int_array): rename read_target_long_array - and force the sizeof an ovly_table element to sizeof(long), - instead of sizeof(int). - -Tue Feb 17 18:05:05 1998 Frank Ch. Eigler - - * remote-mips.c (mips_request): Use unsigned long during parsing - returned value from monitor, to prevent accidental sign extension. - -Tue Feb 17 14:28:33 1998 Peter Schauer - - * acconfig.h: FORCE_MMCHECK changed to MMCHECK_FORCE. - * configure.in: Ditto. - * configure: Regenerated. - -Tue Feb 17 14:07:34 1998 Peter Schauer - - * gdbtypes.c (check_typedef): Do not try to resolve the length of - a type which has TYPE_FLAG_TARGET_STUB set, if the target type has - set TYPE_FLAG_TARGET_STUB as well. - -Tue Feb 17 14:32:18 1998 Andrew Cagney - - * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): - Pass register size to sim_{fetch,store}_register. Check nr of - register bytes transfered is correct. - -Mon Feb 16 14:05:54 1998 Andrew Cagney - - * remote-d10v.c (remote_d10v_open): Call push_remote_target - instead of open_remote_target. - - * remote.c (remote_xfer_memory): Use REMOTE_TRANSLATE_XFER_ADDRESS - to translate addr/size when defined. - (open_remote_target): Delete. - - * target.h (open_remote_target): Delete. - - * config/d10v/tm-d10v.h (REMOTE_TRANSLATE_XFER_ADDRESS): Define. - -Mon Feb 16 14:05:54 1998 Andrew Cagney - - * d10v-tdep.c (d10v_extract_return_value): Wierd. GCC wants to - return odd sized register quantities with only half of the first - register used! - - * config/d10v/tm-d10v.h (USE_STRUCT_CONVENTION): Use stack when - size > 8. - -Mon Feb 16 14:05:54 1998 Andrew Cagney - - * config/d10v/tm-d10v.h (USE_STRUCT_CONVENTION): Define. True when - sizeof type > 1. - -Sun Feb 15 16:10:50 1998 Ron Unrau - - * parse.c (write_dollar_variable): call new function - target_map_name_to_register to allow targets to define their own - register name aliases. - * infcmd.c (registers_info): use target_map_name_to_register so that - "print $reg" and "info reg $reg" use the same register name aliases. - -Fri Feb 13 16:40:30 1998 Stan Shebs - - * config/i386/i386mk.mt (OBJFORMATS): Delete, no longer used. - * config/i386/xm-i386mk.h: Fix an include. - * config/pyr/tm-pyr.h (PC_INNER_THAN): Remove, never used. - -Thu Feb 12 16:12:07 1998 Frank Ch. Eigler - - * remote-mips.c (mips_enter_debug): Sleep before sending CR to - monitor. - (mips_exit_debug): Accept any whitespace / verbiage before monitor - prompt reappears. - -Thu Feb 12 18:25:42 1998 Andrew Cagney - - * d10v-tdep.c (show_regs): Avoid use of %llx when printing 8 byte - accumulators. - -Thu Feb 12 17:10:22 1998 Andrew Cagney - - * valops.c (value_at): For d10v, make read pointers with - read_target_unsigned_integer, keep addresses unsigned. - (value_fetch_lazy): Ditto. - -Thu Feb 12 12:14:02 1998 Andrew Cagney - - * remote-d10v.c: New file. Layer the d10v GDB->remote memory map - on top of the remote serial memory transfer functions. - - * config/d10v/d10v.mt (TDEPFILES): Add remote-d10v.o - - * Makefile.in (remote-d10v.o): Add dependencies. - - * remote.c (remote_open_1): Add arg extended_p, engage extended - protocol when extended_p. - (remote_open, extended_remote_open): Pass !extended_p / - extended_p to remote_open_1. - - * remote.c (open_remote_target), target.h: New function. - -Wed Feb 11 08:41:15 1998 Andrew Cagney - - * config/i386/fbsd.mh (XDEPFILES): Add ser-tcp.o. - -Tue Feb 10 17:50:37 1998 Keith Seitz - - * tracepoint.c (tracepoint_operation): Call the modify_tracepoint_hook - if it exists. - Remove static declaration of free_actions. - - * tracepoint.h: Add declaration of free_actions. - -Tue Feb 10 12:17:13 1998 Fred Fish - - * symtab.c (decode_line_1): Revert change that mistakenly - removed assignment of sals[0].pc field. - -Mon Feb 10 12:37:47 1998 Philippe De Muyter - - * m68k/tm-delta68.h (EXTRACT_RETURN_VALUE): Type argument for - `REGISTER_CONVERT_TO_VIRTUAL is `TYPE', not - `REGISTER_VIRTUAL_TYPE (FP0_REGNUM)'; - (STORE_RETURN_VALUE): Ditto, and offset for `write_register_bytes' - is `REGISTER_BYTE (FP0_REGNUM)', not `FP0_REGNUM'. - (FRAME_NUM_ARGS): New macro. - * m68k/tm-news.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): Ditto. - * delta68-nat.c (clear_insn_cache): New function, forgotten in previous - patch. - -Mon Feb 9 11:10:06 1998 Andrew Cagney - - * d10v-tdep.c: Replace references to IMEM_ADDR and DMEM_ADDR with - D10V_MAKE_[DI]ADDR and D10V_CONVERT_[ID]ADDR_TO_RAW macros. - - * config/d10v/tm-d10v.h (IMEM_START): Move to 0x01...... - (DMEM_START): Move to 0x00...... - (STACK_START): Move to 0x00..7ffe. - (D10V_MAKE_IADDR, D10V_MAKE_DADDR): Translate unconditionally. - - * d10v-tdep.c (d10v_xlate_addr): Delete function. - -Mon Feb 9 15:10:21 1998 Fred Fish - - * symtab.c (fixup_psymbol_section): Move forward declaration to - top of file with other such decls. Make it a static function. - * symtab.h: Minor formatting tweaks. - -Mon Feb 9 13:14:12 1998 Stan Shebs - - * config/a29k-udi.mt, config/i960/vxworks960.mt (REMOTE_OBS): - Remove redefinition. - * config/i960/tm-i960.h (BREAKPOINT): Define. - -Mon Feb 9 15:35:38 1998 Ian Lance Taylor - - * Makefile.in (init.c): Ignore errors when making init.c. Seems - necessary to work around bug in Solaris make. - -Sun Feb 6 02:44:28 1998 Philippe De Muyter - - * m68k/tm-delta68.h (CPLUS_MARKER): Macro deleted. - (EXTRACT_STRUCT_VALUE_ADDRESS): Macro defined. - (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): Macros modified - because floating-point values return via %fp0. - (CLEAR_INSN_CACHE): New macro. - * m68k/tm-m68k.h (REGISTER_CONVERT_TO_VIRTUAL): Macro fixed - to use DOUBLEST. - (REGISTER_CONVERT_TO_RAW): Ditto. - * infptrace.c (child_xfer_memory): If CLEAR_INSN_CACHE is defined, - call it after having written in child process's memory. - * inflow.c (PROCESS_GROUP_TYPE): Macro defined if HAVE_TERMIO. - (gdb_has_a_terminal, terminal_ours_1): Functions fixed for HAVE_TERMIO. - -Fri Feb 6 16:17:30 1998 Jeffrey A Law (law@cygnus.com) - - * config/mips/tm-mips64.h (TARGET_LONG_BIT): Allow final target to - override. - (TARGET_LONG_LONG_BIT): Likewise. - (TARGET_PTR_BIT): Likewise. - -Fri Feb 6 17:42:22 1998 Andrew Cagney - - * config/d10v/tm-d10v.h (D10V_CONVERT_IADDR_TO_RAW, - D10V_CONVERT_DADDR_TO_RAW): Define. - - * d10v-tdep.c (d10v_push_arguments): Re-write. Pass arguments in - registers, regardless of their size, when they fit. - -Thu Feb 5 13:16:36 1998 Andrew Cagney - - * d10v-tdep.c (d10v_extract_return_value): For function pointers - translate address to IMAP area. - - * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Delete dummy from - struct. - (POP_FRAME): Point at generic_pop_current_frame. - - * d10v-tdep.c (d10v_pop_frame): Delete code handling dummy frames, - handled earlier. - (d10v_push_return_address): New function. - (d10v_pop_dummy_frame): Delete. - (d10v_fix_call_dummy): Delete. - (d10v_call_dummy_address): Delete. - - * d10v-tdep.c (d10v_init_extra_frame_info): Clear dummy and - frameless. - - * d10v-tdep.c (d10v_push_arguments): Keep stack word aligned. - - * config/d10v/tm-d10v.h (EXTRACT_STRUCT_VALUE_ADDRESS): Extract - address of structure from first ARG1_REGNUM. - - * d10v-tdep.c (d10v_push_arguments): Force 4 byte args into - even-odd register pair. Store 1 and 2 byte args in registers. - - * valops.c (value_fetch_lazy): Ensure that a D10V function pointer - is fetched in the correct byte order. - (value_at): Ditto. Also ensure data pointers are mapped to data - segment. - - * config/d10v/tm-d10v.h (D10V_DADDR_P, D10V_IADDR_P): - - * d10v-tdep.c: Replace 2 with REGISTER_RAW_SIZE. - (d10v_pop_frame): Replace R13 with LR_REGNUM. - (d10v_push_arguments): Replace R2 with ARG1_REGNUM. - (d10v_push_arguments): Replace 6 with ARGN_REGNUM. - (d10v_extract_return_value): Access return value with RET1_REGNUM. - - * config/d10v/tm-d10v.h (ARG1_REGNUM, ARGN_REGNUM, RET1_REGNUM): - Define. - (STORE_RETURN_VALUE): Specify return register using RET1_REGNUM. - (STORE_STRUCT_RETURN): Specify ARG1_REGNUM as the struct ptr - location. - -Thu Feb 5 13:16:36 1998 Andrew Cagney - - * blockframe.c (generic_pop_dummy_frame): Flush the frame, no - longer valid. - - * blockframe.c (generic_pop_current_frame), frames.h: New - function. - -Thu Feb 5 17:18:16 1998 Andrew Cagney - - * remote-sim.c (gdbsim_create_inferior): clear_proceed_status - before /re/starting the simulator. - -Thu Feb 5 15:55:31 1998 C. M. Heard (heard@vvnet.com) - - * top.c (do_nothing): Remove signal handler after signal is caught. - -Thu Feb 5 11:57:06 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c (tracepoint_operation): call free_actions instead - of free. (free_actions): eliminate some memory leaks for actions. - (validate_actionline): pass string arg by reference, so we can - change the pointer. Change all memrange collection arguments to - canonical form (literal address and size), to enforce early - evaluation. Accept UNOP_MEMVAL (assembly variables) for - trace collection. (parse_and_eval_memrange): accept expressions - for the address and size fields of a memrange (and evaluate - them immediately). (several places): use -1 instead of zero - to distinguish an absolute memrange from a register-relative one. - (encode_actions): add handling for UNOP_MEMVAL (assembly variable). - -Wed Feb 4 17:40:21 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in (SFILES): add tracepoint.c. - (LINTFILES): add @CONFIG_SRCS@. - (SOURCES): Ditto. - * configure.in (CONFIG_SRCS): Mirror use of CONFIG_OBS. - * configure: Regenerated. - -Tue Feb 3 16:12:32 1998 Gordon W. Ross (gwr@mc.com) - - * infptrace.c (child_resume): Don't try to step if - NO_SINGLE_STEP is defined. - -Mon Feb 2 19:06:13 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * Makefile.in (VERSION): Bump to 4.16.2. - -Mon Feb 2 17:18:25 1998 Richard Henderson - - * alpha-nat.c (fetch_aout_core_registers): Rename from - fetch_core_registers. - (fetch_elf_core_registers): New function. - (supply_gregset): Use ALPHA_REGSET_BASE. - (supply_fpregset): Likewise. - (fill_fpregset): Likewise. - (alpha_aout_core_fns): Rename from alpha_core_fns. - (alpha_elf_core_fns): New. - * config/alpha/alpha-linux.mh (NATDEPFILES): solib.o not osfsolib.o. - Disable MMALLOC. - * config/alpha/nm-linux.h (SVR4_SHARED_LIBS): Define if ELF. - (TARGET_ELF64): Likewise. - (ALPHA_REGSET_BASE): New. - * config/alpha/nm-osf.h (ALPHA_REGSET_BASE): New. - * config/alpha/tm-alphalinux.h: Include tm-sysv4.h. - - * solib.c (elf_locate_base): Add TARGET_ELF64 support. - (info_sharedlibary_command): Likewise. - - * configure.host: Match alpha*. - * configure.tgt: Likewise. - -Fri Jan 30 15:11:38 1998 David Taylor - - Changes by - * infrun.c (IN_SOLIB_DYNSYM_RESOLVE_CODE): new macro for detecting - whether we are in the dynamic symbol resolution code - (wait_for_inferior): invoke it. - * solib.c (in_svr4_dynsym_resolve_code): new function - (enable_break): record start and end of the dynamic linker - text and plt sections for use in in_svr4_dynsym_resolve_code. - * solib.h (IN_SOLIB_DYNSYM_RESOLVE_CODE): add svr4 definition; - (in_svr4_dynsym_resolve_code): declare it. - * config/nm-gnu.h (solib.h): move inclusion to after definition - of SVR4_SHARED_LIBS. - * config/nm-sysv4.h (solib.h): ditto. - * config/i386/nm-i386sco5.h (solib.h): ditto. - * config/i386/nm-linux.h (solib.h): ditto. - * config/mips/nm-irix5.h (IN_SOLIB_DYNSYM_RESOLVE_CODE): undefine. - -Thu Jan 29 19:39:31 1998 Stan Shebs - - * coffread.c (coff_symtab_read) [SEM]: Remove code, macro can - never be defined. - * dbxread.c (process_one_symbol) [BLOCK_ADDRESS_ABSOLUTE]: - Remove, no longer needed. - * hppa-tdep.c (N_SET_MAGIC): Remove, no longer used. - * config/pa/xm-hppab.h (SEEK_SET, SEEK_CUR, SEEK_END): Ditto. - * config/mips/tm-mipsm3.h (NUMERIC_REG_NAMES): Ditto. - * config/mips/mipsm3.mt (TDEPFILES): Remove mipsread.o. - -Wed Jan 28 14:46:52 1998 Stan Shebs - - Suggested by Chris Walter : - * dwarfread.c (set_cu_language): Recognize Fortran. - * dwarf2read.c (set_cu_language): Ditto. - (read_array_type): Fix language test. - -Wed Jan 28 12:51:08 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * blockframe.c (generic_frame_chain_valid): A frame pointer may - be valid if it is equal to the frame pointer of its caller (ie. - not necessarily strictly INNER_THAN). Allows frameless functions. - -Wed Jan 28 11:23:25 1998 Mark Alexander - - * monitor.c (monitor_vsprintf): New function to handle - printing of large addresses using %A format specifier. - (monitor_printf_noecho, monitor_printf): Use monitor_vsprintf - instead of vsprintf. - * dve3900-rom.c (_initialize_r3900_rom): Use %A instead of %Lx - to print addresses. - -Tue Jan 27 16:14:23 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * configure.in (CONFIG_LDFLAGS): Only add -export-dynamic - when using GNU ld. - -Mon Jan 26 19:07:46 1998 Jason Molenda (crash@bugshack.cygnus.com) - - * config/alpha/tm-alphalinux.h (alpha_linux_sigtramp_offset): - Add closing parenthesis. From HJ Lu. - -Mon Jan 26 17:54:45 1998 Mark Alexander - - * dve3900-rom.c: Improve performance by using memory commands - that print less fluff. Minor cosmetic changes. - Eliminate compiler warnings. - -Sat Jan 24 23:44:43 1998 Martin M. Hunt - - * breakpoint.c (enable_breakpoint): Preserve breakpoint - disposition when enabling a breakpoint. - - * symtab.c (find_pc_sect_line): If no symbol information - is found, return correct pc anyway. - -Fri Jan 23 17:26:22 1998 Stan Shebs - - * configure.host (i[3456]86-*-osf1mk*, mips-*-mach3*, - ns32k-*-mach3*): Fix file names. - (i[3456]86-*-os9k, m88*-*-mach3*, w65-*-*): Remove config - recognition, no source files for these. - * configure.tgt (powerpc-*-aix4*): Remove config, now identical - to powerpc-*-aix*. - * config/powerpc/{aix4.mh,aix4.mt,tm-ppc-aix4.h}: Remove files, - no longer needed. - -Fri Jan 23 16:49:41 1998 Mark Alexander - - * monitor.c (monitor_write, monitor_readchar): New functions. - * monitor.h (monitor_write, monitor_readchar): Declare. - * dve3900-rom.c: Add support for fast loading on ethernet connections. - -Fri Jan 23 07:47:06 1998 Fred Fish - - * config/d10v/tm-d10v.h (CALL_DUMMY): Define as "{ 0 }". - (TARGET_READ_FP): Define to d10v_read_fp rather than d10v_read_sp. - (TARGET_WRITE_FP): Define to d10v_write_fp rather than d10v_write_sp. - (d10v_write_fp, d10v_read_fp): Add prototypes. - * symtab.c (decode_line_1): Remove assignment of sals[0].pc field. - * symfile.c (simple_overlay_update, simple_overlay_update_1): - Ignore the size of overlay sections. This check is redundant anyway. - * printcmd.c (print_frame_args): Ditto. - * valops.c (value_fetch_lazy): Ditto. - * values.c (unpack_long): Ditto. - * d10v-tdep.c (d10v_frame_chain, d10v_frame_find_saved_regs, - d10v_init_extra_frame_info): Fix some minor bugs so the finish command - works properly. - (show_regs): Change num1 and num2 types from "long long" to "LONGEST". - (d10v_read_fp, d10v_write_fp): New functions. - (d10v_push_arguments): Remove unneeded assigns to "val" and "contents". - (d10v_push_arguments): Fix for pointers and structs. - (d10v_extract_return_value): Fix for pointers and chars. - -Tue Jan 20 18:53:18 1998 Stan Shebs - - * configure.tgt (i386-*-mach*, m88*-*-mach3*): Remove config - recognition, no source files for these (note that the i386 Mach - config is for pre-Mach 3). - (mips*-*-mach3*, ns32k-*-mach3*): Fix file names. - * config/mips/mipsel64.mt: Remove, never referenced. - -Mon Jan 19 14:01:28 1998 Stan Shebs - - * top.c (print_gdb_version): Restore to original message. - -Mon Jan 19 13:34:40 1998 Ian Lance Taylor - - From cgf@bbc.com (Chris Faylor): - * win32-nat.c (child_mourn_inferior): Call ContinueDebugEvent to - let the child exit. - (child_kill_inferior): Respond to all debug events as the child is - terminating. - - * Makefile.in (all): Change gdb dependency to gdb$(EXEEXT). - (uninstall): Add $(EXEEXT) to file name to remove. - (gdb$(EXEEXT)): Rename target from plain gdb. - (gdb1$(EXEEXT)): Rename target from plain gdb1. - (clean, mostlyclean): Add $(EXEEXT) to binary names to remove. - -1998-01-16 Felix Lee - - * top.c (print_gdb_version): delete stutter. - -Thu Jan 15 12:29:13 1998 Nick Clifton - - * remote-rdi.c (arm_rdi_open): Patch from Tony.Thompson@arm.com - to prevent spurous error messages on non-ICE targets. - -Wed Jan 14 19:27:02 1998 Stan Shebs - - * config/mips/{r3900.mt,r3900l.mt,tm-r3900.h,tm-r3900l.h}: - Remove, no longer used. - -Wed Jan 14 18:11:26 1998 Michael Meissner - - Patch from Jim Wilson. - * d30v-tdep.c (d30v_frame_find_saved_regs_offsets): Properly - declare void function before use. - - * config/d30v/tm-d30v.h (CALL_DUMMY): Initialize as { 0 }, not {}. - -Tue Jan 13 16:38:48 1998 Fred Fish - - * configure.in (--with-mmalloc): Add new configure arg to use the - mmalloc package. Default is to not use it. - (START_INFERIOR_TRAPS_EXPECTED): Define to the integer 2, not - the string "2". - * acconfig.h (USE_MMALLOC, FORCE_MMCHECK): Add #undef. - * configure: Regenerated. - * config.in: Regenerated. - * Makefile.in (MMALLOC_DIR, MMALLOC_SRC): Remove. - (MMALLOC): Set using configure. - (MMALLOC_CFLAGS): Set using configure. - - * config/i386/tm-linux.h (sys_quotactl): Define to 1 rather - than just defining it. - * mpw-make.sed: Undefine USE_MMALLOC rather than defining NO_MMALLOC. - * utils.c (NO_MMALLOC): Use USE_MMALLOC instead. - * objfiles.c: ditto. - * defs.h: ditto. - - * config/sparc/sun4os4.mh (MMALLOC_CFLAGS): Remove. - * config/m68k/sun3os4.mh (MMALLOC_CFLAGS): Remove. - * config/i386/cygwin32.mh (MMALLOC_CFLAGS): Remove. - * config/alpha/alpha-osf3.mh (MMALLOC_CFLAGS): Remove. - * config/alpha/alpha-osf2.mh (MMALLOC_CFLAGS): Remove. - * gdbserver/Makefile.in (MMALLOC_*): Remove. - * config/rs6000/rs6000.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/rs6000/aix4.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/powerpc/aix4.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/powerpc/aix.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/ns32k/ns32km3.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/mips/mipsm3.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/mips/decstation.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/m88k/cxux.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/i386/xm-windows.h (NO_MMALLOC, NO_MMCHECK): Remove. - * config/i386/i386mk.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/i386/i386m3.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/i386/i386gnu.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/alpha/alpha-osf1.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - * config/alpha/alpha-linux.mh (MMALLOC, MMALLOC_CFLAGS): Remove. - -Mon Jan 12 11:46:51 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * config/m68k/tm-m68k.h (REGISTER_VIRTUAL_TYPE): make A0 thru A7 - default to void pointer type (so that their default radix is hex). - - * symtab.c: move rbreak_command from no_class to class_breakpoint - so it will be listed under "help breakpoints". - -Sat Jan 10 14:58:04 1998 Stan Shebs - - * rdi-share/hostchan.c: Remove gettimeofday declaration. - -Thu Jan 8 11:03:59 1998 Nick Clifton - - * remote-rdp.c: Applied patches submitted by Tony.Thompson@arm.com - to implement the Angel remote debugging interface. - - * Makefile.in: Add build rules for remote-rdi.c and - rdi-share/libangsd.a. - - * configure.tgt: Updated from source on branch. - * config/arm/tm-arm.h: Updated from source on branch. - * arm-tdep.c: Updated from source on branch. - - * rdi-share: New directory, RDI library contributed by ARM. - -Mon Jan 5 20:21:59 1998 Mark Alexander - - * monitor.h (MO_PRINT_PROGRAM_OUTPUT): Define. - * monitor.c (monitor_wait): Echo program output. - * dve3900-rom.c (_initialize_r3900_rom): Remove MO_HANDLE_NL flag, - add MO_PRINT_PROGRAM_OUTPUT flag. - -Mon Jan 5 18:21:11 1998 David Taylor - - * top.h (HAVE_SIGSETJMP): define SIGJMP_BUF, SIGSETJMP, and - SIGLONGJMP appropriately based on whether HAVE_SIGSETJMP is - defined. - * top.c (return_to_top_level, catch_errors): use the new macros - * main.c (SET_TOP_LEVEL): ditto. - * config/xm-sysv4.h (HAVE_SIGSETJMP): Define. - -Fri Jan 2 18:48:58 1998 Mark Alexander - - * configure.in: Double up brackets in shell case pattern. - -Fri Jan 2 17:06:05 1998 Michael Snyder (msnyder@cleaver.cygnus.com) - - * tracepoint.c (finish_tfind_command): improved algorithm for - deciding when we've "stepped" into a new stack frame. - (map_args_over_tracepoints): loop over tracepoint list "safely", - since list elements may be deleted during loop. - (read_actions): add actions to history list. - -For older changes see ChangeLog-97 - -Local Variables: -mode: change-log -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/contrib/gdb/gdb/arm-convert.s b/contrib/gdb/gdb/arm-convert.s deleted file mode 100644 index 8124052bb10..00000000000 --- a/contrib/gdb/gdb/arm-convert.s +++ /dev/null @@ -1,16 +0,0 @@ -/* OBSOLETE .text */ -/* OBSOLETE .global _convert_from_extended */ -/* OBSOLETE */ -/* OBSOLETE _convert_from_extended: */ -/* OBSOLETE */ -/* OBSOLETE ldfe f0,[a1] */ -/* OBSOLETE stfd f0,[a2] */ -/* OBSOLETE movs pc,lr */ -/* OBSOLETE */ -/* OBSOLETE .global _convert_to_extended */ -/* OBSOLETE */ -/* OBSOLETE _convert_to_extended: */ -/* OBSOLETE */ -/* OBSOLETE ldfd f0,[a1] */ -/* OBSOLETE stfe f0,[a2] */ -/* OBSOLETE movs pc,lr */ diff --git a/contrib/gdb/gdb/arm-xdep.c b/contrib/gdb/gdb/arm-xdep.c deleted file mode 100644 index 64ca9003665..00000000000 --- a/contrib/gdb/gdb/arm-xdep.c +++ /dev/null @@ -1,575 +0,0 @@ -/* OBSOLETE /* Acorn Risc Machine host machine support. */ -/* OBSOLETE Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. */ -/* OBSOLETE */ -/* OBSOLETE This file is part of GDB. */ -/* OBSOLETE */ -/* OBSOLETE This program is free software; you can redistribute it and/or modify */ -/* OBSOLETE it under the terms of the GNU General Public License as published by */ -/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */ -/* OBSOLETE (at your option) any later version. */ -/* OBSOLETE */ -/* OBSOLETE This program is distributed in the hope that it will be useful, */ -/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* OBSOLETE GNU General Public License for more details. */ -/* OBSOLETE */ -/* OBSOLETE You should have received a copy of the GNU General Public License */ -/* OBSOLETE along with this program; if not, write to the Free Software */ -/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */ -/* OBSOLETE Boston, MA 02111-1307, USA. *x/ */ -/* OBSOLETE */ -/* OBSOLETE #include "defs.h" */ -/* OBSOLETE #include "frame.h" */ -/* OBSOLETE #include "inferior.h" */ -/* OBSOLETE #include "opcode/arm.h" */ -/* OBSOLETE */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE */ -/* OBSOLETE #define N_TXTADDR(hdr) 0x8000 */ -/* OBSOLETE #define N_DATADDR(hdr) (hdr.a_text + 0x8000) */ -/* OBSOLETE */ -/* OBSOLETE #include "gdbcore.h" */ -/* OBSOLETE */ -/* OBSOLETE #include /* After a.out.h *x/ */ -/* OBSOLETE #include */ -/* OBSOLETE #include "gdb_stat.h" */ -/* OBSOLETE */ -/* OBSOLETE #include */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE fetch_inferior_registers (regno) */ -/* OBSOLETE int regno; /* Original value discarded *x/ */ -/* OBSOLETE { */ -/* OBSOLETE register unsigned int regaddr; */ -/* OBSOLETE char buf[MAX_REGISTER_RAW_SIZE]; */ -/* OBSOLETE register int i; */ -/* OBSOLETE */ -/* OBSOLETE struct user u; */ -/* OBSOLETE unsigned int offset = (char *) &u.u_ar0 - (char *) &u; */ -/* OBSOLETE offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0) */ -/* OBSOLETE - KERNEL_U_ADDR; */ -/* OBSOLETE */ -/* OBSOLETE registers_fetched (); */ -/* OBSOLETE */ -/* OBSOLETE for (regno = 0; regno < 16; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE regaddr = offset + regno * 4; */ -/* OBSOLETE *(int *) &buf[0] = ptrace (PT_READ_U, inferior_pid, */ -/* OBSOLETE (PTRACE_ARG3_TYPE) regaddr, 0); */ -/* OBSOLETE if (regno == PC_REGNUM) */ -/* OBSOLETE *(int *) &buf[0] = GET_PC_PART (*(int *) &buf[0]); */ -/* OBSOLETE supply_register (regno, buf); */ -/* OBSOLETE } */ -/* OBSOLETE *(int *) &buf[0] = ptrace (PT_READ_U, inferior_pid, */ -/* OBSOLETE (PTRACE_ARG3_TYPE) (offset + PC * 4), 0); */ -/* OBSOLETE supply_register (PS_REGNUM, buf); /* set virtual register ps same as pc *x/ */ -/* OBSOLETE */ -/* OBSOLETE /* read the floating point registers *x/ */ -/* OBSOLETE offset = (char *) &u.u_fp_regs - (char *) &u; */ -/* OBSOLETE *(int *) buf = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0); */ -/* OBSOLETE supply_register (FPS_REGNUM, buf); */ -/* OBSOLETE for (regno = 16; regno < 24; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE regaddr = offset + 4 + 12 * (regno - 16); */ -/* OBSOLETE for (i = 0; i < 12; i += sizeof (int)) */ -/* OBSOLETE *(int *) &buf[i] = ptrace (PT_READ_U, inferior_pid, */ -/* OBSOLETE (PTRACE_ARG3_TYPE) (regaddr + i), 0); */ -/* OBSOLETE supply_register (regno, buf); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Store our register values back into the inferior. */ -/* OBSOLETE If REGNO is -1, do this for all registers. */ -/* OBSOLETE Otherwise, REGNO specifies which register (so we can save time). *x/ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE store_inferior_registers (regno) */ -/* OBSOLETE int regno; */ -/* OBSOLETE { */ -/* OBSOLETE register unsigned int regaddr; */ -/* OBSOLETE char buf[80]; */ -/* OBSOLETE */ -/* OBSOLETE struct user u; */ -/* OBSOLETE unsigned long value; */ -/* OBSOLETE unsigned int offset = (char *) &u.u_ar0 - (char *) &u; */ -/* OBSOLETE offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0) */ -/* OBSOLETE - KERNEL_U_ADDR; */ -/* OBSOLETE */ -/* OBSOLETE if (regno >= 0) */ -/* OBSOLETE { */ -/* OBSOLETE if (regno >= 16) */ -/* OBSOLETE return; */ -/* OBSOLETE regaddr = offset + 4 * regno; */ -/* OBSOLETE errno = 0; */ -/* OBSOLETE value = read_register (regno); */ -/* OBSOLETE if (regno == PC_REGNUM) */ -/* OBSOLETE value = SET_PC_PART (read_register (PS_REGNUM), value); */ -/* OBSOLETE ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value); */ -/* OBSOLETE if (errno != 0) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (buf, "writing register number %d", regno); */ -/* OBSOLETE perror_with_name (buf); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE for (regno = 0; regno < 15; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE regaddr = offset + regno * 4; */ -/* OBSOLETE errno = 0; */ -/* OBSOLETE value = read_register (regno); */ -/* OBSOLETE if (regno == PC_REGNUM) */ -/* OBSOLETE value = SET_PC_PART (read_register (PS_REGNUM), value); */ -/* OBSOLETE ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value); */ -/* OBSOLETE if (errno != 0) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (buf, "writing all regs, number %d", regno); */ -/* OBSOLETE perror_with_name (buf); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Work with core dump and executable files, for GDB. */ -/* OBSOLETE This code would be in corefile.c if it weren't machine-dependent. *x/ */ -/* OBSOLETE */ -/* OBSOLETE /* Structure to describe the chain of shared libraries used */ -/* OBSOLETE by the execfile. */ -/* OBSOLETE e.g. prog shares Xt which shares X11 which shares c. *x/ */ -/* OBSOLETE */ -/* OBSOLETE struct shared_library */ -/* OBSOLETE { */ -/* OBSOLETE struct exec_header header; */ -/* OBSOLETE char name[SHLIBLEN]; */ -/* OBSOLETE CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file *x/ */ -/* OBSOLETE long data_offset; /* offset of data section in file *x/ */ -/* OBSOLETE int chan; /* file descriptor for the file *x/ */ -/* OBSOLETE struct shared_library *shares; /* library this one shares *x/ */ -/* OBSOLETE }; */ -/* OBSOLETE static struct shared_library *shlib = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* Hook for `exec_file_command' command to call. *x/ */ -/* OBSOLETE */ -/* OBSOLETE extern void (*exec_file_display_hook) (); */ -/* OBSOLETE */ -/* OBSOLETE static CORE_ADDR unshared_text_start; */ -/* OBSOLETE */ -/* OBSOLETE /* extended header from exec file (for shared library info) *x/ */ -/* OBSOLETE */ -/* OBSOLETE static struct exec_header exec_header; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE core_file_command (filename, from_tty) */ -/* OBSOLETE char *filename; */ -/* OBSOLETE int from_tty; */ -/* OBSOLETE { */ -/* OBSOLETE int val; */ -/* OBSOLETE */ -/* OBSOLETE /* Discard all vestiges of any previous core file */ -/* OBSOLETE and mark data and stack spaces as empty. *x/ */ -/* OBSOLETE */ -/* OBSOLETE if (corefile) */ -/* OBSOLETE free (corefile); */ -/* OBSOLETE corefile = 0; */ -/* OBSOLETE */ -/* OBSOLETE if (corechan >= 0) */ -/* OBSOLETE close (corechan); */ -/* OBSOLETE corechan = -1; */ -/* OBSOLETE */ -/* OBSOLETE data_start = 0; */ -/* OBSOLETE data_end = 0; */ -/* OBSOLETE stack_start = STACK_END_ADDR; */ -/* OBSOLETE stack_end = STACK_END_ADDR; */ -/* OBSOLETE */ -/* OBSOLETE /* Now, if a new core file was specified, open it and digest it. *x/ */ -/* OBSOLETE */ -/* OBSOLETE if (filename) */ -/* OBSOLETE { */ -/* OBSOLETE filename = tilde_expand (filename); */ -/* OBSOLETE make_cleanup (free, filename); */ -/* OBSOLETE */ -/* OBSOLETE if (have_inferior_p ()) */ -/* OBSOLETE error ("To look at a core file, you must kill the program with \"kill\"."); */ -/* OBSOLETE corechan = open (filename, O_RDONLY, 0); */ -/* OBSOLETE if (corechan < 0) */ -/* OBSOLETE perror_with_name (filename); */ -/* OBSOLETE /* 4.2-style (and perhaps also sysV-style) core dump file. *x/ */ -/* OBSOLETE { */ -/* OBSOLETE struct user u; */ -/* OBSOLETE */ -/* OBSOLETE unsigned int reg_offset, fp_reg_offset; */ -/* OBSOLETE */ -/* OBSOLETE val = myread (corechan, &u, sizeof u); */ -/* OBSOLETE if (val < 0) */ -/* OBSOLETE perror_with_name ("Not a core file: reading upage"); */ -/* OBSOLETE if (val != sizeof u) */ -/* OBSOLETE error ("Not a core file: could only read %d bytes", val); */ -/* OBSOLETE */ -/* OBSOLETE /* We are depending on exec_file_command having been called */ -/* OBSOLETE previously to set exec_data_start. Since the executable */ -/* OBSOLETE and the core file share the same text segment, the address */ -/* OBSOLETE of the data segment will be the same in both. *x/ */ -/* OBSOLETE data_start = exec_data_start; */ -/* OBSOLETE */ -/* OBSOLETE data_end = data_start + NBPG * u.u_dsize; */ -/* OBSOLETE stack_start = stack_end - NBPG * u.u_ssize; */ -/* OBSOLETE data_offset = NBPG * UPAGES; */ -/* OBSOLETE stack_offset = NBPG * (UPAGES + u.u_dsize); */ -/* OBSOLETE */ -/* OBSOLETE /* Some machines put an absolute address in here and some put */ -/* OBSOLETE the offset in the upage of the regs. *x/ */ -/* OBSOLETE reg_offset = (int) u.u_ar0; */ -/* OBSOLETE if (reg_offset > NBPG * UPAGES) */ -/* OBSOLETE reg_offset -= KERNEL_U_ADDR; */ -/* OBSOLETE fp_reg_offset = (char *) &u.u_fp_regs - (char *) &u; */ -/* OBSOLETE */ -/* OBSOLETE /* I don't know where to find this info. */ -/* OBSOLETE So, for now, mark it as not available. *x/ */ -/* OBSOLETE N_SET_MAGIC (core_aouthdr, 0); */ -/* OBSOLETE */ -/* OBSOLETE /* Read the register values out of the core file and store */ -/* OBSOLETE them where `read_register' will find them. *x/ */ -/* OBSOLETE */ -/* OBSOLETE { */ -/* OBSOLETE register int regno; */ -/* OBSOLETE */ -/* OBSOLETE for (regno = 0; regno < NUM_REGS; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE char buf[MAX_REGISTER_RAW_SIZE]; */ -/* OBSOLETE */ -/* OBSOLETE if (regno < 16) */ -/* OBSOLETE val = lseek (corechan, reg_offset + 4 * regno, 0); */ -/* OBSOLETE else if (regno < 24) */ -/* OBSOLETE val = lseek (corechan, fp_reg_offset + 4 + 12 * (regno - 24), 0); */ -/* OBSOLETE else if (regno == 24) */ -/* OBSOLETE val = lseek (corechan, fp_reg_offset, 0); */ -/* OBSOLETE else if (regno == 25) */ -/* OBSOLETE val = lseek (corechan, reg_offset + 4 * PC, 0); */ -/* OBSOLETE if (val < 0 */ -/* OBSOLETE || (val = myread (corechan, buf, sizeof buf)) < 0) */ -/* OBSOLETE { */ -/* OBSOLETE char *buffer = (char *) alloca (strlen (REGISTER_NAME (regno)) */ -/* OBSOLETE + 30); */ -/* OBSOLETE strcpy (buffer, "Reading register "); */ -/* OBSOLETE strcat (buffer, REGISTER_NAME (regno)); */ -/* OBSOLETE */ -/* OBSOLETE perror_with_name (buffer); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (regno == PC_REGNUM) */ -/* OBSOLETE *(int *) buf = GET_PC_PART (*(int *) buf); */ -/* OBSOLETE supply_register (regno, buf); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE if (filename[0] == '/') */ -/* OBSOLETE corefile = savestring (filename, strlen (filename)); */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE corefile = concat (current_directory, "/", filename, NULL); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE flush_cached_frames (); */ -/* OBSOLETE select_frame (get_current_frame (), 0); */ -/* OBSOLETE validate_files (); */ -/* OBSOLETE } */ -/* OBSOLETE else if (from_tty) */ -/* OBSOLETE printf ("No core file now.\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #if 0 */ -/* OBSOLETE /* Work with core dump and executable files, for GDB. */ -/* OBSOLETE This code would be in corefile.c if it weren't machine-dependent. *x/ */ -/* OBSOLETE */ -/* OBSOLETE /* Structure to describe the chain of shared libraries used */ -/* OBSOLETE by the execfile. */ -/* OBSOLETE e.g. prog shares Xt which shares X11 which shares c. *x/ */ -/* OBSOLETE */ -/* OBSOLETE struct shared_library */ -/* OBSOLETE { */ -/* OBSOLETE struct exec_header header; */ -/* OBSOLETE char name[SHLIBLEN]; */ -/* OBSOLETE CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file *x/ */ -/* OBSOLETE long data_offset; /* offset of data section in file *x/ */ -/* OBSOLETE int chan; /* file descriptor for the file *x/ */ -/* OBSOLETE struct shared_library *shares; /* library this one shares *x/ */ -/* OBSOLETE }; */ -/* OBSOLETE static struct shared_library *shlib = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* Hook for `exec_file_command' command to call. *x/ */ -/* OBSOLETE */ -/* OBSOLETE extern void (*exec_file_display_hook) (); */ -/* OBSOLETE */ -/* OBSOLETE static CORE_ADDR unshared_text_start; */ -/* OBSOLETE */ -/* OBSOLETE /* extended header from exec file (for shared library info) *x/ */ -/* OBSOLETE */ -/* OBSOLETE static struct exec_header exec_header; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE exec_file_command (filename, from_tty) */ -/* OBSOLETE char *filename; */ -/* OBSOLETE int from_tty; */ -/* OBSOLETE { */ -/* OBSOLETE int val; */ -/* OBSOLETE */ -/* OBSOLETE /* Eliminate all traces of old exec file. */ -/* OBSOLETE Mark text segment as empty. *x/ */ -/* OBSOLETE */ -/* OBSOLETE if (execfile) */ -/* OBSOLETE free (execfile); */ -/* OBSOLETE execfile = 0; */ -/* OBSOLETE data_start = 0; */ -/* OBSOLETE data_end -= exec_data_start; */ -/* OBSOLETE text_start = 0; */ -/* OBSOLETE unshared_text_start = 0; */ -/* OBSOLETE text_end = 0; */ -/* OBSOLETE exec_data_start = 0; */ -/* OBSOLETE exec_data_end = 0; */ -/* OBSOLETE if (execchan >= 0) */ -/* OBSOLETE close (execchan); */ -/* OBSOLETE execchan = -1; */ -/* OBSOLETE if (shlib) */ -/* OBSOLETE { */ -/* OBSOLETE close_shared_library (shlib); */ -/* OBSOLETE shlib = 0; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Now open and digest the file the user requested, if any. *x/ */ -/* OBSOLETE */ -/* OBSOLETE if (filename) */ -/* OBSOLETE { */ -/* OBSOLETE filename = tilde_expand (filename); */ -/* OBSOLETE make_cleanup (free, filename); */ -/* OBSOLETE */ -/* OBSOLETE execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, */ -/* OBSOLETE &execfile); */ -/* OBSOLETE if (execchan < 0) */ -/* OBSOLETE perror_with_name (filename); */ -/* OBSOLETE */ -/* OBSOLETE { */ -/* OBSOLETE struct stat st_exec; */ -/* OBSOLETE */ -/* OBSOLETE #ifdef HEADER_SEEK_FD */ -/* OBSOLETE HEADER_SEEK_FD (execchan); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE val = myread (execchan, &exec_header, sizeof exec_header); */ -/* OBSOLETE exec_aouthdr = exec_header.a_exec; */ -/* OBSOLETE */ -/* OBSOLETE if (val < 0) */ -/* OBSOLETE perror_with_name (filename); */ -/* OBSOLETE */ -/* OBSOLETE text_start = 0x8000; */ -/* OBSOLETE */ -/* OBSOLETE /* Look for shared library if needed *x/ */ -/* OBSOLETE if (exec_header.a_exec.a_magic & MF_USES_SL) */ -/* OBSOLETE shlib = open_shared_library (exec_header.a_shlibname, text_start); */ -/* OBSOLETE */ -/* OBSOLETE text_offset = N_TXTOFF (exec_aouthdr); */ -/* OBSOLETE exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text; */ -/* OBSOLETE */ -/* OBSOLETE if (shlib) */ -/* OBSOLETE { */ -/* OBSOLETE unshared_text_start = shared_text_end (shlib) & ~0x7fff; */ -/* OBSOLETE stack_start = shlib->header.a_exec.a_sldatabase; */ -/* OBSOLETE stack_end = STACK_END_ADDR; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE unshared_text_start = 0x8000; */ -/* OBSOLETE text_end = unshared_text_start + exec_aouthdr.a_text; */ -/* OBSOLETE */ -/* OBSOLETE exec_data_start = unshared_text_start + exec_aouthdr.a_text; */ -/* OBSOLETE exec_data_end = exec_data_start + exec_aouthdr.a_data; */ -/* OBSOLETE */ -/* OBSOLETE data_start = exec_data_start; */ -/* OBSOLETE data_end += exec_data_start; */ -/* OBSOLETE */ -/* OBSOLETE fstat (execchan, &st_exec); */ -/* OBSOLETE exec_mtime = st_exec.st_mtime; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE validate_files (); */ -/* OBSOLETE } */ -/* OBSOLETE else if (from_tty) */ -/* OBSOLETE printf ("No executable file now.\n"); */ -/* OBSOLETE */ -/* OBSOLETE /* Tell display code (if any) about the changed file name. *x/ */ -/* OBSOLETE if (exec_file_display_hook) */ -/* OBSOLETE (*exec_file_display_hook) (filename); */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE #if 0 */ -/* OBSOLETE /* Read from the program's memory (except for inferior processes). */ -/* OBSOLETE This function is misnamed, since it only reads, never writes; and */ -/* OBSOLETE since it will use the core file and/or executable file as necessary. */ -/* OBSOLETE */ -/* OBSOLETE It should be extended to write as well as read, FIXME, for patching files. */ -/* OBSOLETE */ -/* OBSOLETE Return 0 if address could be read, EIO if addresss out of bounds. *x/ */ -/* OBSOLETE */ -/* OBSOLETE int */ -/* OBSOLETE xfer_core_file (memaddr, myaddr, len) */ -/* OBSOLETE CORE_ADDR memaddr; */ -/* OBSOLETE char *myaddr; */ -/* OBSOLETE int len; */ -/* OBSOLETE { */ -/* OBSOLETE register int i; */ -/* OBSOLETE register int val; */ -/* OBSOLETE int xferchan; */ -/* OBSOLETE char **xferfile; */ -/* OBSOLETE int fileptr; */ -/* OBSOLETE int returnval = 0; */ -/* OBSOLETE */ -/* OBSOLETE while (len > 0) */ -/* OBSOLETE { */ -/* OBSOLETE xferfile = 0; */ -/* OBSOLETE xferchan = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* Determine which file the next bunch of addresses reside in, */ -/* OBSOLETE and where in the file. Set the file's read/write pointer */ -/* OBSOLETE to point at the proper place for the desired address */ -/* OBSOLETE and set xferfile and xferchan for the correct file. */ -/* OBSOLETE */ -/* OBSOLETE If desired address is nonexistent, leave them zero. */ -/* OBSOLETE */ -/* OBSOLETE i is set to the number of bytes that can be handled */ -/* OBSOLETE along with the next address. */ -/* OBSOLETE */ -/* OBSOLETE We put the most likely tests first for efficiency. *x/ */ -/* OBSOLETE */ -/* OBSOLETE /* Note that if there is no core file */ -/* OBSOLETE data_start and data_end are equal. *x/ */ -/* OBSOLETE if (memaddr >= data_start && memaddr < data_end) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, data_end - memaddr); */ -/* OBSOLETE fileptr = memaddr - data_start + data_offset; */ -/* OBSOLETE xferfile = &corefile; */ -/* OBSOLETE xferchan = corechan; */ -/* OBSOLETE } */ -/* OBSOLETE /* Note that if there is no core file */ -/* OBSOLETE stack_start and stack_end define the shared library data. *x/ */ -/* OBSOLETE else if (memaddr >= stack_start && memaddr < stack_end) */ -/* OBSOLETE { */ -/* OBSOLETE if (corechan < 0) */ -/* OBSOLETE { */ -/* OBSOLETE struct shared_library *lib; */ -/* OBSOLETE for (lib = shlib; lib; lib = lib->shares) */ -/* OBSOLETE if (memaddr >= lib->header.a_exec.a_sldatabase && */ -/* OBSOLETE memaddr < lib->header.a_exec.a_sldatabase + */ -/* OBSOLETE lib->header.a_exec.a_data) */ -/* OBSOLETE break; */ -/* OBSOLETE if (lib) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, lib->header.a_exec.a_sldatabase + */ -/* OBSOLETE lib->header.a_exec.a_data - memaddr); */ -/* OBSOLETE fileptr = lib->data_offset + memaddr - */ -/* OBSOLETE lib->header.a_exec.a_sldatabase; */ -/* OBSOLETE xferfile = execfile; */ -/* OBSOLETE xferchan = lib->chan; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, stack_end - memaddr); */ -/* OBSOLETE fileptr = memaddr - stack_start + stack_offset; */ -/* OBSOLETE xferfile = &corefile; */ -/* OBSOLETE xferchan = corechan; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE else if (corechan < 0 */ -/* OBSOLETE && memaddr >= exec_data_start && memaddr < exec_data_end) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, exec_data_end - memaddr); */ -/* OBSOLETE fileptr = memaddr - exec_data_start + exec_data_offset; */ -/* OBSOLETE xferfile = &execfile; */ -/* OBSOLETE xferchan = execchan; */ -/* OBSOLETE } */ -/* OBSOLETE else if (memaddr >= text_start && memaddr < text_end) */ -/* OBSOLETE { */ -/* OBSOLETE struct shared_library *lib; */ -/* OBSOLETE for (lib = shlib; lib; lib = lib->shares) */ -/* OBSOLETE if (memaddr >= lib->text_start && */ -/* OBSOLETE memaddr < lib->text_start + lib->header.a_exec.a_text) */ -/* OBSOLETE break; */ -/* OBSOLETE if (lib) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, lib->header.a_exec.a_text + */ -/* OBSOLETE lib->text_start - memaddr); */ -/* OBSOLETE fileptr = memaddr - lib->text_start + text_offset; */ -/* OBSOLETE xferfile = &execfile; */ -/* OBSOLETE xferchan = lib->chan; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, text_end - memaddr); */ -/* OBSOLETE fileptr = memaddr - unshared_text_start + text_offset; */ -/* OBSOLETE xferfile = &execfile; */ -/* OBSOLETE xferchan = execchan; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE else if (memaddr < text_start) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, text_start - memaddr); */ -/* OBSOLETE } */ -/* OBSOLETE else if (memaddr >= text_end */ -/* OBSOLETE && memaddr < (corechan >= 0 ? data_start : exec_data_start)) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, data_start - memaddr); */ -/* OBSOLETE } */ -/* OBSOLETE else if (corechan >= 0 */ -/* OBSOLETE && memaddr >= data_end && memaddr < stack_start) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, stack_start - memaddr); */ -/* OBSOLETE } */ -/* OBSOLETE else if (corechan < 0 && memaddr >= exec_data_end) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, -memaddr); */ -/* OBSOLETE } */ -/* OBSOLETE else if (memaddr >= stack_end && stack_end != 0) */ -/* OBSOLETE { */ -/* OBSOLETE i = min (len, -memaddr); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE /* Address did not classify into one of the known ranges. */ -/* OBSOLETE This shouldn't happen; we catch the endpoints. *x/ */ -/* OBSOLETE internal_error ("Bad case logic in xfer_core_file."); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Now we know which file to use. */ -/* OBSOLETE Set up its pointer and transfer the data. *x/ */ -/* OBSOLETE if (xferfile) */ -/* OBSOLETE { */ -/* OBSOLETE if (*xferfile == 0) */ -/* OBSOLETE if (xferfile == &execfile) */ -/* OBSOLETE error ("No program file to examine."); */ -/* OBSOLETE else */ -/* OBSOLETE error ("No core dump file or running program to examine."); */ -/* OBSOLETE val = lseek (xferchan, fileptr, 0); */ -/* OBSOLETE if (val < 0) */ -/* OBSOLETE perror_with_name (*xferfile); */ -/* OBSOLETE val = myread (xferchan, myaddr, i); */ -/* OBSOLETE if (val < 0) */ -/* OBSOLETE perror_with_name (*xferfile); */ -/* OBSOLETE } */ -/* OBSOLETE /* If this address is for nonexistent memory, */ -/* OBSOLETE read zeros if reading, or do nothing if writing. */ -/* OBSOLETE Actually, we never right. *x/ */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE memset (myaddr, '\0', i); */ -/* OBSOLETE returnval = EIO; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE memaddr += i; */ -/* OBSOLETE myaddr += i; */ -/* OBSOLETE len -= i; */ -/* OBSOLETE } */ -/* OBSOLETE return returnval; */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ diff --git a/contrib/gdb/gdb/c-exp.tab.c b/contrib/gdb/gdb/c-exp.tab.c deleted file mode 100644 index 46ff4363d0e..00000000000 --- a/contrib/gdb/gdb/c-exp.tab.c +++ /dev/null @@ -1,2865 +0,0 @@ - -/* A Bison parser, made from c-exp.y - by GNU Bison version 1.27 - */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define INT 257 -#define FLOAT 258 -#define STRING 259 -#define NAME 260 -#define TYPENAME 261 -#define NAME_OR_INT 262 -#define STRUCT 263 -#define CLASS 264 -#define UNION 265 -#define ENUM 266 -#define SIZEOF 267 -#define UNSIGNED 268 -#define COLONCOLON 269 -#define TEMPLATE 270 -#define ERROR 271 -#define SIGNED_KEYWORD 272 -#define LONG 273 -#define SHORT 274 -#define INT_KEYWORD 275 -#define CONST_KEYWORD 276 -#define VOLATILE_KEYWORD 277 -#define DOUBLE_KEYWORD 278 -#define VARIABLE 279 -#define ASSIGN_MODIFY 280 -#define THIS 281 -#define TRUEKEYWORD 282 -#define FALSEKEYWORD 283 -#define ABOVE_COMMA 284 -#define OROR 285 -#define ANDAND 286 -#define EQUAL 287 -#define NOTEQUAL 288 -#define LEQ 289 -#define GEQ 290 -#define LSH 291 -#define RSH 292 -#define UNARY 293 -#define INCREMENT 294 -#define DECREMENT 295 -#define ARROW 296 -#define BLOCKNAME 297 -#define FILENAME 298 - -#line 38 "c-exp.y" - - -#include "defs.h" -#include "gdb_string.h" -#include -#include "expression.h" -#include "value.h" -#include "parser-defs.h" -#include "language.h" -#include "c-lang.h" -#include "bfd.h" /* Required by objfiles.h. */ -#include "symfile.h" /* Required by objfiles.h. */ -#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ - -/* Flag indicating we're dealing with HP-compiled objects */ -extern int hp_som_som_object_present; - -/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), - as well as gratuitiously global symbol names, so we can have multiple - yacc generated parsers in gdb. Note that these are only the variables - produced by yacc. If other parser generators (bison, byacc, etc) produce - additional global names that conflict at link time, then those parser - generators need to be fixed instead of adding those names to this list. */ - -#define yymaxdepth c_maxdepth -#define yyparse c_parse -#define yylex c_lex -#define yyerror c_error -#define yylval c_lval -#define yychar c_char -#define yydebug c_debug -#define yypact c_pact -#define yyr1 c_r1 -#define yyr2 c_r2 -#define yydef c_def -#define yychk c_chk -#define yypgo c_pgo -#define yyact c_act -#define yyexca c_exca -#define yyerrflag c_errflag -#define yynerrs c_nerrs -#define yyps c_ps -#define yypv c_pv -#define yys c_s -#define yy_yys c_yys -#define yystate c_state -#define yytmp c_tmp -#define yyv c_v -#define yy_yyv c_yyv -#define yyval c_val -#define yylloc c_lloc -#define yyreds c_reds /* With YYDEBUG defined */ -#define yytoks c_toks /* With YYDEBUG defined */ -#define yylhs c_yylhs -#define yylen c_yylen -#define yydefred c_yydefred -#define yydgoto c_yydgoto -#define yysindex c_yysindex -#define yyrindex c_yyrindex -#define yygindex c_yygindex -#define yytable c_yytable -#define yycheck c_yycheck - -#ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ -#endif - -int -yyparse PARAMS ((void)); - -static int -yylex PARAMS ((void)); - -void -yyerror PARAMS ((char *)); - - -#line 120 "c-exp.y" -typedef union - { - LONGEST lval; - struct { - LONGEST val; - struct type *type; - } typed_val_int; - struct { - DOUBLEST dval; - struct type *type; - } typed_val_float; - struct symbol *sym; - struct type *tval; - struct stoken sval; - struct ttype tsym; - struct symtoken ssym; - int voidval; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - - struct type **tvec; - int *ivec; - } YYSTYPE; -#line 145 "c-exp.y" - -/* YYSTYPE gets defined by %union */ -static int -parse_number PARAMS ((char *, int, int, YYSTYPE *)); -#include - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 214 -#define YYFLAG -32768 -#define YYNTBASE 69 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 298 ? yytranslate[x] : 91) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 62, 2, 2, 2, 52, 38, 2, 59, - 65, 50, 48, 30, 49, 57, 51, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 68, 2, 41, - 32, 42, 33, 47, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 58, 2, 64, 37, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 66, 36, 67, 63, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 31, 34, 35, 39, 40, 43, 44, - 45, 46, 53, 54, 55, 56, 60, 61 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 4, 6, 8, 12, 15, 18, 21, 24, - 27, 30, 33, 36, 39, 42, 46, 50, 55, 59, - 63, 68, 73, 74, 80, 82, 83, 85, 89, 91, - 95, 100, 105, 109, 113, 117, 121, 125, 129, 133, - 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, - 177, 181, 185, 191, 195, 199, 201, 203, 205, 207, - 209, 214, 216, 218, 220, 222, 224, 226, 230, 234, - 238, 243, 245, 248, 250, 252, 255, 258, 261, 265, - 269, 271, 274, 276, 279, 281, 285, 288, 290, 293, - 295, 298, 302, 305, 309, 311, 315, 317, 319, 321, - 323, 326, 330, 333, 337, 341, 346, 349, 353, 355, - 358, 361, 364, 367, 370, 373, 375, 378, 380, 386, - 389, 392, 394, 396, 398, 400, 402, 406, 408, 410, - 412, 414, 416 -}; - -static const short yyrhs[] = { 71, - 0, 70, 0, 85, 0, 72, 0, 71, 30, 72, - 0, 50, 72, 0, 38, 72, 0, 49, 72, 0, - 62, 72, 0, 63, 72, 0, 54, 72, 0, 55, - 72, 0, 72, 54, 0, 72, 55, 0, 13, 72, - 0, 72, 56, 89, 0, 72, 56, 79, 0, 72, - 56, 50, 72, 0, 72, 57, 89, 0, 72, 57, - 79, 0, 72, 57, 50, 72, 0, 72, 58, 71, - 64, 0, 0, 72, 59, 73, 75, 65, 0, 66, - 0, 0, 72, 0, 75, 30, 72, 0, 67, 0, - 74, 75, 76, 0, 74, 85, 76, 72, 0, 59, - 85, 65, 72, 0, 59, 71, 65, 0, 72, 47, - 72, 0, 72, 50, 72, 0, 72, 51, 72, 0, - 72, 52, 72, 0, 72, 48, 72, 0, 72, 49, - 72, 0, 72, 45, 72, 0, 72, 46, 72, 0, - 72, 39, 72, 0, 72, 40, 72, 0, 72, 43, - 72, 0, 72, 44, 72, 0, 72, 41, 72, 0, - 72, 42, 72, 0, 72, 38, 72, 0, 72, 37, - 72, 0, 72, 36, 72, 0, 72, 35, 72, 0, - 72, 34, 72, 0, 72, 33, 72, 68, 72, 0, - 72, 32, 72, 0, 72, 26, 72, 0, 3, 0, - 8, 0, 4, 0, 78, 0, 25, 0, 13, 59, - 85, 65, 0, 5, 0, 27, 0, 28, 0, 29, - 0, 60, 0, 61, 0, 77, 15, 89, 0, 77, - 15, 89, 0, 86, 15, 89, 0, 86, 15, 63, - 89, 0, 79, 0, 15, 89, 0, 90, 0, 86, - 0, 86, 22, 0, 86, 23, 0, 86, 81, 0, - 86, 22, 81, 0, 86, 23, 81, 0, 50, 0, - 50, 81, 0, 38, 0, 38, 81, 0, 82, 0, - 59, 81, 65, 0, 82, 83, 0, 83, 0, 82, - 84, 0, 84, 0, 58, 64, 0, 58, 3, 64, - 0, 59, 65, 0, 59, 88, 65, 0, 80, 0, - 86, 15, 50, 0, 7, 0, 21, 0, 19, 0, - 20, 0, 19, 21, 0, 14, 19, 21, 0, 19, - 19, 0, 19, 19, 21, 0, 14, 19, 19, 0, - 14, 19, 19, 21, 0, 20, 21, 0, 14, 20, - 21, 0, 24, 0, 19, 24, 0, 9, 89, 0, - 10, 89, 0, 11, 89, 0, 12, 89, 0, 14, - 87, 0, 14, 0, 18, 87, 0, 18, 0, 16, - 89, 41, 85, 42, 0, 22, 86, 0, 23, 86, - 0, 7, 0, 21, 0, 19, 0, 20, 0, 85, - 0, 88, 30, 85, 0, 6, 0, 60, 0, 7, - 0, 8, 0, 6, 0, 60, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 230, 231, 234, 241, 242, 247, 250, 253, 257, 261, - 265, 269, 273, 277, 281, 285, 291, 299, 303, 309, - 317, 321, 325, 329, 335, 339, 342, 346, 350, 353, - 360, 366, 372, 378, 382, 386, 390, 394, 398, 402, - 406, 410, 414, 418, 422, 426, 430, 434, 438, 442, - 446, 450, 454, 458, 462, 468, 475, 486, 493, 496, - 500, 508, 533, 538, 545, 554, 562, 568, 579, 595, - 608, 632, 633, 667, 725, 731, 732, 733, 735, 737, - 741, 743, 745, 747, 749, 752, 754, 759, 766, 768, - 772, 774, 778, 780, 792, 793, 798, 800, 802, 804, - 806, 808, 810, 812, 814, 816, 818, 820, 822, 824, - 826, 829, 832, 835, 838, 840, 842, 844, 849, 856, - 857, 860, 861, 867, 873, 882, 887, 894, 895, 896, - 897, 900, 901 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","INT","FLOAT", -"STRING","NAME","TYPENAME","NAME_OR_INT","STRUCT","CLASS","UNION","ENUM","SIZEOF", -"UNSIGNED","COLONCOLON","TEMPLATE","ERROR","SIGNED_KEYWORD","LONG","SHORT","INT_KEYWORD", -"CONST_KEYWORD","VOLATILE_KEYWORD","DOUBLE_KEYWORD","VARIABLE","ASSIGN_MODIFY", -"THIS","TRUEKEYWORD","FALSEKEYWORD","','","ABOVE_COMMA","'='","'?'","OROR","ANDAND", -"'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'","'>'","LEQ","GEQ","LSH","RSH","'@'", -"'+'","'-'","'*'","'/'","'%'","UNARY","INCREMENT","DECREMENT","ARROW","'.'", -"'['","'('","BLOCKNAME","FILENAME","'!'","'~'","']'","')'","'{'","'}'","':'", -"start","type_exp","exp1","exp","@1","lcurly","arglist","rcurly","block","variable", -"qualified_name","ptype","abs_decl","direct_abs_decl","array_mod","func_mod", -"type","typebase","typename","nonempty_typelist","name","name_not_typename", NULL -}; -#endif - -static const short yyr1[] = { 0, - 69, 69, 70, 71, 71, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 73, 72, 74, 75, 75, 75, 76, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 77, 77, 77, 78, 79, - 79, 78, 78, 78, 80, 80, 80, 80, 80, 80, - 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, - 83, 83, 84, 84, 85, 85, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 87, 87, 87, 87, 88, 88, 89, 89, 89, - 89, 90, 90 -}; - -static const short yyr2[] = { 0, - 1, 1, 1, 1, 3, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 3, 3, 4, 3, 3, - 4, 4, 0, 5, 1, 0, 1, 3, 1, 3, - 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 5, 3, 3, 1, 1, 1, 1, 1, - 4, 1, 1, 1, 1, 1, 1, 3, 3, 3, - 4, 1, 2, 1, 1, 2, 2, 2, 3, 3, - 1, 2, 1, 2, 1, 3, 2, 1, 2, 1, - 2, 3, 2, 3, 1, 3, 1, 1, 1, 1, - 2, 3, 2, 3, 3, 4, 2, 3, 1, 2, - 2, 2, 2, 2, 2, 1, 2, 1, 5, 2, - 2, 1, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 1, 1 -}; - -static const short yydefact[] = { 0, - 56, 58, 62, 132, 97, 57, 0, 0, 0, 0, - 0, 116, 0, 0, 118, 99, 100, 98, 0, 0, - 109, 60, 63, 64, 65, 0, 0, 0, 0, 0, - 0, 133, 67, 0, 0, 25, 2, 1, 4, 26, - 0, 59, 72, 95, 3, 75, 74, 128, 130, 131, - 129, 111, 112, 113, 114, 0, 15, 0, 122, 124, - 125, 123, 115, 73, 0, 124, 125, 117, 103, 101, - 110, 107, 120, 121, 7, 8, 6, 11, 12, 0, - 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 13, 14, 0, 0, - 0, 23, 27, 0, 0, 0, 0, 76, 77, 83, - 81, 0, 0, 78, 85, 88, 90, 0, 0, 105, - 102, 108, 0, 104, 33, 0, 5, 55, 54, 0, - 52, 51, 50, 49, 48, 42, 43, 46, 47, 44, - 45, 40, 41, 34, 38, 39, 35, 36, 37, 130, - 0, 17, 16, 0, 20, 19, 0, 26, 0, 29, - 30, 0, 69, 96, 0, 70, 79, 80, 84, 82, - 0, 91, 93, 0, 126, 75, 0, 0, 87, 89, - 61, 106, 0, 32, 0, 18, 21, 22, 0, 28, - 31, 71, 92, 86, 0, 0, 94, 119, 53, 24, - 127, 0, 0, 0 -}; - -static const short yydefgoto[] = { 212, - 37, 80, 39, 168, 40, 114, 171, 41, 42, 43, - 44, 124, 125, 126, 127, 185, 58, 63, 187, 176, - 47 -}; - -static const short yypact[] = { 205, --32768,-32768,-32768,-32768,-32768,-32768, 46, 46, 46, 46, - 269, 57, 46, 46, 100, 134, -14,-32768, 228, 228, --32768,-32768,-32768,-32768,-32768, 205, 205, 205, 205, 205, - 205, 21,-32768, 205, 205,-32768,-32768, -16, 504, 205, - 22,-32768,-32768,-32768,-32768, 107,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768, 205, 14, 23,-32768, 7, - 24,-32768,-32768,-32768, 10,-32768,-32768,-32768, 34,-32768, --32768,-32768,-32768,-32768, 14, 14, 14, 14, 14, -26, - -21, 14, 14, 205, 205, 205, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205,-32768,-32768, 419, 438, - 205,-32768, 504, -25, -2, 46, 53, 8, 8, 8, - 8, -1, 359,-32768, -41,-32768,-32768, 9, 42, 54, --32768,-32768, 228,-32768,-32768, 205, 504, 504, 504, 467, - 556, 580, 603, 625, 646, 665, 665, 254, 254, 254, - 254, 124, 124, 356, 416, 416, 14, 14, 14, 89, - 205,-32768,-32768, 205,-32768,-32768, -17, 205, 205,-32768, --32768, 205, 93,-32768, 46,-32768,-32768,-32768,-32768,-32768, - 45,-32768,-32768, 50,-32768, 146, -22, 128,-32768,-32768, - 333,-32768, 68, 14, 205, 14, 14,-32768, -3, 504, - 14,-32768,-32768,-32768, 67, 228,-32768,-32768, 531,-32768, --32768, 125, 126,-32768 -}; - -static const short yypgoto[] = {-32768, --32768, 3, -5,-32768,-32768, -44, 12,-32768,-32768, -76, --32768, 79,-32768, 11, 16, 1, 0, 113,-32768, 2, --32768 -}; - - -#define YYLAST 724 - - -static const short yytable[] = { 46, - 45, 181, 38, 84, 169, 57, 72, 206, 52, 53, - 54, 55, 84, 84, 64, 65, 122, 188, 73, 74, - 75, 76, 77, 78, 79, 130, 169, 131, 82, 83, - 46, 81, 162, 165, 113, -66, 116, 129, 135, 46, - 115, 170, 207, 136, 132, 120, 198, 48, 49, 50, - 133, 48, 49, 50, 134, 46, 128, 121, 48, 49, - 50, 210, 182, 59, 170, 122, 123, 107, 108, 109, - 110, 111, 112, 191, 192, 60, 61, 62, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 51, 174, -97, 175, 51, 59, -68, 203, 208, - 163, 166, 51, 167, 204, 175, 174, 173, 66, 67, - 62, 117, 186, 199, 213, 214, 172, 68, 118, 119, - 194, 0, 186, 193, 5, 189, 7, 8, 9, 10, - 190, 12, 0, 14, 120, 15, 16, 17, 18, 19, - 20, 21, 69, 0, 70, 196, 121, 71, 197, 0, - 205, 0, 113, 200, 122, 123, 201, 118, 119, 0, - 101, 102, 103, 104, 105, 106, 202, 107, 108, 109, - 110, 111, 112, 120, 0, 194, 0, 186, 0, 209, - 0, 0, 183, 0, 0, 121, 177, 178, 179, 180, - 0, 184, 0, 122, 123, 186, 211, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 0, 15, 16, 17, 18, 19, 20, 21, 22, - 0, 23, 24, 25, 5, 0, 7, 8, 9, 10, - 0, 12, 26, 14, 0, 15, 16, 17, 18, 19, - 20, 21, 0, 27, 28, 0, 0, 0, 29, 30, - 0, 0, 0, 31, 32, 33, 34, 35, 0, 0, - 36, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 0, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 23, 24, 25, 99, 100, - 101, 102, 103, 104, 105, 106, 26, 107, 108, 109, - 110, 111, 112, 0, 0, 0, 0, 27, 28, 0, - 0, 0, 29, 30, 0, 0, 0, 56, 32, 33, - 34, 35, 0, 0, 36, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 23, - 24, 25, 0, 0, 0, 5, 0, 7, 8, 9, - 10, 0, 12, 0, 14, 0, 15, 16, 17, 18, - 19, 20, 21, 0, 0, 0, 29, 30, 0, 0, - 0, 31, 32, 33, 34, 35, 120, 0, 36, 0, - 0, 0, 0, 102, 103, 104, 105, 106, 121, 107, - 108, 109, 110, 111, 112, 0, 122, 123, 0, 0, - 0, 0, 0, 183, 48, 160, 50, 7, 8, 9, - 10, 0, 12, 0, 14, 0, 15, 16, 17, 18, - 19, 20, 21, 48, 160, 50, 7, 8, 9, 10, - 0, 12, 0, 14, 0, 15, 16, 17, 18, 19, - 20, 21, 0, 0, 0, 104, 105, 106, 161, 107, - 108, 109, 110, 111, 112, 0, 0, 0, 51, 0, - 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, - 0, 0, 85, 0, 0, 0, 0, 51, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 111, 112, 0, 0, 0, 85, - 0, 0, 0, 0, 195, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, - 110, 111, 112, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 111, 112, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 0, 107, - 108, 109, 110, 111, 112, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 0, 107, 108, 109, 110, 111, 112, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 111, 112, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 111, 112, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 0, 107, - 108, 109, 110, 111, 112, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 111, 112 -}; - -static const short yycheck[] = { 0, - 0, 3, 0, 30, 30, 11, 21, 30, 7, 8, - 9, 10, 30, 30, 13, 14, 58, 59, 19, 20, - 26, 27, 28, 29, 30, 19, 30, 21, 34, 35, - 31, 31, 109, 110, 40, 15, 15, 15, 65, 40, - 40, 67, 65, 65, 21, 38, 64, 6, 7, 8, - 41, 6, 7, 8, 21, 56, 56, 50, 6, 7, - 8, 65, 64, 7, 67, 58, 59, 54, 55, 56, - 57, 58, 59, 65, 21, 19, 20, 21, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 60, 50, 15, 63, 60, 7, 15, 64, 42, - 109, 110, 60, 111, 65, 63, 50, 116, 19, 20, - 21, 15, 123, 168, 0, 0, 115, 15, 22, 23, - 136, -1, 133, 133, 7, 125, 9, 10, 11, 12, - 125, 14, -1, 16, 38, 18, 19, 20, 21, 22, - 23, 24, 19, -1, 21, 161, 50, 24, 164, -1, - 15, -1, 168, 169, 58, 59, 172, 22, 23, -1, - 47, 48, 49, 50, 51, 52, 175, 54, 55, 56, - 57, 58, 59, 38, -1, 191, -1, 188, -1, 195, - -1, -1, 65, -1, -1, 50, 118, 119, 120, 121, - -1, 123, -1, 58, 59, 206, 206, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, -1, 18, 19, 20, 21, 22, 23, 24, 25, - -1, 27, 28, 29, 7, -1, 9, 10, 11, 12, - -1, 14, 38, 16, -1, 18, 19, 20, 21, 22, - 23, 24, -1, 49, 50, -1, -1, -1, 54, 55, - -1, -1, -1, 59, 60, 61, 62, 63, -1, -1, - 66, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, -1, 18, 19, 20, 21, - 22, 23, 24, 25, -1, 27, 28, 29, 45, 46, - 47, 48, 49, 50, 51, 52, 38, 54, 55, 56, - 57, 58, 59, -1, -1, -1, -1, 49, 50, -1, - -1, -1, 54, 55, -1, -1, -1, 59, 60, 61, - 62, 63, -1, -1, 66, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, - 18, 19, 20, 21, 22, 23, 24, 25, -1, 27, - 28, 29, -1, -1, -1, 7, -1, 9, 10, 11, - 12, -1, 14, -1, 16, -1, 18, 19, 20, 21, - 22, 23, 24, -1, -1, -1, 54, 55, -1, -1, - -1, 59, 60, 61, 62, 63, 38, -1, 66, -1, - -1, -1, -1, 48, 49, 50, 51, 52, 50, 54, - 55, 56, 57, 58, 59, -1, 58, 59, -1, -1, - -1, -1, -1, 65, 6, 7, 8, 9, 10, 11, - 12, -1, 14, -1, 16, -1, 18, 19, 20, 21, - 22, 23, 24, 6, 7, 8, 9, 10, 11, 12, - -1, 14, -1, 16, -1, 18, 19, 20, 21, 22, - 23, 24, -1, -1, -1, 50, 51, 52, 50, 54, - 55, 56, 57, 58, 59, -1, -1, -1, 60, -1, - -1, -1, -1, -1, -1, -1, -1, 50, -1, -1, - -1, -1, 26, -1, -1, -1, -1, 60, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, - 54, 55, 56, 57, 58, 59, -1, -1, -1, 26, - -1, -1, -1, -1, 68, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, -1, 54, 55, 56, - 57, 58, 59, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, -1, 54, 55, 56, 57, 58, 59, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, - 55, 56, 57, 58, 59, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, -1, 54, 55, 56, 57, 58, 59, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, - 58, 59, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, -1, 54, 55, - 56, 57, 58, 59, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, - 55, 56, 57, 58, 59, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, -1, 54, 55, - 56, 57, 58, 59 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/lib/bison.simple" -/* This file comes from bison-1.27. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for xmalloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC xmalloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 216 "/usr/lib/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to xreallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to xreallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 3: -#line 235 "c-exp.y" -{ write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type(yyvsp[0].tval); - write_exp_elt_opcode(OP_TYPE);; - break;} -case 5: -#line 243 "c-exp.y" -{ write_exp_elt_opcode (BINOP_COMMA); ; - break;} -case 6: -#line 248 "c-exp.y" -{ write_exp_elt_opcode (UNOP_IND); ; - break;} -case 7: -#line 251 "c-exp.y" -{ write_exp_elt_opcode (UNOP_ADDR); ; - break;} -case 8: -#line 254 "c-exp.y" -{ write_exp_elt_opcode (UNOP_NEG); ; - break;} -case 9: -#line 258 "c-exp.y" -{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ; - break;} -case 10: -#line 262 "c-exp.y" -{ write_exp_elt_opcode (UNOP_COMPLEMENT); ; - break;} -case 11: -#line 266 "c-exp.y" -{ write_exp_elt_opcode (UNOP_PREINCREMENT); ; - break;} -case 12: -#line 270 "c-exp.y" -{ write_exp_elt_opcode (UNOP_PREDECREMENT); ; - break;} -case 13: -#line 274 "c-exp.y" -{ write_exp_elt_opcode (UNOP_POSTINCREMENT); ; - break;} -case 14: -#line 278 "c-exp.y" -{ write_exp_elt_opcode (UNOP_POSTDECREMENT); ; - break;} -case 15: -#line 282 "c-exp.y" -{ write_exp_elt_opcode (UNOP_SIZEOF); ; - break;} -case 16: -#line 286 "c-exp.y" -{ write_exp_elt_opcode (STRUCTOP_PTR); - write_exp_string (yyvsp[0].sval); - write_exp_elt_opcode (STRUCTOP_PTR); ; - break;} -case 17: -#line 292 "c-exp.y" -{ /* exp->type::name becomes exp->*(&type::name) */ - /* Note: this doesn't work if name is a - static member! FIXME */ - write_exp_elt_opcode (UNOP_ADDR); - write_exp_elt_opcode (STRUCTOP_MPTR); ; - break;} -case 18: -#line 300 "c-exp.y" -{ write_exp_elt_opcode (STRUCTOP_MPTR); ; - break;} -case 19: -#line 304 "c-exp.y" -{ write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string (yyvsp[0].sval); - write_exp_elt_opcode (STRUCTOP_STRUCT); ; - break;} -case 20: -#line 310 "c-exp.y" -{ /* exp.type::name becomes exp.*(&type::name) */ - /* Note: this doesn't work if name is a - static member! FIXME */ - write_exp_elt_opcode (UNOP_ADDR); - write_exp_elt_opcode (STRUCTOP_MEMBER); ; - break;} -case 21: -#line 318 "c-exp.y" -{ write_exp_elt_opcode (STRUCTOP_MEMBER); ; - break;} -case 22: -#line 322 "c-exp.y" -{ write_exp_elt_opcode (BINOP_SUBSCRIPT); ; - break;} -case 23: -#line 328 "c-exp.y" -{ start_arglist (); ; - break;} -case 24: -#line 330 "c-exp.y" -{ write_exp_elt_opcode (OP_FUNCALL); - write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_FUNCALL); ; - break;} -case 25: -#line 336 "c-exp.y" -{ start_arglist (); ; - break;} -case 27: -#line 343 "c-exp.y" -{ arglist_len = 1; ; - break;} -case 28: -#line 347 "c-exp.y" -{ arglist_len++; ; - break;} -case 29: -#line 351 "c-exp.y" -{ yyval.lval = end_arglist () - 1; ; - break;} -case 30: -#line 354 "c-exp.y" -{ write_exp_elt_opcode (OP_ARRAY); - write_exp_elt_longcst ((LONGEST) 0); - write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); - write_exp_elt_opcode (OP_ARRAY); ; - break;} -case 31: -#line 361 "c-exp.y" -{ write_exp_elt_opcode (UNOP_MEMVAL); - write_exp_elt_type (yyvsp[-2].tval); - write_exp_elt_opcode (UNOP_MEMVAL); ; - break;} -case 32: -#line 367 "c-exp.y" -{ write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type (yyvsp[-2].tval); - write_exp_elt_opcode (UNOP_CAST); ; - break;} -case 33: -#line 373 "c-exp.y" -{ ; - break;} -case 34: -#line 379 "c-exp.y" -{ write_exp_elt_opcode (BINOP_REPEAT); ; - break;} -case 35: -#line 383 "c-exp.y" -{ write_exp_elt_opcode (BINOP_MUL); ; - break;} -case 36: -#line 387 "c-exp.y" -{ write_exp_elt_opcode (BINOP_DIV); ; - break;} -case 37: -#line 391 "c-exp.y" -{ write_exp_elt_opcode (BINOP_REM); ; - break;} -case 38: -#line 395 "c-exp.y" -{ write_exp_elt_opcode (BINOP_ADD); ; - break;} -case 39: -#line 399 "c-exp.y" -{ write_exp_elt_opcode (BINOP_SUB); ; - break;} -case 40: -#line 403 "c-exp.y" -{ write_exp_elt_opcode (BINOP_LSH); ; - break;} -case 41: -#line 407 "c-exp.y" -{ write_exp_elt_opcode (BINOP_RSH); ; - break;} -case 42: -#line 411 "c-exp.y" -{ write_exp_elt_opcode (BINOP_EQUAL); ; - break;} -case 43: -#line 415 "c-exp.y" -{ write_exp_elt_opcode (BINOP_NOTEQUAL); ; - break;} -case 44: -#line 419 "c-exp.y" -{ write_exp_elt_opcode (BINOP_LEQ); ; - break;} -case 45: -#line 423 "c-exp.y" -{ write_exp_elt_opcode (BINOP_GEQ); ; - break;} -case 46: -#line 427 "c-exp.y" -{ write_exp_elt_opcode (BINOP_LESS); ; - break;} -case 47: -#line 431 "c-exp.y" -{ write_exp_elt_opcode (BINOP_GTR); ; - break;} -case 48: -#line 435 "c-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_AND); ; - break;} -case 49: -#line 439 "c-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_XOR); ; - break;} -case 50: -#line 443 "c-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_IOR); ; - break;} -case 51: -#line 447 "c-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ; - break;} -case 52: -#line 451 "c-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ; - break;} -case 53: -#line 455 "c-exp.y" -{ write_exp_elt_opcode (TERNOP_COND); ; - break;} -case 54: -#line 459 "c-exp.y" -{ write_exp_elt_opcode (BINOP_ASSIGN); ; - break;} -case 55: -#line 463 "c-exp.y" -{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode (yyvsp[-1].opcode); - write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); ; - break;} -case 56: -#line 469 "c-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (yyvsp[0].typed_val_int.type); - write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val)); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 57: -#line 476 "c-exp.y" -{ YYSTYPE val; - parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (val.typed_val_int.type); - write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); - write_exp_elt_opcode (OP_LONG); - ; - break;} -case 58: -#line 487 "c-exp.y" -{ write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (yyvsp[0].typed_val_float.type); - write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval); - write_exp_elt_opcode (OP_DOUBLE); ; - break;} -case 61: -#line 501 "c-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_int); - CHECK_TYPEDEF (yyvsp[-1].tval); - write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 62: -#line 509 "c-exp.y" -{ /* C strings are converted into array constants with - an explicit null byte added at the end. Thus - the array upper bound is the string length. - There is no such thing in C as a completely empty - string. */ - char *sp = yyvsp[0].sval.ptr; int count = yyvsp[0].sval.length; - while (count-- > 0) - { - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_char); - write_exp_elt_longcst ((LONGEST)(*sp++)); - write_exp_elt_opcode (OP_LONG); - } - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_char); - write_exp_elt_longcst ((LONGEST)'\0'); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_opcode (OP_ARRAY); - write_exp_elt_longcst ((LONGEST) 0); - write_exp_elt_longcst ((LONGEST) (yyvsp[0].sval.length)); - write_exp_elt_opcode (OP_ARRAY); ; - break;} -case 63: -#line 534 "c-exp.y" -{ write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); ; - break;} -case 64: -#line 539 "c-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_bool); - write_exp_elt_longcst ((LONGEST) 1); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 65: -#line 546 "c-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_bool); - write_exp_elt_longcst ((LONGEST) 0); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 66: -#line 555 "c-exp.y" -{ - if (yyvsp[0].ssym.sym) - yyval.bval = SYMBOL_BLOCK_VALUE (yyvsp[0].ssym.sym); - else - error ("No file or function \"%s\".", - copy_name (yyvsp[0].ssym.stoken)); - ; - break;} -case 67: -#line 563 "c-exp.y" -{ - yyval.bval = yyvsp[0].bval; - ; - break;} -case 68: -#line 569 "c-exp.y" -{ struct symbol *tem - = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) - error ("No function \"%s\" in specified context.", - copy_name (yyvsp[0].sval)); - yyval.bval = SYMBOL_BLOCK_VALUE (tem); ; - break;} -case 69: -#line 580 "c-exp.y" -{ struct symbol *sym; - sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (sym == 0) - error ("No symbol \"%s\" in specified context.", - copy_name (yyvsp[0].sval)); - - write_exp_elt_opcode (OP_VAR_VALUE); - /* block_found is set by lookup_symbol. */ - write_exp_elt_block (block_found); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); ; - break;} -case 70: -#line 596 "c-exp.y" -{ - struct type *type = yyvsp[-2].tval; - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) - error ("`%s' is not defined as an aggregate type.", - TYPE_NAME (type)); - - write_exp_elt_opcode (OP_SCOPE); - write_exp_elt_type (type); - write_exp_string (yyvsp[0].sval); - write_exp_elt_opcode (OP_SCOPE); - ; - break;} -case 71: -#line 609 "c-exp.y" -{ - struct type *type = yyvsp[-3].tval; - struct stoken tmp_token; - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) - error ("`%s' is not defined as an aggregate type.", - TYPE_NAME (type)); - - tmp_token.ptr = (char*) alloca (yyvsp[0].sval.length + 2); - tmp_token.length = yyvsp[0].sval.length + 1; - tmp_token.ptr[0] = '~'; - memcpy (tmp_token.ptr+1, yyvsp[0].sval.ptr, yyvsp[0].sval.length); - tmp_token.ptr[tmp_token.length] = 0; - - /* Check for valid destructor name. */ - destructor_name_p (tmp_token.ptr, type); - write_exp_elt_opcode (OP_SCOPE); - write_exp_elt_type (type); - write_exp_string (tmp_token); - write_exp_elt_opcode (OP_SCOPE); - ; - break;} -case 73: -#line 634 "c-exp.y" -{ - char *name = copy_name (yyvsp[0].sval); - struct symbol *sym; - struct minimal_symbol *msymbol; - - sym = - lookup_symbol (name, (const struct block *) NULL, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (sym) - { - write_exp_elt_opcode (OP_VAR_VALUE); - write_exp_elt_block (NULL); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); - break; - } - - msymbol = lookup_minimal_symbol (name, NULL, NULL); - if (msymbol != NULL) - { - write_exp_msymbol (msymbol, - lookup_function_type (builtin_type_int), - builtin_type_int); - } - else - if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); - else - error ("No symbol \"%s\" in current context.", name); - ; - break;} -case 74: -#line 668 "c-exp.y" -{ struct symbol *sym = yyvsp[0].ssym.sym; - - if (sym) - { - if (symbol_read_needs_frame (sym)) - { - if (innermost_block == 0 || - contained_in (block_found, - innermost_block)) - innermost_block = block_found; - } - - write_exp_elt_opcode (OP_VAR_VALUE); - /* We want to use the selected frame, not - another more inner frame which happens to - be in the same block. */ - write_exp_elt_block (NULL); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); - } - else if (yyvsp[0].ssym.is_a_field_of_this) - { - /* C++: it hangs off of `this'. Must - not inadvertently convert from a method call - to data ref. */ - if (innermost_block == 0 || - contained_in (block_found, innermost_block)) - innermost_block = block_found; - write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (STRUCTOP_PTR); - write_exp_string (yyvsp[0].ssym.stoken); - write_exp_elt_opcode (STRUCTOP_PTR); - } - else - { - struct minimal_symbol *msymbol; - register char *arg = copy_name (yyvsp[0].ssym.stoken); - - msymbol = - lookup_minimal_symbol (arg, NULL, NULL); - if (msymbol != NULL) - { - write_exp_msymbol (msymbol, - lookup_function_type (builtin_type_int), - builtin_type_int); - } - else if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); - else - error ("No symbol \"%s\" in current context.", - copy_name (yyvsp[0].ssym.stoken)); - } - ; - break;} -case 78: -#line 734 "c-exp.y" -{ yyval.tval = follow_types (yyvsp[-1].tval); ; - break;} -case 79: -#line 736 "c-exp.y" -{ yyval.tval = follow_types (yyvsp[-2].tval); ; - break;} -case 80: -#line 738 "c-exp.y" -{ yyval.tval = follow_types (yyvsp[-2].tval); ; - break;} -case 81: -#line 742 "c-exp.y" -{ push_type (tp_pointer); yyval.voidval = 0; ; - break;} -case 82: -#line 744 "c-exp.y" -{ push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; ; - break;} -case 83: -#line 746 "c-exp.y" -{ push_type (tp_reference); yyval.voidval = 0; ; - break;} -case 84: -#line 748 "c-exp.y" -{ push_type (tp_reference); yyval.voidval = yyvsp[0].voidval; ; - break;} -case 86: -#line 753 "c-exp.y" -{ yyval.voidval = yyvsp[-1].voidval; ; - break;} -case 87: -#line 755 "c-exp.y" -{ - push_type_int (yyvsp[0].lval); - push_type (tp_array); - ; - break;} -case 88: -#line 760 "c-exp.y" -{ - push_type_int (yyvsp[0].lval); - push_type (tp_array); - yyval.voidval = 0; - ; - break;} -case 89: -#line 767 "c-exp.y" -{ push_type (tp_function); ; - break;} -case 90: -#line 769 "c-exp.y" -{ push_type (tp_function); ; - break;} -case 91: -#line 773 "c-exp.y" -{ yyval.lval = -1; ; - break;} -case 92: -#line 775 "c-exp.y" -{ yyval.lval = yyvsp[-1].typed_val_int.val; ; - break;} -case 93: -#line 779 "c-exp.y" -{ yyval.voidval = 0; ; - break;} -case 94: -#line 781 "c-exp.y" -{ free ((PTR)yyvsp[-1].tvec); yyval.voidval = 0; ; - break;} -case 96: -#line 794 "c-exp.y" -{ yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); ; - break;} -case 97: -#line 799 "c-exp.y" -{ yyval.tval = yyvsp[0].tsym.type; ; - break;} -case 98: -#line 801 "c-exp.y" -{ yyval.tval = builtin_type_int; ; - break;} -case 99: -#line 803 "c-exp.y" -{ yyval.tval = builtin_type_long; ; - break;} -case 100: -#line 805 "c-exp.y" -{ yyval.tval = builtin_type_short; ; - break;} -case 101: -#line 807 "c-exp.y" -{ yyval.tval = builtin_type_long; ; - break;} -case 102: -#line 809 "c-exp.y" -{ yyval.tval = builtin_type_unsigned_long; ; - break;} -case 103: -#line 811 "c-exp.y" -{ yyval.tval = builtin_type_long_long; ; - break;} -case 104: -#line 813 "c-exp.y" -{ yyval.tval = builtin_type_long_long; ; - break;} -case 105: -#line 815 "c-exp.y" -{ yyval.tval = builtin_type_unsigned_long_long; ; - break;} -case 106: -#line 817 "c-exp.y" -{ yyval.tval = builtin_type_unsigned_long_long; ; - break;} -case 107: -#line 819 "c-exp.y" -{ yyval.tval = builtin_type_short; ; - break;} -case 108: -#line 821 "c-exp.y" -{ yyval.tval = builtin_type_unsigned_short; ; - break;} -case 109: -#line 823 "c-exp.y" -{ yyval.tval = builtin_type_double; ; - break;} -case 110: -#line 825 "c-exp.y" -{ yyval.tval = builtin_type_long_double; ; - break;} -case 111: -#line 827 "c-exp.y" -{ yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), - expression_context_block); ; - break;} -case 112: -#line 830 "c-exp.y" -{ yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), - expression_context_block); ; - break;} -case 113: -#line 833 "c-exp.y" -{ yyval.tval = lookup_union (copy_name (yyvsp[0].sval), - expression_context_block); ; - break;} -case 114: -#line 836 "c-exp.y" -{ yyval.tval = lookup_enum (copy_name (yyvsp[0].sval), - expression_context_block); ; - break;} -case 115: -#line 839 "c-exp.y" -{ yyval.tval = lookup_unsigned_typename (TYPE_NAME(yyvsp[0].tsym.type)); ; - break;} -case 116: -#line 841 "c-exp.y" -{ yyval.tval = builtin_type_unsigned_int; ; - break;} -case 117: -#line 843 "c-exp.y" -{ yyval.tval = lookup_signed_typename (TYPE_NAME(yyvsp[0].tsym.type)); ; - break;} -case 118: -#line 845 "c-exp.y" -{ yyval.tval = builtin_type_int; ; - break;} -case 119: -#line 850 "c-exp.y" -{ yyval.tval = lookup_template_type(copy_name(yyvsp[-3].sval), yyvsp[-1].tval, - expression_context_block); - ; - break;} -case 120: -#line 856 "c-exp.y" -{ yyval.tval = yyvsp[0].tval; ; - break;} -case 121: -#line 857 "c-exp.y" -{ yyval.tval = yyvsp[0].tval; ; - break;} -case 123: -#line 862 "c-exp.y" -{ - yyval.tsym.stoken.ptr = "int"; - yyval.tsym.stoken.length = 3; - yyval.tsym.type = builtin_type_int; - ; - break;} -case 124: -#line 868 "c-exp.y" -{ - yyval.tsym.stoken.ptr = "long"; - yyval.tsym.stoken.length = 4; - yyval.tsym.type = builtin_type_long; - ; - break;} -case 125: -#line 874 "c-exp.y" -{ - yyval.tsym.stoken.ptr = "short"; - yyval.tsym.stoken.length = 5; - yyval.tsym.type = builtin_type_short; - ; - break;} -case 126: -#line 883 "c-exp.y" -{ yyval.tvec = (struct type **) xmalloc (sizeof (struct type *) * 2); - yyval.ivec[0] = 1; /* Number of types in vector */ - yyval.tvec[1] = yyvsp[0].tval; - ; - break;} -case 127: -#line 888 "c-exp.y" -{ int len = sizeof (struct type *) * (++(yyvsp[-2].ivec[0]) + 1); - yyval.tvec = (struct type **) xrealloc ((char *) yyvsp[-2].tvec, len); - yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval; - ; - break;} -case 128: -#line 894 "c-exp.y" -{ yyval.sval = yyvsp[0].ssym.stoken; ; - break;} -case 129: -#line 895 "c-exp.y" -{ yyval.sval = yyvsp[0].ssym.stoken; ; - break;} -case 130: -#line 896 "c-exp.y" -{ yyval.sval = yyvsp[0].tsym.stoken; ; - break;} -case 131: -#line 897 "c-exp.y" -{ yyval.sval = yyvsp[0].ssym.stoken; ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 542 "/usr/lib/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) xmalloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} -#line 911 "c-exp.y" - - -/* Take care of parsing a number (anything that starts with a digit). - Set yylval and return the token type; update lexptr. - LEN is the number of characters in it. */ - -/*** Needs some error checking for the float case ***/ - -static int -parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; - int parsed_float; - YYSTYPE *putithere; -{ - /* FIXME: Shouldn't these be unsigned? We don't deal with negative values - here, and we do kind of silly things like cast to unsigned. */ - register LONGEST n = 0; - register LONGEST prevn = 0; - ULONGEST un; - - register int i = 0; - register int c; - register int base = input_radix; - int unsigned_p = 0; - - /* Number of "L" suffixes encountered. */ - int long_p = 0; - - /* We have found a "L" or "U" suffix. */ - int found_suffix = 0; - - ULONGEST high_bit; - struct type *signed_type; - struct type *unsigned_type; - - if (parsed_float) - { - /* It's a float since it contains a point or an exponent. */ - char c; - int num = 0; /* number of tokens scanned by scanf */ - char saved_char = p[len]; - - p[len] = 0; /* null-terminate the token */ - if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) - num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c); - else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) - num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c); - else - { -#ifdef SCANF_HAS_LONG_DOUBLE - num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c); -#else - /* Scan it into a double, then assign it to the long double. - This at least wins with values representable in the range - of doubles. */ - double temp; - num = sscanf (p, "%lg%c", &temp,&c); - putithere->typed_val_float.dval = temp; -#endif - } - p[len] = saved_char; /* restore the input stream */ - if (num != 1) /* check scanf found ONLY a float ... */ - return ERROR; - /* See if it has `f' or `l' suffix (float or long double). */ - - c = tolower (p[len - 1]); - - if (c == 'f') - putithere->typed_val_float.type = builtin_type_float; - else if (c == 'l') - putithere->typed_val_float.type = builtin_type_long_double; - else if (isdigit (c) || c == '.') - putithere->typed_val_float.type = builtin_type_double; - else - return ERROR; - - return FLOAT; - } - - /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ - if (p[0] == '0') - switch (p[1]) - { - case 'x': - case 'X': - if (len >= 3) - { - p += 2; - base = 16; - len -= 2; - } - break; - - case 't': - case 'T': - case 'd': - case 'D': - if (len >= 3) - { - p += 2; - base = 10; - len -= 2; - } - break; - - default: - base = 8; - break; - } - - while (len-- > 0) - { - c = *p++; - if (c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != 'l' && c != 'u') - n *= base; - if (c >= '0' && c <= '9') - { - if (found_suffix) - return ERROR; - n += i = c - '0'; - } - else - { - if (base > 10 && c >= 'a' && c <= 'f') - { - if (found_suffix) - return ERROR; - n += i = c - 'a' + 10; - } - else if (c == 'l') - { - ++long_p; - found_suffix = 1; - } - else if (c == 'u') - { - unsigned_p = 1; - found_suffix = 1; - } - else - return ERROR; /* Char not a digit */ - } - if (i >= base) - return ERROR; /* Invalid digit in this base */ - - /* Portably test for overflow (only works for nonzero values, so make - a second check for zero). FIXME: Can't we just make n and prevn - unsigned and avoid this? */ - if (c != 'l' && c != 'u' && (prevn >= n) && n != 0) - unsigned_p = 1; /* Try something unsigned */ - - /* Portably test for unsigned overflow. - FIXME: This check is wrong; for example it doesn't find overflow - on 0x123456789 when LONGEST is 32 bits. */ - if (c != 'l' && c != 'u' && n != 0) - { - if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n)) - error ("Numeric constant too large."); - } - prevn = n; - } - - /* An integer constant is an int, a long, or a long long. An L - suffix forces it to be long; an LL suffix forces it to be long - long. If not forced to a larger size, it gets the first type of - the above that it fits in. To figure out whether it fits, we - shift it right and see whether anything remains. Note that we - can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one - operation, because many compilers will warn about such a shift - (which always produces a zero result). Sometimes TARGET_INT_BIT - or TARGET_LONG_BIT will be that big, sometimes not. To deal with - the case where it is we just always shift the value more than - once, with fewer bits each time. */ - - un = (ULONGEST)n >> 2; - if (long_p == 0 - && (un >> (TARGET_INT_BIT - 2)) == 0) - { - high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1); - - /* A large decimal (not hex or octal) constant (between INT_MAX - and UINT_MAX) is a long or unsigned long, according to ANSI, - never an unsigned int, but this code treats it as unsigned - int. This probably should be fixed. GCC gives a warning on - such constants. */ - - unsigned_type = builtin_type_unsigned_int; - signed_type = builtin_type_int; - } - else if (long_p <= 1 - && (un >> (TARGET_LONG_BIT - 2)) == 0) - { - high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1); - unsigned_type = builtin_type_unsigned_long; - signed_type = builtin_type_long; - } - else - { - int shift; - if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT) - /* A long long does not fit in a LONGEST. */ - shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1); - else - shift = (TARGET_LONG_LONG_BIT - 1); - high_bit = (ULONGEST) 1 << shift; - unsigned_type = builtin_type_unsigned_long_long; - signed_type = builtin_type_long_long; - } - - putithere->typed_val_int.val = n; - - /* If the high bit of the worked out type is set then this number - has to be unsigned. */ - - if (unsigned_p || (n & high_bit)) - { - putithere->typed_val_int.type = unsigned_type; - } - else - { - putithere->typed_val_int.type = signed_type; - } - - return INT; -} - -struct token -{ - char *operator; - int token; - enum exp_opcode opcode; -}; - -static const struct token tokentab3[] = - { - {">>=", ASSIGN_MODIFY, BINOP_RSH}, - {"<<=", ASSIGN_MODIFY, BINOP_LSH} - }; - -static const struct token tokentab2[] = - { - {"+=", ASSIGN_MODIFY, BINOP_ADD}, - {"-=", ASSIGN_MODIFY, BINOP_SUB}, - {"*=", ASSIGN_MODIFY, BINOP_MUL}, - {"/=", ASSIGN_MODIFY, BINOP_DIV}, - {"%=", ASSIGN_MODIFY, BINOP_REM}, - {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR}, - {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND}, - {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR}, - {"++", INCREMENT, BINOP_END}, - {"--", DECREMENT, BINOP_END}, - {"->", ARROW, BINOP_END}, - {"&&", ANDAND, BINOP_END}, - {"||", OROR, BINOP_END}, - {"::", COLONCOLON, BINOP_END}, - {"<<", LSH, BINOP_END}, - {">>", RSH, BINOP_END}, - {"==", EQUAL, BINOP_END}, - {"!=", NOTEQUAL, BINOP_END}, - {"<=", LEQ, BINOP_END}, - {">=", GEQ, BINOP_END} - }; - -/* Read one token, getting characters through lexptr. */ - -static int -yylex () -{ - int c; - int namelen; - unsigned int i; - char *tokstart; - char *tokptr; - int tempbufindex; - static char *tempbuf; - static int tempbufsize; - struct symbol * sym_class = NULL; - char * token_string = NULL; - int class_prefix = 0; - int unquoted_expr; - - retry: - - unquoted_expr = 1; - - tokstart = lexptr; - /* See if it is a special token of length 3. */ - for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) - if (STREQN (tokstart, tokentab3[i].operator, 3)) - { - lexptr += 3; - yylval.opcode = tokentab3[i].opcode; - return tokentab3[i].token; - } - - /* See if it is a special token of length 2. */ - for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) - if (STREQN (tokstart, tokentab2[i].operator, 2)) - { - lexptr += 2; - yylval.opcode = tokentab2[i].opcode; - return tokentab2[i].token; - } - - switch (c = *tokstart) - { - case 0: - return 0; - - case ' ': - case '\t': - case '\n': - lexptr++; - goto retry; - - case '\'': - /* We either have a character constant ('0' or '\177' for example) - or we have a quoted symbol reference ('foo(int,int)' in C++ - for example). */ - lexptr++; - c = *lexptr++; - if (c == '\\') - c = parse_escape (&lexptr); - else if (c == '\'') - error ("Empty character constant."); - - yylval.typed_val_int.val = c; - yylval.typed_val_int.type = builtin_type_char; - - c = *lexptr++; - if (c != '\'') - { - namelen = skip_quoted (tokstart) - tokstart; - if (namelen > 2) - { - lexptr = tokstart + namelen; - unquoted_expr = 0; - if (lexptr[-1] != '\'') - error ("Unmatched single quote."); - namelen -= 2; - tokstart++; - goto tryname; - } - error ("Invalid character constant."); - } - return INT; - - case '(': - paren_depth++; - lexptr++; - return c; - - case ')': - if (paren_depth == 0) - return 0; - paren_depth--; - lexptr++; - return c; - - case ',': - if (comma_terminates && paren_depth == 0) - return 0; - lexptr++; - return c; - - case '.': - /* Might be a floating point number. */ - if (lexptr[1] < '0' || lexptr[1] > '9') - goto symbol; /* Nope, must be a symbol. */ - /* FALL THRU into number case. */ - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - /* It's a number. */ - int got_dot = 0, got_e = 0, toktype; - register char *p = tokstart; - int hex = input_radix > 10; - - if (c == '0' && (p[1] == 'x' || p[1] == 'X')) - { - p += 2; - hex = 1; - } - else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) - { - p += 2; - hex = 0; - } - - for (;; ++p) - { - /* This test includes !hex because 'e' is a valid hex digit - and thus does not indicate a floating point number when - the radix is hex. */ - if (!hex && !got_e && (*p == 'e' || *p == 'E')) - got_dot = got_e = 1; - /* This test does not include !hex, because a '.' always indicates - a decimal floating point number regardless of the radix. */ - else if (!got_dot && *p == '.') - got_dot = 1; - else if (got_e && (p[-1] == 'e' || p[-1] == 'E') - && (*p == '-' || *p == '+')) - /* This is the sign of the exponent, not the end of the - number. */ - continue; - /* We will take any letters or digits. parse_number will - complain if past the radix, or if L or U are not final. */ - else if ((*p < '0' || *p > '9') - && ((*p < 'a' || *p > 'z') - && (*p < 'A' || *p > 'Z'))) - break; - } - toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval); - if (toktype == ERROR) - { - char *err_copy = (char *) alloca (p - tokstart + 1); - - memcpy (err_copy, tokstart, p - tokstart); - err_copy[p - tokstart] = 0; - error ("Invalid number \"%s\".", err_copy); - } - lexptr = p; - return toktype; - } - - case '+': - case '-': - case '*': - case '/': - case '%': - case '|': - case '&': - case '^': - case '~': - case '!': - case '@': - case '<': - case '>': - case '[': - case ']': - case '?': - case ':': - case '=': - case '{': - case '}': - symbol: - lexptr++; - return c; - - case '"': - - /* Build the gdb internal form of the input string in tempbuf, - translating any standard C escape forms seen. Note that the - buffer is null byte terminated *only* for the convenience of - debugging gdb itself and printing the buffer contents when - the buffer contains no embedded nulls. Gdb does not depend - upon the buffer being null byte terminated, it uses the length - string instead. This allows gdb to handle C strings (as well - as strings in other languages) with embedded null bytes */ - - tokptr = ++tokstart; - tempbufindex = 0; - - do { - /* Grow the static temp buffer if necessary, including allocating - the first one on demand. */ - if (tempbufindex + 1 >= tempbufsize) - { - tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64); - } - switch (*tokptr) - { - case '\0': - case '"': - /* Do nothing, loop will terminate. */ - break; - case '\\': - tokptr++; - c = parse_escape (&tokptr); - if (c == -1) - { - continue; - } - tempbuf[tempbufindex++] = c; - break; - default: - tempbuf[tempbufindex++] = *tokptr++; - break; - } - } while ((*tokptr != '"') && (*tokptr != '\0')); - if (*tokptr++ != '"') - { - error ("Unterminated string in expression."); - } - tempbuf[tempbufindex] = '\0'; /* See note above */ - yylval.sval.ptr = tempbuf; - yylval.sval.length = tempbufindex; - lexptr = tokptr; - return (STRING); - } - - if (!(c == '_' || c == '$' - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) - /* We must have come across a bad character (e.g. ';'). */ - error ("Invalid character '%c' in expression.", c); - - /* It's a name. See how long it is. */ - namelen = 0; - for (c = tokstart[namelen]; - (c == '_' || c == '$' || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) - { - /* Template parameter lists are part of the name. - FIXME: This mishandles `print $a<4&&$a>3'. */ - - if (c == '<') - { - if (hp_som_som_object_present) - { - /* Scan ahead to get rest of the template specification. Note - that we look ahead only when the '<' adjoins non-whitespace - characters; for comparison expressions, e.g. "a < b > c", - there must be spaces before the '<', etc. */ - - char * p = find_template_name_end (tokstart + namelen); - if (p) - namelen = p - tokstart; - break; - } - else - { - int i = namelen; - int nesting_level = 1; - while (tokstart[++i]) - { - if (tokstart[i] == '<') - nesting_level++; - else if (tokstart[i] == '>') - { - if (--nesting_level == 0) - break; - } - } - if (tokstart[i] == '>') - namelen = i; - else - break; - } - } - c = tokstart[++namelen]; - } - - /* The token "if" terminates the expression and is NOT - removed from the input stream. */ - if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') - { - return 0; - } - - lexptr += namelen; - - tryname: - - /* Catch specific keywords. Should be done with a data structure. */ - switch (namelen) - { - case 8: - if (STREQN (tokstart, "unsigned", 8)) - return UNSIGNED; - if (current_language->la_language == language_cplus - && STREQN (tokstart, "template", 8)) - return TEMPLATE; - if (STREQN (tokstart, "volatile", 8)) - return VOLATILE_KEYWORD; - break; - case 6: - if (STREQN (tokstart, "struct", 6)) - return STRUCT; - if (STREQN (tokstart, "signed", 6)) - return SIGNED_KEYWORD; - if (STREQN (tokstart, "sizeof", 6)) - return SIZEOF; - if (STREQN (tokstart, "double", 6)) - return DOUBLE_KEYWORD; - break; - case 5: - if (current_language->la_language == language_cplus) - { - if (STREQN (tokstart, "false", 5)) - return FALSEKEYWORD; - if (STREQN (tokstart, "class", 5)) - return CLASS; - } - if (STREQN (tokstart, "union", 5)) - return UNION; - if (STREQN (tokstart, "short", 5)) - return SHORT; - if (STREQN (tokstart, "const", 5)) - return CONST_KEYWORD; - break; - case 4: - if (STREQN (tokstart, "enum", 4)) - return ENUM; - if (STREQN (tokstart, "long", 4)) - return LONG; - if (current_language->la_language == language_cplus) - { - if (STREQN (tokstart, "true", 4)) - return TRUEKEYWORD; - - if (STREQN (tokstart, "this", 4)) - { - static const char this_name[] = - { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' }; - - if (lookup_symbol (this_name, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL)) - return THIS; - } - } - break; - case 3: - if (STREQN (tokstart, "int", 3)) - return INT_KEYWORD; - break; - default: - break; - } - - yylval.sval.ptr = tokstart; - yylval.sval.length = namelen; - - if (*tokstart == '$') - { - write_dollar_variable (yylval.sval); - return VARIABLE; - } - - /* Look ahead and see if we can consume more of the input - string to get a reasonable class/namespace spec or a - fully-qualified name. This is a kludge to get around the - HP aCC compiler's generation of symbol names with embedded - colons for namespace and nested classes. */ - if (unquoted_expr) - { - /* Only do it if not inside single quotes */ - sym_class = parse_nested_classes_for_hpacc (yylval.sval.ptr, yylval.sval.length, - &token_string, &class_prefix, &lexptr); - if (sym_class) - { - /* Replace the current token with the bigger one we found */ - yylval.sval.ptr = token_string; - yylval.sval.length = strlen (token_string); - } - } - - /* Use token-type BLOCKNAME for symbols that happen to be defined as - functions or symtabs. If this is not so, then ... - Use token-type TYPENAME for symbols that happen to be defined - currently as names of types; NAME for other symbols. - The caller is not constrained to care about the distinction. */ - { - char *tmp = copy_name (yylval.sval); - struct symbol *sym; - int is_a_field_of_this = 0; - int hextype; - - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, - current_language->la_language == language_cplus - ? &is_a_field_of_this : (int *) NULL, - (struct symtab **) NULL); - /* Call lookup_symtab, not lookup_partial_symtab, in case there are - no psymtabs (coff, xcoff, or some future change to blow away the - psymtabs once once symbols are read). */ - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) - { - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return BLOCKNAME; - } - else if (!sym) - { /* See if it's a file name. */ - struct symtab *symtab; - - symtab = lookup_symtab (tmp); - - if (symtab) - { - yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); - return FILENAME; - } - } - - if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) - { -#if 1 - /* Despite the following flaw, we need to keep this code enabled. - Because we can get called from check_stub_method, if we don't - handle nested types then it screws many operations in any - program which uses nested types. */ - /* In "A::x", if x is a member function of A and there happens - to be a type (nested or not, since the stabs don't make that - distinction) named x, then this code incorrectly thinks we - are dealing with nested types rather than a member function. */ - - char *p; - char *namestart; - struct symbol *best_sym; - - /* Look ahead to detect nested types. This probably should be - done in the grammar, but trying seemed to introduce a lot - of shift/reduce and reduce/reduce conflicts. It's possible - that it could be done, though. Or perhaps a non-grammar, but - less ad hoc, approach would work well. */ - - /* Since we do not currently have any way of distinguishing - a nested type from a non-nested one (the stabs don't tell - us whether a type is nested), we just ignore the - containing type. */ - - p = lexptr; - best_sym = sym; - while (1) - { - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - if (*p == ':' && p[1] == ':') - { - /* Skip the `::'. */ - p += 2; - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - namestart = p; - while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9') - || (*p >= 'a' && *p <= 'z') - || (*p >= 'A' && *p <= 'Z')) - ++p; - if (p != namestart) - { - struct symbol *cur_sym; - /* As big as the whole rest of the expression, which is - at least big enough. */ - char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3); - char *tmp1; - - tmp1 = ncopy; - memcpy (tmp1, tmp, strlen (tmp)); - tmp1 += strlen (tmp); - memcpy (tmp1, "::", 2); - tmp1 += 2; - memcpy (tmp1, namestart, p - namestart); - tmp1[p - namestart] = '\0'; - cur_sym = lookup_symbol (ncopy, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (cur_sym) - { - if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) - { - best_sym = cur_sym; - lexptr = p; - } - else - break; - } - else - break; - } - else - break; - } - else - break; - } - - yylval.tsym.type = SYMBOL_TYPE (best_sym); -#else /* not 0 */ - yylval.tsym.type = SYMBOL_TYPE (sym); -#endif /* not 0 */ - return TYPENAME; - } - if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) - return TYPENAME; - - /* Input names that aren't symbols but ARE valid hex numbers, - when the input radix permits them, can be names or numbers - depending on the parse. Note we support radixes > 16 here. */ - if (!sym && - ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || - (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) - { - YYSTYPE newlval; /* Its value is ignored. */ - hextype = parse_number (tokstart, namelen, 0, &newlval); - if (hextype == INT) - { - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return NAME_OR_INT; - } - } - - /* Any other kind of symbol */ - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return NAME; - } -} - -void -yyerror (msg) - char *msg; -{ - error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); -} diff --git a/contrib/gdb/gdb/callback.c b/contrib/gdb/gdb/callback.c deleted file mode 100644 index d59ecdabd7a..00000000000 --- a/contrib/gdb/gdb/callback.c +++ /dev/null @@ -1,349 +0,0 @@ -/* Host callback routines for GDB. - Copyright 1995 Free Software Foundation, Inc. - Contributed by Cygnus Support. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file provides a standard way for targets to talk to the host OS - level. - - This interface will probably need a bit more banging to make it - smooth. Currently the simulator uses this file to provide the - callbacks for itself when it's built standalone, which is rather - ugly. */ - -#ifndef INSIDE_SIMULATOR -#include "defs.h" -#endif - -#include "ansidecl.h" -#include "callback.h" -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - -#include -#include -#include -#include - - - -/* Set the callback copy of errno from what we see now. */ -static int -wrap (p, val) - host_callback *p; - int val; -{ - p->last_errno = errno; - return val; -} - -/* Make sure the FD provided is ok. If not, return non-zero - and set errno. */ - -static int -fdbad (p, fd) - host_callback *p; - int fd; -{ - if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd]) - { - p->last_errno = EINVAL; - return -1; - } - return 0; -} - -static int -fdmap (p, fd) - host_callback *p; - int fd; -{ - return p->fdmap[fd]; -} - -int -os_close (p, fd) - host_callback *p; - int fd; -{ - int result; - - result = fdbad (p, fd); - if (result) - return result; - result = wrap (p, close (fdmap (p, fd))); - return result; -} - -int -os_get_errno (p) - host_callback *p; -{ - /* !!! fixme, translate from host to taget errno value */ - return p->last_errno; -} - - -int -os_isatty (p, fd) - host_callback *p; - int fd; -{ - int result; - - result = fdbad (p, fd); - if (result) - return result; - result = wrap (p, isatty (fdmap (fd))); - return result; -} - -int -os_lseek (p, fd, off, way) - host_callback *p; - int fd; - long off; - int way; -{ - int result; - - result = fdbad (p, fd); - if (result) - return result; - result = lseek (fdmap (p, fd), off, way); - return result; -} - -int -os_open (p, name, flags) - host_callback *p; - const char *name; - int flags; -{ - int i; - for (i = 0; i < MAX_CALLBACK_FDS; i++) - { - if (!p->fdopen[i]) - { - int f = open (name, flags); - if (f < 0) - { - p->last_errno = errno; - return f; - } - p->fdopen[i] = 1; - p->fdmap[i] = f; - return i; - } - } - p->last_errno = EMFILE; - return -1; -} - -int -os_read (p, fd, buf, len) - host_callback *p; - int fd; - char *buf; - int len; -{ - int result; - - result = fdbad (p, fd); - if (result) - return result; - result = wrap (p, read (fdmap (p, fd), buf, len)); - return result; -} - -int -os_read_stdin (p, buf, len) - host_callback *p; - char *buf; - int len; -{ - return wrap (p, read (0, buf, len)); -} - -int -os_write (p, fd, buf, len) - host_callback *p; - int fd; - const char *buf; - int len; -{ - int result; - - result = fdbad (p, fd); - if (result) - return result; - result = wrap (p, write (fdmap (p, fd), buf, len)); - return result; -} - -/* ignore the grossness of INSIDE_SIMULATOR, it will go away one day. */ -int -os_write_stdout (p, buf, len) - host_callback *p; - const char *buf; - int len; -{ -#ifdef INSIDE_SIMULATOR - return os_write (p, 1, buf, len); -#else - int i; - char b[2]; - for (i = 0; i< len; i++) - { - b[0] = buf[i]; - b[1] = 0; - if (target_output_hook) - target_output_hook (b); - else - fputs_filtered (b, gdb_stdout); - } - return len; -#endif -} - -int -os_rename (p, f1, f2) - host_callback *p; - const char *f1; - const char *f2; -{ - return wrap (p, rename (f1, f2)); -} - - -int -os_system (p, s) - host_callback *p; - const char *s; -{ - return wrap (p, system (s)); -} - -long -os_time (p, t) - host_callback *p; - long *t; -{ - return wrap (p, time (t)); -} - - -int -os_unlink (p, f1) - host_callback *p; - const char *f1; -{ - return wrap (p, unlink (f1)); -} - - -int -os_shutdown (p) -host_callback *p; -{ - int i; - for (i = 0; i < MAX_CALLBACK_FDS; i++) - { - if (p->fdopen[i] && !p->alwaysopen[i]) { - close (p->fdmap[i]); - p->fdopen[i] = 0; - } - } - return 1; -} - -int os_init(p) -host_callback *p; -{ - int i; - os_shutdown (p); - for (i= 0; i < 3; i++) - { - p->fdmap[i] = i; - p->fdopen[i] = 1; - p->alwaysopen[i] = 1; - } - return 1; -} - - -/* !!fixme!! - This bit is ugly. When the interface has settled down I'll - move the whole file into sim/common and remove this bit. */ - -/* VARARGS */ -void -#ifdef ANSI_PROTOTYPES -os_printf_filtered (host_callback *p, const char *format, ...) -#else -os_printf_filtered (p, va_alist) - host_callback *p; - va_dcl -#endif -{ - va_list args; -#ifdef ANSI_PROTOTYPES - va_start (args, format); -#else - char *format; - - va_start (args); - format = va_arg (args, char *); -#endif - -#ifdef INSIDE_SIMULATOR - vprintf (format, args); -#else - vfprintf_filtered (stdout, format, args); -#endif - - va_end (args); -} - -host_callback default_callback = -{ - os_close, - os_get_errno, - os_isatty, - os_lseek, - os_open, - os_read, - os_read_stdin, - os_rename, - os_system, - os_time, - os_unlink, - os_write, - os_write_stdout, - - os_shutdown, - os_init, - - os_printf_filtered, - - 0, /* last errno */ -}; diff --git a/contrib/gdb/gdb/callback.h b/contrib/gdb/gdb/callback.h deleted file mode 100644 index b97c3b2ce81..00000000000 --- a/contrib/gdb/gdb/callback.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef CALLBACK_H -#define CALLBACK_H -typedef struct host_callback_struct host_callback; - -#define MAX_CALLBACK_FDS 10 - -struct host_callback_struct -{ - int (*close) PARAMS ((host_callback *,int)); - int (*get_errno) PARAMS ((host_callback *)); - int (*isatty) PARAMS ((host_callback *, int)); - int (*lseek) PARAMS ((host_callback *, int, long , int)); - int (*open) PARAMS ((host_callback *, const char*, int mode)); - int (*read) PARAMS ((host_callback *,int, char *, int)); - int (*read_stdin) PARAMS (( host_callback *, char *, int)); - int (*rename) PARAMS ((host_callback *, const char *, const char *)); - int (*system) PARAMS ((host_callback *, const char *)); - long (*time) PARAMS ((host_callback *, long *)); - int (*unlink) PARAMS ((host_callback *, const char *)); - int (*write) PARAMS ((host_callback *,int, const char *, int)); - int (*write_stdout) PARAMS ((host_callback *, const char *, int)); - - - /* Used when the target has gone away, so we can close open - handles and free memory etc etc. */ - int (*shutdown) PARAMS ((host_callback *)); - int (*init) PARAMS ((host_callback *)); - - /* Talk to the user on a console. */ - void (*printf_filtered) PARAMS ((host_callback *, const char *, ...)); - - int last_errno; /* host format */ - - int fdmap[MAX_CALLBACK_FDS]; - char fdopen[MAX_CALLBACK_FDS]; - char alwaysopen[MAX_CALLBACK_FDS]; -}; -#endif - - -extern host_callback default_callback; diff --git a/contrib/gdb/gdb/command.c b/contrib/gdb/gdb/command.c deleted file mode 100644 index 58af56701f5..00000000000 --- a/contrib/gdb/gdb/command.c +++ /dev/null @@ -1,1564 +0,0 @@ -/* Handle lists of commands, their decoding and documentation, for GDB. - Copyright 1986, 1989, 1990, 1991, 1998 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcmd.h" -#include "symtab.h" -#include "value.h" -#include -#include "gdb_string.h" -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_WAIT_H -# include -#else -# ifdef HAVE_SYS_WAIT_H -# include -# endif -#endif - -#include "wait.h" - -/* Prototypes for local functions */ - -static void undef_cmd_error PARAMS ((char *, char *)); - -static void show_user PARAMS ((char *, int)); - -static void show_user_1 PARAMS ((struct cmd_list_element *, GDB_FILE *)); - -static void make_command PARAMS ((char *, int)); - -static void shell_escape PARAMS ((char *, int)); - -static int parse_binary_operation PARAMS ((char *)); - -static void print_doc_line PARAMS ((GDB_FILE *, char *)); - -void _initialize_command PARAMS ((void)); - -/* Add element named NAME. - CLASS is the top level category into which commands are broken down - for "help" purposes. - FUN should be the function to execute the command; - it will get a character string as argument, with leading - and trailing blanks already eliminated. - - DOC is a documentation string for the command. - Its first line should be a complete sentence. - It should start with ? for a command that is an abbreviation - or with * for a command that most users don't need to know about. - - Add this command to command list *LIST. - - Returns a pointer to the added command (not necessarily the head - of *LIST). */ - -struct cmd_list_element * -add_cmd (name, class, fun, doc, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c - = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); - struct cmd_list_element *p; - - delete_cmd (name, list); - - if (*list == NULL || STRCMP ((*list)->name, name) >= 0) - { - c->next = *list; - *list = c; - } - else - { - p = *list; - while (p->next && STRCMP (p->next->name, name) <= 0) - { - p = p->next; - } - c->next = p->next; - p->next = c; - } - - c->name = name; - c->class = class; - c->function.cfunc = fun; - c->doc = doc; - c->hook = NULL; - c->prefixlist = NULL; - c->prefixname = NULL; - c->allow_unknown = 0; - c->abbrev_flag = 0; - c->completer = make_symbol_completion_list; - c->type = not_set_cmd; - c->var = NULL; - c->var_type = var_boolean; - c->enums = NULL; - c->user_commands = NULL; - c->hookee = NULL; - c->cmd_pointer = NULL; - - return c; -} - -/* Same as above, except that the abbrev_flag is set. */ - -#if 0 /* Currently unused */ - -struct cmd_list_element * -add_abbrev_cmd (name, class, fun, doc, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c - = add_cmd (name, class, fun, doc, list); - - c->abbrev_flag = 1; - return c; -} - -#endif - -struct cmd_list_element * -add_alias_cmd (name, oldname, class, abbrev_flag, list) - char *name; - char *oldname; - enum command_class class; - int abbrev_flag; - struct cmd_list_element **list; -{ - /* Must do this since lookup_cmd tries to side-effect its first arg */ - char *copied_name; - register struct cmd_list_element *old; - register struct cmd_list_element *c; - copied_name = (char *) alloca (strlen (oldname) + 1); - strcpy (copied_name, oldname); - old = lookup_cmd (&copied_name, *list, "", 1, 1); - - if (old == 0) - { - delete_cmd (name, list); - return 0; - } - - c = add_cmd (name, class, old->function.cfunc, old->doc, list); - c->prefixlist = old->prefixlist; - c->prefixname = old->prefixname; - c->allow_unknown = old->allow_unknown; - c->abbrev_flag = abbrev_flag; - c->cmd_pointer = old; - return c; -} - -/* Like add_cmd but adds an element for a command prefix: - a name that should be followed by a subcommand to be looked up - in another command list. PREFIXLIST should be the address - of the variable containing that list. */ - -struct cmd_list_element * -add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname, - allow_unknown, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **prefixlist; - char *prefixname; - int allow_unknown; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); - c->prefixlist = prefixlist; - c->prefixname = prefixname; - c->allow_unknown = allow_unknown; - return c; -} - -/* Like add_prefix_cmd but sets the abbrev_flag on the new command. */ - -struct cmd_list_element * -add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname, - allow_unknown, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **prefixlist; - char *prefixname; - int allow_unknown; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); - c->prefixlist = prefixlist; - c->prefixname = prefixname; - c->allow_unknown = allow_unknown; - c->abbrev_flag = 1; - return c; -} - -/* This is an empty "cfunc". */ -void -not_just_help_class_command (args, from_tty) - char *args; - int 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. - VAR_TYPE is the kind of thing we are setting. - VAR is address of the variable being controlled by this command. - DOC is the documentation string. */ - -struct cmd_list_element * -add_set_cmd (name, class, var_type, var, doc, list) - char *name; - enum command_class class; - var_types var_type; - char *var; - char *doc; - struct cmd_list_element **list; -{ - struct cmd_list_element *c - = 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; -} - -/* Add element named NAME to command list LIST (the list for set - or some sublist thereof). - CLASS is as in add_cmd. - ENUMLIST is a list of strings which may follow NAME. - VAR is address of the variable which will contain the matching string - (from ENUMLIST). - DOC is the documentation string. */ - -struct cmd_list_element * -add_set_enum_cmd (name, class, enumlist, var, doc, list) - char *name; - enum command_class class; - char *enumlist[]; - char *var; - char *doc; - struct cmd_list_element **list; -{ - struct cmd_list_element *c - = add_set_cmd (name, class, var_enum, var, doc, list); - c->enums = enumlist; - - return c; -} - -/* Where SETCMD has already been added, add the corresponding show - command to LIST and return a pointer to the added command (not - necessarily the head of LIST). */ -struct cmd_list_element * -add_show_from_set (setcmd, list) - struct cmd_list_element *setcmd; - struct cmd_list_element **list; -{ - struct cmd_list_element *showcmd = - (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); - struct cmd_list_element *p; - - memcpy (showcmd, setcmd, sizeof (struct cmd_list_element)); - delete_cmd (showcmd->name, list); - showcmd->type = show_cmd; - - /* Replace "set " at start of docstring with "show ". */ - if (setcmd->doc[0] == 'S' && setcmd->doc[1] == 'e' - && setcmd->doc[2] == 't' && setcmd->doc[3] == ' ') - showcmd->doc = concat ("Show ", setcmd->doc + 4, NULL); - else - fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n"); - - if (*list == NULL || STRCMP ((*list)->name, showcmd->name) >= 0) - { - showcmd->next = *list; - *list = showcmd; - } - else - { - p = *list; - while (p->next && STRCMP (p->next->name, showcmd->name) <= 0) - { - p = p->next; - } - showcmd->next = p->next; - p->next = showcmd; - } - - return showcmd; -} - -/* Remove the command named NAME from the command list. */ - -void -delete_cmd (name, list) - char *name; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c; - struct cmd_list_element *p; - - while (*list && STREQ ((*list)->name, name)) - { - if ((*list)->hookee) - (*list)->hookee->hook = 0; /* Hook slips out of its mouth */ - p = (*list)->next; - free ((PTR)*list); - *list = p; - } - - if (*list) - for (c = *list; c->next;) - { - if (STREQ (c->next->name, name)) - { - if (c->next->hookee) - c->next->hookee->hook = 0; /* hooked cmd gets away. */ - p = c->next->next; - free ((PTR)c->next); - c->next = p; - } - else - c = c->next; - } -} - -/* This command really has to deal with two things: - * 1) I want documentation on *this string* (usually called by - * "help commandname"). - * 2) I want documentation on *this list* (usually called by - * giving a command that requires subcommands. Also called by saying - * just "help".) - * - * I am going to split this into two seperate comamnds, help_cmd and - * help_list. - */ - -void -help_cmd (command, stream) - char *command; - GDB_FILE *stream; -{ - struct cmd_list_element *c; - extern struct cmd_list_element *cmdlist; - - if (!command) - { - help_list (cmdlist, "", all_classes, stream); - return; - } - - c = lookup_cmd (&command, cmdlist, "", 0, 0); - - if (c == 0) - return; - - /* There are three cases here. - If c->prefixlist is nonzero, we have a prefix command. - Print its documentation, then list its subcommands. - - If c->function is nonzero, we really have a command. - Print its documentation and return. - - If c->function is zero, we have a class name. - Print its documentation (as if it were a command) - and then set class to the number of this class - so that the commands in the class will be listed. */ - - fputs_filtered (c->doc, stream); - fputs_filtered ("\n", stream); - - if (c->prefixlist == 0 && c->function.cfunc != NULL) - return; - fprintf_filtered (stream, "\n"); - - /* If this is a prefix command, print it's subcommands */ - if (c->prefixlist) - help_list (*c->prefixlist, c->prefixname, all_commands, stream); - - /* If this is a class name, print all of the commands in the class */ - if (c->function.cfunc == NULL) - help_list (cmdlist, "", c->class, stream); - - if (c->hook) - fprintf_filtered (stream, "\nThis command has a hook defined: %s\n", - c->hook->name); -} - -/* - * Get a specific kind of help on a command list. - * - * LIST is the list. - * CMDTYPE is the prefix to use in the title string. - * CLASS is the class with which to list the nodes of this list (see - * documentation for help_cmd_list below), As usual, ALL_COMMANDS for - * everything, ALL_CLASSES for just classes, and non-negative for only things - * in a specific class. - * and STREAM is the output stream on which to print things. - * If you call this routine with a class >= 0, it recurses. - */ -void -help_list (list, cmdtype, class, stream) - struct cmd_list_element *list; - char *cmdtype; - enum command_class class; - GDB_FILE *stream; -{ - int len; - char *cmdtype1, *cmdtype2; - - /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub" */ - len = strlen (cmdtype); - cmdtype1 = (char *) alloca (len + 1); - cmdtype1[0] = 0; - cmdtype2 = (char *) alloca (len + 4); - cmdtype2[0] = 0; - if (len) - { - cmdtype1[0] = ' '; - strncpy (cmdtype1 + 1, cmdtype, len - 1); - cmdtype1[len] = 0; - strncpy (cmdtype2, cmdtype, len - 1); - strcpy (cmdtype2 + len - 1, " sub"); - } - - if (class == all_classes) - fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2); - else - fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2); - - help_cmd_list (list, class, cmdtype, (int)class >= 0, stream); - - if (class == all_classes) - fprintf_filtered (stream, "\n\ -Type \"help%s\" followed by a class name for a list of commands in that class.", - cmdtype1); - - fprintf_filtered (stream, "\n\ -Type \"help%s\" followed by %scommand name for full documentation.\n\ -Command name abbreviations are allowed if unambiguous.\n", - cmdtype1, cmdtype2); -} - -/* Print only the first line of STR on STREAM. */ -static void -print_doc_line (stream, str) - GDB_FILE *stream; - char *str; -{ - static char *line_buffer = 0; - static int line_size; - register char *p; - - if (!line_buffer) - { - line_size = 80; - line_buffer = (char *) xmalloc (line_size); - } - - p = str; - while (*p && *p != '\n' && *p != '.' && *p != ',') - p++; - if (p - str > line_size - 1) - { - line_size = p - str + 1; - free ((PTR)line_buffer); - line_buffer = (char *) xmalloc (line_size); - } - strncpy (line_buffer, str, p - str); - line_buffer[p - str] = '\0'; - if (islower (line_buffer[0])) - line_buffer[0] = toupper (line_buffer[0]); - fputs_filtered (line_buffer, stream); -} - -/* - * Implement a help command on command list LIST. - * RECURSE should be non-zero if this should be done recursively on - * all sublists of LIST. - * PREFIX is the prefix to print before each command name. - * STREAM is the stream upon which the output should be written. - * CLASS should be: - * A non-negative class number to list only commands in that - * class. - * ALL_COMMANDS to list all commands in list. - * ALL_CLASSES to list all classes in list. - * - * Note that RECURSE will be active on *all* sublists, not just the - * ones selected by the criteria above (ie. the selection mechanism - * is at the low level, not the high-level). - */ -void -help_cmd_list (list, class, prefix, recurse, stream) - struct cmd_list_element *list; - enum command_class class; - char *prefix; - int recurse; - GDB_FILE *stream; -{ - register struct cmd_list_element *c; - - for (c = list; c; c = c->next) - { - if (c->abbrev_flag == 0 && - (class == all_commands - || (class == all_classes && c->function.cfunc == NULL) - || (class == c->class && c->function.cfunc != NULL))) - { - fprintf_filtered (stream, "%s%s -- ", prefix, c->name); - print_doc_line (stream, c->doc); - fputs_filtered ("\n", stream); - } - if (recurse - && c->prefixlist != 0 - && c->abbrev_flag == 0) - help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream); - } -} - - -/* Search the input clist for 'command'. Return the command if - found (or NULL if not), and return the number of commands - found in nfound */ - -static struct cmd_list_element * -find_cmd(command, len, clist, ignore_help_classes, nfound) - char *command; - struct cmd_list_element *clist; - int ignore_help_classes; - int *nfound; -{ - struct cmd_list_element *found, *c; - - found = (struct cmd_list_element *)NULL; - *nfound = 0; - for (c = clist; c; c = c->next) - if (!strncmp (command, c->name, len) - && (!ignore_help_classes || c->function.cfunc)) - { - found = c; - (*nfound)++; - if (c->name[len] == '\0') - { - *nfound = 1; - break; - } - } - return found; -} - -/* This routine takes a line of TEXT and a CLIST in which to start the - lookup. When it returns it will have incremented the text pointer past - the section of text it matched, set *RESULT_LIST to point to the list in - which the last word was matched, and will return a pointer to the cmd - list element which the text matches. It will return NULL if no match at - all was possible. It will return -1 (cast appropriately, ick) if ambigous - matches are possible; in this case *RESULT_LIST will be set to point to - the list in which there are ambiguous choices (and *TEXT will be set to - the ambiguous text string). - - If the located command was an abbreviation, this routine returns the base - command of the abbreviation. - - It does no error reporting whatsoever; control will always return - to the superior routine. - - In the case of an ambiguous return (-1), *RESULT_LIST will be set to point - at the prefix_command (ie. the best match) *or* (special case) will be NULL - if no prefix command was ever found. For example, in the case of "info a", - "info" matches without ambiguity, but "a" could be "args" or "address", so - *RESULT_LIST is set to the cmd_list_element for "info". So in this case - RESULT_LIST should not be interpeted as a pointer to the beginning of a - list; it simply points to a specific command. In the case of an ambiguous - return *TEXT is advanced past the last non-ambiguous prefix (e.g. - "info t" can be "info types" or "info target"; upon return *TEXT has been - advanced past "info "). - - If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise - affect the operation). - - This routine does *not* modify the text pointed to by TEXT. - - If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which - are actually help classes rather than commands (i.e. the function field of - the struct cmd_list_element is NULL). */ - -struct cmd_list_element * -lookup_cmd_1 (text, clist, result_list, ignore_help_classes) - char **text; - struct cmd_list_element *clist, **result_list; - int ignore_help_classes; -{ - char *p, *command; - int len, tmp, nfound; - struct cmd_list_element *found, *c; - - while (**text == ' ' || **text == '\t') - (*text)++; - - /* Treating underscores as part of command words is important - so that "set args_foo()" doesn't get interpreted as - "set args _foo()". */ - for (p = *text; - *p && (isalnum(*p) || *p == '-' || *p == '_' || - (tui_version && - (*p == '+' || *p == '<' || *p == '>' || *p == '$')) || - (xdb_commands && (*p == '!' || *p == '/' || *p == '?'))); - p++) - ; - - /* If nothing but whitespace, return 0. */ - if (p == *text) - return 0; - - len = p - *text; - - /* *text and p now bracket the first command word to lookup (and - it's length is len). We copy this into a local temporary */ - - - command = (char *) alloca (len + 1); - for (tmp = 0; tmp < len; tmp++) - { - char x = (*text)[tmp]; - command[tmp] = x; - } - command[len] = '\0'; - - /* Look it up. */ - found = 0; - nfound = 0; - found = find_cmd(command, len, clist, ignore_help_classes, &nfound); - - /* - ** We didn't find the command in the entered case, so lower case it - ** and search again. - */ - if (!found || nfound == 0) - { - for (tmp = 0; tmp < len; tmp++) - { - char x = command[tmp]; - command[tmp] = isupper(x) ? tolower(x) : x; - } - found = find_cmd(command, len, clist, ignore_help_classes, &nfound); - } - - /* If nothing matches, we have a simple failure. */ - if (nfound == 0) - return 0; - - if (nfound > 1) - { - if (result_list != NULL) - /* Will be modified in calling routine - if we know what the prefix command is. */ - *result_list = 0; - return (struct cmd_list_element *) -1; /* Ambiguous. */ - } - - /* We've matched something on this list. Move text pointer forward. */ - - *text = p; - - /* If this was an abbreviation, use the base command instead. */ - - if (found->cmd_pointer) - found = found->cmd_pointer; - - /* If we found a prefix command, keep looking. */ - - if (found->prefixlist) - { - c = lookup_cmd_1 (text, *found->prefixlist, result_list, - ignore_help_classes); - if (!c) - { - /* Didn't find anything; this is as far as we got. */ - if (result_list != NULL) - *result_list = clist; - return found; - } - else if (c == (struct cmd_list_element *) -1) - { - /* We've gotten this far properly, but the next step - is ambiguous. We need to set the result list to the best - we've found (if an inferior hasn't already set it). */ - if (result_list != NULL) - if (!*result_list) - /* This used to say *result_list = *found->prefixlist - If that was correct, need to modify the documentation - at the top of this function to clarify what is supposed - to be going on. */ - *result_list = found; - return c; - } - else - { - /* We matched! */ - return c; - } - } - else - { - if (result_list != NULL) - *result_list = clist; - return found; - } -} - -/* All this hair to move the space to the front of cmdtype */ - -static void -undef_cmd_error (cmdtype, q) - char *cmdtype, *q; -{ - error ("Undefined %scommand: \"%s\". Try \"help%s%.*s\".", - cmdtype, - q, - *cmdtype? " ": "", - strlen(cmdtype)-1, - cmdtype); -} - -/* Look up the contents of *LINE as a command in the command list LIST. - LIST is a chain of struct cmd_list_element's. - If it is found, return the struct cmd_list_element for that command - and update *LINE to point after the command name, at the first argument. - If not found, call error if ALLOW_UNKNOWN is zero - otherwise (or if error returns) return zero. - Call error if specified command is ambiguous, - unless ALLOW_UNKNOWN is negative. - CMDTYPE precedes the word "command" in the error message. - - If INGNORE_HELP_CLASSES is nonzero, ignore any command list - elements which are actually help classes rather than commands (i.e. - the function field of the struct cmd_list_element is 0). */ - -struct cmd_list_element * -lookup_cmd (line, list, cmdtype, allow_unknown, ignore_help_classes) - char **line; - struct cmd_list_element *list; - char *cmdtype; - int allow_unknown; - int 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) - { - if (!allow_unknown) - { - if (!*line) - error ("Lack of needed %scommand", cmdtype); - else - { - char *p = *line, *q; - - while (isalnum(*p) || *p == '-') - p++; - - q = (char *) alloca (p - *line + 1); - strncpy (q, *line, p - *line); - q[p - *line] = '\0'; - undef_cmd_error (cmdtype, q); - } - } - else - return 0; - } - else if (c == (struct cmd_list_element *) -1) - { - /* Ambigous. Local values should be off prefixlist or called - values. */ - int local_allow_unknown = (last_list ? last_list->allow_unknown : - allow_unknown); - char *local_cmdtype = last_list ? last_list->prefixname : cmdtype; - struct cmd_list_element *local_list = - (last_list ? *(last_list->prefixlist) : list); - - if (local_allow_unknown < 0) - { - if (last_list) - return last_list; /* Found something. */ - else - return 0; /* Found nothing. */ - } - else - { - /* Report as error. */ - int amb_len; - char ambbuf[100]; - - for (amb_len = 0; - ((*line)[amb_len] && (*line)[amb_len] != ' ' - && (*line)[amb_len] != '\t'); - amb_len++) - ; - - ambbuf[0] = 0; - for (c = local_list; c; c = c->next) - if (!strncmp (*line, c->name, amb_len)) - { - if (strlen (ambbuf) + strlen (c->name) + 6 < (int)sizeof ambbuf) - { - if (strlen (ambbuf)) - strcat (ambbuf, ", "); - strcat (ambbuf, c->name); - } - else - { - strcat (ambbuf, ".."); - break; - } - } - error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype, - *line, ambbuf); - return 0; /* lint */ - } - } - else - { - /* We've got something. It may still not be what the caller - wants (if this command *needs* a subcommand). */ - while (**line == ' ' || **line == '\t') - (*line)++; - - if (c->prefixlist && **line && !c->allow_unknown) - undef_cmd_error (c->prefixname, *line); - - /* Seems to be what he wants. Return it. */ - return c; - } - return 0; -} - -#if 0 -/* Look up the contents of *LINE as a command in the command list LIST. - LIST is a chain of struct cmd_list_element's. - If it is found, return the struct cmd_list_element for that command - and update *LINE to point after the command name, at the first argument. - If not found, call error if ALLOW_UNKNOWN is zero - otherwise (or if error returns) return zero. - Call error if specified command is ambiguous, - unless ALLOW_UNKNOWN is negative. - CMDTYPE precedes the word "command" in the error message. */ - -struct cmd_list_element * -lookup_cmd (line, list, cmdtype, allow_unknown) - char **line; - struct cmd_list_element *list; - char *cmdtype; - int allow_unknown; -{ - register char *p; - register struct cmd_list_element *c, *found; - int nfound; - char ambbuf[100]; - char *processed_cmd; - int i, cmd_len; - - /* Skip leading whitespace. */ - - while (**line == ' ' || **line == '\t') - (*line)++; - - /* Clear out trailing whitespace. */ - - p = *line + strlen (*line); - while (p != *line && (p[-1] == ' ' || p[-1] == '\t')) - p--; - *p = 0; - - /* Find end of command name. */ - - p = *line; - while (*p == '-' || isalnum(*p)) - p++; - - /* Look up the command name. - If exact match, keep that. - Otherwise, take command abbreviated, if unique. Note that (in my - opinion) a null string does *not* indicate ambiguity; simply the - end of the argument. */ - - if (p == *line) - { - if (!allow_unknown) - error ("Lack of needed %scommand", cmdtype); - return 0; - } - - /* Copy over to a local buffer, converting to lowercase on the way. - This is in case the command being parsed is a subcommand which - doesn't match anything, and that's ok. We want the original - untouched for the routine of the original command. */ - - processed_cmd = (char *) alloca (p - *line + 1); - for (cmd_len = 0; cmd_len < p - *line; cmd_len++) - { - char x = (*line)[cmd_len]; - if (isupper(x)) - processed_cmd[cmd_len] = tolower(x); - else - processed_cmd[cmd_len] = x; - } - processed_cmd[cmd_len] = '\0'; - - /* Check all possibilities in the current command list. */ - found = 0; - nfound = 0; - for (c = list; c; c = c->next) - { - if (!strncmp (processed_cmd, c->name, cmd_len)) - { - found = c; - nfound++; - if (c->name[cmd_len] == 0) - { - nfound = 1; - break; - } - } - } - - /* Report error for undefined command name. */ - - if (nfound != 1) - { - if (nfound > 1 && allow_unknown >= 0) - { - ambbuf[0] = 0; - for (c = list; c; c = c->next) - if (!strncmp (processed_cmd, c->name, cmd_len)) - { - if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf) - { - if (strlen (ambbuf)) - strcat (ambbuf, ", "); - strcat (ambbuf, c->name); - } - else - { - strcat (ambbuf, ".."); - break; - } - } - error ("Ambiguous %scommand \"%s\": %s.", cmdtype, - processed_cmd, ambbuf); - } - else if (!allow_unknown) - error ("Undefined %scommand: \"%s\".", cmdtype, processed_cmd); - return 0; - } - - /* Skip whitespace before the argument. */ - - while (*p == ' ' || *p == '\t') p++; - *line = p; - - if (found->prefixlist && *p) - { - c = lookup_cmd (line, *found->prefixlist, found->prefixname, - found->allow_unknown); - if (c) - return c; - } - - return found; -} -#endif - -/* Helper function for SYMBOL_COMPLETION_FUNCTION. */ - -/* Return a vector of char pointers which point to the different - possible completions in LIST of TEXT. - - WORD points in the same buffer as TEXT, and completions should be - returned relative to this position. For example, suppose TEXT is "foo" - and we want to complete to "foobar". If WORD is "oo", return - "oobar"; if WORD is "baz/foo", return "baz/foobar". */ - -char ** -complete_on_cmdlist (list, text, word) - struct cmd_list_element *list; - char *text; - char *word; -{ - struct cmd_list_element *ptr; - char **matchlist; - int sizeof_matchlist; - int matches; - int textlen = strlen (text); - - sizeof_matchlist = 10; - matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *)); - matches = 0; - - for (ptr = list; ptr; ptr = ptr->next) - if (!strncmp (ptr->name, text, textlen) - && !ptr->abbrev_flag - && (ptr->function.cfunc - || ptr->prefixlist)) - { - if (matches == sizeof_matchlist) - { - sizeof_matchlist *= 2; - matchlist = (char **) xrealloc ((char *)matchlist, - (sizeof_matchlist - * sizeof (char *))); - } - - matchlist[matches] = (char *) - xmalloc (strlen (word) + strlen (ptr->name) + 1); - if (word == text) - strcpy (matchlist[matches], ptr->name); - else if (word > text) - { - /* Return some portion of ptr->name. */ - strcpy (matchlist[matches], ptr->name + (word - text)); - } - else - { - /* Return some of text plus ptr->name. */ - strncpy (matchlist[matches], word, text - word); - matchlist[matches][text - word] = '\0'; - strcat (matchlist[matches], ptr->name); - } - ++matches; - } - - if (matches == 0) - { - free ((PTR)matchlist); - matchlist = 0; - } - else - { - matchlist = (char **) xrealloc ((char *)matchlist, ((matches + 1) - * sizeof (char *))); - matchlist[matches] = (char *) 0; - } - - return matchlist; -} - -/* Helper function for SYMBOL_COMPLETION_FUNCTION. */ - -/* Return a vector of char pointers which point to the different - possible completions in CMD of TEXT. - - WORD points in the same buffer as TEXT, and completions should be - returned relative to this position. For example, suppose TEXT is "foo" - and we want to complete to "foobar". If WORD is "oo", return - "oobar"; if WORD is "baz/foo", return "baz/foobar". */ - -char ** -complete_on_enum (enumlist, text, word) - char **enumlist; - char *text; - char *word; -{ - char **matchlist; - int sizeof_matchlist; - int matches; - int textlen = strlen (text); - int i; - char *name; - - sizeof_matchlist = 10; - matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *)); - matches = 0; - - for (i = 0; (name = enumlist[i]) != NULL; i++) - if (strncmp (name, text, textlen) == 0) - { - if (matches == sizeof_matchlist) - { - sizeof_matchlist *= 2; - matchlist = (char **) xrealloc ((char *)matchlist, - (sizeof_matchlist - * sizeof (char *))); - } - - matchlist[matches] = (char *) - xmalloc (strlen (word) + strlen (name) + 1); - if (word == text) - strcpy (matchlist[matches], name); - else if (word > text) - { - /* Return some portion of name. */ - strcpy (matchlist[matches], name + (word - text)); - } - else - { - /* Return some of text plus name. */ - strncpy (matchlist[matches], word, text - word); - matchlist[matches][text - word] = '\0'; - strcat (matchlist[matches], name); - } - ++matches; - } - - if (matches == 0) - { - free ((PTR)matchlist); - matchlist = 0; - } - else - { - matchlist = (char **) xrealloc ((char *)matchlist, ((matches + 1) - * sizeof (char *))); - matchlist[matches] = (char *) 0; - } - - return matchlist; -} - -static int -parse_binary_operation (arg) - char *arg; -{ - int length; - - if (!arg || !*arg) - return 1; - - length = strlen (arg); - - while (arg[length - 1] == ' ' || arg[length - 1] == '\t') - length--; - - if (!strncmp (arg, "on", length) - || !strncmp (arg, "1", length) - || !strncmp (arg, "yes", length)) - return 1; - else - if (!strncmp (arg, "off", length) - || !strncmp (arg, "0", length) - || !strncmp (arg, "no", length)) - return 0; - else - { - error ("\"on\" or \"off\" expected."); - return 0; - } -} - -/* Do a "set" or "show" command. ARG is NULL if no argument, or the text - of the argument, and FROM_TTY is nonzero if this command is being entered - directly by the user (i.e. these are just like any other - command). C is the command list element for the command. */ -void -do_setshow_command (arg, from_tty, c) - char *arg; - int from_tty; - struct cmd_list_element *c; -{ - if (c->type == set_cmd) - { - switch (c->var_type) - { - case var_string: - { - char *new; - char *p; - char *q; - int ch; - - if (arg == NULL) - arg = ""; - new = (char *) xmalloc (strlen (arg) + 2); - p = arg; q = new; - while ((ch = *p++) != '\000') - { - if (ch == '\\') - { - /* \ 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); - if (ch == 0) - break; /* C loses */ - else if (ch > 0) - *q++ = ch; - } - else - *q++ = ch; - } -#if 0 - if (*(p - 1) != '\\') - *q++ = ' '; -#endif - *q++ = '\0'; - new = (char *) xrealloc (new, q - new); - if (*(char **)c->var != NULL) - free (*(char **)c->var); - *(char **) c->var = new; - } - break; - case var_string_noescape: - if (arg == NULL) - arg = ""; - if (*(char **)c->var != NULL) - free (*(char **)c->var); - *(char **) c->var = savestring (arg, strlen (arg)); - break; - case var_filename: - if (arg == NULL) - error_no_arg ("filename to set it to."); - if (*(char **)c->var != NULL) - free (*(char **)c->var); - *(char **)c->var = tilde_expand (arg); - break; - case var_boolean: - *(int *) c->var = parse_binary_operation (arg); - break; - case var_uinteger: - if (arg == NULL) - error_no_arg ("integer to set it to."); - *(unsigned int *) c->var = parse_and_eval_address (arg); - if (*(unsigned int *) c->var == 0) - *(unsigned int *) c->var = UINT_MAX; - break; - case var_integer: - { - unsigned int val; - if (arg == NULL) - error_no_arg ("integer to set it to."); - val = parse_and_eval_address (arg); - if (val == 0) - *(int *) c->var = INT_MAX; - else if (val >= INT_MAX) - error ("integer %u out of range", val); - else - *(int *) c->var = val; - break; - } - case var_zinteger: - if (arg == NULL) - error_no_arg ("integer to set it to."); - *(int *) c->var = parse_and_eval_address (arg); - break; - case var_enum: - { - int i; - int len; - int nmatches; - char *match = NULL; - char *p; - - /* if no argument was supplied, print an informative error message */ - if (arg == NULL) - { - char msg[1024]; - strcpy (msg, "Requires an argument. Valid arguments are "); - for (i = 0; c->enums[i]; i++) - { - if (i != 0) - strcat (msg, ", "); - strcat (msg, c->enums[i]); - } - strcat (msg, "."); - error (msg); - } - - p = strchr (arg, ' '); - - if (p) - len = p - arg; - else - len = strlen (arg); - - nmatches = 0; - for (i = 0; c->enums[i]; i++) - if (strncmp (arg, c->enums[i], len) == 0) - { - match = c->enums[i]; - nmatches++; - } - - if (nmatches <= 0) - error ("Undefined item: \"%s\".", arg); - - if (nmatches > 1) - error ("Ambiguous item \"%s\".", arg); - - *(char **)c->var = match; - } - break; - default: - error ("gdb internal error: bad var_type in do_setshow_command"); - } - } - else if (c->type == show_cmd) - { - /* Print doc minus "show" at start. */ - print_doc_line (gdb_stdout, c->doc + 5); - - fputs_filtered (" is ", gdb_stdout); - wrap_here (" "); - switch (c->var_type) - { - case var_string: - { - unsigned char *p; - - fputs_filtered ("\"", gdb_stdout); - if (*(unsigned char **)c->var) - for (p = *(unsigned char **) c->var; *p != '\0'; p++) - gdb_printchar (*p, gdb_stdout, '"'); - fputs_filtered ("\"", gdb_stdout); - } - break; - case var_string_noescape: - case var_filename: - case var_enum: - fputs_filtered ("\"", gdb_stdout); - if (*(char **)c->var) - fputs_filtered (*(char **) c->var, gdb_stdout); - fputs_filtered ("\"", gdb_stdout); - break; - case var_boolean: - fputs_filtered (*(int *) c->var ? "on" : "off", gdb_stdout); - break; - case var_uinteger: - if (*(unsigned int *) c->var == UINT_MAX) { - fputs_filtered ("unlimited", gdb_stdout); - break; - } - /* else fall through */ - case var_zinteger: - fprintf_filtered (gdb_stdout, "%u", *(unsigned int *) c->var); - break; - case var_integer: - if (*(int *) c->var == INT_MAX) - { - fputs_filtered ("unlimited", gdb_stdout); - } - else - fprintf_filtered (gdb_stdout, "%d", *(int *) c->var); - break; - - default: - error ("gdb internal error: bad var_type in do_setshow_command"); - } - fputs_filtered (".\n", gdb_stdout); - } - else - error ("gdb internal error: bad cmd_type in do_setshow_command"); - (*c->function.sfunc) (NULL, from_tty, c); -} - -/* Show all the settings in a list of show commands. */ - -void -cmd_show_list (list, from_tty, prefix) - struct cmd_list_element *list; - int from_tty; - char *prefix; -{ - for (; list != NULL; list = list->next) { - /* If we find a prefix, run its list, prefixing our output by its - prefix (with "show " skipped). */ - if (list->prefixlist && !list->abbrev_flag) - cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5); - if (list->type == show_cmd) - { - fputs_filtered (prefix, gdb_stdout); - fputs_filtered (list->name, gdb_stdout); - fputs_filtered (": ", gdb_stdout); - do_setshow_command ((char *)NULL, from_tty, list); - } - } -} - -/* ARGSUSED */ -static void -shell_escape (arg, from_tty) - char *arg; - int from_tty; -{ -#ifdef CANT_FORK - /* FIXME: what about errors (I don't know how GO32 system() handles - them)? */ - system (arg); -#else /* Can fork. */ - int rc, status, pid; - char *p, *user_shell; - - if ((user_shell = (char *) getenv ("SHELL")) == NULL) - user_shell = "/bin/sh"; - - /* Get the name of the shell for arg0 */ - if ((p = strrchr (user_shell, '/')) == NULL) - p = user_shell; - else - p++; /* Get past '/' */ - - if ((pid = fork()) == 0) - { - if (!arg) - execl (user_shell, p, 0); - else - execl (user_shell, p, "-c", arg, 0); - - fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell, - safe_strerror (errno)); - gdb_flush (gdb_stderr); - _exit (0177); - } - - if (pid != -1) - while ((rc = wait (&status)) != pid && rc != -1) - ; - else - error ("Fork failed"); -#endif /* Can fork. */ -} - -static void -make_command (arg, from_tty) - char *arg; - int from_tty; -{ - char *p; - - if (arg == 0) - p = "make"; - else - { - p = xmalloc (sizeof("make ") + strlen(arg)); - strcpy (p, "make "); - strcpy (p + sizeof("make ")-1, arg); - } - - shell_escape (p, from_tty); -} - -static void -show_user_1 (c, stream) - struct cmd_list_element *c; - GDB_FILE *stream; -{ - register struct command_line *cmdlines; - - cmdlines = c->user_commands; - if (!cmdlines) - return; - fputs_filtered ("User command ", stream); - fputs_filtered (c->name, stream); - fputs_filtered (":\n", stream); - - while (cmdlines) - { - print_command_line (cmdlines, 4); - cmdlines = cmdlines->next; - } - fputs_filtered ("\n", stream); -} - -/* ARGSUSED */ -static void -show_user (args, from_tty) - char *args; - int from_tty; -{ - struct cmd_list_element *c; - extern struct cmd_list_element *cmdlist; - - if (args) - { - c = lookup_cmd (&args, cmdlist, "", 0, 1); - if (c->class != class_user) - error ("Not a user command."); - show_user_1 (c, gdb_stdout); - } - else - { - for (c = cmdlist; c; c = c->next) - { - if (c->class == class_user) - show_user_1 (c, gdb_stdout); - } - } -} - -void -_initialize_command () -{ - add_com ("shell", class_support, shell_escape, - "Execute the rest of the line as a shell command. \n\ -With no arguments, run an inferior shell."); - - if (xdb_commands) - add_com_alias("!", "shell", class_support, 0); - - add_com ("make", class_support, make_command, - "Run the ``make'' program using the rest of the line as arguments."); - add_cmd ("user", no_class, show_user, - "Show definitions of user defined commands.\n\ -Argument is the name of the user defined command.\n\ -With no argument, show definitions of all user defined commands.", &showlist); -} diff --git a/contrib/gdb/gdb/config/i386/cygwin32.mh b/contrib/gdb/gdb/config/i386/cygwin32.mh deleted file mode 100644 index 25f15cfcd03..00000000000 --- a/contrib/gdb/gdb/config/i386/cygwin32.mh +++ /dev/null @@ -1,6 +0,0 @@ -MH_CFLAGS= -XM_FILE=xm-cygwin32.h -TERMCAP= -NATDEPFILES=win32-nat.o -XM_CLIBS=-lkernel32 - diff --git a/contrib/gdb/gdb/config/i386/cygwin32.mt b/contrib/gdb/gdb/config/i386/cygwin32.mt deleted file mode 100644 index 22b45473ad6..00000000000 --- a/contrib/gdb/gdb/config/i386/cygwin32.mt +++ /dev/null @@ -1,6 +0,0 @@ -# Target: Intel 386 run win32 -TDEPFILES= i386-tdep.o i387-tdep.o -TM_FILE= tm-cygwin32.h - - - diff --git a/contrib/gdb/gdb/config/i386/nm-sun386.h b/contrib/gdb/gdb/config/i386/nm-sun386.h deleted file mode 100644 index f7a904b4f1a..00000000000 --- a/contrib/gdb/gdb/config/i386/nm-sun386.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Native support for Sun 386i, for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Do implement the attach and detach commands. */ - -#define ATTACH_DETACH - -/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ -#define FETCH_INFERIOR_REGISTERS - -#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES) diff --git a/contrib/gdb/gdb/config/i386/sun386.mh b/contrib/gdb/gdb/config/i386/sun386.mh deleted file mode 100644 index d2496610b17..00000000000 --- a/contrib/gdb/gdb/config/i386/sun386.mh +++ /dev/null @@ -1,5 +0,0 @@ -# Host: Sun 386i -XDEPFILES= -XM_FILE= xm-sun386.h -NAT_FILE= nm-sun386.h -NATDEPFILES= infptrace.o inftarg.o fork-child.o sun386-nat.o diff --git a/contrib/gdb/gdb/config/i386/sun386.mt b/contrib/gdb/gdb/config/i386/sun386.mt deleted file mode 100644 index 665ca643fd5..00000000000 --- a/contrib/gdb/gdb/config/i386/sun386.mt +++ /dev/null @@ -1,3 +0,0 @@ -# Target: Sun 386i target configuration file. -TDEPFILES= i386-tdep.o solib.o -TM_FILE= tm-sun386.h diff --git a/contrib/gdb/gdb/config/i386/tm-cygwin32.h b/contrib/gdb/gdb/config/i386/tm-cygwin32.h deleted file mode 100644 index f7464ba66cb..00000000000 --- a/contrib/gdb/gdb/config/i386/tm-cygwin32.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Macro definitions for i386 running under the win32 API Unix. - Copyright 1995, 1996 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#include "i386/tm-i386v.h" - -#undef MAX_REGISTER_RAW_SIZE -#undef MAX_REGISTER_VIRTUAL_SIZE -#undef NUM_REGS -#undef REGISTER_BYTE -#undef REGISTER_BYTES -#undef REGISTER_CONVERTIBLE -#undef REGISTER_CONVERT_TO_RAW -#undef REGISTER_CONVERT_TO_VIRTUAL -#undef REGISTER_NAMES -#undef REGISTER_RAW_SIZE -#undef REGISTER_VIRTUAL_SIZE -#undef REGISTER_VIRTUAL_TYPE - -/* Number of machine registers */ - -#define NUM_REGS 24 - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ - -/* the order of the first 8 registers must match the compiler's - * numbering scheme (which is the same as the 386 scheme) - * also, this table must match regmap in i386-pinsn.c. - */ - -#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ - "esp", "ebp", "esi", "edi", \ - "eip", "ps", "cs", "ss", \ - "ds", "es", "fs", "gs", \ - "st", "st(1)","st(2)","st(3)",\ - "st(4)","st(5)","st(6)","st(7)",} - -#define FP0_REGNUM 16 - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ - -#define REGISTER_BYTES (16 * 4 + 8 * 10) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) (((N) < 16) ? (N) * 4 : (((N) - 16) * 10) + (16 * 4)) - -/* Number of bytes of storage in the actual machine representation - for register N. */ - -#define REGISTER_RAW_SIZE(N) (((N) < 16) ? 4 : 10) - -/* Number of bytes of storage in the program's representation - for register N. */ - -#define REGISTER_VIRTUAL_SIZE(N) (((N) < 16) ? 4 : 10) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 10 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 10 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#define REGISTER_CONVERTIBLE(N) \ - ((N < FP0_REGNUM) ? 0 : 1) - -/* Convert data from raw format for register REGNUM in buffer FROM - to virtual format with type TYPE in buffer TO. */ -extern void -i387_to_double PARAMS ((char *, char *)); - - -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ -{ \ - double val; \ - i387_to_double ((FROM), (char *)&val); \ - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ -} - -extern void -double_to_i387 PARAMS ((char *, char *)); - -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ -{ \ - double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ - double_to_i387((char *)&val, (TO)); \ -} - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#define REGISTER_VIRTUAL_TYPE(N) \ - ((N < FP0_REGNUM) ? builtin_type_int : \ - builtin_type_double) - -#define NAMES_HAVE_UNDERSCORE - - -#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) skip_trampoline_code (pc, name) -#define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc, 0) -extern CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR pc, char *name)); diff --git a/contrib/gdb/gdb/config/i386/tm-sun386.h b/contrib/gdb/gdb/config/i386/tm-sun386.h deleted file mode 100644 index 259fd518238..00000000000 --- a/contrib/gdb/gdb/config/i386/tm-sun386.h +++ /dev/null @@ -1,205 +0,0 @@ -/* Parameters for a Sun 386i target machine, for GDB, the GNU debugger. - Copyright 1986, 1987, 1991, 1992, 1993 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if !defined (TM_SUN386_H) -#define TM_SUN386_H 1 - -#include "i386/tm-i386.h" - -#ifndef sun386 -#define sun386 -#endif -#define GDB_TARGET_IS_SUN386 1 -#define SUNOS4 -#define USE_MACHINE_REG_H - -/* Perhaps some day this will work even without the following #define */ -#define COFF_ENCAPSULATE - -#ifdef COFF_ENCAPSULATE -/* Avoid conflicts between our include files and - (maybe not needed anymore). */ -#define _EXEC_ -#endif - -/* sun386 ptrace seems unable to change the frame pointer */ -#define PTRACE_FP_BUG - -/* Address of end of stack space. */ - -#define STACK_END_ADDR 0xfc000000 - -/* Number of machine registers */ - -#undef NUM_REGS -#define NUM_REGS 35 - -/* Initializer for an array of names of registers. There should be NUM_REGS - strings in this initializer. The order of the first 8 registers must match - the compiler's numbering scheme (which is the same as the 386 scheme) also, - this table must match regmap in i386-pinsn.c. */ - -#undef REGISTER_NAMES -#define REGISTER_NAMES { "gs", "fs", "es", "ds", \ - "edi", "esi", "ebp", "esp", \ - "ebx", "edx", "ecx", "eax", \ - "retaddr", "trapnum", "errcode", "ip", \ - "cs", "ps", "sp", "ss", \ - "fst0", "fst1", "fst2", "fst3", \ - "fst4", "fst5", "fst6", "fst7", \ - "fctrl", "fstat", "ftag", "fip", \ - "fcs", "fopoff", "fopsel" \ - } - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -#undef FP_REGNUM -#define FP_REGNUM 6 /* (ebp) Contains address of executing stack frame */ -#undef SP_REGNUM -#define SP_REGNUM 18 /* (usp) Contains address of top of stack */ -#undef PS_REGNUM -#define PS_REGNUM 17 /* (ps) Contains processor status */ -#undef PC_REGNUM -#define PC_REGNUM 15 /* (eip) Contains program counter */ -#undef FP0_REGNUM -#define FP0_REGNUM 20 /* Floating point register 0 */ -#undef FPC_REGNUM -#define FPC_REGNUM 28 /* 80387 control register */ - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ - -#undef REGISTER_BYTES -#define REGISTER_BYTES (20*4+8*10+7*4) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#undef REGISTER_BYTE -#define REGISTER_BYTE(N) \ - ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 160 \ - : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 10) + 80 \ - : (N) * 4) - -/* Number of bytes of storage in the actual machine representation - for register N. */ - -#undef REGISTER_RAW_SIZE -#define REGISTER_RAW_SIZE(N) (((unsigned)((N) - FP0_REGNUM)) < 8 ? 10 : 4) - -/* Number of bytes of storage in the program's representation - for register N. */ - -#undef REGISTER_VIRTUAL_SIZE -#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)((N) - FP0_REGNUM)) < 8 ? 8 : 4) - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#undef REGISTER_CONVERTIBLE -#define REGISTER_CONVERTIBLE(N) (((unsigned)((N) - FP0_REGNUM)) < 8) - -/* Convert data from raw format for register REGNUM in buffer FROM - to virtual format with type TYPE in buffer TO. */ - -#undef REGISTER_CONVERT_TO_VIRTUAL -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ -{ \ - double val; \ - i387_to_double ((FROM), (char *)&val); \ - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ -} -extern void -i387_to_double PARAMS ((char *, char *)); - -/* Convert data from virtual format with type TYPE in buffer FROM - to raw format for register REGNUM in buffer TO. */ - -#undef REGISTER_CONVERT_TO_RAW -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ -{ \ - double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ - double_to_i387((char *)&val, (TO)); \ -} -extern void -double_to_i387 PARAMS ((char *, char *)); - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#undef REGISTER_VIRTUAL_TYPE -#define REGISTER_VIRTUAL_TYPE(N) \ - (((unsigned)((N) - FP0_REGNUM)) < 8 ? builtin_type_double : builtin_type_int) - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -#undef EXTRACT_RETURN_VALUE -#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - memcpy (VALBUF, REGBUF + REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 11), TYPE_LENGTH (TYPE)) - -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. */ - -#undef STORE_RETURN_VALUE -#define STORE_RETURN_VALUE(TYPE,VALBUF) \ - write_register_bytes (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 11), VALBUF, TYPE_LENGTH (TYPE)) - -/* Describe the pointer in each stack frame to the previous stack frame - (its caller). */ - -/* FRAME_CHAIN takes a frame's nominal address - and produces the frame's chain-pointer. */ - -#undef FRAME_CHAIN -#define FRAME_CHAIN(thisframe) \ - (!inside_entry_file ((thisframe)->pc) ? \ - read_memory_integer ((thisframe)->frame, 4) :\ - 0) - -/* Define other aspects of the stack frame. */ - -/* A macro that tells us whether the function invocation represented - by FI does not have a frame on the stack associated with it. If it - does not, FRAMELESS is set to 1, else 0. */ - -#undef FRAMELESS_FUNCTION_INVOCATION -#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \ -{ (FRAMELESS) = frameless_look_for_prologue (FI); } - -#undef FRAME_SAVED_PC -#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4)) - -/* Insert the specified number of args and function address - into a call sequence of the above form stored at DUMMYNAME. */ - -#undef FIX_CALL_DUMMY -#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \ -{ \ - *(int *)((char *)(dummyname) + 1) = (int)(fun) - (pc) - 5; \ -} - -#endif /* !defined (TM_SUN386_H) */ - diff --git a/contrib/gdb/gdb/config/i386/windows.mh b/contrib/gdb/gdb/config/i386/windows.mh deleted file mode 100644 index 3933a6e0053..00000000000 --- a/contrib/gdb/gdb/config/i386/windows.mh +++ /dev/null @@ -1,17 +0,0 @@ -# gdbwin.o and ser-win32s.c have to be named because they have -# _initialize functions that need to be found by init.c -# gui.ores has to be named, or else msvc won't link it in. -XDEPFILES = \ - mswin/gdbwin.o \ - mswin/ser-win32s.o \ - mswin/gui.ores \ - mswin/libwingdb.a - -$(XDEPFILES): - rootme=`pwd` ; export rootme ; \ - ( cd mswin ; \ - $(MAKE) $(FLAGS_TO_PASS) all ) - -XM_FILE=xm-windows.h -MMALLOC= -SER_HARDWIRE = diff --git a/contrib/gdb/gdb/config/i386/xm-cygwin32.h b/contrib/gdb/gdb/config/i386/xm-cygwin32.h deleted file mode 100644 index becbebe08ba..00000000000 --- a/contrib/gdb/gdb/config/i386/xm-cygwin32.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Definitions for hosting on WIN32, for GDB. - Copyright 1995, 1996 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define HOST_BYTE_ORDER LITTLE_ENDIAN - -#include "fopen-bin.h" - -#define GDBINIT_FILENAME "gdb.ini" - - -#define SLASH_P(X) ((X)=='\\' || (X) == '/') -#define ROOTED_P(X) ((SLASH_P((X)[0]))|| ((X)[1] ==':')) -#define SLASH_CHAR '/' -#define SLASH_STRING "/" - - -/* If we longjmp out of the signal handler we never get another one. - So disable immediate_quit inside request_quit */ -#define REQUEST_QUIT - - - - - - diff --git a/contrib/gdb/gdb/config/i386/xm-i386lynx.h b/contrib/gdb/gdb/config/i386/xm-i386lynx.h deleted file mode 100644 index 6078cb6f2cb..00000000000 --- a/contrib/gdb/gdb/config/i386/xm-i386lynx.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Host-dependent definitions for Intel 386 running LynxOS. - Copyright 1993 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define HOST_BYTE_ORDER LITTLE_ENDIAN - -/* Get generic LynxOS host definitions. */ - -#include "xm-lynx.h" diff --git a/contrib/gdb/gdb/config/i386/xm-linux.h b/contrib/gdb/gdb/config/i386/xm-linux.h deleted file mode 100644 index 217c6d4d094..00000000000 --- a/contrib/gdb/gdb/config/i386/xm-linux.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Native support for GNU/Linux, for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef XM_LINUX_H -#define XM_LINUX_H - -#define HOST_BYTE_ORDER LITTLE_ENDIAN - -#define HAVE_TERMIOS - -/* This is the amount to subtract from u.u_ar0 - to get the offset in the core file of the register values. */ -#define KERNEL_U_ADDR 0x0 - -#define NEED_POSIX_SETPGID - -/* Need R_OK etc, but USG isn't defined. */ -#include - -#endif /* #ifndef XM_LINUX_H */ diff --git a/contrib/gdb/gdb/config/i386/xm-sun386.h b/contrib/gdb/gdb/config/i386/xm-sun386.h deleted file mode 100644 index 51c3b58c11b..00000000000 --- a/contrib/gdb/gdb/config/i386/xm-sun386.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Host support for Sun 386i, for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define HOST_BYTE_ORDER LITTLE_ENDIAN diff --git a/contrib/gdb/gdb/config/i386/xm-windows.h b/contrib/gdb/gdb/config/i386/xm-windows.h deleted file mode 100644 index e083010067c..00000000000 --- a/contrib/gdb/gdb/config/i386/xm-windows.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Definitions for hosting on WIN32, built with Microsoft Visual C/C++, for GDB. - Copyright 1996, 1998 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "i386/xm-cygwin.h" - -#undef PRINTF_HAS_LONG_LONG -#undef HAVE_UNISTD_H -#undef HAVE_TERMIO_H -#undef HAVE_TERMIOS_H -#undef HAVE_SGTTY_H -#undef HAVE_SBRK -#define CANT_FORK - -#define MALLOC_INCOMPATIBLE - -#include - -#define SIGQUIT 3 -#define SIGTRAP 5 diff --git a/contrib/gdb/gdb/config/nm-empty.h b/contrib/gdb/gdb/config/nm-empty.h deleted file mode 100644 index 7069d8c8a4e..00000000000 --- a/contrib/gdb/gdb/config/nm-empty.h +++ /dev/null @@ -1,2 +0,0 @@ -/* This is just a dummy file to symlink to when GDB is configured as a - cross-only debugger. */ diff --git a/contrib/gdb/gdb/config/nm-gnu.h b/contrib/gdb/gdb/config/nm-gnu.h deleted file mode 100644 index 8f17406abc2..00000000000 --- a/contrib/gdb/gdb/config/nm-gnu.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Common declarations for the GNU Hurd - - Copyright 1995, 1996, 1998, 1999 Free Software Foundation, Inc. - - Written by Miles Bader - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef __NM_GNU_H__ -#define __NM_GNU_H__ - -#include -#include -#include -#include "regcache.h" - -extern char *gnu_target_pid_to_str (int pid); - -/* Before storing, we need to read all the registers. */ -#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES) - -/* Don't do wait_for_inferior on attach. */ -#define ATTACH_NO_WAIT - -/* Use SVR4 style shared library support */ -#define SVR4_SHARED_LIBS -#include "solib.h" -#define NO_CORE_OPS - -#endif /* __NM_GNU_H__ */ diff --git a/contrib/gdb/gdb/config/nm-lynx.h b/contrib/gdb/gdb/config/nm-lynx.h deleted file mode 100644 index 1cd2bd1ceb1..00000000000 --- a/contrib/gdb/gdb/config/nm-lynx.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Native-dependent definitions for LynxOS. - Copyright 1993, 1994, 1995, 1996, 1999, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef NM_LYNX_H -#define NM_LYNX_H - -#include -#include -/* sys/kernel.h should define this, but doesn't always, sigh. */ -#ifndef __LYNXOS -#define __LYNXOS -#endif -#include -#include -#include -#include -#include -#include -#include -#include "gdbthread.h" - -/* This is the amount to subtract from u.u_ar0 to get the offset in - the core file of the register values. */ - -#define KERNEL_U_ADDR USRSTACK - -#undef FLOAT_INFO /* No float info yet */ - -/* As of LynxOS 2.2.2 (beta 8/15/94), this is int. Previous versions seem to - have had no prototype, so I'm not sure why GDB used to define this to - char *. */ -#define PTRACE_ARG3_TYPE int - -/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ - -#define FETCH_INFERIOR_REGISTERS - -/* Thread ID of stopped thread. */ - -#define WIFTID(x) (((union wait *)&x)->w_tid) - -/* Override child_wait in inftarg.c */ - -#define CHILD_WAIT - -/* Override child_resume in infptrace.c */ - -#define CHILD_RESUME - -/* Override child_thread_alive in intarg.c */ - -#define CHILD_THREAD_ALIVE - -#include "target.h" - -extern ptid_t child_wait (ptid_t ptid, - struct target_waitstatus *status); - -/* Lynx needs a special definition of this so that we can - print out the pid and thread number seperately. */ - - -/* override child_pid_to_str in inftarg.c */ -#define CHILD_PID_TO_STR -extern char *lynx_pid_to_str (ptid_t ptid); - -#endif /* NM_LYNX_H */ diff --git a/contrib/gdb/gdb/config/nm-m3.h b/contrib/gdb/gdb/config/nm-m3.h deleted file mode 100644 index f89838ed967..00000000000 --- a/contrib/gdb/gdb/config/nm-m3.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Mach 3.0 common definitions and global vars. - - Copyright 1992, 1993, 1994, 1996 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef NM_M3_H -#define NM_M3_H - -#include -#include "regcache.h" - -/* Mach3 doesn't declare errno in . */ -extern int errno; - -/* Task port of our debugged inferior. */ - -extern task_t inferior_task; - -/* Thread port of the current thread in the inferior. */ - -extern thread_t current_thread; - -/* If nonzero, we must suspend/abort && resume threads - * when setting or getting the state. - */ -extern int must_suspend_thread; - -#define PREPARE_TO_PROCEED(select_it) mach3_prepare_to_proceed(select_it) - -/* Try to get the privileged host port for authentication to machid - - * If you can get this, you may debug anything on this host. - * - * If you can't, gdb gives it's own task port as the - * authentication port - */ -#define mach_privileged_host_port() task_by_pid(-1) - -/* - * This is the MIG ID number of the emulator/server bsd_execve() RPC call. - * - * It SHOULD never change, but if it does, gdb `run' - * command won't work until you fix this define. - * - */ -#define MIG_EXEC_SYSCALL_ID 101000 - -/* If our_message_port gets a msg with this ID, - * GDB suspends it's inferior and enters command level. - * (Useful at least if ^C does not work) - */ -#define GDB_MESSAGE_ID_STOP 0x41151 - -/* wait3 WNOHANG is defined in but - * for some reason gdb does not want to include - * that file. - * - * If your system defines WNOHANG differently, this has to be changed. - */ -#define WNOHANG 1 - -/* Before storing, we need to read all the registers. */ - -#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES) - -/* Check if the inferior exists */ -#define MACH_ERROR_NO_INFERIOR \ - do if (!MACH_PORT_VALID (inferior_task)) \ - error ("Inferior task does not exist."); while(0) - -/* Error handler for mach calls */ -#define CHK(str,ret) \ - do if (ret != KERN_SUCCESS) \ - error ("Gdb %s [%d] %s : %s\n",__FILE__,__LINE__,str, \ - mach_error_string(ret)); while(0) - -/* This is from POE9 emulator/emul_stack.h - */ -/* - * Top of emulator stack holds link and reply port. - */ -struct emul_stack_top - { - struct emul_stack_top *link; - mach_port_t reply_port; - }; - -#define EMULATOR_STACK_SIZE (4096*4) - -#define THREAD_ALLOWED_TO_BREAK(mid) mach_thread_for_breakpoint (mid) - -#define THREAD_PARSE_ID(arg) mach_thread_parse_id (arg) - -#define THREAD_OUTPUT_ID(mid) mach_thread_output_id (mid) - -#define ATTACH_TO_THREAD attach_to_thread - -/* Don't do wait_for_inferior on attach. */ -#define ATTACH_NO_WAIT - -/* Do Mach 3 dependent operations when ^C or a STOP is requested */ -#define DO_QUIT() mach3_quit () - -#if 0 -/* This is bogus. It is NOT OK to quit out of target_wait. */ -/* If in mach_msg() and ^C is typed set immediate_quit */ -#define REQUEST_QUIT() mach3_request_quit () -#endif - -#endif /* NM_M3_H */ diff --git a/contrib/gdb/gdb/config/nm-nbsd.h b/contrib/gdb/gdb/config/nm-nbsd.h deleted file mode 100644 index 402f606fd26..00000000000 --- a/contrib/gdb/gdb/config/nm-nbsd.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Native-dependent definitions for NetBSD. - Copyright 1994, 1996, 1999 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#define PTRACE_ARG3_TYPE char* - -#define FETCH_INFERIOR_REGISTERS - -#define ATTACH_DETACH - -#include "solib.h" /* Support for shared libraries. */ -#if defined (SVR4_SHARED_LIBS) -#include "elf/common.h" /* Additional ELF shared library info. */ -#endif - -#if !defined (SVR4_SHARED_LIBS) - -/* 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 diff --git a/contrib/gdb/gdb/config/nm-sysv4.h b/contrib/gdb/gdb/config/nm-sysv4.h deleted file mode 100644 index 4b4f09897bc..00000000000 --- a/contrib/gdb/gdb/config/nm-sysv4.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Definitions for running gdb on a host machine running any flavor of SVR4. - Copyright 1991, 1992, 1993, 1998 Free Software Foundation, Inc. - Written by Fred Fish at Cygnus Support (fnf@cygnus.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Use SVR4 style shared library support */ - -#define SVR4_SHARED_LIBS -#include "solib.h" - -/* SVR4 has /proc support, so use it instead of ptrace. */ - -#define USE_PROC_FS - -/* SVR4 machines can easily do attach and detach via /proc (procfs.c) - support */ - -#define ATTACH_DETACH diff --git a/contrib/gdb/gdb/config/tm-lynx.h b/contrib/gdb/gdb/config/tm-lynx.h deleted file mode 100644 index 13aeca1c3f7..00000000000 --- a/contrib/gdb/gdb/config/tm-lynx.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Macro definitions for LynxOS targets. - Copyright 1993, 1995 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef TM_LYNX_H -#define TM_LYNX_H - -/* Override number of expected traps from sysv. */ -#define START_INFERIOR_TRAPS_EXPECTED 2 - -#include "coff-solib.h" /* COFF shared library support */ - -/* Lynx's signal.h doesn't seem to have any macros for what signal numbers - the real-time events are. */ -#define REALTIME_LO 33 -/* One more than the last one. */ -#define REALTIME_HI 64 - -#endif /* TM_LYNX_H */ diff --git a/contrib/gdb/gdb/config/tm-nbsd.h b/contrib/gdb/gdb/config/tm-nbsd.h deleted file mode 100644 index d002d6bb2b5..00000000000 --- a/contrib/gdb/gdb/config/tm-nbsd.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Target machine sub-description for NetBSD. - This is included by other tm-*.h files to specify NetBSD-specific stuff. - Copyright 1993, 1994 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef SVR4_SHARED_LIBS - -/* Return non-zero if we are in a shared library trampoline code stub. */ - -#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \ - (name && !strcmp(name, "_DYNAMIC")) - -#endif /* !SVR4_SHARED_LIBS */ diff --git a/contrib/gdb/gdb/config/tm-sunos.h b/contrib/gdb/gdb/config/tm-sunos.h deleted file mode 100644 index c8db07e865e..00000000000 --- a/contrib/gdb/gdb/config/tm-sunos.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Target machine sub-description for SunOS version 4. - This is included by other tm-*.h files to specify SunOS-specific stuff. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "solib.h" /* Support for shared libraries. */ - -/* Return non-zero if we are in a shared library trampoline code stub. */ - -#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \ - lookup_solib_trampoline_symbol_by_pc (pc) - -/* If PC is in a shared library trampoline code, return the PC - where the function itself actually starts. If not, return 0. */ - -#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc) diff --git a/contrib/gdb/gdb/config/tm-sysv4.h b/contrib/gdb/gdb/config/tm-sysv4.h deleted file mode 100644 index 35b95eb71f8..00000000000 --- a/contrib/gdb/gdb/config/tm-sysv4.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Macro definitions for GDB on all SVR4 target systems. - Copyright 1991, 1992, 1993, 1994, 1996, 1997, 2000 - Free Software Foundation, Inc. - Written by Fred Fish at Cygnus Support (fnf@cygnus.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* For SVR4 shared libraries, each call to a library routine goes through - a small piece of trampoline code in the ".plt" section. - The horribly ugly wait_for_inferior() routine uses this macro to detect - when we have stepped into one of these fragments. - We do not use lookup_solib_trampoline_symbol_by_pc, because - we cannot always find the shared library trampoline symbols - (e.g. on Irix5). */ - -#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) in_plt_section((pc), (name)) -extern int in_plt_section (CORE_ADDR, char *); - -/* If PC is in a shared library trampoline code, return the PC - where the function itself actually starts. If not, return 0. */ - -#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc) - -/* It is unknown which, if any, SVR4 assemblers do not accept dollar signs - in identifiers. The default in G++ is to use dots instead, for all SVR4 - systems, so we make that our default also. FIXME: There should be some - way to get G++ to tell us what CPLUS_MARKER it is using, perhaps by - stashing it in the debugging information as part of the name of an - invented symbol ("gcc_cplus_marker$" for example). */ - -#undef CPLUS_MARKER -#define CPLUS_MARKER '.' diff --git a/contrib/gdb/gdb/config/xm-aix4.h b/contrib/gdb/gdb/config/xm-aix4.h deleted file mode 100644 index bea086a371b..00000000000 --- a/contrib/gdb/gdb/config/xm-aix4.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Parameters for hosting on an PowerPC, for GDB, the GNU debugger. - Copyright 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - Contributed by Cygnus Corporation. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* The following text is taken from config/rs6000.mh: - * # The IBM version of /usr/include/rpc/rpc.h has a bug -- it says - * # `extern fd_set svc_fdset;' without ever defining the type fd_set. - * # Unfortunately this occurs in the vx-share code, which is not configured - * # like the rest of GDB (e.g. it doesn't include "defs.h"). - * # We circumvent this bug by #define-ing fd_set here, but undefining it in - * # the xm-rs6000.h file before ordinary modules try to use it. FIXME, IBM! - * MH_CFLAGS='-Dfd_set=int' - * So, here we do the undefine...which has to occur before we include - * below. - */ -#undef fd_set - -#include - -/* At least as of AIX 3.2, we have termios. */ -#define HAVE_TERMIOS 1 -/* #define HAVE_TERMIO 1 */ - -#define USG 1 - -#define FIVE_ARG_PTRACE - -/* This system requires that we open a terminal with O_NOCTTY for it to - not become our controlling terminal. */ - -#define USE_O_NOCTTY - -/* Brain death inherited from PC's pervades. */ -#undef NULL -#define NULL 0 - -/* The IBM compiler requires this in order to properly compile alloca(). */ -#pragma alloca - -/* There is no vfork. */ - -#define vfork fork - -char *termdef (); - -/* Signal handler for SIGWINCH `window size changed'. */ - -#define SIGWINCH_HANDLER aix_resizewindow -extern void aix_resizewindow (int); - -/* `lines_per_page' and `chars_per_line' are local to utils.c. Rectify this. */ - -#define SIGWINCH_HANDLER_BODY \ - \ -/* Respond to SIGWINCH `window size changed' signal, and reset GDB's \ - window settings appropriately. */ \ - \ -void \ -aix_resizewindow (signo) \ - int signo; \ -{ \ - int fd = fileno (stdout); \ - if (isatty (fd)) { \ - int val; \ - \ - val = atoi (termdef (fd, 'l')); \ - if (val > 0) \ - lines_per_page = val; \ - val = atoi (termdef (fd, 'c')); \ - if (val > 0) \ - chars_per_line = val; \ - } \ -} diff --git a/contrib/gdb/gdb/config/xm-lynx.h b/contrib/gdb/gdb/config/xm-lynx.h deleted file mode 100644 index 6f19abdb810..00000000000 --- a/contrib/gdb/gdb/config/xm-lynx.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Host-dependent definitions for any CPU running LynxOS. - Copyright 1993 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* for INT_MIN, to avoid "INT_MIN redefined" warnings from defs.h */ - -#include diff --git a/contrib/gdb/gdb/config/xm-mpw.h b/contrib/gdb/gdb/config/xm-mpw.h deleted file mode 100644 index 0c473d75572..00000000000 --- a/contrib/gdb/gdb/config/xm-mpw.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Macro definitions for running GDB on Apple Macintoshes. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "mpw.h" - -#include "fopen-bin.h" - -#include "spin.h" - -#define CANT_FORK - -/* Map these standard functions to versions that can do I/O in a console - window. */ - -#define printf hacked_printf -#define fprintf hacked_fprintf -#define vprintf hacked_vfprintf -#define fputs hacked_fputs -#define fputc hacked_fputc -#undef putc -#define putc hacked_putc -#define fflush hacked_fflush - -#define fgetc hacked_fgetc - -#define POSIX_UTIME - -/* No declaration of strdup in MPW's string.h, oddly enough. */ - -char *strdup (char *s1); - -/* '.' indicates drivers on the Mac, so we need a different filename. */ - -#define GDBINIT_FILENAME "_gdbinit" - -/* Commas are more common to separate dirnames in a path on Macs. */ - -#define DIRNAME_SEPARATOR ',' - -/* This is a real crufty hack. */ - -#define HAVE_TERMIO - -/* Addons to the basic MPW-supported signal list. */ - -#ifndef SIGQUIT -#define SIGQUIT (1<<6) -#endif -#ifndef SIGHUP -#define SIGHUP (1<<7) -#endif - -/* If __STDC__ is on, then this definition will be missing. */ - -#ifndef fileno -#define fileno(p) (p)->_file -#endif - -#ifndef R_OK -#define R_OK 4 -#endif - -extern int StandAlone; - -extern int mac_app; diff --git a/contrib/gdb/gdb/config/xm-nbsd.h b/contrib/gdb/gdb/config/xm-nbsd.h deleted file mode 100644 index c8d00f6dd63..00000000000 --- a/contrib/gdb/gdb/config/xm-nbsd.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Host-dependent definitions for any CPU running NetBSD. - Copyright 1993, 1994, 1995, 1996, 1999 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Include this to get things like NGROUPS which doesn't - define on some systems. */ -#include - -/* NetBSD has termios facilities. */ -#define HAVE_TERMIOS diff --git a/contrib/gdb/gdb/config/xm-sysv4.h b/contrib/gdb/gdb/config/xm-sysv4.h deleted file mode 100644 index 614d4032772..00000000000 --- a/contrib/gdb/gdb/config/xm-sysv4.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Definitions for running gdb on a host machine running any flavor of SVR4. - Copyright 1991, 1992, 1993, 1995, 1998 Free Software Foundation, Inc. - Written by Fred Fish at Cygnus Support (fnf@cygnus.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* SVR4 has termios facilities. */ - -#undef HAVE_TERMIO -#define HAVE_TERMIOS - -/* SVR4 is a derivative of System V Release 3 (USG) */ - -#define USG diff --git a/contrib/gdb/gdb/cpu32bug-rom.c b/contrib/gdb/gdb/cpu32bug-rom.c deleted file mode 100644 index 2801be9ea0f..00000000000 --- a/contrib/gdb/gdb/cpu32bug-rom.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Remote debugging interface for CPU32Bug Rom monitor for GDB, the GNU debugger. - Copyright 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - Written by Stu Grossman of Cygnus Support - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "regcache.h" - -static void cpu32bug_open (char *args, int from_tty); - -static void -cpu32bug_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - int regno; - - if (regnamelen != 2) - return; - - switch (regname[0]) - { - case 'S': - if (regname[1] != 'R') - return; - regno = PS_REGNUM; - break; - case 'P': - if (regname[1] != 'C') - return; - regno = PC_REGNUM; - break; - case 'D': - if (regname[1] < '0' || regname[1] > '7') - return; - regno = regname[1] - '0' + D0_REGNUM; - break; - case 'A': - if (regname[1] < '0' || regname[1] > '7') - return; - regno = regname[1] - '0' + A0_REGNUM; - break; - default: - return; - } - - monitor_supply_register (regno, val); -} - -/* - * This array of registers needs to match the indexes used by GDB. The - * whole reason this exists is because the various ROM monitors use - * different names than GDB does, and don't support all the - * registers either. So, typing "info reg sp" becomes an "A7". - */ - -static char *cpu32bug_regnames[NUM_REGS] = -{ - "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", - "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", - "SR", "PC", -}; - -/* - * Define the monitor command strings. Since these are passed directly - * through to a printf style function, we need can include formatting - * strings. We also need a CR or LF on the end. - */ - -static struct target_ops cpu32bug_ops; - -static char *cpu32bug_inits[] = -{"\r", NULL}; - -static struct monitor_ops cpu32bug_cmds; - -static void -init_cpu32bug_cmds (void) -{ - cpu32bug_cmds.flags = MO_CLR_BREAK_USES_ADDR; - cpu32bug_cmds.init = cpu32bug_inits; /* Init strings */ - cpu32bug_cmds.cont = "g\r"; /* continue command */ - cpu32bug_cmds.step = "t\r"; /* single step */ - cpu32bug_cmds.stop = NULL; /* interrupt command */ - cpu32bug_cmds.set_break = "br %x\r"; /* set a breakpoint */ - cpu32bug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */ - cpu32bug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */ - cpu32bug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */ - cpu32bug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */ - cpu32bug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */ - cpu32bug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */ - cpu32bug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - cpu32bug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ - cpu32bug_cmds.setmem.term = NULL; /* setreg.term */ - cpu32bug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ - cpu32bug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */ - cpu32bug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */ - cpu32bug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */ - cpu32bug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - cpu32bug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */ - cpu32bug_cmds.getmem.term = NULL; /* getmem.term */ - cpu32bug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - cpu32bug_cmds.setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */ - cpu32bug_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - cpu32bug_cmds.setreg.term = NULL; /* setreg.term */ - cpu32bug_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - cpu32bug_cmds.getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */ - cpu32bug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */ - cpu32bug_cmds.getreg.term = NULL; /* getreg.term */ - cpu32bug_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - cpu32bug_cmds.dump_registers = "rd\r"; /* dump_registers */ - cpu32bug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - cpu32bug_cmds.supply_register = cpu32bug_supply_register; /* supply_register */ - cpu32bug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - cpu32bug_cmds.load = "lo\r"; /* download command */ - cpu32bug_cmds.loadresp = "\n"; /* load response */ - cpu32bug_cmds.prompt = "CPU32Bug>"; /* monitor command prompt */ - cpu32bug_cmds.line_term = "\r"; /* end-of-line terminator */ - cpu32bug_cmds.cmd_end = NULL; /* optional command terminator */ - cpu32bug_cmds.target = &cpu32bug_ops; /* target operations */ - cpu32bug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - cpu32bug_cmds.regnames = cpu32bug_regnames; /* registers names */ - cpu32bug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -}; /* init_cpu32bug_cmds */ - -static void -cpu32bug_open (char *args, int from_tty) -{ - monitor_open (args, &cpu32bug_cmds, from_tty); -} - -void -_initialize_cpu32bug_rom (void) -{ - init_cpu32bug_cmds (); - init_monitor_ops (&cpu32bug_ops); - - cpu32bug_ops.to_shortname = "cpu32bug"; - cpu32bug_ops.to_longname = "CPU32Bug monitor"; - cpu32bug_ops.to_doc = "Debug via the CPU32Bug monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - cpu32bug_ops.to_open = cpu32bug_open; - - add_target (&cpu32bug_ops); -} diff --git a/contrib/gdb/gdb/cxux-nat.c b/contrib/gdb/gdb/cxux-nat.c deleted file mode 100644 index 742f89cdb19..00000000000 --- a/contrib/gdb/gdb/cxux-nat.c +++ /dev/null @@ -1,537 +0,0 @@ -/* Native support for Motorola 88k running Harris CX/UX. - Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, - 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" - -#include -#include -#include -#include -#include "gdbcore.h" -#include - -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "symtab.h" -#include "regcache.h" - -#ifndef USER /* added to support BCS ptrace_user */ -#define USER ptrace_user -#endif -#include -#include -#include -#include "gdb_stat.h" - -#include "symtab.h" -#include "setjmp.h" -#include "value.h" - -#include - -/* CX/UX provides them already, but as word offsets instead of char offsets */ -#define SXIP_OFFSET (PT_SXIP * 4) -#define SNIP_OFFSET (PT_SNIP * 4) -#define SFIP_OFFSET (PT_SFIP * 4) -#define PSR_OFFSET (PT_PSR * sizeof(int)) -#define FPSR_OFFSET (PT_FPSR * sizeof(int)) -#define FPCR_OFFSET (PT_FPCR * sizeof(int)) - -#define XREGADDR(r) (((char *)&u.pt_x0-(char *)&u) + \ - ((r)-X0_REGNUM)*sizeof(X_REGISTER_RAW_TYPE)) - -extern int have_symbol_file_p (); - -extern jmp_buf stack_jmp; - -extern int errno; - -void -fetch_inferior_registers (int regno) -{ - register unsigned int regaddr; - char buf[MAX_REGISTER_RAW_SIZE]; - register int i; - - struct USER u; - unsigned int offset; - - offset = (char *) &u.pt_r0 - (char *) &u; - regaddr = offset; /* byte offset to r0; */ - -/* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */ - for (regno = 0; regno < PC_REGNUM; regno++) - { - /*regaddr = register_addr (regno, offset); */ - /* 88k enhancement */ - - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - *(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (int); - } - supply_register (regno, buf); - } - /* now load up registers 32-37; special pc registers */ - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) PSR_OFFSET, 0); - supply_register (PSR_REGNUM, buf); - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) FPSR_OFFSET, 0); - supply_register (FPSR_REGNUM, buf); - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) FPCR_OFFSET, 0); - supply_register (FPCR_REGNUM, buf); - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SXIP_OFFSET, 0); - supply_register (SXIP_REGNUM, buf); - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SNIP_OFFSET, 0); - supply_register (SNIP_REGNUM, buf); - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SFIP_OFFSET, 0); - supply_register (SFIP_REGNUM, buf); - - if (target_is_m88110) - { - for (regaddr = XREGADDR (X0_REGNUM), regno = X0_REGNUM; - regno < NUM_REGS; - regno++, regaddr += 16) - { - X_REGISTER_RAW_TYPE xval; - - *(int *) &xval.w1 = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) regaddr, 0); - *(int *) &xval.w2 = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) (regaddr + 4), 0); - *(int *) &xval.w3 = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) (regaddr + 8), 0); - *(int *) &xval.w4 = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) (regaddr + 12), 0); - supply_register (regno, (void *) &xval); - } - } -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (int regno) -{ - register unsigned int regaddr; - char buf[80]; - - struct USER u; - - unsigned int offset = (char *) &u.pt_r0 - (char *) &u; - - regaddr = offset; - - /* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either - svr3 doesn't run on an 88110, or the kernel isolates the different (not - completely sure this is true, but seems to be. */ - if (regno >= 0) - { - /* regaddr = register_addr (regno, offset); */ - if (regno < PC_REGNUM) - { - regaddr = offset + regno * sizeof (int); - errno = 0; - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) regaddr, read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } - else if (regno == PSR_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register (regno)); - else if (regno == FPSR_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register (regno)); - else if (regno == FPCR_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register (regno)); - else if (regno == SXIP_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (regno)); - else if (regno == SNIP_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (regno)); - else if (regno == SFIP_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (regno)); - else if (target_is_m88110 && regno < NUM_REGS) - { - X_REGISTER_RAW_TYPE xval; - - read_register_bytes (REGISTER_BYTE (regno), (char *) &xval, - sizeof (X_REGISTER_RAW_TYPE)); - regaddr = XREGADDR (regno); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, xval.w1); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 4, xval.w2); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 8, xval.w3); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 12, xval.w4); - } - else - printf_unfiltered ("Bad register number for store_inferior routine\n"); - } - else - { - for (regno = 0; regno < PC_REGNUM; regno++) - { - /* regaddr = register_addr (regno, offset); */ - errno = 0; - regaddr = offset + regno * sizeof (int); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) regaddr, read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register (regno)); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register (regno)); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register (regno)); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (SXIP_REGNUM)); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (SNIP_REGNUM)); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (SFIP_REGNUM)); - if (target_is_m88110) - { - for (regno = X0_REGNUM; regno < NUM_REGS; regno++) - { - X_REGISTER_RAW_TYPE xval; - - read_register_bytes (REGISTER_BYTE (regno), (char *) &xval, - sizeof (X_REGISTER_RAW_TYPE)); - regaddr = XREGADDR (regno); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, xval.w1); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 4), xval.w2); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 8), xval.w3); - ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 12), xval.w4); - } - } - } -} - -/* blockend is the address of the end of the user structure */ - -m88k_register_u_addr (int blockend, int regnum) -{ - struct USER u; - int ustart = blockend - sizeof (struct USER); - - if (regnum < PSR_REGNUM) - return (ustart + ((int) &u.pt_r0 - (int) &u) + - REGISTER_SIZE * regnum); - else if (regnum == PSR_REGNUM) - return (ustart + ((int) &u.pt_psr) - (int) &u); - else if (regnum == FPSR_REGNUM) - return (ustart + ((int) &u.pt_fpsr) - (int) &u); - else if (regnum == FPCR_REGNUM) - return (ustart + ((int) &u.pt_fpcr) - (int) &u); - else if (regnum == SXIP_REGNUM) - return (ustart + SXIP_OFFSET); - else if (regnum == SNIP_REGNUM) - return (ustart + SNIP_OFFSET); - else if (regnum == SFIP_REGNUM) - return (ustart + SFIP_OFFSET); - else if (target_is_m88110) - return (ustart + ((int) &u.pt_x0 - (int) &u) + /* Must be X register */ - sizeof (u.pt_x0) * (regnum - X0_REGNUM)); - else - return (blockend + REGISTER_SIZE * regnum); -} - -#ifdef USE_PROC_FS - -#include - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* Given a pointer to a general register set in /proc format (gregset_t *), - unpack the register contents and supply them as gdb's idea of the current - register values. */ - -void -supply_gregset (gregset_t *gregsetp) -{ - register int regi; - register greg_t *regp = (greg_t *) gregsetp; - - for (regi = 0; regi <= SP_REGNUM; regi++) - supply_register (regi, (char *) (regp + regi)); - - supply_register (SXIP_REGNUM, (char *) (regp + R_XIP)); - supply_register (SNIP_REGNUM, (char *) (regp + R_NIP)); - supply_register (SFIP_REGNUM, (char *) (regp + R_FIP)); - supply_register (PSR_REGNUM, (char *) (regp + R_PSR)); - supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR)); - supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR)); -} - -void -fill_gregset (gregset_t *gregsetp, int regno) -{ - int regi; - register greg_t *regp = (greg_t *) gregsetp; - - for (regi = 0; regi <= R_R31; regi++) - if ((regno == -1) || (regno == regi)) - *(regp + regi) = *(int *) ®isters[REGISTER_BYTE (regi)]; - - if ((regno == -1) || (regno == SXIP_REGNUM)) - *(regp + R_XIP) = *(int *) ®isters[REGISTER_BYTE (SXIP_REGNUM)]; - if ((regno == -1) || (regno == SNIP_REGNUM)) - *(regp + R_NIP) = *(int *) ®isters[REGISTER_BYTE (SNIP_REGNUM)]; - if ((regno == -1) || (regno == SFIP_REGNUM)) - *(regp + R_FIP) = *(int *) ®isters[REGISTER_BYTE (SFIP_REGNUM)]; - if ((regno == -1) || (regno == PSR_REGNUM)) - *(regp + R_PSR) = *(int *) ®isters[REGISTER_BYTE (PSR_REGNUM)]; - if ((regno == -1) || (regno == FPSR_REGNUM)) - *(regp + R_FPSR) = *(int *) ®isters[REGISTER_BYTE (FPSR_REGNUM)]; - if ((regno == -1) || (regno == FPCR_REGNUM)) - *(regp + R_FPCR) = *(int *) ®isters[REGISTER_BYTE (FPCR_REGNUM)]; -} - -#endif /* USE_PROC_FS */ - -/* This support adds the equivalent of adb's % command. When - the `add-shared-symbol-files' command is given, this routine scans - the dynamic linker's link map and reads the minimal symbols - from each shared object file listed in the map. */ - -struct link_map -{ - unsigned long l_addr; /* address at which object is mapped */ - char *l_name; /* full name of loaded object */ - void *l_ld; /* dynamic structure of object */ - struct link_map *l_next; /* next link object */ - struct link_map *l_prev; /* previous link object */ -}; - -#define LINKS_MAP_POINTER "_ld_tail" -#define LIBC_FILE "/usr/lib/libc.so.1" -#define SHARED_OFFSET 0xf0001000 - -#ifndef PATH_MAX -#define PATH_MAX 1023 /* maximum size of path name on OS */ -#endif - -void -add_shared_symbol_files (void) -{ - void *desc; - struct link_map *ld_map, *lm, lms; - struct minimal_symbol *minsym; - struct objfile *objfile; - char *path_name; - - if (ptid_equal (inferior_ptid, null_ptid)) - { - warning ("The program has not yet been started."); - return; - } - - objfile = symbol_file_add (LIBC_FILE, 0, NULL, 0, OBJF_READNOW); - minsym = lookup_minimal_symbol (LINKS_MAP_POINTER, objfile); - - ld_map = (struct link_map *) - read_memory_integer (((int) SYMBOL_VALUE_ADDRESS (minsym) + SHARED_OFFSET), 4); - lm = ld_map; - while (lm) - { - int local_errno = 0; - - read_memory ((CORE_ADDR) lm, (char *) &lms, sizeof (struct link_map)); - if (lms.l_name) - { - if (target_read_string ((CORE_ADDR) lms.l_name, &path_name, - PATH_MAX, &local_errno)) - { - struct section_addr_info section_addrs; - memset (§ion_addrs, 0, sizeof (section_addrs)); - section_addrs.other[0].addr = lms.l_addr; - section_addrs.other[0].name = ".text"; - symbol_file_add (path_name, 1, §ion_addrs, 0, 0); - xfree (path_name); - } - } - /* traverse links in reverse order so that we get the - the symbols the user actually gets. */ - lm = lms.l_prev; - } - - /* Getting new symbols may change our opinion about what is - frameless. */ - reinit_frame_cache (); -} - -#if defined(_ES_MP) - -#include - -unsigned int -m88k_harris_core_register_addr (int regno, int reg_ptr) -{ - unsigned int word_offset; - - switch (regno) - { - case PSR_REGNUM: - word_offset = R_EPSR; - break; - case FPSR_REGNUM: - word_offset = R_FPSR; - break; - case FPCR_REGNUM: - word_offset = R_FPCR; - break; - case SXIP_REGNUM: - word_offset = R_EXIP; - break; - case SNIP_REGNUM: - word_offset = R_ENIP; - break; - case SFIP_REGNUM: - word_offset = R_EFIP; - break; - default: - if (regno <= FP_REGNUM) - word_offset = regno; - else - word_offset = ((regno - X0_REGNUM) * 4); - } - return (word_offset * 4); -} - -#endif /* _ES_MP */ - -void -_initialize_m88k_nat (void) -{ -#ifdef _ES_MP - /* Enable 88110 support, as we don't support the 88100 under ES/MP. */ - - target_is_m88110 = 1; -#elif defined(_CX_UX) - /* Determine whether we're running on an 88100 or an 88110. */ - target_is_m88110 = (sinfo (SYSMACHINE, 0) == SYS5800); -#endif /* _CX_UX */ -} - -#ifdef _ES_MP -/* Given a pointer to a general register set in /proc format (gregset_t *), - unpack the register contents and supply them as gdb's idea of the current - register values. */ - -void -supply_gregset (gregset_t *gregsetp) -{ - register int regi; - register greg_t *regp = (greg_t *) gregsetp; - - for (regi = 0; regi < R_R31; regi++) - { - supply_register (regi, (char *) (regp + regi)); - } - supply_register (PSR_REGNUM, (char *) (regp + R_EPSR)); - supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR)); - supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR)); - supply_register (SXIP_REGNUM, (char *) (regp + R_EXIP)); - supply_register (SNIP_REGNUM, (char *) (regp + R_ENIP)); - supply_register (SFIP_REGNUM, (char *) (regp + R_EFIP)); -} - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), unpack the register contents and supply them as gdb's - idea of the current floating point register values. */ - -void -supply_fpregset (fpregset_t *fpregsetp) -{ - register int regi; - char *from; - - for (regi = FP0_REGNUM; regi <= FPLAST_REGNUM; regi++) - { - from = (char *) &((*fpregsetp)[regi - FP0_REGNUM]); - supply_register (regi, from); - } -} - -#endif /* _ES_MP */ - -#ifdef _CX_UX - -#include - -unsigned int -m88k_harris_core_register_addr (int regno, int reg_ptr) -{ - unsigned int word_offset; - - switch (regno) - { - case PSR_REGNUM: - word_offset = R_PSR; - break; - case FPSR_REGNUM: - word_offset = R_FPSR; - break; - case FPCR_REGNUM: - word_offset = R_FPCR; - break; - case SXIP_REGNUM: - word_offset = R_XIP; - break; - case SNIP_REGNUM: - word_offset = R_NIP; - break; - case SFIP_REGNUM: - word_offset = R_FIP; - break; - default: - if (regno <= FP_REGNUM) - word_offset = regno; - else - word_offset = ((regno - X0_REGNUM) * 4) + R_X0; - } - return (word_offset * 4); -} - -#endif /* _CX_UX */ diff --git a/contrib/gdb/gdb/doc/HPPA-cfg.texi b/contrib/gdb/gdb/doc/HPPA-cfg.texi deleted file mode 100644 index 88a138cab8b..00000000000 --- a/contrib/gdb/gdb/doc/HPPA-cfg.texi +++ /dev/null @@ -1,114 +0,0 @@ -@c GDB MANUAL configuration file. -@c Copyright (c) 1993 Free Software Foundation, Inc. -@c -@c NOTE: While the GDB manual is configurable (by changing these -@c switches), its configuration is ***NOT*** automatically tied in to -@c source configuration---because the authors expect that, save in -@c unusual cases, the most inclusive form of the manual is appropriate -@c no matter how the program itself is configured. -@c -@c The only automatically-varying variable is the GDB version number, -@c which the Makefile rewrites based on the VERSION variable from -@c `../Makefile.in'. -@c -@c GDB version number is recorded in the variable GDBVN -@include GDBvn.texi -@c -@c ---------------------------------------------------------------------- -@c PLATFORM FLAGS: -@clear GENERIC -@c -@c HP PA-RISC target: -@set HPPA -@c -@c Hitachi H8/300 target: -@clear H8 -@c Hitachi H8/300 target ONLY: -@clear H8EXCLUSIVE -@c -@c remote MIPS target: -@clear MIPS -@c -@c SPARC target: -@clear SPARC -@c -@c AMD 29000 target: -@clear AMD29K -@c -@c Intel 960 target: -@clear I960 -@c -@c Tandem ST2000 (phone switch) target: -@clear ST2000 -@c -@c Zilog 8000 target: -@clear Z8K -@c -@c Wind River Systems VxWorks environment: -@clear VXWORKS -@c -@c ---------------------------------------------------------------------- -@c DOC FEATURE FLAGS: -@c -@c Bare-board target? -@clear BARETARGET -@c -@c Restrict languages discussed to C? -@c This is backward. As time permits, change this to language-specific -@c switches for what to include. -@clear CONLY -@c Discuss Fortran? -@clear FORTRAN -@c -@c Discuss Modula 2? -@clear MOD2 -@c -@c Specifically for host machine running DOS? -@clear DOSHOST -@c -@c Talk about CPU simulator targets? -@clear SIMS -@c -@c Remote serial line settings of interest? -@set SERIAL -@c -@c Discuss features requiring Posix or similar OS environment? -@set POSIX -@c -@c Discuss remote serial debugging stub? -@clear REMOTESTUB -@c -@c Discuss gdbserver? -@set GDBSERVER -@c -@c Discuss gdbserve.nlm? -@set GDBSERVE -@c -@c Refrain from discussing how to configure sw and format doc? -@clear PRECONFIGURED -@c -@c Refrain from referring to unfree publications? -@set FSFDOC -@c -@c ---------------------------------------------------------------------- -@c STRINGS: -@c -@c Name of GDB program. Used also for (gdb) prompt string. -@set GDBP gdb -@c -@c Name of GDB product. Used in running text. -@set GDBN GDB -@c -@c Name of target. -@set TARGET HP 9000 Systems -@c -@c Name of host. Should not be used in generic configs, but generic -@c value may catch some flubs. -@set HOST machine specific -@c -@c Name of GCC product -@set NGCC GCC -@c -@c Name of GCC program -@set GCC gcc - diff --git a/contrib/gdb/gdb/doc/h8-cfg.texi b/contrib/gdb/gdb/doc/h8-cfg.texi deleted file mode 100644 index 823c7c244b5..00000000000 --- a/contrib/gdb/gdb/doc/h8-cfg.texi +++ /dev/null @@ -1,47 +0,0 @@ -@c GDB version number is recorded in the variable GDBVN -@include GDBvn.texi -@c -@set AGGLOMERATION -@clear AMD29K -@set BARETARGET -@clear CONLY -@set DOSHOST -@clear FORTRAN -@clear FSFDOC -@clear GDBSERVER -@clear GENERIC -@set H8 -@set H8EXCLUSIVE -@clear HAVE-FLOAT -@clear I960 -@clear MOD2 -@clear NOVEL -@clear POSIX -@set PRECONFIGURED -@clear REMOTESTUB -@set SIMS -@clear SERIAL -@clear SPARC -@clear ST2000 -@clear VXWORKS -@clear Z8K -@c ---------------------------------------------------------------------- -@c STRINGS: -@c -@c Name of GDB program. Used also for (gdb) prompt string. -@set GDBP gdb -@c -@c Name of GDB product. Used in running text. -@set GDBN GDB -@c -@c Name of GDB initialization file. -@set GDBINIT .gdbinit -@c -@c Name of target. -@set TARGET Hitachi Microprocessors -@c -@c Name of GCC product -@set NGCC GCC -@c -@c Name of GCC program -@set GCC gcc diff --git a/contrib/gdb/gdb/doc/libgdb.texinfo b/contrib/gdb/gdb/doc/libgdb.texinfo deleted file mode 100644 index 4fadcb2c9b5..00000000000 --- a/contrib/gdb/gdb/doc/libgdb.texinfo +++ /dev/null @@ -1,878 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename libgdb.info -@settitle Libgdb -@setchapternewpage off -@c %**end of header - -@ifinfo -This file documents libgdb, the GNU symbolic debugger in a library. - -This is Edition 0.3, Oct 1993, of @cite{Libgdb}. -Copyright 1993 Cygnus Support - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ifinfo - -@c This title page illustrates only one of the -@c two methods of forming a title page. - -@titlepage -@title Libgdb -@subtitle Version 0.3 -@subtitle Oct 1993 -@author Thomas Lord - -@c The following two commands -@c start the copyright page. -@page -@vskip 0pt plus 1filll -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Copyright @copyright{} 1993 Cygnus Support -@end titlepage - -@ifinfo -@node Top, Overview, (dir), (dir) - -This info file documents libgdb: an API for GDB, the GNU symbolic debugger. - -@menu -* Overview:: The basics of libgdb and this document. -* Interpreter:: Libgdb is an Interpreter-Based Server. -* Top Level:: You Provide the Top Level for the Libgdb - Command Interpreter . -* I/O:: How the Server's I/O Can be Used. -* Invoking:: Invoking the Interpreter, Executing - Commands. -* Defining Commands:: How New Commands are Created. -* Variables:: How Builtin Variables are Defined. -* Asynchronous:: Scheduling Asynchronous Computations. -* Commands:: Debugger Commands for Libgdb Applications -@end menu - -@end ifinfo -@node Overview, Interpreter, top, top -@comment node-name, next, previous, up -@chapter Overview -@cindex overview -@cindex definitions - -@heading Function and Purpose - -Libgdb is a package which provides an API to the functionality of GDB, -the GNU symbolic debugger. It is specifically intended to support the -development of a symbolic debugger with a graphic interface. - - -@heading This Document - -This document is a specification of the libgdb API. It is written in -the form of a programmer's manual. So the goal of this document is to -explain what functions make up the API, and how they can be used in a -running application. - - -@heading Terminology - -In this document, @dfn{libgdb} refers to a library containing the -functions defined herein, @dfn{application} refers to any program built -with that library. - - -@heading Dependencies - -Programs which are linked with libgdb must be linked with libbfd, -libopcodes, libiberty, and libmmalloc. - -@heading Acknowledgments - -Essential contributions to this design were made by Stu Grossman, Jim -Kingdon, and Rich Pixley. - -@node Interpreter, Top Level, Overview, Top -@comment node-name, next, previous, up -@chapter Libgdb is an Interpreter Based Server -@cindex interpreter -@cindex server - -To understand libgdb, it is necessary to understand how the library is -structured. Historically, GDB is written as a small interpreter for a -simple command language. The commands of the language perform useful -debugging functions. - -Libgdb is built from GDB by turning the interpreter into a debugging -server. The server reads debugging commands from any source and -interprets them, directing the output arbitrarily. - -In addition to changing GDB from a tty-based program to a server, a -number of new GDB commands have been added to make the server more -useful for a program with a graphic interface. - -Finally, libgdb includes provisions for asynchronous processing within -the application. - -Most operations that can be carried out with libgdb involve the GDB -command interpreter. The usual mode of operation is that the operation -is expressed as a string of GDB commands, which the interpreter is then -invoked to carry out. The output from commands executed in this manner -can be redirected in a variety of useful ways for further processing by -the application. - -The command interpreter provides an extensive system of hooks so an -application can monitor any aspect of the debugging library's state. An -application can set its own breakpoints and attach commands and -conditions to those. It is possible to attach hooks to any debugger -command; the hooks are invoked whenever that command is about to be -invoked. By means of these, the displays of a graphical interface can -be kept fully up to date at all times. - -We show you how to define new primitives in the command language. By -defining new primitives and using them in breakpoint scripts and command -hooks, an application can schedule the execution of arbitrary C-code at -almost any point of interest in the operation of libgdb. - -We show you how to define new GDB convenience variables for which your -code computes a value on demand. Referring to such variables in a -breakpoint condition is a convenient way to conditionalize breakpoints -in novel ways. - -To summarize: in libgdb, the gdb command language is turned into a -debugging server. The server takes commands as input, and the server's -output is redirectable. An application uses libgdb by formatting -debugging commands and invoking the interpreter. The application might -maintain breakpoints, watchpoints and many kinds of hooks. An application -can define new primitives for the interpreter. - -@node Top Level, I/O, Interpreter, Top -@chapter You Provide the Top Level for the Libgdb Command Interpreter -@cindex {top level} - -When you use libgdb, your code is providing a @dfn{top level} for the -command language interpreter. The top level is significant because it -provides commands for the the interpreter to execute. In addition, the -top level is responsible for handling some kinds of errors, and -performing certain cleanup operations on behalf of the interpreter. - -@heading Initialization - -Before calling any other libgdb functions, call this: - -@deftypefun void gdb_init (void) -Perform one-time initialization for libgdb. -@end deftypefun - -An application may wish to evaluate specific gdb commands as part of its -own initialization. The details of how this can be accomplished are -explained below. - -@heading The Top-Level Loop - -There is a strong presumption in libgdb that the application has -the form of a loop. Here is what such a loop might look like: - -@example -while (gdb_still_going ()) - @{ - if (!GDB_TOP_LEVEL ()) - @{ - char * command; - gdb_start_top_loop (); - command = process_events (); - gdb_execute_command (command); - gdb_finish_top_loop (); - @} - @} -@end example - -The function @code{gdb_still_going} returns 1 until the gdb command -`quit' is run. - -The macro @code{GDB_TOP_LEVEL} invokes setjmp to set the top level error -handler. When a command results in an error, the interpreter exits with -a longjmp. There is nothing special libgdb requires of the top level -error handler other than it be present and that it restart the top level -loop. Errors are explained in detail in a later chapter. - -Each time through the top level loop two important things happen: a -debugger command is constructed on the basis of user input, and the -interpreter is invoked to execute that command. In the sample code, the -call to the imaginary function @code{process_events} represents the -point at which a graphical interface should read input events until -ready to execute a debugger command. The call to -@code{gdb_execute_command} invokes the command interpreter (what happens -to the output from the command will be explained later). - -Libgdb manages some resources using the top-level loop. The primary -reason for this is error-handling: even if a command terminates with an -error, it may already have allocated resources which need to be freed. -The freeing of such resources takes place at the top-level, regardless -of how the the command exits. The calls to @code{gdb_start_top_loop} -and @code{gdb_finish_top_loop} let libgdb know when it is safe to -perform operations associated with these resources. - -@heading Breakpoint Commands - -Breakpoint commands are scripts of GDB operations associated with -particular breakpoints. When a breakpoint is reached, its associated -commands are executed. - -Breakpoint commands are invoked by the libgdb function -@code{gdb_finish_top_loop}. - -Notice that if control returns to the top-level error handler, the -execution of breakpoint commands is bypassed. This can happen as a -result of errors during either @code{gdb_execute_command} or -@code{gdb_finish_top_loop}. - -@heading Application Initialization - -Sometimes it is inconvenient to execute commands via a command loop for -example, the commands an application uses to initialize itself. An -alternative to @code{execute_command} is @code{execute_catching_errors}. -When @code{execute_catching_errors} is used, no top level error handler -need be in effect, and it is not necessary to call -@code{gdb_start_top_loop} or @code{gdb_finish_top_loop}. - - -@heading Cleanup - -The debugger command ``quit'' performs all necessary cleanup for libgdb. -After it has done so, it changes the return value of -@code{gdb_still_going} to 0 and returns to the top level error handler. - - -@node I/O, Invoking, Top Level, Top -@comment node-name, next, previous, up -@chapter How the Server's I/O Can be Used -@cindex I/O - -In the last chapter it was pointed out that a libgdb application is -responsible for providing commands for the interpreter to execute. -However some commands require further input (for example, the ``quit'' -command might ask for confirmation). Almost all commands produce output -of some kind. The purpose of this section is to explain how libgdb -performs its I/O, and how an application can take advantage of -this. - - -@heading I/O Vectors - -Libgdb has no fixed strategy for I/O. Instead, all operations are -performed by functions called via structures of function pointers. -Applications supply theses structures and can change them at any -time. - -@deftp Type {struct gdb_input_vector} -@deftpx Type {struct gdb_output_vector} -These structures contain a set of function pointers. Each function -determines how a particular type of i/o is performed. The details of -these strucutres are explained below. - -The application allocates these structures, initializes them to all bits -zero, fills in the function pointers, and then registers names for them -them with libgdb. -@end deftp - -@deftypefun void gdb_name_input_vector (@var{name}, @var{vec}) -@deftypefunx void gdb_remove_input_vector (@var{name}, @var{vec}) -@deftypefunx void gdb_name_output_vector (@var{name}, @var{vec}) -@deftypefunx void gdb_remove_input_vector (@var{name}, @var{vec}) -@example - char * @var{name}; - struct gdb_output_vector * @var{vec}; -@end example -These functions are used to give and remove names to i/o vectors. Note -that if a name is used twice, the most recent definition applies. -@end deftypefun - - - -@subheading Output - -An output vector is a structure with at least these fields: - -@example -struct gdb_output_vector -@{ - /* output */ - void (*put_string) (struct gdb_output_vector *, char * str); -@} -@end example - -Use the function @code{memset} or something equivalent to initialize an -output vector to all bits zero. Then fill in the function pointer with -your function. - -A debugger command can produce three kinds of output: error messages -(such as when trying to delete a non-existent breakpoint), informational -messages (such as the notification printed when a breakpoint is hit), -and the output specifically requested by a command (for example, the -value printed by the ``print'' command). At any given time, then, -libgdb has three output vectors. These are called the @dfn{error}, -@dfn{info}, @dfn{value} vector respectively. - -@subheading Input - -@example -struct gdb_input_vector -@{ - int (*query) (struct gdb_input_vector *, - char * prompt, - int quit_allowed); - int * (*selection) (struct gdb_input_vector *, - char * prompt, - char ** choices); - char * (*read_string) (struct gdb_input_vector *, - char * prompt); - char ** (*read_strings) (struct gdb_input_vector *, - char * prompt); -@} -@end example - -Use the function @code{memset} or something equivalent to initialize an -input vector to all bits zero. Then fill in the function pointers with -your functions. - -There are four kinds of input requests explicitly made by libgdb. - -A @dfn{query} is a yes or no question. The user can respond to a query -with an affirmative or negative answer, or by telling gdb to abort the -command (in some cases an abort is not permitted). Query should return -'y' or 'n' or 0 to abort. - -A @dfn{selection} is a list of options from which the user selects a subset. -Selections should return a NULL terminated array of integers, which are -indexes into the array of choices. It can return NULL instead to abort -the command. The array returned by this function will be passed to -@code{free} by libgdb. - -A @dfn{read_string} asks the user to supply an arbitrary string. It may -return NULL to abort the command. The string returned by @code{read_string} -should be allocated by @code{malloc}; it will be freed by libgdb. - -A @dfn{read_strings} asks the user to supply multiple lines of input -(for example, the body of a command created using `define'). It, too, -may return NULL to abort. The array and the strings returned by this -function will be freed by libgdb. - -@heading I/O Redirection from the Application Top-Level - -@deftypefun struct gdb_io_vecs gdb_set_io (struct gdb_io_vecs *) -@example - -struct gdb_io_vecs -@{ - struct gdb_input_vector * input; - struct gdb_output_vector * error; - struct gdb_output_vector * info; - struct gdb_output_vector * value; -@} -@end example - -This establishes a new set of i/o vectors, and returns the old setting. -Any of the pointers in this structure may be NULL, indicating that the -current value should be used. - -This function is useful for setting up i/o vectors before any libgdb -commands have been invoked (hence before any input or output has taken -place). -@end deftypefun - -It is explained in a later chapter how to redirect output temporarily. -(@xref{Invoking}.) - -@heading I/O Redirection in Debugger Commands - -A libgdb application creates input and output vectors and assigns them names. -Which input and output vectors are used by libgdb is established by -executing these debugger commands: - -@defun {set input-vector} name -@defunx {set error-output-vector} name -@defunx {set info-output-vector} name -@defunx {set value-output-vector} name -Choose an I/O vector by name. -@end defun - - -A few debugger commands are for use only within commands defined using -the debugger command `define' (they have no effect at other times). -These commands exist so that an application can maintain hooks which -redirect output without affecting the global I/O vectors. - -@defun with-input-vector name -@defunx with-error-output-vector name -@defunx with-info-output-vector name -@defunx with-value-output-vector name -Set an I/O vector, but only temporarily. The setting has effect only -within the command definition in which it occurs. -@end defun - - -@heading Initial Conditions - -When libgdb is initialized, a set of default I/O vectors is put in -place. The default vectors are called @code{default-input-vector}, -@code{default-output-vector}, &c. - -The default query function always returns `y'. Other input functions -always abort. The default output functions discard output silently. - - -@node Invoking, Defining Commands, I/O, Top -@chapter Invoking the Interpreter, Executing Commands -@cindex {executing commands} -@cindex {invoking the interpreter} - -This section introduces the libgdb functions which invoke the command -interpreter. - -@deftypefun void gdb_execute_command (@var{command}) -@example -char * @var{command}; -@end example -Interpret the argument debugger command. An error handler must be set -when this function is called. (@xref{Top Level}.) -@end deftypefun - -It is possible to override the current I/O vectors for the duration of a -single command: - -@deftypefun void gdb_execute_with_io (@var{command}, @var{vecs}) -@example -char * @var{command}; -struct gdb_io_vecs * @var{vecs}; - -struct gdb_io_vecs -@{ - struct gdb_input_vector * input; - struct gdb_output_vector * error; - struct gdb_output_vector * info; - struct gdb_output_vector * value; -@} -@end example - -Execute @var{command}, temporarily using the i/o vectors in @var{vecs}. - -Any of the vectors may be NULL, indicating that the current value should -be used. An error handler must be in place when this function is used. -@end deftypefun - -@deftypefun {struct gdb_str_output} gdb_execute_for_strings (@var{cmd}) -@example -char * cmd; -@end example -@deftypefunx {struct gdb_str_output} gdb_execute_for_strings2 (@var{cmd}, @var{input}) -@example -char * cmd; -struct gdb_input_vector * input; -@end example -@page -@example -struct gdb_str_output -@{ - char * error; - char * info; - char * value; -@}; -@end example - -Execute @var{cmd}, collecting its output as strings. If no error -occurs, all three strings will be present in the structure, the -empty-string rather than NULL standing for no output of a particular -kind. - -If the command aborts with an error, then the @code{value} field will be -NULL, though the other two strings will be present. - -In all cases, the strings returned are allocated by malloc and should be -freed by the caller. - -The first form listed uses the current input vector, but overrides the -current output vector. The second form additionally allows the input -vector to be overridden. - -This function does not require that an error handler be installed. -@end deftypefun - -@deftypefun void execute_catching_errors (@var{command}) -@example -char * @var{command}; -@end example -Like @code{execute_command} except that no error handler is required. -@end deftypefun - -@deftypefun void execute_with_text (@var{command}, @var{text}) -@example -char * @var{command}; -char ** @var{text}; -@end example -Like @code{execute_catching_errors}, except that the input vector is -overridden. The new input vector handles only calls to @code{query} (by -returning 'y') and calls to @code{read_strings} by returning a copy of -@var{text} and the strings it points to. - -This form of execute_command is useful for commands like @code{define}, -@code{document}, and @code{commands}. -@end deftypefun - - - -@node Defining Commands, Variables, Invoking, Top -@comment node-name, next, previous, up -@chapter How New Commands are Created -@cindex {commands, defining} - -Applications are, of course, free to take advantage of the existing GDB -macro definition capability (the @code{define} and @code{document} -functions). - -In addition, an application can add new primitives to the GDB command -language. - -@deftypefun void gdb_define_app_command (@var{name}, @var{fn}, @var{doc}) -@example -char * @var{name}; -gdb_cmd_fn @var{fn}; -char * @var{doc}; - -typedef void (*gdb_cmd_fn) (char * args); -@end example - -Create a new command call @var{name}. The new command is in the -@code{application} help class. When invoked, the command-line arguments -to the command are passed as a single string. - -Calling this function twice with the same name replaces an earlier -definition, but application commands can not replace builtin commands of -the same name. - -The documentation string of the command is set to a copy the string -@var{doc}. -@end deftypefun - -@node Variables, Asynchronous, Defining Commands, Top -@comment node-name, next, previous, up -@chapter How Builtin Variables are Defined -@cindex {variables, defining} - -Convenience variables provide a way for values maintained by libgdb to -be referenced in expressions (e.g. @code{$bpnum}). Libgdb includes a -means by which the application can define new, integer valued -convenience variables: -@page -@deftypefun void gdb_define_int_var (@var{name}, @var{fn}, @var{fn_arg}) -@example -char * @var{name}; -int (*@var{fn}) (void *); -void * @var{fn_arg}; -@end example -This function defines (or undefines) a convenience variable called @var{name}. -If @var{fn} is NULL, the variable becomes undefined. Otherwise, -@var{fn} is a function which, when passed @var{fn_arg} returns the value -of the newly defined variable. - -No libgdb functions should be called by @var{fn}. -@end deftypefun - -One use for this function is to create breakpoint conditions computed in -novel ways. This is done by defining a convenience variable and -referring to that variable in a breakpoint condition expression. - - -@node Asynchronous, Commands, Variables, Top -@chapter Scheduling Asynchronous Computations -@cindex asynchronous - - -A running libgdb function can take a long time. Libgdb includes a hook -so that an application can run intermittently during long debugger -operations. - -@deftypefun void gdb_set_poll_fn (@var{fn}, @var{fn_arg}) -@example -void (*@var{fn})(void * fn_arg, int (*gdb_poll)()); -void * @var{fn_arg}; -@end example -Arrange to call @var{fn} periodically during lengthy debugger operations. -If @var{fn} is NULL, polling is turned off. @var{fn} should take two -arguments: an opaque pointer passed as @var{fn_arg} to -@code{gdb_set_poll_fn}, and a function pointer. The function pointer -passed to @var{fn} is provided by libgdb and points to a function that -returns 0 when the poll function should return. That is, when -@code{(*gdb_poll)()} returns 0, libgdb is ready to continue @var{fn} -should return quickly. - -It is possible that @code{(*gdb_poll)()} will return 0 the first time it -is called, so it is reasonable for an application to do minimal processing -before checking whether to return. - -No libgdb functions should be called from an application's poll function, -with one exception: @code{gdb_request_quit}. -@end deftypefun - - -@deftypefun void gdb_request_quit (void) -This function, if called from a poll function, requests that the -currently executing libgdb command be interrupted as soon as possible, -and that control be returned to the top-level via an error. - -The quit is not immediate. It will not occur until at least after the -application's poll function returns. -@end deftypefun - -@node Commands, Top, Asynchronous, Top -@comment node-name, next, previous, up -@chapter Debugger Commands for Libgdb Applications - -The debugger commands available to libgdb applications are the same commands -available interactively via GDB. This section is an overview of the -commands newly created as part of libgdb. - -This section is not by any means a complete reference to the GDB command -language. See the GDB manual for such a reference. - -@menu -* Command Hooks:: Setting Hooks to Execute With Debugger Commands. -* View Commands:: View Commands Mirror Show Commands -* Breakpoints:: The Application Can Have Its Own Breakpoints -@end menu - -@node Command Hooks, View Commands, Commands, Commands -@comment node-name, next, previous, up -@section Setting Hooks to Execute With Debugger Commands. - -Debugger commands support hooks. A command hook is executed just before -the interpreter invokes the hooked command. - -There are two hooks allowed for every command. By convention, one hook -is for use by users, the other is for use by the application. - -A user hook is created for a command XYZZY by using -@code{define-command} to create a command called @code{hook-XYZZY}. - -An application hook is created for a command XYZZY by using -@code{define-command} to create a command called @code{apphook-XYZZY}. - -Application hooks are useful for interfaces which wish to continuously -monitor certain aspects of debugger state. The application can set a -hook on all commands that might modify the watched state. When the hook -is executed, it can use i/o redirection to notify parts of the -application that previous data may be out of date. After the top-level loop -resumes, the application can recompute any values that may have changed. -(@xref{I/O}.) - -@node View Commands, Breakpoints, Command Hooks, Commands -@comment node-name, next, previous, up -@section View Commands Mirror Show Commands - -The GDB command language contains many @code{set} and @code{show} -commands. These commands are used to modify or examine parameters to -the debugger. - -It is difficult to get the current state of a parameter from the -@code{show} command because @code{show} is very verbose. - -@example -(gdb) show check type -Type checking is "auto; currently off". -(gdb) show width -Number of characters gdb thinks are in a line is 80. -@end example - -For every @code{show} command, libgdb includes a @code{view} command. -@code{view} is like @code{show} without the verbose commentary: - -@example -(gdb) view check type -auto; currently off -(gdb) view width -80 -@end example - -(The precise format of the ouput from @code{view} is subject to change. -In particular, @code{view} may one-day print values which can be used as -arguments to the corresponding @code{set} command.) - -@node Breakpoints, Structured Output, View Commands, Commands -@comment node-name, next, previous, up -@section The Application Can Have Its Own Breakpoints - -The GDB breakpoint commands were written with a strong presumption that -all breakpoints are managed by a human user. Therefore, the command -language contains commands like `delete' which affect all breakpoints -without discrimination. - -In libgdb, there is added support for breakpoints and watchpoints which -are set by the application and which should not be affected by ordinary, -indiscriminate commands. These are called @dfn{protected} breakpoints. - -@deffn {Debugger Command} break-protected ... -@deffnx {Debugger Command} watch-protected ... -These work like @code{break} and @code{watch} except that the resulting -breakpoint is given a negative number. Negative numbered breakpoints do -not appear in the output of @code{info breakpoints} but do in that of -@code{info all-breakpoints}. Negative numbered breakpoints are not -affected by commands which ordinarily affect `all' breakpoints (e.g. -@code{delete} with no arguments). - -Note that libgdb itself creates protected breakpoints, so programs -should not rely on being able to allocate particular protected -breakpoint numbers for themselves. -@end deffn - -More than one breakpoint may be set at a given location. Libgdb adds -the concept of @dfn{priority} to breakpoints. A priority is an integer, -assigned to each breakpoint. When a breakpoint is reached, the -conditions of all breakpoints at the same location are evaluated in -order of ascending priority. When breakpoint commands are executed, -they are also executed in ascending priority (until all have been -executed, an error occurs, or one set of commands continues the -target). - -@deffn {Debugger Command} priority n bplist -Set the priority for breakpoints @var{bplist} to @var{n}. -By default, breakpoints are assigned a priority of zero. -@end deffn - -@node Structured Output, Commands, Breakpoints, Commands -@comment node-name, next, previous, up -@section Structured Output, The @code{Explain} Command - -(This section may be subject to considerable revision.) - -When GDB prints a the value of an expression, the printed representation -contains information that can be usefully fed back into future commands -and expressions. For example, - -@example -(gdb) print foo -$16 = @{v = 0x38ae0, v_length = 40@} -@end example - -On the basis of this output, a user knows, for example, that -@code{$16.v} refers to a pointer valued @code{0x38ae0} - -A new output command helps to make information like this available to -the application. - -@deffn {Debugger Command} explain expression -@deffnx {Debugger Command} explain /format expression -Print the value of @var{expression} in the manner of the @code{print} -command, but embed that output in a list syntax containing information -about the structure of the output. -@end deffn - -As an example, @code{explain argv} might produce this output: - -@example -(exp-attribute - ((expression "$19") - (type "char **") - (address "48560") - (deref-expression "*$19")) - "$19 = 0x3800\n") -@end example - -The syntax of output from @code{explain} is: - -@example - := - | (exp-concat *) - | (exp-attribute ) - - := ( * ) - - := ( ) -@end example - -The string-concatenation of all of the @code{} (except -those in property lists) yields the output generated by the equivalent -@code{print} command. Quoted strings may contain quotes and backslashes -if they are escaped by backslash. "\n" in a quoted string stands for -newline; unescaped newlines do not occur within the strings output by -@code{explain}. - -Property names are made up of alphabetic characters, dashes, and -underscores. - -The set of properties is open-ended. As GDB acquires support for new -source languages and other new capabilities, new property types may be -added to the output of this command. Future commands may offer -applications some selectivity concerning which properties are reported. - -The initial set of properties defined includes: - -@itemize @bullet -@item @code{expression} - -This is an expression, such as @code{$42} or @code{$42.x}. The -expression can be used to refer to the value printed in the attributed -part of the string. - -@item @code{type} - -This is a user-readable name for the type of the attributed value. - -@item @code{address} - -If the value is stored in a target register, this is a register number. -If the value is stored in a GDB convenience variable, this is an integer -that is unique among all the convenience variables. Otherwise, this is -the address in the target where the value is stored. - -@item @code{deref-expression} - -If the attributed value is a pointer type, this is an expression that -refers to the dereferenced value. -@end itemize - -Here is a larger example, using the same object passed to @code{print} -in an earlier example of this section. - -@example -(gdb) explain foo -(exp-attribute - ( (expression "$16") - (type "struct bytecode_vector") - (address 14336) ) - (exp-concat - "$16 = @{" - (exp-attribute - ( (expression "$16.v") - (type "char *") - (address 14336) - (deref-expression "*$16.v") ) - "v = 0x38ae0") - (exp-attribute - ( (expression "$16.v_length") - (type "int") - (address 14340) ) - ", v_length = 40") - "@}\n")) -@end example - -It is undefined how libgdb will indent these lines of output or -where newlines will be included. - -@bye diff --git a/contrib/gdb/gdb/doc/refcard.dvi b/contrib/gdb/gdb/doc/refcard.dvi deleted file mode 100644 index e152395d31db024bdbcf82bfe7ac05fcc86b488c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21732 zcmcIseXJZ;b$@mslsKU@Aq^j)O_K=hv3Np zi+^?WiG?e%n}074yRB1u_x;_ycfa%T%O1G%eGk0r@Vm|NBljFRe&p!kBO5RO$OkXI z>`x8_pI^9~i}CkmVK;l*Q&?`^zwz877oseW)5N@WxcT$?$Z!Ui8q4B~i@PL2$Fur}#%N~3DtEpMZOwcVaExh|*J~*h(#*%FBo(m67LX&1D zy72IDIOIvMX@Bj~Wq)m+I9>rGRkx4YQLDegqnc1JJUHs-ak5f|X%@Bn-CpSf96otf zO~ANC+Hm5PooIaE!o!p0ei9boP<`?!j|#H7l|{kH-kIC4PvhjwH=Zp_P?&1D!I^Pl z2u83Te#WtAob?lXMv$F({HrUSI4^w4MtKora>4*$(|%@pS-O%1UBXYGU>7j62tXTPPHPyn()vA5~d08D!`(CL{z|(1QIe+ zBsT#h9)Kh|B|PfHNwjG4BI@m^ zoi&(-+BXTdcd)Ud)NAE|6;OofZi<sx{B;D4!NKi*7`07{Dgg0rysrJV23Q`v zdG$M<^Las9mX=ndPOouV9%iwSqGyUlF%+pud%ShRl+Ek@_*uv9RKz^X?nnEvulCWY zShNG|K4^kYo|^HaW&|?EN8Wpn8SRW#%=qw9d$db%z2X(uSGd0G=>12IAAjK3{T`lJ zPW-SV9PKhily&1IC?XT~vkW$ocRy5XxClFCSpsX>=B^?&PPvtPA?}78dxO)Wd!xcB z(XWz2wH8e=jHW_3)d^sYbKW<5@Ras&pQumBl^!W+5-pLxgwl@4e&w@S26G%N6DLlt zZvSxe)z8)@rUnlKrj&bUC|nV%;@~eD*3vw3Dhm4~oX8B|T4?Kzsjc&PVC|)6^t`jG zi#269^o}+6c%}$2=K?v`G`Mn6Rmvsod$!W=MoC#%=1>}d0@nQPqm}*u@@Z0i>GB;< zwC=1t8N6sW-n-|E2Oi({h0h-_2ZkG0KXB9d?UOiJ=IZgC69fy(b8&)x`A$G^iW3AD zP&NrLEIM#)aTbL|)E1-=9Mq=wWZda^!1+%y-BV0D81DN_y{RY$BENRD=I!n0qC6A) zYDPg0)7yp>M5SjP!I=DrW}famn5Q5Y|aZ}G%uMpV!(!4gk` z-4ayP?G+I2pcW#`jEb)&IA2ZI=Ri`22gfpCXkoR$6lDcq7DANxECXDey-tq96B($` zTAZbc=#o0mEDl;TE`aE84}h7;THyO&52EjUw}kBWdsn~;!vTl%GF(NUfl)zvBRXn_ zFQ}ID6yMTff{n`XdSo5!%N z3L5*oVZgH*Br6fIUxz_H3A#$X8)-Hui?p2JUp%E2TyLGX28znqa&!!=02HBr7D97p zH#ix|jj!*v2Z^BvaeQdZb)y@bdvizIB<%XRc`AorO8dBx>O_N%)B4B0y}!s$Z|u0^OEt0^ufOBdPeGrI=okbSKlT(7 zpuLO44ga%m(cr&tG535L$wwAN=0v(&0Izi%Cj{S967_)If6=@v33qS2>I+XCJNNDV zbh{E&!tW&pfo;iv6`9eWAu~F=@bvE=`kjUC$SW3JcW(H^_Pciec=|_(SJSAo3zNx> z7vHJz`}>|j{C*C3O->AH$9`?&xhpONMOd!(&dAe}^k4btGqhu}cPz0#NWd^

RSvcWTs3ybQ!@ zoWx2iLWPhrMY_+_0`8fKH0>M@ko5-*953CXSznD31Du$ou4;HAmRq4`m0nL+N{Gx# zbjk-_@e!P(`*rzTZo0VS1j!7nvDX*dIu@;po2m2QhE@e;9lipq4D5we1B?Xe3|Q(^ zxMqxpdRW1pk1=lD;ahJt@Mi5!lu2Y2oeCof+0BG|Y`mtNKropSQ=!;rffp{cqbn08 zZ=Q&0-Uz8SZw`>q{``Q}OVB_|DU>@<9;~nvxzI(~){Z(+A*S9(f>tKy)t`5Zru3T- zr;ICv>f<^844PLtgF!qzDpE5RY(_gJ4RmE7dx_>8A{O4WTJuj)N}y~x!uBwdbQZYz z{MC(?grs>pr-7cU3QReTFO*8zR=Tp&L;(!X!zpZD@nNaODGm1iY;lfWuIjq=Ui3kp zaHE75bp8SQ?EeBjVWbII33E2Zt(SDj=pfQdv1pbi+?u z>T=96dYj1UJhK|FBnZ=pJ1l+3B)gy3B8c9!dcpKfGce_gsO{KIW>myotw4RwJHXWg zDBnp!o-I5(*>~Z=aUOS~ghfmHlLC_J4XO*0R#g#&7t6BfJiXM6qBY!@h}RJ~IKlV` z^V(V}M{zEWpoAOP&2naijE%hLrbcL-n=1mEcLGY10@H0p*10OT6f*b~{~{Dm<9>;vlqBXwEuU z51(upS^7$9r_u=vMLMTVdZW&%c)|(G7M2WaCRJf*Gp=?Hxvp{O4Y$PzaXCZ+YS4sE zd_A%qoKA|w)K*IrQip|I{75KXiZ3P3eUvNV1WVW;&E}`uzWE0SX7bbK zk9B^!?R(#S!$n&jO+`-+r_y`N($4Tn+iyF|RbxcpAgb?tu(Rk;KnCry!rou+k#c5iAlw_4lSLnvGNLBdGdFCNZVtH6gj9r(=vFYI@kMMJW;9o%3JXUK^$%7>~CSsqf zqCUZl0rb|0x!&V^ZSWW=aX8O_yyXV*>ICd|45}2$!>j7CHQ7Wcb6DZnl+1bNv5C9M zCNK!+PP6DmaYz_cS!`htqNG@gaxhn&6e(i}_k{GiGTL%6P`u{Red+H&pM)QtfXq&q zq{e>NO|s@h&RUL>I9~-4G;vM1bnbxbOqliN))iz?(a*H~rM6a}>91C}%q^QJi(wPJ zY5)c6PFk>R9>Dv1a#M*zwj>t$1&TIeB=xAOwJQe=H?MhG(+j~ShaJ#afJxG4^Pr|N z%F!tyL<=6-kn}Bdi<#u;!J&!)jbAq7J<2%Oc~-0S2-@@{bRtQY(--%vmUs}oYA@}1 z4@T&bGr2)q0oDs5<4qg6aHWjcuscgLkV;Z19=L*xy60yBo#ipwQgDYzp>+K#uJ}@& zjW|}?;OGpJa(Ql~Vb88e9ewg1#l=B`Mv6Nb-i=#=4qTsjDBJM&9WfPolPyER9Vav|FWov67W=^h;ra;|+y8fRy>{ph>5j$H{v zZpmtNDriGu-GF^7n>))g7pBWH>Qf|5fccC2*jot*y@?lCp8CrrAS!0gXUtH6Y@rdH z4e*PPVc@T@QLmK0gI1n)5PM6vEQ>m@Iubif?RN!Pp->E8fbk8e#?(67E>yE(gBxn+ zbbRBAgCca==^44t=yE4M3G*a+JQjsAqZXBzJV7J{*J>5I9GLN18dE64O*=;;3VNzK z(Azs8R|ENXaADZc&$ zNeIHMg=;md?bWHJx#l|C=j~*SIzP1K#Odf%K;lELTf1z!BA0N5fSviSa*{wj(C3wg zd5KG6FLL1c3rwW7uHd0;0~58&x^}LDzxsErv!El!QdSgoX@as5`T~D$nH?@g(&_lq9PIQIS~}!`1jn_AkRzDGi|kfNJ>xzd6YB&^`!v?% zkl4;DkD%CG8%C$|c5#~q1y_HT8Y>-biN!V+p8mo3t_doRAdnB(q1W?+EK||4{DlR$ zNu5Z>DsnAEVL~opK;_asnN_2eAhZ0r9U1pLFiC6}t7i~RF9ef9jU5Mt!gUSiO{JLv z+BxVcFs-xY=)#wmC&i%0Q1Z(wuCC+oM?xx6bruOh5z*3#8p%*?v}z$J>{sn~oEhJY zUmP%3;=}Y$q-I`~q#Tq8c%8i=2p3}$z46WN(vaF@RIKvu>P~kD{k@{Oy3s$pv7zD^ zr$M1fYjN5ahsqsl=PiU6e|Cvhzd2co1(^nOdSl_Yho4wjSYBS({;5Cb8IC86Nr{b% zCTytD);vUl%^IJZr{JJfx$&d9U>!pQbRDbQeEQ6XGP|LD5AmphgU`+39WA+FN;Qci zbTx!$jI4F22J?!Ta#%sHQgdyMs|BL-eZoR`6b;H5cC$uSw?;&Jy|`WC^Syg2O>m7Q zHz&dy0%fo{o>L+Jg0vOmzIGIw5;jsy$JwbD{FGt=Y^%nrIJk+(QkAu0I%GHU@# zu9jCQtLlWf5Yn2b{daQp94R^^m{Q3HIwO&GB&|e)06r75aO9Zl8#chw@JOZ7HH%#m z?brsogtH0j?28zA!X=ilm)2Kryfa=o#4M%_Jdh9{HG%nEWzBKVUwc9k0x}+k)qnG?{ZhA^?zD;K zhB#GA4;b+9PedKJ+eRW~k+H|>sWd)rBtT+{dF?JYXCwTs8f9|m^Y_U-TGEiSvr;|r zsNosB$l&eT6!#dD|SH~wQ6sPw2uG;?I6xG^fVN)>nV5$ z5^4XqK1n4X_jXkC^U{?ii{!j{o0&~`JCSgTkF1MyoLUglrVpLk*_M_U%K(I7H4CIR zxAox3yyIY&IRClMtB5(KepX^2o^!_>$yDZ+^G}}wRG&_eG}lN({TXTGM>$3dr-3o( zaY45}^U?D>OCe)NF!y%VqFg7Hrlt{0*hp+W&3-rEJ>tt8)IfD>*-C`bnpz9-vIu?= z1%fd>$62Lb8DynQUONW|Pny`qD#*|+OjjXT7Qh#oA;KN;EdmL(ZQxm7HL5gm(5)W- z>qw0f2-IoB9nxCrVo9`WNI`)Hv(7&C;GE#5o(EIcZ>iBEe`;Vf-=VF9%RNT{EDCg( z+)^oqQB9>(-P!GuKdy=P(+_zbuKH#$CDm&>&X8;CA4OdkR#luEyE*QE-Tn%1xG-1 zzVsMQuTCZYNY8P8k;2=dfQ7kHIJ=S+>k`>g8~+D9V0}a)XBWPA{1)^MyO@YTxmb*5 zC+@m;Xq4zi5-Q{`8$?8Tu!49KmO`p%{hW2JItUX6RCNP;OtKtjQlpuq$!+NlpZ+?L zM(6})$ju8;8h|z7)bpc#l*IjlnSjKr4uzHHEJ)lSN(S0Pq{no|TJyIqLSBGDg+V}& zsUAyKSs1hY=viCYu{<`FJ9UZxO;2%~(M?$r?dEQu_yvaZG|pUYX$j!y}M7SdxF z0Ut^V4u`0_O8{ld`eNzO6R4(4Y}~e%H(xugC2|O=Q@kwW`GF80_ndU(B!dMwAmZ>~>?cl^1k9 zi;FF=K4d+g+)Eh^ZN+Vb5Phvqxi26(W!(~^+a&>`+G)4s(S_Phr@gJ?u`|CumT}c&UQEM&G@(N0KS7Vl!*li4m_V zSGmHO)(BvQ!8e_ULs;ahH0q6A5nD7=+T*Mn4(4*O+e4HmqCv1zaPAI0I-DuILmDkC z-cVAdrGy27Lt(6+ z>buNM3#Vk|-6g=DbGSQ^$8(|_&_I-hM%KB0$dY%mH|#(R(8b0}htzhL4|+n=x+|Jz zXs^GBFrq5l*7e%CUAJ0fY3mV0#dApWm4c)p2#QgOYF9M~O~2CCnPfjf%oQ6v2;O#_ zqY+vtAluZbgKGnMkDjp;ltTsB=0N$3^%j{(g<%fbH8|0>W%eEsQ$elm8$WaLTq|1C ztvOcEj<#B0WCY&XD;S%(S`~5$MEZIqFe+{}mv81UGNgp9Y2cE|z~UM7PU>NX#rTxibt}>_*pbKwkN#%9a7JNH~%y^r4H%r`1Y3*x1O>Q4_W|l6GB;XAh zB!M#O8U`6(q8AW?Xk*Tt-ghfRT=Re^N}$EX{H}$J0z-G@-49q-o#U8|-|b6SO^6;LEV}Az z1yi_z1Q;ZE57!2ANdfPTt4L7w8dpzE1Y0po@2dAu!Lqz$MrU*OGREbR5Zb?uhy*n( z#jCCjsGvh=y@^ zyft#R=QhMB7ii9EdP%_u9Gqt5T0tO}mZq?9-ly&+I#62xkO4oZ^4<^#0Ewlr-0+)U zx&^7VE8${LkP5;fwjkGxfehz?#(ZIStNpcD(iecT)yyVYMucqof_fCQL9vwe7^XU$hN4WC$BPq}a*Lc< zKO`hV#E_v}BmIA=BYH4g>rJ0d$c z2wJfD5)9V;NKf<_4~B1mVUSq?N#9X7z~>bdEll{JAXWlI+1T#ia|{KDF|691GvJ|v z5-UNq@SPzlgU3nRO!0SX-$rM)P;#OMNG;Udd-MTw1es0UxzjTWxI?l^zdu~=%!_RT0r+LHH6|`0bos8RAlFvKiMjt%UMMv z_bnyMjKg>((P*dcS*e~-nSF$#DkXW8Yd%7>4j zqZqB0chC?-z_y>!BJcFJokb9VK8BKne0*^k0huXgPm_bt;j_OKjd z{98*%U*00>v)lP9*v!#~RYl(9LkZKK3&wQ9jeX@z2UB_`RpYsca4e6q0uFY)o$a&??+V@1-S7mvxM$nn?|KvXLE=!eUqyNoH-(X z6*s4^nI%NF4viDtG=+XS5gv}EVA0J_{bXU`mXG;g|KvA2w?F-vAK@FA+vk6-bMB`w qFU|XS=B2q`?Cd0)?*`|ZttUsyQtpWDB$fBpyTeqaFr diff --git a/contrib/gdb/gdb/doc/remote.texi b/contrib/gdb/gdb/doc/remote.texi deleted file mode 100644 index 816b65837de..00000000000 --- a/contrib/gdb/gdb/doc/remote.texi +++ /dev/null @@ -1,1708 +0,0 @@ -@c -*- Texinfo -*- -@c Copyright (c) 1990 1991 1992 1993 Free Software Foundation, Inc. -@c This file is part of the source for the GDB manual. -@c This text diverted to "Remote Debugging" section in general case; -@c however, if we're doing a manual specifically for one of these, it -@c belongs up front (in "Getting In and Out" chapter). - -@ifset REMOTESTUB -@node Remote Serial -@subsection The @value{GDBN} remote serial protocol - -@cindex remote serial debugging, overview -To debug a program running on another machine (the debugging -@dfn{target} machine), you must first arrange for all the usual -prerequisites for the program to run by itself. For example, for a C -program, you need: - -@enumerate -@item -A startup routine to set up the C runtime environment; these usually -have a name like @file{crt0}. The startup routine may be supplied by -your hardware supplier, or you may have to write your own. - -@item -You probably need a C subroutine library to support your program's -subroutine calls, notably managing input and output. - -@item -A way of getting your program to the other machine---for example, a -download program. These are often supplied by the hardware -manufacturer, but you may have to write your own from hardware -documentation. -@end enumerate - -The next step is to arrange for your program to use a serial port to -communicate with the machine where @value{GDBN} is running (the @dfn{host} -machine). In general terms, the scheme looks like this: - -@table @emph -@item On the host, -@value{GDBN} already understands how to use this protocol; when everything -else is set up, you can simply use the @samp{target remote} command -(@pxref{Targets,,Specifying a Debugging Target}). - -@item On the target, -you must link with your program a few special-purpose subroutines that -implement the @value{GDBN} remote serial protocol. The file containing these -subroutines is called a @dfn{debugging stub}. - -@ifset GDBSERVER -On certain remote targets, you can use an auxiliary program -@code{gdbserver} instead of linking a stub into your program. -@xref{Server,,Using the @code{gdbserver} program}, for details. -@end ifset -@end table - -The debugging stub is specific to the architecture of the remote -machine; for example, use @file{sparc-stub.c} to debug programs on -@sc{sparc} boards. - -@cindex remote serial stub list -These working remote stubs are distributed with @value{GDBN}: - -@table @code - -@item i386-stub.c -@kindex i386-stub.c -@cindex Intel -@cindex i386 -For Intel 386 and compatible architectures. - -@item m68k-stub.c -@kindex m68k-stub.c -@cindex Motorola 680x0 -@cindex m680x0 -For Motorola 680x0 architectures. - -@item sh-stub.c -@kindex sh-stub.c -@cindex Hitachi -@cindex SH -For Hitachi SH architectures. - -@item sparc-stub.c -@kindex sparc-stub.c -@cindex Sparc -For @sc{sparc} architectures. - -@item sparcl-stub.c -@kindex sparcl-stub.c -@cindex Fujitsu -@cindex SparcLite -For Fujitsu @sc{sparclite} architectures. - -@end table - -The @file{README} file in the @value{GDBN} distribution may list other -recently added stubs. - -@menu -* Stub Contents:: What the stub can do for you -* Bootstrapping:: What you must do for the stub -* Debug Session:: Putting it all together -* Protocol:: Outline of the communication protocol -@ifset GDBSERVER -* Server:: Using the `gdbserver' program -@end ifset -@ifset GDBSERVE -* NetWare:: Using the `gdbserve.nlm' program -@end ifset -@end menu - -@node Stub Contents -@subsubsection What the stub can do for you - -@cindex remote serial stub -The debugging stub for your architecture supplies these three -subroutines: - -@table @code -@item set_debug_traps -@kindex set_debug_traps -@cindex remote serial stub, initialization -This routine arranges for @code{handle_exception} to run when your -program stops. You must call this subroutine explicitly near the -beginning of your program. - -@item handle_exception -@kindex handle_exception -@cindex remote serial stub, main routine -This is the central workhorse, but your program never calls it -explicitly---the setup code arranges for @code{handle_exception} to -run when a trap is triggered. - -@code{handle_exception} takes control when your program stops during -execution (for example, on a breakpoint), and mediates communications -with @value{GDBN} on the host machine. This is where the communications -protocol is implemented; @code{handle_exception} acts as the @value{GDBN} -representative on the target machine; it begins by sending summary -information on the state of your program, then continues to execute, -retrieving and transmitting any information @value{GDBN} needs, until you -execute a @value{GDBN} command that makes your program resume; at that point, -@code{handle_exception} returns control to your own code on the target -machine. - -@item breakpoint -@cindex @code{breakpoint} subroutine, remote -Use this auxiliary subroutine to make your program contain a -breakpoint. Depending on the particular situation, this may be the only -way for @value{GDBN} to get control. For instance, if your target -machine has some sort of interrupt button, you won't need to call this; -pressing the interrupt button transfers control to -@code{handle_exception}---in effect, to @value{GDBN}. On some machines, -simply receiving characters on the serial port may also trigger a trap; -again, in that situation, you don't need to call @code{breakpoint} from -your own program---simply running @samp{target remote} from the host -@value{GDBN} session gets control. - -Call @code{breakpoint} if none of these is true, or if you simply want -to make certain your program stops at a predetermined point for the -start of your debugging session. -@end table - -@node Bootstrapping -@subsubsection What you must do for the stub - -@cindex remote stub, support routines -The debugging stubs that come with @value{GDBN} are set up for a particular -chip architecture, but they have no information about the rest of your -debugging target machine. - -First of all you need to tell the stub how to communicate with the -serial port. - -@table @code -@item int getDebugChar() -@kindex getDebugChar -Write this subroutine to read a single character from the serial port. -It may be identical to @code{getchar} for your target system; a -different name is used to allow you to distinguish the two if you wish. - -@item void putDebugChar(int) -@kindex putDebugChar -Write this subroutine to write a single character to the serial port. -It may be identical to @code{putchar} for your target system; a -different name is used to allow you to distinguish the two if you wish. -@end table - -@cindex control C, and remote debugging -@cindex interrupting remote targets -If you want @value{GDBN} to be able to stop your program while it is -running, you need to use an interrupt-driven serial driver, and arrange -for it to stop when it receives a @code{^C} (@samp{\003}, the control-C -character). That is the character which @value{GDBN} uses to tell the -remote system to stop. - -Getting the debugging target to return the proper status to @value{GDBN} -probably requires changes to the standard stub; one quick and dirty way -is to just execute a breakpoint instruction (the ``dirty'' part is that -@value{GDBN} reports a @code{SIGTRAP} instead of a @code{SIGINT}). - -Other routines you need to supply are: - -@table @code -@item void exceptionHandler (int @var{exception_number}, void *@var{exception_address}) -@kindex exceptionHandler -Write this function to install @var{exception_address} in the exception -handling tables. You need to do this because the stub does not have any -way of knowing what the exception handling tables on your target system -are like (for example, the processor's table might be in @sc{rom}, -containing entries which point to a table in @sc{ram}). -@var{exception_number} is the exception number which should be changed; -its meaning is architecture-dependent (for example, different numbers -might represent divide by zero, misaligned access, etc). When this -exception occurs, control should be transferred directly to -@var{exception_address}, and the processor state (stack, registers, -and so on) should be just as it is when a processor exception occurs. So if -you want to use a jump instruction to reach @var{exception_address}, it -should be a simple jump, not a jump to subroutine. - -For the 386, @var{exception_address} should be installed as an interrupt -gate so that interrupts are masked while the handler runs. The gate -should be at privilege level 0 (the most privileged level). The -@sc{sparc} and 68k stubs are able to mask interrup themselves without -help from @code{exceptionHandler}. - -@item void flush_i_cache() -@kindex flush_i_cache -(sparc and sparclite only) Write this subroutine to flush the -instruction cache, if any, on your target machine. If there is no -instruction cache, this subroutine may be a no-op. - -On target machines that have instruction caches, @value{GDBN} requires this -function to make certain that the state of your program is stable. -@end table - -@noindent -You must also make sure this library routine is available: - -@table @code -@item void *memset(void *, int, int) -@kindex memset -This is the standard library function @code{memset} that sets an area of -memory to a known value. If you have one of the free versions of -@code{libc.a}, @code{memset} can be found there; otherwise, you must -either obtain it from your hardware manufacturer, or write your own. -@end table - -If you do not use the GNU C compiler, you may need other standard -library subroutines as well; this varies from one stub to another, -but in general the stubs are likely to use any of the common library -subroutines which @code{gcc} generates as inline code. - - -@node Debug Session -@subsubsection Putting it all together - -@cindex remote serial debugging summary -In summary, when your program is ready to debug, you must follow these -steps. - -@enumerate -@item -Make sure you have the supporting low-level routines -(@pxref{Bootstrapping,,What you must do for the stub}): -@display -@code{getDebugChar}, @code{putDebugChar}, -@code{flush_i_cache}, @code{memset}, @code{exceptionHandler}. -@end display - -@item -Insert these lines near the top of your program: - -@example -set_debug_traps(); -breakpoint(); -@end example - -@item -For the 680x0 stub only, you need to provide a variable called -@code{exceptionHook}. Normally you just use: - -@example -void (*exceptionHook)() = 0; -@end example - -but if before calling @code{set_debug_traps}, you set it to point to a -function in your program, that function is called when -@code{@value{GDBN}} continues after stopping on a trap (for example, bus -error). The function indicated by @code{exceptionHook} is called with -one parameter: an @code{int} which is the exception number. - -@item -Compile and link together: your program, the @value{GDBN} debugging stub for -your target architecture, and the supporting subroutines. - -@item -Make sure you have a serial connection between your target machine and -the @value{GDBN} host, and identify the serial port on the host. - -@item -@c The "remote" target now provides a `load' command, so we should -@c document that. FIXME. -Download your program to your target machine (or get it there by -whatever means the manufacturer provides), and start it. - -@item -To start remote debugging, run @value{GDBN} on the host machine, and specify -as an executable file the program that is running in the remote machine. -This tells @value{GDBN} how to find your program's symbols and the contents -of its pure text. - -@cindex serial line, @code{target remote} -Then establish communication using the @code{target remote} command. -Its argument specifies how to communicate with the target -machine---either via a devicename attached to a direct serial line, or a -TCP port (usually to a terminal server which in turn has a serial line -to the target). For example, to use a serial line connected to the -device named @file{/dev/ttyb}: - -@example -target remote /dev/ttyb -@end example - -@cindex TCP port, @code{target remote} -To use a TCP connection, use an argument of the form -@code{@var{host}:port}. For example, to connect to port 2828 on a -terminal server named @code{manyfarms}: - -@example -target remote manyfarms:2828 -@end example -@end enumerate - -Now you can use all the usual commands to examine and change data and to -step and continue the remote program. - -To resume the remote program and stop debugging it, use the @code{detach} -command. - -@cindex interrupting remote programs -@cindex remote programs, interrupting -Whenever @value{GDBN} is waiting for the remote program, if you type the -interrupt character (often @key{C-C}), @value{GDBN} attempts to stop the -program. This may or may not succeed, depending in part on the hardware -and the serial drivers the remote system uses. If you type the -interrupt character once again, @value{GDBN} displays this prompt: - -@example -Interrupted while waiting for the program. -Give up (and stop debugging it)? (y or n) -@end example - -If you type @kbd{y}, @value{GDBN} abandons the remote debugging session. -(If you decide you want to try again later, you can use @samp{target -remote} again to connect once more.) If you type @kbd{n}, @value{GDBN} -goes back to waiting. - -@node Protocol -@subsubsection Communication protocol - -@cindex debugging stub, example -@cindex remote stub, example -@cindex stub example, remote debugging -The stub files provided with @value{GDBN} implement the target side of the -communication protocol, and the @value{GDBN} side is implemented in the -@value{GDBN} source file @file{remote.c}. Normally, you can simply allow -these subroutines to communicate, and ignore the details. (If you're -implementing your own stub file, you can still ignore the details: start -with one of the existing stub files. @file{sparc-stub.c} is the best -organized, and therefore the easiest to read.) - -However, there may be occasions when you need to know something about -the protocol---for example, if there is only one serial port to your -target machine, you might want your program to do something special if -it recognizes a packet meant for @value{GDBN}. - -@cindex protocol, @value{GDBN} remote serial -@cindex serial protocol, @value{GDBN} remote -@cindex remote serial protocol -All @value{GDBN} commands and responses (other than acknowledgements, which -are single characters) are sent as a packet which includes a -checksum. A packet is introduced with the character @samp{$}, and ends -with the character @samp{#} followed by a two-digit checksum: - -@example -$@var{packet info}#@var{checksum} -@end example - -@cindex checksum, for @value{GDBN} remote -@noindent -@var{checksum} is computed as the modulo 256 sum of the @var{packet -info} characters. - -When either the host or the target machine receives a packet, the first -response expected is an acknowledgement: a single character, either -@samp{+} (to indicate the package was received correctly) or @samp{-} -(to request retransmission). - -The host (@value{GDBN}) sends commands, and the target (the debugging stub -incorporated in your program) sends data in response. The target also -sends data when your program stops. - -Command packets are distinguished by their first character, which -identifies the kind of command. - -These are some of the commands currently supported (for a complete list of -commands, look in @file{gdb/remote.c.}): - -@table @code -@item g -Requests the values of CPU registers. - -@item G -Sets the values of CPU registers. - -@item m@var{addr},@var{count} -Read @var{count} bytes at location @var{addr}. - -@item M@var{addr},@var{count}:@dots{} -Write @var{count} bytes at location @var{addr}. - -@need 500 -@item c -@itemx c@var{addr} -Resume execution at the current address (or at @var{addr} if supplied). - -@need 500 -@item s -@itemx s@var{addr} -Step the target program for one instruction, from either the current -program counter or from @var{addr} if supplied. - -@item k -Kill the target program. - -@item ? -Report the most recent signal. To allow you to take advantage of the -@value{GDBN} signal handling commands, one of the functions of the debugging -stub is to report CPU traps as the corresponding POSIX signal values. - -@item T -Allows the remote stub to send only the registers that @value{GDBN} needs -to make a quick decision about single-stepping or conditional breakpoints. -This eliminates the need to fetch the entire register set for each instruction -being stepped through. - -@value{GDBN} now implements a write-through cache for registers and only -re-reads the registers if the target has run. -@end table - -@kindex set remotedebug -@kindex show remotedebug -@cindex packets, reporting on stdout -@cindex serial connections, debugging -If you have trouble with the serial connection, you can use the command -@code{set remotedebug}. This makes @value{GDBN} report on all packets sent -back and forth across the serial line to the remote machine. The -packet-debugging information is printed on the @value{GDBN} standard output -stream. @code{set remotedebug off} turns it off, and @code{show -remotedebug} shows you its current state. - -@ifset GDBSERVER -@node Server -@subsubsection Using the @code{gdbserver} program - -@kindex gdbserver -@cindex remote connection without stubs -@code{gdbserver} is a control program for Unix-like systems, which -allows you to connect your program with a remote @value{GDBN} via -@code{target remote}---but without linking in the usual debugging stub. - -@code{gdbserver} is not a complete replacement for the debugging stubs, -because it requires essentially the same operating-system facilities -that @value{GDBN} itself does. In fact, a system that can run -@code{gdbserver} to connect to a remote @value{GDBN} could also run -@value{GDBN} locally! @code{gdbserver} is sometimes useful nevertheless, -because it is a much smaller program than @value{GDBN} itself. It is -also easier to port than all of @value{GDBN}, so you may be able to get -started more quickly on a new system by using @code{gdbserver}. -Finally, if you develop code for real-time systems, you may find that -the tradeoffs involved in real-time operation make it more convenient to -do as much development work as possible on another system, for example -by cross-compiling. You can use @code{gdbserver} to make a similar -choice for debugging. - -@value{GDBN} and @code{gdbserver} communicate via either a serial line -or a TCP connection, using the standard @value{GDBN} remote serial -protocol. - -@table @emph -@item On the target machine, -you need to have a copy of the program you want to debug. -@code{gdbserver} does not need your program's symbol table, so you can -strip the program if necessary to save space. @value{GDBN} on the host -system does all the symbol handling. - -To use the server, you must tell it how to communicate with @value{GDBN}; -the name of your program; and the arguments for your program. The -syntax is: - -@smallexample -target> gdbserver @var{comm} @var{program} [ @var{args} @dots{} ] -@end smallexample - -@var{comm} is either a device name (to use a serial line) or a TCP -hostname and portnumber. For example, to debug Emacs with the argument -@samp{foo.txt} and communicate with @value{GDBN} over the serial port -@file{/dev/com1}: - -@smallexample -target> gdbserver /dev/com1 emacs foo.txt -@end smallexample - -@code{gdbserver} waits passively for the host @value{GDBN} to communicate -with it. - -To use a TCP connection instead of a serial line: - -@smallexample -target> gdbserver host:2345 emacs foo.txt -@end smallexample - -The only difference from the previous example is the first argument, -specifying that you are communicating with the host @value{GDBN} via -TCP. The @samp{host:2345} argument means that @code{gdbserver} is to -expect a TCP connection from machine @samp{host} to local TCP port 2345. -(Currently, the @samp{host} part is ignored.) You can choose any number -you want for the port number as long as it does not conflict with any -TCP ports already in use on the target system (for example, @code{23} is -reserved for @code{telnet}).@footnote{If you choose a port number that -conflicts with another service, @code{gdbserver} prints an error message -and exits.} You must use the same port number with the host @value{GDBN} -@code{target remote} command. - -@item On the @value{GDBN} host machine, -you need an unstripped copy of your program, since @value{GDBN} needs -symbols and debugging information. Start up @value{GDBN} as usual, -using the name of the local copy of your program as the first argument. -(You may also need the @w{@samp{--baud}} option if the serial line is -running at anything other than 9600 bps.) After that, use @code{target -remote} to establish communications with @code{gdbserver}. Its argument -is either a device name (usually a serial device, like -@file{/dev/ttyb}), or a TCP port descriptor in the form -@code{@var{host}:@var{PORT}}. For example: - -@smallexample -(@value{GDBP}) target remote /dev/ttyb -@end smallexample - -@noindent -communicates with the server via serial line @file{/dev/ttyb}, and - -@smallexample -(@value{GDBP}) target remote the-target:2345 -@end smallexample - -@noindent -communicates via a TCP connection to port 2345 on host @w{@file{the-target}}. -For TCP connections, you must start up @code{gdbserver} prior to using -the @code{target remote} command. Otherwise you may get an error whose -text depends on the host system, but which usually looks something like -@samp{Connection refused}. -@end table -@end ifset - -@ifset GDBSERVE -@node NetWare -@subsubsection Using the @code{gdbserve.nlm} program - -@kindex gdbserve.nlm -@code{gdbserve.nlm} is a control program for NetWare systems, which -allows you to connect your program with a remote @value{GDBN} via -@code{target remote}. - -@value{GDBN} and @code{gdbserve.nlm} communicate via a serial line, -using the standard @value{GDBN} remote serial protocol. - -@table @emph -@item On the target machine, -you need to have a copy of the program you want to debug. -@code{gdbserve.nlm} does not need your program's symbol table, so you -can strip the program if necessary to save space. @value{GDBN} on the -host system does all the symbol handling. - -To use the server, you must tell it how to communicate with -@value{GDBN}; the name of your program; and the arguments for your -program. The syntax is: - -@smallexample -load gdbserve [ BOARD=@var{board} ] [ PORT=@var{port} ] - [ BAUD=@var{baud} ] @var{program} [ @var{args} @dots{} ] -@end smallexample - -@var{board} and @var{port} specify the serial line; @var{baud} specifies -the baud rate used by the connection. @var{port} and @var{node} default -to 0, @var{baud} defaults to 9600 bps. - -For example, to debug Emacs with the argument @samp{foo.txt}and -communicate with @value{GDBN} over serial port number 2 or board 1 -using a 19200 bps connection: - -@smallexample -load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt -@end smallexample - -@item On the @value{GDBN} host machine, -you need an unstripped copy of your program, since @value{GDBN} needs -symbols and debugging information. Start up @value{GDBN} as usual, -using the name of the local copy of your program as the first argument. -(You may also need the @w{@samp{--baud}} option if the serial line is -running at anything other than 9600 bps. After that, use @code{target -remote} to establish communications with @code{gdbserve.nlm}. Its -argument is a device name (usually a serial device, like -@file{/dev/ttyb}). For example: - -@smallexample -(@value{GDBP}) target remote /dev/ttyb -@end smallexample - -@noindent -communications with the server via serial line @file{/dev/ttyb}. -@end table -@end ifset - -@end ifset - -@ifset I960 -@node i960-Nindy Remote -@subsection @value{GDBN} with a remote i960 (Nindy) - -@cindex Nindy -@cindex i960 -@dfn{Nindy} is a ROM Monitor program for Intel 960 target systems. When -@value{GDBN} is configured to control a remote Intel 960 using Nindy, you can -tell @value{GDBN} how to connect to the 960 in several ways: - -@itemize @bullet -@item -Through command line options specifying serial port, version of the -Nindy protocol, and communications speed; - -@item -By responding to a prompt on startup; - -@item -By using the @code{target} command at any point during your @value{GDBN} -session. @xref{Target Commands, ,Commands for managing targets}. - -@end itemize - -@menu -* Nindy Startup:: Startup with Nindy -* Nindy Options:: Options for Nindy -* Nindy Reset:: Nindy reset command -@end menu - -@node Nindy Startup -@subsubsection Startup with Nindy - -If you simply start @code{@value{GDBP}} without using any command-line -options, you are prompted for what serial port to use, @emph{before} you -reach the ordinary @value{GDBN} prompt: - -@example -Attach /dev/ttyNN -- specify NN, or "quit" to quit: -@end example - -@noindent -Respond to the prompt with whatever suffix (after @samp{/dev/tty}) -identifies the serial port you want to use. You can, if you choose, -simply start up with no Nindy connection by responding to the prompt -with an empty line. If you do this and later wish to attach to Nindy, -use @code{target} (@pxref{Target Commands, ,Commands for managing targets}). - -@node Nindy Options -@subsubsection Options for Nindy - -These are the startup options for beginning your @value{GDBN} session with a -Nindy-960 board attached: - -@table @code -@item -r @var{port} -Specify the serial port name of a serial interface to be used to connect -to the target system. This option is only available when @value{GDBN} is -configured for the Intel 960 target architecture. You may specify -@var{port} as any of: a full pathname (e.g. @samp{-r /dev/ttya}), a -device name in @file{/dev} (e.g. @samp{-r ttya}), or simply the unique -suffix for a specific @code{tty} (e.g. @samp{-r a}). - -@item -O -(An uppercase letter ``O'', not a zero.) Specify that @value{GDBN} should use -the ``old'' Nindy monitor protocol to connect to the target system. -This option is only available when @value{GDBN} is configured for the Intel 960 -target architecture. - -@quotation -@emph{Warning:} if you specify @samp{-O}, but are actually trying to -connect to a target system that expects the newer protocol, the connection -fails, appearing to be a speed mismatch. @value{GDBN} repeatedly -attempts to reconnect at several different line speeds. You can abort -this process with an interrupt. -@end quotation - -@item -brk -Specify that @value{GDBN} should first send a @code{BREAK} signal to the target -system, in an attempt to reset it, before connecting to a Nindy target. - -@quotation -@emph{Warning:} Many target systems do not have the hardware that this -requires; it only works with a few boards. -@end quotation -@end table - -The standard @samp{-b} option controls the line speed used on the serial -port. - -@c @group -@node Nindy Reset -@subsubsection Nindy reset command - -@table @code -@item reset -@kindex reset -For a Nindy target, this command sends a ``break'' to the remote target -system; this is only useful if the target has been equipped with a -circuit to perform a hard reset (or some other interesting action) when -a break is detected. -@end table -@c @end group -@end ifset - -@ifset AMD29K -@node UDI29K Remote -@subsection The UDI protocol for AMD29K - -@cindex UDI -@cindex AMD29K via UDI -@value{GDBN} supports AMD's UDI (``Universal Debugger Interface'') -protocol for debugging the a29k processor family. To use this -configuration with AMD targets running the MiniMON monitor, you need the -program @code{MONTIP}, available from AMD at no charge. You can also -use @value{GDBN} with the UDI-conformant a29k simulator program -@code{ISSTIP}, also available from AMD. - -@table @code -@item target udi @var{keyword} -@kindex udi -Select the UDI interface to a remote a29k board or simulator, where -@var{keyword} is an entry in the AMD configuration file @file{udi_soc}. -This file contains keyword entries which specify parameters used to -connect to a29k targets. If the @file{udi_soc} file is not in your -working directory, you must set the environment variable @samp{UDICONF} -to its pathname. -@end table - -@node EB29K Remote -@subsection The EBMON protocol for AMD29K - -@cindex EB29K board -@cindex running 29K programs - -AMD distributes a 29K development board meant to fit in a PC, together -with a DOS-hosted monitor program called @code{EBMON}. As a shorthand -term, this development system is called the ``EB29K''. To use -@value{GDBN} from a Unix system to run programs on the EB29K board, you -must first connect a serial cable between the PC (which hosts the EB29K -board) and a serial port on the Unix system. In the following, we -assume you've hooked the cable between the PC's @file{COM1} port and -@file{/dev/ttya} on the Unix system. - -@menu -* Comms (EB29K):: Communications setup -* gdb-EB29K:: EB29K cross-debugging -* Remote Log:: Remote log -@end menu - -@node Comms (EB29K) -@subsubsection Communications setup - -The next step is to set up the PC's port, by doing something like this -in DOS on the PC: - -@example -C:\> MODE com1:9600,n,8,1,none -@end example - -@noindent -This example---run on an MS DOS 4.0 system---sets the PC port to 9600 -bps, no parity, eight data bits, one stop bit, and no ``retry'' action; -you must match the communications parameters when establishing the Unix -end of the connection as well. -@c FIXME: Who knows what this "no retry action" crud from the DOS manual may -@c mean? It's optional; leave it out? ---doc@cygnus.com, 25feb91 - -To give control of the PC to the Unix side of the serial line, type -the following at the DOS console: - -@example -C:\> CTTY com1 -@end example - -@noindent -(Later, if you wish to return control to the DOS console, you can use -the command @code{CTTY con}---but you must send it over the device that -had control, in our example over the @file{COM1} serial line). - -From the Unix host, use a communications program such as @code{tip} or -@code{cu} to communicate with the PC; for example, - -@example -cu -s 9600 -l /dev/ttya -@end example - -@noindent -The @code{cu} options shown specify, respectively, the linespeed and the -serial port to use. If you use @code{tip} instead, your command line -may look something like the following: - -@example -tip -9600 /dev/ttya -@end example - -@noindent -Your system may require a different name where we show -@file{/dev/ttya} as the argument to @code{tip}. The communications -parameters, including which port to use, are associated with the -@code{tip} argument in the ``remote'' descriptions file---normally the -system table @file{/etc/remote}. -@c FIXME: What if anything needs doing to match the "n,8,1,none" part of -@c the DOS side's comms setup? cu can support -o (odd -@c parity), -e (even parity)---apparently no settings for no parity or -@c for character size. Taken from stty maybe...? John points out tip -@c can set these as internal variables, eg ~s parity=none; man stty -@c suggests that it *might* work to stty these options with stdin or -@c stdout redirected... ---doc@cygnus.com, 25feb91 - -@kindex EBMON -Using the @code{tip} or @code{cu} connection, change the DOS working -directory to the directory containing a copy of your 29K program, then -start the PC program @code{EBMON} (an EB29K control program supplied -with your board by AMD). You should see an initial display from -@code{EBMON} similar to the one that follows, ending with the -@code{EBMON} prompt @samp{#}--- - -@example -C:\> G: - -G:\> CD \usr\joe\work29k - -G:\USR\JOE\WORK29K> EBMON -Am29000 PC Coprocessor Board Monitor, version 3.0-18 -Copyright 1990 Advanced Micro Devices, Inc. -Written by Gibbons and Associates, Inc. - -Enter '?' or 'H' for help - -PC Coprocessor Type = EB29K -I/O Base = 0x208 -Memory Base = 0xd0000 - -Data Memory Size = 2048KB -Available I-RAM Range = 0x8000 to 0x1fffff -Available D-RAM Range = 0x80002000 to 0x801fffff - -PageSize = 0x400 -Register Stack Size = 0x800 -Memory Stack Size = 0x1800 - -CPU PRL = 0x3 -Am29027 Available = No -Byte Write Available = Yes - -# ~. -@end example - -Then exit the @code{cu} or @code{tip} program (done in the example by -typing @code{~.} at the @code{EBMON} prompt). @code{EBMON} keeps -running, ready for @value{GDBN} to take over. - -For this example, we've assumed what is probably the most convenient -way to make sure the same 29K program is on both the PC and the Unix -system: a PC/NFS connection that establishes ``drive @code{G:}'' on the -PC as a file system on the Unix host. If you do not have PC/NFS or -something similar connecting the two systems, you must arrange some -other way---perhaps floppy-disk transfer---of getting the 29K program -from the Unix system to the PC; @value{GDBN} does @emph{not} download it over the -serial line. - -@node gdb-EB29K -@subsubsection EB29K cross-debugging - -Finally, @code{cd} to the directory containing an image of your 29K -program on the Unix system, and start @value{GDBN}---specifying as argument the -name of your 29K program: - -@example -cd /usr/joe/work29k -@value{GDBP} myfoo -@end example - -@need 500 -Now you can use the @code{target} command: - -@example -target amd-eb /dev/ttya 9600 MYFOO -@c FIXME: test above 'target amd-eb' as spelled, with caps! caps are meant to -@c emphasize that this is the name as seen by DOS (since I think DOS is -@c single-minded about case of letters). ---doc@cygnus.com, 25feb91 -@end example - -@noindent -In this example, we've assumed your program is in a file called -@file{myfoo}. Note that the filename given as the last argument to -@code{target amd-eb} should be the name of the program as it appears to DOS. -In our example this is simply @code{MYFOO}, but in general it can include -a DOS path, and depending on your transfer mechanism may not resemble -the name on the Unix side. - -At this point, you can set any breakpoints you wish; when you are ready -to see your program run on the 29K board, use the @value{GDBN} command -@code{run}. - -To stop debugging the remote program, use the @value{GDBN} @code{detach} -command. - -To return control of the PC to its console, use @code{tip} or @code{cu} -once again, after your @value{GDBN} session has concluded, to attach to -@code{EBMON}. You can then type the command @code{q} to shut down -@code{EBMON}, returning control to the DOS command-line interpreter. -Type @code{CTTY con} to return command input to the main DOS console, -and type @kbd{~.} to leave @code{tip} or @code{cu}. - -@node Remote Log -@subsubsection Remote log -@kindex eb.log -@cindex log file for EB29K - -The @code{target amd-eb} command creates a file @file{eb.log} in the -current working directory, to help debug problems with the connection. -@file{eb.log} records all the output from @code{EBMON}, including echoes -of the commands sent to it. Running @samp{tail -f} on this file in -another window often helps to understand trouble with @code{EBMON}, or -unexpected events on the PC side of the connection. - -@end ifset - -@ifset ST2000 -@node ST2000 Remote -@subsection @value{GDBN} with a Tandem ST2000 - -To connect your ST2000 to the host system, see the manufacturer's -manual. Once the ST2000 is physically attached, you can run: - -@example -target st2000 @var{dev} @var{speed} -@end example - -@noindent -to establish it as your debugging environment. @var{dev} is normally -the name of a serial device, such as @file{/dev/ttya}, connected to the -ST2000 via a serial line. You can instead specify @var{dev} as a TCP -connection (for example, to a serial line attached via a terminal -concentrator) using the syntax @code{@var{hostname}:@var{portnumber}}. - -The @code{load} and @code{attach} commands are @emph{not} defined for -this target; you must load your program into the ST2000 as you normally -would for standalone operation. @value{GDBN} reads debugging information -(such as symbols) from a separate, debugging version of the program -available on your host computer. -@c FIXME!! This is terribly vague; what little content is here is -@c basically hearsay. - -@cindex ST2000 auxiliary commands -These auxiliary @value{GDBN} commands are available to help you with the ST2000 -environment: - -@table @code -@item st2000 @var{command} -@kindex st2000 @var{cmd} -@cindex STDBUG commands (ST2000) -@cindex commands to STDBUG (ST2000) -Send a @var{command} to the STDBUG monitor. See the manufacturer's -manual for available commands. - -@item connect -@cindex connect (to STDBUG) -Connect the controlling terminal to the STDBUG command monitor. When -you are done interacting with STDBUG, typing either of two character -sequences gets you back to the @value{GDBN} command prompt: -@kbd{@key{RET}~.} (Return, followed by tilde and period) or -@kbd{@key{RET}~@key{C-d}} (Return, followed by tilde and control-D). -@end table -@end ifset - -@ifset VXWORKS -@node VxWorks Remote -@subsection @value{GDBN} and VxWorks -@cindex VxWorks - -@value{GDBN} enables developers to spawn and debug tasks running on networked -VxWorks targets from a Unix host. Already-running tasks spawned from -the VxWorks shell can also be debugged. @value{GDBN} uses code that runs on -both the Unix host and on the VxWorks target. The program -@code{gdb} is installed and executed on the Unix host. (It may be -installed with the name @code{vxgdb}, to distinguish it from a -@value{GDBN} for debugging programs on the host itself.) - -@table @code -@item VxWorks-timeout @var{args} -@kindex vxworks-timeout -All VxWorks-based targets now support the option @code{vxworks-timeout}. -This option is set by the user, and @var{args} represents the number of -seconds @value{GDBN} waits for responses to rpc's. You might use this if -your VxWorks target is a slow software simulator or is on the far side -of a thin network line. -@end table - -The following information on connecting to VxWorks was current when -this manual was produced; newer releases of VxWorks may use revised -procedures. - -@kindex INCLUDE_RDB -To use @value{GDBN} with VxWorks, you must rebuild your VxWorks kernel -to include the remote debugging interface routines in the VxWorks -library @file{rdb.a}. To do this, define @code{INCLUDE_RDB} in the -VxWorks configuration file @file{configAll.h} and rebuild your VxWorks -kernel. The resulting kernel contains @file{rdb.a}, and spawns the -source debugging task @code{tRdbTask} when VxWorks is booted. For more -information on configuring and remaking VxWorks, see the manufacturer's -manual. -@c VxWorks, see the @cite{VxWorks Programmer's Guide}. - -Once you have included @file{rdb.a} in your VxWorks system image and set -your Unix execution search path to find @value{GDBN}, you are ready to -run @value{GDBN}. From your Unix host, run @code{gdb} (or @code{vxgdb}, -depending on your installation). - -@value{GDBN} comes up showing the prompt: - -@example -(vxgdb) -@end example - -@menu -* VxWorks Connection:: Connecting to VxWorks -* VxWorks Download:: VxWorks download -* VxWorks Attach:: Running tasks -@end menu - -@node VxWorks Connection -@subsubsection Connecting to VxWorks - -The @value{GDBN} command @code{target} lets you connect to a VxWorks target on the -network. To connect to a target whose host name is ``@code{tt}'', type: - -@example -(vxgdb) target vxworks tt -@end example - -@need 750 -@value{GDBN} displays messages like these: - -@smallexample -Attaching remote machine across net... -Connected to tt. -@end smallexample - -@need 1000 -@value{GDBN} then attempts to read the symbol tables of any object modules -loaded into the VxWorks target since it was last booted. @value{GDBN} locates -these files by searching the directories listed in the command search -path (@pxref{Environment, ,Your program's environment}); if it fails -to find an object file, it displays a message such as: - -@example -prog.o: No such file or directory. -@end example - -When this happens, add the appropriate directory to the search path with -the @value{GDBN} command @code{path}, and execute the @code{target} -command again. - -@node VxWorks Download -@subsubsection VxWorks download - -@cindex download to VxWorks -If you have connected to the VxWorks target and you want to debug an -object that has not yet been loaded, you can use the @value{GDBN} -@code{load} command to download a file from Unix to VxWorks -incrementally. The object file given as an argument to the @code{load} -command is actually opened twice: first by the VxWorks target in order -to download the code, then by @value{GDBN} in order to read the symbol -table. This can lead to problems if the current working directories on -the two systems differ. If both systems have NFS mounted the same -filesystems, you can avoid these problems by using absolute paths. -Otherwise, it is simplest to set the working directory on both systems -to the directory in which the object file resides, and then to reference -the file by its name, without any path. For instance, a program -@file{prog.o} may reside in @file{@var{vxpath}/vw/demo/rdb} in VxWorks -and in @file{@var{hostpath}/vw/demo/rdb} on the host. To load this -program, type this on VxWorks: - -@example --> cd "@var{vxpath}/vw/demo/rdb" -@end example -v -Then, in @value{GDBN}, type: - -@example -(vxgdb) cd @var{hostpath}/vw/demo/rdb -(vxgdb) load prog.o -@end example - -@value{GDBN} displays a response similar to this: - -@smallexample -Reading symbol data from wherever/vw/demo/rdb/prog.o... done. -@end smallexample - -You can also use the @code{load} command to reload an object module -after editing and recompiling the corresponding source file. Note that -this makes @value{GDBN} delete all currently-defined breakpoints, -auto-displays, and convenience variables, and to clear the value -history. (This is necessary in order to preserve the integrity of -debugger data structures that reference the target system's symbol -table.) - -@node VxWorks Attach -@subsubsection Running tasks - -@cindex running VxWorks tasks -You can also attach to an existing task using the @code{attach} command as -follows: - -@example -(vxgdb) attach @var{task} -@end example - -@noindent -where @var{task} is the VxWorks hexadecimal task ID. The task can be running -or suspended when you attach to it. Running tasks are suspended at -the time of attachment. -@end ifset - -@ifset SPARCLET -@node Sparclet Remote -@subsection @value{GDBN} and Sparclet -@cindex Sparclet - -@value{GDBN} enables developers to debug tasks running on -Sparclet targets from a Unix host. -@value{GDBN} uses code that runs on -both the Unix host and on the Sparclet target. The program -@code{gdb} is installed and executed on the Unix host. - -@table @code -@item timeout @var{args} -@kindex remotetimeout -@value{GDBN} now supports the option @code{remotetimeout}. -This option is set by the user, and @var{args} represents the number of -seconds @value{GDBN} waits for responses. -@end table - -@kindex Compiling -When compiling for debugging, include the options "-g" to get debug -information and "-Ttext" to relocate the program to where you wish to -load it on the target. You may also want to add the options "-n" or -"-N" in order to reduce the size of the sections. - -@example -sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N -@end example - -You can use objdump to verify that the addresses are what you intended. - -@example -sparclet-aout-objdump --headers --syms prog -@end example - -@kindex Running -Once you have set -your Unix execution search path to find @value{GDBN}, you are ready to -run @value{GDBN}. From your Unix host, run @code{gdb} -(or @code{sparclet-aout-gdb}, depending on your installation). - -@value{GDBN} comes up showing the prompt: - -@example -(gdbslet) -@end example - -@menu -* Sparclet File:: Setting the file to debug -* Sparclet Connection:: Connecting to Sparclet -* Sparclet Download:: Sparclet download -* Sparclet Execution:: Running and debugging -@end menu - -@node Sparclet File -@subsubsection Setting file to debug - -The @value{GDBN} command @code{file} lets you choose with program to debug. - -@example -(gdbslet) file prog -@end example - -@need 1000 -@value{GDBN} then attempts to read the symbol table of @file{prog}. -@value{GDBN} locates -the file by searching the directories listed in the command search -path. -If the file was compiled with debug information (option "-g"), source -files will be searched as well. -@value{GDBN} locates -the source files by searching the directories listed in the directory search -path (@pxref{Environment, ,Your program's environment}). -If it fails -to find a file, it displays a message such as: - -@example -prog: No such file or directory. -@end example - -When this happens, add the appropriate directories to the search paths with -the @value{GDBN} commands @code{path} and @code{dir}, and execute the -@code{target} command again. - -@node Sparclet Connection -@subsubsection Connecting to Sparclet - -The @value{GDBN} command @code{target} lets you connect to a Sparclet target. -To connect to a target on serial port ``@code{ttya}'', type: - -@example -(gdbslet) target sparclet /dev/ttya -Remote target sparclet connected to /dev/ttya -main () at ../prog.c:3 -@end example - -@need 750 -@value{GDBN} displays messages like these: - -@smallexample -Connected to ttya. -@end smallexample - -@node Sparclet Download -@subsubsection Sparclet download - -@cindex download to Sparclet -Once connected to the Sparclet target, -you can use the @value{GDBN} -@code{load} command to download the file from the host to the target. -The file name and load offset should be given as arguments to the @code{load} -command. -Since the file format is aout, the program must be loaded to the starting -address. You can use objdump to find out what this value is. The load -offset is an offset which is added to the VMA (virtual memory address) -of each of the file's sections. -For instance, if the program -@file{prog} was linked to text address 0x1201000, with data at 0x12010160 -and bss at 0x12010170, in @value{GDBN}, type: - -@example -(gdbslet) load prog 0x12010000 -Loading section .text, size 0xdb0 vma 0x12010000 -@end example - -If the code is loaded at a different address then what the program was linked -to, you may need to use the @code{section} and @code{add-symbol-file} commands -to tell @value{GDBN} where to map the symbol table. - -@node Sparclet Execution -@subsubsection Running and debugging - -@cindex running and debugging Sparclet programs -You can now begin debugging the task using @value{GDBN}'s execution control -commands, @code{b}, @code{step}, @code{run}, etc. See the @value{GDBN} -manual for the list of commands. - -@example -(gdbslet) b main -Breakpoint 1 at 0x12010000: file prog.c, line 3. -(gdbslet) run -Starting program: prog -Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3 -3 char *symarg = 0; -(gdbslet) step -4 char *execarg = "hello!"; -(gdbslet) -@end example - -@end ifset - -@ifset H8 -@node Hitachi Remote -@subsection @value{GDBN} and Hitachi microprocessors -@value{GDBN} needs to know these things to talk to your -Hitachi SH, H8/300, or H8/500: - -@enumerate -@item -that you want to use @samp{target hms}, the remote debugging interface -for Hitachi microprocessors, or @samp{target e7000}, the in-circuit -emulator for the Hitachi SH and the Hitachi 300H. (@samp{target hms} is -the default when GDB is configured specifically for the Hitachi SH, -H8/300, or H8/500.) - -@item -what serial device connects your host to your Hitachi board (the first -serial device available on your host is the default). - -@ifclear H8EXCLUSIVE -@c this is only for Unix hosts, not of interest to Hitachi -@item -what speed to use over the serial device. -@end ifclear -@end enumerate - -@menu -* Hitachi Boards:: Connecting to Hitachi boards. -* Hitachi ICE:: Using the E7000 In-Circuit Emulator. -* Hitachi Special:: Special @value{GDBN} commands for Hitachi micros. -@end menu - -@node Hitachi Boards -@subsubsection Connecting to Hitachi boards - -@ifclear H8EXCLUSIVE -@c only for Unix hosts -@kindex device -@cindex serial device, Hitachi micros -Use the special @code{@value{GDBP}} command @samp{device @var{port}} if you -need to explicitly set the serial device. The default @var{port} is the -first available port on your host. This is only necessary on Unix -hosts, where it is typically something like @file{/dev/ttya}. - -@kindex speed -@cindex serial line speed, Hitachi micros -@code{@value{GDBP}} has another special command to set the communications -speed: @samp{speed @var{bps}}. This command also is only used from Unix -hosts; on DOS hosts, set the line speed as usual from outside GDB with -the DOS @kbd{mode} command (for instance, @w{@samp{mode -com2:9600,n,8,1,p}} for a 9600 bps connection). - -The @samp{device} and @samp{speed} commands are available only when you -use a Unix host to debug your Hitachi microprocessor programs. If you -use a DOS host, -@end ifclear -@value{GDBN} depends on an auxiliary terminate-and-stay-resident program -called @code{asynctsr} to communicate with the development board -through a PC serial port. You must also use the DOS @code{mode} command -to set up the serial port on the DOS side. - -@ifset DOSHOST -The following sample session illustrates the steps needed to start a -program under @value{GDBN} control on an H8/300. The example uses a -sample H8/300 program called @file{t.x}. The procedure is the same for -the Hitachi SH and the H8/500. - -First hook up your development board. In this example, we use a -board attached to serial port @code{COM2}; if you use a different serial -port, substitute its name in the argument of the @code{mode} command. -When you call @code{asynctsr}, the auxiliary comms program used by the -degugger, you give it just the numeric part of the serial port's name; -for example, @samp{asyncstr 2} below runs @code{asyncstr} on -@code{COM2}. - -@example -C:\H8300\TEST> asynctsr 2 -C:\H8300\TEST> mode com2:9600,n,8,1,p - -Resident portion of MODE loaded - -COM2: 9600, n, 8, 1, p - -@end example - -@quotation -@emph{Warning:} We have noticed a bug in PC-NFS that conflicts with -@code{asynctsr}. If you also run PC-NFS on your DOS host, you may need to -disable it, or even boot without it, to use @code{asynctsr} to control -your development board. -@end quotation - -@kindex target hms -Now that serial communications are set up, and the development board is -connected, you can start up @value{GDBN}. Call @code{@value{GDBP}} with -the name of your program as the argument. @code{@value{GDBP}} prompts -you, as usual, with the prompt @samp{(@value{GDBP})}. Use two special -commands to begin your debugging session: @samp{target hms} to specify -cross-debugging to the Hitachi board, and the @code{load} command to -download your program to the board. @code{load} displays the names of -the program's sections, and a @samp{*} for each 2K of data downloaded. -(If you want to refresh @value{GDBN} data on symbols or on the -executable file without downloading, use the @value{GDBN} commands -@code{file} or @code{symbol-file}. These commands, and @code{load} -itself, are described in @ref{Files,,Commands to specify files}.) - -@smallexample -(eg-C:\H8300\TEST) @value{GDBP} t.x -GDB is free software and you are welcome to distribute copies - of it under certain conditions; type "show copying" to see - the conditions. -There is absolutely no warranty for GDB; type "show warranty" -for details. -GDB @value{GDBVN}, Copyright 1992 Free Software Foundation, Inc... -(gdb) target hms -Connected to remote H8/300 HMS system. -(gdb) load t.x -.text : 0x8000 .. 0xabde *********** -.data : 0xabde .. 0xad30 * -.stack : 0xf000 .. 0xf014 * -@end smallexample - -At this point, you're ready to run or debug your program. From here on, -you can use all the usual @value{GDBN} commands. The @code{break} command -sets breakpoints; the @code{run} command starts your program; -@code{print} or @code{x} display data; the @code{continue} command -resumes execution after stopping at a breakpoint. You can use the -@code{help} command at any time to find out more about @value{GDBN} commands. - -Remember, however, that @emph{operating system} facilities aren't -available on your development board; for example, if your program hangs, -you can't send an interrupt---but you can press the @sc{reset} switch! - -Use the @sc{reset} button on the development board -@itemize @bullet -@item -to interrupt your program (don't use @kbd{ctl-C} on the DOS host---it has -no way to pass an interrupt signal to the development board); and - -@item -to return to the @value{GDBN} command prompt after your program finishes -normally. The communications protocol provides no other way for @value{GDBN} -to detect program completion. -@end itemize - -In either case, @value{GDBN} sees the effect of a @sc{reset} on the -development board as a ``normal exit'' of your program. -@end ifset - -@node Hitachi ICE -@subsubsection Using the E7000 in-circuit emulator - -@kindex target e7000 -You can use the E7000 in-circuit emulator to develop code for either the -Hitachi SH or the H8/300H. Use one of these forms of the @samp{target -e7000} command to connect @value{GDBN} to your E7000: - -@table @code -@item target e7000 @var{port} @var{speed} -Use this form if your E7000 is connected to a serial port. The -@var{port} argument identifies what serial port to use (for example, -@samp{com2}). The third argument is the line speed in bits per second -(for example, @samp{9600}). - -@item target e7000 @var{hostname} -If your E7000 is installed as a host on a TCP/IP network, you can just -specify its hostname; @value{GDBN} uses @code{telnet} to connect. -@end table - -@node Hitachi Special -@subsubsection Special @value{GDBN} commands for Hitachi micros - -Some @value{GDBN} commands are available only on the H8/300 or the -H8/500 configurations: - -@table @code -@kindex set machine -@kindex show machine -@item set machine h8300 -@itemx set machine h8300h -Condition @value{GDBN} for one of the two variants of the H8/300 -architecture with @samp{set machine}. You can use @samp{show machine} -to check which variant is currently in effect. - -@kindex set memory @var{mod} -@cindex memory models, H8/500 -@item set memory @var{mod} -@itemx show memory -Specify which H8/500 memory model (@var{mod}) you are using with -@samp{set memory}; check which memory model is in effect with @samp{show -memory}. The accepted values for @var{mod} are @code{small}, -@code{big}, @code{medium}, and @code{compact}. -@end table - -@end ifset - -@ifset MIPS -@node MIPS Remote -@subsection @value{GDBN} and remote MIPS boards - -@cindex MIPS boards -@value{GDBN} can use the MIPS remote debugging protocol to talk to a -MIPS board attached to a serial line. This is available when -you configure @value{GDBN} with @samp{--target=mips-idt-ecoff}. - -@need 1000 -Use these @value{GDBN} commands to specify the connection to your target board: - -@table @code -@item target mips @var{port} -@kindex target mips @var{port} -To run a program on the board, start up @code{@value{GDBP}} with the -name of your program as the argument. To connect to the board, use the -command @samp{target mips @var{port}}, where @var{port} is the name of -the serial port connected to the board. If the program has not already -been downloaded to the board, you may use the @code{load} command to -download it. You can then use all the usual @value{GDBN} commands. - -For example, this sequence connects to the target board through a serial -port, and loads and runs a program called @var{prog} through the -debugger: - -@example -host$ @value{GDBP} @var{prog} -GDB is free software and @dots{} -(gdb) target mips /dev/ttyb -(gdb) load @var{prog} -(gdb) run -@end example - -@item target mips @var{hostname}:@var{portnumber} -On some @value{GDBN} host configurations, you can specify a TCP -connection (for instance, to a serial line managed by a terminal -concentrator) instead of a serial port, using the syntax -@samp{@var{hostname}:@var{portnumber}}. - -@item target pmon @var{port} -@kindex target pmon @var{port} - -@item target ddb @var{port} -@kindex target ddb @var{port} - -@item target lsi @var{port} -@kindex target lsi @var{port} - -@end table - - -@noindent -@value{GDBN} also supports these special commands for MIPS targets: - -@table @code -@item set processor @var{args} -@itemx show processor -@kindex set processor @var{args} -@kindex show processor -Use the @code{set processor} command to set the type of MIPS -processor when you want to access processor-type-specific registers. -For example, @code{set processor @var{r3041}} tells @value{GDBN} -to use the CPO registers appropriate for the 3041 chip. -Use the @code{show processor} command to see what MIPS processor @value{GDBN} -is using. Use the @code{info reg} command to see what registers -@value{GDBN} is using. - -@item set mipsfpu double -@itemx set mipsfpu single -@itemx set mipsfpu none -@itemx show mipsfpu -@kindex set mipsfpu -@kindex show mipsfpu -@cindex MIPS remote floating point -@cindex floating point, MIPS remote -If your target board does not support the MIPS floating point -coprocessor, you should use the command @samp{set mipsfpu none} (if you -need this, you may wish to put the command in your @value{GDBINIT} -file). This tells @value{GDBN} how to find the return value of -functions which return floating point values. It also allows -@value{GDBN} to avoid saving the floating point registers when calling -functions on the board. If you are using a floating point coprocessor -with only single precision floating point support, as on the @sc{r4650} -processor, use the command @samp{set mipsfpu single}. The default -double precision floating point coprocessor may be selected using -@samp{set mipsfpu double}. - -In previous versions the only choices were double precision or no -floating point, so @samp{set mipsfpu on} will select double precision -and @samp{set mipsfpu off} will select no floating point. - -As usual, you can inquire about the @code{mipsfpu} variable with -@samp{show mipsfpu}. - -@item set remotedebug @var{n} -@itemx show remotedebug -@kindex set remotedebug -@kindex show remotedebug -@cindex @code{remotedebug}, MIPS protocol -@cindex MIPS @code{remotedebug} protocol -@c FIXME! For this to be useful, you must know something about the MIPS -@c FIXME...protocol. Where is it described? -You can see some debugging information about communications with the board -by setting the @code{remotedebug} variable. If you set it to @code{1} using -@samp{set remotedebug 1}, every packet is displayed. If you set it -to @code{2}, every character is displayed. You can check the current value -at any time with the command @samp{show remotedebug}. - -@item set timeout @var{seconds} -@itemx set retransmit-timeout @var{seconds} -@itemx show timeout -@itemx show retransmit-timeout -@cindex @code{timeout}, MIPS protocol -@cindex @code{retransmit-timeout}, MIPS protocol -@kindex set timeout -@kindex show timeout -@kindex set retransmit-timeout -@kindex show retransmit-timeout -You can control the timeout used while waiting for a packet, in the MIPS -remote protocol, with the @code{set timeout @var{seconds}} command. The -default is 5 seconds. Similarly, you can control the timeout used while -waiting for an acknowledgement of a packet with the @code{set -retransmit-timeout @var{seconds}} command. The default is 3 seconds. -You can inspect both values with @code{show timeout} and @code{show -retransmit-timeout}. (These commands are @emph{only} available when -@value{GDBN} is configured for @samp{--target=mips-idt-ecoff}.) - -The timeout set by @code{set timeout} does not apply when @value{GDBN} -is waiting for your program to stop. In that case, @value{GDBN} waits -forever because it has no way of knowing how long the program is going -to run before stopping. -@end table -@end ifset - -@ifset SIMS -@node Simulator -@subsection Simulated CPU target - -@ifset GENERIC -@cindex simulator -@cindex simulator, Z8000 -@cindex Z8000 simulator -@cindex simulator, H8/300 or H8/500 -@cindex H8/300 or H8/500 simulator -@cindex simulator, Hitachi SH -@cindex Hitachi SH simulator -@cindex CPU simulator -For some configurations, @value{GDBN} includes a CPU simulator that you -can use instead of a hardware CPU to debug your programs. -Currently, simulators are available for ARM, D10V, D30V, FR30, H8/300, -H8/500, i960, M32R, MIPS, MN10200, MN10300, PowerPC, SH, Sparc, V850, -W65, and Z8000. -@end ifset - -@ifclear GENERIC -@ifset H8 -@cindex simulator, H8/300 or H8/500 -@cindex Hitachi H8/300 or H8/500 simulator -@cindex simulator, Hitachi SH -@cindex Hitachi SH simulator -When configured for debugging Hitachi microprocessor targets, -@value{GDBN} includes a CPU simulator for the target chip (a Hitachi SH, -H8/300, or H8/500). -@end ifset - -@ifset Z8K -@cindex simulator, Z8000 -@cindex Zilog Z8000 simulator -When configured for debugging Zilog Z8000 targets, @value{GDBN} includes -a Z8000 simulator. -@end ifset -@end ifclear - -@ifset Z8K -For the Z8000 family, @samp{target sim} simulates either the Z8002 (the -unsegmented variant of the Z8000 architecture) or the Z8001 (the -segmented variant). The simulator recognizes which architecture is -appropriate by inspecting the object code. -@end ifset - -@table @code -@item target sim @var{args} -@kindex sim -@kindex target sim -Debug programs on a simulated CPU. If the simulator supports setup -options, specify them via @var{args}. -@end table - -@noindent -After specifying this target, you can debug programs for the simulated -CPU in the same style as programs for your host computer; use the -@code{file} command to load a new program image, the @code{run} command -to run your program, and so on. - -As well as making available all the usual machine registers (see -@code{info reg}), the Z8000 simulator provides three additional items -of information as specially named registers: - -@table @code -@item cycles -Counts clock-ticks in the simulator. - -@item insts -Counts instructions run in the simulator. - -@item time -Execution time in 60ths of a second. -@end table - -You can refer to these values in @value{GDBN} expressions with the usual -conventions; for example, @w{@samp{b fputc if $cycles>5000}} sets a -conditional breakpoint that suspends only after at least 5000 -simulated clock ticks. -@end ifset - -@c need to add much more detail about sims! diff --git a/contrib/gdb/gdb/f-exp.tab.c b/contrib/gdb/gdb/f-exp.tab.c deleted file mode 100644 index c4932484bf3..00000000000 --- a/contrib/gdb/gdb/f-exp.tab.c +++ /dev/null @@ -1,2155 +0,0 @@ - -/* A Bison parser, made from f-exp.y - by GNU Bison version 1.27 - */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define INT 257 -#define FLOAT 258 -#define STRING_LITERAL 259 -#define BOOLEAN_LITERAL 260 -#define NAME 261 -#define TYPENAME 262 -#define NAME_OR_INT 263 -#define SIZEOF 264 -#define ERROR 265 -#define INT_KEYWORD 266 -#define INT_S2_KEYWORD 267 -#define LOGICAL_S1_KEYWORD 268 -#define LOGICAL_S2_KEYWORD 269 -#define LOGICAL_KEYWORD 270 -#define REAL_KEYWORD 271 -#define REAL_S8_KEYWORD 272 -#define REAL_S16_KEYWORD 273 -#define COMPLEX_S8_KEYWORD 274 -#define COMPLEX_S16_KEYWORD 275 -#define COMPLEX_S32_KEYWORD 276 -#define BOOL_AND 277 -#define BOOL_OR 278 -#define BOOL_NOT 279 -#define CHARACTER 280 -#define VARIABLE 281 -#define ASSIGN_MODIFY 282 -#define ABOVE_COMMA 283 -#define EQUAL 284 -#define NOTEQUAL 285 -#define LESSTHAN 286 -#define GREATERTHAN 287 -#define LEQ 288 -#define GEQ 289 -#define LSH 290 -#define RSH 291 -#define UNARY 292 - -#line 43 "f-exp.y" - - -#include "defs.h" -#include "gdb_string.h" -#include "expression.h" -#include "value.h" -#include "parser-defs.h" -#include "language.h" -#include "f-lang.h" -#include "bfd.h" /* Required by objfiles.h. */ -#include "symfile.h" /* Required by objfiles.h. */ -#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ - -/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), - as well as gratuitiously global symbol names, so we can have multiple - yacc generated parsers in gdb. Note that these are only the variables - produced by yacc. If other parser generators (bison, byacc, etc) produce - additional global names that conflict at link time, then those parser - generators need to be fixed instead of adding those names to this list. */ - -#define yymaxdepth f_maxdepth -#define yyparse f_parse -#define yylex f_lex -#define yyerror f_error -#define yylval f_lval -#define yychar f_char -#define yydebug f_debug -#define yypact f_pact -#define yyr1 f_r1 -#define yyr2 f_r2 -#define yydef f_def -#define yychk f_chk -#define yypgo f_pgo -#define yyact f_act -#define yyexca f_exca -#define yyerrflag f_errflag -#define yynerrs f_nerrs -#define yyps f_ps -#define yypv f_pv -#define yys f_s -#define yy_yys f_yys -#define yystate f_state -#define yytmp f_tmp -#define yyv f_v -#define yy_yyv f_yyv -#define yyval f_val -#define yylloc f_lloc -#define yyreds f_reds /* With YYDEBUG defined */ -#define yytoks f_toks /* With YYDEBUG defined */ -#define yylhs f_yylhs -#define yylen f_yylen -#define yydefred f_yydefred -#define yydgoto f_yydgoto -#define yysindex f_yysindex -#define yyrindex f_yyrindex -#define yygindex f_yygindex -#define yytable f_yytable -#define yycheck f_yycheck - -#ifndef YYDEBUG -#define YYDEBUG 1 /* Default to no yydebug support */ -#endif - -int yyparse PARAMS ((void)); - -static int yylex PARAMS ((void)); - -void yyerror PARAMS ((char *)); - -static void growbuf_by_size PARAMS ((int)); - -static int match_string_literal PARAMS ((void)); - - -#line 122 "f-exp.y" -typedef union - { - LONGEST lval; - struct { - LONGEST val; - struct type *type; - } typed_val; - DOUBLEST dval; - struct symbol *sym; - struct type *tval; - struct stoken sval; - struct ttype tsym; - struct symtoken ssym; - int voidval; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - - struct type **tvec; - int *ivec; - } YYSTYPE; -#line 144 "f-exp.y" - -/* YYSTYPE gets defined by %union */ -static int parse_number PARAMS ((char *, int, int, YYSTYPE *)); -#include - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 125 -#define YYFLAG -32768 -#define YYNTBASE 55 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 292 ? yytranslate[x] : 71) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 49, 35, 2, 51, - 52, 47, 45, 29, 46, 2, 48, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 54, 2, 2, - 31, 2, 32, 44, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 34, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 33, 2, 53, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 30, 36, 37, 38, 39, 40, 41, 42, - 43, 50 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 4, 6, 10, 13, 16, 19, 22, 25, - 28, 29, 35, 36, 38, 40, 44, 48, 52, 56, - 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, - 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, - 141, 145, 147, 149, 151, 153, 155, 160, 162, 164, - 166, 168, 170, 173, 175, 178, 180, 183, 185, 189, - 192, 194, 197, 201, 203, 205, 207, 209, 211, 213, - 215, 217, 219, 221, 223, 225, 227, 229, 231, 235, - 237, 239, 241 -}; - -static const short yyrhs[] = { 57, - 0, 56, 0, 63, 0, 51, 57, 52, 0, 47, - 57, 0, 35, 57, 0, 46, 57, 0, 25, 57, - 0, 53, 57, 0, 10, 57, 0, 0, 57, 51, - 58, 59, 52, 0, 0, 57, 0, 60, 0, 59, - 29, 57, 0, 57, 54, 57, 0, 57, 29, 57, - 0, 51, 61, 52, 0, 51, 63, 52, 57, 0, - 57, 44, 57, 0, 57, 47, 57, 0, 57, 48, - 57, 0, 57, 49, 57, 0, 57, 45, 57, 0, - 57, 46, 57, 0, 57, 42, 57, 0, 57, 43, - 57, 0, 57, 36, 57, 0, 57, 37, 57, 0, - 57, 40, 57, 0, 57, 41, 57, 0, 57, 38, - 57, 0, 57, 39, 57, 0, 57, 35, 57, 0, - 57, 34, 57, 0, 57, 33, 57, 0, 57, 23, - 57, 0, 57, 24, 57, 0, 57, 31, 57, 0, - 57, 28, 57, 0, 3, 0, 9, 0, 4, 0, - 62, 0, 27, 0, 10, 51, 63, 52, 0, 6, - 0, 5, 0, 70, 0, 64, 0, 68, 0, 68, - 65, 0, 47, 0, 47, 65, 0, 35, 0, 35, - 65, 0, 66, 0, 51, 65, 52, 0, 66, 67, - 0, 67, 0, 51, 52, 0, 51, 69, 52, 0, - 8, 0, 12, 0, 13, 0, 26, 0, 16, 0, - 15, 0, 14, 0, 17, 0, 18, 0, 19, 0, - 20, 0, 21, 0, 22, 0, 8, 0, 63, 0, - 69, 29, 63, 0, 7, 0, 8, 0, 9, 0, - 7, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 221, 222, 225, 231, 236, 239, 242, 246, 250, 254, - 263, 265, 271, 274, 278, 281, 285, 290, 294, 298, - 306, 310, 314, 318, 322, 326, 330, 334, 338, 342, - 346, 350, 354, 358, 362, 366, 370, 374, 379, 383, - 387, 393, 400, 409, 416, 419, 422, 430, 437, 445, - 489, 492, 493, 536, 538, 540, 542, 544, 547, 549, - 551, 555, 557, 562, 564, 566, 568, 570, 572, 574, - 576, 578, 580, 582, 584, 586, 590, 594, 599, 606, - 608, 610, 614 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","INT","FLOAT", -"STRING_LITERAL","BOOLEAN_LITERAL","NAME","TYPENAME","NAME_OR_INT","SIZEOF", -"ERROR","INT_KEYWORD","INT_S2_KEYWORD","LOGICAL_S1_KEYWORD","LOGICAL_S2_KEYWORD", -"LOGICAL_KEYWORD","REAL_KEYWORD","REAL_S8_KEYWORD","REAL_S16_KEYWORD","COMPLEX_S8_KEYWORD", -"COMPLEX_S16_KEYWORD","COMPLEX_S32_KEYWORD","BOOL_AND","BOOL_OR","BOOL_NOT", -"CHARACTER","VARIABLE","ASSIGN_MODIFY","','","ABOVE_COMMA","'='","'?'","'|'", -"'^'","'&'","EQUAL","NOTEQUAL","LESSTHAN","GREATERTHAN","LEQ","GEQ","LSH","RSH", -"'@'","'+'","'-'","'*'","'/'","'%'","UNARY","'('","')'","'~'","':'","start", -"type_exp","exp","@1","arglist","substring","complexnum","variable","type","ptype", -"abs_decl","direct_abs_decl","func_mod","typebase","nonempty_typelist","name_not_typename", NULL -}; -#endif - -static const short yyr1[] = { 0, - 55, 55, 56, 57, 57, 57, 57, 57, 57, 57, - 58, 57, 59, 59, 59, 59, 60, 61, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, - 63, 64, 64, 65, 65, 65, 65, 65, 66, 66, - 66, 67, 67, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, -1, 69, 69, -1, - -1, -1, 70 -}; - -static const short yyr2[] = { 0, - 1, 1, 1, 3, 2, 2, 2, 2, 2, 2, - 0, 5, 0, 1, 1, 3, 3, 3, 3, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 4, 1, 1, 1, - 1, 1, 2, 1, 2, 1, 2, 1, 3, 2, - 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 1 -}; - -static const short yydefact[] = { 0, - 42, 44, 49, 48, 83, 64, 43, 0, 65, 66, - 70, 69, 68, 71, 72, 73, 74, 75, 76, 0, - 67, 46, 0, 0, 0, 0, 0, 2, 1, 45, - 3, 51, 52, 50, 0, 10, 8, 6, 7, 5, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 11, 56, 54, 0, 53, - 58, 61, 0, 0, 4, 19, 0, 38, 39, 41, - 40, 37, 36, 35, 29, 30, 33, 34, 31, 32, - 27, 28, 21, 25, 26, 22, 23, 24, 13, 57, - 55, 62, 78, 0, 0, 0, 60, 47, 18, 20, - 14, 0, 15, 59, 0, 63, 0, 0, 12, 79, - 17, 16, 0, 0, 0 -}; - -static const short yydefgoto[] = { 123, - 28, 41, 99, 112, 113, 42, 30, 103, 32, 70, - 71, 72, 33, 105, 34 -}; - -static const short yypact[] = { 75, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 126,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 135, --32768,-32768, 135, 135, 135, 75, 135,-32768, 309,-32768, --32768,-32768, -34,-32768, 75, -49, -49, -49, -49, -49, - 279, -46, -45, -49, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135,-32768, -34, -34, 206,-32768, - -42,-32768, -36, 135,-32768,-32768, 135, 355, 336, 309, - 309, 390, 407, 161, 221, 221, -11, -11, -11, -11, - 22, 22, 58, -37, -37, -49, -49, -49, 135,-32768, --32768,-32768,-32768, -33, -26, 230,-32768, 186, 309, -49, - 250, -24,-32768,-32768, 397,-32768, 135, 135,-32768,-32768, - 309, 309, 15, 18,-32768 -}; - -static const short yypgoto[] = {-32768, --32768, 0,-32768,-32768,-32768,-32768,-32768, 4,-32768, -25, --32768, -50,-32768,-32768,-32768 -}; - - -#define YYLAST 458 - - -static const short yytable[] = { 29, - 67, 66, 115, 31, 118, 76, 77, 36, 106, 63, - 64, 65, 68, 66, 124, 108, 69, 125, 114, 37, - 107, 0, 38, 39, 40, 116, 44, 119, 0, 43, - 58, 59, 60, 61, 62, 63, 64, 65, 73, 66, - 0, 100, 101, 104, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 60, 61, 62, 63, 64, - 65, 0, 66, 109, 0, 0, 110, 1, 2, 3, - 4, 5, 6, 7, 8, 0, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 0, 111, 20, - 21, 22, 61, 62, 63, 64, 65, 110, 66, 23, - 0, 0, 0, 0, 0, 0, 121, 122, 120, 0, - 24, 25, 0, 0, 0, 26, 0, 27, 1, 2, - 3, 4, 5, 0, 7, 8, 0, 1, 2, 3, - 4, 5, 0, 7, 8, 0, 0, 0, 0, 0, - 20, 0, 22, 0, 0, 0, 0, 0, 0, 20, - 23, 22, 0, 0, 0, 0, 0, 0, 0, 23, - 0, 24, 25, 0, 0, 0, 35, 0, 27, 0, - 24, 25, 0, 0, 0, 26, 0, 27, 1, 2, - 3, 4, 5, 0, 7, 8, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 20, 66, 22, 6, 0, 0, 0, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, - 0, 21, 0, 0, 0, 0, 26, 6, 27, 0, - 67, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 68, 0, 0, 21, 69, 102, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 0, 66, 45, 46, 0, 0, 0, 47, 0, 0, - 48, 102, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 0, - 66, 45, 46, 117, 0, 0, 47, 74, 0, 48, - 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 0, 66, - 75, 45, 46, 0, 0, 0, 47, 0, 0, 48, - 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 45, 66, - 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 0, 66, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 6, 66, 0, 0, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, - 0, 0, 21, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 0, - 66, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 0, 66 -}; - -static const short yycheck[] = { 0, - 35, 51, 29, 0, 29, 52, 52, 8, 51, 47, - 48, 49, 47, 51, 0, 52, 51, 0, 52, 20, - 71, -1, 23, 24, 25, 52, 27, 52, -1, 26, - 42, 43, 44, 45, 46, 47, 48, 49, 35, 51, - -1, 67, 68, 69, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 44, 45, 46, 47, 48, - 49, -1, 51, 74, -1, -1, 77, 3, 4, 5, - 6, 7, 8, 9, 10, -1, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, -1, 99, 25, - 26, 27, 45, 46, 47, 48, 49, 108, 51, 35, - -1, -1, -1, -1, -1, -1, 117, 118, 115, -1, - 46, 47, -1, -1, -1, 51, -1, 53, 3, 4, - 5, 6, 7, -1, 9, 10, -1, 3, 4, 5, - 6, 7, -1, 9, 10, -1, -1, -1, -1, -1, - 25, -1, 27, -1, -1, -1, -1, -1, -1, 25, - 35, 27, -1, -1, -1, -1, -1, -1, -1, 35, - -1, 46, 47, -1, -1, -1, 51, -1, 53, -1, - 46, 47, -1, -1, -1, 51, -1, 53, 3, 4, - 5, 6, 7, -1, 9, 10, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 25, 51, 27, 8, -1, -1, -1, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, -1, -1, - -1, 26, -1, -1, -1, -1, 51, 8, 53, -1, - 35, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 47, -1, -1, 26, 51, 52, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - -1, 51, 23, 24, -1, -1, -1, 28, -1, -1, - 31, 52, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, -1, - 51, 23, 24, 54, -1, -1, 28, 29, -1, 31, - -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, -1, 51, - 52, 23, 24, -1, -1, -1, 28, -1, -1, 31, - -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 23, 51, - -1, -1, -1, -1, -1, -1, -1, -1, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, -1, 51, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 8, 51, -1, -1, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, - -1, -1, 26, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, -1, - 51, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, -1, 51 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/lib/bison.simple" -/* This file comes from bison-1.27. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for xmalloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC xmalloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 216 "/usr/lib/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to xreallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to xreallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 3: -#line 226 "f-exp.y" -{ write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type(yyvsp[0].tval); - write_exp_elt_opcode(OP_TYPE); ; - break;} -case 4: -#line 232 "f-exp.y" -{ ; - break;} -case 5: -#line 237 "f-exp.y" -{ write_exp_elt_opcode (UNOP_IND); ; - break;} -case 6: -#line 240 "f-exp.y" -{ write_exp_elt_opcode (UNOP_ADDR); ; - break;} -case 7: -#line 243 "f-exp.y" -{ write_exp_elt_opcode (UNOP_NEG); ; - break;} -case 8: -#line 247 "f-exp.y" -{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ; - break;} -case 9: -#line 251 "f-exp.y" -{ write_exp_elt_opcode (UNOP_COMPLEMENT); ; - break;} -case 10: -#line 255 "f-exp.y" -{ write_exp_elt_opcode (UNOP_SIZEOF); ; - break;} -case 11: -#line 264 "f-exp.y" -{ start_arglist (); ; - break;} -case 12: -#line 266 "f-exp.y" -{ write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); - write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); ; - break;} -case 14: -#line 275 "f-exp.y" -{ arglist_len = 1; ; - break;} -case 15: -#line 279 "f-exp.y" -{ arglist_len = 2;; - break;} -case 16: -#line 282 "f-exp.y" -{ arglist_len++; ; - break;} -case 17: -#line 286 "f-exp.y" -{ ; - break;} -case 18: -#line 291 "f-exp.y" -{ ; - break;} -case 19: -#line 295 "f-exp.y" -{ write_exp_elt_opcode(OP_COMPLEX); ; - break;} -case 20: -#line 299 "f-exp.y" -{ write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type (yyvsp[-2].tval); - write_exp_elt_opcode (UNOP_CAST); ; - break;} -case 21: -#line 307 "f-exp.y" -{ write_exp_elt_opcode (BINOP_REPEAT); ; - break;} -case 22: -#line 311 "f-exp.y" -{ write_exp_elt_opcode (BINOP_MUL); ; - break;} -case 23: -#line 315 "f-exp.y" -{ write_exp_elt_opcode (BINOP_DIV); ; - break;} -case 24: -#line 319 "f-exp.y" -{ write_exp_elt_opcode (BINOP_REM); ; - break;} -case 25: -#line 323 "f-exp.y" -{ write_exp_elt_opcode (BINOP_ADD); ; - break;} -case 26: -#line 327 "f-exp.y" -{ write_exp_elt_opcode (BINOP_SUB); ; - break;} -case 27: -#line 331 "f-exp.y" -{ write_exp_elt_opcode (BINOP_LSH); ; - break;} -case 28: -#line 335 "f-exp.y" -{ write_exp_elt_opcode (BINOP_RSH); ; - break;} -case 29: -#line 339 "f-exp.y" -{ write_exp_elt_opcode (BINOP_EQUAL); ; - break;} -case 30: -#line 343 "f-exp.y" -{ write_exp_elt_opcode (BINOP_NOTEQUAL); ; - break;} -case 31: -#line 347 "f-exp.y" -{ write_exp_elt_opcode (BINOP_LEQ); ; - break;} -case 32: -#line 351 "f-exp.y" -{ write_exp_elt_opcode (BINOP_GEQ); ; - break;} -case 33: -#line 355 "f-exp.y" -{ write_exp_elt_opcode (BINOP_LESS); ; - break;} -case 34: -#line 359 "f-exp.y" -{ write_exp_elt_opcode (BINOP_GTR); ; - break;} -case 35: -#line 363 "f-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_AND); ; - break;} -case 36: -#line 367 "f-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_XOR); ; - break;} -case 37: -#line 371 "f-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_IOR); ; - break;} -case 38: -#line 375 "f-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ; - break;} -case 39: -#line 380 "f-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ; - break;} -case 40: -#line 384 "f-exp.y" -{ write_exp_elt_opcode (BINOP_ASSIGN); ; - break;} -case 41: -#line 388 "f-exp.y" -{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode (yyvsp[-1].opcode); - write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); ; - break;} -case 42: -#line 394 "f-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (yyvsp[0].typed_val.type); - write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val.val)); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 43: -#line 401 "f-exp.y" -{ YYSTYPE val; - parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (val.typed_val.type); - write_exp_elt_longcst ((LONGEST)val.typed_val.val); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 44: -#line 410 "f-exp.y" -{ write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (builtin_type_f_real_s8); - write_exp_elt_dblcst (yyvsp[0].dval); - write_exp_elt_opcode (OP_DOUBLE); ; - break;} -case 47: -#line 423 "f-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_f_integer); - CHECK_TYPEDEF (yyvsp[-1].tval); - write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 48: -#line 431 "f-exp.y" -{ write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); - write_exp_elt_opcode (OP_BOOL); - ; - break;} -case 49: -#line 438 "f-exp.y" -{ - write_exp_elt_opcode (OP_STRING); - write_exp_string (yyvsp[0].sval); - write_exp_elt_opcode (OP_STRING); - ; - break;} -case 50: -#line 446 "f-exp.y" -{ struct symbol *sym = yyvsp[0].ssym.sym; - - if (sym) - { - if (symbol_read_needs_frame (sym)) - { - if (innermost_block == 0 || - contained_in (block_found, - innermost_block)) - innermost_block = block_found; - } - write_exp_elt_opcode (OP_VAR_VALUE); - /* We want to use the selected frame, not - another more inner frame which happens to - be in the same block. */ - write_exp_elt_block (NULL); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); - break; - } - else - { - struct minimal_symbol *msymbol; - register char *arg = copy_name (yyvsp[0].ssym.stoken); - - msymbol = - lookup_minimal_symbol (arg, NULL, NULL); - if (msymbol != NULL) - { - write_exp_msymbol (msymbol, - lookup_function_type (builtin_type_int), - builtin_type_int); - } - else if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); - else - error ("No symbol \"%s\" in current context.", - copy_name (yyvsp[0].ssym.stoken)); - } - ; - break;} -case 53: -#line 494 "f-exp.y" -{ - /* This is where the interesting stuff happens. */ - int done = 0; - int array_size; - struct type *follow_type = yyvsp[-1].tval; - struct type *range_type; - - while (!done) - switch (pop_type ()) - { - case tp_end: - done = 1; - break; - case tp_pointer: - follow_type = lookup_pointer_type (follow_type); - break; - case tp_reference: - follow_type = lookup_reference_type (follow_type); - break; - case tp_array: - array_size = pop_type_int (); - if (array_size != -1) - { - range_type = - create_range_type ((struct type *) NULL, - builtin_type_f_integer, 0, - array_size - 1); - follow_type = - create_array_type ((struct type *) NULL, - follow_type, range_type); - } - else - follow_type = lookup_pointer_type (follow_type); - break; - case tp_function: - follow_type = lookup_function_type (follow_type); - break; - } - yyval.tval = follow_type; - ; - break;} -case 54: -#line 537 "f-exp.y" -{ push_type (tp_pointer); yyval.voidval = 0; ; - break;} -case 55: -#line 539 "f-exp.y" -{ push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; ; - break;} -case 56: -#line 541 "f-exp.y" -{ push_type (tp_reference); yyval.voidval = 0; ; - break;} -case 57: -#line 543 "f-exp.y" -{ push_type (tp_reference); yyval.voidval = yyvsp[0].voidval; ; - break;} -case 59: -#line 548 "f-exp.y" -{ yyval.voidval = yyvsp[-1].voidval; ; - break;} -case 60: -#line 550 "f-exp.y" -{ push_type (tp_function); ; - break;} -case 61: -#line 552 "f-exp.y" -{ push_type (tp_function); ; - break;} -case 62: -#line 556 "f-exp.y" -{ yyval.voidval = 0; ; - break;} -case 63: -#line 558 "f-exp.y" -{ free ((PTR)yyvsp[-1].tvec); yyval.voidval = 0; ; - break;} -case 64: -#line 563 "f-exp.y" -{ yyval.tval = yyvsp[0].tsym.type; ; - break;} -case 65: -#line 565 "f-exp.y" -{ yyval.tval = builtin_type_f_integer; ; - break;} -case 66: -#line 567 "f-exp.y" -{ yyval.tval = builtin_type_f_integer_s2; ; - break;} -case 67: -#line 569 "f-exp.y" -{ yyval.tval = builtin_type_f_character; ; - break;} -case 68: -#line 571 "f-exp.y" -{ yyval.tval = builtin_type_f_logical;; - break;} -case 69: -#line 573 "f-exp.y" -{ yyval.tval = builtin_type_f_logical_s2;; - break;} -case 70: -#line 575 "f-exp.y" -{ yyval.tval = builtin_type_f_logical_s1;; - break;} -case 71: -#line 577 "f-exp.y" -{ yyval.tval = builtin_type_f_real;; - break;} -case 72: -#line 579 "f-exp.y" -{ yyval.tval = builtin_type_f_real_s8;; - break;} -case 73: -#line 581 "f-exp.y" -{ yyval.tval = builtin_type_f_real_s16;; - break;} -case 74: -#line 583 "f-exp.y" -{ yyval.tval = builtin_type_f_complex_s8;; - break;} -case 75: -#line 585 "f-exp.y" -{ yyval.tval = builtin_type_f_complex_s16;; - break;} -case 76: -#line 587 "f-exp.y" -{ yyval.tval = builtin_type_f_complex_s32;; - break;} -case 78: -#line 595 "f-exp.y" -{ yyval.tvec = (struct type **) xmalloc (sizeof (struct type *) * 2); - yyval.ivec[0] = 1; /* Number of types in vector */ - yyval.tvec[1] = yyvsp[0].tval; - ; - break;} -case 79: -#line 600 "f-exp.y" -{ int len = sizeof (struct type *) * (++(yyvsp[-2].ivec[0]) + 1); - yyval.tvec = (struct type **) xrealloc ((char *) yyvsp[-2].tvec, len); - yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval; - ; - break;} -case 80: -#line 607 "f-exp.y" -{ yyval.sval = yyvsp[0].ssym.stoken; ; - break;} -case 81: -#line 609 "f-exp.y" -{ yyval.sval = yyvsp[0].tsym.stoken; ; - break;} -case 82: -#line 611 "f-exp.y" -{ yyval.sval = yyvsp[0].ssym.stoken; ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 542 "/usr/lib/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) xmalloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} -#line 624 "f-exp.y" - - -/* Take care of parsing a number (anything that starts with a digit). - Set yylval and return the token type; update lexptr. - LEN is the number of characters in it. */ - -/*** Needs some error checking for the float case ***/ - -static int -parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; - int parsed_float; - YYSTYPE *putithere; -{ - register LONGEST n = 0; - register LONGEST prevn = 0; - register int i; - register int c; - register int base = input_radix; - int unsigned_p = 0; - int long_p = 0; - ULONGEST high_bit; - struct type *signed_type; - struct type *unsigned_type; - - if (parsed_float) - { - /* It's a float since it contains a point or an exponent. */ - /* [dD] is not understood as an exponent by atof, change it to 'e'. */ - char *tmp, *tmp2; - - tmp = strsave (p); - for (tmp2 = tmp; *tmp2; ++tmp2) - if (*tmp2 == 'd' || *tmp2 == 'D') - *tmp2 = 'e'; - putithere->dval = atof (tmp); - free (tmp); - return FLOAT; - } - - /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ - if (p[0] == '0') - switch (p[1]) - { - case 'x': - case 'X': - if (len >= 3) - { - p += 2; - base = 16; - len -= 2; - } - break; - - case 't': - case 'T': - case 'd': - case 'D': - if (len >= 3) - { - p += 2; - base = 10; - len -= 2; - } - break; - - default: - base = 8; - break; - } - - while (len-- > 0) - { - c = *p++; - if (c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != 'l' && c != 'u') - n *= base; - if (c >= '0' && c <= '9') - n += i = c - '0'; - else - { - if (base > 10 && c >= 'a' && c <= 'f') - n += i = c - 'a' + 10; - else if (len == 0 && c == 'l') - long_p = 1; - else if (len == 0 && c == 'u') - unsigned_p = 1; - else - return ERROR; /* Char not a digit */ - } - if (i >= base) - return ERROR; /* Invalid digit in this base */ - - /* Portably test for overflow (only works for nonzero values, so make - a second check for zero). */ - if ((prevn >= n) && n != 0) - unsigned_p=1; /* Try something unsigned */ - /* If range checking enabled, portably test for unsigned overflow. */ - if (RANGE_CHECK && n != 0) - { - if ((unsigned_p && (unsigned)prevn >= (unsigned)n)) - range_error("Overflow on numeric constant."); - } - prevn = n; - } - - /* If the number is too big to be an int, or it's got an l suffix - then it's a long. Work out if this has to be a long by - shifting right and and seeing if anything remains, and the - target int size is different to the target long size. - - In the expression below, we could have tested - (n >> TARGET_INT_BIT) - to see if it was zero, - but too many compilers warn about that, when ints and longs - are the same size. So we shift it twice, with fewer bits - each time, for the same result. */ - - if ((TARGET_INT_BIT != TARGET_LONG_BIT - && ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */ - || long_p) - { - high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1); - unsigned_type = builtin_type_unsigned_long; - signed_type = builtin_type_long; - } - else - { - high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1); - unsigned_type = builtin_type_unsigned_int; - signed_type = builtin_type_int; - } - - putithere->typed_val.val = n; - - /* If the high bit of the worked out type is set then this number - has to be unsigned. */ - - if (unsigned_p || (n & high_bit)) - putithere->typed_val.type = unsigned_type; - else - putithere->typed_val.type = signed_type; - - return INT; -} - -struct token -{ - char *operator; - int token; - enum exp_opcode opcode; -}; - -static const struct token dot_ops[] = -{ - { ".and.", BOOL_AND, BINOP_END }, - { ".AND.", BOOL_AND, BINOP_END }, - { ".or.", BOOL_OR, BINOP_END }, - { ".OR.", BOOL_OR, BINOP_END }, - { ".not.", BOOL_NOT, BINOP_END }, - { ".NOT.", BOOL_NOT, BINOP_END }, - { ".eq.", EQUAL, BINOP_END }, - { ".EQ.", EQUAL, BINOP_END }, - { ".eqv.", EQUAL, BINOP_END }, - { ".NEQV.", NOTEQUAL, BINOP_END }, - { ".neqv.", NOTEQUAL, BINOP_END }, - { ".EQV.", EQUAL, BINOP_END }, - { ".ne.", NOTEQUAL, BINOP_END }, - { ".NE.", NOTEQUAL, BINOP_END }, - { ".le.", LEQ, BINOP_END }, - { ".LE.", LEQ, BINOP_END }, - { ".ge.", GEQ, BINOP_END }, - { ".GE.", GEQ, BINOP_END }, - { ".gt.", GREATERTHAN, BINOP_END }, - { ".GT.", GREATERTHAN, BINOP_END }, - { ".lt.", LESSTHAN, BINOP_END }, - { ".LT.", LESSTHAN, BINOP_END }, - { NULL, 0, 0 } -}; - -struct f77_boolean_val -{ - char *name; - int value; -}; - -static const struct f77_boolean_val boolean_values[] = -{ - { ".true.", 1 }, - { ".TRUE.", 1 }, - { ".false.", 0 }, - { ".FALSE.", 0 }, - { NULL, 0 } -}; - -static const struct token f77_keywords[] = -{ - { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END }, - { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END }, - { "character", CHARACTER, BINOP_END }, - { "integer_2", INT_S2_KEYWORD, BINOP_END }, - { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END }, - { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END }, - { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END }, - { "integer", INT_KEYWORD, BINOP_END }, - { "logical", LOGICAL_KEYWORD, BINOP_END }, - { "real_16", REAL_S16_KEYWORD, BINOP_END }, - { "complex", COMPLEX_S8_KEYWORD, BINOP_END }, - { "sizeof", SIZEOF, BINOP_END }, - { "real_8", REAL_S8_KEYWORD, BINOP_END }, - { "real", REAL_KEYWORD, BINOP_END }, - { NULL, 0, 0 } -}; - -/* Implementation of a dynamically expandable buffer for processing input - characters acquired through lexptr and building a value to return in - yylval. Ripped off from ch-exp.y */ - -static char *tempbuf; /* Current buffer contents */ -static int tempbufsize; /* Size of allocated buffer */ -static int tempbufindex; /* Current index into buffer */ - -#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */ - -#define CHECKBUF(size) \ - do { \ - if (tempbufindex + (size) >= tempbufsize) \ - { \ - growbuf_by_size (size); \ - } \ - } while (0); - - -/* Grow the static temp buffer if necessary, including allocating the first one - on demand. */ - -static void -growbuf_by_size (count) - int count; -{ - int growby; - - growby = max (count, GROWBY_MIN_SIZE); - tempbufsize += growby; - if (tempbuf == NULL) - tempbuf = (char *) xmalloc (tempbufsize); - else - tempbuf = (char *) xrealloc (tempbuf, tempbufsize); -} - -/* Blatantly ripped off from ch-exp.y. This routine recognizes F77 - string-literals. - - Recognize a string literal. A string literal is a nonzero sequence - of characters enclosed in matching single quotes, except that - a single character inside single quotes is a character literal, which - we reject as a string literal. To embed the terminator character inside - a string, it is simply doubled (I.E. 'this''is''one''string') */ - -static int -match_string_literal () -{ - char *tokptr = lexptr; - - for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++) - { - CHECKBUF (1); - if (*tokptr == *lexptr) - { - if (*(tokptr + 1) == *lexptr) - tokptr++; - else - break; - } - tempbuf[tempbufindex++] = *tokptr; - } - if (*tokptr == '\0' /* no terminator */ - || tempbufindex == 0) /* no string */ - return 0; - else - { - tempbuf[tempbufindex] = '\0'; - yylval.sval.ptr = tempbuf; - yylval.sval.length = tempbufindex; - lexptr = ++tokptr; - return STRING_LITERAL; - } -} - -/* Read one token, getting characters through lexptr. */ - -static int -yylex () -{ - int c; - int namelen; - unsigned int i,token; - char *tokstart; - - retry: - - tokstart = lexptr; - - /* First of all, let us make sure we are not dealing with the - special tokens .true. and .false. which evaluate to 1 and 0. */ - - if (*lexptr == '.') - { - for (i = 0; boolean_values[i].name != NULL; i++) - { - if STREQN (tokstart, boolean_values[i].name, - strlen (boolean_values[i].name)) - { - lexptr += strlen (boolean_values[i].name); - yylval.lval = boolean_values[i].value; - return BOOLEAN_LITERAL; - } - } - } - - /* See if it is a special .foo. operator */ - - for (i = 0; dot_ops[i].operator != NULL; i++) - if (STREQN (tokstart, dot_ops[i].operator, strlen (dot_ops[i].operator))) - { - lexptr += strlen (dot_ops[i].operator); - yylval.opcode = dot_ops[i].opcode; - return dot_ops[i].token; - } - - switch (c = *tokstart) - { - case 0: - return 0; - - case ' ': - case '\t': - case '\n': - lexptr++; - goto retry; - - case '\'': - token = match_string_literal (); - if (token != 0) - return (token); - break; - - case '(': - paren_depth++; - lexptr++; - return c; - - case ')': - if (paren_depth == 0) - return 0; - paren_depth--; - lexptr++; - return c; - - case ',': - if (comma_terminates && paren_depth == 0) - return 0; - lexptr++; - return c; - - case '.': - /* Might be a floating point number. */ - if (lexptr[1] < '0' || lexptr[1] > '9') - goto symbol; /* Nope, must be a symbol. */ - /* FALL THRU into number case. */ - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - /* It's a number. */ - int got_dot = 0, got_e = 0, got_d = 0, toktype; - register char *p = tokstart; - int hex = input_radix > 10; - - if (c == '0' && (p[1] == 'x' || p[1] == 'X')) - { - p += 2; - hex = 1; - } - else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) - { - p += 2; - hex = 0; - } - - for (;; ++p) - { - if (!hex && !got_e && (*p == 'e' || *p == 'E')) - got_dot = got_e = 1; - else if (!hex && !got_d && (*p == 'd' || *p == 'D')) - got_dot = got_d = 1; - else if (!hex && !got_dot && *p == '.') - got_dot = 1; - else if (((got_e && (p[-1] == 'e' || p[-1] == 'E')) - || (got_d && (p[-1] == 'd' || p[-1] == 'D'))) - && (*p == '-' || *p == '+')) - /* This is the sign of the exponent, not the end of the - number. */ - continue; - /* We will take any letters or digits. parse_number will - complain if past the radix, or if L or U are not final. */ - else if ((*p < '0' || *p > '9') - && ((*p < 'a' || *p > 'z') - && (*p < 'A' || *p > 'Z'))) - break; - } - toktype = parse_number (tokstart, p - tokstart, got_dot|got_e|got_d, - &yylval); - if (toktype == ERROR) - { - char *err_copy = (char *) alloca (p - tokstart + 1); - - memcpy (err_copy, tokstart, p - tokstart); - err_copy[p - tokstart] = 0; - error ("Invalid number \"%s\".", err_copy); - } - lexptr = p; - return toktype; - } - - case '+': - case '-': - case '*': - case '/': - case '%': - case '|': - case '&': - case '^': - case '~': - case '!': - case '@': - case '<': - case '>': - case '[': - case ']': - case '?': - case ':': - case '=': - case '{': - case '}': - symbol: - lexptr++; - return c; - } - - if (!(c == '_' || c == '$' - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) - /* We must have come across a bad character (e.g. ';'). */ - error ("Invalid character '%c' in expression.", c); - - namelen = 0; - for (c = tokstart[namelen]; - (c == '_' || c == '$' || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); - c = tokstart[++namelen]); - - /* The token "if" terminates the expression and is NOT - removed from the input stream. */ - - if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') - return 0; - - lexptr += namelen; - - /* Catch specific keywords. */ - - for (i = 0; f77_keywords[i].operator != NULL; i++) - if (STREQN(tokstart, f77_keywords[i].operator, - strlen(f77_keywords[i].operator))) - { - /* lexptr += strlen(f77_keywords[i].operator); */ - yylval.opcode = f77_keywords[i].opcode; - return f77_keywords[i].token; - } - - yylval.sval.ptr = tokstart; - yylval.sval.length = namelen; - - if (*tokstart == '$') - { - write_dollar_variable (yylval.sval); - return VARIABLE; - } - - /* Use token-type TYPENAME for symbols that happen to be defined - currently as names of types; NAME for other symbols. - The caller is not constrained to care about the distinction. */ - { - char *tmp = copy_name (yylval.sval); - struct symbol *sym; - int is_a_field_of_this = 0; - int hextype; - - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, - current_language->la_language == language_cplus - ? &is_a_field_of_this : NULL, - NULL); - if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) - { - yylval.tsym.type = SYMBOL_TYPE (sym); - return TYPENAME; - } - if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) - return TYPENAME; - - /* Input names that aren't symbols but ARE valid hex numbers, - when the input radix permits them, can be names or numbers - depending on the parse. Note we support radixes > 16 here. */ - if (!sym - && ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) - || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) - { - YYSTYPE newlval; /* Its value is ignored. */ - hextype = parse_number (tokstart, namelen, 0, &newlval); - if (hextype == INT) - { - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return NAME_OR_INT; - } - } - - /* Any other kind of symbol */ - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return NAME; - } -} - -void -yyerror (msg) - char *msg; -{ - error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); -} diff --git a/contrib/gdb/gdb/gdba.el b/contrib/gdb/gdb/gdba.el deleted file mode 100644 index 0f715864228..00000000000 --- a/contrib/gdb/gdb/gdba.el +++ /dev/null @@ -1,2607 +0,0 @@ -(defmacro gud (form) - (` (save-excursion (set-buffer "*gud-a.out*") (, form)))) - -(defun dbug (foo &optional fun) - (save-excursion - (set-buffer (get-buffer-create "*trace*")) - (goto-char (point-max)) - (insert "***" (symbol-name foo) "\n") - (if fun - (funcall fun)))) - - -;;; gud.el --- Grand Unified Debugger mode for gdb, sdb, dbx, or xdb -;;; under Emacs - -;; Author: Eric S. Raymond -;; Maintainer: FSF -;; Version: 1.3 -;; Keywords: unix, tools - -;; Copyright (C) 1992, 1993 Free Software Foundation, Inc. - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; The ancestral gdb.el was by W. Schelter -;; It was later rewritten by rms. Some ideas were due to Masanobu. -;; Grand Unification (sdb/dbx support) by Eric S. Raymond -;; The overloading code was then rewritten by Barry Warsaw , -;; who also hacked the mode to use comint.el. Shane Hartman -;; added support for xdb (HPUX debugger). - -;; Cygnus Support added support for gdb's --annotate=2. - -;;; Code: - -(require 'comint) -(require 'etags) - -;; ====================================================================== -;; GUD commands must be visible in C buffers visited by GUD - -(defvar gud-key-prefix "\C-x\C-a" - "Prefix of all GUD commands valid in C buffers.") - -(global-set-key (concat gud-key-prefix "\C-l") 'gud-refresh) -(global-set-key "\C-x " 'gud-break) ;; backward compatibility hack - -;; ====================================================================== -;; the overloading mechanism - -(defun gud-overload-functions (gud-overload-alist) - "Overload functions defined in GUD-OVERLOAD-ALIST. -This association list has elements of the form - (ORIGINAL-FUNCTION-NAME OVERLOAD-FUNCTION)" - (mapcar - (function (lambda (p) (fset (car p) (symbol-function (cdr p))))) - gud-overload-alist)) - -(defun gud-massage-args (file args) - (error "GUD not properly entered.")) - -(defun gud-marker-filter (str) - (error "GUD not properly entered.")) - -(defun gud-find-file (f) - (error "GUD not properly entered.")) - -;; ====================================================================== -;; command definition - -;; This macro is used below to define some basic debugger interface commands. -;; Of course you may use `gud-def' with any other debugger command, including -;; user defined ones. - -;; A macro call like (gud-def FUNC NAME KEY DOC) expands to a form -;; which defines FUNC to send the command NAME to the debugger, gives -;; it the docstring DOC, and binds that function to KEY in the GUD -;; major mode. The function is also bound in the global keymap with the -;; GUD prefix. - -(defmacro gud-def (func cmd key &optional doc) - "Define FUNC to be a command sending STR and bound to KEY, with -optional doc string DOC. Certain %-escapes in the string arguments -are interpreted specially if present. These are: - - %f name (without directory) of current source file. - %d directory of current source file. - %l number of current source line - %e text of the C lvalue or function-call expression surrounding point. - %a text of the hexadecimal address surrounding point - %p prefix argument to the command (if any) as a number - - The `current' source file is the file of the current buffer (if -we're in a C file) or the source file current at the last break or -step (if we're in the GUD buffer). - The `current' line is that of the current buffer (if we're in a -source file) or the source line number at the last break or step (if -we're in the GUD buffer)." - (list 'progn - (list 'defun func '(arg) - (or doc "") - '(interactive "p") - (list 'gud-call cmd 'arg)) - (if key - (list 'define-key - '(current-local-map) - (concat "\C-c" key) - (list 'quote func))) - (if key - (list 'global-set-key - (list 'concat 'gud-key-prefix key) - (list 'quote func))))) - -;; Where gud-display-frame should put the debugging arrow. This is -;; set by the marker-filter, which scans the debugger's output for -;; indications of the current program counter. -(defvar gud-last-frame nil) - -;; Used by gud-refresh, which should cause gud-display-frame to redisplay -;; the last frame, even if it's been called before and gud-last-frame has -;; been set to nil. -(defvar gud-last-last-frame nil) - -;; All debugger-specific information is collected here. -;; Here's how it works, in case you ever need to add a debugger to the mode. -;; -;; Each entry must define the following at startup: -;; -;; -;; comint-prompt-regexp -;; gud--massage-args -;; gud--marker-filter -;; gud--find-file -;; -;; The job of the massage-args method is to modify the given list of -;; debugger arguments before running the debugger. -;; -;; The job of the marker-filter method is to detect file/line markers in -;; strings and set the global gud-last-frame to indicate what display -;; action (if any) should be triggered by the marker. Note that only -;; whatever the method *returns* is displayed in the buffer; thus, you -;; can filter the debugger's output, interpreting some and passing on -;; the rest. -;; -;; The job of the find-file method is to visit and return the buffer indicated -;; by the car of gud-tag-frame. This may be a file name, a tag name, or -;; something else. - -;; ====================================================================== -;; gdb functions - -;;; History of argument lists passed to gdb. -(defvar gud-gdb-history nil) - -(defun gud-gdb-massage-args (file args) - (cons "--annotate=2" (cons file args))) - - -;; -;; In this world, there are gdb instance objects (of unspecified -;; representation) and buffers associated with those objects. -;; - -;; -;; gdb-instance objects -;; - -(defun make-gdb-instance (proc) - "Create a gdb instance object from a gdb process." - (setq last-proc proc) - (let ((instance (cons 'gdb-instance proc))) - (save-excursion - (set-buffer (process-buffer proc)) - (setq gdb-buffer-instance instance) - (progn - (mapcar 'make-variable-buffer-local gdb-instance-variables) - (setq gdb-buffer-type 'gud) - ;; If we're taking over the buffer of another process, - ;; take over it's ancillery buffers as well. - ;; - (let ((dead (or old-gdb-buffer-instance))) - (mapcar - (function - (lambda (b) - (progn - (set-buffer b) - (if (eq dead gdb-buffer-instance) - (setq gdb-buffer-instance instance))))) - (buffer-list))))) - instance)) - -(defun gdb-instance-process (inst) (cdr inst)) - -;;; The list of instance variables is built up by the expansions of -;;; DEF-GDB-VARIABLE -;;; -(defvar gdb-instance-variables '() - "A list of variables that are local to the gud buffer associated -with a gdb instance.") - -(defmacro def-gdb-variable - (name accessor setter &optional default doc) - (` - (progn - (defvar (, name) (, default) (, (or doc "undocumented"))) - (if (not (memq '(, name) gdb-instance-variables)) - (setq gdb-instance-variables - (cons '(, name) gdb-instance-variables))) - (, (and accessor - (` - (defun (, accessor) (instance) - (let - ((buffer (gdb-get-instance-buffer instance 'gud))) - (and buffer - (save-excursion - (set-buffer buffer) - (, name)))))))) - (, (and setter - (` - (defun (, setter) (instance val) - (let - ((buffer (gdb-get-instance-buffer instance 'gud))) - (and buffer - (save-excursion - (set-buffer buffer) - (setq (, name) val))))))))))) - -(defmacro def-gdb-var (root-symbol &optional default doc) - (let* ((root (symbol-name root-symbol)) - (accessor (intern (concat "gdb-instance-" root))) - (setter (intern (concat "set-gdb-instance-" root))) - (var-name (intern (concat "gdb-" root)))) - (` (def-gdb-variable - (, var-name) (, accessor) (, setter) - (, default) (, doc))))) - -(def-gdb-var buffer-instance nil - "In an instance buffer, the buffer's instance.") - -(def-gdb-var buffer-type nil - "One of the symbols bound in gdb-instance-buffer-rules") - -(def-gdb-var burst "" - "A string of characters from gdb that have not yet been processed.") - -(def-gdb-var input-queue () - "A list of high priority gdb command objects.") - -(def-gdb-var idle-input-queue () - "A list of low priority gdb command objects.") - -(def-gdb-var prompting nil - "True when gdb is idle with no pending input.") - -(def-gdb-var output-sink 'user - "The disposition of the output of the current gdb command. -Possible values are these symbols: - - user -- gdb output should be copied to the gud buffer - for the user to see. - - inferior -- gdb output should be copied to the inferior-io buffer - - pre-emacs -- output should be ignored util the post-prompt - annotation is received. Then the output-sink - becomes:... - emacs -- output should be collected in the partial-output-buffer - for subsequent processing by a command. This is the - disposition of output generated by commands that - gud mode sends to gdb on its own behalf. - post-emacs -- ignore input until the prompt annotation is - received, then go to USER disposition. -") - -(def-gdb-var current-item nil - "The most recent command item sent to gdb.") - -(def-gdb-var pending-triggers '() - "A list of trigger functions that have run later than their output -handlers.") - -(defun in-gdb-instance-context (instance form) - "Funcall `form' in the gud buffer of `instance'" - (save-excursion - (set-buffer (gdb-get-instance-buffer instance 'gud)) - (funcall form))) - -;; end of instance vars - -;; -;; finding instances -;; - -(defun gdb-proc->instance (proc) - (save-excursion - (set-buffer (process-buffer proc)) - gdb-buffer-instance)) - -(defun gdb-mru-instance-buffer () - "Return the most recently used (non-auxiliary) gdb gud buffer." - (save-excursion - (gdb-goto-first-gdb-instance (buffer-list)))) - -(defun gdb-goto-first-gdb-instance (blist) - "Use gdb-mru-instance-buffer -- not this." - (and blist - (progn - (set-buffer (car blist)) - (or (and gdb-buffer-instance - (eq gdb-buffer-type 'gud) - (car blist)) - (gdb-goto-first-gdb-instance (cdr blist)))))) - -(defun buffer-gdb-instance (buf) - (save-excursion - (set-buffer buf) - gdb-buffer-instance)) - -(defun gdb-needed-default-instance () - "Return the most recently used gdb instance or signal an error." - (let ((buffer (gdb-mru-instance-buffer))) - (or (and buffer (buffer-gdb-instance buffer)) - (error "No instance of gdb found.")))) - -(defun gdb-instance-target-string (instance) - "The apparent name of the program being debugged by a gdb instance. -For sure this the root string used in smashing together the gud -buffer's name, even if that doesn't happen to be the name of a -program." - (in-gdb-instance-context - instance - (function (lambda () gud-target-name)))) - - - -;; -;; Instance Buffers. -;; - -;; More than one buffer can be associated with a gdb instance. -;; -;; Each buffer has a TYPE -- a symbol that identifies the function -;; of that particular buffer. -;; -;; The usual gud interaction buffer is given the type `gud' and -;; is constructed specially. -;; -;; Others are constructed by gdb-get-create-instance-buffer and -;; named according to the rules set forth in the gdb-instance-buffer-rules-assoc - -(defun gdb-get-instance-buffer (instance key) - "Return the instance buffer for `instance' tagged with type `key'. -The key should be one of the cars in `gdb-instance-buffer-rules-assoc'." - (save-excursion - (gdb-look-for-tagged-buffer instance key (buffer-list)))) - -(defun gdb-get-create-instance-buffer (instance key) - "Create a new gdb instance buffer of the type specified by `key'. -The key should be one of the cars in `gdb-instance-buffer-rules-assoc'." - (or (gdb-get-instance-buffer instance key) - (let* ((rules (assoc key gdb-instance-buffer-rules-assoc)) - (name (funcall (gdb-rules-name-maker rules) instance)) - (new (get-buffer-create name))) - (save-excursion - (set-buffer new) - (make-variable-buffer-local 'gdb-buffer-type) - (setq gdb-buffer-type key) - (make-variable-buffer-local 'gdb-buffer-instance) - (setq gdb-buffer-instance instance) - (if (cdr (cdr rules)) - (funcall (car (cdr (cdr rules))))) - new)))) - -(defun gdb-rules-name-maker (rules) (car (cdr rules))) - -(defun gdb-look-for-tagged-buffer (instance key bufs) - (let ((retval nil)) - (while (and (not retval) bufs) - (set-buffer (car bufs)) - (if (and (eq gdb-buffer-instance instance) - (eq gdb-buffer-type key)) - (setq retval (car bufs))) - (setq bufs (cdr bufs)) - ) - retval)) - -(defun gdb-instance-buffer-p (buf) - (save-excursion - (set-buffer buf) - (and gdb-buffer-type - (not (eq gdb-buffer-type 'gud))))) - -;; -;; This assoc maps buffer type symbols to rules. Each rule is a list of -;; at least one and possible more functions. The functions have these -;; roles in defining a buffer type: -;; -;; NAME - take an instance, return a name for this type buffer for that -;; instance. -;; The remaining function(s) are optional: -;; -;; MODE - called in new new buffer with no arguments, should establish -;; the proper mode for the buffer. -;; - -(defvar gdb-instance-buffer-rules-assoc '()) - -(defun gdb-set-instance-buffer-rules (buffer-type &rest rules) - (let ((binding (assoc buffer-type gdb-instance-buffer-rules-assoc))) - (if binding - (setcdr binding rules) - (setq gdb-instance-buffer-rules-assoc - (cons (cons buffer-type rules) - gdb-instance-buffer-rules-assoc))))) - -(gdb-set-instance-buffer-rules 'gud 'error) ; gud buffers are an exception to the rules - -;; -;; partial-output buffers -;; -;; These accumulate output from a command executed on -;; behalf of emacs (rather than the user). -;; - -(gdb-set-instance-buffer-rules 'gdb-partial-output-buffer - 'gdb-partial-output-name) - -(defun gdb-partial-output-name (instance) - (concat "*partial-output-" - (gdb-instance-target-string instance) - "*")) - - -(gdb-set-instance-buffer-rules 'gdb-inferior-io - 'gdb-inferior-io-name - 'gud-inferior-io-mode) - -(defun gdb-inferior-io-name (instance) - (concat "*input/output of " - (gdb-instance-target-string instance) - "*")) - -(defvar gdb-inferior-io-mode-map (copy-keymap comint-mode-map)) -(define-key comint-mode-map "\C-c\C-c" 'gdb-inferior-io-interrupt) -(define-key comint-mode-map "\C-c\C-z" 'gdb-inferior-io-stop) -(define-key comint-mode-map "\C-c\C-\\" 'gdb-inferior-io-quit) -(define-key comint-mode-map "\C-c\C-d" 'gdb-inferior-io-eof) - -(defun gud-inferior-io-mode () - "Major mode for gud inferior-io. - -\\{comint-mode-map}" - ;; We want to use comint because it has various nifty and familiar - ;; features. We don't need a process, but comint wants one, so create - ;; a dummy one. - (make-comint (substring (buffer-name) 1 (- (length (buffer-name)) 1)) - "/bin/cat") - (setq major-mode 'gud-inferior-io-mode) - (setq mode-name "Debuggee I/O") - (setq comint-input-sender 'gud-inferior-io-sender) -) - -(defun gud-inferior-io-sender (proc string) - (save-excursion - (set-buffer (process-buffer proc)) - (let ((instance gdb-buffer-instance)) - (set-buffer (gdb-get-instance-buffer instance 'gud)) - (let ((gud-proc (get-buffer-process (current-buffer)))) - (process-send-string gud-proc string) - (process-send-string gud-proc "\n") - )) - )) - -(defun gdb-inferior-io-interrupt (instance) - "Interrupt the program being debugged." - (interactive (list (gdb-needed-default-instance))) - (interrupt-process - (get-buffer-process (gdb-get-instance-buffer instance 'gud)) comint-ptyp)) - -(defun gdb-inferior-io-quit (instance) - "Send quit signal to the program being debugged." - (interactive (list (gdb-needed-default-instance))) - (quit-process - (get-buffer-process (gdb-get-instance-buffer instance 'gud)) comint-ptyp)) - -(defun gdb-inferior-io-stop (instance) - "Stop the program being debugged." - (interactive (list (gdb-needed-default-instance))) - (stop-process - (get-buffer-process (gdb-get-instance-buffer instance 'gud)) comint-ptyp)) - -(defun gdb-inferior-io-eof (instance) - "Send end-of-file to the program being debugged." - (interactive (list (gdb-needed-default-instance))) - (process-send-eof - (get-buffer-process (gdb-get-instance-buffer instance 'gud)))) - - -;; -;; gdb communications -;; - -;; INPUT: things sent to gdb -;; -;; Each instance has a high and low priority -;; input queue. Low priority input is sent only -;; when the high priority queue is idle. -;; -;; The queues are lists. Each element is either -;; a string (indicating user or user-like input) -;; or a list of the form: -;; -;; (INPUT-STRING HANDLER-FN) -;; -;; -;; The handler function will be called from the -;; partial-output buffer when the command completes. -;; This is the way to write commands which -;; invoke gdb commands autonomously. -;; -;; These lists are consumed tail first. -;; - -(defun gdb-send (proc string) - "A comint send filter for gdb. -This filter may simply queue output for a later time." - (let ((instance (gdb-proc->instance proc))) - (gdb-instance-enqueue-input instance (concat string "\n")))) - -;; Note: Stuff enqueued here will be sent to the next prompt, even if it -;; is a query, or other non-top-level prompt. To guarantee stuff will get -;; sent to the top-level prompt, currently it must be put in the idle queue. -;; ^^^^^^^^^ -;; [This should encourage gud extentions that invoke gdb commands to let -;; the user go first; it is not a bug. -t] -;; - -(defun gdb-instance-enqueue-input (instance item) - (if (gdb-instance-prompting instance) - (progn - (gdb-send-item instance item) - (set-gdb-instance-prompting instance nil)) - (set-gdb-instance-input-queue - instance - (cons item (gdb-instance-input-queue instance))))) - -(defun gdb-instance-dequeue-input (instance) - (let ((queue (gdb-instance-input-queue instance))) - (and queue - (if (not (cdr queue)) - (let ((answer (car queue))) - (set-gdb-instance-input-queue instance '()) - answer) - (gdb-take-last-elt queue))))) - -(defun gdb-instance-enqueue-idle-input (instance item) - (if (and (gdb-instance-prompting instance) - (not (gdb-instance-input-queue instance))) - (progn - (gdb-send-item instance item) - (set-gdb-instance-prompting instance nil)) - (set-gdb-instance-idle-input-queue - instance - (cons item (gdb-instance-idle-input-queue instance))))) - -(defun gdb-instance-dequeue-idle-input (instance) - (let ((queue (gdb-instance-idle-input-queue instance))) - (and queue - (if (not (cdr queue)) - (let ((answer (car queue))) - (set-gdb-instance-idle-input-queue instance '()) - answer) - (gdb-take-last-elt queue))))) - -; Don't use this in general. -(defun gdb-take-last-elt (l) - (if (cdr (cdr l)) - (gdb-take-last-elt (cdr l)) - (let ((answer (car (cdr l)))) - (setcdr l '()) - answer))) - - -;; -;; output -- things gdb prints to emacs -;; -;; GDB output is a stream interrupted by annotations. -;; Annotations can be recognized by their beginning -;; with \C-j\C-z\C-z\C-j -;; -;; The tag is a string obeying symbol syntax. -;; -;; The optional part `' can be either the empty string -;; or a space followed by more data relating to the annotation. -;; For example, the SOURCE annotation is followed by a filename, -;; line number and various useless goo. This data must not include -;; any newlines. -;; - - -(defun gud-gdb-marker-filter (string) - "A gud marker filter for gdb." - ;; Bogons don't tell us the process except through scoping crud. - (let ((instance (gdb-proc->instance proc))) - (gdb-output-burst instance string))) - -(defvar gdb-annotation-rules - '(("frames-invalid" gdb-invalidate-frames) - ("breakpoints-invalid" gdb-invalidate-breakpoints) - ("pre-prompt" gdb-pre-prompt) - ("prompt" gdb-prompt) - ("commands" gdb-subprompt) - ("overload-choice" gdb-subprompt) - ("query" gdb-subprompt) - ("prompt-for-continue" gdb-subprompt) - ("post-prompt" gdb-post-prompt) - ("source" gdb-source) - ("starting" gdb-starting) - ("exited" gdb-stopping) - ("signalled" gdb-stopping) - ("signal" gdb-stopping) - ("breakpoint" gdb-stopping) - ("watchpoint" gdb-stopping) - ("stopped" gdb-stopped) - ) - "An assoc mapping annotation tags to functions which process them.") - - -(defun gdb-ignore-annotation (instance args) - nil) - -(defconst gdb-source-spec-regexp - "\\(.*\\):\\([0-9]*\\):[0-9]*:[a-z]*:0x[a-f0-9]*") - -;; Do not use this except as an annotation handler." -(defun gdb-source (instance args) - (string-match gdb-source-spec-regexp args) - ;; Extract the frame position from the marker. - (setq gud-last-frame - (cons - (substring args (match-beginning 1) (match-end 1)) - (string-to-int (substring args - (match-beginning 2) - (match-end 2)))))) - -;; An annotation handler for `prompt'. -;; This sends the next command (if any) to gdb. -(defun gdb-prompt (instance ignored) - (let ((sink (gdb-instance-output-sink instance))) - (cond - ((eq sink 'user) t) - ((eq sink 'post-emacs) - (set-gdb-instance-output-sink instance 'user)) - (t - (set-gdb-instance-output-sink instance 'user) - (error "Phase error in gdb-prompt (got %s)" sink)))) - (let ((highest (gdb-instance-dequeue-input instance))) - (if highest - (gdb-send-item instance highest) - (let ((lowest (gdb-instance-dequeue-idle-input instance))) - (if lowest - (gdb-send-item instance lowest) - (progn - (set-gdb-instance-prompting instance t) - (gud-display-frame))))))) - -;; An annotation handler for non-top-level prompts. -(defun gdb-subprompt (instance ignored) - (let ((highest (gdb-instance-dequeue-input instance))) - (if highest - (gdb-send-item instance highest) - (set-gdb-instance-prompting instance t)))) - -(defun gdb-send-item (instance item) - (set-gdb-instance-current-item instance item) - (if (stringp item) - (progn - (set-gdb-instance-output-sink instance 'user) - (process-send-string (gdb-instance-process instance) - item)) - (progn - (gdb-clear-partial-output instance) - (set-gdb-instance-output-sink instance 'pre-emacs) - (process-send-string (gdb-instance-process instance) - (car item))))) - -;; An annotation handler for `pre-prompt'. -;; This terminates the collection of output from a previous -;; command if that happens to be in effect. -(defun gdb-pre-prompt (instance ignored) - (let ((sink (gdb-instance-output-sink instance))) - (cond - ((eq sink 'user) t) - ((eq sink 'emacs) - (set-gdb-instance-output-sink instance 'post-emacs) - (let ((handler - (car (cdr (gdb-instance-current-item instance))))) - (save-excursion - (set-buffer (gdb-get-create-instance-buffer - instance 'gdb-partial-output-buffer)) - (funcall handler)))) - (t - (set-gdb-instance-output-sink instance 'user) - (error "Output sink phase error 1."))))) - -;; An annotation handler for `starting'. This says that I/O for the subprocess -;; is now the program being debugged, not GDB. -(defun gdb-starting (instance ignored) - (let ((sink (gdb-instance-output-sink instance))) - (cond - ((eq sink 'user) - (set-gdb-instance-output-sink instance 'inferior) - ;; FIXME: need to send queued input - ) - (t (error "Unexpected `starting' annotation"))))) - -;; An annotation handler for `exited' and other annotations which say that -;; I/O for the subprocess is now GDB, not the program being debugged. -(defun gdb-stopping (instance ignored) - (let ((sink (gdb-instance-output-sink instance))) - (cond - ((eq sink 'inferior) - (set-gdb-instance-output-sink instance 'user) - ) - (t (error "Unexpected stopping annotation"))))) - -;; An annotation handler for `stopped'. It is just like gdb-stopping, except -;; that if we already set the output sink to 'user in gdb-stopping, that is -;; fine. -(defun gdb-stopped (instance ignored) - (let ((sink (gdb-instance-output-sink instance))) - (cond - ((eq sink 'inferior) - (set-gdb-instance-output-sink instance 'user) - ) - ((eq sink 'user) - t) - (t (error "Unexpected stopping annotation"))))) - -;; An annotation handler for `post-prompt'. -;; This begins the collection of output from the current -;; command if that happens to be appropriate." -(defun gdb-post-prompt (instance ignored) - (gdb-invalidate-registers instance ignored) - (let ((sink (gdb-instance-output-sink instance))) - (cond - ((eq sink 'user) t) - ((eq sink 'pre-emacs) - (set-gdb-instance-output-sink instance 'emacs)) - - (t - (set-gdb-instance-output-sink instance 'user) - (error "Output sink phase error 3."))))) - -;; Handle a burst of output from a gdb instance. -;; This function is (indirectly) used as a gud-marker-filter. -;; It must return output (if any) to be insterted in the gud -;; buffer. - -(defun gdb-output-burst (instance string) - "Handle a burst of output from a gdb instance. -This function is (indirectly) used as a gud-marker-filter. -It must return output (if any) to be insterted in the gud -buffer." - - (save-match-data - (let ( - ;; Recall the left over burst from last time - (burst (concat (gdb-instance-burst instance) string)) - ;; Start accumulating output for the gud buffer - (output "")) - - ;; Process all the complete markers in this chunk. - - (while (string-match "\n\032\032\\(.*\\)\n" burst) - (let ((annotation (substring burst - (match-beginning 1) - (match-end 1)))) - - ;; Stuff prior to the match is just ordinary output. - ;; It is either concatenated to OUTPUT or directed - ;; elsewhere. - (setq output - (gdb-concat-output - instance - output - (substring burst 0 (match-beginning 0)))) - - ;; Take that stuff off the burst. - (setq burst (substring burst (match-end 0))) - - ;; Parse the tag from the annotation, and maybe its arguments. - (string-match "\\(\\S-*\\) ?\\(.*\\)" annotation) - (let* ((annotation-type (substring annotation - (match-beginning 1) - (match-end 1))) - (annotation-arguments (substring annotation - (match-beginning 2) - (match-end 2))) - (annotation-rule (assoc annotation-type - gdb-annotation-rules))) - ;; Call the handler for this annotation. - (if annotation-rule - (funcall (car (cdr annotation-rule)) - instance - annotation-arguments) - ;; Else the annotation is not recognized. Ignore it silently, - ;; so that GDB can add new annotations without causing - ;; us to blow up. - )))) - - - ;; Does the remaining text end in a partial line? - ;; If it does, then keep part of the burst until we get more. - (if (string-match "\n\\'\\|\n\032\\'\\|\n\032\032.*\\'" - burst) - (progn - ;; Everything before the potential marker start can be output. - (setq output - (gdb-concat-output - instance - output - (substring burst 0 (match-beginning 0)))) - - ;; Everything after, we save, to combine with later input. - (setq burst (substring burst (match-beginning 0)))) - - ;; In case we know the burst contains no partial annotations: - (progn - (setq output (gdb-concat-output instance output burst)) - (setq burst ""))) - - ;; Save the remaining burst for the next call to this function. - (set-gdb-instance-burst instance burst) - output))) - -(defun gdb-concat-output (instance so-far new) - (let ((sink (gdb-instance-output-sink instance))) - (cond - ((eq sink 'user) (concat so-far new)) - ((or (eq sink 'pre-emacs) (eq sink 'post-emacs)) so-far) - ((eq sink 'emacs) - (gdb-append-to-partial-output instance new) - so-far) - ((eq sink 'inferior) - (gdb-append-to-inferior-io instance new) - so-far) - (t (error "Bogon output sink %S" sink))))) - -(defun gdb-append-to-partial-output (instance string) - (save-excursion - (set-buffer - (gdb-get-create-instance-buffer - instance 'gdb-partial-output-buffer)) - (goto-char (point-max)) - (insert string))) - -(defun gdb-clear-partial-output (instance) - (save-excursion - (set-buffer - (gdb-get-create-instance-buffer - instance 'gdb-partial-output-buffer)) - (delete-region (point-min) (point-max)))) - -(defun gdb-append-to-inferior-io (instance string) - (save-excursion - (set-buffer - (gdb-get-create-instance-buffer - instance 'gdb-inferior-io)) - (goto-char (point-max)) - (insert-before-markers string)) - (gud-display-buffer - (gdb-get-create-instance-buffer instance - 'gdb-inferior-io))) - -(defun gdb-clear-inferior-io (instance) - (save-excursion - (set-buffer - (gdb-get-create-instance-buffer - instance 'gdb-inferior-io)) - (delete-region (point-min) (point-max)))) - - - -;; One trick is to have a command who's output is always available in -;; a buffer of it's own, and is always up to date. We build several -;; buffers of this type. -;; -;; There are two aspects to this: gdb has to tell us when the output -;; for that command might have changed, and we have to be able to run -;; the command behind the user's back. -;; -;; The idle input queue and the output phasing associated with -;; the instance variable `(gdb-instance-output-sink instance)' help -;; us to run commands behind the user's back. -;; -;; Below is the code for specificly managing buffers of output from one -;; command. -;; - - -;; The trigger function is suitable for use in the assoc GDB-ANNOTATION-RULES -;; It adds an idle input for the command we are tracking. It should be the -;; annotation rule binding of whatever gdb sends to tell us this command -;; might have changed it's output. -;; -;; NAME is the fucntion name. DEMAND-PREDICATE tests if output is really needed. -;; GDB-COMMAND is a string of such. OUTPUT-HANDLER is the function bound to the -;; input in the input queue (see comment about ``gdb communications'' above). -(defmacro def-gdb-auto-update-trigger (name demand-predicate gdb-command output-handler) - (` - (defun (, name) (instance &optional ignored) - (if (and ((, demand-predicate) instance) - (not (member '(, name) - (gdb-instance-pending-triggers instance)))) - (progn - (gdb-instance-enqueue-idle-input - instance - (list (, gdb-command) '(, output-handler))) - (set-gdb-instance-pending-triggers - instance - (cons '(, name) - (gdb-instance-pending-triggers instance)))))))) - -(defmacro def-gdb-auto-update-handler (name trigger buf-key) - (` - (defun (, name) () - (set-gdb-instance-pending-triggers - instance - (delq '(, trigger) - (gdb-instance-pending-triggers instance))) - (let ((buf (gdb-get-instance-buffer instance - '(, buf-key)))) - (and buf - (save-excursion - (set-buffer buf) - (let ((p (point)) - (buffer-read-only nil)) - (delete-region (point-min) (point-max)) - (insert-buffer (gdb-get-create-instance-buffer - instance - 'gdb-partial-output-buffer)) - (goto-char p)))))))) - -(defmacro def-gdb-auto-updated-buffer - (buffer-key trigger-name gdb-command output-handler-name) - (` - (progn - (def-gdb-auto-update-trigger (, trigger-name) - ;; The demand predicate: - (lambda (instance) - (gdb-get-instance-buffer instance '(, buffer-key))) - (, gdb-command) - (, output-handler-name)) - (def-gdb-auto-update-handler (, output-handler-name) - (, trigger-name) (, buffer-key))))) - - - -;; -;; Breakpoint buffers -;; -;; These display the output of `info breakpoints'. -;; - - -(gdb-set-instance-buffer-rules 'gdb-breakpoints-buffer - 'gdb-breakpoints-buffer-name - 'gud-breakpoints-mode) - -(def-gdb-auto-updated-buffer gdb-breakpoints-buffer - ;; This defines the auto update rule for buffers of type - ;; `gdb-breakpoints-buffer'. - ;; - ;; It defines a function to serve as the annotation handler that - ;; handles the `foo-invalidated' message. That function is called: - gdb-invalidate-breakpoints - - ;; To update the buffer, this command is sent to gdb. - "server info breakpoints\n" - - ;; This also defines a function to be the handler for the output - ;; from the command above. That function will copy the output into - ;; the appropriately typed buffer. That function will be called: - gdb-info-breakpoints-handler) - -(defun gdb-breakpoints-buffer-name (instance) - (save-excursion - (set-buffer (process-buffer (gdb-instance-process instance))) - (concat "*breakpoints of " (gdb-instance-target-string instance) "*"))) - -(defun gud-display-breakpoints-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-display-buffer - (gdb-get-create-instance-buffer instance - 'gdb-breakpoints-buffer))) - -(defun gud-frame-breakpoints-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-frame-buffer - (gdb-get-create-instance-buffer instance - 'gdb-breakpoints-buffer))) - -(defvar gud-breakpoints-mode-map nil) -(setq gud-breakpoints-mode-map (make-keymap)) -(suppress-keymap gud-breakpoints-mode-map) -(define-key gud-breakpoints-mode-map " " 'gud-toggle-bp-this-line) -(define-key gud-breakpoints-mode-map "d" 'gud-delete-bp-this-line) - -(defun gud-breakpoints-mode () - "Major mode for gud breakpoints. - -\\{gud-breakpoints-mode-map}" - (setq major-mode 'gud-breakpoints-mode) - (setq mode-name "Breakpoints") - (use-local-map gud-breakpoints-mode-map) - (setq buffer-read-only t) - (gdb-invalidate-breakpoints gdb-buffer-instance)) - -(defun gud-toggle-bp-this-line () - (interactive) - (save-excursion - (beginning-of-line 1) - (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)")) - (error "Not recognized as breakpoint line (demo foo).") - (gdb-instance-enqueue-idle-input - gdb-buffer-instance - (list - (concat - (if (eq ?y (char-after (match-beginning 2))) - "server disable " - "server enable ") - (buffer-substring (match-beginning 0) - (match-end 1)) - "\n") - '(lambda () nil))) - ))) - -(defun gud-delete-bp-this-line () - (interactive) - (save-excursion - (beginning-of-line 1) - (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)")) - (error "Not recognized as breakpoint line (demo foo).") - (gdb-instance-enqueue-idle-input - gdb-buffer-instance - (list - (concat - "server delete " - (buffer-substring (match-beginning 0) - (match-end 1)) - "\n") - '(lambda () nil))) - ))) - - - - -;; -;; Frames buffers. These display a perpetually correct bactracktrace -;; (from the command `where'). -;; -;; Alas, if your stack is deep, they are costly. -;; - -(gdb-set-instance-buffer-rules 'gdb-stack-buffer - 'gdb-stack-buffer-name - 'gud-frames-mode) - -(def-gdb-auto-updated-buffer gdb-stack-buffer - gdb-invalidate-frames - "server where\n" - gdb-info-frames-handler) - -(defun gdb-stack-buffer-name (instance) - (save-excursion - (set-buffer (process-buffer (gdb-instance-process instance))) - (concat "*stack frames of " - (gdb-instance-target-string instance) "*"))) - -(defun gud-display-stack-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-display-buffer - (gdb-get-create-instance-buffer instance - 'gdb-stack-buffer))) - -(defun gud-frame-stack-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-frame-buffer - (gdb-get-create-instance-buffer instance - 'gdb-stack-buffer))) - -(defvar gud-frames-mode-map nil) -(setq gud-frames-mode-map (make-keymap)) -(suppress-keymap gud-frames-mode-map) -(define-key gud-frames-mode-map [mouse-2] - 'gud-frames-select-by-mouse) - -(defun gud-frames-mode () - "Major mode for gud frames. - -\\{gud-frames-mode-map}" - (setq major-mode 'gud-frames-mode) - (setq mode-name "Frames") - (setq buffer-read-only t) - (use-local-map gud-frames-mode-map) - (gdb-invalidate-frames gdb-buffer-instance)) - -(defun gud-get-frame-number () - (save-excursion - (let* ((pos (re-search-backward "^#\\([0-9]*\\)" nil t)) - (n (or (and pos - (string-to-int - (buffer-substring (match-beginning 1) - (match-end 1)))) - 0))) - n))) - -(defun gud-frames-select-by-mouse (e) - (interactive "e") - (let (selection) - (save-excursion - (set-buffer (window-buffer (posn-window (event-end e)))) - (save-excursion - (goto-char (posn-point (event-end e))) - (setq selection (gud-get-frame-number)))) - (select-window (posn-window (event-end e))) - (save-excursion - (set-buffer (gdb-get-instance-buffer (gdb-needed-default-instance) 'gud)) - (gud-call "fr %p" selection) - (gud-display-frame)))) - - -;; -;; Registers buffers -;; - -(def-gdb-auto-updated-buffer gdb-registers-buffer - gdb-invalidate-registers - "server info registers\n" - gdb-info-registers-handler) - -(gdb-set-instance-buffer-rules 'gdb-registers-buffer - 'gdb-registers-buffer-name - 'gud-registers-mode) - -(defvar gud-registers-mode-map nil) -(setq gud-registers-mode-map (make-keymap)) -(suppress-keymap gud-registers-mode-map) - -(defun gud-registers-mode () - "Major mode for gud registers. - -\\{gud-registers-mode-map}" - (setq major-mode 'gud-registers-mode) - (setq mode-name "Registers") - (setq buffer-read-only t) - (use-local-map gud-registers-mode-map) - (gdb-invalidate-registers gdb-buffer-instance)) - -(defun gdb-registers-buffer-name (instance) - (save-excursion - (set-buffer (process-buffer (gdb-instance-process instance))) - (concat "*registers of " (gdb-instance-target-string instance) "*"))) - -(defun gud-display-registers-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-display-buffer - (gdb-get-create-instance-buffer instance - 'gdb-registers-buffer))) - -(defun gud-frame-registers-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-frame-buffer - (gdb-get-create-instance-buffer instance - 'gdb-registers-buffer))) - - - -;;;; Menu windows: - - -;; MENU-LIST is ((option option option...) (option option ...)...) -;; -(defun gud-display-menu (menu-list) - (setq fill-column (min 120 (- (window-width) - (min 8 (window-width))))) - (while menu-list - (mapcar (function (lambda (x) (insert (symbol-name x) " "))) (car menu-list)) - (fill-paragraph nil) - (insert "\n\n") - (setq menu-list (cdr menu-list))) - (goto-char (point-min)) - (while (re-search-forward "\\([^ \n]+\\)\\(\n\\| \\)" nil t) - (put-text-property (match-beginning 1) (match-end 1) - 'mouse-face 'highlight)) - (goto-char (point-min))) - -(defun gud-goto-menu (menu) - (setq gud-menu-position menu) - (let ((buffer-read-only nil)) - (delete-region (point-min) (point-max)) - (gud-display-menu menu))) - -(defun gud-menu-pick (event) - "Choose an item from a gdb command menu." - (interactive "e") - (let (choice) - (save-excursion - (set-buffer (window-buffer (posn-window (event-start event)))) - (goto-char (posn-point (event-start event))) - (let (beg end) - (skip-chars-forward "^ \t\n") - (setq end (point)) - (skip-chars-backward "^ \t\n") - (setq beg (point)) - (setq choice (buffer-substring beg end)) - (message choice) - (gud-invoke-menu (intern choice)))))) - -(defun gud-invoke-menu (symbol) - (let ((meaning (assoc symbol gud-menu-rules))) - (cond - ((and (consp meaning) - (consp (car (cdr meaning)))) - (gud-goto-menu (car (cdr meaning)))) - (meaning (call-interactively (car (cdr meaning))))))) - - - -(gdb-set-instance-buffer-rules 'gdb-command-buffer - 'gdb-command-buffer-name - 'gud-command-mode) - -(defvar gud-command-mode-map nil) -(setq gud-command-mode-map (make-keymap)) -(suppress-keymap gud-command-mode-map) -(define-key gud-command-mode-map [mouse-2] 'gud-menu-pick) - -(defun gud-command-mode () - "Major mode for gud menu. - -\\{gud-command-mode-map}" (interactive) (setq major-mode 'gud-command-mode) - (setq mode-name "Menu") (setq buffer-read-only t) (use-local-map - gud-command-mode-map) (make-variable-buffer-local 'gud-menu-position) - (if (not gud-menu-position) (gud-goto-menu gud-running-menu))) - -(defun gdb-command-buffer-name (instance) - (save-excursion - (set-buffer (process-buffer (gdb-instance-process instance))) - (concat "*menu of " (gdb-instance-target-string instance) "*"))) - -(defun gud-display-command-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-display-buffer - (gdb-get-create-instance-buffer instance - 'gdb-command-buffer) - 6)) - -(defun gud-frame-command-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-frame-buffer - (gdb-get-create-instance-buffer instance - 'gdb-command-buffer))) - -(defvar gud-selected-menu-titles ()) -(setq gud-selected-menu-titles - '(RUNNING STACK DATA BREAKPOINTS FILES)) - -(setq gud-running-menu - (list - '(RUNNING stack breakpoints files) - '(target run next step continue finish stepi kill help-running))) - -(setq gud-stack-menu - (list - '(running STACK breakpoints files) - '(up down frame backtrace return help-stack))) - -(setq gud-data-menu - (list - '(running stack DATA breakpoints files) - '(whatis ptype print set display undisplay disassemble help-data))) - -(setq gud-breakpoints-menu - (list - '(running stack BREAKPOINTS files) - '(awatch rwatch watch break delete enable disable condition ignore help-breakpoints))) - -(setq gud-files-menu - (list - '(running stack breakpoints FILES) - '(file core-file help-files) - '(exec-file load symbol-file add-symbol-file sharedlibrary))) - -(setq gud-menu-rules - (list - (list 'running gud-running-menu) - (list 'RUNNING gud-running-menu) - (list 'stack gud-stack-menu) - (list 'STACK gud-stack-menu) - (list 'data gud-data-menu) - (list 'DATA gud-data-menu) - (list 'breakpoints gud-breakpoints-menu) - (list 'BREAKPOINTS gud-breakpoints-menu) - (list 'files gud-files-menu) - (list 'FILES gud-files-menu) - - (list 'target 'gud-target) - (list 'kill 'gud-kill) - (list 'stepi 'gud-stepi) - (list 'step 'gud-step) - (list 'next 'gud-next) - (list 'finish 'gud-finish) - (list 'continue 'gud-cont) - (list 'run 'gud-run) - - (list 'backtrace 'gud-backtrace) - (list 'frame 'gud-frame) - (list 'down 'gud-down) - (list 'up 'gud-up) - (list 'return 'gud-return) - - (list 'file 'gud-file) - (list 'core-file 'gud-core-file) - (list 'cd 'gud-cd) - - (list 'exec-file 'gud-exec-file) - (list 'load 'gud-load) - (list 'symbol-file 'gud-symbol-file) - (list 'add-symbol-file 'gud-add-symbol-file) - (list 'sharedlibrary 'gud-sharedlibrary) - )) - - - - -(defun gdb-call-showing-gud (instance command) - (gud-display-gud-buffer instance) - (comint-input-sender (gdb-instance-process instance) command)) - -(defvar gud-target-history ()) - -(defun gud-temp-buffer-show (buf) - (let ((ow (selected-window))) - (unwind-protect - (progn - (pop-to-buffer buf) - - ;; This insertion works around a bug in emacs. - ;; The bug is that all the empty space after a - ;; highlighted word that terminates a buffer - ;; gets highlighted. That's really ugly, so - ;; make sure a highlighted word can't ever - ;; terminate the buffer. - (goto-char (point-max)) - (insert "\n") - (goto-char (point-min)) - - (if (< (window-height) 10) - (enlarge-window (- 10 (window-height))))) - (select-window ow)))) - -(defun gud-target (instance command) - (interactive - (let* ((instance (gdb-needed-default-instance)) - (temp-buffer-show-function (function gud-temp-buffer-show)) - (target-name (completing-read (format "Target type: ") - '(("remote") - ("core") - ("child") - ("exec")) - nil - t - nil - 'gud-target-history))) - (list instance - (cond - ((equal target-name "child") "run") - - ((equal target-name "core") - (concat "target core " - (read-file-name "core file: " - nil - "core" - t))) - - ((equal target-name "exec") - (concat "target exec " - (read-file-name "exec file: " - nil - "a.out" - t))) - - ((equal target-name "remote") - (concat "target remote " - (read-file-name "serial line for remote: " - "/dev/" - "ttya" - t))) - - (t "echo No such target command!"))))) - - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - -(defun gud-backtrace () - (interactive) - (let ((instance (gdb-needed-default-instance))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) - "backtrace")))) - -(defun gud-frame () - (interactive) - (let ((instance (gdb-needed-default-instance))) - (apply comint-input-sender - (list (gdb-instance-process instance) - "frame")))) - -(defun gud-return (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "return " (read-string "Expression to return: "))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - - -(defun gud-file (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "file " (read-file-name "Executable to debug: " - nil - "a.out" - t))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - -(defun gud-core-file (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "core " (read-file-name "Core file to debug: " - nil - "core-file" - t))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - -(defun gud-cd (dir) - (interactive "FChange GDB's default directory: ") - (let ((instance (gdb-needed-default-instance))) - (save-excursion - (set-buffer (gdb-get-instance-buffer instance 'gud)) - (cd dir)) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) - (concat "cd " dir))))) - - -(defun gud-exec-file (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "exec-file " (read-file-name "Init memory from executable: " - nil - "a.out" - t))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - -(defun gud-load (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "load " (read-file-name "Dynamicly load from file: " - nil - "a.out" - t))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - -(defun gud-symbol-file (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "symbol-file " (read-file-name "Read symbol table from file: " - nil - "a.out" - t))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - - -(defun gud-add-symbol-file (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "add-symbol-file " - (read-file-name "Add symbols from file: " - nil - "a.out" - t))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - - -(defun gud-sharedlibrary (instance command) - (interactive - (let ((temp-buffer-show-function (function gud-temp-buffer-show))) - (list (gdb-needed-default-instance) - (concat "sharedlibrary " - (read-string "Load symbols for files matching regexp: "))))) - (gud-display-gud-buffer instance) - (apply comint-input-sender - (list (gdb-instance-process instance) command))) - - - - - -;;;; Window management - - -;;; FIXME: This should only return true for buffers in the current instance -(defun gud-protected-buffer-p (buffer) - "Is BUFFER a buffer which we want to leave displayed?" - (save-excursion - (set-buffer buffer) - (or gdb-buffer-type - overlay-arrow-position))) - -;;; The way we abuse the dedicated-p flag is pretty gross, but seems -;;; to do the right thing. Seeing as there is no way for Lisp code to -;;; get at the use_time field of a window, I'm not sure there exists a -;;; more elegant solution without writing C code. - -(defun gud-display-buffer (buf &optional size) - (let ((must-split nil) - (answer nil)) - (unwind-protect - (progn - (walk-windows - '(lambda (win) - (if (gud-protected-buffer-p (window-buffer win)) - (set-window-dedicated-p win t)))) - (setq answer (get-buffer-window buf)) - (if (not answer) - (let ((window (get-lru-window))) - (if window - (progn - (set-window-buffer window buf) - (setq answer window)) - (setq must-split t))))) - (walk-windows - '(lambda (win) - (if (gud-protected-buffer-p (window-buffer win)) - (set-window-dedicated-p win nil))))) - (if must-split - (let* ((largest (get-largest-window)) - (cur-size (window-height largest)) - (new-size (and size (< size cur-size) (- cur-size size)))) - (setq answer (split-window largest new-size)) - (set-window-buffer answer buf))) - answer)) - -(defun existing-source-window (buffer) - (catch 'found - (save-excursion - (walk-windows - (function - (lambda (win) - (if (and overlay-arrow-position - (eq (window-buffer win) - (marker-buffer overlay-arrow-position))) - (progn - (set-window-buffer win buffer) - (throw 'found win)))))) - nil))) - -(defun gud-display-source-buffer (buffer) - (or (existing-source-window buffer) - (gud-display-buffer buffer))) - -(defun gud-frame-buffer (buf) - (save-excursion - (set-buffer buf) - (make-frame))) - - - -;;; Shared keymap initialization: - -(defun make-windows-menu (map) - (define-key map [menu-bar displays] - (cons "GDB-Windows" (make-sparse-keymap "GDB-Windows"))) - (define-key map [menu-bar displays gdb] - '("Gdb" . gud-display-gud-buffer)) - (define-key map [menu-bar displays registers] - '("Registers" . gud-display-registers-buffer)) - (define-key map [menu-bar displays frames] - '("Stack" . gud-display-stack-buffer)) - (define-key map [menu-bar displays breakpoints] - '("Breakpoints" . gud-display-breakpoints-buffer)) - (define-key map [menu-bar displays commands] - '("Commands" . gud-display-command-buffer))) - -(defun gud-display-gud-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-display-buffer - (gdb-get-create-instance-buffer instance 'gud))) - -(make-windows-menu gud-breakpoints-mode-map) -(make-windows-menu gud-frames-mode-map) -(make-windows-menu gud-registers-mode-map) - - - -(defun make-frames-menu (map) - (define-key map [menu-bar frames] - (cons "GDB-Frames" (make-sparse-keymap "GDB-Frames"))) - (define-key map [menu-bar frames gdb] - '("Gdb" . gud-frame-gud-buffer)) - (define-key map [menu-bar frames registers] - '("Registers" . gud-frame-registers-buffer)) - (define-key map [menu-bar frames frames] - '("Stack" . gud-frame-stack-buffer)) - (define-key map [menu-bar frames breakpoints] - '("Breakpoints" . gud-frame-breakpoints-buffer)) - (define-key map [menu-bar displays commands] - '("Commands" . gud-display-command-buffer))) - -(defun gud-frame-gud-buffer (instance) - (interactive (list (gdb-needed-default-instance))) - (gud-frame-buffer - (gdb-get-create-instance-buffer instance 'gud))) - -(make-frames-menu gud-breakpoints-mode-map) -(make-frames-menu gud-frames-mode-map) -(make-frames-menu gud-registers-mode-map) - - -(defun gud-gdb-find-file (f) - (find-file-noselect f)) - -;;;###autoload -(defun gdb (command-line) - "Run gdb on program FILE in buffer *gud-FILE*. -The directory containing FILE becomes the initial working directory -and source-file directory for your debugger." - (interactive - (list (read-from-minibuffer "Run gdb (like this): " - (if (consp gud-gdb-history) - (car gud-gdb-history) - "gdb ") - nil nil - '(gud-gdb-history . 1)))) - (gud-overload-functions - '((gud-massage-args . gud-gdb-massage-args) - (gud-marker-filter . gud-gdb-marker-filter) - (gud-find-file . gud-gdb-find-file) - )) - - (let* ((words (gud-chop-words command-line)) - (program (car words)) - (file-word (let ((w (cdr words))) - (while (and w (= ?- (aref (car w) 0))) - (setq w (cdr w))) - (car w))) - (args (delq file-word (cdr words))) - (file (expand-file-name file-word)) - (filepart (file-name-nondirectory file)) - (buffer-name (concat "*gud-" filepart "*"))) - (setq gdb-first-time (not (get-buffer-process buffer-name)))) - - (gud-common-init command-line) - - (gud-def gud-break "break %f:%l" "\C-b" "Set breakpoint at current line.") - (gud-def gud-tbreak "tbreak %f:%l" "\C-t" "Set breakpoint at current line.") - (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line") - (gud-def gud-kill "kill" nil "Kill the program.") - (gud-def gud-run "run" nil "Run the program.") - (gud-def gud-stepi "stepi %p" "\C-i" "Step one instruction with display.") - (gud-def gud-step "step %p" "\C-s" "Step one source line with display.") - (gud-def gud-next "next %p" "\C-n" "Step one line (skip functions).") - (gud-def gud-finish "finish" "\C-f" "Finish executing current function.") - (gud-def gud-cont "cont" "\C-r" "Continue with display.") - (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).") - (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).") - (gud-def gud-print "print %e" "\C-p" "Evaluate C expression at point.") - - (setq comint-prompt-regexp "^(.*gdb[+]?) *") - (setq comint-input-sender 'gdb-send) - (run-hooks 'gdb-mode-hook) - (let ((instance - (make-gdb-instance (get-buffer-process (current-buffer))) - )) - (if gdb-first-time (gdb-clear-inferior-io instance))) - ) - - -;; ====================================================================== -;; sdb functions - -;;; History of argument lists passed to sdb. -(defvar gud-sdb-history nil) - -(defvar gud-sdb-needs-tags (not (file-exists-p "/var")) - "If nil, we're on a System V Release 4 and don't need the tags hack.") - -(defvar gud-sdb-lastfile nil) - -(defun gud-sdb-massage-args (file args) - (cons file args)) - -(defun gud-sdb-marker-filter (string) - (cond - ;; System V Release 3.2 uses this format - ((string-match "\\(^0x\\w* in \\|^\\|\n\\)\\([^:\n]*\\):\\([0-9]*\\):.*\n" - string) - (setq gud-last-frame - (cons - (substring string (match-beginning 2) (match-end 2)) - (string-to-int - (substring string (match-beginning 3) (match-end 3)))))) - ;; System V Release 4.0 - ((string-match "^\\(BREAKPOINT\\|STEPPED\\) process [0-9]+ function [^ ]+ in \\(.+\\)\n" - string) - (setq gud-sdb-lastfile - (substring string (match-beginning 2) (match-end 2)))) - ((and gud-sdb-lastfile (string-match "^\\([0-9]+\\):" string)) - (setq gud-last-frame - (cons - gud-sdb-lastfile - (string-to-int - (substring string (match-beginning 1) (match-end 1)))))) - (t - (setq gud-sdb-lastfile nil))) - string) - -(defun gud-sdb-find-file (f) - (if gud-sdb-needs-tags - (find-tag-noselect f) - (find-file-noselect f))) - -;;;###autoload -(defun sdb (command-line) - "Run sdb on program FILE in buffer *gud-FILE*. -The directory containing FILE becomes the initial working directory -and source-file directory for your debugger." - (interactive - (list (read-from-minibuffer "Run sdb (like this): " - (if (consp gud-sdb-history) - (car gud-sdb-history) - "sdb ") - nil nil - '(gud-sdb-history . 1)))) - (if (and gud-sdb-needs-tags - (not (and (boundp 'tags-file-name) (file-exists-p tags-file-name)))) - (error "The sdb support requires a valid tags table to work.")) - (gud-overload-functions '((gud-massage-args . gud-sdb-massage-args) - (gud-marker-filter . gud-sdb-marker-filter) - (gud-find-file . gud-sdb-find-file) - )) - - (gud-common-init command-line) - - (gud-def gud-break "%l b" "\C-b" "Set breakpoint at current line.") - (gud-def gud-tbreak "%l c" "\C-t" "Set temporary breakpoint at current line.") - (gud-def gud-remove "%l d" "\C-d" "Remove breakpoint at current line") - (gud-def gud-step "s %p" "\C-s" "Step one source line with display.") - (gud-def gud-stepi "i %p" "\C-i" "Step one instruction with display.") - (gud-def gud-next "S %p" "\C-n" "Step one line (skip functions).") - (gud-def gud-cont "c" "\C-r" "Continue with display.") - (gud-def gud-print "%e/" "\C-p" "Evaluate C expression at point.") - - (setq comint-prompt-regexp "\\(^\\|\n\\)\\*") - (run-hooks 'sdb-mode-hook) - ) - -;; ====================================================================== -;; dbx functions - -;;; History of argument lists passed to dbx. -(defvar gud-dbx-history nil) - -(defun gud-dbx-massage-args (file args) - (cons file args)) - -(defun gud-dbx-marker-filter (string) - (if (or (string-match - "stopped in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\"" - string) - (string-match - "signal .* in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\"" - string)) - (setq gud-last-frame - (cons - (substring string (match-beginning 2) (match-end 2)) - (string-to-int - (substring string (match-beginning 1) (match-end 1)))))) - string) - -(defun gud-dbx-find-file (f) - (find-file-noselect f)) - -;;;###autoload -(defun dbx (command-line) - "Run dbx on program FILE in buffer *gud-FILE*. -The directory containing FILE becomes the initial working directory -and source-file directory for your debugger." - (interactive - (list (read-from-minibuffer "Run dbx (like this): " - (if (consp gud-dbx-history) - (car gud-dbx-history) - "dbx ") - nil nil - '(gud-dbx-history . 1)))) - (gud-overload-functions '((gud-massage-args . gud-dbx-massage-args) - (gud-marker-filter . gud-dbx-marker-filter) - (gud-find-file . gud-dbx-find-file) - )) - - (gud-common-init command-line) - - (gud-def gud-break "file \"%d%f\"\nstop at %l" - "\C-b" "Set breakpoint at current line.") -;; (gud-def gud-break "stop at \"%f\":%l" -;; "\C-b" "Set breakpoint at current line.") - (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line") - (gud-def gud-step "step %p" "\C-s" "Step one line with display.") - (gud-def gud-stepi "stepi %p" "\C-i" "Step one instruction with display.") - (gud-def gud-next "next %p" "\C-n" "Step one line (skip functions).") - (gud-def gud-cont "cont" "\C-r" "Continue with display.") - (gud-def gud-up "up %p" "<" "Up (numeric arg) stack frames.") - (gud-def gud-down "down %p" ">" "Down (numeric arg) stack frames.") - (gud-def gud-print "print %e" "\C-p" "Evaluate C expression at point.") - - (setq comint-prompt-regexp "^[^)]*dbx) *") - (run-hooks 'dbx-mode-hook) - ) - -;; ====================================================================== -;; xdb (HP PARISC debugger) functions - -;;; History of argument lists passed to xdb. -(defvar gud-xdb-history nil) - -(defvar gud-xdb-directories nil - "*A list of directories that xdb should search for source code. -If nil, only source files in the program directory -will be known to xdb. - -The file names should be absolute, or relative to the directory -containing the executable being debugged.") - -(defun gud-xdb-massage-args (file args) - (nconc (let ((directories gud-xdb-directories) - (result nil)) - (while directories - (setq result (cons (car directories) (cons "-d" result))) - (setq directories (cdr directories))) - (nreverse (cons file result))) - args)) - -(defun gud-xdb-file-name (f) - "Transform a relative pathname to a full pathname in xdb mode" - (let ((result nil)) - (if (file-exists-p f) - (setq result (expand-file-name f)) - (let ((directories gud-xdb-directories)) - (while directories - (let ((path (concat (car directories) "/" f))) - (if (file-exists-p path) - (setq result (expand-file-name path) - directories nil))) - (setq directories (cdr directories))))) - result)) - -;; xdb does not print the lines all at once, so we have to accumulate them -(defvar gud-xdb-accumulation "") - -(defun gud-xdb-marker-filter (string) - (let (result) - (if (or (string-match comint-prompt-regexp string) - (string-match ".*\012" string)) - (setq result (concat gud-xdb-accumulation string) - gud-xdb-accumulation "") - (setq gud-xdb-accumulation (concat gud-xdb-accumulation string))) - (if result - (if (or (string-match "\\([^\n \t:]+\\): [^:]+: \\([0-9]+\\):" result) - (string-match "[^: \t]+:[ \t]+\\([^:]+\\): [^:]+: \\([0-9]+\\):" - result)) - (let ((line (string-to-int - (substring result (match-beginning 2) (match-end 2)))) - (file (gud-xdb-file-name - (substring result (match-beginning 1) (match-end 1))))) - (if file - (setq gud-last-frame (cons file line)))))) - (or result ""))) - -(defun gud-xdb-find-file (f) - (let ((realf (gud-xdb-file-name f))) - (if realf (find-file-noselect realf)))) - -;;;###autoload -(defun xdb (command-line) - "Run xdb on program FILE in buffer *gud-FILE*. -The directory containing FILE becomes the initial working directory -and source-file directory for your debugger. - -You can set the variable 'gud-xdb-directories' to a list of program source -directories if your program contains sources from more than one directory." - (interactive - (list (read-from-minibuffer "Run xdb (like this): " - (if (consp gud-xdb-history) - (car gud-xdb-history) - "xdb ") - nil nil - '(gud-xdb-history . 1)))) - (gud-overload-functions '((gud-massage-args . gud-xdb-massage-args) - (gud-marker-filter . gud-xdb-marker-filter) - (gud-find-file . gud-xdb-find-file))) - - (gud-common-init command-line) - - (gud-def gud-break "b %f:%l" "\C-b" "Set breakpoint at current line.") - (gud-def gud-tbreak "b %f:%l\\t" "\C-t" - "Set temporary breakpoint at current line.") - (gud-def gud-remove "db" "\C-d" "Remove breakpoint at current line") - (gud-def gud-step "s %p" "\C-s" "Step one line with display.") - (gud-def gud-next "S %p" "\C-n" "Step one line (skip functions).") - (gud-def gud-cont "c" "\C-r" "Continue with display.") - (gud-def gud-up "up %p" "<" "Up (numeric arg) stack frames.") - (gud-def gud-down "down %p" ">" "Down (numeric arg) stack frames.") - (gud-def gud-finish "bu\\t" "\C-f" "Finish executing current function.") - (gud-def gud-print "p %e" "\C-p" "Evaluate C expression at point.") - - (setq comint-prompt-regexp "^>") - (make-local-variable 'gud-xdb-accumulation) - (setq gud-xdb-accumulation "") - (run-hooks 'xdb-mode-hook)) - -;; ====================================================================== -;; perldb functions - -;;; History of argument lists passed to perldb. -(defvar gud-perldb-history nil) - -(defun gud-perldb-massage-args (file args) - (cons "-d" (cons file (cons "-emacs" args)))) - -;; There's no guarantee that Emacs will hand the filter the entire -;; marker at once; it could be broken up across several strings. We -;; might even receive a big chunk with several markers in it. If we -;; receive a chunk of text which looks like it might contain the -;; beginning of a marker, we save it here between calls to the -;; filter. -(defvar gud-perldb-marker-acc "") - -(defun gud-perldb-marker-filter (string) - (save-match-data - (setq gud-perldb-marker-acc (concat gud-perldb-marker-acc string)) - (let ((output "")) - - ;; Process all the complete markers in this chunk. - (while (string-match "^\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n" - gud-perldb-marker-acc) - (setq - - ;; Extract the frame position from the marker. - gud-last-frame - (cons (substring gud-perldb-marker-acc (match-beginning 1) (match-end 1)) - (string-to-int (substring gud-perldb-marker-acc - (match-beginning 2) - (match-end 2)))) - - ;; Append any text before the marker to the output we're going - ;; to return - we don't include the marker in this text. - output (concat output - (substring gud-perldb-marker-acc 0 (match-beginning 0))) - - ;; Set the accumulator to the remaining text. - gud-perldb-marker-acc (substring gud-perldb-marker-acc (match-end 0)))) - - ;; Does the remaining text look like it might end with the - ;; beginning of another marker? If it does, then keep it in - ;; gud-perldb-marker-acc until we receive the rest of it. Since we - ;; know the full marker regexp above failed, it's pretty simple to - ;; test for marker starts. - (if (string-match "^\032.*\\'" gud-perldb-marker-acc) - (progn - ;; Everything before the potential marker start can be output. - (setq output (concat output (substring gud-perldb-marker-acc - 0 (match-beginning 0)))) - - ;; Everything after, we save, to combine with later input. - (setq gud-perldb-marker-acc - (substring gud-perldb-marker-acc (match-beginning 0)))) - - (setq output (concat output gud-perldb-marker-acc) - gud-perldb-marker-acc "")) - - output))) - -(defun gud-perldb-find-file (f) - (find-file-noselect f)) - -;;;###autoload -(defun perldb (command-line) - "Run perldb on program FILE in buffer *gud-FILE*. -The directory containing FILE becomes the initial working directory -and source-file directory for your debugger." - (interactive - (list (read-from-minibuffer "Run perldb (like this): " - (if (consp gud-perldb-history) - (car gud-perldb-history) - "perl ") - nil nil - '(gud-perldb-history . 1)))) - (gud-overload-functions '((gud-massage-args . gud-perldb-massage-args) - (gud-marker-filter . gud-perldb-marker-filter) - (gud-find-file . gud-perldb-find-file) - )) - - (gud-common-init command-line) - - (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.") - (gud-def gud-remove "d %l" "\C-d" "Remove breakpoint at current line") - (gud-def gud-step "s" "\C-s" "Step one source line with display.") - (gud-def gud-next "n" "\C-n" "Step one line (skip functions).") - (gud-def gud-cont "c" "\C-r" "Continue with display.") -; (gud-def gud-finish "finish" "\C-f" "Finish executing current function.") -; (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).") -; (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).") - (gud-def gud-print "%e" "\C-p" "Evaluate perl expression at point.") - - (setq comint-prompt-regexp "^ DB<[0-9]+> ") - (run-hooks 'perldb-mode-hook) - ) - -;; -;; End of debugger-specific information -;; - - -;;; When we send a command to the debugger via gud-call, it's annoying -;;; to see the command and the new prompt inserted into the debugger's -;;; buffer; we have other ways of knowing the command has completed. -;;; -;;; If the buffer looks like this: -;;; -------------------- -;;; (gdb) set args foo bar -;;; (gdb) -!- -;;; -------------------- -;;; (the -!- marks the location of point), and we type `C-x SPC' in a -;;; source file to set a breakpoint, we want the buffer to end up like -;;; this: -;;; -------------------- -;;; (gdb) set args foo bar -;;; Breakpoint 1 at 0x92: file make-docfile.c, line 49. -;;; (gdb) -!- -;;; -------------------- -;;; Essentially, the old prompt is deleted, and the command's output -;;; and the new prompt take its place. -;;; -;;; Not echoing the command is easy enough; you send it directly using -;;; comint-input-sender, and it never enters the buffer. However, -;;; getting rid of the old prompt is trickier; you don't want to do it -;;; when you send the command, since that will result in an annoying -;;; flicker as the prompt is deleted, redisplay occurs while Emacs -;;; waits for a response from the debugger, and the new prompt is -;;; inserted. Instead, we'll wait until we actually get some output -;;; from the subprocess before we delete the prompt. If the command -;;; produced no output other than a new prompt, that prompt will most -;;; likely be in the first chunk of output received, so we will delete -;;; the prompt and then replace it with an identical one. If the -;;; command produces output, the prompt is moving anyway, so the -;;; flicker won't be annoying. -;;; -;;; So - when we want to delete the prompt upon receipt of the next -;;; chunk of debugger output, we position gud-delete-prompt-marker at -;;; the start of the prompt; the process filter will notice this, and -;;; delete all text between it and the process output marker. If -;;; gud-delete-prompt-marker points nowhere, we leave the current -;;; prompt alone. -(defvar gud-delete-prompt-marker nil) - - -(defvar gdbish-comint-mode-map (copy-keymap comint-mode-map)) -(define-key gdbish-comint-mode-map "\C-c\M-\C-r" 'gud-display-registers-buffer) -(define-key gdbish-comint-mode-map "\C-c\M-\C-f" 'gud-display-stack-buffer) -(define-key gdbish-comint-mode-map "\C-c\M-\C-b" 'gud-display-breakpoints-buffer) - -(make-windows-menu gdbish-comint-mode-map) -(make-frames-menu gdbish-comint-mode-map) - -(defun gud-mode () - "Major mode for interacting with an inferior debugger process. - - You start it up with one of the commands M-x gdb, M-x sdb, M-x dbx, -or M-x xdb. Each entry point finishes by executing a hook; `gdb-mode-hook', -`sdb-mode-hook', `dbx-mode-hook' or `xdb-mode-hook' respectively. - -After startup, the following commands are available in both the GUD -interaction buffer and any source buffer GUD visits due to a breakpoint stop -or step operation: - -\\[gud-break] sets a breakpoint at the current file and line. In the -GUD buffer, the current file and line are those of the last breakpoint or -step. In a source buffer, they are the buffer's file and current line. - -\\[gud-remove] removes breakpoints on the current file and line. - -\\[gud-refresh] displays in the source window the last line referred to -in the gud buffer. - -\\[gud-step], \\[gud-next], and \\[gud-stepi] do a step-one-line, -step-one-line (not entering function calls), and step-one-instruction -and then update the source window with the current file and position. -\\[gud-cont] continues execution. - -\\[gud-print] tries to find the largest C lvalue or function-call expression -around point, and sends it to the debugger for value display. - -The above commands are common to all supported debuggers except xdb which -does not support stepping instructions. - -Under gdb, sdb and xdb, \\[gud-tbreak] behaves exactly like \\[gud-break], -except that the breakpoint is temporary; that is, it is removed when -execution stops on it. - -Under gdb, dbx, and xdb, \\[gud-up] pops up through an enclosing stack -frame. \\[gud-down] drops back down through one. - -If you are using gdb or xdb, \\[gud-finish] runs execution to the return from -the current function and stops. - -All the keystrokes above are accessible in the GUD buffer -with the prefix C-c, and in all buffers through the prefix C-x C-a. - -All pre-defined functions for which the concept make sense repeat -themselves the appropriate number of times if you give a prefix -argument. - -You may use the `gud-def' macro in the initialization hook to define other -commands. - -Other commands for interacting with the debugger process are inherited from -comint mode, which see." - (interactive) - (comint-mode) - (setq major-mode 'gud-mode) - (setq mode-name "Debugger") - (setq mode-line-process '(": %s")) - (use-local-map (copy-keymap gdbish-comint-mode-map)) - (setq gud-last-frame nil) - (make-local-variable 'comint-prompt-regexp) - (make-local-variable 'gud-delete-prompt-marker) - (setq gud-delete-prompt-marker (make-marker)) - (run-hooks 'gud-mode-hook) -) - -(defvar gud-comint-buffer nil) - -;; Chop STRING into words separated by SPC or TAB and return a list of them. -(defun gud-chop-words (string) - (let ((i 0) (beg 0) - (len (length string)) - (words nil)) - (while (< i len) - (if (memq (aref string i) '(?\t ? )) - (progn - (setq words (cons (substring string beg i) words) - beg (1+ i)) - (while (and (< beg len) (memq (aref string beg) '(?\t ? ))) - (setq beg (1+ beg))) - (setq i (1+ beg))) - (setq i (1+ i)))) - (if (< beg len) - (setq words (cons (substring string beg) words))) - (nreverse words))) - -(defvar gud-target-name "--unknown--" - "The apparent name of the program being debugged in a gud buffer. -For sure this the root string used in smashing together the gud -buffer's name, even if that doesn't happen to be the name of a -program.") - -;; Perform initializations common to all debuggers. -(defun gud-common-init (command-line) - (let* ((words (gud-chop-words command-line)) - (program (car words)) - (file-word (let ((w (cdr words))) - (while (and w (= ?- (aref (car w) 0))) - (setq w (cdr w))) - (car w))) - (args (delq file-word (cdr words))) - (file (expand-file-name file-word)) - (filepart (file-name-nondirectory file)) - (buffer-name (concat "*gud-" filepart "*"))) - (switch-to-buffer buffer-name) - (setq default-directory (file-name-directory file)) - (or (bolp) (newline)) - (insert "Current directory is " default-directory "\n") - (let ((old-instance gdb-buffer-instance)) - (apply 'make-comint (concat "gud-" filepart) program nil - (gud-massage-args file args)) - (gud-mode) - (make-variable-buffer-local 'old-gdb-buffer-instance) - (setq old-gdb-buffer-instance old-instance)) - (make-variable-buffer-local 'gud-target-name) - (setq gud-target-name filepart)) - (set-process-filter (get-buffer-process (current-buffer)) 'gud-filter) - (set-process-sentinel (get-buffer-process (current-buffer)) 'gud-sentinel) - (gud-set-buffer) - ) - -(defun gud-set-buffer () - (cond ((eq major-mode 'gud-mode) - (setq gud-comint-buffer (current-buffer))))) - -;; These functions are responsible for inserting output from your debugger -;; into the buffer. The hard work is done by the method that is -;; the value of gud-marker-filter. - -(defun gud-filter (proc string) - ;; Here's where the actual buffer insertion is done - (let ((inhibit-quit t)) - (save-excursion - (set-buffer (process-buffer proc)) - (let (moving output-after-point) - (save-excursion - (goto-char (process-mark proc)) - ;; If we have been so requested, delete the debugger prompt. - (if (marker-buffer gud-delete-prompt-marker) - (progn - (delete-region (point) gud-delete-prompt-marker) - (set-marker gud-delete-prompt-marker nil))) - (insert-before-markers (gud-marker-filter string)) - (setq moving (= (point) (process-mark proc))) - (setq output-after-point (< (point) (process-mark proc))) - ;; Check for a filename-and-line number. - ;; Don't display the specified file - ;; unless (1) point is at or after the position where output appears - ;; and (2) this buffer is on the screen. - (if (and gud-last-frame - (not output-after-point) - (get-buffer-window (current-buffer))) - (gud-display-frame))) - (if moving (goto-char (process-mark proc))))))) - -(defun gud-proc-died (proc) - ;; Stop displaying an arrow in a source file. - (setq overlay-arrow-position nil) - - ;; Kill the dummy process, so that C-x C-c won't worry about it. - (save-excursion - (set-buffer (process-buffer proc)) - (kill-process - (get-buffer-process - (gdb-get-instance-buffer gdb-buffer-instance 'gdb-inferior-io)))) - ) - -(defun gud-sentinel (proc msg) - (cond ((null (buffer-name (process-buffer proc))) - ;; buffer killed - (gud-proc-died proc) - (set-process-buffer proc nil)) - ((memq (process-status proc) '(signal exit)) - (gud-proc-died proc) - - ;; Fix the mode line. - (setq mode-line-process - (concat ": " - (symbol-name (process-status proc)))) - (let* ((obuf (current-buffer))) - ;; save-excursion isn't the right thing if - ;; process-buffer is current-buffer - (unwind-protect - (progn - ;; Write something in *compilation* and hack its mode line, - (set-buffer (process-buffer proc)) - ;; Force mode line redisplay soon - (set-buffer-modified-p (buffer-modified-p)) - (if (eobp) - (insert ?\n mode-name " " msg) - (save-excursion - (goto-char (point-max)) - (insert ?\n mode-name " " msg))) - ;; If buffer and mode line will show that the process - ;; is dead, we can delete it now. Otherwise it - ;; will stay around until M-x list-processes. - (delete-process proc)) - ;; Restore old buffer, but don't restore old point - ;; if obuf is the gud buffer. - (set-buffer obuf)))))) - -(defun gud-display-frame () - "Find and obey the last filename-and-line marker from the debugger. -Obeying it means displaying in another window the specified file and line." - (interactive) - (if gud-last-frame - (progn -; (gud-set-buffer) - (gud-display-line (car gud-last-frame) (cdr gud-last-frame)) - (setq gud-last-last-frame gud-last-frame - gud-last-frame nil)))) - -;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen -;; and that its line LINE is visible. -;; Put the overlay-arrow on the line LINE in that buffer. -;; Most of the trickiness in here comes from wanting to preserve the current -;; region-restriction if that's possible. We use an explicit display-buffer -;; to get around the fact that this is called inside a save-excursion. - -(defun gud-display-line (true-file line) - (let* ((buffer (gud-find-file true-file)) - (window (gud-display-source-buffer buffer)) - (pos)) - (if (not window) - (error "foo bar baz")) -;;; (if (equal buffer (current-buffer)) -;;; nil -;;; (setq buffer-read-only nil)) - (save-excursion -;;; (setq buffer-read-only t) - (set-buffer buffer) - (save-restriction - (widen) - (goto-line line) - (setq pos (point)) - (setq overlay-arrow-string "=>") - (or overlay-arrow-position - (setq overlay-arrow-position (make-marker))) - (set-marker overlay-arrow-position (point) (current-buffer))) - (cond ((or (< pos (point-min)) (> pos (point-max))) - (widen) - (goto-char pos)))) - (set-window-point window overlay-arrow-position))) - -;;; The gud-call function must do the right thing whether its invoking -;;; keystroke is from the GUD buffer itself (via major-mode binding) -;;; or a C buffer. In the former case, we want to supply data from -;;; gud-last-frame. Here's how we do it: - -(defun gud-format-command (str arg) - (let ((insource (not (eq (current-buffer) gud-comint-buffer)))) - (if (string-match "\\(.*\\)%f\\(.*\\)" str) - (setq str (concat - (substring str (match-beginning 1) (match-end 1)) - (file-name-nondirectory (if insource - (buffer-file-name) - (car gud-last-frame))) - (substring str (match-beginning 2) (match-end 2))))) - (if (string-match "\\(.*\\)%d\\(.*\\)" str) - (setq str (concat - (substring str (match-beginning 1) (match-end 1)) - (file-name-directory (if insource - (buffer-file-name) - (car gud-last-frame))) - (substring str (match-beginning 2) (match-end 2))))) - (if (string-match "\\(.*\\)%l\\(.*\\)" str) - (setq str (concat - (substring str (match-beginning 1) (match-end 1)) - (if insource - (save-excursion - (beginning-of-line) - (save-restriction (widen) - (1+ (count-lines 1 (point))))) - (cdr gud-last-frame)) - (substring str (match-beginning 2) (match-end 2))))) - (if (string-match "\\(.*\\)%e\\(.*\\)" str) - (setq str (concat - (substring str (match-beginning 1) (match-end 1)) - (find-c-expr) - (substring str (match-beginning 2) (match-end 2))))) - (if (string-match "\\(.*\\)%a\\(.*\\)" str) - (setq str (concat - (substring str (match-beginning 1) (match-end 1)) - (gud-read-address) - (substring str (match-beginning 2) (match-end 2))))) - (if (string-match "\\(.*\\)%p\\(.*\\)" str) - (setq str (concat - (substring str (match-beginning 1) (match-end 1)) - (if arg (int-to-string arg) "") - (substring str (match-beginning 2) (match-end 2))))) - ) - str - ) - -(defun gud-read-address () - "Return a string containing the core-address found in the buffer at point." - (save-excursion - (let ((pt (point)) found begin) - (setq found (if (search-backward "0x" (- pt 7) t) (point))) - (cond - (found (forward-char 2) - (buffer-substring found - (progn (re-search-forward "[^0-9a-f]") - (forward-char -1) - (point)))) - (t (setq begin (progn (re-search-backward "[^0-9]") - (forward-char 1) - (point))) - (forward-char 1) - (re-search-forward "[^0-9]") - (forward-char -1) - (buffer-substring begin (point))))))) - -(defun gud-call (fmt &optional arg) - (let ((msg (gud-format-command fmt arg))) - (message "Command: %s" msg) - (sit-for 0) - (gud-basic-call msg))) - -(defun gud-basic-call (command) - "Invoke the debugger COMMAND displaying source in other window." - (interactive) - (gud-set-buffer) - (let ((proc (get-buffer-process gud-comint-buffer))) - - ;; Arrange for the current prompt to get deleted. - (save-excursion - (set-buffer gud-comint-buffer) - (goto-char (process-mark proc)) - (beginning-of-line) - (if (looking-at comint-prompt-regexp) - (set-marker gud-delete-prompt-marker (point))) - (apply comint-input-sender (list proc command))))) - -(defun gud-refresh (&optional arg) - "Fix up a possibly garbled display, and redraw the arrow." - (interactive "P") - (recenter arg) - (or gud-last-frame (setq gud-last-frame gud-last-last-frame)) - (gud-display-frame)) - -;;; Code for parsing expressions out of C code. The single entry point is -;;; find-c-expr, which tries to return an lvalue expression from around point. -;;; -;;; The rest of this file is a hacked version of gdbsrc.el by -;;; Debby Ayers , -;;; Rich Schaefer Schlumberger, Austin, Tx. - -(defun find-c-expr () - "Returns the C expr that surrounds point." - (interactive) - (save-excursion - (let ((p) (expr) (test-expr)) - (setq p (point)) - (setq expr (expr-cur)) - (setq test-expr (expr-prev)) - (while (expr-compound test-expr expr) - (setq expr (cons (car test-expr) (cdr expr))) - (goto-char (car expr)) - (setq test-expr (expr-prev))) - (goto-char p) - (setq test-expr (expr-next)) - (while (expr-compound expr test-expr) - (setq expr (cons (car expr) (cdr test-expr))) - (setq test-expr (expr-next)) - ) - (buffer-substring (car expr) (cdr expr))))) - -(defun expr-cur () - "Returns the expr that point is in; point is set to beginning of expr. -The expr is represented as a cons cell, where the car specifies the point in -the current buffer that marks the beginning of the expr and the cdr specifies -the character after the end of the expr." - (let ((p (point)) (begin) (end)) - (expr-backward-sexp) - (setq begin (point)) - (expr-forward-sexp) - (setq end (point)) - (if (>= p end) - (progn - (setq begin p) - (goto-char p) - (expr-forward-sexp) - (setq end (point)) - ) - ) - (goto-char begin) - (cons begin end))) - -(defun expr-backward-sexp () - "Version of `backward-sexp' that catches errors." - (condition-case nil - (backward-sexp) - (error t))) - -(defun expr-forward-sexp () - "Version of `forward-sexp' that catches errors." - (condition-case nil - (forward-sexp) - (error t))) - -(defun expr-prev () - "Returns the previous expr, point is set to beginning of that expr. -The expr is represented as a cons cell, where the car specifies the point in -the current buffer that marks the beginning of the expr and the cdr specifies -the character after the end of the expr" - (let ((begin) (end)) - (expr-backward-sexp) - (setq begin (point)) - (expr-forward-sexp) - (setq end (point)) - (goto-char begin) - (cons begin end))) - -(defun expr-next () - "Returns the following expr, point is set to beginning of that expr. -The expr is represented as a cons cell, where the car specifies the point in -the current buffer that marks the beginning of the expr and the cdr specifies -the character after the end of the expr." - (let ((begin) (end)) - (expr-forward-sexp) - (expr-forward-sexp) - (setq end (point)) - (expr-backward-sexp) - (setq begin (point)) - (cons begin end))) - -(defun expr-compound-sep (span-start span-end) - "Returns '.' for '->' & '.', returns ' ' for white space, -returns '?' for other punctuation." - (let ((result ? ) - (syntax)) - (while (< span-start span-end) - (setq syntax (char-syntax (char-after span-start))) - (cond - ((= syntax ? ) t) - ((= syntax ?.) (setq syntax (char-after span-start)) - (cond - ((= syntax ?.) (setq result ?.)) - ((and (= syntax ?-) (= (char-after (+ span-start 1)) ?>)) - (setq result ?.) - (setq span-start (+ span-start 1))) - (t (setq span-start span-end) - (setq result ??))))) - (setq span-start (+ span-start 1))) - result)) - -(defun expr-compound (first second) - "Non-nil if concatenating FIRST and SECOND makes a single C token. -The two exprs are represented as a cons cells, where the car -specifies the point in the current buffer that marks the beginning of the -expr and the cdr specifies the character after the end of the expr. -Link exprs of the form: - Expr -> Expr - Expr . Expr - Expr (Expr) - Expr [Expr] - (Expr) Expr - [Expr] Expr" - (let ((span-start (cdr first)) - (span-end (car second)) - (syntax)) - (setq syntax (expr-compound-sep span-start span-end)) - (cond - ((= (car first) (car second)) nil) - ((= (cdr first) (cdr second)) nil) - ((= syntax ?.) t) - ((= syntax ? ) - (setq span-start (char-after (- span-start 1))) - (setq span-end (char-after span-end)) - (cond - ((= span-start ?) ) t ) - ((= span-start ?] ) t ) - ((= span-end ?( ) t ) - ((= span-end ?[ ) t ) - (t nil)) - ) - (t nil)))) - -(provide 'gud) - -;;; gud.el ends here diff --git a/contrib/gdb/gdb/gdbserver/low-linux.c b/contrib/gdb/gdb/gdbserver/low-linux.c deleted file mode 100644 index 106021057a3..00000000000 --- a/contrib/gdb/gdb/gdbserver/low-linux.c +++ /dev/null @@ -1,451 +0,0 @@ -/* Low level interface to ptrace, for the remote server for GDB. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include -#include "frame.h" -#include "inferior.h" - -#include -#include -#include -#include -#include -#include -#if 0 -#include -#endif -#include - -/***************Begin MY defs*********************/ -int quit_flag = 0; -char registers[REGISTER_BYTES]; - -/* Index within `registers' of the first byte of the space for - register N. */ - - -char buf2[MAX_REGISTER_RAW_SIZE]; -/***************End MY defs*********************/ - -#include - -#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) -#include -#endif - -extern char **environ; -extern int errno; -extern int inferior_pid; -void quit (), perror_with_name (); -int query (); - -/* Start an inferior process and returns its pid. - ALLARGS is a vector of program-name and args. - ENV is the environment vector to pass. */ - -int -create_inferior (program, allargs) - char *program; - char **allargs; -{ - int pid; - - pid = fork (); - if (pid < 0) - perror_with_name ("fork"); - - if (pid == 0) - { - ptrace (PTRACE_TRACEME, 0, 0, 0); - - execv (program, allargs); - - fprintf (stderr, "Cannot exec %s: %s.\n", program, - errno < sys_nerr ? sys_errlist[errno] : "unknown error"); - fflush (stderr); - _exit (0177); - } - - return pid; -} - -/* Kill the inferior process. Make us have no inferior. */ - -void -kill_inferior () -{ - if (inferior_pid == 0) - return; - ptrace (PTRACE_KILL, inferior_pid, 0, 0); - wait (0); - /*************inferior_died ();****VK**************/ -} - -/* Return nonzero if the given thread is still alive. */ -int -mythread_alive (pid) - int pid; -{ - return 1; -} - -/* Wait for process, returns status */ - -unsigned char -mywait (status) - char *status; -{ - int pid; - union wait w; - - pid = wait (&w); - if (pid != inferior_pid) - perror_with_name ("wait"); - - if (WIFEXITED (w)) - { - fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w)); - *status = 'W'; - return ((unsigned char) WEXITSTATUS (w)); - } - else if (!WIFSTOPPED (w)) - { - fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w)); - *status = 'X'; - return ((unsigned char) WTERMSIG (w)); - } - - fetch_inferior_registers (0); - - *status = 'T'; - return ((unsigned char) WSTOPSIG (w)); -} - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -myresume (step, signal) - int step; - int signal; -{ - errno = 0; - ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal); - if (errno) - perror_with_name ("ptrace"); -} - - -#if !defined (offsetof) -#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) -#endif - -/* U_REGS_OFFSET is the offset of the registers within the u area. */ -#if !defined (U_REGS_OFFSET) -#define U_REGS_OFFSET \ - ptrace (PT_READ_U, inferior_pid, \ - (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \ - - KERNEL_U_ADDR -#endif - -#ifndef TARGET_M68K -/* this table must line up with REGISTER_NAMES in tm-i386v.h */ -/* symbols like 'EAX' come from */ -static int regmap[] = -{ - EAX, ECX, EDX, EBX, - UESP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS, -}; - -int -i386_register_u_addr (blockend, regnum) - int blockend; - int regnum; -{ -#if 0 - /* this will be needed if fp registers are reinstated */ - /* for now, you can look at them with 'info float' - * sys5 wont let you change them with ptrace anyway - */ - if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) - { - int ubase, fpstate; - struct user u; - ubase = blockend + 4 * (SS + 1) - KSTKSZ; - fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u); - return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM)); - } - else -#endif - return (blockend + 4 * regmap[regnum]); - -} -#else /* TARGET_M68K */ -/* This table must line up with REGISTER_NAMES in tm-m68k.h */ -static int regmap[] = -{ -#ifdef PT_D0 - PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7, - PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP, - PT_SR, PT_PC, -#else - 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, - 17, 18, -#endif -#ifdef PT_FP0 - PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7, - PT_FPCR, PT_FPSR, PT_FPIAR -#else - 21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47 -#endif -}; - -/* BLOCKEND is the value of u.u_ar0, and points to the place where GS - is stored. */ - -int -m68k_linux_register_u_addr (blockend, regnum) - int blockend; - int regnum; -{ - return (blockend + 4 * regmap[regnum]); -} -#endif - -CORE_ADDR -register_addr (regno, blockend) - int regno; - CORE_ADDR blockend; -{ - CORE_ADDR addr; - - if (regno < 0 || regno >= ARCH_NUM_REGS) - error ("Invalid register number %d.", regno); - - REGISTER_U_ADDR (addr, blockend, regno); - - return addr; -} - -/* Fetch one register. */ - -static void -fetch_register (regno) - int regno; -{ - register unsigned int regaddr; - register int i; - - /* Offset of registers within the u area. */ - unsigned int offset; - - offset = U_REGS_OFFSET; - - regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - errno = 0; - *(int *) ®isters[ regno * 4 + i] = ptrace (PTRACE_PEEKUSR, inferior_pid, - (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (int); - if (errno != 0) - { - /* Warning, not error, in case we are attached; sometimes the - kernel doesn't let us at the registers. */ - char *err = strerror (errno); - char *msg = alloca (strlen (err) + 128); - sprintf (msg, "reading register %d: %s", regno, err); - error (msg); - goto error_exit; - } - } - error_exit:; -} - -/* Fetch all registers, or just one, from the child process. */ - -void -fetch_inferior_registers (regno) - int regno; -{ - if (regno == -1 || regno == 0) - for (regno = 0; regno < NUM_REGS-NUM_FREGS; regno++) - fetch_register (regno); - else - fetch_register (regno); -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (regno) - int regno; -{ - register unsigned int regaddr; - register int i; - unsigned int offset = U_REGS_OFFSET; - - if (regno >= 0) - { -#if 0 - if (CANNOT_STORE_REGISTER (regno)) - return; -#endif - regaddr = register_addr (regno, offset); - errno = 0; -#if 0 - if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM) - { - scratch = *(int *) ®isters[REGISTER_BYTE (regno)] | 0x3; - ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - scratch, 0); - if (errno != 0) - { - /* Error, even if attached. Failing to write these two - registers is pretty serious. */ - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } - else -#endif - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) - { - errno = 0; - ptrace (PTRACE_POKEUSR, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - *(int *) ®isters[REGISTER_BYTE (regno) + i]); - if (errno != 0) - { - /* Warning, not error, in case we are attached; sometimes the - kernel doesn't let us at the registers. */ - char *err = strerror (errno); - char *msg = alloca (strlen (err) + 128); - sprintf (msg, "writing register %d: %s", - regno, err); - error (msg); - return; - } - regaddr += sizeof(int); - } - } - else - for (regno = 0; regno < NUM_REGS-NUM_FREGS; regno++) - store_inferior_registers (regno); -} - -/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory - in the NEW_SUN_PTRACE case. - It ought to be straightforward. But it appears that writing did - not write the data that I specified. I cannot understand where - it got the data that it actually did write. */ - -/* Copy LEN bytes from inferior's memory starting at MEMADDR - to debugger memory starting at MYADDR. */ - -void -read_inferior_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - register int i; - /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -sizeof (int); - /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); - /* Allocate buffer of that many longwords. */ - register int *buffer = (int *) alloca (count * sizeof (int)); - - /* Read all the longwords */ - for (i = 0; i < count; i++, addr += sizeof (int)) - { - buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0); - } - - /* Copy appropriate bytes out of the buffer. */ - memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); -} - -/* Copy LEN bytes of data from debugger memory at MYADDR - to inferior's memory at MEMADDR. - On failure (cannot write the inferior) - returns the value of errno. */ - -int -write_inferior_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - register int i; - /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -sizeof (int); - /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); - /* Allocate buffer of that many longwords. */ - register int *buffer = (int *) alloca (count * sizeof (int)); - extern int errno; - - /* Fill start and end extra bytes of buffer with existing memory data. */ - - buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0); - - if (count > 1) - { - buffer[count - 1] - = ptrace (PTRACE_PEEKTEXT, inferior_pid, - addr + (count - 1) * sizeof (int), 0); - } - - /* Copy data to be written over corresponding part of buffer */ - - memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); - - /* Write the entire buffer. */ - - for (i = 0; i < count; i++, addr += sizeof (int)) - { - errno = 0; - ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]); - if (errno) - return errno; - } - - return 0; -} - -void -initialize () -{ - inferior_pid = 0; -} - -int -have_inferior_p () -{ - return inferior_pid != 0; -} diff --git a/contrib/gdb/gdb/gnu-nat.c b/contrib/gdb/gdb/gnu-nat.c deleted file mode 100644 index e48b536aff4..00000000000 --- a/contrib/gdb/gdb/gnu-nat.c +++ /dev/null @@ -1,3357 +0,0 @@ -/* Interface GDB to the GNU Hurd. - Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - Written by Miles Bader - - Some code and ideas from m3-nat.c by Jukka Virtanen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include "gdb_string.h" -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "defs.h" -#include "inferior.h" -#include "symtab.h" -#include "value.h" -#include "language.h" -#include "target.h" -#include "gdb_wait.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "gdbthread.h" -#include "gdb_assert.h" - -#include "gnu-nat.h" - -#include "exc_request_S.h" -#include "notify_S.h" -#include "process_reply_S.h" -#include "msg_reply_S.h" -#include "exc_request_U.h" -#include "msg_U.h" - -static process_t proc_server = MACH_PORT_NULL; - -/* If we've sent a proc_wait_request to the proc server, the pid of the - process we asked about. We can only ever have one outstanding. */ -int proc_wait_pid = 0; - -/* The number of wait requests we've sent, and expect replies from. */ -int proc_waits_pending = 0; - -int gnu_debug_flag = 0; - -/* Forward decls */ - -extern struct target_ops gnu_ops; - -struct inf *make_inf (); -void inf_clear_wait (struct inf *inf); -void inf_cleanup (struct inf *inf); -void inf_startup (struct inf *inf, int pid); -int inf_update_suspends (struct inf *inf); -void inf_set_pid (struct inf *inf, pid_t pid); -void inf_validate_procs (struct inf *inf); -void inf_steal_exc_ports (struct inf *inf); -void inf_restore_exc_ports (struct inf *inf); -struct proc *inf_tid_to_proc (struct inf *inf, int tid); -inline void inf_set_threads_resume_sc (struct inf *inf, - struct proc *run_thread, - int run_others); -inline int inf_set_threads_resume_sc_for_signal_thread (struct inf *inf); -inline void inf_suspend (struct inf *inf); -inline void inf_resume (struct inf *inf); -void inf_set_step_thread (struct inf *inf, struct proc *proc); -void inf_detach (struct inf *inf); -void inf_attach (struct inf *inf, int pid); -void inf_signal (struct inf *inf, enum target_signal sig); -void inf_continue (struct inf *inf); - -#define inf_debug(_inf, msg, args...) \ - do { struct inf *__inf = (_inf); \ - debug ("{inf %d %p}: " msg, __inf->pid, __inf , ##args); } while (0) - -void proc_abort (struct proc *proc, int force); -struct proc *make_proc (struct inf *inf, mach_port_t port, int tid); -struct proc *_proc_free (struct proc *proc); -int proc_update_sc (struct proc *proc); -error_t proc_get_exception_port (struct proc *proc, mach_port_t * port); -error_t proc_set_exception_port (struct proc *proc, mach_port_t port); -static mach_port_t _proc_get_exc_port (struct proc *proc); -void proc_steal_exc_port (struct proc *proc, mach_port_t exc_port); -void proc_restore_exc_port (struct proc *proc); -int proc_trace (struct proc *proc, int set); - -/* Evaluate RPC_EXPR in a scope with the variables MSGPORT and REFPORT bound - to INF's msg port and task port respectively. If it has no msg port, - EIEIO is returned. INF must refer to a running process! */ -#define INF_MSGPORT_RPC(inf, rpc_expr) \ - HURD_MSGPORT_RPC (proc_getmsgport (proc_server, inf->pid, &msgport), \ - (refport = inf->task->port, 0), 0, \ - msgport ? (rpc_expr) : EIEIO) - -/* Like INF_MSGPORT_RPC, but will also resume the signal thread to ensure - there's someone around to deal with the RPC (and resuspend things - afterwards). This effects INF's threads' resume_sc count. */ -#define INF_RESUME_MSGPORT_RPC(inf, rpc_expr) \ - (inf_set_threads_resume_sc_for_signal_thread (inf) \ - ? ({ error_t __e; \ - inf_resume (inf); \ - __e = INF_MSGPORT_RPC (inf, rpc_expr); \ - inf_suspend (inf); \ - __e; }) \ - : EIEIO) - - -/* The state passed by an exception message. */ -struct exc_state - { - int exception; /* The exception code */ - int code, subcode; - mach_port_t handler; /* The real exception port to handle this. */ - mach_port_t reply; /* The reply port from the exception call. */ - }; - -/* The results of the last wait an inf did. */ -struct inf_wait - { - struct target_waitstatus status; /* The status returned to gdb. */ - struct exc_state exc; /* The exception that caused us to return. */ - struct proc *thread; /* The thread in question. */ - int suppress; /* Something trivial happened. */ - }; - -/* The state of an inferior. */ -struct inf - { - /* Fields describing the current inferior. */ - - struct proc *task; /* The mach task. */ - struct proc *threads; /* A linked list of all threads in TASK. */ - - /* True if THREADS needn't be validated by querying the task. We assume that - we and the task in question are the only ones frobbing the thread list, - so as long as we don't let any code run, we don't have to worry about - THREADS changing. */ - int threads_up_to_date; - - pid_t pid; /* The real system PID. */ - - struct inf_wait wait; /* What to return from target_wait. */ - - /* One thread proc in INF may be in `single-stepping mode'. This is it. */ - struct proc *step_thread; - - /* The thread we think is the signal thread. */ - struct proc *signal_thread; - - mach_port_t event_port; /* Where we receive various msgs. */ - - /* True if we think at least one thread in the inferior could currently be - running. */ - unsigned int running:1; - - /* True if the process has stopped (in the proc server sense). Note that - since a proc server `stop' leaves the signal thread running, the inf can - be RUNNING && STOPPED... */ - unsigned int stopped:1; - - /* True if the inferior has no message port. */ - unsigned int nomsg:1; - - /* True if the inferior is traced. */ - unsigned int traced:1; - - /* True if we shouldn't try waiting for the inferior, usually because we - can't for some reason. */ - unsigned int no_wait:1; - - /* When starting a new inferior, we don't try to validate threads until all - the proper execs have been done. This is a count of how many execs we - expect to happen. */ - unsigned pending_execs; - - /* Fields describing global state */ - - /* The task suspend count used when gdb has control. This is normally 1 to - make things easier for us, but sometimes (like when attaching to vital - system servers) it may be desirable to let the task continue to run - (pausing individual threads as necessary). */ - int pause_sc; - - /* The task suspend count left when detaching from a task. */ - int detach_sc; - - /* The initial values used for the run_sc and pause_sc of newly discovered - threads -- see the definition of those fields in struct proc. */ - int default_thread_run_sc; - int default_thread_pause_sc; - int default_thread_detach_sc; - - /* True if the process should be traced when started/attached. Newly - started processes *must* be traced at first to exec them properly, but - if this is false, tracing is turned off as soon it has done so. */ - int want_signals; - - /* True if exceptions from the inferior process should be trapped. This - must be on to use breakpoints. */ - int want_exceptions; - }; - - -int -__proc_pid (struct proc *proc) -{ - return proc->inf->pid; -} - - -/* Update PROC's real suspend count to match it's desired one. Returns true - if we think PROC is now in a runnable state. */ -int -proc_update_sc (struct proc *proc) -{ - int running; - int err = 0; - int delta = proc->sc - proc->cur_sc; - - if (delta) - proc_debug (proc, "sc: %d --> %d", proc->cur_sc, proc->sc); - - if (proc->sc == 0 && proc->state_changed) - /* Since PROC may start running, we must write back any state changes. */ - { - gdb_assert (proc_is_thread (proc)); - proc_debug (proc, "storing back changed thread state"); - err = thread_set_state (proc->port, THREAD_STATE_FLAVOR, - (thread_state_t) &proc->state, THREAD_STATE_SIZE); - if (!err) - proc->state_changed = 0; - } - - if (delta > 0) - { - while (delta-- > 0 && !err) - { - if (proc_is_task (proc)) - err = task_suspend (proc->port); - else - err = thread_suspend (proc->port); - } - } - else - { - while (delta++ < 0 && !err) - { - if (proc_is_task (proc)) - err = task_resume (proc->port); - else - err = thread_resume (proc->port); - } - } - if (!err) - proc->cur_sc = proc->sc; - - /* If we got an error, then the task/thread has disappeared. */ - running = !err && proc->sc == 0; - - proc_debug (proc, "is %s", err ? "dead" : running ? "running" : "suspended"); - if (err) - proc_debug (proc, "err = %s", strerror (err)); - - if (running) - { - proc->aborted = 0; - proc->state_valid = proc->state_changed = 0; - proc->fetched_regs = 0; - } - - return running; -} - - -/* Thread_abort is called on PROC if needed. PROC must be a thread proc. - If PROC is deemed `precious', then nothing is done unless FORCE is true. - In particular, a thread is precious if it's running (in which case forcing - it includes suspending it first), or if it has an exception pending. */ -void -proc_abort (struct proc *proc, int force) -{ - gdb_assert (proc_is_thread (proc)); - - if (!proc->aborted) - { - struct inf *inf = proc->inf; - int running = (proc->cur_sc == 0 && inf->task->cur_sc == 0); - - if (running && force) - { - proc->sc = 1; - inf_update_suspends (proc->inf); - running = 0; - warning ("Stopped %s.", proc_string (proc)); - } - else if (proc == inf->wait.thread && inf->wait.exc.reply && !force) - /* An exception is pending on PROC, which don't mess with. */ - running = 1; - - if (!running) - /* We only abort the thread if it's not actually running. */ - { - thread_abort (proc->port); - proc_debug (proc, "aborted"); - proc->aborted = 1; - } - else - proc_debug (proc, "not aborting"); - } -} - -/* Make sure that the state field in PROC is up to date, and return a pointer - to it, or 0 if something is wrong. If WILL_MODIFY is true, makes sure - that the thread is stopped and aborted first, and sets the state_changed - field in PROC to true. */ -thread_state_t -proc_get_state (struct proc *proc, int will_modify) -{ - int was_aborted = proc->aborted; - - proc_debug (proc, "updating state info%s", - will_modify ? " (with intention to modify)" : ""); - - proc_abort (proc, will_modify); - - if (!was_aborted && proc->aborted) - /* PROC's state may have changed since we last fetched it. */ - proc->state_valid = 0; - - if (!proc->state_valid) - { - mach_msg_type_number_t state_size = THREAD_STATE_SIZE; - error_t err = - thread_get_state (proc->port, THREAD_STATE_FLAVOR, - (thread_state_t) &proc->state, &state_size); - proc_debug (proc, "getting thread state"); - proc->state_valid = !err; - } - - if (proc->state_valid) - { - if (will_modify) - proc->state_changed = 1; - return (thread_state_t) &proc->state; - } - else - return 0; -} - - -/* Set PORT to PROC's exception port. */ -error_t -proc_get_exception_port (struct proc * proc, mach_port_t * port) -{ - if (proc_is_task (proc)) - return task_get_exception_port (proc->port, port); - else - return thread_get_exception_port (proc->port, port); -} - -/* Set PROC's exception port to PORT. */ -error_t -proc_set_exception_port (struct proc * proc, mach_port_t port) -{ - proc_debug (proc, "setting exception port: %d", port); - if (proc_is_task (proc)) - return task_set_exception_port (proc->port, port); - else - return thread_set_exception_port (proc->port, port); -} - -/* Get PROC's exception port, cleaning up a bit if proc has died. */ -static mach_port_t -_proc_get_exc_port (struct proc *proc) -{ - mach_port_t exc_port; - error_t err = proc_get_exception_port (proc, &exc_port); - - if (err) - /* PROC must be dead. */ - { - if (proc->exc_port) - mach_port_deallocate (mach_task_self (), proc->exc_port); - proc->exc_port = MACH_PORT_NULL; - if (proc->saved_exc_port) - mach_port_deallocate (mach_task_self (), proc->saved_exc_port); - proc->saved_exc_port = MACH_PORT_NULL; - } - - return exc_port; -} - -/* Replace PROC's exception port with EXC_PORT, unless it's already been - done. Stash away any existing exception port so we can restore it later. */ -void -proc_steal_exc_port (struct proc *proc, mach_port_t exc_port) -{ - mach_port_t cur_exc_port = _proc_get_exc_port (proc); - - if (cur_exc_port) - { - error_t err = 0; - - proc_debug (proc, "inserting exception port: %d", exc_port); - - if (cur_exc_port != exc_port) - /* Put in our exception port. */ - err = proc_set_exception_port (proc, exc_port); - - if (err || cur_exc_port == proc->exc_port) - /* We previously set the exception port, and it's still set. So we - just keep the old saved port which is what the proc set. */ - { - if (cur_exc_port) - mach_port_deallocate (mach_task_self (), cur_exc_port); - } - else - /* Keep a copy of PROC's old exception port so it can be restored. */ - { - if (proc->saved_exc_port) - mach_port_deallocate (mach_task_self (), proc->saved_exc_port); - proc->saved_exc_port = cur_exc_port; - } - - proc_debug (proc, "saved exception port: %d", proc->saved_exc_port); - - if (!err) - proc->exc_port = exc_port; - else - warning ("Error setting exception port for %s: %s", - proc_string (proc), strerror (err)); - } -} - -/* If we previously replaced PROC's exception port, put back what we - found there at the time, unless *our* exception port has since been - overwritten, in which case who knows what's going on. */ -void -proc_restore_exc_port (struct proc *proc) -{ - mach_port_t cur_exc_port = _proc_get_exc_port (proc); - - if (cur_exc_port) - { - error_t err = 0; - - proc_debug (proc, "restoring real exception port"); - - if (proc->exc_port == cur_exc_port) - /* Our's is still there. */ - err = proc_set_exception_port (proc, proc->saved_exc_port); - - if (proc->saved_exc_port) - mach_port_deallocate (mach_task_self (), proc->saved_exc_port); - proc->saved_exc_port = MACH_PORT_NULL; - - if (!err) - proc->exc_port = MACH_PORT_NULL; - else - warning ("Error setting exception port for %s: %s", - proc_string (proc), strerror (err)); - } -} - - -/* Turns hardware tracing in PROC on or off when SET is true or false, - respectively. Returns true on success. */ -int -proc_trace (struct proc *proc, int set) -{ - thread_state_t state = proc_get_state (proc, 1); - - if (!state) - return 0; /* the thread must be dead. */ - - proc_debug (proc, "tracing %s", set ? "on" : "off"); - - if (set) - { - /* XXX We don't get the exception unless the thread has its own - exception port???? */ - if (proc->exc_port == MACH_PORT_NULL) - proc_steal_exc_port (proc, proc->inf->event_port); - THREAD_STATE_SET_TRACED (state); - } - else - THREAD_STATE_CLEAR_TRACED (state); - - return 1; -} - - -/* A variable from which to assign new TIDs. */ -static int next_thread_id = 1; - -/* Returns a new proc structure with the given fields. Also adds a - notification for PORT becoming dead to be sent to INF's notify port. */ -struct proc * -make_proc (struct inf *inf, mach_port_t port, int tid) -{ - error_t err; - mach_port_t prev_port = MACH_PORT_NULL; - struct proc *proc = xmalloc (sizeof (struct proc)); - - proc->port = port; - proc->tid = tid; - proc->inf = inf; - proc->next = 0; - proc->saved_exc_port = MACH_PORT_NULL; - proc->exc_port = MACH_PORT_NULL; - - proc->sc = 0; - proc->cur_sc = 0; - - /* Note that these are all the values for threads; the task simply uses the - corresponding field in INF directly. */ - proc->run_sc = inf->default_thread_run_sc; - proc->pause_sc = inf->default_thread_pause_sc; - proc->detach_sc = inf->default_thread_detach_sc; - proc->resume_sc = proc->run_sc; - - proc->aborted = 0; - proc->dead = 0; - proc->state_valid = 0; - proc->state_changed = 0; - - proc_debug (proc, "is new"); - - /* Get notified when things die. */ - err = - mach_port_request_notification (mach_task_self (), port, - MACH_NOTIFY_DEAD_NAME, 1, - inf->event_port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - &prev_port); - if (err) - warning ("Couldn't request notification for port %d: %s", - port, strerror (err)); - else - { - proc_debug (proc, "notifications to: %d", inf->event_port); - if (prev_port != MACH_PORT_NULL) - mach_port_deallocate (mach_task_self (), prev_port); - } - - if (inf->want_exceptions) - { - if (proc_is_task (proc)) - /* Make the task exception port point to us. */ - proc_steal_exc_port (proc, inf->event_port); - else - /* Just clear thread exception ports -- they default to the - task one. */ - proc_steal_exc_port (proc, MACH_PORT_NULL); - } - - return proc; -} - -/* Frees PROC and any resources it uses, and returns the value of PROC's - next field. */ -struct proc * -_proc_free (struct proc *proc) -{ - struct inf *inf = proc->inf; - struct proc *next = proc->next; - - proc_debug (proc, "freeing..."); - - if (proc == inf->step_thread) - /* Turn off single stepping. */ - inf_set_step_thread (inf, 0); - if (proc == inf->wait.thread) - inf_clear_wait (inf); - if (proc == inf->signal_thread) - inf->signal_thread = 0; - - if (proc->port != MACH_PORT_NULL) - { - if (proc->exc_port != MACH_PORT_NULL) - /* Restore the original exception port. */ - proc_restore_exc_port (proc); - if (proc->cur_sc != 0) - /* Resume the thread/task. */ - { - proc->sc = 0; - proc_update_sc (proc); - } - mach_port_deallocate (mach_task_self (), proc->port); - } - - xfree (proc); - return next; -} - - -struct inf * -make_inf (void) -{ - struct inf *inf = xmalloc (sizeof (struct inf)); - - inf->task = 0; - inf->threads = 0; - inf->threads_up_to_date = 0; - inf->pid = 0; - inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS; - inf->wait.thread = 0; - inf->wait.exc.handler = MACH_PORT_NULL; - inf->wait.exc.reply = MACH_PORT_NULL; - inf->step_thread = 0; - inf->signal_thread = 0; - inf->event_port = MACH_PORT_NULL; - inf->running = 0; - inf->stopped = 0; - inf->nomsg = 1; - inf->traced = 0; - inf->no_wait = 0; - inf->pending_execs = 0; - inf->pause_sc = 1; - inf->detach_sc = 0; - inf->default_thread_run_sc = 0; - inf->default_thread_pause_sc = 0; - inf->default_thread_detach_sc = 0; - inf->want_signals = 1; /* By default */ - inf->want_exceptions = 1; /* By default */ - - return inf; -} - -/* Clear INF's target wait status. */ -void -inf_clear_wait (struct inf *inf) -{ - inf_debug (inf, "clearing wait"); - inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS; - inf->wait.thread = 0; - inf->wait.suppress = 0; - if (inf->wait.exc.handler != MACH_PORT_NULL) - { - mach_port_deallocate (mach_task_self (), inf->wait.exc.handler); - inf->wait.exc.handler = MACH_PORT_NULL; - } - if (inf->wait.exc.reply != MACH_PORT_NULL) - { - mach_port_deallocate (mach_task_self (), inf->wait.exc.reply); - inf->wait.exc.reply = MACH_PORT_NULL; - } -} - - -void -inf_cleanup (struct inf *inf) -{ - inf_debug (inf, "cleanup"); - - inf_clear_wait (inf); - - inf_set_pid (inf, -1); - inf->pid = 0; - inf->running = 0; - inf->stopped = 0; - inf->nomsg = 1; - inf->traced = 0; - inf->no_wait = 0; - inf->pending_execs = 0; - - if (inf->event_port) - { - mach_port_destroy (mach_task_self (), inf->event_port); - inf->event_port = MACH_PORT_NULL; - } -} - -void -inf_startup (struct inf *inf, int pid) -{ - error_t err; - - inf_debug (inf, "startup: pid = %d", pid); - - inf_cleanup (inf); - - /* Make the port on which we receive all events. */ - err = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, &inf->event_port); - if (err) - error ("Error allocating event port: %s", strerror (err)); - - /* Make a send right for it, so we can easily copy it for other people. */ - mach_port_insert_right (mach_task_self (), inf->event_port, - inf->event_port, MACH_MSG_TYPE_MAKE_SEND); - inf_set_pid (inf, pid); -} - - -/* Close current process, if any, and attach INF to process PORT. */ -void -inf_set_pid (struct inf *inf, pid_t pid) -{ - task_t task_port; - struct proc *task = inf->task; - - inf_debug (inf, "setting pid: %d", pid); - - if (pid < 0) - task_port = MACH_PORT_NULL; - else - { - error_t err = proc_pid2task (proc_server, pid, &task_port); - if (err) - error ("Error getting task for pid %d: %s", pid, strerror (err)); - } - - inf_debug (inf, "setting task: %d", task_port); - - if (inf->pause_sc) - task_suspend (task_port); - - if (task && task->port != task_port) - { - inf->task = 0; - inf_validate_procs (inf); /* Trash all the threads. */ - _proc_free (task); /* And the task. */ - } - - if (task_port != MACH_PORT_NULL) - { - inf->task = make_proc (inf, task_port, PROC_TID_TASK); - inf->threads_up_to_date = 0; - } - - if (inf->task) - { - inf->pid = pid; - if (inf->pause_sc) - /* Reflect task_suspend above. */ - inf->task->sc = inf->task->cur_sc = 1; - } - else - inf->pid = -1; -} - - -/* Validates INF's stopped, nomsg and traced field from the actual - proc server state. Note that the traced field is only updated from - the proc server state if we do not have a message port. If we do - have a message port we'd better look at the tracemask itself. */ -static void -inf_validate_procinfo (struct inf *inf) -{ - char *noise; - mach_msg_type_number_t noise_len = 0; - struct procinfo *pi; - mach_msg_type_number_t pi_len = 0; - int info_flags = 0; - error_t err = - proc_getprocinfo (proc_server, inf->pid, &info_flags, - (procinfo_t *) &pi, &pi_len, &noise, &noise_len); - - if (!err) - { - inf->stopped = !!(pi->state & PI_STOPPED); - inf->nomsg = !!(pi->state & PI_NOMSG); - if (inf->nomsg) - inf->traced = !!(pi->state & PI_TRACED); - vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); - if (noise_len > 0) - vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len); - } -} - -/* Validates INF's task suspend count. If it's higher than we expect, - verify with the user before `stealing' the extra count. */ -static void -inf_validate_task_sc (struct inf *inf) -{ - char *noise; - mach_msg_type_number_t noise_len = 0; - struct procinfo *pi; - mach_msg_type_number_t pi_len = 0; - int info_flags = PI_FETCH_TASKINFO; - int suspend_count = -1; - error_t err; - - retry: - err = proc_getprocinfo (proc_server, inf->pid, &info_flags, - (procinfo_t *) &pi, &pi_len, &noise, &noise_len); - if (err) - { - inf->task->dead = 1; /* oh well */ - return; - } - - if (inf->task->cur_sc < pi->taskinfo.suspend_count && suspend_count == -1) - { - /* The proc server might have suspended the task while stopping - it. This happens when the task is handling a traced signal. - Refetch the suspend count. The proc server should be - finished stopping the task by now. */ - suspend_count = pi->taskinfo.suspend_count; - goto retry; - } - - suspend_count = pi->taskinfo.suspend_count; - - vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); - if (noise_len > 0) - vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); - - if (inf->task->cur_sc < suspend_count) - { - int abort; - - target_terminal_ours (); /* Allow I/O. */ - abort = !query ("Pid %d has an additional task suspend count of %d;" - " clear it? ", inf->pid, - suspend_count - inf->task->cur_sc); - target_terminal_inferior (); /* Give it back to the child. */ - - if (abort) - error ("Additional task suspend count left untouched."); - - inf->task->cur_sc = suspend_count; - } -} - -/* Turns tracing for INF on or off, depending on ON, unless it already - is. If INF is running, the resume_sc count of INF's threads will - be modified, and the signal thread will briefly be run to change - the trace state. */ -void -inf_set_traced (struct inf *inf, int on) -{ - if (on == inf->traced) - return; - - if (inf->task && !inf->task->dead) - /* Make it take effect immediately. */ - { - sigset_t mask = on ? ~(sigset_t) 0 : 0; - error_t err = - INF_RESUME_MSGPORT_RPC (inf, msg_set_init_int (msgport, refport, - INIT_TRACEMASK, mask)); - if (err == EIEIO) - { - if (on) - warning ("Can't modify tracing state for pid %d: %s", - inf->pid, "No signal thread"); - inf->traced = on; - } - else if (err) - warning ("Can't modify tracing state for pid %d: %s", - inf->pid, strerror (err)); - else - inf->traced = on; - } - else - inf->traced = on; -} - - -/* Makes all the real suspend count deltas of all the procs in INF - match the desired values. Careful to always do thread/task suspend - counts in the safe order. Returns true if at least one thread is - thought to be running. */ -int -inf_update_suspends (struct inf *inf) -{ - struct proc *task = inf->task; - /* We don't have to update INF->threads even though we're iterating over it - because we'll change a thread only if it already has an existing proc - entry. */ - - inf_debug (inf, "updating suspend counts"); - - if (task) - { - struct proc *thread; - int task_running = (task->sc == 0), thread_running = 0; - - if (task->sc > task->cur_sc) - /* The task is becoming _more_ suspended; do before any threads. */ - task_running = proc_update_sc (task); - - if (inf->pending_execs) - /* When we're waiting for an exec, things may be happening behind our - back, so be conservative. */ - thread_running = 1; - - /* Do all the thread suspend counts. */ - for (thread = inf->threads; thread; thread = thread->next) - thread_running |= proc_update_sc (thread); - - if (task->sc != task->cur_sc) - /* We didn't do the task first, because we wanted to wait for the - threads; do it now. */ - task_running = proc_update_sc (task); - - inf_debug (inf, "%srunning...", - (thread_running && task_running) ? "" : "not "); - - inf->running = thread_running && task_running; - - /* Once any thread has executed some code, we can't depend on the - threads list any more. */ - if (inf->running) - inf->threads_up_to_date = 0; - - return inf->running; - } - - return 0; -} - - -/* Converts a GDB pid to a struct proc. */ -struct proc * -inf_tid_to_thread (struct inf *inf, int tid) -{ - struct proc *thread = inf->threads; - - while (thread) - if (thread->tid == tid) - return thread; - else - thread = thread->next; - return 0; -} - -/* Converts a thread port to a struct proc. */ -struct proc * -inf_port_to_thread (struct inf *inf, mach_port_t port) -{ - struct proc *thread = inf->threads; - while (thread) - if (thread->port == port) - return thread; - else - thread = thread->next; - return 0; -} - - -/* Make INF's list of threads be consistent with reality of TASK. */ -void -inf_validate_procs (struct inf *inf) -{ - thread_array_t threads; - mach_msg_type_number_t num_threads, i; - struct proc *task = inf->task; - - /* If no threads are currently running, this function will guarantee that - things are up to date. The exception is if there are zero threads -- - then it is almost certainly in an odd state, and probably some outside - agent will create threads. */ - inf->threads_up_to_date = inf->threads ? !inf->running : 0; - - if (task) - { - error_t err = task_threads (task->port, &threads, &num_threads); - inf_debug (inf, "fetching threads"); - if (err) - /* TASK must be dead. */ - { - task->dead = 1; - task = 0; - } - } - - if (!task) - { - num_threads = 0; - inf_debug (inf, "no task"); - } - - { - /* Make things normally linear. */ - mach_msg_type_number_t search_start = 0; - /* Which thread in PROCS corresponds to each task thread, & the task. */ - struct proc *matched[num_threads + 1]; - /* The last thread in INF->threads, so we can add to the end. */ - struct proc *last = 0; - /* The current thread we're considering. */ - struct proc *thread = inf->threads; - - bzero (matched, sizeof (matched)); - - while (thread) - { - mach_msg_type_number_t left; - - for (i = search_start, left = num_threads; left; i++, left--) - { - if (i >= num_threads) - i -= num_threads; /* I wrapped around. */ - if (thread->port == threads[i]) - /* We already know about this thread. */ - { - matched[i] = thread; - last = thread; - thread = thread->next; - search_start++; - break; - } - } - - if (!left) - { - proc_debug (thread, "died!"); - thread->port = MACH_PORT_NULL; - thread = _proc_free (thread); /* THREAD is dead. */ - (last ? last->next : inf->threads) = thread; - } - } - - for (i = 0; i < num_threads; i++) - { - if (matched[i]) - /* Throw away the duplicate send right. */ - mach_port_deallocate (mach_task_self (), threads[i]); - else - /* THREADS[I] is a thread we don't know about yet! */ - { - thread = make_proc (inf, threads[i], next_thread_id++); - (last ? last->next : inf->threads) = thread; - last = thread; - proc_debug (thread, "new thread: %d", threads[i]); - add_thread (pid_to_ptid (thread->tid)); /* Tell GDB's generic thread code. */ - } - } - - vm_deallocate (mach_task_self (), - (vm_address_t) threads, (num_threads * sizeof (thread_t))); - } -} - - -/* Makes sure that INF's thread list is synced with the actual process. */ -inline int -inf_update_procs (struct inf *inf) -{ - if (!inf->task) - return 0; - if (!inf->threads_up_to_date) - inf_validate_procs (inf); - return !!inf->task; -} - -/* Sets the resume_sc of each thread in inf. That of RUN_THREAD is set to 0, - and others are set to their run_sc if RUN_OTHERS is true, and otherwise - their pause_sc. */ -inline void -inf_set_threads_resume_sc (struct inf *inf, - struct proc *run_thread, int run_others) -{ - struct proc *thread; - inf_update_procs (inf); - for (thread = inf->threads; thread; thread = thread->next) - if (thread == run_thread) - thread->resume_sc = 0; - else if (run_others) - thread->resume_sc = thread->run_sc; - else - thread->resume_sc = thread->pause_sc; -} - - -/* Cause INF to continue execution immediately; individual threads may still - be suspended (but their suspend counts will be updated). */ -inline void -inf_resume (struct inf *inf) -{ - struct proc *thread; - - inf_update_procs (inf); - - for (thread = inf->threads; thread; thread = thread->next) - thread->sc = thread->resume_sc; - - if (inf->task) - { - if (!inf->pending_execs) - /* Try to make sure our task count is correct -- in the case where - we're waiting for an exec though, things are too volatile, so just - assume things will be reasonable (which they usually will be). */ - inf_validate_task_sc (inf); - inf->task->sc = 0; - } - - inf_update_suspends (inf); -} - -/* Cause INF to stop execution immediately; individual threads may still - be running. */ -inline void -inf_suspend (struct inf *inf) -{ - struct proc *thread; - - inf_update_procs (inf); - - for (thread = inf->threads; thread; thread = thread->next) - thread->sc = thread->pause_sc; - - if (inf->task) - inf->task->sc = inf->pause_sc; - - inf_update_suspends (inf); -} - - -/* INF has one thread PROC that is in single-stepping mode. This - function changes it to be PROC, changing any old step_thread to be - a normal one. A PROC of 0 clears any existing value. */ -void -inf_set_step_thread (struct inf *inf, struct proc *thread) -{ - gdb_assert (!thread || proc_is_thread (thread)); - - if (thread) - inf_debug (inf, "setting step thread: %d/%d", inf->pid, thread->tid); - else - inf_debug (inf, "clearing step thread"); - - if (inf->step_thread != thread) - { - if (inf->step_thread && inf->step_thread->port != MACH_PORT_NULL) - if (!proc_trace (inf->step_thread, 0)) - return; - if (thread && proc_trace (thread, 1)) - inf->step_thread = thread; - else - inf->step_thread = 0; - } -} - - -/* Set up the thread resume_sc's so that only the signal thread is running - (plus whatever other thread are set to always run). Returns true if we - did so, or false if we can't find a signal thread. */ -inline int -inf_set_threads_resume_sc_for_signal_thread (struct inf *inf) -{ - if (inf->signal_thread) - { - inf_set_threads_resume_sc (inf, inf->signal_thread, 0); - return 1; - } - else - return 0; -} - -static void -inf_update_signal_thread (struct inf *inf) -{ - /* XXX for now we assume that if there's a msgport, the 2nd thread is - the signal thread. */ - inf->signal_thread = inf->threads ? inf->threads->next : 0; -} - - -/* Detachs from INF's inferior task, letting it run once again... */ -void -inf_detach (struct inf *inf) -{ - struct proc *task = inf->task; - - inf_debug (inf, "detaching..."); - - inf_clear_wait (inf); - inf_set_step_thread (inf, 0); - - if (task) - { - struct proc *thread; - - inf_validate_procinfo (inf); - - inf_set_traced (inf, 0); - if (inf->stopped) - { - if (inf->nomsg) - inf_continue (inf); - else - inf_signal (inf, TARGET_SIGNAL_0); - } - - proc_restore_exc_port (task); - task->sc = inf->detach_sc; - - for (thread = inf->threads; thread; thread = thread->next) - { - proc_restore_exc_port (thread); - thread->sc = thread->detach_sc; - } - - inf_update_suspends (inf); - } - - inf_cleanup (inf); -} - -/* Attaches INF to the process with process id PID, returning it in a - suspended state suitable for debugging. */ -void -inf_attach (struct inf *inf, int pid) -{ - inf_debug (inf, "attaching: %d", pid); - - if (inf->pid) - inf_detach (inf); - - inf_startup (inf, pid); -} - - -/* Makes sure that we've got our exception ports entrenched in the process. */ -void -inf_steal_exc_ports (struct inf *inf) -{ - struct proc *thread; - - inf_debug (inf, "stealing exception ports"); - - inf_set_step_thread (inf, 0); /* The step thread is special. */ - - proc_steal_exc_port (inf->task, inf->event_port); - for (thread = inf->threads; thread; thread = thread->next) - proc_steal_exc_port (thread, MACH_PORT_NULL); -} - -/* Makes sure the process has its own exception ports. */ -void -inf_restore_exc_ports (struct inf *inf) -{ - struct proc *thread; - - inf_debug (inf, "restoring exception ports"); - - inf_set_step_thread (inf, 0); /* The step thread is special. */ - - proc_restore_exc_port (inf->task); - for (thread = inf->threads; thread; thread = thread->next) - proc_restore_exc_port (thread); -} - - -/* Deliver signal SIG to INF. If INF is stopped, delivering a signal, even - signal 0, will continue it. INF is assumed to be in a paused state, and - the resume_sc's of INF's threads may be affected. */ -void -inf_signal (struct inf *inf, enum target_signal sig) -{ - error_t err = 0; - int host_sig = target_signal_to_host (sig); - -#define NAME target_signal_to_name (sig) - - if (host_sig >= _NSIG) - /* A mach exception. Exceptions are encoded in the signal space by - putting them after _NSIG; this assumes they're positive (and not - extremely large)! */ - { - struct inf_wait *w = &inf->wait; - if (w->status.kind == TARGET_WAITKIND_STOPPED - && w->status.value.sig == sig - && w->thread && !w->thread->aborted) - /* We're passing through the last exception we received. This is - kind of bogus, because exceptions are per-thread whereas gdb - treats signals as per-process. We just forward the exception to - the correct handler, even it's not for the same thread as TID -- - i.e., we pretend it's global. */ - { - struct exc_state *e = &w->exc; - inf_debug (inf, "passing through exception:" - " task = %d, thread = %d, exc = %d" - ", code = %d, subcode = %d", - w->thread->port, inf->task->port, - e->exception, e->code, e->subcode); - err = - exception_raise_request (e->handler, - e->reply, MACH_MSG_TYPE_MOVE_SEND_ONCE, - w->thread->port, inf->task->port, - e->exception, e->code, e->subcode); - } - else - error ("Can't forward spontaneous exception (%s).", NAME); - } - else - /* A Unix signal. */ - if (inf->stopped) - /* The process is stopped and expecting a signal. Just send off a - request and let it get handled when we resume everything. */ - { - inf_debug (inf, "sending %s to stopped process", NAME); - err = - INF_MSGPORT_RPC (inf, - msg_sig_post_untraced_request (msgport, - inf->event_port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - host_sig, 0, - refport)); - if (!err) - /* Posting an untraced signal automatically continues it. - We clear this here rather than when we get the reply - because we'd rather assume it's not stopped when it - actually is, than the reverse. */ - inf->stopped = 0; - } - else - /* It's not expecting it. We have to let just the signal thread - run, and wait for it to get into a reasonable state before we - can continue the rest of the process. When we finally resume the - process the signal we request will be the very first thing that - happens. */ - { - inf_debug (inf, "sending %s to unstopped process" - " (so resuming signal thread)", NAME); - err = - INF_RESUME_MSGPORT_RPC (inf, - msg_sig_post_untraced (msgport, host_sig, - 0, refport)); - } - - if (err == EIEIO) - /* Can't do too much... */ - warning ("Can't deliver signal %s: No signal thread.", NAME); - else if (err) - warning ("Delivering signal %s: %s", NAME, strerror (err)); - -#undef NAME -} - - -/* Continue INF without delivering a signal. This is meant to be used - when INF does not have a message port. */ -void -inf_continue (struct inf *inf) -{ - process_t proc; - error_t err = proc_pid2proc (proc_server, inf->pid, &proc); - - if (!err) - { - inf_debug (inf, "continuing process"); - - err = proc_mark_cont (proc); - if (!err) - { - struct proc *thread; - - for (thread = inf->threads; thread; thread = thread->next) - thread_resume (thread->port); - - inf->stopped = 0; - } - } - - if (err) - warning ("Can't continue process: %s", strerror (err)); -} - - -/* The inferior used for all gdb target ops. */ -struct inf *current_inferior = 0; - -/* The inferior being waited for by gnu_wait. Since GDB is decidely not - multi-threaded, we don't bother to lock this. */ -struct inf *waiting_inf; - -/* Wait for something to happen in the inferior, returning what in STATUS. */ -static ptid_t -gnu_wait (ptid_t tid, struct target_waitstatus *status) -{ - struct msg - { - mach_msg_header_t hdr; - mach_msg_type_t type; - int data[8000]; - } msg; - error_t err; - struct proc *thread; - struct inf *inf = current_inferior; - - extern int exc_server (mach_msg_header_t *, mach_msg_header_t *); - extern int msg_reply_server (mach_msg_header_t *, mach_msg_header_t *); - extern int notify_server (mach_msg_header_t *, mach_msg_header_t *); - extern int process_reply_server (mach_msg_header_t *, mach_msg_header_t *); - - gdb_assert (inf->task); - - if (!inf->threads && !inf->pending_execs) - /* No threads! Assume that maybe some outside agency is frobbing our - task, and really look for new threads. If we can't find any, just tell - the user to try again later. */ - { - inf_validate_procs (inf); - if (!inf->threads && !inf->task->dead) - error ("There are no threads; try again later."); - } - - waiting_inf = inf; - - inf_debug (inf, "waiting for: %d", PIDGET (tid)); - -rewait: - if (proc_wait_pid != inf->pid && !inf->no_wait) - /* Always get information on events from the proc server. */ - { - inf_debug (inf, "requesting wait on pid %d", inf->pid); - - if (proc_wait_pid) - /* The proc server is single-threaded, and only allows a single - outstanding wait request, so we have to cancel the previous one. */ - { - inf_debug (inf, "cancelling previous wait on pid %d", proc_wait_pid); - interrupt_operation (proc_server, 0); - } - - err = - proc_wait_request (proc_server, inf->event_port, inf->pid, WUNTRACED); - if (err) - warning ("wait request failed: %s", strerror (err)); - else - { - inf_debug (inf, "waits pending: %d", proc_waits_pending); - proc_wait_pid = inf->pid; - /* Even if proc_waits_pending was > 0 before, we still won't - get any other replies, because it was either from a - different INF, or a different process attached to INF -- - and the event port, which is the wait reply port, changes - when you switch processes. */ - proc_waits_pending = 1; - } - } - - inf_clear_wait (inf); - - /* What can happen? (1) Dead name notification; (2) Exceptions arrive; - (3) wait reply from the proc server. */ - - inf_debug (inf, "waiting for an event..."); - err = mach_msg (&msg.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, - 0, sizeof (struct msg), inf->event_port, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - /* Re-suspend the task. */ - inf_suspend (inf); - - if (!inf->task && inf->pending_execs) - /* When doing an exec, it's possible that the old task wasn't reused - (e.g., setuid execs). So if the task seems to have disappeared, - attempt to refetch it, as the pid should still be the same. */ - inf_set_pid (inf, inf->pid); - - if (err == EMACH_RCV_INTERRUPTED) - inf_debug (inf, "interrupted"); - else if (err) - error ("Couldn't wait for an event: %s", strerror (err)); - else - { - struct - { - mach_msg_header_t hdr; - mach_msg_type_t err_type; - kern_return_t err; - char noise[200]; - } - reply; - - inf_debug (inf, "event: msgid = %d", msg.hdr.msgh_id); - - /* Handle what we got. */ - if (!notify_server (&msg.hdr, &reply.hdr) - && !exc_server (&msg.hdr, &reply.hdr) - && !process_reply_server (&msg.hdr, &reply.hdr) - && !msg_reply_server (&msg.hdr, &reply.hdr)) - /* Whatever it is, it's something strange. */ - error ("Got a strange event, msg id = %d.", msg.hdr.msgh_id); - - if (reply.err) - error ("Handling event, msgid = %d: %s", - msg.hdr.msgh_id, strerror (reply.err)); - } - - if (inf->pending_execs) - /* We're waiting for the inferior to finish execing. */ - { - struct inf_wait *w = &inf->wait; - enum target_waitkind kind = w->status.kind; - - if (kind == TARGET_WAITKIND_SPURIOUS) - /* Since gdb is actually counting the number of times the inferior - stops, expecting one stop per exec, we only return major events - while execing. */ - { - w->suppress = 1; - inf_debug (inf, "pending_execs = %d, ignoring minor event", - inf->pending_execs); - } - else if (kind == TARGET_WAITKIND_STOPPED - && w->status.value.sig == TARGET_SIGNAL_TRAP) - /* Ah hah! A SIGTRAP from the inferior while starting up probably - means we've succesfully completed an exec! */ - { - if (--inf->pending_execs == 0) - /* We're done! */ - { -#if 0 /* do we need this? */ - prune_threads (1); /* Get rid of the old shell threads */ - renumber_threads (0); /* Give our threads reasonable names. */ -#endif - } - inf_debug (inf, "pending exec completed, pending_execs => %d", - inf->pending_execs); - } - else if (kind == TARGET_WAITKIND_STOPPED) - /* It's possible that this signal is because of a crashed process - being handled by the hurd crash server; in this case, the process - will have an extra task suspend, which we need to know about. - Since the code in inf_resume that normally checks for this is - disabled while INF->pending_execs, we do the check here instead. */ - inf_validate_task_sc (inf); - } - - if (inf->wait.suppress) - /* Some totally spurious event happened that we don't consider - worth returning to gdb. Just keep waiting. */ - { - inf_debug (inf, "suppressing return, rewaiting..."); - inf_resume (inf); - goto rewait; - } - - /* Pass back out our results. */ - bcopy (&inf->wait.status, status, sizeof (*status)); - - thread = inf->wait.thread; - if (thread) - tid = pid_to_ptid (thread->tid); - else - thread = inf_tid_to_thread (inf, PIDGET (tid)); - - if (!thread || thread->port == MACH_PORT_NULL) - { - /* TID is dead; try and find a new thread. */ - if (inf_update_procs (inf) && inf->threads) - tid = pid_to_ptid (inf->threads->tid); /* The first available thread. */ - else - tid = inferior_ptid; /* let wait_for_inferior handle exit case */ - } - - if (thread && PIDGET (tid) >= 0 && status->kind != TARGET_WAITKIND_SPURIOUS - && inf->pause_sc == 0 && thread->pause_sc == 0) - /* If something actually happened to THREAD, make sure we - suspend it. */ - { - thread->sc = 1; - inf_update_suspends (inf); - } - - inf_debug (inf, "returning tid = %d, status = %s (%d)", PIDGET (tid), - status->kind == TARGET_WAITKIND_EXITED ? "EXITED" - : status->kind == TARGET_WAITKIND_STOPPED ? "STOPPED" - : status->kind == TARGET_WAITKIND_SIGNALLED ? "SIGNALLED" - : status->kind == TARGET_WAITKIND_LOADED ? "LOADED" - : status->kind == TARGET_WAITKIND_SPURIOUS ? "SPURIOUS" - : "?", - status->value.integer); - - return tid; -} - - -/* The rpc handler called by exc_server. */ -error_t -S_exception_raise_request (mach_port_t port, mach_port_t reply_port, - thread_t thread_port, task_t task_port, - int exception, int code, int subcode) -{ - struct inf *inf = waiting_inf; - struct proc *thread = inf_port_to_thread (inf, thread_port); - - inf_debug (waiting_inf, - "thread = %d, task = %d, exc = %d, code = %d, subcode = %d", - thread_port, task_port, exception, code, subcode); - - if (!thread) - /* We don't know about thread? */ - { - inf_update_procs (inf); - thread = inf_port_to_thread (inf, thread_port); - if (!thread) - /* Give up, the generating thread is gone. */ - return 0; - } - - mach_port_deallocate (mach_task_self (), thread_port); - mach_port_deallocate (mach_task_self (), task_port); - - if (!thread->aborted) - /* THREAD hasn't been aborted since this exception happened (abortion - clears any exception state), so it must be real. */ - { - /* Store away the details; this will destroy any previous info. */ - inf->wait.thread = thread; - - inf->wait.status.kind = TARGET_WAITKIND_STOPPED; - - if (exception == EXC_BREAKPOINT) - /* GDB likes to get SIGTRAP for breakpoints. */ - { - inf->wait.status.value.sig = TARGET_SIGNAL_TRAP; - mach_port_deallocate (mach_task_self (), reply_port); - } - else - /* Record the exception so that we can forward it later. */ - { - if (thread->exc_port == port) - { - inf_debug (waiting_inf, "Handler is thread exception port <%d>", - thread->saved_exc_port); - inf->wait.exc.handler = thread->saved_exc_port; - } - else - { - inf_debug (waiting_inf, "Handler is task exception port <%d>", - inf->task->saved_exc_port); - inf->wait.exc.handler = inf->task->saved_exc_port; - gdb_assert (inf->task->exc_port == port); - } - if (inf->wait.exc.handler != MACH_PORT_NULL) - /* Add a reference to the exception handler. */ - mach_port_mod_refs (mach_task_self (), - inf->wait.exc.handler, MACH_PORT_RIGHT_SEND, - 1); - - inf->wait.exc.exception = exception; - inf->wait.exc.code = code; - inf->wait.exc.subcode = subcode; - inf->wait.exc.reply = reply_port; - - /* Exceptions are encoded in the signal space by putting them after - _NSIG; this assumes they're positive (and not extremely large)! */ - inf->wait.status.value.sig = - target_signal_from_host (_NSIG + exception); - } - } - else - /* A supppressed exception, which ignore. */ - { - inf->wait.suppress = 1; - mach_port_deallocate (mach_task_self (), reply_port); - } - - return 0; -} - - -/* Fill in INF's wait field after a task has died without giving us more - detailed information. */ -void -inf_task_died_status (struct inf *inf) -{ - warning ("Pid %d died with unknown exit status, using SIGKILL.", inf->pid); - inf->wait.status.kind = TARGET_WAITKIND_SIGNALLED; - inf->wait.status.value.sig = TARGET_SIGNAL_KILL; -} - -/* Notify server routines. The only real one is dead name notification. */ -error_t -do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port) -{ - struct inf *inf = waiting_inf; - - inf_debug (waiting_inf, "port = %d", dead_port); - - if (inf->task && inf->task->port == dead_port) - { - proc_debug (inf->task, "is dead"); - inf->task->port = MACH_PORT_NULL; - if (proc_wait_pid == inf->pid) - /* We have a wait outstanding on the process, which will return more - detailed information, so delay until we get that. */ - inf->wait.suppress = 1; - else - /* We never waited for the process (maybe it wasn't a child), so just - pretend it got a SIGKILL. */ - inf_task_died_status (inf); - } - else - { - struct proc *thread = inf_port_to_thread (inf, dead_port); - if (thread) - { - proc_debug (thread, "is dead"); - thread->port = MACH_PORT_NULL; - } - - if (inf->task->dead) - /* Since the task is dead, its threads are dying with it. */ - inf->wait.suppress = 1; - } - - mach_port_deallocate (mach_task_self (), dead_port); - inf->threads_up_to_date = 0; /* Just in case */ - - return 0; -} - - -static error_t -ill_rpc (char *fun) -{ - warning ("illegal rpc: %s", fun); - return 0; -} - -error_t -do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t count) -{ - return ill_rpc (__FUNCTION__); -} - -error_t -do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name) -{ - return ill_rpc (__FUNCTION__); -} - -error_t -do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name) -{ - return ill_rpc (__FUNCTION__); -} - -error_t -do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t name) -{ - return ill_rpc (__FUNCTION__); -} - -error_t -do_mach_notify_send_once (mach_port_t notify) -{ - return ill_rpc (__FUNCTION__); -} - - -/* Process_reply server routines. We only use process_wait_reply. */ - -error_t -S_proc_wait_reply (mach_port_t reply, error_t err, - int status, int sigcode, rusage_t rusage, pid_t pid) -{ - struct inf *inf = waiting_inf; - - inf_debug (inf, "err = %s, pid = %d, status = 0x%x, sigcode = %d", - err ? strerror (err) : "0", pid, status, sigcode); - - if (err && proc_wait_pid && (!inf->task || !inf->task->port)) - /* Ack. The task has died, but the task-died notification code didn't - tell anyone because it thought a more detailed reply from the - procserver was forthcoming. However, we now learn that won't - happen... So we have to act like the task just died, and this time, - tell the world. */ - inf_task_died_status (inf); - - if (--proc_waits_pending == 0) - /* PROC_WAIT_PID represents the most recent wait. We will always get - replies in order because the proc server is single threaded. */ - proc_wait_pid = 0; - - inf_debug (inf, "waits pending now: %d", proc_waits_pending); - - if (err) - { - if (err != EINTR) - { - warning ("Can't wait for pid %d: %s", inf->pid, strerror (err)); - inf->no_wait = 1; - - /* Since we can't see the inferior's signals, don't trap them. */ - inf_set_traced (inf, 0); - } - } - else if (pid == inf->pid) - { - store_waitstatus (&inf->wait.status, status); - if (inf->wait.status.kind == TARGET_WAITKIND_STOPPED) - /* The process has sent us a signal, and stopped itself in a sane - state pending our actions. */ - { - inf_debug (inf, "process has stopped itself"); - inf->stopped = 1; - } - } - else - inf->wait.suppress = 1; /* Something odd happened. Ignore. */ - - return 0; -} - -error_t -S_proc_setmsgport_reply (mach_port_t reply, error_t err, - mach_port_t old_msg_port) -{ - return ill_rpc (__FUNCTION__); -} - -error_t -S_proc_getmsgport_reply (mach_port_t reply, error_t err, mach_port_t msg_port) -{ - return ill_rpc (__FUNCTION__); -} - - -/* Msg_reply server routines. We only use msg_sig_post_untraced_reply. */ - -error_t -S_msg_sig_post_untraced_reply (mach_port_t reply, error_t err) -{ - struct inf *inf = waiting_inf; - - if (err == EBUSY) - /* EBUSY is what we get when the crash server has grabbed control of the - process and doesn't like what signal we tried to send it. Just act - like the process stopped (using a signal of 0 should mean that the - *next* time the user continues, it will pass signal 0, which the crash - server should like). */ - { - inf->wait.status.kind = TARGET_WAITKIND_STOPPED; - inf->wait.status.value.sig = TARGET_SIGNAL_0; - } - else if (err) - warning ("Signal delivery failed: %s", strerror (err)); - - if (err) - /* We only get this reply when we've posted a signal to a process which we - thought was stopped, and which we expected to continue after the signal. - Given that the signal has failed for some reason, it's reasonable to - assume it's still stopped. */ - inf->stopped = 1; - else - inf->wait.suppress = 1; - - return 0; -} - -error_t -S_msg_sig_post_reply (mach_port_t reply, error_t err) -{ - return ill_rpc (__FUNCTION__); -} - - -/* Returns the number of messages queued for the receive right PORT. */ -static mach_port_msgcount_t -port_msgs_queued (mach_port_t port) -{ - struct mach_port_status status; - error_t err = - mach_port_get_receive_status (mach_task_self (), port, &status); - - if (err) - return 0; - else - return status.mps_msgcount; -} - - -/* Resume execution of the inferior process. - - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. - - TID STEP: - -1 true Single step the current thread allowing other threads to run. - -1 false Continue the current thread allowing other threads to run. - X true Single step the given thread, don't allow any others to run. - X false Continue the given thread, do not allow any others to run. - (Where X, of course, is anything except -1) - - Note that a resume may not `take' if there are pending exceptions/&c - still unprocessed from the last resume we did (any given resume may result - in multiple events returned by wait). - */ -static void -gnu_resume (ptid_t tid, int step, enum target_signal sig) -{ - struct proc *step_thread = 0; - struct inf *inf = current_inferior; - - inf_debug (inf, "tid = %d, step = %d, sig = %d", PIDGET (tid), step, sig); - - inf_validate_procinfo (inf); - - if (sig != TARGET_SIGNAL_0 || inf->stopped) - { - if (sig == TARGET_SIGNAL_0 && inf->nomsg) - inf_continue (inf); - else - inf_signal (inf, sig); - } - else if (inf->wait.exc.reply != MACH_PORT_NULL) - /* We received an exception to which we have chosen not to forward, so - abort the faulting thread, which will perhaps retake it. */ - { - proc_abort (inf->wait.thread, 1); - warning ("Aborting %s with unforwarded exception %s.", - proc_string (inf->wait.thread), - target_signal_to_name (inf->wait.status.value.sig)); - } - - if (port_msgs_queued (inf->event_port)) - /* If there are still messages in our event queue, don't bother resuming - the process, as we're just going to stop it right away anyway. */ - return; - - inf_update_procs (inf); - - if (PIDGET (tid) < 0) - /* Allow all threads to run, except perhaps single-stepping one. */ - { - inf_debug (inf, "running all threads; tid = %d", PIDGET (inferior_ptid)); - tid = inferior_ptid; /* What to step. */ - inf_set_threads_resume_sc (inf, 0, 1); - } - else - /* Just allow a single thread to run. */ - { - struct proc *thread = inf_tid_to_thread (inf, PIDGET (tid)); - if (!thread) - error ("Can't run single thread id %d: no such thread!"); - inf_debug (inf, "running one thread: %d/%d", inf->pid, thread->tid); - inf_set_threads_resume_sc (inf, thread, 0); - } - - if (step) - { - step_thread = inf_tid_to_thread (inf, PIDGET (tid)); - if (!step_thread) - warning ("Can't step thread id %d: no such thread.", PIDGET (tid)); - else - inf_debug (inf, "stepping thread: %d/%d", inf->pid, step_thread->tid); - } - if (step_thread != inf->step_thread) - inf_set_step_thread (inf, step_thread); - - inf_debug (inf, "here we go..."); - inf_resume (inf); -} - - -static void -gnu_kill_inferior (void) -{ - struct proc *task = current_inferior->task; - if (task) - { - proc_debug (task, "terminating..."); - task_terminate (task->port); - inf_set_pid (current_inferior, -1); - } - target_mourn_inferior (); -} - -/* Clean up after the inferior dies. */ -static void -gnu_mourn_inferior (void) -{ - inf_debug (current_inferior, "rip"); - inf_detach (current_inferior); - unpush_target (&gnu_ops); - generic_mourn_inferior (); -} - - -/* Fork an inferior process, and start debugging it. */ - -/* Set INFERIOR_PID to the first thread available in the child, if any. */ -static int -inf_pick_first_thread (void) -{ - if (current_inferior->task && current_inferior->threads) - /* The first thread. */ - return current_inferior->threads->tid; - else - /* What may be the next thread. */ - return next_thread_id; -} - -static struct inf * -cur_inf (void) -{ - if (!current_inferior) - current_inferior = make_inf (); - return current_inferior; -} - -static void -gnu_create_inferior (char *exec_file, char *allargs, char **env) -{ - struct inf *inf = cur_inf (); - - void trace_me () - { - /* We're in the child; make this process stop as soon as it execs. */ - inf_debug (inf, "tracing self"); - if (ptrace (PTRACE_TRACEME) != 0) - error ("ptrace (PTRACE_TRACEME) failed!"); - } - void attach_to_child (int pid) - { - /* Attach to the now stopped child, which is actually a shell... */ - inf_debug (inf, "attaching to child: %d", pid); - - inf_attach (inf, pid); - - attach_flag = 0; - push_target (&gnu_ops); - - inf->pending_execs = 2; - inf->nomsg = 1; - inf->traced = 1; - - /* Now let the child run again, knowing that it will stop immediately - because of the ptrace. */ - inf_resume (inf); - inferior_ptid = pid_to_ptid (inf_pick_first_thread ()); - - startup_inferior (inf->pending_execs); - } - - inf_debug (inf, "creating inferior"); - - fork_inferior (exec_file, allargs, env, trace_me, attach_to_child, - NULL, NULL); - - inf_validate_procinfo (inf); - inf_update_signal_thread (inf); - inf_set_traced (inf, inf->want_signals); - - /* Execing the process will have trashed our exception ports; steal them - back (or make sure they're restored if the user wants that). */ - if (inf->want_exceptions) - inf_steal_exc_ports (inf); - else - inf_restore_exc_ports (inf); - - /* Here we go! */ - proceed ((CORE_ADDR) -1, 0, 0); -} - -/* Mark our target-struct as eligible for stray "run" and "attach" - commands. */ -static int -gnu_can_run (void) -{ - return 1; -} - - -#ifdef ATTACH_DETACH - -/* Attach to process PID, then initialize for debugging it - and wait for the trace-trap that results from attaching. */ -static void -gnu_attach (char *args, int from_tty) -{ - int pid; - char *exec_file; - struct inf *inf = cur_inf (); - - if (!args) - error_no_arg ("process-id to attach"); - - pid = atoi (args); - - if (pid == getpid ()) /* Trying to masturbate? */ - error ("I refuse to debug myself!"); - - if (from_tty) - { - exec_file = (char *) get_exec_file (0); - - if (exec_file) - printf_unfiltered ("Attaching to program `%s', pid %d\n", - exec_file, pid); - else - printf_unfiltered ("Attaching to pid %d\n", pid); - - gdb_flush (gdb_stdout); - } - - inf_debug (inf, "attaching to pid: %d", pid); - - inf_attach (inf, pid); - inf_update_procs (inf); - - inferior_ptid = pid_to_ptid (inf_pick_first_thread ()); - - attach_flag = 1; - push_target (&gnu_ops); - - /* We have to initialize the terminal settings now, since the code - below might try to restore them. */ - target_terminal_init (); - - /* If the process was stopped before we attached, make it continue the next - time the user does a continue. */ - inf_validate_procinfo (inf); - - inf_update_signal_thread (inf); - inf_set_traced (inf, inf->want_signals); - -#if 0 /* Do we need this? */ - renumber_threads (0); /* Give our threads reasonable names. */ -#endif -} - - -/* Take a program previously attached to and detaches it. - The program resumes execution and will no longer stop - on signals, etc. We'd better not have left any breakpoints - in the program or it'll die when it hits one. For this - to work, it may be necessary for the process to have been - previously attached. It *might* work if the program was - started via fork. */ -static void -gnu_detach (char *args, int from_tty) -{ - if (from_tty) - { - char *exec_file = get_exec_file (0); - if (exec_file) - printf_unfiltered ("Detaching from program `%s' pid %d\n", - exec_file, current_inferior->pid); - else - printf_unfiltered ("Detaching from pid %d\n", current_inferior->pid); - gdb_flush (gdb_stdout); - } - - inf_detach (current_inferior); - - inferior_ptid = null_ptid; - - unpush_target (&gnu_ops); /* Pop out of handling an inferior */ -} -#endif /* ATTACH_DETACH */ - - -static void -gnu_terminal_init_inferior (void) -{ - gdb_assert (current_inferior); - terminal_init_inferior_with_pgrp (current_inferior->pid); -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ -static void -gnu_prepare_to_store (void) -{ -#ifdef CHILD_PREPARE_TO_STORE - CHILD_PREPARE_TO_STORE (); -#endif -} - -static void -gnu_open (char *arg, int from_tty) -{ - error ("Use the \"run\" command to start a Unix child process."); -} - -static void -gnu_stop (void) -{ - error ("to_stop target function not implemented"); -} - -static char * -gnu_pid_to_exec_file (int pid) -{ - error ("to_pid_to_exec_file target function not implemented"); - return NULL; -} - - -static int -gnu_thread_alive (ptid_t tid) -{ - inf_update_procs (current_inferior); - return !!inf_tid_to_thread (current_inferior, PIDGET (tid)); -} - - -/* Read inferior task's LEN bytes from ADDR and copy it to MYADDR in - gdb's address space. Return 0 on failure; number of bytes read - otherwise. */ -int -gnu_read_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length) -{ - error_t err; - vm_address_t low_address = (vm_address_t) trunc_page (addr); - vm_size_t aligned_length = - (vm_size_t) round_page (addr + length) - low_address; - pointer_t copied; - int copy_count; - - /* Get memory from inferior with page aligned addresses */ - err = vm_read (task, low_address, aligned_length, &copied, ©_count); - if (err) - return 0; - - err = hurd_safe_copyin (myaddr, (void *) addr - low_address + copied, length); - if (err) - { - warning ("Read from inferior faulted: %s", strerror (err)); - length = 0; - } - - err = vm_deallocate (mach_task_self (), copied, copy_count); - if (err) - warning ("gnu_read_inferior vm_deallocate failed: %s", strerror (err)); - - return length; -} - -#define CHK_GOTO_OUT(str,ret) \ - do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0) - -struct vm_region_list -{ - struct vm_region_list *next; - vm_prot_t protection; - vm_address_t start; - vm_size_t length; -}; - -struct obstack region_obstack; - -/* Write gdb's LEN bytes from MYADDR and copy it to ADDR in inferior - task's address space. */ -int -gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length) -{ - error_t err = 0; - vm_address_t low_address = (vm_address_t) trunc_page (addr); - vm_size_t aligned_length = - (vm_size_t) round_page (addr + length) - low_address; - pointer_t copied; - int copy_count; - int deallocate = 0; - - char *errstr = "Bug in gnu_write_inferior"; - - struct vm_region_list *region_element; - struct vm_region_list *region_head = (struct vm_region_list *) NULL; - - /* Get memory from inferior with page aligned addresses */ - err = vm_read (task, - low_address, - aligned_length, - &copied, - ©_count); - CHK_GOTO_OUT ("gnu_write_inferior vm_read failed", err); - - deallocate++; - - err = hurd_safe_copyout ((void *) addr - low_address + copied, - myaddr, length); - CHK_GOTO_OUT ("Write to inferior faulted", err); - - obstack_init (®ion_obstack); - - /* Do writes atomically. - First check for holes and unwritable memory. */ - { - vm_size_t remaining_length = aligned_length; - vm_address_t region_address = low_address; - - struct vm_region_list *scan; - - while (region_address < low_address + aligned_length) - { - vm_prot_t protection; - vm_prot_t max_protection; - vm_inherit_t inheritance; - boolean_t shared; - mach_port_t object_name; - vm_offset_t offset; - vm_size_t region_length = remaining_length; - vm_address_t old_address = region_address; - - err = vm_region (task, - ®ion_address, - ®ion_length, - &protection, - &max_protection, - &inheritance, - &shared, - &object_name, - &offset); - CHK_GOTO_OUT ("vm_region failed", err); - - /* Check for holes in memory */ - if (old_address != region_address) - { - warning ("No memory at 0x%x. Nothing written", - old_address); - err = KERN_SUCCESS; - length = 0; - goto out; - } - - if (!(max_protection & VM_PROT_WRITE)) - { - warning ("Memory at address 0x%x is unwritable. Nothing written", - old_address); - err = KERN_SUCCESS; - length = 0; - goto out; - } - - /* Chain the regions for later use */ - region_element = - (struct vm_region_list *) - obstack_alloc (®ion_obstack, sizeof (struct vm_region_list)); - - region_element->protection = protection; - region_element->start = region_address; - region_element->length = region_length; - - /* Chain the regions along with protections */ - region_element->next = region_head; - region_head = region_element; - - region_address += region_length; - remaining_length = remaining_length - region_length; - } - - /* If things fail after this, we give up. - Somebody is messing up inferior_task's mappings. */ - - /* Enable writes to the chained vm regions */ - for (scan = region_head; scan; scan = scan->next) - { - if (!(scan->protection & VM_PROT_WRITE)) - { - err = vm_protect (task, - scan->start, - scan->length, - FALSE, - scan->protection | VM_PROT_WRITE); - CHK_GOTO_OUT ("vm_protect: enable write failed", err); - } - } - - err = vm_write (task, - low_address, - copied, - aligned_length); - CHK_GOTO_OUT ("vm_write failed", err); - - /* Set up the original region protections, if they were changed */ - for (scan = region_head; scan; scan = scan->next) - { - if (!(scan->protection & VM_PROT_WRITE)) - { - err = vm_protect (task, - scan->start, - scan->length, - FALSE, - scan->protection); - CHK_GOTO_OUT ("vm_protect: enable write failed", err); - } - } - } - -out: - if (deallocate) - { - obstack_free (®ion_obstack, 0); - - (void) vm_deallocate (mach_task_self (), - copied, - copy_count); - } - - if (err != KERN_SUCCESS) - { - warning ("%s: %s", errstr, mach_error_string (err)); - return 0; - } - - return length; -} - - -/* Return 0 on failure, number of bytes handled otherwise. TARGET - is ignored. */ -static int -gnu_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, - struct target_ops *target) -{ - task_t task = (current_inferior - ? (current_inferior->task - ? current_inferior->task->port : 0) - : 0); - - if (task == MACH_PORT_NULL) - return 0; - else - { - inf_debug (current_inferior, "%s %p[%d] %s %p", - write ? "writing" : "reading", memaddr, len, - write ? "<--" : "-->", myaddr); - if (write) - return gnu_write_inferior (task, memaddr, myaddr, len); - else - return gnu_read_inferior (task, memaddr, myaddr, len); - } -} - - -/* Return printable description of proc. */ -char * -proc_string (struct proc *proc) -{ - static char tid_str[80]; - if (proc_is_task (proc)) - sprintf (tid_str, "process %d", proc->inf->pid); - else - sprintf (tid_str, "thread %d.%d", - proc->inf->pid, pid_to_thread_id (MERGEPID (proc->tid, 0))); - return tid_str; -} - -static char * -gnu_pid_to_str (ptid_t ptid) -{ - struct inf *inf = current_inferior; - int tid = PIDGET (ptid); - struct proc *thread = inf_tid_to_thread (inf, tid); - - if (thread) - return proc_string (thread); - else - { - static char tid_str[80]; - sprintf (tid_str, "bogus thread id %d", tid); - return tid_str; - } -} - - -extern void gnu_store_registers (int regno); -extern void gnu_fetch_registers (int regno); - -struct target_ops gnu_ops; - -static void -init_gnu_ops (void) -{ - gnu_ops.to_shortname = "GNU"; /* to_shortname */ - gnu_ops.to_longname = "GNU Hurd process"; /* to_longname */ - gnu_ops.to_doc = "GNU Hurd process"; /* to_doc */ - gnu_ops.to_open = gnu_open; /* to_open */ - gnu_ops.to_close = 0; /* to_close */ - gnu_ops.to_attach = gnu_attach; /* to_attach */ - gnu_ops.to_post_attach = NULL; - gnu_ops.to_require_attach = NULL; /* to_require_attach */ - gnu_ops.to_detach = gnu_detach; /* to_detach */ - gnu_ops.to_require_detach = NULL; /* to_require_detach */ - gnu_ops.to_resume = gnu_resume; /* to_resume */ - gnu_ops.to_wait = gnu_wait; /* to_wait */ - gnu_ops.to_post_wait = NULL; /* to_post_wait */ - gnu_ops.to_fetch_registers = gnu_fetch_registers; /* to_fetch_registers */ - gnu_ops.to_store_registers = gnu_store_registers; /* to_store_registers */ - gnu_ops.to_prepare_to_store = gnu_prepare_to_store; /* to_prepare_to_store */ - gnu_ops.to_xfer_memory = gnu_xfer_memory; /* to_xfer_memory */ - gnu_ops.to_files_info = 0; /* to_files_info */ - gnu_ops.to_insert_breakpoint = memory_insert_breakpoint; - gnu_ops.to_remove_breakpoint = memory_remove_breakpoint; - gnu_ops.to_terminal_init = gnu_terminal_init_inferior; - gnu_ops.to_terminal_inferior = terminal_inferior; - gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output; - gnu_ops.to_terminal_ours = terminal_ours; - gnu_ops.to_terminal_info = child_terminal_info; - gnu_ops.to_kill = gnu_kill_inferior; /* to_kill */ - gnu_ops.to_load = 0; /* to_load */ - gnu_ops.to_lookup_symbol = 0; /* to_lookup_symbol */ - gnu_ops.to_create_inferior = gnu_create_inferior; /* to_create_inferior */ - gnu_ops.to_post_startup_inferior = NULL; /* to_post_startup_inferior */ - /* to_acknowledge_created_inferior */ - gnu_ops.to_acknowledge_created_inferior = NULL; - /* to_clone_and_follow_inferior */ - gnu_ops.to_clone_and_follow_inferior = NULL; - /* to_post_follow_inferior_by_clone */ - gnu_ops.to_post_follow_inferior_by_clone = NULL; - gnu_ops.to_insert_fork_catchpoint = NULL; - gnu_ops.to_remove_fork_catchpoint = NULL; - gnu_ops.to_insert_vfork_catchpoint = NULL; - gnu_ops.to_remove_vfork_catchpoint = NULL; - gnu_ops.to_has_forked = NULL; /* to_has_forked */ - gnu_ops.to_has_vforked = NULL; /* to_has_vforked */ - gnu_ops.to_can_follow_vfork_prior_to_exec = NULL; - gnu_ops.to_post_follow_vfork = NULL; /* to_post_follow_vfork */ - gnu_ops.to_insert_exec_catchpoint = NULL; - gnu_ops.to_remove_exec_catchpoint = NULL; - gnu_ops.to_has_execd = NULL; - gnu_ops.to_reported_exec_events_per_exec_call = NULL; - gnu_ops.to_has_exited = NULL; - gnu_ops.to_mourn_inferior = gnu_mourn_inferior; /* to_mourn_inferior */ - gnu_ops.to_can_run = gnu_can_run; /* to_can_run */ - gnu_ops.to_notice_signals = 0; /* to_notice_signals */ - gnu_ops.to_thread_alive = gnu_thread_alive; /* to_thread_alive */ - gnu_ops.to_pid_to_str = gnu_pid_to_str; /* to_pid_to_str */ - gnu_ops.to_stop = gnu_stop; /* to_stop */ - gnu_ops.to_pid_to_exec_file = gnu_pid_to_exec_file; /* to_pid_to_exec_file */ - gnu_ops.to_stratum = process_stratum; /* to_stratum */ - gnu_ops.DONT_USE = 0; /* to_next */ - gnu_ops.to_has_all_memory = 1; /* to_has_all_memory */ - gnu_ops.to_has_memory = 1; /* to_has_memory */ - gnu_ops.to_has_stack = 1; /* to_has_stack */ - gnu_ops.to_has_registers = 1; /* to_has_registers */ - gnu_ops.to_has_execution = 1; /* to_has_execution */ - gnu_ops.to_sections = 0; /* sections */ - gnu_ops.to_sections_end = 0; /* sections_end */ - gnu_ops.to_magic = OPS_MAGIC; /* to_magic */ -} /* init_gnu_ops */ - - -/* User task commands. */ - -struct cmd_list_element *set_task_cmd_list = 0; -struct cmd_list_element *show_task_cmd_list = 0; -/* User thread commands. */ - -/* Commands with a prefix of `set/show thread'. */ -extern struct cmd_list_element *thread_cmd_list; -struct cmd_list_element *set_thread_cmd_list = NULL; -struct cmd_list_element *show_thread_cmd_list = NULL; - -/* Commands with a prefix of `set/show thread default'. */ -struct cmd_list_element *set_thread_default_cmd_list = NULL; -struct cmd_list_element *show_thread_default_cmd_list = NULL; - -static void -set_thread_cmd (char *args, int from_tty) -{ - printf_unfiltered ("\"set thread\" must be followed by the name of a thread property, or \"default\".\n"); -} - -static void -show_thread_cmd (char *args, int from_tty) -{ - printf_unfiltered ("\"show thread\" must be followed by the name of a thread property, or \"default\".\n"); -} - -static void -set_thread_default_cmd (char *args, int from_tty) -{ - printf_unfiltered ("\"set thread default\" must be followed by the name of a thread property.\n"); -} - -static void -show_thread_default_cmd (char *args, int from_tty) -{ - printf_unfiltered ("\"show thread default\" must be followed by the name of a thread property.\n"); -} - -static int -parse_int_arg (char *args, char *cmd_prefix) -{ - if (args) - { - char *arg_end; - int val = strtoul (args, &arg_end, 10); - if (*args && *arg_end == '\0') - return val; - } - error ("Illegal argument for \"%s\" command, should be an integer.", cmd_prefix); -} - -static int -_parse_bool_arg (char *args, char *t_val, char *f_val, char *cmd_prefix) -{ - if (!args || strcmp (args, t_val) == 0) - return 1; - else if (strcmp (args, f_val) == 0) - return 0; - else - error ("Illegal argument for \"%s\" command, should be \"%s\" or \"%s\".", - cmd_prefix, t_val, f_val); -} - -#define parse_bool_arg(args, cmd_prefix) \ - _parse_bool_arg (args, "on", "off", cmd_prefix) - -static void -check_empty (char *args, char *cmd_prefix) -{ - if (args) - error ("Garbage after \"%s\" command: `%s'", cmd_prefix, args); -} - -/* Returns the alive thread named by INFERIOR_PID, or signals an error. */ -static struct proc * -cur_thread (void) -{ - struct inf *inf = cur_inf (); - struct proc *thread = inf_tid_to_thread (inf, PIDGET (inferior_ptid)); - if (!thread) - error ("No current thread."); - return thread; -} - -/* Returns the current inferior, but signals an error if it has no task. */ -static struct inf * -active_inf (void) -{ - struct inf *inf = cur_inf (); - if (!inf->task) - error ("No current process."); - return inf; -} - - -static void -set_task_pause_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - int old_sc = inf->pause_sc; - - inf->pause_sc = parse_bool_arg (args, "set task pause"); - - if (old_sc == 0 && inf->pause_sc != 0) - /* If the task is currently unsuspended, immediately suspend it, - otherwise wait until the next time it gets control. */ - inf_suspend (inf); -} - -static void -show_task_pause_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - check_empty (args, "show task pause"); - printf_unfiltered ("The inferior task %s suspended while gdb has control.\n", - inf->task - ? (inf->pause_sc == 0 ? "isn't" : "is") - : (inf->pause_sc == 0 ? "won't be" : "will be")); -} - -static void -set_task_detach_sc_cmd (char *args, int from_tty) -{ - cur_inf ()->detach_sc = parse_int_arg (args, "set task detach-suspend-count"); -} - -static void -show_task_detach_sc_cmd (char *args, int from_tty) -{ - check_empty (args, "show task detach-suspend-count"); - printf_unfiltered ("The inferior task will be left with a suspend count of %d when detaching.\n", - cur_inf ()->detach_sc); -} - - -static void -set_thread_default_pause_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - inf->default_thread_pause_sc = - parse_bool_arg (args, "set thread default pause") ? 0 : 1; -} - -static void -show_thread_default_pause_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - int sc = inf->default_thread_pause_sc; - check_empty (args, "show thread default pause"); - printf_unfiltered ("New threads %s suspended while gdb has control%s.\n", - sc ? "are" : "aren't", - !sc && inf->pause_sc ? " (but the task is)" : ""); -} - -static void -set_thread_default_run_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - inf->default_thread_run_sc = - parse_bool_arg (args, "set thread default run") ? 0 : 1; -} - -static void -show_thread_default_run_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - check_empty (args, "show thread default run"); - printf_unfiltered ("New threads %s allowed to run.\n", - inf->default_thread_run_sc == 0 ? "are" : "aren't"); -} - -static void -set_thread_default_detach_sc_cmd (char *args, int from_tty) -{ - cur_inf ()->default_thread_detach_sc = - parse_int_arg (args, "set thread default detach-suspend-count"); -} - -static void -show_thread_default_detach_sc_cmd (char *args, int from_tty) -{ - check_empty (args, "show thread default detach-suspend-count"); - printf_unfiltered ("New threads will get a detach-suspend-count of %d.\n", - cur_inf ()->default_thread_detach_sc); -} - - -/* Steal a send right called NAME in the inferior task, and make it PROC's - saved exception port. */ -static void -steal_exc_port (struct proc *proc, mach_port_t name) -{ - error_t err; - mach_port_t port; - mach_msg_type_name_t port_type; - - if (!proc || !proc->inf->task) - error ("No inferior task."); - - err = mach_port_extract_right (proc->inf->task->port, - name, MACH_MSG_TYPE_COPY_SEND, - &port, &port_type); - if (err) - error ("Couldn't extract send right %d from inferior: %s", - name, strerror (err)); - - if (proc->saved_exc_port) - /* Get rid of our reference to the old one. */ - mach_port_deallocate (mach_task_self (), proc->saved_exc_port); - - proc->saved_exc_port = port; - - if (!proc->exc_port) - /* If PROC is a thread, we may not have set its exception port before. - We can't use proc_steal_exc_port because it also sets saved_exc_port. */ - { - proc->exc_port = proc->inf->event_port; - err = proc_set_exception_port (proc, proc->exc_port); - error ("Can't set exception port for %s: %s", - proc_string (proc), strerror (err)); - } -} - -static void -set_task_exc_port_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - if (!args) - error ("No argument to \"set task exception-port\" command."); - steal_exc_port (inf->task, parse_and_eval_address (args)); -} - -static void -set_stopped_cmd (char *args, int from_tty) -{ - cur_inf ()->stopped = _parse_bool_arg (args, "yes", "no", "set stopped"); -} - -static void -show_stopped_cmd (char *args, int from_tty) -{ - struct inf *inf = active_inf (); - check_empty (args, "show stopped"); - printf_unfiltered ("The inferior process %s stopped.\n", - inf->stopped ? "is" : "isn't"); -} - -static void -set_sig_thread_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - - if (!args || (!isdigit (*args) && strcmp (args, "none") != 0)) - error ("Illegal argument to \"set signal-thread\" command.\n" - "Should be an integer thread ID, or `none'."); - - if (strcmp (args, "none") == 0) - inf->signal_thread = 0; - else - { - int tid = PIDGET (thread_id_to_pid (atoi (args))); - if (tid < 0) - error ("Thread ID %s not known. Use the \"info threads\" command to\n" - "see the IDs of currently known threads.", args); - inf->signal_thread = inf_tid_to_thread (inf, tid); - } -} - -static void -show_sig_thread_cmd (char *args, int from_tty) -{ - struct inf *inf = active_inf (); - check_empty (args, "show signal-thread"); - if (inf->signal_thread) - printf_unfiltered ("The signal thread is %s.\n", - proc_string (inf->signal_thread)); - else - printf_unfiltered ("There is no signal thread.\n"); -} - - -static void -set_signals_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - - inf->want_signals = parse_bool_arg (args, "set signals"); - - if (inf->task && inf->want_signals != inf->traced) - /* Make this take effect immediately in a running process. */ - inf_set_traced (inf, inf->want_signals); -} - -static void -show_signals_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - check_empty (args, "show signals"); - printf_unfiltered ("The inferior process's signals %s intercepted.\n", - inf->task - ? (inf->traced ? "are" : "aren't") - : (inf->want_signals ? "will be" : "won't be")); -} - -static void -set_exceptions_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - int val = parse_bool_arg (args, "set exceptions"); - - if (inf->task && inf->want_exceptions != val) - /* Make this take effect immediately in a running process. */ - /* XXX */ ; - - inf->want_exceptions = val; -} - -static void -show_exceptions_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - check_empty (args, "show exceptions"); - printf_unfiltered ("Exceptions in the inferior %s trapped.\n", - inf->task - ? (inf->want_exceptions ? "are" : "aren't") - : (inf->want_exceptions ? "will be" : "won't be")); -} - - -static void -set_task_cmd (char *args, int from_tty) -{ - printf_unfiltered ("\"set task\" must be followed by the name" - " of a task property.\n"); -} - -static void -show_task_cmd (char *args, int from_tty) -{ - struct inf *inf = cur_inf (); - - check_empty (args, "show task"); - - show_signals_cmd (0, from_tty); - show_exceptions_cmd (0, from_tty); - show_task_pause_cmd (0, from_tty); - - if (inf->pause_sc == 0) - show_thread_default_pause_cmd (0, from_tty); - show_thread_default_run_cmd (0, from_tty); - - if (inf->task) - { - show_stopped_cmd (0, from_tty); - show_sig_thread_cmd (0, from_tty); - } - - if (inf->detach_sc != 0) - show_task_detach_sc_cmd (0, from_tty); - if (inf->default_thread_detach_sc != 0) - show_thread_default_detach_sc_cmd (0, from_tty); -} - - -static void -set_noninvasive_cmd (char *args, int from_tty) -{ - /* Invert the sense of the arg for each component. */ - char *inv_args = parse_bool_arg (args, "set noninvasive") ? "off" : "on"; - - set_task_pause_cmd (inv_args, from_tty); - set_signals_cmd (inv_args, from_tty); - set_exceptions_cmd (inv_args, from_tty); -} - - -static void -info_port_rights (char *args, mach_port_type_t only) -{ - struct inf *inf = active_inf (); - struct value *vmark = value_mark (); - - if (args) - /* Explicit list of port rights. */ - { - while (*args) - { - struct value *val = parse_to_comma_and_eval (&args); - long right = value_as_long (val); - error_t err = - print_port_info (right, 0, inf->task->port, PORTINFO_DETAILS, - stdout); - if (err) - error ("%ld: %s.", right, strerror (err)); - } - } - else - /* Print all of them. */ - { - error_t err = - print_task_ports_info (inf->task->port, only, PORTINFO_DETAILS, - stdout); - if (err) - error ("%s.", strerror (err)); - } - - value_free_to_mark (vmark); -} - -static void -info_send_rights_cmd (char *args, int from_tty) -{ - info_port_rights (args, MACH_PORT_TYPE_SEND); -} - -static void -info_recv_rights_cmd (char *args, int from_tty) -{ - info_port_rights (args, MACH_PORT_TYPE_RECEIVE); -} - -static void -info_port_sets_cmd (char *args, int from_tty) -{ - info_port_rights (args, MACH_PORT_TYPE_PORT_SET); -} - -static void -info_dead_names_cmd (char *args, int from_tty) -{ - info_port_rights (args, MACH_PORT_TYPE_DEAD_NAME); -} - -static void -info_port_rights_cmd (char *args, int from_tty) -{ - info_port_rights (args, ~0); -} - - -static void -add_task_commands (void) -{ - add_cmd ("pause", class_run, set_thread_default_pause_cmd, - "Set whether the new threads are suspended while gdb has control.\n\ -This property normally has no effect because the whole task is\n\ -suspended, however, that may be disabled with \"set task pause off\".\n\ -The default value is \"off\".", - &set_thread_default_cmd_list); - add_cmd ("pause", no_class, show_thread_default_pause_cmd, - "Show whether new threads are suspended while gdb has control.", - &show_thread_default_cmd_list); - - add_cmd ("run", class_run, set_thread_default_run_cmd, - "Set whether new threads are allowed to run \ -(once gdb has noticed them).", - &set_thread_default_cmd_list); - add_cmd ("run", no_class, show_thread_default_run_cmd, - "Show whether new threads are allowed to run \ -(once gdb has noticed them).", - &show_thread_default_cmd_list); - - add_cmd ("detach-suspend-count", class_run, set_thread_default_detach_sc_cmd, - "Set the default detach-suspend-count value for new threads.", - &set_thread_default_cmd_list); - add_cmd ("detach-suspend-count", no_class, show_thread_default_detach_sc_cmd, - "Show the default detach-suspend-count value for new threads.", - &show_thread_default_cmd_list); - - add_cmd ("signals", class_run, set_signals_cmd, - "Set whether the inferior process's signals will be intercepted.\n\ -Mach exceptions (such as breakpoint traps) are not affected.", - &setlist); - add_alias_cmd ("sigs", "signals", class_run, 1, &setlist); - add_cmd ("signals", no_class, show_signals_cmd, - "Show whether the inferior process's signals will be intercepted.", - &showlist); - add_alias_cmd ("sigs", "signals", no_class, 1, &showlist); - - add_cmd ("signal-thread", class_run, set_sig_thread_cmd, - "Set the thread that gdb thinks is the libc signal thread.\n\ -This thread is run when delivering a signal to a non-stopped process.", - &setlist); - add_alias_cmd ("sigthread", "signal-thread", class_run, 1, &setlist); - add_cmd ("signal-thread", no_class, show_sig_thread_cmd, - "Set the thread that gdb thinks is the libc signal thread.", - &showlist); - add_alias_cmd ("sigthread", "signal-thread", no_class, 1, &showlist); - - add_cmd ("stopped", class_run, set_stopped_cmd, - "Set whether gdb thinks the inferior process is stopped \ -as with SIGSTOP.\n\ -Stopped process will be continued by sending them a signal.", - &setlist); - add_cmd ("stopped", no_class, show_signals_cmd, - "Show whether gdb thinks the inferior process is stopped \ -as with SIGSTOP.", - &showlist); - - add_cmd ("exceptions", class_run, set_exceptions_cmd, - "Set whether exceptions in the inferior process will be trapped.\n\ -When exceptions are turned off, neither breakpoints nor single-stepping\n\ -will work.", - &setlist); - /* Allow `set exc' despite conflict with `set exception-port'. */ - add_alias_cmd ("exc", "exceptions", class_run, 1, &setlist); - add_cmd ("exceptions", no_class, show_exceptions_cmd, - "Show whether exceptions in the inferior process will be trapped.", - &showlist); - - add_prefix_cmd ("task", no_class, set_task_cmd, - "Command prefix for setting task attributes.", - &set_task_cmd_list, "set task ", 0, &setlist); - add_prefix_cmd ("task", no_class, show_task_cmd, - "Command prefix for showing task attributes.", - &show_task_cmd_list, "show task ", 0, &showlist); - - add_cmd ("pause", class_run, set_task_pause_cmd, - "Set whether the task is suspended while gdb has control.\n\ -A value of \"on\" takes effect immediately, otherwise nothing happens\n\ -until the next time the program is continued.\n\ -When setting this to \"off\", \"set thread default pause on\" can be\n\ -used to pause individual threads by default instead.", - &set_task_cmd_list); - add_cmd ("pause", no_class, show_task_pause_cmd, - "Show whether the task is suspended while gdb has control.", - &show_task_cmd_list); - - add_cmd ("detach-suspend-count", class_run, set_task_detach_sc_cmd, - "Set the suspend count will leave on the thread when detaching.", - &set_task_cmd_list); - add_cmd ("detach-suspend-count", no_class, show_task_detach_sc_cmd, - "Show the suspend count will leave on the thread when detaching.", - &show_task_cmd_list); - - add_cmd ("exception-port", no_class, set_task_exc_port_cmd, - "Set the task exception port to which we forward exceptions.\n\ -The argument should be the value of the send right in the task.", - &set_task_cmd_list); - add_alias_cmd ("excp", "exception-port", no_class, 1, &set_task_cmd_list); - add_alias_cmd ("exc-port", "exception-port", no_class, 1, - &set_task_cmd_list); - - /* A convenient way of turning on all options require to noninvasively - debug running tasks. */ - add_cmd ("noninvasive", no_class, set_noninvasive_cmd, - "Set task options so that we interfere as little as possible.\n\ -This is the same as setting `task pause', `exceptions', and\n\ -`signals' to the opposite value.", - &setlist); - - /* Commands to show information about the task's ports. */ - add_cmd ("send-rights", class_info, info_send_rights_cmd, - "Show information about the task's send rights", - &infolist); - add_cmd ("receive-rights", class_info, info_recv_rights_cmd, - "Show information about the task's receive rights", - &infolist); - add_cmd ("port-rights", class_info, info_port_rights_cmd, - "Show information about the task's port rights", - &infolist); - add_cmd ("port-sets", class_info, info_port_sets_cmd, - "Show information about the task's port sets", - &infolist); - add_cmd ("dead-names", class_info, info_dead_names_cmd, - "Show information about the task's dead names", - &infolist); - add_info_alias ("ports", "port-rights", 1); - add_info_alias ("port", "port-rights", 1); - add_info_alias ("psets", "port-sets", 1); -} - - -static void -set_thread_pause_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - int old_sc = thread->pause_sc; - thread->pause_sc = parse_bool_arg (args, "set thread pause"); - if (old_sc == 0 && thread->pause_sc != 0 && thread->inf->pause_sc == 0) - /* If the task is currently unsuspended, immediately suspend it, - otherwise wait until the next time it gets control. */ - inf_suspend (thread->inf); -} - -static void -show_thread_pause_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - int sc = thread->pause_sc; - check_empty (args, "show task pause"); - printf_unfiltered ("Thread %s %s suspended while gdb has control%s.\n", - proc_string (thread), - sc ? "is" : "isn't", - !sc && thread->inf->pause_sc ? " (but the task is)" : ""); -} - -static void -set_thread_run_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - thread->run_sc = parse_bool_arg (args, "set thread run") ? 0 : 1; -} - -static void -show_thread_run_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - check_empty (args, "show thread run"); - printf_unfiltered ("Thread %s %s allowed to run.", - proc_string (thread), - thread->run_sc == 0 ? "is" : "isn't"); -} - -static void -set_thread_detach_sc_cmd (char *args, int from_tty) -{ - cur_thread ()->detach_sc = parse_int_arg (args, - "set thread detach-suspend-count"); -} - -static void -show_thread_detach_sc_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - check_empty (args, "show thread detach-suspend-count"); - printf_unfiltered ("Thread %s will be left with a suspend count" - " of %d when detaching.\n", - proc_string (thread), - thread->detach_sc); -} - -static void -set_thread_exc_port_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - if (!args) - error ("No argument to \"set thread exception-port\" command."); - steal_exc_port (thread, parse_and_eval_address (args)); -} - -#if 0 -static void -show_thread_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - check_empty (args, "show thread"); - show_thread_run_cmd (0, from_tty); - show_thread_pause_cmd (0, from_tty); - if (thread->detach_sc != 0) - show_thread_detach_sc_cmd (0, from_tty); -} -#endif - -static void -thread_takeover_sc_cmd (char *args, int from_tty) -{ - struct proc *thread = cur_thread (); - thread_basic_info_data_t _info; - thread_basic_info_t info = &_info; - mach_msg_type_number_t info_len = THREAD_BASIC_INFO_COUNT; - error_t err = - thread_info (thread->port, THREAD_BASIC_INFO, (int *) &info, &info_len); - if (err) - error ("%s.", strerror (err)); - thread->sc = info->suspend_count; - if (from_tty) - printf_unfiltered ("Suspend count was %d.\n", thread->sc); - if (info != &_info) - vm_deallocate (mach_task_self (), (vm_address_t) info, - info_len * sizeof (int)); -} - - -static void -add_thread_commands (void) -{ - add_prefix_cmd ("thread", no_class, set_thread_cmd, - "Command prefix for setting thread properties.", - &set_thread_cmd_list, "set thread ", 0, &setlist); - add_prefix_cmd ("default", no_class, show_thread_cmd, - "Command prefix for setting default thread properties.", - &set_thread_default_cmd_list, "set thread default ", 0, - &set_thread_cmd_list); - add_prefix_cmd ("thread", no_class, set_thread_default_cmd, - "Command prefix for showing thread properties.", - &show_thread_cmd_list, "show thread ", 0, &showlist); - add_prefix_cmd ("default", no_class, show_thread_default_cmd, - "Command prefix for showing default thread properties.", - &show_thread_default_cmd_list, "show thread default ", 0, - &show_thread_cmd_list); - - add_cmd ("pause", class_run, set_thread_pause_cmd, - "Set whether the current thread is suspended \ -while gdb has control.\n\ -A value of \"on\" takes effect immediately, otherwise nothing happens\n\ -until the next time the program is continued. This property normally\n\ -has no effect because the whole task is suspended, however, that may\n\ -be disabled with \"set task pause off\".\n\ -The default value is \"off\".", - &set_thread_cmd_list); - add_cmd ("pause", no_class, show_thread_pause_cmd, - "Show whether the current thread is suspended \ -while gdb has control.", - &show_thread_cmd_list); - - add_cmd ("run", class_run, set_thread_run_cmd, - "Set whether the current thread is allowed to run.", - &set_thread_cmd_list); - add_cmd ("run", no_class, show_thread_run_cmd, - "Show whether the current thread is allowed to run.", - &show_thread_cmd_list); - - add_cmd ("detach-suspend-count", class_run, set_thread_detach_sc_cmd, - "Set the suspend count will leave on the thread when detaching.\n\ -Note that this is relative to suspend count when gdb noticed the thread;\n\ -use the `thread takeover-suspend-count' to force it to an absolute value.", - &set_thread_cmd_list); - add_cmd ("detach-suspend-count", no_class, show_thread_detach_sc_cmd, - "Show the suspend count will leave on the thread when detaching.\n\ -Note that this is relative to suspend count when gdb noticed the thread;\n\ -use the `thread takeover-suspend-count' to force it to an absolute value.", - &show_thread_cmd_list); - - add_cmd ("exception-port", no_class, set_thread_exc_port_cmd, - "Set the thread exception port to which we forward exceptions.\n\ -This overrides the task exception port.\n\ -The argument should be the value of the send right in the task.", - &set_thread_cmd_list); - add_alias_cmd ("excp", "exception-port", no_class, 1, &set_thread_cmd_list); - add_alias_cmd ("exc-port", "exception-port", no_class, 1, - &set_thread_cmd_list); - - add_cmd ("takeover-suspend-count", no_class, thread_takeover_sc_cmd, - "Force the threads absolute suspend-count to be gdb's.\n\ -Prior to giving this command, gdb's thread suspend-counts are relative\n\ -to the thread's initial suspend-count when gdb notices the threads.", - &thread_cmd_list); -} - - -void -_initialize_gnu_nat (void) -{ - proc_server = getproc (); - - init_gnu_ops (); - add_target (&gnu_ops); - - add_task_commands (); - add_thread_commands (); - add_set_cmd ("gnu-debug", class_maintenance, - var_boolean, (char *) &gnu_debug_flag, - "Set debugging output for the gnu backend.", &maintenancelist); -} - -#ifdef FLUSH_INFERIOR_CACHE - -/* When over-writing code on some machines the I-Cache must be flushed - explicitly, because it is not kept coherent by the lazy hardware. - This definitely includes breakpoints, for instance, or else we - end up looping in mysterious Bpt traps */ - -void -flush_inferior_icache (CORE_ADDR pc, int amount) -{ - vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH; - error_t ret; - - ret = vm_machine_attribute (current_inferior->task->port, - pc, - amount, - MATTR_CACHE, - &flush); - if (ret != KERN_SUCCESS) - warning ("Error flushing inferior's cache : %s", strerror (ret)); -} -#endif /* FLUSH_INFERIOR_CACHE */ diff --git a/contrib/gdb/gdb/gnu-nat.h b/contrib/gdb/gdb/gnu-nat.h deleted file mode 100644 index cc430835f2c..00000000000 --- a/contrib/gdb/gdb/gnu-nat.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Common things used by the various *gnu-nat.c files - Copyright 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. - - Written by Miles Bader - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef __GNU_NAT_H__ -#define __GNU_NAT_H__ - -#include -#include - -struct inf; - -extern struct inf *current_inferior; - -/* Converts a GDB pid to a struct proc. */ -struct proc *inf_tid_to_thread (struct inf *inf, int tid); - -/* Makes sure that INF's thread list is synced with the actual process. */ -int inf_update_procs (struct inf *inf); - -/* A proc is either a thread, or the task (there can only be one task proc - because it always has the same TID, PROC_TID_TASK). */ -struct proc - { - thread_t port; /* The task or thread port. */ - int tid; /* The GDB pid (actually a thread id). */ - int num; /* An id number for threads, to print. */ - - mach_port_t saved_exc_port; /* The task/thread's real exception port. */ - mach_port_t exc_port; /* Our replacement, which for. */ - - int sc; /* Desired suspend count. */ - int cur_sc; /* Implemented suspend count. */ - int run_sc; /* Default sc when the program is running. */ - int pause_sc; /* Default sc when gdb has control. */ - int resume_sc; /* Sc resulting from the last resume. */ - int detach_sc; /* SC to leave around when detaching - from program. */ - - thread_state_data_t state; /* Registers, &c. */ - int state_valid:1; /* True if STATE is up to date. */ - int state_changed:1; - - int aborted:1; /* True if thread_abort has been called. */ - int dead:1; /* We happen to know it's actually dead. */ - - /* Bit mask of registers fetched by gdb. This is used when we re-fetch - STATE after aborting the thread, to detect that gdb may have out-of-date - information. */ - unsigned long fetched_regs; - - struct inf *inf; /* Where we come from. */ - - struct proc *next; - }; - -/* The task has a thread entry with this TID. */ -#define PROC_TID_TASK (-1) - -#define proc_is_task(proc) ((proc)->tid == PROC_TID_TASK) -#define proc_is_thread(proc) ((proc)->tid != PROC_TID_TASK) - -extern int __proc_pid (struct proc *proc); - -/* Make sure that the state field in PROC is up to date, and return a - pointer to it, or 0 if something is wrong. If WILL_MODIFY is true, - makes sure that the thread is stopped and aborted first, and sets - the state_changed field in PROC to true. */ -extern thread_state_t proc_get_state (struct proc *proc, int will_modify); - -/* Return printable description of proc. */ -extern char *proc_string (struct proc *proc); - -#define proc_debug(_proc, msg, args...) \ - do { struct proc *__proc = (_proc); \ - debug ("{proc %d/%d %p}: " msg, \ - __proc_pid (__proc), __proc->tid, __proc , ##args); } while (0) - -extern int gnu_debug_flag; - -#define debug(msg, args...) \ - do { if (gnu_debug_flag) \ - fprintf_unfiltered (gdb_stdlog, "%s: " msg "\r\n", __FUNCTION__ , ##args); } while (0) - -#endif /* __GNU_NAT_H__ */ diff --git a/contrib/gdb/gdb/gnu-regex.c b/contrib/gdb/gdb/gnu-regex.c deleted file mode 100644 index 84db70f7952..00000000000 --- a/contrib/gdb/gdb/gnu-regex.c +++ /dev/null @@ -1,5797 +0,0 @@ -/* Extended regular expression matching and search library, - version 0.12. - (Implements POSIX draft P1003.2/D11.2, except for some of the - internationalization features.) - Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc. - - NOTE: The canonical source of this file is maintained with the - GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* AIX requires this to be the first thing in the file. */ -#if defined _AIX && !defined REGEX_MALLOC - #pragma alloca -#endif - -#undef _GNU_SOURCE -#define _GNU_SOURCE - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef PARAMS -# if defined __GNUC__ || (defined __STDC__ && __STDC__) -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif /* GCC. */ -#endif /* Not PARAMS. */ - -#if defined STDC_HEADERS && !defined emacs -# include -#else -/* We need this for `gnu-regex.h', and perhaps for the Emacs include files. */ -# include -#endif - -/* For platform which support the ISO C amendement 1 functionality we - support user defined character classes. */ -#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) - /* Solaris 2.5 has a bug: must be included before . */ -# include -# include -#endif - -/* This is for other GNU distributions with internationalized messages. */ -/* CYGNUS LOCAL: ../intl will handle this for us */ -#ifdef ENABLE_NLS -# include -#else -# define gettext(msgid) (msgid) -#endif - -#ifndef gettext_noop -/* This define is so xgettext can find the internationalizable - strings. */ -# define gettext_noop(String) String -#endif - -/* The `emacs' switch turns on certain matching commands - that make sense only in Emacs. */ -#ifdef emacs - -# include "lisp.h" -# include "buffer.h" -# include "syntax.h" - -#else /* not emacs */ - -/* If we are not linking with Emacs proper, - we can't use the relocating allocator - even if config.h says that we can. */ -# undef REL_ALLOC - -# if defined STDC_HEADERS || defined _LIBC -# include -# else -char *malloc (); -char *realloc (); -# endif - -/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow. - If nothing else has been done, use the method below. */ -# ifdef INHIBIT_STRING_HEADER -# if !(defined HAVE_BZERO && defined HAVE_BCOPY) -# if !defined bzero && !defined bcopy -# undef INHIBIT_STRING_HEADER -# endif -# endif -# endif - -/* This is the normal way of making sure we have a bcopy and a bzero. - This is used in most programs--a few other programs avoid this - by defining INHIBIT_STRING_HEADER. */ -# ifndef INHIBIT_STRING_HEADER -# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC -# include -# ifndef bzero -# ifndef _LIBC -# define bzero(s, n) (memset (s, '\0', n), (s)) -# else -# define bzero(s, n) __bzero (s, n) -# endif -# endif -# else -# include -# ifndef memcmp -# define memcmp(s1, s2, n) bcmp (s1, s2, n) -# endif -# ifndef memcpy -# define memcpy(d, s, n) (bcopy (s, d, n), (d)) -# endif -# endif -# endif - -/* Define the syntax stuff for \<, \>, etc. */ - -/* This must be nonzero for the wordchar and notwordchar pattern - commands in re_match_2. */ -# ifndef Sword -# define Sword 1 -# endif - -# ifdef SWITCH_ENUM_BUG -# define SWITCH_ENUM_CAST(x) ((int)(x)) -# else -# define SWITCH_ENUM_CAST(x) (x) -# endif - -/* How many characters in the character set. */ -# define CHAR_SET_SIZE 256 - -/* GDB LOCAL: define _REGEX_RE_COMP to get BSD style re_comp and re_exec */ -#ifndef _REGEX_RE_COMP -#define _REGEX_RE_COMP -#endif - -# ifdef SYNTAX_TABLE - -extern char *re_syntax_table; - -# else /* not SYNTAX_TABLE */ - -static char re_syntax_table[CHAR_SET_SIZE]; - -static void -init_syntax_once () -{ - register int c; - static int done = 0; - - if (done) - return; - - bzero (re_syntax_table, sizeof re_syntax_table); - - for (c = 'a'; c <= 'z'; c++) - re_syntax_table[c] = Sword; - - for (c = 'A'; c <= 'Z'; c++) - re_syntax_table[c] = Sword; - - for (c = '0'; c <= '9'; c++) - re_syntax_table[c] = Sword; - - re_syntax_table['_'] = Sword; - - done = 1; -} - -# endif /* not SYNTAX_TABLE */ - -# define SYNTAX(c) re_syntax_table[c] - -#endif /* not emacs */ - -/* Get the interface, including the syntax bits. */ -/* CYGNUS LOCAL: call it gnu-regex.h, not regex.h, to avoid name conflicts */ -#include "gnu-regex.h" - -/* isalpha etc. are used for the character classes. */ -#include - -/* Jim Meyering writes: - - "... Some ctype macros are valid only for character codes that - isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when - using /bin/cc or gcc but without giving an ansi option). So, all - ctype uses should be through macros like ISPRINT... If - STDC_HEADERS is defined, then autoconf has verified that the ctype - macros don't need to be guarded with references to isascii. ... - Defining isascii to 1 should let any compiler worth its salt - eliminate the && through constant folding." - Solaris defines some of these symbols so we must undefine them first. */ - -#undef ISASCII -#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII) -# define ISASCII(c) 1 -#else -# define ISASCII(c) isascii(c) -#endif - -#ifdef isblank -# define ISBLANK(c) (ISASCII (c) && isblank (c)) -#else -# define ISBLANK(c) ((c) == ' ' || (c) == '\t') -#endif -#ifdef isgraph -# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) -#else -# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) -#endif - -#undef ISPRINT -#define ISPRINT(c) (ISASCII (c) && isprint (c)) -#define ISDIGIT(c) (ISASCII (c) && isdigit (c)) -#define ISALNUM(c) (ISASCII (c) && isalnum (c)) -#define ISALPHA(c) (ISASCII (c) && isalpha (c)) -#define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) -#define ISLOWER(c) (ISASCII (c) && islower (c)) -#define ISPUNCT(c) (ISASCII (c) && ispunct (c)) -#define ISSPACE(c) (ISASCII (c) && isspace (c)) -#define ISUPPER(c) (ISASCII (c) && isupper (c)) -#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) - -#ifndef NULL -# define NULL (void *)0 -#endif - -/* We remove any previous definition of `SIGN_EXTEND_CHAR', - since ours (we hope) works properly with all combinations of - machines, compilers, `char' and `unsigned char' argument types. - (Per Bothner suggested the basic approach.) */ -#undef SIGN_EXTEND_CHAR -#if __STDC__ -# define SIGN_EXTEND_CHAR(c) ((signed char) (c)) -#else /* not __STDC__ */ -/* As in Harbison and Steele. */ -# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) -#endif - -/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we - use `alloca' instead of `malloc'. This is because using malloc in - re_search* or re_match* could cause memory leaks when C-g is used in - Emacs; also, malloc is slower and causes storage fragmentation. On - the other hand, malloc is more portable, and easier to debug. - - Because we sometimes use alloca, some routines have to be macros, - not functions -- `alloca'-allocated space disappears at the end of the - function it is called in. */ - -#ifdef REGEX_MALLOC - -# define REGEX_ALLOCATE malloc -# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) -# define REGEX_FREE free - -#else /* not REGEX_MALLOC */ - -/* Emacs already defines alloca, sometimes. */ -# ifndef alloca - -/* Make alloca work the best possible way. */ -# ifdef __GNUC__ -# define alloca __builtin_alloca -# else /* not __GNUC__ */ -# if HAVE_ALLOCA_H -# include -# endif /* HAVE_ALLOCA_H */ -# endif /* not __GNUC__ */ - -# endif /* not alloca */ - -# define REGEX_ALLOCATE alloca - -/* Assumes a `char *destination' variable. */ -# define REGEX_REALLOCATE(source, osize, nsize) \ - (destination = (char *) alloca (nsize), \ - memcpy (destination, source, osize)) - -/* No need to do anything to free, after alloca. */ -# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */ - -#endif /* not REGEX_MALLOC */ - -/* Define how to allocate the failure stack. */ - -#if defined REL_ALLOC && defined REGEX_MALLOC - -# define REGEX_ALLOCATE_STACK(size) \ - r_alloc (&failure_stack_ptr, (size)) -# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ - r_re_alloc (&failure_stack_ptr, (nsize)) -# define REGEX_FREE_STACK(ptr) \ - r_alloc_free (&failure_stack_ptr) - -#else /* not using relocating allocator */ - -# ifdef REGEX_MALLOC - -# define REGEX_ALLOCATE_STACK malloc -# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) -# define REGEX_FREE_STACK free - -# else /* not REGEX_MALLOC */ - -# define REGEX_ALLOCATE_STACK alloca - -# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ - REGEX_REALLOCATE (source, osize, nsize) -/* No need to explicitly free anything. */ -# define REGEX_FREE_STACK(arg) - -# endif /* not REGEX_MALLOC */ -#endif /* not using relocating allocator */ - - -/* True if `size1' is non-NULL and PTR is pointing anywhere inside - `string1' or just past its end. This works if PTR is NULL, which is - a good thing. */ -#define FIRST_STRING_P(ptr) \ - (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) - -/* (Re)Allocate N items of type T using malloc, or fail. */ -#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) -#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) -#define RETALLOC_IF(addr, n, t) \ - if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t) -#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) - -#define BYTEWIDTH 8 /* In bits. */ - -#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) - -#undef MAX -#undef MIN -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -typedef char boolean; -#define false 0 -#define true 1 - -static int re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp, - const char *string1, int size1, - const char *string2, int size2, - int pos, - struct re_registers *regs, - int stop)); - -/* These are the command codes that appear in compiled regular - expressions. Some opcodes are followed by argument bytes. A - command code can specify any interpretation whatsoever for its - arguments. Zero bytes may appear in the compiled regular expression. */ - -typedef enum -{ - no_op = 0, - - /* Succeed right away--no more backtracking. */ - succeed, - - /* Followed by one byte giving n, then by n literal bytes. */ - exactn, - - /* Matches any (more or less) character. */ - anychar, - - /* Matches any one char belonging to specified set. First - following byte is number of bitmap bytes. Then come bytes - for a bitmap saying which chars are in. Bits in each byte - are ordered low-bit-first. A character is in the set if its - bit is 1. A character too large to have a bit in the map is - automatically not in the set. */ - charset, - - /* Same parameters as charset, but match any character that is - not one of those specified. */ - charset_not, - - /* Start remembering the text that is matched, for storing in a - register. Followed by one byte with the register number, in - the range 0 to one less than the pattern buffer's re_nsub - field. Then followed by one byte with the number of groups - inner to this one. (This last has to be part of the - start_memory only because we need it in the on_failure_jump - of re_match_2.) */ - start_memory, - - /* Stop remembering the text that is matched and store it in a - memory register. Followed by one byte with the register - number, in the range 0 to one less than `re_nsub' in the - pattern buffer, and one byte with the number of inner groups, - just like `start_memory'. (We need the number of inner - groups here because we don't have any easy way of finding the - corresponding start_memory when we're at a stop_memory.) */ - stop_memory, - - /* Match a duplicate of something remembered. Followed by one - byte containing the register number. */ - duplicate, - - /* Fail unless at beginning of line. */ - begline, - - /* Fail unless at end of line. */ - endline, - - /* Succeeds if at beginning of buffer (if emacs) or at beginning - of string to be matched (if not). */ - begbuf, - - /* Analogously, for end of buffer/string. */ - endbuf, - - /* Followed by two byte relative address to which to jump. */ - jump, - - /* Same as jump, but marks the end of an alternative. */ - jump_past_alt, - - /* Followed by two-byte relative address of place to resume at - in case of failure. */ - on_failure_jump, - - /* Like on_failure_jump, but pushes a placeholder instead of the - current string position when executed. */ - on_failure_keep_string_jump, - - /* Throw away latest failure point and then jump to following - two-byte relative address. */ - pop_failure_jump, - - /* Change to pop_failure_jump if know won't have to backtrack to - match; otherwise change to jump. This is used to jump - back to the beginning of a repeat. If what follows this jump - clearly won't match what the repeat does, such that we can be - sure that there is no use backtracking out of repetitions - already matched, then we change it to a pop_failure_jump. - Followed by two-byte address. */ - maybe_pop_jump, - - /* Jump to following two-byte address, and push a dummy failure - point. This failure point will be thrown away if an attempt - is made to use it for a failure. A `+' construct makes this - before the first repeat. Also used as an intermediary kind - of jump when compiling an alternative. */ - dummy_failure_jump, - - /* Push a dummy failure point and continue. Used at the end of - alternatives. */ - push_dummy_failure, - - /* Followed by two-byte relative address and two-byte number n. - After matching N times, jump to the address upon failure. */ - succeed_n, - - /* Followed by two-byte relative address, and two-byte number n. - Jump to the address N times, then fail. */ - jump_n, - - /* Set the following two-byte relative address to the - subsequent two-byte number. The address *includes* the two - bytes of number. */ - set_number_at, - - wordchar, /* Matches any word-constituent character. */ - notwordchar, /* Matches any char that is not a word-constituent. */ - - wordbeg, /* Succeeds if at word beginning. */ - wordend, /* Succeeds if at word end. */ - - wordbound, /* Succeeds if at a word boundary. */ - notwordbound /* Succeeds if not at a word boundary. */ - -#ifdef emacs - ,before_dot, /* Succeeds if before point. */ - at_dot, /* Succeeds if at point. */ - after_dot, /* Succeeds if after point. */ - - /* Matches any character whose syntax is specified. Followed by - a byte which contains a syntax code, e.g., Sword. */ - syntaxspec, - - /* Matches any character whose syntax is not that specified. */ - notsyntaxspec -#endif /* emacs */ -} re_opcode_t; - -/* Common operations on the compiled pattern. */ - -/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ - -#define STORE_NUMBER(destination, number) \ - do { \ - (destination)[0] = (number) & 0377; \ - (destination)[1] = (number) >> 8; \ - } while (0) - -/* Same as STORE_NUMBER, except increment DESTINATION to - the byte after where the number is stored. Therefore, DESTINATION - must be an lvalue. */ - -#define STORE_NUMBER_AND_INCR(destination, number) \ - do { \ - STORE_NUMBER (destination, number); \ - (destination) += 2; \ - } while (0) - -/* Put into DESTINATION a number stored in two contiguous bytes starting - at SOURCE. */ - -#define EXTRACT_NUMBER(destination, source) \ - do { \ - (destination) = *(source) & 0377; \ - (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ - } while (0) - -#ifdef DEBUG -static void extract_number _RE_ARGS ((int *dest, unsigned char *source)); -static void -extract_number (dest, source) - int *dest; - unsigned char *source; -{ - int temp = SIGN_EXTEND_CHAR (*(source + 1)); - *dest = *source & 0377; - *dest += temp << 8; -} - -# ifndef EXTRACT_MACROS /* To debug the macros. */ -# undef EXTRACT_NUMBER -# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) -# endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. - SOURCE must be an lvalue. */ - -#define EXTRACT_NUMBER_AND_INCR(destination, source) \ - do { \ - EXTRACT_NUMBER (destination, source); \ - (source) += 2; \ - } while (0) - -#ifdef DEBUG -static void extract_number_and_incr _RE_ARGS ((int *destination, - unsigned char **source)); -static void -extract_number_and_incr (destination, source) - int *destination; - unsigned char **source; -{ - extract_number (destination, *source); - *source += 2; -} - -# ifndef EXTRACT_MACROS -# undef EXTRACT_NUMBER_AND_INCR -# define EXTRACT_NUMBER_AND_INCR(dest, src) \ - extract_number_and_incr (&dest, &src) -# endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* If DEBUG is defined, Regex prints many voluminous messages about what - it is doing (if the variable `debug' is nonzero). If linked with the - main program in `iregex.c', you can enter patterns and strings - interactively. And if linked with the main program in `main.c' and - the other test files, you can run the already-written tests. */ - -#ifdef DEBUG - -/* We use standard I/O for debugging. */ -# include - -/* It is useful to test things that ``must'' be true when debugging. */ -# include - -static int debug = 0; - -# define DEBUG_STATEMENT(e) e -# define DEBUG_PRINT1(x) if (debug) printf (x) -# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) -# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) -# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) -# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ - if (debug) print_partial_compiled_pattern (s, e) -# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ - if (debug) print_double_string (w, s1, sz1, s2, sz2) - - -/* Print the fastmap in human-readable form. */ - -void -print_fastmap (fastmap) - char *fastmap; -{ - unsigned was_a_range = 0; - unsigned i = 0; - - while (i < (1 << BYTEWIDTH)) - { - if (fastmap[i++]) - { - was_a_range = 0; - putchar (i - 1); - while (i < (1 << BYTEWIDTH) && fastmap[i]) - { - was_a_range = 1; - i++; - } - if (was_a_range) - { - printf ("-"); - putchar (i - 1); - } - } - } - putchar ('\n'); -} - - -/* Print a compiled pattern string in human-readable form, starting at - the START pointer into it and ending just before the pointer END. */ - -void -print_partial_compiled_pattern (start, end) - unsigned char *start; - unsigned char *end; -{ - int mcnt, mcnt2; - unsigned char *p1; - unsigned char *p = start; - unsigned char *pend = end; - - if (start == NULL) - { - printf ("(null)\n"); - return; - } - - /* Loop over pattern commands. */ - while (p < pend) - { - printf ("%d:\t", p - start); - - switch ((re_opcode_t) *p++) - { - case no_op: - printf ("/no_op"); - break; - - case exactn: - mcnt = *p++; - printf ("/exactn/%d", mcnt); - do - { - putchar ('/'); - putchar (*p++); - } - while (--mcnt); - break; - - case start_memory: - mcnt = *p++; - printf ("/start_memory/%d/%d", mcnt, *p++); - break; - - case stop_memory: - mcnt = *p++; - printf ("/stop_memory/%d/%d", mcnt, *p++); - break; - - case duplicate: - printf ("/duplicate/%d", *p++); - break; - - case anychar: - printf ("/anychar"); - break; - - case charset: - case charset_not: - { - register int c, last = -100; - register int in_range = 0; - - printf ("/charset [%s", - (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); - - assert (p + *p < pend); - - for (c = 0; c < 256; c++) - if (c / 8 < *p - && (p[1 + (c/8)] & (1 << (c % 8)))) - { - /* Are we starting a range? */ - if (last + 1 == c && ! in_range) - { - putchar ('-'); - in_range = 1; - } - /* Have we broken a range? */ - else if (last + 1 != c && in_range) - { - putchar (last); - in_range = 0; - } - - if (! in_range) - putchar (c); - - last = c; - } - - if (in_range) - putchar (last); - - putchar (']'); - - p += 1 + *p; - } - break; - - case begline: - printf ("/begline"); - break; - - case endline: - printf ("/endline"); - break; - - case on_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_jump to %d", p + mcnt - start); - break; - - case on_failure_keep_string_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_keep_string_jump to %d", p + mcnt - start); - break; - - case dummy_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/dummy_failure_jump to %d", p + mcnt - start); - break; - - case push_dummy_failure: - printf ("/push_dummy_failure"); - break; - - case maybe_pop_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/maybe_pop_jump to %d", p + mcnt - start); - break; - - case pop_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/pop_failure_jump to %d", p + mcnt - start); - break; - - case jump_past_alt: - extract_number_and_incr (&mcnt, &p); - printf ("/jump_past_alt to %d", p + mcnt - start); - break; - - case jump: - extract_number_and_incr (&mcnt, &p); - printf ("/jump to %d", p + mcnt - start); - break; - - case succeed_n: - extract_number_and_incr (&mcnt, &p); - p1 = p + mcnt; - extract_number_and_incr (&mcnt2, &p); - printf ("/succeed_n to %d, %d times", p1 - start, mcnt2); - break; - - case jump_n: - extract_number_and_incr (&mcnt, &p); - p1 = p + mcnt; - extract_number_and_incr (&mcnt2, &p); - printf ("/jump_n to %d, %d times", p1 - start, mcnt2); - break; - - case set_number_at: - extract_number_and_incr (&mcnt, &p); - p1 = p + mcnt; - extract_number_and_incr (&mcnt2, &p); - printf ("/set_number_at location %d to %d", p1 - start, mcnt2); - break; - - case wordbound: - printf ("/wordbound"); - break; - - case notwordbound: - printf ("/notwordbound"); - break; - - case wordbeg: - printf ("/wordbeg"); - break; - - case wordend: - printf ("/wordend"); - -# ifdef emacs - case before_dot: - printf ("/before_dot"); - break; - - case at_dot: - printf ("/at_dot"); - break; - - case after_dot: - printf ("/after_dot"); - break; - - case syntaxspec: - printf ("/syntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; - - case notsyntaxspec: - printf ("/notsyntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; -# endif /* emacs */ - - case wordchar: - printf ("/wordchar"); - break; - - case notwordchar: - printf ("/notwordchar"); - break; - - case begbuf: - printf ("/begbuf"); - break; - - case endbuf: - printf ("/endbuf"); - break; - - default: - printf ("?%d", *(p-1)); - } - - putchar ('\n'); - } - - printf ("%d:\tend of pattern.\n", p - start); -} - - -void -print_compiled_pattern (bufp) - struct re_pattern_buffer *bufp; -{ - unsigned char *buffer = bufp->buffer; - - print_partial_compiled_pattern (buffer, buffer + bufp->used); - printf ("%ld bytes used/%ld bytes allocated.\n", - bufp->used, bufp->allocated); - - if (bufp->fastmap_accurate && bufp->fastmap) - { - printf ("fastmap: "); - print_fastmap (bufp->fastmap); - } - - printf ("re_nsub: %d\t", bufp->re_nsub); - printf ("regs_alloc: %d\t", bufp->regs_allocated); - printf ("can_be_null: %d\t", bufp->can_be_null); - printf ("newline_anchor: %d\n", bufp->newline_anchor); - printf ("no_sub: %d\t", bufp->no_sub); - printf ("not_bol: %d\t", bufp->not_bol); - printf ("not_eol: %d\t", bufp->not_eol); - printf ("syntax: %lx\n", bufp->syntax); - /* Perhaps we should print the translate table? */ -} - - -void -print_double_string (where, string1, size1, string2, size2) - const char *where; - const char *string1; - const char *string2; - int size1; - int size2; -{ - int this_char; - - if (where == NULL) - printf ("(null)"); - else - { - if (FIRST_STRING_P (where)) - { - for (this_char = where - string1; this_char < size1; this_char++) - putchar (string1[this_char]); - - where = string2; - } - - for (this_char = where - string2; this_char < size2; this_char++) - putchar (string2[this_char]); - } -} - -void -printchar (c) - int c; -{ - putc (c, stderr); -} - -#else /* not DEBUG */ - -# undef assert -# define assert(e) - -# define DEBUG_STATEMENT(e) -# define DEBUG_PRINT1(x) -# define DEBUG_PRINT2(x1, x2) -# define DEBUG_PRINT3(x1, x2, x3) -# define DEBUG_PRINT4(x1, x2, x3, x4) -# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) -# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) - -#endif /* not DEBUG */ - -/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can - also be assigned to arbitrarily: each pattern buffer stores its own - syntax, so it can be changed between regex compilations. */ -/* This has no initializer because initialized variables in Emacs - become read-only after dumping. */ -reg_syntax_t re_syntax_options; - - -/* Specify the precise syntax of regexps for compilation. This provides - for compatibility for various utilities which historically have - different, incompatible syntaxes. - - The argument SYNTAX is a bit mask comprised of the various bits - defined in gnu-regex.h. We return the old syntax. */ - -reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; -{ - reg_syntax_t ret = re_syntax_options; - - re_syntax_options = syntax; -#ifdef DEBUG - if (syntax & RE_DEBUG) - debug = 1; - else if (debug) /* was on but now is not */ - debug = 0; -#endif /* DEBUG */ - return ret; -} -#ifdef _LIBC -weak_alias (__re_set_syntax, re_set_syntax) -#endif - -/* This table gives an error message for each of the error codes listed - in gnu-regex.h. Obviously the order here has to be same as there. - POSIX doesn't require that we do anything for REG_NOERROR, - but why not be nice? */ - -static const char *re_error_msgid[] = - { - gettext_noop ("Success"), /* REG_NOERROR */ - gettext_noop ("No match"), /* REG_NOMATCH */ - gettext_noop ("Invalid regular expression"), /* REG_BADPAT */ - gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */ - gettext_noop ("Invalid character class name"), /* REG_ECTYPE */ - gettext_noop ("Trailing backslash"), /* REG_EESCAPE */ - gettext_noop ("Invalid back reference"), /* REG_ESUBREG */ - gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */ - gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */ - gettext_noop ("Unmatched \\{"), /* REG_EBRACE */ - gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */ - gettext_noop ("Invalid range end"), /* REG_ERANGE */ - gettext_noop ("Memory exhausted"), /* REG_ESPACE */ - gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */ - gettext_noop ("Premature end of regular expression"), /* REG_EEND */ - gettext_noop ("Regular expression too big"), /* REG_ESIZE */ - gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */ - }; - -/* Avoiding alloca during matching, to placate r_alloc. */ - -/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the - searching and matching functions should not call alloca. On some - systems, alloca is implemented in terms of malloc, and if we're - using the relocating allocator routines, then malloc could cause a - relocation, which might (if the strings being searched are in the - ralloc heap) shift the data out from underneath the regexp - routines. - - Here's another reason to avoid allocation: Emacs - processes input from X in a signal handler; processing X input may - call malloc; if input arrives while a matching routine is calling - malloc, then we're scrod. But Emacs can't just block input while - calling matching routines; then we don't notice interrupts when - they come in. So, Emacs blocks input around all regexp calls - except the matching calls, which it leaves unprotected, in the - faith that they will not malloc. */ - -/* Normally, this is fine. */ -#define MATCH_MAY_ALLOCATE - -/* When using GNU C, we are not REALLY using the C alloca, no matter - what config.h may say. So don't take precautions for it. */ -#ifdef __GNUC__ -# undef C_ALLOCA -#endif - -/* The match routines may not allocate if (1) they would do it with malloc - and (2) it's not safe for them to use malloc. - Note that if REL_ALLOC is defined, matching would not use malloc for the - failure stack, but we would still use it for the register vectors; - so REL_ALLOC should not affect this. */ -#if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs -# undef MATCH_MAY_ALLOCATE -#endif - - -/* Failure stack declarations and macros; both re_compile_fastmap and - re_match_2 use a failure stack. These have to be macros because of - REGEX_ALLOCATE_STACK. */ - - -/* Number of failure points for which to initially allocate space - when matching. If this number is exceeded, we allocate more - space, so it is not a hard limit. */ -#ifndef INIT_FAILURE_ALLOC -# define INIT_FAILURE_ALLOC 5 -#endif - -/* Roughly the maximum number of failure points on the stack. Would be - exactly that if always used MAX_FAILURE_ITEMS items each time we failed. - This is a variable only so users of regex can assign to it; we never - change it ourselves. */ - -#ifdef INT_IS_16BIT - -# if defined MATCH_MAY_ALLOCATE -/* 4400 was enough to cause a crash on Alpha OSF/1, - whose default stack limit is 2mb. */ -long int re_max_failures = 4000; -# else -long int re_max_failures = 2000; -# endif - -union fail_stack_elt -{ - unsigned char *pointer; - long int integer; -}; - -typedef union fail_stack_elt fail_stack_elt_t; - -typedef struct -{ - fail_stack_elt_t *stack; - unsigned long int size; - unsigned long int avail; /* Offset of next open position. */ -} fail_stack_type; - -#else /* not INT_IS_16BIT */ - -# if defined MATCH_MAY_ALLOCATE -/* 4400 was enough to cause a crash on Alpha OSF/1, - whose default stack limit is 2mb. */ -int re_max_failures = 20000; -# else -int re_max_failures = 2000; -# endif - -union fail_stack_elt -{ - unsigned char *pointer; - int integer; -}; - -typedef union fail_stack_elt fail_stack_elt_t; - -typedef struct -{ - fail_stack_elt_t *stack; - unsigned size; - unsigned avail; /* Offset of next open position. */ -} fail_stack_type; - -#endif /* INT_IS_16BIT */ - -#define FAIL_STACK_EMPTY() (fail_stack.avail == 0) -#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) -#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) - - -/* Define macros to initialize and free the failure stack. - Do `return -2' if the alloc fails. */ - -#ifdef MATCH_MAY_ALLOCATE -# define INIT_FAIL_STACK() \ - do { \ - fail_stack.stack = (fail_stack_elt_t *) \ - REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ - \ - if (fail_stack.stack == NULL) \ - return -2; \ - \ - fail_stack.size = INIT_FAILURE_ALLOC; \ - fail_stack.avail = 0; \ - } while (0) - -# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack) -#else -# define INIT_FAIL_STACK() \ - do { \ - fail_stack.avail = 0; \ - } while (0) - -# define RESET_FAIL_STACK() -#endif - - -/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. - - Return 1 if succeeds, and 0 if either ran out of memory - allocating space for it or it was already too large. - - REGEX_REALLOCATE_STACK requires `destination' be declared. */ - -#define DOUBLE_FAIL_STACK(fail_stack) \ - ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \ - ? 0 \ - : ((fail_stack).stack = (fail_stack_elt_t *) \ - REGEX_REALLOCATE_STACK ((fail_stack).stack, \ - (fail_stack).size * sizeof (fail_stack_elt_t), \ - ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ - \ - (fail_stack).stack == NULL \ - ? 0 \ - : ((fail_stack).size <<= 1, \ - 1))) - - -/* Push pointer POINTER on FAIL_STACK. - Return 1 if was able to do so and 0 if ran out of memory allocating - space to do so. */ -#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ - ((FAIL_STACK_FULL () \ - && !DOUBLE_FAIL_STACK (FAIL_STACK)) \ - ? 0 \ - : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ - 1)) - -/* Push a pointer value onto the failure stack. - Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_POINTER(item) \ - fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item) - -/* This pushes an integer-valued item onto the failure stack. - Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_INT(item) \ - fail_stack.stack[fail_stack.avail++].integer = (item) - -/* Push a fail_stack_elt_t value onto the failure stack. - Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_ELT(item) \ - fail_stack.stack[fail_stack.avail++] = (item) - -/* These three POP... operations complement the three PUSH... operations. - All assume that `fail_stack' is nonempty. */ -#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer -#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer -#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] - -/* Used to omit pushing failure point id's when we're not debugging. */ -#ifdef DEBUG -# define DEBUG_PUSH PUSH_FAILURE_INT -# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT () -#else -# define DEBUG_PUSH(item) -# define DEBUG_POP(item_addr) -#endif - - -/* Push the information about the state we will need - if we ever fail back to it. - - Requires variables fail_stack, regstart, regend, reg_info, and - num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination' - be declared. - - Does `return FAILURE_CODE' if runs out of memory. */ - -#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ - do { \ - char *destination; \ - /* Must be int, so when we don't save any registers, the arithmetic \ - of 0 + -1 isn't done as unsigned. */ \ - /* Can't be int, since there is not a shred of a guarantee that int \ - is wide enough to hold a value of something to which pointer can \ - be assigned */ \ - active_reg_t this_reg; \ - \ - DEBUG_STATEMENT (failure_id++); \ - DEBUG_STATEMENT (nfailure_points_pushed++); \ - DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ - DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ - DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ - \ - DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \ - DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ - \ - /* Ensure we have enough space allocated for what we will push. */ \ - while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ - { \ - if (!DOUBLE_FAIL_STACK (fail_stack)) \ - return failure_code; \ - \ - DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ - (fail_stack).size); \ - DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ - } \ - \ - /* Push the info, starting with the registers. */ \ - DEBUG_PRINT1 ("\n"); \ - \ - if (1) \ - for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ - this_reg++) \ - { \ - DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \ - DEBUG_STATEMENT (num_regs_pushed++); \ - \ - DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ - PUSH_FAILURE_POINTER (regstart[this_reg]); \ - \ - DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ - PUSH_FAILURE_POINTER (regend[this_reg]); \ - \ - DEBUG_PRINT2 (" info: %p\n ", \ - reg_info[this_reg].word.pointer); \ - DEBUG_PRINT2 (" match_null=%d", \ - REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ - DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ - DEBUG_PRINT2 (" matched_something=%d", \ - MATCHED_SOMETHING (reg_info[this_reg])); \ - DEBUG_PRINT2 (" ever_matched=%d", \ - EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ - DEBUG_PRINT1 ("\n"); \ - PUSH_FAILURE_ELT (reg_info[this_reg].word); \ - } \ - \ - DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\ - PUSH_FAILURE_INT (lowest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\ - PUSH_FAILURE_INT (highest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ - PUSH_FAILURE_POINTER (pattern_place); \ - \ - DEBUG_PRINT2 (" Pushing string %p: `", string_place); \ - DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ - size2); \ - DEBUG_PRINT1 ("'\n"); \ - PUSH_FAILURE_POINTER (string_place); \ - \ - DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ - DEBUG_PUSH (failure_id); \ - } while (0) - -/* This is the number of items that are pushed and popped on the stack - for each register. */ -#define NUM_REG_ITEMS 3 - -/* Individual items aside from the registers. */ -#ifdef DEBUG -# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ -#else -# define NUM_NONREG_ITEMS 4 -#endif - -/* We push at most this many items on the stack. */ -/* We used to use (num_regs - 1), which is the number of registers - this regexp will save; but that was changed to 5 - to avoid stack overflow for a regexp with lots of parens. */ -#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS) - -/* We actually push this many items. */ -#define NUM_FAILURE_ITEMS \ - (((0 \ - ? 0 : highest_active_reg - lowest_active_reg + 1) \ - * NUM_REG_ITEMS) \ - + NUM_NONREG_ITEMS) - -/* How many items can still be added to the stack without overflowing it. */ -#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) - - -/* Pops what PUSH_FAIL_STACK pushes. - - We restore into the parameters, all of which should be lvalues: - STR -- the saved data position. - PAT -- the saved pattern position. - LOW_REG, HIGH_REG -- the highest and lowest active registers. - REGSTART, REGEND -- arrays of string positions. - REG_INFO -- array of information about each subexpression. - - Also assumes the variables `fail_stack' and (if debugging), `bufp', - `pend', `string1', `size1', `string2', and `size2'. */ - -#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ -{ \ - DEBUG_STATEMENT (unsigned failure_id;) \ - active_reg_t this_reg; \ - const unsigned char *string_temp; \ - \ - assert (!FAIL_STACK_EMPTY ()); \ - \ - /* Remove failure points and point to how many regs pushed. */ \ - DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ - DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ - DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ - \ - assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ - \ - DEBUG_POP (&failure_id); \ - DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ - \ - /* If the saved string location is NULL, it came from an \ - on_failure_keep_string_jump opcode, and we want to throw away the \ - saved NULL, thus retaining our current position in the string. */ \ - string_temp = POP_FAILURE_POINTER (); \ - if (string_temp != NULL) \ - str = (const char *) string_temp; \ - \ - DEBUG_PRINT2 (" Popping string %p: `", str); \ - DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ - DEBUG_PRINT1 ("'\n"); \ - \ - pat = (unsigned char *) POP_FAILURE_POINTER (); \ - DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ - \ - /* Restore register info. */ \ - high_reg = (active_reg_t) POP_FAILURE_INT (); \ - DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \ - \ - low_reg = (active_reg_t) POP_FAILURE_INT (); \ - DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \ - \ - if (1) \ - for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ - { \ - DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \ - \ - reg_info[this_reg].word = POP_FAILURE_ELT (); \ - DEBUG_PRINT2 (" info: %p\n", \ - reg_info[this_reg].word.pointer); \ - \ - regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \ - DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ - \ - regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \ - DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ - } \ - else \ - { \ - for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \ - { \ - reg_info[this_reg].word.integer = 0; \ - regend[this_reg] = 0; \ - regstart[this_reg] = 0; \ - } \ - highest_active_reg = high_reg; \ - } \ - \ - set_regs_matched_done = 0; \ - DEBUG_STATEMENT (nfailure_points_popped++); \ -} /* POP_FAILURE_POINT */ - - - -/* Structure for per-register (a.k.a. per-group) information. - Other register information, such as the - starting and ending positions (which are addresses), and the list of - inner groups (which is a bits list) are maintained in separate - variables. - - We are making a (strictly speaking) nonportable assumption here: that - the compiler will pack our bit fields into something that fits into - the type of `word', i.e., is something that fits into one item on the - failure stack. */ - - -/* Declarations and macros for re_match_2. */ - -typedef union -{ - fail_stack_elt_t word; - struct - { - /* This field is one if this group can match the empty string, - zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ -#define MATCH_NULL_UNSET_VALUE 3 - unsigned match_null_string_p : 2; - unsigned is_active : 1; - unsigned matched_something : 1; - unsigned ever_matched_something : 1; - } bits; -} register_info_type; - -#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) -#define IS_ACTIVE(R) ((R).bits.is_active) -#define MATCHED_SOMETHING(R) ((R).bits.matched_something) -#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) - - -/* Call this when have matched a real character; it sets `matched' flags - for the subexpressions which we are currently inside. Also records - that those subexprs have matched. */ -#define SET_REGS_MATCHED() \ - do \ - { \ - if (!set_regs_matched_done) \ - { \ - active_reg_t r; \ - set_regs_matched_done = 1; \ - for (r = lowest_active_reg; r <= highest_active_reg; r++) \ - { \ - MATCHED_SOMETHING (reg_info[r]) \ - = EVER_MATCHED_SOMETHING (reg_info[r]) \ - = 1; \ - } \ - } \ - } \ - while (0) - -/* Registers are set to a sentinel when they haven't yet matched. */ -static char reg_unset_dummy; -#define REG_UNSET_VALUE (®_unset_dummy) -#define REG_UNSET(e) ((e) == REG_UNSET_VALUE) - -/* Subroutine declarations and macros for regex_compile. */ - -static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size, - reg_syntax_t syntax, - struct re_pattern_buffer *bufp)); -static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg)); -static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, - int arg1, int arg2)); -static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, - int arg, unsigned char *end)); -static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, - int arg1, int arg2, unsigned char *end)); -static boolean at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p, - reg_syntax_t syntax)); -static boolean at_endline_loc_p _RE_ARGS ((const char *p, const char *pend, - reg_syntax_t syntax)); -static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr, - const char *pend, - char *translate, - reg_syntax_t syntax, - unsigned char *b)); - -/* Fetch the next character in the uncompiled pattern---translating it - if necessary. Also cast from a signed character in the constant - string passed to us by the user to an unsigned char that we can use - as an array index (in, e.g., `translate'). */ -#ifndef PATFETCH -# define PATFETCH(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - if (translate) c = (unsigned char) translate[c]; \ - } while (0) -#endif - -/* Fetch the next character in the uncompiled pattern, with no - translation. */ -#define PATFETCH_RAW(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - } while (0) - -/* Go backwards one character in the pattern. */ -#define PATUNFETCH p-- - - -/* If `translate' is non-null, return translate[D], else just D. We - cast the subscript to translate because some data is declared as - `char *', to avoid warnings when a string constant is passed. But - when we use a character as a subscript we must make it unsigned. */ -#ifndef TRANSLATE -# define TRANSLATE(d) \ - (translate ? (char) translate[(unsigned char) (d)] : (d)) -#endif - - -/* Macros for outputting the compiled pattern into `buffer'. */ - -/* If the buffer isn't allocated when it comes in, use this. */ -#define INIT_BUF_SIZE 32 - -/* Make sure we have at least N more bytes of space in buffer. */ -#define GET_BUFFER_SPACE(n) \ - while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \ - EXTEND_BUFFER () - -/* Make sure we have one more byte of buffer space and then add C to it. */ -#define BUF_PUSH(c) \ - do { \ - GET_BUFFER_SPACE (1); \ - *b++ = (unsigned char) (c); \ - } while (0) - - -/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ -#define BUF_PUSH_2(c1, c2) \ - do { \ - GET_BUFFER_SPACE (2); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - } while (0) - - -/* As with BUF_PUSH_2, except for three bytes. */ -#define BUF_PUSH_3(c1, c2, c3) \ - do { \ - GET_BUFFER_SPACE (3); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - *b++ = (unsigned char) (c3); \ - } while (0) - - -/* Store a jump with opcode OP at LOC to location TO. We store a - relative address offset by the three bytes the jump itself occupies. */ -#define STORE_JUMP(op, loc, to) \ - store_op1 (op, loc, (int) ((to) - (loc) - 3)) - -/* Likewise, for a two-argument jump. */ -#define STORE_JUMP2(op, loc, to, arg) \ - store_op2 (op, loc, (int) ((to) - (loc) - 3), arg) - -/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ -#define INSERT_JUMP(op, loc, to) \ - insert_op1 (op, loc, (int) ((to) - (loc) - 3), b) - -/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ -#define INSERT_JUMP2(op, loc, to, arg) \ - insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b) - - -/* This is not an arbitrary limit: the arguments which represent offsets - into the pattern are two bytes long. So if 2^16 bytes turns out to - be too small, many things would have to change. */ -/* Any other compiler which, like MSC, has allocation limit below 2^16 - bytes will have to use approach similar to what was done below for - MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up - reallocating to 0 bytes. Such thing is not going to work too well. - You have been warned!! */ -#if defined _MSC_VER && !defined WIN32 -/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes. - The REALLOC define eliminates a flurry of conversion warnings, - but is not required. */ -# define MAX_BUF_SIZE 65500L -# define REALLOC(p,s) realloc ((p), (size_t) (s)) -#else -# define MAX_BUF_SIZE (1L << 16) -# define REALLOC(p,s) realloc ((p), (s)) -#endif - -/* Extend the buffer by twice its current size via realloc and - reset the pointers that pointed into the old block to point to the - correct places in the new one. If extending the buffer results in it - being larger than MAX_BUF_SIZE, then flag memory exhausted. */ -#define EXTEND_BUFFER() \ - do { \ - unsigned char *old_buffer = bufp->buffer; \ - if (bufp->allocated == MAX_BUF_SIZE) \ - return REG_ESIZE; \ - bufp->allocated <<= 1; \ - if (bufp->allocated > MAX_BUF_SIZE) \ - bufp->allocated = MAX_BUF_SIZE; \ - bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\ - if (bufp->buffer == NULL) \ - return REG_ESPACE; \ - /* If the buffer moved, move all the pointers into it. */ \ - if (old_buffer != bufp->buffer) \ - { \ - b = (b - old_buffer) + bufp->buffer; \ - begalt = (begalt - old_buffer) + bufp->buffer; \ - if (fixup_alt_jump) \ - fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ - if (laststart) \ - laststart = (laststart - old_buffer) + bufp->buffer; \ - if (pending_exact) \ - pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ - } \ - } while (0) - - -/* Since we have one byte reserved for the register number argument to - {start,stop}_memory, the maximum number of groups we can report - things about is what fits in that byte. */ -#define MAX_REGNUM 255 - -/* But patterns can have more than `MAX_REGNUM' registers. We just - ignore the excess. */ -typedef unsigned regnum_t; - - -/* Macros for the compile stack. */ - -/* Since offsets can go either forwards or backwards, this type needs to - be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ -/* int may be not enough when sizeof(int) == 2. */ -typedef long pattern_offset_t; - -typedef struct -{ - pattern_offset_t begalt_offset; - pattern_offset_t fixup_alt_jump; - pattern_offset_t inner_group_offset; - pattern_offset_t laststart_offset; - regnum_t regnum; -} compile_stack_elt_t; - - -typedef struct -{ - compile_stack_elt_t *stack; - unsigned size; - unsigned avail; /* Offset of next open position. */ -} compile_stack_type; - - -#define INIT_COMPILE_STACK_SIZE 32 - -#define COMPILE_STACK_EMPTY (compile_stack.avail == 0) -#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) - -/* The next available element. */ -#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) - - -/* Set the bit for character C in a list. */ -#define SET_LIST_BIT(c) \ - (b[((unsigned char) (c)) / BYTEWIDTH] \ - |= 1 << (((unsigned char) c) % BYTEWIDTH)) - - -/* Get the next unsigned number in the uncompiled pattern. */ -#define GET_UNSIGNED_NUMBER(num) \ - { if (p != pend) \ - { \ - PATFETCH (c); \ - while (ISDIGIT (c)) \ - { \ - if (num < 0) \ - num = 0; \ - num = num * 10 + c - '0'; \ - if (p == pend) \ - break; \ - PATFETCH (c); \ - } \ - } \ - } - -#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) -/* The GNU C library provides support for user-defined character classes - and the functions from ISO C amendement 1. */ -# ifdef CHARCLASS_NAME_MAX -# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX -# else -/* This shouldn't happen but some implementation might still have this - problem. Use a reasonable default value. */ -# define CHAR_CLASS_MAX_LENGTH 256 -# endif - -# ifdef _LIBC -# define IS_CHAR_CLASS(string) __wctype (string) -# else -# define IS_CHAR_CLASS(string) wctype (string) -# endif -#else -# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ - -# define IS_CHAR_CLASS(string) \ - (STREQ (string, "alpha") || STREQ (string, "upper") \ - || STREQ (string, "lower") || STREQ (string, "digit") \ - || STREQ (string, "alnum") || STREQ (string, "xdigit") \ - || STREQ (string, "space") || STREQ (string, "print") \ - || STREQ (string, "punct") || STREQ (string, "graph") \ - || STREQ (string, "cntrl") || STREQ (string, "blank")) -#endif - -#ifndef MATCH_MAY_ALLOCATE - -/* If we cannot allocate large objects within re_match_2_internal, - we make the fail stack and register vectors global. - The fail stack, we grow to the maximum size when a regexp - is compiled. - The register vectors, we adjust in size each time we - compile a regexp, according to the number of registers it needs. */ - -static fail_stack_type fail_stack; - -/* Size with which the following vectors are currently allocated. - That is so we can make them bigger as needed, - but never make them smaller. */ -static int regs_allocated_size; - -static const char ** regstart, ** regend; -static const char ** old_regstart, ** old_regend; -static const char **best_regstart, **best_regend; -static register_info_type *reg_info; -static const char **reg_dummy; -static register_info_type *reg_info_dummy; - -/* Make the register vectors big enough for NUM_REGS registers, - but don't make them smaller. */ - -static -regex_grow_registers (num_regs) - int num_regs; -{ - if (num_regs > regs_allocated_size) - { - RETALLOC_IF (regstart, num_regs, const char *); - RETALLOC_IF (regend, num_regs, const char *); - RETALLOC_IF (old_regstart, num_regs, const char *); - RETALLOC_IF (old_regend, num_regs, const char *); - RETALLOC_IF (best_regstart, num_regs, const char *); - RETALLOC_IF (best_regend, num_regs, const char *); - RETALLOC_IF (reg_info, num_regs, register_info_type); - RETALLOC_IF (reg_dummy, num_regs, const char *); - RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); - - regs_allocated_size = num_regs; - } -} - -#endif /* not MATCH_MAY_ALLOCATE */ - -static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type - compile_stack, - regnum_t regnum)); - -/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. - Returns one of error codes defined in `gnu-regex.h', or zero for success. - - Assumes the `allocated' (and perhaps `buffer') and `translate' - fields are set in BUFP on entry. - - If it succeeds, results are put in BUFP (if it returns an error, the - contents of BUFP are undefined): - `buffer' is the compiled pattern; - `syntax' is set to SYNTAX; - `used' is set to the length of the compiled pattern; - `fastmap_accurate' is zero; - `re_nsub' is the number of subexpressions in PATTERN; - `not_bol' and `not_eol' are zero; - - The `fastmap' and `newline_anchor' fields are neither - examined nor set. */ - -/* Return, freeing storage we allocated. */ -#define FREE_STACK_RETURN(value) \ - return (free (compile_stack.stack), value) - -static reg_errcode_t -regex_compile (pattern, size, syntax, bufp) - const char *pattern; - size_t size; - reg_syntax_t syntax; - struct re_pattern_buffer *bufp; -{ - /* We fetch characters from PATTERN here. Even though PATTERN is - `char *' (i.e., signed), we declare these variables as unsigned, so - they can be reliably used as array indices. */ - register unsigned char c, c1; - - /* A random temporary spot in PATTERN. */ - const char *p1; - - /* Points to the end of the buffer, where we should append. */ - register unsigned char *b; - - /* Keeps track of unclosed groups. */ - compile_stack_type compile_stack; - - /* Points to the current (ending) position in the pattern. */ - const char *p = pattern; - const char *pend = pattern + size; - - /* How to translate the characters in the pattern. */ - RE_TRANSLATE_TYPE translate = bufp->translate; - - /* Address of the count-byte of the most recently inserted `exactn' - command. This makes it possible to tell if a new exact-match - character can be added to that command or if the character requires - a new `exactn' command. */ - unsigned char *pending_exact = 0; - - /* Address of start of the most recently finished expression. - This tells, e.g., postfix * where to find the start of its - operand. Reset at the beginning of groups and alternatives. */ - unsigned char *laststart = 0; - - /* Address of beginning of regexp, or inside of last group. */ - unsigned char *begalt; - - /* Place in the uncompiled pattern (i.e., the {) to - which to go back if the interval is invalid. */ - const char *beg_interval; - - /* Address of the place where a forward jump should go to the end of - the containing expression. Each alternative of an `or' -- except the - last -- ends with a forward jump of this sort. */ - unsigned char *fixup_alt_jump = 0; - - /* Counts open-groups as they are encountered. Remembered for the - matching close-group on the compile stack, so the same register - number is put in the stop_memory as the start_memory. */ - regnum_t regnum = 0; - -#ifdef DEBUG - DEBUG_PRINT1 ("\nCompiling pattern: "); - if (debug) - { - unsigned debug_count; - - for (debug_count = 0; debug_count < size; debug_count++) - putchar (pattern[debug_count]); - putchar ('\n'); - } -#endif /* DEBUG */ - - /* Initialize the compile stack. */ - compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); - if (compile_stack.stack == NULL) - return REG_ESPACE; - - compile_stack.size = INIT_COMPILE_STACK_SIZE; - compile_stack.avail = 0; - - /* Initialize the pattern buffer. */ - bufp->syntax = syntax; - bufp->fastmap_accurate = 0; - bufp->not_bol = bufp->not_eol = 0; - - /* Set `used' to zero, so that if we return an error, the pattern - printer (for debugging) will think there's no pattern. We reset it - at the end. */ - bufp->used = 0; - - /* Always count groups, whether or not bufp->no_sub is set. */ - bufp->re_nsub = 0; - -#if !defined emacs && !defined SYNTAX_TABLE - /* Initialize the syntax table. */ - init_syntax_once (); -#endif - - if (bufp->allocated == 0) - { - if (bufp->buffer) - { /* If zero allocated, but buffer is non-null, try to realloc - enough space. This loses if buffer's address is bogus, but - that is the user's responsibility. */ - RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); - } - else - { /* Caller did not allocate a buffer. Do it for them. */ - bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); - } - if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE); - - bufp->allocated = INIT_BUF_SIZE; - } - - begalt = b = bufp->buffer; - - /* Loop through the uncompiled pattern until we're at the end. */ - while (p != pend) - { - PATFETCH (c); - - switch (c) - { - case '^': - { - if ( /* If at start of pattern, it's an operator. */ - p == pattern + 1 - /* If context independent, it's an operator. */ - || syntax & RE_CONTEXT_INDEP_ANCHORS - /* Otherwise, depends on what's come before. */ - || at_begline_loc_p (pattern, p, syntax)) - BUF_PUSH (begline); - else - goto normal_char; - } - break; - - - case '$': - { - if ( /* If at end of pattern, it's an operator. */ - p == pend - /* If context independent, it's an operator. */ - || syntax & RE_CONTEXT_INDEP_ANCHORS - /* Otherwise, depends on what's next. */ - || at_endline_loc_p (p, pend, syntax)) - BUF_PUSH (endline); - else - goto normal_char; - } - break; - - - case '+': - case '?': - if ((syntax & RE_BK_PLUS_QM) - || (syntax & RE_LIMITED_OPS)) - goto normal_char; - handle_plus: - case '*': - /* If there is no previous pattern... */ - if (!laststart) - { - if (syntax & RE_CONTEXT_INVALID_OPS) - FREE_STACK_RETURN (REG_BADRPT); - else if (!(syntax & RE_CONTEXT_INDEP_OPS)) - goto normal_char; - } - - { - /* Are we optimizing this jump? */ - boolean keep_string_p = false; - - /* 1 means zero (many) matches is allowed. */ - char zero_times_ok = 0, many_times_ok = 0; - - /* If there is a sequence of repetition chars, collapse it - down to just one (the right one). We can't combine - interval operators with these because of, e.g., `a{2}*', - which should only match an even number of `a's. */ - - for (;;) - { - zero_times_ok |= c != '+'; - many_times_ok |= c != '?'; - - if (p == pend) - break; - - PATFETCH (c); - - if (c == '*' - || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) - ; - - else if (syntax & RE_BK_PLUS_QM && c == '\\') - { - if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); - - PATFETCH (c1); - if (!(c1 == '+' || c1 == '?')) - { - PATUNFETCH; - PATUNFETCH; - break; - } - - c = c1; - } - else - { - PATUNFETCH; - break; - } - - /* If we get here, we found another repeat character. */ - } - - /* Star, etc. applied to an empty pattern is equivalent - to an empty pattern. */ - if (!laststart) - break; - - /* Now we know whether or not zero matches is allowed - and also whether or not two or more matches is allowed. */ - if (many_times_ok) - { /* More than one repetition is allowed, so put in at the - end a backward relative jump from `b' to before the next - jump we're going to put in below (which jumps from - laststart to after this jump). - - But if we are at the `*' in the exact sequence `.*\n', - insert an unconditional jump backwards to the ., - instead of the beginning of the loop. This way we only - push a failure point once, instead of every time - through the loop. */ - assert (p - 1 > pattern); - - /* Allocate the space for the jump. */ - GET_BUFFER_SPACE (3); - - /* We know we are not at the first character of the pattern, - because laststart was nonzero. And we've already - incremented `p', by the way, to be the character after - the `*'. Do we have to do something analogous here - for null bytes, because of RE_DOT_NOT_NULL? */ - if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') - && zero_times_ok - && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') - && !(syntax & RE_DOT_NEWLINE)) - { /* We have .*\n. */ - STORE_JUMP (jump, b, laststart); - keep_string_p = true; - } - else - /* Anything else. */ - STORE_JUMP (maybe_pop_jump, b, laststart - 3); - - /* We've added more stuff to the buffer. */ - b += 3; - } - - /* On failure, jump from laststart to b + 3, which will be the - end of the buffer after this jump is inserted. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump - : on_failure_jump, - laststart, b + 3); - pending_exact = 0; - b += 3; - - if (!zero_times_ok) - { - /* At least one repetition is required, so insert a - `dummy_failure_jump' before the initial - `on_failure_jump' instruction of the loop. This - effects a skip over that instruction the first time - we hit that loop. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); - b += 3; - } - } - break; - - - case '.': - laststart = b; - BUF_PUSH (anychar); - break; - - - case '[': - { - boolean had_char_class = false; - - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - /* Ensure that we have enough space to push a charset: the - opcode, the length count, and the bitset; 34 bytes in all. */ - GET_BUFFER_SPACE (34); - - laststart = b; - - /* We test `*p == '^' twice, instead of using an if - statement, so we only need one BUF_PUSH. */ - BUF_PUSH (*p == '^' ? charset_not : charset); - if (*p == '^') - p++; - - /* Remember the first position in the bracket expression. */ - p1 = p; - - /* Push the number of bytes in the bitmap. */ - BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); - - /* Clear the whole map. */ - bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); - - /* charset_not matches newline according to a syntax bit. */ - if ((re_opcode_t) b[-2] == charset_not - && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) - SET_LIST_BIT ('\n'); - - /* Read in characters and ranges, setting map bits. */ - for (;;) - { - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - PATFETCH (c); - - /* \ might escape characters inside [...] and [^...]. */ - if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') - { - if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); - - PATFETCH (c1); - SET_LIST_BIT (c1); - continue; - } - - /* Could be the end of the bracket expression. If it's - not (i.e., when the bracket expression is `[]' so - far), the ']' character bit gets set way below. */ - if (c == ']' && p != p1 + 1) - break; - - /* Look ahead to see if it's a range when the last thing - was a character class. */ - if (had_char_class && c == '-' && *p != ']') - FREE_STACK_RETURN (REG_ERANGE); - - /* Look ahead to see if it's a range when the last thing - was a character: if this is a hyphen not at the - beginning or the end of a list, then it's the range - operator. */ - if (c == '-' - && !(p - 2 >= pattern && p[-2] == '[') - && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') - && *p != ']') - { - reg_errcode_t ret - = compile_range (&p, pend, translate, syntax, b); - if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); - } - - else if (p[0] == '-' && p[1] != ']') - { /* This handles ranges made up of characters only. */ - reg_errcode_t ret; - - /* Move past the `-'. */ - PATFETCH (c1); - - ret = compile_range (&p, pend, translate, syntax, b); - if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); - } - - /* See if we're at the beginning of a possible character - class. */ - - else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') - { /* Leave room for the null. */ - char str[CHAR_CLASS_MAX_LENGTH + 1]; - - PATFETCH (c); - c1 = 0; - - /* If pattern is `[[:'. */ - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - for (;;) - { - PATFETCH (c); - if ((c == ':' && *p == ']') || p == pend - || c1 == CHAR_CLASS_MAX_LENGTH) - break; - str[c1++] = c; - } - str[c1] = '\0'; - - /* If isn't a word bracketed by `[:' and `:]': - undo the ending character, the letters, and leave - the leading `:' and `[' (but set bits for them). */ - if (c == ':' && *p == ']') - { -/* CYGNUS LOCAL: Skip this code if we don't have btowc(). btowc() is */ -/* defined in the 1994 Amendment 1 to ISO C and may not be present on */ -/* systems where we have wchar.h and wctype.h. */ -#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_BTOWC) - boolean is_lower = STREQ (str, "lower"); - boolean is_upper = STREQ (str, "upper"); - wctype_t wt; - int ch; - - wt = IS_CHAR_CLASS (str); - if (wt == 0) - FREE_STACK_RETURN (REG_ECTYPE); - - /* Throw away the ] at the end of the character - class. */ - PATFETCH (c); - - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - for (ch = 0; ch < 1 << BYTEWIDTH; ++ch) - { -# ifdef _LIBC - if (__iswctype (__btowc (ch), wt)) - SET_LIST_BIT (ch); -#else - if (iswctype (btowc (ch), wt)) - SET_LIST_BIT (ch); -#endif - - if (translate && (is_upper || is_lower) - && (ISUPPER (ch) || ISLOWER (ch))) - SET_LIST_BIT (ch); - } - - had_char_class = true; -#else - int ch; - boolean is_alnum = STREQ (str, "alnum"); - boolean is_alpha = STREQ (str, "alpha"); - boolean is_blank = STREQ (str, "blank"); - boolean is_cntrl = STREQ (str, "cntrl"); - boolean is_digit = STREQ (str, "digit"); - boolean is_graph = STREQ (str, "graph"); - boolean is_lower = STREQ (str, "lower"); - boolean is_print = STREQ (str, "print"); - boolean is_punct = STREQ (str, "punct"); - boolean is_space = STREQ (str, "space"); - boolean is_upper = STREQ (str, "upper"); - boolean is_xdigit = STREQ (str, "xdigit"); - - if (!IS_CHAR_CLASS (str)) - FREE_STACK_RETURN (REG_ECTYPE); - - /* Throw away the ] at the end of the character - class. */ - PATFETCH (c); - - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - for (ch = 0; ch < 1 << BYTEWIDTH; ch++) - { - /* This was split into 3 if's to - avoid an arbitrary limit in some compiler. */ - if ( (is_alnum && ISALNUM (ch)) - || (is_alpha && ISALPHA (ch)) - || (is_blank && ISBLANK (ch)) - || (is_cntrl && ISCNTRL (ch))) - SET_LIST_BIT (ch); - if ( (is_digit && ISDIGIT (ch)) - || (is_graph && ISGRAPH (ch)) - || (is_lower && ISLOWER (ch)) - || (is_print && ISPRINT (ch))) - SET_LIST_BIT (ch); - if ( (is_punct && ISPUNCT (ch)) - || (is_space && ISSPACE (ch)) - || (is_upper && ISUPPER (ch)) - || (is_xdigit && ISXDIGIT (ch))) - SET_LIST_BIT (ch); - if ( translate && (is_upper || is_lower) - && (ISUPPER (ch) || ISLOWER (ch))) - SET_LIST_BIT (ch); - } - had_char_class = true; -#endif /* libc || wctype.h */ - } - else - { - c1++; - while (c1--) - PATUNFETCH; - SET_LIST_BIT ('['); - SET_LIST_BIT (':'); - had_char_class = false; - } - } - else - { - had_char_class = false; - SET_LIST_BIT (c); - } - } - - /* Discard any (non)matching list bytes that are all 0 at the - end of the map. Decrease the map-length byte too. */ - while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) - b[-1]--; - b += b[-1]; - } - break; - - - case '(': - if (syntax & RE_NO_BK_PARENS) - goto handle_open; - else - goto normal_char; - - - case ')': - if (syntax & RE_NO_BK_PARENS) - goto handle_close; - else - goto normal_char; - - - case '\n': - if (syntax & RE_NEWLINE_ALT) - goto handle_alt; - else - goto normal_char; - - - case '|': - if (syntax & RE_NO_BK_VBAR) - goto handle_alt; - else - goto normal_char; - - - case '{': - if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) - goto handle_interval; - else - goto normal_char; - - - case '\\': - if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); - - /* Do not translate the character after the \, so that we can - distinguish, e.g., \B from \b, even if we normally would - translate, e.g., B to b. */ - PATFETCH_RAW (c); - - switch (c) - { - case '(': - if (syntax & RE_NO_BK_PARENS) - goto normal_backslash; - - handle_open: - bufp->re_nsub++; - regnum++; - - if (COMPILE_STACK_FULL) - { - RETALLOC (compile_stack.stack, compile_stack.size << 1, - compile_stack_elt_t); - if (compile_stack.stack == NULL) return REG_ESPACE; - - compile_stack.size <<= 1; - } - - /* These are the values to restore when we hit end of this - group. They are all relative offsets, so that if the - whole pattern moves because of realloc, they will still - be valid. */ - COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; - COMPILE_STACK_TOP.fixup_alt_jump - = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; - COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; - COMPILE_STACK_TOP.regnum = regnum; - - /* We will eventually replace the 0 with the number of - groups inner to this one. But do not push a - start_memory for groups beyond the last one we can - represent in the compiled pattern. */ - if (regnum <= MAX_REGNUM) - { - COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; - BUF_PUSH_3 (start_memory, regnum, 0); - } - - compile_stack.avail++; - - fixup_alt_jump = 0; - laststart = 0; - begalt = b; - /* If we've reached MAX_REGNUM groups, then this open - won't actually generate any code, so we'll have to - clear pending_exact explicitly. */ - pending_exact = 0; - break; - - - case ')': - if (syntax & RE_NO_BK_PARENS) goto normal_backslash; - - if (COMPILE_STACK_EMPTY) - { - if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) - goto normal_backslash; - else - FREE_STACK_RETURN (REG_ERPAREN); - } - - handle_close: - if (fixup_alt_jump) - { /* Push a dummy failure point at the end of the - alternative for a possible future - `pop_failure_jump' to pop. See comments at - `push_dummy_failure' in `re_match_2'. */ - BUF_PUSH (push_dummy_failure); - - /* We allocated space for this jump when we assigned - to `fixup_alt_jump', in the `handle_alt' case below. */ - STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); - } - - /* See similar code for backslashed left paren above. */ - if (COMPILE_STACK_EMPTY) - { - if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) - goto normal_char; - else - FREE_STACK_RETURN (REG_ERPAREN); - } - - /* Since we just checked for an empty stack above, this - ``can't happen''. */ - assert (compile_stack.avail != 0); - { - /* We don't just want to restore into `regnum', because - later groups should continue to be numbered higher, - as in `(ab)c(de)' -- the second group is #2. */ - regnum_t this_group_regnum; - - compile_stack.avail--; - begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; - fixup_alt_jump - = COMPILE_STACK_TOP.fixup_alt_jump - ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 - : 0; - laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; - this_group_regnum = COMPILE_STACK_TOP.regnum; - /* If we've reached MAX_REGNUM groups, then this open - won't actually generate any code, so we'll have to - clear pending_exact explicitly. */ - pending_exact = 0; - - /* We're at the end of the group, so now we know how many - groups were inside this one. */ - if (this_group_regnum <= MAX_REGNUM) - { - unsigned char *inner_group_loc - = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; - - *inner_group_loc = regnum - this_group_regnum; - BUF_PUSH_3 (stop_memory, this_group_regnum, - regnum - this_group_regnum); - } - } - break; - - - case '|': /* `\|'. */ - if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) - goto normal_backslash; - handle_alt: - if (syntax & RE_LIMITED_OPS) - goto normal_char; - - /* Insert before the previous alternative a jump which - jumps to this alternative if the former fails. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (on_failure_jump, begalt, b + 6); - pending_exact = 0; - b += 3; - - /* The alternative before this one has a jump after it - which gets executed if it gets matched. Adjust that - jump so it will jump to this alternative's analogous - jump (put in below, which in turn will jump to the next - (if any) alternative's such jump, etc.). The last such - jump jumps to the correct final destination. A picture: - _____ _____ - | | | | - | v | v - a | b | c - - If we are at `b', then fixup_alt_jump right now points to a - three-byte space after `a'. We'll put in the jump, set - fixup_alt_jump to right after `b', and leave behind three - bytes which we'll fill in when we get to after `c'. */ - - if (fixup_alt_jump) - STORE_JUMP (jump_past_alt, fixup_alt_jump, b); - - /* Mark and leave space for a jump after this alternative, - to be filled in later either by next alternative or - when know we're at the end of a series of alternatives. */ - fixup_alt_jump = b; - GET_BUFFER_SPACE (3); - b += 3; - - laststart = 0; - begalt = b; - break; - - - case '{': - /* If \{ is a literal. */ - if (!(syntax & RE_INTERVALS) - /* If we're at `\{' and it's not the open-interval - operator. */ - || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - || (p - 2 == pattern && p == pend)) - goto normal_backslash; - - handle_interval: - { - /* If got here, then the syntax allows intervals. */ - - /* At least (most) this many matches must be made. */ - int lower_bound = -1, upper_bound = -1; - - beg_interval = p - 1; - - if (p == pend) - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - FREE_STACK_RETURN (REG_EBRACE); - } - - GET_UNSIGNED_NUMBER (lower_bound); - - if (c == ',') - { - GET_UNSIGNED_NUMBER (upper_bound); - if (upper_bound < 0) upper_bound = RE_DUP_MAX; - } - else - /* Interval such as `{1}' => match exactly once. */ - upper_bound = lower_bound; - - if (lower_bound < 0 || upper_bound > RE_DUP_MAX - || lower_bound > upper_bound) - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - FREE_STACK_RETURN (REG_BADBR); - } - - if (!(syntax & RE_NO_BK_BRACES)) - { - if (c != '\\') FREE_STACK_RETURN (REG_EBRACE); - - PATFETCH (c); - } - - if (c != '}') - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - FREE_STACK_RETURN (REG_BADBR); - } - - /* We just parsed a valid interval. */ - - /* If it's invalid to have no preceding re. */ - if (!laststart) - { - if (syntax & RE_CONTEXT_INVALID_OPS) - FREE_STACK_RETURN (REG_BADRPT); - else if (syntax & RE_CONTEXT_INDEP_OPS) - laststart = b; - else - goto unfetch_interval; - } - - /* If the upper bound is zero, don't want to succeed at - all; jump from `laststart' to `b + 3', which will be - the end of the buffer after we insert the jump. */ - if (upper_bound == 0) - { - GET_BUFFER_SPACE (3); - INSERT_JUMP (jump, laststart, b + 3); - b += 3; - } - - /* Otherwise, we have a nontrivial interval. When - we're all done, the pattern will look like: - set_number_at - set_number_at - succeed_n - - jump_n - (The upper bound and `jump_n' are omitted if - `upper_bound' is 1, though.) */ - else - { /* If the upper bound is > 1, we need to insert - more at the end of the loop. */ - unsigned nbytes = 10 + (upper_bound > 1) * 10; - - GET_BUFFER_SPACE (nbytes); - - /* Initialize lower bound of the `succeed_n', even - though it will be set during matching by its - attendant `set_number_at' (inserted next), - because `re_compile_fastmap' needs to know. - Jump to the `jump_n' we might insert below. */ - INSERT_JUMP2 (succeed_n, laststart, - b + 5 + (upper_bound > 1) * 5, - lower_bound); - b += 5; - - /* Code to initialize the lower bound. Insert - before the `succeed_n'. The `5' is the last two - bytes of this `set_number_at', plus 3 bytes of - the following `succeed_n'. */ - insert_op2 (set_number_at, laststart, 5, lower_bound, b); - b += 5; - - if (upper_bound > 1) - { /* More than one repetition is allowed, so - append a backward jump to the `succeed_n' - that starts this interval. - - When we've reached this during matching, - we'll have matched the interval once, so - jump back only `upper_bound - 1' times. */ - STORE_JUMP2 (jump_n, b, laststart + 5, - upper_bound - 1); - b += 5; - - /* The location we want to set is the second - parameter of the `jump_n'; that is `b-2' as - an absolute address. `laststart' will be - the `set_number_at' we're about to insert; - `laststart+3' the number to set, the source - for the relative address. But we are - inserting into the middle of the pattern -- - so everything is getting moved up by 5. - Conclusion: (b - 2) - (laststart + 3) + 5, - i.e., b - laststart. - - We insert this at the beginning of the loop - so that if we fail during matching, we'll - reinitialize the bounds. */ - insert_op2 (set_number_at, laststart, b - laststart, - upper_bound - 1, b); - b += 5; - } - } - pending_exact = 0; - beg_interval = NULL; - } - break; - - unfetch_interval: - /* If an invalid interval, match the characters as literals. */ - assert (beg_interval); - p = beg_interval; - beg_interval = NULL; - - /* normal_char and normal_backslash need `c'. */ - PATFETCH (c); - - if (!(syntax & RE_NO_BK_BRACES)) - { - if (p > pattern && p[-1] == '\\') - goto normal_backslash; - } - goto normal_char; - -#ifdef emacs - /* There is no way to specify the before_dot and after_dot - operators. rms says this is ok. --karl */ - case '=': - BUF_PUSH (at_dot); - break; - - case 's': - laststart = b; - PATFETCH (c); - BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); - break; - - case 'S': - laststart = b; - PATFETCH (c); - BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); - break; -#endif /* emacs */ - - - case 'w': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - laststart = b; - BUF_PUSH (wordchar); - break; - - - case 'W': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - laststart = b; - BUF_PUSH (notwordchar); - break; - - - case '<': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - BUF_PUSH (wordbeg); - break; - - case '>': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - BUF_PUSH (wordend); - break; - - case 'b': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - BUF_PUSH (wordbound); - break; - - case 'B': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - BUF_PUSH (notwordbound); - break; - - case '`': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - BUF_PUSH (begbuf); - break; - - case '\'': - if (syntax & RE_NO_GNU_OPS) - goto normal_char; - BUF_PUSH (endbuf); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - if (syntax & RE_NO_BK_REFS) - goto normal_char; - - c1 = c - '0'; - - if (c1 > regnum) - FREE_STACK_RETURN (REG_ESUBREG); - - /* Can't back reference to a subexpression if inside of it. */ - if (group_in_compile_stack (compile_stack, (regnum_t) c1)) - goto normal_char; - - laststart = b; - BUF_PUSH_2 (duplicate, c1); - break; - - - case '+': - case '?': - if (syntax & RE_BK_PLUS_QM) - goto handle_plus; - else - goto normal_backslash; - - default: - normal_backslash: - /* You might think it would be useful for \ to mean - not to translate; but if we don't translate it - it will never match anything. */ - c = TRANSLATE (c); - goto normal_char; - } - break; - - - default: - /* Expects the character in `c'. */ - normal_char: - /* If no exactn currently being built. */ - if (!pending_exact - - /* If last exactn not at current position. */ - || pending_exact + *pending_exact + 1 != b - - /* We have only one byte following the exactn for the count. */ - || *pending_exact == (1 << BYTEWIDTH) - 1 - - /* If followed by a repetition operator. */ - || *p == '*' || *p == '^' - || ((syntax & RE_BK_PLUS_QM) - ? *p == '\\' && (p[1] == '+' || p[1] == '?') - : (*p == '+' || *p == '?')) - || ((syntax & RE_INTERVALS) - && ((syntax & RE_NO_BK_BRACES) - ? *p == '{' - : (p[0] == '\\' && p[1] == '{')))) - { - /* Start building a new exactn. */ - - laststart = b; - - BUF_PUSH_2 (exactn, 0); - pending_exact = b - 1; - } - - BUF_PUSH (c); - (*pending_exact)++; - break; - } /* switch (c) */ - } /* while p != pend */ - - - /* Through the pattern now. */ - - if (fixup_alt_jump) - STORE_JUMP (jump_past_alt, fixup_alt_jump, b); - - if (!COMPILE_STACK_EMPTY) - FREE_STACK_RETURN (REG_EPAREN); - - /* If we don't want backtracking, force success - the first time we reach the end of the compiled pattern. */ - if (syntax & RE_NO_POSIX_BACKTRACKING) - BUF_PUSH (succeed); - - free (compile_stack.stack); - - /* We have succeeded; set the length of the buffer. */ - bufp->used = b - bufp->buffer; - -#ifdef DEBUG - if (debug) - { - DEBUG_PRINT1 ("\nCompiled pattern: \n"); - print_compiled_pattern (bufp); - } -#endif /* DEBUG */ - -#ifndef MATCH_MAY_ALLOCATE - /* Initialize the failure stack to the largest possible stack. This - isn't necessary unless we're trying to avoid calling alloca in - the search and match routines. */ - { - int num_regs = bufp->re_nsub + 1; - - /* Since DOUBLE_FAIL_STACK refuses to double only if the current size - is strictly greater than re_max_failures, the largest possible stack - is 2 * re_max_failures failure points. */ - if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS)) - { - fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS); - -# ifdef emacs - if (! fail_stack.stack) - fail_stack.stack - = (fail_stack_elt_t *) xmalloc (fail_stack.size - * sizeof (fail_stack_elt_t)); - else - fail_stack.stack - = (fail_stack_elt_t *) xrealloc (fail_stack.stack, - (fail_stack.size - * sizeof (fail_stack_elt_t))); -# else /* not emacs */ - if (! fail_stack.stack) - fail_stack.stack - = (fail_stack_elt_t *) malloc (fail_stack.size - * sizeof (fail_stack_elt_t)); - else - fail_stack.stack - = (fail_stack_elt_t *) realloc (fail_stack.stack, - (fail_stack.size - * sizeof (fail_stack_elt_t))); -# endif /* not emacs */ - } - - regex_grow_registers (num_regs); - } -#endif /* not MATCH_MAY_ALLOCATE */ - - return REG_NOERROR; -} /* regex_compile */ - -/* Subroutines for `regex_compile'. */ - -/* Store OP at LOC followed by two-byte integer parameter ARG. */ - -static void -store_op1 (op, loc, arg) - re_opcode_t op; - unsigned char *loc; - int arg; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg); -} - - -/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -store_op2 (op, loc, arg1, arg2) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg1); - STORE_NUMBER (loc + 3, arg2); -} - - -/* Copy the bytes from LOC to END to open up three bytes of space at LOC - for OP followed by two-byte integer parameter ARG. */ - -static void -insert_op1 (op, loc, arg, end) - re_opcode_t op; - unsigned char *loc; - int arg; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 3; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op1 (op, loc, arg); -} - - -/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -insert_op2 (op, loc, arg1, arg2, end) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 5; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op2 (op, loc, arg1, arg2); -} - - -/* P points to just after a ^ in PATTERN. Return true if that ^ comes - after an alternative or a begin-subexpression. We assume there is at - least one character before the ^. */ - -static boolean -at_begline_loc_p (pattern, p, syntax) - const char *pattern, *p; - reg_syntax_t syntax; -{ - const char *prev = p - 2; - boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; - - return - /* After a subexpression? */ - (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) - /* After an alternative? */ - || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); -} - - -/* The dual of at_begline_loc_p. This one is for $. We assume there is - at least one character after the $, i.e., `P < PEND'. */ - -static boolean -at_endline_loc_p (p, pend, syntax) - const char *p, *pend; - reg_syntax_t syntax; -{ - const char *next = p; - boolean next_backslash = *next == '\\'; - const char *next_next = p + 1 < pend ? p + 1 : 0; - - return - /* Before a subexpression? */ - (syntax & RE_NO_BK_PARENS ? *next == ')' - : next_backslash && next_next && *next_next == ')') - /* Before an alternative? */ - || (syntax & RE_NO_BK_VBAR ? *next == '|' - : next_backslash && next_next && *next_next == '|'); -} - - -/* Returns true if REGNUM is in one of COMPILE_STACK's elements and - false if it's not. */ - -static boolean -group_in_compile_stack (compile_stack, regnum) - compile_stack_type compile_stack; - regnum_t regnum; -{ - int this_element; - - for (this_element = compile_stack.avail - 1; - this_element >= 0; - this_element--) - if (compile_stack.stack[this_element].regnum == regnum) - return true; - - return false; -} - - -/* Read the ending character of a range (in a bracket expression) from the - uncompiled pattern *P_PTR (which ends at PEND). We assume the - starting character is in `P[-2]'. (`P[-1]' is the character `-'.) - Then we set the translation of all bits between the starting and - ending characters (inclusive) in the compiled pattern B. - - Return an error code. - - We use these short variable names so we can use the same macros as - `regex_compile' itself. */ - -static reg_errcode_t -compile_range (p_ptr, pend, translate, syntax, b) - const char **p_ptr, *pend; - RE_TRANSLATE_TYPE translate; - reg_syntax_t syntax; - unsigned char *b; -{ - unsigned this_char; - - const char *p = *p_ptr; - unsigned int range_start, range_end; - - if (p == pend) - return REG_ERANGE; - - /* Even though the pattern is a signed `char *', we need to fetch - with unsigned char *'s; if the high bit of the pattern character - is set, the range endpoints will be negative if we fetch using a - signed char *. - - We also want to fetch the endpoints without translating them; the - appropriate translation is done in the bit-setting loop below. */ - /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */ - range_start = ((const unsigned char *) p)[-2]; - range_end = ((const unsigned char *) p)[0]; - - /* Have to increment the pointer into the pattern string, so the - caller isn't still at the ending character. */ - (*p_ptr)++; - - /* If the start is after the end, the range is empty. */ - if (range_start > range_end) - return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; - - /* Here we see why `this_char' has to be larger than an `unsigned - char' -- the range is inclusive, so if `range_end' == 0xff - (assuming 8-bit characters), we would otherwise go into an infinite - loop, since all characters <= 0xff. */ - for (this_char = range_start; this_char <= range_end; this_char++) - { - SET_LIST_BIT (TRANSLATE (this_char)); - } - - return REG_NOERROR; -} - -/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in - BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible - characters can start a string that matches the pattern. This fastmap - is used by re_search to skip quickly over impossible starting points. - - The caller must supply the address of a (1 << BYTEWIDTH)-byte data - area as BUFP->fastmap. - - We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in - the pattern buffer. - - Returns 0 if we succeed, -2 if an internal error. */ - -int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; -{ - int j, k; -#ifdef MATCH_MAY_ALLOCATE - fail_stack_type fail_stack; -#endif -#ifndef REGEX_MALLOC - char *destination; -#endif - - register char *fastmap = bufp->fastmap; - unsigned char *pattern = bufp->buffer; - unsigned char *p = pattern; - register unsigned char *pend = pattern + bufp->used; - -#ifdef REL_ALLOC - /* This holds the pointer to the failure stack, when - it is allocated relocatably. */ - fail_stack_elt_t *failure_stack_ptr; -#endif - - /* Assume that each path through the pattern can be null until - proven otherwise. We set this false at the bottom of switch - statement, to which we get only if a particular path doesn't - match the empty string. */ - boolean path_can_be_null = true; - - /* We aren't doing a `succeed_n' to begin with. */ - boolean succeed_n_p = false; - - assert (fastmap != NULL && p != NULL); - - INIT_FAIL_STACK (); - bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ - bufp->fastmap_accurate = 1; /* It will be when we're done. */ - bufp->can_be_null = 0; - - while (1) - { - if (p == pend || *p == succeed) - { - /* We have reached the (effective) end of pattern. */ - if (!FAIL_STACK_EMPTY ()) - { - bufp->can_be_null |= path_can_be_null; - - /* Reset for next path. */ - path_can_be_null = true; - - p = fail_stack.stack[--fail_stack.avail].pointer; - - continue; - } - else - break; - } - - /* We should never be about to go beyond the end of the pattern. */ - assert (p < pend); - - switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) - { - - /* I guess the idea here is to simply not bother with a fastmap - if a backreference is used, since it's too hard to figure out - the fastmap for the corresponding group. Setting - `can_be_null' stops `re_search_2' from using the fastmap, so - that is all we do. */ - case duplicate: - bufp->can_be_null = 1; - goto done; - - - /* Following are the cases which match a character. These end - with `break'. */ - - case exactn: - fastmap[p[1]] = 1; - break; - - - case charset: - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) - fastmap[j] = 1; - break; - - - case charset_not: - /* Chars beyond end of map must be allowed. */ - for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) - fastmap[j] = 1; - - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) - fastmap[j] = 1; - break; - - - case wordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) == Sword) - fastmap[j] = 1; - break; - - - case notwordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) != Sword) - fastmap[j] = 1; - break; - - - case anychar: - { - int fastmap_newline = fastmap['\n']; - - /* `.' matches anything ... */ - for (j = 0; j < (1 << BYTEWIDTH); j++) - fastmap[j] = 1; - - /* ... except perhaps newline. */ - if (!(bufp->syntax & RE_DOT_NEWLINE)) - fastmap['\n'] = fastmap_newline; - - /* Return if we have already set `can_be_null'; if we have, - then the fastmap is irrelevant. Something's wrong here. */ - else if (bufp->can_be_null) - goto done; - - /* Otherwise, have to check alternative paths. */ - break; - } - -#ifdef emacs - case syntaxspec: - k = *p++; - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) == (enum syntaxcode) k) - fastmap[j] = 1; - break; - - - case notsyntaxspec: - k = *p++; - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) != (enum syntaxcode) k) - fastmap[j] = 1; - break; - - - /* All cases after this match the empty string. These end with - `continue'. */ - - - case before_dot: - case at_dot: - case after_dot: - continue; -#endif /* emacs */ - - - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: - case wordbound: - case notwordbound: - case wordbeg: - case wordend: - case push_dummy_failure: - continue; - - - case jump_n: - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case jump_past_alt: - case dummy_failure_jump: - EXTRACT_NUMBER_AND_INCR (j, p); - p += j; - if (j > 0) - continue; - - /* Jump backward implies we just went through the body of a - loop and matched nothing. Opcode jumped to should be - `on_failure_jump' or `succeed_n'. Just treat it like an - ordinary jump. For a * loop, it has pushed its failure - point already; if so, discard that as redundant. */ - if ((re_opcode_t) *p != on_failure_jump - && (re_opcode_t) *p != succeed_n) - continue; - - p++; - EXTRACT_NUMBER_AND_INCR (j, p); - p += j; - - /* If what's on the stack is where we are now, pop it. */ - if (!FAIL_STACK_EMPTY () - && fail_stack.stack[fail_stack.avail - 1].pointer == p) - fail_stack.avail--; - - continue; - - - case on_failure_jump: - case on_failure_keep_string_jump: - handle_on_failure_jump: - EXTRACT_NUMBER_AND_INCR (j, p); - - /* For some patterns, e.g., `(a?)?', `p+j' here points to the - end of the pattern. We don't want to push such a point, - since when we restore it above, entering the switch will - increment `p' past the end of the pattern. We don't need - to push such a point since we obviously won't find any more - fastmap entries beyond `pend'. Such a pattern can match - the null string, though. */ - if (p + j < pend) - { - if (!PUSH_PATTERN_OP (p + j, fail_stack)) - { - RESET_FAIL_STACK (); - return -2; - } - } - else - bufp->can_be_null = 1; - - if (succeed_n_p) - { - EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ - succeed_n_p = false; - } - - continue; - - - case succeed_n: - /* Get to the number of times to succeed. */ - p += 2; - - /* Increment p past the n for when k != 0. */ - EXTRACT_NUMBER_AND_INCR (k, p); - if (k == 0) - { - p -= 4; - succeed_n_p = true; /* Spaghetti code alert. */ - goto handle_on_failure_jump; - } - continue; - - - case set_number_at: - p += 4; - continue; - - - case start_memory: - case stop_memory: - p += 2; - continue; - - - default: - abort (); /* We have listed all the cases. */ - } /* switch *p++ */ - - /* Getting here means we have found the possible starting - characters for one path of the pattern -- and that the empty - string does not match. We need not follow this path further. - Instead, look at the next alternative (remembered on the - stack), or quit if no more. The test at the top of the loop - does these things. */ - path_can_be_null = false; - p = pend; - } /* while p */ - - /* Set `can_be_null' for the last path (also the first path, if the - pattern is empty). */ - bufp->can_be_null |= path_can_be_null; - - done: - RESET_FAIL_STACK (); - return 0; -} /* re_compile_fastmap */ -#ifdef _LIBC -weak_alias (__re_compile_fastmap, re_compile_fastmap) -#endif - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use - this memory for recording register information. STARTS and ENDS - must be allocated using the malloc library routine, and must each - be at least NUM_REGS * sizeof (regoff_t) bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ - -void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - unsigned num_regs; - regoff_t *starts, *ends; -{ - if (num_regs) - { - bufp->regs_allocated = REGS_REALLOCATE; - regs->num_regs = num_regs; - regs->start = starts; - regs->end = ends; - } - else - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; - regs->start = regs->end = (regoff_t *) 0; - } -} -#ifdef _LIBC -weak_alias (__re_set_registers, re_set_registers) -#endif - -/* Searching routines. */ - -/* Like re_search_2, below, but only one string is specified, and - doesn't let you say where to stop matching. */ - -int -re_search (bufp, string, size, startpos, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, startpos, range; - struct re_registers *regs; -{ - return re_search_2 (bufp, NULL, 0, string, size, startpos, range, - regs, size); -} -#ifdef _LIBC -weak_alias (__re_search, re_search) -#endif - - -/* Using the compiled pattern in BUFP->buffer, first tries to match the - virtual concatenation of STRING1 and STRING2, starting first at index - STARTPOS, then at STARTPOS + 1, and so on. - - STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. - - RANGE is how far to scan while trying to match. RANGE = 0 means try - only at STARTPOS; in general, the last start tried is STARTPOS + - RANGE. - - In REGS, return the indices of the virtual concatenation of STRING1 - and STRING2 that matched the entire BUFP->buffer and its contained - subexpressions. - - Do not consider matching one past the index STOP in the virtual - concatenation of STRING1 and STRING2. - - We return either the position in the strings at which the match was - found, -1 if no match, or -2 if error (such as failure - stack overflow). */ - -int -re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int startpos; - int range; - struct re_registers *regs; - int stop; -{ - int val; - register char *fastmap = bufp->fastmap; - register RE_TRANSLATE_TYPE translate = bufp->translate; - int total_size = size1 + size2; - int endpos = startpos + range; - - /* Check for out-of-range STARTPOS. */ - if (startpos < 0 || startpos > total_size) - return -1; - - /* Fix up RANGE if it might eventually take us outside - the virtual concatenation of STRING1 and STRING2. - Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */ - if (endpos < 0) - range = 0 - startpos; - else if (endpos > total_size) - range = total_size - startpos; - - /* If the search isn't to be a backwards one, don't waste time in a - search for a pattern that must be anchored. */ - if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0) - { - if (startpos > 0) - return -1; - else - range = 1; - } - -#ifdef emacs - /* In a forward search for something that starts with \=. - don't keep searching past point. */ - if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0) - { - range = PT - startpos; - if (range <= 0) - return -1; - } -#endif /* emacs */ - - /* Update the fastmap now if not correct already. */ - if (fastmap && !bufp->fastmap_accurate) - if (re_compile_fastmap (bufp) == -2) - return -2; - - /* Loop through the string, looking for a place to start matching. */ - for (;;) - { - /* If a fastmap is supplied, skip quickly over characters that - cannot be the start of a match. If the pattern can match the - null string, however, we don't need to skip characters; we want - the first null string. */ - if (fastmap && startpos < total_size && !bufp->can_be_null) - { - if (range > 0) /* Searching forwards. */ - { - register const char *d; - register int lim = 0; - int irange = range; - - if (startpos < size1 && startpos + range >= size1) - lim = range - (size1 - startpos); - - d = (startpos >= size1 ? string2 - size1 : string1) + startpos; - - /* Written out as an if-else to avoid testing `translate' - inside the loop. */ - if (translate) - while (range > lim - && !fastmap[(unsigned char) - translate[(unsigned char) *d++]]) - range--; - else - while (range > lim && !fastmap[(unsigned char) *d++]) - range--; - - startpos += irange - range; - } - else /* Searching backwards. */ - { - register char c = (size1 == 0 || startpos >= size1 - ? string2[startpos - size1] - : string1[startpos]); - - if (!fastmap[(unsigned char) TRANSLATE (c)]) - goto advance; - } - } - - /* If can't match the null string, and that's all we have left, fail. */ - if (range >= 0 && startpos == total_size && fastmap - && !bufp->can_be_null) - return -1; - - val = re_match_2_internal (bufp, string1, size1, string2, size2, - startpos, regs, stop); -#ifndef REGEX_MALLOC -# ifdef C_ALLOCA - alloca (0); -# endif -#endif - - if (val >= 0) - return startpos; - - if (val == -2) - return -2; - - advance: - if (!range) - break; - else if (range > 0) - { - range--; - startpos++; - } - else - { - range++; - startpos--; - } - } - return -1; -} /* re_search_2 */ -#ifdef _LIBC -weak_alias (__re_search_2, re_search_2) -#endif - -/* This converts PTR, a pointer into one of the search strings `string1' - and `string2' into an offset from the beginning of that string. */ -#define POINTER_TO_OFFSET(ptr) \ - (FIRST_STRING_P (ptr) \ - ? ((regoff_t) ((ptr) - string1)) \ - : ((regoff_t) ((ptr) - string2 + size1))) - -/* Macros for dealing with the split strings in re_match_2. */ - -#define MATCHING_IN_FIRST_STRING (dend == end_match_1) - -/* Call before fetching a character with *d. This switches over to - string2 if necessary. */ -#define PREFETCH() \ - while (d == dend) \ - { \ - /* End of string2 => fail. */ \ - if (dend == end_match_2) \ - goto fail; \ - /* End of string1 => advance to string2. */ \ - d = string2; \ - dend = end_match_2; \ - } - - -/* Test if at very beginning or at very end of the virtual concatenation - of `string1' and `string2'. If only one string, it's `string2'. */ -#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) -#define AT_STRINGS_END(d) ((d) == end2) - - -/* Test if D points to a character which is word-constituent. We have - two special cases to check for: if past the end of string1, look at - the first character in string2; and if before the beginning of - string2, look at the last character in string1. */ -#define WORDCHAR_P(d) \ - (SYNTAX ((d) == end1 ? *string2 \ - : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ - == Sword) - -/* Disabled due to a compiler bug -- see comment at case wordbound */ -#if 0 -/* Test if the character before D and the one at D differ with respect - to being word-constituent. */ -#define AT_WORD_BOUNDARY(d) \ - (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ - || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) -#endif - -/* Free everything we malloc. */ -#ifdef MATCH_MAY_ALLOCATE -# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL -# define FREE_VARIABLES() \ - do { \ - REGEX_FREE_STACK (fail_stack.stack); \ - FREE_VAR (regstart); \ - FREE_VAR (regend); \ - FREE_VAR (old_regstart); \ - FREE_VAR (old_regend); \ - FREE_VAR (best_regstart); \ - FREE_VAR (best_regend); \ - FREE_VAR (reg_info); \ - FREE_VAR (reg_dummy); \ - FREE_VAR (reg_info_dummy); \ - } while (0) -#else -# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ -#endif /* not MATCH_MAY_ALLOCATE */ - -/* These values must meet several constraints. They must not be valid - register values; since we have a limit of 255 registers (because - we use only one byte in the pattern for the register number), we can - use numbers larger than 255. They must differ by 1, because of - NUM_FAILURE_ITEMS above. And the value for the lowest register must - be larger than the value for the highest register, so we do not try - to actually save any registers when none are active. */ -#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) -#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) - -/* Matching routines. */ - -#ifndef emacs /* Emacs never uses this. */ -/* re_match is like re_match_2 except it takes only a single string. */ - -int -re_match (bufp, string, size, pos, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, pos; - struct re_registers *regs; -{ - int result = re_match_2_internal (bufp, NULL, 0, string, size, - pos, regs, size); -# ifndef REGEX_MALLOC -# ifdef C_ALLOCA - alloca (0); -# endif -# endif - return result; -} -# ifdef _LIBC -weak_alias (__re_match, re_match) -# endif -#endif /* not emacs */ - -static boolean group_match_null_string_p _RE_ARGS ((unsigned char **p, - unsigned char *end, - register_info_type *reg_info)); -static boolean alt_match_null_string_p _RE_ARGS ((unsigned char *p, - unsigned char *end, - register_info_type *reg_info)); -static boolean common_op_match_null_string_p _RE_ARGS ((unsigned char **p, - unsigned char *end, - register_info_type *reg_info)); -static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2, - int len, char *translate)); - -/* re_match_2 matches the compiled pattern in BUFP against the - the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 - and SIZE2, respectively). We start matching at POS, and stop - matching at STOP. - - If REGS is non-null and the `no_sub' field of BUFP is nonzero, we - store offsets for the substring each group matched in REGS. See the - documentation for exactly how many groups we fill. - - We return -1 if no match, -2 if an internal error (such as the - failure stack overflowing). Otherwise, we return the length of the - matched substring. */ - -int -re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int pos; - struct re_registers *regs; - int stop; -{ - int result = re_match_2_internal (bufp, string1, size1, string2, size2, - pos, regs, stop); -#ifndef REGEX_MALLOC -# ifdef C_ALLOCA - alloca (0); -# endif -#endif - return result; -} -#ifdef _LIBC -weak_alias (__re_match_2, re_match_2) -#endif - -/* This is a separate function so that we can force an alloca cleanup - afterwards. */ -static int -re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int pos; - struct re_registers *regs; - int stop; -{ - /* General temporaries. */ - int mcnt; - unsigned char *p1; - - /* Just past the end of the corresponding string. */ - const char *end1, *end2; - - /* Pointers into string1 and string2, just past the last characters in - each to consider matching. */ - const char *end_match_1, *end_match_2; - - /* Where we are in the data, and the end of the current string. */ - const char *d, *dend; - - /* Where we are in the pattern, and the end of the pattern. */ - unsigned char *p = bufp->buffer; - register unsigned char *pend = p + bufp->used; - - /* Mark the opcode just after a start_memory, so we can test for an - empty subpattern when we get to the stop_memory. */ - unsigned char *just_past_start_mem = 0; - - /* We use this to map every character in the string. */ - RE_TRANSLATE_TYPE translate = bufp->translate; - - /* Failure point stack. Each place that can handle a failure further - down the line pushes a failure point on this stack. It consists of - restart, regend, and reg_info for all registers corresponding to - the subexpressions we're currently inside, plus the number of such - registers, and, finally, two char *'s. The first char * is where - to resume scanning the pattern; the second one is where to resume - scanning the strings. If the latter is zero, the failure point is - a ``dummy''; if a failure happens and the failure point is a dummy, - it gets discarded and the next next one is tried. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ - fail_stack_type fail_stack; -#endif -#ifdef DEBUG - static unsigned failure_id = 0; - unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; -#endif - -#ifdef REL_ALLOC - /* This holds the pointer to the failure stack, when - it is allocated relocatably. */ - fail_stack_elt_t *failure_stack_ptr; -#endif - - /* We fill all the registers internally, independent of what we - return, for use in backreferences. The number here includes - an element for register zero. */ - size_t num_regs = bufp->re_nsub + 1; - - /* The currently active registers. */ - active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG; - active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG; - - /* Information on the contents of registers. These are pointers into - the input strings; they record just what was matched (on this - attempt) by a subexpression part of the pattern, that is, the - regnum-th regstart pointer points to where in the pattern we began - matching and the regnum-th regend points to right after where we - stopped matching the regnum-th subexpression. (The zeroth register - keeps track of what the whole pattern matches.) */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **regstart, **regend; -#endif - - /* If a group that's operated upon by a repetition operator fails to - match anything, then the register for its start will need to be - restored because it will have been set to wherever in the string we - are when we last see its open-group operator. Similarly for a - register's end. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **old_regstart, **old_regend; -#endif - - /* The is_active field of reg_info helps us keep track of which (possibly - nested) subexpressions we are currently in. The matched_something - field of reg_info[reg_num] helps us tell whether or not we have - matched any of the pattern so far this time through the reg_num-th - subexpression. These two fields get reset each time through any - loop their register is in. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ - register_info_type *reg_info; -#endif - - /* The following record the register info as found in the above - variables when we find a match better than any we've seen before. - This happens as we backtrack through the failure points, which in - turn happens only if we have not yet matched the entire string. */ - unsigned best_regs_set = false; -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **best_regstart, **best_regend; -#endif - - /* Logically, this is `best_regend[0]'. But we don't want to have to - allocate space for that if we're not allocating space for anything - else (see below). Also, we never need info about register 0 for - any of the other register vectors, and it seems rather a kludge to - treat `best_regend' differently than the rest. So we keep track of - the end of the best match so far in a separate variable. We - initialize this to NULL so that when we backtrack the first time - and need to test it, it's not garbage. */ - const char *match_end = NULL; - - /* This helps SET_REGS_MATCHED avoid doing redundant work. */ - int set_regs_matched_done = 0; - - /* Used when we pop values we don't care about. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **reg_dummy; - register_info_type *reg_info_dummy; -#endif - -#ifdef DEBUG - /* Counts the total number of registers pushed. */ - unsigned num_regs_pushed = 0; -#endif - - DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); - - INIT_FAIL_STACK (); - -#ifdef MATCH_MAY_ALLOCATE - /* Do not bother to initialize all the register variables if there are - no groups in the pattern, as it takes a fair amount of time. If - there are groups, we include space for register 0 (the whole - pattern), even though we never use it, since it simplifies the - array indexing. We should fix this. */ - if (bufp->re_nsub) - { - regstart = REGEX_TALLOC (num_regs, const char *); - regend = REGEX_TALLOC (num_regs, const char *); - old_regstart = REGEX_TALLOC (num_regs, const char *); - old_regend = REGEX_TALLOC (num_regs, const char *); - best_regstart = REGEX_TALLOC (num_regs, const char *); - best_regend = REGEX_TALLOC (num_regs, const char *); - reg_info = REGEX_TALLOC (num_regs, register_info_type); - reg_dummy = REGEX_TALLOC (num_regs, const char *); - reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); - - if (!(regstart && regend && old_regstart && old_regend && reg_info - && best_regstart && best_regend && reg_dummy && reg_info_dummy)) - { - FREE_VARIABLES (); - return -2; - } - } - else - { - /* We must initialize all our variables to NULL, so that - `FREE_VARIABLES' doesn't try to free them. */ - regstart = regend = old_regstart = old_regend = best_regstart - = best_regend = reg_dummy = NULL; - reg_info = reg_info_dummy = (register_info_type *) NULL; - } -#endif /* MATCH_MAY_ALLOCATE */ - - /* The starting position is bogus. */ - if (pos < 0 || pos > size1 + size2) - { - FREE_VARIABLES (); - return -1; - } - - /* Initialize subexpression text positions to -1 to mark ones that no - start_memory/stop_memory has been seen for. Also initialize the - register information struct. */ - for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) - { - regstart[mcnt] = regend[mcnt] - = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; - - REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; - IS_ACTIVE (reg_info[mcnt]) = 0; - MATCHED_SOMETHING (reg_info[mcnt]) = 0; - EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; - } - - /* We move `string1' into `string2' if the latter's empty -- but not if - `string1' is null. */ - if (size2 == 0 && string1 != NULL) - { - string2 = string1; - size2 = size1; - string1 = 0; - size1 = 0; - } - end1 = string1 + size1; - end2 = string2 + size2; - - /* Compute where to stop matching, within the two strings. */ - if (stop <= size1) - { - end_match_1 = string1 + stop; - end_match_2 = string2; - } - else - { - end_match_1 = end1; - end_match_2 = string2 + stop - size1; - } - - /* `p' scans through the pattern as `d' scans through the data. - `dend' is the end of the input string that `d' points within. `d' - is advanced into the following input string whenever necessary, but - this happens before fetching; therefore, at the beginning of the - loop, `d' can be pointing at the end of a string, but it cannot - equal `string2'. */ - if (size1 > 0 && pos <= size1) - { - d = string1 + pos; - dend = end_match_1; - } - else - { - d = string2 + pos - size1; - dend = end_match_2; - } - - DEBUG_PRINT1 ("The compiled pattern is:\n"); - DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); - DEBUG_PRINT1 ("The string to match is: `"); - DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); - DEBUG_PRINT1 ("'\n"); - - /* This loops over pattern commands. It exits by returning from the - function if the match is complete, or it drops through if the match - fails at this starting point in the input data. */ - for (;;) - { -#ifdef _LIBC - DEBUG_PRINT2 ("\n%p: ", p); -#else - DEBUG_PRINT2 ("\n0x%x: ", p); -#endif - - if (p == pend) - { /* End of pattern means we might have succeeded. */ - DEBUG_PRINT1 ("end of pattern ... "); - - /* If we haven't matched the entire string, and we want the - longest match, try backtracking. */ - if (d != end_match_2) - { - /* 1 if this match ends in the same string (string1 or string2) - as the best previous match. */ - boolean same_str_p = (FIRST_STRING_P (match_end) - == MATCHING_IN_FIRST_STRING); - /* 1 if this match is the best seen so far. */ - boolean best_match_p; - - /* AIX compiler got confused when this was combined - with the previous declaration. */ - if (same_str_p) - best_match_p = d > match_end; - else - best_match_p = !MATCHING_IN_FIRST_STRING; - - DEBUG_PRINT1 ("backtracking.\n"); - - if (!FAIL_STACK_EMPTY ()) - { /* More failure points to try. */ - - /* If exceeds best match so far, save it. */ - if (!best_regs_set || best_match_p) - { - best_regs_set = true; - match_end = d; - - DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); - - for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) - { - best_regstart[mcnt] = regstart[mcnt]; - best_regend[mcnt] = regend[mcnt]; - } - } - goto fail; - } - - /* If no failure points, don't restore garbage. And if - last match is real best match, don't restore second - best one. */ - else if (best_regs_set && !best_match_p) - { - restore_best_regs: - /* Restore best match. It may happen that `dend == - end_match_1' while the restored d is in string2. - For example, the pattern `x.*y.*z' against the - strings `x-' and `y-z-', if the two strings are - not consecutive in memory. */ - DEBUG_PRINT1 ("Restoring best registers.\n"); - - d = match_end; - dend = ((d >= string1 && d <= end1) - ? end_match_1 : end_match_2); - - for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) - { - regstart[mcnt] = best_regstart[mcnt]; - regend[mcnt] = best_regend[mcnt]; - } - } - } /* d != end_match_2 */ - - succeed_label: - DEBUG_PRINT1 ("Accepting match.\n"); - - /* If caller wants register contents data back, do it. */ - if (regs && !bufp->no_sub) - { - /* Have the register data arrays been allocated? */ - if (bufp->regs_allocated == REGS_UNALLOCATED) - { /* No. So allocate them with malloc. We need one - extra element beyond `num_regs' for the `-1' marker - GNU code uses. */ - regs->num_regs = MAX (RE_NREGS, num_regs + 1); - regs->start = TALLOC (regs->num_regs, regoff_t); - regs->end = TALLOC (regs->num_regs, regoff_t); - if (regs->start == NULL || regs->end == NULL) - { - FREE_VARIABLES (); - return -2; - } - bufp->regs_allocated = REGS_REALLOCATE; - } - else if (bufp->regs_allocated == REGS_REALLOCATE) - { /* Yes. If we need more elements than were already - allocated, reallocate them. If we need fewer, just - leave it alone. */ - if (regs->num_regs < num_regs + 1) - { - regs->num_regs = num_regs + 1; - RETALLOC (regs->start, regs->num_regs, regoff_t); - RETALLOC (regs->end, regs->num_regs, regoff_t); - if (regs->start == NULL || regs->end == NULL) - { - FREE_VARIABLES (); - return -2; - } - } - } - else - { - /* These braces fend off a "empty body in an else-statement" - warning under GCC when assert expands to nothing. */ - assert (bufp->regs_allocated == REGS_FIXED); - } - - /* Convert the pointer data in `regstart' and `regend' to - indices. Register zero has to be set differently, - since we haven't kept track of any info for it. */ - if (regs->num_regs > 0) - { - regs->start[0] = pos; - regs->end[0] = (MATCHING_IN_FIRST_STRING - ? ((regoff_t) (d - string1)) - : ((regoff_t) (d - string2 + size1))); - } - - /* Go through the first `min (num_regs, regs->num_regs)' - registers, since that is all we initialized. */ - for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs); - mcnt++) - { - if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) - regs->start[mcnt] = regs->end[mcnt] = -1; - else - { - regs->start[mcnt] - = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]); - regs->end[mcnt] - = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]); - } - } - - /* If the regs structure we return has more elements than - were in the pattern, set the extra elements to -1. If - we (re)allocated the registers, this is the case, - because we always allocate enough to have at least one - -1 at the end. */ - for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++) - regs->start[mcnt] = regs->end[mcnt] = -1; - } /* regs && !bufp->no_sub */ - - DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", - nfailure_points_pushed, nfailure_points_popped, - nfailure_points_pushed - nfailure_points_popped); - DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); - - mcnt = d - pos - (MATCHING_IN_FIRST_STRING - ? string1 - : string2 - size1); - - DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); - - FREE_VARIABLES (); - return mcnt; - } - - /* Otherwise match next pattern command. */ - switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) - { - /* Ignore these. Used to ignore the n of succeed_n's which - currently have n == 0. */ - case no_op: - DEBUG_PRINT1 ("EXECUTING no_op.\n"); - break; - - case succeed: - DEBUG_PRINT1 ("EXECUTING succeed.\n"); - goto succeed_label; - - /* Match the next n pattern characters exactly. The following - byte in the pattern defines n, and the n bytes after that - are the characters to match. */ - case exactn: - mcnt = *p++; - DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); - - /* This is written out as an if-else so we don't waste time - testing `translate' inside the loop. */ - if (translate) - { - do - { - PREFETCH (); - if ((unsigned char) translate[(unsigned char) *d++] - != (unsigned char) *p++) - goto fail; - } - while (--mcnt); - } - else - { - do - { - PREFETCH (); - if (*d++ != (char) *p++) goto fail; - } - while (--mcnt); - } - SET_REGS_MATCHED (); - break; - - - /* Match any character except possibly a newline or a null. */ - case anychar: - DEBUG_PRINT1 ("EXECUTING anychar.\n"); - - PREFETCH (); - - if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') - || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) - goto fail; - - SET_REGS_MATCHED (); - DEBUG_PRINT2 (" Matched `%d'.\n", *d); - d++; - break; - - - case charset: - case charset_not: - { - register unsigned char c; - boolean not = (re_opcode_t) *(p - 1) == charset_not; - - DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); - - PREFETCH (); - c = TRANSLATE (*d); /* The character to match. */ - - /* Cast to `unsigned' instead of `unsigned char' in case the - bit list is a full 32 bytes long. */ - if (c < (unsigned) (*p * BYTEWIDTH) - && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - - p += 1 + *p; - - if (!not) goto fail; - - SET_REGS_MATCHED (); - d++; - break; - } - - - /* The beginning of a group is represented by start_memory. - The arguments are the register number in the next byte, and the - number of groups inner to this one in the next. The text - matched within the group is recorded (in the internal - registers data structure) under the register number. */ - case start_memory: - DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); - - /* Find out if this group can match the empty string. */ - p1 = p; /* To send to group_match_null_string_p. */ - - if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) - REG_MATCH_NULL_STRING_P (reg_info[*p]) - = group_match_null_string_p (&p1, pend, reg_info); - - /* Save the position in the string where we were the last time - we were at this open-group operator in case the group is - operated upon by a repetition operator, e.g., with `(a*)*b' - against `ab'; then we want to ignore where we are now in - the string in case this attempt to match fails. */ - old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) - ? REG_UNSET (regstart[*p]) ? d : regstart[*p] - : regstart[*p]; - DEBUG_PRINT2 (" old_regstart: %d\n", - POINTER_TO_OFFSET (old_regstart[*p])); - - regstart[*p] = d; - DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); - - IS_ACTIVE (reg_info[*p]) = 1; - MATCHED_SOMETHING (reg_info[*p]) = 0; - - /* Clear this whenever we change the register activity status. */ - set_regs_matched_done = 0; - - /* This is the new highest active register. */ - highest_active_reg = *p; - - /* If nothing was active before, this is the new lowest active - register. */ - if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) - lowest_active_reg = *p; - - /* Move past the register number and inner group count. */ - p += 2; - just_past_start_mem = p; - - break; - - - /* The stop_memory opcode represents the end of a group. Its - arguments are the same as start_memory's: the register - number, and the number of inner groups. */ - case stop_memory: - DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); - - /* We need to save the string position the last time we were at - this close-group operator in case the group is operated - upon by a repetition operator, e.g., with `((a*)*(b*)*)*' - against `aba'; then we want to ignore where we are now in - the string in case this attempt to match fails. */ - old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) - ? REG_UNSET (regend[*p]) ? d : regend[*p] - : regend[*p]; - DEBUG_PRINT2 (" old_regend: %d\n", - POINTER_TO_OFFSET (old_regend[*p])); - - regend[*p] = d; - DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); - - /* This register isn't active anymore. */ - IS_ACTIVE (reg_info[*p]) = 0; - - /* Clear this whenever we change the register activity status. */ - set_regs_matched_done = 0; - - /* If this was the only register active, nothing is active - anymore. */ - if (lowest_active_reg == highest_active_reg) - { - lowest_active_reg = NO_LOWEST_ACTIVE_REG; - highest_active_reg = NO_HIGHEST_ACTIVE_REG; - } - else - { /* We must scan for the new highest active register, since - it isn't necessarily one less than now: consider - (a(b)c(d(e)f)g). When group 3 ends, after the f), the - new highest active register is 1. */ - unsigned char r = *p - 1; - while (r > 0 && !IS_ACTIVE (reg_info[r])) - r--; - - /* If we end up at register zero, that means that we saved - the registers as the result of an `on_failure_jump', not - a `start_memory', and we jumped to past the innermost - `stop_memory'. For example, in ((.)*) we save - registers 1 and 2 as a result of the *, but when we pop - back to the second ), we are at the stop_memory 1. - Thus, nothing is active. */ - if (r == 0) - { - lowest_active_reg = NO_LOWEST_ACTIVE_REG; - highest_active_reg = NO_HIGHEST_ACTIVE_REG; - } - else - highest_active_reg = r; - } - - /* If just failed to match something this time around with a - group that's operated on by a repetition operator, try to - force exit from the ``loop'', and restore the register - information for this group that we had before trying this - last match. */ - if ((!MATCHED_SOMETHING (reg_info[*p]) - || just_past_start_mem == p - 1) - && (p + 2) < pend) - { - boolean is_a_jump_n = false; - - p1 = p + 2; - mcnt = 0; - switch ((re_opcode_t) *p1++) - { - case jump_n: - is_a_jump_n = true; - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case dummy_failure_jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (is_a_jump_n) - p1 += 2; - break; - - default: - /* do nothing */ ; - } - p1 += mcnt; - - /* If the next operation is a jump backwards in the pattern - to an on_failure_jump right before the start_memory - corresponding to this stop_memory, exit from the loop - by forcing a failure after pushing on the stack the - on_failure_jump's jump in the pattern, and d. */ - if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump - && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) - { - /* If this group ever matched anything, then restore - what its registers were before trying this last - failed match, e.g., with `(a*)*b' against `ab' for - regstart[1], and, e.g., with `((a*)*(b*)*)*' - against `aba' for regend[3]. - - Also restore the registers for inner groups for, - e.g., `((a*)(b*))*' against `aba' (register 3 would - otherwise get trashed). */ - - if (EVER_MATCHED_SOMETHING (reg_info[*p])) - { - unsigned r; - - EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; - - /* Restore this and inner groups' (if any) registers. */ - for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1); - r++) - { - regstart[r] = old_regstart[r]; - - /* xx why this test? */ - if (old_regend[r] >= regstart[r]) - regend[r] = old_regend[r]; - } - } - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - PUSH_FAILURE_POINT (p1 + mcnt, d, -2); - - goto fail; - } - } - - /* Move past the register number and the inner group count. */ - p += 2; - break; - - - /* \ has been turned into a `duplicate' command which is - followed by the numeric value of as the register number. */ - case duplicate: - { - register const char *d2, *dend2; - int regno = *p++; /* Get which register to match against. */ - DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); - - /* Can't back reference a group which we've never matched. */ - if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) - goto fail; - - /* Where in input to try to start matching. */ - d2 = regstart[regno]; - - /* Where to stop matching; if both the place to start and - the place to stop matching are in the same string, then - set to the place to stop, otherwise, for now have to use - the end of the first string. */ - - dend2 = ((FIRST_STRING_P (regstart[regno]) - == FIRST_STRING_P (regend[regno])) - ? regend[regno] : end_match_1); - for (;;) - { - /* If necessary, advance to next segment in register - contents. */ - while (d2 == dend2) - { - if (dend2 == end_match_2) break; - if (dend2 == regend[regno]) break; - - /* End of string1 => advance to string2. */ - d2 = string2; - dend2 = regend[regno]; - } - /* At end of register contents => success */ - if (d2 == dend2) break; - - /* If necessary, advance to next segment in data. */ - PREFETCH (); - - /* How many characters left in this segment to match. */ - mcnt = dend - d; - - /* Want how many consecutive characters we can match in - one shot, so, if necessary, adjust the count. */ - if (mcnt > dend2 - d2) - mcnt = dend2 - d2; - - /* Compare that many; failure if mismatch, else move - past them. */ - if (translate - ? bcmp_translate (d, d2, mcnt, translate) - : memcmp (d, d2, mcnt)) - goto fail; - d += mcnt, d2 += mcnt; - - /* Do this because we've match some characters. */ - SET_REGS_MATCHED (); - } - } - break; - - - /* begline matches the empty string at the beginning of the string - (unless `not_bol' is set in `bufp'), and, if - `newline_anchor' is set, after newlines. */ - case begline: - DEBUG_PRINT1 ("EXECUTING begline.\n"); - - if (AT_STRINGS_BEG (d)) - { - if (!bufp->not_bol) break; - } - else if (d[-1] == '\n' && bufp->newline_anchor) - { - break; - } - /* In all other cases, we fail. */ - goto fail; - - - /* endline is the dual of begline. */ - case endline: - DEBUG_PRINT1 ("EXECUTING endline.\n"); - - if (AT_STRINGS_END (d)) - { - if (!bufp->not_eol) break; - } - - /* We have to ``prefetch'' the next character. */ - else if ((d == end1 ? *string2 : *d) == '\n' - && bufp->newline_anchor) - { - break; - } - goto fail; - - - /* Match at the very beginning of the data. */ - case begbuf: - DEBUG_PRINT1 ("EXECUTING begbuf.\n"); - if (AT_STRINGS_BEG (d)) - break; - goto fail; - - - /* Match at the very end of the data. */ - case endbuf: - DEBUG_PRINT1 ("EXECUTING endbuf.\n"); - if (AT_STRINGS_END (d)) - break; - goto fail; - - - /* on_failure_keep_string_jump is used to optimize `.*\n'. It - pushes NULL as the value for the string on the stack. Then - `pop_failure_point' will keep the current value for the - string, instead of restoring it. To see why, consider - matching `foo\nbar' against `.*\n'. The .* matches the foo; - then the . fails against the \n. But the next thing we want - to do is match the \n against the \n; if we restored the - string value, we would be back at the foo. - - Because this is used only in specific cases, we don't need to - check all the things that `on_failure_jump' does, to make - sure the right things get saved on the stack. Hence we don't - share its code. The only reason to push anything on the - stack at all is that otherwise we would have to change - `anychar's code to do something besides goto fail in this - case; that seems worse than this. */ - case on_failure_keep_string_jump: - DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); -#ifdef _LIBC - DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt); -#else - DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); -#endif - - PUSH_FAILURE_POINT (p + mcnt, NULL, -2); - break; - - - /* Uses of on_failure_jump: - - Each alternative starts with an on_failure_jump that points - to the beginning of the next alternative. Each alternative - except the last ends with a jump that in effect jumps past - the rest of the alternatives. (They really jump to the - ending jump of the following alternative, because tensioning - these jumps is a hassle.) - - Repeats start with an on_failure_jump that points past both - the repetition text and either the following jump or - pop_failure_jump back to this on_failure_jump. */ - case on_failure_jump: - on_failure: - DEBUG_PRINT1 ("EXECUTING on_failure_jump"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); -#ifdef _LIBC - DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt); -#else - DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); -#endif - - /* If this on_failure_jump comes right before a group (i.e., - the original * applied to a group), save the information - for that group and all inner ones, so that if we fail back - to this point, the group's information will be correct. - For example, in \(a*\)*\1, we need the preceding group, - and in \(zz\(a*\)b*\)\2, we need the inner group. */ - - /* We can't use `p' to check ahead because we push - a failure point to `p + mcnt' after we do this. */ - p1 = p; - - /* We need to skip no_op's before we look for the - start_memory in case this on_failure_jump is happening as - the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 - against aba. */ - while (p1 < pend && (re_opcode_t) *p1 == no_op) - p1++; - - if (p1 < pend && (re_opcode_t) *p1 == start_memory) - { - /* We have a new highest active register now. This will - get reset at the start_memory we are about to get to, - but we will have saved all the registers relevant to - this repetition op, as described above. */ - highest_active_reg = *(p1 + 1) + *(p1 + 2); - if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) - lowest_active_reg = *(p1 + 1); - } - - DEBUG_PRINT1 (":\n"); - PUSH_FAILURE_POINT (p + mcnt, d, -2); - break; - - - /* A smart repeat ends with `maybe_pop_jump'. - We change it to either `pop_failure_jump' or `jump'. */ - case maybe_pop_jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); - { - register unsigned char *p2 = p; - - /* Compare the beginning of the repeat with what in the - pattern follows its end. If we can establish that there - is nothing that they would both match, i.e., that we - would have to backtrack because of (as in, e.g., `a*a') - then we can change to pop_failure_jump, because we'll - never have to backtrack. - - This is not true in the case of alternatives: in - `(a|ab)*' we do need to backtrack to the `ab' alternative - (e.g., if the string was `ab'). But instead of trying to - detect that here, the alternative has put on a dummy - failure point which is what we will end up popping. */ - - /* Skip over open/close-group commands. - If what follows this loop is a ...+ construct, - look at what begins its body, since we will have to - match at least one of that. */ - while (1) - { - if (p2 + 2 < pend - && ((re_opcode_t) *p2 == stop_memory - || (re_opcode_t) *p2 == start_memory)) - p2 += 3; - else if (p2 + 6 < pend - && (re_opcode_t) *p2 == dummy_failure_jump) - p2 += 6; - else - break; - } - - p1 = p + mcnt; - /* p1[0] ... p1[2] are the `on_failure_jump' corresponding - to the `maybe_finalize_jump' of this case. Examine what - follows. */ - - /* If we're at the end of the pattern, we can change. */ - if (p2 == pend) - { - /* Consider what happens when matching ":\(.*\)" - against ":/". I don't really understand this code - yet. */ - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 - (" End of pattern: change to `pop_failure_jump'.\n"); - } - - else if ((re_opcode_t) *p2 == exactn - || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) - { - register unsigned char c - = *p2 == (unsigned char) endline ? '\n' : p2[2]; - - if ((re_opcode_t) p1[3] == exactn && p1[5] != c) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", - c, p1[5]); - } - - else if ((re_opcode_t) p1[3] == charset - || (re_opcode_t) p1[3] == charset_not) - { - int not = (re_opcode_t) p1[3] == charset_not; - - if (c < (unsigned char) (p1[4] * BYTEWIDTH) - && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - - /* `not' is equal to 1 if c would match, which means - that we can't change to pop_failure_jump. */ - if (!not) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - } - else if ((re_opcode_t) *p2 == charset) - { -#ifdef DEBUG - register unsigned char c - = *p2 == (unsigned char) endline ? '\n' : p2[2]; -#endif - -#if 0 - if ((re_opcode_t) p1[3] == exactn - && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5] - && (p2[2 + p1[5] / BYTEWIDTH] - & (1 << (p1[5] % BYTEWIDTH))))) -#else - if ((re_opcode_t) p1[3] == exactn - && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4] - && (p2[2 + p1[4] / BYTEWIDTH] - & (1 << (p1[4] % BYTEWIDTH))))) -#endif - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", - c, p1[5]); - } - - else if ((re_opcode_t) p1[3] == charset_not) - { - int idx; - /* We win if the charset_not inside the loop - lists every character listed in the charset after. */ - for (idx = 0; idx < (int) p2[1]; idx++) - if (! (p2[2 + idx] == 0 - || (idx < (int) p1[4] - && ((p2[2 + idx] & ~ p1[5 + idx]) == 0)))) - break; - - if (idx == p2[1]) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - else if ((re_opcode_t) p1[3] == charset) - { - int idx; - /* We win if the charset inside the loop - has no overlap with the one after the loop. */ - for (idx = 0; - idx < (int) p2[1] && idx < (int) p1[4]; - idx++) - if ((p2[2 + idx] & p1[5 + idx]) != 0) - break; - - if (idx == p2[1] || idx == p1[4]) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - } - } - p -= 2; /* Point at relative address again. */ - if ((re_opcode_t) p[-1] != pop_failure_jump) - { - p[-1] = (unsigned char) jump; - DEBUG_PRINT1 (" Match => jump.\n"); - goto unconditional_jump; - } - /* Note fall through. */ - - - /* The end of a simple repeat has a pop_failure_jump back to - its matching on_failure_jump, where the latter will push a - failure point. The pop_failure_jump takes off failure - points put on by this pop_failure_jump's matching - on_failure_jump; we got through the pattern to here from the - matching on_failure_jump, so didn't fail. */ - case pop_failure_jump: - { - /* We need to pass separate storage for the lowest and - highest registers, even though we don't care about the - actual values. Otherwise, we will restore only one - register from the stack, since lowest will == highest in - `pop_failure_point'. */ - active_reg_t dummy_low_reg, dummy_high_reg; - unsigned char *pdummy; - const char *sdummy; - - DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); - POP_FAILURE_POINT (sdummy, pdummy, - dummy_low_reg, dummy_high_reg, - reg_dummy, reg_dummy, reg_info_dummy); - } - /* Note fall through. */ - - unconditional_jump: -#ifdef _LIBC - DEBUG_PRINT2 ("\n%p: ", p); -#else - DEBUG_PRINT2 ("\n0x%x: ", p); -#endif - /* Note fall through. */ - - /* Unconditionally jump (without popping any failure points). */ - case jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ - DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); - p += mcnt; /* Do the jump. */ -#ifdef _LIBC - DEBUG_PRINT2 ("(to %p).\n", p); -#else - DEBUG_PRINT2 ("(to 0x%x).\n", p); -#endif - break; - - - /* We need this opcode so we can detect where alternatives end - in `group_match_null_string_p' et al. */ - case jump_past_alt: - DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); - goto unconditional_jump; - - - /* Normally, the on_failure_jump pushes a failure point, which - then gets popped at pop_failure_jump. We will end up at - pop_failure_jump, also, and with a pattern of, say, `a+', we - are skipping over the on_failure_jump, so we have to push - something meaningless for pop_failure_jump to pop. */ - case dummy_failure_jump: - DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); - /* It doesn't matter what we push for the string here. What - the code at `fail' tests is the value for the pattern. */ - PUSH_FAILURE_POINT (NULL, NULL, -2); - goto unconditional_jump; - - - /* At the end of an alternative, we need to push a dummy failure - point in case we are followed by a `pop_failure_jump', because - we don't want the failure point for the alternative to be - popped. For example, matching `(a|ab)*' against `aab' - requires that we match the `ab' alternative. */ - case push_dummy_failure: - DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); - /* See comments just above at `dummy_failure_jump' about the - two zeroes. */ - PUSH_FAILURE_POINT (NULL, NULL, -2); - break; - - /* Have to succeed matching what follows at least n times. - After that, handle like `on_failure_jump'. */ - case succeed_n: - EXTRACT_NUMBER (mcnt, p + 2); - DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); - - assert (mcnt >= 0); - /* Originally, this is how many times we HAVE to succeed. */ - if (mcnt > 0) - { - mcnt--; - p += 2; - STORE_NUMBER_AND_INCR (p, mcnt); -#ifdef _LIBC - DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt); -#else - DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - 2, mcnt); -#endif - } - else if (mcnt == 0) - { -#ifdef _LIBC - DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2); -#else - DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); -#endif - p[2] = (unsigned char) no_op; - p[3] = (unsigned char) no_op; - goto on_failure; - } - break; - - case jump_n: - EXTRACT_NUMBER (mcnt, p + 2); - DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); - - /* Originally, this is how many times we CAN jump. */ - if (mcnt) - { - mcnt--; - STORE_NUMBER (p + 2, mcnt); -#ifdef _LIBC - DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt); -#else - DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + 2, mcnt); -#endif - goto unconditional_jump; - } - /* If don't have to jump any more, skip over the rest of command. */ - else - p += 4; - break; - - case set_number_at: - { - DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); - p1 = p + mcnt; - EXTRACT_NUMBER_AND_INCR (mcnt, p); -#ifdef _LIBC - DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt); -#else - DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); -#endif - STORE_NUMBER (p1, mcnt); - break; - } - -#if 0 - /* The DEC Alpha C compiler 3.x generates incorrect code for the - test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of - AT_WORD_BOUNDARY, so this code is disabled. Expanding the - macro and introducing temporary variables works around the bug. */ - - case wordbound: - DEBUG_PRINT1 ("EXECUTING wordbound.\n"); - if (AT_WORD_BOUNDARY (d)) - break; - goto fail; - - case notwordbound: - DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); - if (AT_WORD_BOUNDARY (d)) - goto fail; - break; -#else - case wordbound: - { - boolean prevchar, thischar; - - DEBUG_PRINT1 ("EXECUTING wordbound.\n"); - if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) - break; - - prevchar = WORDCHAR_P (d - 1); - thischar = WORDCHAR_P (d); - if (prevchar != thischar) - break; - goto fail; - } - - case notwordbound: - { - boolean prevchar, thischar; - - DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); - if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) - goto fail; - - prevchar = WORDCHAR_P (d - 1); - thischar = WORDCHAR_P (d); - if (prevchar != thischar) - goto fail; - break; - } -#endif - - case wordbeg: - DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); - if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) - break; - goto fail; - - case wordend: - DEBUG_PRINT1 ("EXECUTING wordend.\n"); - if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) - && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) - break; - goto fail; - -#ifdef emacs - case before_dot: - DEBUG_PRINT1 ("EXECUTING before_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) >= point) - goto fail; - break; - - case at_dot: - DEBUG_PRINT1 ("EXECUTING at_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) != point) - goto fail; - break; - - case after_dot: - DEBUG_PRINT1 ("EXECUTING after_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) <= point) - goto fail; - break; - - case syntaxspec: - DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchsyntax; - - case wordchar: - DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); - mcnt = (int) Sword; - matchsyntax: - PREFETCH (); - /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ - d++; - if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt) - goto fail; - SET_REGS_MATCHED (); - break; - - case notsyntaxspec: - DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchnotsyntax; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); - mcnt = (int) Sword; - matchnotsyntax: - PREFETCH (); - /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ - d++; - if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt) - goto fail; - SET_REGS_MATCHED (); - break; - -#else /* not emacs */ - case wordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); - PREFETCH (); - if (!WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); - PREFETCH (); - if (WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; -#endif /* not emacs */ - - default: - abort (); - } - continue; /* Successfully executed one pattern command; keep going. */ - - - /* We goto here if a matching operation fails. */ - fail: - if (!FAIL_STACK_EMPTY ()) - { /* A restart point is known. Restore to that state. */ - DEBUG_PRINT1 ("\nFAIL:\n"); - POP_FAILURE_POINT (d, p, - lowest_active_reg, highest_active_reg, - regstart, regend, reg_info); - - /* If this failure point is a dummy, try the next one. */ - if (!p) - goto fail; - - /* If we failed to the end of the pattern, don't examine *p. */ - assert (p <= pend); - if (p < pend) - { - boolean is_a_jump_n = false; - - /* If failed to a backwards jump that's part of a repetition - loop, need to pop this failure point and use the next one. */ - switch ((re_opcode_t) *p) - { - case jump_n: - is_a_jump_n = true; - case maybe_pop_jump: - case pop_failure_jump: - case jump: - p1 = p + 1; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - - if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) - || (!is_a_jump_n - && (re_opcode_t) *p1 == on_failure_jump)) - goto fail; - break; - default: - /* do nothing */ ; - } - } - - if (d >= string1 && d <= end1) - dend = end_match_1; - } - else - break; /* Matching at this starting point really fails. */ - } /* for (;;) */ - - if (best_regs_set) - goto restore_best_regs; - - FREE_VARIABLES (); - - return -1; /* Failure to match. */ -} /* re_match_2 */ - -/* Subroutine definitions for re_match_2. */ - - -/* We are passed P pointing to a register number after a start_memory. - - Return true if the pattern up to the corresponding stop_memory can - match the empty string, and false otherwise. - - If we find the matching stop_memory, sets P to point to one past its number. - Otherwise, sets P to an undefined byte less than or equal to END. - - We don't handle duplicates properly (yet). */ - -static boolean -group_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - /* Point to after the args to the start_memory. */ - unsigned char *p1 = *p + 2; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and return true or - false, as appropriate, when we get to one that can't, or to the - matching stop_memory. */ - - switch ((re_opcode_t) *p1) - { - /* Could be either a loop or a series of alternatives. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - /* If the next operation is not a jump backwards in the - pattern. */ - - if (mcnt >= 0) - { - /* Go through the on_failure_jumps of the alternatives, - seeing if any of the alternatives cannot match nothing. - The last alternative starts with only a jump, - whereas the rest start with on_failure_jump and end - with a jump, e.g., here is the pattern for `a|b|c': - - /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 - /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 - /exactn/1/c - - So, we have to first go through the first (n-1) - alternatives and then deal with the last one separately. */ - - - /* Deal with the first (n-1) alternatives, which start - with an on_failure_jump (see above) that jumps to right - past a jump_past_alt. */ - - while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) - { - /* `mcnt' holds how many bytes long the alternative - is, including the ending `jump_past_alt' and - its number. */ - - if (!alt_match_null_string_p (p1, p1 + mcnt - 3, - reg_info)) - return false; - - /* Move to right after this alternative, including the - jump_past_alt. */ - p1 += mcnt; - - /* Break if it's the beginning of an n-th alternative - that doesn't begin with an on_failure_jump. */ - if ((re_opcode_t) *p1 != on_failure_jump) - break; - - /* Still have to check that it's not an n-th - alternative that starts with an on_failure_jump. */ - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) - { - /* Get to the beginning of the n-th alternative. */ - p1 -= 3; - break; - } - } - - /* Deal with the last alternative: go back and get number - of the `jump_past_alt' just before it. `mcnt' contains - the length of the alternative. */ - EXTRACT_NUMBER (mcnt, p1 - 2); - - if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) - return false; - - p1 += mcnt; /* Get past the n-th alternative. */ - } /* if mcnt > 0 */ - break; - - - case stop_memory: - assert (p1[1] == **p); - *p = p1 + 2; - return true; - - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return false; -} /* group_match_null_string_p */ - - -/* Similar to group_match_null_string_p, but doesn't deal with alternatives: - It expects P to be the first byte of a single alternative and END one - byte past the last. The alternative can contain groups. */ - -static boolean -alt_match_null_string_p (p, end, reg_info) - unsigned char *p, *end; - register_info_type *reg_info; -{ - int mcnt; - unsigned char *p1 = p; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and break when we get - to one that can't. */ - - switch ((re_opcode_t) *p1) - { - /* It's a loop. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - break; - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return true; -} /* alt_match_null_string_p */ - - -/* Deals with the ops common to group_match_null_string_p and - alt_match_null_string_p. - - Sets P to one after the op and its arguments, if any. */ - -static boolean -common_op_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - boolean ret; - int reg_no; - unsigned char *p1 = *p; - - switch ((re_opcode_t) *p1++) - { - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: - case wordbeg: - case wordend: - case wordbound: - case notwordbound: -#ifdef emacs - case before_dot: - case at_dot: - case after_dot: -#endif - break; - - case start_memory: - reg_no = *p1; - assert (reg_no > 0 && reg_no <= MAX_REGNUM); - ret = group_match_null_string_p (&p1, end, reg_info); - - /* Have to set this here in case we're checking a group which - contains a group and a back reference to it. */ - - if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) - REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; - - if (!ret) - return false; - break; - - /* If this is an optimized succeed_n for zero times, make the jump. */ - case jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (mcnt >= 0) - p1 += mcnt; - else - return false; - break; - - case succeed_n: - /* Get to the number of times to succeed. */ - p1 += 2; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - if (mcnt == 0) - { - p1 -= 4; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - } - else - return false; - break; - - case duplicate: - if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) - return false; - break; - - case set_number_at: - p1 += 4; - - default: - /* All other opcodes mean we cannot match the empty string. */ - return false; - } - - *p = p1; - return true; -} /* common_op_match_null_string_p */ - - -/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN - bytes; nonzero otherwise. */ - -static int -bcmp_translate (s1, s2, len, translate) - const char *s1, *s2; - register int len; - RE_TRANSLATE_TYPE translate; -{ - register const unsigned char *p1 = (const unsigned char *) s1; - register const unsigned char *p2 = (const unsigned char *) s2; - while (len) - { - if (translate[*p1++] != translate[*p2++]) return 1; - len--; - } - return 0; -} - -/* Entry points for GNU code. */ - -/* re_compile_pattern is the GNU regular expression compiler: it - compiles PATTERN (of length SIZE) and puts the result in BUFP. - Returns 0 if the pattern was valid, otherwise an error string. - - Assumes the `allocated' (and perhaps `buffer') and `translate' fields - are set in BUFP on entry. - - We call regex_compile to do the actual compilation. */ - -const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - size_t length; - struct re_pattern_buffer *bufp; -{ - reg_errcode_t ret; - - /* GNU code is written to assume at least RE_NREGS registers will be set - (and at least one extra will be -1). */ - bufp->regs_allocated = REGS_UNALLOCATED; - - /* And GNU code determines whether or not to get register information - by passing null for the REGS argument to re_match, etc., not by - setting no_sub. */ - bufp->no_sub = 0; - - /* Match anchors at newline. */ - bufp->newline_anchor = 1; - - ret = regex_compile (pattern, length, re_syntax_options, bufp); - - if (!ret) - return NULL; - return gettext (re_error_msgid[(int) ret]); -} -#ifdef _LIBC -weak_alias (__re_compile_pattern, re_compile_pattern) -#endif - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined _REGEX_RE_COMP || defined _LIBC - -/* BSD has one and only one pattern buffer. */ -static struct re_pattern_buffer re_comp_buf; - -char * -#ifdef _LIBC -/* Make these definitions weak in libc, so POSIX programs can redefine - these names if they don't use our functions, and still use - regcomp/regexec below without link errors. */ -weak_function -#endif -re_comp (s) - const char *s; -{ - reg_errcode_t ret; - - if (!s) - { - if (!re_comp_buf.buffer) - return gettext ("No previous regular expression"); - return 0; - } - - if (!re_comp_buf.buffer) - { - re_comp_buf.buffer = (unsigned char *) malloc (200); - if (re_comp_buf.buffer == NULL) - return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); - re_comp_buf.allocated = 200; - - re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); - if (re_comp_buf.fastmap == NULL) - return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); - } - - /* Since `re_exec' always passes NULL for the `regs' argument, we - don't need to initialize the pattern buffer fields which affect it. */ - - /* Match anchors at newlines. */ - re_comp_buf.newline_anchor = 1; - - ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); - - if (!ret) - return NULL; - - /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ - return (char *) gettext (re_error_msgid[(int) ret]); -} - - -int -#ifdef _LIBC -weak_function -#endif -re_exec (s) - const char *s; -{ - const int len = strlen (s); - return - 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); -} - -#endif /* _REGEX_RE_COMP */ - -/* POSIX.2 functions. Don't define these for Emacs. */ - -#ifndef emacs - -/* regcomp takes a regular expression as a string and compiles it. - - PREG is a regex_t *. We do not expect any fields to be initialized, - since POSIX says we shouldn't. Thus, we set - - `buffer' to the compiled pattern; - `used' to the length of the compiled pattern; - `syntax' to RE_SYNTAX_POSIX_EXTENDED if the - REG_EXTENDED bit in CFLAGS is set; otherwise, to - RE_SYNTAX_POSIX_BASIC; - `newline_anchor' to REG_NEWLINE being set in CFLAGS; - `fastmap' and `fastmap_accurate' to zero; - `re_nsub' to the number of subexpressions in PATTERN. - - PATTERN is the address of the pattern string. - - CFLAGS is a series of bits which affect compilation. - - If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we - use POSIX basic syntax. - - If REG_NEWLINE is set, then . and [^...] don't match newline. - Also, regexec will try a match beginning after every newline. - - If REG_ICASE is set, then we considers upper- and lowercase - versions of letters to be equivalent when matching. - - If REG_NOSUB is set, then when PREG is passed to regexec, that - routine will report only success or failure, and nothing about the - registers. - - It returns 0 if it succeeds, nonzero if it doesn't. (See gnu-regex.h for - the return codes and their meanings.) */ - -int -regcomp (preg, pattern, cflags) - regex_t *preg; - const char *pattern; - int cflags; -{ - reg_errcode_t ret; - reg_syntax_t syntax - = (cflags & REG_EXTENDED) ? - RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; - - /* regex_compile will allocate the space for the compiled pattern. */ - preg->buffer = 0; - preg->allocated = 0; - preg->used = 0; - - /* Don't bother to use a fastmap when searching. This simplifies the - REG_NEWLINE case: if we used a fastmap, we'd have to put all the - characters after newlines into the fastmap. This way, we just try - every character. */ - preg->fastmap = 0; - - if (cflags & REG_ICASE) - { - unsigned i; - - preg->translate - = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE - * sizeof (*(RE_TRANSLATE_TYPE)0)); - if (preg->translate == NULL) - return (int) REG_ESPACE; - - /* Map uppercase characters to corresponding lowercase ones. */ - for (i = 0; i < CHAR_SET_SIZE; i++) - preg->translate[i] = ISUPPER (i) ? tolower (i) : i; - } - else - preg->translate = NULL; - - /* If REG_NEWLINE is set, newlines are treated differently. */ - if (cflags & REG_NEWLINE) - { /* REG_NEWLINE implies neither . nor [^...] match newline. */ - syntax &= ~RE_DOT_NEWLINE; - syntax |= RE_HAT_LISTS_NOT_NEWLINE; - /* It also changes the matching behavior. */ - preg->newline_anchor = 1; - } - else - preg->newline_anchor = 0; - - preg->no_sub = !!(cflags & REG_NOSUB); - - /* POSIX says a null character in the pattern terminates it, so we - can use strlen here in compiling the pattern. */ - ret = regex_compile (pattern, strlen (pattern), syntax, preg); - - /* POSIX doesn't distinguish between an unmatched open-group and an - unmatched close-group: both are REG_EPAREN. */ - if (ret == REG_ERPAREN) ret = REG_EPAREN; - - return (int) ret; -} -#ifdef _LIBC -weak_alias (__regcomp, regcomp) -#endif - - -/* regexec searches for a given pattern, specified by PREG, in the - string STRING. - - If NMATCH is zero or REG_NOSUB was set in the cflags argument to - `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at - least NMATCH elements, and we set them to the offsets of the - corresponding matched substrings. - - EFLAGS specifies `execution flags' which affect matching: if - REG_NOTBOL is set, then ^ does not match at the beginning of the - string; if REG_NOTEOL is set, then $ does not match at the end. - - We return 0 if we find a match and REG_NOMATCH if not. */ - -int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *preg; - const char *string; - size_t nmatch; - regmatch_t pmatch[]; - int eflags; -{ - int ret; - struct re_registers regs; - regex_t private_preg; - int len = strlen (string); - boolean want_reg_info = !preg->no_sub && nmatch > 0; - - private_preg = *preg; - - private_preg.not_bol = !!(eflags & REG_NOTBOL); - private_preg.not_eol = !!(eflags & REG_NOTEOL); - - /* The user has told us exactly how many registers to return - information about, via `nmatch'. We have to pass that on to the - matching routines. */ - private_preg.regs_allocated = REGS_FIXED; - - if (want_reg_info) - { - regs.num_regs = nmatch; - regs.start = TALLOC (nmatch, regoff_t); - regs.end = TALLOC (nmatch, regoff_t); - if (regs.start == NULL || regs.end == NULL) - return (int) REG_NOMATCH; - } - - /* Perform the searching operation. */ - ret = re_search (&private_preg, string, len, - /* start: */ 0, /* range: */ len, - want_reg_info ? ®s : (struct re_registers *) 0); - - /* Copy the register information to the POSIX structure. */ - if (want_reg_info) - { - if (ret >= 0) - { - unsigned r; - - for (r = 0; r < nmatch; r++) - { - pmatch[r].rm_so = regs.start[r]; - pmatch[r].rm_eo = regs.end[r]; - } - } - - /* If we needed the temporary register info, free the space now. */ - free (regs.start); - free (regs.end); - } - - /* We want zero return to mean success, unlike `re_search'. */ - return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; -} -#ifdef _LIBC -weak_alias (__regexec, regexec) -#endif - - -/* Returns a message corresponding to an error code, ERRCODE, returned - from either regcomp or regexec. We don't use PREG here. */ - -size_t -__regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *preg; - char *errbuf; - size_t errbuf_size; -{ - const char *msg; - size_t msg_size; - - if (errcode < 0 - || errcode >= (int) (sizeof (re_error_msgid) - / sizeof (re_error_msgid[0]))) - /* Only error codes returned by the rest of the code should be passed - to this routine. If we are given anything else, or if other regex - code generates an invalid error code, then the program has a bug. - Dump core so we can fix it. */ - abort (); - - msg = gettext (re_error_msgid[errcode]); - - msg_size = strlen (msg) + 1; /* Includes the null. */ - - if (errbuf_size != 0) - { - if (msg_size > errbuf_size) - { -#if defined HAVE_MEMPCPY || defined _LIBC - *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; -#else - memcpy (errbuf, msg, errbuf_size - 1); - errbuf[errbuf_size - 1] = 0; -#endif - } - else - memcpy (errbuf, msg, msg_size); - } - - return msg_size; -} -#ifdef _LIBC -weak_alias (__regerror, regerror) -#endif - - -/* Free dynamically allocated space used by PREG. */ - -void -regfree (preg) - regex_t *preg; -{ - if (preg->buffer != NULL) - free (preg->buffer); - preg->buffer = NULL; - - preg->allocated = 0; - preg->used = 0; - - if (preg->fastmap != NULL) - free (preg->fastmap); - preg->fastmap = NULL; - preg->fastmap_accurate = 0; - - if (preg->translate != NULL) - free (preg->translate); - preg->translate = NULL; -} -#ifdef _LIBC -weak_alias (__regfree, regfree) -#endif - -#endif /* not emacs */ diff --git a/contrib/gdb/gdb/gnu-regex.h b/contrib/gdb/gdb/gnu-regex.h deleted file mode 100644 index 9153ea1b07d..00000000000 --- a/contrib/gdb/gdb/gnu-regex.h +++ /dev/null @@ -1,576 +0,0 @@ -/* Definitions for data structures and routines for the regular - expression library, version 0.12. - Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc. - - NOTE: The canonical source of this file is maintained with the - GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _REGEX_H -#define _REGEX_H 1 - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* POSIX says that must be included (by the caller) before - . */ - -#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS -/* VMS doesn't have `size_t' in , even though POSIX says it - should be there. */ -# include -#endif - -/* GDB LOCAL: define _REGEX_RE_COMP to get BSD style re_comp and re_exec */ -#ifndef _REGEX_RE_COMP -#define _REGEX_RE_COMP -#endif - -/* The following two types have to be signed and unsigned integer type - wide enough to hold a value of a pointer. For most ANSI compilers - ptrdiff_t and size_t should be likely OK. Still size of these two - types is 2 for Microsoft C. Ugh... */ -typedef long int s_reg_t; -typedef unsigned long int active_reg_t; - -/* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ -typedef unsigned long int reg_syntax_t; - -/* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) - -/* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - -/* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - -/* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - -/* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - -/* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - -/* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - -/* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - -/* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - -/* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - -/* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -#define RE_LIMITED_OPS (RE_INTERVALS << 1) - -/* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - -/* If this bit is set, then `{...}' defines an interval, and \{ and \} - are literals. - If not set, then `\{...\}' defines an interval. */ -#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - -/* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - -/* If this bit is set, then \ matches . - If not set, then \ is a back-reference. */ -#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - -/* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - -/* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - -/* If this bit is set, then an unmatched ) is ordinary. - If not set, then an unmatched ) is invalid. */ -#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) - -/* If this bit is set, succeed as soon as we match the whole pattern, - without further backtracking. */ -#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) - -/* If this bit is set, do not process the GNU regex operators. - If not set, then the GNU regex operators are recognized. */ -#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) - -/* If this bit is set, turn on internal regex debugging. - If not set, and debugging was on, turn it off. - This only works if regex.c is compiled -DDEBUG. - We define this bit always, so that all that's needed to turn on - debugging is to recompile regex.c; the calling code can always have - this bit set, and it won't affect anything in the normal case. */ -#define RE_DEBUG (RE_NO_GNU_OPS << 1) - -/* This global variable defines the particular regexp syntax to use (for - some interfaces). When a regexp is compiled, the syntax used is - stored in the pattern buffer, so changing this does not affect - already-compiled regexps. */ -extern reg_syntax_t re_syntax_options; - -/* Define combinations of the above bits for the standard possibilities. - (The [[[ comments delimit what gets put into the Texinfo file, so - don't delete them!) */ -/* [[[begin syntaxes]]] */ -#define RE_SYNTAX_EMACS 0 - -#define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ - | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) - -#define RE_SYNTAX_GNU_AWK \ - ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ - & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS)) - -#define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INTERVALS | RE_NO_GNU_OPS) - -#define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -#define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -#define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) - -/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - -/* Syntax bits common to both basic and extended POSIX regex syntax. */ -#define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -#define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) - -/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -#define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS - replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ -#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) -/* [[[end syntaxes]]] */ - -/* Maximum number of duplicates an interval can allow. Some systems - (erroneously) define this in other header files, but we want our - value, so remove any previous define. */ -#ifdef RE_DUP_MAX -# undef RE_DUP_MAX -#endif -/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ -#define RE_DUP_MAX (0x7fff) - - -/* POSIX `cflags' bits (i.e., information for `regcomp'). */ - -/* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (REG_EXTENDED << 1) - -/* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (REG_ICASE << 1) - -/* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (REG_NEWLINE << 1) - - -/* POSIX `eflags' bits (i.e., information for regexec). */ - -/* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - -/* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - - -/* If any error codes are removed, changed, or added, update the - `re_error_msg' table in regex.c. */ -typedef enum -{ -#if (_XOPEN_SOURCE - 0) == 500 - REG_NOSYS = -1, /* This will never happen for this implementation. */ -#endif - - REG_NOERROR = 0, /* Success. */ - REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - REG_BADPAT, /* Invalid pattern. */ - REG_ECOLLATE, /* Not implemented. */ - REG_ECTYPE, /* Invalid character class name. */ - REG_EESCAPE, /* Trailing backslash. */ - REG_ESUBREG, /* Invalid back reference. */ - REG_EBRACK, /* Unmatched left bracket. */ - REG_EPAREN, /* Parenthesis imbalance. */ - REG_EBRACE, /* Unmatched \{. */ - REG_BADBR, /* Invalid contents of \{\}. */ - REG_ERANGE, /* Invalid range end. */ - REG_ESPACE, /* Ran out of memory. */ - REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - REG_EEND, /* Premature end. */ - REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ - REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ -} reg_errcode_t; - -/* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - compiled, the `re_nsub' field is available. All other fields are - private to the regex routines. */ - -#ifndef RE_TRANSLATE_TYPE -# define RE_TRANSLATE_TYPE char * -#endif - -struct re_pattern_buffer -{ -/* [[[begin pattern_buffer]]] */ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are - sometimes used as array indexes. */ - unsigned char *buffer; - - /* Number of bytes to which `buffer' points. */ - unsigned long int allocated; - - /* Number of bytes actually used in `buffer'. */ - unsigned long int used; - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t syntax; - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses - the fastmap, if there is one, to skip over impossible - starting points for matches. */ - char *fastmap; - - /* Either a translate table to apply to all characters before - comparing them, or zero for no translation. The translation - is applied to a pattern when it is compiled and to a string - when it is matched. */ - RE_TRANSLATE_TYPE translate; - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in `re_search_2', to see - whether or not we should use the fastmap, so we don't set - this absolutely perfectly; see `re_compile_fastmap' (the - `duplicate' case). */ - unsigned can_be_null : 1; - - /* If REGS_UNALLOCATED, allocate space in the `regs' structure - for `max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#define REGS_UNALLOCATED 0 -#define REGS_REALLOCATE 1 -#define REGS_FIXED 2 - unsigned regs_allocated : 2; - - /* Set to zero when `regex_compile' compiles a pattern; set to one - by `re_compile_fastmap' if it updates the fastmap. */ - unsigned fastmap_accurate : 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ - unsigned no_sub : 1; - - /* If set, a beginning-of-line anchor doesn't match at the - beginning of the string. */ - unsigned not_bol : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned not_eol : 1; - - /* If true, an anchor at a newline matches. */ - unsigned newline_anchor : 1; - -/* [[[end pattern_buffer]]] */ -}; - -typedef struct re_pattern_buffer regex_t; - -/* Type for byte offsets within the string. POSIX mandates this. */ -typedef int regoff_t; - - -/* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ -struct re_registers -{ - unsigned num_regs; - regoff_t *start; - regoff_t *end; -}; - - -/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - `re_match_2' returns information about at least this many registers - the first time a `regs' structure is passed. */ -#ifndef RE_NREGS -# define RE_NREGS 30 -#endif - - -/* POSIX specification for registers. Aside from the different names than - `re_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ -typedef struct -{ - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ -} regmatch_t; - -/* Declarations for routines. */ - -/* To avoid duplicating every routine declaration -- once with a - prototype (if we are ANSI), and once without (if we aren't) -- we - use the following macro to declare argument types. This - unfortunately clutters up the declarations a bit, but I think it's - worth it. */ - -#if __STDC__ - -# define _RE_ARGS(args) args - -#else /* not __STDC__ */ - -# define _RE_ARGS(args) () - -#endif /* not __STDC__ */ - -/* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the `re_syntax_options' variable. */ -extern reg_syntax_t __re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); -extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); - -/* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ -extern const char *__re_compile_pattern - _RE_ARGS ((const char *pattern, size_t length, - struct re_pattern_buffer *buffer)); -extern const char *re_compile_pattern - _RE_ARGS ((const char *pattern, size_t length, - struct re_pattern_buffer *buffer)); - - -/* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ -extern int __re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); -extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); - - -/* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern int __re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); -extern int re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); - - -/* Like `re_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ -extern int __re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); -extern int re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); - - -/* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern int __re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); -extern int re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); - - -/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern int __re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); -extern int re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); - - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least `NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ -extern void __re_set_registers - _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, - unsigned num_regs, regoff_t *starts, regoff_t *ends)); -extern void re_set_registers - _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, - unsigned num_regs, regoff_t *starts, regoff_t *ends)); - -#ifdef _REGEX_RE_COMP -# ifndef _CRAY -/* 4.2 bsd compatibility. */ -extern char *re_comp _RE_ARGS ((const char *)); -extern int re_exec _RE_ARGS ((const char *)); -# endif -#endif - -/* POSIX compatibility. */ -extern int __regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern, - int __cflags)); -extern int regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern, - int __cflags)); - -extern int __regexec _RE_ARGS ((const regex_t *__preg, - const char *__string, size_t __nmatch, - regmatch_t __pmatch[], int __eflags)); -extern int regexec _RE_ARGS ((const regex_t *__preg, - const char *__string, size_t __nmatch, - regmatch_t __pmatch[], int __eflags)); - -extern size_t __regerror _RE_ARGS ((int __errcode, const regex_t *__preg, - char *__errbuf, size_t __errbuf_size)); -extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, - char *__errbuf, size_t __errbuf_size)); - -extern void __regfree _RE_ARGS ((regex_t *__preg)); -extern void regfree _RE_ARGS ((regex_t *__preg)); - - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif /* regex.h */ - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ diff --git a/contrib/gdb/gdb/go32-xdep.c b/contrib/gdb/gdb/go32-xdep.c deleted file mode 100644 index 01c817a6b41..00000000000 --- a/contrib/gdb/gdb/go32-xdep.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Host-dependent code for dos running GO32 for GDB, the GNU debugger. - Copyright 1992 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include - -int -sigsetmask (mask) - int mask; -{ - return 0; -} - -void -strlwr (str) - char *str; -{ - for (; *str; str++) - *str = tolower(*str); -} diff --git a/contrib/gdb/gdb/hp-psymtab-read.c b/contrib/gdb/gdb/hp-psymtab-read.c deleted file mode 100644 index 5926ada3f3e..00000000000 --- a/contrib/gdb/gdb/hp-psymtab-read.c +++ /dev/null @@ -1,2381 +0,0 @@ -/* Read hp debug symbols and convert to internal format, for GDB. - Copyright 1993, 1996, 1998, 1999 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Written by the Center for Software Science at the University of Utah - and by Cygnus Support. */ - -/* Common include file for hp_symtab_read.c and hp_psymtab_read.c. - This has nested includes of a bunch of stuff. */ -#include "hpread.h" -#include "demangle.h" - -/* To generate dumping code, uncomment this define. The dumping - itself is controlled by routine-local statics called "dumping". */ -/* #define DUMPING 1 */ - -/* To use the quick look-up tables, uncomment this define. */ -#define QUICK_LOOK_UP 1 - -/* To call PXDB to process un-processed files, uncomment this define. */ -#define USE_PXDB 1 - -/* Forward procedure declarations */ - -void hpread_symfile_init - PARAMS ((struct objfile *)); - -void -do_pxdb PARAMS ((bfd *)); - -void hpread_build_psymtabs - PARAMS ((struct objfile *, struct section_offsets *, int)); - -void hpread_symfile_finish - PARAMS ((struct objfile *)); - -static union dnttentry *hpread_get_gntt - PARAMS ((int, struct objfile *)); - -static unsigned long hpread_get_textlow - PARAMS ((int, int, struct objfile *, int)); - -static struct partial_symtab *hpread_start_psymtab - PARAMS ((struct objfile *, struct section_offsets *, char *, CORE_ADDR, int, - struct partial_symbol **, struct partial_symbol **)); - -static struct partial_symtab *hpread_end_psymtab - PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR, - struct partial_symtab **, int)); - -/* End of forward routine declarations */ - -#ifdef USE_PXDB - -/* NOTE use of system files! May not be portable. */ - -#define PXDB_SVR4 "/opt/langtools/bin/pxdb" -#define PXDB_BSD "/usr/bin/pxdb" - -#include -#include -#include - -/* check for the existance of a file, given its full pathname */ -int -file_exists (filename) - char *filename; -{ - if (filename) - return (access (filename, F_OK) == 0); - return 0; -} - - -/* Translate from the "hp_language" enumeration in hp-symtab.h - used in the debug info to gdb's generic enumeration in defs.h. */ -static enum language -trans_lang (in_lang) - enum hp_language in_lang; -{ - if (in_lang == HP_LANGUAGE_C) - return language_c; - - else if (in_lang == HP_LANGUAGE_CPLUSPLUS) - return language_cplus; - - else if (in_lang == HP_LANGUAGE_F77) - return language_fortran; - - else - return language_unknown; -} - -static char main_string[] = "main"; - -/* Call PXDB to process our file. - - Approach copied from DDE's "dbgk_run_pxdb". Note: we - don't check for BSD location of pxdb, nor for existance - of pxdb itself, etc. - - NOTE: uses system function and string functions directly. - - Return value: 1 if ok, 0 if not */ -int -hpread_call_pxdb (file_name) - char *file_name; -{ - char *p; - int status; - int retval; - - if (file_exists (PXDB_SVR4)) - { - p = malloc (strlen (PXDB_SVR4) + strlen (file_name) + 2); - strcpy (p, PXDB_SVR4); - strcat (p, " "); - strcat (p, file_name); - - warning ("File not processed by pxdb--about to process now.\n"); - status = system (p); - - retval = (status == 0); - } - else - { - warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name); - - retval = 0; - } - return retval; -} /* hpread_call_pxdb */ - - -/* Return 1 if the file turns out to need pre-processing - by PXDB, and we have thus called PXDB to do this processing - and the file therefore needs to be re-loaded. Otherwise - return 0. */ -int -hpread_pxdb_needed (sym_bfd) - bfd *sym_bfd; -{ - asection *pinfo_section, *debug_section, *header_section; - unsigned int do_pxdb; - char *buf; - bfd_size_type header_section_size; - - unsigned long tmp; - unsigned int pxdbed; - - header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$"); - if (!header_section) - { - return 0; /* No header at all, can't recover... */ - } - - debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$"); - pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$"); - - if (pinfo_section && !debug_section) - { - /* Debug info with DOC, has different header format. - this only happens if the file was pxdbed and compiled optimized - otherwise the PINFO section is not there. */ - header_section_size = bfd_section_size (objfile->obfd, header_section); - - if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header)) - { - buf = alloca (sizeof (DOC_info_PXDB_header)); - - if (!bfd_get_section_contents (sym_bfd, - header_section, - buf, 0, - header_section_size)) - error ("bfd_get_section_contents\n"); - - tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4)); - pxdbed = (tmp >> 31) & 0x1; - - if (!pxdbed) - error ("file debug header info invalid\n"); - do_pxdb = 0; - } - - else - error ("invalid $HEADER$ size in executable \n"); - } - - else - { - - /* this can be three different cases: - 1. pxdbed and not doc - - DEBUG and HEADER sections are there - - header is PXDB_header type - - pxdbed flag is set to 1 - - 2. not pxdbed and doc - - DEBUG and HEADER sections are there - - header is DOC_info_header type - - pxdbed flag is set to 0 - - 3. not pxdbed and not doc - - DEBUG and HEADER sections are there - - header is XDB_header type - - pxdbed flag is set to 0 - - NOTE: the pxdbed flag is meaningful also in the not - already pxdb processed version of the header, - because in case on non-already processed by pxdb files - that same bit in the header would be always zero. - Why? Because the bit is the leftmost bit of a word - which contains a 'length' which is always a positive value - so that bit is never set to 1 (otherwise it would be negative) - - Given the above, we have two choices : either we ignore the - size of the header itself and just look at the pxdbed field, - or we check the size and then we (for safety and paranoia related - issues) check the bit. - The first solution is used by DDE, the second by PXDB itself. - I am using the second one here, because I already wrote it, - and it is the end of a long day. - Also, using the first approach would still involve size issues - because we need to read in the contents of the header section, and - give the correct amount of stuff we want to read to the - get_bfd_section_contents function. */ - - /* decide which case depending on the size of the header section. - The size is as defined in hp-symtab.h */ - - header_section_size = bfd_section_size (objfile->obfd, header_section); - - if (header_section_size == (bfd_size_type) sizeof (PXDB_header)) /* pxdb and not doc */ - { - - buf = alloca (sizeof (PXDB_header)); - if (!bfd_get_section_contents (sym_bfd, - header_section, - buf, 0, - header_section_size)) - error ("bfd_get_section_contents\n"); - - tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3)); - pxdbed = (tmp >> 31) & 0x1; - - if (pxdbed) - do_pxdb = 0; - else - error ("file debug header invalid\n"); - } - else /*not pxdbed and doc OR not pxdbed and non doc */ - do_pxdb = 1; - } - - if (do_pxdb) - { - return 1; - } - else - { - return 0; - } -} /* hpread_pxdb_needed */ - -#endif - -/* Check whether the file needs to be preprocessed by pxdb. - If so, call pxdb. */ - -void -do_pxdb (sym_bfd) - bfd *sym_bfd; -{ - /* The following code is HP-specific. The "right" way of - doing this is unknown, but we bet would involve a target- - specific pre-file-load check using a generic mechanism. */ - - /* This code will not be executed if the file is not in SOM - format (i.e. if compiled with gcc) */ - if (hpread_pxdb_needed (sym_bfd)) - { - /*This file has not been pre-processed. Preprocess now */ - - if (hpread_call_pxdb (sym_bfd->filename)) - { - /* The call above has changed the on-disk file, - we can close the file anyway, because the - symbols will be reread in when the target is run */ - bfd_close (sym_bfd); - } - } -} - - - -#ifdef QUICK_LOOK_UP - -/* Code to handle quick lookup-tables follows. */ - - -/* Some useful macros */ -#define VALID_FILE(i) ((i) < pxdb_header_p->fd_entries) -#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries) -#define VALID_PROC(i) ((i) < pxdb_header_p->pd_entries) -#define VALID_CLASS(i) ((i) < pxdb_header_p->cd_entries) - -#define FILE_START(i) (qFD[i].adrStart) -#define MODULE_START(i) (qMD[i].adrStart) -#define PROC_START(i) (qPD[i].adrStart) - -#define FILE_END(i) (qFD[i].adrEnd) -#define MODULE_END(i) (qMD[i].adrEnd) -#define PROC_END(i) (qPD[i].adrEnd) - -#define FILE_ISYM(i) (qFD[i].isym) -#define MODULE_ISYM(i) (qMD[i].isym) -#define PROC_ISYM(i) (qPD[i].isym) - -#define VALID_CURR_FILE (curr_fd < pxdb_header_p->fd_entries) -#define VALID_CURR_MODULE (curr_md < pxdb_header_p->md_entries) -#define VALID_CURR_PROC (curr_pd < pxdb_header_p->pd_entries) -#define VALID_CURR_CLASS (curr_cd < pxdb_header_p->cd_entries) - -#define CURR_FILE_START (qFD[curr_fd].adrStart) -#define CURR_MODULE_START (qMD[curr_md].adrStart) -#define CURR_PROC_START (qPD[curr_pd].adrStart) - -#define CURR_FILE_END (qFD[curr_fd].adrEnd) -#define CURR_MODULE_END (qMD[curr_md].adrEnd) -#define CURR_PROC_END (qPD[curr_pd].adrEnd) - -#define CURR_FILE_ISYM (qFD[curr_fd].isym) -#define CURR_MODULE_ISYM (qMD[curr_md].isym) -#define CURR_PROC_ISYM (qPD[curr_pd].isym) - -#define TELL_OBJFILE \ - do { \ - if( !told_objfile ) { \ - told_objfile = 1; \ - warning ("\nIn object file \"%s\":\n", \ - objfile->name); \ - } \ - } while (0) - - - -/* Keeping track of the start/end symbol table (LNTT) indices of - psymtabs created so far */ - -typedef struct - { - int start; - int end; - } -pst_syms_struct; - -static pst_syms_struct *pst_syms_array = 0; - -static pst_syms_count = 0; -static pst_syms_size = 0; - -/* used by the TELL_OBJFILE macro */ -static boolean told_objfile = 0; - -/* Set up psymtab symbol index stuff */ -static void -init_pst_syms () -{ - pst_syms_count = 0; - pst_syms_size = 20; - pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct)); -} - -/* Clean up psymtab symbol index stuff */ -static void -clear_pst_syms () -{ - pst_syms_count = 0; - pst_syms_size = 0; - free (pst_syms_array); - pst_syms_array = 0; -} - -/* Add information about latest psymtab to symbol index table */ -static void -record_pst_syms (start_sym, end_sym) - int start_sym; - int end_sym; -{ - if (++pst_syms_count > pst_syms_size) - { - pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array, - 2 * pst_syms_size * sizeof (pst_syms_struct)); - pst_syms_size *= 2; - } - pst_syms_array[pst_syms_count - 1].start = start_sym; - pst_syms_array[pst_syms_count - 1].end = end_sym; -} - -/* Find a suitable symbol table index which can serve as the upper - bound of a psymtab that starts at INDEX - - This scans backwards in the psymtab symbol index table to find a - "hole" in which the given index can fit. This is a heuristic!! - We don't search the entire table to check for multiple holes, - we don't care about overlaps, etc. - - Return 0 => not found */ -static int -find_next_pst_start (index) - int index; -{ - int i; - - for (i = pst_syms_count - 1; i >= 0; i--) - if (pst_syms_array[i].end <= index) - return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1; - - if (pst_syms_array[0].start > index) - return pst_syms_array[0].start - 1; - - return 0; -} - - - -/* Utility functions to find the ending symbol index for a psymtab */ - -/* Find the next file entry that begins beyond INDEX, and return - its starting symbol index - 1. - QFD is the file table, CURR_FD is the file entry from where to start, - PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work). - - Return 0 => not found */ -static int -find_next_file_isym (index, qFD, curr_fd, pxdb_header_p) - int index; - quick_file_entry *qFD; - int curr_fd; - PXDB_header_ptr pxdb_header_p; -{ - while (VALID_CURR_FILE) - { - if (CURR_FILE_ISYM >= index) - return CURR_FILE_ISYM - 1; - curr_fd++; - } - return 0; -} - -/* Find the next procedure entry that begins beyond INDEX, and return - its starting symbol index - 1. - QPD is the procedure table, CURR_PD is the proc entry from where to start, - PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work). - - Return 0 => not found */ -static int -find_next_proc_isym (index, qPD, curr_pd, pxdb_header_p) - int index; - quick_procedure_entry *qPD; - int curr_pd; - PXDB_header_ptr pxdb_header_p; -{ - while (VALID_CURR_PROC) - { - if (CURR_PROC_ISYM >= index) - return CURR_PROC_ISYM - 1; - curr_pd++; - } - return 0; -} - -/* Find the next module entry that begins beyond INDEX, and return - its starting symbol index - 1. - QMD is the module table, CURR_MD is the modue entry from where to start, - PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work). - - Return 0 => not found */ -static int -find_next_module_isym (index, qMD, curr_md, pxdb_header_p) - int index; - quick_module_entry *qMD; - int curr_md; - PXDB_header_ptr pxdb_header_p; -{ - while (VALID_CURR_MODULE) - { - if (CURR_MODULE_ISYM >= index) - return CURR_MODULE_ISYM - 1; - curr_md++; - } - return 0; -} - -/* Scan and record partial symbols for all functions starting from index - pointed to by CURR_PD_P, and between code addresses START_ADR and END_ADR. - Other parameters are explained in comments below. */ - -/* This used to be inline in hpread_quick_traverse, but now that we do essentially the - same thing for two different cases (modules and module-less files), it's better - organized in a separate routine, although it does take lots of arguments. pai/1997-10-08 */ - -static int -scan_procs (curr_pd_p, qPD, max_procs, start_adr, end_adr, pst, vt_bits, objfile, section_offsets) - int *curr_pd_p; /* pointer to current proc index */ - quick_procedure_entry *qPD; /* the procedure quick lookup table */ - int max_procs; /* number of entries in proc. table */ - CORE_ADDR start_adr; /* beginning of code range for current psymtab */ - CORE_ADDR end_adr; /* end of code range for current psymtab */ - struct partial_symtab *pst; /* current psymtab */ - char *vt_bits; /* strings table of SOM debug space */ - struct objfile *objfile; /* current object file */ - struct section_offsets *section_offsets; /* not really used for HP-UX currently */ -{ - union dnttentry *dn_bufp; - int symbol_count = 0; /* Total number of symbols in this psymtab */ - int curr_pd = *curr_pd_p; /* Convenience variable -- avoid dereferencing pointer all the time */ - -#ifdef DUMPING - /* Turn this on for lots of debugging information in this routine */ - static int dumping = 0; -#endif - -#ifdef DUMPING - if (dumping) - { - printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd); - } -#endif - - while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs)) - { - - char *rtn_name; /* mangled name */ - char *rtn_dem_name; /* qualified demangled name */ - char *class_name; - int class; - - if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) && - vt_bits[(long) qPD[curr_pd].sbAlias]) /* not a null string */ - { - /* Get mangled name for the procedure, and demangle it */ - rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias]; - rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS); - } - else - { - rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc]; - rtn_dem_name = NULL; - } - - /* Hack to get around HP C/C++ compilers' insistence on providing - "_MAIN_" as an alternate name for "main" */ - if ((strcmp (rtn_name, "_MAIN_") == 0) && - (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0)) - rtn_dem_name = rtn_name = main_string; - -#ifdef DUMPING - if (dumping) - { - printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd); - } -#endif - - /* Check for module-spanning routines. */ - if (CURR_PROC_END > end_adr) - { - TELL_OBJFILE; - warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd); - } - - /* Add this routine symbol to the list in the objfile. - Unfortunately we have to go to the LNTT to determine the - correct list to put it on. An alternative (which the - code used to do) would be to not check and always throw - it on the "static" list. But if we go that route, then - symbol_lookup() needs to be tweaked a bit to account - for the fact that the function might not be found on - the correct list in the psymtab. - RT */ - dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile); - if (dn_bufp->dfunc.global) - add_psymbol_with_dem_name_to_list (rtn_name, - strlen (rtn_name), - rtn_dem_name, - strlen (rtn_dem_name), - VAR_NAMESPACE, - LOC_BLOCK, /* "I am a routine" */ - &objfile->global_psymbols, - (qPD[curr_pd].adrStart + /* Starting address of rtn */ - ANOFFSET (section_offsets, SECT_OFF_TEXT)), - 0, /* core addr?? */ - trans_lang ((enum hp_language) qPD[curr_pd].language), - objfile); - else - add_psymbol_with_dem_name_to_list (rtn_name, - strlen (rtn_name), - rtn_dem_name, - strlen (rtn_dem_name), - VAR_NAMESPACE, - LOC_BLOCK, /* "I am a routine" */ - &objfile->static_psymbols, - (qPD[curr_pd].adrStart + /* Starting address of rtn */ - ANOFFSET (section_offsets, SECT_OFF_TEXT)), - 0, /* core addr?? */ - trans_lang ((enum hp_language) qPD[curr_pd].language), - objfile); - - symbol_count++; - *curr_pd_p = ++curr_pd; /* bump up count & reflect in caller */ - } /* loop over procedures */ - -#ifdef DUMPING - if (dumping) - { - if (symbol_count == 0) - printf ("Scan_procs: no symbols found!\n"); - } -#endif - - return symbol_count; -} - - -/* Traverse the quick look-up tables, building a set of psymtabs. - - This constructs a psymtab for modules and files in the quick lookup - tables. - - Mostly, modules correspond to compilation units, so we try to - create psymtabs that correspond to modules; however, in some cases - a file can result in a compiled object which does not have a module - entry for it, so in such cases we create a psymtab for the file. */ - -int -hpread_quick_traverse (objfile, section_offsets, gntt_bits, vt_bits, pxdb_header_p) - struct objfile *objfile; /* The object file descriptor */ - struct section_offsets *section_offsets; /* ?? Null for HP */ - char *gntt_bits; /* GNTT entries, loaded in from the file */ - char *vt_bits; /* VT (string) entries ditto. */ - PXDB_header_ptr pxdb_header_p; /* Pointer to pxdb header ditto */ -{ - struct partial_symtab *pst; - - char *addr; - - quick_procedure_entry *qPD; - quick_file_entry *qFD; - quick_module_entry *qMD; - quick_class_entry *qCD; - - int idx; - int i; - CORE_ADDR start_adr; /* current psymtab's starting code addr */ - CORE_ADDR end_adr; /* current psymtab's ending code addr */ - CORE_ADDR next_mod_adr; /* next module's starting code addr */ - int curr_pd; /* current procedure */ - int curr_fd; /* current file */ - int curr_md; /* current module */ - int start_sym; /* current psymtab's starting symbol index */ - int end_sym; /* current psymtab's ending symbol index */ - int max_LNTT_sym_index; - int syms_in_pst; - B_TYPE *class_entered; - - struct partial_symbol **global_syms; /* We'll be filling in the "global" */ - struct partial_symbol **static_syms; /* and "static" tables in the objfile - as we go, so we need a pair of - current pointers. */ - -#ifdef DUMPING - /* Turn this on for lots of debugging information in this routine. - You get a blow-by-blow account of quick lookup table reading */ - static int dumping = 0; -#endif - - pst = (struct partial_symtab *) 0; - - /* Clear out some globals */ - init_pst_syms (); - told_objfile = 0; - - /* Demangling style -- if EDG style already set, don't change it, - as HP style causes some problems with the KAI EDG compiler */ - if (current_demangling_style != edg_demangling) - { - /* Otherwise, ensure that we are using HP style demangling */ - set_demangling_style (HP_DEMANGLING_STYLE_STRING); - } - - /* First we need to find the starting points of the quick - look-up tables in the GNTT. */ - - addr = gntt_bits; - - qPD = (quick_procedure_entry_ptr) addr; - addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry); - -#ifdef DUMPING - if (dumping) - { - printf ("\n Printing routines as we see them\n"); - for (i = 0; VALID_PROC (i); i++) - { - idx = (long) qPD[i].sbProc; - printf ("%s %x..%x\n", &vt_bits[idx], - (int) PROC_START (i), - (int) PROC_END (i)); - } - } -#endif - - qFD = (quick_file_entry_ptr) addr; - addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry); - -#ifdef DUMPING - if (dumping) - { - printf ("\n Printing files as we see them\n"); - for (i = 0; VALID_FILE (i); i++) - { - idx = (long) qFD[i].sbFile; - printf ("%s %x..%x\n", &vt_bits[idx], - (int) FILE_START (i), - (int) FILE_END (i)); - } - } -#endif - - qMD = (quick_module_entry_ptr) addr; - addr += pxdb_header_p->md_entries * sizeof (quick_module_entry); - -#ifdef DUMPING - if (dumping) - { - printf ("\n Printing modules as we see them\n"); - for (i = 0; i < pxdb_header_p->md_entries; i++) - { - idx = (long) qMD[i].sbMod; - printf ("%s\n", &vt_bits[idx]); - } - } -#endif - - qCD = (quick_class_entry_ptr) addr; - addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry); - -#ifdef DUMPING - if (dumping) - { - printf ("\n Printing classes as we see them\n"); - for (i = 0; VALID_CLASS (i); i++) - { - idx = (long) qCD[i].sbClass; - printf ("%s\n", &vt_bits[idx]); - } - - printf ("\n Done with dump, on to build!\n"); - } -#endif - - /* We need this index only while hp-symtab-read.c expects - a byte offset to the end of the LNTT entries for a given - psymtab. Thus the need for it should go away someday. - - When it goes away, then we won't have any need to load the - LNTT from the objfile at psymtab-time, and start-up will be - faster. To make that work, we'll need some way to create - a null pst for the "globals" pseudo-module. */ - max_LNTT_sym_index = LNTT_SYMCOUNT (objfile); - - /* Scan the module descriptors and make a psymtab for each. - - We know the MDs, FDs and the PDs are in order by starting - address. We use that fact to traverse all three arrays in - parallel, knowing when the next PD is in a new file - and we need to create a new psymtab. */ - curr_pd = 0; /* Current procedure entry */ - curr_fd = 0; /* Current file entry */ - curr_md = 0; /* Current module entry */ - - start_adr = 0; /* Current psymtab code range */ - end_adr = 0; - - start_sym = 0; /* Current psymtab symbol range */ - end_sym = 0; - - syms_in_pst = 0; /* Symbol count for psymtab */ - - /* Psts actually just have pointers into the objfile's - symbol table, not their own symbol tables. */ - global_syms = objfile->global_psymbols.list; - static_syms = objfile->static_psymbols.list; - - - /* First skip over pseudo-entries with address 0. These represent inlined - routines and abstract (uninstantiated) template routines. - FIXME: These should be read in and available -- even if we can't set - breakpoints, etc., there's some information that can be presented - to the user. pai/1997-10-08 */ - - while (VALID_CURR_PROC && (CURR_PROC_START == 0)) - curr_pd++; - - /* Loop over files, modules, and procedures in code address order. Each - time we enter an iteration of this loop, curr_pd points to the first - unprocessed procedure, curr_fd points to the first unprocessed file, and - curr_md to the first unprocessed module. Each iteration of this loop - updates these as required -- any or all of them may be bumpd up - each time around. When we exit this loop, we are done with all files - and modules in the tables -- there may still be some procedures, however. - - Note: This code used to loop only over module entries, under the assumption - that files can occur via inclusions and are thus unreliable, while a - compiled object always corresponds to a module. With CTTI in the HP aCC - compiler, it turns out that compiled objects may have only files and no - modules; so we have to loop over files and modules, creating psymtabs for - either as appropriate. Unfortunately there are some problems (notably: - 1. the lack of "SRC_FILE_END" entries in the LNTT, 2. the lack of pointers - to the ending symbol indices of a module or a file) which make it quite hard - to do this correctly. Currently it uses a bunch of heuristics to start and - end psymtabs; they seem to work well with most objects generated by aCC, but - who knows when that will change... */ - - while (VALID_CURR_FILE || VALID_CURR_MODULE) - { - - char *mod_name_string; - char *full_name_string; - - /* First check for modules like "version.c", which have no code - in them but still have qMD entries. They also have no qFD or - qPD entries. Their start address is -1 and their end address - is 0. */ - if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0)) - { - - mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod]; - -#ifdef DUMPING - if (dumping) - printf ("Module with data only %s\n", mod_name_string); -#endif - - /* We'll skip the rest (it makes error-checking easier), and - just make an empty pst. Right now empty psts are not put - in the pst chain, so all this is for naught, but later it - might help. */ - - pst = hpread_start_psymtab (objfile, - section_offsets, /* ?? */ - mod_name_string, - CURR_MODULE_START, /* Low text address: bogus! */ - (CURR_MODULE_ISYM * sizeof (struct dntt_type_block)), - /* ldsymoff */ - global_syms, - static_syms); - - pst = hpread_end_psymtab (pst, - NULL, /* psymtab_include_list */ - 0, /* includes_used */ - end_sym * sizeof (struct dntt_type_block), - /* byte index in LNTT of end - = capping symbol offset - = LDSYMOFF of nextfile */ - 0, /* text high */ - NULL, /* dependency_list */ - 0); /* dependencies_used */ - - global_syms = objfile->global_psymbols.next; - static_syms = objfile->static_psymbols.next; - - curr_md++; - } - else if (VALID_CURR_MODULE && - ((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) || - (CURR_MODULE_END == 0) || (CURR_MODULE_END == -1))) - { - TELL_OBJFILE; - warning ("Module \"%s\" [0x%x] has non-standard addresses. It starts at 0x%x, ends at 0x%x, and will be skipped.", - mod_name_string, curr_md, start_adr, end_adr); - /* On to next module */ - curr_md++; - } - else - { - /* First check if we are looking at a file with code in it - that does not overlap the current module's code range */ - - if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0) - { - - /* Looking at file not corresponding to any module, - create a psymtab for it */ - full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile]; - start_adr = CURR_FILE_START; - end_adr = CURR_FILE_END; - start_sym = CURR_FILE_ISYM; - - /* Check if there are any procedures not handled until now, that - begin before the start address of this file, and if so, adjust - this module's start address to include them. This handles routines that - are in between file or module ranges for some reason (probably - indicates a compiler bug */ - - if (CURR_PROC_START < start_adr) - { - TELL_OBJFILE; - warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.", - &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd); - start_adr = CURR_PROC_START; - if (CURR_PROC_ISYM < start_sym) - start_sym = CURR_PROC_ISYM; - } - - /* Sometimes (compiler bug -- COBOL) the module end address is higher - than the start address of the next module, so check for that and - adjust accordingly */ - - if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr)) - { - TELL_OBJFILE; - warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.", - full_name_string, curr_fd); - end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */ - } - if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr)) - { - TELL_OBJFILE; - warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.", - full_name_string, curr_fd); - end_adr = CURR_MODULE_START - 1; /* Is -4 (or -8 for 64-bit) better? */ - } - - -#ifdef DUMPING - if (dumping) - { - printf ("Make new psymtab for file %s (%x to %x).\n", - full_name_string, start_adr, end_adr); - } -#endif - /* Create the basic psymtab, connecting it in the list - for this objfile and pointing its symbol entries - to the current end of the symbol areas in the objfile. - - The "ldsymoff" parameter is the byte offset in the LNTT - of the first symbol in this file. Some day we should - turn this into an index (fix in hp-symtab-read.c as well). - And it's not even the right byte offset, as we're using - the size of a union! FIXME! */ - pst = hpread_start_psymtab (objfile, - section_offsets, /* ?? */ - full_name_string, - start_adr, /* Low text address */ - (start_sym * sizeof (struct dntt_type_block)), - /* ldsymoff */ - global_syms, - static_syms); - - /* Set up to only enter each class referenced in this module once. */ - class_entered = malloc (B_BYTES (pxdb_header_p->cd_entries)); - B_CLRALL (class_entered, pxdb_header_p->cd_entries); - - /* Scan the procedure descriptors for procedures in the current - file, based on the starting addresses. */ - - syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries, - start_adr, end_adr, - pst, vt_bits, objfile, section_offsets); - - /* Get ending symbol offset */ - - end_sym = 0; - /* First check for starting index before previous psymtab */ - if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end) - { - end_sym = find_next_pst_start (start_sym); - } - /* Look for next start index of a file or module, or procedure */ - if (!end_sym) - { - int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p); - int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p); - int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p); - - if (next_file_isym && next_module_isym) - { - /* pick lower of next file or module start index */ - end_sym = min (next_file_isym, next_module_isym); - } - else - { - /* one of them is zero, pick the other */ - end_sym = max (next_file_isym, next_module_isym); - } - - /* As a precaution, check next procedure index too */ - if (!end_sym) - end_sym = next_proc_isym; - else - end_sym = min (end_sym, next_proc_isym); - } - - /* Couldn't find procedure, file, or module, use globals as default */ - if (!end_sym) - end_sym = pxdb_header_p->globals; - -#ifdef DUMPING - if (dumping) - { - printf ("File psymtab indices: %x to %x\n", start_sym, end_sym); - } -#endif - - pst = hpread_end_psymtab (pst, - NULL, /* psymtab_include_list */ - 0, /* includes_used */ - end_sym * sizeof (struct dntt_type_block), - /* byte index in LNTT of end - = capping symbol offset - = LDSYMOFF of nextfile */ - end_adr, /* text high */ - NULL, /* dependency_list */ - 0); /* dependencies_used */ - - record_pst_syms (start_sym, end_sym); - - if (NULL == pst) - warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd); - -#ifdef DUMPING - if (dumping) - { - printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n", - full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym); - } -#endif - /* Prepare for the next psymtab. */ - global_syms = objfile->global_psymbols.next; - static_syms = objfile->static_psymbols.next; - free (class_entered); - - curr_fd++; - } /* Psymtab for file */ - else - { - /* We have a module for which we create a psymtab */ - - mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod]; - - /* We will include the code ranges of any files that happen to - overlap with this module */ - - /* So, first pick the lower of the file's and module's start addresses */ - start_adr = CURR_MODULE_START; - if (VALID_CURR_FILE) - { - if (CURR_FILE_START < CURR_MODULE_START) - { - TELL_OBJFILE; - warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".", - &vt_bits[(long) qFD[curr_fd].sbFile], - curr_fd, mod_name_string); - - start_adr = CURR_FILE_START; - } - } - - /* Also pick the lower of the file's and the module's start symbol indices */ - start_sym = CURR_MODULE_ISYM; - if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM)) - start_sym = CURR_FILE_ISYM; - - /* For the end address, we scan through the files till we find one - that overlaps the current module but ends beyond it; if no such file exists we - simply use the module's start address. - (Note, if file entries themselves overlap - we take the longest overlapping extension beyond the end of the module...) - We assume that modules never overlap. */ - - end_adr = CURR_MODULE_END; - - if (VALID_CURR_FILE) - { - while (VALID_CURR_FILE && (CURR_FILE_START < end_adr)) - { - -#ifdef DUMPING - if (dumping) - printf ("Maybe skipping file %s which overlaps with module %s\n", - &vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string); -#endif - if (CURR_FILE_END > end_adr) - { - TELL_OBJFILE; - warning ("File \"%s\" [0x%x] crosses end of module \"%s\".", - &vt_bits[(long) qFD[curr_fd].sbFile], - curr_fd, mod_name_string); - end_adr = CURR_FILE_END; - } - curr_fd++; - } - curr_fd--; /* back up after going too far */ - } - - /* Sometimes (compiler bug -- COBOL) the module end address is higher - than the start address of the next module, so check for that and - adjust accordingly */ - - if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr)) - { - TELL_OBJFILE; - warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.", - mod_name_string, curr_md); - end_adr = MODULE_START (curr_md + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */ - } - if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr)) - { - TELL_OBJFILE; - warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.", - mod_name_string, curr_md); - end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */ - } - - /* Use one file to get the full name for the module. This - situation can arise if there is executable code in a #include - file. Each file with code in it gets a qFD. Files which don't - contribute code don't get a qFD, even if they include files - which do, e.g.: - - body.c: rtn.h: - int x; int main() { - #include "rtn.h" return x; - } - - There will a qFD for "rtn.h",and a qMD for "body.c", - but no qMD for "rtn.h" or qFD for "body.c"! - - We pick the name of the last file to overlap with this - module. C convention is to put include files first. In a - perfect world, we could check names and use the file whose full - path name ends with the module name. */ - - if (VALID_CURR_FILE) - full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile]; - else - full_name_string = mod_name_string; - - /* Check if there are any procedures not handled until now, that - begin before the start address we have now, and if so, adjust - this psymtab's start address to include them. This handles routines that - are in between file or module ranges for some reason (probably - indicates a compiler bug */ - - if (CURR_PROC_START < start_adr) - { - TELL_OBJFILE; - warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.", - &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd); - start_adr = CURR_PROC_START; - if (CURR_PROC_ISYM < start_sym) - start_sym = CURR_PROC_ISYM; - } - -#ifdef DUMPING - if (dumping) - { - printf ("Make new psymtab for module %s (%x to %x), using file %s\n", - mod_name_string, start_adr, end_adr, full_name_string); - } -#endif - /* Create the basic psymtab, connecting it in the list - for this objfile and pointing its symbol entries - to the current end of the symbol areas in the objfile. - - The "ldsymoff" parameter is the byte offset in the LNTT - of the first symbol in this file. Some day we should - turn this into an index (fix in hp-symtab-read.c as well). - And it's not even the right byte offset, as we're using - the size of a union! FIXME! */ - pst = hpread_start_psymtab (objfile, - section_offsets, /* ?? */ - full_name_string, - start_adr, /* Low text address */ - (start_sym * sizeof (struct dntt_type_block)), - /* ldsymoff */ - global_syms, - static_syms); - - /* Set up to only enter each class referenced in this module once. */ - class_entered = malloc (B_BYTES (pxdb_header_p->cd_entries)); - B_CLRALL (class_entered, pxdb_header_p->cd_entries); - - /* Scan the procedure descriptors for procedures in the current - module, based on the starting addresses. */ - - syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries, - start_adr, end_adr, - pst, vt_bits, objfile, section_offsets); - - /* Get ending symbol offset */ - - end_sym = 0; - /* First check for starting index before previous psymtab */ - if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end) - { - end_sym = find_next_pst_start (start_sym); - } - /* Look for next start index of a file or module, or procedure */ - if (!end_sym) - { - int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p); - int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p); - int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p); - - if (next_file_isym && next_module_isym) - { - /* pick lower of next file or module start index */ - end_sym = min (next_file_isym, next_module_isym); - } - else - { - /* one of them is zero, pick the other */ - end_sym = max (next_file_isym, next_module_isym); - } - - /* As a precaution, check next procedure index too */ - if (!end_sym) - end_sym = next_proc_isym; - else - end_sym = min (end_sym, next_proc_isym); - } - - /* Couldn't find procedure, file, or module, use globals as default */ - if (!end_sym) - end_sym = pxdb_header_p->globals; - -#ifdef DUMPING - if (dumping) - { - printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym); - } -#endif - - pst = hpread_end_psymtab (pst, - NULL, /* psymtab_include_list */ - 0, /* includes_used */ - end_sym * sizeof (struct dntt_type_block), - /* byte index in LNTT of end - = capping symbol offset - = LDSYMOFF of nextfile */ - end_adr, /* text high */ - NULL, /* dependency_list */ - 0); /* dependencies_used */ - - record_pst_syms (start_sym, end_sym); - - if (NULL == pst) - warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md); - -#ifdef DUMPING - if (dumping) - { - printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n", - mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym); - } -#endif - - /* Prepare for the next psymtab. */ - global_syms = objfile->global_psymbols.next; - static_syms = objfile->static_psymbols.next; - free (class_entered); - - curr_md++; - curr_fd++; - } /* psymtab for module */ - } /* psymtab for non-bogus file or module */ - } /* End of while loop over all files & modules */ - - /* There may be some routines after all files and modules -- these will get - inserted in a separate new module of their own */ - if (VALID_CURR_PROC) - { - start_adr = CURR_PROC_START; - end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd; - TELL_OBJFILE; - warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd); -#ifdef DUMPING - if (dumping) - { - printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n", - curr_pd, start_adr, end_adr); - } -#endif - pst = hpread_start_psymtab (objfile, - section_offsets, /* ?? */ - "orphans", - start_adr, /* Low text address */ - (CURR_PROC_ISYM * sizeof (struct dntt_type_block)), - /* ldsymoff */ - global_syms, - static_syms); - - scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries, - start_adr, end_adr, - pst, vt_bits, objfile, section_offsets); - - pst = hpread_end_psymtab (pst, - NULL, /* psymtab_include_list */ - 0, /* includes_used */ - pxdb_header_p->globals * sizeof (struct dntt_type_block), - /* byte index in LNTT of end - = capping symbol offset - = LDSYMOFF of nextfile */ - end_adr, /* text high */ - NULL, /* dependency_list */ - 0); /* dependencies_used */ - } - - -#ifdef NEVER_NEVER - /* Now build psts for non-module things (in the tail of - the LNTT, after the last END MODULE entry). - - If null psts were kept on the chain, this would be - a solution. FIXME */ - pst = hpread_start_psymtab (objfile, - section_offsets, - "globals", - 0, - (pxdb_header_p->globals - * sizeof (struct dntt_type_block)), - objfile->global_psymbols.next, - objfile->static_psymbols.next); - hpread_end_psymtab (pst, - NULL, 0, - (max_LNTT_sym_index * sizeof (struct dntt_type_block)), - 0, - NULL, 0); -#endif - - clear_pst_syms (); - - return 1; - -} /* End of hpread_quick_traverse. */ - - -/* Get appropriate header, based on pxdb type. - Return value: 1 if ok, 0 if not */ -int -hpread_get_header (objfile, pxdb_header_p) - struct objfile *objfile; - PXDB_header_ptr pxdb_header_p; -{ - asection *pinfo_section, *debug_section, *header_section; - -#ifdef DUMPING - /* Turn on for debugging information */ - static int dumping = 0; -#endif - - header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$"); - if (!header_section) - { - /* We don't have either PINFO or DEBUG sections. But - stuff like "libc.sl" has no debug info. There's no - need to warn the user of this, as it may be ok. The - caller will figure it out and issue any needed - messages. */ -#ifdef DUMPING - if (dumping) - printf ("==No debug info at all for %s.\n", objfile->name); -#endif - - return 0; - } - - /* We would like either a $DEBUG$ or $PINFO$ section. - Once we know which, we can understand the header - data (which we have defined to suit the more common - $DEBUG$ case). */ - debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$"); - pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$"); - if (debug_section) - { - /* The expected case: normal pxdb header. */ - bfd_get_section_contents (objfile->obfd, header_section, - pxdb_header_p, 0, sizeof (PXDB_header)); - - if (!pxdb_header_p->pxdbed) - { - /* This shouldn't happen if we check in "symfile.c". */ - return 0; - } /* DEBUG section */ - } - - else if (pinfo_section) - { - /* The DOC case; we need to translate this into a - regular header. */ - DOC_info_PXDB_header doc_header; - -#ifdef DUMPING - if (dumping) - { - printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name); - } -#endif - - bfd_get_section_contents (objfile->obfd, - header_section, - &doc_header, 0, - sizeof (DOC_info_PXDB_header)); - - if (!doc_header.pxdbed) - { - /* This shouldn't happen if we check in "symfile.c". */ - warning ("File \"%s\" not processed by pxdb!", objfile->name); - return 0; - } - - /* Copy relevent fields to standard header passed in. */ - pxdb_header_p->pd_entries = doc_header.pd_entries; - pxdb_header_p->fd_entries = doc_header.fd_entries; - pxdb_header_p->md_entries = doc_header.md_entries; - pxdb_header_p->pxdbed = doc_header.pxdbed; - pxdb_header_p->bighdr = doc_header.bighdr; - pxdb_header_p->sa_header = doc_header.sa_header; - pxdb_header_p->inlined = doc_header.inlined; - pxdb_header_p->globals = doc_header.globals; - pxdb_header_p->time = doc_header.time; - pxdb_header_p->pg_entries = doc_header.pg_entries; - pxdb_header_p->functions = doc_header.functions; - pxdb_header_p->files = doc_header.files; - pxdb_header_p->cd_entries = doc_header.cd_entries; - pxdb_header_p->aa_entries = doc_header.aa_entries; - pxdb_header_p->oi_entries = doc_header.oi_entries; - pxdb_header_p->version = doc_header.version; - } /* PINFO section */ - - else - { -#ifdef DUMPING - if (dumping) - printf ("==No debug info at all for %s.\n", objfile->name); -#endif - - return 0; - - } - - return 1; -} /* End of hpread_get_header */ -#endif /* QUICK_LOOK_UP */ - - -/* Initialization for reading native HP C debug symbols from OBJFILE. - - Its only purpose in life is to set up the symbol reader's private - per-objfile data structures, and read in the raw contents of the debug - sections (attaching pointers to the debug info into the private data - structures). - - Since BFD doesn't know how to read debug symbols in a format-independent - way (and may never do so...), we have to do it ourselves. Note we may - be called on a file without native HP C debugging symbols. - - FIXME, there should be a cleaner peephole into the BFD environment - here. */ -void -hpread_symfile_init (objfile) - struct objfile *objfile; -{ - asection *vt_section, *slt_section, *lntt_section, *gntt_section; - - /* Allocate struct to keep track of the symfile */ - objfile->sym_private = (PTR) - xmmalloc (objfile->md, sizeof (struct hpread_symfile_info)); - memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info)); - - /* We haven't read in any types yet. */ - TYPE_VECTOR (objfile) = 0; - - /* Read in data from the $GNTT$ subspace. */ - gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$"); - if (!gntt_section) - return; - - GNTT (objfile) - = obstack_alloc (&objfile->symbol_obstack, - bfd_section_size (objfile->obfd, gntt_section)); - - bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile), - 0, bfd_section_size (objfile->obfd, gntt_section)); - - GNTT_SYMCOUNT (objfile) - = bfd_section_size (objfile->obfd, gntt_section) - / sizeof (struct dntt_type_block); - - /* Read in data from the $LNTT$ subspace. Also keep track of the number - of LNTT symbols. - - FIXME: this could be moved into the psymtab-to-symtab expansion - code, and save startup time. At the moment this data is - still used, though. We'd need a way to tell hp-symtab-read.c - whether or not to load the LNTT. */ - lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$"); - if (!lntt_section) - return; - - LNTT (objfile) - = obstack_alloc (&objfile->symbol_obstack, - bfd_section_size (objfile->obfd, lntt_section)); - - bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile), - 0, bfd_section_size (objfile->obfd, lntt_section)); - - LNTT_SYMCOUNT (objfile) - = bfd_section_size (objfile->obfd, lntt_section) - / sizeof (struct dntt_type_block); - - /* Read in data from the $SLT$ subspace. $SLT$ contains information - on source line numbers. */ - slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$"); - if (!slt_section) - return; - - SLT (objfile) = - obstack_alloc (&objfile->symbol_obstack, - bfd_section_size (objfile->obfd, slt_section)); - - bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile), - 0, bfd_section_size (objfile->obfd, slt_section)); - - /* Read in data from the $VT$ subspace. $VT$ contains things like - names and constants. Keep track of the number of symbols in the VT. */ - vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$"); - if (!vt_section) - return; - - VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section); - - VT (objfile) = - (char *) obstack_alloc (&objfile->symbol_obstack, - VT_SIZE (objfile)); - - bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile), - 0, VT_SIZE (objfile)); -} - -/* Scan and build partial symbols for a symbol file. - - The minimal symbol table (either SOM or HP a.out) has already been - read in; all we need to do is setup partial symbols based on the - native debugging information. - - Note that the minimal table is produced by the linker, and has - only global routines in it; the psymtab is based on compiler- - generated debug information and has non-global - routines in it as well as files and class information. - - We assume hpread_symfile_init has been called to initialize the - symbol reader's private data structures. - - SECTION_OFFSETS contains offsets relative to which the symbols in the - various sections are (depending where the sections were actually loaded). - MAINLINE is true if we are reading the main symbol table (as - opposed to a shared lib or dynamically loaded file). */ -void -hpread_build_psymtabs (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; -{ - -#ifdef DUMPING - /* Turn this on to get debugging output. */ - static int dumping = 0; -#endif - - char *namestring; - int past_first_source_file = 0; - struct cleanup *old_chain; - - int hp_symnum, symcount, i; - int scan_start = 0; - - union dnttentry *dn_bufp; - unsigned long valu; - char *p; - int texthigh = 0; - int have_name = 0; - - /* Current partial symtab */ - struct partial_symtab *pst; - - /* List of current psymtab's include files */ - char **psymtab_include_list; - int includes_allocated; - int includes_used; - - /* Index within current psymtab dependency list */ - struct partial_symtab **dependency_list; - int dependencies_used, dependencies_allocated; - - /* Just in case the stabs reader left turds lying around. */ - free_pending_blocks (); - make_cleanup ((make_cleanup_func) really_free_pendings, 0); - - pst = (struct partial_symtab *) 0; - - /* We shouldn't use alloca, instead use malloc/free. Doing so avoids - a number of problems with cross compilation and creating useless holes - in the stack when we have to allocate new entries. FIXME. */ - - includes_allocated = 30; - includes_used = 0; - psymtab_include_list = (char **) alloca (includes_allocated * - sizeof (char *)); - - dependencies_allocated = 30; - dependencies_used = 0; - dependency_list = - (struct partial_symtab **) alloca (dependencies_allocated * - sizeof (struct partial_symtab *)); - - old_chain = make_cleanup ((make_cleanup_func) free_objfile, objfile); - - last_source_file = 0; - -#ifdef QUICK_LOOK_UP - { - /* Begin code for new-style loading of quick look-up tables. */ - - /* elz: this checks whether the file has beeen processed by pxdb. - If not we would like to try to read the psymbols in - anyway, but it turns out to be not so easy. So this could - actually be commented out, but I leave it in, just in case - we decide to add support for non-pxdb-ed stuff in the future. */ - PXDB_header pxdb_header; - int found_modules_in_program; - - if (hpread_get_header (objfile, &pxdb_header)) - { - /* Build a minimal table. No types, no global variables, - no include files.... */ -#ifdef DUMPING - if (dumping) - printf ("\nNew method for %s\n", objfile->name); -#endif - - /* elz: quick_traverse returns true if it found - some modules in the main source file, other - than those in end.c - In C and C++, all the files have MODULES entries - in the LNTT, and the quick table traverse is all - based on finding these MODULES entries. Without - those it cannot work. - It happens that F77 programs don't have MODULES - so the quick traverse gets confused. F90 programs - have modules, and the quick method still works. - So, if modules (other than those in end.c) are - not found we give up on the quick table stuff, - and fall back on the slower method */ - found_modules_in_program = hpread_quick_traverse (objfile, - section_offsets, - GNTT (objfile), - VT (objfile), - &pxdb_header); - - discard_cleanups (old_chain); - - /* Set up to scan the global section of the LNTT. - - This field is not always correct: if there are - no globals, it will point to the last record in - the regular LNTT, which is usually an END MODULE. - - Since it might happen that there could be a file - with just one global record, there's no way to - tell other than by looking at the record, so that's - done below. */ - if (found_modules_in_program) - scan_start = pxdb_header.globals; - } -#ifdef DUMPING - else - { - if (dumping) - printf ("\nGoing on to old method for %s\n", objfile->name); - } -#endif - } -#endif /* QUICK_LOOK_UP */ - - /* Make two passes, one over the GNTT symbols, the other for the - LNTT symbols. - - JB comment: above isn't true--they only make one pass, over - the LNTT. */ - for (i = 0; i < 1; i++) - { - int within_function = 0; - - if (i) - symcount = GNTT_SYMCOUNT (objfile); - else - symcount = LNTT_SYMCOUNT (objfile); - - - for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++) - { - QUIT; - if (i) - dn_bufp = hpread_get_gntt (hp_symnum, objfile); - else - dn_bufp = hpread_get_lntt (hp_symnum, objfile); - - if (dn_bufp->dblock.extension) - continue; - - /* Only handle things which are necessary for minimal symbols. - everything else is ignored. */ - switch (dn_bufp->dblock.kind) - { - case DNTT_TYPE_SRCFILE: - { -#ifdef QUICK_LOOK_UP - if (scan_start == hp_symnum - && symcount == hp_symnum + 1) - { - /* If there are NO globals in an executable, - PXDB's index to the globals will point to - the last record in the file, which - could be this record. (this happened for F77 libraries) - ignore it and be done! */ - continue; - } -#endif /* QUICK_LOOK_UP */ - - /* A source file of some kind. Note this may simply - be an included file. */ - SET_NAMESTRING (dn_bufp, &namestring, objfile); - - /* Check if this is the source file we are already working - with. */ - if (pst && !strcmp (namestring, pst->filename)) - continue; - - /* Check if this is an include file, if so check if we have - already seen it. Add it to the include list */ - p = strrchr (namestring, '.'); - if (!strcmp (p, ".h")) - { - int j, found; - - found = 0; - for (j = 0; j < includes_used; j++) - if (!strcmp (namestring, psymtab_include_list[j])) - { - found = 1; - break; - } - if (found) - continue; - - /* Add it to the list of includes seen so far and - allocate more include space if necessary. */ - psymtab_include_list[includes_used++] = namestring; - if (includes_used >= includes_allocated) - { - char **orig = psymtab_include_list; - - psymtab_include_list = (char **) - alloca ((includes_allocated *= 2) * - sizeof (char *)); - memcpy ((PTR) psymtab_include_list, (PTR) orig, - includes_used * sizeof (char *)); - } - continue; - } - - if (pst) - { - if (!have_name) - { - pst->filename = (char *) - obstack_alloc (&pst->objfile->psymbol_obstack, - strlen (namestring) + 1); - strcpy (pst->filename, namestring); - have_name = 1; - continue; - } - continue; - } - - /* This is a bonafide new source file. - End the current partial symtab and start a new one. */ - - if (pst && past_first_source_file) - { - hpread_end_psymtab (pst, psymtab_include_list, - includes_used, - (hp_symnum - * sizeof (struct dntt_type_block)), - texthigh, - dependency_list, dependencies_used); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } - else - past_first_source_file = 1; - - valu = hpread_get_textlow (i, hp_symnum, objfile, symcount); - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - pst = hpread_start_psymtab (objfile, section_offsets, - namestring, valu, - (hp_symnum - * sizeof (struct dntt_type_block)), - objfile->global_psymbols.next, - objfile->static_psymbols.next); - texthigh = valu; - have_name = 1; - continue; - } - - case DNTT_TYPE_MODULE: - /* A source file. It's still unclear to me what the - real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE - is supposed to be. */ - - /* First end the previous psymtab */ - if (pst) - { - hpread_end_psymtab (pst, psymtab_include_list, includes_used, - ((hp_symnum - 1) - * sizeof (struct dntt_type_block)), - texthigh, - dependency_list, dependencies_used); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - have_name = 0; - } - - /* Now begin a new module and a new psymtab for it */ - SET_NAMESTRING (dn_bufp, &namestring, objfile); - valu = hpread_get_textlow (i, hp_symnum, objfile, symcount); - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - if (!pst) - { - pst = hpread_start_psymtab (objfile, section_offsets, - namestring, valu, - (hp_symnum - * sizeof (struct dntt_type_block)), - objfile->global_psymbols.next, - objfile->static_psymbols.next); - texthigh = valu; - have_name = 0; - } - continue; - - case DNTT_TYPE_FUNCTION: - case DNTT_TYPE_ENTRY: - /* The beginning of a function. DNTT_TYPE_ENTRY may also denote - a secondary entry point. */ - valu = dn_bufp->dfunc.hiaddr + ANOFFSET (section_offsets, - SECT_OFF_TEXT); - if (valu > texthigh) - texthigh = valu; - valu = dn_bufp->dfunc.lowaddr + - ANOFFSET (section_offsets, SECT_OFF_TEXT); - SET_NAMESTRING (dn_bufp, &namestring, objfile); - if (dn_bufp->dfunc.global) - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->global_psymbols, valu, - 0, language_unknown, objfile); - else - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->static_psymbols, valu, - 0, language_unknown, objfile); - within_function = 1; - continue; - - case DNTT_TYPE_DOC_FUNCTION: - valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (section_offsets, - SECT_OFF_TEXT); - if (valu > texthigh) - texthigh = valu; - valu = dn_bufp->ddocfunc.lowaddr + - ANOFFSET (section_offsets, SECT_OFF_TEXT); - SET_NAMESTRING (dn_bufp, &namestring, objfile); - if (dn_bufp->ddocfunc.global) - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->global_psymbols, valu, - 0, language_unknown, objfile); - else - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->static_psymbols, valu, - 0, language_unknown, objfile); - within_function = 1; - continue; - - case DNTT_TYPE_BEGIN: - case DNTT_TYPE_END: - /* We don't check MODULE end here, because there can be - symbols beyond the module end which properly belong to the - current psymtab -- so we wait till the next MODULE start */ - - -#ifdef QUICK_LOOK_UP - if (scan_start == hp_symnum - && symcount == hp_symnum + 1) - { - /* If there are NO globals in an executable, - PXDB's index to the globals will point to - the last record in the file, which is - probably an END MODULE, i.e. this record. - ignore it and be done! */ - continue; - } -#endif /* QUICK_LOOK_UP */ - - /* Scope block begin/end. We only care about function - and file blocks right now. */ - - if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) || - (dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION)) - within_function = 0; - continue; - - case DNTT_TYPE_SVAR: - case DNTT_TYPE_DVAR: - case DNTT_TYPE_TYPEDEF: - case DNTT_TYPE_TAGDEF: - { - /* Variables, typedefs an the like. */ - enum address_class storage; - namespace_enum namespace; - - /* Don't add locals to the partial symbol table. */ - if (within_function - && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR - || dn_bufp->dblock.kind == DNTT_TYPE_DVAR)) - continue; - - /* TAGDEFs go into the structure namespace. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF) - namespace = STRUCT_NAMESPACE; - else - namespace = VAR_NAMESPACE; - - /* What kind of "storage" does this use? */ - if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR) - storage = LOC_STATIC; - else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR - && dn_bufp->ddvar.regvar) - storage = LOC_REGISTER; - else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR) - storage = LOC_LOCAL; - else - storage = LOC_UNDEF; - - SET_NAMESTRING (dn_bufp, &namestring, objfile); - if (!pst) - { - pst = hpread_start_psymtab (objfile, section_offsets, - "globals", 0, - (hp_symnum - * sizeof (struct dntt_type_block)), - objfile->global_psymbols.next, - objfile->static_psymbols.next); - } - - /* Compute address of the data symbol */ - valu = dn_bufp->dsvar.location; - /* Relocate in case it's in a shared library */ - if (storage == LOC_STATIC) - valu += ANOFFSET (section_offsets, SECT_OFF_DATA); - - /* Luckily, dvar, svar, typedef, and tagdef all - have their "global" bit in the same place, so it works - (though it's bad programming practice) to reference - "dsvar.global" even though we may be looking at - any of the above four types. */ - if (dn_bufp->dsvar.global) - { - add_psymbol_to_list (namestring, strlen (namestring), - namespace, storage, - &objfile->global_psymbols, - valu, - 0, language_unknown, objfile); - } - else - { - add_psymbol_to_list (namestring, strlen (namestring), - namespace, storage, - &objfile->static_psymbols, - valu, - 0, language_unknown, objfile); - } - - /* For TAGDEF's, the above code added the tagname to the - struct namespace. This will cause tag "t" to be found - on a reference of the form "(struct t) x". But for - C++ classes, "t" will also be a typename, which we - want to find on a reference of the form "ptype t". - Therefore, we also add "t" to the var namespace. - Do the same for enum's due to the way aCC generates - debug info for these (see more extended comment - in hp-symtab-read.c). - We do the same for templates, so that "ptype t" - where "t" is a template also works. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF && - dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile)) - { - int global = dn_bufp->dtag.global; - /* Look ahead to see if it's a C++ class */ - dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile); - if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS || - dn_bufp->dblock.kind == DNTT_TYPE_ENUM || - dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) - { - if (global) - { - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, storage, - &objfile->global_psymbols, - dn_bufp->dsvar.location, - 0, language_unknown, objfile); - } - else - { - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, storage, - &objfile->static_psymbols, - dn_bufp->dsvar.location, - 0, language_unknown, objfile); - } - } - } - } - continue; - - case DNTT_TYPE_MEMENUM: - case DNTT_TYPE_CONST: - /* Constants and members of enumerated types. */ - SET_NAMESTRING (dn_bufp, &namestring, objfile); - if (!pst) - { - pst = hpread_start_psymtab (objfile, section_offsets, - "globals", 0, - (hp_symnum - * sizeof (struct dntt_type_block)), - objfile->global_psymbols.next, - objfile->static_psymbols.next); - } - if (dn_bufp->dconst.global) - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, LOC_CONST, - &objfile->global_psymbols, 0, - 0, language_unknown, objfile); - else - add_psymbol_to_list (namestring, strlen (namestring), - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, 0, - 0, language_unknown, objfile); - continue; - default: - continue; - } - } - } - - /* End any pending partial symbol table. */ - if (pst) - { - hpread_end_psymtab (pst, psymtab_include_list, includes_used, - hp_symnum * sizeof (struct dntt_type_block), - 0, dependency_list, dependencies_used); - } - - discard_cleanups (old_chain); -} - -/* Perform any local cleanups required when we are done with a particular - objfile. I.E, we are in the process of discarding all symbol information - for an objfile, freeing up all memory held for it, and unlinking the - objfile struct from the global list of known objfiles. */ - -void -hpread_symfile_finish (objfile) - struct objfile *objfile; -{ - if (objfile->sym_private != NULL) - { - mfree (objfile->md, objfile->sym_private); - } -} - - -/* The remaining functions are all for internal use only. */ - -/* Various small functions to get entries in the debug symbol sections. */ - -union dnttentry * -hpread_get_lntt (index, objfile) - int index; - struct objfile *objfile; -{ - return (union dnttentry *) - &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]); -} - -static union dnttentry * -hpread_get_gntt (index, objfile) - int index; - struct objfile *objfile; -{ - return (union dnttentry *) - &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]); -} - -union sltentry * -hpread_get_slt (index, objfile) - int index; - struct objfile *objfile; -{ - return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]); -} - -/* Get the low address associated with some symbol (typically the start - of a particular source file or module). Since that information is not - stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we must infer it from - the existance of DNTT_TYPE_FUNCTION symbols. */ - -static unsigned long -hpread_get_textlow (global, index, objfile, symcount) - int global; - int index; - struct objfile *objfile; - int symcount; -{ - union dnttentry *dn_bufp; - struct minimal_symbol *msymbol; - - /* Look for a DNTT_TYPE_FUNCTION symbol. */ - if (index < symcount) /* symcount is the number of symbols in */ - { /* the dbinfo, LNTT table */ - do - { - if (global) - dn_bufp = hpread_get_gntt (index++, objfile); - else - dn_bufp = hpread_get_lntt (index++, objfile); - } - while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION - && dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION - && dn_bufp->dblock.kind != DNTT_TYPE_END - && index < symcount); - } - - /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION. This - might happen when a sourcefile has no functions. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_END) - return 0; - - /* Avoid going past the end of the LNTT file */ - if (index == symcount) - return 0; - - /* The minimal symbols are typically more accurate for some reason. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION) - msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL, - objfile); - else /* must be a DNTT_TYPE_DOC_FUNCTION */ - msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL, - objfile); - - if (msymbol) - return SYMBOL_VALUE_ADDRESS (msymbol); - else - return dn_bufp->dfunc.lowaddr; -} - -/* Allocate and partially fill a partial symtab. It will be - completely filled at the end of the symbol list. - - SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR - is the address relative to which its symbols are (incremental) or 0 - (normal). */ - -static struct partial_symtab * -hpread_start_psymtab (objfile, section_offsets, - filename, textlow, ldsymoff, global_syms, static_syms) - struct objfile *objfile; - struct section_offsets *section_offsets; - char *filename; - CORE_ADDR textlow; - int ldsymoff; - struct partial_symbol **global_syms; - struct partial_symbol **static_syms; -{ - int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT); - extern void hpread_psymtab_to_symtab (); - struct partial_symtab *result = - start_psymtab_common (objfile, section_offsets, - filename, textlow, global_syms, static_syms); - - result->textlow += offset; - result->read_symtab_private = (char *) - obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc)); - LDSYMOFF (result) = ldsymoff; - result->read_symtab = hpread_psymtab_to_symtab; - - return result; -} - - -/* Close off the current usage of PST. - Returns PST or NULL if the partial symtab was empty and thrown away. - - capping_symbol_offset --Byte index in LNTT or GNTT of the - last symbol processed during the build - of the previous pst. - - FIXME: List variables and peculiarities of same. */ - -static struct partial_symtab * -hpread_end_psymtab (pst, include_list, num_includes, capping_symbol_offset, - capping_text, dependency_list, number_dependencies) - struct partial_symtab *pst; - char **include_list; - int num_includes; - int capping_symbol_offset; - CORE_ADDR capping_text; - struct partial_symtab **dependency_list; - int number_dependencies; -{ - int i; - struct objfile *objfile = pst->objfile; - int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT); - -#ifdef DUMPING - /* Turn on to see what kind of a psymtab we've built. */ - static int dumping = 0; -#endif - - if (capping_symbol_offset != -1) - LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst); - else - LDSYMLEN (pst) = 0; - pst->texthigh = capping_text + offset; - - pst->n_global_syms = - objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset); - pst->n_static_syms = - objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset); - -#ifdef DUMPING - if (dumping) - { - printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n", - pst->filename, - LDSYMOFF (pst), - LDSYMOFF (pst) / sizeof (struct dntt_type_block), - LDSYMLEN (pst), - LDSYMLEN (pst) / sizeof (struct dntt_type_block), - pst->n_global_syms, pst->n_static_syms); - } -#endif - - pst->number_of_dependencies = number_dependencies; - if (number_dependencies) - { - pst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, - number_dependencies * sizeof (struct partial_symtab *)); - memcpy (pst->dependencies, dependency_list, - number_dependencies * sizeof (struct partial_symtab *)); - } - else - pst->dependencies = 0; - - for (i = 0; i < num_includes; i++) - { - struct partial_symtab *subpst = - allocate_psymtab (include_list[i], objfile); - - subpst->section_offsets = pst->section_offsets; - subpst->read_symtab_private = - (char *) obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct symloc)); - LDSYMOFF (subpst) = - LDSYMLEN (subpst) = - subpst->textlow = - subpst->texthigh = 0; - - /* We could save slight bits of space by only making one of these, - shared by the entire set of include files. FIXME-someday. */ - subpst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct partial_symtab *)); - subpst->dependencies[0] = pst; - subpst->number_of_dependencies = 1; - - subpst->globals_offset = - subpst->n_global_syms = - subpst->statics_offset = - subpst->n_static_syms = 0; - - subpst->readin = 0; - subpst->symtab = 0; - subpst->read_symtab = pst->read_symtab; - } - - sort_pst_symbols (pst); - - /* If there is already a psymtab or symtab for a file of this name, remove it. - (If there is a symtab, more drastic things also happen.) - This happens in VxWorks. */ - 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. - 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. - It's also wrong if we're using the quick look-up tables, as - we can get empty psymtabs from modules with no routines in - them. */ - - discard_psymtab (pst); - - /* Indicate that psymtab was thrown away. */ - pst = (struct partial_symtab *) NULL; - - } - return pst; -} - - -/* End of hp-psymtab-read.c */ - -/* Set indentation to 4 spaces for Emacs; this file is - mostly non-GNU-ish in its style :-( */ -#if 0 -***Local Variables: -***c - basic - offset:4 -*** End: -#endif - - diff --git a/contrib/gdb/gdb/hp-symtab-read.c b/contrib/gdb/gdb/hp-symtab-read.c deleted file mode 100644 index 90d4a10c6bc..00000000000 --- a/contrib/gdb/gdb/hp-symtab-read.c +++ /dev/null @@ -1,3988 +0,0 @@ -/* Read hp debug symbols and convert to internal format, for GDB. - Copyright 1993, 1996 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Written by the Center for Software Science at the University of Utah - and by Cygnus Support. */ - -/* Common include for hp-symtab-read.c and hp-psymtab-read.c. - * Note this has nested includes for a bunch of stuff. - */ -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "hpread.h" -#include "demangle.h" -#include "complaints.h" - - - - -static struct complaint hpread_unhandled_end_common_complaint = -{ - "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n", 0, 0 -}; - -static struct complaint hpread_unhandled_type_complaint = -{ - "hpread_type_translate: unhandled type code.", 0, 0 -}; - -static struct complaint hpread_struct_complaint = -{ - "hpread_read_struct_type: expected SVAR type...", 0, 0 -}; - -static struct complaint hpread_array_complaint = -{ - "error in hpread_array_type.", 0, 0 -}; - -static struct complaint hpread_type_lookup_complaint = -{ - "error in hpread_type_lookup().", 0, 0 -}; - - -static struct complaint hpread_unexpected_end_complaint = -{ - "internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind.", 0, 0 -}; - -static struct complaint hpread_tagdef_complaint = -{ - "error processing class tagdef", 0, 0 -}; - -static struct complaint hpread_unhandled_common_complaint = -{ - "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON.", 0, 0 -}; - -static struct complaint hpread_unhandled_blockdata_complaint = -{ - "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA.", 0, 0 -}; - - -/* Forward procedure declarations */ - -static unsigned long hpread_get_scope_start - PARAMS ((sltpointer, struct objfile *)); - -static unsigned long hpread_get_line - PARAMS ((sltpointer, struct objfile *)); - -static CORE_ADDR hpread_get_location - PARAMS ((sltpointer, struct objfile *)); - -static void hpread_psymtab_to_symtab_1 - PARAMS ((struct partial_symtab *)); - -void hpread_psymtab_to_symtab - PARAMS ((struct partial_symtab *)); - -static struct symtab *hpread_expand_symtab - PARAMS ((struct objfile *, int, int, CORE_ADDR, int, - struct section_offsets *, char *)); - -static int hpread_type_translate - PARAMS ((dnttpointer)); - -static struct type **hpread_lookup_type - PARAMS ((dnttpointer, struct objfile *)); - -static struct type *hpread_alloc_type - PARAMS ((dnttpointer, struct objfile *)); - -static struct type *hpread_read_enum_type - PARAMS ((dnttpointer, union dnttentry *, struct objfile *)); - -static struct type *hpread_read_function_type - PARAMS ((dnttpointer, union dnttentry *, struct objfile *, int)); - -static struct type *hpread_read_doc_function_type - PARAMS ((dnttpointer, union dnttentry *, struct objfile *, int)); - -static struct type *hpread_read_struct_type - PARAMS ((dnttpointer, union dnttentry *, struct objfile *)); - -static struct type *hpread_get_nth_template_arg - PARAMS ((struct objfile *, int)); - -static struct type * hpread_read_templ_arg_type - PARAMS ((dnttpointer, union dnttentry *, struct objfile *, char *)); - -static struct type *hpread_read_set_type - PARAMS ((dnttpointer, union dnttentry *, struct objfile *)); - -static struct type * hpread_read_array_type - PARAMS ((dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile)); - -static struct type *hpread_read_subrange_type - PARAMS ((dnttpointer, union dnttentry *, struct objfile *)); - -static struct type * hpread_type_lookup - PARAMS ((dnttpointer, struct objfile *)); - -static sltpointer hpread_record_lines - PARAMS ((struct subfile *, sltpointer, sltpointer, - struct objfile *, CORE_ADDR)); - -static void hpread_process_one_debug_symbol - PARAMS ((union dnttentry *, char *, struct section_offsets *, - struct objfile *, CORE_ADDR, int, char *, int, int * )); - -static int hpread_get_scope_depth - PARAMS ((union dnttentry *, struct objfile *, int)); - -static void fix_static_member_physnames - PARAMS ((struct type *, char *, struct objfile *)); - -static void fixup_class_method_type - PARAMS ((struct type *, struct type *, struct objfile *)); - -static void hpread_adjust_bitoffsets PARAMS ((struct type *, int)); - -static dnttpointer hpread_get_next_skip_over_anon_unions - PARAMS ((int, dnttpointer, union dnttentry **, struct objfile *)); - -/* Global to indicate presence of HP-compiled objects, - in particular, SOM executable file with SOM debug info - Defined in symtab.c, used in hppa-tdep.c. */ -extern int hp_som_som_object_present; - -/* Static used to indicate a class type that requires a - fix-up of one of its method types */ -static struct type * fixup_class = NULL; - -/* Static used to indicate the method type that is to be - used to fix-up the type for fixup_class */ -static struct type * fixup_method = NULL; - - - -/* Get the nesting depth for the source line identified by INDEX. */ - -static unsigned long -hpread_get_scope_start (index, objfile) - sltpointer index; - struct objfile *objfile; -{ - union sltentry *sl_bufp; - - sl_bufp = hpread_get_slt (index, objfile); - return sl_bufp->sspec.backptr.dnttp.index; -} - -/* Get the source line number the the line identified by INDEX. */ - -static unsigned long -hpread_get_line (index, objfile) - sltpointer index; - struct objfile *objfile; -{ - union sltentry *sl_bufp; - - sl_bufp = hpread_get_slt (index, objfile); - return sl_bufp->snorm.line; -} - -/* Find the code address associated with a given sltpointer */ - -static CORE_ADDR -hpread_get_location (index, objfile) - sltpointer index; - struct objfile *objfile; -{ - union sltentry *sl_bufp; - int i; - - /* code location of special sltentrys is determined from context */ - sl_bufp = hpread_get_slt (index, objfile); - - if (sl_bufp->snorm.sltdesc == SLT_END) - { - /* find previous normal sltentry and get address */ - for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) && - (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) && - (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++) - sl_bufp = hpread_get_slt (index - i, objfile); - if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET) - return sl_bufp->snormoff.address; - else - return sl_bufp->snorm.address; - } - - /* find next normal sltentry and get address */ - for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) && - (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) && - (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++) - sl_bufp = hpread_get_slt (index + i, objfile); - if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET) - return sl_bufp->snormoff.address; - else - return sl_bufp->snorm.address; -} - - -/* Return 1 if an HP debug symbol of type KIND has a name associated with - * it, else return 0. (This function is not currently used, but I'll - * leave it here in case it proves useful later on. - RT). - */ - -int -hpread_has_name (kind) - enum dntt_entry_type kind; -{ - switch (kind) - { - case DNTT_TYPE_SRCFILE: - case DNTT_TYPE_MODULE: - case DNTT_TYPE_FUNCTION: - case DNTT_TYPE_DOC_FUNCTION: - case DNTT_TYPE_ENTRY: - case DNTT_TYPE_IMPORT: - case DNTT_TYPE_LABEL: - case DNTT_TYPE_FPARAM: - case DNTT_TYPE_SVAR: - case DNTT_TYPE_DVAR: - case DNTT_TYPE_CONST: - case DNTT_TYPE_TYPEDEF: - case DNTT_TYPE_TAGDEF: - case DNTT_TYPE_MEMENUM: - case DNTT_TYPE_FIELD: - case DNTT_TYPE_SA: - case DNTT_TYPE_BLOCKDATA: - case DNTT_TYPE_MEMFUNC: - case DNTT_TYPE_DOC_MEMFUNC: - return 1; - - case DNTT_TYPE_BEGIN: - case DNTT_TYPE_END: - case DNTT_TYPE_POINTER: - case DNTT_TYPE_ENUM: - case DNTT_TYPE_SET: - case DNTT_TYPE_ARRAY: - case DNTT_TYPE_STRUCT: - case DNTT_TYPE_UNION: - case DNTT_TYPE_VARIANT: - case DNTT_TYPE_FILE: - case DNTT_TYPE_FUNCTYPE: - case DNTT_TYPE_SUBRANGE: - case DNTT_TYPE_WITH: - case DNTT_TYPE_COMMON: - case DNTT_TYPE_COBSTRUCT: - case DNTT_TYPE_XREF: - case DNTT_TYPE_MACRO: - case DNTT_TYPE_CLASS_SCOPE: - case DNTT_TYPE_REFERENCE: - case DNTT_TYPE_PTRMEM: - case DNTT_TYPE_PTRMEMFUNC: - case DNTT_TYPE_CLASS: - case DNTT_TYPE_GENFIELD: - case DNTT_TYPE_VFUNC: - case DNTT_TYPE_MEMACCESS: - case DNTT_TYPE_INHERITANCE: - case DNTT_TYPE_FRIEND_CLASS: - case DNTT_TYPE_FRIEND_FUNC: - case DNTT_TYPE_MODIFIER: - case DNTT_TYPE_OBJECT_ID: - case DNTT_TYPE_TEMPLATE: - case DNTT_TYPE_TEMPLATE_ARG: - case DNTT_TYPE_FUNC_TEMPLATE: - case DNTT_TYPE_LINK: - /* DNTT_TYPE_DYN_ARRAY_DESC ? */ - /* DNTT_TYPE_DESC_SUBRANGE ? */ - /* DNTT_TYPE_BEGIN_EXT ? */ - /* DNTT_TYPE_INLN ? */ - /* DNTT_TYPE_INLN_LIST ? */ - /* DNTT_TYPE_ALIAS ? */ - default: - return 0; - } -} - -/* Do the dirty work of reading in the full symbol from a partial symbol - table. */ - -static void -hpread_psymtab_to_symtab_1 (pst) - struct partial_symtab *pst; -{ - struct cleanup *old_chain; - int i; - - /* Get out quick if passed junk. */ - if (!pst) - return; - - /* Complain if we've already read in this symbol table. */ - if (pst->readin) - { - fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n", - pst->filename); - return; - } - - /* Read in all partial symtabs on which this one is dependent */ - for (i = 0; i < pst->number_of_dependencies; i++) - if (!pst->dependencies[i]->readin) - { - /* Inform about additional files that need to be read in. */ - if (info_verbose) - { - fputs_filtered (" ", gdb_stdout); - wrap_here (""); - fputs_filtered ("and ", gdb_stdout); - wrap_here (""); - printf_filtered ("%s...", pst->dependencies[i]->filename); - wrap_here (""); /* Flush output */ - gdb_flush (gdb_stdout); - } - hpread_psymtab_to_symtab_1 (pst->dependencies[i]); - } - - /* If it's real... */ - if (LDSYMLEN (pst)) - { - /* Init stuff necessary for reading in symbols */ - buildsym_init (); - old_chain = make_cleanup (really_free_pendings, 0); - - pst->symtab = - hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst), - pst->textlow, pst->texthigh - pst->textlow, - pst->section_offsets, pst->filename); - sort_symtab_syms (pst->symtab); - - do_cleanups (old_chain); - } - - pst->readin = 1; -} - -/* Read in all of the symbols for a given psymtab for real. - Be verbose about it if the user wants that. */ - -void -hpread_psymtab_to_symtab (pst) - struct partial_symtab *pst; -{ - /* Get out quick if given junk. */ - if (!pst) - return; - - /* Sanity check. */ - if (pst->readin) - { - fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n", - pst->filename); - return; - } - - /* elz: setting the flag to indicate that the code of the target - was compiled using an HP compiler (aCC, cc) - the processing_acc_compilation variable is declared in the - file buildsym.h, the HP_COMPILED_TARGET is defined to be equal - to 3 in the file tm_hppa.h*/ - - processing_gcc_compilation = 0; - - if (LDSYMLEN (pst) || pst->number_of_dependencies) - { - /* Print the message now, before reading the string table, - to avoid disconcerting pauses. */ - if (info_verbose) - { - printf_filtered ("Reading in symbols for %s...", pst->filename); - gdb_flush (gdb_stdout); - } - - hpread_psymtab_to_symtab_1 (pst); - - /* Match with global symbols. This only needs to be done once, - after all of the symtabs and dependencies have been read in. */ - scan_file_globals (pst->objfile); - - /* Finish up the debug error message. */ - if (info_verbose) - printf_filtered ("done.\n"); - } -} - -/* Read in a defined section of a specific object file's symbols. - - DESC is the file descriptor for the file, positioned at the - beginning of the symtab - SYM_OFFSET is the offset within the file of - the beginning of the symbols we want to read - SYM_SIZE is the size of the symbol info to read in. - TEXT_OFFSET is the beginning of the text segment we are reading symbols for - TEXT_SIZE is the size of the text segment read in. - SECTION_OFFSETS are the relocation offsets which get added to each symbol. */ - -static struct symtab * -hpread_expand_symtab (objfile, sym_offset, sym_size, text_offset, text_size, - section_offsets, filename) - struct objfile *objfile; - int sym_offset; - int sym_size; - CORE_ADDR text_offset; - int text_size; - struct section_offsets *section_offsets; - char *filename; -{ - char *namestring; - union dnttentry *dn_bufp; - unsigned max_symnum; - int at_module_boundary = 0; - /* 1 => at end, -1 => at beginning */ - - int sym_index = sym_offset / sizeof (struct dntt_type_block); - - current_objfile = objfile; - subfile_stack = 0; - - last_source_file = 0; - - /* Demangling style -- if EDG style already set, don't change it, - as HP style causes some problems with the KAI EDG compiler */ - if (current_demangling_style != edg_demangling) { - /* Otherwise, ensure that we are using HP style demangling */ - set_demangling_style (HP_DEMANGLING_STYLE_STRING); - } - - dn_bufp = hpread_get_lntt (sym_index, objfile); - if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) || - (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE))) - { - start_symtab ("globals", NULL, 0); - record_debugformat ("HP"); - } - - /* The psymtab builder (hp-psymtab-read.c) is the one that - * determined the "sym_size" argument (i.e. how many DNTT symbols - * are in this symtab), which we use to compute "max_symnum" - * (point in DNTT to which we read). - * - * Perhaps this should be changed so that - * process_one_debug_symbol() "knows" when - * to stop reading (based on reading from the MODULE to the matching - * END), and take out this reliance on a #-syms being passed in... - * (I'm worried about the reliability of this number). But I'll - * leave it as-is, for now. - RT - * - * The change above has been made. I've left the "for" loop control - * in to prepare for backing this out again. -JB - */ - max_symnum = sym_size / sizeof (struct dntt_type_block); - /* No reason to multiply on pst side and divide on sym side... FIXME */ - - /* Read in and process each debug symbol within the specified range. - */ - for (symnum = 0; - symnum < max_symnum; - symnum++) - { - QUIT; /* Allow this to be interruptable */ - dn_bufp = hpread_get_lntt (sym_index + symnum, objfile); - - if (dn_bufp->dblock.extension) - continue; - - /* Yow! We call SET_NAMESTRING on things without names! */ - SET_NAMESTRING (dn_bufp, &namestring, objfile); - - hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets, - objfile, text_offset, text_size, - filename, symnum + sym_index, - &at_module_boundary - ); - - /* OLD COMMENTS: This routine is only called for psts. All psts - * correspond to MODULES. If we ever do lazy-reading of globals - * from the LNTT, then there will be a pst which ends when the - * LNTT ends, and not at an END MODULE entry. Then we'll have - * to re-visit this break. - - if( at_end_of_module ) - break; - - */ - - /* We no longer break out of the loop when we reach the end of a - module. The reason is that with CTTI, the compiler can generate - function symbols (for template function instantiations) which are not - in any module; typically they show up beyond a module's end, and - before the next module's start. We include them in the current - module. However, we still don't trust the MAX_SYMNUM value from - the psymtab, so we break out if we enter a new module. */ - - if (at_module_boundary == -1) - break; - } - - current_objfile = NULL; - hp_som_som_object_present = 1; /* Indicate we've processed an HP SOM SOM file */ - - return end_symtab (text_offset + text_size, objfile, 0); -} - - - - -/* Convert basic types from HP debug format into GDB internal format. */ - -static int -hpread_type_translate (typep) - dnttpointer typep; -{ - if (!typep.dntti.immediate) { - error ("error in hpread_type_translate\n."); - return; - } - - switch (typep.dntti.type) - { - case HP_TYPE_BOOLEAN: - case HP_TYPE_BOOLEAN_S300_COMPAT: - case HP_TYPE_BOOLEAN_VAX_COMPAT: - return FT_BOOLEAN; - case HP_TYPE_CHAR: /* C signed char, C++ plain char */ - - case HP_TYPE_WIDE_CHAR: - return FT_CHAR; - case HP_TYPE_INT: - if (typep.dntti.bitlength <= 8) - return FT_SIGNED_CHAR; /* C++ signed char */ - if (typep.dntti.bitlength <= 16) - return FT_SHORT; - if (typep.dntti.bitlength <= 32) - return FT_INTEGER; - return FT_LONG_LONG; - case HP_TYPE_LONG: - if (typep.dntti.bitlength <= 8) - return FT_SIGNED_CHAR; /* C++ signed char. */ - return FT_LONG; - case HP_TYPE_UNSIGNED_LONG: - if (typep.dntti.bitlength <= 8) - return FT_UNSIGNED_CHAR; /* C/C++ unsigned char */ - if (typep.dntti.bitlength <= 16) - return FT_UNSIGNED_SHORT; - if (typep.dntti.bitlength <= 32) - return FT_UNSIGNED_LONG; - return FT_UNSIGNED_LONG_LONG; - case HP_TYPE_UNSIGNED_INT: - if (typep.dntti.bitlength <= 8) - return FT_UNSIGNED_CHAR; - if (typep.dntti.bitlength <= 16) - return FT_UNSIGNED_SHORT; - if (typep.dntti.bitlength <= 32) - return FT_UNSIGNED_INTEGER; - return FT_UNSIGNED_LONG_LONG; - case HP_TYPE_REAL: - case HP_TYPE_REAL_3000: - case HP_TYPE_DOUBLE: - if (typep.dntti.bitlength == 64) - return FT_DBL_PREC_FLOAT; - if (typep.dntti.bitlength == 128) - return FT_EXT_PREC_FLOAT; - return FT_FLOAT; - case HP_TYPE_COMPLEX: - case HP_TYPE_COMPLEXS3000: - if (typep.dntti.bitlength == 128) - return FT_DBL_PREC_COMPLEX; - if (typep.dntti.bitlength == 192) - return FT_EXT_PREC_COMPLEX; - return FT_COMPLEX; - case HP_TYPE_VOID: - return FT_VOID; - case HP_TYPE_STRING200: - case HP_TYPE_LONGSTRING200: - case HP_TYPE_FTN_STRING_SPEC: - case HP_TYPE_MOD_STRING_SPEC: - case HP_TYPE_MOD_STRING_3000: - case HP_TYPE_FTN_STRING_S300_COMPAT: - case HP_TYPE_FTN_STRING_VAX_COMPAT: - return FT_STRING; - case HP_TYPE_TEMPLATE_ARG: - return FT_TEMPLATE_ARG; - case HP_TYPE_TEXT: - case HP_TYPE_FLABEL: - case HP_TYPE_PACKED_DECIMAL: - case HP_TYPE_ANYPOINTER: - case HP_TYPE_GLOBAL_ANYPOINTER: - case HP_TYPE_LOCAL_ANYPOINTER: - default: - warning ("hpread_type_translate: unhandled type code.\n"); - return FT_VOID; - } -} - -/* Given a position in the DNTT, return a pointer to the - * already-built "struct type" (if any), for the type defined - * at that position. - */ - -static struct type ** -hpread_lookup_type (hp_type, objfile) - dnttpointer hp_type; - struct objfile *objfile; -{ - unsigned old_len; - int index = hp_type.dnttp.index; - int size_changed = 0; - - /* The immediate flag indicates this doesn't actually point to - * a type DNTT. - */ - if (hp_type.dntti.immediate) - return NULL; - - /* For each objfile, we maintain a "type vector". - * This an array of "struct type *"'s with one pointer per DNTT index. - * Given a DNTT index, we look in this array to see if we have - * already processed this DNTT and if it is a type definition. - * If so, then we can locate a pointer to the already-built - * "struct type", and not build it again. - * - * The need for this arises because our DNTT-walking code wanders - * around. In particular, it will encounter the same type multiple - * times (once for each object of that type). We don't want to - * built multiple "struct type"'s for the same thing. - * - * Having said this, I should point out that this type-vector is - * an expensive way to keep track of this. If most DNTT entries are - * 3 words, the type-vector will be 1/3 the size of the DNTT itself. - * Alternative solutions: - * - Keep a compressed or hashed table. Less memory, but more expensive - * to search and update. - * - (Suggested by JB): Overwrite the DNTT entry itself - * with the info. Create a new type code "ALREADY_BUILT", and modify - * the DNTT to have that type code and point to the already-built entry. - * -RT - */ - - if (index < LNTT_SYMCOUNT (objfile)) - { - if (index >= TYPE_VECTOR_LENGTH (objfile)) - { - old_len = TYPE_VECTOR_LENGTH (objfile); - - /* See if we need to allocate a type-vector. */ - if (old_len == 0) - { - TYPE_VECTOR_LENGTH(objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile); - TYPE_VECTOR (objfile) = (struct type **) - xmmalloc (objfile->md, TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)); - memset (&TYPE_VECTOR (objfile)[old_len], 0, - (TYPE_VECTOR_LENGTH (objfile) - old_len) * - sizeof (struct type *)); - } - - /* See if we need to resize type-vector. With my change to - * initially allocate a correct-size type-vector, this code - * should no longer trigger. - */ - while (index >= TYPE_VECTOR_LENGTH (objfile)) { - TYPE_VECTOR_LENGTH (objfile) *= 2; - size_changed = 1; - } - if (size_changed) { - TYPE_VECTOR (objfile) = (struct type **) - xmrealloc (objfile -> md, - (char *) TYPE_VECTOR (objfile), - (TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *))); - - memset (&TYPE_VECTOR (objfile)[old_len], 0, - (TYPE_VECTOR_LENGTH (objfile) - old_len) * - sizeof (struct type *)); - } - - } - return &TYPE_VECTOR (objfile)[index]; - } - else - return NULL; -} - -/* Possibly allocate a GDB internal type so we can internalize HP_TYPE. - Note we'll just return the address of a GDB internal type if we already - have it lying around. */ - -static struct type * -hpread_alloc_type (hp_type, objfile) - dnttpointer hp_type; - struct objfile *objfile; -{ - struct type **type_addr; - - type_addr = hpread_lookup_type (hp_type, objfile); - if (*type_addr == 0) { - *type_addr = alloc_type (objfile); - - /* A hack - if we really are a C++ class symbol, then this default - * will get overriden later on. - */ - TYPE_CPLUS_SPECIFIC (*type_addr) - = (struct cplus_struct_type *) &cplus_struct_default; - } - - return *type_addr; -} - -/* Read a native enumerated type and return it in GDB internal form. */ - -static struct type * -hpread_read_enum_type (hp_type, dn_bufp, objfile) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; -{ - struct type *type; - struct pending **symlist, *osyms, *syms; - struct pending *local_list = NULL; - int o_nsyms, nsyms = 0; - dnttpointer mem; - union dnttentry *memp; - char *name; - long n; - struct symbol *sym; - - /* Allocate a GDB type. If we've already read in this enum type, - * it'll return the already built GDB type, so stop here. - * (Note: I added this check, to conform with what's done for - * struct, union, class. - * I assume this is OK. - RT) - */ - type = hpread_alloc_type (hp_type, objfile); - if (TYPE_CODE (type) == TYPE_CODE_ENUM) - return type; - - /* HP C supports "sized enums", where a specifier such as "short" or - "char" can be used to get enums of different sizes. So don't assume - an enum is always 4 bytes long. pai/1997-08-21 */ - TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8; - - symlist = &file_symbols; - osyms = *symlist; - o_nsyms = osyms ? osyms->nsyms : 0; - - /* Get a name for each member and add it to our list of members. - * The list of "mem" SOM records we are walking should all be - * SOM type DNTT_TYPE_MEMENUM (not checked). - */ - mem = dn_bufp->denum.firstmem; - while (mem.word && mem.word != DNTTNIL) - { - memp = hpread_get_lntt (mem.dnttp.index, objfile); - - name = VT (objfile) + memp->dmember.name; - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - &objfile->symbol_obstack); - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_VALUE (sym) = memp->dmember.value; - add_symbol_to_list (sym, symlist); - nsyms++; - mem = memp->dmember.nextmem; - } - - /* Now that we know more about the enum, fill in more info. */ - TYPE_CODE (type) = TYPE_CODE_ENUM; - TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; - TYPE_NFIELDS (type) = nsyms; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nsyms); - - /* Find the symbols for the members and put them into the type. - The symbols can be found in the symlist that we put them on - to cause them to be defined. osyms contains the old value - of that symlist; everything up to there was defined by us. - - Note that we preserve the order of the enum constants, so - that in something like "enum {FOO, LAST_THING=FOO}" we print - FOO, not LAST_THING. */ - for (syms = *symlist, n = 0; syms; syms = syms->next) - { - int j = 0; - if (syms == osyms) - j = o_nsyms; - for (; j < syms->nsyms; j++, n++) - { - struct symbol *xsym = syms->symbol[j]; - SYMBOL_TYPE (xsym) = type; - TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym); - TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); - TYPE_FIELD_BITSIZE (type, n) = 0; - } - if (syms == osyms) - break; - } - - return type; -} - -/* Read and internalize a native function debug symbol. */ - -static struct type * -hpread_read_function_type (hp_type, dn_bufp, objfile, newblock) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; - int newblock; -{ - struct type *type, *type1; - struct pending *syms; - struct pending *local_list = NULL; - int nsyms = 0; - dnttpointer param; - union dnttentry *paramp; - char *name; - long n; - struct symbol *sym; - int record_args = 1; - - /* See if we've already read in this type. */ - type = hpread_alloc_type (hp_type, objfile); - if (TYPE_CODE (type) == TYPE_CODE_FUNC) - { - record_args = 0; /* already read in, don't modify type */ - } - else - { - /* Nope, so read it in and store it away. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION || - dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC) - type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval, - objfile)); - else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE) - type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval, - objfile)); - else /* expect DNTT_TYPE_FUNC_TEMPLATE */ - type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval, - objfile)); - memcpy ((char *) type, (char *) type1, sizeof (struct type)); - - /* Mark it -- in the middle of processing */ - TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE; - } - - /* Now examine each parameter noting its type, location, and a - wealth of other information. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION || - dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC) - param = dn_bufp->dfunc.firstparam; - else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE) - param = dn_bufp->dfunctype.firstparam; - else /* expect DNTT_TYPE_FUNC_TEMPLATE */ - param = dn_bufp->dfunc_template.firstparam; - while (param.word && param.word != DNTTNIL) - { - paramp = hpread_get_lntt (param.dnttp.index, objfile); - nsyms++; - param = paramp->dfparam.nextparam; - - /* Get the name. */ - name = VT (objfile) + paramp->dfparam.name; - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - (void) memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - &objfile->symbol_obstack); - - /* Figure out where it lives. */ - if (paramp->dfparam.regparam) - SYMBOL_CLASS (sym) = LOC_REGPARM; - else if (paramp->dfparam.indirect) - SYMBOL_CLASS (sym) = LOC_REF_ARG; - else - SYMBOL_CLASS (sym) = LOC_ARG; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (paramp->dfparam.copyparam) - { - SYMBOL_VALUE (sym) = paramp->dfparam.location ; -#ifdef HPREAD_ADJUST_STACK_ADDRESS - SYMBOL_VALUE (sym) - += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); -#endif - /* This is likely a pass-by-invisible reference parameter, - Hack on the symbol class to make GDB happy. */ - /* ??rehrauer: This appears to be broken w/r/t to passing - C values of type float and struct. Perhaps this ought - to be highighted as a special case, but for now, just - allowing these to be LOC_ARGs seems to work fine. - */ -#if 0 - SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; -#endif - } - else - SYMBOL_VALUE (sym) = paramp->dfparam.location; - - /* Get its type. */ - SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile); - /* Add it to the symbol list. */ - /* Note 1 (RT) At the moment, add_symbol_to_list() is also being - * called on FPARAM symbols from the process_one_debug_symbol() - * level... so parameters are getting added twice! (this shows - * up in the symbol dump you get from "maint print symbols ..."). - * Note 2 (RT) I took out the processing of FPARAM from the - * process_one_debug_symbol() level, so at the moment parameters are only - * being processed here. This seems to have no ill effect. - */ - /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put - each fparam on the local_symbols list from here. Now we use the - local_list to which fparams are added below, and set the param_symbols - global to point to that at the end of this routine. */ - /* elz: I added this new list of symbols which is local to the function. - this list is the one which is actually used to build the type for the - function rather than the gloabal list pointed to by symlist. - Using a global list to keep track of the parameters is wrong, because - this function is called recursively if one parameter happend to be - a function itself with more parameters in it. Adding parameters to the - same global symbol list would not work! - Actually it did work in case of cc compiled programs where you do - not check the parameter lists of the arguments. */ - add_symbol_to_list (sym, &local_list); - - } - - /* If type was read in earlier, don't bother with modifying - the type struct */ - if (!record_args) - goto finish; - - /* Note how many parameters we found. */ - TYPE_NFIELDS (type) = nsyms; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile->type_obstack, - sizeof (struct field) * nsyms); - - /* Find the symbols for the parameters and - use them to fill parameter-type information into the function-type. - The parameter symbols can be found in the local_list that we just put them on. */ - /* Note that we preserve the order of the parameters, so - that in something like "enum {FOO, LAST_THING=FOO}" we print - FOO, not LAST_THING. */ - - /* get the parameters types from the local list not the global list - so that the type can be correctly constructed for functions which - have function as parameters */ - for (syms = local_list, n = 0; syms; syms = syms->next) - { - int j = 0; - for (j=0; j < syms->nsyms; j++, n++) - { - struct symbol *xsym = syms->symbol[j]; - TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym); - TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym); - TYPE_FIELD_BITPOS (type, n) = n; - TYPE_FIELD_BITSIZE (type, n) = 0; - } - } - /* Mark it as having been processed */ - TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE); - - /* Check whether we need to fix-up a class type with this function's type */ - if (fixup_class && (fixup_method == type)) - { - fixup_class_method_type (fixup_class, fixup_method, objfile); - fixup_class = NULL; - fixup_method = NULL; - } - - /* Set the param list of this level of the context stack - to our local list. Do this only if this function was - called for creating a new block, and not if it was called - simply to get the function type. This prevents recursive - invocations from trashing param_symbols. */ -finish: - if (newblock) - param_symbols = local_list; - - return type; -} - - -/* Read and internalize a native DOC function debug symbol. */ -/* This is almost identical to hpread_read_function_type(), except - * for references to dn_bufp->ddocfunc instead of db_bufp->dfunc. - * Since debug information for DOC functions is more likely to be - * volatile, please leave it this way. - */ -static struct type * -hpread_read_doc_function_type (hp_type, dn_bufp, objfile, newblock) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; - int newblock; -{ - struct type *type, *type1; - struct pending *syms; - struct pending *local_list = NULL; - int nsyms = 0; - dnttpointer param; - union dnttentry *paramp; - char *name; - long n; - struct symbol *sym; - int record_args = 1; - - /* See if we've already read in this type. */ - type = hpread_alloc_type (hp_type, objfile); - if (TYPE_CODE (type) == TYPE_CODE_FUNC) - { - record_args = 0; /* already read in, don't modify type */ - } - else - { - /* Nope, so read it in and store it away. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION || - dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) - type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval, - objfile)); - memcpy ((char *) type, (char *) type1, sizeof (struct type)); - - /* Mark it -- in the middle of processing */ - TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE; - } - - /* Now examine each parameter noting its type, location, and a - wealth of other information. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION || - dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) - param = dn_bufp->ddocfunc.firstparam; - while (param.word && param.word != DNTTNIL) - { - paramp = hpread_get_lntt (param.dnttp.index, objfile); - nsyms++; - param = paramp->dfparam.nextparam; - - /* Get the name. */ - name = VT (objfile) + paramp->dfparam.name; - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - (void) memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = name; - - /* Figure out where it lives. */ - if (paramp->dfparam.regparam) - SYMBOL_CLASS (sym) = LOC_REGPARM; - else if (paramp->dfparam.indirect) - SYMBOL_CLASS (sym) = LOC_REF_ARG; - else - SYMBOL_CLASS (sym) = LOC_ARG; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (paramp->dfparam.copyparam) - { - SYMBOL_VALUE (sym) = paramp->dfparam.location ; -#ifdef HPREAD_ADJUST_STACK_ADDRESS - SYMBOL_VALUE (sym) - += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); -#endif - /* This is likely a pass-by-invisible reference parameter, - Hack on the symbol class to make GDB happy. */ - /* ??rehrauer: This appears to be broken w/r/t to passing - C values of type float and struct. Perhaps this ought - to be highighted as a special case, but for now, just - allowing these to be LOC_ARGs seems to work fine. - */ -#if 0 - SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; -#endif - } - else - SYMBOL_VALUE (sym) = paramp->dfparam.location; - - /* Get its type. */ - SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile); - /* Add it to the symbol list. */ - /* Note 1 (RT) At the moment, add_symbol_to_list() is also being - * called on FPARAM symbols from the process_one_debug_symbol() - * level... so parameters are getting added twice! (this shows - * up in the symbol dump you get from "maint print symbols ..."). - * Note 2 (RT) I took out the processing of FPARAM from the - * process_one_debug_symbol() level, so at the moment parameters are only - * being processed here. This seems to have no ill effect. - */ - /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put - each fparam on the local_symbols list from here. Now we use the - local_list to which fparams are added below, and set the param_symbols - global to point to that at the end of this routine. */ - - /* elz: I added this new list of symbols which is local to the function. - this list is the one which is actually used to build the type for the - function rather than the gloabal list pointed to by symlist. - Using a global list to keep track of the parameters is wrong, because - this function is called recursively if one parameter happend to be - a function itself with more parameters in it. Adding parameters to the - same global symbol list would not work! - Actually it did work in case of cc compiled programs where you do not check the - parameter lists of the arguments. */ - add_symbol_to_list (sym, &local_list); - } - - /* If type was read in earlier, don't bother with modifying - the type struct */ - if (!record_args) - goto finish; - - /* Note how many parameters we found. */ - TYPE_NFIELDS (type) = nsyms; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile->type_obstack, - sizeof (struct field) * nsyms); - - /* Find the symbols for the parameters and - use them to fill parameter-type information into the function-type. - The parameter symbols can be found in the local_list that we just put them on. */ - /* Note that we preserve the order of the parameters, so - that in something like "enum {FOO, LAST_THING=FOO}" we print - FOO, not LAST_THING. */ - - /* get the parameters types from the local list not the global list - so that the type can be correctly constructed for functions which - have function as parameters - */ - for (syms = local_list, n = 0; syms; syms = syms->next) - { - int j = 0; - for (j = 0; j < syms->nsyms; j++, n++) - { - struct symbol *xsym = syms->symbol[j]; - TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym); - TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym); - TYPE_FIELD_BITPOS (type, n) = n; - TYPE_FIELD_BITSIZE (type, n) = 0; - } - } - - /* Mark it as having been processed */ - TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE); - - /* Check whether we need to fix-up a class type with this function's type */ - if (fixup_class && (fixup_method == type)) - { - fixup_class_method_type (fixup_class, fixup_method, objfile); - fixup_class = NULL; - fixup_method = NULL; - } - - /* Set the param list of this level of the context stack - to our local list. Do this only if this function was - called for creating a new block, and not if it was called - simply to get the function type. This prevents recursive - invocations from trashing param_symbols. */ -finish: - if (newblock) - param_symbols = local_list; - - return type; -} - - - -/* A file-level variable which keeps track of the current-template - * being processed. Set in hpread_read_struct_type() while processing - * a template type. Referred to in hpread_get_nth_templ_arg(). - * Yes, this is a kludge, but it arises from the kludge that already - * exists in symtab.h, namely the fact that they encode - * "template argument n" with fundamental type FT_TEMPLATE_ARG and - * bitlength n. This means that deep in processing fundamental types - * I need to ask the question "what template am I in the middle of?". - * The alternative to stuffing a global would be to pass an argument - * down the chain of calls just for this purpose. - * - * There may be problems handling nested templates... tough. - */ -static struct type * current_template = NULL; - -/* Read in and internalize a structure definition. - * This same routine is called for struct, union, and class types. - * Also called for templates, since they build a very similar - * type entry as for class types. - */ - -static struct type * -hpread_read_struct_type (hp_type, dn_bufp, objfile) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; -{ - /* The data members get linked together into a list of struct nextfield's */ - struct nextfield - { - struct nextfield *next; - struct field field; - unsigned char attributes; /* store visibility and virtuality info */ -# define ATTR_VIRTUAL 1 -# define ATTR_PRIVATE 2 -# define ATTR_PROTECT 3 - }; - - - /* The methods get linked together into a list of struct next_fn_field's */ - struct next_fn_field - { - struct next_fn_field *next; - struct fn_fieldlist field; - struct fn_field fn_field; - int num_fn_fields; - }; - - /* The template args get linked together into a list of struct next_template's */ - struct next_template - { - struct next_template *next; - struct template_arg arg; - }; - - /* The template instantiations get linked together into a list of these... */ - struct next_instantiation - { - struct next_instantiation * next; - struct type * t; - }; - - struct type *type; - struct type *baseclass; - struct type *memtype; - struct nextfield *list = 0, *tmp_list = 0; - struct next_fn_field *fn_list = 0; - struct next_fn_field *fn_p; - struct next_template *t_new, *t_list = 0; - struct nextfield *new; - struct next_fn_field *fn_new; - struct next_instantiation *i_new, *i_list = 0; - int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0; - int n_base_classes = 0, n_templ_args = 0; - int ninstantiations = 0; - dnttpointer field, fn_field, parent; - union dnttentry *fieldp, *fn_fieldp, *parentp; - int i; - int static_member = 0; - int const_member = 0; - int volatile_member = 0; - unsigned long vtbl_offset; - int need_bitvectors = 0; - char * method_name = NULL; - char * method_alias = NULL; - - - /* Is it something we've already dealt with? */ - type = hpread_alloc_type (hp_type, objfile); - if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) || - (TYPE_CODE (type) == TYPE_CODE_UNION) || - (TYPE_CODE (type) == TYPE_CODE_CLASS) || - (TYPE_CODE (type) == TYPE_CODE_TEMPLATE)) - return type; - - /* Get the basic type correct. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT) - { - TYPE_CODE (type) = TYPE_CODE_STRUCT; - TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8; - } - else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION) - { - TYPE_CODE (type) = TYPE_CODE_UNION; - TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8; - } - else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) - { - TYPE_CODE (type) = TYPE_CODE_CLASS; - TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8; - - /* Overrides the TYPE_CPLUS_SPECIFIC(type) with allocated memory - * rather than &cplus_struct_default. - */ - allocate_cplus_struct_type(type); - - /* Fill in declared-type. - * (The C++ compiler will emit TYPE_CODE_CLASS - * for all 3 of "class", "struct" - * "union", and we have to look at the "class_decl" field if we - * want to know how it was really declared) - */ - /* (0==class, 1==union, 2==struct) */ - TYPE_DECLARED_TYPE(type) = dn_bufp->dclass.class_decl; - } - else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) - { - /* Get the basic type correct. */ - TYPE_CODE (type) = TYPE_CODE_TEMPLATE; - allocate_cplus_struct_type(type); - TYPE_DECLARED_TYPE(type) = DECLARED_TYPE_TEMPLATE; - } - else - return type; - - - TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; - - /* For classes, read the parent list. - * Question (RT): Do we need to do this for templates also? - */ - if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) { - - /* First read the parent-list (classes from which we derive fields) */ - parent = dn_bufp->dclass.parentlist; - while (parent.word && parent.word != DNTTNIL) { - parentp = hpread_get_lntt (parent.dnttp.index, objfile); - - /* "parentp" should point to a DNTT_TYPE_INHERITANCE record */ - - /* Get space to record the next field/data-member. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - FIELD_BITSIZE (list->field) = 0; - - /* The "classname" field is actually a DNTT pointer to the base class */ - baseclass = hpread_type_lookup (parentp->dinheritance.classname, - objfile); - FIELD_TYPE (list->field) = baseclass; - - list->field.name = type_name_no_tag(FIELD_TYPE (list->field)); - - list->attributes = 0; - - /* Check for virtuality of base, and set the - * offset of the base subobject within the object. - * (Offset set to -1 for virtual bases (for now).) - */ - if (parentp->dinheritance.Virtual) - { - B_SET(&(list->attributes), ATTR_VIRTUAL); - parentp->dinheritance.offset = -1; - } - else - FIELD_BITPOS (list->field) = parentp->dinheritance.offset; - - /* Check visibility */ - switch (parentp->dinheritance.visibility) - { - case 1: - B_SET(&(list->attributes), ATTR_PROTECT); - break; - case 2: - B_SET(&(list->attributes), ATTR_PRIVATE); - break; - } - - n_base_classes++; - nfields++; - - parent = parentp->dinheritance.next; - } - } - - /* For templates, read the template argument list. - * This must be done before processing the member list, because - * the member list may refer back to this. E.g.: - * template class q2 { - * public: - * T1 a; - * T2 b; - * }; - * We need to read the argument list "T1", "T2" first. - */ - if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) { - /* Kludge alert: This stuffs a global "current_template" which - * is referred to by hpread_get_nth_templ_arg(). The global - * is cleared at the end of this routine. - */ - current_template = type; - - /* Read in the argument list */ - field = dn_bufp->dtemplate.arglist; - while (field.word && field.word != DNTTNIL) { - /* Get this template argument*/ - fieldp = hpread_get_lntt (field.dnttp.index, objfile); - if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG) - { - warning ("Invalid debug info: Template argument entry is of wrong kind"); - break; - } - /* Bump the count */ - n_templ_args++; - /* Allocate and fill in a struct next_template */ - t_new = (struct next_template *) alloca (sizeof (struct next_template)); - t_new->next = t_list; - t_list = t_new; - t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name; - t_list->arg.type = hpread_read_templ_arg_type(field, fieldp, - objfile, t_list->arg.name); - /* Walk to the next template argument */ - field = fieldp->dtempl_arg.nextarg; - } - } - - TYPE_NTEMPLATE_ARGS(type) = n_templ_args; - - if (n_templ_args > 0) - TYPE_TEMPLATE_ARGS(type) = (struct template_arg *) - obstack_alloc (&objfile->type_obstack, sizeof (struct template_arg) * n_templ_args); - for (n = n_templ_args; t_list; t_list = t_list->next) - { - n -= 1; - TYPE_TEMPLATE_ARG(type, n) = t_list->arg; - } - - /* Next read in and internalize all the fields/members. */ - if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT) - field = dn_bufp->dstruct.firstfield; - else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION) - field = dn_bufp->dunion.firstfield; - else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) - field = dn_bufp->dclass.memberlist; - else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) - field = dn_bufp->dtemplate.memberlist; - else - field.word = DNTTNIL; - - while (field.word && field.word != DNTTNIL) - { - fieldp = hpread_get_lntt (field.dnttp.index, objfile); - - /* At this point "fieldp" may point to either a DNTT_TYPE_FIELD - * or a DNTT_TYPE_GENFIELD record. - */ - vtbl_offset = 0; - static_member = 0; - const_member = 0; - volatile_member = 0; - - if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD) { - - /* The type will be GENFIELD if the field is a method or - * a static member (or some other cases -- see below) - */ - - /* Follow a link to get to the record for the field. */ - fn_field = fieldp->dgenfield.field; - fn_fieldp = hpread_get_lntt(fn_field.dnttp.index, objfile); - - /* Virtual funcs are indicated by a VFUNC which points to the - * real entry - */ - if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC) { - vtbl_offset = fn_fieldp->dvfunc.vtbl_offset; - fn_field = fn_fieldp->dvfunc.funcptr; - fn_fieldp = hpread_get_lntt(fn_field.dnttp.index, objfile); - } - - /* A function's entry may be preceded by a modifier which - * labels it static/constant/volatile. - */ - if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER) { - static_member = fn_fieldp->dmodifier.m_static; - const_member = fn_fieldp->dmodifier.m_const; - volatile_member = fn_fieldp->dmodifier.m_volatile; - fn_field = fn_fieldp->dmodifier.type; - fn_fieldp = hpread_get_lntt(fn_field.dnttp.index, objfile); - } - - /* Check whether we have a method */ - if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) || - (fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) || - (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) || - (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION)) { - /* Method found */ - - short ix = 0; - - /* Look up function type of method */ - memtype = hpread_type_lookup (fn_field, objfile); - - /* Methods can be seen before classes in the SOM records. - If we are processing this class because it's a parameter of a - method, at this point the method's type is actually incomplete; - we'll have to fix it up later; mark the class for this. */ - - if (TYPE_INCOMPLETE (memtype)) - { - TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE; - if (fixup_class) - warning ("Two classes to fix up for method?? Type information may be incorrect for some classes."); - if (fixup_method) - warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes."); - fixup_class = type; /* remember this class has to be fixed up */ - fixup_method = memtype; /* remember the method type to be used in fixup */ - } - - /* HP aCC generates operator names without the "operator" keyword, and - generates null strings as names for operators that are - user-defined type conversions to basic types (e.g. operator int ()). - So try to reconstruct name as best as possible. */ - - method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name); - method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias); - - if (!method_name || /* no name */ - !*method_name || /* or null name */ - cplus_mangle_opname (method_name, DMGL_ANSI)) /* or name is an operator like "<" */ - { - char * tmp_name = cplus_demangle (method_alias, DMGL_ANSI); - char * op_string = strstr (tmp_name, "operator"); - method_name = xmalloc (strlen (op_string) + 1); /* don't overwrite VT! */ - strcpy (method_name, op_string); - } - - /* First check if a method of the same name has already been seen. */ - fn_p = fn_list; - while (fn_p) - { - if (STREQ (fn_p->field.name, method_name)) - break; - fn_p = fn_p->next; - } - - /* If no such method was found, allocate a new entry in the list */ - if (!fn_p) - { - /* Get space to record this member function */ - /* Note: alloca used; this will disappear on routine exit */ - fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field)); - fn_new->next = fn_list; - fn_list = fn_new; - - /* Fill in the fields of the struct nextfield */ - - /* Record the (unmangled) method name */ - fn_list->field.name = method_name; - /* Initial space for overloaded methods */ - /* Note: xmalloc is used; this will persist after this routine exits */ - fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field))); - fn_list->field.length = 1; /* Init # of overloaded instances */ - fn_list->num_fn_fields = 5; /* # of entries for which space allocated */ - fn_p = fn_list; - ix = 0; /* array index for fn_field */ - /* Bump the total count of the distinctly named methods */ - n_fn_fields++; - } - else /* Another overloaded instance of an already seen method name */ - { - if (++(fn_p->field.length) > fn_p->num_fn_fields) - { - /* Increase space allocated for overloaded instances */ - fn_p->field.fn_fields - = (struct fn_field *) xrealloc (fn_p->field.fn_fields, - (fn_p->num_fn_fields + 5) * sizeof (struct fn_field)); - fn_p->num_fn_fields += 5; - } - ix = fn_p->field.length -1; /* array index for fn_field */ - } - - /* "physname" is intended to be the name of this overloaded instance. */ - if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) && - method_alias && - *method_alias) /* not a null string */ - fn_p->field.fn_fields[ix].physname = method_alias; - else - fn_p->field.fn_fields[ix].physname = method_name; - /* What's expected here is the function type */ - /* But mark it as NULL if the method was incompletely processed - We'll fix this up later when the method is fully processed */ - if (TYPE_INCOMPLETE (memtype)) - { - fn_p->field.fn_fields[ix].type = NULL; - fn_p->field.fn_fields[ix].args = NULL; - } - else - { - fn_p->field.fn_fields[ix].type = memtype; - - /* The argument list */ - fn_p->field.fn_fields[ix].type->type_specific.arg_types = - (struct type **) obstack_alloc(&objfile->type_obstack, - sizeof(struct type *) * (memtype->nfields + 1)); - for (i = 0; i < memtype->nfields; i++) - fn_p->field.fn_fields[ix].type->type_specific.arg_types[i] = memtype->fields[i].type; - /* void termination */ - fn_p->field.fn_fields[ix].type->type_specific.arg_types[memtype->nfields] = builtin_type_void; - - /* pai: It's not clear why this args field has to be set. Perhaps - * it should be eliminated entirely. */ - fn_p->field.fn_fields[ix].args = - (struct type **) obstack_alloc(&objfile->type_obstack, - sizeof(struct type *) * (memtype->nfields + 1)); - for (i = 0; i < memtype->nfields; i++) - fn_p->field.fn_fields[ix].args[i] = memtype->fields[i].type; - /* null-terminated, unlike arg_types above e*/ - fn_p->field.fn_fields[ix].args[memtype->nfields] = NULL; - } - /* For virtual functions, fill in the voffset field with the - * virtual table offset. (This is just copied over from the - * SOM record; not sure if it is what GDB expects here...). - * But if the function is a static method, set it to 1. - * - * Note that we have to add 1 because 1 indicates a static - * method, and 0 indicates a non-static, non-virtual method */ - - if (static_member) - fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC; - else - fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0; - - /* Also fill in the fcontext field with the current - * class. (The latter isn't quite right: should be the baseclass - * that defines the virtual function... Note we do have - * a variable "baseclass" that we could stuff into the fcontext - * field, but "baseclass" isn't necessarily right either, - * since the virtual function could have been defined more - * than one level up). - */ - - if (vtbl_offset != 0) - fn_p->field.fn_fields[ix].fcontext = type; - else - fn_p->field.fn_fields[ix].fcontext = NULL; - - /* Other random fields pertaining to this method */ - fn_p->field.fn_fields[ix].is_const = const_member; - fn_p->field.fn_fields[ix].is_volatile = volatile_member; /* ?? */ - switch (fieldp->dgenfield.visibility) { - case 1: - fn_p->field.fn_fields[ix].is_protected = 1; - fn_p->field.fn_fields[ix].is_private = 0; - break; - case 2: - fn_p->field.fn_fields[ix].is_protected = 0; - fn_p->field.fn_fields[ix].is_private = 1; - break; - default: /* public */ - fn_p->field.fn_fields[ix].is_protected = 0; - fn_p->field.fn_fields[ix].is_private = 0; - } - fn_p->field.fn_fields[ix].is_stub = 0; - - /* HP aCC emits both MEMFUNC and FUNCTION entries for a method; - if the class points to the FUNCTION, there is usually separate - code for the method; but if we have a MEMFUNC, the method has - been inlined (and there is usually no FUNCTION entry) - FIXME Not sure if this test is accurate. pai/1997-08-22 */ - if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) || - (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)) - fn_p->field.fn_fields[ix].is_inlined = 1; - else - fn_p->field.fn_fields[ix].is_inlined = 0; - - fn_p->field.fn_fields[ix].dummy = 0; - - /* Bump the total count of the member functions */ - n_fn_fields_total++; - - } else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR) { - /* This case is for static data members of classes */ - - /* pai:: FIXME -- check that "staticmem" bit is set */ - - /* Get space to record this static member */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - list->field.name = VT (objfile) + fn_fieldp->dsvar.name; - FIELD_BITSIZE (list->field) = -1; /* indicates static member */ - SET_FIELD_PHYSNAME (list->field, 0); /* initialize to empty */ - memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile); - - FIELD_TYPE (list->field) = memtype; - list->attributes = 0; - switch (fieldp->dgenfield.visibility) { - case 1: - B_SET(&(list->attributes), ATTR_PROTECT); - break; - case 2: - B_SET(&(list->attributes), ATTR_PRIVATE); - break; - } - nfields++; - } - - else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD) - { - /* FIELDs follow GENFIELDs for fields of anonymous unions. - Code below is replicated from the case for FIELDs further - below, except that fieldp is replaced by fn_fieldp */ - if (!fn_fieldp->dfield.a_union) - warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set"); - /* Get space to record the next field/data-member. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - list->field.name = VT (objfile) + fn_fieldp->dfield.name; - FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset; - if (fn_fieldp->dfield.bitlength % 8) - list->field.bitsize = fn_fieldp->dfield.bitlength; - else - list->field.bitsize = 0; - - memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile); - list->field.type = memtype; - list->attributes = 0; - switch (fn_fieldp->dfield.visibility) { - case 1: - B_SET(&(list->attributes), ATTR_PROTECT); - break; - case 2: - B_SET(&(list->attributes), ATTR_PRIVATE); - break; - } - nfields++; - } - else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR) - { - /* Field of anonymous union; union is not inside a class */ - if (!fn_fieldp->dsvar.a_union) - warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set"); - /* Get space to record the next field/data-member. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - list->field.name = VT (objfile) + fn_fieldp->dsvar.name; - FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */ - FIELD_BITSIZE (list->field) = 0; /* use length from type */ - memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile); - list->field.type = memtype; - list->attributes = 0; - /* No info to set visibility -- always public */ - nfields++; - } - else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR) - { - /* Field of anonymous union; union is not inside a class */ - if (!fn_fieldp->ddvar.a_union) - warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set"); - /* Get space to record the next field/data-member. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - list->field.name = VT (objfile) + fn_fieldp->ddvar.name; - FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */ - FIELD_BITSIZE (list->field) = 0; /* use length from type */ - memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile); - list->field.type = memtype; - list->attributes = 0; - /* No info to set visibility -- always public */ - nfields++; - } - else { /* Not a method, nor a static data member, nor an anon union field */ - - /* This case is for miscellaneous type entries (local enums, - local function templates, etc.) that can be present - inside a class. */ - - /* Enums -- will be handled by other code that takes care - of DNTT_TYPE_ENUM; here we see only DNTT_TYPE_MEMENUM so - it's not clear we could have handled them here at all. */ - /* FUNC_TEMPLATE: is handled by other code (??). */ - /* MEMACCESS: modified access for inherited member. Not - sure what to do with this, ignoriing it at present. */ - - /* What other entries can appear following a GENFIELD which - we do not handle above? (MODIFIER, VFUNC handled above.) */ - - if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) && - (fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) && - (fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE)) - warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD", - fn_fieldp->dblock.kind); - } - /* walk to the next FIELD or GENFIELD */ - field = fieldp->dgenfield.nextfield; - - } - else if (fieldp->dblock.kind == DNTT_TYPE_FIELD) { - - /* Ordinary structure/union/class field */ - struct type * anon_union_type; - - /* Get space to record the next field/data-member. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - list->field.name = VT (objfile) + fieldp->dfield.name; - - - /* A FIELD by itself (without a GENFIELD) can also be a static member */ - if (fieldp->dfield.staticmem) - { - FIELD_BITPOS (list->field) = -1; - FIELD_BITSIZE (list->field) = 0; - } - else /* Non-static data member */ - { - FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset; - if (fieldp->dfield.bitlength % 8) - FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength; - else - FIELD_BITSIZE (list->field) = 0; - } - - memtype = hpread_type_lookup (fieldp->dfield.type, objfile); - FIELD_TYPE (list->field) = memtype; - list->attributes = 0; - switch (fieldp->dfield.visibility) { - case 1: - B_SET(&(list->attributes), ATTR_PROTECT); - break; - case 2: - B_SET(&(list->attributes), ATTR_PRIVATE); - break; - } - nfields++; - - - /* Note 1: First, we have to check if the current field is an anonymous - union. If it is, then *its* fields are threaded along in the - nextfield chain. :-( This was supposed to help debuggers, but is - really just a nuisance since we deal with anonymous unions anyway by - checking that the name is null. So anyway, we skip over the fields - of the anonymous union. pai/1997-08-22 */ - /* Note 2: In addition, the bitoffsets for the fields of the anon union - are relative to the enclosing struct, *NOT* relative to the anon - union! This is an even bigger nuisance -- we have to go in and munge - the anon union's type information appropriately. pai/1997-08-22 */ - - /* Both tasks noted above are done by a separate function. This takes us - to the next FIELD or GENFIELD, skipping anon unions, and recursively - processing intermediate types. */ - field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile); - - } else { - /* neither field nor genfield ?? is this possible?? */ - /* pai:: FIXME walk to the next -- how? */ - warning ("Internal error: unexpected DNTT kind %d encountered as field of struct"); - warning ("Skipping remaining fields of struct"); - break; /* get out of loop of fields */ - } - } - - /* If it's a template, read in the instantiation list */ - if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) { - ninstantiations = 0; - field = dn_bufp->dtemplate.expansions; - while (field.word && field.word != DNTTNIL) { - fieldp = hpread_get_lntt (field.dnttp.index, objfile); - - /* The expansions or nextexp should point to a tagdef */ - if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF) - break; - - i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation)); - i_new->next = i_list; - i_list = i_new; - i_list->t = hpread_type_lookup (field, objfile); - ninstantiations++; - - /* And the "type" field of that should point to a class */ - field = fieldp->dtag.type; - fieldp = hpread_get_lntt (field.dnttp.index, objfile); - if (fieldp->dblock.kind != DNTT_TYPE_CLASS) - break; - - /* Get the next expansion */ - field = fieldp->dclass.nextexp; - } - } - TYPE_NINSTANTIATIONS(type) = ninstantiations; - if (ninstantiations > 0) - TYPE_INSTANTIATIONS(type) = (struct type **) - obstack_alloc (&objfile->type_obstack, sizeof (struct type *) * ninstantiations); - for (n = ninstantiations; i_list; i_list = i_list->next) - { - n -= 1; - TYPE_INSTANTIATION(type, n) = i_list->t; - } - - - /* Copy the field-list to GDB's symbol table */ - TYPE_NFIELDS (type) = nfields; - TYPE_N_BASECLASSES (type) = n_base_classes; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields); - /* Copy the saved-up fields into the field vector. */ - for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next) - { - n -= 1; - TYPE_FIELD (type, n) = tmp_list->field; - } - - /* Copy the "function-field-list" (i.e., the list of member - * functions in the class) to GDB's symbol table - */ - TYPE_NFN_FIELDS (type) = n_fn_fields; - TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total; - TYPE_FN_FIELDLISTS(type) = (struct fn_fieldlist *) - obstack_alloc (&objfile->type_obstack, sizeof (struct fn_fieldlist) * n_fn_fields); - for (n = n_fn_fields; fn_list; fn_list = fn_list->next) - { - n -= 1; - TYPE_FN_FIELDLIST(type, n) = fn_list->field; - } - - /* pai:: FIXME -- perhaps each bitvector should be created individually */ - for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next) - { - n -= 1; - if (tmp_list->attributes) - { - need_bitvectors = 1; - break; - } - } - - if (need_bitvectors) - { - /* pai:: this step probably redundant */ - ALLOCATE_CPLUS_STRUCT_TYPE (type); - - TYPE_FIELD_VIRTUAL_BITS (type) = - (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); - B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields); - - TYPE_FIELD_PRIVATE_BITS (type) = - (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); - B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields); - - TYPE_FIELD_PROTECTED_BITS (type) = - (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); - B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields); - - /* this field vector isn't actually used with HP aCC */ - TYPE_FIELD_IGNORE_BITS (type) = - (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); - B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields); - - while (nfields-- > 0) - { - if (B_TST(&(list->attributes),ATTR_VIRTUAL)) - SET_TYPE_FIELD_VIRTUAL (type, nfields); - if (B_TST(&(list->attributes),ATTR_PRIVATE)) - SET_TYPE_FIELD_PRIVATE (type, nfields); - if (B_TST(&(list->attributes),ATTR_PROTECT)) - SET_TYPE_FIELD_PROTECTED (type, nfields); - - list = list->next; - } - } - else - { - TYPE_FIELD_VIRTUAL_BITS(type) = NULL; - TYPE_FIELD_PROTECTED_BITS(type) = NULL; - TYPE_FIELD_PRIVATE_BITS(type) = NULL; - } - - if (has_vtable(type)) - { - /* Allocate space for class runtime information */ - TYPE_RUNTIME_PTR(type) = (struct runtime_info *) xmalloc (sizeof(struct runtime_info)); - /* Set flag for vtable */ - TYPE_VTABLE(type) = 1; - /* The first non-virtual base class with a vtable. */ - TYPE_PRIMARY_BASE(type) = primary_base_class(type); - /* The virtual base list. */ - TYPE_VIRTUAL_BASE_LIST(type) = virtual_base_list(type); - } - else - TYPE_RUNTIME_PTR(type) = NULL; - - /* If this is a local type (C++ - declared inside a function), record file name & line # */ - if (hpread_get_scope_depth (dn_bufp, objfile, 1 /* no need for real depth */)) - { - TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info)); - TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1); - strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name); - if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0)) - TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line; - else - TYPE_LOCALTYPE_LINE (type) = 0; - } - else - TYPE_LOCALTYPE_PTR (type) = NULL; - - /* Clear the global saying what template we are in the middle of processing */ - current_template = NULL; - - return type; -} - -/* Adjust the physnames for each static member of a struct - or class type to be something like "A::x"; then various - other pieces of code that do a lookup_symbol on the phyname - work correctly. - TYPE is a pointer to the struct/class type - NAME is a char * (string) which is the class/struct name - Void return */ - -static void -fix_static_member_physnames (type, class_name, objfile) - struct type * type; - char * class_name; - struct objfile * objfile; -{ - int i; - - /* We fix the member names only for classes or structs */ - if (TYPE_CODE (type) != TYPE_CODE_STRUCT) - return; - - for (i=0; i < TYPE_NFIELDS (type); i++) - if (TYPE_FIELD_STATIC (type, i)) - { - if (TYPE_FIELD_STATIC_PHYSNAME (type, i)) - return; /* physnames are already set */ - - SET_FIELD_PHYSNAME (type->fields[i], - obstack_alloc (&objfile->type_obstack, - strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3)); - strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name); - strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::"); - strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i)); - } -} - -/* Fix-up the type structure for a CLASS so that the type entry - * for a method (previously marked with a null type in hpread_read_struct_type() - * is set correctly to METHOD. - * OBJFILE is as for other such functions. - * Void return. */ - -static void -fixup_class_method_type (class, method, objfile) - struct type * class; - struct type * method; - struct objfile * objfile; -{ - int i, j, k; - - if (!class || !method || !objfile) - return; - - /* Only for types that have methods */ - if ((TYPE_CODE (class) != TYPE_CODE_CLASS) && - (TYPE_CODE (class) != TYPE_CODE_UNION)) - return; - - /* Loop over all methods and find the one marked with a NULL type */ - for (i = 0; i < TYPE_NFN_FIELDS (class); i++) - for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++) - if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL) - { - /* Set the method type */ - TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method; - /* The argument list */ - (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types - = (struct type **) obstack_alloc(&objfile->type_obstack, - sizeof(struct type *) * (method->nfields + 1)); - for (k = 0; k < method->nfields; k++) - (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[k] = method->fields[k].type; - /* void termination */ - (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[method->nfields] = builtin_type_void; - - /* pai: It's not clear why this args field has to be set. Perhaps - * it should be eliminated entirely. */ - (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args - = (struct type **) obstack_alloc(&objfile->type_obstack, - sizeof(struct type *) * (method->nfields + 1)); - for (k = 0; k < method->nfields; k++) - (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[k] = method->fields[k].type; - /* null-terminated, unlike arg_types above */ - (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[method->nfields] = NULL; - - /* Break out of both loops -- only one method to fix up in a class */ - goto finish; - } - -finish: - TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE; -} - - -/* If we're in the middle of processing a template, get a pointer - * to the Nth template argument. - * An example may make this clearer: - * template class q2 { - * public: - * T1 a; - * T2 b; - * }; - * The type for "a" will be "first template arg" and - * the type for "b" will be "second template arg". - * We need to look these up in order to fill in "a" and "b"'s type. - * This is called from hpread_type_lookup(). - */ -static struct type * -hpread_get_nth_template_arg(objfile, n) - struct objfile *objfile; - int n; -{ - if (current_template != NULL) - return TYPE_TEMPLATE_ARG(current_template, n).type; - else - return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG); -} - -/* Read in and internalize a TEMPL_ARG (template arg) symbol. */ - -static struct type * -hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; - char * name; -{ - struct type *type; - - /* See if it's something we've already deal with. */ - type = hpread_alloc_type (hp_type, objfile); - if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG) - return type; - - /* Nope. Fill in the appropriate fields. */ - TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG; - TYPE_LENGTH (type) = 0; - TYPE_NFIELDS (type) = 0; - TYPE_NAME (type) = name; - return type; -} - -/* Read in and internalize a set debug symbol. */ - -static struct type * -hpread_read_set_type (hp_type, dn_bufp, objfile) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; -{ - struct type *type; - - /* See if it's something we've already deal with. */ - type = hpread_alloc_type (hp_type, objfile); - if (TYPE_CODE (type) == TYPE_CODE_SET) - return type; - - /* Nope. Fill in the appropriate fields. */ - TYPE_CODE (type) = TYPE_CODE_SET; - TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8; - TYPE_NFIELDS (type) = 0; - TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype, - objfile); - return type; -} - -/* Read in and internalize an array debug symbol. */ - -static struct type * -hpread_read_array_type (hp_type, dn_bufp, objfile) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; -{ - struct type *type; - - /* Allocate an array type symbol. - * Why no check for already-read here, like in the other - * hpread_read_xxx_type routines? Because it kept us - * from properly determining the size of the array! - */ - type = hpread_alloc_type (hp_type, objfile); - - TYPE_CODE (type) = TYPE_CODE_ARRAY; - - /* Although the hp-symtab.h does not *require* this to be the case, - * GDB is assuming that "arrayisbytes" and "elemisbytes" be consistent. - * I.e., express both array-length and element-length in bits, - * or express both array-length and element-length in bytes. - */ - if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) || - (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes))) { - warning ("error in hpread_array_type.\n"); - return; - } else if (dn_bufp->darray.arraylength == 0x7fffffff) { - /* The HP debug format represents char foo[]; as an array with - * length 0x7fffffff. Internally GDB wants to represent this - * as an array of length zero. - */ - TYPE_LENGTH (type) = 0; - } else if (dn_bufp->darray.arrayisbytes) - TYPE_LENGTH (type) = dn_bufp->darray.arraylength; - else /* arraylength is in bits */ - TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8; - - TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype, - objfile); - - /* The one "field" is used to store the subscript type */ - /* Since C and C++ multi-dimensional arrays are simply represented - * as: array of array of ..., we only need one subscript-type - * per array. This subscript type is typically a subrange of integer. - * If this gets extended to support languages like Pascal, then - * we need to fix this to represent multi-dimensional arrays properly. - */ - TYPE_NFIELDS (type) = 1; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile->type_obstack, sizeof (struct field)); - TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype, - objfile); - return type; -} - -/* Read in and internalize a subrange debug symbol. */ -static struct type * -hpread_read_subrange_type (hp_type, dn_bufp, objfile) - dnttpointer hp_type; - union dnttentry *dn_bufp; - struct objfile *objfile; -{ - struct type *type; - - /* Is it something we've already dealt with. */ - type = hpread_alloc_type (hp_type, objfile); - if (TYPE_CODE (type) == TYPE_CODE_RANGE) - return type; - - /* Nope, internalize it. */ - TYPE_CODE (type) = TYPE_CODE_RANGE; - TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8; - TYPE_NFIELDS (type) = 2; - TYPE_FIELDS (type) - = (struct field *) obstack_alloc (&objfile->type_obstack, - 2 * sizeof (struct field)); - - if (dn_bufp->dsubr.dyn_low) - TYPE_FIELD_BITPOS (type, 0) = 0; - else - TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound; - - if (dn_bufp->dsubr.dyn_high) - TYPE_FIELD_BITPOS (type, 1) = -1; - else - TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound; - TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype, - objfile); - return type; -} - -/* struct type * hpread_type_lookup(hp_type, objfile) - * Arguments: - * hp_type: A pointer into the DNTT specifying what type we - * are about to "look up"., or else [for fundamental types - * like int, float, ...] an "immediate" structure describing - * the type. - * objfile: ? - * Return value: A pointer to a "struct type" (representation of a - * type in GDB's internal symbol table - see gdbtypes.h) - * Routine description: - * There are a variety of places when scanning the DNTT when we - * need to interpret a "type" field. The simplest and most basic - * example is when we're processing the symbol table record - * for a data symbol (a SVAR or DVAR record). That has - * a "type" field specifying the type of the data symbol. That - * "type" field is either an "immediate" type specification (for the - * fundamental types) or a DNTT pointer (for more complicated types). - * For the more complicated types, we may or may not have already - * processed the pointed-to type. (Multiple data symbols can of course - * share the same type). - * The job of hpread_type_lookup() is to process this "type" field. - * Most of the real work is done in subroutines. Here we interpret - * the immediate flag. If not immediate, chase the DNTT pointer to - * find our way to the SOM record describing the type, switch on - * the SOM kind, and then call an appropriate subroutine depending - * on what kind of type we are constructing. (e.g., an array type, - * a struct/class type, etc). - */ -static struct type * -hpread_type_lookup (hp_type, objfile) - dnttpointer hp_type; - struct objfile *objfile; -{ - union dnttentry *dn_bufp; - struct type * tmp_type; - - /* First see if it's a simple builtin type. */ - if (hp_type.dntti.immediate) - /* If this is a template argument, the argument number is - * encoded in the bitlength. All other cases, just return - * GDB's representation of this fundamental type. - */ - if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG) - return hpread_get_nth_template_arg(objfile, hp_type.dntti.bitlength); - else - return lookup_fundamental_type (objfile, hpread_type_translate (hp_type)); - - /* Not a builtin type. We'll have to read it in. */ - if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile)) - dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile); - else - /* This is a fancy way of returning NULL */ - return lookup_fundamental_type (objfile, FT_VOID); - - switch (dn_bufp->dblock.kind) - { - case DNTT_TYPE_SRCFILE: - case DNTT_TYPE_MODULE: - case DNTT_TYPE_ENTRY: - case DNTT_TYPE_BEGIN: - case DNTT_TYPE_END: - case DNTT_TYPE_IMPORT: - case DNTT_TYPE_LABEL: - case DNTT_TYPE_FPARAM: - case DNTT_TYPE_SVAR: - case DNTT_TYPE_DVAR: - case DNTT_TYPE_CONST: - case DNTT_TYPE_MEMENUM: - case DNTT_TYPE_VARIANT: - case DNTT_TYPE_FILE: - case DNTT_TYPE_WITH: - case DNTT_TYPE_COMMON: - case DNTT_TYPE_COBSTRUCT: - case DNTT_TYPE_XREF: - case DNTT_TYPE_SA: - case DNTT_TYPE_MACRO: - case DNTT_TYPE_BLOCKDATA: - case DNTT_TYPE_CLASS_SCOPE: - case DNTT_TYPE_MEMACCESS: - case DNTT_TYPE_INHERITANCE: - case DNTT_TYPE_OBJECT_ID: - case DNTT_TYPE_FRIEND_CLASS: - case DNTT_TYPE_FRIEND_FUNC: - /* These are not types - something went wrong. */ - /* This is a fancy way of returning NULL */ - return lookup_fundamental_type (objfile, FT_VOID); - - case DNTT_TYPE_FUNCTION: - /* We wind up here when dealing with class member functions - * (called from hpread_read_struct_type(), i.e. when processing - * the class definition itself). - */ - return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); - - case DNTT_TYPE_DOC_FUNCTION: - return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0); - - case DNTT_TYPE_TYPEDEF: - { - /* A typedef - chase it down by making a recursive call */ - struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type, - objfile); - - /* The following came from the base hpread.c that we inherited. - * It is WRONG so I have commented it out. - RT - *... - - char *suffix; - suffix = VT (objfile) + dn_bufp->dtype.name; - TYPE_NAME (structtype) = suffix; - - * ... further explanation .... - * - * What we have here is a typedef pointing to a typedef. - * E.g., - * typedef int foo; - * typedef foo fum; - * - * What we desire to build is (these are pictures - * of "struct type"'s): - * - * +---------+ +----------+ +------------+ - * | typedef | | typedef | | fund. type | - * | type| -> | type| -> | | - * | "fum" | | "foo" | | "int" | - * +---------+ +----------+ +------------+ - * - * What this commented-out code is doing is smashing the - * name of pointed-to-type to be the same as the pointed-from - * type. So we wind up with something like: - * - * +---------+ +----------+ +------------+ - * | typedef | | typedef | | fund. type | - * | type| -> | type| -> | | - * | "fum" | | "fum" | | "fum" | - * +---------+ +----------+ +------------+ - * - */ - - return structtype; - } - - case DNTT_TYPE_TAGDEF: - { - /* Just a little different from above. We have to tack on - * an identifier of some kind (struct, union, enum, class, etc). - */ - struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type, - objfile); - char *prefix, *suffix; - suffix = VT (objfile) + dn_bufp->dtype.name; - - /* Lookup the next type in the list. It should be a structure, - * union, class, enum, or template type. - * We will need to attach that to our name. - */ - if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile)) - dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile); - else { - complain (&hpread_type_lookup_complaint); - return; - } - - if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT) { - prefix = "struct "; - } else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION) { - prefix = "union "; - } else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) { - /* Further field for CLASS saying how it was really declared */ - /* 0==class, 1==union, 2==struct */ - if (dn_bufp->dclass.class_decl == 0) - prefix = "class "; - else if (dn_bufp->dclass.class_decl == 1) - prefix = "union "; - else if (dn_bufp->dclass.class_decl == 2) - prefix = "struct "; - else - prefix = ""; - } else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM) { - prefix = "enum "; - } else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) { - prefix = "template "; - } else { - prefix = ""; - } - - /* Build the correct name. */ - structtype->name - = (char *) obstack_alloc (&objfile->type_obstack, - strlen (prefix) + strlen (suffix) + 1); - TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix); - TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix); - TYPE_TAG_NAME (structtype) = suffix; - - /* For classes/structs, we have to set the static member "physnames" - to point to strings like "Class::Member" */ - if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT) - fix_static_member_physnames (structtype, suffix, objfile); - - return structtype; - } - - case DNTT_TYPE_POINTER: - /* Pointer type - call a routine in gdbtypes.c that constructs - * the appropriate GDB type. - */ - return make_pointer_type ( - hpread_type_lookup (dn_bufp->dptr.pointsto, - objfile), - NULL); - - case DNTT_TYPE_REFERENCE: - /* C++ reference type - call a routine in gdbtypes.c that constructs - * the appropriate GDB type. - */ - return make_reference_type ( - hpread_type_lookup (dn_bufp->dreference.pointsto, - objfile), - NULL); - - case DNTT_TYPE_ENUM: - return hpread_read_enum_type (hp_type, dn_bufp, objfile); - case DNTT_TYPE_SET: - return hpread_read_set_type (hp_type, dn_bufp, objfile); - case DNTT_TYPE_SUBRANGE: - return hpread_read_subrange_type (hp_type, dn_bufp, objfile); - case DNTT_TYPE_ARRAY: - return hpread_read_array_type (hp_type, dn_bufp, objfile); - case DNTT_TYPE_STRUCT: - case DNTT_TYPE_UNION: - return hpread_read_struct_type (hp_type, dn_bufp, objfile); - case DNTT_TYPE_FIELD: - return hpread_type_lookup (dn_bufp->dfield.type, objfile); - - case DNTT_TYPE_FUNCTYPE: - /* Here we want to read the function SOMs and return a - * type for it. We get here, for instance, when processing - * pointer-to-function type. - */ - return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); - - case DNTT_TYPE_PTRMEM: - /* Declares a C++ pointer-to-data-member type. - * The "pointsto" field defines the class, - * while the "memtype" field defines the pointed-to-type. - */ - { - struct type * ptrmemtype; - struct type * class_type; - struct type * memtype; - memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype, - objfile), - class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto, - objfile), - ptrmemtype = alloc_type(objfile); - smash_to_member_type(ptrmemtype, class_type, memtype); - return make_pointer_type(ptrmemtype, NULL); - } - break; - - case DNTT_TYPE_PTRMEMFUNC: - /* Defines a C++ pointer-to-function-member type. - * The "pointsto" field defines the class, - * while the "memtype" field defines the pointed-to-type. - */ - { - struct type * ptrmemtype; - struct type * class_type; - struct type * functype; - struct type * retvaltype; - int nargs; - int i; - struct type ** args_type; - class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto, - objfile); - functype = hpread_type_lookup (dn_bufp->dptrmem.memtype, - objfile); - retvaltype = TYPE_TARGET_TYPE (functype); - nargs = TYPE_NFIELDS (functype); - args_type = (struct type **) xmalloc ((nargs+1) * sizeof (struct type *)); - for (i = 0; i < nargs; i++) { - args_type[i] = TYPE_FIELD_TYPE (functype, i); - } - args_type[nargs] = NULL; - ptrmemtype = alloc_type(objfile); - smash_to_method_type(ptrmemtype, class_type, retvaltype, args_type); - return make_pointer_type(ptrmemtype, NULL); - } - break; - - case DNTT_TYPE_CLASS: - return hpread_read_struct_type (hp_type, dn_bufp, objfile); - - case DNTT_TYPE_GENFIELD: - /* Chase pointer from GENFIELD to FIELD, and make recursive - * call on that. - */ - return hpread_type_lookup (dn_bufp->dgenfield.field, objfile); - - case DNTT_TYPE_VFUNC: - /* C++ virtual function. - * We get here in the course of processing a class type which - * contains virtual functions. Just go through another level - * of indirection to get to the pointed-to function SOM. - */ - return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile); - - case DNTT_TYPE_MODIFIER: - /* Check the modifiers and then just make a recursive call on - * the "type" pointed to by the modifier DNTT. - * - * pai:: FIXME -- do we ever want to handle "m_duplicate" and - * "m_void" modifiers? Is static_flag really needed here? - * (m_static used for methods of classes, elsewhere). - */ - tmp_type = make_cv_type (dn_bufp->dmodifier.m_const, - dn_bufp->dmodifier.m_volatile, - hpread_type_lookup (dn_bufp->dmodifier.type, objfile), - 0); - return tmp_type; - - - case DNTT_TYPE_MEMFUNC: - /* Member function. Treat like a function. - * I think we get here in the course of processing a - * pointer-to-member-function type... - */ - return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); - - case DNTT_TYPE_DOC_MEMFUNC: - return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0); - - case DNTT_TYPE_TEMPLATE: - /* Template - sort of the header for a template definition, - * which like a class, points to a member list and also points - * to a TEMPLATE_ARG list of type-arguments. - */ - return hpread_read_struct_type (hp_type, dn_bufp, objfile); - - case DNTT_TYPE_TEMPLATE_ARG: - { - char * name; - /* The TEMPLATE record points to an argument list of - * TEMPLATE_ARG records, each of which describes one - * of the type-arguments. - */ - name = VT (objfile) + dn_bufp->dtempl_arg.name; - return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name); - } - - case DNTT_TYPE_FUNC_TEMPLATE: - /* We wind up here when processing a TEMPLATE type, - * if the template has member function(s). - * Treat it like a FUNCTION. - */ - return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); - - case DNTT_TYPE_LINK: - /* The LINK record is used to link up templates with instantiations. - * There is no type associated with the LINK record per se. - */ - return lookup_fundamental_type (objfile, FT_VOID); - - /* Also not yet handled... */ - /* case DNTT_TYPE_DYN_ARRAY_DESC: */ - /* case DNTT_TYPE_DESC_SUBRANGE: */ - /* case DNTT_TYPE_BEGIN_EXT: */ - /* case DNTT_TYPE_INLN: */ - /* case DNTT_TYPE_INLN_LIST: */ - /* case DNTT_TYPE_ALIAS: */ - default: - /* A fancy way of returning NULL */ - return lookup_fundamental_type (objfile, FT_VOID); - } -} - -static sltpointer -hpread_record_lines (subfile, s_idx, e_idx, objfile, offset) - struct subfile *subfile; - sltpointer s_idx, e_idx; - struct objfile *objfile; - CORE_ADDR offset; -{ - union sltentry *sl_bufp; - - while (s_idx <= e_idx) - { - sl_bufp = hpread_get_slt (s_idx, objfile); - /* Only record "normal" entries in the SLT. */ - if (sl_bufp->snorm.sltdesc == SLT_NORMAL - || sl_bufp->snorm.sltdesc == SLT_EXIT) - record_line (subfile, sl_bufp->snorm.line, - sl_bufp->snorm.address + offset); - else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET) - record_line (subfile, sl_bufp->snormoff.line, - sl_bufp->snormoff.address + offset); - s_idx++; - } - return e_idx; -} - -/* Given a function "f" which is a member of a class, find - * the classname that it is a member of. Used to construct - * the name (e.g., "c::f") which GDB will put in the - * "demangled name" field of the function's symbol. - * Called from hpread_process_one_debug_symbol() - * If "f" is not a member function, return NULL. - */ -char * class_of (functype) -struct type * functype; -{ - struct type * first_param_type; - char * first_param_name; - struct type * pointed_to_type; - char * class_name; - - /* Check that the function has a first argument "this", - * and that "this" is a pointer to a class. If not, - * functype is not a member function, so return NULL. - */ - if (TYPE_NFIELDS(functype) == 0) - return NULL; - first_param_name = TYPE_FIELD_NAME (functype, 0); - if (first_param_name == NULL) - return NULL; /* paranoia */ - if (strcmp(first_param_name, "this")) - return NULL; - first_param_type = TYPE_FIELD_TYPE (functype, 0); - if (first_param_type == NULL) - return NULL; /* paranoia */ - if (TYPE_CODE(first_param_type) != TYPE_CODE_PTR) - return NULL; - - /* Get the thing that "this" points to, check that - * it's a class, and get its class name. - */ - pointed_to_type = TYPE_TARGET_TYPE(first_param_type); - if (pointed_to_type == NULL) - return NULL; /* paranoia */ - if (TYPE_CODE(pointed_to_type) != TYPE_CODE_CLASS) - return NULL; - class_name = TYPE_NAME(pointed_to_type); - if (class_name == NULL) - return NULL; /* paranoia */ - - /* The class name may be of the form "class c", in which case - * we want to strip off the leading "class ". - */ - if (strncmp(class_name, "class ", 6) == 0) - class_name += 6; - - return class_name; -} - -/* Internalize one native debug symbol. - * Called in a loop from hpread_expand_symtab(). - * Arguments: - * dn_bufp: - * name: - * section_offsets: - * objfile: - * text_offset: - * text_size: - * filename: - * index: Index of this symbol - * at_module_boundary_p Pointer to boolean flag to control caller's loop. - */ - -static void -hpread_process_one_debug_symbol (dn_bufp, name, section_offsets, objfile, - text_offset, text_size, filename, - index, at_module_boundary_p - ) - union dnttentry *dn_bufp; - char *name; - struct section_offsets *section_offsets; - struct objfile *objfile; - CORE_ADDR text_offset; - int text_size; - char *filename; - int index; - int *at_module_boundary_p; -{ - unsigned long desc; - int type; - CORE_ADDR valu; - int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT); - int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA); - union dnttentry *dn_temp; - dnttpointer hp_type; - struct symbol *sym; - struct context_stack *new; - char * class_scope_name; - extern int is_in_import_list (); /* in somread.c */ - - /* Allocate one GDB debug symbol and fill in some default values. */ - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->symbol_obstack); - SYMBOL_LANGUAGE (sym) = language_auto; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_LINE (sym) = 0; - SYMBOL_VALUE (sym) = 0; - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - - /* Just a trick in case the SOM debug symbol is a type definition. - * There are routines that are set up to build a GDB type symbol, given - * a SOM dnttpointer. So we set up a dummy SOM dnttpointer "hp_type". - * This allows us to call those same routines. - */ - hp_type.dnttp.extension = 1; - hp_type.dnttp.immediate = 0; - hp_type.dnttp.global = 0; - hp_type.dnttp.index = index; - - /* This "type" is the type of SOM record. - * Switch on SOM type. - */ - type = dn_bufp->dblock.kind; - switch (type) - { - case DNTT_TYPE_SRCFILE: - /* This type of symbol indicates from which source file or - * include file any following data comes. It may indicate: - * - * o The start of an entirely new source file (and thus - * a new module) - * - * o The start of a different source file due to #include - * - * o The end of an include file and the return to the original - * file. Thus if "foo.c" includes "bar.h", we see first - * a SRCFILE for foo.c, then one for bar.h, and then one for - * foo.c again. - * - * If it indicates the start of a new module then we must - * finish the symbol table of the previous module - * (if any) and start accumulating a new symbol table. - */ - - valu = text_offset; - if (!last_source_file ) { - /* - * A note on "last_source_file": this is a char* pointing - * to the actual file name. "start_symtab" sets it, - * "end_symtab" clears it. - * - * So if "last_source_file" is NULL, then either this is - * the first record we are looking at, or a previous call - * to "end_symtab()" was made to close out the previous - * module. Since we're now quitting the scan loop when we - * see a MODULE END record, we should never get here, except - * in the case that we're not using the quick look-up tables - * and have to use the old system as a fall-back. - */ - start_symtab (name, NULL, valu); - record_debugformat ("HP"); - SL_INDEX (objfile) = dn_bufp->dsfile.address; - } - - else { - /* Either a new include file, or a SRCFILE record - * saying we are back in the main source (or out of - * a nested include file) again. - */ - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->dsfile.address, - objfile, offset); - } - - /* A note on "start_subfile". This routine will check - * the name we pass it and look for an existing subfile - * of that name. There's thus only one sub-file for the - * actual source (e.g. for "foo.c" in foo.c), despite the - * fact that we'll see lots of SRCFILE entries for foo.c - * inside foo.c. - */ - start_subfile (name, NULL); - break; - - case DNTT_TYPE_MODULE: - /* - * We no longer ignore DNTT_TYPE_MODULE symbols. The module - * represents the meaningful semantic structure of a compilation - * unit. We expect to start the psymtab-to-symtab expansion - * looking at a MODULE entry, and to end it at the corresponding - * END MODULE entry. - * - *--Begin outdated comments - * - * This record signifies the start of a new source module - * In C/C++ there is no explicit "module" construct in the language, - * but each compilation unit is implicitly a module and they - * do emit the DNTT_TYPE_MODULE records. - * The end of the module is marked by a matching DNTT_TYPE_END record. - * - * The reason GDB gets away with ignoring the DNTT_TYPE_MODULE record - * is it notices the DNTT_TYPE_END record for the previous - * module (see comments under DNTT_TYPE_END case), and then treats - * the next DNTT_TYPE_SRCFILE record as if it were the module-start record. - * (i.e., it makes a start_symtab() call). - * This scheme seems a little convoluted, but I'll leave it - * alone on the principle "if it ain't broke don't fix - * it". (RT). - * - *-- End outdated comments - */ - - valu = text_offset; - if (!last_source_file ) - { - /* Start of a new module. We know this because "last_source_file" - * is NULL, which can only happen the first time or if we just - * made a call to end_symtab() to close out the previous module. - */ - start_symtab (name, NULL, valu); - SL_INDEX (objfile) = dn_bufp->dmodule.address; - } - else - { - /* This really shouldn't happen if we're using the quick - * look-up tables, as it would mean we'd scanned past an - * END MODULE entry. But if we're not using the tables, - * we started the module on the SRCFILE entry, so it's ok. - * For now, accept this. - */ - /* warning( "Error expanding psymtab, missed module end, found entry for %s", - * name ); - */ - *at_module_boundary_p = -1; - } - - start_subfile (name, NULL); - break; - - case DNTT_TYPE_FUNCTION: - case DNTT_TYPE_ENTRY: - /* A function or secondary entry point. */ - valu = dn_bufp->dfunc.lowaddr + offset; - - /* Record lines up to this point. */ - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->dfunc.address, - objfile, offset); - - WITHIN_FUNCTION (objfile) = 1; - CURRENT_FUNCTION_VALUE (objfile) = valu; - - /* Stack must be empty now. */ - if (context_stack_depth != 0) - complain (&lbrac_unmatched_complaint, (char *) symnum); - new = push_context (0, valu); - - /* Built a type for the function. This includes processing - * the symbol records for the function parameters. - */ - SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1); - - /* The "SYMBOL_NAME" field is expected to be the mangled name - * (if any), which we get from the "alias" field of the SOM record - * if that exists. - */ - if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) && - dn_bufp->dfunc.alias && /* has an alias */ - *(char *)(VT (objfile) + dn_bufp->dfunc.alias)) /* not a null string */ - SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias; - else - SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name; - - /* Special hack to get around HP compilers' insistence on - * reporting "main" as "_MAIN_" for C/C++ */ - if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) && - (strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0)) - SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name; - - /* The SYMBOL_CPLUS_DEMANGLED_NAME field is expected to - * be the demangled name. - */ - if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) - { - /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up - * calling the demangler in libiberty (cplus_demangle()) to - * do the job. This generally does the job, even though - * it's intended for the GNU compiler and not the aCC compiler - * Note that SYMBOL_INIT_DEMANGLED_NAME calls the - * demangler with arguments DMGL_PARAMS | DMGL_ANSI. - * Generally, we don't want params when we display - * a demangled name, but when I took out the DMGL_PARAMS, - * some things broke, so I'm leaving it in here, and - * working around the issue in stack.c. - RT - */ - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) && - (!SYMBOL_CPLUS_DEMANGLED_NAME(sym))) { - - /* Well, the symbol name is mangled, but the - * demangler in libiberty failed so the demangled - * field is still NULL. Try to - * do the job ourselves based on the "name" field - * in the SOM record. A complication here is that - * the name field contains only the function name - * (like "f"), whereas we want the class qualification - * (as in "c::f"). Try to reconstruct that. - */ - char * basename; - char * classname; - char * dem_name; - basename = VT (objfile) + dn_bufp->dfunc.name; - classname = class_of(SYMBOL_TYPE(sym)); - if (classname) { - dem_name = xmalloc(strlen(basename)+strlen(classname)+3); - strcpy(dem_name, classname); - strcat(dem_name, "::"); - strcat(dem_name, basename); - SYMBOL_CPLUS_DEMANGLED_NAME(sym) = dem_name; - SYMBOL_LANGUAGE (sym) = language_cplus; - } - } - } - - /* Add the function symbol to the list of symbols in this blockvector */ - if (dn_bufp->dfunc.global) - add_symbol_to_list (sym, &global_symbols); - else - add_symbol_to_list (sym, &file_symbols); - new->name = sym; - - /* Search forward to the next BEGIN and also read - * in the line info up to that point. - * Not sure why this is needed. - * In HP FORTRAN this code is harmful since there - * may not be a BEGIN after the FUNCTION. - * So I made it C/C++ specific. - RT - */ - if (dn_bufp->dfunc.language == HP_LANGUAGE_C || - dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) { - while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN) - { - dn_bufp = hpread_get_lntt (++index, objfile); - if (dn_bufp->dblock.extension) - continue; - } - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->dbegin.address, - objfile, offset); - SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile); - } - record_line (current_subfile, SYMBOL_LINE (sym), valu); - break; - - case DNTT_TYPE_DOC_FUNCTION: - valu = dn_bufp->ddocfunc.lowaddr + offset; - - /* Record lines up to this point. */ - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->ddocfunc.address, - objfile, offset); - - WITHIN_FUNCTION (objfile) = 1; - CURRENT_FUNCTION_VALUE (objfile) = valu; - /* Stack must be empty now. */ - if (context_stack_depth != 0) - complain (&lbrac_unmatched_complaint, (char *) symnum); - new = push_context (0, valu); - - /* Built a type for the function. This includes processing - * the symbol records for the function parameters. - */ - SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1); - - /* The "SYMBOL_NAME" field is expected to be the mangled name - * (if any), which we get from the "alias" field of the SOM record - * if that exists. - */ - if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) && - dn_bufp->ddocfunc.alias && /* has an alias */ - *(char *)(VT (objfile) + dn_bufp->ddocfunc.alias)) /* not a null string */ - SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias; - else - SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name; - - /* Special hack to get around HP compilers' insistence on - * reporting "main" as "_MAIN_" for C/C++ */ - if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) && - (strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0)) - SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name; - - if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) { - - /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up - * calling the demangler in libiberty (cplus_demangle()) to - * do the job. This generally does the job, even though - * it's intended for the GNU compiler and not the aCC compiler - * Note that SYMBOL_INIT_DEMANGLED_NAME calls the - * demangler with arguments DMGL_PARAMS | DMGL_ANSI. - * Generally, we don't want params when we display - * a demangled name, but when I took out the DMGL_PARAMS, - * some things broke, so I'm leaving it in here, and - * working around the issue in stack.c. - RT - */ - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - - if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) && - (!SYMBOL_CPLUS_DEMANGLED_NAME(sym))) { - - /* Well, the symbol name is mangled, but the - * demangler in libiberty failed so the demangled - * field is still NULL. Try to - * do the job ourselves based on the "name" field - * in the SOM record. A complication here is that - * the name field contains only the function name - * (like "f"), whereas we want the class qualification - * (as in "c::f"). Try to reconstruct that. - */ - char * basename; - char * classname; - char * dem_name; - basename = VT (objfile) + dn_bufp->ddocfunc.name; - classname = class_of(SYMBOL_TYPE(sym)); - if (classname) { - dem_name = xmalloc(strlen(basename)+strlen(classname)+3); - strcpy(dem_name, classname); - strcat(dem_name, "::"); - strcat(dem_name, basename); - SYMBOL_CPLUS_DEMANGLED_NAME(sym) = dem_name; - SYMBOL_LANGUAGE (sym) = language_cplus; - } - } - } - - /* Add the function symbol to the list of symbols in this blockvector */ - if (dn_bufp->ddocfunc.global) - add_symbol_to_list (sym, &global_symbols); - else - add_symbol_to_list (sym, &file_symbols); - new->name = sym; - - /* Search forward to the next BEGIN and also read - * in the line info up to that point. - * Not sure why this is needed. - * In HP FORTRAN this code is harmful since there - * may not be a BEGIN after the FUNCTION. - * So I made it C/C++ specific. - RT - */ - if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C || - dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) { - while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN) - { - dn_bufp = hpread_get_lntt (++index, objfile); - if (dn_bufp->dblock.extension) - continue; - } - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->dbegin.address, - objfile, offset); - SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile); - } - record_line (current_subfile, SYMBOL_LINE (sym), valu); - break; - - case DNTT_TYPE_BEGIN: - /* Begin a new scope. */ - if (context_stack_depth == 1 /* this means we're at function level */ && - context_stack[0].name != NULL /* this means it's a function */ && - context_stack[0].depth == 0 /* this means it's the first BEGIN - we've seen after the FUNCTION */ - ) - { - /* This is the first BEGIN after a FUNCTION. - * We ignore this one, since HP compilers always insert - * at least one BEGIN, i.e. it's: - * - * FUNCTION - * argument symbols - * BEGIN - * local symbols - * (possibly nested BEGIN ... END's if there are inner { } blocks) - * END - * END - * - * By ignoring this first BEGIN, the local symbols get treated - * as belonging to the function scope, and "print func::local_sym" - * works (which is what we want). - */ - - /* All we do here is increase the depth count associated with - * the FUNCTION entry in the context stack. This ensures that - * the next BEGIN we see (if any), representing a real nested { } - * block, will get processed. - */ - - context_stack[0].depth++; - - } else { - - /* Record lines up to this SLT pointer. */ - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->dbegin.address, - objfile, offset); - /* Calculate start address of new scope */ - valu = hpread_get_location (dn_bufp->dbegin.address, objfile); - valu += offset; /* Relocate for dynamic loading */ - /* We use the scope start DNTT index as nesting depth identifier! */ - desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile); - new = push_context (desc, valu); - } - break; - - case DNTT_TYPE_END: - /* End a scope. */ - - /* Valid end kinds are: - * MODULE - * FUNCTION - * WITH - * COMMON - * BEGIN - * CLASS_SCOPE - */ - - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->dend.address, - objfile, offset); - switch (dn_bufp->dend.endkind) - { - case DNTT_TYPE_MODULE: - /* Ending a module ends the symbol table for that module. - * Calling end_symtab() has the side effect of clearing the - * last_source_file pointer, which in turn signals - * process_one_debug_symbol() to treat the next DNTT_TYPE_SRCFILE - * record as a module-begin. - */ - valu = text_offset + text_size + offset; - - /* Tell our caller that we're done with expanding the - * debug information for a module. - */ - *at_module_boundary_p = 1; - - /* Don't do this, as our caller will do it! - * - * (void) end_symtab (valu, objfile, 0); - */ - break; - - case DNTT_TYPE_FUNCTION: - /* Ending a function, well, ends the function's scope. */ - dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index, - objfile); - valu = dn_temp->dfunc.hiaddr + offset; - /* Insert func params into local list */ - merge_symbol_lists (¶m_symbols, &local_symbols); - new = pop_context (); - /* Make a block for the local symbols within. */ - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, valu, objfile); - WITHIN_FUNCTION (objfile) = 0; /* This may have to change for Pascal */ - local_symbols = new->locals; - param_symbols = new->params; - break; - - case DNTT_TYPE_BEGIN: - if (context_stack_depth == 1 && - context_stack[0].name != NULL && - context_stack[0].depth == 1) - { - /* This is the END corresponding to the - * BEGIN which we ignored - see DNTT_TYPE_BEGIN case above. - */ - context_stack[0].depth--; - } else { - /* Ending a local scope. */ - valu = hpread_get_location (dn_bufp->dend.address, objfile); - /* Why in the hell is this needed? */ - valu += offset + 9; /* Relocate for dynamic loading */ - new = pop_context (); - desc = dn_bufp->dend.beginscope.dnttp.index; - if (desc != new->depth) - complain (&lbrac_mismatch_complaint, (char *) symnum); - - /* Make a block for the local symbols within. */ - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, valu, objfile); - local_symbols = new->locals; - param_symbols = new->params; - } - break; - - case DNTT_TYPE_WITH: - /* Since we ignore the DNTT_TYPE_WITH that starts the scope, - * we can ignore the DNTT_TYPE_END that ends it. - */ - break; - - case DNTT_TYPE_COMMON: - /* End a FORTRAN common block. We don't currently handle these */ - complain (&hpread_unhandled_end_common_complaint); - break; - - case DNTT_TYPE_CLASS_SCOPE: - - /* pai: FIXME Not handling nested classes for now -- must - * maintain a stack */ - class_scope_name = NULL; - -#if 0 - /* End a class scope */ - valu = hpread_get_location (dn_bufp->dend.address, objfile); - /* Why in the hell is this needed? */ - valu += offset + 9; /* Relocate for dynamic loading */ - new = pop_context (); - desc = dn_bufp->dend.beginscope.dnttp.index; - if (desc != new->depth) - complain (&lbrac_mismatch_complaint, (char *) symnum); - /* Make a block for the local symbols within. */ - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, valu, objfile); - local_symbols = new->locals; - param_symbols = new->params; -#endif - break; - - default: - complain (&hpread_unexpected_end_complaint); - break; - } - break; - - /* DNTT_TYPE_IMPORT is not handled */ - - case DNTT_TYPE_LABEL: - SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE; - break; - - case DNTT_TYPE_FPARAM: - /* Function parameters. */ - /* Note 1: This code was present in the 4.16 sources, and then - removed, because fparams are handled in - hpread_read_function_type(). However, while fparam symbols - are indeed handled twice, this code here cannot be removed - because then they don't get added to the local symbol list of - the function's code block, which leads to a failure to look - up locals, "this"-relative member names, etc. So I've put - this code back in. pai/1997-07-21 */ - /* Note 2: To fix a defect, we stopped adding FPARAMS to local_symbols - in hpread_read_function_type(), so FPARAMS had to be handled - here. I changed the location to be the appropriate argument - kinds rather than LOC_LOCAL. pai/1997-08-08 */ - /* Note 3: Well, the fix in Note 2 above broke argument printing - in traceback frames, and further it makes assumptions about the - order of the FPARAM entries from HP compilers (cc and aCC in particular - generate them in reverse orders -- fixing one breaks for the other). - So I've added code in hpread_read_function_type() to add fparams - to a param_symbols list for the current context level. These are - then merged into local_symbols when a function end is reached. - pai/1997-08-11 */ - - break; /* do nothing; handled in hpread_read_function_type() */ - -#if 0 /* Old code */ - if (dn_bufp->dfparam.regparam) - SYMBOL_CLASS (sym) = LOC_REGISTER; - else if (dn_bufp->dfparam.indirect) - SYMBOL_CLASS (sym) = LOC_REF_ARG; - else - SYMBOL_CLASS (sym) = LOC_ARG; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (dn_bufp->dfparam.copyparam) - { - SYMBOL_VALUE (sym) = dn_bufp->dfparam.location; -#ifdef HPREAD_ADJUST_STACK_ADDRESS - SYMBOL_VALUE (sym) - += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); -#endif - } - else - SYMBOL_VALUE (sym) = dn_bufp->dfparam.location; - SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile); - add_symbol_to_list (sym, &fparam_symbols); - break; -#endif - - case DNTT_TYPE_SVAR: - /* Static variables. */ - SYMBOL_CLASS (sym) = LOC_STATIC; - - /* Note: There is a case that arises with globals in shared - * libraries where we need to set the address to LOC_INDIRECT. - * This case is if you have a global "g" in one library, and - * it is referenced "extern g;" in another library. - * If we're processing the symbols for the referencing library, - * we'll see a global "g", but in this case the address given - * in the symbol table contains a pointer to the real "g". - * We use the storage class LOC_INDIRECT to indicate this. RT - */ - if (is_in_import_list (SYMBOL_NAME(sym), objfile)) - SYMBOL_CLASS (sym) = LOC_INDIRECT; - - SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset; - SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile); - - if (dn_bufp->dsvar.global) - add_symbol_to_list (sym, &global_symbols); - - else if (WITHIN_FUNCTION (objfile)) - add_symbol_to_list (sym, &local_symbols); - - else - add_symbol_to_list (sym, &file_symbols); - - if (dn_bufp->dsvar.thread_specific) - { - /* Thread-local variable. - */ - SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC; - SYMBOL_BASEREG (sym) = CR27_REGNUM; - - if( objfile->flags & OBJF_SHARED ) { - /* - * This variable is not only thread local but - * in a shared library. - * - * Alas, the shared lib structures are private - * to "somsolib.c". But C lets us point to one. - */ - struct so_list *so; - - if( objfile->obj_private == NULL ) - error( "Internal error in reading shared library information." ); - - so = ((obj_private_data_t *)(objfile->obj_private))->so_info; - if( so == NULL ) - error( "Internal error in reading shared library information." ); - - /* Thread-locals in shared libraries do NOT have the - * standard offset ("data_offset"), so we re-calculate - * where to look for this variable, using a call-back - * to interpret the private shared-library data. - */ - SYMBOL_VALUE_ADDRESS(sym) = dn_bufp->dsvar.location + - so_lib_thread_start_addr( so ); - } - } - break; - - case DNTT_TYPE_DVAR: - /* Dynamic variables. */ - if (dn_bufp->ddvar.regvar) - SYMBOL_CLASS (sym) = LOC_REGISTER; - else - SYMBOL_CLASS (sym) = LOC_LOCAL; - - SYMBOL_VALUE (sym) = dn_bufp->ddvar.location; -#ifdef HPREAD_ADJUST_STACK_ADDRESS - SYMBOL_VALUE (sym) - += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); -#endif - SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile); - if (dn_bufp->ddvar.global) - add_symbol_to_list (sym, &global_symbols); - else if (WITHIN_FUNCTION (objfile)) - add_symbol_to_list (sym, &local_symbols); - else - add_symbol_to_list (sym, &file_symbols); - break; - - case DNTT_TYPE_CONST: - /* A constant (pascal?). */ - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_VALUE (sym) = dn_bufp->dconst.location; - SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile); - if (dn_bufp->dconst.global) - add_symbol_to_list (sym, &global_symbols); - else if (WITHIN_FUNCTION (objfile)) - add_symbol_to_list (sym, &local_symbols); - else - add_symbol_to_list (sym, &file_symbols); - break; - - case DNTT_TYPE_TYPEDEF: - /* A typedef. We do want to process these, since a name is - * added to the namespace for the typedef'ed name. - */ - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile); - if (dn_bufp->dtype.global) - add_symbol_to_list (sym, &global_symbols); - else if (WITHIN_FUNCTION (objfile)) - add_symbol_to_list (sym, &local_symbols); - else - add_symbol_to_list (sym, &file_symbols); - break; - - case DNTT_TYPE_TAGDEF: - { - int global = dn_bufp->dtag.global; - /* Structure, union, enum, template, or class tag definition */ - /* We do want to process these, since a name is - * added to the namespace for the tag name (and if C++ class, - * for the typename also). - */ - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - - /* The tag contains in its "type" field a pointer to the - * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, DNTT_TYPE_ENUM, - * DNTT_TYPE_CLASS or DNTT_TYPE_TEMPLATE - * record that actually defines the type. - */ - SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile); - TYPE_NAME (sym->type) = SYMBOL_NAME (sym); - TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym); - if (dn_bufp->dtag.global) - add_symbol_to_list (sym, &global_symbols); - else if (WITHIN_FUNCTION (objfile)) - add_symbol_to_list (sym, &local_symbols); - else - add_symbol_to_list (sym, &file_symbols); - - /* If this is a C++ class, then we additionally - * need to define a typedef for the - * class type. E.g., so that the name "c" becomes visible as - * a type name when the user says "class c { ... }". - * In order to figure this out, we need to chase down the "type" - * field to get to the DNTT_TYPE_CLASS record. - * - * We also add the typename for ENUM. Though this isn't - * strictly correct, it is necessary because of the debug info - * generated by the aCC compiler, in which we cannot - * distinguish between: - * enum e { ... }; - * and - * typedef enum { ... } e; - * I.e., the compiler emits the same debug info for the above - * two cases, in both cases "e" appearing as a tagdef. - * Therefore go ahead and generate the typename so that - * "ptype e" will work in the above cases. - * - * We also add the typename for TEMPLATE, so as to allow "ptype t" - * when "t" is a template name. - */ - if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile)) - dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile); - else { - complain (&hpread_tagdef_complaint); - return; - } - if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS || - dn_bufp->dblock.kind == DNTT_TYPE_ENUM || - dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) { - struct symbol *newsym; - - newsym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - memset (newsym, 0, sizeof (struct symbol)); - SYMBOL_NAME (newsym) = name; - SYMBOL_LANGUAGE (newsym) = language_auto; - SYMBOL_NAMESPACE (newsym) = VAR_NAMESPACE; - SYMBOL_LINE (newsym) = 0; - SYMBOL_VALUE (newsym) = 0; - SYMBOL_CLASS (newsym) = LOC_TYPEDEF; - SYMBOL_TYPE (newsym) = sym->type; - if (global) - add_symbol_to_list (newsym, &global_symbols); - else if (WITHIN_FUNCTION (objfile)) - add_symbol_to_list (newsym, &local_symbols); - else - add_symbol_to_list (newsym, &file_symbols); - } - } - break; - - case DNTT_TYPE_POINTER: - /* Declares a pointer type. Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_ENUM: - /* Declares an enum type. Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_MEMENUM: - /* Member of enum */ - /* Ignored at this level, but hpread_read_enum_type() will take - * care of walking the list of enumeration members. - */ - break; - - case DNTT_TYPE_SET: - /* Declares a set type. Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_SUBRANGE: - /* Declares a subrange type. Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_ARRAY: - /* Declares an array type. Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_STRUCT: - case DNTT_TYPE_UNION: - /* Declares an struct/union type. - * Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_FIELD: - /* Structure/union/class field */ - /* Ignored at this level, but hpread_read_struct_type() will take - * care of walking the list of structure/union/class members. - */ - break; - - /* DNTT_TYPE_VARIANT is not handled by GDB */ - - /* DNTT_TYPE_FILE is not handled by GDB */ - - case DNTT_TYPE_FUNCTYPE: - /* Function type */ - /* Ignored at this level, handled within hpread_type_lookup() */ - break; - - case DNTT_TYPE_WITH: - /* This is emitted within methods to indicate "with " - * scoping rules (i.e., indicate that the class data members - * are directly visible). - * However, since GDB already infers this by looking at the - * "this" argument, interpreting the DNTT_TYPE_WITH - * symbol record is unnecessary. - */ - break; - - case DNTT_TYPE_COMMON: - /* FORTRAN common. Not yet handled. */ - complain (&hpread_unhandled_common_complaint); - break; - - /* DNTT_TYPE_COBSTRUCT is not handled by GDB. */ - /* DNTT_TYPE_XREF is not handled by GDB. */ - /* DNTT_TYPE_SA is not handled by GDB. */ - /* DNTT_TYPE_MACRO is not handled by GDB */ - - case DNTT_TYPE_BLOCKDATA: - /* Not sure what this is - part of FORTRAN support maybe? - * Anyway, not yet handled. - */ - complain (&hpread_unhandled_blockdata_complaint); - break; - - case DNTT_TYPE_CLASS_SCOPE: - - - - /* The compiler brackets member functions with a CLASS_SCOPE/END - * pair of records, presumably to put them in a different scope - * from the module scope where they are normally defined. - * E.g., in the situation: - * void f() { ... } - * void c::f() { ...} - * The member function "c::f" will be bracketed by a CLASS_SCOPE/END. - * This causes "break f" at the module level to pick the - * the file-level function f(), not the member function - * (which needs to be referenced via "break c::f"). - * - * Here we record the class name to generate the demangled names of - * member functions later. - * - * FIXME Not being used now for anything -- cplus_demangle seems - * enough for getting the class-qualified names of functions. We - * may need this for handling nested classes and types. */ - - /* pai: FIXME Not handling nested classes for now -- need to - * maintain a stack */ - - dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile); - if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF) - class_scope_name = VT (objfile) + dn_temp->dtag.name; - else - class_scope_name = NULL; - -#if 0 - - /* Begin a new scope. */ - SL_INDEX (objfile) = hpread_record_lines (current_subfile, - SL_INDEX (objfile), - dn_bufp->dclass_scope.address, - objfile, offset); - valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile); - valu += offset; /* Relocate for dynamic loading */ - desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile); - /* We use the scope start DNTT index as the nesting depth identifier! */ - new = push_context (desc, valu); -#endif - break; - - case DNTT_TYPE_REFERENCE: - /* Declares a C++ reference type. Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_PTRMEM: - /* Declares a C++ pointer-to-data-member type. This does not - * need to be handled at this level; being a type description it - * is instead handled at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_PTRMEMFUNC: - /* Declares a C++ pointer-to-function-member type. This does not - * need to be handled at this level; being a type description it - * is instead handled at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_CLASS: - /* Declares a class type. - * Should not be necessary to do anything - * with the type at this level; these are processed - * at the hpread_type_lookup() level. - */ - break; - - case DNTT_TYPE_GENFIELD: - /* I believe this is used for class member functions */ - /* Ignored at this level, but hpread_read_struct_type() will take - * care of walking the list of class members. - */ - break; - - case DNTT_TYPE_VFUNC: - /* Virtual function */ - /* This does not have to be handled at this level; handled in - * the course of processing class symbols. - */ - break; - - case DNTT_TYPE_MEMACCESS: - /* DDE ignores this symbol table record. - * It has something to do with "modified access" to class members. - * I'll assume we can safely ignore it too. - */ - break; - - case DNTT_TYPE_INHERITANCE: - /* These don't have to be handled here, since they are handled - * within hpread_read_struct_type() in the process of constructing - * a class type. - */ - break; - - case DNTT_TYPE_FRIEND_CLASS: - case DNTT_TYPE_FRIEND_FUNC: - /* These can safely be ignored, as GDB doesn't need this - * info. DDE only uses it in "describe". We may later want - * to extend GDB's "ptype" to give this info, but for now - * it seems safe enough to ignore it. - */ - break; - - case DNTT_TYPE_MODIFIER: - /* Intended to supply "modified access" to a type */ - /* From the way DDE handles this, it looks like it always - * modifies a type. Therefore it is safe to ignore it at this - * level, and handle it in hpread_type_lookup(). - */ - break; - - case DNTT_TYPE_OBJECT_ID: - /* Just ignore this - that's all DDE does */ - break; - - case DNTT_TYPE_MEMFUNC: - /* Member function */ - /* This does not have to be handled at this level; handled in - * the course of processing class symbols. - */ - break; - - case DNTT_TYPE_DOC_MEMFUNC: - /* Member function */ - /* This does not have to be handled at this level; handled in - * the course of processing class symbols. - */ - break; - - case DNTT_TYPE_TEMPLATE: - /* Template - sort of the header for a template definition, - * which like a class, points to a member list and also points - * to a TEMPLATE_ARG list of type-arguments. - * We do not need to process TEMPLATE records at this level though. - */ - break; - - case DNTT_TYPE_TEMPLATE_ARG: - /* The TEMPLATE record points to an argument list of - * TEMPLATE_ARG records, each of which describes one - * of the type-arguments. - * We do not need to process TEMPLATE_ARG records at this level though. - */ - break; - - case DNTT_TYPE_FUNC_TEMPLATE: - /* This will get emitted for member functions of templates. - * But we don't need to process this record at this level though, - * we will process it in the course of processing a TEMPLATE - * record. - */ - break; - - case DNTT_TYPE_LINK: - /* The LINK record is used to link up templates with instantiations. */ - /* It is not clear why this is needed, and furthermore aCC does - * not appear to generate this, so I think we can safely ignore it. - RT - */ - break; - - /* DNTT_TYPE_DYN_ARRAY_DESC is not handled by GDB */ - /* DNTT_TYPE_DESC_SUBRANGE is not handled by GDB */ - /* DNTT_TYPE_BEGIN_EXT is not handled by GDB */ - /* DNTT_TYPE_INLN is not handled by GDB */ - /* DNTT_TYPE_INLN_LIST is not handled by GDB */ - /* DNTT_TYPE_ALIAS is not handled by GDB */ - - default: - break; - } -} - -/* Get nesting depth for a DNTT entry. - * DN_BUFP points to a DNTT entry. - * OBJFILE is the object file. - * REPORT_NESTED is a flag; if 0, real nesting depth is - * reported, if it is 1, the function simply returns a - * non-zero value if the nesting depth is anything > 0. - * - * Return value is an integer. 0 => not a local type / name - * positive return => type or name is local to some - * block or function. - */ - - -/* elz: ATTENTION: FIXME: NOTE: WARNING!!!! - this function now returns 0 right away. It was taking too much time - at start up. Now, though, the local types are not handled correctly. -*/ - - -static int -hpread_get_scope_depth (dn_bufp, objfile, report_nested) - union dnttentry * dn_bufp; - struct objfile * objfile; - int report_nested; -{ - register int index; - register union dnttentry * dn_tmp; - register short depth = 0; -/****************************/ - return 0; -/****************************/ - - index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block)); - - while (--index >= 0) - { - dn_tmp = hpread_get_lntt (index, objfile); - switch (dn_tmp->dblock.kind) - { - case DNTT_TYPE_MODULE: - return depth; - case DNTT_TYPE_END: - /* index is signed int; dnttp.index is 29-bit unsigned int! */ - index = (int) dn_tmp->dend.beginscope.dnttp.index; - break; - case DNTT_TYPE_BEGIN: - case DNTT_TYPE_FUNCTION: - case DNTT_TYPE_DOC_FUNCTION: - case DNTT_TYPE_WITH: - case DNTT_TYPE_COMMON: - case DNTT_TYPE_CLASS_SCOPE: - depth++; - if (report_nested) - return 1; - break; - default: - break; - } - } - return depth; -} - -/* Adjust the bitoffsets for all fields of an anonymous union of - type TYPE by negative BITS. This handles HP aCC's hideous habit - of giving members of anonymous unions bit offsets relative to the - enclosing structure instead of relative to the union itself. */ - -static void -hpread_adjust_bitoffsets (type, bits) - struct type * type; - int bits; -{ - register int i; - - /* This is done only for unions; caller had better check that - it is an anonymous one. */ - if (TYPE_CODE (type) != TYPE_CODE_UNION) - return; - - /* Adjust each field; since this is a union, there are no base - classes. Also no static membes. Also, no need for recursion as - the members of this union if themeselves structs or unions, have - the correct bitoffsets; if an anonymous union is a member of this - anonymous union, the code in hpread_read_struct_type() will - adjust for that. */ - - for (i = 0; i < TYPE_NFIELDS (type); i++) - TYPE_FIELD_BITPOS (type, i) -= bits; -} - -/* Because of quirks in HP compilers' treatment of anonymous unions inside - classes, we have to chase through a chain of threaded FIELD entries. - If we encounter an anonymous union in the chain, we must recursively skip over - that too. - - This function does a "next" in the chain of FIELD entries, but transparently - skips over anonymous unions' fields (recursively). - - Inputs are the number of times to do "next" at the top level, the dnttpointer - (FIELD) and entry pointer (FIELDP) for the dntt record corresponding to it, - and the ubiquitous objfile parameter. (Note: FIELDP is a **.) Return value - is a dnttpointer for the new field after all the skipped ones */ - -static dnttpointer -hpread_get_next_skip_over_anon_unions (skip_fields, field, fieldp, objfile) - int skip_fields; - dnttpointer field; - union dnttentry ** fieldp; - struct objfile * objfile; -{ - struct type * anon_type; - register int i; - int bitoffset; - char * name; - - for (i=0; i < skip_fields; i++) - { - /* Get type of item we're looking at now; recursively processes the types - of these intermediate items we skip over, so they aren't lost. */ - anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile); - anon_type = CHECK_TYPEDEF (anon_type); - bitoffset = (*fieldp)->dfield.bitoffset; - name = VT (objfile) + (*fieldp)->dfield.name; - /* First skip over one item to avoid stack death on recursion */ - field = (*fieldp)->dfield.nextfield; - *fieldp = hpread_get_lntt (field.dnttp.index, objfile); - /* Do we have another anonymous union? If so, adjust the bitoffsets - of its members and skip over its members. */ - if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) && - (!name || STREQ (name, ""))) - { - hpread_adjust_bitoffsets (anon_type, bitoffset); - field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile); - } - } - return field; -} - - diff --git a/contrib/gdb/gdb/hpread.h b/contrib/gdb/gdb/hpread.h deleted file mode 100644 index 7864dd65150..00000000000 --- a/contrib/gdb/gdb/hpread.h +++ /dev/null @@ -1,150 +0,0 @@ -/* hpread.h - * Common include file for: - * hp_symtab_read.c - * hp_psymtab_read.c - */ - -/* Copyright 1993, 1996 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Written by the Center for Software Science at the University of Utah - and by Cygnus Support. */ - -#include "defs.h" -#include "bfd.h" -#include "gdb_string.h" -#include "hp-symtab.h" -#include "syms.h" -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "complaints.h" -#include "gdb-stabs.h" -#include "gdbtypes.h" -#include "demangle.h" - -/* Private information attached to an objfile which we use to find - and internalize the HP C debug symbols within that objfile. */ - -struct hpread_symfile_info -{ - /* The contents of each of the debug sections (there are 4 of them). */ - char *gntt; - char *lntt; - char *slt; - char *vt; - - /* We keep the size of the $VT$ section for range checking. */ - unsigned int vt_size; - - /* Some routines still need to know the number of symbols in the - main debug sections ($LNTT$ and $GNTT$). */ - unsigned int lntt_symcount; - unsigned int gntt_symcount; - - /* To keep track of all the types we've processed. */ - struct type **type_vector; - int type_vector_length; - - /* Keeps track of the beginning of a range of source lines. */ - sltpointer sl_index; - - /* Some state variables we'll need. */ - int within_function; - - /* Keep track of the current function's address. We may need to look - up something based on this address. */ - unsigned int current_function_value; -}; - -/* Accessor macros to get at the fields. */ -#define HPUX_SYMFILE_INFO(o) \ - ((struct hpread_symfile_info *)((o)->sym_private)) -#define GNTT(o) (HPUX_SYMFILE_INFO(o)->gntt) -#define LNTT(o) (HPUX_SYMFILE_INFO(o)->lntt) -#define SLT(o) (HPUX_SYMFILE_INFO(o)->slt) -#define VT(o) (HPUX_SYMFILE_INFO(o)->vt) -#define VT_SIZE(o) (HPUX_SYMFILE_INFO(o)->vt_size) -#define LNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->lntt_symcount) -#define GNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->gntt_symcount) -#define TYPE_VECTOR(o) (HPUX_SYMFILE_INFO(o)->type_vector) -#define TYPE_VECTOR_LENGTH(o) (HPUX_SYMFILE_INFO(o)->type_vector_length) -#define SL_INDEX(o) (HPUX_SYMFILE_INFO(o)->sl_index) -#define WITHIN_FUNCTION(o) (HPUX_SYMFILE_INFO(o)->within_function) -#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value) - -/* Given the native debug symbol SYM, set NAMEP to the name associated - with the debug symbol. Note we may be called with a debug symbol which - has no associated name, in that case we return an empty string. - - Also note we "know" that the name for any symbol is always in the - same place. Hence we don't have to conditionalize on the symbol type. */ -#define SET_NAMESTRING(SYM, NAMEP, OBJFILE) \ - if (! hpread_has_name ((SYM)->dblock.kind)) \ - *NAMEP = ""; \ - else if (((unsigned)(SYM)->dsfile.name) >= VT_SIZE (OBJFILE)) \ - { \ - complain (&string_table_offset_complaint, (char *) symnum); \ - *NAMEP = ""; \ - } \ - else \ - *NAMEP = (SYM)->dsfile.name + VT (OBJFILE) - -/* We put a pointer to this structure in the read_symtab_private field - of the psymtab. */ - -struct symloc -{ - /* The offset within the file symbol table of first local symbol for - this file. */ - - int ldsymoff; - - /* Length (in bytes) of the section of the symbol table devoted to - this file's symbols (actually, the section bracketed may contain - more than just this file's symbols). If ldsymlen is 0, the only - reason for this thing's existence is the dependency list. - Nothing else will happen when it is read in. */ - - int ldsymlen; -}; - -#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff) -#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen) -#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private)) - -/* FIXME: Shouldn't this stuff be in a .h file somewhere? */ -/* Nonzero means give verbose info on gdb action. */ -extern int info_verbose; - -/* Complaints about the symbols we have encountered. */ -extern struct complaint string_table_offset_complaint; -extern struct complaint lbrac_unmatched_complaint; -extern struct complaint lbrac_mismatch_complaint; - -extern union sltentry *hpread_get_slt - PARAMS ((int, struct objfile *)); - -extern union dnttentry *hpread_get_lntt - PARAMS ((int, struct objfile *)); - -int hpread_has_name - PARAMS ((enum dntt_entry_type)); - -/* end of hpread.h */ diff --git a/contrib/gdb/gdb/i386gnu-nat.c b/contrib/gdb/gdb/i386gnu-nat.c deleted file mode 100644 index 9188ea4c654..00000000000 --- a/contrib/gdb/gdb/i386gnu-nat.c +++ /dev/null @@ -1,271 +0,0 @@ -/* Low level interface to i386 running the GNU Hurd. - Copyright 1992, 1995, 1996, 1998, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "floatformat.h" -#include "regcache.h" - -#include "gdb_assert.h" -#include -#include - -#include -#include -#include -#include - -#include "i386-tdep.h" - -#include "gnu-nat.h" -#include "i387-nat.h" - - -/* Offset to the thread_state_t location where REG is stored. */ -#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg) - -/* At REG_OFFSET[N] is the offset to the thread_state_t location where - the GDB register N is stored. */ -static int reg_offset[] = -{ - REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx), - REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi), - REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss), - REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs) -}; - -#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum]) - - -/* Get the whole floating-point state of THREAD and record the - values of the corresponding (pseudo) registers. */ -static void -fetch_fpregs (struct proc *thread) -{ - mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; - struct i386_float_state state; - error_t err; - - err = thread_get_state (thread->port, i386_FLOAT_STATE, - (thread_state_t) &state, &count); - if (err) - { - warning ("Couldn't fetch floating-point state from %s", - proc_string (thread)); - return; - } - - if (!state.initialized) - /* The floating-point state isn't initialized. */ - { - int i; - - for (i = FP0_REGNUM; i <= FOP_REGNUM; i++) - supply_register (i, NULL); - - return; - } - - /* Supply the floating-point registers. */ - i387_supply_fsave (state.hw_state); -} - -/* Fetch register REGNO, or all regs if REGNO is -1. */ -void -gnu_fetch_registers (int regno) -{ - struct proc *thread; - - /* Make sure we know about new threads. */ - inf_update_procs (current_inferior); - - thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); - if (!thread) - error ("Can't fetch registers from thread %d: No such thread", - PIDGET (inferior_ptid)); - - if (regno < NUM_GREGS || regno == -1) - { - thread_state_t state; - - /* This does the dirty work for us. */ - state = proc_get_state (thread, 0); - if (!state) - { - warning ("Couldn't fetch registers from %s", - proc_string (thread)); - return; - } - - if (regno == -1) - { - int i; - - proc_debug (thread, "fetching all register"); - - for (i = 0; i < NUM_GREGS; i++) - supply_register (i, REG_ADDR (state, i)); - thread->fetched_regs = ~0; - } - else - { - proc_debug (thread, "fetching register %s", REGISTER_NAME (regno)); - - supply_register (regno, REG_ADDR (state, regno)); - thread->fetched_regs |= (1 << regno); - } - } - - if (regno >= NUM_GREGS || regno == -1) - { - proc_debug (thread, "fetching floating-point registers"); - - fetch_fpregs (thread); - } -} - - -/* Store the whole floating-point state into THREAD using information - from the corresponding (pseudo) registers. */ -static void -store_fpregs (struct proc *thread, int regno) -{ - mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; - struct i386_float_state state; - error_t err; - - err = thread_get_state (thread->port, i386_FLOAT_STATE, - (thread_state_t) &state, &count); - if (err) - { - warning ("Couldn't fetch floating-point state from %s", - proc_string (thread)); - return; - } - - /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow - take into account REGISTER_VALID like the old code did? */ - i387_fill_fsave (state.hw_state, regno); - - err = thread_set_state (thread->port, i386_FLOAT_STATE, - (thread_state_t) &state, i386_FLOAT_STATE_COUNT); - if (err) - { - warning ("Couldn't store floating-point state into %s", - proc_string (thread)); - return; - } -} - -/* Store at least register REGNO, or all regs if REGNO == -1. */ -void -gnu_store_registers (int regno) -{ - struct proc *thread; - - /* Make sure we know about new threads. */ - inf_update_procs (current_inferior); - - thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); - if (!thread) - error ("Couldn't store registers into thread %d: No such thread", - PIDGET (inferior_ptid)); - - if (regno < NUM_GREGS || regno == -1) - { - thread_state_t state; - thread_state_data_t old_state; - int was_aborted = thread->aborted; - int was_valid = thread->state_valid; - int trace; - - if (!was_aborted && was_valid) - memcpy (&old_state, &thread->state, sizeof (old_state)); - - state = proc_get_state (thread, 1); - if (!state) - { - warning ("Couldn't store registers into %s", proc_string (thread)); - return; - } - - /* Save the T bit. We might try to restore the %eflags register - below, but changing the T bit would seriously confuse GDB. */ - trace = ((struct i386_thread_state *)state)->efl & 0x100; - - if (!was_aborted && was_valid) - /* See which registers have changed after aborting the thread. */ - { - int check_regno; - - for (check_regno = 0; check_regno < NUM_GREGS; check_regno++) - if ((thread->fetched_regs & (1 << check_regno)) - && memcpy (REG_ADDR (&old_state, check_regno), - REG_ADDR (state, check_regno), - REGISTER_RAW_SIZE (check_regno))) - /* Register CHECK_REGNO has changed! Ack! */ - { - warning ("Register %s changed after the thread was aborted", - REGISTER_NAME (check_regno)); - if (regno >= 0 && regno != check_regno) - /* Update GDB's copy of the register. */ - supply_register (check_regno, REG_ADDR (state, check_regno)); - else - warning ("... also writing this register! Suspicious..."); - } - } - -#define fill(state, regno) \ - memcpy (REG_ADDR(state, regno), ®isters[REGISTER_BYTE (regno)], \ - REGISTER_RAW_SIZE (regno)) - - if (regno == -1) - { - int i; - - proc_debug (thread, "storing all registers"); - - for (i = 0; i < NUM_GREGS; i++) - if (register_valid[i]) - fill (state, i); - } - else - { - proc_debug (thread, "storing register %s", REGISTER_NAME (regno)); - - gdb_assert (register_valid[regno]); - fill (state, regno); - } - - /* Restore the T bit. */ - ((struct i386_thread_state *)state)->efl &= ~0x100; - ((struct i386_thread_state *)state)->efl |= trace; - } - -#undef fill - - if (regno >= NUM_GREGS || regno == -1) - { - proc_debug (thread, "storing floating-point registers"); - - store_fpregs (thread, regno); - } -} diff --git a/contrib/gdb/gdb/irix4-nat.c b/contrib/gdb/gdb/irix4-nat.c deleted file mode 100644 index 0f447767af2..00000000000 --- a/contrib/gdb/gdb/irix4-nat.c +++ /dev/null @@ -1,207 +0,0 @@ -/* Native support for the SGI Iris running IRIX version 4, for GDB. - Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2000, - 2001 Free Software Foundation, Inc. - Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU - and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. - Implemented for Irix 4.x by Garrett A. Wollman. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "gdbcore.h" -#include "regcache.h" - -#include -#include -#include /* For JB_XXX. */ - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* Size of elements in jmpbuf */ - -#define JB_ELEMENT_SIZE 4 - -typedef unsigned int greg_t; /* why isn't this defined? */ - -static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR); - -/* - * See the comment in m68k-tdep.c regarding the utility of these functions. - */ - -void -supply_gregset (gregset_t *gregsetp) -{ - register int regi; - register greg_t *regp = (greg_t *) (gregsetp->gp_regs); - static char zerobuf[MAX_REGISTER_RAW_SIZE] = - {0}; - - /* FIXME: somewhere, there should be a #define for the meaning - of this magic number 32; we should use that. */ - for (regi = 0; regi < 32; regi++) - supply_register (regi, (char *) (regp + regi)); - - supply_register (PC_REGNUM, (char *) &(gregsetp->gp_pc)); - supply_register (HI_REGNUM, (char *) &(gregsetp->gp_mdhi)); - supply_register (LO_REGNUM, (char *) &(gregsetp->gp_mdlo)); - supply_register (CAUSE_REGNUM, (char *) &(gregsetp->gp_cause)); - - /* Fill inaccessible registers with zero. */ - supply_register (BADVADDR_REGNUM, zerobuf); -} - -void -fill_gregset (gregset_t *gregsetp, int regno) -{ - int regi; - register greg_t *regp = (greg_t *) (gregsetp->gp_regs); - - /* same FIXME as above wrt 32 */ - for (regi = 0; regi < 32; regi++) - if ((regno == -1) || (regno == regi)) - *(regp + regi) = *(greg_t *) & registers[REGISTER_BYTE (regi)]; - - if ((regno == -1) || (regno == PC_REGNUM)) - gregsetp->gp_pc = *(greg_t *) & registers[REGISTER_BYTE (PC_REGNUM)]; - - if ((regno == -1) || (regno == CAUSE_REGNUM)) - gregsetp->gp_cause = *(greg_t *) & registers[REGISTER_BYTE (CAUSE_REGNUM)]; - - if ((regno == -1) || (regno == HI_REGNUM)) - gregsetp->gp_mdhi = *(greg_t *) & registers[REGISTER_BYTE (HI_REGNUM)]; - - if ((regno == -1) || (regno == LO_REGNUM)) - gregsetp->gp_mdlo = *(greg_t *) & registers[REGISTER_BYTE (LO_REGNUM)]; -} - -/* - * Now we do the same thing for floating-point registers. - * We don't bother to condition on FP0_REGNUM since any - * reasonable MIPS configuration has an R3010 in it. - * - * Again, see the comments in m68k-tdep.c. - */ - -void -supply_fpregset (fpregset_t *fpregsetp) -{ - register int regi; - static char zerobuf[MAX_REGISTER_RAW_SIZE] = - {0}; - - for (regi = 0; regi < 32; regi++) - supply_register (FP0_REGNUM + regi, - (char *) &fpregsetp->fp_r.fp_regs[regi]); - - supply_register (FCRCS_REGNUM, (char *) &fpregsetp->fp_csr); - - /* FIXME: how can we supply FCRIR_REGNUM? SGI doesn't tell us. */ - supply_register (FCRIR_REGNUM, zerobuf); -} - -void -fill_fpregset (fpregset_t *fpregsetp, int regno) -{ - int regi; - char *from, *to; - - for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++) - { - if ((regno == -1) || (regno == regi)) - { - from = (char *) ®isters[REGISTER_BYTE (regi)]; - to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]); - memcpy (to, from, REGISTER_RAW_SIZE (regi)); - } - } - - if ((regno == -1) || (regno == FCRCS_REGNUM)) - fpregsetp->fp_csr = *(unsigned *) ®isters[REGISTER_BYTE (FCRCS_REGNUM)]; -} - - -/* Figure out where the longjmp will land. - We expect the first arg to be a pointer to the jmp_buf structure from which - we extract the pc (JB_PC) that we will land at. The pc is copied into PC. - This routine returns true on success. */ - -int -get_longjmp_target (CORE_ADDR *pc) -{ - char *buf; - CORE_ADDR jb_addr; - - buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT); - jb_addr = read_register (A0_REGNUM); - - if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) - return 0; - - *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); - - return 1; -} - -/* Provide registers to GDB from a core file. - - CORE_REG_SECT points to an array of bytes, which were obtained from - a core file which BFD thinks might contain register contents. - CORE_REG_SIZE is its size. - - Normally, WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set - 2 --- the floating-point register set - However, for Irix 4, WHICH isn't used. - - REG_ADDR is also unused. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) -{ - if (core_reg_size != REGISTER_BYTES) - { - warning ("wrong size gregset struct in core file"); - return; - } - - memcpy ((char *) registers, core_reg_sect, core_reg_size); -} - - -/* Register that we are able to handle irix4 core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns irix4_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_core_irix4 (void) -{ - add_core_fns (&irix4_core_fns); -} diff --git a/contrib/gdb/gdb/irix5-nat.c b/contrib/gdb/gdb/irix5-nat.c deleted file mode 100644 index 459abe3879c..00000000000 --- a/contrib/gdb/gdb/irix5-nat.c +++ /dev/null @@ -1,1320 +0,0 @@ -/* Native support for the SGI Iris running IRIX version 5, for GDB. - Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001 Free Software Foundation, Inc. - Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU - and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. - Implemented for Irix 4.x by Garrett A. Wollman. - Modified for Irix 5.x by Ian Lance Taylor. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "gdbcore.h" -#include "target.h" -#include "regcache.h" - -#include "gdb_string.h" -#include -#include -#include /* For JB_XXX. */ - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR); - -/* Size of elements in jmpbuf */ - -#define JB_ELEMENT_SIZE 4 - -/* - * See the comment in m68k-tdep.c regarding the utility of these functions. - * - * These definitions are from the MIPS SVR4 ABI, so they may work for - * any MIPS SVR4 target. - */ - -void -supply_gregset (gregset_t *gregsetp) -{ - register int regi; - register greg_t *regp = &(*gregsetp)[0]; - int gregoff = sizeof (greg_t) - MIPS_REGSIZE; - static char zerobuf[MAX_REGISTER_RAW_SIZE] = - {0}; - - for (regi = 0; regi <= CTX_RA; regi++) - supply_register (regi, (char *) (regp + regi) + gregoff); - - supply_register (PC_REGNUM, (char *) (regp + CTX_EPC) + gregoff); - supply_register (HI_REGNUM, (char *) (regp + CTX_MDHI) + gregoff); - supply_register (LO_REGNUM, (char *) (regp + CTX_MDLO) + gregoff); - supply_register (CAUSE_REGNUM, (char *) (regp + CTX_CAUSE) + gregoff); - - /* Fill inaccessible registers with zero. */ - supply_register (BADVADDR_REGNUM, zerobuf); -} - -void -fill_gregset (gregset_t *gregsetp, int regno) -{ - int regi; - register greg_t *regp = &(*gregsetp)[0]; - - /* Under Irix6, if GDB is built with N32 ABI and is debugging an O32 - executable, we have to sign extend the registers to 64 bits before - filling in the gregset structure. */ - - for (regi = 0; regi <= CTX_RA; regi++) - if ((regno == -1) || (regno == regi)) - *(regp + regi) = - extract_signed_integer (®isters[REGISTER_BYTE (regi)], - REGISTER_RAW_SIZE (regi)); - - if ((regno == -1) || (regno == PC_REGNUM)) - *(regp + CTX_EPC) = - extract_signed_integer (®isters[REGISTER_BYTE (PC_REGNUM)], - REGISTER_RAW_SIZE (PC_REGNUM)); - - if ((regno == -1) || (regno == CAUSE_REGNUM)) - *(regp + CTX_CAUSE) = - extract_signed_integer (®isters[REGISTER_BYTE (CAUSE_REGNUM)], - REGISTER_RAW_SIZE (CAUSE_REGNUM)); - - if ((regno == -1) || (regno == HI_REGNUM)) - *(regp + CTX_MDHI) = - extract_signed_integer (®isters[REGISTER_BYTE (HI_REGNUM)], - REGISTER_RAW_SIZE (HI_REGNUM)); - - if ((regno == -1) || (regno == LO_REGNUM)) - *(regp + CTX_MDLO) = - extract_signed_integer (®isters[REGISTER_BYTE (LO_REGNUM)], - REGISTER_RAW_SIZE (LO_REGNUM)); -} - -/* - * Now we do the same thing for floating-point registers. - * We don't bother to condition on FP0_REGNUM since any - * reasonable MIPS configuration has an R3010 in it. - * - * Again, see the comments in m68k-tdep.c. - */ - -void -supply_fpregset (fpregset_t *fpregsetp) -{ - register int regi; - static char zerobuf[MAX_REGISTER_RAW_SIZE] = - {0}; - - /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */ - - for (regi = 0; regi < 32; regi++) - supply_register (FP0_REGNUM + regi, - (char *) &fpregsetp->fp_r.fp_regs[regi]); - - supply_register (FCRCS_REGNUM, (char *) &fpregsetp->fp_csr); - - /* FIXME: how can we supply FCRIR_REGNUM? SGI doesn't tell us. */ - supply_register (FCRIR_REGNUM, zerobuf); -} - -void -fill_fpregset (fpregset_t *fpregsetp, int regno) -{ - int regi; - char *from, *to; - - /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */ - - for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++) - { - if ((regno == -1) || (regno == regi)) - { - from = (char *) ®isters[REGISTER_BYTE (regi)]; - to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]); - memcpy (to, from, REGISTER_RAW_SIZE (regi)); - } - } - - if ((regno == -1) || (regno == FCRCS_REGNUM)) - fpregsetp->fp_csr = *(unsigned *) ®isters[REGISTER_BYTE (FCRCS_REGNUM)]; -} - - -/* Figure out where the longjmp will land. - We expect the first arg to be a pointer to the jmp_buf structure from which - we extract the pc (JB_PC) that we will land at. The pc is copied into PC. - This routine returns true on success. */ - -int -get_longjmp_target (CORE_ADDR *pc) -{ - char *buf; - CORE_ADDR jb_addr; - - buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT); - jb_addr = read_register (A0_REGNUM); - - if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) - return 0; - - *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); - - return 1; -} - -/* Provide registers to GDB from a core file. - - CORE_REG_SECT points to an array of bytes, which were obtained from - a core file which BFD thinks might contain register contents. - CORE_REG_SIZE is its size. - - Normally, WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set - 2 --- the floating-point register set - However, for Irix 5, WHICH isn't used. - - REG_ADDR is also unused. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) -{ - if (core_reg_size == REGISTER_BYTES) - { - memcpy ((char *) registers, core_reg_sect, core_reg_size); - } - else if (MIPS_REGSIZE == 4 && - core_reg_size == (2 * MIPS_REGSIZE) * NUM_REGS) - { - /* This is a core file from a N32 executable, 64 bits are saved - for all registers. */ - char *srcp = core_reg_sect; - char *dstp = registers; - int regno; - - for (regno = 0; regno < NUM_REGS; regno++) - { - if (regno >= FP0_REGNUM && regno < (FP0_REGNUM + 32)) - { - /* FIXME, this is wrong, N32 has 64 bit FP regs, but GDB - currently assumes that they are 32 bit. */ - *dstp++ = *srcp++; - *dstp++ = *srcp++; - *dstp++ = *srcp++; - *dstp++ = *srcp++; - if (REGISTER_RAW_SIZE (regno) == 4) - { - /* copying 4 bytes from eight bytes? - I don't see how this can be right... */ - srcp += 4; - } - else - { - /* copy all 8 bytes (sizeof(double)) */ - *dstp++ = *srcp++; - *dstp++ = *srcp++; - *dstp++ = *srcp++; - *dstp++ = *srcp++; - } - } - else - { - srcp += 4; - *dstp++ = *srcp++; - *dstp++ = *srcp++; - *dstp++ = *srcp++; - *dstp++ = *srcp++; - } - } - } - else - { - warning ("wrong size gregset struct in core file"); - return; - } - - registers_fetched (); -} - -/* Irix 5 uses what appears to be a unique form of shared library - support. This is a copy of solib.c modified for Irix 5. */ -/* FIXME: Most of this code could be merged with osfsolib.c and solib.c - by using next_link_map_member and xfer_link_map_member in solib.c. */ - -#include -#include -#include -#include - -/* includes and , which causes conflicts - with our versions of those files included by tm-mips.h. Prevent - from including them with some appropriate defines. */ -#define __SYM_H__ -#define __SYMCONST_H__ -#include -#ifdef HAVE_OBJLIST_H -#include -#endif - -#ifdef NEW_OBJ_INFO_MAGIC -#define HANDLE_NEW_OBJ_LIST -#endif - -#include "symtab.h" -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "command.h" -#include "frame.h" -#include "gdb_regex.h" -#include "inferior.h" -#include "language.h" -#include "gdbcmd.h" - -/* The symbol which starts off the list of shared libraries. */ -#define DEBUG_BASE "__rld_obj_head" - -/* Irix 6.x introduces a new variant of object lists. - To be able to debug O32 executables under Irix 6, we have to handle both - variants. */ - -typedef enum -{ - OBJ_LIST_OLD, /* Pre Irix 6.x object list. */ - OBJ_LIST_32, /* 32 Bit Elf32_Obj_Info. */ - OBJ_LIST_64 /* 64 Bit Elf64_Obj_Info, FIXME not yet implemented. */ -} -obj_list_variant; - -/* Define our own link_map structure. - This will help to share code with osfsolib.c and solib.c. */ - -struct link_map - { - obj_list_variant l_variant; /* which variant of object list */ - CORE_ADDR l_lladdr; /* addr in inferior list was read from */ - CORE_ADDR l_next; /* address of next object list entry */ - }; - -/* Irix 5 shared objects are pre-linked to particular addresses - although the dynamic linker may have to relocate them if the - address ranges of the libraries used by the main program clash. - The offset is the difference between the address where the object - is mapped and the binding address of the shared library. */ -#define LM_OFFSET(so) ((so) -> offset) -/* Loaded address of shared library. */ -#define LM_ADDR(so) ((so) -> lmstart) - -char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */ - -struct so_list - { - struct so_list *next; /* next structure in linked list */ - struct link_map lm; - CORE_ADDR offset; /* prelink to load address offset */ - char *so_name; /* shared object lib name */ - CORE_ADDR lmstart; /* lower addr bound of mapped object */ - CORE_ADDR lmend; /* upper addr bound of mapped object */ - char symbols_loaded; /* flag: symbols read in yet? */ - char from_tty; /* flag: print msgs? */ - struct objfile *objfile; /* objfile for loaded lib */ - struct section_table *sections; - struct section_table *sections_end; - struct section_table *textsection; - bfd *abfd; - }; - -static struct so_list *so_list_head; /* List of known shared objects */ -static CORE_ADDR debug_base; /* Base of dynamic linker structures */ -static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ - -/* Local function prototypes */ - -static void sharedlibrary_command (char *, int); - -static int enable_break (void); - -static int disable_break (void); - -static void info_sharedlibrary_command (char *, int); - -static int symbol_add_stub (void *); - -static struct so_list *find_solib (struct so_list *); - -static struct link_map *first_link_map_member (void); - -static struct link_map *next_link_map_member (struct so_list *); - -static void xfer_link_map_member (struct so_list *, struct link_map *); - -static CORE_ADDR locate_base (void); - -static int solib_map_sections (void *); - -/* - - LOCAL FUNCTION - - solib_map_sections -- open bfd and build sections for shared lib - - SYNOPSIS - - static int solib_map_sections (struct so_list *so) - - DESCRIPTION - - Given a pointer to one of the shared objects in our list - of mapped objects, use the recorded name to open a bfd - descriptor for the object, build a section table, and then - relocate all the section addresses by the base address at - which the shared object was mapped. - - FIXMES - - In most (all?) cases the shared object file name recorded in the - dynamic linkage tables will be a fully qualified pathname. For - cases where it isn't, do we really mimic the systems search - mechanism correctly in the below code (particularly the tilde - expansion stuff?). - */ - -static int -solib_map_sections (void *arg) -{ - struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */ - char *filename; - char *scratch_pathname; - int scratch_chan; - struct section_table *p; - struct cleanup *old_chain; - bfd *abfd; - - filename = tilde_expand (so->so_name); - old_chain = make_cleanup (xfree, filename); - - scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, - &scratch_pathname); - if (scratch_chan < 0) - { - scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename, - O_RDONLY, 0, &scratch_pathname); - } - if (scratch_chan < 0) - { - perror_with_name (filename); - } - /* Leave scratch_pathname allocated. abfd->name will point to it. */ - - abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan); - if (!abfd) - { - close (scratch_chan); - error ("Could not open `%s' as an executable file: %s", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } - /* Leave bfd open, core_xfer_memory and "info files" need it. */ - so->abfd = abfd; - abfd->cacheable = 1; - - if (!bfd_check_format (abfd, bfd_object)) - { - error ("\"%s\": not in executable format: %s.", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } - if (build_section_table (abfd, &so->sections, &so->sections_end)) - { - error ("Can't find the file sections in `%s': %s", - bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ())); - } - - for (p = so->sections; p < so->sections_end; p++) - { - /* Relocate the section binding addresses as recorded in the shared - object's file by the offset to get the address to which the - object was actually mapped. */ - p->addr += LM_OFFSET (so); - p->endaddr += LM_OFFSET (so); - so->lmend = (CORE_ADDR) max (p->endaddr, so->lmend); - if (STREQ (p->the_bfd_section->name, ".text")) - { - so->textsection = p; - } - } - - /* Free the file names, close the file now. */ - do_cleanups (old_chain); - - /* must be non-zero */ - return (1); -} - -/* - - LOCAL FUNCTION - - locate_base -- locate the base address of dynamic linker structs - - SYNOPSIS - - CORE_ADDR locate_base (void) - - DESCRIPTION - - For both the SunOS and SVR4 shared library implementations, if the - inferior executable has been linked dynamically, there is a single - address somewhere in the inferior's data space which is the key to - locating all of the dynamic linker's runtime structures. This - address is the value of the symbol defined by the macro DEBUG_BASE. - The job of this function is to find and return that address, or to - return 0 if there is no such address (the executable is statically - linked for example). - - For SunOS, the job is almost trivial, since the dynamic linker and - all of it's structures are statically linked to the executable at - link time. Thus the symbol for the address we are looking for has - already been added to the minimal symbol table for the executable's - objfile at the time the symbol file's symbols were read, and all we - have to do is look it up there. Note that we explicitly do NOT want - to find the copies in the shared library. - - The SVR4 version is much more complicated because the dynamic linker - and it's structures are located in the shared C library, which gets - run as the executable's "interpreter" by the kernel. We have to go - to a lot more work to discover the address of DEBUG_BASE. Because - of this complexity, we cache the value we find and return that value - on subsequent invocations. Note there is no copy in the executable - symbol tables. - - Irix 5 is basically like SunOS. - - Note that we can assume nothing about the process state at the time - we need to find this address. We may be stopped on the first instruc- - tion of the interpreter (C shared library), the first instruction of - the executable itself, or somewhere else entirely (if we attached - to the process for example). - - */ - -static CORE_ADDR -locate_base (void) -{ - struct minimal_symbol *msymbol; - CORE_ADDR address = 0; - - msymbol = lookup_minimal_symbol (DEBUG_BASE, NULL, symfile_objfile); - if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) - { - address = SYMBOL_VALUE_ADDRESS (msymbol); - } - return (address); -} - -/* - - LOCAL FUNCTION - - first_link_map_member -- locate first member in dynamic linker's map - - SYNOPSIS - - static struct link_map *first_link_map_member (void) - - DESCRIPTION - - Read in a copy of the first member in the inferior's dynamic - link map from the inferior's dynamic linker structures, and return - a pointer to the link map descriptor. - */ - -static struct link_map * -first_link_map_member (void) -{ - struct obj_list *listp; - struct obj_list list_old; - struct link_map *lm; - static struct link_map first_lm; - CORE_ADDR lladdr; - CORE_ADDR next_lladdr; - - /* We have not already read in the dynamic linking structures - from the inferior, lookup the address of the base structure. */ - debug_base = locate_base (); - if (debug_base == 0) - return NULL; - - /* Get address of first list entry. */ - read_memory (debug_base, (char *) &listp, sizeof (struct obj_list *)); - - if (listp == NULL) - return NULL; - - /* Get first list entry. */ - /* The MIPS Sign extends addresses. */ - lladdr = host_pointer_to_address (listp); - read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list)); - - /* The first entry in the list is the object file we are debugging, - so skip it. */ - next_lladdr = host_pointer_to_address (list_old.next); - -#ifdef HANDLE_NEW_OBJ_LIST - if (list_old.data == NEW_OBJ_INFO_MAGIC) - { - Elf32_Obj_Info list_32; - - read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info)); - if (list_32.oi_size != sizeof (Elf32_Obj_Info)) - return NULL; - next_lladdr = (CORE_ADDR) list_32.oi_next; - } -#endif - - if (next_lladdr == 0) - return NULL; - - first_lm.l_lladdr = next_lladdr; - lm = &first_lm; - return lm; -} - -/* - - LOCAL FUNCTION - - next_link_map_member -- locate next member in dynamic linker's map - - SYNOPSIS - - static struct link_map *next_link_map_member (so_list_ptr) - - DESCRIPTION - - Read in a copy of the next member in the inferior's dynamic - link map from the inferior's dynamic linker structures, and return - a pointer to the link map descriptor. - */ - -static struct link_map * -next_link_map_member (struct so_list *so_list_ptr) -{ - struct link_map *lm = &so_list_ptr->lm; - CORE_ADDR next_lladdr = lm->l_next; - static struct link_map next_lm; - - if (next_lladdr == 0) - { - /* We have hit the end of the list, so check to see if any were - added, but be quiet if we can't read from the target any more. */ - int status = 0; - - if (lm->l_variant == OBJ_LIST_OLD) - { - struct obj_list list_old; - - status = target_read_memory (lm->l_lladdr, - (char *) &list_old, - sizeof (struct obj_list)); - next_lladdr = host_pointer_to_address (list_old.next); - } -#ifdef HANDLE_NEW_OBJ_LIST - else if (lm->l_variant == OBJ_LIST_32) - { - Elf32_Obj_Info list_32; - status = target_read_memory (lm->l_lladdr, - (char *) &list_32, - sizeof (Elf32_Obj_Info)); - next_lladdr = (CORE_ADDR) list_32.oi_next; - } -#endif - - if (status != 0 || next_lladdr == 0) - return NULL; - } - - next_lm.l_lladdr = next_lladdr; - lm = &next_lm; - return lm; -} - -/* - - LOCAL FUNCTION - - xfer_link_map_member -- set local variables from dynamic linker's map - - SYNOPSIS - - static void xfer_link_map_member (so_list_ptr, lm) - - DESCRIPTION - - Read in a copy of the requested member in the inferior's dynamic - link map from the inferior's dynamic linker structures, and fill - in the necessary so_list_ptr elements. - */ - -static void -xfer_link_map_member (struct so_list *so_list_ptr, struct link_map *lm) -{ - struct obj_list list_old; - CORE_ADDR lladdr = lm->l_lladdr; - struct link_map *new_lm = &so_list_ptr->lm; - int errcode; - - read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list)); - - new_lm->l_variant = OBJ_LIST_OLD; - new_lm->l_lladdr = lladdr; - new_lm->l_next = host_pointer_to_address (list_old.next); - -#ifdef HANDLE_NEW_OBJ_LIST - if (list_old.data == NEW_OBJ_INFO_MAGIC) - { - Elf32_Obj_Info list_32; - - read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info)); - if (list_32.oi_size != sizeof (Elf32_Obj_Info)) - return; - new_lm->l_variant = OBJ_LIST_32; - new_lm->l_next = (CORE_ADDR) list_32.oi_next; - - target_read_string ((CORE_ADDR) list_32.oi_pathname, - &so_list_ptr->so_name, - list_32.oi_pathname_len + 1, &errcode); - if (errcode != 0) - memory_error (errcode, (CORE_ADDR) list_32.oi_pathname); - - LM_ADDR (so_list_ptr) = (CORE_ADDR) list_32.oi_ehdr; - LM_OFFSET (so_list_ptr) = - (CORE_ADDR) list_32.oi_ehdr - (CORE_ADDR) list_32.oi_orig_ehdr; - } - else -#endif - { -#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32 - /* If we are compiling GDB under N32 ABI, the alignments in - the obj struct are different from the O32 ABI and we will get - wrong values when accessing the struct. - As a workaround we use fixed values which are good for - Irix 6.2. */ - char buf[432]; - - read_memory ((CORE_ADDR) list_old.data, buf, sizeof (buf)); - - target_read_string (extract_address (&buf[236], 4), - &so_list_ptr->so_name, - INT_MAX, &errcode); - if (errcode != 0) - memory_error (errcode, extract_address (&buf[236], 4)); - - LM_ADDR (so_list_ptr) = extract_address (&buf[196], 4); - LM_OFFSET (so_list_ptr) = - extract_address (&buf[196], 4) - extract_address (&buf[248], 4); -#else - struct obj obj_old; - - read_memory ((CORE_ADDR) list_old.data, (char *) &obj_old, - sizeof (struct obj)); - - target_read_string ((CORE_ADDR) obj_old.o_path, - &so_list_ptr->so_name, - INT_MAX, &errcode); - if (errcode != 0) - memory_error (errcode, (CORE_ADDR) obj_old.o_path); - - LM_ADDR (so_list_ptr) = (CORE_ADDR) obj_old.o_praw; - LM_OFFSET (so_list_ptr) = - (CORE_ADDR) obj_old.o_praw - obj_old.o_base_address; -#endif - } - - catch_errors (solib_map_sections, (char *) so_list_ptr, - "Error while mapping shared library sections:\n", - RETURN_MASK_ALL); -} - - -/* - - LOCAL FUNCTION - - find_solib -- step through list of shared objects - - SYNOPSIS - - struct so_list *find_solib (struct so_list *so_list_ptr) - - DESCRIPTION - - This module contains the routine which finds the names of any - loaded "images" in the current process. The argument in must be - NULL on the first call, and then the returned value must be passed - in on subsequent calls. This provides the capability to "step" down - the list of loaded objects. On the last object, a NULL value is - returned. - */ - -static struct so_list * -find_solib (struct so_list *so_list_ptr) -{ - struct so_list *so_list_next = NULL; - struct link_map *lm = NULL; - struct so_list *new; - - if (so_list_ptr == NULL) - { - /* We are setting up for a new scan through the loaded images. */ - if ((so_list_next = so_list_head) == NULL) - { - /* Find the first link map list member. */ - lm = first_link_map_member (); - } - } - else - { - /* We have been called before, and are in the process of walking - the shared library list. Advance to the next shared object. */ - lm = next_link_map_member (so_list_ptr); - so_list_next = so_list_ptr->next; - } - if ((so_list_next == NULL) && (lm != NULL)) - { - new = (struct so_list *) xmalloc (sizeof (struct so_list)); - memset ((char *) new, 0, sizeof (struct so_list)); - /* Add the new node as the next node in the list, or as the root - node if this is the first one. */ - if (so_list_ptr != NULL) - { - so_list_ptr->next = new; - } - else - { - so_list_head = new; - } - so_list_next = new; - xfer_link_map_member (new, lm); - } - return (so_list_next); -} - -/* A small stub to get us past the arg-passing pinhole of catch_errors. */ - -static int -symbol_add_stub (void *arg) -{ - register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ - CORE_ADDR text_addr = 0; - struct section_addr_info section_addrs; - - memset (§ion_addrs, 0, sizeof (section_addrs)); - if (so->textsection) - text_addr = so->textsection->addr; - else if (so->abfd != NULL) - { - asection *lowest_sect; - - /* If we didn't find a mapped non zero sized .text section, set up - text_addr so that the relocation in symbol_file_add does no harm. */ - - lowest_sect = bfd_get_section_by_name (so->abfd, ".text"); - if (lowest_sect == NULL) - bfd_map_over_sections (so->abfd, find_lowest_section, - (PTR) &lowest_sect); - if (lowest_sect) - text_addr = bfd_section_vma (so->abfd, lowest_sect) + LM_OFFSET (so); - } - - - section_addrs.other[0].name = ".text"; - section_addrs.other[0].addr = text_addr; - so->objfile = symbol_file_add (so->so_name, so->from_tty, - §ion_addrs, 0, 0); - /* must be non-zero */ - return (1); -} - -/* - - GLOBAL FUNCTION - - solib_add -- add a shared library file to the symtab and section list - - SYNOPSIS - - void solib_add (char *arg_string, int from_tty, - struct target_ops *target, int readsyms) - - DESCRIPTION - - */ - -void -solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) -{ - register struct so_list *so = NULL; /* link map state variable */ - - /* Last shared library that we read. */ - struct so_list *so_last = NULL; - - char *re_err; - int count; - int old; - - if (!readsyms) - return; - - if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL) - { - error ("Invalid regexp: %s", re_err); - } - - /* Add the shared library sections to the section table of the - specified target, if any. */ - if (target) - { - /* Count how many new section_table entries there are. */ - so = NULL; - count = 0; - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0]) - { - count += so->sections_end - so->sections; - } - } - - if (count) - { - old = target_resize_to_sections (target, count); - - /* Add these section table entries to the target's table. */ - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0]) - { - count = so->sections_end - so->sections; - memcpy ((char *) (target->to_sections + old), - so->sections, - (sizeof (struct section_table)) * count); - old += count; - } - } - } - } - - /* Now add the symbol files. */ - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0] && re_exec (so->so_name)) - { - so->from_tty = from_tty; - if (so->symbols_loaded) - { - if (from_tty) - { - printf_unfiltered ("Symbols already loaded for %s\n", so->so_name); - } - } - else if (catch_errors - (symbol_add_stub, (char *) so, - "Error while reading shared library symbols:\n", - RETURN_MASK_ALL)) - { - so_last = so; - so->symbols_loaded = 1; - } - } - } - - /* Getting new symbols may change our opinion about what is - frameless. */ - if (so_last) - reinit_frame_cache (); -} - -/* - - LOCAL FUNCTION - - info_sharedlibrary_command -- code for "info sharedlibrary" - - SYNOPSIS - - static void info_sharedlibrary_command () - - DESCRIPTION - - Walk through the shared library list and print information - about each attached library. - */ - -static void -info_sharedlibrary_command (char *ignore, int from_tty) -{ - register struct so_list *so = NULL; /* link map state variable */ - int header_done = 0; - - if (exec_bfd == NULL) - { - printf_unfiltered ("No executable file.\n"); - return; - } - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0]) - { - if (!header_done) - { - printf_unfiltered ("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read", - "Shared Object Library"); - header_done++; - } - printf_unfiltered ("%-12s", - local_hex_string_custom ((unsigned long) LM_ADDR (so), - "08l")); - printf_unfiltered ("%-12s", - local_hex_string_custom ((unsigned long) so->lmend, - "08l")); - printf_unfiltered ("%-12s", so->symbols_loaded ? "Yes" : "No"); - printf_unfiltered ("%s\n", so->so_name); - } - } - if (so_list_head == NULL) - { - printf_unfiltered ("No shared libraries loaded at this time.\n"); - } -} - -/* - - GLOBAL FUNCTION - - solib_address -- check to see if an address is in a shared lib - - SYNOPSIS - - char *solib_address (CORE_ADDR address) - - DESCRIPTION - - Provides a hook for other gdb routines to discover whether or - not a particular address is within the mapped address space of - a shared library. Any address between the base mapping address - and the first address beyond the end of the last mapping, is - considered to be within the shared library address space, for - our purposes. - - For example, this routine is called at one point to disable - breakpoints which are in shared libraries that are not currently - mapped in. - */ - -char * -solib_address (CORE_ADDR address) -{ - register struct so_list *so = 0; /* link map state variable */ - - while ((so = find_solib (so)) != NULL) - { - if (so->so_name[0]) - { - if ((address >= (CORE_ADDR) LM_ADDR (so)) && - (address < (CORE_ADDR) so->lmend)) - return (so->so_name); - } - } - return (0); -} - -/* Called by free_all_symtabs */ - -void -clear_solib (void) -{ - struct so_list *next; - char *bfd_filename; - - disable_breakpoints_in_shlibs (1); - - while (so_list_head) - { - if (so_list_head->sections) - { - xfree (so_list_head->sections); - } - if (so_list_head->abfd) - { - remove_target_sections (so_list_head->abfd); - bfd_filename = bfd_get_filename (so_list_head->abfd); - if (!bfd_close (so_list_head->abfd)) - warning ("cannot close \"%s\": %s", - bfd_filename, bfd_errmsg (bfd_get_error ())); - } - else - /* This happens for the executable on SVR4. */ - bfd_filename = NULL; - - next = so_list_head->next; - if (bfd_filename) - xfree (bfd_filename); - xfree (so_list_head->so_name); - xfree (so_list_head); - so_list_head = next; - } - debug_base = 0; -} - -/* - - LOCAL FUNCTION - - disable_break -- remove the "mapping changed" breakpoint - - SYNOPSIS - - static int disable_break () - - DESCRIPTION - - Removes the breakpoint that gets hit when the dynamic linker - completes a mapping change. - - */ - -static int -disable_break (void) -{ - int status = 1; - - - /* Note that breakpoint address and original contents are in our address - space, so we just need to write the original contents back. */ - - if (memory_remove_breakpoint (breakpoint_addr, shadow_contents) != 0) - { - status = 0; - } - - /* For the SVR4 version, we always know the breakpoint address. For the - SunOS version we don't know it until the above code is executed. - Grumble if we are stopped anywhere besides the breakpoint address. */ - - if (stop_pc != breakpoint_addr) - { - warning ("stopped at unknown breakpoint while handling shared libraries"); - } - - return (status); -} - -/* - - LOCAL FUNCTION - - enable_break -- arrange for dynamic linker to hit breakpoint - - SYNOPSIS - - int enable_break (void) - - DESCRIPTION - - This functions inserts a breakpoint at the entry point of the - main executable, where all shared libraries are mapped in. - */ - -static int -enable_break (void) -{ - if (symfile_objfile != NULL - && target_insert_breakpoint (symfile_objfile->ei.entry_point, - shadow_contents) == 0) - { - breakpoint_addr = symfile_objfile->ei.entry_point; - return 1; - } - - return 0; -} - -/* - - GLOBAL FUNCTION - - solib_create_inferior_hook -- shared library startup support - - SYNOPSIS - - void solib_create_inferior_hook() - - DESCRIPTION - - When gdb starts up the inferior, it nurses it along (through the - shell) until it is ready to execute it's first instruction. At this - point, this function gets called via expansion of the macro - SOLIB_CREATE_INFERIOR_HOOK. - - For SunOS executables, this first instruction is typically the - one at "_start", or a similar text label, regardless of whether - the executable is statically or dynamically linked. The runtime - startup code takes care of dynamically linking in any shared - libraries, once gdb allows the inferior to continue. - - For SVR4 executables, this first instruction is either the first - instruction in the dynamic linker (for dynamically linked - executables) or the instruction at "start" for statically linked - executables. For dynamically linked executables, the system - first exec's /lib/libc.so.N, which contains the dynamic linker, - and starts it running. The dynamic linker maps in any needed - shared libraries, maps in the actual user executable, and then - jumps to "start" in the user executable. - - For both SunOS shared libraries, and SVR4 shared libraries, we - can arrange to cooperate with the dynamic linker to discover the - names of shared libraries that are dynamically linked, and the - base addresses to which they are linked. - - This function is responsible for discovering those names and - addresses, and saving sufficient information about them to allow - their symbols to be read at a later time. - - FIXME - - Between enable_break() and disable_break(), this code does not - properly handle hitting breakpoints which the user might have - set in the startup code or in the dynamic linker itself. Proper - handling will probably have to wait until the implementation is - changed to use the "breakpoint handler function" method. - - Also, what if child has exit()ed? Must exit loop somehow. - */ - -void -solib_create_inferior_hook (void) -{ - if (!enable_break ()) - { - warning ("shared library handler failed to enable breakpoint"); - return; - } - - /* Now run the target. It will eventually hit the breakpoint, at - which point all of the libraries will have been mapped in and we - can go groveling around in the dynamic linker structures to find - out what we need to know about them. */ - - clear_proceed_status (); - stop_soon_quietly = 1; - stop_signal = TARGET_SIGNAL_0; - do - { - target_resume (pid_to_ptid (-1), 0, stop_signal); - wait_for_inferior (); - } - while (stop_signal != TARGET_SIGNAL_TRAP); - - /* We are now either at the "mapping complete" breakpoint (or somewhere - else, a condition we aren't prepared to deal with anyway), so adjust - the PC as necessary after a breakpoint, disable the breakpoint, and - add any shared libraries that were mapped in. */ - - if (DECR_PC_AFTER_BREAK) - { - stop_pc -= DECR_PC_AFTER_BREAK; - write_register (PC_REGNUM, stop_pc); - } - - if (!disable_break ()) - { - warning ("shared library handler failed to disable breakpoint"); - } - - /* solib_add will call reinit_frame_cache. - But we are stopped in the startup code and we might not have symbols - for the startup code, so heuristic_proc_start could be called - and will put out an annoying warning. - Delaying the resetting of stop_soon_quietly until after symbol loading - suppresses the warning. */ - solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); - stop_soon_quietly = 0; -} - -/* - - LOCAL FUNCTION - - sharedlibrary_command -- handle command to explicitly add library - - SYNOPSIS - - static void sharedlibrary_command (char *args, int from_tty) - - DESCRIPTION - - */ - -static void -sharedlibrary_command (char *args, int from_tty) -{ - dont_repeat (); - solib_add (args, from_tty, (struct target_ops *) 0, 1); -} - -void -_initialize_solib (void) -{ - add_com ("sharedlibrary", class_files, sharedlibrary_command, - "Load shared object library symbols for files matching REGEXP."); - add_info ("sharedlibrary", info_sharedlibrary_command, - "Status of loaded shared object libraries."); - - add_show_from_set - (add_set_cmd ("auto-solib-add", class_support, var_boolean, - (char *) &auto_solib_add, - "Set autoloading of shared library symbols.\n\ -If \"on\", symbols from all shared object libraries will be loaded\n\ -automatically when the inferior begins execution, when the dynamic linker\n\ -informs gdb that a new library has been loaded, or when attaching to the\n\ -inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", - &setlist), - &showlist); -} - - -/* Register that we are able to handle irix5 core file formats. - This really is bfd_target_unknown_flavour */ - -static struct core_fns irix5_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_core_irix5 (void) -{ - add_core_fns (&irix5_core_fns); -} diff --git a/contrib/gdb/gdb/isi-xdep.c b/contrib/gdb/gdb/isi-xdep.c deleted file mode 100644 index 8773c83ea7a..00000000000 --- a/contrib/gdb/gdb/isi-xdep.c +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 1993 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include -int rloc[] = { - R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, FP, SP, PS, PC -}; diff --git a/contrib/gdb/gdb/jv-exp.tab.c b/contrib/gdb/gdb/jv-exp.tab.c deleted file mode 100644 index 39920caea20..00000000000 --- a/contrib/gdb/gdb/jv-exp.tab.c +++ /dev/null @@ -1,2351 +0,0 @@ - -/* A Bison parser, made from jv-exp.y - by GNU Bison version 1.25 - */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define INTEGER_LITERAL 258 -#define FLOATING_POINT_LITERAL 259 -#define IDENTIFIER 260 -#define STRING_LITERAL 261 -#define BOOLEAN_LITERAL 262 -#define TYPENAME 263 -#define NAME_OR_INT 264 -#define ERROR 265 -#define LONG 266 -#define SHORT 267 -#define BYTE 268 -#define INT 269 -#define CHAR 270 -#define BOOLEAN 271 -#define DOUBLE 272 -#define FLOAT 273 -#define VARIABLE 274 -#define ASSIGN_MODIFY 275 -#define THIS 276 -#define SUPER 277 -#define NEW 278 -#define OROR 279 -#define ANDAND 280 -#define EQUAL 281 -#define NOTEQUAL 282 -#define LEQ 283 -#define GEQ 284 -#define LSH 285 -#define RSH 286 -#define INCREMENT 287 -#define DECREMENT 288 - -#line 38 "jv-exp.y" - - -#include "defs.h" -#include "gdb_string.h" -#include -#include "expression.h" -#include "value.h" -#include "parser-defs.h" -#include "language.h" -#include "jv-lang.h" -#include "bfd.h" /* Required by objfiles.h. */ -#include "symfile.h" /* Required by objfiles.h. */ -#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ - -/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), - as well as gratuitiously global symbol names, so we can have multiple - yacc generated parsers in gdb. Note that these are only the variables - produced by yacc. If other parser generators (bison, byacc, etc) produce - additional global names that conflict at link time, then those parser - generators need to be fixed instead of adding those names to this list. */ - -#define yymaxdepth java_maxdepth -#define yyparse java_parse -#define yylex java_lex -#define yyerror java_error -#define yylval java_lval -#define yychar java_char -#define yydebug java_debug -#define yypact java_pact -#define yyr1 java_r1 -#define yyr2 java_r2 -#define yydef java_def -#define yychk java_chk -#define yypgo java_pgo -#define yyact java_act -#define yyexca java_exca -#define yyerrflag java_errflag -#define yynerrs java_nerrs -#define yyps java_ps -#define yypv java_pv -#define yys java_s -#define yy_yys java_yys -#define yystate java_state -#define yytmp java_tmp -#define yyv java_v -#define yy_yyv java_yyv -#define yyval java_val -#define yylloc java_lloc -#define yyreds java_reds /* With YYDEBUG defined */ -#define yytoks java_toks /* With YYDEBUG defined */ -#define yylhs java_yylhs -#define yylen java_yylen -#define yydefred java_yydefred -#define yydgoto java_yydgoto -#define yysindex java_yysindex -#define yyrindex java_yyrindex -#define yygindex java_yygindex -#define yytable java_yytable -#define yycheck java_yycheck - -#ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ -#endif - -int -yyparse PARAMS ((void)); - -static int -yylex PARAMS ((void)); - -void -yyerror PARAMS ((char *)); - -static struct type * java_type_from_name PARAMS ((struct stoken)); -static void push_expression_name PARAMS ((struct stoken)); -static void push_fieldnames PARAMS ((struct stoken)); - -static struct expression *copy_exp PARAMS ((struct expression *, int)); -static void insert_exp PARAMS ((int, struct expression *)); - - -#line 124 "jv-exp.y" -typedef union - { - LONGEST lval; - struct { - LONGEST val; - struct type *type; - } typed_val_int; - struct { - DOUBLEST dval; - struct type *type; - } typed_val_float; - struct symbol *sym; - struct type *tval; - struct stoken sval; - struct ttype tsym; - struct symtoken ssym; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - int *ivec; - } YYSTYPE; -#line 146 "jv-exp.y" - -/* YYSTYPE gets defined by %union */ -static int -parse_number PARAMS ((char *, int, int, YYSTYPE *)); -#include - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 208 -#define YYFLAG -32768 -#define YYNTBASE 57 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 288 ? yytranslate[x] : 112) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 55, 2, 2, 2, 44, 31, 2, 49, - 50, 42, 40, 24, 41, 47, 43, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 56, 2, 34, - 25, 35, 26, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 48, 2, 53, 30, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 51, 29, 52, 54, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 27, 28, - 32, 33, 36, 37, 38, 39, 45, 46 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, - 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, - 40, 42, 44, 46, 48, 51, 54, 56, 58, 60, - 62, 64, 66, 70, 72, 76, 78, 80, 82, 84, - 88, 90, 92, 94, 96, 100, 102, 104, 110, 112, - 116, 117, 119, 124, 129, 131, 134, 138, 141, 145, - 147, 148, 152, 156, 161, 168, 175, 180, 185, 190, - 192, 194, 196, 198, 200, 203, 206, 208, 210, 213, - 216, 219, 221, 224, 227, 229, 232, 235, 237, 243, - 248, 254, 256, 260, 264, 268, 270, 274, 278, 280, - 284, 288, 290, 294, 298, 302, 306, 308, 312, 316, - 318, 322, 324, 328, 330, 334, 336, 340, 342, 346, - 348, 354, 356, 358, 362, 366, 368, 370, 372, 374 -}; - -static const short yyrhs[] = { 73, - 0, 58, 0, 59, 0, 62, 0, 68, 0, 6, - 0, 3, 0, 9, 0, 4, 0, 7, 0, 60, - 0, 63, 0, 16, 0, 64, 0, 65, 0, 13, - 0, 12, 0, 14, 0, 11, 0, 15, 0, 18, - 0, 17, 0, 69, 0, 66, 0, 62, 84, 0, - 69, 84, 0, 5, 0, 72, 0, 71, 0, 72, - 0, 5, 0, 9, 0, 69, 47, 71, 0, 111, - 0, 73, 24, 111, 0, 75, 0, 81, 0, 61, - 0, 21, 0, 49, 111, 50, 0, 78, 0, 86, - 0, 87, 0, 88, 0, 76, 79, 77, 0, 51, - 0, 52, 0, 23, 67, 49, 80, 50, 0, 111, - 0, 79, 24, 111, 0, 0, 79, 0, 23, 62, - 82, 85, 0, 23, 66, 82, 85, 0, 83, 0, - 82, 83, 0, 48, 111, 53, 0, 48, 53, 0, - 84, 48, 53, 0, 84, 0, 0, 74, 47, 71, - 0, 19, 47, 71, 0, 69, 49, 80, 50, 0, - 74, 47, 71, 49, 80, 50, 0, 22, 47, 71, - 49, 80, 50, 0, 69, 48, 111, 53, 0, 19, - 48, 111, 53, 0, 75, 48, 111, 53, 0, 74, - 0, 69, 0, 19, 0, 90, 0, 91, 0, 89, - 45, 0, 89, 46, 0, 93, 0, 94, 0, 40, - 92, 0, 41, 92, 0, 42, 92, 0, 95, 0, - 45, 92, 0, 46, 92, 0, 89, 0, 54, 92, - 0, 55, 92, 0, 96, 0, 49, 62, 85, 50, - 92, 0, 49, 111, 50, 95, 0, 49, 69, 84, - 50, 95, 0, 92, 0, 97, 42, 92, 0, 97, - 43, 92, 0, 97, 44, 92, 0, 97, 0, 98, - 40, 97, 0, 98, 41, 97, 0, 98, 0, 99, - 38, 98, 0, 99, 39, 98, 0, 99, 0, 100, - 34, 99, 0, 100, 35, 99, 0, 100, 36, 99, - 0, 100, 37, 99, 0, 100, 0, 101, 32, 100, - 0, 101, 33, 100, 0, 101, 0, 102, 31, 101, - 0, 102, 0, 103, 30, 102, 0, 103, 0, 104, - 29, 103, 0, 104, 0, 105, 28, 104, 0, 105, - 0, 106, 27, 105, 0, 106, 0, 106, 26, 111, - 56, 107, 0, 107, 0, 109, 0, 110, 25, 107, - 0, 110, 20, 107, 0, 70, 0, 19, 0, 86, - 0, 88, 0, 108, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 203, 204, 207, 215, 217, 220, 229, 235, 243, 248, - 253, 263, 265, 269, 271, 274, 277, 279, 281, 283, - 287, 290, 301, 306, 310, 313, 317, 319, 322, 324, - 327, 329, 332, 356, 357, 361, 363, 366, 368, 371, - 372, 373, 374, 375, 376, 383, 388, 393, 398, 401, - 405, 408, 411, 414, 418, 420, 423, 427, 430, 434, - 436, 440, 443, 448, 451, 453, 457, 475, 477, 481, - 483, 485, 487, 488, 491, 496, 501, 503, 504, 505, - 507, 509, 512, 517, 522, 524, 526, 528, 531, 536, - 557, 564, 566, 568, 570, 574, 576, 578, 582, 584, - 586, 591, 593, 595, 597, 599, 604, 606, 608, 612, - 614, 618, 620, 623, 625, 629, 631, 635, 637, 641, - 643, 647, 649, 652, 655, 661, 664, 666, 667, 671 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","INTEGER_LITERAL", -"FLOATING_POINT_LITERAL","IDENTIFIER","STRING_LITERAL","BOOLEAN_LITERAL","TYPENAME", -"NAME_OR_INT","ERROR","LONG","SHORT","BYTE","INT","CHAR","BOOLEAN","DOUBLE", -"FLOAT","VARIABLE","ASSIGN_MODIFY","THIS","SUPER","NEW","','","'='","'?'","OROR", -"ANDAND","'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'","'>'","LEQ","GEQ","LSH", -"RSH","'+'","'-'","'*'","'/'","'%'","INCREMENT","DECREMENT","'.'","'['","'('", -"')'","'{'","'}'","']'","'~'","'!'","':'","start","type_exp","PrimitiveOrArrayType", -"StringLiteral","Literal","PrimitiveType","NumericType","IntegralType","FloatingPointType", -"ClassOrInterfaceType","ClassType","ArrayType","Name","ForcedName","SimpleName", -"QualifiedName","exp1","Primary","PrimaryNoNewArray","lcurly","rcurly","ClassInstanceCreationExpression", -"ArgumentList","ArgumentList_opt","ArrayCreationExpression","DimExprs","DimExpr", -"Dims","Dims_opt","FieldAccess","MethodInvocation","ArrayAccess","PostfixExpression", -"PostIncrementExpression","PostDecrementExpression","UnaryExpression","PreIncrementExpression", -"PreDecrementExpression","UnaryExpressionNotPlusMinus","CastExpression","MultiplicativeExpression", -"AdditiveExpression","ShiftExpression","RelationalExpression","EqualityExpression", -"AndExpression","ExclusiveOrExpression","InclusiveOrExpression","ConditionalAndExpression", -"ConditionalOrExpression","ConditionalExpression","AssignmentExpression","Assignment", -"LeftHandSide","Expression", NULL -}; -#endif - -static const short yyr1[] = { 0, - 57, 57, 58, 59, 59, 60, 61, 61, 61, 61, - 61, 62, 62, 63, 63, 64, 64, 64, 64, 64, - 65, 65, 66, 67, 68, 68, 69, 69, 70, 70, - 71, 71, 72, 73, 73, 74, 74, 75, 75, 75, - 75, 75, 75, 75, 75, 76, 77, 78, 79, 79, - 80, 80, 81, 81, 82, 82, 83, 84, 84, 85, - 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, - 89, 89, 89, 89, 90, 91, 92, 92, 92, 92, - 92, 92, 93, 94, 95, 95, 95, 95, 96, 96, - 96, 97, 97, 97, 97, 98, 98, 98, 99, 99, - 99, 100, 100, 100, 100, 100, 101, 101, 101, 102, - 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, - 107, 108, 108, 109, 109, 110, 110, 110, 110, 111 -}; - -static const short yyr2[] = { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, - 1, 1, 3, 1, 3, 1, 1, 1, 1, 3, - 1, 1, 1, 1, 3, 1, 1, 5, 1, 3, - 0, 1, 4, 4, 1, 2, 3, 2, 3, 1, - 0, 3, 3, 4, 6, 6, 4, 4, 4, 1, - 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, - 2, 1, 2, 2, 1, 2, 2, 1, 5, 4, - 5, 1, 3, 3, 3, 1, 3, 3, 1, 3, - 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 5, 1, 1, 3, 3, 1, 1, 1, 1, 1 -}; - -static const short yydefact[] = { 0, - 7, 9, 27, 6, 10, 8, 19, 17, 16, 18, - 20, 13, 22, 21, 72, 39, 0, 0, 0, 0, - 0, 0, 0, 0, 46, 0, 0, 2, 3, 11, - 38, 4, 12, 14, 15, 5, 71, 126, 29, 28, - 1, 70, 36, 0, 41, 37, 42, 43, 44, 85, - 73, 74, 92, 77, 78, 82, 88, 96, 99, 102, - 107, 110, 112, 114, 116, 118, 120, 122, 130, 123, - 0, 34, 0, 0, 0, 27, 0, 24, 0, 23, - 28, 8, 72, 71, 42, 44, 79, 80, 81, 83, - 84, 61, 71, 0, 86, 87, 0, 25, 0, 0, - 51, 26, 0, 0, 0, 0, 49, 75, 76, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 31, 32, 63, 0, 0, 0, 61, 55, 61, 51, - 0, 60, 0, 0, 40, 58, 0, 33, 0, 52, - 0, 35, 62, 0, 0, 47, 45, 93, 94, 95, - 97, 98, 100, 101, 103, 104, 105, 106, 108, 109, - 111, 113, 115, 117, 0, 119, 125, 124, 68, 51, - 0, 0, 56, 53, 54, 0, 0, 0, 90, 59, - 67, 64, 51, 69, 50, 0, 0, 57, 48, 89, - 91, 0, 121, 66, 65, 0, 0, 0 -}; - -static const short yydefgoto[] = { 206, - 28, 29, 30, 31, 32, 33, 34, 35, 78, 79, - 36, 84, 38, 39, 81, 41, 42, 43, 44, 157, - 45, 150, 151, 46, 137, 138, 142, 143, 85, 48, - 86, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 107 -}; - -static const short yypact[] = { 206, --32768,-32768, -5,-32768,-32768, -3,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768, 1,-32768, -34, 225, 312, 312, - 312, 312, 312, 206,-32768, 312, 312,-32768,-32768,-32768, --32768, -23,-32768,-32768,-32768,-32768, 34,-32768,-32768, 7, - 4, -28, -17, 365,-32768,-32768, 15,-32768, 21, 74, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 45, 44, 86, - 35, 96, 3, 23, 8, 51, 104,-32768,-32768,-32768, - 32,-32768, 46, 365, 46,-32768, 25, 25, 14, 55, --32768,-32768, 87, 47,-32768,-32768,-32768,-32768,-32768,-32768, --32768, -23, 34, 40,-32768,-32768, 57, 50, 46, 259, - 365, 50, 365, 46, 365, -13,-32768,-32768,-32768, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 365, 312, 312, 312, --32768,-32768,-32768, 61, 59, 365, 56,-32768, 56, 365, - 365, 50, 66, 43, 372,-32768, 69,-32768, 73, 108, - 106,-32768, 111, 109, 365,-32768,-32768,-32768,-32768,-32768, - 45, 45, 44, 44, 86, 86, 86, 86, 35, 35, - 96, 3, 23, 8, 107, 51,-32768,-32768,-32768, 365, - 112, 259,-32768,-32768,-32768, 114, 312, 372,-32768,-32768, --32768,-32768, 365,-32768,-32768, 312, 116,-32768,-32768,-32768, --32768, 118,-32768,-32768,-32768, 169, 170,-32768 -}; - -static const short yypgoto[] = {-32768, --32768,-32768,-32768,-32768, -8,-32768,-32768,-32768,-32768,-32768, --32768, 5,-32768, -66, 0,-32768,-32768,-32768,-32768,-32768, --32768, 127, -126,-32768, 94, -94, -29, -40, 6,-32768, - 12,-32768,-32768,-32768, 39,-32768,-32768, -141,-32768, 24, - 28, -42, 36, 52, 53, 49, 58, 48,-32768, -128, --32768,-32768,-32768, 18 -}; - - -#define YYLAST 427 - - -static const short yytable[] = { 40, - 177, 178, 98, 189, 37, 47, 133, 102, 135, 77, - 155, 49, 75, 186, -31, 92, -32, 72, 104, -31, - -127, -32, 80, 40, 97, -127, -30, 103, 93, 47, - 105, -30, 148, 123, -128, 49, 125, 153, 156, -128, - -129, 94, 183, 40, 183, -129, 201, 73, 74, 47, - 131, 129, 124, 197, 132, 49, 130, 87, 88, 89, - 90, 91, 140, 144, 95, 96, 202, 203, 117, 118, - 119, 120, 136, 40, 165, 166, 167, 168, 126, 47, - 99, 100, 101, 113, 114, 49, 110, 111, 112, 145, - 147, 134, 188, 99, 141, 101, 184, 147, 185, 40, - 40, 99, 40, 182, 40, 47, 47, 180, 47, 146, - 47, 49, 49, 179, 49, 187, 49, 149, 108, 109, - 152, 190, 154, 115, 116, 191, 40, 121, 122, 127, - 128, 155, 47, 73, 74, 40, 161, 162, 49, 40, - 40, 47, 163, 164, 175, 47, 47, 49, 158, 159, - 160, 49, 49, 181, 40, 192, 169, 170, 149, 193, - 47, 194, 196, 199, 198, 204, 49, 205, 207, 208, - 106, 139, 195, 173, 171, 176, 172, 0, 0, 40, - 0, 40, 0, 174, 0, 47, 0, 47, 0, 0, - 0, 49, 40, 49, 0, 0, 0, 0, 47, 181, - 0, 0, 0, 0, 49, 0, 0, 0, 1, 2, - 3, 4, 5, 0, 6, 0, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 200, 16, 17, 18, 76, - 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, - 12, 13, 14, 0, 0, 19, 20, 21, 0, 0, - 22, 23, 0, 0, 24, 0, 25, 0, 0, 26, - 27, 1, 2, 3, 4, 5, 0, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, - 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, - 21, 0, 0, 22, 23, 0, 0, 24, 0, 25, - 0, 146, 26, 27, 1, 2, 76, 4, 5, 0, - 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 0, 16, 17, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 19, 20, 21, 0, 0, 22, 23, 0, 0, - 24, 0, 25, 0, 0, 26, 27, 1, 2, 3, - 4, 5, 0, 6, 1, 2, 76, 4, 5, 0, - 82, 0, 0, 15, 0, 16, 17, 18, 0, 0, - 83, 0, 16, 17, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 20, 21, 0, 0, 22, - 23, 0, 0, 24, 0, 25, 0, 0, 26, 27, - 24, 0, 25, 0, 0, 26, 27 -}; - -static const short yycheck[] = { 0, - 129, 130, 32, 145, 0, 0, 73, 37, 75, 18, - 24, 0, 47, 140, 20, 24, 20, 0, 47, 25, - 20, 25, 18, 24, 48, 25, 20, 24, 24, 24, - 48, 25, 99, 31, 20, 24, 29, 104, 52, 25, - 20, 24, 137, 44, 139, 25, 188, 47, 48, 44, - 5, 20, 30, 180, 9, 44, 25, 19, 20, 21, - 22, 23, 49, 93, 26, 27, 193, 196, 34, 35, - 36, 37, 48, 74, 117, 118, 119, 120, 28, 74, - 47, 48, 49, 40, 41, 74, 42, 43, 44, 50, - 48, 74, 50, 47, 48, 49, 137, 48, 139, 100, - 101, 47, 103, 48, 105, 100, 101, 49, 103, 53, - 105, 100, 101, 53, 103, 50, 105, 100, 45, 46, - 103, 53, 105, 38, 39, 53, 127, 32, 33, 26, - 27, 24, 127, 47, 48, 136, 113, 114, 127, 140, - 141, 136, 115, 116, 127, 140, 141, 136, 110, 111, - 112, 140, 141, 136, 155, 50, 121, 122, 141, 49, - 155, 53, 56, 50, 53, 50, 155, 50, 0, 0, - 44, 78, 155, 125, 123, 128, 124, -1, -1, 180, - -1, 182, -1, 126, -1, 180, -1, 182, -1, -1, - -1, 180, 193, 182, -1, -1, -1, -1, 193, 182, - -1, -1, -1, -1, 193, -1, -1, -1, 3, 4, - 5, 6, 7, -1, 9, -1, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 187, 21, 22, 23, 5, - -1, -1, -1, -1, -1, 11, 12, 13, 14, 15, - 16, 17, 18, -1, -1, 40, 41, 42, -1, -1, - 45, 46, -1, -1, 49, -1, 51, -1, -1, 54, - 55, 3, 4, 5, 6, 7, -1, 9, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 19, -1, 21, - 22, 23, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, - 42, -1, -1, 45, 46, -1, -1, 49, -1, 51, - -1, 53, 54, 55, 3, 4, 5, 6, 7, -1, - 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 19, -1, 21, 22, 23, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 40, 41, 42, -1, -1, 45, 46, -1, -1, - 49, -1, 51, -1, -1, 54, 55, 3, 4, 5, - 6, 7, -1, 9, 3, 4, 5, 6, 7, -1, - 9, -1, -1, 19, -1, 21, 22, 23, -1, -1, - 19, -1, 21, 22, 23, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 40, 41, 42, -1, -1, 45, - 46, -1, -1, 49, -1, 51, -1, -1, 54, 55, - 49, -1, 51, -1, -1, 54, 55 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/stone/jimb/main-98r2/share/bison.simple" - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -#ifndef alloca -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) -#include -#else /* not sparc */ -#if defined (MSDOS) && !defined (__TURBOC__) -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) - #pragma alloca -#else /* not MSDOS, __TURBOC__, or _AIX */ -#ifdef __hpux -#ifdef __cplusplus -extern "C" { -void *alloca (unsigned int); -}; -#else /* not __cplusplus */ -void *alloca (); -#endif /* not __cplusplus */ -#endif /* __hpux */ -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc. */ -#endif /* not GNU C. */ -#endif /* alloca not defined. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -int yyparse (void); -#endif - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, int count) -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 196 "/stone/jimb/main-98r2/share/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to xreallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to xreallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp)); - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 3: -#line 208 "jv-exp.y" -{ - write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type(yyvsp[0].tval); - write_exp_elt_opcode(OP_TYPE); - ; - break;} -case 6: -#line 222 "jv-exp.y" -{ - write_exp_elt_opcode (OP_STRING); - write_exp_string (yyvsp[0].sval); - write_exp_elt_opcode (OP_STRING); - ; - break;} -case 7: -#line 231 "jv-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (yyvsp[0].typed_val_int.type); - write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val)); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 8: -#line 236 "jv-exp.y" -{ YYSTYPE val; - parse_number (yyvsp[0].sval.ptr, yyvsp[0].sval.length, 0, &val); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (val.typed_val_int.type); - write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); - write_exp_elt_opcode (OP_LONG); - ; - break;} -case 9: -#line 244 "jv-exp.y" -{ write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (yyvsp[0].typed_val_float.type); - write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval); - write_exp_elt_opcode (OP_DOUBLE); ; - break;} -case 10: -#line 249 "jv-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (java_boolean_type); - write_exp_elt_longcst ((LONGEST)yyvsp[0].lval); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 13: -#line 266 "jv-exp.y" -{ yyval.tval = java_boolean_type; ; - break;} -case 16: -#line 276 "jv-exp.y" -{ yyval.tval = java_byte_type; ; - break;} -case 17: -#line 278 "jv-exp.y" -{ yyval.tval = java_short_type; ; - break;} -case 18: -#line 280 "jv-exp.y" -{ yyval.tval = java_int_type; ; - break;} -case 19: -#line 282 "jv-exp.y" -{ yyval.tval = java_long_type; ; - break;} -case 20: -#line 284 "jv-exp.y" -{ yyval.tval = java_char_type; ; - break;} -case 21: -#line 289 "jv-exp.y" -{ yyval.tval = java_float_type; ; - break;} -case 22: -#line 291 "jv-exp.y" -{ yyval.tval = java_double_type; ; - break;} -case 23: -#line 303 "jv-exp.y" -{ yyval.tval = java_type_from_name (yyvsp[0].sval); ; - break;} -case 25: -#line 312 "jv-exp.y" -{ yyval.tval = java_array_type (yyvsp[-1].tval, yyvsp[0].lval); ; - break;} -case 26: -#line 314 "jv-exp.y" -{ yyval.tval = java_array_type (java_type_from_name (yyvsp[-1].sval), yyvsp[0].lval); ; - break;} -case 33: -#line 334 "jv-exp.y" -{ yyval.sval.length = yyvsp[-2].sval.length + yyvsp[0].sval.length + 1; - if (yyvsp[-2].sval.ptr + yyvsp[-2].sval.length + 1 == yyvsp[0].sval.ptr - && yyvsp[-2].sval.ptr[yyvsp[-2].sval.length] == '.') - yyval.sval.ptr = yyvsp[-2].sval.ptr; /* Optimization. */ - else - { - yyval.sval.ptr = (char *) xmalloc (yyval.sval.length + 1); - make_cleanup (free, yyval.sval.ptr); - sprintf (yyval.sval.ptr, "%.*s.%.*s", - yyvsp[-2].sval.length, yyvsp[-2].sval.ptr, yyvsp[0].sval.length, yyvsp[0].sval.ptr); - } ; - break;} -case 35: -#line 358 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_COMMA); ; - break;} -case 39: -#line 369 "jv-exp.y" -{ write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); ; - break;} -case 45: -#line 377 "jv-exp.y" -{ write_exp_elt_opcode (OP_ARRAY); - write_exp_elt_longcst ((LONGEST) 0); - write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); - write_exp_elt_opcode (OP_ARRAY); ; - break;} -case 46: -#line 385 "jv-exp.y" -{ start_arglist (); ; - break;} -case 47: -#line 390 "jv-exp.y" -{ yyval.lval = end_arglist () - 1; ; - break;} -case 48: -#line 395 "jv-exp.y" -{ error ("FIXME - ClassInstanceCreationExpression"); ; - break;} -case 49: -#line 400 "jv-exp.y" -{ arglist_len = 1; ; - break;} -case 50: -#line 402 "jv-exp.y" -{ arglist_len++; ; - break;} -case 51: -#line 407 "jv-exp.y" -{ arglist_len = 0; ; - break;} -case 53: -#line 413 "jv-exp.y" -{ error ("FIXME - ArrayCreatiionExpression"); ; - break;} -case 54: -#line 415 "jv-exp.y" -{ error ("FIXME - ArrayCreatiionExpression"); ; - break;} -case 58: -#line 429 "jv-exp.y" -{ yyval.lval = 1; ; - break;} -case 59: -#line 431 "jv-exp.y" -{ yyval.lval = yyvsp[-2].lval + 1; ; - break;} -case 61: -#line 437 "jv-exp.y" -{ yyval.lval = 0; ; - break;} -case 62: -#line 442 "jv-exp.y" -{ push_fieldnames (yyvsp[0].sval); ; - break;} -case 63: -#line 444 "jv-exp.y" -{ push_fieldnames (yyvsp[0].sval); ; - break;} -case 64: -#line 450 "jv-exp.y" -{ error ("method invocation not implemented"); ; - break;} -case 65: -#line 452 "jv-exp.y" -{ error ("method invocation not implemented"); ; - break;} -case 66: -#line 454 "jv-exp.y" -{ error ("method invocation not implemented"); ; - break;} -case 67: -#line 459 "jv-exp.y" -{ - /* Emit code for the Name now, then exchange it in the - expout array with the Expression's code. We could - introduce a OP_SWAP code or a reversed version of - BINOP_SUBSCRIPT, but that makes the rest of GDB pay - for our parsing kludges. */ - struct expression *name_expr; - - push_expression_name (yyvsp[-3].sval); - name_expr = copy_exp (expout, expout_ptr); - expout_ptr -= name_expr->nelts; - insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr), - name_expr); - free (name_expr); - write_exp_elt_opcode (BINOP_SUBSCRIPT); - ; - break;} -case 68: -#line 476 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_SUBSCRIPT); ; - break;} -case 69: -#line 478 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_SUBSCRIPT); ; - break;} -case 71: -#line 484 "jv-exp.y" -{ push_expression_name (yyvsp[0].sval); ; - break;} -case 75: -#line 493 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_POSTINCREMENT); ; - break;} -case 76: -#line 498 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_POSTDECREMENT); ; - break;} -case 80: -#line 506 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_NEG); ; - break;} -case 81: -#line 508 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_IND); ; - break;} -case 83: -#line 514 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_PREINCREMENT); ; - break;} -case 84: -#line 519 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_PREDECREMENT); ; - break;} -case 86: -#line 525 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_COMPLEMENT); ; - break;} -case 87: -#line 527 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ; - break;} -case 89: -#line 533 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type (java_array_type (yyvsp[-3].tval, yyvsp[-2].lval)); - write_exp_elt_opcode (UNOP_CAST); ; - break;} -case 90: -#line 537 "jv-exp.y" -{ - int exp_size = expout_ptr; - int last_exp_size = length_of_subexp(expout, expout_ptr); - struct type *type; - int i; - int base = expout_ptr - last_exp_size - 3; - if (base < 0 || expout->elts[base+2].opcode != OP_TYPE) - error ("invalid cast expression"); - type = expout->elts[base+1].type; - /* Remove the 'Expression' and slide the - UnaryExpressionNotPlusMinus down to replace it. */ - for (i = 0; i < last_exp_size; i++) - expout->elts[base + i] = expout->elts[base + i + 3]; - expout_ptr -= 3; - if (TYPE_CODE (type) == TYPE_CODE_STRUCT) - type = lookup_pointer_type (type); - write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type (type); - write_exp_elt_opcode (UNOP_CAST); - ; - break;} -case 91: -#line 558 "jv-exp.y" -{ write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type (java_array_type (java_type_from_name (yyvsp[-3].sval), yyvsp[-2].lval)); - write_exp_elt_opcode (UNOP_CAST); ; - break;} -case 93: -#line 567 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_MUL); ; - break;} -case 94: -#line 569 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_DIV); ; - break;} -case 95: -#line 571 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_REM); ; - break;} -case 97: -#line 577 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_ADD); ; - break;} -case 98: -#line 579 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_SUB); ; - break;} -case 100: -#line 585 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_LSH); ; - break;} -case 101: -#line 587 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_RSH); ; - break;} -case 103: -#line 594 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_LESS); ; - break;} -case 104: -#line 596 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_GTR); ; - break;} -case 105: -#line 598 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_LEQ); ; - break;} -case 106: -#line 600 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_GEQ); ; - break;} -case 108: -#line 607 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_EQUAL); ; - break;} -case 109: -#line 609 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_NOTEQUAL); ; - break;} -case 111: -#line 615 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_AND); ; - break;} -case 113: -#line 621 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_XOR); ; - break;} -case 115: -#line 626 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_BITWISE_IOR); ; - break;} -case 117: -#line 632 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ; - break;} -case 119: -#line 638 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ; - break;} -case 121: -#line 644 "jv-exp.y" -{ write_exp_elt_opcode (TERNOP_COND); ; - break;} -case 124: -#line 654 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_ASSIGN); ; - break;} -case 125: -#line 656 "jv-exp.y" -{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode (yyvsp[-1].opcode); - write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); ; - break;} -case 126: -#line 663 "jv-exp.y" -{ push_expression_name (yyvsp[0].sval); ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 498 "/stone/jimb/main-98r2/share/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) xmalloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; -} -#line 675 "jv-exp.y" - -/* Take care of parsing a number (anything that starts with a digit). - Set yylval and return the token type; update lexptr. - LEN is the number of characters in it. */ - -/*** Needs some error checking for the float case ***/ - -static int -parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; - int parsed_float; - YYSTYPE *putithere; -{ - register ULONGEST n = 0; - ULONGEST limit, limit_div_base; - - register int c; - register int base = input_radix; - - struct type *type; - - if (parsed_float) - { - /* It's a float since it contains a point or an exponent. */ - char c; - int num = 0; /* number of tokens scanned by scanf */ - char saved_char = p[len]; - - p[len] = 0; /* null-terminate the token */ - if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) - num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c); - else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) - num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c); - else - { -#ifdef SCANF_HAS_LONG_DOUBLE - num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c); -#else - /* Scan it into a double, then assign it to the long double. - This at least wins with values representable in the range - of doubles. */ - double temp; - num = sscanf (p, "%lg%c", &temp, &c); - putithere->typed_val_float.dval = temp; -#endif - } - p[len] = saved_char; /* restore the input stream */ - if (num != 1) /* check scanf found ONLY a float ... */ - return ERROR; - /* See if it has `f' or `d' suffix (float or double). */ - - c = tolower (p[len - 1]); - - if (c == 'f' || c == 'F') - putithere->typed_val_float.type = builtin_type_float; - else if (isdigit (c) || c == '.' || c == 'd' || c == 'D') - putithere->typed_val_float.type = builtin_type_double; - else - return ERROR; - - return FLOATING_POINT_LITERAL; - } - - /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ - if (p[0] == '0') - switch (p[1]) - { - case 'x': - case 'X': - if (len >= 3) - { - p += 2; - base = 16; - len -= 2; - } - break; - - case 't': - case 'T': - case 'd': - case 'D': - if (len >= 3) - { - p += 2; - base = 10; - len -= 2; - } - break; - - default: - base = 8; - break; - } - - c = p[len-1]; - limit = (ULONGEST)0xffffffff; - if (c == 'l' || c == 'L') - { - type = java_long_type; - len--; - /* A paranoid calculation of (1<<64)-1. */ - limit = ((limit << 16) << 16) | limit; - } - else - { - type = java_int_type; - } - limit_div_base = limit / (ULONGEST) base; - - while (--len >= 0) - { - c = *p++; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - return ERROR; /* Char not a digit */ - if (c >= base) - return ERROR; - if (n > limit_div_base - || (n *= base) > limit - c) - error ("Numeric constant too large."); - n += c; - } - - putithere->typed_val_int.val = n; - putithere->typed_val_int.type = type; - return INTEGER_LITERAL; -} - -struct token -{ - char *operator; - int token; - enum exp_opcode opcode; -}; - -static const struct token tokentab3[] = - { - {">>=", ASSIGN_MODIFY, BINOP_RSH}, - {"<<=", ASSIGN_MODIFY, BINOP_LSH} - }; - -static const struct token tokentab2[] = - { - {"+=", ASSIGN_MODIFY, BINOP_ADD}, - {"-=", ASSIGN_MODIFY, BINOP_SUB}, - {"*=", ASSIGN_MODIFY, BINOP_MUL}, - {"/=", ASSIGN_MODIFY, BINOP_DIV}, - {"%=", ASSIGN_MODIFY, BINOP_REM}, - {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR}, - {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND}, - {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR}, - {"++", INCREMENT, BINOP_END}, - {"--", DECREMENT, BINOP_END}, - {"&&", ANDAND, BINOP_END}, - {"||", OROR, BINOP_END}, - {"<<", LSH, BINOP_END}, - {">>", RSH, BINOP_END}, - {"==", EQUAL, BINOP_END}, - {"!=", NOTEQUAL, BINOP_END}, - {"<=", LEQ, BINOP_END}, - {">=", GEQ, BINOP_END} - }; - -/* Read one token, getting characters through lexptr. */ - -static int -yylex () -{ - int c; - int namelen; - unsigned int i; - char *tokstart; - char *tokptr; - int tempbufindex; - static char *tempbuf; - static int tempbufsize; - - retry: - - tokstart = lexptr; - /* See if it is a special token of length 3. */ - for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) - if (STREQN (tokstart, tokentab3[i].operator, 3)) - { - lexptr += 3; - yylval.opcode = tokentab3[i].opcode; - return tokentab3[i].token; - } - - /* See if it is a special token of length 2. */ - for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) - if (STREQN (tokstart, tokentab2[i].operator, 2)) - { - lexptr += 2; - yylval.opcode = tokentab2[i].opcode; - return tokentab2[i].token; - } - - switch (c = *tokstart) - { - case 0: - return 0; - - case ' ': - case '\t': - case '\n': - lexptr++; - goto retry; - - case '\'': - /* We either have a character constant ('0' or '\177' for example) - or we have a quoted symbol reference ('foo(int,int)' in C++ - for example). */ - lexptr++; - c = *lexptr++; - if (c == '\\') - c = parse_escape (&lexptr); - else if (c == '\'') - error ("Empty character constant."); - - yylval.typed_val_int.val = c; - yylval.typed_val_int.type = builtin_type_char; - - c = *lexptr++; - if (c != '\'') - { - namelen = skip_quoted (tokstart) - tokstart; - if (namelen > 2) - { - lexptr = tokstart + namelen; - if (lexptr[-1] != '\'') - error ("Unmatched single quote."); - namelen -= 2; - tokstart++; - goto tryname; - } - error ("Invalid character constant."); - } - return INTEGER_LITERAL; - - case '(': - paren_depth++; - lexptr++; - return c; - - case ')': - if (paren_depth == 0) - return 0; - paren_depth--; - lexptr++; - return c; - - case ',': - if (comma_terminates && paren_depth == 0) - return 0; - lexptr++; - return c; - - case '.': - /* Might be a floating point number. */ - if (lexptr[1] < '0' || lexptr[1] > '9') - goto symbol; /* Nope, must be a symbol. */ - /* FALL THRU into number case. */ - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - /* It's a number. */ - int got_dot = 0, got_e = 0, toktype; - register char *p = tokstart; - int hex = input_radix > 10; - - if (c == '0' && (p[1] == 'x' || p[1] == 'X')) - { - p += 2; - hex = 1; - } - else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) - { - p += 2; - hex = 0; - } - - for (;; ++p) - { - /* This test includes !hex because 'e' is a valid hex digit - and thus does not indicate a floating point number when - the radix is hex. */ - if (!hex && !got_e && (*p == 'e' || *p == 'E')) - got_dot = got_e = 1; - /* This test does not include !hex, because a '.' always indicates - a decimal floating point number regardless of the radix. */ - else if (!got_dot && *p == '.') - got_dot = 1; - else if (got_e && (p[-1] == 'e' || p[-1] == 'E') - && (*p == '-' || *p == '+')) - /* This is the sign of the exponent, not the end of the - number. */ - continue; - /* We will take any letters or digits. parse_number will - complain if past the radix, or if L or U are not final. */ - else if ((*p < '0' || *p > '9') - && ((*p < 'a' || *p > 'z') - && (*p < 'A' || *p > 'Z'))) - break; - } - toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval); - if (toktype == ERROR) - { - char *err_copy = (char *) alloca (p - tokstart + 1); - - memcpy (err_copy, tokstart, p - tokstart); - err_copy[p - tokstart] = 0; - error ("Invalid number \"%s\".", err_copy); - } - lexptr = p; - return toktype; - } - - case '+': - case '-': - case '*': - case '/': - case '%': - case '|': - case '&': - case '^': - case '~': - case '!': - case '<': - case '>': - case '[': - case ']': - case '?': - case ':': - case '=': - case '{': - case '}': - symbol: - lexptr++; - return c; - - case '"': - - /* Build the gdb internal form of the input string in tempbuf, - translating any standard C escape forms seen. Note that the - buffer is null byte terminated *only* for the convenience of - debugging gdb itself and printing the buffer contents when - the buffer contains no embedded nulls. Gdb does not depend - upon the buffer being null byte terminated, it uses the length - string instead. This allows gdb to handle C strings (as well - as strings in other languages) with embedded null bytes */ - - tokptr = ++tokstart; - tempbufindex = 0; - - do { - /* Grow the static temp buffer if necessary, including allocating - the first one on demand. */ - if (tempbufindex + 1 >= tempbufsize) - { - tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64); - } - switch (*tokptr) - { - case '\0': - case '"': - /* Do nothing, loop will terminate. */ - break; - case '\\': - tokptr++; - c = parse_escape (&tokptr); - if (c == -1) - { - continue; - } - tempbuf[tempbufindex++] = c; - break; - default: - tempbuf[tempbufindex++] = *tokptr++; - break; - } - } while ((*tokptr != '"') && (*tokptr != '\0')); - if (*tokptr++ != '"') - { - error ("Unterminated string in expression."); - } - tempbuf[tempbufindex] = '\0'; /* See note above */ - yylval.sval.ptr = tempbuf; - yylval.sval.length = tempbufindex; - lexptr = tokptr; - return (STRING_LITERAL); - } - - if (!(c == '_' || c == '$' - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) - /* We must have come across a bad character (e.g. ';'). */ - error ("Invalid character '%c' in expression.", c); - - /* It's a name. See how long it is. */ - namelen = 0; - for (c = tokstart[namelen]; - (c == '_' - || c == '$' - || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || c == '<'); - ) - { - if (c == '<') - { - int i = namelen; - while (tokstart[++i] && tokstart[i] != '>'); - if (tokstart[i] == '>') - namelen = i; - } - c = tokstart[++namelen]; - } - - /* The token "if" terminates the expression and is NOT - removed from the input stream. */ - if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') - { - return 0; - } - - lexptr += namelen; - - tryname: - - /* Catch specific keywords. Should be done with a data structure. */ - switch (namelen) - { - case 7: - if (STREQN (tokstart, "boolean", 7)) - return BOOLEAN; - break; - case 6: - if (STREQN (tokstart, "double", 6)) - return DOUBLE; - break; - case 5: - if (STREQN (tokstart, "short", 5)) - return SHORT; - if (STREQN (tokstart, "false", 5)) - { - yylval.lval = 0; - return BOOLEAN_LITERAL; - } - if (STREQN (tokstart, "super", 5)) - return SUPER; - if (STREQN (tokstart, "float", 5)) - return FLOAT; - break; - case 4: - if (STREQN (tokstart, "long", 4)) - return LONG; - if (STREQN (tokstart, "byte", 4)) - return BYTE; - if (STREQN (tokstart, "char", 4)) - return CHAR; - if (STREQN (tokstart, "true", 4)) - { - yylval.lval = 1; - return BOOLEAN_LITERAL; - } - if (current_language->la_language == language_cplus - && STREQN (tokstart, "this", 4)) - { - static const char this_name[] = - { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' }; - - if (lookup_symbol (this_name, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL)) - return THIS; - } - break; - case 3: - if (STREQN (tokstart, "int", 3)) - return INT; - if (STREQN (tokstart, "new", 3)) - return NEW; - break; - default: - break; - } - - yylval.sval.ptr = tokstart; - yylval.sval.length = namelen; - - if (*tokstart == '$') - { - write_dollar_variable (yylval.sval); - return VARIABLE; - } - - /* Input names that aren't symbols but ARE valid hex numbers, - when the input radix permits them, can be names or numbers - depending on the parse. Note we support radixes > 16 here. */ - if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || - (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) - { - YYSTYPE newlval; /* Its value is ignored. */ - int hextype = parse_number (tokstart, namelen, 0, &newlval); - if (hextype == INTEGER_LITERAL) - return NAME_OR_INT; - } - return IDENTIFIER; -} - -void -yyerror (msg) - char *msg; -{ - error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); -} - -static struct type * -java_type_from_name (name) - struct stoken name; - -{ - char *tmp = copy_name (name); - struct type *typ = java_lookup_class (tmp); - if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT) - error ("No class named %s.", tmp); - return typ; -} - -/* If NAME is a valid variable name in this scope, push it and return 1. - Otherwise, return 0. */ - -static int -push_variable (name) - struct stoken name; - -{ - char *tmp = copy_name (name); - int is_a_field_of_this = 0; - struct symbol *sym; - sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE, - &is_a_field_of_this, (struct symtab **) NULL); - if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF) - { - if (symbol_read_needs_frame (sym)) - { - if (innermost_block == 0 || - contained_in (block_found, innermost_block)) - innermost_block = block_found; - } - - write_exp_elt_opcode (OP_VAR_VALUE); - /* We want to use the selected frame, not another more inner frame - which happens to be in the same block. */ - write_exp_elt_block (NULL); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); - return 1; - } - if (is_a_field_of_this) - { - /* it hangs off of `this'. Must not inadvertently convert from a - method call to data ref. */ - if (innermost_block == 0 || - contained_in (block_found, innermost_block)) - innermost_block = block_found; - write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (STRUCTOP_PTR); - write_exp_string (name); - write_exp_elt_opcode (STRUCTOP_PTR); - return 1; - } - return 0; -} - -/* Assuming a reference expression has been pushed, emit the - STRUCTOP_STRUCT ops to access the field named NAME. If NAME is a - qualified name (has '.'), generate a field access for each part. */ - -static void -push_fieldnames (name) - struct stoken name; -{ - int i; - struct stoken token; - token.ptr = name.ptr; - for (i = 0; ; i++) - { - if (i == name.length || name.ptr[i] == '.') - { - /* token.ptr is start of current field name. */ - token.length = &name.ptr[i] - token.ptr; - write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string (token); - write_exp_elt_opcode (STRUCTOP_STRUCT); - token.ptr += token.length + 1; - } - if (i >= name.length) - break; - } -} - -/* Helper routine for push_expression_name. - Handle a qualified name, where DOT_INDEX is the index of the first '.' */ - -static void -push_qualified_expression_name (name, dot_index) - struct stoken name; - int dot_index; -{ - struct stoken token; - char *tmp; - struct type *typ; - - token.ptr = name.ptr; - token.length = dot_index; - - if (push_variable (token)) - { - token.ptr = name.ptr + dot_index + 1; - token.length = name.length - dot_index - 1; - push_fieldnames (token); - return; - } - - token.ptr = name.ptr; - for (;;) - { - token.length = dot_index; - tmp = copy_name (token); - typ = java_lookup_class (tmp); - if (typ != NULL) - { - if (dot_index == name.length) - { - write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type(typ); - write_exp_elt_opcode(OP_TYPE); - return; - } - dot_index++; /* Skip '.' */ - name.ptr += dot_index; - name.length -= dot_index; - dot_index = 0; - while (dot_index < name.length && name.ptr[dot_index] != '.') - dot_index++; - token.ptr = name.ptr; - token.length = dot_index; - write_exp_elt_opcode (OP_SCOPE); - write_exp_elt_type (typ); - write_exp_string (token); - write_exp_elt_opcode (OP_SCOPE); - if (dot_index < name.length) - { - dot_index++; - name.ptr += dot_index; - name.length -= dot_index; - push_fieldnames (name); - } - return; - } - else if (dot_index >= name.length) - break; - dot_index++; /* Skip '.' */ - while (dot_index < name.length && name.ptr[dot_index] != '.') - dot_index++; - } - error ("unknown type `%.*s'", name.length, name.ptr); -} - -/* Handle Name in an expression (or LHS). - Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */ - -static void -push_expression_name (name) - struct stoken name; -{ - char *tmp; - struct type *typ; - char *ptr; - int i; - - for (i = 0; i < name.length; i++) - { - if (name.ptr[i] == '.') - { - /* It's a Qualified Expression Name. */ - push_qualified_expression_name (name, i); - return; - } - } - - /* It's a Simple Expression Name. */ - - if (push_variable (name)) - return; - tmp = copy_name (name); - typ = java_lookup_class (tmp); - if (typ != NULL) - { - write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type(typ); - write_exp_elt_opcode(OP_TYPE); - } - else - { - struct minimal_symbol *msymbol; - - msymbol = lookup_minimal_symbol (tmp, NULL, NULL); - if (msymbol != NULL) - { - write_exp_msymbol (msymbol, - lookup_function_type (builtin_type_int), - builtin_type_int); - } - else if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); - else - error ("No symbol \"%s\" in current context.", tmp); - } - -} - - -/* The following two routines, copy_exp and insert_exp, aren't specific to - Java, so they could go in parse.c, but their only purpose is to support - the parsing kludges we use in this file, so maybe it's best to isolate - them here. */ - -/* Copy the expression whose last element is at index ENDPOS - 1 in EXPR - into a freshly xmalloc'ed struct expression. Its language_defn is set - to null. */ -static struct expression * -copy_exp (expr, endpos) - struct expression *expr; - int endpos; -{ - int len = length_of_subexp (expr, endpos); - struct expression *new - = (struct expression *) xmalloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len)); - new->nelts = len; - memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len)); - new->language_defn = 0; - - return new; -} - -/* Insert the expression NEW into the current expression (expout) at POS. */ -static void -insert_exp (pos, new) - int pos; - struct expression *new; -{ - int newlen = new->nelts; - - /* Grow expout if necessary. In this function's only use at present, - this should never be necessary. */ - if (expout_ptr + newlen > expout_size) - { - expout_size = max (expout_size * 2, expout_ptr + newlen + 10); - expout = (struct expression *) - xrealloc ((char *) expout, (sizeof (struct expression) - + EXP_ELEM_TO_BYTES (expout_size))); - } - - { - int i; - - for (i = expout_ptr - 1; i >= pos; i--) - expout->elts[i + newlen] = expout->elts[i]; - } - - memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen)); - expout_ptr += newlen; -} diff --git a/contrib/gdb/gdb/kdb-start.c b/contrib/gdb/gdb/kdb-start.c deleted file mode 100644 index 7a4acb71208..00000000000 --- a/contrib/gdb/gdb/kdb-start.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Main loop for the standalone kernel debugger, for GDB, the GNU Debugger. - Copyright 1989, 1991, 1992 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" - -static char *args[] = -{"kdb", "kdb-symbols", 0}; - -static char *environment[] = -{0}; - -char **environ; - -start () -{ - INIT_STACK (kdb_stack_beg, kdb_stack_end); - - environ = environment; - - main (2, args, environment); -} diff --git a/contrib/gdb/gdb/lynx-nat.c b/contrib/gdb/gdb/lynx-nat.c deleted file mode 100644 index 9cd1672d336..00000000000 --- a/contrib/gdb/gdb/lynx-nat.c +++ /dev/null @@ -1,829 +0,0 @@ -/* Native-dependent code for LynxOS. - Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "regcache.h" - -#include -#include -#include - -static unsigned long registers_addr (int pid); -static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); - -#define X(ENTRY)(offsetof(struct econtext, ENTRY)) - -#ifdef I386 -/* Mappings from tm-i386v.h */ - -static int regmap[] = -{ - X (eax), - X (ecx), - X (edx), - X (ebx), - X (esp), /* sp */ - X (ebp), /* fp */ - X (esi), - X (edi), - X (eip), /* pc */ - X (flags), /* ps */ - X (cs), - X (ss), - X (ds), - X (es), - X (ecode), /* Lynx doesn't give us either fs or gs, so */ - X (fault), /* we just substitute these two in the hopes - that they are useful. */ -}; -#endif /* I386 */ - -#ifdef M68K -/* Mappings from tm-m68k.h */ - -static int regmap[] = -{ - X (regs[0]), /* d0 */ - X (regs[1]), /* d1 */ - X (regs[2]), /* d2 */ - X (regs[3]), /* d3 */ - X (regs[4]), /* d4 */ - X (regs[5]), /* d5 */ - X (regs[6]), /* d6 */ - X (regs[7]), /* d7 */ - X (regs[8]), /* a0 */ - X (regs[9]), /* a1 */ - X (regs[10]), /* a2 */ - X (regs[11]), /* a3 */ - X (regs[12]), /* a4 */ - X (regs[13]), /* a5 */ - X (regs[14]), /* fp */ - offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */ - X (status), /* ps */ - X (pc), - - X (fregs[0 * 3]), /* fp0 */ - X (fregs[1 * 3]), /* fp1 */ - X (fregs[2 * 3]), /* fp2 */ - X (fregs[3 * 3]), /* fp3 */ - X (fregs[4 * 3]), /* fp4 */ - X (fregs[5 * 3]), /* fp5 */ - X (fregs[6 * 3]), /* fp6 */ - X (fregs[7 * 3]), /* fp7 */ - - X (fcregs[0]), /* fpcontrol */ - X (fcregs[1]), /* fpstatus */ - X (fcregs[2]), /* fpiaddr */ - X (ssw), /* fpcode */ - X (fault), /* fpflags */ -}; -#endif /* M68K */ - -#ifdef SPARC -/* Mappings from tm-sparc.h */ - -#define FX(ENTRY)(offsetof(struct fcontext, ENTRY)) - -static int regmap[] = -{ - -1, /* g0 */ - X (g1), - X (g2), - X (g3), - X (g4), - -1, /* g5->g7 aren't saved by Lynx */ - -1, - -1, - - X (o[0]), - X (o[1]), - X (o[2]), - X (o[3]), - X (o[4]), - X (o[5]), - X (o[6]), /* sp */ - X (o[7]), /* ra */ - - -1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */ - - -1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */ - - FX (f.fregs[0]), /* f0 */ - FX (f.fregs[1]), - FX (f.fregs[2]), - FX (f.fregs[3]), - FX (f.fregs[4]), - FX (f.fregs[5]), - FX (f.fregs[6]), - FX (f.fregs[7]), - FX (f.fregs[8]), - FX (f.fregs[9]), - FX (f.fregs[10]), - FX (f.fregs[11]), - FX (f.fregs[12]), - FX (f.fregs[13]), - FX (f.fregs[14]), - FX (f.fregs[15]), - FX (f.fregs[16]), - FX (f.fregs[17]), - FX (f.fregs[18]), - FX (f.fregs[19]), - FX (f.fregs[20]), - FX (f.fregs[21]), - FX (f.fregs[22]), - FX (f.fregs[23]), - FX (f.fregs[24]), - FX (f.fregs[25]), - FX (f.fregs[26]), - FX (f.fregs[27]), - FX (f.fregs[28]), - FX (f.fregs[29]), - FX (f.fregs[30]), - FX (f.fregs[31]), - - X (y), - X (psr), - X (wim), - X (tbr), - X (pc), - X (npc), - FX (fsr), /* fpsr */ - -1, /* cpsr */ -}; -#endif /* SPARC */ - -#ifdef rs6000 - -static int regmap[] = -{ - X (iregs[0]), /* r0 */ - X (iregs[1]), - X (iregs[2]), - X (iregs[3]), - X (iregs[4]), - X (iregs[5]), - X (iregs[6]), - X (iregs[7]), - X (iregs[8]), - X (iregs[9]), - X (iregs[10]), - X (iregs[11]), - X (iregs[12]), - X (iregs[13]), - X (iregs[14]), - X (iregs[15]), - X (iregs[16]), - X (iregs[17]), - X (iregs[18]), - X (iregs[19]), - X (iregs[20]), - X (iregs[21]), - X (iregs[22]), - X (iregs[23]), - X (iregs[24]), - X (iregs[25]), - X (iregs[26]), - X (iregs[27]), - X (iregs[28]), - X (iregs[29]), - X (iregs[30]), - X (iregs[31]), - - X (fregs[0]), /* f0 */ - X (fregs[1]), - X (fregs[2]), - X (fregs[3]), - X (fregs[4]), - X (fregs[5]), - X (fregs[6]), - X (fregs[7]), - X (fregs[8]), - X (fregs[9]), - X (fregs[10]), - X (fregs[11]), - X (fregs[12]), - X (fregs[13]), - X (fregs[14]), - X (fregs[15]), - X (fregs[16]), - X (fregs[17]), - X (fregs[18]), - X (fregs[19]), - X (fregs[20]), - X (fregs[21]), - X (fregs[22]), - X (fregs[23]), - X (fregs[24]), - X (fregs[25]), - X (fregs[26]), - X (fregs[27]), - X (fregs[28]), - X (fregs[29]), - X (fregs[30]), - X (fregs[31]), - - X (srr0), /* IAR (PC) */ - X (srr1), /* MSR (PS) */ - X (cr), /* CR */ - X (lr), /* LR */ - X (ctr), /* CTR */ - X (xer), /* XER */ - X (mq) /* MQ */ -}; - -#endif /* rs6000 */ - -#ifdef SPARC - -/* This routine handles some oddball cases for Sparc registers and LynxOS. - In partucular, it causes refs to G0, g5->7, and all fp regs to return zero. - It also handles knows where to find the I & L regs on the stack. */ - -void -fetch_inferior_registers (int regno) -{ - int whatregs = 0; - -#define WHATREGS_FLOAT 1 -#define WHATREGS_GEN 2 -#define WHATREGS_STACK 4 - - if (regno == -1) - whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK; - else if (regno >= L0_REGNUM && regno <= I7_REGNUM) - whatregs = WHATREGS_STACK; - else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) - whatregs = WHATREGS_FLOAT; - else - whatregs = WHATREGS_GEN; - - if (whatregs & WHATREGS_GEN) - { - struct econtext ec; /* general regs */ - char buf[MAX_REGISTER_RAW_SIZE]; - int retval; - int i; - - errno = 0; - retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & ec, 0); - if (errno) - perror_with_name ("ptrace(PTRACE_GETREGS)"); - - memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM)); - supply_register (G0_REGNUM, buf); - supply_register (TBR_REGNUM, (char *) &ec.tbr); - - memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &ec.g1, - 4 * REGISTER_RAW_SIZE (G1_REGNUM)); - for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++) - register_valid[i] = 1; - - supply_register (PS_REGNUM, (char *) &ec.psr); - supply_register (Y_REGNUM, (char *) &ec.y); - supply_register (PC_REGNUM, (char *) &ec.pc); - supply_register (NPC_REGNUM, (char *) &ec.npc); - supply_register (WIM_REGNUM, (char *) &ec.wim); - - memcpy (®isters[REGISTER_BYTE (O0_REGNUM)], ec.o, - 8 * REGISTER_RAW_SIZE (O0_REGNUM)); - for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++) - register_valid[i] = 1; - } - - if (whatregs & WHATREGS_STACK) - { - CORE_ADDR sp; - int i; - - sp = read_register (SP_REGNUM); - - target_read_memory (sp + FRAME_SAVED_I0, - ®isters[REGISTER_BYTE (I0_REGNUM)], - 8 * REGISTER_RAW_SIZE (I0_REGNUM)); - for (i = I0_REGNUM; i <= I7_REGNUM; i++) - register_valid[i] = 1; - - target_read_memory (sp + FRAME_SAVED_L0, - ®isters[REGISTER_BYTE (L0_REGNUM)], - 8 * REGISTER_RAW_SIZE (L0_REGNUM)); - for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++) - register_valid[i] = 1; - } - - if (whatregs & WHATREGS_FLOAT) - { - struct fcontext fc; /* fp regs */ - int retval; - int i; - - errno = 0; - retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & fc, 0); - if (errno) - perror_with_name ("ptrace(PTRACE_GETFPREGS)"); - - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs, - 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); - for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) - register_valid[i] = 1; - - supply_register (FPS_REGNUM, (char *) &fc.fsr); - } -} - -/* This routine handles storing of the I & L regs for the Sparc. The trick - here is that they actually live on the stack. The really tricky part is - that when changing the stack pointer, the I & L regs must be written to - where the new SP points, otherwise the regs will be incorrect when the - process is started up again. We assume that the I & L regs are valid at - this point. */ - -void -store_inferior_registers (int regno) -{ - int whatregs = 0; - - if (regno == -1) - whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK; - else if (regno >= L0_REGNUM && regno <= I7_REGNUM) - whatregs = WHATREGS_STACK; - else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) - whatregs = WHATREGS_FLOAT; - else if (regno == SP_REGNUM) - whatregs = WHATREGS_STACK | WHATREGS_GEN; - else - whatregs = WHATREGS_GEN; - - if (whatregs & WHATREGS_GEN) - { - struct econtext ec; /* general regs */ - int retval; - - ec.tbr = read_register (TBR_REGNUM); - memcpy (&ec.g1, ®isters[REGISTER_BYTE (G1_REGNUM)], - 4 * REGISTER_RAW_SIZE (G1_REGNUM)); - - ec.psr = read_register (PS_REGNUM); - ec.y = read_register (Y_REGNUM); - ec.pc = read_register (PC_REGNUM); - ec.npc = read_register (NPC_REGNUM); - ec.wim = read_register (WIM_REGNUM); - - memcpy (ec.o, ®isters[REGISTER_BYTE (O0_REGNUM)], - 8 * REGISTER_RAW_SIZE (O0_REGNUM)); - - errno = 0; - retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & ec, 0); - if (errno) - perror_with_name ("ptrace(PTRACE_SETREGS)"); - } - - if (whatregs & WHATREGS_STACK) - { - int regoffset; - CORE_ADDR sp; - - sp = read_register (SP_REGNUM); - - if (regno == -1 || regno == SP_REGNUM) - { - if (!register_valid[L0_REGNUM + 5]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - target_write_memory (sp + FRAME_SAVED_I0, - ®isters[REGISTER_BYTE (I0_REGNUM)], - 8 * REGISTER_RAW_SIZE (I0_REGNUM)); - - target_write_memory (sp + FRAME_SAVED_L0, - ®isters[REGISTER_BYTE (L0_REGNUM)], - 8 * REGISTER_RAW_SIZE (L0_REGNUM)); - } - else if (regno >= L0_REGNUM && regno <= I7_REGNUM) - { - if (!register_valid[regno]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7) - regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM) - + FRAME_SAVED_L0; - else - regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM) - + FRAME_SAVED_I0; - target_write_memory (sp + regoffset, - ®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno)); - } - } - - if (whatregs & WHATREGS_FLOAT) - { - struct fcontext fc; /* fp regs */ - int retval; - -/* We read fcontext first so that we can get good values for fq_t... */ - errno = 0; - retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & fc, 0); - if (errno) - perror_with_name ("ptrace(PTRACE_GETFPREGS)"); - - memcpy (fc.f.fregs, ®isters[REGISTER_BYTE (FP0_REGNUM)], - 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); - - fc.fsr = read_register (FPS_REGNUM); - - errno = 0; - retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & fc, 0); - if (errno) - perror_with_name ("ptrace(PTRACE_SETFPREGS)"); - } -} -#endif /* SPARC */ - -#if defined (I386) || defined (M68K) || defined (rs6000) - -/* Return the offset relative to the start of the per-thread data to the - saved context block. */ - -static unsigned long -registers_addr (int pid) -{ - CORE_ADDR stblock; - int ecpoff = offsetof (st_t, ecp); - CORE_ADDR ecp; - - errno = 0; - stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, - 0); - if (errno) - perror_with_name ("ptrace(PTRACE_THREADUSER)"); - - ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff, - 0); - if (errno) - perror_with_name ("ptrace(PTRACE_PEEKTHREAD)"); - - return ecp - stblock; -} - -/* Fetch one or more registers from the inferior. REGNO == -1 to get - them all. We actually fetch more than requested, when convenient, - marking them as valid so we won't fetch them again. */ - -void -fetch_inferior_registers (int regno) -{ - int reglo, reghi; - int i; - unsigned long ecp; - - if (regno == -1) - { - reglo = 0; - reghi = NUM_REGS - 1; - } - else - reglo = reghi = regno; - - ecp = registers_addr (PIDGET (inferior_ptid)); - - for (regno = reglo; regno <= reghi; regno++) - { - char buf[MAX_REGISTER_RAW_SIZE]; - int ptrace_fun = PTRACE_PEEKTHREAD; - -#ifdef M68K - ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD; -#endif - - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - unsigned int reg; - - errno = 0; - reg = ptrace (ptrace_fun, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0); - if (errno) - perror_with_name ("ptrace(PTRACE_PEEKUSP)"); - - *(int *) &buf[i] = reg; - } - supply_register (regno, buf); - } -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (int regno) -{ - int reglo, reghi; - int i; - unsigned long ecp; - - if (regno == -1) - { - reglo = 0; - reghi = NUM_REGS - 1; - } - else - reglo = reghi = regno; - - ecp = registers_addr (PIDGET (inferior_ptid)); - - for (regno = reglo; regno <= reghi; regno++) - { - int ptrace_fun = PTRACE_POKEUSER; - - if (CANNOT_STORE_REGISTER (regno)) - continue; - -#ifdef M68K - ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER; -#endif - - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - unsigned int reg; - - reg = *(unsigned int *) ®isters[REGISTER_BYTE (regno) + i]; - - errno = 0; - ptrace (ptrace_fun, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg); - if (errno) - perror_with_name ("ptrace(PTRACE_POKEUSP)"); - } - } -} -#endif /* defined (I386) || defined (M68K) || defined (rs6000) */ - -/* Wait for child to do something. Return pid of child, or -1 in case - of error; store status through argument pointer OURSTATUS. */ - -ptid_t -child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) -{ - int save_errno; - int thread; - union wait status; - int pid; - - while (1) - { - int sig; - - set_sigint_trap (); /* Causes SIGINT to be passed on to the - attached process. */ - pid = wait (&status); - - save_errno = errno; - - clear_sigint_trap (); - - if (pid == -1) - { - if (save_errno == EINTR) - continue; - fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n", - safe_strerror (save_errno)); - /* Claim it exited with unknown signal. */ - ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; - return -1; - } - - if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */ - continue; - - thread = status.w_tid; /* Get thread id from status */ - - /* Initial thread value can only be acquired via wait, so we have to - resort to this hack. */ - - if (TIDGET (inferior_ptid) == 0 && thread != 0) - { - inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread); - add_thread (inferior_ptid); - } - - ptid = BUILDPID (pid, thread); - - /* We've become a single threaded process again. */ - if (thread == 0) - inferior_ptid = ptid; - - /* Check for thread creation. */ - if (WIFSTOPPED (status) - && WSTOPSIG (status) == SIGTRAP - && !in_thread_list (ptid)) - { - int realsig; - - realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid), - (PTRACE_ARG3_TYPE) 0, 0); - - if (realsig == SIGNEWTHREAD) - { - /* It's a new thread notification. We don't want to much with - realsig -- the code in wait_for_inferior expects SIGTRAP. */ - ourstatus->kind = TARGET_WAITKIND_SPURIOUS; - ourstatus->value.sig = TARGET_SIGNAL_0; - return ptid; - } - else - error ("Signal for unknown thread was not SIGNEWTHREAD"); - } - - /* Check for thread termination. */ - else if (WIFSTOPPED (status) - && WSTOPSIG (status) == SIGTRAP - && in_thread_list (ptid)) - { - int realsig; - - realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid), - (PTRACE_ARG3_TYPE) 0, 0); - - if (realsig == SIGTHREADEXIT) - { - ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0); - continue; - } - } - -#ifdef SPARC - /* SPARC Lynx uses an byte reversed wait status; we must use the - host macros to access it. These lines just a copy of - store_waitstatus. We can't use CHILD_SPECIAL_WAITSTATUS - because target.c can't include the Lynx . */ - if (WIFEXITED (status)) - { - ourstatus->kind = TARGET_WAITKIND_EXITED; - ourstatus->value.integer = WEXITSTATUS (status); - } - else if (!WIFSTOPPED (status)) - { - ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = - target_signal_from_host (WTERMSIG (status)); - } - else - { - ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = - target_signal_from_host (WSTOPSIG (status)); - } -#else - store_waitstatus (ourstatus, status.w_status); -#endif - - return ptid; - } -} - -/* Return nonzero if the given thread is still alive. */ -int -child_thread_alive (ptid_t ptid) -{ - int pid = PIDGET (ptid); - - /* Arggh. Apparently pthread_kill only works for threads within - the process that calls pthread_kill. - - We want to avoid the lynx signal extensions as they simply don't - map well to the generic gdb interface we want to keep. - - All we want to do is determine if a particular thread is alive; - it appears as if we can just make a harmless thread specific - ptrace call to do that. */ - return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1); -} - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -child_resume (ptid_t ptid, int step, enum target_signal signal) -{ - int func; - int pid = PIDGET (ptid); - - errno = 0; - - /* If pid == -1, then we want to step/continue all threads, else - we only want to step/continue a single thread. */ - if (pid == -1) - { - pid = PIDGET (inferior_ptid); - func = step ? PTRACE_SINGLESTEP : PTRACE_CONT; - } - else - func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE; - - - /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where - it was. (If GDB wanted it to start some other way, we have already - written a new PC value to the child.) - - If this system does not support PT_STEP, a higher level function will - have called single_step() to transmute the step request into a - continue request (by setting breakpoints on all possible successor - instructions), so we don't have to worry about that here. */ - - ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal)); - - if (errno) - perror_with_name ("ptrace"); -} - -/* Convert a Lynx process ID to a string. Returns the string in a static - buffer. */ - -char * -child_pid_to_str (ptid_t ptid) -{ - static char buf[40]; - - sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid)); - - return buf; -} - -/* Extract the register values out of the core file and store - them where `read_register' will find them. - - CORE_REG_SECT points to the register values themselves, read into memory. - CORE_REG_SIZE is the size of that area. - WHICH says which set of registers we are handling (0 = int, 2 = float - on machines where they are discontiguous). - REG_ADDR is the offset from u.u_ar0 to the register values relative to - core_reg_sect. This is used with old-fashioned core files to - locate the registers in a large upage-plus-stack ".reg" section. - Original upage address X is at location core_reg_sect+x+reg_addr. - */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR reg_addr) -{ - struct st_entry s; - unsigned int regno; - - for (regno = 0; regno < NUM_REGS; regno++) - if (regmap[regno] != -1) - supply_register (regno, core_reg_sect + offsetof (st_t, ec) - + regmap[regno]); - -#ifdef SPARC -/* Fetching this register causes all of the I & L regs to be read from the - stack and validated. */ - - fetch_inferior_registers (I0_REGNUM); -#endif -} - - -/* Register that we are able to handle lynx core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns lynx_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_core_lynx (void) -{ - add_core_fns (&lynx_core_fns); -} diff --git a/contrib/gdb/gdb/m2-exp.tab.c b/contrib/gdb/gdb/m2-exp.tab.c deleted file mode 100644 index eefdf807ef7..00000000000 --- a/contrib/gdb/gdb/m2-exp.tab.c +++ /dev/null @@ -1,2162 +0,0 @@ - -/* A Bison parser, made from m2-exp.y - by GNU Bison version 1.27 - */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define INT 257 -#define HEX 258 -#define ERROR 259 -#define UINT 260 -#define M2_TRUE 261 -#define M2_FALSE 262 -#define CHAR 263 -#define FLOAT 264 -#define STRING 265 -#define NAME 266 -#define BLOCKNAME 267 -#define IDENT 268 -#define VARNAME 269 -#define TYPENAME 270 -#define SIZE 271 -#define CAP 272 -#define ORD 273 -#define HIGH 274 -#define ABS 275 -#define MIN_FUNC 276 -#define MAX_FUNC 277 -#define FLOAT_FUNC 278 -#define VAL 279 -#define CHR 280 -#define ODD 281 -#define TRUNC 282 -#define INC 283 -#define DEC 284 -#define INCL 285 -#define EXCL 286 -#define COLONCOLON 287 -#define INTERNAL_VAR 288 -#define ABOVE_COMMA 289 -#define ASSIGN 290 -#define LEQ 291 -#define GEQ 292 -#define NOTEQUAL 293 -#define IN 294 -#define OROR 295 -#define LOGICAL_AND 296 -#define DIV 297 -#define MOD 298 -#define UNARY 299 -#define DOT 300 -#define NOT 301 -#define QID 302 - -#line 40 "m2-exp.y" - - -#include "defs.h" -#include "gdb_string.h" -#include "expression.h" -#include "language.h" -#include "value.h" -#include "parser-defs.h" -#include "m2-lang.h" -#include "bfd.h" /* Required by objfiles.h. */ -#include "symfile.h" /* Required by objfiles.h. */ -#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ - -/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), - as well as gratuitiously global symbol names, so we can have multiple - yacc generated parsers in gdb. Note that these are only the variables - produced by yacc. If other parser generators (bison, byacc, etc) produce - additional global names that conflict at link time, then those parser - generators need to be fixed instead of adding those names to this list. */ - -#define yymaxdepth m2_maxdepth -#define yyparse m2_parse -#define yylex m2_lex -#define yyerror m2_error -#define yylval m2_lval -#define yychar m2_char -#define yydebug m2_debug -#define yypact m2_pact -#define yyr1 m2_r1 -#define yyr2 m2_r2 -#define yydef m2_def -#define yychk m2_chk -#define yypgo m2_pgo -#define yyact m2_act -#define yyexca m2_exca -#define yyerrflag m2_errflag -#define yynerrs m2_nerrs -#define yyps m2_ps -#define yypv m2_pv -#define yys m2_s -#define yy_yys m2_yys -#define yystate m2_state -#define yytmp m2_tmp -#define yyv m2_v -#define yy_yyv m2_yyv -#define yyval m2_val -#define yylloc m2_lloc -#define yyreds m2_reds /* With YYDEBUG defined */ -#define yytoks m2_toks /* With YYDEBUG defined */ -#define yylhs m2_yylhs -#define yylen m2_yylen -#define yydefred m2_yydefred -#define yydgoto m2_yydgoto -#define yysindex m2_yysindex -#define yyrindex m2_yyrindex -#define yygindex m2_yygindex -#define yytable m2_yytable -#define yycheck m2_yycheck - -#ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ -#endif - -int -yyparse PARAMS ((void)); - -static int -yylex PARAMS ((void)); - -void -yyerror PARAMS ((char *)); - -#if 0 -static char * -make_qualname PARAMS ((char *, char *)); -#endif - -static int -parse_number PARAMS ((int)); - -/* The sign of the number being parsed. */ -static int number_sign = 1; - -/* The block that the module specified by the qualifer on an identifer is - contained in, */ -#if 0 -static struct block *modblock=0; -#endif - - -#line 135 "m2-exp.y" -typedef union - { - LONGEST lval; - ULONGEST ulval; - DOUBLEST dval; - struct symbol *sym; - struct type *tval; - struct stoken sval; - int voidval; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - - struct type **tvec; - int *ivec; - } YYSTYPE; -#include - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 181 -#define YYFLAG -32768 -#define YYNTBASE 68 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 302 ? yytranslate[x] : 82) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 44, 2, 2, 48, 2, 60, - 64, 52, 50, 35, 51, 2, 53, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 38, - 42, 39, 2, 49, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 59, 2, 67, 57, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 65, 2, 66, 62, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, - 40, 41, 43, 45, 46, 47, 54, 55, 56, 58, - 61, 63 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 4, 6, 9, 10, 14, 17, 20, 22, - 24, 29, 34, 39, 44, 49, 54, 59, 66, 71, - 76, 81, 84, 89, 96, 101, 108, 112, 114, 118, - 125, 132, 136, 141, 142, 148, 149, 155, 156, 158, - 162, 164, 168, 173, 178, 182, 186, 190, 194, 198, - 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, - 242, 246, 250, 252, 254, 256, 258, 260, 262, 264, - 269, 271, 273, 275, 279, 281, 283, 287, 289 -}; - -static const short yyrhs[] = { 70, - 0, 69, 0, 81, 0, 70, 57, 0, 0, 51, - 71, 70, 0, 50, 70, 0, 72, 70, 0, 61, - 0, 62, 0, 18, 60, 70, 64, 0, 19, 60, - 70, 64, 0, 21, 60, 70, 64, 0, 20, 60, - 70, 64, 0, 22, 60, 81, 64, 0, 23, 60, - 81, 64, 0, 24, 60, 70, 64, 0, 25, 60, - 81, 35, 70, 64, 0, 26, 60, 70, 64, 0, - 27, 60, 70, 64, 0, 28, 60, 70, 64, 0, - 17, 70, 0, 29, 60, 70, 64, 0, 29, 60, - 70, 35, 70, 64, 0, 30, 60, 70, 64, 0, - 30, 60, 70, 35, 70, 64, 0, 70, 58, 12, - 0, 73, 0, 70, 45, 73, 0, 31, 60, 70, - 35, 70, 64, 0, 32, 60, 70, 35, 70, 64, - 0, 65, 76, 66, 0, 81, 65, 76, 66, 0, - 0, 70, 59, 74, 77, 67, 0, 0, 70, 60, - 75, 76, 64, 0, 0, 70, 0, 76, 35, 70, - 0, 70, 0, 77, 35, 70, 0, 65, 81, 66, - 70, 0, 81, 60, 70, 64, 0, 60, 70, 64, - 0, 70, 49, 70, 0, 70, 52, 70, 0, 70, - 53, 70, 0, 70, 54, 70, 0, 70, 55, 70, - 0, 70, 50, 70, 0, 70, 51, 70, 0, 70, - 42, 70, 0, 70, 43, 70, 0, 70, 44, 70, - 0, 70, 40, 70, 0, 70, 41, 70, 0, 70, - 38, 70, 0, 70, 39, 70, 0, 70, 47, 70, - 0, 70, 46, 70, 0, 70, 37, 70, 0, 7, - 0, 8, 0, 3, 0, 6, 0, 9, 0, 10, - 0, 80, 0, 17, 60, 81, 64, 0, 11, 0, - 79, 0, 13, 0, 78, 33, 13, 0, 79, 0, - 34, 0, 78, 33, 12, 0, 12, 0, 16, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 204, 205, 208, 217, 220, 222, 227, 231, 235, 236, - 239, 243, 247, 251, 255, 261, 267, 271, 277, 281, - 285, 289, 294, 298, 304, 308, 314, 320, 323, 327, - 331, 334, 336, 342, 347, 353, 357, 363, 366, 370, - 375, 380, 385, 391, 397, 405, 409, 413, 417, 421, - 425, 429, 433, 437, 439, 443, 447, 451, 455, 459, - 463, 467, 474, 480, 486, 493, 502, 510, 517, 520, - 527, 534, 538, 547, 559, 567, 571, 587, 638 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","INT","HEX", -"ERROR","UINT","M2_TRUE","M2_FALSE","CHAR","FLOAT","STRING","NAME","BLOCKNAME", -"IDENT","VARNAME","TYPENAME","SIZE","CAP","ORD","HIGH","ABS","MIN_FUNC","MAX_FUNC", -"FLOAT_FUNC","VAL","CHR","ODD","TRUNC","INC","DEC","INCL","EXCL","COLONCOLON", -"INTERNAL_VAR","','","ABOVE_COMMA","ASSIGN","'<'","'>'","LEQ","GEQ","'='","NOTEQUAL", -"'#'","IN","OROR","LOGICAL_AND","'&'","'@'","'+'","'-'","'*'","'/'","DIV","MOD", -"UNARY","'^'","DOT","'['","'('","NOT","'~'","QID","')'","'{'","'}'","']'","start", -"type_exp","exp","@1","not_exp","set","@2","@3","arglist","non_empty_arglist", -"block","fblock","variable","type", NULL -}; -#endif - -static const short yyr1[] = { 0, - 68, 68, 69, 70, 71, 70, 70, 70, 72, 72, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 73, 73, 74, 70, 75, 70, 76, 76, 76, - 77, 77, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 78, 79, 79, 80, 80, 80, 80, 81 -}; - -static const short yyr2[] = { 0, - 1, 1, 1, 2, 0, 3, 2, 2, 1, 1, - 4, 4, 4, 4, 4, 4, 4, 6, 4, 4, - 4, 2, 4, 6, 4, 6, 3, 1, 3, 6, - 6, 3, 4, 0, 5, 0, 5, 0, 1, 3, - 1, 3, 4, 4, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, 1, 4, - 1, 1, 1, 3, 1, 1, 3, 1, 1 -}; - -static const short yydefact[] = { 0, - 65, 66, 63, 64, 67, 68, 71, 78, 73, 79, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 76, 0, 5, 0, - 9, 10, 38, 2, 1, 0, 28, 0, 75, 69, - 3, 0, 22, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, - 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 0, 34, 36, 8, 0, 0, - 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 6, 45, 0, - 32, 0, 62, 58, 59, 56, 57, 53, 54, 55, - 38, 29, 0, 61, 60, 46, 51, 52, 47, 48, - 49, 50, 27, 0, 38, 77, 74, 0, 0, 70, - 11, 12, 14, 13, 15, 16, 17, 0, 19, 20, - 21, 0, 23, 0, 25, 0, 0, 40, 43, 41, - 0, 0, 44, 33, 0, 0, 0, 0, 0, 0, - 35, 37, 18, 24, 26, 30, 31, 42, 0, 0, - 0 -}; - -static const short yydefgoto[] = { 179, - 34, 63, 61, 36, 37, 134, 135, 64, 161, 38, - 39, 40, 44 -}; - -static const short yypact[] = { 155, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 215, -27, -22, -20, -19, 14, 24, 26, 27, 28, - 29, 31, 32, 33, 35, 36,-32768, 155,-32768, 155, --32768,-32768, 155,-32768, 742, 155,-32768, -6, -4,-32768, - -34, 155, 5, -34, 155, 155, 155, 155, 44, 44, - 155, 44, 155, 155, 155, 155, 155, 155, 155, 5, - 155, 272, 742, -31, -41, 155, 155, 155, 155, 155, - 155, 155, 155, -15, 155, 155, 155, 155, 155, 155, - 155, 155, 155,-32768, 85,-32768,-32768, 5, -5, 155, - 155, -21, 300, 328, 356, 384, 34, 39, 412, 64, - 440, 468, 496, 78, 244, 692, 718, 5,-32768, 155, --32768, 155, 766, -37, -37, -37, -37, -37, -37, -37, - 155,-32768, 40, 141, 201, 777, 786, 786, 5, 5, - 5, 5,-32768, 155, 155,-32768,-32768, 524, -29,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 155,-32768,-32768, --32768, 155,-32768, 155,-32768, 155, 155, 742, 5, 742, - -33, -32,-32768,-32768, 552, 580, 608, 636, 664, 155, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 742, 100, 106, --32768 -}; - -static const short yypgoto[] = {-32768, --32768, 0,-32768,-32768, 37,-32768,-32768, -86,-32768,-32768, --32768,-32768, 52 -}; - - -#define YYLAST 846 - - -static const short yytable[] = { 35, - 10, 170, 110, 110, 139, 110, 136, 137, 75, 76, - 43, 77, 78, 79, 80, 81, 82, 83, 90, 84, - 85, 86, 87, 91, 112, 90, 89, 60, -72, 62, - 91, 172, 45, 171, 111, 88, 164, 46, 90, 47, - 48, 62, 140, 91, 93, 94, 95, 96, 162, 121, - 99, 41, 101, 102, 103, 104, 105, 106, 107, 10, - 108, 84, 85, 86, 87, 113, 114, 115, 116, 117, - 118, 119, 120, 49, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 50, 65, 51, 52, 53, 54, 138, - 55, 56, 57, 92, 58, 59, 133, 145, 148, 180, - 97, 98, 146, 100, 91, 181, 0, 0, 0, 158, - 122, 159, 152, 0, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 123, 77, 78, 79, 80, - 81, 82, 83, 160, 84, 85, 86, 87, 0, 0, - 0, 153, 0, 0, 0, 0, 0, 165, 0, 0, - 0, 166, 0, 167, 0, 168, 169, 1, 0, 0, - 2, 3, 4, 5, 6, 7, 8, 9, 0, 178, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 76, 27, 77, - 78, 79, 80, 81, 82, 83, 0, 84, 85, 86, - 87, 0, 0, 0, 28, 29, 0, 0, 0, 0, - 0, 0, 0, 0, 30, 31, 32, 1, 0, 33, - 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 0, 27, 77, - 78, 79, 80, 81, 82, 83, 0, 84, 85, 86, - 87, 0, 0, 0, 28, 29, 0, 0, 0, 0, - 0, 0, 0, 0, 42, 31, 32, 0, 154, 33, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 0, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 85, 86, 87, 0, 0, 0, 155, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 0, - 77, 78, 79, 80, 81, 82, 83, 0, 84, 85, - 86, 87, 0, 0, 0, 109, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 0, 77, 78, - 79, 80, 81, 82, 83, 0, 84, 85, 86, 87, - 0, 0, 0, 141, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 0, 77, 78, 79, 80, - 81, 82, 83, 0, 84, 85, 86, 87, 0, 0, - 0, 142, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 0, 77, 78, 79, 80, 81, 82, - 83, 0, 84, 85, 86, 87, 0, 0, 0, 143, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 0, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 85, 86, 87, 0, 0, 0, 144, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 0, - 77, 78, 79, 80, 81, 82, 83, 0, 84, 85, - 86, 87, 0, 0, 0, 147, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 0, 77, 78, - 79, 80, 81, 82, 83, 0, 84, 85, 86, 87, - 0, 0, 0, 149, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 0, 77, 78, 79, 80, - 81, 82, 83, 0, 84, 85, 86, 87, 0, 0, - 0, 150, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 0, 77, 78, 79, 80, 81, 82, - 83, 0, 84, 85, 86, 87, 0, 0, 0, 151, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 0, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 85, 86, 87, 0, 0, 0, 163, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 0, - 77, 78, 79, 80, 81, 82, 83, 0, 84, 85, - 86, 87, 0, 0, 0, 173, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 0, 77, 78, - 79, 80, 81, 82, 83, 0, 84, 85, 86, 87, - 0, 0, 0, 174, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 0, 77, 78, 79, 80, - 81, 82, 83, 0, 84, 85, 86, 87, 0, 0, - 0, 175, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 0, 77, 78, 79, 80, 81, 82, - 83, 0, 84, 85, 86, 87, 0, 0, 0, 176, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 0, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 85, 86, 87, 0, 0, 156, 177, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 0, - 77, 78, 79, 80, 81, 82, 83, 0, 84, 85, - 86, 87, 157, 0, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 0, 77, 78, 79, 80, - 81, 82, 83, 0, 84, 85, 86, 87, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 0, - 77, 78, 79, 80, 81, 82, 83, 0, 84, 85, - 86, 87,-32768, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 0, 77, 78, 79, 80, 81, 82, - 83, 0, 84, 85, 86, 87, 78, 79, 80, 81, - 82, 83, 0, 84, 85, 86, 87, 80, 81, 82, - 83, 0, 84, 85, 86, 87 -}; - -static const short yycheck[] = { 0, - 16, 35, 35, 35, 91, 35, 12, 13, 46, 47, - 11, 49, 50, 51, 52, 53, 54, 55, 60, 57, - 58, 59, 60, 65, 66, 60, 33, 28, 33, 30, - 65, 64, 60, 67, 66, 36, 66, 60, 60, 60, - 60, 42, 64, 65, 45, 46, 47, 48, 135, 65, - 51, 0, 53, 54, 55, 56, 57, 58, 59, 16, - 61, 57, 58, 59, 60, 66, 67, 68, 69, 70, - 71, 72, 73, 60, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 60, 33, 60, 60, 60, 60, 90, - 60, 60, 60, 42, 60, 60, 12, 64, 35, 0, - 49, 50, 64, 52, 65, 0, -1, -1, -1, 110, - 74, 112, 35, -1, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 74, 49, 50, 51, 52, - 53, 54, 55, 134, 57, 58, 59, 60, -1, -1, - -1, 64, -1, -1, -1, -1, -1, 148, -1, -1, - -1, 152, -1, 154, -1, 156, 157, 3, -1, -1, - 6, 7, 8, 9, 10, 11, 12, 13, -1, 170, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 47, 34, 49, - 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, - 60, -1, -1, -1, 50, 51, -1, -1, -1, -1, - -1, -1, -1, -1, 60, 61, 62, 3, -1, 65, - 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, -1, 34, 49, - 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, - 60, -1, -1, -1, 50, 51, -1, -1, -1, -1, - -1, -1, -1, -1, 60, 61, 62, -1, 35, 65, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, -1, 49, 50, 51, 52, 53, 54, 55, -1, - 57, 58, 59, 60, -1, -1, -1, 64, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, -1, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, -1, -1, -1, 64, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, -1, 49, 50, - 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, - -1, -1, -1, 64, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, -1, 49, 50, 51, 52, - 53, 54, 55, -1, 57, 58, 59, 60, -1, -1, - -1, 64, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, -1, 49, 50, 51, 52, 53, 54, - 55, -1, 57, 58, 59, 60, -1, -1, -1, 64, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, -1, 49, 50, 51, 52, 53, 54, 55, -1, - 57, 58, 59, 60, -1, -1, -1, 64, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, -1, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, -1, -1, -1, 64, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, -1, 49, 50, - 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, - -1, -1, -1, 64, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, -1, 49, 50, 51, 52, - 53, 54, 55, -1, 57, 58, 59, 60, -1, -1, - -1, 64, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, -1, 49, 50, 51, 52, 53, 54, - 55, -1, 57, 58, 59, 60, -1, -1, -1, 64, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, -1, 49, 50, 51, 52, 53, 54, 55, -1, - 57, 58, 59, 60, -1, -1, -1, 64, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, -1, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, -1, -1, -1, 64, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, -1, 49, 50, - 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, - -1, -1, -1, 64, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, -1, 49, 50, 51, 52, - 53, 54, 55, -1, 57, 58, 59, 60, -1, -1, - -1, 64, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, -1, 49, 50, 51, 52, 53, 54, - 55, -1, 57, 58, 59, 60, -1, -1, -1, 64, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, -1, 49, 50, 51, 52, 53, 54, 55, -1, - 57, 58, 59, 60, -1, -1, 35, 64, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, -1, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, 35, -1, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, -1, 49, 50, 51, 52, - 53, 54, 55, -1, 57, 58, 59, 60, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, -1, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, -1, 49, 50, 51, 52, 53, 54, - 55, -1, 57, 58, 59, 60, 50, 51, 52, 53, - 54, 55, -1, 57, 58, 59, 60, 52, 53, 54, - 55, -1, 57, 58, 59, 60 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/lib/bison.simple" -/* This file comes from bison-1.27. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for xmalloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC xmalloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 216 "/usr/lib/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to xreallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to xreallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 3: -#line 209 "m2-exp.y" -{ write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type(yyvsp[0].tval); - write_exp_elt_opcode(OP_TYPE); - ; - break;} -case 4: -#line 218 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_IND); ; - break;} -case 5: -#line 221 "m2-exp.y" -{ number_sign = -1; ; - break;} -case 6: -#line 223 "m2-exp.y" -{ number_sign = 1; - write_exp_elt_opcode (UNOP_NEG); ; - break;} -case 7: -#line 228 "m2-exp.y" -{ write_exp_elt_opcode(UNOP_PLUS); ; - break;} -case 8: -#line 232 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ; - break;} -case 11: -#line 240 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_CAP); ; - break;} -case 12: -#line 244 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_ORD); ; - break;} -case 13: -#line 248 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_ABS); ; - break;} -case 14: -#line 252 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_HIGH); ; - break;} -case 15: -#line 256 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_MIN); - write_exp_elt_type (yyvsp[-1].tval); - write_exp_elt_opcode (UNOP_MIN); ; - break;} -case 16: -#line 262 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_MAX); - write_exp_elt_type (yyvsp[-1].tval); - write_exp_elt_opcode (UNOP_MIN); ; - break;} -case 17: -#line 268 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_FLOAT); ; - break;} -case 18: -#line 272 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_VAL); - write_exp_elt_type (yyvsp[-3].tval); - write_exp_elt_opcode (BINOP_VAL); ; - break;} -case 19: -#line 278 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_CHR); ; - break;} -case 20: -#line 282 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_ODD); ; - break;} -case 21: -#line 286 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_TRUNC); ; - break;} -case 22: -#line 290 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_SIZEOF); ; - break;} -case 23: -#line 295 "m2-exp.y" -{ write_exp_elt_opcode(UNOP_PREINCREMENT); ; - break;} -case 24: -#line 299 "m2-exp.y" -{ write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode(BINOP_ADD); - write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); ; - break;} -case 25: -#line 305 "m2-exp.y" -{ write_exp_elt_opcode(UNOP_PREDECREMENT);; - break;} -case 26: -#line 309 "m2-exp.y" -{ write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode(BINOP_SUB); - write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); ; - break;} -case 27: -#line 315 "m2-exp.y" -{ write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string (yyvsp[0].sval); - write_exp_elt_opcode (STRUCTOP_STRUCT); ; - break;} -case 29: -#line 324 "m2-exp.y" -{ error("Sets are not implemented.");; - break;} -case 30: -#line 328 "m2-exp.y" -{ error("Sets are not implemented.");; - break;} -case 31: -#line 332 "m2-exp.y" -{ error("Sets are not implemented.");; - break;} -case 32: -#line 335 "m2-exp.y" -{ error("Sets are not implemented.");; - break;} -case 33: -#line 337 "m2-exp.y" -{ error("Sets are not implemented.");; - break;} -case 34: -#line 346 "m2-exp.y" -{ start_arglist(); ; - break;} -case 35: -#line 348 "m2-exp.y" -{ write_exp_elt_opcode (MULTI_SUBSCRIPT); - write_exp_elt_longcst ((LONGEST) end_arglist()); - write_exp_elt_opcode (MULTI_SUBSCRIPT); ; - break;} -case 36: -#line 356 "m2-exp.y" -{ start_arglist (); ; - break;} -case 37: -#line 358 "m2-exp.y" -{ write_exp_elt_opcode (OP_FUNCALL); - write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_FUNCALL); ; - break;} -case 39: -#line 367 "m2-exp.y" -{ arglist_len = 1; ; - break;} -case 40: -#line 371 "m2-exp.y" -{ arglist_len++; ; - break;} -case 41: -#line 376 "m2-exp.y" -{ arglist_len = 1; ; - break;} -case 42: -#line 381 "m2-exp.y" -{ arglist_len++; ; - break;} -case 43: -#line 386 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_MEMVAL); - write_exp_elt_type (yyvsp[-2].tval); - write_exp_elt_opcode (UNOP_MEMVAL); ; - break;} -case 44: -#line 392 "m2-exp.y" -{ write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type (yyvsp[-3].tval); - write_exp_elt_opcode (UNOP_CAST); ; - break;} -case 45: -#line 398 "m2-exp.y" -{ ; - break;} -case 46: -#line 406 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_REPEAT); ; - break;} -case 47: -#line 410 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_MUL); ; - break;} -case 48: -#line 414 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_DIV); ; - break;} -case 49: -#line 418 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_INTDIV); ; - break;} -case 50: -#line 422 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_REM); ; - break;} -case 51: -#line 426 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_ADD); ; - break;} -case 52: -#line 430 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_SUB); ; - break;} -case 53: -#line 434 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_EQUAL); ; - break;} -case 54: -#line 438 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_NOTEQUAL); ; - break;} -case 55: -#line 440 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_NOTEQUAL); ; - break;} -case 56: -#line 444 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_LEQ); ; - break;} -case 57: -#line 448 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_GEQ); ; - break;} -case 58: -#line 452 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_LESS); ; - break;} -case 59: -#line 456 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_GTR); ; - break;} -case 60: -#line 460 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ; - break;} -case 61: -#line 464 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ; - break;} -case 62: -#line 468 "m2-exp.y" -{ write_exp_elt_opcode (BINOP_ASSIGN); ; - break;} -case 63: -#line 475 "m2-exp.y" -{ write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); - write_exp_elt_opcode (OP_BOOL); ; - break;} -case 64: -#line 481 "m2-exp.y" -{ write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); - write_exp_elt_opcode (OP_BOOL); ; - break;} -case 65: -#line 487 "m2-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_m2_int); - write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 66: -#line 494 "m2-exp.y" -{ - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_m2_card); - write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); - write_exp_elt_opcode (OP_LONG); - ; - break;} -case 67: -#line 503 "m2-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_m2_char); - write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 68: -#line 511 "m2-exp.y" -{ write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (builtin_type_m2_real); - write_exp_elt_dblcst (yyvsp[0].dval); - write_exp_elt_opcode (OP_DOUBLE); ; - break;} -case 70: -#line 521 "m2-exp.y" -{ write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_int); - write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); - write_exp_elt_opcode (OP_LONG); ; - break;} -case 71: -#line 528 "m2-exp.y" -{ write_exp_elt_opcode (OP_M2_STRING); - write_exp_string (yyvsp[0].sval); - write_exp_elt_opcode (OP_M2_STRING); ; - break;} -case 72: -#line 535 "m2-exp.y" -{ yyval.bval = SYMBOL_BLOCK_VALUE(yyvsp[0].sym); ; - break;} -case 73: -#line 539 "m2-exp.y" -{ struct symbol *sym - = lookup_symbol (copy_name (yyvsp[0].sval), expression_context_block, - VAR_NAMESPACE, 0, NULL); - yyval.sym = sym;; - break;} -case 74: -#line 548 "m2-exp.y" -{ struct symbol *tem - = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, - VAR_NAMESPACE, 0, NULL); - if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) - error ("No function \"%s\" in specified context.", - copy_name (yyvsp[0].sval)); - yyval.sym = tem; - ; - break;} -case 75: -#line 560 "m2-exp.y" -{ write_exp_elt_opcode(OP_VAR_VALUE); - write_exp_elt_block (NULL); - write_exp_elt_sym (yyvsp[0].sym); - write_exp_elt_opcode (OP_VAR_VALUE); ; - break;} -case 77: -#line 572 "m2-exp.y" -{ struct symbol *sym; - sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, - VAR_NAMESPACE, 0, NULL); - if (sym == 0) - error ("No symbol \"%s\" in specified context.", - copy_name (yyvsp[0].sval)); - - write_exp_elt_opcode (OP_VAR_VALUE); - /* block_found is set by lookup_symbol. */ - write_exp_elt_block (block_found); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); ; - break;} -case 78: -#line 588 "m2-exp.y" -{ struct symbol *sym; - int is_a_field_of_this; - - sym = lookup_symbol (copy_name (yyvsp[0].sval), - expression_context_block, - VAR_NAMESPACE, - &is_a_field_of_this, - NULL); - if (sym) - { - if (symbol_read_needs_frame (sym)) - { - if (innermost_block == 0 || - contained_in (block_found, - innermost_block)) - innermost_block = block_found; - } - - write_exp_elt_opcode (OP_VAR_VALUE); - /* We want to use the selected frame, not - another more inner frame which happens to - be in the same block. */ - write_exp_elt_block (NULL); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); - } - else - { - struct minimal_symbol *msymbol; - register char *arg = copy_name (yyvsp[0].sval); - - msymbol = - lookup_minimal_symbol (arg, NULL, NULL); - if (msymbol != NULL) - { - write_exp_msymbol - (msymbol, - lookup_function_type (builtin_type_int), - builtin_type_int); - } - else if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"symbol-file\" command."); - else - error ("No symbol \"%s\" in current context.", - copy_name (yyvsp[0].sval)); - } - ; - break;} -case 79: -#line 639 "m2-exp.y" -{ yyval.tval = lookup_typename (copy_name (yyvsp[0].sval), - expression_context_block, 0); ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 542 "/usr/lib/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) xmalloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} -#line 644 "m2-exp.y" - - -#if 0 /* FIXME! */ -int -overflow(a,b) - long a,b; -{ - return (MAX_OF_TYPE(builtin_type_m2_int) - b) < a; -} - -int -uoverflow(a,b) - unsigned long a,b; -{ - return (MAX_OF_TYPE(builtin_type_m2_card) - b) < a; -} -#endif /* FIXME */ - -/* Take care of parsing a number (anything that starts with a digit). - Set yylval and return the token type; update lexptr. - LEN is the number of characters in it. */ - -/*** Needs some error checking for the float case ***/ - -static int -parse_number (olen) - int olen; -{ - register char *p = lexptr; - register LONGEST n = 0; - register LONGEST prevn = 0; - register int c,i,ischar=0; - register int base = input_radix; - register int len = olen; - int unsigned_p = number_sign == 1 ? 1 : 0; - - if(p[len-1] == 'H') - { - base = 16; - len--; - } - else if(p[len-1] == 'C' || p[len-1] == 'B') - { - base = 8; - ischar = p[len-1] == 'C'; - len--; - } - - /* Scan the number */ - for (c = 0; c < len; c++) - { - if (p[c] == '.' && base == 10) - { - /* It's a float since it contains a point. */ - yylval.dval = atof (p); - lexptr += len; - return FLOAT; - } - if (p[c] == '.' && base != 10) - error("Floating point numbers must be base 10."); - if (base == 10 && (p[c] < '0' || p[c] > '9')) - error("Invalid digit \'%c\' in number.",p[c]); - } - - while (len-- > 0) - { - c = *p++; - n *= base; - if( base == 8 && (c == '8' || c == '9')) - error("Invalid digit \'%c\' in octal number.",c); - if (c >= '0' && c <= '9') - i = c - '0'; - else - { - if (base == 16 && c >= 'A' && c <= 'F') - i = c - 'A' + 10; - else - return ERROR; - } - n+=i; - if(i >= base) - return ERROR; - if(!unsigned_p && number_sign == 1 && (prevn >= n)) - unsigned_p=1; /* Try something unsigned */ - /* Don't do the range check if n==i and i==0, since that special - case will give an overflow error. */ - if(RANGE_CHECK && n!=i && i) - { - if((unsigned_p && (unsigned)prevn >= (unsigned)n) || - ((!unsigned_p && number_sign==-1) && -prevn <= -n)) - range_error("Overflow on numeric constant."); - } - prevn=n; - } - - lexptr = p; - if(*p == 'B' || *p == 'C' || *p == 'H') - lexptr++; /* Advance past B,C or H */ - - if (ischar) - { - yylval.ulval = n; - return CHAR; - } - else if ( unsigned_p && number_sign == 1) - { - yylval.ulval = n; - return UINT; - } - else if((unsigned_p && (n<0))) { - range_error("Overflow on numeric constant -- number too large."); - /* But, this can return if range_check == range_warn. */ - } - yylval.lval = n; - return INT; -} - - -/* Some tokens */ - -static struct -{ - char name[2]; - int token; -} tokentab2[] = -{ - { {'<', '>'}, NOTEQUAL }, - { {':', '='}, ASSIGN }, - { {'<', '='}, LEQ }, - { {'>', '='}, GEQ }, - { {':', ':'}, COLONCOLON }, - -}; - -/* Some specific keywords */ - -struct keyword { - char keyw[10]; - int token; -}; - -static struct keyword keytab[] = -{ - {"OR" , OROR }, - {"IN", IN },/* Note space after IN */ - {"AND", LOGICAL_AND}, - {"ABS", ABS }, - {"CHR", CHR }, - {"DEC", DEC }, - {"NOT", NOT }, - {"DIV", DIV }, - {"INC", INC }, - {"MAX", MAX_FUNC }, - {"MIN", MIN_FUNC }, - {"MOD", MOD }, - {"ODD", ODD }, - {"CAP", CAP }, - {"ORD", ORD }, - {"VAL", VAL }, - {"EXCL", EXCL }, - {"HIGH", HIGH }, - {"INCL", INCL }, - {"SIZE", SIZE }, - {"FLOAT", FLOAT_FUNC }, - {"TRUNC", TRUNC }, -}; - - -/* Read one token, getting characters through lexptr. */ - -/* This is where we will check to make sure that the language and the operators used are - compatible */ - -static int -yylex () -{ - register int c; - register int namelen; - register int i; - register char *tokstart; - register char quote; - - retry: - - tokstart = lexptr; - - - /* See if it is a special token of length 2 */ - for( i = 0 ; i < (int) (sizeof tokentab2 / sizeof tokentab2[0]) ; i++) - if(STREQN(tokentab2[i].name, tokstart, 2)) - { - lexptr += 2; - return tokentab2[i].token; - } - - switch (c = *tokstart) - { - case 0: - return 0; - - case ' ': - case '\t': - case '\n': - lexptr++; - goto retry; - - case '(': - paren_depth++; - lexptr++; - return c; - - case ')': - if (paren_depth == 0) - return 0; - paren_depth--; - lexptr++; - return c; - - case ',': - if (comma_terminates && paren_depth == 0) - return 0; - lexptr++; - return c; - - case '.': - /* Might be a floating point number. */ - if (lexptr[1] >= '0' && lexptr[1] <= '9') - break; /* Falls into number code. */ - else - { - lexptr++; - return DOT; - } - -/* These are character tokens that appear as-is in the YACC grammar */ - case '+': - case '-': - case '*': - case '/': - case '^': - case '<': - case '>': - case '[': - case ']': - case '=': - case '{': - case '}': - case '#': - case '@': - case '~': - case '&': - lexptr++; - return c; - - case '\'' : - case '"': - quote = c; - for (namelen = 1; (c = tokstart[namelen]) != quote && c != '\0'; namelen++) - if (c == '\\') - { - c = tokstart[++namelen]; - if (c >= '0' && c <= '9') - { - c = tokstart[++namelen]; - if (c >= '0' && c <= '9') - c = tokstart[++namelen]; - } - } - if(c != quote) - error("Unterminated string or character constant."); - yylval.sval.ptr = tokstart + 1; - yylval.sval.length = namelen - 1; - lexptr += namelen + 1; - - if(namelen == 2) /* Single character */ - { - yylval.ulval = tokstart[1]; - return CHAR; - } - else - return STRING; - } - - /* Is it a number? */ - /* Note: We have already dealt with the case of the token '.'. - See case '.' above. */ - if ((c >= '0' && c <= '9')) - { - /* It's a number. */ - int got_dot = 0, got_e = 0; - register char *p = tokstart; - int toktype; - - for (++p ;; ++p) - { - if (!got_e && (*p == 'e' || *p == 'E')) - got_dot = got_e = 1; - else if (!got_dot && *p == '.') - got_dot = 1; - else if (got_e && (p[-1] == 'e' || p[-1] == 'E') - && (*p == '-' || *p == '+')) - /* This is the sign of the exponent, not the end of the - number. */ - continue; - else if ((*p < '0' || *p > '9') && - (*p < 'A' || *p > 'F') && - (*p != 'H')) /* Modula-2 hexadecimal number */ - break; - } - toktype = parse_number (p - tokstart); - if (toktype == ERROR) - { - char *err_copy = (char *) alloca (p - tokstart + 1); - - memcpy (err_copy, tokstart, p - tokstart); - err_copy[p - tokstart] = 0; - error ("Invalid number \"%s\".", err_copy); - } - lexptr = p; - return toktype; - } - - if (!(c == '_' || c == '$' - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) - /* We must have come across a bad character (e.g. ';'). */ - error ("Invalid character '%c' in expression.", c); - - /* It's a name. See how long it is. */ - namelen = 0; - for (c = tokstart[namelen]; - (c == '_' || c == '$' || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); - c = tokstart[++namelen]) - ; - - /* The token "if" terminates the expression and is NOT - removed from the input stream. */ - if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') - { - return 0; - } - - lexptr += namelen; - - /* Lookup special keywords */ - for(i = 0 ; i < (int) (sizeof(keytab) / sizeof(keytab[0])) ; i++) - if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen)) - return keytab[i].token; - - yylval.sval.ptr = tokstart; - yylval.sval.length = namelen; - - if (*tokstart == '$') - { - write_dollar_variable (yylval.sval); - return INTERNAL_VAR; - } - - /* Use token-type BLOCKNAME for symbols that happen to be defined as - functions. If this is not so, then ... - Use token-type TYPENAME for symbols that happen to be defined - currently as names of types; NAME for other symbols. - The caller is not constrained to care about the distinction. */ - { - - - char *tmp = copy_name (yylval.sval); - struct symbol *sym; - - if (lookup_partial_symtab (tmp)) - return BLOCKNAME; - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, 0, NULL); - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) - return BLOCKNAME; - if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1)) - return TYPENAME; - - if(sym) - { - switch(sym->aclass) - { - case LOC_STATIC: - case LOC_REGISTER: - case LOC_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_LOCAL: - case LOC_LOCAL_ARG: - case LOC_BASEREG: - case LOC_BASEREG_ARG: - case LOC_CONST: - case LOC_CONST_BYTES: - case LOC_OPTIMIZED_OUT: - return NAME; - - case LOC_TYPEDEF: - return TYPENAME; - - case LOC_BLOCK: - return BLOCKNAME; - - case LOC_UNDEF: - error("internal: Undefined class in m2lex()"); - - case LOC_LABEL: - case LOC_UNRESOLVED: - error("internal: Unforseen case in m2lex()"); - - default: - error ("unhandled token in m2lex()"); - break; - } - } - else - { - /* Built-in BOOLEAN type. This is sort of a hack. */ - if(STREQN(tokstart,"TRUE",4)) - { - yylval.ulval = 1; - return M2_TRUE; - } - else if(STREQN(tokstart,"FALSE",5)) - { - yylval.ulval = 0; - return M2_FALSE; - } - } - - /* Must be another type of name... */ - return NAME; - } -} - -#if 0 /* Unused */ -static char * -make_qualname(mod,ident) - char *mod, *ident; -{ - char *new = xmalloc(strlen(mod)+strlen(ident)+2); - - strcpy(new,mod); - strcat(new,"."); - strcat(new,ident); - return new; -} -#endif /* 0 */ - -void -yyerror (msg) - char *msg; -{ - error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); -} diff --git a/contrib/gdb/gdb/m32r-rom.c b/contrib/gdb/gdb/m32r-rom.c deleted file mode 100644 index b4bfefdf210..00000000000 --- a/contrib/gdb/gdb/m32r-rom.c +++ /dev/null @@ -1,626 +0,0 @@ -/* Remote debugging interface to m32r and mon2000 ROM monitors for GDB, - the GNU debugger. - Copyright 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - Adapted by Michael Snyder of Cygnus Support. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This module defines communication with the Mitsubishi m32r monitor */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "symtab.h" -#include "command.h" -#include "gdbcmd.h" -#include "symfile.h" /* for generic load */ -#include /* for time_t */ -#include "gdb_string.h" -#include "objfiles.h" /* for ALL_OBJFILES etc. */ -#include "inferior.h" /* for write_pc() */ -#include -#include "regcache.h" - -extern void report_transfer_performance (unsigned long, time_t, time_t); - -/* - * All this stuff just to get my host computer's IP address! - */ -#include -#include /* for hostent */ -#include /* for struct in_addr */ -#if 1 -#include /* for inet_ntoa */ -#endif - -static char *board_addr; /* user-settable IP address for M32R-EVA */ -static char *server_addr; /* user-settable IP address for gdb host */ -static char *download_path; /* user-settable path for SREC files */ - - -/* - * Function: m32r_load_1 (helper function) - */ - -static void -m32r_load_section (bfd *abfd, asection *s, void *obj) -{ - unsigned int *data_count = obj; - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_lma (abfd, s); - unsigned int buffer, i; - - *data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx lma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - monitor_printf ("%s mw\r", paddr_nz (section_base)); - for (i = 0; i < section_size; i += 4) - { - QUIT; - monitor_expect (" -> ", NULL, 0); - bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); - monitor_printf ("%x\n", buffer); - } - monitor_expect (" -> ", NULL, 0); - monitor_printf ("q\n"); - monitor_expect_prompt (NULL, 0); - } -} - -static int -m32r_load_1 (void *dummy) -{ - int data_count = 0; - - bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count); - return data_count; -} - -/* - * Function: m32r_load (an alternate way to load) - */ - -static void -m32r_load (char *filename, int from_tty) -{ - bfd *abfd; - asection *s; - unsigned int i, data_count = 0; - time_t start_time, end_time; /* for timing of download */ - - if (filename == NULL || filename[0] == 0) - filename = get_exec_file (1); - - abfd = bfd_openr (filename, 0); - if (!abfd) - error ("Unable to open file %s\n", filename); - if (bfd_check_format (abfd, bfd_object) == 0) - error ("File is not an object file\n"); - start_time = time (NULL); -#if 0 - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_vma (abfd, s); - unsigned int buffer; - - data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx vma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - monitor_printf ("%x mw\r", section_base); - for (i = 0; i < section_size; i += 4) - { - monitor_expect (" -> ", NULL, 0); - bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); - monitor_printf ("%x\n", buffer); - } - monitor_expect (" -> ", NULL, 0); - monitor_printf ("q\n"); - monitor_expect_prompt (NULL, 0); - } -#else - if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL))) - { - monitor_printf ("q\n"); - return; - } -#endif - end_time = time (NULL); - printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); - report_transfer_performance (data_count, start_time, end_time); - - /* Finally, make the PC point at the start address */ - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - inferior_ptid = null_ptid; /* No process now */ - - /* This is necessary because many things were based on the PC at the - time that we attached to the monitor, which is no longer valid - now that we have loaded new code (and just changed the PC). - Another way to do this might be to call normal_stop, except that - the stack may not be valid, and things would get horribly - confused... */ - - clear_symtab_users (); -} - -static void -m32r_load_gen (char *filename, int from_tty) -{ - generic_load (filename, from_tty); -} - -static void m32r_open (char *args, int from_tty); -static void mon2000_open (char *args, int from_tty); - -/* This array of registers needs to match the indexes used by GDB. The - whole reason this exists is because the various ROM monitors use - different names than GDB does, and don't support all the registers - either. So, typing "info reg sp" becomes an "A7". */ - -static char *m32r_regnames[] = -{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch", -}; - -static void -m32r_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - int regno; - int num_regs = sizeof (m32r_regnames) / sizeof (m32r_regnames[0]); - - for (regno = 0; regno < num_regs; regno++) - if (strncmp (regname, m32r_regnames[regno], regnamelen) == 0) - break; - - if (regno >= num_regs) - return; /* no match */ - - if (regno == ACCL_REGNUM) - { /* special handling for 64-bit acc reg */ - monitor_supply_register (ACCH_REGNUM, val); - val = strchr (val, ':'); /* skip past ':' to get 2nd word */ - if (val != NULL) - monitor_supply_register (ACCL_REGNUM, val + 1); - } - else - { - monitor_supply_register (regno, val); - if (regno == PSW_REGNUM) - { - unsigned long psw = strtoul (val, NULL, 16); - char *zero = "00000000", *one = "00000001"; - -#ifdef SM_REGNUM - /* Stack mode bit */ - monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero); -#endif -#ifdef BSM_REGNUM - /* Backup stack mode bit */ - monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero); -#endif -#ifdef IE_REGNUM - /* Interrupt enable bit */ - monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero); -#endif -#ifdef BIE_REGNUM - /* Backup interrupt enable bit */ - monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero); -#endif -#ifdef COND_REGNUM - /* Condition bit (carry etc.) */ - monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero); -#endif -#ifdef CBR_REGNUM - monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero); -#endif -#ifdef BPC_REGNUM - monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */ -#endif -#ifdef BCARRY_REGNUM - monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */ -#endif - } - - if (regno == SPI_REGNUM || regno == SPU_REGNUM) - { /* special handling for stack pointer (spu or spi) */ - unsigned long stackmode = read_register (PSW_REGNUM) & 0x80; - - if (regno == SPI_REGNUM && !stackmode) /* SP == SPI */ - monitor_supply_register (SP_REGNUM, val); - else if (regno == SPU_REGNUM && stackmode) /* SP == SPU */ - monitor_supply_register (SP_REGNUM, val); - } - } -} - -/* m32r RevC board monitor */ - -static struct target_ops m32r_ops; - -static char *m32r_inits[] = -{"\r", NULL}; - -static struct monitor_ops m32r_cmds; - -static void -init_m32r_cmds (void) -{ - m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; - m32r_cmds.init = m32r_inits; /* Init strings */ - m32r_cmds.cont = "go\r"; /* continue command */ - m32r_cmds.step = "step\r"; /* single step */ - m32r_cmds.stop = NULL; /* interrupt command */ - m32r_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ - m32r_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ - m32r_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ - m32r_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ - m32r_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ - m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */ - m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */ - m32r_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - m32r_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - m32r_cmds.setmem.term = NULL; /* setmem.term */ - m32r_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ - m32r_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ - m32r_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ - m32r_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ - m32r_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - m32r_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - m32r_cmds.getmem.term = NULL; /* getmem.term */ - m32r_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - m32r_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ - m32r_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - m32r_cmds.setreg.term = NULL; /* setreg.term */ - m32r_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - m32r_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ - m32r_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ - m32r_cmds.getreg.term = NULL; /* getreg.term */ - m32r_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - m32r_cmds.dump_registers = ".reg\r"; /* dump_registers */ - m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - m32r_cmds.supply_register = m32r_supply_register; /* supply_register */ - m32r_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - m32r_cmds.load = NULL; /* download command */ - m32r_cmds.loadresp = NULL; /* load response */ - m32r_cmds.prompt = "ok "; /* monitor command prompt */ - m32r_cmds.line_term = "\r"; /* end-of-line terminator */ - m32r_cmds.cmd_end = NULL; /* optional command terminator */ - m32r_cmds.target = &m32r_ops; /* target operations */ - m32r_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - m32r_cmds.regnames = m32r_regnames; /* registers names */ - m32r_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -} /* init_m32r_cmds */ - -static void -m32r_open (char *args, int from_tty) -{ - monitor_open (args, &m32r_cmds, from_tty); -} - -/* Mon2000 monitor (MSA2000 board) */ - -static struct target_ops mon2000_ops; -static struct monitor_ops mon2000_cmds; - -static void -init_mon2000_cmds (void) -{ - mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; - mon2000_cmds.init = m32r_inits; /* Init strings */ - mon2000_cmds.cont = "go\r"; /* continue command */ - mon2000_cmds.step = "step\r"; /* single step */ - mon2000_cmds.stop = NULL; /* interrupt command */ - mon2000_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ - mon2000_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ - mon2000_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ - mon2000_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ - mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ - mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */ - mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */ - mon2000_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - mon2000_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - mon2000_cmds.setmem.term = NULL; /* setmem.term */ - mon2000_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ - mon2000_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ - mon2000_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ - mon2000_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ - mon2000_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - mon2000_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - mon2000_cmds.getmem.term = NULL; /* getmem.term */ - mon2000_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - mon2000_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ - mon2000_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - mon2000_cmds.setreg.term = NULL; /* setreg.term */ - mon2000_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - mon2000_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ - mon2000_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ - mon2000_cmds.getreg.term = NULL; /* getreg.term */ - mon2000_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - mon2000_cmds.dump_registers = ".reg\r"; /* dump_registers */ - mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - mon2000_cmds.supply_register = m32r_supply_register; /* supply_register */ - mon2000_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - mon2000_cmds.load = NULL; /* download command */ - mon2000_cmds.loadresp = NULL; /* load response */ - mon2000_cmds.prompt = "Mon2000>"; /* monitor command prompt */ - mon2000_cmds.line_term = "\r"; /* end-of-line terminator */ - mon2000_cmds.cmd_end = NULL; /* optional command terminator */ - mon2000_cmds.target = &mon2000_ops; /* target operations */ - mon2000_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - mon2000_cmds.regnames = m32r_regnames; /* registers names */ - mon2000_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -} /* init_mon2000_cmds */ - -static void -mon2000_open (char *args, int from_tty) -{ - monitor_open (args, &mon2000_cmds, from_tty); -} - -/* Function: set_board_address - Tell the BootOne monitor what it's ethernet IP address is. */ - -static void -m32r_set_board_address (char *args, int from_tty) -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("ulip %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (IP address for M32R-EVA board)"); -} - -/* Function: set_server_address - Tell the BootOne monitor what gdb's ethernet IP address is. */ - -static void -m32r_set_server_address (char *args, int from_tty) -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("uhip %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (IP address of GDB's host computer)"); -} - -/* Function: set_download_path - Tell the BootOne monitor the default path for downloadable SREC files. */ - -static void -m32r_set_download_path (char *args, int from_tty) -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("up %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (default path for downloadable SREC files)"); -} - -static void -m32r_upload_command (char *args, int from_tty) -{ - bfd *abfd; - asection *s; - time_t start_time, end_time; /* for timing of download */ - int resp_len, data_count = 0; - char buf[1024]; - struct hostent *hostent; - struct in_addr inet_addr; - - /* first check to see if there's an ethernet port! */ - monitor_printf ("ust\r"); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - if (!strchr (buf, ':')) - error ("No ethernet connection!"); - - if (board_addr == 0) - { - /* scan second colon in the output from the "ust" command */ - char *myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1; - - while (isspace (*myIPaddress)) - myIPaddress++; - - if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */ - error ("Please use 'set board-address' to set the M32R-EVA board's IP address."); - if (strchr (myIPaddress, '(')) - *(strchr (myIPaddress, '(')) = '\0'; /* delete trailing junk */ - board_addr = xstrdup (myIPaddress); - } - if (server_addr == 0) - { - buf[0] = 0; - gethostname (buf, sizeof (buf)); - if (buf[0] != 0) - hostent = gethostbyname (buf); - if (hostent != 0) - { -#if 1 - memcpy (&inet_addr.s_addr, hostent->h_addr, - sizeof (inet_addr.s_addr)); - server_addr = (char *) inet_ntoa (inet_addr); -#else - server_addr = (char *) inet_ntoa (hostent->h_addr); -#endif - } - if (server_addr == 0) /* failed? */ - error ("Need to know gdb host computer's IP address (use 'set server-address')"); - } - - if (args == 0 || args[0] == 0) /* no args: upload the current file */ - args = get_exec_file (1); - - if (args[0] != '/' && download_path == 0) - { - if (current_directory) - download_path = xstrdup (current_directory); - else - error ("Need to know default download path (use 'set download-path')"); - } - - start_time = time (NULL); - monitor_printf ("uhip %s\r", server_addr); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - monitor_printf ("ulip %s\r", board_addr); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - if (args[0] != '/') - monitor_printf ("up %s\r", download_path); /* use default path */ - else - monitor_printf ("up\r"); /* rooted filename/path */ - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - - if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec")) - monitor_printf ("ul %s\r", args); - else /* add ".srec" suffix */ - monitor_printf ("ul %s.srec\r", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - - if (buf[0] == 0 || strstr (buf, "complete") == 0) - error ("Upload file not found: %s.srec\nCheck IP addresses and download path.", args); - else - printf_filtered (" -- Ethernet load complete.\n"); - - end_time = time (NULL); - abfd = bfd_openr (args, 0); - if (abfd != NULL) - { /* Download is done -- print section statistics */ - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - } - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_lma (abfd, s); - unsigned int buffer; - - data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx lma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - } - /* Finally, make the PC point at the start address */ - write_pc (bfd_get_start_address (abfd)); - report_transfer_performance (data_count, start_time, end_time); - printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); - } - inferior_ptid = null_ptid; /* No process now */ - - /* This is necessary because many things were based on the PC at the - time that we attached to the monitor, which is no longer valid - now that we have loaded new code (and just changed the PC). - Another way to do this might be to call normal_stop, except that - the stack may not be valid, and things would get horribly - confused... */ - - clear_symtab_users (); -} - -void -_initialize_m32r_rom (void) -{ - /* Initialize m32r RevC monitor target */ - init_m32r_cmds (); - init_monitor_ops (&m32r_ops); - - m32r_ops.to_shortname = "m32r"; - m32r_ops.to_longname = "m32r monitor"; - m32r_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ - m32r_ops.to_doc = "Debug via the m32r monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - m32r_ops.to_open = m32r_open; - add_target (&m32r_ops); - - /* Initialize mon2000 monitor target */ - init_mon2000_cmds (); - init_monitor_ops (&mon2000_ops); - - mon2000_ops.to_shortname = "mon2000"; - mon2000_ops.to_longname = "Mon2000 monitor"; - mon2000_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ - mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - mon2000_ops.to_open = mon2000_open; - add_target (&mon2000_ops); - - add_show_from_set - (add_set_cmd ("download-path", class_obscure, var_string, - (char *) &download_path, - "Set the default path for downloadable SREC files.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("board-address", class_obscure, var_string, - (char *) &board_addr, - "Set IP address for M32R-EVA target board.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("server-address", class_obscure, var_string, - (char *) &server_addr, - "Set IP address for download server (GDB's host computer).", - &setlist), - &showlist); - - add_com ("upload", class_obscure, m32r_upload_command, - "Upload the srec file via the monitor's Ethernet upload capability."); - - add_com ("tload", class_obscure, m32r_load, "test upload command."); -} diff --git a/contrib/gdb/gdb/m32r-stub.c b/contrib/gdb/gdb/m32r-stub.c deleted file mode 100644 index cb956264d67..00000000000 --- a/contrib/gdb/gdb/m32r-stub.c +++ /dev/null @@ -1,1711 +0,0 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for M32R by Michael Snyder, Cygnus Support. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific M32R vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses it's own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN - * AA..AA - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - - -/************************************************************************ - * - * external low-level support routines - */ -extern void putDebugChar(); /* write a single character */ -extern int getDebugChar(); /* read and return a single char */ -extern void exceptionHandler(); /* assign an exception handler */ - -/***************************************************************************** - * BUFMAX defines the maximum number of characters in inbound/outbound buffers - * at least NUMREGBYTES*2 are needed for register packets - */ -#define BUFMAX 400 - -static char initialized; /* boolean flag. != 0 means we've been initialized */ - -int remote_debug; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ - -static const unsigned char hexchars[]="0123456789abcdef"; - -#define NUMREGS 24 - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) -enum regnames { R0, R1, R2, R3, R4, R5, R6, R7, - R8, R9, R10, R11, R12, R13, R14, R15, - PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH }; - -enum SYS_calls { - SYS_null, - SYS_exit, - SYS_open, - SYS_close, - SYS_read, - SYS_write, - SYS_lseek, - SYS_unlink, - SYS_getpid, - SYS_kill, - SYS_fstat, - SYS_sbrk, - SYS_fork, - SYS_execve, - SYS_wait4, - SYS_link, - SYS_chdir, - SYS_stat, - SYS_utime, - SYS_chown, - SYS_chmod, - SYS_time, - SYS_pipe }; - -static int registers[NUMREGS]; - -#define STACKSIZE 8096 -static unsigned char remcomInBuffer[BUFMAX]; -static unsigned char remcomOutBuffer[BUFMAX]; -static int remcomStack[STACKSIZE/sizeof(int)]; -static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - -static unsigned int save_vectors[18]; /* previous exception vectors */ - -/* Indicate to caller of mem2hex or hex2mem that there has been an error. */ -static volatile int mem_err = 0; - -/* Store the vector number here (since GDB only gets the signal - number through the usual means, and that's not very specific). */ -int gdb_m32r_vector = -1; - -#if 0 -#include "syscall.h" /* for SYS_exit, SYS_write etc. */ -#endif - -/* Global entry points: - */ - -extern void handle_exception(int); -extern void set_debug_traps(void); -extern void breakpoint(void); - -/* Local functions: - */ - -static int computeSignal(int); -static void putpacket(unsigned char *); -static unsigned char *getpacket(void); - -static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int); -static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int); -static int hexToInt(unsigned char **, int *); -static unsigned char *bin2mem(unsigned char *, unsigned char *, int, int); -static void stash_registers(void); -static void restore_registers(void); -static int prepare_to_step(int); -static int finish_from_step(void); -static unsigned long crc32 (unsigned char *, int, unsigned long); - -static void gdb_error(char *, char *); -static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int); - -static unsigned char *strcpy (unsigned char *, const unsigned char *); -static int strlen (const unsigned char *); - -/* - * This function does all command procesing for interfacing to gdb. - */ - -void -handle_exception(int exceptionVector) -{ - int sigval, stepping; - int addr, length, i; - unsigned char * ptr; - unsigned char buf[16]; - int binary; - - if (!finish_from_step()) - return; /* "false step": let the target continue */ - - gdb_m32r_vector = exceptionVector; - - if (remote_debug) - { - mem2hex((unsigned char *) &exceptionVector, buf, 4, 0); - gdb_error("Handle exception %s, ", buf); - mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); - gdb_error("PC == 0x%s\n", buf); - } - - /* reply to host that an exception has occurred */ - sigval = computeSignal( exceptionVector ); - - ptr = remcomOutBuffer; - - *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); /* PC */ - *ptr++ = ';'; - - *ptr++ = hexchars[R13 >> 4]; - *ptr++ = hexchars[R13 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); /* FP */ - *ptr++ = ';'; - - *ptr++ = hexchars[R15 >> 4]; - *ptr++ = hexchars[R15 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); /* SP */ - *ptr++ = ';'; - *ptr++ = 0; - - if (exceptionVector == 0) /* simulated SYS call stuff */ - { - mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); - switch (registers[R0]) { - case SYS_exit: - gdb_error("Target program has exited at %s\n", buf); - ptr = remcomOutBuffer; - *ptr++ = 'W'; - sigval = registers[R1] & 0xff; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - *ptr++ = 0; - break; - case SYS_open: - gdb_error("Target attempts SYS_open call at %s\n", buf); - break; - case SYS_close: - gdb_error("Target attempts SYS_close call at %s\n", buf); - break; - case SYS_read: - gdb_error("Target attempts SYS_read call at %s\n", buf); - break; - case SYS_write: - if (registers[R1] == 1 || /* write to stdout */ - registers[R1] == 2) /* write to stderr */ - { /* (we can do that) */ - registers[R0] = gdb_write((void *) registers[R2], registers[R3]); - return; - } - else - gdb_error("Target attempts SYS_write call at %s\n", buf); - break; - case SYS_lseek: - gdb_error("Target attempts SYS_lseek call at %s\n", buf); - break; - case SYS_unlink: - gdb_error("Target attempts SYS_unlink call at %s\n", buf); - break; - case SYS_getpid: - gdb_error("Target attempts SYS_getpid call at %s\n", buf); - break; - case SYS_kill: - gdb_error("Target attempts SYS_kill call at %s\n", buf); - break; - case SYS_fstat: - gdb_error("Target attempts SYS_fstat call at %s\n", buf); - break; - default: - gdb_error("Target attempts unknown SYS call at %s\n", buf); - break; - } - } - - putpacket(remcomOutBuffer); - - stepping = 0; - - while (1==1) { - remcomOutBuffer[0] = 0; - ptr = getpacket(); - binary = 0; - switch (*ptr++) { - default: /* Unknown code. Return an empty reply message. */ - break; - case 'R': - if (hexToInt (&ptr, &addr)) - registers[PC] = addr; - strcpy(remcomOutBuffer, "OK"); - break; - case '!': - strcpy(remcomOutBuffer, "OK"); - break; - case 'X': /* XAA..AA,LLLL:#cs */ - binary = 1; - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - { - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - if (*(ptr++) == ':') - { - mem_err = 0; - if (binary) - bin2mem (ptr, (unsigned char *) addr, length, 1); - else - hex2mem(ptr, (unsigned char*) addr, length, 1); - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - gdb_error ("memory fault", ""); - } else { - strcpy(remcomOutBuffer,"OK"); - } - ptr = 0; - } - if (ptr) - { - strcpy(remcomOutBuffer,"E02"); - } - } - break; - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - { - ptr = 0; - mem_err = 0; - mem2hex((unsigned char*) addr, remcomOutBuffer, length, 1); - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - gdb_error ("memory fault", ""); - } - } - if (ptr) - { - strcpy(remcomOutBuffer,"E01"); - } - break; - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - case 'd': - remote_debug = !(remote_debug); /* toggle debug flag */ - break; - case 'g': /* return the value of the CPU registers */ - mem2hex((unsigned char*) registers, remcomOutBuffer, NUMREGBYTES, 0); - break; - case 'P': /* set the value of a single CPU register - return OK */ - { - int regno; - - if (hexToInt (&ptr, ®no) && *ptr++ == '=') - if (regno >= 0 && regno < NUMREGS) - { - int stackmode; - - hex2mem (ptr, (unsigned char *) ®isters[regno], 4, 0); - /* - * Since we just changed a single CPU register, let's - * make sure to keep the several stack pointers consistant. - */ - stackmode = registers[PSW] & 0x80; - if (regno == R15) /* stack pointer changed */ - { /* need to change SPI or SPU */ - if (stackmode == 0) - registers[SPI] = registers[R15]; - else - registers[SPU] = registers[R15]; - } - else if (regno == SPU) /* "user" stack pointer changed */ - { - if (stackmode != 0) /* stack in user mode: copy SP */ - registers[R15] = registers[SPU]; - } - else if (regno == SPI) /* "interrupt" stack pointer changed */ - { - if (stackmode == 0) /* stack in interrupt mode: copy SP */ - registers[R15] = registers[SPI]; - } - else if (regno == PSW) /* stack mode may have changed! */ - { /* force SP to either SPU or SPI */ - if (stackmode == 0) /* stack in user mode */ - registers[R15] = registers[SPI]; - else /* stack in interrupt mode */ - registers[R15] = registers[SPU]; - } - strcpy (remcomOutBuffer, "OK"); - break; - } - strcpy (remcomOutBuffer, "E01"); - break; - } - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem(ptr, (unsigned char*) registers, NUMREGBYTES, 0); - strcpy(remcomOutBuffer,"OK"); - break; - case 's': /* sAA..AA Step one instruction from AA..AA(optional) */ - stepping = 1; - case 'c': /* cAA..AA Continue from address AA..AA(optional) */ - /* try to read optional parameter, pc unchanged if no parm */ - if (hexToInt(&ptr,&addr)) - registers[ PC ] = addr; - - if (stepping) /* single-stepping */ - { - if (!prepare_to_step(0)) /* set up for single-step */ - { - /* prepare_to_step has already emulated the target insn: - Send SIGTRAP to gdb, don't resume the target at all. */ - ptr = remcomOutBuffer; - *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */ - *ptr++ = '0'; - *ptr++ = '5'; - - *ptr++ = hexchars[PC >> 4]; /* send PC */ - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[R13 >> 4]; /* send FP */ - *ptr++ = hexchars[R13 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[R15 >> 4]; /* send SP */ - *ptr++ = hexchars[R15 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); - *ptr++ = ';'; - *ptr++ = 0; - - break; - } - } - else /* continuing, not single-stepping */ - { - /* OK, about to do a "continue". First check to see if the - target pc is on an odd boundary (second instruction in the - word). If so, we must do a single-step first, because - ya can't jump or return back to an odd boundary! */ - if ((registers[PC] & 2) != 0) - prepare_to_step(1); - } - - return; - - case 'D': /* Detach */ -#if 0 - /* I am interpreting this to mean, release the board from control - by the remote stub. To do this, I am restoring the original - (or at least previous) exception vectors. - */ - for (i = 0; i < 18; i++) - exceptionHandler (i, save_vectors[i]); - putpacket ("OK"); - return; /* continue the inferior */ -#else - strcpy(remcomOutBuffer,"OK"); - break; -#endif - case 'q': - if (*ptr++ == 'C' && - *ptr++ == 'R' && - *ptr++ == 'C' && - *ptr++ == ':') - { - unsigned long start, len, our_crc; - - if (hexToInt (&ptr, (int *) &start) && - *ptr++ == ',' && - hexToInt (&ptr, (int *) &len)) - { - remcomOutBuffer[0] = 'C'; - our_crc = crc32 ((unsigned char *) start, len, 0xffffffff); - mem2hex ((char *) &our_crc, - &remcomOutBuffer[1], - sizeof (long), - 0); - } /* else do nothing */ - } /* else do nothing */ - break; - - case 'k': /* kill the program */ - continue; - } /* switch */ - - /* reply to the request */ - putpacket(remcomOutBuffer); - } -} - -/* qCRC support */ - -/* Table used by the crc32 function to calcuate the checksum. */ -static unsigned long crc32_table[256] = {0, 0}; - -static unsigned long -crc32 (unsigned char *buf, int len, unsigned long crc) -{ - if (! crc32_table[1]) - { - /* Initialize the CRC table and the decoding table. */ - int i, j; - unsigned long c; - - for (i = 0; i < 256; i++) - { - for (c = i << 24, j = 8; j > 0; --j) - c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1); - crc32_table[i] = c; - } - } - - while (len--) - { - crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255]; - buf++; - } - return crc; -} - -static int -hex (unsigned char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); - return (-1); -} - -/* scan for the sequence $# */ - -unsigned char * -getpacket (void) -{ - unsigned char *buffer = &remcomInBuffer[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - char ch; - - while (1) - { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - -retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) - { - ch = getDebugChar (); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - { - if (remote_debug) - { - unsigned char buf[16]; - - mem2hex((unsigned char *) &checksum, buf, 4, 0); - gdb_error("Bad checksum: my count = %s, ", buf); - mem2hex((unsigned char *) &xmitcsum, buf, 4, 0); - gdb_error("sent count = %s\n", buf); - gdb_error(" -- Bad buffer: \"%s\"\n", buffer); - } - putDebugChar ('-'); /* failed checksum */ - } - else - { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } - } - } -} - -/* send the packet in buffer. */ - -static void -putpacket (unsigned char *buffer) -{ - unsigned char checksum; - int count; - char ch; - - /* $#. */ - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while (ch=buffer[count]) { - putDebugChar(ch); - checksum += ch; - count += 1; - } - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum % 16]); - } while (getDebugChar() != '+'); -} - -/* Address of a routine to RTE to if we get a memory fault. */ - -static void (*volatile mem_fault_routine)() = 0; - -static void -set_mem_err (void) -{ - mem_err = 1; -} - -/* Check the address for safe access ranges. As currently defined, - this routine will reject the "expansion bus" address range(s). - To make those ranges useable, someone must implement code to detect - whether there's anything connected to the expansion bus. */ - -static int -mem_safe (unsigned char *addr) -{ -#define BAD_RANGE_ONE_START ((unsigned char *) 0x600000) -#define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000) -#define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000) -#define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000) - - if (addr < BAD_RANGE_ONE_START) return 1; /* safe */ - if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */ - if (addr < BAD_RANGE_TWO_START) return 1; /* safe */ - if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */ -} - -/* These are separate functions so that they are so short and sweet - that the compiler won't save any registers (if there is a fault - to mem_fault, they won't get restored, so there better not be any - saved). */ -static int -get_char (unsigned char *addr) -{ -#if 1 - if (mem_fault_routine && !mem_safe(addr)) - { - mem_fault_routine (); - return 0; - } -#endif - return *addr; -} - -static void -set_char (unsigned char *addr, unsigned char val) -{ -#if 1 - if (mem_fault_routine && !mem_safe (addr)) - { - mem_fault_routine (); - return; - } -#endif - *addr = val; -} - -/* Convert the memory pointed to by mem into hex, placing result in buf. - Return a pointer to the last char put in buf (null). - If MAY_FAULT is non-zero, then we should set mem_err in response to - a fault; if zero treat a fault like any other fault in the stub. */ - -static unsigned char * -mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - if (may_fault) - mem_fault_routine = 0; - return(buf); -} - -/* Convert the hex array pointed to by buf into binary to be placed in mem. - Return a pointer to the character AFTER the last byte written. */ - -static unsigned char* -hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - (*ptr)++; - } - return (numChars); -} - -/* - Table of branch instructions: - - 10B6 RTE return from trap or exception - 1FCr JMP jump - 1ECr JL jump and link - 7Fxx BRA branch - FFxxxxxx BRA branch (long) - B09rxxxx BNEZ branch not-equal-zero - Br1rxxxx BNE branch not-equal - 7Dxx BNC branch not-condition - FDxxxxxx BNC branch not-condition (long) - B0Arxxxx BLTZ branch less-than-zero - B0Crxxxx BLEZ branch less-equal-zero - 7Exx BL branch and link - FExxxxxx BL branch and link (long) - B0Drxxxx BGTZ branch greater-than-zero - B0Brxxxx BGEZ branch greater-equal-zero - B08rxxxx BEQZ branch equal-zero - Br0rxxxx BEQ branch equal - 7Cxx BC branch condition - FCxxxxxx BC branch condition (long) - */ - -static int -isShortBranch (unsigned char *instr) -{ - unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */ - - if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */ - return 1; /* return from trap or exception */ - - if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */ - if ((instr[1] & 0xF0) == 0xC0) - return 2; /* jump thru a register */ - - if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */ - instr0 == 0x7E || instr0 == 0x7F) - return 3; /* eight bit PC offset */ - - return 0; -} - -static int -isLongBranch (unsigned char *instr) -{ - if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */ - instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */ - return 4; - if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */ - { - if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */ - (instr[1] & 0xF0) == 0x10) - return 5; - if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */ - if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 || - (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 || - (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0) - return 6; - } - return 0; -} - -/* if address is NOT on a 4-byte boundary, or high-bit of instr is zero, - then it's a 2-byte instruction, else it's a 4-byte instruction. */ - -#define INSTRUCTION_SIZE(addr) \ - ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4) - -static int -isBranch (unsigned char *instr) -{ - if (INSTRUCTION_SIZE(instr) == 2) - return isShortBranch(instr); - else - return isLongBranch(instr); -} - -static int -willBranch (unsigned char *instr, int branchCode) -{ - switch (branchCode) - { - case 0: return 0; /* not a branch */ - case 1: return 1; /* RTE */ - case 2: return 1; /* JL or JMP */ - case 3: /* BC, BNC, BL, BRA (short) */ - case 4: /* BC, BNC, BL, BRA (long) */ - switch (instr[0] & 0x0F) - { - case 0xC: /* Branch if Condition Register */ - return (registers[CBR] != 0); - case 0xD: /* Branch if NOT Condition Register */ - return (registers[CBR] == 0); - case 0xE: /* Branch and Link */ - case 0xF: /* Branch (unconditional) */ - return 1; - default: /* oops? */ - return 0; - } - case 5: /* BNE, BEQ */ - switch (instr[1] & 0xF0) - { - case 0x00: /* Branch if r1 equal to r2 */ - return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]); - case 0x10: /* Branch if r1 NOT equal to r2 */ - return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]); - default: /* oops? */ - return 0; - } - case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */ - switch (instr[1] & 0xF0) - { - case 0x80: /* Branch if reg equal to zero */ - return (registers[instr[1] & 0x0F] == 0); - case 0x90: /* Branch if reg NOT equal to zero */ - return (registers[instr[1] & 0x0F] != 0); - case 0xA0: /* Branch if reg less than zero */ - return (registers[instr[1] & 0x0F] < 0); - case 0xB0: /* Branch if reg greater or equal to zero */ - return (registers[instr[1] & 0x0F] >= 0); - case 0xC0: /* Branch if reg less than or equal to zero */ - return (registers[instr[1] & 0x0F] <= 0); - case 0xD0: /* Branch if reg greater than zero */ - return (registers[instr[1] & 0x0F] > 0); - default: /* oops? */ - return 0; - } - default: /* oops? */ - return 0; - } -} - -static int -branchDestination (unsigned char *instr, int branchCode) -{ - switch (branchCode) { - default: - case 0: /* not a branch */ - return 0; - case 1: /* RTE */ - return registers[BPC] & ~3; /* pop BPC into PC */ - case 2: /* JL or JMP */ - return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */ - case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */ - return (((int) instr) & ~3) + ((char) instr[1] << 2); - case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */ - return ((int) instr + - ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2)); - case 5: /* BNE, BEQ (16-bit relative offset) */ - case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */ - return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2)); - } - - /* An explanatory note: in the last three return expressions, I have - cast the most-significant byte of the return offset to char. - What this accomplishes is sign extension. If the other - less-significant bytes were signed as well, they would get sign - extended too and, if negative, their leading bits would clobber - the bits of the more-significant bytes ahead of them. There are - other ways I could have done this, but sign extension from - odd-sized integers is always a pain. */ -} - -static void -branchSideEffects (unsigned char *instr, int branchCode) -{ - switch (branchCode) - { - case 1: /* RTE */ - return; /* I this is already handled... */ - case 2: /* JL (or JMP) */ - case 3: /* BL (or BC, BNC, BRA) */ - case 4: - if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */ - registers[R14] = (registers[PC] & ~3) + 4; - return; - default: /* any other branch has no side effects */ - return; - } -} - -static struct STEPPING_CONTEXT { - int stepping; /* true when we've started a single-step */ - unsigned long target_addr; /* the instr we're trying to execute */ - unsigned long target_size; /* the size of the target instr */ - unsigned long noop_addr; /* where we've inserted a no-op, if any */ - unsigned long trap1_addr; /* the trap following the target instr */ - unsigned long trap2_addr; /* the trap at a branch destination, if any */ - unsigned short noop_save; /* instruction overwritten by our no-op */ - unsigned short trap1_save; /* instruction overwritten by trap1 */ - unsigned short trap2_save; /* instruction overwritten by trap2 */ - unsigned short continue_p; /* true if NOT returning to gdb after step */ -} stepping; - -/* Function: prepare_to_step - Called from handle_exception to prepare the user program to single-step. - Places a trap instruction after the target instruction, with special - extra handling for branch instructions and for instructions in the - second half-word of a word. - - Returns: True if we should actually execute the instruction; - False if we are going to emulate executing the instruction, - in which case we simply report to GDB that the instruction - has already been executed. */ - -#define TRAP1 0x10f1; /* trap #1 instruction */ -#define NOOP 0x7000; /* noop instruction */ - -static unsigned short trap1 = TRAP1; -static unsigned short noop = NOOP; - -static int -prepare_to_step(continue_p) - int continue_p; /* if this isn't REALLY a single-step (see below) */ -{ - unsigned long pc = registers[PC]; - int branchCode = isBranch((unsigned char *) pc); - unsigned char *p; - - /* zero out the stepping context - (paranoia -- it should already be zeroed) */ - for (p = (unsigned char *) &stepping; - p < ((unsigned char *) &stepping) + sizeof(stepping); - p++) - *p = 0; - - if (branchCode != 0) /* next instruction is a branch */ - { - branchSideEffects((unsigned char *) pc, branchCode); - if (willBranch((unsigned char *)pc, branchCode)) - registers[PC] = branchDestination((unsigned char *) pc, branchCode); - else - registers[PC] = pc + INSTRUCTION_SIZE(pc); - return 0; /* branch "executed" -- just notify GDB */ - } - else if (((int) pc & 2) != 0) /* "second-slot" instruction */ - { - /* insert no-op before pc */ - stepping.noop_addr = pc - 2; - stepping.noop_save = *(unsigned short *) stepping.noop_addr; - *(unsigned short *) stepping.noop_addr = noop; - /* insert trap after pc */ - stepping.trap1_addr = pc + 2; - stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; - *(unsigned short *) stepping.trap1_addr = trap1; - } - else /* "first-slot" instruction */ - { - /* insert trap after pc */ - stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc); - stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; - *(unsigned short *) stepping.trap1_addr = trap1; - } - /* "continue_p" means that we are actually doing a continue, and not - being requested to single-step by GDB. Sometimes we have to do - one single-step before continuing, because the PC is on a half-word - boundary. There's no way to simply resume at such an address. */ - stepping.continue_p = continue_p; - stepping.stepping = 1; /* starting a single-step */ - return 1; -} - -/* Function: finish_from_step - Called from handle_exception to finish up when the user program - returns from a single-step. Replaces the instructions that had - been overwritten by traps or no-ops, - - Returns: True if we should notify GDB that the target stopped. - False if we only single-stepped because we had to before we - could continue (ie. we were trying to continue at a - half-word boundary). In that case don't notify GDB: - just "continue continuing". */ - -static int -finish_from_step (void) -{ - if (stepping.stepping) /* anything to do? */ - { - int continue_p = stepping.continue_p; - unsigned char *p; - - if (stepping.noop_addr) /* replace instr "under" our no-op */ - *(unsigned short *) stepping.noop_addr = stepping.noop_save; - if (stepping.trap1_addr) /* replace instr "under" our trap */ - *(unsigned short *) stepping.trap1_addr = stepping.trap1_save; - if (stepping.trap2_addr) /* ditto our other trap, if any */ - *(unsigned short *) stepping.trap2_addr = stepping.trap2_save; - - for (p = (unsigned char *) &stepping; /* zero out the stepping context */ - p < ((unsigned char *) &stepping) + sizeof(stepping); - p++) - *p = 0; - - return !(continue_p); - } - else /* we didn't single-step, therefore this must be a legitimate stop */ - return 1; -} - -struct PSWreg { /* separate out the bit flags in the PSW register */ - int pad1 : 16; - int bsm : 1; - int bie : 1; - int pad2 : 5; - int bc : 1; - int sm : 1; - int ie : 1; - int pad3 : 5; - int c : 1; -} *psw; - -/* Upon entry the value for LR to save has been pushed. - We unpush that so that the value for the stack pointer saved is correct. - Upon entry, all other registers are assumed to have not been modified - since the interrupt/trap occured. */ - -asm (" -stash_registers: - push r0 - push r1 - seth r1, #shigh(registers) - add3 r1, r1, #low(registers) - pop r0 ; r1 - st r0, @(4,r1) - pop r0 ; r0 - st r0, @r1 - addi r1, #4 ; only add 4 as subsequent saves are `pre inc' - st r2, @+r1 - st r3, @+r1 - st r4, @+r1 - st r5, @+r1 - st r6, @+r1 - st r7, @+r1 - st r8, @+r1 - st r9, @+r1 - st r10, @+r1 - st r11, @+r1 - st r12, @+r1 - st r13, @+r1 ; fp - pop r0 ; lr (r14) - st r0, @+r1 - st sp, @+r1 ; sp contains right value at this point - mvfc r0, cr0 - st r0, @+r1 ; cr0 == PSW - mvfc r0, cr1 - st r0, @+r1 ; cr1 == CBR - mvfc r0, cr2 - st r0, @+r1 ; cr2 == SPI - mvfc r0, cr3 - st r0, @+r1 ; cr3 == SPU - mvfc r0, cr6 - st r0, @+r1 ; cr6 == BPC - st r0, @+r1 ; PC == BPC - mvfaclo r0 - st r0, @+r1 ; ACCL - mvfachi r0 - st r0, @+r1 ; ACCH - jmp lr"); - -/* C routine to clean up what stash_registers did. - It is called after calling stash_registers. - This is separate from stash_registers as we want to do this in C - but doing stash_registers in C isn't straightforward. */ - -static void -cleanup_stash (void) -{ - psw = (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */ - psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */ - psw->ie = psw->bie; - psw->c = psw->bc; - registers[CBR] = psw->bc; /* fix up pre-trap "C" register */ - -#if 0 /* FIXME: Was in previous version. Necessary? - (Remember that we use the "rte" insn to return from the - trap/interrupt so the values of bsm, bie, bc are important. */ - psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */ -#endif - - /* FIXME: Copied from previous version. This can probably be deleted - since methinks stash_registers has already done this. */ - registers[PC] = registers[BPC]; /* pre-trap PC */ - - /* FIXME: Copied from previous version. Necessary? */ - if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */ - registers[SPU] = registers[R15]; - else - registers[SPI] = registers[R15]; -} - -asm (" -restore_and_return: - seth r0, #shigh(registers+8) - add3 r0, r0, #low(registers+8) - ld r2, @r0+ ; restore r2 - ld r3, @r0+ ; restore r3 - ld r4, @r0+ ; restore r4 - ld r5, @r0+ ; restore r5 - ld r6, @r0+ ; restore r6 - ld r7, @r0+ ; restore r7 - ld r8, @r0+ ; restore r8 - ld r9, @r0+ ; restore r9 - ld r10, @r0+ ; restore r10 - ld r11, @r0+ ; restore r11 - ld r12, @r0+ ; restore r12 - ld r13, @r0+ ; restore r13 - ld r14, @r0+ ; restore r14 - ld r15, @r0+ ; restore r15 - ld r1, @r0+ ; restore cr0 == PSW - mvtc r1, cr0 - ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only) - mvtc r1, cr1 - ld r1, @r0+ ; restore cr2 == SPI - mvtc r1, cr2 - ld r1, @r0+ ; restore cr3 == SPU - mvtc r1, cr3 - addi r0, #4 ; skip BPC - ld r1, @r0+ ; restore cr6 (BPC) == PC - mvtc r1, cr6 - ld r1, @r0+ ; restore ACCL - mvtaclo r1 - ld r1, @r0+ ; restore ACCH - mvtachi r1 - seth r0, #shigh(registers) - add3 r0, r0, #low(registers) - ld r1, @(4,r0) ; restore r1 - ld r0, @r0 ; restore r0 - rte"); - -/* General trap handler, called after the registers have been stashed. - NUM is the trap/exception number. */ - -static void -process_exception (int num) -{ - cleanup_stash (); - asm volatile (" - seth r1, #shigh(stackPtr) - add3 r1, r1, #low(stackPtr) - ld r15, @r1 ; setup local stack (protect user stack) - mv r0, %0 - bl handle_exception - bl restore_and_return" - : : "r" (num) : "r0", "r1"); -} - -void _catchException0 (); - -asm (" -_catchException0: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #0 - bl process_exception"); - -void _catchException1 (); - -asm (" -_catchException1: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - bl cleanup_stash - seth r1, #shigh(stackPtr) - add3 r1, r1, #low(stackPtr) - ld r15, @r1 ; setup local stack (protect user stack) - seth r1, #shigh(registers + 21*4) ; PC - add3 r1, r1, #low(registers + 21*4) - ld r0, @r1 - addi r0, #-4 ; back up PC for breakpoint trap. - st r0, @r1 ; FIXME: what about bp in right slot? - ldi r0, #1 - bl handle_exception - bl restore_and_return"); - -void _catchException2 (); - -asm (" -_catchException2: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #2 - bl process_exception"); - -void _catchException3 (); - -asm (" -_catchException3: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #3 - bl process_exception"); - -void _catchException4 (); - -asm (" -_catchException4: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #4 - bl process_exception"); - -void _catchException5 (); - -asm (" -_catchException5: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #5 - bl process_exception"); - -void _catchException6 (); - -asm (" -_catchException6: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #6 - bl process_exception"); - -void _catchException7 (); - -asm (" -_catchException7: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #7 - bl process_exception"); - -void _catchException8 (); - -asm (" -_catchException8: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #8 - bl process_exception"); - -void _catchException9 (); - -asm (" -_catchException9: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #9 - bl process_exception"); - -void _catchException10 (); - -asm (" -_catchException10: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #10 - bl process_exception"); - -void _catchException11 (); - -asm (" -_catchException11: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #11 - bl process_exception"); - -void _catchException12 (); - -asm (" -_catchException12: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #12 - bl process_exception"); - -void _catchException13 (); - -asm (" -_catchException13: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #13 - bl process_exception"); - -void _catchException14 (); - -asm (" -_catchException14: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #14 - bl process_exception"); - -void _catchException15 (); - -asm (" -_catchException15: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #15 - bl process_exception"); - -void _catchException16 (); - -asm (" -_catchException16: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #16 - bl process_exception"); - -void _catchException17 (); - -asm (" -_catchException17: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #17 - bl process_exception"); - - -/* this function is used to set up exception handlers for tracing and - breakpoints */ -void -set_debug_traps (void) -{ - /* extern void remcomHandler(); */ - int i; - - for (i = 0; i < 18; i++) /* keep a copy of old vectors */ - if (save_vectors[i] == 0) /* only copy them the first time */ - save_vectors[i] = getExceptionHandler (i); - - stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - - exceptionHandler (0, _catchException0); - exceptionHandler (1, _catchException1); - exceptionHandler (2, _catchException2); - exceptionHandler (3, _catchException3); - exceptionHandler (4, _catchException4); - exceptionHandler (5, _catchException5); - exceptionHandler (6, _catchException6); - exceptionHandler (7, _catchException7); - exceptionHandler (8, _catchException8); - exceptionHandler (9, _catchException9); - exceptionHandler (10, _catchException10); - exceptionHandler (11, _catchException11); - exceptionHandler (12, _catchException12); - exceptionHandler (13, _catchException13); - exceptionHandler (14, _catchException14); - exceptionHandler (15, _catchException15); - exceptionHandler (16, _catchException16); - /* exceptionHandler (17, _catchException17); */ - - initialized = 1; -} - -/* This function will generate a breakpoint exception. It is used at the - beginning of a program to sync up with a debugger and can be used - otherwise as a quick means to stop program execution and "break" into - the debugger. */ - -#define BREAKPOINT() asm volatile (" trap #2"); - -void -breakpoint (void) -{ - if (initialized) - BREAKPOINT(); -} - -/* STDOUT section: - Stuff pertaining to simulating stdout by sending chars to gdb to be echoed. - Functions: gdb_putchar(char ch) - gdb_puts(char *str) - gdb_write(char *str, int len) - gdb_error(char *format, char *parm) - */ - -/* Function: gdb_putchar(int) - Make gdb write a char to stdout. - Returns: the char */ - -static int -gdb_putchar (int ch) -{ - char buf[4]; - - buf[0] = 'O'; - buf[1] = hexchars[ch >> 4]; - buf[2] = hexchars[ch & 0x0F]; - buf[3] = 0; - putpacket(buf); - return ch; -} - -/* Function: gdb_write(char *, int) - Make gdb write n bytes to stdout (not assumed to be null-terminated). - Returns: number of bytes written */ - -static int -gdb_write (char *data, int len) -{ - char *buf, *cpy; - int i; - - buf = remcomOutBuffer; - buf[0] = 'O'; - i = 0; - while (i < len) - { - for (cpy = buf+1; - i < len && cpy < buf + sizeof(remcomOutBuffer) - 3; - i++) - { - *cpy++ = hexchars[data[i] >> 4]; - *cpy++ = hexchars[data[i] & 0x0F]; - } - *cpy = 0; - putpacket(buf); - } - return len; -} - -/* Function: gdb_puts(char *) - Make gdb write a null-terminated string to stdout. - Returns: the length of the string */ - -static int -gdb_puts (char *str) -{ - return gdb_write(str, strlen(str)); -} - -/* Function: gdb_error(char *, char *) - Send an error message to gdb's stdout. - First string may have 1 (one) optional "%s" in it, which - will cause the optional second string to be inserted. */ - -static void -gdb_error (char *format, char *parm) -{ - char buf[400], *cpy; - int len; - - if (remote_debug) - { - if (format && *format) - len = strlen(format); - else - return; /* empty input */ - - if (parm && *parm) - len += strlen(parm); - - for (cpy = buf; *format; ) - { - if (format[0] == '%' && format[1] == 's') /* include second string */ - { - format += 2; /* advance two chars instead of just one */ - while (parm && *parm) - *cpy++ = *parm++; - } - else - *cpy++ = *format++; - } - *cpy = '\0'; - gdb_puts(buf); - } -} - -static unsigned char * -strcpy (unsigned char *dest, const unsigned char *src) -{ - unsigned char *ret = dest; - - if (dest && src) - { - while (*src) - *dest++ = *src++; - *dest = 0; - } - return ret; -} - -static int -strlen (const unsigned char *src) -{ - int ret; - - for (ret = 0; *src; src++) - ret++; - - return ret; -} - -#if 0 -void exit (code) - int code; -{ - _exit (code); -} - -int atexit (void *p) -{ - return 0; -} - -void abort (void) -{ - _exit (1); -} -#endif diff --git a/contrib/gdb/gdb/m32r-tdep.c b/contrib/gdb/gdb/m32r-tdep.c deleted file mode 100644 index 4b883fb213e..00000000000 --- a/contrib/gdb/gdb/m32r-tdep.c +++ /dev/null @@ -1,705 +0,0 @@ -/* Target-dependent code for the Mitsubishi m32r for GDB, the GNU debugger. - Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "obstack.h" -#include "target.h" -#include "value.h" -#include "bfd.h" -#include "gdb_string.h" -#include "gdbcore.h" -#include "symfile.h" -#include "regcache.h" - -/* Function: m32r_use_struct_convention - Return nonzero if call_function should allocate stack space for a - struct return? */ -int -m32r_use_struct_convention (int gcc_p, struct type *type) -{ - return (TYPE_LENGTH (type) > 8); -} - -/* Function: frame_find_saved_regs - Return the frame_saved_regs structure for the frame. - Doesn't really work for dummy frames, but it does pass back - an empty frame_saved_regs, so I guess that's better than total failure */ - -void -m32r_frame_find_saved_regs (struct frame_info *fi, - struct frame_saved_regs *regaddr) -{ - memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs)); -} - -/* Turn this on if you want to see just how much instruction decoding - if being done, its quite a lot - */ -#if 0 -static void -dump_insn (char *commnt, CORE_ADDR pc, int insn) -{ - printf_filtered (" %s %08x %08x ", - commnt, (unsigned int) pc, (unsigned int) insn); - TARGET_PRINT_INSN (pc, &tm_print_insn_info); - printf_filtered ("\n"); -} -#define insn_debug(args) { printf_filtered args; } -#else -#define dump_insn(a,b,c) {} -#define insn_debug(args) {} -#endif - -#define DEFAULT_SEARCH_LIMIT 44 - -/* Function: scan_prologue - This function decodes the target function prologue to determine - 1) the size of the stack frame, and 2) which registers are saved on it. - It saves the offsets of saved regs in the frame_saved_regs argument, - and returns the frame size. */ - -/* - The sequence it currently generates is: - - if (varargs function) { ddi sp,#n } - push registers - if (additional stack <= 256) { addi sp,#-stack } - else if (additional stack < 65k) { add3 sp,sp,#-stack - - } else if (additional stack) { - seth sp,#(stack & 0xffff0000) - or3 sp,sp,#(stack & 0x0000ffff) - sub sp,r4 - } - if (frame pointer) { - mv sp,fp - } - - These instructions are scheduled like everything else, so you should stop at - the first branch instruction. - - */ - -/* This is required by skip prologue and by m32r_init_extra_frame_info. - The results of decoding a prologue should be cached because this - thrashing is getting nuts. - I am thinking of making a container class with two indexes, name and - address. It may be better to extend the symbol table. - */ - -static void -decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit, CORE_ADDR *pl_endptr, /* var parameter */ - unsigned long *framelength, struct frame_info *fi, - struct frame_saved_regs *fsr) -{ - unsigned long framesize; - int insn; - int op1; - int maybe_one_more = 0; - CORE_ADDR after_prologue = 0; - CORE_ADDR after_stack_adjust = 0; - CORE_ADDR current_pc; - - - framesize = 0; - after_prologue = 0; - insn_debug (("rd prolog l(%d)\n", scan_limit - current_pc)); - - for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2) - { - - insn = read_memory_unsigned_integer (current_pc, 2); - dump_insn ("insn-1", current_pc, insn); /* MTZ */ - - /* If this is a 32 bit instruction, we dont want to examine its - immediate data as though it were an instruction */ - if (current_pc & 0x02) - { /* Clear the parallel execution bit from 16 bit instruction */ - if (maybe_one_more) - { /* The last instruction was a branch, usually terminates - the series, but if this is a parallel instruction, - it may be a stack framing instruction */ - if (!(insn & 0x8000)) - { - insn_debug (("Really done")); - break; /* nope, we are really done */ - } - } - insn &= 0x7fff; /* decode this instruction further */ - } - else - { - if (maybe_one_more) - break; /* This isnt the one more */ - if (insn & 0x8000) - { - insn_debug (("32 bit insn\n")); - if (current_pc == scan_limit) - scan_limit += 2; /* extend the search */ - current_pc += 2; /* skip the immediate data */ - if (insn == 0x8faf) /* add3 sp, sp, xxxx */ - /* add 16 bit sign-extended offset */ - { - insn_debug (("stack increment\n")); - framesize += -((short) read_memory_unsigned_integer (current_pc, 2)); - } - else - { - if (((insn >> 8) == 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */ - read_memory_unsigned_integer (current_pc + 2, 2) == 0x0f24) - { /* subtract 24 bit sign-extended negative-offset */ - dump_insn ("insn-2", current_pc + 2, insn); - insn = read_memory_unsigned_integer (current_pc - 2, 4); - dump_insn ("insn-3(l4)", current_pc - 2, insn); - if (insn & 0x00800000) /* sign extend */ - insn |= 0xff000000; /* negative */ - else - insn &= 0x00ffffff; /* positive */ - framesize += insn; - } - } - after_prologue = current_pc; - continue; - } - } - op1 = insn & 0xf000; /* isolate just the first nibble */ - - if ((insn & 0xf0ff) == 0x207f) - { /* st reg, @-sp */ - int regno; - insn_debug (("push\n")); -#if 0 /* No, PUSH FP is not an indication that we will use a frame pointer. */ - if (((insn & 0xffff) == 0x2d7f) && fi) - fi->using_frame_pointer = 1; -#endif - framesize += 4; -#if 0 -/* Why should we increase the scan limit, just because we did a push? - And if there is a reason, surely we would only want to do it if we - had already reached the scan limit... */ - if (current_pc == scan_limit) - scan_limit += 2; -#endif - regno = ((insn >> 8) & 0xf); - if (fsr) /* save_regs offset */ - fsr->regs[regno] = framesize; - after_prologue = 0; - continue; - } - if ((insn >> 8) == 0x4f) /* addi sp, xx */ - /* add 8 bit sign-extended offset */ - { - int stack_adjust = (char) (insn & 0xff); - - /* there are probably two of these stack adjustments: - 1) A negative one in the prologue, and - 2) A positive one in the epilogue. - We are only interested in the first one. */ - - if (stack_adjust < 0) - { - framesize -= stack_adjust; - after_prologue = 0; - /* A frameless function may have no "mv fp, sp". - In that case, this is the end of the prologue. */ - after_stack_adjust = current_pc + 2; - } - continue; - } - if (insn == 0x1d8f) - { /* mv fp, sp */ - if (fi) - fi->using_frame_pointer = 1; /* fp is now valid */ - insn_debug (("done fp found\n")); - after_prologue = current_pc + 2; - break; /* end of stack adjustments */ - } - if (insn == 0x7000) /* Nop looks like a branch, continue explicitly */ - { - insn_debug (("nop\n")); - after_prologue = current_pc + 2; - continue; /* nop occurs between pushes */ - } - /* End of prolog if any of these are branch instructions */ - if ((op1 == 0x7000) - || (op1 == 0xb000) - || (op1 == 0xf000)) - { - after_prologue = current_pc; - insn_debug (("Done: branch\n")); - maybe_one_more = 1; - continue; - } - /* Some of the branch instructions are mixed with other types */ - if (op1 == 0x1000) - { - int subop = insn & 0x0ff0; - if ((subop == 0x0ec0) || (subop == 0x0fc0)) - { - insn_debug (("done: jmp\n")); - after_prologue = current_pc; - maybe_one_more = 1; - continue; /* jmp , jl */ - } - } - } - - if (current_pc >= scan_limit) - { - if (pl_endptr) - { -#if 1 - if (after_stack_adjust != 0) - /* We did not find a "mv fp,sp", but we DID find - a stack_adjust. Is it safe to use that as the - end of the prologue? I just don't know. */ - { - *pl_endptr = after_stack_adjust; - if (framelength) - *framelength = framesize; - } - else -#endif - /* We reached the end of the loop without finding the end - of the prologue. No way to win -- we should report failure. - The way we do that is to return the original start_pc. - GDB will set a breakpoint at the start of the function (etc.) */ - *pl_endptr = start_pc; - } - return; - } - if (after_prologue == 0) - after_prologue = current_pc; - - insn_debug ((" framesize %d, firstline %08x\n", framesize, after_prologue)); - if (framelength) - *framelength = framesize; - if (pl_endptr) - *pl_endptr = after_prologue; -} /* decode_prologue */ - -/* Function: skip_prologue - Find end of function prologue */ - -CORE_ADDR -m32r_skip_prologue (CORE_ADDR pc) -{ - CORE_ADDR func_addr, func_end; - struct symtab_and_line sal; - - /* See what the symbol table says */ - - if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - { - sal = find_pc_line (func_addr, 0); - - if (sal.line != 0 && sal.end <= func_end) - { - - insn_debug (("BP after prologue %08x\n", sal.end)); - func_end = sal.end; - } - else - /* Either there's no line info, or the line after the prologue is after - the end of the function. In this case, there probably isn't a - prologue. */ - { - insn_debug (("No line info, line(%x) sal_end(%x) funcend(%x)\n", - sal.line, sal.end, func_end)); - func_end = min (func_end, func_addr + DEFAULT_SEARCH_LIMIT); - } - } - else - func_end = pc + DEFAULT_SEARCH_LIMIT; - decode_prologue (pc, func_end, &sal.end, 0, 0, 0); - return sal.end; -} - -static unsigned long -m32r_scan_prologue (struct frame_info *fi, struct frame_saved_regs *fsr) -{ - struct symtab_and_line sal; - CORE_ADDR prologue_start, prologue_end, current_pc; - unsigned long framesize = 0; - - /* this code essentially duplicates skip_prologue, - but we need the start address below. */ - - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) - { - sal = find_pc_line (prologue_start, 0); - - if (sal.line == 0) /* no line info, use current PC */ - if (prologue_start == entry_point_address ()) - return 0; - } - else - { - prologue_start = fi->pc; - prologue_end = prologue_start + 48; /* We're in the boondocks: - allow for 16 pushes, an add, - and "mv fp,sp" */ - } -#if 0 - prologue_end = min (prologue_end, fi->pc); -#endif - insn_debug (("fipc(%08x) start(%08x) end(%08x)\n", - fi->pc, prologue_start, prologue_end)); - prologue_end = min (prologue_end, prologue_start + DEFAULT_SEARCH_LIMIT); - decode_prologue (prologue_start, prologue_end, &prologue_end, &framesize, - fi, fsr); - return framesize; -} - -/* Function: init_extra_frame_info - This function actually figures out the frame address for a given pc and - sp. This is tricky on the m32r because we sometimes don't use an explicit - frame pointer, and the previous stack pointer isn't necessarily recorded - on the stack. The only reliable way to get this info is to - examine the prologue. */ - -void -m32r_init_extra_frame_info (struct frame_info *fi) -{ - int reg; - - if (fi->next) - fi->pc = FRAME_SAVED_PC (fi->next); - - memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); - - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - { - /* We need to setup fi->frame here because run_stack_dummy gets it wrong - by assuming it's always FP. */ - fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); - fi->framesize = 0; - return; - } - else - { - fi->using_frame_pointer = 0; - fi->framesize = m32r_scan_prologue (fi, &fi->fsr); - - if (!fi->next) - if (fi->using_frame_pointer) - { - fi->frame = read_register (FP_REGNUM); - } - else - fi->frame = read_register (SP_REGNUM); - else - /* fi->next means this is not the innermost frame */ if (fi->using_frame_pointer) - /* we have an FP */ - if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */ - fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4); - for (reg = 0; reg < NUM_REGS; reg++) - if (fi->fsr.regs[reg] != 0) - fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg]; - } -} - -/* Function: m32r_virtual_frame_pointer - Return the register that the function uses for a frame pointer, - plus any necessary offset to be applied to the register before - any frame pointer offsets. */ - -void -m32r_virtual_frame_pointer (CORE_ADDR pc, long *reg, long *offset) -{ - struct frame_info fi; - - /* Set up a dummy frame_info. */ - fi.next = NULL; - fi.prev = NULL; - fi.frame = 0; - fi.pc = pc; - - /* Analyze the prolog and fill in the extra info. */ - m32r_init_extra_frame_info (&fi); - - - /* Results will tell us which type of frame it uses. */ - if (fi.using_frame_pointer) - { - *reg = FP_REGNUM; - *offset = 0; - } - else - { - *reg = SP_REGNUM; - *offset = 0; - } -} - -/* Function: find_callers_reg - Find REGNUM on the stack. Otherwise, it's in an active register. One thing - we might want to do here is to check REGNUM against the clobber mask, and - somehow flag it as invalid if it isn't saved on the stack somewhere. This - would provide a graceful failure mode when trying to get the value of - caller-saves registers for an inner frame. */ - -CORE_ADDR -m32r_find_callers_reg (struct frame_info *fi, int regnum) -{ - for (; fi; fi = fi->next) - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, regnum); - else if (fi->fsr.regs[regnum] != 0) - return read_memory_integer (fi->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum)); - return read_register (regnum); -} - -/* Function: frame_chain - Given a GDB frame, determine the address of the calling function's frame. - This will be used to create a new GDB frame struct, and then - INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. - For m32r, we save the frame size when we initialize the frame_info. */ - -CORE_ADDR -m32r_frame_chain (struct frame_info *fi) -{ - CORE_ADDR fn_start, callers_pc, fp; - - /* is this a dummy frame? */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return fi->frame; /* dummy frame same as caller's frame */ - - /* is caller-of-this a dummy frame? */ - callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ - fp = m32r_find_callers_reg (fi, FP_REGNUM); - if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) - return fp; /* dummy frame's frame may bear no relation to ours */ - - if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; /* in _start fn, don't chain further */ - if (fi->framesize == 0) - { - printf_filtered ("cannot determine frame size @ %s , pc(%s)\n", - paddr (fi->frame), - paddr (fi->pc)); - return 0; - } - insn_debug (("m32rx frame %08x\n", fi->frame + fi->framesize)); - return fi->frame + fi->framesize; -} - -/* Function: push_return_address (pc) - Set up the return address for the inferior function call. - Necessary for targets that don't actually execute a JSR/BSR instruction - (ie. when using an empty CALL_DUMMY) */ - -CORE_ADDR -m32r_push_return_address (CORE_ADDR pc, CORE_ADDR sp) -{ - write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ()); - return sp; -} - - -/* Function: pop_frame - Discard from the stack the innermost frame, - restoring all saved registers. */ - -struct frame_info * -m32r_pop_frame (struct frame_info *frame) -{ - int regnum; - - if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - generic_pop_dummy_frame (); - else - { - for (regnum = 0; regnum < NUM_REGS; regnum++) - if (frame->fsr.regs[regnum] != 0) - write_register (regnum, - read_memory_integer (frame->fsr.regs[regnum], 4)); - - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - write_register (SP_REGNUM, read_register (FP_REGNUM)); - if (read_register (PSW_REGNUM) & 0x80) - write_register (SPU_REGNUM, read_register (SP_REGNUM)); - else - write_register (SPI_REGNUM, read_register (SP_REGNUM)); - } - flush_cached_frames (); - return NULL; -} - -/* Function: frame_saved_pc - Find the caller of this frame. We do this by seeing if RP_REGNUM is saved - in the stack anywhere, otherwise we get it from the registers. */ - -CORE_ADDR -m32r_frame_saved_pc (struct frame_info *fi) -{ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); - else - return m32r_find_callers_reg (fi, RP_REGNUM); -} - -/* Function: push_arguments - Setup the function arguments for calling a function in the inferior. - - On the Mitsubishi M32R architecture, there are four registers (R0 to R3) - which are dedicated for passing function arguments. Up to the first - four arguments (depending on size) may go into these registers. - The rest go on the stack. - - Arguments that are smaller than 4 bytes will still take up a whole - register or a whole 32-bit word on the stack, and will be - right-justified in the register or the stack word. This includes - chars, shorts, and small aggregate types. - - Arguments of 8 bytes size are split between two registers, if - available. If only one register is available, the argument will - be split between the register and the stack. Otherwise it is - passed entirely on the stack. Aggregate types with sizes between - 4 and 8 bytes are passed entirely on the stack, and are left-justified - within the double-word (as opposed to aggregates smaller than 4 bytes - which are right-justified). - - Aggregates of greater than 8 bytes are first copied onto the stack, - and then a pointer to the copy is passed in the place of the normal - argument (either in a register if available, or on the stack). - - Functions that must return an aggregate type can return it in the - normal return value registers (R0 and R1) if its size is 8 bytes or - less. For larger return values, the caller must allocate space for - the callee to copy the return value to. A pointer to this space is - passed as an implicit first argument, always in R0. */ - -CORE_ADDR -m32r_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - unsigned char struct_return, CORE_ADDR struct_addr) -{ - int stack_offset, stack_alloc; - int argreg; - int argnum; - struct type *type; - CORE_ADDR regval; - char *val; - char valbuf[4]; - int len; - int odd_sized_struct; - - /* first force sp to a 4-byte alignment */ - sp = sp & ~3; - - argreg = ARG0_REGNUM; - /* The "struct return pointer" pseudo-argument goes in R0 */ - if (struct_return) - write_register (argreg++, struct_addr); - - /* Now make sure there's space on the stack */ - for (argnum = 0, stack_alloc = 0; - argnum < nargs; argnum++) - stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3); - sp -= stack_alloc; /* make room on stack for args */ - - - /* Now load as many as possible of the first arguments into - registers, and push the rest onto the stack. There are 16 bytes - in four registers available. Loop thru args from first to last. */ - - argreg = ARG0_REGNUM; - for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++) - { - type = VALUE_TYPE (args[argnum]); - len = TYPE_LENGTH (type); - memset (valbuf, 0, sizeof (valbuf)); - if (len < 4) - { /* value gets right-justified in the register or stack word */ - memcpy (valbuf + (4 - len), - (char *) VALUE_CONTENTS (args[argnum]), len); - val = valbuf; - } - else - val = (char *) VALUE_CONTENTS (args[argnum]); - - if (len > 4 && (len & 3) != 0) - odd_sized_struct = 1; /* such structs go entirely on stack */ - else - odd_sized_struct = 0; - while (len > 0) - { - if (argreg > ARGLAST_REGNUM || odd_sized_struct) - { /* must go on the stack */ - write_memory (sp + stack_offset, val, 4); - stack_offset += 4; - } - /* NOTE WELL!!!!! This is not an "else if" clause!!! - That's because some *&^%$ things get passed on the stack - AND in the registers! */ - if (argreg <= ARGLAST_REGNUM) - { /* there's room in a register */ - regval = extract_address (val, REGISTER_RAW_SIZE (argreg)); - write_register (argreg++, regval); - } - /* Store the value 4 bytes at a time. This means that things - larger than 4 bytes may go partly in registers and partly - on the stack. */ - len -= REGISTER_RAW_SIZE (argreg); - val += REGISTER_RAW_SIZE (argreg); - } - } - return sp; -} - -/* Function: fix_call_dummy - If there is real CALL_DUMMY code (eg. on the stack), this function - has the responsability to insert the address of the actual code that - is the target of the target function call. */ - -void -m32r_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - /* ld24 r8, <(imm24) fun> */ - *(unsigned long *) (dummy) = (fun & 0x00ffffff) | 0xe8000000; -} - - -/* Function: m32r_write_sp - Because SP is really a read-only register that mirrors either SPU or SPI, - we must actually write one of those two as well, depending on PSW. */ - -void -m32r_write_sp (CORE_ADDR val) -{ - unsigned long psw = read_register (PSW_REGNUM); - - if (psw & 0x80) /* stack mode: user or interrupt */ - write_register (SPU_REGNUM, val); - else - write_register (SPI_REGNUM, val); - write_register (SP_REGNUM, val); -} - -void -_initialize_m32r_tdep (void) -{ - tm_print_insn = print_insn_m32r; -} diff --git a/contrib/gdb/gdb/m68k-stub.c b/contrib/gdb/gdb/m68k-stub.c deleted file mode 100644 index 54e06b13ccb..00000000000 --- a/contrib/gdb/gdb/m68k-stub.c +++ /dev/null @@ -1,1098 +0,0 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. The breakpoint instruction - * is hardwired to trap #1 because not to do so is a compatibility problem-- - * there either should be a standard breakpoint instruction, or the protocol - * should be extended to provide some means to communicate which breakpoint - * instruction is in use (or have the stub insert the breakpoint). - * - * Some explanation is probably necessary to explain how exceptions are - * handled. When an exception is encountered the 68000 pushes the current - * program counter and status register onto the supervisor stack and then - * transfers execution to a location specified in it's vector table. - * The handlers for the exception vectors are hardwired to jmp to an address - * given by the relation: (exception - 256) * 6. These are decending - * addresses starting from -6, -12, -18, ... By allowing 6 bytes for - * each entry, a jsr, jmp, bsr, ... can be used to enter the exception - * handler. Using a jsr to handle an exception has an added benefit of - * allowing a single handler to service several exceptions and use the - * return address as the key differentiation. The vector number can be - * computed from the return address by [ exception = (addr + 1530) / 6 ]. - * The sole purpose of the routine _catchException is to compute the - * exception number and push it on the stack in place of the return address. - * The external function exceptionHandler() is - * used to attach a specific handler to a specific m68k exception. - * For 68020 machines, the ability to have a return address around just - * so the vector can be determined is not necessary because the '020 pushes an - * extra word onto the stack containing the vector offset - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses it's own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include -#include -#include - -/************************************************************************ - * - * external low-level support routines - */ -typedef void (*ExceptionHook)(int); /* pointer to function with int parm */ -typedef void (*Function)(); /* pointer to a function */ - -extern void putDebugChar(); /* write a single character */ -extern int getDebugChar(); /* read and return a single char */ - -extern Function exceptionHandler(); /* assign an exception handler */ -extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */ - -/************************/ -/* FORWARD DECLARATIONS */ -/************************/ -static void -initializeRemcomErrorFrame (); - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 400 - -static char initialized; /* boolean flag. != 0 means we've been initialized */ - -int remote_debug; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ - -static const char hexchars[]="0123456789abcdef"; - -/* there are 180 bytes of registers on a 68020 w/68881 */ -/* many of the fpa registers are 12 byte (96 bit) registers */ -#define NUMREGBYTES 180 -enum regnames {D0,D1,D2,D3,D4,D5,D6,D7, - A0,A1,A2,A3,A4,A5,A6,A7, - PS,PC, - FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7, - FPCONTROL,FPSTATUS,FPIADDR - }; - - -/* We keep a whole frame cache here. "Why?", I hear you cry, "doesn't - GDB handle that sort of thing?" Well, yes, I believe the only - reason for this cache is to save and restore floating point state - (fsave/frestore). A cleaner way to do this would be to make the - fsave data part of the registers which GDB deals with like any - other registers. This should not be a performance problem if the - ability to read individual registers is added to the protocol. */ - -typedef struct FrameStruct -{ - struct FrameStruct *previous; - int exceptionPC; /* pc value when this frame created */ - int exceptionVector; /* cpu vector causing exception */ - short frameSize; /* size of cpu frame in words */ - short sr; /* for 68000, this not always sr */ - int pc; - short format; - int fsaveHeader; - int morejunk[0]; /* exception frame, fp save... */ -} Frame; - -#define FRAMESIZE 500 -int gdbFrameStack[FRAMESIZE]; -static Frame *lastFrame; - -/* - * these should not be static cuz they can be used outside this module - */ -int registers[NUMREGBYTES/4]; -int superStack; - -#define STACKSIZE 10000 -int remcomStack[STACKSIZE/sizeof(int)]; -static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - -/* - * In many cases, the system will want to continue exception processing - * when a continue command is given. - * oldExceptionHook is a function to invoke in this case. - */ - -static ExceptionHook oldExceptionHook; - -#ifdef mc68020 -/* the size of the exception stack on the 68020 varies with the type of - * exception. The following table is the number of WORDS used - * for each exception format. - */ -const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 }; -#endif - -#ifdef mc68332 -static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 }; -#endif - -/************* jump buffer used for setjmp/longjmp **************************/ -jmp_buf remcomEnv; - -/*************************** ASSEMBLY CODE MACROS *************************/ -/* */ - -#ifdef __HAVE_68881__ -/* do an fsave, then remember the address to begin a restore from */ -#define SAVE_FP_REGS() asm(" fsave a0@-"); \ - asm(" fmovemx fp0-fp7,_registers+72"); \ - asm(" fmoveml fpcr/fpsr/fpi,_registers+168"); -#define RESTORE_FP_REGS() \ -asm(" \n\ - fmoveml _registers+168,fpcr/fpsr/fpi \n\ - fmovemx _registers+72,fp0-fp7 \n\ - cmpl #-1,a0@ | skip frestore flag set ? \n\ - beq skip_frestore \n\ - frestore a0@+ \n\ -skip_frestore: \n\ -"); - -#else -#define SAVE_FP_REGS() -#define RESTORE_FP_REGS() -#endif /* __HAVE_68881__ */ - -void return_to_super(); -void return_to_user(); - -asm(" -.text -.globl _return_to_super -_return_to_super: - movel _registers+60,sp /* get new stack pointer */ - movel _lastFrame,a0 /* get last frame info */ - bra return_to_any - -.globl _return_to_user -_return_to_user: - movel _registers+60,a0 /* get usp */ - movel a0,usp /* set usp */ - movel _superStack,sp /* get original stack pointer */ - -return_to_any: - movel _lastFrame,a0 /* get last frame info */ - movel a0@+,_lastFrame /* link in previous frame */ - addql #8,a0 /* skip over pc, vector#*/ - movew a0@+,d0 /* get # of words in cpu frame */ - addw d0,a0 /* point to end of data */ - addw d0,a0 /* point to end of data */ - movel a0,a1 -# -# copy the stack frame - subql #1,d0 -copyUserLoop: - movew a1@-,sp@- - dbf d0,copyUserLoop -"); - RESTORE_FP_REGS() - asm(" moveml _registers,d0-d7/a0-a6"); - asm(" rte"); /* pop and go! */ - -#define DISABLE_INTERRUPTS() asm(" oriw #0x0700,sr"); -#define BREAKPOINT() asm(" trap #1"); - -/* this function is called immediately when a level 7 interrupt occurs */ -/* if the previous interrupt level was 7 then we're already servicing */ -/* this interrupt and an rte is in order to return to the debugger. */ -/* For the 68000, the offset for sr is 6 due to the jsr return address */ -asm(" -.text -.globl __debug_level7 -__debug_level7: - movew d0,sp@-"); -#if defined (mc68020) || defined (mc68332) -asm(" movew sp@(2),d0"); -#else -asm(" movew sp@(6),d0"); -#endif -asm(" andiw #0x700,d0 - cmpiw #0x700,d0 - beq _already7 - movew sp@+,d0 - bra __catchException -_already7: - movew sp@+,d0"); -#if !defined (mc68020) && !defined (mc68332) -asm(" lea sp@(4),sp"); /* pull off 68000 return address */ -#endif -asm(" rte"); - -extern void _catchException (); - -#if defined (mc68020) || defined (mc68332) -/* This function is called when a 68020 exception occurs. It saves - * all the cpu and fpcp regs in the _registers array, creates a frame on a - * linked list of frames which has the cpu and fpcp stack frames needed - * to properly restore the context of these processors, and invokes - * an exception handler (remcom_handler). - * - * stack on entry: stack on exit: - * N bytes of junk exception # MSWord - * Exception Format Word exception # MSWord - * Program counter LSWord - * Program counter MSWord - * Status Register - * - * - */ -asm(" -.text -.globl __catchException -__catchException:"); -DISABLE_INTERRUPTS(); -asm(" - moveml d0-d7/a0-a6,_registers /* save registers */ - movel _lastFrame,a0 /* last frame pointer */ -"); -SAVE_FP_REGS(); -asm(" - lea _registers,a5 /* get address of registers */ - movew sp@,d1 /* get status register */ - movew d1,a5@(66) /* save sr */ - movel sp@(2),a4 /* save pc in a4 for later use */ - movel a4,a5@(68) /* save pc in _regisers[] */ - -# -# figure out how many bytes in the stack frame - movew sp@(6),d0 /* get '020 exception format */ - movew d0,d2 /* make a copy of format word */ - andiw #0xf000,d0 /* mask off format type */ - rolw #5,d0 /* rotate into the low byte *2 */ - lea _exceptionSize,a1 - addw d0,a1 /* index into the table */ - movew a1@,d0 /* get number of words in frame */ - movew d0,d3 /* save it */ - subw d0,a0 /* adjust save pointer */ - subw d0,a0 /* adjust save pointer(bytes) */ - movel a0,a1 /* copy save pointer */ - subql #1,d0 /* predecrement loop counter */ -# -# copy the frame -saveFrameLoop: - movew sp@+,a1@+ - dbf d0,saveFrameLoop -# -# now that the stack has been clenaed, -# save the a7 in use at time of exception - movel sp,_superStack /* save supervisor sp */ - andiw #0x2000,d1 /* were we in supervisor mode ? */ - beq userMode - movel a7,a5@(60) /* save a7 */ - bra a7saveDone -userMode: - movel usp,a1 - movel a1,a5@(60) /* save user stack pointer */ -a7saveDone: - -# -# save size of frame - movew d3,a0@- - -# -# compute exception number - andl #0xfff,d2 /* mask off vector offset */ - lsrw #2,d2 /* divide by 4 to get vect num */ - movel d2,a0@- /* save it */ -# -# save pc causing exception - movel a4,a0@- -# -# save old frame link and set the new value - movel _lastFrame,a1 /* last frame pointer */ - movel a1,a0@- /* save pointer to prev frame */ - movel a0,_lastFrame - - movel d2,sp@- /* push exception num */ - movel _exceptionHook,a0 /* get address of handler */ - jbsr a0@ /* and call it */ - clrl sp@ /* replace exception num parm with frame ptr */ - jbsr __returnFromException /* jbsr, but never returns */ -"); -#else /* mc68000 */ -/* This function is called when an exception occurs. It translates the - * return address found on the stack into an exception vector # which - * is then handled by either handle_exception or a system handler. - * _catchException provides a front end for both. - * - * stack on entry: stack on exit: - * Program counter MSWord exception # MSWord - * Program counter LSWord exception # MSWord - * Status Register - * Return Address MSWord - * Return Address LSWord - */ -asm(" -.text -.globl __catchException -__catchException:"); -DISABLE_INTERRUPTS(); -asm(" - moveml d0-d7/a0-a6,_registers /* save registers */ - movel _lastFrame,a0 /* last frame pointer */ -"); -SAVE_FP_REGS(); -asm(" - lea _registers,a5 /* get address of registers */ - movel sp@+,d2 /* pop return address */ - addl #1530,d2 /* convert return addr to */ - divs #6,d2 /* exception number */ - extl d2 - - moveql #3,d3 /* assume a three word frame */ - - cmpiw #3,d2 /* bus error or address error ? */ - bgt normal /* if >3 then normal error */ - movel sp@+,a0@- /* copy error info to frame buff*/ - movel sp@+,a0@- /* these are never used */ - moveql #7,d3 /* this is a 7 word frame */ - -normal: - movew sp@+,d1 /* pop status register */ - movel sp@+,a4 /* pop program counter */ - movew d1,a5@(66) /* save sr */ - movel a4,a5@(68) /* save pc in _regisers[] */ - movel a4,a0@- /* copy pc to frame buffer */ - movew d1,a0@- /* copy sr to frame buffer */ - - movel sp,_superStack /* save supervisor sp */ - - andiw #0x2000,d1 /* were we in supervisor mode ? */ - beq userMode - movel a7,a5@(60) /* save a7 */ - bra saveDone -userMode: - movel usp,a1 /* save user stack pointer */ - movel a1,a5@(60) /* save user stack pointer */ -saveDone: - - movew d3,a0@- /* push frame size in words */ - movel d2,a0@- /* push vector number */ - movel a4,a0@- /* push exception pc */ - -# -# save old frame link and set the new value - movel _lastFrame,a1 /* last frame pointer */ - movel a1,a0@- /* save pointer to prev frame */ - movel a0,_lastFrame - - movel d2,sp@- /* push exception num */ - movel _exceptionHook,a0 /* get address of handler */ - jbsr a0@ /* and call it */ - clrl sp@ /* replace exception num parm with frame ptr */ - jbsr __returnFromException /* jbsr, but never returns */ -"); -#endif - - -/* - * remcomHandler is a front end for handle_exception. It moves the - * stack pointer into an area reserved for debugger use in case the - * breakpoint happened in supervisor mode. - */ -asm("_remcomHandler:"); -asm(" addl #4,sp"); /* pop off return address */ -asm(" movel sp@+,d0"); /* get the exception number */ -asm(" movel _stackPtr,sp"); /* move to remcom stack area */ -asm(" movel d0,sp@-"); /* push exception onto stack */ -asm(" jbsr _handle_exception"); /* this never returns */ -asm(" rts"); /* return */ - -void -_returnFromException (Frame * frame) -{ - /* if no passed in frame, use the last one */ - if (!frame) - { - frame = lastFrame; - frame->frameSize = 4; - frame->format = 0; - frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info */ - } - -#if !defined (mc68020) && !defined (mc68332) - /* a 68000 cannot use the internal info pushed onto a bus error - * or address error frame when doing an RTE so don't put this info - * onto the stack or the stack will creep every time this happens. - */ - frame->frameSize = 3; -#endif - - /* throw away any frames in the list after this frame */ - lastFrame = frame; - - frame->sr = registers[(int) PS]; - frame->pc = registers[(int) PC]; - - if (registers[(int) PS] & 0x2000) - { - /* return to supervisor mode... */ - return_to_super (); - } - else - { /* return to user mode */ - return_to_user (); - } -} - -int -hex (ch) - char ch; -{ - if ((ch >= 'a') && (ch <= 'f')) - return (ch - 'a' + 10); - if ((ch >= '0') && (ch <= '9')) - return (ch - '0'); - if ((ch >= 'A') && (ch <= 'F')) - return (ch - 'A' + 10); - return (-1); -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -/* scan for the sequence $# */ - -unsigned char * -getpacket (void) -{ - unsigned char *buffer = &remcomInBuffer[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - char ch; - - while (1) - { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - - retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) - { - ch = getDebugChar (); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - { - if (remote_debug) - { - fprintf (stderr, - "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", - checksum, xmitcsum, buffer); - } - putDebugChar ('-'); /* failed checksum */ - } - else - { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } - } - } -} - -/* send the packet in buffer. */ - -void -putpacket (buffer) - char *buffer; -{ - unsigned char checksum; - int count; - char ch; - - /* $#. */ - do - { - putDebugChar ('$'); - checksum = 0; - count = 0; - - while (ch = buffer[count]) - { - putDebugChar (ch); - checksum += ch; - count += 1; - } - - putDebugChar ('#'); - putDebugChar (hexchars[checksum >> 4]); - putDebugChar (hexchars[checksum % 16]); - - } - while (getDebugChar () != '+'); - -} - -void -debug_error (format, parm) - char *format; - char *parm; -{ - if (remote_debug) - fprintf (stderr, format, parm); -} - -/* convert the memory pointed to by mem into hex, placing result in buf */ -/* return a pointer to the last char put in buf (null) */ -char * -mem2hex (mem, buf, count) - char *mem; - char *buf; - int count; -{ - int i; - unsigned char ch; - for (i = 0; i < count; i++) - { - ch = *mem++; - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - return (buf); -} - -/* convert the hex array pointed to by buf into binary to be placed in mem */ -/* return a pointer to the character AFTER the last byte written */ -char * -hex2mem (buf, mem, count) - char *buf; - char *mem; - int count; -{ - int i; - unsigned char ch; - for (i = 0; i < count; i++) - { - ch = hex (*buf++) << 4; - ch = ch + hex (*buf++); - *mem++ = ch; - } - return (mem); -} - -/* a bus error has occurred, perform a longjmp - to return execution and allow handling of the error */ - -void -handle_buserror () -{ - longjmp (remcomEnv, 1); -} - -/* this function takes the 68000 exception number and attempts to - translate this number into a unix compatible signal value */ -int -computeSignal (exceptionVector) - int exceptionVector; -{ - int sigval; - switch (exceptionVector) - { - case 2: - sigval = 10; - break; /* bus error */ - case 3: - sigval = 10; - break; /* address error */ - case 4: - sigval = 4; - break; /* illegal instruction */ - case 5: - sigval = 8; - break; /* zero divide */ - case 6: - sigval = 8; - break; /* chk instruction */ - case 7: - sigval = 8; - break; /* trapv instruction */ - case 8: - sigval = 11; - break; /* privilege violation */ - case 9: - sigval = 5; - break; /* trace trap */ - case 10: - sigval = 4; - break; /* line 1010 emulator */ - case 11: - sigval = 4; - break; /* line 1111 emulator */ - - /* Coprocessor protocol violation. Using a standard MMU or FPU - this cannot be triggered by software. Call it a SIGBUS. */ - case 13: - sigval = 10; - break; - - case 31: - sigval = 2; - break; /* interrupt */ - case 33: - sigval = 5; - break; /* breakpoint */ - - /* This is a trap #8 instruction. Apparently it is someone's software - convention for some sort of SIGFPE condition. Whose? How many - people are being screwed by having this code the way it is? - Is there a clean solution? */ - case 40: - sigval = 8; - break; /* floating point err */ - - case 48: - sigval = 8; - break; /* floating point err */ - case 49: - sigval = 8; - break; /* floating point err */ - case 50: - sigval = 8; - break; /* zero divide */ - case 51: - sigval = 8; - break; /* underflow */ - case 52: - sigval = 8; - break; /* operand error */ - case 53: - sigval = 8; - break; /* overflow */ - case 54: - sigval = 8; - break; /* NAN */ - default: - sigval = 7; /* "software generated" */ - } - return (sigval); -} - -/**********************************************/ -/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ -/* RETURN NUMBER OF CHARS PROCESSED */ -/**********************************************/ -int -hexToInt (char **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - - while (**ptr) - { - hexValue = hex (**ptr); - if (hexValue >= 0) - { - *intValue = (*intValue << 4) | hexValue; - numChars++; - } - else - break; - - (*ptr)++; - } - - return (numChars); -} - -/* - * This function does all command procesing for interfacing to gdb. - */ -void -handle_exception (int exceptionVector) -{ - int sigval, stepping; - int addr, length; - char *ptr; - int newPC; - Frame *frame; - - if (remote_debug) - printf ("vector=%d, sr=0x%x, pc=0x%x\n", - exceptionVector, registers[PS], registers[PC]); - - /* reply to host that an exception has occurred */ - sigval = computeSignal (exceptionVector); - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - - putpacket (remcomOutBuffer); - - stepping = 0; - - while (1 == 1) - { - remcomOutBuffer[0] = 0; - ptr = getpacket (); - switch (*ptr++) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - case 'd': - remote_debug = !(remote_debug); /* toggle debug flag */ - break; - case 'g': /* return the value of the CPU registers */ - mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES); - break; - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem (ptr, (char *) registers, NUMREGBYTES); - strcpy (remcomOutBuffer, "OK"); - break; - - /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - case 'm': - if (setjmp (remcomEnv) == 0) - { - exceptionHandler (2, handle_buserror); - - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - if (hexToInt (&ptr, &addr)) - if (*(ptr++) == ',') - if (hexToInt (&ptr, &length)) - { - ptr = 0; - mem2hex ((char *) addr, remcomOutBuffer, length); - } - - if (ptr) - { - strcpy (remcomOutBuffer, "E01"); - } - } - else - { - exceptionHandler (2, _catchException); - strcpy (remcomOutBuffer, "E03"); - debug_error ("bus error"); - } - - /* restore handler for bus error */ - exceptionHandler (2, _catchException); - break; - - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - case 'M': - if (setjmp (remcomEnv) == 0) - { - exceptionHandler (2, handle_buserror); - - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - if (hexToInt (&ptr, &addr)) - if (*(ptr++) == ',') - if (hexToInt (&ptr, &length)) - if (*(ptr++) == ':') - { - hex2mem (ptr, (char *) addr, length); - ptr = 0; - strcpy (remcomOutBuffer, "OK"); - } - if (ptr) - { - strcpy (remcomOutBuffer, "E02"); - } - } - else - { - exceptionHandler (2, _catchException); - strcpy (remcomOutBuffer, "E03"); - debug_error ("bus error"); - } - - /* restore handler for bus error */ - exceptionHandler (2, _catchException); - break; - - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 's': - stepping = 1; - case 'c': - /* try to read optional parameter, pc unchanged if no parm */ - if (hexToInt (&ptr, &addr)) - registers[PC] = addr; - - newPC = registers[PC]; - - /* clear the trace bit */ - registers[PS] &= 0x7fff; - - /* set the trace bit if we're stepping */ - if (stepping) - registers[PS] |= 0x8000; - - /* - * look for newPC in the linked list of exception frames. - * if it is found, use the old frame it. otherwise, - * fake up a dummy frame in returnFromException(). - */ - if (remote_debug) - printf ("new pc = 0x%x\n", newPC); - frame = lastFrame; - while (frame) - { - if (remote_debug) - printf ("frame at 0x%x has pc=0x%x, except#=%d\n", - frame, frame->exceptionPC, frame->exceptionVector); - if (frame->exceptionPC == newPC) - break; /* bingo! a match */ - /* - * for a breakpoint instruction, the saved pc may - * be off by two due to re-executing the instruction - * replaced by the trap instruction. Check for this. - */ - if ((frame->exceptionVector == 33) && - (frame->exceptionPC == (newPC + 2))) - break; - if (frame == frame->previous) - { - frame = 0; /* no match found */ - break; - } - frame = frame->previous; - } - - /* - * If we found a match for the PC AND we are not returning - * as a result of a breakpoint (33), - * trace exception (9), nmi (31), jmp to - * the old exception handler as if this code never ran. - */ - if (frame) - { - if ((frame->exceptionVector != 9) && - (frame->exceptionVector != 31) && - (frame->exceptionVector != 33)) - { - /* - * invoke the previous handler. - */ - if (oldExceptionHook) - (*oldExceptionHook) (frame->exceptionVector); - newPC = registers[PC]; /* pc may have changed */ - if (newPC != frame->exceptionPC) - { - if (remote_debug) - printf ("frame at 0x%x has pc=0x%x, except#=%d\n", - frame, frame->exceptionPC, - frame->exceptionVector); - /* re-use the last frame, we're skipping it (longjump?) */ - frame = (Frame *) 0; - _returnFromException (frame); /* this is a jump */ - } - } - } - - /* if we couldn't find a frame, create one */ - if (frame == 0) - { - frame = lastFrame - 1; - - /* by using a bunch of print commands with breakpoints, - it's possible for the frame stack to creep down. If it creeps - too far, give up and reset it to the top. Normal use should - not see this happen. - */ - if ((unsigned int) (frame - 2) < (unsigned int) &gdbFrameStack) - { - initializeRemcomErrorFrame (); - frame = lastFrame; - } - frame->previous = lastFrame; - lastFrame = frame; - frame = 0; /* null so _return... will properly initialize it */ - } - - _returnFromException (frame); /* this is a jump */ - - break; - - /* kill the program */ - case 'k': /* do nothing */ - break; - } /* switch */ - - /* reply to the request */ - putpacket (remcomOutBuffer); - } -} - - -void -initializeRemcomErrorFrame (void) -{ - lastFrame = ((Frame *) & gdbFrameStack[FRAMESIZE - 1]) - 1; - lastFrame->previous = lastFrame; -} - -/* this function is used to set up exception handlers for tracing and - breakpoints */ -void -set_debug_traps () -{ - extern void _debug_level7 (); - extern void remcomHandler (); - int exception; - - initializeRemcomErrorFrame (); - stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1]; - - for (exception = 2; exception <= 23; exception++) - exceptionHandler (exception, _catchException); - - /* level 7 interrupt */ - exceptionHandler (31, _debug_level7); - - /* breakpoint exception (trap #1) */ - exceptionHandler (33, _catchException); - - /* This is a trap #8 instruction. Apparently it is someone's software - convention for some sort of SIGFPE condition. Whose? How many - people are being screwed by having this code the way it is? - Is there a clean solution? */ - exceptionHandler (40, _catchException); - - /* 48 to 54 are floating point coprocessor errors */ - for (exception = 48; exception <= 54; exception++) - exceptionHandler (exception, _catchException); - - if (oldExceptionHook != remcomHandler) - { - oldExceptionHook = exceptionHook; - exceptionHook = remcomHandler; - } - - initialized = 1; - -} - -/* This function will generate a breakpoint exception. It is used at the - beginning of a program to sync up with a debugger and can be used - otherwise as a quick means to stop program execution and "break" into - the debugger. */ - -void -breakpoint () -{ - if (initialized) - BREAKPOINT (); -} diff --git a/contrib/gdb/gdb/m68k-tdep.c b/contrib/gdb/gdb/m68k-tdep.c deleted file mode 100644 index 1c4bc4d4d1f..00000000000 --- a/contrib/gdb/gdb/m68k-tdep.c +++ /dev/null @@ -1,685 +0,0 @@ -/* Target dependent code for the Motorola 68000 series. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "symtab.h" -#include "gdbcore.h" -#include "value.h" -#include "gdb_string.h" -#include "inferior.h" -#include "regcache.h" - - -#define P_LINKL_FP 0x480e -#define P_LINKW_FP 0x4e56 -#define P_PEA_FP 0x4856 -#define P_MOVL_SP_FP 0x2c4f -#define P_MOVL 0x207c -#define P_JSR 0x4eb9 -#define P_BSR 0x61ff -#define P_LEAL 0x43fb -#define P_MOVML 0x48ef -#define P_FMOVM 0xf237 -#define P_TRAP 0x4e40 - -/* The only reason this is here is the tm-altos.h reference below. It - was moved back here from tm-m68k.h. FIXME? */ - -extern CORE_ADDR -altos_skip_prologue (CORE_ADDR pc) -{ - register int op = read_memory_integer (pc, 2); - if (op == P_LINKW_FP) - pc += 4; /* Skip link #word */ - else if (op == P_LINKL_FP) - pc += 6; /* Skip link #long */ - /* Not sure why branches are here. */ - /* From tm-altos.h */ - else if (op == 0060000) - pc += 4; /* Skip bra #word */ - else if (op == 00600377) - pc += 6; /* skip bra #long */ - else if ((op & 0177400) == 0060000) - pc += 2; /* skip bra #char */ - return pc; -} - -int -delta68_in_sigtramp (CORE_ADDR pc, char *name) -{ - if (name != NULL) - return strcmp (name, "_sigcode") == 0; - else - return 0; -} - -CORE_ADDR -delta68_frame_args_address (struct frame_info *frame_info) -{ - /* we assume here that the only frameless functions are the system calls - or other functions who do not put anything on the stack. */ - if (frame_info->signal_handler_caller) - return frame_info->frame + 12; - else if (frameless_look_for_prologue (frame_info)) - { - /* Check for an interrupted system call */ - if (frame_info->next && frame_info->next->signal_handler_caller) - return frame_info->next->frame + 16; - else - return frame_info->frame + 4; - } - else - return frame_info->frame; -} - -CORE_ADDR -delta68_frame_saved_pc (struct frame_info *frame_info) -{ - return read_memory_integer (delta68_frame_args_address (frame_info) + 4, 4); -} - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -int -isi_frame_num_args (struct frame_info *fi) -{ - int val; - CORE_ADDR pc = FRAME_SAVED_PC (fi); - int insn = 0177777 & read_memory_integer (pc, 2); - val = 0; - if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ - val = read_memory_integer (pc + 2, 2); - else if ((insn & 0170777) == 0050217 /* addql #N, sp */ - || (insn & 0170777) == 0050117) /* addqw */ - { - val = (insn >> 9) & 7; - if (val == 0) - val = 8; - } - else if (insn == 0157774) /* addal #WW, sp */ - val = read_memory_integer (pc + 2, 4); - val >>= 2; - return val; -} - -int -delta68_frame_num_args (struct frame_info *fi) -{ - int val; - CORE_ADDR pc = FRAME_SAVED_PC (fi); - int insn = 0177777 & read_memory_integer (pc, 2); - val = 0; - if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ - val = read_memory_integer (pc + 2, 2); - else if ((insn & 0170777) == 0050217 /* addql #N, sp */ - || (insn & 0170777) == 0050117) /* addqw */ - { - val = (insn >> 9) & 7; - if (val == 0) - val = 8; - } - else if (insn == 0157774) /* addal #WW, sp */ - val = read_memory_integer (pc + 2, 4); - val >>= 2; - return val; -} - -int -news_frame_num_args (struct frame_info *fi) -{ - int val; - CORE_ADDR pc = FRAME_SAVED_PC (fi); - int insn = 0177777 & read_memory_integer (pc, 2); - val = 0; - if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ - val = read_memory_integer (pc + 2, 2); - else if ((insn & 0170777) == 0050217 /* addql #N, sp */ - || (insn & 0170777) == 0050117) /* addqw */ - { - val = (insn >> 9) & 7; - if (val == 0) - val = 8; - } - else if (insn == 0157774) /* addal #WW, sp */ - val = read_memory_integer (pc + 2, 4); - val >>= 2; - return val; -} - -/* Push an empty stack frame, to record the current PC, etc. */ - -void -m68k_push_dummy_frame (void) -{ - register CORE_ADDR sp = read_register (SP_REGNUM); - register int regnum; - char raw_buffer[12]; - - sp = push_word (sp, read_register (PC_REGNUM)); - sp = push_word (sp, read_register (FP_REGNUM)); - write_register (FP_REGNUM, sp); - - /* Always save the floating-point registers, whether they exist on - this target or not. */ - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) - { - read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); - sp = push_bytes (sp, raw_buffer, 12); - } - - for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) - { - sp = push_word (sp, read_register (regnum)); - } - sp = push_word (sp, read_register (PS_REGNUM)); - write_register (SP_REGNUM, sp); -} - -/* Discard from the stack the innermost frame, - restoring all saved registers. */ - -void -m68k_pop_frame (void) -{ - register struct frame_info *frame = get_current_frame (); - register CORE_ADDR fp; - register int regnum; - struct frame_saved_regs fsr; - char raw_buffer[12]; - - fp = FRAME_FP (frame); - get_frame_saved_regs (frame, &fsr); - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) - { - if (fsr.regs[regnum]) - { - read_memory (fsr.regs[regnum], raw_buffer, 12); - write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); - } - } - for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) - { - if (fsr.regs[regnum]) - { - write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); - } - } - if (fsr.regs[PS_REGNUM]) - { - write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); - } - write_register (FP_REGNUM, read_memory_integer (fp, 4)); - write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); - write_register (SP_REGNUM, fp + 8); - flush_cached_frames (); -} - - -/* Given an ip value corresponding to the start of a function, - return the ip of the first instruction after the function - prologue. This is the generic m68k support. Machines which - require something different can override the SKIP_PROLOGUE - macro to point elsewhere. - - Some instructions which typically may appear in a function - prologue include: - - A link instruction, word form: - - link.w %a6,&0 4e56 XXXX - - A link instruction, long form: - - link.l %fp,&F%1 480e XXXX XXXX - - A movm instruction to preserve integer regs: - - movm.l &M%1,(4,%sp) 48ef XXXX XXXX - - A fmovm instruction to preserve float regs: - - fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX - - Some profiling setup code (FIXME, not recognized yet): - - lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX - bsr _mcount 61ff XXXX XXXX - - */ - -CORE_ADDR -m68k_skip_prologue (CORE_ADDR ip) -{ - register CORE_ADDR limit; - struct symtab_and_line sal; - register int op; - - /* Find out if there is a known limit for the extent of the prologue. - If so, ensure we don't go past it. If not, assume "infinity". */ - - sal = find_pc_line (ip, 0); - limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0; - - while (ip < limit) - { - op = read_memory_integer (ip, 2); - op &= 0xFFFF; - - if (op == P_LINKW_FP) - ip += 4; /* Skip link.w */ - else if (op == P_PEA_FP) - ip += 2; /* Skip pea %fp */ - else if (op == P_MOVL_SP_FP) - ip += 2; /* Skip move.l %sp, %fp */ - else if (op == P_LINKL_FP) - ip += 6; /* Skip link.l */ - else if (op == P_MOVML) - ip += 6; /* Skip movm.l */ - else if (op == P_FMOVM) - ip += 10; /* Skip fmovm */ - else - break; /* Found unknown code, bail out. */ - } - return (ip); -} - -void -m68k_find_saved_regs (struct frame_info *frame_info, - struct frame_saved_regs *saved_regs) -{ - register int regnum; - register int regmask; - register CORE_ADDR next_addr; - register CORE_ADDR pc; - - /* First possible address for a pc in a call dummy for this frame. */ - CORE_ADDR possible_call_dummy_start = - (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12; - - int nextinsn; - memset (saved_regs, 0, sizeof (*saved_regs)); - if ((frame_info)->pc >= possible_call_dummy_start - && (frame_info)->pc <= (frame_info)->frame) - { - - /* It is a call dummy. We could just stop now, since we know - what the call dummy saves and where. But this code proceeds - to parse the "prologue" which is part of the call dummy. - This is needlessly complex and confusing. FIXME. */ - - next_addr = (frame_info)->frame; - pc = possible_call_dummy_start; - } - else - { - pc = get_pc_function_start ((frame_info)->pc); - - nextinsn = read_memory_integer (pc, 2); - if (P_PEA_FP == nextinsn - && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2)) - { - /* pea %fp - move.l %sp, %fp */ - next_addr = frame_info->frame; - pc += 4; - } - else if (P_LINKL_FP == nextinsn) - /* link.l %fp */ - /* Find the address above the saved - regs using the amount of storage from the link instruction. */ - { - next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4); - pc += 6; - } - else if (P_LINKW_FP == nextinsn) - /* link.w %fp */ - /* Find the address above the saved - regs using the amount of storage from the link instruction. */ - { - next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2); - pc += 4; - } - else - goto lose; - - /* If have an addal #-n, sp next, adjust next_addr. */ - if ((0177777 & read_memory_integer (pc, 2)) == 0157774) - next_addr += read_memory_integer (pc += 2, 4), pc += 4; - } - - for ( ; ; ) - { - nextinsn = 0xffff & read_memory_integer (pc, 2); - regmask = read_memory_integer (pc + 2, 2); - /* fmovemx to -(sp) */ - if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000) - { - /* Regmask's low bit is for register fp7, the first pushed */ - for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1) - if (regmask & 1) - saved_regs->regs[regnum] = (next_addr -= 12); - pc += 4; - } - /* fmovemx to (fp + displacement) */ - else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000) - { - register CORE_ADDR addr; - - addr = (frame_info)->frame + read_memory_integer (pc + 4, 2); - /* Regmask's low bit is for register fp7, the first pushed */ - for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1) - if (regmask & 1) - { - saved_regs->regs[regnum] = addr; - addr += 12; - } - pc += 6; - } - /* moveml to (sp) */ - else if (0044327 == nextinsn) - { - /* Regmask's low bit is for register 0, the first written */ - for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) - if (regmask & 1) - { - saved_regs->regs[regnum] = next_addr; - next_addr += 4; - } - pc += 4; - } - /* moveml to (fp + displacement) */ - else if (0044356 == nextinsn) - { - register CORE_ADDR addr; - - addr = (frame_info)->frame + read_memory_integer (pc + 4, 2); - /* Regmask's low bit is for register 0, the first written */ - for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) - if (regmask & 1) - { - saved_regs->regs[regnum] = addr; - addr += 4; - } - pc += 6; - } - /* moveml to -(sp) */ - else if (0044347 == nextinsn) - { - /* Regmask's low bit is for register 15, the first pushed */ - for (regnum = 16; --regnum >= 0; regmask >>= 1) - if (regmask & 1) - saved_regs->regs[regnum] = (next_addr -= 4); - pc += 4; - } - /* movl r,-(sp) */ - else if (0x2f00 == (0xfff0 & nextinsn)) - { - regnum = 0xf & nextinsn; - saved_regs->regs[regnum] = (next_addr -= 4); - pc += 2; - } - /* fmovemx to index of sp */ - else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000) - { - /* Regmask's low bit is for register fp0, the first written */ - for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1) - if (regmask & 1) - { - saved_regs->regs[regnum] = next_addr; - next_addr += 12; - } - pc += 10; - } - /* clrw -(sp); movw ccr,-(sp) */ - else if (0x4267 == nextinsn && 0x42e7 == regmask) - { - saved_regs->regs[PS_REGNUM] = (next_addr -= 4); - pc += 4; - } - else - break; - } -lose:; - saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8; - saved_regs->regs[FP_REGNUM] = (frame_info)->frame; - saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4; -#ifdef SIG_SP_FP_OFFSET - /* Adjust saved SP_REGNUM for fake _sigtramp frames. */ - if (frame_info->signal_handler_caller && frame_info->next) - saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET; -#endif -} - - -#ifdef USE_PROC_FS /* Target dependent support for /proc */ - -#include - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* The /proc interface divides the target machine's register set up into - two different sets, the general register set (gregset) and the floating - point register set (fpregset). For each set, there is an ioctl to get - the current register set and another ioctl to set the current values. - - The actual structure passed through the ioctl interface is, of course, - naturally machine dependent, and is different for each set of registers. - For the m68k for example, the general register set is typically defined - by: - - typedef int gregset_t[18]; - - #define R_D0 0 - ... - #define R_PS 17 - - and the floating point set by: - - typedef struct fpregset { - int f_pcr; - int f_psr; - int f_fpiaddr; - int f_fpregs[8][3]; (8 regs, 96 bits each) - } fpregset_t; - - These routines provide the packing and unpacking of gregset_t and - fpregset_t formatted data. - - */ - -/* Atari SVR4 has R_SR but not R_PS */ - -#if !defined (R_PS) && defined (R_SR) -#define R_PS R_SR -#endif - -/* Given a pointer to a general register set in /proc format (gregset_t *), - unpack the register contents and supply them as gdb's idea of the current - register values. */ - -void -supply_gregset (gregset_t *gregsetp) -{ - register int regi; - register greg_t *regp = (greg_t *) gregsetp; - - for (regi = 0; regi < R_PC; regi++) - { - supply_register (regi, (char *) (regp + regi)); - } - supply_register (PS_REGNUM, (char *) (regp + R_PS)); - supply_register (PC_REGNUM, (char *) (regp + R_PC)); -} - -void -fill_gregset (gregset_t *gregsetp, int regno) -{ - register int regi; - register greg_t *regp = (greg_t *) gregsetp; - - for (regi = 0; regi < R_PC; regi++) - { - if ((regno == -1) || (regno == regi)) - { - *(regp + regi) = *(int *) ®isters[REGISTER_BYTE (regi)]; - } - } - if ((regno == -1) || (regno == PS_REGNUM)) - { - *(regp + R_PS) = *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)]; - } - if ((regno == -1) || (regno == PC_REGNUM)) - { - *(regp + R_PC) = *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)]; - } -} - -#if defined (FP0_REGNUM) - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), unpack the register contents and supply them as gdb's - idea of the current floating point register values. */ - -void -supply_fpregset (fpregset_t *fpregsetp) -{ - register int regi; - char *from; - - for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++) - { - from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]); - supply_register (regi, from); - } - supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr)); - supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr)); - supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr)); -} - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), update the register specified by REGNO from gdb's idea - of the current floating point register set. If REGNO is -1, update - them all. */ - -void -fill_fpregset (fpregset_t *fpregsetp, int regno) -{ - int regi; - char *to; - char *from; - - for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++) - { - if ((regno == -1) || (regno == regi)) - { - from = (char *) ®isters[REGISTER_BYTE (regi)]; - to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]); - memcpy (to, from, REGISTER_RAW_SIZE (regi)); - } - } - if ((regno == -1) || (regno == FPC_REGNUM)) - { - fpregsetp->f_pcr = *(int *) ®isters[REGISTER_BYTE (FPC_REGNUM)]; - } - if ((regno == -1) || (regno == FPS_REGNUM)) - { - fpregsetp->f_psr = *(int *) ®isters[REGISTER_BYTE (FPS_REGNUM)]; - } - if ((regno == -1) || (regno == FPI_REGNUM)) - { - fpregsetp->f_fpiaddr = *(int *) ®isters[REGISTER_BYTE (FPI_REGNUM)]; - } -} - -#endif /* defined (FP0_REGNUM) */ - -#endif /* USE_PROC_FS */ - -/* Figure out where the longjmp will land. Slurp the args out of the stack. - We expect the first arg to be a pointer to the jmp_buf structure from which - we extract the pc (JB_PC) that we will land at. The pc is copied into PC. - This routine returns true on success. */ - -/* NOTE: cagney/2000-11-08: For this function to be fully multi-arched - the macro's JB_PC and JB_ELEMENT_SIZE would need to be moved into - the ``struct gdbarch_tdep'' object and then set on a target ISA/ABI - dependant basis. */ - -int -m68k_get_longjmp_target (CORE_ADDR *pc) -{ -#if defined (JB_PC) && defined (JB_ELEMENT_SIZE) - char *buf; - CORE_ADDR sp, jb_addr; - - buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT); - sp = read_register (SP_REGNUM); - - if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */ - buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) - return 0; - - jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); - - if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) - return 0; - - *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); - - return 1; -#else - internal_error (__FILE__, __LINE__, - "m68k_get_longjmp_target: not implemented"); - return 0; -#endif -} - -/* Immediately after a function call, return the saved pc before the frame - is setup. For sun3's, we check for the common case of being inside of a - system call, and if so, we know that Sun pushes the call # on the stack - prior to doing the trap. */ - -CORE_ADDR -m68k_saved_pc_after_call (struct frame_info *frame) -{ -#ifdef SYSCALL_TRAP - int op; - - op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2); - - if (op == SYSCALL_TRAP) - return read_memory_integer (read_register (SP_REGNUM) + 4, 4); - else -#endif /* SYSCALL_TRAP */ - return read_memory_integer (read_register (SP_REGNUM), 4); -} - - -void -_initialize_m68k_tdep (void) -{ - tm_print_insn = print_insn_m68k; -} diff --git a/contrib/gdb/gdb/m68klinux-nat.c b/contrib/gdb/gdb/m68klinux-nat.c deleted file mode 100644 index 82a6124a7aa..00000000000 --- a/contrib/gdb/gdb/m68klinux-nat.c +++ /dev/null @@ -1,710 +0,0 @@ -/* Motorola m68k native support for GNU/Linux. - - Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation, - Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "language.h" -#include "gdbcore.h" -#include "regcache.h" - -#ifdef USG -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_REG_H -#include -#endif - -#include -#include "gdb_stat.h" - -#include "floatformat.h" - -#include "target.h" - - -/* This table must line up with REGISTER_NAMES in tm-m68k.h */ -static const int regmap[] = -{ - PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7, - PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP, - PT_SR, PT_PC, - /* PT_FP0, ..., PT_FP7 */ - 21, 24, 27, 30, 33, 36, 39, 42, - /* PT_FPCR, PT_FPSR, PT_FPIAR */ - 45, 46, 47 -}; - -/* Which ptrace request retrieves which registers? - These apply to the corresponding SET requests as well. */ -#define NUM_GREGS (18) -#define MAX_NUM_REGS (NUM_GREGS + 11) - -int -getregs_supplies (int regno) -{ - return 0 <= regno && regno < NUM_GREGS; -} - -int -getfpregs_supplies (int regno) -{ - return FP0_REGNUM <= regno && regno <= FPI_REGNUM; -} - -/* Does the current host support the GETREGS request? */ -int have_ptrace_getregs = -#ifdef HAVE_PTRACE_GETREGS - 1 -#else - 0 -#endif -; - - - -/* BLOCKEND is the value of u.u_ar0, and points to the place where GS - is stored. */ - -int -m68k_linux_register_u_addr (int blockend, int regnum) -{ - return (blockend + 4 * regmap[regnum]); -} - - -/* Fetching registers directly from the U area, one at a time. */ - -/* FIXME: This duplicates code from `inptrace.c'. The problem is that we - define FETCH_INFERIOR_REGISTERS since we want to use our own versions - of {fetch,store}_inferior_registers that use the GETREGS request. This - means that the code in `infptrace.c' is #ifdef'd out. But we need to - fall back on that code when GDB is running on top of a kernel that - doesn't support the GETREGS request. */ - -#ifndef PT_READ_U -#define PT_READ_U PTRACE_PEEKUSR -#endif -#ifndef PT_WRITE_U -#define PT_WRITE_U PTRACE_POKEUSR -#endif - -/* Default the type of the ptrace transfer to int. */ -#ifndef PTRACE_XFER_TYPE -#define PTRACE_XFER_TYPE int -#endif - -/* Fetch one register. */ - -static void -fetch_register (int regno) -{ - /* This isn't really an address. But ptrace thinks of it as one. */ - CORE_ADDR regaddr; - char mess[128]; /* For messages */ - register int i; - unsigned int offset; /* Offset of registers within the u area. */ - char buf[MAX_REGISTER_RAW_SIZE]; - int tid; - - if (CANNOT_FETCH_REGISTER (regno)) - { - memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ - supply_register (regno, buf); - return; - } - - /* Overload thread id onto process id */ - if ((tid = TIDGET (inferior_ptid)) == 0) - tid = PIDGET (inferior_ptid); /* no thread id, just use process id */ - - offset = U_REGS_OFFSET; - - regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid, - (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (PTRACE_XFER_TYPE); - if (errno != 0) - { - sprintf (mess, "reading register %s (#%d)", - REGISTER_NAME (regno), regno); - perror_with_name (mess); - } - } - supply_register (regno, buf); -} - -/* Fetch register values from the inferior. - If REGNO is negative, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -old_fetch_inferior_registers (int regno) -{ - if (regno >= 0) - { - fetch_register (regno); - } - else - { - for (regno = 0; regno < NUM_REGS; regno++) - { - fetch_register (regno); - } - } -} - -/* Store one register. */ - -static void -store_register (int regno) -{ - /* This isn't really an address. But ptrace thinks of it as one. */ - CORE_ADDR regaddr; - char mess[128]; /* For messages */ - register int i; - unsigned int offset; /* Offset of registers within the u area. */ - int tid; - char *buf = alloca (MAX_REGISTER_RAW_SIZE); - - if (CANNOT_STORE_REGISTER (regno)) - { - return; - } - - /* Overload thread id onto process id */ - if ((tid = TIDGET (inferior_ptid)) == 0) - tid = PIDGET (inferior_ptid); /* no thread id, just use process id */ - - offset = U_REGS_OFFSET; - - regaddr = register_addr (regno, offset); - - /* Put the contents of regno into a local buffer */ - regcache_collect (regno, buf); - - /* Store the local buffer into the inferior a chunk at the time. */ - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr, - *(PTRACE_XFER_TYPE *) (buf + i)); - regaddr += sizeof (PTRACE_XFER_TYPE); - if (errno != 0) - { - sprintf (mess, "writing register %s (#%d)", - REGISTER_NAME (regno), regno); - perror_with_name (mess); - } - } -} - -/* Store our register values back into the inferior. - If REGNO is negative, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -old_store_inferior_registers (int regno) -{ - if (regno >= 0) - { - store_register (regno); - } - else - { - for (regno = 0; regno < NUM_REGS; regno++) - { - store_register (regno); - } - } -} - -/* Given a pointer to a general register set in /proc format - (elf_gregset_t *), unpack the register contents and supply - them as gdb's idea of the current register values. */ - - -/* Note both m68k-tdep.c and m68klinux-nat.c contain definitions - for supply_gregset and supply_fpregset. The definitions - in m68k-tdep.c are valid if USE_PROC_FS is defined. Otherwise, - the definitions in m68klinux-nat.c will be used. This is a - bit of a hack. The supply_* routines do not belong in - *_tdep.c files. But, there are several lynx ports that currently - depend on these definitions. */ - -#ifndef USE_PROC_FS - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -void -supply_gregset (elf_gregset_t *gregsetp) -{ - elf_greg_t *regp = (elf_greg_t *) gregsetp; - int regi; - - for (regi = D0_REGNUM; regi <= SP_REGNUM; regi++) - supply_register (regi, (char *) ®p[regmap[regi]]); - supply_register (PS_REGNUM, (char *) ®p[PT_SR]); - supply_register (PC_REGNUM, (char *) ®p[PT_PC]); -} - -/* Fill register REGNO (if it is a general-purpose register) in - *GREGSETPS with the value in GDB's register array. If REGNO is -1, - do this for all registers. */ -void -fill_gregset (elf_gregset_t *gregsetp, int regno) -{ - elf_greg_t *regp = (elf_greg_t *) gregsetp; - int i; - - for (i = 0; i < NUM_GREGS; i++) - if ((regno == -1 || regno == i)) - regcache_collect (i, regp + regmap[i]); -} - -#ifdef HAVE_PTRACE_GETREGS - -/* Fetch all general-purpose registers from process/thread TID and - store their values in GDB's register array. */ - -static void -fetch_regs (int tid) -{ - elf_gregset_t regs; - - if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0) - { - if (errno == EIO) - { - /* The kernel we're running on doesn't support the GETREGS - request. Reset `have_ptrace_getregs'. */ - have_ptrace_getregs = 0; - return; - } - - perror_with_name ("Couldn't get registers"); - } - - supply_gregset (®s); -} - -/* Store all valid general-purpose registers in GDB's register array - into the process/thread specified by TID. */ - -static void -store_regs (int tid, int regno) -{ - elf_gregset_t regs; - - if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0) - perror_with_name ("Couldn't get registers"); - - fill_gregset (®s, regno); - - if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0) - perror_with_name ("Couldn't write registers"); -} - -#else - -static void fetch_regs (int tid) {} -static void store_regs (int tid, int regno) {} - -#endif - - -/* Transfering floating-point registers between GDB, inferiors and cores. */ - -/* What is the address of fpN within the floating-point register set F? */ -#define FPREG_ADDR(f, n) ((char *) &(f)->fpregs[(n) * 3]) - -/* Fill GDB's register array with the floating-point register values in - *FPREGSETP. */ - -void -supply_fpregset (elf_fpregset_t *fpregsetp) -{ - int regi; - - for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++) - supply_register (regi, FPREG_ADDR (fpregsetp, regi - FP0_REGNUM)); - supply_register (FPC_REGNUM, (char *) &fpregsetp->fpcntl[0]); - supply_register (FPS_REGNUM, (char *) &fpregsetp->fpcntl[1]); - supply_register (FPI_REGNUM, (char *) &fpregsetp->fpcntl[2]); -} - -/* Fill register REGNO (if it is a floating-point register) in - *FPREGSETP with the value in GDB's register array. If REGNO is -1, - do this for all registers. */ - -void -fill_fpregset (elf_fpregset_t *fpregsetp, int regno) -{ - int i; - - /* Fill in the floating-point registers. */ - for (i = FP0_REGNUM; i < FP0_REGNUM + 8; i++) - if (regno == -1 || regno == i) - regcache_collect (regno, FPREG_ADDR (fpregsetp, regno - FP0_REGNUM)); - - /* Fill in the floating-point control registers. */ - for (i = FPC_REGNUM; i <= FPI_REGNUM; i++) - if (regno == -1 || regno == i) - regcache_collect (regno, (char *) &fpregsetp->fpcntl[regno - FPC_REGNUM]); -} - -#ifdef HAVE_PTRACE_GETREGS - -/* Fetch all floating-point registers from process/thread TID and store - thier values in GDB's register array. */ - -static void -fetch_fpregs (int tid) -{ - elf_fpregset_t fpregs; - - if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0) - perror_with_name ("Couldn't get floating point status"); - - supply_fpregset (&fpregs); -} - -/* Store all valid floating-point registers in GDB's register array - into the process/thread specified by TID. */ - -static void -store_fpregs (int tid, int regno) -{ - elf_fpregset_t fpregs; - - if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0) - perror_with_name ("Couldn't get floating point status"); - - fill_fpregset (&fpregs, regno); - - if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0) - perror_with_name ("Couldn't write floating point status"); -} - -#else - -static void fetch_fpregs (int tid) {} -static void store_fpregs (int tid, int regno) {} - -#endif - -#endif - -/* Transferring arbitrary registers between GDB and inferior. */ - -/* Fetch register REGNO from the child process. If REGNO is -1, do - this for all registers (including the floating point and SSE - registers). */ - -void -fetch_inferior_registers (int regno) -{ - int tid; - - /* Use the old method of peeking around in `struct user' if the - GETREGS request isn't available. */ - if (! have_ptrace_getregs) - { - old_fetch_inferior_registers (regno); - return; - } - - /* GNU/Linux LWP ID's are process ID's. */ - if ((tid = TIDGET (inferior_ptid)) == 0) - tid = PIDGET (inferior_ptid); /* Not a threaded program. */ - - /* Use the PTRACE_GETFPXREGS request whenever possible, since it - transfers more registers in one system call, and we'll cache the - results. But remember that fetch_fpxregs can fail, and return - zero. */ - if (regno == -1) - { - fetch_regs (tid); - - /* The call above might reset `have_ptrace_getregs'. */ - if (! have_ptrace_getregs) - { - old_fetch_inferior_registers (-1); - return; - } - - fetch_fpregs (tid); - return; - } - - if (getregs_supplies (regno)) - { - fetch_regs (tid); - return; - } - - if (getfpregs_supplies (regno)) - { - fetch_fpregs (tid); - return; - } - - internal_error (__FILE__, __LINE__, - "Got request for bad register number %d.", regno); -} - -/* Store register REGNO back into the child process. If REGNO is -1, - do this for all registers (including the floating point and SSE - registers). */ -void -store_inferior_registers (int regno) -{ - int tid; - - /* Use the old method of poking around in `struct user' if the - SETREGS request isn't available. */ - if (! have_ptrace_getregs) - { - old_store_inferior_registers (regno); - return; - } - - /* GNU/Linux LWP ID's are process ID's. */ - if ((tid = TIDGET (inferior_ptid)) == 0) - tid = PIDGET (inferior_ptid); /* Not a threaded program. */ - - /* Use the PTRACE_SETFPREGS requests whenever possible, since it - transfers more registers in one system call. But remember that - store_fpregs can fail, and return zero. */ - if (regno == -1) - { - store_regs (tid, regno); - store_fpregs (tid, regno); - return; - } - - if (getregs_supplies (regno)) - { - store_regs (tid, regno); - return; - } - - if (getfpregs_supplies (regno)) - { - store_fpregs (tid, regno); - return; - } - - internal_error (__FILE__, __LINE__, - "Got request to store bad register number %d.", regno); -} - -/* Interpreting register set info found in core files. */ - -/* Provide registers to GDB from a core file. - - (We can't use the generic version of this function in - core-regset.c, because we need to use elf_gregset_t instead of - gregset_t.) - - CORE_REG_SECT points to an array of bytes, which are the contents - of a `note' from a core file which BFD thinks might contain - register contents. CORE_REG_SIZE is its size. - - WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set, in elf_gregset_t format - 2 --- the floating-point register set, in elf_fpregset_t format - - REG_ADDR isn't used on GNU/Linux. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) -{ - elf_gregset_t gregset; - elf_fpregset_t fpregset; - - switch (which) - { - case 0: - if (core_reg_size != sizeof (gregset)) - warning ("Wrong size gregset in core file."); - else - { - memcpy (&gregset, core_reg_sect, sizeof (gregset)); - supply_gregset (&gregset); - } - break; - - case 2: - if (core_reg_size != sizeof (fpregset)) - warning ("Wrong size fpregset in core file."); - else - { - memcpy (&fpregset, core_reg_sect, sizeof (fpregset)); - supply_fpregset (&fpregset); - } - break; - - default: - /* We've covered all the kinds of registers we know about here, - so this must be something we wouldn't know what to do with - anyway. Just ignore it. */ - break; - } -} - - -int -kernel_u_size (void) -{ - return (sizeof (struct user)); -} - -/* Check whether insn1 and insn2 are parts of a signal trampoline. */ - -#define IS_SIGTRAMP(insn1, insn2) \ - (/* addaw #20,sp; moveq #119,d0; trap #0 */ \ - (insn1 == 0xdefc0014 && insn2 == 0x70774e40) \ - /* moveq #119,d0; trap #0 */ \ - || insn1 == 0x70774e40) - -#define IS_RT_SIGTRAMP(insn1, insn2) \ - (/* movel #173,d0; trap #0 */ \ - (insn1 == 0x203c0000 && insn2 == 0x00ad4e40) \ - /* moveq #82,d0; notb d0; trap #0 */ \ - || (insn1 == 0x70524600 && (insn2 >> 16) == 0x4e40)) - -/* Return non-zero if PC points into the signal trampoline. For the sake - of m68k_linux_frame_saved_pc we also distinguish between non-RT and RT - signal trampolines. */ - -int -m68k_linux_in_sigtramp (CORE_ADDR pc) -{ - CORE_ADDR sp; - char buf[12]; - unsigned long insn0, insn1, insn2; - - if (read_memory_nobpt (pc - 4, buf, sizeof (buf))) - return 0; - insn1 = extract_unsigned_integer (buf + 4, 4); - insn2 = extract_unsigned_integer (buf + 8, 4); - if (IS_SIGTRAMP (insn1, insn2)) - return 1; - if (IS_RT_SIGTRAMP (insn1, insn2)) - return 2; - - insn0 = extract_unsigned_integer (buf, 4); - if (IS_SIGTRAMP (insn0, insn1)) - return 1; - if (IS_RT_SIGTRAMP (insn0, insn1)) - return 2; - - insn0 = (insn0 << 16) | (insn1 >> 16); - insn1 = (insn1 << 16) | (insn2 >> 16); - if (IS_SIGTRAMP (insn0, insn1)) - return 1; - if (IS_RT_SIGTRAMP (insn0, insn1)) - return 2; - - return 0; -} - -/* Offset to saved PC in sigcontext, from . */ -#define SIGCONTEXT_PC_OFFSET 26 - -/* Offset to saved PC in ucontext, from . */ -#define UCONTEXT_PC_OFFSET 88 - -/* Get saved user PC for sigtramp from sigcontext or ucontext. */ - -static CORE_ADDR -m68k_linux_sigtramp_saved_pc (struct frame_info *frame) -{ - CORE_ADDR sigcontext_addr; - char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; - int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT; - int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT; - - /* Get sigcontext address, it is the third parameter on the stack. */ - if (frame->next) - sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next) - + FRAME_ARGS_SKIP - + sigcontext_offs, - ptrbytes); - else - sigcontext_addr = read_memory_integer (read_register (SP_REGNUM) - + sigcontext_offs, - ptrbytes); - - /* Don't cause a memory_error when accessing sigcontext in case the - stack layout has changed or the stack is corrupt. */ - if (m68k_linux_in_sigtramp (frame->pc) == 2) - target_read_memory (sigcontext_addr + UCONTEXT_PC_OFFSET, buf, ptrbytes); - else - target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes); - return extract_unsigned_integer (buf, ptrbytes); -} - -/* Return the saved program counter for FRAME. */ - -CORE_ADDR -m68k_linux_frame_saved_pc (struct frame_info *frame) -{ - if (frame->signal_handler_caller) - return m68k_linux_sigtramp_saved_pc (frame); - - return read_memory_integer (frame->frame + 4, 4); -} - -/* Register that we are able to handle GNU/Linux ELF core file - formats. */ - -static struct core_fns linux_elf_core_fns = -{ - bfd_target_elf_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_m68k_linux_nat () -{ - add_core_fns (&linux_elf_core_fns); -} diff --git a/contrib/gdb/gdb/m68knbsd-nat.c b/contrib/gdb/gdb/m68knbsd-nat.c deleted file mode 100644 index ec986eeb364..00000000000 --- a/contrib/gdb/gdb/m68knbsd-nat.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Native-dependent code for Motorola m68k's running NetBSD, for GDB. - Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include -#include -#include -#include -#include "inferior.h" -#include "gdbcore.h" -#include "regcache.h" - -void -fetch_inferior_registers (int regno) -{ - struct reg inferior_registers; - struct fpreg inferior_fp_registers; - - ptrace (PT_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0); - memcpy (®isters[REGISTER_BYTE (0)], &inferior_registers, - sizeof (inferior_registers)); - - ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0); - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, - sizeof (inferior_fp_registers)); - - registers_fetched (); -} - -void -store_inferior_registers (int regno) -{ - struct reg inferior_registers; - struct fpreg inferior_fp_registers; - - memcpy (&inferior_registers, ®isters[REGISTER_BYTE (0)], - sizeof (inferior_registers)); - ptrace (PT_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0); - - memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], - sizeof (inferior_fp_registers)); - ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0); -} - -struct md_core -{ - struct reg intreg; - struct fpreg freg; -}; - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR ignore) -{ - struct md_core *core_reg = (struct md_core *) core_reg_sect; - - /* Integer registers */ - memcpy (®isters[REGISTER_BYTE (0)], - &core_reg->intreg, sizeof (struct reg)); - /* Floating point registers */ - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], - &core_reg->freg, sizeof (struct fpreg)); -} - -/* Register that we are able to handle m68knbsd core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns m68knbsd_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_m68knbsd_nat (void) -{ - add_core_fns (&m68knbsd_core_fns); -} diff --git a/contrib/gdb/gdb/m88k-nat.c b/contrib/gdb/gdb/m88k-nat.c deleted file mode 100644 index b631cda2735..00000000000 --- a/contrib/gdb/gdb/m88k-nat.c +++ /dev/null @@ -1,290 +0,0 @@ -/* Native-dependent Motorola 88xxx support for GDB, the GNU Debugger. - Copyright 1988, 1990, 1991, 1992, 1993, 1995, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "regcache.h" - -#include -#include -#include -#include -#include "gdbcore.h" -#include - -#ifndef USER /* added to support BCS ptrace_user */ -#define USER ptrace_user -#endif -#include -#include -#include -#include "gdb_stat.h" - -#include "symtab.h" -#include "setjmp.h" -#include "value.h" - -#ifdef DELTA88 -#include - -/* define offsets to the pc instruction offsets in ptrace_user struct */ -#define SXIP_OFFSET ((char *)&u.pt_sigframe.sig_sxip - (char *)&u) -#define SNIP_OFFSET ((char *)&u.pt_sigframe.sig_snip - (char *)&u) -#define SFIP_OFFSET ((char *)&u.pt_sigframe.sig_sfip - (char *)&u) -#else -/* define offsets to the pc instruction offsets in ptrace_user struct */ -#define SXIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sxip - (char *)&u) -#define SNIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_snip - (char *)&u) -#define SFIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u) -#endif - -extern int have_symbol_file_p (); - -extern jmp_buf stack_jmp; - -extern int errno; - -void -fetch_inferior_registers (int regno) -{ - register unsigned int regaddr; - char buf[MAX_REGISTER_RAW_SIZE]; - register int i; - - struct USER u; - unsigned int offset; - - offset = (char *) &u.pt_r0 - (char *) &u; - regaddr = offset; /* byte offset to r0; */ - -/* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */ - for (regno = 0; regno < NUM_REGS; regno++) - { - /*regaddr = register_addr (regno, offset); */ - /* 88k enhancement */ - - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - *(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (int); - } - supply_register (regno, buf); - } - /* now load up registers 36 - 38; special pc registers */ - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SXIP_OFFSET, 0); - supply_register (SXIP_REGNUM, buf); - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SNIP_OFFSET, 0); - supply_register (SNIP_REGNUM, buf); - *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SFIP_OFFSET, 0); - supply_register (SFIP_REGNUM, buf); -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (int regno) -{ - register unsigned int regaddr; - char buf[80]; - - struct USER u; - - unsigned int offset = (char *) &u.pt_r0 - (char *) &u; - - regaddr = offset; - - /* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either - svr3 doesn't run on an 88110, or the kernel isolates the different (not - completely sure this is true, but seems to be. */ - if (regno >= 0) - { - /* regaddr = register_addr (regno, offset); */ - if (regno < PC_REGNUM) - { - regaddr = offset + regno * sizeof (int); - errno = 0; - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) regaddr, read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } - else if (regno == SXIP_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (regno)); - else if (regno == SNIP_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (regno)); - else if (regno == SFIP_REGNUM) - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (regno)); - else - printf_unfiltered ("Bad register number for store_inferior routine\n"); - } - else - { - for (regno = 0; regno < PC_REGNUM; regno++) - { - /* regaddr = register_addr (regno, offset); */ - errno = 0; - regaddr = offset + regno * sizeof (int); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) regaddr, read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (SXIP_REGNUM)); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (SNIP_REGNUM)); - ptrace (6, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (SFIP_REGNUM)); - } -} - - -/* blockend is the address of the end of the user structure */ -m88k_register_u_addr (int blockend, int regnum) -{ - struct USER u; - int ustart = blockend - sizeof (struct USER); - switch (regnum) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - return (ustart + ((int) &u.pt_r0 - (int) &u) + REGISTER_SIZE * regnum); - case PSR_REGNUM: - return (ustart + ((int) &u.pt_psr - (int) &u)); - case FPSR_REGNUM: - return (ustart + ((int) &u.pt_fpsr - (int) &u)); - case FPCR_REGNUM: - return (ustart + ((int) &u.pt_fpcr - (int) &u)); - case SXIP_REGNUM: - return (ustart + SXIP_OFFSET); - case SNIP_REGNUM: - return (ustart + SNIP_OFFSET); - case SFIP_REGNUM: - return (ustart + SFIP_OFFSET); - default: - if (regnum < NUM_REGS) - /* The register is one of those which is not defined... - give it zero */ - return (ustart + ((int) &u.pt_r0 - (int) &u)); - else - return (blockend + REGISTER_SIZE * regnum); - } -} - -#ifdef USE_PROC_FS - -#include - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* Given a pointer to a general register set in /proc format (gregset_t *), - unpack the register contents and supply them as gdb's idea of the current - register values. */ - -void -supply_gregset (gregset_t *gregsetp) -{ - register int regi; - register greg_t *regp = (greg_t *) gregsetp; - - for (regi = 0; regi <= SP_REGNUM; regi++) - supply_register (regi, (char *) (regp + regi)); - - supply_register (SXIP_REGNUM, (char *) (regp + R_XIP)); - supply_register (SNIP_REGNUM, (char *) (regp + R_NIP)); - supply_register (SFIP_REGNUM, (char *) (regp + R_FIP)); - supply_register (PSR_REGNUM, (char *) (regp + R_PSR)); - supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR)); - supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR)); -} - -void -fill_gregset (gregset_t *gregsetp, int regno) -{ - int regi; - register greg_t *regp = (greg_t *) gregsetp; - - for (regi = 0; regi <= R_R31; regi++) - if ((regno == -1) || (regno == regi)) - *(regp + regi) = *(int *) ®isters[REGISTER_BYTE (regi)]; - - if ((regno == -1) || (regno == SXIP_REGNUM)) - *(regp + R_XIP) = *(int *) ®isters[REGISTER_BYTE (SXIP_REGNUM)]; - if ((regno == -1) || (regno == SNIP_REGNUM)) - *(regp + R_NIP) = *(int *) ®isters[REGISTER_BYTE (SNIP_REGNUM)]; - if ((regno == -1) || (regno == SFIP_REGNUM)) - *(regp + R_FIP) = *(int *) ®isters[REGISTER_BYTE (SFIP_REGNUM)]; - if ((regno == -1) || (regno == PSR_REGNUM)) - *(regp + R_PSR) = *(int *) ®isters[REGISTER_BYTE (PSR_REGNUM)]; - if ((regno == -1) || (regno == FPSR_REGNUM)) - *(regp + R_FPSR) = *(int *) ®isters[REGISTER_BYTE (FPSR_REGNUM)]; - if ((regno == -1) || (regno == FPCR_REGNUM)) - *(regp + R_FPCR) = *(int *) ®isters[REGISTER_BYTE (FPCR_REGNUM)]; -} - -#endif /* USE_PROC_FS */ diff --git a/contrib/gdb/gdb/m88k-tdep.c b/contrib/gdb/gdb/m88k-tdep.c deleted file mode 100644 index 86ca0982bfe..00000000000 --- a/contrib/gdb/gdb/m88k-tdep.c +++ /dev/null @@ -1,634 +0,0 @@ -/* Target-machine dependent code for Motorola 88000 series, for GDB. - Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, - 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "value.h" -#include "gdbcore.h" -#include "symtab.h" -#include "setjmp.h" -#include "value.h" -#include "regcache.h" - -/* Size of an instruction */ -#define BYTES_PER_88K_INSN 4 - -void frame_find_saved_regs (); - -/* Is this target an m88110? Otherwise assume m88100. This has - relevance for the ways in which we screw with instruction pointers. */ - -int target_is_m88110 = 0; - -/* The type of a register. */ -struct type * -m88k_register_type (int regnum) -{ - if (regnum >= XFP_REGNUM) - return builtin_type_m88110_ext; - else if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM) - return builtin_type_void_func_ptr; - else - return builtin_type_int32; -} - - -/* The m88k kernel aligns all instructions on 4-byte boundaries. The - kernel also uses the least significant two bits for its own hocus - pocus. When gdb receives an address from the kernel, it needs to - preserve those right-most two bits, but gdb also needs to be careful - to realize that those two bits are not really a part of the address - of an instruction. Shrug. */ - -CORE_ADDR -m88k_addr_bits_remove (CORE_ADDR addr) -{ - return ((addr) & ~3); -} - - -/* Given a GDB frame, determine the address of the calling function's frame. - This will be used to create a new GDB frame struct, and then - INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. - - For us, the frame address is its stack pointer value, so we look up - the function prologue to determine the caller's sp value, and return it. */ - -CORE_ADDR -frame_chain (struct frame_info *thisframe) -{ - - frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0); - /* NOTE: this depends on frame_find_saved_regs returning the VALUE, not - the ADDRESS, of SP_REGNUM. It also depends on the cache of - frame_find_saved_regs results. */ - if (thisframe->fsr->regs[SP_REGNUM]) - return thisframe->fsr->regs[SP_REGNUM]; - else - return thisframe->frame; /* Leaf fn -- next frame up has same SP. */ -} - -int -frameless_function_invocation (struct frame_info *frame) -{ - - frame_find_saved_regs (frame, (struct frame_saved_regs *) 0); - /* NOTE: this depends on frame_find_saved_regs returning the VALUE, not - the ADDRESS, of SP_REGNUM. It also depends on the cache of - frame_find_saved_regs results. */ - if (frame->fsr->regs[SP_REGNUM]) - return 0; /* Frameful -- return addr saved somewhere */ - else - return 1; /* Frameless -- no saved return address */ -} - -void -init_extra_frame_info (int fromleaf, struct frame_info *frame) -{ - frame->fsr = 0; /* Not yet allocated */ - frame->args_pointer = 0; /* Unknown */ - frame->locals_pointer = 0; /* Unknown */ -} - -/* Examine an m88k function prologue, recording the addresses at which - registers are saved explicitly by the prologue code, and returning - the address of the first instruction after the prologue (but not - after the instruction at address LIMIT, as explained below). - - LIMIT places an upper bound on addresses of the instructions to be - examined. If the prologue code scan reaches LIMIT, the scan is - aborted and LIMIT is returned. This is used, when examining the - prologue for the current frame, to keep examine_prologue () from - claiming that a given register has been saved when in fact the - instruction that saves it has not yet been executed. LIMIT is used - at other times to stop the scan when we hit code after the true - function prologue (e.g. for the first source line) which might - otherwise be mistaken for function prologue. - - The format of the function prologue matched by this routine is - derived from examination of the source to gcc 1.95, particularly - the routine output_prologue () in config/out-m88k.c. - - subu r31,r31,n # stack pointer update - - (st rn,r31,offset)? # save incoming regs - (st.d rn,r31,offset)? - - (addu r30,r31,n)? # frame pointer update - - (pic sequence)? # PIC code prologue - - (or rn,rm,0)? # Move parameters to other regs - */ - -/* Macros for extracting fields from instructions. */ - -#define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos)) -#define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width)) -#define SUBU_OFFSET(x) ((unsigned)(x & 0xFFFF)) -#define ST_OFFSET(x) ((unsigned)((x) & 0xFFFF)) -#define ST_SRC(x) EXTRACT_FIELD ((x), 21, 5) -#define ADDU_OFFSET(x) ((unsigned)(x & 0xFFFF)) - -/* - * prologue_insn_tbl is a table of instructions which may comprise a - * function prologue. Associated with each table entry (corresponding - * to a single instruction or group of instructions), is an action. - * This action is used by examine_prologue (below) to determine - * the state of certain machine registers and where the stack frame lives. - */ - -enum prologue_insn_action -{ - PIA_SKIP, /* don't care what the instruction does */ - PIA_NOTE_ST, /* note register stored and where */ - PIA_NOTE_STD, /* note pair of registers stored and where */ - PIA_NOTE_SP_ADJUSTMENT, /* note stack pointer adjustment */ - PIA_NOTE_FP_ASSIGNMENT, /* note frame pointer assignment */ - PIA_NOTE_PROLOGUE_END, /* no more prologue */ -}; - -struct prologue_insns - { - unsigned long insn; - unsigned long mask; - enum prologue_insn_action action; - }; - -struct prologue_insns prologue_insn_tbl[] = -{ - /* Various register move instructions */ - {0x58000000, 0xf800ffff, PIA_SKIP}, /* or/or.u with immed of 0 */ - {0xf4005800, 0xfc1fffe0, PIA_SKIP}, /* or rd, r0, rs */ - {0xf4005800, 0xfc00ffff, PIA_SKIP}, /* or rd, rs, r0 */ - - /* Stack pointer setup: "subu sp, sp, n" where n is a multiple of 8 */ - {0x67ff0000, 0xffff0007, PIA_NOTE_SP_ADJUSTMENT}, - - /* Frame pointer assignment: "addu r30, r31, n" */ - {0x63df0000, 0xffff0000, PIA_NOTE_FP_ASSIGNMENT}, - - /* Store to stack instructions; either "st rx, sp, n" or "st.d rx, sp, n" */ - {0x241f0000, 0xfc1f0000, PIA_NOTE_ST}, /* st rx, sp, n */ - {0x201f0000, 0xfc1f0000, PIA_NOTE_STD}, /* st.d rs, sp, n */ - - /* Instructions needed for setting up r25 for pic code. */ - {0x5f200000, 0xffff0000, PIA_SKIP}, /* or.u r25, r0, offset_high */ - {0xcc000002, 0xffffffff, PIA_SKIP}, /* bsr.n Lab */ - {0x5b390000, 0xffff0000, PIA_SKIP}, /* or r25, r25, offset_low */ - {0xf7396001, 0xffffffff, PIA_SKIP}, /* Lab: addu r25, r25, r1 */ - - /* Various branch or jump instructions which have a delay slot -- these - do not form part of the prologue, but the instruction in the delay - slot might be a store instruction which should be noted. */ - {0xc4000000, 0xe4000000, PIA_NOTE_PROLOGUE_END}, - /* br.n, bsr.n, bb0.n, or bb1.n */ - {0xec000000, 0xfc000000, PIA_NOTE_PROLOGUE_END}, /* bcnd.n */ - {0xf400c400, 0xfffff7e0, PIA_NOTE_PROLOGUE_END} /* jmp.n or jsr.n */ - -}; - - -/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or - is not the address of a valid instruction, the address of the next - instruction beyond ADDR otherwise. *PWORD1 receives the first word - of the instruction. */ - -#define NEXT_PROLOGUE_INSN(addr, lim, pword1) \ - (((addr) < (lim)) ? next_insn (addr, pword1) : 0) - -/* Read the m88k instruction at 'memaddr' and return the address of - the next instruction after that, or 0 if 'memaddr' is not the - address of a valid instruction. The instruction - is stored at 'pword1'. */ - -CORE_ADDR -next_insn (CORE_ADDR memaddr, unsigned long *pword1) -{ - *pword1 = read_memory_integer (memaddr, BYTES_PER_88K_INSN); - return memaddr + BYTES_PER_88K_INSN; -} - -/* Read a register from frames called by us (or from the hardware regs). */ - -static int -read_next_frame_reg (struct frame_info *frame, int regno) -{ - for (; frame; frame = frame->next) - { - if (regno == SP_REGNUM) - return FRAME_FP (frame); - else if (frame->fsr->regs[regno]) - return read_memory_integer (frame->fsr->regs[regno], 4); - } - return read_register (regno); -} - -/* Examine the prologue of a function. `ip' points to the first instruction. - `limit' is the limit of the prologue (e.g. the addr of the first - linenumber, or perhaps the program counter if we're stepping through). - `frame_sp' is the stack pointer value in use in this frame. - `fsr' is a pointer to a frame_saved_regs structure into which we put - info about the registers saved by this frame. - `fi' is a struct frame_info pointer; we fill in various fields in it - to reflect the offsets of the arg pointer and the locals pointer. */ - -static CORE_ADDR -examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit, - CORE_ADDR frame_sp, struct frame_saved_regs *fsr, - struct frame_info *fi) -{ - register CORE_ADDR next_ip; - register int src; - unsigned long insn; - int size, offset; - char must_adjust[32]; /* If set, must adjust offsets in fsr */ - int sp_offset = -1; /* -1 means not set (valid must be mult of 8) */ - int fp_offset = -1; /* -1 means not set */ - CORE_ADDR frame_fp; - CORE_ADDR prologue_end = 0; - - memset (must_adjust, '\0', sizeof (must_adjust)); - next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn); - - while (next_ip) - { - struct prologue_insns *pip; - - for (pip = prologue_insn_tbl; (insn & pip->mask) != pip->insn;) - if (++pip >= prologue_insn_tbl + sizeof prologue_insn_tbl) - goto end_of_prologue_found; /* not a prologue insn */ - - switch (pip->action) - { - case PIA_NOTE_ST: - case PIA_NOTE_STD: - if (sp_offset != -1) - { - src = ST_SRC (insn); - offset = ST_OFFSET (insn); - must_adjust[src] = 1; - fsr->regs[src++] = offset; /* Will be adjusted later */ - if (pip->action == PIA_NOTE_STD && src < 32) - { - offset += 4; - must_adjust[src] = 1; - fsr->regs[src++] = offset; - } - } - else - goto end_of_prologue_found; - break; - case PIA_NOTE_SP_ADJUSTMENT: - if (sp_offset == -1) - sp_offset = -SUBU_OFFSET (insn); - else - goto end_of_prologue_found; - break; - case PIA_NOTE_FP_ASSIGNMENT: - if (fp_offset == -1) - fp_offset = ADDU_OFFSET (insn); - else - goto end_of_prologue_found; - break; - case PIA_NOTE_PROLOGUE_END: - if (!prologue_end) - prologue_end = ip; - break; - case PIA_SKIP: - default: - /* Do nothing */ - break; - } - - ip = next_ip; - next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn); - } - -end_of_prologue_found: - - if (prologue_end) - ip = prologue_end; - - /* We're done with the prologue. If we don't care about the stack - frame itself, just return. (Note that fsr->regs has been trashed, - but the one caller who calls with fi==0 passes a dummy there.) */ - - if (fi == 0) - return ip; - - /* - OK, now we have: - - sp_offset original (before any alloca calls) displacement of SP - (will be negative). - - fp_offset displacement from original SP to the FP for this frame - or -1. - - fsr->regs[0..31] displacement from original SP to the stack - location where reg[0..31] is stored. - - must_adjust[0..31] set if corresponding offset was set. - - If alloca has been called between the function prologue and the current - IP, then the current SP (frame_sp) will not be the original SP as set by - the function prologue. If the current SP is not the original SP, then the - compiler will have allocated an FP for this frame, fp_offset will be set, - and we can use it to calculate the original SP. - - Then, we figure out where the arguments and locals are, and relocate the - offsets in fsr->regs to absolute addresses. */ - - if (fp_offset != -1) - { - /* We have a frame pointer, so get it, and base our calc's on it. */ - frame_fp = (CORE_ADDR) read_next_frame_reg (fi->next, ACTUAL_FP_REGNUM); - frame_sp = frame_fp - fp_offset; - } - else - { - /* We have no frame pointer, therefore frame_sp is still the same value - as set by prologue. But where is the frame itself? */ - if (must_adjust[SRP_REGNUM]) - { - /* Function header saved SRP (r1), the return address. Frame starts - 4 bytes down from where it was saved. */ - frame_fp = frame_sp + fsr->regs[SRP_REGNUM] - 4; - fi->locals_pointer = frame_fp; - } - else - { - /* Function header didn't save SRP (r1), so we are in a leaf fn or - are otherwise confused. */ - frame_fp = -1; - } - } - - /* The locals are relative to the FP (whether it exists as an allocated - register, or just as an assumed offset from the SP) */ - fi->locals_pointer = frame_fp; - - /* The arguments are just above the SP as it was before we adjusted it - on entry. */ - fi->args_pointer = frame_sp - sp_offset; - - /* Now that we know the SP value used by the prologue, we know where - it saved all the registers. */ - for (src = 0; src < 32; src++) - if (must_adjust[src]) - fsr->regs[src] += frame_sp; - - /* The saved value of the SP is always known. */ - /* (we hope...) */ - if (fsr->regs[SP_REGNUM] != 0 - && fsr->regs[SP_REGNUM] != frame_sp - sp_offset) - fprintf_unfiltered (gdb_stderr, "Bad saved SP value %lx != %lx, offset %x!\n", - fsr->regs[SP_REGNUM], - frame_sp - sp_offset, sp_offset); - - fsr->regs[SP_REGNUM] = frame_sp - sp_offset; - - return (ip); -} - -/* Given an ip value corresponding to the start of a function, - return the ip of the first instruction after the function - prologue. */ - -CORE_ADDR -m88k_skip_prologue (CORE_ADDR ip) -{ - struct frame_saved_regs saved_regs_dummy; - struct symtab_and_line sal; - CORE_ADDR limit; - - sal = find_pc_line (ip, 0); - limit = (sal.end) ? sal.end : 0xffffffff; - - return (examine_prologue (ip, limit, (CORE_ADDR) 0, &saved_regs_dummy, - (struct frame_info *) 0)); -} - -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. - - We cache the result of doing this in the frame_obstack, since it is - fairly expensive. */ - -void -frame_find_saved_regs (struct frame_info *fi, struct frame_saved_regs *fsr) -{ - register struct frame_saved_regs *cache_fsr; - CORE_ADDR ip; - struct symtab_and_line sal; - CORE_ADDR limit; - - if (!fi->fsr) - { - cache_fsr = (struct frame_saved_regs *) - frame_obstack_alloc (sizeof (struct frame_saved_regs)); - memset (cache_fsr, '\0', sizeof (struct frame_saved_regs)); - fi->fsr = cache_fsr; - - /* Find the start and end of the function prologue. If the PC - is in the function prologue, we only consider the part that - has executed already. In the case where the PC is not in - the function prologue, we set limit to two instructions beyond - where the prologue ends in case if any of the prologue instructions - were moved into a delay slot of a branch instruction. */ - - ip = get_pc_function_start (fi->pc); - sal = find_pc_line (ip, 0); - limit = (sal.end && sal.end < fi->pc) ? sal.end + 2 * BYTES_PER_88K_INSN - : fi->pc; - - /* This will fill in fields in *fi as well as in cache_fsr. */ -#ifdef SIGTRAMP_FRAME_FIXUP - if (fi->signal_handler_caller) - SIGTRAMP_FRAME_FIXUP (fi->frame); -#endif - examine_prologue (ip, limit, fi->frame, cache_fsr, fi); -#ifdef SIGTRAMP_SP_FIXUP - if (fi->signal_handler_caller && fi->fsr->regs[SP_REGNUM]) - SIGTRAMP_SP_FIXUP (fi->fsr->regs[SP_REGNUM]); -#endif - } - - if (fsr) - *fsr = *fi->fsr; -} - -/* Return the address of the locals block for the frame - described by FI. Returns 0 if the address is unknown. - NOTE! Frame locals are referred to by negative offsets from the - argument pointer, so this is the same as frame_args_address(). */ - -CORE_ADDR -frame_locals_address (struct frame_info *fi) -{ - struct frame_saved_regs fsr; - - if (fi->args_pointer) /* Cached value is likely there. */ - return fi->args_pointer; - - /* Nope, generate it. */ - - get_frame_saved_regs (fi, &fsr); - - return fi->args_pointer; -} - -/* Return the address of the argument block for the frame - described by FI. Returns 0 if the address is unknown. */ - -CORE_ADDR -frame_args_address (struct frame_info *fi) -{ - struct frame_saved_regs fsr; - - if (fi->args_pointer) /* Cached value is likely there. */ - return fi->args_pointer; - - /* Nope, generate it. */ - - get_frame_saved_regs (fi, &fsr); - - return fi->args_pointer; -} - -/* Return the saved PC from this frame. - - If the frame has a memory copy of SRP_REGNUM, use that. If not, - just use the register SRP_REGNUM itself. */ - -CORE_ADDR -frame_saved_pc (struct frame_info *frame) -{ - return read_next_frame_reg (frame, SRP_REGNUM); -} - - -#define DUMMY_FRAME_SIZE 192 - -static void -write_word (CORE_ADDR sp, ULONGEST word) -{ - register int len = REGISTER_SIZE; - char buffer[MAX_REGISTER_RAW_SIZE]; - - store_unsigned_integer (buffer, len, word); - write_memory (sp, buffer, len); -} - -void -m88k_push_dummy_frame (void) -{ - register CORE_ADDR sp = read_register (SP_REGNUM); - register int rn; - int offset; - - sp -= DUMMY_FRAME_SIZE; /* allocate a bunch of space */ - - for (rn = 0, offset = 0; rn <= SP_REGNUM; rn++, offset += 4) - write_word (sp + offset, read_register (rn)); - - write_word (sp + offset, read_register (SXIP_REGNUM)); - offset += 4; - - write_word (sp + offset, read_register (SNIP_REGNUM)); - offset += 4; - - write_word (sp + offset, read_register (SFIP_REGNUM)); - offset += 4; - - write_word (sp + offset, read_register (PSR_REGNUM)); - offset += 4; - - write_word (sp + offset, read_register (FPSR_REGNUM)); - offset += 4; - - write_word (sp + offset, read_register (FPCR_REGNUM)); - offset += 4; - - write_register (SP_REGNUM, sp); - write_register (ACTUAL_FP_REGNUM, sp); -} - -void -pop_frame (void) -{ - register struct frame_info *frame = get_current_frame (); - register int regnum; - struct frame_saved_regs fsr; - - get_frame_saved_regs (frame, &fsr); - - if (PC_IN_CALL_DUMMY (read_pc (), read_register (SP_REGNUM), frame->frame)) - { - /* FIXME: I think get_frame_saved_regs should be handling this so - that we can deal with the saved registers properly (e.g. frame - 1 is a call dummy, the user types "frame 2" and then "print $ps"). */ - register CORE_ADDR sp = read_register (ACTUAL_FP_REGNUM); - int offset; - - for (regnum = 0, offset = 0; regnum <= SP_REGNUM; regnum++, offset += 4) - (void) write_register (regnum, read_memory_integer (sp + offset, 4)); - - write_register (SXIP_REGNUM, read_memory_integer (sp + offset, 4)); - offset += 4; - - write_register (SNIP_REGNUM, read_memory_integer (sp + offset, 4)); - offset += 4; - - write_register (SFIP_REGNUM, read_memory_integer (sp + offset, 4)); - offset += 4; - - write_register (PSR_REGNUM, read_memory_integer (sp + offset, 4)); - offset += 4; - - write_register (FPSR_REGNUM, read_memory_integer (sp + offset, 4)); - offset += 4; - - write_register (FPCR_REGNUM, read_memory_integer (sp + offset, 4)); - offset += 4; - - } - else - { - for (regnum = FP_REGNUM; regnum > 0; regnum--) - if (fsr.regs[regnum]) - write_register (regnum, - read_memory_integer (fsr.regs[regnum], 4)); - write_pc (frame_saved_pc (frame)); - } - reinit_frame_cache (); -} - -void -_initialize_m88k_tdep (void) -{ - tm_print_insn = print_insn_m88k; -} diff --git a/contrib/gdb/gdb/mon960-rom.c b/contrib/gdb/gdb/mon960-rom.c deleted file mode 100644 index 2b7fe5fd58d..00000000000 --- a/contrib/gdb/gdb/mon960-rom.c +++ /dev/null @@ -1,260 +0,0 @@ -/* Remote target glue for the Intel 960 MON960 ROM monitor. - Copyright 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "srec.h" -#include "xmodem.h" -#include "symtab.h" -#include "symfile.h" /* for generic_load */ -#include "inferior.h" /* for write_pc() */ - -#define USE_GENERIC_LOAD - -static struct target_ops mon960_ops; - -static void mon960_open (char *args, int from_tty); - -#ifdef USE_GENERIC_LOAD - -static void -mon960_load_gen (char *filename, int from_tty) -{ - generic_load (filename, from_tty); - /* Finally, make the PC point at the start address */ - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - inferior_ptid = null_ptid; /* No process now */ -} - -#else - -static void -mon960_load (struct serial *desc, char *file, int hashmark) -{ - bfd *abfd; - asection *s; - char *buffer; - int i; - - buffer = alloca (XMODEM_PACKETSIZE); - abfd = bfd_openr (file, 0); - if (!abfd) - { - printf_filtered ("Unable to open file %s\n", file); - return; - } - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - return; - } - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size; - printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, - s->vma + s->_raw_size); - gdb_flush (gdb_stdout); - monitor_printf (current_monitor->load, s->vma); - if (current_monitor->loadresp) - monitor_expect (current_monitor->loadresp, NULL, 0); - xmodem_init_xfer (desc); - section_size = bfd_section_size (abfd, s); - for (i = 0; i < section_size; i += XMODEM_DATASIZE) - { - int numbytes; - numbytes = min (XMODEM_DATASIZE, section_size - i); - bfd_get_section_contents (abfd, s, buffer + XMODEM_DATAOFFSET, i, - numbytes); - xmodem_send_packet (desc, buffer, numbytes, hashmark); - if (hashmark) - { - putchar_unfiltered ('#'); - gdb_flush (gdb_stdout); - } - } /* Per-packet (or S-record) loop */ - xmodem_finish_xfer (desc); - monitor_expect_prompt (NULL, 0); - putchar_unfiltered ('\n'); - } /* Loadable sections */ - if (hashmark) - putchar_unfiltered ('\n'); -} - -#endif /* USE_GENERIC_LOAD */ - -/* This array of registers need to match the indexes used by GDB. - This exists because the various ROM monitors use different strings - than does GDB, and don't necessarily support all the registers - either. So, typing "info reg sp" becomes a "r30". */ - -/* these correspond to the offsets from tm-* files from config directories */ -/* g0-g14, fp, pfp, sp, rip,r3-15, pc, ac, tc, fp0-3 */ -/* NOTE: "ip" is documented as "ir" in the Mon960 UG. */ -/* NOTE: "ir" can't be accessed... but there's an ip and rip. */ -static char *full_regnames[NUM_REGS] = -{ - /* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7", - /* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - /* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - /* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp", - /* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3", -}; - -static char *mon960_regnames[NUM_REGS]; - -/* Define the monitor command strings. Since these are passed directly - through to a printf style function, we may include formatting - strings. We also need a CR or LF on the end. */ - -/* need to pause the monitor for timing reasons, so slow it down */ - -#if 0 -/* FIXME: this extremely long init string causes MON960 to return two NAKS - instead of performing the autobaud recognition, at least when gdb - is running on GNU/Linux. The short string below works on Linux, and on - SunOS using a tcp serial connection. Must retest on SunOS using a - direct serial connection; if that works, get rid of the long string. */ -static char *mon960_inits[] = -{"\n\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r\n\r\n", NULL}; -#else -static char *mon960_inits[] = -{"\r", NULL}; -#endif - -static struct monitor_ops mon960_cmds; - -static void -init_mon960_cmds (void) -{ - mon960_cmds.flags = MO_CLR_BREAK_USES_ADDR - | MO_NO_ECHO_ON_OPEN | MO_SEND_BREAK_ON_STOP | MO_GETMEM_READ_SINGLE; /* flags */ - mon960_cmds.init = mon960_inits; /* Init strings */ - mon960_cmds.cont = "go\n\r"; /* continue command */ - mon960_cmds.step = "st\n\r"; /* single step */ - mon960_cmds.stop = NULL; /* break interrupts the program */ - mon960_cmds.set_break = NULL; /* set a breakpoint */ - mon960_cmds.clr_break = /* can't use "br" because only 2 hw bps are supported */ - mon960_cmds.clr_all_break = NULL; /* clear a breakpoint - "de" is for hw bps */ - NULL, /* clear all breakpoints */ - mon960_cmds.fill = NULL; /* fill (start end val) */ - /* can't use "fi" because it takes words, not bytes */ - /* can't use "mb", "md" or "mo" because they require interaction */ - mon960_cmds.setmem.cmdb = NULL; /* setmem.cmdb (addr, value) */ - mon960_cmds.setmem.cmdw = NULL; /* setmem.cmdw (addr, value) */ - mon960_cmds.setmem.cmdl = "md %x %x\n\r"; /* setmem.cmdl (addr, value) */ - mon960_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - mon960_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - mon960_cmds.setmem.term = NULL; /* setmem.term */ - mon960_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ - /* since the parsing of multiple bytes is difficult due to - interspersed addresses, we'll only read 1 value at a time, - even tho these can handle a count */ - mon960_cmds.getmem.cmdb = "db %x\n\r"; /* getmem.cmdb (addr, #bytes) */ - mon960_cmds.getmem.cmdw = "ds %x\n\r"; /* getmem.cmdw (addr, #swords) */ - mon960_cmds.getmem.cmdl = "di %x\n\r"; /* getmem.cmdl (addr, #words) */ - mon960_cmds.getmem.cmdll = "dd %x\n\r"; /* getmem.cmdll (addr, #dwords) */ - mon960_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */ - mon960_cmds.getmem.term = NULL; /* getmem.term */ - mon960_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - mon960_cmds.setreg.cmd = "md %s %x\n\r"; /* setreg.cmd (name, value) */ - mon960_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - mon960_cmds.setreg.term = NULL; /* setreg.term */ - mon960_cmds.setreg.term_cmd = NULL, /* setreg.term_cmd */ - mon960_cmds.getreg.cmd = "di %s\n\r"; /* getreg.cmd (name) */ - mon960_cmds.getreg.resp_delim = " : "; /* getreg.resp_delim */ - mon960_cmds.getreg.term = NULL; /* getreg.term */ - mon960_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - mon960_cmds.dump_registers = "re\n\r"; /* dump_registers */ - mon960_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */ - mon960_cmds.supply_register = NULL; /* supply_register */ -#ifdef USE_GENERIC_LOAD - mon960_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - mon960_cmds.load = NULL; /* download command */ - mon960_cmds.loadresp = NULL; /* load response */ -#else - mon960_cmds.load_routine = mon960_load; /* load_routine (defaults to SRECs) */ - mon960_cmds.load = "do\n\r"; /* download command */ - mon960_cmds.loadresp = "Downloading\n\r"; /* load response */ -#endif - mon960_cmds.prompt = "=>"; /* monitor command prompt */ - mon960_cmds.line_term = "\n\r"; /* end-of-command delimitor */ - mon960_cmds.cmd_end = NULL; /* optional command terminator */ - mon960_cmds.target = &mon960_ops; /* target operations */ - mon960_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - mon960_cmds.regnames = mon960_regnames; /* registers names */ - mon960_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -}; - -static void -mon960_open (char *args, int from_tty) -{ - char buf[64]; - - monitor_open (args, &mon960_cmds, from_tty); - - /* Attempt to fetch the value of the first floating point register (fp0). - If the monitor returns a string containing the word "Bad" we'll assume - this processor has no floating point registers, and nullify the - regnames entries that refer to FP registers. */ - - monitor_printf (mon960_cmds.getreg.cmd, full_regnames[FP0_REGNUM]); /* di fp0 */ - if (monitor_expect_prompt (buf, sizeof (buf)) != -1) - if (strstr (buf, "Bad") != NULL) - { - int i; - - for (i = FP0_REGNUM; i < FP0_REGNUM + 4; i++) - mon960_regnames[i] = NULL; - } -} - -void -_initialize_mon960 (void) -{ - memcpy (mon960_regnames, full_regnames, sizeof (full_regnames)); - - init_mon960_cmds (); - - init_monitor_ops (&mon960_ops); - - mon960_ops.to_shortname = "mon960"; /* for the target command */ - mon960_ops.to_longname = "Intel 960 MON960 monitor"; -#ifdef USE_GENERIC_LOAD - mon960_ops.to_load = mon960_load_gen; /* FIXME - should go back and try "do" */ -#endif - /* use SW breaks; target only supports 2 HW breakpoints */ - mon960_ops.to_insert_breakpoint = memory_insert_breakpoint; - mon960_ops.to_remove_breakpoint = memory_remove_breakpoint; - - mon960_ops.to_doc = - "Use an Intel 960 board running the MON960 debug monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - - mon960_ops.to_open = mon960_open; - add_target (&mon960_ops); -} diff --git a/contrib/gdb/gdb/mpw-config.in b/contrib/gdb/gdb/mpw-config.in deleted file mode 100644 index ed07878338b..00000000000 --- a/contrib/gdb/gdb/mpw-config.in +++ /dev/null @@ -1,81 +0,0 @@ -# Configuration fragment for GDB. - -If "{host_canonical}" =~ /m68k-apple-mpw/ - forward-include "{srcdir}"config:m68k:xm-mpw.h xm.h - Set siow_lib '"{Libraries}"SIOW.o' - -Else If "{host_canonical}" =~ /powerpc-apple-mpw/ - forward-include "{srcdir}"config:powerpc:xm-mpw.h xm.h - Set siow_lib '"{PPCLibraries}"PPCSIOW.o' - -End If - -Set xdepfiles '"{o}"mac-xdep.c.o' - -Set enable_cflags "" - -# Make a copy of this file and give it a different name, so it -# won't be confused with GDB's serial.h. - -Duplicate -y "{CIncludes}"Serial.h MacSerial.h - -Echo "/* dummy */" >termio.h - -If "{target_canonical}" =~ /m68k-apple-macos/ - forward-include "{srcdir}"config:m68k:tm-mac.h tm.h - forward-include "{srcdir}"config:m68k:tm-m68k.h 'm68k/tm-m68k.h' - Set tdepfiles '"{o}"m68k-tdep.c.o' - -Else If "{target_canonical}" =~ /powerpc-apple-macos/ - forward-include "{srcdir}"config:powerpc:tm-macos.h tm.h - forward-include "{srcdir}"config:rs6000:tm-rs6000.h 'rs6000/tm-rs6000.h' - Set tdepfiles '"{o}"rs6000-tdep.c.o "{o}"xcoffread.c.o' - -Else If "{target_canonical}" =~ /i386-unknown-go32/ - forward-include "{srcdir}"config:i386:tm-i386v.h tm.h - Set tdepfiles '"{o}"i386-tdep.c.o' - -Else If "{target_canonical}" =~ /mips-idt-ecoff/ - forward-include "{srcdir}"config:mips:tm-embed.h tm.h - forward-include "{srcdir}"config:mips:tm-bigmips.h 'mips/tm-bigmips.h' - forward-include "{srcdir}"config:mips:tm-mips.h 'mips/tm-mips.h' - Set tdepfiles '"{o}"mips-tdep.c.o "{o}"remote-mips.c.o' - -Else If "{target_canonical}" =~ /sh-hitachi-hms/ - forward-include "{srcdir}"config:sh:tm-sh.h tm.h - Set tdepfiles '"{o}"sh-tdep.c.o' - -End If - -If "{target_canonical}" =~ /m68k-apple-macos/ - forward-include "{srcdir}"config:m68k:nm-macos.h nm.h - Set natdepfiles '"{o}"mac-nat.c.o' - -Else If "{target_canonical}" =~ /powerpc-apple-macos/ - forward-include "{srcdir}"config:powerpc:nm-macos.h nm.h - Set natdepfiles '"{o}"mac-nat.c.o' - -Else - forward-include "{srcdir}"config:nm-empty.h nm.h - Set natdepfiles ' ' - -End If - -Echo '# From mpw-config.in' > "{o}"mk.tmp -Echo "TDEPFILES = " {tdepfiles} >> "{o}"mk.tmp -Echo "XDEPFILES = " {xdepfiles} >> "{o}"mk.tmp -Echo "NATDEPFILES = " {natdepfiles} >> "{o}"mk.tmp -Echo "XM_ADD_FILES = " >> "{o}"mk.tmp -Echo "TM_ADD_FILES = " >> "{o}"mk.tmp -Echo "NAT_ADD_FILES = " >> "{o}"mk.tmp -Echo "XM_CDEPS = " >> "{o}"mk.tmp -Echo "TM_CDEPS = " >> "{o}"mk.tmp -Echo "NAT_CDEPS = " >> "{o}"mk.tmp -Echo "SIOW_LIB = " {siow_lib} >> "{o}"mk.tmp -Echo "ENABLE_CFLAGS = " {enable_cflags} >> "{o}"mk.tmp -Echo '# End from mpw-config.in' >> "{o}"mk.tmp - -Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new -Echo '#include "mpw.h"' >> "{o}"config.new - -MoveIfChange "{o}"config.new "{o}"config.h diff --git a/contrib/gdb/gdb/mpw-make.sed b/contrib/gdb/gdb/mpw-make.sed deleted file mode 100644 index ce6a9ecdb15..00000000000 --- a/contrib/gdb/gdb/mpw-make.sed +++ /dev/null @@ -1,178 +0,0 @@ -# Sed commands that finish translating the GDB Unix Makefile to MPW syntax. - -/^host_alias =/s/^/#/ -/^target_alias =/s/^/#/ - -/^host_makefile_frag@$/d -/^target_makefile_frag@$/d - -/@ENABLE_CFLAGS@/s/@ENABLE_CFLAGS@/{ENABLE_CFLAGS}/g -/^ENABLE_CFLAGS=/s/^/#/ - -# Edit all the symbolic definitions pointing to various libraries and such. - -/^INCLUDE_DIR = /s/"{srcdir}":include/"{topsrcdir}"include:/ - -/^MMALLOC_DIR = /s/::mmalloc/mmalloc:/ -/^MMALLOC_SRC = /s/"{srcdir}"/"{topsrcdir}"/ -/^MMALLOC =/s/=.*$/=/ -/MMALLOC_CFLAGS =/s/=.*$/= -u USE_MMALLOC/ - -/^BFD_DIR = /s/::bfd/bfd:/ -/^BFD = /s/{BFD_DIR}:libbfd/{BFD_DIR}libbfd/ -/^BFD_SRC = /s/"{srcdir}"/"{topsrcdir}"/ - -/^READLINE_DIR = /s/::readline/readline:/ -/^READLINE =/s/=.*$/=/ -/^READLINE_SRC = /s/"{srcdir}"/"{topsrcdir}"/ - -/^INCLUDE_CFLAGS = /s/$/ -i "{topsrcdir}"include:mpw: -i ::extra-include:/ - -/^SER_HARDWIRE =/s/ser-unix/ser-mac/ - -/^TERMCAP =/s/ =.*$/ =/ - -# Whack out various autoconf vars that we don't need. -/@CONFIG_LDFLAGS@/s/@CONFIG_LDFLAGS@//g -/@HLDFLAGS@/s/@HLDFLAGS@//g -/@DEFS@/s/@DEFS@//g -/@YACC@/s/@YACC@/byacc/g -/@ENABLE_OBS@/s/@ENABLE_OBS@//g -/@ENABLE_CLIBS@/s/@ENABLE_CLIBS@//g -/@LIBS@/s/@LIBS@//g - -# Whack out autoconf hook for thread debugging. -/@THREAD_DB_OBS@/s/@THREAD_DB_OBS@//g - -# Fix up paths to include directories. -/INCLUDE_DIR/s/"{s}"{INCLUDE_DIR}/{INCLUDE_DIR}/g -/INCLUDE_DIR/s/{INCLUDE_DIR}:/{INCLUDE_DIR}/g -/INCLUDE_DIR/s/"{INCLUDE_DIR}":/"{INCLUDE_DIR}"/g - -/{BFD_DIR}/s/"{BFD_DIR}":/"{BFD_DIR}"/g -/{BFD_DIR}/s/\([ ]\){BFD_DIR}/\1::{BFD_DIR}/g -/{BFD_DIR}/s/\([ ]\)"{BFD_DIR}"/\1::"{BFD_DIR}"/g - -/{BFD_SRC}/s/"{s}"{BFD_SRC}/{BFD_SRC}/g -/{BFD_SRC}/s/{BFD_SRC}:/{BFD_SRC}/g - -/{READLINE_SRC}/s/"{s}"{READLINE_SRC}/{READLINE_SRC}/g - -/^readline_headers =/,/^$/c\ -readline_headers =\ - - -# This isn't really useful, and seems to cause nonsensical complaints. -/{ALLDEPFILES}/s/{ALLDEPFILES}//g - -/^copying.c \\Option-f /,/^$/d - -# Fix the syntax of bits of C code that go into version.c. -/char /s/'char .Option-x/'char */ - -# Point at files in the obj dir rather than src dir. -/version/s/"{s}"version\.c/"{o}"version.c/g -/version/s/^version\.c/"{o}"version.c/ -/config/s/"{s}"config\.h/"{o}"config.h/g -/config/s/^config\.h/"{o}"config.h/ -/xm/s/"{s}"xm\.h/"{o}"xm.h/g -/xm/s/^xm\.h/"{o}"xm.h/ -/tm/s/"{s}"tm\.h/"{o}"tm.h/g -/tm/s/^tm\.h/"{o}"tm.h/ -/nm/s/"{s}"nm\.h/"{o}"nm.h/g -/nm/s/^nm\.h/"{o}"nm.h/ - -/exp.tab.c/s/"{s}"\([a-z0-9]*\)-exp\.tab\.c/"{o}"\1-exp.tab.c/g -/exp.tab.c/s/^\([a-z0-9]*\)-exp\.tab\.c/"{o}"\1-exp.tab.c/ - -/y.tab/s/"{s}"y.tab\.c/"{o}"y.tab.c/g -/y.tab/s/^y.tab\.c/"{o}"y.tab.c/ - -/init/s/"{s}"init\.c-tmp/"{o}"init.c-tmp/g -/init/s/^init\.c-tmp/"{o}"init.c-tmp/ -/init/s/"{s}"init\.c/"{o}"init.c/g -/init/s/^init\.c/"{o}"init.c/ - -# Fix up the generation of version.c. -/"{o}"version.c \\Option-f Makefile/,/^$/c\ -"{o}"version.c \\Option-f Makefile\ - echo -n 'char *version = "' >"{o}"version.c\ - echo -n "{VERSION}" >>"{o}"version.c\ - echo '";' >>"{o}"version.c\ - echo -n 'char *host_name = "' >>"{o}"version.c\ - echo -n "{host_alias}" >>"{o}"version.c\ - echo '";' >>"{o}"version.c\ - echo -n 'char *target_name = "' >>"{o}"version.c\ - echo -n "{target_alias}" >>"{o}"version.c\ - echo '";' >>"{o}"version.c\ - - -/ansidecl/s/include "{s}""ansidecl.h"/include "ansidecl.h"/ - -# Open-brace in a command causes much confusion; replace with the -# result from a script. -/initialize_all_files ()/c\ - Echo -n 'void initialize_all_files () ' >> "{o}"init.c-tmp\ - open-brace >> "{o}"init.c-tmp - -# Replace the whole sed bit for init.c; it's simpler that way... -/echo {OBS} {TSOBS}/,/echo '}'/c\ - For i in {OBS} {TSOBS}\ - Set filename "`Echo {i} | sed \\Option-d\ - -e '/^Onindy.c.o/d' \\Option-d\ - -e '/^nindy.c.o/d' \\Option-d\ - -e '/ttyflush.c.o/d' \\Option-d\ - -e '/xdr_ld.c.o/d' \\Option-d\ - -e '/xdr_ptrace.c.o/d' \\Option-d\ - -e '/xdr_rdb.c.o/d' \\Option-d\ - -e '/udr.c.o/d' \\Option-d\ - -e '/udip2soc.c.o/d' \\Option-d\ - -e '/udi2go32.c.o/d' \\Option-d\ - -e '/version.c.o/d' \\Option-d\ - -e '/[a-z0-9A-Z_]*-exp.tab.c.o/d' \\Option-d\ - -e 's/\\.c\\.o/.c/' \\Option-d\ - -e 's/^://'`"\ - If "{filename}" != ""\ - sed <"{s}""{filename}" >>"{o}"init.c-tmp -n \\Option-d\ - -e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\\([a-z_0-9A-Z]*\\).*/ {extern void \\1 (); \\1 ();}/p'\ - End If\ - End For\ - Echo '}' >>"{o}"init.c-tmp - -# Fix the main compile/link command. -/{CC_LD} {INTERNAL_LDFLAGS} -o gdb/,/"{o}"init.c.o {OBS} {TSOBS} {ADD_FILES} {CLIBS} {LOADLIBES}/c\ - {CC_LD} {INTERNAL_LDFLAGS} -o gdb{PROG_EXT} "{o}"init.c.o {OBS} {TSOBS} {ADD_FILES} {CLIBS} {LOADLIBES} {EXTRALIBS}\ - {MAKEPEF} gdb{PROG_EXT} -o gdb {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\ - {REZ} "{s}"mac-gdb.r -o gdb -append -d PROG_NAME='"'gdb'"' -d VERSION_STRING='"'{version}'"'\ - -# Replace the install actions with MPW-friendly script. -/^install \\Option-f /,/^$/c\ -install \\Option-f all install-only\ -\ -install-only \\Option-f \ - NewFolderRecursive "{bindir}"\ - Duplicate -y gdb "{bindir}"gdb\ - If "`Exists SiowGDB`" != ""\ - Duplicate -y SiowGDB "{bindir}"SiowGDB\ - End If\ - - -# Don't do any recursive subdir stuff. -/ subdir_do/s/{MAKE}/null-command/ - -# Edit out actions that only confuse MPW Make. -/^config.status \\Option-f/,/^$/d -/^Makefile \\Option-f/,/^$/d - -# Don't test config.h dependencies. -/^"{o}"config.h \\Option-f/s/^/#/ - -# Add an action to build SIOWgdb. -$a\ -SIOWgdb \\Option-f {OBS} {TSOBS} {ADD_DEPS} {CDEPS} "{o}"init.c.o\ - Delete -i -y SIOWgdb\ - {CC_LD} {INTERNAL_LDFLAGS} -t 'APPL' -c 'gdb ' -o SIOWgdb{PROG_EXT} "{o}"init.c.o {OBS} {TSOBS} {ADD_FILES} {CLIBS} {SIOW_LIB} {LOADLIBES} {EXTRALIBS}\ - {MAKEPEF} SIOWgdb{PROG_EXT} -o SIOWgdb -ft 'APPL' -fc 'gdb ' {MAKEPEF_FLAGS} \ - {REZ} -o SIOWgdb "{RIncludes}"siow.r -append -d __kPrefSize=5000 -d __kMinSize=2000 -d APPNAME='"'SIOWgdb'"' \ - {REZ} "{s}"mac-gdb.r -o SIOWgdb -append -d VERSION_STRING='"'{version}'"'\ - diff --git a/contrib/gdb/gdb/news-xdep.c b/contrib/gdb/gdb/news-xdep.c deleted file mode 100644 index 7f57aeb1d46..00000000000 --- a/contrib/gdb/gdb/news-xdep.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Low level interface to ptrace, for GDB when running under Unix. - Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef __GNUC__ -/* Bad implement execle(3). It's depend for "/bin/cc". - - main() - { - printf("execle:\n"); - execle(FILE, ARGS, envp); - exit(1); - } - - GCC: - link a6,#0 - pea LC5 ; call printf - jbsr _printf - ; ; (not popd stack) - pea _envp ; call execle - clrl sp@- - pea LC4 - pea LC4 - pea LC4 - pea LC3 - pea LC6 - jbsr _execle - addw #32,sp ; delayed pop !! - - /bin/cc: - link.l fp,#L23 - movem.l #L24,(sp) - pea L26 ; call printf - jbsr _printf - addq.l #4,sp ; <--- popd stack !! - pea _envp ; call execle - clr.l -(sp) - pea L32 - - */ - -execle(name, args) - char *name, *args; -{ - register char **env = &args; - while (*env++) - ; - execve(name, (char **)&args, (char **)*env); -} -#endif diff --git a/contrib/gdb/gdb/nindy-tdep.c b/contrib/gdb/gdb/nindy-tdep.c deleted file mode 100644 index 1f35062e2bd..00000000000 --- a/contrib/gdb/gdb/nindy-tdep.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Target-machine dependent code for the NINDY monitor running on the Intel 960 - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 2000 - Free Software Foundation, Inc. - Contributed by Intel Corporation. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Miscellaneous NINDY-dependent routines. - Some replace macros normally defined in "tm.h". */ - -#include "defs.h" -#include "symtab.h" -#include "frame.h" -#include "gdbcore.h" - -/* 'start_frame' is a variable in the NINDY runtime startup routine - that contains the frame pointer of the 'start' routine (the routine - that calls 'main'). By reading its contents out of remote memory, - we can tell where the frame chain ends: backtraces should halt before - they display this frame. */ - -int -nindy_frame_chain_valid (CORE_ADDR chain, struct frame_info *curframe) -{ - struct symbol *sym; - struct minimal_symbol *msymbol; - - /* crtnindy.o is an assembler module that is assumed to be linked - * first in an i80960 executable. It contains the true entry point; - * it performs startup up initialization and then calls 'main'. - * - * 'sf' is the name of a variable in crtnindy.o that is set - * during startup to the address of the first frame. - * - * 'a' is the address of that variable in 80960 memory. - */ - static char sf[] = "start_frame"; - CORE_ADDR a; - - - chain &= ~0x3f; /* Zero low 6 bits because previous frame pointers - contain return status info in them. */ - if (chain == 0) - { - return 0; - } - - sym = lookup_symbol (sf, 0, VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (sym != 0) - { - a = SYMBOL_VALUE (sym); - } - else - { - msymbol = lookup_minimal_symbol (sf, NULL, NULL); - if (msymbol == NULL) - return 0; - a = SYMBOL_VALUE_ADDRESS (msymbol); - } - - return (chain != read_memory_integer (a, 4)); -} diff --git a/contrib/gdb/gdb/ns32k-tdep.c b/contrib/gdb/gdb/ns32k-tdep.c deleted file mode 100644 index e9bbfc479a9..00000000000 --- a/contrib/gdb/gdb/ns32k-tdep.c +++ /dev/null @@ -1,190 +0,0 @@ -/* Print NS 32000 instructions for GDB, the GNU debugger. - Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "gdbcore.h" - -static int sign_extend (int value, int bits); - -void -_initialize_ns32k_tdep (void) -{ - tm_print_insn = print_insn_ns32k; -} - -/* Advance PC across any function entry prologue instructions - to reach some "real" code. */ - -CORE_ADDR -umax_skip_prologue (CORE_ADDR pc) -{ - register unsigned char op = read_memory_integer (pc, 1); - if (op == 0x82) - { - op = read_memory_integer (pc + 2, 1); - if ((op & 0x80) == 0) - pc += 3; - else if ((op & 0xc0) == 0x80) - pc += 4; - else - pc += 6; - } - return pc; -} - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. - Encore's C compiler often reuses same area on stack for args, - so this will often not work properly. If the arg names - are known, it's likely most of them will be printed. */ - -int -umax_frame_num_args (struct frame_info *fi) -{ - int numargs; - CORE_ADDR pc; - CORE_ADDR enter_addr; - unsigned int insn; - unsigned int addr_mode; - int width; - - numargs = -1; - enter_addr = ns32k_get_enter_addr ((fi)->pc); - if (enter_addr > 0) - { - pc = ((enter_addr == 1) - ? SAVED_PC_AFTER_CALL (fi) - : FRAME_SAVED_PC (fi)); - insn = read_memory_integer (pc, 2); - addr_mode = (insn >> 11) & 0x1f; - insn = insn & 0x7ff; - if ((insn & 0x7fc) == 0x57c - && addr_mode == 0x14) /* immediate */ - { - if (insn == 0x57c) /* adjspb */ - width = 1; - else if (insn == 0x57d) /* adjspw */ - width = 2; - else if (insn == 0x57f) /* adjspd */ - width = 4; - else - internal_error (__FILE__, __LINE__, "bad else"); - numargs = read_memory_integer (pc + 2, width); - if (width > 1) - flip_bytes (&numargs, width); - numargs = -sign_extend (numargs, width * 8) / 4; - } - } - return numargs; -} - -static int -sign_extend (int value, int bits) -{ - value = value & ((1 << bits) - 1); - return (value & (1 << (bits - 1)) - ? value | (~((1 << bits) - 1)) - : value); -} - -void -flip_bytes (void *p, int count) -{ - char tmp; - char *ptr = 0; - - while (count > 0) - { - tmp = *ptr; - ptr[0] = ptr[count - 1]; - ptr[count - 1] = tmp; - ptr++; - count -= 2; - } -} - -/* Return the number of locals in the current frame given a pc - pointing to the enter instruction. This is used in the macro - FRAME_FIND_SAVED_REGS. */ - -int -ns32k_localcount (CORE_ADDR enter_pc) -{ - unsigned char localtype; - int localcount; - - localtype = read_memory_integer (enter_pc + 2, 1); - if ((localtype & 0x80) == 0) - localcount = localtype; - else if ((localtype & 0xc0) == 0x80) - localcount = (((localtype & 0x3f) << 8) - | (read_memory_integer (enter_pc + 3, 1) & 0xff)); - else - localcount = (((localtype & 0x3f) << 24) - | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16) - | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8) - | (read_memory_integer (enter_pc + 5, 1) & 0xff)); - return localcount; -} - - -/* Nonzero if instruction at PC is a return instruction. */ - -static int -ns32k_about_to_return (CORE_ADDR pc) -{ - return (read_memory_integer (pc, 1) == 0x12); -} - - -/* - * Get the address of the enter opcode for the function - * containing PC, if there is an enter for the function, - * and if the pc is between the enter and exit. - * Returns positive address if pc is between enter/exit, - * 1 if pc before enter or after exit, 0 otherwise. - */ - -CORE_ADDR -ns32k_get_enter_addr (CORE_ADDR pc) -{ - CORE_ADDR enter_addr; - unsigned char op; - - if (pc == 0) - return 0; - - if (ns32k_about_to_return (pc)) - return 1; /* after exit */ - - enter_addr = get_pc_function_start (pc); - - if (pc == enter_addr) - return 1; /* before enter */ - - op = read_memory_integer (enter_addr, 1); - - if (op != 0x82) - return 0; /* function has no enter/exit */ - - return enter_addr; /* pc is between enter and exit */ -} diff --git a/contrib/gdb/gdb/ns32km3-nat.c b/contrib/gdb/gdb/ns32km3-nat.c deleted file mode 100644 index cdafb9ce0d4..00000000000 --- a/contrib/gdb/gdb/ns32km3-nat.c +++ /dev/null @@ -1,183 +0,0 @@ -/* Low level interface to ns532 running mach 3.0. - Copyright (C) 1992 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" - -#include - -#include -#include -#include -#include - -#define private static - - -/* Find offsets to thread states at compile time. - * If your compiler does not grok this, calculate offsets - * offsets yourself and use them (or get a compatible compiler :-) - */ - -#define REG_N_OFFSET(reg) (int)(&((struct ns532_combined_state *)0)->ts.reg) -#define REG_F_OFFSET(reg) (int)(&((struct ns532_combined_state *)0)->fs.reg) - -/* at reg_offset[i] is the offset to the ns532_combined_state - * location where the gdb registers[i] is stored. - */ - -static int reg_offset[] = -{ - REG_N_OFFSET(r0), REG_N_OFFSET(r1), REG_N_OFFSET(r2), REG_N_OFFSET(r3), - REG_N_OFFSET(r4), REG_N_OFFSET(r5), REG_N_OFFSET(r6), REG_N_OFFSET(r7), - REG_F_OFFSET(l0a), REG_F_OFFSET(l0b),REG_F_OFFSET(l2a),REG_F_OFFSET(l2b), - REG_F_OFFSET(l4a), REG_F_OFFSET(l4b),REG_F_OFFSET(l6a),REG_F_OFFSET(l6b), - REG_N_OFFSET(sp), REG_N_OFFSET(fp), REG_N_OFFSET(pc), REG_N_OFFSET(psr), - REG_F_OFFSET(fsr), - REG_F_OFFSET(l0a), REG_F_OFFSET(l1a),REG_F_OFFSET(l2a),REG_F_OFFSET(l3a), - REG_F_OFFSET(l4a), REG_F_OFFSET(l5a),REG_F_OFFSET(l6a),REG_F_OFFSET(l7a), -}; - -#define REG_ADDRESS(state,regnum) ((char *)(state)+reg_offset[regnum]) - -/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM - * Caller knows that the regs handled in one transaction are of same size. - */ -#define FETCH_REGS(state, regnum, count) \ - memcpy (®isters[REGISTER_BYTE (regnum)], \ - (char *)state+reg_offset[ regnum ], \ - count*REGISTER_SIZE) - -/* Store COUNT contiguous registers to thread STATE starting from REGNUM */ -#define STORE_REGS(state, regnum, count) \ - memcpy ((char *)state+reg_offset[ regnum ], \ - ®isters[REGISTER_BYTE (regnum)], \ - count*REGISTER_SIZE) - -/* - * Fetch inferiors registers for gdb. - * REGNO specifies which (as gdb views it) register, -1 for all. - */ - -void -fetch_inferior_registers (regno) - int regno; -{ - kern_return_t ret; - thread_state_data_t state; - unsigned int stateCnt = NS532_COMBINED_STATE_COUNT; - int index; - - if (! MACH_PORT_VALID (current_thread)) - error ("fetch inferior registers: Invalid thread"); - - if (must_suspend_thread) - setup_thread (current_thread, 1); - - ret = thread_get_state (current_thread, - NS532_COMBINED_STATE, - state, - &stateCnt); - - if (ret != KERN_SUCCESS) - warning ("fetch_inferior_registers: %s ", - mach_error_string (ret)); -#if 0 - /* It may be more effective to store validate all of them, - * since we fetched them all anyway - */ - else if (regno != -1) - supply_register (regno, (char *)state+reg_offset[regno]); -#endif - else - { - for (index = 0; index < NUM_REGS; index++) - supply_register (index, (char *)state+reg_offset[index]); - } - - if (must_suspend_thread) - setup_thread (current_thread, 0); -} - -/* Store our register values back into the inferior. - * If REGNO is -1, do this for all registers. - * Otherwise, REGNO specifies which register - * - * On mach3 all registers are always saved in one call. - */ -void -store_inferior_registers (regno) - int regno; -{ - kern_return_t ret; - thread_state_data_t state; - unsigned int stateCnt = NS532_COMBINED_STATE_COUNT; - register int index; - - if (! MACH_PORT_VALID (current_thread)) - error ("store inferior registers: Invalid thread"); - - if (must_suspend_thread) - setup_thread (current_thread, 1); - - /* Fetch the state of the current thread */ - ret = thread_get_state (current_thread, - NS532_COMBINED_STATE, - state, - &stateCnt); - - if (ret != KERN_SUCCESS) - { - warning ("store_inferior_registers (get): %s", - mach_error_string (ret)); - if (must_suspend_thread) - setup_thread (current_thread, 0); - return; - } - - /* move gdb's registers to thread's state - * - * Since we save all registers anyway, save the ones - * that gdb thinks are valid (e.g. ignore the regno - * parameter) - */ -#if 0 - if (regno != -1) - STORE_REGS (state, regno, 1); - else -#endif - { - for (index = 0; index < NUM_REGS; index++) - STORE_REGS (state, index, 1); - } - - /* Write gdb's current view of register to the thread - */ - ret = thread_set_state (current_thread, - NS532_COMBINED_STATE, - state, - NS532_COMBINED_STATE_COUNT); - - if (ret != KERN_SUCCESS) - warning ("store_inferior_registers (set): %s", - mach_error_string (ret)); - - if (must_suspend_thread) - setup_thread (current_thread, 0); -} diff --git a/contrib/gdb/gdb/ns32knbsd-nat.c b/contrib/gdb/gdb/ns32knbsd-nat.c deleted file mode 100644 index fd6e6197efc..00000000000 --- a/contrib/gdb/gdb/ns32knbsd-nat.c +++ /dev/null @@ -1,364 +0,0 @@ -/* Functions specific to running gdb native on an ns32k running NetBSD - Copyright 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include -#include -#include -#include - -#include "defs.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "regcache.h" - -#define RF(dst, src) \ - memcpy(®isters[REGISTER_BYTE(dst)], &src, sizeof(src)) - -#define RS(src, dst) \ - memcpy(&dst, ®isters[REGISTER_BYTE(src)], sizeof(dst)) - -void -fetch_inferior_registers (int regno) -{ - struct reg inferior_registers; - struct fpreg inferior_fpregisters; - - ptrace (PT_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0); - ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0); - - RF (R0_REGNUM + 0, inferior_registers.r_r0); - RF (R0_REGNUM + 1, inferior_registers.r_r1); - RF (R0_REGNUM + 2, inferior_registers.r_r2); - RF (R0_REGNUM + 3, inferior_registers.r_r3); - RF (R0_REGNUM + 4, inferior_registers.r_r4); - RF (R0_REGNUM + 5, inferior_registers.r_r5); - RF (R0_REGNUM + 6, inferior_registers.r_r6); - RF (R0_REGNUM + 7, inferior_registers.r_r7); - - RF (SP_REGNUM, inferior_registers.r_sp); - RF (FP_REGNUM, inferior_registers.r_fp); - RF (PC_REGNUM, inferior_registers.r_pc); - RF (PS_REGNUM, inferior_registers.r_psr); - - RF (FPS_REGNUM, inferior_fpregisters.r_fsr); - RF (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]); - RF (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]); - RF (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]); - RF (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]); - RF (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]); - RF (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]); - RF (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]); - RF (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]); - registers_fetched (); -} - -void -store_inferior_registers (int regno) -{ - struct reg inferior_registers; - struct fpreg inferior_fpregisters; - - RS (R0_REGNUM + 0, inferior_registers.r_r0); - RS (R0_REGNUM + 1, inferior_registers.r_r1); - RS (R0_REGNUM + 2, inferior_registers.r_r2); - RS (R0_REGNUM + 3, inferior_registers.r_r3); - RS (R0_REGNUM + 4, inferior_registers.r_r4); - RS (R0_REGNUM + 5, inferior_registers.r_r5); - RS (R0_REGNUM + 6, inferior_registers.r_r6); - RS (R0_REGNUM + 7, inferior_registers.r_r7); - - RS (SP_REGNUM, inferior_registers.r_sp); - RS (FP_REGNUM, inferior_registers.r_fp); - RS (PC_REGNUM, inferior_registers.r_pc); - RS (PS_REGNUM, inferior_registers.r_psr); - - RS (FPS_REGNUM, inferior_fpregisters.r_fsr); - RS (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]); - RS (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]); - RS (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]); - RS (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]); - RS (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]); - RS (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]); - RS (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]); - RS (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]); - - ptrace (PT_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0); - ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0); -} - - -/* XXX - Add this to machine/regs.h instead? */ -struct coreregs -{ - struct reg intreg; - struct fpreg freg; -}; - -/* Get registers from a core file. REG_ADDR is unused. */ -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, - unsigned int reg_addr) -{ - struct coreregs *core_reg; - - core_reg = (struct coreregs *) core_reg_sect; - - /* - * We have *all* registers - * in the first core section. - * Ignore which. - */ - - if (core_reg_size < sizeof (*core_reg)) - { - fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n"); - return; - } - - /* Integer registers */ - RF (R0_REGNUM + 0, core_reg->intreg.r_r0); - RF (R0_REGNUM + 1, core_reg->intreg.r_r1); - RF (R0_REGNUM + 2, core_reg->intreg.r_r2); - RF (R0_REGNUM + 3, core_reg->intreg.r_r3); - RF (R0_REGNUM + 4, core_reg->intreg.r_r4); - RF (R0_REGNUM + 5, core_reg->intreg.r_r5); - RF (R0_REGNUM + 6, core_reg->intreg.r_r6); - RF (R0_REGNUM + 7, core_reg->intreg.r_r7); - - RF (SP_REGNUM, core_reg->intreg.r_sp); - RF (FP_REGNUM, core_reg->intreg.r_fp); - RF (PC_REGNUM, core_reg->intreg.r_pc); - RF (PS_REGNUM, core_reg->intreg.r_psr); - - /* Floating point registers */ - RF (FPS_REGNUM, core_reg->freg.r_fsr); - RF (FP0_REGNUM + 0, core_reg->freg.r_freg[0]); - RF (FP0_REGNUM + 2, core_reg->freg.r_freg[2]); - RF (FP0_REGNUM + 4, core_reg->freg.r_freg[4]); - RF (FP0_REGNUM + 6, core_reg->freg.r_freg[6]); - RF (LP0_REGNUM + 1, core_reg->freg.r_freg[1]); - RF (LP0_REGNUM + 3, core_reg->freg.r_freg[3]); - RF (LP0_REGNUM + 5, core_reg->freg.r_freg[5]); - RF (LP0_REGNUM + 7, core_reg->freg.r_freg[7]); - registers_fetched (); -} - -/* Register that we are able to handle ns32knbsd core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns nat_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_ns32knbsd_nat (void) -{ - add_core_fns (&nat_core_fns); -} - - -/* - * kernel_u_size() is not helpful on NetBSD because - * the "u" struct is NOT in the core dump file. - */ - -#ifdef FETCH_KCORE_REGISTERS -/* - * Get registers from a kernel crash dump or live kernel. - * Called by kcore-nbsd.c:get_kcore_registers(). - */ -void -fetch_kcore_registers (struct pcb *pcb) -{ - struct switchframe sf; - struct reg intreg; - int dummy; - - /* Integer registers */ - if (target_read_memory ((CORE_ADDR) pcb->pcb_ksp, (char *) &sf, sizeof sf)) - error ("Cannot read integer registers."); - - /* We use the psr at kernel entry */ - if (target_read_memory ((CORE_ADDR) pcb->pcb_onstack, (char *) &intreg, sizeof intreg)) - error ("Cannot read processor status register."); - - dummy = 0; - RF (R0_REGNUM + 0, dummy); - RF (R0_REGNUM + 1, dummy); - RF (R0_REGNUM + 2, dummy); - RF (R0_REGNUM + 3, sf.sf_r3); - RF (R0_REGNUM + 4, sf.sf_r4); - RF (R0_REGNUM + 5, sf.sf_r5); - RF (R0_REGNUM + 6, sf.sf_r6); - RF (R0_REGNUM + 7, sf.sf_r7); - - dummy = pcb->pcb_kfp + 8; - RF (SP_REGNUM, dummy); - RF (FP_REGNUM, sf.sf_fp); - RF (PC_REGNUM, sf.sf_pc); - RF (PS_REGNUM, intreg.r_psr); - - /* Floating point registers */ - RF (FPS_REGNUM, pcb->pcb_fsr); - RF (FP0_REGNUM + 0, pcb->pcb_freg[0]); - RF (FP0_REGNUM + 2, pcb->pcb_freg[2]); - RF (FP0_REGNUM + 4, pcb->pcb_freg[4]); - RF (FP0_REGNUM + 6, pcb->pcb_freg[6]); - RF (LP0_REGNUM + 1, pcb->pcb_freg[1]); - RF (LP0_REGNUM + 3, pcb->pcb_freg[3]); - RF (LP0_REGNUM + 5, pcb->pcb_freg[5]); - RF (LP0_REGNUM + 7, pcb->pcb_freg[7]); - registers_fetched (); -} -#endif /* FETCH_KCORE_REGISTERS */ - -void -clear_regs (void) -{ - double zero = 0.0; - int null = 0; - - /* Integer registers */ - RF (R0_REGNUM + 0, null); - RF (R0_REGNUM + 1, null); - RF (R0_REGNUM + 2, null); - RF (R0_REGNUM + 3, null); - RF (R0_REGNUM + 4, null); - RF (R0_REGNUM + 5, null); - RF (R0_REGNUM + 6, null); - RF (R0_REGNUM + 7, null); - - RF (SP_REGNUM, null); - RF (FP_REGNUM, null); - RF (PC_REGNUM, null); - RF (PS_REGNUM, null); - - /* Floating point registers */ - RF (FPS_REGNUM, zero); - RF (FP0_REGNUM + 0, zero); - RF (FP0_REGNUM + 2, zero); - RF (FP0_REGNUM + 4, zero); - RF (FP0_REGNUM + 6, zero); - RF (LP0_REGNUM + 0, zero); - RF (LP0_REGNUM + 1, zero); - RF (LP0_REGNUM + 2, zero); - RF (LP0_REGNUM + 3, zero); - return; -} - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -int -frame_num_args (struct frame_info *fi) -{ - CORE_ADDR enter_addr; - CORE_ADDR argp; - int inst; - int args; - int i; - - if (read_memory_integer (fi->frame, 4) == 0 && fi->pc < 0x10000) - { - /* main is always called with three args */ - return (3); - } - enter_addr = ns32k_get_enter_addr (fi->pc); - if (enter_addr = 0) - return (-1); - argp = enter_addr == 1 ? SAVED_PC_AFTER_CALL (fi) : FRAME_SAVED_PC (fi); - for (i = 0; i < 16; i++) - { - /* - * After a bsr gcc may emit the following instructions - * to remove the arguments from the stack: - * cmpqd 0,tos - to remove 4 bytes from the stack - * cmpd tos,tos - to remove 8 bytes from the stack - * adjsp[bwd] -n - to remove n bytes from the stack - * Gcc sometimes delays emitting these instructions and - * may even throw a branch between our feet. - */ - inst = read_memory_integer (argp, 4); - args = read_memory_integer (argp + 2, 4); - if ((inst & 0xff) == 0xea) - { /* br */ - args = ((inst >> 8) & 0xffffff) | (args << 24); - if (args & 0x80) - { - if (args & 0x40) - { - args = ntohl (args); - } - else - { - args = ntohs (args & 0xffff); - if (args & 0x2000) - args |= 0xc000; - } - } - else - { - args = args & 0xff; - if (args & 0x40) - args |= 0x80; - } - argp += args; - continue; - } - if ((inst & 0xffff) == 0xb81f) /* cmpqd 0,tos */ - return (1); - else if ((inst & 0xffff) == 0xbdc7) /* cmpd tos,tos */ - return (2); - else if ((inst & 0xfffc) == 0xa57c) - { /* adjsp[bwd] */ - switch (inst & 3) - { - case 0: - args = ((args & 0xff) + 0x80); - break; - case 1: - args = ((ntohs (args) & 0xffff) + 0x8000); - break; - case 3: - args = -ntohl (args); - break; - default: - return (-1); - } - if (args / 4 > 10 || (args & 3) != 0) - continue; - return (args / 4); - } - argp += 1; - } - return (-1); -} diff --git a/contrib/gdb/gdb/op50-rom.c b/contrib/gdb/gdb/op50-rom.c deleted file mode 100644 index a256c91455b..00000000000 --- a/contrib/gdb/gdb/op50-rom.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Remote target glue for the Oki op50n based eval board. - - Copyright 1995, 1998, 1999, 2000 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" - -static void op50n_open (char *args, int from_tty); - -/* - * this array of registers need to match the indexes used by GDB. The - * whole reason this exists is cause the various ROM monitors use - * different strings than GDB does, and doesn't support all the - * registers either. So, typing "info reg sp" becomes a "r30". - */ - -static char *op50n_regnames[NUM_REGS] = -{ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "cr11", "p", NULL, NULL, NULL, "cr15", "cr19", "cr20", - "cr21", "cr22", NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, "cr0", "cr8", "cr9", "cr10", "cr12", - "cr13", "cr24", "cr25", "cr26", -}; - -/* - * Define the monitor command strings. Since these are passed directly - * through to a printf style function, we need can include formatting - * strings. We also need a CR or LF on the end. - */ - -static struct target_ops op50n_ops; - -static char *op50n_inits[] = -{".\r", NULL}; - -static struct monitor_ops op50n_cmds; - -static void -init_op50n_cmds (void) -{ - op50n_cmds.flags = MO_CLR_BREAK_USES_ADDR /*| MO_GETMEM_READ_SINGLE */ ; /* flags */ - op50n_cmds.init = op50n_inits; /* Init strings */ - op50n_cmds.cont = "g\r"; /* continue command */ - op50n_cmds.step = "t\r"; /* single step */ - op50n_cmds.stop = "\003.\r"; /* Interrupt char */ - op50n_cmds.set_break = "b %x\r"; /* set a breakpoint */ - op50n_cmds.clr_break = "b %x;0\r"; /* clear breakpoint at addr */ - op50n_cmds.clr_all_break = "bx\r"; /* clear all breakpoints */ - op50n_cmds.fill = "fx %x s%x %x\r"; /* memory fill cmd (addr, len, val) */ - op50n_cmds.setmem.cmdb = "sx %x %x\r"; /* setmem.cmdb (addr, value) */ - op50n_cmds.setmem.cmdw = "sh %x %x\r"; /* setmem.cmdw (addr, value) */ - op50n_cmds.setmem.cmdl = "s %x %x\r"; /* setmem.cmdl (addr, value) */ - op50n_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - op50n_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - op50n_cmds.setmem.term = NULL; /* setmem.term */ - op50n_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ -#if 0 - { - "sx %x\r", /* getmem.cmdb (addr, len) */ - "sh %x\r", /* getmem.cmdw (addr, len) */ - "s %x\r", /* getmem.cmdl (addr, len) */ - NULL, /* getmem.cmdll (addr, len) */ - " : ", /* getmem.resp_delim */ - " ", /* getmem.term */ - ".\r", /* getmem.term_cmd */ - }; -#else - op50n_cmds.getmem.cmdb = "dx %x s%x\r"; /* getmem.cmdb (addr, len) */ - op50n_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ - op50n_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ - op50n_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - op50n_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */ - op50n_cmds.getmem.term = NULL; /* getmem.term */ - op50n_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ -#endif - op50n_cmds.setreg.cmd = "x %s %x\r"; /* setreg.cmd (name, value) */ - op50n_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - op50n_cmds.setreg.term = NULL; /* setreg.term */ - op50n_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - op50n_cmds.getreg.cmd = "x %s\r"; /* getreg.cmd (name) */ - op50n_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */ - op50n_cmds.getreg.term = " "; /* getreg.term */ - op50n_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */ - op50n_cmds.dump_registers = NULL; /* dump_registers */ - op50n_cmds.register_pattern = NULL; /* register_pattern */ - op50n_cmds.supply_register = NULL; /* supply_register */ - op50n_cmds.load_routine = NULL; /* load routine */ - op50n_cmds.load = "r 0\r"; /* download command */ - op50n_cmds.loadresp = NULL; /* load response */ - op50n_cmds.prompt = "\n#"; /* monitor command prompt */ - op50n_cmds.line_term = "\r"; /* end-of-command delimitor */ - op50n_cmds.cmd_end = NULL; /* optional command terminator */ - op50n_cmds.target = &op50n_ops; /* target operations */ - op50n_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - op50n_cmds.regnames = op50n_regnames; /* register names */ - op50n_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -}; - -static void -op50n_open (char *args, int from_tty) -{ - monitor_open (args, &op50n_cmds, from_tty); -} - -void -_initialize_op50n (void) -{ - init_op50n_cmds (); - init_monitor_ops (&op50n_ops); - - op50n_ops.to_shortname = "op50n"; - op50n_ops.to_longname = "Oki's debug monitor for the Op50n Eval board"; - op50n_ops.to_doc = "Debug on a Oki OP50N eval board.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - op50n_ops.to_open = op50n_open; - - add_target (&op50n_ops); -} diff --git a/contrib/gdb/gdb/os9kread.c b/contrib/gdb/gdb/os9kread.c deleted file mode 100644 index 498498ba2b5..00000000000 --- a/contrib/gdb/gdb/os9kread.c +++ /dev/null @@ -1,1621 +0,0 @@ -/* Read os9/os9k symbol tables and convert to internal format, for GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This module provides three functions: os9k_symfile_init, - which initializes to read a symbol file; os9k_new_init, which - discards existing cached information when all symbols are being - discarded; and os9k_symfile_read, which reads a symbol table - from a file. - - os9k_symfile_read only does the minimum work necessary for letting the - user "name" things symbolically; it does not read the entire symtab. - Instead, it reads the external and static symbols and puts them in partial - symbol tables. When more extensive information is requested of a - file, the corresponding partial symbol table is mutated into a full - fledged symbol table by going back and reading the symbols - for real. os9k_psymtab_to_symtab() is the function that does this */ - -#include "defs.h" -#include "gdb_string.h" -#include "gdb_assert.h" -#include - -#if defined(USG) || defined(__CYGNUSCLIB__) -#include -#include -#endif - -#include "obstack.h" -#include "gdb_stat.h" -#include "symtab.h" -#include "breakpoint.h" -#include "command.h" -#include "target.h" -#include "gdbcore.h" /* for bfd stuff */ -#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */ -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "gdb-stabs.h" -#include "demangle.h" -#include "language.h" /* Needed inside partial-stab.h */ -#include "complaints.h" -#include "os9k.h" -#include "stabsread.h" - -extern void _initialize_os9kread (void); - -/* Each partial symbol table entry contains a pointer to private data for the - read_symtab() function to use when expanding a partial symbol table entry - to a full symbol table entry. - - For dbxread this structure contains the offset within the file symbol table - of first local symbol for this file, and count of the section - of the symbol table devoted to this file's symbols (actually, the section - bracketed may contain more than just this file's symbols). It also contains - further information needed to locate the symbols if they are in an ELF file. - - If ldsymcnt is 0, the only reason for this thing's existence is the - dependency list. Nothing else will happen when it is read in. */ - -#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff) -#define LDSYMCNT(p) (((struct symloc *)((p)->read_symtab_private))->ldsymnum) - -struct symloc - { - int ldsymoff; - int ldsymnum; - }; - -/* Remember what we deduced to be the source language of this psymtab. */ -static enum language psymtab_language = language_unknown; - -/* keep partial symbol table file nested depth */ -static int psymfile_depth = 0; - -/* keep symbol table file nested depth */ -static int symfile_depth = 0; - -extern int previous_stab_code; - -/* Name of last function encountered. Used in Solaris to approximate - object file boundaries. */ -static char *last_function_name; - -/* Complaints about the symbols we have encountered. */ -extern struct complaint lbrac_complaint; - -extern struct complaint unknown_symtype_complaint; - -extern struct complaint unknown_symchar_complaint; - -extern struct complaint lbrac_rbrac_complaint; - -extern struct complaint repeated_header_complaint; - -extern struct complaint repeated_header_name_complaint; - -#if 0 -static struct complaint lbrac_unmatched_complaint = -{"unmatched Increment Block Entry before symtab pos %d", 0, 0}; - -static struct complaint lbrac_mismatch_complaint = -{"IBE/IDE symbol mismatch at symtab pos %d", 0, 0}; -#endif - -/* Local function prototypes */ - -static void read_minimal_symbols (struct objfile *); - -static void os9k_read_ofile_symtab (struct partial_symtab *); - -static void os9k_psymtab_to_symtab (struct partial_symtab *); - -static void os9k_psymtab_to_symtab_1 (struct partial_symtab *); - -static void read_os9k_psymtab (struct objfile *, CORE_ADDR, int); - -static int fill_sym (FILE *, bfd *); - -static void os9k_symfile_init (struct objfile *); - -static void os9k_new_init (struct objfile *); - -static void os9k_symfile_read (struct objfile *, int); - -static void os9k_symfile_finish (struct objfile *); - -static void -os9k_process_one_symbol (int, int, CORE_ADDR, char *, - struct section_offsets *, struct objfile *); - -static struct partial_symtab *os9k_start_psymtab (struct objfile *, char *, - CORE_ADDR, int, int, - struct partial_symbol **, - struct partial_symbol **); - -static struct partial_symtab *os9k_end_psymtab (struct partial_symtab *, - char **, int, int, CORE_ADDR, - struct partial_symtab **, - int); - -static void record_minimal_symbol (char *, CORE_ADDR, int, struct objfile *); - -#define HANDLE_RBRAC(val) \ - if ((val) > pst->texthigh) pst->texthigh = (val); - -#define SWAP_STBHDR(hdrp, abfd) \ - { \ - (hdrp)->fmtno = bfd_get_16(abfd, (unsigned char *)&(hdrp)->fmtno); \ - (hdrp)->crc = bfd_get_32(abfd, (unsigned char *)&(hdrp)->crc); \ - (hdrp)->offset = bfd_get_32(abfd, (unsigned char *)&(hdrp)->offset); \ - (hdrp)->nsym = bfd_get_32(abfd, (unsigned char *)&(hdrp)->nsym); \ - } -#define SWAP_STBSYM(symp, abfd) \ - { \ - (symp)->value = bfd_get_32(abfd, (unsigned char *)&(symp)->value); \ - (symp)->type = bfd_get_16(abfd, (unsigned char *)&(symp)->type); \ - (symp)->stroff = bfd_get_32(abfd, (unsigned char *)&(symp)->stroff); \ - } -#define N_DATA 0 -#define N_BSS 1 -#define N_RDATA 2 -#define N_IDATA 3 -#define N_TEXT 4 -#define N_ABS 6 - -static void -record_minimal_symbol (char *name, CORE_ADDR address, int type, - struct objfile *objfile) -{ - enum minimal_symbol_type ms_type; - - switch (type) - { - case N_TEXT: - ms_type = mst_text; - address += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - break; - case N_DATA: - ms_type = mst_data; - break; - case N_BSS: - ms_type = mst_bss; - break; - case N_RDATA: - ms_type = mst_bss; - break; - case N_IDATA: - ms_type = mst_data; - break; - case N_ABS: - ms_type = mst_abs; - break; - default: - ms_type = mst_unknown; - break; - } - - prim_record_minimal_symbol (name, address, ms_type, objfile); -} - -/* read and process .stb file and store in minimal symbol table */ -typedef char mhhdr[80]; -struct stbhdr - { - mhhdr comhdr; - char *name; - short fmtno; - int crc; - int offset; - int nsym; - char *pad; - }; -struct stbsymbol - { - int value; - short type; - int stroff; - }; -#define STBSYMSIZE 10 - -static void -read_minimal_symbols (struct objfile *objfile) -{ - FILE *fp; - bfd *abfd; - struct stbhdr hdr; - struct stbsymbol sym; - int ch, i, j, off; - char buf[64], buf1[128]; - - fp = objfile->auxf1; - if (fp == NULL) - return; - abfd = objfile->obfd; - fread (&hdr.comhdr[0], sizeof (mhhdr), 1, fp); - i = 0; - ch = getc (fp); - while (ch != -1) - { - buf[i] = (char) ch; - i++; - if (ch == 0) - break; - ch = getc (fp); - }; - if (i % 2) - ch = getc (fp); - hdr.name = &buf[0]; - - fread (&hdr.fmtno, sizeof (hdr.fmtno), 1, fp); - fread (&hdr.crc, sizeof (hdr.crc), 1, fp); - fread (&hdr.offset, sizeof (hdr.offset), 1, fp); - fread (&hdr.nsym, sizeof (hdr.nsym), 1, fp); - SWAP_STBHDR (&hdr, abfd); - - /* read symbols */ - init_minimal_symbol_collection (); - off = hdr.offset; - for (i = hdr.nsym; i > 0; i--) - { - fseek (fp, (long) off, 0); - fread (&sym.value, sizeof (sym.value), 1, fp); - fread (&sym.type, sizeof (sym.type), 1, fp); - fread (&sym.stroff, sizeof (sym.stroff), 1, fp); - SWAP_STBSYM (&sym, abfd); - fseek (fp, (long) sym.stroff, 0); - j = 0; - ch = getc (fp); - while (ch != -1) - { - buf1[j] = (char) ch; - j++; - if (ch == 0) - break; - ch = getc (fp); - }; - record_minimal_symbol (buf1, sym.value, sym.type & 7, objfile); - off += STBSYMSIZE; - }; - install_minimal_symbols (objfile); - return; -} - -/* Scan and build partial symbols for a symbol file. - We have been initialized by a call to os9k_symfile_init, which - put all the relevant info into a "struct os9k_symfile_info", - hung off the objfile structure. - - MAINLINE is true if we are reading the main symbol - table (as opposed to a shared lib or dynamically loaded file). */ - -static void -os9k_symfile_read (struct objfile *objfile, int mainline) -{ - bfd *sym_bfd; - struct cleanup *back_to; - - sym_bfd = objfile->obfd; - /* If we are reinitializing, or if we have never loaded syms yet, init */ - if (mainline - || (objfile->global_psymbols.size == 0 - && objfile->static_psymbols.size == 0)) - init_psymbol_list (objfile, DBX_SYMCOUNT (objfile)); - - free_pending_blocks (); - back_to = make_cleanup (really_free_pendings, 0); - - make_cleanup_discard_minimal_symbols (); - read_minimal_symbols (objfile); - - /* Now that the symbol table data of the executable file are all in core, - process them and define symbols accordingly. */ - read_os9k_psymtab (objfile, - DBX_TEXT_ADDR (objfile), - DBX_TEXT_SIZE (objfile)); - - do_cleanups (back_to); -} - -/* Initialize anything that needs initializing when a completely new - symbol file is specified (not just adding some symbols from another - file, e.g. a shared library). */ - -static void -os9k_new_init (struct objfile *ignore) -{ - stabsread_new_init (); - buildsym_new_init (); - psymfile_depth = 0; -/* - init_header_files (); - */ -} - -/* os9k_symfile_init () - It is passed a struct objfile which contains, among other things, - the BFD for the file whose symbols are being read, and a slot for a pointer - to "private data" which we fill with goodies. - - Since BFD doesn't know how to read debug symbols in a format-independent - way (and may never do so...), we have to do it ourselves. We will never - be called unless this is an a.out (or very similar) file. - FIXME, there should be a cleaner peephole into the BFD environment here. */ - -static void -os9k_symfile_init (struct objfile *objfile) -{ - bfd *sym_bfd = objfile->obfd; - char *name = bfd_get_filename (sym_bfd); - char dbgname[512], stbname[512]; - FILE *symfile = 0; - FILE *minfile = 0; - asection *text_sect; - - strcpy (dbgname, name); - strcat (dbgname, ".dbg"); - strcpy (stbname, name); - strcat (stbname, ".stb"); - - if ((symfile = fopen (dbgname, "r")) == NULL) - { - warning ("Symbol file %s not found", dbgname); - } - objfile->auxf2 = symfile; - - if ((minfile = fopen (stbname, "r")) == NULL) - { - warning ("Symbol file %s not found", stbname); - } - objfile->auxf1 = minfile; - - /* Allocate struct to keep track of the symfile */ - objfile->sym_stab_info = (struct dbx_symfile_info *) - xmmalloc (objfile->md, sizeof (struct dbx_symfile_info)); - DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL; - - text_sect = bfd_get_section_by_name (sym_bfd, ".text"); - if (!text_sect) - error ("Can't find .text section in file"); - DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect); - DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect); - - DBX_SYMBOL_SIZE (objfile) = 0; /* variable size symbol */ - DBX_SYMCOUNT (objfile) = 0; /* used to be bfd_get_symcount(sym_bfd) */ - DBX_SYMTAB_OFFSET (objfile) = 0; /* used to be SYMBOL_TABLE_OFFSET */ -} - -/* Perform any local cleanups required when we are done with a particular - objfile. I.E, we are in the process of discarding all symbol information - for an objfile, freeing up all memory held for it, and unlinking the - objfile struct from the global list of known objfiles. */ - -static void -os9k_symfile_finish (struct objfile *objfile) -{ - if (objfile->sym_stab_info != NULL) - { - xmfree (objfile->md, objfile->sym_stab_info); - } -/* - free_header_files (); - */ -} - - -struct st_dbghdr -{ - int sync; - short rev; - int crc; - short os; - short cpu; -}; -#define SYNC (int)0xefbefeca - -#define SWAP_DBGHDR(hdrp, abfd) \ - { \ - (hdrp)->sync = bfd_get_32(abfd, (unsigned char *)&(hdrp)->sync); \ - (hdrp)->rev = bfd_get_16(abfd, (unsigned char *)&(hdrp)->rev); \ - (hdrp)->crc = bfd_get_32(abfd, (unsigned char *)&(hdrp)->crc); \ - (hdrp)->os = bfd_get_16(abfd, (unsigned char *)&(hdrp)->os); \ - (hdrp)->cpu = bfd_get_16(abfd, (unsigned char *)&(hdrp)->cpu); \ - } - -#define N_SYM_CMPLR 0 -#define N_SYM_SLINE 1 -#define N_SYM_SYM 2 -#define N_SYM_LBRAC 3 -#define N_SYM_RBRAC 4 -#define N_SYM_SE 5 - -struct internal_symstruct - { - short n_type; - short n_desc; - long n_value; - char *n_strx; - }; -static struct internal_symstruct symbol; -static struct internal_symstruct *symbuf = &symbol; -static char strbuf[4096]; -static struct st_dbghdr dbghdr; -static short cmplrid; - -#define VER_PRE_ULTRAC ((short)4) -#define VER_ULTRAC ((short)5) - -static int -fill_sym (FILE *dbg_file, bfd *abfd) -{ - short si, nmask; - long li; - int ii; - char *p; - - int nbytes = fread (&si, sizeof (si), 1, dbg_file); - if (nbytes == 0) - return 0; - if (nbytes < 0) - perror_with_name ("reading .dbg file."); - symbuf->n_desc = 0; - symbuf->n_value = 0; - symbuf->n_strx = NULL; - symbuf->n_type = bfd_get_16 (abfd, (unsigned char *) &si); - symbuf->n_type = 0xf & symbuf->n_type; - switch (symbuf->n_type) - { - case N_SYM_CMPLR: - fread (&si, sizeof (si), 1, dbg_file); - symbuf->n_desc = bfd_get_16 (abfd, (unsigned char *) &si); - cmplrid = symbuf->n_desc & 0xff; - break; - case N_SYM_SLINE: - fread (&li, sizeof (li), 1, dbg_file); - symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li); - fread (&li, sizeof (li), 1, dbg_file); - li = bfd_get_32 (abfd, (unsigned char *) &li); - symbuf->n_strx = (char *) (li >> 12); - symbuf->n_desc = li & 0xfff; - break; - case N_SYM_SYM: - fread (&li, sizeof (li), 1, dbg_file); - symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li); - si = 0; - do - { - ii = getc (dbg_file); - strbuf[si++] = (char) ii; - } - while (ii != 0 || si % 2 != 0); - symbuf->n_strx = strbuf; - p = (char *) strchr (strbuf, ':'); - if (!p) - break; - if ((p[1] == 'F' || p[1] == 'f') && cmplrid == VER_PRE_ULTRAC) - { - fread (&si, sizeof (si), 1, dbg_file); - nmask = bfd_get_16 (abfd, (unsigned char *) &si); - for (ii = 0; ii < nmask; ii++) - fread (&si, sizeof (si), 1, dbg_file); - } - break; - case N_SYM_LBRAC: - fread (&li, sizeof (li), 1, dbg_file); - symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li); - break; - case N_SYM_RBRAC: - fread (&li, sizeof (li), 1, dbg_file); - symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li); - break; - case N_SYM_SE: - break; - } - return 1; -} - -/* 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. - SYMFILE_NAME is the name of the file we are reading from. */ - -static void -read_os9k_psymtab (struct objfile *objfile, CORE_ADDR text_addr, int text_size) -{ - register struct internal_symstruct *bufp = 0; /* =0 avoids gcc -Wall glitch */ - register char *namestring; - int past_first_source_file = 0; - CORE_ADDR last_o_file_start = 0; -#if 0 - struct cleanup *back_to; -#endif - bfd *abfd; - FILE *fp; - - /* End of the text segment of the executable file. */ - static CORE_ADDR end_of_text_addr; - - /* Current partial symtab */ - static struct partial_symtab *pst = 0; - - /* List of current psymtab's include files */ - char **psymtab_include_list; - int includes_allocated; - int includes_used; - - /* Index within current psymtab dependency list */ - struct partial_symtab **dependency_list; - int dependencies_used, dependencies_allocated; - - includes_allocated = 30; - includes_used = 0; - psymtab_include_list = (char **) alloca (includes_allocated * - sizeof (char *)); - - dependencies_allocated = 30; - dependencies_used = 0; - dependency_list = - (struct partial_symtab **) alloca (dependencies_allocated * - sizeof (struct partial_symtab *)); - - last_source_file = NULL; - -#ifdef END_OF_TEXT_DEFAULT - end_of_text_addr = END_OF_TEXT_DEFAULT; -#else - end_of_text_addr = text_addr + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)) - + text_size; /* Relocate */ -#endif - - abfd = objfile->obfd; - fp = objfile->auxf2; - if (!fp) - return; - - fread (&dbghdr.sync, sizeof (dbghdr.sync), 1, fp); - fread (&dbghdr.rev, sizeof (dbghdr.rev), 1, fp); - fread (&dbghdr.crc, sizeof (dbghdr.crc), 1, fp); - fread (&dbghdr.os, sizeof (dbghdr.os), 1, fp); - fread (&dbghdr.cpu, sizeof (dbghdr.cpu), 1, fp); - SWAP_DBGHDR (&dbghdr, abfd); - - symnum = 0; - while (1) - { - int ret; - long cursymoffset; - - /* Get the symbol for this run and pull out some info */ - QUIT; /* allow this to be interruptable */ - cursymoffset = ftell (objfile->auxf2); - ret = fill_sym (objfile->auxf2, abfd); - if (ret <= 0) - break; - else - symnum++; - bufp = symbuf; - - /* Special case to speed up readin. */ - if (bufp->n_type == (short) N_SYM_SLINE) - continue; - -#define CUR_SYMBOL_VALUE bufp->n_value - /* partial-stab.h */ - - switch (bufp->n_type) - { - char *p; - - case N_SYM_CMPLR: - continue; - - case N_SYM_SE: - CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (psymfile_depth == 1 && pst) - { - os9k_end_psymtab (pst, psymtab_include_list, includes_used, - symnum, CUR_SYMBOL_VALUE, - dependency_list, dependencies_used); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } - psymfile_depth--; - continue; - - case N_SYM_SYM: /* Typedef or automatic variable. */ - namestring = bufp->n_strx; - p = (char *) strchr (namestring, ':'); - if (!p) - continue; /* Not a debugging symbol. */ - - /* Main processing section for debugging symbols which - the initial read through the symbol tables needs to worry - about. If we reach this point, the symbol which we are - considering is definitely one we are interested in. - p must also contain the (valid) index into the namestring - which indicates the debugging type symbol. */ - - switch (p[1]) - { - case 'S': - { - unsigned long valu; - enum language tmp_language; - char *str, *p; - int n; - - valu = CUR_SYMBOL_VALUE; - if (valu) - valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - past_first_source_file = 1; - - p = strchr (namestring, ':'); - if (p) - n = p - namestring; - else - n = strlen (namestring); - str = alloca (n + 1); - strncpy (str, namestring, n); - str[n] = '\0'; - - if (psymfile_depth == 0) - { - if (!pst) - pst = os9k_start_psymtab (objfile, - str, valu, - cursymoffset, - symnum - 1, - objfile->global_psymbols.next, - objfile->static_psymbols.next); - } - else - { /* this is a include file */ - tmp_language = deduce_language_from_filename (str); - if (tmp_language != language_unknown - && (tmp_language != language_c - || psymtab_language != language_cplus)) - psymtab_language = tmp_language; - -/* - if (pst && STREQ (str, pst->filename)) - continue; - { - register int i; - for (i = 0; i < includes_used; i++) - if (STREQ (str, psymtab_include_list[i])) - { - i = -1; - break; - } - if (i == -1) - continue; - } - */ - - psymtab_include_list[includes_used++] = str; - if (includes_used >= includes_allocated) - { - char **orig = psymtab_include_list; - - psymtab_include_list = (char **) - alloca ((includes_allocated *= 2) * sizeof (char *)); - memcpy ((PTR) psymtab_include_list, (PTR) orig, - includes_used * sizeof (char *)); - } - - } - psymfile_depth++; - continue; - } - - case 'v': - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - &objfile->static_psymbols, - 0, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - case 'V': - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - &objfile->global_psymbols, - 0, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - case 'T': - if (p != namestring) /* a name is there, not just :T... */ - { - add_psymbol_to_list (namestring, p - namestring, - STRUCT_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, - psymtab_language, objfile); - if (p[2] == 't') - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, psymtab_language, - objfile); - p += 1; - } - /* The semantics of C++ state that "struct foo { ... }" - also defines a typedef for "foo". Unfortuantely, cfront - never makes the typedef when translating from C++ to C. - We make the typedef here so that "ptype foo" works as - expected for cfront translated code. */ - else if (psymtab_language == language_cplus) - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, psymtab_language, - objfile); - } - } - goto check_enum; - case 't': - if (p != namestring) /* a name is there, not just :T... */ - { - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, - psymtab_language, objfile); - } - check_enum: - /* If this is an enumerated type, we need to - add all the enum constants to the partial symbol - table. This does not cover enums without names, e.g. - "enum {a, b} c;" in C, but fortunately those are - rare. There is no way for GDB to find those from the - enum type without spending too much time on it. Thus - to solve this problem, the compiler needs to put out the - enum in a nameless type. GCC2 does this. */ - - /* We are looking for something of the form - ":" ("t" | "T") [ "="] "e" - { ":" ","} ";". */ - - /* Skip over the colon and the 't' or 'T'. */ - p += 2; - /* This type may be given a number. Also, numbers can come - in pairs like (0,26). Skip over it. */ - while ((*p >= '0' && *p <= '9') - || *p == '(' || *p == ',' || *p == ')' - || *p == '=') - p++; - - if (*p++ == 'e') - { - /* We have found an enumerated type. skip size */ - while (*p >= '0' && *p <= '9') - p++; - /* According to comments in read_enum_type - a comma could end it instead of a semicolon. - I don't know where that happens. - Accept either. */ - while (*p && *p != ';' && *p != ',') - { - char *q; - - /* Check for and handle cretinous dbx symbol name - continuation! - if (*p == '\\') - p = next_symbol_text (objfile); - */ - - /* Point to the character after the name - of the enum constant. */ - for (q = p; *q && *q != ':'; q++) - ; - /* Note that the value doesn't matter for - enum constants in psymtabs, just in symtabs. */ - add_psymbol_to_list (p, q - p, - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, 0, - 0, psymtab_language, objfile); - /* Point past the name. */ - p = q; - /* Skip over the value. */ - while (*p && *p != ',') - p++; - /* Advance past the comma. */ - if (*p) - p++; - } - } - continue; - case 'c': - /* Constant, e.g. from "const" in Pascal. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, CUR_SYMBOL_VALUE, - 0, psymtab_language, objfile); - continue; - - case 'f': - CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (pst && pst->textlow == 0) - pst->textlow = CUR_SYMBOL_VALUE; - - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - &objfile->static_psymbols, CUR_SYMBOL_VALUE, - 0, psymtab_language, objfile); - continue; - - case 'F': - CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (pst && pst->textlow == 0) - pst->textlow = CUR_SYMBOL_VALUE; - - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - &objfile->global_psymbols, CUR_SYMBOL_VALUE, - 0, psymtab_language, objfile); - continue; - - case 'p': - case 'l': - case 's': - continue; - - case ':': - /* It is a C++ nested symbol. We don't need to record it - (I don't think); if we try to look up foo::bar::baz, - then symbols for the symtab containing foo should get - read in, I think. */ - /* Someone says sun cc puts out symbols like - /foo/baz/maclib::/usr/local/bin/maclib, - which would get here with a symbol type of ':'. */ - continue; - - default: - /* Unexpected symbol descriptor. The second and subsequent stabs - of a continued stab can show up here. The question is - whether they ever can mimic a normal stab--it would be - nice if not, since we certainly don't want to spend the - time searching to the end of every string looking for - a backslash. */ - - complain (&unknown_symchar_complaint, p[1]); - continue; - } - - case N_SYM_RBRAC: - CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); -#ifdef HANDLE_RBRAC - HANDLE_RBRAC (CUR_SYMBOL_VALUE); - continue; -#endif - case N_SYM_LBRAC: - continue; - - default: - /* If we haven't found it yet, ignore it. It's probably some - new type we don't know about yet. */ - complain (&unknown_symtype_complaint, - local_hex_string ((unsigned long) bufp->n_type)); - continue; - } - } - - DBX_SYMCOUNT (objfile) = symnum; - - /* If there's stuff to be cleaned up, clean it up. */ - if (DBX_SYMCOUNT (objfile) > 0 -/*FIXME, does this have a bug at start address 0? */ - && last_o_file_start - && objfile->ei.entry_point < bufp->n_value - && objfile->ei.entry_point >= last_o_file_start) - { - objfile->ei.entry_file_lowpc = last_o_file_start; - objfile->ei.entry_file_highpc = bufp->n_value; - } - - if (pst) - { - os9k_end_psymtab (pst, psymtab_include_list, includes_used, - symnum, end_of_text_addr, - dependency_list, dependencies_used); - } -/* - do_cleanups (back_to); - */ -} - -/* Allocate and partially fill a partial symtab. It will be - completely filled at the end of the symbol list. - - SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR - is the address relative to which its symbols are (incremental) or 0 - (normal). */ - - -static struct partial_symtab * -os9k_start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow, - int ldsymoff, int ldsymcnt, - struct partial_symbol **global_syms, - struct partial_symbol **static_syms) -{ - struct partial_symtab *result = - start_psymtab_common (objfile, objfile->section_offsets, - filename, textlow, global_syms, static_syms); - - result->read_symtab_private = (char *) - obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc)); - - LDSYMOFF (result) = ldsymoff; - LDSYMCNT (result) = ldsymcnt; - result->read_symtab = os9k_psymtab_to_symtab; - - /* Deduce the source language from the filename for this psymtab. */ - psymtab_language = deduce_language_from_filename (filename); - return result; -} - -/* Close off the current usage of PST. - Returns PST or NULL if the partial symtab was empty and thrown away. - FIXME: List variables and peculiarities of same. */ - -static struct partial_symtab * -os9k_end_psymtab (struct partial_symtab *pst, char **include_list, - int num_includes, int capping_symbol_cnt, - CORE_ADDR capping_text, - struct partial_symtab **dependency_list, - int number_dependencies) -{ - int i; - struct partial_symtab *p1; - struct objfile *objfile = pst->objfile; - - if (capping_symbol_cnt != -1) - LDSYMCNT (pst) = capping_symbol_cnt - LDSYMCNT (pst); - - /* 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. - The first trick is in partial-stab.h: if we see a static - or global function, and the textlow for the current pst - is still 0, then we use that function's address for - the textlow of the pst. - - Now, to fill in texthigh, we remember the last function seen - in the .o file (also in partial-stab.h). Also, there's a hack in - bfd/elf.c and gdb/elfread.c to pass the ELF st_size field - to here via the misc_info field. Therefore, we can fill in - a reliable texthigh by taking the address plus size of the - last function in the file. - - Unfortunately, that does not cover the case where the last function - in the file is static. See the paragraph below for more comments - on this situation. - - Finally, if we have a valid textlow for the current file, we run - down the partial_symtab_list filling in previous texthighs that - are still unknown. */ - - if (pst->texthigh == 0 && last_function_name) - { - char *p; - int n; - struct minimal_symbol *minsym; - - p = strchr (last_function_name, ':'); - if (p == NULL) - p = last_function_name; - n = p - last_function_name; - p = alloca (n + 1); - strncpy (p, last_function_name, n); - p[n] = 0; - - minsym = lookup_minimal_symbol (p, NULL, objfile); - - if (minsym) - { - pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + (long) MSYMBOL_INFO (minsym); - } - else - { - /* This file ends with a static function, and it's - difficult to imagine how hard it would be to track down - the elf symbol. Luckily, most of the time no one will notice, - since the next file will likely be compiled with -g, so - the code below will copy the first fuction's start address - back to our texthigh variable. (Also, if this file is the - last one in a dynamically linked program, texthigh already - has the right value.) If the next file isn't compiled - with -g, then the last function in this file winds up owning - all of the text space up to the next -g file, or the end (minus - shared libraries). This only matters for single stepping, - and even then it will still work, except that it will single - step through all of the covered functions, instead of setting - breakpoints around them as it usualy does. This makes it - pretty slow, but at least it doesn't fail. - - We can fix this with a fairly big change to bfd, but we need - to coordinate better with Cygnus if we want to do that. FIXME. */ - } - last_function_name = NULL; - } - - /* this test will be true if the last .o file is only data */ - if (pst->textlow == 0) - pst->textlow = pst->texthigh; - - /* If we know our own starting text address, then walk through all other - psymtabs for this objfile, and if any didn't know their ending text - address, set it to our starting address. Take care to not set our - own ending address to our starting address, nor to set addresses on - `dependency' files that have both textlow and texthigh zero. */ - if (pst->textlow) - { - ALL_OBJFILE_PSYMTABS (objfile, p1) - { - if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst) - { - p1->texthigh = pst->textlow; - /* if this file has only data, then make textlow match texthigh */ - if (p1->textlow == 0) - p1->textlow = p1->texthigh; - } - } - } - - /* End of kludge for patching Solaris textlow and texthigh. */ - - pst->n_global_syms = - objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset); - pst->n_static_syms = - objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset); - - pst->number_of_dependencies = number_dependencies; - if (number_dependencies) - { - pst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, - number_dependencies * sizeof (struct partial_symtab *)); - memcpy (pst->dependencies, dependency_list, - number_dependencies * sizeof (struct partial_symtab *)); - } - else - pst->dependencies = 0; - - for (i = 0; i < num_includes; i++) - { - struct partial_symtab *subpst = - allocate_psymtab (include_list[i], objfile); - - subpst->section_offsets = pst->section_offsets; - subpst->read_symtab_private = - (char *) obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct symloc)); - LDSYMOFF (subpst) = - LDSYMCNT (subpst) = - subpst->textlow = - subpst->texthigh = 0; - - /* We could save slight bits of space by only making one of these, - shared by the entire set of include files. FIXME-someday. */ - subpst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct partial_symtab *)); - subpst->dependencies[0] = pst; - subpst->number_of_dependencies = 1; - - subpst->globals_offset = - subpst->n_global_syms = - subpst->statics_offset = - subpst->n_static_syms = 0; - - subpst->readin = 0; - subpst->symtab = 0; - subpst->read_symtab = pst->read_symtab; - } - - sort_pst_symbols (pst); - - /* If there is already a psymtab or symtab for a file of this name, - remove it. - (If there is a symtab, more drastic things also happen.) - This happens in VxWorks. */ - 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. */ - /* Indicate that psymtab was thrown away. */ - - discard_psymtab (pst); - - pst = (struct partial_symtab *) NULL; - } - return pst; -} - -static void -os9k_psymtab_to_symtab_1 (struct partial_symtab *pst) -{ - struct cleanup *old_chain; - int i; - - if (!pst) - return; - - if (pst->readin) - { - fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", - pst->filename); - return; - } - - /* Read in all partial symtabs on which this one is dependent */ - for (i = 0; i < pst->number_of_dependencies; i++) - if (!pst->dependencies[i]->readin) - { - /* Inform about additional files that need to be read in. */ - if (info_verbose) - { - fputs_filtered (" ", gdb_stdout); - wrap_here (""); - fputs_filtered ("and ", gdb_stdout); - wrap_here (""); - printf_filtered ("%s...", pst->dependencies[i]->filename); - wrap_here (""); /* Flush output */ - gdb_flush (gdb_stdout); - } - os9k_psymtab_to_symtab_1 (pst->dependencies[i]); - } - - if (LDSYMCNT (pst)) /* Otherwise it's a dummy */ - { - /* Init stuff necessary for reading in symbols */ - stabsread_init (); - buildsym_init (); - old_chain = make_cleanup (really_free_pendings, 0); - - /* Read in this file's symbols */ - os9k_read_ofile_symtab (pst); - sort_symtab_syms (pst->symtab); - do_cleanups (old_chain); - } - - pst->readin = 1; -} - -/* Read in all of the symbols for a given psymtab for real. - Be verbose about it if the user wants that. */ - -static void -os9k_psymtab_to_symtab (struct partial_symtab *pst) -{ - bfd *sym_bfd; - - if (!pst) - return; - - if (pst->readin) - { - fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", - pst->filename); - return; - } - - if (LDSYMCNT (pst) || pst->number_of_dependencies) - { - /* Print the message now, before reading the string table, - to avoid disconcerting pauses. */ - if (info_verbose) - { - printf_filtered ("Reading in symbols for %s...", pst->filename); - gdb_flush (gdb_stdout); - } - - sym_bfd = pst->objfile->obfd; - os9k_psymtab_to_symtab_1 (pst); - - /* Match with global symbols. This only needs to be done once, - after all of the symtabs and dependencies have been read in. */ - scan_file_globals (pst->objfile); - - /* Finish up the debug error message. */ - if (info_verbose) - printf_filtered ("done.\n"); - } -} - -/* Read in a defined section of a specific object file's symbols. */ -static void -os9k_read_ofile_symtab (struct partial_symtab *pst) -{ - register struct internal_symstruct *bufp; - unsigned char type; - unsigned max_symnum; - register bfd *abfd; - struct objfile *objfile; - int sym_offset; /* Offset to start of symbols to read */ - CORE_ADDR text_offset; /* Start of text segment for symbols */ - int text_size; /* Size of text segment for symbols */ - FILE *dbg_file; - - objfile = pst->objfile; - sym_offset = LDSYMOFF (pst); - max_symnum = LDSYMCNT (pst); - text_offset = pst->textlow; - text_size = pst->texthigh - pst->textlow; - - current_objfile = objfile; - subfile_stack = NULL; - last_source_file = NULL; - - abfd = objfile->obfd; - dbg_file = objfile->auxf2; - -#if 0 - /* It is necessary to actually read one symbol *before* the start - of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL - occurs before the N_SO symbol. - Detecting this in read_dbx_symtab - would slow down initial readin, so we look for it here instead. */ - if (!processing_acc_compilation && sym_offset >= (int) symbol_size) - { - fseek (objefile->auxf2, sym_offset, SEEK_CUR); - fill_sym (objfile->auxf2, abfd); - bufp = symbuf; - - processing_gcc_compilation = 0; - if (bufp->n_type == N_TEXT) - { - if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 1; - else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 2; - } - - /* Try to select a C++ demangling based on the compilation unit - producer. */ - - if (processing_gcc_compilation) - { - if (AUTO_DEMANGLING) - { - set_demangling_style (GNU_DEMANGLING_STYLE_STRING); - } - } - } - else - { - /* The N_SO starting this symtab is the first symbol, so we - better not check the symbol before it. I'm not this can - happen, but it doesn't hurt to check for it. */ - bfd_seek (symfile_bfd, sym_offset, SEEK_CUR); - processing_gcc_compilation = 0; - } -#endif /* 0 */ - - fseek (dbg_file, (long) sym_offset, 0); -/* - if (bufp->n_type != (unsigned char)N_SYM_SYM) - error("First symbol in segment of executable not a source symbol"); - */ - - for (symnum = 0; symnum < max_symnum; symnum++) - { - QUIT; /* Allow this to be interruptable */ - fill_sym (dbg_file, abfd); - bufp = symbuf; - type = bufp->n_type; - - os9k_process_one_symbol ((int) type, (int) bufp->n_desc, - (CORE_ADDR) bufp->n_value, bufp->n_strx, pst->section_offsets, objfile); - - /* We skip checking for a new .o or -l file; that should never - happen in this routine. */ -#if 0 - else - if (type == N_TEXT) - { - /* I don't think this code will ever be executed, because - the GCC_COMPILED_FLAG_SYMBOL usually is right before - the N_SO symbol which starts this source file. - However, there is no reason not to accept - the GCC_COMPILED_FLAG_SYMBOL anywhere. */ - - if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 1; - else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 2; - - if (AUTO_DEMANGLING) - { - set_demangling_style (GNU_DEMANGLING_STYLE_STRING); - } - } - else if (type & N_EXT || type == (unsigned char) N_TEXT - || type == (unsigned char) N_NBTEXT - ) - { - /* Global symbol: see if we came across a dbx defintion for - a corresponding symbol. If so, store the value. Remove - syms from the chain when their values are stored, but - search the whole chain, as there may be several syms from - different files with the same name. */ - /* This is probably not true. Since the files will be read - in one at a time, each reference to a global symbol will - be satisfied in each file as it appears. So we skip this - section. */ - ; - } -#endif /* 0 */ - } - - current_objfile = NULL; - - /* In a Solaris elf file, this variable, which comes from the - value of the N_SO symbol, will still be 0. Luckily, text_offset, - which comes from pst->textlow is correct. */ - if (last_source_start_addr == 0) - last_source_start_addr = text_offset; - pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile)); - end_stabs (); -} - - -/* This handles a single symbol from the symbol-file, building symbols - into a GDB symtab. It takes these arguments and an implicit argument. - - TYPE is the type field of the ".stab" symbol entry. - DESC is the desc field of the ".stab" entry. - VALU is the value field of the ".stab" entry. - NAME is the symbol name, in our address space. - SECTION_OFFSETS is a set of amounts by which the sections of this object - file were relocated when it was loaded into memory. - All symbols that refer - to memory locations need to be offset by these amounts. - OBJFILE is the object file from which we are reading symbols. - It is used in end_symtab. */ - -static void -os9k_process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, - struct section_offsets *section_offsets, - struct objfile *objfile) -{ - register struct context_stack *new; - /* The stab type used for the definition of the last function. - N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers. */ - static int function_stab_type = 0; - -#if 0 - /* Something is wrong if we see real data before - seeing a source file name. */ - if (last_source_file == NULL && type != (unsigned char) N_SO) - { - /* Ignore any symbols which appear before an N_SO symbol. - Currently no one puts symbols there, but we should deal - gracefully with the case. A complain()t might be in order, - but this should not be an error (). */ - return; - } -#endif /* 0 */ - - switch (type) - { - case N_SYM_LBRAC: - /* On most machines, the block addresses are relative to the - N_SO, the linker did not relocate them (sigh). */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); - new = push_context (desc, valu); - break; - - case N_SYM_RBRAC: - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); - new = pop_context (); - -#if !defined (OS9K_VARIABLES_INSIDE_BLOCK) -#define OS9K_VARIABLES_INSIDE_BLOCK(desc, gcc_p) 1 -#endif - - if (!OS9K_VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation)) - local_symbols = new->locals; - - if (context_stack_depth > 1) - { - /* 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) - { - /* 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); - } - } - else - { - if (context_stack_depth == 0) - { - within_function = 0; - /* Make a block for the local symbols within. */ - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, valu, objfile); - } - else - { - /* attach local_symbols to the end of new->locals */ - if (!new->locals) - new->locals = local_symbols; - else - { - struct pending *p; - - p = new->locals; - while (p->next) - p = p->next; - p->next = local_symbols; - } - } - } - - if (OS9K_VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation)) - /* Now pop locals of block just finished. */ - local_symbols = new->locals; - break; - - - case N_SYM_SLINE: - /* This type of "symbol" really just records - one line-number -- core-address correspondence. - Enter it in the line list for this symbol table. */ - /* Relocate for dynamic loading and for ELF acc fn-relative syms. */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); - /* FIXME: loses if sizeof (char *) > sizeof (int) */ - gdb_assert (sizeof (name) <= sizeof (int)); - record_line (current_subfile, (int) name, valu); - break; - - /* The following symbol types need to have the appropriate offset added - to their value; then we process symbol definitions in the name. */ - case N_SYM_SYM: - - if (name) - { - char deftype; - char *dirn, *n; - char *p = strchr (name, ':'); - if (p == NULL) - deftype = '\0'; - else - deftype = p[1]; - - - switch (deftype) - { - case 'S': - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); - n = strrchr (name, '/'); - if (n != NULL) - { - *n = '\0'; - n++; - dirn = name; - } - else - { - n = name; - dirn = NULL; - } - *p = '\0'; - if (symfile_depth++ == 0) - { - if (last_source_file) - { - end_symtab (valu, objfile, SECT_OFF_TEXT (objfile)); - end_stabs (); - } - start_stabs (); - os9k_stabs = 1; - start_symtab (n, dirn, valu); - record_debugformat ("OS9"); - } - else - { - push_subfile (); - start_subfile (n, dirn != NULL ? dirn : current_subfile->dirname); - } - break; - - case 'f': - case 'F': - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); - function_stab_type = type; - - within_function = 1; - new = push_context (0, valu); - new->name = define_symbol (valu, name, desc, type, objfile); - break; - - case 'V': - case 'v': - valu += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile)); - define_symbol (valu, name, desc, type, objfile); - break; - - default: - define_symbol (valu, name, desc, type, objfile); - break; - } - } - break; - - case N_SYM_SE: - if (--symfile_depth != 0) - start_subfile (pop_subfile (), current_subfile->dirname); - break; - - default: - complain (&unknown_symtype_complaint, - local_hex_string ((unsigned long) type)); - /* FALLTHROUGH */ - break; - - case N_SYM_CMPLR: - break; - } - previous_stab_code = type; -} - -static struct sym_fns os9k_sym_fns = -{ - bfd_target_os9k_flavour, - os9k_new_init, /* sym_new_init: init anything gbl to entire symtab */ - os9k_symfile_init, /* sym_init: read initial info, setup for sym_read() */ - os9k_symfile_read, /* sym_read: read a symbol file into symtab */ - os9k_symfile_finish, /* sym_finish: finished with file, cleanup */ - default_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_os9kread (void) -{ - add_symtab_fns (&os9k_sym_fns); -} diff --git a/contrib/gdb/gdb/partial-stab.h b/contrib/gdb/gdb/partial-stab.h deleted file mode 100644 index d74c1c9ca5f..00000000000 --- a/contrib/gdb/gdb/partial-stab.h +++ /dev/null @@ -1,812 +0,0 @@ -/* Shared code to pre-read a stab (dbx-style), when building a psymtab. - Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998 - Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* The following need to be defined: - SET_NAMESTRING() --Set namestring to name of symbol. - CUR_SYMBOL_TYPE --Type code of current symbol. - CUR_SYMBOL_VALUE --Value field of current symbol. May be adjusted here. - namestring - variable pointing to the name of the stab. - section_offsets - variable pointing to the section offsets. - pst - the partial symbol table being built. - - psymtab_include_list, includes_used, includes_allocated - list of include - file names (N_SOL) seen so far. - dependency_list, dependencies_used, dependencies_allocated - list of - N_EXCL stabs seen so far. - - END_PSYMTAB -- end a partial symbol table. - START_PSYMTAB -- start a partial symbol table. - */ - -/* End of macro definitions, now let's handle them symbols! */ - - switch (CUR_SYMBOL_TYPE) - { - char *p; - /* - * Standard, external, non-debugger, symbols - */ - - case N_TEXT | N_EXT: - case N_NBTEXT | N_EXT: - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); - goto record_it; - - case N_DATA | N_EXT: - case N_NBDATA | N_EXT: - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); - goto record_it; - - case N_BSS: - case N_BSS | N_EXT: - case N_NBBSS | N_EXT: - case N_SETV | N_EXT: /* FIXME, is this in BSS? */ - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_BSS); - goto record_it; - - case N_ABS | N_EXT: - record_it: -#ifdef DBXREAD_ONLY - SET_NAMESTRING(); - - bss_ext_symbol: - record_minimal_symbol (namestring, CUR_SYMBOL_VALUE, - CUR_SYMBOL_TYPE, objfile); /* Always */ -#endif /* DBXREAD_ONLY */ - continue; - - /* Standard, local, non-debugger, symbols */ - - case N_NBTEXT: - - /* We need to be able to deal with both N_FN or N_TEXT, - because we have no way of knowing whether the sys-supplied ld - or GNU ld was used to make the executable. Sequents throw - in another wrinkle -- they renumbered N_FN. */ - - case N_FN: - case N_FN_SEQ: - case N_TEXT: -#ifdef DBXREAD_ONLY - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); - SET_NAMESTRING(); - if ((namestring[0] == '-' && namestring[1] == 'l') - || (namestring [(nsl = strlen (namestring)) - 1] == 'o' - && namestring [nsl - 2] == '.')) - { - if (objfile -> ei.entry_point < CUR_SYMBOL_VALUE && - objfile -> ei.entry_point >= last_o_file_start) - { - objfile -> ei.entry_file_lowpc = last_o_file_start; - objfile -> ei.entry_file_highpc = CUR_SYMBOL_VALUE; - } - if (past_first_source_file && pst - /* The gould NP1 uses low values for .o and -l symbols - which are not the address. */ - && CUR_SYMBOL_VALUE >= pst->textlow) - { - END_PSYMTAB (pst, psymtab_include_list, includes_used, - symnum * symbol_size, - CUR_SYMBOL_VALUE > pst->texthigh - ? CUR_SYMBOL_VALUE : pst->texthigh, - dependency_list, dependencies_used, textlow_not_set); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } - else - past_first_source_file = 1; - last_o_file_start = CUR_SYMBOL_VALUE; - } - else - goto record_it; -#endif /* DBXREAD_ONLY */ - continue; - - case N_DATA: - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); - goto record_it; - - case N_UNDF | N_EXT: -#ifdef DBXREAD_ONLY - if (CUR_SYMBOL_VALUE != 0) { - /* This is a "Fortran COMMON" symbol. See if the target - environment knows where it has been relocated to. */ - - CORE_ADDR reladdr; - - SET_NAMESTRING(); - if (target_lookup_symbol (namestring, &reladdr)) { - continue; /* Error in lookup; ignore symbol for now. */ - } - CUR_SYMBOL_TYPE ^= (N_BSS^N_UNDF); /* Define it as a bss-symbol */ - CUR_SYMBOL_VALUE = reladdr; - goto bss_ext_symbol; - } -#endif /* DBXREAD_ONLY */ - continue; /* Just undefined, not COMMON */ - - case N_UNDF: -#ifdef DBXREAD_ONLY - if (processing_acc_compilation && CUR_SYMBOL_STRX == 1) { - /* Deal with relative offsets in the string table - used in ELF+STAB under Solaris. If we want to use the - n_strx field, which contains the name of the file, - we must adjust file_string_table_offset *before* calling - SET_NAMESTRING(). */ - past_first_source_file = 1; - file_string_table_offset = next_file_string_table_offset; - next_file_string_table_offset = - file_string_table_offset + CUR_SYMBOL_VALUE; - if (next_file_string_table_offset < file_string_table_offset) - error ("string table offset backs up at %d", symnum); - /* FIXME -- replace error() with complaint. */ - continue; - } -#endif /* DBXREAD_ONLY */ - continue; - - /* Lots of symbol types we can just ignore. */ - - case N_ABS: - case N_NBDATA: - case N_NBBSS: - continue; - - /* Keep going . . .*/ - - /* - * Special symbol types for GNU - */ - case N_INDR: - case N_INDR | N_EXT: - case N_SETA: - case N_SETA | N_EXT: - case N_SETT: - case N_SETT | N_EXT: - case N_SETD: - case N_SETD | N_EXT: - case N_SETB: - case N_SETB | N_EXT: - case N_SETV: - continue; - - /* - * Debugger symbols - */ - - case N_SO: { - unsigned long valu; - static int prev_so_symnum = -10; - static int first_so_symnum; - char *p; - int prev_textlow_not_set; - - valu = CUR_SYMBOL_VALUE + ANOFFSET (section_offsets, SECT_OFF_TEXT); - - prev_textlow_not_set = textlow_not_set; - -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* A zero value is probably an indication for the SunPRO 3.0 - compiler. end_psymtab explicitly tests for zero, so - don't relocate it. */ - - if (CUR_SYMBOL_VALUE == 0) - { - textlow_not_set = 1; - valu = 0; - } - else - textlow_not_set = 0; -#else - textlow_not_set = 0; -#endif - past_first_source_file = 1; - - if (prev_so_symnum != symnum - 1) - { /* Here if prev stab wasn't N_SO */ - first_so_symnum = symnum; - - if (pst) - { - END_PSYMTAB (pst, psymtab_include_list, includes_used, - symnum * symbol_size, - valu > pst->texthigh ? valu : pst->texthigh, - dependency_list, dependencies_used, - prev_textlow_not_set); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } - } - - prev_so_symnum = symnum; - - /* End the current partial symtab and start a new one */ - - SET_NAMESTRING(); - - /* Null name means end of .o file. Don't start a new one. */ - if (*namestring == '\000') - continue; - - /* Some compilers (including gcc) emit a pair of initial N_SOs. - The first one is a directory name; the second the file name. - If pst exists, is empty, and has a filename ending in '/', - we assume the previous N_SO was a directory name. */ - - p = strrchr (namestring, '/'); - if (p && *(p+1) == '\000') - continue; /* Simply ignore directory name SOs */ - - /* Some other compilers (C++ ones in particular) emit useless - SOs for non-existant .c files. We ignore all subsequent SOs that - immediately follow the first. */ - - if (!pst) - pst = START_PSYMTAB (objfile, section_offsets, - namestring, valu, - first_so_symnum * symbol_size, - objfile -> global_psymbols.next, - objfile -> static_psymbols.next); - continue; - } - - case N_BINCL: - { -#ifdef DBXREAD_ONLY - enum language tmp_language; - /* Add this bincl to the bincl_list for future EXCLs. No - need to save the string; it'll be around until - read_dbx_symtab function returns */ - - SET_NAMESTRING(); - - tmp_language = deduce_language_from_filename (namestring); - - /* Only change the psymtab's language if we've learned - something useful (eg. tmp_language is not language_unknown). - In addition, to match what start_subfile does, never change - from C++ to C. */ - if (tmp_language != language_unknown - && (tmp_language != language_c - || psymtab_language != language_cplus)) - psymtab_language = tmp_language; - - if (pst == NULL) - { - /* FIXME: we should not get here without a PST to work on. - Attempt to recover. */ - complain (&unclaimed_bincl_complaint, namestring, symnum); - continue; - } - add_bincl_to_list (pst, namestring, CUR_SYMBOL_VALUE); - - /* Mark down an include file in the current psymtab */ - - goto record_include_file; - -#else /* DBXREAD_ONLY */ - continue; -#endif - } - - case N_SOL: - { - enum language tmp_language; - /* Mark down an include file in the current psymtab */ - - SET_NAMESTRING(); - - tmp_language = deduce_language_from_filename (namestring); - - /* Only change the psymtab's language if we've learned - something useful (eg. tmp_language is not language_unknown). - In addition, to match what start_subfile does, never change - from C++ to C. */ - if (tmp_language != language_unknown - && (tmp_language != language_c - || psymtab_language != language_cplus)) - psymtab_language = tmp_language; - - /* In C++, one may expect the same filename to come round many - times, when code is coming alternately from the main file - and from inline functions in other files. So I check to see - if this is a file we've seen before -- either the main - source file, or a previously included file. - - This seems to be a lot of time to be spending on N_SOL, but - things like "break c-exp.y:435" need to work (I - suppose the psymtab_include_list could be hashed or put - in a binary tree, if profiling shows this is a major hog). */ - if (pst && STREQ (namestring, pst->filename)) - continue; - { - register int i; - for (i = 0; i < includes_used; i++) - if (STREQ (namestring, psymtab_include_list[i])) - { - i = -1; - break; - } - if (i == -1) - continue; - } - -#ifdef DBXREAD_ONLY - record_include_file: -#endif - - psymtab_include_list[includes_used++] = namestring; - if (includes_used >= includes_allocated) - { - char **orig = psymtab_include_list; - - psymtab_include_list = (char **) - alloca ((includes_allocated *= 2) * - sizeof (char *)); - memcpy ((PTR)psymtab_include_list, (PTR)orig, - includes_used * sizeof (char *)); - } - continue; - } - case N_LSYM: /* Typedef or automatic variable. */ - case N_STSYM: /* Data seg var -- static */ - case N_LCSYM: /* BSS " */ - case N_ROSYM: /* Read-only data seg var -- static. */ - case N_NBSTS: /* Gould nobase. */ - case N_NBLCS: /* symbols. */ - case N_FUN: - case N_GSYM: /* Global (extern) variable; can be - data or bss (sigh FIXME). */ - - /* Following may probably be ignored; I'll leave them here - for now (until I do Pascal and Modula 2 extensions). */ - - case N_PC: /* I may or may not need this; I - suspect not. */ - case N_M2C: /* I suspect that I can ignore this here. */ - case N_SCOPE: /* Same. */ - - SET_NAMESTRING(); - -#ifdef DBXREAD_ONLY - /* See if this is an end of function stab. */ - if (CUR_SYMBOL_TYPE == N_FUN && *namestring == '\000') - { - unsigned long valu; - - /* It's value is the size (in bytes) of the function for - function relative stabs, or the address of the function's - end for old style stabs. */ - valu = CUR_SYMBOL_VALUE + last_function_start; - if (pst->texthigh == 0 || valu > pst->texthigh) - pst->texthigh = valu; - break; - } -#endif - - p = (char *) strchr (namestring, ':'); - if (!p) - continue; /* Not a debugging symbol. */ - - - - /* Main processing section for debugging symbols which - the initial read through the symbol tables needs to worry - about. If we reach this point, the symbol which we are - considering is definitely one we are interested in. - p must also contain the (valid) index into the namestring - which indicates the debugging type symbol. */ - - switch (p[1]) - { - case 'S': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); -#ifdef STATIC_TRANSFORM_NAME - namestring = STATIC_TRANSFORM_NAME (namestring); -#endif - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - &objfile->static_psymbols, - 0, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - case 'G': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); - /* The addresses in these entries are reported to be - wrong. See the code that reads 'G's for symtabs. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - &objfile->global_psymbols, - 0, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - case 'T': - if (p != namestring) /* a name is there, not just :T... */ - { - add_psymbol_to_list (namestring, p - namestring, - STRUCT_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, - psymtab_language, objfile); - if (p[2] == 't') - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, - psymtab_language, objfile); - p += 1; - } - /* The semantics of C++ state that "struct foo { ... }" - also defines a typedef for "foo". Unfortuantely, cfront - never makes the typedef when translating from C++ to C. - We make the typedef here so that "ptype foo" works as - expected for cfront translated code. */ - else if (psymtab_language == language_cplus) - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, - psymtab_language, objfile); - } - } - goto check_enum; - case 't': - if (p != namestring) /* a name is there, not just :T... */ - { - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - CUR_SYMBOL_VALUE, 0, - psymtab_language, objfile); - } - check_enum: - /* If this is an enumerated type, we need to - add all the enum constants to the partial symbol - table. This does not cover enums without names, e.g. - "enum {a, b} c;" in C, but fortunately those are - rare. There is no way for GDB to find those from the - enum type without spending too much time on it. Thus - to solve this problem, the compiler needs to put out the - enum in a nameless type. GCC2 does this. */ - - /* We are looking for something of the form - ":" ("t" | "T") [ "="] "e" - { ":" ","} ";". */ - - /* Skip over the colon and the 't' or 'T'. */ - p += 2; - /* This type may be given a number. Also, numbers can come - in pairs like (0,26). Skip over it. */ - while ((*p >= '0' && *p <= '9') - || *p == '(' || *p == ',' || *p == ')' - || *p == '=') - p++; - - if (*p++ == 'e') - { - /* The aix4 compiler emits extra crud before the members. */ - if (*p == '-') - { - /* Skip over the type (?). */ - while (*p != ':') - p++; - - /* Skip over the colon. */ - p++; - } - - /* We have found an enumerated type. */ - /* According to comments in read_enum_type - a comma could end it instead of a semicolon. - I don't know where that happens. - Accept either. */ - while (*p && *p != ';' && *p != ',') - { - char *q; - - /* Check for and handle cretinous dbx symbol name - continuation! */ - if (*p == '\\' || (*p == '?' && p[1] == '\0')) - p = next_symbol_text (objfile); - - /* Point to the character after the name - of the enum constant. */ - for (q = p; *q && *q != ':'; q++) - ; - /* Note that the value doesn't matter for - enum constants in psymtabs, just in symtabs. */ - add_psymbol_to_list (p, q - p, - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, 0, - 0, psymtab_language, objfile); - /* Point past the name. */ - p = q; - /* Skip over the value. */ - while (*p && *p != ',') - p++; - /* Advance past the comma. */ - if (*p) - p++; - } - } - continue; - case 'c': - /* Constant, e.g. from "const" in Pascal. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, CUR_SYMBOL_VALUE, - 0, psymtab_language, objfile); - continue; - - case 'f': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); -#ifdef DBXREAD_ONLY - /* Keep track of the start of the last function so we - can handle end of function symbols. */ - last_function_start = CUR_SYMBOL_VALUE; - /* Kludges for ELF/STABS with Sun ACC */ - last_function_name = namestring; -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit - value for the bottom of the text seg in those cases. */ - if (pst && textlow_not_set) - { - pst->textlow = - find_stab_function_addr (namestring, pst, objfile); - textlow_not_set = 0; - } -#endif -#if 0 - if (startup_file_end == 0) - startup_file_end = CUR_SYMBOL_VALUE; -#endif - /* End kludge. */ - - /* In reordered executables this function may lie outside - the bounds created by N_SO symbols. If that's the case - use the address of this function as the low bound for - the partial symbol table. */ - if (textlow_not_set - || (CUR_SYMBOL_VALUE < pst->textlow - && CUR_SYMBOL_VALUE - != ANOFFSET (section_offsets, SECT_OFF_TEXT))) - { - pst->textlow = CUR_SYMBOL_VALUE; - textlow_not_set = 0; - } -#endif /* DBXREAD_ONLY */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - &objfile->static_psymbols, - 0, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - /* Global functions were ignored here, but now they - are put into the global psymtab like one would expect. - They're also in the minimal symbol table. */ - case 'F': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); -#ifdef DBXREAD_ONLY - /* Keep track of the start of the last function so we - can handle end of function symbols. */ - last_function_start = CUR_SYMBOL_VALUE; - /* Kludges for ELF/STABS with Sun ACC */ - last_function_name = namestring; -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit - value for the bottom of the text seg in those cases. */ - if (pst && textlow_not_set) - { - pst->textlow = - find_stab_function_addr (namestring, pst, objfile); - textlow_not_set = 0; - } -#endif -#if 0 - if (startup_file_end == 0) - startup_file_end = CUR_SYMBOL_VALUE; -#endif - /* End kludge. */ - /* In reordered executables this function may lie outside - the bounds created by N_SO symbols. If that's the case - use the address of this function as the low bound for - the partial symbol table. */ - if (textlow_not_set - || (CUR_SYMBOL_VALUE < pst->textlow - && CUR_SYMBOL_VALUE - != ANOFFSET (section_offsets, SECT_OFF_TEXT))) - { - pst->textlow = CUR_SYMBOL_VALUE; - textlow_not_set = 0; - } -#endif /* DBXREAD_ONLY */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - &objfile->global_psymbols, - 0, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - /* Two things show up here (hopefully); static symbols of - local scope (static used inside braces) or extensions - of structure symbols. We can ignore both. */ - case 'V': - case '(': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - case '#': /* for symbol identification (used in live ranges) */ - /* added to support cfront stabs strings */ - case 'Z': /* for definition continuations */ - case 'P': /* for prototypes */ - continue; - - case ':': - /* It is a C++ nested symbol. We don't need to record it - (I don't think); if we try to look up foo::bar::baz, - then symbols for the symtab containing foo should get - read in, I think. */ - /* Someone says sun cc puts out symbols like - /foo/baz/maclib::/usr/local/bin/maclib, - which would get here with a symbol type of ':'. */ - continue; - - default: - /* Unexpected symbol descriptor. The second and subsequent stabs - of a continued stab can show up here. The question is - whether they ever can mimic a normal stab--it would be - nice if not, since we certainly don't want to spend the - time searching to the end of every string looking for - a backslash. */ - - complain (&unknown_symchar_complaint, p[1]); - - /* Ignore it; perhaps it is an extension that we don't - know about. */ - continue; - } - - case N_EXCL: -#ifdef DBXREAD_ONLY - - SET_NAMESTRING(); - - /* Find the corresponding bincl and mark that psymtab on the - psymtab dependency list */ - { - struct partial_symtab *needed_pst = - find_corresponding_bincl_psymtab (namestring, CUR_SYMBOL_VALUE); - - /* If this include file was defined earlier in this file, - leave it alone. */ - if (needed_pst == pst) continue; - - if (needed_pst) - { - int i; - int found = 0; - - for (i = 0; i < dependencies_used; i++) - if (dependency_list[i] == needed_pst) - { - found = 1; - break; - } - - /* If it's already in the list, skip the rest. */ - if (found) continue; - - dependency_list[dependencies_used++] = needed_pst; - if (dependencies_used >= dependencies_allocated) - { - struct partial_symtab **orig = dependency_list; - dependency_list = - (struct partial_symtab **) - alloca ((dependencies_allocated *= 2) - * sizeof (struct partial_symtab *)); - memcpy ((PTR)dependency_list, (PTR)orig, - (dependencies_used - * sizeof (struct partial_symtab *))); -#ifdef DEBUG_INFO - fprintf_unfiltered (gdb_stderr, "Had to reallocate dependency list.\n"); - fprintf_unfiltered (gdb_stderr, "New dependencies allocated: %d\n", - dependencies_allocated); -#endif - } - } - } -#endif /* DBXREAD_ONLY */ - continue; - - case N_ENDM: -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* Solaris 2 end of module, finish current partial symbol table. - END_PSYMTAB will set pst->texthigh to the proper value, which - is necessary if a module compiled without debugging info - follows this module. */ - if (pst) - { - END_PSYMTAB (pst, psymtab_include_list, includes_used, - symnum * symbol_size, - (CORE_ADDR) 0, - dependency_list, dependencies_used, textlow_not_set); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } -#endif - continue; - - case N_RBRAC: -#ifdef HANDLE_RBRAC - HANDLE_RBRAC(CUR_SYMBOL_VALUE); - continue; -#endif - case N_EINCL: - case N_DSLINE: - case N_BSLINE: - case N_SSYM: /* Claim: Structure or union element. - Hopefully, I can ignore this. */ - case N_ENTRY: /* Alternate entry point; can ignore. */ - case N_MAIN: /* Can definitely ignore this. */ - case N_CATCH: /* These are GNU C++ extensions */ - case N_EHDECL: /* that can safely be ignored here. */ - case N_LENG: - case N_BCOMM: - case N_ECOMM: - case N_ECOML: - case N_FNAME: - case N_SLINE: - case N_RSYM: - case N_PSYM: - case N_LBRAC: - case N_NSYMS: /* Ultrix 4.0: symbol count */ - case N_DEFD: /* GNU Modula-2 */ - case N_ALIAS: /* SunPro F77: alias name, ignore for now. */ - - case N_OBJ: /* useless types from Solaris */ - case N_OPT: - /* These symbols aren't interesting; don't worry about them */ - - continue; - - default: - /* If we haven't found it yet, ignore it. It's probably some - new type we don't know about yet. */ - complain (&unknown_symtype_complaint, - local_hex_string (CUR_SYMBOL_TYPE)); - continue; - } diff --git a/contrib/gdb/gdb/ptx4-nat.c b/contrib/gdb/gdb/ptx4-nat.c deleted file mode 100644 index 65eef9d3518..00000000000 --- a/contrib/gdb/gdb/ptx4-nat.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Native-dependent code for ptx 4.0 - Copyright 1988, 1989, 1991, 1992, 1994, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "gdbcore.h" -#include "regcache.h" -#include -#include -#include -#include - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -/* Given a pointer to a general register set in /proc format (gregset_t *), - unpack the register contents and supply them as gdb's idea of the current - register values. */ - -void -supply_gregset (gregset_t *gregsetp) -{ - supply_register (EAX_REGNUM, (char *) &(*gregsetp)[EAX]); - supply_register (EDX_REGNUM, (char *) &(*gregsetp)[EDX]); - supply_register (ECX_REGNUM, (char *) &(*gregsetp)[ECX]); - supply_register (EBX_REGNUM, (char *) &(*gregsetp)[EBX]); - supply_register (ESI_REGNUM, (char *) &(*gregsetp)[ESI]); - supply_register (EDI_REGNUM, (char *) &(*gregsetp)[EDI]); - supply_register (ESP_REGNUM, (char *) &(*gregsetp)[UESP]); - supply_register (EBP_REGNUM, (char *) &(*gregsetp)[EBP]); - supply_register (EIP_REGNUM, (char *) &(*gregsetp)[EIP]); - supply_register (EFLAGS_REGNUM, (char *) &(*gregsetp)[EFL]); -} - -void -fill_gregset (gregset_t *gregsetp, int regno) -{ - int regi; - - for (regi = 0; regi < NUM_REGS; regi++) - { - if ((regno == -1) || (regno == regi)) - { - (*gregsetp)[regi] = *(greg_t *) & registers[REGISTER_BYTE (regi)]; - } - } -} - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), unpack the register contents and supply them as gdb's - idea of the current floating point register values. */ - -void -supply_fpregset (fpregset_t *fpregsetp) -{ - supply_fpu_registers ((struct fpusave *) &fpregsetp->fp_reg_set); - supply_fpa_registers ((struct fpasave *) &fpregsetp->f_wregs); -} - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), update the register specified by REGNO from gdb's idea - of the current floating point register set. If REGNO is -1, update - them all. */ - -void -fill_fpregset (fpregset_t *fpregsetp, int regno) -{ - int regi; - char *to; - char *from; - - /* FIXME: see m68k-tdep.c for an example, for the m68k. */ -} - -/* - * This doesn't quite do the same thing as the procfs.c version, but give - * it the same name so we don't have to put an ifdef in solib.c. - */ -/* this could use elf_interpreter() from elfread.c */ -int -proc_iterate_over_mappings (int (*func) (int, CORE_ADDR)) -{ - vaddr_t curseg, memptr; - pt_vseg_t pv; - int rv, cmperr; - sec_ptr interp_sec; - char *interp_content; - int interp_fd, funcstat; - unsigned int size; - char buf1[NBPG], buf2[NBPG]; - - /* - * The following is really vile. We can get the name of the - * shared library from the exec_bfd, and we can get a list of - * each virtual memory segment, but there is no simple way to - * find the mapped segment from the shared library (ala - * procfs's PIOCOPENMEM). As a pretty nasty kludge, we - * compare the virtual memory segment to the contents of the - * .interp file. If they match, we assume that we've got the - * right one. - */ - - /* - * TODO: for attach, use XPT_OPENT to get the executable, in - * case we're attached without knowning the executable's - * filename. - */ - -#ifdef VERBOSE_DEBUG - printf ("proc_iter\n"); -#endif - interp_sec = bfd_get_section_by_name (exec_bfd, ".interp"); - if (!interp_sec) - { - return 0; - } - - size = bfd_section_size (exec_bfd, interp_sec); - interp_content = alloca (size); - if (0 == bfd_get_section_contents (exec_bfd, interp_sec, - interp_content, (file_ptr) 0, size)) - { - return 0; - } - -#ifdef VERBOSE_DEBUG - printf ("proc_iter: \"%s\"\n", interp_content); -#endif - interp_fd = open (interp_content, O_RDONLY, 0); - if (-1 == interp_fd) - { - return 0; - } - - curseg = 0; - while (1) - { - rv = ptrace (PT_NEXT_VSEG, PIDGET (inferior_ptid), &pv, curseg); -#ifdef VERBOSE_DEBUG - printf ("PT_NEXT_VSEG: rv %d errno %d\n", rv, errno); -#endif - if (-1 == rv) - break; - if (0 == rv) - break; -#ifdef VERBOSE_DEBUG - printf ("pv.pv_start 0x%x pv_size 0x%x pv_prot 0x%x\n", - pv.pv_start, pv.pv_size, pv.pv_prot); -#endif - curseg = pv.pv_start + pv.pv_size; - - rv = lseek (interp_fd, 0, SEEK_SET); - if (-1 == rv) - { - perror ("lseek"); - close (interp_fd); - return 0; - } - for (memptr = pv.pv_start; memptr < pv.pv_start + pv.pv_size; - memptr += NBPG) - { -#ifdef VERBOSE_DEBUG - printf ("memptr 0x%x\n", memptr); -#endif - rv = read (interp_fd, buf1, NBPG); - if (-1 == rv) - { - perror ("read"); - close (interp_fd); - return 0; - } - rv = ptrace (PT_RDATA_PAGE, PIDGET (inferior_ptid), buf2, - memptr); - if (-1 == rv) - { - perror ("ptrace"); - close (interp_fd); - return 0; - } - cmperr = memcmp (buf1, buf2, NBPG); - if (cmperr) - break; - } - if (0 == cmperr) - { - /* this is it */ - funcstat = (*func) (interp_fd, pv.pv_start); - break; - } - } - close (interp_fd); - return 0; -} diff --git a/contrib/gdb/gdb/pyr-tdep.c b/contrib/gdb/gdb/pyr-tdep.c deleted file mode 100644 index 85e9a072f3c..00000000000 --- a/contrib/gdb/gdb/pyr-tdep.c +++ /dev/null @@ -1,452 +0,0 @@ -/* Pyramid target-dependent code for GDB. - Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" - -/*** Prettier register printing. ***/ - -/* Print registers in the same format as pyramid's dbx, adb, sdb. */ -pyr_print_registers(reg_buf, regnum) - long *reg_buf[]; -{ - register int regno; - int usp, ksp; - struct user u; - - for (regno = 0; regno < 16; regno++) { - printf_unfiltered/*_filtered*/ ("%6.6s: %8x %6.6s: %8x %6s: %8x %6s: %8x\n", - REGISTER_NAME (regno), reg_buf[regno], - REGISTER_NAME (regno+16), reg_buf[regno+16], - REGISTER_NAME (regno+32), reg_buf[regno+32], - REGISTER_NAME (regno+48), reg_buf[regno+48]); - } - usp = ptrace (3, inferior_pid, - (PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_usp) - - ((char *)&u), 0); - ksp = ptrace (3, inferior_pid, - (PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_ksp) - - ((char *)&u), 0); - printf_unfiltered/*_filtered*/ ("\n%6.6s: %8x %6.6s: %8x (%08x) %6.6s %8x\n", - REGISTER_NAME (CSP_REGNUM),reg_buf[CSP_REGNUM], - REGISTER_NAME (KSP_REGNUM), reg_buf[KSP_REGNUM], ksp, - "usp", usp); -} - -/* Print the register regnum, or all registers if regnum is -1. - fpregs is currently ignored. */ - -pyr_do_registers_info (regnum, fpregs) - int regnum; - int fpregs; -{ - /* On a pyr, we know a virtual register can always fit in an long. - Here (and elsewhere) we take advantage of that. Yuk. */ - long raw_regs[MAX_REGISTER_RAW_SIZE*NUM_REGS]; - register int i; - - for (i = 0 ; i < 64 ; i++) { - read_relative_register_raw_bytes(i, raw_regs+i); - } - if (regnum == -1) - pyr_print_registers (raw_regs, regnum); - else - for (i = 0; i < NUM_REGS; i++) - if (i == regnum) { - long val = raw_regs[i]; - - fputs_filtered (REGISTER_NAME (i), gdb_stdout); - printf_filtered(":"); - print_spaces_filtered (6 - strlen (REGISTER_NAME (i)), gdb_stdout); - if (val == 0) - printf_filtered ("0"); - else - printf_filtered ("%s %d", local_hex_string_custom(val,"08"), val); - printf_filtered("\n"); - } -} - -/*** Debugging editions of various macros from m-pyr.h ****/ - -CORE_ADDR frame_locals_address (frame) - struct frame_info *frame; -{ - register int addr = find_saved_register (frame,CFP_REGNUM); - register int result = read_memory_integer (addr, 4); -#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING - fprintf_unfiltered (gdb_stderr, - "\t[[..frame_locals:%8x, %s= %x @%x fcfp= %x foo= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n", - frame->frame, - REGISTER_NAME (CFP_REGNUM), - result, addr, - frame->frame_cfp, (CFP_REGNUM), - - - read_register(13), read_register(29), read_register(61), - find_saved_register(frame, 61)); -#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */ - - /* FIXME: I thought read_register (CFP_REGNUM) should be the right answer; - or at least CFP_REGNUM relative to FRAME (ie, result). - There seems to be a bug in the way the innermost frame is set up. */ - - return ((frame->next) ? result: frame->frame_cfp); -} - -CORE_ADDR frame_args_addr (frame) - struct frame_info *frame; -{ - register int addr = find_saved_register (frame,CFP_REGNUM); - register int result = read_memory_integer (addr, 4); - -#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING - fprintf_unfiltered (gdb_stderr, - "\t[[..frame_args:%8x, %s= %x @%x fcfp= %x r_r= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n", - frame->frame, - REGISTER_NAME (CFP_REGNUM), - result, addr, - frame->frame_cfp, read_register(CFP_REGNUM), - - read_register(13), read_register(29), read_register(61), - find_saved_register(frame, 61)); -#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */ - - /* FIXME: I thought read_register (CFP_REGNUM) should be the right answer; - or at least CFP_REGNUM relative to FRAME (ie, result). - There seems to be a bug in the way the innermost frame is set up. */ - return ((frame->next) ? result: frame->frame_cfp); -} - -#include "symtab.h" -#include "opcode/pyr.h" -#include "gdbcore.h" - - -/* A couple of functions used for debugging frame-handling on - Pyramids. (The Pyramid-dependent handling of register values for - windowed registers is known to be buggy.) - - When debugging, these functions can supplant the normal definitions of some - of the macros in tm-pyramid.h The quantity of information produced - when these functions are used makes the gdb unusable as a - debugger for user programs. */ - -extern unsigned pyr_saved_pc(), pyr_frame_chain(); - -CORE_ADDR pyr_frame_chain(frame) - CORE_ADDR frame; -{ - int foo=frame - CONTROL_STACK_FRAME_SIZE; - /* printf_unfiltered ("...following chain from %x: got %x\n", frame, foo);*/ - return foo; -} - -CORE_ADDR pyr_saved_pc(frame) - CORE_ADDR frame; -{ - int foo=0; - foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4); - printf_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n", - frame, 60/4, foo); - return foo; -} - -/* Pyramid instructions are never longer than this many bytes. */ -#define MAXLEN 24 - -/* Number of elements in the opcode table. */ -/*const*/ static int nopcodes = (sizeof (pyr_opcodes) / sizeof( pyr_opcodes[0])); -#define NOPCODES (nopcodes) - -/* Let's be byte-independent so we can use this as a cross-assembler. */ - -#define NEXTLONG(p) \ - (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]) - -/* Print one instruction at address MEMADDR in debugged memory, - on STREAM. Returns length of the instruction, in bytes. */ - -int -pyr_print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; -{ - unsigned char buffer[MAXLEN]; - register int i, nargs, insn_size =4; - register unsigned char *p; - register char *d; - register int insn_opcode, operand_mode; - register int index_multiplier, index_reg_regno, op_1_regno, op_2_regno ; - long insn; /* first word of the insn, not broken down. */ - pyr_insn_format insn_decode; /* the same, broken out into op{code,erands} */ - long extra_1, extra_2; - - read_memory (memaddr, buffer, MAXLEN); - insn_decode = *((pyr_insn_format *) buffer); - insn = * ((int *) buffer); - insn_opcode = insn_decode.operator; - operand_mode = insn_decode.mode; - index_multiplier = insn_decode.index_scale; - index_reg_regno = insn_decode.index_reg; - op_1_regno = insn_decode.operand_1; - op_2_regno = insn_decode.operand_2; - - - if (*((int *)buffer) == 0x0) { - /* "halt" looks just like an invalid "jump" to the insn decoder, - so is dealt with as a special case */ - fprintf_unfiltered (stream, "halt"); - return (4); - } - - for (i = 0; i < NOPCODES; i++) - if (pyr_opcodes[i].datum.code == insn_opcode) - break; - - if (i == NOPCODES) - /* FIXME: Handle unrecognised instructions better. */ - fprintf_unfiltered (stream, "???\t#%08x\t(op=%x mode =%x)", - insn, insn_decode.operator, insn_decode.mode); - else - { - /* Print the mnemonic for the instruction. Pyramid insn operands - are so regular that we can deal with almost all of them - separately. - Unconditional branches are an exception: they are encoded as - conditional branches (branch if false condition, I think) - with no condition specified. The average user will not be - aware of this. To maintain their illusion that an - unconditional branch insn exists, we will have to FIXME to - treat the insn mnemnonic of all branch instructions here as a - special case: check the operands of branch insn and print an - appropriate mnemonic. */ - - fprintf_unfiltered (stream, "%s\t", pyr_opcodes[i].name); - - /* Print the operands of the insn (as specified in - insn.operand_mode). - Branch operands of branches are a special case: they are a word - offset, not a byte offset. */ - - if (insn_decode.operator == 0x01 || insn_decode.operator == 0x02) { - register int bit_codes=(insn >> 16)&0xf; - register int i; - register int displacement = (insn & 0x0000ffff) << 2; - - static char cc_bit_names[] = "cvzn"; /* z,n,c,v: strange order? */ - - /* Is bfc and no bits specified an unconditional branch?*/ - for (i=0;i<4;i++) { - if ((bit_codes) & 0x1) - fputc_unfiltered (cc_bit_names[i], stream); - bit_codes >>= 1; - } - - fprintf_unfiltered (stream, ",%0x", - displacement + memaddr); - return (insn_size); - } - - switch (operand_mode) { - case 0: - fprintf_unfiltered (stream, "%s,%s", - REGISTER_NAME (op_1_regno), - REGISTER_NAME (op_2_regno)); - break; - - case 1: - fprintf_unfiltered (stream, " 0x%0x,%s", - op_1_regno, - REGISTER_NAME (op_2_regno)); - break; - - case 2: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - fprintf_unfiltered (stream, " $0x%0x,%s", - extra_1, - REGISTER_NAME (op_2_regno)); - break; - case 3: - fprintf_unfiltered (stream, " (%s),%s", - REGISTER_NAME (op_1_regno), - REGISTER_NAME (op_2_regno)); - break; - - case 4: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - fprintf_unfiltered (stream, " 0x%0x(%s),%s", - extra_1, - REGISTER_NAME (op_1_regno), - REGISTER_NAME (op_2_regno)); - break; - - /* S1 destination mode */ - case 5: - fprintf_unfiltered (stream, - ((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"), - REGISTER_NAME (op_1_regno), - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - - case 6: - fprintf_unfiltered (stream, - ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]" - : " $%#0x,(%s)"), - op_1_regno, - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - - case 7: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - fprintf_unfiltered (stream, - ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]" - : " $%#0x,(%s)"), - extra_1, - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - - case 8: - fprintf_unfiltered (stream, - ((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"), - REGISTER_NAME (op_1_regno), - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - - case 9: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - fprintf_unfiltered (stream, - ((index_reg_regno) - ? "%#0x(%s),(%s)[%s*%1d]" - : "%#0x(%s),(%s)"), - extra_1, - REGISTER_NAME (op_1_regno), - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - - /* S2 destination mode */ - case 10: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - fprintf_unfiltered (stream, - ((index_reg_regno) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"), - REGISTER_NAME (op_1_regno), - extra_1, - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - case 11: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - fprintf_unfiltered (stream, - ((index_reg_regno) ? - " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"), - op_1_regno, - extra_1, - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - case 12: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - read_memory (memaddr+8, buffer, MAXLEN); - insn_size += 4; - extra_2 = * ((int *) buffer); - fprintf_unfiltered (stream, - ((index_reg_regno) ? - " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"), - extra_1, - extra_2, - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - - case 13: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - fprintf_unfiltered (stream, - ((index_reg_regno) - ? " (%s),%#0x(%s)[%s*%1d]" - : " (%s),%#0x(%s)"), - REGISTER_NAME (op_1_regno), - extra_1, - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - case 14: - read_memory (memaddr+4, buffer, MAXLEN); - insn_size += 4; - extra_1 = * ((int *) buffer); - read_memory (memaddr+8, buffer, MAXLEN); - insn_size += 4; - extra_2 = * ((int *) buffer); - fprintf_unfiltered (stream, - ((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]" - : "%#0x(%s),%#0x(%s) "), - extra_1, - REGISTER_NAME (op_1_regno), - extra_2, - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - break; - - default: - fprintf_unfiltered (stream, - ((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"), - REGISTER_NAME (op_1_regno), - REGISTER_NAME (op_2_regno), - REGISTER_NAME (index_reg_regno), - index_multiplier); - fprintf_unfiltered (stream, - "\t\t# unknown mode in %08x", - insn); - break; - } /* switch */ - } - - { - return insn_size; - } - abort (); -} diff --git a/contrib/gdb/gdb/pyr-xdep.c b/contrib/gdb/gdb/pyr-xdep.c deleted file mode 100644 index dd6d9a92400..00000000000 --- a/contrib/gdb/gdb/pyr-xdep.c +++ /dev/null @@ -1,370 +0,0 @@ -/* Low level Pyramid interface to ptrace, for GDB when running under Unix. - Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" - -#include -#include -#include -#include -/* #include Can we live without this? */ - -#include "gdbcore.h" -#include /* After a.out.h */ -#include -#include "gdb_stat.h" - - -void -fetch_inferior_registers (regno) - int regno; -{ - register int datum; - register unsigned int regaddr; - int reg_buf[NUM_REGS+1]; - struct user u; - register int skipped_frames = 0; - - registers_fetched (); - - for (regno = 0; regno < 64; regno++) { - reg_buf[regno] = ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) regno, 0); - -#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING) - printf_unfiltered ("Fetching register %s, got %0x\n", - REGISTER_NAME (regno), - reg_buf[regno]); -#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */ - - if (reg_buf[regno] == -1 && errno == EIO) { - printf_unfiltered("fetch_interior_registers: fetching register %s\n", - REGISTER_NAME (regno)); - errno = 0; - } - supply_register (regno, reg_buf+regno); - } - /* that leaves regs 64, 65, and 66 */ - datum = ptrace (3, inferior_pid, - (PTRACE_ARG3_TYPE) (((char *)&u.u_pcb.pcb_csp) - - ((char *)&u)), 0); - - - - /* FIXME: Find the Current Frame Pointer (CFP). CFP is a global - register (ie, NOT windowed), that gets saved in a frame iff - the code for that frame has a prologue (ie, "adsf N"). If - there is a prologue, the adsf insn saves the old cfp in - pr13, cfp is set to sp, and N bytes of locals are allocated - (sp is decremented by n). - This makes finding CFP hard. I guess the right way to do it - is: - - If this is the innermost frame, believe ptrace() or - the core area. - - Otherwise: - Find the first insn of the current frame. - - find the saved pc; - - find the call insn that saved it; - - figure out where the call is to; - - if the first insn is an adsf, we got a frame - pointer. */ - - - /* Normal processors have separate stack pointers for user and - kernel mode. Getting the last user mode frame on such - machines is easy: the kernel context of the ptrace()'d - process is on the kernel stack, and the USP points to what - we want. But Pyramids only have a single cfp for both user and - kernel mode. And processes being ptrace()'d have some - kernel-context control frames on their stack. - To avoid tracing back into the kernel context of an inferior, - we skip 0 or more contiguous control frames where the pc is - in the kernel. */ - - while (1) { - register int inferior_saved_pc; - inferior_saved_pc = ptrace (1, inferior_pid, - (PTRACE_ARG3_TYPE) (datum+((32+15)*4)), 0); - if (inferior_saved_pc > 0) break; -#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING) - printf_unfiltered("skipping kernel frame %08x, pc=%08x\n", datum, - inferior_saved_pc); -#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */ - skipped_frames++; - datum -= CONTROL_STACK_FRAME_SIZE; - } - - reg_buf[CSP_REGNUM] = datum; - supply_register(CSP_REGNUM, reg_buf+CSP_REGNUM); -#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING - if (skipped_frames) { - fprintf_unfiltered (gdb_stderr, - "skipped %d frames from %x to %x; cfp was %x, now %x\n", - skipped_frames, reg_buf[CSP_REGNUM]); - } -#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */ -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (regno) - int regno; -{ - register unsigned int regaddr; - char buf[80]; - - if (regno >= 0) - { - if ((0 <= regno) && (regno < 64)) { - /*regaddr = register_addr (regno, offset);*/ - regaddr = regno; - errno = 0; - ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } - } - else - { - for (regno = 0; regno < NUM_REGS; regno++) - { - /*regaddr = register_addr (regno, offset);*/ - regaddr = regno; - errno = 0; - ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing all regs, number %d", regno); - perror_with_name (buf); - } - } -} - -/*** Extensions to core and dump files, for GDB. */ - -extern unsigned int last_frame_offset; - -#ifdef PYRAMID_CORE - -/* Can't make definitions here static, since corefile.c needs them - to do bounds checking on the core-file areas. O well. */ - -/* have two stacks: one for data, one for register windows. */ -extern CORE_ADDR reg_stack_start; -extern CORE_ADDR reg_stack_end; - -/* need this so we can find the global registers: they never get saved. */ -CORE_ADDR global_reg_offset; -static CORE_ADDR last_frame_address; -CORE_ADDR last_frame_offset; - - -/* Address in core file of start of register window stack area. - Don't know if is this any of meaningful, useful or necessary. */ -extern int reg_stack_offset; - -#endif /* PYRAMID_CORE */ - - -/* Work with core dump and executable files, for GDB. - This code would be in corefile.c if it weren't machine-dependent. */ - -void -core_file_command (filename, from_tty) - char *filename; - int from_tty; -{ - int val; - extern char registers[]; - - /* Discard all vestiges of any previous core file - and mark data and stack spaces as empty. */ - - if (corefile) - free (corefile); - corefile = 0; - - if (corechan >= 0) - close (corechan); - corechan = -1; - - data_start = 0; - data_end = 0; - stack_start = STACK_END_ADDR; - stack_end = STACK_END_ADDR; - -#ifdef PYRAMID_CORE - reg_stack_start = CONTROL_STACK_ADDR; - reg_stack_end = CONTROL_STACK_ADDR; /* this isn't strictly true...*/ -#endif /* PYRAMID_CORE */ - - /* Now, if a new core file was specified, open it and digest it. */ - - if (filename) - { - filename = tilde_expand (filename); - make_cleanup (free, filename); - - if (have_inferior_p ()) - error ("To look at a core file, you must kill the program with \"kill\"."); - corechan = open (filename, O_RDONLY, 0); - if (corechan < 0) - perror_with_name (filename); - /* 4.2-style (and perhaps also sysV-style) core dump file. */ - { - struct user u; - - unsigned int reg_offset; - - val = myread (corechan, &u, sizeof u); - if (val < 0) - perror_with_name ("Not a core file: reading upage"); - if (val != sizeof u) - error ("Not a core file: could only read %d bytes", val); - data_start = exec_data_start; - - data_end = data_start + NBPG * u.u_dsize; - data_offset = NBPG * UPAGES; - stack_offset = NBPG * (UPAGES + u.u_dsize); - - /* find registers in core file */ -#ifdef PYRAMID_PTRACE - stack_start = stack_end - NBPG * u.u_ussize; - reg_stack_offset = stack_offset + (NBPG *u.u_ussize); - reg_stack_end = reg_stack_start + NBPG * u.u_cssize; - - last_frame_address = ((int) u.u_pcb.pcb_csp); - last_frame_offset = reg_stack_offset + last_frame_address - - CONTROL_STACK_ADDR ; - global_reg_offset = (char *)&u - (char *)&u.u_pcb.pcb_gr0 ; - - /* skip any control-stack frames that were executed in the - kernel. */ - - while (1) { - char buf[4]; - val = lseek (corechan, last_frame_offset+(47*4), 0); - if (val < 0) - perror_with_name (filename); - val = myread (corechan, buf, sizeof buf); - if (val < 0) - perror_with_name (filename); - - if (*(int *)buf >= 0) - break; - printf_unfiltered ("skipping frame %s\n", local_hex_string (last_frame_address)); - last_frame_offset -= CONTROL_STACK_FRAME_SIZE; - last_frame_address -= CONTROL_STACK_FRAME_SIZE; - } - reg_offset = last_frame_offset; - -#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING) - printf_unfiltered ("Control stack pointer = %s\n", - local_hex_string (u.u_pcb.pcb_csp)); - printf_unfiltered ("offset to control stack %d outermost frame %d (%s)\n", - reg_stack_offset, reg_offset, local_hex_string (last_frame_address)); -#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */ - -#else /* not PYRAMID_CORE */ - stack_start = stack_end - NBPG * u.u_ssize; - reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR; -#endif /* not PYRAMID_CORE */ - -#ifdef __not_on_pyr_yet - /* Some machines put an absolute address in here and some put - the offset in the upage of the regs. */ - reg_offset = (int) u.u_ar0; - if (reg_offset > NBPG * UPAGES) - reg_offset -= KERNEL_U_ADDR; -#endif - - /* I don't know where to find this info. - So, for now, mark it as not available. */ - N_SET_MAGIC (core_aouthdr, 0); - - /* Read the register values out of the core file and store - them where `read_register' will find them. */ - - { - register int regno; - - for (regno = 0; regno < 64; regno++) - { - char buf[MAX_REGISTER_RAW_SIZE]; - - val = lseek (corechan, register_addr (regno, reg_offset), 0); - if (val < 0 - || (val = myread (corechan, buf, sizeof buf)) < 0) - { - char * buffer = (char *) alloca (strlen (REGISTER_NAME (regno)) - + 30); - strcpy (buffer, "Reading register "); - strcat (buffer, REGISTER_NAME (regno)); - - perror_with_name (buffer); - } - - if (val < 0) - perror_with_name (filename); -#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING - printf_unfiltered ("[reg %s(%d), offset in file %s=0x%0x, addr =0x%0x, =%0x]\n", - REGISTER_NAME (regno), regno, filename, - register_addr(regno, reg_offset), - regno * 4 + last_frame_address, - *((int *)buf)); -#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */ - supply_register (regno, buf); - } - } - } - if (filename[0] == '/') - corefile = savestring (filename, strlen (filename)); - else - { - corefile = concat (current_directory, "/", filename, NULL); - } - -#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING) - printf_unfiltered ("Providing CSP (%s) as nominal address of current frame.\n", - local_hex_string(last_frame_address)); -#endif PYRAMID_CONTROL_FRAME_DEBUGGING - /* FIXME: Which of the following is correct? */ -#if 0 - set_current_frame ( create_new_frame (read_register (FP_REGNUM), - read_pc ())); -#else - set_current_frame ( create_new_frame (last_frame_address, - read_pc ())); -#endif - - select_frame (get_current_frame (), 0); - validate_files (); - } - else if (from_tty) - printf_unfiltered ("No core file now.\n"); -} diff --git a/contrib/gdb/gdb/remote-adapt.c b/contrib/gdb/gdb/remote-adapt.c deleted file mode 100644 index 7e87360d178..00000000000 --- a/contrib/gdb/gdb/remote-adapt.c +++ /dev/null @@ -1,1524 +0,0 @@ -/* OBSOLETE /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18. */ -/* OBSOLETE Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, */ -/* OBSOLETE 2001 Free Software Foundation, Inc. */ -/* OBSOLETE Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu). */ -/* OBSOLETE Adapted from work done at Cygnus Support in remote-eb.c. */ -/* OBSOLETE */ -/* OBSOLETE This file is part of GDB. */ -/* OBSOLETE */ -/* OBSOLETE This program is free software; you can redistribute it and/or modify */ -/* OBSOLETE it under the terms of the GNU General Public License as published by */ -/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */ -/* OBSOLETE (at your option) any later version. */ -/* OBSOLETE */ -/* OBSOLETE This program is distributed in the hope that it will be useful, */ -/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* OBSOLETE GNU General Public License for more details. */ -/* OBSOLETE */ -/* OBSOLETE You should have received a copy of the GNU General Public License */ -/* OBSOLETE along with this program; if not, write to the Free Software */ -/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */ -/* OBSOLETE Boston, MA 02111-1307, USA. */ */ -/* OBSOLETE */ -/* OBSOLETE /* This is like remote.c but is for an esoteric situation-- */ -/* OBSOLETE having a 29k board attached to an Adapt inline monitor. */ -/* OBSOLETE The monitor is connected via serial line to a unix machine */ -/* OBSOLETE running gdb. */ -/* OBSOLETE */ -/* OBSOLETE 3/91 - developed on Sun3 OS 4.1, by David Wood */ -/* OBSOLETE o - I can't get binary coff to load. */ -/* OBSOLETE o - I can't get 19200 baud rate to work. */ -/* OBSOLETE 7/91 o - Freeze mode tracing can be done on a 29050. */ */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE #include "defs.h" */ -/* OBSOLETE #include "gdb_string.h" */ -/* OBSOLETE #include "inferior.h" */ -/* OBSOLETE #include "value.h" */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include "terminal.h" */ -/* OBSOLETE #include "target.h" */ -/* OBSOLETE #include "gdbcore.h" */ -/* OBSOLETE #include "regcache.h" */ -/* OBSOLETE */ -/* OBSOLETE /* This processor is getting rusty but I am trying to keep it */ -/* OBSOLETE up to date at least with data structure changes. */ -/* OBSOLETE Activate this block to compile just this file. */ -/* OBSOLETE */ */ -/* OBSOLETE #define COMPILE_CHECK 0 */ -/* OBSOLETE #if COMPILE_CHECK */ -/* OBSOLETE #define Q_REGNUM 0 */ -/* OBSOLETE #define VAB_REGNUM 0 */ -/* OBSOLETE #define CPS_REGNUM 0 */ -/* OBSOLETE #define IPA_REGNUM 0 */ -/* OBSOLETE #define IPB_REGNUM 0 */ -/* OBSOLETE #define GR1_REGNUM 0 */ -/* OBSOLETE #define LR0_REGNUM 0 */ -/* OBSOLETE #define IPC_REGNUM 0 */ -/* OBSOLETE #define CR_REGNUM 0 */ -/* OBSOLETE #define BP_REGNUM 0 */ -/* OBSOLETE #define FC_REGNUM 0 */ -/* OBSOLETE #define INTE_REGNUM 0 */ -/* OBSOLETE #define EXO_REGNUM 0 */ -/* OBSOLETE #define GR96_REGNUM 0 */ -/* OBSOLETE #define NPC_REGNUM */ -/* OBSOLETE #define FPE_REGNUM 0 */ -/* OBSOLETE #define PC2_REGNUM 0 */ -/* OBSOLETE #define FPS_REGNUM 0 */ -/* OBSOLETE #define ALU_REGNUM 0 */ -/* OBSOLETE #define LRU_REGNUM 0 */ -/* OBSOLETE #define TERMINAL int */ -/* OBSOLETE #define RAW 1 */ -/* OBSOLETE #define ANYP 1 */ -/* OBSOLETE extern int a29k_freeze_mode; */ -/* OBSOLETE extern int processor_type; */ -/* OBSOLETE extern char *processor_name; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* External data declarations */ */ -/* OBSOLETE extern int stop_soon_quietly; /* for wait_for_inferior */ */ -/* OBSOLETE */ -/* OBSOLETE /* Forward data declarations */ */ -/* OBSOLETE extern struct target_ops adapt_ops; /* Forward declaration */ */ -/* OBSOLETE */ -/* OBSOLETE /* Forward function declarations */ */ -/* OBSOLETE static void adapt_fetch_registers (); */ -/* OBSOLETE static void adapt_store_registers (); */ -/* OBSOLETE static void adapt_close (); */ -/* OBSOLETE static int adapt_clear_breakpoints (); */ -/* OBSOLETE */ -/* OBSOLETE #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400) */ -/* OBSOLETE #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE) */ -/* OBSOLETE */ -/* OBSOLETE /* Can't seem to get binary coff working */ */ -/* OBSOLETE #define ASCII_COFF /* Adapt will be downloaded with ascii coff */ */ -/* OBSOLETE */ -/* OBSOLETE /* FIXME: Replace with `set remotedebug'. */ */ -/* OBSOLETE #define LOG_FILE "adapt.log" */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE FILE *log_file = NULL; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE static int timeout = 5; */ -/* OBSOLETE static char *dev_name; */ -/* OBSOLETE */ -/* OBSOLETE /* Descriptor for I/O to remote machine. Initialize it to -1 so that */ -/* OBSOLETE adapt_open knows that we don't have a file open when the program */ -/* OBSOLETE starts. */ */ -/* OBSOLETE int adapt_desc = -1; */ -/* OBSOLETE */ -/* OBSOLETE /* stream which is fdopen'd from adapt_desc. Only valid when */ -/* OBSOLETE adapt_desc != -1. */ */ -/* OBSOLETE FILE *adapt_stream; */ -/* OBSOLETE */ -/* OBSOLETE #define ON 1 */ -/* OBSOLETE #define OFF 0 */ -/* OBSOLETE static void */ -/* OBSOLETE rawmode (int desc, int turnon) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE TERMINAL sg; */ -/* OBSOLETE */ -/* OBSOLETE if (desc < 0) */ -/* OBSOLETE return; */ -/* OBSOLETE */ -/* OBSOLETE ioctl (desc, TIOCGETP, &sg); */ -/* OBSOLETE */ -/* OBSOLETE if (turnon) */ -/* OBSOLETE { */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE sg.c_lflag &= ~(ICANON); */ -/* OBSOLETE #else */ -/* OBSOLETE sg.sg_flags |= RAW; */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE sg.c_lflag |= ICANON; */ -/* OBSOLETE #else */ -/* OBSOLETE sg.sg_flags &= ~(RAW); */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE ioctl (desc, TIOCSETP, &sg); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Suck up all the input from the adapt */ */ -/* OBSOLETE slurp_input (void) */ -/* OBSOLETE { */ -/* OBSOLETE char buf[8]; */ -/* OBSOLETE */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE /* termio does the timeout for us. */ */ -/* OBSOLETE while (read (adapt_desc, buf, 8) > 0); */ -/* OBSOLETE #else */ -/* OBSOLETE alarm (timeout); */ -/* OBSOLETE while (read (adapt_desc, buf, 8) > 0); */ -/* OBSOLETE alarm (0); */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Read a character from the remote system, doing all the fancy */ -/* OBSOLETE timeout stuff. */ */ -/* OBSOLETE static int */ -/* OBSOLETE readchar (void) */ -/* OBSOLETE { */ -/* OBSOLETE char buf; */ -/* OBSOLETE */ -/* OBSOLETE buf = '\0'; */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE /* termio does the timeout for us. */ */ -/* OBSOLETE read (adapt_desc, &buf, 1); */ -/* OBSOLETE #else */ -/* OBSOLETE alarm (timeout); */ -/* OBSOLETE if (read (adapt_desc, &buf, 1) < 0) */ -/* OBSOLETE { */ -/* OBSOLETE if (errno == EINTR) */ -/* OBSOLETE error ("Timeout reading from remote system."); */ -/* OBSOLETE else */ -/* OBSOLETE perror_with_name ("remote"); */ -/* OBSOLETE } */ -/* OBSOLETE alarm (0); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE if (buf == '\0') */ -/* OBSOLETE error ("Timeout reading from remote system."); */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE putc (buf & 0x7f, log_file); */ -/* OBSOLETE #endif */ -/* OBSOLETE return buf & 0x7f; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Keep discarding input from the remote system, until STRING is found. */ -/* OBSOLETE Let the user break out immediately. */ */ -/* OBSOLETE static void */ -/* OBSOLETE expect (char *string) */ -/* OBSOLETE { */ -/* OBSOLETE char *p = string; */ -/* OBSOLETE */ -/* OBSOLETE fflush (adapt_stream); */ -/* OBSOLETE immediate_quit++; */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE if (readchar () == *p) */ -/* OBSOLETE { */ -/* OBSOLETE p++; */ -/* OBSOLETE if (*p == '\0') */ -/* OBSOLETE { */ -/* OBSOLETE immediate_quit--; */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE p = string; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Keep discarding input until we see the adapt prompt. */ -/* OBSOLETE */ -/* OBSOLETE The convention for dealing with the prompt is that you */ -/* OBSOLETE o give your command */ -/* OBSOLETE o *then* wait for the prompt. */ -/* OBSOLETE */ -/* OBSOLETE Thus the last thing that a procedure does with the serial line */ -/* OBSOLETE will be an expect_prompt(). Exception: adapt_resume does not */ -/* OBSOLETE wait for the prompt, because the terminal is being handed over */ -/* OBSOLETE to the inferior. However, the next thing which happens after that */ -/* OBSOLETE is a adapt_wait which does wait for the prompt. */ -/* OBSOLETE Note that this includes abnormal exit, e.g. error(). This is */ -/* OBSOLETE necessary to prevent getting into states from which we can't */ -/* OBSOLETE recover. */ */ -/* OBSOLETE static void */ -/* OBSOLETE expect_prompt (void) */ -/* OBSOLETE { */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE /* This is a convenient place to do this. The idea is to do it often */ -/* OBSOLETE enough that we never lose much data if we terminate abnormally. */ */ -/* OBSOLETE fflush (log_file); */ -/* OBSOLETE #endif */ -/* OBSOLETE fflush (adapt_stream); */ -/* OBSOLETE expect ("\n# "); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Get a hex digit from the remote system & return its value. */ -/* OBSOLETE If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ */ -/* OBSOLETE static int */ -/* OBSOLETE get_hex_digit (int ignore_space) */ -/* OBSOLETE { */ -/* OBSOLETE int ch; */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE ch = readchar (); */ -/* OBSOLETE if (ch >= '0' && ch <= '9') */ -/* OBSOLETE return ch - '0'; */ -/* OBSOLETE else if (ch >= 'A' && ch <= 'F') */ -/* OBSOLETE return ch - 'A' + 10; */ -/* OBSOLETE else if (ch >= 'a' && ch <= 'f') */ -/* OBSOLETE return ch - 'a' + 10; */ -/* OBSOLETE else if (ch == ' ' && ignore_space) */ -/* OBSOLETE ; */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE error ("Invalid hex digit from remote system."); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Get a byte from adapt_desc and put it in *BYT. Accept any number */ -/* OBSOLETE leading spaces. */ */ -/* OBSOLETE static void */ -/* OBSOLETE get_hex_byte (char *byt) */ -/* OBSOLETE { */ -/* OBSOLETE int val; */ -/* OBSOLETE */ -/* OBSOLETE val = get_hex_digit (1) << 4; */ -/* OBSOLETE val |= get_hex_digit (0); */ -/* OBSOLETE *byt = val; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Read a 32-bit hex word from the adapt, preceded by a space */ */ -/* OBSOLETE static long */ -/* OBSOLETE get_hex_word (void) */ -/* OBSOLETE { */ -/* OBSOLETE long val; */ -/* OBSOLETE int j; */ -/* OBSOLETE */ -/* OBSOLETE val = 0; */ -/* OBSOLETE for (j = 0; j < 8; j++) */ -/* OBSOLETE val = (val << 4) + get_hex_digit (j == 0); */ -/* OBSOLETE return val; */ -/* OBSOLETE } */ -/* OBSOLETE /* Get N 32-bit hex words from remote, each preceded by a space */ -/* OBSOLETE and put them in registers starting at REGNO. */ */ -/* OBSOLETE static void */ -/* OBSOLETE get_hex_regs (int n, int regno) */ -/* OBSOLETE { */ -/* OBSOLETE long val; */ -/* OBSOLETE while (n--) */ -/* OBSOLETE { */ -/* OBSOLETE val = get_hex_word (); */ -/* OBSOLETE supply_register (regno++, (char *) &val); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE /* Called when SIGALRM signal sent due to alarm() timeout. */ */ -/* OBSOLETE #ifndef HAVE_TERMIO */ -/* OBSOLETE */ -/* OBSOLETE volatile int n_alarms; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE adapt_timer (void) */ -/* OBSOLETE { */ -/* OBSOLETE #if 0 */ -/* OBSOLETE if (kiodebug) */ -/* OBSOLETE printf ("adapt_timer called\n"); */ -/* OBSOLETE #endif */ -/* OBSOLETE n_alarms++; */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* malloc'd name of the program on the remote system. */ */ -/* OBSOLETE static char *prog_name = NULL; */ -/* OBSOLETE */ -/* OBSOLETE /* Number of SIGTRAPs we need to simulate. That is, the next */ -/* OBSOLETE NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return */ -/* OBSOLETE SIGTRAP without actually waiting for anything. */ */ -/* OBSOLETE */ -/* OBSOLETE static int need_artificial_trap = 0; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE adapt_kill (char *arg, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (adapt_stream, "K"); */ -/* OBSOLETE fprintf (adapt_stream, "\r"); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE /* */ -/* OBSOLETE * Download a file specified in 'args', to the adapt. */ -/* OBSOLETE * FIXME: Assumes the file to download is a binary coff file. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_load (char *args, int fromtty) */ -/* OBSOLETE { */ -/* OBSOLETE FILE *fp; */ -/* OBSOLETE int n; */ -/* OBSOLETE char buffer[1024]; */ -/* OBSOLETE */ -/* OBSOLETE if (!adapt_stream) */ -/* OBSOLETE { */ -/* OBSOLETE printf_filtered ("Adapt not open. Use 'target' command to open adapt\n"); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* OK, now read in the file. Y=read, C=COFF, T=dTe port */ -/* OBSOLETE 0=start address. */ */ -/* OBSOLETE */ -/* OBSOLETE #ifdef ASCII_COFF /* Ascii coff */ */ -/* OBSOLETE fprintf (adapt_stream, "YA T,0\r"); */ -/* OBSOLETE fflush (adapt_stream); /* Just in case */ */ -/* OBSOLETE /* FIXME: should check args for only 1 argument */ */ -/* OBSOLETE sprintf (buffer, "cat %s | btoa > /tmp/#adapt-btoa", args); */ -/* OBSOLETE system (buffer); */ -/* OBSOLETE fp = fopen ("/tmp/#adapt-btoa", "r"); */ -/* OBSOLETE rawmode (adapt_desc, OFF); */ -/* OBSOLETE while (n = fread (buffer, 1, 1024, fp)) */ -/* OBSOLETE { */ -/* OBSOLETE do */ -/* OBSOLETE { */ -/* OBSOLETE n -= write (adapt_desc, buffer, n); */ -/* OBSOLETE } */ -/* OBSOLETE while (n > 0); */ -/* OBSOLETE if (n < 0) */ -/* OBSOLETE { */ -/* OBSOLETE perror ("writing ascii coff"); */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE fclose (fp); */ -/* OBSOLETE rawmode (adapt_desc, ON); */ -/* OBSOLETE system ("rm /tmp/#adapt-btoa"); */ -/* OBSOLETE #else /* Binary coff - can't get it to work . */ */ -/* OBSOLETE fprintf (adapt_stream, "YC T,0\r"); */ -/* OBSOLETE fflush (adapt_stream); /* Just in case */ */ -/* OBSOLETE if (!(fp = fopen (args, "r"))) */ -/* OBSOLETE { */ -/* OBSOLETE printf_filtered ("Can't open %s\n", args); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE while (n = fread (buffer, 1, 512, fp)) */ -/* OBSOLETE { */ -/* OBSOLETE do */ -/* OBSOLETE { */ -/* OBSOLETE n -= write (adapt_desc, buffer, n); */ -/* OBSOLETE } */ -/* OBSOLETE while (n > 0); */ -/* OBSOLETE if (n < 0) */ -/* OBSOLETE { */ -/* OBSOLETE perror ("writing ascii coff"); */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE fclose (fp); */ -/* OBSOLETE #endif */ -/* OBSOLETE expect_prompt (); /* Skip garbage that comes out */ */ -/* OBSOLETE fprintf (adapt_stream, "\r"); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* This is called not only when we first attach, but also when the */ -/* OBSOLETE user types "run" after having attached. */ */ -/* OBSOLETE void */ -/* OBSOLETE adapt_create_inferior (char *execfile, char *args, char **env) */ -/* OBSOLETE { */ -/* OBSOLETE int entry_pt; */ -/* OBSOLETE */ -/* OBSOLETE if (args && *args) */ -/* OBSOLETE error ("Can't pass arguments to remote adapt process."); */ -/* OBSOLETE */ -/* OBSOLETE if (execfile == 0 || exec_bfd == 0) */ -/* OBSOLETE error ("No executable file specified"); */ -/* OBSOLETE */ -/* OBSOLETE entry_pt = (int) bfd_get_start_address (exec_bfd); */ -/* OBSOLETE */ -/* OBSOLETE if (adapt_stream) */ -/* OBSOLETE { */ -/* OBSOLETE adapt_kill (NULL, NULL); */ -/* OBSOLETE adapt_clear_breakpoints (); */ -/* OBSOLETE init_wait_for_inferior (); */ -/* OBSOLETE /* Clear the input because what the adapt sends back is different */ -/* OBSOLETE * depending on whether it was running or not. */ -/* OBSOLETE */ */ -/* OBSOLETE slurp_input (); /* After this there should be a prompt */ */ -/* OBSOLETE fprintf (adapt_stream, "\r"); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE printf_filtered ("Do you want to download '%s' (y/n)? [y] : ", prog_name); */ -/* OBSOLETE { */ -/* OBSOLETE char buffer[10]; */ -/* OBSOLETE gets (buffer); */ -/* OBSOLETE if (*buffer != 'n') */ -/* OBSOLETE { */ -/* OBSOLETE adapt_load (prog_name, 0); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #ifdef NOTDEF */ -/* OBSOLETE /* Set the PC and wait for a go/cont */ */ -/* OBSOLETE fprintf (adapt_stream, "G %x,N\r", entry_pt); */ -/* OBSOLETE printf_filtered ("Now use the 'continue' command to start.\n"); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE #else */ -/* OBSOLETE insert_breakpoints (); /* Needed to get correct instruction in cache */ */ -/* OBSOLETE proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE printf_filtered ("Adapt not open yet.\n"); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Translate baud rates from integers to damn B_codes. Unix should */ -/* OBSOLETE have outgrown this crap years ago, but even POSIX wouldn't buck it. */ */ -/* OBSOLETE */ -/* OBSOLETE #ifndef B19200 */ -/* OBSOLETE #define B19200 EXTA */ -/* OBSOLETE #endif */ -/* OBSOLETE #ifndef B38400 */ -/* OBSOLETE #define B38400 EXTB */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE static struct */ -/* OBSOLETE { */ -/* OBSOLETE int rate, damn_b; */ -/* OBSOLETE } */ -/* OBSOLETE baudtab[] = */ -/* OBSOLETE { */ -/* OBSOLETE { */ -/* OBSOLETE 0, B0 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 50, B50 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 75, B75 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 110, B110 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 134, B134 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 150, B150 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 200, B200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 300, B300 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 600, B600 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 1200, B1200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 1800, B1800 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 2400, B2400 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 4800, B4800 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 9600, B9600 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 19200, B19200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 38400, B38400 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE -1, -1 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE }; */ -/* OBSOLETE */ -/* OBSOLETE static int */ -/* OBSOLETE damn_b (int rate) */ -/* OBSOLETE { */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; baudtab[i].rate != -1; i++) */ -/* OBSOLETE if (rate == baudtab[i].rate) */ -/* OBSOLETE return baudtab[i].damn_b; */ -/* OBSOLETE return B38400; /* Random */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /* Open a connection to a remote debugger. */ -/* OBSOLETE NAME is the filename used for communication, then a space, */ -/* OBSOLETE then the baud rate. */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE static int baudrate = 9600; */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_open (char *name, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE TERMINAL sg; */ -/* OBSOLETE unsigned int prl; */ -/* OBSOLETE char *p; */ -/* OBSOLETE */ -/* OBSOLETE /* Find the first whitespace character, it separates dev_name from */ -/* OBSOLETE prog_name. */ */ -/* OBSOLETE if (name == 0) */ -/* OBSOLETE goto erroid; */ -/* OBSOLETE */ -/* OBSOLETE for (p = name; */ -/* OBSOLETE *p != '\0' && !isspace (*p); p++) */ -/* OBSOLETE ; */ -/* OBSOLETE if (*p == '\0') */ -/* OBSOLETE erroid: */ -/* OBSOLETE error ("\ */ -/* OBSOLETE Please include the name of the device for the serial port,\n\ */ -/* OBSOLETE the baud rate, and the name of the program to run on the remote system."); */ -/* OBSOLETE dev_name = (char *) xmalloc (p - name + 1); */ -/* OBSOLETE strncpy (dev_name, name, p - name); */ -/* OBSOLETE dev_name[p - name] = '\0'; */ -/* OBSOLETE */ -/* OBSOLETE /* Skip over the whitespace after dev_name */ */ -/* OBSOLETE for (; isspace (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE */ -/* OBSOLETE if (1 != sscanf (p, "%d ", &baudrate)) */ -/* OBSOLETE goto erroid; */ -/* OBSOLETE */ -/* OBSOLETE /* Skip the number and then the spaces */ */ -/* OBSOLETE for (; isdigit (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE for (; isspace (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE */ -/* OBSOLETE if (prog_name != NULL) */ -/* OBSOLETE xfree (prog_name); */ -/* OBSOLETE prog_name = savestring (p, strlen (p)); */ -/* OBSOLETE */ -/* OBSOLETE adapt_close (0); */ -/* OBSOLETE */ -/* OBSOLETE adapt_desc = open (dev_name, O_RDWR); */ -/* OBSOLETE if (adapt_desc < 0) */ -/* OBSOLETE perror_with_name (dev_name); */ -/* OBSOLETE ioctl (adapt_desc, TIOCGETP, &sg); */ -/* OBSOLETE #if ! defined(COMPILE_CHECK) */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE sg.c_cc[VMIN] = 0; /* read with timeout. */ */ -/* OBSOLETE sg.c_cc[VTIME] = timeout * 10; */ -/* OBSOLETE sg.c_lflag &= ~(ICANON | ECHO); */ -/* OBSOLETE sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate); */ -/* OBSOLETE #else */ -/* OBSOLETE sg.sg_ispeed = damn_b (baudrate); */ -/* OBSOLETE sg.sg_ospeed = damn_b (baudrate); */ -/* OBSOLETE sg.sg_flags |= RAW | ANYP; */ -/* OBSOLETE sg.sg_flags &= ~ECHO; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE ioctl (adapt_desc, TIOCSETP, &sg); */ -/* OBSOLETE adapt_stream = fdopen (adapt_desc, "r+"); */ -/* OBSOLETE #endif /* compile_check */ */ -/* OBSOLETE push_target (&adapt_ops); */ -/* OBSOLETE */ -/* OBSOLETE #ifndef HAVE_TERMIO */ -/* OBSOLETE #ifndef NO_SIGINTERRUPT */ -/* OBSOLETE /* Cause SIGALRM's to make reads fail with EINTR instead of resuming */ -/* OBSOLETE the read. */ */ -/* OBSOLETE if (siginterrupt (SIGALRM, 1) != 0) */ -/* OBSOLETE perror ("adapt_open: error in siginterrupt"); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* Set up read timeout timer. */ */ -/* OBSOLETE if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1) */ -/* OBSOLETE perror ("adapt_open: error in signal"); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE log_file = fopen (LOG_FILE, "w"); */ -/* OBSOLETE if (log_file == NULL) */ -/* OBSOLETE perror_with_name (LOG_FILE); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* Put this port into NORMAL mode, send the 'normal' character */ */ -/* OBSOLETE write (adapt_desc, "", 1); /* Control A */ */ -/* OBSOLETE write (adapt_desc, "\r", 1); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE /* Hello? Are you there? */ */ -/* OBSOLETE write (adapt_desc, "\r", 1); */ -/* OBSOLETE */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE /* Clear any break points */ */ -/* OBSOLETE adapt_clear_breakpoints (); */ -/* OBSOLETE */ -/* OBSOLETE /* Print out some stuff, letting the user now what's going on */ */ -/* OBSOLETE printf_filtered ("Connected to an Adapt via %s.\n", dev_name); */ -/* OBSOLETE /* FIXME: can this restriction be removed? */ */ -/* OBSOLETE printf_filtered ("Remote debugging using virtual addresses works only\n"); */ -/* OBSOLETE printf_filtered ("\twhen virtual addresses map 1:1 to physical addresses.\n"); */ -/* OBSOLETE if (processor_type != a29k_freeze_mode) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf_filtered (gdb_stderr, */ -/* OBSOLETE "Freeze-mode debugging not available, and can only be done on an A29050.\n"); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Close out all files and local state before this target loses control. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_close (int quitting) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE /* Clear any break points */ */ -/* OBSOLETE adapt_clear_breakpoints (); */ -/* OBSOLETE */ -/* OBSOLETE /* Put this port back into REMOTE mode */ */ -/* OBSOLETE if (adapt_stream) */ -/* OBSOLETE { */ -/* OBSOLETE fflush (adapt_stream); */ -/* OBSOLETE sleep (1); /* Let any output make it all the way back */ */ -/* OBSOLETE write (adapt_desc, "R\r", 2); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Due to a bug in Unix, fclose closes not only the stdio stream, */ -/* OBSOLETE but also the file descriptor. So we don't actually close */ -/* OBSOLETE adapt_desc. */ */ -/* OBSOLETE if (adapt_stream) */ -/* OBSOLETE fclose (adapt_stream); /* This also closes adapt_desc */ */ -/* OBSOLETE if (adapt_desc >= 0) */ -/* OBSOLETE /* close (adapt_desc); */ */ -/* OBSOLETE */ -/* OBSOLETE /* Do not try to close adapt_desc again, later in the program. */ */ -/* OBSOLETE adapt_stream = NULL; */ -/* OBSOLETE adapt_desc = -1; */ -/* OBSOLETE */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE if (log_file) */ -/* OBSOLETE { */ -/* OBSOLETE if (ferror (log_file)) */ -/* OBSOLETE printf_filtered ("Error writing log file.\n"); */ -/* OBSOLETE if (fclose (log_file) != 0) */ -/* OBSOLETE printf_filtered ("Error closing log file.\n"); */ -/* OBSOLETE log_file = NULL; */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Attach to the target that is already loaded and possibly running */ */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_attach (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf_filtered ("Attaching to remote program %s.\n", prog_name); */ -/* OBSOLETE */ -/* OBSOLETE /* Send the adapt a kill. It is ok if it is not already running */ */ -/* OBSOLETE fprintf (adapt_stream, "K\r"); */ -/* OBSOLETE fflush (adapt_stream); */ -/* OBSOLETE expect_prompt (); /* Slurp the echo */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /* Terminate the open connection to the remote debugger. */ -/* OBSOLETE Use this when you want to detach and do something else */ -/* OBSOLETE with your gdb. */ */ -/* OBSOLETE void */ -/* OBSOLETE adapt_detach (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE if (adapt_stream) */ -/* OBSOLETE { /* Send it on its way (tell it to continue) */ */ -/* OBSOLETE adapt_clear_breakpoints (); */ -/* OBSOLETE fprintf (adapt_stream, "G\r"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE pop_target (); /* calls adapt_close to do the real work */ */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf_filtered ("Ending remote %s debugging\n", target_shortname); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Tell the remote machine to resume. */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE adapt_resume (ptid_t ptid, int step, enum target_signal sig) */ -/* OBSOLETE { */ -/* OBSOLETE if (step) */ -/* OBSOLETE { */ -/* OBSOLETE write (adapt_desc, "t 1,s\r", 6); */ -/* OBSOLETE /* Wait for the echo. */ */ -/* OBSOLETE expect ("t 1,s\r\n"); */ -/* OBSOLETE /* Then comes a line containing the instruction we stepped to. */ */ -/* OBSOLETE expect ("@"); */ -/* OBSOLETE /* Then we get the prompt. */ */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE /* Force the next adapt_wait to return a trap. Not doing anything */ -/* OBSOLETE about I/O from the target means that the user has to type */ -/* OBSOLETE "continue" to see any. FIXME, this should be fixed. */ */ -/* OBSOLETE need_artificial_trap = 1; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE write (adapt_desc, "G\r", 2); */ -/* OBSOLETE /* Swallow the echo. */ */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Wait until the remote machine stops, then return, */ -/* OBSOLETE storing status in STATUS just as `wait' would. */ */ -/* OBSOLETE */ -/* OBSOLETE ptid_t */ -/* OBSOLETE adapt_wait (ptid_t ptid, struct target_waitstatus *status) */ -/* OBSOLETE { */ -/* OBSOLETE /* Strings to look for. '?' means match any single character. */ -/* OBSOLETE Note that with the algorithm we use, the initial character */ -/* OBSOLETE of the string cannot recur in the string, or we will not */ -/* OBSOLETE find some cases of the string in the input. */ */ -/* OBSOLETE */ -/* OBSOLETE static char bpt[] = "@"; */ -/* OBSOLETE /* It would be tempting to look for "\n[__exit + 0x8]\n" */ -/* OBSOLETE but that requires loading symbols with "yc i" and even if */ -/* OBSOLETE we did do that we don't know that the file has symbols. */ */ -/* OBSOLETE static char exitmsg[] = "@????????I JMPTI GR121,LR0"; */ -/* OBSOLETE char *bp = bpt; */ -/* OBSOLETE char *ep = exitmsg; */ -/* OBSOLETE */ -/* OBSOLETE /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */ */ -/* OBSOLETE char swallowed[50]; */ -/* OBSOLETE /* Current position in swallowed. */ */ -/* OBSOLETE char *swallowed_p = swallowed; */ -/* OBSOLETE */ -/* OBSOLETE int ch; */ -/* OBSOLETE int ch_handled; */ -/* OBSOLETE int old_timeout = timeout; */ -/* OBSOLETE int old_immediate_quit = immediate_quit; */ -/* OBSOLETE */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE */ -/* OBSOLETE if (need_artificial_trap != 0) */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE need_artificial_trap--; */ -/* OBSOLETE return inferior_ptid; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE timeout = 0; /* Don't time out -- user program is running. */ */ -/* OBSOLETE immediate_quit = 1; /* Helps ability to QUIT */ */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE QUIT; /* Let user quit and leave process running */ */ -/* OBSOLETE ch_handled = 0; */ -/* OBSOLETE ch = readchar (); */ -/* OBSOLETE if (ch == *bp) */ -/* OBSOLETE { */ -/* OBSOLETE bp++; */ -/* OBSOLETE if (*bp == '\0') */ -/* OBSOLETE break; */ -/* OBSOLETE ch_handled = 1; */ -/* OBSOLETE */ -/* OBSOLETE *swallowed_p++ = ch; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE bp = bpt; */ -/* OBSOLETE if (ch == *ep || *ep == '?') */ -/* OBSOLETE { */ -/* OBSOLETE ep++; */ -/* OBSOLETE if (*ep == '\0') */ -/* OBSOLETE break; */ -/* OBSOLETE */ -/* OBSOLETE if (!ch_handled) */ -/* OBSOLETE *swallowed_p++ = ch; */ -/* OBSOLETE ch_handled = 1; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE ep = exitmsg; */ -/* OBSOLETE if (!ch_handled) */ -/* OBSOLETE { */ -/* OBSOLETE char *p; */ -/* OBSOLETE /* Print out any characters which have been swallowed. */ */ -/* OBSOLETE for (p = swallowed; p < swallowed_p; ++p) */ -/* OBSOLETE putc (*p, stdout); */ -/* OBSOLETE swallowed_p = swallowed; */ -/* OBSOLETE putc (ch, stdout); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE if (*bp == '\0') */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE } */ -/* OBSOLETE timeout = old_timeout; */ -/* OBSOLETE immediate_quit = old_immediate_quit; */ -/* OBSOLETE return inferior_ptid; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Return the name of register number REGNO */ -/* OBSOLETE in the form input and output by adapt. */ -/* OBSOLETE */ -/* OBSOLETE Returns a pointer to a static buffer containing the answer. */ */ -/* OBSOLETE static char * */ -/* OBSOLETE get_reg_name (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE static char buf[80]; */ -/* OBSOLETE if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) */ -/* OBSOLETE sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96); */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32) */ -/* OBSOLETE sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64); */ -/* OBSOLETE #endif */ -/* OBSOLETE else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) */ -/* OBSOLETE sprintf (buf, "LR%03d", regno - LR0_REGNUM); */ -/* OBSOLETE else if (regno == Q_REGNUM) */ -/* OBSOLETE strcpy (buf, "SR131"); */ -/* OBSOLETE else if (regno >= BP_REGNUM && regno <= CR_REGNUM) */ -/* OBSOLETE sprintf (buf, "SR%03d", regno - BP_REGNUM + 133); */ -/* OBSOLETE else if (regno == ALU_REGNUM) */ -/* OBSOLETE strcpy (buf, "SR132"); */ -/* OBSOLETE else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM) */ -/* OBSOLETE sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128); */ -/* OBSOLETE else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE /* When a 29050 is in freeze-mode, read shadow pcs instead */ */ -/* OBSOLETE if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC) */ -/* OBSOLETE sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20); */ -/* OBSOLETE else */ -/* OBSOLETE sprintf (buf, "SR%03d", regno - VAB_REGNUM); */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno == GR1_REGNUM) */ -/* OBSOLETE strcpy (buf, "GR001"); */ -/* OBSOLETE return buf; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Read the remote registers. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_fetch_registers (void) */ -/* OBSOLETE { */ -/* OBSOLETE int reg_index; */ -/* OBSOLETE int regnum_index; */ -/* OBSOLETE char tempbuf[10]; */ -/* OBSOLETE int sreg_buf[16]; */ -/* OBSOLETE int i, j; */ -/* OBSOLETE */ -/* OBSOLETE /* */ -/* OBSOLETE * Global registers */ -/* OBSOLETE */ */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE write (adapt_desc, "dw gr64,gr95\r", 13); */ -/* OBSOLETE for (reg_index = 64, regnum_index = GR64_REGNUM; */ -/* OBSOLETE reg_index < 96; */ -/* OBSOLETE reg_index += 4, regnum_index += 4) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (tempbuf, "GR%03d ", reg_index); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE get_hex_regs (4, regnum_index); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE write (adapt_desc, "dw gr96,gr127\r", 14); */ -/* OBSOLETE for (reg_index = 96, regnum_index = GR96_REGNUM; */ -/* OBSOLETE reg_index < 128; */ -/* OBSOLETE reg_index += 4, regnum_index += 4) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (tempbuf, "GR%03d ", reg_index); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE get_hex_regs (4, regnum_index); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* */ -/* OBSOLETE * Local registers */ -/* OBSOLETE */ */ -/* OBSOLETE for (i = 0; i < 128; i += 32) */ -/* OBSOLETE { */ -/* OBSOLETE /* The PC has a tendency to hang if we get these */ -/* OBSOLETE all in one fell swoop ("dw lr0,lr127"). */ */ -/* OBSOLETE sprintf (tempbuf, "dw lr%d\r", i); */ -/* OBSOLETE write (adapt_desc, tempbuf, strlen (tempbuf)); */ -/* OBSOLETE for (reg_index = i, regnum_index = LR0_REGNUM + i; */ -/* OBSOLETE reg_index < i + 32; */ -/* OBSOLETE reg_index += 4, regnum_index += 4) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (tempbuf, "LR%03d ", reg_index); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE get_hex_regs (4, regnum_index); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* */ -/* OBSOLETE * Special registers */ -/* OBSOLETE */ */ -/* OBSOLETE sprintf (tempbuf, "dw sr0\r"); */ -/* OBSOLETE write (adapt_desc, tempbuf, strlen (tempbuf)); */ -/* OBSOLETE for (i = 0; i < 4; i++) */ -/* OBSOLETE { /* SR0 - SR14 */ */ -/* OBSOLETE sprintf (tempbuf, "SR%3d", i * 4); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE for (j = 0; j < (i == 3 ? 3 : 4); j++) */ -/* OBSOLETE sreg_buf[i * 4 + j] = get_hex_word (); */ -/* OBSOLETE } */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE /* */ -/* OBSOLETE * Read the pcs individually if we are in freeze mode. */ -/* OBSOLETE * See get_reg_name(), it translates the register names for the pcs to */ -/* OBSOLETE * the names of the shadow pcs. */ -/* OBSOLETE */ */ -/* OBSOLETE if (USE_SHADOW_PC) */ -/* OBSOLETE { */ -/* OBSOLETE sreg_buf[10] = read_register (NPC_REGNUM); /* pc0 */ */ -/* OBSOLETE sreg_buf[11] = read_register (PC_REGNUM); /* pc1 */ */ -/* OBSOLETE sreg_buf[12] = read_register (PC2_REGNUM); /* pc2 */ */ -/* OBSOLETE } */ -/* OBSOLETE for (i = 0; i < 14; i++) /* Supply vab -> lru */ */ -/* OBSOLETE supply_register (VAB_REGNUM + i, (char *) &sreg_buf[i]); */ -/* OBSOLETE sprintf (tempbuf, "dw sr128\r"); */ -/* OBSOLETE write (adapt_desc, tempbuf, strlen (tempbuf)); */ -/* OBSOLETE for (i = 0; i < 2; i++) */ -/* OBSOLETE { /* SR128 - SR135 */ */ -/* OBSOLETE sprintf (tempbuf, "SR%3d", 128 + i * 4); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE for (j = 0; j < 4; j++) */ -/* OBSOLETE sreg_buf[i * 4 + j] = get_hex_word (); */ -/* OBSOLETE } */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE supply_register (IPC_REGNUM, (char *) &sreg_buf[0]); */ -/* OBSOLETE supply_register (IPA_REGNUM, (char *) &sreg_buf[1]); */ -/* OBSOLETE supply_register (IPB_REGNUM, (char *) &sreg_buf[2]); */ -/* OBSOLETE supply_register (Q_REGNUM, (char *) &sreg_buf[3]); */ -/* OBSOLETE /* Skip ALU */ */ -/* OBSOLETE supply_register (BP_REGNUM, (char *) &sreg_buf[5]); */ -/* OBSOLETE supply_register (FC_REGNUM, (char *) &sreg_buf[6]); */ -/* OBSOLETE supply_register (CR_REGNUM, (char *) &sreg_buf[7]); */ -/* OBSOLETE */ -/* OBSOLETE /* There doesn't seem to be any way to get these. */ */ -/* OBSOLETE { */ -/* OBSOLETE int val = -1; */ -/* OBSOLETE supply_register (FPE_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (INTE_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (FPS_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (EXO_REGNUM, (char *) &val); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE write (adapt_desc, "dw gr1,gr1\r", 11); */ -/* OBSOLETE expect ("GR001 "); */ -/* OBSOLETE get_hex_regs (1, GR1_REGNUM); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Fetch register REGNO, or all registers if REGNO is -1. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_fetch_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE if (regno == -1) */ -/* OBSOLETE adapt_fetch_registers (); */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE char *name = get_reg_name (regno); */ -/* OBSOLETE fprintf (adapt_stream, "dw %s,%s\r", name, name); */ -/* OBSOLETE expect (name); */ -/* OBSOLETE expect (" "); */ -/* OBSOLETE get_hex_regs (1, regno); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Store the remote registers from the contents of the block REGS. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_store_registers (void) */ -/* OBSOLETE { */ -/* OBSOLETE int i, j; */ -/* OBSOLETE */ -/* OBSOLETE fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE for (j = 0; j < 32; j += 16) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (adapt_stream, "s gr%d,", j + 64); */ -/* OBSOLETE for (i = 0; i < 15; ++i) */ -/* OBSOLETE fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i)); */ -/* OBSOLETE fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE for (j = 0; j < 32; j += 16) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (adapt_stream, "s gr%d,", j + 96); */ -/* OBSOLETE for (i = 0; i < 15; ++i) */ -/* OBSOLETE fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i)); */ -/* OBSOLETE fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE for (j = 0; j < 128; j += 16) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (adapt_stream, "s lr%d,", j); */ -/* OBSOLETE for (i = 0; i < 15; ++i) */ -/* OBSOLETE fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i)); */ -/* OBSOLETE fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM), */ -/* OBSOLETE read_register (IPA_REGNUM), read_register (IPB_REGNUM)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM), */ -/* OBSOLETE read_register (FC_REGNUM), read_register (CR_REGNUM)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE fprintf (adapt_stream, "s sr0,"); */ -/* OBSOLETE for (i = 0; i < 7; ++i) */ -/* OBSOLETE fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE fprintf (adapt_stream, "s sr7,"); */ -/* OBSOLETE for (i = 7; i < 14; ++i) */ -/* OBSOLETE fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Store register REGNO, or all if REGNO == -1. */ -/* OBSOLETE Return errno value. */ */ -/* OBSOLETE void */ -/* OBSOLETE adapt_store_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */ */ -/* OBSOLETE if (regno == -1) */ -/* OBSOLETE adapt_store_registers (); */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE char *name = get_reg_name (regno); */ -/* OBSOLETE fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno)); */ -/* OBSOLETE /* Setting GR1 changes the numbers of all the locals, so */ -/* OBSOLETE invalidate the register cache. Do this *after* calling */ -/* OBSOLETE read_register, because we want read_register to return the */ -/* OBSOLETE value that write_register has just stuffed into the registers */ -/* OBSOLETE array, not the value of the register fetched from the */ -/* OBSOLETE inferior. */ */ -/* OBSOLETE if (regno == GR1_REGNUM) */ -/* OBSOLETE registers_changed (); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Get ready to modify the registers array. On machines which store */ -/* OBSOLETE individual registers, this doesn't need to do anything. On machines */ -/* OBSOLETE which store all the registers in one fell swoop, this makes sure */ -/* OBSOLETE that registers contains all the registers from the program being */ -/* OBSOLETE debugged. */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE adapt_prepare_to_store (void) */ -/* OBSOLETE { */ -/* OBSOLETE /* Do nothing, since we can store individual regs */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE static CORE_ADDR */ -/* OBSOLETE translate_addr (CORE_ADDR addr) */ -/* OBSOLETE { */ -/* OBSOLETE #if defined(KERNEL_DEBUGGING) */ -/* OBSOLETE /* Check for a virtual address in the kernel */ */ -/* OBSOLETE /* Assume physical address of ublock is in paddr_u register */ */ -/* OBSOLETE if (addr >= UVADDR) */ -/* OBSOLETE { */ -/* OBSOLETE /* PADDR_U register holds the physical address of the ublock */ */ -/* OBSOLETE CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM); */ -/* OBSOLETE return (i + addr - (CORE_ADDR) UVADDR); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE return (addr); */ -/* OBSOLETE } */ -/* OBSOLETE #else */ -/* OBSOLETE return (addr); */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /* FIXME! Merge these two. */ */ -/* OBSOLETE int */ -/* OBSOLETE adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, */ -/* OBSOLETE struct mem_attrib *attrib ATTRIBUTE_UNUSED, */ -/* OBSOLETE struct target_ops *target ATTRIBUTE_UNUSED) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE memaddr = translate_addr (memaddr); */ -/* OBSOLETE */ -/* OBSOLETE if (write) */ -/* OBSOLETE return adapt_write_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE else */ -/* OBSOLETE return adapt_read_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE adapt_files_info (void) */ -/* OBSOLETE { */ -/* OBSOLETE printf_filtered ("\tAttached to %s at %d baud and running program %s\n", */ -/* OBSOLETE dev_name, baudrate, prog_name); */ -/* OBSOLETE printf_filtered ("\ton an %s processor.\n", processor_name[processor_type]); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Copy LEN bytes of data from debugger memory at MYADDR */ -/* OBSOLETE to inferior's memory at MEMADDR. Returns errno value. */ -/* OBSOLETE * sb/sh instructions don't work on unaligned addresses, when TU=1. */ -/* OBSOLETE */ */ -/* OBSOLETE int */ -/* OBSOLETE adapt_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int i; */ -/* OBSOLETE unsigned int cps; */ -/* OBSOLETE */ -/* OBSOLETE /* Turn TU bit off so we can do 'sb' commands */ */ -/* OBSOLETE cps = read_register (CPS_REGNUM); */ -/* OBSOLETE if (cps & 0x00000800) */ -/* OBSOLETE write_register (CPS_REGNUM, cps & ~(0x00000800)); */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; i < len; i++) */ -/* OBSOLETE { */ -/* OBSOLETE if ((i % 16) == 0) */ -/* OBSOLETE fprintf (adapt_stream, "sb %x,", memaddr + i); */ -/* OBSOLETE if ((i % 16) == 15 || i == len - 1) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (adapt_stream, "%x\r", ((unsigned char *) myaddr)[i]); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE fprintf (adapt_stream, "%x,", ((unsigned char *) myaddr)[i]); */ -/* OBSOLETE } */ -/* OBSOLETE /* Restore the old value of cps if the TU bit was on */ */ -/* OBSOLETE if (cps & 0x00000800) */ -/* OBSOLETE write_register (CPS_REGNUM, cps); */ -/* OBSOLETE return len; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Read LEN bytes from inferior memory at MEMADDR. Put the result */ -/* OBSOLETE at debugger address MYADDR. Returns errno value. */ */ -/* OBSOLETE int */ -/* OBSOLETE adapt_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE /* Number of bytes read so far. */ */ -/* OBSOLETE int count; */ -/* OBSOLETE */ -/* OBSOLETE /* Starting address of this pass. */ */ -/* OBSOLETE unsigned long startaddr; */ -/* OBSOLETE */ -/* OBSOLETE /* Number of bytes to read in this pass. */ */ -/* OBSOLETE int len_this_pass; */ -/* OBSOLETE */ -/* OBSOLETE /* Note that this code works correctly if startaddr is just less */ -/* OBSOLETE than UINT_MAX (well, really CORE_ADDR_MAX if there was such a */ -/* OBSOLETE thing). That is, something like */ -/* OBSOLETE adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4) */ -/* OBSOLETE works--it never adds len to memaddr and gets 0. */ */ -/* OBSOLETE /* However, something like */ -/* OBSOLETE adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4) */ -/* OBSOLETE doesn't need to work. Detect it and give up if there's an attempt */ -/* OBSOLETE to do that. */ */ -/* OBSOLETE */ -/* OBSOLETE if (((memaddr - 1) + len) < memaddr) */ -/* OBSOLETE return EIO; */ -/* OBSOLETE */ -/* OBSOLETE startaddr = memaddr; */ -/* OBSOLETE count = 0; */ -/* OBSOLETE while (count < len) */ -/* OBSOLETE { */ -/* OBSOLETE len_this_pass = 16; */ -/* OBSOLETE if ((startaddr % 16) != 0) */ -/* OBSOLETE len_this_pass -= startaddr % 16; */ -/* OBSOLETE if (len_this_pass > (len - count)) */ -/* OBSOLETE len_this_pass = (len - count); */ -/* OBSOLETE */ -/* OBSOLETE fprintf (adapt_stream, "db %x,%x\r", startaddr, */ -/* OBSOLETE (startaddr - 1) + len_this_pass); */ -/* OBSOLETE */ -/* OBSOLETE #ifdef NOTDEF /* Why do this */ */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE /* Look for 8 hex digits. */ */ -/* OBSOLETE i = 0; */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE if (isxdigit (readchar ())) */ -/* OBSOLETE ++i; */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE error ("Hex digit expected from remote system."); */ -/* OBSOLETE } */ -/* OBSOLETE if (i >= 8) */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE #endif /* NOTDEF */ */ -/* OBSOLETE */ -/* OBSOLETE expect (" "); */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; i < len_this_pass; i++) */ -/* OBSOLETE get_hex_byte (&myaddr[count++]); */ -/* OBSOLETE */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE startaddr += len_this_pass; */ -/* OBSOLETE } */ -/* OBSOLETE return count; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #define MAX_BREAKS 8 */ -/* OBSOLETE static int num_brkpts = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* Insert a breakpoint at ADDR. SAVE is normally the address of the */ -/* OBSOLETE pattern buffer where the instruction that the breakpoint overwrites */ -/* OBSOLETE is saved. It is unused here since the Adapt Monitor is responsible */ -/* OBSOLETE for saving/restoring the original instruction. */ */ -/* OBSOLETE */ -/* OBSOLETE static int */ -/* OBSOLETE adapt_insert_breakpoint (CORE_ADDR addr, char *save) */ -/* OBSOLETE { */ -/* OBSOLETE if (num_brkpts < MAX_BREAKS) */ -/* OBSOLETE { */ -/* OBSOLETE num_brkpts++; */ -/* OBSOLETE fprintf (adapt_stream, "B %x", addr); */ -/* OBSOLETE fprintf (adapt_stream, "\r"); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE return (0); /* Success */ */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE fprintf_filtered (gdb_stderr, */ -/* OBSOLETE "Too many break points, break point not installed\n"); */ -/* OBSOLETE return (1); /* Failure */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Remove a breakpoint at ADDR. SAVE is normally the previously */ -/* OBSOLETE saved pattern, but is unused here as the Adapt Monitor is */ -/* OBSOLETE responsible for saving/restoring instructions. */ */ -/* OBSOLETE */ -/* OBSOLETE static int */ -/* OBSOLETE adapt_remove_breakpoint (CORE_ADDR addr, char *save) */ -/* OBSOLETE { */ -/* OBSOLETE if (num_brkpts > 0) */ -/* OBSOLETE { */ -/* OBSOLETE num_brkpts--; */ -/* OBSOLETE fprintf (adapt_stream, "BR %x", addr); */ -/* OBSOLETE fprintf (adapt_stream, "\r"); */ -/* OBSOLETE fflush (adapt_stream); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE return (0); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Clear the adapts notion of what the break points are */ */ -/* OBSOLETE static int */ -/* OBSOLETE adapt_clear_breakpoints (void) */ -/* OBSOLETE { */ -/* OBSOLETE if (adapt_stream) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (adapt_stream, "BR"); /* Clear all break points */ */ -/* OBSOLETE fprintf (adapt_stream, "\r"); */ -/* OBSOLETE fflush (adapt_stream); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE num_brkpts = 0; */ -/* OBSOLETE } */ -/* OBSOLETE static void */ -/* OBSOLETE adapt_mourn (void) */ -/* OBSOLETE { */ -/* OBSOLETE adapt_clear_breakpoints (); */ -/* OBSOLETE pop_target (); /* Pop back to no-child state */ */ -/* OBSOLETE generic_mourn_inferior (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Display everthing we read in from the adapt until we match/see the */ -/* OBSOLETE * specified string */ -/* OBSOLETE */ */ -/* OBSOLETE static int */ -/* OBSOLETE display_until (char *str) */ -/* OBSOLETE { */ -/* OBSOLETE int i = 0, j, c; */ -/* OBSOLETE */ -/* OBSOLETE while (c = readchar ()) */ -/* OBSOLETE { */ -/* OBSOLETE if (c == str[i]) */ -/* OBSOLETE { */ -/* OBSOLETE i++; */ -/* OBSOLETE if (i == strlen (str)) */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE if (i) */ -/* OBSOLETE { */ -/* OBSOLETE for (j = 0; j < i; j++) /* Put everthing we matched */ */ -/* OBSOLETE putchar (str[j]); */ -/* OBSOLETE i = 0; */ -/* OBSOLETE } */ -/* OBSOLETE putchar (c); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /* Put a command string, in args, out to the adapt. The adapt is assumed to */ -/* OBSOLETE be in raw mode, all writing/reading done through adapt_desc. */ -/* OBSOLETE Ouput from the adapt is placed on the users terminal until the */ -/* OBSOLETE prompt from the adapt is seen. */ -/* OBSOLETE FIXME: Can't handle commands that take input. */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE adapt_com (char *args, int fromtty) */ -/* OBSOLETE { */ -/* OBSOLETE if (!adapt_stream) */ -/* OBSOLETE { */ -/* OBSOLETE printf_filtered ("Adapt not open. Use the 'target' command to open.\n"); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Clear all input so only command relative output is displayed */ */ -/* OBSOLETE slurp_input (); */ -/* OBSOLETE */ -/* OBSOLETE switch (islower (args[0]) ? toupper (args[0]) : args[0]) */ -/* OBSOLETE { */ -/* OBSOLETE default: */ -/* OBSOLETE printf_filtered ("Unknown/Unimplemented adapt command '%s'\n", args); */ -/* OBSOLETE break; */ -/* OBSOLETE case 'G': /* Go, begin execution */ */ -/* OBSOLETE write (adapt_desc, args, strlen (args)); */ -/* OBSOLETE write (adapt_desc, "\r", 1); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE break; */ -/* OBSOLETE case 'B': /* Break points, B or BR */ */ -/* OBSOLETE case 'C': /* Check current 29k status (running/halted) */ */ -/* OBSOLETE case 'D': /* Display data/registers */ */ -/* OBSOLETE case 'I': /* Input from i/o space */ */ -/* OBSOLETE case 'J': /* Jam an instruction */ */ -/* OBSOLETE case 'K': /* Kill, stop execution */ */ -/* OBSOLETE case 'L': /* Disassemble */ */ -/* OBSOLETE case 'O': /* Output to i/o space */ */ -/* OBSOLETE case 'T': /* Trace */ */ -/* OBSOLETE case 'P': /* Pulse an input line */ */ -/* OBSOLETE case 'X': /* Examine special purpose registers */ */ -/* OBSOLETE case 'Z': /* Display trace buffer */ */ -/* OBSOLETE write (adapt_desc, args, strlen (args)); */ -/* OBSOLETE write (adapt_desc, "\r", 1); */ -/* OBSOLETE expect (args); /* Don't display the command */ */ -/* OBSOLETE display_until ("# "); */ -/* OBSOLETE break; */ -/* OBSOLETE /* Begin commands that take input in the form 'c x,y[,z...]' */ */ -/* OBSOLETE case 'S': /* Set memory or register */ */ -/* OBSOLETE if (strchr (args, ',')) */ -/* OBSOLETE { /* Assume it is properly formatted */ */ -/* OBSOLETE write (adapt_desc, args, strlen (args)); */ -/* OBSOLETE write (adapt_desc, "\r", 1); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Define the target subroutine names */ */ -/* OBSOLETE */ -/* OBSOLETE struct target_ops adapt_ops; */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE init_adapt_ops (void) */ -/* OBSOLETE { */ -/* OBSOLETE adapt_ops.to_shortname = "adapt"; */ -/* OBSOLETE adapt_ops.to_longname = "Remote AMD `Adapt' target"; */ -/* OBSOLETE adapt_ops.to_doc = "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232"; */ -/* OBSOLETE adapt_ops.to_open = adapt_open; */ -/* OBSOLETE adapt_ops.to_close = adapt_close; */ -/* OBSOLETE adapt_ops.to_attach = adapt_attach; */ -/* OBSOLETE adapt_ops.to_post_attach = NULL; */ -/* OBSOLETE adapt_ops.to_require_attach = NULL; */ -/* OBSOLETE adapt_ops.to_detach = adapt_detach; */ -/* OBSOLETE adapt_ops.to_require_detach = NULL; */ -/* OBSOLETE adapt_ops.to_resume = adapt_resume; */ -/* OBSOLETE adapt_ops.to_wait = adapt_wait; */ -/* OBSOLETE adapt_ops.to_post_wait = NULL; */ -/* OBSOLETE adapt_ops.to_fetch_registers = adapt_fetch_register; */ -/* OBSOLETE adapt_ops.to_store_registers = adapt_store_register; */ -/* OBSOLETE adapt_ops.to_prepare_to_store = adapt_prepare_to_store; */ -/* OBSOLETE adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory; */ -/* OBSOLETE adapt_ops.to_files_info = adapt_files_info; */ -/* OBSOLETE adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint; */ -/* OBSOLETE adapt_ops.to_remove_breakpoint = adapt_remove_breakpoint; */ -/* OBSOLETE adapt_ops.to_terminal_init = 0; */ -/* OBSOLETE adapt_ops.to_terminal_inferior = 0; */ -/* OBSOLETE adapt_ops.to_terminal_ours_for_output = 0; */ -/* OBSOLETE adapt_ops.to_terminal_ours = 0; */ -/* OBSOLETE adapt_ops.to_terminal_info = 0; */ -/* OBSOLETE adapt_ops.to_kill = adapt_kill; */ -/* OBSOLETE adapt_ops.to_load = adapt_load; */ -/* OBSOLETE adapt_ops.to_lookup_symbol = 0; */ -/* OBSOLETE adapt_ops.to_create_inferior = adapt_create_inferior; */ -/* OBSOLETE adapt_ops.to_post_startup_inferior = NULL; */ -/* OBSOLETE adapt_ops.to_acknowledge_created_inferior = NULL; */ -/* OBSOLETE adapt_ops.to_clone_and_follow_inferior = NULL; */ -/* OBSOLETE adapt_ops.to_post_follow_inferior_by_clone = NULL; */ -/* OBSOLETE adapt_ops.to_insert_fork_catchpoint = NULL; */ -/* OBSOLETE adapt_ops.to_remove_fork_catchpoint = NULL; */ -/* OBSOLETE adapt_ops.to_insert_vfork_catchpoint = NULL; */ -/* OBSOLETE adapt_ops.to_remove_vfork_catchpoint = NULL; */ -/* OBSOLETE adapt_ops.to_has_forked = NULL; */ -/* OBSOLETE adapt_ops.to_has_vforked = NULL; */ -/* OBSOLETE adapt_ops.to_can_follow_vfork_prior_to_exec = NULL; */ -/* OBSOLETE adapt_ops.to_post_follow_vfork = NULL; */ -/* OBSOLETE adapt_ops.to_insert_exec_catchpoint = NULL; */ -/* OBSOLETE adapt_ops.to_remove_exec_catchpoint = NULL; */ -/* OBSOLETE adapt_ops.to_has_execd = NULL; */ -/* OBSOLETE adapt_ops.to_reported_exec_events_per_exec_call = NULL; */ -/* OBSOLETE adapt_ops.to_has_exited = NULL; */ -/* OBSOLETE adapt_ops.to_mourn_inferior = adapt_mourn; */ -/* OBSOLETE adapt_ops.to_can_run = 0; */ -/* OBSOLETE adapt_ops.to_notice_signals = 0; */ -/* OBSOLETE adapt_ops.to_thread_alive = 0; */ -/* OBSOLETE adapt_ops.to_stop = 0; /* process_stratum; */ */ -/* OBSOLETE adapt_ops.to_pid_to_exec_file = NULL; */ -/* OBSOLETE adapt_ops.to_stratum = 0; */ -/* OBSOLETE adapt_ops.DONT_USE = 0; */ -/* OBSOLETE adapt_ops.to_has_all_memory = 1; */ -/* OBSOLETE adapt_ops.to_has_memory = 1; */ -/* OBSOLETE adapt_ops.to_has_stack = 1; */ -/* OBSOLETE adapt_ops.to_has_registers = 1; */ -/* OBSOLETE adapt_ops.to_has_execution = 0; */ -/* OBSOLETE adapt_ops.to_sections = 0; */ -/* OBSOLETE adapt_ops.to_sections_end = 0; */ -/* OBSOLETE adapt_ops.to_magic = OPS_MAGIC; */ -/* OBSOLETE } /* init_adapt_ops */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE _initialize_remote_adapt (void) */ -/* OBSOLETE { */ -/* OBSOLETE init_adapt_ops (); */ -/* OBSOLETE add_target (&adapt_ops); */ -/* OBSOLETE add_com ("adapt ", class_obscure, adapt_com, */ -/* OBSOLETE "Send a command to the AMD Adapt remote monitor."); */ -/* OBSOLETE } */ diff --git a/contrib/gdb/gdb/remote-array.c b/contrib/gdb/gdb/remote-array.c deleted file mode 100644 index 204aaed40a4..00000000000 --- a/contrib/gdb/gdb/remote-array.c +++ /dev/null @@ -1,1457 +0,0 @@ -/* Remote debugging interface for Array Tech RAID controller.. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - - Contributed by Cygnus Support. Written by Rob Savoye for Cygnus. - - This module talks to a debug monitor called 'MONITOR', which - We communicate with MONITOR via either a direct serial line, or a TCP - (or possibly TELNET) stream to a terminal multiplexor, - which in turn talks to the target board. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include -#include -#include "gdb_string.h" -#include "command.h" -#include "serial.h" -#include "monitor.h" -#include "remote-utils.h" -#include "inferior.h" -#include "version.h" -#include "regcache.h" - -extern int baud_rate; - -#define ARRAY_PROMPT ">> " - -static void debuglogs (int, char *, ...); -static void array_open (); -static void array_close (); -static void array_detach (); -static void array_attach (); -static void array_resume (ptid_t ptid, int step, enum target_signal sig); -static void array_fetch_register (); -static void array_store_register (); -static void array_fetch_registers (); -static void array_store_registers (); -static void array_prepare_to_store (); -static void array_files_info (); -static void array_kill (); -static void array_create_inferior (); -static void array_mourn_inferior (); -static void make_gdb_packet (); -static int array_xfer_memory (); -static ptid_t array_wait (ptid_t ptid, - struct target_waitstatus *status); -static int array_insert_breakpoint (); -static int array_remove_breakpoint (); -static int tohex (); -static int to_hex (); -static int from_hex (); -static int array_send_packet (); -static int array_get_packet (); -static unsigned long ascii2hexword (); -static void hexword2ascii (); - -#define LOG_FILE "monitor.log" -#if defined (LOG_FILE) -FILE *log_file; -#endif - -static int timeout = 30; -/* Having this larger than 400 causes us to be incompatible with m68k-stub.c - and i386-stub.c. Normally, no one would notice because it only matters - for writing large chunks of memory (e.g. in downloads). Also, this needs - to be more than 400 if required to hold the registers (see below, where - we round it up based on REGISTER_BYTES). */ -#define PBUFSIZ 400 - -/* - * Descriptor for I/O to remote machine. Initialize it to NULL so that - * array_open knows that we don't have a file open when the program starts. - */ -struct serial *array_desc = NULL; - -/* - * this array of registers need to match the indexes used by GDB. The - * whole reason this exists is cause the various ROM monitors use - * different strings than GDB does, and doesn't support all the - * registers either. So, typing "info reg sp" becomes a "r30". - */ -extern char *tmp_mips_processor_type; -extern int mips_set_processor_type (); - -static struct target_ops array_ops; - -static void -init_array_ops (void) -{ - array_ops.to_shortname = "array"; - array_ops.to_longname = - "Debug using the standard GDB remote protocol for the Array Tech target.", - array_ops.to_doc = - "Debug using the standard GDB remote protocol for the Array Tech target.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - array_ops.to_open = array_open; - array_ops.to_close = array_close; - array_ops.to_attach = NULL; - array_ops.to_post_attach = NULL; - array_ops.to_require_attach = NULL; - array_ops.to_detach = array_detach; - array_ops.to_require_detach = NULL; - array_ops.to_resume = array_resume; - array_ops.to_wait = array_wait; - array_ops.to_post_wait = NULL; - array_ops.to_fetch_registers = array_fetch_registers; - array_ops.to_store_registers = array_store_registers; - array_ops.to_prepare_to_store = array_prepare_to_store; - array_ops.to_xfer_memory = array_xfer_memory; - array_ops.to_files_info = array_files_info; - array_ops.to_insert_breakpoint = array_insert_breakpoint; - array_ops.to_remove_breakpoint = array_remove_breakpoint; - array_ops.to_terminal_init = 0; - array_ops.to_terminal_inferior = 0; - array_ops.to_terminal_ours_for_output = 0; - array_ops.to_terminal_ours = 0; - array_ops.to_terminal_info = 0; - array_ops.to_kill = array_kill; - array_ops.to_load = 0; - array_ops.to_lookup_symbol = 0; - array_ops.to_create_inferior = array_create_inferior; - array_ops.to_post_startup_inferior = NULL; - array_ops.to_acknowledge_created_inferior = NULL; - array_ops.to_clone_and_follow_inferior = NULL; - array_ops.to_post_follow_inferior_by_clone = NULL; - array_ops.to_insert_fork_catchpoint = NULL; - array_ops.to_remove_fork_catchpoint = NULL; - array_ops.to_insert_vfork_catchpoint = NULL; - array_ops.to_remove_vfork_catchpoint = NULL; - array_ops.to_has_forked = NULL; - array_ops.to_has_vforked = NULL; - array_ops.to_can_follow_vfork_prior_to_exec = NULL; - array_ops.to_post_follow_vfork = NULL; - array_ops.to_insert_exec_catchpoint = NULL; - array_ops.to_remove_exec_catchpoint = NULL; - array_ops.to_has_execd = NULL; - array_ops.to_reported_exec_events_per_exec_call = NULL; - array_ops.to_has_exited = NULL; - array_ops.to_mourn_inferior = array_mourn_inferior; - array_ops.to_can_run = 0; - array_ops.to_notice_signals = 0; - array_ops.to_thread_alive = 0; - array_ops.to_stop = 0; - array_ops.to_pid_to_exec_file = NULL; - array_ops.to_stratum = process_stratum; - array_ops.DONT_USE = 0; - array_ops.to_has_all_memory = 1; - array_ops.to_has_memory = 1; - array_ops.to_has_stack = 1; - array_ops.to_has_registers = 1; - array_ops.to_has_execution = 1; - array_ops.to_sections = 0; - array_ops.to_sections_end = 0; - array_ops.to_magic = OPS_MAGIC; -}; - -/* - * printf_monitor -- send data to monitor. Works just like printf. - */ -static void -printf_monitor (char *pattern,...) -{ - va_list args; - char buf[PBUFSIZ]; - int i; - - va_start (args, pattern); - - vsprintf (buf, pattern, args); - - debuglogs (1, "printf_monitor(), Sending: \"%s\".", buf); - - if (strlen (buf) > PBUFSIZ) - error ("printf_monitor(): string too long"); - if (serial_write (array_desc, buf, strlen (buf))) - fprintf (stderr, "serial_write failed: %s\n", safe_strerror (errno)); -} -/* - * write_monitor -- send raw data to monitor. - */ -static void -write_monitor (char data[], int len) -{ - if (serial_write (array_desc, data, len)) - fprintf (stderr, "serial_write failed: %s\n", safe_strerror (errno)); - - *(data + len + 1) = '\0'; - debuglogs (1, "write_monitor(), Sending: \"%s\".", data); - -} - -/* - * debuglogs -- deal with debugging info to multiple sources. This takes - * two real args, the first one is the level to be compared against - * the sr_get_debug() value, the second arg is a printf buffer and args - * to be formatted and printed. A CR is added after each string is printed. - */ -static void -debuglogs (int level, char *pattern,...) -{ - va_list args; - char *p; - unsigned char buf[PBUFSIZ]; - char newbuf[PBUFSIZ]; - int i; - - va_start (args, pattern); - - if ((level < 0) || (level > 100)) - { - error ("Bad argument passed to debuglogs(), needs debug level"); - return; - } - - vsprintf (buf, pattern, args); /* format the string */ - - /* convert some characters so it'll look right in the log */ - p = newbuf; - for (i = 0; buf[i] != '\0'; i++) - { - if (i > PBUFSIZ) - error ("Debug message too long"); - switch (buf[i]) - { - case '\n': /* newlines */ - *p++ = '\\'; - *p++ = 'n'; - continue; - case '\r': /* carriage returns */ - *p++ = '\\'; - *p++ = 'r'; - continue; - case '\033': /* escape */ - *p++ = '\\'; - *p++ = 'e'; - continue; - case '\t': /* tab */ - *p++ = '\\'; - *p++ = 't'; - continue; - case '\b': /* backspace */ - *p++ = '\\'; - *p++ = 'b'; - continue; - default: /* no change */ - *p++ = buf[i]; - } - - if (buf[i] < 26) - { /* modify control characters */ - *p++ = '^'; - *p++ = buf[i] + 'A'; - continue; - } - if (buf[i] >= 128) - { /* modify control characters */ - *p++ = '!'; - *p++ = buf[i] + 'A'; - continue; - } - } - *p = '\0'; /* terminate the string */ - - if (sr_get_debug () > level) - printf_unfiltered ("%s\n", newbuf); - -#ifdef LOG_FILE /* write to the monitor log */ - if (log_file != 0x0) - { - fputs (newbuf, log_file); - fputc ('\n', log_file); - fflush (log_file); - } -#endif -} - -/* readchar -- read a character from the remote system, doing all the fancy - * timeout stuff. - */ -static int -readchar (int timeout) -{ - int c; - - c = serial_readchar (array_desc, abs (timeout)); - - if (sr_get_debug () > 5) - { - putchar (c & 0x7f); - debuglogs (5, "readchar: timeout = %d\n", timeout); - } - -#ifdef LOG_FILE - if (isascii (c)) - putc (c & 0x7f, log_file); -#endif - - if (c >= 0) - return c & 0x7f; - - if (c == SERIAL_TIMEOUT) - { - if (timeout <= 0) - return c; /* Polls shouldn't generate timeout errors */ - error ("Timeout reading from remote system."); -#ifdef LOG_FILE - fputs ("ERROR: Timeout reading from remote system", log_file); -#endif - } - perror_with_name ("readchar"); -} - -/* - * expect -- scan input from the remote system, until STRING is found. - * If DISCARD is non-zero, then discard non-matching input, else print - * it out. Let the user break out immediately. - */ -static void -expect (char *string, int discard) -{ - char *p = string; - int c; - - - debuglogs (1, "Expecting \"%s\".", string); - - immediate_quit++; - while (1) - { - c = readchar (timeout); - if (!isascii (c)) - continue; - if (c == *p++) - { - if (*p == '\0') - { - immediate_quit--; - debuglogs (4, "Matched"); - return; - } - } - else - { - if (!discard) - { - fputc_unfiltered (c, gdb_stdout); - } - p = string; - } - } -} - -/* Keep discarding input until we see the MONITOR array_cmds->prompt. - - The convention for dealing with the expect_prompt is that you - o give your command - o *then* wait for the expect_prompt. - - Thus the last thing that a procedure does with the serial line - will be an expect_prompt(). Exception: array_resume does not - wait for the expect_prompt, because the terminal is being handed over - to the inferior. However, the next thing which happens after that - is a array_wait which does wait for the expect_prompt. - Note that this includes abnormal exit, e.g. error(). This is - necessary to prevent getting into states from which we can't - recover. */ -static void -expect_prompt (int discard) -{ - expect (ARRAY_PROMPT, discard); -} - -/* - * junk -- ignore junk characters. Returns a 1 if junk, 0 otherwise - */ -static int -junk (char ch) -{ - switch (ch) - { - case '\0': - case ' ': - case '-': - case '\t': - case '\r': - case '\n': - if (sr_get_debug () > 5) - debuglogs (5, "Ignoring \'%c\'.", ch); - return 1; - default: - if (sr_get_debug () > 5) - debuglogs (5, "Accepting \'%c\'.", ch); - return 0; - } -} - -/* - * get_hex_digit -- Get a hex digit from the remote system & return its value. - * If ignore is nonzero, ignore spaces, newline & tabs. - */ -static int -get_hex_digit (int ignore) -{ - static int ch; - while (1) - { - ch = readchar (timeout); - if (junk (ch)) - continue; - if (sr_get_debug () > 4) - { - debuglogs (4, "get_hex_digit() got a 0x%x(%c)", ch, ch); - } - else - { -#ifdef LOG_FILE /* write to the monitor log */ - if (log_file != 0x0) - { - fputs ("get_hex_digit() got a 0x", log_file); - fputc (ch, log_file); - fputc ('\n', log_file); - fflush (log_file); - } -#endif - } - - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else if (ch == ' ' && ignore) - ; - else - { - expect_prompt (1); - debuglogs (4, "Invalid hex digit from remote system. (0x%x)", ch); - error ("Invalid hex digit from remote system. (0x%x)", ch); - } - } -} - -/* get_hex_byte -- Get a byte from monitor and put it in *BYT. - * Accept any number leading spaces. - */ -static void -get_hex_byte (char *byt) -{ - int val; - - val = get_hex_digit (1) << 4; - debuglogs (4, "get_hex_byte() -- Read first nibble 0x%x", val); - - val |= get_hex_digit (0); - debuglogs (4, "get_hex_byte() -- Read second nibble 0x%x", val); - *byt = val; - - debuglogs (4, "get_hex_byte() -- Read a 0x%x", val); -} - -/* - * get_hex_word -- Get N 32-bit words from remote, each preceded by a space, - * and put them in registers starting at REGNO. - */ -static int -get_hex_word (void) -{ - long val, newval; - int i; - - val = 0; - - for (i = 0; i < 8; i++) - val = (val << 4) + get_hex_digit (i == 0); - - debuglogs (4, "get_hex_word() got a 0x%x.", val); - - return val; -} - -/* This is called not only when we first attach, but also when the - user types "run" after having attached. */ -static void -array_create_inferior (char *execfile, char *args, char **env) -{ - int entry_pt; - - if (args && *args) - error ("Can't pass arguments to remote MONITOR process"); - - if (execfile == 0 || exec_bfd == 0) - error ("No executable file specified"); - - entry_pt = (int) bfd_get_start_address (exec_bfd); - -/* The "process" (board) is already stopped awaiting our commands, and - the program is already downloaded. We just set its PC and go. */ - - clear_proceed_status (); - - /* Tell wait_for_inferior that we've started a new process. */ - init_wait_for_inferior (); - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - target_terminal_init (); - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - /* insert_step_breakpoint (); FIXME, do we need this? */ - - /* Let 'er rip... */ - proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0); -} - -/* - * array_open -- open a connection to a remote debugger. - * NAME is the filename used for communication. - */ -static int baudrate = 9600; -static char dev_name[100]; - -static void -array_open (char *args, char *name, int from_tty) -{ - char packet[PBUFSIZ]; - - if (args == NULL) - error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\ -`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name); - -/* if (is_open) */ - array_close (0); - - target_preopen (from_tty); - unpush_target (&array_ops); - - tmp_mips_processor_type = "lsi33k"; /* change the default from r3051 */ - mips_set_processor_type_command ("lsi33k", 0); - - strcpy (dev_name, args); - array_desc = serial_open (dev_name); - - if (array_desc == NULL) - perror_with_name (dev_name); - - if (baud_rate != -1) - { - if (serial_setbaudrate (array_desc, baud_rate)) - { - serial_close (array_desc); - perror_with_name (name); - } - } - - serial_raw (array_desc); - -#if defined (LOG_FILE) - log_file = fopen (LOG_FILE, "w"); - if (log_file == NULL) - perror_with_name (LOG_FILE); - fprintf (log_file, "GDB %s (%s", version, host_name); - fprintf (log_file, " --target %s)\n", array_ops.to_shortname); - fprintf (log_file, "Remote target %s connected to %s\n\n", array_ops.to_shortname, dev_name); -#endif - - /* see if the target is alive. For a ROM monitor, we can just try to force the - expect_prompt to print a few times. For the GDB remote protocol, the application - being debugged is sitting at a breakpoint and waiting for GDB to initialize - the connection. We force it to give us an empty packet to see if it's alive. - */ - debuglogs (3, "Trying to ACK the target's debug stub"); - /* unless your are on the new hardware, the old board won't initialize - because the '@' doesn't flush output like it does on the new ROMS. - */ - printf_monitor ("@"); /* ask for the last signal */ - expect_prompt (1); /* See if we get a expect_prompt */ -#ifdef TEST_ARRAY /* skip packet for testing */ - make_gdb_packet (packet, "?"); /* ask for a bogus packet */ - if (array_send_packet (packet) == 0) - error ("Couldn't transmit packet\n"); - printf_monitor ("@\n"); /* force it to flush stdout */ - expect_prompt (1); /* See if we get a expect_prompt */ -#endif - push_target (&array_ops); - if (from_tty) - printf ("Remote target %s connected to %s\n", array_ops.to_shortname, dev_name); -} - -/* - * array_close -- Close out all files and local state before this - * target loses control. - */ - -static void -array_close (int quitting) -{ - serial_close (array_desc); - array_desc = NULL; - - debuglogs (1, "array_close (quitting=%d)", quitting); - -#if defined (LOG_FILE) - if (log_file) - { - if (ferror (log_file)) - printf_filtered ("Error writing log file.\n"); - if (fclose (log_file) != 0) - printf_filtered ("Error closing log file.\n"); - } -#endif -} - -/* - * array_detach -- terminate the open connection to the remote - * debugger. Use this when you want to detach and do something - * else with your gdb. - */ -static void -array_detach (int from_tty) -{ - - debuglogs (1, "array_detach ()"); - - pop_target (); /* calls array_close to do the real work */ - if (from_tty) - printf ("Ending remote %s debugging\n", target_shortname); -} - -/* - * array_attach -- attach GDB to the target. - */ -static void -array_attach (char *args, int from_tty) -{ - if (from_tty) - printf ("Starting remote %s debugging\n", target_shortname); - - debuglogs (1, "array_attach (args=%s)", args); - - printf_monitor ("go %x\n"); - /* swallow the echo. */ - expect ("go %x\n", 1); -} - -/* - * array_resume -- Tell the remote machine to resume. - */ -static void -array_resume (ptid_t ptid, int step, enum target_signal sig) -{ - debuglogs (1, "array_resume (step=%d, sig=%d)", step, sig); - - if (step) - { - printf_monitor ("s\n"); - } - else - { - printf_monitor ("go\n"); - } -} - -#define TMPBUFSIZ 5 - -/* - * array_wait -- Wait until the remote machine stops, then return, - * storing status in status just as `wait' would. - */ -static ptid_t -array_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int old_timeout = timeout; - int result, i; - char c; - struct serial *tty_desc; - serial_ttystate ttystate; - - debuglogs (1, "array_wait (), printing extraneous text."); - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - timeout = 0; /* Don't time out -- user program is running. */ - -#if !defined(__GO32__) && !defined(__MSDOS__) && !defined(_WIN32) - tty_desc = serial_fdopen (0); - ttystate = serial_get_tty_state (tty_desc); - serial_raw (tty_desc); - - i = 0; - /* poll on the serial port and the keyboard. */ - while (1) - { - c = readchar (timeout); - if (c > 0) - { - if (c == *(ARRAY_PROMPT + i)) - { - if (++i >= strlen (ARRAY_PROMPT)) - { /* matched the prompt */ - debuglogs (4, "array_wait(), got the expect_prompt."); - break; - } - } - else - { /* not the prompt */ - i = 0; - } - fputc_unfiltered (c, gdb_stdout); - gdb_flush (gdb_stdout); - } - c = serial_readchar (tty_desc, timeout); - if (c > 0) - { - serial_write (array_desc, &c, 1); - /* do this so it looks like there's keyboard echo */ - if (c == 3) /* exit on Control-C */ - break; -#if 0 - fputc_unfiltered (c, gdb_stdout); - gdb_flush (gdb_stdout); -#endif - } - } - serial_set_tty_state (tty_desc, ttystate); -#else - expect_prompt (1); - debuglogs (4, "array_wait(), got the expect_prompt."); -#endif - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - - timeout = old_timeout; - - return inferior_ptid; -} - -/* - * array_fetch_registers -- read the remote registers into the - * block regs. - */ -static void -array_fetch_registers (int ignored) -{ - char *reg = alloca (MAX_REGISTER_RAW_SIZE); - int regno; - char *p; - char *packet = alloca (PBUFSIZ); - - debuglogs (1, "array_fetch_registers (ignored=%d)\n", ignored); - - memset (packet, 0, PBUFSIZ); - make_gdb_packet (packet, "g"); - if (array_send_packet (packet) == 0) - error ("Couldn't transmit packet\n"); - if (array_get_packet (packet) == 0) - error ("Couldn't receive packet\n"); - /* FIXME: read bytes from packet */ - debuglogs (4, "array_fetch_registers: Got a \"%s\" back\n", packet); - for (regno = 0; regno <= PC_REGNUM + 4; regno++) - { - /* supply register stores in target byte order, so swap here */ - /* FIXME: convert from ASCII hex to raw bytes */ - LONGEST i = ascii2hexword (packet + (regno * 8)); - debuglogs (5, "Adding register %d = %x\n", regno, i); - store_unsigned_integer (®, REGISTER_RAW_SIZE (regno), i); - supply_register (regno, (char *) ®); - } -} - -/* - * This is unused by targets like this one that use a - * protocol based on GDB's remote protocol. - */ -static void -array_fetch_register (int ignored) -{ - array_fetch_registers (0 /* ignored */); -} - -/* - * Get all the registers from the targets. They come back in a large array. - */ -static void -array_store_registers (int ignored) -{ - int regno; - unsigned long i; - char packet[PBUFSIZ]; - char buf[PBUFSIZ]; - char num[9]; - - debuglogs (1, "array_store_registers()"); - - memset (packet, 0, PBUFSIZ); - memset (buf, 0, PBUFSIZ); - buf[0] = 'G'; - - /* Unimplemented registers read as all bits zero. */ - /* FIXME: read bytes from packet */ - for (regno = 0; regno < 41; regno++) - { /* FIXME */ - /* supply register stores in target byte order, so swap here */ - /* FIXME: convert from ASCII hex to raw bytes */ - i = (unsigned long) read_register (regno); - hexword2ascii (num, i); - strcpy (buf + (regno * 8) + 1, num); - } - *(buf + (regno * 8) + 2) = 0; - make_gdb_packet (packet, buf); - if (array_send_packet (packet) == 0) - error ("Couldn't transmit packet\n"); - if (array_get_packet (packet) == 0) - error ("Couldn't receive packet\n"); - - registers_changed (); -} - -/* - * This is unused by targets like this one that use a - * protocol based on GDB's remote protocol. - */ -static void -array_store_register (int ignored) -{ - array_store_registers (0 /* ignored */); -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -array_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -static void -array_files_info (void) -{ - printf ("\tAttached to %s at %d baud.\n", - dev_name, baudrate); -} - -/* - * array_write_inferior_memory -- Copy LEN bytes of data from debugger - * memory at MYADDR to inferior's memory at MEMADDR. Returns length moved. - */ -static int -array_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - unsigned long i; - int j; - char packet[PBUFSIZ]; - char buf[PBUFSIZ]; - char num[9]; - char *p; - - debuglogs (1, "array_write_inferior_memory (memaddr=0x%x, myaddr=0x%x, len=%d)", memaddr, myaddr, len); - memset (buf, '\0', PBUFSIZ); /* this also sets the string terminator */ - p = buf; - - *p++ = 'M'; /* The command to write memory */ - hexword2ascii (num, memaddr); /* convert the address */ - strcpy (p, num); /* copy the address */ - p += 8; - *p++ = ','; /* add comma delimeter */ - hexword2ascii (num, len); /* Get the length as a 4 digit number */ - *p++ = num[4]; - *p++ = num[5]; - *p++ = num[6]; - *p++ = num[7]; - *p++ = ':'; /* add the colon delimeter */ - for (j = 0; j < len; j++) - { /* copy the data in after converting it */ - *p++ = tohex ((myaddr[j] >> 4) & 0xf); - *p++ = tohex (myaddr[j] & 0xf); - } - - make_gdb_packet (packet, buf); - if (array_send_packet (packet) == 0) - error ("Couldn't transmit packet\n"); - if (array_get_packet (packet) == 0) - error ("Couldn't receive packet\n"); - - return len; -} - -/* - * array_read_inferior_memory -- read LEN bytes from inferior memory - * at MEMADDR. Put the result at debugger address MYADDR. Returns - * length moved. - */ -static int -array_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - int j; - char buf[20]; - char packet[PBUFSIZ]; - int count; /* Number of bytes read so far. */ - unsigned long startaddr; /* Starting address of this pass. */ - int len_this_pass; /* Number of bytes to read in this pass. */ - - debuglogs (1, "array_read_inferior_memory (memaddr=0x%x, myaddr=0x%x, len=%d)", memaddr, myaddr, len); - - /* Note that this code works correctly if startaddr is just less - than UINT_MAX (well, really CORE_ADDR_MAX if there was such a - thing). That is, something like - array_read_bytes (CORE_ADDR_MAX - 4, foo, 4) - works--it never adds len To memaddr and gets 0. */ - /* However, something like - array_read_bytes (CORE_ADDR_MAX - 3, foo, 4) - doesn't need to work. Detect it and give up if there's an attempt - to do that. */ - if (((memaddr - 1) + len) < memaddr) - { - errno = EIO; - return 0; - } - - for (count = 0, startaddr = memaddr; count < len; startaddr += len_this_pass) - { - /* Try to align to 16 byte boundry (why?) */ - len_this_pass = 16; - if ((startaddr % 16) != 0) - { - len_this_pass -= startaddr % 16; - } - /* Only transfer bytes we need */ - if (len_this_pass > (len - count)) - { - len_this_pass = (len - count); - } - /* Fetch the bytes */ - debuglogs (3, "read %d bytes from inferior address %x", len_this_pass, - startaddr); - sprintf (buf, "m%08lx,%04x", startaddr, len_this_pass); - make_gdb_packet (packet, buf); - if (array_send_packet (packet) == 0) - { - error ("Couldn't transmit packet\n"); - } - if (array_get_packet (packet) == 0) - { - error ("Couldn't receive packet\n"); - } - if (*packet == 0) - { - error ("Got no data in the GDB packet\n"); - } - /* Pick packet apart and xfer bytes to myaddr */ - debuglogs (4, "array_read_inferior_memory: Got a \"%s\" back\n", packet); - for (j = 0; j < len_this_pass; j++) - { - /* extract the byte values */ - myaddr[count++] = from_hex (*(packet + (j * 2))) * 16 + from_hex (*(packet + (j * 2) + 1)); - debuglogs (5, "myaddr[%d] set to %x\n", count - 1, myaddr[count - 1]); - } - } - return (count); -} - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If WRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - Returns the number of bytes transferred. */ - -static int -array_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, struct target_ops *target) -{ - if (write) - return array_write_inferior_memory (memaddr, myaddr, len); - else - return array_read_inferior_memory (memaddr, myaddr, len); -} - -static void -array_kill (char *args, int from_tty) -{ - return; /* ignore attempts to kill target system */ -} - -/* Clean up when a program exits. - The program actually lives on in the remote processor's RAM, and may be - run again without a download. Don't leave it full of breakpoint - instructions. */ - -static void -array_mourn_inferior (void) -{ - remove_breakpoints (); - generic_mourn_inferior (); /* Do all the proper things now */ -} - -#define MAX_ARRAY_BREAKPOINTS 16 - -static CORE_ADDR breakaddr[MAX_ARRAY_BREAKPOINTS] = -{0}; - -/* - * array_insert_breakpoint -- add a breakpoint - */ -static int -array_insert_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - int bp_size = 0; - CORE_ADDR bp_addr = addr; - - debuglogs (1, "array_insert_breakpoint() addr = 0x%x", addr); - BREAKPOINT_FROM_PC (&bp_addr, &bp_size); - - for (i = 0; i <= MAX_ARRAY_BREAKPOINTS; i++) - { - if (breakaddr[i] == 0) - { - breakaddr[i] = addr; - if (sr_get_debug () > 4) - printf ("Breakpoint at %s\n", paddr_nz (addr)); - array_read_inferior_memory (bp_addr, shadow, bp_size); - printf_monitor ("b 0x%x\n", addr); - expect_prompt (1); - return 0; - } - } - - fprintf (stderr, "Too many breakpoints (> 16) for monitor\n"); - return 1; -} - -/* - * _remove_breakpoint -- Tell the monitor to remove a breakpoint - */ -static int -array_remove_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - - debuglogs (1, "array_remove_breakpoint() addr = 0x%x", addr); - - for (i = 0; i < MAX_ARRAY_BREAKPOINTS; i++) - { - if (breakaddr[i] == addr) - { - breakaddr[i] = 0; - /* some monitors remove breakpoints based on the address */ - printf_monitor ("bd %x\n", i); - expect_prompt (1); - return 0; - } - } - fprintf (stderr, "Can't find breakpoint associated with 0x%s\n", - paddr_nz (addr)); - return 1; -} - -static void -array_stop (void) -{ - debuglogs (1, "array_stop()"); - printf_monitor ("\003"); - expect_prompt (1); -} - -/* - * array_command -- put a command string, in args, out to MONITOR. - * Output from MONITOR is placed on the users terminal until the - * expect_prompt is seen. FIXME - */ -static void -monitor_command (char *args, int fromtty) -{ - debuglogs (1, "monitor_command (args=%s)", args); - - if (array_desc == NULL) - error ("monitor target not open."); - - if (!args) - error ("Missing command."); - - printf_monitor ("%s\n", args); - expect_prompt (0); -} - -/* - * make_gdb_packet -- make a GDB packet. The data is always ASCII. - * A debug packet whose contents are - * is encapsulated for transmission in the form: - * - * $ # CSUM1 CSUM2 - * - * must be ASCII alphanumeric and cannot include characters - * '$' or '#'. If starts with two characters followed by - * ':', then the existing stubs interpret this as a sequence number. - * - * CSUM1 and CSUM2 are ascii hex representation of an 8-bit - * checksum of , the most significant nibble is sent first. - * the hex digits 0-9,a-f are used. - * - */ -static void -make_gdb_packet (char *buf, char *data) -{ - int i; - unsigned char csum = 0; - int cnt; - char *p; - - debuglogs (3, "make_gdb_packet(%s)\n", data); - cnt = strlen (data); - if (cnt > PBUFSIZ) - error ("make_gdb_packet(): to much data\n"); - - /* start with the packet header */ - p = buf; - *p++ = '$'; - - /* calculate the checksum */ - for (i = 0; i < cnt; i++) - { - csum += data[i]; - *p++ = data[i]; - } - - /* terminate the data with a '#' */ - *p++ = '#'; - - /* add the checksum as two ascii digits */ - *p++ = tohex ((csum >> 4) & 0xf); - *p++ = tohex (csum & 0xf); - *p = 0x0; /* Null terminator on string */ -} - -/* - * array_send_packet -- send a GDB packet to the target with error handling. We - * get a '+' (ACK) back if the packet is received and the checksum - * matches. Otherwise a '-' (NAK) is returned. It returns a 1 for a - * successful transmition, or a 0 for a failure. - */ -static int -array_send_packet (char *packet) -{ - int c, retries, i; - char junk[PBUFSIZ]; - - retries = 0; - -#if 0 - /* scan the packet to make sure it only contains valid characters. - this may sound silly, but sometimes a garbled packet will hang - the target board. We scan the whole thing, then print the error - message. - */ - for (i = 0; i < strlen (packet); i++) - { - debuglogs (5, "array_send_packet(): Scanning \'%c\'\n", packet[i]); - /* legit hex numbers or command */ - if ((isxdigit (packet[i])) || (isalpha (packet[i]))) - continue; - switch (packet[i]) - { - case '+': /* ACK */ - case '-': /* NAK */ - case '#': /* end of packet */ - case '$': /* start of packet */ - continue; - default: /* bogus character */ - retries++; - debuglogs (4, "array_send_packet(): Found a non-ascii digit \'%c\' in the packet.\n", packet[i]); - } - } -#endif - - if (retries > 0) - error ("Can't send packet, found %d non-ascii characters", retries); - - /* ok, try to send the packet */ - retries = 0; - while (retries++ <= 10) - { - printf_monitor ("%s", packet); - - /* read until either a timeout occurs (-2) or '+' is read */ - while (retries <= 10) - { - c = readchar (-timeout); - debuglogs (3, "Reading a GDB protocol packet... Got a '%c'\n", c); - switch (c) - { - case '+': - debuglogs (3, "Got Ack\n"); - return 1; - case SERIAL_TIMEOUT: - debuglogs (3, "Timed out reading serial port\n"); - printf_monitor ("@"); /* resync with the monitor */ - expect_prompt (1); /* See if we get a expect_prompt */ - break; /* Retransmit buffer */ - case '-': - debuglogs (3, "Got NAK\n"); - printf_monitor ("@"); /* resync with the monitor */ - expect_prompt (1); /* See if we get a expect_prompt */ - break; - case '$': - /* it's probably an old response, or the echo of our command. - * just gobble up the packet and ignore it. - */ - debuglogs (3, "Got a junk packet\n"); - i = 0; - do - { - c = readchar (timeout); - junk[i++] = c; - } - while (c != '#'); - c = readchar (timeout); - junk[i++] = c; - c = readchar (timeout); - junk[i++] = c; - junk[i++] = '\0'; - debuglogs (3, "Reading a junk packet, got a \"%s\"\n", junk); - continue; /* Now, go look for next packet */ - default: - continue; - } - retries++; - debuglogs (3, "Retransmitting packet \"%s\"\n", packet); - break; /* Here to retransmit */ - } - } /* outer while */ - return 0; -} - -/* - * array_get_packet -- get a GDB packet from the target. Basically we read till we - * see a '#', then check the checksum. It returns a 1 if it's gotten a - * packet, or a 0 it the packet wasn't transmitted correctly. - */ -static int -array_get_packet (char *packet) -{ - int c; - int retries; - unsigned char csum; - unsigned char pktcsum; - char *bp; - - csum = 0; - bp = packet; - - memset (packet, 1, PBUFSIZ); - retries = 0; - while (retries <= 10) - { - do - { - c = readchar (timeout); - if (c == SERIAL_TIMEOUT) - { - debuglogs (3, "array_get_packet: got time out from serial port.\n"); - } - debuglogs (3, "Waiting for a '$', got a %c\n", c); - } - while (c != '$'); - - retries = 0; - while (retries <= 10) - { - c = readchar (timeout); - debuglogs (3, "array_get_packet: got a '%c'\n", c); - switch (c) - { - case SERIAL_TIMEOUT: - debuglogs (3, "Timeout in mid-packet, retrying\n"); - return 0; - case '$': - debuglogs (3, "Saw new packet start in middle of old one\n"); - return 0; /* Start a new packet, count retries */ - case '#': - *bp = '\0'; - pktcsum = from_hex (readchar (timeout)) << 4; - pktcsum |= from_hex (readchar (timeout)); - if (csum == 0) - debuglogs (3, "\nGDB packet checksum zero, must be a bogus packet\n"); - if (csum == pktcsum) - { - debuglogs (3, "\nGDB packet checksum correct, packet data is \"%s\",\n", packet); - printf_monitor ("@"); - expect_prompt (1); - return 1; - } - debuglogs (3, "Bad checksum, sentsum=0x%x, csum=0x%x\n", pktcsum, csum); - return 0; - case '*': /* Run length encoding */ - debuglogs (5, "Run length encoding in packet\n"); - csum += c; - c = readchar (timeout); - csum += c; - c = c - ' ' + 3; /* Compute repeat count */ - - if (c > 0 && c < 255 && bp + c - 1 < packet + PBUFSIZ - 1) - { - memset (bp, *(bp - 1), c); - bp += c; - continue; - } - *bp = '\0'; - printf_filtered ("Repeat count %d too large for buffer.\n", c); - return 0; - - default: - if ((!isxdigit (c)) && (!ispunct (c))) - debuglogs (4, "Got a non-ascii digit \'%c\'.\\n", c); - if (bp < packet + PBUFSIZ - 1) - { - *bp++ = c; - csum += c; - continue; - } - - *bp = '\0'; - puts_filtered ("Remote packet too long.\n"); - return 0; - } - } - } - return 0; /* exceeded retries */ -} - -/* - * ascii2hexword -- convert an ascii number represented by 8 digits to a hex value. - */ -static unsigned long -ascii2hexword (unsigned char *mem) -{ - unsigned long val; - int i; - char buf[9]; - - val = 0; - for (i = 0; i < 8; i++) - { - val <<= 4; - if (mem[i] >= 'A' && mem[i] <= 'F') - val = val + mem[i] - 'A' + 10; - if (mem[i] >= 'a' && mem[i] <= 'f') - val = val + mem[i] - 'a' + 10; - if (mem[i] >= '0' && mem[i] <= '9') - val = val + mem[i] - '0'; - buf[i] = mem[i]; - } - buf[8] = '\0'; - debuglogs (4, "ascii2hexword() got a 0x%x from %s(%x).\n", val, buf, mem); - return val; -} - -/* - * ascii2hexword -- convert a hex value to an ascii number represented by 8 - * digits. - */ -static void -hexword2ascii (unsigned char *mem, unsigned long num) -{ - int i; - unsigned char ch; - - debuglogs (4, "hexword2ascii() converting %x ", num); - for (i = 7; i >= 0; i--) - { - mem[i] = tohex ((num >> 4) & 0xf); - mem[i] = tohex (num & 0xf); - num = num >> 4; - } - mem[8] = '\0'; - debuglogs (4, "\tto a %s", mem); -} - -/* Convert hex digit A to a number. */ -static int -from_hex (int a) -{ - if (a == 0) - return 0; - - debuglogs (4, "from_hex got a 0x%x(%c)\n", a, a); - if (a >= '0' && a <= '9') - return a - '0'; - if (a >= 'a' && a <= 'f') - return a - 'a' + 10; - if (a >= 'A' && a <= 'F') - return a - 'A' + 10; - else - { - error ("Reply contains invalid hex digit 0x%x", a); - } -} - -/* Convert number NIB to a hex digit. */ -static int -tohex (int nib) -{ - if (nib < 10) - return '0' + nib; - else - return 'a' + nib - 10; -} - -/* - * _initialize_remote_monitors -- setup a few addtitional commands that - * are usually only used by monitors. - */ -void -_initialize_remote_monitors (void) -{ - /* generic monitor command */ - add_com ("monitor", class_obscure, monitor_command, - "Send a command to the debug monitor."); - -} - -/* - * _initialize_array -- do any special init stuff for the target. - */ -void -_initialize_array (void) -{ - init_array_ops (); - add_target (&array_ops); -} diff --git a/contrib/gdb/gdb/remote-bug.c b/contrib/gdb/gdb/remote-bug.c deleted file mode 100644 index f74ce9768e2..00000000000 --- a/contrib/gdb/gdb/remote-bug.c +++ /dev/null @@ -1,1027 +0,0 @@ -/* Remote debugging interface for Motorola's MVME187BUG monitor, an embedded - monitor for the m88k. - - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation, Inc. - - Contributed by Cygnus Support. Written by K. Richard Pixley. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "gdb_string.h" -#include "regcache.h" -#include -#include -#include -#include - -#include "terminal.h" -#include "gdbcore.h" -#include "gdbcmd.h" - -#include "serial.h" -#include "remote-utils.h" - -/* External data declarations */ -extern int stop_soon_quietly; /* for wait_for_inferior */ - -/* Forward data declarations */ -extern struct target_ops bug_ops; /* Forward declaration */ - -/* Forward function declarations */ -static int bug_clear_breakpoints (void); - -static int bug_read_memory (CORE_ADDR memaddr, - unsigned char *myaddr, int len); - -static int bug_write_memory (CORE_ADDR memaddr, - unsigned char *myaddr, int len); - -/* This variable is somewhat arbitrary. It's here so that it can be - set from within a running gdb. */ - -static int srec_max_retries = 3; - -/* Each S-record download to the target consists of an S0 header - record, some number of S3 data records, and one S7 termination - record. I call this download a "frame". Srec_frame says how many - bytes will be represented in each frame. */ - -#define SREC_SIZE 160 -static int srec_frame = SREC_SIZE; - -/* This variable determines how many bytes will be represented in each - S3 s-record. */ - -static int srec_bytes = 40; - -/* At one point it appeared to me as though the bug monitor could not - really be expected to receive two sequential characters at 9600 - baud reliably. Echo-pacing is an attempt to force data across the - line even in this condition. Specifically, in echo-pace mode, each - character is sent one at a time and we look for the echo before - sending the next. This is excruciatingly slow. */ - -static int srec_echo_pace = 0; - -/* How long to wait after an srec for a possible error message. - Similar to the above, I tried sleeping after sending each S3 record - in hopes that I might actually see error messages from the bug - monitor. This might actually work if we were to use sleep - intervals smaller than 1 second. */ - -static int srec_sleep = 0; - -/* Every srec_noise records, flub the checksum. This is a debugging - feature. Set the variable to something other than 1 in order to - inject *deliberate* checksum errors. One might do this if one - wanted to test error handling and recovery. */ - -static int srec_noise = 0; - -/* Called when SIGALRM signal sent due to alarm() timeout. */ - -/* Number of SIGTRAPs we need to simulate. That is, the next - NEED_ARTIFICIAL_TRAP calls to bug_wait should just return - SIGTRAP without actually waiting for anything. */ - -static int need_artificial_trap = 0; - -/* - * Download a file specified in 'args', to the bug. - */ - -static void -bug_load (char *args, int fromtty) -{ - bfd *abfd; - asection *s; - char buffer[1024]; - - sr_check_open (); - - inferior_ptid = null_ptid; - abfd = bfd_openr (args, 0); - if (!abfd) - { - printf_filtered ("Unable to open file %s\n", args); - return; - } - - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - return; - } - - s = abfd->sections; - while (s != (asection *) NULL) - { - srec_frame = SREC_SIZE; - if (s->flags & SEC_LOAD) - { - int i; - - char *buffer = xmalloc (srec_frame); - - printf_filtered ("%s\t: 0x%4lx .. 0x%4lx ", s->name, s->vma, s->vma + s->_raw_size); - gdb_flush (gdb_stdout); - for (i = 0; i < s->_raw_size; i += srec_frame) - { - if (srec_frame > s->_raw_size - i) - srec_frame = s->_raw_size - i; - - bfd_get_section_contents (abfd, s, buffer, i, srec_frame); - bug_write_memory (s->vma + i, buffer, srec_frame); - printf_filtered ("*"); - gdb_flush (gdb_stdout); - } - printf_filtered ("\n"); - xfree (buffer); - } - s = s->next; - } - sprintf (buffer, "rs ip %lx", (unsigned long) abfd->start_address); - sr_write_cr (buffer); - gr_expect_prompt (); -} - -#if 0 -static char * -get_word (char **p) -{ - char *s = *p; - char *word; - char *copy; - size_t len; - - while (isspace (*s)) - s++; - - word = s; - - len = 0; - - while (*s && !isspace (*s)) - { - s++; - len++; - - } - copy = xmalloc (len + 1); - memcpy (copy, word, len); - copy[len] = 0; - *p = s; - return copy; -} -#endif - -static struct gr_settings bug_settings = -{ - "Bug>", /* prompt */ - &bug_ops, /* ops */ - bug_clear_breakpoints, /* clear_all_breakpoints */ - gr_generic_checkin, /* checkin */ -}; - -static char *cpu_check_strings[] = -{ - "=", - "Invalid Register", -}; - -static void -bug_open (char *args, int from_tty) -{ - if (args == NULL) - args = ""; - - gr_open (args, from_tty, &bug_settings); - /* decide *now* whether we are on an 88100 or an 88110 */ - sr_write_cr ("rs cr06"); - sr_expect ("rs cr06"); - - switch (gr_multi_scan (cpu_check_strings, 0)) - { - case 0: /* this is an m88100 */ - target_is_m88110 = 0; - break; - case 1: /* this is an m88110 */ - target_is_m88110 = 1; - break; - default: - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } -} - -/* Tell the remote machine to resume. */ - -void -bug_resume (ptid_t ptid, int step, enum target_signal sig) -{ - if (step) - { - sr_write_cr ("t"); - - /* Force the next bug_wait to return a trap. Not doing anything - about I/O from the target means that the user has to type - "continue" to see any. FIXME, this should be fixed. */ - need_artificial_trap = 1; - } - else - sr_write_cr ("g"); - - return; -} - -/* Wait until the remote machine stops, then return, - storing status in STATUS just as `wait' would. */ - -static char *wait_strings[] = -{ - "At Breakpoint", - "Exception: Data Access Fault (Local Bus Timeout)", - "\r8??\?-Bug>", /* The '\?' avoids creating a trigraph */ - "\r197-Bug>", - NULL, -}; - -ptid_t -bug_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int old_timeout = sr_get_timeout (); - int old_immediate_quit = immediate_quit; - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - /* read off leftovers from resume so that the rest can be passed - back out as stdout. */ - if (need_artificial_trap == 0) - { - sr_expect ("Effective address: "); - (void) sr_get_hex_word (); - sr_expect ("\r\n"); - } - - sr_set_timeout (-1); /* Don't time out -- user program is running. */ - immediate_quit = 1; /* Helps ability to QUIT */ - - switch (gr_multi_scan (wait_strings, need_artificial_trap == 0)) - { - case 0: /* breakpoint case */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - /* user output from the target can be discarded here. (?) */ - gr_expect_prompt (); - break; - - case 1: /* bus error */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_BUS; - /* user output from the target can be discarded here. (?) */ - gr_expect_prompt (); - break; - - case 2: /* normal case */ - case 3: - if (need_artificial_trap != 0) - { - /* stepping */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - need_artificial_trap--; - break; - } - else - { - /* exit case */ - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - break; - } - - case -1: /* trouble */ - default: - fprintf_filtered (gdb_stderr, - "Trouble reading target during wait\n"); - break; - } - - sr_set_timeout (old_timeout); - immediate_quit = old_immediate_quit; - return inferior_ptid; -} - -/* Return the name of register number REGNO - in the form input and output by bug. - - Returns a pointer to a static buffer containing the answer. */ -static char * -get_reg_name (int regno) -{ - static char *rn[] = - { - "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07", - "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - - /* these get confusing because we omit a few and switch some ordering around. */ - - "cr01", /* 32 = psr */ - "fcr62", /* 33 = fpsr */ - "fcr63", /* 34 = fpcr */ - "ip", /* this is something of a cheat. */ - /* 35 = sxip */ - "cr05", /* 36 = snip */ - "cr06", /* 37 = sfip */ - - "x00", "x01", "x02", "x03", "x04", "x05", "x06", "x07", - "x08", "x09", "x10", "x11", "x12", "x13", "x14", "x15", - "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", - "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", - }; - - return rn[regno]; -} - -#if 0 /* not currently used */ -/* Read from remote while the input matches STRING. Return zero on - success, -1 on failure. */ - -static int -bug_scan (char *s) -{ - int c; - - while (*s) - { - c = sr_readchar (); - if (c != *s++) - { - fflush (stdout); - printf ("\nNext character is '%c' - %d and s is \"%s\".\n", c, c, --s); - return (-1); - } - } - - return (0); -} -#endif /* never */ - -static int -bug_srec_write_cr (char *s) -{ - char *p = s; - - if (srec_echo_pace) - for (p = s; *p; ++p) - { - if (sr_get_debug () > 0) - printf ("%c", *p); - - do - serial_write (sr_get_desc (), p, 1); - while (sr_pollchar () != *p); - } - else - { - sr_write_cr (s); -/* return(bug_scan (s) || bug_scan ("\n")); */ - } - - return (0); -} - -/* Store register REGNO, or all if REGNO == -1. */ - -static void -bug_fetch_register (int regno) -{ - sr_check_open (); - - if (regno == -1) - { - int i; - - for (i = 0; i < NUM_REGS; ++i) - bug_fetch_register (i); - } - else if (target_is_m88110 && regno == SFIP_REGNUM) - { - /* m88110 has no sfip. */ - long l = 0; - supply_register (regno, (char *) &l); - } - else if (regno < XFP_REGNUM) - { - char buffer[MAX_REGISTER_RAW_SIZE]; - - sr_write ("rs ", 3); - sr_write_cr (get_reg_name (regno)); - sr_expect ("="); - store_unsigned_integer (buffer, REGISTER_RAW_SIZE (regno), - sr_get_hex_word ()); - gr_expect_prompt (); - supply_register (regno, buffer); - } - else - { - /* Float register so we need to parse a strange data format. */ - long p; - unsigned char fpreg_buf[10]; - - sr_write ("rs ", 3); - sr_write (get_reg_name (regno), strlen (get_reg_name (regno))); - sr_write_cr (";d"); - sr_expect ("rs"); - sr_expect (get_reg_name (regno)); - sr_expect (";d"); - sr_expect ("="); - - /* sign */ - p = sr_get_hex_digit (1); - fpreg_buf[0] = p << 7; - - /* exponent */ - sr_expect ("_"); - p = sr_get_hex_digit (1); - fpreg_buf[0] += (p << 4); - fpreg_buf[0] += sr_get_hex_digit (1); - - fpreg_buf[1] = sr_get_hex_digit (1) << 4; - - /* fraction */ - sr_expect ("_"); - fpreg_buf[1] += sr_get_hex_digit (1); - - fpreg_buf[2] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1); - fpreg_buf[3] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1); - fpreg_buf[4] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1); - fpreg_buf[5] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1); - fpreg_buf[6] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1); - fpreg_buf[7] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1); - fpreg_buf[8] = 0; - fpreg_buf[9] = 0; - - gr_expect_prompt (); - supply_register (regno, fpreg_buf); - } - - return; -} - -/* Store register REGNO, or all if REGNO == -1. */ - -static void -bug_store_register (int regno) -{ - char buffer[1024]; - sr_check_open (); - - if (regno == -1) - { - int i; - - for (i = 0; i < NUM_REGS; ++i) - bug_store_register (i); - } - else - { - char *regname; - - regname = get_reg_name (regno); - - if (target_is_m88110 && regno == SFIP_REGNUM) - return; - else if (regno < XFP_REGNUM) - sprintf (buffer, "rs %s %08lx", - regname, - (long) read_register (regno)); - else - { - unsigned char *fpreg_buf = - (unsigned char *) ®isters[REGISTER_BYTE (regno)]; - - sprintf (buffer, "rs %s %1x_%02x%1x_%1x%02x%02x%02x%02x%02x%02x;d", - regname, - /* sign */ - (fpreg_buf[0] >> 7) & 0xf, - /* exponent */ - fpreg_buf[0] & 0x7f, - (fpreg_buf[1] >> 8) & 0xf, - /* fraction */ - fpreg_buf[1] & 0xf, - fpreg_buf[2], - fpreg_buf[3], - fpreg_buf[4], - fpreg_buf[5], - fpreg_buf[6], - fpreg_buf[7]); - } - - sr_write_cr (buffer); - gr_expect_prompt (); - } - - return; -} - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If WRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - Returns the number of bytes transferred. */ - -int -bug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, struct target_ops *target) -{ - int res; - - if (len <= 0) - return 0; - - if (write) - res = bug_write_memory (memaddr, myaddr, len); - else - res = bug_read_memory (memaddr, myaddr, len); - - return res; -} - -static void -start_load (void) -{ - char *command; - - command = (srec_echo_pace ? "lo 0 ;x" : "lo 0"); - - sr_write_cr (command); - sr_expect (command); - sr_expect ("\r\n"); - bug_srec_write_cr ("S0030000FC"); - return; -} - -/* This is an extremely vulnerable and fragile function. I've made - considerable attempts to make this deterministic, but I've - certainly forgotten something. The trouble is that S-records are - only a partial file format, not a protocol. Worse, apparently the - m88k bug monitor does not run in real time while receiving - S-records. Hence, we must pay excruciating attention to when and - where error messages are returned, and what has actually been sent. - - Each call represents a chunk of memory to be sent to the target. - We break that chunk into an S0 header record, some number of S3 - data records each containing srec_bytes, and an S7 termination - record. */ - -static char *srecord_strings[] = -{ - "S-RECORD", - "-Bug>", - NULL, -}; - -static int -bug_write_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - int done; - int checksum; - int x; - int retries; - char *buffer = alloca ((srec_bytes + 8) << 1); - - retries = 0; - - do - { - done = 0; - - if (retries > srec_max_retries) - return (-1); - - if (retries > 0) - { - if (sr_get_debug () > 0) - printf ("\n\n"); - - /* This gr_expect_prompt call is extremely important. Without - it, we will tend to resend our packet so fast that it - will arrive before the bug monitor is ready to receive - it. This would lead to a very ugly resend loop. */ - - gr_expect_prompt (); - } - - start_load (); - - while (done < len) - { - int thisgo; - int idx; - char *buf = buffer; - CORE_ADDR address; - - checksum = 0; - thisgo = len - done; - if (thisgo > srec_bytes) - thisgo = srec_bytes; - - address = memaddr + done; - sprintf (buf, "S3%02X%08lX", thisgo + 4 + 1, (long) address); - buf += 12; - - checksum += (thisgo + 4 + 1 - + (address & 0xff) - + ((address >> 8) & 0xff) - + ((address >> 16) & 0xff) - + ((address >> 24) & 0xff)); - - for (idx = 0; idx < thisgo; idx++) - { - sprintf (buf, "%02X", myaddr[idx + done]); - checksum += myaddr[idx + done]; - buf += 2; - } - - if (srec_noise > 0) - { - /* FIXME-NOW: insert a deliberate error every now and then. - This is intended for testing/debugging the error handling - stuff. */ - static int counter = 0; - if (++counter > srec_noise) - { - counter = 0; - ++checksum; - } - } - - sprintf (buf, "%02X", ~checksum & 0xff); - bug_srec_write_cr (buffer); - - if (srec_sleep != 0) - sleep (srec_sleep); - - /* This pollchar is probably redundant to the gr_multi_scan - below. Trouble is, we can't be sure when or where an - error message will appear. Apparently, when running at - full speed from a typical sun4, error messages tend to - appear to arrive only *after* the s7 record. */ - - if ((x = sr_pollchar ()) != 0) - { - if (sr_get_debug () > 0) - printf ("\n\n"); - - ++retries; - - /* flush any remaining input and verify that we are back - at the prompt level. */ - gr_expect_prompt (); - /* start all over again. */ - start_load (); - done = 0; - continue; - } - - done += thisgo; - } - - bug_srec_write_cr ("S7060000000000F9"); - ++retries; - - /* Having finished the load, we need to figure out whether we - had any errors. */ - } - while (gr_multi_scan (srecord_strings, 0) == 0);; - - return (0); -} - -/* Copy LEN bytes of data from debugger memory at MYADDR - to inferior's memory at MEMADDR. Returns errno value. - * sb/sh instructions don't work on unaligned addresses, when TU=1. - */ - -/* Read LEN bytes from inferior memory at MEMADDR. Put the result - at debugger address MYADDR. Returns errno value. */ -static int -bug_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - char request[100]; - char *buffer; - char *p; - char type; - char size; - unsigned char c; - unsigned int inaddr; - unsigned int checksum; - - sprintf (request, "du 0 %lx:&%d", (long) memaddr, len); - sr_write_cr (request); - - p = buffer = alloca (len); - - /* scan up through the header */ - sr_expect ("S0030000FC"); - - while (p < buffer + len) - { - /* scan off any white space. */ - while (sr_readchar () != 'S');; - - /* what kind of s-rec? */ - type = sr_readchar (); - - /* scan record size */ - sr_get_hex_byte (&size); - checksum = size; - --size; - inaddr = 0; - - switch (type) - { - case '7': - case '8': - case '9': - goto done; - - case '3': - sr_get_hex_byte (&c); - inaddr = (inaddr << 8) + c; - checksum += c; - --size; - /* intentional fall through */ - case '2': - sr_get_hex_byte (&c); - inaddr = (inaddr << 8) + c; - checksum += c; - --size; - /* intentional fall through */ - case '1': - sr_get_hex_byte (&c); - inaddr = (inaddr << 8) + c; - checksum += c; - --size; - sr_get_hex_byte (&c); - inaddr = (inaddr << 8) + c; - checksum += c; - --size; - break; - - default: - /* bonk */ - error ("reading s-records."); - } - - if (inaddr < memaddr - || (memaddr + len) < (inaddr + size)) - error ("srec out of memory range."); - - if (p != buffer + inaddr - memaddr) - error ("srec out of sequence."); - - for (; size; --size, ++p) - { - sr_get_hex_byte (p); - checksum += *p; - } - - sr_get_hex_byte (&c); - if (c != (~checksum & 0xff)) - error ("bad s-rec checksum"); - } - -done: - gr_expect_prompt (); - if (p != buffer + len) - return (1); - - memcpy (myaddr, buffer, len); - return (0); -} - -#define MAX_BREAKS 16 -static int num_brkpts = 0; - -/* Insert a breakpoint at ADDR. SAVE is normally the address of the - pattern buffer where the instruction that the breakpoint overwrites - is saved. It is unused here since the bug is responsible for - saving/restoring the original instruction. */ - -static int -bug_insert_breakpoint (CORE_ADDR addr, char *save) -{ - sr_check_open (); - - if (num_brkpts < MAX_BREAKS) - { - char buffer[100]; - - num_brkpts++; - sprintf (buffer, "br %lx", (long) addr); - sr_write_cr (buffer); - gr_expect_prompt (); - return (0); - } - else - { - fprintf_filtered (gdb_stderr, - "Too many break points, break point not installed\n"); - return (1); - } - -} - -/* Remove a breakpoint at ADDR. SAVE is normally the previously - saved pattern, but is unused here since the bug is responsible - for saving/restoring instructions. */ - -static int -bug_remove_breakpoint (CORE_ADDR addr, char *save) -{ - if (num_brkpts > 0) - { - char buffer[100]; - - num_brkpts--; - sprintf (buffer, "nobr %lx", (long) addr); - sr_write_cr (buffer); - gr_expect_prompt (); - - } - return (0); -} - -/* Clear the bugs notion of what the break points are */ -static int -bug_clear_breakpoints (void) -{ - - if (sr_is_open ()) - { - sr_write_cr ("nobr"); - sr_expect ("nobr"); - gr_expect_prompt (); - } - num_brkpts = 0; - return (0); -} - -struct target_ops bug_ops; - -static void -init_bug_ops (void) -{ - bug_ops.to_shortname = "bug"; - "Remote BUG monitor", - bug_ops.to_longname = "Use the mvme187 board running the BUG monitor connected by a serial line."; - bug_ops.to_doc = " "; - bug_ops.to_open = bug_open; - bug_ops.to_close = gr_close; - bug_ops.to_attach = 0; - bug_ops.to_post_attach = NULL; - bug_ops.to_require_attach = NULL; - bug_ops.to_detach = gr_detach; - bug_ops.to_require_detach = NULL; - bug_ops.to_resume = bug_resume; - bug_ops.to_wait = bug_wait; - bug_ops.to_post_wait = NULL; - bug_ops.to_fetch_registers = bug_fetch_register; - bug_ops.to_store_registers = bug_store_register; - bug_ops.to_prepare_to_store = gr_prepare_to_store; - bug_ops.to_xfer_memory = bug_xfer_memory; - bug_ops.to_files_info = gr_files_info; - bug_ops.to_insert_breakpoint = bug_insert_breakpoint; - bug_ops.to_remove_breakpoint = bug_remove_breakpoint; - bug_ops.to_terminal_init = 0; - bug_ops.to_terminal_inferior = 0; - bug_ops.to_terminal_ours_for_output = 0; - bug_ops.to_terminal_ours = 0; - bug_ops.to_terminal_info = 0; - bug_ops.to_kill = gr_kill; - bug_ops.to_load = bug_load; - bug_ops.to_lookup_symbol = 0; - bug_ops.to_create_inferior = gr_create_inferior; - bug_ops.to_post_startup_inferior = NULL; - bug_ops.to_acknowledge_created_inferior = NULL; - bug_ops.to_clone_and_follow_inferior = NULL; - bug_ops.to_post_follow_inferior_by_clone = NULL; - bug_ops.to_insert_fork_catchpoint = NULL; - bug_ops.to_remove_fork_catchpoint = NULL; - bug_ops.to_insert_vfork_catchpoint = NULL; - bug_ops.to_remove_vfork_catchpoint = NULL; - bug_ops.to_has_forked = NULL; - bug_ops.to_has_vforked = NULL; - bug_ops.to_can_follow_vfork_prior_to_exec = NULL; - bug_ops.to_post_follow_vfork = NULL; - bug_ops.to_insert_exec_catchpoint = NULL; - bug_ops.to_remove_exec_catchpoint = NULL; - bug_ops.to_has_execd = NULL; - bug_ops.to_reported_exec_events_per_exec_call = NULL; - bug_ops.to_has_exited = NULL; - bug_ops.to_mourn_inferior = gr_mourn; - bug_ops.to_can_run = 0; - bug_ops.to_notice_signals = 0; - bug_ops.to_thread_alive = 0; - bug_ops.to_stop = 0; - bug_ops.to_pid_to_exec_file = NULL; - bug_ops.to_stratum = process_stratum; - bug_ops.DONT_USE = 0; - bug_ops.to_has_all_memory = 1; - bug_ops.to_has_memory = 1; - bug_ops.to_has_stack = 1; - bug_ops.to_has_registers = 0; - bug_ops.to_has_execution = 0; - bug_ops.to_sections = 0; - bug_ops.to_sections_end = 0; - bug_ops.to_magic = OPS_MAGIC; /* Always the last thing */ -} /* init_bug_ops */ - -void -_initialize_remote_bug (void) -{ - init_bug_ops (); - add_target (&bug_ops); - - add_show_from_set - (add_set_cmd ("srec-bytes", class_support, var_uinteger, - (char *) &srec_bytes, - "\ -Set the number of bytes represented in each S-record.\n\ -This affects the communication protocol with the remote target.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("srec-max-retries", class_support, var_uinteger, - (char *) &srec_max_retries, - "\ -Set the number of retries for shipping S-records.\n\ -This affects the communication protocol with the remote target.", - &setlist), - &showlist); - -#if 0 - /* This needs to set SREC_SIZE, not srec_frame which gets changed at the - end of a download. But do we need the option at all? */ - add_show_from_set - (add_set_cmd ("srec-frame", class_support, var_uinteger, - (char *) &srec_frame, - "\ -Set the number of bytes in an S-record frame.\n\ -This affects the communication protocol with the remote target.", - &setlist), - &showlist); -#endif /* 0 */ - - add_show_from_set - (add_set_cmd ("srec-noise", class_support, var_zinteger, - (char *) &srec_noise, - "\ -Set number of S-record to send before deliberately flubbing a checksum.\n\ -Zero means flub none at all. This affects the communication protocol\n\ -with the remote target.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("srec-sleep", class_support, var_zinteger, - (char *) &srec_sleep, - "\ -Set number of seconds to sleep after an S-record for a possible error message to arrive.\n\ -This affects the communication protocol with the remote target.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("srec-echo-pace", class_support, var_boolean, - (char *) &srec_echo_pace, - "\ -Set echo-verification.\n\ -When on, use verification by echo when downloading S-records. This is\n\ -much slower, but generally more reliable.", - &setlist), - &showlist); -} diff --git a/contrib/gdb/gdb/remote-d10v.c b/contrib/gdb/gdb/remote-d10v.c deleted file mode 100644 index d529b2180f6..00000000000 --- a/contrib/gdb/gdb/remote-d10v.c +++ /dev/null @@ -1,228 +0,0 @@ -/* Remote target communications for d10v connected via a serial line. - Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free - Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdb_string.h" -#include -#include "frame.h" -#include "inferior.h" -#include "bfd.h" -#include "symfile.h" -#include "target.h" -#include "wait.h" -/*#include "terminal.h"*/ -#include "gdbcmd.h" -#include "objfiles.h" -#include "gdb-stabs.h" -#include "gdbthread.h" - -#include "dcache.h" - -#ifdef USG -#include -#endif - -#include -#include "serial.h" - -/* Prototypes for local functions */ - -static void remote_d10v_open PARAMS ((char *name, int from_tty)); - -/* Define the target subroutine names */ -static struct target_ops remote_d10v_ops; - -/* Open a connection to a remote debugger. - NAME is the filename used for communication. */ - -static void -remote_d10v_open (name, from_tty) - char *name; - int from_tty; -{ - pop_target (); - push_remote_target (name, from_tty); -} - - -/* Translate a GDB virtual ADDR/LEN into a format the remote target - understands. Returns number of bytes that can be transfered - starting at taddr, ZERO if no bytes can be transfered. */ -int -remote_d10v_translate_xfer_address (memaddr, nr_bytes, taddr) - CORE_ADDR memaddr; - int nr_bytes; - CORE_ADDR *taddr; -{ - CORE_ADDR phys; - CORE_ADDR seg; - CORE_ADDR off; - char *from = "unknown"; - char *to = "unknown"; - unsigned short imap0 = read_register (IMAP0_REGNUM); - unsigned short imap1 = read_register (IMAP1_REGNUM); - unsigned short dmap = read_register (DMAP_REGNUM); - - /* GDB interprets addresses as: - - 0x00xxxxxx: Logical data address segment (DMAP translated memory) - 0x01xxxxxx: Logical instruction address segment (IMAP translated memory) - 0x10xxxxxx: Physical data memory segment (On-chip data memory) - 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory) - 0x12xxxxxx: Phisical unified memory segment (Unified memory) - - The remote d10v board interprets addresses as: - - 0x00xxxxxx: Phisical unified memory segment (Unified memory) - 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) - 0x02xxxxxx: Physical data memory segment (On-chip data memory) - - Translate according to current IMAP/dmap registers */ - - enum { - targ_unified = 0x00000000, - targ_insn = 0x01000000, - targ_data = 0x02000000, - }; - - seg = (memaddr >> 24); - off = (memaddr & 0xffffffL); - - switch (seg) - { - case 0x00: /* in logical data address segment */ - { - from = "logical-data"; - if (off <= 0x7fffL) - { - /* On chip data */ - phys = targ_data + off; - if (off + nr_bytes > 0x7fffL) - /* don't cross VM boundary */ - nr_bytes = 0x7fffL - off + 1; - to = "chip-data"; - } - else if (off <= 0xbfffL) - { - short map = dmap; - if (map & 0x1000) - { - /* Instruction memory */ - phys = targ_insn | ((map & 0xf) << 14) | (off & 0x3fff); - to = "chip-insn"; - } - else - { - /* Unified memory */ - phys = targ_unified | ((map & 0x3ff) << 14) | (off & 0x3fff); - to = "unified"; - } - if (off + nr_bytes > 0xbfffL) - /* don't cross VM boundary */ - nr_bytes = (0xbfffL - off + 1); - } - else - { - /* Logical address out side of data segments, not supported */ - return (0); - } - break; - } - - case 0x01: /* in logical instruction address segment */ - { - short map; - from = "logical-insn"; - if (off <= 0x1ffffL) - { - map = imap0; - } - else if (off <= 0x3ffffL) - { - map = imap1; - } - else - { - /* Logical address outside of IMAP[01] segment, not - supported */ - return (0); - } - if ((off & 0x1ffff) + nr_bytes > 0x1ffffL) - { - /* don't cross VM boundary */ - nr_bytes = 0x1ffffL - (off & 0x1ffffL) + 1; - } - if (map & 0x1000) - /* Instruction memory */ - { - phys = targ_insn | off; - to = "chip-insn"; - } - else - { - phys = ((map & 0x7fL) << 17) + (off & 0x1ffffL); - if (phys > 0xffffffL) - /* Address outside of unified address segment */ - return (0); - phys |= targ_unified; - to = "unified"; - } - break; - } - - case 0x10: /* Physical data memory segment */ - from = "phys-data"; - phys = targ_data | off; - to = "chip-data"; - break; - - case 0x11: /* Physical instruction memory */ - from = "phys-insn"; - phys = targ_insn | off; - to = "chip-insn"; - break; - - case 0x12: /* Physical unified memory */ - from = "phys-unified"; - phys = targ_unified | off; - to = "unified"; - break; - - default: - return (0); - } - - - *taddr = phys; - return nr_bytes; -} - - -void -_initialize_remote_d10v () -{ - remote_d10v_ops.to_shortname = "d10v"; - remote_d10v_ops.to_longname = "Remote d10v serial target in gdb-specific protocol"; - remote_d10v_ops.to_doc = "Use a remote d10v via a serial line, using a gdb-specific protocol.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - remote_d10v_ops.to_open = remote_d10v_open; - - add_target (&remote_d10v_ops); -} diff --git a/contrib/gdb/gdb/remote-e7000.c b/contrib/gdb/gdb/remote-e7000.c deleted file mode 100644 index dee664d8736..00000000000 --- a/contrib/gdb/gdb/remote-e7000.c +++ /dev/null @@ -1,2227 +0,0 @@ -/* Remote debugging interface for Hitachi E7000 ICE, for GDB - - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation, Inc. - - Contributed by Cygnus Support. - - Written by Steve Chamberlain for Cygnus Support. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* The E7000 is an in-circuit emulator for the Hitachi H8/300-H and - Hitachi-SH processor. It has serial port and a lan port. - - The monitor command set makes it difficult to load large ammounts of - data over the lan without using ftp - so try not to issue load - commands when communicating over ethernet; use the ftpload command. - - The monitor pauses for a second when dumping srecords to the serial - line too, so we use a slower per byte mechanism but without the - startup overhead. Even so, it's pretty slow... */ - -#include "defs.h" -#include "gdbcore.h" -#include "gdbarch.h" -#include "inferior.h" -#include "target.h" -#include "value.h" -#include "command.h" -#include "gdb_string.h" -#include "gdbcmd.h" -#include -#include "serial.h" -#include "remote-utils.h" -#include "symfile.h" -#include "regcache.h" -#include -#include - - -#if 1 -#define HARD_BREAKPOINTS /* Now handled by set option. */ -#define BC_BREAKPOINTS use_hard_breakpoints -#endif - -#define CTRLC 0x03 -#define ENQ 0x05 -#define ACK 0x06 -#define CTRLZ 0x1a - -/* This file is used by 2 different targets, sh-elf and h8300. The - h8300 is not multiarched and doesn't use the registers defined in - tm-sh.h. To avoid using a macro GDB_TARGET_IS_SH, we do runtime check - of the target, which requires that these namse below are always - defined also in the h8300 case. */ - -#if !defined (PR_REGNUM) -#define PR_REGNUM -1 -#endif -#if !defined (GBR_REGNUM) -#define GBR_REGNUM -1 -#endif -#if !defined (VBR_REGNUM) -#define VBR_REGNUM -1 -#endif -#if !defined (MACH_REGNUM) -#define MACH_REGNUM -1 -#endif -#if !defined (MACL_REGNUM) -#define MACL_REGNUM -1 -#endif -#if !defined (SR_REGNUM) -#define SR_REGNUM -1 -#endif - -extern void report_transfer_performance (unsigned long, time_t, time_t); - -extern char *sh_processor_type; - -/* Local function declarations. */ - -static void e7000_close (int); - -static void e7000_fetch_register (int); - -static void e7000_store_register (int); - -static void e7000_command (char *, int); - -static void e7000_login_command (char *, int); - -static void e7000_ftp_command (char *, int); - -static void e7000_drain_command (char *, int); - -static void expect (char *); - -static void expect_full_prompt (void); - -static void expect_prompt (void); - -static int e7000_parse_device (char *args, char *dev_name, int baudrate); -/* Variables. */ - -static struct serial *e7000_desc; - -/* Allow user to chose between using hardware breakpoints or memory. */ -static int use_hard_breakpoints = 0; /* use sw breakpoints by default */ - -/* Nonzero if using the tcp serial driver. */ - -static int using_tcp; /* direct tcp connection to target */ -static int using_tcp_remote; /* indirect connection to target - via tcp to controller */ - -/* Nonzero if using the pc isa card. */ - -static int using_pc; - -extern struct target_ops e7000_ops; /* Forward declaration */ - -char *ENQSTRING = "\005"; - -/* Nonzero if some routine (as opposed to the user) wants echoing. - FIXME: Do this reentrantly with an extra parameter. */ - -static int echo; - -static int ctrl_c; - -static int timeout = 20; - -/* Send data to e7000debug. */ - -static void -puts_e7000debug (char *buf) -{ - if (!e7000_desc) - error ("Use \"target e7000 ...\" first."); - - if (remote_debug) - printf_unfiltered ("Sending %s\n", buf); - - if (serial_write (e7000_desc, buf, strlen (buf))) - fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n", safe_strerror (errno)); - - /* And expect to see it echoed, unless using the pc interface */ -#if 0 - if (!using_pc) -#endif - expect (buf); -} - -static void -putchar_e7000 (int x) -{ - char b[1]; - - b[0] = x; - serial_write (e7000_desc, b, 1); -} - -static void -write_e7000 (char *s) -{ - serial_write (e7000_desc, s, strlen (s)); -} - -static int -normal (int x) -{ - if (x == '\n') - return '\r'; - return x; -} - -/* Read a character from the remote system, doing all the fancy timeout - stuff. Handles serial errors and EOF. If TIMEOUT == 0, and no chars, - returns -1, else returns next char. Discards chars > 127. */ - -static int -readchar (int timeout) -{ - int c; - - do - { - c = serial_readchar (e7000_desc, timeout); - } - while (c > 127); - - if (c == SERIAL_TIMEOUT) - { - if (timeout == 0) - return -1; - echo = 0; - error ("Timeout reading from remote system."); - } - else if (c < 0) - error ("Serial communication error"); - - if (remote_debug) - { - putchar_unfiltered (c); - gdb_flush (gdb_stdout); - } - - return normal (c); -} - -#if 0 -char * -tl (int x) -{ - static char b[8][10]; - static int p; - - p++; - p &= 7; - if (x >= ' ') - { - b[p][0] = x; - b[p][1] = 0; - } - else - { - sprintf (b[p], "<%d>", x); - } - - return b[p]; -} -#endif - -/* Scan input from the remote system, until STRING is found. If - DISCARD is non-zero, then discard non-matching input, else print it - out. Let the user break out immediately. */ - -static void -expect (char *string) -{ - char *p = string; - int c; - int nl = 0; - - while (1) - { - c = readchar (timeout); - - if (echo) - { - if (c == '\r' || c == '\n') - { - if (!nl) - putchar_unfiltered ('\n'); - nl = 1; - } - else - { - nl = 0; - putchar_unfiltered (c); - } - gdb_flush (gdb_stdout); - } - if (normal (c) == normal (*p++)) - { - if (*p == '\0') - return; - } - else - { - p = string; - - if (normal (c) == normal (string[0])) - p++; - } - } -} - -/* Keep discarding input until we see the e7000 prompt. - - The convention for dealing with the prompt is that you - o give your command - o *then* wait for the prompt. - - Thus the last thing that a procedure does with the serial line will - be an expect_prompt(). Exception: e7000_resume does not wait for - the prompt, because the terminal is being handed over to the - inferior. However, the next thing which happens after that is a - e7000_wait which does wait for the prompt. Note that this includes - abnormal exit, e.g. error(). This is necessary to prevent getting - into states from which we can't recover. */ - -static void -expect_prompt (void) -{ - expect (":"); -} - -static void -expect_full_prompt (void) -{ - expect ("\r:"); -} - -static int -convert_hex_digit (int ch) -{ - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - return -1; -} - -static int -get_hex (int *start) -{ - int value = convert_hex_digit (*start); - int try; - - *start = readchar (timeout); - while ((try = convert_hex_digit (*start)) >= 0) - { - value <<= 4; - value += try; - *start = readchar (timeout); - } - return value; -} - -#if 0 -/* Get N 32-bit words from remote, each preceded by a space, and put - them in registers starting at REGNO. */ - -static void -get_hex_regs (int n, int regno) -{ - long val; - int i; - - for (i = 0; i < n; i++) - { - int j; - - val = 0; - for (j = 0; j < 8; j++) - val = (val << 4) + get_hex_digit (j == 0); - supply_register (regno++, (char *) &val); - } -} -#endif - -/* This is called not only when we first attach, but also when the - user types "run" after having attached. */ - -static void -e7000_create_inferior (char *execfile, char *args, char **env) -{ - int entry_pt; - - if (args && *args) - error ("Can't pass arguments to remote E7000DEBUG process"); - - if (execfile == 0 || exec_bfd == 0) - error ("No executable file specified"); - - entry_pt = (int) bfd_get_start_address (exec_bfd); - -#ifdef CREATE_INFERIOR_HOOK - CREATE_INFERIOR_HOOK (0); /* No process-ID */ -#endif - - /* The "process" (board) is already stopped awaiting our commands, and - the program is already downloaded. We just set its PC and go. */ - - clear_proceed_status (); - - /* Tell wait_for_inferior that we've started a new process. */ - init_wait_for_inferior (); - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - target_terminal_init (); - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - /* insert_step_breakpoint (); FIXME, do we need this? */ - proceed ((CORE_ADDR) entry_pt, -1, 0); /* Let 'er rip... */ -} - -/* Open a connection to a remote debugger. NAME is the filename used - for communication. */ - -static int baudrate = 9600; -static char dev_name[100]; - -static char *machine = ""; -static char *user = ""; -static char *passwd = ""; -static char *dir = ""; - -/* Grab the next token and buy some space for it */ - -static char * -next (char **ptr) -{ - char *p = *ptr; - char *s; - char *r; - int l = 0; - - while (*p && *p == ' ') - p++; - s = p; - while (*p && (*p != ' ' && *p != '\t')) - { - l++; - p++; - } - r = xmalloc (l + 1); - memcpy (r, s, l); - r[l] = 0; - *ptr = p; - return r; -} - -static void -e7000_login_command (char *args, int from_tty) -{ - if (args) - { - machine = next (&args); - user = next (&args); - passwd = next (&args); - dir = next (&args); - if (from_tty) - { - printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir); - } - } - else - { - error ("Syntax is ftplogin "); - } -} - -/* Start an ftp transfer from the E7000 to a host */ - -static void -e7000_ftp_command (char *args, int from_tty) -{ - /* FIXME: arbitrary limit on machine names and such. */ - char buf[200]; - - int oldtimeout = timeout; - timeout = remote_timeout; - - sprintf (buf, "ftp %s\r", machine); - puts_e7000debug (buf); - expect (" Username : "); - sprintf (buf, "%s\r", user); - puts_e7000debug (buf); - expect (" Password : "); - write_e7000 (passwd); - write_e7000 ("\r"); - expect ("success\r"); - expect ("FTP>"); - sprintf (buf, "cd %s\r", dir); - puts_e7000debug (buf); - expect ("FTP>"); - sprintf (buf, "ll 0;s:%s\r", args); - puts_e7000debug (buf); - expect ("FTP>"); - puts_e7000debug ("bye\r"); - expect (":"); - timeout = oldtimeout; -} - -static int -e7000_parse_device (char *args, char *dev_name, int baudrate) -{ - char junk[128]; - int n = 0; - if (args && strcasecmp (args, "pc") == 0) - { - strcpy (dev_name, args); - using_pc = 1; - } - else - { - /* FIXME! temp hack to allow use with port master - - target tcp_remote */ - if (args && strncmp (args, "tcp", 10) == 0) - { - char com_type[128]; - n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk); - using_tcp_remote = 1; - n--; - } - else if (args) - { - n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk); - } - - if (n != 1 && n != 2) - { - error ("Bad arguments. Usage:\ttarget e7000 \n\ -or \t\ttarget e7000 [:]\n\ -or \t\ttarget e7000 tcp_remote [:]\n\ -or \t\ttarget e7000 pc\n"); - } - -#if !defined(__GO32__) && !defined(_WIN32) && !defined(__CYGWIN__) - /* FIXME! test for ':' is ambiguous */ - if (n == 1 && strchr (dev_name, ':') == 0) - { - /* Default to normal telnet port */ - /* serial_open will use this to determine tcp communication */ - strcat (dev_name, ":23"); - } -#endif - if (!using_tcp_remote && strchr (dev_name, ':')) - using_tcp = 1; - } - - return n; -} - -/* Stub for catch_errors. */ - -static int -e7000_start_remote (void *dummy) -{ - int loop; - int sync; - int try; - int quit_trying; - - immediate_quit++; /* Allow user to interrupt it */ - - /* Hello? Are you there? */ - sync = 0; - loop = 0; - try = 0; - quit_trying = 20; - putchar_e7000 (CTRLC); - while (!sync && ++try <= quit_trying) - { - int c; - - printf_unfiltered ("[waiting for e7000...]\n"); - - write_e7000 ("\r"); - c = readchar (1); - - /* FIXME! this didn't seem right-> while (c != SERIAL_TIMEOUT) - * we get stuck in this loop ... - * We may never timeout, and never sync up :-( - */ - while (!sync && c != -1) - { - /* Dont echo cr's */ - if (c != '\r') - { - putchar_unfiltered (c); - gdb_flush (gdb_stdout); - } - /* Shouldn't we either break here, or check for sync in inner loop? */ - if (c == ':') - sync = 1; - - if (loop++ == 20) - { - putchar_e7000 (CTRLC); - loop = 0; - } - - QUIT; - - if (quit_flag) - { - putchar_e7000 (CTRLC); - /* Was-> quit_flag = 0; */ - c = -1; - quit_trying = try + 1; /* we don't want to try anymore */ - } - else - { - c = readchar (1); - } - } - } - - if (!sync) - { - fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n", try); - error ("Unable to synchronize with target.\n"); - } - - puts_e7000debug ("\r"); - expect_prompt (); - puts_e7000debug ("b -\r"); /* Clear breakpoints */ - expect_prompt (); - - immediate_quit--; - -/* This is really the job of start_remote however, that makes an assumption - that the target is about to print out a status message of some sort. That - doesn't happen here. */ - - flush_cached_frames (); - registers_changed (); - stop_pc = read_pc (); - set_current_frame (create_new_frame (read_fp (), stop_pc)); - select_frame (get_current_frame (), 0); - print_stack_frame (selected_frame, -1, 1); - - return 1; -} - -static void -e7000_open (char *args, int from_tty) -{ - int n; - - target_preopen (from_tty); - - n = e7000_parse_device (args, dev_name, baudrate); - - push_target (&e7000_ops); - - e7000_desc = serial_open (dev_name); - - if (!e7000_desc) - perror_with_name (dev_name); - - if (serial_setbaudrate (e7000_desc, baudrate)) - { - serial_close (e7000_desc); - perror_with_name (dev_name); - } - serial_raw (e7000_desc); - -#ifdef GDB_TARGET_IS_H8300 - h8300hmode = 1; -#endif - - /* Start the remote connection; if error (0), discard this target. - In particular, if the user quits, be sure to discard it - (we'd be in an inconsistent state otherwise). */ - if (!catch_errors (e7000_start_remote, (char *) 0, - "Couldn't establish connection to remote target\n", RETURN_MASK_ALL)) - if (from_tty) - printf_filtered ("Remote target %s connected to %s\n", target_shortname, - dev_name); -} - -/* Close out all files and local state before this target loses control. */ - -static void -e7000_close (int quitting) -{ - if (e7000_desc) - { - serial_close (e7000_desc); - e7000_desc = 0; - } -} - -/* Terminate the open connection to the remote debugger. Use this - when you want to detach and do something else with your gdb. */ - -static void -e7000_detach (char *arg, int from_tty) -{ - pop_target (); /* calls e7000_close to do the real work */ - if (from_tty) - printf_unfiltered ("Ending remote %s debugging\n", target_shortname); -} - -/* Tell the remote machine to resume. */ - -static void -e7000_resume (ptid_t ptid, int step, enum target_signal sigal) -{ - if (step) - puts_e7000debug ("S\r"); - else - puts_e7000debug ("G\r"); -} - -/* Read the remote registers into the block REGS. - - For the H8/300 a register dump looks like: - - PC=00021A CCR=80:I******* - ER0 - ER3 0000000A 0000002E 0000002E 00000000 - ER4 - ER7 00000000 00000000 00000000 00FFEFF6 - 000218 MOV.B R1L,R2L - STEP NORMAL END or - BREAK POINT - */ - -char *want_h8300h = "PC=%p CCR=%c\n\ - ER0 - ER3 %0 %1 %2 %3\n\ - ER4 - ER7 %4 %5 %6 %7\n"; - -char *want_nopc_h8300h = "%p CCR=%c\n\ - ER0 - ER3 %0 %1 %2 %3\n\ - ER4 - ER7 %4 %5 %6 %7"; - -char *want_h8300s = "PC=%p CCR=%c\n\ - MACH=\n\ - ER0 - ER3 %0 %1 %2 %3\n\ - ER4 - ER7 %4 %5 %6 %7\n"; - -char *want_nopc_h8300s = "%p CCR=%c EXR=%9\n\ - ER0 - ER3 %0 %1 %2 %3\n\ - ER4 - ER7 %4 %5 %6 %7"; - -char *want_sh = "PC=%16 SR=%22\n\ -PR=%17 GBR=%18 VBR=%19\n\ -MACH=%20 MACL=%21\n\ -R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ -R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n"; - -char *want_nopc_sh = "%16 SR=%22\n\ - PR=%17 GBR=%18 VBR=%19\n\ - MACH=%20 MACL=%21\n\ - R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ - R8-15 %8 %9 %10 %11 %12 %13 %14 %15"; - -char *want_sh3 = "PC=%16 SR=%22\n\ -PR=%17 GBR=%18 VBR=%19\n\ -MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\ -R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ -R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\ -R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\ -R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\ -R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\ -R4_BANK1-R7_BANK1 %37 %38 %39 %40"; - -char *want_nopc_sh3 = "%16 SR=%22\n\ - PR=%17 GBR=%18 VBR=%19\n\ - MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\ - R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ - R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\ - R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\ - R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\ - R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\ - R4_BANK1-R7_BANK1 %37 %38 %39 %40"; - -static int -gch (void) -{ - return readchar (timeout); -} - -static unsigned int -gbyte (void) -{ - int high = convert_hex_digit (gch ()); - int low = convert_hex_digit (gch ()); - - return (high << 4) + low; -} - -void -fetch_regs_from_dump (int (*nextchar) (), char *want) -{ - int regno; - char buf[MAX_REGISTER_RAW_SIZE]; - - int thischar = nextchar (); - - if (want == NULL) - internal_error (__FILE__, __LINE__, "Register set not selected."); - - while (*want) - { - switch (*want) - { - case '\n': - /* Skip to end of line and then eat all new line type stuff */ - while (thischar != '\n' && thischar != '\r') - thischar = nextchar (); - while (thischar == '\n' || thischar == '\r') - thischar = nextchar (); - want++; - break; - - case ' ': - while (thischar == ' ' - || thischar == '\t' - || thischar == '\r' - || thischar == '\n') - thischar = nextchar (); - want++; - break; - - default: - if (*want == thischar) - { - want++; - if (*want) - thischar = nextchar (); - - } - else if (thischar == ' ' || thischar == '\n' || thischar == '\r') - { - thischar = nextchar (); - } - else - { - error ("out of sync in fetch registers wanted <%s>, got <%c 0x%x>", - want, thischar, thischar); - } - - break; - case '%': - /* Got a register command */ - want++; - switch (*want) - { -#ifdef PC_REGNUM - case 'p': - regno = PC_REGNUM; - want++; - break; -#endif -#ifdef CCR_REGNUM - case 'c': - regno = CCR_REGNUM; - want++; - break; -#endif -#ifdef SP_REGNUM - case 's': - regno = SP_REGNUM; - want++; - break; -#endif -#ifdef FP_REGNUM - case 'f': - regno = FP_REGNUM; - want++; - break; -#endif - - default: - if (isdigit (want[0])) - { - if (isdigit (want[1])) - { - regno = (want[0] - '0') * 10 + want[1] - '0'; - want += 2; - } - else - { - regno = want[0] - '0'; - want++; - } - } - - else - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } - store_signed_integer (buf, - REGISTER_RAW_SIZE (regno), - (LONGEST) get_hex (&thischar)); - supply_register (regno, buf); - break; - } - } -} - -static void -e7000_fetch_registers (void) -{ - int regno; - char *wanted = NULL; - - puts_e7000debug ("R\r"); - - if (TARGET_ARCHITECTURE->arch == bfd_arch_sh) - { - wanted = want_sh; - switch (TARGET_ARCHITECTURE->mach) - { - case bfd_mach_sh3: - case bfd_mach_sh3e: - case bfd_mach_sh4: - wanted = want_sh3; - } - } -#ifdef GDB_TARGET_IS_H8300 - if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300) - { - if (h8300smode) - wanted = want_h8300s; - else - wanted = want_h8300h; - } -#endif - - fetch_regs_from_dump (gch, wanted); - - /* And supply the extra ones the simulator uses */ - for (regno = NUM_REALREGS; regno < NUM_REGS; regno++) - { - int buf = 0; - - supply_register (regno, (char *) (&buf)); - } -} - -/* Fetch register REGNO, or all registers if REGNO is -1. Returns - errno value. */ - -static void -e7000_fetch_register (int regno) -{ - e7000_fetch_registers (); -} - -/* Store the remote registers from the contents of the block REGS. */ - -static void -e7000_store_registers (void) -{ - int regno; - - for (regno = 0; regno < NUM_REALREGS; regno++) - e7000_store_register (regno); - - registers_changed (); -} - -/* Store register REGNO, or all if REGNO == 0. Return errno value. */ - -static void -e7000_store_register (int regno) -{ - char buf[200]; - - if (regno == -1) - { - e7000_store_registers (); - return; - } - - if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300) - { - if (regno <= 7) - { - sprintf (buf, ".ER%d %s\r", regno, phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - else if (regno == PC_REGNUM) - { - sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } -#ifdef CCR_REGNUM - else if (regno == CCR_REGNUM) - { - sprintf (buf, ".CCR %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } -#endif - } - - else if (TARGET_ARCHITECTURE->arch == bfd_arch_sh) - { - if (regno == PC_REGNUM) - { - sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - - else if (regno == SR_REGNUM) - { - sprintf (buf, ".SR %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - - else if (regno == PR_REGNUM) - { - sprintf (buf, ".PR %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - - else if (regno == GBR_REGNUM) - { - sprintf (buf, ".GBR %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - - else if (regno == VBR_REGNUM) - { - sprintf (buf, ".VBR %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - - else if (regno == MACH_REGNUM) - { - sprintf (buf, ".MACH %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - - else if (regno == MACL_REGNUM) - { - sprintf (buf, ".MACL %s\r", phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - else - { - sprintf (buf, ".R%d %s\r", regno, phex_nz (read_register (regno), 0)); - puts_e7000debug (buf); - } - } - - expect_prompt (); -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -e7000_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -static void -e7000_files_info (struct target_ops *ops) -{ - printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate); -} - -static int -stickbyte (char *where, unsigned int what) -{ - static CONST char digs[] = "0123456789ABCDEF"; - - where[0] = digs[(what >> 4) & 0xf]; - where[1] = digs[(what & 0xf) & 0xf]; - - return what; -} - -/* Write a small ammount of memory. */ - -static int -write_small (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - int i; - char buf[200]; - - for (i = 0; i < len; i++) - { - if (((memaddr + i) & 3) == 0 && (i + 3 < len)) - { - /* Can be done with a long word */ - sprintf (buf, "m %s %x%02x%02x%02x;l\r", - paddr_nz (memaddr + i), - myaddr[i], myaddr[i + 1], myaddr[i + 2], myaddr[i + 3]); - puts_e7000debug (buf); - i += 3; - } - else - { - sprintf (buf, "m %s %x\r", paddr_nz (memaddr + i), myaddr[i]); - puts_e7000debug (buf); - } - } - - expect_prompt (); - - return len; -} - -/* Write a large ammount of memory, this only works with the serial - mode enabled. Command is sent as - - il ;s:s\r -> - <- il ;s:s\r - <- ENQ - ACK -> - <- LO s\r - Srecords... - ^Z -> - <- ENQ - ACK -> - <- : - */ - -static int -write_large (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - int i; -#define maxstride 128 - int stride; - - puts_e7000debug ("IL ;S:FK\r"); - expect (ENQSTRING); - putchar_e7000 (ACK); - expect ("LO FK\r"); - - for (i = 0; i < len; i += stride) - { - char compose[maxstride * 2 + 50]; - int address = i + memaddr; - int j; - int check_sum; - int where = 0; - int alen; - - stride = len - i; - if (stride > maxstride) - stride = maxstride; - - compose[where++] = 'S'; - check_sum = 0; - if (address >= 0xffffff) - alen = 4; - else if (address >= 0xffff) - alen = 3; - else - alen = 2; - /* Insert type. */ - compose[where++] = alen - 1 + '0'; - /* Insert length. */ - check_sum += stickbyte (compose + where, alen + stride + 1); - where += 2; - while (alen > 0) - { - alen--; - check_sum += stickbyte (compose + where, address >> (8 * (alen))); - where += 2; - } - - for (j = 0; j < stride; j++) - { - check_sum += stickbyte (compose + where, myaddr[i + j]); - where += 2; - } - stickbyte (compose + where, ~check_sum); - where += 2; - compose[where++] = '\r'; - compose[where++] = '\n'; - compose[where++] = 0; - - serial_write (e7000_desc, compose, where); - j = readchar (0); - if (j == -1) - { - /* This is ok - nothing there */ - } - else if (j == ENQ) - { - /* Hmm, it's trying to tell us something */ - expect (":"); - error ("Error writing memory"); - } - else - { - printf_unfiltered ("@%d}@", j); - while ((j = readchar (0)) > 0) - { - printf_unfiltered ("@{%d}@", j); - } - } - } - - /* Send the trailer record */ - write_e7000 ("S70500000000FA\r"); - putchar_e7000 (CTRLZ); - expect (ENQSTRING); - putchar_e7000 (ACK); - expect (":"); - - return len; -} - -/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's - memory at MEMADDR. Returns length moved. - - Can't use the Srecord load over ethernet, so don't use fast method - then. */ - -static int -e7000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - if (len < 16 || using_tcp || using_pc) - return write_small (memaddr, myaddr, len); - else - return write_large (memaddr, myaddr, len); -} - -/* Read LEN bytes from inferior memory at MEMADDR. Put the result - at debugger address MYADDR. Returns length moved. - - Small transactions we send - m ;l - and receive - 00000000 12345678 ? - */ - -static int -e7000_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - int count; - int c; - int i; - char buf[200]; - /* Starting address of this pass. */ - -/* printf("READ INF %x %x %d\n", memaddr, myaddr, len); */ - if (((memaddr - 1) + len) < memaddr) - { - errno = EIO; - return 0; - } - - sprintf (buf, "m %s;l\r", paddr_nz (memaddr)); - puts_e7000debug (buf); - - for (count = 0; count < len; count += 4) - { - /* Suck away the address */ - c = gch (); - while (c != ' ') - c = gch (); - c = gch (); - if (c == '*') - { /* Some kind of error */ - puts_e7000debug (".\r"); /* Some errors leave us in memory input mode */ - expect_full_prompt (); - return -1; - } - while (c != ' ') - c = gch (); - - /* Now read in the data */ - for (i = 0; i < 4; i++) - { - int b = gbyte (); - if (count + i < len) - { - myaddr[count + i] = b; - } - } - - /* Skip the trailing ? and send a . to end and a cr for more */ - gch (); - gch (); - if (count + 4 >= len) - puts_e7000debug (".\r"); - else - puts_e7000debug ("\r"); - - } - expect_prompt (); - return len; -} - - - -/* - For large transfers we used to send - - - d \r - - and receive -

< D A T A > < ASCII CODE > - 00000000 5F FD FD FF DF 7F DF FF 01 00 01 00 02 00 08 04 "_..............." - 00000010 FF D7 FF 7F D7 F1 7F FF 00 05 00 00 08 00 40 00 "..............@." - 00000020 7F FD FF F7 7F FF FF F7 00 00 00 00 00 00 00 00 "................" - - A cost in chars for each transaction of 80 + 5*n-bytes. - - Large transactions could be done with the srecord load code, but - there is a pause for a second before dumping starts, which slows the - average rate down! - */ - -static int -e7000_read_inferior_memory_large (CORE_ADDR memaddr, unsigned char *myaddr, - int len) -{ - int count; - int c; - char buf[200]; - - /* Starting address of this pass. */ - - if (((memaddr - 1) + len) < memaddr) - { - errno = EIO; - return 0; - } - - sprintf (buf, "d %s %s\r", paddr_nz (memaddr), paddr_nz (memaddr + len - 1)); - puts_e7000debug (buf); - - count = 0; - c = gch (); - - /* skip down to the first ">" */ - while (c != '>') - c = gch (); - /* now skip to the end of that line */ - while (c != '\r') - c = gch (); - c = gch (); - - while (count < len) - { - /* get rid of any white space before the address */ - while (c <= ' ') - c = gch (); - - /* Skip the address */ - get_hex (&c); - - /* read in the bytes on the line */ - while (c != '"' && count < len) - { - if (c == ' ') - c = gch (); - else - { - myaddr[count++] = get_hex (&c); - } - } - /* throw out the rest of the line */ - while (c != '\r') - c = gch (); - } - - /* wait for the ":" prompt */ - while (c != ':') - c = gch (); - - return len; -} - -#if 0 - -static int -fast_but_for_the_pause_e7000_read_inferior_memory (CORE_ADDR memaddr, - char *myaddr, int len) -{ - int loop; - int c; - char buf[200]; - - if (((memaddr - 1) + len) < memaddr) - { - errno = EIO; - return 0; - } - - sprintf (buf, "is %x@%x:s\r", memaddr, len); - puts_e7000debug (buf); - gch (); - c = gch (); - if (c != ENQ) - { - /* Got an error */ - error ("Memory read error"); - } - putchar_e7000 (ACK); - expect ("SV s"); - loop = 1; - while (loop) - { - int type; - int length; - int addr; - int i; - - c = gch (); - switch (c) - { - case ENQ: /* ENQ, at the end */ - loop = 0; - break; - case 'S': - /* Start of an Srecord */ - type = gch (); - length = gbyte (); - switch (type) - { - case '7': /* Termination record, ignore */ - case '0': - case '8': - case '9': - /* Header record - ignore it */ - while (length--) - { - gbyte (); - } - break; - case '1': - case '2': - case '3': - { - int alen; - - alen = type - '0' + 1; - addr = 0; - while (alen--) - { - addr = (addr << 8) + gbyte (); - length--; - } - - for (i = 0; i < length - 1; i++) - myaddr[i + addr - memaddr] = gbyte (); - - gbyte (); /* Ignore checksum */ - } - } - } - } - - putchar_e7000 (ACK); - expect ("TOP ADDRESS ="); - expect ("END ADDRESS ="); - expect (":"); - - return len; -} - -#endif - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If WRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - Returns the number of bytes transferred. */ - -static int -e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, struct mem_attrib *attrib, - struct target_ops *target) -{ - if (write) - return e7000_write_inferior_memory (memaddr, myaddr, len); - else if (len < 16) - return e7000_read_inferior_memory (memaddr, myaddr, len); - else - return e7000_read_inferior_memory_large (memaddr, myaddr, len); -} - -static void -e7000_kill (void) -{ -} - -static void -e7000_load (char *args, int from_tty) -{ - struct cleanup *old_chain; - asection *section; - bfd *pbfd; - bfd_vma entry; -#define WRITESIZE 0x1000 - char buf[2 + 4 + 4 + WRITESIZE]; /* `DT' + + + */ - char *filename; - int quiet; - int nostart; - time_t start_time, end_time; /* Start and end times of download */ - unsigned long data_count; /* Number of bytes transferred to memory */ - int oldtimeout = timeout; - - timeout = remote_timeout; - - - /* FIXME! change test to test for type of download */ - if (!using_tcp) - { - generic_load (args, from_tty); - return; - } - - /* for direct tcp connections, we can do a fast binary download */ - buf[0] = 'D'; - buf[1] = 'T'; - quiet = 0; - nostart = 0; - filename = NULL; - - while (*args != '\000') - { - char *arg; - - while (isspace (*args)) - args++; - - arg = args; - - while ((*args != '\000') && !isspace (*args)) - args++; - - if (*args != '\000') - *args++ = '\000'; - - if (*arg != '-') - filename = arg; - else if (strncmp (arg, "-quiet", strlen (arg)) == 0) - quiet = 1; - else if (strncmp (arg, "-nostart", strlen (arg)) == 0) - nostart = 1; - else - error ("unknown option `%s'", arg); - } - - if (!filename) - filename = get_exec_file (1); - - pbfd = bfd_openr (filename, gnutarget); - if (pbfd == NULL) - { - perror_with_name (filename); - return; - } - old_chain = make_cleanup_bfd_close (pbfd); - - if (!bfd_check_format (pbfd, bfd_object)) - error ("\"%s\" is not an object file: %s", filename, - bfd_errmsg (bfd_get_error ())); - - start_time = time (NULL); - data_count = 0; - - puts_e7000debug ("mw\r"); - - expect ("\nOK"); - - for (section = pbfd->sections; section; section = section->next) - { - if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) - { - bfd_vma section_address; - bfd_size_type section_size; - file_ptr fptr; - - section_address = bfd_get_section_vma (pbfd, section); - section_size = bfd_get_section_size_before_reloc (section); - - if (!quiet) - printf_filtered ("[Loading section %s at 0x%s (%s bytes)]\n", - bfd_get_section_name (pbfd, section), - paddr_nz (section_address), - paddr_u (section_size)); - - fptr = 0; - - data_count += section_size; - - while (section_size > 0) - { - int count; - static char inds[] = "|/-\\"; - static int k = 0; - - QUIT; - - count = min (section_size, WRITESIZE); - - buf[2] = section_address >> 24; - buf[3] = section_address >> 16; - buf[4] = section_address >> 8; - buf[5] = section_address; - - buf[6] = count >> 24; - buf[7] = count >> 16; - buf[8] = count >> 8; - buf[9] = count; - - bfd_get_section_contents (pbfd, section, buf + 10, fptr, count); - - if (serial_write (e7000_desc, buf, count + 10)) - fprintf_unfiltered (gdb_stderr, - "e7000_load: serial_write failed: %s\n", - safe_strerror (errno)); - - expect ("OK"); - - if (!quiet) - { - printf_unfiltered ("\r%c", inds[k++ % 4]); - gdb_flush (gdb_stdout); - } - - section_address += count; - fptr += count; - section_size -= count; - } - } - } - - write_e7000 ("ED"); - - expect_prompt (); - - end_time = time (NULL); - -/* Finally, make the PC point at the start address */ - - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - inferior_ptid = null_ptid; /* No process now */ - -/* This is necessary because many things were based on the PC at the time that - we attached to the monitor, which is no longer valid now that we have loaded - new code (and just changed the PC). Another way to do this might be to call - normal_stop, except that the stack may not be valid, and things would get - horribly confused... */ - - clear_symtab_users (); - - if (!nostart) - { - entry = bfd_get_start_address (pbfd); - - if (!quiet) - printf_unfiltered ("[Starting %s at 0x%s]\n", filename, paddr_nz (entry)); - -/* start_routine (entry); */ - } - - report_transfer_performance (data_count, start_time, end_time); - - do_cleanups (old_chain); - timeout = oldtimeout; -} - -/* Clean up when a program exits. - - The program actually lives on in the remote processor's RAM, and may be - run again without a download. Don't leave it full of breakpoint - instructions. */ - -static void -e7000_mourn_inferior (void) -{ - remove_breakpoints (); - unpush_target (&e7000_ops); - generic_mourn_inferior (); /* Do all the proper things now */ -} - -#define MAX_BREAKPOINTS 200 -#ifdef HARD_BREAKPOINTS -#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 : MAX_BREAKPOINTS) -#else -#define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS -#endif - -/* Since we can change to soft breakpoints dynamically, we must define - more than enough. Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */ -static CORE_ADDR breakaddr[MAX_BREAKPOINTS] = -{0}; - -static int -e7000_insert_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - char buf[200]; -#if 0 - static char nop[2] = NOP; -#endif - - for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++) - if (breakaddr[i] == 0) - { - breakaddr[i] = addr; - /* Save old contents, and insert a nop in the space */ -#ifdef HARD_BREAKPOINTS - if (BC_BREAKPOINTS) - { - sprintf (buf, "BC%d A=%s\r", i + 1, paddr_nz (addr)); - puts_e7000debug (buf); - } - else - { - sprintf (buf, "B %s\r", paddr_nz (addr)); - puts_e7000debug (buf); - } -#else -#if 0 - e7000_read_inferior_memory (addr, shadow, 2); - e7000_write_inferior_memory (addr, nop, 2); -#endif - - sprintf (buf, "B %x\r", addr); - puts_e7000debug (buf); -#endif - expect_prompt (); - return 0; - } - - error ("Too many breakpoints ( > %d) for the E7000\n", - MAX_E7000DEBUG_BREAKPOINTS); - return 1; -} - -static int -e7000_remove_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - char buf[200]; - - for (i = 0; i < MAX_E7000DEBUG_BREAKPOINTS; i++) - if (breakaddr[i] == addr) - { - breakaddr[i] = 0; -#ifdef HARD_BREAKPOINTS - if (BC_BREAKPOINTS) - { - sprintf (buf, "BC%d - \r", i + 1); - puts_e7000debug (buf); - } - else - { - sprintf (buf, "B - %s\r", paddr_nz (addr)); - puts_e7000debug (buf); - } - expect_prompt (); -#else - sprintf (buf, "B - %s\r", paddr_nz (addr)); - puts_e7000debug (buf); - expect_prompt (); - -#if 0 - /* Replace the insn under the break */ - e7000_write_inferior_memory (addr, shadow, 2); -#endif -#endif - - return 0; - } - - warning ("Can't find breakpoint associated with 0x%s\n", paddr_nz (addr)); - return 1; -} - -/* Put a command string, in args, out to STDBUG. Output from STDBUG - is placed on the users terminal until the prompt is seen. */ - -static void -e7000_command (char *args, int fromtty) -{ - /* FIXME: arbitrary limit on length of args. */ - char buf[200]; - - echo = 0; - - if (!e7000_desc) - error ("e7000 target not open."); - if (!args) - { - puts_e7000debug ("\r"); - } - else - { - sprintf (buf, "%s\r", args); - puts_e7000debug (buf); - } - - echo++; - ctrl_c = 2; - expect_full_prompt (); - echo--; - ctrl_c = 0; - printf_unfiltered ("\n"); - - /* Who knows what the command did... */ - registers_changed (); -} - - -static void -e7000_drain_command (char *args, int fromtty) -{ - int c; - - puts_e7000debug ("end\r"); - putchar_e7000 (CTRLC); - - while ((c = readchar (1) != -1)) - { - if (quit_flag) - { - putchar_e7000 (CTRLC); - quit_flag = 0; - } - if (c > ' ' && c < 127) - printf_unfiltered ("%c", c & 0xff); - else - printf_unfiltered ("<%x>", c & 0xff); - } -} - -#define NITEMS 7 - -static int -why_stop (void) -{ - static char *strings[NITEMS] = - { - "STEP NORMAL", - "BREAK POINT", - "BREAK KEY", - "BREAK CONDI", - "CYCLE ACCESS", - "ILLEGAL INSTRUCTION", - "WRITE PROTECT", - }; - char *p[NITEMS]; - int c; - int i; - - for (i = 0; i < NITEMS; ++i) - p[i] = strings[i]; - - c = gch (); - while (1) - { - for (i = 0; i < NITEMS; i++) - { - if (c == *(p[i])) - { - p[i]++; - if (*(p[i]) == 0) - { - /* found one of the choices */ - return i; - } - } - else - p[i] = strings[i]; - } - - c = gch (); - } -} - -/* Suck characters, if a string match, then return the strings index - otherwise echo them. */ - -int -expect_n (char **strings) -{ - char *(ptr[10]); - int n; - int c; - char saveaway[100]; - char *buffer = saveaway; - /* Count number of expect strings */ - - for (n = 0; strings[n]; n++) - { - ptr[n] = strings[n]; - } - - while (1) - { - int i; - int gotone = 0; - - c = readchar (1); - if (c == -1) - { - printf_unfiltered ("[waiting for e7000...]\n"); - } -#ifdef __GO32__ - if (kbhit ()) - { - int k = getkey (); - - if (k == 1) - quit_flag = 1; - } -#endif - if (quit_flag) - { - putchar_e7000 (CTRLC); /* interrupt the running program */ - quit_flag = 0; - } - - for (i = 0; i < n; i++) - { - if (c == ptr[i][0]) - { - ptr[i]++; - if (ptr[i][0] == 0) - { - /* Gone all the way */ - return i; - } - gotone = 1; - } - else - { - ptr[i] = strings[i]; - } - } - - if (gotone) - { - /* Save it up incase we find that there was no match */ - *buffer++ = c; - } - else - { - if (buffer != saveaway) - { - *buffer++ = 0; - printf_unfiltered ("%s", buffer); - buffer = saveaway; - } - if (c != -1) - { - putchar_unfiltered (c); - gdb_flush (gdb_stdout); - } - } - } -} - -/* We subtract two from the pc here rather than use - DECR_PC_AFTER_BREAK since the e7000 doesn't always add two to the - pc, and the simulators never do. */ - -static void -sub2_from_pc (void) -{ - char buf[4]; - char buf2[200]; - - store_signed_integer (buf, - REGISTER_RAW_SIZE (PC_REGNUM), - read_register (PC_REGNUM) - 2); - supply_register (PC_REGNUM, buf); - sprintf (buf2, ".PC %s\r", phex_nz (read_register (PC_REGNUM), 0)); - puts_e7000debug (buf2); -} - -#define WAS_SLEEP 0 -#define WAS_INT 1 -#define WAS_RUNNING 2 -#define WAS_OTHER 3 - -static char *estrings[] = -{ - "** SLEEP", - "BREAK !", - "** PC", - "PC", - NULL -}; - -/* Wait until the remote machine stops, then return, storing status in - STATUS just as `wait' would. */ - -static ptid_t -e7000_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int stop_reason; - int regno; - int running_count = 0; - int had_sleep = 0; - int loop = 1; - char *wanted_nopc = NULL; - - /* Then echo chars until PC= string seen */ - gch (); /* Drop cr */ - gch (); /* and space */ - - while (loop) - { - switch (expect_n (estrings)) - { - case WAS_OTHER: - /* how did this happen ? */ - loop = 0; - break; - case WAS_SLEEP: - had_sleep = 1; - putchar_e7000 (CTRLC); - loop = 0; - break; - case WAS_INT: - loop = 0; - break; - case WAS_RUNNING: - running_count++; - if (running_count == 20) - { - printf_unfiltered ("[running...]\n"); - running_count = 0; - } - break; - default: - /* error? */ - break; - } - } - - /* Skip till the PC= */ - expect ("="); - - if (TARGET_ARCHITECTURE->arch == bfd_arch_sh) - { - wanted_nopc = want_nopc_sh; - switch (TARGET_ARCHITECTURE->mach) - { - case bfd_mach_sh3: - case bfd_mach_sh3e: - case bfd_mach_sh4: - wanted_nopc = want_nopc_sh3; - } - } -#ifdef GDB_TARGET_IS_H8300 - if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300) - { - if (h8300smode) - wanted_nopc = want_nopc_h8300s; - else - wanted_nopc = want_nopc_h8300h; - } -#endif - fetch_regs_from_dump (gch, wanted_nopc); - - /* And supply the extra ones the simulator uses */ - for (regno = NUM_REALREGS; regno < NUM_REGS; regno++) - { - int buf = 0; - supply_register (regno, (char *) &buf); - } - - stop_reason = why_stop (); - expect_full_prompt (); - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - - switch (stop_reason) - { - case 1: /* Breakpoint */ - write_pc (read_pc ()); /* PC is always off by 2 for breakpoints */ - status->value.sig = TARGET_SIGNAL_TRAP; - break; - case 0: /* Single step */ - status->value.sig = TARGET_SIGNAL_TRAP; - break; - case 2: /* Interrupt */ - if (had_sleep) - { - status->value.sig = TARGET_SIGNAL_TRAP; - sub2_from_pc (); - } - else - { - status->value.sig = TARGET_SIGNAL_INT; - } - break; - case 3: - break; - case 4: - printf_unfiltered ("a cycle address error?\n"); - status->value.sig = TARGET_SIGNAL_UNKNOWN; - break; - case 5: - status->value.sig = TARGET_SIGNAL_ILL; - break; - case 6: - status->value.sig = TARGET_SIGNAL_SEGV; - break; - case 7: /* Anything else (NITEMS + 1) */ - printf_unfiltered ("a write protect error?\n"); - status->value.sig = TARGET_SIGNAL_UNKNOWN; - break; - default: - /* Get the user's attention - this should never happen. */ - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } - - return inferior_ptid; -} - -/* Stop the running program. */ - -static void -e7000_stop (void) -{ - /* Sending a ^C is supposed to stop the running program. */ - putchar_e7000 (CTRLC); -} - -/* Define the target subroutine names. */ - -struct target_ops e7000_ops; - -static void -init_e7000_ops (void) -{ - e7000_ops.to_shortname = "e7000"; - e7000_ops.to_longname = "Remote Hitachi e7000 target"; - e7000_ops.to_doc = "Use a remote Hitachi e7000 ICE connected by a serial line;\n\ -or a network connection.\n\ -Arguments are the name of the device for the serial line,\n\ -the speed to connect at in bits per second.\n\ -eg\n\ -target e7000 /dev/ttya 9600\n\ -target e7000 foobar"; - e7000_ops.to_open = e7000_open; - e7000_ops.to_close = e7000_close; - e7000_ops.to_attach = 0; - e7000_ops.to_post_attach = NULL; - e7000_ops.to_require_attach = NULL; - e7000_ops.to_detach = e7000_detach; - e7000_ops.to_require_detach = NULL; - e7000_ops.to_resume = e7000_resume; - e7000_ops.to_wait = e7000_wait; - e7000_ops.to_post_wait = NULL; - e7000_ops.to_fetch_registers = e7000_fetch_register; - e7000_ops.to_store_registers = e7000_store_register; - e7000_ops.to_prepare_to_store = e7000_prepare_to_store; - e7000_ops.to_xfer_memory = e7000_xfer_inferior_memory; - e7000_ops.to_files_info = e7000_files_info; - e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint; - e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint; - e7000_ops.to_terminal_init = 0; - e7000_ops.to_terminal_inferior = 0; - e7000_ops.to_terminal_ours_for_output = 0; - e7000_ops.to_terminal_ours = 0; - e7000_ops.to_terminal_info = 0; - e7000_ops.to_kill = e7000_kill; - e7000_ops.to_load = e7000_load; - e7000_ops.to_lookup_symbol = 0; - e7000_ops.to_create_inferior = e7000_create_inferior; - e7000_ops.to_post_startup_inferior = NULL; - e7000_ops.to_acknowledge_created_inferior = NULL; - e7000_ops.to_clone_and_follow_inferior = NULL; - e7000_ops.to_post_follow_inferior_by_clone = NULL; - e7000_ops.to_insert_fork_catchpoint = NULL; - e7000_ops.to_remove_fork_catchpoint = NULL; - e7000_ops.to_insert_vfork_catchpoint = NULL; - e7000_ops.to_remove_vfork_catchpoint = NULL; - e7000_ops.to_has_forked = NULL; - e7000_ops.to_has_vforked = NULL; - e7000_ops.to_can_follow_vfork_prior_to_exec = NULL; - e7000_ops.to_post_follow_vfork = NULL; - e7000_ops.to_insert_exec_catchpoint = NULL; - e7000_ops.to_remove_exec_catchpoint = NULL; - e7000_ops.to_has_execd = NULL; - e7000_ops.to_reported_exec_events_per_exec_call = NULL; - e7000_ops.to_has_exited = NULL; - e7000_ops.to_mourn_inferior = e7000_mourn_inferior; - e7000_ops.to_can_run = 0; - e7000_ops.to_notice_signals = 0; - e7000_ops.to_thread_alive = 0; - e7000_ops.to_stop = e7000_stop; - e7000_ops.to_pid_to_exec_file = NULL; - e7000_ops.to_stratum = process_stratum; - e7000_ops.DONT_USE = 0; - e7000_ops.to_has_all_memory = 1; - e7000_ops.to_has_memory = 1; - e7000_ops.to_has_stack = 1; - e7000_ops.to_has_registers = 1; - e7000_ops.to_has_execution = 1; - e7000_ops.to_sections = 0; - e7000_ops.to_sections_end = 0; - e7000_ops.to_magic = OPS_MAGIC; -}; - -void -_initialize_remote_e7000 (void) -{ - init_e7000_ops (); - add_target (&e7000_ops); - - add_com ("e7000", class_obscure, e7000_command, - "Send a command to the e7000 monitor."); - - add_com ("ftplogin", class_obscure, e7000_login_command, - "Login to machine and change to directory."); - - add_com ("ftpload", class_obscure, e7000_ftp_command, - "Fetch and load a file from previously described place."); - - add_com ("drain", class_obscure, e7000_drain_command, - "Drain pending e7000 text buffers."); - - add_show_from_set (add_set_cmd ("usehardbreakpoints", no_class, - var_integer, (char *) &use_hard_breakpoints, - "Set use of hardware breakpoints for all breakpoints.\n", &setlist), - &showlist); -} diff --git a/contrib/gdb/gdb/remote-eb.c b/contrib/gdb/gdb/remote-eb.c deleted file mode 100644 index dcee34514f2..00000000000 --- a/contrib/gdb/gdb/remote-eb.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* OBSOLETE /* Remote debugging interface for AMD 29000 EBMON on IBM PC, for GDB. */ -/* OBSOLETE Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001 */ -/* OBSOLETE Free Software Foundation, Inc. */ -/* OBSOLETE Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus. */ -/* OBSOLETE */ -/* OBSOLETE This file is part of GDB. */ -/* OBSOLETE */ -/* OBSOLETE This program is free software; you can redistribute it and/or modify */ -/* OBSOLETE it under the terms of the GNU General Public License as published by */ -/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */ -/* OBSOLETE (at your option) any later version. */ -/* OBSOLETE */ -/* OBSOLETE This program is distributed in the hope that it will be useful, */ -/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* OBSOLETE GNU General Public License for more details. */ -/* OBSOLETE */ -/* OBSOLETE You should have received a copy of the GNU General Public License */ -/* OBSOLETE along with this program; if not, write to the Free Software */ -/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */ -/* OBSOLETE Boston, MA 02111-1307, USA. */ */ -/* OBSOLETE */ -/* OBSOLETE /* This is like remote.c but is for an esoteric situation-- */ -/* OBSOLETE having a a29k board in a PC hooked up to a unix machine with */ -/* OBSOLETE a serial line, and running ctty com1 on the PC, through which */ -/* OBSOLETE the unix machine can run ebmon. Not to mention that the PC */ -/* OBSOLETE has PC/NFS, so it can access the same executables that gdb can, */ -/* OBSOLETE over the net in real time. */ */ -/* OBSOLETE */ -/* OBSOLETE #include "defs.h" */ -/* OBSOLETE #include "gdb_string.h" */ -/* OBSOLETE #include "regcache.h" */ -/* OBSOLETE */ -/* OBSOLETE #include "inferior.h" */ -/* OBSOLETE #include "bfd.h" */ -/* OBSOLETE #include "symfile.h" */ -/* OBSOLETE #include "value.h" */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include "terminal.h" */ -/* OBSOLETE #include "target.h" */ -/* OBSOLETE #include "gdbcore.h" */ -/* OBSOLETE */ -/* OBSOLETE extern struct target_ops eb_ops; /* Forward declaration */ */ -/* OBSOLETE */ -/* OBSOLETE static void eb_close (); */ -/* OBSOLETE */ -/* OBSOLETE #define LOG_FILE "eb.log" */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE FILE *log_file; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE static int timeout = 24; */ -/* OBSOLETE */ -/* OBSOLETE /* Descriptor for I/O to remote machine. Initialize it to -1 so that */ -/* OBSOLETE eb_open knows that we don't have a file open when the program */ -/* OBSOLETE starts. */ */ -/* OBSOLETE int eb_desc = -1; */ -/* OBSOLETE */ -/* OBSOLETE /* stream which is fdopen'd from eb_desc. Only valid when */ -/* OBSOLETE eb_desc != -1. */ */ -/* OBSOLETE FILE *eb_stream; */ -/* OBSOLETE */ -/* OBSOLETE /* Read a character from the remote system, doing all the fancy */ -/* OBSOLETE timeout stuff. */ */ -/* OBSOLETE static int */ -/* OBSOLETE readchar (void) */ -/* OBSOLETE { */ -/* OBSOLETE char buf; */ -/* OBSOLETE */ -/* OBSOLETE buf = '\0'; */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE /* termio does the timeout for us. */ */ -/* OBSOLETE read (eb_desc, &buf, 1); */ -/* OBSOLETE #else */ -/* OBSOLETE alarm (timeout); */ -/* OBSOLETE if (read (eb_desc, &buf, 1) < 0) */ -/* OBSOLETE { */ -/* OBSOLETE if (errno == EINTR) */ -/* OBSOLETE error ("Timeout reading from remote system."); */ -/* OBSOLETE else */ -/* OBSOLETE perror_with_name ("remote"); */ -/* OBSOLETE } */ -/* OBSOLETE alarm (0); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE if (buf == '\0') */ -/* OBSOLETE error ("Timeout reading from remote system."); */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE putc (buf & 0x7f, log_file); */ -/* OBSOLETE #endif */ -/* OBSOLETE return buf & 0x7f; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Keep discarding input from the remote system, until STRING is found. */ -/* OBSOLETE Let the user break out immediately. */ */ -/* OBSOLETE static void */ -/* OBSOLETE expect (char *string) */ -/* OBSOLETE { */ -/* OBSOLETE char *p = string; */ -/* OBSOLETE */ -/* OBSOLETE immediate_quit++; */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE if (readchar () == *p) */ -/* OBSOLETE { */ -/* OBSOLETE p++; */ -/* OBSOLETE if (*p == '\0') */ -/* OBSOLETE { */ -/* OBSOLETE immediate_quit--; */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE p = string; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Keep discarding input until we see the ebmon prompt. */ -/* OBSOLETE */ -/* OBSOLETE The convention for dealing with the prompt is that you */ -/* OBSOLETE o give your command */ -/* OBSOLETE o *then* wait for the prompt. */ -/* OBSOLETE */ -/* OBSOLETE Thus the last thing that a procedure does with the serial line */ -/* OBSOLETE will be an expect_prompt(). Exception: eb_resume does not */ -/* OBSOLETE wait for the prompt, because the terminal is being handed over */ -/* OBSOLETE to the inferior. However, the next thing which happens after that */ -/* OBSOLETE is a eb_wait which does wait for the prompt. */ -/* OBSOLETE Note that this includes abnormal exit, e.g. error(). This is */ -/* OBSOLETE necessary to prevent getting into states from which we can't */ -/* OBSOLETE recover. */ */ -/* OBSOLETE static void */ -/* OBSOLETE expect_prompt (void) */ -/* OBSOLETE { */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE /* This is a convenient place to do this. The idea is to do it often */ -/* OBSOLETE enough that we never lose much data if we terminate abnormally. */ */ -/* OBSOLETE fflush (log_file); */ -/* OBSOLETE #endif */ -/* OBSOLETE expect ("\n# "); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Get a hex digit from the remote system & return its value. */ -/* OBSOLETE If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ */ -/* OBSOLETE static int */ -/* OBSOLETE get_hex_digit (int ignore_space) */ -/* OBSOLETE { */ -/* OBSOLETE int ch; */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE ch = readchar (); */ -/* OBSOLETE if (ch >= '0' && ch <= '9') */ -/* OBSOLETE return ch - '0'; */ -/* OBSOLETE else if (ch >= 'A' && ch <= 'F') */ -/* OBSOLETE return ch - 'A' + 10; */ -/* OBSOLETE else if (ch >= 'a' && ch <= 'f') */ -/* OBSOLETE return ch - 'a' + 10; */ -/* OBSOLETE else if (ch == ' ' && ignore_space) */ -/* OBSOLETE ; */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE error ("Invalid hex digit from remote system."); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Get a byte from eb_desc and put it in *BYT. Accept any number */ -/* OBSOLETE leading spaces. */ */ -/* OBSOLETE static void */ -/* OBSOLETE get_hex_byte (char *byt) */ -/* OBSOLETE { */ -/* OBSOLETE int val; */ -/* OBSOLETE */ -/* OBSOLETE val = get_hex_digit (1) << 4; */ -/* OBSOLETE val |= get_hex_digit (0); */ -/* OBSOLETE *byt = val; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Get N 32-bit words from remote, each preceded by a space, */ -/* OBSOLETE and put them in registers starting at REGNO. */ */ -/* OBSOLETE static void */ -/* OBSOLETE get_hex_regs (int n, int regno) */ -/* OBSOLETE { */ -/* OBSOLETE long val; */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; i < n; i++) */ -/* OBSOLETE { */ -/* OBSOLETE int j; */ -/* OBSOLETE */ -/* OBSOLETE val = 0; */ -/* OBSOLETE for (j = 0; j < 8; j++) */ -/* OBSOLETE val = (val << 4) + get_hex_digit (j == 0); */ -/* OBSOLETE supply_register (regno++, (char *) &val); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Called when SIGALRM signal sent due to alarm() timeout. */ */ -/* OBSOLETE #ifndef HAVE_TERMIO */ -/* OBSOLETE */ -/* OBSOLETE volatile int n_alarms; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE eb_timer (void) */ -/* OBSOLETE { */ -/* OBSOLETE #if 0 */ -/* OBSOLETE if (kiodebug) */ -/* OBSOLETE printf ("eb_timer called\n"); */ -/* OBSOLETE #endif */ -/* OBSOLETE n_alarms++; */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* malloc'd name of the program on the remote system. */ */ -/* OBSOLETE static char *prog_name = NULL; */ -/* OBSOLETE */ -/* OBSOLETE /* Nonzero if we have loaded the file ("yc") and not yet issued a "gi" */ -/* OBSOLETE command. "gi" is supposed to happen exactly once for each "yc". */ */ -/* OBSOLETE static int need_gi = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* Number of SIGTRAPs we need to simulate. That is, the next */ -/* OBSOLETE NEED_ARTIFICIAL_TRAP calls to eb_wait should just return */ -/* OBSOLETE SIGTRAP without actually waiting for anything. */ */ -/* OBSOLETE */ -/* OBSOLETE static int need_artificial_trap = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* This is called not only when we first attach, but also when the */ -/* OBSOLETE user types "run" after having attached. */ */ -/* OBSOLETE static void */ -/* OBSOLETE eb_create_inferior (char *execfile, char *args, char **env) */ -/* OBSOLETE { */ -/* OBSOLETE int entry_pt; */ -/* OBSOLETE */ -/* OBSOLETE if (args && *args) */ -/* OBSOLETE error ("Can't pass arguments to remote EBMON process"); */ -/* OBSOLETE */ -/* OBSOLETE if (execfile == 0 || exec_bfd == 0) */ -/* OBSOLETE error ("No executable file specified"); */ -/* OBSOLETE */ -/* OBSOLETE entry_pt = (int) bfd_get_start_address (exec_bfd); */ -/* OBSOLETE */ -/* OBSOLETE { */ -/* OBSOLETE /* OK, now read in the file. Y=read, C=COFF, D=no symbols */ -/* OBSOLETE 0=start address, %s=filename. */ */ -/* OBSOLETE */ -/* OBSOLETE fprintf (eb_stream, "YC D,0:%s", prog_name); */ -/* OBSOLETE */ -/* OBSOLETE if (args != NULL) */ -/* OBSOLETE fprintf (eb_stream, " %s", args); */ -/* OBSOLETE */ -/* OBSOLETE fprintf (eb_stream, "\n"); */ -/* OBSOLETE fflush (eb_stream); */ -/* OBSOLETE */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE need_gi = 1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* The "process" (board) is already stopped awaiting our commands, and */ -/* OBSOLETE the program is already downloaded. We just set its PC and go. */ */ -/* OBSOLETE */ -/* OBSOLETE clear_proceed_status (); */ -/* OBSOLETE */ -/* OBSOLETE /* Tell wait_for_inferior that we've started a new process. */ */ -/* OBSOLETE init_wait_for_inferior (); */ -/* OBSOLETE */ -/* OBSOLETE /* Set up the "saved terminal modes" of the inferior */ -/* OBSOLETE based on what modes we are starting it with. */ */ -/* OBSOLETE target_terminal_init (); */ -/* OBSOLETE */ -/* OBSOLETE /* Install inferior's terminal modes. */ */ -/* OBSOLETE target_terminal_inferior (); */ -/* OBSOLETE */ -/* OBSOLETE /* insert_step_breakpoint (); FIXME, do we need this? */ */ -/* OBSOLETE proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0); /* Let 'er rip... */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Translate baud rates from integers to damn B_codes. Unix should */ -/* OBSOLETE have outgrown this crap years ago, but even POSIX wouldn't buck it. */ */ -/* OBSOLETE */ -/* OBSOLETE #ifndef B19200 */ -/* OBSOLETE #define B19200 EXTA */ -/* OBSOLETE #endif */ -/* OBSOLETE #ifndef B38400 */ -/* OBSOLETE #define B38400 EXTB */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE struct */ -/* OBSOLETE { */ -/* OBSOLETE int rate, damn_b; */ -/* OBSOLETE } */ -/* OBSOLETE baudtab[] = */ -/* OBSOLETE { */ -/* OBSOLETE { */ -/* OBSOLETE 0, B0 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 50, B50 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 75, B75 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 110, B110 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 134, B134 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 150, B150 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 200, B200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 300, B300 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 600, B600 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 1200, B1200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 1800, B1800 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 2400, B2400 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 4800, B4800 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 9600, B9600 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 19200, B19200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 38400, B38400 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE -1, -1 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE }; */ -/* OBSOLETE */ -/* OBSOLETE int */ -/* OBSOLETE damn_b (int rate) */ -/* OBSOLETE { */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; baudtab[i].rate != -1; i++) */ -/* OBSOLETE if (rate == baudtab[i].rate) */ -/* OBSOLETE return baudtab[i].damn_b; */ -/* OBSOLETE return B38400; /* Random */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /* Open a connection to a remote debugger. */ -/* OBSOLETE NAME is the filename used for communication, then a space, */ -/* OBSOLETE then the name of the program as we should name it to EBMON. */ */ -/* OBSOLETE */ -/* OBSOLETE static int baudrate = 9600; */ -/* OBSOLETE static char *dev_name; */ -/* OBSOLETE void */ -/* OBSOLETE eb_open (char *name, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE TERMINAL sg; */ -/* OBSOLETE */ -/* OBSOLETE char *p; */ -/* OBSOLETE */ -/* OBSOLETE target_preopen (from_tty); */ -/* OBSOLETE */ -/* OBSOLETE /* Find the first whitespace character, it separates dev_name from */ -/* OBSOLETE prog_name. */ */ -/* OBSOLETE if (name == 0) */ -/* OBSOLETE goto erroid; */ -/* OBSOLETE */ -/* OBSOLETE for (p = name; */ -/* OBSOLETE *p != '\0' && !isspace (*p); p++) */ -/* OBSOLETE ; */ -/* OBSOLETE if (*p == '\0') */ -/* OBSOLETE erroid: */ -/* OBSOLETE error ("\ */ -/* OBSOLETE Please include the name of the device for the serial port,\n\ */ -/* OBSOLETE the baud rate, and the name of the program to run on the remote system."); */ -/* OBSOLETE dev_name = alloca (p - name + 1); */ -/* OBSOLETE strncpy (dev_name, name, p - name); */ -/* OBSOLETE dev_name[p - name] = '\0'; */ -/* OBSOLETE */ -/* OBSOLETE /* Skip over the whitespace after dev_name */ */ -/* OBSOLETE for (; isspace (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE */ -/* OBSOLETE if (1 != sscanf (p, "%d ", &baudrate)) */ -/* OBSOLETE goto erroid; */ -/* OBSOLETE */ -/* OBSOLETE /* Skip the number and then the spaces */ */ -/* OBSOLETE for (; isdigit (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE for (; isspace (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE */ -/* OBSOLETE if (prog_name != NULL) */ -/* OBSOLETE xfree (prog_name); */ -/* OBSOLETE prog_name = savestring (p, strlen (p)); */ -/* OBSOLETE */ -/* OBSOLETE eb_close (0); */ -/* OBSOLETE */ -/* OBSOLETE eb_desc = open (dev_name, O_RDWR); */ -/* OBSOLETE if (eb_desc < 0) */ -/* OBSOLETE perror_with_name (dev_name); */ -/* OBSOLETE ioctl (eb_desc, TIOCGETP, &sg); */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE sg.c_cc[VMIN] = 0; /* read with timeout. */ */ -/* OBSOLETE sg.c_cc[VTIME] = timeout * 10; */ -/* OBSOLETE sg.c_lflag &= ~(ICANON | ECHO); */ -/* OBSOLETE sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate); */ -/* OBSOLETE #else */ -/* OBSOLETE sg.sg_ispeed = damn_b (baudrate); */ -/* OBSOLETE sg.sg_ospeed = damn_b (baudrate); */ -/* OBSOLETE sg.sg_flags |= RAW | ANYP; */ -/* OBSOLETE sg.sg_flags &= ~ECHO; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE ioctl (eb_desc, TIOCSETP, &sg); */ -/* OBSOLETE eb_stream = fdopen (eb_desc, "r+"); */ -/* OBSOLETE */ -/* OBSOLETE push_target (&eb_ops); */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf ("Remote %s debugging %s using %s\n", target_shortname, */ -/* OBSOLETE prog_name, dev_name); */ -/* OBSOLETE */ -/* OBSOLETE #ifndef HAVE_TERMIO */ -/* OBSOLETE #ifndef NO_SIGINTERRUPT */ -/* OBSOLETE /* Cause SIGALRM's to make reads fail with EINTR instead of resuming */ -/* OBSOLETE the read. */ */ -/* OBSOLETE if (siginterrupt (SIGALRM, 1) != 0) */ -/* OBSOLETE perror ("eb_open: error in siginterrupt"); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* Set up read timeout timer. */ */ -/* OBSOLETE if ((void (*)) signal (SIGALRM, eb_timer) == (void (*)) -1) */ -/* OBSOLETE perror ("eb_open: error in signal"); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE log_file = fopen (LOG_FILE, "w"); */ -/* OBSOLETE if (log_file == NULL) */ -/* OBSOLETE perror_with_name (LOG_FILE); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* Hello? Are you there? */ */ -/* OBSOLETE write (eb_desc, "\n", 1); */ -/* OBSOLETE */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Close out all files and local state before this target loses control. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE eb_close (int quitting) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE /* Due to a bug in Unix, fclose closes not only the stdio stream, */ -/* OBSOLETE but also the file descriptor. So we don't actually close */ -/* OBSOLETE eb_desc. */ */ -/* OBSOLETE if (eb_stream) */ -/* OBSOLETE fclose (eb_stream); /* This also closes eb_desc */ */ -/* OBSOLETE if (eb_desc >= 0) */ -/* OBSOLETE /* close (eb_desc); */ */ -/* OBSOLETE */ -/* OBSOLETE /* Do not try to close eb_desc again, later in the program. */ */ -/* OBSOLETE eb_stream = NULL; */ -/* OBSOLETE eb_desc = -1; */ -/* OBSOLETE */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE if (log_file) */ -/* OBSOLETE { */ -/* OBSOLETE if (ferror (log_file)) */ -/* OBSOLETE printf ("Error writing log file.\n"); */ -/* OBSOLETE if (fclose (log_file) != 0) */ -/* OBSOLETE printf ("Error closing log file.\n"); */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Terminate the open connection to the remote debugger. */ -/* OBSOLETE Use this when you want to detach and do something else */ -/* OBSOLETE with your gdb. */ */ -/* OBSOLETE void */ -/* OBSOLETE eb_detach (int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE pop_target (); /* calls eb_close to do the real work */ */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf ("Ending remote %s debugging\n", target_shortname); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Tell the remote machine to resume. */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE eb_resume (ptid_t ptid, int step, enum target_signal sig) */ -/* OBSOLETE { */ -/* OBSOLETE if (step) */ -/* OBSOLETE { */ -/* OBSOLETE write (eb_desc, "t 1,s\n", 6); */ -/* OBSOLETE /* Wait for the echo. */ */ -/* OBSOLETE expect ("t 1,s\r"); */ -/* OBSOLETE /* Then comes a line containing the instruction we stepped to. */ */ -/* OBSOLETE expect ("\n@"); */ -/* OBSOLETE /* Then we get the prompt. */ */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE /* Force the next eb_wait to return a trap. Not doing anything */ -/* OBSOLETE about I/O from the target means that the user has to type */ -/* OBSOLETE "continue" to see any. This should be fixed. */ */ -/* OBSOLETE need_artificial_trap = 1; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE if (need_gi) */ -/* OBSOLETE { */ -/* OBSOLETE need_gi = 0; */ -/* OBSOLETE write (eb_desc, "gi\n", 3); */ -/* OBSOLETE */ -/* OBSOLETE /* Swallow the echo of "gi". */ */ -/* OBSOLETE expect ("gi\r"); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE write (eb_desc, "GR\n", 3); */ -/* OBSOLETE /* Swallow the echo. */ */ -/* OBSOLETE expect ("GR\r"); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Wait until the remote machine stops, then return, */ -/* OBSOLETE storing status in STATUS just as `wait' would. */ */ -/* OBSOLETE */ -/* OBSOLETE ptid_t */ -/* OBSOLETE eb_wait (ptid_t ptid, struct target_waitstatus *status) */ -/* OBSOLETE { */ -/* OBSOLETE /* Strings to look for. '?' means match any single character. */ -/* OBSOLETE Note that with the algorithm we use, the initial character */ -/* OBSOLETE of the string cannot recur in the string, or we will not */ -/* OBSOLETE find some cases of the string in the input. */ */ -/* OBSOLETE */ -/* OBSOLETE static char bpt[] = "Invalid interrupt taken - #0x50 - "; */ -/* OBSOLETE /* It would be tempting to look for "\n[__exit + 0x8]\n" */ -/* OBSOLETE but that requires loading symbols with "yc i" and even if */ -/* OBSOLETE we did do that we don't know that the file has symbols. */ */ -/* OBSOLETE static char exitmsg[] = "\n@????????I JMPTI GR121,LR0"; */ -/* OBSOLETE char *bp = bpt; */ -/* OBSOLETE char *ep = exitmsg; */ -/* OBSOLETE */ -/* OBSOLETE /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */ */ -/* OBSOLETE char swallowed[50]; */ -/* OBSOLETE /* Current position in swallowed. */ */ -/* OBSOLETE char *swallowed_p = swallowed; */ -/* OBSOLETE */ -/* OBSOLETE int ch; */ -/* OBSOLETE int ch_handled; */ -/* OBSOLETE */ -/* OBSOLETE int old_timeout = timeout; */ -/* OBSOLETE */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE */ -/* OBSOLETE if (need_artificial_trap != 0) */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE need_artificial_trap--; */ -/* OBSOLETE return 0; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE timeout = 0; /* Don't time out -- user program is running. */ */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE ch_handled = 0; */ -/* OBSOLETE ch = readchar (); */ -/* OBSOLETE if (ch == *bp) */ -/* OBSOLETE { */ -/* OBSOLETE bp++; */ -/* OBSOLETE if (*bp == '\0') */ -/* OBSOLETE break; */ -/* OBSOLETE ch_handled = 1; */ -/* OBSOLETE */ -/* OBSOLETE *swallowed_p++ = ch; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE bp = bpt; */ -/* OBSOLETE */ -/* OBSOLETE if (ch == *ep || *ep == '?') */ -/* OBSOLETE { */ -/* OBSOLETE ep++; */ -/* OBSOLETE if (*ep == '\0') */ -/* OBSOLETE break; */ -/* OBSOLETE */ -/* OBSOLETE if (!ch_handled) */ -/* OBSOLETE *swallowed_p++ = ch; */ -/* OBSOLETE ch_handled = 1; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE ep = exitmsg; */ -/* OBSOLETE */ -/* OBSOLETE if (!ch_handled) */ -/* OBSOLETE { */ -/* OBSOLETE char *p; */ -/* OBSOLETE */ -/* OBSOLETE /* Print out any characters which have been swallowed. */ */ -/* OBSOLETE for (p = swallowed; p < swallowed_p; ++p) */ -/* OBSOLETE putc (*p, stdout); */ -/* OBSOLETE swallowed_p = swallowed; */ -/* OBSOLETE */ -/* OBSOLETE putc (ch, stdout); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE if (*bp == '\0') */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE } */ -/* OBSOLETE timeout = old_timeout; */ -/* OBSOLETE */ -/* OBSOLETE return 0; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Return the name of register number REGNO */ -/* OBSOLETE in the form input and output by EBMON. */ -/* OBSOLETE */ -/* OBSOLETE Returns a pointer to a static buffer containing the answer. */ */ -/* OBSOLETE static char * */ -/* OBSOLETE get_reg_name (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE static char buf[80]; */ -/* OBSOLETE if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) */ -/* OBSOLETE sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96); */ -/* OBSOLETE else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) */ -/* OBSOLETE sprintf (buf, "LR%03d", regno - LR0_REGNUM); */ -/* OBSOLETE else if (regno == Q_REGNUM) */ -/* OBSOLETE strcpy (buf, "SR131"); */ -/* OBSOLETE else if (regno >= BP_REGNUM && regno <= CR_REGNUM) */ -/* OBSOLETE sprintf (buf, "SR%03d", regno - BP_REGNUM + 133); */ -/* OBSOLETE else if (regno == ALU_REGNUM) */ -/* OBSOLETE strcpy (buf, "SR132"); */ -/* OBSOLETE else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM) */ -/* OBSOLETE sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128); */ -/* OBSOLETE else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM) */ -/* OBSOLETE sprintf (buf, "SR%03d", regno - VAB_REGNUM); */ -/* OBSOLETE else if (regno == GR1_REGNUM) */ -/* OBSOLETE strcpy (buf, "GR001"); */ -/* OBSOLETE return buf; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Read the remote registers into the block REGS. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE eb_fetch_registers (void) */ -/* OBSOLETE { */ -/* OBSOLETE int reg_index; */ -/* OBSOLETE int regnum_index; */ -/* OBSOLETE char tempbuf[10]; */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE #if 0 */ -/* OBSOLETE /* This should not be necessary, because one is supposed to read the */ -/* OBSOLETE registers only when the inferior is stopped (at least with */ -/* OBSOLETE ptrace() and why not make it the same for remote?). */ */ -/* OBSOLETE /* ^A is the "normal character" used to make sure we are talking to EBMON */ -/* OBSOLETE and not to the program being debugged. */ */ -/* OBSOLETE write (eb_desc, "\001\n"); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE write (eb_desc, "dw gr96,gr127\n", 14); */ -/* OBSOLETE for (reg_index = 96, regnum_index = GR96_REGNUM; */ -/* OBSOLETE reg_index < 128; */ -/* OBSOLETE reg_index += 4, regnum_index += 4) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (tempbuf, "GR%03d ", reg_index); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE get_hex_regs (4, regnum_index); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; i < 128; i += 32) */ -/* OBSOLETE { */ -/* OBSOLETE /* The PC has a tendency to hang if we get these */ -/* OBSOLETE all in one fell swoop ("dw lr0,lr127"). */ */ -/* OBSOLETE sprintf (tempbuf, "dw lr%d\n", i); */ -/* OBSOLETE write (eb_desc, tempbuf, strlen (tempbuf)); */ -/* OBSOLETE for (reg_index = i, regnum_index = LR0_REGNUM + i; */ -/* OBSOLETE reg_index < i + 32; */ -/* OBSOLETE reg_index += 4, regnum_index += 4) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (tempbuf, "LR%03d ", reg_index); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE get_hex_regs (4, regnum_index); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE write (eb_desc, "dw sr133,sr133\n", 15); */ -/* OBSOLETE expect ("SR133 "); */ -/* OBSOLETE get_hex_regs (1, BP_REGNUM); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE */ -/* OBSOLETE write (eb_desc, "dw sr134,sr134\n", 15); */ -/* OBSOLETE expect ("SR134 "); */ -/* OBSOLETE get_hex_regs (1, FC_REGNUM); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE */ -/* OBSOLETE write (eb_desc, "dw sr135,sr135\n", 15); */ -/* OBSOLETE expect ("SR135 "); */ -/* OBSOLETE get_hex_regs (1, CR_REGNUM); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE */ -/* OBSOLETE write (eb_desc, "dw sr131,sr131\n", 15); */ -/* OBSOLETE expect ("SR131 "); */ -/* OBSOLETE get_hex_regs (1, Q_REGNUM); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE */ -/* OBSOLETE write (eb_desc, "dw sr0,sr14\n", 12); */ -/* OBSOLETE for (reg_index = 0, regnum_index = VAB_REGNUM; */ -/* OBSOLETE regnum_index <= LRU_REGNUM; */ -/* OBSOLETE regnum_index += 4, reg_index += 4) */ -/* OBSOLETE { */ -/* OBSOLETE sprintf (tempbuf, "SR%03d ", reg_index); */ -/* OBSOLETE expect (tempbuf); */ -/* OBSOLETE get_hex_regs (reg_index == 12 ? 3 : 4, regnum_index); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* There doesn't seem to be any way to get these. */ */ -/* OBSOLETE { */ -/* OBSOLETE int val = -1; */ -/* OBSOLETE supply_register (FPE_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (INTE_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (FPS_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (EXO_REGNUM, (char *) &val); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE write (eb_desc, "dw gr1,gr1\n", 11); */ -/* OBSOLETE expect ("GR001 "); */ -/* OBSOLETE get_hex_regs (1, GR1_REGNUM); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Fetch register REGNO, or all registers if REGNO is -1. */ -/* OBSOLETE Returns errno value. */ */ -/* OBSOLETE void */ -/* OBSOLETE eb_fetch_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE if (regno == -1) */ -/* OBSOLETE eb_fetch_registers (); */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE char *name = get_reg_name (regno); */ -/* OBSOLETE fprintf (eb_stream, "dw %s,%s\n", name, name); */ -/* OBSOLETE expect (name); */ -/* OBSOLETE expect (" "); */ -/* OBSOLETE get_hex_regs (1, regno); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Store the remote registers from the contents of the block REGS. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE eb_store_registers (void) */ -/* OBSOLETE { */ -/* OBSOLETE int i, j; */ -/* OBSOLETE fprintf (eb_stream, "s gr1,%x\n", read_register (GR1_REGNUM)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE for (j = 0; j < 32; j += 16) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (eb_stream, "s gr%d,", j + 96); */ -/* OBSOLETE for (i = 0; i < 15; ++i) */ -/* OBSOLETE fprintf (eb_stream, "%x,", read_register (GR96_REGNUM + j + i)); */ -/* OBSOLETE fprintf (eb_stream, "%x\n", read_register (GR96_REGNUM + j + 15)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE for (j = 0; j < 128; j += 16) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (eb_stream, "s lr%d,", j); */ -/* OBSOLETE for (i = 0; i < 15; ++i) */ -/* OBSOLETE fprintf (eb_stream, "%x,", read_register (LR0_REGNUM + j + i)); */ -/* OBSOLETE fprintf (eb_stream, "%x\n", read_register (LR0_REGNUM + j + 15)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE fprintf (eb_stream, "s sr133,%x,%x,%x\n", read_register (BP_REGNUM), */ -/* OBSOLETE read_register (FC_REGNUM), read_register (CR_REGNUM)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE fprintf (eb_stream, "s sr131,%x\n", read_register (Q_REGNUM)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE fprintf (eb_stream, "s sr0,"); */ -/* OBSOLETE for (i = 0; i < 11; ++i) */ -/* OBSOLETE fprintf (eb_stream, "%x,", read_register (VAB_REGNUM + i)); */ -/* OBSOLETE fprintf (eb_stream, "%x\n", read_register (VAB_REGNUM + 11)); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Store register REGNO, or all if REGNO == 0. */ -/* OBSOLETE Return errno value. */ */ -/* OBSOLETE void */ -/* OBSOLETE eb_store_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE if (regno == -1) */ -/* OBSOLETE eb_store_registers (); */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE char *name = get_reg_name (regno); */ -/* OBSOLETE fprintf (eb_stream, "s %s,%x\n", name, read_register (regno)); */ -/* OBSOLETE /* Setting GR1 changes the numbers of all the locals, so */ -/* OBSOLETE invalidate the register cache. Do this *after* calling */ -/* OBSOLETE read_register, because we want read_register to return the */ -/* OBSOLETE value that write_register has just stuffed into the registers */ -/* OBSOLETE array, not the value of the register fetched from the */ -/* OBSOLETE inferior. */ */ -/* OBSOLETE if (regno == GR1_REGNUM) */ -/* OBSOLETE registers_changed (); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Get ready to modify the registers array. On machines which store */ -/* OBSOLETE individual registers, this doesn't need to do anything. On machines */ -/* OBSOLETE which store all the registers in one fell swoop, this makes sure */ -/* OBSOLETE that registers contains all the registers from the program being */ -/* OBSOLETE debugged. */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE eb_prepare_to_store (void) */ -/* OBSOLETE { */ -/* OBSOLETE /* Do nothing, since we can store individual regs */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Transfer LEN bytes between GDB address MYADDR and target address */ -/* OBSOLETE MEMADDR. If WRITE is non-zero, transfer them to the target, */ -/* OBSOLETE otherwise transfer them from the target. TARGET is unused. */ -/* OBSOLETE */ -/* OBSOLETE Returns the number of bytes transferred. */ */ -/* OBSOLETE */ -/* OBSOLETE int */ -/* OBSOLETE eb_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, */ -/* OBSOLETE struct mem_attrib *attrib ATTRIBUTE_UNUSED, */ -/* OBSOLETE struct target_ops *target ATTRIBUTE_UNUSED) */ -/* OBSOLETE { */ -/* OBSOLETE if (write) */ -/* OBSOLETE return eb_write_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE else */ -/* OBSOLETE return eb_read_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE eb_files_info (void) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("\tAttached to %s at %d baud and running program %s.\n", */ -/* OBSOLETE dev_name, baudrate, prog_name); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Copy LEN bytes of data from debugger memory at MYADDR */ -/* OBSOLETE to inferior's memory at MEMADDR. Returns length moved. */ */ -/* OBSOLETE int */ -/* OBSOLETE eb_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; i < len; i++) */ -/* OBSOLETE { */ -/* OBSOLETE if ((i % 16) == 0) */ -/* OBSOLETE fprintf (eb_stream, "sb %x,", memaddr + i); */ -/* OBSOLETE if ((i % 16) == 15 || i == len - 1) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf (eb_stream, "%x\n", ((unsigned char *) myaddr)[i]); */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE fprintf (eb_stream, "%x,", ((unsigned char *) myaddr)[i]); */ -/* OBSOLETE } */ -/* OBSOLETE return len; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Read LEN bytes from inferior memory at MEMADDR. Put the result */ -/* OBSOLETE at debugger address MYADDR. Returns length moved. */ */ -/* OBSOLETE int */ -/* OBSOLETE eb_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE /* Number of bytes read so far. */ */ -/* OBSOLETE int count; */ -/* OBSOLETE */ -/* OBSOLETE /* Starting address of this pass. */ */ -/* OBSOLETE unsigned long startaddr; */ -/* OBSOLETE */ -/* OBSOLETE /* Number of bytes to read in this pass. */ */ -/* OBSOLETE int len_this_pass; */ -/* OBSOLETE */ -/* OBSOLETE /* Note that this code works correctly if startaddr is just less */ -/* OBSOLETE than UINT_MAX (well, really CORE_ADDR_MAX if there was such a */ -/* OBSOLETE thing). That is, something like */ -/* OBSOLETE eb_read_bytes (CORE_ADDR_MAX - 4, foo, 4) */ -/* OBSOLETE works--it never adds len to memaddr and gets 0. */ */ -/* OBSOLETE /* However, something like */ -/* OBSOLETE eb_read_bytes (CORE_ADDR_MAX - 3, foo, 4) */ -/* OBSOLETE doesn't need to work. Detect it and give up if there's an attempt */ -/* OBSOLETE to do that. */ */ -/* OBSOLETE if (((memaddr - 1) + len) < memaddr) */ -/* OBSOLETE { */ -/* OBSOLETE errno = EIO; */ -/* OBSOLETE return 0; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE startaddr = memaddr; */ -/* OBSOLETE count = 0; */ -/* OBSOLETE while (count < len) */ -/* OBSOLETE { */ -/* OBSOLETE len_this_pass = 16; */ -/* OBSOLETE if ((startaddr % 16) != 0) */ -/* OBSOLETE len_this_pass -= startaddr % 16; */ -/* OBSOLETE if (len_this_pass > (len - count)) */ -/* OBSOLETE len_this_pass = (len - count); */ -/* OBSOLETE */ -/* OBSOLETE fprintf (eb_stream, "db %x,%x\n", startaddr, */ -/* OBSOLETE (startaddr - 1) + len_this_pass); */ -/* OBSOLETE expect ("\n"); */ -/* OBSOLETE */ -/* OBSOLETE /* Look for 8 hex digits. */ */ -/* OBSOLETE i = 0; */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE if (isxdigit (readchar ())) */ -/* OBSOLETE ++i; */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE error ("Hex digit expected from remote system."); */ -/* OBSOLETE } */ -/* OBSOLETE if (i >= 8) */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE expect (" "); */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; i < len_this_pass; i++) */ -/* OBSOLETE get_hex_byte (&myaddr[count++]); */ -/* OBSOLETE */ -/* OBSOLETE expect_prompt (); */ -/* OBSOLETE */ -/* OBSOLETE startaddr += len_this_pass; */ -/* OBSOLETE } */ -/* OBSOLETE return len; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE eb_kill (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE return; /* Ignore attempts to kill target system */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Clean up when a program exits. */ -/* OBSOLETE */ -/* OBSOLETE The program actually lives on in the remote processor's RAM, and may be */ -/* OBSOLETE run again without a download. Don't leave it full of breakpoint */ -/* OBSOLETE instructions. */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE eb_mourn_inferior (void) */ -/* OBSOLETE { */ -/* OBSOLETE remove_breakpoints (); */ -/* OBSOLETE unpush_target (&eb_ops); */ -/* OBSOLETE generic_mourn_inferior (); /* Do all the proper things now */ */ -/* OBSOLETE } */ -/* OBSOLETE /* Define the target subroutine names */ */ -/* OBSOLETE */ -/* OBSOLETE struct target_ops eb_ops; */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE init_eb_ops (void) */ -/* OBSOLETE { */ -/* OBSOLETE eb_ops.to_shortname = "amd-eb"; */ -/* OBSOLETE eb_ops.to_longname = "Remote serial AMD EBMON target"; */ -/* OBSOLETE eb_ops.to_doc = "Use a remote computer running EBMON connected by a serial line.\n\ */ -/* OBSOLETE Arguments are the name of the device for the serial line,\n\ */ -/* OBSOLETE the speed to connect at in bits per second, and the filename of the\n\ */ -/* OBSOLETE executable as it exists on the remote computer. For example,\n\ */ -/* OBSOLETE target amd-eb /dev/ttya 9600 demo", */ -/* OBSOLETE eb_ops.to_open = eb_open; */ -/* OBSOLETE eb_ops.to_close = eb_close; */ -/* OBSOLETE eb_ops.to_attach = 0; */ -/* OBSOLETE eb_ops.to_post_attach = NULL; */ -/* OBSOLETE eb_ops.to_require_attach = NULL; */ -/* OBSOLETE eb_ops.to_detach = eb_detach; */ -/* OBSOLETE eb_ops.to_require_detach = NULL; */ -/* OBSOLETE eb_ops.to_resume = eb_resume; */ -/* OBSOLETE eb_ops.to_wait = eb_wait; */ -/* OBSOLETE eb_ops.to_post_wait = NULL; */ -/* OBSOLETE eb_ops.to_fetch_registers = eb_fetch_register; */ -/* OBSOLETE eb_ops.to_store_registers = eb_store_register; */ -/* OBSOLETE eb_ops.to_prepare_to_store = eb_prepare_to_store; */ -/* OBSOLETE eb_ops.to_xfer_memory = eb_xfer_inferior_memory; */ -/* OBSOLETE eb_ops.to_files_info = eb_files_info; */ -/* OBSOLETE eb_ops.to_insert_breakpoint = 0; */ -/* OBSOLETE eb_ops.to_remove_breakpoint = 0; /* Breakpoints */ */ -/* OBSOLETE eb_ops.to_terminal_init = 0; */ -/* OBSOLETE eb_ops.to_terminal_inferior = 0; */ -/* OBSOLETE eb_ops.to_terminal_ours_for_output = 0; */ -/* OBSOLETE eb_ops.to_terminal_ours = 0; */ -/* OBSOLETE eb_ops.to_terminal_info = 0; /* Terminal handling */ */ -/* OBSOLETE eb_ops.to_kill = eb_kill; */ -/* OBSOLETE eb_ops.to_load = generic_load; /* load */ */ -/* OBSOLETE eb_ops.to_lookup_symbol = 0; /* lookup_symbol */ */ -/* OBSOLETE eb_ops.to_create_inferior = eb_create_inferior; */ -/* OBSOLETE eb_ops.to_post_startup_inferior = NULL; */ -/* OBSOLETE eb_ops.to_acknowledge_created_inferior = NULL; */ -/* OBSOLETE eb_ops.to_clone_and_follow_inferior = NULL; */ -/* OBSOLETE eb_ops.to_post_follow_inferior_by_clone = NULL; */ -/* OBSOLETE eb_ops.to_insert_fork_catchpoint = NULL; */ -/* OBSOLETE eb_ops.to_remove_fork_catchpoint = NULL; */ -/* OBSOLETE eb_ops.to_insert_vfork_catchpoint = NULL; */ -/* OBSOLETE eb_ops.to_remove_vfork_catchpoint = NULL; */ -/* OBSOLETE eb_ops.to_has_forked = NULL; */ -/* OBSOLETE eb_ops.to_has_vforked = NULL; */ -/* OBSOLETE eb_ops.to_can_follow_vfork_prior_to_exec = NULL; */ -/* OBSOLETE eb_ops.to_post_follow_vfork = NULL; */ -/* OBSOLETE eb_ops.to_insert_exec_catchpoint = NULL; */ -/* OBSOLETE eb_ops.to_remove_exec_catchpoint = NULL; */ -/* OBSOLETE eb_ops.to_has_execd = NULL; */ -/* OBSOLETE eb_ops.to_reported_exec_events_per_exec_call = NULL; */ -/* OBSOLETE eb_ops.to_has_exited = NULL; */ -/* OBSOLETE eb_ops.to_mourn_inferior = eb_mourn_inferior; */ -/* OBSOLETE eb_ops.to_can_run = 0; /* can_run */ */ -/* OBSOLETE eb_ops.to_notice_signals = 0; /* notice_signals */ */ -/* OBSOLETE eb_ops.to_thread_alive = 0; /* thread-alive */ */ -/* OBSOLETE eb_ops.to_stop = 0; /* to_stop */ */ -/* OBSOLETE eb_ops.to_pid_to_exec_file = NULL; */ -/* OBSOLETE eb_ops.to_stratum = process_stratum; */ -/* OBSOLETE eb_ops.DONT_USE = 0; /* next */ */ -/* OBSOLETE eb_ops.to_has_all_memory = 1; */ -/* OBSOLETE eb_ops.to_has_memory = 1; */ -/* OBSOLETE eb_ops.to_has_stack = 1; */ -/* OBSOLETE eb_ops.to_has_registers = 1; */ -/* OBSOLETE eb_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */ */ -/* OBSOLETE eb_ops.to_sections = 0; /* sections */ */ -/* OBSOLETE eb_ops.to_sections_end = 0; /* sections end */ */ -/* OBSOLETE eb_ops.to_magic = OPS_MAGIC; /* Always the last thing */ */ -/* OBSOLETE }; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE _initialize_remote_eb (void) */ -/* OBSOLETE { */ -/* OBSOLETE init_eb_ops (); */ -/* OBSOLETE add_target (&eb_ops); */ -/* OBSOLETE } */ diff --git a/contrib/gdb/gdb/remote-es.c b/contrib/gdb/gdb/remote-es.c deleted file mode 100644 index dabbcd8b91f..00000000000 --- a/contrib/gdb/gdb/remote-es.c +++ /dev/null @@ -1,2127 +0,0 @@ -/* Memory-access and commands for remote es1800 processes, for GDB. - - Copyright 1988, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. - - This file is added to GDB to make it possible to do debugging via an - ES-1800 emulator. The code was originally written by Johan Holmberg - TT/SJ Ericsson Telecom AB and later modified by Johan Henriksson - TT/SJ. It was modified for gdb 4.0 by TX/DK Jan Nordenand by TX/DKG - Harald Johansen. - - This file is part of GDB. - - GDB is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - GDB is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -/* Emulator communication protocol. - All values are encoded in ascii hex digits. - - Request - Command - Reply - read registers: - DR - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - -- 6 - - 7 - - D = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX - A = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX - PC = XXXXXX SSP = XXXXXX USP = XXXXXX SR = XXXXXXXX - > - Each byte of register data is described by two hex digits. - - write regs - D0=XXXXXXXX - >D1=XXXXXXXX - >D2=XXXXXXXX - >D3=XXXXXXXX - >D4=XXXXXXXX - >D5=XXXXXXXX - >D6=XXXXXXXX - >D7=XXXXXXXX - >A0=XXXXXXXX - >A1=XXXXXXXX - >A2=XXXXXXXX - >A3=XXXXXXXX - >A4=XXXXXXXX - >A5=XXXXXXXX - >A6=XXXXXXXX - >A7=XXXXXXXX - >SR=XXXXXXXX - >PC=XXXXXX - > - Each byte of register data is described by two hex digits. - - read mem - @.BAA..AA - $FFFFFFXX - > - AA..AA is address, XXXXXXX is the contents - - write mem - @.BAA..AA=$XXXXXXXX - > - AA..AA is address, XXXXXXXX is data - - cont - PC=$AA..AA - >RBK - R> - AA..AA is address to resume. If AA..AA is omitted, resume at same address. - - step - PC=$AA..AA - >STP - R> - AA..AA is address to resume. If AA..AA is omitted, resume at same address. - - kill req - STP - > - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "defs.h" -#include "gdb_string.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "command.h" -#include "symfile.h" -#include "remote-utils.h" -#include "gdbcore.h" -#include "serial.h" -#include "regcache.h" -#include "value.h" - -/* Prototypes for local functions */ - -static void es1800_child_detach (char *, int); - -static void es1800_child_open (char *, int); - -static void es1800_transparent (char *, int); - -static void es1800_create_inferior (char *, char *, char **); - -static void es1800_load (char *, int); - -static void es1800_kill (void); - -static int verify_break (int); - -static int es1800_remove_breakpoint (CORE_ADDR, char *); - -static int es1800_insert_breakpoint (CORE_ADDR, char *); - -static void es1800_files_info (struct target_ops *); - -static int -es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int, - struct mem_attrib *, struct target_ops *); - -static void es1800_prepare_to_store (void); - -static ptid_t es1800_wait (ptid_t, struct target_waitstatus *); - -static void es1800_resume (ptid_t, int, enum target_signal); - -static void es1800_detach (char *, int); - -static void es1800_attach (char *, int); - -static int damn_b (char *); - -static void es1800_open (char *, int); - -static void es1800_timer (void); - -static void es1800_reset (char *); - -static void es1800_request_quit (void); - -static int readchar (void); - -static void expect (char *, int); - -static void expect_prompt (void); - -static void download (FILE *, int, int); - -#if 0 -static void bfd_copy (bfd *, bfd *); -#endif - -static void get_break_addr (int, CORE_ADDR *); - -static int fromhex (int); - -static int tohex (int); - -static void es1800_close (int); - -static void es1800_fetch_registers (void); - -static void es1800_fetch_register (int); - -static void es1800_store_register (int); - -static void es1800_read_bytes (CORE_ADDR, char *, int); - -static void es1800_write_bytes (CORE_ADDR, char *, int); - -static void send_with_reply (char *, char *, int); - -static void send_command (char *); - -static void send (char *); - -static void getmessage (char *, int); - -static void es1800_mourn_inferior (void); - -static void es1800_create_break_insn (char *, int); - -static void es1800_init_break (char *, int); - -/* Local variables */ - -/* FIXME: Convert this to use "set remotedebug" instead. */ -#define LOG_FILE "es1800.log" -#if defined (LOG_FILE) -static FILE *log_file; -#endif - -extern struct target_ops es1800_ops; /* Forward decl */ -extern struct target_ops es1800_child_ops; /* Forward decl */ - -static int kiodebug; -static int timeout = 100; -static char *savename; /* Name of i/o device used */ -static serial_ttystate es1800_saved_ttystate; -static int es1800_fc_save; /* Save fcntl state */ - -/* indicates that the emulator uses 32-bit data-adress (68020-mode) - instead of 24-bit (68000 -mode) */ - -static int m68020; - -#define MODE (m68020 ? "M68020" : "M68000" ) -#define ES1800_BREAK_VEC (0xf) - -/* Descriptor for I/O to remote machine. Initialize it to NULL so that - es1800_open knows that we don't have a file open when the program - starts. */ - -static struct serial *es1800_desc = NULL; - -#define PBUFSIZ 1000 -#define HDRLEN sizeof("@.BAAAAAAAA=$VV\r") - -/* Maximum number of bytes to read/write at once. The value here - is chosen to fill up a packet. */ - -#define MAXBUFBYTES ((PBUFSIZ-150)*16/75 ) - -static int es1800_break_vec = 0; -static char es1800_break_insn[2]; -static long es1800_break_address; -static void (*old_sigint) (); /* Old signal-handler for sigint */ -static jmp_buf interrupt; - -/* Local signalhandler to allow breaking tranfers or program run. - Rely on global variables: old_sigint(), interrupt */ - -static void -es1800_request_quit (void) -{ - /* restore original signalhandler */ - signal (SIGINT, old_sigint); - longjmp (interrupt, 1); -} - - -/* Reset emulator. - Sending reset character(octal 32) to emulator. - quit - return to '(esgdb)' prompt or continue */ - -static void -es1800_reset (char *quit) -{ - char buf[80]; - - if (quit) - { - printf ("\nResetting emulator... "); - } - strcpy (buf, "\032"); - send (buf); - expect_prompt (); - if (quit) - { - error ("done\n"); - } -} - - -/* Open a connection to a remote debugger and push the new target - onto the stack. Check if the emulator is responding and find out - what kind of processor the emulator is connected to. - Initiate the breakpoint handling in the emulator. - - name - the filename used for communication (ex. '/dev/tta') - from_tty - says whether to be verbose or not */ - -static void -es1800_open (char *name, int from_tty) -{ - char buf[PBUFSIZ]; - char *p; - int i, fcflag; - - m68020 = 0; - - if (!name) /* no device name given in target command */ - { - error_no_arg ("serial port device name"); - } - - target_preopen (from_tty); - es1800_close (0); - - /* open the device and configure it for communication */ - -#ifndef DEBUG_STDIN - - es1800_desc = serial_open (name); - if (es1800_desc == NULL) - { - perror_with_name (name); - } - savename = savestring (name, strlen (name)); - - es1800_saved_ttystate = serial_get_tty_state (es1800_desc); - - if ((fcflag = fcntl (deprecated_serial_fd (es1800_desc), F_GETFL, 0)) == -1) - { - perror_with_name ("fcntl serial"); - } - es1800_fc_save = fcflag; - - fcflag = (fcflag & (FREAD | FWRITE)); /* mask out any funny stuff */ - if (fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, fcflag) == -1) - { - perror_with_name ("fcntl serial"); - } - - if (baud_rate != -1) - { - if (serial_setbaudrate (es1800_desc, baud_rate)) - { - serial_close (es1800_desc); - perror_with_name (name); - } - } - - serial_raw (es1800_desc); - - /* If there is something sitting in the buffer we might take it as a - response to a command, which would be bad. */ - serial_flush_input (es1800_desc); - -#endif /* DEBUG_STDIN */ - - push_target (&es1800_ops); /* Switch to using remote target now */ - if (from_tty) - { - printf ("Remote ES1800 debugging using %s\n", name); - } - -#if defined (LOG_FILE) - - log_file = fopen (LOG_FILE, "w"); - if (log_file == NULL) - { - perror_with_name (LOG_FILE); - } - -#endif /* LOG_FILE */ - - /* Hello? Are you there?, also check mode */ - - /* send_with_reply( "DB 0 TO 1", buf, sizeof(buf)); */ - /* for (p = buf, i = 0; *p++ =='0';) *//* count the number of zeros */ - /* i++; */ - - send ("\032"); - getmessage (buf, sizeof (buf)); /* send reset character */ - - if (from_tty) - { - printf ("Checking mode.... "); - } - /* m68020 = (i==8); *//* if eight zeros then we are in m68020 mode */ - - /* What kind of processor am i talking to ? */ - p = buf; - while (*p++ != '\n') - {; - } - while (*p++ != '\n') - {; - } - while (*p++ != '\n') - {; - } - for (i = 0; i < 20; i++, p++) - {; - } - m68020 = !strncmp (p, "68020", 5); - if (from_tty) - { - printf ("You are in %s(%c%c%c%c%c)-mode\n", MODE, p[0], p[1], p[2], - p[3], p[4]); - } - - /* if no init_break statement is present in .gdb file we have to check - whether to download a breakpoint routine or not */ - -#if 0 - if ((es1800_break_vec == 0) || (verify_break (es1800_break_vec) != 0) - && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? ")) - { - CORE_ADDR memaddress; - printf ("Give the start address of the breakpoint routine: "); - scanf ("%li", &memaddress); - es1800_init_break ((es1800_break_vec ? es1800_break_vec : - ES1800_BREAK_VEC), memaddress); - } -#endif - -} - -/* Close out all files and local state before this target loses control. - quitting - are we quitting gdb now? */ - -static void -es1800_close (int quitting) -{ - if (es1800_desc != NULL) - { - printf ("\nClosing connection to emulator...\n"); - if (serial_set_tty_state (es1800_desc, es1800_saved_ttystate) < 0) - print_sys_errmsg ("warning: unable to restore tty state", errno); - fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, es1800_fc_save); - serial_close (es1800_desc); - es1800_desc = NULL; - } - if (savename != NULL) - { - xfree (savename); - } - savename = NULL; - -#if defined (LOG_FILE) - - if (log_file != NULL) - { - if (ferror (log_file)) - { - printf ("Error writing log file.\n"); - } - if (fclose (log_file) != 0) - { - printf ("Error closing log file.\n"); - } - log_file = NULL; - } - -#endif /* LOG_FILE */ - -} - -/* Attaches to a process on the target side - proc_id - the id of the process to be attached. - from_tty - says whether to be verbose or not */ - -static void -es1800_attach (char *args, int from_tty) -{ - error ("Cannot attach to pid %s, this feature is not implemented yet.", - args); -} - - -/* Takes a program previously attached to and detaches it. - We better not have left any breakpoints - in the program or it'll die when it hits one. - Close the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. - - args - arguments given to the 'detach' command - from_tty - says whether to be verbose or not */ - -static void -es1800_detach (char *args, int from_tty) -{ - if (args) - { - error ("Argument given to \"detach\" when remotely debugging."); - } - pop_target (); - if (from_tty) - { - printf ("Ending es1800 remote debugging.\n"); - } -} - - -/* Tell the remote machine to resume. - step - single-step or run free - siggnal - the signal value to be given to the target (0 = no signal) */ - -static void -es1800_resume (ptid_t ptid, int step, enum target_signal siggnal) -{ - char buf[PBUFSIZ]; - - if (siggnal) - { - error ("Can't send signals to a remote system."); - } - if (step) - { - strcpy (buf, "STP\r"); - send (buf); - } - else - { - send_command ("RBK"); - } -} - -/* Wait until the remote machine stops, then return, - storing status in STATUS just as `wait' would. - status - */ - -static ptid_t -es1800_wait (ptid_t ptid, struct target_waitstatus *status) -{ - unsigned char buf[PBUFSIZ]; - int old_timeout = timeout; - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - timeout = 0; /* Don't time out -- user program is running. */ - if (!setjmp (interrupt)) - { - old_sigint = signal (SIGINT, es1800_request_quit); - while (1) - { - getmessage (buf, sizeof (buf)); - if (strncmp (buf, "\r\n* BREAK *", 11) == 0) - { - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - send_command ("STP"); /* Restore stack and PC and such */ - if (m68020) - { - send_command ("STP"); - } - break; - } - if (strncmp (buf, "STP\r\n ", 6) == 0) - { - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - break; - } - if (buf[strlen (buf) - 2] == 'R') - { - printf ("Unexpected emulator reply: \n%s\n", buf); - } - else - { - printf ("Unexpected stop: \n%s\n", buf); - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_QUIT; - break; - } - } - } - else - { - fflush (stdin); - printf ("\nStopping emulator..."); - if (!setjmp (interrupt)) - { - old_sigint = signal (SIGINT, es1800_request_quit); - send_command ("STP"); - printf (" emulator stopped\n"); - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_INT; - } - else - { - fflush (stdin); - es1800_reset ((char *) 1); - } - } - signal (SIGINT, old_sigint); - timeout = old_timeout; - return inferior_ptid; -} - - -/* Fetch register values from remote machine. - regno - the register to be fetched (fetch all registers if -1) */ - -static void -es1800_fetch_register (int regno) -{ - char buf[PBUFSIZ]; - int k; - int r; - char *p; - static char regtab[18][4] = - { - "D0 ", "D1 ", "D2 ", "D3 ", "D4 ", "D5 ", "D6 ", "D7 ", - "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", "A6 ", "SSP", - "SR ", "PC " - }; - - if ((regno < 15) || (regno == 16) || (regno == 17)) - { - r = regno * 4; - send_with_reply (regtab[regno], buf, sizeof (buf)); - p = buf; - for (k = 0; k < 4; k++) - { - if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0)) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]); - } - } - else - { - es1800_fetch_registers (); - } -} - -/* Read the remote registers into REGISTERS. - Always fetches all registers. */ - -static void -es1800_fetch_registers (void) -{ - char buf[PBUFSIZ]; - char SR_buf[PBUFSIZ]; - int i; - int k; - int r; - char *p; - - send_with_reply ("DR", buf, sizeof (buf)); - - /* Reply is edited to a string that describes registers byte by byte, - each byte encoded as two hex characters. */ - - p = buf; - r = 0; - - /* parsing row one - D0-D7-registers */ - - while (*p++ != '\n') - {; - } - for (i = 4; i < 70; i += (i == 39 ? 3 : 1)) - { - for (k = 0; k < 4; k++) - { - if (p[i + 0] == 0 || p[i + 1] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = (fromhex (p[i + 0]) * 16) + fromhex (p[i + 1]); - i += 2; - } - } - p += i; - - /* parsing row two - A0-A6-registers */ - - while (*p++ != '\n') - {; - } - for (i = 4; i < 61; i += (i == 39 ? 3 : 1)) - { - for (k = 0; k < 4; k++) - { - if (p[i + 0] == 0 || p[i + 1] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = (fromhex (p[i + 0])) * 16 + fromhex (p[i + 1]); - i += 2; - } - } - p += i; - - while (*p++ != '\n') - {; - } - - /* fetch SSP-, SR- and PC-registers */ - - /* first - check STATUS-word and decide which stackpointer to use */ - - send_with_reply ("SR", SR_buf, sizeof (SR_buf)); - p = SR_buf; - p += 5; - - if (m68020) - { - if (*p == '3') /* use masterstackpointer MSP */ - { - send_with_reply ("MSP", buf, sizeof (buf)); - } - else if (*p == '2') /* use interruptstackpointer ISP */ - { - send_with_reply ("ISP", buf, sizeof (buf)); - } - else - /* use userstackpointer USP */ - { - send_with_reply ("USP", buf, sizeof (buf)); - } - p = buf; - for (k = 0; k < 4; k++) - { - if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]); - } - - p = SR_buf; - for (k = 0; k < 4; k++) - { - if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = - fromhex (SR_buf[k * 2 + 1]) * 16 + fromhex (SR_buf[k * 2 + 2]); - } - send_with_reply ("PC", buf, sizeof (buf)); - p = buf; - for (k = 0; k < 4; k++) - { - if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]); - } - } - else - /* 68000-mode */ - { - if (*p == '2') /* use supervisorstackpointer SSP */ - { - send_with_reply ("SSP", buf, sizeof (buf)); - } - else - /* use userstackpointer USP */ - { - send_with_reply ("USP", buf, sizeof (buf)); - } - - /* fetch STACKPOINTER */ - - p = buf; - for (k = 0; k < 4; k++) - { - if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]); - } - - /* fetch STATUS */ - - p = SR_buf; - for (k = 0; k < 4; k++) - { - if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = - fromhex (SR_buf[k * 2 + 1]) * 16 + fromhex (SR_buf[k * 2 + 2]); - } - - /* fetch PC */ - - send_with_reply ("PC", buf, sizeof (buf)); - p = buf; - for (k = 0; k < 4; k++) - { - if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0) - { - error ("Emulator reply is too short: %s", buf); - } - registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]); - } - } -} - -/* Store register value, located in REGISTER, on the target processor. - regno - the register-number of the register to store - (-1 means store them all) - FIXME: Return errno value. */ - -static void -es1800_store_register (int regno) -{ - - static char regtab[18][4] = - { - "D0 ", "D1 ", "D2 ", "D3 ", "D4 ", "D5 ", "D6 ", "D7 ", - "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", "A6 ", "SSP", - "SR ", "PC " - }; - - char buf[PBUFSIZ]; - char SR_buf[PBUFSIZ]; - char stack_pointer[4]; - char *p; - int i; - int j; - int k; - unsigned char *r; - - r = (unsigned char *) registers; - - if (regno == -1) /* write all registers */ - { - j = 0; - k = 18; - } - else - /* write one register */ - { - j = regno; - k = regno + 1; - r += regno * 4; - } - - if ((regno == -1) || (regno == 15)) - { - /* fetch current status */ - send_with_reply ("SR", SR_buf, sizeof (SR_buf)); - p = SR_buf; - p += 5; - if (m68020) - { - if (*p == '3') /* use masterstackpointer MSP */ - { - strcpy (stack_pointer, "MSP"); - } - else - { - if (*p == '2') /* use interruptstackpointer ISP */ - { - strcpy (stack_pointer, "ISP"); - } - else - { - strcpy (stack_pointer, "USP"); /* use userstackpointer USP */ - } - } - } - else - /* 68000-mode */ - { - if (*p == '2') /* use supervisorstackpointer SSP */ - { - strcpy (stack_pointer, "SSP"); - } - else - { - strcpy (stack_pointer, "USP"); /* use userstackpointer USP */ - } - } - strcpy (regtab[15], stack_pointer); - } - - for (i = j; i < k; i++) - { - buf[0] = regtab[i][0]; - buf[1] = regtab[i][1]; - buf[2] = regtab[i][2]; - buf[3] = '='; - buf[4] = '$'; - buf[5] = tohex ((*r >> 4) & 0x0f); - buf[6] = tohex (*r++ & 0x0f); - buf[7] = tohex ((*r >> 4) & 0x0f); - buf[8] = tohex (*r++ & 0x0f); - buf[9] = tohex ((*r >> 4) & 0x0f); - buf[10] = tohex (*r++ & 0x0f); - buf[11] = tohex ((*r >> 4) & 0x0f); - buf[12] = tohex (*r++ & 0x0f); - buf[13] = 0; - - send_with_reply (buf, buf, sizeof (buf)); /* FIXME, reply not used? */ - } -} - - -/* Prepare to store registers. */ - -static void -es1800_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -/* Convert hex digit A to a number. */ - -static int -fromhex (int a) -{ - if (a >= '0' && a <= '9') - { - return a - '0'; - } - else if (a >= 'a' && a <= 'f') - { - return a - 'a' + 10; - } - else if (a >= 'A' && a <= 'F') - { - return a - 'A' + 10; - } - else - { - error ("Reply contains invalid hex digit"); - } - return (-1); -} - - -/* Convert number NIB to a hex digit. */ - -static int -tohex (int nib) -{ - if (nib < 10) - { - return ('0' + nib); - } - else - { - return ('A' + nib - 10); - } -} - -/* Read or write LEN bytes from inferior memory at MEMADDR, transferring - to or from debugger address MYADDR. Write to inferior if WRITE is - nonzero. Returns length of data written or read; 0 for error. - - memaddr - the target's address - myaddr - gdb's address - len - number of bytes - write - write if != 0 otherwise read - tops - unused */ - -static int -es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, struct mem_attrib *attrib, - struct target_ops *target) -{ - int origlen = len; - int xfersize; - - while (len > 0) - { - xfersize = len > MAXBUFBYTES ? MAXBUFBYTES : len; - if (write) - { - es1800_write_bytes (memaddr, myaddr, xfersize); - } - else - { - es1800_read_bytes (memaddr, myaddr, xfersize); - } - memaddr += xfersize; - myaddr += xfersize; - len -= xfersize; - } - return (origlen); /* no error possible */ -} - - -/* Write memory data directly to the emulator. - This does not inform the data cache; the data cache uses this. - MEMADDR is the address in the remote memory space. - MYADDR is the address of the buffer in our space. - LEN is the number of bytes. - - memaddr - the target's address - myaddr - gdb's address - len - number of bytes */ - -static void -es1800_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) -{ - char buf[PBUFSIZ]; - int i; - char *p; - - p = myaddr; - for (i = 0; i < len; i++) - { - sprintf (buf, "@.B$%x=$%x", memaddr + i, (*p++) & 0xff); - send_with_reply (buf, buf, sizeof (buf)); /* FIXME send_command? */ - } -} - - -/* Read memory data directly from the emulator. - This does not use the data cache; the data cache uses this. - - memaddr - the target's address - myaddr - gdb's address - len - number of bytes */ - -static void -es1800_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) -{ - static int DB_tab[16] = - {8, 11, 14, 17, 20, 23, 26, 29, 34, 37, 40, 43, 46, 49, 52, 55}; - char buf[PBUFSIZ]; - int i; - int low_addr; - char *p; - char *b; - - if (len > PBUFSIZ / 2 - 1) - { - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } - - if (len == 1) /* The emulator does not like expressions like: */ - { - len = 2; /* DB.B $20018 TO $20018 */ - } - - /* Reply describes registers byte by byte, each byte encoded as two hex - characters. */ - - sprintf (buf, "DB.B $%x TO $%x", memaddr, memaddr + len - 1); - send_with_reply (buf, buf, sizeof (buf)); - b = buf; - low_addr = memaddr & 0x0f; - for (i = low_addr; i < low_addr + len; i++) - { - if ((!(i % 16)) && i) - { /* if (i = 16,32,48) */ - while (*p++ != '\n') - {; - } - b = p; - } - p = b + DB_tab[i % 16] + (m68020 ? 2 : 0); - if (p[0] == 32 || p[1] == 32) - { - error ("Emulator reply is too short: %s", buf); - } - myaddr[i - low_addr] = fromhex (p[0]) * 16 + fromhex (p[1]); - } -} - -/* Display information about the current target. TOPS is unused. */ - -static void -es1800_files_info (struct target_ops *tops) -{ - printf ("ES1800 Attached to %s at %d baud in %s mode\n", savename, 19200, - MODE); -} - - -/* We read the contents of the target location and stash it, - then overwrite it with a breakpoint instruction. - - addr - is the target location in the target machine. - contents_cache - is a pointer to memory allocated for saving the target contents. - It is guaranteed by the caller to be long enough to save sizeof - BREAKPOINT bytes. - - FIXME: This size is target_arch dependent and should be available in - the target_arch transfer vector, if we ever have one... */ - -static int -es1800_insert_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - int val; - - val = target_read_memory (addr, contents_cache, sizeof (es1800_break_insn)); - - if (val == 0) - { - val = target_write_memory (addr, es1800_break_insn, - sizeof (es1800_break_insn)); - } - - return (val); -} - - -/* Write back the stashed instruction - - addr - is the target location in the target machine. - contents_cache - is a pointer to memory allocated for saving the target contents. - It is guaranteed by the caller to be long enough to save sizeof - BREAKPOINT bytes. */ - -static int -es1800_remove_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - - return (target_write_memory (addr, contents_cache, - sizeof (es1800_break_insn))); -} - -/* create_break_insn () - Primitive datastructures containing the es1800 breakpoint instruction */ - -static void -es1800_create_break_insn (char *ins, int vec) -{ - if (vec == 15) - { - ins[0] = 0x4e; - ins[1] = 0x4f; - } -} - - -/* verify_break () - Seach for breakpoint routine in emulator memory. - returns non-zero on failure - vec - trap vector used for breakpoints */ - -static int -verify_break (int vec) -{ - CORE_ADDR memaddress; - char buf[8]; - char *instr = "NqNqNqNs"; /* breakpoint routine */ - int status; - - get_break_addr (vec, &memaddress); - - if (memaddress) - { - status = target_read_memory (memaddress, buf, 8); - if (status != 0) - { - memory_error (status, memaddress); - } - return (strcmp (instr, buf)); - } - return (-1); -} - - -/* get_break_addr () - find address of breakpoint routine - vec - trap vector used for breakpoints - addrp - store the address here */ - -static void -get_break_addr (int vec, CORE_ADDR *addrp) -{ - CORE_ADDR memaddress = 0; - int status; - int k; - char buf[PBUFSIZ]; - char base_addr[4]; - char *p; - - if (m68020) - { - send_with_reply ("VBR ", buf, sizeof (buf)); - p = buf; - for (k = 0; k < 4; k++) - { - if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0)) - { - error ("Emulator reply is too short: %s", buf); - } - base_addr[k] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]); - } - /* base addr of exception vector table */ - memaddress = *((CORE_ADDR *) base_addr); - } - - memaddress += (vec + 32) * 4; /* address of trap vector */ - status = target_read_memory (memaddress, (char *) addrp, 4); - if (status != 0) - { - memory_error (status, memaddress); - } -} - - -/* Kill an inferior process */ - -static void -es1800_kill (void) -{ - if (!ptid_equal (inferior_ptid, null_ptid)) - { - inferior_ptid = null_ptid; - es1800_mourn_inferior (); - } -} - - -/* Load a file to the ES1800 emulator. - Converts the file from a.out format into Extended Tekhex format - before the file is loaded. - Also loads the trap routine, and sets the ES1800 breakpoint on it - filename - the a.out to be loaded - from_tty - says whether to be verbose or not - FIXME Uses emulator overlay memory for trap routine */ - -static void -es1800_load (char *filename, int from_tty) -{ - - FILE *instream; - char loadname[15]; - char buf[160]; - struct cleanup *old_chain; - int es1800_load_format = 5; - - if (es1800_desc == NULL) - { - printf ("No emulator attached, type emulator-command first\n"); - return; - } - - filename = tilde_expand (filename); - make_cleanup (xfree, filename); - - switch (es1800_load_format) - { - case 2: /* Extended Tekhex */ - if (from_tty) - { - printf ("Converting \"%s\" to Extended Tekhex Format\n", filename); - } - sprintf (buf, "tekhex %s", filename); - system (buf); - sprintf (loadname, "out.hex"); - break; - - case 5: /* Motorola S-rec */ - if (from_tty) - { - printf ("Converting \"%s\" to Motorola S-record format\n", - filename); - } - /* in the future the source code in copy (part of binutils-1.93) will - be included in this file */ - sprintf (buf, - "copy -s \"a.out-sunos-big\" -d \"srec\" %s /tmp/out.hex", - filename); - system (buf); - sprintf (loadname, "/tmp/out.hex"); - break; - - default: - error ("Downloading format not defined\n"); - } - - breakpoint_init_inferior (); - inferior_ptid = null_ptid; - if (from_tty) - { - printf ("Downloading \"%s\" to the ES 1800\n", filename); - } - if ((instream = fopen (loadname, "r")) == NULL) - { - perror_with_name ("fopen:"); - } - - old_chain = make_cleanup (fclose, instream); - immediate_quit++; - - es1800_reset (0); - - download (instream, from_tty, es1800_load_format); - - /* if breakpoint routine is not present anymore we have to check - whether to download a new breakpoint routine or not */ - - if ((verify_break (es1800_break_vec) != 0) - && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? ")) - { - char buf[128]; - printf ("Using break vector 0x%x\n", es1800_break_vec); - sprintf (buf, "0x%x ", es1800_break_vec); - printf ("Give the start address of the breakpoint routine: "); - fgets (buf + strlen (buf), sizeof (buf) - strlen (buf), stdin); - es1800_init_break (buf, 0); - } - - do_cleanups (old_chain); - expect_prompt (); - readchar (); /* FIXME I am getting a ^G = 7 after the prompt */ - printf ("\n"); - - if (fclose (instream) == EOF) - { - ; - } - - if (es1800_load_format != 2) - { - sprintf (buf, "/usr/bin/rm %s", loadname); - system (buf); - } - - symbol_file_add_main (filename, from_tty); /* reading symbol table */ - immediate_quit--; -} - -#if 0 - -#define NUMCPYBYTES 20 - -static void -bfd_copy (bfd *from_bfd, bfd *to_bfd) -{ - asection *p, *new; - int i; - char buf[NUMCPYBYTES]; - - for (p = from_bfd->sections; p != NULL; p = p->next) - { - printf (" Copying section %s. Size = %x.\n", p->name, p->_cooked_size); - printf (" vma = %x, offset = %x, output_sec = %x\n", - p->vma, p->output_offset, p->output_section); - new = bfd_make_section (to_bfd, p->name); - if (p->_cooked_size && - !bfd_set_section_size (to_bfd, new, p->_cooked_size)) - { - error ("Wrong BFD size!\n"); - } - if (!bfd_set_section_flags (to_bfd, new, p->flags)) - { - error ("bfd_set_section_flags"); - } - new->vma = p->vma; - - for (i = 0; (i + NUMCPYBYTES) < p->_cooked_size; i += NUMCPYBYTES) - { - if (!bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i, - (bfd_size_type) NUMCPYBYTES)) - { - error ("bfd_get_section_contents\n"); - } - if (!bfd_set_section_contents (to_bfd, new, (PTR) buf, (file_ptr) i, - (bfd_size_type) NUMCPYBYTES)) - { - error ("bfd_set_section_contents\n"); - } - } - bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i, - (bfd_size_type) (p->_cooked_size - i)); - bfd_set_section_contents (to_bfd, new, (PTR) buf, (file_ptr) i, - (bfd_size_type) (p->_cooked_size - i)); - } -} - -#endif - -/* Start an process on the es1800 and set inferior_ptid to the new - process' pid. - execfile - the file to run - args - arguments passed to the program - env - the environment vector to pass */ - -static void -es1800_create_inferior (char *execfile, char *args, char **env) -{ - int entry_pt; - int pid; -#if 0 - struct expression *expr; - register struct cleanup *old_chain = 0; - register value val; -#endif - - if (args && *args) - { - error ("Can't pass arguments to remote ES1800 process"); - } - -#if 0 - if (query ("Use 'start' as entry point? ")) - { - expr = parse_c_expression ("start"); - old_chain = make_cleanup (free_current_contents, &expr); - val = evaluate_expression (expr); - entry_pt = (val->location).address; - } - else - { - printf ("Enter the program's entry point (in hexadecimal): "); - scanf ("%x", &entry_pt); - } -#endif - - if (execfile == 0 || exec_bfd == 0) - { - error ("No executable file specified"); - } - - entry_pt = (int) bfd_get_start_address (exec_bfd); - - pid = 42; - - /* Now that we have a child process, make it our target. */ - - push_target (&es1800_child_ops); - - /* The "process" (board) is already stopped awaiting our commands, and - the program is already downloaded. We just set its PC and go. */ - - inferior_ptid = pid_to_ptid (pid); /* Needed for wait_for_inferior below */ - - clear_proceed_status (); - - /* Tell wait_for_inferior that we've started a new process. */ - - init_wait_for_inferior (); - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - - target_terminal_init (); - - /* Install inferior's terminal modes. */ - - target_terminal_inferior (); - - /* remote_start (args); */ - /* trap_expected = 0; */ - /* insert_step_breakpoint (); FIXME, do we need this? */ - - /* Let 'er rip... */ - proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0); - -} - - -/* The process has died, clean up. */ - -static void -es1800_mourn_inferior (void) -{ - remove_breakpoints (); - unpush_target (&es1800_child_ops); - generic_mourn_inferior (); /* Do all the proper things now */ -} - -/* ES1800-protocol specific routines */ - -/* Keep discarding input from the remote system, until STRING is found. - Let the user break out immediately. - string - the string to expect - nowait - break out if string not the emulator's first respond otherwise - read until string is found (== 0) */ - -static void -expect (char *string, int nowait) -{ - char c; - char *p = string; - - immediate_quit++; - while (1) - { - c = readchar (); - if (isalpha (c)) - { - c = toupper (c); - } - if (c == toupper (*p)) - { - p++; - if (*p == '\0') - { - immediate_quit--; - return; - } - } - else if (!nowait) - { - p = string; - } - else - { - printf ("\'%s\' expected\n", string); - printf ("char %d is %d", p - string, c); - error ("\n"); - } - } -} - -/* Keep discarding input until we see the prompt. */ - -static void -expect_prompt (void) -{ - expect (">", 0); -} - - -/* Read one character */ - -#ifdef DEBUG_STDIN - -/* read from stdin */ - -static int -readchar (void) -{ - char buf[1]; - - buf[0] = '\0'; - printf ("readchar, give one character\n"); - read (0, buf, 1); - -#if defined (LOG_FILE) - putc (buf[0] & 0x7f, log_file); -#endif - - return (buf[0] & 0x7f); -} - -#else /* !DEBUG_STDIN */ - -/* Read a character from the remote system, doing all the fancy - timeout stuff. */ - -static int -readchar (void) -{ - int ch; - - ch = serial_readchar (es1800_desc, timeout); - - /* FIXME: doing an error() here will probably cause trouble, at least if from - es1800_wait. */ - if (ch == SERIAL_TIMEOUT) - error ("Timeout reading from remote system."); - else if (ch == SERIAL_ERROR) - perror_with_name ("remote read"); - -#if defined (LOG_FILE) - putc (ch & 0x7f, log_file); - fflush (log_file); -#endif - - return (ch); -} - -#endif /* DEBUG_STDIN */ - - -/* Send a command to the emulator and save the reply. - Report an error if we get an error reply. - string - the es1800 command - buf - containing the emulator reply on return - len - size of buf */ - -static void -send_with_reply (char *string, char *buf, int len) -{ - send (string); - serial_write (es1800_desc, "\r", 1); - -#ifndef DEBUG_STDIN - expect (string, 1); - expect ("\r\n", 0); -#endif - - getmessage (buf, len); -} - - -/* Send the command in STR to the emulator adding \r. check - the echo for consistency. - string - the es1800 command */ - -static void -send_command (char *string) -{ - send (string); - serial_write (es1800_desc, "\r", 1); - -#ifndef DEBUG_STDIN - expect (string, 0); - expect_prompt (); -#endif - -} - -/* Send a string - string - the es1800 command */ - -static void -send (char *string) -{ - if (kiodebug) - { - fprintf (stderr, "Sending: %s\n", string); - } - serial_write (es1800_desc, string, strlen (string)); -} - - -/* Read a message from the emulator and store it in BUF. - buf - containing the emulator reply on return - len - size of buf */ - -static void -getmessage (char *buf, int len) -{ - char *bp; - int c; - int prompt_found = 0; - extern kiodebug; - -#if defined (LOG_FILE) - /* This is a convenient place to do this. The idea is to do it often - enough that we never lose much data if we terminate abnormally. */ - fflush (log_file); -#endif - - bp = buf; - c = readchar (); - do - { - if (c) - { - if (len-- < 2) /* char and terminaling NULL */ - { - error ("input buffer overrun\n"); - } - *bp++ = c; - } - c = readchar (); - if ((c == '>') && (*(bp - 1) == ' ')) - { - prompt_found = 1; - } - } - while (!prompt_found); - *bp = 0; - - if (kiodebug) - { - fprintf (stderr, "message received :%s\n", buf); - } -} - -static void -download (FILE *instream, int from_tty, int format) -{ - char c; - char buf[160]; - int i = 0; - - send_command ("SET #2,$1A"); /* reset char = ^Z */ - send_command ("SET #3,$11,$13"); /* XON XOFF */ - if (format == 2) - { - send_command ("SET #26,#2"); - } - else - { - send_command ("SET #26,#5"); /* Format=Extended Tekhex */ - } - send_command ("DFB = $10"); - send_command ("PUR"); - send_command ("CES"); - send ("DNL\r"); - expect ("DNL", 1); - if (from_tty) - { - printf (" 0 records loaded...\r"); - } - while (fgets (buf, 160, instream)) - { - send (buf); - if (from_tty) - { - printf ("%5d\b\b\b\b\b", ++i); - fflush (stdout); - } - if ((c = readchar ()) != 006) - { - error ("expected ACK"); - } - } - if (from_tty) - { - printf ("- All"); - } -} - -/* Additional commands */ - -#if defined (TIOCGETP) && defined (FNDELAY) && defined (EWOULDBLOCK) -#define PROVIDE_TRANSPARENT -#endif - -#ifdef PROVIDE_TRANSPARENT -/* Talk directly to the emulator - FIXME, uses busy wait, and is SUNOS (or at least BSD) specific */ - -/*ARGSUSED */ -static void -es1800_transparent (char *args, int from_tty) -{ - int console; - struct sgttyb modebl; - int fcflag; - int cc; - struct sgttyb console_mode_save; - int console_fc_save; - int es1800_fc_save; - int inputcnt = 80; - char inputbuf[80]; - int consolecnt = 0; - char consolebuf[80]; - int es1800_cnt = 0; - char es1800_buf[80]; - int i; - - dont_repeat (); - if (es1800_desc == NULL) - { - printf ("No emulator attached, type emulator-command first\n"); - return; - } - - printf ("\n"); - printf ("You are now communicating directly with the ES 1800 emulator.\n"); - printf ("To leave this mode (transparent mode), press ^E.\n"); - printf ("\n"); - printf (" >"); - fflush (stdout); - - if ((console = open ("/dev/tty", O_RDWR)) == -1) - { - perror_with_name ("/dev/tty:"); - } - - if ((fcflag = fcntl (console, F_GETFL, 0)) == -1) - { - perror_with_name ("fcntl console"); - } - - console_fc_save = fcflag; - fcflag = fcflag | FNDELAY; - - if (fcntl (console, F_SETFL, fcflag) == -1) - { - perror_with_name ("fcntl console"); - } - - if (ioctl (console, TIOCGETP, &modebl)) - { - perror_with_name ("ioctl console"); - } - - console_mode_save = modebl; - modebl.sg_flags = RAW; - - if (ioctl (console, TIOCSETP, &modebl)) - { - perror_with_name ("ioctl console"); - } - - if ((fcflag = fcntl (deprecated_serial_fd (es1800_desc), F_GETFL, 0)) == -1) - { - perror_with_name ("fcntl serial"); - } - - es1800_fc_save = fcflag; - fcflag = fcflag | FNDELAY; - - if (fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, fcflag) == -1) - { - perror_with_name ("fcntl serial"); - } - - while (1) - { - cc = read (console, inputbuf, inputcnt); - if (cc != -1) - { - if ((*inputbuf & 0x7f) == 0x05) - { - break; - } - for (i = 0; i < cc;) - { - es1800_buf[es1800_cnt++] = inputbuf[i++]; - } - if ((cc = serial_write (es1800_desc, es1800_buf, es1800_cnt)) == -1) - { - perror_with_name ("FEL! write:"); - } - es1800_cnt -= cc; - if (es1800_cnt && cc) - { - for (i = 0; i < es1800_cnt; i++) - { - es1800_buf[i] = es1800_buf[cc + i]; - } - } - } - else if (errno != EWOULDBLOCK) - { - perror_with_name ("FEL! read:"); - } - - cc = read (deprecated_serial_fd (es1800_desc), inputbuf, inputcnt); - if (cc != -1) - { - for (i = 0; i < cc;) - { - consolebuf[consolecnt++] = inputbuf[i++]; - } - if ((cc = write (console, consolebuf, consolecnt)) == -1) - { - perror_with_name ("FEL! write:"); - } - consolecnt -= cc; - if (consolecnt && cc) - { - for (i = 0; i < consolecnt; i++) - { - consolebuf[i] = consolebuf[cc + i]; - } - } - } - else if (errno != EWOULDBLOCK) - { - perror_with_name ("FEL! read:"); - } - } - - console_fc_save = console_fc_save & !FNDELAY; - if (fcntl (console, F_SETFL, console_fc_save) == -1) - { - perror_with_name ("FEL! fcntl"); - } - - if (ioctl (console, TIOCSETP, &console_mode_save)) - { - perror_with_name ("FEL! ioctl"); - } - - close (console); - - if (fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, es1800_fc_save) == -1) - { - perror_with_name ("FEL! fcntl"); - } - - printf ("\n"); - -} -#endif /* PROVIDE_TRANSPARENT */ - -static void -es1800_init_break (char *args, int from_tty) -{ - CORE_ADDR memaddress = 0; - char buf[PBUFSIZ]; - char base_addr[4]; - char *space_index; - char *p; - int k; - - if (args == NULL) - { - error_no_arg ("a trap vector"); - } - - if (!(space_index = strchr (args, ' '))) - { - error ("Two arguments needed (trap vector and address of break routine).\n"); - } - - *space_index = '\0'; - - es1800_break_vec = strtol (args, (char **) NULL, 0); - es1800_break_address = parse_and_eval_address (space_index + 1); - - es1800_create_break_insn (es1800_break_insn, es1800_break_vec); - - if (m68020) - { - send_with_reply ("VBR ", buf, sizeof (buf)); - p = buf; - for (k = 0; k < 4; k++) - { - if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0)) - { - error ("Emulator reply is too short: %s", buf); - } - base_addr[k] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]); - } - /* base addr of exception vector table */ - memaddress = *((CORE_ADDR *) base_addr); - } - - memaddress += (es1800_break_vec + 32) * 4; /* address of trap vector */ - - sprintf (buf, "@.L%lx=$%lx", memaddress, es1800_break_address); - send_command (buf); /* set the address of the break routine in the */ - /* trap vector */ - - sprintf (buf, "@.L%lx=$4E714E71", es1800_break_address); /* NOP; NOP */ - send_command (buf); - sprintf (buf, "@.L%lx=$4E714E73", es1800_break_address + 4); /* NOP; RTE */ - send_command (buf); - - sprintf (buf, "AC2=$%lx", es1800_break_address + 4); - /* breakpoint at es1800-break_address */ - send_command (buf); - send_command ("WHEN AC2 THEN BRK"); /* ie in exception routine */ - - if (from_tty) - { - printf ("Breakpoint (trap $%x) routine at address: %lx\n", - es1800_break_vec, es1800_break_address); - } -} - -static void -es1800_child_open (char *arg, int from_tty) -{ - error ("Use the \"run\" command to start a child process."); -} - -static void -es1800_child_detach (char *args, int from_tty) -{ - if (args) - { - error ("Argument given to \"detach\" when remotely debugging."); - } - - pop_target (); - if (from_tty) - { - printf ("Ending debugging the process %d.\n", PIDGET (inferior_ptid)); - } -} - - -/* Define the target subroutine names */ - -struct target_ops es1800_ops; - -static void -init_es1800_ops (void) -{ - es1800_ops.to_shortname = "es1800"; - es1800_ops.to_longname = "Remote serial target in ES1800-emulator protocol"; - es1800_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - es1800_ops.to_open = es1800_open; - es1800_ops.to_close = es1800_close; - es1800_ops.to_attach = es1800_attach; - es1800_ops.to_post_attach = NULL; - es1800_ops.to_require_attach = NULL; - es1800_ops.to_detach = es1800_detach; - es1800_ops.to_require_detach = NULL; - es1800_ops.to_resume = es1800_resume; - es1800_ops.to_wait = NULL; - es1800_ops.to_post_wait = NULL; - es1800_ops.to_fetch_registers = NULL; - es1800_ops.to_store_registers = NULL; - es1800_ops.to_prepare_to_store = es1800_prepare_to_store; - es1800_ops.to_xfer_memory = es1800_xfer_inferior_memory; - es1800_ops.to_files_info = es1800_files_info; - es1800_ops.to_insert_breakpoint = es1800_insert_breakpoint; - es1800_ops.to_remove_breakpoint = es1800_remove_breakpoint; - es1800_ops.to_terminal_init = NULL; - es1800_ops.to_terminal_inferior = NULL; - es1800_ops.to_terminal_ours_for_output = NULL; - es1800_ops.to_terminal_ours = NULL; - es1800_ops.to_terminal_info = NULL; - es1800_ops.to_kill = NULL; - es1800_ops.to_load = es1800_load; - es1800_ops.to_lookup_symbol = NULL; - es1800_ops.to_create_inferior = es1800_create_inferior; - es1800_ops.to_post_startup_inferior = NULL; - es1800_ops.to_acknowledge_created_inferior = NULL; - es1800_ops.to_clone_and_follow_inferior = NULL; - es1800_ops.to_post_follow_inferior_by_clone = NULL; - es1800_ops.to_insert_fork_catchpoint = NULL; - es1800_ops.to_remove_fork_catchpoint = NULL; - es1800_ops.to_insert_vfork_catchpoint = NULL; - es1800_ops.to_remove_vfork_catchpoint = NULL; - es1800_ops.to_has_forked = NULL; - es1800_ops.to_has_vforked = NULL; - es1800_ops.to_can_follow_vfork_prior_to_exec = NULL; - es1800_ops.to_post_follow_vfork = NULL; - es1800_ops.to_insert_exec_catchpoint = NULL; - es1800_ops.to_remove_exec_catchpoint = NULL; - es1800_ops.to_has_execd = NULL; - es1800_ops.to_reported_exec_events_per_exec_call = NULL; - es1800_ops.to_has_exited = NULL; - es1800_ops.to_mourn_inferior = NULL; - es1800_ops.to_can_run = 0; - es1800_ops.to_notice_signals = 0; - es1800_ops.to_thread_alive = 0; - es1800_ops.to_stop = 0; - es1800_ops.to_pid_to_exec_file = NULL; - es1800_ops.to_stratum = core_stratum; - es1800_ops.DONT_USE = 0; - es1800_ops.to_has_all_memory = 0; - es1800_ops.to_has_memory = 1; - es1800_ops.to_has_stack = 0; - es1800_ops.to_has_registers = 0; - es1800_ops.to_has_execution = 0; - es1800_ops.to_sections = NULL; - es1800_ops.to_sections_end = NULL; - es1800_ops.to_magic = OPS_MAGIC; -} - -/* Define the target subroutine names */ - -struct target_ops es1800_child_ops; - -static void -init_es1800_child_ops (void) -{ - es1800_child_ops.to_shortname = "es1800_process"; - es1800_child_ops.to_longname = "Remote serial target in ES1800-emulator protocol"; - es1800_child_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - es1800_child_ops.to_open = es1800_child_open; - es1800_child_ops.to_close = NULL; - es1800_child_ops.to_attach = es1800_attach; - es1800_child_ops.to_post_attach = NULL; - es1800_child_ops.to_require_attach = NULL; - es1800_child_ops.to_detach = es1800_child_detach; - es1800_child_ops.to_require_detach = NULL; - es1800_child_ops.to_resume = es1800_resume; - es1800_child_ops.to_wait = es1800_wait; - es1800_child_ops.to_post_wait = NULL; - es1800_child_ops.to_fetch_registers = es1800_fetch_register; - es1800_child_ops.to_store_registers = es1800_store_register; - es1800_child_ops.to_prepare_to_store = es1800_prepare_to_store; - es1800_child_ops.to_xfer_memory = es1800_xfer_inferior_memory; - es1800_child_ops.to_files_info = es1800_files_info; - es1800_child_ops.to_insert_breakpoint = es1800_insert_breakpoint; - es1800_child_ops.to_remove_breakpoint = es1800_remove_breakpoint; - es1800_child_ops.to_terminal_init = NULL; - es1800_child_ops.to_terminal_inferior = NULL; - es1800_child_ops.to_terminal_ours_for_output = NULL; - es1800_child_ops.to_terminal_ours = NULL; - es1800_child_ops.to_terminal_info = NULL; - es1800_child_ops.to_kill = es1800_kill; - es1800_child_ops.to_load = es1800_load; - es1800_child_ops.to_lookup_symbol = NULL; - es1800_child_ops.to_create_inferior = es1800_create_inferior; - es1800_child_ops.to_post_startup_inferior = NULL; - es1800_child_ops.to_acknowledge_created_inferior = NULL; - es1800_child_ops.to_clone_and_follow_inferior = NULL; - es1800_child_ops.to_post_follow_inferior_by_clone = NULL; - es1800_child_ops.to_insert_fork_catchpoint = NULL; - es1800_child_ops.to_remove_fork_catchpoint = NULL; - es1800_child_ops.to_insert_vfork_catchpoint = NULL; - es1800_child_ops.to_remove_vfork_catchpoint = NULL; - es1800_child_ops.to_has_forked = NULL; - es1800_child_ops.to_has_vforked = NULL; - es1800_child_ops.to_can_follow_vfork_prior_to_exec = NULL; - es1800_child_ops.to_post_follow_vfork = NULL; - es1800_child_ops.to_insert_exec_catchpoint = NULL; - es1800_child_ops.to_remove_exec_catchpoint = NULL; - es1800_child_ops.to_has_execd = NULL; - es1800_child_ops.to_reported_exec_events_per_exec_call = NULL; - es1800_child_ops.to_has_exited = NULL; - es1800_child_ops.to_mourn_inferior = es1800_mourn_inferior; - es1800_child_ops.to_can_run = 0; - es1800_child_ops.to_notice_signals = 0; - es1800_child_ops.to_thread_alive = 0; - es1800_child_ops.to_stop = 0; - es1800_child_ops.to_pid_to_exec_file = NULL; - es1800_child_ops.to_stratum = process_stratum; - es1800_child_ops.DONT_USE = 0; - es1800_child_ops.to_has_all_memory = 1; - es1800_child_ops.to_has_memory = 1; - es1800_child_ops.to_has_stack = 1; - es1800_child_ops.to_has_registers = 1; - es1800_child_ops.to_has_execution = 1; - es1800_child_ops.to_sections = NULL; - es1800_child_ops.to_sections_end = NULL; - es1800_child_ops.to_magic = OPS_MAGIC; -} - -void -_initialize_es1800 (void) -{ - init_es1800_ops (); - init_es1800_child_ops (); - add_target (&es1800_ops); - add_target (&es1800_child_ops); -#ifdef PROVIDE_TRANSPARENT - add_com ("transparent", class_support, es1800_transparent, - "Start transparent communication with the ES 1800 emulator."); -#endif /* PROVIDE_TRANSPARENT */ - add_com ("init_break", class_support, es1800_init_break, - "Download break routine and initialize break facility on ES 1800"); -} diff --git a/contrib/gdb/gdb/remote-est.c b/contrib/gdb/gdb/remote-est.c deleted file mode 100644 index e045a8951cd..00000000000 --- a/contrib/gdb/gdb/remote-est.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Remote debugging interface for EST-300 ICE, for GDB - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - Contributed by Cygnus Support. - - Written by Steve Chamberlain for Cygnus Support. - Re-written by Stu Grossman of Cygnus Support - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "regcache.h" - -static void est_open (char *args, int from_tty); - -static void -est_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - int regno; - - if (regnamelen != 2) - return; - - switch (regname[0]) - { - case 'S': - if (regname[1] != 'R') - return; - regno = PS_REGNUM; - break; - case 'P': - if (regname[1] != 'C') - return; - regno = PC_REGNUM; - break; - case 'D': - if (regname[1] < '0' || regname[1] > '7') - return; - regno = regname[1] - '0' + D0_REGNUM; - break; - case 'A': - if (regname[1] < '0' || regname[1] > '7') - return; - regno = regname[1] - '0' + A0_REGNUM; - break; - default: - return; - } - - monitor_supply_register (regno, val); -} - -/* - * This array of registers needs to match the indexes used by GDB. The - * whole reason this exists is because the various ROM monitors use - * different names than GDB does, and don't support all the - * registers either. So, typing "info reg sp" becomes a "r30". - */ - -static char *est_regnames[NUM_REGS] = -{ - "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", - "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", - "SR", "PC", -}; - -/* - * Define the monitor command strings. Since these are passed directly - * through to a printf style function, we need can include formatting - * strings. We also need a CR or LF on the end. - */ - -static struct target_ops est_ops; - -static char *est_inits[] = -{"he\r", /* Resets the prompt, and clears repeated cmds */ - NULL}; - -static struct monitor_ops est_cmds; - -static void -init_est_cmds (void) -{ - est_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT | - MO_SREC_ACK | MO_SREC_ACK_PLUS; - est_cmds.init = est_inits; /* Init strings */ - est_cmds.cont = "go\r"; /* continue command */ - est_cmds.step = "sidr\r"; /* single step */ - est_cmds.stop = "\003"; /* ^C interrupts the program */ - est_cmds.set_break = "sb %x\r"; /* set a breakpoint */ - est_cmds.clr_break = "rb %x\r"; /* clear a breakpoint */ - est_cmds.clr_all_break = "rb\r"; /* clear all breakpoints */ - est_cmds.fill = "bfb %x %x %x\r"; /* fill (start end val) */ - est_cmds.setmem.cmdb = "smb %x %x\r"; /* setmem.cmdb (addr, value) */ - est_cmds.setmem.cmdw = "smw %x %x\r"; /* setmem.cmdw (addr, value) */ - est_cmds.setmem.cmdl = "sml %x %x\r"; /* setmem.cmdl (addr, value) */ - est_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - est_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ - est_cmds.setmem.term = NULL; /* setreg.term */ - est_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ - est_cmds.getmem.cmdb = "dmb %x %x\r"; /* getmem.cmdb (addr, len) */ - est_cmds.getmem.cmdw = "dmw %x %x\r"; /* getmem.cmdw (addr, len) */ - est_cmds.getmem.cmdl = "dml %x %x\r"; /* getmem.cmdl (addr, len) */ - est_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - est_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - est_cmds.getmem.term = NULL; /* getmem.term */ - est_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - est_cmds.setreg.cmd = "sr %s %x\r"; /* setreg.cmd (name, value) */ - est_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - est_cmds.setreg.term = NULL; /* setreg.term */ - est_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - est_cmds.getreg.cmd = "dr %s\r"; /* getreg.cmd (name) */ - est_cmds.getreg.resp_delim = " = "; /* getreg.resp_delim */ - est_cmds.getreg.term = NULL; /* getreg.term */ - est_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - est_cmds.dump_registers = "dr\r"; /* dump_registers */ - est_cmds.register_pattern = "\\(\\w+\\) = \\([0-9a-fA-F]+\\)"; /* register_pattern */ - est_cmds.supply_register = est_supply_register; /* supply_register */ - est_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - est_cmds.load = "dl\r"; /* download command */ - est_cmds.loadresp = "+"; /* load response */ - est_cmds.prompt = ">BKM>"; /* monitor command prompt */ - est_cmds.line_term = "\r"; /* end-of-line terminator */ - est_cmds.cmd_end = NULL; /* optional command terminator */ - est_cmds.target = &est_ops; /* target operations */ - est_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - est_cmds.regnames = est_regnames; /* registers names */ - est_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -} /* init_est_cmds */ - -static void -est_open (char *args, int from_tty) -{ - monitor_open (args, &est_cmds, from_tty); -} - -void -_initialize_est (void) -{ - init_est_cmds (); - init_monitor_ops (&est_ops); - - est_ops.to_shortname = "est"; - est_ops.to_longname = "EST background debug monitor"; - est_ops.to_doc = "Debug via the EST BDM.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - est_ops.to_open = est_open; - - add_target (&est_ops); -} diff --git a/contrib/gdb/gdb/remote-hms.c b/contrib/gdb/gdb/remote-hms.c deleted file mode 100644 index 4a2b088c508..00000000000 --- a/contrib/gdb/gdb/remote-hms.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Remote debugging interface for Hitachi HMS Monitor Version 1.0 - Copyright 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - Contributed by Cygnus Support. Written by Steve Chamberlain - (sac@cygnus.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "regcache.h" - -static void hms_open (char *args, int from_tty); -static void -hms_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - int regno; - - if (regnamelen != 2) - return; - if (regname[0] != 'P') - return; - /* We scan off all the registers in one go */ - - val = monitor_supply_register (PC_REGNUM, val); - /* Skip the ccr string */ - while (*val != '=' && *val) - val++; - - val = monitor_supply_register (CCR_REGNUM, val + 1); - - /* Skip up to rest of regs */ - while (*val != '=' && *val) - val++; - - for (regno = 0; regno < 7; regno++) - { - val = monitor_supply_register (regno, val + 1); - } -} - -/* - * This array of registers needs to match the indexes used by GDB. The - * whole reason this exists is because the various ROM monitors use - * different names than GDB does, and don't support all the - * registers either. So, typing "info reg sp" becomes a "r30". - */ - -static char *hms_regnames[NUM_REGS] = -{ - "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "CCR", "PC" -}; - -/* - * Define the monitor command strings. Since these are passed directly - * through to a printf style function, we need can include formatting - * strings. We also need a CR or LF on the end. - */ - -static struct target_ops hms_ops; - -static char *hms_inits[] = -{"\003", /* Resets the prompt, and clears repeated cmds */ - NULL}; - -static struct monitor_ops hms_cmds; - -static void -init_hms_cmds (void) -{ - hms_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_GETMEM_NEEDS_RANGE; - hms_cmds.init = hms_inits; /* Init strings */ - hms_cmds.cont = "g\r"; /* continue command */ - hms_cmds.step = "s\r"; /* single step */ - hms_cmds.stop = "\003"; /* ^C interrupts the program */ - hms_cmds.set_break = "b %x\r"; /* set a breakpoint */ - hms_cmds.clr_break = "b - %x\r"; /* clear a breakpoint */ - hms_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */ - hms_cmds.fill = "f %x %x %x\r"; /* fill (start end val) */ - hms_cmds.setmem.cmdb = "m.b %x=%x\r"; /* setmem.cmdb (addr, value) */ - hms_cmds.setmem.cmdw = "m.w %x=%x\r"; /* setmem.cmdw (addr, value) */ - hms_cmds.setmem.cmdl = NULL; /* setmem.cmdl (addr, value) */ - hms_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - hms_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ - hms_cmds.setmem.term = NULL; /* setreg.term */ - hms_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ - hms_cmds.getmem.cmdb = "m.b %x %x\r"; /* getmem.cmdb (addr, addr) */ - hms_cmds.getmem.cmdw = "m.w %x %x\r"; /* getmem.cmdw (addr, addr) */ - hms_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, addr) */ - hms_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr) */ - hms_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - hms_cmds.getmem.term = ">"; /* getmem.term */ - hms_cmds.getmem.term_cmd = "\003"; /* getmem.term_cmd */ - hms_cmds.setreg.cmd = "r %s=%x\r"; /* setreg.cmd (name, value) */ - hms_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - hms_cmds.setreg.term = NULL; /* setreg.term */ - hms_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - hms_cmds.getreg.cmd = "r %s\r"; /* getreg.cmd (name) */ - hms_cmds.getreg.resp_delim = " ("; /* getreg.resp_delim */ - hms_cmds.getreg.term = ":"; /* getreg.term */ - hms_cmds.getreg.term_cmd = "\003"; /* getreg.term_cmd */ - hms_cmds.dump_registers = "r\r"; /* dump_registers */ - hms_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */ - hms_cmds.supply_register = hms_supply_register; /* supply_register */ - hms_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - hms_cmds.load = "tl\r"; /* download command */ - hms_cmds.loadresp = NULL; /* load response */ - hms_cmds.prompt = ">"; /* monitor command prompt */ - hms_cmds.line_term = "\r"; /* end-of-command delimitor */ - hms_cmds.cmd_end = NULL; /* optional command terminator */ - hms_cmds.target = &hms_ops; /* target operations */ - hms_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - hms_cmds.regnames = hms_regnames; /* registers names */ - hms_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -} /* init_hms-cmds */ - -static void -hms_open (char *args, int from_tty) -{ - monitor_open (args, &hms_cmds, from_tty); -} - -int write_dos_tick_delay; - -void -_initialize_remote_hms (void) -{ - init_hms_cmds (); - init_monitor_ops (&hms_ops); - - hms_ops.to_shortname = "hms"; - hms_ops.to_longname = "Hitachi Microsystems H8/300 debug monitor"; - hms_ops.to_doc = "Debug via the HMS monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - hms_ops.to_open = hms_open; - /* By trial and error I've found that this delay doesn't break things */ - write_dos_tick_delay = 1; - add_target (&hms_ops); -} diff --git a/contrib/gdb/gdb/remote-mm.c b/contrib/gdb/gdb/remote-mm.c deleted file mode 100644 index 1cd630ea744..00000000000 --- a/contrib/gdb/gdb/remote-mm.c +++ /dev/null @@ -1,1848 +0,0 @@ -/* OBSOLETE /* Remote debugging interface for Am290*0 running MiniMON monitor, for GDB. */ -/* OBSOLETE Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, */ -/* OBSOLETE 2001 Free Software Foundation, Inc. */ -/* OBSOLETE Originally written by Daniel Mann at AMD. */ -/* OBSOLETE */ -/* OBSOLETE This file is part of GDB. */ -/* OBSOLETE */ -/* OBSOLETE This program is free software; you can redistribute it and/or modify */ -/* OBSOLETE it under the terms of the GNU General Public License as published by */ -/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */ -/* OBSOLETE (at your option) any later version. */ -/* OBSOLETE */ -/* OBSOLETE This program is distributed in the hope that it will be useful, */ -/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* OBSOLETE GNU General Public License for more details. */ -/* OBSOLETE */ -/* OBSOLETE You should have received a copy of the GNU General Public License */ -/* OBSOLETE along with this program; if not, write to the Free Software */ -/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */ -/* OBSOLETE Boston, MA 02111-1307, USA. */ */ -/* OBSOLETE */ -/* OBSOLETE /* This is like remote.c but ecpects MiniMON to be running on the Am29000 */ -/* OBSOLETE target hardware. */ -/* OBSOLETE - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this */ -/* OBSOLETE file to gdb 3.95. I was unable to get this working on sun3os4 */ -/* OBSOLETE with termio, only with sgtty. Because we are only attempting to */ -/* OBSOLETE use this module to debug our kernel, which is already loaded when */ -/* OBSOLETE gdb is started up, I did not code up the file downloading facilities. */ -/* OBSOLETE As a result this module has only the stubs to download files. */ -/* OBSOLETE You should get tagged at compile time if you need to make any */ -/* OBSOLETE changes/additions. */ */ -/* OBSOLETE */ -/* OBSOLETE #include "defs.h" */ -/* OBSOLETE #include "inferior.h" */ -/* OBSOLETE #include "value.h" */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include "gdb_string.h" */ -/* OBSOLETE #include "terminal.h" */ -/* OBSOLETE #include "minimon.h" */ -/* OBSOLETE #include "target.h" */ -/* OBSOLETE #include "regcache.h" */ -/* OBSOLETE */ -/* OBSOLETE /* Offset of member MEMBER in a struct of type TYPE. */ */ -/* OBSOLETE #define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) */ -/* OBSOLETE */ -/* OBSOLETE #define DRAIN_INPUT() (msg_recv_serial((union msg_t*)0)) */ -/* OBSOLETE */ -/* OBSOLETE extern int stop_soon_quietly; /* for wait_for_inferior */ */ -/* OBSOLETE */ -/* OBSOLETE static void mm_resume (ptid_t ptid, int step, enum target_signal sig) */ -/* OBSOLETE static void mm_fetch_registers (); */ -/* OBSOLETE static int fetch_register (); */ -/* OBSOLETE static void mm_store_registers (); */ -/* OBSOLETE static int store_register (); */ -/* OBSOLETE static int regnum_to_srnum (); */ -/* OBSOLETE static void mm_close (); */ -/* OBSOLETE static char *msg_str (); */ -/* OBSOLETE static char *error_msg_str (); */ -/* OBSOLETE static int expect_msg (); */ -/* OBSOLETE static void init_target_mm (); */ -/* OBSOLETE static int mm_memory_space (); */ -/* OBSOLETE */ -/* OBSOLETE #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400) */ -/* OBSOLETE #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE) */ -/* OBSOLETE */ -/* OBSOLETE /* FIXME: Replace with `set remotedebug'. */ */ -/* OBSOLETE #define LLOG_FILE "minimon.log" */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE FILE *log_file; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* */ -/* OBSOLETE * Size of message buffers. I couldn't get memory reads to work when */ -/* OBSOLETE * the byte_count was larger than 512 (it may be a baud rate problem). */ -/* OBSOLETE */ */ -/* OBSOLETE #define BUFER_SIZE 512 */ -/* OBSOLETE /* */ -/* OBSOLETE * Size of data area in message buffer on the TARGET (remote system). */ -/* OBSOLETE */ */ -/* OBSOLETE #define MAXDATA_T (target_config.max_msg_size - \ */ -/* OBSOLETE offsetof(struct write_r_msg_t,data[0])) */ -/* OBSOLETE /* */ -/* OBSOLETE * Size of data area in message buffer on the HOST (gdb). */ -/* OBSOLETE */ */ -/* OBSOLETE #define MAXDATA_H (BUFER_SIZE - offsetof(struct write_r_msg_t,data[0])) */ -/* OBSOLETE /* */ -/* OBSOLETE * Defined as the minimum size of data areas of the two message buffers */ -/* OBSOLETE */ */ -/* OBSOLETE #define MAXDATA (MAXDATA_H < MAXDATA_T ? MAXDATA_H : MAXDATA_T) */ -/* OBSOLETE */ -/* OBSOLETE static char out_buf[BUFER_SIZE]; */ -/* OBSOLETE static char in_buf[BUFER_SIZE]; */ -/* OBSOLETE */ -/* OBSOLETE int msg_recv_serial (); */ -/* OBSOLETE int msg_send_serial (); */ -/* OBSOLETE */ -/* OBSOLETE #define MAX_RETRIES 5000 */ -/* OBSOLETE extern struct target_ops mm_ops; /* Forward declaration */ */ -/* OBSOLETE struct config_msg_t target_config; /* HIF needs this */ */ -/* OBSOLETE union msg_t *out_msg_buf = (union msg_t *) out_buf; */ -/* OBSOLETE union msg_t *in_msg_buf = (union msg_t *) in_buf; */ -/* OBSOLETE */ -/* OBSOLETE static int timeout = 5; */ -/* OBSOLETE */ -/* OBSOLETE /* Descriptor for I/O to remote machine. Initialize it to -1 so that */ -/* OBSOLETE mm_open knows that we don't have a file open when the program */ -/* OBSOLETE starts. */ */ -/* OBSOLETE int mm_desc = -1; */ -/* OBSOLETE */ -/* OBSOLETE /* stream which is fdopen'd from mm_desc. Only valid when */ -/* OBSOLETE mm_desc != -1. */ */ -/* OBSOLETE FILE *mm_stream; */ -/* OBSOLETE */ -/* OBSOLETE /* Called when SIGALRM signal sent due to alarm() timeout. */ */ -/* OBSOLETE #ifndef HAVE_TERMIO */ -/* OBSOLETE */ -/* OBSOLETE volatile int n_alarms; */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE mm_timer (void) */ -/* OBSOLETE { */ -/* OBSOLETE #if 0 */ -/* OBSOLETE if (kiodebug) */ -/* OBSOLETE printf ("mm_timer called\n"); */ -/* OBSOLETE #endif */ -/* OBSOLETE n_alarms++; */ -/* OBSOLETE } */ -/* OBSOLETE #endif /* HAVE_TERMIO */ */ -/* OBSOLETE */ -/* OBSOLETE /* malloc'd name of the program on the remote system. */ */ -/* OBSOLETE static char *prog_name = NULL; */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /* Number of SIGTRAPs we need to simulate. That is, the next */ -/* OBSOLETE NEED_ARTIFICIAL_TRAP calls to mm_wait should just return */ -/* OBSOLETE SIGTRAP without actually waiting for anything. */ */ -/* OBSOLETE */ -/* OBSOLETE /**************************************************** REMOTE_CREATE_INFERIOR */ */ -/* OBSOLETE /* This is called not only when we first attach, but also when the */ -/* OBSOLETE user types "run" after having attached. */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_create_inferior (char *execfile, char *args, char **env) */ -/* OBSOLETE { */ -/* OBSOLETE #define MAX_TOKENS 25 */ -/* OBSOLETE #define BUFFER_SIZE 256 */ -/* OBSOLETE int token_count; */ -/* OBSOLETE int result; */ -/* OBSOLETE char *token[MAX_TOKENS]; */ -/* OBSOLETE char cmd_line[BUFFER_SIZE]; */ -/* OBSOLETE */ -/* OBSOLETE if (args && *args) */ -/* OBSOLETE error ("Can't pass arguments to remote mm process (yet)."); */ -/* OBSOLETE */ -/* OBSOLETE if (execfile == 0 /* || exec_bfd == 0 */ ) */ -/* OBSOLETE error ("No executable file specified"); */ -/* OBSOLETE */ -/* OBSOLETE if (!mm_stream) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Minimon not open yet.\n"); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* On ultra3 (NYU) we assume the kernel is already running so there is */ -/* OBSOLETE no file to download. */ -/* OBSOLETE FIXME: Fixed required here -> load your program, possibly with mm_load(). */ -/* OBSOLETE */ */ -/* OBSOLETE printf_filtered ("\n\ */ -/* OBSOLETE Assuming you are at NYU debuging a kernel, i.e., no need to download.\n\n"); */ -/* OBSOLETE */ -/* OBSOLETE /* We will get a task spawn event immediately. */ */ -/* OBSOLETE init_wait_for_inferior (); */ -/* OBSOLETE clear_proceed_status (); */ -/* OBSOLETE stop_soon_quietly = 1; */ -/* OBSOLETE proceed (-1, TARGET_SIGNAL_DEFAULT, 0); */ -/* OBSOLETE normal_stop (); */ -/* OBSOLETE } */ -/* OBSOLETE /**************************************************** REMOTE_MOURN_INFERIOR */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_mourn (void) */ -/* OBSOLETE { */ -/* OBSOLETE pop_target (); /* Pop back to no-child state */ */ -/* OBSOLETE generic_mourn_inferior (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************************** damn_b */ -/* OBSOLETE */ */ -/* OBSOLETE /* Translate baud rates from integers to damn B_codes. Unix should */ -/* OBSOLETE have outgrown this crap years ago, but even POSIX wouldn't buck it. */ */ -/* OBSOLETE */ -/* OBSOLETE #ifndef B19200 */ -/* OBSOLETE #define B19200 EXTA */ -/* OBSOLETE #endif */ -/* OBSOLETE #ifndef B38400 */ -/* OBSOLETE #define B38400 EXTB */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE static struct */ -/* OBSOLETE { */ -/* OBSOLETE int rate, damn_b; */ -/* OBSOLETE } */ -/* OBSOLETE baudtab[] = */ -/* OBSOLETE { */ -/* OBSOLETE { */ -/* OBSOLETE 0, B0 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 50, B50 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 75, B75 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 110, B110 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 134, B134 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 150, B150 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 200, B200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 300, B300 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 600, B600 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 1200, B1200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 1800, B1800 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 2400, B2400 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 4800, B4800 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 9600, B9600 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 19200, B19200 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE 38400, B38400 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE { */ -/* OBSOLETE -1, -1 */ -/* OBSOLETE } */ -/* OBSOLETE , */ -/* OBSOLETE }; */ -/* OBSOLETE */ -/* OBSOLETE static int */ -/* OBSOLETE damn_b (int rate) */ -/* OBSOLETE { */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; baudtab[i].rate != -1; i++) */ -/* OBSOLETE if (rate == baudtab[i].rate) */ -/* OBSOLETE return baudtab[i].damn_b; */ -/* OBSOLETE return B38400; /* Random */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /***************************************************************** REMOTE_OPEN */ -/* OBSOLETE ** Open a connection to remote minimon. */ -/* OBSOLETE NAME is the filename used for communication, then a space, */ -/* OBSOLETE then the baud rate. */ -/* OBSOLETE 'target adapt /dev/ttya 9600 [prognam]' for example. */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE static char *dev_name; */ -/* OBSOLETE int baudrate = 9600; */ -/* OBSOLETE static void */ -/* OBSOLETE mm_open (char *name, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE TERMINAL sg; */ -/* OBSOLETE unsigned int prl; */ -/* OBSOLETE char *p; */ -/* OBSOLETE */ -/* OBSOLETE /* Find the first whitespace character, it separates dev_name from */ -/* OBSOLETE prog_name. */ */ -/* OBSOLETE for (p = name; */ -/* OBSOLETE p && *p && !isspace (*p); p++) */ -/* OBSOLETE ; */ -/* OBSOLETE if (p == 0 || *p == '\0') */ -/* OBSOLETE erroid: */ -/* OBSOLETE error ("Usage : [progname]"); */ -/* OBSOLETE dev_name = (char *) xmalloc (p - name + 1); */ -/* OBSOLETE strncpy (dev_name, name, p - name); */ -/* OBSOLETE dev_name[p - name] = '\0'; */ -/* OBSOLETE */ -/* OBSOLETE /* Skip over the whitespace after dev_name */ */ -/* OBSOLETE for (; isspace (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE */ -/* OBSOLETE if (1 != sscanf (p, "%d ", &baudrate)) */ -/* OBSOLETE goto erroid; */ -/* OBSOLETE */ -/* OBSOLETE /* Skip the number and then the spaces */ */ -/* OBSOLETE for (; isdigit (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE for (; isspace (*p); p++) */ -/* OBSOLETE /*EMPTY */ ; */ -/* OBSOLETE */ -/* OBSOLETE if (prog_name != NULL) */ -/* OBSOLETE xfree (prog_name); */ -/* OBSOLETE prog_name = savestring (p, strlen (p)); */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE if (mm_desc >= 0) */ -/* OBSOLETE close (mm_desc); */ -/* OBSOLETE */ -/* OBSOLETE mm_desc = open (dev_name, O_RDWR); */ -/* OBSOLETE if (mm_desc < 0) */ -/* OBSOLETE perror_with_name (dev_name); */ -/* OBSOLETE ioctl (mm_desc, TIOCGETP, &sg); */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE sg.c_cc[VMIN] = 0; /* read with timeout. */ */ -/* OBSOLETE sg.c_cc[VTIME] = timeout * 10; */ -/* OBSOLETE sg.c_lflag &= ~(ICANON | ECHO); */ -/* OBSOLETE sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate); */ -/* OBSOLETE #else */ -/* OBSOLETE sg.sg_ispeed = damn_b (baudrate); */ -/* OBSOLETE sg.sg_ospeed = damn_b (baudrate); */ -/* OBSOLETE sg.sg_flags |= RAW; */ -/* OBSOLETE sg.sg_flags |= ANYP; */ -/* OBSOLETE sg.sg_flags &= ~ECHO; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE ioctl (mm_desc, TIOCSETP, &sg); */ -/* OBSOLETE mm_stream = fdopen (mm_desc, "r+"); */ -/* OBSOLETE */ -/* OBSOLETE push_target (&mm_ops); */ -/* OBSOLETE */ -/* OBSOLETE #ifndef HAVE_TERMIO */ -/* OBSOLETE #ifndef NO_SIGINTERRUPT */ -/* OBSOLETE /* Cause SIGALRM's to make reads fail with EINTR instead of resuming */ -/* OBSOLETE the read. */ */ -/* OBSOLETE if (siginterrupt (SIGALRM, 1) != 0) */ -/* OBSOLETE perror ("mm_open: error in siginterrupt"); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* Set up read timeout timer. */ */ -/* OBSOLETE if ((void (*)) signal (SIGALRM, mm_timer) == (void (*)) -1) */ -/* OBSOLETE perror ("mm_open: error in signal"); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE log_file = fopen (LOG_FILE, "w"); */ -/* OBSOLETE if (log_file == NULL) */ -/* OBSOLETE perror_with_name (LOG_FILE); */ -/* OBSOLETE #endif */ -/* OBSOLETE /* */ -/* OBSOLETE ** Initialize target configuration structure (global) */ -/* OBSOLETE */ */ -/* OBSOLETE DRAIN_INPUT (); */ -/* OBSOLETE out_msg_buf->config_req_msg.code = CONFIG_REQ; */ -/* OBSOLETE out_msg_buf->config_req_msg.length = 4 * 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); /* send config request message */ */ -/* OBSOLETE */ -/* OBSOLETE expect_msg (CONFIG, in_msg_buf, 1); */ -/* OBSOLETE */ -/* OBSOLETE a29k_get_processor_type (); */ -/* OBSOLETE */ -/* OBSOLETE /* Print out some stuff, letting the user now what's going on */ */ -/* OBSOLETE printf_filtered ("Connected to MiniMon via %s.\n", dev_name); */ -/* OBSOLETE /* FIXME: can this restriction be removed? */ */ -/* OBSOLETE printf_filtered ("Remote debugging using virtual addresses works only\n"); */ -/* OBSOLETE printf_filtered ("\twhen virtual addresses map 1:1 to physical addresses.\n") */ -/* OBSOLETE ; */ -/* OBSOLETE if (processor_type != a29k_freeze_mode) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf_filtered (gdb_stderr, */ -/* OBSOLETE "Freeze-mode debugging not available, and can only be done on an A29050.\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE target_config.code = CONFIG; */ -/* OBSOLETE target_config.length = 0; */ -/* OBSOLETE target_config.processor_id = in_msg_buf->config_msg.processor_id; */ -/* OBSOLETE target_config.version = in_msg_buf->config_msg.version; */ -/* OBSOLETE target_config.I_mem_start = in_msg_buf->config_msg.I_mem_start; */ -/* OBSOLETE target_config.I_mem_size = in_msg_buf->config_msg.I_mem_size; */ -/* OBSOLETE target_config.D_mem_start = in_msg_buf->config_msg.D_mem_start; */ -/* OBSOLETE target_config.D_mem_size = in_msg_buf->config_msg.D_mem_size; */ -/* OBSOLETE target_config.ROM_start = in_msg_buf->config_msg.ROM_start; */ -/* OBSOLETE target_config.ROM_size = in_msg_buf->config_msg.ROM_size; */ -/* OBSOLETE target_config.max_msg_size = in_msg_buf->config_msg.max_msg_size; */ -/* OBSOLETE target_config.max_bkpts = in_msg_buf->config_msg.max_bkpts; */ -/* OBSOLETE target_config.coprocessor = in_msg_buf->config_msg.coprocessor; */ -/* OBSOLETE target_config.reserved = in_msg_buf->config_msg.reserved; */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Connected to MiniMON :\n"); */ -/* OBSOLETE printf (" Debugcore version %d.%d\n", */ -/* OBSOLETE 0x0f & (target_config.version >> 4), */ -/* OBSOLETE 0x0f & (target_config.version)); */ -/* OBSOLETE printf (" Configuration version %d.%d\n", */ -/* OBSOLETE 0x0f & (target_config.version >> 12), */ -/* OBSOLETE 0x0f & (target_config.version >> 8)); */ -/* OBSOLETE printf (" Message system version %d.%d\n", */ -/* OBSOLETE 0x0f & (target_config.version >> 20), */ -/* OBSOLETE 0x0f & (target_config.version >> 16)); */ -/* OBSOLETE printf (" Communication driver version %d.%d\n", */ -/* OBSOLETE 0x0f & (target_config.version >> 28), */ -/* OBSOLETE 0x0f & (target_config.version >> 24)); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Leave the target running... */ -/* OBSOLETE * The above message stopped the target in the dbg core (MiniMon), */ -/* OBSOLETE * so restart the target out of MiniMon, */ -/* OBSOLETE */ */ -/* OBSOLETE out_msg_buf->go_msg.code = GO; */ -/* OBSOLETE out_msg_buf->go_msg.length = 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE /* No message to expect after a GO */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /**************************************************************** REMOTE_CLOSE */ -/* OBSOLETE ** Close the open connection to the minimon debugger. */ -/* OBSOLETE Use this when you want to detach and do something else */ -/* OBSOLETE with your gdb. */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_close ( /*FIXME: how is quitting used */ */ -/* OBSOLETE int quitting) */ -/* OBSOLETE { */ -/* OBSOLETE if (mm_desc < 0) */ -/* OBSOLETE error ("Can't close remote connection: not debugging remotely."); */ -/* OBSOLETE */ -/* OBSOLETE /* We should never get here if there isn't something valid in */ -/* OBSOLETE mm_desc and mm_stream. */ -/* OBSOLETE */ -/* OBSOLETE Due to a bug in Unix, fclose closes not only the stdio stream, */ -/* OBSOLETE but also the file descriptor. So we don't actually close */ -/* OBSOLETE mm_desc. */ */ -/* OBSOLETE DRAIN_INPUT (); */ -/* OBSOLETE fclose (mm_stream); */ -/* OBSOLETE /* close (mm_desc); */ */ -/* OBSOLETE */ -/* OBSOLETE /* Do not try to close mm_desc again, later in the program. */ */ -/* OBSOLETE mm_stream = NULL; */ -/* OBSOLETE mm_desc = -1; */ -/* OBSOLETE */ -/* OBSOLETE #if defined (LOG_FILE) */ -/* OBSOLETE if (ferror (log_file)) */ -/* OBSOLETE printf ("Error writing log file.\n"); */ -/* OBSOLETE if (fclose (log_file) != 0) */ -/* OBSOLETE printf ("Error closing log file.\n"); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE printf ("Ending remote debugging\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /************************************************************* REMOTE_ATACH */ */ -/* OBSOLETE /* Attach to a program that is already loaded and running */ -/* OBSOLETE * Upon exiting the process's execution is stopped. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_attach (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE if (!mm_stream) */ -/* OBSOLETE error ("MiniMon not opened yet, use the 'target minimon' command.\n"); */ -/* OBSOLETE */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf ("Attaching to remote program %s...\n", prog_name); */ -/* OBSOLETE */ -/* OBSOLETE /* Make sure the target is currently running, it is supposed to be. */ */ -/* OBSOLETE /* FIXME: is it ok to send MiniMon a BREAK if it is already stopped in */ -/* OBSOLETE * the dbg core. If so, we don't need to send this GO. */ -/* OBSOLETE */ */ -/* OBSOLETE out_msg_buf->go_msg.code = GO; */ -/* OBSOLETE out_msg_buf->go_msg.length = 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE sleep (2); /* At the worst it will stop, receive a message, continue */ */ -/* OBSOLETE */ -/* OBSOLETE /* Send the mm a break. */ */ -/* OBSOLETE out_msg_buf->break_msg.code = BREAK; */ -/* OBSOLETE out_msg_buf->break_msg.length = 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE } */ -/* OBSOLETE /********************************************************** REMOTE_DETACH */ */ -/* OBSOLETE /* Terminate the open connection to the remote debugger. */ -/* OBSOLETE Use this when you want to detach and do something else */ -/* OBSOLETE with your gdb. Leave remote process running (with no breakpoints set). */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_detach (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE remove_breakpoints (); /* Just in case there were any left in */ */ -/* OBSOLETE out_msg_buf->go_msg.code = GO; */ -/* OBSOLETE out_msg_buf->go_msg.length = 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE pop_target (); /* calls mm_close to do the real work */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /*************************************************************** REMOTE_RESUME */ -/* OBSOLETE ** Tell the remote machine to resume. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE mm_resume (ptid_t ptid, int step, enum target_signal sig) */ -/* OBSOLETE { */ -/* OBSOLETE if (sig != TARGET_SIGNAL_0) */ -/* OBSOLETE warning ("Can't send signals to a remote MiniMon system."); */ -/* OBSOLETE */ -/* OBSOLETE if (step) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->step_msg.code = STEP; */ -/* OBSOLETE out_msg_buf->step_msg.length = 1 * 4; */ -/* OBSOLETE out_msg_buf->step_msg.count = 1; /* step 1 instruction */ */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->go_msg.code = GO; */ -/* OBSOLETE out_msg_buf->go_msg.length = 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /***************************************************************** REMOTE_WAIT */ -/* OBSOLETE ** Wait until the remote machine stops, then return, */ -/* OBSOLETE storing status in STATUS just as `wait' would. */ */ -/* OBSOLETE */ -/* OBSOLETE static ptid_t */ -/* OBSOLETE mm_wait (ptid_t ptid, struct target_waitstatus *status) */ -/* OBSOLETE { */ -/* OBSOLETE int i, result; */ -/* OBSOLETE int old_timeout = timeout; */ -/* OBSOLETE int old_immediate_quit = immediate_quit; */ -/* OBSOLETE */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* wait for message to arrive. It should be: */ -/* OBSOLETE - A HIF service request. */ -/* OBSOLETE - A HIF exit service request. */ -/* OBSOLETE - A CHANNEL0_ACK. */ -/* OBSOLETE - A CHANNEL1 request. */ -/* OBSOLETE - a debugcore HALT message. */ -/* OBSOLETE HIF services must be responded too, and while-looping continued. */ -/* OBSOLETE If the target stops executing, mm_wait() should return. */ -/* OBSOLETE */ */ -/* OBSOLETE timeout = 0; /* Wait indefinetly for a message */ */ -/* OBSOLETE immediate_quit = 1; /* Helps ability to QUIT */ */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE while (msg_recv_serial (in_msg_buf)) */ -/* OBSOLETE { */ -/* OBSOLETE QUIT; /* Let user quit if they want */ */ -/* OBSOLETE } */ -/* OBSOLETE switch (in_msg_buf->halt_msg.code) */ -/* OBSOLETE { */ -/* OBSOLETE case HIF_CALL: */ -/* OBSOLETE i = in_msg_buf->hif_call_rtn_msg.service_number; */ -/* OBSOLETE result = service_HIF (in_msg_buf); */ -/* OBSOLETE if (i == 1) /* EXIT */ */ -/* OBSOLETE goto exit; */ -/* OBSOLETE if (result) */ -/* OBSOLETE printf ("Warning: failure during HIF service %d\n", i); */ -/* OBSOLETE break; */ -/* OBSOLETE case CHANNEL0_ACK: */ -/* OBSOLETE service_HIF (in_msg_buf); */ -/* OBSOLETE break; */ -/* OBSOLETE case CHANNEL1: */ -/* OBSOLETE i = in_msg_buf->channel1_msg.length; */ -/* OBSOLETE in_msg_buf->channel1_msg.data[i] = '\0'; */ -/* OBSOLETE printf ("%s", in_msg_buf->channel1_msg.data); */ -/* OBSOLETE gdb_flush (gdb_stdout); */ -/* OBSOLETE /* Send CHANNEL1_ACK message */ */ -/* OBSOLETE out_msg_buf->channel1_ack_msg.code = CHANNEL1_ACK; */ -/* OBSOLETE out_msg_buf->channel1_ack_msg.length = 0; */ -/* OBSOLETE result = msg_send_serial (out_msg_buf); */ -/* OBSOLETE break; */ -/* OBSOLETE case HALT: */ -/* OBSOLETE goto halted; */ -/* OBSOLETE default: */ -/* OBSOLETE goto halted; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE halted: */ -/* OBSOLETE /* FIXME, these printfs should not be here. This is a source level */ -/* OBSOLETE debugger, guys! */ */ -/* OBSOLETE if (in_msg_buf->halt_msg.trap_number == 0) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d (break point)\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 1) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_BUS; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 3 */ -/* OBSOLETE || in_msg_buf->halt_msg.trap_number == 4) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_FPE; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 5) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ILL; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number >= 6 */ -/* OBSOLETE && in_msg_buf->halt_msg.trap_number <= 11) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_SEGV; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 12 */ -/* OBSOLETE || in_msg_buf->halt_msg.trap_number == 13) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ILL; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 14) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ALRM; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 15) */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number >= 16 */ -/* OBSOLETE && in_msg_buf->halt_msg.trap_number <= 21) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_INT; */ -/* OBSOLETE } */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 22) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Am290*0 received vector number %d\n", */ -/* OBSOLETE in_msg_buf->halt_msg.trap_number); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ILL; */ -/* OBSOLETE } /* BREAK message was sent */ */ -/* OBSOLETE else if (in_msg_buf->halt_msg.trap_number == 75) */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE exit: */ -/* OBSOLETE { */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE timeout = old_timeout; /* Restore original timeout value */ */ -/* OBSOLETE immediate_quit = old_immediate_quit; */ -/* OBSOLETE return inferior_ptid; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************* REMOTE_FETCH_REGISTERS */ -/* OBSOLETE * Read a remote register 'regno'. */ -/* OBSOLETE * If regno==-1 then read all the registers. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_fetch_registers (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE INT32 *data_p; */ -/* OBSOLETE */ -/* OBSOLETE if (regno >= 0) */ -/* OBSOLETE { */ -/* OBSOLETE fetch_register (regno); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Gr1/rsp */ */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = 4 * 1; */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = 1; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE expect_msg (READ_ACK, in_msg_buf, 1); */ -/* OBSOLETE data_p = &(in_msg_buf->read_r_ack_msg.data[0]); */ -/* OBSOLETE supply_register (GR1_REGNUM, data_p); */ -/* OBSOLETE */ -/* OBSOLETE #if defined(GR64_REGNUM) /* Read gr64-127 */ */ -/* OBSOLETE /* Global Registers gr64-gr95 */ */ -/* OBSOLETE out_msg_buf->read_req_msg.code = READ_REQ; */ -/* OBSOLETE out_msg_buf->read_req_msg.length = 4 * 3; */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = 4 * 32; */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = 64; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE expect_msg (READ_ACK, in_msg_buf, 1); */ -/* OBSOLETE data_p = &(in_msg_buf->read_r_ack_msg.data[0]); */ -/* OBSOLETE */ -/* OBSOLETE for (regno = GR64_REGNUM; regno < GR64_REGNUM + 32; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE supply_register (regno, data_p++); */ -/* OBSOLETE } */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE */ -/* OBSOLETE /* Global Registers gr96-gr127 */ */ -/* OBSOLETE out_msg_buf->read_req_msg.code = READ_REQ; */ -/* OBSOLETE out_msg_buf->read_req_msg.length = 4 * 3; */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = 4 * 32; */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = 96; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE expect_msg (READ_ACK, in_msg_buf, 1); */ -/* OBSOLETE data_p = &(in_msg_buf->read_r_ack_msg.data[0]); */ -/* OBSOLETE */ -/* OBSOLETE for (regno = GR96_REGNUM; regno < GR96_REGNUM + 32; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE supply_register (regno, data_p++); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Local Registers */ */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = 4 * (128); */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = LOCAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE expect_msg (READ_ACK, in_msg_buf, 1); */ -/* OBSOLETE data_p = &(in_msg_buf->read_r_ack_msg.data[0]); */ -/* OBSOLETE */ -/* OBSOLETE for (regno = LR0_REGNUM; regno < LR0_REGNUM + 128; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE supply_register (regno, data_p++); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Protected Special Registers */ */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = 4 * 15; */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = SPECIAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = 0; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE expect_msg (READ_ACK, in_msg_buf, 1); */ -/* OBSOLETE data_p = &(in_msg_buf->read_r_ack_msg.data[0]); */ -/* OBSOLETE */ -/* OBSOLETE for (regno = 0; regno <= 14; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE supply_register (SR_REGNUM (regno), data_p++); */ -/* OBSOLETE } */ -/* OBSOLETE if (USE_SHADOW_PC) */ -/* OBSOLETE { /* Let regno_to_srnum() handle the register number */ */ -/* OBSOLETE fetch_register (NPC_REGNUM); */ -/* OBSOLETE fetch_register (PC_REGNUM); */ -/* OBSOLETE fetch_register (PC2_REGNUM); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Unprotected Special Registers */ */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = 4 * 8; */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = SPECIAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = 128; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE expect_msg (READ_ACK, in_msg_buf, 1); */ -/* OBSOLETE data_p = &(in_msg_buf->read_r_ack_msg.data[0]); */ -/* OBSOLETE */ -/* OBSOLETE for (regno = 128; regno <= 135; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE supply_register (SR_REGNUM (regno), data_p++); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* There doesn't seem to be any way to get these. */ */ -/* OBSOLETE { */ -/* OBSOLETE int val = -1; */ -/* OBSOLETE supply_register (FPE_REGNUM, &val); */ -/* OBSOLETE supply_register (INTE_REGNUM, &val); */ -/* OBSOLETE supply_register (FPS_REGNUM, &val); */ -/* OBSOLETE supply_register (EXO_REGNUM, &val); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /****************************************************** REMOTE_STORE_REGISTERS */ -/* OBSOLETE * Store register regno into the target. */ -/* OBSOLETE * If regno==-1 then store all the registers. */ -/* OBSOLETE * Result is 0 for success, -1 for failure. */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE mm_store_registers (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE int result; */ -/* OBSOLETE */ -/* OBSOLETE if (regno >= 0) */ -/* OBSOLETE { */ -/* OBSOLETE store_register (regno); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE result = 0; */ -/* OBSOLETE */ -/* OBSOLETE out_msg_buf->write_r_msg.code = WRITE_REQ; */ -/* OBSOLETE */ -/* OBSOLETE /* Gr1/rsp */ */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * 1; */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE out_msg_buf->write_r_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 1; */ -/* OBSOLETE out_msg_buf->write_r_msg.data[0] = read_register (GR1_REGNUM); */ -/* OBSOLETE */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE /* Global registers gr64-gr95 */ */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * (32); */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 64; */ -/* OBSOLETE */ -/* OBSOLETE for (regno = GR64_REGNUM; regno < GR64_REGNUM + 32; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_r_msg.data[regno - GR64_REGNUM] = read_register (regno); */ -/* OBSOLETE } */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE */ -/* OBSOLETE /* Global registers gr96-gr127 */ */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * (32); */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 96; */ -/* OBSOLETE for (regno = GR96_REGNUM; regno < GR96_REGNUM + 32; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_r_msg.data[regno - GR96_REGNUM] = read_register (regno); */ -/* OBSOLETE } */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Local Registers */ */ -/* OBSOLETE out_msg_buf->write_r_msg.memory_space = LOCAL_REG; */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * 128; */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 0; */ -/* OBSOLETE */ -/* OBSOLETE for (regno = LR0_REGNUM; regno < LR0_REGNUM + 128; regno++) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_r_msg.data[regno - LR0_REGNUM] = read_register (regno); */ -/* OBSOLETE } */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Protected Special Registers */ */ -/* OBSOLETE /* VAB through TMR */ */ -/* OBSOLETE out_msg_buf->write_r_msg.memory_space = SPECIAL_REG; */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * 10; */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 0; */ -/* OBSOLETE for (regno = 0; regno <= 9; regno++) /* VAB through TMR */ */ -/* OBSOLETE out_msg_buf->write_r_msg.data[regno] = read_register (SR_REGNUM (regno)); */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* PC0, PC1, PC2 possibly as shadow registers */ */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * 3; */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE for (regno = 10; regno <= 12; regno++) /* LRU and MMU */ */ -/* OBSOLETE out_msg_buf->write_r_msg.data[regno - 10] = read_register (SR_REGNUM (regno)); */ -/* OBSOLETE if (USE_SHADOW_PC) */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 20; /* SPC0 */ */ -/* OBSOLETE else */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 10; /* PC0 */ */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* LRU and MMU */ */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * 2; */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 13; */ -/* OBSOLETE for (regno = 13; regno <= 14; regno++) /* LRU and MMU */ */ -/* OBSOLETE out_msg_buf->write_r_msg.data[regno - 13] = read_register (SR_REGNUM (regno)); */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Unprotected Special Registers */ */ -/* OBSOLETE out_msg_buf->write_r_msg.byte_count = 4 * 8; */ -/* OBSOLETE out_msg_buf->write_r_msg.length = 3 * 4 + out_msg_buf->write_r_msg.byte_count; */ -/* OBSOLETE out_msg_buf->write_r_msg.address = 128; */ -/* OBSOLETE for (regno = 128; regno <= 135; regno++) */ -/* OBSOLETE out_msg_buf->write_r_msg.data[regno - 128] = read_register (SR_REGNUM (regno)); */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (!expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE registers_changed (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /*************************************************** REMOTE_PREPARE_TO_STORE */ */ -/* OBSOLETE /* Get ready to modify the registers array. On machines which store */ -/* OBSOLETE individual registers, this doesn't need to do anything. On machines */ -/* OBSOLETE which store all the registers in one fell swoop, this makes sure */ -/* OBSOLETE that registers contains all the registers from the program being */ -/* OBSOLETE debugged. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE mm_prepare_to_store (void) */ -/* OBSOLETE { */ -/* OBSOLETE /* Do nothing, since we can store individual regs */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************* REMOTE_XFER_MEMORY */ */ -/* OBSOLETE static CORE_ADDR */ -/* OBSOLETE translate_addr (CORE_ADDR addr) */ -/* OBSOLETE { */ -/* OBSOLETE #if defined(KERNEL_DEBUGGING) */ -/* OBSOLETE /* Check for a virtual address in the kernel */ */ -/* OBSOLETE /* Assume physical address of ublock is in paddr_u register */ */ -/* OBSOLETE /* FIXME: doesn't work for user virtual addresses */ */ -/* OBSOLETE if (addr >= UVADDR) */ -/* OBSOLETE { */ -/* OBSOLETE /* PADDR_U register holds the physical address of the ublock */ */ -/* OBSOLETE CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM); */ -/* OBSOLETE return (i + addr - (CORE_ADDR) UVADDR); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE return (addr); */ -/* OBSOLETE } */ -/* OBSOLETE #else */ -/* OBSOLETE return (addr); */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************* REMOTE_FILES_INFO */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_files_info (void) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("\tAttached to %s at %d baud and running program %s.\n", */ -/* OBSOLETE dev_name, baudrate, prog_name); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /************************************************* REMOTE_INSERT_BREAKPOINT */ */ -/* OBSOLETE static int */ -/* OBSOLETE mm_insert_breakpoint (CORE_ADDR addr, char *contents_cache) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.code = BKPT_SET; */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.length = 4 * 4; */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.memory_space = I_MEM; */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.bkpt_addr = (ADDR32) addr; */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.pass_count = 1; */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.bkpt_type = -1; /* use illop for 29000 */ */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (expect_msg (BKPT_SET_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE return 0; /* Success */ */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE return 1; /* Failure */ */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /************************************************* REMOTE_DELETE_BREAKPOINT */ */ -/* OBSOLETE static int */ -/* OBSOLETE mm_remove_breakpoint (CORE_ADDR addr, char *contents_cache) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->bkpt_rm_msg.code = BKPT_RM; */ -/* OBSOLETE out_msg_buf->bkpt_rm_msg.length = 4 * 3; */ -/* OBSOLETE out_msg_buf->bkpt_rm_msg.memory_space = I_MEM; */ -/* OBSOLETE out_msg_buf->bkpt_rm_msg.bkpt_addr = (ADDR32) addr; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE if (expect_msg (BKPT_RM_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE return 0; /* Success */ */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE return 1; /* Failure */ */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************* REMOTE_KILL */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_kill (char *arg, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE char buf[4]; */ -/* OBSOLETE */ -/* OBSOLETE #if defined(KERNEL_DEBUGGING) */ -/* OBSOLETE /* We don't ever kill the kernel */ */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Kernel not killed, but left in current state.\n"); */ -/* OBSOLETE printf ("Use detach to leave kernel running.\n"); */ -/* OBSOLETE } */ -/* OBSOLETE #else */ -/* OBSOLETE out_msg_buf->break_msg.code = BREAK; */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.length = 4 * 0; */ -/* OBSOLETE expect_msg (HALT, in_msg_buf, from_tty); */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Target has been stopped."); */ -/* OBSOLETE printf ("Would you like to do a hardware reset (y/n) [n] "); */ -/* OBSOLETE fgets (buf, 3, stdin); */ -/* OBSOLETE if (buf[0] == 'y') */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->reset_msg.code = RESET; */ -/* OBSOLETE out_msg_buf->bkpt_set_msg.length = 4 * 0; */ -/* OBSOLETE expect_msg (RESET_ACK, in_msg_buf, from_tty); */ -/* OBSOLETE printf ("Target has been reset."); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE pop_target (); */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /***************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Load a program into the target. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE mm_load (char *arg_string, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE dont_repeat (); */ -/* OBSOLETE */ -/* OBSOLETE #if defined(KERNEL_DEBUGGING) */ -/* OBSOLETE printf ("The kernel had better be loaded already! Loading not done.\n"); */ -/* OBSOLETE #else */ -/* OBSOLETE if (arg_string == 0) */ -/* OBSOLETE error ("The load command takes a file name"); */ -/* OBSOLETE */ -/* OBSOLETE arg_string = tilde_expand (arg_string); */ -/* OBSOLETE make_cleanup (xfree, arg_string); */ -/* OBSOLETE QUIT; */ -/* OBSOLETE immediate_quit++; */ -/* OBSOLETE error ("File loading is not yet supported for MiniMon."); */ -/* OBSOLETE /* FIXME, code to load your file here... */ */ -/* OBSOLETE /* You may need to do an init_target_mm() */ */ -/* OBSOLETE /* init_target_mm(?,?,?,?,?,?,?,?); */ */ -/* OBSOLETE immediate_quit--; */ -/* OBSOLETE /* symbol_file_add (arg_string, from_tty, text_addr, 0, 0); */ */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /************************************************ REMOTE_WRITE_INFERIOR_MEMORY */ -/* OBSOLETE ** Copy LEN bytes of data from debugger memory at MYADDR */ -/* OBSOLETE to inferior's memory at MEMADDR. Returns number of bytes written. */ */ -/* OBSOLETE static int */ -/* OBSOLETE mm_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int i, nwritten; */ -/* OBSOLETE */ -/* OBSOLETE out_msg_buf->write_req_msg.code = WRITE_REQ; */ -/* OBSOLETE out_msg_buf->write_req_msg.memory_space = mm_memory_space (memaddr); */ -/* OBSOLETE */ -/* OBSOLETE nwritten = 0; */ -/* OBSOLETE while (nwritten < len) */ -/* OBSOLETE { */ -/* OBSOLETE int num_to_write = len - nwritten; */ -/* OBSOLETE if (num_to_write > MAXDATA) */ -/* OBSOLETE num_to_write = MAXDATA; */ -/* OBSOLETE for (i = 0; i < num_to_write; i++) */ -/* OBSOLETE out_msg_buf->write_req_msg.data[i] = myaddr[i + nwritten]; */ -/* OBSOLETE out_msg_buf->write_req_msg.byte_count = num_to_write; */ -/* OBSOLETE out_msg_buf->write_req_msg.length = 3 * 4 + num_to_write; */ -/* OBSOLETE out_msg_buf->write_req_msg.address = memaddr + nwritten; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE */ -/* OBSOLETE if (expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE nwritten += in_msg_buf->write_ack_msg.byte_count; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE return (nwritten); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /************************************************* REMOTE_READ_INFERIOR_MEMORY */ -/* OBSOLETE ** Read LEN bytes from inferior memory at MEMADDR. Put the result */ -/* OBSOLETE at debugger address MYADDR. Returns number of bytes read. */ */ -/* OBSOLETE static int */ -/* OBSOLETE mm_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int i, nread; */ -/* OBSOLETE */ -/* OBSOLETE out_msg_buf->read_req_msg.code = READ_REQ; */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = mm_memory_space (memaddr); */ -/* OBSOLETE */ -/* OBSOLETE nread = 0; */ -/* OBSOLETE while (nread < len) */ -/* OBSOLETE { */ -/* OBSOLETE int num_to_read = (len - nread); */ -/* OBSOLETE if (num_to_read > MAXDATA) */ -/* OBSOLETE num_to_read = MAXDATA; */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = num_to_read; */ -/* OBSOLETE out_msg_buf->read_req_msg.length = 3 * 4 + num_to_read; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = memaddr + nread; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE */ -/* OBSOLETE if (expect_msg (READ_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE for (i = 0; i < in_msg_buf->read_ack_msg.byte_count; i++) */ -/* OBSOLETE myaddr[i + nread] = in_msg_buf->read_ack_msg.data[i]; */ -/* OBSOLETE nread += in_msg_buf->read_ack_msg.byte_count; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE return (nread); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* FIXME! Merge these two. */ */ -/* OBSOLETE static int */ -/* OBSOLETE mm_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, */ -/* OBSOLETE struct mem_attrib *attrib ATTRIBUTE_UNUSED, */ -/* OBSOLETE struct target_ops *target ATTRIBUTE_UNUSED) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE memaddr = translate_addr (memaddr); */ -/* OBSOLETE */ -/* OBSOLETE if (write) */ -/* OBSOLETE return mm_write_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE else */ -/* OBSOLETE return mm_read_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************** MSG_SEND_SERIAL */ -/* OBSOLETE ** This function is used to send a message over the */ -/* OBSOLETE ** serial line. */ -/* OBSOLETE ** */ -/* OBSOLETE ** If the message is successfully sent, a zero is */ -/* OBSOLETE ** returned. If the message was not sendable, a -1 */ -/* OBSOLETE ** is returned. This function blocks. That is, it */ -/* OBSOLETE ** does not return until the message is completely */ -/* OBSOLETE ** sent, or until an error is encountered. */ -/* OBSOLETE ** */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE int */ -/* OBSOLETE msg_send_serial (union msg_t *msg_ptr) */ -/* OBSOLETE { */ -/* OBSOLETE INT32 message_size; */ -/* OBSOLETE int byte_count; */ -/* OBSOLETE int result; */ -/* OBSOLETE char c; */ -/* OBSOLETE */ -/* OBSOLETE /* Send message header */ */ -/* OBSOLETE byte_count = 0; */ -/* OBSOLETE message_size = msg_ptr->generic_msg.length + (2 * sizeof (INT32)); */ -/* OBSOLETE do */ -/* OBSOLETE { */ -/* OBSOLETE c = *((char *) msg_ptr + byte_count); */ -/* OBSOLETE result = write (mm_desc, &c, 1); */ -/* OBSOLETE if (result == 1) */ -/* OBSOLETE { */ -/* OBSOLETE byte_count = byte_count + 1; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE while ((byte_count < message_size)); */ -/* OBSOLETE */ -/* OBSOLETE return (0); */ -/* OBSOLETE } /* end msg_send_serial() */ */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************** MSG_RECV_SERIAL */ -/* OBSOLETE ** This function is used to receive a message over a */ -/* OBSOLETE ** serial line. */ -/* OBSOLETE ** */ -/* OBSOLETE ** If the message is waiting in the buffer, a zero is */ -/* OBSOLETE ** returned and the buffer pointed to by msg_ptr is filled */ -/* OBSOLETE ** in. If no message was available, a -1 is returned. */ -/* OBSOLETE ** If timeout==0, wait indefinetly for a character. */ -/* OBSOLETE ** */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE int */ -/* OBSOLETE msg_recv_serial (union msg_t *msg_ptr) */ -/* OBSOLETE { */ -/* OBSOLETE static INT32 length = 0; */ -/* OBSOLETE static INT32 byte_count = 0; */ -/* OBSOLETE int result; */ -/* OBSOLETE char c; */ -/* OBSOLETE if (msg_ptr == 0) /* re-sync request */ */ -/* OBSOLETE { */ -/* OBSOLETE length = 0; */ -/* OBSOLETE byte_count = 0; */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE /* The timeout here is the prevailing timeout set with VTIME */ */ -/* OBSOLETE ->"timeout==0 semantics not supported" */ -/* OBSOLETE read (mm_desc, in_buf, BUFER_SIZE); */ -/* OBSOLETE #else */ -/* OBSOLETE alarm (1); */ -/* OBSOLETE read (mm_desc, in_buf, BUFER_SIZE); */ -/* OBSOLETE alarm (0); */ -/* OBSOLETE #endif */ -/* OBSOLETE return (0); */ -/* OBSOLETE } */ -/* OBSOLETE /* Receive message */ */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE /* Timeout==0, help support the mm_wait() routine */ */ -/* OBSOLETE ->"timeout==0 semantics not supported (and its nice if they are)" */ -/* OBSOLETE result = read (mm_desc, &c, 1); */ -/* OBSOLETE #else */ -/* OBSOLETE alarm (timeout); */ -/* OBSOLETE result = read (mm_desc, &c, 1); */ -/* OBSOLETE alarm (0); */ -/* OBSOLETE #endif */ -/* OBSOLETE if (result < 0) */ -/* OBSOLETE { */ -/* OBSOLETE if (errno == EINTR) */ -/* OBSOLETE { */ -/* OBSOLETE error ("Timeout reading from remote system."); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE perror_with_name ("remote"); */ -/* OBSOLETE } */ -/* OBSOLETE else if (result == 1) */ -/* OBSOLETE { */ -/* OBSOLETE *((char *) msg_ptr + byte_count) = c; */ -/* OBSOLETE byte_count = byte_count + 1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Message header received. Save message length. */ */ -/* OBSOLETE if (byte_count == (2 * sizeof (INT32))) */ -/* OBSOLETE length = msg_ptr->generic_msg.length; */ -/* OBSOLETE */ -/* OBSOLETE if (byte_count >= (length + (2 * sizeof (INT32)))) */ -/* OBSOLETE { */ -/* OBSOLETE /* Message received */ */ -/* OBSOLETE byte_count = 0; */ -/* OBSOLETE return (0); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE return (-1); */ -/* OBSOLETE */ -/* OBSOLETE } /* end msg_recv_serial() */ */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************************* KBD_RAW */ -/* OBSOLETE ** This function is used to put the keyboard in "raw" */ -/* OBSOLETE ** mode for BSD Unix. The original status is saved */ -/* OBSOLETE ** so that it may be restored later. */ -/* OBSOLETE */ */ -/* OBSOLETE TERMINAL kbd_tbuf; */ -/* OBSOLETE */ -/* OBSOLETE int */ -/* OBSOLETE kbd_raw (void) */ -/* OBSOLETE { */ -/* OBSOLETE int result; */ -/* OBSOLETE TERMINAL tbuf; */ -/* OBSOLETE */ -/* OBSOLETE /* Get keyboard termio (to save to restore original modes) */ */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE result = ioctl (0, TCGETA, &kbd_tbuf); */ -/* OBSOLETE #else */ -/* OBSOLETE result = ioctl (0, TIOCGETP, &kbd_tbuf); */ -/* OBSOLETE #endif */ -/* OBSOLETE if (result == -1) */ -/* OBSOLETE return (errno); */ -/* OBSOLETE */ -/* OBSOLETE /* Get keyboard TERMINAL (for modification) */ */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE result = ioctl (0, TCGETA, &tbuf); */ -/* OBSOLETE #else */ -/* OBSOLETE result = ioctl (0, TIOCGETP, &tbuf); */ -/* OBSOLETE #endif */ -/* OBSOLETE if (result == -1) */ -/* OBSOLETE return (errno); */ -/* OBSOLETE */ -/* OBSOLETE /* Set up new parameters */ */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE tbuf.c_iflag = tbuf.c_iflag & */ -/* OBSOLETE ~(INLCR | ICRNL | IUCLC | ISTRIP | IXON | BRKINT); */ -/* OBSOLETE tbuf.c_lflag = tbuf.c_lflag & ~(ICANON | ISIG | ECHO); */ -/* OBSOLETE tbuf.c_cc[4] = 0; /* MIN */ */ -/* OBSOLETE tbuf.c_cc[5] = 0; /* TIME */ */ -/* OBSOLETE #else */ -/* OBSOLETE /* FIXME: not sure if this is correct (matches HAVE_TERMIO). */ */ -/* OBSOLETE tbuf.sg_flags |= RAW; */ -/* OBSOLETE tbuf.sg_flags |= ANYP; */ -/* OBSOLETE tbuf.sg_flags &= ~ECHO; */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* Set keyboard termio to new mode (RAW) */ */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE result = ioctl (0, TCSETAF, &tbuf); */ -/* OBSOLETE #else */ -/* OBSOLETE result = ioctl (0, TIOCSETP, &tbuf); */ -/* OBSOLETE #endif */ -/* OBSOLETE if (result == -1) */ -/* OBSOLETE return (errno); */ -/* OBSOLETE */ -/* OBSOLETE return (0); */ -/* OBSOLETE } /* end kbd_raw() */ */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /***************************************************************** KBD_RESTORE */ -/* OBSOLETE ** This function is used to put the keyboard back in the */ -/* OBSOLETE ** mode it was in before kbk_raw was called. Note that */ -/* OBSOLETE ** kbk_raw() must have been called at least once before */ -/* OBSOLETE ** kbd_restore() is called. */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE int */ -/* OBSOLETE kbd_restore (void) */ -/* OBSOLETE { */ -/* OBSOLETE int result; */ -/* OBSOLETE */ -/* OBSOLETE /* Set keyboard termio to original mode */ */ -/* OBSOLETE #ifdef HAVE_TERMIO */ -/* OBSOLETE result = ioctl (0, TCSETAF, &kbd_tbuf); */ -/* OBSOLETE #else */ -/* OBSOLETE result = ioctl (0, TIOCGETP, &kbd_tbuf); */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE if (result == -1) */ -/* OBSOLETE return (errno); */ -/* OBSOLETE */ -/* OBSOLETE return (0); */ -/* OBSOLETE } /* end kbd_cooked() */ */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /*****************************************************************************/ */ -/* OBSOLETE /* Fetch a single register indicatated by 'regno'. */ -/* OBSOLETE * Returns 0/-1 on success/failure. */ -/* OBSOLETE */ */ -/* OBSOLETE static int */ -/* OBSOLETE fetch_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE int result; */ -/* OBSOLETE out_msg_buf->read_req_msg.code = READ_REQ; */ -/* OBSOLETE out_msg_buf->read_req_msg.length = 4 * 3; */ -/* OBSOLETE out_msg_buf->read_req_msg.byte_count = 4; */ -/* OBSOLETE */ -/* OBSOLETE if (regno == GR1_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = 1; */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = (regno - GR96_REGNUM) + 96; */ -/* OBSOLETE } */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = (regno - GR64_REGNUM) + 64; */ -/* OBSOLETE } */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = LOCAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = (regno - LR0_REGNUM); */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE int val = -1; */ -/* OBSOLETE supply_register (160 + (regno - FPE_REGNUM), &val); */ -/* OBSOLETE return 0; /* Pretend Success */ */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->read_req_msg.memory_space = SPECIAL_REG; */ -/* OBSOLETE out_msg_buf->read_req_msg.address = regnum_to_srnum (regno); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE */ -/* OBSOLETE if (expect_msg (READ_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE supply_register (regno, &(in_msg_buf->read_r_ack_msg.data[0])); */ -/* OBSOLETE result = 0; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE return result; */ -/* OBSOLETE } */ -/* OBSOLETE /*****************************************************************************/ */ -/* OBSOLETE /* Store a single register indicated by 'regno'. */ -/* OBSOLETE * Returns 0/-1 on success/failure. */ -/* OBSOLETE */ */ -/* OBSOLETE static int */ -/* OBSOLETE store_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE int result; */ -/* OBSOLETE */ -/* OBSOLETE out_msg_buf->write_req_msg.code = WRITE_REQ; */ -/* OBSOLETE out_msg_buf->write_req_msg.length = 4 * 4; */ -/* OBSOLETE out_msg_buf->write_req_msg.byte_count = 4; */ -/* OBSOLETE out_msg_buf->write_r_msg.data[0] = read_register (regno); */ -/* OBSOLETE */ -/* OBSOLETE if (regno == GR1_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->write_req_msg.address = 1; */ -/* OBSOLETE /* Setting GR1 changes the numbers of all the locals, so invalidate the */ -/* OBSOLETE * register cache. Do this *after* calling read_register, because we want */ -/* OBSOLETE * read_register to return the value that write_register has just stuffed */ -/* OBSOLETE * into the registers array, not the value of the register fetched from */ -/* OBSOLETE * the inferior. */ -/* OBSOLETE */ */ -/* OBSOLETE registers_changed (); */ -/* OBSOLETE } */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->write_req_msg.address = (regno - GR64_REGNUM) + 64; */ -/* OBSOLETE } */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_req_msg.memory_space = GLOBAL_REG; */ -/* OBSOLETE out_msg_buf->write_req_msg.address = (regno - GR96_REGNUM) + 96; */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_req_msg.memory_space = LOCAL_REG; */ -/* OBSOLETE out_msg_buf->write_req_msg.address = (regno - LR0_REGNUM); */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE return 0; /* Pretend Success */ */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE /* An unprotected or protected special register */ */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->write_req_msg.memory_space = SPECIAL_REG; */ -/* OBSOLETE out_msg_buf->write_req_msg.address = regnum_to_srnum (regno); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE */ -/* OBSOLETE if (expect_msg (WRITE_ACK, in_msg_buf, 1)) */ -/* OBSOLETE { */ -/* OBSOLETE result = 0; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE result = -1; */ -/* OBSOLETE } */ -/* OBSOLETE return result; */ -/* OBSOLETE } */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Convert a gdb special register number to a 29000 special register number. */ -/* OBSOLETE */ */ -/* OBSOLETE static int */ -/* OBSOLETE regnum_to_srnum (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE switch (regno) */ -/* OBSOLETE { */ -/* OBSOLETE case VAB_REGNUM: */ -/* OBSOLETE return (0); */ -/* OBSOLETE case OPS_REGNUM: */ -/* OBSOLETE return (1); */ -/* OBSOLETE case CPS_REGNUM: */ -/* OBSOLETE return (2); */ -/* OBSOLETE case CFG_REGNUM: */ -/* OBSOLETE return (3); */ -/* OBSOLETE case CHA_REGNUM: */ -/* OBSOLETE return (4); */ -/* OBSOLETE case CHD_REGNUM: */ -/* OBSOLETE return (5); */ -/* OBSOLETE case CHC_REGNUM: */ -/* OBSOLETE return (6); */ -/* OBSOLETE case RBP_REGNUM: */ -/* OBSOLETE return (7); */ -/* OBSOLETE case TMC_REGNUM: */ -/* OBSOLETE return (8); */ -/* OBSOLETE case TMR_REGNUM: */ -/* OBSOLETE return (9); */ -/* OBSOLETE case NPC_REGNUM: */ -/* OBSOLETE return (USE_SHADOW_PC ? (20) : (10)); */ -/* OBSOLETE case PC_REGNUM: */ -/* OBSOLETE return (USE_SHADOW_PC ? (21) : (11)); */ -/* OBSOLETE case PC2_REGNUM: */ -/* OBSOLETE return (USE_SHADOW_PC ? (22) : (12)); */ -/* OBSOLETE case MMU_REGNUM: */ -/* OBSOLETE return (13); */ -/* OBSOLETE case LRU_REGNUM: */ -/* OBSOLETE return (14); */ -/* OBSOLETE case IPC_REGNUM: */ -/* OBSOLETE return (128); */ -/* OBSOLETE case IPA_REGNUM: */ -/* OBSOLETE return (129); */ -/* OBSOLETE case IPB_REGNUM: */ -/* OBSOLETE return (130); */ -/* OBSOLETE case Q_REGNUM: */ -/* OBSOLETE return (131); */ -/* OBSOLETE case ALU_REGNUM: */ -/* OBSOLETE return (132); */ -/* OBSOLETE case BP_REGNUM: */ -/* OBSOLETE return (133); */ -/* OBSOLETE case FC_REGNUM: */ -/* OBSOLETE return (134); */ -/* OBSOLETE case CR_REGNUM: */ -/* OBSOLETE return (135); */ -/* OBSOLETE case FPE_REGNUM: */ -/* OBSOLETE return (160); */ -/* OBSOLETE case INTE_REGNUM: */ -/* OBSOLETE return (161); */ -/* OBSOLETE case FPS_REGNUM: */ -/* OBSOLETE return (162); */ -/* OBSOLETE case EXO_REGNUM: */ -/* OBSOLETE return (164); */ -/* OBSOLETE default: */ -/* OBSOLETE return (255); /* Failure ? */ */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Initialize the target debugger (minimon only). */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE init_target_mm (ADDR32 tstart, ADDR32 tend, ADDR32 dstart, ADDR32 dend, */ -/* OBSOLETE ADDR32 entry, INT32 ms_size, INT32 rs_size, ADDR32 arg_start) */ -/* OBSOLETE { */ -/* OBSOLETE out_msg_buf->init_msg.code = INIT; */ -/* OBSOLETE out_msg_buf->init_msg.length = sizeof (struct init_msg_t) - 2 * sizeof (INT32); */ -/* OBSOLETE out_msg_buf->init_msg.text_start = tstart; */ -/* OBSOLETE out_msg_buf->init_msg.text_end = tend; */ -/* OBSOLETE out_msg_buf->init_msg.data_start = dstart; */ -/* OBSOLETE out_msg_buf->init_msg.data_end = dend; */ -/* OBSOLETE out_msg_buf->init_msg.entry_point = entry; */ -/* OBSOLETE out_msg_buf->init_msg.mem_stack_size = ms_size; */ -/* OBSOLETE out_msg_buf->init_msg.reg_stack_size = rs_size; */ -/* OBSOLETE out_msg_buf->init_msg.arg_start = arg_start; */ -/* OBSOLETE msg_send_serial (out_msg_buf); */ -/* OBSOLETE expect_msg (INIT_ACK, in_msg_buf, 1); */ -/* OBSOLETE } */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Return a pointer to a string representing the given message code. */ -/* OBSOLETE * Not all messages are represented here, only the ones that we expect */ -/* OBSOLETE * to be called with. */ -/* OBSOLETE */ */ -/* OBSOLETE static char * */ -/* OBSOLETE msg_str (INT32 code) */ -/* OBSOLETE { */ -/* OBSOLETE static char cbuf[32]; */ -/* OBSOLETE */ -/* OBSOLETE switch (code) */ -/* OBSOLETE { */ -/* OBSOLETE case BKPT_SET_ACK: */ -/* OBSOLETE sprintf (cbuf, "%s (%d)", "BKPT_SET_ACK", code); */ -/* OBSOLETE break; */ -/* OBSOLETE case BKPT_RM_ACK: */ -/* OBSOLETE sprintf (cbuf, "%s (%d)", "BKPT_RM_ACK", code); */ -/* OBSOLETE break; */ -/* OBSOLETE case INIT_ACK: */ -/* OBSOLETE sprintf (cbuf, "%s (%d)", "INIT_ACK", code); */ -/* OBSOLETE break; */ -/* OBSOLETE case READ_ACK: */ -/* OBSOLETE sprintf (cbuf, "%s (%d)", "READ_ACK", code); */ -/* OBSOLETE break; */ -/* OBSOLETE case WRITE_ACK: */ -/* OBSOLETE sprintf (cbuf, "%s (%d)", "WRITE_ACK", code); */ -/* OBSOLETE break; */ -/* OBSOLETE case ERROR: */ -/* OBSOLETE sprintf (cbuf, "%s (%d)", "ERROR", code); */ -/* OBSOLETE break; */ -/* OBSOLETE case HALT: */ -/* OBSOLETE sprintf (cbuf, "%s (%d)", "HALT", code); */ -/* OBSOLETE break; */ -/* OBSOLETE default: */ -/* OBSOLETE sprintf (cbuf, "UNKNOWN (%d)", code); */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE return (cbuf); */ -/* OBSOLETE } */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Selected (not all of them) error codes that we might get. */ -/* OBSOLETE */ */ -/* OBSOLETE static char * */ -/* OBSOLETE error_msg_str (INT32 code) */ -/* OBSOLETE { */ -/* OBSOLETE static char cbuf[50]; */ -/* OBSOLETE */ -/* OBSOLETE switch (code) */ -/* OBSOLETE { */ -/* OBSOLETE case EMFAIL: */ -/* OBSOLETE return ("EMFAIL: unrecoverable error"); */ -/* OBSOLETE case EMBADADDR: */ -/* OBSOLETE return ("EMBADADDR: Illegal address"); */ -/* OBSOLETE case EMBADREG: */ -/* OBSOLETE return ("EMBADREG: Illegal register "); */ -/* OBSOLETE case EMACCESS: */ -/* OBSOLETE return ("EMACCESS: Could not access memory"); */ -/* OBSOLETE case EMBADMSG: */ -/* OBSOLETE return ("EMBADMSG: Unknown message type"); */ -/* OBSOLETE case EMMSG2BIG: */ -/* OBSOLETE return ("EMMSG2BIG: Message to large"); */ -/* OBSOLETE case EMNOSEND: */ -/* OBSOLETE return ("EMNOSEND: Could not send message"); */ -/* OBSOLETE case EMNORECV: */ -/* OBSOLETE return ("EMNORECV: Could not recv message"); */ -/* OBSOLETE case EMRESET: */ -/* OBSOLETE return ("EMRESET: Could not RESET target"); */ -/* OBSOLETE case EMCONFIG: */ -/* OBSOLETE return ("EMCONFIG: Could not get target CONFIG"); */ -/* OBSOLETE case EMSTATUS: */ -/* OBSOLETE return ("EMSTATUS: Could not get target STATUS"); */ -/* OBSOLETE case EMREAD: */ -/* OBSOLETE return ("EMREAD: Could not READ target memory"); */ -/* OBSOLETE case EMWRITE: */ -/* OBSOLETE return ("EMWRITE: Could not WRITE target memory"); */ -/* OBSOLETE case EMBKPTSET: */ -/* OBSOLETE return ("EMBKPTSET: Could not set breakpoint"); */ -/* OBSOLETE case EMBKPTRM: */ -/* OBSOLETE return ("EMBKPTRM: Could not remove breakpoint"); */ -/* OBSOLETE case EMBKPTSTAT: */ -/* OBSOLETE return ("EMBKPTSTAT: Could not get breakpoint status"); */ -/* OBSOLETE case EMBKPTNONE: */ -/* OBSOLETE return ("EMBKPTNONE: All breakpoints in use"); */ -/* OBSOLETE case EMBKPTUSED: */ -/* OBSOLETE return ("EMBKPTUSED: Breakpoints already in use"); */ -/* OBSOLETE case EMINIT: */ -/* OBSOLETE return ("EMINIT: Could not init target memory"); */ -/* OBSOLETE case EMGO: */ -/* OBSOLETE return ("EMGO: Could not start execution"); */ -/* OBSOLETE case EMSTEP: */ -/* OBSOLETE return ("EMSTEP: Could not single step"); */ -/* OBSOLETE case EMBREAK: */ -/* OBSOLETE return ("EMBREAK: Could not BREAK"); */ -/* OBSOLETE case EMCOMMERR: */ -/* OBSOLETE return ("EMCOMMERR: Communication error"); */ -/* OBSOLETE default: */ -/* OBSOLETE sprintf (cbuf, "error number %d", code); */ -/* OBSOLETE break; */ -/* OBSOLETE } /* end switch */ */ -/* OBSOLETE */ -/* OBSOLETE return (cbuf); */ -/* OBSOLETE } */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE */ -/* OBSOLETE /* Receive a message, placing it in MSG_BUF, and expect it to be of */ -/* OBSOLETE type MSGCODE. If an error occurs, a non-zero FROM_TTY indicates */ -/* OBSOLETE that the message should be printed. */ -/* OBSOLETE */ -/* OBSOLETE Return 0 for failure, 1 for success. */ */ -/* OBSOLETE */ -/* OBSOLETE static int */ -/* OBSOLETE expect_msg (INT32 msgcode, union msg_t *msg_buf, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE int retries = 0; */ -/* OBSOLETE while (msg_recv_serial (msg_buf) && (retries++ < MAX_RETRIES)); */ -/* OBSOLETE if (retries >= MAX_RETRIES) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Expected msg %s, ", msg_str (msgcode)); */ -/* OBSOLETE printf ("no message received!\n"); */ -/* OBSOLETE return (0); /* Failure */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (msg_buf->generic_msg.code != msgcode) */ -/* OBSOLETE { */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE printf ("Expected msg %s, ", msg_str (msgcode)); */ -/* OBSOLETE printf ("got msg %s\n", msg_str (msg_buf->generic_msg.code)); */ -/* OBSOLETE if (msg_buf->generic_msg.code == ERROR) */ -/* OBSOLETE printf ("%s\n", error_msg_str (msg_buf->error_msg.error_code)); */ -/* OBSOLETE } */ -/* OBSOLETE return (0); /* Failure */ */ -/* OBSOLETE } */ -/* OBSOLETE return (1); /* Success */ */ -/* OBSOLETE } */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Determine the MiniMon memory space qualifier based on the addr. */ -/* OBSOLETE * FIXME: Can't distinguis I_ROM/D_ROM. */ -/* OBSOLETE * FIXME: Doesn't know anything about I_CACHE/D_CACHE. */ -/* OBSOLETE */ */ -/* OBSOLETE static int */ -/* OBSOLETE mm_memory_space (CORE_ADDR *addr) */ -/* OBSOLETE { */ -/* OBSOLETE ADDR32 tstart = target_config.I_mem_start; */ -/* OBSOLETE ADDR32 tend = tstart + target_config.I_mem_size; */ -/* OBSOLETE ADDR32 dstart = target_config.D_mem_start; */ -/* OBSOLETE ADDR32 dend = tstart + target_config.D_mem_size; */ -/* OBSOLETE ADDR32 rstart = target_config.ROM_start; */ -/* OBSOLETE ADDR32 rend = tstart + target_config.ROM_size; */ -/* OBSOLETE */ -/* OBSOLETE if (((ADDR32) addr >= tstart) && ((ADDR32) addr < tend)) */ -/* OBSOLETE { */ -/* OBSOLETE return I_MEM; */ -/* OBSOLETE } */ -/* OBSOLETE else if (((ADDR32) addr >= dstart) && ((ADDR32) addr < dend)) */ -/* OBSOLETE { */ -/* OBSOLETE return D_MEM; */ -/* OBSOLETE } */ -/* OBSOLETE else if (((ADDR32) addr >= rstart) && ((ADDR32) addr < rend)) */ -/* OBSOLETE { */ -/* OBSOLETE /* FIXME: how do we determine between D_ROM and I_ROM */ */ -/* OBSOLETE return D_ROM; */ -/* OBSOLETE } */ -/* OBSOLETE else /* FIXME: what do me do now? */ */ -/* OBSOLETE return D_MEM; /* Hmmm! */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Define the target subroutine names */ -/* OBSOLETE */ */ -/* OBSOLETE struct target_ops mm_ops; */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE init_mm_ops (void) */ -/* OBSOLETE { */ -/* OBSOLETE mm_ops.to_shortname = "minimon"; */ -/* OBSOLETE mm_ops.to_longname = "Remote AMD/Minimon target"; */ -/* OBSOLETE mm_ops.to_doc = "Remote debug an AMD 290*0 using the MiniMon dbg core on the target"; */ -/* OBSOLETE mm_ops.to_open = mm_open; */ -/* OBSOLETE mm_ops.to_close = mm_close; */ -/* OBSOLETE mm_ops.to_attach = mm_attach; */ -/* OBSOLETE mm_ops.to_post_attach = NULL; */ -/* OBSOLETE mm_ops.to_require_attach = NULL; */ -/* OBSOLETE mm_ops.to_detach = mm_detach; */ -/* OBSOLETE mm_ops.to_require_detach = NULL; */ -/* OBSOLETE mm_ops.to_resume = mm_resume; */ -/* OBSOLETE mm_ops.to_wait = mm_wait; */ -/* OBSOLETE mm_ops.to_post_wait = NULL; */ -/* OBSOLETE mm_ops.to_fetch_registers = mm_fetch_registers; */ -/* OBSOLETE mm_ops.to_store_registers = mm_store_registers; */ -/* OBSOLETE mm_ops.to_prepare_to_store = mm_prepare_to_store; */ -/* OBSOLETE mm_ops.to_xfer_memory = mm_xfer_inferior_memory; */ -/* OBSOLETE mm_ops.to_files_info = mm_files_info; */ -/* OBSOLETE mm_ops.to_insert_breakpoint = mm_insert_breakpoint; */ -/* OBSOLETE mm_ops.to_remove_breakpoint = mm_remove_breakpoint; */ -/* OBSOLETE mm_ops.to_terminal_init = 0; */ -/* OBSOLETE mm_ops.to_terminal_inferior = 0; */ -/* OBSOLETE mm_ops.to_terminal_ours_for_output = 0; */ -/* OBSOLETE mm_ops.to_terminal_ours = 0; */ -/* OBSOLETE mm_ops.to_terminal_info = 0; */ -/* OBSOLETE mm_ops.to_kill = mm_kill; */ -/* OBSOLETE mm_ops.to_load = mm_load; */ -/* OBSOLETE mm_ops.to_lookup_symbol = 0; */ -/* OBSOLETE mm_ops.to_create_inferior = mm_create_inferior; */ -/* OBSOLETE mm_ops.to_post_startup_inferior = NULL; */ -/* OBSOLETE mm_ops.to_acknowledge_created_inferior = NULL; */ -/* OBSOLETE mm_ops.to_clone_and_follow_inferior = NULL; */ -/* OBSOLETE mm_ops.to_post_follow_inferior_by_clone = NULL; */ -/* OBSOLETE mm_ops.to_insert_fork_catchpoint = NULL; */ -/* OBSOLETE mm_ops.to_remove_fork_catchpoint = NULL; */ -/* OBSOLETE mm_ops.to_insert_vfork_catchpoint = NULL; */ -/* OBSOLETE mm_ops.to_remove_vfork_catchpoint = NULL; */ -/* OBSOLETE mm_ops.to_has_forked = NULL; */ -/* OBSOLETE mm_ops.to_has_vforked = NULL; */ -/* OBSOLETE mm_ops.to_can_follow_vfork_prior_to_exec = NULL; */ -/* OBSOLETE mm_ops.to_post_follow_vfork = NULL; */ -/* OBSOLETE mm_ops.to_insert_exec_catchpoint = NULL; */ -/* OBSOLETE mm_ops.to_remove_exec_catchpoint = NULL; */ -/* OBSOLETE mm_ops.to_has_execd = NULL; */ -/* OBSOLETE mm_ops.to_reported_exec_events_per_exec_call = NULL; */ -/* OBSOLETE mm_ops.to_has_exited = NULL; */ -/* OBSOLETE mm_ops.to_mourn_inferior = mm_mourn; */ -/* OBSOLETE mm_ops.to_can_run = 0; */ -/* OBSOLETE mm_ops.to_notice_signals = 0; */ -/* OBSOLETE mm_ops.to_thread_alive = 0; */ -/* OBSOLETE mm_ops.to_stop = 0; */ -/* OBSOLETE mm_ops.to_pid_to_exec_file = NULL; */ -/* OBSOLETE mm_ops.to_stratum = process_stratum; */ -/* OBSOLETE mm_ops.DONT_USE = 0; */ -/* OBSOLETE mm_ops.to_has_all_memory = 1; */ -/* OBSOLETE mm_ops.to_has_memory = 1; */ -/* OBSOLETE mm_ops.to_has_stack = 1; */ -/* OBSOLETE mm_ops.to_has_registers = 1; */ -/* OBSOLETE mm_ops.to_has_execution = 1; */ -/* OBSOLETE mm_ops.to_sections = 0; */ -/* OBSOLETE mm_ops.to_sections_end = 0; */ -/* OBSOLETE mm_ops.to_magic = OPS_MAGIC; */ -/* OBSOLETE }; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE _initialize_remote_mm (void) */ -/* OBSOLETE { */ -/* OBSOLETE init_mm_ops (); */ -/* OBSOLETE add_target (&mm_ops); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #ifdef NO_HIF_SUPPORT */ -/* OBSOLETE service_HIF (union msg_t *msg) */ -/* OBSOLETE { */ -/* OBSOLETE return (0); /* Emulate a failure */ */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ diff --git a/contrib/gdb/gdb/remote-nindy.c b/contrib/gdb/gdb/remote-nindy.c deleted file mode 100644 index 679dfad919e..00000000000 --- a/contrib/gdb/gdb/remote-nindy.c +++ /dev/null @@ -1,762 +0,0 @@ -/* Memory-access and commands for remote NINDY process, for GDB. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, - 2000, 2001, 2002 Free Software Foundation, Inc. - - Contributed by Intel Corporation. Modified from remote.c by Chris Benenati. - - GDB is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY. No author or distributor accepts responsibility to anyone - for the consequences of using it or for whether it serves any - particular purpose or works at all, unless he says so in writing. - Refer to the GDB General Public License for full details. - - Everyone is granted permission to copy, modify and redistribute GDB, - but only under the conditions described in the GDB General Public - License. A copy of this license is supposed to have been given to you - along with GDB so you can know your rights and responsibilities. It - should be in a file named COPYING. Among other things, the copyright - notice and this notice must be preserved on all copies. - - In other words, go ahead and share GDB, but don't try to stop - anyone else from sharing it farther. Help stamp out software hoarding! */ - -/* - Except for the data cache routines, this file bears little resemblence - to remote.c. A new (although similar) protocol has been specified, and - portions of the code are entirely dependent on having an i80960 with a - NINDY ROM monitor at the other end of the line. - */ - -/***************************************************************************** - * - * REMOTE COMMUNICATION PROTOCOL BETWEEN GDB960 AND THE NINDY ROM MONITOR. - * - * - * MODES OF OPERATION - * ----- -- --------- - * - * As far as NINDY is concerned, GDB is always in one of two modes: command - * mode or passthrough mode. - * - * In command mode (the default) pre-defined packets containing requests - * are sent by GDB to NINDY. NINDY never talks except in reponse to a request. - * - * Once the the user program is started, GDB enters passthrough mode, to give - * the user program access to the terminal. GDB remains in this mode until - * NINDY indicates that the program has stopped. - * - * - * PASSTHROUGH MODE - * ----------- ---- - * - * GDB writes all input received from the keyboard directly to NINDY, and writes - * all characters received from NINDY directly to the monitor. - * - * Keyboard input is neither buffered nor echoed to the monitor. - * - * GDB remains in passthrough mode until NINDY sends a single ^P character, - * to indicate that the user process has stopped. - * - * Note: - * GDB assumes NINDY performs a 'flushreg' when the user program stops. - * - * - * COMMAND MODE - * ------- ---- - * - * All info (except for message ack and nak) is transferred between gdb - * and the remote processor in messages of the following format: - * - * # - * - * where - * # is a literal character - * - * ASCII information; all numeric information is in the - * form of hex digits ('0'-'9' and lowercase 'a'-'f'). - * - * - * is a pair of ASCII hex digits representing an 8-bit - * checksum formed by adding together each of the - * characters in . - * - * The receiver of a message always sends a single character to the sender - * to indicate that the checksum was good ('+') or bad ('-'); the sender - * re-transmits the entire message over until a '+' is received. - * - * In response to a command NINDY always sends back either data or - * a result code of the form "Xnn", where "nn" are hex digits and "X00" - * means no errors. (Exceptions: the "s" and "c" commands don't respond.) - * - * SEE THE HEADER OF THE FILE "gdb.c" IN THE NINDY MONITOR SOURCE CODE FOR A - * FULL DESCRIPTION OF LEGAL COMMANDS. - * - * SEE THE FILE "stop.h" IN THE NINDY MONITOR SOURCE CODE FOR A LIST - * OF STOP CODES. - * - ***************************************************************************/ - -#include "defs.h" -#include -#include -#include - -#include "frame.h" -#include "inferior.h" -#include "bfd.h" -#include "symfile.h" -#include "target.h" -#include "gdbcore.h" -#include "command.h" -#include "floatformat.h" -#include "regcache.h" - -#include -#include -#include "serial.h" -#include "nindy-share/env.h" -#include "nindy-share/stop.h" -#include "remote-utils.h" - -extern int unlink (); -extern char *getenv (); -extern char *mktemp (); - -extern void generic_mourn_inferior (); - -extern struct target_ops nindy_ops; -extern FILE *instream; - -extern char ninStopWhy (); -extern int ninMemGet (); -extern int ninMemPut (); - -int nindy_initial_brk; /* nonzero if want to send an initial BREAK to nindy */ -int nindy_old_protocol; /* nonzero if want to use old protocol */ -char *nindy_ttyname; /* name of tty to talk to nindy on, or null */ - -#define DLE '\020' /* Character NINDY sends to indicate user program has - * halted. */ -#define TRUE 1 -#define FALSE 0 - -/* From nindy-share/nindy.c. */ -extern struct serial *nindy_serial; - -static int have_regs = 0; /* 1 iff regs read since i960 last halted */ -static int regs_changed = 0; /* 1 iff regs were modified since last read */ - -extern char *exists (); - -static void nindy_fetch_registers (int); - -static void nindy_store_registers (int); - -static char *savename; - -static void -nindy_close (int quitting) -{ - if (nindy_serial != NULL) - serial_close (nindy_serial); - nindy_serial = NULL; - - if (savename) - xfree (savename); - savename = 0; -} - -/* Open a connection to a remote debugger. - FIXME, there should be "set" commands for the options that are - now specified with gdb command-line options (old_protocol, - and initial_brk). */ -void -nindy_open (char *name, /* "/dev/ttyXX", "ttyXX", or "XX": tty to be opened */ - int from_tty) -{ - char baudrate[1024]; - - if (!name) - error_no_arg ("serial port device name"); - - target_preopen (from_tty); - - nindy_close (0); - - have_regs = regs_changed = 0; - - /* Allow user to interrupt the following -- we could hang if there's - no NINDY at the other end of the remote tty. */ - immediate_quit++; - /* If baud_rate is -1, then ninConnect will not recognize the baud rate - and will deal with the situation in a (more or less) reasonable - fashion. */ - sprintf (baudrate, "%d", baud_rate); - ninConnect (name, baudrate, - nindy_initial_brk, !from_tty, nindy_old_protocol); - immediate_quit--; - - if (nindy_serial == NULL) - { - perror_with_name (name); - } - - savename = savestring (name, strlen (name)); - push_target (&nindy_ops); - - target_fetch_registers (-1); - - init_thread_list (); - init_wait_for_inferior (); - clear_proceed_status (); - normal_stop (); -} - -/* User-initiated quit of nindy operations. */ - -static void -nindy_detach (char *name, int from_tty) -{ - if (name) - error ("Too many arguments"); - pop_target (); -} - -static void -nindy_files_info (void) -{ - /* FIXME: this lies about the baud rate if we autobauded. */ - printf_unfiltered ("\tAttached to %s at %d bits per second%s%s.\n", savename, - baud_rate, - nindy_old_protocol ? " in old protocol" : "", - nindy_initial_brk ? " with initial break" : ""); -} - -/* Return the number of characters in the buffer BUF before - the first DLE character. N is maximum number of characters to - consider. */ - -static -int -non_dle (char *buf, int n) -{ - int i; - - for (i = 0; i < n; i++) - { - if (buf[i] == DLE) - { - break; - } - } - return i; -} - -/* Tell the remote machine to resume. */ - -void -nindy_resume (ptid_t ptid, int step, enum target_signal siggnal) -{ - if (siggnal != TARGET_SIGNAL_0 && siggnal != stop_signal) - warning ("Can't send signals to remote NINDY targets."); - - if (regs_changed) - { - nindy_store_registers (-1); - regs_changed = 0; - } - have_regs = 0; - ninGo (step); -} - -/* FIXME, we can probably use the normal terminal_inferior stuff here. - We have to do terminal_inferior and then set up the passthrough - settings initially. Thereafter, terminal_ours and terminal_inferior - will automatically swap the settings around for us. */ - -struct clean_up_tty_args -{ - serial_ttystate state; - struct serial *serial; -}; -static struct clean_up_tty_args tty_args; - -static void -clean_up_tty (PTR ptrarg) -{ - struct clean_up_tty_args *args = (struct clean_up_tty_args *) ptrarg; - serial_set_tty_state (args->serial, args->state); - xfree (args->state); - warning ("\n\nYou may need to reset the 80960 and/or reload your program.\n"); -} - -/* Recover from ^Z or ^C while remote process is running */ -static void (*old_ctrlc) (); -#ifdef SIGTSTP -static void (*old_ctrlz) (); -#endif - -static void -clean_up_int (void) -{ - serial_set_tty_state (tty_args.serial, tty_args.state); - xfree (tty_args.state); - - signal (SIGINT, old_ctrlc); -#ifdef SIGTSTP - signal (SIGTSTP, old_ctrlz); -#endif - error ("\n\nYou may need to reset the 80960 and/or reload your program.\n"); -} - -/* Wait until the remote machine stops. While waiting, operate in passthrough - * mode; i.e., pass everything NINDY sends to gdb_stdout, and everything from - * stdin to NINDY. - * - * Return to caller, storing status in 'status' just as `wait' would. - */ - -static ptid_t -nindy_wait (ptid_t ptid, struct target_waitstatus *status) -{ - fd_set fds; - int c; - char buf[2]; - int i, n; - unsigned char stop_exit; - unsigned char stop_code; - struct cleanup *old_cleanups; - long ip_value, fp_value, sp_value; /* Reg values from stop */ - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */ - - /* Save current tty attributes, and restore them when done. */ - tty_args.serial = serial_fdopen (0); - tty_args.state = serial_get_tty_state (tty_args.serial); - old_ctrlc = signal (SIGINT, clean_up_int); -#ifdef SIGTSTP - old_ctrlz = signal (SIGTSTP, clean_up_int); -#endif - - old_cleanups = make_cleanup (clean_up_tty, &tty_args); - - /* Pass input from keyboard to NINDY as it arrives. NINDY will interpret - and perform echo. */ - /* This used to set CBREAK and clear ECHO and CRMOD. I hope this is close - enough. */ - serial_raw (tty_args.serial); - - while (1) - { - /* Input on remote */ - c = serial_readchar (nindy_serial, -1); - if (c == SERIAL_ERROR) - { - error ("Cannot read from serial line"); - } - else if (c == 0x1b) /* ESC */ - { - c = serial_readchar (nindy_serial, -1); - c &= ~0x40; - } - else if (c != 0x10) /* DLE */ - /* Write out any characters preceding DLE */ - { - buf[0] = (char) c; - write (1, buf, 1); - } - else - { - stop_exit = ninStopWhy (&stop_code, - &ip_value, &fp_value, &sp_value); - if (!stop_exit && (stop_code == STOP_SRQ)) - { - immediate_quit++; - ninSrq (); - immediate_quit--; - } - else - { - /* Get out of loop */ - supply_register (IP_REGNUM, - (char *) &ip_value); - supply_register (FP_REGNUM, - (char *) &fp_value); - supply_register (SP_REGNUM, - (char *) &sp_value); - break; - } - } - } - - serial_set_tty_state (tty_args.serial, tty_args.state); - xfree (tty_args.state); - discard_cleanups (old_cleanups); - - if (stop_exit) - { - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = stop_code; - } - else - { - /* nindy has some special stop code need to be handled */ - if (stop_code == STOP_GDB_BPT) - stop_code = TRACE_STEP; - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = i960_fault_to_signal (stop_code); - } - return inferior_ptid; -} - -/* Read the remote registers into the block REGS. */ - -/* This is the block that ninRegsGet and ninRegsPut handles. */ -struct nindy_regs -{ - char local_regs[16 * 4]; - char global_regs[16 * 4]; - char pcw_acw[2 * 4]; - char ip[4]; - char tcw[4]; - char fp_as_double[4 * 8]; -}; - -static void -nindy_fetch_registers (int regno) -{ - struct nindy_regs nindy_regs; - int regnum; - - immediate_quit++; - ninRegsGet ((char *) &nindy_regs); - immediate_quit--; - - memcpy (®isters[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs, 16 * 4); - memcpy (®isters[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16 * 4); - memcpy (®isters[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2 * 4); - memcpy (®isters[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1 * 4); - memcpy (®isters[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1 * 4); - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], nindy_regs.fp_as_double, 4 * 8); - - registers_fetched (); -} - -static void -nindy_prepare_to_store (void) -{ - /* Fetch all regs if they aren't already here. */ - read_register_bytes (0, NULL, REGISTER_BYTES); -} - -static void -nindy_store_registers (int regno) -{ - struct nindy_regs nindy_regs; - int regnum; - - memcpy (nindy_regs.local_regs, ®isters[REGISTER_BYTE (R0_REGNUM)], 16 * 4); - memcpy (nindy_regs.global_regs, ®isters[REGISTER_BYTE (G0_REGNUM)], 16 * 4); - memcpy (nindy_regs.pcw_acw, ®isters[REGISTER_BYTE (PCW_REGNUM)], 2 * 4); - memcpy (nindy_regs.ip, ®isters[REGISTER_BYTE (IP_REGNUM)], 1 * 4); - memcpy (nindy_regs.tcw, ®isters[REGISTER_BYTE (TCW_REGNUM)], 1 * 4); - memcpy (nindy_regs.fp_as_double, ®isters[REGISTER_BYTE (FP0_REGNUM)], 8 * 4); - - immediate_quit++; - ninRegsPut ((char *) &nindy_regs); - immediate_quit--; -} - -/* Copy LEN bytes to or from inferior's memory starting at MEMADDR - to debugger memory starting at MYADDR. Copy to inferior if - SHOULD_WRITE is nonzero. Returns the length copied. TARGET is - unused. */ - -int -nindy_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int should_write, struct mem_attrib *attrib, - struct target_ops *target) -{ - int res; - - if (len <= 0) - return 0; - - if (should_write) - res = ninMemPut (memaddr, myaddr, len); - else - res = ninMemGet (memaddr, myaddr, len); - - return res; -} - -static void -nindy_create_inferior (char *execfile, char *args, char **env) -{ - int entry_pt; - int pid; - - if (args && *args) - error ("Can't pass arguments to remote NINDY process"); - - if (execfile == 0 || exec_bfd == 0) - error ("No executable file specified"); - - entry_pt = (int) bfd_get_start_address (exec_bfd); - - pid = 42; - - /* The "process" (board) is already stopped awaiting our commands, and - the program is already downloaded. We just set its PC and go. */ - - inferior_ptid = pid_to_ptid (pid); /* Needed for wait_for_inferior below */ - - clear_proceed_status (); - - /* Tell wait_for_inferior that we've started a new process. */ - init_wait_for_inferior (); - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - target_terminal_init (); - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - /* insert_step_breakpoint (); FIXME, do we need this? */ - /* Let 'er rip... */ - proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0); -} - -static void -reset_command (char *args, int from_tty) -{ - if (nindy_serial == NULL) - { - error ("No target system to reset -- use 'target nindy' command."); - } - if (query ("Really reset the target system?", 0, 0)) - { - serial_send_break (nindy_serial); - tty_flush (nindy_serial); - } -} - -void -nindy_kill (char *args, int from_tty) -{ - return; /* Ignore attempts to kill target system */ -} - -/* Clean up when a program exits. - - The program actually lives on in the remote processor's RAM, and may be - run again without a download. Don't leave it full of breakpoint - instructions. */ - -void -nindy_mourn_inferior (void) -{ - remove_breakpoints (); - unpush_target (&nindy_ops); - generic_mourn_inferior (); /* Do all the proper things now */ -} - -/* Pass the args the way catch_errors wants them. */ -static int -nindy_open_stub (char *arg) -{ - nindy_open (arg, 1); - return 1; -} - -static void -nindy_load (char *filename, int from_tty) -{ - asection *s; - /* Can't do unix style forking on a VMS system, so we'll use bfd to do - all the work for us - */ - - bfd *file = bfd_openr (filename, 0); - if (!file) - { - perror_with_name (filename); - return; - } - - if (!bfd_check_format (file, bfd_object)) - { - error ("can't prove it's an object file\n"); - return; - } - - for (s = file->sections; s; s = s->next) - { - if (s->flags & SEC_LOAD) - { - char *buffer = xmalloc (s->_raw_size); - bfd_get_section_contents (file, s, buffer, 0, s->_raw_size); - printf ("Loading section %s, size %x vma %x\n", - s->name, - s->_raw_size, - s->vma); - ninMemPut (s->vma, buffer, s->_raw_size); - xfree (buffer); - } - } - bfd_close (file); -} - -static int -load_stub (char *arg) -{ - target_load (arg, 1); - return 1; -} - -/* This routine is run as a hook, just before the main command loop is - entered. If gdb is configured for the i960, but has not had its - nindy target specified yet, this will loop prompting the user to do so. - - Unlike the loop provided by Intel, we actually let the user get out - of this with a RETURN. This is useful when e.g. simply examining - an i960 object file on the host system. */ - -void -nindy_before_main_loop (void) -{ - char ttyname[100]; - char *p, *p2; - - while (target_stack->target_ops != &nindy_ops) /* What is this crap??? */ - { /* remote tty not specified yet */ - if (instream == stdin) - { - printf_unfiltered ("\nAttach /dev/ttyNN -- specify NN, or \"quit\" to quit: "); - gdb_flush (gdb_stdout); - } - fgets (ttyname, sizeof (ttyname) - 1, stdin); - - /* Strip leading and trailing whitespace */ - for (p = ttyname; isspace (*p); p++) - { - ; - } - if (*p == '\0') - { - return; /* User just hit spaces or return, wants out */ - } - for (p2 = p; !isspace (*p2) && (*p2 != '\0'); p2++) - { - ; - } - *p2 = '\0'; - if (STREQ ("quit", p)) - { - exit (1); - } - - if (catch_errors (nindy_open_stub, p, "", RETURN_MASK_ALL)) - { - /* Now that we have a tty open for talking to the remote machine, - download the executable file if one was specified. */ - if (exec_bfd) - { - catch_errors (load_stub, bfd_get_filename (exec_bfd), "", - RETURN_MASK_ALL); - } - } - } -} - -/* Define the target subroutine names */ - -struct target_ops nindy_ops; - -static void -init_nindy_ops (void) -{ - nindy_ops.to_shortname = "nindy"; - "Remote serial target in i960 NINDY-specific protocol", - nindy_ops.to_longname = "Use a remote i960 system running NINDY connected by a serial line.\n\ -Specify the name of the device the serial line is connected to.\n\ -The speed (baud rate), whether to use the old NINDY protocol,\n\ -and whether to send a break on startup, are controlled by options\n\ -specified when you started GDB."; - nindy_ops.to_doc = ""; - nindy_ops.to_open = nindy_open; - nindy_ops.to_close = nindy_close; - nindy_ops.to_attach = 0; - nindy_ops.to_post_attach = NULL; - nindy_ops.to_require_attach = NULL; - nindy_ops.to_detach = nindy_detach; - nindy_ops.to_require_detach = NULL; - nindy_ops.to_resume = nindy_resume; - nindy_ops.to_wait = nindy_wait; - nindy_ops.to_post_wait = NULL; - nindy_ops.to_fetch_registers = nindy_fetch_registers; - nindy_ops.to_store_registers = nindy_store_registers; - nindy_ops.to_prepare_to_store = nindy_prepare_to_store; - nindy_ops.to_xfer_memory = nindy_xfer_inferior_memory; - nindy_ops.to_files_info = nindy_files_info; - nindy_ops.to_insert_breakpoint = memory_insert_breakpoint; - nindy_ops.to_remove_breakpoint = memory_remove_breakpoint; - nindy_ops.to_terminal_init = 0; - nindy_ops.to_terminal_inferior = 0; - nindy_ops.to_terminal_ours_for_output = 0; - nindy_ops.to_terminal_ours = 0; - nindy_ops.to_terminal_info = 0; /* Terminal crud */ - nindy_ops.to_kill = nindy_kill; - nindy_ops.to_load = nindy_load; - nindy_ops.to_lookup_symbol = 0; /* lookup_symbol */ - nindy_ops.to_create_inferior = nindy_create_inferior; - nindy_ops.to_post_startup_inferior = NULL; - nindy_ops.to_acknowledge_created_inferior = NULL; - nindy_ops.to_clone_and_follow_inferior = NULL; - nindy_ops.to_post_follow_inferior_by_clone = NULL; - nindy_ops.to_insert_fork_catchpoint = NULL; - nindy_ops.to_remove_fork_catchpoint = NULL; - nindy_ops.to_insert_vfork_catchpoint = NULL; - nindy_ops.to_remove_vfork_catchpoint = NULL; - nindy_ops.to_has_forked = NULL; - nindy_ops.to_has_vforked = NULL; - nindy_ops.to_can_follow_vfork_prior_to_exec = NULL; - nindy_ops.to_post_follow_vfork = NULL; - nindy_ops.to_insert_exec_catchpoint = NULL; - nindy_ops.to_remove_exec_catchpoint = NULL; - nindy_ops.to_has_execd = NULL; - nindy_ops.to_reported_exec_events_per_exec_call = NULL; - nindy_ops.to_has_exited = NULL; - nindy_ops.to_mourn_inferior = nindy_mourn_inferior; - nindy_ops.to_can_run = 0; /* can_run */ - nindy_ops.to_notice_signals = 0; /* notice_signals */ - nindy_ops.to_thread_alive = 0; /* to_thread_alive */ - nindy_ops.to_stop = 0; /* to_stop */ - nindy_ops.to_pid_to_exec_file = NULL; - nindy_ops.to_stratum = process_stratum; - nindy_ops.DONT_USE = 0; /* next */ - nindy_ops.to_has_all_memory = 1; - nindy_ops.to_has_memory = 1; - nindy_ops.to_has_stack = 1; - nindy_ops.to_has_registers = 1; - nindy_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */ - nindy_ops.to_sections = 0; - nindy_ops.to_sections_end = 0; /* Section pointers */ - nindy_ops.to_magic = OPS_MAGIC; /* Always the last thing */ -} - -void -_initialize_nindy (void) -{ - init_nindy_ops (); - add_target (&nindy_ops); - add_com ("reset", class_obscure, reset_command, - "Send a 'break' to the remote target system.\n\ -Only useful if the target has been equipped with a circuit\n\ -to perform a hard reset when a break is detected."); -} diff --git a/contrib/gdb/gdb/remote-nrom.c b/contrib/gdb/gdb/remote-nrom.c deleted file mode 100644 index 436c3d272a6..00000000000 --- a/contrib/gdb/gdb/remote-nrom.c +++ /dev/null @@ -1,351 +0,0 @@ -/* Remote debugging with the XLNT Designs, Inc (XDI) NetROM. - Copyright 1990, 1991, 1992, 1995, 1998, 1999, 2000 - Free Software Foundation, Inc. - Contributed by: - Roger Moyers - XLNT Designs, Inc. - 15050 Avenue of Science, Suite 106 - San Diego, CA 92128 - (619)487-9320 - roger@xlnt.com - Adapted from work done at Cygnus Support in remote-nindy.c, - later merged in by Stan Shebs at Cygnus. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcmd.h" -#include "serial.h" -#include "target.h" - -/* Default ports used to talk with the NetROM. */ - -#define DEFAULT_NETROM_LOAD_PORT 1236 -#define DEFAULT_NETROM_CONTROL_PORT 1237 - -static void nrom_close (int quitting); - -/* New commands. */ - -static void nrom_passthru (char *, int); - -/* We talk to the NetROM over these sockets. */ - -static struct serial *load_desc = NULL; -static struct serial *ctrl_desc = NULL; - -static int load_port = DEFAULT_NETROM_LOAD_PORT; -static int control_port = DEFAULT_NETROM_CONTROL_PORT; - -static char nrom_hostname[100]; - -/* Forward data declaration. */ - -extern struct target_ops nrom_ops; - -/* Scan input from the remote system, until STRING is found. Print chars that - don't match. */ - -static int -expect (char *string) -{ - char *p = string; - int c; - - immediate_quit++; - - while (1) - { - c = serial_readchar (ctrl_desc, 5); - - if (c == *p++) - { - if (*p == '\0') - { - immediate_quit--; - return 0; - } - } - else - { - fputc_unfiltered (c, gdb_stdout); - p = string; - if (c == *p) - p++; - } - } -} - -static void -nrom_kill (void) -{ - nrom_close (0); -} - -static struct serial * -open_socket (char *name, int port) -{ - char sockname[100]; - struct serial *desc; - - sprintf (sockname, "%s:%d", name, port); - desc = serial_open (sockname); - if (!desc) - perror_with_name (sockname); - - return desc; -} - -static void -load_cleanup (void) -{ - serial_close (load_desc); - load_desc = NULL; -} - -/* Download a file specified in ARGS to the netROM. */ - -static void -nrom_load (char *args, int fromtty) -{ - int fd, rd_amt, fsize; - bfd *pbfd; - asection *section; - char *downloadstring = "download 0\n"; - struct cleanup *old_chain; - - /* Tell the netrom to get ready to download. */ - if (serial_write (ctrl_desc, downloadstring, strlen (downloadstring))) - error ("nrom_load: control_send() of `%s' failed", downloadstring); - - expect ("Waiting for a connection...\n"); - - load_desc = open_socket (nrom_hostname, load_port); - - old_chain = make_cleanup (load_cleanup, 0); - - pbfd = bfd_openr (args, 0); - - if (pbfd) - { - make_cleanup (bfd_close, pbfd); - - if (!bfd_check_format (pbfd, bfd_object)) - error ("\"%s\": not in executable format: %s", - args, bfd_errmsg (bfd_get_error ())); - - for (section = pbfd->sections; section; section = section->next) - { - if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC) - { - bfd_vma section_address; - unsigned long section_size; - const char *section_name; - - section_name = bfd_get_section_name (pbfd, section); - section_address = bfd_get_section_vma (pbfd, section); - section_size = bfd_section_size (pbfd, section); - - if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) - { - file_ptr fptr; - - printf_filtered ("[Loading section %s at %x (%d bytes)]\n", - section_name, section_address, - section_size); - - fptr = 0; - - while (section_size > 0) - { - char buffer[1024]; - int count; - - count = min (section_size, 1024); - - bfd_get_section_contents (pbfd, section, buffer, fptr, - count); - - serial_write (load_desc, buffer, count); - section_address += count; - fptr += count; - section_size -= count; - } - } - else - /* BSS and such */ - { - printf_filtered ("[section %s: not loading]\n", - section_name); - } - } - } - } - else - error ("\"%s\": Could not open", args); - - do_cleanups (old_chain); -} - -/* Open a connection to the remote NetROM devices. */ - -static void -nrom_open (char *name, int from_tty) -{ - int errn; - - if (!name || strchr (name, '/') || strchr (name, ':')) - error ( - "To open a NetROM connection, you must specify the hostname\n\ -or IP address of the NetROM device you wish to use."); - - strcpy (nrom_hostname, name); - - target_preopen (from_tty); - - unpush_target (&nrom_ops); - - ctrl_desc = open_socket (nrom_hostname, control_port); - - push_target (&nrom_ops); - - if (from_tty) - printf_filtered ("Connected to NetROM device \"%s\"\n", nrom_hostname); -} - -/* Close out all files and local state before this target loses control. */ - -static void -nrom_close (int quitting) -{ - if (load_desc) - serial_close (load_desc); - if (ctrl_desc) - serial_close (ctrl_desc); -} - -/* Pass arguments directly to the NetROM. */ - -static void -nrom_passthru (char *args, int fromtty) -{ - char buf[1024]; - - sprintf (buf, "%s\n", args); - if (serial_write (ctrl_desc, buf, strlen (buf))) - error ("nrom_reset: control_send() of `%s'failed", args); -} - -static void -nrom_mourn (void) -{ - unpush_target (&nrom_ops); - generic_mourn_inferior (); -} - -/* Define the target vector. */ - -struct target_ops nrom_ops; - -static void -init_nrom_ops (void) -{ - nrom_ops.to_shortname = "nrom"; - nrom_ops.to_longname = "Remote XDI `NetROM' target"; - nrom_ops.to_doc = "Remote debug using a NetROM over Ethernet"; - nrom_ops.to_open = nrom_open; - nrom_ops.to_close = nrom_close; - nrom_ops.to_attach = NULL; - nrom_ops.to_post_attach = NULL; - nrom_ops.to_require_attach = NULL; - nrom_ops.to_detach = NULL; - nrom_ops.to_require_detach = NULL; - nrom_ops.to_resume = NULL; - nrom_ops.to_wait = NULL; - nrom_ops.to_post_wait = NULL; - nrom_ops.to_fetch_registers = NULL; - nrom_ops.to_store_registers = NULL; - nrom_ops.to_prepare_to_store = NULL; - nrom_ops.to_xfer_memory = NULL; - nrom_ops.to_files_info = NULL; - nrom_ops.to_insert_breakpoint = NULL; - nrom_ops.to_remove_breakpoint = NULL; - nrom_ops.to_terminal_init = NULL; - nrom_ops.to_terminal_inferior = NULL; - nrom_ops.to_terminal_ours_for_output = NULL; - nrom_ops.to_terminal_ours = NULL; - nrom_ops.to_terminal_info = NULL; - nrom_ops.to_kill = nrom_kill; - nrom_ops.to_load = nrom_load; - nrom_ops.to_lookup_symbol = NULL; - nrom_ops.to_create_inferior = NULL; - nrom_ops.to_post_startup_inferior = NULL; - nrom_ops.to_acknowledge_created_inferior = NULL; - nrom_ops.to_clone_and_follow_inferior = NULL; - nrom_ops.to_post_follow_inferior_by_clone = NULL; - nrom_ops.to_insert_fork_catchpoint = NULL; - nrom_ops.to_remove_fork_catchpoint = NULL; - nrom_ops.to_insert_vfork_catchpoint = NULL; - nrom_ops.to_remove_vfork_catchpoint = NULL; - nrom_ops.to_has_forked = NULL; - nrom_ops.to_has_vforked = NULL; - nrom_ops.to_can_follow_vfork_prior_to_exec = NULL; - nrom_ops.to_post_follow_vfork = NULL; - nrom_ops.to_insert_exec_catchpoint = NULL; - nrom_ops.to_remove_exec_catchpoint = NULL; - nrom_ops.to_has_execd = NULL; - nrom_ops.to_reported_exec_events_per_exec_call = NULL; - nrom_ops.to_has_exited = NULL; - nrom_ops.to_mourn_inferior = nrom_mourn; - nrom_ops.to_can_run = NULL; - nrom_ops.to_notice_signals = 0; - nrom_ops.to_thread_alive = 0; - nrom_ops.to_stop = 0; - nrom_ops.to_pid_to_exec_file = NULL; - nrom_ops.to_stratum = download_stratum; - nrom_ops.DONT_USE = NULL; - nrom_ops.to_has_all_memory = 1; - nrom_ops.to_has_memory = 1; - nrom_ops.to_has_stack = 1; - nrom_ops.to_has_registers = 1; - nrom_ops.to_has_execution = 0; - nrom_ops.to_sections = NULL; - nrom_ops.to_sections_end = NULL; - nrom_ops.to_magic = OPS_MAGIC; -} - -void -_initialize_remote_nrom (void) -{ - init_nrom_ops (); - add_target (&nrom_ops); - - add_show_from_set ( - add_set_cmd ("nrom_load_port", no_class, var_zinteger, (char *) &load_port, - "Set the port to use for NetROM downloads\n", &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("nrom_control_port", no_class, var_zinteger, (char *) &control_port, - "Set the port to use for NetROM debugger services\n", &setlist), - &showlist); - - add_cmd ("nrom", no_class, nrom_passthru, - "Pass arguments as command to NetROM", - &cmdlist); -} diff --git a/contrib/gdb/gdb/remote-os9k.c b/contrib/gdb/gdb/remote-os9k.c deleted file mode 100644 index 2cedfb00527..00000000000 --- a/contrib/gdb/gdb/remote-os9k.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* Remote debugging interface for boot monitors, for GDB. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, - 2000, 2001, 2002 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This file was derived from remote-eb.c, which did a similar job, but for - an AMD-29K running EBMON. That file was in turn derived from remote.c - as mentioned in the following comment (left in for comic relief): - - "This is like remote.c but is for a different situation-- - having a PC running os9000 hook up with a unix machine with - a serial line, and running ctty com2 on the PC. os9000 has a debug - monitor called ROMBUG running. Not to mention that the PC - has PC/NFS, so it can access the same executables that gdb can, - over the net in real time." - - In reality, this module talks to a debug monitor called 'ROMBUG', which - We communicate with ROMBUG via a direct serial line, the network version - of ROMBUG is not available yet. - */ - -/* FIXME This file needs to be rewritten if it's to work again, either - to self-contained or to use the new monitor interface. */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "gdb_string.h" -#include -#include "command.h" -#include "serial.h" -#include "monitor.h" -#include "remote-utils.h" -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdb-stabs.h" -#include "regcache.h" - -struct cmd_list_element *showlist; -extern struct target_ops rombug_ops; /* Forward declaration */ -extern struct monitor_ops rombug_cmds; /* Forward declaration */ -extern struct cmd_list_element *setlist; -extern struct cmd_list_element *unsetlist; -extern int attach_flag; - -static void rombug_close (); -static void rombug_fetch_register (); -static void rombug_fetch_registers (); -static void rombug_store_register (); -#if 0 -static int sr_get_debug (); /* flag set by "set remotedebug" */ -#endif -static int hashmark; /* flag set by "set hash" */ -static int rombug_is_open = 0; - -/* FIXME: Replace with sr_get_debug (). */ -#define LOG_FILE "monitor.log" -FILE *log_file; -static int monitor_log = 0; -static int tty_xon = 0; -static int tty_xoff = 0; - -static int timeout = 10; -static int is_trace_mode = 0; -/* Descriptor for I/O to remote machine. Initialize it to NULL */ -static struct serial *monitor_desc = NULL; - -static CORE_ADDR bufaddr = 0; -static int buflen = 0; -static char readbuf[16]; - -/* Send data to monitor. Works just like printf. */ -static void -printf_monitor (char *pattern,...) -{ - va_list args; - char buf[200]; - int i; - - va_start (args, pattern); - - vsprintf (buf, pattern, args); - va_end (args); - - if (serial_write (monitor_desc, buf, strlen (buf))) - fprintf (stderr, "serial_write failed: %s\n", safe_strerror (errno)); -} - -/* Read a character from the remote system, doing all the fancy timeout stuff */ -static int -readchar (int timeout) -{ - int c; - - c = serial_readchar (monitor_desc, timeout); - - if (sr_get_debug ()) - putchar (c & 0x7f); - - if (monitor_log && isascii (c)) - putc (c & 0x7f, log_file); - - if (c >= 0) - return c & 0x7f; - - if (c == SERIAL_TIMEOUT) - { - if (timeout == 0) - return c; /* Polls shouldn't generate timeout errors */ - - error ("Timeout reading from remote system."); - } - - perror_with_name ("remote-monitor"); -} - -/* Scan input from the remote system, until STRING is found. If DISCARD is - non-zero, then discard non-matching input, else print it out. - Let the user break out immediately. */ -static void -expect (char *string, int discard) -{ - char *p = string; - int c; - - if (sr_get_debug ()) - printf ("Expecting \"%s\"\n", string); - - immediate_quit++; - while (1) - { - c = readchar (timeout); - if (!isascii (c)) - continue; - if (c == *p++) - { - if (*p == '\0') - { - immediate_quit--; - if (sr_get_debug ()) - printf ("\nMatched\n"); - return; - } - } - else - { - if (!discard) - { - fwrite (string, 1, (p - 1) - string, stdout); - putchar ((char) c); - fflush (stdout); - } - p = string; - } - } -} - -/* Keep discarding input until we see the ROMBUG prompt. - - The convention for dealing with the prompt is that you - o give your command - o *then* wait for the prompt. - - Thus the last thing that a procedure does with the serial line - will be an expect_prompt(). Exception: rombug_resume does not - wait for the prompt, because the terminal is being handed over - to the inferior. However, the next thing which happens after that - is a rombug_wait which does wait for the prompt. - Note that this includes abnormal exit, e.g. error(). This is - necessary to prevent getting into states from which we can't - recover. */ -static void -expect_prompt (int discard) -{ - if (monitor_log) - /* This is a convenient place to do this. The idea is to do it often - enough that we never lose much data if we terminate abnormally. */ - fflush (log_file); - - if (is_trace_mode) - { - expect ("trace", discard); - } - else - { - expect (PROMPT, discard); - } -} - -/* Get a hex digit from the remote system & return its value. - If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ -static int -get_hex_digit (int ignore_space) -{ - int ch; - while (1) - { - ch = readchar (timeout); - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else if (ch == ' ' && ignore_space) - ; - else - { - expect_prompt (1); - error ("Invalid hex digit from remote system."); - } - } -} - -/* Get a byte from monitor and put it in *BYT. Accept any number - leading spaces. */ -static void -get_hex_byte (char *byt) -{ - int val; - - val = get_hex_digit (1) << 4; - val |= get_hex_digit (0); - *byt = val; -} - -/* Get N 32-bit words from remote, each preceded by a space, - and put them in registers starting at REGNO. */ -static void -get_hex_regs (int n, int regno) -{ - long val; - int i; - unsigned char b; - - for (i = 0; i < n; i++) - { - int j; - - val = 0; - for (j = 0; j < 4; j++) - { - get_hex_byte (&b); - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - val = (val << 8) + b; - else - val = val + (b << (j * 8)); - } - supply_register (regno++, (char *) &val); - } -} - -/* This is called not only when we first attach, but also when the - user types "run" after having attached. */ -static void -rombug_create_inferior (char *execfile, char *args, char **env) -{ - int entry_pt; - - if (args && *args) - error ("Can't pass arguments to remote ROMBUG process"); - - if (execfile == 0 || exec_bfd == 0) - error ("No executable file specified"); - - entry_pt = (int) bfd_get_start_address (exec_bfd); - - if (monitor_log) - fputs ("\nIn Create_inferior()", log_file); - - -/* The "process" (board) is already stopped awaiting our commands, and - the program is already downloaded. We just set its PC and go. */ - - init_wait_for_inferior (); - proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0); -} - -/* Open a connection to a remote debugger. - NAME is the filename used for communication. */ - -static char dev_name[100]; - -static void -rombug_open (char *args, int from_tty) -{ - if (args == NULL) - error ("Use `target RomBug DEVICE-NAME' to use a serial port, or \n\ -`target RomBug HOST-NAME:PORT-NUMBER' to use a network connection."); - - target_preopen (from_tty); - - if (rombug_is_open) - unpush_target (&rombug_ops); - - strcpy (dev_name, args); - monitor_desc = serial_open (dev_name); - if (monitor_desc == NULL) - perror_with_name (dev_name); - - /* if baud rate is set by 'set remotebaud' */ - if (serial_setbaudrate (monitor_desc, sr_get_baud_rate ())) - { - serial_close (monitor_desc); - perror_with_name ("RomBug"); - } - serial_raw (monitor_desc); - if (tty_xon || tty_xoff) - { - struct hardware_ttystate - { - struct termios t; - } - *tty_s; - - tty_s = (struct hardware_ttystate *) serial_get_tty_state (monitor_desc); - if (tty_xon) - tty_s->t.c_iflag |= IXON; - if (tty_xoff) - tty_s->t.c_iflag |= IXOFF; - serial_set_tty_state (monitor_desc, (serial_ttystate) tty_s); - } - - rombug_is_open = 1; - - log_file = fopen (LOG_FILE, "w"); - if (log_file == NULL) - perror_with_name (LOG_FILE); - - push_monitor (&rombug_cmds); - printf_monitor ("\r"); /* CR wakes up monitor */ - expect_prompt (1); - push_target (&rombug_ops); - attach_flag = 1; - - if (from_tty) - printf ("Remote %s connected to %s\n", target_shortname, - dev_name); - - rombug_fetch_registers (); - - printf_monitor ("ov e \r"); - expect_prompt (1); - bufaddr = 0; - buflen = 0; -} - -/* - * Close out all files and local state before this target loses control. - */ - -static void -rombug_close (int quitting) -{ - if (rombug_is_open) - { - serial_close (monitor_desc); - monitor_desc = NULL; - rombug_is_open = 0; - } - - if (log_file) - { - if (ferror (log_file)) - fprintf (stderr, "Error writing log file.\n"); - if (fclose (log_file) != 0) - fprintf (stderr, "Error closing log file.\n"); - log_file = 0; - } -} - -int -rombug_link (char *mod_name, CORE_ADDR *text_reloc) -{ - int i, j; - unsigned long val; - unsigned char b; - - printf_monitor ("l %s \r", mod_name); - expect_prompt (1); - printf_monitor (".r \r"); - expect (REG_DELIM, 1); - for (i = 0; i <= 7; i++) - { - val = 0; - for (j = 0; j < 4; j++) - { - get_hex_byte (&b); - val = (val << 8) + b; - } - } - expect_prompt (1); - *text_reloc = val; - return 1; -} - -/* Terminate the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. */ -static void -rombug_detach (int from_tty) -{ - if (attach_flag) - { - printf_monitor (GO_CMD); - attach_flag = 0; - } - pop_target (); /* calls rombug_close to do the real work */ - if (from_tty) - printf ("Ending remote %s debugging\n", target_shortname); -} - -/* - * Tell the remote machine to resume. - */ -static void -rombug_resume (ptid_t ptid, int step, enum target_signal sig) -{ - if (monitor_log) - fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig); - - if (step) - { - is_trace_mode = 1; - printf_monitor (STEP_CMD); - /* wait for the echo. ** - expect (STEP_CMD, 1); - */ - } - else - { - printf_monitor (GO_CMD); - /* swallow the echo. ** - expect (GO_CMD, 1); - */ - } - bufaddr = 0; - buflen = 0; -} - -/* - * Wait until the remote machine stops, then return, - * storing status in status just as `wait' would. - */ - -static ptid * -rombug_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int old_timeout = timeout; - struct section_offsets *offs; - CORE_ADDR addr, pc; - struct obj_section *obj_sec; - - if (monitor_log) - fputs ("\nIn wait ()", log_file); - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - timeout = -1; /* Don't time out -- user program is running. */ - expect ("eax:", 0); /* output any message before register display */ - expect_prompt (1); /* Wait for prompt, outputting extraneous text */ - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - timeout = old_timeout; - rombug_fetch_registers (); - bufaddr = 0; - buflen = 0; - pc = read_register (PC_REGNUM); - addr = read_register (DATABASE_REG); - obj_sec = find_pc_section (pc); - if (obj_sec != NULL) - { - if (obj_sec->objfile != symfile_objfile) - new_symfile_objfile (obj_sec->objfile, 1, 0); - offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS); - memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS); - offs->offsets[SECT_OFF_DATA (symfile_objfile)] = addr; - offs->offsets[SECT_OFF_BSS (symfile_objfile)] = addr; - - objfile_relocate (symfile_objfile, offs); - } - - return inferior_ptid; -} - -/* Return the name of register number regno in the form input and output by - monitor. Currently, register_names just happens to contain exactly what - monitor wants. Lets take advantage of that just as long as possible! */ - -static char * -get_reg_name (int regno) -{ - static char buf[50]; - char *p; - char *b; - - b = buf; - - if (regno < 0) - return (""); -/* - for (p = REGISTER_NAME (regno); *p; p++) - *b++ = toupper(*p); - *b = '\000'; - */ - p = (char *) REGISTER_NAME (regno); - return p; -/* - return buf; - */ -} - -/* read the remote registers into the block regs. */ - -static void -rombug_fetch_registers (void) -{ - int regno, j, i; - long val; - unsigned char b; - - printf_monitor (GET_REG); - expect ("eax:", 1); - expect ("\n", 1); - get_hex_regs (1, 0); - get_hex_regs (1, 3); - get_hex_regs (1, 1); - get_hex_regs (1, 2); - get_hex_regs (1, 6); - get_hex_regs (1, 7); - get_hex_regs (1, 5); - get_hex_regs (1, 4); - for (regno = 8; regno <= 15; regno++) - { - expect (REG_DELIM, 1); - if (regno >= 8 && regno <= 13) - { - val = 0; - for (j = 0; j < 2; j++) - { - get_hex_byte (&b); - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - val = (val << 8) + b; - else - val = val + (b << (j * 8)); - } - - if (regno == 8) - i = 10; - if (regno >= 9 && regno <= 12) - i = regno + 3; - if (regno == 13) - i = 11; - supply_register (i, (char *) &val); - } - else if (regno == 14) - { - get_hex_regs (1, PC_REGNUM); - } - else if (regno == 15) - { - get_hex_regs (1, 9); - } - else - { - val = 0; - supply_register (regno, (char *) &val); - } - } - is_trace_mode = 0; - expect_prompt (1); -} - -/* Fetch register REGNO, or all registers if REGNO is -1. - Returns errno value. */ -static void -rombug_fetch_register (int regno) -{ - int val, j; - unsigned char b; - - if (monitor_log) - { - fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno)); - fflush (log_file); - } - - if (regno < 0) - { - rombug_fetch_registers (); - } - else - { - char *name = get_reg_name (regno); - printf_monitor (GET_REG); - if (regno >= 10 && regno <= 15) - { - expect ("\n", 1); - expect ("\n", 1); - expect (name, 1); - expect (REG_DELIM, 1); - val = 0; - for (j = 0; j < 2; j++) - { - get_hex_byte (&b); - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - val = (val << 8) + b; - else - val = val + (b << (j * 8)); - } - supply_register (regno, (char *) &val); - } - else if (regno == 8 || regno == 9) - { - expect ("\n", 1); - expect ("\n", 1); - expect ("\n", 1); - expect (name, 1); - expect (REG_DELIM, 1); - get_hex_regs (1, regno); - } - else - { - expect (name, 1); - expect (REG_DELIM, 1); - expect ("\n", 1); - get_hex_regs (1, 0); - get_hex_regs (1, 3); - get_hex_regs (1, 1); - get_hex_regs (1, 2); - get_hex_regs (1, 6); - get_hex_regs (1, 7); - get_hex_regs (1, 5); - get_hex_regs (1, 4); - } - expect_prompt (1); - } - return; -} - -/* Store the remote registers from the contents of the block REGS. */ - -static void -rombug_store_registers (void) -{ - int regno; - - for (regno = 0; regno <= PC_REGNUM; regno++) - rombug_store_register (regno); - - registers_changed (); -} - -/* Store register REGNO, or all if REGNO == 0. - return errno value. */ -static void -rombug_store_register (int regno) -{ - char *name; - - if (monitor_log) - fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno); - - if (regno == -1) - rombug_store_registers (); - else - { - if (sr_get_debug ()) - printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno)); - - name = get_reg_name (regno); - if (name == 0) - return; - printf_monitor (SET_REG, name, read_register (regno)); - - is_trace_mode = 0; - expect_prompt (1); - } -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -rombug_prepare_to_store (void) -{ - /* Do nothing, since we can store individual regs */ -} - -static void -rombug_files_info (void) -{ - printf ("\tAttached to %s at %d baud.\n", - dev_name, sr_get_baud_rate ()); -} - -/* Copy LEN bytes of data from debugger memory at MYADDR - to inferior's memory at MEMADDR. Returns length moved. */ -static int -rombug_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) -{ - int i; - char buf[10]; - - if (monitor_log) - fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len); - - printf_monitor (MEM_SET_CMD, memaddr); - for (i = 0; i < len; i++) - { - expect (CMD_DELIM, 1); - printf_monitor ("%x \r", myaddr[i]); - if (sr_get_debug ()) - printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]); - } - expect (CMD_DELIM, 1); - if (CMD_END) - printf_monitor (CMD_END); - is_trace_mode = 0; - expect_prompt (1); - - bufaddr = 0; - buflen = 0; - return len; -} - -/* Read LEN bytes from inferior memory at MEMADDR. Put the result - at debugger address MYADDR. Returns length moved. */ -static int -rombug_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - int i, j; - - /* Number of bytes read so far. */ - int count; - - /* Starting address of this pass. */ - unsigned long startaddr; - - /* Number of bytes to read in this pass. */ - int len_this_pass; - - if (monitor_log) - fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len); - - /* Note that this code works correctly if startaddr is just less - than UINT_MAX (well, really CORE_ADDR_MAX if there was such a - thing). That is, something like - rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4) - works--it never adds len To memaddr and gets 0. */ - /* However, something like - rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4) - doesn't need to work. Detect it and give up if there's an attempt - to do that. */ - if (((memaddr - 1) + len) < memaddr) - { - errno = EIO; - return 0; - } - if (bufaddr <= memaddr && (memaddr + len) <= (bufaddr + buflen)) - { - memcpy (myaddr, &readbuf[memaddr - bufaddr], len); - return len; - } - - startaddr = memaddr; - count = 0; - while (count < len) - { - len_this_pass = 16; - if ((startaddr % 16) != 0) - len_this_pass -= startaddr % 16; - if (len_this_pass > (len - count)) - len_this_pass = (len - count); - if (sr_get_debug ()) - printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr); - - printf_monitor (MEM_DIS_CMD, startaddr, 8); - expect ("- ", 1); - for (i = 0; i < 16; i++) - { - get_hex_byte (&readbuf[i]); - } - bufaddr = startaddr; - buflen = 16; - memcpy (&myaddr[count], readbuf, len_this_pass); - count += len_this_pass; - startaddr += len_this_pass; - expect (CMD_DELIM, 1); - } - if (CMD_END) - printf_monitor (CMD_END); - is_trace_mode = 0; - expect_prompt (1); - - return len; -} - -/* Transfer LEN bytes between GDB address MYADDR and target address - MEMADDR. If WRITE is non-zero, transfer them to the target, - otherwise transfer them from the target. TARGET is unused. - - Returns the number of bytes transferred. */ - -static int -rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, - int write, struct mem_attrib *attrib, - struct target_ops *target) -{ - if (write) - return rombug_write_inferior_memory (memaddr, myaddr, len); - else - return rombug_read_inferior_memory (memaddr, myaddr, len); -} - -static void -rombug_kill (char *args, int from_tty) -{ - return; /* ignore attempts to kill target system */ -} - -/* Clean up when a program exits. - The program actually lives on in the remote processor's RAM, and may be - run again without a download. Don't leave it full of breakpoint - instructions. */ - -static void -rombug_mourn_inferior (void) -{ - remove_breakpoints (); - generic_mourn_inferior (); /* Do all the proper things now */ -} - -#define MAX_MONITOR_BREAKPOINTS 16 - -static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = -{0}; - -static int -rombug_insert_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - CORE_ADDR bp_addr = addr; - int bp_size = 0; - - if (monitor_log) - fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr); - BREAKPOINT_FROM_PC (&bp_addr, &bp_size); - - for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++) - if (breakaddr[i] == 0) - { - breakaddr[i] = addr; - if (sr_get_debug ()) - printf ("Breakpoint at %x\n", addr); - rombug_read_inferior_memory (bp_addr, shadow, bp_size); - printf_monitor (SET_BREAK_CMD, addr); - is_trace_mode = 0; - expect_prompt (1); - return 0; - } - - fprintf (stderr, "Too many breakpoints (> 16) for monitor\n"); - return 1; -} - -/* - * _remove_breakpoint -- Tell the monitor to remove a breakpoint - */ -static int -rombug_remove_breakpoint (CORE_ADDR addr, char *shadow) -{ - int i; - - if (monitor_log) - fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr); - - for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++) - if (breakaddr[i] == addr) - { - breakaddr[i] = 0; - printf_monitor (CLR_BREAK_CMD, addr); - is_trace_mode = 0; - expect_prompt (1); - return 0; - } - - fprintf (stderr, "Can't find breakpoint associated with 0x%x\n", addr); - return 1; -} - -/* Load a file. This is usually an srecord, which is ascii. No - protocol, just sent line by line. */ - -#define DOWNLOAD_LINE_SIZE 100 -static void -rombug_load (char *arg) -{ -/* this part comment out for os9* */ -#if 0 - FILE *download; - char buf[DOWNLOAD_LINE_SIZE]; - int i, bytes_read; - - if (sr_get_debug ()) - printf ("Loading %s to monitor\n", arg); - - download = fopen (arg, "r"); - if (download == NULL) - { - error (sprintf (buf, "%s Does not exist", arg)); - return; - } - - printf_monitor (LOAD_CMD); -/* expect ("Waiting for S-records from host... ", 1); */ - - while (!feof (download)) - { - bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download); - if (hashmark) - { - putchar ('.'); - fflush (stdout); - } - - if (serial_write (monitor_desc, buf, bytes_read)) - { - fprintf (stderr, "serial_write failed: (while downloading) %s\n", safe_strerror (errno)); - break; - } - i = 0; - while (i++ <= 200000) - { - }; /* Ugly HACK, probably needs flow control */ - if (bytes_read < DOWNLOAD_LINE_SIZE) - { - if (!feof (download)) - error ("Only read %d bytes\n", bytes_read); - break; - } - } - - if (hashmark) - { - putchar ('\n'); - } - if (!feof (download)) - error ("Never got EOF while downloading"); - fclose (download); -#endif /* 0 */ -} - -/* Put a command string, in args, out to MONITOR. - Output from MONITOR is placed on the users terminal until the prompt - is seen. */ - -static void -rombug_command (char *args, int fromtty) -{ - if (monitor_desc == NULL) - error ("monitor target not open."); - - if (monitor_log) - fprintf (log_file, "\nIn command (args=%s)\n", args); - - if (!args) - error ("Missing command."); - - printf_monitor ("%s\r", args); - expect_prompt (0); -} - -#if 0 -/* Connect the user directly to MONITOR. This command acts just like the - 'cu' or 'tip' command. Use ~. or ~^D to break out. */ - -static struct ttystate ttystate; - -static void -cleanup_tty (void) -{ - printf ("\r\n[Exiting connect mode]\r\n"); - /*serial_restore(0, &ttystate); */ -} - -static void -connect_command (char *args, int fromtty) -{ - fd_set readfds; - int numfds; - int c; - char cur_esc = 0; - - dont_repeat (); - - if (monitor_desc == NULL) - error ("monitor target not open."); - - if (args) - fprintf ("This command takes no args. They have been ignored.\n"); - - printf ("[Entering connect mode. Use ~. or ~^D to escape]\n"); - - serial_raw (0, &ttystate); - - make_cleanup (cleanup_tty, 0); - - FD_ZERO (&readfds); - - while (1) - { - do - { - FD_SET (0, &readfds); - FD_SET (deprecated_serial_fd (monitor_desc), &readfds); - numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0); - } - while (numfds == 0); - - if (numfds < 0) - perror_with_name ("select"); - - if (FD_ISSET (0, &readfds)) - { /* tty input, send to monitor */ - c = getchar (); - if (c < 0) - perror_with_name ("connect"); - - printf_monitor ("%c", c); - switch (cur_esc) - { - case 0: - if (c == '\r') - cur_esc = c; - break; - case '\r': - if (c == '~') - cur_esc = c; - else - cur_esc = 0; - break; - case '~': - if (c == '.' || c == '\004') - return; - else - cur_esc = 0; - } - } - - if (FD_ISSET (deprecated_serial_fd (monitor_desc), &readfds)) - { - while (1) - { - c = readchar (0); - if (c < 0) - break; - putchar (c); - } - fflush (stdout); - } - } -} -#endif - -/* - * Define the monitor command strings. Since these are passed directly - * through to a printf style function, we need can include formatting - * strings. We also need a CR or LF on the end. - */ -#warning FIXME: monitor interface pattern strings, stale struct decl -struct monitor_ops rombug_cmds = -{ - "g \r", /* execute or usually GO command */ - "g \r", /* continue command */ - "t \r", /* single step */ - "b %x\r", /* set a breakpoint */ - "k %x\r", /* clear a breakpoint */ - "c %x\r", /* set memory to a value */ - "d %x %d\r", /* display memory */ - "$%08X", /* prompt memory commands use */ - ".%s %x\r", /* set a register */ - ":", /* delimiter between registers */ - ". \r", /* read a register */ - "mf \r", /* download command */ - "RomBug: ", /* monitor command prompt */ - ": ", /* end-of-command delimitor */ - ".\r" /* optional command terminator */ -}; - -struct target_ops rombug_ops; - -static void -init_rombug_ops (void) -{ - rombug_ops.to_shortname = "rombug"; - rombug_ops.to_longname = "Microware's ROMBUG debug monitor"; - rombug_ops.to_doc = "Use a remote computer running the ROMBUG debug monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya).", - rombug_ops.to_open = rombug_open; - rombug_ops.to_close = rombug_close; - rombug_ops.to_attach = 0; - rombug_ops.to_post_attach = NULL; - rombug_ops.to_require_attach = NULL; - rombug_ops.to_detach = rombug_detach; - rombug_ops.to_require_detach = NULL; - rombug_ops.to_resume = rombug_resume; - rombug_ops.to_wait = rombug_wait; - rombug_ops.to_post_wait = NULL; - rombug_ops.to_fetch_registers = rombug_fetch_register; - rombug_ops.to_store_registers = rombug_store_register; - rombug_ops.to_prepare_to_store = rombug_prepare_to_store; - rombug_ops.to_xfer_memory = rombug_xfer_inferior_memory; - rombug_ops.to_files_info = rombug_files_info; - rombug_ops.to_insert_breakpoint = rombug_insert_breakpoint; - rombug_ops.to_remove_breakpoint = rombug_remove_breakpoint; /* Breakpoints */ - rombug_ops.to_terminal_init = 0; - rombug_ops.to_terminal_inferior = 0; - rombug_ops.to_terminal_ours_for_output = 0; - rombug_ops.to_terminal_ours = 0; - rombug_ops.to_terminal_info = 0; /* Terminal handling */ - rombug_ops.to_kill = rombug_kill; - rombug_ops.to_load = rombug_load; /* load */ - rombug_ops.to_lookup_symbol = rombug_link; /* lookup_symbol */ - rombug_ops.to_create_inferior = rombug_create_inferior; - rombug_ops.to_post_startup_inferior = NULL; - rombug_ops.to_acknowledge_created_inferior = NULL; - rombug_ops.to_clone_and_follow_inferior = NULL; - rombug_ops.to_post_follow_inferior_by_clone = NULL; - rombug_ops.to_insert_fork_catchpoint = NULL; - rombug_ops.to_remove_fork_catchpoint = NULL; - rombug_ops.to_insert_vfork_catchpoint = NULL; - rombug_ops.to_remove_vfork_catchpoint = NULL; - rombug_ops.to_has_forked = NULL; - rombug_ops.to_has_vforked = NULL; - rombug_ops.to_can_follow_vfork_prior_to_exec = NULL; - rombug_ops.to_post_follow_vfork = NULL; - rombug_ops.to_insert_exec_catchpoint = NULL; - rombug_ops.to_remove_exec_catchpoint = NULL; - rombug_ops.to_has_execd = NULL; - rombug_ops.to_reported_exec_events_per_exec_call = NULL; - rombug_ops.to_has_exited = NULL; - rombug_ops.to_mourn_inferior = rombug_mourn_inferior; - rombug_ops.to_can_run = 0; /* can_run */ - rombug_ops.to_notice_signals = 0; /* notice_signals */ - rombug_ops.to_thread_alive = 0; - rombug_ops.to_stop = 0; /* to_stop */ - rombug_ops.to_pid_to_exec_file = NULL; - rombug_ops.to_stratum = process_stratum; - rombug_ops.DONT_USE = 0; /* next */ - rombug_ops.to_has_all_memory = 1; - rombug_ops.to_has_memory = 1; - rombug_ops.to_has_stack = 1; - rombug_ops.to_has_registers = 1; - rombug_ops.to_has_execution = 1; /* has execution */ - rombug_ops.to_sections = 0; - rombug_ops.to_sections_end = 0; /* Section pointers */ - rombug_ops.to_magic = OPS_MAGIC; /* Always the last thing */ -} - -void -_initialize_remote_os9k (void) -{ - init_rombug_ops (); - add_target (&rombug_ops); - - add_show_from_set ( - add_set_cmd ("hash", no_class, var_boolean, (char *) &hashmark, - "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("timeout", no_class, var_zinteger, - (char *) &timeout, - "Set timeout in seconds for remote MIPS serial I/O.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("remotelog", no_class, var_zinteger, - (char *) &monitor_log, - "Set monitor activity log on(=1) or off(=0).", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("remotexon", no_class, var_zinteger, - (char *) &tty_xon, - "Set remote tty line XON control", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("remotexoff", no_class, var_zinteger, - (char *) &tty_xoff, - "Set remote tty line XOFF control", - &setlist), - &showlist); - - add_com ("rombug ", class_obscure, rombug_command, - "Send a command to the debug monitor."); -#if 0 - add_com ("connect", class_obscure, connect_command, - "Connect the terminal directly up to a serial based command monitor.\nUse ~. or ~^D to break out."); -#endif -} diff --git a/contrib/gdb/gdb/remote-pa.c b/contrib/gdb/gdb/remote-pa.c deleted file mode 100644 index 1121e15effa..00000000000 --- a/contrib/gdb/gdb/remote-pa.c +++ /dev/null @@ -1,1540 +0,0 @@ -/* Remote target communications for serial-line targets in custom GDB protocol - Copyright 1988, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Remote communication protocol. - - A debug packet whose contents are - is encapsulated for transmission in the form: - - $ # CSUM1 CSUM2 - - must be ASCII alphanumeric and cannot include characters - '$' or '#'. If starts with two characters followed by - ':', then the existing stubs interpret this as a sequence number. - - CSUM1 and CSUM2 are ascii hex representation of an 8-bit - checksum of , the most significant nibble is sent first. - the hex digits 0-9,a-f are used. - - Receiver responds with: - - + - if CSUM is correct and ready for next packet - - - if CSUM is incorrect - - is as follows: - All values are encoded in ascii hex digits. - - Request Packet - - read registers g - reply XX....X Each byte of register data - is described by two hex digits. - Registers are in the internal order - for GDB, and the bytes in a register - are in the same order the machine uses. - or ENN for an error. - - write regs GXX..XX Each byte of register data - is described by two hex digits. - reply OK for success - ENN for an error - - write reg Pn...=r... Write register n... with value r..., - which contains two hex digits for each - byte in the register (target byte - order). - reply OK for success - ENN for an error - (not supported by all stubs). - - read mem mAA..AA,LLLL AA..AA is address, LLLL is length. - reply XX..XX XX..XX is mem contents - Can be fewer bytes than requested - if able to read only part of the data. - or ENN NN is errno - - write mem MAA..AA,LLLL:XX..XX - AA..AA is address, - LLLL is number of bytes, - XX..XX is data - reply OK for success - ENN for an error (this includes the case - where only part of the data was - written). - - cont cAA..AA AA..AA is address to resume - If AA..AA is omitted, - resume at same address. - - step sAA..AA AA..AA is address to resume - If AA..AA is omitted, - resume at same address. - - last signal ? Reply the current reason for stopping. - This is the same reply as is generated - for step or cont : SAA where AA is the - signal number. - - There is no immediate reply to step or cont. - The reply comes when the machine stops. - It is SAA AA is the "signal number" - - or... TAAn...:r...;n:r...;n...:r...; - AA = signal number - n... = register number - r... = register contents - or... WAA The process exited, and AA is - the exit status. This is only - applicable for certains sorts of - targets. - kill request k - - toggle debug d toggle debug flag (see 386 & 68k stubs) - reset r reset -- see sparc stub. - reserved On other requests, the stub should - ignore the request and send an empty - response ($#). This way - we can extend the protocol and GDB - can tell whether the stub it is - talking to uses the old or the new. - search tAA:PP,MM Search backwards starting at address - AA for a match with pattern PP and - mask MM. PP and MM are 4 bytes. - Not supported by all stubs. - - general query qXXXX Request info about XXXX. - general set QXXXX=yyyy Set value of XXXX to yyyy. - query sect offs qOffsets Get section offsets. Reply is - Text=xxx;Data=yyy;Bss=zzz - console output Otext Send text to stdout. Only comes from - remote target. - - Responses can be run-length encoded to save space. A '*' means that - the next character is an ASCII encoding giving a repeat count which - stands for that many repititions of the character preceding the '*'. - The encoding is n+29, yielding a printable character where n >=3 - (which is where rle starts to win). Don't use an n > 126. - - So - "0* " means the same as "0000". */ - -#include "defs.h" -#include "gdb_string.h" -#include -#include "frame.h" -#include "inferior.h" -#include "bfd.h" -#include "symfile.h" -#include "target.h" -#include "wait.h" -#include "terminal.h" -#include "gdbcmd.h" -#include "objfiles.h" -#include "gdb-stabs.h" -#include "remote-utils.h" -#include "dcache.h" - -#ifdef USG -#include -#endif - -#include -#include "serial.h" - -/* Prototypes for local functions */ - -static int -remote_write_bytes PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); - -static int -remote_read_bytes PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); - -static void -remote_files_info PARAMS ((struct target_ops *ignore)); - -static int -remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len, - int should_write, struct target_ops *target)); - -static void -remote_prepare_to_store PARAMS ((void)); - -static void -remote_fetch_registers PARAMS ((int regno)); - -static void -remote_resume PARAMS ((int pid, int step, enum target_signal siggnal)); - -static int -remote_start_remote PARAMS ((char *dummy)); - -static void -remote_open PARAMS ((char *name, int from_tty)); - -static void -remote_close PARAMS ((int quitting)); - -static void -remote_store_registers PARAMS ((int regno)); - -static void -getpkt PARAMS ((char *buf, int forever)); - -static void -putpkt PARAMS ((char *buf)); - -static void -remote_send PARAMS ((char *buf)); - -static int -readchar PARAMS ((int timeout)); - -static int -remote_wait PARAMS ((int pid, struct target_waitstatus *status)); - -static int -tohex PARAMS ((int nib)); - -static int -fromhex PARAMS ((int a)); - -static void -remote_detach PARAMS ((char *args, int from_tty)); - -static void -remote_interrupt PARAMS ((int signo)); - -static void -remote_interrupt_twice PARAMS ((int signo)); - -static void -interrupt_query PARAMS ((void)); - -static void -hppro_load PARAMS ((char *name, int from_tty)); - -extern struct target_ops remote_ops; /* Forward decl */ - -/* This was 5 seconds, which is a long time to sit and wait. - Unless this is going though some terminal server or multiplexer or - other form of hairy serial connection, I would think 2 seconds would - be plenty. */ -static int remote_timeout = 2; - -/* Descriptor for I/O to remote machine. Initialize it to NULL so that - remote_open knows that we don't have a file open when the program - starts. */ -extern serial_t remote_desc; - -/* Having this larger than 400 causes us to be incompatible with m68k-stub.c - and i386-stub.c. Normally, no one would notice because it only matters - for writing large chunks of memory (e.g. in downloads). Also, this needs - to be more than 400 if required to hold the registers (see below, where - we round it up based on REGISTER_BYTES). */ -#define PBUFSIZ 400 - -/* Maximum number of bytes to read/write at once. The value here - is chosen to fill up a packet (the headers account for the 32). */ -#define MAXBUFBYTES ((PBUFSIZ-32)/2) - -/* Round up PBUFSIZ to hold all the registers, at least. */ -/* The blank line after the #if seems to be required to work around a - bug in HP's PA compiler. */ -#if REGISTER_BYTES > MAXBUFBYTES - -#undef PBUFSIZ -#define PBUFSIZ (REGISTER_BYTES * 2 + 32) -#endif - -/* Should we try the 'P' request? If this is set to one when the stub - doesn't support 'P', the only consequence is some unnecessary traffic. */ -static int stub_supports_P = 1; - -/* sets the download protocol, choices are srec, generic, boot */ -char *loadtype; -static char *loadtype_str; -static void set_loadtype_command -PARAMS ((char *, int, struct cmd_list_element *)); - -static void -hppro_load (file, from_tty) - char *file; - int from_tty; -{ - puts ("Loading... HA!"); -} - - -/* Clean up connection to a remote debugger. */ - -/* ARGSUSED */ -static void -remote_close (quitting) - int quitting; -{ - if (remote_desc) - SERIAL_CLOSE (remote_desc); - remote_desc = NULL; -} - -/* Query the remote side for the text, data and bss offsets. */ - -static void -get_offsets () -{ - unsigned char buf[PBUFSIZ]; - int nvals; - CORE_ADDR text_addr, data_addr, bss_addr; - struct section_offsets *offs; - - putpkt ("qOffsets"); - - getpkt (buf, 0); - - if (buf[0] == '\000') - return; /* Return silently. Stub doesn't support this - command. */ - if (buf[0] == 'E') - { - warning ("Remote failure reply: %s", buf); - return; - } - - nvals = sscanf (buf, "Text=%lx;Data=%lx;Bss=%lx", &text_addr, &data_addr, - &bss_addr); - if (nvals != 3) - error ("Malformed response to offset query, %s", buf); - - if (symfile_objfile == NULL) - return; - - offs = (struct section_offsets *) alloca (sizeof (struct section_offsets) - + symfile_objfile->num_sections - * sizeof (offs->offsets)); - memcpy (offs, symfile_objfile->section_offsets, - sizeof (struct section_offsets) - + symfile_objfile->num_sections - * sizeof (offs->offsets)); - - /* FIXME: This code assumes gdb-stabs.h is being used; it's broken - for xcoff, dwarf, sdb-coff, etc. But there is no simple - canonical representation for this stuff. (Just what does "text" - as seen by the stub mean, anyway? I think it means all sections - with SEC_CODE set, but we currently have no way to deal with that). */ - - ANOFFSET (offs, SECT_OFF_TEXT) = text_addr; - - /* This is a temporary kludge to force data and bss to use the same offsets - because that's what nlmconv does now. The real solution requires changes - to the stub and remote.c that I don't have time to do right now. */ - - ANOFFSET (offs, SECT_OFF_DATA) = data_addr; - ANOFFSET (offs, SECT_OFF_BSS) = data_addr; - - objfile_relocate (symfile_objfile, offs); -} - -#define INBUFSIZE 10 - -void -boot_board() -{ - char c; - char buf[INBUFSIZE]; - char *ptr; - - /* See if we can connect to the boot ROM command line */ - ptr = buf; - while (1) { - SERIAL_WRITE (remote_desc, "\r\n", 2); - c = readchar (2); - if ((sr_get_debug() > 2) && (isascii(c))) - putchar (c); - if (c == SERIAL_TIMEOUT) { - if (sr_get_debug()) - puts_filtered ("Timed out.\n"); - break; - } - if (c == '&') { - if (sr_get_debug() > 2) - puts ("Got ACK from stub"); - break; - } - if (c == '>') { - if (sr_get_debug() > 2) - puts ("Got prompt from ROM monitor"); - break; - } - } - -} - -/* Stub for catch_errors. */ -static int -remote_start_remote (dummy) - char *dummy; -{ - int timeout; - - immediate_quit = 1; /* Allow user to interrupt it */ - - /* Ack any packet which the remote side has already sent. */ - - if (sr_get_debug()) - puts ("Trying a '+' to ACK the target."); - - SERIAL_WRITE (remote_desc, "+", 1); - -#if 0 - boot_board(); - - get_offsets (); /* Get text, data & bss offsets */ -#endif - - putpkt ("?"); /* initiate a query from remote machine */ - immediate_quit = 0; - - start_remote (); /* Initialize gdb process mechanisms */ - - return 1; -} - -/* Open a connection to a remote debugger. - NAME is the filename used for communication. */ - -static DCACHE *remote_dcache; - -static void -remote_open (name, from_tty) - char *name; - int from_tty; -{ - if (name == 0) - error ( -"To open a remote debug connection, you need to specify what serial\n\ -device is attached to the remote system (e.g. /dev/ttya)."); - - target_preopen (from_tty); - - unpush_target (&remote_ops); - - remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes); - - remote_desc = SERIAL_OPEN (name); - if (!remote_desc) - perror_with_name (name); - - if (baud_rate != -1) - { - if (SERIAL_SETBAUDRATE (remote_desc, baud_rate)) - { - SERIAL_CLOSE (remote_desc); - perror_with_name (name); - } - } - - SERIAL_RAW (remote_desc); - - /* If there is something sitting in the buffer we might take it as a - response to a command, which would be bad. */ - SERIAL_FLUSH_INPUT (remote_desc); - - if (from_tty) - { - puts_filtered ("Remote debugging using "); - puts_filtered (name); - puts_filtered ("\n"); - } - push_target (&remote_ops); /* Switch to using remote target now */ - - /* Start out by trying the 'P' request to set registers. We set this each - time that we open a new target so that if the user switches from one - stub to another, we can (if the target is closed and reopened) cope. */ - stub_supports_P = 1; - - /* Without this, some commands which require an active target (such as kill) - won't work. This variable serves (at least) double duty as both the pid - of the target process (if it has such), and as a flag indicating that a - target is active. These functions should be split out into seperate - variables, especially since GDB will someday have a notion of debugging - several processes. */ - - inferior_pid = 42000; - - /* Start the remote connection; if error (0), discard this target. - In particular, if the user quits, be sure to discard it - (we'd be in an inconsistent state otherwise). */ - if (!catch_errors (remote_start_remote, (char *)0, - "Couldn't establish connection to remote target\n", RETURN_MASK_ALL)) - pop_target(); -} - -/* remote_detach() - takes a program previously attached to and detaches it. - We better not have left any breakpoints - in the program or it'll die when it hits one. - Close the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. */ - -static void -remote_detach (args, from_tty) - char *args; - int from_tty; -{ - if (args) - error ("Argument given to \"detach\" when remotely debugging."); - - pop_target (); - if (from_tty) - puts_filtered ("Ending remote debugging.\n"); -} - -/* Convert hex digit A to a number. */ - -static int -fromhex (a) - int a; -{ - if (a >= '0' && a <= '9') - return a - '0'; - else if (a >= 'a' && a <= 'f') - return a - 'a' + 10; - else - error ("Reply contains invalid hex digit"); -} - -/* Convert number NIB to a hex digit. */ - -static int -tohex (nib) - int nib; -{ - if (nib < 10) - return '0'+nib; - else - return 'a'+nib-10; -} - -/* Tell the remote machine to resume. */ - -static void -remote_resume (pid, step, siggnal) - int pid, step; - enum target_signal siggnal; -{ - char buf[PBUFSIZ]; - - if (siggnal) - { - target_terminal_ours_for_output (); - printf_filtered - ("Can't send signals to a remote system. %s not sent.\n", - target_signal_to_name (siggnal)); target_terminal_inferior (); - } - - dcache_flush (remote_dcache); - - strcpy (buf, step ? "s": "c"); - - putpkt (buf); -} - -/* Send ^C to target to halt it. Target will respond, and send us a - packet. */ - -static void -remote_interrupt (signo) - int signo; -{ - /* If this doesn't work, try more severe steps. */ - signal (signo, remote_interrupt_twice); - - if (remote_debug) - printf_unfiltered ("remote_interrupt called\n"); - - SERIAL_WRITE (remote_desc, "\003", 1); /* Send a ^C */ -} - -static void (*ofunc)(); - -/* The user typed ^C twice. */ -static void -remote_interrupt_twice (signo) - int signo; -{ - signal (signo, ofunc); - - interrupt_query (); - - signal (signo, remote_interrupt); -} - -/* Ask the user what to do when an interrupt is received. */ - -static void -interrupt_query () -{ - target_terminal_ours (); - - if (query ("Interrupted while waiting for the program.\n\ -Give up (and stop debugging it)? ")) - { - target_mourn_inferior (); - return_to_top_level (RETURN_QUIT); - } - - target_terminal_inferior (); -} - -/* Wait until the remote machine stops, then return, - storing status in STATUS just as `wait' would. - Returns "pid" (though it's not clear what, if anything, that - means in the case of this target). */ - -static int -remote_wait (pid, status) - int pid; - struct target_waitstatus *status; -{ - unsigned char buf[PBUFSIZ]; - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - while (1) - { - unsigned char *p; - - ofunc = (void (*)()) signal (SIGINT, remote_interrupt); - getpkt ((char *) buf, 1); - signal (SIGINT, ofunc); - - switch (buf[0]) - { - case 'E': /* Error of some sort */ - warning ("Remote failure reply: %s", buf); - continue; - case 'T': /* Status with PC, SP, FP, ... */ - { - int i; - long regno; - char regs[MAX_REGISTER_RAW_SIZE]; - - /* Expedited reply, containing Signal, {regno, reg} repeat */ - /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where - ss = signal number - n... = register number - r... = register contents - */ - - p = &buf[3]; /* after Txx */ - - while (*p) - { - unsigned char *p1; - - regno = strtol (p, (char **) &p1, 16); /* Read the register number */ - - if (p1 == p) - warning ("Remote sent badly formed register number: %s\nPacket: '%s'\n", - p1, buf); - - p = p1; - - if (*p++ != ':') - warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n", - p, buf); - - if (regno >= NUM_REGS) - warning ("Remote sent bad register number %d: %s\nPacket: '%s'\n", - regno, p, buf); - - for (i = 0; i < REGISTER_RAW_SIZE (regno); i++) - { - if (p[0] == 0 || p[1] == 0) - warning ("Remote reply is too short: %s", buf); - regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); - p += 2; - } - - if (*p++ != ';') - warning ("Remote register badly formatted: %s", buf); - - supply_register (regno, regs); - } - } - /* fall through */ - case 'S': /* Old style status, just signal only */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = (enum target_signal) - (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))); - - return inferior_pid; - case 'W': /* Target exited */ - { - /* The remote process exited. */ - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]); - return inferior_pid; - } - case 'O': /* Console output */ - fputs_filtered (buf + 1, gdb_stdout); - continue; - default: - warning ("Invalid remote reply: %s", buf); - continue; - } - } - return inferior_pid; -} - -/* Number of bytes of registers this stub implements. */ -static int register_bytes_found; - -/* Read the remote registers into the block REGS. */ -/* Currently we just read all the registers, so we don't use regno. */ -/* ARGSUSED */ -static void -remote_fetch_registers (regno) - int regno; -{ - char buf[PBUFSIZ]; - int i; - char *p; - char regs[REGISTER_BYTES]; - - sprintf (buf, "g"); - remote_send (buf); - - /* Unimplemented registers read as all bits zero. */ - memset (regs, 0, REGISTER_BYTES); - - /* We can get out of synch in various cases. If the first character - in the buffer is not a hex character, assume that has happened - and try to fetch another packet to read. */ - while ((buf[0] < '0' || buf[0] > '9') - && (buf[0] < 'a' || buf[0] > 'f')) - { - if (remote_debug) - printf_unfiltered ("Bad register packet; fetching a new packet\n"); - getpkt (buf, 0); - } - - /* Reply describes registers byte by byte, each byte encoded as two - hex characters. Suck them all up, then supply them to the - register cacheing/storage mechanism. */ - - p = buf; - for (i = 0; i < REGISTER_BYTES; i++) - { - if (p[0] == 0) - break; - if (p[1] == 0) - { - warning ("Remote reply is of odd length: %s", buf); - /* Don't change register_bytes_found in this case, and don't - print a second warning. */ - goto supply_them; - } - regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); - p += 2; - } - - if (i != register_bytes_found) - { - register_bytes_found = i; -#ifdef REGISTER_BYTES_OK - if (!REGISTER_BYTES_OK (i)) - warning ("Remote reply is too short: %s", buf); -#endif - } - - supply_them: - for (i = 0; i < NUM_REGS; i++) - supply_register (i, ®s[REGISTER_BYTE(i)]); -} - -/* Prepare to store registers. Since we may send them all (using a - 'G' request), we have to read out the ones we don't want to change - first. */ - -static void -remote_prepare_to_store () -{ - /* Make sure the entire registers array is valid. */ - read_register_bytes (0, (char *)NULL, REGISTER_BYTES); -} - -/* Store register REGNO, or all registers if REGNO == -1, from the contents - of REGISTERS. FIXME: ignores errors. */ - -static void -remote_store_registers (regno) - int regno; -{ - char buf[PBUFSIZ]; - int i; - char *p; - - if (regno >= 0 && stub_supports_P) - { - /* Try storing a single register. */ - char *regp; - - sprintf (buf, "P%x=", regno); - p = buf + strlen (buf); - regp = ®isters[REGISTER_BYTE (regno)]; - for (i = 0; i < REGISTER_RAW_SIZE (regno); ++i) - { - *p++ = tohex ((regp[i] >> 4) & 0xf); - *p++ = tohex (regp[i] & 0xf); - } - *p = '\0'; - remote_send (buf); - if (buf[0] != '\0') - { - /* The stub understands the 'P' request. We are done. */ - return; - } - - /* The stub does not support the 'P' request. Use 'G' instead, - and don't try using 'P' in the future (it will just waste our - time). */ - stub_supports_P = 0; - } - - buf[0] = 'G'; - - /* Command describes registers byte by byte, - each byte encoded as two hex characters. */ - - p = buf + 1; - /* remote_prepare_to_store insures that register_bytes_found gets set. */ - for (i = 0; i < register_bytes_found; i++) - { - *p++ = tohex ((registers[i] >> 4) & 0xf); - *p++ = tohex (registers[i] & 0xf); - } - *p = '\0'; - - remote_send (buf); -} - -#if 0 - -/* Use of the data cache is disabled because it loses for looking at - and changing hardware I/O ports and the like. Accepting `volatile' - would perhaps be one way to fix it. Another idea would be to use the - executable file for the text segment (for all SEC_CODE sections? - For all SEC_READONLY sections?). This has problems if you want to - actually see what the memory contains (e.g. self-modifying code, - clobbered memory, user downloaded the wrong thing). */ - -/* Read a word from remote address ADDR and return it. - This goes through the data cache. */ - -static int -remote_fetch_word (addr) - CORE_ADDR addr; -{ - return dcache_fetch (remote_dcache, addr); -} - -/* Write a word WORD into remote address ADDR. - This goes through the data cache. */ - -static void -remote_store_word (addr, word) - CORE_ADDR addr; - int word; -{ - dcache_poke (remote_dcache, addr, word); -} -#endif /* 0 */ - -/* Write memory data directly to the remote machine. - This does not inform the data cache; the data cache uses this. - MEMADDR is the address in the remote memory space. - MYADDR is the address of the buffer in our space. - LEN is the number of bytes. - - Returns number of bytes transferred, or 0 for error. */ - -static int -remote_write_bytes (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - char buf[PBUFSIZ]; - int i; - char *p; - - /* FIXME-32x64: Need a version of print_address_numeric which puts the - result in a buffer like sprintf. */ - sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, len); - - /* We send target system values byte by byte, in increasing byte addresses, - each byte encoded as two hex characters. */ - - p = buf + strlen (buf); - for (i = 0; i < len; i++) - { - *p++ = tohex ((myaddr[i] >> 4) & 0xf); - *p++ = tohex (myaddr[i] & 0xf); - } - *p = '\0'; - - putpkt (buf); - getpkt (buf, 0); - - if (buf[0] == 'E') - { - /* There is no correspondance between what the remote protocol uses - for errors and errno codes. We would like a cleaner way of - representing errors (big enough to include errno codes, bfd_error - codes, and others). But for now just return EIO. */ - errno = EIO; - return 0; - } - return len; -} - -/* Read memory data directly from the remote machine. - This does not use the data cache; the data cache uses this. - MEMADDR is the address in the remote memory space. - MYADDR is the address of the buffer in our space. - LEN is the number of bytes. - - Returns number of bytes transferred, or 0 for error. */ - -static int -remote_read_bytes (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - char buf[PBUFSIZ]; - int i; - char *p; - - if (len > PBUFSIZ / 2 - 1) - abort (); - - /* FIXME-32x64: Need a version of print_address_numeric which puts the - result in a buffer like sprintf. */ - sprintf (buf, "m%lx,%x", (unsigned long) memaddr, len); - putpkt (buf); - getpkt (buf, 0); - - if (buf[0] == 'E') - { - /* There is no correspondance between what the remote protocol uses - for errors and errno codes. We would like a cleaner way of - representing errors (big enough to include errno codes, bfd_error - codes, and others). But for now just return EIO. */ - errno = EIO; - return 0; - } - - /* Reply describes memory byte by byte, - each byte encoded as two hex characters. */ - - p = buf; - for (i = 0; i < len; i++) - { - if (p[0] == 0 || p[1] == 0) - /* Reply is short. This means that we were able to read only part - of what we wanted to. */ - break; - myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]); - p += 2; - } - return i; -} - -/* Read or write LEN bytes from inferior memory at MEMADDR, transferring - to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is - nonzero. Returns length of data written or read; 0 for error. */ - -/* ARGSUSED */ -static int -remote_xfer_memory(memaddr, myaddr, len, should_write, target) - CORE_ADDR memaddr; - char *myaddr; - int len; - int should_write; - struct target_ops *target; /* ignored */ -{ - int xfersize; - int bytes_xferred; - int total_xferred = 0; - - while (len > 0) - { - if (len > MAXBUFBYTES) - xfersize = MAXBUFBYTES; - else - xfersize = len; - - if (should_write) - bytes_xferred = remote_write_bytes (memaddr, myaddr, xfersize); - else - bytes_xferred = remote_read_bytes (memaddr, myaddr, xfersize); - - /* If we get an error, we are done xferring. */ - if (bytes_xferred == 0) - break; - - memaddr += bytes_xferred; - myaddr += bytes_xferred; - len -= bytes_xferred; - total_xferred += bytes_xferred; - } - return total_xferred; -} - -#if 0 -/* Enable after 4.12. */ - -void -remote_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; -{ - if (increment == -4 && len == 4) - { - long mask_long, data_long; - long data_found_long; - CORE_ADDR addr_we_found; - char buf[PBUFSIZ]; - long returned_long[2]; - char *p; - - mask_long = extract_unsigned_integer (mask, len); - data_long = extract_unsigned_integer (data, len); - sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long); - putpkt (buf); - getpkt (buf, 0); - if (buf[0] == '\0') - { - /* The stub doesn't support the 't' request. We might want to - remember this fact, but on the other hand the stub could be - switched on us. Maybe we should remember it only until - the next "target remote". */ - generic_search (len, data, mask, startaddr, increment, lorange, - hirange, addr_found, data_found); - return; - } - - if (buf[0] == 'E') - /* There is no correspondance between what the remote protocol uses - for errors and errno codes. We would like a cleaner way of - representing errors (big enough to include errno codes, bfd_error - codes, and others). But for now just use EIO. */ - memory_error (EIO, startaddr); - p = buf; - addr_we_found = 0; - while (*p != '\0' && *p != ',') - addr_we_found = (addr_we_found << 4) + fromhex (*p++); - if (*p == '\0') - error ("Protocol error: short return for search"); - - data_found_long = 0; - while (*p != '\0' && *p != ',') - data_found_long = (data_found_long << 4) + fromhex (*p++); - /* Ignore anything after this comma, for future extensions. */ - - if (addr_we_found < lorange || addr_we_found >= hirange) - { - *addr_found = 0; - return; - } - - *addr_found = addr_we_found; - *data_found = store_unsigned_integer (data_we_found, len); - return; - } - generic_search (len, data, mask, startaddr, increment, lorange, - hirange, addr_found, data_found); -} -#endif /* 0 */ - -static void -remote_files_info (ignore) - struct target_ops *ignore; -{ - puts_filtered ("Debugging a target over a serial line.\n"); -} - -/* Stuff for dealing with the packets which are part of this protocol. - See comment at top of file for details. */ - -/* Read a single character from the remote end, masking it down to 7 bits. */ - -static int -readchar (timeout) - int timeout; -{ - int ch; - - ch = SERIAL_READCHAR (remote_desc, timeout); - - switch (ch) - { - case SERIAL_EOF: - error ("Remote connection closed"); - case SERIAL_ERROR: - perror_with_name ("Remote communication error"); - case SERIAL_TIMEOUT: - return ch; - default: - return ch & 0x7f; - } -} - -/* Send the command in BUF to the remote machine, - and read the reply into BUF. - Report an error if we get an error reply. */ - -static void -remote_send (buf) - char *buf; -{ - - putpkt (buf); - getpkt (buf, 0); - - if (buf[0] == 'E') - error ("Remote failure reply: %s", buf); -} - -/* Send a packet to the remote machine, with error checking. - The data of the packet is in BUF. */ -static void -putpkt (buf) - char *buf; -{ - int i; - unsigned char csum = 0; - char buf2[PBUFSIZ]; - int cnt = strlen (buf); - int ch; - char *p; - - /* Copy the packet into buffer BUF2, encapsulating it - and giving it a checksum. */ - - if (cnt > sizeof(buf2) - 5) /* Prosanity check */ - abort(); - - p = buf2; - *p++ = '$'; - - for (i = 0; i < cnt; i++) - { - csum += buf[i]; - *p++ = buf[i]; - } - *p++ = '#'; - *p++ = tohex ((csum >> 4) & 0xf); - *p++ = tohex (csum & 0xf); - - /* Send it over and over until we get a positive ack. */ - - while (1) - { - int started_error_output = 0; - - if (remote_debug) - { - *p = '\0'; - printf_unfiltered ("Sending packet: %s...", buf2); - gdb_flush(gdb_stdout); - } - if (SERIAL_WRITE (remote_desc, buf2, p - buf2)) - perror_with_name ("putpkt: write failed"); - - /* read until either a timeout occurs (-2) or '+' is read */ - while (1) - { - ch = readchar (remote_timeout); - - if (remote_debug) - { - switch (ch) - { - case '+': - case SERIAL_TIMEOUT: - case '$': - if (started_error_output) - { - putchar_unfiltered ('\n'); - started_error_output = 0; - } - } - } - - switch (ch) - { - case '+': - if (remote_debug) - printf_unfiltered("Got Ack\n"); - return; - case SERIAL_TIMEOUT: - break; /* Retransmit buffer */ - case '$': - { - unsigned char junkbuf[PBUFSIZ]; - - /* It's probably an old response, and we're out of sync. Just - gobble up the packet and ignore it. */ - getpkt (junkbuf, 0); - continue; /* Now, go look for + */ - } - default: - if (remote_debug) - { - if (!started_error_output) - { - started_error_output = 1; - printf_unfiltered ("putpkt: Junk: "); - } - putchar_unfiltered (ch & 0177); - } - continue; - } - break; /* Here to retransmit */ - } - -#if 0 - /* This is wrong. If doing a long backtrace, the user should be - able to get out next time we call QUIT, without anything as violent - as interrupt_query. If we want to provide a way out of here - without getting to the next QUIT, it should be based on hitting - ^C twice as in remote_wait. */ - if (quit_flag) - { - quit_flag = 0; - interrupt_query (); - } -#endif - } -} - -/* Come here after finding the start of the frame. Collect the rest into BUF, - verifying the checksum, length, and handling run-length compression. - Returns 0 on any error, 1 on success. */ - -static int -read_frame (buf) - char *buf; -{ - unsigned char csum; - char *bp; - int c; - - csum = 0; - bp = buf; - - while (1) - { - c = readchar (remote_timeout); - - switch (c) - { - case SERIAL_TIMEOUT: - if (remote_debug) - puts_filtered ("Timeout in mid-packet, retrying\n"); - return 0; - case '$': - if (remote_debug) - puts_filtered ("Saw new packet start in middle of old one\n"); - return 0; /* Start a new packet, count retries */ - case '#': - { - unsigned char pktcsum; - - *bp = '\000'; - - pktcsum = fromhex (readchar (remote_timeout)) << 4; - pktcsum |= fromhex (readchar (remote_timeout)); - - if (csum == pktcsum) - return 1; - - printf_filtered ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=", - pktcsum, csum); - puts_filtered (buf); - puts_filtered ("\n"); - - return 0; - } - case '*': /* Run length encoding */ - csum += c; - c = readchar (remote_timeout); - csum += c; - c = c - ' ' + 3; /* Compute repeat count */ - - if (bp + c - 1 < buf + PBUFSIZ - 1) - { - memset (bp, *(bp - 1), c); - bp += c; - continue; - } - - *bp = '\0'; - printf_filtered ("Repeat count %d too large for buffer: ", c); - puts_filtered (buf); - puts_filtered ("\n"); - return 0; - - default: - if (bp < buf + PBUFSIZ - 1) - { - *bp++ = c; - csum += c; - continue; - } - - *bp = '\0'; - puts_filtered ("Remote packet too long: "); - puts_filtered (buf); - puts_filtered ("\n"); - - return 0; - } - } -} - -/* Read a packet from the remote machine, with error checking, - and store it in BUF. BUF is expected to be of size PBUFSIZ. - If FOREVER, wait forever rather than timing out; this is used - while the target is executing user code. */ - -static void -getpkt (buf, forever) - char *buf; - int forever; -{ - char *bp; - int c; - int tries; - int timeout; - int val; - - if (forever) - timeout = -1; - else - timeout = remote_timeout; - -#define MAX_TRIES 10 - - for (tries = 1; tries <= MAX_TRIES; tries++) - { - /* This can loop forever if the remote side sends us characters - continuously, but if it pauses, we'll get a zero from readchar - because of timeout. Then we'll count that as a retry. */ - - /* Note that we will only wait forever prior to the start of a packet. - After that, we expect characters to arrive at a brisk pace. They - should show up within remote_timeout intervals. */ - - do - { - c = readchar (timeout); - - if (c == SERIAL_TIMEOUT) - { - if (remote_debug) - puts_filtered ("Timed out.\n"); - goto retry; - } - } - while (c != '$'); - - /* We've found the start of a packet, now collect the data. */ - - val = read_frame (buf); - - if (val == 1) - { - if (remote_debug) - fprintf_unfiltered (gdb_stderr, "Packet received: %s\n", buf); - SERIAL_WRITE (remote_desc, "+", 1); - return; - } - - /* Try the whole thing again. */ -retry: - SERIAL_WRITE (remote_desc, "-", 1); - } - - /* We have tried hard enough, and just can't receive the packet. Give up. */ - - printf_unfiltered ("Ignoring packet error, continuing...\n"); - SERIAL_WRITE (remote_desc, "+", 1); -} - -static void -remote_kill () -{ - putpkt ("k"); - /* Don't wait for it to die. I'm not really sure it matters whether - we do or not. For the existing stubs, kill is a noop. */ - target_mourn_inferior (); -} - -static void -remote_mourn () -{ - unpush_target (&remote_ops); - generic_mourn_inferior (); -} - -#ifdef REMOTE_BREAKPOINT - -/* On some machines, e.g. 68k, we may use a different breakpoint instruction - than other targets. */ -static unsigned char break_insn[] = REMOTE_BREAKPOINT; - -#else /* No REMOTE_BREAKPOINT. */ - -/* Same old breakpoint instruction. This code does nothing different - than mem-break.c. */ -static unsigned char break_insn[] = BREAKPOINT; - -#endif /* No REMOTE_BREAKPOINT. */ - -/* Insert a breakpoint on targets that don't have any better breakpoint - support. We read the contents of the target location and stash it, - then overwrite it with a breakpoint instruction. ADDR is the target - location in the target machine. CONTENTS_CACHE is a pointer to - memory allocated for saving the target contents. It is guaranteed - by the caller to be long enough to save sizeof BREAKPOINT bytes (this - is accomplished via BREAKPOINT_MAX). */ - -static int -remote_insert_breakpoint (addr, contents_cache) - CORE_ADDR addr; - char *contents_cache; -{ - int val; - - val = target_read_memory (addr, contents_cache, sizeof break_insn); - - if (val == 0) - val = target_write_memory (addr, (char *)break_insn, sizeof break_insn); - - return val; -} - -static int -remote_remove_breakpoint (addr, contents_cache) - CORE_ADDR addr; - char *contents_cache; -{ - return target_write_memory (addr, contents_cache, sizeof break_insn); -} - -/* Define the target subroutine names */ - -struct target_ops remote_hppro_ops = { - "hppro", /* to_shortname */ - "Remote serial target for HP-PRO targets", /* to_longname */ - "Use a remote computer via a serial line, using a gdb-specific protocol.\n\ -This is for targets that supports the HP-PRO standard.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya) or telnet port.", /* to_doc */ - remote_open, /* to_open */ - remote_close, /* to_close */ - NULL, /* to_attach */ - remote_detach, /* to_detach */ - remote_resume, /* to_resume */ - remote_wait, /* to_wait */ - remote_fetch_registers, /* to_fetch_registers */ - remote_store_registers, /* to_store_registers */ - remote_prepare_to_store, /* to_prepare_to_store */ - remote_xfer_memory, /* to_xfer_memory */ - remote_files_info, /* to_files_info */ - - remote_insert_breakpoint, /* to_insert_breakpoint */ - remote_remove_breakpoint, /* to_remove_breakpoint */ - - NULL, /* to_terminal_init */ - NULL, /* to_terminal_inferior */ - NULL, /* to_terminal_ours_for_output */ - NULL, /* to_terminal_ours */ - NULL, /* to_terminal_info */ - remote_kill, /* to_kill */ - hppro_load, /* to_load */ - NULL, /* to_lookup_symbol */ - NULL, /* to_create_inferior */ - remote_mourn, /* to_mourn_inferior */ - 0, /* to_can_run */ - 0, /* to_notice_signals */ - 0, /* to_thread_alive */ - 0, /* to_stop */ - process_stratum, /* to_stratum */ - NULL, /* to_next */ - 1, /* to_has_all_memory */ - 1, /* to_has_memory */ - 1, /* to_has_stack */ - 1, /* to_has_registers */ - 1, /* to_has_execution */ - NULL, /* sections */ - NULL, /* sections_end */ - OPS_MAGIC /* to_magic */ -}; - -void -_initialize_remote_hppro () -{ - struct cmd_list_element *c; - add_target (&remote_hppro_ops); - - /* this sets the type of download protocol */ - c = add_set_cmd ("loadtype", no_class, var_string, (char *)&loadtype_str, - "Set the type of the remote load protocol.\n", &setlist); - c->function.sfunc = set_loadtype_command; - add_show_from_set (c, &showlist); - loadtype_str = savestring ("generic", 8); - - /* this adds a command to boot the board */ - add_com ("boot", class_support, boot_board, - "Boot the damn target board.\n"); -} - -static void -set_loadtype_command (ignore, from_tty, c) - char *ignore; - int from_tty; - struct cmd_list_element *c; -{ - loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var)); -} - diff --git a/contrib/gdb/gdb/remote-sds.c b/contrib/gdb/gdb/remote-sds.c deleted file mode 100644 index 507ac5be208..00000000000 --- a/contrib/gdb/gdb/remote-sds.c +++ /dev/null @@ -1,1145 +0,0 @@ -/* Remote target communications for serial-line targets using SDS' protocol. - - Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This interface was written by studying the behavior of the SDS - monitor on an ADS 821/860 board, and by consulting the - documentation of the monitor that is available on Motorola's web - site. -sts 8/13/97 */ - -#include "defs.h" -#include "gdb_string.h" -#include -#include "frame.h" -#include "inferior.h" -#include "bfd.h" -#include "symfile.h" -#include "target.h" -#include "gdbcmd.h" -#include "objfiles.h" -#include "gdb-stabs.h" -#include "gdbthread.h" -#include "gdbcore.h" -#include "regcache.h" - -#ifdef USG -#include -#endif - -#include -#include "serial.h" - -extern void _initialize_remote_sds (void); - -/* Declarations of local functions. */ - -static int sds_write_bytes (CORE_ADDR, char *, int); - -static int sds_read_bytes (CORE_ADDR, char *, int); - -static void sds_files_info (struct target_ops *ignore); - -static int sds_xfer_memory (CORE_ADDR, char *, int, int, - struct mem_attrib *, struct target_ops *); - -static void sds_prepare_to_store (void); - -static void sds_fetch_registers (int); - -static void sds_resume (ptid_t, int, enum target_signal); - -static int sds_start_remote (PTR); - -static void sds_open (char *, int); - -static void sds_close (int); - -static void sds_store_registers (int); - -static void sds_mourn (void); - -static void sds_create_inferior (char *, char *, char **); - -static void sds_load (char *, int); - -static int getmessage (unsigned char *, int); - -static int putmessage (unsigned char *, int); - -static int sds_send (unsigned char *, int); - -static int readchar (int); - -static ptid_t sds_wait (ptid_t, struct target_waitstatus *); - -static void sds_kill (void); - -static int tohex (int); - -static int fromhex (int); - -static void sds_detach (char *, int); - -static void sds_interrupt (int); - -static void sds_interrupt_twice (int); - -static void interrupt_query (void); - -static int read_frame (char *); - -static int sds_insert_breakpoint (CORE_ADDR, char *); - -static int sds_remove_breakpoint (CORE_ADDR, char *); - -static void init_sds_ops (void); - -static void sds_command (char *args, int from_tty); - -/* Define the target operations vector. */ - -static struct target_ops sds_ops; - -/* This was 5 seconds, which is a long time to sit and wait. - Unless this is going though some terminal server or multiplexer or - other form of hairy serial connection, I would think 2 seconds would - be plenty. */ - -static int sds_timeout = 2; - -/* Descriptor for I/O to remote machine. Initialize it to NULL so - that sds_open knows that we don't have a file open when the program - starts. */ - -static struct serial *sds_desc = NULL; - -/* This limit comes from the monitor. */ - -#define PBUFSIZ 250 - -/* Maximum number of bytes to read/write at once. The value here - is chosen to fill up a packet (the headers account for the 32). */ -#define MAXBUFBYTES ((PBUFSIZ-32)/2) - -static int next_msg_id; - -static int just_started; - -static int message_pending; - - -/* Clean up connection to a remote debugger. */ - -/* ARGSUSED */ -static void -sds_close (int quitting) -{ - if (sds_desc) - serial_close (sds_desc); - sds_desc = NULL; -} - -/* Stub for catch_errors. */ - -static int -sds_start_remote (PTR dummy) -{ - int c; - unsigned char buf[200]; - - immediate_quit++; /* Allow user to interrupt it */ - - /* Ack any packet which the remote side has already sent. */ - serial_write (sds_desc, "{#*\r\n", 5); - serial_write (sds_desc, "{#}\r\n", 5); - - while ((c = readchar (1)) >= 0) - printf_unfiltered ("%c", c); - printf_unfiltered ("\n"); - - next_msg_id = 251; - - buf[0] = 26; - sds_send (buf, 1); - - buf[0] = 0; - sds_send (buf, 1); - - immediate_quit--; - - start_remote (); /* Initialize gdb process mechanisms */ - return 1; -} - -/* Open a connection to a remote debugger. - NAME is the filename used for communication. */ - -static void -sds_open (char *name, int from_tty) -{ - if (name == 0) - error ("To open a remote debug connection, you need to specify what serial\n\ -device is attached to the remote system (e.g. /dev/ttya)."); - - target_preopen (from_tty); - - unpush_target (&sds_ops); - - sds_desc = serial_open (name); - if (!sds_desc) - perror_with_name (name); - - if (baud_rate != -1) - { - if (serial_setbaudrate (sds_desc, baud_rate)) - { - serial_close (sds_desc); - perror_with_name (name); - } - } - - - serial_raw (sds_desc); - - /* If there is something sitting in the buffer we might take it as a - response to a command, which would be bad. */ - serial_flush_input (sds_desc); - - if (from_tty) - { - puts_filtered ("Remote debugging using "); - puts_filtered (name); - puts_filtered ("\n"); - } - push_target (&sds_ops); /* Switch to using remote target now */ - - just_started = 1; - - /* Start the remote connection; if error (0), discard this target. - In particular, if the user quits, be sure to discard it (we'd be - in an inconsistent state otherwise). */ - if (!catch_errors (sds_start_remote, NULL, - "Couldn't establish connection to remote target\n", - RETURN_MASK_ALL)) - pop_target (); -} - -/* This takes a program previously attached to and detaches it. After - this is done, GDB can be used to debug some other program. We - better not have left any breakpoints in the target program or it'll - die when it hits one. */ - -static void -sds_detach (char *args, int from_tty) -{ - char buf[PBUFSIZ]; - - if (args) - error ("Argument given to \"detach\" when remotely debugging."); - -#if 0 - /* Tell the remote target to detach. */ - strcpy (buf, "D"); - sds_send (buf, 1); -#endif - - pop_target (); - if (from_tty) - puts_filtered ("Ending remote debugging.\n"); -} - -/* Convert hex digit A to a number. */ - -static int -fromhex (int a) -{ - if (a >= '0' && a <= '9') - return a - '0'; - else if (a >= 'a' && a <= 'f') - return a - 'a' + 10; - else - error ("Reply contains invalid hex digit %d", a); -} - -/* Convert number NIB to a hex digit. */ - -static int -tohex (int nib) -{ - if (nib < 10) - return '0' + nib; - else - return 'a' + nib - 10; -} - -static int -tob64 (unsigned char *inbuf, char *outbuf, int len) -{ - int i, sum; - char *p; - - if (len % 3 != 0) - error ("bad length"); - - p = outbuf; - for (i = 0; i < len; i += 3) - { - /* Collect the next three bytes into a number. */ - sum = ((long) *inbuf++) << 16; - sum |= ((long) *inbuf++) << 8; - sum |= ((long) *inbuf++); - - /* Spit out 4 6-bit encodings. */ - *p++ = ((sum >> 18) & 0x3f) + '0'; - *p++ = ((sum >> 12) & 0x3f) + '0'; - *p++ = ((sum >> 6) & 0x3f) + '0'; - *p++ = (sum & 0x3f) + '0'; - } - return (p - outbuf); -} - -static int -fromb64 (char *inbuf, char *outbuf, int len) -{ - int i, sum; - - if (len % 4 != 0) - error ("bad length"); - - for (i = 0; i < len; i += 4) - { - /* Collect 4 6-bit digits. */ - sum = (*inbuf++ - '0') << 18; - sum |= (*inbuf++ - '0') << 12; - sum |= (*inbuf++ - '0') << 6; - sum |= (*inbuf++ - '0'); - - /* Now take the resulting 24-bit number and get three bytes out - of it. */ - *outbuf++ = (sum >> 16) & 0xff; - *outbuf++ = (sum >> 8) & 0xff; - *outbuf++ = sum & 0xff; - } - - return (len / 4) * 3; -} - - -/* Tell the remote machine to resume. */ - -static enum target_signal last_sent_signal = TARGET_SIGNAL_0; -int last_sent_step; - -static void -sds_resume (ptid_t ptid, int step, enum target_signal siggnal) -{ - unsigned char buf[PBUFSIZ]; - - last_sent_signal = siggnal; - last_sent_step = step; - - buf[0] = (step ? 21 : 20); - buf[1] = 0; /* (should be signal?) */ - - sds_send (buf, 2); -} - -/* Send a message to target to halt it. Target will respond, and send - us a message pending notice. */ - -static void -sds_interrupt (int signo) -{ - unsigned char buf[PBUFSIZ]; - - /* If this doesn't work, try more severe steps. */ - signal (signo, sds_interrupt_twice); - - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "sds_interrupt called\n"); - - buf[0] = 25; - sds_send (buf, 1); -} - -static void (*ofunc) (); - -/* The user typed ^C twice. */ - -static void -sds_interrupt_twice (int signo) -{ - signal (signo, ofunc); - - interrupt_query (); - - signal (signo, sds_interrupt); -} - -/* Ask the user what to do when an interrupt is received. */ - -static void -interrupt_query (void) -{ - target_terminal_ours (); - - if (query ("Interrupted while waiting for the program.\n\ -Give up (and stop debugging it)? ")) - { - target_mourn_inferior (); - throw_exception (RETURN_QUIT); - } - - target_terminal_inferior (); -} - -/* If nonzero, ignore the next kill. */ -int kill_kludge; - -/* Wait until the remote machine stops, then return, storing status in - STATUS just as `wait' would. Returns "pid" (though it's not clear - what, if anything, that means in the case of this target). */ - -static ptid_t -sds_wait (ptid_t ptid, struct target_waitstatus *status) -{ - unsigned char buf[PBUFSIZ]; - int retlen; - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - ofunc = (void (*)()) signal (SIGINT, sds_interrupt); - - signal (SIGINT, ofunc); - - if (just_started) - { - just_started = 0; - status->kind = TARGET_WAITKIND_STOPPED; - return inferior_ptid; - } - - while (1) - { - getmessage (buf, 1); - - if (message_pending) - { - buf[0] = 26; - retlen = sds_send (buf, 1); - if (remote_debug) - { - fprintf_unfiltered (gdb_stdlog, "Signals: %02x%02x %02x %02x\n", - buf[0], buf[1], - buf[2], buf[3]); - } - message_pending = 0; - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - goto got_status; - } - } -got_status: - return inferior_ptid; -} - -static unsigned char sprs[16]; - -/* Read the remote registers into the block REGS. */ -/* Currently we just read all the registers, so we don't use regno. */ - -/* ARGSUSED */ -static void -sds_fetch_registers (int regno) -{ - unsigned char buf[PBUFSIZ]; - int i, retlen; - char regs[REGISTER_BYTES]; - - /* Unimplemented registers read as all bits zero. */ - memset (regs, 0, REGISTER_BYTES); - - buf[0] = 18; - buf[1] = 1; - buf[2] = 0; - retlen = sds_send (buf, 3); - - for (i = 0; i < 4 * 6; ++i) - regs[i + 4 * 32 + 8 * 32] = buf[i]; - for (i = 0; i < 4 * 4; ++i) - sprs[i] = buf[i + 4 * 7]; - - buf[0] = 18; - buf[1] = 2; - buf[2] = 0; - retlen = sds_send (buf, 3); - - for (i = 0; i < retlen; i++) - regs[i] = buf[i]; - - /* (should warn about reply too short) */ - - for (i = 0; i < NUM_REGS; i++) - supply_register (i, ®s[REGISTER_BYTE (i)]); -} - -/* Prepare to store registers. Since we may send them all, we have to - read out the ones we don't want to change first. */ - -static void -sds_prepare_to_store (void) -{ - /* Make sure the entire registers array is valid. */ - read_register_bytes (0, (char *) NULL, REGISTER_BYTES); -} - -/* Store register REGNO, or all registers if REGNO == -1, from the contents - of REGISTERS. FIXME: ignores errors. */ - -static void -sds_store_registers (int regno) -{ - unsigned char *p, buf[PBUFSIZ]; - int i; - - /* Store all the special-purpose registers. */ - p = buf; - *p++ = 19; - *p++ = 1; - *p++ = 0; - *p++ = 0; - for (i = 0; i < 4 * 6; i++) - *p++ = registers[i + 4 * 32 + 8 * 32]; - for (i = 0; i < 4 * 1; i++) - *p++ = 0; - for (i = 0; i < 4 * 4; i++) - *p++ = sprs[i]; - - sds_send (buf, p - buf); - - /* Store all the general-purpose registers. */ - p = buf; - *p++ = 19; - *p++ = 2; - *p++ = 0; - *p++ = 0; - for (i = 0; i < 4 * 32; i++) - *p++ = registers[i]; - - sds_send (buf, p - buf); - -} - -/* Write memory data directly to the remote machine. This does not - inform the data cache; the data cache uses this. MEMADDR is the - address in the remote memory space. MYADDR is the address of the - buffer in our space. LEN is the number of bytes. - - Returns number of bytes transferred, or 0 for error. */ - -static int -sds_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) -{ - int max_buf_size; /* Max size of packet output buffer */ - int origlen; - unsigned char buf[PBUFSIZ]; - int todo; - int i; - - /* Chop the transfer down if necessary */ - - max_buf_size = 150; - - origlen = len; - while (len > 0) - { - todo = min (len, max_buf_size); - - buf[0] = 13; - buf[1] = 0; - buf[2] = (int) (memaddr >> 24) & 0xff; - buf[3] = (int) (memaddr >> 16) & 0xff; - buf[4] = (int) (memaddr >> 8) & 0xff; - buf[5] = (int) (memaddr) & 0xff; - buf[6] = 1; - buf[7] = 0; - - for (i = 0; i < todo; i++) - buf[i + 8] = myaddr[i]; - - sds_send (buf, 8 + todo); - - /* (should look at result) */ - - myaddr += todo; - memaddr += todo; - len -= todo; - } - return origlen; -} - -/* Read memory data directly from the remote machine. This does not - use the data cache; the data cache uses this. MEMADDR is the - address in the remote memory space. MYADDR is the address of the - buffer in our space. LEN is the number of bytes. - - Returns number of bytes transferred, or 0 for error. */ - -static int -sds_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) -{ - int max_buf_size; /* Max size of packet output buffer */ - int origlen, retlen; - unsigned char buf[PBUFSIZ]; - int todo; - int i; - - /* Chop the transfer down if necessary */ - - max_buf_size = 150; - - origlen = len; - while (len > 0) - { - todo = min (len, max_buf_size); - - buf[0] = 12; - buf[1] = 0; - buf[2] = (int) (memaddr >> 24) & 0xff; - buf[3] = (int) (memaddr >> 16) & 0xff; - buf[4] = (int) (memaddr >> 8) & 0xff; - buf[5] = (int) (memaddr) & 0xff; - buf[6] = (int) (todo >> 8) & 0xff; - buf[7] = (int) (todo) & 0xff; - buf[8] = 1; - - retlen = sds_send (buf, 9); - - if (retlen - 2 != todo) - { - return 0; - } - - /* Reply describes memory byte by byte. */ - - for (i = 0; i < todo; i++) - myaddr[i] = buf[i + 2]; - - myaddr += todo; - memaddr += todo; - len -= todo; - } - - return origlen; -} - -/* Read or write LEN bytes from inferior memory at MEMADDR, - transferring to or from debugger address MYADDR. Write to inferior - if SHOULD_WRITE is nonzero. Returns length of data written or - read; 0 for error. TARGET is unused. */ - -/* ARGSUSED */ -static int -sds_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write, - struct mem_attrib *attrib, struct target_ops *target) -{ - int res; - - if (should_write) - res = sds_write_bytes (memaddr, myaddr, len); - else - res = sds_read_bytes (memaddr, myaddr, len); - - return res; -} - - -static void -sds_files_info (struct target_ops *ignore) -{ - puts_filtered ("Debugging over a serial connection, using SDS protocol.\n"); -} - -/* Stuff for dealing with the packets which are part of this protocol. - See comment at top of file for details. */ - -/* Read a single character from the remote end, masking it down to 7 bits. */ - -static int -readchar (int timeout) -{ - int ch; - - ch = serial_readchar (sds_desc, timeout); - - if (remote_debug > 1 && ch >= 0) - fprintf_unfiltered (gdb_stdlog, "%c(%x)", ch, ch); - - switch (ch) - { - case SERIAL_EOF: - error ("Remote connection closed"); - case SERIAL_ERROR: - perror_with_name ("Remote communication error"); - case SERIAL_TIMEOUT: - return ch; - default: - return ch & 0x7f; - } -} - -/* An SDS-style checksum is a sum of the bytes modulo 253. (Presumably - because 253, 254, and 255 are special flags in the protocol.) */ - -static int -compute_checksum (int csum, char *buf, int len) -{ - int i; - - for (i = 0; i < len; ++i) - csum += (unsigned char) buf[i]; - - csum %= 253; - return csum; -} - -/* Send the command in BUF to the remote machine, and read the reply - into BUF also. */ - -static int -sds_send (unsigned char *buf, int len) -{ - putmessage (buf, len); - - return getmessage (buf, 0); -} - -/* Send a message to the remote machine. */ - -static int -putmessage (unsigned char *buf, int len) -{ - int i, enclen; - unsigned char csum = 0; - char buf2[PBUFSIZ], buf3[PBUFSIZ]; - unsigned char header[3]; - char *p; - - /* Copy the packet into buffer BUF2, encapsulating it - and giving it a checksum. */ - - if (len > 170) /* Prosanity check */ - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - if (remote_debug) - { - fprintf_unfiltered (gdb_stdlog, "Message to send: \""); - for (i = 0; i < len; ++i) - fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); - fprintf_unfiltered (gdb_stdlog, "\"\n"); - } - - p = buf2; - *p++ = '$'; - - if (len % 3 != 0) - { - buf[len] = '\0'; - buf[len + 1] = '\0'; - } - - header[1] = next_msg_id; - - header[2] = len; - - csum = compute_checksum (csum, buf, len); - csum = compute_checksum (csum, header + 1, 2); - - header[0] = csum; - - tob64 (header, p, 3); - p += 4; - enclen = tob64 (buf, buf3, ((len + 2) / 3) * 3); - - for (i = 0; i < enclen; ++i) - *p++ = buf3[i]; - *p++ = '\r'; - *p++ = '\n'; - - next_msg_id = (next_msg_id + 3) % 245; - - /* Send it over and over until we get a positive ack. */ - - while (1) - { - if (remote_debug) - { - *p = '\0'; - fprintf_unfiltered (gdb_stdlog, "Sending encoded: \"%s\"", buf2); - fprintf_unfiltered (gdb_stdlog, - " (Checksum %d, id %d, length %d)\n", - header[0], header[1], header[2]); - gdb_flush (gdb_stdlog); - } - if (serial_write (sds_desc, buf2, p - buf2)) - perror_with_name ("putmessage: write failed"); - - return 1; - } -} - -/* Come here after finding the start of the frame. Collect the rest - into BUF. Returns 0 on any error, 1 on success. */ - -static int -read_frame (char *buf) -{ - char *bp; - int c; - - bp = buf; - - while (1) - { - c = readchar (sds_timeout); - - switch (c) - { - case SERIAL_TIMEOUT: - if (remote_debug) - fputs_filtered ("Timeout in mid-message, retrying\n", gdb_stdlog); - return 0; - case '$': - if (remote_debug) - fputs_filtered ("Saw new packet start in middle of old one\n", - gdb_stdlog); - return 0; /* Start a new packet, count retries */ - case '\r': - break; - - case '\n': - { - *bp = '\000'; - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "Received encoded: \"%s\"\n", - buf); - return 1; - } - - default: - if (bp < buf + PBUFSIZ - 1) - { - *bp++ = c; - continue; - } - - *bp = '\0'; - puts_filtered ("Message too long: "); - puts_filtered (buf); - puts_filtered ("\n"); - - return 0; - } - } -} - -/* Read a packet from the remote machine, with error checking, - and store it in BUF. BUF is expected to be of size PBUFSIZ. - If FOREVER, wait forever rather than timing out; this is used - while the target is executing user code. */ - -static int -getmessage (unsigned char *buf, int forever) -{ - int c, c2, c3; - int tries; - int timeout; - int val, i, len, csum; - unsigned char header[3]; - unsigned char inbuf[500]; - - strcpy (buf, "timeout"); - - if (forever) - { - timeout = watchdog > 0 ? watchdog : -1; - } - - else - timeout = sds_timeout; - -#define MAX_TRIES 3 - - for (tries = 1; tries <= MAX_TRIES; tries++) - { - /* This can loop forever if the remote side sends us characters - continuously, but if it pauses, we'll get a zero from readchar - because of timeout. Then we'll count that as a retry. */ - - /* Note that we will only wait forever prior to the start of a packet. - After that, we expect characters to arrive at a brisk pace. They - should show up within sds_timeout intervals. */ - - do - { - c = readchar (timeout); - - if (c == SERIAL_TIMEOUT) - { - if (forever) /* Watchdog went off. Kill the target. */ - { - target_mourn_inferior (); - error ("Watchdog has expired. Target detached.\n"); - } - if (remote_debug) - fputs_filtered ("Timed out.\n", gdb_stdlog); - goto retry; - } - } - while (c != '$' && c != '{'); - - /* We might have seen a "trigraph", a sequence of three characters - that indicate various sorts of communication state. */ - - if (c == '{') - { - /* Read the other two chars of the trigraph. */ - c2 = readchar (timeout); - c3 = readchar (timeout); - if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "Trigraph %c%c%c received\n", - c, c2, c3); - if (c3 == '+') - { - message_pending = 1; - return 0; /*???? */ - } - continue; - } - - val = read_frame (inbuf); - - if (val == 1) - { - fromb64 (inbuf, header, 4); - /* (should check out other bits) */ - fromb64 (inbuf + 4, buf, strlen (inbuf) - 4); - - len = header[2]; - - csum = 0; - csum = compute_checksum (csum, buf, len); - csum = compute_checksum (csum, header + 1, 2); - - if (csum != header[0]) - fprintf_unfiltered (gdb_stderr, - "Checksum mismatch: computed %d, received %d\n", - csum, header[0]); - - if (header[2] == 0xff) - fprintf_unfiltered (gdb_stderr, "Requesting resend...\n"); - - if (remote_debug) - { - fprintf_unfiltered (gdb_stdlog, - "... (Got checksum %d, id %d, length %d)\n", - header[0], header[1], header[2]); - fprintf_unfiltered (gdb_stdlog, "Message received: \""); - for (i = 0; i < len; ++i) - { - fprintf_unfiltered (gdb_stdlog, "%02x", (unsigned char) buf[i]); - } - fprintf_unfiltered (gdb_stdlog, "\"\n"); - } - - /* no ack required? */ - return len; - } - - /* Try the whole thing again. */ - retry: - /* need to do something here */ - } - - /* We have tried hard enough, and just can't receive the packet. Give up. */ - - printf_unfiltered ("Ignoring packet error, continuing...\n"); - return 0; -} - -static void -sds_kill (void) -{ - /* Don't try to do anything to the target. */ -} - -static void -sds_mourn (void) -{ - unpush_target (&sds_ops); - generic_mourn_inferior (); -} - -static void -sds_create_inferior (char *exec_file, char *args, char **env) -{ - inferior_ptid = pid_to_ptid (42000); - - /* Clean up from the last time we were running. */ - clear_proceed_status (); - - /* Let the remote process run. */ - proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0); -} - -static void -sds_load (char *filename, int from_tty) -{ - generic_load (filename, from_tty); - - inferior_ptid = null_ptid; -} - -/* The SDS monitor has commands for breakpoint insertion, although it - it doesn't actually manage the breakpoints, it just returns the - replaced instruction back to the debugger. */ - -static int -sds_insert_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - int i, retlen; - unsigned char *p, buf[PBUFSIZ]; - - p = buf; - *p++ = 16; - *p++ = 0; - *p++ = (int) (addr >> 24) & 0xff; - *p++ = (int) (addr >> 16) & 0xff; - *p++ = (int) (addr >> 8) & 0xff; - *p++ = (int) (addr) & 0xff; - - retlen = sds_send (buf, p - buf); - - for (i = 0; i < 4; ++i) - contents_cache[i] = buf[i + 2]; - - return 0; -} - -static int -sds_remove_breakpoint (CORE_ADDR addr, char *contents_cache) -{ - int i, retlen; - unsigned char *p, buf[PBUFSIZ]; - - p = buf; - *p++ = 17; - *p++ = 0; - *p++ = (int) (addr >> 24) & 0xff; - *p++ = (int) (addr >> 16) & 0xff; - *p++ = (int) (addr >> 8) & 0xff; - *p++ = (int) (addr) & 0xff; - for (i = 0; i < 4; ++i) - *p++ = contents_cache[i]; - - retlen = sds_send (buf, p - buf); - - return 0; -} - -static void -init_sds_ops (void) -{ - sds_ops.to_shortname = "sds"; - sds_ops.to_longname = "Remote serial target with SDS protocol"; - sds_ops.to_doc = "Use a remote computer via a serial line; using the SDS protocol.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - sds_ops.to_open = sds_open; - sds_ops.to_close = sds_close; - sds_ops.to_detach = sds_detach; - sds_ops.to_resume = sds_resume; - sds_ops.to_wait = sds_wait; - sds_ops.to_fetch_registers = sds_fetch_registers; - sds_ops.to_store_registers = sds_store_registers; - sds_ops.to_prepare_to_store = sds_prepare_to_store; - sds_ops.to_xfer_memory = sds_xfer_memory; - sds_ops.to_files_info = sds_files_info; - sds_ops.to_insert_breakpoint = sds_insert_breakpoint; - sds_ops.to_remove_breakpoint = sds_remove_breakpoint; - sds_ops.to_kill = sds_kill; - sds_ops.to_load = sds_load; - sds_ops.to_create_inferior = sds_create_inferior; - sds_ops.to_mourn_inferior = sds_mourn; - sds_ops.to_stratum = process_stratum; - sds_ops.to_has_all_memory = 1; - sds_ops.to_has_memory = 1; - sds_ops.to_has_stack = 1; - sds_ops.to_has_registers = 1; - sds_ops.to_has_execution = 1; - sds_ops.to_magic = OPS_MAGIC; -} - -/* Put a command string, in args, out to the monitor and display the - reply message. */ - -static void -sds_command (char *args, int from_tty) -{ - char *p; - int i, len, retlen; - unsigned char buf[1000]; - - /* Convert hexadecimal chars into a byte buffer. */ - p = args; - len = 0; - while (*p != '\0') - { - buf[len++] = fromhex (p[0]) * 16 + fromhex (p[1]); - if (p[1] == '\0') - break; - p += 2; - } - - retlen = sds_send (buf, len); - - printf_filtered ("Reply is "); - for (i = 0; i < retlen; ++i) - { - printf_filtered ("%02x", buf[i]); - } - printf_filtered ("\n"); -} - -void -_initialize_remote_sds (void) -{ - init_sds_ops (); - add_target (&sds_ops); - - add_show_from_set (add_set_cmd ("sdstimeout", no_class, - var_integer, (char *) &sds_timeout, - "Set timeout value for sds read.\n", &setlist), - &showlist); - - add_com ("sds", class_obscure, sds_command, - "Send a command to the SDS monitor."); -} diff --git a/contrib/gdb/gdb/remote-sim.h b/contrib/gdb/gdb/remote-sim.h deleted file mode 100644 index 8c106a29262..00000000000 --- a/contrib/gdb/gdb/remote-sim.h +++ /dev/null @@ -1,142 +0,0 @@ -/* This file defines the interface between the simulator and gdb. - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if !defined (REMOTE_SIM_H) -#define REMOTE_SIM_H 1 - -#include "callback.h" -/* This file is used when building stand-alone simulators, so isolate this - file from gdb. */ - -/* Pick up CORE_ADDR_TYPE if defined (from gdb), otherwise use same value as - gdb does (unsigned int - from defs.h). */ - -#ifndef CORE_ADDR_TYPE -typedef unsigned int SIM_ADDR; -#else -typedef CORE_ADDR_TYPE SIM_ADDR; -#endif - -/* Callbacks. - The simulator may use the following callbacks (gdb routines) which the - standalone program must provide. - - void printf_filtered (char *msg, ...); - void error /-* noreturn *-/ (char *msg, ...); - void *xmalloc (long size); - int sim_callback_write_stdout (char *, int len); - - The new way of doing I/O is to use the pointer provided by GDB - via the sim_set_callbacks call, look in callbacks.c to see what - can be done. -*/ - -/* Main simulator entry points ... - - All functions that can get an error must call the gdb routine `error', - they can only return upon success. */ - -/* Initialize the simulator. This function is called when the simulator - is selected from the command line. ARGS is passed from the command line - and can be used to select whatever run time options the simulator provides. - ARGS is the raw character string and must be parsed by the simulator, - which is trivial to do with the buildargv function in libiberty. - It is ok to do nothing. */ - -void sim_open PARAMS ((char *args)); - -/* Terminate usage of the simulator. This may involve freeing target memory - and closing any open files and mmap'd areas. You cannot assume sim_kill - has already been called. - QUITTING is non-zero if we cannot hang on errors. */ - -void sim_close PARAMS ((int quitting)); - -/* Load program PROG into the simulator. - Return non-zero if you wish the caller to handle it - (it is done this way because most simulators can use gr_load_image, - but defining it as a callback seems awkward). */ - -int sim_load PARAMS ((char *prog, int from_tty)); - -/* Prepare to run the simulated program. - START_ADDRESS is, yes, you guessed it, the start address of the program. - ARGV and ENV are NULL terminated lists of pointers. - Gdb will set the start address via sim_store_register as well, but - standalone versions of existing simulators are not set up to cleanly call - sim_store_register, so the START_ADDRESS argument is there as a - workaround. */ - -void sim_create_inferior PARAMS ((SIM_ADDR start_address, - char **argv, char **env)); - -/* Kill the running program. - This may involve closing any open files and deleting any mmap'd areas. */ - -void sim_kill PARAMS ((void)); - -/* Read LENGTH bytes of the simulated program's memory and store in BUF. - Result is number of bytes read, or zero if error. */ - -int sim_read PARAMS ((SIM_ADDR mem, unsigned char *buf, int length)); - -/* Store LENGTH bytes from BUF in the simulated program's memory. - Result is number of bytes write, or zero if error. */ - -int sim_write PARAMS ((SIM_ADDR mem, unsigned char *buf, int length)); - -/* Fetch register REGNO and store the raw value in BUF. */ - -void sim_fetch_register PARAMS ((int regno, unsigned char *buf)); - -/* Store register REGNO from BUF (in raw format). */ - -void sim_store_register PARAMS ((int regno, unsigned char *buf)); - -/* Print some interesting information about the simulator. - VERBOSE is non-zero for the wordy version. */ - -void sim_info PARAMS ((int verbose)); - -/* Fetch why the program stopped. - SIGRC will contain either the argument to exit() or the signal number. */ - -enum sim_stop { sim_exited, sim_stopped, sim_signalled }; - -void sim_stop_reason PARAMS ((enum sim_stop *reason, int *sigrc)); - -/* Run (or resume) the program. */ - -void sim_resume PARAMS ((int step, int siggnal)); - -/* Passthru for other commands that the simulator might support. */ - -void sim_do_command PARAMS ((char *cmd)); - - -/* Callbacks for the simulator to use. */ - -int sim_callback_write_stdout PARAMS ((char *, int)); - -/* Provide simulator with a standard host_callback_struct. */ - -void sim_set_callbacks PARAMS ((struct host_callback_struct *)); - - -#endif /* !defined (REMOTE_SIM_H) */ diff --git a/contrib/gdb/gdb/remote-udi.c b/contrib/gdb/gdb/remote-udi.c deleted file mode 100644 index f7863a81395..00000000000 --- a/contrib/gdb/gdb/remote-udi.c +++ /dev/null @@ -1,1722 +0,0 @@ -/* OBSOLETE /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB. */ -/* OBSOLETE Copyright 1990, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 */ -/* OBSOLETE Free Software Foundation, Inc. */ -/* OBSOLETE Written by Daniel Mann. Contributed by AMD. */ -/* OBSOLETE */ -/* OBSOLETE This file is part of GDB. */ -/* OBSOLETE */ -/* OBSOLETE This program is free software; you can redistribute it and/or modify */ -/* OBSOLETE it under the terms of the GNU General Public License as published by */ -/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */ -/* OBSOLETE (at your option) any later version. */ -/* OBSOLETE */ -/* OBSOLETE This program is distributed in the hope that it will be useful, */ -/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* OBSOLETE GNU General Public License for more details. */ -/* OBSOLETE */ -/* OBSOLETE You should have received a copy of the GNU General Public License */ -/* OBSOLETE along with this program; if not, write to the Free Software */ -/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */ -/* OBSOLETE Boston, MA 02111-1307, USA. */ */ -/* OBSOLETE */ -/* OBSOLETE /* This is like remote.c but uses the Universal Debug Interface (UDI) to */ -/* OBSOLETE talk to the target hardware (or simulator). UDI is a TCP/IP based */ -/* OBSOLETE protocol; for hardware that doesn't run TCP, an interface adapter */ -/* OBSOLETE daemon talks UDI on one side, and talks to the hardware (typically */ -/* OBSOLETE over a serial port) on the other side. */ -/* OBSOLETE */ -/* OBSOLETE - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6. */ -/* OBSOLETE - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this */ -/* OBSOLETE file to gdb 3.95. I was unable to get this working on sun3os4 */ -/* OBSOLETE with termio, only with sgtty. */ -/* OBSOLETE - Daniel Mann at AMD took the 3.95 adaptions above and replaced */ -/* OBSOLETE MiniMON interface with UDI-p interface. */ */ -/* OBSOLETE */ -/* OBSOLETE #include "defs.h" */ -/* OBSOLETE #include "frame.h" */ -/* OBSOLETE #include "inferior.h" */ -/* OBSOLETE #include "value.h" */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include */ -/* OBSOLETE #include "gdb_string.h" */ -/* OBSOLETE #include "terminal.h" */ -/* OBSOLETE #include "target.h" */ -/* OBSOLETE #include "29k-share/udi/udiproc.h" */ -/* OBSOLETE #include "gdbcmd.h" */ -/* OBSOLETE #include "bfd.h" */ -/* OBSOLETE #include "gdbcore.h" /* For download function */ */ -/* OBSOLETE #include "regcache.h" */ -/* OBSOLETE */ -/* OBSOLETE /* access the register store directly, without going through */ -/* OBSOLETE the normal handler functions. This avoids an extra data copy. */ */ -/* OBSOLETE */ -/* OBSOLETE extern int stop_soon_quietly; /* for wait_for_inferior */ */ -/* OBSOLETE extern struct value *call_function_by_hand (); */ -/* OBSOLETE static void udi_resume (ptid_t ptid, int step, enum target_signal sig); */ -/* OBSOLETE static void udi_fetch_registers (int regno); */ -/* OBSOLETE static void udi_load (char *args, int from_tty); */ -/* OBSOLETE static void fetch_register (int regno); */ -/* OBSOLETE static void udi_store_registers (int regno); */ -/* OBSOLETE static int store_register (int regno); */ -/* OBSOLETE static int regnum_to_srnum (int regno); */ -/* OBSOLETE static void udi_close (int quitting); */ -/* OBSOLETE static CPUSpace udi_memory_space (CORE_ADDR addr); */ -/* OBSOLETE static int udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, */ -/* OBSOLETE int len); */ -/* OBSOLETE static int udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, */ -/* OBSOLETE int len); */ -/* OBSOLETE static void download (char *load_arg_string, int from_tty); */ -/* OBSOLETE char CoffFileName[100] = ""; */ -/* OBSOLETE */ -/* OBSOLETE #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400) */ -/* OBSOLETE #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE) */ -/* OBSOLETE */ -/* OBSOLETE static int timeout = 5; */ -/* OBSOLETE extern struct target_ops udi_ops; /* Forward declaration */ */ -/* OBSOLETE */ -/* OBSOLETE /* Special register enumeration. */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************************* UDI DATA*/ */ -/* OBSOLETE #define MAXDATA 2*1024 /* max UDI[read/write] byte size */ */ -/* OBSOLETE /* Descriptor for I/O to remote machine. Initialize it to -1 so that */ -/* OBSOLETE udi_open knows that we don't have a file open when the program */ -/* OBSOLETE starts. */ */ -/* OBSOLETE */ -/* OBSOLETE UDISessionId udi_session_id = -1; */ -/* OBSOLETE static char *udi_config_id; */ -/* OBSOLETE */ -/* OBSOLETE CPUOffset IMemStart = 0; */ -/* OBSOLETE CPUSizeT IMemSize = 0; */ -/* OBSOLETE CPUOffset DMemStart = 0; */ -/* OBSOLETE CPUSizeT DMemSize = 0; */ -/* OBSOLETE CPUOffset RMemStart = 0; */ -/* OBSOLETE CPUSizeT RMemSize = 0; */ -/* OBSOLETE UDIUInt32 CPUPRL; */ -/* OBSOLETE UDIUInt32 CoProcPRL; */ -/* OBSOLETE */ -/* OBSOLETE UDIMemoryRange address_ranges[2]; /* Text and data */ */ -/* OBSOLETE UDIResource entry = */ -/* OBSOLETE {0, 0}; /* Entry point */ */ -/* OBSOLETE CPUSizeT stack_sizes[2]; /* Regular and memory stacks */ */ -/* OBSOLETE */ -/* OBSOLETE #define SBUF_MAX 1024 /* maximum size of string handling buffer */ */ -/* OBSOLETE char sbuf[SBUF_MAX]; */ -/* OBSOLETE */ -/* OBSOLETE typedef struct bkpt_entry_str */ -/* OBSOLETE { */ -/* OBSOLETE UDIResource Addr; */ -/* OBSOLETE UDIUInt32 PassCount; */ -/* OBSOLETE UDIBreakType Type; */ -/* OBSOLETE unsigned int BreakId; */ -/* OBSOLETE } */ -/* OBSOLETE bkpt_entry_t; */ -/* OBSOLETE #define BKPT_TABLE_SIZE 40 */ -/* OBSOLETE static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE]; */ -/* OBSOLETE extern char dfe_errmsg[]; /* error string */ */ -/* OBSOLETE */ -/* OBSOLETE /* malloc'd name of the program on the remote system. */ */ -/* OBSOLETE static char *prog_name = NULL; */ -/* OBSOLETE */ -/* OBSOLETE /* This is called not only when we first attach, but also when the */ -/* OBSOLETE user types "run" after having attached. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_create_inferior (char *execfile, char *args, char **env) */ -/* OBSOLETE { */ -/* OBSOLETE char *args1; */ -/* OBSOLETE */ -/* OBSOLETE if (execfile) */ -/* OBSOLETE { */ -/* OBSOLETE if (prog_name != NULL) */ -/* OBSOLETE xfree (prog_name); */ -/* OBSOLETE prog_name = savestring (execfile, strlen (execfile)); */ -/* OBSOLETE } */ -/* OBSOLETE else if (entry.Offset) */ -/* OBSOLETE execfile = ""; */ -/* OBSOLETE else */ -/* OBSOLETE error ("No image loaded into target."); */ -/* OBSOLETE */ -/* OBSOLETE if (udi_session_id < 0) */ -/* OBSOLETE { */ -/* OBSOLETE /* If the TIP is not open, open it. */ */ -/* OBSOLETE if (UDIConnect (udi_config_id, &udi_session_id)) */ -/* OBSOLETE error ("UDIConnect() failed: %s\n", dfe_errmsg); */ -/* OBSOLETE /* We will need to download the program. */ */ -/* OBSOLETE entry.Offset = 0; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE inferior_ptid = pid_to_ptid (40000); */ -/* OBSOLETE */ -/* OBSOLETE if (!entry.Offset) */ -/* OBSOLETE download (execfile, 0); */ -/* OBSOLETE */ -/* OBSOLETE args1 = alloca (strlen (execfile) + strlen (args) + 2); */ -/* OBSOLETE */ -/* OBSOLETE if (execfile[0] == '\0') */ -/* OBSOLETE */ -/* OBSOLETE /* It is empty. We need to quote it somehow, or else the target */ -/* OBSOLETE will think there is no argument being passed here. According */ -/* OBSOLETE to the UDI spec it is quoted "according to TIP OS rules" which */ -/* OBSOLETE I guess means quoting it like the Unix shell should work */ -/* OBSOLETE (sounds pretty bogus to me...). In fact it doesn't work (with */ -/* OBSOLETE isstip anyway), but passing in two quotes as the argument seems */ -/* OBSOLETE like a reasonable enough behavior anyway (I guess). */ */ -/* OBSOLETE */ -/* OBSOLETE strcpy (args1, "''"); */ -/* OBSOLETE else */ -/* OBSOLETE strcpy (args1, execfile); */ -/* OBSOLETE strcat (args1, " "); */ -/* OBSOLETE strcat (args1, args); */ -/* OBSOLETE */ -/* OBSOLETE UDIInitializeProcess (address_ranges, /* ProcessMemory[] */ */ -/* OBSOLETE (UDIInt) 2, /* NumberOfRanges */ */ -/* OBSOLETE entry, /* EntryPoint */ */ -/* OBSOLETE stack_sizes, /* *StackSizes */ */ -/* OBSOLETE (UDIInt) 2, /* NumberOfStacks */ */ -/* OBSOLETE args1); /* ArgString */ */ -/* OBSOLETE */ -/* OBSOLETE init_wait_for_inferior (); */ -/* OBSOLETE clear_proceed_status (); */ -/* OBSOLETE proceed (-1, TARGET_SIGNAL_DEFAULT, 0); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_mourn (void) */ -/* OBSOLETE { */ -/* OBSOLETE #if 0 */ -/* OBSOLETE /* Requiring "target udi" each time you run is a major pain. I suspect */ -/* OBSOLETE this was just blindy copied from remote.c, in which "target" and */ -/* OBSOLETE "run" are combined. Having a udi target without an inferior seems */ -/* OBSOLETE to work between "target udi" and "run", so why not now? */ */ -/* OBSOLETE pop_target (); /* Pop back to no-child state */ */ -/* OBSOLETE #endif */ -/* OBSOLETE /* But if we're going to want to run it again, we better remove the */ -/* OBSOLETE breakpoints... */ */ -/* OBSOLETE remove_breakpoints (); */ -/* OBSOLETE generic_mourn_inferior (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************************** UDI_OPEN */ -/* OBSOLETE ** Open a connection to remote TIP. */ -/* OBSOLETE NAME is the socket domain used for communication with the TIP, */ -/* OBSOLETE then a space and the socket name or TIP-host name. */ -/* OBSOLETE '' for example. */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE /* XXX - need cleanups for udiconnect for various failures!!! */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_open (char *name, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE unsigned int prl; */ -/* OBSOLETE char *p; */ -/* OBSOLETE int cnt; */ -/* OBSOLETE UDIMemoryRange KnownMemory[10]; */ -/* OBSOLETE UDIUInt32 ChipVersions[10]; */ -/* OBSOLETE UDIInt NumberOfRanges = 10; */ -/* OBSOLETE UDIInt NumberOfChips = 10; */ -/* OBSOLETE UDIPId PId; */ -/* OBSOLETE UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId; */ -/* OBSOLETE */ -/* OBSOLETE target_preopen (from_tty); */ -/* OBSOLETE */ -/* OBSOLETE entry.Offset = 0; */ -/* OBSOLETE */ -/* OBSOLETE for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++) */ -/* OBSOLETE bkpt_table[cnt].Type = 0; */ -/* OBSOLETE */ -/* OBSOLETE if (udi_config_id) */ -/* OBSOLETE xfree (udi_config_id); */ -/* OBSOLETE */ -/* OBSOLETE if (!name) */ -/* OBSOLETE error ("Usage: target udi config_id, where config_id appears in udi_soc file"); */ -/* OBSOLETE */ -/* OBSOLETE udi_config_id = xstrdup (strtok (name, " \t")); */ -/* OBSOLETE */ -/* OBSOLETE if (UDIConnect (udi_config_id, &udi_session_id)) */ -/* OBSOLETE /* FIXME: Should set udi_session_id to -1 here. */ */ -/* OBSOLETE error ("UDIConnect() failed: %s\n", dfe_errmsg); */ -/* OBSOLETE */ -/* OBSOLETE push_target (&udi_ops); */ -/* OBSOLETE */ -/* OBSOLETE /* */ -/* OBSOLETE ** Initialize target configuration structure (global) */ -/* OBSOLETE */ */ -/* OBSOLETE if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges, */ -/* OBSOLETE ChipVersions, &NumberOfChips)) */ -/* OBSOLETE error ("UDIGetTargetConfig() failed"); */ -/* OBSOLETE if (NumberOfChips > 2) */ -/* OBSOLETE fprintf_unfiltered (gdb_stderr, "Target has more than one processor\n"); */ -/* OBSOLETE for (cnt = 0; cnt < NumberOfRanges; cnt++) */ -/* OBSOLETE { */ -/* OBSOLETE switch (KnownMemory[cnt].Space) */ -/* OBSOLETE { */ -/* OBSOLETE default: */ -/* OBSOLETE fprintf_unfiltered (gdb_stderr, "UDIGetTargetConfig() unknown memory space\n"); */ -/* OBSOLETE break; */ -/* OBSOLETE case UDI29KCP_S: */ -/* OBSOLETE break; */ -/* OBSOLETE case UDI29KIROMSpace: */ -/* OBSOLETE RMemStart = KnownMemory[cnt].Offset; */ -/* OBSOLETE RMemSize = KnownMemory[cnt].Size; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDI29KIRAMSpace: */ -/* OBSOLETE IMemStart = KnownMemory[cnt].Offset; */ -/* OBSOLETE IMemSize = KnownMemory[cnt].Size; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDI29KDRAMSpace: */ -/* OBSOLETE DMemStart = KnownMemory[cnt].Offset; */ -/* OBSOLETE DMemSize = KnownMemory[cnt].Size; */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE a29k_get_processor_type (); */ -/* OBSOLETE */ -/* OBSOLETE if (UDICreateProcess (&PId)) */ -/* OBSOLETE fprintf_unfiltered (gdb_stderr, "UDICreateProcess() failed\n"); */ -/* OBSOLETE */ -/* OBSOLETE /* Print out some stuff, letting the user now what's going on */ */ -/* OBSOLETE if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId, */ -/* OBSOLETE &TIPIPCId, sbuf)) */ -/* OBSOLETE error ("UDICapabilities() failed"); */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE printf_filtered ("Connected via UDI socket,\n\ */ -/* OBSOLETE DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n", */ -/* OBSOLETE (DFEIPCId >> 8) & 0xf, (DFEIPCId >> 4) & 0xf, DFEIPCId & 0xf, */ -/* OBSOLETE (TIPIPCId >> 8) & 0xf, (TIPIPCId >> 4) & 0xf, TIPIPCId & 0xf, */ -/* OBSOLETE (TargetId >> 8) & 0xf, (TargetId >> 4) & 0xf, TargetId & 0xf, */ -/* OBSOLETE sbuf); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************************* UDI_CLOSE */ -/* OBSOLETE Close the open connection to the TIP process. */ -/* OBSOLETE Use this when you want to detach and do something else */ -/* OBSOLETE with your gdb. */ */ -/* OBSOLETE static void */ -/* OBSOLETE udi_close ( /*FIXME: how is quitting used */ */ -/* OBSOLETE int quitting) */ -/* OBSOLETE { */ -/* OBSOLETE if (udi_session_id < 0) */ -/* OBSOLETE return; */ -/* OBSOLETE */ -/* OBSOLETE /* We should never get here if there isn't something valid in */ -/* OBSOLETE udi_session_id. */ */ -/* OBSOLETE */ -/* OBSOLETE if (UDIDisconnect (udi_session_id, UDITerminateSession)) */ -/* OBSOLETE { */ -/* OBSOLETE if (quitting) */ -/* OBSOLETE warning ("UDIDisconnect() failed in udi_close"); */ -/* OBSOLETE else */ -/* OBSOLETE error ("UDIDisconnect() failed in udi_close"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Do not try to close udi_session_id again, later in the program. */ */ -/* OBSOLETE udi_session_id = -1; */ -/* OBSOLETE inferior_ptid = null_ptid; */ -/* OBSOLETE */ -/* OBSOLETE printf_filtered (" Ending remote debugging\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /**************************************************************** UDI_ATACH */ */ -/* OBSOLETE /* Attach to a program that is already loaded and running */ -/* OBSOLETE * Upon exiting the process's execution is stopped. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE udi_attach (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE UDIResource From; */ -/* OBSOLETE UDIInt32 PC_adds; */ -/* OBSOLETE UDICount Count = 1; */ -/* OBSOLETE UDISizeT Size = 4; */ -/* OBSOLETE UDICount CountDone; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE */ -/* OBSOLETE if (args == NULL) */ -/* OBSOLETE error_no_arg ("program to attach"); */ -/* OBSOLETE */ -/* OBSOLETE if (udi_session_id < 0) */ -/* OBSOLETE error ("UDI connection not opened yet, use the 'target udi' command.\n"); */ -/* OBSOLETE */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf_unfiltered ("Attaching to remote program %s...\n", prog_name); */ -/* OBSOLETE */ -/* OBSOLETE UDIStop (); */ -/* OBSOLETE From.Space = UDI29KSpecialRegs; */ -/* OBSOLETE From.Offset = 11; */ -/* OBSOLETE if (err = UDIRead (From, &PC_adds, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead failed in udi_attach"); */ -/* OBSOLETE printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds); */ -/* OBSOLETE } */ -/* OBSOLETE /************************************************************* UDI_DETACH */ */ -/* OBSOLETE /* Terminate the open connection to the TIP process. */ -/* OBSOLETE Use this when you want to detach and do something else */ -/* OBSOLETE with your gdb. Leave remote process running (with no breakpoints set). */ */ -/* OBSOLETE static void */ -/* OBSOLETE udi_detach (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE remove_breakpoints (); /* Just in case there were any left in */ */ -/* OBSOLETE */ -/* OBSOLETE if (UDIDisconnect (udi_session_id, UDIContinueSession)) */ -/* OBSOLETE error ("UDIDisconnect() failed in udi_detach"); */ -/* OBSOLETE */ -/* OBSOLETE /* Don't try to UDIDisconnect it again in udi_close, which is called from */ -/* OBSOLETE pop_target. */ */ -/* OBSOLETE udi_session_id = -1; */ -/* OBSOLETE inferior_ptid = null_ptid; */ -/* OBSOLETE */ -/* OBSOLETE pop_target (); */ -/* OBSOLETE */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf_unfiltered ("Detaching from TIP\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /****************************************************************** UDI_RESUME */ -/* OBSOLETE ** Tell the remote machine to resume. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_resume (ptid_t ptid, int step, enum target_signal sig) */ -/* OBSOLETE { */ -/* OBSOLETE UDIError tip_error; */ -/* OBSOLETE UDIUInt32 Steps = 1; */ -/* OBSOLETE UDIStepType StepType = UDIStepNatural; */ -/* OBSOLETE UDIRange Range; */ -/* OBSOLETE */ -/* OBSOLETE if (step) /* step 1 instruction */ */ -/* OBSOLETE { */ -/* OBSOLETE tip_error = UDIStep (Steps, StepType, Range); */ -/* OBSOLETE if (!tip_error) */ -/* OBSOLETE return; */ -/* OBSOLETE */ -/* OBSOLETE fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error); */ -/* OBSOLETE error ("failed in udi_resume"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (UDIExecute ()) */ -/* OBSOLETE error ("UDIExecute() failed in udi_resume"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /******************************************************************** UDI_WAIT */ -/* OBSOLETE ** Wait until the remote machine stops, then return, */ -/* OBSOLETE storing status in STATUS just as `wait' would. */ */ -/* OBSOLETE */ -/* OBSOLETE static ptid_t */ -/* OBSOLETE udi_wait (ptid_t ptid, struct target_waitstatus *status) */ -/* OBSOLETE { */ -/* OBSOLETE UDIInt32 MaxTime; */ -/* OBSOLETE UDIPId PId; */ -/* OBSOLETE UDIInt32 StopReason; */ -/* OBSOLETE UDISizeT CountDone; */ -/* OBSOLETE int old_timeout = timeout; */ -/* OBSOLETE int old_immediate_quit = immediate_quit; */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* wait for message to arrive. It should be: */ -/* OBSOLETE If the target stops executing, udi_wait() should return. */ -/* OBSOLETE */ */ -/* OBSOLETE timeout = 0; /* Wait indefinetly for a message */ */ -/* OBSOLETE immediate_quit = 1; /* Helps ability to QUIT */ */ -/* OBSOLETE */ -/* OBSOLETE while (1) */ -/* OBSOLETE { */ -/* OBSOLETE i = 0; */ -/* OBSOLETE MaxTime = UDIWaitForever; */ -/* OBSOLETE UDIWait (MaxTime, &PId, &StopReason); */ -/* OBSOLETE QUIT; /* Let user quit if they want */ */ -/* OBSOLETE */ -/* OBSOLETE switch (StopReason & UDIGrossState) */ -/* OBSOLETE { */ -/* OBSOLETE case UDIStdoutReady: */ -/* OBSOLETE if (UDIGetStdout (sbuf, (UDISizeT) SBUF_MAX, &CountDone)) */ -/* OBSOLETE /* This is said to happen if the program tries to output */ -/* OBSOLETE a whole bunch of output (more than SBUF_MAX, I would */ -/* OBSOLETE guess). It doesn't seem to happen with the simulator. */ */ -/* OBSOLETE warning ("UDIGetStdout() failed in udi_wait"); */ -/* OBSOLETE fwrite (sbuf, 1, CountDone, stdout); */ -/* OBSOLETE gdb_flush (gdb_stdout); */ -/* OBSOLETE continue; */ -/* OBSOLETE */ -/* OBSOLETE case UDIStderrReady: */ -/* OBSOLETE UDIGetStderr (sbuf, (UDISizeT) SBUF_MAX, &CountDone); */ -/* OBSOLETE fwrite (sbuf, 1, CountDone, stderr); */ -/* OBSOLETE gdb_flush (gdb_stderr); */ -/* OBSOLETE continue; */ -/* OBSOLETE */ -/* OBSOLETE case UDIStdinNeeded: */ -/* OBSOLETE { */ -/* OBSOLETE int ch; */ -/* OBSOLETE i = 0; */ -/* OBSOLETE do */ -/* OBSOLETE { */ -/* OBSOLETE ch = getchar (); */ -/* OBSOLETE if (ch == EOF) */ -/* OBSOLETE break; */ -/* OBSOLETE sbuf[i++] = ch; */ -/* OBSOLETE } */ -/* OBSOLETE while (i < SBUF_MAX && ch != '\n'); */ -/* OBSOLETE UDIPutStdin (sbuf, (UDISizeT) i, &CountDone); */ -/* OBSOLETE continue; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE case UDIRunning: */ -/* OBSOLETE /* In spite of the fact that we told UDIWait to wait forever, it will */ -/* OBSOLETE return spuriously sometimes. */ */ -/* OBSOLETE case UDIStdinModeX: */ -/* OBSOLETE continue; */ -/* OBSOLETE default: */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE switch (StopReason & UDIGrossState) */ -/* OBSOLETE { */ -/* OBSOLETE case UDITrapped: */ -/* OBSOLETE printf_unfiltered ("Am290*0 received vector number %d\n", StopReason >> 24); */ -/* OBSOLETE */ -/* OBSOLETE switch ((StopReason >> 8) & 0xff) */ -/* OBSOLETE { */ -/* OBSOLETE case 0: /* Illegal opcode */ */ -/* OBSOLETE printf_unfiltered (" (break point)\n"); */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE break; */ -/* OBSOLETE case 1: /* Unaligned Access */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_BUS; */ -/* OBSOLETE break; */ -/* OBSOLETE case 3: */ -/* OBSOLETE case 4: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_FPE; */ -/* OBSOLETE break; */ -/* OBSOLETE case 5: /* Protection Violation */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE /* Why not SEGV? What is a Protection Violation? */ */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ILL; */ -/* OBSOLETE break; */ -/* OBSOLETE case 6: */ -/* OBSOLETE case 7: */ -/* OBSOLETE case 8: /* User Instruction Mapping Miss */ */ -/* OBSOLETE case 9: /* User Data Mapping Miss */ */ -/* OBSOLETE case 10: /* Supervisor Instruction Mapping Miss */ */ -/* OBSOLETE case 11: /* Supervisor Data Mapping Miss */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_SEGV; */ -/* OBSOLETE break; */ -/* OBSOLETE case 12: */ -/* OBSOLETE case 13: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ILL; */ -/* OBSOLETE break; */ -/* OBSOLETE case 14: /* Timer */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ALRM; */ -/* OBSOLETE break; */ -/* OBSOLETE case 15: /* Trace */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE break; */ -/* OBSOLETE case 16: /* INTR0 */ */ -/* OBSOLETE case 17: /* INTR1 */ */ -/* OBSOLETE case 18: /* INTR2 */ */ -/* OBSOLETE case 19: /* INTR3/Internal */ */ -/* OBSOLETE case 20: /* TRAP0 */ */ -/* OBSOLETE case 21: /* TRAP1 */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_INT; */ -/* OBSOLETE break; */ -/* OBSOLETE case 22: /* Floating-Point Exception */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE /* Why not FPE? */ */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_ILL; */ -/* OBSOLETE break; */ -/* OBSOLETE case 77: /* assert 77 */ */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE break; */ -/* OBSOLETE default: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE } */ -/* OBSOLETE break; */ -/* OBSOLETE case UDINotExecuting: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TERM; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDIStopped: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TSTP; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDIWarned: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_URG; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDIStepped: */ -/* OBSOLETE case UDIBreak: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDIWaiting: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_STOP; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDIHalted: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; */ -/* OBSOLETE status->value.sig = TARGET_SIGNAL_KILL; */ -/* OBSOLETE break; */ -/* OBSOLETE case UDIExited: */ -/* OBSOLETE default: */ -/* OBSOLETE status->kind = TARGET_WAITKIND_EXITED; */ -/* OBSOLETE status->value.integer = 0; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE timeout = old_timeout; /* Restore original timeout value */ */ -/* OBSOLETE immediate_quit = old_immediate_quit; */ -/* OBSOLETE return inferior_ptid; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #if 0 */ -/* OBSOLETE /* Handy for debugging */ */ -/* OBSOLETE udi_pc (void) */ -/* OBSOLETE { */ -/* OBSOLETE UDIResource From; */ -/* OBSOLETE UDIUInt32 *To; */ -/* OBSOLETE UDICount Count; */ -/* OBSOLETE UDISizeT Size = 4; */ -/* OBSOLETE UDICount CountDone; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE int pc[2]; */ -/* OBSOLETE unsigned long myregs[256]; */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KPC; */ -/* OBSOLETE From.Offset = 0; */ -/* OBSOLETE To = (UDIUInt32 *) pc; */ -/* OBSOLETE Count = 2; */ -/* OBSOLETE */ -/* OBSOLETE err = UDIRead (From, To, Count, Size, &CountDone, HostEndian); */ -/* OBSOLETE */ -/* OBSOLETE printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n", */ -/* OBSOLETE err, CountDone, pc[0], pc[1]); */ -/* OBSOLETE */ -/* OBSOLETE udi_fetch_registers (-1); */ -/* OBSOLETE */ -/* OBSOLETE printf_unfiltered ("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *) ®isters[4 * PC_REGNUM], */ -/* OBSOLETE *(int *) ®isters[4 * NPC_REGNUM]); */ -/* OBSOLETE */ -/* OBSOLETE /* Now, read all the registers globally */ */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KGlobalRegs; */ -/* OBSOLETE From.Offset = 0; */ -/* OBSOLETE err = UDIRead (From, myregs, 256, 4, &CountDone, HostEndian); */ -/* OBSOLETE */ -/* OBSOLETE printf ("err = %d, CountDone = %d\n", err, CountDone); */ -/* OBSOLETE */ -/* OBSOLETE printf ("\n"); */ -/* OBSOLETE */ -/* OBSOLETE for (i = 0; i < 256; i += 2) */ -/* OBSOLETE printf ("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i], */ -/* OBSOLETE myregs[i + 1], myregs[i + 1]); */ -/* OBSOLETE printf ("\n"); */ -/* OBSOLETE */ -/* OBSOLETE return pc[0]; */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************** UDI_FETCH_REGISTERS */ -/* OBSOLETE * Read a remote register 'regno'. */ -/* OBSOLETE * If regno==-1 then read all the registers. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE udi_fetch_registers (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE UDIResource From; */ -/* OBSOLETE UDIUInt32 *To; */ -/* OBSOLETE UDICount Count; */ -/* OBSOLETE UDISizeT Size = 4; */ -/* OBSOLETE UDICount CountDone; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE int i; */ -/* OBSOLETE */ -/* OBSOLETE if (regno >= 0) */ -/* OBSOLETE { */ -/* OBSOLETE fetch_register (regno); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Gr1/rsp */ */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KGlobalRegs; */ -/* OBSOLETE From.Offset = 1; */ -/* OBSOLETE To = (UDIUInt32 *) & registers[4 * GR1_REGNUM]; */ -/* OBSOLETE Count = 1; */ -/* OBSOLETE if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead() failed in udi_fetch_registers"); */ -/* OBSOLETE */ -/* OBSOLETE register_valid[GR1_REGNUM] = 1; */ -/* OBSOLETE */ -/* OBSOLETE #if defined(GR64_REGNUM) /* Read gr64-127 */ */ -/* OBSOLETE */ -/* OBSOLETE /* Global Registers gr64-gr95 */ */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KGlobalRegs; */ -/* OBSOLETE From.Offset = 64; */ -/* OBSOLETE To = (UDIUInt32 *) & registers[4 * GR64_REGNUM]; */ -/* OBSOLETE Count = 32; */ -/* OBSOLETE if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead() failed in udi_fetch_registers"); */ -/* OBSOLETE */ -/* OBSOLETE for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++) */ -/* OBSOLETE register_valid[i] = 1; */ -/* OBSOLETE */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE */ -/* OBSOLETE /* Global Registers gr96-gr127 */ */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KGlobalRegs; */ -/* OBSOLETE From.Offset = 96; */ -/* OBSOLETE To = (UDIUInt32 *) & registers[4 * GR96_REGNUM]; */ -/* OBSOLETE Count = 32; */ -/* OBSOLETE if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead() failed in udi_fetch_registers"); */ -/* OBSOLETE */ -/* OBSOLETE for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++) */ -/* OBSOLETE register_valid[i] = 1; */ -/* OBSOLETE */ -/* OBSOLETE /* Local Registers */ */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KLocalRegs; */ -/* OBSOLETE From.Offset = 0; */ -/* OBSOLETE To = (UDIUInt32 *) & registers[4 * LR0_REGNUM]; */ -/* OBSOLETE Count = 128; */ -/* OBSOLETE if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead() failed in udi_fetch_registers"); */ -/* OBSOLETE */ -/* OBSOLETE for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++) */ -/* OBSOLETE register_valid[i] = 1; */ -/* OBSOLETE */ -/* OBSOLETE /* Protected Special Registers */ */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KSpecialRegs; */ -/* OBSOLETE From.Offset = 0; */ -/* OBSOLETE To = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)]; */ -/* OBSOLETE Count = 15; */ -/* OBSOLETE if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead() failed in udi_fetch_registers"); */ -/* OBSOLETE */ -/* OBSOLETE for (i = SR_REGNUM (0); i < SR_REGNUM (0) + 15; i++) */ -/* OBSOLETE register_valid[i] = 1; */ -/* OBSOLETE */ -/* OBSOLETE if (USE_SHADOW_PC) */ -/* OBSOLETE { /* Let regno_to_srnum() handle the register number */ */ -/* OBSOLETE fetch_register (NPC_REGNUM); */ -/* OBSOLETE fetch_register (PC_REGNUM); */ -/* OBSOLETE fetch_register (PC2_REGNUM); */ -/* OBSOLETE */ -/* OBSOLETE /* Unprotected Special Registers sr128-sr135 */ */ -/* OBSOLETE */ -/* OBSOLETE From.Space = UDI29KSpecialRegs; */ -/* OBSOLETE From.Offset = 128; */ -/* OBSOLETE To = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)]; */ -/* OBSOLETE Count = 135 - 128 + 1; */ -/* OBSOLETE if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead() failed in udi_fetch_registers"); */ -/* OBSOLETE */ -/* OBSOLETE for (i = SR_REGNUM (128); i < SR_REGNUM (128) + 135 - 128 + 1; i++) */ -/* OBSOLETE register_valid[i] = 1; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (remote_debug) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf_unfiltered (gdb_stdlog, "Fetching all registers\n"); */ -/* OBSOLETE fprintf_unfiltered (gdb_stdlog, */ -/* OBSOLETE "Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", */ -/* OBSOLETE read_register (NPC_REGNUM), */ -/* OBSOLETE read_register (PC_REGNUM), */ -/* OBSOLETE read_register (PC2_REGNUM)); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* There doesn't seem to be any way to get these. */ */ -/* OBSOLETE { */ -/* OBSOLETE int val = -1; */ -/* OBSOLETE supply_register (FPE_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (INTE_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (FPS_REGNUM, (char *) &val); */ -/* OBSOLETE supply_register (EXO_REGNUM, (char *) &val); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************* UDI_STORE_REGISTERS */ -/* OBSOLETE ** Store register regno into the target. */ -/* OBSOLETE * If regno==-1 then store all the registers. */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_store_registers (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE UDIUInt32 *From; */ -/* OBSOLETE UDIResource To; */ -/* OBSOLETE UDICount Count; */ -/* OBSOLETE UDISizeT Size = 4; */ -/* OBSOLETE UDICount CountDone; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE */ -/* OBSOLETE if (regno >= 0) */ -/* OBSOLETE { */ -/* OBSOLETE store_register (regno); */ -/* OBSOLETE return; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (remote_debug) */ -/* OBSOLETE { */ -/* OBSOLETE fprintf_unfiltered (gdb_stdlog, "Storing all registers\n"); */ -/* OBSOLETE fprintf_unfiltered (gdb_stdlog, */ -/* OBSOLETE "PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", */ -/* OBSOLETE read_register (NPC_REGNUM), */ -/* OBSOLETE read_register (PC_REGNUM), */ -/* OBSOLETE read_register (PC2_REGNUM)); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Gr1/rsp */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * GR1_REGNUM]; */ -/* OBSOLETE To.Space = UDI29KGlobalRegs; */ -/* OBSOLETE To.Offset = 1; */ -/* OBSOLETE Count = 1; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE */ -/* OBSOLETE /* Global registers gr64-gr95 */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * GR64_REGNUM]; */ -/* OBSOLETE To.Space = UDI29KGlobalRegs; */ -/* OBSOLETE To.Offset = 64; */ -/* OBSOLETE Count = 32; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE */ -/* OBSOLETE /* Global registers gr96-gr127 */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * GR96_REGNUM]; */ -/* OBSOLETE To.Space = UDI29KGlobalRegs; */ -/* OBSOLETE To.Offset = 96; */ -/* OBSOLETE Count = 32; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE /* Local Registers */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * LR0_REGNUM]; */ -/* OBSOLETE To.Space = UDI29KLocalRegs; */ -/* OBSOLETE To.Offset = 0; */ -/* OBSOLETE Count = 128; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /* Protected Special Registers *//* VAB through TMR */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)]; */ -/* OBSOLETE To.Space = UDI29KSpecialRegs; */ -/* OBSOLETE To.Offset = 0; */ -/* OBSOLETE Count = 10; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE /* PC0, PC1, PC2 possibly as shadow registers */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * SR_REGNUM (10)]; */ -/* OBSOLETE To.Space = UDI29KSpecialRegs; */ -/* OBSOLETE Count = 3; */ -/* OBSOLETE if (USE_SHADOW_PC) */ -/* OBSOLETE To.Offset = 20; /* SPC0 */ */ -/* OBSOLETE else */ -/* OBSOLETE To.Offset = 10; /* PC0 */ */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE /* PC1 via UDI29KPC */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * PC_REGNUM]; */ -/* OBSOLETE To.Space = UDI29KPC; */ -/* OBSOLETE To.Offset = 0; /* PC1 */ */ -/* OBSOLETE Count = 1; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE /* LRU and MMU */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * SR_REGNUM (13)]; */ -/* OBSOLETE To.Space = UDI29KSpecialRegs; */ -/* OBSOLETE To.Offset = 13; */ -/* OBSOLETE Count = 2; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE /* Unprotected Special Registers */ */ -/* OBSOLETE */ -/* OBSOLETE From = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)]; */ -/* OBSOLETE To.Space = UDI29KSpecialRegs; */ -/* OBSOLETE To.Offset = 128; */ -/* OBSOLETE Count = 135 - 128 + 1; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIWrite() failed in udi_store_regisetrs"); */ -/* OBSOLETE */ -/* OBSOLETE registers_changed (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /****************************************************** UDI_PREPARE_TO_STORE */ */ -/* OBSOLETE /* Get ready to modify the registers array. On machines which store */ -/* OBSOLETE individual registers, this doesn't need to do anything. On machines */ -/* OBSOLETE which store all the registers in one fell swoop, this makes sure */ -/* OBSOLETE that registers contains all the registers from the program being */ -/* OBSOLETE debugged. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_prepare_to_store (void) */ -/* OBSOLETE { */ -/* OBSOLETE /* Do nothing, since we can store individual regs */ */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************** TRANSLATE_ADDR */ */ -/* OBSOLETE static CORE_ADDR */ -/* OBSOLETE translate_addr (CORE_ADDR addr) */ -/* OBSOLETE { */ -/* OBSOLETE #if defined(ULTRA3) && defined(KERNEL_DEBUGGING) */ -/* OBSOLETE /* Check for a virtual address in the kernel */ */ -/* OBSOLETE /* Assume physical address of ublock is in paddr_u register */ */ -/* OBSOLETE /* FIXME: doesn't work for user virtual addresses */ */ -/* OBSOLETE if (addr >= UVADDR) */ -/* OBSOLETE { */ -/* OBSOLETE /* PADDR_U register holds the physical address of the ublock */ */ -/* OBSOLETE CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM); */ -/* OBSOLETE return (i + addr - (CORE_ADDR) UVADDR); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE return (addr); */ -/* OBSOLETE } */ -/* OBSOLETE #else */ -/* OBSOLETE return (addr); */ -/* OBSOLETE #endif */ -/* OBSOLETE } */ -/* OBSOLETE /************************************************* UDI_XFER_INFERIOR_MEMORY */ */ -/* OBSOLETE /* FIXME! Merge these two. */ */ -/* OBSOLETE static int */ -/* OBSOLETE udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, */ -/* OBSOLETE struct mem_attrib *attrib ATTRIBUTE_UNUSED, */ -/* OBSOLETE struct target_ops *target ATTRIBUTE_UNUSED) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE memaddr = translate_addr (memaddr); */ -/* OBSOLETE */ -/* OBSOLETE if (write) */ -/* OBSOLETE return udi_write_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE else */ -/* OBSOLETE return udi_read_inferior_memory (memaddr, myaddr, len); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************** UDI_FILES_INFO */ */ -/* OBSOLETE static void */ -/* OBSOLETE udi_files_info (struct target_ops *target) */ -/* OBSOLETE { */ -/* OBSOLETE printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id); */ -/* OBSOLETE if (prog_name != NULL) */ -/* OBSOLETE printf_unfiltered ("and running program %s", prog_name); */ -/* OBSOLETE printf_unfiltered (".\n"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /**************************************************** UDI_INSERT_BREAKPOINT */ */ -/* OBSOLETE static int */ -/* OBSOLETE udi_insert_breakpoint (CORE_ADDR addr, char *contents_cache) */ -/* OBSOLETE { */ -/* OBSOLETE int cnt; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE */ -/* OBSOLETE for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++) */ -/* OBSOLETE if (bkpt_table[cnt].Type == 0) /* Find first free slot */ */ -/* OBSOLETE break; */ -/* OBSOLETE */ -/* OBSOLETE if (cnt >= BKPT_TABLE_SIZE) */ -/* OBSOLETE error ("Too many breakpoints set"); */ -/* OBSOLETE */ -/* OBSOLETE bkpt_table[cnt].Addr.Offset = addr; */ -/* OBSOLETE bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace; */ -/* OBSOLETE bkpt_table[cnt].PassCount = 1; */ -/* OBSOLETE bkpt_table[cnt].Type = UDIBreakFlagExecute; */ -/* OBSOLETE */ -/* OBSOLETE err = UDISetBreakpoint (bkpt_table[cnt].Addr, */ -/* OBSOLETE bkpt_table[cnt].PassCount, */ -/* OBSOLETE bkpt_table[cnt].Type, */ -/* OBSOLETE &bkpt_table[cnt].BreakId); */ -/* OBSOLETE */ -/* OBSOLETE if (err == 0) */ -/* OBSOLETE return 0; /* Success */ */ -/* OBSOLETE */ -/* OBSOLETE bkpt_table[cnt].Type = 0; */ -/* OBSOLETE error ("UDISetBreakpoint returned error code %d\n", err); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /**************************************************** UDI_REMOVE_BREAKPOINT */ */ -/* OBSOLETE static int */ -/* OBSOLETE udi_remove_breakpoint (CORE_ADDR addr, char *contents_cache) */ -/* OBSOLETE { */ -/* OBSOLETE int cnt; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE */ -/* OBSOLETE for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++) */ -/* OBSOLETE if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */ */ -/* OBSOLETE break; */ -/* OBSOLETE */ -/* OBSOLETE if (cnt >= BKPT_TABLE_SIZE) */ -/* OBSOLETE error ("Can't find breakpoint in table"); */ -/* OBSOLETE */ -/* OBSOLETE bkpt_table[cnt].Type = 0; */ -/* OBSOLETE */ -/* OBSOLETE err = UDIClearBreakpoint (bkpt_table[cnt].BreakId); */ -/* OBSOLETE if (err == 0) */ -/* OBSOLETE return 0; /* Success */ */ -/* OBSOLETE */ -/* OBSOLETE error ("UDIClearBreakpoint returned error code %d\n", err); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_kill (void) */ -/* OBSOLETE { */ -/* OBSOLETE */ -/* OBSOLETE #if 0 */ -/* OBSOLETE /* */ -/* OBSOLETE UDIStop does not really work as advertised. It causes the TIP to close it's */ -/* OBSOLETE connection, which usually results in GDB dying with a SIGPIPE. For now, we */ -/* OBSOLETE just invoke udi_close, which seems to get things right. */ -/* OBSOLETE */ */ -/* OBSOLETE UDIStop (); */ -/* OBSOLETE */ -/* OBSOLETE udi_session_id = -1; */ -/* OBSOLETE inferior_ptid = null_ptid; */ -/* OBSOLETE */ -/* OBSOLETE if (from_tty) */ -/* OBSOLETE printf_unfiltered ("Target has been stopped."); */ -/* OBSOLETE #endif /* 0 */ */ -/* OBSOLETE #if 0 */ -/* OBSOLETE udi_close (0); */ -/* OBSOLETE pop_target (); */ -/* OBSOLETE #endif /* 0 */ */ -/* OBSOLETE */ -/* OBSOLETE /* Keep the target around, e.g. so "run" can do the right thing when */ -/* OBSOLETE we are already debugging something. */ */ -/* OBSOLETE */ -/* OBSOLETE if (UDIDisconnect (udi_session_id, UDITerminateSession)) */ -/* OBSOLETE { */ -/* OBSOLETE warning ("UDIDisconnect() failed"); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Do not try to close udi_session_id again, later in the program. */ */ -/* OBSOLETE udi_session_id = -1; */ -/* OBSOLETE inferior_ptid = null_ptid; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* */ -/* OBSOLETE Load a program into the target. Args are: `program {options}'. The options */ -/* OBSOLETE are used to control loading of the program, and are NOT passed onto the */ -/* OBSOLETE loaded code as arguments. (You need to use the `run' command to do that.) */ -/* OBSOLETE */ -/* OBSOLETE The options are: */ -/* OBSOLETE -ms %d Set mem stack size to %d */ -/* OBSOLETE -rs %d Set regular stack size to %d */ -/* OBSOLETE -i send init info (default) */ -/* OBSOLETE -noi don't send init info */ -/* OBSOLETE -[tT] Load Text section */ -/* OBSOLETE -[dD] Load Data section */ -/* OBSOLETE -[bB] Load BSS section */ -/* OBSOLETE -[lL] Load Lit section */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE download (char *load_arg_string, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE #define DEFAULT_MEM_STACK_SIZE 0x6000 */ -/* OBSOLETE #define DEFAULT_REG_STACK_SIZE 0x2000 */ -/* OBSOLETE */ -/* OBSOLETE char *token; */ -/* OBSOLETE char *filename; */ -/* OBSOLETE asection *section; */ -/* OBSOLETE bfd *pbfd; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1; */ -/* OBSOLETE */ -/* OBSOLETE address_ranges[0].Space = UDI29KIRAMSpace; */ -/* OBSOLETE address_ranges[0].Offset = 0xffffffff; */ -/* OBSOLETE address_ranges[0].Size = 0; */ -/* OBSOLETE */ -/* OBSOLETE address_ranges[1].Space = UDI29KDRAMSpace; */ -/* OBSOLETE address_ranges[1].Offset = 0xffffffff; */ -/* OBSOLETE address_ranges[1].Size = 0; */ -/* OBSOLETE */ -/* OBSOLETE stack_sizes[0] = DEFAULT_REG_STACK_SIZE; */ -/* OBSOLETE stack_sizes[1] = DEFAULT_MEM_STACK_SIZE; */ -/* OBSOLETE */ -/* OBSOLETE dont_repeat (); */ -/* OBSOLETE */ -/* OBSOLETE filename = strtok (load_arg_string, " \t"); */ -/* OBSOLETE if (!filename) */ -/* OBSOLETE error ("Must specify at least a file name with the load command"); */ -/* OBSOLETE */ -/* OBSOLETE filename = tilde_expand (filename); */ -/* OBSOLETE make_cleanup (xfree, filename); */ -/* OBSOLETE */ -/* OBSOLETE while (token = strtok (NULL, " \t")) */ -/* OBSOLETE { */ -/* OBSOLETE if (token[0] == '-') */ -/* OBSOLETE { */ -/* OBSOLETE token++; */ -/* OBSOLETE */ -/* OBSOLETE if (STREQ (token, "ms")) */ -/* OBSOLETE stack_sizes[1] = atol (strtok (NULL, " \t")); */ -/* OBSOLETE else if (STREQ (token, "rs")) */ -/* OBSOLETE stack_sizes[0] = atol (strtok (NULL, " \t")); */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE load_text = load_data = load_bss = load_lit = 0; */ -/* OBSOLETE */ -/* OBSOLETE while (*token) */ -/* OBSOLETE { */ -/* OBSOLETE switch (*token++) */ -/* OBSOLETE { */ -/* OBSOLETE case 't': */ -/* OBSOLETE case 'T': */ -/* OBSOLETE load_text = 1; */ -/* OBSOLETE break; */ -/* OBSOLETE case 'd': */ -/* OBSOLETE case 'D': */ -/* OBSOLETE load_data = 1; */ -/* OBSOLETE break; */ -/* OBSOLETE case 'b': */ -/* OBSOLETE case 'B': */ -/* OBSOLETE load_bss = 1; */ -/* OBSOLETE break; */ -/* OBSOLETE case 'l': */ -/* OBSOLETE case 'L': */ -/* OBSOLETE load_lit = 1; */ -/* OBSOLETE break; */ -/* OBSOLETE default: */ -/* OBSOLETE error ("Unknown UDI load option -%s", token - 1); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE pbfd = bfd_openr (filename, gnutarget); */ -/* OBSOLETE */ -/* OBSOLETE if (!pbfd) */ -/* OBSOLETE /* FIXME: should be using bfd_errmsg, not assuming it was */ -/* OBSOLETE bfd_error_system_call. */ */ -/* OBSOLETE perror_with_name (filename); */ -/* OBSOLETE */ -/* OBSOLETE /* FIXME: should be checking for errors from bfd_close (for one thing, */ -/* OBSOLETE on error it does not free all the storage associated with the */ -/* OBSOLETE bfd). */ */ -/* OBSOLETE make_cleanup_bfd_close (pbfd); */ -/* OBSOLETE */ -/* OBSOLETE QUIT; */ -/* OBSOLETE immediate_quit++; */ -/* OBSOLETE */ -/* OBSOLETE if (!bfd_check_format (pbfd, bfd_object)) */ -/* OBSOLETE error ("It doesn't seem to be an object file"); */ -/* OBSOLETE */ -/* OBSOLETE for (section = pbfd->sections; section; section = section->next) */ -/* OBSOLETE { */ -/* OBSOLETE if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC) */ -/* OBSOLETE { */ -/* OBSOLETE UDIResource To; */ -/* OBSOLETE UDICount Count; */ -/* OBSOLETE unsigned long section_size, section_end; */ -/* OBSOLETE const char *section_name; */ -/* OBSOLETE */ -/* OBSOLETE section_name = bfd_get_section_name (pbfd, section); */ -/* OBSOLETE if (STREQ (section_name, ".text") && !load_text) */ -/* OBSOLETE continue; */ -/* OBSOLETE else if (STREQ (section_name, ".data") && !load_data) */ -/* OBSOLETE continue; */ -/* OBSOLETE else if (STREQ (section_name, ".bss") && !load_bss) */ -/* OBSOLETE continue; */ -/* OBSOLETE else if (STREQ (section_name, ".lit") && !load_lit) */ -/* OBSOLETE continue; */ -/* OBSOLETE */ -/* OBSOLETE To.Offset = bfd_get_section_vma (pbfd, section); */ -/* OBSOLETE section_size = bfd_section_size (pbfd, section); */ -/* OBSOLETE section_end = To.Offset + section_size; */ -/* OBSOLETE */ -/* OBSOLETE if (section_size == 0) */ -/* OBSOLETE /* This is needed at least in the BSS case, where the code */ -/* OBSOLETE below starts writing before it even checks the size. */ */ -/* OBSOLETE continue; */ -/* OBSOLETE */ -/* OBSOLETE printf_unfiltered ("[Loading section %s at %x (%d bytes)]\n", */ -/* OBSOLETE section_name, */ -/* OBSOLETE To.Offset, */ -/* OBSOLETE section_size); */ -/* OBSOLETE */ -/* OBSOLETE if (bfd_get_section_flags (pbfd, section) & SEC_CODE) */ -/* OBSOLETE { */ -/* OBSOLETE To.Space = UDI29KIRAMSpace; */ -/* OBSOLETE */ -/* OBSOLETE address_ranges[0].Offset = min (address_ranges[0].Offset, */ -/* OBSOLETE To.Offset); */ -/* OBSOLETE address_ranges[0].Size = max (address_ranges[0].Size, */ -/* OBSOLETE section_end */ -/* OBSOLETE - address_ranges[0].Offset); */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE To.Space = UDI29KDRAMSpace; */ -/* OBSOLETE */ -/* OBSOLETE address_ranges[1].Offset = min (address_ranges[1].Offset, */ -/* OBSOLETE To.Offset); */ -/* OBSOLETE address_ranges[1].Size = max (address_ranges[1].Size, */ -/* OBSOLETE section_end */ -/* OBSOLETE - address_ranges[1].Offset); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */ */ -/* OBSOLETE { */ -/* OBSOLETE file_ptr fptr; */ -/* OBSOLETE */ -/* OBSOLETE fptr = 0; */ -/* OBSOLETE */ -/* OBSOLETE while (section_size > 0) */ -/* OBSOLETE { */ -/* OBSOLETE char buffer[1024]; */ -/* OBSOLETE */ -/* OBSOLETE Count = min (section_size, 1024); */ -/* OBSOLETE */ -/* OBSOLETE bfd_get_section_contents (pbfd, section, buffer, fptr, */ -/* OBSOLETE Count); */ -/* OBSOLETE */ -/* OBSOLETE err = UDIWrite ((UDIHostMemPtr) buffer, /* From */ */ -/* OBSOLETE To, /* To */ */ -/* OBSOLETE Count, /* Count */ */ -/* OBSOLETE (UDISizeT) 1, /* Size */ */ -/* OBSOLETE &Count, /* CountDone */ */ -/* OBSOLETE (UDIBool) 0); /* HostEndian */ */ -/* OBSOLETE if (err) */ -/* OBSOLETE error ("UDIWrite failed, error = %d", err); */ -/* OBSOLETE */ -/* OBSOLETE To.Offset += Count; */ -/* OBSOLETE fptr += Count; */ -/* OBSOLETE section_size -= Count; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE /* BSS */ */ -/* OBSOLETE { */ -/* OBSOLETE UDIResource From; */ -/* OBSOLETE unsigned long zero = 0; */ -/* OBSOLETE */ -/* OBSOLETE /* Write a zero byte at the vma */ */ -/* OBSOLETE /* FIXME: Broken for sections of 1-3 bytes (we test for */ -/* OBSOLETE zero above). */ */ -/* OBSOLETE err = UDIWrite ((UDIHostMemPtr) & zero, /* From */ */ -/* OBSOLETE To, /* To */ */ -/* OBSOLETE (UDICount) 1, /* Count */ */ -/* OBSOLETE (UDISizeT) 4, /* Size */ */ -/* OBSOLETE &Count, /* CountDone */ */ -/* OBSOLETE (UDIBool) 0); /* HostEndian */ */ -/* OBSOLETE if (err) */ -/* OBSOLETE error ("UDIWrite failed, error = %d", err); */ -/* OBSOLETE */ -/* OBSOLETE From = To; */ -/* OBSOLETE To.Offset += 4; */ -/* OBSOLETE */ -/* OBSOLETE /* Now, duplicate it for the length of the BSS */ */ -/* OBSOLETE err = UDICopy (From, /* From */ */ -/* OBSOLETE To, /* To */ */ -/* OBSOLETE (UDICount) (section_size / 4 - 1), /* Count */ */ -/* OBSOLETE (UDISizeT) 4, /* Size */ */ -/* OBSOLETE &Count, /* CountDone */ */ -/* OBSOLETE (UDIBool) 1); /* Direction */ */ -/* OBSOLETE if (err) */ -/* OBSOLETE { */ -/* OBSOLETE char message[100]; */ -/* OBSOLETE int xerr; */ -/* OBSOLETE */ -/* OBSOLETE xerr = UDIGetErrorMsg (err, 100, message, &Count); */ -/* OBSOLETE if (!xerr) */ -/* OBSOLETE fprintf_unfiltered (gdb_stderr, "Error is %s\n", message); */ -/* OBSOLETE else */ -/* OBSOLETE fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr); */ -/* OBSOLETE error ("UDICopy failed, error = %d", err); */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE entry.Space = UDI29KIRAMSpace; */ -/* OBSOLETE entry.Offset = bfd_get_start_address (pbfd); */ -/* OBSOLETE */ -/* OBSOLETE immediate_quit--; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /* Function to download an image into the remote target. */ */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE udi_load (char *args, int from_tty) */ -/* OBSOLETE { */ -/* OBSOLETE download (args, from_tty); */ -/* OBSOLETE */ -/* OBSOLETE /* As a convenience, pick up any symbol info that is in the program */ -/* OBSOLETE being loaded. Note that we assume that the program is the``mainline''; */ -/* OBSOLETE if this is not always true, then this code will need to be augmented. */ */ -/* OBSOLETE symbol_file_add (strtok (args, " \t"), from_tty, NULL, 1, 0); */ -/* OBSOLETE */ -/* OBSOLETE /* Getting new symbols may change our opinion about what is */ -/* OBSOLETE frameless. */ */ -/* OBSOLETE reinit_frame_cache (); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /*************************************************** UDI_WRITE_INFERIOR_MEMORY */ -/* OBSOLETE ** Copy LEN bytes of data from debugger memory at MYADDR */ -/* OBSOLETE to inferior's memory at MEMADDR. Returns number of bytes written. */ */ -/* OBSOLETE static int */ -/* OBSOLETE udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int nwritten = 0; */ -/* OBSOLETE UDIUInt32 *From; */ -/* OBSOLETE UDIResource To; */ -/* OBSOLETE UDICount Count; */ -/* OBSOLETE UDISizeT Size = 1; */ -/* OBSOLETE UDICount CountDone = 0; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE */ -/* OBSOLETE To.Space = udi_memory_space (memaddr); */ -/* OBSOLETE From = (UDIUInt32 *) myaddr; */ -/* OBSOLETE */ -/* OBSOLETE while (nwritten < len) */ -/* OBSOLETE { */ -/* OBSOLETE Count = len - nwritten; */ -/* OBSOLETE if (Count > MAXDATA) */ -/* OBSOLETE Count = MAXDATA; */ -/* OBSOLETE To.Offset = memaddr + nwritten; */ -/* OBSOLETE if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE { */ -/* OBSOLETE error ("UDIWrite() failed in udi_write_inferior_memory"); */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE nwritten += CountDone; */ -/* OBSOLETE From += CountDone; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE return (nwritten); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /**************************************************** UDI_READ_INFERIOR_MEMORY */ -/* OBSOLETE ** Read LEN bytes from inferior memory at MEMADDR. Put the result */ -/* OBSOLETE at debugger address MYADDR. Returns number of bytes read. */ */ -/* OBSOLETE static int */ -/* OBSOLETE udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) */ -/* OBSOLETE { */ -/* OBSOLETE int nread = 0; */ -/* OBSOLETE UDIResource From; */ -/* OBSOLETE UDIUInt32 *To; */ -/* OBSOLETE UDICount Count; */ -/* OBSOLETE UDISizeT Size = 1; */ -/* OBSOLETE UDICount CountDone = 0; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE */ -/* OBSOLETE From.Space = udi_memory_space (memaddr); */ -/* OBSOLETE To = (UDIUInt32 *) myaddr; */ -/* OBSOLETE */ -/* OBSOLETE while (nread < len) */ -/* OBSOLETE { */ -/* OBSOLETE Count = len - nread; */ -/* OBSOLETE if (Count > MAXDATA) */ -/* OBSOLETE Count = MAXDATA; */ -/* OBSOLETE From.Offset = memaddr + nread; */ -/* OBSOLETE if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE { */ -/* OBSOLETE error ("UDIRead() failed in udi_read_inferior_memory"); */ -/* OBSOLETE break; */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE nread += CountDone; */ -/* OBSOLETE To += CountDone; */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE return (nread); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE /********************************************************************* WARNING */ -/* OBSOLETE */ */ -/* OBSOLETE udi_warning (int num) */ -/* OBSOLETE { */ -/* OBSOLETE error ("ERROR while loading program into remote TIP: $d\n", num); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE */ -/* OBSOLETE /*****************************************************************************/ */ -/* OBSOLETE /* Fetch a single register indicatated by 'regno'. */ -/* OBSOLETE * Returns 0/-1 on success/failure. */ -/* OBSOLETE */ */ -/* OBSOLETE static void */ -/* OBSOLETE fetch_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE UDIResource From; */ -/* OBSOLETE UDIUInt32 To; */ -/* OBSOLETE UDICount Count = 1; */ -/* OBSOLETE UDISizeT Size = 4; */ -/* OBSOLETE UDICount CountDone; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE UDIError err; */ -/* OBSOLETE int result; */ -/* OBSOLETE */ -/* OBSOLETE if (regno == GR1_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE From.Space = UDI29KGlobalRegs; */ -/* OBSOLETE From.Offset = 1; */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE From.Space = UDI29KGlobalRegs; */ -/* OBSOLETE From.Offset = (regno - GR96_REGNUM) + 96;; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE */ -/* OBSOLETE else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE From.Space = UDI29KGlobalRegs; */ -/* OBSOLETE From.Offset = (regno - GR64_REGNUM) + 64; */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE */ -/* OBSOLETE else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) */ -/* OBSOLETE { */ -/* OBSOLETE From.Space = UDI29KLocalRegs; */ -/* OBSOLETE From.Offset = (regno - LR0_REGNUM); */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE int val = -1; */ -/* OBSOLETE /*supply_register(160 + (regno - FPE_REGNUM),(char *) &val); */ */ -/* OBSOLETE supply_register (regno, (char *) &val); */ -/* OBSOLETE return; /* Pretend Success */ */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE { */ -/* OBSOLETE From.Space = UDI29KSpecialRegs; */ -/* OBSOLETE From.Offset = regnum_to_srnum (regno); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (err = UDIRead (From, &To, Count, Size, &CountDone, HostEndian)) */ -/* OBSOLETE error ("UDIRead() failed in udi_fetch_registers"); */ -/* OBSOLETE */ -/* OBSOLETE supply_register (regno, (char *) &To); */ -/* OBSOLETE */ -/* OBSOLETE if (remote_debug) */ -/* OBSOLETE fprintf_unfiltered (gdb_stdlog, "Fetching register %s = 0x%x\n", */ -/* OBSOLETE REGISTER_NAME (regno), To); */ -/* OBSOLETE } */ -/* OBSOLETE /*****************************************************************************/ */ -/* OBSOLETE /* Store a single register indicated by 'regno'. */ -/* OBSOLETE * Returns 0/-1 on success/failure. */ -/* OBSOLETE */ */ -/* OBSOLETE static int */ -/* OBSOLETE store_register (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE int result; */ -/* OBSOLETE UDIUInt32 From; */ -/* OBSOLETE UDIResource To; */ -/* OBSOLETE UDICount Count = 1; */ -/* OBSOLETE UDISizeT Size = 4; */ -/* OBSOLETE UDICount CountDone; */ -/* OBSOLETE UDIBool HostEndian = 0; */ -/* OBSOLETE */ -/* OBSOLETE From = read_register (regno); /* get data value */ */ -/* OBSOLETE */ -/* OBSOLETE if (remote_debug) */ -/* OBSOLETE fprintf_unfiltered (gdb_stdlog, "Storing register %s = 0x%x\n", */ -/* OBSOLETE REGISTER_NAME (regno), From); */ -/* OBSOLETE */ -/* OBSOLETE if (regno == GR1_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE To.Space = UDI29KGlobalRegs; */ -/* OBSOLETE To.Offset = 1; */ -/* OBSOLETE result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian); */ -/* OBSOLETE /* Setting GR1 changes the numbers of all the locals, so invalidate the */ -/* OBSOLETE * register cache. Do this *after* calling read_register, because we want */ -/* OBSOLETE * read_register to return the value that write_register has just stuffed */ -/* OBSOLETE * into the registers array, not the value of the register fetched from */ -/* OBSOLETE * the inferior. */ -/* OBSOLETE */ */ -/* OBSOLETE registers_changed (); */ -/* OBSOLETE } */ -/* OBSOLETE #if defined(GR64_REGNUM) */ -/* OBSOLETE else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE To.Space = UDI29KGlobalRegs; */ -/* OBSOLETE To.Offset = (regno - GR64_REGNUM) + 64; */ -/* OBSOLETE result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian); */ -/* OBSOLETE } */ -/* OBSOLETE #endif /* GR64_REGNUM */ */ -/* OBSOLETE else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) */ -/* OBSOLETE { */ -/* OBSOLETE To.Space = UDI29KGlobalRegs; */ -/* OBSOLETE To.Offset = (regno - GR96_REGNUM) + 96; */ -/* OBSOLETE result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian); */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) */ -/* OBSOLETE { */ -/* OBSOLETE To.Space = UDI29KLocalRegs; */ -/* OBSOLETE To.Offset = (regno - LR0_REGNUM); */ -/* OBSOLETE result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian); */ -/* OBSOLETE } */ -/* OBSOLETE else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM) */ -/* OBSOLETE return 0; /* Pretend Success */ */ -/* OBSOLETE else if (regno == PC_REGNUM) */ -/* OBSOLETE { */ -/* OBSOLETE /* PC1 via UDI29KPC */ */ -/* OBSOLETE */ -/* OBSOLETE To.Space = UDI29KPC; */ -/* OBSOLETE To.Offset = 0; /* PC1 */ */ -/* OBSOLETE result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian); */ -/* OBSOLETE */ -/* OBSOLETE /* Writing to this loc actually changes the values of pc0 & pc1 */ */ -/* OBSOLETE */ -/* OBSOLETE register_valid[PC_REGNUM] = 0; /* pc1 */ */ -/* OBSOLETE register_valid[NPC_REGNUM] = 0; /* pc0 */ */ -/* OBSOLETE } */ -/* OBSOLETE else */ -/* OBSOLETE /* An unprotected or protected special register */ */ -/* OBSOLETE { */ -/* OBSOLETE To.Space = UDI29KSpecialRegs; */ -/* OBSOLETE To.Offset = regnum_to_srnum (regno); */ -/* OBSOLETE result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian); */ -/* OBSOLETE } */ -/* OBSOLETE */ -/* OBSOLETE if (result != 0) */ -/* OBSOLETE error ("UDIWrite() failed in store_registers"); */ -/* OBSOLETE */ -/* OBSOLETE return 0; */ -/* OBSOLETE } */ -/* OBSOLETE /********************************************************** REGNUM_TO_SRNUM */ */ -/* OBSOLETE /* */ -/* OBSOLETE * Convert a gdb special register number to a 29000 special register number. */ -/* OBSOLETE */ */ -/* OBSOLETE static int */ -/* OBSOLETE regnum_to_srnum (int regno) */ -/* OBSOLETE { */ -/* OBSOLETE switch (regno) */ -/* OBSOLETE { */ -/* OBSOLETE case VAB_REGNUM: */ -/* OBSOLETE return (0); */ -/* OBSOLETE case OPS_REGNUM: */ -/* OBSOLETE return (1); */ -/* OBSOLETE case CPS_REGNUM: */ -/* OBSOLETE return (2); */ -/* OBSOLETE case CFG_REGNUM: */ -/* OBSOLETE return (3); */ -/* OBSOLETE case CHA_REGNUM: */ -/* OBSOLETE return (4); */ -/* OBSOLETE case CHD_REGNUM: */ -/* OBSOLETE return (5); */ -/* OBSOLETE case CHC_REGNUM: */ -/* OBSOLETE return (6); */ -/* OBSOLETE case RBP_REGNUM: */ -/* OBSOLETE return (7); */ -/* OBSOLETE case TMC_REGNUM: */ -/* OBSOLETE return (8); */ -/* OBSOLETE case TMR_REGNUM: */ -/* OBSOLETE return (9); */ -/* OBSOLETE case NPC_REGNUM: */ -/* OBSOLETE return (USE_SHADOW_PC ? (20) : (10)); */ -/* OBSOLETE case PC_REGNUM: */ -/* OBSOLETE return (USE_SHADOW_PC ? (21) : (11)); */ -/* OBSOLETE case PC2_REGNUM: */ -/* OBSOLETE return (USE_SHADOW_PC ? (22) : (12)); */ -/* OBSOLETE case MMU_REGNUM: */ -/* OBSOLETE return (13); */ -/* OBSOLETE case LRU_REGNUM: */ -/* OBSOLETE return (14); */ -/* OBSOLETE case IPC_REGNUM: */ -/* OBSOLETE return (128); */ -/* OBSOLETE case IPA_REGNUM: */ -/* OBSOLETE return (129); */ -/* OBSOLETE case IPB_REGNUM: */ -/* OBSOLETE return (130); */ -/* OBSOLETE case Q_REGNUM: */ -/* OBSOLETE return (131); */ -/* OBSOLETE case ALU_REGNUM: */ -/* OBSOLETE return (132); */ -/* OBSOLETE case BP_REGNUM: */ -/* OBSOLETE return (133); */ -/* OBSOLETE case FC_REGNUM: */ -/* OBSOLETE return (134); */ -/* OBSOLETE case CR_REGNUM: */ -/* OBSOLETE return (135); */ -/* OBSOLETE case FPE_REGNUM: */ -/* OBSOLETE return (160); */ -/* OBSOLETE case INTE_REGNUM: */ -/* OBSOLETE return (161); */ -/* OBSOLETE case FPS_REGNUM: */ -/* OBSOLETE return (162); */ -/* OBSOLETE case EXO_REGNUM: */ -/* OBSOLETE return (164); */ -/* OBSOLETE default: */ -/* OBSOLETE return (255); /* Failure ? */ */ -/* OBSOLETE } */ -/* OBSOLETE } */ -/* OBSOLETE /****************************************************************************/ */ -/* OBSOLETE /* */ -/* OBSOLETE * Determine the Target memory space qualifier based on the addr. */ -/* OBSOLETE * FIXME: Can't distinguis I_ROM/D_ROM. */ -/* OBSOLETE * FIXME: Doesn't know anything about I_CACHE/D_CACHE. */ -/* OBSOLETE */ */ -/* OBSOLETE static CPUSpace */ -/* OBSOLETE udi_memory_space (CORE_ADDR addr) */ -/* OBSOLETE { */ -/* OBSOLETE UDIUInt32 tstart = IMemStart; */ -/* OBSOLETE UDIUInt32 tend = tstart + IMemSize; */ -/* OBSOLETE UDIUInt32 dstart = DMemStart; */ -/* OBSOLETE UDIUInt32 dend = tstart + DMemSize; */ -/* OBSOLETE UDIUInt32 rstart = RMemStart; */ -/* OBSOLETE UDIUInt32 rend = tstart + RMemSize; */ -/* OBSOLETE */ -/* OBSOLETE if (((UDIUInt32) addr >= tstart) && ((UDIUInt32) addr < tend)) */ -/* OBSOLETE { */ -/* OBSOLETE return UDI29KIRAMSpace; */ -/* OBSOLETE } */ -/* OBSOLETE else if (((UDIUInt32) addr >= dstart) && ((UDIUInt32) addr < dend)) */ -/* OBSOLETE { */ -/* OBSOLETE return UDI29KDRAMSpace; */ -/* OBSOLETE } */ -/* OBSOLETE else if (((UDIUInt32) addr >= rstart) && ((UDIUInt32) addr < rend)) */ -/* OBSOLETE { */ -/* OBSOLETE /* FIXME: how do we determine between D_ROM and I_ROM */ */ -/* OBSOLETE return UDI29KIROMSpace; */ -/* OBSOLETE } */ -/* OBSOLETE else /* FIXME: what do me do now? */ */ -/* OBSOLETE return UDI29KDRAMSpace; /* Hmmm! */ */ -/* OBSOLETE } */ -/* OBSOLETE /*********************************************************************** STUBS */ -/* OBSOLETE */ */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE convert16 (void) */ -/* OBSOLETE {; */ -/* OBSOLETE } */ -/* OBSOLETE void */ -/* OBSOLETE convert32 (void) */ -/* OBSOLETE {; */ -/* OBSOLETE } */ -/* OBSOLETE struct ui_file *EchoFile = 0; /* used for debugging */ */ -/* OBSOLETE int QuietMode = 0; /* used for debugging */ */ -/* OBSOLETE */ -/* OBSOLETE #ifdef NO_HIF_SUPPORT */ -/* OBSOLETE service_HIF (union msg_t *msg) */ -/* OBSOLETE { */ -/* OBSOLETE return (0); /* Emulate a failure */ */ -/* OBSOLETE } */ -/* OBSOLETE #endif */ -/* OBSOLETE */ -/* OBSOLETE /* Target_ops vector. Not static because there does not seem to be */ -/* OBSOLETE any portable way to do a forward declaration of a static variable. */ -/* OBSOLETE The RS/6000 doesn't like "extern" followed by "static"; SunOS */ -/* OBSOLETE /bin/cc doesn't like "static" twice. */ */ -/* OBSOLETE */ -/* OBSOLETE struct target_ops udi_ops; */ -/* OBSOLETE */ -/* OBSOLETE static void */ -/* OBSOLETE init_udi_ops (void) */ -/* OBSOLETE { */ -/* OBSOLETE udi_ops.to_shortname = "udi"; */ -/* OBSOLETE udi_ops.to_longname = "Remote UDI connected TIP"; */ -/* OBSOLETE udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\ */ -/* OBSOLETE Arguments are\n\ */ -/* OBSOLETE `configuration-id AF_INET hostname port-number'\n\ */ -/* OBSOLETE To connect via the network, where hostname and port-number specify the\n\ */ -/* OBSOLETE host and port where you can connect via UDI.\n\ */ -/* OBSOLETE configuration-id is unused.\n\ */ -/* OBSOLETE \n\ */ -/* OBSOLETE `configuration-id AF_UNIX socket-name tip-program'\n\ */ -/* OBSOLETE To connect using a local connection to the \"tip.exe\" program which is\n\ */ -/* OBSOLETE supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\ */ -/* OBSOLETE tip program must already be started; connect to it using that socket.\n\ */ -/* OBSOLETE If not, start up tip-program, which should be the name of the tip\n\ */ -/* OBSOLETE program. If appropriate, the PATH environment variable is searched.\n\ */ -/* OBSOLETE configuration-id is unused.\n\ */ -/* OBSOLETE \n\ */ -/* OBSOLETE `configuration-id'\n\ */ -/* OBSOLETE Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\ */ -/* OBSOLETE are files containing lines in the above formats. configuration-id is\n\ */ -/* OBSOLETE used to pick which line of the file to use."; */ -/* OBSOLETE udi_ops.to_open = udi_open; */ -/* OBSOLETE udi_ops.to_close = udi_close; */ -/* OBSOLETE udi_ops.to_attach = udi_attach; */ -/* OBSOLETE udi_ops.to_detach = udi_detach; */ -/* OBSOLETE udi_ops.to_resume = udi_resume; */ -/* OBSOLETE udi_ops.to_wait = udi_wait; */ -/* OBSOLETE udi_ops.to_fetch_registers = udi_fetch_registers; */ -/* OBSOLETE udi_ops.to_store_registers = udi_store_registers; */ -/* OBSOLETE udi_ops.to_prepare_to_store = udi_prepare_to_store; */ -/* OBSOLETE udi_ops.to_xfer_memory = udi_xfer_inferior_memory; */ -/* OBSOLETE udi_ops.to_files_info = udi_files_info; */ -/* OBSOLETE udi_ops.to_insert_breakpoint = udi_insert_breakpoint; */ -/* OBSOLETE udi_ops.to_remove_breakpoint = udi_remove_breakpoint; */ -/* OBSOLETE udi_ops.to_terminal_init = 0; */ -/* OBSOLETE udi_ops.to_terminal_inferior = 0; */ -/* OBSOLETE udi_ops.to_terminal_ours_for_output = 0; */ -/* OBSOLETE udi_ops.to_terminal_ours = 0; */ -/* OBSOLETE udi_ops.to_terminal_info = 0; */ -/* OBSOLETE udi_ops.to_kill = udi_kill; */ -/* OBSOLETE udi_ops.to_load = udi_load; */ -/* OBSOLETE udi_ops.to_lookup_symbol = 0; */ -/* OBSOLETE udi_ops.to_create_inferior = udi_create_inferior; */ -/* OBSOLETE udi_ops.to_mourn_inferior = udi_mourn; */ -/* OBSOLETE udi_ops.to_can_run = 0; */ -/* OBSOLETE udi_ops.to_notice_signals = 0; */ -/* OBSOLETE udi_ops.to_thread_alive = 0; */ -/* OBSOLETE udi_ops.to_stop = 0; */ -/* OBSOLETE udi_ops.to_stratum = process_stratum; */ -/* OBSOLETE udi_ops.DONT_USE = 0; */ -/* OBSOLETE udi_ops.to_has_all_memory = 1; */ -/* OBSOLETE udi_ops.to_has_memory = 1; */ -/* OBSOLETE udi_ops.to_has_stack = 1; */ -/* OBSOLETE udi_ops.to_has_registers = 1; */ -/* OBSOLETE udi_ops.to_has_execution = 1; */ -/* OBSOLETE udi_ops.to_sections = 0; */ -/* OBSOLETE udi_ops.to_sections_end = 0; */ -/* OBSOLETE udi_ops.to_magic = OPS_MAGIC; */ -/* OBSOLETE }; */ -/* OBSOLETE */ -/* OBSOLETE void */ -/* OBSOLETE _initialize_remote_udi (void) */ -/* OBSOLETE { */ -/* OBSOLETE init_udi_ops (); */ -/* OBSOLETE add_target (&udi_ops); */ -/* OBSOLETE } */ diff --git a/contrib/gdb/gdb/remote-vx.c b/contrib/gdb/gdb/remote-vx.c deleted file mode 100644 index 5ec4df42fd7..00000000000 --- a/contrib/gdb/gdb/remote-vx.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* Memory-access and commands for remote VxWorks processes, for GDB. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, - 2000, 2001, 2002 Free Software Foundation, Inc. - - Contributed by Wind River Systems and Cygnus Support. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "command.h" -#include "symtab.h" -#include "complaints.h" -#include "gdbcmd.h" -#include "bfd.h" /* Required by objfiles.h. */ -#include "symfile.h" -#include "objfiles.h" -#include "gdb-stabs.h" -#include "regcache.h" - -#include "gdb_string.h" -#include -#include -#include -#include -#include -#define malloc bogon_malloc /* Sun claims "char *malloc()" not void * */ -#define free bogon_free /* Sun claims "int free()" not void */ -#define realloc bogon_realloc /* Sun claims "char *realloc()", not void * */ -#include -#undef malloc -#undef free -#undef realloc -#include /* UTek's doesn't #incl this */ -#include -#include "vx-share/ptrace.h" -#include "vx-share/xdr_ptrace.h" -#include "vx-share/xdr_ld.h" -#include "vx-share/xdr_rdb.h" -#include "vx-share/dbgRpcLib.h" - -#include - -/* Maximum number of bytes to transfer in a single - PTRACE_{READ,WRITE}DATA request. */ -#define VX_MEMXFER_MAX 4096 - -extern void vx_read_register (); -extern void vx_write_register (); -extern void symbol_file_command (); -extern int stop_soon_quietly; /* for wait_for_inferior */ - -static int net_step (); -static int net_ptrace_clnt_call (); /* Forward decl */ -static enum clnt_stat net_clnt_call (); /* Forward decl */ - -/* Target ops structure for accessing memory and such over the net */ - -static struct target_ops vx_ops; - -/* Target ops structure for accessing VxWorks child processes over the net */ - -static struct target_ops vx_run_ops; - -/* Saved name of target host and called function for "info files". - Both malloc'd. */ - -static char *vx_host; -static char *vx_running; /* Called function */ - -/* Nonzero means target that is being debugged remotely has a floating - point processor. */ - -int target_has_fp; - -/* Default error message when the network is forking up. */ - -static const char rpcerr[] = "network target debugging: rpc error"; - -CLIENT *pClient; /* client used in net debugging */ -static int ptraceSock = RPC_ANYSOCK; - -enum clnt_stat net_clnt_call (); -static void parse_args (); - -static struct timeval rpcTimeout = -{10, 0}; - -static char *skip_white_space (); -static char *find_white_space (); - -/* Tell the VxWorks target system to download a file. - The load addresses of the text, data, and bss segments are - stored in *pTextAddr, *pDataAddr, and *pBssAddr (respectively). - Returns 0 for success, -1 for failure. */ - -static int -net_load (char *filename, CORE_ADDR *pTextAddr, CORE_ADDR *pDataAddr, - CORE_ADDR *pBssAddr) -{ - enum clnt_stat status; - struct ldfile ldstruct; - struct timeval load_timeout; - - memset ((char *) &ldstruct, '\0', sizeof (ldstruct)); - - /* We invoke clnt_call () here directly, instead of through - net_clnt_call (), because we need to set a large timeout value. - The load on the target side can take quite a while, easily - more than 10 seconds. The user can kill this call by typing - CTRL-C if there really is a problem with the load. - - Do not change the tv_sec value without checking -- select() imposes - a limit of 10**8 on it for no good reason that I can see... */ - - load_timeout.tv_sec = 99999999; /* A large number, effectively inf. */ - load_timeout.tv_usec = 0; - - status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile, - &ldstruct, load_timeout); - - if (status == RPC_SUCCESS) - { - if (*ldstruct.name == 0) /* load failed on VxWorks side */ - return -1; - *pTextAddr = ldstruct.txt_addr; - *pDataAddr = ldstruct.data_addr; - *pBssAddr = ldstruct.bss_addr; - return 0; - } - else - return -1; -} - -/* returns 0 if successful, errno if RPC failed or VxWorks complains. */ - -static int -net_break (int addr, u_long procnum) -{ - enum clnt_stat status; - int break_status; - Rptrace ptrace_in; /* XXX This is stupid. It doesn't need to be a ptrace - structure. How about something smaller? */ - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - break_status = 0; - - ptrace_in.addr = addr; - ptrace_in.pid = PIDGET (inferior_ptid); - - status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int, - &break_status); - - if (status != RPC_SUCCESS) - return errno; - - if (break_status == -1) - return ENOMEM; - return break_status; /* probably (FIXME) zero */ -} - -/* returns 0 if successful, errno otherwise */ - -static int -vx_insert_breakpoint (int addr) -{ - return net_break (addr, VX_BREAK_ADD); -} - -/* returns 0 if successful, errno otherwise */ - -static int -vx_remove_breakpoint (int addr) -{ - return net_break (addr, VX_BREAK_DELETE); -} - -/* Start an inferior process and sets inferior_ptid 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. - Returns process id. Errors reported with error(). - On VxWorks, we ignore exec_file. */ - -static void -vx_create_inferior (char *exec_file, char *args, char **env) -{ - enum clnt_stat status; - arg_array passArgs; - TASK_START taskStart; - - memset ((char *) &passArgs, '\0', sizeof (passArgs)); - memset ((char *) &taskStart, '\0', sizeof (taskStart)); - - /* parse arguments, put them in passArgs */ - - parse_args (args, &passArgs); - - if (passArgs.arg_array_len == 0) - error ("You must specify a function name to run, and arguments if any"); - - status = net_clnt_call (PROCESS_START, xdr_arg_array, &passArgs, - xdr_TASK_START, &taskStart); - - if ((status != RPC_SUCCESS) || (taskStart.status == -1)) - error ("Can't create process on remote target machine"); - - /* Save the name of the running function */ - vx_running = savestring (passArgs.arg_array_val[0], - strlen (passArgs.arg_array_val[0])); - - push_target (&vx_run_ops); - inferior_ptid = pid_to_ptid (taskStart.pid); - - /* We will get a trace trap after one instruction. - Insert breakpoints and continue. */ - - init_wait_for_inferior (); - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - target_terminal_init (); - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - stop_soon_quietly = 1; - wait_for_inferior (); /* Get the task spawn event */ - stop_soon_quietly = 0; - - /* insert_step_breakpoint (); FIXME, do we need this? */ - proceed (-1, TARGET_SIGNAL_DEFAULT, 0); -} - -/* Fill ARGSTRUCT in argc/argv form with the arguments from the - argument string ARGSTRING. */ - -static void -parse_args (register char *arg_string, arg_array *arg_struct) -{ - register int arg_count = 0; /* number of arguments */ - register int arg_index = 0; - register char *p0; - - memset ((char *) arg_struct, '\0', sizeof (arg_array)); - - /* first count how many arguments there are */ - - p0 = arg_string; - while (*p0 != '\0') - { - if (*(p0 = skip_white_space (p0)) == '\0') - break; - p0 = find_white_space (p0); - arg_count++; - } - - arg_struct->arg_array_len = arg_count; - arg_struct->arg_array_val = (char **) xmalloc ((arg_count + 1) - * sizeof (char *)); - - /* now copy argument strings into arg_struct. */ - - while (*(arg_string = skip_white_space (arg_string))) - { - p0 = find_white_space (arg_string); - arg_struct->arg_array_val[arg_index++] = savestring (arg_string, - p0 - arg_string); - arg_string = p0; - } - - arg_struct->arg_array_val[arg_count] = NULL; -} - -/* Advance a string pointer across whitespace and return a pointer - to the first non-white character. */ - -static char * -skip_white_space (register char *p) -{ - while (*p == ' ' || *p == '\t') - p++; - return p; -} - -/* Search for the first unquoted whitespace character in a string. - Returns a pointer to the character, or to the null terminator - if no whitespace is found. */ - -static char * -find_white_space (register char *p) -{ - register int c; - - while ((c = *p) != ' ' && c != '\t' && c) - { - if (c == '\'' || c == '"') - { - while (*++p != c && *p) - { - if (*p == '\\') - p++; - } - if (!*p) - break; - } - p++; - } - return p; -} - -/* Poll the VxWorks target system for an event related - to the debugged task. - Returns -1 if remote wait failed, task status otherwise. */ - -static int -net_wait (RDB_EVENT *pEvent) -{ - int pid; - enum clnt_stat status; - - memset ((char *) pEvent, '\0', sizeof (RDB_EVENT)); - - pid = PIDGET (inferior_ptid); - status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT, - pEvent); - - /* return (status == RPC_SUCCESS)? pEvent->status: -1; */ - if (status == RPC_SUCCESS) - return ((pEvent->status) ? 1 : 0); - else if (status == RPC_TIMEDOUT) - return (1); - else - return (-1); -} - -/* Suspend the remote task. - Returns -1 if suspend fails on target system, 0 otherwise. */ - -static int -net_quit (void) -{ - int pid; - int quit_status; - enum clnt_stat status; - - quit_status = 0; - - /* don't let rdbTask suspend itself by passing a pid of 0 */ - - if ((pid = PIDGET (inferior_ptid)) == 0) - return -1; - - status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int, - &quit_status); - - return (status == RPC_SUCCESS) ? quit_status : -1; -} - -/* Read a register or registers from the remote system. */ - -void -net_read_registers (char *reg_buf, int len, u_long procnum) -{ - int status; - Rptrace ptrace_in; - Ptrace_return ptrace_out; - C_bytes out_data; - char message[100]; - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); - - /* Initialize RPC input argument structure. */ - - ptrace_in.pid = PIDGET (inferior_ptid); - ptrace_in.info.ttype = NOINFO; - - /* Initialize RPC return value structure. */ - - out_data.bytes = reg_buf; - out_data.len = len; - ptrace_out.info.more_data = (caddr_t) & out_data; - - /* Call RPC; take an error exit if appropriate. */ - - status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out); - if (status) - error (rpcerr); - if (ptrace_out.status == -1) - { - errno = ptrace_out.errno_num; - sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS) - ? "general-purpose" - : "floating-point"); - perror_with_name (message); - } -} - -/* Write register values to a VxWorks target. REG_BUF points to a buffer - containing the raw register values, LEN is the length of REG_BUF in - bytes, and PROCNUM is the RPC procedure number (PTRACE_SETREGS or - PTRACE_SETFPREGS). An error exit is taken if the RPC call fails or - if an error status is returned by the remote debug server. This is - a utility routine used by vx_write_register (). */ - -void -net_write_registers (char *reg_buf, int len, u_long procnum) -{ - int status; - Rptrace ptrace_in; - Ptrace_return ptrace_out; - C_bytes in_data; - char message[100]; - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); - - /* Initialize RPC input argument structure. */ - - in_data.bytes = reg_buf; - in_data.len = len; - - ptrace_in.pid = PIDGET (inferior_ptid); - ptrace_in.info.ttype = DATA; - ptrace_in.info.more_data = (caddr_t) & in_data; - - /* Call RPC; take an error exit if appropriate. */ - - status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out); - if (status) - error (rpcerr); - if (ptrace_out.status == -1) - { - errno = ptrace_out.errno_num; - sprintf (message, "writing %s registers", (procnum == PTRACE_SETREGS) - ? "general-purpose" - : "floating-point"); - perror_with_name (message); - } -} - -/* Prepare to store registers. Since we will store all of them, - read out their current values now. */ - -static void -vx_prepare_to_store (void) -{ - /* Fetch all registers, if any of them are not yet fetched. */ - read_register_bytes (0, NULL, REGISTER_BYTES); -} - -/* Copy LEN bytes to or from remote inferior's memory starting at MEMADDR - to debugger memory starting at MYADDR. WRITE is true if writing to the - inferior. TARGET is unused. - Result is the number of bytes written or read (zero if error). The - protocol allows us to return a negative count, indicating that we can't - handle the current address but can handle one N bytes further, but - vxworks doesn't give us that information. */ - -static int -vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, struct target_ops *target) -{ - int status; - Rptrace ptrace_in; - Ptrace_return ptrace_out; - C_bytes data; - enum ptracereq request; - int nleft, nxfer; - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); - - ptrace_in.pid = PIDGET (inferior_ptid); /* XXX pid unnecessary for READDATA */ - ptrace_in.addr = (int) memaddr; /* Where from */ - ptrace_in.data = len; /* How many bytes */ - - if (write) - { - ptrace_in.info.ttype = DATA; - ptrace_in.info.more_data = (caddr_t) & data; - - data.bytes = (caddr_t) myaddr; /* Where from */ - data.len = len; /* How many bytes (again, for XDR) */ - request = PTRACE_WRITEDATA; - } - else - { - ptrace_out.info.more_data = (caddr_t) & data; - request = PTRACE_READDATA; - } - /* Loop until the entire request has been satisfied, transferring - at most VX_MEMXFER_MAX bytes per iteration. Break from the loop - if an error status is returned by the remote debug server. */ - - nleft = len; - status = 0; - - while (nleft > 0 && status == 0) - { - nxfer = min (nleft, VX_MEMXFER_MAX); - - ptrace_in.addr = (int) memaddr; - ptrace_in.data = nxfer; - data.bytes = (caddr_t) myaddr; - data.len = nxfer; - - /* Request a block from the remote debug server; if RPC fails, - report an error and return to debugger command level. */ - - if (net_ptrace_clnt_call (request, &ptrace_in, &ptrace_out)) - error (rpcerr); - - status = ptrace_out.status; - if (status == 0) - { - memaddr += nxfer; - myaddr += nxfer; - nleft -= nxfer; - } - else - { - /* A target-side error has ocurred. Set errno to the error - code chosen by the target so that a later perror () will - say something meaningful. */ - - errno = ptrace_out.errno_num; - } - } - - /* Return the number of bytes transferred. */ - - return (len - nleft); -} - -static void -vx_files_info (void) -{ - printf_unfiltered ("\tAttached to host `%s'", vx_host); - printf_unfiltered (", which has %sfloating point", target_has_fp ? "" : "no "); - printf_unfiltered (".\n"); -} - -static void -vx_run_files_info (void) -{ - printf_unfiltered ("\tRunning %s VxWorks process %s", - vx_running ? "child" : "attached", - local_hex_string (PIDGET (inferior_ptid))); - if (vx_running) - printf_unfiltered (", function `%s'", vx_running); - printf_unfiltered (".\n"); -} - -static void -vx_resume (ptid_t ptid, int step, enum target_signal siggnal) -{ - int status; - Rptrace ptrace_in; - Ptrace_return ptrace_out; - CORE_ADDR cont_addr; - - if (ptid_equal (ptid, minus_one_ptid)) - ptid = inferior_ptid; - - if (siggnal != 0 && siggnal != stop_signal) - error ("Cannot send signals to VxWorks processes"); - - /* Set CONT_ADDR to the address at which we are continuing, - or to 1 if we are continuing from where the program stopped. - This conforms to traditional ptrace () usage, but at the same - time has special meaning for the VxWorks remote debug server. - If the address is not 1, the server knows that the target - program is jumping to a new address, which requires special - handling if there is a breakpoint at the new address. */ - - cont_addr = read_register (PC_REGNUM); - if (cont_addr == stop_pc) - cont_addr = 1; - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); - - ptrace_in.pid = PIDGET (ptid); - ptrace_in.addr = cont_addr; /* Target side insists on this, or it panics. */ - - if (step) - status = net_step (); - else - status = net_ptrace_clnt_call (PTRACE_CONT, &ptrace_in, &ptrace_out); - - if (status) - error (rpcerr); - if (ptrace_out.status == -1) - { - errno = ptrace_out.errno_num; - perror_with_name ("Resuming remote process"); - } -} - -static void -vx_mourn_inferior (void) -{ - pop_target (); /* Pop back to no-child state */ - generic_mourn_inferior (); -} - - -static void vx_add_symbols (char *, int, CORE_ADDR, CORE_ADDR, CORE_ADDR); - -struct find_sect_args - { - CORE_ADDR text_start; - CORE_ADDR data_start; - CORE_ADDR bss_start; - }; - -static void find_sect (bfd *, asection *, void *); - -static void -find_sect (bfd *abfd, asection *sect, PTR obj) -{ - struct find_sect_args *args = (struct find_sect_args *) obj; - - if (bfd_get_section_flags (abfd, sect) & (SEC_CODE & SEC_READONLY)) - args->text_start = bfd_get_section_vma (abfd, sect); - else if (bfd_get_section_flags (abfd, sect) & SEC_ALLOC) - { - if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) - { - /* Exclude .ctor and .dtor sections which have SEC_CODE set but not - SEC_DATA. */ - if (bfd_get_section_flags (abfd, sect) & SEC_DATA) - args->data_start = bfd_get_section_vma (abfd, sect); - } - else - args->bss_start = bfd_get_section_vma (abfd, sect); - } -} - -static void -vx_add_symbols (char *name, int from_tty, CORE_ADDR text_addr, - CORE_ADDR data_addr, CORE_ADDR bss_addr) -{ - struct section_offsets *offs; - struct objfile *objfile; - struct find_sect_args ss; - - /* It might be nice to suppress the breakpoint_re_set which happens here - because we are going to do one again after the objfile_relocate. */ - objfile = symbol_file_add (name, from_tty, NULL, 0, 0); - - /* This is a (slightly cheesy) way of superceding the old symbols. A less - cheesy way would be to find the objfile with the same name and - free_objfile it. */ - objfile_to_front (objfile); - - offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS); - memcpy (offs, objfile->section_offsets, SIZEOF_SECTION_OFFSETS); - - ss.text_start = 0; - ss.data_start = 0; - ss.bss_start = 0; - bfd_map_over_sections (objfile->obfd, find_sect, &ss); - - /* Both COFF and b.out frontends use these SECT_OFF_* values. */ - offs->offsets[SECT_OFF_TEXT (objfile)] = text_addr - ss.text_start; - offs->offsets[SECT_OFF_DATA (objfile)] = data_addr - ss.data_start; - offs->offsets[SECT_OFF_BSS (objfile)] = bss_addr - ss.bss_start; - objfile_relocate (objfile, offs); -} - -/* This function allows the addition of incrementally linked object files. */ - -static void -vx_load_command (char *arg_string, int from_tty) -{ - CORE_ADDR text_addr; - CORE_ADDR data_addr; - CORE_ADDR bss_addr; - - if (arg_string == 0) - error ("The load command takes a file name"); - - arg_string = tilde_expand (arg_string); - make_cleanup (xfree, arg_string); - - dont_repeat (); - - /* Refuse to load the module if a debugged task is running. Doing so - can have a number of unpleasant consequences to the running task. */ - - if (PIDGET (inferior_ptid) != 0 && target_has_execution) - { - if (query ("You may not load a module while the target task is running.\n\ -Kill the target task? ")) - target_kill (); - else - error ("Load canceled."); - } - - QUIT; - immediate_quit++; - if (net_load (arg_string, &text_addr, &data_addr, &bss_addr) == -1) - error ("Load failed on target machine"); - immediate_quit--; - - vx_add_symbols (arg_string, from_tty, text_addr, data_addr, bss_addr); - - /* Getting new symbols may change our opinion about what is - frameless. */ - reinit_frame_cache (); -} - -/* Single step the target program at the source or machine level. - Takes an error exit if rpc fails. - Returns -1 if remote single-step operation fails, else 0. */ - -static int -net_step (void) -{ - enum clnt_stat status; - int step_status; - SOURCE_STEP source_step; - - source_step.taskId = PIDGET (inferior_ptid); - - if (step_range_end) - { - source_step.startAddr = step_range_start; - source_step.endAddr = step_range_end; - } - else - { - source_step.startAddr = 0; - source_step.endAddr = 0; - } - - status = net_clnt_call (VX_SOURCE_STEP, xdr_SOURCE_STEP, &source_step, - xdr_int, &step_status); - - if (status == RPC_SUCCESS) - return step_status; - else - error (rpcerr); -} - -/* Emulate ptrace using RPC calls to the VxWorks target system. - Returns nonzero (-1) if RPC status to VxWorks is bad, 0 otherwise. */ - -static int -net_ptrace_clnt_call (enum ptracereq request, Rptrace *pPtraceIn, - Ptrace_return *pPtraceOut) -{ - enum clnt_stat status; - - status = net_clnt_call (request, xdr_rptrace, pPtraceIn, xdr_ptrace_return, - pPtraceOut); - - if (status != RPC_SUCCESS) - return -1; - - return 0; -} - -/* Query the target for the name of the file from which VxWorks was - booted. pBootFile is the address of a pointer to the buffer to - receive the file name; if the pointer pointed to by pBootFile is - NULL, memory for the buffer will be allocated by XDR. - Returns -1 if rpc failed, 0 otherwise. */ - -static int -net_get_boot_file (char **pBootFile) -{ - enum clnt_stat status; - - status = net_clnt_call (VX_BOOT_FILE_INQ, xdr_void, (char *) 0, - xdr_wrapstring, pBootFile); - return (status == RPC_SUCCESS) ? 0 : -1; -} - -/* Fetch a list of loaded object modules from the VxWorks target - and store in PLOADTABLE. - Returns -1 if rpc failed, 0 otherwise - There's no way to check if the returned loadTable is correct. - VxWorks doesn't check it. */ - -static int -net_get_symbols (ldtabl *pLoadTable) -{ - enum clnt_stat status; - - memset ((char *) pLoadTable, '\0', sizeof (struct ldtabl)); - - status = net_clnt_call (VX_STATE_INQ, xdr_void, 0, xdr_ldtabl, pLoadTable); - return (status == RPC_SUCCESS) ? 0 : -1; -} - -/* Look up a symbol in the VxWorks target's symbol table. - Returns status of symbol read on target side (0=success, -1=fail) - Returns -1 and complain()s if rpc fails. */ - -struct complaint cant_contact_target = -{"Lost contact with VxWorks target", 0, 0}; - -static int -vx_lookup_symbol (char *name, /* symbol name */ - CORE_ADDR *pAddr) -{ - enum clnt_stat status; - SYMBOL_ADDR symbolAddr; - - *pAddr = 0; - memset ((char *) &symbolAddr, '\0', sizeof (symbolAddr)); - - status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name, - xdr_SYMBOL_ADDR, &symbolAddr); - if (status != RPC_SUCCESS) - { - complain (&cant_contact_target); - return -1; - } - - *pAddr = symbolAddr.addr; - return symbolAddr.status; -} - -/* Check to see if the VxWorks target has a floating point coprocessor. - Returns 1 if target has floating point processor, 0 otherwise. - Calls error() if rpc fails. */ - -static int -net_check_for_fp (void) -{ - enum clnt_stat status; - bool_t fp = 0; /* true if fp processor is present on target board */ - - status = net_clnt_call (VX_FP_INQUIRE, xdr_void, 0, xdr_bool, &fp); - if (status != RPC_SUCCESS) - error (rpcerr); - - return (int) fp; -} - -/* Establish an RPC connection with the VxWorks target system. - Calls error () if unable to establish connection. */ - -static void -net_connect (char *host) -{ - struct sockaddr_in destAddr; - struct hostent *destHost; - unsigned long addr; - - /* Get the internet address for the given host. Allow a numeric - IP address or a hostname. */ - - addr = inet_addr (host); - if (addr == -1) - { - destHost = (struct hostent *) gethostbyname (host); - if (destHost == NULL) - /* FIXME: Probably should include hostname here in quotes. - For example if the user types "target vxworks vx960 " it should - say "Invalid host `vx960 '." not just "Invalid hostname". */ - error ("Invalid hostname. Couldn't find remote host address."); - addr = *(unsigned long *) destHost->h_addr; - } - - memset (&destAddr, '\0', sizeof (destAddr)); - - destAddr.sin_addr.s_addr = addr; - destAddr.sin_family = AF_INET; - destAddr.sin_port = 0; /* set to actual port that remote - ptrace is listening on. */ - - /* Create a tcp client transport on which to issue - calls to the remote ptrace server. */ - - ptraceSock = RPC_ANYSOCK; - pClient = clnttcp_create (&destAddr, RDBPROG, RDBVERS, &ptraceSock, 0, 0); - /* FIXME, here is where we deal with different version numbers of the - proto */ - - if (pClient == NULL) - { - clnt_pcreateerror ("\tnet_connect"); - error ("Couldn't connect to remote target."); - } -} - -/* Sleep for the specified number of milliseconds - * (assumed to be less than 1000). - * If select () is interrupted, returns immediately; - * takes an error exit if select () fails for some other reason. - */ - -static void -sleep_ms (long ms) -{ - struct timeval select_timeout; - int status; - - select_timeout.tv_sec = 0; - select_timeout.tv_usec = ms * 1000; - - status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, - &select_timeout); - - if (status < 0 && errno != EINTR) - perror_with_name ("select"); -} - -static ptid_t -vx_wait (ptid_t ptid_to_wait_for, struct target_waitstatus *status) -{ - register int pid; - RDB_EVENT rdbEvent; - int quit_failed; - - do - { - /* If CTRL-C is hit during this loop, - suspend the inferior process. */ - - quit_failed = 0; - if (quit_flag) - { - quit_failed = (net_quit () == -1); - quit_flag = 0; - } - - /* If a net_quit () or net_wait () call has failed, - allow the user to break the connection with the target. - We can't simply error () out of this loop, since the - data structures representing the state of the inferior - are in an inconsistent state. */ - - if (quit_failed || net_wait (&rdbEvent) == -1) - { - terminal_ours (); - if (query ("Can't %s. Disconnect from target system? ", - (quit_failed) ? "suspend remote task" - : "get status of remote task")) - { - target_mourn_inferior (); - error ("Use the \"target\" command to reconnect."); - } - else - { - terminal_inferior (); - continue; - } - } - - pid = rdbEvent.taskId; - if (pid == 0) - { - sleep_ms (200); /* FIXME Don't kill the network too badly */ - } - else if (pid != PIDGET (inferior_ptid)) - internal_error (__FILE__, __LINE__, - "Bad pid for debugged task: %s\n", - local_hex_string ((unsigned long) pid)); - } - while (pid == 0); - - /* The mostly likely kind. */ - status->kind = TARGET_WAITKIND_STOPPED; - - switch (rdbEvent.eventType) - { - case EVENT_EXIT: - status->kind = TARGET_WAITKIND_EXITED; - /* FIXME is it possible to distinguish between a - normal vs abnormal exit in VxWorks? */ - status->value.integer = 0; - break; - - case EVENT_START: - /* Task was just started. */ - status->value.sig = TARGET_SIGNAL_TRAP; - break; - - case EVENT_STOP: - status->value.sig = TARGET_SIGNAL_TRAP; - /* XXX was it stopped by a signal? act accordingly */ - break; - - case EVENT_BREAK: /* Breakpoint was hit. */ - status->value.sig = TARGET_SIGNAL_TRAP; - break; - - case EVENT_SUSPEND: /* Task was suspended, probably by ^C. */ - status->value.sig = TARGET_SIGNAL_INT; - break; - - case EVENT_BUS_ERR: /* Task made evil nasty reference. */ - status->value.sig = TARGET_SIGNAL_BUS; - break; - - case EVENT_ZERO_DIV: /* Division by zero */ - status->value.sig = TARGET_SIGNAL_FPE; - break; - - case EVENT_SIGNAL: -#ifdef I80960 - status->value.sig = i960_fault_to_signal (rdbEvent.sigType); -#else - /* Back in the old days, before enum target_signal, this code used - to add NSIG to the signal number and claim that PRINT_RANDOM_SIGNAL - would take care of it. But PRINT_RANDOM_SIGNAL has never been - defined except on the i960, so I don't really know what we are - supposed to do on other architectures. */ - status->value.sig = TARGET_SIGNAL_UNKNOWN; -#endif - break; - } /* switch */ - return pid_to_ptid (pid); -} - -static int -symbol_stub (char *arg) -{ - symbol_file_add_main (arg, 0); - return 1; -} - -static int -add_symbol_stub (char *arg) -{ - struct ldfile *pLoadFile = (struct ldfile *) arg; - - printf_unfiltered ("\t%s: ", pLoadFile->name); - vx_add_symbols (pLoadFile->name, 0, pLoadFile->txt_addr, - pLoadFile->data_addr, pLoadFile->bss_addr); - printf_unfiltered ("ok\n"); - return 1; -} -/* Target command for VxWorks target systems. - - Used in vxgdb. Takes the name of a remote target machine - running vxWorks and connects to it to initialize remote network - debugging. */ - -static void -vx_open (char *args, int from_tty) -{ - extern int close (); - char *bootFile; - extern char *source_path; - struct ldtabl loadTable; - struct ldfile *pLoadFile; - int i; - extern CLIENT *pClient; - int symbols_added = 0; - - if (!args) - error_no_arg ("target machine name"); - - target_preopen (from_tty); - - unpush_target (&vx_ops); - printf_unfiltered ("Attaching remote machine across net...\n"); - gdb_flush (gdb_stdout); - - /* Allow the user to kill the connect attempt by typing ^C. - Wait until the call to target_has_fp () completes before - disallowing an immediate quit, since even if net_connect () - is successful, the remote debug server might be hung. */ - - immediate_quit++; - - net_connect (args); - target_has_fp = net_check_for_fp (); - printf_filtered ("Connected to %s.\n", args); - - immediate_quit--; - - push_target (&vx_ops); - - /* Save a copy of the target host's name. */ - vx_host = savestring (args, strlen (args)); - - /* Find out the name of the file from which the target was booted - and load its symbol table. */ - - printf_filtered ("Looking in Unix path for all loaded modules:\n"); - bootFile = NULL; - if (!net_get_boot_file (&bootFile)) - { - if (*bootFile) - { - printf_filtered ("\t%s: ", bootFile); - /* This assumes that the kernel is never relocated. Hope that is an - accurate assumption. */ - if (catch_errors - (symbol_stub, - bootFile, - "Error while reading symbols from boot file:\n", - RETURN_MASK_ALL)) - puts_filtered ("ok\n"); - } - else if (from_tty) - printf_unfiltered ("VxWorks kernel symbols not loaded.\n"); - } - else - error ("Can't retrieve boot file name from target machine."); - - clnt_freeres (pClient, xdr_wrapstring, &bootFile); - - if (net_get_symbols (&loadTable) != 0) - error ("Can't read loaded modules from target machine"); - - i = 0 - 1; - while (++i < loadTable.tbl_size) - { - QUIT; /* FIXME, avoids clnt_freeres below: mem leak */ - pLoadFile = &loadTable.tbl_ent[i]; -#ifdef WRS_ORIG - { - register int desc; - struct cleanup *old_chain; - char *fullname = NULL; - - desc = openp (source_path, 0, pLoadFile->name, O_RDONLY, 0, &fullname); - if (desc < 0) - perror_with_name (pLoadFile->name); - old_chain = make_cleanup (close, desc); - add_file_at_addr (fullname, desc, pLoadFile->txt_addr, pLoadFile->data_addr, - pLoadFile->bss_addr); - do_cleanups (old_chain); - } -#else - /* FIXME: Is there something better to search than the PATH? (probably - not the source path, since source might be in different directories - than objects. */ - - if (catch_errors (add_symbol_stub, (char *) pLoadFile, (char *) 0, - RETURN_MASK_ALL)) - symbols_added = 1; -#endif - } - printf_filtered ("Done.\n"); - - clnt_freeres (pClient, xdr_ldtabl, &loadTable); - - /* Getting new symbols may change our opinion about what is - frameless. */ - if (symbols_added) - reinit_frame_cache (); -} - -/* Takes a task started up outside of gdb and ``attaches'' to it. - This stops it cold in its tracks and allows us to start tracing it. */ - -static void -vx_attach (char *args, int from_tty) -{ - unsigned long pid; - char *cptr = 0; - Rptrace ptrace_in; - Ptrace_return ptrace_out; - int status; - - if (!args) - error_no_arg ("process-id to attach"); - - pid = strtoul (args, &cptr, 0); - if ((cptr == args) || (*cptr != '\0')) - error ("Invalid process-id -- give a single number in decimal or 0xhex"); - - if (from_tty) - printf_unfiltered ("Attaching pid %s.\n", - local_hex_string ((unsigned long) pid)); - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); - ptrace_in.pid = pid; - - status = net_ptrace_clnt_call (PTRACE_ATTACH, &ptrace_in, &ptrace_out); - if (status == -1) - error (rpcerr); - if (ptrace_out.status == -1) - { - errno = ptrace_out.errno_num; - perror_with_name ("Attaching remote process"); - } - - /* It worked... */ - - inferior_ptid = pid_to_ptid (pid); - push_target (&vx_run_ops); - - if (vx_running) - xfree (vx_running); - vx_running = 0; -} - -/* detach_command -- - takes a program previously attached to and detaches it. - The program resumes execution and will no longer stop - on signals, etc. We better not have left any breakpoints - in the program or it'll die when it hits one. For this - to work, it may be necessary for the process to have been - previously attached. It *might* work if the program was - started via the normal ptrace (PTRACE_TRACEME). */ - -static void -vx_detach (char *args, int from_tty) -{ - Rptrace ptrace_in; - Ptrace_return ptrace_out; - int signal = 0; - int status; - - if (args) - error ("Argument given to VxWorks \"detach\"."); - - if (from_tty) - printf_unfiltered ("Detaching pid %s.\n", - local_hex_string ( - (unsigned long) PIDGET (inferior_ptid))); - - if (args) /* FIXME, should be possible to leave suspended */ - signal = atoi (args); - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); - ptrace_in.pid = PIDGET (inferior_ptid); - - status = net_ptrace_clnt_call (PTRACE_DETACH, &ptrace_in, &ptrace_out); - if (status == -1) - error (rpcerr); - if (ptrace_out.status == -1) - { - errno = ptrace_out.errno_num; - perror_with_name ("Detaching VxWorks process"); - } - - inferior_ptid = null_ptid; - pop_target (); /* go back to non-executing VxWorks connection */ -} - -/* vx_kill -- takes a running task and wipes it out. */ - -static void -vx_kill (void) -{ - Rptrace ptrace_in; - Ptrace_return ptrace_out; - int status; - - printf_unfiltered ("Killing pid %s.\n", local_hex_string ((unsigned long) PIDGET (inferior_ptid))); - - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); - ptrace_in.pid = PIDGET (inferior_ptid); - - status = net_ptrace_clnt_call (PTRACE_KILL, &ptrace_in, &ptrace_out); - if (status == -1) - warning (rpcerr); - else if (ptrace_out.status == -1) - { - errno = ptrace_out.errno_num; - perror_with_name ("Killing VxWorks process"); - } - - /* If it gives good status, the process is *gone*, no events remain. - If the kill failed, assume the process is gone anyhow. */ - inferior_ptid = null_ptid; - pop_target (); /* go back to non-executing VxWorks connection */ -} - -/* Clean up from the VxWorks process target as it goes away. */ - -static void -vx_proc_close (int quitting) -{ - inferior_ptid = null_ptid; /* No longer have a process. */ - if (vx_running) - xfree (vx_running); - vx_running = 0; -} - -/* Make an RPC call to the VxWorks target. - Returns RPC status. */ - -static enum clnt_stat -net_clnt_call (enum ptracereq procNum, xdrproc_t inProc, char *in, - xdrproc_t outProc, char *out) -{ - enum clnt_stat status; - - status = clnt_call (pClient, procNum, inProc, in, outProc, out, rpcTimeout); - - if (status != RPC_SUCCESS) - clnt_perrno (status); - - return status; -} - -/* Clean up before losing control. */ - -static void -vx_close (int quitting) -{ - if (pClient) - clnt_destroy (pClient); /* The net connection */ - pClient = 0; - - if (vx_host) - xfree (vx_host); /* The hostname */ - vx_host = 0; -} - -/* A vxprocess target should be started via "run" not "target". */ -/*ARGSUSED */ -static void -vx_proc_open (char *name, int from_tty) -{ - error ("Use the \"run\" command to start a VxWorks process."); -} - -static void -init_vx_ops (void) -{ - vx_ops.to_shortname = "vxworks"; - vx_ops.to_longname = "VxWorks target memory via RPC over TCP/IP"; - vx_ops.to_doc = "Use VxWorks target memory. \n\ -Specify the name of the machine to connect to."; - vx_ops.to_open = vx_open; - vx_ops.to_close = vx_close; - vx_ops.to_attach = vx_attach; - vx_ops.to_xfer_memory = vx_xfer_memory; - vx_ops.to_files_info = vx_files_info; - vx_ops.to_load = vx_load_command; - vx_ops.to_lookup_symbol = vx_lookup_symbol; - vx_ops.to_create_inferior = vx_create_inferior; - vx_ops.to_stratum = core_stratum; - vx_ops.to_has_all_memory = 1; - vx_ops.to_has_memory = 1; - vx_ops.to_magic = OPS_MAGIC; /* Always the last thing */ -}; - -static void -init_vx_run_ops (void) -{ - vx_run_ops.to_shortname = "vxprocess"; - vx_run_ops.to_longname = "VxWorks process"; - vx_run_ops.to_doc = "VxWorks process; started by the \"run\" command."; - vx_run_ops.to_open = vx_proc_open; - vx_run_ops.to_close = vx_proc_close; - vx_run_ops.to_detach = vx_detach; - vx_run_ops.to_resume = vx_resume; - vx_run_ops.to_wait = vx_wait; - vx_run_ops.to_fetch_registers = vx_read_register; - vx_run_ops.to_store_registers = vx_write_register; - vx_run_ops.to_prepare_to_store = vx_prepare_to_store; - vx_run_ops.to_xfer_memory = vx_xfer_memory; - vx_run_ops.to_files_info = vx_run_files_info; - vx_run_ops.to_insert_breakpoint = vx_insert_breakpoint; - vx_run_ops.to_remove_breakpoint = vx_remove_breakpoint; - vx_run_ops.to_kill = vx_kill; - vx_run_ops.to_load = vx_load_command; - vx_run_ops.to_lookup_symbol = vx_lookup_symbol; - vx_run_ops.to_mourn_inferior = vx_mourn_inferior; - vx_run_ops.to_stratum = process_stratum; - vx_run_ops.to_has_memory = 1; - vx_run_ops.to_has_stack = 1; - vx_run_ops.to_has_registers = 1; - vx_run_ops.to_has_execution = 1; - vx_run_ops.to_magic = OPS_MAGIC; -} - -void -_initialize_vx (void) -{ - init_vx_ops (); - add_target (&vx_ops); - init_vx_run_ops (); - add_target (&vx_run_ops); - - add_show_from_set - (add_set_cmd ("vxworks-timeout", class_support, var_uinteger, - (char *) &rpcTimeout.tv_sec, - "Set seconds to wait for rpc calls to return.\n\ -Set the number of seconds to wait for rpc calls to return.", &setlist), - &showlist); -} diff --git a/contrib/gdb/gdb/remote-vx29k.c b/contrib/gdb/gdb/remote-vx29k.c deleted file mode 100644 index 798cd088396..00000000000 --- a/contrib/gdb/gdb/remote-vx29k.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Am29k-dependent portions of the RPC protocol - - Contributed by Wind River Systems. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include "defs.h" - -#include "vx-share/regPacket.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "command.h" -#include "symtab.h" -#include "symfile.h" /* for struct complaint */ -#include "regcache.h" - -#include "gdb_string.h" -#include -#include -#include -#include -#include - -#ifdef _AIX /* IBM claims "void *malloc()" not char * */ -#define malloc bogon_malloc -#endif - -#include -#include /* UTek's doesn't #incl this */ -#include -#include "vx-share/ptrace.h" -#include "vx-share/xdr_ptrace.h" -#include "vx-share/xdr_ld.h" -#include "vx-share/xdr_rdb.h" -#include "vx-share/dbgRpcLib.h" - -/* get rid of value.h if possible */ -#include -#include - -/* Flag set if target has fpu */ - -extern int target_has_fp; - -/* Generic register read/write routines in remote-vx.c. */ - -extern void net_read_registers (); -extern void net_write_registers (); - -/* Read a register or registers from the VxWorks target. - REGNO is the register to read, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_read_register (int regno) -{ - char am29k_greg_packet[AM29K_GREG_PLEN]; - char am29k_fpreg_packet[AM29K_FPREG_PLEN]; - - /* Get general-purpose registers. When copying values into - registers [], don't assume that a location in registers [] - is properly aligned for the target data type. */ - - net_read_registers (am29k_greg_packet, AM29K_GREG_PLEN, PTRACE_GETREGS); - - /* Now copy the register values into registers[]. - Note that this code depends on the ordering of the REGNUMs - as defined in "tm-29k.h". */ - - bcopy (&am29k_greg_packet[AM29K_R_GR96], - ®isters[REGISTER_BYTE (GR96_REGNUM)], 160 * AM29K_GREG_SIZE); - bcopy (&am29k_greg_packet[AM29K_R_VAB], - ®isters[REGISTER_BYTE (VAB_REGNUM)], 15 * AM29K_GREG_SIZE); - registers[REGISTER_BYTE (INTE_REGNUM)] = am29k_greg_packet[AM29K_R_INTE]; - bcopy (&am29k_greg_packet[AM29K_R_RSP], - ®isters[REGISTER_BYTE (GR1_REGNUM)], 5 * AM29K_GREG_SIZE); - - /* PAD For now, don't care about exop register */ - - memset (®isters[REGISTER_BYTE (EXO_REGNUM)], '\0', AM29K_GREG_SIZE); - - /* If the target has floating point registers, fetch them. - Otherwise, zero the floating point register values in - registers[] for good measure, even though we might not - need to. */ - - if (target_has_fp) - { - net_read_registers (am29k_fpreg_packet, AM29K_FPREG_PLEN, - PTRACE_GETFPREGS); - registers[REGISTER_BYTE (FPE_REGNUM)] = am29k_fpreg_packet[AM29K_R_FPE]; - registers[REGISTER_BYTE (FPS_REGNUM)] = am29k_fpreg_packet[AM29K_R_FPS]; - - /* PAD For now, don't care about registers (?) AI0 to q */ - - memset (®isters[REGISTER_BYTE (161)], '\0', 21 * AM29K_FPREG_SIZE); - } - else - { - memset (®isters[REGISTER_BYTE (FPE_REGNUM)], '\0', AM29K_FPREG_SIZE); - memset (®isters[REGISTER_BYTE (FPS_REGNUM)], '\0', AM29K_FPREG_SIZE); - - /* PAD For now, don't care about registers (?) AI0 to q */ - - memset (®isters[REGISTER_BYTE (161)], '\0', 21 * AM29K_FPREG_SIZE); - } - - /* Mark the register cache valid. */ - - registers_fetched (); -} - -/* Store a register or registers into the VxWorks target. - REGNO is the register to store, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_write_register (int regno) -{ - char am29k_greg_packet[AM29K_GREG_PLEN]; - char am29k_fpreg_packet[AM29K_FPREG_PLEN]; - - /* Store general purpose registers. When copying values from - registers [], don't assume that a location in registers [] - is properly aligned for the target data type. */ - - bcopy (®isters[REGISTER_BYTE (GR96_REGNUM)], - &am29k_greg_packet[AM29K_R_GR96], 160 * AM29K_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (VAB_REGNUM)], - &am29k_greg_packet[AM29K_R_VAB], 15 * AM29K_GREG_SIZE); - am29k_greg_packet[AM29K_R_INTE] = registers[REGISTER_BYTE (INTE_REGNUM)]; - bcopy (®isters[REGISTER_BYTE (GR1_REGNUM)], - &am29k_greg_packet[AM29K_R_RSP], 5 * AM29K_GREG_SIZE); - - net_write_registers (am29k_greg_packet, AM29K_GREG_PLEN, PTRACE_SETREGS); - - /* Store floating point registers if the target has them. */ - - if (target_has_fp) - { - am29k_fpreg_packet[AM29K_R_FPE] = registers[REGISTER_BYTE (FPE_REGNUM)]; - am29k_fpreg_packet[AM29K_R_FPS] = registers[REGISTER_BYTE (FPS_REGNUM)]; - - net_write_registers (am29k_fpreg_packet, AM29K_FPREG_PLEN, - PTRACE_SETFPREGS); - } -} - -/* VxWorks zeroes fp when the task is initialized; we use this - to terminate the frame chain. Chain means here the nominal address of - a frame, that is, the return address (lr0) address in the stack. To - obtain the frame pointer (lr1) contents, we must add 4 bytes. - Note : may be we should modify init_frame_info() to get the frame pointer - and store it into the frame_info struct rather than reading its - contents when FRAME_CHAIN_VALID is invoked. THISFRAME is unused. */ - -int -vx29k_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - int fp_contents; - - read_memory ((CORE_ADDR) (chain + 4), (char *) &fp_contents, 4); - return (fp_contents != 0); -} diff --git a/contrib/gdb/gdb/remote-vx68.c b/contrib/gdb/gdb/remote-vx68.c deleted file mode 100644 index 2ebaa633f77..00000000000 --- a/contrib/gdb/gdb/remote-vx68.c +++ /dev/null @@ -1,156 +0,0 @@ -/* 68k-dependent portions of the RPC protocol - used with a VxWorks target - - Contributed by Wind River Systems. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include "defs.h" - -#include "vx-share/regPacket.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "command.h" -#include "symtab.h" -#include "symfile.h" /* for struct complaint */ -#include "regcache.h" - -#include "gdb_string.h" -#include -#include -#include -#include -#include - -#ifdef _AIX /* IBM claims "void *malloc()" not char * */ -#define malloc bogon_malloc -#endif - -#include - -#ifdef _AIX -#undef malloc -#endif - -#include /* UTek's doesn't #incl this */ -#include -#include "vx-share/ptrace.h" -#include "vx-share/xdr_ptrace.h" -#include "vx-share/xdr_ld.h" -#include "vx-share/xdr_rdb.h" -#include "vx-share/dbgRpcLib.h" - -/* get rid of value.h if possible */ -#include -#include - -/* Flag set if target has fpu */ - -extern int target_has_fp; - -/* Generic register read/write routines in remote-vx.c. */ - -extern void net_read_registers (); -extern void net_write_registers (); - -/* Read a register or registers from the VxWorks target. - REGNO is the register to read, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_read_register (int regno) -{ - char mc68k_greg_packet[MC68K_GREG_PLEN]; - char mc68k_fpreg_packet[MC68K_FPREG_PLEN]; - - /* Get general-purpose registers. */ - - net_read_registers (mc68k_greg_packet, MC68K_GREG_PLEN, PTRACE_GETREGS); - - bcopy (&mc68k_greg_packet[MC68K_R_D0], registers, 16 * MC68K_GREG_SIZE); - bcopy (&mc68k_greg_packet[MC68K_R_SR], ®isters[REGISTER_BYTE (PS_REGNUM)], - MC68K_GREG_SIZE); - bcopy (&mc68k_greg_packet[MC68K_R_PC], ®isters[REGISTER_BYTE (PC_REGNUM)], - MC68K_GREG_SIZE); - - /* Get floating-point registers, if the target system has them. - Otherwise, zero them. */ - - if (target_has_fp) - { - net_read_registers (mc68k_fpreg_packet, MC68K_FPREG_PLEN, - PTRACE_GETFPREGS); - - bcopy (&mc68k_fpreg_packet[MC68K_R_FP0], - ®isters[REGISTER_BYTE (FP0_REGNUM)], - MC68K_FPREG_SIZE * 8); - bcopy (&mc68k_fpreg_packet[MC68K_R_FPCR], - ®isters[REGISTER_BYTE (FPC_REGNUM)], - MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8)); - } - else - { - bzero (®isters[REGISTER_BYTE (FP0_REGNUM)], - MC68K_FPREG_SIZE * 8); - bzero (®isters[REGISTER_BYTE (FPC_REGNUM)], - MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8)); - } - - /* Mark the register cache valid. */ - - registers_fetched (); -} - -/* Store a register or registers into the VxWorks target. - REGNO is the register to store, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_write_register (int regno) -{ - char mc68k_greg_packet[MC68K_GREG_PLEN]; - char mc68k_fpreg_packet[MC68K_FPREG_PLEN]; - - /* Store general-purpose registers. */ - - bcopy (registers, &mc68k_greg_packet[MC68K_R_D0], 16 * MC68K_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (PS_REGNUM)], - &mc68k_greg_packet[MC68K_R_SR], MC68K_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (PC_REGNUM)], - &mc68k_greg_packet[MC68K_R_PC], MC68K_GREG_SIZE); - - net_write_registers (mc68k_greg_packet, MC68K_GREG_PLEN, PTRACE_SETREGS); - - /* Store floating point registers if the target has them. */ - - if (target_has_fp) - { - bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], - &mc68k_fpreg_packet[MC68K_R_FP0], - MC68K_FPREG_SIZE * 8); - bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)], - &mc68k_fpreg_packet[MC68K_R_FPCR], - MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8)); - - net_write_registers (mc68k_fpreg_packet, MC68K_FPREG_PLEN, - PTRACE_SETFPREGS); - } -} diff --git a/contrib/gdb/gdb/remote-vx960.c b/contrib/gdb/gdb/remote-vx960.c deleted file mode 100644 index 08568bc4ca6..00000000000 --- a/contrib/gdb/gdb/remote-vx960.c +++ /dev/null @@ -1,160 +0,0 @@ -/* i80960-dependent portions of the RPC protocol - used with a VxWorks target - - Contributed by Wind River Systems. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include "defs.h" - -#include "vx-share/regPacket.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "command.h" -#include "symtab.h" -#include "symfile.h" /* for struct complaint */ -#include "regcache.h" - -#include "gdb_string.h" -#include -#include -#include -#include -#include - -#ifdef _AIX /* IBM claims "void *malloc()" not char * */ -#define malloc bogon_malloc -#endif - -#include -#include /* UTek's doesn't #incl this */ -#include -#include "vx-share/ptrace.h" -#include "vx-share/xdr_ptrace.h" -#include "vx-share/xdr_ld.h" -#include "vx-share/xdr_rdb.h" -#include "vx-share/dbgRpcLib.h" - -/* get rid of value.h if possible */ -#include -#include - -/* Flag set if target has fpu */ - -extern int target_has_fp; - -/* 960 floating point format descriptor, from "i960-tdep.c." */ - -extern struct ext_format ext_format_i960; - -/* Generic register read/write routines in remote-vx.c. */ - -extern void net_read_registers (); -extern void net_write_registers (); - -/* Read a register or registers from the VxWorks target. - REGNO is the register to read, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_read_register (int regno) -{ - char i960_greg_packet[I960_GREG_PLEN]; - char i960_fpreg_packet[I960_FPREG_PLEN]; - - /* Get general-purpose registers. When copying values into - registers [], don't assume that a location in registers [] - is properly aligned for the target data type. */ - - net_read_registers (i960_greg_packet, I960_GREG_PLEN, PTRACE_GETREGS); - - bcopy (&i960_greg_packet[I960_R_R0], - ®isters[REGISTER_BYTE (R0_REGNUM)], 16 * I960_GREG_SIZE); - bcopy (&i960_greg_packet[I960_R_G0], - ®isters[REGISTER_BYTE (G0_REGNUM)], 16 * I960_GREG_SIZE); - bcopy (&i960_greg_packet[I960_R_PCW], - ®isters[REGISTER_BYTE (PCW_REGNUM)], sizeof (int)); - bcopy (&i960_greg_packet[I960_R_ACW], - ®isters[REGISTER_BYTE (ACW_REGNUM)], sizeof (int)); - bcopy (&i960_greg_packet[I960_R_TCW], - ®isters[REGISTER_BYTE (TCW_REGNUM)], sizeof (int)); - - /* If the target has floating point registers, fetch them. - Otherwise, zero the floating point register values in - registers[] for good measure, even though we might not - need to. */ - - if (target_has_fp) - { - net_read_registers (i960_fpreg_packet, I960_FPREG_PLEN, - PTRACE_GETFPREGS); - bcopy (&i960_fpreg_packet[I960_R_FP0], - ®isters[REGISTER_BYTE (FP0_REGNUM)], - REGISTER_RAW_SIZE (FP0_REGNUM) * 4); - } - else - bzero (®isters[REGISTER_BYTE (FP0_REGNUM)], - REGISTER_RAW_SIZE (FP0_REGNUM) * 4); - - /* Mark the register cache valid. */ - - registers_fetched (); -} - -/* Store a register or registers into the VxWorks target. - REGNO is the register to store, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_write_register (int regno) -{ - char i960_greg_packet[I960_GREG_PLEN]; - char i960_fpreg_packet[I960_FPREG_PLEN]; - - /* Store floating-point registers. When copying values from - registers [], don't assume that a location in registers [] - is properly aligned for the target data type. */ - - bcopy (®isters[REGISTER_BYTE (R0_REGNUM)], - &i960_greg_packet[I960_R_R0], 16 * I960_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (G0_REGNUM)], - &i960_greg_packet[I960_R_G0], 16 * I960_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (PCW_REGNUM)], - &i960_greg_packet[I960_R_PCW], sizeof (int)); - bcopy (®isters[REGISTER_BYTE (ACW_REGNUM)], - &i960_greg_packet[I960_R_ACW], sizeof (int)); - bcopy (®isters[REGISTER_BYTE (TCW_REGNUM)], - &i960_greg_packet[I960_R_TCW], sizeof (int)); - - net_write_registers (i960_greg_packet, I960_GREG_PLEN, PTRACE_SETREGS); - - /* Store floating point registers if the target has them. */ - - if (target_has_fp) - { - bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], - &i960_fpreg_packet[I960_R_FP0], - REGISTER_RAW_SIZE (FP0_REGNUM) * 4); - - net_write_registers (i960_fpreg_packet, I960_FPREG_PLEN, - PTRACE_SETFPREGS); - } -} diff --git a/contrib/gdb/gdb/remote-vxmips.c b/contrib/gdb/gdb/remote-vxmips.c deleted file mode 100644 index 8be4a2f9464..00000000000 --- a/contrib/gdb/gdb/remote-vxmips.c +++ /dev/null @@ -1,199 +0,0 @@ -/* MIPS-dependent portions of the RPC protocol - used with a VxWorks target - - Contributed by Wind River Systems. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include "defs.h" - -#include "vx-share/regPacket.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "command.h" -#include "symtab.h" -#include "symfile.h" /* for struct complaint */ -#include "regcache.h" - -#include "gdb_string.h" -#include -#include -#include -#include -#include -#include -#include /* UTek's doesn't #incl this */ -#include -#include "vx-share/ptrace.h" -#include "vx-share/xdr_ptrace.h" -#include "vx-share/xdr_ld.h" -#include "vx-share/xdr_rdb.h" -#include "vx-share/dbgRpcLib.h" - -/* get rid of value.h if possible */ -#include -#include - -/* Flag set if target has fpu */ - -extern int target_has_fp; - -/* Generic register read/write routines in remote-vx.c. */ - -extern void net_read_registers (); -extern void net_write_registers (); - -/* Read a register or registers from the VxWorks target. - REGNO is the register to read, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_read_register (int regno) -{ - char mips_greg_packet[MIPS_GREG_PLEN]; - char mips_fpreg_packet[MIPS_FPREG_PLEN]; - - /* Get general-purpose registers. */ - - net_read_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_GETREGS); - - /* this code copies the registers obtained by RPC - stored in a structure(s) like this : - - Register(s) Offset(s) - gp 0-31 0x00 - hi 0x80 - lo 0x84 - sr 0x88 - pc 0x8c - - into a stucture like this: - - 0x00 GP 0-31 - 0x80 SR - 0x84 LO - 0x88 HI - 0x8C BAD --- Not available currently - 0x90 CAUSE --- Not available currently - 0x94 PC - 0x98 FP 0-31 - 0x118 FCSR - 0x11C FIR --- Not available currently - 0x120 FP --- Not available currently - - structure is 0x124 (292) bytes in length */ - - /* Copy the general registers. */ - - bcopy (&mips_greg_packet[MIPS_R_GP0], ®isters[0], 32 * MIPS_GREG_SIZE); - - /* Copy SR, LO, HI, and PC. */ - - bcopy (&mips_greg_packet[MIPS_R_SR], - ®isters[REGISTER_BYTE (PS_REGNUM)], MIPS_GREG_SIZE); - bcopy (&mips_greg_packet[MIPS_R_LO], - ®isters[REGISTER_BYTE (LO_REGNUM)], MIPS_GREG_SIZE); - bcopy (&mips_greg_packet[MIPS_R_HI], - ®isters[REGISTER_BYTE (HI_REGNUM)], MIPS_GREG_SIZE); - bcopy (&mips_greg_packet[MIPS_R_PC], - ®isters[REGISTER_BYTE (PC_REGNUM)], MIPS_GREG_SIZE); - - /* If the target has floating point registers, fetch them. - Otherwise, zero the floating point register values in - registers[] for good measure, even though we might not - need to. */ - - if (target_has_fp) - { - net_read_registers (mips_fpreg_packet, MIPS_FPREG_PLEN, - PTRACE_GETFPREGS); - - /* Copy the floating point registers. */ - - bcopy (&mips_fpreg_packet[MIPS_R_FP0], - ®isters[REGISTER_BYTE (FP0_REGNUM)], - REGISTER_RAW_SIZE (FP0_REGNUM) * 32); - - /* Copy the floating point control/status register (fpcsr). */ - - bcopy (&mips_fpreg_packet[MIPS_R_FPCSR], - ®isters[REGISTER_BYTE (FCRCS_REGNUM)], - REGISTER_RAW_SIZE (FCRCS_REGNUM)); - } - else - { - bzero ((char *) ®isters[REGISTER_BYTE (FP0_REGNUM)], - REGISTER_RAW_SIZE (FP0_REGNUM) * 32); - bzero ((char *) ®isters[REGISTER_BYTE (FCRCS_REGNUM)], - REGISTER_RAW_SIZE (FCRCS_REGNUM)); - } - - /* Mark the register cache valid. */ - - registers_fetched (); -} - -/* Store a register or registers into the VxWorks target. - REGNO is the register to store, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -vx_write_register (int regno) -{ - char mips_greg_packet[MIPS_GREG_PLEN]; - char mips_fpreg_packet[MIPS_FPREG_PLEN]; - - /* Store general registers. */ - - bcopy (®isters[0], &mips_greg_packet[MIPS_R_GP0], 32 * MIPS_GREG_SIZE); - - /* Copy SR, LO, HI, and PC. */ - - bcopy (®isters[REGISTER_BYTE (PS_REGNUM)], - &mips_greg_packet[MIPS_R_SR], MIPS_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (LO_REGNUM)], - &mips_greg_packet[MIPS_R_LO], MIPS_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (HI_REGNUM)], - &mips_greg_packet[MIPS_R_HI], MIPS_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (PC_REGNUM)], - &mips_greg_packet[MIPS_R_PC], MIPS_GREG_SIZE); - - net_write_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_SETREGS); - - /* Store floating point registers if the target has them. */ - - if (target_has_fp) - { - /* Copy the floating point data registers. */ - - bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], - &mips_fpreg_packet[MIPS_R_FP0], - REGISTER_RAW_SIZE (FP0_REGNUM) * 32); - - /* Copy the floating point control/status register (fpcsr). */ - - bcopy (®isters[REGISTER_BYTE (FCRCS_REGNUM)], - &mips_fpreg_packet[MIPS_R_FPCSR], - REGISTER_RAW_SIZE (FCRCS_REGNUM)); - - net_write_registers (mips_fpreg_packet, MIPS_FPREG_PLEN, - PTRACE_SETFPREGS); - } -} diff --git a/contrib/gdb/gdb/remote-vxsparc.c b/contrib/gdb/gdb/remote-vxsparc.c deleted file mode 100644 index 014f1d457ef..00000000000 --- a/contrib/gdb/gdb/remote-vxsparc.c +++ /dev/null @@ -1,194 +0,0 @@ -/* sparc-dependent portions of the RPC protocol - used with a VxWorks target - - Contributed by Wind River Systems. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include "defs.h" - -#include "vx-share/regPacket.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcore.h" -#include "command.h" -#include "symtab.h" -#include "symfile.h" /* for struct complaint */ -#include "regcache.h" - -#include "gdb_string.h" -#include -#include -#include -#include -#include - -#ifdef _AIX /* IBM claims "void *malloc()" not char * */ -#define malloc bogon_malloc -#endif - -#include -#include /* UTek's doesn't #incl this */ -#include -#include "vx-share/ptrace.h" -#include "vx-share/xdr_ptrace.h" -#include "vx-share/xdr_ld.h" -#include "vx-share/xdr_rdb.h" -#include "vx-share/dbgRpcLib.h" - -/* get rid of value.h if possible */ -#include -#include - -/* Flag set if target has fpu */ - -extern int target_has_fp; - -/* sparc floating point format descriptor, from "sparc-tdep.c." */ - -extern struct ext_format ext_format_sparc; - -/* Generic register read/write routines in remote-vx.c. */ - -extern void net_read_registers (); -extern void net_write_registers (); - -/* Read a register or registers from the VxWorks target. - REGNO is the register to read, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_read_register (int regno) -{ - char sparc_greg_packet[SPARC_GREG_PLEN]; - char sparc_fpreg_packet[SPARC_FPREG_PLEN]; - CORE_ADDR sp; - - /* Get general-purpose registers. When copying values into - registers [], don't assume that a location in registers [] - is properly aligned for the target data type. */ - - net_read_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_GETREGS); - - /* Now copy the register values into registers[]. - Note that this code depends on the ordering of the REGNUMs - as defined in "tm-sparc.h". */ - - bcopy (&sparc_greg_packet[SPARC_R_G0], - ®isters[REGISTER_BYTE (G0_REGNUM)], 32 * SPARC_GREG_SIZE); - bcopy (&sparc_greg_packet[SPARC_R_Y], - ®isters[REGISTER_BYTE (Y_REGNUM)], 6 * SPARC_GREG_SIZE); - - /* Now write the local and in registers to the register window - spill area in the frame. VxWorks does not do this for the - active frame automatically; it greatly simplifies debugging - (FRAME_FIND_SAVED_REGS, in particular, depends on this). */ - - sp = extract_address (®isters[REGISTER_BYTE (SP_REGNUM)], - REGISTER_RAW_SIZE (CORE_ADDR)); - write_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM)); - - /* If the target has floating point registers, fetch them. - Otherwise, zero the floating point register values in - registers[] for good measure, even though we might not - need to. */ - - if (target_has_fp) - { - net_read_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN, - PTRACE_GETFPREGS); - bcopy (&sparc_fpreg_packet[SPARC_R_FP0], - ®isters[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE); - bcopy (&sparc_fpreg_packet[SPARC_R_FSR], - ®isters[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE); - } - else - { - bzero (®isters[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE); - bzero (®isters[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE); - } - - /* Mark the register cache valid. */ - - registers_fetched (); -} - -/* Store a register or registers into the VxWorks target. - REGNO is the register to store, or -1 for all; currently, - it is ignored. FIXME look at regno to improve efficiency. */ - -void -vx_write_register (int regno) -{ - char sparc_greg_packet[SPARC_GREG_PLEN]; - char sparc_fpreg_packet[SPARC_FPREG_PLEN]; - int in_gp_regs; - int in_fp_regs; - CORE_ADDR sp; - - /* Store general purpose registers. When copying values from - registers [], don't assume that a location in registers [] - is properly aligned for the target data type. */ - - in_gp_regs = 1; - in_fp_regs = 1; - if (regno >= 0) - { - if ((G0_REGNUM <= regno && regno <= I7_REGNUM) - || (Y_REGNUM <= regno && regno <= NPC_REGNUM)) - in_fp_regs = 0; - else - in_gp_regs = 0; - } - if (in_gp_regs) - { - bcopy (®isters[REGISTER_BYTE (G0_REGNUM)], - &sparc_greg_packet[SPARC_R_G0], 32 * SPARC_GREG_SIZE); - bcopy (®isters[REGISTER_BYTE (Y_REGNUM)], - &sparc_greg_packet[SPARC_R_Y], 6 * SPARC_GREG_SIZE); - - net_write_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_SETREGS); - - /* If this is a local or in register, or we're storing all - registers, update the register window spill area. */ - - if (regno < 0 || (L0_REGNUM <= regno && regno <= I7_REGNUM)) - { - sp = extract_address (®isters[REGISTER_BYTE (SP_REGNUM)], - REGISTER_RAW_SIZE (CORE_ADDR)); - write_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM)); - } - } - - /* Store floating point registers if the target has them. */ - - if (in_fp_regs && target_has_fp) - { - bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], - &sparc_fpreg_packet[SPARC_R_FP0], 32 * SPARC_FPREG_SIZE); - bcopy (®isters[REGISTER_BYTE (FPS_REGNUM)], - &sparc_fpreg_packet[SPARC_R_FSR], 1 * SPARC_FPREG_SIZE); - - net_write_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN, - PTRACE_SETFPREGS); - } -} diff --git a/contrib/gdb/gdb/ser-e7kpc.c b/contrib/gdb/gdb/ser-e7kpc.c deleted file mode 100644 index 49b2c89c324..00000000000 --- a/contrib/gdb/gdb/ser-e7kpc.c +++ /dev/null @@ -1,438 +0,0 @@ -/* Remote serial interface using Hitachi E7000 PC ISA card in a PC - Copyright 1994, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#if defined __GO32__ || defined _WIN32 -#include "defs.h" -#include "serial.h" -#include "gdb_string.h" - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#ifdef __GO32__ -#include -#endif - -static int e7000pc_open (struct serial *scb, const char *name); -static void e7000pc_raw (struct serial *scb); -static int e7000pc_readchar (struct serial *scb, int timeout); -static int e7000pc_setbaudrate (struct serial *scb, int rate); -static int e7000pc_write (struct serial *scb, const char *str, int len); -static void e7000pc_close (struct serial *scb); -static serial_ttystate e7000pc_get_tty_state (struct serial *scb); -static int e7000pc_set_tty_state (struct serial *scb, serial_ttystate state); - -#define OFF_DPD 0x0000 -#define OFF_DDP 0x1000 -#define OFF_CPD 0x2000 -#define OFF_CDP 0x2400 -#define OFF_FA 0x3000 -#define OFF_FB 0x3002 -#define OFF_FC 0x3004 -#define OFF_IRQTOD 0x3008 -#define OFF_IRQTOP 0x300a -#define OFF_READY 0x300c -#define OFF_PON 0x300e - -#define IDLE 0x0000 -#define CMD_CI 0x4349 -#define CMD_CO 0x434f -#define CMD_LO 0x4c4f -#define CMD_LS 0x4c53 -#define CMD_SV 0x5356 -#define CMD_SS 0x5353 -#define CMD_OK 0x4f4b -#define CMD_ER 0x4552 -#define CMD_NF 0x4e46 -#define CMD_AB 0x4142 -#define CMD_ED 0x4544 -#define CMD_CE 0x4345 - -static unsigned long fa; -static unsigned long irqtod; -static unsigned long ready; -static unsigned long fb; -static unsigned long cpd; -static unsigned long cdp; -static unsigned long ready; -static unsigned long pon; -static unsigned long irqtop; -static unsigned long board_at; - -#ifdef __GO32__ - -#define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);} -#define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);} -#define GET_BYTE(x) ( dosmemget(x,1,&bb), bb) -#define GET_WORD(x) ( dosmemget(x,2,&sb), sb) -static unsigned char bb; -static unsigned short sb; - -#else /* win32 */ - -#define SET_BYTE(x,y) *(volatile unsigned char *)(x) = (y) -#define SET_WORD(x,y) *(volatile unsigned short *)(x) = (y) -#define GET_BYTE(x) (*(volatile unsigned char *)(x)) -#define GET_WORD(x) (*(volatile unsigned short *)(x)) -#define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN)) -#define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN)) -#endif - -static struct sw - { - int sw; - int addr; - } -sigs[] = -{ - { - 0x14, 0xd0000 - } - , - { - 0x15, 0xd4000 - } - , - { - 0x16, 0xd8000 - } - , - { - 0x17, 0xdc000 - } - , - 0 -}; - -#define get_ds_base() 0 - -static int -e7000pc_init (void) -{ - int try; - unsigned long dsbase; - - dsbase = get_ds_base (); - - /* Look around in memory for the board's signature */ - - for (try = 0; sigs[try].sw; try++) - { - int val; - board_at = sigs[try].addr - dsbase; - fa = board_at + OFF_FA; - fb = board_at + OFF_FB; - cpd = board_at + OFF_CPD; - cdp = board_at + OFF_CDP; - ready = board_at + OFF_READY; - pon = board_at + OFF_PON; - irqtop = board_at + OFF_IRQTOP; - irqtod = board_at + OFF_IRQTOD; - - val = GET_WORD (ready); - - if (val == (0xaaa0 | sigs[try].sw)) - { - if (GET_WORD (pon) & 0xf) - { - SET_WORD (fa, 0); - SET_WORD (fb, 0); - - SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */ - SET_WORD (ready, 1); - printf_filtered ("\nConnected to the E7000PC at address 0x%x\n", - sigs[try].addr); - return 1; - } - error ("The E7000 PC board is working, but the E7000 is turned off.\n"); - return 0; - } - } - - error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\ -and that the switch settings are correct. Some other DOS programs can \n\ -stop the board from working. Try starting from a very minimal boot, \n\ -perhaps you need to disable EMM386 over the region where the board has\n\ -its I/O space, remove other unneeded cards, etc etc\n"); - return 0; - -} - -static int pbuf_size; -static int pbuf_index; - -/* Return next byte from cdp. If no more, then return -1. */ - -static int -e7000_get (void) -{ - static char pbuf[1000]; - char tmp[1000]; - int x; - - if (pbuf_index < pbuf_size) - { - x = pbuf[pbuf_index++]; - } - else if ((GET_WORD (fb) & 1)) - { - int i; - pbuf_size = GET_WORD (cdp + 2); - - dosmemget (cdp + 8, pbuf_size + 1, tmp); - - /* Tell the E7000 we've eaten */ - SET_WORD (fb, 0); - /* Swap it around */ - for (i = 0; i < pbuf_size; i++) - { - pbuf[i] = tmp[i ^ 1]; - } - pbuf_index = 0; - x = pbuf[pbuf_index++]; - } - else - { - x = -1; - } - return x; -} - -/* Works just like read(), except that it takes a TIMEOUT in seconds. Note - that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */ - -static int -dosasync_read (int fd, char *buf, int len, int timeout) -{ - long now; - long then; - int i = 0; - - /* Then look for some more if we're still hungry */ - time (&now); - then = now + timeout; - while (i < len) - { - int ch = e7000_get (); - - /* While there's room in the buffer, and we've already - read the stuff in, suck it over */ - if (ch != -1) - { - buf[i++] = ch; - while (i < len && pbuf_index < pbuf_size) - { - ch = e7000_get (); - if (ch == -1) - break; - buf[i++] = ch; - } - } - - time (&now); - - if (timeout == 0) - return i; - if (now >= then && timeout > 0) - { - return i; - } - } - return len; -} - - -static int -dosasync_write (int fd, const char *buf, int len) -{ - int i; - char dummy[1000]; - - /* Construct copy locally */ - ((short *) dummy)[0] = CMD_CI; - ((short *) dummy)[1] = len; - ((short *) dummy)[2] = 0; - ((short *) dummy)[3] = 0; - for (i = 0; i < len; i++) - { - dummy[(8 + i) ^ 1] = buf[i]; - } - - /* Wait for the card to get ready */ - while (GET_WORD (fa) & 1); - - /* Blast onto the ISA card */ - dosmemput (dummy, 8 + len + 1, cpd); - - SET_WORD (fa, 1); - SET_WORD (irqtod, 1); /* Interrupt the E7000 */ - - return len; -} - -static int -e7000pc_open (struct serial *scb, const char *name) -{ - if (strncasecmp (name, "pc", 2) != 0) - { - errno = ENOENT; - return -1; - } - - scb->fd = e7000pc_init (); - - if (!scb->fd) - return -1; - - return 0; -} - -static int -e7000pc_noop (struct serial *scb) -{ - return 0; -} - -static void -e7000pc_raw (struct serial *scb) -{ - /* Always in raw mode */ -} - -static int -e7000pc_readchar (struct serial *scb, int timeout) -{ - char buf; - -top: - - if (dosasync_read (scb->fd, &buf, 1, timeout)) - { - if (buf == 0) - goto top; - return buf; - } - else - return SERIAL_TIMEOUT; -} - -struct e7000pc_ttystate -{ - int dummy; -}; - -/* e7000pc_{get set}_tty_state() are both dummys to fill out the function - vector. Someday, they may do something real... */ - -static serial_ttystate -e7000pc_get_tty_state (struct serial *scb) -{ - struct e7000pc_ttystate *state; - - state = (struct e7000pc_ttystate *) xmalloc (sizeof *state); - - return (serial_ttystate) state; -} - -static int -e7000pc_set_tty_state (struct serial *scb, serial_ttystate ttystate) -{ - return 0; -} - -static int -e7000pc_noflush_set_tty_state (struct serial *scb, - serial_ttystate new_ttystate, - serial_ttystate old_ttystate) -{ - return 0; -} - -static void -e7000pc_print_tty_state (struct serial *scb, - serial_ttystate ttystate, - struct ui_file *stream) -{ - /* Nothing to print. */ - return; -} - -static int -e7000pc_setbaudrate (struct serial *scb, int rate) -{ - return 0; -} - -static int -e7000pc_setstopbits (struct serial *scb, int rate) -{ - return 0; -} - -static int -e7000pc_write (struct serial *scb, const char *str, int len) -{ - dosasync_write (scb->fd, str, len); - - return 0; -} - -static void -e7000pc_close (struct serial *scb) -{ -} - -static struct serial_ops e7000pc_ops = -{ - "pc", - 0, - e7000pc_open, - e7000pc_close, - e7000pc_readchar, - e7000pc_write, - e7000pc_noop, /* flush output */ - e7000pc_noop, /* flush input */ - e7000pc_noop, /* send break -- currently used only for nindy */ - e7000pc_raw, - e7000pc_get_tty_state, - e7000pc_set_tty_state, - e7000pc_print_tty_state, - e7000pc_noflush_set_tty_state, - e7000pc_setbaudrate, - e7000pc_setstopbits, - e7000pc_noop, /* wait for output to drain */ -}; - -void -_initialize_ser_e7000pc (void) -{ - serial_add_interface (&e7000pc_ops); -} -#else - -void -_initialize_ser_e7000pc (void) -{ - -} -#endif diff --git a/contrib/gdb/gdb/ser-go32.c b/contrib/gdb/gdb/ser-go32.c deleted file mode 100644 index 0642b5aa4bd..00000000000 --- a/contrib/gdb/gdb/ser-go32.c +++ /dev/null @@ -1,964 +0,0 @@ -/* Remote serial interface for local (hardwired) serial ports for GO32. - Copyright 1992, 1993, 2000, 2001 Free Software Foundation, Inc. - - Contributed by Nigel Stephens, Algorithmics Ltd. (nigel@algor.co.uk). - - This version uses DPMI interrupts to handle buffered i/o - without the separate "asynctsr" program. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcmd.h" -#include "serial.h" -#include "gdb_string.h" - - -/* - * NS16550 UART registers - */ - -#define COM1ADDR 0x3f8 -#define COM2ADDR 0x2f8 -#define COM3ADDR 0x3e8 -#define COM4ADDR 0x3e0 - -#define com_data 0 /* data register (R/W) */ -#define com_dlbl 0 /* divisor latch low (W) */ -#define com_ier 1 /* interrupt enable (W) */ -#define com_dlbh 1 /* divisor latch high (W) */ -#define com_iir 2 /* interrupt identification (R) */ -#define com_fifo 2 /* FIFO control (W) */ -#define com_lctl 3 /* line control register (R/W) */ -#define com_cfcr 3 /* line control register (R/W) */ -#define com_mcr 4 /* modem control register (R/W) */ -#define com_lsr 5 /* line status register (R/W) */ -#define com_msr 6 /* modem status register (R/W) */ - -/* - * Constants for computing 16 bit baud rate divisor (lower byte - * in com_dlbl, upper in com_dlbh) from 1.8432MHz crystal. Divisor is - * 1.8432 MHz / (16 * X) for X bps. If the baud rate can't be set - * to within +- (desired_rate*SPEED_TOLERANCE/1000) bps, we fail. - */ -#define COMTICK (1843200/16) -#define SPEED_TOLERANCE 30 /* thousandths; real == desired +- 3.0% */ - -/* interrupt enable register */ -#define IER_ERXRDY 0x1 /* int on rx ready */ -#define IER_ETXRDY 0x2 /* int on tx ready */ -#define IER_ERLS 0x4 /* int on line status change */ -#define IER_EMSC 0x8 /* int on modem status change */ - -/* interrupt identification register */ -#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ -#define IIR_IMASK 0xf /* interrupt cause mask */ -#define IIR_NOPEND 0x1 /* nothing pending */ -#define IIR_RLS 0x6 /* receive line status */ -#define IIR_RXRDY 0x4 /* receive ready */ -#define IIR_RXTOUT 0xc /* receive timeout */ -#define IIR_TXRDY 0x2 /* transmit ready */ -#define IIR_MLSC 0x0 /* modem status */ - - -/* fifo control register */ -#define FIFO_ENABLE 0x01 /* enable fifo */ -#define FIFO_RCV_RST 0x02 /* reset receive fifo */ -#define FIFO_XMT_RST 0x04 /* reset transmit fifo */ -#define FIFO_DMA_MODE 0x08 /* enable dma mode */ -#define FIFO_TRIGGER_1 0x00 /* trigger at 1 char */ -#define FIFO_TRIGGER_4 0x40 /* trigger at 4 chars */ -#define FIFO_TRIGGER_8 0x80 /* trigger at 8 chars */ -#define FIFO_TRIGGER_14 0xc0 /* trigger at 14 chars */ - -/* character format control register */ -#define CFCR_DLAB 0x80 /* divisor latch */ -#define CFCR_SBREAK 0x40 /* send break */ -#define CFCR_PZERO 0x30 /* zero parity */ -#define CFCR_PONE 0x20 /* one parity */ -#define CFCR_PEVEN 0x10 /* even parity */ -#define CFCR_PODD 0x00 /* odd parity */ -#define CFCR_PENAB 0x08 /* parity enable */ -#define CFCR_STOPB 0x04 /* 2 stop bits */ -#define CFCR_8BITS 0x03 /* 8 data bits */ -#define CFCR_7BITS 0x02 /* 7 data bits */ -#define CFCR_6BITS 0x01 /* 6 data bits */ -#define CFCR_5BITS 0x00 /* 5 data bits */ - -/* modem control register */ -#define MCR_LOOPBACK 0x10 /* loopback */ -#define MCR_IENABLE 0x08 /* output 2 = int enable */ -#define MCR_DRS 0x04 /* output 1 = xxx */ -#define MCR_RTS 0x02 /* enable RTS */ -#define MCR_DTR 0x01 /* enable DTR */ - -/* line status register */ -#define LSR_RCV_FIFO 0x80 /* error in receive fifo */ -#define LSR_TSRE 0x40 /* transmitter empty */ -#define LSR_TXRDY 0x20 /* transmitter ready */ -#define LSR_BI 0x10 /* break detected */ -#define LSR_FE 0x08 /* framing error */ -#define LSR_PE 0x04 /* parity error */ -#define LSR_OE 0x02 /* overrun error */ -#define LSR_RXRDY 0x01 /* receiver ready */ -#define LSR_RCV_MASK 0x1f - -/* modem status register */ -#define MSR_DCD 0x80 -#define MSR_RI 0x40 -#define MSR_DSR 0x20 -#define MSR_CTS 0x10 -#define MSR_DDCD 0x08 -#define MSR_TERI 0x04 -#define MSR_DDSR 0x02 -#define MSR_DCTS 0x01 - -#include -#include -#include -#include -typedef unsigned long u_long; - -/* 16550 rx fifo trigger point */ -#define FIFO_TRIGGER FIFO_TRIGGER_4 - -/* input buffer size */ -#define CBSIZE 4096 - -#define RAWHZ 18 - -#ifdef DOS_STATS -#define CNT_RX 16 -#define CNT_TX 17 -#define CNT_STRAY 18 -#define CNT_ORUN 19 -#define NCNT 20 - -static int intrcnt; -static int cnts[NCNT]; -static char *cntnames[NCNT] = -{ - /* h/w interrupt counts. */ - "mlsc", "nopend", "txrdy", "?3", - "rxrdy", "?5", "rls", "?7", - "?8", "?9", "?a", "?b", - "rxtout", "?d", "?e", "?f", - /* s/w counts. */ - "rxcnt", "txcnt", "stray", "swoflo" -}; - -#define COUNT(x) cnts[x]++ -#else -#define COUNT(x) -#endif - -/* Main interrupt controller port addresses. */ -#define ICU_BASE 0x20 -#define ICU_OCW2 (ICU_BASE + 0) -#define ICU_MASK (ICU_BASE + 1) - -/* Original interrupt controller mask register. */ -unsigned char icu_oldmask; - -/* Maximum of 8 interrupts (we don't handle the slave icu yet). */ -#define NINTR 8 - -static struct intrupt - { - char inuse; - struct dos_ttystate *port; - _go32_dpmi_seginfo old_rmhandler; - _go32_dpmi_seginfo old_pmhandler; - _go32_dpmi_seginfo new_rmhandler; - _go32_dpmi_seginfo new_pmhandler; - _go32_dpmi_registers regs; - } -intrupts[NINTR]; - - -static struct dos_ttystate - { - int base; - int irq; - int refcnt; - struct intrupt *intrupt; - int fifo; - int baudrate; - unsigned char cbuf[CBSIZE]; - unsigned int first; - unsigned int count; - int txbusy; - unsigned char old_mcr; - int ferr; - int perr; - int oflo; - int msr; - } -ports[4] = -{ - { - COM1ADDR, 4, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 - } - , - { - COM2ADDR, 3, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 - } - , - { - COM3ADDR, 4, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 - } - , - { - COM4ADDR, 3, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 - } -}; - -static int dos_open (struct serial *scb, const char *name); -static void dos_raw (struct serial *scb); -static int dos_readchar (struct serial *scb, int timeout); -static int dos_setbaudrate (struct serial *scb, int rate); -static int dos_write (struct serial *scb, const char *str, int len); -static void dos_close (struct serial *scb); -static serial_ttystate dos_get_tty_state (struct serial *scb); -static int dos_set_tty_state (struct serial *scb, serial_ttystate state); -static int dos_baudconv (int rate); - -#define inb(p,a) inportb((p)->base + (a)) -#define outb(p,a,v) outportb((p)->base + (a), (v)) -#define disable() asm volatile ("cli"); -#define enable() asm volatile ("sti"); - - -static int -dos_getc (volatile struct dos_ttystate *port) -{ - int c; - - if (port->count == 0) - return -1; - - c = port->cbuf[port->first]; - disable (); - port->first = (port->first + 1) & (CBSIZE - 1); - port->count--; - enable (); - return c; -} - - -static int -dos_putc (int c, struct dos_ttystate *port) -{ - if (port->count >= CBSIZE - 1) - return -1; - port->cbuf[(port->first + port->count) & (CBSIZE - 1)] = c; - port->count++; - return 0; -} - - - -static void -dos_comisr (int irq) -{ - struct dos_ttystate *port; - unsigned char iir, lsr, c; - - disable (); /* Paranoia */ - outportb (ICU_OCW2, 0x20); /* End-Of-Interrupt */ -#ifdef DOS_STATS - ++intrcnt; -#endif - - port = intrupts[irq].port; - if (!port) - { - COUNT (CNT_STRAY); - return; /* not open */ - } - - while (1) - { - iir = inb (port, com_iir) & IIR_IMASK; - switch (iir) - { - - case IIR_RLS: - lsr = inb (port, com_lsr); - goto rx; - - case IIR_RXTOUT: - case IIR_RXRDY: - lsr = 0; - - rx: - do - { - c = inb (port, com_data); - if (lsr & (LSR_BI | LSR_FE | LSR_PE | LSR_OE)) - { - if (lsr & (LSR_BI | LSR_FE)) - port->ferr++; - else if (lsr & LSR_PE) - port->perr++; - if (lsr & LSR_OE) - port->oflo++; - } - - if (dos_putc (c, port) < 0) - { - COUNT (CNT_ORUN); - } - else - { - COUNT (CNT_RX); - } - } - while ((lsr = inb (port, com_lsr)) & LSR_RXRDY); - break; - - case IIR_MLSC: - /* could be used to flowcontrol Tx */ - port->msr = inb (port, com_msr); - break; - - case IIR_TXRDY: - port->txbusy = 0; - break; - - case IIR_NOPEND: - /* no more pending interrupts, all done */ - return; - - default: - /* unexpected interrupt, ignore */ - break; - } - COUNT (iir); - } -} - -#define ISRNAME(x) dos_comisr##x -#define ISR(x) static void ISRNAME(x)(void) {dos_comisr(x);} - -ISR (0) ISR (1) ISR (2) ISR (3) -ISR (4) ISR (5) ISR (6) ISR (7) - -typedef void (*isr_t) (void); - -static isr_t isrs[NINTR] = - { - ISRNAME (0), ISRNAME (1), ISRNAME (2), ISRNAME (3), - ISRNAME (4), ISRNAME (5), ISRNAME (6), ISRNAME (7) - }; - - - -static struct intrupt * -dos_hookirq (unsigned int irq) -{ - struct intrupt *intr; - unsigned int vec; - isr_t isr; - - if (irq >= NINTR) - return 0; - - intr = &intrupts[irq]; - if (intr->inuse) - return 0; - - vec = 0x08 + irq; - isr = isrs[irq]; - - /* setup real mode handler */ - _go32_dpmi_get_real_mode_interrupt_vector (vec, &intr->old_rmhandler); - - intr->new_rmhandler.pm_selector = _go32_my_cs (); - intr->new_rmhandler.pm_offset = (u_long) isr; - if (_go32_dpmi_allocate_real_mode_callback_iret (&intr->new_rmhandler, - &intr->regs)) - { - return 0; - } - - if (_go32_dpmi_set_real_mode_interrupt_vector (vec, &intr->new_rmhandler)) - { - return 0; - } - - /* setup protected mode handler */ - _go32_dpmi_get_protected_mode_interrupt_vector (vec, &intr->old_pmhandler); - - intr->new_pmhandler.pm_selector = _go32_my_cs (); - intr->new_pmhandler.pm_offset = (u_long) isr; - _go32_dpmi_allocate_iret_wrapper (&intr->new_pmhandler); - - if (_go32_dpmi_set_protected_mode_interrupt_vector (vec, - &intr->new_pmhandler)) - { - return 0; - } - - /* setup interrupt controller mask */ - disable (); - outportb (ICU_MASK, inportb (ICU_MASK) & ~(1 << irq)); - enable (); - - intr->inuse = 1; - return intr; -} - - -static void -dos_unhookirq (struct intrupt *intr) -{ - unsigned int irq, vec; - unsigned char mask; - - irq = intr - intrupts; - vec = 0x08 + irq; - - /* restore old interrupt mask bit */ - mask = 1 << irq; - disable (); - outportb (ICU_MASK, inportb (ICU_MASK) | (mask & icu_oldmask)); - enable (); - - /* remove real mode handler */ - _go32_dpmi_set_real_mode_interrupt_vector (vec, &intr->old_rmhandler); - _go32_dpmi_free_real_mode_callback (&intr->new_rmhandler); - - /* remove protected mode handler */ - _go32_dpmi_set_protected_mode_interrupt_vector (vec, &intr->old_pmhandler); - _go32_dpmi_free_iret_wrapper (&intr->new_pmhandler); - intr->inuse = 0; -} - - - -static int -dos_open (struct serial *scb, const char *name) -{ - struct dos_ttystate *port; - int fd, i; - - if (strncasecmp (name, "/dev/", 5) == 0) - name += 5; - else if (strncasecmp (name, "\\dev\\", 5) == 0) - name += 5; - - if (strlen (name) != 4 || strncasecmp (name, "com", 3) != 0) - { - errno = ENOENT; - return -1; - } - - if (name[3] < '1' || name[3] > '4') - { - errno = ENOENT; - return -1; - } - - /* FIXME: this is a Bad Idea (tm)! One should *never* invent file - handles, since they might be already used by other files/devices. - The Right Way to do this is to create a real handle by dup()'ing - some existing one. */ - fd = name[3] - '1'; - port = &ports[fd]; - if (port->refcnt++ > 0) - { - /* Device already opened another user. Just point at it. */ - scb->fd = fd; - return 0; - } - - /* force access to ID reg */ - outb (port, com_cfcr, 0); - outb (port, com_iir, 0); - for (i = 0; i < 17; i++) - { - if ((inb (port, com_iir) & 0x38) == 0) - goto ok; - (void) inb (port, com_data); /* clear recv */ - } - errno = ENODEV; - return -1; - -ok: - /* disable all interrupts in chip */ - outb (port, com_ier, 0); - - /* tentatively enable 16550 fifo, and see if it responds */ - outb (port, com_fifo, - FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER); - sleep (1); - port->fifo = ((inb (port, com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK); - - /* clear pending status reports. */ - (void) inb (port, com_lsr); - (void) inb (port, com_msr); - - /* enable external interrupt gate (to avoid floating IRQ) */ - outb (port, com_mcr, MCR_IENABLE); - - /* hook up interrupt handler and initialise icu */ - port->intrupt = dos_hookirq (port->irq); - if (!port->intrupt) - { - outb (port, com_mcr, 0); - outb (port, com_fifo, 0); - errno = ENODEV; - return -1; - } - - disable (); - - /* record port */ - port->intrupt->port = port; - scb->fd = fd; - - /* clear rx buffer, tx busy flag and overflow count */ - port->first = port->count = 0; - port->txbusy = 0; - port->oflo = 0; - - /* set default baud rate and mode: 9600,8,n,1 */ - i = dos_baudconv (port->baudrate = 9600); - outb (port, com_cfcr, CFCR_DLAB); - outb (port, com_dlbl, i & 0xff); - outb (port, com_dlbh, i >> 8); - outb (port, com_cfcr, CFCR_8BITS); - - /* enable all interrupts */ - outb (port, com_ier, IER_ETXRDY | IER_ERXRDY | IER_ERLS | IER_EMSC); - - /* enable DTR & RTS */ - outb (port, com_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE); - - enable (); - - return 0; -} - - -static void -dos_close (struct serial *scb) -{ - struct dos_ttystate *port; - struct intrupt *intrupt; - - if (!scb) - return; - - port = &ports[scb->fd]; - - if (port->refcnt-- > 1) - return; - - if (!(intrupt = port->intrupt)) - return; - - /* disable interrupts, fifo, flow control */ - disable (); - port->intrupt = 0; - intrupt->port = 0; - outb (port, com_fifo, 0); - outb (port, com_ier, 0); - enable (); - - /* unhook handler, and disable interrupt gate */ - dos_unhookirq (intrupt); - outb (port, com_mcr, 0); - - /* Check for overflow errors */ - if (port->oflo) - { - fprintf_unfiltered (gdb_stderr, - "Serial input overruns occurred.\n"); - fprintf_unfiltered (gdb_stderr, "This system %s handle %d baud.\n", - port->fifo ? "cannot" : "needs a 16550 to", - port->baudrate); - } -} - - - -static int -dos_noop (struct serial *scb) -{ - return 0; -} - -static void -dos_raw (struct serial *scb) -{ - /* Always in raw mode */ -} - -static int -dos_readchar (struct serial *scb, int timeout) -{ - struct dos_ttystate *port = &ports[scb->fd]; - long then; - int c; - - then = rawclock () + (timeout * RAWHZ); - while ((c = dos_getc (port)) < 0) - { - if (timeout >= 0 && (rawclock () - then) >= 0) - return SERIAL_TIMEOUT; - } - - return c; -} - - -static serial_ttystate -dos_get_tty_state (struct serial *scb) -{ - struct dos_ttystate *port = &ports[scb->fd]; - struct dos_ttystate *state; - - /* Are they asking about a port we opened? */ - if (port->refcnt <= 0) - { - /* We've never heard about this port. We should fail this call, - unless they are asking about one of the 3 standard handles, - in which case we pretend the handle was open by us if it is - connected to a terminal device. This is beacuse Unix - terminals use the serial interface, so GDB expects the - standard handles to go through here. */ - if (scb->fd >= 3 || !isatty (scb->fd)) - return NULL; - } - - state = (struct dos_ttystate *) xmalloc (sizeof *state); - *state = *port; - return (serial_ttystate) state; -} - -static int -dos_set_tty_state (struct serial *scb, serial_ttystate ttystate) -{ - struct dos_ttystate *state; - - state = (struct dos_ttystate *) ttystate; - dos_setbaudrate (scb, state->baudrate); - return 0; -} - -static int -dos_noflush_set_tty_state (struct serial *scb, serial_ttystate new_ttystate, - serial_ttystate old_ttystate) -{ - struct dos_ttystate *state; - - state = (struct dos_ttystate *) new_ttystate; - dos_setbaudrate (scb, state->baudrate); - return 0; -} - -static int -dos_flush_input (struct serial *scb) -{ - struct dos_ttystate *port = &ports[scb->fd]; - disable (); - port->first = port->count = 0; - if (port->fifo) - outb (port, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_TRIGGER); - enable (); - return 0; -} - -static void -dos_print_tty_state (struct serial *scb, serial_ttystate ttystate, - struct ui_file *stream) -{ - /* Nothing to print */ - return; -} - -static int -dos_baudconv (int rate) -{ - long x, err; - - if (rate <= 0) - return -1; - -#define divrnd(n, q) (((n) * 2 / (q) + 1) / 2) /* divide and round off */ - x = divrnd (COMTICK, rate); - if (x <= 0) - return -1; - - err = divrnd (1000 * COMTICK, x * rate) - 1000; - if (err < 0) - err = -err; - if (err > SPEED_TOLERANCE) - return -1; -#undef divrnd - return x; -} - - -static int -dos_setbaudrate (struct serial *scb, int rate) -{ - struct dos_ttystate *port = &ports[scb->fd]; - - if (port->baudrate != rate) - { - int x; - unsigned char cfcr; - - x = dos_baudconv (rate); - if (x <= 0) - { - fprintf_unfiltered (gdb_stderr, "%d: impossible baudrate\n", rate); - errno = EINVAL; - return -1; - } - - disable (); - cfcr = inb (port, com_cfcr); - - outb (port, com_cfcr, CFCR_DLAB); - outb (port, com_dlbl, x & 0xff); - outb (port, com_dlbh, x >> 8); - outb (port, com_cfcr, cfcr); - port->baudrate = rate; - enable (); - } - - return 0; -} - -static int -dos_setstopbits (struct serial *scb, int num) -{ - struct dos_ttystate *port = &ports[scb->fd]; - unsigned char cfcr; - - disable (); - cfcr = inb (port, com_cfcr); - - switch (num) - { - case SERIAL_1_STOPBITS: - outb (port, com_cfcr, cfcr & ~CFCR_STOPB); - break; - case SERIAL_1_AND_A_HALF_STOPBITS: - case SERIAL_2_STOPBITS: - outb (port, com_cfcr, cfcr | CFCR_STOPB); - break; - default: - enable (); - return 1; - } - enable (); - - return 0; -} - -static int -dos_write (struct serial *scb, const char *str, int len) -{ - volatile struct dos_ttystate *port = &ports[scb->fd]; - int fifosize = port->fifo ? 16 : 1; - long then; - int cnt; - - while (len > 0) - { - /* send the data, fifosize bytes at a time */ - cnt = fifosize > len ? len : fifosize; - port->txbusy = 1; - /* Francisco Pastor says OUTSB messes - up the communications with UARTs with FIFOs. */ -#ifdef UART_FIFO_WORKS - outportsb (port->base + com_data, str, cnt); - str += cnt; - len -= cnt; -#else - for ( ; cnt > 0; cnt--, len--) - outportb (port->base + com_data, *str++); -#endif -#ifdef DOS_STATS - cnts[CNT_TX] += cnt; -#endif - /* wait for transmission to complete (max 1 sec) */ - then = rawclock () + RAWHZ; - while (port->txbusy) - { - if ((rawclock () - then) >= 0) - { - errno = EIO; - return SERIAL_ERROR; - } - } - } - return 0; -} - - -static int -dos_sendbreak (struct serial *scb) -{ - volatile struct dos_ttystate *port = &ports[scb->fd]; - unsigned char cfcr; - long then; - - cfcr = inb (port, com_cfcr); - outb (port, com_cfcr, cfcr | CFCR_SBREAK); - - /* 0.25 sec delay */ - then = rawclock () + RAWHZ / 4; - while ((rawclock () - then) < 0) - continue; - - outb (port, com_cfcr, cfcr); - return 0; -} - - -static struct serial_ops dos_ops = -{ - "hardwire", - 0, - dos_open, - dos_close, - dos_readchar, - dos_write, - dos_noop, /* flush output */ - dos_flush_input, - dos_sendbreak, - dos_raw, - dos_get_tty_state, - dos_set_tty_state, - dos_print_tty_state, - dos_noflush_set_tty_state, - dos_setbaudrate, - dos_setstopbits, - dos_noop, /* wait for output to drain */ - (void (*)(struct serial *, int))NULL /* change into async mode */ -}; - - -static void -dos_info (char *arg, int from_tty) -{ - struct dos_ttystate *port; -#ifdef DOS_STATS - int i; -#endif - - for (port = ports; port < &ports[4]; port++) - { - if (port->baudrate == 0) - continue; - printf_filtered ("Port:\tCOM%ld (%sactive)\n", (long)(port - ports) + 1, - port->intrupt ? "" : "not "); - printf_filtered ("Addr:\t0x%03x (irq %d)\n", port->base, port->irq); - printf_filtered ("16550:\t%s\n", port->fifo ? "yes" : "no"); - printf_filtered ("Speed:\t%d baud\n", port->baudrate); - printf_filtered ("Errs:\tframing %d parity %d overflow %d\n\n", - port->ferr, port->perr, port->oflo); - } - -#ifdef DOS_STATS - printf_filtered ("\nTotal interrupts: %d\n", intrcnt); - for (i = 0; i < NCNT; i++) - if (cnts[i]) - printf_filtered ("%s:\t%d\n", cntnames[i], cnts[i]); -#endif -} - - -void -_initialize_ser_dos (void) -{ - serial_add_interface (&dos_ops); - - /* Save original interrupt mask register. */ - icu_oldmask = inportb (ICU_MASK); - - /* Mark fixed motherboard irqs as inuse. */ - intrupts[0].inuse = /* timer tick */ - intrupts[1].inuse = /* keyboard */ - intrupts[2].inuse = 1; /* slave icu */ - - add_show_from_set ( - add_set_cmd ("com1base", class_obscure, var_zinteger, - (char *) &ports[0].base, - "Set COM1 base i/o port address.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("com1irq", class_obscure, var_zinteger, - (char *) &ports[0].irq, - "Set COM1 interrupt request.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("com2base", class_obscure, var_zinteger, - (char *) &ports[1].base, - "Set COM2 base i/o port address.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("com2irq", class_obscure, var_zinteger, - (char *) &ports[1].irq, - "Set COM2 interrupt request.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("com3base", class_obscure, var_zinteger, - (char *) &ports[2].base, - "Set COM3 base i/o port address.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("com3irq", class_obscure, var_zinteger, - (char *) &ports[2].irq, - "Set COM3 interrupt request.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("com4base", class_obscure, var_zinteger, - (char *) &ports[3].base, - "Set COM4 base i/o port address.", - &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("com4irq", class_obscure, var_zinteger, - (char *) &ports[3].irq, - "Set COM4 interrupt request.", - &setlist), - &showlist); - - add_info ("serial", dos_info, - "Print DOS serial port status."); -} diff --git a/contrib/gdb/gdb/ser-mac.c b/contrib/gdb/gdb/ser-mac.c deleted file mode 100644 index df0040edbf2..00000000000 --- a/contrib/gdb/gdb/ser-mac.c +++ /dev/null @@ -1,362 +0,0 @@ -/* Remote serial interface for local (hardwired) serial ports for Macintosh. - Copyright 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support. Written by Stan Shebs. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "serial.h" - -#include -#include -/* This is the regular Mac Serial.h, but copied to a different name - so as not to get confused with the GDB serial.h above. */ -#include "MacSerial.h" - -/* This is unused for now. We just return a placeholder. */ - -struct mac_ttystate - { - int bogus; - }; - -static int mac_open PARAMS ((serial_t scb, const char *name)); -static void mac_raw PARAMS ((serial_t scb)); -static int mac_readchar PARAMS ((serial_t scb, int timeout)); -static int mac_setbaudrate PARAMS ((serial_t scb, int rate)); -static int mac_write PARAMS ((serial_t scb, const char *str, int len)); -static void mac_close PARAMS ((serial_t scb)); -static serial_ttystate mac_get_tty_state PARAMS ((serial_t scb)); -static int mac_set_tty_state PARAMS ((serial_t scb, serial_ttystate state)); -static char *aptr PARAMS ((short p)); - -short input_refnum; -short output_refnum; - -char *mac_input_buffer; -char *mac_output_buffer; - -static int -mac_open (scb, name) - serial_t scb; - const char *name; -{ - OSErr err; - - /* Alloc buffer space first - that way any allocation failures are - intercepted before the serial driver gets involved. */ - if (mac_input_buffer == NULL) - mac_input_buffer = (char *) xmalloc (4096); - /* Match on a name and open a port. */ - if (strcmp (name, "modem") == 0) - { - err = OpenDriver ("\p.AIn", &input_refnum); - if (err != 0) - { - return (-1); - } - err = OpenDriver ("\p.AOut", &output_refnum); - if (err != 0) - { - CloseDriver (input_refnum); - return (-1); - } - } - else if (strcmp (name, "printer") == 0) - { - err = OpenDriver ("\p.BIn", &input_refnum); - if (err != 0) - { - return (-1); - } - err = OpenDriver ("\p.BOut", &output_refnum); - if (err != 0) - { - CloseDriver (input_refnum); - return (-1); - } - /* fake */ - scb->fd = 1; - return 0; - } - else - { - error ("You must specify a valid serial port name; your choices are `modem' or `printer'."); - errno = ENOENT; - return (-1); - } - /* We got something open. */ - if (1 /* using custom buffer */) - SerSetBuf (input_refnum, mac_input_buffer, 4096); - /* Set to a GDB-preferred state. */ - SerReset (input_refnum, stop10|noParity|data8|baud9600); - SerReset (output_refnum, stop10|noParity|data8|baud9600); - { - CntrlParam cb; - struct SerShk *handshake; - - cb.ioCRefNum = output_refnum; - cb.csCode = 14; - handshake = (struct SerShk *) &cb.csParam[0]; - handshake->fXOn = 0; - handshake->fCTS = 0; - handshake->xOn = 0; - handshake->xOff = 0; - handshake->errs = 0; - handshake->evts = 0; - handshake->fInX = 0; - handshake->fDTR = 0; - err = PBControl ((ParmBlkPtr) &cb, 0); - if (err < 0) - return (-1); - } - /* fake */ - scb->fd = 1; - return 0; -} - -static int -mac_noop (scb) - serial_t scb; -{ - return 0; -} - -static void -mac_raw (scb) - serial_t scb; -{ - /* Always effectively in raw mode. */ -} - -/* Read a character with user-specified timeout. TIMEOUT is number of seconds - to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns - char if successful. Returns -2 if timeout expired, EOF if line dropped - dead, or -3 for any other error (see errno in that case). */ - -static int -mac_readchar (scb, timeout) - serial_t scb; - int timeout; -{ - int status, n; - /* time_t */ unsigned long start_time, now; - OSErr err; - CntrlParam cb; - IOParam pb; - - if (scb->bufcnt-- > 0) - return *scb->bufp++; - - time (&start_time); - - while (1) - { - cb.ioCRefNum = input_refnum; - cb.csCode = 2; - err = PBStatus ((ParmBlkPtr) &cb, 0); - if (err < 0) - return SERIAL_ERROR; - n = *((long *) &cb.csParam[0]); - if (n > 0) - { - pb.ioRefNum = input_refnum; - pb.ioBuffer = (Ptr) (scb->buf); - pb.ioReqCount = (n > 64 ? 64 : n); - err = PBRead ((ParmBlkPtr) &pb, 0); - if (err < 0) - return SERIAL_ERROR; - scb->bufcnt = pb.ioReqCount; - scb->bufcnt--; - scb->bufp = scb->buf; - return *scb->bufp++; - } - else if (timeout == 0) - return SERIAL_TIMEOUT; - else if (timeout == -1) - ; - else - { - time (&now); - if (now > start_time + timeout) - return SERIAL_TIMEOUT; - } - PROGRESS (1); - } -} - -/* mac_{get set}_tty_state() are both dummys to fill out the function - vector. Someday, they may do something real... */ - -static serial_ttystate -mac_get_tty_state (scb) - serial_t scb; -{ - struct mac_ttystate *state; - - state = (struct mac_ttystate *) xmalloc (sizeof *state); - - return (serial_ttystate) state; -} - -static int -mac_set_tty_state (scb, ttystate) - serial_t scb; - serial_ttystate ttystate; -{ - return 0; -} - -static int -mac_noflush_set_tty_state (scb, new_ttystate, old_ttystate) - serial_t scb; - serial_ttystate new_ttystate; - serial_ttystate old_ttystate; -{ - return 0; -} - -static void -mac_print_tty_state (scb, ttystate) - serial_t scb; - serial_ttystate ttystate; -{ - /* Nothing to print. */ - return; -} - -/* If there is a tricky formula to relate real baud rates - to what the serial driver wants, we should use it. Until - we get one, this table will have to do. */ - -static struct { - int real_rate; - int bits; -} mac_baud_rate_table[] = { - { 57600, baud57600 }, - { 38400, 1 }, - { 19200, baud19200 }, - { 9600, baud9600 }, - { 7200, baud7200 }, - { 4800, baud4800 }, - { 3600, baud3600 }, - { 2400, baud2400 }, - { 1800, baud1800 }, - { 1200, baud1200 }, - { 600, baud600 }, - { 300, baud300 }, - { 0, 0 } -}; - -static int -mac_set_baud_rate (scb, rate) - serial_t scb; - int rate; -{ - int i, bits; - - for (i = 0; mac_baud_rate_table[i].real_rate != 0; ++i) - { - if (mac_baud_rate_table[i].real_rate == rate) - { - bits = mac_baud_rate_table[i].bits; - break; - } - } - SerReset (input_refnum, stop10|noParity|data8|bits); - SerReset (output_refnum, stop10|noParity|data8|bits); -} - -static int -mac_set_stop_bits (scb, num) - serial_t scb; - int num; -{ - return 0; -} - -int first_mac_write = 0; - -static int -mac_write (scb, str, len) - serial_t scb; - const char *str; - int len; -{ - OSErr err; - IOParam pb; - - if (first_mac_write++ < 4) - { - sleep (1); - } - pb.ioRefNum = output_refnum; - pb.ioBuffer = (Ptr) str; - pb.ioReqCount = len; - err = PBWrite ((ParmBlkPtr) &pb, 0); - if (err < 0) - { - return 1; - } - return 0; -} - -static void -mac_close (serial_t scb) -{ - if (input_refnum) - { - if (1 /* custom buffer */) - SerSetBuf (input_refnum, mac_input_buffer, 0); - CloseDriver (input_refnum); - input_refnum = 0; - } - if (output_refnum) - { - if (0 /* custom buffer */) - SerSetBuf (input_refnum, mac_output_buffer, 0); - CloseDriver (output_refnum); - output_refnum = 0; - } -} - -static struct serial_ops mac_ops = -{ - "hardwire", - 0, - mac_open, - mac_close, - mac_readchar, - mac_write, - mac_noop, /* flush output */ - mac_noop, /* flush input */ - mac_noop, /* send break -- currently only for nindy */ - mac_raw, - mac_get_tty_state, - mac_set_tty_state, - mac_print_tty_state, - mac_noflush_set_tty_state, - mac_set_baud_rate, - mac_set_stop_bits, - mac_noop, /* wait for output to drain */ -}; - -void -_initialize_ser_mac () -{ - serial_add_interface (&mac_ops); -} diff --git a/contrib/gdb/gdb/ser-ocd.c b/contrib/gdb/gdb/ser-ocd.c deleted file mode 100644 index 971f84e049c..00000000000 --- a/contrib/gdb/gdb/ser-ocd.c +++ /dev/null @@ -1,209 +0,0 @@ -/* Remote serial interface for Macraigor Systems implementation of - On-Chip Debugging using serial target box or serial wiggler - - Copyright 1994, 1997 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "serial.h" - -#ifdef _WIN32 -#include -#endif - -static int ser_ocd_open PARAMS ((serial_t scb, const char *name)); -static void ser_ocd_raw PARAMS ((serial_t scb)); -static int ser_ocd_readchar PARAMS ((serial_t scb, int timeout)); -static int ser_ocd_setbaudrate PARAMS ((serial_t scb, int rate)); -static int ser_ocd_write PARAMS ((serial_t scb, const char *str, int len)); -static void ser_ocd_close PARAMS ((serial_t scb)); -static serial_ttystate ser_ocd_get_tty_state PARAMS ((serial_t scb)); -static int ser_ocd_set_tty_state PARAMS ((serial_t scb, serial_ttystate state)); - -#ifdef _WIN32 -/* On Windows, this function pointer is initialized to a function in - the wiggler DLL. */ -static int (*dll_do_command) PARAMS ((const char *, char *)); -#endif - -static int -ocd_open (scb, name) - serial_t scb; - const char *name; -{ -#ifdef _WIN32 - /* Find the wiggler DLL which talks to the board. */ - if (dll_do_command == NULL) - { - HINSTANCE handle; - - /* FIXME: Should the user be able to configure this? */ - handle = LoadLibrary ("Wigglers.dll"); - if (handle == NULL) - error ("Can't load Wigglers.dll"); - - dll_do_command = ((int (*) PARAMS ((const char *, char *))) - GetProcAddress (handle, "do_command")); - if (dll_do_command == NULL) - error ("Can't find do_command function in Wigglers.dll"); - } -#else - /* No wiggler DLLs on Unix yet, fail. */ - error ("Wiggler library not available for this type of host."); -#endif /* _WIN32 */ - return 0; -} - -static int -ocd_noop (scb) - serial_t scb; -{ - return 0; -} - -static void -ocd_raw (scb) - serial_t scb; -{ - /* Always in raw mode */ -} - -static void -ocd_readremote () -{ -} - -/* We need a buffer to store responses from the Wigglers.dll */ -#define WIGGLER_BUFF_SIZE 512 -unsigned char from_wiggler_buffer[WIGGLER_BUFF_SIZE]; -unsigned char * wiggler_buffer_ptr; /* curr spot in buffer */ - -static int -ocd_readchar (scb, timeout) - serial_t scb; - int timeout; -{ - /* Catch attempts at reading past the end of the buffer */ - if (wiggler_buffer_ptr > - (from_wiggler_buffer + (sizeof (char *) * WIGGLER_BUFF_SIZE))) - error ("ocd_readchar asked to read past the end of the buffer!"); - - return (int) *wiggler_buffer_ptr++; /* return curr char and increment ptr */ -} - -struct ocd_ttystate { - int dummy; -}; - -/* ocd_{get set}_tty_state() are both dummys to fill out the function - vector. Someday, they may do something real... */ - -static serial_ttystate -ocd_get_tty_state (scb) - serial_t scb; -{ - struct ocd_ttystate *state; - - state = (struct ocd_ttystate *) xmalloc (sizeof *state); - - return (serial_ttystate) state; -} - -static int -ocd_set_tty_state (scb, ttystate) - serial_t scb; - serial_ttystate ttystate; -{ - return 0; -} - -static int -ocd_noflush_set_tty_state (scb, new_ttystate, old_ttystate) - serial_t scb; - serial_ttystate new_ttystate; - serial_ttystate old_ttystate; -{ - return 0; -} - -static void -ocd_print_tty_state (scb, ttystate) - serial_t scb; - serial_ttystate ttystate; -{ - /* Nothing to print. */ - return; -} - -static int -ocd_setbaudrate (scb, rate) - serial_t scb; - int rate; -{ - return 0; -} - -static int -ocd_write (scb, str, len) - serial_t scb; - const char *str; - int len; -{ - char c; - -#ifdef _WIN32 - /* send packet to Wigglers.dll and store response so we can give it to - remote-wiggler.c when get_packet is run */ - dll_do_command (str, from_wiggler_buffer); - wiggler_buffer_ptr = from_wiggler_buffer; -#endif - - return 0; -} - -static void -ocd_close (scb) - serial_t scb; -{ -} - -static struct serial_ops ocd_ops = -{ - "ocd", - 0, - ocd_open, - ocd_close, - ocd_readchar, - ocd_write, - ocd_noop, /* flush output */ - ocd_noop, /* flush input */ - ocd_noop, /* send break -- currently used only for nindy */ - ocd_raw, - ocd_get_tty_state, - ocd_set_tty_state, - ocd_print_tty_state, - ocd_noflush_set_tty_state, - ocd_setbaudrate, - ocd_noop, /* wait for output to drain */ -}; - -void -_initialize_ser_ocd_bdm () -{ - serial_add_interface (&ocd_ops); -} diff --git a/contrib/gdb/gdb/signals.h b/contrib/gdb/gdb/signals.h deleted file mode 100644 index a1348b63733..00000000000 --- a/contrib/gdb/gdb/signals.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Signal handler definitions for GDB, the GNU Debugger. - Copyright (C) 1986, 1989 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file is almost the same as including except that it - eliminates certain signal names when job control is not supported, - (or, on some systems, when job control is there but doesn't work - the way GDB expects it to work). */ -/* This has been superceded by the job_control variable in serial.h. */ - -#include diff --git a/contrib/gdb/gdb/somread.c b/contrib/gdb/gdb/somread.c deleted file mode 100644 index e4fec18ae62..00000000000 --- a/contrib/gdb/gdb/somread.c +++ /dev/null @@ -1,743 +0,0 @@ -/* Read HP PA/Risc object files for GDB. - Copyright 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. - Written by Fred Fish at Cygnus Support. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "bfd.h" -#include -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "stabsread.h" -#include "gdb-stabs.h" -#include "complaints.h" -#include "gdb_string.h" -#include "demangle.h" -#include "som.h" -#include "libhppa.h" - -/* Various things we might complain about... */ - -static void som_symfile_init (struct objfile *); - -static void som_new_init (struct objfile *); - -static void som_symfile_read (struct objfile *, int); - -static void som_symfile_finish (struct objfile *); - -static void -som_symtab_read (bfd *, struct objfile *, struct section_offsets *); - -static void -som_symfile_offsets (struct objfile *, struct section_addr_info *); - -/* FIXME: These should really be in a common header somewhere */ - -extern void hpread_build_psymtabs (struct objfile *, int); - -extern void hpread_symfile_finish (struct objfile *); - -extern void hpread_symfile_init (struct objfile *); - -extern void do_pxdb (bfd *); - -/* - - LOCAL FUNCTION - - som_symtab_read -- read the symbol table of a SOM file - - SYNOPSIS - - void som_symtab_read (bfd *abfd, struct objfile *objfile, - struct section_offsets *section_offsets) - - DESCRIPTION - - Given an open bfd, a base address to relocate symbols to, and a - flag that specifies whether or not this bfd is for an executable - or not (may be shared library for example), add all the global - function and data symbols to the minimal symbol table. - */ - -static void -som_symtab_read (bfd *abfd, struct objfile *objfile, - struct section_offsets *section_offsets) -{ - unsigned int number_of_symbols; - int val, dynamic; - char *stringtab; - asection *shlib_info; - struct symbol_dictionary_record *buf, *bufp, *endbufp; - char *symname; - CONST int symsize = sizeof (struct symbol_dictionary_record); - CORE_ADDR text_offset, data_offset; - - - text_offset = ANOFFSET (section_offsets, 0); - data_offset = ANOFFSET (section_offsets, 1); - - number_of_symbols = bfd_get_symcount (abfd); - - /* FIXME (alloca): could be quite large. */ - buf = alloca (symsize * number_of_symbols); - bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET); - val = bfd_bread (buf, symsize * number_of_symbols, abfd); - if (val != symsize * number_of_symbols) - error ("Couldn't read symbol dictionary!"); - - /* FIXME (alloca): could be quite large. */ - stringtab = alloca (obj_som_stringtab_size (abfd)); - bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET); - val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd); - if (val != obj_som_stringtab_size (abfd)) - error ("Can't read in HP string table."); - - /* We need to determine if objfile is a dynamic executable (so we - can do the right thing for ST_ENTRY vs ST_CODE symbols). - - There's nothing in the header which easily allows us to do - this. The only reliable way I know of is to check for the - existence of a $SHLIB_INFO$ section with a non-zero size. */ - /* The code below is not a reliable way to check whether an - * executable is dynamic, so I commented it out - RT - * shlib_info = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$"); - * if (shlib_info) - * dynamic = (bfd_section_size (objfile->obfd, shlib_info) != 0); - * else - * dynamic = 0; - */ - /* I replaced the code with a simple check for text offset not being - * zero. Still not 100% reliable, but a more reliable way of asking - * "is this a dynamic executable?" than the above. RT - */ - dynamic = (text_offset != 0); - - endbufp = buf + number_of_symbols; - for (bufp = buf; bufp < endbufp; ++bufp) - { - enum minimal_symbol_type ms_type; - - QUIT; - - switch (bufp->symbol_scope) - { - case SS_UNIVERSAL: - case SS_EXTERNAL: - switch (bufp->symbol_type) - { - case ST_SYM_EXT: - case ST_ARG_EXT: - continue; - - case ST_CODE: - case ST_PRI_PROG: - case ST_SEC_PROG: - case ST_MILLICODE: - symname = bufp->name.n_strx + stringtab; - ms_type = mst_text; - bufp->symbol_value += text_offset; - bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); - break; - - case ST_ENTRY: - symname = bufp->name.n_strx + stringtab; - /* For a dynamic executable, ST_ENTRY symbols are - the stubs, while the ST_CODE symbol is the real - function. */ - if (dynamic) - ms_type = mst_solib_trampoline; - else - ms_type = mst_text; - bufp->symbol_value += text_offset; - bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); - break; - - case ST_STUB: - symname = bufp->name.n_strx + stringtab; - ms_type = mst_solib_trampoline; - bufp->symbol_value += text_offset; - bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); - break; - - case ST_DATA: - symname = bufp->name.n_strx + stringtab; - bufp->symbol_value += data_offset; - ms_type = mst_data; - break; - default: - continue; - } - break; - -#if 0 - /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */ - case SS_GLOBAL: -#endif - case SS_LOCAL: - switch (bufp->symbol_type) - { - case ST_SYM_EXT: - case ST_ARG_EXT: - continue; - - case ST_CODE: - symname = bufp->name.n_strx + stringtab; - ms_type = mst_file_text; - bufp->symbol_value += text_offset; - bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); - - check_strange_names: - /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local - label prefixes for stabs, constant data, etc. So we need - only filter out L$ symbols which are left in due to - limitations in how GAS generates SOM relocations. - - When linking in the HPUX C-library the HP linker has - the nasty habit of placing section symbols from the literal - subspaces in the middle of the program's text. Filter - those out as best we can. Check for first and last character - being '$'. - - And finally, the newer HP compilers emit crud like $PIC_foo$N - in some circumstance (PIC code I guess). It's also claimed - that they emit D$ symbols too. What stupidity. */ - if ((symname[0] == 'L' && symname[1] == '$') - || (symname[0] == '$' && symname[strlen (symname) - 1] == '$') - || (symname[0] == 'D' && symname[1] == '$') - || (strncmp (symname, "$PIC", 4) == 0)) - continue; - break; - - case ST_PRI_PROG: - case ST_SEC_PROG: - case ST_MILLICODE: - symname = bufp->name.n_strx + stringtab; - ms_type = mst_file_text; - bufp->symbol_value += text_offset; - bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); - break; - - case ST_ENTRY: - symname = bufp->name.n_strx + stringtab; - /* For a dynamic executable, ST_ENTRY symbols are - the stubs, while the ST_CODE symbol is the real - function. */ - if (dynamic) - ms_type = mst_solib_trampoline; - else - ms_type = mst_file_text; - bufp->symbol_value += text_offset; - bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); - break; - - case ST_STUB: - symname = bufp->name.n_strx + stringtab; - ms_type = mst_solib_trampoline; - bufp->symbol_value += text_offset; - bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); - break; - - - case ST_DATA: - symname = bufp->name.n_strx + stringtab; - bufp->symbol_value += data_offset; - ms_type = mst_file_data; - goto check_strange_names; - - default: - continue; - } - break; - - /* This can happen for common symbols when -E is passed to the - final link. No idea _why_ that would make the linker force - common symbols to have an SS_UNSAT scope, but it does. - - This also happens for weak symbols, but their type is - ST_DATA. */ - case SS_UNSAT: - switch (bufp->symbol_type) - { - case ST_STORAGE: - case ST_DATA: - symname = bufp->name.n_strx + stringtab; - bufp->symbol_value += data_offset; - ms_type = mst_data; - break; - - default: - continue; - } - break; - - default: - continue; - } - - if (bufp->name.n_strx > obj_som_stringtab_size (abfd)) - error ("Invalid symbol data; bad HP string table offset: %d", - bufp->name.n_strx); - - prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type, - objfile); - } -} - -/* Scan and build partial symbols for a symbol file. - We have been initialized by a call to som_symfile_init, which - currently does nothing. - - SECTION_OFFSETS is a set of offsets to apply to relocate the symbols - in each section. This is ignored, as it isn't needed for SOM. - - MAINLINE is true if we are reading the main symbol - table (as opposed to a shared lib or dynamically loaded file). - - This function only does the minimum work necessary for letting the - user "name" things symbolically; it does not read the entire symtab. - Instead, it reads the external and static symbols and puts them in partial - symbol tables. When more extensive information is requested of a - file, the corresponding partial symbol table is mutated into a full - fledged symbol table by going back and reading the symbols - for real. - - We look for sections with specific names, to tell us what debug - format to look for: FIXME!!! - - somstab_build_psymtabs() handles STABS symbols. - - Note that SOM files have a "minimal" symbol table, which is vaguely - reminiscent of a COFF symbol table, but has only the minimal information - necessary for linking. We process this also, and use the information to - build gdb's minimal symbol table. This gives us some minimal debugging - capability even for files compiled without -g. */ - -static void -som_symfile_read (struct objfile *objfile, int mainline) -{ - bfd *abfd = objfile->obfd; - struct cleanup *back_to; - - do_pxdb (symfile_bfd_open (objfile->name)); - - init_minimal_symbol_collection (); - back_to = make_cleanup_discard_minimal_symbols (); - - /* Read in the import list and the export list. Currently - the export list isn't used; the import list is used in - hp-symtab-read.c to handle static vars declared in other - shared libraries. */ - init_import_symbols (objfile); -#if 0 /* Export symbols not used today 1997-08-05 */ - init_export_symbols (objfile); -#else - objfile->export_list = NULL; - objfile->export_list_size = 0; -#endif - - /* Process the normal SOM symbol table first. - This reads in the DNTT and string table, but doesn't - actually scan the DNTT. It does scan the linker symbol - table and thus build up a "minimal symbol table". */ - - som_symtab_read (abfd, objfile, objfile->section_offsets); - - /* Now read information from the stabs debug sections. - This is a no-op for SOM. - Perhaps it is intended for some kind of mixed STABS/SOM - situation? */ - stabsect_build_psymtabs (objfile, mainline, - "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$"); - - /* Now read the native debug information. - This builds the psymtab. This used to be done via a scan of - the DNTT, but is now done via the PXDB-built quick-lookup tables - together with a scan of the GNTT. See hp-psymtab-read.c. */ - hpread_build_psymtabs (objfile, mainline); - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. - Further symbol-reading is done incrementally, file-by-file, - in a step known as "psymtab-to-symtab" expansion. hp-symtab-read.c - contains the code to do the actual DNTT scanning and symtab building. */ - install_minimal_symbols (objfile); - - /* Force hppa-tdep.c to re-read the unwind descriptors. */ - objfile->obj_private = NULL; - do_cleanups (back_to); -} - -/* Initialize anything that needs initializing when a completely new symbol - file is specified (not just adding some symbols from another file, e.g. a - shared library). - - We reinitialize buildsym, since we may be reading stabs from a SOM file. */ - -static void -som_new_init (struct objfile *ignore) -{ - stabsread_new_init (); - buildsym_new_init (); -} - -/* Perform any local cleanups required when we are done with a particular - objfile. I.E, we are in the process of discarding all symbol information - for an objfile, freeing up all memory held for it, and unlinking the - objfile struct from the global list of known objfiles. */ - -static void -som_symfile_finish (struct objfile *objfile) -{ - if (objfile->sym_stab_info != NULL) - { - xmfree (objfile->md, objfile->sym_stab_info); - } - hpread_symfile_finish (objfile); -} - -/* SOM specific initialization routine for reading symbols. */ - -static void -som_symfile_init (struct objfile *objfile) -{ - /* SOM objects may be reordered, so set OBJF_REORDERED. If we - find this causes a significant slowdown in gdb then we could - set it in the debug symbol readers only when necessary. */ - objfile->flags |= OBJF_REORDERED; - hpread_symfile_init (objfile); -} - -/* SOM specific parsing routine for section offsets. - - Plain and simple for now. */ - -static void -som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs) -{ - int i; - CORE_ADDR text_addr; - - objfile->num_sections = SECT_OFF_MAX; - objfile->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS); - - /* FIXME: ezannoni 2000-04-20 The section names in SOM are not - .text, .data, etc, but $TEXT$, $DATA$,... We should initialize - SET_OFF_* from bfd. (See default_symfile_offsets()). But I don't - know the correspondence between SOM sections and GDB's idea of - section names. So for now we default to what is was before these - changes.*/ - objfile->sect_index_text = 0; - objfile->sect_index_data = 1; - objfile->sect_index_bss = 2; - objfile->sect_index_rodata = 3; - - /* First see if we're a shared library. If so, get the section - offsets from the library, else get them from addrs. */ - if (!som_solib_section_offsets (objfile, objfile->section_offsets)) - { - /* Note: Here is OK to compare with ".text" because this is the - name that gdb itself gives to that section, not the SOM - name. */ - for (i = 0; i < SECT_OFF_MAX && addrs->other[i].name; i++) - if (strcmp (addrs->other[i].name, ".text") == 0) - break; - text_addr = addrs->other[i].addr; - - for (i = 0; i < SECT_OFF_MAX; i++) - (objfile->section_offsets)->offsets[i] = text_addr; - } -} - -/* Read in and initialize the SOM import list which is present - for all executables and shared libraries. The import list - consists of the symbols that are referenced in OBJFILE but - not defined there. (Variables that are imported are dealt - with as "loc_indirect" vars.) - Return value = number of import symbols read in. */ -int -init_import_symbols (struct objfile *objfile) -{ - unsigned int import_list; - unsigned int import_list_size; - unsigned int string_table; - unsigned int string_table_size; - char *string_buffer; - register int i; - register int j; - register int k; - asection *text_section; /* section handle */ - unsigned int dl_header[12]; /* SOM executable header */ - - /* A struct for an entry in the SOM import list */ - typedef struct - { - int name; /* index into the string table */ - short dont_care1; /* we don't use this */ - unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */ - unsigned int reserved2:8; /* not used */ - } - SomImportEntry; - - /* We read 100 entries in at a time from the disk file. */ -#define SOM_READ_IMPORTS_NUM 100 -#define SOM_READ_IMPORTS_CHUNK_SIZE (sizeof (SomImportEntry) * SOM_READ_IMPORTS_NUM) - SomImportEntry buffer[SOM_READ_IMPORTS_NUM]; - - /* Initialize in case we error out */ - objfile->import_list = NULL; - objfile->import_list_size = 0; - - /* It doesn't work, for some reason, to read in space $TEXT$; - the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */ - text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$"); - if (!text_section) - return 0; - /* Get the SOM executable header */ - bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int)); - - /* Check header version number for 10.x HP-UX */ - /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912. - FIXME: Change for future HP-UX releases and mods to the SOM executable format */ - if (dl_header[0] != 93092112) - return 0; - - import_list = dl_header[4]; - import_list_size = dl_header[5]; - if (!import_list_size) - return 0; - string_table = dl_header[10]; - string_table_size = dl_header[11]; - if (!string_table_size) - return 0; - - /* Suck in SOM string table */ - string_buffer = (char *) xmalloc (string_table_size); - bfd_get_section_contents (objfile->obfd, text_section, string_buffer, - string_table, string_table_size); - - /* Allocate import list in the psymbol obstack; this has nothing - to do with psymbols, just a matter of convenience. We want the - import list to be freed when the objfile is deallocated */ - objfile->import_list - = (ImportEntry *) obstack_alloc (&objfile->psymbol_obstack, - import_list_size * sizeof (ImportEntry)); - - /* Read in the import entries, a bunch at a time */ - for (j = 0, k = 0; - j < (import_list_size / SOM_READ_IMPORTS_NUM); - j++) - { - bfd_get_section_contents (objfile->obfd, text_section, buffer, - import_list + j * SOM_READ_IMPORTS_CHUNK_SIZE, - SOM_READ_IMPORTS_CHUNK_SIZE); - for (i = 0; i < SOM_READ_IMPORTS_NUM; i++, k++) - { - if (buffer[i].type != (unsigned char) 0) - { - objfile->import_list[k] - = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1); - strcpy (objfile->import_list[k], string_buffer + buffer[i].name); - /* Some day we might want to record the type and other information too */ - } - else /* null type */ - objfile->import_list[k] = NULL; - - } - } - - /* Get the leftovers */ - if (k < import_list_size) - bfd_get_section_contents (objfile->obfd, text_section, buffer, - import_list + k * sizeof (SomImportEntry), - (import_list_size - k) * sizeof (SomImportEntry)); - for (i = 0; k < import_list_size; i++, k++) - { - if (buffer[i].type != (unsigned char) 0) - { - objfile->import_list[k] - = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1); - strcpy (objfile->import_list[k], string_buffer + buffer[i].name); - /* Some day we might want to record the type and other information too */ - } - else - objfile->import_list[k] = NULL; - } - - objfile->import_list_size = import_list_size; - xfree (string_buffer); - return import_list_size; -} - -/* Read in and initialize the SOM export list which is present - for all executables and shared libraries. The import list - consists of the symbols that are referenced in OBJFILE but - not defined there. (Variables that are imported are dealt - with as "loc_indirect" vars.) - Return value = number of import symbols read in. */ -int -init_export_symbols (struct objfile *objfile) -{ - unsigned int export_list; - unsigned int export_list_size; - unsigned int string_table; - unsigned int string_table_size; - char *string_buffer; - register int i; - register int j; - register int k; - asection *text_section; /* section handle */ - unsigned int dl_header[12]; /* SOM executable header */ - - /* A struct for an entry in the SOM export list */ - typedef struct - { - int next; /* for hash table use -- we don't use this */ - int name; /* index into string table */ - int value; /* offset or plabel */ - int dont_care1; /* not used */ - unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */ - char dont_care2; /* not used */ - short dont_care3; /* not used */ - } - SomExportEntry; - - /* We read 100 entries in at a time from the disk file. */ -#define SOM_READ_EXPORTS_NUM 100 -#define SOM_READ_EXPORTS_CHUNK_SIZE (sizeof (SomExportEntry) * SOM_READ_EXPORTS_NUM) - SomExportEntry buffer[SOM_READ_EXPORTS_NUM]; - - /* Initialize in case we error out */ - objfile->export_list = NULL; - objfile->export_list_size = 0; - - /* It doesn't work, for some reason, to read in space $TEXT$; - the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */ - text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$"); - if (!text_section) - return 0; - /* Get the SOM executable header */ - bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int)); - - /* Check header version number for 10.x HP-UX */ - /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912. - FIXME: Change for future HP-UX releases and mods to the SOM executable format */ - if (dl_header[0] != 93092112) - return 0; - - export_list = dl_header[8]; - export_list_size = dl_header[9]; - if (!export_list_size) - return 0; - string_table = dl_header[10]; - string_table_size = dl_header[11]; - if (!string_table_size) - return 0; - - /* Suck in SOM string table */ - string_buffer = (char *) xmalloc (string_table_size); - bfd_get_section_contents (objfile->obfd, text_section, string_buffer, - string_table, string_table_size); - - /* Allocate export list in the psymbol obstack; this has nothing - to do with psymbols, just a matter of convenience. We want the - export list to be freed when the objfile is deallocated */ - objfile->export_list - = (ExportEntry *) obstack_alloc (&objfile->psymbol_obstack, - export_list_size * sizeof (ExportEntry)); - - /* Read in the export entries, a bunch at a time */ - for (j = 0, k = 0; - j < (export_list_size / SOM_READ_EXPORTS_NUM); - j++) - { - bfd_get_section_contents (objfile->obfd, text_section, buffer, - export_list + j * SOM_READ_EXPORTS_CHUNK_SIZE, - SOM_READ_EXPORTS_CHUNK_SIZE); - for (i = 0; i < SOM_READ_EXPORTS_NUM; i++, k++) - { - if (buffer[i].type != (unsigned char) 0) - { - objfile->export_list[k].name - = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1); - strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name); - objfile->export_list[k].address = buffer[i].value; - /* Some day we might want to record the type and other information too */ - } - else - /* null type */ - { - objfile->export_list[k].name = NULL; - objfile->export_list[k].address = 0; - } - } - } - - /* Get the leftovers */ - if (k < export_list_size) - bfd_get_section_contents (objfile->obfd, text_section, buffer, - export_list + k * sizeof (SomExportEntry), - (export_list_size - k) * sizeof (SomExportEntry)); - for (i = 0; k < export_list_size; i++, k++) - { - if (buffer[i].type != (unsigned char) 0) - { - objfile->export_list[k].name - = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1); - strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name); - /* Some day we might want to record the type and other information too */ - objfile->export_list[k].address = buffer[i].value; - } - else - { - objfile->export_list[k].name = NULL; - objfile->export_list[k].address = 0; - } - } - - objfile->export_list_size = export_list_size; - xfree (string_buffer); - return export_list_size; -} - - - -/* Register that we are able to handle SOM object file formats. */ - -static struct sym_fns som_sym_fns = -{ - bfd_target_som_flavour, - som_new_init, /* sym_new_init: init anything gbl to entire symtab */ - som_symfile_init, /* sym_init: read initial info, setup for sym_read() */ - som_symfile_read, /* sym_read: read a symbol file into symtab */ - som_symfile_finish, /* sym_finish: finished with file, cleanup */ - som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_somread (void) -{ - add_symtab_fns (&som_sym_fns); -} diff --git a/contrib/gdb/gdb/somsolib.c b/contrib/gdb/gdb/somsolib.c deleted file mode 100644 index d623e4b76db..00000000000 --- a/contrib/gdb/gdb/somsolib.c +++ /dev/null @@ -1,1616 +0,0 @@ -/* Handle HP SOM shared libraries for GDB, the GNU Debugger. - Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Written by the Center for Software Science at the Univerity of Utah - and by Cygnus Support. */ - - -#include "defs.h" - -#include "frame.h" -#include "bfd.h" -#include "som.h" -#include "libhppa.h" -#include "gdbcore.h" -#include "symtab.h" -#include "breakpoint.h" -#include "symfile.h" -#include "objfiles.h" -#include "inferior.h" -#include "gdb-stabs.h" -#include "gdb_stat.h" -#include "gdbcmd.h" -#include "assert.h" -#include "language.h" -#include "regcache.h" - -#include - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -/* Uncomment this to turn on some debugging output. - */ - -/* #define SOLIB_DEBUG - */ - -/* Defined in exec.c; used to prevent dangling pointer bug. - */ -extern struct target_ops exec_ops; - -/* This lives in hppa-tdep.c. */ -extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc); - -/* These ought to be defined in some public interface, but aren't. They - define the meaning of the various bits in the distinguished __dld_flags - variable that is declared in every debuggable a.out on HP-UX, and that - is shared between the debugger and the dynamic linker. - */ -#define DLD_FLAGS_MAPPRIVATE 0x1 -#define DLD_FLAGS_HOOKVALID 0x2 -#define DLD_FLAGS_LISTVALID 0x4 -#define DLD_FLAGS_BOR_ENABLE 0x8 - -/* TODO: - - * Most of this code should work for hp300 shared libraries. Does - anyone care enough to weed out any SOM-isms. - - * Support for hpux8 dynamic linker. */ - -/* The basic structure which describes a dynamically loaded object. This - data structure is private to the dynamic linker and isn't found in - any HPUX include file. */ - -struct som_solib_mapped_entry - { - /* The name of the library. */ - char *name; - - /* Version of this structure (it is expected to change again in hpux10). */ - unsigned char struct_version; - - /* Binding mode for this library. */ - unsigned char bind_mode; - - /* Version of this library. */ - short library_version; - - /* Start of text address, - * link-time text location (length of text area), - * end of text address. */ - CORE_ADDR text_addr; - CORE_ADDR text_link_addr; - CORE_ADDR text_end; - - /* Start of data, start of bss and end of data. */ - CORE_ADDR data_start; - CORE_ADDR bss_start; - CORE_ADDR data_end; - - /* Value of linkage pointer (%r19). */ - CORE_ADDR got_value; - - /* Next entry. */ - struct som_solib_mapped_entry *next; - - /* There are other fields, but I don't have information as to what is - contained in them. */ - - /* For versions from HPUX-10.30 and up */ - - /* Address in target of offset from thread-local register of - * start of this thread's data. I.e., the first thread-local - * variable in this shared library starts at *(tsd_start_addr) - * from that area pointed to by cr27 (mpsfu_hi). - * - * We do the indirection as soon as we read it, so from then - * on it's the offset itself. - */ - CORE_ADDR tsd_start_addr; - - /* Following this are longwords holding: - - * ?, ?, ?, ptr to -1, ptr to-1, ptr to lib name (leaf name), - * ptr to __data_start, ptr to __data_end - */ - - - }; - -/* A structure to keep track of all the known shared objects. */ -struct so_list - { - struct som_solib_mapped_entry som_solib; - struct objfile *objfile; - bfd *abfd; - struct section_table *sections; - struct section_table *sections_end; -/* elz: added this field to store the address in target space (in the - library) of the library descriptor (handle) which we read into - som_solib_mapped_entry structure */ - CORE_ADDR solib_addr; - struct so_list *next; - - }; - -static struct so_list *so_list_head; - - -/* This is the cumulative size in bytes of the symbol tables of all - shared objects on the so_list_head list. (When we say size, here - we mean of the information before it is brought into memory and - potentially expanded by GDB.) When adding a new shlib, this value - is compared against the threshold size, held by auto_solib_limit - (in megabytes). If adding symbols for the new shlib would cause - the total size to exceed the threshold, then the new shlib's - symbols are not loaded. */ -static LONGEST som_solib_total_st_size; - -/* When the threshold is reached for any shlib, we refuse to add - symbols for subsequent shlibs, even if those shlibs' symbols would - be small enough to fit under the threshold. (Although this may - result in one, early large shlib preventing the loading of later, - smalller shlibs' symbols, it allows us to issue one informational - message. The alternative, to issue a message for each shlib whose - symbols aren't loaded, could be a big annoyance where the threshold - is exceeded due to a very large number of shlibs.) - */ -static int som_solib_st_size_threshold_exceeded; - -/* These addresses should be filled in by som_solib_create_inferior_hook. - They are also used elsewhere in this module. - */ -typedef struct - { - CORE_ADDR address; - struct unwind_table_entry *unwind; - } -addr_and_unwind_t; - -/* When adding fields, be sure to clear them in _initialize_som_solib. */ -static struct - { - boolean is_valid; - addr_and_unwind_t hook; - addr_and_unwind_t hook_stub; - addr_and_unwind_t load; - addr_and_unwind_t load_stub; - addr_and_unwind_t unload; - addr_and_unwind_t unload2; - addr_and_unwind_t unload_stub; - } -dld_cache; - - - -static void som_sharedlibrary_info_command (char *, int); - -static void som_solib_sharedlibrary_command (char *, int); - -static LONGEST -som_solib_sizeof_symbol_table (char *filename) -{ - bfd *abfd; - int desc; - char *absolute_name; - LONGEST st_size = (LONGEST) 0; - asection *sect; - - /* We believe that filename was handed to us by the dynamic linker, and - is therefore always an absolute path. - */ - desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, 0, &absolute_name); - if (desc < 0) - { - perror_with_name (filename); - } - filename = absolute_name; - - abfd = bfd_fdopenr (filename, gnutarget, desc); - if (!abfd) - { - close (desc); - make_cleanup (xfree, filename); - error ("\"%s\": can't open to read symbols: %s.", filename, - bfd_errmsg (bfd_get_error ())); - } - - if (!bfd_check_format (abfd, bfd_object)) /* Reads in section info */ - { - bfd_close (abfd); /* This also closes desc */ - make_cleanup (xfree, filename); - error ("\"%s\": can't read symbols: %s.", filename, - bfd_errmsg (bfd_get_error ())); - } - - /* Sum the sizes of the various sections that compose debug info. */ - - /* This contains non-DOC information. */ - sect = bfd_get_section_by_name (abfd, "$DEBUG$"); - if (sect) - st_size += (LONGEST) bfd_section_size (abfd, sect); - - /* This contains DOC information. */ - sect = bfd_get_section_by_name (abfd, "$PINFO$"); - if (sect) - st_size += (LONGEST) bfd_section_size (abfd, sect); - - bfd_close (abfd); /* This also closes desc */ - xfree (filename); - - /* Unfortunately, just summing the sizes of various debug info - sections isn't a very accurate measurement of how much heap - space the debugger will need to hold them. It also doesn't - account for space needed by linker (aka "minimal") symbols. - - Anecdotal evidence suggests that just summing the sizes of - debug-info-related sections understates the heap space needed - to represent it internally by about an order of magnitude. - - Since it's not exactly brain surgery we're doing here, rather - than attempt to more accurately measure the size of a shlib's - symbol table in GDB's heap, we'll just apply a 10x fudge- - factor to the debug info sections' size-sum. No, this doesn't - account for minimal symbols in non-debuggable shlibs. But it - all roughly washes out in the end. - */ - return st_size * (LONGEST) 10; -} - - -static void -som_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty, - CORE_ADDR text_addr) -{ - obj_private_data_t *obj_private; - struct obj_section *s; - - so->objfile = symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED); - so->abfd = so->objfile->obfd; - - /* syms_from_objfile has bizarre section offset code, - so I do my own right here. */ - for (s = so->objfile->sections; s < so->objfile->sections_end; s++) - { - flagword aflag = bfd_get_section_flags(so->abfd, s->the_bfd_section); - if (aflag & SEC_CODE) - { - s->addr += so->som_solib.text_addr - so->som_solib.text_link_addr; - s->endaddr += so->som_solib.text_addr - so->som_solib.text_link_addr; - } - else if (aflag & SEC_DATA) - { - s->addr += so->som_solib.data_start; - s->endaddr += so->som_solib.data_start; - } - else - ; - } - - /* Mark this as a shared library and save private data. - */ - so->objfile->flags |= OBJF_SHARED; - - if (so->objfile->obj_private == NULL) - { - obj_private = (obj_private_data_t *) - obstack_alloc (&so->objfile->psymbol_obstack, - sizeof (obj_private_data_t)); - obj_private->unwind_info = NULL; - obj_private->so_info = NULL; - so->objfile->obj_private = (PTR) obj_private; - } - - obj_private = (obj_private_data_t *) so->objfile->obj_private; - obj_private->so_info = so; - - if (!bfd_check_format (so->abfd, bfd_object)) - { - error ("\"%s\": not in executable format: %s.", - name, bfd_errmsg (bfd_get_error ())); - } -} - - -static void -som_solib_load_symbols (struct so_list *so, char *name, int from_tty, - CORE_ADDR text_addr, struct target_ops *target) -{ - struct section_table *p; - int status; - char buf[4]; - CORE_ADDR presumed_data_start; - -#ifdef SOLIB_DEBUG - printf ("--Adding symbols for shared library \"%s\"\n", name); -#endif - - som_solib_add_solib_objfile (so, name, from_tty, text_addr); - - /* Now we need to build a section table for this library since - we might be debugging a core file from a dynamically linked - executable in which the libraries were not privately mapped. */ - if (build_section_table (so->abfd, - &so->sections, - &so->sections_end)) - { - error ("Unable to build section table for shared library\n."); - return; - } - - /* Relocate all the sections based on where they got loaded. */ - for (p = so->sections; p < so->sections_end; p++) - { - if (p->the_bfd_section->flags & SEC_CODE) - { - p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); - p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); - } - else if (p->the_bfd_section->flags & SEC_DATA) - { - p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); - p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); - } - } - - /* Now see if we need to map in the text and data for this shared - library (for example debugging a core file which does not use - private shared libraries.). - - Carefully peek at the first text address in the library. If the - read succeeds, then the libraries were privately mapped and were - included in the core dump file. - - If the peek failed, then the libraries were not privately mapped - and are not in the core file, we'll have to read them in ourselves. */ - status = target_read_memory (text_addr, buf, 4); - if (status != 0) - { - int old, new; - - new = so->sections_end - so->sections; - - old = target_resize_to_sections (target, new); - - /* Copy over the old data before it gets clobbered. */ - memcpy ((char *) (target->to_sections + old), - so->sections, - ((sizeof (struct section_table)) * new)); - } -} - - -/* Add symbols from shared libraries into the symtab list, unless the - size threshold specified by auto_solib_limit (in megabytes) would - be exceeded. */ - -void -som_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) -{ - struct minimal_symbol *msymbol; - struct so_list *so_list_tail; - CORE_ADDR addr; - asection *shlib_info; - int status; - unsigned int dld_flags; - char buf[4], *re_err; - int threshold_warning_given = 0; - - /* First validate our arguments. */ - if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL) - { - error ("Invalid regexp: %s", re_err); - } - - /* If we're debugging a core file, or have attached to a running - process, then som_solib_create_inferior_hook will not have been - called. - - We need to first determine if we're dealing with a dynamically - linked executable. If not, then return without an error or warning. - - We also need to examine __dld_flags to determine if the shared library - list is valid and to determine if the libraries have been privately - mapped. */ - if (symfile_objfile == NULL) - return; - - /* First see if the objfile was dynamically linked. */ - shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$"); - if (!shlib_info) - return; - - /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */ - if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) - return; - - msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); - if (msymbol == NULL) - { - error ("Unable to find __dld_flags symbol in object file.\n"); - return; - } - - addr = SYMBOL_VALUE_ADDRESS (msymbol); - /* Read the current contents. */ - status = target_read_memory (addr, buf, 4); - if (status != 0) - { - error ("Unable to read __dld_flags\n"); - return; - } - dld_flags = extract_unsigned_integer (buf, 4); - - /* __dld_list may not be valid. If not, then we punt, warning the user if - we were called as a result of the add-symfile command. - */ - if ((dld_flags & DLD_FLAGS_LISTVALID) == 0) - { - if (from_tty) - error ("__dld_list is not valid according to __dld_flags.\n"); - return; - } - - /* If the libraries were not mapped private, warn the user. */ - if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0) - warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n"); - - msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL); - if (!msymbol) - { - /* Older crt0.o files (hpux8) don't have __dld_list as a symbol, - but the data is still available if you know where to look. */ - msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); - if (!msymbol) - { - error ("Unable to find dynamic library list.\n"); - return; - } - addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8; - } - else - addr = SYMBOL_VALUE_ADDRESS (msymbol); - - status = target_read_memory (addr, buf, 4); - if (status != 0) - { - error ("Unable to find dynamic library list.\n"); - return; - } - - addr = extract_unsigned_integer (buf, 4); - - /* If addr is zero, then we're using an old dynamic loader which - doesn't maintain __dld_list. We'll have to use a completely - different approach to get shared library information. */ - if (addr == 0) - goto old_dld; - - /* Using the information in __dld_list is the preferred method - to get at shared library information. It doesn't depend on - any functions in /opt/langtools/lib/end.o and has a chance of working - with hpux10 when it is released. */ - status = target_read_memory (addr, buf, 4); - if (status != 0) - { - error ("Unable to find dynamic library list.\n"); - return; - } - - /* addr now holds the address of the first entry in the dynamic - library list. */ - addr = extract_unsigned_integer (buf, 4); - - /* Now that we have a pointer to the dynamic library list, walk - through it and add the symbols for each library. */ - - so_list_tail = so_list_head; - /* Find the end of the list of shared objects. */ - while (so_list_tail && so_list_tail->next) - so_list_tail = so_list_tail->next; - -#ifdef SOLIB_DEBUG - printf ("--About to read shared library list data\n"); -#endif - - /* "addr" will always point to the base of the - * current data entry describing the current - * shared library. - */ - while (1) - { - CORE_ADDR name_addr, text_addr; - unsigned int name_len; - char *name; - struct so_list *new_so; - struct so_list *so_list = so_list_head; - struct stat statbuf; - LONGEST st_size; - int is_main_program; - - if (addr == 0) - break; - - /* Get a pointer to the name of this library. */ - status = target_read_memory (addr, buf, 4); - if (status != 0) - goto err; - - name_addr = extract_unsigned_integer (buf, 4); - name_len = 0; - while (1) - { - target_read_memory (name_addr + name_len, buf, 1); - if (status != 0) - goto err; - - name_len++; - if (*buf == '\0') - break; - } - name = alloca (name_len); - status = target_read_memory (name_addr, name, name_len); - if (status != 0) - goto err; - - /* See if we've already loaded something with this name. */ - while (so_list) - { - if (!strcmp (so_list->som_solib.name, name)) - break; - so_list = so_list->next; - } - - /* See if the file exists. If not, give a warning, but don't - die. */ - status = stat (name, &statbuf); - if (status == -1) - { - warning ("Can't find file %s referenced in dld_list.", name); - - status = target_read_memory (addr + 36, buf, 4); - if (status != 0) - goto err; - - addr = (CORE_ADDR) extract_unsigned_integer (buf, 4); - continue; - } - - /* If we've already loaded this one or it's the main program, skip it. */ - is_main_program = (strcmp (name, symfile_objfile->name) == 0); - if (so_list || is_main_program) - { - /* This is the "next" pointer in the strcuture. - */ - status = target_read_memory (addr + 36, buf, 4); - if (status != 0) - goto err; - - addr = (CORE_ADDR) extract_unsigned_integer (buf, 4); - - /* Record the main program's symbol table size. */ - if (is_main_program && !so_list) - { - st_size = som_solib_sizeof_symbol_table (name); - som_solib_total_st_size += st_size; - } - - /* Was this a shlib that we noted but didn't load the symbols for? - If so, were we invoked this time from the command-line, via - a 'sharedlibrary' or 'add-symbol-file' command? If yes to - both, we'd better load the symbols this time. - */ - if (from_tty && so_list && !is_main_program && (so_list->objfile == NULL)) - som_solib_load_symbols (so_list, - name, - from_tty, - so_list->som_solib.text_addr, - target); - - continue; - } - - name = obsavestring (name, name_len - 1, - &symfile_objfile->symbol_obstack); - - status = target_read_memory (addr + 8, buf, 4); - if (status != 0) - goto err; - - text_addr = extract_unsigned_integer (buf, 4); - - new_so = (struct so_list *) xmalloc (sizeof (struct so_list)); - memset ((char *) new_so, 0, sizeof (struct so_list)); - if (so_list_head == NULL) - { - so_list_head = new_so; - so_list_tail = new_so; - } - else - { - so_list_tail->next = new_so; - so_list_tail = new_so; - } - - /* Fill in all the entries in GDB's shared library list. - */ - - new_so->solib_addr = addr; - new_so->som_solib.name = name; - status = target_read_memory (addr + 4, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1); - new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1); - /* Following is "high water mark", highest version number - * seen, rather than plain version number. - */ - new_so->som_solib.library_version = extract_unsigned_integer (buf, 2); - new_so->som_solib.text_addr = text_addr; - - /* Q: What about longword at "addr + 8"? - * A: It's read above, out of order, into "text_addr". - */ - - status = target_read_memory (addr + 12, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4); - - status = target_read_memory (addr + 16, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.text_end = extract_unsigned_integer (buf, 4); - - status = target_read_memory (addr + 20, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.data_start = extract_unsigned_integer (buf, 4); - - status = target_read_memory (addr + 24, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4); - - status = target_read_memory (addr + 28, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.data_end = extract_unsigned_integer (buf, 4); - - status = target_read_memory (addr + 32, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.got_value = extract_unsigned_integer (buf, 4); - - status = target_read_memory (addr + 36, buf, 4); - if (status != 0) - goto err; - - new_so->som_solib.next = - address_to_host_pointer (extract_unsigned_integer (buf, 4)); - - /* Note that we don't re-set "addr" to the next pointer - * until after we've read the trailing data. - */ - - status = target_read_memory (addr + 40, buf, 4); - new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4); - if (status != 0) - goto err; - - /* Now indirect via that value! - */ - status = target_read_memory (new_so->som_solib.tsd_start_addr, buf, 4); - new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4); - if (status != 0) - goto err; -#ifdef SOLIB_DEBUG - printf ("\n+ library \"%s\" is described at 0x%x\n", name, addr); - printf (" 'version' is %d\n", new_so->som_solib.struct_version); - printf (" 'bind_mode' is %d\n", new_so->som_solib.bind_mode); - printf (" 'library_version' is %d\n", new_so->som_solib.library_version); - printf (" 'text_addr' is 0x%x\n", new_so->som_solib.text_addr); - printf (" 'text_link_addr' is 0x%x\n", new_so->som_solib.text_link_addr); - printf (" 'text_end' is 0x%x\n", new_so->som_solib.text_end); - printf (" 'data_start' is 0x%x\n", new_so->som_solib.data_start); - printf (" 'bss_start' is 0x%x\n", new_so->som_solib.bss_start); - printf (" 'data_end' is 0x%x\n", new_so->som_solib.data_end); - printf (" 'got_value' is %x\n", new_so->som_solib.got_value); - printf (" 'next' is 0x%x\n", new_so->som_solib.next); - printf (" 'tsd_start_addr' is 0x%x\n", new_so->som_solib.tsd_start_addr); -#endif - - /* Go on to the next shared library descriptor. - */ - addr = (CORE_ADDR) new_so->som_solib.next; - - - - /* At this point, we have essentially hooked the shlib into the - "info share" command. However, we haven't yet loaded its - symbol table. We must now decide whether we ought to, i.e., - whether doing so would exceed the symbol table size threshold. - - If the threshold has just now been exceeded, then we'll issue - a warning message (which explains how to load symbols manually, - if the user so desires). - - If the threshold has just now or previously been exceeded, - we'll just add the shlib to the list of object files, but won't - actually load its symbols. (This is more useful than it might - sound, for it allows us to e.g., still load and use the shlibs' - unwind information for stack tracebacks.) - */ - - /* Note that we DON'T want to preclude the user from using the - add-symbol-file command! Thus, we only worry about the threshold - when we're invoked for other reasons. - */ - st_size = som_solib_sizeof_symbol_table (name); - som_solib_st_size_threshold_exceeded = - !from_tty && - auto_solib_limit > 0 && - readsyms && - ((st_size + som_solib_total_st_size) > (auto_solib_limit * (LONGEST) (1024 * 1024))); - - if (som_solib_st_size_threshold_exceeded) - { - if (!threshold_warning_given) - warning ("Symbols for some libraries have not been loaded, because\ndoing so would exceed the size threshold specified by auto-solib-limit.\nTo manually load symbols, use the 'sharedlibrary' command.\nTo raise the threshold, set auto-solib-limit to a larger value and rerun\nthe program.\n"); - threshold_warning_given = 1; - - /* We'll still make note of this shlib, even if we don't - read its symbols. This allows us to use its unwind - information well enough to know how to e.g., correctly - do a traceback from a PC within the shlib, even if we - can't symbolize those PCs... - */ - som_solib_add_solib_objfile (new_so, name, from_tty, text_addr); - continue; - } - - som_solib_total_st_size += st_size; - - /* This fills in new_so->objfile, among others. */ - som_solib_load_symbols (new_so, name, from_tty, text_addr, target); - } - -#ifdef SOLIB_DEBUG - printf ("--Done reading shared library data\n"); -#endif - - /* Getting new symbols may change our opinion about what is - frameless. */ - reinit_frame_cache (); - return; - -old_dld: - error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n"); - return; - -err: - error ("Error while reading dynamic library list.\n"); - return; -} - - -/* This hook gets called just before the first instruction in the - inferior process is executed. - - This is our opportunity to set magic flags in the inferior so - that GDB can be notified when a shared library is mapped in and - to tell the dynamic linker that a private copy of the library is - needed (so GDB can set breakpoints in the library). - - __dld_flags is the location of the magic flags; as of this implementation - there are 3 flags of interest: - - bit 0 when set indicates that private copies of the libraries are needed - bit 1 when set indicates that the callback hook routine is valid - bit 2 when set indicates that the dynamic linker should maintain the - __dld_list structure when loading/unloading libraries. - - Note that shared libraries are not mapped in at this time, so we have - run the inferior until the libraries are mapped in. Typically this - means running until the "_start" is called. */ - -void -som_solib_create_inferior_hook (void) -{ - struct minimal_symbol *msymbol; - unsigned int dld_flags, status, have_endo; - asection *shlib_info; - char buf[4]; - struct objfile *objfile; - CORE_ADDR anaddr; - - /* First, remove all the solib event breakpoints. Their addresses - may have changed since the last time we ran the program. */ - remove_solib_event_breakpoints (); - - if (symfile_objfile == NULL) - return; - - /* First see if the objfile was dynamically linked. */ - shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$"); - if (!shlib_info) - return; - - /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */ - if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) - return; - - have_endo = 0; - /* Slam the pid of the process into __d_pid. - - We used to warn when this failed, but that warning is only useful - on very old HP systems (hpux9 and older). The warnings are an - annoyance to users of modern systems and foul up the testsuite as - well. As a result, the warnings have been disabled. */ - msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile); - if (msymbol == NULL) - goto keep_going; - - anaddr = SYMBOL_VALUE_ADDRESS (msymbol); - store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); - status = target_write_memory (anaddr, buf, 4); - if (status != 0) - { - warning ("Unable to write __d_pid"); - warning ("Suggest linking with /opt/langtools/lib/end.o."); - warning ("GDB will be unable to track shl_load/shl_unload calls"); - goto keep_going; - } - - /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook; - This will force the dynamic linker to call __d_trap when significant - events occur. - - Note that the above is the pre-HP-UX 9.0 behaviour. At 9.0 and above, - the dld provides an export stub named "__d_trap" as well as the - function named "__d_trap" itself, but doesn't provide "_DLD_HOOK". - We'll look first for the old flavor and then the new. - */ - msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile); - if (msymbol == NULL) - msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); - if (msymbol == NULL) - { - warning ("Unable to find _DLD_HOOK symbol in object file."); - warning ("Suggest linking with /opt/langtools/lib/end.o."); - warning ("GDB will be unable to track shl_load/shl_unload calls"); - goto keep_going; - } - anaddr = SYMBOL_VALUE_ADDRESS (msymbol); - dld_cache.hook.address = anaddr; - - /* Grrr, this might not be an export symbol! We have to find the - export stub. */ - ALL_OBJFILES (objfile) - { - struct unwind_table_entry *u; - struct minimal_symbol *msymbol2; - - /* What a crock. */ - msymbol2 = lookup_minimal_symbol_solib_trampoline (SYMBOL_NAME (msymbol), - NULL, objfile); - /* Found a symbol with the right name. */ - if (msymbol2) - { - struct unwind_table_entry *u; - /* It must be a shared library trampoline. */ - if (SYMBOL_TYPE (msymbol2) != mst_solib_trampoline) - continue; - - /* It must also be an export stub. */ - u = find_unwind_entry (SYMBOL_VALUE (msymbol2)); - if (!u || u->stub_unwind.stub_type != EXPORT) - continue; - - /* OK. Looks like the correct import stub. */ - anaddr = SYMBOL_VALUE (msymbol2); - dld_cache.hook_stub.address = anaddr; - } - } - store_unsigned_integer (buf, 4, anaddr); - - msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile); - if (msymbol == NULL) - { - warning ("Unable to find __dld_hook symbol in object file."); - warning ("Suggest linking with /opt/langtools/lib/end.o."); - warning ("GDB will be unable to track shl_load/shl_unload calls"); - goto keep_going; - } - anaddr = SYMBOL_VALUE_ADDRESS (msymbol); - status = target_write_memory (anaddr, buf, 4); - - /* Now set a shlib_event breakpoint at __d_trap so we can track - significant shared library events. */ - msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); - if (msymbol == NULL) - { - warning ("Unable to find __dld_d_trap symbol in object file."); - warning ("Suggest linking with /opt/langtools/lib/end.o."); - warning ("GDB will be unable to track shl_load/shl_unload calls"); - goto keep_going; - } - create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol)); - - /* We have all the support usually found in end.o, so we can track - shl_load and shl_unload calls. */ - have_endo = 1; - -keep_going: - - /* Get the address of __dld_flags, if no such symbol exists, then we can - not debug the shared code. */ - msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); - if (msymbol == NULL) - { - error ("Unable to find __dld_flags symbol in object file.\n"); - } - - anaddr = SYMBOL_VALUE_ADDRESS (msymbol); - - /* Read the current contents. */ - status = target_read_memory (anaddr, buf, 4); - if (status != 0) - { - error ("Unable to read __dld_flags\n"); - } - dld_flags = extract_unsigned_integer (buf, 4); - - /* Turn on the flags we care about. */ - dld_flags |= DLD_FLAGS_MAPPRIVATE; - if (have_endo) - dld_flags |= DLD_FLAGS_HOOKVALID; - store_unsigned_integer (buf, 4, dld_flags); - status = target_write_memory (anaddr, buf, 4); - if (status != 0) - { - error ("Unable to write __dld_flags\n"); - } - - /* Now find the address of _start and set a breakpoint there. - We still need this code for two reasons: - - * Not all sites have /opt/langtools/lib/end.o, so it's not always - possible to track the dynamic linker's events. - - * At this time no events are triggered for shared libraries - loaded at startup time (what a crock). */ - - msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile); - if (msymbol == NULL) - { - error ("Unable to find _start symbol in object file.\n"); - } - - anaddr = SYMBOL_VALUE_ADDRESS (msymbol); - - /* Make the breakpoint at "_start" a shared library event breakpoint. */ - create_solib_event_breakpoint (anaddr); - - /* Wipe out all knowledge of old shared libraries since their - mapping can change from one exec to another! */ - while (so_list_head) - { - struct so_list *temp; - - temp = so_list_head; - xfree (so_list_head); - so_list_head = temp->next; - } - clear_symtab_users (); -} - -/* This operation removes the "hook" between GDB and the dynamic linker, - which causes the dld to notify GDB of shared library events. - - After this operation completes, the dld will no longer notify GDB of - shared library events. To resume notifications, GDB must call - som_solib_create_inferior_hook. - - This operation does not remove any knowledge of shared libraries which - GDB may already have been notified of. - */ -void -som_solib_remove_inferior_hook (int pid) -{ - CORE_ADDR addr; - struct minimal_symbol *msymbol; - int status; - char dld_flags_buffer[TARGET_INT_BIT / TARGET_CHAR_BIT]; - unsigned int dld_flags_value; - struct cleanup *old_cleanups = save_inferior_ptid (); - - /* Ensure that we're really operating on the specified process. */ - inferior_ptid = pid_to_ptid (pid); - - /* We won't bother to remove the solib breakpoints from this process. - - In fact, on PA64 the breakpoint is hard-coded into the dld callback, - and thus we're not supposed to remove it. - - Rather, we'll merely clear the dld_flags bit that enables callbacks. - */ - msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); - - addr = SYMBOL_VALUE_ADDRESS (msymbol); - status = target_read_memory (addr, dld_flags_buffer, TARGET_INT_BIT / TARGET_CHAR_BIT); - - dld_flags_value = extract_unsigned_integer (dld_flags_buffer, - sizeof (dld_flags_value)); - - dld_flags_value &= ~DLD_FLAGS_HOOKVALID; - store_unsigned_integer (dld_flags_buffer, - sizeof (dld_flags_value), - dld_flags_value); - status = target_write_memory (addr, dld_flags_buffer, TARGET_INT_BIT / TARGET_CHAR_BIT); - - do_cleanups (old_cleanups); -} - - -/* This function creates a breakpoint on the dynamic linker hook, which - is called when e.g., a shl_load or shl_unload call is made. This - breakpoint will only trigger when a shl_load call is made. - - If filename is NULL, then loads of any dll will be caught. Else, - only loads of the file whose pathname is the string contained by - filename will be caught. - - Undefined behaviour is guaranteed if this function is called before - som_solib_create_inferior_hook. - */ -void -som_solib_create_catch_load_hook (int pid, int tempflag, char *filename, - char *cond_string) -{ - create_solib_load_event_breakpoint ("__d_trap", tempflag, filename, cond_string); -} - -/* This function creates a breakpoint on the dynamic linker hook, which - is called when e.g., a shl_load or shl_unload call is made. This - breakpoint will only trigger when a shl_unload call is made. - - If filename is NULL, then unloads of any dll will be caught. Else, - only unloads of the file whose pathname is the string contained by - filename will be caught. - - Undefined behaviour is guaranteed if this function is called before - som_solib_create_inferior_hook. - */ -void -som_solib_create_catch_unload_hook (int pid, int tempflag, char *filename, - char *cond_string) -{ - create_solib_unload_event_breakpoint ("__d_trap", tempflag, filename, cond_string); -} - -int -som_solib_have_load_event (int pid) -{ - CORE_ADDR event_kind; - - event_kind = read_register (ARG0_REGNUM); - return (event_kind == SHL_LOAD); -} - -int -som_solib_have_unload_event (int pid) -{ - CORE_ADDR event_kind; - - event_kind = read_register (ARG0_REGNUM); - return (event_kind == SHL_UNLOAD); -} - -static char * -som_solib_library_pathname (int pid) -{ - CORE_ADDR dll_handle_address; - CORE_ADDR dll_pathname_address; - struct som_solib_mapped_entry dll_descriptor; - char *p; - static char dll_pathname[1024]; - - /* Read the descriptor of this newly-loaded library. */ - dll_handle_address = read_register (ARG1_REGNUM); - read_memory (dll_handle_address, (char *) &dll_descriptor, sizeof (dll_descriptor)); - - /* We can find a pointer to the dll's pathname within the descriptor. */ - dll_pathname_address = (CORE_ADDR) dll_descriptor.name; - - /* Read the pathname, one byte at a time. */ - p = dll_pathname; - for (;;) - { - char b; - read_memory (dll_pathname_address++, (char *) &b, 1); - *p++ = b; - if (b == '\0') - break; - } - - return dll_pathname; -} - -char * -som_solib_loaded_library_pathname (int pid) -{ - if (!som_solib_have_load_event (pid)) - error ("Must have a load event to use this query"); - - return som_solib_library_pathname (pid); -} - -char * -som_solib_unloaded_library_pathname (int pid) -{ - if (!som_solib_have_unload_event (pid)) - error ("Must have an unload event to use this query"); - - return som_solib_library_pathname (pid); -} - -static void -som_solib_desire_dynamic_linker_symbols (void) -{ - struct objfile *objfile; - struct unwind_table_entry *u; - struct minimal_symbol *dld_msymbol; - - /* Do we already know the value of these symbols? If so, then - we've no work to do. - - (If you add clauses to this test, be sure to likewise update the - test within the loop.) - */ - if (dld_cache.is_valid) - return; - - ALL_OBJFILES (objfile) - { - dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile); - if (dld_msymbol != NULL) - { - dld_cache.load.address = SYMBOL_VALUE (dld_msymbol); - dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address); - } - - dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load", - NULL, - objfile); - if (dld_msymbol != NULL) - { - if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) - { - u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); - if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) - { - dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol); - dld_cache.load_stub.unwind = u; - } - } - } - - dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile); - if (dld_msymbol != NULL) - { - dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol); - dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address); - - /* ??rehrauer: I'm not sure exactly what this is, but it appears - that on some HPUX 10.x versions, there's two unwind regions to - cover the body of "shl_unload", the second being 4 bytes past - the end of the first. This is a large hack to handle that - case, but since I don't seem to have any legitimate way to - look for this thing via the symbol table... - */ - if (dld_cache.unload.unwind != NULL) - { - u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4); - if (u != NULL) - { - dld_cache.unload2.address = u->region_start; - dld_cache.unload2.unwind = u; - } - } - } - - dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload", - NULL, - objfile); - if (dld_msymbol != NULL) - { - if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) - { - u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); - if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) - { - dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol); - dld_cache.unload_stub.unwind = u; - } - } - } - - /* Did we find everything we were looking for? If so, stop. */ - if ((dld_cache.load.address != 0) - && (dld_cache.load_stub.address != 0) - && (dld_cache.unload.address != 0) - && (dld_cache.unload_stub.address != 0)) - { - dld_cache.is_valid = 1; - break; - } - } - - dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address); - dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address); - - /* We're prepared not to find some of these symbols, which is why - this function is a "desire" operation, and not a "require". - */ -} - -int -som_solib_in_dynamic_linker (int pid, CORE_ADDR pc) -{ - struct unwind_table_entry *u_pc; - - /* Are we in the dld itself? - - ??rehrauer: Large hack -- We'll assume that any address in a - shared text region is the dld's text. This would obviously - fall down if the user attached to a process, whose shlibs - weren't mapped to a (writeable) private region. However, in - that case the debugger probably isn't able to set the fundamental - breakpoint in the dld callback anyways, so this hack should be - safe. - */ - if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000) - return 1; - - /* Cache the address of some symbols that are part of the dynamic - linker, if not already known. - */ - som_solib_desire_dynamic_linker_symbols (); - - /* Are we in the dld callback? Or its export stub? */ - u_pc = find_unwind_entry (pc); - if (u_pc == NULL) - return 0; - - if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind)) - return 1; - - /* Or the interface of the dld (i.e., "shl_load" or friends)? */ - if ((u_pc == dld_cache.load.unwind) - || (u_pc == dld_cache.unload.unwind) - || (u_pc == dld_cache.unload2.unwind) - || (u_pc == dld_cache.load_stub.unwind) - || (u_pc == dld_cache.unload_stub.unwind)) - return 1; - - /* Apparently this address isn't part of the dld's text. */ - return 0; -} - - -/* Return the GOT value for the shared library in which ADDR belongs. If - ADDR isn't in any known shared library, return zero. */ - -CORE_ADDR -som_solib_get_got_by_pc (CORE_ADDR addr) -{ - struct so_list *so_list = so_list_head; - CORE_ADDR got_value = 0; - - while (so_list) - { - if (so_list->som_solib.text_addr <= addr - && so_list->som_solib.text_end > addr) - { - got_value = so_list->som_solib.got_value; - break; - } - so_list = so_list->next; - } - return got_value; -} - -/* elz: - Return the address of the handle of the shared library - in which ADDR belongs. If - ADDR isn't in any known shared library, return zero. */ -/* this function is used in hppa_fix_call_dummy in hppa-tdep.c */ - -CORE_ADDR -som_solib_get_solib_by_pc (CORE_ADDR addr) -{ - struct so_list *so_list = so_list_head; - - while (so_list) - { - if (so_list->som_solib.text_addr <= addr - && so_list->som_solib.text_end > addr) - { - break; - } - so_list = so_list->next; - } - if (so_list) - return so_list->solib_addr; - else - return 0; -} - - -int -som_solib_section_offsets (struct objfile *objfile, - struct section_offsets *offsets) -{ - struct so_list *so_list = so_list_head; - - while (so_list) - { - /* Oh what a pain! We need the offsets before so_list->objfile - is valid. The BFDs will never match. Make a best guess. */ - if (strstr (objfile->name, so_list->som_solib.name)) - { - asection *private_section; - - /* The text offset is easy. */ - offsets->offsets[SECT_OFF_TEXT (objfile)] - = (so_list->som_solib.text_addr - - so_list->som_solib.text_link_addr); - offsets->offsets[SECT_OFF_RODATA (objfile)] - = ANOFFSET (offsets, SECT_OFF_TEXT (objfile)); - - /* We should look at presumed_dp in the SOM header, but - that's not easily available. This should be OK though. */ - private_section = bfd_get_section_by_name (objfile->obfd, - "$PRIVATE$"); - if (!private_section) - { - warning ("Unable to find $PRIVATE$ in shared library!"); - offsets->offsets[SECT_OFF_DATA (objfile)] = 0; - offsets->offsets[SECT_OFF_BSS (objfile)] = 0; - return 1; - } - offsets->offsets[SECT_OFF_DATA (objfile)] - = (so_list->som_solib.data_start - private_section->vma); - offsets->offsets[SECT_OFF_BSS (objfile)] - = ANOFFSET (offsets, SECT_OFF_DATA (objfile)); - return 1; - } - so_list = so_list->next; - } - return 0; -} - -/* Dump information about all the currently loaded shared libraries. */ - -static void -som_sharedlibrary_info_command (char *ignore, int from_tty) -{ - struct so_list *so_list = so_list_head; - - if (exec_bfd == NULL) - { - printf_unfiltered ("No executable file.\n"); - return; - } - - if (so_list == NULL) - { - printf_unfiltered ("No shared libraries loaded at this time.\n"); - return; - } - - printf_unfiltered ("Shared Object Libraries\n"); - printf_unfiltered (" %-12s%-12s%-12s%-12s%-12s%-12s\n", - " flags", " tstart", " tend", " dstart", " dend", " dlt"); - while (so_list) - { - unsigned int flags; - - flags = so_list->som_solib.struct_version << 24; - flags |= so_list->som_solib.bind_mode << 16; - flags |= so_list->som_solib.library_version; - printf_unfiltered ("%s", so_list->som_solib.name); - if (so_list->objfile == NULL) - printf_unfiltered (" (symbols not loaded)"); - printf_unfiltered ("\n"); - printf_unfiltered (" %-12s", local_hex_string_custom (flags, "08l")); - printf_unfiltered ("%-12s", - local_hex_string_custom (so_list->som_solib.text_addr, "08l")); - printf_unfiltered ("%-12s", - local_hex_string_custom (so_list->som_solib.text_end, "08l")); - printf_unfiltered ("%-12s", - local_hex_string_custom (so_list->som_solib.data_start, "08l")); - printf_unfiltered ("%-12s", - local_hex_string_custom (so_list->som_solib.data_end, "08l")); - printf_unfiltered ("%-12s\n", - local_hex_string_custom (so_list->som_solib.got_value, "08l")); - so_list = so_list->next; - } -} - -static void -som_solib_sharedlibrary_command (char *args, int from_tty) -{ - dont_repeat (); - som_solib_add (args, from_tty, (struct target_ops *) 0, 1); -} - - - -char * -som_solib_address (CORE_ADDR addr) -{ - struct so_list *so = so_list_head; - - while (so) - { - /* Is this address within this shlib's text range? If so, - return the shlib's name. - */ - if ((addr >= so->som_solib.text_addr) && (addr <= so->som_solib.text_end)) - return so->som_solib.name; - - /* Nope, keep looking... */ - so = so->next; - } - - /* No, we couldn't prove that the address is within a shlib. */ - return NULL; -} - - -void -som_solib_restart (void) -{ - struct so_list *sl = so_list_head; - - /* Before the shlib info vanishes, use it to disable any breakpoints - that may still be active in those shlibs. - */ - disable_breakpoints_in_shlibs (0); - - /* Discard all the shlib descriptors. - */ - while (sl) - { - struct so_list *next_sl = sl->next; - xfree (sl); - sl = next_sl; - } - so_list_head = NULL; - - som_solib_total_st_size = (LONGEST) 0; - som_solib_st_size_threshold_exceeded = 0; - - dld_cache.is_valid = 0; - - dld_cache.hook.address = 0; - dld_cache.hook.unwind = NULL; - - dld_cache.hook_stub.address = 0; - dld_cache.hook_stub.unwind = NULL; - - dld_cache.load.address = 0; - dld_cache.load.unwind = NULL; - - dld_cache.load_stub.address = 0; - dld_cache.load_stub.unwind = NULL; - - dld_cache.unload.address = 0; - dld_cache.unload.unwind = NULL; - - dld_cache.unload2.address = 0; - dld_cache.unload2.unwind = NULL; - - dld_cache.unload_stub.address = 0; - dld_cache.unload_stub.unwind = NULL; -} - - -/* LOCAL FUNCTION - - no_shared_libraries -- handle command to explicitly discard symbols - from shared libraries. - - DESCRIPTION - - Implements the command "nosharedlibrary", which discards symbols - that have been auto-loaded from shared libraries. Symbols from - shared libraries that were added by explicit request of the user - are not discarded. Also called from remote.c. */ - -void -no_shared_libraries (char *ignored, int from_tty) -{ - /* FIXME */ -} - - -void -_initialize_som_solib (void) -{ - add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command, - "Load shared object library symbols for files matching REGEXP."); - add_info ("sharedlibrary", som_sharedlibrary_info_command, - "Status of loaded shared object libraries."); - - add_show_from_set - (add_set_cmd ("auto-solib-add", class_support, var_boolean, - (char *) &auto_solib_add, - "Set autoloading of shared library symbols.\n\ -If \"on\", symbols from all shared object libraries will be loaded\n\ -automatically when the inferior begins execution, when the dynamic linker\n\ -informs gdb that a new library has been loaded, or when attaching to the\n\ -inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("auto-solib-limit", class_support, var_zinteger, - (char *) &auto_solib_limit, - "Set threshold (in Mb) for autoloading shared library symbols.\n\ -When shared library autoloading is enabled, new libraries will be loaded\n\ -only until the total size of shared library symbols exceeds this\n\ -threshold in megabytes. Is ignored when using `sharedlibrary'.", - &setlist), - &showlist); - - /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how - much data space a process can use. We ought to be reading - MAXDSIZ and setting auto_solib_limit to some large fraction of - that value. If not that, we maybe ought to be setting it smaller - than the default for MAXDSIZ (that being 64Mb, I believe). - However, [1] this threshold is only crudely approximated rather - than actually measured, and [2] 50 Mbytes is too small for - debugging gdb itself. Thus, the arbitrary 100 figure. */ - auto_solib_limit = 100; /* Megabytes */ - - som_solib_restart (); -} - -/* Get some HPUX-specific data from a shared lib. - */ -CORE_ADDR -so_lib_thread_start_addr (struct so_list *so) -{ - return so->som_solib.tsd_start_addr; -} diff --git a/contrib/gdb/gdb/somsolib.h b/contrib/gdb/gdb/somsolib.h deleted file mode 100644 index 4b23760199c..00000000000 --- a/contrib/gdb/gdb/somsolib.h +++ /dev/null @@ -1,165 +0,0 @@ -/* HP SOM Shared library declarations for GDB, the GNU Debugger. - Copyright 1992, 1994, 1995, 1998, 1999, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Written by the Center for Software Science at the Univerity of Utah - and by Cygnus Support. */ - -/* Forward decl's for prototypes */ -struct target_ops; -struct objfile; -struct section_offsets; - -/* Called to add symbols from a shared library to gdb's symbol table. */ - -#define SOLIB_ADD(filename, from_tty, targ, readsyms) \ - som_solib_add (filename, from_tty, targ, readsyms) - -extern void som_solib_add (char *, int, struct target_ops *, int); - -extern CORE_ADDR som_solib_get_got_by_pc (CORE_ADDR); - -extern int -som_solib_section_offsets (struct objfile *, struct section_offsets *); - -/* Function to be called when the inferior starts up, to discover the names - of shared libraries that are dynamically linked, the base addresses to - which they are linked, and sufficient information to read in their symbols - at a later time. */ - -#define SOLIB_CREATE_INFERIOR_HOOK(PID) som_solib_create_inferior_hook() - -extern void som_solib_create_inferior_hook (void); - -/* Function to be called to remove the connection between debugger and - dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK. - (This operation does not remove shared library information from - the debugger, as CLEAR_SOLIB does.) - */ -#define SOLIB_REMOVE_INFERIOR_HOOK(PID) som_solib_remove_inferior_hook(PID) - -extern void som_solib_remove_inferior_hook (int); - -/* This function is called by the "catch load" command. It allows - the debugger to be notified by the dynamic linker when a specified - library file (or any library file, if filename is NULL) is loaded. - */ -#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag, filename,cond_string) \ - som_solib_create_catch_load_hook (pid, tempflag, filename, cond_string) - -extern void som_solib_create_catch_load_hook (int, int, char *, char *); - -/* This function is called by the "catch unload" command. It allows - the debugger to be notified by the dynamic linker when a specified - library file (or any library file, if filename is NULL) is unloaded. - */ -#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename, cond_string) \ - som_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string) - -extern void som_solib_create_catch_unload_hook (int, int, char *, char *); - -/* This function returns TRUE if the dynamic linker has just reported - a load of a library. - - This function must be used only when the inferior has stopped in - the dynamic linker hook, or undefined results are guaranteed. - */ -#define SOLIB_HAVE_LOAD_EVENT(pid) \ - som_solib_have_load_event (pid) - -extern int som_solib_have_load_event (int); - -/* This function returns a pointer to the string representation of the - pathname of the dynamically-linked library that has just been loaded. - - This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE, - or undefined results are guaranteed. - - This string's contents are only valid immediately after the inferior - has stopped in the dynamic linker hook, and becomes invalid as soon - as the inferior is continued. Clients should make a copy of this - string if they wish to continue the inferior and then access the string. - */ -#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ - som_solib_loaded_library_pathname (pid) - -extern char *som_solib_loaded_library_pathname (int); - -/* This function returns TRUE if the dynamic linker has just reported - an unload of a library. - - This function must be used only when the inferior has stopped in - the dynamic linker hook, or undefined results are guaranteed. - */ -#define SOLIB_HAVE_UNLOAD_EVENT(pid) \ - som_solib_have_unload_event (pid) - -extern int som_solib_have_unload_event (int); - -/* This function returns a pointer to the string representation of the - pathname of the dynamically-linked library that has just been unloaded. - - This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE, - or undefined results are guaranteed. - - This string's contents are only valid immediately after the inferior - has stopped in the dynamic linker hook, and becomes invalid as soon - as the inferior is continued. Clients should make a copy of this - string if they wish to continue the inferior and then access the string. - */ -#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ - som_solib_unloaded_library_pathname (pid) - -extern char *som_solib_unloaded_library_pathname (int); - -/* This function returns TRUE if pc is the address of an instruction that - lies within the dynamic linker (such as the event hook, or the dld - itself). - - This function must be used only when a dynamic linker event has been - caught, and the inferior is being stepped out of the hook, or undefined - results are guaranteed. - */ -#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ - som_solib_in_dynamic_linker (pid, pc) - -extern int som_solib_in_dynamic_linker (int, CORE_ADDR); - -/* This function must be called when the inferior is killed, and the program - restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard - any symbol tables. - - Presently, this functionality is not implemented. - */ -#define SOLIB_RESTART() \ - som_solib_restart () - -extern void som_solib_restart (void); - -/* If we can't set a breakpoint, and it's in a shared library, just - disable it. */ - -#define DISABLE_UNSETTABLE_BREAK(addr) (som_solib_address(addr) != NULL) - -extern char *som_solib_address (CORE_ADDR); /* somsolib.c */ - -/* If ADDR lies in a shared library, return its name. */ - -#define PC_SOLIB(addr) som_solib_address (addr) diff --git a/contrib/gdb/gdb/stop-gdb.c b/contrib/gdb/gdb/stop-gdb.c deleted file mode 100644 index ee84609664c..00000000000 --- a/contrib/gdb/gdb/stop-gdb.c +++ /dev/null @@ -1,109 +0,0 @@ -/* A client to make GDB return to command level in Mach 3. - Copyright 1992, 1993, 1994, 2000 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Authors: Jukka Virtanen and Peter Stout . - - A simple client to make GDB (versions 4.4 and later) on Mach 3 return - to the command level when it is waiting for the inferior to stop. - - Actions: Lookup the send right to the GDB message port from the - NetMsgServer. - - Send an asynchronous message with msgh_id - GDB_MESSAGE_ID_STOP to that port. - */ - -#include - -#include "defs.h" - -#include -#include -#include -#include -#include - -void -main (int argc, char **argv) -{ - kern_return_t kr; - mach_msg_header_t msg; - mach_port_t gdb_port; - char *host; - char *name; - - if (argc == 1) - argv[argc++] = GDB_DEF_NAME; - - if (argc != 2) - { - fprintf (stderr, "Usage : %s \n", argv[0]); - exit (1); - } - - /* Allow the user to specify a remote host. */ - host = strchr (argv[1], '@'); - if (host) - *(host++) = '\0'; - else - host = (char *) ""; - - name = malloc (strlen (argv[1]) + sizeof (GDB_NAME_PREFIX)); - if (name == NULL) - { - fprintf (stderr, "Unable to allocate memory for name."); - exit (1); - } - - strcpy (name, GDB_NAME_PREFIX); - strcat (name, argv[1]); - - /* Look up the GDB service port. For convenience, add the - GDB_NAME_PREFIX the argument before looking up the name. - For backwards compatibility, do it without. */ - - kr = netname_look_up (name_server_port, host, name, &gdb_port); - if (kr == NETNAME_NOT_CHECKED_IN) - kr = netname_look_up (name_server_port, host, argv[1], &gdb_port); - if (kr != KERN_SUCCESS) - { - fprintf (stderr, "Unable to lookup the GDB service port: %s.\n", - mach_error_string (kr)); - exit (1); - } - - /* Code generated by mig stub generator, with minor cleanups :-) - - simpleroutine stop_inferior(gdb_port : mach_port_t); */ - - msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); - msg.msgh_remote_port = gdb_port; - msg.msgh_local_port = MACH_PORT_NULL; - msg.msgh_size = sizeof (msg); - msg.msgh_seqno = 0; - msg.msgh_id = GDB_MESSAGE_ID_STOP; - - kr = mach_msg_send (&msg); - if (kr != KERN_SUCCESS) - fprintf (stderr, "Message not sent, return code %d : %s\n", kr, - mach_error_string (kr)); - - exit (kr != KERN_SUCCESS); -} diff --git a/contrib/gdb/gdb/stuff.c b/contrib/gdb/gdb/stuff.c deleted file mode 100644 index babd29fae6f..00000000000 --- a/contrib/gdb/gdb/stuff.c +++ /dev/null @@ -1,178 +0,0 @@ -/* Program to stuff files into a specially prepared space in kdb. - Copyright (C) 1986, 1989, 1991 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Written 13-Mar-86 by David Bridgham. */ - -#include -#include -#include -#include "gdb_stat.h" -#include -#include - -main (argc, argv) - int argc; - char *argv[]; -{ - register char *cp; - char *outfile; - register int i; - int offset; - int out_fd, in_fd; - struct stat stat_buf; - int size, pad; - char buf[1024]; - static char zeros[4] = - {0}; - - if (argc < 4) - err ("Not enough arguments\nUsage: %s -o kdb file1 file2 ...\n", - argv[0]); - - outfile = 0; - for (i = 1; i < argc; i++) - { - if (STREQ (argv[i], "-o")) - outfile = argv[++i]; - } - if (outfile == 0) - err ("Output file not specified\n"); - - offset = get_offset (outfile, "_heap"); - - out_fd = open (outfile, O_WRONLY); - if (out_fd < 0) - err ("Error opening %s for write: %s\n", outfile, strerror (errno)); - if (lseek (out_fd, offset, 0) < 0) - err ("Error seeking to heap in %s: %s\n", outfile, strerror (errno)); - - /* For each file listed on the command line, write it into the - * 'heap' of the output file. Make sure to skip the arguments - * that name the output file. */ - for (i = 1; i < argc; i++) - { - if (STREQ (argv[i], "-o")) - continue; - if ((in_fd = open (argv[i], O_RDONLY)) < 0) - err ("Error opening %s for read: %s\n", argv[i], - strerror (errno)); - if (fstat (in_fd, &stat_buf) < 0) - err ("Error stat'ing %s: %s\n", argv[i], strerror (errno)); - size = strlen (argv[i]); - pad = 4 - (size & 3); - size += pad + stat_buf.st_size + sizeof (int); - write (out_fd, &size, sizeof (int)); - write (out_fd, argv[i], strlen (argv[i])); - write (out_fd, zeros, pad); - while ((size = read (in_fd, buf, sizeof (buf))) > 0) - write (out_fd, buf, size); - close (in_fd); - } - size = 0; - write (out_fd, &size, sizeof (int)); - close (out_fd); - return (0); -} - -/* Read symbol table from file and returns the offset into the file - * where symbol sym_name is located. If error, print message and - * exit. */ -get_offset (file, sym_name) - char *file; - char *sym_name; -{ - int f; - struct exec file_hdr; - struct nlist *symbol_table; - int size; - char *strings; - - f = open (file, O_RDONLY); - if (f < 0) - err ("Error opening %s: %s\n", file, strerror (errno)); - if (read (f, &file_hdr, sizeof (file_hdr)) < 0) - err ("Error reading exec structure: %s\n", strerror (errno)); - if (N_BADMAG (file_hdr)) - err ("File %s not an a.out file\n", file); - - /* read in symbol table */ - if ((symbol_table = (struct nlist *) malloc (file_hdr.a_syms)) == 0) - err ("Couldn't allocate space for symbol table\n"); - if (lseek (f, N_SYMOFF (file_hdr), 0) == -1) - err ("lseek error: %s\n", strerror (errno)); - if (read (f, symbol_table, file_hdr.a_syms) == -1) - err ("Error reading symbol table from %s: %s\n", file, - strerror (errno)); - - /* read in string table */ - if (read (f, &size, 4) == -1) - err ("reading string table size: %s\n", strerror (errno)); - if ((strings = (char *) malloc (size)) == 0) - err ("Couldn't allocate memory for string table\n"); - if (read (f, strings, size - 4) == -1) - err ("reading string table: %s\n", strerror (errno)); - - /* Find the core address at which the first byte of kdb text segment - should be loaded into core when kdb is run. */ - origin = find_symbol ("_etext", symbol_table, file_hdr.a_syms, strings) - - file_hdr.a_text; - /* Find the core address at which the heap will appear. */ - coreaddr = find_symbol (sym_name, symbol_table, file_hdr.a_syms, strings); - /* Return address in file of the heap data space. */ - return (N_TXTOFF (file_hdr) + core_addr - origin); -} - -find_symbol (sym_name, symbol_table, length, strings) - char *sym_name; - struct nlist *symbol_table; - int length; - char *strings; -{ - register struct nlist *sym; - - /* Find symbol in question */ - for (sym = symbol_table; - sym != (struct nlist *) ((char *) symbol_table + length); - sym++) - { - if ((sym->n_type & N_TYPE) != N_DATA) - continue; - if (sym->n_un.n_strx == 0) - continue; - if (STREQ (sym_name, strings + sym->n_un.n_strx - 4)) - return sym->n_value; - } - err ("Data symbol %s not found in %s\n", sym_name, file); -} - -/* VARARGS */ -void -err (va_alist) - va_dcl -{ - va_list args; - char *string; - - va_start (args); - string = va_arg (args, char *); - vfprintf (gdb_stderr, string, args); - va_end (args); - exit (-1); -} diff --git a/contrib/gdb/gdb/symm-nat.c b/contrib/gdb/gdb/symm-nat.c deleted file mode 100644 index d6867774310..00000000000 --- a/contrib/gdb/gdb/symm-nat.c +++ /dev/null @@ -1,902 +0,0 @@ -/* Sequent Symmetry host interface, for GDB when running under Unix. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1999, 2000, - 2001 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* FIXME, some 387-specific items of use taken from i387-tdep.c -- ought to be - merged back in. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "symtab.h" -#include "target.h" -#include "regcache.h" - -/* FIXME: What is the _INKERNEL define for? */ -#define _INKERNEL -#include -#undef _INKERNEL -#include -#include -#include -#include -#include -#include -#include "gdb_stat.h" -#ifdef _SEQUENT_ -#include -#else -/* Dynix has only machine/ptrace.h, which is already included by sys/user.h */ -/* Dynix has no mptrace call */ -#define mptrace ptrace -#endif -#include "gdbcore.h" -#include -#include -#define TERMINAL struct sgttyb - -#include "gdbcore.h" - -void -store_inferior_registers (int regno) -{ - struct pt_regset regs; - int i; - - /* FIXME: Fetching the registers is a kludge to initialize all elements - in the fpu and fpa status. This works for normal debugging, but - might cause problems when calling functions in the inferior. - At least fpu_control and fpa_pcr (probably more) should be added - to the registers array to solve this properly. */ - mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); - - regs.pr_eax = *(int *) ®isters[REGISTER_BYTE (0)]; - regs.pr_ebx = *(int *) ®isters[REGISTER_BYTE (5)]; - regs.pr_ecx = *(int *) ®isters[REGISTER_BYTE (2)]; - regs.pr_edx = *(int *) ®isters[REGISTER_BYTE (1)]; - regs.pr_esi = *(int *) ®isters[REGISTER_BYTE (6)]; - regs.pr_edi = *(int *) ®isters[REGISTER_BYTE (7)]; - regs.pr_esp = *(int *) ®isters[REGISTER_BYTE (14)]; - regs.pr_ebp = *(int *) ®isters[REGISTER_BYTE (15)]; - regs.pr_eip = *(int *) ®isters[REGISTER_BYTE (16)]; - regs.pr_flags = *(int *) ®isters[REGISTER_BYTE (17)]; - for (i = 0; i < 31; i++) - { - regs.pr_fpa.fpa_regs[i] = - *(int *) ®isters[REGISTER_BYTE (FP1_REGNUM + i)]; - } - memcpy (regs.pr_fpu.fpu_stack[0], ®isters[REGISTER_BYTE (ST0_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[1], ®isters[REGISTER_BYTE (ST1_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[2], ®isters[REGISTER_BYTE (ST2_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[3], ®isters[REGISTER_BYTE (ST3_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[4], ®isters[REGISTER_BYTE (ST4_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[5], ®isters[REGISTER_BYTE (ST5_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[6], ®isters[REGISTER_BYTE (ST6_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[7], ®isters[REGISTER_BYTE (ST7_REGNUM)], 10); - mptrace (XPT_WREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); -} - -void -fetch_inferior_registers (int regno) -{ - int i; - struct pt_regset regs; - - registers_fetched (); - - mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); - *(int *) ®isters[REGISTER_BYTE (EAX_REGNUM)] = regs.pr_eax; - *(int *) ®isters[REGISTER_BYTE (EBX_REGNUM)] = regs.pr_ebx; - *(int *) ®isters[REGISTER_BYTE (ECX_REGNUM)] = regs.pr_ecx; - *(int *) ®isters[REGISTER_BYTE (EDX_REGNUM)] = regs.pr_edx; - *(int *) ®isters[REGISTER_BYTE (ESI_REGNUM)] = regs.pr_esi; - *(int *) ®isters[REGISTER_BYTE (EDI_REGNUM)] = regs.pr_edi; - *(int *) ®isters[REGISTER_BYTE (EBP_REGNUM)] = regs.pr_ebp; - *(int *) ®isters[REGISTER_BYTE (ESP_REGNUM)] = regs.pr_esp; - *(int *) ®isters[REGISTER_BYTE (EIP_REGNUM)] = regs.pr_eip; - *(int *) ®isters[REGISTER_BYTE (EFLAGS_REGNUM)] = regs.pr_flags; - for (i = 0; i < FPA_NREGS; i++) - { - *(int *) ®isters[REGISTER_BYTE (FP1_REGNUM + i)] = - regs.pr_fpa.fpa_regs[i]; - } - memcpy (®isters[REGISTER_BYTE (ST0_REGNUM)], regs.pr_fpu.fpu_stack[0], 10); - memcpy (®isters[REGISTER_BYTE (ST1_REGNUM)], regs.pr_fpu.fpu_stack[1], 10); - memcpy (®isters[REGISTER_BYTE (ST2_REGNUM)], regs.pr_fpu.fpu_stack[2], 10); - memcpy (®isters[REGISTER_BYTE (ST3_REGNUM)], regs.pr_fpu.fpu_stack[3], 10); - memcpy (®isters[REGISTER_BYTE (ST4_REGNUM)], regs.pr_fpu.fpu_stack[4], 10); - memcpy (®isters[REGISTER_BYTE (ST5_REGNUM)], regs.pr_fpu.fpu_stack[5], 10); - memcpy (®isters[REGISTER_BYTE (ST6_REGNUM)], regs.pr_fpu.fpu_stack[6], 10); - memcpy (®isters[REGISTER_BYTE (ST7_REGNUM)], regs.pr_fpu.fpu_stack[7], 10); -} - -/* FIXME: This should be merged with i387-tdep.c as well. */ -static -print_fpu_status (struct pt_regset ep) -{ - int i; - int bothstatus; - int top; - int fpreg; - unsigned char *p; - - printf_unfiltered ("80387:"); - if (ep.pr_fpu.fpu_ip == 0) - { - printf_unfiltered (" not in use.\n"); - return; - } - else - { - printf_unfiltered ("\n"); - } - if (ep.pr_fpu.fpu_status != 0) - { - print_387_status_word (ep.pr_fpu.fpu_status); - } - print_387_control_word (ep.pr_fpu.fpu_control); - printf_unfiltered ("last exception: "); - printf_unfiltered ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4); - printf_unfiltered ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip); - printf_unfiltered ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel); - - top = (ep.pr_fpu.fpu_status >> 11) & 7; - - printf_unfiltered ("regno tag msb lsb value\n"); - for (fpreg = 7; fpreg >= 0; fpreg--) - { - double val; - - printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); - - switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3) - { - case 0: - printf_unfiltered ("valid "); - break; - case 1: - printf_unfiltered ("zero "); - break; - case 2: - printf_unfiltered ("trap "); - break; - case 3: - printf_unfiltered ("empty "); - break; - } - for (i = 9; i >= 0; i--) - printf_unfiltered ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]); - - i387_to_double ((char *) ep.pr_fpu.fpu_stack[fpreg], (char *) &val); - printf_unfiltered (" %g\n", val); - } - if (ep.pr_fpu.fpu_rsvd1) - warning ("rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1); - if (ep.pr_fpu.fpu_rsvd2) - warning ("rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2); - if (ep.pr_fpu.fpu_rsvd3) - warning ("rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3); - if (ep.pr_fpu.fpu_rsvd5) - warning ("rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5); -} - - -print_1167_control_word (unsigned int pcr) -{ - int pcr_tmp; - - pcr_tmp = pcr & FPA_PCR_MODE; - printf_unfiltered ("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12); - switch (pcr_tmp & 12) - { - case 0: - printf_unfiltered ("RN (Nearest Value)"); - break; - case 1: - printf_unfiltered ("RZ (Zero)"); - break; - case 2: - printf_unfiltered ("RP (Positive Infinity)"); - break; - case 3: - printf_unfiltered ("RM (Negative Infinity)"); - break; - } - printf_unfiltered ("; IRND= %d ", pcr_tmp & 2); - if (0 == pcr_tmp & 2) - { - printf_unfiltered ("(same as RND)\n"); - } - else - { - printf_unfiltered ("(toward zero)\n"); - } - pcr_tmp = pcr & FPA_PCR_EM; - printf_unfiltered ("\tEM= %#x", pcr_tmp); - if (pcr_tmp & FPA_PCR_EM_DM) - printf_unfiltered (" DM"); - if (pcr_tmp & FPA_PCR_EM_UOM) - printf_unfiltered (" UOM"); - if (pcr_tmp & FPA_PCR_EM_PM) - printf_unfiltered (" PM"); - if (pcr_tmp & FPA_PCR_EM_UM) - printf_unfiltered (" UM"); - if (pcr_tmp & FPA_PCR_EM_OM) - printf_unfiltered (" OM"); - if (pcr_tmp & FPA_PCR_EM_ZM) - printf_unfiltered (" ZM"); - if (pcr_tmp & FPA_PCR_EM_IM) - printf_unfiltered (" IM"); - printf_unfiltered ("\n"); - pcr_tmp = FPA_PCR_CC; - printf_unfiltered ("\tCC= %#x", pcr_tmp); - if (pcr_tmp & FPA_PCR_20MHZ) - printf_unfiltered (" 20MHZ"); - if (pcr_tmp & FPA_PCR_CC_Z) - printf_unfiltered (" Z"); - if (pcr_tmp & FPA_PCR_CC_C2) - printf_unfiltered (" C2"); - - /* Dynix defines FPA_PCR_CC_C0 to 0x100 and ptx defines - FPA_PCR_CC_C1 to 0x100. Use whichever is defined and assume - the OS knows what it is doing. */ -#ifdef FPA_PCR_CC_C1 - if (pcr_tmp & FPA_PCR_CC_C1) - printf_unfiltered (" C1"); -#else - if (pcr_tmp & FPA_PCR_CC_C0) - printf_unfiltered (" C0"); -#endif - - switch (pcr_tmp) - { - case FPA_PCR_CC_Z: - printf_unfiltered (" (Equal)"); - break; -#ifdef FPA_PCR_CC_C1 - case FPA_PCR_CC_C1: -#else - case FPA_PCR_CC_C0: -#endif - printf_unfiltered (" (Less than)"); - break; - case 0: - printf_unfiltered (" (Greater than)"); - break; - case FPA_PCR_CC_Z | -#ifdef FPA_PCR_CC_C1 - FPA_PCR_CC_C1 -#else - FPA_PCR_CC_C0 -#endif - | FPA_PCR_CC_C2: - printf_unfiltered (" (Unordered)"); - break; - default: - printf_unfiltered (" (Undefined)"); - break; - } - printf_unfiltered ("\n"); - pcr_tmp = pcr & FPA_PCR_AE; - printf_unfiltered ("\tAE= %#x", pcr_tmp); - if (pcr_tmp & FPA_PCR_AE_DE) - printf_unfiltered (" DE"); - if (pcr_tmp & FPA_PCR_AE_UOE) - printf_unfiltered (" UOE"); - if (pcr_tmp & FPA_PCR_AE_PE) - printf_unfiltered (" PE"); - if (pcr_tmp & FPA_PCR_AE_UE) - printf_unfiltered (" UE"); - if (pcr_tmp & FPA_PCR_AE_OE) - printf_unfiltered (" OE"); - if (pcr_tmp & FPA_PCR_AE_ZE) - printf_unfiltered (" ZE"); - if (pcr_tmp & FPA_PCR_AE_EE) - printf_unfiltered (" EE"); - if (pcr_tmp & FPA_PCR_AE_IE) - printf_unfiltered (" IE"); - printf_unfiltered ("\n"); -} - -print_1167_regs (long regs[FPA_NREGS]) -{ - int i; - - union - { - double d; - long l[2]; - } - xd; - union - { - float f; - long l; - } - xf; - - - for (i = 0; i < FPA_NREGS; i++) - { - xf.l = regs[i]; - printf_unfiltered ("%%fp%d: raw= %#x, single= %f", i + 1, regs[i], xf.f); - if (!(i & 1)) - { - printf_unfiltered ("\n"); - } - else - { - xd.l[1] = regs[i]; - xd.l[0] = regs[i + 1]; - printf_unfiltered (", double= %f\n", xd.d); - } - } -} - -print_fpa_status (struct pt_regset ep) -{ - - printf_unfiltered ("WTL 1167:"); - if (ep.pr_fpa.fpa_pcr != 0) - { - printf_unfiltered ("\n"); - print_1167_control_word (ep.pr_fpa.fpa_pcr); - print_1167_regs (ep.pr_fpa.fpa_regs); - } - else - { - printf_unfiltered (" not in use.\n"); - } -} - -#if 0 /* disabled because it doesn't go through the target vector. */ -i386_float_info (void) -{ - char ubuf[UPAGES * NBPG]; - struct pt_regset regset; - - if (have_inferior_p ()) - { - PTRACE_READ_REGS (PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regset); - } - else - { - int corechan = bfd_cache_lookup (core_bfd); - if (lseek (corechan, 0, 0) < 0) - { - perror ("seek on core file"); - } - if (myread (corechan, ubuf, UPAGES * NBPG) < 0) - { - perror ("read on core file"); - } - /* only interested in the floating point registers */ - regset.pr_fpu = ((struct user *) ubuf)->u_fpusave; - regset.pr_fpa = ((struct user *) ubuf)->u_fpasave; - } - print_fpu_status (regset); - print_fpa_status (regset); -} -#endif - -static volatile int got_sigchld; - -/*ARGSUSED */ -/* This will eventually be more interesting. */ -void -sigchld_handler (int signo) -{ - got_sigchld++; -} - -/* - * Signals for which the default action does not cause the process - * to die. See for where this came from (alas, we - * can't use those macros directly) - */ -#ifndef sigmask -#define sigmask(s) (1 << ((s) - 1)) -#endif -#define SIGNALS_DFL_SAFE sigmask(SIGSTOP) | sigmask(SIGTSTP) | \ - sigmask(SIGTTIN) | sigmask(SIGTTOU) | sigmask(SIGCHLD) | \ - sigmask(SIGCONT) | sigmask(SIGWINCH) | sigmask(SIGPWR) | \ - sigmask(SIGURG) | sigmask(SIGPOLL) - -#ifdef ATTACH_DETACH -/* - * Thanks to XPT_MPDEBUGGER, we have to mange child_wait(). - */ -ptid_t -child_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int save_errno, rv, xvaloff, saoff, sa_hand; - struct pt_stop pt; - struct user u; - sigset_t set; - /* Host signal number for a signal which the inferior terminates with, or - 0 if it hasn't terminated due to a signal. */ - static int death_by_signal = 0; -#ifdef SVR4_SHARED_LIBS /* use this to distinguish ptx 2 vs ptx 4 */ - prstatus_t pstatus; -#endif - int pid = PIDGET (ptid); - - do - { - set_sigint_trap (); /* Causes SIGINT to be passed on to the - attached process. */ - save_errno = errno; - - got_sigchld = 0; - - sigemptyset (&set); - - while (got_sigchld == 0) - { - sigsuspend (&set); - } - - clear_sigint_trap (); - - rv = mptrace (XPT_STOPSTAT, 0, (char *) &pt, 0); - if (-1 == rv) - { - printf ("XPT_STOPSTAT: errno %d\n", errno); /* DEBUG */ - continue; - } - - pid = pt.ps_pid; - - if (pid != PIDGET (inferior_ptid)) - { - /* NOTE: the mystery fork in csh/tcsh needs to be ignored. - * We should not return new children for the initial run - * of a process until it has done the exec. - */ - /* inferior probably forked; send it on its way */ - rv = mptrace (XPT_UNDEBUG, pid, 0, 0); - if (-1 == rv) - { - printf ("child_wait: XPT_UNDEBUG: pid %d: %s\n", pid, - safe_strerror (errno)); - } - continue; - } - /* FIXME: Do we deal with fork notification correctly? */ - switch (pt.ps_reason) - { - case PTS_FORK: - /* multi proc: treat like PTS_EXEC */ - /* - * Pretend this didn't happen, since gdb isn't set up - * to deal with stops on fork. - */ - rv = ptrace (PT_CONTSIG, pid, 1, 0); - if (-1 == rv) - { - printf ("PTS_FORK: PT_CONTSIG: error %d\n", errno); - } - continue; - case PTS_EXEC: - /* - * Pretend this is a SIGTRAP. - */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - break; - case PTS_EXIT: - /* - * Note: we stop before the exit actually occurs. Extract - * the exit code from the uarea. If we're stopped in the - * exit() system call, the exit code will be in - * u.u_ap[0]. An exit due to an uncaught signal will have - * something else in here, see the comment in the default: - * case, below. Finally,let the process exit. - */ - if (death_by_signal) - { - status->kind = TARGET_WAITKIND_SIGNALED; - status->value.sig = target_signal_from_host (death_by_signal); - death_by_signal = 0; - break; - } - xvaloff = (unsigned long) &u.u_ap[0] - (unsigned long) &u; - errno = 0; - rv = ptrace (PT_RUSER, pid, (char *) xvaloff, 0); - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = rv; - /* - * addr & data to mptrace() don't matter here, since - * the process is already dead. - */ - rv = mptrace (XPT_UNDEBUG, pid, 0, 0); - if (-1 == rv) - { - printf ("child_wait: PTS_EXIT: XPT_UNDEBUG: pid %d error %d\n", pid, - errno); - } - break; - case PTS_WATCHPT_HIT: - internal_error (__FILE__, __LINE__, - "PTS_WATCHPT_HIT\n"); - break; - default: - /* stopped by signal */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = target_signal_from_host (pt.ps_reason); - death_by_signal = 0; - - if (0 == (SIGNALS_DFL_SAFE & sigmask (pt.ps_reason))) - { - break; - } - /* else default action of signal is to die */ -#ifdef SVR4_SHARED_LIBS - rv = ptrace (PT_GET_PRSTATUS, pid, (char *) &pstatus, 0); - if (-1 == rv) - error ("child_wait: signal %d PT_GET_PRSTATUS: %s\n", - pt.ps_reason, safe_strerror (errno)); - if (pstatus.pr_cursig != pt.ps_reason) - { - printf ("pstatus signal %d, pt signal %d\n", - pstatus.pr_cursig, pt.ps_reason); - } - sa_hand = (int) pstatus.pr_action.sa_handler; -#else - saoff = (unsigned long) &u.u_sa[0] - (unsigned long) &u; - saoff += sizeof (struct sigaction) * (pt.ps_reason - 1); - errno = 0; - sa_hand = ptrace (PT_RUSER, pid, (char *) saoff, 0); - if (errno) - error ("child_wait: signal %d: RUSER: %s\n", - pt.ps_reason, safe_strerror (errno)); -#endif - if ((int) SIG_DFL == sa_hand) - { - /* we will be dying */ - death_by_signal = pt.ps_reason; - } - break; - } - - } - while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ - - return pid_to_ptid (pid); -} -#else /* !ATTACH_DETACH */ -/* - * Simple child_wait() based on inftarg.c child_wait() for use until - * the MPDEBUGGER child_wait() works properly. This will go away when - * that is fixed. - */ -ptid_t -child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) -{ - int save_errno; - int status; - int pid = PIDGET (ptid); - - do - { - pid = wait (&status); - save_errno = errno; - - if (pid == -1) - { - if (save_errno == EINTR) - continue; - fprintf (stderr, "Child process unexpectedly missing: %s.\n", - safe_strerror (save_errno)); - ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; - return pid_to_ptid (-1); - } - } - while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ - store_waitstatus (ourstatus, status); - return pid_to_ptid (pid); -} -#endif /* ATTACH_DETACH */ - - - -/* This function simply calls ptrace with the given arguments. - It exists so that all calls to ptrace are isolated in this - machine-dependent file. */ -int -call_ptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data) -{ - return ptrace (request, pid, addr, data); -} - -int -call_mptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data) -{ - return mptrace (request, pid, addr, data); -} - -#if defined (DEBUG_PTRACE) -/* For the rest of the file, use an extra level of indirection */ -/* This lets us breakpoint usefully on call_ptrace. */ -#define ptrace call_ptrace -#define mptrace call_mptrace -#endif - -void -kill_inferior (void) -{ - if (ptid_equal (inferior_ptid, null_ptid)) - return; - - /* For MPDEBUGGER, don't use PT_KILL, since the child will stop - again with a PTS_EXIT. Just hit him with SIGKILL (so he stops) - and detach. */ - - kill (PIDGET (inferior_ptid), SIGKILL); -#ifdef ATTACH_DETACH - detach (SIGKILL); -#else /* ATTACH_DETACH */ - ptrace (PT_KILL, PIDGET (inferior_ptid), 0, 0); - wait ((int *) NULL); -#endif /* ATTACH_DETACH */ - target_mourn_inferior (); -} - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -child_resume (ptid_t ptid, int step, enum target_signal signal) -{ - int pid = PIDGET (ptid); - - errno = 0; - - if (pid == -1) - pid = PIDGET (inferior_ptid); - - /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where - it was. (If GDB wanted it to start some other way, we have already - written a new PC value to the child.) - - If this system does not support PT_SSTEP, a higher level function will - have called single_step() to transmute the step request into a - continue request (by setting breakpoints on all possible successor - instructions), so we don't have to worry about that here. */ - - if (step) - ptrace (PT_SSTEP, pid, (PTRACE_ARG3_TYPE) 1, signal); - else - ptrace (PT_CONTSIG, pid, (PTRACE_ARG3_TYPE) 1, signal); - - if (errno) - perror_with_name ("ptrace"); -} - -#ifdef ATTACH_DETACH -/* Start debugging the process whose number is PID. */ -int -attach (int pid) -{ - sigset_t set; - int rv; - - rv = mptrace (XPT_DEBUG, pid, 0, 0); - if (-1 == rv) - { - error ("mptrace(XPT_DEBUG): %s", safe_strerror (errno)); - } - rv = mptrace (XPT_SIGNAL, pid, 0, SIGSTOP); - if (-1 == rv) - { - error ("mptrace(XPT_SIGNAL): %s", safe_strerror (errno)); - } - attach_flag = 1; - return pid; -} - -void -detach (int signo) -{ - int rv; - - rv = mptrace (XPT_UNDEBUG, PIDGET (inferior_ptid), 1, signo); - if (-1 == rv) - { - error ("mptrace(XPT_UNDEBUG): %s", safe_strerror (errno)); - } - attach_flag = 0; -} - -#endif /* ATTACH_DETACH */ - -/* Default the type of the ptrace transfer to int. */ -#ifndef PTRACE_XFER_TYPE -#define PTRACE_XFER_TYPE int -#endif - - -/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory - in the NEW_SUN_PTRACE case. - It ought to be straightforward. But it appears that writing did - not write the data that I specified. I cannot understand where - it got the data that it actually did write. */ - -/* Copy LEN bytes to or from inferior's memory starting at MEMADDR - to debugger memory starting at MYADDR. Copy to inferior if - WRITE is nonzero. TARGET is ignored. - - Returns the length copied, which is either the LEN argument or zero. - This xfer function does not do partial moves, since child_ops - doesn't allow memory operations to cross below us in the target stack - anyway. */ - -int -child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, - struct target_ops *target) -{ - register int i; - /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); - /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) - / sizeof (PTRACE_XFER_TYPE); - /* Allocate buffer of that many longwords. */ - /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe - because it uses alloca to allocate a buffer of arbitrary size. - For very large xfers, this could crash GDB's stack. */ - register PTRACE_XFER_TYPE *buffer - = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); - - if (write) - { - /* Fill start and end extra bytes of buffer with existing memory data. */ - - if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE)) - { - /* Need part of initial word -- fetch it. */ - buffer[0] = ptrace (PT_RTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, - 0); - } - - if (count > 1) /* FIXME, avoid if even boundary */ - { - buffer[count - 1] - = ptrace (PT_RTEXT, PIDGET (inferior_ptid), - ((PTRACE_ARG3_TYPE) - (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))), - 0); - } - - /* Copy data to be written over corresponding part of buffer */ - - memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), - myaddr, - len); - - /* Write the entire buffer. */ - - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - ptrace (PT_WDATA, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, - buffer[i]); - if (errno) - { - /* Using the appropriate one (I or D) is necessary for - Gould NP1, at least. */ - errno = 0; - ptrace (PT_WTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, - buffer[i]); - } - if (errno) - return 0; - } - } - else - { - /* Read all the longwords */ - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - buffer[i] = ptrace (PT_RTEXT, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) addr, 0); - if (errno) - return 0; - QUIT; - } - - /* Copy appropriate bytes out of the buffer. */ - memcpy (myaddr, - (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), - len); - } - return len; -} - - -void -_initialize_symm_nat (void) -{ -#ifdef ATTACH_DETACH -/* - * the MPDEBUGGER is necessary for process tree debugging and attach - * to work, but it alters the behavior of debugged processes, so other - * things (at least child_wait()) will have to change to accomodate - * that. - * - * Note that attach is not implemented in dynix 3, and not in ptx - * until version 2.1 of the OS. - */ - int rv; - sigset_t set; - struct sigaction sact; - - rv = mptrace (XPT_MPDEBUGGER, 0, 0, 0); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): mptrace(XPT_MPDEBUGGER): %s", - safe_strerror (errno)); - } - - /* - * Under MPDEBUGGER, we get SIGCLHD when a traced process does - * anything of interest. - */ - - /* - * Block SIGCHLD. We leave it blocked all the time, and then - * call sigsuspend() in child_wait() to wait for the child - * to do something. None of these ought to fail, but check anyway. - */ - sigemptyset (&set); - rv = sigaddset (&set, SIGCHLD); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): sigaddset(SIGCHLD): %s", - safe_strerror (errno)); - } - rv = sigprocmask (SIG_BLOCK, &set, (sigset_t *) NULL); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): sigprocmask(SIG_BLOCK): %s", - safe_strerror (errno)); - } - - sact.sa_handler = sigchld_handler; - sigemptyset (&sact.sa_mask); - sact.sa_flags = SA_NOCLDWAIT; /* keep the zombies away */ - rv = sigaction (SIGCHLD, &sact, (struct sigaction *) NULL); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): sigaction(SIGCHLD): %s", - safe_strerror (errno)); - } -#endif -} diff --git a/contrib/gdb/gdb/symm-tdep.c b/contrib/gdb/gdb/symm-tdep.c deleted file mode 100644 index 37a2f511aa7..00000000000 --- a/contrib/gdb/gdb/symm-tdep.c +++ /dev/null @@ -1,102 +0,0 @@ -/* Sequent Symmetry target interface, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* many 387-specific items of use taken from i386-dep.c */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "symtab.h" - -#include -#include -#include -#include -#include -#include "gdb_stat.h" -#include "gdbcore.h" -#include - -void -symmetry_extract_return_value (struct type *type, char *regbuf, char *valbuf) -{ - union - { - double d; - int l[2]; - } - xd; - struct minimal_symbol *msymbol; - float f; - - if (TYPE_CODE_FLT == TYPE_CODE (type)) - { - msymbol = lookup_minimal_symbol ("1167_flt", NULL, NULL); - if (msymbol != NULL) - { - /* found "1167_flt" means 1167, %fp2-%fp3 */ - /* float & double; 19= %fp2, 20= %fp3 */ - /* no single precision on 1167 */ - xd.l[1] = *((int *) ®buf[REGISTER_BYTE (19)]); - xd.l[0] = *((int *) ®buf[REGISTER_BYTE (20)]); - switch (TYPE_LENGTH (type)) - { - case 4: - /* FIXME: broken for cross-debugging. */ - f = (float) xd.d; - memcpy (valbuf, &f, TYPE_LENGTH (type)); - break; - case 8: - /* FIXME: broken for cross-debugging. */ - memcpy (valbuf, &xd.d, TYPE_LENGTH (type)); - break; - default: - error ("Unknown floating point size"); - break; - } - } - else - { - /* 387 %st(0), gcc uses this */ - i387_to_double (((int *) ®buf[REGISTER_BYTE (3)]), - &xd.d); - switch (TYPE_LENGTH (type)) - { - case 4: /* float */ - f = (float) xd.d; - /* FIXME: broken for cross-debugging. */ - memcpy (valbuf, &f, 4); - break; - case 8: /* double */ - /* FIXME: broken for cross-debugging. */ - memcpy (valbuf, &xd.d, 8); - break; - default: - error ("Unknown floating point size"); - break; - } - } - } - else - { - memcpy (valbuf, regbuf, TYPE_LENGTH (type)); - } -} diff --git a/contrib/gdb/gdb/thread.h b/contrib/gdb/gdb/thread.h deleted file mode 100644 index 6777887af2e..00000000000 --- a/contrib/gdb/gdb/thread.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Multi-process/thread control defs for GDB, the GNU debugger. - Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993 - - Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. - Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef THREAD_H -#define THREAD_H - -extern void init_thread_list PARAMS ((void)); - -extern void add_thread PARAMS ((int pid)); - -extern int in_thread_list PARAMS ((int pid)); - -extern int pid_to_thread_id PARAMS ((int pid)); - -extern int valid_thread_id PARAMS ((int thread)); - -extern void load_infrun_state PARAMS ((int, CORE_ADDR *, CORE_ADDR *, char **, - int *, struct breakpoint **, - struct breakpoint **, CORE_ADDR *, - CORE_ADDR *, CORE_ADDR *, int *, int *)); - -extern void save_infrun_state PARAMS ((int, CORE_ADDR, CORE_ADDR, char *, - int, struct breakpoint *, - struct breakpoint *, CORE_ADDR, - CORE_ADDR, CORE_ADDR, int, int)); - -#endif /* THREAD_H */ diff --git a/contrib/gdb/gdb/tui/ChangeLog b/contrib/gdb/gdb/tui/ChangeLog deleted file mode 100644 index 7dc1bf60460..00000000000 --- a/contrib/gdb/gdb/tui/ChangeLog +++ /dev/null @@ -1,121 +0,0 @@ -1999-01-26 Jason Molenda (jsm@bugshack.cygnus.com) - - * tui.h: Include stdarg.h instead of varargs.h if we're on an ISO Cish - system. - -Thu Dec 31 12:08:32 1998 David Taylor - - The following changes were made by Jim Blandy , - Edith Epstein , Elena Zannoni - Stan Shebs , and David - Taylor , as part of the project to merge in - changes originally made by HP; HP did not create ChangeLog - entries. - - * Makefile.in: New file; we're merging HP's changes into GDB, and - we've moved the TUI files into a subdirectory, so we need a new - Makefile. - - * tui.c: - #include , if we have it, to get declarations for - the termcap functions on Solaris. - (tgoto): Add external K&R declaration for this; Solaris doesn't - bother to actually declare it in their header files. - (_tuiReset): Ignore the #definition of TIOCGETC if USG is defined; - we'd rather use the USG mechanisms than the Berkeley mechanisms - (TIOCGETC is one of the Berkeley terminal control ioctls). - Apologies if this causes trouble later; this should all be handled - by autoconf... - (strcat_to_buf, strcat_to_buf_with_fmt): New functions, moved here - from ../utils.h. - (tuiFree): replace safe_free with free. - (strcat_to_buf): new function, copied from utils.c. - (tuiInit): Add ignored `argv0' argument, to match the type that - init_ui_hook expects; updated declaration. Call the - initialize_tui_files function constructed above. Initialize - flush_hook to NULL. - (tuiInitWindows): Call tuiSetLocatorContent, to get the first - element of the locator window's content allocated. This seems - wrong, because it must have been initialized somehow in HP's - sources, and we should do it the same way now. But we do get - further before it segfaults. [Postscript: HP didn't bother to - initialize it; they compile - (va_catch_errors, vcatch_errors): Functions moved here from - ../utils.c in HP's sources. They're not used anywhere else. - (xdb_style): Delete this variable, and remove all references to - it. It's always true. - (tuiInit, _tui_vDo): References removed. - - * tui.h: Add prototypes. - Don't #include "gendefs.h"; it's only used in the TUI. - Integrate its contents into this file: - #include here. - (Opaque, OpaqueFuncPtr): Typedefs moved to here. - - * tuiCommand.c: #include "defs.h", so we get the appropriate - definition of GDB_FILE. - - * tuiData.c - (freeWindow): replace safe_free with free. - (tui_version): don't define it here; it's defined in main.c now. - - * tuiDisassem.c - (tuiSetDisassemContent): Call strcat_address_numeric instead of - strcat_address. Simplify the control structure. Use predefined - GDB function to print asm inst address. Use GDB_FILE to collect - output into buffers. - - * tuiIO.c - (tgoto): Add external K&R declaration for this here too. - (tuiGetc, tuiTermSetup, tuiTermUnsetup): Same. - (tuiPuts_unfiltered): change FILE to GDB_FILE. - (tui_tputs): fix prototype for 3rd argument. - - * tuiIO.h (tuiPuts_unfiltered): change declaration. - - * tuiLayout.c - (_tuiSetLayoutTo): for displaying registers, hook up the HP code - that decides which registers to display (i.e. single precision - float, double precision float, general, special). Previously, - only handled TUI_GENERAL_REGS. Now that the code is hooked up, - compiling with -z poses a problem. When the first layout command - is 'layout regs', dataWin->detail is a NULL pointer, and gdb - core dumps. - - * tuiLayout.c (_tuiSetLayoutTo): replace safe_free with free. - - * tuiRegs.c #include "defs.h" earlier, to avoid problems in - . No idea exactly what's conflicting with what, but the - errors went away... - (_tuiRegisterFormat): Change so that function creates a GDB_FILE - object, calls pa_do_strcat_registers_info, copies the register - info into a buffer, and deallocates the GDB_FILE object. Remove - some code that is not executed. Also, call to - pa_do_strcat_registers_info has an additional parameter, - precision. This code requires some new per-target functions that - we don't want to merge. Dyke it out, with #ifdef - TUI_EXTENDED_FORMATTERS. - (_tuiSetSpecialRegsContent): this function was ifdefed out. - Hooked this up. - (_tuiSetGeneralAndSpecialRegsContent): this function was ifdefed - out. Hooked it up. - (IS_64BIT): Just define this to be zero; we're not merging in the - 64-bit support. - (tuiShowRegisters): Comment out all references to the "special" - regs; we don't have a distinction between the "special" and - "non-special" regs in most of our machine descriptions. This code - is PA-specific in other ways as well, and needs to be redesigned - to be portable to other processors. - - * tuiWin.c: #include , to get a declaration for - strchr. - - * tui.c, tuiCommand.c, tuiData.c, tuiDataWin.c, tuiDisassem.c, - tuiGeneralWin.c, tuiIO.c, tuiLayout.c, tuiRegs.c, tuiSource.c, - tuiSourceWin.c, tuiStack.c, tuiWin.c: New files (from HP). Changed - bool to int throughout. Re-indented, GNU style. - - * tui.h, tuiCommand.h, tuiData.h, tuiDataWin.h, tuiDisassem.h, - tuiGeneralWin.h, tuiIO.h, tuiLayout.h, tuiRegs.h, tuiSource.h, - tuiSourceWin.h, tuiStack.h, tuiWin.h: new files (from HP). - Changed bool to int throughout. diff --git a/contrib/gdb/gdb/tui/Makefile b/contrib/gdb/gdb/tui/Makefile deleted file mode 100644 index ed89c6e6176..00000000000 --- a/contrib/gdb/gdb/tui/Makefile +++ /dev/null @@ -1,182 +0,0 @@ -# Generated automatically from Makefile.in by configure. -# Copyright 1998 Free Software Foundation, Inc. - -# This file is part of GDB. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -all: libtui.a - -srcdir=. - -SHELL = /bin/sh - -CC=gcc -CFLAGS=-g -O2 -AR=ar -RANLIB=ranlib - -# Host and target-dependent makefile fragments come in here. - -# Host: Sun 4 or Sparcstation, running SunOS 4 -XDEPFILES= ser-tcp.o -XM_FILE= xm-sun4os4.h -NAT_FILE= nm-sun4os4.h -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o -HOST_IPC=-DBSD_IPC -GDBSERVER_DEPFILES= low-sparc.o -# Setting XM_CLIBS=-lresolv would let us use the DNS, but that would screw -# anyone who wants to use NIS, which includes at least one Cygnus customer -# (PR 3593). So leave it this way until/unless we find a resolver which can -# get names from either DNS or NIS from the same GDB binary. - -# Target: Sun 4 or Sparcstation, running SunOS 4 -TDEPFILES= sparc-tdep.o solib.o -TM_FILE= tm-sun4os4.h -# End of host and target-dependent makefile fragments - -# Where is our "include" directory? Typically $(srcdir)/../include. -# This is essentially the header file directory for the library -# routines in libiberty. -INCLUDE_DIR = $(srcdir)/../../include -INCLUDE_CFLAGS = -I$(INCLUDE_DIR) - -# Configured by the --with-mmalloc option to configure. -MMALLOC = -MMALLOC_CFLAGS = - -# Where is the BFD library? Typically in ../bfd. -BFD_DIR = ../../bfd -BFD_SRC = $(srcdir)/$(BFD_DIR) -BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC) - -# Where is the READLINE library? Typically in ../readline. -READLINE_DIR = ../../readline -READLINE_SRC = $(srcdir)/$(READLINE_DIR) -READLINE_CFLAGS = -I$(READLINE_SRC) - -# Where is the INTL library? Typically in ../intl. -INTL_DIR = ../../intl -INTL_SRC = $(srcdir)/$(INTL_DIR) -INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC) - -# Where is the TCL library? Typically in ../tcl. -TCL_CFLAGS = @TCLHDIR@ - -# Where is the TK library? Typically in ../tk. -TK_CFLAGS = @TKHDIR@ @TK_BUILD_INCLUDES@ - -# Where is Itcl? Typically in ../itcl. -ITCL_CFLAGS = @ITCLHDIR@ - -# Where is Tix? Typically in ../tix. -TIX_CFLAGS = @TIXHDIR@ - -X11_CFLAGS = @TK_XINCLUDES@ - -ENABLE_IDE= @ENABLE_IDE@ - -GUI_CFLAGS_X = -I$(srcdir)/../../libgui/src - -IDE_CFLAGS_X = -I$(srcdir)/../../libidetcl/src -I$(srcdir)/../../libide/src \ - `if [ x"$(ENABLE_IDE)" != x ] ; then \ - echo -DIDE -I$(srcdir)/../../ilu/runtime/mainloop;\ - fi` - -IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X) - -ENABLE_CFLAGS= - -# -I. for config files. -# -I$(srcdir) for gdb internal headers and possibly for gnu-regex.h also. -# -I$(srcdir)/config for more generic config files. - -# It is also possible that you will need to add -I/usr/include/sys if -# your system doesn't have fcntl.h in /usr/include (which is where it -# should be according to Posix). -DEFS = -DHAVE_CONFIG_H -GDB_CFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config $(DEFS) - -# M{H,T}_CFLAGS, if defined, have host- and target-dependent CFLAGS -# from the config directory. -GLOBAL_CFLAGS = $(MT_CFLAGS) $(MH_CFLAGS) -#PROFILE_CFLAGS = -pg - -# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros. -INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \ - $(GDB_CFLAGS) $(READLINE_CFLAGS) $(BFD_CFLAGS) \ - $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) $(INTL_CFLAGS) \ - $(ENABLE_CFLAGS) - -HEADERS = tuiIO.h tuiData.h tuiGeneralWin.h tuiLayout.h tuiStack.h \ - tuiSource.h tuiCommand.h tuiWin.h tuiDisassem.h \ - tuiSourceWin.h tuiRegs.h tuiDataWin.h - -SOURCES = tui.c tuiData.c tuiSource.c tuiStack.c tuiIO.c \ - tuiGeneralWin.c tuiLayout.c tuiWin.c tuiCommand.c \ - tuiDisassem.c tuiSourceWin.c tuiRegs.c tuiDataWin.c - -OBJECTS = tui.o tuiData.o tuiSource.o tuiStack.o tuiIO.o \ - tuiGeneralWin.o tuiLayout.o tuiWin.o tuiCommand.o \ - tuiDisassem.o tuiSourceWin.o tuiRegs.o tuiDataWin.o \ - tuiInit.o - - -# Prevent Sun make from putting in the machine type. Setting -# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1. -.c.o: - $(CC) -c $(INTERNAL_CFLAGS) $< -.SUFFIXES: .cpp -.c.cpp: - $(CC) -E $(INTERNAL_CFLAGS) $< > $@ - -libtui.a: $(OBJECTS) - rm -f libtui.a - $(AR) rc libtui.a $(OBJECTS) - $(RANLIB) libtui.a - -tui.o: tui.c tui.h tuiData.h tuiLayout.h tuiIO.h tuiRegs.h tuiWin.h -tuiCommand.o: tui.h tuiData.h tuiWin.h tuiIO.h -tuiData.o: tui.h tuiData.h -tuiDataWin.o: tui.h tuiData.h tuiRegs.h -tuiDisassem.o: tui.h tuiData.h tuiLayout.h tuiSourceWin.h tuiStack.h -tuiGeneralWin.o: tui.h tuiData.h tuiGeneralWin.h -tuiIO.o: tui.h tuiData.h tuiIO.h tuiCommand.h tuiWin.h -tuiLayout.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiRegs.h \ - tuiDisassem.h -tuiRegs.o: tui.h tuiData.h tuiLayout.h tuiWin.h -tuiSource.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h -tuiSourceWin.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h \ - tuiDisassem.h -tuiStack.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h -tuiWin.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiSourceWin.h \ - tuiDataWin.h - -tuiInit.o: tuiInit.c -tuiInit.c: $(SOURCES) - @echo Making tuiInit.c - @rm -f init.c-tmp - @echo '/* Do not modify this file. */' >init.c-tmp - @echo '/* It is created automatically by the Makefile. */'>>init.c-tmp - @echo '#include "ansidecl.h"' >>init.c-tmp - @echo 'extern void initialize_tui_files PARAMS ((void));' >>init.c-tmp - @echo 'void initialize_tui_files PARAMS ((void)) {' >>init.c-tmp - @-( cd $(srcdir) ; grep '^_initialize_[a-z_0-9A-Z]* *(' $(SOURCES) ) 2>/dev/null \ - | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 PARAMS ((void)); \1 ();}/' >>init.c-tmp - @echo '}' >>init.c-tmp - @mv init.c-tmp tuiInit.c - -clean: - rm -f *.o *.a diff --git a/contrib/gdb/gdb/tui/Makefile.in b/contrib/gdb/gdb/tui/Makefile.in deleted file mode 100644 index 256464b5bc5..00000000000 --- a/contrib/gdb/gdb/tui/Makefile.in +++ /dev/null @@ -1,168 +0,0 @@ -# Copyright 1998 Free Software Foundation, Inc. - -# This file is part of GDB. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -all: libtui.a - -srcdir=@srcdir@ -VPATH = @srcdir@ - -SHELL = @SHELL@ - -CC=@CC@ -CFLAGS=@CFLAGS@ -AR=@AR@ -RANLIB=@RANLIB@ - -# Host and target-dependent makefile fragments come in here. -@host_makefile_frag@ -@target_makefile_frag@ -# End of host and target-dependent makefile fragments - -# Where is our "include" directory? Typically $(srcdir)/../include. -# This is essentially the header file directory for the library -# routines in libiberty. -INCLUDE_DIR = $(srcdir)/../../include -INCLUDE_CFLAGS = -I$(INCLUDE_DIR) - -# Configured by the --with-mmalloc option to configure. -MMALLOC = @MMALLOC@ -MMALLOC_CFLAGS = @MMALLOC_CFLAGS@ - -# Where is the BFD library? Typically in ../bfd. -BFD_DIR = ../../bfd -BFD_SRC = $(srcdir)/$(BFD_DIR) -BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC) - -# Where is the READLINE library? Typically in ../readline. -READLINE_DIR = ../../readline -READLINE_SRC = $(srcdir)/$(READLINE_DIR) -READLINE_CFLAGS = -I$(READLINE_SRC) - -# Where is the INTL library? Typically in ../intl. -INTL_DIR = ../../intl -INTL_SRC = $(srcdir)/$(INTL_DIR) -INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC) - -# Where is the TCL library? Typically in ../tcl. -TCL_CFLAGS = @TCLHDIR@ - -# Where is the TK library? Typically in ../tk. -TK_CFLAGS = @TKHDIR@ @TK_BUILD_INCLUDES@ - -# Where is Itcl? Typically in ../itcl. -ITCL_CFLAGS = @ITCLHDIR@ - -# Where is Tix? Typically in ../tix. -TIX_CFLAGS = @TIXHDIR@ - -X11_CFLAGS = @TK_XINCLUDES@ - -ENABLE_IDE= @ENABLE_IDE@ - -GUI_CFLAGS_X = -I$(srcdir)/../../libgui/src - -IDE_CFLAGS_X = -I$(srcdir)/../../libidetcl/src -I$(srcdir)/../../libide/src \ - `if [ x"$(ENABLE_IDE)" != x ] ; then \ - echo -DIDE -I$(srcdir)/../../ilu/runtime/mainloop;\ - fi` - -IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X) - -ENABLE_CFLAGS= @ENABLE_CFLAGS@ - -# -I. for config files. -# -I$(srcdir) for gdb internal headers and possibly for gnu-regex.h also. -# -I$(srcdir)/config for more generic config files. - -# It is also possible that you will need to add -I/usr/include/sys if -# your system doesn't have fcntl.h in /usr/include (which is where it -# should be according to Posix). -DEFS = @DEFS@ -GDB_CFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config $(DEFS) - -# M{H,T}_CFLAGS, if defined, have host- and target-dependent CFLAGS -# from the config directory. -GLOBAL_CFLAGS = $(MT_CFLAGS) $(MH_CFLAGS) -#PROFILE_CFLAGS = -pg - -# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros. -INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \ - $(GDB_CFLAGS) $(READLINE_CFLAGS) $(BFD_CFLAGS) \ - $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) $(INTL_CFLAGS) \ - $(ENABLE_CFLAGS) - -HEADERS = tuiIO.h tuiData.h tuiGeneralWin.h tuiLayout.h tuiStack.h \ - tuiSource.h tuiCommand.h tuiWin.h tuiDisassem.h \ - tuiSourceWin.h tuiRegs.h tuiDataWin.h - -SOURCES = tui.c tuiData.c tuiSource.c tuiStack.c tuiIO.c \ - tuiGeneralWin.c tuiLayout.c tuiWin.c tuiCommand.c \ - tuiDisassem.c tuiSourceWin.c tuiRegs.c tuiDataWin.c - -OBJECTS = tui.o tuiData.o tuiSource.o tuiStack.o tuiIO.o \ - tuiGeneralWin.o tuiLayout.o tuiWin.o tuiCommand.o \ - tuiDisassem.o tuiSourceWin.o tuiRegs.o tuiDataWin.o \ - tuiInit.o - - -# Prevent Sun make from putting in the machine type. Setting -# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1. -.c.o: - $(CC) -c $(INTERNAL_CFLAGS) $< -.SUFFIXES: .cpp -.c.cpp: - $(CC) -E $(INTERNAL_CFLAGS) $< > $@ - -libtui.a: $(OBJECTS) - rm -f libtui.a - $(AR) rc libtui.a $(OBJECTS) - $(RANLIB) libtui.a - -tui.o: tui.c tui.h tuiData.h tuiLayout.h tuiIO.h tuiRegs.h tuiWin.h -tuiCommand.o: tui.h tuiData.h tuiWin.h tuiIO.h -tuiData.o: tui.h tuiData.h -tuiDataWin.o: tui.h tuiData.h tuiRegs.h -tuiDisassem.o: tui.h tuiData.h tuiLayout.h tuiSourceWin.h tuiStack.h -tuiGeneralWin.o: tui.h tuiData.h tuiGeneralWin.h -tuiIO.o: tui.h tuiData.h tuiIO.h tuiCommand.h tuiWin.h -tuiLayout.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiRegs.h \ - tuiDisassem.h -tuiRegs.o: tui.h tuiData.h tuiLayout.h tuiWin.h -tuiSource.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h -tuiSourceWin.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h \ - tuiDisassem.h -tuiStack.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h -tuiWin.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiSourceWin.h \ - tuiDataWin.h - -tuiInit.o: tuiInit.c -tuiInit.c: $(SOURCES) - @echo Making tuiInit.c - @rm -f init.c-tmp - @echo '/* Do not modify this file. */' >init.c-tmp - @echo '/* It is created automatically by the Makefile. */'>>init.c-tmp - @echo '#include "ansidecl.h"' >>init.c-tmp - @echo 'extern void initialize_tui_files PARAMS ((void));' >>init.c-tmp - @echo 'void initialize_tui_files PARAMS ((void)) {' >>init.c-tmp - @-( cd $(srcdir) ; grep '^_initialize_[a-z_0-9A-Z]* *(' $(SOURCES) ) 2>/dev/null \ - | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 PARAMS ((void)); \1 ();}/' >>init.c-tmp - @echo '}' >>init.c-tmp - @mv init.c-tmp tuiInit.c - -clean: - rm -f *.o *.a diff --git a/contrib/gdb/gdb/tui/tui.c b/contrib/gdb/gdb/tui/tui.c deleted file mode 100644 index f64db4442a8..00000000000 --- a/contrib/gdb/gdb/tui/tui.c +++ /dev/null @@ -1,830 +0,0 @@ -/* -** tui.c -** General functions for the WDB TUI -*/ - -#include -#include -#include -#include -#include -#ifdef HAVE_TERM_H -#include -#endif -#include -#include -#include -#include -#include "defs.h" -#include "gdbcmd.h" -#include "tui.h" -#include "tuiData.h" -#include "tuiLayout.h" -#include "tuiIO.h" -#include "tuiRegs.h" -#include "tuiWin.h" - -/* The Solaris header files seem to provide no declaration for this at - all when __STDC__ is defined. This shouldn't conflict with - anything. */ -extern char *tgoto (); - -/*********************** -** Local Definitions -************************/ -#define FILEDES 2 -/* Solaris defines CTRL. */ -#ifndef CTRL -#define CTRL(x) (x & ~0140) -#endif -#define CHK(val, dft) (val<=0 ? dft : val) - -#define TOGGLE_USAGE "Usage:toggle breakpoints" -#define TUI_TOGGLE_USAGE "Usage:\ttoggle $fregs\n\ttoggle breakpoints" - -/***************************** -** Local static forward decls -******************************/ -static void _tuiReset PARAMS ((void)); -static void _toggle_command PARAMS ((char *, int)); -static void _tui_vToggle_command PARAMS ((va_list)); -static Opaque _tui_vDo PARAMS ((TuiOpaqueFuncPtr, va_list)); - - - -/*********************** -** Public Functions -************************/ - -/* -** tuiInit(). -*/ -void -#ifdef __STDC__ -tuiInit (char *argv0) -#else -tuiInit (argv0) - char *argv0; -#endif -{ - extern void init_page_info (); - extern void initialize_tui_files PARAMS ((void)); - - initialize_tui_files (); - initializeStaticData (); - initscr (); - refresh (); - setTermHeightTo (LINES); - setTermWidthTo (COLS); - tuiInitWindows (); - wrefresh (cmdWin->generic.handle); - init_page_info (); - /* Don't hook debugger output if doing command-window - * the XDB way. However, one thing we do want to do in - * XDB style is set up the scrolling region to be - * the bottom of the screen (tuiTermUnsetup()). - */ - fputs_unfiltered_hook = NULL; - flush_hook = NULL; - rl_initialize (); /* need readline initialization to - * create termcap sequences - */ - tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch); - - return; -} /* tuiInit */ - - -/* -** tuiInitWindows(). -*/ -void -#ifdef __STDC__ -tuiInitWindows (void) -#else -tuiInitWindows () -#endif -{ - TuiWinType type; - - tuiSetLocatorContent (0); - showLayout (SRC_COMMAND); - keypad (cmdWin->generic.handle, TRUE); - echo (); - crmode (); - nl (); - tuiSetWinFocusTo (srcWin); - - return; -} /* tuiInitWindows */ - - -/* -** tuiCleanUp(). -** Kill signal handler and cleanup termination method -*/ -void -#ifdef __STDC__ -tuiResetScreen (void) -#else -tuiResetScreen () -#endif -{ - TuiWinType type = SRC_WIN; - - keypad (cmdWin->generic.handle, FALSE); - for (; type < MAX_MAJOR_WINDOWS; type++) - { - if (m_winPtrNotNull (winList[type]) && - winList[type]->generic.type != UNDEFINED_WIN && - !winList[type]->generic.isVisible) - tuiDelWindow (winList[type]); - } - endwin (); - initscr (); - refresh (); - echo (); - crmode (); - nl (); - - return; -} /* tuiResetScreen */ - - -/* -** tuiCleanUp(). -** Kill signal handler and cleanup termination method -*/ -void -#ifdef __STDC__ -tuiCleanUp (void) -#else -tuiCleanUp () -#endif -{ - char *buffer; - extern char *term_cursor_move; - - signal (SIGINT, SIG_IGN); - tuiTermSetup (0); /* Restore scrolling region to whole screen */ - keypad (cmdWin->generic.handle, FALSE); - freeAllWindows (); - endwin (); - buffer = tgoto (term_cursor_move, 0, termHeight ()); - tputs (buffer, 1, putchar); - _tuiReset (); - - return; -} /* tuiCleanUp */ - - -/* -** tuiError(). -*/ -void -#ifdef __STDC__ -tuiError ( - char *string, - int exitGdb) -#else -tuiError (string, exitGdb) - char *string; - int exitGdb; -#endif -{ - puts_unfiltered (string); - if (exitGdb) - { - tuiCleanUp (); - exit (-1); - } - - return; -} /* tuiError */ - - -/* -** tui_vError() -** tuiError with args in a va_list. -*/ -void -#ifdef __STDC__ -tui_vError ( - va_list args) -#else -tui_vError (args) - va_list args; -#endif -{ - char *string; - int exitGdb; - - string = va_arg (args, char *); - exitGdb = va_arg (args, int); - - tuiError (string, exitGdb); - - return; -} /* tui_vError */ - - -/* -** tuiFree() -** Wrapper on top of free() to ensure that input address is greater than 0x0 -*/ -void -#ifdef __STDC__ -tuiFree ( - char *ptr) -#else -tuiFree (ptr) - char *ptr; -#endif -{ - if (ptr != (char *) NULL) - { - free (ptr); - } - - return; -} /* tuiFree */ - - -/* tuiGetLowDisassemblyAddress(). -** Determine what the low address will be to display in the TUI's -** disassembly window. This may or may not be the same as the -** low address input. -*/ -Opaque -#ifdef __STDC__ -tuiGetLowDisassemblyAddress ( - Opaque low, - Opaque pc) -#else -tuiGetLowDisassemblyAddress (low, pc) - Opaque low; - Opaque pc; -#endif -{ - int line; - Opaque newLow; - - /* - ** Determine where to start the disassembly so that the pc is about in the - ** middle of the viewport. - */ - for (line = 0, newLow = pc; - (newLow > low && - line < (tuiDefaultWinViewportHeight (DISASSEM_WIN, - DISASSEM_COMMAND) / 2));) - { - bfd_byte buffer[4]; - - newLow -= sizeof (bfd_getb32 (buffer)); - line++; - } - - return newLow; -} /* tuiGetLowDisassemblyAddress */ - - -/* tui_vGetLowDisassemblyAddress(). -** Determine what the low address will be to display in the TUI's -** disassembly window with args in a va_list. -*/ -Opaque -#ifdef __STDC__ -tui_vGetLowDisassemblyAddress ( - va_list args) -#else -tui_vGetLowDisassemblyAddress (args) - va_list args; -#endif -{ - int line; - Opaque newLow; - Opaque low; - Opaque pc; - - low = va_arg (args, Opaque); - pc = va_arg (args, Opaque); - - return (tuiGetLowDisassemblyAddress (low, pc)); - -} /* tui_vGetLowDisassemblyAddress */ - - -/* -** tuiDo(). -** General purpose function to execute a tui function. Transitions -** between curses and the are handled here. This function is called -** by non-tui gdb functions. -** -** Errors are caught here. -** If there is no error, the value returned by 'func' is returned. -** If there is an error, then zero is returned. -** -** Must not be called with immediate_quit in effect (bad things might -** happen, say we got a signal in the middle of a memcpy to quit_return). -** This is an OK restriction; with very few exceptions immediate_quit can -** be replaced by judicious use of QUIT. -*/ -Opaque -#ifdef __STDC__ -tuiDo ( - TuiOpaqueFuncPtr func,...) -#else -tuiDo (func, va_alist) - TuiOpaqueFuncPtr func; - va_dcl -#endif -{ - extern int terminal_is_ours; - - Opaque ret = (Opaque) NULL; - - /* It is an error to be tuiDo'ing if we - * don't own the terminal. - */ - if (!terminal_is_ours) - return ret; - - if (tui_version) - { - va_list args; - -#ifdef __STDC__ - va_start (args, func); -#else - va_start (args); -#endif - ret = _tui_vDo (func, args); - va_end (args); - } - - return ret; -} /* tuiDo */ - - -/* -** tuiDoAndReturnToTop(). -** General purpose function to execute a tui function. Transitions -** between curses and the are handled here. This function is called -** by non-tui gdb functions who wish to reset gdb to the top level. -** After the tuiDo is performed, a return to the top level occurs. -** -** Errors are caught here. -** If there is no error, the value returned by 'func' is returned. -** If there is an error, then zero is returned. -** -** Must not be called with immediate_quit in effect (bad things might -** happen, say we got a signal in the middle of a memcpy to quit_return). -** This is an OK restriction; with very few exceptions immediate_quit can -** be replaced by judicious use of QUIT. -** -*/ -Opaque -#ifdef __STDC__ -tuiDoAndReturnToTop ( - TuiOpaqueFuncPtr func,...) -#else -tuiDoAndReturnToTop (func, va_alist) - TuiOpaqueFuncPtr func; - va_dcl -#endif -{ - extern int terminal_is_ours; - - Opaque ret = (Opaque) NULL; - - /* It is an error to be tuiDo'ing if we - * don't own the terminal. - */ - if (!terminal_is_ours) - return ret; - - if (tui_version) - { - va_list args; - -#ifdef __STDC__ - va_start (args, func); -#else - va_start (args); -#endif - ret = _tui_vDo (func, args); - - /* force a return to the top level */ - return_to_top_level (RETURN_ERROR); - } - - return ret; -} /* tuiDoAndReturnToTop */ - - -void -#ifdef __STDC__ -tui_vSelectSourceSymtab ( - va_list args) -#else -tui_vSelectSourceSymtab (args) - va_list args; -#endif -{ - struct symtab *s = va_arg (args, struct symtab *); - - select_source_symtab (s); - return; -} /* tui_vSelectSourceSymtab */ - - -/* -** _initialize_tui(). -** Function to initialize gdb commands, for tui window manipulation. -*/ -void -_initialize_tui () -{ -#if 0 - if (tui_version) - { - add_com ("toggle", class_tui, _toggle_command, - "Toggle Terminal UI Features\n\ -Usage: Toggle $fregs\n\ -\tToggles between single and double precision floating point registers.\n"); - } -#endif - char *helpStr; - - if (tui_version) - helpStr = "Toggle Specified Features\n\ -Usage:\ttoggle $fregs\n\ttoggle breakpoints"; - else - helpStr = "Toggle Specified Features\nUsage:toggle breakpoints"; - add_abbrev_prefix_cmd ("toggle", - class_tui, - _toggle_command, - helpStr, - &togglelist, - "toggle ", - 1, - &cmdlist); -} /* _initialize_tui*/ - - -/* -** va_catch_errors(). -** General purpose function to execute a function, catching errors. -** If there is no error, the value returned by 'func' is returned. -** If there is error, then zero is returned. -** Note that 'func' must take a variable argument list as well. -** -** Must not be called with immediate_quit in effect (bad things might -** happen, say we got a signal in the middle of a memcpy to quit_return). -** This is an OK restriction; with very few exceptions immediate_quit can -** be replaced by judicious use of QUIT. -*/ -Opaque -#ifdef __STDC__ -va_catch_errors ( - TuiOpaqueFuncPtr func, - va_list args) -#else -va_catch_errors (func, args) - TuiOpaqueFuncPtr func; - va_list args; -#endif -{ - Opaque ret = (Opaque) NULL; - - /* - ** We could have used catch_errors(), but it doesn't handle variable args. - ** Also, for the tui, we always want to catch all errors, so we don't - ** need to pass a mask, or an error string. - */ - jmp_buf saved_error; - jmp_buf saved_quit; - jmp_buf tmp_jmp; - struct cleanup *saved_cleanup_chain; - char *saved_error_pre_print; - char *saved_quit_pre_print; - extern jmp_buf error_return; - extern jmp_buf quit_return; - - saved_cleanup_chain = save_cleanups (); - saved_error_pre_print = error_pre_print; - saved_quit_pre_print = quit_pre_print; - - memcpy ((char *) saved_error, (char *) error_return, sizeof (jmp_buf)); - error_pre_print = ""; - memcpy (saved_quit, quit_return, sizeof (jmp_buf)); - quit_pre_print = ""; - - if (setjmp (tmp_jmp) == 0) - { - va_list argList = args; - memcpy (error_return, tmp_jmp, sizeof (jmp_buf)); - memcpy (quit_return, tmp_jmp, sizeof (jmp_buf)); - ret = func (argList); - } - restore_cleanups (saved_cleanup_chain); - memcpy (error_return, saved_error, sizeof (jmp_buf)); - error_pre_print = saved_error_pre_print; - memcpy (quit_return, saved_quit, sizeof (jmp_buf)); - quit_pre_print = saved_quit_pre_print; - - return ret; -} - -/* -** vcatch_errors(). -** Catch errors occurring in tui or non tui function, handling -** variable param lists. Note that 'func' must take a variable -** argument list as well. -*/ -Opaque -#ifdef __STDC__ -vcatch_errors ( - OpaqueFuncPtr func,...) -#else -vcatch_errors (va_alist) - va_dcl -/* -vcatch_errors(func, va_alist) - OpaqueFuncPtr func; - va_dcl -*/ -#endif -{ - Opaque ret = (Opaque) NULL; - va_list args; -#ifdef __STDC__ - va_start (args, func); -/* - va_arg(args, OpaqueFuncPtr); -*/ -#else - OpaqueFuncPtr func; - - va_start (args); - func = va_arg (args, OpaqueFuncPtr); -#endif - ret = va_catch_errors (func, args); - va_end (args); - - return ret; -} - - -void -#ifdef __STDC__ -strcat_to_buf ( - char *buf, - int buflen, - char *itemToAdd) -#else -strcat_to_buf (buf, buflen, itemToAdd) - char *buf; - int buflen; - char *itemToAdd; -#endif -{ - if (itemToAdd != (char *) NULL && buf != (char *) NULL) - { - if ((strlen (buf) + strlen (itemToAdd)) <= buflen) - strcat (buf, itemToAdd); - else - strncat (buf, itemToAdd, (buflen - strlen (buf))); - } - - return; -} /* strcat_to_buf */ - -/* VARARGS */ -void -#ifdef ANSI_PROTOTYPES -strcat_to_buf_with_fmt ( - char *buf, - int bufLen, - char *format,...) -#else -strcat_to_buf_with_fmt (va_alist) - va_dcl -#endif -{ - char *linebuffer; - struct cleanup *old_cleanups; - va_list args; -#ifdef ANSI_PROTOTYPES - va_start (args, format); -#else - char *buf; - int bufLen; - char *format; - - va_start (args); - buf = va_arg (args, char *); - bufLen = va_arg (args, int); - format = va_arg (args, char *); -#endif - vasprintf (&linebuffer, format, args); - old_cleanups = make_cleanup (free, linebuffer); - strcat_to_buf (buf, bufLen, linebuffer); - do_cleanups (old_cleanups); - va_end (args); -} - - - - - -/*********************** -** Static Functions -************************/ - - -/* -** _tui_vDo(). -** General purpose function to execute a tui function. Transitions -** between curses and the are handled here. This function is called -** by non-tui gdb functions. -** -** Errors are caught here. -** If there is no error, the value returned by 'func' is returned. -** If there is an error, then zero is returned. -** -** Must not be called with immediate_quit in effect (bad things might -** happen, say we got a signal in the middle of a memcpy to quit_return). -** This is an OK restriction; with very few exceptions immediate_quit can -** be replaced by judicious use of QUIT. -*/ -static Opaque -#ifdef __STDC__ -_tui_vDo ( - TuiOpaqueFuncPtr func, - va_list args) -#else -_tui_vDo (func, args) - TuiOpaqueFuncPtr func; - va_list args; -#endif -{ - extern int terminal_is_ours; - - Opaque ret = (Opaque) NULL; - - /* It is an error to be tuiDo'ing if we - * don't own the terminal. - */ - if (!terminal_is_ours) - return ret; - - if (tui_version) - { - /* If doing command window the "XDB way" (command window - * is unmanaged by curses... - */ - /* Set up terminal for TUI */ - tuiTermSetup (1); - - ret = va_catch_errors (func, args); - - /* Set up terminal for command window */ - tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch); - } - - return ret; -} /* _tui_vDo */ - - -static void -#ifdef __STDC__ -_toggle_command ( - char *arg, - int fromTTY) -#else -_toggle_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - printf_filtered ("Specify feature to toggle.\n%s\n", - (tui_version) ? TUI_TOGGLE_USAGE : TOGGLE_USAGE); -/* - tuiDo((TuiOpaqueFuncPtr)_Toggle_command, arg, fromTTY); -*/ -} - -/* -** _tui_vToggle_command(). -*/ -static void -#ifdef __STDC__ -_tui_vToggle_command ( - va_list args) -#else -_tui_vToggle_command (args) - va_list args; -#endif -{ - char *arg; - int fromTTY; - - arg = va_arg (args, char *); - - if (arg == (char *) NULL) - printf_filtered (TOGGLE_USAGE); - else - { - char *ptr = (char *) tuiStrDup (arg); - int i; - - for (i = 0; (ptr[i]); i++) - ptr[i] = toupper (arg[i]); - - if (subsetCompare (ptr, TUI_FLOAT_REGS_NAME)) - tuiToggleFloatRegs (); -/* else if (subsetCompare(ptr, "ANOTHER TOGGLE OPTION")) - ... -*/ - else - printf_filtered (TOGGLE_USAGE); - tuiFree (ptr); - } - - return; -} /* _tuiToggle_command */ - - -static void -#ifdef __STDC__ -_tuiReset (void) -#else -_tuiReset () -#endif -{ - struct termio mode; - - /* - ** reset the teletype mode bits to a sensible state. - ** Copied tset.c - */ -#if ! defined (USG) && defined (TIOCGETC) - struct tchars tbuf; -#endif /* !USG && TIOCGETC */ -#ifdef UCB_NTTY - struct ltchars ltc; - - if (ldisc == NTTYDISC) - { - ioctl (FILEDES, TIOCGLTC, <c); - ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z')); - ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y')); - ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R')); - ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O')); - ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W')); - ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V')); - ioctl (FILEDES, TIOCSLTC, <c); - } -#endif /* UCB_NTTY */ -#ifndef USG -#ifdef TIOCGETC - ioctl (FILEDES, TIOCGETC, &tbuf); - tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?')); - tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\')); - tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q')); - tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S')); - tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D')); - /* brkc is left alone */ - ioctl (FILEDES, TIOCSETC, &tbuf); -#endif /* TIOCGETC */ - mode.sg_flags &= ~(RAW -#ifdef CBREAK - | CBREAK -#endif /* CBREAK */ - | VTDELAY | ALLDELAY); - mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP; -#else /*USG*/ - ioctl (FILEDES, TCGETA, &mode); - mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?')); - mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\')); - mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D')); - - mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF); - mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON); - mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | - NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY); - mode.c_oflag |= (OPOST | ONLCR); - mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL); -#ifndef hp9000s800 - mode.c_cflag |= (CS8 | CREAD); -#else /*hp9000s800*/ - mode.c_cflag |= (CS8 | CSTOPB | CREAD); -#endif /* hp9000s800 */ - mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH); - mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK); - ioctl (FILEDES, TCSETAW, &mode); -#endif /* USG */ - - return; -} /* _tuiReset */ diff --git a/contrib/gdb/gdb/tui/tui.h b/contrib/gdb/gdb/tui/tui.h deleted file mode 100644 index bc9fb31e649..00000000000 --- a/contrib/gdb/gdb/tui/tui.h +++ /dev/null @@ -1,120 +0,0 @@ -/* External/Public TUI Header File */ - -#ifndef TUI_H -#define TUI_H -#include - -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - -#include "ansidecl.h" - -#if defined(reg) -#undef reg -#endif -#if defined(chtype) -#undef chtype -#endif - -/* Opaque data type */ -typedef char *Opaque; -typedef Opaque (*OpaqueFuncPtr) PARAMS ((va_list)); -typedef char **OpaqueList; -typedef OpaqueList OpaquePtr; - -/* Generic function pointer */ -typedef void (*TuiVoidFuncPtr) PARAMS ((va_list)); -typedef int (*TuiIntFuncPtr) PARAMS ((va_list)); -/* -typedef Opaque (*TuiOpaqueFuncPtr) PARAMS ((va_list)); -*/ -typedef OpaqueFuncPtr TuiOpaqueFuncPtr; - -extern Opaque vcatch_errors PARAMS ((OpaqueFuncPtr, ...)); -extern Opaque va_catch_errors PARAMS ((OpaqueFuncPtr, va_list)); - -extern void strcat_to_buf PARAMS ((char *, int, char *)); -extern void strcat_to_buf_with_fmt PARAMS ((char *, int, char *, ...)); - -/* Types of error returns */ -typedef enum { - TUI_SUCCESS, - TUI_FAILURE -} TuiStatus, *TuiStatusPtr; - -/* Types of windows */ -typedef enum { - SRC_WIN = 0, - DISASSEM_WIN, - DATA_WIN, - CMD_WIN, - /* This must ALWAYS be AFTER the major windows last */ - MAX_MAJOR_WINDOWS, - /* auxillary windows */ - LOCATOR_WIN, - EXEC_INFO_WIN, - DATA_ITEM_WIN, - /* This must ALWAYS be next to last */ - MAX_WINDOWS, - UNDEFINED_WIN /* LAST */ -} TuiWinType, *TuiWinTypePtr; - -/* This is a point definition */ -typedef struct _TuiPoint { - int x, y; -} TuiPoint, *TuiPointPtr; - -/* Generic window information */ -typedef struct _TuiGenWinInfo { - WINDOW *handle; /* window handle */ - TuiWinType type; /* type of window */ - int width; /* window width */ - int height; /* window height */ - TuiPoint origin; /* origin of window */ - OpaquePtr content; /* content of window */ - int contentSize; /* Size of content (# of elements) */ - int contentInUse; /* Can it be used, or is it already used? */ - int viewportHeight; /* viewport height */ - int lastVisibleLine; /* index of last visible line */ - int isVisible; /* whether the window is visible or not */ -} TuiGenWinInfo, *TuiGenWinInfoPtr; - -/* GENERAL TUI FUNCTIONS */ -/* tui.c */ -extern void tuiInit PARAMS ((char *argv0)); -extern void tuiInitWindows PARAMS ((void)); -extern void tuiResetScreen PARAMS ((void)); -extern void tuiCleanUp PARAMS ((void)); -extern void tuiError PARAMS ((char *, int)); -extern void tui_vError PARAMS ((va_list)); -extern void tuiFree PARAMS ((char *)); -extern Opaque tuiDo PARAMS ((TuiOpaqueFuncPtr, ...)); -extern Opaque tuiDoAndReturnToTop PARAMS ((TuiOpaqueFuncPtr, ...)); -extern Opaque tuiGetLowDisassemblyAddress PARAMS ((Opaque, Opaque)); -extern Opaque tui_vGetLowDisassemblyAddress PARAMS ((va_list)); -extern void tui_vSelectSourceSymtab PARAMS ((va_list)); - -/* tuiDataWin.c */ -extern void tui_vCheckDataValues PARAMS ((va_list)); - -/* tuiIO.c */ -extern void tui_vStartNewLines PARAMS ((va_list)); - -/* tuiLayout.c */ -extern void tui_vAddWinToLayout PARAMS ((va_list)); -extern TuiStatus tui_vSetLayoutTo PARAMS ((va_list)); - -/* tuiSourceWin.c */ -extern void tuiDisplayMainFunction PARAMS ((void)); -extern void tuiUpdateAllExecInfos PARAMS ((void)); -extern void tuiUpdateOnEnd PARAMS ((void)); -extern void tui_vAllSetHasBreakAt PARAMS ((va_list)); -extern void tui_vUpdateSourceWindowsWithAddr PARAMS ((va_list)); - -/* tuiStack.c */ -extern void tui_vShowFrameInfo PARAMS ((va_list)); -extern void tui_vUpdateLocatorFilename PARAMS ((va_list)); -#endif /* TUI_H */ diff --git a/contrib/gdb/gdb/tui/tuiCommand.c b/contrib/gdb/gdb/tui/tuiCommand.c deleted file mode 100644 index 454dc62e857..00000000000 --- a/contrib/gdb/gdb/tui/tuiCommand.c +++ /dev/null @@ -1,215 +0,0 @@ -/* -** tuiCommand.c -** This module contains functions specific to command window processing. -*/ - - -#include "defs.h" -#include "tui.h" -#include "tuiData.h" -#include "tuiWin.h" -#include "tuiIO.h" - - -/***************************************** -** STATIC LOCAL FUNCTIONS FORWARD DECLS ** -******************************************/ - - - -/***************************************** -** PUBLIC FUNCTIONS ** -******************************************/ - -/* -** tuiDispatchCtrlChar(). -** Dispatch the correct tui function based upon the control character. -*/ -unsigned int -#ifdef __STDC__ -tuiDispatchCtrlChar ( - unsigned int ch) -#else -tuiDispatchCtrlChar (ch) - unsigned int ch; -#endif -{ - TuiWinInfoPtr winInfo = tuiWinWithFocus (); - - /* - ** If the command window has the logical focus, or no-one does - ** assume it is the command window; in this case, pass the - ** character on through and do nothing here. - */ - if (winInfo == (TuiWinInfoPtr) NULL || winInfo == cmdWin) - return ch; - else - { - unsigned int c = 0, chCopy = ch; - register int i; - char *term; - - /* If this is an xterm, page next/prev keys aren't returned - ** by keypad as a single char, so we must handle them here. - ** Seems like a bug in the curses library? - */ - term = (char *) getenv ("TERM"); - for (i = 0; (term && term[i]); i++) - term[i] = toupper (term[i]); - if ((strcmp (term, "XTERM") == 0) && m_isStartSequence (ch)) - { - unsigned int pageCh = 0, tmpChar; - - tmpChar = 0; - while (!m_isEndSequence (tmpChar)) - { - tmpChar = (int) wgetch (cmdWin->generic.handle); - if (!tmpChar) - break; - if (tmpChar == 53) - pageCh = KEY_PPAGE; - else if (tmpChar == 54) - pageCh = KEY_NPAGE; - } - chCopy = pageCh; - } - - switch (chCopy) - { - case KEY_NPAGE: - tuiScrollForward (winInfo, 0); - break; - case KEY_PPAGE: - tuiScrollBackward (winInfo, 0); - break; - case KEY_DOWN: - case KEY_SF: - tuiScrollForward (winInfo, 1); - break; - case KEY_UP: - case KEY_SR: - tuiScrollBackward (winInfo, 1); - break; - case KEY_RIGHT: - tuiScrollLeft (winInfo, 1); - break; - case KEY_LEFT: - tuiScrollRight (winInfo, 1); - break; - case '\f': - tuiRefreshAll (); - break; - default: - c = chCopy; - break; - } - return c; - } -} /* tuiDispatchCtrlChar */ - - -/* -** tuiIncrCommandCharCountBy() -** Increment the current character count in the command window, -** checking for overflow. Returns the new value of the char count. -*/ -int -#ifdef __STDC__ -tuiIncrCommandCharCountBy ( - int count) -#else -tuiIncrCommandCharCountBy (count) - int count; -#endif -{ - if (tui_version) - { - if ((count + cmdWin->detail.commandInfo.curch) >= cmdWin->generic.width) - cmdWin->detail.commandInfo.curch = - (count + cmdWin->detail.commandInfo.curch) - cmdWin->generic.width; - else - cmdWin->detail.commandInfo.curch += count; - } - - return cmdWin->detail.commandInfo.curch; -} /* tuiIncrCommandCharCountBy */ - - -/* -** tuiDecrCommandCharCountBy() -** Decrement the current character count in the command window, -** checking for overflow. Returns the new value of the char count. -*/ -int -#ifdef __STDC__ -tuiDecrCommandCharCountBy ( - int count) -#else -tuiDecrCommandCharCountBy (count) - int count; -#endif -{ - if (tui_version) - { - if ((cmdWin->detail.commandInfo.curch - count) < 0) - cmdWin->detail.commandInfo.curch = - cmdWin->generic.width + (cmdWin->detail.commandInfo.curch - count); - else - cmdWin->detail.commandInfo.curch -= count; - } - - return cmdWin->detail.commandInfo.curch; -} /* tuiDecrCommandCharCountBy */ - - -/* -** tuiSetCommandCharCountTo() -** Set the character count to count. -*/ -int -#ifdef __STDC__ -tuiSetCommandCharCountTo ( - int count) -#else -tuiSetCommandCharCountTo (count) - int count; -#endif -{ - if (tui_version) - { - if (count > cmdWin->generic.width - 1) - { - cmdWin->detail.commandInfo.curch = 0; - tuiIncrCommandCharCountBy (count); - } - else - cmdWin->detail.commandInfo.curch -= count; - } - - return cmdWin->detail.commandInfo.curch; -} /* tuiSetCommandCharCountTo */ - - - -/* -** tuiClearCommandCharCount() -** Clear the character count to count. -*/ -int -#ifdef __STDC__ -tuiClearCommandCharCount (void) -#else -tuiClearCommandCharCount () -#endif -{ - if (tui_version) - cmdWin->detail.commandInfo.curch = 0; - - return cmdWin->detail.commandInfo.curch; -} /* tuiClearCommandCharCount */ - - - -/***************************************** -** STATIC LOCAL FUNCTIONS ** -******************************************/ diff --git a/contrib/gdb/gdb/tui/tuiCommand.h b/contrib/gdb/gdb/tui/tuiCommand.h deleted file mode 100644 index 206d918dd56..00000000000 --- a/contrib/gdb/gdb/tui/tuiCommand.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _TUI_COMMAND_H -#define _TUI_COMMAND_H -/* -** This header file supports -*/ - - -/***************************************** -** TYPE DEFINITIONS ** -******************************************/ - - - -/***************************************** -** PUBLIC FUNCTION EXTERNAL DECLS ** -******************************************/ - -extern unsigned int tuiDispatchCtrlChar PARAMS ((unsigned int)); -extern int tuiIncrCommandCharCountBy PARAMS ((int)); -extern int tuiDecrCommandCharCountBy PARAMS ((int)); -extern int tuiSetCommandCharCountTo PARAMS ((int)); -extern int tuiClearCommandCharCount PARAMS ((void)); - -#endif /*_TUI_COMMAND_H*/ diff --git a/contrib/gdb/gdb/tui/tuiData.c b/contrib/gdb/gdb/tui/tuiData.c deleted file mode 100644 index 758a6cde492..00000000000 --- a/contrib/gdb/gdb/tui/tuiData.c +++ /dev/null @@ -1,1624 +0,0 @@ -/* -** tuiData.c -** This module contains functions for manipulating the data -** structures used by the TUI -*/ - -#include "defs.h" -#include "tui.h" -#include "tuiData.h" - -/**************************** -** GLOBAL DECLARATIONS -****************************/ -TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS]; - -/*************************** -** Private Definitions -****************************/ -#define FILE_WIDTH 30 -#define PROC_WIDTH 40 -#define LINE_WIDTH 4 -#define PC_WIDTH 8 - -/*************************** -** Private data -****************************/ -static char *_tuiNullStr = TUI_NULL_STR; -static char *_tuiBlankStr = " "; -static char *_tuiLocationStr = " >"; -static char *_tuiBreakStr = " * "; -static char *_tuiBreakLocationStr = " *>"; -static TuiLayoutType _currentLayout = UNDEFINED_LAYOUT; -static int _termHeight, _termWidth; -static int _historyLimit = DEFAULT_HISTORY_COUNT; -static TuiGenWinInfo _locator; -static TuiGenWinInfo _execInfo[2]; -static TuiWinInfoPtr _srcWinList[2]; -static TuiList _sourceWindows = -{(OpaqueList) _srcWinList, 0}; -static int _defaultTabLen = DEFAULT_TAB_LEN; -static TuiWinInfoPtr _winWithFocus = (TuiWinInfoPtr) NULL; -static TuiLayoutDef _layoutDef = -{SRC_WIN, /* displayMode */ - FALSE, /* split */ - TUI_UNDEFINED_REGS, /* regsDisplayType */ - TUI_SFLOAT_REGS}; /* floatRegsDisplayType */ -static int _winResized = FALSE; - - -/********************************* -** Static function forward decls -**********************************/ -static void freeContent PARAMS ((TuiWinContent, int, TuiWinType)); -static void freeContentElements PARAMS ((TuiWinContent, int, TuiWinType)); - - - -/********************************* -** PUBLIC FUNCTIONS -**********************************/ - -/****************************************** -** ACCESSORS & MUTATORS FOR PRIVATE DATA -******************************************/ - -/* -** tuiWinResized(). -** Answer a whether the terminal window has been resized or not -*/ -int -#ifdef __STDC__ -tuiWinResized (void) -#else -tuiWinResized () -#endif -{ - return _winResized; -} /* tuiWinResized */ - - -/* -** tuiSetWinResized(). -** Set a whether the terminal window has been resized or not -*/ -void -#ifdef __STDC__ -tuiSetWinResizedTo ( - int resized) -#else -tuiSetWinResizedTo (resized) - int resized; -#endif -{ - _winResized = resized; - - return; -} /* tuiSetWinResizedTo */ - - -/* -** tuiLayoutDef(). -** Answer a pointer to the current layout definition -*/ -TuiLayoutDefPtr -#ifdef __STDC__ -tuiLayoutDef (void) -#else -tuiLayoutDef () -#endif -{ - return &_layoutDef; -} /* tuiLayoutDef */ - - -/* -** tuiWinWithFocus(). -** Answer the window with the logical focus -*/ -TuiWinInfoPtr -#ifdef __STDC__ -tuiWinWithFocus (void) -#else -tuiWinWithFocus () -#endif -{ - return _winWithFocus; -} /* tuiWinWithFocus */ - - -/* -** tuiSetWinWithFocus(). -** Set the window that has the logical focus -*/ -void -#ifdef __STDC__ -tuiSetWinWithFocus ( - TuiWinInfoPtr winInfo) -#else -tuiSetWinWithFocus (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - _winWithFocus = winInfo; - - return; -} /* tuiSetWinWithFocus */ - - -/* -** tuiDefaultTabLen(). -** Answer the length in chars, of tabs -*/ -int -#ifdef __STDC__ -tuiDefaultTabLen (void) -#else -tuiDefaultTabLen () -#endif -{ - return _defaultTabLen; -} /* tuiDefaultTabLen */ - - -/* -** tuiSetDefaultTabLen(). -** Set the length in chars, of tabs -*/ -void -#ifdef __STDC__ -tuiSetDefaultTabLen ( - int len) -#else -tuiSetDefaultTabLen (len) - int len; -#endif -{ - _defaultTabLen = len; - - return; -} /* tuiSetDefaultTabLen */ - - -/* -** currentSourceWin() -** Accessor for the current source window. Usually there is only -** one source window (either source or disassembly), but both can -** be displayed at the same time. -*/ -TuiListPtr -#ifdef __STDC__ -sourceWindows (void) -#else -sourceWindows () -#endif -{ - return &_sourceWindows; -} /* currentSourceWindows */ - - -/* -** clearSourceWindows() -** Clear the list of source windows. Usually there is only one -** source window (either source or disassembly), but both can be -** displayed at the same time. -*/ -void -#ifdef __STDC__ -clearSourceWindows (void) -#else -clearSourceWindows () -#endif -{ - _sourceWindows.list[0] = (Opaque) NULL; - _sourceWindows.list[1] = (Opaque) NULL; - _sourceWindows.count = 0; - - return; -} /* currentSourceWindows */ - - -/* -** clearSourceWindowsDetail() -** Clear the pertinant detail in the source windows. -*/ -void -#ifdef __STDC__ -clearSourceWindowsDetail (void) -#else -clearSourceWindowsDetail () -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - clearWinDetail ((TuiWinInfoPtr) (sourceWindows ())->list[i]); - - return; -} /* currentSourceWindows */ - - -/* -** addSourceWindowToList(). -** Add a window to the list of source windows. Usually there is -** only one source window (either source or disassembly), but -** both can be displayed at the same time. -*/ -void -#ifdef __STDC__ -addToSourceWindows ( - TuiWinInfoPtr winInfo) -#else -addToSourceWindows (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - if (_sourceWindows.count < 2) - _sourceWindows.list[_sourceWindows.count++] = (Opaque) winInfo; - - return; -} /* addToSourceWindows */ - - -/* -** clearWinDetail() -** Clear the pertinant detail in the windows. -*/ -void -#ifdef __STDC__ -clearWinDetail ( - TuiWinInfoPtr winInfo) -#else -clearWinDetail (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - if (m_winPtrNotNull (winInfo)) - { - switch (winInfo->generic.type) - { - case SRC_WIN: - case DISASSEM_WIN: - winInfo->detail.sourceInfo.startLineOrAddr.addr = (Opaque) NULL; - winInfo->detail.sourceInfo.horizontalOffset = 0; - break; - case CMD_WIN: - winInfo->detail.commandInfo.curLine = - winInfo->detail.commandInfo.curch = 0; - break; - case DATA_WIN: - winInfo->detail.dataDisplayInfo.dataContent = - (TuiWinContent) NULL; - winInfo->detail.dataDisplayInfo.dataContentCount = 0; - winInfo->detail.dataDisplayInfo.regsContent = - (TuiWinContent) NULL; - winInfo->detail.dataDisplayInfo.regsContentCount = 0; - winInfo->detail.dataDisplayInfo.regsDisplayType = - TUI_UNDEFINED_REGS; - winInfo->detail.dataDisplayInfo.regsColumnCount = 1; - winInfo->detail.dataDisplayInfo.displayRegs = FALSE; - break; - default: - break; - } - } - - return; -} /* clearWinDetail */ - - -/* -** blankStr() -** Accessor for the blank string. -*/ -char * -#ifdef __STDC__ -blankStr (void) -#else -blankStr () -#endif -{ - return _tuiBlankStr; -} /* blankStr */ - - -/* -** locationStr() -** Accessor for the location string. -*/ -char * -#ifdef __STDC__ -locationStr (void) -#else -locationStr () -#endif -{ - return _tuiLocationStr; -} /* locationStr */ - - -/* -** breakStr() -** Accessor for the break string. -*/ -char * -#ifdef __STDC__ -breakStr (void) -#else -breakStr () -#endif -{ - return _tuiBreakStr; -} /* breakStr */ - - -/* -** breakLocationStr() -** Accessor for the breakLocation string. -*/ -char * -#ifdef __STDC__ -breakLocationStr (void) -#else -breakLocationStr () -#endif -{ - return _tuiBreakLocationStr; -} /* breakLocationStr */ - - -/* -** nullStr() -** Accessor for the null string. -*/ -char * -#ifdef __STDC__ -nullStr (void) -#else -nullStr () -#endif -{ - return _tuiNullStr; -} /* nullStr */ - - -/* -** sourceExecInfoPtr(). -** Accessor for the source execution info ptr. -*/ -TuiGenWinInfoPtr -#ifdef __STDC__ -sourceExecInfoWinPtr (void) -#else -sourceExecInfoWinPtr () -#endif -{ - return &_execInfo[0]; -} /* sourceExecInfoWinPtr */ - - -/* -** disassemExecInfoPtr(). -** Accessor for the disassem execution info ptr. -*/ -TuiGenWinInfoPtr -#ifdef __STDC__ -disassemExecInfoWinPtr (void) -#else -disassemExecInfoWinPtr () -#endif -{ - return &_execInfo[1]; -} /* disassemExecInfoWinPtr */ - - -/* -** locatorWinInfoPtr(). -** Accessor for the locator win info. Answers a pointer to the -** static locator win info struct. -*/ -TuiGenWinInfoPtr -#ifdef __STDC__ -locatorWinInfoPtr (void) -#else -locatorWinInfoPtr () -#endif -{ - return &_locator; -} /* locatorWinInfoPtr */ - - -/* -** historyLimit(). -** Accessor for the history limit -*/ -int -#ifdef __STDC__ -historyLimit (void) -#else -historyLimit () -#endif -{ - return _historyLimit; -} /* historyLimit */ - - -/* -** setHistoryLimitTo(). -** Mutator for the history limit -*/ -void -#ifdef __STDC__ -setHistoryLimitTo ( - int h) -#else -setHistoryLimitTo (h) - int h; -#endif -{ - _historyLimit = h; - - return; -} /* setHistoryLimitTo */ - -/* -** termHeight(). -** Accessor for the termHeight -*/ -int -#ifdef __STDC__ -termHeight (void) -#else -termHeight () -#endif -{ - return _termHeight; -} /* termHeight */ - - -/* -** setTermHeightTo(). -** Mutator for the term height -*/ -void -#ifdef __STDC__ -setTermHeightTo ( - int h) -#else -setTermHeightTo (h) - int h; -#endif -{ - _termHeight = h; - - return; -} /* setTermHeightTo */ - - -/* -** termWidth(). -** Accessor for the termWidth -*/ -int -#ifdef __STDC__ -termWidth (void) -#else -termWidth () -#endif -{ - return _termWidth; -} /* termWidth */ - - -/* -** setTermWidth(). -** Mutator for the termWidth -*/ -void -#ifdef __STDC__ -setTermWidthTo ( - int w) -#else -setTermWidthTo (w) - int w; -#endif -{ - _termWidth = w; - - return; -} /* setTermWidthTo */ - - -/* -** currentLayout(). -** Accessor for the current layout -*/ -TuiLayoutType -#ifdef __STDC__ -currentLayout (void) -#else -currentLayout () -#endif -{ - return _currentLayout; -} /* currentLayout */ - - -/* -** setCurrentLayoutTo(). -** Mutator for the current layout -*/ -void -#ifdef __STDC__ -setCurrentLayoutTo ( - TuiLayoutType newLayout) -#else -setCurrentLayoutTo (newLayout) - TuiLayoutType newLayout; -#endif -{ - _currentLayout = newLayout; - - return; -} /* setCurrentLayoutTo */ - - -/* -** setGenWinOrigin(). -** Set the origin of the window -*/ -void -#ifdef __STDC__ -setGenWinOrigin ( - TuiGenWinInfoPtr winInfo, - int x, - int y) -#else -setGenWinOrigin (winInfo, x, y) - TuiGenWinInfoPtr winInfo; - int x; - int y; -#endif -{ - winInfo->origin.x = x; - winInfo->origin.y = y; - - return; -} /* setGenWinOrigin */ - - -/***************************** -** OTHER PUBLIC FUNCTIONS -*****************************/ - - -/* -** tuiNextWin(). -** Answer the next window in the list, cycling back to the top -** if necessary -*/ -TuiWinInfoPtr -#ifdef __STDC__ -tuiNextWin ( - TuiWinInfoPtr curWin) -#else -tuiNextWin (curWin) - TuiWinInfoPtr curWin; -#endif -{ - TuiWinType type = curWin->generic.type; - TuiWinInfoPtr nextWin = (TuiWinInfoPtr) NULL; - - if (curWin->generic.type == CMD_WIN) - type = SRC_WIN; - else - type = curWin->generic.type + 1; - while (type != curWin->generic.type && m_winPtrIsNull (nextWin)) - { - if (winList[type]->generic.isVisible) - nextWin = winList[type]; - else - { - if (type == CMD_WIN) - type = SRC_WIN; - else - type++; - } - } - - return nextWin; -} /* tuiNextWin */ - - -/* -** tuiPrevWin(). -** Answer the prev window in the list, cycling back to the bottom -** if necessary -*/ -TuiWinInfoPtr -#ifdef __STDC__ -tuiPrevWin ( - TuiWinInfoPtr curWin) -#else -tuiPrevWin (curWin) - TuiWinInfoPtr curWin; -#endif -{ - TuiWinType type = curWin->generic.type; - TuiWinInfoPtr prev = (TuiWinInfoPtr) NULL; - - if (curWin->generic.type == SRC_WIN) - type = CMD_WIN; - else - type = curWin->generic.type - 1; - while (type != curWin->generic.type && m_winPtrIsNull (prev)) - { - if (winList[type]->generic.isVisible) - prev = winList[type]; - else - { - if (type == SRC_WIN) - type = CMD_WIN; - else - type--; - } - } - - return prev; -} /* tuiPrevWin */ - - -/* -** displayableWinContentOf(). -** Answer a the content at the location indicated by index. Note -** that if this is a locator window, the string returned should be -** freed after use. -*/ -char * -#ifdef __STDC__ -displayableWinContentOf ( - TuiGenWinInfoPtr winInfo, - TuiWinElementPtr elementPtr) -#else -displayableWinContentOf (winInfo, elementPtr) - TuiGenWinInfoPtr winInfo; - TuiWinElementPtr elementPtr; -#endif -{ - - char *string = nullStr (); - - if (elementPtr != (TuiWinElementPtr) NULL || winInfo->type == LOCATOR_WIN) - { - /* - ** Now convert the line to a displayable string - */ - switch (winInfo->type) - { - case SRC_WIN: - case DISASSEM_WIN: - string = elementPtr->whichElement.source.line; - break; - case CMD_WIN: - string = elementPtr->whichElement.command.line; - break; - case LOCATOR_WIN: - if ((string = (char *) xmalloc ( - (termWidth () + 1) * sizeof (char))) == (char *) NULL) - string = nullStr (); - else - { - char lineNo[50], pc[50], buf[50], *fname, *pname; - register int strSize = termWidth (), i, procWidth, fileWidth; - - /* - ** First determine the amount of file/proc name width - ** we have available - */ - i = strSize - (PC_WIDTH + LINE_WIDTH - + 25 /* pc and line labels */ - + strlen (FILE_PREFIX) + 1 /* file label */ - + 15 /* procedure label */ ); - if (i >= FILE_WIDTH + PROC_WIDTH) - { - fileWidth = FILE_WIDTH; - procWidth = PROC_WIDTH; - } - else - { - fileWidth = i / 2; - procWidth = i - fileWidth; - } - - /* Now convert elements to string form */ - if (elementPtr != (TuiWinElementPtr) NULL && - *elementPtr->whichElement.locator.fileName != (char) 0 && - srcWin->generic.isVisible) - fname = elementPtr->whichElement.locator.fileName; - else - fname = "??"; - if (elementPtr != (TuiWinElementPtr) NULL && - *elementPtr->whichElement.locator.procName != (char) 0) - pname = elementPtr->whichElement.locator.procName; - else - pname = "??"; - if (elementPtr != (TuiWinElementPtr) NULL && - elementPtr->whichElement.locator.lineNo > 0) - sprintf (lineNo, "%d", - elementPtr->whichElement.locator.lineNo); - else - strcpy (lineNo, "??"); - if (elementPtr != (TuiWinElementPtr) NULL && - elementPtr->whichElement.locator.addr > (Opaque) 0) - sprintf (pc, "0x%x", - elementPtr->whichElement.locator.addr); - else - strcpy (pc, "??"); - /* - ** Now create the locator line from the string version - ** of the elements. We could use sprintf() here but - ** that wouldn't ensure that we don't overrun the size - ** of the allocated buffer. strcat_to_buf() will. - */ - *string = (char) 0; - /* Filename */ - strcat_to_buf (string, strSize, " "); - strcat_to_buf (string, strSize, FILE_PREFIX); - if (strlen (fname) > fileWidth) - { - strncpy (buf, fname, fileWidth - 1); - buf[fileWidth - 1] = '*'; - buf[fileWidth] = (char) 0; - } - else - strcpy (buf, fname); - strcat_to_buf (string, strSize, buf); - /* procedure/class name */ - sprintf (buf, "%15s", PROC_PREFIX); - strcat_to_buf (string, strSize, buf); - if (strlen (pname) > procWidth) - { - strncpy (buf, pname, procWidth - 1); - buf[procWidth - 1] = '*'; - buf[procWidth] = (char) 0; - } - else - strcpy (buf, pname); - strcat_to_buf (string, strSize, buf); - sprintf (buf, "%10s", LINE_PREFIX); - strcat_to_buf (string, strSize, buf); - strcat_to_buf (string, strSize, lineNo); - sprintf (buf, "%10s", PC_PREFIX); - strcat_to_buf (string, strSize, buf); - strcat_to_buf (string, strSize, pc); - for (i = strlen (string); i < strSize; i++) - string[i] = ' '; - string[strSize] = (char) 0; - } - break; - case EXEC_INFO_WIN: - string = elementPtr->whichElement.simpleString; - break; - default: - break; - } - } - return string; -} /* displayableWinContentOf */ - - -/* -** winContentAt(). -** Answer a the content at the location indicated by index -*/ -char * -#ifdef __STDC__ -displayableWinContentAt ( - TuiGenWinInfoPtr winInfo, - int index) -#else -displayableWinContentAt (winInfo, index) - TuiGenWinInfoPtr winInfo; - int index; -#endif -{ - return (displayableWinContentOf (winInfo, (TuiWinElementPtr) winInfo->content[index])); -} /* winContentAt */ - - -/* -** winElementHeight(). -** Answer the height of the element in lines -*/ -int -#ifdef __STDC__ -winElementHeight ( - TuiGenWinInfoPtr winInfo, - TuiWinElementPtr element) -#else -winElementHeight (winInfo, element) - TuiGenWinInfoPtr winInfo; - TuiWinElementPtr element; -#endif -{ - int h; - - if (winInfo->type == DATA_WIN) -/* FOR NOW SAY IT IS ONLY ONE LINE HIGH */ - h = 1; - else - h = 1; - - return h; -} /* winElementHeight */ - - -/* -** winByName(). -** Answer the window represented by name -*/ -TuiWinInfoPtr -#ifdef __STDC__ -winByName ( - char *name) -#else -winByName (name) - char *name; -#endif -{ - TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; - int i = 0; - - while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo)) - { - if (strcmp (name, winName (&(winList[i]->generic))) == 0) - winInfo = winList[i]; - i++; - } - - return winInfo; -} /* winByName */ - - -/* -** partialWinByName(). -** Answer the window represented by name -*/ -TuiWinInfoPtr -#ifdef __STDC__ -partialWinByName ( - char *name) -#else -partialWinByName (name) - char *name; -#endif -{ - TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; - - if (name != (char *) NULL) - { - int i = 0; - - while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo)) - { - char *curName = winName (&winList[i]->generic); - if (strlen (name) <= strlen (curName) && - strncmp (name, curName, strlen (name)) == 0) - winInfo = winList[i]; - i++; - } - } - - return winInfo; -} /* partialWinByName */ - - -/* -** winName(). -** Answer the name of the window -*/ -char * -#ifdef __STDC__ -winName ( - TuiGenWinInfoPtr winInfo) -#else -winName (winInfo) - TuiGenWinInfoPtr winInfo; -#endif -{ - char *name = (char *) NULL; - - switch (winInfo->type) - { - case SRC_WIN: - name = SRC_NAME; - break; - case CMD_WIN: - name = CMD_NAME; - break; - case DISASSEM_WIN: - name = DISASSEM_NAME; - break; - case DATA_WIN: - name = DATA_NAME; - break; - default: - name = ""; - break; - } - - return name; -} /* winName */ - - -/* -** initializeStaticData -*/ -void -#ifdef __STDC__ -initializeStaticData (void) -#else -initializeStaticData () -#endif -{ - initGenericPart (sourceExecInfoWinPtr ()); - initGenericPart (disassemExecInfoWinPtr ()); - initGenericPart (locatorWinInfoPtr ()); - - return; -} /* initializeStaticData */ - - -/* -** allocGenericWinInfo(). -*/ -TuiGenWinInfoPtr -#ifdef __STDC__ -allocGenericWinInfo (void) -#else -allocGenericWinInfo () -#endif -{ - TuiGenWinInfoPtr win; - - if ((win = (TuiGenWinInfoPtr) xmalloc ( - sizeof (TuiGenWinInfoPtr))) != (TuiGenWinInfoPtr) NULL) - initGenericPart (win); - - return win; -} /* allocGenericWinInfo */ - - -/* -** initGenericPart(). -*/ -void -#ifdef __STDC__ -initGenericPart ( - TuiGenWinInfoPtr win) -#else -initGenericPart (win) - TuiGenWinInfoPtr win; -#endif -{ - win->width = - win->height = - win->origin.x = - win->origin.y = - win->viewportHeight = - win->contentSize = - win->lastVisibleLine = 0; - win->handle = (WINDOW *) NULL; - win->content = (OpaquePtr) NULL; - win->contentInUse = - win->isVisible = FALSE; - - return; -} /* initGenericPart */ - - -/* -** initContentElement(). -*/ -void -#ifdef __STDC__ -initContentElement ( - TuiWinElementPtr element, - TuiWinType type) -#else -initContentElement (element, type) - TuiWinElementPtr element; - TuiWinType type; -#endif -{ - element->highlight = FALSE; - switch (type) - { - case SRC_WIN: - case DISASSEM_WIN: - element->whichElement.source.line = (char *) NULL; - element->whichElement.source.lineOrAddr.lineNo = 0; - element->whichElement.source.isExecPoint = FALSE; - element->whichElement.source.hasBreak = FALSE; - break; - case DATA_WIN: - initGenericPart (&element->whichElement.dataWindow); - element->whichElement.dataWindow.type = DATA_ITEM_WIN; - ((TuiGenWinInfoPtr) & element->whichElement.dataWindow)->content = - (OpaquePtr) allocContent (1, DATA_ITEM_WIN); - ((TuiGenWinInfoPtr) - & element->whichElement.dataWindow)->contentSize = 1; - break; - case CMD_WIN: - element->whichElement.command.line = (char *) NULL; - break; - case DATA_ITEM_WIN: - element->whichElement.data.name = (char *) NULL; - element->whichElement.data.type = TUI_REGISTER; - element->whichElement.data.itemNo = UNDEFINED_ITEM; - element->whichElement.data.value = (Opaque) NULL; - element->whichElement.data.highlight = FALSE; - break; - case LOCATOR_WIN: - element->whichElement.locator.fileName[0] = - element->whichElement.locator.procName[0] = (char) 0; - element->whichElement.locator.lineNo = 0; - element->whichElement.locator.addr = 0; - break; - case EXEC_INFO_WIN: - element->whichElement.simpleString = blankStr (); - break; - default: - break; - } - return; -} /* initContentElement */ - -/* -** initWinInfo(). -*/ -void -#ifdef __STDC__ -initWinInfo ( - TuiWinInfoPtr winInfo) -#else -initWinInfo (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - initGenericPart (&winInfo->generic); - winInfo->canHighlight = - winInfo->isHighlighted = FALSE; - switch (winInfo->generic.type) - { - case SRC_WIN: - case DISASSEM_WIN: - winInfo->detail.sourceInfo.executionInfo = (TuiGenWinInfoPtr) NULL; - winInfo->detail.sourceInfo.hasLocator = FALSE; - winInfo->detail.sourceInfo.horizontalOffset = 0; - winInfo->detail.sourceInfo.startLineOrAddr.addr = (Opaque) NULL; - break; - case DATA_WIN: - winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL; - winInfo->detail.dataDisplayInfo.dataContentCount = 0; - winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL; - winInfo->detail.dataDisplayInfo.regsContentCount = 0; - winInfo->detail.dataDisplayInfo.regsDisplayType = - TUI_UNDEFINED_REGS; - winInfo->detail.dataDisplayInfo.regsColumnCount = 1; - winInfo->detail.dataDisplayInfo.displayRegs = FALSE; - break; - case CMD_WIN: - winInfo->detail.commandInfo.curLine = 0; - winInfo->detail.commandInfo.curch = 0; - break; - default: - winInfo->detail.opaque = (Opaque) NULL; - break; - } - - return; -} /* initWinInfo */ - - -/* -** allocWinInfo(). -*/ -TuiWinInfoPtr -#ifdef __STDC__ -allocWinInfo ( - TuiWinType type) -#else -allocWinInfo (type) - TuiWinType type; -#endif -{ - TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; - - winInfo = (TuiWinInfoPtr) xmalloc (sizeof (TuiWinInfo)); - if (m_winPtrNotNull (winInfo)) - { - winInfo->generic.type = type; - initWinInfo (winInfo); - } - - return winInfo; -} /* allocWinInfo */ - - -/* -** allocContent(). -** Allocates the content and elements in a block. -*/ -TuiWinContent -#ifdef __STDC__ -allocContent ( - int numElements, - TuiWinType type) -#else -allocContent (numElements, type) - int numElements; - TuiWinType type; -#endif -{ - TuiWinContent content = (TuiWinContent) NULL; - char *elementBlockPtr = (char *) NULL; - int i; - - if ((content = (TuiWinContent) - xmalloc (sizeof (TuiWinElementPtr) * numElements)) != (TuiWinContent) NULL) - { /* - ** All windows, except the data window, can allocate the elements - ** in a chunk. The data window cannot because items can be - ** added/removed from the data display by the user at any time. - */ - if (type != DATA_WIN) - { - if ((elementBlockPtr = (char *) - xmalloc (sizeof (TuiWinElement) * numElements)) != (char *) NULL) - { - for (i = 0; i < numElements; i++) - { - content[i] = (TuiWinElementPtr) elementBlockPtr; - initContentElement (content[i], type); - elementBlockPtr += sizeof (TuiWinElement); - } - } - else - { - tuiFree ((char *) content); - content = (TuiWinContent) NULL; - } - } - } - - return content; -} /* allocContent */ - - -/* -** addContentElements(). -** Adds the input number of elements to the windows's content. If -** no content has been allocated yet, allocContent() is called to -** do this. The index of the first element added is returned, -** unless there is a memory allocation error, in which case, (-1) -** is returned. -*/ -int -#ifdef __STDC__ -addContentElements ( - TuiGenWinInfoPtr winInfo, - int numElements) -#else -addContentElements (winInfo, numElements) - TuiGenWinInfoPtr winInfo; - int numElements; -#endif -{ - TuiWinElementPtr elementPtr; - int i, indexStart; - - if (winInfo->content == (OpaquePtr) NULL) - { - winInfo->content = (OpaquePtr) allocContent (numElements, winInfo->type); - indexStart = 0; - } - else - indexStart = winInfo->contentSize; - if (winInfo->content != (OpaquePtr) NULL) - { - for (i = indexStart; (i < numElements + indexStart); i++) - { - if ((elementPtr = (TuiWinElementPtr) - xmalloc (sizeof (TuiWinElement))) != (TuiWinElementPtr) NULL) - { - winInfo->content[i] = (Opaque) elementPtr; - initContentElement (elementPtr, winInfo->type); - winInfo->contentSize++; - } - else /* things must be really hosed now! We ran out of memory!?*/ - return (-1); - } - } - - return indexStart; -} /* addContentElements */ - - -/* -** tuiDelWindow(). -** Delete all curses windows associated with winInfo, leaving everything -** else in tact. -*/ -void -#ifdef __STDC__ -tuiDelWindow ( - TuiWinInfoPtr winInfo) -#else -tuiDelWindow (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - Opaque detail; - int i; - TuiGenWinInfoPtr genericWin; - - - switch (winInfo->generic.type) - { - case SRC_WIN: - case DISASSEM_WIN: - genericWin = locatorWinInfoPtr (); - if (genericWin != (TuiGenWinInfoPtr) NULL) - { - tuiDelwin (genericWin->handle); - genericWin->handle = (WINDOW *) NULL; - genericWin->isVisible = FALSE; - } - genericWin = winInfo->detail.sourceInfo.executionInfo; - if (genericWin != (TuiGenWinInfoPtr) NULL) - { - tuiDelwin (genericWin->handle); - genericWin->handle = (WINDOW *) NULL; - genericWin->isVisible = FALSE; - } - break; - case DATA_WIN: - if (winInfo->generic.content != (OpaquePtr) NULL) - { - int i; - - tuiDelDataWindows ( - winInfo->detail.dataDisplayInfo.regsContent, - winInfo->detail.dataDisplayInfo.regsContentCount); - tuiDelDataWindows ( - winInfo->detail.dataDisplayInfo.dataContent, - winInfo->detail.dataDisplayInfo.dataContentCount); - } - break; - default: - break; - } - if (winInfo->generic.handle != (WINDOW *) NULL) - { - tuiDelwin (winInfo->generic.handle); - winInfo->generic.handle = (WINDOW *) NULL; - winInfo->generic.isVisible = FALSE; - } - - return; -} /* tuiDelWindow */ - - -/* -** freeWindow(). -*/ -void -#ifdef __STDC__ -freeWindow ( - TuiWinInfoPtr winInfo) -#else -freeWindow (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - Opaque detail; - int i; - TuiGenWinInfoPtr genericWin; - - - switch (winInfo->generic.type) - { - case SRC_WIN: - case DISASSEM_WIN: - genericWin = locatorWinInfoPtr (); - if (genericWin != (TuiGenWinInfoPtr) NULL) - { - tuiDelwin (genericWin->handle); - genericWin->handle = (WINDOW *) NULL; - } - freeWinContent (genericWin); - genericWin = winInfo->detail.sourceInfo.executionInfo; - if (genericWin != (TuiGenWinInfoPtr) NULL) - { - tuiDelwin (genericWin->handle); - genericWin->handle = (WINDOW *) NULL; - freeWinContent (genericWin); - } - break; - case DATA_WIN: - if (winInfo->generic.content != (OpaquePtr) NULL) - { - freeDataContent ( - winInfo->detail.dataDisplayInfo.regsContent, - winInfo->detail.dataDisplayInfo.regsContentCount); - winInfo->detail.dataDisplayInfo.regsContent = - (TuiWinContent) NULL; - winInfo->detail.dataDisplayInfo.regsContentCount = 0; - freeDataContent ( - winInfo->detail.dataDisplayInfo.dataContent, - winInfo->detail.dataDisplayInfo.dataContentCount); - winInfo->detail.dataDisplayInfo.dataContent = - (TuiWinContent) NULL; - winInfo->detail.dataDisplayInfo.dataContentCount = 0; - winInfo->detail.dataDisplayInfo.regsDisplayType = - TUI_UNDEFINED_REGS; - winInfo->detail.dataDisplayInfo.regsColumnCount = 1; - winInfo->detail.dataDisplayInfo.displayRegs = FALSE; - winInfo->generic.content = (OpaquePtr) NULL; - winInfo->generic.contentSize = 0; - } - break; - default: - break; - } - if (winInfo->generic.handle != (WINDOW *) NULL) - { - tuiDelwin (winInfo->generic.handle); - winInfo->generic.handle = (WINDOW *) NULL; - freeWinContent (&winInfo->generic); - } - free (winInfo); - - return; -} /* freeWindow */ - - -/* -** freeAllSourceWinsContent(). -*/ -void -#ifdef __STDC__ -freeAllSourceWinsContent (void) -#else -freeAllSourceWinsContent () -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - { - TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; - - if (m_winPtrNotNull (winInfo)) - { - freeWinContent (&(winInfo->generic)); - freeWinContent (winInfo->detail.sourceInfo.executionInfo); - } - } - - return; -} /* freeAllSourceWinsContent */ - - -/* -** freeWinContent(). -*/ -void -#ifdef __STDC__ -freeWinContent ( - TuiGenWinInfoPtr winInfo) -#else -freeWinContent (winInfo) - TuiGenWinInfoPtr winInfo; -#endif -{ - if (winInfo->content != (OpaquePtr) NULL) - { - freeContent ((TuiWinContent) winInfo->content, - winInfo->contentSize, - winInfo->type); - winInfo->content = (OpaquePtr) NULL; - } - winInfo->contentSize = 0; - - return; -} /* freeWinContent */ - - -/* -** freeAllWindows(). -*/ -void -#ifdef __STDC__ -freeAllWindows (void) -#else -freeAllWindows () -#endif -{ - TuiWinType type = SRC_WIN; - - for (; type < MAX_MAJOR_WINDOWS; type++) - if (m_winPtrNotNull (winList[type]) && - winList[type]->generic.type != UNDEFINED_WIN) - freeWindow (winList[type]); - return; -} /* freeAllWindows */ - - -void -#ifdef __STDC__ -tuiDelDataWindows ( - TuiWinContent content, - int contentSize) -#else -tuiDelDataWindows (content, contentSize) - TuiWinContent content; - int contentSize; -#endif -{ - int i; - - /* - ** Remember that data window content elements are of type TuiGenWinInfoPtr, - ** each of which whose single element is a data element. - */ - for (i = 0; i < contentSize; i++) - { - TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow; - - if (genericWin != (TuiGenWinInfoPtr) NULL) - { - tuiDelwin (genericWin->handle); - genericWin->handle = (WINDOW *) NULL; - genericWin->isVisible = FALSE; - } - } - - return; -} /* tuiDelDataWindows */ - - -void -#ifdef __STDC__ -freeDataContent ( - TuiWinContent content, - int contentSize) -#else -freeDataContent (content, contentSize) - TuiWinContent content; - int contentSize; -#endif -{ - int i; - - /* - ** Remember that data window content elements are of type TuiGenWinInfoPtr, - ** each of which whose single element is a data element. - */ - for (i = 0; i < contentSize; i++) - { - TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow; - - if (genericWin != (TuiGenWinInfoPtr) NULL) - { - tuiDelwin (genericWin->handle); - genericWin->handle = (WINDOW *) NULL; - freeWinContent (genericWin); - } - } - freeContent (content, - contentSize, - DATA_WIN); - - return; -} /* freeDataContent */ - - -/********************************** -** LOCAL STATIC FUNCTIONS ** -**********************************/ - - -/* -** freeContent(). -*/ -static void -#ifdef __STDC__ -freeContent ( - TuiWinContent content, - int contentSize, - TuiWinType winType) -#else -freeContent (content, contentSize, winType) - TuiWinContent content; - int contentSize; - TuiWinType winType; -#endif -{ - if (content != (TuiWinContent) NULL) - { - freeContentElements (content, contentSize, winType); - tuiFree ((char *) content); - } - - return; -} /* freeContent */ - - -/* -** freeContentElements(). -*/ -static void -#ifdef __STDC__ -freeContentElements ( - TuiWinContent content, - int contentSize, - TuiWinType type) -#else -freeContentElements (content, contentSize, type) - TuiWinContent content; - int contentSize; - TuiWinType type; -#endif -{ - if (content != (TuiWinContent) NULL) - { - int i; - - if (type == SRC_WIN || type == DISASSEM_WIN) - { - /* free whole source block */ - if (content[0]->whichElement.source.line != (char *) NULL) - tuiFree (content[0]->whichElement.source.line); - } - else - { - for (i = 0; i < contentSize; i++) - { - TuiWinElementPtr element; - - element = content[i]; - if (element != (TuiWinElementPtr) NULL) - { - switch (type) - { - case DATA_WIN: - tuiFree ((char *) element); - break; - case DATA_ITEM_WIN: - /* - ** Note that data elements are not allocated - ** in a single block, but individually, as needed. - */ - if (element->whichElement.data.type != TUI_REGISTER) - tuiFree ((char *) - element->whichElement.data.name); - tuiFree ((char *) element->whichElement.data.value); - tuiFree ((char *) element); - break; - case CMD_WIN: - tuiFree ((char *) element->whichElement.command.line); - break; - default: - break; - } - } - } - } - if (type != DATA_WIN && type != DATA_ITEM_WIN) - tuiFree ((char *) content[0]); /* free the element block */ - } - - return; -} /* freeContentElements */ diff --git a/contrib/gdb/gdb/tui/tuiData.h b/contrib/gdb/gdb/tui/tuiData.h deleted file mode 100644 index bb4d19c90e2..00000000000 --- a/contrib/gdb/gdb/tui/tuiData.h +++ /dev/null @@ -1,302 +0,0 @@ -#ifndef TUI_DATA_H -#define TUI_DATA_H - -/* Constant definitions */ -#define DEFAULT_TAB_LEN 8 -#define NO_SRC_STRING "[ No Source Available ]" -#define NO_DISASSEM_STRING "[ No Assembly Available ]" -#define NO_REGS_STRING "[ Register Values Unavailable ]" -#define NO_DATA_STRING "[ No Data Values Displayed ]" -#define MAX_CONTENT_COUNT 100 -#define SRC_NAME "SRC" -#define CMD_NAME "CMD" -#define DATA_NAME "REGS" -#define DISASSEM_NAME "ASM" -#define TUI_NULL_STR "" -#define DEFAULT_HISTORY_COUNT 25 -#define BOX_WINDOW TRUE -#define DONT_BOX_WINDOW FALSE -#define HILITE TRUE -#define NO_HILITE FALSE -#define WITH_LOCATOR TRUE -#define NO_LOCATOR FALSE -#define EMPTY_SOURCE_PROMPT TRUE -#define NO_EMPTY_SOURCE_PROMPT FALSE -#define UNDEFINED_ITEM -1 -#define MIN_WIN_HEIGHT 3 -#define MIN_CMD_WIN_HEIGHT 3 - -#define FILE_PREFIX "File: " -#define PROC_PREFIX "Procedure: " -#define LINE_PREFIX "Line: " -#define PC_PREFIX "pc: " - -#define TUI_FLOAT_REGS_NAME "$FREGS" -#define TUI_FLOAT_REGS_NAME_LOWER "$fregs" -#define TUI_GENERAL_REGS_NAME "$GREGS" -#define TUI_GENERAL_REGS_NAME_LOWER "$gregs" -#define TUI_SPECIAL_REGS_NAME "$SREGS" -#define TUI_SPECIAL_REGS_NAME_LOWER "$sregs" -#define TUI_GENERAL_SPECIAL_REGS_NAME "$REGS" -#define TUI_GENERAL_SPECIAL_REGS_NAME_LOWER "$regs" - -/* Scroll direction enum */ -typedef enum { - FORWARD_SCROLL, - BACKWARD_SCROLL, - LEFT_SCROLL, - RIGHT_SCROLL -} TuiScrollDirection, *TuiScrollDirectionPtr; - - -/* General list struct */ -typedef struct _TuiList { - OpaqueList list; - int count; -} TuiList, *TuiListPtr; - - -/* The kinds of layouts available */ -typedef enum { - SRC_COMMAND, - DISASSEM_COMMAND, - SRC_DISASSEM_COMMAND, - SRC_DATA_COMMAND, - DISASSEM_DATA_COMMAND, - UNDEFINED_LAYOUT -} TuiLayoutType, *TuiLayoutTypePtr; - -/* Basic data types that can be displayed in the data window. */ -typedef enum _TuiDataType { - TUI_REGISTER, - TUI_SCALAR, - TUI_COMPLEX, - TUI_STRUCT -} TuiDataType, TuiDataTypePtr; - -/* Types of register displays */ -typedef enum _TuiRegisterDisplayType { - TUI_UNDEFINED_REGS, - TUI_GENERAL_REGS, - TUI_SFLOAT_REGS, - TUI_DFLOAT_REGS, - TUI_SPECIAL_REGS, - TUI_GENERAL_AND_SPECIAL_REGS -} TuiRegisterDisplayType, *TuiRegisterDisplayTypePtr; - -/* Structure describing source line or line address */ -typedef union _TuiLineOrAddress { - int lineNo; - Opaque addr; -} TuiLineOrAddress, *TuiLineOrAddressPtr; - -/* Current Layout definition */ -typedef struct _TuiLayoutDef { - TuiWinType displayMode; - int split; - TuiRegisterDisplayType regsDisplayType; - TuiRegisterDisplayType floatRegsDisplayType; -} TuiLayoutDef, *TuiLayoutDefPtr; - -/* Elements in the Source/Disassembly Window */ -typedef struct _TuiSourceElement -{ - char *line; - TuiLineOrAddress lineOrAddr; - int isExecPoint; - int hasBreak; -} TuiSourceElement, *TuiSourceElementPtr; - - -/* Elements in the data display window content */ -typedef struct _TuiDataElement -{ - char *name; - int itemNo; /* the register number, or data display number */ - TuiDataType type; - Opaque value; - int highlight; -} TuiDataElement, *TuiDataElementPtr; - - -/* Elements in the command window content */ -typedef struct _TuiCommandElement -{ - char *line; -} TuiCommandElement, *TuiCommandElementPtr; - - -#define MAX_LOCATOR_ELEMENT_LEN 100 - -/* Elements in the locator window content */ -typedef struct _TuiLocatorElement -{ - char fileName[MAX_LOCATOR_ELEMENT_LEN]; - char procName[MAX_LOCATOR_ELEMENT_LEN]; - int lineNo; - Opaque addr; -} TuiLocatorElement, *TuiLocatorElementPtr; - - -/* An content element in a window */ -typedef union -{ - TuiSourceElement source; /* the source elements */ - TuiGenWinInfo dataWindow; /* data display elements */ - TuiDataElement data; /* elements of dataWindow */ - TuiCommandElement command; /* command elements */ - TuiLocatorElement locator; /* locator elements */ - char *simpleString; /* simple char based elements */ -} TuiWhichElement, *TuiWhichElementPtr; - -typedef struct _TuiWinElement -{ - int highlight; - TuiWhichElement whichElement; -} TuiWinElement, *TuiWinElementPtr; - - -/* This describes the content of the window. */ -typedef TuiWinElementPtr *TuiWinContent; - - -/* This struct defines the specific information about a data display window */ -typedef struct _TuiDataInfo { - TuiWinContent dataContent; /* start of data display content */ - int dataContentCount; - TuiWinContent regsContent; /* start of regs display content */ - int regsContentCount; - TuiRegisterDisplayType regsDisplayType; - int regsColumnCount; - int displayRegs; /* Should regs be displayed at all? */ -} TuiDataInfo, *TuiDataInfoPtr; - - -typedef struct _TuiSourceInfo { - int hasLocator; /* Does locator belongs to this window? */ - TuiGenWinInfoPtr executionInfo; /* execution information window */ - int horizontalOffset; /* used for horizontal scroll */ - TuiLineOrAddress startLineOrAddr; -} TuiSourceInfo, *TuiSourceInfoPtr; - - -typedef struct _TuiCommandInfo { - int curLine; /* The current line position */ - int curch; /* The current cursor position */ -} TuiCommandInfo, *TuiCommandInfoPtr; - - -/* This defines information about each logical window */ -typedef struct _TuiWinInfo { - TuiGenWinInfo generic; /* general window information */ - union { - TuiSourceInfo sourceInfo; - TuiDataInfo dataDisplayInfo; - TuiCommandInfo commandInfo; - Opaque opaque; - } detail; - int canHighlight; /* Can this window ever be highlighted? */ - int isHighlighted; /* Is this window highlighted? */ -} TuiWinInfo, *TuiWinInfoPtr; - -/* MACROS (prefixed with m_) */ - -/* Testing macros */ -#define m_genWinPtrIsNull(winInfo) \ - ((winInfo) == (TuiGenWinInfoPtr)NULL) -#define m_genWinPtrNotNull(winInfo) \ - ((winInfo) != (TuiGenWinInfoPtr)NULL) -#define m_winPtrIsNull(winInfo) \ - ((winInfo) == (TuiWinInfoPtr)NULL) -#define m_winPtrNotNull(winInfo) \ - ((winInfo) != (TuiWinInfoPtr)NULL) - -#define m_winIsSourceType(type) \ - (type == SRC_WIN || type == DISASSEM_WIN) -#define m_winIsAuxillary(winType) \ - (winType > MAX_MAJOR_WINDOWS) -#define m_hasLocator(winInfo) \ - ( ((winInfo) != (TuiWinInfoPtr)NULL) ? \ - (winInfo->detail.sourceInfo.hasLocator) : \ - FALSE ) - -#define m_setWinHighlightOn(winInfo) \ - if ((winInfo) != (TuiWinInfoPtr)NULL) \ - (winInfo)->isHighlighted = TRUE -#define m_setWinHighlightOff(winInfo) \ - if ((winInfo) != (TuiWinInfoPtr)NULL) \ - (winInfo)->isHighlighted = FALSE - - -/* Global Data */ -extern TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS]; -extern int tui_version; - -/* Macros */ -#define srcWin winList[SRC_WIN] -#define disassemWin winList[DISASSEM_WIN] -#define dataWin winList[DATA_WIN] -#define cmdWin winList[CMD_WIN] - -/* Data Manipulation Functions */ -extern void initializeStaticData PARAMS ((void)); -extern TuiGenWinInfoPtr allocGenericWinInfo PARAMS ((void)); -extern TuiWinInfoPtr allocWinInfo PARAMS ((TuiWinType)); -extern void initGenericPart PARAMS ((TuiGenWinInfoPtr)); -extern void initWinInfo PARAMS ((TuiWinInfoPtr)); -extern TuiWinContent allocContent PARAMS ((int, TuiWinType)); -extern int addContentElements - PARAMS ((TuiGenWinInfoPtr, int)); -extern void initContentElement - PARAMS ((TuiWinElementPtr, TuiWinType)); -extern void freeWindow PARAMS ((TuiWinInfoPtr)); -extern void freeAllWindows PARAMS ((void)); -extern void freeWinContent PARAMS ((TuiGenWinInfoPtr)); -extern void freeDataContent PARAMS ((TuiWinContent, int)); -extern void freeAllSourceWinsContent PARAMS ((void)); -extern void tuiDelWindow PARAMS ((TuiWinInfoPtr)); -extern void tuiDelDataWindows PARAMS ((TuiWinContent, int)); -extern TuiWinInfoPtr winByName PARAMS ((char *)); -extern TuiWinInfoPtr partialWinByName PARAMS ((char *)); -extern char *winName PARAMS ((TuiGenWinInfoPtr)); -extern char *displayableWinContentOf - PARAMS ((TuiGenWinInfoPtr, TuiWinElementPtr)); -extern char *displayableWinContentAt - PARAMS ((TuiGenWinInfoPtr, int)); -extern int winElementHeight - PARAMS ((TuiGenWinInfoPtr, TuiWinElementPtr)); -extern TuiLayoutType currentLayout PARAMS ((void)); -extern void setCurrentLayoutTo PARAMS ((TuiLayoutType)); -extern int termHeight PARAMS ((void)); -extern void setTermHeight PARAMS ((int)); -extern int termWidth PARAMS ((void)); -extern void setTermWidth PARAMS ((int)); -extern int historyLimit PARAMS ((void)); -extern void setHistoryLimit PARAMS ((int)); -extern void setGenWinOrigin PARAMS ((TuiGenWinInfoPtr, int, int)); -extern TuiGenWinInfoPtr locatorWinInfoPtr PARAMS ((void)); -extern TuiGenWinInfoPtr sourceExecInfoWinPtr PARAMS ((void)); -extern TuiGenWinInfoPtr disassemExecInfoWinPtr PARAMS ((void)); -extern char *nullStr PARAMS ((void)); -extern char *blankStr PARAMS ((void)); -extern char *locationStr PARAMS ((void)); -extern char *breakStr PARAMS ((void)); -extern char *breakLocationStr PARAMS ((void)); -extern TuiListPtr sourceWindows PARAMS ((void)); -extern void clearSourceWindows PARAMS ((void)); -extern void clearSourceWindowsDetail PARAMS ((void)); -extern void clearWinDetail PARAMS ((TuiWinInfoPtr winInfo)); -extern void tuiAddToSourceWindows PARAMS ((TuiWinInfoPtr)); -extern int tuiDefaultTabLen PARAMS ((void)); -extern void tuiSetDefaultTabLen PARAMS ((int)); -extern TuiWinInfoPtr tuiWinWithFocus PARAMS ((void)); -extern void tuiSetWinWithFocus PARAMS ((TuiWinInfoPtr)); -extern TuiLayoutDefPtr tuiLayoutDef PARAMS ((void)); -extern int tuiWinResized PARAMS ((void)); -extern void tuiSetWinResizedTo PARAMS ((int)); - -extern TuiWinInfoPtr tuiNextWin PARAMS ((TuiWinInfoPtr)); -extern TuiWinInfoPtr tuiPrevWin PARAMS ((TuiWinInfoPtr)); - - -#endif /* TUI_DATA_H */ diff --git a/contrib/gdb/gdb/tui/tuiDataWin.c b/contrib/gdb/gdb/tui/tuiDataWin.c deleted file mode 100644 index 522730ae2fd..00000000000 --- a/contrib/gdb/gdb/tui/tuiDataWin.c +++ /dev/null @@ -1,400 +0,0 @@ -/* -** tuiDataWin.c -** This module contains functions to support the data/register window display. -*/ - - -#include "defs.h" -#include "tui.h" -#include "tuiData.h" -#include "tuiRegs.h" - - -/***************************************** -** STATIC LOCAL FUNCTIONS FORWARD DECLS ** -******************************************/ - - - -/***************************************** -** PUBLIC FUNCTIONS ** -******************************************/ - - -/* -** tuiFirstDataItemDisplayed() -** Answer the index first element displayed. -** If none are displayed, then return (-1). -*/ -int -#ifdef __STDC__ -tuiFirstDataItemDisplayed (void) -#else -tuiFirstDataItemDisplayed () -#endif -{ - int elementNo = (-1); - int i; - - for (i = 0; (i < dataWin->generic.contentSize && elementNo < 0); i++) - { - TuiGenWinInfoPtr dataItemWin; - - dataItemWin = &((TuiWinContent) - dataWin->generic.content)[i]->whichElement.dataWindow; - if (dataItemWin->handle != (WINDOW *) NULL && dataItemWin->isVisible) - elementNo = i; - } - - return elementNo; -} /* tuiFirstDataItemDisplayed */ - - -/* -** tuiFirstDataElementNoInLine() -** Answer the index of the first element in lineNo. If lineNo is -** past the data area (-1) is returned. -*/ -int -#ifdef __STDC__ -tuiFirstDataElementNoInLine ( - int lineNo) -#else -tuiFirstDataElementNoInLine (lineNo) - int lineNo; -#endif -{ - int firstElementNo = (-1); - - /* - ** First see if there is a register on lineNo, and if so, set the - ** first element number - */ - if ((firstElementNo = tuiFirstRegElementNoInLine (lineNo)) == -1) - { /* - ** Looking at the general data, the 1st element on lineNo - */ - } - - return firstElementNo; -} /* tuiFirstDataElementNoInLine */ - - -/* -** tuiDeleteDataContentWindows() -** Function to delete all the item windows in the data window. -** This is usually done when the data window is scrolled. -*/ -void -#ifdef __STDC__ -tuiDeleteDataContentWindows (void) -#else -tuiDeleteDataContentWindows () -#endif -{ - int i; - TuiGenWinInfoPtr dataItemWinPtr; - - for (i = 0; (i < dataWin->generic.contentSize); i++) - { - dataItemWinPtr = &((TuiWinContent) - dataWin->generic.content)[i]->whichElement.dataWindow; - tuiDelwin (dataItemWinPtr->handle); - dataItemWinPtr->handle = (WINDOW *) NULL; - dataItemWinPtr->isVisible = FALSE; - } - - return; -} /* tuiDeleteDataContentWindows */ - - -void -#ifdef __STDC__ -tuiEraseDataContent ( - char *prompt) -#else -tuiEraseDataContent (prompt) - char *prompt; -#endif -{ - werase (dataWin->generic.handle); - checkAndDisplayHighlightIfNeeded (dataWin); - if (prompt != (char *) NULL) - { - int halfWidth = (dataWin->generic.width - 2) / 2; - int xPos; - - if (strlen (prompt) >= halfWidth) - xPos = 1; - else - xPos = halfWidth - strlen (prompt); - mvwaddstr (dataWin->generic.handle, - (dataWin->generic.height / 2), - xPos, - prompt); - } - wrefresh (dataWin->generic.handle); - - return; -} /* tuiEraseDataContent */ - - -/* -** tuiDisplayAllData(). -** This function displays the data that is in the data window's -** content. It does not set the content. -*/ -void -#ifdef __STDC__ -tuiDisplayAllData (void) -#else -tuiDisplayAllData () -#endif -{ - if (dataWin->generic.contentSize <= 0) - tuiEraseDataContent (NO_DATA_STRING); - else - { - tuiEraseDataContent ((char *) NULL); - tuiDeleteDataContentWindows (); - checkAndDisplayHighlightIfNeeded (dataWin); - tuiDisplayRegistersFrom (0); - /* - ** Then display the other data - */ - if (dataWin->detail.dataDisplayInfo.dataContent != - (TuiWinContent) NULL && - dataWin->detail.dataDisplayInfo.dataContentCount > 0) - { - } - } - return; -} /* tuiDisplayAllData */ - - -/* -** tuiDisplayDataFromLine() -** Function to display the data starting at line, lineNo, in the -** data window. -*/ -void -#ifdef __STDC__ -tuiDisplayDataFromLine ( - int lineNo) -#else -tuiDisplayDataFromLine (lineNo) - int lineNo; -#endif -{ - int _lineNo = lineNo; - - if (lineNo < 0) - _lineNo = 0; - - checkAndDisplayHighlightIfNeeded (dataWin); - - /* there is no general data, force regs to display (if there are any) */ - if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0) - tuiDisplayRegistersFromLine (_lineNo, TRUE); - else - { - int elementNo, startLineNo; - int regsLastLine = tuiLastRegsLineNo (); - - - /* display regs if we can */ - if (tuiDisplayRegistersFromLine (_lineNo, FALSE) < 0) - { /* - ** _lineNo is past the regs display, so calc where the - ** start data element is - */ - if (regsLastLine < _lineNo) - { /* figure out how many lines each element is to obtain - the start elementNo */ - } - } - else - { /* - ** calculate the starting element of the data display, given - ** regsLastLine and how many lines each element is, up to - ** _lineNo - */ - } - /* Now display the data , starting at elementNo */ - } - - return; -} /* tuiDisplayDataFromLine */ - - -/* -** tuiDisplayDataFrom() -** Display data starting at element elementNo -*/ -void -#ifdef __STDC__ -tuiDisplayDataFrom ( - int elementNo, - int reuseWindows) -#else -tuiDisplayDataFrom (elementNo, reuseWindows) - int elementNo; - int reuseWindows; -#endif -{ - int firstLine = (-1); - - if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) - firstLine = tuiLineFromRegElementNo (elementNo); - else - { /* calculate the firstLine from the element number */ - } - - if (firstLine >= 0) - { - tuiEraseDataContent ((char *) NULL); - if (!reuseWindows) - tuiDeleteDataContentWindows (); - tuiDisplayDataFromLine (firstLine); - } - - return; -} /* tuiDisplayDataFrom */ - - -/* -** tuiRefreshDataWin() -** Function to redisplay the contents of the data window. -*/ -void -#ifdef __STDC__ -tuiRefreshDataWin (void) -#else -tuiRefreshDataWin () -#endif -{ - tuiEraseDataContent ((char *) NULL); - if (dataWin->generic.contentSize > 0) - { - int firstElement = tuiFirstDataItemDisplayed (); - - if (firstElement >= 0) /* re-use existing windows */ - tuiDisplayDataFrom (firstElement, TRUE); - } - - return; -} /* tuiRefreshDataWin */ - - -/* -** tuiCheckDataValues(). -** Function to check the data values and hilite any that have changed -*/ -void -#ifdef __STDC__ -tuiCheckDataValues ( - struct frame_info *frame) -#else -tuiCheckDataValues (frame) - struct frame_info *frame; -#endif -{ - tuiCheckRegisterValues (frame); - - /* Now check any other data values that there are */ - if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) - { - int i; - - for (i = 0; dataWin->detail.dataDisplayInfo.dataContentCount; i++) - { -#ifdef LATER - TuiDataElementPtr dataElementPtr; - TuiGenWinInfoPtr dataItemWinPtr; - Opaque newValue; - - dataItemPtr = &dataWin->detail.dataDisplayInfo. - dataContent[i]->whichElement.dataWindow; - dataElementPtr = &((TuiWinContent) - dataItemWinPtr->content)[0]->whichElement.data; - if value - has changed (dataElementPtr, frame, &newValue) - { - dataElementPtr->value = newValue; - update the display with the new value, hiliting it. - } -#endif - } - } -} /* tuiCheckDataValues */ - - -/* -** tui_vCheckDataValues(). -** Function to check the data values and hilite any that have -** changed with args in a va_list -*/ -void -#ifdef __STDC__ -tui_vCheckDataValues ( - va_list args) -#else -tui_vCheckDataValues (args) - va_list args; -#endif -{ - struct frame_info *frame = va_arg (args, struct frame_info *); - - tuiCheckDataValues (frame); - - return; -} /* tui_vCheckDataValues */ - - -/* -** tuiVerticalDataScroll() -** Scroll the data window vertically forward or backward. -*/ -void -#ifdef __STDC__ -tuiVerticalDataScroll ( - TuiScrollDirection scrollDirection, - int numToScroll) -#else -tuiVerticalDataScroll (scrollDirection, numToScroll) - TuiScrollDirection scrollDirection; - int numToScroll; -#endif -{ - int firstElementNo; - int firstLine = (-1); - - firstElementNo = tuiFirstDataItemDisplayed (); - if (firstElementNo < dataWin->detail.dataDisplayInfo.regsContentCount) - firstLine = tuiLineFromRegElementNo (firstElementNo); - else - { /* calculate the first line from the element number which is in - ** the general data content - */ - } - - if (firstLine >= 0) - { - int lastElementNo, lastLine; - - if (scrollDirection == FORWARD_SCROLL) - firstLine += numToScroll; - else - firstLine -= numToScroll; - tuiEraseDataContent ((char *) NULL); - tuiDeleteDataContentWindows (); - tuiDisplayDataFromLine (firstLine); - } - - return; -} /* tuiVerticalDataScroll */ - - -/***************************************** -** STATIC LOCAL FUNCTIONS ** -******************************************/ diff --git a/contrib/gdb/gdb/tui/tuiDataWin.h b/contrib/gdb/gdb/tui/tuiDataWin.h deleted file mode 100644 index 8f9e46d80e7..00000000000 --- a/contrib/gdb/gdb/tui/tuiDataWin.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _TUI_DATAWIN_H -#define _TUI_DATAWIN_H -/* -** This header file supports the display of registers/data in the data window. -*/ - - -/***************************************** -** TYPE DEFINITIONS ** -******************************************/ - - - -/***************************************** -** PUBLIC FUNCTION EXTERNAL DECLS ** -******************************************/ -extern void tuiEraseDataContent PARAMS ((char *)); -extern void tuiDisplayAllData PARAMS ((void)); -extern void tuiCheckDataValues PARAMS ((struct frame_info *)); -extern void tui_vCheckDataValues PARAMS ((va_list)); -extern void tuiDisplayDataFromLine PARAMS ((int)); -extern int tuiFirstDataItemDisplayed PARAMS ((void)); -extern int tuiFirstDataElementNoInLine PARAMS ((int)); -extern void tuiDeleteDataContentWindows PARAMS ((void)); -extern void tuiRefreshDataWin PARAMS ((void)); -extern void tuiDisplayDataFrom PARAMS ((int, int)); -extern void tuiVerticalDataScroll PARAMS ((TuiScrollDirection, int)); - -#endif /*_TUI_DATAWIN_H*/ diff --git a/contrib/gdb/gdb/tui/tuiDisassem.c b/contrib/gdb/gdb/tui/tuiDisassem.c deleted file mode 100644 index ad0b70f655d..00000000000 --- a/contrib/gdb/gdb/tui/tuiDisassem.c +++ /dev/null @@ -1,343 +0,0 @@ -/* -** tuiDisassem.c -** This module contains functions for handling disassembly display. -*/ - - -#include "defs.h" -#include "symtab.h" -#include "breakpoint.h" -#include "frame.h" - -#include "tui.h" -#include "tuiData.h" -#include "tuiLayout.h" -#include "tuiSourceWin.h" -#include "tuiStack.h" - - -/***************************************** -** STATIC LOCAL FUNCTIONS FORWARD DECLS ** -******************************************/ - -static struct breakpoint *_hasBreak PARAMS ((CORE_ADDR)); - - -/***************************************** -** PUBLIC FUNCTIONS ** -******************************************/ - -/* -** tuiSetDisassemContent(). -** Function to set the disassembly window's content. -*/ -TuiStatus -#ifdef __STDC__ -tuiSetDisassemContent ( - struct symtab *s, - Opaque startAddr) -#else - tuiSetDisassemContent (s, startAddr) - struct symtab *s; - Opaque startAddr; -#endif -{ - TuiStatus ret = TUI_FAILURE; - GDB_FILE *gdb_dis_out; - - if (startAddr != (Opaque) NULL) - { - register int i, desc; - - if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS) - { - register int offset = disassemWin->detail.sourceInfo.horizontalOffset; - register int threshold, curLine = 0, lineWidth, maxLines; - CORE_ADDR newpc, pc; - disassemble_info asmInfo; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - extern void strcat_address PARAMS ((CORE_ADDR, char *, int)); - extern void strcat_address_numeric PARAMS ((CORE_ADDR, int, char *, int)); - int curLen = 0; - int tab_len = tuiDefaultTabLen (); - - maxLines = disassemWin->generic.height - 2; /* account for hilite */ - lineWidth = disassemWin->generic.width - 1; - threshold = (lineWidth - 1) + offset; - - /* now init the gdb_file structure */ - gdb_dis_out = gdb_file_init_astring (threshold); - - INIT_DISASSEMBLE_INFO_NO_ARCH (asmInfo, gdb_dis_out, (fprintf_ftype) fprintf_filtered); - asmInfo.read_memory_func = dis_asm_read_memory; - asmInfo.memory_error_func = dis_asm_memory_error; - - disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr; - - /* Now construct each line */ - for (curLine = 0, pc = (CORE_ADDR) startAddr; (curLine < maxLines);) - { - TuiWinElementPtr element = (TuiWinElementPtr)disassemWin->generic.content[curLine]; - struct breakpoint *bp; - - print_address (pc, gdb_dis_out); - - curLen = strlen (gdb_file_get_strbuf (gdb_dis_out)); - i = curLen - ((curLen / tab_len) * tab_len); - - /* adjust buffer length if necessary */ - gdb_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i ) : 0, gdb_dis_out); - - /* Add spaces to make the instructions start onthe same column */ - while (i < tab_len) - { - gdb_file_get_strbuf (gdb_dis_out)[curLen] = ' '; - i++; - curLen++; - } - gdb_file_get_strbuf (gdb_dis_out)[curLen] = '\0'; - - newpc = pc + ((*tm_print_insn) (pc, &asmInfo)); - - /* Now copy the line taking the offset into account */ - if (strlen (gdb_file_get_strbuf (gdb_dis_out)) > offset) - strcpy (element->whichElement.source.line, - &(gdb_file_get_strbuf (gdb_dis_out)[offset])); - else - element->whichElement.source.line[0] = '\0'; - element->whichElement.source.lineOrAddr.addr = (Opaque) pc; - element->whichElement.source.isExecPoint = - (pc == (CORE_ADDR) ((TuiWinElementPtr)locator->content[0])->whichElement.locator.addr); - bp = _hasBreak (pc); - element->whichElement.source.hasBreak = - (bp != (struct breakpoint *) NULL && - (!element->whichElement.source.isExecPoint || - (bp->disposition != del || bp->hit_count <= 0))); - curLine++; - pc = newpc; - /* reset the buffer to empty */ - gdb_file_get_strbuf (gdb_dis_out)[0] = '\0'; - } - gdb_file_deallocate (&gdb_dis_out); - disassemWin->generic.contentSize = curLine; - ret = TUI_SUCCESS; - } - } - - return ret; -} /* tuiSetDisassemContent */ - - -/* -** tuiShowDisassem(). -** Function to display the disassembly window with disassembled code. -*/ -void -#ifdef __STDC__ -tuiShowDisassem ( - Opaque startAddr) -#else -tuiShowDisassem (startAddr) - Opaque startAddr; -#endif -{ - struct symtab *s = find_pc_symtab ((CORE_ADDR) startAddr); - TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); - - tuiAddWinToLayout (DISASSEM_WIN); - tuiUpdateSourceWindow (disassemWin, s, startAddr, FALSE); - /* - ** if the focus was in the src win, put it in the asm win, if the - ** source view isn't split - */ - if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin) - tuiSetWinFocusTo (disassemWin); - - return; -} /* tuiShowDisassem */ - - -/* -** tuiShowDisassemAndUpdateSource(). -** Function to display the disassembly window. -*/ -void -#ifdef __STDC__ -tuiShowDisassemAndUpdateSource ( - Opaque startAddr) -#else -tuiShowDisassemAndUpdateSource (startAddr) - Opaque startAddr; -#endif -{ - struct symtab_and_line sal; - - tuiShowDisassem (startAddr); - if (currentLayout () == SRC_DISASSEM_COMMAND) - { - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - /* - ** Update what is in the source window if it is displayed too, - ** note that it follows what is in the disassembly window and visa-versa - */ - sal = find_pc_line ((CORE_ADDR) startAddr, 0); - current_source_symtab = sal.symtab; - tuiUpdateSourceWindow (srcWin, sal.symtab, (Opaque) sal.line, TRUE); - tuiUpdateLocatorFilename (sal.symtab->filename); - } - - return; -} /* tuiShowDisassemAndUpdateSource */ - - -/* -** tuiShowDisassemAsIs(). -** Function to display the disassembly window. This function shows -** the disassembly as specified by the horizontal offset. -*/ -void -#ifdef __STDC__ -tuiShowDisassemAsIs ( - Opaque addr) -#else -tuiShowDisassemAsIs (addr) - Opaque addr; -#endif -{ - tuiAddWinToLayout (DISASSEM_WIN); - tuiUpdateSourceWindowAsIs (disassemWin, (struct symtab *) NULL, addr, FALSE); - /* - ** Update what is in the source window if it is displayed too, not that it - ** follows what is in the disassembly window and visa-versa - */ - if (currentLayout () == SRC_DISASSEM_COMMAND) - tuiShowSourceContent (srcWin); /*???? Need to do more? */ - - return; -} /* tuiShowDisassem */ - - -/* -** tuiGetBeginAsmAddress(). -*/ -Opaque -#ifdef __STDC__ -tuiGetBeginAsmAddress (void) -#else -tuiGetBeginAsmAddress () -#endif -{ - TuiGenWinInfoPtr locator; - TuiLocatorElementPtr element; - Opaque addr; - - locator = locatorWinInfoPtr (); - element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator; - - if (element->addr == (Opaque) 0) - { - /*the target is not executing, because the pc is 0*/ - - addr = (Opaque) parse_and_eval_address ("main"); - - if (addr == (Opaque) 0) - addr = (Opaque) parse_and_eval_address ("MAIN"); - - } - else /* the target is executing */ - addr = element->addr; - - return addr; -} /* tuiGetBeginAsmAddress */ - - -/* -** tuiVerticalDisassemScroll(). -** Scroll the disassembly forward or backward vertically -*/ -void -#ifdef __STDC__ -tuiVerticalDisassemScroll ( - TuiScrollDirection scrollDirection, - int numToScroll) -#else -tuiVerticalDisassemScroll (scrollDirection, numToScroll) - TuiScrollDirection scrollDirection; - int numToScroll; -#endif -{ - if (disassemWin->generic.content != (OpaquePtr) NULL) - { - Opaque pc, lowAddr; - TuiWinContent content; - struct symtab *s; - - content = (TuiWinContent) disassemWin->generic.content; - if (current_source_symtab == (struct symtab *) NULL) - s = find_pc_symtab (selected_frame->pc); - else - s = current_source_symtab; - - pc = content[0]->whichElement.source.lineOrAddr.addr; - if (find_pc_partial_function ((CORE_ADDR) pc, - (char **) NULL, - (CORE_ADDR *) & lowAddr, - (CORE_ADDR) NULL) == 0) - error ("No function contains prgram counter for selected frame.\n"); - else - { - register int line = 0; - register Opaque newLow; - bfd_byte buffer[4]; - - newLow = pc; - if (scrollDirection == FORWARD_SCROLL) - { - for (; line < numToScroll; line++) - newLow += sizeof (bfd_getb32 (buffer)); - } - else - { - for (; newLow >= (Opaque) 0 && line < numToScroll; line++) - newLow -= sizeof (bfd_getb32 (buffer)); - } - tuiUpdateSourceWindowAsIs (disassemWin, s, newLow, FALSE); - } - } - - return; -} /* tuiVerticalDisassemScroll */ - - - -/***************************************** -** STATIC LOCAL FUNCTIONS ** -******************************************/ -/* -** _hasBreak(). -** Answer whether there is a break point at the input line in the -** source file indicated -*/ -static struct breakpoint * -#ifdef __STDC__ -_hasBreak ( - CORE_ADDR addr) -#else -_hasBreak (addr) - CORE_ADDR addr; -#endif -{ - struct breakpoint *bpWithBreak = (struct breakpoint *) NULL; - struct breakpoint *bp; - extern struct breakpoint *breakpoint_chain; - - - for (bp = breakpoint_chain; - (bp != (struct breakpoint *) NULL && - bpWithBreak == (struct breakpoint *) NULL); - bp = bp->next) - if (addr == bp->address) - bpWithBreak = bp; - - return bpWithBreak; -} /* _hasBreak */ diff --git a/contrib/gdb/gdb/tui/tuiDisassem.h b/contrib/gdb/gdb/tui/tuiDisassem.h deleted file mode 100644 index 711ac48587d..00000000000 --- a/contrib/gdb/gdb/tui/tuiDisassem.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _TUI_DISASSEM_H -#define _TUI_DISASSEM_H -/* -** This header file supports -*/ - -/***************************************** -** TYPE DEFINITIONS ** -******************************************/ - - - -/***************************************** -** PUBLIC FUNCTION EXTERNAL DECLS ** -******************************************/ -extern TuiStatus tuiSetDisassemContent PARAMS ((struct symtab *, Opaque)); -extern void tuiShowDisassem PARAMS ((Opaque)); -extern void tuiShowDisassemAndUpdateSource PARAMS ((Opaque)); -extern void tuiVerticalDisassemScroll PARAMS ((TuiScrollDirection, int)); -extern Opaque tuiGetBeginAsmAddress PARAMS ((void)); - -#endif /*_TUI_DISASSEM_H*/ diff --git a/contrib/gdb/gdb/tui/tuiGeneralWin.c b/contrib/gdb/gdb/tui/tuiGeneralWin.c deleted file mode 100644 index 5af0cd7a92e..00000000000 --- a/contrib/gdb/gdb/tui/tuiGeneralWin.c +++ /dev/null @@ -1,469 +0,0 @@ -/* -** TuiGeneralWin.c -** This module supports general window behavior -*/ - -#include -#include "defs.h" -#include "tui.h" -#include "tuiData.h" -#include "tuiGeneralWin.h" - - -/* -** local support functions -*/ -static void _winResize PARAMS ((void)); - - -/*********************** -** PUBLIC FUNCTIONS -***********************/ -/* -** tuiRefreshWin() -** Refresh the window -*/ -void -#ifdef __STDC__ -tuiRefreshWin ( - TuiGenWinInfoPtr winInfo) -#else -tuiRefreshWin (winInfo) - TuiGenWinInfoPtr winInfo; -#endif -{ - if (winInfo->type == DATA_WIN && winInfo->contentSize > 0) - { - int i; - - for (i = 0; (i < winInfo->contentSize); i++) - { - TuiGenWinInfoPtr dataItemWinPtr; - - dataItemWinPtr = &((TuiWinContent) - winInfo->content)[i]->whichElement.dataWindow; - if (m_genWinPtrNotNull (dataItemWinPtr) && - dataItemWinPtr->handle != (WINDOW *) NULL) - wrefresh (dataItemWinPtr->handle); - } - } - else if (winInfo->type == CMD_WIN) - { - /* Do nothing */ - } - else - { - if (winInfo->handle != (WINDOW *) NULL) - wrefresh (winInfo->handle); - } - - return; -} /* tuiRefreshWin */ - - -/* -** tuiDelwin() -** Function to delete the curses window, checking for null -*/ -void -#ifdef __STDC__ -tuiDelwin ( - WINDOW * window) -#else -tuiDelwin (window) - WINDOW *window; -#endif -{ - if (window != (WINDOW *) NULL) - delwin (window); - - return; -} /* tuiDelwin */ - - -/* -** boxWin(). -*/ -void -#ifdef __STDC__ -boxWin ( - TuiGenWinInfoPtr winInfo, - int highlightFlag) -#else -boxWin (winInfo, highlightFlag) - TuiGenWinInfoPtr winInfo; - int highlightFlag; -#endif -{ - if (m_genWinPtrNotNull (winInfo) && winInfo->handle != (WINDOW *) NULL) - { - if (highlightFlag == HILITE) - box (winInfo->handle, '|', '-'); - else - { -/* wattron(winInfo->handle, A_DIM);*/ - box (winInfo->handle, ':', '.'); -/* wattroff(winInfo->handle, A_DIM);*/ - } - } - - return; -} /* boxWin */ - - -/* -** unhighlightWin(). -*/ -void -#ifdef __STDC__ -unhighlightWin ( - TuiWinInfoPtr winInfo) -#else -unhighlightWin (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - if (m_winPtrNotNull (winInfo) && winInfo->generic.handle != (WINDOW *) NULL) - { - boxWin ((TuiGenWinInfoPtr) winInfo, NO_HILITE); - wrefresh (winInfo->generic.handle); - m_setWinHighlightOff (winInfo); - } -} /* unhighlightWin */ - - -/* -** highlightWin(). -*/ -void -#ifdef __STDC__ -highlightWin ( - TuiWinInfoPtr winInfo) -#else -highlightWin (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - if (m_winPtrNotNull (winInfo) && - winInfo->canHighlight && winInfo->generic.handle != (WINDOW *) NULL) - { - boxWin ((TuiGenWinInfoPtr) winInfo, HILITE); - wrefresh (winInfo->generic.handle); - m_setWinHighlightOn (winInfo); - } -} /* highlightWin */ - - -/* -** checkAndDisplayHighlightIfNecessay -*/ -void -#ifdef __STDC__ -checkAndDisplayHighlightIfNeeded ( - TuiWinInfoPtr winInfo) -#else -checkAndDisplayHighlightIfNeeded (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - if (m_winPtrNotNull (winInfo) && winInfo->generic.type != CMD_WIN) - { - if (winInfo->isHighlighted) - highlightWin (winInfo); - else - unhighlightWin (winInfo); - - } - return; -} /* checkAndDisplayHighlightIfNeeded */ - - -/* -** makeWindow(). -*/ -void -#ifdef __STDC__ -makeWindow ( - TuiGenWinInfoPtr winInfo, - int boxIt) -#else -makeWindow (winInfo, boxIt) - TuiGenWinInfoPtr winInfo; - int boxIt; -#endif -{ - WINDOW *handle; - - handle = newwin (winInfo->height, - winInfo->width, - winInfo->origin.y, - winInfo->origin.x); - winInfo->handle = handle; - if (handle != (WINDOW *) NULL) - { - if (boxIt == BOX_WINDOW) - boxWin (winInfo, NO_HILITE); - winInfo->isVisible = TRUE; - scrollok (handle, TRUE); - tuiRefreshWin (winInfo); - -#ifndef FOR_TEST - if ( /*!m_WinIsAuxillary(winInfo->type) && */ - (winInfo->type != CMD_WIN) && - (winInfo->content == (OpaquePtr) NULL)) - { - mvwaddstr (handle, 1, 1, winName (winInfo)); - tuiRefreshWin (winInfo); - } -#endif /*FOR_TEST*/ - } - - return; -} /* makeWindow */ - - -/* -** tuiClearWin(). -** Clear the window of all contents without calling wclear. -*/ -void -#ifdef __STDC__ -tuiClearWin ( - TuiGenWinInfoPtr winInfo) -#else -tuiClearWin (winInfo) - TuiGenWinInfoPtr winInfo; -#endif -{ - if (m_genWinPtrNotNull (winInfo) && winInfo->handle != (WINDOW *) NULL) - { - int curRow, curCol; - - for (curRow = 0; (curRow < winInfo->height); curRow++) - for (curCol = 0; (curCol < winInfo->width); curCol++) - mvwaddch (winInfo->handle, curRow, curCol, ' '); - - tuiRefreshWin (winInfo); - } - - return; -} /* tuiClearWin */ - - -/* -** makeVisible(). -** We can't really make windows visible, or invisible. So we -** have to delete the entire window when making it visible, -** and create it again when making it visible. -*/ -void -#ifdef __STDC__ -makeVisible ( - TuiGenWinInfoPtr winInfo, - int visible) -#else -makeVisible (winInfo, visible) - TuiGenWinInfoPtr winInfo; - int visible; -#endif -{ - /* Don't tear down/recreate command window */ - if (winInfo->type == CMD_WIN) - return; - - if (visible) - { - if (!winInfo->isVisible) - { - makeWindow ( - winInfo, - (winInfo->type != CMD_WIN && !m_winIsAuxillary (winInfo->type))); - winInfo->isVisible = TRUE; - } - tuiRefreshWin (winInfo); - } - else if (!visible && - winInfo->isVisible && winInfo->handle != (WINDOW *) NULL) - { - winInfo->isVisible = FALSE; - tuiClearWin (winInfo); - tuiDelwin (winInfo->handle); - winInfo->handle = (WINDOW *) NULL; - } - - return; -} /* makeVisible */ - - -/* -** makeAllVisible(). -** Makes all windows invisible (except the command and locator windows) -*/ -void -#ifdef __STDC__ -makeAllVisible ( - int visible) -#else -makeAllVisible (visible) - int visible; -#endif -{ - int i; - - for (i = 0; i < MAX_MAJOR_WINDOWS; i++) - { - if (m_winPtrNotNull (winList[i]) && - ((winList[i])->generic.type) != CMD_WIN) - { - if (m_winIsSourceType ((winList[i])->generic.type)) - makeVisible ((winList[i])->detail.sourceInfo.executionInfo, - visible); - makeVisible ((TuiGenWinInfoPtr) winList[i], visible); - } - } - - return; -} /* makeAllVisible */ - - -/* -** scrollWinForward -*/ -void -#ifdef __STDC__ -scrollWinForward ( - TuiGenWinInfoPtr winInfo, - int numLines) -#else -scrollWinForward (winInfo, numLines) - TuiGenWinInfoPtr winInfo; - int numLines; -#endif -{ - if (winInfo->content != (OpaquePtr) NULL && - winInfo->lastVisibleLine < winInfo->contentSize - 1) - { - int i, firstLine, newLastLine; - - firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1; - if (winInfo->lastVisibleLine + numLines > winInfo->contentSize) - newLastLine = winInfo->contentSize - 1; - else - newLastLine = winInfo->lastVisibleLine + numLines - 1; - - for (i = (newLastLine - winInfo->viewportHeight); - (i <= newLastLine); i++) - { - TuiWinElementPtr line; - int lineHeight; - - line = (TuiWinElementPtr) winInfo->content[i]; - if (line->highlight) - wstandout (winInfo->handle); - mvwaddstr (winInfo->handle, - i - (newLastLine - winInfo->viewportHeight), - 1, - displayableWinContentOf (winInfo, line)); - if (line->highlight) - wstandend (winInfo->handle); - lineHeight = winElementHeight (winInfo, line); - newLastLine += (lineHeight - 1); - } - winInfo->lastVisibleLine = newLastLine; - } - - return; -} /* scrollWinForward */ - - -/* -** scrollWinBackward -*/ -void -#ifdef __STDC__ -scrollWinBackward ( - TuiGenWinInfoPtr winInfo, - int numLines) -#else -scrollWinBackward (winInfo, numLines) - TuiGenWinInfoPtr winInfo; - int numLines; -#endif -{ - if (winInfo->content != (OpaquePtr) NULL && - (winInfo->lastVisibleLine - winInfo->viewportHeight) > 0) - { - int i, newLastLine, firstLine; - - firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1; - if ((firstLine - numLines) < 0) - newLastLine = winInfo->viewportHeight - 1; - else - newLastLine = winInfo->lastVisibleLine - numLines + 1; - - for (i = newLastLine - winInfo->viewportHeight; (i <= newLastLine); i++) - { - TuiWinElementPtr line; - int lineHeight; - - line = (TuiWinElementPtr) winInfo->content[i]; - if (line->highlight) - wstandout (winInfo->handle); - mvwaddstr (winInfo->handle, - i - (newLastLine - winInfo->viewportHeight), - 1, - displayableWinContentOf (winInfo, line)); - if (line->highlight) - wstandend (winInfo->handle); - lineHeight = winElementHeight (winInfo, line); - newLastLine += (lineHeight - 1); - } - winInfo->lastVisibleLine = newLastLine; - } - - return; -} /* scrollWinBackward */ - - -/* -** refreshAll(). -** Function to refresh all the windows currently displayed -*/ -void -#ifdef __STDC__ -refreshAll ( - TuiWinInfoPtr * list) -#else -refreshAll (list) - TuiWinInfoPtr *list; -#endif -{ - TuiWinType type; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) - { - if (list[type]->generic.isVisible) - { - if (type == SRC_WIN || type == DISASSEM_WIN) - { - touchwin (list[type]->detail.sourceInfo.executionInfo->handle); - tuiRefreshWin (list[type]->detail.sourceInfo.executionInfo); - } - touchwin (list[type]->generic.handle); - tuiRefreshWin (&list[type]->generic); - } - } - if (locator->isVisible) - { - touchwin (locator->handle); - tuiRefreshWin (locator); - } - - return; -} /* refreshAll */ - - -/********************************* -** Local Static Functions -*********************************/ diff --git a/contrib/gdb/gdb/tui/tuiGeneralWin.h b/contrib/gdb/gdb/tui/tuiGeneralWin.h deleted file mode 100644 index 559f8ab3339..00000000000 --- a/contrib/gdb/gdb/tui/tuiGeneralWin.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TUI_GENERAL_WIN_H -#define TUI_GENERAL_WIN_H - -/* -** Functions -*/ -extern void tuiClearWin PARAMS ((TuiGenWinInfoPtr)); -extern void unhighlightWin PARAMS ((TuiWinInfoPtr)); -extern void makeVisible PARAMS ((TuiGenWinInfoPtr, int)); -extern void makeAllVisible PARAMS ((int)); -extern void scrollWinForward PARAMS ((TuiGenWinInfoPtr, int)); -extern void scrollWinBackward PARAMS ((TuiGenWinInfoPtr, int)); -extern void makeWindow PARAMS ((TuiGenWinInfoPtr, int)); -extern TuiWinInfoPtr copyWin PARAMS ((TuiWinInfoPtr)); -extern void boxWin PARAMS ((TuiGenWinInfoPtr, int)); -extern void highlightWin PARAMS ((TuiWinInfoPtr)); -extern void checkAndDisplayHighlightIfNeeded PARAMS ((TuiWinInfoPtr)); -extern void refreshAll PARAMS ((TuiWinInfoPtr *)); -extern void tuiDelwin PARAMS ((WINDOW *window)); -extern void tuiRefreshWin PARAMS ((TuiGenWinInfoPtr)); - -/* -** Macros -*/ -#define m_beVisible(winInfo) makeVisible((TuiGenWinInfoPtr)(winInfo), TRUE) -#define m_beInvisible(winInfo) \ - makeVisible((TuiGenWinInfoPtr)(winInfo), FALSE) -#define m_allBeVisible() makeAllVisible(TRUE) -#define m_allBeInvisible() makeAllVisible(FALSE) - -#endif /*TUI_GENERAL_WIN_H*/ diff --git a/contrib/gdb/gdb/tui/tuiIO.c b/contrib/gdb/gdb/tui/tuiIO.c deleted file mode 100644 index 29a3613f968..00000000000 --- a/contrib/gdb/gdb/tui/tuiIO.c +++ /dev/null @@ -1,734 +0,0 @@ - -/* -** This module contains functions to support i/o in the TUI -*/ - - -#include -#include "defs.h" -#include "terminal.h" -#include "tui.h" -#include "tuiData.h" -#include "tuiIO.h" -#include "tuiCommand.h" -#include "tuiWin.h" - -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - -/* The Solaris header files seem to provide no declaration for this at - all when __STDC__ is defined. This shouldn't conflict with - anything. */ -extern char *tgoto (); - -int insert_mode = 0; - -/******************************************** -** LOCAL STATIC FORWARD DECLS ** -********************************************/ -static void _updateCommandInfo PARAMS ((int)); -static unsigned int _tuiHandleResizeDuringIO PARAMS ((unsigned int)); - - -/********************************************************************************* -** PUBLIC FUNCTIONS ** -*********************************************************************************/ - -/* -** tuiPuts_unfiltered(). -** Function to put a string to the command window -** When running in TUI mode, this is the "hook" -** for fputs_unfiltered(). That is, all debugger -** output eventually makes it's way to the bottom-level -** routine fputs_unfiltered (main.c), which (in TUI -** mode), calls tuiPuts_unfiltered(). -*/ -void -#ifdef __STDC__ -tuiPuts_unfiltered ( - const char *string, - GDB_FILE * stream) -#else -tuiPuts_unfiltered (string, stream) - char *string; - GDB_FILE *stream; -#endif -{ - int len = strlen (string); - int i, linech; - - for (i = 0; i < len; i++) - { - if (string[i] == '\n' || string[i] == '\r') - m_tuiStartNewLine; - else - { - if ((cmdWin->detail.commandInfo.curch + 1) > cmdWin->generic.width) - m_tuiStartNewLine; - - if (insert_mode) - { - mvwinsch (cmdWin->generic.handle, - cmdWin->detail.commandInfo.curLine, - cmdWin->detail.commandInfo.curch++, - string[i]); - wmove (cmdWin->generic.handle, - cmdWin->detail.commandInfo.curLine, - cmdWin->detail.commandInfo.curch); - } - else - mvwaddch (cmdWin->generic.handle, - cmdWin->detail.commandInfo.curLine, - cmdWin->detail.commandInfo.curch++, - string[i]); - } - } - tuiRefreshWin (&cmdWin->generic); - - return; -} /* tuiPuts_unfiltered */ - -/* A cover routine for tputs(). - * tputs() is called from the readline package to put - * out strings representing cursor positioning. - * In TUI mode (non-XDB-style), tui_tputs() is called instead. - * - * The reason we need to hook tputs() is: - * Since the output is going to curses and not to - * a raw terminal, we need to intercept these special - * sequences, and handle them them here. - * - * This function seems to be correctly handling all sequences - * aimed at hpterm's, but there is additional work to do - * for xterm's and dtterm's. I abandoned further work on this - * in favor of "XDB style". In "XDB style", the command region - * looks like terminal, not a curses window, and this routine - * is not called. - RT - */ -void -tui_tputs (str, affcnt, putfunc) - char *str; - int affcnt; - int (*putfunc) PARAMS ((int)); -{ - extern char *rl_prompt; /* the prompt string */ - - /* This set of globals are defined and initialized - * by the readline package. - * - * Note we're assuming tui_tputs() is being called - * by the readline package. That's because we're recognizing - * that a given string is being passed by - * matching the string address against readline's - * term_ global. To make this more general, - * we'd have to actually recognize the termcap sequence - * inside the string (more work than I want to do). - RT - * - * We don't see or need to handle every one of these here; - * this is just the full list defined in readline/readline.c - */ - extern char *term_backspace; - extern char *term_clreol; - extern char *term_clrpag; - extern char *term_cr; - extern char *term_dc; - extern char *term_ei; - extern char *term_goto; - extern char *term_ic; - extern char *term_im; - extern char *term_mm; - extern char *term_mo; - extern char *term_up; - extern char *term_scroll_region; - extern char *term_memory_lock; - extern char *term_memory_unlock; - extern char *term_cursor_move; - extern char *visible_bell; - - /* Sanity check - if not TUI, just call tputs() */ - if (!tui_version) - tputs (str, affcnt, putfunc); - - /* The strings we special-case are handled first */ - - if (str == term_backspace) - { - /* Backspace. */ - - /* We see this on an emacs control-B. - * I.e., it's like the left-arrow key (not like the backspace key). - * The effect that readline wants when it transmits this - * character to us is simply to back up one character - * (but not to write a space over the old character). - */ - - _updateCommandInfo (-1); - wmove (cmdWin->generic.handle, - cmdWin->detail.commandInfo.curLine, - cmdWin->detail.commandInfo.curch); - wrefresh (cmdWin->generic.handle); - - } - else if (str == term_clreol) - { - - /* Clear to end of line. */ - wclrtoeol (cmdWin->generic.handle); - wrefresh (cmdWin->generic.handle); - - } - else if (str == term_cr) - { - - /* Carriage return */ - _updateCommandInfo (-cmdWin->detail.commandInfo.curch); - wmove (cmdWin->generic.handle, - cmdWin->detail.commandInfo.curLine, - 0 /* readline will rewrite the prompt from 0 */ ); - wrefresh (cmdWin->generic.handle); - - } - else if (str == term_goto) - { - - /* This is actually a tgoto() specifying a character position, - * followed by either a term_IC/term_DC which [I think] means - * insert/delete one character at that position. - * There are complications with this one - need to either - * extract the position from the string, or have a backdoor - * means of communicating it from ../readline/display.c. - * So this one is not yet implemented. - * Not doing it seems to have no ill effects on command-line-editing - * that I've noticed so far. - RT - */ - - } - else if (str == term_dc) - { - - /* Delete character at current cursor position */ - wdelch (cmdWin->generic.handle); - wrefresh (cmdWin->generic.handle); - - } - else if (str == term_im) - { - - /* Turn on insert mode. */ - insert_mode = 1; - - } - else if (str == term_ei) - { - - /* Turn off insert mode. */ - insert_mode = 0; - - /* Strings we know about but don't handle - * specially here are just passed along to tputs(). - * - * These are not handled because (as far as I can tell) - * they are not actually emitted by the readline package - * in the course of doing command-line editing. Some of them - * theoretically could be used in the future, in which case we'd - * need to handle them. - */ - } - else if (str == term_ic || /* insert character */ - str == term_cursor_move || /* cursor move */ - str == term_clrpag ||/* clear page */ - str == term_mm || /* turn on meta key */ - str == term_mo || /* turn off meta key */ - str == term_up || /* up one line (not expected) */ - str == term_scroll_region || /* set scroll region */ - str == term_memory_lock || /* lock screen above cursor */ - str == term_memory_unlock || /* unlock screen above cursor */ - str == visible_bell) - { /* flash screen */ - tputs (str, affcnt, putfunc); - } - else - { /* something else */ - tputs (str, affcnt, putfunc); - } -} /* tui_tputs */ - - -/* -** tui_vwgetch() -** Wrapper around wgetch with the window in a va_list -*/ -unsigned int -#ifdef __STDC__ -tui_vwgetch (va_list args) -#else -tui_vwgetch (args) - va_list args; -#endif -{ - unsigned int ch; - WINDOW *window; - - window = va_arg (args, WINDOW *); - - return ((unsigned int) wgetch (window)); -} /* tui_vwgetch */ - - -/* -** tui_vread() -** Wrapper around read() with paramets in a va_list -*/ -unsigned int -#ifdef __STDC__ -tui_vread (va_list args) -#else -tui_vread (args) - va_list args; -#endif -{ - int result = 0; - int filedes = va_arg (args, int); - char *buf = va_arg (args, char *); - int nbytes = va_arg (args, int); - - result = read (filedes, buf, nbytes); - - return result; -} /* tui_vread() */ - -/* -** tuiRead() -** Function to perform a read() catching resize events -*/ -int -#ifdef __STDC__ -tuiRead ( - int filedes, - char *buf, - int nbytes) -#else -tuiRead (filedes, buf, nbytes) - int filedes; - char *buf; - int nbytes; -#endif -{ - int result = 0; - - result = (int) vcatch_errors ((OpaqueFuncPtr) tui_vread, filedes, buf, nbytes); - *buf = _tuiHandleResizeDuringIO (*buf); - - return result; -} /* tuiRead */ - - -/* -** tuiGetc(). -** Get a character from the command window. -** This is called from the readline package, -** that is, we have: -** tuiGetc() [here], called from -** readline code [in ../readline/], called from -** command_line_input() in top.c -*/ -unsigned int -#ifdef __STDC__ -tuiGetc (void) -#else -tuiGetc () -#endif -{ - unsigned int ch; - extern char *rl_prompt; - extern char *rl_line_buffer; - extern int rl_point; - - /* Call the curses routine that reads one character */ -#ifndef COMMENT - ch = (unsigned int) vcatch_errors ((OpaqueFuncPtr) tui_vwgetch, - cmdWin->generic.handle); -#else - ch = wgetch (cmdWin->generic.handle); -#endif - ch = _tuiHandleResizeDuringIO (ch); - - if (m_isCommandChar (ch)) - { /* Handle prev/next/up/down here */ - tuiTermSetup (0); - ch = tuiDispatchCtrlChar (ch); - cmdWin->detail.commandInfo.curch = strlen (rl_prompt) + rl_point; - tuiTermUnsetup (0, cmdWin->detail.commandInfo.curch); - } - if (ch == '\n' || ch == '\r' || ch == '\f') - cmdWin->detail.commandInfo.curch = 0; - else - tuiIncrCommandCharCountBy (1); - - return ch; -} /* tuiGetc */ - - -/* -** tuiBufferGetc(). -*/ -/*elz: this function reads a line of input from the user and -puts it in a static buffer. Subsequent calls to this same function -obtain one char at the time, providing the caller with a behavior -similar to fgetc. When the input is buffered, the backspaces have -the needed effect, i.e. ignore the last char active in the buffer*/ -/* so far this function is called only from the query function in -utils.c*/ - -unsigned int -#ifdef __STDC__ -tuiBufferGetc (void) -#else -tuiBufferGetc () -#endif -{ - unsigned int ch; - static unsigned char _ibuffer[512]; - static int index_read = -1; - static int length_of_answer = -1; - int pos = 0; - - if (length_of_answer == -1) - { - /* this is the first time through, need to read the answer*/ - do - { - /* Call the curses routine that reads one character */ - ch = (unsigned int) wgetch (cmdWin->generic.handle); - if (ch != '\b') - { - _ibuffer[pos] = ch; - pos++; - } - else - pos--; - } - while (ch != '\r' && ch != '\n'); - - length_of_answer = pos; - index_read = 0; - } - - ch = _ibuffer[index_read]; - index_read++; - - if (index_read == length_of_answer) - { - /*this is the last time through, reset for next query*/ - index_read = -1; - length_of_answer = -1; - } - - wrefresh (cmdWin->generic.handle); - - return (ch); -} /* tuiBufferGetc */ - - -/* -** tuiStartNewLines(). -*/ -void -#ifdef __STDC__ -tuiStartNewLines ( - int numLines) -#else -tuiStartNewLines (numLines) - int numLines; -#endif -{ - if (numLines > 0) - { - if (cmdWin->generic.viewportHeight > 1 && - cmdWin->detail.commandInfo.curLine < cmdWin->generic.viewportHeight) - cmdWin->detail.commandInfo.curLine += numLines; - else - scroll (cmdWin->generic.handle); - cmdWin->detail.commandInfo.curch = 0; - wmove (cmdWin->generic.handle, - cmdWin->detail.commandInfo.curLine, - cmdWin->detail.commandInfo.curch); - tuiRefreshWin (&cmdWin->generic); - } - - return; -} /* tuiStartNewLines */ - - -/* -** tui_vStartNewLines(). -** With numLines in a va_list -*/ -void -#ifdef __STDC__ -tui_vStartNewLines ( - va_list args) -#else -tui_vStartNewLines (args) - va_list args; -#endif -{ - int numLines = va_arg (args, int); - - tuiStartNewLines (numLines); - - return; -} /* tui_vStartNewLines */ - - -/**************************************************************************** -** LOCAL STATIC FUNCTIONS ** -*****************************************************************************/ - - -/* -** _tuiHandleResizeDuringIO -** This function manages the cleanup when a resize has occured -** From within a call to getch() or read. Returns the character -** to return from getc or read. -*/ -static unsigned int -#ifdef __STDC__ -_tuiHandleResizeDuringIO ( - unsigned int originalCh) /* the char just read */ -#else -_tuiHandleResizeDuringIO (originalCh) - unsigned int originalCh; -#endif -{ - if (tuiWinResized ()) - { - tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll); - dont_repeat (); - tuiSetWinResizedTo (FALSE); - rl_reset (); - return '\n'; - } - else - return originalCh; -} /* _tuiHandleResizeDuringIO */ - - -/* -** _updateCommandInfo(). -** Function to update the command window information. -*/ -static void -#ifdef __STDC__ -_updateCommandInfo ( - int sizeOfString) -#else -_updateCommandInfo (sizeOfString) - int sizeOfString; -#endif -{ - - if ((sizeOfString + - cmdWin->detail.commandInfo.curch) > cmdWin->generic.width) - { - int newCurch = sizeOfString + cmdWin->detail.commandInfo.curch; - - tuiStartNewLines (1); - cmdWin->detail.commandInfo.curch = newCurch - cmdWin->generic.width; - } - else - cmdWin->detail.commandInfo.curch += sizeOfString; - - return; -} /* _updateCommandInfo */ - - -/* Looked at in main.c, fputs_unfiltered(), to decide - * if it's safe to do standard output to the command window. - */ -int tui_owns_terminal = 0; - -/* Called to set up the terminal for TUI (curses) I/O. - * We do this either on our way "in" to GDB after target - * program execution, or else within tuiDo just before - * going off to TUI routines. - */ - -void -#ifdef __STDC__ -tuiTermSetup ( - int turn_off_echo) -#else -tuiTermSetup (turn_off_echo) - int turn_off_echo; -#endif -{ - char *buffer; - int start; - int end; - int endcol; - extern char *term_scroll_region; - extern char *term_cursor_move; - extern char *term_memory_lock; - extern char *term_memory_unlock; - - /* Turn off echoing, since the TUI does not - * expect echoing. Below I only put in the TERMIOS - * case, since that is what applies on HP-UX. turn_off_echo - * is 1 except for the case where we're being called - * on a "quit", in which case we want to leave echo on. - */ - if (turn_off_echo) - { -#ifdef HAVE_TERMIOS - struct termios tio; - tcgetattr (0, &tio); - tio.c_lflag &= ~(ECHO); - tcsetattr (0, TCSANOW, &tio); -#endif - } - - /* Compute the start and end lines of the command - * region. (Actually we only use end here) - */ - start = winList[CMD_WIN]->generic.origin.y; - end = start + winList[CMD_WIN]->generic.height - 1; - endcol = winList[CMD_WIN]->generic.width - 1; - - if (term_memory_unlock) - { - - /* Un-do the effect of the memory lock in terminal_inferior() */ - tputs (term_memory_unlock, 1, (int (*)PARAMS ((int))) putchar); - fflush (stdout); - - } - else if (term_scroll_region) - { - - /* Un-do the effect of setting scroll region in terminal_inferior() */ - /* I'm actually not sure how to do this (we don't know for - * sure what the scroll region was *before* we changed it), - * but I'll guess that setting it to the whole screen is - * the right thing. So, ... - */ - - /* Set scroll region to be 0..end */ - buffer = (char *) tgoto (term_scroll_region, end, 0); - tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); - - } /* else we're out of luck */ - - /* This is an attempt to keep the logical & physical - * cursor in synch, going into curses. Without this, - * curses seems to be confused by the fact that - * GDB has physically moved the curser on it. One - * visible effect of removing this code is that the - * locator window fails to get updated and the line - * of text that *should* go into the locator window - * often goes to the wrong place. - */ - /* What's done here is to tell curses to write a ' ' - * at the bottom right corner of the screen. - * The idea is to wind up with the cursor in a known - * place. - * Note I'm relying on refresh() - * only writing what changed (the space), - * not the whole screen. - */ - standend (); - move (end, endcol - 1); - addch (' '); - refresh (); - - tui_owns_terminal = 1; -} /* tuiTermSetup */ - - -/* Called to set up the terminal for target program I/O, meaning I/O - * is confined to the command-window area. We also call this on our - * way out of tuiDo, thus setting up the terminal this way for - * debugger command I/O. */ -void -#ifdef __STDC__ -tuiTermUnsetup ( - int turn_on_echo, - int to_column) -#else -tuiTermUnsetup (turn_on_echo, to_column) - int turn_on_echo; - int to_column; -#endif -{ - int start; - int end; - int curline; - char *buffer; - /* The next bunch of things are from readline */ - extern char *term_scroll_region; - extern char *term_cursor_move; - extern char *term_memory_lock; - extern char *term_memory_unlock; - extern char *term_se; - - /* We need to turn on echoing, since the TUI turns it off */ - /* Below I only put in the TERMIOS case, since that - * is what applies on HP-UX. - */ - if (turn_on_echo) - { -#ifdef HAVE_TERMIOS - struct termios tio; - tcgetattr (0, &tio); - tio.c_lflag |= (ECHO); - tcsetattr (0, TCSANOW, &tio); -#endif - } - - /* Compute the start and end lines of the command - * region, as well as the last "real" line of - * the region (normally same as end, except when - * we're first populating the region) - */ - start = winList[CMD_WIN]->generic.origin.y; - end = start + winList[CMD_WIN]->generic.height - 1; - curline = start + winList[CMD_WIN]->detail.commandInfo.curLine; - - /* We want to confine target I/O to the command region. - * In order to do so, we must either have "memory lock" - * (hpterm's) or "scroll regions" (xterm's). - */ - if (term_cursor_move && term_memory_lock) - { - - /* Memory lock means lock region above cursor. - * So first position the cursor, then call memory lock. - */ - buffer = tgoto (term_cursor_move, 0, start); - tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); - tputs (term_memory_lock, 1, (int (*)PARAMS ((int))) putchar); - - } - else if (term_scroll_region) - { - - /* Set the scroll region to the command window */ - buffer = tgoto (term_scroll_region, end, start); - tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); - - } /* else we can't do anything about target I/O */ - - /* Also turn off standout mode, in case it is on */ - if (term_se != NULL) - tputs (term_se, 1, (int (*)PARAMS ((int))) putchar); - - /* Now go to the appropriate spot on the end line */ - buffer = tgoto (term_cursor_move, to_column, end); - tputs (buffer, 1, (int (*)PARAMS ((int))) putchar); - fflush (stdout); - - tui_owns_terminal = 0; -} /* tuiTermUnsetup */ diff --git a/contrib/gdb/gdb/tui/tuiIO.h b/contrib/gdb/gdb/tui/tuiIO.h deleted file mode 100644 index bcbeffe4edc..00000000000 --- a/contrib/gdb/gdb/tui/tuiIO.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _TUI_IO_H -#define _TUI_IO_H -/* -** This header contains defitions to support tuiIO.c -*/ - - -#include - -extern void tuiPuts_unfiltered PARAMS ((const char *, GDB_FILE *)); -extern unsigned int tuiGetc PARAMS ((void)); -extern unsigned int tuiBufferGetc PARAMS ((void)); -extern int tuiRead PARAMS ((int, char *, int)); -extern void tuiStartNewLines PARAMS ((int)); -extern void tui_vStartNewLines PARAMS ((va_list)); -extern unsigned int tui_vwgetch PARAMS ((va_list)); -extern void tuiTermSetup PARAMS ((int)); -extern void tuiTermUnsetup PARAMS ((int, int)); - - - -#define m_tuiStartNewLine tuiStartNewLines(1) -#define m_isStartSequence(ch) (ch == 27) -#define m_isEndSequence(ch) (ch == 126) -#define m_isBackspace(ch) (ch == 8) -#define m_isDeleteChar(ch) (ch == KEY_DC) -#define m_isDeleteLine(ch) (ch == KEY_DL) -#define m_isDeleteToEol(ch) (ch == KEY_EOL) -#define m_isNextPage(ch) (ch == KEY_NPAGE) -#define m_isPrevPage(ch) (ch == KEY_PPAGE) -#define m_isLeftArrow(ch) (ch == KEY_LEFT) -#define m_isRightArrow(ch) (ch == KEY_RIGHT) - -#define m_isCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch) || \ - m_isLeftArrow(ch) || m_isRightArrow(ch) || \ - (ch == KEY_UP) || (ch == KEY_DOWN) || \ - (ch == KEY_SF) || (ch == KEY_SR) || \ - (ch == (int)'\f') || m_isStartSequence(ch)) - -#define m_isXdbStyleCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch)) - - -#endif /*_TUI_IO_H*/ diff --git a/contrib/gdb/gdb/tui/tuiLayout.c b/contrib/gdb/gdb/tui/tuiLayout.c deleted file mode 100644 index 6aa380cfe41..00000000000 --- a/contrib/gdb/gdb/tui/tuiLayout.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* -** tuiLayout.c -** This module contains procedures for handling the layout of the windows. -*/ - - -#include "defs.h" -#include "command.h" -#include "symtab.h" -#include "frame.h" - -#include "tui.h" -#include "tuiData.h" -#include "tuiGeneralWin.h" -#include "tuiStack.h" -#include "tuiRegs.h" -#include "tuiDisassem.h" - -/******************************* -** Static Local Decls -********************************/ - -static void _initGenWinInfo PARAMS - ((TuiGenWinInfoPtr, TuiWinType, int, int, int, int)); -static void _initAndMakeWin PARAMS - ((Opaque *, TuiWinType, int, int, int, int, int)); -static void _showSourceOrDisassemAndCommand PARAMS - ((TuiLayoutType)); -static void _makeSourceOrDisassemWindow PARAMS - ((TuiWinInfoPtr *, TuiWinType, int, int)); -static void _makeCommandWindow PARAMS ((TuiWinInfoPtr *, int, int)); -static void _makeSourceWindow PARAMS ((TuiWinInfoPtr *, int, int)); -static void _makeDisassemWindow PARAMS - ((TuiWinInfoPtr *, int, int)); -static void _makeDataWindow PARAMS ((TuiWinInfoPtr *, int, int)); -static void _showSourceCommand PARAMS ((void)); -static void _showDisassemCommand PARAMS ((void)); -static void _showSourceDisassemCommand PARAMS ((void)); -static void _showData PARAMS ((TuiLayoutType)); -static TuiLayoutType _nextLayout PARAMS ((void)); -static TuiLayoutType _prevLayout PARAMS ((void)); -static void _tuiLayout_command PARAMS ((char *, int)); -static void _tuiToggleLayout_command PARAMS ((char *, int)); -static void _tui_vToggleLayout_command PARAMS ((va_list)); -static void _tuiToggleSplitLayout_command PARAMS ((char *, int)); -static void _tui_vToggleSplitLayout_command PARAMS ((va_list)); -static Opaque _extractDisplayStartAddr PARAMS ((void)); -static void _tuiHandleXDBLayout PARAMS ((TuiLayoutDefPtr)); -static TuiStatus _tuiSetLayoutTo PARAMS ((char *)); - - -/*************************************** -** DEFINITIONS -***************************************/ - -#define LAYOUT_USAGE "Usage: layout prev | next | \n" - -/*************************************** -** Static Local Data -***************************************/ -static TuiLayoutType lastLayout = UNDEFINED_LAYOUT; - -/*************************************** -** PUBLIC FUNCTIONS -***************************************/ - -/* -** showLayout(). -** Show the screen layout defined -*/ -void -#ifdef __STDC__ -showLayout ( - TuiLayoutType layout) -#else -showLayout (layout) - TuiLayoutType layout; -#endif -{ - TuiLayoutType curLayout = currentLayout (); - - if (layout != curLayout) - { - /* - ** Since the new layout may cause changes in window size, we - ** should free the content and reallocate on next display of - ** source/asm - */ - tuiClearAllSourceWinsContent (NO_EMPTY_SOURCE_PROMPT); - freeAllSourceWinsContent (); - clearSourceWindows (); - if (layout == SRC_DATA_COMMAND || layout == DISASSEM_DATA_COMMAND) - { - _showData (layout); - refreshAll (winList); - } - else - { - /* First make the current layout be invisible */ - m_allBeInvisible (); - m_beInvisible (locatorWinInfoPtr ()); - - switch (layout) - { - /* Now show the new layout */ - case SRC_COMMAND: - _showSourceCommand (); - addToSourceWindows (srcWin); - break; - case DISASSEM_COMMAND: - _showDisassemCommand (); - addToSourceWindows (disassemWin); - break; - case SRC_DISASSEM_COMMAND: - _showSourceDisassemCommand (); - addToSourceWindows (srcWin); - addToSourceWindows (disassemWin); - break; - default: - break; - } - } - } - - return; -} /* showLayout */ - - -/* -** tuiSetLayout() -** Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND, -** SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND. -** If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or -** UNDEFINED_LAYOUT, then the data window is populated according -** to regsDisplayType. -*/ -TuiStatus -#ifdef __STDC__ -tuiSetLayout ( - TuiLayoutType layoutType, - TuiRegisterDisplayType regsDisplayType) -#else -tuiSetLayout (layoutType, regsDisplayType) - TuiLayoutType layoutType; - TuiRegisterDisplayType regsDisplayType; -#endif -{ - TuiStatus status = TUI_SUCCESS; - - if (layoutType != UNDEFINED_LAYOUT || regsDisplayType != TUI_UNDEFINED_REGS) - { - TuiLayoutType curLayout = currentLayout (), newLayout = UNDEFINED_LAYOUT; - int regsPopulate = FALSE; - Opaque addr = _extractDisplayStartAddr (); - TuiWinInfoPtr newWinWithFocus = (TuiWinInfoPtr) NULL, winWithFocus = tuiWinWithFocus (); - TuiLayoutDefPtr layoutDef = tuiLayoutDef (); - - - if (layoutType == UNDEFINED_LAYOUT && - regsDisplayType != TUI_UNDEFINED_REGS) - { - if (curLayout == SRC_DISASSEM_COMMAND) - newLayout = DISASSEM_DATA_COMMAND; - else if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND) - newLayout = SRC_DATA_COMMAND; - else if (curLayout == DISASSEM_COMMAND || - curLayout == DISASSEM_DATA_COMMAND) - newLayout = DISASSEM_DATA_COMMAND; - } - else - newLayout = layoutType; - - regsPopulate = (newLayout == SRC_DATA_COMMAND || - newLayout == DISASSEM_DATA_COMMAND || - regsDisplayType != TUI_UNDEFINED_REGS); - if (newLayout != curLayout || regsDisplayType != TUI_UNDEFINED_REGS) - { - if (newLayout != curLayout) - { - if (winWithFocus != cmdWin) - tuiClearWinFocus (); - showLayout (newLayout); - /* - ** Now determine where focus should be - */ - if (winWithFocus != cmdWin) - { - switch (newLayout) - { - case SRC_COMMAND: - tuiSetWinFocusTo (srcWin); - layoutDef->displayMode = SRC_WIN; - layoutDef->split = FALSE; - break; - case DISASSEM_COMMAND: - /* the previous layout was not showing - ** code. this can happen if there is no - ** source available: - ** 1. if the source file is in another dir OR - ** 2. if target was compiled without -g - ** We still want to show the assembly though! - */ - addr = vcatch_errors ((OpaqueFuncPtr) - tuiGetBeginAsmAddress); - tuiSetWinFocusTo (disassemWin); - layoutDef->displayMode = DISASSEM_WIN; - layoutDef->split = FALSE; - break; - case SRC_DISASSEM_COMMAND: - /* the previous layout was not showing - ** code. this can happen if there is no - ** source available: - ** 1. if the source file is in another dir OR - ** 2. if target was compiled without -g - ** We still want to show the assembly though! - */ - addr = vcatch_errors ((OpaqueFuncPtr) - tuiGetBeginAsmAddress); - if (winWithFocus == srcWin) - tuiSetWinFocusTo (srcWin); - else - tuiSetWinFocusTo (disassemWin); - layoutDef->split = TRUE; - break; - case SRC_DATA_COMMAND: - if (winWithFocus != dataWin) - tuiSetWinFocusTo (srcWin); - else - tuiSetWinFocusTo (dataWin); - layoutDef->displayMode = SRC_WIN; - layoutDef->split = FALSE; - break; - case DISASSEM_DATA_COMMAND: - /* the previous layout was not showing - ** code. this can happen if there is no - ** source available: - ** 1. if the source file is in another dir OR - ** 2. if target was compiled without -g - ** We still want to show the assembly though! - */ - addr = vcatch_errors ((OpaqueFuncPtr) - tuiGetBeginAsmAddress); - if (winWithFocus != dataWin) - tuiSetWinFocusTo (disassemWin); - else - tuiSetWinFocusTo (dataWin); - layoutDef->displayMode = DISASSEM_WIN; - layoutDef->split = FALSE; - break; - default: - break; - } - } - if (newWinWithFocus != (TuiWinInfoPtr) NULL) - tuiSetWinFocusTo (newWinWithFocus); - /* - ** Now update the window content - */ - if (!regsPopulate && - (newLayout == SRC_DATA_COMMAND || - newLayout == DISASSEM_DATA_COMMAND)) - tuiDisplayAllData (); - - tuiUpdateSourceWindowsWithAddr (addr); - } - if (regsPopulate) - { - layoutDef->regsDisplayType = - (regsDisplayType == TUI_UNDEFINED_REGS ? - TUI_GENERAL_REGS : regsDisplayType); - tuiShowRegisters (layoutDef->regsDisplayType); - } - } - } - else - status = TUI_FAILURE; - - return status; -} /* tuiSetLayout */ - - -/* -** tui_vSetLayoutTo() -** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, -** REGS, $REGS, $GREGS, $FREGS, $SREGS with arguments in a va_list -*/ -TuiStatus -#ifdef __STDC__ -tui_vSetLayoutTo ( - va_list args) -#else -tui_vSetLayoutTo (args) - va_list args; -#endif -{ - char *layoutName; - - layoutName = va_arg (args, char *); - - return (_tuiSetLayoutTo (layoutName)); -} /* tui_vSetLayoutTo */ - - -/* -** tuiAddWinToLayout(). -** Add the specified window to the layout in a logical way. -** This means setting up the most logical layout given the -** window to be added. -*/ -void -#ifdef __STDC__ -tuiAddWinToLayout ( - TuiWinType type) -#else -tuiAddWinToLayout (type) - TuiWinType type; -#endif -{ - TuiLayoutType curLayout = currentLayout (); - - switch (type) - { - case SRC_WIN: - if (curLayout != SRC_COMMAND && - curLayout != SRC_DISASSEM_COMMAND && - curLayout != SRC_DATA_COMMAND) - { - clearSourceWindowsDetail (); - if (curLayout == DISASSEM_DATA_COMMAND) - showLayout (SRC_DATA_COMMAND); - else - showLayout (SRC_COMMAND); - } - break; - case DISASSEM_WIN: - if (curLayout != DISASSEM_COMMAND && - curLayout != SRC_DISASSEM_COMMAND && - curLayout != DISASSEM_DATA_COMMAND) - { - clearSourceWindowsDetail (); - if (curLayout == SRC_DATA_COMMAND) - showLayout (DISASSEM_DATA_COMMAND); - else - showLayout (DISASSEM_COMMAND); - } - break; - case DATA_WIN: - if (curLayout != SRC_DATA_COMMAND && - curLayout != DISASSEM_DATA_COMMAND) - { - if (curLayout == DISASSEM_COMMAND) - showLayout (DISASSEM_DATA_COMMAND); - else - showLayout (SRC_DATA_COMMAND); - } - break; - default: - break; - } - - return; -} /* tuiAddWinToLayout */ - - -/* -** tui_vAddWinToLayout(). -** Add the specified window to the layout in a logical way, -** with arguments in a va_list. -*/ -void -#ifdef __STDC__ -tui_vAddWinToLayout ( - va_list args) -#else -tui_vAddWinToLayout (args) - va_list args; -#endif -{ - TuiWinType type = va_arg (args, TuiWinType); - - tuiAddWinToLayout (type); - - return; -} /* tui_vAddWinToLayout */ - - -/* -** tuiDefaultWinHeight(). -** Answer the height of a window. If it hasn't been created yet, -** answer what the height of a window would be based upon its -** type and the layout. -*/ -int -#ifdef __STDC__ -tuiDefaultWinHeight ( - TuiWinType type, - TuiLayoutType layout) -#else -tuiDefaultWinHeight (type, layout) - TuiWinType type; - TuiLayoutType layout; -#endif -{ - int h; - - if (winList[type] != (TuiWinInfoPtr) NULL) - h = winList[type]->generic.height; - else - { - switch (layout) - { - case SRC_COMMAND: - case DISASSEM_COMMAND: - if (m_winPtrIsNull (cmdWin)) - h = termHeight () / 2; - else - h = termHeight () - cmdWin->generic.height; - break; - case SRC_DISASSEM_COMMAND: - case SRC_DATA_COMMAND: - case DISASSEM_DATA_COMMAND: - if (m_winPtrIsNull (cmdWin)) - h = termHeight () / 3; - else - h = (termHeight () - cmdWin->generic.height) / 2; - break; - default: - h = 0; - break; - } - } - - return h; -} /* tuiDefaultWinHeight */ - - -/* -** tuiDefaultWinViewportHeight(). -** Answer the height of a window. If it hasn't been created yet, -** answer what the height of a window would be based upon its -** type and the layout. -*/ -int -#ifdef __STDC__ -tuiDefaultWinViewportHeight ( - TuiWinType type, - TuiLayoutType layout) -#else -tuiDefaultWinViewportHeight (type, layout) - TuiWinType type; - TuiLayoutType layout; -#endif -{ - int h; - - h = tuiDefaultWinHeight (type, layout); - - if (winList[type] == cmdWin) - h -= 1; - else - h -= 2; - - return h; -} /* tuiDefaultWinViewportHeight */ - - -/* -** _initialize_tuiLayout(). -** Function to initialize gdb commands, for tui window layout -** manipulation. -*/ -void -_initialize_tuiLayout () -{ - if (tui_version) - { - add_com ("layout", class_tui, _tuiLayout_command, - "Change the layout of windows.\n\ -Usage: layout prev | next | \n\ -Layout names are:\n\ - src : Displays source and command windows.\n\ - asm : Displays disassembly and command windows.\n\ - split : Displays source, disassembly and command windows.\n\ - regs : Displays register window. If existing layout\n\ - is source/command or assembly/command, the \n\ - register window is displayed. If the\n\ - source/assembly/command (split) is displayed, \n\ - the register window is displayed with \n\ - the window that has current logical focus.\n"); - if (xdb_commands) - { - add_com ("td", class_tui, _tuiToggleLayout_command, - "Toggle between Source/Command and Disassembly/Command layouts.\n"); - add_com ("ts", class_tui, _tuiToggleSplitLayout_command, - "Toggle between Source/Command or Disassembly/Command and \n\ -Source/Disassembly/Command layouts.\n"); - } - } - - return; -} /* _intialize_tuiLayout */ - - -/************************* -** STATIC LOCAL FUNCTIONS -**************************/ - - -/* -** _tuiSetLayoutTo() -** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, REGS, -** $REGS, $GREGS, $FREGS, $SREGS. -*/ -static TuiStatus -#ifdef __STDC__ -_tuiSetLayoutTo ( - char *layoutName) -#else -_tuiSetLayoutTo (layoutName) - char *layoutName; -#endif -{ - TuiStatus status = TUI_SUCCESS; - - if (layoutName != (char *) NULL) - { - register int i; - register char *bufPtr; - TuiLayoutType newLayout = UNDEFINED_LAYOUT; - TuiRegisterDisplayType dpyType = TUI_UNDEFINED_REGS; - TuiLayoutType curLayout = currentLayout (); - - bufPtr = (char *) tuiStrDup (layoutName); - for (i = 0; (i < strlen (layoutName)); i++) - bufPtr[i] = toupper (bufPtr[i]); - - /* First check for ambiguous input */ - if (strlen (bufPtr) <= 1 && (*bufPtr == 'S' || *bufPtr == '$')) - { - warning ("Ambiguous command input.\n"); - status = TUI_FAILURE; - } - else - { - if (subsetCompare (bufPtr, "SRC")) - newLayout = SRC_COMMAND; - else if (subsetCompare (bufPtr, "ASM")) - newLayout = DISASSEM_COMMAND; - else if (subsetCompare (bufPtr, "SPLIT")) - newLayout = SRC_DISASSEM_COMMAND; - else if (subsetCompare (bufPtr, "REGS") || - subsetCompare (bufPtr, TUI_GENERAL_SPECIAL_REGS_NAME) || - subsetCompare (bufPtr, TUI_GENERAL_REGS_NAME) || - subsetCompare (bufPtr, TUI_FLOAT_REGS_NAME) || - subsetCompare (bufPtr, TUI_SPECIAL_REGS_NAME)) - { - if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND) - newLayout = SRC_DATA_COMMAND; - else - newLayout = DISASSEM_DATA_COMMAND; - -/* could ifdef out the following code. when compile with -z, there are null - pointer references that cause a core dump if 'layout regs' is the first - layout command issued by the user. HP has asked us to hook up this code - - edie epstein - */ - if (subsetCompare (bufPtr, TUI_FLOAT_REGS_NAME)) - { - if (dataWin->detail.dataDisplayInfo.regsDisplayType != - TUI_SFLOAT_REGS && - dataWin->detail.dataDisplayInfo.regsDisplayType != - TUI_DFLOAT_REGS) - dpyType = TUI_SFLOAT_REGS; - else - dpyType = - dataWin->detail.dataDisplayInfo.regsDisplayType; - } - else if (subsetCompare (bufPtr, - TUI_GENERAL_SPECIAL_REGS_NAME)) - dpyType = TUI_GENERAL_AND_SPECIAL_REGS; - else if (subsetCompare (bufPtr, TUI_GENERAL_REGS_NAME)) - dpyType = TUI_GENERAL_REGS; - else if (subsetCompare (bufPtr, TUI_SPECIAL_REGS_NAME)) - dpyType = TUI_SPECIAL_REGS; - else - { - if (dataWin->detail.dataDisplayInfo.regsDisplayType != - TUI_UNDEFINED_REGS) - dpyType = - dataWin->detail.dataDisplayInfo.regsDisplayType; - else - dpyType = TUI_GENERAL_REGS; - } - -/* end of potential ifdef - */ - -/* if ifdefed out code above, then assume that the user wishes to display the - general purpose registers - */ - -/* dpyType = TUI_GENERAL_REGS; - */ - } - else if (subsetCompare (bufPtr, "NEXT")) - newLayout = _nextLayout (); - else if (subsetCompare (bufPtr, "PREV")) - newLayout = _prevLayout (); - else - status = TUI_FAILURE; - free (bufPtr); - - tuiSetLayout (newLayout, dpyType); - } - } - else - status = TUI_FAILURE; - - return status; -} /* _tuiSetLayoutTo */ - - -static Opaque -#ifdef __STDC__ -_extractDisplayStartAddr (void) -#else -_extractDisplayStartAddr () -#endif -{ - TuiLayoutType curLayout = currentLayout (); - Opaque addr; - - switch (curLayout) - { - case SRC_COMMAND: - case SRC_DATA_COMMAND: - addr = (Opaque) find_line_pc ( - current_source_symtab, - srcWin->detail.sourceInfo.startLineOrAddr.lineNo); - break; - case DISASSEM_COMMAND: - case SRC_DISASSEM_COMMAND: - case DISASSEM_DATA_COMMAND: - addr = disassemWin->detail.sourceInfo.startLineOrAddr.addr; - break; - default: - addr = (Opaque) NULL; - break; - } - - return addr; -} /* _extractDisplayStartAddr */ - - -static void -#ifdef __STDC__ -_tuiHandleXDBLayout ( - TuiLayoutDefPtr layoutDef) -#else -_tuiHandleXDBLayout (layoutDef) - TuiLayoutDefPtr layoutDef; -#endif -{ - if (layoutDef->split) - { - tuiSetLayout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS); - tuiSetWinFocusTo (winList[layoutDef->displayMode]); - } - else - { - if (layoutDef->displayMode == SRC_WIN) - tuiSetLayout (SRC_COMMAND, TUI_UNDEFINED_REGS); - else - tuiSetLayout (DISASSEM_DATA_COMMAND, layoutDef->regsDisplayType); - } - - - return; -} /* _tuiHandleXDBLayout */ - - -static void -#ifdef __STDC__ -_tuiToggleLayout_command ( - char *arg, - int fromTTY) -#else -_tuiToggleLayout_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) _tui_vToggleLayout_command, arg, fromTTY); -} - -static void -#ifdef __STDC__ -_tui_vToggleLayout_command ( - va_list args) -#else -_tui_vToggleLayout_command (args) - va_list args; -#endif -{ - TuiLayoutDefPtr layoutDef = tuiLayoutDef (); - - if (layoutDef->displayMode == SRC_WIN) - layoutDef->displayMode = DISASSEM_WIN; - else - layoutDef->displayMode = SRC_WIN; - - if (!layoutDef->split) - _tuiHandleXDBLayout (layoutDef); - - return; -} /* _tuiToggleLayout_command */ - - -static void -#ifdef __STDC__ -_tuiToggleSplitLayout_command ( - char *arg, - int fromTTY) -#else -_tuiToggleSplitLayout_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) _tui_vToggleSplitLayout_command, arg, fromTTY); -} - -static void -#ifdef __STDC__ -_tui_vToggleSplitLayout_command ( - va_list args) -#else -_tui_vToggleSplitLayout_command (args) - va_list args; -#endif -{ - TuiLayoutDefPtr layoutDef = tuiLayoutDef (); - - layoutDef->split = (!layoutDef->split); - _tuiHandleXDBLayout (layoutDef); - - return; -} /* _tui_vToggleSplitLayout_command */ - - -static void -#ifdef __STDC__ -_tuiLayout_command ( - char *arg, - int fromTTY) -#else -_tuiLayout_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - if ((TuiStatus) tuiDo ( - (TuiOpaqueFuncPtr) tui_vSetLayoutTo, arg) != TUI_SUCCESS) - warning ("Invalid layout specified.\n%s" LAYOUT_USAGE); - - return; -} /* _tuiLayout_command */ - -/* -** _nextLayout(). -** Answer the previous layout to cycle to. -*/ -static TuiLayoutType -#ifdef __STDC__ -_nextLayout (void) -#else -_nextLayout () -#endif -{ - TuiLayoutType newLayout; - - newLayout = currentLayout (); - if (newLayout == UNDEFINED_LAYOUT) - newLayout = SRC_COMMAND; - else - { - newLayout++; - if (newLayout == UNDEFINED_LAYOUT) - newLayout = SRC_COMMAND; - } - - return newLayout; -} /* _nextLayout */ - - -/* -** _prevLayout(). -** Answer the next layout to cycle to. -*/ -static TuiLayoutType -#ifdef __STDC__ -_prevLayout (void) -#else -_prevLayout () -#endif -{ - TuiLayoutType newLayout; - - newLayout = currentLayout (); - if (newLayout == SRC_COMMAND) - newLayout = DISASSEM_DATA_COMMAND; - else - { - newLayout--; - if (newLayout == UNDEFINED_LAYOUT) - newLayout = DISASSEM_DATA_COMMAND; - } - - return newLayout; -} /* _prevLayout */ - - - -/* -** _makeCommandWindow(). -*/ -static void -#ifdef __STDC__ -_makeCommandWindow ( - TuiWinInfoPtr * winInfoPtr, - int height, - int originY) -#else -_makeCommandWindow (winInfoPtr, height, originY) - TuiWinInfoPtr *winInfoPtr; - int height; - int originY; -#endif -{ - _initAndMakeWin ((Opaque *) winInfoPtr, - CMD_WIN, - height, - termWidth (), - 0, - originY, - DONT_BOX_WINDOW); - - (*winInfoPtr)->canHighlight = FALSE; - - return; -} /* _makeCommandWindow */ - - -/* -** _makeSourceWindow(). -*/ -static void -#ifdef __STDC__ -_makeSourceWindow ( - TuiWinInfoPtr * winInfoPtr, - int height, - int originY) -#else -_makeSourceWindow (winInfoPtr, height, originY) - TuiWinInfoPtr *winInfoPtr; - int height; - int originY; -#endif -{ - _makeSourceOrDisassemWindow (winInfoPtr, SRC_WIN, height, originY); - - return; -} /* _makeSourceWindow */ - - -/* -** _makeDisassemWindow(). -*/ -static void -#ifdef __STDC__ -_makeDisassemWindow ( - TuiWinInfoPtr * winInfoPtr, - int height, - int originY) -#else -_makeDisassemWindow (winInfoPtr, height, originY) - TuiWinInfoPtr *winInfoPtr; - int height; - int originY; -#endif -{ - _makeSourceOrDisassemWindow (winInfoPtr, DISASSEM_WIN, height, originY); - - return; -} /* _makeDisassemWindow */ - - -/* -** _makeDataWindow(). -*/ -static void -#ifdef __STDC__ -_makeDataWindow ( - TuiWinInfoPtr * winInfoPtr, - int height, - int originY) -#else -_makeDataWindow (winInfoPtr, height, originY) - TuiWinInfoPtr *winInfoPtr; - int height; - int originY; -#endif -{ - _initAndMakeWin ((Opaque *) winInfoPtr, - DATA_WIN, - height, - termWidth (), - 0, - originY, - BOX_WINDOW); - - return; -} /* _makeDataWindow */ - - - -/* -** _showSourceCommand(). -** Show the Source/Command layout -*/ -static void -#ifdef __STDC__ -_showSourceCommand (void) -#else -_showSourceCommand () -#endif -{ - _showSourceOrDisassemAndCommand (SRC_COMMAND); - - return; -} /* _showSourceCommand */ - - -/* -** _showDisassemCommand(). -** Show the Dissassem/Command layout -*/ -static void -#ifdef __STDC__ -_showDisassemCommand (void) -#else -_showDisassemCommand () -#endif -{ - _showSourceOrDisassemAndCommand (DISASSEM_COMMAND); - - return; -} /* _showDisassemCommand */ - - -/* -** _showSourceDisassemCommand(). -** Show the Source/Disassem/Command layout -*/ -static void -#ifdef __STDC__ -_showSourceDisassemCommand (void) -#else -_showSourceDisassemCommand () -#endif -{ - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - if (currentLayout () != SRC_DISASSEM_COMMAND) - { - int cmdHeight, srcHeight, asmHeight; - - if (m_winPtrNotNull (cmdWin)) - cmdHeight = cmdWin->generic.height; - else - cmdHeight = termHeight () / 3; - - srcHeight = (termHeight () - cmdHeight) / 2; - asmHeight = termHeight () - (srcHeight + cmdHeight); - - if (m_winPtrIsNull (srcWin)) - _makeSourceWindow (&srcWin, srcHeight, 0); - else - { - _initGenWinInfo (&srcWin->generic, - srcWin->generic.type, - srcHeight, - srcWin->generic.width, - srcWin->detail.sourceInfo.executionInfo->width, - 0); - srcWin->canHighlight = TRUE; - _initGenWinInfo (srcWin->detail.sourceInfo.executionInfo, - EXEC_INFO_WIN, - srcHeight, - 3, - 0, - 0); - m_beVisible (srcWin); - m_beVisible (srcWin->detail.sourceInfo.executionInfo); - srcWin->detail.sourceInfo.hasLocator = FALSE;; - } - if (m_winPtrNotNull (srcWin)) - { - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - tuiShowSourceContent (srcWin); - if (m_winPtrIsNull (disassemWin)) - { - _makeDisassemWindow (&disassemWin, asmHeight, srcHeight - 1); - _initAndMakeWin ((Opaque *) & locator, - LOCATOR_WIN, - 2 /* 1 */ , - termWidth (), - 0, - (srcHeight + asmHeight) - 1, - DONT_BOX_WINDOW); - } - else - { - _initGenWinInfo (locator, - LOCATOR_WIN, - 2 /* 1 */ , - termWidth (), - 0, - (srcHeight + asmHeight) - 1); - disassemWin->detail.sourceInfo.hasLocator = TRUE; - _initGenWinInfo ( - &disassemWin->generic, - disassemWin->generic.type, - asmHeight, - disassemWin->generic.width, - disassemWin->detail.sourceInfo.executionInfo->width, - srcHeight - 1); - _initGenWinInfo (disassemWin->detail.sourceInfo.executionInfo, - EXEC_INFO_WIN, - asmHeight, - 3, - 0, - srcHeight - 1); - disassemWin->canHighlight = TRUE; - m_beVisible (disassemWin); - m_beVisible (disassemWin->detail.sourceInfo.executionInfo); - } - if (m_winPtrNotNull (disassemWin)) - { - srcWin->detail.sourceInfo.hasLocator = FALSE; - disassemWin->detail.sourceInfo.hasLocator = TRUE; - m_beVisible (locator); - tuiShowLocatorContent (); - tuiShowSourceContent (disassemWin); - - if (m_winPtrIsNull (cmdWin)) - _makeCommandWindow (&cmdWin, - cmdHeight, - termHeight () - cmdHeight); - else - { - _initGenWinInfo (&cmdWin->generic, - cmdWin->generic.type, - cmdWin->generic.height, - cmdWin->generic.width, - 0, - cmdWin->generic.origin.y); - cmdWin->canHighlight = FALSE; - m_beVisible (cmdWin); - } - if (m_winPtrNotNull (cmdWin)) - tuiRefreshWin (&cmdWin->generic); - } - } - setCurrentLayoutTo (SRC_DISASSEM_COMMAND); - } - - return; -} /* _showSourceDisassemCommand */ - - -/* -** _showData(). -** Show the Source/Data/Command or the Dissassembly/Data/Command layout -*/ -static void -#ifdef __STDC__ -_showData ( - TuiLayoutType newLayout) -#else -_showData (newLayout) - TuiLayoutType newLayout; -#endif -{ - int totalHeight = (termHeight () - cmdWin->generic.height); - int srcHeight, dataHeight; - TuiWinType winType; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - - dataHeight = totalHeight / 2; - srcHeight = totalHeight - dataHeight; - m_allBeInvisible (); - m_beInvisible (locator); - _makeDataWindow (&dataWin, dataHeight, 0); - dataWin->canHighlight = TRUE; - if (newLayout == SRC_DATA_COMMAND) - winType = SRC_WIN; - else - winType = DISASSEM_WIN; - if (m_winPtrIsNull (winList[winType])) - { - if (winType == SRC_WIN) - _makeSourceWindow (&winList[winType], srcHeight, dataHeight - 1); - else - _makeDisassemWindow (&winList[winType], srcHeight, dataHeight - 1); - _initAndMakeWin ((Opaque *) & locator, - LOCATOR_WIN, - 2 /* 1 */ , - termWidth (), - 0, - totalHeight - 1, - DONT_BOX_WINDOW); - } - else - { - _initGenWinInfo (&winList[winType]->generic, - winList[winType]->generic.type, - srcHeight, - winList[winType]->generic.width, - winList[winType]->detail.sourceInfo.executionInfo->width, - dataHeight - 1); - _initGenWinInfo (winList[winType]->detail.sourceInfo.executionInfo, - EXEC_INFO_WIN, - srcHeight, - 3, - 0, - dataHeight - 1); - m_beVisible (winList[winType]); - m_beVisible (winList[winType]->detail.sourceInfo.executionInfo); - _initGenWinInfo (locator, - LOCATOR_WIN, - 2 /* 1 */ , - termWidth (), - 0, - totalHeight - 1); - } - winList[winType]->detail.sourceInfo.hasLocator = TRUE; - m_beVisible (locator); - tuiShowLocatorContent (); - addToSourceWindows (winList[winType]); - setCurrentLayoutTo (newLayout); - - return; -} /* _showData */ - -/* -** _initGenWinInfo(). -*/ -static void -#ifdef __STDC__ -_initGenWinInfo ( - TuiGenWinInfoPtr winInfo, - TuiWinType type, - int height, - int width, - int originX, - int originY) -#else -_initGenWinInfo (winInfo, type, height, width, originX, originY) - TuiGenWinInfoPtr winInfo; - TuiWinType type; - int height; - int width; - int originX; - int originY; -#endif -{ - int h = height; - - winInfo->type = type; - winInfo->width = width; - winInfo->height = h; - if (h > 1) - { - winInfo->viewportHeight = h - 1; - if (winInfo->type != CMD_WIN) - winInfo->viewportHeight--; - } - else - winInfo->viewportHeight = 1; - winInfo->origin.x = originX; - winInfo->origin.y = originY; - - return; -} /* _initGenWinInfo */ - -/* -** _initAndMakeWin(). -*/ -static void -#ifdef __STDC__ -_initAndMakeWin ( - Opaque * winInfoPtr, - TuiWinType winType, - int height, - int width, - int originX, - int originY, - int boxIt) -#else -_initAndMakeWin (winInfoPtr, winType, height, width, originX, originY, boxIt) - Opaque *winInfoPtr; - TuiWinType winType; - int height; - int width; - int originX; - int originY; - int boxIt; -#endif -{ - Opaque opaqueWinInfo = *winInfoPtr; - TuiGenWinInfoPtr generic; - - if (opaqueWinInfo == (Opaque) NULL) - { - if (m_winIsAuxillary (winType)) - opaqueWinInfo = (Opaque) allocGenericWinInfo (); - else - opaqueWinInfo = (Opaque) allocWinInfo (winType); - } - if (m_winIsAuxillary (winType)) - generic = (TuiGenWinInfoPtr) opaqueWinInfo; - else - generic = &((TuiWinInfoPtr) opaqueWinInfo)->generic; - - if (opaqueWinInfo != (Opaque) NULL) - { - _initGenWinInfo (generic, winType, height, width, originX, originY); - if (!m_winIsAuxillary (winType)) - { - if (generic->type == CMD_WIN) - ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = FALSE; - else - ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = TRUE; - } - makeWindow (generic, boxIt); - if (winType == LOCATOR_WIN) - tuiClearLocatorDisplay (); - echo (); - } - *winInfoPtr = opaqueWinInfo; - - return; -} /* _initAndMakeWin */ - - -/* -** _makeSourceOrDisassemWindow(). -*/ -static void -#ifdef __STDC__ -_makeSourceOrDisassemWindow ( - TuiWinInfoPtr * winInfoPtr, - TuiWinType type, - int height, - int originY) -#else -_makeSourceOrDisassemWindow (winInfoPtr, type, height, originY) - TuiWinInfoPtr *winInfoPtr; - TuiWinType type; - int height; - int originY; -#endif -{ - TuiGenWinInfoPtr executionInfo = (TuiGenWinInfoPtr) NULL; - - /* - ** Create the exeuction info window. - */ - if (type == SRC_WIN) - executionInfo = sourceExecInfoWinPtr (); - else - executionInfo = disassemExecInfoWinPtr (); - _initAndMakeWin ((Opaque *) & executionInfo, - EXEC_INFO_WIN, - height, - 3, - 0, - originY, - DONT_BOX_WINDOW); - /* - ** Now create the source window. - */ - _initAndMakeWin ((Opaque *) winInfoPtr, - type, - height, - termWidth () - executionInfo->width, - executionInfo->width, - originY, - BOX_WINDOW); - - (*winInfoPtr)->detail.sourceInfo.executionInfo = executionInfo; - - return; -} /* _makeSourceOrDisassemWindow */ - - -/* -** _showSourceOrDisassemAndCommand(). -** Show the Source/Command or the Disassem layout -*/ -static void -#ifdef __STDC__ -_showSourceOrDisassemAndCommand ( - TuiLayoutType layoutType) -#else -_showSourceOrDisassemAndCommand (layoutType) - TuiLayoutType layoutType; -#endif -{ - if (currentLayout () != layoutType) - { - TuiWinInfoPtr *winInfoPtr; - int areaLeft; - int srcHeight, cmdHeight; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - if (m_winPtrNotNull (cmdWin)) - cmdHeight = cmdWin->generic.height; - else - cmdHeight = termHeight () / 3; - srcHeight = termHeight () - cmdHeight; - - - if (layoutType == SRC_COMMAND) - winInfoPtr = &srcWin; - else - winInfoPtr = &disassemWin; - - if (m_winPtrIsNull (*winInfoPtr)) - { - if (layoutType == SRC_COMMAND) - _makeSourceWindow (winInfoPtr, srcHeight - 1, 0); - else - _makeDisassemWindow (winInfoPtr, srcHeight - 1, 0); - _initAndMakeWin ((Opaque *) & locator, - LOCATOR_WIN, - 2 /* 1 */ , - termWidth (), - 0, - srcHeight - 1, - DONT_BOX_WINDOW); - } - else - { - _initGenWinInfo (locator, - LOCATOR_WIN, - 2 /* 1 */ , - termWidth (), - 0, - srcHeight - 1); - (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE; - _initGenWinInfo ( - &(*winInfoPtr)->generic, - (*winInfoPtr)->generic.type, - srcHeight - 1, - (*winInfoPtr)->generic.width, - (*winInfoPtr)->detail.sourceInfo.executionInfo->width, - 0); - _initGenWinInfo ((*winInfoPtr)->detail.sourceInfo.executionInfo, - EXEC_INFO_WIN, - srcHeight - 1, - 3, - 0, - 0); - (*winInfoPtr)->canHighlight = TRUE; - m_beVisible (*winInfoPtr); - m_beVisible ((*winInfoPtr)->detail.sourceInfo.executionInfo); - } - if (m_winPtrNotNull (*winInfoPtr)) - { - (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE; - m_beVisible (locator); - tuiShowLocatorContent (); - tuiShowSourceContent (*winInfoPtr); - - if (m_winPtrIsNull (cmdWin)) - { - _makeCommandWindow (&cmdWin, cmdHeight, srcHeight); - tuiRefreshWin (&cmdWin->generic); - } - else - { - _initGenWinInfo (&cmdWin->generic, - cmdWin->generic.type, - cmdWin->generic.height, - cmdWin->generic.width, - cmdWin->generic.origin.x, - cmdWin->generic.origin.y); - cmdWin->canHighlight = FALSE; - m_beVisible (cmdWin); - } - } - setCurrentLayoutTo (layoutType); - } - - return; -} /* _showSourceOrDisassemAndCommand */ diff --git a/contrib/gdb/gdb/tui/tuiLayout.h b/contrib/gdb/gdb/tui/tuiLayout.h deleted file mode 100644 index 57d8bbc90b6..00000000000 --- a/contrib/gdb/gdb/tui/tuiLayout.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef TUI_LAYOUT_H -#define TUI_LAYOUT_H - -extern void showLayout PARAMS ((TuiLayoutType)); -extern void tuiAddWinToLayout PARAMS ((TuiWinType)); -extern void tui_vAddWinToLayout PARAMS ((va_list)); -extern int tuiDefaultWinHeight - PARAMS ((TuiWinType, TuiLayoutType)); -extern int tuiDefaultWinViewportHeight - PARAMS ((TuiWinType, TuiLayoutType)); -extern TuiStatus tuiSetLayout - PARAMS ((TuiLayoutType, TuiRegisterDisplayType)); -extern TuiStatus tui_vSetLayoutTo PARAMS ((va_list)); - -#endif /*TUI_LAYOUT_H*/ diff --git a/contrib/gdb/gdb/tui/tuiRegs.c b/contrib/gdb/gdb/tui/tuiRegs.c deleted file mode 100644 index b78b9bc873c..00000000000 --- a/contrib/gdb/gdb/tui/tuiRegs.c +++ /dev/null @@ -1,1210 +0,0 @@ - -/* -** tuiRegs.c -** This module contains functions to support display of registers -** in the data window. -*/ - - -#include "defs.h" -#include "tui.h" -#include "tuiData.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "gdbcmd.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "tuiLayout.h" -#include "tuiWin.h" - - -/***************************************** -** LOCAL DEFINITIONS ** -******************************************/ -#define DOUBLE_FLOAT_LABEL_WIDTH 6 -#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: " -#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */ - -#define SINGLE_FLOAT_LABEL_WIDTH 6 -#define SINGLE_FLOAT_LABEL_FMT "%6.6s: " -#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */ - -#define SINGLE_LABEL_WIDTH 10 -#define SINGLE_LABEL_FMT "%10.10s: " -#define SINGLE_VALUE_WIDTH 14/* minimum of 8 but may be in sci notation */ - -/* In the code HP gave Cygnus, this was actually a function call to a - PA-specific function, which was supposed to determine whether the - target was a 64-bit or 32-bit processor. However, the 64-bit - support wasn't complete, so we didn't merge that in, so we leave - this here as a stub. */ -#define IS_64BIT 0 - -/***************************************** -** STATIC DATA ** -******************************************/ - - -/***************************************** -** STATIC LOCAL FUNCTIONS FORWARD DECLS ** -******************************************/ -static TuiStatus _tuiSetRegsContent - PARAMS ((int, int, struct frame_info *, - TuiRegisterDisplayType, int)); -static char *_tuiRegisterName PARAMS ((int)); -static TuiStatus _tuiGetRegisterRawValue - PARAMS ((int, char *, struct frame_info *)); -static void _tuiSetRegisterElement - PARAMS ((int, struct frame_info *, - TuiDataElementPtr, int)); -static void _tuiDisplayRegister - PARAMS ((int, TuiGenWinInfoPtr, enum precision_type)); -static void _tuiRegisterFormat - PARAMS ((char *, int, int, TuiDataElementPtr, - enum precision_type)); -static TuiStatus _tuiSetGeneralRegsContent PARAMS ((int)); -static TuiStatus _tuiSetSpecialRegsContent PARAMS ((int)); -static TuiStatus _tuiSetGeneralAndSpecialRegsContent PARAMS ((int)); -static TuiStatus _tuiSetFloatRegsContent PARAMS ((TuiRegisterDisplayType, int)); -static int _tuiRegValueHasChanged - PARAMS ((TuiDataElementPtr, struct frame_info *, - char *)); -static void _tuiShowFloat_command PARAMS ((char *, int)); -static void _tuiShowGeneral_command PARAMS ((char *, int)); -static void _tuiShowSpecial_command PARAMS ((char *, int)); -static void _tui_vShowRegisters_commandSupport PARAMS ((va_list)); -static void _tuiToggleFloatRegs_command PARAMS ((char *, int)); -static void _tuiScrollRegsForward_command PARAMS ((char *, int)); -static void _tuiScrollRegsBackward_command PARAMS ((char *, int)); -static void _tui_vShowRegisters_commandSupport PARAMS ((va_list)); - - - -/***************************************** -** PUBLIC FUNCTIONS ** -******************************************/ - -/* -** tuiLastRegsLineNo() -** Answer the number of the last line in the regs display. -** If there are no registers (-1) is returned. -*/ -int -#ifdef __STDC__ -tuiLastRegsLineNo (void) -#else -tuiLastRegsLineNo () -#endif -{ - register int numLines = (-1); - - if (dataWin->detail.dataDisplayInfo.regsContentCount > 0) - { - numLines = (dataWin->detail.dataDisplayInfo.regsContentCount / - dataWin->detail.dataDisplayInfo.regsColumnCount); - if (dataWin->detail.dataDisplayInfo.regsContentCount % - dataWin->detail.dataDisplayInfo.regsColumnCount) - numLines++; - } - return numLines; -} /* tuiLastRegsLineNo */ - - -/* -** tuiLineFromRegElementNo() -** Answer the line number that the register element at elementNo is -** on. If elementNo is greater than the number of register elements -** there are, -1 is returned. -*/ -int -#ifdef __STDC__ -tuiLineFromRegElementNo ( - int elementNo) -#else -tuiLineFromRegElementNo (elementNo) - int elementNo; -#endif -{ - if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) - { - int i, line = (-1); - - i = 1; - while (line == (-1)) - { - if (elementNo < - (dataWin->detail.dataDisplayInfo.regsColumnCount * i)) - line = i - 1; - else - i++; - } - - return line; - } - else - return (-1); -} /* tuiLineFromRegElementNo */ - - -/* -** tuiFirstRegElementNoInLine() -** Answer the index of the first element in lineNo. If lineNo is -** past the register area (-1) is returned. -*/ -int -#ifdef __STDC__ -tuiFirstRegElementNoInLine ( - int lineNo) -#else -tuiFirstRegElementNoInLine (lineNo) - int lineNo; -#endif -{ - if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) - <= dataWin->detail.dataDisplayInfo.regsContentCount) - return ((lineNo + 1) * - dataWin->detail.dataDisplayInfo.regsColumnCount) - - dataWin->detail.dataDisplayInfo.regsColumnCount; - else - return (-1); -} /* tuiFirstRegElementNoInLine */ - - -/* -** tuiLastRegElementNoInLine() -** Answer the index of the last element in lineNo. If lineNo is past -** the register area (-1) is returned. -*/ -int -#ifdef __STDC__ -tuiLastRegElementNoInLine ( - int lineNo) -#else -tuiLastRegElementNoInLine (lineNo) - int lineNo; -#endif -{ - if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <= - dataWin->detail.dataDisplayInfo.regsContentCount) - return ((lineNo + 1) * - dataWin->detail.dataDisplayInfo.regsColumnCount) - 1; - else - return (-1); -} /* tuiLastRegElementNoInLine */ - - -/* -** tuiCalculateRegsColumnCount -** Calculate the number of columns that should be used to display -** the registers. -*/ -int -#ifdef __STDC__ -tuiCalculateRegsColumnCount ( - TuiRegisterDisplayType dpyType) -#else -tuiCalculateRegsColumnCount (dpyType) - TuiRegisterDisplayType dpyType; -#endif -{ - int colCount, colWidth; - - if (IS_64BIT || dpyType == TUI_DFLOAT_REGS) - colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH; - else - { - if (dpyType == TUI_SFLOAT_REGS) - colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH; - else - colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH; - } - colCount = (dataWin->generic.width - 2) / colWidth; - - return colCount; -} /* tuiCalulateRegsColumnCount */ - - -/* -** tuiShowRegisters(). -** Show the registers int the data window as indicated by dpyType. -** If there is any other registers being displayed, then they are -** cleared. What registers are displayed is dependent upon dpyType. -*/ -void -#ifdef __STDC__ -tuiShowRegisters ( - TuiRegisterDisplayType dpyType) -#else -tuiShowRegisters (dpyType) - TuiRegisterDisplayType dpyType; -#endif -{ - TuiStatus ret = TUI_FAILURE; - int refreshValuesOnly = FALSE; - - /* Say that registers should be displayed, even if there is a problem */ - dataWin->detail.dataDisplayInfo.displayRegs = TRUE; - - if (target_has_registers) - { - refreshValuesOnly = - (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType); - switch (dpyType) - { - case TUI_GENERAL_REGS: - ret = _tuiSetGeneralRegsContent (refreshValuesOnly); - break; - case TUI_SFLOAT_REGS: - case TUI_DFLOAT_REGS: - ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly); - break; - -/* could ifdef out */ - - case TUI_SPECIAL_REGS: - ret = _tuiSetSpecialRegsContent (refreshValuesOnly); - break; - case TUI_GENERAL_AND_SPECIAL_REGS: - ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly); - break; - -/* end of potential if def */ - - default: - break; - } - } - if (ret == TUI_FAILURE) - { - dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS; - tuiEraseDataContent (NO_REGS_STRING); - } - else - { - int i; - - /* Clear all notation of changed values */ - for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++) - { - TuiGenWinInfoPtr dataItemWin; - - dataItemWin = &dataWin->detail.dataDisplayInfo. - regsContent[i]->whichElement.dataWindow; - (&((TuiWinElementPtr) - dataItemWin->content[0])->whichElement.data)->highlight = FALSE; - } - dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType; - tuiDisplayAllData (); - } - (tuiLayoutDef ())->regsDisplayType = dpyType; - - return; -} /* tuiShowRegisters */ - - -/* -** tuiDisplayRegistersFrom(). -** Function to display the registers in the content from -** 'startElementNo' until the end of the register content or the -** end of the display height. No checking for displaying past -** the end of the registers is done here. -*/ -void -#ifdef __STDC__ -tuiDisplayRegistersFrom ( - int startElementNo) -#else -tuiDisplayRegistersFrom (startElementNo) - int startElementNo; -#endif -{ - if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL && - dataWin->detail.dataDisplayInfo.regsContentCount > 0) - { - register int i = startElementNo; - int j, valueCharsWide, charsWide, itemWinWidth, curY, labelWidth; - enum precision_type precision; - - precision = (dataWin->detail.dataDisplayInfo.regsDisplayType - == TUI_DFLOAT_REGS) ? - double_precision : unspecified_precision; - if (IS_64BIT || - dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS) - { - valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH; - labelWidth = DOUBLE_FLOAT_LABEL_WIDTH; - } - else - { - if (dataWin->detail.dataDisplayInfo.regsDisplayType == - TUI_SFLOAT_REGS) - { - valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH; - labelWidth = SINGLE_FLOAT_LABEL_WIDTH; - } - else - { - valueCharsWide = SINGLE_VALUE_WIDTH; - labelWidth = SINGLE_LABEL_WIDTH; - } - } - itemWinWidth = valueCharsWide + labelWidth; - /* - ** Now create each data "sub" window, and write the display into it. - */ - curY = 1; - while (i < dataWin->detail.dataDisplayInfo.regsContentCount && - curY <= dataWin->generic.viewportHeight) - { - for (j = 0; - (j < dataWin->detail.dataDisplayInfo.regsColumnCount && - i < dataWin->detail.dataDisplayInfo.regsContentCount); j++) - { - TuiGenWinInfoPtr dataItemWin; - TuiDataElementPtr dataElementPtr; - - /* create the window if necessary*/ - dataItemWin = &dataWin->detail.dataDisplayInfo. - regsContent[i]->whichElement.dataWindow; - dataElementPtr = &((TuiWinElementPtr) - dataItemWin->content[0])->whichElement.data; - if (dataItemWin->handle == (WINDOW *) NULL) - { - dataItemWin->height = 1; - dataItemWin->width = (precision == double_precision) ? - itemWinWidth + 2 : itemWinWidth + 1; - dataItemWin->origin.x = (itemWinWidth * j) + 1; - dataItemWin->origin.y = curY; - makeWindow (dataItemWin, DONT_BOX_WINDOW); - } - /* - ** Get the printable representation of the register - ** and display it - */ - _tuiDisplayRegister ( - dataElementPtr->itemNo, dataItemWin, precision); - i++; /* next register */ - } - curY++; /* next row; */ - } - } - - return; -} /* tuiDisplayRegistersFrom */ - - -/* -** tuiDisplayRegElementAtLine(). -** Function to display the registers in the content from -** 'startElementNo' on 'startLineNo' until the end of the -** register content or the end of the display height. -** This function checks that we won't display off the end -** of the register display. -*/ -void -#ifdef __STDC__ -tuiDisplayRegElementAtLine ( - int startElementNo, - int startLineNo) -#else -tuiDisplayRegElementAtLine (startElementNo, startLineNo) - int startElementNo; - int startLineNo; -#endif -{ - if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL && - dataWin->detail.dataDisplayInfo.regsContentCount > 0) - { - register int elementNo = startElementNo; - - if (startElementNo != 0 && startLineNo != 0) - { - register int lastLineNo, firstLineOnLastPage; - - lastLineNo = tuiLastRegsLineNo (); - firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2); - if (firstLineOnLastPage < 0) - firstLineOnLastPage = 0; - /* - ** If there is no other data displayed except registers, - ** and the elementNo causes us to scroll past the end of the - ** registers, adjust what element to really start the display at. - */ - if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 && - startLineNo > firstLineOnLastPage) - elementNo = tuiFirstRegElementNoInLine (firstLineOnLastPage); - } - tuiDisplayRegistersFrom (elementNo); - } - - return; -} /* tuiDisplayRegElementAtLine */ - - - -/* -** tuiDisplayRegistersFromLine(). -** Function to display the registers starting at line lineNo in -** the data window. Answers the line number that the display -** actually started from. If nothing is displayed (-1) is returned. -*/ -int -#ifdef __STDC__ -tuiDisplayRegistersFromLine ( - int lineNo, - int forceDisplay) -#else -tuiDisplayRegistersFromLine (lineNo, forceDisplay) - int lineNo; - int forceDisplay; -#endif -{ - int elementNo; - - if (dataWin->detail.dataDisplayInfo.regsContentCount > 0) - { - int line, elementNo; - - if (lineNo < 0) - line = 0; - else if (forceDisplay) - { /* - ** If we must display regs (forceDisplay is true), then make - ** sure that we don't display off the end of the registers. - */ - if (lineNo >= tuiLastRegsLineNo ()) - { - if ((line = tuiLineFromRegElementNo ( - dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0) - line = 0; - } - else - line = lineNo; - } - else - line = lineNo; - - elementNo = tuiFirstRegElementNoInLine (line); - if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount) - tuiDisplayRegElementAtLine (elementNo, line); - else - line = (-1); - - return line; - } - - return (-1); /* nothing was displayed */ -} /* tuiDisplayRegistersFromLine */ - - -/* -** tuiCheckRegisterValues() -** This function check all displayed registers for changes in -** values, given a particular frame. If the values have changed, -** they are updated with the new value and highlighted. -*/ -void -#ifdef __STDC__ -tuiCheckRegisterValues ( - struct frame_info *frame) -#else -tuiCheckRegisterValues (frame) - struct frame_info *frame; -#endif -{ - if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) - { - if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 && - dataWin->detail.dataDisplayInfo.displayRegs) - tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType); - else - { - int i, j; - char rawBuf[MAX_REGISTER_RAW_SIZE]; - - for (i = 0; - (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++) - { - TuiDataElementPtr dataElementPtr; - TuiGenWinInfoPtr dataItemWinPtr; - int wasHilighted; - - dataItemWinPtr = &dataWin->detail.dataDisplayInfo. - regsContent[i]->whichElement.dataWindow; - dataElementPtr = &((TuiWinElementPtr) - dataItemWinPtr->content[0])->whichElement.data; - wasHilighted = dataElementPtr->highlight; - dataElementPtr->highlight = - _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]); - if (dataElementPtr->highlight) - { - for (j = 0; j < MAX_REGISTER_RAW_SIZE; j++) - ((char *) dataElementPtr->value)[j] = rawBuf[j]; - _tuiDisplayRegister ( - dataElementPtr->itemNo, - dataItemWinPtr, - ((dataWin->detail.dataDisplayInfo.regsDisplayType == - TUI_DFLOAT_REGS) ? - double_precision : unspecified_precision)); - } - else if (wasHilighted) - { - dataElementPtr->highlight = FALSE; - _tuiDisplayRegister ( - dataElementPtr->itemNo, - dataItemWinPtr, - ((dataWin->detail.dataDisplayInfo.regsDisplayType == - TUI_DFLOAT_REGS) ? - double_precision : unspecified_precision)); - } - } - } - } - return; -} /* tuiCheckRegisterValues */ - - -/* -** tuiToggleFloatRegs(). -*/ -void -#ifdef __STDC__ -tuiToggleFloatRegs (void) -#else -tuiToggleFloatRegs () -#endif -{ - TuiLayoutDefPtr layoutDef = tuiLayoutDef (); - - if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS) - layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS; - else - layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS; - - if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible && - (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS || - dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)) - tuiShowRegisters (layoutDef->floatRegsDisplayType); - - return; -} /* tuiToggleFloatRegs */ - - -void -_initialize_tuiRegs () -{ - if (tui_version && xdb_commands) - { - add_com ("fr", class_tui, _tuiShowFloat_command, - "Display only floating point registers\n"); - add_com ("gr", class_tui, _tuiShowGeneral_command, - "Display only general registers\n"); - add_com ("sr", class_tui, _tuiShowSpecial_command, - "Display only special registers\n"); - add_com ("+r", class_tui, _tuiScrollRegsForward_command, - "Scroll the registers window forward\n"); - add_com ("-r", class_tui, _tuiScrollRegsBackward_command, - "Scroll the register window backward\n"); - add_com ("tf", class_tui, _tuiToggleFloatRegs_command, - "Toggle between single and double precision floating point registers.\n"); - add_cmd (TUI_FLOAT_REGS_NAME_LOWER, - class_tui, - _tuiToggleFloatRegs_command, - "Toggle between single and double precision floating point \ -registers.\n", - &togglelist); - } - - return; -} /* _initialize_tuiRegs */ - - -/***************************************** -** STATIC LOCAL FUNCTIONS ** -******************************************/ - - -/* -** _tuiRegisterName(). -** Return the register name. -*/ -static char * -#ifdef __STDC__ -_tuiRegisterName ( - int regNum) -#else -_tuiRegisterName (regNum) - int regNum; -#endif -{ - if (reg_names[regNum] != (char *) NULL && *(reg_names[regNum]) != (char) 0) - return reg_names[regNum]; - else - return ((char *) NULL); -} /* tuiGetRegisterName */ - - -/* -** _tuiRegisterFormat -** Function to format the register name and value into a buffer, -** suitable for printing or display -*/ -static void -#ifdef __STDC__ -_tuiRegisterFormat ( - char *buf, - int bufLen, - int regNum, - TuiDataElementPtr dataElement, - enum precision_type precision) -#else -_tuiRegisterFormat (buf, bufLen, regNum, dataElement, precision) - char *buf; - int bufLen; - int regNum; - TuiDataElementPtr dataElement; - enum precision_type precision; -#endif -{ - char tmpBuf[15]; - char *fmt; - GDB_FILE *stream; - - stream = gdb_file_init_astring(bufLen); - pa_do_strcat_registers_info (regNum, 0, stream, precision); - strcpy (buf, gdb_file_get_strbuf(stream)); - gdb_file_deallocate(&stream); - - return; -} /* _tuiRegisterFormat */ - - -#define NUM_GENERAL_REGS 32 -/* -** _tuiSetGeneralRegsContent(). -** Set the content of the data window to consist of the general registers. -*/ -static TuiStatus -#ifdef __STDC__ -_tuiSetGeneralRegsContent ( - int refreshValuesOnly) -#else -_tuiSetGeneralRegsContent (refreshValuesOnly) - int refreshValuesOnly; -#endif -{ - return (_tuiSetRegsContent (0, - NUM_GENERAL_REGS - 1, - selected_frame, - TUI_GENERAL_REGS, - refreshValuesOnly)); - -} /* _tuiSetGeneralRegsContent */ - - -#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM -/* -** _tuiSetSpecialRegsContent(). -** Set the content of the data window to consist of the special registers. -*/ -static TuiStatus -#ifdef __STDC__ -_tuiSetSpecialRegsContent ( - int refreshValuesOnly) -#else -_tuiSetSpecialRegsContent (refreshValuesOnly) - int refreshValuesOnly; -#endif -{ - TuiStatus ret = TUI_FAILURE; - int i, endRegNum; - - endRegNum = FP0_REGNUM - 1; -#if 0 - endRegNum = (-1); - for (i = START_SPECIAL_REGS; (i < ARCH_NUM_REGS && endRegNum < 0); i++) - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT) - endRegNum = i - 1; -#endif - ret = _tuiSetRegsContent (START_SPECIAL_REGS, - endRegNum, - selected_frame, - TUI_SPECIAL_REGS, - refreshValuesOnly); - - return ret; -} /* _tuiSetSpecialRegsContent */ - - -/* -** _tuiSetGeneralAndSpecialRegsContent(). -** Set the content of the data window to consist of the special registers. -*/ -static TuiStatus -#ifdef __STDC__ -_tuiSetGeneralAndSpecialRegsContent ( - int refreshValuesOnly) -#else -_tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly) - int refreshValuesOnly; -#endif -{ - TuiStatus ret = TUI_FAILURE; - int i, endRegNum = (-1); - - endRegNum = FP0_REGNUM - 1; -#if 0 - endRegNum = (-1); - for (i = 0; (i < ARCH_NUM_REGS && endRegNum < 0); i++) - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT) - endRegNum = i - 1; -#endif - ret = _tuiSetRegsContent ( - 0, endRegNum, selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly); - - return ret; -} /* _tuiSetGeneralAndSpecialRegsContent */ - -/* -** _tuiSetFloatRegsContent(). -** Set the content of the data window to consist of the float registers. -*/ -static TuiStatus -#ifdef __STDC__ -_tuiSetFloatRegsContent ( - TuiRegisterDisplayType dpyType, - int refreshValuesOnly) -#else -_tuiSetFloatRegsContent (dpyType, refreshValuesOnly) - TuiRegisterDisplayType dpyType; - int refreshValuesOnly; -#endif -{ - TuiStatus ret = TUI_FAILURE; - int i, startRegNum; - - startRegNum = FP0_REGNUM; -#if 0 - startRegNum = (-1); - for (i = ARCH_NUM_REGS - 1; (i >= 0 && startRegNum < 0); i--) - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) != TYPE_CODE_FLT) - startRegNum = i + 1; -#endif - ret = _tuiSetRegsContent (startRegNum, - ARCH_NUM_REGS - 1, - selected_frame, - dpyType, - refreshValuesOnly); - - return ret; -} /* _tuiSetFloatRegsContent */ - - -/* -** _tuiRegValueHasChanged(). -** Answer TRUE if the register's value has changed, FALSE otherwise. -** If TRUE, newValue is filled in with the new value. -*/ -static int -#ifdef __STDC__ -_tuiRegValueHasChanged ( - TuiDataElementPtr dataElement, - struct frame_info *frame, - char *newValue) -#else -_tuiRegValueHasChanged (dataElement, frame, newValue) - TuiDataElementPtr dataElement; - struct frame_info *frame; - char *newValue; -#endif -{ - int hasChanged = FALSE; - - if (dataElement->itemNo != UNDEFINED_ITEM && - _tuiRegisterName (dataElement->itemNo) != (char *) NULL) - { - char rawBuf[MAX_REGISTER_RAW_SIZE]; - int i; - - if (_tuiGetRegisterRawValue ( - dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS) - { - for (i = 0; (i < MAX_REGISTER_RAW_SIZE && !hasChanged); i++) - hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]); - if (hasChanged && newValue != (char *) NULL) - { - for (i = 0; (i < MAX_REGISTER_RAW_SIZE); i++) - newValue[i] = rawBuf[i]; - } - } - } - return hasChanged; -} /* _tuiRegValueHasChanged */ - - - -/* -** _tuiGetRegisterRawValue(). -** Get the register raw value. The raw value is returned in regValue. -*/ -static TuiStatus -#ifdef __STDC__ -_tuiGetRegisterRawValue ( - int regNum, - char *regValue, - struct frame_info *frame) -#else -_tuiGetRegisterRawValue (regNum, regValue, frame) - int regNum; - char *regValue; - struct frame_info *frame; -#endif -{ - TuiStatus ret = TUI_FAILURE; - - if (target_has_registers) - { - read_relative_register_raw_bytes_for_frame (regNum, regValue, frame); - ret = TUI_SUCCESS; - } - - return ret; -} /* _tuiGetRegisterRawValue */ - - - -/* -** _tuiSetRegisterElement(). -** Function to initialize a data element with the input and -** the register value. -*/ -static void -#ifdef __STDC__ -_tuiSetRegisterElement ( - int regNum, - struct frame_info *frame, - TuiDataElementPtr dataElement, - int refreshValueOnly) -#else -_tuiSetRegisterElement (regNum, frame, dataElement, refreshValueOnly) - int regNum; - struct frame_info *frame; - TuiDataElementPtr dataElement; - int refreshValueOnly; -#endif -{ - if (dataElement != (TuiDataElementPtr) NULL) - { - if (!refreshValueOnly) - { - dataElement->itemNo = regNum; - dataElement->name = _tuiRegisterName (regNum); - dataElement->highlight = FALSE; - } - if (dataElement->value == (Opaque) NULL) - dataElement->value = (Opaque) xmalloc (MAX_REGISTER_RAW_SIZE); - if (dataElement->value != (Opaque) NULL) - _tuiGetRegisterRawValue (regNum, dataElement->value, frame); - } - - return; -} /* _tuiSetRegisterElement */ - - -/* -** _tuiSetRegsContent(). -** Set the content of the data window to consist of the registers -** numbered from startRegNum to endRegNum. Note that if -** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored. -*/ -static TuiStatus -#ifdef __STDC__ -_tuiSetRegsContent ( - int startRegNum, - int endRegNum, - struct frame_info *frame, - TuiRegisterDisplayType dpyType, - int refreshValuesOnly) -#else -_tuiSetRegsContent (startRegNum, endRegNum, frame, dpyType, refreshValuesOnly) - int startRegNum; - int endRegNum; - struct frame_info *frame; - TuiRegisterDisplayType dpyType; - int refreshValuesOnly; -#endif -{ - TuiStatus ret = TUI_FAILURE; - int numRegs = endRegNum - startRegNum + 1; - int allocatedHere = FALSE; - - if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 && - !refreshValuesOnly) - { - freeDataContent (dataWin->detail.dataDisplayInfo.regsContent, - dataWin->detail.dataDisplayInfo.regsContentCount); - dataWin->detail.dataDisplayInfo.regsContentCount = 0; - } - if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0) - { - dataWin->detail.dataDisplayInfo.regsContent = - allocContent (numRegs, DATA_WIN); - allocatedHere = TRUE; - } - - if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL) - { - int i; - - if (!refreshValuesOnly || allocatedHere) - { - dataWin->generic.content = (OpaquePtr) NULL; - dataWin->generic.contentSize = 0; - addContentElements (&dataWin->generic, numRegs); - dataWin->detail.dataDisplayInfo.regsContent = - (TuiWinContent) dataWin->generic.content; - dataWin->detail.dataDisplayInfo.regsContentCount = numRegs; - } - /* - ** Now set the register names and values - */ - for (i = startRegNum; (i <= endRegNum); i++) - { - TuiGenWinInfoPtr dataItemWin; - - dataItemWin = &dataWin->detail.dataDisplayInfo. - regsContent[i - startRegNum]->whichElement.dataWindow; - _tuiSetRegisterElement ( - i, - frame, - &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data, - !allocatedHere && refreshValuesOnly); - } - dataWin->detail.dataDisplayInfo.regsColumnCount = - tuiCalculateRegsColumnCount (dpyType); -#ifdef LATER - if (dataWin->detail.dataDisplayInfo.dataContentCount > 0) - { - /* delete all the windows? */ - /* realloc content equal to dataContentCount + regsContentCount */ - /* append dataWin->detail.dataDisplayInfo.dataContent to content */ - } -#endif - dataWin->generic.contentSize = - dataWin->detail.dataDisplayInfo.regsContentCount + - dataWin->detail.dataDisplayInfo.dataContentCount; - ret = TUI_SUCCESS; - } - - return ret; -} /* _tuiSetRegsContent */ - - -/* -** _tuiDisplayRegister(). -** Function to display a register in a window. If hilite is TRUE, -** than the value will be displayed in reverse video -*/ -static void -#ifdef __STDC__ -_tuiDisplayRegister ( - int regNum, - TuiGenWinInfoPtr winInfo, /* the data item window */ - enum precision_type precision) -#else -_tuiDisplayRegister (regNum, winInfo, precision) - int regNum; - TuiGenWinInfoPtr winInfo; /* the data item window */ - enum precision_type precision; -#endif -{ - if (winInfo->handle != (WINDOW *) NULL) - { - char buf[100]; - int valueCharsWide, labelWidth; - TuiDataElementPtr dataElementPtr = &((TuiWinContent) - winInfo->content)[0]->whichElement.data; - - if (IS_64BIT || - dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS) - { - valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH; - labelWidth = DOUBLE_FLOAT_LABEL_WIDTH; - } - else - { - if (dataWin->detail.dataDisplayInfo.regsDisplayType == - TUI_SFLOAT_REGS) - { - valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH; - labelWidth = SINGLE_FLOAT_LABEL_WIDTH; - } - else - { - valueCharsWide = SINGLE_VALUE_WIDTH; - labelWidth = SINGLE_LABEL_WIDTH; - } - } - - buf[0] = (char) 0; - _tuiRegisterFormat (buf, - valueCharsWide + labelWidth, - regNum, - dataElementPtr, - precision); - if (dataElementPtr->highlight) - wstandout (winInfo->handle); - - werase (winInfo->handle); - wmove (winInfo->handle, 0, 0); - waddstr (winInfo->handle, buf); - - if (dataElementPtr->highlight) - wstandend (winInfo->handle); - tuiRefreshWin (winInfo); - } - return; -} /* _tuiDisplayRegister */ - - -static void -#ifdef __STDC__ -_tui_vShowRegisters_commandSupport ( - va_list args) -#else -_tui_vShowRegisters_commandSupport (args) - va_list args; -#endif -{ - TuiRegisterDisplayType dpyType = va_arg (args, TuiRegisterDisplayType); - - if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) - { /* Data window already displayed, show the registers */ - if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType) - tuiShowRegisters (dpyType); - } - else - (tuiLayoutDef ())->regsDisplayType = dpyType; - - return; -} /* _tui_vShowRegisters_commandSupport */ - - -static void -#ifdef __STDC__ -_tuiShowFloat_command ( - char *arg, - int fromTTY) -#else -_tuiShowFloat_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible || - (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS && - dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS)) - tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport, - (tuiLayoutDef ())->floatRegsDisplayType); - - return; -} /* _tuiShowFloat_command */ - - -static void -#ifdef __STDC__ -_tuiShowGeneral_command ( - char *arg, - int fromTTY) -#else -_tuiShowGeneral_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport, - TUI_GENERAL_REGS); - - return; -} /* _tuiShowGeneral_command */ - - -static void -#ifdef __STDC__ -_tuiShowSpecial_command ( - char *arg, - int fromTTY) -#else -_tuiShowSpecial_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport, - TUI_SPECIAL_REGS); - - return; -} /* _tuiShowSpecial_command */ - - -static void -#ifdef __STDC__ -_tuiToggleFloatRegs_command ( - char *arg, - int fromTTY) -#else -_tuiToggleFloatRegs_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible) - tuiDo ((TuiOpaqueFuncPtr) tuiToggleFloatRegs); - else - { - TuiLayoutDefPtr layoutDef = tuiLayoutDef (); - - if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS) - layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS; - else - layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS; - } - - - return; -} /* _tuiToggleFloatRegs_command */ - - -static void -#ifdef __STDC__ -_tuiScrollRegsForward_command ( - char *arg, - int fromTTY) -#else -_tuiScrollRegsForward_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, FORWARD_SCROLL, dataWin, 1); - - return; -} /* _tuiScrollRegsForward_command */ - - -static void -#ifdef __STDC__ -_tuiScrollRegsBackward_command ( - char *arg, - int fromTTY) -#else -_tuiScrollRegsBackward_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, BACKWARD_SCROLL, dataWin, 1); - - return; -} /* _tuiScrollRegsBackward_command */ diff --git a/contrib/gdb/gdb/tui/tuiRegs.h b/contrib/gdb/gdb/tui/tuiRegs.h deleted file mode 100644 index 4a777ec9a9b..00000000000 --- a/contrib/gdb/gdb/tui/tuiRegs.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _TUI_REGS_H -#define _TUI_REGS_H -/* -** This header file supports the display of registers in the data window. -*/ - -/***************************************** -** TYPE DEFINITIONS ** -******************************************/ - - - -/***************************************** -** PUBLIC FUNCTION EXTERNAL DECLS ** -******************************************/ -extern void tuiCheckRegisterValues PARAMS ((struct frame_info *)); -extern void tuiShowRegisters PARAMS ((TuiRegisterDisplayType)); -extern void tuiDisplayRegistersFrom PARAMS ((int)); -extern int tuiDisplayRegistersFromLine PARAMS ((int, int)); -extern int tuiLastRegsLineNo PARAMS ((void)); -extern int tuiFirstRegElementInLine PARAMS ((int)); -extern int tuiLastRegElementInLine PARAMS ((int)); -extern int tuiLineFromRegElementNo PARAMS ((int)); -extern void tuiToggleFloatRegs PARAMS ((void)); -extern int tuiCalculateRegsColumnCount PARAMS ((TuiRegisterDisplayType)); - - -#endif /*_TUI_REGS_H*/ diff --git a/contrib/gdb/gdb/tui/tuiSource.c b/contrib/gdb/gdb/tui/tuiSource.c deleted file mode 100644 index e0259d014b4..00000000000 --- a/contrib/gdb/gdb/tui/tuiSource.c +++ /dev/null @@ -1,465 +0,0 @@ -/* -** tuiSource.c -** This module contains functions for displaying source in the source window -*/ - -#include "defs.h" -#include -#include "symtab.h" -#include "frame.h" -#include "breakpoint.h" - -#include "tui.h" -#include "tuiData.h" -#include "tuiStack.h" -#include "tuiSourceWin.h" -#include "tuiSource.h" - - -/***************************************** -** EXTERNAL FUNCTION DECLS ** -******************************************/ - -extern int open_source_file PARAMS ((struct symtab *)); -extern void find_source_lines PARAMS ((struct symtab *, int)); - -/***************************************** -** EXTERNAL DATA DECLS ** -******************************************/ -extern int current_source_line; -extern struct symtab *current_source_symtab; - - -/***************************************** -** STATIC LOCAL FUNCTIONS FORWARD DECLS ** -******************************************/ - -static struct breakpoint *_hasBreak PARAMS ((char *, int)); - - -/***************************************** -** STATIC LOCAL DATA ** -******************************************/ - - -/***************************************** -** PUBLIC FUNCTIONS ** -******************************************/ - -/********************************* -** SOURCE/DISASSEM FUNCTIONS ** -*********************************/ - -/* -** tuiSetSourceContent(). -** Function to display source in the source window. -*/ -TuiStatus -#ifdef __STDC__ -tuiSetSourceContent ( - struct symtab *s, - int lineNo, - int noerror) -#else -tuiSetSourceContent (s, lineNo, noerror) - struct symtab *s; - int lineNo; - int noerror; -#endif -{ - TuiStatus ret = TUI_FAILURE; - - if (s != (struct symtab *) NULL && s->filename != (char *) NULL) - { - register FILE *stream; - register int i, desc, c, lineWidth, nlines; - register char *srcLine; - - if ((ret = tuiAllocSourceBuffer (srcWin)) == TUI_SUCCESS) - { - lineWidth = srcWin->generic.width - 1; - /* - ** Take hilite (window border) into account, when calculating - ** the number of lines - */ - nlines = (lineNo + (srcWin->generic.height - 2)) - lineNo; - desc = open_source_file (s); - if (desc < 0) - { - if (!noerror) - { - char *name = alloca (strlen (s->filename) + 100); - sprintf (name, "%s:%d", s->filename, lineNo); - print_sys_errmsg (name, errno); - } - ret = TUI_FAILURE; - } - else - { - if (s->line_charpos == 0) - find_source_lines (s, desc); - - if (lineNo < 1 || lineNo > s->nlines) - { - close (desc); - printf_unfiltered ( - "Line number %d out of range; %s has %d lines.\n", - lineNo, s->filename, s->nlines); - } - else if (lseek (desc, s->line_charpos[lineNo - 1], 0) < 0) - { - close (desc); - perror_with_name (s->filename); - } - else - { - register int offset, curLineNo, curLine, curLen, threshold; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - /* - ** Determine the threshold for the length of the line - ** and the offset to start the display - */ - offset = srcWin->detail.sourceInfo.horizontalOffset; - threshold = (lineWidth - 1) + offset; - stream = fdopen (desc, FOPEN_RT); - clearerr (stream); - curLine = 0; - curLineNo = - srcWin->detail.sourceInfo.startLineOrAddr.lineNo = lineNo; - if (offset > 0) - srcLine = (char *) xmalloc ( - (threshold + 1) * sizeof (char)); - while (curLine < nlines) - { - TuiWinElementPtr element = (TuiWinElementPtr) - srcWin->generic.content[curLine]; - struct breakpoint *bp; - - /* get the first character in the line */ - c = fgetc (stream); - - if (offset == 0) - srcLine = ((TuiWinElementPtr) - srcWin->generic.content[ - curLine])->whichElement.source.line; - /* Init the line with the line number */ - sprintf (srcLine, "%-6d", curLineNo); - curLen = strlen (srcLine); - i = curLen - - ((curLen / tuiDefaultTabLen ()) * tuiDefaultTabLen ()); - while (i < tuiDefaultTabLen ()) - { - srcLine[curLen] = ' '; - i++; - curLen++; - } - srcLine[curLen] = (char) 0; - - /* - ** Set whether element is the execution point and - ** whether there is a break point on it. - */ - element->whichElement.source.lineOrAddr.lineNo = - curLineNo; - element->whichElement.source.isExecPoint = - (strcmp (((TuiWinElementPtr) - locator->content[0])->whichElement.locator.fileName, - s->filename) == 0 - && curLineNo == ((TuiWinElementPtr) - locator->content[0])->whichElement.locator.lineNo); - bp = _hasBreak (s->filename, curLineNo); - element->whichElement.source.hasBreak = - (bp != (struct breakpoint *) NULL && - (!element->whichElement.source.isExecPoint || - (bp->disposition != del || bp->hit_count <= 0))); - if (c != EOF) - { - i = strlen (srcLine) - 1; - do - { - if ((c != '\n') && - (c != '\r') && (++i < threshold)) - { - if (c < 040 && c != '\t') - { - srcLine[i++] = '^'; - srcLine[i] = c + 0100; - } - else if (c == 0177) - { - srcLine[i++] = '^'; - srcLine[i] = '?'; - } - else - { /* - ** Store the charcter in the line - ** buffer. If it is a tab, then - ** translate to the correct number of - ** chars so we don't overwrite our - ** buffer. - */ - if (c == '\t') - { - int j, maxTabLen = tuiDefaultTabLen (); - - for (j = i - ( - (i / maxTabLen) * maxTabLen); - ((j < maxTabLen) && - i < threshold); - i++, j++) - srcLine[i] = ' '; - i--; - } - else - srcLine[i] = c; - } - srcLine[i + 1] = 0; - } - else - { /* - ** if we have not reached EOL, then eat - ** chars until we do - */ - while (c != EOF && c != '\n' && c != '\r') - c = fgetc (stream); - } - } - while (c != EOF && c != '\n' && c != '\r' && - i < threshold && (c = fgetc (stream))); - } - /* Now copy the line taking the offset into account */ - if (strlen (srcLine) > offset) - strcpy (((TuiWinElementPtr) srcWin->generic.content[ - curLine])->whichElement.source.line, - &srcLine[offset]); - else - ((TuiWinElementPtr) - srcWin->generic.content[ - curLine])->whichElement.source.line[0] = (char) 0; - curLine++; - curLineNo++; - } - if (offset > 0) - tuiFree (srcLine); - fclose (stream); - srcWin->generic.contentSize = nlines; - ret = TUI_SUCCESS; - } - } - } - } - return ret; -} /* tuiSetSourceContent */ - - -/* elz: this function sets the contents of the source window to empty - except for a line in the middle with a warning message about the - source not being available. This function is called by - tuiEraseSourceContents, which in turn is invoked when the source files - cannot be accessed*/ - -void -#ifdef __STDC__ -tuiSetSourceContentNil ( - TuiWinInfoPtr winInfo, - char *warning_string) -#else -tuiSetSourceContentNil (winInfo, warning_string) - TuiWinInfoPtr winInfo; - char *warning_string; -#endif -{ - int lineWidth; - int nLines; - int curr_line = 0; - - lineWidth = winInfo->generic.width - 1; - nLines = winInfo->generic.height - 2; - - /* set to empty each line in the window, except for the one - which contains the message*/ - while (curr_line < winInfo->generic.contentSize) - { - /* set the information related to each displayed line - to null: i.e. the line number is 0, there is no bp, - it is not where the program is stopped */ - - TuiWinElementPtr element = - (TuiWinElementPtr) winInfo->generic.content[curr_line]; - element->whichElement.source.lineOrAddr.lineNo = 0; - element->whichElement.source.isExecPoint = FALSE; - element->whichElement.source.hasBreak = FALSE; - - /* set the contents of the line to blank*/ - element->whichElement.source.line[0] = (char) 0; - - /* if the current line is in the middle of the screen, then we want to - display the 'no source available' message in it. - Note: the 'weird' arithmetic with the line width and height comes from - the function tuiEraseSourceContent. We need to keep the screen and the - window's actual contents in synch */ - - if (curr_line == (nLines / 2 + 1)) - { - int i; - int xpos; - int warning_length = strlen (warning_string); - char *srcLine; - - srcLine = element->whichElement.source.line; - - if (warning_length >= ((lineWidth - 1) / 2)) - xpos = 1; - else - xpos = (lineWidth - 1) / 2 - warning_length; - - for (i = 0; i < xpos; i++) - srcLine[i] = ' '; - - sprintf (srcLine + i, "%s", warning_string); - - for (i = xpos + warning_length; i < lineWidth; i++) - srcLine[i] = ' '; - - srcLine[i] = '\n'; - - } /* end if */ - - curr_line++; - - } /* end while*/ - -} /*tuiSetSourceContentNil*/ - - - - -/* -** tuiShowSource(). -** Function to display source in the source window. This function -** initializes the horizontal scroll to 0. -*/ -void -#ifdef __STDC__ -tuiShowSource ( - struct symtab *s, - Opaque line, - int noerror) -#else -tuiShowSource (s, line, noerror) - struct symtab *s; - Opaque line; - int noerror; -#endif -{ - srcWin->detail.sourceInfo.horizontalOffset = 0; - m_tuiShowSourceAsIs (s, line, noerror); - - return; -} /* tuiShowSource */ - - -/* -** tuiSourceIsDisplayed(). -** Answer whether the source is currently displayed in the source window. -*/ -int -#ifdef __STDC__ -tuiSourceIsDisplayed ( - char *fname) -#else -tuiSourceIsDisplayed (fname) - char *fname; -#endif -{ - return (srcWin->generic.contentInUse && - (strcmp (((TuiWinElementPtr) (locatorWinInfoPtr ())-> - content[0])->whichElement.locator.fileName, fname) == 0)); -} /* tuiSourceIsDisplayed */ - - -/* -** tuiVerticalSourceScroll(). -** Scroll the source forward or backward vertically -*/ -void -#ifdef __STDC__ -tuiVerticalSourceScroll ( - TuiScrollDirection scrollDirection, - int numToScroll) -#else -tuiVerticalSourceScroll (scrollDirection, numToScroll) - TuiScrollDirection scrollDirection; - int numToScroll; -#endif -{ - if (srcWin->generic.content != (OpaquePtr) NULL) - { - int line; - Opaque addr; - struct symtab *s; - TuiWinContent content = (TuiWinContent) srcWin->generic.content; - - if (current_source_symtab == (struct symtab *) NULL) - s = find_pc_symtab (selected_frame->pc); - else - s = current_source_symtab; - - if (scrollDirection == FORWARD_SCROLL) - { - line = content[0]->whichElement.source.lineOrAddr.lineNo + - numToScroll; - if (line > s->nlines) - /*line = s->nlines - winInfo->generic.contentSize + 1;*/ - /*elz: fix for dts 23398*/ - line = content[0]->whichElement.source.lineOrAddr.lineNo; - } - else - { - line = content[0]->whichElement.source.lineOrAddr.lineNo - - numToScroll; - if (line <= 0) - line = 1; - } - tuiUpdateSourceWindowAsIs (srcWin, s, (Opaque) line, FALSE); - } - - return; -} /* tuiVerticalSourceScroll */ - - -/***************************************** -** STATIC LOCAL FUNCTIONS ** -******************************************/ - -/* -** _hasBreak(). -** Answer whether there is a break point at the input line in -** the source file indicated -*/ -static struct breakpoint * -#ifdef __STDC__ -_hasBreak ( - char *sourceFileName, - int lineNo) -#else -_hasBreak (sourceFileName, lineNo) - char *sourceFileName; - int lineNo; -#endif -{ - struct breakpoint *bpWithBreak = (struct breakpoint *) NULL; - struct breakpoint *bp; - extern struct breakpoint *breakpoint_chain; - - - for (bp = breakpoint_chain; - (bp != (struct breakpoint *) NULL && - bpWithBreak == (struct breakpoint *) NULL); - bp = bp->next) - if ((strcmp (sourceFileName, bp->source_file) == 0) && - (lineNo == bp->line_number)) - bpWithBreak = bp; - - return bpWithBreak; -} /* _hasBreak */ diff --git a/contrib/gdb/gdb/tui/tuiSource.h b/contrib/gdb/gdb/tui/tuiSource.h deleted file mode 100644 index f898c611c71..00000000000 --- a/contrib/gdb/gdb/tui/tuiSource.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _TUI_SOURCE_H -#define _TUI_SOURCE_H -/* -** This header file supports -*/ - - -#include "defs.h" -#if 0 -#include "symtab.h" -#include "breakpoint.h" -#endif - -extern TuiStatus tuiSetSourceContent PARAMS ((struct symtab *, int, int)); -extern void tuiShowSource PARAMS ((struct symtab *, Opaque, int)); -extern void tuiShowSourceAsIs PARAMS ((struct symtab *, Opaque, int)); -extern int tuiSourceIsDisplayed PARAMS ((char *)); -extern void tuiVerticalSourceScroll PARAMS ((TuiScrollDirection, int)); - - -/******************* -** MACROS ** -*******************/ -#define m_tuiShowSourceAsIs(s, line, noerror) tuiUpdateSourceWindowAsIs(srcWin, s, line, noerror) - - -#endif /*_TUI_SOURCE_H*/ diff --git a/contrib/gdb/gdb/tui/tuiSourceWin.c b/contrib/gdb/gdb/tui/tuiSourceWin.c deleted file mode 100644 index e20392598ad..00000000000 --- a/contrib/gdb/gdb/tui/tuiSourceWin.c +++ /dev/null @@ -1,1098 +0,0 @@ -/* -** tuiSourceWin.c -** This module contains functions for displaying source or assembly in the "source" window. -* The "source" window may be the assembly or the source windows. -*/ - -#include "defs.h" -#include -#include "symtab.h" -#include "frame.h" -#include "breakpoint.h" - -#include "tui.h" -#include "tuiData.h" -#include "tuiStack.h" -#include "tuiSourceWin.h" -#include "tuiSource.h" -#include "tuiDisassem.h" - - -/***************************************** -** EXTERNAL FUNCTION DECLS ** -******************************************/ - -/***************************************** -** EXTERNAL DATA DECLS ** -******************************************/ -extern int current_source_line; -extern struct symtab *current_source_symtab; - - -/***************************************** -** STATIC LOCAL FUNCTIONS FORWARD DECLS ** -******************************************/ - -/***************************************** -** STATIC LOCAL DATA ** -******************************************/ - - -/***************************************** -** PUBLIC FUNCTIONS ** -******************************************/ - -/********************************* -** SOURCE/DISASSEM FUNCTIONS ** -*********************************/ - -/* -** tuiSrcWinIsDisplayed(). -*/ -int -#ifdef __STDC__ -tuiSrcWinIsDisplayed (void) -#else -tuiSrcWinIsDisplayed () -#endif -{ - return (m_winPtrNotNull (srcWin) && srcWin->generic.isVisible); -} /* tuiSrcWinIsDisplayed */ - - -/* -** tuiAsmWinIsDisplayed(). -*/ -int -#ifdef __STDC__ -tuiAsmWinIsDisplayed (void) -#else -tuiAsmWinIsDisplayed () -#endif -{ - return (m_winPtrNotNull (disassemWin) && disassemWin->generic.isVisible); -} /* tuiAsmWinIsDisplayed */ - - -/* -** tuiDisplayMainFunction(). -** Function to display the "main" routine" -*/ -void -#ifdef __STDC__ -tuiDisplayMainFunction (void) -#else -tuiDisplayMainFunction () -#endif -{ - if ((sourceWindows ())->count > 0) - { - CORE_ADDR addr; - - addr = parse_and_eval_address ("main"); - if (addr <= (CORE_ADDR) 0) - addr = parse_and_eval_address ("MAIN"); - if (addr > (CORE_ADDR) 0) - { - struct symtab_and_line sal; - - tuiUpdateSourceWindowsWithAddr ((Opaque) addr); - sal = find_pc_line (addr, 0); - tuiSwitchFilename (sal.symtab->filename); - } - } - - return; -} /* tuiDisplayMainFunction */ - - - -/* -** tuiUpdateSourceWindow(). -** Function to display source in the source window. This function -** initializes the horizontal scroll to 0. -*/ -void -#ifdef __STDC__ -tuiUpdateSourceWindow ( - TuiWinInfoPtr winInfo, - struct symtab *s, - Opaque lineOrAddr, - int noerror) -#else -tuiUpdateSourceWindow (winInfo, s, lineOrAddr, noerror) - TuiWinInfoPtr winInfo; - struct symtab *s; - Opaque lineOrAddr; - int noerror; -#endif -{ - winInfo->detail.sourceInfo.horizontalOffset = 0; - tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror); - - return; -} /* tuiUpdateSourceWindow */ - - -/* -** tuiUpdateSourceWindowAsIs(). -** Function to display source in the source/asm window. This -** function shows the source as specified by the horizontal offset. -*/ -void -#ifdef __STDC__ -tuiUpdateSourceWindowAsIs ( - TuiWinInfoPtr winInfo, - struct symtab *s, - Opaque lineOrAddr, - int noerror) -#else -tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror) - TuiWinInfoPtr winInfo; - struct symtab *s; - Opaque lineOrAddr; - int noerror; -#endif -{ - TuiStatus ret; - - if (winInfo->generic.type == SRC_WIN) - ret = tuiSetSourceContent (s, (int) lineOrAddr, noerror); - else - ret = tuiSetDisassemContent (s, (Opaque) lineOrAddr); - - if (ret == TUI_FAILURE) - { - tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); - tuiClearExecInfoContent (winInfo); - } - else - { - tuiEraseSourceContent (winInfo, NO_EMPTY_SOURCE_PROMPT); - tuiShowSourceContent (winInfo); - tuiUpdateExecInfo (winInfo); - if (winInfo->generic.type == SRC_WIN) - { - current_source_line = (int) lineOrAddr + - (winInfo->generic.contentSize - 2); - current_source_symtab = s; - /* - ** If the focus was in the asm win, put it in the src - ** win if we don't have a split layout - */ - if (tuiWinWithFocus () == disassemWin && - currentLayout () != SRC_DISASSEM_COMMAND) - tuiSetWinFocusTo (srcWin); - } - } - - - return; -} /* tuiUpdateSourceWindowAsIs */ - - -/* -** tuiUpdateSourceWindowsWithAddr(). -** Function to ensure that the source and/or disassemly windows -** reflect the input address. -*/ -void -#ifdef __STDC__ -tuiUpdateSourceWindowsWithAddr ( - Opaque addr) -#else -tuiUpdateSourceWindowsWithAddr (addr) - Opaque addr; -#endif -{ - if (addr > (Opaque) NULL) - { - struct symtab_and_line sal; - - switch (currentLayout ()) - { - case DISASSEM_COMMAND: - case DISASSEM_DATA_COMMAND: - tuiShowDisassem (addr); - break; - case SRC_DISASSEM_COMMAND: - tuiShowDisassemAndUpdateSource (addr); - break; - default: - sal = find_pc_line ((CORE_ADDR) addr, 0); - tuiShowSource (sal.symtab, - (Opaque) sal.line, - FALSE); - break; - } - } - else - { - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - { - TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; - - tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); - tuiClearExecInfoContent (winInfo); - } - } - - return; -} /* tuiUpdateSourceWindowsWithAddr */ - - -/* -** tui_vUpdateSourceWindowsWithAddr() -** Update the source window with the address in a va_list -*/ -void -#ifdef __STDC__ -tui_vUpdateSourceWindowsWithAddr ( - va_list args) -#else -tui_vUpdateSourceWindowsWithAddr (args) - va_list args; -#endif -{ - Opaque addr = va_arg (args, Opaque); - - tuiUpdateSourceWindowsWithAddr (addr); - - return; -} /* tui_vUpdateSourceWindowsWithAddr */ - - -/* -** tuiUpdateSourceWindowsWithLine(). -** Function to ensure that the source and/or disassemly windows -** reflect the input address. -*/ -void -#ifdef __STDC__ -tuiUpdateSourceWindowsWithLine ( - struct symtab *s, - int line) -#else -tuiUpdateSourceWindowsWithLine (s, line) - struct symtab *s; - int line; -#endif -{ - switch (currentLayout ()) - { - case DISASSEM_COMMAND: - case DISASSEM_DATA_COMMAND: - tuiUpdateSourceWindowsWithAddr ((Opaque) find_line_pc (s, line)); - break; - default: - tuiShowSource (s, (Opaque) line, FALSE); - if (currentLayout () == SRC_DISASSEM_COMMAND) - tuiShowDisassem ((Opaque) find_line_pc (s, line)); - break; - } - - return; -} /* tuiUpdateSourceWindowsWithLine */ - - -/* -** tui_vUpdateSourceWindowsWithLine() -** Update the source window with the line number in a va_list -*/ -void -#ifdef __STDC__ -tui_vUpdateSourceWindowsWithLine ( - va_list args) -#else -tui_vUpdateSourceWindowsWithLine (args) - va_list args; -#endif -{ - struct symtab *s = va_arg (args, struct symtab *); - int line = va_arg (args, int); - - tuiUpdateSourceWindowsWithLine (s, line); - - return; -} /* tui_vUpdateSourceWindowsWithLine */ - - -/* -** tuiClearSourceContent(). -*/ -void -#ifdef __STDC__ -tuiClearSourceContent ( - TuiWinInfoPtr winInfo, - int displayPrompt) -#else -tuiClearSourceContent (winInfo, displayPrompt) - TuiWinInfoPtr winInfo; - int displayPrompt; -#endif -{ - if (m_winPtrNotNull (winInfo)) - { - register int i; - - winInfo->generic.contentInUse = FALSE; - tuiEraseSourceContent (winInfo, displayPrompt); - for (i = 0; i < winInfo->generic.contentSize; i++) - { - TuiWinElementPtr element = - (TuiWinElementPtr) winInfo->generic.content[i]; - element->whichElement.source.hasBreak = FALSE; - element->whichElement.source.isExecPoint = FALSE; - } - } - - return; -} /* tuiClearSourceContent */ - - -/* -** tuiClearAllSourceWinsContent(). -*/ -void -#ifdef __STDC__ -tuiClearAllSourceWinsContent ( - int displayPrompt) -#else -tuiClearAllSourceWinsContent (displayPrompt) - int displayPrompt; -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiClearSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i], - displayPrompt); - - return; -} /* tuiClearAllSourceWinsContent */ - - -/* -** tuiEraseSourceContent(). -*/ -void -#ifdef __STDC__ -tuiEraseSourceContent ( - TuiWinInfoPtr winInfo, - int displayPrompt) -#else -tuiEraseSourceContent (winInfo, displayPrompt) - TuiWinInfoPtr winInfo; - int displayPrompt; -#endif -{ - int xPos; - int halfWidth = (winInfo->generic.width - 2) / 2; - - if (winInfo->generic.handle != (WINDOW *) NULL) - { - werase (winInfo->generic.handle); - checkAndDisplayHighlightIfNeeded (winInfo); - if (displayPrompt == EMPTY_SOURCE_PROMPT) - { - char *noSrcStr; - - if (winInfo->generic.type == SRC_WIN) - noSrcStr = NO_SRC_STRING; - else - noSrcStr = NO_DISASSEM_STRING; - if (strlen (noSrcStr) >= halfWidth) - xPos = 1; - else - xPos = halfWidth - strlen (noSrcStr); - mvwaddstr (winInfo->generic.handle, - (winInfo->generic.height / 2), - xPos, - noSrcStr); - - /* elz: added this function call to set the real contents of - the window to what is on the screen, so that later calls - to refresh, do display - the correct stuff, and not the old image */ - - tuiSetSourceContentNil (winInfo, noSrcStr); - } - tuiRefreshWin (&winInfo->generic); - } - return; -} /* tuiEraseSourceContent */ - - -/* -** tuiEraseAllSourceContent(). -*/ -void -#ifdef __STDC__ -tuiEraseAllSourceWinsContent ( - int displayPrompt) -#else -tuiEraseAllSourceWinsContent (displayPrompt) - int displayPrompt; -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiEraseSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i], - displayPrompt); - - return; -} /* tuiEraseAllSourceWinsContent */ - - -/* -** tuiShowSourceContent(). -*/ -void -#ifdef __STDC__ -tuiShowSourceContent ( - TuiWinInfoPtr winInfo) -#else -tuiShowSourceContent (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - int curLine, i, curX; - - tuiEraseSourceContent (winInfo, (winInfo->generic.contentSize <= 0)); - if (winInfo->generic.contentSize > 0) - { - char *line; - - for (curLine = 1; (curLine <= winInfo->generic.contentSize); curLine++) - mvwaddstr ( - winInfo->generic.handle, - curLine, - 1, - ((TuiWinElementPtr) - winInfo->generic.content[curLine - 1])->whichElement.source.line); - } - checkAndDisplayHighlightIfNeeded (winInfo); - tuiRefreshWin (&winInfo->generic); - winInfo->generic.contentInUse = TRUE; - - return; -} /* tuiShowSourceContent */ - - -/* -** tuiShowAllSourceWinsContent() -*/ -void -#ifdef __STDC__ -tuiShowAllSourceWinsContent (void) -#else -tuiShowAllSourceWinsContent () -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiShowSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); - - return; -} /* tuiShowAllSourceWinsContent */ - - -/* -** tuiHorizontalSourceScroll(). -** Scroll the source forward or backward horizontally -*/ -void -#ifdef __STDC__ -tuiHorizontalSourceScroll ( - TuiWinInfoPtr winInfo, - TuiScrollDirection direction, - int numToScroll) -#else -tuiHorizontalSourceScroll (winInfo, direction, numToScroll) - TuiWinInfoPtr winInfo; - TuiScrollDirection direction; - int numToScroll; -#endif -{ - if (winInfo->generic.content != (OpaquePtr) NULL) - { - int offset; - struct symtab *s; - - if (current_source_symtab == (struct symtab *) NULL) - s = find_pc_symtab (selected_frame->pc); - else - s = current_source_symtab; - - if (direction == LEFT_SCROLL) - offset = winInfo->detail.sourceInfo.horizontalOffset + numToScroll; - else - { - if ((offset = - winInfo->detail.sourceInfo.horizontalOffset - numToScroll) < 0) - offset = 0; - } - winInfo->detail.sourceInfo.horizontalOffset = offset; - tuiUpdateSourceWindowAsIs ( - winInfo, - s, - ((winInfo == srcWin) ? - (Opaque) ((TuiWinElementPtr) - winInfo->generic.content[0])->whichElement.source.lineOrAddr.lineNo : - (Opaque) ((TuiWinElementPtr) - winInfo->generic.content[0])->whichElement.source.lineOrAddr.addr), - (int) FALSE); - } - - return; -} /* tuiHorizontalSourceScroll */ - - -/* -** tuiSetHasExecPointAt(). -** Set or clear the hasBreak flag in the line whose line is lineNo. -*/ -void -#ifdef __STDC__ -tuiSetIsExecPointAt ( - Opaque lineOrAddr, - TuiWinInfoPtr winInfo) -#else -tuiSetIsExecPointAt (lineOrAddr, winInfo) - Opaque lineOrAddr; - TuiWinInfoPtr winInfo; -#endif -{ - int i; - TuiWinContent content = (TuiWinContent) winInfo->generic.content; - - i = 0; - while (i < winInfo->generic.contentSize) - { - if (content[i]->whichElement.source.lineOrAddr.addr == lineOrAddr) - content[i]->whichElement.source.isExecPoint = TRUE; - else - content[i]->whichElement.source.isExecPoint = FALSE; - i++; - } - - return; -} /* tuiSetIsExecPointAt */ - - -/* -** tuiSetHasBreakAt(). -** Set or clear the hasBreak flag in the line whose line is lineNo. -*/ -void -#ifdef __STDC__ -tuiSetHasBreakAt ( - struct breakpoint *bp, - TuiWinInfoPtr winInfo, - int hasBreak) -#else -tuiSetHasBreakAt (bp, winInfo, hasBreak) - struct breakpoint *bp; - TuiWinInfoPtr winInfo; - int hasBreak; -#endif -{ - int i; - TuiWinContent content = (TuiWinContent) winInfo->generic.content; - - i = 0; - while (i < winInfo->generic.contentSize) - { - int gotIt; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - if (winInfo == srcWin) - { - char *fileNameDisplayed = (char *) NULL; - - if (((TuiWinElementPtr) - locator->content[0])->whichElement.locator.fileName != - (char *) NULL) - fileNameDisplayed = ((TuiWinElementPtr) - locator->content[0])->whichElement.locator.fileName; - else if (current_source_symtab != (struct symtab *) NULL) - fileNameDisplayed = current_source_symtab->filename; - - gotIt = (fileNameDisplayed != (char *) NULL && - (strcmp (bp->source_file, fileNameDisplayed) == 0) && - content[i]->whichElement.source.lineOrAddr.lineNo == - bp->line_number); - } - else - gotIt = (content[i]->whichElement.source.lineOrAddr.addr - == (Opaque) bp->address); - if (gotIt) - { - content[i]->whichElement.source.hasBreak = hasBreak; - break; - } - i++; - } - - return; -} /* tuiSetHasBreakAt */ - - -/* -** tuiAllSetHasBreakAt(). -** Set or clear the hasBreak flag in all displayed source windows. -*/ -void -#ifdef __STDC__ -tuiAllSetHasBreakAt ( - struct breakpoint *bp, - int hasBreak) -#else -tuiAllSetHasBreakAt (bp, hasBreak) - struct breakpoint *bp; - int hasBreak; -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiSetHasBreakAt (bp, - (TuiWinInfoPtr) (sourceWindows ())->list[i], hasBreak); - - return; -} /* tuiAllSetHasBreakAt */ - - -/* -** tui_vAllSetHasBreakAt() -** Set or clear the hasBreak flag in all displayed source windows, -** with params in a va_list -*/ -void -#ifdef __STDC__ -tui_vAllSetHasBreakAt ( - va_list args) -#else -tui_vAllSetHasBreakAt (args) - va_list args; -#endif -{ - struct breakpoint *bp = va_arg (args, struct breakpoint *); - int hasBreak = va_arg (args, int); - - tuiAllSetHasBreakAt (bp, hasBreak); - - return; -} /* tui_vAllSetHasBreakAt */ - - - -/********************************* -** EXECUTION INFO FUNCTIONS ** -*********************************/ - -/* -** tuiSetExecInfoContent(). -** Function to initialize the content of the execution info window, -** based upon the input window which is either the source or -** disassembly window. -*/ -TuiStatus -#ifdef __STDC__ -tuiSetExecInfoContent ( - TuiWinInfoPtr winInfo) -#else -tuiSetExecInfoContent (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - TuiStatus ret = TUI_SUCCESS; - - if (winInfo->detail.sourceInfo.executionInfo != (TuiGenWinInfoPtr) NULL) - { - TuiGenWinInfoPtr execInfoPtr = winInfo->detail.sourceInfo.executionInfo; - - if (execInfoPtr->content == (OpaquePtr) NULL) - execInfoPtr->content = - (OpaquePtr) allocContent (winInfo->generic.height, - execInfoPtr->type); - if (execInfoPtr->content != (OpaquePtr) NULL) - { - int i; - - for (i = 0; i < winInfo->generic.contentSize; i++) - { - TuiWinElementPtr element; - TuiWinElementPtr srcElement; - - element = (TuiWinElementPtr) execInfoPtr->content[i]; - srcElement = (TuiWinElementPtr) winInfo->generic.content[i]; - /* - ** First check to see if we have a breakpoint that is - ** temporary. If so, and this is our current execution point, - ** then clear the break indicator. - */ - if (srcElement->whichElement.source.hasBreak && - srcElement->whichElement.source.isExecPoint) - { - struct breakpoint *bp; - int found = FALSE; - extern struct breakpoint *breakpoint_chain; - - for (bp = breakpoint_chain; - (bp != (struct breakpoint *) NULL && !found); - bp = bp->next) - { - found = - (winInfo == srcWin && - bp->line_number == - srcElement->whichElement.source.lineOrAddr.lineNo) || - (winInfo == disassemWin && - bp->address == (CORE_ADDR) - srcElement->whichElement.source.lineOrAddr.addr); - if (found) - srcElement->whichElement.source.hasBreak = - (bp->disposition != del || bp->hit_count <= 0); - } - if (!found) - srcElement->whichElement.source.hasBreak = FALSE; - } - /* - ** Now update the exec info content based upon the state - ** of each line as indicated by the source content. - */ - if (srcElement->whichElement.source.hasBreak && - srcElement->whichElement.source.isExecPoint) - element->whichElement.simpleString = breakLocationStr (); - else if (srcElement->whichElement.source.hasBreak) - element->whichElement.simpleString = breakStr (); - else if (srcElement->whichElement.source.isExecPoint) - element->whichElement.simpleString = locationStr (); - else - element->whichElement.simpleString = blankStr (); - } - execInfoPtr->contentSize = winInfo->generic.contentSize; - } - else - ret = TUI_FAILURE; - } - - return ret; -} /* tuiSetExecInfoContent */ - - -/* -** tuiShowExecInfoContent(). -*/ -void -#ifdef __STDC__ -tuiShowExecInfoContent ( - TuiWinInfoPtr winInfo) -#else -tuiShowExecInfoContent (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo; - int curLine; - - werase (execInfo->handle); - tuiRefreshWin (execInfo); - for (curLine = 1; (curLine <= execInfo->contentSize); curLine++) - mvwaddstr (execInfo->handle, - curLine, - 0, - ((TuiWinElementPtr) - execInfo->content[curLine - 1])->whichElement.simpleString); - tuiRefreshWin (execInfo); - execInfo->contentInUse = TRUE; - - return; -} /* tuiShowExecInfoContent */ - - -/* -** tuiShowAllExecInfosContent() -*/ -void -#ifdef __STDC__ -tuiShowAllExecInfosContent (void) -#else -tuiShowAllExecInfosContent () -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiShowExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); - - return; -} /* tuiShowAllExecInfosContent */ - - -/* -** tuiEraseExecInfoContent(). -*/ -void -#ifdef __STDC__ -tuiEraseExecInfoContent ( - TuiWinInfoPtr winInfo) -#else -tuiEraseExecInfoContent (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo; - - werase (execInfo->handle); - tuiRefreshWin (execInfo); - - return; -} /* tuiEraseExecInfoContent */ - - -/* -** tuiEraseAllExecInfosContent() -*/ -void -#ifdef __STDC__ -tuiEraseAllExecInfosContent (void) -#else -tuiEraseAllExecInfosContent () -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiEraseExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); - - return; -} /* tuiEraseAllExecInfosContent */ - - -/* -** tuiClearExecInfoContent(). -*/ -void -#ifdef __STDC__ -tuiClearExecInfoContent ( - TuiWinInfoPtr winInfo) -#else -tuiClearExecInfoContent (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - winInfo->detail.sourceInfo.executionInfo->contentInUse = FALSE; - tuiEraseExecInfoContent (winInfo); - - return; -} /* tuiClearExecInfoContent */ - - -/* -** tuiClearAllExecInfosContent() -*/ -void -#ifdef __STDC__ -tuiClearAllExecInfosContent (void) -#else -tuiClearAllExecInfosContent () -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiClearExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]); - - return; -} /* tuiClearAllExecInfosContent */ - - -/* -** tuiUpdateExecInfo(). -** Function to update the execution info window -*/ -void -#ifdef __STDC__ -tuiUpdateExecInfo ( - TuiWinInfoPtr winInfo) -#else -tuiUpdateExecInfo (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - tuiSetExecInfoContent (winInfo); - tuiShowExecInfoContent (winInfo); -} /* tuiUpdateExecInfo - - -/* -** tuiUpdateAllExecInfos() -*/ -void -#ifdef __STDC__ -tuiUpdateAllExecInfos (void) -#else -tuiUpdateAllExecInfos () -#endif -{ - int i; - - for (i = 0; i < (sourceWindows ())->count; i++) - tuiUpdateExecInfo ((TuiWinInfoPtr) (sourceWindows ())->list[i]); - - return; -} /* tuiUpdateAllExecInfos*/ - - - -/* tuiUpdateOnEnd() -** elz: This function clears the execution info from the source windows -** and resets the locator to display no line info, procedure info, pc -** info. It is called by stack_publish_stopped_with_no_frame, which -** is called then the target terminates execution -*/ -void -#ifdef __STDC__ -tuiUpdateOnEnd (void) -#else -tuiUpdateOnEnd () -#endif -{ - int i; - TuiGenWinInfoPtr locator; - char *filename; - TuiWinInfoPtr winInfo; - - locator = locatorWinInfoPtr (); - - /* for all the windows (src, asm) */ - for (i = 0; i < (sourceWindows ())->count; i++) - { - winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; - - tuiSetIsExecPointAt ((Opaque) - 1, winInfo); /* the target is'n running */ - /* -1 should not match any line number or pc */ - tuiSetExecInfoContent (winInfo); /*set winInfo so that > is'n displayed*/ - tuiShowExecInfoContent (winInfo); /* display the new contents */ - } - - /*now update the locator*/ - tuiClearLocatorDisplay (); - tuiGetLocatorFilename (locator, &filename); - tuiSetLocatorInfo ( - filename, - (char *) NULL, - 0, - (Opaque) NULL, - &((TuiWinElementPtr) locator->content[0])->whichElement.locator); - tuiShowLocatorContent (); - - return; -} /* tuiUpdateOnEnd */ - - - -TuiStatus -#ifdef __STDC__ -tuiAllocSourceBuffer ( - TuiWinInfoPtr winInfo) -#else -tuiAllocSourceBuffer (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - register char *srcLine, *srcLineBuf; - register int i, lineWidth, c, maxLines; - TuiStatus ret = TUI_FAILURE; - - maxLines = winInfo->generic.height; /* less the highlight box */ - lineWidth = winInfo->generic.width - 1; - /* - ** Allocate the buffer for the source lines. Do this only once since they - ** will be re-used for all source displays. The only other time this will - ** be done is when a window's size changes. - */ - if (winInfo->generic.content == (OpaquePtr) NULL) - { - srcLineBuf = (char *) xmalloc ((maxLines * lineWidth) * sizeof (char)); - if (srcLineBuf == (char *) NULL) - fputs_unfiltered ( - "Unable to Allocate Memory for Source or Disassembly Display.\n", - gdb_stderr); - else - { - /* allocate the content list */ - if ((winInfo->generic.content = - (OpaquePtr) allocContent (maxLines, SRC_WIN)) == (OpaquePtr) NULL) - { - tuiFree (srcLineBuf); - srcLineBuf = (char *) NULL; - fputs_unfiltered ( - "Unable to Allocate Memory for Source or Disassembly Display.\n", - gdb_stderr); - } - } - for (i = 0; i < maxLines; i++) - ((TuiWinElementPtr) - winInfo->generic.content[i])->whichElement.source.line = - srcLineBuf + (lineWidth * i); - ret = TUI_SUCCESS; - } - else - ret = TUI_SUCCESS; - - return ret; -} /* tuiAllocSourceBuffer */ - - -/* -** tuiLineIsDisplayed(). -** Answer whether the a particular line number or address is displayed -** in the current source window. -*/ -int -#ifdef __STDC__ -tuiLineIsDisplayed ( - Opaque lineNoOrAddr, - TuiWinInfoPtr winInfo, - int checkThreshold) -#else -tuiLineIsDisplayed (lineNoOrAddr, winInfo, checkThreshold) - Opaque lineNoOrAddr; - TuiWinInfoPtr winInfo; - int checkThreshold; -#endif -{ - int isDisplayed = FALSE; - int i, threshold; - - if (checkThreshold) - threshold = SCROLL_THRESHOLD; - else - threshold = 0; - i = 0; - while (i < winInfo->generic.contentSize - threshold && !isDisplayed) - { - if (winInfo == srcWin) - isDisplayed = (((TuiWinElementPtr) - winInfo->generic.content[i])->whichElement.source.lineOrAddr.lineNo - == (int) lineNoOrAddr); - else - isDisplayed = (((TuiWinElementPtr) - winInfo->generic.content[i])->whichElement.source.lineOrAddr.addr - == lineNoOrAddr); - i++; - } - - return isDisplayed; -} /* tuiLineIsDisplayed */ - - -/***************************************** -** STATIC LOCAL FUNCTIONS ** -******************************************/ diff --git a/contrib/gdb/gdb/tui/tuiSourceWin.h b/contrib/gdb/gdb/tui/tuiSourceWin.h deleted file mode 100644 index 13f3a78ab18..00000000000 --- a/contrib/gdb/gdb/tui/tuiSourceWin.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef _TUI_SOURCEWIN_H -#define _TUI_SOURCEWIN_H -/* -** This header file supports -*/ - - -extern void tuiDisplayMainFunction PARAMS ((void)); -extern void tuiUpdateSourceWindow PARAMS - ((TuiWinInfoPtr, struct symtab *, Opaque, int)); -extern void tuiUpdateSourceWindowAsIs PARAMS - ((TuiWinInfoPtr, struct symtab *, Opaque, int)); -extern void tuiUpdateSourceWindowsWithAddr PARAMS ((Opaque)); -extern void tui_vUpdateSourceWindowsWithAddr PARAMS ((va_list)); -extern void tuiUpdateSourceWindowsWithLine PARAMS ((struct symtab *, int)); -extern void tui_vUpdateSourceWindowsWithLine PARAMS ((va_list)); -extern void tuiUpdateSourceWindowsFromLocator PARAMS ((void)); -extern void tuiClearSourceContent PARAMS ((TuiWinInfoPtr, int)); -extern void tuiClearAllSourceWinsContent PARAMS ((int)); -extern void tuiEraseSourceContent PARAMS ((TuiWinInfoPtr, int)); -extern void tuiEraseAllSourceWinsContent PARAMS ((int)); -extern void tuiSetSourceContentNil PARAMS ((TuiWinInfoPtr, char *)); -extern void tuiShowSourceContent PARAMS ((TuiWinInfoPtr)); -extern void tuiShowAllSourceWinsContent PARAMS ((void)); -extern void tuiHorizontalSourceScroll PARAMS ((TuiWinInfoPtr, TuiScrollDirection, int)); -extern void tuiUpdateOnEnd PARAMS ((void)); - -extern TuiStatus tuiSetExecInfoContent PARAMS ((TuiWinInfoPtr)); -extern void tuiShowExecInfoContent PARAMS ((TuiWinInfoPtr)); -extern void tuiShowAllExecInfosContent PARAMS ((void)); -extern void tuiEraseExecInfoContent PARAMS ((TuiWinInfoPtr)); -extern void tuiEraseAllExecInfosContent PARAMS ((void)); -extern void tuiClearExecInfoContent PARAMS ((TuiWinInfoPtr)); -extern void tuiClearAllExecInfosContent PARAMS ((void)); -extern void tuiUpdateExecInfo PARAMS ((TuiWinInfoPtr)); -extern void tuiUpdateAllExecInfos PARAMS ((void)); - -extern void tuiSetIsExecPointAt PARAMS ((Opaque, TuiWinInfoPtr)); -extern void tuiSetHasBreakAt PARAMS ((struct breakpoint *, TuiWinInfoPtr, int)); -extern void tuiAllSetHasBreakAt PARAMS ((struct breakpoint *, int)); -extern void tui_vAllSetHasBreakAt PARAMS ((va_list)); -extern TuiStatus tuiAllocSourceBuffer PARAMS ((TuiWinInfoPtr)); -extern int tuiLineIsDisplayed PARAMS ((Opaque, TuiWinInfoPtr, int)); - - -/* -** Constant definitions -*/ -#define SCROLL_THRESHOLD 2 /* threshold for lazy scroll */ - - -/* -** Macros -*/ -#define m_tuiSetBreakAt(bp, winInfo) tuiSetHasBreakAt((bp, winInfo, TRUE) -#define m_tuiClearBreakAt(bp, winInfo) tuiSetHasBreakAt(bp, winInfo, FALSE) - -#define m_tuiAllSetBreakAt(bp) tuiAllSetHasBreakAt(bp, TRUE) -#define m_tuiAllClearBreakAt(bp) tuiAllSetHasBreakAt(bp, FALSE) - -#define m_tuiSrcLineDisplayed(lineNo) tuiLineIsDisplayed((Opaque)(lineNo), srcWin, FALSE) -#define m_tuiSrcAddrDisplayed(addr) tuiLineIsDisplayed((Opaque)(addr), disassemWin, FALSE) -#define m_tuiSrcLineDisplayedWithinThreshold(lineNo) \ - tuiLineIsDisplayed((Opaque)(lineNo), srcWin, TRUE) -#define m_tuiSrcAddrDisplayedWithinThreshold(addr) \ - tuiLineIsDisplayed((Opaque)(addr), disassemWin, TRUE) -#define m_tuiLineDisplayedWithinThreshold(winInfo, lineOrAddr) \ - ( (winInfo == srcWin) ? \ - m_tuiSrcLineDisplayedWithinThreshold(lineOrAddr) : \ - m_tuiSrcAddrDisplayedWithinThreshold(lineOrAddr) ) - - - -#endif /*_TUI_SOURCEWIN_H */ diff --git a/contrib/gdb/gdb/tui/tuiStack.c b/contrib/gdb/gdb/tui/tuiStack.c deleted file mode 100644 index 401dfe23d82..00000000000 --- a/contrib/gdb/gdb/tui/tuiStack.c +++ /dev/null @@ -1,554 +0,0 @@ -/* -** This module contains functions for displaying the locator information in the locator window. -*/ - -#include "defs.h" -#include "symtab.h" -#include "breakpoint.h" -#include "frame.h" - -#include "tui.h" -#include "tuiData.h" -#include "tuiStack.h" -#include "tuiSourceWin.h" - - -/***************************************** -** STATIC LOCAL FUNCTIONS FORWARD DECLS ** -******************************************/ - -static char *_getFuncNameFromFrame PARAMS ((struct frame_info *)); -static void _tuiUpdateLocation_command PARAMS ((char *, int)); - - - -/***************************************** -** PUBLIC FUNCTION ** -******************************************/ - -/* -** tuiClearLocatorDisplay() -*/ -void -#ifdef __STDC__ -tuiClearLocatorDisplay (void) -#else -tuiClearLocatorDisplay () -#endif -{ - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - int i; - - if (locator->handle != (WINDOW *) NULL) - { - /* No need to werase, since writing a line of - * blanks which we do below, is equivalent. - */ - /* werase(locator->handle); */ - wmove (locator->handle, 0, 0); - wstandout (locator->handle); - for (i = 0; i < locator->width; i++) - waddch (locator->handle, ' '); - wstandend (locator->handle); - tuiRefreshWin (locator); - wmove (locator->handle, 0, 0); - locator->contentInUse = FALSE; - } - - return; -} /* tuiClearLocatorDisplay */ - - -/* -** tuiShowLocatorContent() -*/ -void -#ifdef __STDC__ -tuiShowLocatorContent (void) -#else -tuiShowLocatorContent () -#endif -{ - char *string; - TuiGenWinInfoPtr locator; - - locator = locatorWinInfoPtr (); - - if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL) - { - string = displayableWinContentAt (locator, 0); - if (string != (char *) NULL) - { - wmove (locator->handle, 0, 0); - wstandout (locator->handle); - waddstr (locator->handle, string); - wstandend (locator->handle); - tuiRefreshWin (locator); - wmove (locator->handle, 0, 0); - if (string != nullStr ()) - tuiFree (string); - locator->contentInUse = TRUE; - } - } - - return; -} /* tuiShowLocatorContent */ - - -/* -** tuiSetLocatorInfo(). -** Function to update the locator, with the provided arguments. -*/ -void -#ifdef __STDC__ -tuiSetLocatorInfo ( - char *fname, - char *procname, - int lineNo, - Opaque addr, - TuiLocatorElementPtr element) -#else -tuiSetLocatorInfo (fname, procname, lineNo, addr, element) - char *fname; - char *procname; - int lineNo; - Opaque addr; - TuiLocatorElementPtr element; -#endif -{ -#ifdef COMMENT - /* first free the old info */ - if (element->fileName) - tuiFree (element->fileName); - if (element->procName) - tuiFree (element->procName); - - if (fname == (char *) NULL) - element->fileName = fname; - else - element->fileName = tuiStrDup (fname); - if (procname == (char *) NULL) - element->procName = procname; - else - element->procName = tuiStrDup (procname); -#else - element->fileName[0] = (char) 0; - element->procName[0] = (char) 0; - strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, fname); - strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname); -#endif - element->lineNo = lineNo; - element->addr = (Opaque) addr; - - return; -} /* tuiSetLocatorInfo */ - - -/* -** tuiUpdateLocatorFilename(). -** Update only the filename portion of the locator. -*/ -void -#ifdef __STDC__ -tuiUpdateLocatorFilename ( - char *fileName) -#else -tuiUpdateLocatorFilename (fileName) - char *fileName; -#endif -{ - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - if (locator->content[0] == (Opaque) NULL) - tuiSetLocatorContent ((struct frame_info *) NULL); - ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0; - strcat_to_buf (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName, - MAX_LOCATOR_ELEMENT_LEN, - fileName); - - tuiShowLocatorContent (); - - return; -} /* tuiUpdateLocatorFilename */ - - -/* -** tui_vUpdateLocatorFilename(). -** Update only the filename portion of the locator with args in a va_list. -*/ -void -#ifdef __STDC__ -tui_vUpdateLocatorFilename ( - va_list args) -#else -tui_vUpdateLocatorFilename (args) - va_list args; -#endif -{ - char *fileName; - - fileName = va_arg (args, char *); - tuiUpdateLocatorFilename (fileName); - - return; -} /* tui_vUpdateLocatorFilename */ - - -/* -** tuiSwitchFilename(). -** Update the filename portion of the locator. Clear the other info in locator. -** (elz) -*/ -void -#ifdef __STDC__ -tuiSwitchFilename ( - char *fileName) -#else -tuiSwitchFilename (fileName) - char *fileName; -#endif -{ - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - - if (locator->content[0] == (Opaque) NULL) - tuiSetLocatorContent ((struct frame_info *) NULL); - ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0; - - tuiSetLocatorInfo (fileName, - (char *) NULL, - 0, - (Opaque) NULL, - &((TuiWinElementPtr) locator->content[0])->whichElement.locator); - - tuiShowLocatorContent (); - - return; -} /* tuiSwitchFilename */ - - -/* -** tuiGetLocatorFilename(). -** Get the filename portion of the locator. -** (elz) -*/ -void -#ifdef __STDC__ -tuiGetLocatorFilename ( - TuiGenWinInfoPtr locator, - char **filename) -#else -tuiGetLocatorFilename (locator, filename) - TuiGenWinInfoPtr locator; - char **filename; -#endif -{ - - /* the current filename could be non known, in which case the xmalloc would - allocate no memory, because the length would be 0 */ - if (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName) - { - int name_length = - strlen (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName); - - (*filename) = (char *) xmalloc (name_length + 1); - strcpy ((*filename), - ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName); - } - - return; -} /* tuiGetLocatorFilename */ - - -/* -** tuiUpdateLocatorInfoFromFrame(). -** Function to update the locator, with the information extracted from frameInfo -*/ -void -#ifdef __STDC__ -tuiUpdateLocatorInfoFromFrame ( - struct frame_info *frameInfo, - TuiLocatorElementPtr element) -#else -tuiUpdateLocatorInfoFromFrame (frameInfo, element) - struct frame_info *frameInfo; - TuiLocatorElementPtr element; -#endif -{ - struct symtab_and_line symtabAndLine; - - /* now get the new info */ - symtabAndLine = find_pc_line (frameInfo->pc, - (frameInfo->next != (struct frame_info *) NULL && - !frameInfo->next->signal_handler_caller && - !frame_in_dummy (frameInfo->next))); - if (symtabAndLine.symtab && symtabAndLine.symtab->filename) - tuiSetLocatorInfo (symtabAndLine.symtab->filename, - _getFuncNameFromFrame (frameInfo), - symtabAndLine.line, - (Opaque) frameInfo->pc, - element); - else - tuiSetLocatorInfo ((char *) NULL, - _getFuncNameFromFrame (frameInfo), - 0, - (Opaque) frameInfo->pc, - element); - - return; -} /* tuiUpdateLocatorInfoFromFrame */ - - -/* -** tuiSetLocatorContent(). -** Function to set the content of the locator -*/ -void -#ifdef __STDC__ -tuiSetLocatorContent ( - struct frame_info *frameInfo) -#else -tuiSetLocatorContent (frameInfo) - struct frame_info *frameInfo; -#endif -{ - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - TuiWinElementPtr element; - struct symtab_and_line symtabAndLine; - - /* Allocate the element if necessary */ - if (locator->contentSize <= 0) - { - TuiWinContent contentPtr; - - if ((locator->content = (OpaquePtr) allocContent (1, locator->type)) == (OpaquePtr) NULL) - error ("Unable to Allocate Memory to Display Location."); - locator->contentSize = 1; - } - - if (frameInfo != (struct frame_info *) NULL) - tuiUpdateLocatorInfoFromFrame (frameInfo, - &((TuiWinElementPtr) locator->content[0])->whichElement.locator); - else - tuiSetLocatorInfo ((char *) NULL, - (char *) NULL, - 0, - (Opaque) NULL, - &((TuiWinElementPtr) locator->content[0])->whichElement.locator); - return; -} /* tuiSetLocatorContent */ - - -/* -** tuiUpdateLocatorDisplay(). -** Function to update the locator display -*/ -void -#ifdef __STDC__ -tuiUpdateLocatorDisplay ( - struct frame_info *frameInfo) -#else -tuiUpdateLocatorDisplay (frameInfo) - struct frame_info *frameInfo; -#endif -{ - tuiClearLocatorDisplay (); - tuiSetLocatorContent (frameInfo); - tuiShowLocatorContent (); - - return; -} /* tuiUpdateLocatorDisplay */ - - -/* -** tuiShowFrameInfo(). -** Function to print the frame inforrmation for the TUI. -*/ -void -#ifdef __STDC__ -tuiShowFrameInfo ( - struct frame_info *fi) -#else -tuiShowFrameInfo (fi) - struct frame_info *fi; -#endif -{ - TuiWinInfoPtr winInfo; - register int i; - - if (fi) - { - register int startLine, i; - register struct symtab *s; - CORE_ADDR low; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - int sourceAlreadyDisplayed; - - - s = find_pc_symtab (fi->pc); - sourceAlreadyDisplayed = tuiSourceIsDisplayed (s->filename); - tuiUpdateLocatorDisplay (fi); - for (i = 0; i < (sourceWindows ())->count; i++) - { - winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; - if (winInfo == srcWin) - { - startLine = - (((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo - - (winInfo->generic.viewportHeight / 2)) + 1; - if (startLine <= 0) - startLine = 1; - } - else - { - if (find_pc_partial_function (fi->pc, (char **) NULL, &low, (CORE_ADDR) NULL) == 0) - error ("No function contains program counter for selected frame.\n"); - else - low = (CORE_ADDR) tuiGetLowDisassemblyAddress ((Opaque) low, (Opaque) fi->pc); - } - - if (winInfo == srcWin) - { - if (!(sourceAlreadyDisplayed && m_tuiLineDisplayedWithinThreshold ( - winInfo, - ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo))) - tuiUpdateSourceWindow (winInfo, s, (Opaque) startLine, TRUE); - else - tuiSetIsExecPointAt ((Opaque) - ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo, - winInfo); - } - else - { - if (winInfo == disassemWin) - { - if (!m_tuiLineDisplayedWithinThreshold (winInfo, - ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr)) - tuiUpdateSourceWindow (winInfo, s, (Opaque) low, TRUE); - else - tuiSetIsExecPointAt ((Opaque) - ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr, - winInfo); - } - } - tuiUpdateExecInfo (winInfo); - } - } - else - { - tuiUpdateLocatorDisplay (fi); - for (i = 0; i < (sourceWindows ())->count; i++) - { - winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; - tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); - tuiUpdateExecInfo (winInfo); - } - } - - return; -} /* tuiShowFrameInfo */ - - -/* -** tui_vShowFrameInfo(). -** Function to print the frame inforrmation for the TUI with args in a va_list. -*/ -void -#ifdef __STDC__ -tui_vShowFrameInfo ( - va_list args) -#else -tui_vShowFrameInfo (args) - va_list args; -#endif -{ - struct frame_info *fi; - - fi = va_arg (args, struct frame_info *); - tuiShowFrameInfo (fi); - - return; -} /* tui_vShowFrameInfo */ - - -/* -** _initialize_tuiStack(). -** Function to initialize gdb commands, for tui window stack manipulation. -*/ -void -_initialize_tuiStack () -{ - if (tui_version) - { - add_com ("update", class_tui, _tuiUpdateLocation_command, - "Update the source window and locator to display the current execution point.\n"); - } - - return; -} /* _initialize_tuiStack */ - - -/***************************************** -** STATIC LOCAL FUNCTIONS ** -******************************************/ - -/* -** _getFuncNameFromFrame(). -*/ -static char * -#ifdef __STDC__ -_getFuncNameFromFrame ( - struct frame_info *frameInfo) -#else -_getFuncNameFromFrame (frameInfo) - struct frame_info *frameInfo; -#endif -{ - char *funcName = (char *) NULL; - - find_pc_partial_function (frameInfo->pc, - &funcName, - (CORE_ADDR *) NULL, - (CORE_ADDR *) NULL); - return funcName; -} /* _getFuncNameFromFrame */ - - -/* -** _tuiUpdateLocation_command(). -** Command to update the display with the current execution point -*/ -static void -#ifdef __STDC__ -_tuiUpdateLocation_command ( - char *arg, - int fromTTY) -#else -_tuiUpdateLocation_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ -#ifndef TRY - extern void frame_command PARAMS ((char *, int)); - frame_command ("0", FALSE); -#else - struct frame_info *curFrame; - - /* Obtain the current execution point */ - if ((curFrame = get_current_frame ()) != (struct frame_info *) NULL) - { - struct frame_info *frame; - int curLevel = 0; - - for (frame = get_prev_frame (curLevel); - (frame != (struct frame_info *) NULL && (frame != curFrame)); - frame = get_prev_frame (frame)) - curLevel++; - - if (curFrame != (struct frame_info *) NULL) - print_frame_info (frame, curLevel, 0, 1); - } -#endif - - return; -} /* _tuiUpdateLocation_command */ diff --git a/contrib/gdb/gdb/tui/tuiStack.h b/contrib/gdb/gdb/tui/tuiStack.h deleted file mode 100644 index 20e9a92c61c..00000000000 --- a/contrib/gdb/gdb/tui/tuiStack.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _TUI_STACK_H -#define _TUI_STACK_H -/* -** This header file supports -*/ - -extern void tuiSetLocatorInfo PARAMS ((char *, char *, int, Opaque, TuiLocatorElementPtr)); -extern void tuiUpdateLocatorFilename PARAMS ((char *)); -extern void tui_vUpdateLocatorFilename PARAMS ((va_list)); -extern void tuiUpdateLocatorInfoFromFrame - PARAMS ((struct frame_info *, TuiLocatorElementPtr)); -extern void tuiUpdateLocatorDisplay PARAMS ((struct frame_info *)); -extern void tuiSetLocatorContent PARAMS ((struct frame_info *)); -extern void tuiShowLocatorContent PARAMS ((void)); -extern void tuiClearLocatorContent PARAMS ((void)); -extern void tuiSwitchFilename PARAMS ((char *)); -extern void tuiShowFrameInfo PARAMS ((struct frame_info *)); -extern void tui_vShowFrameInfo PARAMS ((va_list)); -extern void tuiGetLocatorFilename PARAMS ((TuiGenWinInfoPtr, char **)); - - -#endif /*_TUI_STACK_H*/ diff --git a/contrib/gdb/gdb/tui/tuiWin.c b/contrib/gdb/gdb/tui/tuiWin.c deleted file mode 100644 index 45bb0f6a4e9..00000000000 --- a/contrib/gdb/gdb/tui/tuiWin.c +++ /dev/null @@ -1,1650 +0,0 @@ -/* -** tuiWin.c -** This module contains procedures for handling tui window functions -** like resize, scrolling, scrolling, changing focus, etc. -** -** Author: Susan B. Macchia -*/ - - -#include -#include "defs.h" -#include "command.h" -#include "symtab.h" -#include "breakpoint.h" -#include "frame.h" - -#include "tui.h" -#include "tuiData.h" -#include "tuiGeneralWin.h" -#include "tuiStack.h" -#include "tuiSourceWin.h" -#include "tuiDataWin.h" - -/******************************* -** External Declarations -********************************/ -extern void init_page_info (); - -/******************************* -** Static Local Decls -********************************/ -static void _makeVisibleWithNewHeight PARAMS ((TuiWinInfoPtr)); -static void _makeInvisibleAndSetNewHeight PARAMS ((TuiWinInfoPtr, int)); -static TuiStatus _tuiAdjustWinHeights PARAMS ((TuiWinInfoPtr, int)); -static int _newHeightOk PARAMS ((TuiWinInfoPtr, int)); -static void _tuiSetTabWidth_command PARAMS ((char *, int)); -static void _tuiRefreshAll_command PARAMS ((char *, int)); -static void _tuiSetWinHeight_command PARAMS ((char *, int)); -static void _tuiXDBsetWinHeight_command PARAMS ((char *, int)); -static void _tuiAllWindowsInfo PARAMS ((char *, int)); -static void _tuiSetFocus_command PARAMS ((char *, int)); -static void _tuiScrollForward_command PARAMS ((char *, int)); -static void _tuiScrollBackward_command PARAMS ((char *, int)); -static void _tuiScrollLeft_command PARAMS ((char *, int)); -static void _tuiScrollRight_command PARAMS ((char *, int)); -static void _parseScrollingArgs PARAMS ((char *, TuiWinInfoPtr *, int *)); - - -/*************************************** -** DEFINITIONS -***************************************/ -#define WIN_HEIGHT_USAGE "Usage: winheight [+ | -] <#lines>\n" -#define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n" -#define FOCUS_USAGE "Usage: focus { | next | prev}\n" - -/*************************************** -** PUBLIC FUNCTIONS -***************************************/ - -/* -** _initialize_tuiWin(). -** Function to initialize gdb commands, for tui window manipulation. -*/ -void -_initialize_tuiWin () -{ - if (tui_version) - { - add_com ("refresh", class_tui, _tuiRefreshAll_command, - "Refresh the terminal display.\n"); - if (xdb_commands) - add_com_alias ("U", "refresh", class_tui, 0); - add_com ("tabset", class_tui, _tuiSetTabWidth_command, - "Set the width (in characters) of tab stops.\n\ -Usage: tabset \n"); - add_com ("winheight", class_tui, _tuiSetWinHeight_command, - "Set the height of a specified window.\n\ -Usage: winheight [+ | -] <#lines>\n\ -Window names are:\n\ -src : the source window\n\ -cmd : the command window\n\ -asm : the disassembly window\n\ -regs : the register display\n"); - add_com_alias ("wh", "winheight", class_tui, 0); - add_info ("win", _tuiAllWindowsInfo, - "List of all displayed windows.\n"); - add_com ("focus", class_tui, _tuiSetFocus_command, - "Set focus to named window or next/prev window.\n\ -Usage: focus { | next | prev}\n\ -Valid Window names are:\n\ -src : the source window\n\ -asm : the disassembly window\n\ -regs : the register display\n\ -cmd : the command window\n"); - add_com_alias ("fs", "focus", class_tui, 0); - add_com ("+", class_tui, _tuiScrollForward_command, - "Scroll window forward.\nUsage: + [win] [n]\n"); - add_com ("-", class_tui, _tuiScrollBackward_command, - "Scroll window backward.\nUsage: - [win] [n]\n"); - add_com ("<", class_tui, _tuiScrollLeft_command, - "Scroll window forward.\nUsage: < [win] [n]\n"); - add_com (">", class_tui, _tuiScrollRight_command, - "Scroll window backward.\nUsage: > [win] [n]\n"); - if (xdb_commands) - add_com ("w", class_xdb, _tuiXDBsetWinHeight_command, - "XDB compatibility command for setting the height of a command window.\n\ -Usage: w <#lines>\n"); - } - - return; -} /* _intialize_tuiWin */ - - -/* -** tuiClearWinFocusFrom -** Clear the logical focus from winInfo -*/ -void -#ifdef __STDC__ -tuiClearWinFocusFrom ( - TuiWinInfoPtr winInfo) -#else -tuiClearWinFocusFrom (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - if (m_winPtrNotNull (winInfo)) - { - if (winInfo->generic.type != CMD_WIN) - unhighlightWin (winInfo); - tuiSetWinWithFocus ((TuiWinInfoPtr) NULL); - } - - return; -} /* tuiClearWinFocusFrom */ - - -/* -** tuiClearWinFocus(). -** Clear the window that has focus. -*/ -void -#ifdef __STDC__ -tuiClearWinFocus (void) -#else -tuiClearWinFocus () -#endif -{ - tuiClearWinFocusFrom (tuiWinWithFocus ()); - - return; -} /* tuiClearWinFocus */ - - -/* -** tuiSetWinFocusTo -** Set the logical focus to winInfo -*/ -void -#ifdef __STDC__ -tuiSetWinFocusTo ( - TuiWinInfoPtr winInfo) -#else -tuiSetWinFocusTo (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - if (m_winPtrNotNull (winInfo)) - { - TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); - - if (m_winPtrNotNull (winWithFocus) && - winWithFocus->generic.type != CMD_WIN) - unhighlightWin (winWithFocus); - tuiSetWinWithFocus (winInfo); - if (winInfo->generic.type != CMD_WIN) - highlightWin (winInfo); - } - - return; -} /* tuiSetWinFocusTo */ - - -char * -#ifdef __STDC__ -tuiStrDup ( - char *str) -#else -tuiStrDup (str) - char *str; -#endif -{ - char *newStr = (char *) NULL; - - if (str != (char *) NULL) - { - newStr = (char *) xmalloc (strlen (str) + 1); - strcpy (newStr, str); - } - - return newStr; -} /* tuiStrDup */ - - -/* -** tuiScrollForward(). -*/ -void -#ifdef __STDC__ -tuiScrollForward ( - TuiWinInfoPtr winToScroll, - int numToScroll) -#else -tuiScrollForward (winToScroll, numToScroll) - TuiWinInfoPtr winToScroll; - int numToScroll; -#endif -{ - if (winToScroll != cmdWin) - { - int _numToScroll = numToScroll; - - if (numToScroll == 0) - _numToScroll = winToScroll->generic.height - 3; - /* - ** If we are scrolling the source or disassembly window, do a - ** "psuedo" scroll since not all of the source is in memory, - ** only what is in the viewport. If winToScroll is the - ** command window do nothing since the term should handle it. - */ - if (winToScroll == srcWin) - tuiVerticalSourceScroll (FORWARD_SCROLL, _numToScroll); - else if (winToScroll == disassemWin) - tuiVerticalDisassemScroll (FORWARD_SCROLL, _numToScroll); - else if (winToScroll == dataWin) - tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll); - } - - return; -} /* tuiScrollForward */ - - -/* -** tuiScrollBackward(). -*/ -void -#ifdef __STDC__ -tuiScrollBackward ( - TuiWinInfoPtr winToScroll, - int numToScroll) -#else -tuiScrollBackward (winToScroll, numToScroll) - TuiWinInfoPtr winToScroll; - int numToScroll; -#endif -{ - if (winToScroll != cmdWin) - { - int _numToScroll = numToScroll; - - if (numToScroll == 0) - _numToScroll = winToScroll->generic.height - 3; - /* - ** If we are scrolling the source or disassembly window, do a - ** "psuedo" scroll since not all of the source is in memory, - ** only what is in the viewport. If winToScroll is the - ** command window do nothing since the term should handle it. - */ - if (winToScroll == srcWin) - tuiVerticalSourceScroll (BACKWARD_SCROLL, _numToScroll); - else if (winToScroll == disassemWin) - tuiVerticalDisassemScroll (BACKWARD_SCROLL, _numToScroll); - else if (winToScroll == dataWin) - tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll); - } - return; -} /* tuiScrollBackward */ - - -/* -** tuiScrollLeft(). -*/ -void -#ifdef __STDC__ -tuiScrollLeft ( - TuiWinInfoPtr winToScroll, - int numToScroll) -#else -tuiScrollLeft (winToScroll, numToScroll) - TuiWinInfoPtr winToScroll; - int numToScroll; -#endif -{ - if (winToScroll != cmdWin) - { - int _numToScroll = numToScroll; - - if (_numToScroll == 0) - _numToScroll = 1; - /* - ** If we are scrolling the source or disassembly window, do a - ** "psuedo" scroll since not all of the source is in memory, - ** only what is in the viewport. If winToScroll is the - ** command window do nothing since the term should handle it. - */ - if (winToScroll == srcWin || winToScroll == disassemWin) - tuiHorizontalSourceScroll (winToScroll, LEFT_SCROLL, _numToScroll); - } - return; -} /* tuiScrollLeft */ - - -/* -** tuiScrollRight(). -*/ -void -#ifdef __STDC__ -tuiScrollRight ( - TuiWinInfoPtr winToScroll, - int numToScroll) -#else -tuiScrollRight (winToScroll, numToScroll) - TuiWinInfoPtr winToScroll; - int numToScroll; -#endif -{ - if (winToScroll != cmdWin) - { - int _numToScroll = numToScroll; - - if (_numToScroll == 0) - _numToScroll = 1; - /* - ** If we are scrolling the source or disassembly window, do a - ** "psuedo" scroll since not all of the source is in memory, - ** only what is in the viewport. If winToScroll is the - ** command window do nothing since the term should handle it. - */ - if (winToScroll == srcWin || winToScroll == disassemWin) - tuiHorizontalSourceScroll (winToScroll, RIGHT_SCROLL, _numToScroll); - } - return; -} /* tuiScrollRight */ - - -/* -** tui_vScroll(). -** Scroll a window. Arguments are passed through a va_list. -*/ -void -#ifdef __STDC__ -tui_vScroll ( - va_list args) -#else -tui_vScroll (args) - va_list args; -#endif -{ - TuiScrollDirection direction = va_arg (args, TuiScrollDirection); - TuiWinInfoPtr winToScroll = va_arg (args, TuiWinInfoPtr); - int numToScroll = va_arg (args, int); - - switch (direction) - { - case FORWARD_SCROLL: - tuiScrollForward (winToScroll, numToScroll); - break; - case BACKWARD_SCROLL: - tuiScrollBackward (winToScroll, numToScroll); - break; - case LEFT_SCROLL: - tuiScrollLeft (winToScroll, numToScroll); - break; - case RIGHT_SCROLL: - tuiScrollRight (winToScroll, numToScroll); - break; - default: - break; - } - - return; -} /* tui_vScroll */ - - -/* -** tuiRefreshAll(). -*/ -void -#ifdef __STDC__ -tuiRefreshAll (void) -#else -tuiRefreshAll () -#endif -{ - TuiWinType type; - - refreshAll (winList); - for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++) - { - if (winList[type]->generic.isVisible) - { - switch (type) - { - case SRC_WIN: - case DISASSEM_WIN: - tuiClearWin (&winList[type]->generic); - if (winList[type]->detail.sourceInfo.hasLocator) - tuiClearLocatorDisplay (); - tuiShowSourceContent (winList[type]); - checkAndDisplayHighlightIfNeeded (winList[type]); - tuiEraseExecInfoContent (winList[type]); - tuiUpdateExecInfo (winList[type]); - break; - case DATA_WIN: - tuiRefreshDataWin (); - break; - default: - break; - } - } - } - tuiClearLocatorDisplay (); - tuiShowLocatorContent (); - - return; -} /* tuiRefreshAll */ - - -/* -** tuiResizeAll(). -** Resize all the windows based on the the terminal size. This -** function gets called from within the readline sinwinch handler. -*/ -void -#ifdef __STDC__ -tuiResizeAll (void) -#else -tuiResizeAll () -#endif -{ - int heightDiff, widthDiff; - extern int screenheight, screenwidth; /* in readline */ - - widthDiff = screenwidth - termWidth (); - heightDiff = screenheight - termHeight (); - if (heightDiff || widthDiff) - { - TuiLayoutType curLayout = currentLayout (); - TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); - TuiWinInfoPtr firstWin, secondWin; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - TuiWinType winType; - int i, newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2; - - /* turn keypad off while we resize */ - if (winWithFocus != cmdWin) - keypad (cmdWin->generic.handle, FALSE); - init_page_info (); - setTermHeightTo (screenheight); - setTermWidthTo (screenwidth); - if (curLayout == SRC_DISASSEM_COMMAND || - curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND) - numWinsDisplayed++; - splitDiff = heightDiff / numWinsDisplayed; - cmdSplitDiff = splitDiff; - if (heightDiff % numWinsDisplayed) - { - if (heightDiff < 0) - cmdSplitDiff--; - else - cmdSplitDiff++; - } - /* now adjust each window */ - clear (); - refresh (); - switch (curLayout) - { - case SRC_COMMAND: - case DISASSEM_COMMAND: - firstWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; - firstWin->generic.width += widthDiff; - locator->width += widthDiff; - /* check for invalid heights */ - if (heightDiff == 0) - newHeight = firstWin->generic.height; - else if ((firstWin->generic.height + splitDiff) >= - (screenheight - MIN_CMD_WIN_HEIGHT - 1)) - newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1; - else if ((firstWin->generic.height + splitDiff) <= 0) - newHeight = MIN_WIN_HEIGHT; - else - newHeight = firstWin->generic.height + splitDiff; - - _makeInvisibleAndSetNewHeight (firstWin, newHeight); - cmdWin->generic.origin.y = locator->origin.y + 1; - cmdWin->generic.width += widthDiff; - newHeight = screenheight - cmdWin->generic.origin.y; - _makeInvisibleAndSetNewHeight (cmdWin, newHeight); - _makeVisibleWithNewHeight (firstWin); - _makeVisibleWithNewHeight (cmdWin); - if (firstWin->generic.contentSize <= 0) - tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT); - break; - default: - if (curLayout == SRC_DISASSEM_COMMAND) - { - firstWin = srcWin; - firstWin->generic.width += widthDiff; - secondWin = disassemWin; - secondWin->generic.width += widthDiff; - } - else - { - firstWin = dataWin; - firstWin->generic.width += widthDiff; - secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; - secondWin->generic.width += widthDiff; - } - /* Change the first window's height/width */ - /* check for invalid heights */ - if (heightDiff == 0) - newHeight = firstWin->generic.height; - else if ((firstWin->generic.height + - secondWin->generic.height + (splitDiff * 2)) >= - (screenheight - MIN_CMD_WIN_HEIGHT - 1)) - newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2; - else if ((firstWin->generic.height + splitDiff) <= 0) - newHeight = MIN_WIN_HEIGHT; - else - newHeight = firstWin->generic.height + splitDiff; - _makeInvisibleAndSetNewHeight (firstWin, newHeight); - - if (firstWin == dataWin && widthDiff != 0) - firstWin->detail.dataDisplayInfo.regsColumnCount = - tuiCalculateRegsColumnCount ( - firstWin->detail.dataDisplayInfo.regsDisplayType); - locator->width += widthDiff; - - /* Change the second window's height/width */ - /* check for invalid heights */ - if (heightDiff == 0) - newHeight = secondWin->generic.height; - else if ((firstWin->generic.height + - secondWin->generic.height + (splitDiff * 2)) >= - (screenheight - MIN_CMD_WIN_HEIGHT - 1)) - { - newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1; - if (newHeight % 2) - newHeight = (newHeight / 2) + 1; - else - newHeight /= 2; - } - else if ((secondWin->generic.height + splitDiff) <= 0) - newHeight = MIN_WIN_HEIGHT; - else - newHeight = secondWin->generic.height + splitDiff; - secondWin->generic.origin.y = firstWin->generic.height - 1; - _makeInvisibleAndSetNewHeight (secondWin, newHeight); - - /* Change the command window's height/width */ - cmdWin->generic.origin.y = locator->origin.y + 1; - _makeInvisibleAndSetNewHeight ( - cmdWin, cmdWin->generic.height + cmdSplitDiff); - _makeVisibleWithNewHeight (firstWin); - _makeVisibleWithNewHeight (secondWin); - _makeVisibleWithNewHeight (cmdWin); - if (firstWin->generic.contentSize <= 0) - tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT); - if (secondWin->generic.contentSize <= 0) - tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT); - break; - } - /* - ** Now remove all invisible windows, and their content so that they get - ** created again when called for with the new size - */ - for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++) - { - if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) && - !winList[winType]->generic.isVisible) - { - freeWindow (winList[winType]); - winList[winType] = (TuiWinInfoPtr) NULL; - } - } - tuiSetWinResizedTo (TRUE); - /* turn keypad back on, unless focus is in the command window */ - if (winWithFocus != cmdWin) - keypad (cmdWin->generic.handle, TRUE); - } - return; -} /* tuiResizeAll */ - - -/* -** tuiSigwinchHandler() -** SIGWINCH signal handler for the tui. This signal handler is -** always called, even when the readline package clears signals -** because it is set as the old_sigwinch() (TUI only) -*/ -void -#ifdef __STDC__ -tuiSigwinchHandler ( - int signal) -#else -tuiSigwinchHandler (signal) - int signal; -#endif -{ - /* - ** Say that a resize was done so that the readline can do it - ** later when appropriate. - */ - tuiSetWinResizedTo (TRUE); - - return; -} /* tuiSigwinchHandler */ - - - -/************************* -** STATIC LOCAL FUNCTIONS -**************************/ - - -/* -** _tuiScrollForward_command(). -*/ -static void -#ifdef __STDC__ -_tuiScrollForward_command ( - char *arg, - int fromTTY) -#else -_tuiScrollForward_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - int numToScroll = 1; - TuiWinInfoPtr winToScroll; - - if (arg == (char *) NULL) - _parseScrollingArgs (arg, &winToScroll, (int *) NULL); - else - _parseScrollingArgs (arg, &winToScroll, &numToScroll); - tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, - FORWARD_SCROLL, - winToScroll, - numToScroll); - - return; -} /* _tuiScrollForward_command */ - - -/* -** _tuiScrollBackward_command(). -*/ -static void -#ifdef __STDC__ -_tuiScrollBackward_command ( - char *arg, - int fromTTY) -#else -_tuiScrollBackward_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - int numToScroll = 1; - TuiWinInfoPtr winToScroll; - - if (arg == (char *) NULL) - _parseScrollingArgs (arg, &winToScroll, (int *) NULL); - else - _parseScrollingArgs (arg, &winToScroll, &numToScroll); - tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, - BACKWARD_SCROLL, - winToScroll, - numToScroll); - - return; -} /* _tuiScrollBackward_command */ - - -/* -** _tuiScrollLeft_command(). -*/ -static void -#ifdef __STDC__ -_tuiScrollLeft_command ( - char *arg, - int fromTTY) -#else -_tuiScrollLeft_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - int numToScroll; - TuiWinInfoPtr winToScroll; - - _parseScrollingArgs (arg, &winToScroll, &numToScroll); - tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, - LEFT_SCROLL, - winToScroll, - numToScroll); - - return; -} /* _tuiScrollLeft_command */ - - -/* -** _tuiScrollRight_command(). -*/ -static void -#ifdef __STDC__ -_tuiScrollRight_command ( - char *arg, - int fromTTY) -#else -_tuiScrollRight_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - int numToScroll; - TuiWinInfoPtr winToScroll; - - _parseScrollingArgs (arg, &winToScroll, &numToScroll); - tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, - RIGHT_SCROLL, - winToScroll, - numToScroll); - - return; -} /* _tuiScrollRight_command */ - - -/* -** _tuiSetFocus(). -** Set focus to the window named by 'arg' -*/ -static void -#ifdef __STDC__ -_tuiSetFocus ( - char *arg, - int fromTTY) -#else -_tuiSetFocus (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - if (arg != (char *) NULL) - { - char *bufPtr = (char *) tuiStrDup (arg); - int i; - TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL; - - for (i = 0; (i < strlen (bufPtr)); i++) - bufPtr[i] = toupper (arg[i]); - - if (subsetCompare (bufPtr, "NEXT")) - winInfo = tuiNextWin (tuiWinWithFocus ()); - else if (subsetCompare (bufPtr, "PREV")) - winInfo = tuiPrevWin (tuiWinWithFocus ()); - else - winInfo = partialWinByName (bufPtr); - - if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible) - warning ("Invalid window specified. \n\ -The window name specified must be valid and visible.\n"); - else - { - tuiSetWinFocusTo (winInfo); - keypad (cmdWin->generic.handle, (winInfo != cmdWin)); - } - - if (dataWin->generic.isVisible) - tuiRefreshDataWin (); - tuiFree (bufPtr); - printf_filtered ("Focus set to %s window.\n", - winName ((TuiGenWinInfoPtr) tuiWinWithFocus ())); - } - else - warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE); - - return; -} /* _tuiSetFocus */ - - -/* -** _tui_vSetFocus() -*/ -static void -#ifdef __STDC__ -_tui_vSetFocus ( - va_list args) -#else -_tui_vSetFocus (args) - va_list args; -#endif -{ - char *arg = va_arg (args, char *); - int fromTTY = va_arg (args, int); - - _tuiSetFocus (arg, fromTTY); - - return; -} /* tui_vSetFocus */ - - -/* -** _tuiSetFocus_command() -*/ -static void -#ifdef __STDC__ -_tuiSetFocus_command ( - char *arg, - int fromTTY) -#else -_tuiSetFocus_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) _tui_vSetFocus, arg, fromTTY); - - return; -} /* tui_SetFocus */ - - -/* -** _tuiAllWindowsInfo(). -*/ -static void -#ifdef __STDC__ -_tuiAllWindowsInfo ( - char *arg, - int fromTTY) -#else -_tuiAllWindowsInfo (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - TuiWinType type; - TuiWinInfoPtr winWithFocus = tuiWinWithFocus (); - - for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) - if (winList[type]->generic.isVisible) - { - if (winWithFocus == winList[type]) - printf_filtered (" %s\t(%d lines) \n", - winName (&winList[type]->generic), - winList[type]->generic.height); - else - printf_filtered (" %s\t(%d lines)\n", - winName (&winList[type]->generic), - winList[type]->generic.height); - } - - return; -} /* _tuiAllWindowsInfo */ - - -/* -** _tuiRefreshAll_command(). -*/ -static void -#ifdef __STDC__ -_tuiRefreshAll_command ( - char *arg, - int fromTTY) -#else -_tuiRefreshAll_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll); -} - - -/* -** _tuiSetWinTabWidth_command(). -** Set the height of the specified window. -*/ -static void -#ifdef __STDC__ -_tuiSetTabWidth_command ( - char *arg, - int fromTTY) -#else -_tuiSetTabWidth_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - if (arg != (char *) NULL) - { - int ts; - - ts = atoi (arg); - if (ts > 0) - tuiSetDefaultTabLen (ts); - else - warning ("Tab widths greater than 0 must be specified.\n"); - } - - return; -} /* _tuiSetTabWidth_command */ - - -/* -** _tuiSetWinHeight(). -** Set the height of the specified window. -*/ -static void -#ifdef __STDC__ -_tuiSetWinHeight ( - char *arg, - int fromTTY) -#else -_tuiSetWinHeight (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - if (arg != (char *) NULL) - { - char *buf = tuiStrDup (arg); - char *bufPtr = buf; - char *wname = (char *) NULL; - int newHeight, i; - TuiWinInfoPtr winInfo; - - wname = bufPtr; - bufPtr = strchr (bufPtr, ' '); - if (bufPtr != (char *) NULL) - { - *bufPtr = (char) 0; - - /* - ** Validate the window name - */ - for (i = 0; i < strlen (wname); i++) - wname[i] = toupper (wname[i]); - winInfo = partialWinByName (wname); - - if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible) - warning ("Invalid window specified. \n\ -The window name specified must be valid and visible.\n"); - else - { - /* Process the size */ - while (*(++bufPtr) == ' ') - ; - - if (*bufPtr != (char) 0) - { - int negate = FALSE; - int fixedSize = TRUE; - int inputNo;; - - if (*bufPtr == '+' || *bufPtr == '-') - { - if (*bufPtr == '-') - negate = TRUE; - fixedSize = FALSE; - bufPtr++; - } - inputNo = atoi (bufPtr); - if (inputNo > 0) - { - if (negate) - inputNo *= (-1); - if (fixedSize) - newHeight = inputNo; - else - newHeight = winInfo->generic.height + inputNo; - /* - ** Now change the window's height, and adjust all - ** other windows around it - */ - if (_tuiAdjustWinHeights (winInfo, - newHeight) == TUI_FAILURE) - warning ("Invalid window height specified.\n%s", - WIN_HEIGHT_USAGE); - else - init_page_info (); - } - else - warning ("Invalid window height specified.\n%s", - WIN_HEIGHT_USAGE); - } - } - } - else - printf_filtered (WIN_HEIGHT_USAGE); - - if (buf != (char *) NULL) - tuiFree (buf); - } - else - printf_filtered (WIN_HEIGHT_USAGE); - - return; -} /* _tuiSetWinHeight */ - - -/* -** _tui_vSetWinHeight(). -** Set the height of the specified window, with va_list. -*/ -static void -#ifdef __STDC__ -_tui_vSetWinHeight ( - va_list args) -#else -_tui_vSetWinHeight (args) - va_list args; -#endif -{ - char *arg = va_arg (args, char *); - int fromTTY = va_arg (args, int); - - _tuiSetWinHeight (arg, fromTTY); - - return; -} /* _tui_vSetWinHeight */ - - -/* -** _tuiSetWinHeight_command(). -** Set the height of the specified window, with va_list. -*/ -static void -#ifdef __STDC__ -_tuiSetWinHeight_command ( - char *arg, - int fromTTY) -#else -_tuiSetWinHeight_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) _tui_vSetWinHeight, arg, fromTTY); - - return; -} /* _tuiSetWinHeight_command */ - - -/* -** _tuiXDBsetWinHeight(). -** XDB Compatibility command for setting the window height. This will -** increase or decrease the command window by the specified amount. -*/ -static void -#ifdef __STDC__ -_tuiXDBsetWinHeight ( - char *arg, - int fromTTY) -#else -_tuiXDBsetWinHeight (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - if (arg != (char *) NULL) - { - int inputNo = atoi (arg); - - if (inputNo > 0) - { /* Add 1 for the locator */ - int newHeight = termHeight () - (inputNo + 1); - - if (!_newHeightOk (winList[CMD_WIN], newHeight) || - _tuiAdjustWinHeights (winList[CMD_WIN], - newHeight) == TUI_FAILURE) - warning ("Invalid window height specified.\n%s", - XDBWIN_HEIGHT_USAGE); - } - else - warning ("Invalid window height specified.\n%s", - XDBWIN_HEIGHT_USAGE); - } - else - warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE); - - return; -} /* _tuiXDBsetWinHeight */ - - -/* -** _tui_vXDBsetWinHeight(). -** Set the height of the specified window, with va_list. -*/ -static void -#ifdef __STDC__ -_tui_vXDBsetWinHeight ( - va_list args) -#else -_tui_vXDBsetWinHeight (args) - va_list args; -#endif -{ - char *arg = va_arg (args, char *); - int fromTTY = va_arg (args, int); - - _tuiXDBsetWinHeight (arg, fromTTY); - - return; -} /* _tui_vXDBsetWinHeight */ - - -/* -** _tuiSetWinHeight_command(). -** Set the height of the specified window, with va_list. -*/ -static void -#ifdef __STDC__ -_tuiXDBsetWinHeight_command ( - char *arg, - int fromTTY) -#else -_tuiXDBsetWinHeight_command (arg, fromTTY) - char *arg; - int fromTTY; -#endif -{ - tuiDo ((TuiOpaqueFuncPtr) _tui_vXDBsetWinHeight, arg, fromTTY); - - return; -} /* _tuiXDBsetWinHeight_command */ - - -/* -** _tuiAdjustWinHeights(). -** Function to adjust all window heights around the primary -*/ -static TuiStatus -#ifdef __STDC__ -_tuiAdjustWinHeights ( - TuiWinInfoPtr primaryWinInfo, - int newHeight) -#else -_tuiAdjustWinHeights (primaryWinInfo, newHeight) - TuiWinInfoPtr primaryWinInfo; - int newHeight; -#endif -{ - TuiStatus status = TUI_FAILURE; - - if (_newHeightOk (primaryWinInfo, newHeight)) - { - status = TUI_SUCCESS; - if (newHeight != primaryWinInfo->generic.height) - { - int i, diff; - TuiWinInfoPtr winInfo; - TuiGenWinInfoPtr locator = locatorWinInfoPtr (); - TuiLayoutType curLayout = currentLayout (); - - diff = (newHeight - primaryWinInfo->generic.height) * (-1); - if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND) - { - TuiWinInfoPtr srcWinInfo; - - _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight); - if (primaryWinInfo->generic.type == CMD_WIN) - { - winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0]; - srcWinInfo = winInfo; - } - else - { - winInfo = winList[CMD_WIN]; - srcWinInfo = primaryWinInfo; - } - _makeInvisibleAndSetNewHeight (winInfo, - winInfo->generic.height + diff); - cmdWin->generic.origin.y = locator->origin.y + 1; - _makeVisibleWithNewHeight (winInfo); - _makeVisibleWithNewHeight (primaryWinInfo); - if (srcWinInfo->generic.contentSize <= 0) - tuiEraseSourceContent (srcWinInfo, EMPTY_SOURCE_PROMPT); - } - else - { - TuiWinInfoPtr firstWin, secondWin; - - if (curLayout == SRC_DISASSEM_COMMAND) - { - firstWin = srcWin; - secondWin = disassemWin; - } - else - { - firstWin = dataWin; - secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; - } - if (primaryWinInfo == cmdWin) - { /* - ** Split the change in height accross the 1st & 2nd windows - ** adjusting them as well. - */ - int firstSplitDiff = diff / 2; /* subtract the locator */ - int secondSplitDiff = firstSplitDiff; - - if (diff % 2) - { - if (firstWin->generic.height > - secondWin->generic.height) - if (diff < 0) - firstSplitDiff--; - else - firstSplitDiff++; - else - { - if (diff < 0) - secondSplitDiff--; - else - secondSplitDiff++; - } - } - /* make sure that the minimum hieghts are honored */ - while ((firstWin->generic.height + firstSplitDiff) < 3) - { - firstSplitDiff++; - secondSplitDiff--; - } - while ((secondWin->generic.height + secondSplitDiff) < 3) - { - secondSplitDiff++; - firstSplitDiff--; - } - _makeInvisibleAndSetNewHeight ( - firstWin, - firstWin->generic.height + firstSplitDiff); - secondWin->generic.origin.y = firstWin->generic.height - 1; - _makeInvisibleAndSetNewHeight ( - secondWin, secondWin->generic.height + secondSplitDiff); - cmdWin->generic.origin.y = locator->origin.y + 1; - _makeInvisibleAndSetNewHeight (cmdWin, newHeight); - } - else - { - if ((cmdWin->generic.height + diff) < 1) - { /* - ** If there is no way to increase the command window - ** take real estate from the 1st or 2nd window. - */ - if ((cmdWin->generic.height + diff) < 1) - { - int i; - for (i = cmdWin->generic.height + diff; - (i < 1); i++) - if (primaryWinInfo == firstWin) - secondWin->generic.height--; - else - firstWin->generic.height--; - } - } - if (primaryWinInfo == firstWin) - _makeInvisibleAndSetNewHeight (firstWin, newHeight); - else - _makeInvisibleAndSetNewHeight ( - firstWin, - firstWin->generic.height); - secondWin->generic.origin.y = firstWin->generic.height - 1; - if (primaryWinInfo == secondWin) - _makeInvisibleAndSetNewHeight (secondWin, newHeight); - else - _makeInvisibleAndSetNewHeight ( - secondWin, secondWin->generic.height); - cmdWin->generic.origin.y = locator->origin.y + 1; - if ((cmdWin->generic.height + diff) < 1) - _makeInvisibleAndSetNewHeight (cmdWin, 1); - else - _makeInvisibleAndSetNewHeight ( - cmdWin, cmdWin->generic.height + diff); - } - _makeVisibleWithNewHeight (cmdWin); - _makeVisibleWithNewHeight (secondWin); - _makeVisibleWithNewHeight (firstWin); - if (firstWin->generic.contentSize <= 0) - tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT); - if (secondWin->generic.contentSize <= 0) - tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT); - } - } - } - - return status; -} /* _tuiAdjustWinHeights */ - - -/* -** _makeInvisibleAndSetNewHeight(). -** Function make the target window (and auxillary windows associated -** with the targer) invisible, and set the new height and location. -*/ -static void -#ifdef __STDC__ -_makeInvisibleAndSetNewHeight ( - TuiWinInfoPtr winInfo, - int height) -#else -_makeInvisibleAndSetNewHeight (winInfo, height) - TuiWinInfoPtr winInfo; - int height; -#endif -{ - int i; - struct symtab *s; - TuiGenWinInfoPtr genWinInfo; - - - m_beInvisible (&winInfo->generic); - winInfo->generic.height = height; - if (height > 1) - winInfo->generic.viewportHeight = height - 1; - else - winInfo->generic.viewportHeight = height; - if (winInfo != cmdWin) - winInfo->generic.viewportHeight--; - - /* Now deal with the auxillary windows associated with winInfo */ - switch (winInfo->generic.type) - { - case SRC_WIN: - case DISASSEM_WIN: - genWinInfo = winInfo->detail.sourceInfo.executionInfo; - m_beInvisible (genWinInfo); - genWinInfo->height = height; - genWinInfo->origin.y = winInfo->generic.origin.y; - if (height > 1) - genWinInfo->viewportHeight = height - 1; - else - genWinInfo->viewportHeight = height; - if (winInfo != cmdWin) - genWinInfo->viewportHeight--; - - if (m_hasLocator (winInfo)) - { - genWinInfo = locatorWinInfoPtr (); - m_beInvisible (genWinInfo); - genWinInfo->origin.y = winInfo->generic.origin.y + height; - } - break; - case DATA_WIN: - /* delete all data item windows */ - for (i = 0; i < winInfo->generic.contentSize; i++) - { - genWinInfo = (TuiGenWinInfoPtr) & ((TuiWinElementPtr) - winInfo->generic.content[i])->whichElement.dataWindow; - tuiDelwin (genWinInfo->handle); - genWinInfo->handle = (WINDOW *) NULL; - } - break; - default: - break; - } - - return; -} /* _makeInvisibleAndSetNewHeight */ - - -/* -** _makeVisibleWithNewHeight(). -** Function to make the windows with new heights visible. -** This means re-creating the windows' content since the window -** had to be destroyed to be made invisible. -*/ -static void -#ifdef __STDC__ -_makeVisibleWithNewHeight ( - TuiWinInfoPtr winInfo) -#else -_makeVisibleWithNewHeight (winInfo) - TuiWinInfoPtr winInfo; -#endif -{ - int i; - struct symtab *s; - - m_beVisible (&winInfo->generic); - checkAndDisplayHighlightIfNeeded (winInfo); - switch (winInfo->generic.type) - { - case SRC_WIN: - case DISASSEM_WIN: - freeWinContent (winInfo->detail.sourceInfo.executionInfo); - m_beVisible (winInfo->detail.sourceInfo.executionInfo); - if (winInfo->generic.content != (OpaquePtr) NULL) - { - TuiLineOrAddress lineOrAddr; - - if (winInfo->generic.type == SRC_WIN) - lineOrAddr.lineNo = - winInfo->detail.sourceInfo.startLineOrAddr.lineNo; - else - lineOrAddr.addr = - winInfo->detail.sourceInfo.startLineOrAddr.addr; - freeWinContent (&winInfo->generic); - tuiUpdateSourceWindow (winInfo, - current_source_symtab, - ((winInfo->generic.type == SRC_WIN) ? - (Opaque) lineOrAddr.lineNo : - lineOrAddr.addr), - TRUE); - } - else if (selected_frame != (struct frame_info *) NULL) - { - Opaque line = 0; - extern int current_source_line; - - s = find_pc_symtab (selected_frame->pc); - if (winInfo->generic.type == SRC_WIN) - line = (Opaque) current_source_line; - else - line = (Opaque) find_line_pc (s, current_source_line); - tuiUpdateSourceWindow (winInfo, s, line, TRUE); - } - if (m_hasLocator (winInfo)) - { - m_beVisible (locatorWinInfoPtr ()); - tuiClearLocatorDisplay (); - tuiShowLocatorContent (); - } - break; - case DATA_WIN: - tuiDisplayAllData (); - break; - case CMD_WIN: - winInfo->detail.commandInfo.curLine = 0; - winInfo->detail.commandInfo.curch = 0; - wmove (winInfo->generic.handle, - winInfo->detail.commandInfo.curLine, - winInfo->detail.commandInfo.curch); - break; - default: - break; - } - - return; -} /* _makeVisibleWithNewHeight */ - - -static int -#ifdef __STDC__ -_newHeightOk ( - TuiWinInfoPtr primaryWinInfo, - int newHeight) -#else -_newHeightOk (primaryWinInfo, newHeight) - TuiWinInfoPtr primaryWinInfo; - int newHeight; -#endif -{ - int ok = (newHeight < termHeight ()); - - if (ok) - { - int diff, curHeight; - TuiLayoutType curLayout = currentLayout (); - - diff = (newHeight - primaryWinInfo->generic.height) * (-1); - if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND) - { - ok = ((primaryWinInfo->generic.type == CMD_WIN && - newHeight <= (termHeight () - 4) && - newHeight >= MIN_CMD_WIN_HEIGHT) || - (primaryWinInfo->generic.type != CMD_WIN && - newHeight <= (termHeight () - 2) && - newHeight >= MIN_WIN_HEIGHT)); - if (ok) - { /* check the total height */ - TuiWinInfoPtr winInfo; - - if (primaryWinInfo == cmdWin) - winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0]; - else - winInfo = cmdWin; - ok = ((newHeight + - (winInfo->generic.height + diff)) <= termHeight ()); - } - } - else - { - int curTotalHeight, totalHeight, minHeight; - TuiWinInfoPtr firstWin, secondWin; - - if (curLayout == SRC_DISASSEM_COMMAND) - { - firstWin = srcWin; - secondWin = disassemWin; - } - else - { - firstWin = dataWin; - secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0]; - } - /* - ** We could simply add all the heights to obtain the same result - ** but below is more explicit since we subtract 1 for the - ** line that the first and second windows share, and add one - ** for the locator. - */ - curTotalHeight = - (firstWin->generic.height + secondWin->generic.height - 1) - + cmdWin->generic.height + 1 /*locator*/ ; - if (primaryWinInfo == cmdWin) - { - /* locator included since first & second win share a line */ - ok = ((firstWin->generic.height + - secondWin->generic.height + diff) >= - (MIN_WIN_HEIGHT * 2) && - newHeight >= MIN_CMD_WIN_HEIGHT); - if (ok) - { - totalHeight = newHeight + (firstWin->generic.height + - secondWin->generic.height + diff); - minHeight = MIN_CMD_WIN_HEIGHT; - } - } - else - { - minHeight = MIN_WIN_HEIGHT; - /* - ** First see if we can increase/decrease the command - ** window. And make sure that the command window is - ** at least 1 line - */ - ok = ((cmdWin->generic.height + diff) > 0); - if (!ok) - { /* - ** Looks like we have to increase/decrease one of - ** the other windows - */ - if (primaryWinInfo == firstWin) - ok = (secondWin->generic.height + diff) >= minHeight; - else - ok = (firstWin->generic.height + diff) >= minHeight; - } - if (ok) - { - if (primaryWinInfo == firstWin) - totalHeight = newHeight + - secondWin->generic.height + - cmdWin->generic.height + diff; - else - totalHeight = newHeight + - firstWin->generic.height + - cmdWin->generic.height + diff; - } - } - /* - ** Now make sure that the proposed total height doesn't exceed - ** the old total height. - */ - if (ok) - ok = (newHeight >= minHeight && totalHeight <= curTotalHeight); - } - } - - return ok; -} /* _newHeightOk */ - - -/* -** _parseScrollingArgs(). -*/ -static void -#ifdef __STDC__ -_parseScrollingArgs ( - char *arg, - TuiWinInfoPtr * winToScroll, - int *numToScroll) -#else -_parseScrollingArgs (arg, winToScroll, numToScroll) - char *arg; - TuiWinInfoPtr *winToScroll; - int *numToScroll; -#endif -{ - if (numToScroll) - *numToScroll = 0; - *winToScroll = tuiWinWithFocus (); - - /* - ** First set up the default window to scroll, in case there is no - ** window name arg - */ - if (arg != (char *) NULL) - { - char *buf, *bufPtr; - - /* process the number of lines to scroll */ - buf = bufPtr = tuiStrDup (arg); - if (isdigit (*bufPtr)) - { - char *numStr; - - numStr = bufPtr; - bufPtr = strchr (bufPtr, ' '); - if (bufPtr != (char *) NULL) - { - *bufPtr = (char) 0; - if (numToScroll) - *numToScroll = atoi (numStr); - bufPtr++; - } - else if (numToScroll) - *numToScroll = atoi (numStr); - } - - /* process the window name if one is specified */ - if (bufPtr != (char *) NULL) - { - char *wname; - int i; - - if (*bufPtr == ' ') - while (*(++bufPtr) == ' ') - ; - - if (*bufPtr != (char) 0) - wname = bufPtr; - - /* Validate the window name */ - for (i = 0; i < strlen (wname); i++) - wname[i] = toupper (wname[i]); - *winToScroll = partialWinByName (wname); - - if (*winToScroll == (TuiWinInfoPtr) NULL || - !(*winToScroll)->generic.isVisible) - warning ("Invalid window specified. \n\ -The window name specified must be valid and visible.\n"); - else if (*winToScroll == cmdWin) - *winToScroll = (TuiWinInfoPtr) (sourceWindows ())->list[0]; - } - tuiFree (buf); - } - - return; -} /* _parseScrollingArgs */ diff --git a/contrib/gdb/gdb/tui/tuiWin.h b/contrib/gdb/gdb/tui/tuiWin.h deleted file mode 100644 index cb8455dd8e0..00000000000 --- a/contrib/gdb/gdb/tui/tuiWin.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _TUI_WIN_H -#define _TUI_WIN_H -/* -** This header file supports -*/ - -/***************************************** -** TYPE DEFINITIONS ** -******************************************/ - - - -/***************************************** -** PUBLIC FUNCTION EXTERNAL DECLS ** -******************************************/ -extern void tuiScrollForward PARAMS ((TuiWinInfoPtr, int)); -extern void tuiScrollBackward PARAMS ((TuiWinInfoPtr, int)); -extern void tuiScrollLeft PARAMS ((TuiWinInfoPtr, int)); -extern void tuiScrollRight PARAMS ((TuiWinInfoPtr, int)); -extern void tui_vScroll PARAMS ((va_list)); -extern void tuiSetWinFocusTo PARAMS ((TuiWinInfoPtr)); -extern void tuiClearWinFocusFrom PARAMS ((TuiWinInfoPtr)); -extern void tuiClearWinFocus PARAMS ((void)); -extern void tuiResizeAll PARAMS ((void)); -extern void tuiRefreshAll PARAMS ((void)); -extern void tuiSigwinchHandler PARAMS ((int)); - -#endif /*_TUI_WIN_H*/ diff --git a/contrib/gdb/gdb/umax-xdep.c b/contrib/gdb/gdb/umax-xdep.c deleted file mode 100644 index d54519e6384..00000000000 --- a/contrib/gdb/gdb/umax-xdep.c +++ /dev/null @@ -1,133 +0,0 @@ -/* umax host stuff. - Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" - -#include -#include -#include -#include -#include - -#include "gdbcore.h" -#include -#define PTRACE_ATTACH PT_ATTACH -#define PTRACE_DETACH PT_FREEPROC - -#include -#include "gdb_stat.h" - -/* Work with core dump and executable files, for GDB. - This code would be in corefile.c if it weren't machine-dependent. */ - -void -core_file_command (filename, from_tty) - char *filename; - int from_tty; -{ - int val; - extern char registers[]; - - /* Discard all vestiges of any previous core file - and mark data and stack spaces as empty. */ - - if (corefile) - free (corefile); - corefile = 0; - - if (corechan >= 0) - close (corechan); - corechan = -1; - - data_start = 0; - data_end = 0; - stack_start = STACK_END_ADDR; - stack_end = STACK_END_ADDR; - - /* Now, if a new core file was specified, open it and digest it. */ - - if (filename) - { - filename = tilde_expand (filename); - make_cleanup (free, filename); - - if (have_inferior_p ()) - error ("To look at a core file, you must kill the program with \"kill\"."); - corechan = open (filename, O_RDONLY, 0); - if (corechan < 0) - perror_with_name (filename); - /* 4.2-style (and perhaps also sysV-style) core dump file. */ - { - struct ptrace_user u; - int reg_offset; - - val = myread (corechan, &u, sizeof u); - if (val < 0) - perror_with_name (filename); - data_start = exec_data_start; - - data_end = data_start + u.pt_dsize; - stack_start = stack_end - u.pt_ssize; - data_offset = sizeof u; - stack_offset = data_offset + u.pt_dsize; - reg_offset = 0; - - memcpy (&core_aouthdr, &u.pt_aouthdr, sizeof (AOUTHDR)); - printf_unfiltered ("Core file is from \"%s\".\n", u.pt_comm); - if (u.pt_signal > 0) - printf_unfiltered ("Program terminated with signal %d, %s.\n", - u.pt_signal, safe_strsignal (u.pt_signal)); - - /* Read the register values out of the core file and store - them where `read_register' will find them. */ - - { - register int regno; - - for (regno = 0; regno < NUM_REGS; regno++) - { - char buf[MAX_REGISTER_RAW_SIZE]; - - val = lseek (corechan, register_addr (regno, reg_offset), 0); - if (val < 0) - perror_with_name (filename); - - val = myread (corechan, buf, sizeof buf); - if (val < 0) - perror_with_name (filename); - supply_register (regno, buf); - } - } - } - if (filename[0] == '/') - corefile = savestring (filename, strlen (filename)); - else - { - corefile = concat (current_directory, "/", filename, NULL); - } - - flush_cached_frames (); - select_frame (get_current_frame (), 0); - validate_files (); - } - else if (from_tty) - printf_unfiltered ("No core file now.\n"); -} diff --git a/contrib/gdb/gdb/v850-tdep.c b/contrib/gdb/gdb/v850-tdep.c deleted file mode 100644 index 534e9565066..00000000000 --- a/contrib/gdb/gdb/v850-tdep.c +++ /dev/null @@ -1,862 +0,0 @@ -/* Target-dependent code for the NEC V850 for GDB, the GNU debugger. - Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "obstack.h" -#include "target.h" -#include "value.h" -#include "bfd.h" -#include "gdb_string.h" -#include "gdbcore.h" -#include "symfile.h" -#include "arch-utils.h" -#include "regcache.h" - - -static char *v850_generic_reg_names[] = REGISTER_NAMES; - -static char *v850e_reg_names[] = -{ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7", - "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15", - "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23", - "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31", - "pc", "fp" -}; - -char **v850_register_names = v850_generic_reg_names; - -struct - { - char **regnames; - int mach; - } -v850_processor_type_table[] = -{ - { - v850_generic_reg_names, bfd_mach_v850 - } - , - { - v850e_reg_names, bfd_mach_v850e - } - , - { - v850e_reg_names, bfd_mach_v850ea - } - , - { - NULL, 0 - } -}; - -/* Info gleaned from scanning a function's prologue. */ - -struct pifsr /* Info about one saved reg */ - { - int framereg; /* Frame reg (SP or FP) */ - int offset; /* Offset from framereg */ - int cur_frameoffset; /* Current frameoffset */ - int reg; /* Saved register number */ - }; - -struct prologue_info - { - int framereg; - int frameoffset; - int start_function; - struct pifsr *pifsrs; - }; - -static CORE_ADDR v850_scan_prologue (CORE_ADDR pc, struct prologue_info *fs); - - -/* Should call_function allocate stack space for a struct return? */ -int -v850_use_struct_convention (int gcc_p, struct type *type) -{ - return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 4); -} - - - -/* Structure for mapping bits in register lists to register numbers. */ -struct reg_list -{ - long mask; - int regno; -}; - -/* Helper function for v850_scan_prologue to handle prepare instruction. */ - -static void -handle_prepare (int insn, int insn2, CORE_ADDR * current_pc_ptr, - struct prologue_info *pi, struct pifsr **pifsr_ptr) -{ - CORE_ADDR current_pc = *current_pc_ptr; - struct pifsr *pifsr = *pifsr_ptr; - long next = insn2 & 0xffff; - long list12 = ((insn & 1) << 16) + (next & 0xffe0); - long offset = (insn & 0x3e) << 1; - static struct reg_list reg_table[] = - { - {0x00800, 20}, /* r20 */ - {0x00400, 21}, /* r21 */ - {0x00200, 22}, /* r22 */ - {0x00100, 23}, /* r23 */ - {0x08000, 24}, /* r24 */ - {0x04000, 25}, /* r25 */ - {0x02000, 26}, /* r26 */ - {0x01000, 27}, /* r27 */ - {0x00080, 28}, /* r28 */ - {0x00040, 29}, /* r29 */ - {0x10000, 30}, /* ep */ - {0x00020, 31}, /* lp */ - {0, 0} /* end of table */ - }; - int i; - - if ((next & 0x1f) == 0x0b) /* skip imm16 argument */ - current_pc += 2; - else if ((next & 0x1f) == 0x13) /* skip imm16 argument */ - current_pc += 2; - else if ((next & 0x1f) == 0x1b) /* skip imm32 argument */ - current_pc += 4; - - /* Calculate the total size of the saved registers, and add it - it to the immediate value used to adjust SP. */ - for (i = 0; reg_table[i].mask != 0; i++) - if (list12 & reg_table[i].mask) - offset += REGISTER_RAW_SIZE (regtable[i].regno); - pi->frameoffset -= offset; - - /* Calculate the offsets of the registers relative to the value - the SP will have after the registers have been pushed and the - imm5 value has been subtracted from it. */ - if (pifsr) - { - for (i = 0; reg_table[i].mask != 0; i++) - { - if (list12 & reg_table[i].mask) - { - int reg = reg_table[i].regno; - offset -= REGISTER_RAW_SIZE (reg); - pifsr->reg = reg; - pifsr->offset = offset; - pifsr->cur_frameoffset = pi->frameoffset; -#ifdef DEBUG - printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset); -#endif - pifsr++; - } - } - } -#ifdef DEBUG - printf_filtered ("\tfound ctret after regsave func"); -#endif - - /* Set result parameters. */ - *current_pc_ptr = current_pc; - *pifsr_ptr = pifsr; -} - - -/* Helper function for v850_scan_prologue to handle pushm/pushl instructions. - FIXME: the SR bit of the register list is not supported; must check - that the compiler does not ever generate this bit. */ - -static void -handle_pushm (int insn, int insn2, struct prologue_info *pi, - struct pifsr **pifsr_ptr) -{ - struct pifsr *pifsr = *pifsr_ptr; - long list12 = ((insn & 0x0f) << 16) + (insn2 & 0xfff0); - long offset = 0; - static struct reg_list pushml_reg_table[] = - { - {0x80000, PS_REGNUM}, /* PSW */ - {0x40000, 1}, /* r1 */ - {0x20000, 2}, /* r2 */ - {0x10000, 3}, /* r3 */ - {0x00800, 4}, /* r4 */ - {0x00400, 5}, /* r5 */ - {0x00200, 6}, /* r6 */ - {0x00100, 7}, /* r7 */ - {0x08000, 8}, /* r8 */ - {0x04000, 9}, /* r9 */ - {0x02000, 10}, /* r10 */ - {0x01000, 11}, /* r11 */ - {0x00080, 12}, /* r12 */ - {0x00040, 13}, /* r13 */ - {0x00020, 14}, /* r14 */ - {0x00010, 15}, /* r15 */ - {0, 0} /* end of table */ - }; - static struct reg_list pushmh_reg_table[] = - { - {0x80000, 16}, /* r16 */ - {0x40000, 17}, /* r17 */ - {0x20000, 18}, /* r18 */ - {0x10000, 19}, /* r19 */ - {0x00800, 20}, /* r20 */ - {0x00400, 21}, /* r21 */ - {0x00200, 22}, /* r22 */ - {0x00100, 23}, /* r23 */ - {0x08000, 24}, /* r24 */ - {0x04000, 25}, /* r25 */ - {0x02000, 26}, /* r26 */ - {0x01000, 27}, /* r27 */ - {0x00080, 28}, /* r28 */ - {0x00040, 29}, /* r29 */ - {0x00010, 30}, /* r30 */ - {0x00020, 31}, /* r31 */ - {0, 0} /* end of table */ - }; - struct reg_list *reg_table; - int i; - - /* Is this a pushml or a pushmh? */ - if ((insn2 & 7) == 1) - reg_table = pushml_reg_table; - else - reg_table = pushmh_reg_table; - - /* Calculate the total size of the saved registers, and add it - it to the immediate value used to adjust SP. */ - for (i = 0; reg_table[i].mask != 0; i++) - if (list12 & reg_table[i].mask) - offset += REGISTER_RAW_SIZE (regtable[i].regno); - pi->frameoffset -= offset; - - /* Calculate the offsets of the registers relative to the value - the SP will have after the registers have been pushed and the - imm5 value is subtracted from it. */ - if (pifsr) - { - for (i = 0; reg_table[i].mask != 0; i++) - { - if (list12 & reg_table[i].mask) - { - int reg = reg_table[i].regno; - offset -= REGISTER_RAW_SIZE (reg); - pifsr->reg = reg; - pifsr->offset = offset; - pifsr->cur_frameoffset = pi->frameoffset; -#ifdef DEBUG - printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset); -#endif - pifsr++; - } - } - } -#ifdef DEBUG - printf_filtered ("\tfound ctret after regsave func"); -#endif - - /* Set result parameters. */ - *pifsr_ptr = pifsr; -} - - - - -/* Function: scan_prologue - Scan the prologue of the function that contains PC, and record what - we find in PI. PI->fsr must be zeroed by the called. Returns the - pc after the prologue. Note that the addresses saved in pi->fsr - are actually just frame relative (negative offsets from the frame - pointer). This is because we don't know the actual value of the - frame pointer yet. In some circumstances, the frame pointer can't - be determined till after we have scanned the prologue. */ - -static CORE_ADDR -v850_scan_prologue (CORE_ADDR pc, struct prologue_info *pi) -{ - CORE_ADDR func_addr, prologue_end, current_pc; - struct pifsr *pifsr, *pifsr_tmp; - int fp_used; - int ep_used; - int reg; - CORE_ADDR save_pc, save_end; - int regsave_func_p; - int r12_tmp; - - /* First, figure out the bounds of the prologue so that we can limit the - search to something reasonable. */ - - if (find_pc_partial_function (pc, NULL, &func_addr, NULL)) - { - struct symtab_and_line sal; - - sal = find_pc_line (func_addr, 0); - - if (func_addr == entry_point_address ()) - pi->start_function = 1; - else - pi->start_function = 0; - -#if 0 - if (sal.line == 0) - prologue_end = pc; - else - prologue_end = sal.end; -#else - prologue_end = pc; -#endif - } - else - { /* We're in the boondocks */ - func_addr = pc - 100; - prologue_end = pc; - } - - prologue_end = min (prologue_end, pc); - - /* Now, search the prologue looking for instructions that setup fp, save - rp, adjust sp and such. We also record the frame offset of any saved - registers. */ - - pi->frameoffset = 0; - pi->framereg = SP_REGNUM; - fp_used = 0; - ep_used = 0; - pifsr = pi->pifsrs; - regsave_func_p = 0; - save_pc = 0; - save_end = 0; - r12_tmp = 0; - -#ifdef DEBUG - printf_filtered ("Current_pc = 0x%.8lx, prologue_end = 0x%.8lx\n", - (long) func_addr, (long) prologue_end); -#endif - - for (current_pc = func_addr; current_pc < prologue_end;) - { - int insn; - int insn2 = -1; /* dummy value */ - -#ifdef DEBUG - printf_filtered ("0x%.8lx ", (long) current_pc); - TARGET_PRINT_INSN (current_pc, &tm_print_insn_info); -#endif - - insn = read_memory_unsigned_integer (current_pc, 2); - current_pc += 2; - if ((insn & 0x0780) >= 0x0600) /* Four byte instruction? */ - { - insn2 = read_memory_unsigned_integer (current_pc, 2); - current_pc += 2; - } - - if ((insn & 0xffc0) == ((10 << 11) | 0x0780) && !regsave_func_p) - { /* jarl ,10 */ - long low_disp = insn2 & ~(long) 1; - long disp = (((((insn & 0x3f) << 16) + low_disp) - & ~(long) 1) ^ 0x00200000) - 0x00200000; - - save_pc = current_pc; - save_end = prologue_end; - regsave_func_p = 1; - current_pc += disp - 4; - prologue_end = (current_pc - + (2 * 3) /* moves to/from ep */ - + 4 /* addi ,sp,sp */ - + 2 /* jmp [r10] */ - + (2 * 12) /* sst.w to save r2, r20-r29, r31 */ - + 20); /* slop area */ - -#ifdef DEBUG - printf_filtered ("\tfound jarl ,r10, disp = %ld, low_disp = %ld, new pc = 0x%.8lx\n", - disp, low_disp, (long) current_pc + 2); -#endif - continue; - } - else if ((insn & 0xffc0) == 0x0200 && !regsave_func_p) - { /* callt */ - long ctbp = read_register (CTBP_REGNUM); - long adr = ctbp + ((insn & 0x3f) << 1); - - save_pc = current_pc; - save_end = prologue_end; - regsave_func_p = 1; - current_pc = ctbp + (read_memory_unsigned_integer (adr, 2) & 0xffff); - prologue_end = (current_pc - + (2 * 3) /* prepare list2,imm5,sp/imm */ - + 4 /* ctret */ - + 20); /* slop area */ - -#ifdef DEBUG - printf_filtered ("\tfound callt, ctbp = 0x%.8lx, adr = %.8lx, new pc = 0x%.8lx\n", - ctbp, adr, (long) current_pc); -#endif - continue; - } - else if ((insn & 0xffc0) == 0x0780) /* prepare list2,imm5 */ - { - handle_prepare (insn, insn2, ¤t_pc, pi, &pifsr); - continue; - } - else if (insn == 0x07e0 && regsave_func_p && insn2 == 0x0144) - { /* ctret after processing register save function */ - current_pc = save_pc; - prologue_end = save_end; - regsave_func_p = 0; -#ifdef DEBUG - printf_filtered ("\tfound ctret after regsave func"); -#endif - continue; - } - else if ((insn & 0xfff0) == 0x07e0 && (insn2 & 5) == 1) - { /* pushml, pushmh */ - handle_pushm (insn, insn2, pi, &pifsr); - continue; - } - else if ((insn & 0xffe0) == 0x0060 && regsave_func_p) - { /* jmp after processing register save function */ - current_pc = save_pc; - prologue_end = save_end; - regsave_func_p = 0; -#ifdef DEBUG - printf_filtered ("\tfound jmp after regsave func"); -#endif - continue; - } - else if ((insn & 0x07c0) == 0x0780 /* jarl or jr */ - || (insn & 0xffe0) == 0x0060 /* jmp */ - || (insn & 0x0780) == 0x0580) /* branch */ - { -#ifdef DEBUG - printf_filtered ("\n"); -#endif - break; /* Ran into end of prologue */ - } - - else if ((insn & 0xffe0) == ((SP_REGNUM << 11) | 0x0240)) /* add ,sp */ - pi->frameoffset += ((insn & 0x1f) ^ 0x10) - 0x10; - else if (insn == ((SP_REGNUM << 11) | 0x0600 | SP_REGNUM)) /* addi ,sp,sp */ - pi->frameoffset += insn2; - else if (insn == ((FP_RAW_REGNUM << 11) | 0x0000 | SP_REGNUM)) /* mov sp,fp */ - { - fp_used = 1; - pi->framereg = FP_RAW_REGNUM; - } - - else if (insn == ((R12_REGNUM << 11) | 0x0640 | R0_REGNUM)) /* movhi hi(const),r0,r12 */ - r12_tmp = insn2 << 16; - else if (insn == ((R12_REGNUM << 11) | 0x0620 | R12_REGNUM)) /* movea lo(const),r12,r12 */ - r12_tmp += insn2; - else if (insn == ((SP_REGNUM << 11) | 0x01c0 | R12_REGNUM) && r12_tmp) /* add r12,sp */ - pi->frameoffset = r12_tmp; - else if (insn == ((EP_REGNUM << 11) | 0x0000 | SP_REGNUM)) /* mov sp,ep */ - ep_used = 1; - else if (insn == ((EP_REGNUM << 11) | 0x0000 | R1_REGNUM)) /* mov r1,ep */ - ep_used = 0; - else if (((insn & 0x07ff) == (0x0760 | SP_REGNUM) /* st.w ,[sp] */ - || (fp_used - && (insn & 0x07ff) == (0x0760 | FP_RAW_REGNUM))) /* st.w ,[fp] */ - && pifsr - && (((reg = (insn >> 11) & 0x1f) >= SAVE1_START_REGNUM && reg <= SAVE1_END_REGNUM) - || (reg >= SAVE2_START_REGNUM && reg <= SAVE2_END_REGNUM) - || (reg >= SAVE3_START_REGNUM && reg <= SAVE3_END_REGNUM))) - { - pifsr->reg = reg; - pifsr->offset = insn2 & ~1; - pifsr->cur_frameoffset = pi->frameoffset; -#ifdef DEBUG - printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset); -#endif - pifsr++; - } - - else if (ep_used /* sst.w ,[ep] */ - && ((insn & 0x0781) == 0x0501) - && pifsr - && (((reg = (insn >> 11) & 0x1f) >= SAVE1_START_REGNUM && reg <= SAVE1_END_REGNUM) - || (reg >= SAVE2_START_REGNUM && reg <= SAVE2_END_REGNUM) - || (reg >= SAVE3_START_REGNUM && reg <= SAVE3_END_REGNUM))) - { - pifsr->reg = reg; - pifsr->offset = (insn & 0x007e) << 1; - pifsr->cur_frameoffset = pi->frameoffset; -#ifdef DEBUG - printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset); -#endif - pifsr++; - } - -#ifdef DEBUG - printf_filtered ("\n"); -#endif - } - - if (pifsr) - pifsr->framereg = 0; /* Tie off last entry */ - - /* Fix up any offsets to the final offset. If a frame pointer was created, use it - instead of the stack pointer. */ - for (pifsr_tmp = pi->pifsrs; pifsr_tmp && pifsr_tmp != pifsr; pifsr_tmp++) - { - pifsr_tmp->offset -= pi->frameoffset - pifsr_tmp->cur_frameoffset; - pifsr_tmp->framereg = pi->framereg; - -#ifdef DEBUG - printf_filtered ("Saved register r%d, offset = %d, framereg = r%d\n", - pifsr_tmp->reg, pifsr_tmp->offset, pifsr_tmp->framereg); -#endif - } - -#ifdef DEBUG - printf_filtered ("Framereg = r%d, frameoffset = %d\n", pi->framereg, pi->frameoffset); -#endif - - return current_pc; -} - -/* Function: init_extra_frame_info - Setup the frame's frame pointer, pc, and frame addresses for saved - registers. Most of the work is done in scan_prologue(). - - Note that when we are called for the last frame (currently active frame), - that fi->pc and fi->frame will already be setup. However, fi->frame will - be valid only if this routine uses FP. For previous frames, fi-frame will - always be correct (since that is derived from v850_frame_chain ()). - - We can be called with the PC in the call dummy under two circumstances. - First, during normal backtracing, second, while figuring out the frame - pointer just prior to calling the target function (see run_stack_dummy). */ - -void -v850_init_extra_frame_info (struct frame_info *fi) -{ - struct prologue_info pi; - struct pifsr pifsrs[NUM_REGS + 1], *pifsr; - - if (fi->next) - fi->pc = FRAME_SAVED_PC (fi->next); - - memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); - - /* The call dummy doesn't save any registers on the stack, so we can return - now. */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return; - - pi.pifsrs = pifsrs; - - v850_scan_prologue (fi->pc, &pi); - - if (!fi->next && pi.framereg == SP_REGNUM) - fi->frame = read_register (pi.framereg) - pi.frameoffset; - - for (pifsr = pifsrs; pifsr->framereg; pifsr++) - { - fi->fsr.regs[pifsr->reg] = pifsr->offset + fi->frame; - - if (pifsr->framereg == SP_REGNUM) - fi->fsr.regs[pifsr->reg] += pi.frameoffset; - } -} - -/* Function: frame_chain - Figure out the frame prior to FI. Unfortunately, this involves - scanning the prologue of the caller, which will also be done - shortly by v850_init_extra_frame_info. For the dummy frame, we - just return the stack pointer that was in use at the time the - function call was made. */ - -CORE_ADDR -v850_frame_chain (struct frame_info *fi) -{ - struct prologue_info pi; - CORE_ADDR callers_pc, fp; - - /* First, find out who called us */ - callers_pc = FRAME_SAVED_PC (fi); - /* If caller is a call-dummy, then our FP bears no relation to his FP! */ - fp = v850_find_callers_reg (fi, FP_RAW_REGNUM); - if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) - return fp; /* caller is call-dummy: return oldest value of FP */ - - /* Caller is NOT a call-dummy, so everything else should just work. - Even if THIS frame is a call-dummy! */ - pi.pifsrs = NULL; - - v850_scan_prologue (callers_pc, &pi); - - if (pi.start_function) - return 0; /* Don't chain beyond the start function */ - - if (pi.framereg == FP_RAW_REGNUM) - return v850_find_callers_reg (fi, pi.framereg); - - return fi->frame - pi.frameoffset; -} - -/* Function: find_callers_reg - Find REGNUM on the stack. Otherwise, it's in an active register. - One thing we might want to do here is to check REGNUM against the - clobber mask, and somehow flag it as invalid if it isn't saved on - the stack somewhere. This would provide a graceful failure mode - when trying to get the value of caller-saves registers for an inner - frame. */ - -CORE_ADDR -v850_find_callers_reg (struct frame_info *fi, int regnum) -{ - for (; fi; fi = fi->next) - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, regnum); - else if (fi->fsr.regs[regnum] != 0) - return read_memory_unsigned_integer (fi->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum)); - - return read_register (regnum); -} - -/* Function: skip_prologue - Return the address of the first code past the prologue of the function. */ - -CORE_ADDR -v850_skip_prologue (CORE_ADDR pc) -{ - CORE_ADDR func_addr, func_end; - - /* See what the symbol table says */ - - if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - { - struct symtab_and_line sal; - - sal = find_pc_line (func_addr, 0); - - if (sal.line != 0 && sal.end < func_end) - return sal.end; - else - /* Either there's no line info, or the line after the prologue is after - the end of the function. In this case, there probably isn't a - prologue. */ - return pc; - } - -/* We can't find the start of this function, so there's nothing we can do. */ - return pc; -} - -/* Function: pop_frame - This routine gets called when either the user uses the `return' - command, or the call dummy breakpoint gets hit. */ - -void -v850_pop_frame (struct frame_info *frame) -{ - int regnum; - - if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - generic_pop_dummy_frame (); - else - { - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - - for (regnum = 0; regnum < NUM_REGS; regnum++) - if (frame->fsr.regs[regnum] != 0) - write_register (regnum, - read_memory_unsigned_integer (frame->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum))); - - write_register (SP_REGNUM, FRAME_FP (frame)); - } - - flush_cached_frames (); -} - -/* Function: push_arguments - Setup arguments and RP for a call to the target. First four args - go in R6->R9, subsequent args go into sp + 16 -> sp + ... Structs - are passed by reference. 64 bit quantities (doubles and long - longs) may be split between the regs and the stack. When calling a - function that returns a struct, a pointer to the struct is passed - in as a secret first argument (always in R6). - - Stack space for the args has NOT been allocated: that job is up to us. - */ - -CORE_ADDR -v850_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - unsigned char struct_return, CORE_ADDR struct_addr) -{ - int argreg; - int argnum; - int len = 0; - int stack_offset; - - /* First, just for safety, make sure stack is aligned */ - sp &= ~3; - - /* Now make space on the stack for the args. */ - for (argnum = 0; argnum < nargs; argnum++) - len += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3); - sp -= len; /* possibly over-allocating, but it works... */ - /* (you might think we could allocate 16 bytes */ - /* less, but the ABI seems to use it all! ) */ - argreg = ARG0_REGNUM; - - /* the struct_return pointer occupies the first parameter-passing reg */ - if (struct_return) - write_register (argreg++, struct_addr); - - stack_offset = 16; - /* The offset onto the stack at which we will start copying parameters - (after the registers are used up) begins at 16 rather than at zero. - I don't really know why, that's just the way it seems to work. */ - - /* Now load as many as possible of the first arguments into - registers, and push the rest onto the stack. There are 16 bytes - in four registers available. Loop thru args from first to last. */ - for (argnum = 0; argnum < nargs; argnum++) - { - int len; - char *val; - char valbuf[REGISTER_RAW_SIZE (ARG0_REGNUM)]; - - if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT - && TYPE_LENGTH (VALUE_TYPE (*args)) > 8) - { - store_address (valbuf, 4, VALUE_ADDRESS (*args)); - len = 4; - val = valbuf; - } - else - { - len = TYPE_LENGTH (VALUE_TYPE (*args)); - val = (char *) VALUE_CONTENTS (*args); - } - - while (len > 0) - if (argreg <= ARGLAST_REGNUM) - { - CORE_ADDR regval; - - regval = extract_address (val, REGISTER_RAW_SIZE (argreg)); - write_register (argreg, regval); - - len -= REGISTER_RAW_SIZE (argreg); - val += REGISTER_RAW_SIZE (argreg); - argreg++; - } - else - { - write_memory (sp + stack_offset, val, 4); - - len -= 4; - val += 4; - stack_offset += 4; - } - args++; - } - return sp; -} - -/* Function: push_return_address (pc) - Set up the return address for the inferior function call. - Needed for targets where we don't actually execute a JSR/BSR instruction */ - -CORE_ADDR -v850_push_return_address (CORE_ADDR pc, CORE_ADDR sp) -{ - write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ()); - return sp; -} - -/* Function: frame_saved_pc - Find the caller of this frame. We do this by seeing if RP_REGNUM - is saved in the stack anywhere, otherwise we get it from the - registers. If the inner frame is a dummy frame, return its PC - instead of RP, because that's where "caller" of the dummy-frame - will be found. */ - -CORE_ADDR -v850_frame_saved_pc (struct frame_info *fi) -{ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); - else - return v850_find_callers_reg (fi, RP_REGNUM); -} - - -/* Function: fix_call_dummy - Pokes the callee function's address into the CALL_DUMMY assembly stub. - Assumes that the CALL_DUMMY looks like this: - jarl , r31 - trap - */ - -int -v850_fix_call_dummy (char *dummy, CORE_ADDR sp, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - long offset24; - - offset24 = (long) fun - (long) entry_point_address (); - offset24 &= 0x3fffff; - offset24 |= 0xff800000; /* jarl , r31 */ - - store_unsigned_integer ((unsigned int *) &dummy[2], 2, offset24 & 0xffff); - store_unsigned_integer ((unsigned int *) &dummy[0], 2, offset24 >> 16); - return 0; -} - -/* Change the register names based on the current machine type. */ - -static int -v850_target_architecture_hook (const bfd_arch_info_type *ap) -{ - int i, j; - - if (ap->arch != bfd_arch_v850) - return 0; - - for (i = 0; v850_processor_type_table[i].regnames != NULL; i++) - { - if (v850_processor_type_table[i].mach == ap->mach) - { - v850_register_names = v850_processor_type_table[i].regnames; - tm_print_insn_info.mach = ap->mach; - return 1; - } - } - - internal_error (__FILE__, __LINE__, - "Architecture `%s' unrecognized", ap->printable_name); -} - -void -_initialize_v850_tdep (void) -{ - tm_print_insn = print_insn_v850; - target_architecture_hook = v850_target_architecture_hook; -} diff --git a/contrib/gdb/gdb/xmodem.c b/contrib/gdb/gdb/xmodem.c deleted file mode 100644 index 7b8d77d1055..00000000000 --- a/contrib/gdb/gdb/xmodem.c +++ /dev/null @@ -1,275 +0,0 @@ -/* XMODEM support for GDB, the GNU debugger. - Copyright 1995, 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "serial.h" -#include "target.h" -#include "xmodem.h" - -/* These definitions are for xmodem protocol. */ - -#define SOH 0x01 -#define STX 0x02 -#define ACK 0x06 -#define NAK 0x15 -#define EOT 0x04 -#define CANCEL 0x18 - -static int blknum; /* XMODEM block number */ -static int crcflag; /* Sez we are using CRC's instead of cksums */ - -static int -readchar (struct serial *desc, int timeout) -{ - int c; - - c = serial_readchar (desc, timeout); - - if (remote_debug > 0) - fputc_unfiltered (c, gdb_stdlog); - - if (c >= 0) - return c; - - if (c == SERIAL_TIMEOUT) - error ("Timeout reading from remote system."); - - perror_with_name ("xmodem.c:readchar()"); -} - -#define CRC16 0x1021 /* Generator polynomial (X^16 + X^12 + X^5 + 1) */ - -static unsigned short *crctab; - -/* Call this to init the fast CRC-16 calculation table. */ - -static void -crcinit (void) -{ - static int crctab_inited = 0; - int val; - - if (crctab_inited == 1) - return; - - crctab = xmalloc (256 * sizeof (short)); - - for (val = 0; val <= 255; val++) - { - int i; - unsigned int crc; - - crc = val << 8; - - for (i = 0; i < 8; ++i) - { - crc <<= 1; - - if (crc & 0x10000) - crc ^= CRC16; - } - - crctab[val] = crc; - } - - crctab_inited = 1; -} - -/* Calculate a CRC-16 for the LEN byte message pointed at by P. */ - -static unsigned short -docrc (unsigned char *p, int len) -{ - unsigned short crc = 0; - - while (len-- > 0) - crc = (crc << 8) ^ crctab[(crc >> 8) ^ *p++]; - - return crc; -} - -/* Start up the transmit process. Reset state variables. Wait for receiver to - send NAK or CRC request. */ - -int -xmodem_init_xfer (struct serial *desc) -{ - int c; - int i; - - blknum = 1; - crcflag = 0; - crcinit (); - - for (i = 1; i <= 10; i++) - { - c = readchar (desc, 6); - - switch (c) - { - case 'C': - crcflag = 1; - case NAK: - return 0; - default: - fprintf_unfiltered (gdb_stderr, "xmodem_init_xfer: Got unexpected character %c (0%o)\n", c, c); - continue; - case CANCEL: /* target aborted load */ - fprintf_unfiltered (gdb_stderr, "Got a CANCEL from the target.\n"); - continue; - } - } - error ("xmodem_init_xfer: Too many unexpected characters."); -} - -/* Take 128 bytes of data and make a packet out of it. - - * Each packet looks like this: - * +-----+-------+-------+------+-----+ - * | SOH | Seq1. | Seq2. | data | SUM | - * +-----+-------+-------+------+-----+ - * SOH = 0x01 - * Seq1 = The sequence number. - * Seq2 = The complement of the sequence number. - * Data = A 128 bytes of data. - * SUM = Add the contents of the 128 bytes and use the low-order - * 8 bits of the result. - * - * send_xmodem_packet fills in the XMODEM fields of PACKET and sends it to the - * remote system. PACKET must be XMODEM_PACKETSIZE bytes long. The data must - * start 3 bytes after the beginning of the packet to leave room for the - * XMODEM header. LEN is the length of the data portion of the packet (and - * must be <= 128 bytes). If it is < 128 bytes, ^Z padding will be added. - */ - -void -xmodem_send_packet (struct serial *desc, unsigned char *packet, int len, int hashmark) -{ - int i; - int retries; - int pktlen; - int datasize; - - /* build the packet header */ - - packet[1] = blknum; - packet[2] = ~blknum; - - blknum++; - - if (len <= XMODEM_DATASIZE) - { - packet[0] = SOH; - datasize = XMODEM_DATASIZE; - } - else if (len <= XMODEM_1KDATASIZE) - { - packet[0] = STX; - datasize = XMODEM_1KDATASIZE; - } - else - internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Packet way too large */ - - /* Add ^Z padding if packet < 128 (or 1024) bytes */ - - memset (packet + 3 + len, '\026', datasize - len); - - if (crcflag) - { - int crc; - - crc = docrc (packet + 3, datasize); - - packet[3 + datasize] = crc >> 8; - packet[3 + datasize + 1] = crc; - pktlen = datasize + 5; - } - else - { - int sum; - - sum = 0; - for (i = 3; i < datasize + 3; i++) - sum += packet[i]; - - packet[3 + datasize] = sum; /* add the checksum */ - pktlen = datasize + 4; - } - - for (retries = 3; retries >= 0; retries--) - { - int c; - - serial_write (desc, packet, pktlen); - - c = readchar (desc, 3); - switch (c) - { - case ACK: - return; - case NAK: - if (!hashmark) - continue; - putchar_unfiltered ('-'); - gdb_flush (gdb_stdout); - continue; - case CANCEL: - error ("xmodem_send_packet: Transfer aborted by receiver."); - default: - fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c); - continue; - } - } - - serial_write (desc, "\004", 1); /* Send an EOT */ - - error ("xmodem_send_packet: Excessive retries."); -} - -/* Finish off the transfer. Send out the EOT, and wait for an ACK. */ - -void -xmodem_finish_xfer (struct serial *desc) -{ - int retries; - - for (retries = 10; retries >= 0; retries--) - { - int c; - - serial_write (desc, "\004", 1); /* Send an EOT */ - - c = readchar (desc, 3); - switch (c) - { - case ACK: - return; - case NAK: - continue; - case CANCEL: - error ("xmodem_finish_xfer: Transfer aborted by receiver."); - default: - fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c); - continue; - } - } - - error ("xmodem_finish_xfer: Excessive retries."); -} diff --git a/contrib/gdb/gdb/xmodem.h b/contrib/gdb/gdb/xmodem.h deleted file mode 100644 index 86c5008d159..00000000000 --- a/contrib/gdb/gdb/xmodem.h +++ /dev/null @@ -1,30 +0,0 @@ -/* XMODEM support for GDB, the GNU debugger. - Copyright 1995, 2000 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -int xmodem_init_xfer (struct serial *desc); -void send_xmodem_packet (struct serial *desc, unsigned char *packet, int len, - int hashmark); -void xmodem_finish_xfer (struct serial *desc); - -#define XMODEM_DATASIZE 128 /* The data size is ALWAYS 128 */ -#define XMODEM_1KDATASIZE 1024 /* Unless it's 1024!!! */ -#define XMODEM_PACKETSIZE 133 /* data + packet headers and crc */ -#define XMODEM_1KPACKETSIZE 1024 + 5 /* data + packet headers and crc */ -#define XMODEM_DATAOFFSET 3 /* Offset to start of actual data */ diff --git a/contrib/gdb/include/COPYING b/contrib/gdb/include/COPYING deleted file mode 100644 index a43ea2126fb..00000000000 --- a/contrib/gdb/include/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/contrib/gdb/include/ChangeLog b/contrib/gdb/include/ChangeLog deleted file mode 100644 index 3594591bb96..00000000000 --- a/contrib/gdb/include/ChangeLog +++ /dev/null @@ -1,973 +0,0 @@ -Tue Mar 12 17:29:46 1996 Ian Lance Taylor - - * bfdlink.h (bfd_wrapped_link_hash_lookup): Declare. - (struct bfd_link_info): Add wrap_hash field. - -Wed Feb 14 16:49:17 1996 Martin Anantharaman - - * ieee.h (ieee_record_enum_type): Define - ieee_external_reference_info_enum. - -Fri Feb 2 17:09:25 1996 Doug Evans - - * dis-asm.h (DISASM_RAW_INSN): Delete. - -Tue Jan 23 09:21:47 1996 Doug Evans - - * dis-asm.h (INIT_DISASSEMBLE_INFO): Set endian to BFD_ENDIAN_UNKNOWN. - New argument FPRINTF_FUNC. - -Mon Jan 22 16:37:59 1996 Doug Evans - - * dis-asm.h (disassemble_info): New members arch, mach, endian. - (INIT_DISASSEMBLE_INFO): Initialize them. - (DISASM_RAW_INSN{,FLAG}): Define. - -Thu Jan 18 11:32:38 1996 Ian Lance Taylor - - * demangle.h (cplus_demangle_opname): Change opname parameter to - const char *. - (cplus_mangle_opname): Change return type and opname parameter to - const char *. - -Fri Jan 5 00:01:22 1996 Ian Lance Taylor - - * ieee.h (enum ieee_record): Add ieee_asn_record_enum, - ieee_at_record_enum, ieee_ty_record_enum, ieee_atn_record_enum, - ieee_bb_record_enum, and ieee_be_record_enum. - -Wed Jan 3 13:12:09 1996 Fred Fish - - * obstack.h: Update copyright to 1996. - (_obstack_memory_used): Declare. - (obstack_memory_used): Define macro. - -Thu Dec 28 11:42:12 1995 Ian Lance Taylor - - * libiberty.h (xstrdup): Declare. - -Thu Dec 21 14:47:17 1995 Michael Meissner - - * wait.h: Protect all macros with #ifndef. - -Tue Oct 24 21:45:40 1995 Ian Lance Taylor - - * bfdlink.h (struct bfd_link_info): Add static_link field. - -Tue Sep 12 16:28:04 1995 Ian Lance Taylor - - * bfdlink.h (struct bfd_link_callbacks): Add symbol parameter to - warning callback. - -Fri Sep 1 13:11:51 1995 Ian Lance Taylor - - * bfdlink.h (struct bfd_link_callbacks): Change warning callback - to take BFD, section, and address arguments. - -Thu Aug 31 16:45:12 1995 steve chamberlain - - * bfdlink.h (struct bfd_link_info): Remove PE stuff. - -Tue Aug 22 03:18:23 1995 Ken Raeburn - - * libiberty.h: Declare xstrerror. From Pat Rankin. - -Mon Aug 21 18:11:36 1995 steve chamberlain - - * bfdlink.h (struct bfd_link_info): Remove PE stuff. - -Wed Aug 2 08:14:12 1995 Doug Evans - - * dis-asm.h (print_insn_sparc64): Declare. - -Mon Jul 10 13:26:49 1995 Eric Youngdale - - * bfdlink.h (struct bfd_link_info): Add new field symbolic. - -Sun Jul 2 17:48:40 1995 Ian Lance Taylor - - * bfdlink.h (struct bfd_link_info): Change type of base_file to - PTR. - -Thu Jun 29 00:02:45 1995 Steve Chamberlain - - * bfdlink.h (struct bfd_link_info): Added base_file member. - -Tue Jun 20 16:40:04 1995 Steve Chamberlain - - * ansidecl.h: win32s is ANSI enough. - -Thu May 18 04:25:50 1995 Ken Raeburn - - Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk) - - * dis-asm.h (print_insn_arm): Delete declaration. - (print_insn_{little,big}_arm): New declarations. - - * floatformat.h (floatformat_arm_ext): Declare. - -Sat May 13 10:14:08 1995 Steve Chamberlain - - * coff/pe.h: New file. - * bfdlink.h (subsytem, stack_heap_parameters): New. - * coff/i386.h (NT_SECTION_ALIGNMENT, NT_FILE_ALIGNMENT, - NT_DEF_RESERVE, NT_DEF_COMMIT): New. - * coff/internal.h (internal_filehdr): New fields for PE. - (IMAGE_DATA_DIRECTORY): New. - (internal_aouthdr): New fields for PE. - -Thu May 4 14:36:42 1995 Jason Merrill - - * demangle.h: Don't include ansidecl.h if IN_GCC. - - -Tue Feb 21 00:37:28 1995 Jeff Law (law@snake.cs.utah.edu) - - * hp-symtab.h: Don't use bitfield enumerations, the HP C compiler - does not handle them correctly. - - -Thu Feb 9 14:20:27 1995 Ian Lance Taylor - - * libiberty.h (basename): Don't declare parameter type; some - systems have this in their header files. - -Wed Feb 8 17:35:38 1995 Ian Lance Taylor - - * bfdlink.h (struct bfd_link_hash_entry): Change format of common - symbol information, to remove restrictions on maximum size and - alignment power, by using a pointer to a structure instead. - -Mon Feb 6 14:55:32 1995 Ian Lance Taylor - - * bfdlink.h (enum bfd_link_hash_type): Rename bfd_link_hash_weak - to bfd_link_hash_undefweak. Add bfd_link_hash_defweak. - -Mon Jan 16 21:00:23 1995 Stan Shebs - - * dis-asm.h (GDB_INIT_DISASSEMBLE_INFO, etc): Remove all - GDB-specific definitions. - -Sun Jan 15 18:39:35 1995 Steve Chamberlain - - * dis-asm.h (print_insn_w65): Declare. - -Thu Jan 12 17:51:17 1995 Ken Raeburn - - * libiberty.h (hex_p): Fix sense of test. - -Wed Jan 11 22:36:40 1995 Ken Raeburn - - * libiberty.h (_hex_array_size, _hex_bad, _hex_value, hex_init, - hex_p, hex_value): New macros and declarations, for hex.c. - -Fri Jan 6 17:44:14 1995 Ian Lance Taylor - - * dis-asm.h: Make idempotent. - -Wed Dec 14 13:08:43 1994 Stan Shebs - - * progress.h: New file, empty definitions for progress macros. - - -Fri Nov 25 00:14:05 1994 Jeff Law (law@snake.cs.utah.edu) - - * hp-symtab.h: New file describing the debug symbols emitted - by the HP C compilers. - -Fri Nov 11 15:48:37 1994 Ian Lance Taylor - - * bfdlink.h (struct bfd_link_hash_entry): Change u.c.size from 24 - to 26 bits, and change u.c.alignment_power from 8 to 6 bits. 6 - bit in the alignment power is enough for a 64 bit address space. - -Mon Oct 31 13:02:51 1994 Stan Shebs (shebs@andros.cygnus.com) - - * demangle.h (cplus_mangle_opname): Declare. - -Tue Oct 25 11:38:02 1994 Ian Lance Taylor - - * bfdlink.h (struct bfd_link_callbacks): Fix comments for - multiple_common field. - -Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org) - - * aout/aout64.h: Only define QMAGIC if it isn't already defined. - - * dis-asm.h: Add support for the ARM. - -Wed Aug 10 12:51:41 1994 Doug Evans (dje@canuck.cygnus.com) - - * libiberty.h (strsignal): Document its existence even if we - can't declare it. - -Tue Aug 2 14:40:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * os9k.h: Remove u_int16, u_int32, and owner_id typedefs and - expand their uses. Those names conflict with Mach headers. - -Fri Jul 22 14:17:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * bfdlink.h (struct bfd_link_hash_entry): Change u.c.size into a - bitfield. Add field u.c.alignment_power. - -Sun Jul 10 00:26:39 1994 Ian Dall (dall@hfrd.dsto.gov.au) - - * dis-asm.h: Add print_insn_ns32k declaration. - -Mon Jun 20 17:13:29 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * bfdlink.h (bfd_link_hash_table): Make creator a const pointer. - -Sat Jun 18 16:09:32 1994 Stan Shebs (shebs@andros.cygnus.com) - - * demangle.h (cplus_demangle_opname): Declare. - -Thu Jun 16 15:19:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfdlink.h (struct bfd_link_info): Add new field shared. - -Mon Jun 6 14:39:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfdlink.h (struct bfd_link_hash_entry): Remove written field: - not needed for all backends. - -Thu Apr 28 19:06:50 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * dis-asm.h (disassembler): Declare. - -Fri Apr 1 00:38:17 1994 Jim Wilson (wilson@mole.gnu.ai.mit.edu) - - * obstack.h: Delete use of IN_GCC to control whether - stddef.h or gstddef.h is included. - -Tue Mar 22 13:06:02 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfdlink.h (enum bfd_link_order_type): Add bfd_data_link_order. - (struct bfd_link_order): Add data field to union. - -Mon Mar 21 18:45:26 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfdlink.h (struct bfd_link_callbacks): Change bitsize argument - to add_to_set to reloc. Remove bitsize argument from constructor. - Comment that reloc_overflow, reloc_dangerous and unattached_reloc - must handle NULL pointers for reloc location. - (enum bfd_link_order_type): Add bfd_section_reloc_link_order and - bfd_symbol_reloc_link_order. - (struct bfd_link_order): Add reloc field to union. - (struct bfd_link_order_reloc): Define. - -Mon Mar 14 12:27:50 1994 Ian Lance Taylor (ian@cygnus.com) - - * ieee-float.h: Removed; no longer used. - -Tue Mar 1 18:10:49 1994 Kung Hsu (kung@mexican.cygnus.com) - - * os9k.h: os9000 target specific header file, the header of the - object file is used now. - -Sun Feb 27 21:52:26 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * floatformat.h: New file, intended to replace ieee-float.h. - -Sun Feb 20 17:15:42 1994 Ian Lance Taylor (ian@lisa.cygnus.com) - - * ansidecl.h (ANSI_PROTOTYPES): Define if using ANSI prototypes. - -Wed Feb 16 01:07:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * libiberty.h: Don't declare strsignal, to avoid conflicts with - Solaris system header files. - -Sat Feb 12 22:11:32 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * libiberty.h (xexit): Use __volatile__ to avoid losing if - compiling with gcc -traditional. - -Thu Feb 10 14:05:41 1994 Ian Lance Taylor (ian@cygnus.com) - - * libiberty.h: New file. Declares functions provided by - libiberty. - -Tue Feb 8 05:19:52 1994 David J. Mackenzie (djm@thepub.cygnus.com) - - Handle obstack_chunk_alloc returning NULL. This allows - obstacks to be used by libraries, without forcing them - to call exit or longjmp. - * obstack.h (struct obstack): Add alloc_failed flag. - _obstack_begin, _obstack_begin_1): Declare to return int, not void. - (obstack_finish): If alloc_failed, return NULL. - (obstack_base, obstack_next_free, objstack_object_size): - If alloc_failed, return 0. - (obstack_grow, obstack_grow0, obstack_1grow, obstack_ptr_grow, - obstack_int_grow, obstack_blank): If alloc_failed, do nothing that - could corrupt the obstack. - -Mon Jan 24 15:06:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfdlink.h (struct bfd_link_callbacks): Add name, reloc_name and - addend argments to reloc_overflow callback. - -Fri Jan 21 19:13:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * dis-asm.h (print_insn_big_powerpc, print_insn_little_powerpc, - print_insn_rs6000): Declare. - -Thu Jan 6 14:15:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfdlink.h (struct bfd_link_callbacks): Add bitsize argument to - add_to_set field. Add new callback named constructor. - -Thu Dec 30 10:44:06 1993 Ian Lance Taylor (ian@rtl.cygnus.com) - - * bfdlink.h: New file for new BFD linker backend routines. - -Mon Nov 29 10:43:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * dis-asm.h (enum dis_insn_tyupe): Remove non-ANSI trailing comma. - -Sat Oct 2 20:42:26 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dis-asm.h: Move comment to right place. - -Mon Aug 9 19:03:35 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * obstack.h (obstack_chunkfun, obstack_freefun): Add defns from - previous version. Are these Cygnus local changes? - -Fri Aug 6 17:05:47 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * getopt.h, obstack.h: Update to latest FSF version. - -Mon Aug 2 16:37:14 1993 Stu Grossman (grossman at cygnus.com) - - * coff/i386.h: Add Lynx magic number. - -Mon Aug 2 14:45:29 1993 John Gilmore (gnu@cygnus.com) - - * dis-asm.h: Move enum outside of struct defn to avoid warnings. - -Mon Aug 2 08:49:30 1993 Stu Grossman (grossman at cygnus.com) - - * wait.h (WEXITSTATUS, WSTOPSIG): Mask down to 8 bits. This is - for systems that store stuff into the high 16 bits of a wait - status. - -Fri Jul 30 18:38:02 1993 John Gilmore (gnu@cygnus.com) - - * dis-asm.h: Add new fields insn_info_valid, branch_delay_insns, - data_size, insn_type, target, target2. These are used to return - information from the instruction decoders back to the calling - program. Add comments, make more readable. - -Mon Jul 19 22:14:14 1993 Fred Fish (fnf@deneb.cygnus.com) - - * nlm: New directory containing NLM/NetWare includes. - -Thu Jul 15 12:10:04 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * dis-asm.h (struct disassemble_info): New field application_data. - -Thu Jul 15 12:41:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * dis-asm.h: Added declaration of print_insn_m88k. - -Thu Jul 8 09:05:26 1993 Doug Evans (dje@canuck.cygnus.com) - - * opcode/h8300.h: Lots of little fixes for the h8/300h. - -Fri Jul 2 10:31:59 1993 Ian Lance Taylor (ian@cygnus.com) - - * ansidecl.h: Use ANSI macros if __mips and _SYSTYPE_SVR4 are - defined, since RISC/OS cc handles ANSI declarations in SVR4 mode - but does not define __STDC__. - -Sun Jun 20 18:27:52 1993 Ken Raeburn (raeburn@poseidon.cygnus.com) - - * dis-asm.h: Don't need to include ansidecl.h any more. - -Fri Jun 18 03:22:10 1993 John Gilmore (gnu@cygnus.com) - - * oasys.h: Eliminate "int8_type", "int16_type", "int32_type", and - their variants. These changes are coordinated with corresponding - changes in ../bfd/oasys.c. - -Wed Jun 16 10:43:08 1993 Fred Fish (fnf@cygnus.com) - - * bfd.h: Note that it has been removed. - -Tue Jun 8 12:16:03 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - Support for H8/300-H - * dis-asm.h (print_insn_h8300, print_insn_h8300h): Declare it. - * coff/h8300.h: New magic number. - * coff/internal.h: New relocations. - * opcode/h8300.h: Lots of new opcodes. - -Tue Jun 1 07:35:03 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * ansidecl.h (const): Don't define it if it's already defined. - -Thu May 27 18:19:51 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * dis-asm.h (print_insn_hppa): Declare it. - - * bfd.h: Moved to bfd directory. Small stub here includes it - without requiring "-I../bfd". - -Thu Apr 29 12:06:13 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * bfd.h: Updated with BSF_FUNCTION. - -Mon Apr 26 18:15:50 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * bfd.h, dis-asm.h: Updated with Hitachi SH. - -Fri Apr 23 18:41:38 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * bfd.h: Updated with alpha changes. - * dis-asm.h: Added alpha. - -Fri Apr 16 17:35:30 1993 Jim Kingdon (kingdon@cygnus.com) - - * bfd.h: Update for signed bfd_*get_*. - -Thu Apr 15 09:24:21 1993 Jim Kingdon (kingdon@cygnus.com) - - * bfd.h: Updated for file_truncated error. - -Thu Apr 8 10:53:47 1993 Ian Lance Taylor (ian@cygnus.com) - - * ansidecl.h: If no ANSI, define const to be empty. - -Thu Apr 1 09:00:10 1993 Jim Kingdon (kingdon@cygnus.com) - - * dis-asm.h: Declare a29k and i960 print_insn_*. - - * dis-asm.h: Add print_address_func and related stuff. - - * dis-asm.h (dis_asm_read_memory): Fix prototype. - -Wed Mar 31 17:40:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dis-asm.h: Add print_insn_sparc. - -Wed Mar 31 17:51:42 1993 Ian Lance Taylor (ian@cygnus.com) - - * bfd.h: Updated for BFD_RELOC_MIPS_GPREL and bfd_[gs]et_gp_size - prototypes. - -Wed Mar 31 16:35:12 1993 Stu Grossman (grossman@cygnus.com) - - * dis-asm.h: (disassemble_info): Fix typo in prototype of - dis_asm_memory_error(). - -Tue Mar 30 19:09:23 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dis-asm.h (disassembler_info): Add read_memory_func, - memory_error_func, buffer, and length. - ({GDB_,}INIT_DISASSEMBLE_INFO): Set them. - print_insn_*: Remove second argument. - -Tue Mar 30 14:48:55 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * bfd.h: Update for lma field of section. - -Tue Mar 30 12:22:55 1993 Jim Kingdon (kingdon@cygnus.com) - - * ansidecl.h: Use ANSI versions on AIX regardless of __STDC__. - -Fri Mar 19 14:49:49 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * dis-asm.h: Add h8500. - -Thu Mar 18 13:49:09 1993 Per Bothner (bothner@rtl.cygnus.com) - - * ieee-float.h: Moved from ../gdb. - * dis-asm.h: New file. Interface to dis-assembler. - -Thu Mar 11 10:52:57 1993 Fred Fish (fnf@cygnus.com) - - * demangle.h (DMGL_NO_OPTS): Add define (set to 0) to use - in place of bare 0, for readability reasons. - -Tue Mar 2 17:50:11 1993 Fred Fish (fnf@cygnus.com) - - * demangle.h: Replace all references to cfront with ARM. - -Tue Feb 23 12:21:14 1993 Ian Lance Taylor (ian@cygnus.com) - - * bfd.h: Update for new elements in JUMP_TABLE. - -Tue Feb 16 00:51:30 1993 John Gilmore (gnu@cygnus.com) - - * bfd.h: Update for BFD_VERSION 2.1. - -Tue Jan 26 11:49:20 1993 Ian Lance Taylor (ian@cygnus.com) - - * bfd.h: Update for SEC_IS_COMMON flag. - -Tue Jan 19 12:25:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfd.h: Update for bfd_asymbol_value bug fix. - -Fri Jan 8 16:37:18 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * bfd.h: Update to include ECOFF tdata and target_flavour. - -Sun Dec 27 17:52:30 1992 Fred Fish (fnf@cygnus.com) - - * bfd.h: Add declaration for bfd_get_size(). - -Tue Dec 22 22:42:46 1992 Fred Fish (fnf@cygnus.com) - - * demangle.h: Protect file from multiple inclusions with - #if !defined(DEMANGLE_H)...#define DEMANGLE_H...#endif. - -Mon Dec 21 21:25:50 1992 Stu Grossman (grossman at cygnus.com) - - * bfd.h: Update to get hppa_core_struct from bfd.c. - -Thu Dec 17 00:42:35 1992 John Gilmore (gnu@cygnus.com) - - * bfd.h: Update to get tekhex tdata name change from bfd. - -Mon Nov 9 23:55:42 1992 John Gilmore (gnu@cygnus.com) - - * ansidecl.h: Update comments to discourage use of EXFUN. - -Thu Nov 5 16:35:44 1992 Ian Lance Taylor (ian@cygnus.com) - - * bfd.h: Update to bring in SEC_SHARED_LIBRARY. - -Thu Nov 5 03:21:32 1992 John Gilmore (gnu@cygnus.com) - - * bfd.h: Update to match EXFUN, bfd_seclet_struct, and SDEF - cleanups in bfd. - -Wed Nov 4 07:28:05 1992 Ken Raeburn (raeburn@cygnus.com) - - * bout.h (N_CALLNAME, N_BALNAME): Define as char-type values, so - widening works consistently. - -Fri Oct 16 03:17:08 1992 John Gilmore (gnu@cygnus.com) - - * getopt.h: Update to Revised Standard FSF Version. - -Thu Oct 15 21:43:22 1992 K. Richard Pixley (rich@sendai.cygnus.com) - - * getopt.h (struct option): use the provided enum for has_arg. - - * demangle.h (AUTO_DEMANGLING, GNU_DEMANGLING, - LUCID_DEMANGLING): ultrix compilers require enums to be - enums and ints to be ints and casts where they meet. cast some - enums into ints. - -Thu Oct 15 04:35:51 1992 John Gilmore (gnu@cygnus.com) - - * bfd.h: Update after comment changes. - -Thu Oct 8 09:03:02 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * bfd.h (bfd_get_symbol_leading_char): new macro for getting in xvec - -Thu Sep 3 09:10:50 1992 Stu Grossman (grossman at cygnus.com) - - * bfd.h (struct reloc_howto_struct): size needs to be signed if - it's going to hold negative values. - -Sun Aug 30 17:50:27 1992 Per Bothner (bothner@rtl.cygnus.com) - - * demangle.h: New file, moved from ../gdb. Made independent - of gdb. Allow demangling style option to be passed as a - parameter to cplus_demangle(), but using the - current_demangling_style global as the default. - -Sat Aug 29 10:07:55 1992 Fred Fish (fnf@cygnus.com) - - * obstack.h: Merge comment change from current FSF version. - -Thu Aug 27 12:59:29 1992 Brendan Kehoe (brendan@cygnus.com) - - * bfd.h: add we32k - -Tue Aug 25 15:07:47 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * bfd.h: new after Z8000 stuff - -Mon Aug 17 09:01:23 1992 Ken Raeburn (raeburn@cygnus.com) - - * bfd.h: Regenerated after page/segment size changes. - -Sat Aug 1 13:46:31 1992 Fred Fish (fnf@cygnus.com) - - * obstack.h: Merge changes from current FSF version. - -Mon Jul 20 21:06:23 1992 Fred Fish (fnf@cygnus.com) - - * obstack.h (area_id, flags): Remove, replace with extra_arg, - use_extra_arg, and maybe_empty_object. - * obstack.h (OBSTACK_MAYBE_EMPTY_OBJECT, OBSTACK_MMALLOC_LIKE): - Remove, replaced by maybe_empty_object and use_extra_arg bitfields. - * obstack.h (obstack_full_begin, _obstack_begin): Remove area_id - and flags arguments. - * obstack.h (obstack_alloc_arg): New macro to set extra_arg. - -Thu Jul 16 08:12:44 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * bfd.h: new after adding BFD_IS_RELAXABLE - -Sat Jul 4 03:22:23 1992 John Gilmore (gnu at cygnus.com) - - * bfd.h: Regen after adding BSF_FILE. - -Mon Jun 29 14:18:36 1992 Fred Fish (fnf at sunfish) - - * obstack.h: Convert bcopy() use to memcpy(), which is more - portable, more standard, and can take advantage of gcc's builtin - functions for increased performance. - -Thu Jun 25 04:46:08 1992 John Gilmore (gnu at cygnus.com) - - * ansidecl.h (PARAMS): Incorporate this macro from gdb's defs.h. - It's a cleaner way to forward-declare function prototypes. - -Fri Jun 19 15:46:32 1992 Stu Grossman (grossman at cygnus.com) - - * bfd.h: HPPA merge. - -Tue Jun 16 21:30:56 1992 K. Richard Pixley (rich@cygnus.com) - - * getopt.h: gratuitous white space changes merged from other prep - releases. - -Thu Jun 11 01:10:55 1992 John Gilmore (gnu at cygnus.com) - - * bfd.h: Regen'd from bfd.c after removing elf_core_tdata_struct. - -Mon May 18 17:29:03 1992 K. Richard Pixley (rich@cygnus.com) - - * getopt.h: merged changes from make-3.62.11. - - * getopt.h: merged changes from grep-1.6 (alpha). - -Fri May 8 14:53:32 1992 K. Richard Pixley (rich@cygnus.com) - - * getopt.h: merged changes from bison-1.18. - -Sat Mar 14 17:25:20 1992 Fred Fish (fnf@cygnus.com) - - * obstack.h: Add "area_id" and "flags" members to obstack - structure. Add obstack_chunkfun() and obstack_freefun() to - set functions explicitly. Convert maybe_empty_object to - a bit in "flags". - -Thu Feb 27 22:01:02 1992 Per Bothner (bothner@cygnus.com) - - * wait.h (WIFSTOPPED): Add IBM rs6000-specific version. - -Fri Feb 21 20:49:20 1992 John Gilmore (gnu at cygnus.com) - - * obstack.h: Add obstack_full_begin. - * bfd.h, obstack.h: Protolint. - -Thu Jan 30 01:18:42 1992 John Gilmore (gnu at cygnus.com) - - * bfd.h: Remove comma from enum declaration. - -Mon Jan 27 22:01:13 1992 Steve Chamberlain (sac at cygnus.com) - - * bfd.h : new target entr, bfd_relax_section - -Wed Dec 18 17:19:44 1991 Stu Grossman (grossman at cygnus.com) - - * bfd.h, ieee.h, opcode/m68k.h, opcode/sparc.h: ANSIfy enums. - -Thu Dec 12 20:59:56 1991 John Gilmore (gnu at cygnus.com) - - * fopen-same.h, fopen-bin.h: New files for configuring - whether fopen distinguishes binary files or not. For use - by host-dependent config files. - -Sat Nov 30 20:46:43 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * bfd.h: change the documentation format. - - * created coff, elf and opcode and aout directories. Moved: - - aout64.h ==> aout/aout64.h - ar.h ==> aout/ar.h - a.out.encap.h ==> aout/encap.h - a.out.host.h ==> aout/host.h - a.out.hp.h ==> aout/hp.h - a.out.sun4.h ==> aout/sun4.h - ranlib.h ==> aout/ranlib.h - reloc.h ==> aout/reloc.h - stab.def ==> aout/stab.def - stab.gnu.h ==> aout/stab_gnu.h - - coff-a29k.h ==> coff/a29k.h - coff-h8300.h ==> coff/h8300.h - coff-i386.h ==> coff/i386.h - coff-i960.h ==> coff/i960.h - internalcoff.h ==> coff/internal.h - coff-m68k.h ==> coff/m68k.h - coff-m88k.h ==> coff/m88k.h - coff-mips.h ==> coff/mips.h - coff-rs6000.h ==> coff/rs6000.h - - elf-common.h ==> elf/common.h - dwarf.h ==> elf/dwarf.h - elf-external.h ==> elf/external.h - elf-internal.h ==> elf/internal.h - - a29k-opcode.h ==> opcode/a29k.h - arm-opcode.h ==> opcode/arm.h - h8300-opcode.h ==> opcode/h8300.h - i386-opcode.h ==> opcode/i386.h - i860-opcode.h ==> opcode/i860.h - i960-opcode.h ==> opcode/i960.h - m68k-opcode.h ==> opcode/m68k.h - m88k-opcode.h ==> opcode/m88k.h - mips-opcode.h ==> opcode/mips.h - np1-opcode.h ==> opcode/np1.h - ns32k-opcode.h ==> opcode/ns32k.h - pn-opcode.h ==> opcode/pn.h - pyr-opcode.h ==> opcode/pyr.h - sparc-opcode.h ==> opcode/sparc.h - tahoe-opcode.h ==> opcode/tahoe.h - vax-opcode.h ==> opcode/vax.h - - - -Wed Nov 27 10:38:31 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * internalcoff.h: (internal_scnhdr) took out #def dependency, now - s_nreloc and s_nlnno are always long. (internal_reloc): allways - has an offset field now. - -Fri Nov 22 08:12:58 1991 John Gilmore (gnu at cygnus.com) - - * coff-rs6000.h: Lint; use unsigned chars for external fields. - * internalcoff.h: Lint; cast storage classes to signed char. - -Thu Nov 21 21:01:05 1991 Per Bothner (bothner at cygnus.com) - - * stab.def: Remove the GNU extended type codes (e.g. N_SETT). - * aout64.h: The heuristic for distinguishing between - sunos-style and bsd-style ZMAGIC files (wrt. where the - text segment starts) is moved into (the default definition of) - the macro N_HEADER_IN_TEXT. This definition is only used - if no other definition is used - e.g. bfd/newsos3.c defines - N_HEADER_IN_TEXT(x) to be always 0 (as before). - -Thu Nov 21 11:53:03 1991 John Gilmore (gnu at cygnus.com) - - * aout64.h (N_TXTADDR, N_TXTOFF, N_TXTSIZE): New definitions - that should handle all uses. LOGICAL_ versions deleted. - Eliminate N_HEADER_IN_TEXT, using a_entry to determine which - kind of zmagic a.out file we are looking at. - * coff-rs6000.h: Typo. - -Tue Nov 19 18:43:37 1991 Per Bothner (bothner at cygnus.com) - - (Note: This is a revised entry, as was aout64.h.) - * aout64.h: Some cleanups of N_TXTADDR and N_TXTOFF: - Will now work for both old- and new-style ZMAGIC files, - depending on N_HEADER_IN_TEXT macro. - Add LOGICAL_TXTADDR, LOICAL_TXTOFF and LOGICAL_TXTSIZE - that don't count the exec header as part - of the text segment, to be consistent with bfd. - * a.out.sun4.h: Simplified/fixed for previous change. - -Mon Nov 18 00:02:06 1991 Fred Fish (fnf at cygnus.com) - - * dwarf.h: Update to DWARF draft 5 version from gcc2. - -Thu Nov 14 19:44:59 1991 Per Bothner (bothner at cygnus.com) - - * stab.def: Added defs for extended GNU symbol types, - such as N_SETT. These are normally ifdef'd out (because - of conflicts with a.out.gnu.h), but are used by bfb_stab_name(). - -Thu Nov 14 19:17:03 1991 Fred Fish (fnf at cygnus.com) - - * elf-common.h: Add defines to support ELF symbol table code. - -Mon Nov 11 19:01:06 1991 Fred Fish (fnf at cygnus.com) - - * elf-internal.h, elf-external.h, elf-common.h: Add support for - note sections, which are used in ELF core files to hold copies - of various /proc structures. - -Thu Nov 7 08:58:26 1991 Steve Chamberlain (sac at cygnus.com) - - * internalcoff.h: took out the M88 dependency in the lineno - struct. - * coff-m88k.h: defines GET_LINENO_LNNO and PUT_LINENO_LNNO to use - 32bit linno entries. - * a29k-opcode.h: fixed encoding of mtacc - -Sun Nov 3 11:54:22 1991 Per Bothner (bothner at cygnus.com) - - * bfd.h: Updated from ../bfd/bfd-in.h (q.v). - -Fri Nov 1 11:13:53 1991 John Gilmore (gnu at cygnus.com) - - * internalcoff.h: Add x_csect defines. - -Fri Oct 25 03:18:20 1991 John Gilmore (gnu at cygnus.com) - - * Rename COFF-related files in `coff-ARCH.h' form. - coff-a29k.h, coff-i386.h, coff-i960.h, coff-m68k.h, coff-m88k.h, - coff-mips.h, coff-rs6000.h to be exact. - -Thu Oct 24 22:11:11 1991 John Gilmore (gnu at cygnus.com) - - RS/6000 support, by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and - John Gilmore. - - * a.out.gnu.h: Update slightly. - * bfd.h: Add new error code, fix doc, add bfd_arch_rs6000. - * internalcoff.h: Add more F_ codes for filehdr. Add - rs/6000-dependent fields to aouthdr. Add storage classes - to syments. Add 6000-specific auxent. Add r_size in reloc. - * rs6000coff.c: New file. - -Thu Oct 24 04:13:20 1991 Fred Fish (fnf at cygnus.com) - - * dwarf.h: New file for dwarf support. Copied from gcc2 - distribution. - -Wed Oct 16 13:31:45 1991 John Gilmore (gnu at cygnus.com) - - * aout64.h: Remove PAGE_SIZE defines; they are target-dependent. - Add N_FN_SEQ for N_FN symbol type used on Sequent machines. - * stab.def: Include N_FN_SEQ in table. - * bout.h: External formats of structures use unsigned chars. - -Fri Oct 11 12:40:43 1991 Steve Chamberlain (steve at cygnus.com) - - * bfd.h:upgrade from bfd.c - * internalcoff.h: add n_name, n_zeroes and n_offset macros - * amdcoff.h: Define OMAGIC and AOUTHDRSZ. - -Fri Oct 11 10:58:06 1991 Per Bothner (bothner at cygnus.com) - - * a.out.host.h: Change SEGMENT_SIZE to 0x1000 for Sony. - * bfd.h (align_power): Add (actually move) comment. - -Tue Oct 8 15:29:32 1991 Per Bothner (bothner at cygnus.com) - - * sys/h-rtbsd.h: Define MISSING_VFPRINT (for binutils/bucomm.c). - -Sun Oct 6 19:24:39 1991 John Gilmore (gnu at cygnus.com) - - * aout64.h: Move struct internal_exec to ../bfd/libaout.h so - it can be shared by all `a.out-family' code. Rename - EXTERNAL_LIST_SIZE to EXTERNAL_NLIST_SIZE. Use basic types - for nlist members, and make strx integral rather than pointer. - More commentary on n_type values. - * bout.h: Provide a struct external_exec rather than an - internal_exec. - * m68kcoff.h: Remove `tagentries' which snuck in from the i960 - COFF port. - -Fri Oct 4 01:25:59 1991 John Gilmore (gnu at cygnus.com) - - * h8300-opcode.h: Remove `_enum' from the typedef for an enum. - * bfd.h: Update to match bfd changes. - - * sys/h-i386mach.h, sysdep.h: Add 386 Mach host support. - -Tue Oct 1 04:58:42 1991 John Gilmore (gnu at cygnus.com) - - * bfd.h, elf-common.h, elf-external.h, elf-internal.h: - Add preliminary ELF support, sufficient for GDB, from Fred Fish. - * sysdep.h, sys/h-amix.h: Support Amiga SVR4. - - * sys/h-vaxult.h: Make it work. (David Taylor ) - * a.out.vax.h: Remove unused and confusing file. - -Mon Sep 30 12:52:35 1991 Per Bothner (bothner at cygnus.com) - - * sysdep.h: Define NEWSOS3_SYS, and use it. - -Fri Sep 20 13:38:21 1991 John Gilmore (gnu at cygnus.com) - - * a.out.gnu.h (N_FN): Its value *really is* 0x1F. - Fix it, and add comments warning about or-ing N_EXT with it - and/or N_WARNING. - * aout64.h (N_FN): Fix value, add comments about N_EXT. - * stab.def (table at end): Update to show all the type - values <0x20, including low order bits. Move N_FN to - its rightful place. - -Tue Sep 17 17:41:37 1991 Stu Grossman (grossman at cygnus.com) - - * sys/h-irix3.h: sgi/irix support. - -Tue Sep 17 07:52:59 1991 John Gilmore (gnu at cygint.cygnus.com) - - * stab.def (N_DEFD): Add GNU Modula-2 debug stab, from Andrew - Beers. - -Thu Sep 12 14:12:59 1991 John Gilmore (gnu at cygint.cygnus.com) - - * internalcoff.h (SYMNMLEN, FILNMLEN, DIMNUM): Define these - for internalcoff, separately from the various external coff's. - * amdcoff.h, bcs88kcoff.h, i386coff.h, intel-coff.h, m68kcoff.h, - m88k-bcs.h: Prefix SYMNMLEN, FILNMLEN, and DIMNUM with E_'s for - the external struct definitions. - * ecoff.h: Remove these #define's, kludge no longer needed. - - * sys/h-ultra3.h: Add new Ultracomputer host. - * sysdep.h: Add ULTRA3_SYM1_SYS and use it. - -Tue Sep 10 10:11:46 1991 John Gilmore (gnu at cygint.cygnus.com) - - * i386coff.h (LINESZ): Always 6, not based on sizeof(). - (Fix from Peter Schauer .) - -Wed Sep 4 08:58:37 1991 John Gilmore (gnu at cygint.cygnus.com) - - * a.out.gnu.h, aout64.h: Add N_WARNING. Change N_FN to 0x0E, - to match SunOS and BSD. Add N_COMM as 0x12 for SunOS shared lib - support. - * stab.def: Add N_COMM to table, fix overlap comment. - -Tue Sep 3 06:29:20 1991 John Gilmore (gnu at cygint.cygnus.com) - - Merge with latest FSF versions of these files. - - * stab.gnu.h: Add LAST_UNUSED_STAB_CODE. - * stab.def: Update to GPL2. Move N_WARNING out, since not a - debug symbol. Change comments, and reorder table to numeric - order. Update final table comment. - (N_DSLINE, N_BSLINE): Renumber from 0x66 and 0x68, to 0x46 and 0x48. - - * obstack.h: GPL2. Merge. - -Fri Aug 23 01:54:23 1991 John Gilmore (gnu at cygint.cygnus.com) - - * a.out.gnu.h, a.out.sun4.h: Make SEGMENT_SIZE able to depend - on the particular a.out being examined. - * a.out.sun4.h: Define segment sizes for Sun-3's and Sun-4's. - * FIXME: a.out.gnu.h is almost obsolete. - * FIXME: a.out.sun4.h should be renamed a.out.sun.h now. - -Wed Aug 21 20:32:13 1991 John Gilmore (gnu at cygint.cygnus.com) - - * Start a ChangeLog for the includes directory. - - * a.out.gnu.h (N_FN): Fix value -- was 15, should be 0x1E. - * stab.def: Update allocation table in comments at end, - to reflect reality as I know it. - - -Local Variables: -mode: indented-text -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/contrib/gdb/include/ansidecl.h b/contrib/gdb/include/ansidecl.h deleted file mode 100644 index be04e42d56a..00000000000 --- a/contrib/gdb/include/ansidecl.h +++ /dev/null @@ -1,141 +0,0 @@ -/* ANSI and traditional C compatability macros - Copyright 1991, 1992 Free Software Foundation, Inc. - This file is part of the GNU C Library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* ANSI and traditional C compatibility macros - - ANSI C is assumed if __STDC__ is #defined. - - Macro ANSI C definition Traditional C definition - ----- ---- - ---------- ----------- - ---------- - PTR `void *' `char *' - LONG_DOUBLE `long double' `double' - VOLATILE `volatile' `' - SIGNED `signed' `' - PTRCONST `void *const' `char *' - ANSI_PROTOTYPES 1 not defined - - CONST is also defined, but is obsolete. Just use const. - - DEFUN (name, arglist, args) - - Defines function NAME. - - ARGLIST lists the arguments, separated by commas and enclosed in - parentheses. ARGLIST becomes the argument list in traditional C. - - ARGS list the arguments with their types. It becomes a prototype in - ANSI C, and the type declarations in traditional C. Arguments should - be separated with `AND'. For functions with a variable number of - arguments, the last thing listed should be `DOTS'. - - DEFUN_VOID (name) - - Defines a function NAME, which takes no arguments. - - obsolete -- EXFUN (name, (prototype)) -- obsolete. - - Replaced by PARAMS. Do not use; will disappear someday soon. - Was used in external function declarations. - In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in - parentheses). In traditional C it is `NAME()'. - For a function that takes no arguments, PROTOTYPE should be `(void)'. - - PARAMS ((args)) - - We could use the EXFUN macro to handle prototype declarations, but - the name is misleading and the result is ugly. So we just define a - simple macro to handle the parameter lists, as in: - - static int foo PARAMS ((int, char)); - - This produces: `static int foo();' or `static int foo (int, char);' - - EXFUN would have done it like this: - - static int EXFUN (foo, (int, char)); - - but the function is not external...and it's hard to visually parse - the function name out of the mess. EXFUN should be considered - obsolete; new code should be written to use PARAMS. - - For example: - extern int printf PARAMS ((CONST char *format DOTS)); - int DEFUN(fprintf, (stream, format), - FILE *stream AND CONST char *format DOTS) { ... } - void DEFUN_VOID(abort) { ... } -*/ - -#ifndef _ANSIDECL_H - -#define _ANSIDECL_H 1 - - -/* Every source file includes this file, - so they will all get the switch for lint. */ -/* LINTLIBRARY */ - - -#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) -/* All known AIX compilers implement these things (but don't always - define __STDC__). The RISC/OS MIPS compiler defines these things - in SVR4 mode, but does not define __STDC__. */ - -#define PTR void * -#define PTRCONST void *CONST -#define LONG_DOUBLE long double - -#define AND , -#define NOARGS void -#define CONST const -#define VOLATILE volatile -#define SIGNED signed -#define DOTS , ... - -#define EXFUN(name, proto) name proto -#define DEFUN(name, arglist, args) name(args) -#define DEFUN_VOID(name) name(void) - -#define PROTO(type, name, arglist) type name arglist -#define PARAMS(paramlist) paramlist -#define ANSI_PROTOTYPES 1 - -#else /* Not ANSI C. */ - -#define PTR char * -#define PTRCONST PTR -#define LONG_DOUBLE double - -#define AND ; -#define NOARGS -#define CONST -#ifndef const /* some systems define it in header files for non-ansi mode */ -#define const -#endif -#define VOLATILE -#define SIGNED -#define DOTS - -#define EXFUN(name, proto) name() -#define DEFUN(name, arglist, args) name arglist args; -#define DEFUN_VOID(name) name() -#define PROTO(type, name, arglist) type name () -#define PARAMS(paramlist) () - -#endif /* ANSI C. */ - -#endif /* ansidecl.h */ diff --git a/contrib/gdb/include/aout/ChangeLog b/contrib/gdb/include/aout/ChangeLog deleted file mode 100644 index 307448bc87f..00000000000 --- a/contrib/gdb/include/aout/ChangeLog +++ /dev/null @@ -1,174 +0,0 @@ -Mon Mar 11 12:15:52 1996 Ian Lance Taylor - - * stab.def: Use __define_stab_duplicate rather than __define_stab - for duplicate entries N_BROWS and N_MOD2. - * stab_gnu.h (__define_stab_duplicate): Define before including - stab.def. - -Fri Oct 27 17:47:16 1995 Niklas Hallqvist - - * aout64.h, host.h, hp300hpux.h, sun4.h: Changed PAGE_SIZE to - TARGET_PAGE_SIZE. - -Tue Sep 12 12:07:02 1995 Ian Lance Taylor - - * sun4.h (struct internal_sun4_dynamic_link): Change all fields - from long to unsigned long. - -Wed Jul 12 00:15:13 1995 Ken Raeburn - - * sun4.h (PAGE_SIZE): Undefine before defining. - -Thu Jun 16 14:22:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * aout64.h (BMAGIC): Define. - -Sat Jun 11 16:16:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - Add weak symbols as an extension to a.out. - * aout64.h (N_WEAKU, N_WEAKA, N_WEAKT, N_WEAKD, N_WEAKB): Define. - * stab.def: Update symbol value table. - -Thu Jun 2 17:13:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * sun4.h (EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE): Correct from 28 to - 24. Fix up ld_got comment. - -Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dynix3.h: Cleanup, adapt to current bfd version. - -Sat Feb 26 10:25:53 1994 Ian Lance Taylor (ian@cygnus.com) - - * aout64.h: Add casts to avoid warnings from SVR4 cc. - -Fri Feb 11 12:56:04 1994 Stan Shebs (shebs@andros.cygnus.com) - - * ar.h (ARMAG, ARMAGB, ARFMAG): Change '\n' to '\012', for greater - portability. - -Fri Jan 21 00:59:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * sun4.h: Added information about SunOS shared libraries. - -Fri Jan 7 08:20:13 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * aout64.h (N_TXTADDR): Add comment regarding OMAGIC and NMAGIC. - -Sat Dec 25 14:55:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * aout64.h (N_DATOFF): Don't pad (revert change of 8 Jul 1993). - -Tue Nov 16 15:43:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * aout64.h: New macros ZMAGIC_DISK_BLOCK_SIZE and N_DISK_BLOCK_SIZE - for Linux ZMAGIC. - (N_TXTOFF, N_DATOFF): Use them. - -Thu Nov 4 00:33:48 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * aout64.h (RELOC_STD_BITS_RELATIVE_LITTLE): Fixed value to match - sun3 system; used to overlap other fields. - (RELOC_STD_BITS_JMPTABLE_LITTLE): Likewise. - -Wed Nov 3 13:48:27 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * aout64.h (RELOC_STD_BITS_BASEREL_LITTLE): Make it 0x10 (Ken's - suggestion) to avoid conflict with RELOC_STD_BITS_EXTERN_LITTLE. - -Fri Oct 29 15:09:52 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * hp300hpux.h (N_SHARED_LIB): Define to be 0. - -Mon Sep 13 21:00:56 1993 John Gilmore (gnu@cygnus.com) - - * ar.h (ARMAP_TIME_OFFSET): Add and describe. - -Mon Aug 23 Sean Fagan (sef@cygnus.com) - - * aout64.h [ARCH_SIZE != 64]: Allow N_BADMAG to be overridden. - -Mon Aug 16 14:30:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stab_gnu.h: Include aout/stab.def not just stab.def. - -Sun Jul 18 21:41:47 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * dynix3.h: New, for symmetry running dynix. - -Thu Jul 8 12:52:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * aout64.h (N_BADMAG): Recognize QMAGIC. - N_TXTOFF, N_TXTADDR, N_TXTSIZE: Special code for QMAGIC. - N_DATOFF: Pad text size if we need to. - -Fri Jun 18 19:19:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * stab.def (N_ECOML): Fix comment. - -Mon May 31 09:21:30 1993 Jim Kingdon (kingdon@cygnus.com) - - * stab.def: Remove Solaris information on N_FUN stabstring grammar; - I've transferred it to gdb/doc/stabs.texinfo, where it belongs. - -Mon May 10 05:48:43 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * hp300hpux.h: Patch from Glenn Engel for linker problem and - compatibility fix: - (OMAGIC, NMAGIC): New definitions. - (SHAREMAGIC): Deleted. - (HPUX_DOT_O_MAGIC): New macro. - (_N_BADMAG): Adjusted. - (N_HEADER_IN_TEXT, N_DATADDR): New macros. - -Thu Apr 29 12:07:37 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * hp300hpux.h: New file from Glenn Engel, glenne@lsid.hp.com. - -Tue Apr 27 05:51:04 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * aout64.h (struct external_exec, *MAGIC, N_BADMAG): Don't define - if `external_exec' is already defined as a macro. - (N_DATOFF, N_TRELOFF, N_DRELOFF, N_SYMOFF, N_STROFF): Don't define - if already defined. - (struct external_nlist, EXTERNAL_NLIST_SIZE): Don't define if - `external_nlist' is already defined as a macro. - -Sat Aug 15 04:23:02 1992 John Gilmore (gnu@cygnus.com) - - * adobe.h: Add description of a.out.adobe format. - -Fri Jul 3 00:36:52 1992 John Gilmore (gnu at cygnus.com) - - * stab.def: Update more Solaris definitions. - * stab_gnu.h: Add N_SO language types, and Solaris basic float types. - -Sun Jun 14 10:53:53 1992 John Gilmore (gnu at cygnus.com) - - * stab.def: Update descriptions of Solaris-2 stabs; add N_UNDF. - -Thu Jun 11 01:12:07 1992 John Gilmore (gnu at cygnus.com) - - * stab.def: Add N_OBJ and N_OPT from Solaris-2. - -Thu Jan 30 18:12:44 1992 John Gilmore (gnu at cygnus.com) - - * aout/aout64.h: N_TXTSIZE needs some more parentheses. - I don't trust C precedence. - -Wed Dec 18 14:32:01 1991 Per Bothner (bothner at cygnus.com) - - * aout/aout64.h: Move common sunos-specific test - to recognize shared libraries into new macro N_SHARED_LIB. - Use it to simplify&reformat N_TXTADDR, N_TXTOFF, N_TXTSIZE. - -Sat Nov 30 20:34:52 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * ChangeLog, aout64.h, ar.h, encap.h, host.h, hp.h, ranlib.h, - reloc.h, stab.def, stab_gnu.h, sun4.h: All moved from the - devo/include directory - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/include/aout/adobe.h b/contrib/gdb/include/aout/adobe.h deleted file mode 100644 index 3d2f15c6cb7..00000000000 --- a/contrib/gdb/include/aout/adobe.h +++ /dev/null @@ -1,297 +0,0 @@ -/* `a.out.adobe' differences from standard a.out files */ - -#ifndef __A_OUT_ADOBE_H__ -#define __A_OUT_ADOBE_H__ - -#define BYTES_IN_WORD 4 - -/* Struct external_exec is the same. */ - -/* This is the layout on disk of the 32-bit or 64-bit exec header. */ - -struct external_exec -{ - bfd_byte e_info[4]; /* magic number and stuff */ - bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */ - bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */ - bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */ - bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */ - bfd_byte e_entry[BYTES_IN_WORD]; /* start address */ - bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */ - bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */ -}; - -#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7) - -/* Magic numbers for a.out files */ - -#undef ZMAGIC -#define ZMAGIC 0xAD0BE /* Cute, eh? */ -#undef OMAGIC -#undef NMAGIC - -#define N_BADMAG(x) ((x).a_info != ZMAGIC) - -/* By default, segment size is constant. But some machines override this - to be a function of the a.out header (e.g. machine type). */ -#ifndef N_SEGSIZE -#define N_SEGSIZE(x) SEGMENT_SIZE -#endif -#undef N_SEGSIZE /* FIXMEXXXX */ - -/* Segment information for the a.out.Adobe format is specified after the - file header. It contains N segment descriptors, followed by one with - a type of zero. - - The actual text of the segments starts at N_TXTOFF in the file, - regardless of how many or how few segment headers there are. */ - -struct external_segdesc { - unsigned char e_type[1]; - unsigned char e_size[3]; - unsigned char e_virtbase[4]; - unsigned char e_filebase[4]; -}; - -struct internal_segdesc { - unsigned int a_type:8; /* Segment type N_TEXT, N_DATA, 0 */ - unsigned int a_size:24; /* Segment size */ - bfd_vma a_virtbase; /* Virtual address */ - unsigned int a_filebase; /* Base address in object file */ -}; - -#define N_TXTADDR(x) \ - -/* This is documented to be at 1024, but appears to really be at 2048. - FIXME?! */ -#define N_TXTOFF(x) 2048 - -#define N_TXTSIZE(x) ((x).a_text) - -#define N_DATADDR(x) - -#define N_BSSADDR(x) - -/* Offsets of the various portions of the file after the text segment. */ - -#define N_DATOFF(x) ( N_TXTOFF(x) + N_TXTSIZE(x) ) -#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data ) -#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize ) -#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize ) -#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) - -/* Symbols */ -struct external_nlist { - bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */ - bfd_byte e_type[1]; /* type of symbol */ - bfd_byte e_other[1]; /* misc info (usually empty) */ - bfd_byte e_desc[2]; /* description field */ - bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */ -}; - -#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD) - -struct internal_nlist { - unsigned long n_strx; /* index into string table of name */ - unsigned char n_type; /* type of symbol */ - unsigned char n_other; /* misc info (usually empty) */ - unsigned short n_desc; /* description field */ - bfd_vma n_value; /* value of symbol */ -}; - -/* The n_type field is the symbol type, containing: */ - -#define N_UNDF 0 /* Undefined symbol */ -#define N_ABS 2 /* Absolute symbol -- defined at particular addr */ -#define N_TEXT 4 /* Text sym -- defined at offset in text seg */ -#define N_DATA 6 /* Data sym -- defined at offset in data seg */ -#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */ -#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */ -#define N_FN 0x1f /* File name of .o file */ -#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */ -/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT, - N_DATA, or N_BSS. When the low-order bit of other types is set, - (e.g. N_WARNING versus N_FN), they are two different types. */ -#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */ -#define N_TYPE 0x1e -#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */ - -#define N_INDR 0x0a - -/* The following symbols refer to set elements. - All the N_SET[ATDB] symbols with the same name form one set. - Space is allocated for the set in the text section, and each set - elements value is stored into one word of the space. - The first word of the space is the length of the set (number of elements). - - The address of the set is made into an N_SETV symbol - whose name is the same as the name of the set. - This symbol acts like a N_DATA global symbol - in that it can satisfy undefined external references. */ - -/* These appear as input to LD, in a .o file. */ -#define N_SETA 0x14 /* Absolute set element symbol */ -#define N_SETT 0x16 /* Text set element symbol */ -#define N_SETD 0x18 /* Data set element symbol */ -#define N_SETB 0x1A /* Bss set element symbol */ - -/* This is output from LD. */ -#define N_SETV 0x1C /* Pointer to set vector in data area. */ - -/* Warning symbol. The text gives a warning message, the next symbol - in the table will be undefined. When the symbol is referenced, the - message is printed. */ - -#define N_WARNING 0x1e - -/* Relocations - - There are two types of relocation flavours for a.out systems, - standard and extended. The standard form is used on systems where the - instruction has room for all the bits of an offset to the operand, whilst - the extended form is used when an address operand has to be split over n - instructions. Eg, on the 68k, each move instruction can reference - the target with a displacement of 16 or 32 bits. On the sparc, move - instructions use an offset of 14 bits, so the offset is stored in - the reloc field, and the data in the section is ignored. -*/ - -/* This structure describes a single relocation to be performed. - The text-relocation section of the file is a vector of these structures, - all of which apply to the text section. - Likewise, the data-relocation section applies to the data section. */ - -struct reloc_std_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - 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_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_SH_LITTLE 1 - -#define RELOC_STD_BITS_EXTERN_BIG 0x10 -#define RELOC_STD_BITS_EXTERN_LITTLE 0x08 - -#define RELOC_STD_BITS_BASEREL_BIG 0x08 -#define RELOC_STD_BITS_BASEREL_LITTLE 0x08 - -#define RELOC_STD_BITS_JMPTABLE_BIG 0x04 -#define RELOC_STD_BITS_JMPTABLE_LITTLE 0x04 - -#define RELOC_STD_BITS_RELATIVE_BIG 0x02 -#define RELOC_STD_BITS_RELATIVE_LITTLE 0x02 - -#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */ - -struct reloc_std_internal -{ - bfd_vma r_address; /* Address (within segment) to be relocated. */ - /* The meaning of r_symbolnum depends on r_extern. */ - unsigned int r_symbolnum:24; - /* Nonzero means value is a pc-relative offset - and it should be relocated for changes in its own address - as well as for changes in the symbol or section specified. */ - unsigned int r_pcrel:1; - /* Length (as exponent of 2) of the field to be relocated. - Thus, a value of 2 indicates 1<<2 bytes. */ - unsigned int r_length:2; - /* 1 => relocate with value of symbol. - r_symbolnum is the index of the symbol - in files the symbol table. - 0 => relocate with the address of a segment. - r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS - (the N_EXT bit may be set also, but signifies nothing). */ - unsigned int r_extern:1; - /* The next three bits are for SunOS shared libraries, and seem to - be undocumented. */ - unsigned int r_baserel:1; /* Linkage table relative */ - unsigned int r_jmptable:1; /* pc-relative to jump table */ - unsigned int r_relative:1; /* "relative relocation" */ - /* unused */ - unsigned int r_pad:1; /* Padding -- set to zero */ -}; - - -/* EXTENDED RELOCS */ - -struct reloc_ext_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - bfd_byte r_type[1]; /* relocation type */ - 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_TYPE_BIG 0x1F -#define RELOC_EXT_BITS_TYPE_SH_BIG 0 -#define RELOC_EXT_BITS_TYPE_LITTLE 0xF8 -#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3 - -/* Bytes per relocation entry */ -#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD) - -enum reloc_type -{ - /* simple relocations */ - RELOC_8, /* data[0:7] = addend + sv */ - RELOC_16, /* data[0:15] = addend + sv */ - RELOC_32, /* data[0:31] = addend + sv */ - /* pc-rel displacement */ - RELOC_DISP8, /* data[0:7] = addend - pc + sv */ - RELOC_DISP16, /* data[0:15] = addend - pc + sv */ - RELOC_DISP32, /* data[0:31] = addend - pc + sv */ - /* Special */ - RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */ - RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */ - RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */ - RELOC_22, /* data[0:21] = (addend + sv) */ - RELOC_13, /* data[0:12] = (addend + sv) */ - RELOC_LO10, /* data[0:9] = (addend + sv) */ - RELOC_SFA_BASE, - RELOC_SFA_OFF13, - /* P.I.C. (base-relative) */ - RELOC_BASE10, /* Not sure - maybe we can do this the */ - RELOC_BASE13, /* right way now */ - RELOC_BASE22, - /* for some sort of pc-rel P.I.C. (?) */ - RELOC_PC10, - RELOC_PC22, - /* P.I.C. jump table */ - RELOC_JMP_TBL, - /* reputedly for shared libraries somehow */ - RELOC_SEGOFF16, - RELOC_GLOB_DAT, - RELOC_JMP_SLOT, - RELOC_RELATIVE, - - RELOC_11, - RELOC_WDISP2_14, - RELOC_WDISP19, - RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */ - RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */ - - /* 29K relocation types */ - RELOC_JUMPTARG, - RELOC_CONST, - RELOC_CONSTH, - - NO_RELOC - }; - - -struct reloc_internal { - bfd_vma r_address; /* offset of of data to relocate */ - long r_index; /* symbol table index of symbol */ - enum reloc_type r_type; /* relocation type */ - bfd_vma r_addend; /* datum addend */ -}; - -#endif /* __A_OUT_ADOBE_H__ */ diff --git a/contrib/gdb/include/aout/aout64.h b/contrib/gdb/include/aout/aout64.h deleted file mode 100644 index 76f1140b682..00000000000 --- a/contrib/gdb/include/aout/aout64.h +++ /dev/null @@ -1,475 +0,0 @@ -/* `a.out' object-file definitions, including extensions to 64-bit fields */ - -#ifndef __A_OUT_64_H__ -#define __A_OUT_64_H__ - -/* This is the layout on disk of the 32-bit or 64-bit exec header. */ - -#ifndef external_exec -struct external_exec -{ - bfd_byte e_info[4]; /* magic number and stuff */ - bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */ - bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */ - bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */ - bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */ - bfd_byte e_entry[BYTES_IN_WORD]; /* start address */ - bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */ - bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */ -}; - -#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7) - -/* Magic numbers for a.out files */ - -#if ARCH_SIZE==64 -#define OMAGIC 0x1001 /* Code indicating object file */ -#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */ -#define NMAGIC 0x1003 /* Code indicating pure executable. */ - -/* There is no 64-bit QMAGIC as far as I know. */ - -#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC) -#else -#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. - It is used by 386BSD (and variants) and Linux, at least. */ -#ifndef QMAGIC -#define QMAGIC 0314 -#endif -# ifndef N_BADMAG -# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC \ - && N_MAGIC(x) != QMAGIC) -# endif /* N_BADMAG */ -#endif - -#endif - -#ifdef QMAGIC -#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC) -#else -#define N_IS_QMAGIC(x) (0) -#endif - -/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is - 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 - text segment and the data segment (in memory; on disk the padding - between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same - for most machines, but different for sun3. */ - -/* By default, segment size is constant. But some machines override this - to be a function of the a.out header (e.g. machine type). */ - -#ifndef N_SEGSIZE -#define N_SEGSIZE(x) SEGMENT_SIZE -#endif - -/* Virtual memory address of the text section. - This is getting very complicated. A good reason to discard a.out format - for something that specifies these fields explicitly. But til then... - - * OMAGIC and NMAGIC files: - (object files: text for "relocatable addr 0" right after the header) - start at 0, offset is EXEC_BYTES_SIZE, size as stated. - * The text address, offset, and size of ZMAGIC files depend - on the entry point of the file: - * entry point below TEXT_START_ADDR: - (hack for SunOS shared libraries) - start at 0, offset is 0, size as stated. - * If N_HEADER_IN_TEXT(x) is true (which defaults to being the - case when the entry point is EXEC_BYTES_SIZE or further into a page): - no padding is needed; text can start after exec header. Sun - considers the text segment of such files to include the exec header; - for BFD's purposes, we don't, which makes more work for us. - start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE, - size as stated minus EXEC_BYTES_SIZE. - * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when - the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page - aligned)): (padding is needed so that text can start at a page boundary) - start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated. - - Specific configurations may want to hardwire N_HEADER_IN_TEXT, - for efficiency or to allow people to play games with the entry point. - In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos, - and as 0 for most other hosts (Sony News, Vax Ultrix, etc). - (Do this in the appropriate bfd target file.) - (The default is a heuristic that will break if people try changing - the entry point, perhaps with the ld -e flag.) - - * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true, - and for which the starting address is TARGET_PAGE_SIZE (or should this be - SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC). - */ - -/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header - in the text. */ -#ifndef N_HEADER_IN_TEXT -#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE) -#endif - -/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC - files. */ -#ifndef N_SHARED_LIB -#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, */ \ - /* with the header in the text. */ \ - N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \ - N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\ - N_SHARED_LIB(x) ? 0 : \ - N_HEADER_IN_TEXT(x) ? \ - TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\ - TEXT_START_ADDR /* a page of padding */\ - ) -#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 TARGET_PAGE_SIZE. But for Linux, in the - time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is - not what TARGET_PAGE_SIZE needs to be for QMAGIC. */ - -#ifndef ZMAGIC_DISK_BLOCK_SIZE -#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE -#endif - -#define N_DISK_BLOCK_SIZE(x) \ - (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE) - -/* Offset in an a.out of the start of the text section. */ -#ifndef N_TXTOFF -#define N_TXTOFF(x) \ - (/* For {O,N,Q}MAGIC, no padding. */ \ - N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \ - N_SHARED_LIB(x) ? 0 : \ - N_HEADER_IN_TEXT(x) ? \ - EXEC_BYTES_SIZE : /* no padding */\ - ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\ - ) -#endif -/* Size of the text section. It's always as stated, except that we - offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF - for ZMAGIC files that nominally include the exec header - as part of the first page of text. (BFD doesn't consider the - exec header to be part of the text segment.) */ -#ifndef N_TXTSIZE -#define N_TXTSIZE(x) \ - (/* For QMAGIC, we don't consider the header part of the text section. */\ - N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \ - (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \ - N_HEADER_IN_TEXT(x) ? \ - (x).a_text - EXEC_BYTES_SIZE: /* no padding */\ - (x).a_text /* a page of padding */\ - ) -#endif -/* The address of the data segment in virtual memory. - It is the text segment address, plus text segment size, rounded - up to a N_SEGSIZE boundary for pure or pageable files. */ -#ifndef N_DATADDR -#define N_DATADDR(x) \ - (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \ - : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1)))) -#endif -/* The address of the BSS segment -- immediately after the data segment. */ - -#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data) - -/* Offsets of the various portions of the file after the text segment. */ - -/* 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_TXTOFF(x) + N_TXTSIZE(x)) -#endif - -#ifndef N_TRELOFF -#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data ) -#endif -#ifndef N_DRELOFF -#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize ) -#endif -#ifndef N_SYMOFF -#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize ) -#endif -#ifndef N_STROFF -#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) -#endif - -/* Symbols */ -#ifndef external_nlist -struct external_nlist { - bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */ - bfd_byte e_type[1]; /* type of symbol */ - bfd_byte e_other[1]; /* misc info (usually empty) */ - bfd_byte e_desc[2]; /* description field */ - bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */ -}; -#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD) -#endif - -struct internal_nlist { - unsigned long n_strx; /* index into string table of name */ - unsigned char n_type; /* type of symbol */ - unsigned char n_other; /* misc info (usually empty) */ - unsigned short n_desc; /* description field */ - bfd_vma n_value; /* value of symbol */ -}; - -/* The n_type field is the symbol type, containing: */ - -#define N_UNDF 0 /* Undefined symbol */ -#define N_ABS 2 /* Absolute symbol -- defined at particular addr */ -#define N_TEXT 4 /* Text sym -- defined at offset in text seg */ -#define N_DATA 6 /* Data sym -- defined at offset in data seg */ -#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */ -#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */ -#define N_FN 0x1f /* File name of .o file */ -#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */ -/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT, - N_DATA, or N_BSS. When the low-order bit of other types is set, - (e.g. N_WARNING versus N_FN), they are two different types. */ -#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */ -#define N_TYPE 0x1e -#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */ - -#define N_INDR 0x0a - -/* The following symbols refer to set elements. - All the N_SET[ATDB] symbols with the same name form one set. - Space is allocated for the set in the text section, and each set - elements value is stored into one word of the space. - The first word of the space is the length of the set (number of elements). - - The address of the set is made into an N_SETV symbol - whose name is the same as the name of the set. - This symbol acts like a N_DATA global symbol - in that it can satisfy undefined external references. */ - -/* These appear as input to LD, in a .o file. */ -#define N_SETA 0x14 /* Absolute set element symbol */ -#define N_SETT 0x16 /* Text set element symbol */ -#define N_SETD 0x18 /* Data set element symbol */ -#define N_SETB 0x1A /* Bss set element symbol */ - -/* This is output from LD. */ -#define N_SETV 0x1C /* Pointer to set vector in data area. */ - -/* Warning symbol. The text gives a warning message, the next symbol - in the table will be undefined. When the symbol is referenced, the - message is printed. */ - -#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, - standard and extended. The standard form is used on systems where the - instruction has room for all the bits of an offset to the operand, whilst - the extended form is used when an address operand has to be split over n - instructions. Eg, on the 68k, each move instruction can reference - the target with a displacement of 16 or 32 bits. On the sparc, move - instructions use an offset of 14 bits, so the offset is stored in - the reloc field, and the data in the section is ignored. -*/ - -/* This structure describes a single relocation to be performed. - The text-relocation section of the file is a vector of these structures, - all of which apply to the text section. - Likewise, the data-relocation section applies to the data section. */ - -struct reloc_std_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - bfd_byte r_type[1]; /* relocation type */ -}; - -#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80) -#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01) - -#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 ((unsigned int) 0x10) -#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 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 ((unsigned int) 0x04) -#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20) - -#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 */ - -struct reloc_std_internal -{ - bfd_vma r_address; /* Address (within segment) to be relocated. */ - /* The meaning of r_symbolnum depends on r_extern. */ - unsigned int r_symbolnum:24; - /* Nonzero means value is a pc-relative offset - and it should be relocated for changes in its own address - as well as for changes in the symbol or section specified. */ - unsigned int r_pcrel:1; - /* Length (as exponent of 2) of the field to be relocated. - Thus, a value of 2 indicates 1<<2 bytes. */ - unsigned int r_length:2; - /* 1 => relocate with value of symbol. - r_symbolnum is the index of the symbol - in files the symbol table. - 0 => relocate with the address of a segment. - r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS - (the N_EXT bit may be set also, but signifies nothing). */ - unsigned int r_extern:1; - /* The next three bits are for SunOS shared libraries, and seem to - be undocumented. */ - unsigned int r_baserel:1; /* Linkage table relative */ - unsigned int r_jmptable:1; /* pc-relative to jump table */ - unsigned int r_relative:1; /* "relative relocation" */ - /* unused */ - unsigned int r_pad:1; /* Padding -- set to zero */ -}; - - -/* EXTENDED RELOCS */ - -struct reloc_ext_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - bfd_byte r_type[1]; /* relocation type */ - bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */ -}; - -#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80) -#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01) - -#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F) -#define RELOC_EXT_BITS_TYPE_SH_BIG 0 -#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8) -#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3 - -/* Bytes per relocation entry */ -#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD) - -enum reloc_type -{ - /* simple relocations */ - RELOC_8, /* data[0:7] = addend + sv */ - RELOC_16, /* data[0:15] = addend + sv */ - RELOC_32, /* data[0:31] = addend + sv */ - /* pc-rel displacement */ - RELOC_DISP8, /* data[0:7] = addend - pc + sv */ - RELOC_DISP16, /* data[0:15] = addend - pc + sv */ - RELOC_DISP32, /* data[0:31] = addend - pc + sv */ - /* Special */ - RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */ - RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */ - RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */ - RELOC_22, /* data[0:21] = (addend + sv) */ - RELOC_13, /* data[0:12] = (addend + sv) */ - RELOC_LO10, /* data[0:9] = (addend + sv) */ - RELOC_SFA_BASE, - RELOC_SFA_OFF13, - /* P.I.C. (base-relative) */ - RELOC_BASE10, /* Not sure - maybe we can do this the */ - RELOC_BASE13, /* right way now */ - RELOC_BASE22, - /* for some sort of pc-rel P.I.C. (?) */ - RELOC_PC10, - RELOC_PC22, - /* P.I.C. jump table */ - RELOC_JMP_TBL, - /* reputedly for shared libraries somehow */ - RELOC_SEGOFF16, - RELOC_GLOB_DAT, - RELOC_JMP_SLOT, - RELOC_RELATIVE, - - RELOC_11, - RELOC_WDISP2_14, - RELOC_WDISP19, - RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */ - RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */ - - /* 29K relocation types */ - RELOC_JUMPTARG, - 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 - understand ? Should we sort the values ? What about using a - microcode format like the 68k ? - */ - NO_RELOC - }; - - -struct reloc_internal { - bfd_vma r_address; /* offset of of data to relocate */ - long r_index; /* symbol table index of symbol */ - enum reloc_type r_type; /* relocation type */ - bfd_vma r_addend; /* datum addend */ -}; - -/* Q. - Should the length of the string table be 4 bytes or 8 bytes ? - - Q. - What about archive indexes ? - - */ - -#endif /* __A_OUT_64_H__ */ diff --git a/contrib/gdb/include/aout/ar.h b/contrib/gdb/include/aout/ar.h deleted file mode 100644 index 7b5dcdabd10..00000000000 --- a/contrib/gdb/include/aout/ar.h +++ /dev/null @@ -1,36 +0,0 @@ -/* archive file definition for GNU software */ - -/* So far this is correct for BSDish archives. Don't forget that - files must begin on an even byte boundary. */ - -#ifndef __GNU_AR_H__ -#define __GNU_AR_H__ - -/* 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 "!\012" /* For COFF and a.out archives */ -#define ARMAGB "!\012" /* For b.out archives */ -#define SARMAG 8 -#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 - BSD-derived linkers complain. We originally write the ar_date with - this offset from the real file's mod-time. After finishing the - file, we rewrite ar_date if it's not still greater than the mod date. */ - -#define ARMAP_TIME_OFFSET 60 - -struct ar_hdr { - char ar_name[16]; /* name of this member */ - char ar_date[12]; /* file mtime */ - char ar_uid[6]; /* owner uid; printed as decimal */ - char ar_gid[6]; /* owner gid; printed as decimal */ - char ar_mode[8]; /* file mode, printed as octal */ - char ar_size[10]; /* file size, printed as decimal */ - char ar_fmag[2]; /* should contain ARFMAG */ -}; - -#endif /* __GNU_AR_H__ */ diff --git a/contrib/gdb/include/aout/dynix3.h b/contrib/gdb/include/aout/dynix3.h deleted file mode 100644 index efeeebfc4cc..00000000000 --- a/contrib/gdb/include/aout/dynix3.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * a.out specifics for Sequent Symmetry running Dynix 3.x - */ -#ifndef A_OUT_DYNIX3_H -#define A_OUT_DYNIX3_H - -#define external_exec dynix_external_exec - -/* struct exec for Dynix 3 - * - * a_gdtbl and a_bootstrap are only for standalone binaries. - * Shared data fields are not supported by the kernel as of Dynix 3.1, - * but are supported by Dynix compiler programs. - */ -struct dynix_external_exec { - unsigned char e_info[4]; - unsigned char e_text[4]; - unsigned char e_data[4]; - unsigned char e_bss[4]; - unsigned char e_syms[4]; - unsigned char e_entry[4]; - unsigned char e_trsize[4]; - unsigned char e_drsize[4]; - unsigned char e_g_code[8], e_g_data[8], e_g_desc[8]; - unsigned char e_shdata[4]; - unsigned char e_shbss[4]; - unsigned char e_shdrsize[4]; - unsigned char e_bootstrap[44]; - unsigned char e_reserved[12]; - unsigned char e_version[4]; -}; - -#define EXEC_BYTES_SIZE (128) - -/* - * All executables under Dynix are demand paged with read-only text, - * Thus no NMAGIC. - * - * ZMAGIC has a page of 0s at virtual 0, - * XMAGIC has an invalid page at virtual 0 - */ -#define OMAGIC 0x12eb /* .o */ -#define ZMAGIC 0x22eb /* zero @ 0, demand load */ -#define XMAGIC 0x32eb /* invalid @ 0, demand load */ -#define SMAGIC 0x42eb /* standalone, not supported here */ - -#define N_BADMAG(x) ((OMAGIC != N_MAGIC(x)) && \ - (ZMAGIC != N_MAGIC(x)) && \ - (XMAGIC != N_MAGIC(x)) && \ - (SMAGIC != N_MAGIC(x))) - -#define N_ADDRADJ(x) ((ZMAGIC == N_MAGIC(x) || XMAGIC == N_MAGIC(x)) ? 0x1000 : 0) - -#define N_TXTOFF(x) (EXEC_BYTES_SIZE) -#define N_DATOFF(x) (N_TXTOFF(x) + N_TXTSIZE(x)) -#define N_SHDATOFF(x) (N_DATOFF(x) + (x).a_data) -#define N_TRELOFF(x) (N_SHDATOFF(x) + (x).a_shdata) -#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize) -#define N_SHDRELOFF(x) (N_DRELOFF(x) + (x).a_drsize) -#define N_SYMOFF(x) (N_SHDRELOFF(x) + (x).a_shdrsize) -#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms) - -#define N_TXTADDR(x) \ - (((OMAGIC == N_MAGIC(x)) || (SMAGIC == N_MAGIC(x))) ? 0 \ - : TEXT_START_ADDR + EXEC_BYTES_SIZE) - -#define N_TXTSIZE(x) \ - (((OMAGIC == N_MAGIC(x)) || (SMAGIC == N_MAGIC(x))) ? ((x).a_text) \ - : ((x).a_text - N_ADDRADJ(x) - EXEC_BYTES_SIZE)) - -#endif /* A_OUT_DYNIX3_H */ diff --git a/contrib/gdb/include/aout/encap.h b/contrib/gdb/include/aout/encap.h deleted file mode 100644 index b215d49be16..00000000000 --- a/contrib/gdb/include/aout/encap.h +++ /dev/null @@ -1,135 +0,0 @@ -/* Yet Another Try at encapsulating bsd object files in coff. - Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. - Written by Pace Willisson 12/9/88 - - This file is obsolete. It needs to be converted to just define a bunch - of stuff that BFD can use to do coff-encapsulated files. --gnu@cygnus.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - * We only use the coff headers to tell the kernel - * how to exec the file. Therefore, the only fields that need to - * be filled in are the scnptr and vaddr for the text and data - * sections, and the vaddr for the bss. As far as coff is concerned, - * there is no symbol table, relocation, or line numbers. - * - * A normal bsd header (struct exec) is placed after the coff headers, - * and before the real text. I defined a the new fields 'a_machtype' - * and a_flags. If a_machtype is M_386, and a_flags & A_ENCAP is - * true, then the bsd header is preceeded by a coff header. Macros - * like N_TXTOFF and N_TXTADDR use this field to find the bsd header. - * - * The only problem is to track down the bsd exec header. The - * macros HEADER_OFFSET, etc do this. - */ - -#define N_FLAGS_COFF_ENCAPSULATE 0x20 /* coff header precedes bsd header */ - -/* Describe the COFF header used for encapsulation. */ - -struct coffheader -{ - /* filehdr */ - unsigned short f_magic; - unsigned short f_nscns; - long f_timdat; - long f_symptr; - long f_nsyms; - unsigned short f_opthdr; - unsigned short f_flags; - /* aouthdr */ - short magic; - short vstamp; - long tsize; - long dsize; - long bsize; - long entry; - long text_start; - long data_start; - struct coffscn - { - char s_name[8]; - long s_paddr; - long s_vaddr; - long s_size; - long s_scnptr; - long s_relptr; - long s_lnnoptr; - unsigned short s_nreloc; - unsigned short s_nlnno; - long s_flags; - } scns[3]; -}; - -/* Describe some of the parameters of the encapsulation, - including how to find the encapsulated BSD header. */ - -/* FIXME, this is dumb. The same tools can't handle a.outs for different - architectures, just because COFF_MAGIC is different; so you need a - separate GNU nm for every architecture!!? Unfortunately, it needs to - be this way, since the COFF_MAGIC value is determined by the kernel - we're trying to fool here. */ - -#define COFF_MAGIC_I386 0514 /* I386MAGIC */ -#define COFF_MAGIC_M68K 0520 /* MC68MAGIC */ -#define COFF_MAGIC_A29K 0x17A /* Used by asm29k cross-tools */ - -#ifdef COFF_MAGIC -short __header_offset_temp; -#define HEADER_OFFSET(f) \ - (__header_offset_temp = 0, \ - fread ((char *)&__header_offset_temp, sizeof (short), 1, (f)), \ - fseek ((f), -sizeof (short), 1), \ - __header_offset_temp==COFF_MAGIC ? sizeof(struct coffheader) : 0) -#else -#define HEADER_OFFSET(f) 0 -#endif - -#define HEADER_SEEK(f) (fseek ((f), HEADER_OFFSET((f)), 1)) - -/* Describe the characteristics of the BSD header - that appears inside the encapsulation. */ - -/* Encapsulated coff files that are linked ZMAGIC have a text segment - offset just past the header (and a matching TXTADDR), excluding - the headers from the text segment proper but keeping the physical - layout and the virtual memory layout page-aligned. - - Non-encapsulated a.out files that are linked ZMAGIC have a text - segment that starts at 0 and an N_TXTADR similarly offset to 0. - They too are page-aligned with each other, but they include the - a.out header as part of the text. - - The _N_HDROFF gets sizeof struct exec added to it, so we have - to compensate here. See . */ - -#undef _N_HDROFF -#undef N_TXTADDR -#undef N_DATADDR - -#define _N_HDROFF(x) ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \ - sizeof (struct coffheader) : 0) - -/* Address of text segment in memory after it is loaded. */ -#define N_TXTADDR(x) \ - ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \ - sizeof (struct coffheader) + sizeof (struct exec) : 0) -#define SEGMENT_SIZE 0x400000 - -#define N_DATADDR(x) \ - ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \ - (SEGMENT_SIZE + ((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1))) : \ - (N_TXTADDR(x)+(x).a_text)) diff --git a/contrib/gdb/include/aout/host.h b/contrib/gdb/include/aout/host.h deleted file mode 100644 index 8e36212716c..00000000000 --- a/contrib/gdb/include/aout/host.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Parameters about the a.out format, based on the host system on which - the program is compiled. */ - -/* Address of data segment in memory after it is loaded. - It is up to you to define SEGMENT_SIZE - on machines not listed here. */ -#ifndef SEGMENT_SIZE -#if defined(hp300) || defined(pyr) -#define SEGMENT_SIZE page_size -#endif -#ifdef sony -#define SEGMENT_SIZE 0x1000 -#endif /* Sony. */ -#ifdef is68k -#define SEGMENT_SIZE 0x20000 -#endif -#if defined(m68k) && defined(PORTAR) -#define TARGET_PAGE_SIZE 0x400 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#endif -#endif /*!defined(SEGMENT_SIZE)*/ - diff --git a/contrib/gdb/include/aout/hp.h b/contrib/gdb/include/aout/hp.h deleted file mode 100644 index 002f49cf453..00000000000 --- a/contrib/gdb/include/aout/hp.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Special version of for use under hp-ux. - Copyright 1988, 1991 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* THIS FILE IS OBSOLETE. It needs to be revised as a variant "external" - a.out format for use with BFD. */ - -/* The `exec' structure and overall layout must be close to HP's when - we are running on an HP system, otherwise we will not be able to - execute the resulting file. */ - -/* Allow this file to be included twice. */ -#ifndef __GNU_EXEC_MACROS__ - -struct exec -{ - unsigned short a_machtype; /* machine type */ - unsigned short a_magic; /* magic number */ - unsigned long a_spare1; - unsigned long a_spare2; - unsigned long a_text; /* length of text, in bytes */ - unsigned long a_data; /* length of data, in bytes */ - unsigned long a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned long a_trsize; /* length of relocation info for text, in bytes */ - unsigned long a_drsize; /* length of relocation info for data, in bytes */ - unsigned long a_spare3; /* HP = pascal interface size */ - unsigned long a_spare4; /* HP = symbol table size */ - unsigned long a_spare5; /* HP = debug name table size */ - unsigned long a_entry; /* start address */ - unsigned long a_spare6; /* HP = source line table size */ - unsigned long a_spare7; /* HP = value table size */ - unsigned long a_syms; /* length of symbol table data in file, in bytes */ - unsigned long a_spare8; -}; - -/* Tell a.out.gnu.h not to define `struct exec'. */ -#define __STRUCT_EXEC_OVERRIDE__ - -#include "../a.out.gnu.h" - -#undef N_MAGIC -#undef N_MACHTYPE -#undef N_FLAGS -#undef N_SET_INFO -#undef N_SET_MAGIC -#undef N_SET_MACHTYPE -#undef N_SET_FLAGS - -#define N_MAGIC(exec) ((exec) . a_magic) -#define N_MACHTYPE(exec) ((exec) . a_machtype) -#define N_SET_MAGIC(exec, magic) (((exec) . a_magic) = (magic)) -#define N_SET_MACHTYPE(exec, machtype) (((exec) . a_machtype) = (machtype)) - -#undef N_BADMAG -#define N_BADMAG(x) ((_N_BADMAG (x)) || (_N_BADMACH (x))) - -#define _N_BADMACH(x) \ -(((N_MACHTYPE (x)) != HP9000S200_ID) && \ - ((N_MACHTYPE (x)) != HP98x6_ID)) - -#define HP98x6_ID 0x20A -#define HP9000S200_ID 0x20C - -#undef _N_HDROFF -#define _N_HDROFF(x) (SEGMENT_SIZE - (sizeof (struct exec))) - -#define SEGMENT_SIZE 0x1000 - -#endif /* __GNU_EXEC_MACROS__ */ diff --git a/contrib/gdb/include/aout/hp300hpux.h b/contrib/gdb/include/aout/hp300hpux.h deleted file mode 100644 index 44d5196144d..00000000000 --- a/contrib/gdb/include/aout/hp300hpux.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Special version of for use under hp-ux. - Copyright (C) 1988,1993 Free Software Foundation, Inc. */ - -struct hp300hpux_exec_bytes -{ - unsigned char e_info[4]; /* a_machtype/a_magic */ - unsigned char e_spare1[4]; - unsigned char e_spare2[4]; - unsigned char e_text[4]; /* length of text, in bytes */ - unsigned char e_data[4]; /* length of data, in bytes */ - unsigned char e_bss[4]; /* length of uninitialized data area , in bytes */ - unsigned char e_trsize[4]; /* length of relocation info for text, in bytes*/ - unsigned char e_drsize[4]; /* length of relocation info for data, in bytes*/ - unsigned char e_passize[4];/* HP = pascal interface size */ - unsigned char e_syms[4]; /* HP = symbol table size */ - unsigned char e_spare5[4]; /* HP = debug name table size */ - unsigned char e_entry[4]; /* start address */ - unsigned char e_spare6[4]; /* HP = source line table size */ - unsigned char e_supsize[4];/* HP = value table size */ - unsigned char e_drelocs[4]; - unsigned char e_extension[4]; /* file offset of extension */ -}; -#define EXEC_BYTES_SIZE 64 - -struct hp300hpux_nlist_bytes - { - unsigned char e_value[4]; - unsigned char e_type[1]; - unsigned char e_length[1]; /* length of ascii symbol name */ - unsigned char e_almod[2]; /* alignment mod */ - unsigned char e_shlib[2]; /* info about dynamic linking */ - }; -#define EXTERNAL_NLIST_SIZE 10 - -struct hp300hpux_reloc - { - unsigned char r_address[4];/* offset of of data to relocate */ - unsigned char r_index[2]; /* symbol table index of symbol */ - unsigned char r_type[1]; /* relocation type */ - unsigned char r_length[1]; /* length of item to reloc */ - }; - -struct hp300hpux_header_extension -{ - unsigned char e_syms[4]; - unsigned char unique_headers[12*4]; - unsigned char e_header[2]; /* type of header */ - unsigned char e_version[2]; /* version */ - unsigned char e_size[4]; /* bytes following*/ - unsigned char e_extension[4];/* file offset of next extension */ -}; -#define EXTERNAL_EXTENSION_HEADER_SIZE (16*4) - -/* hpux separates object files (0x106) and impure executables (0x107) */ -/* but the bfd code does not distinguish between them. Since we want to*/ -/* read hpux .o files, we add an special define and use it below in */ -/* offset and address calculations. */ - -#define HPUX_DOT_O_MAGIC 0x106 -#define OMAGIC 0x107 /* object file or impure executable. */ -#define NMAGIC 0x108 /* Code indicating pure executable. */ -#define ZMAGIC 0x10B /* demand-paged executable. */ - -#define N_HEADER_IN_TEXT(x) 0 - -#if 0 /* libaout.h only uses the lower 8 bits */ -#define HP98x6_ID 0x20A -#define HP9000S200_ID 0x20C -#endif -#define HP98x6_ID 0x0A -#define HP9000S200_ID 0x0C - -#define N_BADMAG(x) ((_N_BADMAG (x)) || (_N_BADMACH (x))) - -#define N_DATADDR(x) \ - ((N_MAGIC(x)==OMAGIC || N_MAGIC(x)==HPUX_DOT_O_MAGIC) ? \ - (N_TXTADDR(x)+N_TXTSIZE(x)) \ - : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1)))) - -#define _N_BADMACH(x) \ -(((N_MACHTYPE (x)) != HP9000S200_ID) && \ - ((N_MACHTYPE (x)) != HP98x6_ID)) - -#define _N_BADMAG(x) (N_MAGIC(x) != HPUX_DOT_O_MAGIC \ - && N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC ) - -#undef _N_HDROFF -#define _N_HDROFF(x) (SEGMENT_SIZE - (sizeof (struct exec))) - -#undef N_DATOFF -#undef N_PASOFF -#undef N_SYMOFF -#undef N_SUPOFF -#undef N_TRELOFF -#undef N_DRELOFF -#undef N_STROFF - -#define N_DATOFF(x) ( N_TXTOFF(x) + N_TXTSIZE(x) ) -#define N_PASOFF(x) ( N_DATOFF(x) + (x).a_data) -#define N_SYMOFF(x) ( N_PASOFF(x) /* + (x).a_passize*/ ) -#define N_SUPOFF(x) ( N_SYMOFF(x) + (x).a_syms ) -#define N_TRELOFF(x) ( N_SUPOFF(x) /* + 0 (x).a_supsize*/ ) -#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize ) -#define N_EXTHOFF(x) ( N_DRELOFF(x) /* + 0 (x).a_drsize */) -#define N_STROFF(x) ( 0 /* no string table */ ) - -/* use these when the file has gnu symbol tables */ -#define N_GNU_TRELOFF(x) (N_DATOFF(x) + (x).a_data) -#define N_GNU_DRELOFF(x) (N_GNU_TRELOFF(x) + (x).a_trsize) -#define N_GNU_SYMOFF(x) (N_GNU_DRELOFF(x) + (x).a_drsize) - -#define TARGET_PAGE_SIZE 0x1000 -#define SEGMENT_SIZE 0x1000 -#define TEXT_START_ADDR 0 - -#undef N_SHARED_LIB -#define N_SHARED_LIB(x) ( 0 /* no shared libraries */ ) diff --git a/contrib/gdb/include/aout/hppa.h b/contrib/gdb/include/aout/hppa.h deleted file mode 100644 index 7e185de768a..00000000000 --- a/contrib/gdb/include/aout/hppa.h +++ /dev/null @@ -1,7 +0,0 @@ -#include "filehdr.h" -#include "aouthdr.h" -#include "scnhdr.h" -#include "spacehdr.h" -#include "syms.h" - - diff --git a/contrib/gdb/include/aout/ranlib.h b/contrib/gdb/include/aout/ranlib.h deleted file mode 100644 index 982600514b6..00000000000 --- a/contrib/gdb/include/aout/ranlib.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ranlib.h -- archive library index member definition for GNU. - Copyright 1990-1991 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* The Symdef member of an archive contains two things: - a table that maps symbol-string offsets to file offsets, - and a symbol-string table. All the symbol names are - run together (each with trailing null) in the symbol-string - table. There is a single longword bytecount on the front - of each of these tables. Thus if we have two symbols, - "foo" and "_bar", that are in archive members at offsets - 200 and 900, it would look like this: - 16 ; byte count of index table - 0 ; offset of "foo" in string table - 200 ; offset of foo-module in file - 4 ; offset of "bar" in string table - 900 ; offset of bar-module in file - 9 ; byte count of string table - "foo\0_bar\0" ; string table */ - -#define RANLIBMAG "__.SYMDEF" /* Archive file name containing index */ -#define RANLIBSKEW 3 /* Creation time offset */ - -/* Format of __.SYMDEF: - First, a longword containing the size of the 'symdef' data that follows. - Second, zero or more 'symdef' structures. - Third, a longword containing the length of symbol name strings. - Fourth, zero or more symbol name strings (each followed by a null). */ - -struct symdef - { - union - { - unsigned long string_offset; /* In the file */ - char *name; /* In memory, sometimes */ - } s; - /* this points to the front of the file header (AKA member header -- - a struct ar_hdr), not to the front of the file or into the file). - in other words it only tells you which file to read */ - unsigned long file_offset; - }; - -/* Compatability with BSD code */ - -#define ranlib symdef -#define ran_un s -#define ran_strx string_offset -#define ran_name name -#define ran_off file_offset diff --git a/contrib/gdb/include/aout/reloc.h b/contrib/gdb/include/aout/reloc.h deleted file mode 100644 index 563c552a357..00000000000 --- a/contrib/gdb/include/aout/reloc.h +++ /dev/null @@ -1,66 +0,0 @@ -/* reloc.h -- Header file for relocation information. - Copyright 1989-1991 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Relocation types for a.out files using reloc_info_extended - (SPARC and AMD 29000). */ - -#ifndef _RELOC_H_READ_ -#define _RELOC_H_READ_ 1 - -enum reloc_type - { - RELOC_8, RELOC_16, RELOC_32, /* simple relocations */ - RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, /* pc-rel displacement */ - RELOC_WDISP30, RELOC_WDISP22, - RELOC_HI22, RELOC_22, - RELOC_13, RELOC_LO10, - RELOC_SFA_BASE, RELOC_SFA_OFF13, - RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, /* P.I.C. (base-relative) */ - RELOC_PC10, RELOC_PC22, /* for some sort of pc-rel P.I.C. (?) */ - RELOC_JMP_TBL, /* P.I.C. jump table */ - RELOC_SEGOFF16, /* reputedly for shared libraries somehow */ - RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE, - RELOC_11, - RELOC_WDISP2_14, - RELOC_WDISP19, - RELOC_HHI22, - RELOC_HLO10, - - /* 29K relocation types */ - RELOC_JUMPTARG, RELOC_CONST, RELOC_CONSTH, - - RELOC_WDISP14, RELOC_WDISP21, - - NO_RELOC - }; - -#define RELOC_TYPE_NAMES \ -"8", "16", "32", "DISP8", \ -"DISP16", "DISP32", "WDISP30", "WDISP22", \ -"HI22", "22", "13", "LO10", \ -"SFA_BASE", "SFAOFF13", "BASE10", "BASE13", \ -"BASE22", "PC10", "PC22", "JMP_TBL", \ -"SEGOFF16", "GLOB_DAT", "JMP_SLOT", "RELATIVE", \ -"11", "WDISP2_14", "WDISP19", "HHI22", \ -"HLO10", \ -"JUMPTARG", "CONST", "CONSTH", "WDISP14", \ -"WDISP21", \ -"NO_RELOC" - -#endif /* _RELOC_H_READ_ */ - -/* end of reloc.h */ diff --git a/contrib/gdb/include/aout/stab.def b/contrib/gdb/include/aout/stab.def deleted file mode 100644 index 3c6b456d3a9..00000000000 --- a/contrib/gdb/include/aout/stab.def +++ /dev/null @@ -1,264 +0,0 @@ -/* Table of DBX symbol codes for the GNU system. - Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files - overlaps the N_UNDF used for ordinary symbols. In ELF files, the - debug information is in a different file section, so there is no conflict. - This symbol's n_value gives the size of the string section associated - with this file. The symbol's n_strx (relative to the just-updated - string section start address) gives the name of the source file, - e.g. "foo.c", without any path information. The symbol's n_desc gives - the count of upcoming symbols associated with this file (not including - this one). */ -/* __define_stab (N_UNDF, 0x00, "UNDF") */ - -/* Global variable. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_GSYM, 0x20, "GSYM") - -/* Function name for BSD Fortran. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_FNAME, 0x22, "FNAME") - -/* Function name or text-segment variable for C. Value is its address. - Desc is supposedly starting line number, but GCC doesn't set it - and DBX seems not to miss it. */ -__define_stab (N_FUN, 0x24, "FUN") - -/* Data-segment variable with internal linkage. Value is its address. - "Static Sym". */ -__define_stab (N_STSYM, 0x26, "STSYM") - -/* BSS-segment variable with internal linkage. Value is its address. */ -__define_stab (N_LCSYM, 0x28, "LCSYM") - -/* Name of main routine. Only the name is significant. */ -__define_stab (N_MAIN, 0x2a, "MAIN") - -/* Solaris2: Read-only data symbols. */ -__define_stab (N_ROSYM, 0x2c, "ROSYM") - -/* Global symbol in Pascal. - Supposedly the value is its line number; I'm skeptical. */ -__define_stab (N_PC, 0x30, "PC") - -/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */ -__define_stab (N_NSYMS, 0x32, "NSYMS") - -/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */ -__define_stab (N_NOMAP, 0x34, "NOMAP") - -/* New stab from Solaris 2. Like N_SO, but for the object file. Two in - a row provide the build directory and the relative path of the .o from it. - Solaris2 uses this to avoid putting the stabs info into the linked - executable; this stab goes into the ".stab.index" section, and the debugger - reads the real stabs directly from the .o files instead. */ -__define_stab (N_OBJ, 0x38, "OBJ") - -/* New stab from Solaris 2. Options for the debugger, related to the - source language for this module. E.g. whether to use ANSI - integral promotions or traditional integral promotions. */ -__define_stab (N_OPT, 0x3c, "OPT") - -/* Register variable. Value is number of register. */ -__define_stab (N_RSYM, 0x40, "RSYM") - -/* Modula-2 compilation unit. Can someone say what info it contains? */ -__define_stab (N_M2C, 0x42, "M2C") - -/* Line number in text segment. Desc is the line number; - value is corresponding address. On Solaris2, the line number is - relative to the start of the current function. */ -__define_stab (N_SLINE, 0x44, "SLINE") - -/* Similar, for data segment. */ -__define_stab (N_DSLINE, 0x46, "DSLINE") - -/* Similar, for bss segment. */ -__define_stab (N_BSLINE, 0x48, "BSLINE") - -/* Sun's source-code browser stabs. ?? Don't know what the fields are. - Supposedly the field is "path to associated .cb file". THIS VALUE - OVERLAPS WITH N_BSLINE! */ -__define_stab_duplicate (N_BROWS, 0x48, "BROWS") - -/* GNU Modula-2 definition module dependency. Value is the modification time - of the definition file. Other is non-zero if it is imported with the - GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there - are enough empty fields? */ -__define_stab(N_DEFD, 0x4a, "DEFD") - -/* New in Solaris2. Function start/body/end line numbers. */ -__define_stab(N_FLINE, 0x4C, "FLINE") - -/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2 - and one is for C++. Still,... */ -/* GNU C++ exception variable. Name is variable name. */ -__define_stab (N_EHDECL, 0x50, "EHDECL") -/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */ -__define_stab_duplicate (N_MOD2, 0x50, "MOD2") - -/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if - this entry is immediately followed by a CAUGHT stab saying what exception - was caught. Multiple CAUGHT stabs means that multiple exceptions - can be caught here. If Desc is 0, it means all exceptions are caught - here. */ -__define_stab (N_CATCH, 0x54, "CATCH") - -/* Structure or union element. Value is offset in the structure. */ -__define_stab (N_SSYM, 0x60, "SSYM") - -/* Solaris2: Last stab emitted for module. */ -__define_stab (N_ENDM, 0x62, "ENDM") - -/* Name of main source file. - Value is starting text address of the compilation. - If multiple N_SO's appear, the first to contain a trailing / is the - compilation directory. The first to not contain a trailing / is the - source file name, relative to the compilation directory. Others (perhaps - resulting from cfront) are ignored. - On Solaris2, value is undefined, but desc is a source-language code. */ - -__define_stab (N_SO, 0x64, "SO") - -/* Automatic variable in the stack. Value is offset from frame pointer. - Also used for type descriptions. */ -__define_stab (N_LSYM, 0x80, "LSYM") - -/* Beginning of an include file. Only Sun uses this. - In an object file, only the name is significant. - The Sun linker puts data into some of the other fields. */ -__define_stab (N_BINCL, 0x82, "BINCL") - -/* Name of sub-source file (#include file). - Value is starting text address of the compilation. */ -__define_stab (N_SOL, 0x84, "SOL") - -/* Parameter variable. Value is offset from argument pointer. - (On most machines the argument pointer is the same as the frame pointer. */ -__define_stab (N_PSYM, 0xa0, "PSYM") - -/* End of an include file. No name. - This and N_BINCL act as brackets around the file's output. - In an object file, there is no significant data in this entry. - The Sun linker puts data into some of the fields. */ -__define_stab (N_EINCL, 0xa2, "EINCL") - -/* Alternate entry point. Value is its address. */ -__define_stab (N_ENTRY, 0xa4, "ENTRY") - -/* Beginning of lexical block. - The desc is the nesting level in lexical blocks. - The value is the address of the start of the text for the block. - The variables declared inside the block *precede* the N_LBRAC symbol. - On Solaris2, the value is relative to the start of the current function. */ -__define_stab (N_LBRAC, 0xc0, "LBRAC") - -/* Place holder for deleted include file. Replaces a N_BINCL and everything - up to the corresponding N_EINCL. The Sun linker generates these when - it finds multiple identical copies of the symbols from an include file. - This appears only in output from the Sun linker. */ -__define_stab (N_EXCL, 0xc2, "EXCL") - -/* Modula-2 scope information. Can someone say what info it contains? */ -__define_stab (N_SCOPE, 0xc4, "SCOPE") - -/* End of a lexical block. Desc matches the N_LBRAC's desc. - The value is the address of the end of the text for the block. - On Solaris2, the value is relative to the start of the current function. */ -__define_stab (N_RBRAC, 0xe0, "RBRAC") - -/* Begin named common block. Only the name is significant. */ -__define_stab (N_BCOMM, 0xe2, "BCOMM") - -/* End named common block. Only the name is significant - (and it should match the N_BCOMM). */ -__define_stab (N_ECOMM, 0xe4, "ECOMM") - -/* Member of a common block; value is offset within the common block. - This should occur within a BCOMM/ECOMM pair. */ -__define_stab (N_ECOML, 0xe8, "ECOML") - -/* Solaris2: Pascal "with" statement: type,,0,0,offset */ -__define_stab (N_WITH, 0xea, "WITH") - -/* These STAB's are used on Gould systems for Non-Base register symbols - or something like that. FIXME. I have assigned the values at random - since I don't have a Gould here. Fixups from Gould folk welcome... */ -__define_stab (N_NBTEXT, 0xF0, "NBTEXT") -__define_stab (N_NBDATA, 0xF2, "NBDATA") -__define_stab (N_NBBSS, 0xF4, "NBBSS") -__define_stab (N_NBSTS, 0xF6, "NBSTS") -__define_stab (N_NBLCS, 0xF8, "NBLCS") - -/* Second symbol entry containing a length-value for the preceding entry. - The value is the length. */ -__define_stab (N_LENG, 0xfe, "LENG") - -/* The above information, in matrix format. - - STAB MATRIX - _________________________________________________ - | 00 - 1F are not dbx stab symbols | - | In most cases, the low bit is the EXTernal bit| - - | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA | - | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT | - - | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA | - | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT | - - | 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 | - - |_______________________________________________| - | Debug entries with bit 01 set are unused. | - | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM | - | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E | - | 30 PC | 32 NSYMS | 34 NOMAP | 36 | - | 38 OBJ | 3A | 3C OPT | 3E | - | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE | - | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E | - | 50 EHDECL*| 52 | 54 CATCH | 56 | - | 58 | 5A | 5C | 5E | - | 60 SSYM | 62 ENDM | 64 SO | 66 | - | 68 | 6A | 6C | 6E | - | 70 | 72 | 74 | 76 | - | 78 | 7A | 7C | 7E | - | 80 LSYM | 82 BINCL | 84 SOL | 86 | - | 88 | 8A | 8C | 8E | - | 90 | 92 | 94 | 96 | - | 98 | 9A | 9C | 9E | - | A0 PSYM | A2 EINCL | A4 ENTRY | A6 | - | A8 | AA | AC | AE | - | B0 | B2 | B4 | B6 | - | B8 | BA | BC | BE | - | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 | - | C8 | CA | CC | CE | - | D0 | D2 | D4 | D6 | - | D8 | DA | DC | DE | - | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 | - | E8 ECOML | EA WITH | EC | EE | - | F0 | F2 | F4 | F6 | - | F8 | FA | FC | FE LENG | - +-----------------------------------------------+ - * 50 EHDECL is also MOD2. - * 48 BSLINE is also BROWS. - */ diff --git a/contrib/gdb/include/aout/stab_gnu.h b/contrib/gdb/include/aout/stab_gnu.h deleted file mode 100644 index 7d18e14a263..00000000000 --- a/contrib/gdb/include/aout/stab_gnu.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __GNU_STAB__ - -/* Indicate the GNU stab.h is in use. */ - -#define __GNU_STAB__ - -#define __define_stab(NAME, CODE, STRING) NAME=CODE, -#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE, - -enum __stab_debug_code -{ -#include "aout/stab.def" -LAST_UNUSED_STAB_CODE -}; - -#undef __define_stab - -/* Definitions of "desc" field for N_SO stabs in Solaris2. */ - -#define N_SO_AS 1 -#define N_SO_C 2 -#define N_SO_ANSI_C 3 -#define N_SO_CC 4 /* C++ */ -#define N_SO_FORTRAN 5 -#define N_SO_PASCAL 6 - -/* Solaris2: Floating point type values in basic types. */ - -#define NF_NONE 0 -#define NF_SINGLE 1 /* IEEE 32-bit */ -#define NF_DOUBLE 2 /* IEEE 64-bit */ -#define NF_COMPLEX 3 /* Fortran complex */ -#define NF_COMPLEX16 4 /* Fortran double complex */ -#define NF_COMPLEX32 5 /* Fortran complex*16 */ -#define NF_LDOUBLE 6 /* Long double (whatever that is) */ - -#endif /* __GNU_STAB_ */ diff --git a/contrib/gdb/include/aout/sun4.h b/contrib/gdb/include/aout/sun4.h deleted file mode 100644 index f42a0dd4598..00000000000 --- a/contrib/gdb/include/aout/sun4.h +++ /dev/null @@ -1,219 +0,0 @@ -/* SPARC-specific values for a.out files */ - -/* Some systems, e.g., AIX, may have defined this in header files already - included. */ -#undef TARGET_PAGE_SIZE -#define TARGET_PAGE_SIZE 0x2000 /* 8K. aka NBPG in */ -/* Note that some SPARCs have 4K pages, some 8K, some others. */ - -#define SEG_SIZE_SPARC TARGET_PAGE_SIZE -#define SEG_SIZE_SUN3 0x20000 /* Resolution of r/w protection hw */ - -#define TEXT_START_ADDR TARGET_PAGE_SIZE /* Location 0 is not accessible */ -#define N_HEADER_IN_TEXT(x) 1 - -/* Non-default definitions of the accessor macros... */ - -/* Segment size varies on Sun-3 versus Sun-4. */ - -#define N_SEGSIZE(x) (N_MACHTYPE(x) == M_SPARC? SEG_SIZE_SPARC: \ - N_MACHTYPE(x) == M_68020? SEG_SIZE_SUN3: \ - /* Guess? */ TARGET_PAGE_SIZE) - -/* Virtual Address of text segment from the a.out file. For OMAGIC, - (almost always "unlinked .o's" these days), should be zero. - Sun added a kludge so that shared libraries linked ZMAGIC get - an address of zero if a_entry (!!!) is lower than the otherwise - expected text address. These kludges have gotta go! - For linked files, should reflect reality if we know it. */ - -/* This differs from the version in aout64.h (which we override by defining - it here) only for NMAGIC (we return TEXT_START_ADDR+EXEC_BYTES_SIZE; - they return 0). */ - -#define N_TXTADDR(x) \ - (N_MAGIC(x)==OMAGIC? 0 \ - : (N_MAGIC(x) == ZMAGIC && (x).a_entry < TEXT_START_ADDR)? 0 \ - : TEXT_START_ADDR+EXEC_BYTES_SIZE) - -/* When a file is linked against a shared library on SunOS 4, the - dynamic bit in the exec header is set, and the first symbol in the - symbol table is __DYNAMIC. Its value is the address of the - following structure. */ - -struct external_sun4_dynamic -{ - /* The version number of the structure. SunOS 4.1.x creates files - with version number 3, which is what this structure is based on. - According to gdb, version 2 is similar. I believe that version 2 - used a different type of procedure linkage table, and there may - have been other differences. */ - bfd_byte ld_version[4]; - /* The virtual address of a 28 byte structure used in debugging. - The contents are filled in at run time by ld.so. */ - bfd_byte ldd[4]; - /* The virtual address of another structure with information about - how to relocate the executable at run time. */ - bfd_byte ld[4]; -}; - -/* The size of the debugging structure pointed to by the debugger - field of __DYNAMIC. */ -#define EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE (24) - -/* The structure pointed to by the linker field of __DYNAMIC. As far - as I can tell, most of the addresses in this structure are offsets - within the file, but some are actually virtual addresses. */ - -struct internal_sun4_dynamic_link -{ - /* Linked list of loaded objects. This is filled in at runtime by - ld.so and probably by dlopen. */ - unsigned long ld_loaded; - - /* The address of the list of names of shared objects which must be - included at runtime. Each entry in the list is 16 bytes: the 4 - byte address of the string naming the object (e.g., for -lc this - is "c"); 4 bytes of flags--the high bit is whether to search for - the object using the library path; the 2 byte major version - number; the 2 byte minor version number; the 4 byte address of - the next entry in the list (zero if this is the last entry). The - version numbers seem to only be non-zero when doing library - searching. */ - unsigned long ld_need; - - /* The address of the path to search for the shared objects which - must be included. This points to a string in PATH format which - is generated from the -L arguments to the linker. According to - the man page, ld.so implicitly adds ${LD_LIBRARY_PATH} to the - beginning of this string and /lib:/usr/lib:/usr/local/lib to the - end. The string is terminated by a null byte. This field is - zero if there is no additional path. */ - unsigned long ld_rules; - - /* The address of the global offset table. This appears to be a - virtual address, not a file offset. The first entry in the - global offset table seems to be the virtual address of the - sun4_dynamic structure (the same value as the __DYNAMIC symbol). - The global offset table is used for PIC code to hold the - addresses of variables. A dynamically linked file which does not - itself contain PIC code has a four byte global offset table. */ - unsigned long ld_got; - - /* The address of the procedure linkage table. This appears to be a - virtual address, not a file offset. - - On a SPARC, the table is composed of 12 byte entries, each of - which consists of three instructions. The first entry is - sethi %hi(0),%g1 - jmp %g1 - nop - These instructions are changed by ld.so into a jump directly into - ld.so itself. Each subsequent entry is - save %sp, -96, %sp - call
- - The reloc_number is the number of the reloc to use to resolve - this entry. The reloc will be a JMP_SLOT reloc against some - symbol that is not defined in this object file but should be - defined in a shared object (if it is not, ld.so will report a - runtime error and exit). The constant 0x010000000 turns the - reloc number into a sethi of %g0, which does nothing since %g0 is - hardwired to zero. - - When one of these entries is executed, it winds up calling into - ld.so. ld.so looks at the reloc number, available via the return - address, to determine which entry this is. It then looks at the - reloc and patches up the entry in the table into a sethi and jmp - to the real address followed by a nop. This means that the reloc - lookup only has to happen once, and it also means that the - relocation only needs to be done if the function is actually - called. The relocation is expensive because ld.so must look up - the symbol by name. - - The size of the procedure linkage table is given by the ld_plt_sz - field. */ - unsigned long ld_plt; - - /* The address of the relocs. These are in the same format as - ordinary relocs. Symbol index numbers refer to the symbols - pointed to by ld_stab. I think the only way to determine the - number of relocs is to assume that all the bytes from ld_rel to - ld_hash contain reloc entries. */ - unsigned long ld_rel; - - /* The address of a hash table of symbols. The hash table has - roughly the same number of entries as there are dynamic symbols; - I think the only way to get the exact size is to assume that - every byte from ld_hash to ld_stab is devoted to the hash table. - - Each entry in the hash table is eight bytes. The first four - bytes are a symbol index into the dynamic symbols. The second - four bytes are the index of the next hash table entry in the - bucket. The ld_buckets field gives the number of buckets, say B. - The first B entries in the hash table each start a bucket which - is chained through the second four bytes of each entry. A value - of zero ends the chain. - - The hash function is simply - h = 0; - while (*string != '\0') - h = (h << 1) + *string++; - h &= 0x7fffffff; - - To look up a symbol, compute the hash value of the name. Take - the modulos of hash value and the number of buckets. Start at - that entry in the hash table. See if the symbol (from the first - four bytes of the hash table entry) has the name you are looking - for. If not, use the chain field (the second four bytes of the - hash table entry) to move on to the next entry in this bucket. - If the chain field is zero you have reached the end of the - bucket, and the symbol is not in the hash table. */ - unsigned long ld_hash; - - /* The address of the symbol table. This is a list of - external_nlist structures. The string indices are relative to - the ld_symbols field. I think the only way to determine the - number of symbols is to assume that all the bytes between ld_stab - and ld_symbols are external_nlist structures. */ - unsigned long ld_stab; - - /* I don't know what this is for. It seems to always be zero. */ - unsigned long ld_stab_hash; - - /* The number of buckets in the hash table. */ - unsigned long ld_buckets; - - /* The address of the symbol string table. The first string in this - string table need not be the empty string. */ - unsigned long ld_symbols; - - /* The size in bytes of the symbol string table. */ - unsigned long ld_symb_size; - - /* The size in bytes of the text segment. */ - unsigned long ld_text; - - /* The size in bytes of the procedure linkage table. */ - unsigned long ld_plt_sz; -}; - -/* The external form of the structure. */ - -struct external_sun4_dynamic_link -{ - bfd_byte ld_loaded[4]; - bfd_byte ld_need[4]; - bfd_byte ld_rules[4]; - bfd_byte ld_got[4]; - bfd_byte ld_plt[4]; - bfd_byte ld_rel[4]; - bfd_byte ld_hash[4]; - bfd_byte ld_stab[4]; - bfd_byte ld_stab_hash[4]; - bfd_byte ld_buckets[4]; - bfd_byte ld_symbols[4]; - bfd_byte ld_symb_size[4]; - bfd_byte ld_text[4]; - bfd_byte ld_plt_sz[4]; -}; diff --git a/contrib/gdb/include/bfdlink.h b/contrib/gdb/include/bfdlink.h deleted file mode 100644 index 47d80b8c195..00000000000 --- a/contrib/gdb/include/bfdlink.h +++ /dev/null @@ -1,452 +0,0 @@ -/* bfdlink.h -- header file for BFD link routines - Copyright 1993 Free Software Foundation, Inc. - Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef BFDLINK_H -#define BFDLINK_H - -/* Which symbols to strip during a link. */ -enum bfd_link_strip -{ - strip_none, /* Don't strip any symbols. */ - strip_debugger, /* Strip debugging symbols. */ - strip_some, /* keep_hash is the list of symbols to keep. */ - strip_all /* Strip all symbols. */ -}; - -/* Which local symbols to discard during a link. This is irrelevant - if strip_all is used. */ -enum bfd_link_discard -{ - discard_none, /* Don't discard any locals. */ - discard_l, /* Discard locals with a certain prefix. */ - discard_all /* Discard all locals. */ -}; - -/* These are the possible types of an entry in the BFD link hash - table. */ - -enum bfd_link_hash_type -{ - bfd_link_hash_new, /* Symbol is new. */ - bfd_link_hash_undefined, /* Symbol seen before, but undefined. */ - bfd_link_hash_undefweak, /* Symbol is weak and undefined. */ - bfd_link_hash_defined, /* Symbol is defined. */ - bfd_link_hash_defweak, /* Symbol is weak and defined. */ - bfd_link_hash_common, /* Symbol is common. */ - bfd_link_hash_indirect, /* Symbol is an indirect link. */ - bfd_link_hash_warning /* Like indirect, but warn if referenced. */ -}; - -/* The linking routines use a hash table which uses this structure for - its elements. */ - -struct bfd_link_hash_entry -{ - /* Base hash table entry structure. */ - struct bfd_hash_entry root; - /* Type of this entry. */ - enum bfd_link_hash_type type; - - /* Undefined and common symbols are kept in a linked list through - this field. This field is not in the union because that would - force us to remove entries from the list when we changed their - type, which would force the list to be doubly linked, which would - waste more memory. When an undefined or common symbol is - created, it should be added to this list, the head of which is in - the link hash table itself. As symbols are defined, they need - not be removed from the list; anything which reads the list must - doublecheck the symbol type. - - Weak symbols are not kept on this list. - - Defined and defweak symbols use this field as a reference marker. - If the field is not NULL, or this structure is the tail of the - undefined symbol list, the symbol has been referenced. If the - symbol is undefined and becomes defined, this field will - automatically be non-NULL since the symbol will have been on the - undefined symbol list. */ - struct bfd_link_hash_entry *next; - /* A union of information depending upon the type. */ - union - { - /* Nothing is kept for bfd_hash_new. */ - /* bfd_link_hash_undefined, bfd_link_hash_undefweak. */ - struct - { - bfd *abfd; /* BFD symbol was found in. */ - } undef; - /* bfd_link_hash_defined, bfd_link_hash_defweak. */ - struct - { - bfd_vma value; /* Symbol value. */ - asection *section; /* Symbol section. */ - } def; - /* bfd_link_hash_indirect, bfd_link_hash_warning. */ - struct - { - struct bfd_link_hash_entry *link; /* Real symbol. */ - const char *warning; /* Warning (bfd_link_hash_warning only). */ - } i; - /* bfd_link_hash_common. */ - struct - { - /* The linker needs to know three things about common - symbols: the size, the alignment, and the section in - which the symbol should be placed. We store the size - here, and we allocate a small structure to hold the - section and the alignment. The alignment is stored as a - power of two. We don't store all the information - directly because we don't want to increase the size of - the union; this structure is a major space user in the - linker. */ - bfd_size_type size; /* Common symbol size. */ - struct bfd_link_hash_common_entry - { - unsigned int alignment_power; /* Alignment. */ - asection *section; /* Symbol section. */ - } *p; - } c; - } u; -}; - -/* This is the link hash table. It is a derived class of - bfd_hash_table. */ - -struct bfd_link_hash_table -{ - /* The hash table itself. */ - struct bfd_hash_table table; - /* The back end which created this hash table. This indicates the - type of the entries in the hash table, which is sometimes - important information when linking object files of different - types together. */ - const bfd_target *creator; - /* A linked list of undefined and common symbols, linked through the - next field in the bfd_link_hash_entry structure. */ - struct bfd_link_hash_entry *undefs; - /* Entries are added to the tail of the undefs list. */ - struct bfd_link_hash_entry *undefs_tail; -}; - -/* Look up an entry in a link hash table. If FOLLOW is true, this - follows bfd_link_hash_indirect and bfd_link_hash_warning links to - the real symbol. */ -extern struct bfd_link_hash_entry *bfd_link_hash_lookup - PARAMS ((struct bfd_link_hash_table *, const char *, boolean create, - boolean copy, boolean follow)); - -/* Look up an entry in the main linker hash table if the symbol might - be wrapped. This should only be used for references to an - undefined symbol, not for definitions of a symbol. */ - -extern struct bfd_link_hash_entry *bfd_wrapped_link_hash_lookup - PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean, boolean, - boolean)); - -/* Traverse a link hash table. */ -extern void bfd_link_hash_traverse - PARAMS ((struct bfd_link_hash_table *, - boolean (*) (struct bfd_link_hash_entry *, PTR), - PTR)); - -/* Add an entry to the undefs list. */ -extern void bfd_link_add_undef - PARAMS ((struct bfd_link_hash_table *, struct bfd_link_hash_entry *)); - -/* This structure holds all the information needed to communicate - between BFD and the linker when doing a link. */ - -struct bfd_link_info -{ - /* Function callbacks. */ - const struct bfd_link_callbacks *callbacks; - /* true if BFD should generate a relocateable object file. */ - boolean relocateable; - /* true if BFD should generate a shared object. */ - boolean shared; - /* true if BFD should pre-bind symbols in a shared object. */ - boolean symbolic; - /* true if shared objects should be linked directly, not shared. */ - boolean static_link; - /* Which symbols to strip. */ - enum bfd_link_strip strip; - /* Which local symbols to discard. */ - enum bfd_link_discard discard; - /* The local symbol prefix to discard if using discard_l. */ - unsigned int lprefix_len; - const char *lprefix; - /* true if symbols should be retained in memory, false if they - should be freed and reread. */ - boolean keep_memory; - /* The list of input BFD's involved in the link. These are chained - together via the link_next field. */ - bfd *input_bfds; - /* If a symbol should be created for each input BFD, this is section - where those symbols should be placed. It must be a section in - the output BFD. It may be NULL, in which case no such symbols - will be created. This is to support CREATE_OBJECT_SYMBOLS in the - linker command language. */ - asection *create_object_symbols_section; - /* Hash table handled by BFD. */ - struct bfd_link_hash_table *hash; - /* Hash table of symbols to keep. This is NULL unless strip is - strip_some. */ - struct bfd_hash_table *keep_hash; - /* Hash table of symbols to report back via notice_callback. If - this is NULL no symbols are reported back. */ - struct bfd_hash_table *notice_hash; - /* Hash table of symbols which are being wrapped (the --wrap linker - option). If this is NULL, no symbols are being wrapped. */ - struct bfd_hash_table *wrap_hash; - - /* If a base output file is wanted, then this points to it */ - PTR base_file; -}; - -/* This structures holds a set of callback functions. These are - called by the BFD linker routines. The first argument to each - callback function is the bfd_link_info structure being used. Each - function returns a boolean value. If the function returns false, - then the BFD function which called it will return with a failure - indication. */ - -struct bfd_link_callbacks -{ - /* A function which is called when an object is added from an - archive. ABFD is the archive element being added. NAME is the - name of the symbol which caused the archive element to be pulled - in. */ - boolean (*add_archive_element) PARAMS ((struct bfd_link_info *, - bfd *abfd, - const char *name)); - /* A function which is called when a symbol is found with multiple - definitions. NAME is the symbol which is defined multiple times. - OBFD is the old BFD, OSEC is the old section, OVAL is the old - value, NBFD is the new BFD, NSEC is the new section, and NVAL is - the new value. OBFD may be NULL. OSEC and NSEC may be - bfd_com_section or bfd_ind_section. */ - boolean (*multiple_definition) PARAMS ((struct bfd_link_info *, - const char *name, - bfd *obfd, - asection *osec, - bfd_vma oval, - bfd *nbfd, - asection *nsec, - bfd_vma nval)); - /* A function which is called when a common symbol is defined - multiple times. NAME is the symbol appearing multiple times. - OBFD is the BFD of the existing symbol; it may be NULL if this is - not known. OTYPE is the type of the existing symbol, which may - be bfd_link_hash_defined, bfd_link_hash_defweak, - bfd_link_hash_common, or bfd_link_hash_indirect. If OTYPE is - bfd_link_hash_common, OSIZE is the size of the existing symbol. - NBFD is the BFD of the new symbol. NTYPE is the type of the new - symbol, one of bfd_link_hash_defined, bfd_link_hash_common, or - bfd_link_hash_indirect. If NTYPE is bfd_link_hash_common, NSIZE - is the size of the new symbol. */ - boolean (*multiple_common) PARAMS ((struct bfd_link_info *, - const char *name, - bfd *obfd, - enum bfd_link_hash_type otype, - bfd_vma osize, - bfd *nbfd, - enum bfd_link_hash_type ntype, - bfd_vma nsize)); - /* A function which is called to add a symbol to a set. ENTRY is - the link hash table entry for the set itself (e.g., - __CTOR_LIST__). RELOC is the relocation to use for an entry in - the set when generating a relocateable file, and is also used to - get the size of the entry when generating an executable file. - ABFD, SEC and VALUE identify the value to add to the set. */ - boolean (*add_to_set) PARAMS ((struct bfd_link_info *, - struct bfd_link_hash_entry *entry, - bfd_reloc_code_real_type reloc, - bfd *abfd, asection *sec, bfd_vma value)); - /* A function which is called when the name of a g++ constructor or - destructor is found. This is only called by some object file - formats. CONSTRUCTOR is true for a constructor, false for a - destructor. This will use BFD_RELOC_CTOR when generating a - relocateable file. NAME is the name of the symbol found. ABFD, - SECTION and VALUE are the value of the symbol. */ - boolean (*constructor) PARAMS ((struct bfd_link_info *, - boolean constructor, - const char *name, bfd *abfd, asection *sec, - bfd_vma value)); - /* A function which is called to issue a linker warning. For - example, this is called when there is a reference to a warning - symbol. WARNING is the warning to be issued. SYMBOL is the name - of the symbol which triggered the warning; it may be NULL if - there is none. ABFD, SECTION and ADDRESS identify the location - which trigerred the warning; either ABFD or SECTION or both may - be NULL if the location is not known. */ - boolean (*warning) PARAMS ((struct bfd_link_info *, - const char *warning, const char *symbol, - bfd *abfd, asection *section, - bfd_vma address)); - /* A function which is called when a relocation is attempted against - an undefined symbol. NAME is the symbol which is undefined. - ABFD, SECTION and ADDRESS identify the location from which the - reference is made. In some cases SECTION may be NULL. */ - boolean (*undefined_symbol) PARAMS ((struct bfd_link_info *, - const char *name, bfd *abfd, - asection *section, bfd_vma address)); - /* A function which is called when a reloc overflow occurs. NAME is - the name of the symbol or section the reloc is against, - RELOC_NAME is the name of the relocation, and ADDEND is any - addend that is used. ABFD, SECTION and ADDRESS identify the - location at which the overflow occurs; if this is the result of a - bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then - ABFD will be NULL. */ - boolean (*reloc_overflow) PARAMS ((struct bfd_link_info *, - const char *name, - const char *reloc_name, bfd_vma addend, - bfd *abfd, asection *section, - bfd_vma address)); - /* A function which is called when a dangerous reloc is performed. - The canonical example is an a29k IHCONST reloc which does not - follow an IHIHALF reloc. MESSAGE is an appropriate message. - ABFD, SECTION and ADDRESS identify the location at which the - problem occurred; if this is the result of a - bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then - ABFD will be NULL. */ - boolean (*reloc_dangerous) PARAMS ((struct bfd_link_info *, - const char *message, - bfd *abfd, asection *section, - bfd_vma address)); - /* A function which is called when a reloc is found to be attached - to a symbol which is not being written out. NAME is the name of - the symbol. ABFD, SECTION and ADDRESS identify the location of - the reloc; if this is the result of a - bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then - ABFD will be NULL. */ - boolean (*unattached_reloc) PARAMS ((struct bfd_link_info *, - const char *name, - bfd *abfd, asection *section, - bfd_vma address)); - /* A function which is called when a symbol in notice_hash is - defined or referenced. NAME is the symbol. ABFD, SECTION and - ADDRESS are the value of the symbol. If SECTION is - bfd_und_section, this is a reference. */ - boolean (*notice) PARAMS ((struct bfd_link_info *, const char *name, - bfd *abfd, asection *section, bfd_vma address)); -}; - -/* The linker builds link_order structures which tell the code how to - include input data in the output file. */ - -/* These are the types of link_order structures. */ - -enum bfd_link_order_type -{ - bfd_undefined_link_order, /* Undefined. */ - bfd_indirect_link_order, /* Built from a section. */ - bfd_fill_link_order, /* Fill with a 16 bit constant. */ - bfd_data_link_order, /* Set to explicit data. */ - bfd_section_reloc_link_order, /* Relocate against a section. */ - bfd_symbol_reloc_link_order /* Relocate against a symbol. */ -}; - -/* This is the link_order structure itself. These form a chain - attached to the section whose contents they are describing. */ - -struct bfd_link_order -{ - /* Next link_order in chain. */ - struct bfd_link_order *next; - /* Type of link_order. */ - enum bfd_link_order_type type; - /* Offset within output section. */ - bfd_vma offset; - /* Size within output section. */ - bfd_size_type size; - /* Type specific information. */ - union - { - struct - { - /* Section to include. If this is used, then - section->output_section must be the section the - link_order is attached to, section->output_offset must - equal the link_order offset field, and section->_raw_size - must equal the link_order size field. Maybe these - restrictions should be relaxed someday. */ - asection *section; - } indirect; - struct - { - /* Value to fill with. */ - unsigned int value; - } fill; - struct - { - /* Data to put into file. The size field gives the number - of bytes which this field points to. */ - bfd_byte *contents; - } data; - struct - { - /* Description of reloc to generate. Used for - bfd_section_reloc_link_order and - bfd_symbol_reloc_link_order. */ - struct bfd_link_order_reloc *p; - } reloc; - } u; -}; - -/* A linker order of type bfd_section_reloc_link_order or - bfd_symbol_reloc_link_order means to create a reloc against a - section or symbol, respectively. This is used to implement -Ur to - generate relocs for the constructor tables. The - bfd_link_order_reloc structure describes the reloc that BFD should - create. It is similar to a arelent, but I didn't use arelent - because the linker does not know anything about most symbols, and - any asymbol structure it creates will be partially meaningless. - This information could logically be in the bfd_link_order struct, - but I didn't want to waste the space since these types of relocs - are relatively rare. */ - -struct bfd_link_order_reloc -{ - /* Reloc type. */ - bfd_reloc_code_real_type reloc; - - union - { - /* For type bfd_section_reloc_link_order, this is the section - the reloc should be against. This must be a section in the - output BFD, not any of the input BFDs. */ - asection *section; - /* For type bfd_symbol_reloc_link_order, this is the name of the - symbol the reloc should be against. */ - const char *name; - } u; - - /* Addend to use. The object file should contain zero. The BFD - backend is responsible for filling in the contents of the object - file correctly. For some object file formats (e.g., COFF) the - addend must be stored into in the object file, and for some - (e.g., SPARC a.out) it is kept in the reloc. */ - bfd_vma addend; -}; - -/* Allocate a new link_order for a section. */ -extern struct bfd_link_order *bfd_new_link_order PARAMS ((bfd *, asection *)); - -#endif diff --git a/contrib/gdb/include/bout.h b/contrib/gdb/include/bout.h deleted file mode 100644 index 8fc28cc3d6d..00000000000 --- a/contrib/gdb/include/bout.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * This file is a modified version of 'a.out.h'. It is to be used in all - * GNU tools modified to support the i80960 (or tools that operate on - * object files created by such tools). - * - * All i80960 development is done in a CROSS-DEVELOPMENT environment. I.e., - * object code is generated on, and executed under the direction of a symbolic - * debugger running on, a host system. We do not want to be subject to the - * vagaries of which host it is or whether it supports COFF or a.out format, - * or anything else. We DO want to: - * - * o always generate the same format object files, regardless of host. - * - * o have an 'a.out' header that we can modify for our own purposes - * (the 80960 is typically an embedded processor and may require - * enhanced linker support that the normal a.out.h header can't - * accommodate). - * - * As for byte-ordering, the following rules apply: - * - * o Text and data that is actually downloaded to the target is always - * in i80960 (little-endian) order. - * - * o All other numbers (in the header, symbols, relocation directives) - * are in host byte-order: object files CANNOT be lifted from a - * little-end host and used on a big-endian (or vice versa) without - * modification. - * ==> THIS IS NO LONGER TRUE USING BFD. WE CAN GENERATE ANY BYTE ORDER - * FOR THE HEADER, AND READ ANY BYTE ORDER. PREFERENCE WOULD BE TO - * USE LITTLE-ENDIAN BYTE ORDER THROUGHOUT, REGARDLESS OF HOST. <== - * - * o The downloader ('comm960') takes care to generate a pseudo-header - * with correct (i80960) byte-ordering before shipping text and data - * off to the NINDY monitor in the target systems. Symbols and - * relocation info are never sent to the target. - */ - - -#define BMAGIC 0415 -/* We don't accept the following (see N_BADMAG macro). - * They're just here so GNU code will compile. - */ -#define OMAGIC 0407 /* old impure format */ -#define NMAGIC 0410 /* read-only text */ -#define ZMAGIC 0413 /* demand load format */ - -/* FILE HEADER - * All 'lengths' are given as a number of bytes. - * All 'alignments' are for relinkable files only; an alignment of - * 'n' indicates the corresponding segment must begin at an - * address that is a multiple of (2**n). - */ -struct external_exec { - /* Standard stuff */ - unsigned char e_info[4]; /* Identifies this as a b.out file */ - unsigned char e_text[4]; /* Length of text */ - unsigned char e_data[4]; /* Length of data */ - unsigned char e_bss[4]; /* Length of uninitialized data area */ - unsigned char e_syms[4]; /* Length of symbol table */ - unsigned char e_entry[4]; /* Runtime start address */ - unsigned char e_trsize[4]; /* Length of text relocation info */ - unsigned char e_drsize[4]; /* Length of data relocation info */ - - /* Added for i960 */ - unsigned char e_tload[4]; /* Text runtime load address */ - unsigned char e_dload[4]; /* Data runtime load address */ - unsigned char e_talign[1]; /* Alignment of text segment */ - unsigned char e_dalign[1]; /* Alignment of data segment */ - unsigned char e_balign[1]; /* Alignment of bss segment */ - unsigned char e_relaxable[1]; /* Assembled with enough info to allow linker to relax */ -}; - -#define EXEC_BYTES_SIZE (sizeof (struct external_exec)) - -/* These macros use the a_xxx field names, since they operate on the exec - structure after it's been byte-swapped and realigned on the host machine. */ -#define N_BADMAG(x) (((x).a_info)!=BMAGIC) -#define N_TXTOFF(x) EXEC_BYTES_SIZE -#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text ) -#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data ) -#define N_TRELOFF N_TROFF -#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize ) -#define N_DRELOFF N_DROFF -#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize ) -#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) -#define N_DATADDR(x) ( (x).a_dload ) - -/* Address of text segment in memory after it is loaded. */ -#if !defined (N_TXTADDR) -#define N_TXTADDR(x) 0 -#endif - -/* A single entry in the symbol table - */ -struct nlist { - union { - char *n_name; - struct nlist *n_next; - long n_strx; /* Index into string table */ - } n_un; - unsigned char n_type; /* See below */ - char n_other; /* Used in i80960 support -- see below */ - short n_desc; - unsigned long n_value; -}; - - -/* Legal values of n_type - */ -#define N_UNDF 0 /* Undefined symbol */ -#define N_ABS 2 /* Absolute symbol */ -#define N_TEXT 4 /* Text symbol */ -#define N_DATA 6 /* Data symbol */ -#define N_BSS 8 /* BSS symbol */ -#define N_FN 31 /* Filename symbol */ - -#define N_EXT 1 /* External symbol (OR'd in with one of above) */ -#define N_TYPE 036 /* Mask for all the type bits */ -#define N_STAB 0340 /* Mask for all bits used for SDB entries */ - -/* MEANING OF 'n_other' - * - * If non-zero, the 'n_other' fields indicates either a leaf procedure or - * a system procedure, as follows: - * - * 1 <= n_other <= 32 : - * The symbol is the entry point to a system procedure. - * 'n_value' is the address of the entry, as for any other - * procedure. The system procedure number (which can be used in - * a 'calls' instruction) is (n_other-1). These entries come from - * '.sysproc' directives. - * - * n_other == N_CALLNAME - * the symbol is the 'call' entry point to a leaf procedure. - * The *next* symbol in the symbol table must be the corresponding - * 'bal' entry point to the procedure (see following). These - * entries come from '.leafproc' directives in which two different - * symbols are specified (the first one is represented here). - * - * - * n_other == N_BALNAME - * the symbol is the 'bal' entry point to a leaf procedure. - * These entries result from '.leafproc' directives in which only - * one symbol is specified, or in which the same symbol is - * specified twice. - * - * Note that an N_CALLNAME entry *must* have a corresponding N_BALNAME entry, - * but not every N_BALNAME entry must have an N_CALLNAME entry. - */ -#define N_CALLNAME ((char)-1) -#define N_BALNAME ((char)-2) -#define IS_CALLNAME(x) (N_CALLNAME == (x)) -#define IS_BALNAME(x) (N_BALNAME == (x)) -#define IS_OTHER(x) ((x)>0 && (x) <=32) - -#define b_out_relocation_info relocation_info -struct relocation_info { - int r_address; /* File address of item to be relocated */ - unsigned -#define r_index r_symbolnum - r_symbolnum:24,/* Index of symbol on which relocation is based, - * if r_extern is set. Otherwise set to - * either N_TEXT, N_DATA, or N_BSS to - * indicate section on which relocation is - * based. - */ - r_pcrel:1, /* 1 => relocate PC-relative; else absolute - * On i960, pc-relative implies 24-bit - * address, absolute implies 32-bit. - */ - r_length:2, /* Number of bytes to relocate: - * 0 => 1 byte - * 1 => 2 bytes -- used for 13 bit pcrel - * 2 => 4 bytes - */ - r_extern:1, - r_bsr:1, /* Something for the GNU NS32K assembler */ - r_disp:1, /* Something for the GNU NS32K assembler */ - r_callj:1, /* 1 if relocation target is an i960 'callj' */ - r_relaxable:1; /* 1 if enough info is left to relax - the data */ -}; diff --git a/contrib/gdb/include/coff/ChangeLog b/contrib/gdb/include/coff/ChangeLog deleted file mode 100644 index 06c7f80f468..00000000000 --- a/contrib/gdb/include/coff/ChangeLog +++ /dev/null @@ -1,622 +0,0 @@ -Thu Mar 14 15:22:44 1996 Jeffrey A Law (law@cygnus.com) - - * internal.h (R_MEM_INDIRECT): New reloc for the h8300. - -Fri Feb 9 10:44:11 1996 Ian Lance Taylor - - * aux-coff.h: Rename from aux.h, to avoid problems on hapless DOS - systems which think that aux is a com port. - -Mon Feb 5 18:35:00 1996 Ian Lance Taylor - - * i960.h (F_I960HX): Define. - -Wed Jan 31 13:11:54 1996 Richard Henderson - - * aux.h: New file. - * internal.h, m68k.h: Protect against multiple inclusion. - -Wed Nov 22 13:48:39 1995 Ian Lance Taylor - - * ecoff.h (_RCONST, STYP_RCONST, RELOC_SECTION_RCONST): Define. - (NUM_RELOC_SECTIONS): Update. - * symconst.h (scRConst): Define. - -Tue Nov 14 18:54:29 1995 Ian Lance Taylor - - * internal.h (C_NT_WEAK): Define. - -Thu Nov 9 14:08:30 1995 Ian Lance Taylor - - * rs6000.h (STYP_OVRFLO): Define. - -Tue Nov 7 14:38:45 1995 Kim Knuttila - - * coff/powerpc.h (IMAGE_NT_OPTIONAL_HDR_MAGIC): Added define. - * coff/pe.h: Added defines for file level flags - -Mon Nov 6 17:28:01 1995 Harry Dolan - - * i860.h: New file, based on i386.h. - -Wed Nov 1 15:25:18 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 - - * m68k.h (PAGEMAGICEXECSWAPPED): Define. - (PAGEMAGICPEXECSWAPPED): Define. - (PAGEMAGICPEXECTSHLIB): Define. - (PAGEMAGICPEXECPAGED): Define. - (_COMMENT): DEFINE. - * m88k.h (_COMMENT): Define. - -Wed Oct 18 18:36:19 1995 Geoffrey Noer - - * sym.h: #if 0'd out runtime_pdr struct because it chokes - Visual C++ and there aren't any references to it elsewhere in gdb. - -Mon Oct 16 11:12:24 1995 Ian Lance Taylor - - * rs6000.h (SMALL_AOUTSZ): Define. - - * internal.h (XMC_TD): Define. - -Tue Oct 10 18:41:03 1995 Ian Lance Taylor - - * internal.h (struct internal_aouthdr): Add o_cputype field. - * rs6000.h (AOUTHDR): Rename o_resv1 to o_cputype. - -Mon Oct 9 14:45:46 1995 Ian Lance Taylor - - * rs6000.h (AOUTHDR): Add o_maxdata field. Add comments. - (_PAD, _LOADER): Define. - (STYP_LOADER): Define. - * internal.h (struct internal_aouthdr): Add o_maxdata field. - -Thu Oct 5 10:02:57 1995 Ian Lance Taylor - - * ecoff.h: Define section name macros and STYP macros for various - Alpha sections: .got, .hash, .dynsym, .dynstr, .rel.dyn, .conflic, - .comment, .liblist, .dynamic. - -Wed Oct 4 10:56:35 1995 Kim Knuttila - - * pe.h: Moved DOSMAGIC and NT_SIGNATURE defines here - * powerpc.h: removed DOSMAGIC, NT_SIGNATURE, and DEFAULT_* defines - Also removed other unused defines (various MAGIC ones) - * i386.h: removed DOSMAGIC, NT_SIGNATURE, and DEFAULT_* defines - * arm.h: removed DOSMAGIC, NT_SIGNATURE, and DEFAULT_* defines - * apollo.h: removed unused DEFAULT_* defines - * alpha.h: removed unused DEFAULT_* defines - * h8500.h: removed unused DEFAULT_* defines - * h8300.h: removed unused DEFAULT_* defines - * i960.h: removed unused DEFAULT_* defines - * m88k.h: removed unused DEFAULT_* defines - * we32k.h: removed unused DEFAULT_* defines - * rs6000.h: removed unused DEFAULT_* defines - * mips.h: removed unused DEFAULT_* defines - * m68k.h: removed unused DEFAULT_* defines - * z8k.h: removed unused DEFAULT_* defines - * w65.h: removed unused DEFAULT_* defines - * sparc.h: removed unused DEFAULT_* defines - * sh.h: removed unused DEFAULT_* defines - -Fri Sep 29 08:40:08 1995 Kim Knuttila - - * powerpc.h: Reformatted to GNU coding conventions. - -Wed Sep 27 06:50:50 1995 Kim Knuttila - - * pe.h: added defines for more section characteristics - * powerpc.h (new file): base coff definitions for ppc PE - -Tue Sep 12 12:08:20 1995 Ian Lance Taylor - - * internal.h (struct internal_syment): Change n_numaux field from - char to unsigned char. - -Fri Sep 1 15:39:36 1995 Kazumoto Kojima - - * mips.h (struct rpdr_ext): Define. - -Thu Aug 31 16:51:50 1995 steve chamberlain - - * internal.h (internal_aouthdr, internal_filehdr): - don't indirect the pe stuff. - -Tue Aug 29 14:16:07 1995 steve chamberlain - - * i386.h (NT_DEF_RESERVE, NT_DEF_COMMIT): Make the same - as 'the other' compiler. - * internal.h (NT_IMAGE_BASE): Deleted. - (NT_EXE_IMAGE_BASE, NT_DLL_IMAGE_BASE): New. - (PE_DEF_SECTION_ALIGNMENT, PE_DEF_FILE_ALIGNMENT): New. - (R_IMAGEBASE): New. - -Mon Aug 21 18:12:19 1995 steve chamberlain - - * internal.h: (internal_filehdr): Moved PE stuff into - internal_extra_pe_filehdr. - (internal_aouthdr): Moved PE stuff into - interanl_extra_pe_aouthdr. - -Mon Jul 24 14:05:39 1995 Ian Lance Taylor - - * internal.h: Move R_SH_* relocs from here... - * sh.h: ...to here. - (R_SH_SWITCH16, R_SH_SWITCH32): Define. - (R_SH_USES, R_SH_COUNT, R_SH_ALIGN): Define. - -Thu Jun 29 00:04:25 1995 Steve Chamberlain - - * internal.h (NT_DEF_RESERVE, NT_DEF_COMMIT): Increase a lot. - -Tue May 16 15:08:20 1995 Ken Raeburn - - * internal.h (NT_subsystem, NT_stack_heap): Delete - -Tue May 16 15:08:20 1995 Ken Raeburn - - * internal.h (NT_subsystem, NT_stack_heap): Now extern. - -Tue Feb 14 17:59:37 1995 Ian Lance Taylor - - * ecoff.h (struct ecoff_fdrtab_entry): Define. - (struct ecoff_find_line): Define. - -Sat Feb 4 14:38:03 1995 David Mosberger-Tang - - * sym.h (struct pdr): field "prof" added. - - * alpha.h (PDR_BITS1_PROF_*): added, macros for PDR_BITS*_RESERVED_* - updated accordingly. - -Sun Jan 15 18:38:33 1995 Steve Chamberlain - - * w65.h: New file. - -Wed Nov 23 22:43:38 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * sh.h (SH_ARCH_MAGIC_BIG, SH_ARCH_MAGIC_LITTLE): New. - (SHBADMAG): Changed to suit. - -Tue Jul 26 17:46:08 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * i960.h (F_I960JX): New macro. - -Wed Jul 6 00:48:57 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha.h: Add definitions for alpha file header flags, encoding - the object type of the file. - -Mon Jun 20 13:47:01 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * ecoff.h (ecoff_swap_tir_in): Remove declaration. - (ecoff_swap_tir_out): Likewise. - (ecoff_swap_rndx_in, ecoff_swap_rndx_out): Likewise. - (struct ecoff_debug_swap): Add new fields: swap_tir_in, - swap_rndx_in, swap_tir_out, swap_rndx_out, read_debug_info. - -Sun Jun 12 03:51:52 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * symconst.h: Pick up SGI define for stIndirect. - -Fri Apr 22 13:05:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (REGINFO): Don't define. - (struct ecoff_reginfo): Don't define. - - * sh.h (SH_ARCH_MAGIC): Rename from SHMAGIC. SHMAGIC is used by - several targets to mean a shared library. - (SHBADMAG): Corresponding change. - -Thu Apr 14 13:00:53 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (RELOC_BITS3_TYPE_BIG): Changed from 0x1e to 0x3e. - (RELOC_BITS3_TYPEHI_LITTLE): Define. - (RELOC_BITS3_TYPEHI_SH_LITTLE): Define. - (MIPS_R_PCREL16): Change value from 8 to 12 to match Irix 4. - (MIPS_R_RELHI): Define. - (MIPS_R_RELLO): Define. - (MIPS_R_SWITCH): Change value from 9 to 22. - -Thu Apr 7 14:19:35 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (MIPS_R_SWITCH): Define. - -Thu Mar 31 19:28:33 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * internal.h (internal_aouthdr): Added comments for Apollo fields. - -Thu Mar 31 16:28:02 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (STYP_ECOFF_LIB): Define as used on Irix 4. - -Fri Mar 25 17:16:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (struct ecoff_debug_info): Add adjust field. - (struct ecoff_value_adjust): Define. - -Tue Mar 22 13:22:47 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (MIPS_R_PCREL16): Define. - -Sat Feb 26 10:26:38 1994 Ian Lance Taylor (ian@cygnus.com) - - * ecoff.h: Add casts to avoid warnings from SVR4 cc. - -Mon Feb 21 09:48:46 1994 Ian Lance Taylor (ian@lisa.cygnus.com) - - * sym.h (struct runtime_pdr): Make field adr bfd_vma, not unsigned - long. - (SYMR): Make field value bfd_vma, not long. - -Fri Feb 4 23:35:53 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * rs6000.h (STYP_DEBUG): Define. - -Wed Feb 2 14:31:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * internal.h (union internal_auxent): Change x_csect.x_scnlen into - a union of a long and a pointer to a symbol. XCOFF sometimes uses - this field as a symbol index. - -Mon Jan 10 23:54:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (ecoff_debug_info): Remove fields line_end, - external_dnr_end, external_pdr_end, external_sym_end, - external_opt_end, external_aux_end, ss_end, external_fdr_end. - Replace ifdbase with ifdmap. - -Wed Jan 5 17:05:36 1994 Ken Raeburn (raeburn@deneb.cygnus.com) - - * ecoff.h (STYP_EXTENDESC, STYP_COMMENT, STYP_XDATA, STYP_PDATA): - Define. - -Wed Jan 5 16:58:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (NUM_RELOC_SECTIONS): Define. - -Tue Dec 21 09:24:56 1993 Ken Raeburn (raeburn@rtl.cygnus.com) - - * sparc.h (struct external_reloc): Rename field r_addend to - r_offset. - -Sat Dec 11 16:12:32 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * internal.h (R_DISP7, R_SH_IMM16): New reloc types. - -Tue Nov 23 14:23:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (struct ecoff_debug_swap): Added *_end fields for all - the symbolic information pointers. - - * sym.h: Named the EXTR structure ecoff_extr. - -Fri Nov 19 08:21:18 1993 Ken Raeburn (raeburn@rover.cygnus.com) - - * sparc.h (RELSZ): Use correct size. - -Wed Nov 17 17:18:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (struct ecoff_debug_info): Define. - -Tue Nov 2 17:56:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (struct ecoff_debug_swap): Define. - -Thu Oct 28 17:07:50 1993 Stan Shebs (shebs@rtl.cygnus.com) - - * i386.h (I386LYNXMAGIC): Rename to LYNXCOFFMAGIC. - * m68k.h (LYNXCOFFMAGIC): Define. - * sparc.h: New file. - -Tue Oct 19 15:34:50 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * alpha.h (external_aouthdr): Split four byte padding field into - two byte bldrev field and two byte padding field. - - * ecoff.h (_LITA, _PDATA, _XDATA, STYP_LITA): Defined. - -Wed Oct 13 15:52:34 1993 Ken Raeburn (raeburn@cygnus.com) - - Sun Oct 10 17:27:10 1993 Troy Rollo (troy@cbme.unsw.edu.au) - - * coff/internal.h: Added o_sri, o_inlib and o_vid for Apollos - as well as R_DIR16. - - * coff/apollo.h: New file - -Mon Oct 11 17:16:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (REGINFO, struct ecoff_reginfo): Define. - -Tue Oct 5 10:52:53 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * rs6000.h: Change non-ASCII characters in comment to octal - escapes. - -Tue Sep 28 03:27:04 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * ecoff.h (_FINI, STYP_ECOFF_FINI): Add to support .fini section. - -Fri Sep 24 11:53:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (BADMAG): Recognize MIPS_MAGIC_LITTLE3 and MIPS_MAGIC_BIG3. - * ecoff.h: Define MIPS_MAGIC_LITTLE3 and MIPS_MAGIC_BIG3. - -Thu Sep 23 21:07:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mips.h (BADMAG): Recognize MIPS_MAGIC_LITTLE2 and MIPS_MAGIC_BIG2. - * ecoff.h: Define MIPS_MAGIC_LITTLE2 and MIPS_MAGIC_BIG2. - -Thu Sep 16 20:27:21 1993 Jim Kingdon (kingdon@cirdan.cygnus.com) - - * sym.h, symconst.h: Add comment stating these files are not part - of GDB, GAS, etc. In 1991, when we asked rms whether we could - include these files in GDB (although they are copyrighted by - someone besides the FSF), he said it was OK if they were not - considered part of GDB. - -Fri Sep 10 17:40:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (AUX_PUT_ANY): Cast val argument to bfd_vma. - - * alpha.c (external_aouthdr): Need four bytes of padding between - vstamp and tsize. - -Tue Sep 7 14:20:43 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff.h (AUX_GET_ANY, AUX_PUT_ANY): Changed to reflect further - change in bfd swapping routine names. - -Tue Sep 7 10:15:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * ecoff.h (AUX_GET_ANY): Change name of _do_getb32 to reflect bfd - changes. - -Fri Aug 13 14:30:32 1993 Ian Lance Taylor (ian@cygnus.com) - - * ecoff.h (RELOC_SECTION_NONE): Define. - -Thu Aug 12 11:24:42 1993 Ian Lance Taylor (ian@cygnus.com) - - * alpha.h (struct external_reloc): Add r_symndx field. - (RELSZ): Correct. - (RELOC_BITS*): Correct. - (ALPHA_R_*): Define. - * ecoff.h (RELOC_SECTION_{XDATA,PDATA,FINI,LITA,ABS}): Define. - (r_extern): Undefine. - * internal.h (struct internal_reloc): Make r_vaddr bfd_vma rather - than long. Add r_extern field. - - * alpha.h (PDR_BITS*): Define. - * sym.h (PDR): Give correct names to new fields. - - * ecoff.h: Moved MIPS reloc definitions from here... - * mips.h: to here. - -Tue Aug 3 11:17:53 1993 Ian Lance Taylor (ian@cygnus.com) - - * alpha.h: Corrected external symbolic debugging structures to - match actual usage. - * internal.h (internal_filehdr, internal_aouthdr, - internal_scnhdr): Changed type of some fields to bfd_vma so they - can hold 64 bits. - * sym.h (HDRR, FDR, PDR, EXTR): Likewise. - (PDR): Added new fields found on Alpha. - * symconst.h (magicSym2): Define; new value found on Alpha. - - * ecoff.h: New file. - * alpha.h, mips.h: Moved common information into ecoff.h. Moved - external structure definitions in from ecoff-ext.h. - * ecoff-ext.h: Removed; information now in alpha.h and mips.h. - -Sun Jul 18 21:43:59 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * i386.h: Recognize I386PTXMAGIC. - -Fri Jul 16 09:54:35 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h (MIPS_AOUT_{OZ}MAGIC): Renamed from {OZ}MAGIC. - -Thu Jul 15 12:23:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m88k.h (union external_auxent): Move x_fcn back inside x_fcnary. - ({GET,PUT}_FCN_{LNNOPTR,ENDNDX}): Adjust accordingly. - -Sun Jul 11 18:00:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m68k.h: Define MC68KBCSMAGIC. - -Thu Jun 10 11:46:28 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h (_INIT, STYP_MIPS_INIT): Define (used on Irix4). - (STYP_OTHER_LOAD): Define as STYP_MIPS_INIT. - -Wed Jun 9 15:09:09 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h (OMAGIC): Define. - -Mon Apr 26 18:04:47 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * internal.h, sh.h: Support for SH. - -Sat Apr 24 21:34:59 1993 Jim Kingdon (kingdon@cygnus.com) - - * a29k.h: Define _LIT. - -Fri Apr 23 18:41:23 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * alpha.h: New file. - -Thu Apr 8 12:36:34 1993 Ian Lance Taylor (ian@cygnus.com) - - * internal.h (C_SHADOW, C_VERSION): Copied in from m88k.h. - * m88k.h, i386.h, we32k.h: Don't define all the storage classes; - they're already in internal.h. - -Wed Apr 7 11:51:24 1993 Jim Kingdon (kingdon@cygnus.com) - - * internal.h: Change n_sclass to unsigned char. - Change C_EFCN to 0xff, change RS/6000 dbx symbols - to no longer be signed. - -Fri Mar 19 14:52:56 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * internal.h: Add H8/500 reloc types. - -Wed Mar 17 09:46:03 1993 Ian Lance Taylor (ian@cygnus.com) - - * ecoff-ext.h (AUX_PUT_ANY): Don't use void values in branches of - conditional expression. - -Thu Mar 4 14:12:06 1993 Ian Lance Taylor (ian@cygnus.com) - - * ecoff-ext.h (AUX_GET_*): Rewrote to use new macro AUX_GET_ANY. - (AUX_PUT_*): New macros corresponding to the AUX_GET macros. - (ecoff_swap_tir_out): Added prototype. - - * mips.h (N_BTMASK, N_TMASK, N_BTSHFT, N_TSHIFT): Define; these - are needed to interpret gcc debugging output. - -Tue Feb 9 07:43:27 1993 Ian Lance Taylor (ian@cygnus.com) - - * we32k.h (BTYPE, ISPTR, ISFCN, ISARY, DECREF): Removed - more definitions duplicated in internal.h. - -Wed Feb 3 09:18:24 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h (RELOC_BITS3_TYPE_*): Correct for big endian machines. - -Mon Jan 25 11:35:51 1993 Ian Lance Taylor (ian@cygnus.com) - - * internal.h (internal_aouthdr): Added additional fields used only - by MIPS ECOFF. - -Thu Jan 21 10:28:38 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h (AOUTHDR): Added additional fields used by ECOFF. - -Tue Jan 19 12:21:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * i386.h, we32k.h (N_*, T_*, DT_*): Removed still more definitions - duplicated in internal.h. - - * mips.h (RELOC_SECTION_*, ECOFF_R_*): Defined constants for ECOFF - relocs. - -Fri Jan 15 18:17:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff-ext.h: Added prototypes for new ECOFF swapping functions. - (opt_ext): New structure. - * mips.h (ZMAGIC): Defined to be 0413. - (_LIB): Defined to be ".lib" - (external_reloc): MIPS ECOFF relocs are only 8 bytes. Added - macros to aid in swapping. - -Fri Jan 8 16:19:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ecoff-ext.h: Added prototypes for ECOFF swapping functions. - * internal.h (internal_scnhdr): Always provide s_align field, not - just on i960. - (internal_reloc): Always provide r_size field, not just on - RS/6000. - * mips.h (_RDATA, _SDATA, _SBSS, _LIT4, _LIT8, STYP_RDATA, - STYP_SDATA, STYP_SBSS, STYP_LIT4, STYP_LIT8): Defined. - (CODE_MASK, MIPS_IS_STAB, MIPS_MARK_STAB, MIPS_UNMARK_STAB, - STABS_SYMBOL): Moved in from gdb/mipsread.c. - -Wed Jan 6 14:01:46 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * i386.h, we32k.h: removed STYP_* defines, since they duplicated - those in internal.h. - -Tue Dec 29 15:40:07 1992 Ian Lance Taylor (ian@cygnus.com) - - * i386.h: define I386AIXMAGIC for Danbury AIX PS/2 compiler. - -Sat Dec 12 16:07:57 1992 Ian Lance Taylor (ian@cygnus.com) - - * i386.h: don't define BTYPE, ISPTR, ISFCN, ISARY, DECREF: they - are defined in internal.h. - -Thu Nov 12 09:52:01 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * internal.h: (internal_reloc): r_offset is now a long. - * z8k.h: slight comment enhancement - -Wed Sep 30 07:46:08 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * internal.h: changed z8k reloc types - -Fri Aug 28 10:16:31 1992 Brendan Kehoe (brendan@cygnus.com) - - * we32k.h: new file - -Thu Aug 27 13:00:01 1992 Brendan Kehoe (brendan@cygnus.com) - - * symconst.h: comment out cruft at the end of #endif - -Tue Aug 25 15:06:49 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * internal.h: added #define for STYP_LIT, removed from a29k and - h8300. - - * z8k.h: added z8000 support - -Thu Jul 16 16:32:00 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * internal.h: added R_RELLONG_NEG reloc type - -Fri Jun 12 20:11:04 1992 John Gilmore (gnu at cygnus.com) - - * symconst.h: Fix unterminated comment. - -Wed Jun 10 07:57:49 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * i386.h: a.out magic numbers from - mohring@informatik.tu-muenchen.de - -Mon Jun 8 20:13:33 1992 John Gilmore (gnu at cygnus.com) - - * ecoff-ext.h, mips.h: Use unsigned chars everywhere. - (Suggested by Antti Miettinen.) - -Tue Apr 14 15:18:44 1992 John Gilmore (gnu at cygnus.com) - - * sym.h: Add comments. - * symconst.h: Merge with Fred's changes. - -Tue Apr 14 14:30:05 1992 Fred Fish (fnf@cygnus.com) - - * symconst.h: Pick up SGI defines for stStruct, stUnion, stEnum, - langCplusplus, and langCplusplusV2. - -Thu Apr 2 19:47:43 1992 John Gilmore (gnu at cygnus.com) - - * sym.h, symconst.h: MIPS has provided redistributable versions - of these files. Thanks! - * ecoff-ext.h: Add weakext bit to match new sym.h. - -Fri Mar 6 00:10:46 1992 John Gilmore (gnu at cygnus.com) - - * ecoff-ext.h: Add relative file descriptors. - -Thu Feb 27 11:53:04 1992 John Gilmore (gnu at cygnus.com) - - * ecoff-ext.h: New file for external (in-file) form of ecoff - symbol structures. - -Thu Feb 6 11:33:32 1992 Steve Chamberlain (sac at rtl.cygnus.com) - - * h8300.h: made the external_lineno l_lnno field 4 bytes wide. - andded GET/PUT_LINENO_LNNO macros - -Sat Nov 30 20:38:35 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * ChangeLog, a29k.h, h8300.h, i386.h, i960.h, internal.h, m68k.h, - m88k.h, mips.h, rs6000.h: move from above coff-.h - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/include/coff/a29k.h b/contrib/gdb/include/coff/a29k.h deleted file mode 100644 index 13b35f251af..00000000000 --- a/contrib/gdb/include/coff/a29k.h +++ /dev/null @@ -1,305 +0,0 @@ -/* COFF spec for AMD 290*0 - Contributed by David Wood @ New York University. - */ - -#ifndef AMD -# define AMD -#endif - -/****************************************************************/ - -/* -** File Header and related definitions -*/ - -struct external_filehdr -{ - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof (FILHDR) - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - -/* -** Magic numbers for Am29000 -** (AT&T will assign the "real" magic number) -*/ - -#define SIPFBOMAGIC 0572 /* Am29000 (Byte 0 is MSB) */ -#define SIPRBOMAGIC 0573 /* Am29000 (Byte 0 is LSB) */ - - -#define A29K_MAGIC_BIG SIPFBOMAGIC -#define A29K_MAGIC_LITTLE SIPRBOMAGIC -#define A29KBADMAG(x) (((x).f_magic!=A29K_MAGIC_BIG) && \ - ((x).f_magic!=A29K_MAGIC_LITTLE)) - -#define OMAGIC A29K_MAGIC_BIG -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - -/* -** File header flags currently known to us. -** -** Am29000 will use the F_AR32WR and F_AR32W flags to indicate -** the byte ordering in the file. -*/ - -/*--------------------------------------------------------------*/ - -/* -** Optional (a.out) header -*/ - -typedef struct external_aouthdr -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} AOUTHDR; - -#define AOUTSZ (sizeof(AOUTHDR)) -#define AOUTHDRSZ (sizeof(AOUTHDR)) - -/* aouthdr magic numbers */ -#define NMAGIC 0410 /* separate i/d executable */ -#define SHMAGIC 0406 /* NYU/Ultra3 shared data executable - (writable text) */ - -#define _ETEXT "_etext" - -/*--------------------------------------------------------------*/ - -/* -** Section header and related definitions -*/ - -struct external_scnhdr -{ - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof (SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _LIT ".lit" - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - -/* -** Section types - with additional section type for global -** registers which will be relocatable for the Am29000. -** -** In instances where it is necessary for a linker to produce an -** output file which contains text or data not based at virtual -** address 0, e.g. for a ROM, then the linker should accept -** address base information as command input and use PAD sections -** to skip over unused addresses. -*/ - -#define STYP_BSSREG 0x1200 /* Global register area (like STYP_INFO) */ -#define STYP_ENVIR 0x2200 /* Environment (like STYP_INFO) */ -#define STYP_ABS 0x4000 /* Absolute (allocated, not reloc, loaded) */ - -/*--------------------------------------------------------------*/ - -/* -** Relocation information declaration and related definitions -*/ - -struct external_reloc { - char r_vaddr[4]; /* (virtual) address of reference */ - char r_symndx[4]; /* index into symbol table */ - char r_type[2]; /* relocation type */ -}; - -#define RELOC struct external_reloc -#define RELSZ 10 /* sizeof (RELOC) */ - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - -/* -** Relocation types for the Am29000 -*/ - -#define R_ABS 0 /* reference is absolute */ - -#define R_IREL 030 /* instruction relative (jmp/call) */ -#define R_IABS 031 /* instruction absolute (jmp/call) */ -#define R_ILOHALF 032 /* instruction low half (const) */ -#define R_IHIHALF 033 /* instruction high half (consth) part 1 */ -#define R_IHCONST 034 /* instruction high half (consth) part 2 */ - /* constant offset of R_IHIHALF relocation */ -#define R_BYTE 035 /* relocatable byte value */ -#define R_HWORD 036 /* relocatable halfword value */ -#define R_WORD 037 /* relocatable word value */ - -#define R_IGLBLRC 040 /* instruction global register RC */ -#define R_IGLBLRA 041 /* instruction global register RA */ -#define R_IGLBLRB 042 /* instruction global register RB */ - -/* -NOTE: -All the "I" forms refer to 29000 instruction formats. The linker is -expected to know how the numeric information is split and/or aligned -within the instruction word(s). R_BYTE works for instructions, too. - -If the parameter to a CONSTH instruction is a relocatable type, two -relocation records are written. The first has an r_type of R_IHIHALF -(33 octal) and a normal r_vaddr and r_symndx. The second relocation -record has an r_type of R_IHCONST (34 octal), a normal r_vaddr (which -is redundant), and an r_symndx containing the 32-bit constant offset -to the relocation instead of the actual symbol table index. This -second record is always written, even if the constant offset is zero. -The constant fields of the instruction are set to zero. -*/ - -/*--------------------------------------------------------------*/ - -/* -** Line number entry declaration and related definitions -*/ - -struct external_lineno -{ - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - -#define LINENO struct external_lineno -#define LINESZ 6 /* sizeof (LINENO) */ - -/*--------------------------------------------------------------*/ - -/* -** Symbol entry declaration and related definitions -*/ - -#define E_SYMNMLEN 8 /* Number of characters in a symbol name */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - -#define SYMENT struct external_syment -#define SYMESZ sizeof(SYMENT) - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - -/* -** Storage class definitions - new classes for global registers. -*/ - -#define C_GLBLREG 19 /* global register */ -#define C_EXTREG 20 /* external global register */ -#define C_DEFREG 21 /* ext. def. of global register */ - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - -/* -** Derived symbol mask/shifts. -*/ - -#define N_BTMASK (0xf) -#define N_BTSHFT (4) -#define N_TMASK (0x30) -#define N_TSHIFT (2) - -/*--------------------------------------------------------------*/ - -/* -** Auxiliary symbol table entry declaration and related -** definitions. -*/ - -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ -}; - -#define AUXENT union external_auxent -#define AUXESZ 18 diff --git a/contrib/gdb/include/coff/alpha.h b/contrib/gdb/include/coff/alpha.h deleted file mode 100644 index 1f1bfb6ccc7..00000000000 --- a/contrib/gdb/include/coff/alpha.h +++ /dev/null @@ -1,342 +0,0 @@ -/* ECOFF support on Alpha machines. - coff/ecoff.h must be included before this file. */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - unsigned char f_magic[2]; /* magic number */ - unsigned char f_nscns[2]; /* number of sections */ - unsigned char f_timdat[4]; /* time & date stamp */ - unsigned char f_symptr[8]; /* file pointer to symtab */ - unsigned char f_nsyms[4]; /* number of symtab entries */ - unsigned char f_opthdr[2]; /* sizeof(optional hdr) */ - unsigned char f_flags[2]; /* flags */ -}; - -/* Magic numbers are defined in coff/ecoff.h. */ -#define ALPHA_ECOFF_BADMAG(x) ((x).f_magic!=ALPHA_MAGIC) - -/* The object type is encoded in the f_flags. */ -#define F_ALPHA_OBJECT_TYPE_MASK 0x3000 -#define F_ALPHA_NO_SHARED 0x1000 -#define F_ALPHA_SHARABLE 0x2000 -#define F_ALPHA_CALL_SHARED 0x3000 - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct external_aouthdr -{ - unsigned char magic[2]; /* type of file */ - unsigned char vstamp[2]; /* version stamp */ - unsigned char bldrev[2]; /* ?? */ - unsigned char padding[2]; /* pad to quadword boundary */ - unsigned char tsize[8]; /* text size in bytes */ - unsigned char dsize[8]; /* initialized data " " */ - unsigned char bsize[8]; /* uninitialized data " " */ - unsigned char entry[8]; /* entry pt. */ - unsigned char text_start[8]; /* base of text used for this file */ - unsigned char data_start[8]; /* base of data used for this file */ - unsigned char bss_start[8]; /* base of bss used for this file */ - unsigned char gprmask[4]; /* bitmask of general registers used */ - unsigned char fprmask[4]; /* bitmask of floating point registers used */ - unsigned char gp_value[8]; /* value for gp register */ -} AOUTHDR; - -/* compute size of a header */ - -#define AOUTSZ (sizeof(AOUTHDR)) - -/********************** SECTION HEADER **********************/ - -struct external_scnhdr { - unsigned char s_name[8]; /* section name */ - unsigned char s_paddr[8]; /* physical address, aliased s_nlib */ - unsigned char s_vaddr[8]; /* virtual address */ - unsigned char s_size[8]; /* section size */ - unsigned char s_scnptr[8]; /* file ptr to raw data for section */ - unsigned char s_relptr[8]; /* file ptr to relocation */ - unsigned char s_lnnoptr[8]; /* file ptr to line numbers */ - unsigned char s_nreloc[2]; /* number of relocation entries */ - unsigned char s_nlnno[2]; /* number of line number entries*/ - unsigned char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/********************** RELOCATION DIRECTIVES **********************/ - -struct external_reloc { - unsigned char r_vaddr[8]; - unsigned char r_symndx[4]; - unsigned char r_bits[4]; -}; - -#define RELOC struct external_reloc -#define RELSZ 16 - -/* Constants to unpack the r_bits field. The Alpha seems to always be - little endian, so I haven't bothered to define big endian variants - of these. */ - -#define RELOC_BITS0_TYPE_LITTLE 0xff -#define RELOC_BITS0_TYPE_SH_LITTLE 0 - -#define RELOC_BITS1_EXTERN_LITTLE 0x01 - -#define RELOC_BITS1_OFFSET_LITTLE 0x7e -#define RELOC_BITS1_OFFSET_SH_LITTLE 1 - -#define RELOC_BITS1_RESERVED_LITTLE 0x80 -#define RELOC_BITS1_RESERVED_SH_LITTLE 7 -#define RELOC_BITS2_RESERVED_LITTLE 0xff -#define RELOC_BITS2_RESERVED_SH_LEFT_LITTLE 1 -#define RELOC_BITS3_RESERVED_LITTLE 0x03 -#define RELOC_BITS3_RESERVED_SH_LEFT_LITTLE 9 - -#define RELOC_BITS3_SIZE_LITTLE 0xfc -#define RELOC_BITS3_SIZE_SH_LITTLE 2 - -/* The r_type field in a reloc is one of the following values. */ -#define ALPHA_R_IGNORE 0 -#define ALPHA_R_REFLONG 1 -#define ALPHA_R_REFQUAD 2 -#define ALPHA_R_GPREL32 3 -#define ALPHA_R_LITERAL 4 -#define ALPHA_R_LITUSE 5 -#define ALPHA_R_GPDISP 6 -#define ALPHA_R_BRADDR 7 -#define ALPHA_R_HINT 8 -#define ALPHA_R_SREL16 9 -#define ALPHA_R_SREL32 10 -#define ALPHA_R_SREL64 11 -#define ALPHA_R_OP_PUSH 12 -#define ALPHA_R_OP_STORE 13 -#define ALPHA_R_OP_PSUB 14 -#define ALPHA_R_OP_PRSHIFT 15 -#define ALPHA_R_GPVALUE 16 - -/********************** SYMBOLIC INFORMATION **********************/ - -/* Written by John Gilmore. */ - -/* ECOFF uses COFF-like section structures, but its own symbol format. - This file defines the symbol format in fields whose size and alignment - will not vary on different host systems. */ - -/* File header as a set of bytes */ - -struct hdr_ext { - unsigned char h_magic[2]; - unsigned char h_vstamp[2]; - unsigned char h_ilineMax[4]; - unsigned char h_idnMax[4]; - unsigned char h_ipdMax[4]; - unsigned char h_isymMax[4]; - unsigned char h_ioptMax[4]; - unsigned char h_iauxMax[4]; - unsigned char h_issMax[4]; - unsigned char h_issExtMax[4]; - unsigned char h_ifdMax[4]; - unsigned char h_crfd[4]; - unsigned char h_iextMax[4]; - unsigned char h_cbLine[8]; - unsigned char h_cbLineOffset[8]; - unsigned char h_cbDnOffset[8]; - unsigned char h_cbPdOffset[8]; - unsigned char h_cbSymOffset[8]; - unsigned char h_cbOptOffset[8]; - unsigned char h_cbAuxOffset[8]; - unsigned char h_cbSsOffset[8]; - unsigned char h_cbSsExtOffset[8]; - unsigned char h_cbFdOffset[8]; - unsigned char h_cbRfdOffset[8]; - unsigned char h_cbExtOffset[8]; -}; - -/* File descriptor external record */ - -struct fdr_ext { - unsigned char f_adr[8]; - unsigned char f_cbLineOffset[8]; - unsigned char f_cbLine[8]; - unsigned char f_cbSs[8]; - unsigned char f_rss[4]; - unsigned char f_issBase[4]; - unsigned char f_isymBase[4]; - unsigned char f_csym[4]; - unsigned char f_ilineBase[4]; - unsigned char f_cline[4]; - unsigned char f_ioptBase[4]; - unsigned char f_copt[4]; - unsigned char f_ipdFirst[4]; - unsigned char f_cpd[4]; - unsigned char f_iauxBase[4]; - unsigned char f_caux[4]; - unsigned char f_rfdBase[4]; - unsigned char f_crfd[4]; - unsigned char f_bits1[1]; - unsigned char f_bits2[3]; - unsigned char f_padding[4]; -}; - -#define FDR_BITS1_LANG_BIG 0xF8 -#define FDR_BITS1_LANG_SH_BIG 3 -#define FDR_BITS1_LANG_LITTLE 0x1F -#define FDR_BITS1_LANG_SH_LITTLE 0 - -#define FDR_BITS1_FMERGE_BIG 0x04 -#define FDR_BITS1_FMERGE_LITTLE 0x20 - -#define FDR_BITS1_FREADIN_BIG 0x02 -#define FDR_BITS1_FREADIN_LITTLE 0x40 - -#define FDR_BITS1_FBIGENDIAN_BIG 0x01 -#define FDR_BITS1_FBIGENDIAN_LITTLE 0x80 - -#define FDR_BITS2_GLEVEL_BIG 0xC0 -#define FDR_BITS2_GLEVEL_SH_BIG 6 -#define FDR_BITS2_GLEVEL_LITTLE 0x03 -#define FDR_BITS2_GLEVEL_SH_LITTLE 0 - -/* We ignore the `reserved' field in bits2. */ - -/* Procedure descriptor external record */ - -struct pdr_ext { - unsigned char p_adr[8]; - unsigned char p_cbLineOffset[8]; - unsigned char p_isym[4]; - unsigned char p_iline[4]; - unsigned char p_regmask[4]; - unsigned char p_regoffset[4]; - unsigned char p_iopt[4]; - unsigned char p_fregmask[4]; - unsigned char p_fregoffset[4]; - unsigned char p_frameoffset[4]; - unsigned char p_lnLow[4]; - unsigned char p_lnHigh[4]; - unsigned char p_gp_prologue[1]; - unsigned char p_bits1[1]; - unsigned char p_bits2[1]; - unsigned char p_localoff[1]; - unsigned char p_framereg[2]; - unsigned char p_pcreg[2]; -}; - -#define PDR_BITS1_GP_USED_BIG 0x80 -#define PDR_BITS1_REG_FRAME_BIG 0x40 -#define PDR_BITS1_PROF_BIG 0x20 -#define PDR_BITS1_RESERVED_BIG 0x1f -#define PDR_BITS1_RESERVED_SH_LEFT_BIG 8 -#define PDR_BITS2_RESERVED_BIG 0xff -#define PDR_BITS2_RESERVED_SH_BIG 0 - -#define PDR_BITS1_GP_USED_LITTLE 0x01 -#define PDR_BITS1_REG_FRAME_LITTLE 0x02 -#define PDR_BITS1_PROF_LITTLE 0x04 -#define PDR_BITS1_RESERVED_LITTLE 0xf8 -#define PDR_BITS1_RESERVED_SH_LITTLE 3 -#define PDR_BITS2_RESERVED_LITTLE 0xff -#define PDR_BITS2_RESERVED_SH_LEFT_LITTLE 5 - -/* Line numbers */ - -struct line_ext { - unsigned char l_line[4]; -}; - -/* Symbol external record */ - -struct sym_ext { - unsigned char s_value[8]; - unsigned char s_iss[4]; - unsigned char s_bits1[1]; - unsigned char s_bits2[1]; - unsigned char s_bits3[1]; - unsigned char s_bits4[1]; -}; - -#define SYM_BITS1_ST_BIG 0xFC -#define SYM_BITS1_ST_SH_BIG 2 -#define SYM_BITS1_ST_LITTLE 0x3F -#define SYM_BITS1_ST_SH_LITTLE 0 - -#define SYM_BITS1_SC_BIG 0x03 -#define SYM_BITS1_SC_SH_LEFT_BIG 3 -#define SYM_BITS1_SC_LITTLE 0xC0 -#define SYM_BITS1_SC_SH_LITTLE 6 - -#define SYM_BITS2_SC_BIG 0xE0 -#define SYM_BITS2_SC_SH_BIG 5 -#define SYM_BITS2_SC_LITTLE 0x07 -#define SYM_BITS2_SC_SH_LEFT_LITTLE 2 - -#define SYM_BITS2_RESERVED_BIG 0x10 -#define SYM_BITS2_RESERVED_LITTLE 0x08 - -#define SYM_BITS2_INDEX_BIG 0x0F -#define SYM_BITS2_INDEX_SH_LEFT_BIG 16 -#define SYM_BITS2_INDEX_LITTLE 0xF0 -#define SYM_BITS2_INDEX_SH_LITTLE 4 - -#define SYM_BITS3_INDEX_SH_LEFT_BIG 8 -#define SYM_BITS3_INDEX_SH_LEFT_LITTLE 4 - -#define SYM_BITS4_INDEX_SH_LEFT_BIG 0 -#define SYM_BITS4_INDEX_SH_LEFT_LITTLE 12 - -/* External symbol external record */ - -struct ext_ext { - struct sym_ext es_asym; - unsigned char es_bits1[1]; - unsigned char es_bits2[3]; - unsigned char es_ifd[4]; -}; - -#define EXT_BITS1_JMPTBL_BIG 0x80 -#define EXT_BITS1_JMPTBL_LITTLE 0x01 - -#define EXT_BITS1_COBOL_MAIN_BIG 0x40 -#define EXT_BITS1_COBOL_MAIN_LITTLE 0x02 - -#define EXT_BITS1_WEAKEXT_BIG 0x20 -#define EXT_BITS1_WEAKEXT_LITTLE 0x04 - -/* Dense numbers external record */ - -struct dnr_ext { - unsigned char d_rfd[4]; - unsigned char d_index[4]; -}; - -/* Relative file descriptor */ - -struct rfd_ext { - unsigned char rfd[4]; -}; - -/* Optimizer symbol external record */ - -struct opt_ext { - unsigned char o_bits1[1]; - unsigned char o_bits2[1]; - unsigned char o_bits3[1]; - unsigned char o_bits4[1]; - struct rndx_ext o_rndx; - unsigned char o_offset[4]; -}; - -#define OPT_BITS2_VALUE_SH_LEFT_BIG 16 -#define OPT_BITS2_VALUE_SH_LEFT_LITTLE 0 - -#define OPT_BITS3_VALUE_SH_LEFT_BIG 8 -#define OPT_BITS3_VALUE_SH_LEFT_LITTLE 8 - -#define OPT_BITS4_VALUE_SH_LEFT_BIG 0 -#define OPT_BITS4_VALUE_SH_LEFT_LITTLE 16 diff --git a/contrib/gdb/include/coff/apollo.h b/contrib/gdb/include/coff/apollo.h deleted file mode 100644 index c481d482e8b..00000000000 --- a/contrib/gdb/include/coff/apollo.h +++ /dev/null @@ -1,248 +0,0 @@ -/*** coff information for Apollo M68K */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - -/* Motorola 68000/68008/68010/68020 */ -#define MC68MAGIC 0520 -#define MC68KWRMAGIC 0520 /* writeable text segments */ -#define MC68TVMAGIC 0521 -#define MC68KROMAGIC 0521 /* readonly shareable text segments */ -#define MC68KPGMAGIC 0522 /* demand paged text segments */ -#define M68MAGIC 0210 -#define M68TVMAGIC 0211 - -/* Apollo 68000-based machines have a different magic number. This comes - * from /usr/include/apollo/filehdr.h - */ -#define APOLLOM68KMAGIC 0627 - -#define OMAGIC M68MAGIC -#define M68KBADMAG(x) (((x).f_magic!=MC68MAGIC) && ((x).f_magic!=MC68KWRMAGIC) && ((x).f_magic!=MC68TVMAGIC) && \ - ((x).f_magic!=MC68KROMAGIC) && ((x).f_magic!=MC68KPGMAGIC) && ((x).f_magic!=M68MAGIC) && ((x).f_magic!=M68TVMAGIC) && \ - ((x).f_magic!=APOLLOM68KMAGIC) ) - - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ - char o_sri[4]; /* Apollo specific - .sri data pointer */ - char o_inlib[4]; /* Apollo specific - .inlib data pointer */ - char vid[8]; /* Apollo specific - 64 bit version ID */ -} -AOUTHDR; - -#define APOLLO_COFF_VERSION_NUMBER 1 /* the value of the aouthdr magic */ -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) - - - -/********************** SECTION HEADER **********************/ - -struct external_scnhdr { - /* Apollo allow for larger section names by allowing it to be in - * the string table. - */ - char s_name[8]; - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* If s_zeores is all zeroes, s_offset gives the real location of the name - * in the string table. - */ - -#define s_zeroes section_name.s_name -#define s_offset (section_name.s_name+4) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _TV ".tv" -#define _INIT ".init" -#define _FINI ".fini" -#define _LINES ".lines" -#define _BLOCKS ".blocks" -#define _SRI ".sri" /* Static Resource Information (systype, - et al.) */ -#define _MIR ".mir" /* Module Information Records */ -#define _APTV ".aptv" /* Apollo-style transfer vectors. */ -#define _INLIB ".inlib" /* Shared Library information */ -#define _RWDI ".rwdi" /* Read/write data initialization directives for - compressed sections */ -#define _UNWIND ".unwind" /* Stack unwind information */ - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - - -/********************** RELOCATION DIRECTIVES **********************/ - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; -#ifdef M68K_COFF_OFFSET - char r_offset[4]; -#endif - -}; - - -#define RELOC struct external_reloc - -#define RELSZ sizeof(struct external_reloc) - -/* Apollo specific STYP flags */ - -#define STYP_RELOCATED_NOT_LOADED 0x00010000 /* Section is relocated normally during linking, but need - not be loaded during program execution */ -#define STYP_DEBUG 0x00020000 /* debug section */ -#define STYP_OVERLAY 0x00040000 /* Section is overlayed */ -#define STYP_INSTRUCTION 0x00200000 /* Section contains executable code */ - -#define STYP_ZERO 0x00800000 /* Section is initialized to zero */ -#define STYP_INSTALLED 0x02000000 /* Section should be installable in KGT */ -#define STYP_LOOK_INSTALLED 0x04000000 /* Look for section in KGT */ -#define STYP_SECALIGN1 0x08000000 /* Specially aligned section */ -#define STYP_SECALIGN2 0x10000000 /* " " " */ -#define STYP_COMPRESSED 0x20000000 /* No section data per se (s_scnptr = 0), but there are - initialization directives for it in .rwdi section - (used in conjunction with STYP_BSS) */ diff --git a/contrib/gdb/include/coff/arm.h b/contrib/gdb/include/coff/arm.h deleted file mode 100644 index 33b11cbb1de..00000000000 --- a/contrib/gdb/include/coff/arm.h +++ /dev/null @@ -1,215 +0,0 @@ -/*** coff information for the ARM */ - - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - -/* Bits for f_flags: - * F_RELFLG relocation info stripped from file - * F_EXEC file is executable (no unresolved external references) - * F_LNNO line numbers stripped from file - * F_LSYMS local symbols stripped from file - * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax) - */ - -#define F_RELFLG (0x0001) -#define F_EXEC (0x0002) -#define F_LNNO (0x0004) -#define F_LSYMS (0x0008) - - - -#define ARMMAGIC 0xa00 /* I just made these up */ - -#define ARMBADMAG(x) (((x).f_magic != ARMMAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ - - -} -AOUTHDR; - - -#define AOUTSZ (sizeof(AOUTHDR)) - -#define OMAGIC 0404 /* object files, eg as output */ -#define ZMAGIC 0413 /* demand load format, eg normal ld output */ -#define STMAGIC 0401 /* target shlib */ -#define SHMAGIC 0443 /* host shlib */ - - -/* define some NT default values */ -/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */ -#define NT_SECTION_ALIGNMENT 0x1000 -#define NT_FILE_ALIGNMENT 0x200 -#define NT_DEF_RESERVE 0x100000 -#define NT_DEF_COMMIT 0x1000 - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _COMMENT ".comment" -#define _LIB ".lib" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ 6 - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - -#define N_BTMASK (0xf) -#define N_TMASK (0x30) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - -# define _ETEXT "etext" - - -/********************** RELOCATION DIRECTIVES **********************/ - - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; - char r_offset[4]; -}; - - -#define RELOC struct external_reloc -#define RELSZ sizeof (RELOC) diff --git a/contrib/gdb/include/coff/aux-coff.h b/contrib/gdb/include/coff/aux-coff.h deleted file mode 100644 index c89c124d3e0..00000000000 --- a/contrib/gdb/include/coff/aux-coff.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Modifications of internal.h and m68k.h needed by A/UX - Suggested by Ian Lance Taylor */ - -#ifndef GNU_COFF_AUX_H -#define GNU_COFF_AUX_H 1 - -#include "coff/internal.h" -#include "coff/m68k.h" - -/* Section contains 64-byte padded pathnames of shared libraries */ -#undef STYP_LIB -#define STYP_LIB 0x200 - -/* Section contains shared library initialization code */ -#undef STYP_INIT -#define STYP_INIT 0x400 - -/* Section contains .ident information */ -#undef STYP_IDENT -#define STYP_IDENT 0x800 - -/* Section types used by bfd and gas not defined (directly) by A/UX */ -#undef STYP_OVER -#define STYP_OVER 0 -#undef STYP_INFO -#define STYP_INFO STYP_IDENT - -/* Traditional name of the section tagged with STYP_LIB */ -#define _LIB ".lib" - -#endif /* GNU_COFF_AUX_H */ diff --git a/contrib/gdb/include/coff/ecoff.h b/contrib/gdb/include/coff/ecoff.h deleted file mode 100644 index 120f88849e0..00000000000 --- a/contrib/gdb/include/coff/ecoff.h +++ /dev/null @@ -1,408 +0,0 @@ -#ifndef ECOFF_H -#define ECOFF_H - -/* Generic ECOFF support. - This does not include symbol information, found in sym.h and - symconst.h. */ - -/* Mips magic numbers used in filehdr. MIPS_MAGIC_LITTLE is used on - little endian machines. MIPS_MAGIC_BIG is used on big endian - machines. Where is MIPS_MAGIC_1 from? */ -#define MIPS_MAGIC_1 0x0180 -#define MIPS_MAGIC_LITTLE 0x0162 -#define MIPS_MAGIC_BIG 0x0160 - -/* These are the magic numbers used for MIPS code compiled at ISA - level 2. */ -#define MIPS_MAGIC_LITTLE2 0x0166 -#define MIPS_MAGIC_BIG2 0x0163 - -/* These are the magic numbers used for MIPS code compiled at ISA - level 3. */ -#define MIPS_MAGIC_LITTLE3 0x142 -#define MIPS_MAGIC_BIG3 0x140 - -/* Alpha magic numbers used in filehdr. */ -#define ALPHA_MAGIC 0x183 - -/* Magic numbers used in a.out header. */ -#define ECOFF_AOUT_OMAGIC 0407 /* not demand paged (ld -N). */ -#define ECOFF_AOUT_ZMAGIC 0413 /* demand load format, eg normal ld output */ - -/* Names of special sections. */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#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" -#define _GOT ".got" -#define _HASH ".hash" -#define _DYNSYM ".dynsym" -#define _DYNSTR ".dynstr" -#define _RELDYN ".rel.dyn" -#define _CONFLIC ".conflic" -#define _COMMENT ".comment" -#define _LIBLIST ".liblist" -#define _DYNAMIC ".dynamic" -#define _RCONST ".rconst" - -/* ECOFF uses some additional section flags. */ -#define STYP_RDATA 0x100 -#define STYP_SDATA 0x200 -#define STYP_SBSS 0x400 -#define STYP_GOT 0x1000 -#define STYP_DYNAMIC 0x2000 -#define STYP_DYNSYM 0x4000 -#define STYP_RELDYN 0x8000 -#define STYP_DYNSTR 0x10000 -#define STYP_HASH 0x20000 -#define STYP_LIBLIST 0x40000 -#define STYP_CONFLIC 0x100000 -#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_RCONST 0x2200000 -#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" - -/* 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. */ -#define RELOC_SECTION_NONE 0 -#define RELOC_SECTION_TEXT 1 -#define RELOC_SECTION_RDATA 2 -#define RELOC_SECTION_DATA 3 -#define RELOC_SECTION_SDATA 4 -#define RELOC_SECTION_SBSS 5 -#define RELOC_SECTION_BSS 6 -#define RELOC_SECTION_INIT 7 -#define RELOC_SECTION_LIT8 8 -#define RELOC_SECTION_LIT4 9 -#define RELOC_SECTION_XDATA 10 -#define RELOC_SECTION_PDATA 11 -#define RELOC_SECTION_FINI 12 -#define RELOC_SECTION_LITA 13 -#define RELOC_SECTION_ABS 14 -#define RELOC_SECTION_RCONST 15 - -#define NUM_RELOC_SECTIONS 16 - -/********************** STABS **********************/ - -/* gcc uses mips-tfile to output type information in special stabs - entries. These must match the corresponding definition in - gcc/config/mips.h. At some point, these should probably go into a - shared include file, but currently gcc and gdb do not share any - directories. */ -#define CODE_MASK 0x8F300 -#define ECOFF_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) -#define ECOFF_MARK_STAB(code) ((code)+CODE_MASK) -#define ECOFF_UNMARK_STAB(code) ((code)-CODE_MASK) -#define STABS_SYMBOL "@stabs" - -/********************** COFF **********************/ - -/* gcc also uses mips-tfile to output COFF debugging information. - These are the values it uses when outputting the .type directive. - These should also be in a shared include file. */ -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -/********************** AUX **********************/ - -/* The auxiliary type information is the same on all known ECOFF - targets. I can't see any reason that it would ever change, so I am - going to gamble and define the external structures here, in the - target independent ECOFF header file. The internal forms are - defined in coff/sym.h, which was originally donated by MIPS - Computer Systems. */ - -/* Type information external record */ - -struct tir_ext { - unsigned char t_bits1[1]; - unsigned char t_tq45[1]; - unsigned char t_tq01[1]; - unsigned char t_tq23[1]; -}; - -#define TIR_BITS1_FBITFIELD_BIG ((unsigned int) 0x80) -#define TIR_BITS1_FBITFIELD_LITTLE ((unsigned int) 0x01) - -#define TIR_BITS1_CONTINUED_BIG ((unsigned int) 0x40) -#define TIR_BITS1_CONTINUED_LITTLE ((unsigned int) 0x02) - -#define TIR_BITS1_BT_BIG ((unsigned int) 0x3F) -#define TIR_BITS1_BT_SH_BIG 0 -#define TIR_BITS1_BT_LITTLE ((unsigned int) 0xFC) -#define TIR_BITS1_BT_SH_LITTLE 2 - -#define TIR_BITS_TQ4_BIG ((unsigned int) 0xF0) -#define TIR_BITS_TQ4_SH_BIG 4 -#define TIR_BITS_TQ5_BIG ((unsigned int) 0x0F) -#define TIR_BITS_TQ5_SH_BIG 0 -#define TIR_BITS_TQ4_LITTLE ((unsigned int) 0x0F) -#define TIR_BITS_TQ4_SH_LITTLE 0 -#define TIR_BITS_TQ5_LITTLE ((unsigned int) 0xF0) -#define TIR_BITS_TQ5_SH_LITTLE 4 - -#define TIR_BITS_TQ0_BIG ((unsigned int) 0xF0) -#define TIR_BITS_TQ0_SH_BIG 4 -#define TIR_BITS_TQ1_BIG ((unsigned int) 0x0F) -#define TIR_BITS_TQ1_SH_BIG 0 -#define TIR_BITS_TQ0_LITTLE ((unsigned int) 0x0F) -#define TIR_BITS_TQ0_SH_LITTLE 0 -#define TIR_BITS_TQ1_LITTLE ((unsigned int) 0xF0) -#define TIR_BITS_TQ1_SH_LITTLE 4 - -#define TIR_BITS_TQ2_BIG ((unsigned int) 0xF0) -#define TIR_BITS_TQ2_SH_BIG 4 -#define TIR_BITS_TQ3_BIG ((unsigned int) 0x0F) -#define TIR_BITS_TQ3_SH_BIG 0 -#define TIR_BITS_TQ2_LITTLE ((unsigned int) 0x0F) -#define TIR_BITS_TQ2_SH_LITTLE 0 -#define TIR_BITS_TQ3_LITTLE ((unsigned int) 0xF0) -#define TIR_BITS_TQ3_SH_LITTLE 4 - -/* Relative symbol external record */ - -struct rndx_ext { - unsigned char r_bits[4]; -}; - -#define RNDX_BITS0_RFD_SH_LEFT_BIG 4 -#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 ((unsigned int) 0x0F) -#define RNDX_BITS1_RFD_SH_LEFT_LITTLE 8 - -#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 ((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 - -/* Auxiliary symbol information external record */ - -union aux_ext { - struct tir_ext a_ti; - struct rndx_ext a_rndx; - unsigned char a_dnLow[4]; - unsigned char a_dnHigh[4]; - unsigned char a_isym[4]; - unsigned char a_iss[4]; - unsigned char a_width[4]; - unsigned char a_count[4]; -}; - -#define AUX_GET_ANY(bigend, ax, field) \ - ((bigend) ? bfd_getb32 ((ax)->field) : bfd_getl32 ((ax)->field)) - -#define AUX_GET_DNLOW(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_dnLow) -#define AUX_GET_DNHIGH(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_dnHigh) -#define AUX_GET_ISYM(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_isym) -#define AUX_GET_ISS(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_iss) -#define AUX_GET_WIDTH(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_width) -#define AUX_GET_COUNT(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_count) - -#define AUX_PUT_ANY(bigend, val, ax, field) \ - ((bigend) \ - ? (bfd_putb32 ((bfd_vma) (val), (ax)->field), 0) \ - : (bfd_putl32 ((bfd_vma) (val), (ax)->field), 0)) - -#define AUX_PUT_DNLOW(bigend, val, ax) \ - AUX_PUT_ANY ((bigend), (val), (ax), a_dnLow) -#define AUX_PUT_DNHIGH(bigend, val, ax) \ - AUX_PUT_ANY ((bigend), (val), (ax), a_dnHigh) -#define AUX_PUT_ISYM(bigend, val, ax) \ - AUX_PUT_ANY ((bigend), (val), (ax), a_isym) -#define AUX_PUT_ISS(bigend, val, ax) \ - AUX_PUT_ANY ((bigend), (val), (ax), a_iss) -#define AUX_PUT_WIDTH(bigend, val, ax) \ - AUX_PUT_ANY ((bigend), (val), (ax), a_width) -#define AUX_PUT_COUNT(bigend, val, ax) \ - AUX_PUT_ANY ((bigend), (val), (ax), a_count) - -/********************** SYMBOLS **********************/ - -/* 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; -}; - -/* These structures are used by the ECOFF find_nearest_line function. */ - -struct ecoff_fdrtab_entry -{ - /* Base address in .text of this FDR. */ - bfd_vma base_addr; - FDR *fdr; -}; - -struct ecoff_find_line -{ - /* Allocated memory to hold function and file names. */ - char *find_buffer; - - /* FDR table, sorted by address: */ - long fdrtab_len; - struct ecoff_fdrtab_entry *fdrtab; -}; - -/********************** 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) */ diff --git a/contrib/gdb/include/coff/h8300.h b/contrib/gdb/include/coff/h8300.h deleted file mode 100644 index 8fe8f6165fe..00000000000 --- a/contrib/gdb/include/coff/h8300.h +++ /dev/null @@ -1,203 +0,0 @@ -/*** coff information for Hitachi H8/300 and H8/300-H */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - - -#define H8300MAGIC 0x8300 -#define H8300HMAGIC 0x8301 - - -#define H8300BADMAG(x) (((x).f_magic!=H8300MAGIC)) -#define H8300HBADMAG(x) (((x).f_magic!=H8300HMAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - - -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) - - - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" - - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[4]; /* line number */ -}; - -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno)); -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - - -/********************** RELOCATION DIRECTIVES **********************/ - -/* The external reloc has an offset field, because some of the reloc - types on the h8 don't have room in the instruction for the entire - offset - eg the strange jump and high page addressing modes */ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_offset[4]; - char r_type[2]; - char r_stuff[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 16 - - - - diff --git a/contrib/gdb/include/coff/h8500.h b/contrib/gdb/include/coff/h8500.h deleted file mode 100644 index 5a8c9feace9..00000000000 --- a/contrib/gdb/include/coff/h8500.h +++ /dev/null @@ -1,201 +0,0 @@ -/*** coff information for Hitachi H8/500 */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - - -#define H8500MAGIC 0x8500 - - -#define H8500BADMAG(x) ((0xffff && ((x).f_magic)!=H8500MAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - - -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) - - - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" - - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[4]; /* line number */ -}; - -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno)); -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - - -/********************** RELOCATION DIRECTIVES **********************/ - -/* The external reloc has an offset field, because some of the reloc - types on the h8 don't have room in the instruction for the entire - offset - eg the strange jump and high page addressing modes */ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_offset[4]; - char r_type[2]; - char r_stuff[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 16 - - - - diff --git a/contrib/gdb/include/coff/i386.h b/contrib/gdb/include/coff/i386.h deleted file mode 100644 index b7ecf0b6e14..00000000000 --- a/contrib/gdb/include/coff/i386.h +++ /dev/null @@ -1,224 +0,0 @@ -/*** coff information for Intel 386/486. */ - - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - -/* Bits for f_flags: - * F_RELFLG relocation info stripped from file - * F_EXEC file is executable (no unresolved external references) - * F_LNNO line numbers stripped from file - * F_LSYMS local symbols stripped from file - * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax) - */ - -#define F_RELFLG (0x0001) -#define F_EXEC (0x0002) -#define F_LNNO (0x0004) -#define F_LSYMS (0x0008) - - - -#define I386MAGIC 0x14c -#define I386PTXMAGIC 0x154 -#define I386AIXMAGIC 0x175 - -/* This is Lynx's all-platform magic number for executables. */ - -#define LYNXCOFFMAGIC 0415 - -#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \ - && (x).f_magic != I386AIXMAGIC \ - && (x).f_magic != I386PTXMAGIC \ - && (x).f_magic != LYNXCOFFMAGIC) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ - - -} -AOUTHDR; - - -#define AOUTSZ (sizeof(AOUTHDR)) - -#define OMAGIC 0404 /* object files, eg as output */ -#define ZMAGIC 0413 /* demand load format, eg normal ld output */ -#define STMAGIC 0401 /* target shlib */ -#define SHMAGIC 0443 /* host shlib */ - - -/* define some NT default values */ -/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */ -#define NT_SECTION_ALIGNMENT 0x1000 -#define NT_FILE_ALIGNMENT 0x200 -#define NT_DEF_RESERVE 0x100000 -#define NT_DEF_COMMIT 0x1000 - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _COMMENT ".comment" -#define _LIB ".lib" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ 6 - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - -#define N_BTMASK (0xf) -#define N_TMASK (0x30) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - -# define _ETEXT "etext" - - -/********************** RELOCATION DIRECTIVES **********************/ - - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 10 - diff --git a/contrib/gdb/include/coff/i860.h b/contrib/gdb/include/coff/i860.h deleted file mode 100644 index e09ec5f0e51..00000000000 --- a/contrib/gdb/include/coff/i860.h +++ /dev/null @@ -1,204 +0,0 @@ -/* This file was hacked from i386.h [dolan@ssd.intel.com] */ - -/*** coff information for Intel 860. */ - - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - -/* Bits for f_flags: - * F_RELFLG relocation info stripped from file - * F_EXEC file is executable (no unresolved external references) - * F_LNNO line numbers stripped from file - * F_LSYMS local symbols stripped from file - * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax) - */ - -#define F_RELFLG (0x0001) -#define F_EXEC (0x0002) -#define F_LNNO (0x0004) -#define F_LSYMS (0x0008) - - - -#define I860MAGIC 0x14d - -#define I860BADMAG(x) ((x).f_magic != I860MAGIC) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - - -#define AOUTSZ (sizeof(AOUTHDR)) - -/* FIXME: What are the a.out magic numbers? */ - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _COMMENT ".comment" -#define _LIB ".lib" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ 6 - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - -#define N_BTMASK (0xf) -#define N_TMASK (0x30) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - -# define _ETEXT "etext" - - -/********************** RELOCATION DIRECTIVES **********************/ - - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 10 diff --git a/contrib/gdb/include/coff/i960.h b/contrib/gdb/include/coff/i960.h deleted file mode 100644 index c20893c9478..00000000000 --- a/contrib/gdb/include/coff/i960.h +++ /dev/null @@ -1,251 +0,0 @@ -/*** coff information for 80960. Origins: Intel corp, natch. */ - -/* NOTE: Tagentries (cf TAGBITS) are no longer used by the 960 */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - -#define OMAGIC (0407) /* old impure format. data immediately - follows text. both sections are rw. */ -#define NMAGIC (0410) /* split i&d, read-only text */ - -/* -* Intel 80960 (I960) processor flags. -* F_I960TYPE == mask for processor type field. -*/ - -#define F_I960TYPE (0xf000) -#define F_I960CORE (0x1000) -#define F_I960KB (0x2000) -#define F_I960SB (0x2000) -#define F_I960MC (0x3000) -#define F_I960XA (0x4000) -#define F_I960CA (0x5000) -#define F_I960KA (0x6000) -#define F_I960SA (0x6000) -#define F_I960JX (0x7000) -#define F_I960HX (0x8000) - - -/** i80960 Magic Numbers -*/ - -#define I960ROMAGIC (0x160) /* read-only text segments */ -#define I960RWMAGIC (0x161) /* read-write text segments */ - -#define I960BADMAG(x) (((x).f_magic!=I960ROMAGIC) && ((x).f_magic!=I960RWMAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ 20 - -/********************** AOUT "OPTIONAL HEADER" **********************/ - -typedef struct { - unsigned long phys_addr; - unsigned long bitarray; -} TAGBITS; - - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ - char tagentries[4]; /* number of tag entries to follow */ -} -AOUTHDR; - -/* return a pointer to the tag bits array */ - -#define TAGPTR(aout) ((TAGBITS *) (&(aout.tagentries)+1)) - -/* compute size of a header */ - -/*#define AOUTSZ(aout) (sizeof(AOUTHDR)+(aout.tagentries*sizeof(TAGBITS)))*/ -#define AOUTSZ (sizeof(AOUTHDR)) - - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ - char s_align[4]; /* section alignment */ -}; - - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ - char padding[2]; /* force alignment */ -}; - - -#define LINENO struct external_lineno -#define LINESZ 8 - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_flags[2]; - char e_type[4]; - char e_sclass[1]; - char e_numaux[1]; - char pad2[2]; -}; - - - - -#define N_BTMASK (0x1f) -#define N_TMASK (0x60) -#define N_BTSHFT (5) -#define N_TSHIFT (2) - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - /****************************************** - * I960-specific *2nd* aux. entry formats - ******************************************/ - struct { - /* This is a very old typo that keeps getting propagated. */ -#define x_stdindx x_stindx - char x_stindx[4]; /* sys. table entry */ - } x_sc; /* system call entry */ - - struct { - char x_balntry[4]; /* BAL entry point */ - } x_bal; /* BAL-callable function */ - - struct { - char x_timestamp[4]; /* time stamp */ - char x_idstring[20]; /* producer identity string */ - } x_ident; /* Producer ident info */ - -}; - - - -#define SYMENT struct external_syment -#define SYMESZ sizeof(SYMENT) /* FIXME - calc by hand */ -#define AUXENT union external_auxent -#define AUXESZ sizeof(AUXENT) /* FIXME - calc by hand */ - -# define _ETEXT "_etext" - -/********************** RELOCATION DIRECTIVES **********************/ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; - char pad[2]; -}; - - -/* Relevent values for r_type and i960. Would someone please document them */ - - -#define RELOC struct external_reloc -#define RELSZ 12 - diff --git a/contrib/gdb/include/coff/internal.h b/contrib/gdb/include/coff/internal.h deleted file mode 100644 index b43cf766421..00000000000 --- a/contrib/gdb/include/coff/internal.h +++ /dev/null @@ -1,648 +0,0 @@ -/* Internal format of COFF object file data structures, for GNU BFD. - This file is part of BFD, the Binary File Descriptor library. */ - -#ifndef GNU_COFF_INTERNAL_H -#define GNU_COFF_INTERNAL_H 1 - -/* First, make "signed char" work, even on old compilers. */ -#ifndef signed -#ifndef __STDC__ -#define signed /**/ -#endif -#endif - -/********************** FILE HEADER **********************/ - -/* extra stuff in a PE header. */ - -struct internal_extra_pe_filehdr -{ - /* DOS header data follows for PE stuff */ - unsigned short e_magic; /* Magic number, 0x5a4d */ - unsigned short e_cblp; /* Bytes on last page of file, 0x90 */ - unsigned short e_cp; /* Pages in file, 0x3 */ - unsigned short e_crlc; /* Relocations, 0x0 */ - unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */ - unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */ - unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */ - unsigned short e_ss; /* Initial (relative) SS value, 0x0 */ - unsigned short e_sp; /* Initial SP value, 0xb8 */ - unsigned short e_csum; /* Checksum, 0x0 */ - unsigned short e_ip; /* Initial IP value, 0x0 */ - unsigned short e_cs; /* Initial (relative) CS value, 0x0 */ - unsigned short e_lfarlc; /* File address of relocation table, 0x40 */ - unsigned short e_ovno; /* Overlay number, 0x0 */ - unsigned short e_res[4]; /* Reserved words, all 0x0 */ - unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */ - unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */ - unsigned short e_res2[10]; /* Reserved words, all 0x0 */ - bfd_vma e_lfanew; /* File address of new exe header, 0x80 */ - unsigned long dos_message[16]; /* text which always follows dos header */ - bfd_vma nt_signature; /* required NT signature, 0x4550 */ -}; - -struct internal_filehdr -{ - struct internal_extra_pe_filehdr pe; - - /* standard coff internal info */ - unsigned short f_magic; /* magic number */ - unsigned short f_nscns; /* number of sections */ - long f_timdat; /* time & date stamp */ - bfd_vma f_symptr; /* file pointer to symtab */ - long f_nsyms; /* number of symtab entries */ - unsigned short f_opthdr; /* sizeof(optional hdr) */ - unsigned short f_flags; /* flags */ -}; - - -/* Bits for f_flags: - * F_RELFLG relocation info stripped from file - * F_EXEC file is executable (no unresolved external references) - * F_LNNO line numbers stripped from file - * F_LSYMS local symbols stripped from file - * F_AR16WR file is 16-bit little-endian - * F_AR32WR file is 32-bit little-endian - * F_AR32W file is 32-bit big-endian - * F_DYNLOAD rs/6000 aix: dynamically loadable w/imports & exports - * F_SHROBJ rs/6000 aix: file is a shared object - * F_DLL PE format DLL - */ - -#define F_RELFLG (0x0001) -#define F_EXEC (0x0002) -#define F_LNNO (0x0004) -#define F_LSYMS (0x0008) -#define F_AR16WR (0x0080) -#define F_AR32WR (0x0100) -#define F_AR32W (0x0200) -#define F_DYNLOAD (0x1000) -#define F_SHROBJ (0x2000) -#define F_DLL (0x2000) - -/* extra structure which is used in the optional header */ -typedef struct _IMAGE_DATA_DIRECTORY -{ - bfd_vma VirtualAddress; - long Size; -} IMAGE_DATA_DIRECTORY; -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 - -/* default image base for NT */ -#define NT_EXE_IMAGE_BASE 0x400000 -#define NT_DLL_IMAGE_BASE 0x10000000 - -/* Extra stuff in a PE aouthdr */ - -#define PE_DEF_SECTION_ALIGNMENT 0x1000 -#define PE_DEF_FILE_ALIGNMENT 0x200 - -struct internal_extra_pe_aouthdr -{ - /* PE stuff */ - bfd_vma ImageBase; /* address of specific location in memory that - file is located, NT default 0x10000 */ - - bfd_vma SectionAlignment; /* section alignment default 0x1000 */ - bfd_vma FileAlignment; /* file alignment default 0x200 */ - short MajorOperatingSystemVersion; /* minimum version of the operating */ - short MinorOperatingSystemVersion; /* system req'd for exe, default to 1*/ - short MajorImageVersion; /* user defineable field to store version of */ - short MinorImageVersion; /* exe or dll being created, default to 0 */ - short MajorSubsystemVersion; /* minimum subsystem version required to */ - short MinorSubsystemVersion; /* run exe; default to 3.1 */ - long Reserved1; /* seems to be 0 */ - long SizeOfImage; /* size of memory to allocate for prog */ - long SizeOfHeaders; /* size of PE header and section table */ - long CheckSum; /* set to 0 */ - short Subsystem; - - /* type of subsystem exe uses for user interface, - possible values: - 1 - NATIVE Doesn't require a subsystem - 2 - WINDOWS_GUI runs in Windows GUI subsystem - 3 - WINDOWS_CUI runs in Windows char sub. (console app) - 5 - OS2_CUI runs in OS/2 character subsystem - 7 - POSIX_CUI runs in Posix character subsystem */ - short DllCharacteristics; /* flags for DLL init, use 0 */ - bfd_vma SizeOfStackReserve; /* amount of memory to reserve */ - bfd_vma SizeOfStackCommit; /* amount of memory initially committed for - initial thread's stack, default is 0x1000 */ - bfd_vma SizeOfHeapReserve; /* amount of virtual memory to reserve and */ - bfd_vma SizeOfHeapCommit; /* commit, don't know what to defaut it to */ - long LoaderFlags; /* can probably set to 0 */ - long NumberOfRvaAndSizes; /* number of entries in next entry, 16 */ - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -}; - -/********************** AOUT "OPTIONAL HEADER" **********************/ -struct internal_aouthdr -{ - short magic; /* type of file */ - short vstamp; /* version stamp */ - bfd_vma tsize; /* text size in bytes, padded to FW bdry*/ - bfd_vma dsize; /* initialized data " " */ - bfd_vma bsize; /* uninitialized data " " */ - bfd_vma entry; /* entry pt. */ - bfd_vma text_start; /* base of text used for this file */ - bfd_vma data_start; /* base of data used for this file */ - - /* i960 stuff */ - unsigned long tagentries; /* number of tag entries to follow */ - - /* RS/6000 stuff */ - unsigned long o_toc; /* address of TOC */ - short o_snentry; /* section number for entry point */ - short o_sntext; /* section number for text */ - short o_sndata; /* section number for data */ - short o_sntoc; /* section number for toc */ - short o_snloader; /* section number for loader section */ - short o_snbss; /* section number for bss */ - short o_algntext; /* max alignment for text */ - short o_algndata; /* max alignment for data */ - short o_modtype; /* Module type field, 1R,RE,RO */ - short o_cputype; /* Encoded CPU type */ - unsigned long o_maxstack; /* max stack size allowed. */ - unsigned long o_maxdata; /* max data size allowed. */ - - /* ECOFF stuff */ - bfd_vma bss_start; /* Base of bss section. */ - 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. */ - - /* Apollo stuff */ - long o_inlib; /* inlib data */ - long o_sri; /* Static Resource Information */ - long vid[2]; /* Version id */ - - - struct internal_extra_pe_aouthdr pe; - -}; - -/********************** STORAGE CLASSES **********************/ - -/* This used to be defined as -1, but now n_sclass is unsigned. */ -#define C_EFCN 0xff /* physical end of function */ -#define C_NULL 0 -#define C_AUTO 1 /* automatic variable */ -#define C_EXT 2 /* external symbol */ -#define C_STAT 3 /* static */ -#define C_REG 4 /* register variable */ -#define C_EXTDEF 5 /* external definition */ -#define C_LABEL 6 /* label */ -#define C_ULABEL 7 /* undefined label */ -#define C_MOS 8 /* member of structure */ -#define C_ARG 9 /* function argument */ -#define C_STRTAG 10 /* structure tag */ -#define C_MOU 11 /* member of union */ -#define C_UNTAG 12 /* union tag */ -#define C_TPDEF 13 /* type definition */ -#define C_USTATIC 14 /* undefined static */ -#define C_ENTAG 15 /* enumeration tag */ -#define C_MOE 16 /* member of enumeration */ -#define C_REGPARM 17 /* register parameter */ -#define C_FIELD 18 /* bit field */ -#define C_AUTOARG 19 /* auto argument */ -#define C_LASTENT 20 /* dummy entry (end of block) */ -#define C_BLOCK 100 /* ".bb" or ".eb" */ -#define C_FCN 101 /* ".bf" or ".ef" */ -#define C_EOS 102 /* end of structure */ -#define C_FILE 103 /* file name */ -#define C_LINE 104 /* line # reformatted as symbol table entry */ -#define C_ALIAS 105 /* duplicate tag */ -#define C_HIDDEN 106 /* ext symbol in dmert public lib */ - -/* New storage classes for WINDOWS_NT */ -#define C_SECTION 104 /* section name */ -#define C_NT_WEAK 105 /* weak external */ - - /* New storage classes for 80960 */ - -/* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */ -#define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */ - -#define C_SCALL 107 /* Procedure reachable via system call */ -#define C_LEAFEXT 108 /* External leaf */ -#define C_LEAFSTAT 113 /* Static leaf */ -#define C_OPTVAR 109 /* Optimized variable */ -#define C_DEFINE 110 /* Preprocessor #define */ -#define C_PRAGMA 111 /* Advice to compiler or linker */ -#define C_SEGMENT 112 /* 80960 segment name */ - - /* Storage classes for m88k */ -#define C_SHADOW 107 /* shadow symbol */ -#define C_VERSION 108 /* coff version symbol */ - - /* New storage classes for RS/6000 */ -#define C_HIDEXT 107 /* Un-named external symbol */ -#define C_BINCL 108 /* Marks beginning of include file */ -#define C_EINCL 109 /* Marks ending of include file */ - - /* storage classes for stab symbols for RS/6000 */ -#define C_GSYM (0x80) -#define C_LSYM (0x81) -#define C_PSYM (0x82) -#define C_RSYM (0x83) -#define C_RPSYM (0x84) -#define C_STSYM (0x85) -#define C_TCSYM (0x86) -#define C_BCOMM (0x87) -#define C_ECOML (0x88) -#define C_ECOMM (0x89) -#define C_DECL (0x8c) -#define C_ENTRY (0x8d) -#define C_FUN (0x8e) -#define C_BSTAT (0x8f) -#define C_ESTAT (0x90) - -/********************** SECTION HEADER **********************/ -struct internal_scnhdr -{ - char s_name[8]; /* section name */ - bfd_vma s_paddr; /* physical address, aliased s_nlib */ - bfd_vma s_vaddr; /* virtual address */ - bfd_vma s_size; /* section size */ - bfd_vma s_scnptr; /* file ptr to raw data for section */ - bfd_vma s_relptr; /* file ptr to relocation */ - bfd_vma s_lnnoptr; /* file ptr to line numbers */ - unsigned long s_nreloc; /* number of relocation entries */ - unsigned long s_nlnno; /* number of line number entries*/ - long s_flags; /* flags */ - long s_align; /* used on I960 */ -}; - -/* - * s_flags "type" - */ -#define STYP_REG (0x0000) /* "regular": allocated, relocated, loaded */ -#define STYP_DSECT (0x0001) /* "dummy": relocated only*/ -#define STYP_NOLOAD (0x0002) /* "noload": allocated, relocated, not loaded */ -#define STYP_GROUP (0x0004) /* "grouped": formed of input sections */ -#define STYP_PAD (0x0008) /* "padding": not allocated, not relocated, loaded */ -#define STYP_COPY (0x0010) /* "copy": for decision function used by field update; not allocated, not relocated, - loaded; reloc & lineno entries processed normally */ -#define STYP_TEXT (0x0020) /* section contains text only */ -#define S_SHRSEG (0x0020) /* In 3b Update files (output of ogen), sections which appear in SHARED segments of the Pfile - will have the S_SHRSEG flag set by ogen, to inform dufr that updating 1 copy of the proc. will - update all process invocations. */ -#define STYP_DATA (0x0040) /* section contains data only */ -#define STYP_BSS (0x0080) /* section contains bss only */ -#define S_NEWFCN (0x0100) /* In a minimal file or an update file, a new function (as compared with a replaced function) */ -#define STYP_INFO (0x0200) /* comment: not allocated not relocated, not loaded */ -#define STYP_OVER (0x0400) /* overlay: relocated not allocated or loaded */ -#define STYP_LIB (0x0800) /* for .lib: same as INFO */ -#define STYP_MERGE (0x2000) /* merge section -- combines with text, data or bss sections only */ -#define STYP_REVERSE_PAD (0x4000) /* section will be padded with no-op instructions wherever padding is necessary and there is a - - word of contiguous bytes - beginning on a word boundary. */ - -#define STYP_LIT 0x8020 /* Literal data (like STYP_TEXT) */ - - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ - -struct internal_lineno -{ - union - { - long l_symndx; /* function name symbol index, iff l_lnno == 0*/ - long l_paddr; /* (physical) address of line number */ - } l_addr; - unsigned long l_lnno; /* line number */ -}; - -/********************** SYMBOLS **********************/ - -#define SYMNMLEN 8 /* # characters in a symbol name */ -#define FILNMLEN 14 /* # characters in a file name */ -#define DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct internal_syment -{ - union - { - char _n_name[SYMNMLEN]; /* old COFF version */ - struct - { - long _n_zeroes; /* new == 0 */ - long _n_offset; /* offset into string table */ - } _n_n; - char *_n_nptr[2]; /* allows for overlaying */ - } _n; - long n_value; /* value of symbol */ - short n_scnum; /* section number */ - unsigned short n_flags; /* copy of flags from filhdr */ - unsigned short n_type; /* type and derived type */ - unsigned char n_sclass; /* storage class */ - unsigned char n_numaux; /* number of aux. entries */ -}; - -#define n_name _n._n_name -#define n_zeroes _n._n_n._n_zeroes -#define n_offset _n._n_n._n_offset - - -/* Relocatable symbols have number of the section in which they are defined, - or one of the following: */ - -#define N_UNDEF ((short)0) /* undefined symbol */ -#define N_ABS ((short)-1) /* value of symbol is absolute */ -#define N_DEBUG ((short)-2) /* debugging symbol -- value is meaningless */ -#define N_TV ((short)-3) /* indicates symbol needs preload transfer vector */ -#define P_TV ((short)-4) /* indicates symbol needs postload transfer vector*/ - -/* - * Type of a symbol, in low N bits of the word - */ -#define T_NULL 0 -#define T_VOID 1 /* function argument (only used by compiler) */ -#define T_CHAR 2 /* character */ -#define T_SHORT 3 /* short integer */ -#define T_INT 4 /* integer */ -#define T_LONG 5 /* long integer */ -#define T_FLOAT 6 /* floating point */ -#define T_DOUBLE 7 /* double word */ -#define T_STRUCT 8 /* structure */ -#define T_UNION 9 /* union */ -#define T_ENUM 10 /* enumeration */ -#define T_MOE 11 /* member of enumeration*/ -#define T_UCHAR 12 /* unsigned character */ -#define T_USHORT 13 /* unsigned short */ -#define T_UINT 14 /* unsigned integer */ -#define T_ULONG 15 /* unsigned long */ -#define T_LNGDBL 16 /* long double */ - -/* - * derived types, in n_type -*/ -#define DT_NON (0) /* no derived type */ -#define DT_PTR (1) /* pointer */ -#define DT_FCN (2) /* function */ -#define DT_ARY (3) /* array */ - -#define BTYPE(x) ((x) & N_BTMASK) - -#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT)) -#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT)) -#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT)) -#define ISTAG(x) ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG) -#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) - - -union internal_auxent -{ - struct - { - - union - { - long l; /* str, un, or enum tag indx */ - struct coff_ptr_struct *p; - } x_tagndx; - - union - { - struct - { - unsigned short x_lnno; /* declaration line number */ - unsigned short x_size; /* str/union/array size */ - } x_lnsz; - long x_fsize; /* size of function */ - } x_misc; - - union - { - struct - { /* if ISFCN, tag, or .bb */ - long x_lnnoptr; /* ptr to fcn line # */ - union - { /* entry ndx past block end */ - long l; - struct coff_ptr_struct *p; - } x_endndx; - } x_fcn; - - struct - { /* if ISARY, up to 4 dimen. */ - unsigned short x_dimen[DIMNUM]; - } x_ary; - } x_fcnary; - - unsigned short x_tvndx; /* tv index */ - } x_sym; - - union - { - char x_fname[FILNMLEN]; - struct - { - long x_zeroes; - long x_offset; - } x_n; - } x_file; - - struct - { - long x_scnlen; /* section length */ - unsigned short x_nreloc; /* # relocation entries */ - unsigned short x_nlinno; /* # line numbers */ - } x_scn; - - struct - { - long x_tvfill; /* tv fill value */ - unsigned short x_tvlen; /* length of .tv */ - unsigned short x_tvran[2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - /****************************************** - * RS/6000-specific auxent - last auxent for every external symbol - ******************************************/ - struct - { - 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 */ - /* 0-4 - Log 2 of alignment */ - /* 5-7 - symbol type */ - unsigned char x_smclas; /* storage mapping class */ - long x_stab; /* dbx stab info index */ - unsigned short x_snstab; /* sect num with dbx stab */ - } x_csect; /* csect definition information */ - -/* x_smtyp values: */ - -#define SMTYP_ALIGN(x) ((x) >> 3) /* log2 of alignment */ -#define SMTYP_SMTYP(x) ((x) & 0x7) /* symbol type */ -/* Symbol type values: */ -#define XTY_ER 0 /* External reference */ -#define XTY_SD 1 /* Csect definition */ -#define XTY_LD 2 /* Label definition */ -#define XTY_CM 3 /* .BSS */ -#define XTY_EM 4 /* Error message */ -#define XTY_US 5 /* "Reserved for internal use" */ - -/* x_smclas values: */ - -#define XMC_PR 0 /* Read-only program code */ -#define XMC_RO 1 /* Read-only constant */ -#define XMC_DB 2 /* Read-only debug dictionary table */ -#define XMC_TC 3 /* Read-write general TOC entry */ -#define XMC_UA 4 /* Read-write unclassified */ -#define XMC_RW 5 /* Read-write data */ -#define XMC_GL 6 /* Read-only global linkage */ -#define XMC_XO 7 /* Read-only extended operation */ -#define XMC_SV 8 /* Read-only supervisor call */ -#define XMC_BS 9 /* Read-write BSS */ -#define XMC_DS 10 /* Read-write descriptor csect */ -#define XMC_UC 11 /* Read-write unnamed Fortran common */ -#define XMC_TI 12 /* Read-only traceback index csect */ -#define XMC_TB 13 /* Read-only traceback table csect */ -/* 14 ??? */ -#define XMC_TC0 15 /* Read-write TOC anchor */ -#define XMC_TD 16 /* Read-write data in TOC */ - - /****************************************** - * I960-specific *2nd* aux. entry formats - ******************************************/ - struct - { - /* This is a very old typo that keeps getting propagated. */ -#define x_stdindx x_stindx - long x_stindx; /* sys. table entry */ - } x_sc; /* system call entry */ - - struct - { - unsigned long x_balntry; /* BAL entry point */ - } x_bal; /* BAL-callable function */ - - struct - { - unsigned long x_timestamp; /* time stamp */ - char x_idstring[20]; /* producer identity string */ - } x_ident; /* Producer ident info */ - -}; - -/********************** RELOCATION DIRECTIVES **********************/ - -struct internal_reloc -{ - bfd_vma r_vaddr; /* Virtual address of reference */ - long r_symndx; /* Index into symbol table */ - 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 Alpha ECOFF, SPARC, others */ -}; - -#define R_RELBYTE 017 -#define R_RELWORD 020 -#define R_PCRBYTE 022 -#define R_PCRWORD 023 -#define R_PCRLONG 024 - -#define R_DIR16 01 -#define R_DIR32 06 -#define R_PCLONG 020 -#define R_RELBYTE 017 -#define R_RELWORD 020 -#define R_IMAGEBASE 07 - - -#define R_PCR16L 128 -#define R_PCR26L 129 -#define R_VRT16 130 -#define R_HVRT16 131 -#define R_LVRT16 132 -#define R_VRT32 133 -#define R_RELLONG (0x11) /* Direct 32-bit relocation */ -#define R_IPRSHORT (0x18) -#define R_IPRMED (0x19) /* 24-bit ip-relative relocation */ -#define R_IPRLONG (0x1a) -#define R_OPTCALL (0x1b) /* 32-bit optimizable call (leafproc/sysproc) */ -#define R_OPTCALLX (0x1c) /* 64-bit optimizable call (leafproc/sysproc) */ -#define R_GETSEG (0x1d) -#define R_GETPA (0x1e) -#define R_TAGWORD (0x1f) -#define R_JUMPTARG 0x20 /* strange 29k 00xx00xx reloc */ - - -#define R_MOVB1 0x41 /* Special h8 16bit or 8 bit reloc for mov.b */ -#define R_MOVB2 0x42 /* Special h8 opcode for 8bit which could be 16 */ -#define R_JMP1 0x43 /* Special h8 16bit jmp which could be pcrel */ -#define R_JMP2 0x44 /* a branch which used to be a jmp */ -#define R_RELLONG_NEG 0x45 - -#define R_JMPL1 0x46 /* Special h8 24bit jmp which could be pcrel */ -#define R_JMPL_B8 0x47 /* a 8 bit pcrel which used to be a jmp */ - -#define R_MOVLB1 0x48 /* Special h8 24bit or 8 bit reloc for mov.b */ -#define R_MOVLB2 0x49 /* Special h8 opcode for 8bit which could be 24 */ - -/* An h8300 memory indirect jump/call. Forces the address of the jump/call - target into the function vector (in page zero), and the address of the - vector entry to be placed in the jump/call instruction. */ -#define R_MEM_INDIRECT 0x4a - -/* Z8k modes */ -#define R_IMM16 0x01 /* 16 bit abs */ -#define R_JR 0x02 /* jr 8 bit disp */ -#define R_IMM4L 0x23 /* low nibble */ -#define R_IMM8 0x22 /* 8 bit abs */ -#define R_IMM32 R_RELLONG /* 32 bit abs */ -#define R_CALL R_DA /* Absolute address which could be a callr */ -#define R_JP R_DA /* Absolute address which could be a jp */ -#define R_REL16 0x04 /* 16 bit PC rel */ -#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 */ - -#define R_H8500_IMM8 1 /* 8 bit immediate */ -#define R_H8500_IMM16 2 /* 16 bit immediate */ -#define R_H8500_PCREL8 3 /* 8 bit pcrel */ -#define R_H8500_PCREL16 4 /* 16 bit pcrel */ -#define R_H8500_HIGH8 5 /* high 8 bits of 24 bit address */ -#define R_H8500_LOW16 7 /* low 16 bits of 24 bit immediate */ -#define R_H8500_IMM24 6 /* 24 bit immediate */ -#define R_H8500_IMM32 8 /* 32 bit immediate */ -#define R_H8500_HIGH16 9 /* high 16 bits of 32 bit immediate */ - -/* W65 modes */ - -#define R_W65_ABS8 1 /* addr & 0xff */ -#define R_W65_ABS16 2 /* addr & 0xffff */ -#define R_W65_ABS24 3 /* addr & 0xffffff */ - -#define R_W65_ABS8S8 4 /* (addr >> 8) & 0xff */ -#define R_W65_ABS8S16 5 /* (addr >> 16) & 0xff */ - -#define R_W65_ABS16S8 6 /* (addr >> 8) & 0ffff */ -#define R_W65_ABS16S16 7 /* (addr >> 16) & 0ffff */ - -#define R_W65_PCR8 8 -#define R_W65_PCR16 9 - -#define R_W65_DP 10 /* direct page 8 bits only */ - -#endif /* GNU_COFF_INTERNAL_H */ diff --git a/contrib/gdb/include/coff/m68k.h b/contrib/gdb/include/coff/m68k.h deleted file mode 100644 index a3c15be1618..00000000000 --- a/contrib/gdb/include/coff/m68k.h +++ /dev/null @@ -1,221 +0,0 @@ -/*** coff information for M68K */ - -#ifndef GNU_COFF_M68K_H -#define GNU_COFF_M68K_H 1 - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - -/* Motorola 68000/68008/68010/68020 */ -#define MC68MAGIC 0520 -#define MC68KWRMAGIC 0520 /* writeable text segments */ -#define MC68TVMAGIC 0521 -#define MC68KROMAGIC 0521 /* readonly shareable text segments */ -#define MC68KPGMAGIC 0522 /* demand paged text segments */ -#define M68MAGIC 0210 -#define M68TVMAGIC 0211 - -/* this is the magic of the Bull dpx/2 */ -#define MC68KBCSMAGIC 0526 - -/* This is Lynx's all-platform magic number for executables. */ - -#define LYNXCOFFMAGIC 0415 - -#define OMAGIC M68MAGIC - -/* This intentionally does not include MC68KBCSMAGIC; it only includes - magic numbers which imply that names do not have underscores. */ -#define M68KBADMAG(x) (((x).f_magic!=MC68MAGIC) && ((x).f_magic!=MC68KWRMAGIC) && ((x).f_magic!=MC68TVMAGIC) && \ - ((x).f_magic!=MC68KROMAGIC) && ((x).f_magic!=MC68KPGMAGIC) && ((x).f_magic!=M68MAGIC) && ((x).f_magic!=M68TVMAGIC) && ((x).f_magic!=LYNXCOFFMAGIC) ) - -/* Magic numbers for the a.out header. */ - -#define PAGEMAGICEXECSWAPPED 0407 /* executable (swapped) */ -#define PAGEMAGICPEXECSWAPPED 0410 /* pure executable (swapped) */ -#define PAGEMAGICPEXECTSHLIB 0443 /* pure executable (target shared library) */ -#define PAGEMAGICPEXECPAGED 0413 /* pure executable (paged) */ - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - -#define AOUTSZ (sizeof(AOUTHDR)) - - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _COMMENT ".comment" - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - - -/********************** RELOCATION DIRECTIVES **********************/ - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; -#ifdef M68K_COFF_OFFSET - char r_offset[4]; -#endif - -}; - - -#define RELOC struct external_reloc - -#define RELSZ sizeof(struct external_reloc) - -#endif /* GNU_COFF_M68K_H */ diff --git a/contrib/gdb/include/coff/m88k.h b/contrib/gdb/include/coff/m88k.h deleted file mode 100644 index 9068dd3f124..00000000000 --- a/contrib/gdb/include/coff/m88k.h +++ /dev/null @@ -1,218 +0,0 @@ -/*** coff information for 88k bcs */ - -/********************** FILE HEADER **********************/ -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - -#define MC88MAGIC 0540 /* 88k BCS executable */ -#define MC88DMAGIC 0541 /* DG/UX executable */ -#define MC88OMAGIC 0555 /* Object file */ - -#define MC88BADMAG(x) (((x).f_magic!=MC88MAGIC) &&((x).f_magic!=MC88DMAGIC) && ((x).f_magic != MC88OMAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -#define PAGEMAGIC3 0414 /* Split i&d, zero mapped */ -#define PAGEMAGICBCS 0413 - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - - -/* compute size of a header */ - -#define AOUTSZ (sizeof(AOUTHDR)) - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr -{ - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[4]; /* number of relocation entries */ - char s_nlnno[4]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _COMMENT ".comment" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno{ - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - - char l_lnno[4]; - -}; - -#define LINENO struct external_lineno -#define LINESZ 8 - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; - char pad2[2]; -}; - - - - -#define N_BTMASK 017 -#define N_TMASK 060 -#define N_BTSHFT 4 -#define N_TSHIFT 2 - - -/* Note that this isn't the same shape as other coffs */ -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - /* 4 */ - union { - char x_fsize[4]; /* size of function */ - struct { - char x_lnno[4]; /* declaration line number */ - char x_size[4]; /* str/union/array size */ - } x_lnsz; - } x_misc; - - /* 12 */ - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - /* 20 */ - - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[4]; /* # relocation entries */ - char x_nlinno[4]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - -}; - -#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *)ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#define PUT_FCN_LNNOPTR(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size) -#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno) -#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno) -#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size) -#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen) -#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_nreloc) -#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_nlinno) -#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen) -#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc) -#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_32(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno) -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno)) -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); - - - -#define SYMENT struct external_syment -#define SYMESZ 20 -#define AUXENT union external_auxent -#define AUXESZ 20 - - -/********************** RELOCATION DIRECTIVES **********************/ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; - char r_offset[2]; -}; - -#define RELOC struct external_reloc -#define RELSZ 12 - -#define NO_TVNDX diff --git a/contrib/gdb/include/coff/mips.h b/contrib/gdb/include/coff/mips.h deleted file mode 100644 index f35187e83b1..00000000000 --- a/contrib/gdb/include/coff/mips.h +++ /dev/null @@ -1,368 +0,0 @@ -/* ECOFF support on MIPS machines. - coff/ecoff.h must be included before this file. */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - unsigned char f_magic[2]; /* magic number */ - unsigned char f_nscns[2]; /* number of sections */ - unsigned char f_timdat[4]; /* time & date stamp */ - unsigned char f_symptr[4]; /* file pointer to symtab */ - unsigned char f_nsyms[4]; /* number of symtab entries */ - unsigned char f_opthdr[2]; /* sizeof(optional hdr) */ - unsigned char f_flags[2]; /* flags */ -}; - -/* Magic numbers are defined in coff/ecoff.h. */ -#define MIPS_ECOFF_BADMAG(x) (((x).f_magic!=MIPS_MAGIC_1) && \ - ((x).f_magic!=MIPS_MAGIC_LITTLE) &&\ - ((x).f_magic!=MIPS_MAGIC_BIG) && \ - ((x).f_magic!=MIPS_MAGIC_LITTLE2) && \ - ((x).f_magic!=MIPS_MAGIC_BIG2) && \ - ((x).f_magic!=MIPS_MAGIC_LITTLE3) && \ - ((x).f_magic!=MIPS_MAGIC_BIG3)) - -#define FILHDR struct external_filehdr -#define FILHSZ 20 - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct external_aouthdr -{ - unsigned char magic[2]; /* type of file */ - unsigned char vstamp[2]; /* version stamp */ - unsigned char tsize[4]; /* text size in bytes, padded to FW bdry*/ - unsigned char dsize[4]; /* initialized data " " */ - unsigned char bsize[4]; /* uninitialized data " " */ - unsigned char entry[4]; /* entry pt. */ - unsigned char text_start[4]; /* base of text used for this file */ - unsigned char data_start[4]; /* base of data used for this file */ - unsigned char bss_start[4]; /* base of bss used for this file */ - unsigned char gprmask[4]; /* ?? */ - unsigned char cprmask[4][4]; /* ?? */ - unsigned char gp_value[4]; /* value for gp register */ -} AOUTHDR; - -/* compute size of a header */ - -#define AOUTSZ (sizeof(AOUTHDR)) - -/********************** SECTION HEADER **********************/ - -struct external_scnhdr { - unsigned char s_name[8]; /* section name */ - unsigned char s_paddr[4]; /* physical address, aliased s_nlib */ - unsigned char s_vaddr[4]; /* virtual address */ - unsigned char s_size[4]; /* section size */ - unsigned char s_scnptr[4]; /* file ptr to raw data for section */ - unsigned char s_relptr[4]; /* file ptr to relocation */ - unsigned char s_lnnoptr[4]; /* file ptr to line numbers */ - unsigned char s_nreloc[2]; /* number of relocation entries */ - unsigned char s_nlnno[2]; /* number of line number entries*/ - unsigned char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/********************** RELOCATION DIRECTIVES **********************/ - -struct external_reloc { - unsigned char r_vaddr[4]; - unsigned char r_bits[4]; -}; - -#define RELOC struct external_reloc -#define RELSZ 8 - -/* MIPS ECOFF uses a packed 8 byte format for relocs. These constants - are used to unpack the r_bits field. */ - -#define RELOC_BITS0_SYMNDX_SH_LEFT_BIG 16 -#define RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE 0 - -#define RELOC_BITS1_SYMNDX_SH_LEFT_BIG 8 -#define RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE 8 - -#define RELOC_BITS2_SYMNDX_SH_LEFT_BIG 0 -#define RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE 16 - -/* Originally, ECOFF used four bits for the reloc type and had three - reserved bits. Irix 4 added another bit for the reloc type, which - was easy because it was big endian and one of the spare bits became - the new most significant bit. To make this also work for little - endian ECOFF, we need to wrap one of the reserved bits around to - become the most significant bit of the reloc type. */ -#define RELOC_BITS3_TYPE_BIG 0x3E -#define RELOC_BITS3_TYPE_SH_BIG 1 -#define RELOC_BITS3_TYPE_LITTLE 0x78 -#define RELOC_BITS3_TYPE_SH_LITTLE 3 -#define RELOC_BITS3_TYPEHI_LITTLE 0x04 -#define RELOC_BITS3_TYPEHI_SH_LITTLE 2 - -#define RELOC_BITS3_EXTERN_BIG 0x01 -#define RELOC_BITS3_EXTERN_LITTLE 0x80 - -/* The r_type field in a reloc is one of the following values. I - don't know if any other values can appear. These seem to be all - that occur in the Ultrix 4.2 libraries. */ -#define MIPS_R_IGNORE 0 -#define MIPS_R_REFHALF 1 -#define MIPS_R_REFWORD 2 -#define MIPS_R_JMPADDR 3 -#define MIPS_R_REFHI 4 -#define MIPS_R_REFLO 5 -#define MIPS_R_GPREL 6 -#define MIPS_R_LITERAL 7 - -/* These reloc types are a Cygnus extension used when generating - position independent code for embedded systems. The numbers are - taken from Irix 4, but at least for internal relocs Irix 5 does not - give them the same meaning. For an internal reloc the symbol index - of RELHI and RELLO is modified as described below for - MIPS_R_SWITCH. */ -#define MIPS_R_PCREL16 12 -#define MIPS_R_RELHI 13 -#define MIPS_R_RELLO 14 - -/* This reloc type is a Cygnus extension used when generating position - independent code for embedded systems. It is used for an entry in - a switch table, which looks like this: - .word $L3-$LS12 - The object file will contain the correct difference, and does not - require adjustment. However, when the linker is relaxing PC - relative calls, it is possible for $L3 to move farther away. This - reloc always appears in the .text section, and is always against - the .text section. However, the symbol index is not - RELOC_SECTION_TEXT. It is, instead, the distance between this - switch table entry and $LS12. Thus, the original value of $L12 is - vaddr - symndx - and the original value of $L3 is - vaddr - symndx + addend - where addend is the value in the object file. Knowing this, the - linker can know whether the addend in the object file must be - adjusted. */ -#define MIPS_R_SWITCH 22 - -/********************** STABS **********************/ - -#define MIPS_IS_STAB ECOFF_IS_STAB -#define MIPS_MARK_STAB ECOFF_MARK_STAB -#define MIPS_UNMARK_STAB ECOFF_UNMARK_STAB - -/********************** SYMBOLIC INFORMATION **********************/ - -/* Written by John Gilmore. */ - -/* ECOFF uses COFF-like section structures, but its own symbol format. - This file defines the symbol format in fields whose size and alignment - will not vary on different host systems. */ - -/* File header as a set of bytes */ - -struct hdr_ext { - unsigned char h_magic[2]; - unsigned char h_vstamp[2]; - unsigned char h_ilineMax[4]; - unsigned char h_cbLine[4]; - unsigned char h_cbLineOffset[4]; - unsigned char h_idnMax[4]; - unsigned char h_cbDnOffset[4]; - unsigned char h_ipdMax[4]; - unsigned char h_cbPdOffset[4]; - unsigned char h_isymMax[4]; - unsigned char h_cbSymOffset[4]; - unsigned char h_ioptMax[4]; - unsigned char h_cbOptOffset[4]; - unsigned char h_iauxMax[4]; - unsigned char h_cbAuxOffset[4]; - unsigned char h_issMax[4]; - unsigned char h_cbSsOffset[4]; - unsigned char h_issExtMax[4]; - unsigned char h_cbSsExtOffset[4]; - unsigned char h_ifdMax[4]; - unsigned char h_cbFdOffset[4]; - unsigned char h_crfd[4]; - unsigned char h_cbRfdOffset[4]; - unsigned char h_iextMax[4]; - unsigned char h_cbExtOffset[4]; -}; - -/* File descriptor external record */ - -struct fdr_ext { - unsigned char f_adr[4]; - unsigned char f_rss[4]; - unsigned char f_issBase[4]; - unsigned char f_cbSs[4]; - unsigned char f_isymBase[4]; - unsigned char f_csym[4]; - unsigned char f_ilineBase[4]; - unsigned char f_cline[4]; - unsigned char f_ioptBase[4]; - unsigned char f_copt[4]; - unsigned char f_ipdFirst[2]; - unsigned char f_cpd[2]; - unsigned char f_iauxBase[4]; - unsigned char f_caux[4]; - unsigned char f_rfdBase[4]; - unsigned char f_crfd[4]; - unsigned char f_bits1[1]; - unsigned char f_bits2[3]; - unsigned char f_cbLineOffset[4]; - unsigned char f_cbLine[4]; -}; - -#define FDR_BITS1_LANG_BIG 0xF8 -#define FDR_BITS1_LANG_SH_BIG 3 -#define FDR_BITS1_LANG_LITTLE 0x1F -#define FDR_BITS1_LANG_SH_LITTLE 0 - -#define FDR_BITS1_FMERGE_BIG 0x04 -#define FDR_BITS1_FMERGE_LITTLE 0x20 - -#define FDR_BITS1_FREADIN_BIG 0x02 -#define FDR_BITS1_FREADIN_LITTLE 0x40 - -#define FDR_BITS1_FBIGENDIAN_BIG 0x01 -#define FDR_BITS1_FBIGENDIAN_LITTLE 0x80 - -#define FDR_BITS2_GLEVEL_BIG 0xC0 -#define FDR_BITS2_GLEVEL_SH_BIG 6 -#define FDR_BITS2_GLEVEL_LITTLE 0x03 -#define FDR_BITS2_GLEVEL_SH_LITTLE 0 - -/* We ignore the `reserved' field in bits2. */ - -/* Procedure descriptor external record */ - -struct pdr_ext { - unsigned char p_adr[4]; - unsigned char p_isym[4]; - unsigned char p_iline[4]; - unsigned char p_regmask[4]; - unsigned char p_regoffset[4]; - unsigned char p_iopt[4]; - unsigned char p_fregmask[4]; - unsigned char p_fregoffset[4]; - unsigned char p_frameoffset[4]; - unsigned char p_framereg[2]; - unsigned char p_pcreg[2]; - unsigned char p_lnLow[4]; - unsigned char p_lnHigh[4]; - unsigned char p_cbLineOffset[4]; -}; - -/* Runtime procedure table */ - -struct rpdr_ext { - unsigned char p_adr[4]; - unsigned char p_regmask[4]; - unsigned char p_regoffset[4]; - unsigned char p_fregmask[4]; - unsigned char p_fregoffset[4]; - unsigned char p_frameoffset[4]; - unsigned char p_framereg[2]; - unsigned char p_pcreg[2]; - unsigned char p_irpss[4]; - unsigned char p_reserved[4]; - unsigned char p_exception_info[4]; -}; - -/* Line numbers */ - -struct line_ext { - unsigned char l_line[4]; -}; - -/* Symbol external record */ - -struct sym_ext { - unsigned char s_iss[4]; - unsigned char s_value[4]; - unsigned char s_bits1[1]; - unsigned char s_bits2[1]; - unsigned char s_bits3[1]; - unsigned char s_bits4[1]; -}; - -#define SYM_BITS1_ST_BIG 0xFC -#define SYM_BITS1_ST_SH_BIG 2 -#define SYM_BITS1_ST_LITTLE 0x3F -#define SYM_BITS1_ST_SH_LITTLE 0 - -#define SYM_BITS1_SC_BIG 0x03 -#define SYM_BITS1_SC_SH_LEFT_BIG 3 -#define SYM_BITS1_SC_LITTLE 0xC0 -#define SYM_BITS1_SC_SH_LITTLE 6 - -#define SYM_BITS2_SC_BIG 0xE0 -#define SYM_BITS2_SC_SH_BIG 5 -#define SYM_BITS2_SC_LITTLE 0x07 -#define SYM_BITS2_SC_SH_LEFT_LITTLE 2 - -#define SYM_BITS2_RESERVED_BIG 0x10 -#define SYM_BITS2_RESERVED_LITTLE 0x08 - -#define SYM_BITS2_INDEX_BIG 0x0F -#define SYM_BITS2_INDEX_SH_LEFT_BIG 16 -#define SYM_BITS2_INDEX_LITTLE 0xF0 -#define SYM_BITS2_INDEX_SH_LITTLE 4 - -#define SYM_BITS3_INDEX_SH_LEFT_BIG 8 -#define SYM_BITS3_INDEX_SH_LEFT_LITTLE 4 - -#define SYM_BITS4_INDEX_SH_LEFT_BIG 0 -#define SYM_BITS4_INDEX_SH_LEFT_LITTLE 12 - -/* External symbol external record */ - -struct ext_ext { - unsigned char es_bits1[1]; - unsigned char es_bits2[1]; - unsigned char es_ifd[2]; - struct sym_ext es_asym; -}; - -#define EXT_BITS1_JMPTBL_BIG 0x80 -#define EXT_BITS1_JMPTBL_LITTLE 0x01 - -#define EXT_BITS1_COBOL_MAIN_BIG 0x40 -#define EXT_BITS1_COBOL_MAIN_LITTLE 0x02 - -#define EXT_BITS1_WEAKEXT_BIG 0x20 -#define EXT_BITS1_WEAKEXT_LITTLE 0x04 - -/* Dense numbers external record */ - -struct dnr_ext { - unsigned char d_rfd[4]; - unsigned char d_index[4]; -}; - -/* Relative file descriptor */ - -struct rfd_ext { - unsigned char rfd[4]; -}; - -/* Optimizer symbol external record */ - -struct opt_ext { - unsigned char o_bits1[1]; - unsigned char o_bits2[1]; - unsigned char o_bits3[1]; - unsigned char o_bits4[1]; - struct rndx_ext o_rndx; - unsigned char o_offset[4]; -}; - -#define OPT_BITS2_VALUE_SH_LEFT_BIG 16 -#define OPT_BITS2_VALUE_SH_LEFT_LITTLE 0 - -#define OPT_BITS3_VALUE_SH_LEFT_BIG 8 -#define OPT_BITS3_VALUE_SH_LEFT_LITTLE 8 - -#define OPT_BITS4_VALUE_SH_LEFT_BIG 0 -#define OPT_BITS4_VALUE_SH_LEFT_LITTLE 16 diff --git a/contrib/gdb/include/coff/pe.h b/contrib/gdb/include/coff/pe.h deleted file mode 100644 index f13b8b979ea..00000000000 --- a/contrib/gdb/include/coff/pe.h +++ /dev/null @@ -1,161 +0,0 @@ -/* PE COFF header information */ - -#ifndef _PE_H -#define _PE_H - -/* NT specific file attributes */ -#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 -#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 -#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 -#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 -#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 -#define IMAGE_FILE_32BIT_MACHINE 0x0100 -#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 -#define IMAGE_FILE_SYSTEM 0x1000 -#define IMAGE_FILE_DLL 0x2000 -#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 - -/* additional flags to be set for section headers to allow the NT loader to - read and write to the section data (to replace the addresses of data in - dlls for one thing); also to execute the section in .text's case */ -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 -#define IMAGE_SCN_MEM_READ 0x40000000 -#define IMAGE_SCN_MEM_WRITE 0x80000000 - -/* - * Section characteristics added for ppc-nt - */ - -#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */ - -#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */ -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */ -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */ - -#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */ -#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */ -#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */ -#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */ - -#define IMAGE_SCN_MEM_FARDATA 0x00008000 - -#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 -#define IMAGE_SCN_MEM_16BIT 0x00020000 -#define IMAGE_SCN_MEM_LOCKED 0x00040000 -#define IMAGE_SCN_MEM_PRELOAD 0x00080000 - -#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 -#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 -#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 -#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 -#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */ -#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 -#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 - - -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */ -#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */ -#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */ -#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */ - - -/* Magic values that are true for all dos/nt implementations */ -#define DOSMAGIC 0x5a4d -#define NT_SIGNATURE 0x00004550 - - /* NT allows long filenames, we want to accommodate this. This may break - some of the bfd functions */ -#undef FILNMLEN -#define FILNMLEN 18 /* # characters in a file name */ - - -#ifdef COFF_IMAGE_WITH_PE -/* The filehdr is only weired in images */ - -#undef FILHDR -struct external_PE_filehdr -{ - /* DOS header fields */ - char e_magic[2]; /* Magic number, 0x5a4d */ - char e_cblp[2]; /* Bytes on last page of file, 0x90 */ - char e_cp[2]; /* Pages in file, 0x3 */ - char e_crlc[2]; /* Relocations, 0x0 */ - char e_cparhdr[2]; /* Size of header in paragraphs, 0x4 */ - char e_minalloc[2]; /* Minimum extra paragraphs needed, 0x0 */ - char e_maxalloc[2]; /* Maximum extra paragraphs needed, 0xFFFF */ - char e_ss[2]; /* Initial (relative) SS value, 0x0 */ - char e_sp[2]; /* Initial SP value, 0xb8 */ - char e_csum[2]; /* Checksum, 0x0 */ - char e_ip[2]; /* Initial IP value, 0x0 */ - char e_cs[2]; /* Initial (relative) CS value, 0x0 */ - char e_lfarlc[2]; /* File address of relocation table, 0x40 */ - char e_ovno[2]; /* Overlay number, 0x0 */ - char e_res[4][2]; /* Reserved words, all 0x0 */ - char e_oemid[2]; /* OEM identifier (for e_oeminfo), 0x0 */ - char e_oeminfo[2]; /* OEM information; e_oemid specific, 0x0 */ - char e_res2[10][2]; /* Reserved words, all 0x0 */ - char e_lfanew[4]; /* File address of new exe header, 0x80 */ - char dos_message[16][4]; /* other stuff, always follow DOS header */ - char nt_signature[4]; /* required NT signature, 0x4550 */ - - /* From standard header */ - - - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ - -}; - - -#define FILHDR struct external_PE_filehdr - - -#endif - -typedef struct -{ - AOUTHDR standard; - - /* NT extra fields; see internal.h for descriptions */ - char ImageBase[4]; - char SectionAlignment[4]; - char FileAlignment[4]; - char MajorOperatingSystemVersion[2]; - char MinorOperatingSystemVersion[2]; - char MajorImageVersion[2]; - char MinorImageVersion[2]; - char MajorSubsystemVersion[2]; - char MinorSubsystemVersion[2]; - char Reserved1[4]; - char SizeOfImage[4]; - char SizeOfHeaders[4]; - char CheckSum[4]; - char Subsystem[2]; - char DllCharacteristics[2]; - char SizeOfStackReserve[4]; - char SizeOfStackCommit[4]; - char SizeOfHeapReserve[4]; - char SizeOfHeapCommit[4]; - char LoaderFlags[4]; - char NumberOfRvaAndSizes[4]; - /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */ - char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */ - -} PEAOUTHDR; - - -#undef AOUTSZ -#define AOUTSZ sizeof(PEAOUTHDR) - -#undef E_FILNMLEN -#define E_FILNMLEN 18 /* # characters in a file name */ -#endif - - - diff --git a/contrib/gdb/include/coff/powerpc.h b/contrib/gdb/include/coff/powerpc.h deleted file mode 100644 index 6866fc8a0dc..00000000000 --- a/contrib/gdb/include/coff/powerpc.h +++ /dev/null @@ -1,196 +0,0 @@ -/* Basic coff information for the PowerPC - * - * Based on coff/rs6000.h, coff/i386.h and others. - * - * Initial release: Kim Knuttila (krk@cygnus.com) - */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - -/* Bits for f_flags: - * F_RELFLG relocation info stripped from file - * F_EXEC file is executable (no unresolved external references) - * F_LNNO line numbers stripped from file - * F_LSYMS local symbols stripped from file - * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax) - */ - -#define F_RELFLG (0x0001) -#define F_EXEC (0x0002) -#define F_LNNO (0x0004) -#define F_LSYMS (0x0008) - -/* extra NT defines */ -#define PPCMAGIC 0760 /* peeked on aa PowerPC Windows NT box */ -#define DOSMAGIC 0x5a4d /* from arm.h, i386.h */ -#define NT_SIGNATURE 0x00004550 /* from arm.h, i386.h */ - -/* from winnt.h */ -#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b - -#define PPCBADMAG(x) ((x).f_magic != PPCMAGIC) - -/********************** AOUT "OPTIONAL HEADER" **********************/ - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - -#define AOUTSZ (sizeof(AOUTHDR)) - - -/********************** SECTION HEADER **********************/ - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries */ - char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _COMMENT ".comment" -#define _LIB ".lib" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0 */ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - -#define LINENO struct external_lineno -#define LINESZ 6 - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ - -/* Allow the file name length to be overridden in the including file */ -#ifndef E_FILNMLEN -#define E_FILNMLEN 14 -#endif - -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 - -#define N_BTMASK (0xf) -#define N_TMASK (0x30) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; -}; - -#define AUXENT union external_auxent -#define AUXESZ 18 - -#define _ETEXT "etext" - -/********************** RELOCATION DIRECTIVES **********************/ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; -}; - -#define RELOC struct external_reloc -#define RELSZ 10 - diff --git a/contrib/gdb/include/coff/rs6000.h b/contrib/gdb/include/coff/rs6000.h deleted file mode 100644 index 62a6f86cc7c..00000000000 --- a/contrib/gdb/include/coff/rs6000.h +++ /dev/null @@ -1,242 +0,0 @@ -/* IBM RS/6000 "XCOFF" file definitions for BFD. - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM - and John Gilmore of Cygnus Support. */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - /* IBM RS/6000 */ -#define U802WRMAGIC 0730 /* writeable text segments **chh** */ -#define U802ROMAGIC 0735 /* readonly sharable text segments */ -#define U802TOCMAGIC 0737 /* readonly text segments and TOC */ - -#define BADMAG(x) \ - ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \ - (x).f_magic != U802TOCMAGIC) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - unsigned char magic[2]; /* type of file */ - unsigned char vstamp[2]; /* version stamp */ - unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */ - unsigned char dsize[4]; /* initialized data " " */ - unsigned char bsize[4]; /* uninitialized data " " */ - unsigned char entry[4]; /* entry pt. */ - unsigned char text_start[4]; /* base of text used for this file */ - unsigned char data_start[4]; /* base of data used for this file */ - unsigned char o_toc[4]; /* address of TOC */ - unsigned char o_snentry[2]; /* section number of entry point */ - unsigned char o_sntext[2]; /* section number of .text section */ - unsigned char o_sndata[2]; /* section number of .data section */ - unsigned char o_sntoc[2]; /* section number of TOC */ - unsigned char o_snloader[2]; /* section number of .loader section */ - unsigned char o_snbss[2]; /* section number of .bss section */ - unsigned char o_algntext[2]; /* .text alignment */ - unsigned char o_algndata[2]; /* .data alignment */ - unsigned char o_modtype[2]; /* module type (??) */ - unsigned char o_cputype[2]; /* cpu type */ - unsigned char o_maxstack[4]; /* max stack size (??) */ - unsigned char o_maxdata[4]; /* max data size (??) */ - unsigned char o_resv2[12]; /* reserved */ -} -AOUTHDR; - -#define AOUTSZ (sizeof(AOUTHDR)) -#define SMALL_AOUTSZ (28) - -#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */ -#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */ -#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */ - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _PAD ".pad" -#define _LOADER ".loader" - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* XCOFF uses a special .loader section with type STYP_LOADER. */ -#define STYP_LOADER 0x1000 - -/* XCOFF uses a special .debug section with type STYP_DEBUG. */ -#define STYP_DEBUG 0x2000 - -/* XCOFF handles line number or relocation overflow by creating - another section header with STYP_OVRFLO set. */ -#define STYP_OVRFLO 0x8000 - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - struct { - unsigned char x_scnlen[4]; - unsigned char x_parmhash[4]; - unsigned char x_snhash[2]; - unsigned char x_smtyp[1]; - unsigned char x_smclas[1]; - unsigned char x_stab[4]; - unsigned char x_snstab[2]; - } x_csect; - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 -#define DBXMASK 0x80 /* for dbx storage mask */ -#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK) - - - -/********************** RELOCATION DIRECTIVES **********************/ - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_size[1]; - char r_type[1]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 10 - -#define DEFAULT_DATA_SECTION_ALIGNMENT 4 -#define DEFAULT_BSS_SECTION_ALIGNMENT 4 -#define DEFAULT_TEXT_SECTION_ALIGNMENT 4 -/* For new sections we havn't heard of before */ -#define DEFAULT_SECTION_ALIGNMENT 4 diff --git a/contrib/gdb/include/coff/sh.h b/contrib/gdb/include/coff/sh.h deleted file mode 100644 index af49674a9ee..00000000000 --- a/contrib/gdb/include/coff/sh.h +++ /dev/null @@ -1,253 +0,0 @@ -/*** coff information for Hitachi SH */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - - -#define SH_ARCH_MAGIC_BIG 0x0500 -#define SH_ARCH_MAGIC_LITTLE 0x0550 /* Little endian SH */ - - -#define SHBADMAG(x) \ - (((x).f_magic!=SH_ARCH_MAGIC_BIG) && \ - ((x).f_magic!=SH_ARCH_MAGIC_LITTLE)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - - -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) - - - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" - - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[4]; /* line number */ -}; - -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno)); -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - - -/********************** RELOCATION DIRECTIVES **********************/ - -/* The external reloc has an offset field, because some of the reloc - types on the h8 don't have room in the instruction for the entire - offset - eg the strange jump and high page addressing modes */ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_offset[4]; - char r_type[2]; - char r_stuff[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 16 - -/* SH relocation types. Not all of these are actually used. */ - -#define R_SH_UNUSED 0 /* only used internally */ -#define R_SH_PCREL8 3 /* 8 bit pcrel */ -#define R_SH_PCREL16 4 /* 16 bit pcrel */ -#define R_SH_HIGH8 5 /* high 8 bits of 24 bit address */ -#define R_SH_LOW16 7 /* low 16 bits of 24 bit immediate */ -#define R_SH_IMM24 6 /* 24 bit immediate */ -#define R_SH_PCDISP8BY4 9 /* PC rel 8 bits *4 +ve */ -#define R_SH_PCDISP8BY2 10 /* PC rel 8 bits *2 +ve */ -#define R_SH_PCDISP8 11 /* 8 bit branch */ -#define R_SH_PCDISP 12 /* 12 bit branch */ -#define R_SH_IMM32 14 /* 32 bit immediate */ -#define R_SH_IMM8 16 /* 8 bit immediate */ -#define R_SH_IMM8BY2 17 /* 8 bit immediate *2 */ -#define R_SH_IMM8BY4 18 /* 8 bit immediate *4 */ -#define R_SH_IMM4 19 /* 4 bit immediate */ -#define R_SH_IMM4BY2 20 /* 4 bit immediate *2 */ -#define R_SH_IMM4BY4 21 /* 4 bit immediate *4 */ -#define R_SH_PCRELIMM8BY2 22 /* PC rel 8 bits *2 unsigned */ -#define R_SH_PCRELIMM8BY4 23 /* PC rel 8 bits *4 unsigned */ -#define R_SH_IMM16 24 /* 16 bit immediate */ - -/* The switch table reloc types are used for relaxing. They are - generated for expressions such as - .word L1 - L2 - The r_offset field holds the difference between the reloc address - and L2. */ -#define R_SH_SWITCH16 25 /* 16 bit switch table entry */ -#define R_SH_SWITCH32 26 /* 16 bit switch table entry */ - -/* The USES reloc type is used for relaxing. The compiler will - generate .uses pseudo-ops when it finds a function call which it - can relax. The r_offset field of the USES reloc holds the PC - relative offset to the instruction which loads the register used in - the function call. */ -#define R_SH_USES 27 /* .uses pseudo-op */ - -/* The COUNT reloc type is used for relaxing. The assembler will - generate COUNT relocs for addresses referred to by the register - loads associated with USES relocs. The r_offset field of the COUNT - reloc holds the number of times the address is references in the - object file. */ -#define R_SH_COUNT 28 /* Count of constant pool uses */ - -/* The ALIGN reloc type is used for relaxing. The r_offset field is - the power of two to which subsequent portions of the object file - must be aligned. */ -#define R_SH_ALIGN 29 /* .align pseudo-op */ - - - diff --git a/contrib/gdb/include/coff/sparc.h b/contrib/gdb/include/coff/sparc.h deleted file mode 100644 index 0e3217b25f1..00000000000 --- a/contrib/gdb/include/coff/sparc.h +++ /dev/null @@ -1,209 +0,0 @@ -/*** coff information for Sparc. */ - -/* This file is an amalgamation of several standard include files that - define coff format, such as filehdr.h, aouthdr.h, and so forth. In - addition, all datatypes have been translated into character arrays of - (presumed) equivalent size. This is necessary so that this file can - be used with different systems while still yielding the same results. */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr -{ - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - -#define F_RELFLG (0x0001) /* relocation info stripped */ -#define F_EXEC (0x0002) /* file is executable */ -#define F_LNNO (0x0004) /* line numbers stripped */ -#define F_LSYMS (0x0008) /* local symbols stripped */ - -#define SPARCMAGIC (0540) - -/* This is Lynx's all-platform magic number for executables. */ - -#define LYNXCOFFMAGIC (0415) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - -/********************** AOUT "OPTIONAL HEADER" **********************/ - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - -#define AOUTSZ (sizeof(AOUTHDR)) - -#define OMAGIC 0404 /* object files, eg as output */ -#define ZMAGIC 0413 /* demand load format, eg normal ld output */ -#define STMAGIC 0401 /* target shlib */ -#define SHMAGIC 0443 /* host shlib */ - -/********************** SECTION HEADER **********************/ - -struct external_scnhdr -{ - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* Names of "special" sections. */ - -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _TV ".tv" -#define _INIT ".init" -#define _FINI ".fini" -#define _COMMENT ".comment" -#define _LIB ".lib" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - Line numbers are grouped on a per function basis; first entry in a function - grouping will have l_lnno = 0 and in place of physical address will be the - symbol table index of the function name. */ - -struct external_lineno -{ - union { - char l_symndx[4]; /* fn name symbol index, iff l_lnno == 0 */ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - -#define LINENO struct external_lineno -#define LINESZ (6) - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN (8) /* # characters in a symbol name */ -#define E_FILNMLEN (14) /* # characters in a file name */ -#define E_DIMNUM (4) /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; -#if 0 /* of doubtful value */ - char e_nptr[2][4]; - struct { - char e_leading_zero[1]; - char e_dbx_type[1]; - char e_dbx_desc[2]; - } e_dbx; -#endif - } e; - - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; - char padding[2]; -}; - -#define N_BTMASK (0xf) -#define N_TMASK (0x30) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -union external_auxent -{ - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* .tv section info (in auxent of sym .tv)) */ - - char x_fill[20]; /* forces to 20-byte size */ -}; - -#define SYMENT struct external_syment -#define SYMESZ 20 -#define AUXENT union external_auxent -#define AUXESZ 20 - -#define _ETEXT "etext" - -/********************** RELOCATION DIRECTIVES **********************/ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; - char r_spare[2]; - char r_offset[4]; -}; - -#define RELOC struct external_reloc -#define RELSZ sizeof (RELOC) - diff --git a/contrib/gdb/include/coff/sym.h b/contrib/gdb/include/coff/sym.h deleted file mode 100644 index 76204af59ad..00000000000 --- a/contrib/gdb/include/coff/sym.h +++ /dev/null @@ -1,484 +0,0 @@ -/* Declarations of internal format of MIPS ECOFF symbols. - Originally contributed by MIPS Computer Systems and Third Eye Software. - Changes contributed by Cygnus Support are in the public domain. - - This file is just aggregated with the files that make up the GNU - release; it is not considered part of GAS, GDB, or other GNU - programs. */ - -/* - * |-----------------------------------------------------------| - * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.| - * | MIPS Computer Systems, Inc. grants reproduction and use | - * | rights to all parties, PROVIDED that this comment is | - * | maintained in the copy. | - * |-----------------------------------------------------------| - */ -#ifndef _SYM_H -#define _SYM_H - -/* (C) Copyright 1984 by Third Eye Software, Inc. - * - * Third Eye Software, Inc. grants reproduction and use rights to - * all parties, PROVIDED that this comment is maintained in the copy. - * - * Third Eye makes no claims about the applicability of this - * symbol table to a particular use. - */ - -/* - * This file contains the definition of the Third Eye Symbol Table. - * - * Symbols are assumed to be in 'encounter order' - i.e. the order that - * the things they represent were encountered by the compiler/assembler/loader. - * EXCEPT for globals! These are assumed to be bunched together, - * probably right after the last 'normal' symbol. Globals ARE sorted - * in ascending order. - * - * ----------------------------------------------------------------------- - * A brief word about Third Eye naming/use conventions: - * - * All arrays and index's are 0 based. - * All "ifooMax" values are the highest legal value PLUS ONE. This makes - * them good for allocating arrays, etc. All checks are "ifoo < ifooMax". - * - * "isym" Index into the SYMbol table. - * "ipd" Index into the Procedure Descriptor array. - * "ifd" Index into the File Descriptor array. - * "iss" Index into String Space. - * "cb" Count of Bytes. - * "rgPd" array whose domain is "0..ipdMax-1" and RanGe is PDR. - * "rgFd" array whose domain is "0..ifdMax-1" and RanGe is FDR. - */ - - -/* - * Symbolic Header (HDR) structure. - * As long as all the pointers are set correctly, - * we don't care WHAT order the various sections come out in! - * - * A file produced solely for the use of CDB will probably NOT have - * any instructions or data areas in it, as these are available - * in the original. - */ - -typedef struct { - short magic; /* to verify validity of the table */ - short vstamp; /* version stamp */ - long ilineMax; /* number of line number entries */ - bfd_vma cbLine; /* number of bytes for line number entries */ - bfd_vma cbLineOffset; /* offset to start of line number entries*/ - long idnMax; /* max index into dense number table */ - bfd_vma cbDnOffset; /* offset to start dense number table */ - long ipdMax; /* number of procedures */ - bfd_vma cbPdOffset; /* offset to procedure descriptor table */ - long isymMax; /* number of local symbols */ - bfd_vma cbSymOffset; /* offset to start of local symbols*/ - long ioptMax; /* max index into optimization symbol entries */ - bfd_vma cbOptOffset; /* offset to optimization symbol entries */ - long iauxMax; /* number of auxillary symbol entries */ - bfd_vma cbAuxOffset; /* offset to start of auxillary symbol entries*/ - long issMax; /* max index into local strings */ - bfd_vma cbSsOffset; /* offset to start of local strings */ - long issExtMax; /* max index into external strings */ - bfd_vma cbSsExtOffset; /* offset to start of external strings */ - long ifdMax; /* number of file descriptor entries */ - bfd_vma cbFdOffset; /* offset to file descriptor table */ - long crfd; /* number of relative file descriptor entries */ - bfd_vma cbRfdOffset; /* offset to relative file descriptor table */ - long iextMax; /* max index into external symbols */ - bfd_vma cbExtOffset; /* offset to start of external symbol entries*/ - /* If you add machine dependent fields, add them here */ - } HDRR, *pHDRR; -#define cbHDRR sizeof(HDRR) -#define hdrNil ((pHDRR)0) - -/* - * The FDR and PDR structures speed mapping of address <-> name. - * They are sorted in ascending memory order and are kept in - * memory by CDB at runtime. - */ - -/* - * File Descriptor - * - * There is one of these for EVERY FILE, whether compiled with - * full debugging symbols or not. The name of a file should be - * the path name given to the compiler. This allows the user - * to simply specify the names of the directories where the COMPILES - * were done, and we will be able to find their files. - * A field whose comment starts with "R - " indicates that it will be - * setup at runtime. - */ -typedef struct fdr { - bfd_vma adr; /* memory address of beginning of file */ - long rss; /* file name (of source, if known) */ - long issBase; /* file's string space */ - bfd_vma cbSs; /* number of bytes in the ss */ - long isymBase; /* beginning of symbols */ - long csym; /* count file's of symbols */ - long ilineBase; /* file's line symbols */ - long cline; /* count of file's line symbols */ - long ioptBase; /* file's optimization entries */ - long copt; /* count of file's optimization entries */ - unsigned short ipdFirst;/* start of procedures for this file */ - short cpd; /* count of procedures for this file */ - long iauxBase; /* file's auxiliary entries */ - long caux; /* count of file's auxiliary entries */ - long rfdBase; /* index into the file indirect table */ - long crfd; /* count file indirect entries */ - unsigned lang: 5; /* language for this file */ - unsigned fMerge : 1; /* whether this file can be merged */ - unsigned fReadin : 1; /* true if it was read in (not just created) */ - unsigned fBigendian : 1;/* if set, was compiled on big endian machine */ - /* aux's will be in compile host's sex */ - unsigned glevel : 2; /* level this file was compiled with */ - unsigned reserved : 22; /* reserved for future use */ - bfd_vma cbLineOffset; /* byte offset from header for this file ln's */ - bfd_vma cbLine; /* size of lines for this file */ - } FDR, *pFDR; -#define cbFDR sizeof(FDR) -#define fdNil ((pFDR)0) -#define ifdNil -1 -#define ifdTemp 0 -#define ilnNil -1 - - -/* - * Procedure Descriptor - * - * There is one of these for EVERY TEXT LABEL. - * If a procedure is in a file with full symbols, then isym - * will point to the PROC symbols, else it will point to the - * global symbol for the label. - */ - -typedef struct pdr { - bfd_vma adr; /* memory address of start of procedure */ - long isym; /* start of local symbol entries */ - long iline; /* start of line number entries*/ - long regmask; /* save register mask */ - long regoffset; /* save register offset */ - long iopt; /* start of optimization symbol entries*/ - long fregmask; /* save floating point register mask */ - long fregoffset; /* save floating point register offset */ - long frameoffset; /* frame size */ - short framereg; /* frame pointer register */ - short pcreg; /* offset or reg of return pc */ - long lnLow; /* lowest line in the procedure */ - long lnHigh; /* highest line in the procedure */ - bfd_vma cbLineOffset; /* byte offset for this procedure from the fd base */ - /* These fields are new for 64 bit ECOFF. */ - unsigned gp_prologue : 8; /* byte size of GP prologue */ - unsigned gp_used : 1; /* true if the procedure uses GP */ - unsigned reg_frame : 1; /* true if register frame procedure */ - unsigned prof : 1; /* true if compiled with -pg */ - unsigned reserved : 13; /* reserved: must be zero */ - unsigned localoff : 8; /* offset of local variables from vfp */ - } PDR, *pPDR; -#define cbPDR sizeof(PDR) -#define pdNil ((pPDR) 0) -#define ipdNil -1 - -/* - * The structure of the runtime procedure descriptor created by the loader - * for use by the static exception system. - */ -/* - * If 0'd out because exception_info chokes Visual C++ and because there - * don't seem to be any references to this structure elsewhere in gdb. - */ -#if 0 -typedef struct runtime_pdr { - bfd_vma adr; /* memory address of start of procedure */ - long regmask; /* save register mask */ - long regoffset; /* save register offset */ - long fregmask; /* save floating point register mask */ - long fregoffset; /* save floating point register offset */ - long frameoffset; /* frame size */ - short framereg; /* frame pointer register */ - short pcreg; /* offset or reg of return pc */ - long irpss; /* index into the runtime string table */ - long reserved; - struct exception_info *exception_info;/* pointer to exception array */ -} RPDR, *pRPDR; -#define cbRPDR sizeof(RPDR) -#define rpdNil ((pRPDR) 0) -#endif - -/* - * Line Numbers - * - * Line Numbers are segregated from the normal symbols because they - * are [1] smaller , [2] are of no interest to your - * average loader, and [3] are never needed in the middle of normal - * scanning and therefore slow things down. - * - * By definition, the first LINER for any given procedure will have - * the first line of a procedure and represent the first address. - */ - -typedef long LINER, *pLINER; -#define lineNil ((pLINER)0) -#define cbLINER sizeof(LINER) -#define ilineNil -1 - - - -/* - * The Symbol Structure (GFW, to those who Know!) - */ - -typedef struct { - long iss; /* index into String Space of name */ - bfd_vma value; /* value of symbol */ - unsigned st : 6; /* symbol type */ - unsigned sc : 5; /* storage class - text, data, etc */ - unsigned reserved : 1; /* reserved */ - unsigned index : 20; /* index into sym/aux table */ - } SYMR, *pSYMR; -#define symNil ((pSYMR)0) -#define cbSYMR sizeof(SYMR) -#define isymNil -1 -#define indexNil 0xfffff -#define issNil -1 -#define issNull 0 - - -/* The following converts a memory resident string to an iss. - * This hack is recognized in SbFIss, in sym.c of the debugger. - */ -#define IssFSb(sb) (0x80000000 | ((unsigned long)(sb))) - -/* E X T E R N A L S Y M B O L R E C O R D - * - * Same as the SYMR except it contains file context to determine where - * the index is. - */ -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 */ - unsigned reserved:13; /* reserved for future use */ - int ifd; /* where the iss and index fields point into */ - SYMR asym; /* symbol for the external */ - } EXTR, *pEXTR; -#define extNil ((pEXTR)0) -#define cbEXTR sizeof(EXTR) - - -/* A U X I L L A R Y T Y P E I N F O R M A T I O N */ - -/* - * Type Information Record - */ -typedef struct { - unsigned fBitfield : 1; /* set if bit width is specified */ - unsigned continued : 1; /* indicates additional TQ info in next AUX */ - unsigned bt : 6; /* basic type */ - unsigned tq4 : 4; - unsigned tq5 : 4; - /* ---- 16 bit boundary ---- */ - unsigned tq0 : 4; - unsigned tq1 : 4; /* 6 type qualifiers - tqPtr, etc. */ - unsigned tq2 : 4; - unsigned tq3 : 4; - } TIR, *pTIR; -#define cbTIR sizeof(TIR) -#define tiNil ((pTIR)0) -#define itqMax 6 - -/* - * Relative symbol record - * - * If the rfd field is 4095, the index field indexes into the global symbol - * table. - */ - -typedef struct { - unsigned rfd : 12; /* index into the file indirect table */ - unsigned index : 20; /* index int sym/aux/iss tables */ - } RNDXR, *pRNDXR; -#define cbRNDXR sizeof(RNDXR) -#define rndxNil ((pRNDXR)0) - -/* dense numbers or sometimes called block numbers are stored in this type, - * a rfd of 0xffffffff is an index into the global table. - */ -typedef struct { - unsigned long rfd; /* index into the file table */ - unsigned long index; /* index int sym/aux/iss tables */ - } DNR, *pDNR; -#define cbDNR sizeof(DNR) -#define dnNil ((pDNR)0) - - - -/* - * Auxillary information occurs only if needed. - * It ALWAYS occurs in this order when present. - - isymMac used by stProc only - TIR type info - TIR additional TQ info (if first TIR was not enough) - rndx if (bt == btStruct,btUnion,btEnum,btSet,btRange, - btTypedef): - rsym.index == iaux for btSet or btRange - else rsym.index == isym - dimLow btRange, btSet - dimMac btRange, btSet - rndx0 As many as there are tq arrays - dimLow0 - dimHigh0 - ... - rndxMax-1 - dimLowMax-1 - dimHighMax-1 - width in bits if (bit field), width in bits. - */ -#define cAuxMax (6 + (idimMax*3)) - -/* a union of all possible info in the AUX universe */ -typedef union { - TIR ti; /* type information record */ - RNDXR rndx; /* relative index into symbol table */ - long dnLow; /* low dimension */ - long dnHigh; /* high dimension */ - long isym; /* symbol table index (end of proc) */ - long iss; /* index into string space (not used) */ - long width; /* width for non-default sized struc fields */ - long count; /* count of ranges for variant arm */ - } AUXU, *pAUXU; -#define cbAUXU sizeof(AUXU) -#define auxNil ((pAUXU)0) -#define iauxNil -1 - - -/* - * Optimization symbols - * - * Optimization symbols contain some overlap information with the normal - * symbol table. In particular, the proc information - * is somewhat redundant but necessary to easily find the other information - * present. - * - * All of the offsets are relative to the beginning of the last otProc - */ - -typedef struct { - unsigned ot: 8; /* optimization type */ - unsigned value: 24; /* address where we are moving it to */ - RNDXR rndx; /* points to a symbol or opt entry */ - unsigned long offset; /* relative offset this occured */ - } OPTR, *pOPTR; -#define optNil ((pOPTR) 0) -#define cbOPTR sizeof(OPTR) -#define ioptNil -1 - -/* - * File Indirect - * - * When a symbol is referenced across files the following procedure is used: - * 1) use the file index to get the File indirect entry. - * 2) use the file indirect entry to get the File descriptor. - * 3) add the sym index to the base of that file's sym table - * - */ - -typedef long RFDT, *pRFDT; -#define cbRFDT sizeof(RFDT) -#define rfdNil -1 - -/* - * The file indirect table in the mips loader is known as an array of FITs. - * This is done to keep the code in the loader readable in the area where - * these tables are merged. Note this is only a name change. - */ -typedef long FIT, *pFIT; -#define cbFIT sizeof(FIT) -#define ifiNil -1 -#define fiNil ((pFIT) 0) - -#ifdef _LANGUAGE_PASCAL -#define ifdNil -1 -#define ilnNil -1 -#define ipdNil -1 -#define ilineNil -1 -#define isymNil -1 -#define indexNil 16#fffff -#define issNil -1 -#define issNull 0 -#define itqMax 6 -#define iauxNil -1 -#define ioptNil -1 -#define rfdNil -1 -#define ifiNil -1 -#endif /* _LANGUAGE_PASCAL */ - - -/* Dense numbers - * - * Rather than use file index, symbol index pairs to represent symbols - * and globals, we use dense number so that they can be easily embeded - * in intermediate code and the programs that process them can - * use direct access tabls instead of hash table (which would be - * necesary otherwise because of the sparse name space caused by - * file index, symbol index pairs. Dense number are represented - * by RNDXRs. - */ - -/* - * The following table defines the meaning of each SYM field as - * a function of the "st". (scD/B == scData OR scBss) - * - * Note: the value "isymMac" is used by symbols that have the concept - * of enclosing a block of related information. This value is the - * isym of the first symbol AFTER the end associated with the primary - * symbol. For example if a procedure was at isym==90 and had an - * isymMac==155, the associated end would be at isym==154, and the - * symbol at 155 would probably (although not necessarily) be the - * symbol for the next procedure. This allows rapid skipping over - * internal information of various sorts. "stEnd"s ALWAYS have the - * isym of the primary symbol that started the block. - * - -ST SC VALUE INDEX --------- ------ -------- ------ -stFile scText address isymMac -stLabel scText address --- -stGlobal scD/B address iaux -stStatic scD/B address iaux -stParam scAbs offset iaux -stLocal scAbs offset iaux -stProc scText address iaux (isymMac is first AUX) -stStaticProc scText address iaux (isymMac is first AUX) - -stMember scNil ordinal --- (if member of enum) - (mipsread thinks the case below has a bit, not byte, offset.) -stMember scNil byte offset iaux (if member of struct/union) -stMember scBits bit offset iaux (bit field spec) - -stBlock scText address isymMac (text block) - (the code seems to think that rather than scNil, we see scInfo for - the two cases below.) -stBlock scNil cb isymMac (struct/union member define) -stBlock scNil cMembers isymMac (enum member define) - - (New types added by SGI to simplify things:) -stStruct scInfo cb isymMac (struct type define) -stUnion scInfo cb isymMac (union type define) -stEnum scInfo cMembers isymMac (enum type define) - -stEnd scText address isymStart -stEnd scNil ------- isymStart (struct/union/enum) - -stTypedef scNil ------- iaux -stRegReloc sc??? value old register number -stForward sc??? new address isym to original symbol - -stConstant scInfo value --- (scalar) -stConstant scInfo iss --- (complex, e.g. string) - - * - */ -#endif diff --git a/contrib/gdb/include/coff/symconst.h b/contrib/gdb/include/coff/symconst.h deleted file mode 100644 index f40eef2a311..00000000000 --- a/contrib/gdb/include/coff/symconst.h +++ /dev/null @@ -1,177 +0,0 @@ -/* Declarations of constants for internal format of MIPS ECOFF symbols. - Originally contributed by MIPS Computer Systems and Third Eye Software. - Changes contributed by Cygnus Support are in the public domain. - - This file is just aggregated with the files that make up the GNU - release; it is not considered part of GAS, GDB, or other GNU - programs. */ - -/* - * |-----------------------------------------------------------| - * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.| - * | MIPS Computer Systems, Inc. grants reproduction and use | - * | rights to all parties, PROVIDED that this comment is | - * | maintained in the copy. | - * |-----------------------------------------------------------| - */ - -/* (C) Copyright 1984 by Third Eye Software, Inc. - * - * Third Eye Software, Inc. grants reproduction and use rights to - * all parties, PROVIDED that this comment is maintained in the copy. - * - * Third Eye makes no claims about the applicability of this - * symbol table to a particular use. - */ - -/* glevels for field in FDR */ -#define GLEVEL_0 2 -#define GLEVEL_1 1 -#define GLEVEL_2 0 /* for upward compat reasons. */ -#define GLEVEL_3 3 - -/* magic number fo symheader */ -#define magicSym 0x7009 -/* The Alpha uses this value instead, for some reason. */ -#define magicSym2 0x1992 - -/* Language codes */ -#define langC 0 -#define langPascal 1 -#define langFortran 2 -#define langAssembler 3 /* one Assembley inst might map to many mach */ -#define langMachine 4 -#define langNil 5 -#define langAda 6 -#define langPl1 7 -#define langCobol 8 -#define langStdc 9 /* FIXME: Collides with SGI langCplusplus */ -#define langCplusplus 9 /* FIXME: Collides with langStdc */ -#define langCplusplusV2 10 /* SGI addition */ -#define langMax 11 /* maximun allowed 32 -- 5 bits */ - -/* The following are value definitions for the fields in the SYMR */ - -/* - * Storage Classes - */ - -#define scNil 0 -#define scText 1 /* text symbol */ -#define scData 2 /* initialized data symbol */ -#define scBss 3 /* un-initialized data symbol */ -#define scRegister 4 /* value of symbol is register number */ -#define scAbs 5 /* value of symbol is absolute */ -#define scUndefined 6 /* who knows? */ -#define scCdbLocal 7 /* variable's value is IN se->va.?? */ -#define scBits 8 /* this is a bit field */ -#define scCdbSystem 9 /* variable's value is IN CDB's address space */ -#define scDbx 9 /* overlap dbx internal use */ -#define scRegImage 10 /* register value saved on stack */ -#define scInfo 11 /* symbol contains debugger information */ -#define scUserStruct 12 /* address in struct user for current process */ -#define scSData 13 /* load time only small data */ -#define scSBss 14 /* load time only small common */ -#define scRData 15 /* load time only read only data */ -#define scVar 16 /* Var parameter (fortran,pascal) */ -#define scCommon 17 /* common variable */ -#define scSCommon 18 /* small common */ -#define scVarRegister 19 /* Var parameter in a register */ -#define scVariant 20 /* Variant record */ -#define scSUndefined 21 /* small undefined(external) data */ -#define scInit 22 /* .init section symbol */ -#define scBasedVar 23 /* Fortran or PL/1 ptr based var */ -#define scXData 24 /* exception handling data */ -#define scPData 25 /* Procedure section */ -#define scFini 26 /* .fini section */ -#define scRConst 27 /* .rconst section */ -#define scMax 32 - - -/* - * Symbol Types - */ - -#define stNil 0 /* Nuthin' special */ -#define stGlobal 1 /* external symbol */ -#define stStatic 2 /* static */ -#define stParam 3 /* procedure argument */ -#define stLocal 4 /* local variable */ -#define stLabel 5 /* label */ -#define stProc 6 /* " " Procedure */ -#define stBlock 7 /* beginnning of block */ -#define stEnd 8 /* end (of anything) */ -#define stMember 9 /* member (of anything - struct/union/enum */ -#define stTypedef 10 /* type definition */ -#define stFile 11 /* file name */ -#define stRegReloc 12 /* register relocation */ -#define stForward 13 /* forwarding address */ -#define stStaticProc 14 /* load time only static procs */ -#define stConstant 15 /* const */ -#define stStaParam 16 /* Fortran static parameters */ - /* These new symbol types have been recently added to SGI machines. */ -#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 */ -#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 */ -#define stType 63 /* post-coersion SER */ -#define stMax 64 - -/* definitions for fields in TIR */ - -/* type qualifiers for ti.tq0 -> ti.(itqMax-1) */ -#define tqNil 0 /* bt is what you see */ -#define tqPtr 1 /* pointer */ -#define tqProc 2 /* procedure */ -#define tqArray 3 /* duh */ -#define tqFar 4 /* longer addressing - 8086/8 land */ -#define tqVol 5 /* volatile */ -#define tqConst 6 /* const */ -#define tqMax 8 - -/* basic types as seen in ti.bt */ -#define btNil 0 /* undefined (also, enum members) */ -#define btAdr 1 /* address - integer same size as pointer */ -#define btChar 2 /* character */ -#define btUChar 3 /* unsigned character */ -#define btShort 4 /* short */ -#define btUShort 5 /* unsigned short */ -#define btInt 6 /* int */ -#define btUInt 7 /* unsigned int */ -#define btLong 8 /* long */ -#define btULong 9 /* unsigned long */ -#define btFloat 10 /* float (real) */ -#define btDouble 11 /* Double (real) */ -#define btStruct 12 /* Structure (Record) */ -#define btUnion 13 /* Union (variant) */ -#define btEnum 14 /* Enumerated */ -#define btTypedef 15 /* defined via a typedef, isymRef points */ -#define btRange 16 /* subrange of int */ -#define btSet 17 /* pascal sets */ -#define btComplex 18 /* fortran complex */ -#define btDComplex 19 /* fortran double complex */ -#define btIndirect 20 /* forward or unnamed typedef */ -#define btFixedDec 21 /* Fixed Decimal */ -#define btFloatDec 22 /* Float Decimal */ -#define btString 23 /* Varying Length Character String */ -#define btBit 24 /* Aligned Bit String */ -#define btPicture 25 /* Picture */ -#define btVoid 26 /* void */ -#define btLongLong 27 /* long long */ -#define btULongLong 28 /* unsigned long long */ -#define btMax 64 - -#if (_MFG == _MIPS) -/* optimization type codes */ -#define otNil 0 -#define otReg 1 /* move var to reg */ -#define otBlock 2 /* begin basic block */ -#define otProc 3 /* procedure */ -#define otInline 4 /* inline procedure */ -#define otEnd 5 /* whatever you started */ -#define otMax 6 /* KEEP UP TO DATE */ -#endif /* (_MFG == _MIPS) */ diff --git a/contrib/gdb/include/coff/w65.h b/contrib/gdb/include/coff/w65.h deleted file mode 100644 index c80b9fee5de..00000000000 --- a/contrib/gdb/include/coff/w65.h +++ /dev/null @@ -1,201 +0,0 @@ -/*** coff information for WDC 65816 */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - - -#define W65MAGIC 0x6500 - - -#define W65BADMAG(x) (((x).f_magic!=W65MAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - - -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) - - - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" - - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[4]; /* line number */ -}; - -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno)); -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - - -/********************** RELOCATION DIRECTIVES **********************/ - -/* The external reloc has an offset field, because some of the reloc - types on the w65 don't have room in the instruction for the entire - offset - eg the strange jump and high page addressing modes */ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_offset[4]; - char r_type[2]; - char r_stuff[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 16 - - - - diff --git a/contrib/gdb/include/coff/we32k.h b/contrib/gdb/include/coff/we32k.h deleted file mode 100644 index 414c4506e0b..00000000000 --- a/contrib/gdb/include/coff/we32k.h +++ /dev/null @@ -1,206 +0,0 @@ -/*** coff information for we32k */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - -/* Bits for f_flags: - * F_RELFLG relocation info stripped from file - * F_EXEC file is executable (no unresolved external references) - * F_LNNO line numbers stripped from file - * F_LSYMS local symbols stripped from file - * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax) - */ - -#define F_RELFLG (0x0001) -#define F_EXEC (0x0002) -#define F_LNNO (0x0004) -#define F_LSYMS (0x0008) -#define F_BM32B (0020000) -#define F_BM32MAU (0040000) - -#define WE32KMAGIC 0x170 /* we32k sans transfer vector */ -#define FBOMAGIC 0x170 /* we32k sans transfer vector */ -#define MTVMAGIC 0x171 /* we32k with transfer vector */ -#define RBOMAGIC 0x172 /* reserved */ -#define WE32KBADMAG(x) (((x).f_magic != WE32KMAGIC) \ - && ((x).f_magic != FBOMAGIC) \ - && ((x).f_magic != RBOMAGIC) \ - && ((x).f_magic != MTVMAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - -#define AOUTSZ (sizeof(AOUTHDR)) - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _TV ".tv" -#define _INIT ".init" -#define _FINI ".fini" - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - -#define N_BTMASK (0xf) -#define N_TMASK (0x30) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - -# define _ETEXT "etext" - - -/********************** RELOCATION DIRECTIVES **********************/ - - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_type[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ sizeof(RELOC) - diff --git a/contrib/gdb/include/coff/z8k.h b/contrib/gdb/include/coff/z8k.h deleted file mode 100644 index 48817952829..00000000000 --- a/contrib/gdb/include/coff/z8k.h +++ /dev/null @@ -1,201 +0,0 @@ -/*** coff information for Zilog Z800N */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - -/* Type of cpu is stored in flags */ -#define F_Z8001 0x1000 -#define F_Z8002 0x2000 -#define F_MACHMASK 0xf000 - -#define Z8KMAGIC 0x8000 - -#define Z8KBADMAG(x) (((x).f_magic!=Z8KMAGIC)) - -#define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - char magic[2]; /* type of file */ - char vstamp[2]; /* version stamp */ - char tsize[4]; /* text size in bytes, padded to FW bdry*/ - char dsize[4]; /* initialized data " " */ - char bsize[4]; /* uninitialized data " " */ - char entry[4]; /* entry pt. */ - char text_start[4]; /* base of text used for this file */ - char data_start[4]; /* base of data used for this file */ -} -AOUTHDR; - - -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) - - - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" - - -#define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) - - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[4]; /* line number */ -}; - -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno)); -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); - -#define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 - - - -/********************** RELOCATION DIRECTIVES **********************/ - -/* The external reloc has an offset field, because some of the reloc - types on the z8k don't have room in the instruction for the entire - offset - eg with segments */ - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_offset[4]; - char r_type[2]; - char r_stuff[2]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 16 - diff --git a/contrib/gdb/include/demangle.h b/contrib/gdb/include/demangle.h deleted file mode 100644 index d4d0a3f428e..00000000000 --- a/contrib/gdb/include/demangle.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Defs for interface to demanglers. - Copyright 1992, 1995, 1996 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -#if !defined (DEMANGLE_H) -#define DEMANGLE_H - -#ifdef IN_GCC - -/* Add prototype support. */ -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif - -#define PARAMS(ARGS) PROTO(ARGS) - -#ifdef __STDC__ -#define PTR void * -#else -#ifndef const -#define const -#endif -#define PTR char * -#endif - -#else /* ! IN_GCC */ -#include -#endif /* IN_GCC */ - -/* Options passed to cplus_demangle (in 2nd parameter). */ - -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ - -#define DMGL_AUTO (1 << 8) -#define DMGL_GNU (1 << 9) -#define DMGL_LUCID (1 << 10) -#define DMGL_ARM (1 << 11) -/* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM) - -/* Enumeration of possible demangling styles. - - Lucid and ARM styles are still kept logically distinct, even though - they now both behave identically. The resulting style is actual the - union of both. I.E. either style recognizes both "__pt__" and "__rf__" - for operator "->", even though the first is lucid style and the second - is ARM style. (FIXME?) */ - -extern enum demangling_styles -{ - unknown_demangling = 0, - auto_demangling = DMGL_AUTO, - gnu_demangling = DMGL_GNU, - lucid_demangling = DMGL_LUCID, - arm_demangling = DMGL_ARM -} current_demangling_style; - -/* Define string names for the various demangling styles. */ - -#define AUTO_DEMANGLING_STYLE_STRING "auto" -#define GNU_DEMANGLING_STYLE_STRING "gnu" -#define LUCID_DEMANGLING_STYLE_STRING "lucid" -#define ARM_DEMANGLING_STYLE_STRING "arm" - -/* Some macros to test what demangling style is active. */ - -#define CURRENT_DEMANGLING_STYLE current_demangling_style -#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) -#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) -#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) -#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM) - -extern char * -cplus_demangle PARAMS ((const char *mangled, int options)); - -extern int -cplus_demangle_opname PARAMS ((const char *opname, char *result, int options)); - -extern const char * -cplus_mangle_opname PARAMS ((const char *opname, int options)); - -/* Note: This sets global state. FIXME if you care about multi-threading. */ - -extern void -set_cplus_marker_for_demangling PARAMS ((int ch)); - -#endif /* DEMANGLE_H */ diff --git a/contrib/gdb/include/dis-asm.h b/contrib/gdb/include/dis-asm.h deleted file mode 100644 index d70bd514e9c..00000000000 --- a/contrib/gdb/include/dis-asm.h +++ /dev/null @@ -1,175 +0,0 @@ -/* Interface between the opcode library and its callers. - Written by Cygnus Support, 1993. - - The opcode library (libopcodes.a) provides instruction decoders for - a large variety of instruction sets, callable with an identical - interface, for making instruction-processing programs more independent - of the instruction set being processed. */ - -#ifndef DIS_ASM_H -#define DIS_ASM_H - -#include -#include "bfd.h" - -typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...)); - -enum dis_insn_type { - dis_noninsn, /* Not a valid instruction */ - dis_nonbranch, /* Not a branch instruction */ - dis_branch, /* Unconditional branch */ - dis_condbranch, /* Conditional branch */ - dis_jsr, /* Jump to subroutine */ - dis_condjsr, /* Conditional jump to subroutine */ - dis_dref, /* Data reference instruction */ - dis_dref2 /* Two data references in instruction */ -}; - -/* This struct is passed into the instruction decoding routine, - and is passed back out into each callback. The various fields are used - for conveying information from your main routine into your callbacks, - for passing information into the instruction decoders (such as the - addresses of the callback functions), or for passing information - back from the instruction decoders to their callers. - - It must be initialized before it is first passed; this can be done - by hand, or using one of the initialization macros below. */ - -typedef struct disassemble_info { - fprintf_ftype fprintf_func; - FILE *stream; - PTR application_data; - - /* Target description. We could replace this with a pointer to the bfd, - but that would require one. There currently isn't any such requirement - so to avoid introducing one we record these explicitly. */ - /* The bfd_arch value. */ - enum bfd_architecture arch; - /* The bfd_mach value. */ - unsigned long mach; - /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */ - enum bfd_endian endian; - - /* For use by the disassembler. - The top 16 bits are reserved for public use (and are documented here). - The bottom 16 bits are for the internal use of the disassembler. */ - unsigned long flags; - PTR private_data; - - /* Function used to get bytes to disassemble. MEMADDR is the - address of the stuff to be disassembled, MYADDR is the address to - put the bytes in, and LENGTH is the number of bytes to read. - INFO is a pointer to this struct. - Returns an errno value or 0 for success. */ - int (*read_memory_func) - PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length, - struct disassemble_info *info)); - - /* Function which should be called if we get an error that we can't - recover from. STATUS is the errno value from read_memory_func and - MEMADDR is the address that we were trying to read. INFO is a - pointer to this struct. */ - void (*memory_error_func) - PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info)); - - /* Function called to print ADDR. */ - void (*print_address_func) - PARAMS ((bfd_vma addr, struct disassemble_info *info)); - - /* These are for buffer_read_memory. */ - bfd_byte *buffer; - bfd_vma buffer_vma; - int buffer_length; - - /* Results from instruction decoders. Not all decoders yet support - this information. This info is set each time an instruction is - decoded, and is only valid for the last such instruction. - - To determine whether this decoder supports this information, set - insn_info_valid to 0, decode an instruction, then check it. */ - - char insn_info_valid; /* Branch info has been set. */ - char branch_delay_insns; /* How many sequential insn's will run before - a branch takes effect. (0 = normal) */ - char data_size; /* Size of data reference in insn, in bytes */ - enum dis_insn_type insn_type; /* Type of instruction */ - bfd_vma target; /* Target address of branch or dref, if known; - zero if unknown. */ - bfd_vma target2; /* Second target address for dref2 */ - -} disassemble_info; - - -/* Standard disassemblers. Disassemble one instruction at the given - target address. Return number of bytes processed. */ -typedef int (*disassembler_ftype) - PARAMS((bfd_vma, disassemble_info *)); - -extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_big_arm PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_little_arm PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_sparc64 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_shl 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*)); -extern int print_insn_w65 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 - into a buffer before calling the instruction decoder. */ - -/* Here is a function which callers may wish to use for read_memory_func. - It gets bytes from a buffer. */ -extern int buffer_read_memory - PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *)); - -/* This function goes with buffer_read_memory. - It prints a message using info->fprintf_func and info->stream. */ -extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *)); - - -/* Just print the address in hex. This is included for completeness even - though both GDB and objdump provide their own (to print symbolic - addresses). */ -extern void generic_print_address - PARAMS ((bfd_vma, struct disassemble_info *)); - -/* Macro to initialize a disassemble_info struct. This should be called - by all applications creating such a struct. */ -#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \ - (INFO).fprintf_func = (FPRINTF_FUNC), \ - (INFO).stream = (STREAM), \ - (INFO).buffer = NULL, \ - (INFO).buffer_vma = 0, \ - (INFO).buffer_length = 0, \ - (INFO).read_memory_func = buffer_read_memory, \ - (INFO).memory_error_func = perror_memory, \ - (INFO).print_address_func = generic_print_address, \ - (INFO).arch = bfd_arch_unknown, \ - (INFO).mach = 0, \ - (INFO).endian = BFD_ENDIAN_UNKNOWN, \ - (INFO).flags = 0, \ - (INFO).insn_info_valid = 0 - -#endif /* ! defined (DIS_ASM_H) */ diff --git a/contrib/gdb/include/elf/ChangeLog b/contrib/gdb/include/elf/ChangeLog deleted file mode 100644 index b56f9bb1d8d..00000000000 --- a/contrib/gdb/include/elf/ChangeLog +++ /dev/null @@ -1,195 +0,0 @@ -Mon Feb 19 01:55:56 1996 Doug Evans - - * sparc.h (R_SPARC_{PLT32,HIPLT22,LOPLT10,PCPLT32,PCPLT22, - PCPLT10,5,6}): Don't define ifdef SPARC64_OLD_RELOCS. - -Tue Feb 6 11:33:58 1996 Doug Evans - - * sparc.h (enum sparc_elf_reloc_type): Define. - -Wed Jan 17 09:09:16 1996 Doug Evans - - * common.h: Define EM_SPARC32PLUS. - * sparc.h: New file. - -Thu Jan 11 16:27:34 1996 Michael Meissner - - * ppc.h (SHF_EXCLUDE, SHT_ORDERED): New fields from the abi. - -Thu Nov 30 16:47:18 1995 Ian Lance Taylor - - * internal.h (struct elf_segment_map): Add includes_filehdr and - includes_phdrs fields. - -Tue Nov 28 16:58:10 1995 Ian Lance Taylor - - * internal.h (struct elf_segment_map): Define. - -Tue Oct 31 15:19:36 1995 Fred Fish - - * common.h, dwarf.h, external.h, hppa.h, internal.h, - mips.h, ppc.h: Protect against multiple inclusions. - -Thu Sep 21 13:51:58 1995 Michael Meissner - - * ppc.h (EF_PPC_RELOCATABLE_LIB): Add new flag bit. - -Fri Sep 1 15:32:17 1995 Kazumoto Kojima - - * mips.h: Add some definitions used on Irix 5. - -Tue Jun 20 10:18:28 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa.h (CPU_PA_RISC1_0): Protect from redefinitions. - (CPU_PA_RISC1_1): Likewise. - -Wed Mar 8 18:14:37 1995 Michael Meissner - - * ppc.h: New file for PowerPC support. - -Tue Feb 14 13:59:13 1995 Michael Meissner - - * common.h (EM_PPC): Use offical value of 20, not 17. - (EM_PPC_OLD): Define this to be the old value of EM_PPC. - - -Tue Jan 24 09:40:59 1995 Michael Meissner - - * common.h (EM_PPC): New macro, PowerPC machine id. - -Tue Jan 17 10:51:38 1995 Ian Lance Taylor - - * mips.h (SHT_MIPS_MSYM, SHT_MIPS_DWARF, SHT_MIPS_EVENTS): Define. - - -Mon Oct 17 13:43:59 1994 Ian Lance Taylor - - * internal.h (Elf_Internal_Shdr): Remove rawdata and size fields. - Add bfd_section field. - -Tue May 24 16:11:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (Elf32_External_gptab): Define. - -Mon May 16 13:22:04 1994 Jeff Law (law@snake.cs.utah.edu) - - * common.h (EM_HPPA): Delete. - (EM_PARISC): Add. - * hppa.h: New file. - -Mon May 9 13:27:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * common.h (SHN_LORESERVE): Rename from SHN_LORESERV. - (ELF32_R_TYPE, ELF32_R_INFO): Don't rely on size of unsigned char. - (ELF64_R_TYPE): Don't rely on size of unsigned long. - -Mon Apr 25 15:53:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * internal.h (Elf_Internal_Shdr): Use PTR, not void *. - -Fri Mar 11 00:34:59 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips.h (SHN_MIPS_TEXT, SHN_MIPS_DATA): Define. - -Sat Mar 5 14:08:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * internal.h: Remove Elf32_*, Elf64_* typedefs. These names - cause conflicts with system headers, e.g. link.h in gdb/solib.c. - Combine 32- and 64-bit versions of *_Internal_Dyn. - * common.h: Replace uses of Elf64_Word, Elf64_Xword typedefs - by their expansion. - * mips.h: Replace uses of Elf32_Word, Elf32_Sword, Elf32_Addr - typedefs by their expansion. Add DT_MIPS_RLD_MAP definition. - -Fri Feb 18 10:39:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * common.h (EM_CYGNUS_POWERPC): Define. This may be temporary, - depending upon how quickly I can find a real PowerPC ABI. - -Mon Feb 7 08:27:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * internal.h: Change HOST_64_BIT to BFD_HOST_64_BIT. - -Wed Feb 2 14:12:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * common.h: Add comments regarding value of EM_HPPA and how to - pick an unofficial value. - -Wed Nov 17 17:14:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (SHT_MIPS_OPTIONS): Define. - -Mon Nov 8 17:57:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h: Added some more MIPS ABI macro definitions. - -Wed Nov 3 22:07:17 1993 Ken Raeburn (raeburn@rtl.cygnus.com) - - * common.h (EM_MIPS_RS4_BE): New macro. - -Tue Oct 12 07:28:18 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h: New file. MIPS ABI specific information. - -Mon Jun 21 13:13:43 1993 Ken Raeburn (raeburn@poseidon.cygnus.com) - - * internal.h: Combined 32- and 64-bit versions of all structures - except *_Internal_Dyn. This will simply the assembler interface, - and some bfd code. - -Tue May 25 02:00:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * external.h, internal.h, common.h: Added 64-bit versions of some - structures and macros. Renamed old versions to put "32" in the - name. Some are unchanged. - -Thu Apr 29 12:12:20 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * common.h (EM_HPPA, NT_VERSION, STN_UNDEF, DT_*): New macros. - * external.h (Elf_External_Dyn): New type. - - * internal.h (Elf_Intenral_Shdr): New field `size'. - (Elf_Internal_Dyn): New type. - -Tue Apr 20 16:03:45 1993 Fred Fish (fnf@cygnus.com) - - * dwarf.h (LANG_CHILL): Change value to one randomly picked in - the user defined range, to reduce probability of collisions. - -Sun Nov 15 09:34:02 1992 Fred Fish (fnf@cygnus.com) - - * dwarf.h (AT_src_coords): Whitespace change only. - * dwarf.h (AT_body_begin, AT_body_end, LANG_MODULA2): - Add from latest gcc. - * dwarf.h (LANG_CHILL): Add as GNU extension. - -Sat Aug 1 13:46:53 1992 Fred Fish (fnf@cygnus.com) - - * dwarf.h: Replace with current version from gcc distribution. - -Fri Jun 19 19:05:09 1992 John Gilmore (gnu at cygnus.com) - - * internal.h: Add real struct tags to all the Type_Defs, so they - can be used in prototypes where the Type_Defs are not known. - -Fri Apr 3 20:58:58 1992 Mark Eichin (eichin at cygnus.com) - - * common.h: added ELF_R_{SYM,TYPE,INFO} for handling relocation - info - added EM_MIPS, and corrected value of EM_860 based on System V ABI - manual. - - * external.h: added Elf_External_{Rel,Rela}. - - * internal.h: added Elf_Internal_{Rel,Rela}. - added rawdata to Elf_Internal_Shdr. - -Sat Nov 30 20:43:59 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * common.h, dwarf.h, external.h, internal.h, ChangeLog; moved from - ../elf- - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/include/elf/common.h b/contrib/gdb/include/elf/common.h deleted file mode 100644 index c9e74741c57..00000000000 --- a/contrib/gdb/include/elf/common.h +++ /dev/null @@ -1,239 +0,0 @@ -/* ELF support for BFD. - Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, from information published - in "UNIX System V Release 4, Programmers Guide: ANSI C and - Programming Support Tools". - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file is part of ELF support for BFD, and contains the portions - that are common to both the internal and external representations. - For example, ELFMAG0 is the byte 0x7F in both the internal (in-memory) - and external (in-file) representations. */ - -#ifndef _ELF_COMMON_H -#define _ELF_COMMON_H - -/* Fields in e_ident[] */ - -#define EI_MAG0 0 /* File identification byte 0 index */ -#define ELFMAG0 0x7F /* Magic number byte 0 */ - -#define EI_MAG1 1 /* File identification byte 1 index */ -#define ELFMAG1 'E' /* Magic number byte 1 */ - -#define EI_MAG2 2 /* File identification byte 2 index */ -#define ELFMAG2 'L' /* Magic number byte 2 */ - -#define EI_MAG3 3 /* File identification byte 3 index */ -#define ELFMAG3 'F' /* Magic number byte 3 */ - -#define EI_CLASS 4 /* File class */ -#define ELFCLASSNONE 0 /* Invalid class */ -#define ELFCLASS32 1 /* 32-bit objects */ -#define ELFCLASS64 2 /* 64-bit objects */ - -#define EI_DATA 5 /* Data encoding */ -#define ELFDATANONE 0 /* Invalid data encoding */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ - -#define EI_VERSION 6 /* File version */ - -#define EI_PAD 7 /* Start of padding bytes */ - - -/* Values for e_type, which identifies the object file type */ - -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Relocatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_LOPROC 0xFF00 /* Processor-specific */ -#define ET_HIPROC 0xFFFF /* Processor-specific */ - -/* 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 (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 */ - -#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ - -#define EM_PPC 20 /* PowerPC */ - -/* 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 - -/* Old version of PowerPC, this should be removed shortly. */ -#define EM_PPC_OLD 17 - - -/* Values for e_version */ - -#define EV_NONE 0 /* Invalid ELF version */ -#define EV_CURRENT 1 /* Current version */ - -/* Values for program header, p_type field */ - -#define PT_NULL 0 /* Program header table entry unused */ -#define PT_LOAD 1 /* Loadable program segment */ -#define PT_DYNAMIC 2 /* Dynamic linking information */ -#define PT_INTERP 3 /* Program interpreter */ -#define PT_NOTE 4 /* Auxiliary information */ -#define PT_SHLIB 5 /* Reserved, unspecified semantics */ -#define PT_PHDR 6 /* Entry for header table itself */ -#define PT_LOPROC 0x70000000 /* Processor-specific */ -#define PT_HIPROC 0x7FFFFFFF /* Processor-specific */ - -/* Program segment permissions, in program header p_flags field */ - -#define PF_X (1 << 0) /* Segment is executable */ -#define PF_W (1 << 1) /* Segment is writable */ -#define PF_R (1 << 2) /* Segment is readable */ -#define PF_MASKPROC 0xF0000000 /* Processor-specific reserved bits */ - -/* Values for section header, sh_type field */ - -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program specific (private) data */ -#define SHT_SYMTAB 2 /* Link editing symbol table */ -#define SHT_STRTAB 3 /* A string table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* A symbol hash table */ -#define SHT_DYNAMIC 6 /* Information for dynamic linking */ -#define SHT_NOTE 7 /* Information that marks file */ -#define SHT_NOBITS 8 /* Section occupies no space in file */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved, unspecified semantics */ -#define SHT_DYNSYM 11 /* Dynamic linking symbol table */ -#define SHT_LOPROC 0x70000000 /* Processor-specific semantics, lo */ -#define SHT_HIPROC 0x7FFFFFFF /* Processor-specific semantics, hi */ -#define SHT_LOUSER 0x80000000 /* Application-specific semantics */ -#define SHT_HIUSER 0x8FFFFFFF /* Application-specific semantics */ - -/* Values for section header, sh_flags field */ - -#define SHF_WRITE (1 << 0) /* Writable data during execution */ -#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -#define SHF_EXECINSTR (1 << 2) /* Executable machine instructions */ -#define SHF_MASKPROC 0xF0000000 /* Processor-specific semantics */ - -/* Values of note segment descriptor types for core files. */ - -#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ - -/* Values of note segment descriptor types for object files. */ -/* (Only for hppa right now. Should this be moved elsewhere?) */ - -#define NT_VERSION 1 /* Contains a version string. */ - -/* These three macros disassemble and assemble a symbol table st_info field, - which contains the symbol binding and symbol type. The STB_ and STT_ - defines identify the binding and type. */ - -#define ELF_ST_BIND(val) (((unsigned int)(val)) >> 4) -#define ELF_ST_TYPE(val) ((val) & 0xF) -#define ELF_ST_INFO(bind,type) (((bind) << 4) + ((type) & 0xF)) - -#define STN_UNDEF 0 /* undefined symbol index */ - -#define STB_LOCAL 0 /* Symbol not visible outside obj */ -#define STB_GLOBAL 1 /* Symbol visible outside obj */ -#define STB_WEAK 2 /* Like globals, lower precedence */ -#define STB_LOPROC 13 /* Application-specific semantics */ -#define STB_HIPROC 15 /* Application-specific semantics */ - -#define STT_NOTYPE 0 /* Symbol type is unspecified */ -#define STT_OBJECT 1 /* Symbol is a data object */ -#define STT_FUNC 2 /* Symbol is a code object */ -#define STT_SECTION 3 /* Symbol associated with a section */ -#define STT_FILE 4 /* Symbol gives a file name */ -#define STT_LOPROC 13 /* Application-specific semantics */ -#define STT_HIPROC 15 /* Application-specific semantics */ - -/* Special section indices, which may show up in st_shndx fields, among - other places. */ - -#define SHN_UNDEF 0 /* Undefined section reference */ -#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 */ -#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ -#define SHN_HIRESERVE 0xFFFF /* End range of reserved indices */ - -/* relocation info handling macros */ - -#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) ((i) & 0xffffffff) -#define ELF64_R_INFO(s,t) (((bfd_vma) (s) << 32) + (bfd_vma) (t)) - -/* Dynamic section tags */ - -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff - -#endif /* _ELF_COMMON_H */ diff --git a/contrib/gdb/include/elf/dwarf.h b/contrib/gdb/include/elf/dwarf.h deleted file mode 100644 index 4333d5eda40..00000000000 --- a/contrib/gdb/include/elf/dwarf.h +++ /dev/null @@ -1,319 +0,0 @@ -/* Declarations and definitions of codes relating to the DWARF symbolic - debugging information format. - - Written by Ron Guilmette (rfg@ncd.com) - -Copyright (C) 1992 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file is derived from the DWARF specification (a public document) - Revision 1.0.1 (April 8, 1992) developed by the UNIX International - Programming Languages Special Interest Group (UI/PLSIG) and distributed - by UNIX International. Copies of this specification are available from - UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. -*/ - -#ifndef _ELF_DWARF_H -#define _ELF_DWARF_H - -/* Tag names and codes. */ - -enum dwarf_tag { - TAG_padding = 0x0000, - TAG_array_type = 0x0001, - TAG_class_type = 0x0002, - TAG_entry_point = 0x0003, - TAG_enumeration_type = 0x0004, - TAG_formal_parameter = 0x0005, - TAG_global_subroutine = 0x0006, - TAG_global_variable = 0x0007, - /* 0x0008 -- reserved */ - /* 0x0009 -- reserved */ - TAG_label = 0x000a, - TAG_lexical_block = 0x000b, - TAG_local_variable = 0x000c, - TAG_member = 0x000d, - /* 0x000e -- reserved */ - TAG_pointer_type = 0x000f, - TAG_reference_type = 0x0010, - TAG_compile_unit = 0x0011, - TAG_string_type = 0x0012, - TAG_structure_type = 0x0013, - TAG_subroutine = 0x0014, - TAG_subroutine_type = 0x0015, - TAG_typedef = 0x0016, - TAG_union_type = 0x0017, - TAG_unspecified_parameters = 0x0018, - TAG_variant = 0x0019, - TAG_common_block = 0x001a, - TAG_common_inclusion = 0x001b, - TAG_inheritance = 0x001c, - TAG_inlined_subroutine = 0x001d, - TAG_module = 0x001e, - TAG_ptr_to_member_type = 0x001f, - TAG_set_type = 0x0020, - TAG_subrange_type = 0x0021, - TAG_with_stmt = 0x0022, - - /* GNU extensions */ - - TAG_format_label = 0x8000, /* for FORTRAN 77 and Fortran 90 */ - TAG_namelist = 0x8001, /* For Fortran 90 */ - TAG_function_template = 0x8002, /* for C++ */ - TAG_class_template = 0x8003 /* for C++ */ -}; - -#define TAG_lo_user 0x8000 /* implementation-defined range start */ -#define TAG_hi_user 0xffff /* implementation-defined range end */ -#define TAG_source_file TAG_compile_unit /* for backward compatibility */ - -/* Form names and codes. */ - -enum dwarf_form { - FORM_ADDR = 0x1, - FORM_REF = 0x2, - FORM_BLOCK2 = 0x3, - FORM_BLOCK4 = 0x4, - FORM_DATA2 = 0x5, - FORM_DATA4 = 0x6, - FORM_DATA8 = 0x7, - FORM_STRING = 0x8 -}; - -/* Attribute names and codes. */ - -enum dwarf_attribute { - AT_sibling = (0x0010|FORM_REF), - AT_location = (0x0020|FORM_BLOCK2), - AT_name = (0x0030|FORM_STRING), - AT_fund_type = (0x0050|FORM_DATA2), - AT_mod_fund_type = (0x0060|FORM_BLOCK2), - AT_user_def_type = (0x0070|FORM_REF), - AT_mod_u_d_type = (0x0080|FORM_BLOCK2), - AT_ordering = (0x0090|FORM_DATA2), - AT_subscr_data = (0x00a0|FORM_BLOCK2), - AT_byte_size = (0x00b0|FORM_DATA4), - AT_bit_offset = (0x00c0|FORM_DATA2), - AT_bit_size = (0x00d0|FORM_DATA4), - /* (0x00e0|FORM_xxxx) -- reserved */ - AT_element_list = (0x00f0|FORM_BLOCK4), - AT_stmt_list = (0x0100|FORM_DATA4), - AT_low_pc = (0x0110|FORM_ADDR), - AT_high_pc = (0x0120|FORM_ADDR), - AT_language = (0x0130|FORM_DATA4), - AT_member = (0x0140|FORM_REF), - AT_discr = (0x0150|FORM_REF), - AT_discr_value = (0x0160|FORM_BLOCK2), - /* (0x0170|FORM_xxxx) -- reserved */ - /* (0x0180|FORM_xxxx) -- reserved */ - AT_string_length = (0x0190|FORM_BLOCK2), - AT_common_reference = (0x01a0|FORM_REF), - AT_comp_dir = (0x01b0|FORM_STRING), - AT_const_value_string = (0x01c0|FORM_STRING), - AT_const_value_data2 = (0x01c0|FORM_DATA2), - AT_const_value_data4 = (0x01c0|FORM_DATA4), - AT_const_value_data8 = (0x01c0|FORM_DATA8), - AT_const_value_block2 = (0x01c0|FORM_BLOCK2), - AT_const_value_block4 = (0x01c0|FORM_BLOCK4), - AT_containing_type = (0x01d0|FORM_REF), - AT_default_value_addr = (0x01e0|FORM_ADDR), - AT_default_value_data2 = (0x01e0|FORM_DATA2), - AT_default_value_data4 = (0x01e0|FORM_DATA4), - AT_default_value_data8 = (0x01e0|FORM_DATA8), - AT_default_value_string = (0x01e0|FORM_STRING), - AT_friends = (0x01f0|FORM_BLOCK2), - AT_inline = (0x0200|FORM_STRING), - AT_is_optional = (0x0210|FORM_STRING), - AT_lower_bound_ref = (0x0220|FORM_REF), - AT_lower_bound_data2 = (0x0220|FORM_DATA2), - AT_lower_bound_data4 = (0x0220|FORM_DATA4), - AT_lower_bound_data8 = (0x0220|FORM_DATA8), - AT_private = (0x0240|FORM_STRING), - AT_producer = (0x0250|FORM_STRING), - AT_program = (0x0230|FORM_STRING), - AT_protected = (0x0260|FORM_STRING), - AT_prototyped = (0x0270|FORM_STRING), - AT_public = (0x0280|FORM_STRING), - AT_pure_virtual = (0x0290|FORM_STRING), - AT_return_addr = (0x02a0|FORM_BLOCK2), - AT_abstract_origin = (0x02b0|FORM_REF), - AT_start_scope = (0x02c0|FORM_DATA4), - AT_stride_size = (0x02e0|FORM_DATA4), - AT_upper_bound_ref = (0x02f0|FORM_REF), - AT_upper_bound_data2 = (0x02f0|FORM_DATA2), - AT_upper_bound_data4 = (0x02f0|FORM_DATA4), - AT_upper_bound_data8 = (0x02f0|FORM_DATA8), - AT_virtual = (0x0300|FORM_STRING), - - /* GNU extensions. */ - - AT_sf_names = (0x8000|FORM_DATA4), - AT_src_info = (0x8010|FORM_DATA4), - AT_mac_info = (0x8020|FORM_DATA4), - AT_src_coords = (0x8030|FORM_DATA4), - AT_body_begin = (0x8040|FORM_ADDR), - AT_body_end = (0x8050|FORM_ADDR) -}; - -#define AT_lo_user 0x8000 /* implementation-defined range start */ -#define AT_hi_user 0xffff /* implementation-defined range end */ - -/* Location atom names and codes. */ - -enum dwarf_location_atom { - OP_REG = 0x01, - OP_BASEREG = 0x02, - OP_ADDR = 0x03, - OP_CONST = 0x04, - OP_DEREF2 = 0x05, - OP_DEREF4 = 0x06, - OP_ADD = 0x07 -}; - -#define OP_LO_USER 0x80 /* implementation-defined range start */ -#define OP_HI_USER 0xff /* implementation-defined range end */ - -/* Fundamental type names and codes. */ - -enum dwarf_fundamental_type { - FT_char = 0x0001, - FT_signed_char = 0x0002, - FT_unsigned_char = 0x0003, - FT_short = 0x0004, - FT_signed_short = 0x0005, - FT_unsigned_short = 0x0006, - FT_integer = 0x0007, - FT_signed_integer = 0x0008, - FT_unsigned_integer = 0x0009, - FT_long = 0x000a, - FT_signed_long = 0x000b, - FT_unsigned_long = 0x000c, - FT_pointer = 0x000d, /* an alias for (void *) */ - FT_float = 0x000e, - FT_dbl_prec_float = 0x000f, - FT_ext_prec_float = 0x0010, /* breaks "classic" svr4 SDB */ - FT_complex = 0x0011, /* breaks "classic" svr4 SDB */ - FT_dbl_prec_complex = 0x0012, /* breaks "classic" svr4 SDB */ - /* 0x0013 -- reserved */ - FT_void = 0x0014, - FT_boolean = 0x0015, /* breaks "classic" svr4 SDB */ - FT_ext_prec_complex = 0x0016, /* breaks "classic" svr4 SDB */ - FT_label = 0x0017, - - /* GNU extensions - The low order byte must indicate the size (in bytes) for the type. - All of these types will probably break "classic" svr4 SDB */ - - FT_long_long = 0x8008, - FT_signed_long_long = 0x8108, - FT_unsigned_long_long = 0x8208, - - FT_int8 = 0x9001, - FT_signed_int8 = 0x9101, - FT_unsigned_int8 = 0x9201, - FT_int16 = 0x9302, - FT_signed_int16 = 0x9402, - FT_unsigned_int16 = 0x9502, - FT_int32 = 0x9604, - FT_signed_int32 = 0x9704, - FT_unsigned_int32 = 0x9804, - FT_int64 = 0x9908, - FT_signed_int64 = 0x9a08, - FT_unsigned_int64 = 0x9b08, - - FT_real32 = 0xa004, - FT_real64 = 0xa108, - FT_real96 = 0xa20c, - FT_real128 = 0xa310 -}; - -#define FT_lo_user 0x8000 /* implementation-defined range start */ -#define FT_hi_user 0xffff /* implementation defined range end */ - -/* Type modifier names and codes. */ - -enum dwarf_type_modifier { - MOD_pointer_to = 0x01, - MOD_reference_to = 0x02, - MOD_const = 0x03, - MOD_volatile = 0x04 -}; - -#define MOD_lo_user 0x80 /* implementation-defined range start */ -#define MOD_hi_user 0xff /* implementation-defined range end */ - -/* Array ordering names and codes. */ - -enum dwarf_array_dim_ordering { - ORD_row_major = 0, - ORD_col_major = 1 -}; - -/* Array subscript format names and codes. */ - -enum dwarf_subscr_data_formats { - FMT_FT_C_C = 0x0, - FMT_FT_C_X = 0x1, - FMT_FT_X_C = 0x2, - FMT_FT_X_X = 0x3, - FMT_UT_C_C = 0x4, - FMT_UT_C_X = 0x5, - FMT_UT_X_C = 0x6, - FMT_UT_X_X = 0x7, - FMT_ET = 0x8 -}; - -/* Derived from above for ease of use. */ - -#define FMT_CODE(_FUNDAMENTAL_TYPE_P, _UB_CONST_P, _LB_CONST_P) \ - (((_FUNDAMENTAL_TYPE_P) ? 0 : 4) \ - | ((_UB_CONST_P) ? 0 : 2) \ - | ((_LB_CONST_P) ? 0 : 1)) - -/* Source language names and codes. */ - -enum dwarf_source_language { - LANG_C89 = 0x00000001, - LANG_C = 0x00000002, - LANG_ADA83 = 0x00000003, - LANG_C_PLUS_PLUS = 0x00000004, - LANG_COBOL74 = 0x00000005, - LANG_COBOL85 = 0x00000006, - LANG_FORTRAN77 = 0x00000007, - LANG_FORTRAN90 = 0x00000008, - LANG_PASCAL83 = 0x00000009, - LANG_MODULA2 = 0x0000000a, - - /* GNU extensions */ - - LANG_CHILL = 0x00009af3 /* random value for GNU Chill */ -}; - -#define LANG_lo_user 0x00008000 /* implementation-defined range start */ -#define LANG_hi_user 0x0000ffff /* implementation-defined range end */ - -/* Names and codes for GNU "macinfo" extension. */ - -enum dwarf_macinfo_record_type { - MACINFO_start = 's', - MACINFO_resume = 'r', - MACINFO_define = 'd', - MACINFO_undef = 'u' -}; - -#endif /* _ELF_DWARF_H */ diff --git a/contrib/gdb/include/elf/external.h b/contrib/gdb/include/elf/external.h deleted file mode 100644 index e6618cb752f..00000000000 --- a/contrib/gdb/include/elf/external.h +++ /dev/null @@ -1,195 +0,0 @@ -/* ELF support for BFD. - Copyright (C) 1991, 1992 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, from information published - in "UNIX System V Release 4, Programmers Guide: ANSI C and - Programming Support Tools". - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file is part of ELF support for BFD, and contains the portions - that describe how ELF is represented externally by the BFD library. - I.E. it describes the in-file representation of ELF. It requires - the elf-common.h file which contains the portions that are common to - both the internal and external representations. */ - -/* The 64-bit stuff is kind of random. Perhaps someone will publish a - spec someday. */ - -#ifndef _ELF_EXTERNAL_H -#define _ELF_EXTERNAL_H - -/* ELF Header (32-bit implementations) */ - -typedef struct { - unsigned char e_ident[16]; /* ELF "magic number" */ - unsigned char e_type[2]; /* Identifies object file type */ - unsigned char e_machine[2]; /* Specifies required architecture */ - unsigned char e_version[4]; /* Identifies object file version */ - unsigned char e_entry[4]; /* Entry point virtual address */ - unsigned char e_phoff[4]; /* Program header table file offset */ - unsigned char e_shoff[4]; /* Section header table file offset */ - unsigned char e_flags[4]; /* Processor-specific flags */ - unsigned char e_ehsize[2]; /* ELF header size in bytes */ - unsigned char e_phentsize[2]; /* Program header table entry size */ - unsigned char e_phnum[2]; /* Program header table entry count */ - unsigned char e_shentsize[2]; /* Section header table entry size */ - unsigned char e_shnum[2]; /* Section header table entry count */ - unsigned char e_shstrndx[2]; /* Section header string table index */ -} Elf32_External_Ehdr; - -typedef struct { - unsigned char e_ident[16]; /* ELF "magic number" */ - unsigned char e_type[2]; /* Identifies object file type */ - unsigned char e_machine[2]; /* Specifies required architecture */ - unsigned char e_version[4]; /* Identifies object file version */ - unsigned char e_entry[8]; /* Entry point virtual address */ - unsigned char e_phoff[8]; /* Program header table file offset */ - unsigned char e_shoff[8]; /* Section header table file offset */ - unsigned char e_flags[4]; /* Processor-specific flags */ - unsigned char e_ehsize[2]; /* ELF header size in bytes */ - unsigned char e_phentsize[2]; /* Program header table entry size */ - unsigned char e_phnum[2]; /* Program header table entry count */ - unsigned char e_shentsize[2]; /* Section header table entry size */ - unsigned char e_shnum[2]; /* Section header table entry count */ - unsigned char e_shstrndx[2]; /* Section header string table index */ -} Elf64_External_Ehdr; - -/* Program header */ - -typedef struct { - unsigned char p_type[4]; /* Identifies program segment type */ - unsigned char p_offset[4]; /* Segment file offset */ - unsigned char p_vaddr[4]; /* Segment virtual address */ - unsigned char p_paddr[4]; /* Segment physical address */ - unsigned char p_filesz[4]; /* Segment size in file */ - unsigned char p_memsz[4]; /* Segment size in memory */ - unsigned char p_flags[4]; /* Segment flags */ - unsigned char p_align[4]; /* Segment alignment, file & memory */ -} Elf32_External_Phdr; - -typedef struct { - unsigned char p_type[4]; /* Identifies program segment type */ - unsigned char p_flags[4]; /* Segment flags */ - unsigned char p_offset[8]; /* Segment file offset */ - unsigned char p_vaddr[8]; /* Segment virtual address */ - unsigned char p_paddr[8]; /* Segment physical address */ - unsigned char p_filesz[8]; /* Segment size in file */ - unsigned char p_memsz[8]; /* Segment size in memory */ - unsigned char p_align[8]; /* Segment alignment, file & memory */ -} Elf64_External_Phdr; - -/* Section header */ - -typedef struct { - unsigned char sh_name[4]; /* Section name, index in string tbl */ - unsigned char sh_type[4]; /* Type of section */ - unsigned char sh_flags[4]; /* Miscellaneous section attributes */ - unsigned char sh_addr[4]; /* Section virtual addr at execution */ - unsigned char sh_offset[4]; /* Section file offset */ - unsigned char sh_size[4]; /* Size of section in bytes */ - unsigned char sh_link[4]; /* Index of another section */ - unsigned char sh_info[4]; /* Additional section information */ - unsigned char sh_addralign[4]; /* Section alignment */ - unsigned char sh_entsize[4]; /* Entry size if section holds table */ -} Elf32_External_Shdr; - -typedef struct { - unsigned char sh_name[4]; /* Section name, index in string tbl */ - unsigned char sh_type[4]; /* Type of section */ - unsigned char sh_flags[8]; /* Miscellaneous section attributes */ - unsigned char sh_addr[8]; /* Section virtual addr at execution */ - unsigned char sh_offset[8]; /* Section file offset */ - unsigned char sh_size[8]; /* Size of section in bytes */ - unsigned char sh_link[4]; /* Index of another section */ - unsigned char sh_info[4]; /* Additional section information */ - unsigned char sh_addralign[8]; /* Section alignment */ - unsigned char sh_entsize[8]; /* Entry size if section holds table */ -} Elf64_External_Shdr; - -/* Symbol table entry */ - -typedef struct { - unsigned char st_name[4]; /* Symbol name, index in string tbl */ - unsigned char st_value[4]; /* Value of the symbol */ - unsigned char st_size[4]; /* Associated symbol size */ - unsigned char st_info[1]; /* Type and binding attributes */ - unsigned char st_other[1]; /* No defined meaning, 0 */ - unsigned char st_shndx[2]; /* Associated section index */ -} Elf32_External_Sym; - -typedef struct { - unsigned char st_name[4]; /* Symbol name, index in string tbl */ - unsigned char st_info[1]; /* Type and binding attributes */ - unsigned char st_other[1]; /* No defined meaning, 0 */ - unsigned char st_shndx[2]; /* Associated section index */ - unsigned char st_value[8]; /* Value of the symbol */ - unsigned char st_size[8]; /* Associated symbol size */ -} Elf64_External_Sym; - -/* Note segments */ - -typedef struct { - unsigned char namesz[4]; /* Size of entry's owner string */ - unsigned char descsz[4]; /* Size of the note descriptor */ - unsigned char type[4]; /* Interpretation of the descriptor */ - char name[1]; /* Start of the name+desc data */ -} Elf_External_Note; - -/* Relocation Entries */ -typedef struct { - unsigned char r_offset[4]; /* Location at which to apply the action */ - unsigned char r_info[4]; /* index and type of relocation */ -} Elf32_External_Rel; - -typedef struct { - unsigned char r_offset[4]; /* Location at which to apply the action */ - unsigned char r_info[4]; /* index and type of relocation */ - unsigned char r_addend[4]; /* Constant addend used to compute value */ -} Elf32_External_Rela; - -typedef struct { - unsigned char r_offset[8]; /* Location at which to apply the action */ - unsigned char r_info[8]; /* index and type of relocation */ -} Elf64_External_Rel; - -typedef struct { - unsigned char r_offset[8]; /* Location at which to apply the action */ - unsigned char r_info[8]; /* index and type of relocation */ - unsigned char r_addend[8]; /* Constant addend used to compute value */ -} Elf64_External_Rela; - -/* dynamic section structure */ - -typedef struct { - unsigned char d_tag[4]; /* entry tag value */ - union { - unsigned char d_val[4]; - unsigned char d_ptr[4]; - } d_un; -} Elf32_External_Dyn; - -typedef struct { - unsigned char d_tag[8]; /* entry tag value */ - union { - unsigned char d_val[8]; - unsigned char d_ptr[8]; - } d_un; -} Elf64_External_Dyn; - -#endif /* _ELF_EXTERNAL_H */ diff --git a/contrib/gdb/include/elf/hppa.h b/contrib/gdb/include/elf/hppa.h deleted file mode 100644 index c34077fa194..00000000000 --- a/contrib/gdb/include/elf/hppa.h +++ /dev/null @@ -1,94 +0,0 @@ -/* HPPA ELF support for BFD. - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file holds definitions specific to the HPPA ELF ABI. Note - that most of this is not actually implemented by BFD. */ - -#ifndef _ELF_HPPA_H -#define _ELF_HPPA_H - -/* Processor specific flags for the ELF header e_flags field. */ - -/* Target processor IDs to be placed in the low 16 bits of the flags - field. Note these names are shared with SOM, and therefore do not - follow ELF naming conventions. */ - -/* PA 1.0 big endian. */ -#ifndef CPU_PA_RISC1_0 -#define CPU_PA_RISC1_0 0x0000020b -#endif - -/* PA 1.1 big endian. */ -#ifndef CPU_PA_RISC1_1 -#define CPU_PA_RISC1_1 0x00000210 -#endif - -/* PA 1.0 little endian (unsupported) is 0x0000028b. */ -/* PA 1.1 little endian (unsupported) is 0x00000290. */ - -/* Trap null address dereferences. */ -#define ELF_PARISC_TRAPNIL 0x00010000 - -/* .PARISC.archext section is present. */ -#define EF_PARISC_EXT 0x00020000 - -/* Processor specific section types. */ - -/* Holds the global offset table, a table of pointers to external - data. */ -#define SHT_PARISC_GOT SHT_LOPROC+0 - -/* Nonloadable section containing information in architecture - extensions used by the code. */ -#define SHT_PARISC_ARCH SHT_LOPROC+1 - -/* Section in which $global$ is defined. */ -#define SHT_PARISC_GLOBAL SHT_LOPROC+2 - -/* Section holding millicode routines (mul, div, rem, dyncall, etc. */ -#define SHT_PARISC_MILLI SHT_LOPROC+3 - -/* Section holding unwind information for use by debuggers. */ -#define SHT_PARISC_UNWIND SHT_LOPROC+4 - -/* Section holding the procedure linkage table. */ -#define SHT_PARISC_PLT SHT_LOPROC+5 - -/* Short initialized and uninitialized data. */ -#define SHT_PARISC_SDATA SHT_LOPROC+6 -#define SHT_PARISC_SBSS SHT_LOPROC+7 - -/* Optional section holding argument location/relocation info. */ -#define SHT_PARISC_SYMEXTN SHT_LOPROC+8 - -/* Option section for linker stubs. */ -#define SHT_PARISC_STUBS SHT_LOPROC+9 - -/* Processor specific section flags. */ - -/* This section is near the global data pointer and thus allows short - addressing modes to be used. */ -#define SHF_PARISC_SHORT 0x20000000 - -/* Processor specific symbol types. */ - -/* Millicode function entry point. */ -#define STT_PARISC_MILLICODE STT_LOPROC+0 - -#endif /* _ELF_HPPA_H */ diff --git a/contrib/gdb/include/elf/internal.h b/contrib/gdb/include/elf/internal.h deleted file mode 100644 index 6375e892051..00000000000 --- a/contrib/gdb/include/elf/internal.h +++ /dev/null @@ -1,207 +0,0 @@ -/* ELF support for BFD. - 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 - Programming Support Tools". - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file is part of ELF support for BFD, and contains the portions - that describe how ELF is represented internally in the BFD library. - I.E. it describes the in-memory representation of ELF. It requires - the elf-common.h file which contains the portions that are common to - both the internal and external representations. */ - - -/* 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 - packing under various circumstances. */ - -#ifndef _ELF_INTERNAL_H -#define _ELF_INTERNAL_H - -/* ELF Header */ - -#define EI_NIDENT 16 /* Size of e_ident[] */ - -typedef struct elf_internal_ehdr { - unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ - bfd_vma e_entry; /* Entry point virtual address */ - bfd_signed_vma e_phoff; /* Program header table file offset */ - bfd_signed_vma e_shoff; /* Section header table file offset */ - unsigned long e_version; /* Identifies object file version */ - unsigned long e_flags; /* Processor-specific flags */ - unsigned short e_type; /* Identifies object file type */ - unsigned short e_machine; /* Specifies required architecture */ - unsigned short e_ehsize; /* ELF header size in bytes */ - unsigned short e_phentsize; /* Program header table entry size */ - unsigned short e_phnum; /* Program header table entry count */ - unsigned short e_shentsize; /* Section header table entry size */ - unsigned short e_shnum; /* Section header table entry count */ - unsigned short e_shstrndx; /* Section header string table index */ -} Elf_Internal_Ehdr; - -#define elf32_internal_ehdr elf_internal_ehdr -#define Elf32_Internal_Ehdr Elf_Internal_Ehdr -#define elf64_internal_ehdr elf_internal_ehdr -#define Elf64_Internal_Ehdr Elf_Internal_Ehdr - -/* Program header */ - -struct elf_internal_phdr { - unsigned long p_type; /* Identifies program segment type */ - unsigned long p_flags; /* Segment flags */ - bfd_vma p_offset; /* Segment file offset */ - bfd_vma p_vaddr; /* Segment virtual address */ - bfd_vma p_paddr; /* Segment physical address */ - bfd_vma p_filesz; /* Segment size in file */ - bfd_vma p_memsz; /* Segment size in memory */ - bfd_vma p_align; /* Segment alignment, file & memory */ -}; - -typedef struct elf_internal_phdr Elf_Internal_Phdr; -#define elf32_internal_phdr elf_internal_phdr -#define Elf32_Internal_Phdr Elf_Internal_Phdr -#define elf64_internal_phdr elf_internal_phdr -#define Elf64_Internal_Phdr Elf_Internal_Phdr - -/* Section header */ - -typedef struct elf_internal_shdr { - unsigned int sh_name; /* Section name, index in string tbl */ - unsigned int sh_type; /* Type of section */ - bfd_vma sh_flags; /* Miscellaneous section attributes */ - bfd_vma sh_addr; /* Section virtual addr at execution */ - bfd_size_type sh_size; /* Size of section in bytes */ - bfd_size_type sh_entsize; /* Entry size if section holds table */ - unsigned long sh_link; /* Index of another section */ - unsigned long sh_info; /* Additional section information */ - file_ptr sh_offset; /* Section file offset */ - unsigned int sh_addralign; /* Section alignment */ - - /* The internal rep also has some cached info associated with it. */ - asection * bfd_section; /* Associated BFD section. */ - PTR contents; /* Section contents. */ -} Elf_Internal_Shdr; - -#define elf32_internal_shdr elf_internal_shdr -#define Elf32_Internal_Shdr Elf_Internal_Shdr -#define elf64_internal_shdr elf_internal_shdr -#define Elf64_Internal_Shdr Elf_Internal_Shdr - -/* Symbol table entry */ - -struct elf_internal_sym { - bfd_vma st_value; /* Value of the symbol */ - bfd_vma st_size; /* Associated symbol size */ - unsigned long st_name; /* Symbol name, index in string tbl */ - unsigned char st_info; /* Type and binding attributes */ - unsigned char st_other; /* No defined meaning, 0 */ - unsigned short st_shndx; /* Associated section index */ -}; - -typedef struct elf_internal_sym Elf_Internal_Sym; - -#define elf32_internal_sym elf_internal_sym -#define elf64_internal_sym elf_internal_sym -#define Elf32_Internal_Sym Elf_Internal_Sym -#define Elf64_Internal_Sym Elf_Internal_Sym - -/* Note segments */ - -typedef struct elf_internal_note { - unsigned long namesz; /* Size of entry's owner string */ - unsigned long descsz; /* Size of the note descriptor */ - unsigned long type; /* Interpretation of the descriptor */ - char name[1]; /* Start of the name+desc data */ -} Elf_Internal_Note; -#define Elf32_Internal_Note Elf_Internal_Note -#define elf32_internal_note elf_internal_note - -/* Relocation Entries */ - -typedef struct elf_internal_rel { - bfd_vma r_offset; /* Location at which to apply the action */ - /* This needs to support 64-bit values in elf64. */ - bfd_vma r_info; /* index and type of relocation */ -} Elf_Internal_Rel; - -#define elf32_internal_rel elf_internal_rel -#define Elf32_Internal_Rel Elf_Internal_Rel -#define elf64_internal_rel elf_internal_rel -#define Elf64_Internal_Rel Elf_Internal_Rel - -typedef struct elf_internal_rela { - bfd_vma r_offset; /* Location at which to apply the action */ - bfd_vma r_info; /* Index and Type of relocation */ - bfd_signed_vma r_addend; /* Constant addend used to compute value */ -} Elf_Internal_Rela; - -#define elf32_internal_rela elf_internal_rela -#define elf64_internal_rela elf_internal_rela -#define Elf32_Internal_Rela Elf_Internal_Rela -#define Elf64_Internal_Rela Elf_Internal_Rela - -/* dynamic section structure */ - -typedef struct elf_internal_dyn { - /* This needs to support 64-bit values in elf64. */ - bfd_vma d_tag; /* entry tag value */ - union { - /* This needs to support 64-bit values in elf64. */ - bfd_vma d_val; - bfd_vma d_ptr; - } d_un; -} Elf_Internal_Dyn; - -#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 - -/* This structure is used to describe how sections should be assigned - to program segments. */ - -struct elf_segment_map -{ - /* Next program segment. */ - struct elf_segment_map *next; - /* Program segment type. */ - unsigned long p_type; - /* Program segment flags. */ - unsigned long p_flags; - /* Program segment physical address. */ - bfd_vma p_paddr; - /* Whether the p_flags field is valid; if not, the flags are based - on the section flags. */ - unsigned int p_flags_valid : 1; - /* Whether the p_paddr field is valid; if not, the physical address - is based on the section lma values. */ - unsigned int p_paddr_valid : 1; - /* Whether this segment includes the file header. */ - unsigned int includes_filehdr : 1; - /* Whether this segment includes the program headers. */ - unsigned int includes_phdrs : 1; - /* Number of sections (may be 0). */ - unsigned int count; - /* Sections. Actual number of elements is in count field. */ - asection *sections[1]; -}; - -#endif /* _ELF_INTERNAL_H */ diff --git a/contrib/gdb/include/elf/mips.h b/contrib/gdb/include/elf/mips.h deleted file mode 100644 index f0d8cd78965..00000000000 --- a/contrib/gdb/include/elf/mips.h +++ /dev/null @@ -1,298 +0,0 @@ -/* MIPS ELF support for BFD. - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - - By Ian Lance Taylor, Cygnus Support, , from - information in the System V Application Binary Interface, MIPS - Processor Supplement. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file holds definitions specific to the MIPS ELF ABI. Note - that most of this is not actually implemented by BFD. */ - -#ifndef _ELF_MIPS_H -#define _ELF_MIPS_H - -/* Processor specific flags for the ELF header e_flags field. */ - -/* At least one .noreorder directive appears in the source. */ -#define EF_MIPS_NOREORDER 0x00000001 - -/* File contains position independent code. */ -#define EF_MIPS_PIC 0x00000002 - -/* Code in file uses the standard calling sequence for calling - position independent code. */ -#define EF_MIPS_CPIC 0x00000004 - -/* Four bit MIPS architecture field. */ -#define EF_MIPS_ARCH 0xf0000000 - -/* -mips1 code. */ -#define E_MIPS_ARCH_1 0x00000000 - -/* -mips2 code. */ -#define E_MIPS_ARCH_2 0x10000000 - -/* -mips3 code. */ -#define E_MIPS_ARCH_3 0x20000000 - -/* Processor specific section indices. These sections do not actually - exist. Symbols with a st_shndx field corresponding to one of these - values have a special meaning. */ - -/* Defined and allocated common symbol. Value is virtual address. If - relocated, alignment must be preserved. */ -#define SHN_MIPS_ACOMMON 0xff00 - -/* Defined and allocated text symbol. Value is virtual address. - Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */ -#define SHN_MIPS_TEXT 0xff01 - -/* Defined and allocated data symbol. Value is virtual address. - Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */ -#define SHN_MIPS_DATA 0xff02 - -/* Small common symbol. */ -#define SHN_MIPS_SCOMMON 0xff03 - -/* Small undefined symbol. */ -#define SHN_MIPS_SUNDEFINED 0xff04 - -/* Processor specific section types. */ - -/* Section contains the set of dynamic shared objects used when - statically linking. */ -#define SHT_MIPS_LIBLIST 0x70000000 - -/* I'm not sure what this is, but it's used on Irix 5. */ -#define SHT_MIPS_MSYM 0x70000001 - -/* Section contains list of symbols whose definitions conflict with - symbols defined in shared objects. */ -#define SHT_MIPS_CONFLICT 0x70000002 - -/* Section contains the global pointer table. */ -#define SHT_MIPS_GPTAB 0x70000003 - -/* Section contains microcode information. The exact format is - unspecified. */ -#define SHT_MIPS_UCODE 0x70000004 - -/* Section contains some sort of debugging information. The exact - format is unspecified. It's probably ECOFF symbols. */ -#define SHT_MIPS_DEBUG 0x70000005 - -/* Section contains register usage information. */ -#define SHT_MIPS_REGINFO 0x70000006 - -/* Section contains miscellaneous options (used on Irix). */ -#define SHT_MIPS_OPTIONS 0x7000000d - -/* DWARF debugging section (used on Irix 6). */ -#define SHT_MIPS_DWARF 0x7000001e - -/* Events section. This appears on Irix 6. I don't know what it - means. */ -#define SHT_MIPS_EVENTS 0x70000021 - -/* A section of type SHT_MIPS_LIBLIST contains an array of the - following structure. The sh_link field is the section index of the - string table. The sh_info field is the number of entries in the - section. */ -typedef struct -{ - /* String table index for name of shared object. */ - unsigned long l_name; - /* Time stamp. */ - unsigned long l_time_stamp; - /* Checksum of symbol names and common sizes. */ - unsigned long l_checksum; - /* String table index for version. */ - unsigned long l_version; - /* Flags. */ - unsigned long l_flags; -} Elf32_Lib; - -/* The l_flags field of an Elf32_Lib structure may contain the - following flags. */ - -/* Require an exact match at runtime. */ -#define LL_EXACT_MATCH 0x00000001 - -/* Ignore version incompatibilities at runtime. */ -#define LL_IGNORE_INT_VER 0x00000002 - -/* A section of type SHT_MIPS_CONFLICT is an array of indices into the - .dynsym section. Each element has the following type. */ -typedef unsigned long Elf32_Conflict; - -/* A section of type SHT_MIPS_GPTAB contains information about how - much GP space would be required for different -G arguments. This - information is only used so that the linker can provide informative - suggestions as to the best -G value to use. The sh_info field is - the index of the section for which this information applies. The - contents of the section are an array of the following union. The - first element uses the gt_header field. The remaining elements use - the gt_entry field. */ -typedef union -{ - struct - { - /* -G value actually used for this object file. */ - unsigned long gt_current_g_value; - /* Unused. */ - unsigned long gt_unused; - } gt_header; - struct - { - /* If this -G argument has been used... */ - unsigned long gt_g_value; - /* ...this many GP section bytes would be required. */ - unsigned long gt_bytes; - } gt_entry; -} Elf32_gptab; - -/* The external version of Elf32_gptab. */ - -typedef union -{ - struct - { - unsigned char gt_current_g_value[4]; - unsigned char gt_unused[4]; - } gt_header; - struct - { - unsigned char gt_g_value[4]; - unsigned char gt_bytes[4]; - } gt_entry; -} Elf32_External_gptab; - -/* A section of type SHT_MIPS_REGINFO contains the following - structure. */ -typedef struct -{ - /* Mask of general purpose registers used. */ - unsigned long ri_gprmask; - /* Mask of co-processor registers used. */ - unsigned long ri_cprmask[4]; - /* GP register value for this object file. */ - long ri_gp_value; -} Elf32_RegInfo; - -/* The external version of the Elf_RegInfo structure. */ -typedef struct -{ - unsigned char ri_gprmask[4]; - unsigned char ri_cprmask[4][4]; - unsigned char ri_gp_value[4]; -} Elf32_External_RegInfo; - -/* MIPS ELF .reginfo swapping routines. */ -extern void bfd_mips_elf32_swap_reginfo_in - PARAMS ((bfd *, const Elf32_External_RegInfo *, Elf32_RegInfo *)); -extern void bfd_mips_elf32_swap_reginfo_out - PARAMS ((bfd *, const Elf32_RegInfo *, Elf32_External_RegInfo *)); - -/* Processor specific section flags. */ - -/* This section must be in the global data area. */ -#define SHF_MIPS_GPREL 0x10000000 - -/* Processor specific program header types. */ - -/* Register usage information. Identifies one .reginfo section. */ -#define PT_MIPS_REGINFO 0x70000000 - -/* Runtime procedure table. */ -#define PT_MIPS_RTPROC 0x70000001 - -/* Processor specific dynamic array tags. */ - -/* 32 bit version number for runtime linker interface. */ -#define DT_MIPS_RLD_VERSION 0x70000001 - -/* Time stamp. */ -#define DT_MIPS_TIME_STAMP 0x70000002 - -/* Checksum of external strings and common sizes. */ -#define DT_MIPS_ICHECKSUM 0x70000003 - -/* Index of version string in string table. */ -#define DT_MIPS_IVERSION 0x70000004 - -/* 32 bits of flags. */ -#define DT_MIPS_FLAGS 0x70000005 - -/* Base address of the segment. */ -#define DT_MIPS_BASE_ADDRESS 0x70000006 - -/* Address of .conflict section. */ -#define DT_MIPS_CONFLICT 0x70000008 - -/* Address of .liblist section. */ -#define DT_MIPS_LIBLIST 0x70000009 - -/* Number of local global offset table entries. */ -#define DT_MIPS_LOCAL_GOTNO 0x7000000a - -/* Number of entries in the .conflict section. */ -#define DT_MIPS_CONFLICTNO 0x7000000b - -/* Number of entries in the .liblist section. */ -#define DT_MIPS_LIBLISTNO 0x70000010 - -/* Number of entries in the .dynsym section. */ -#define DT_MIPS_SYMTABNO 0x70000011 - -/* Index of first external dynamic symbol not referenced locally. */ -#define DT_MIPS_UNREFEXTNO 0x70000012 - -/* Index of first dynamic symbol in global offset table. */ -#define DT_MIPS_GOTSYM 0x70000013 - -/* Number of page table entries in global offset table. */ -#define DT_MIPS_HIPAGENO 0x70000014 - -/* Address of run time loader map, used for debugging. */ -#define DT_MIPS_RLD_MAP 0x70000016 - -/* Flags which may appear in a DT_MIPS_FLAGS entry. */ - -/* No flags. */ -#define RHF_NONE 0x00000000 - -/* Uses shortcut pointers. */ -#define RHF_QUICKSTART 0x00000001 - -/* Hash size is not a power of two. */ -#define RHF_NOTPOT 0x00000002 - -/* Ignore LD_LIBRARY_PATH. */ -#define RHS_NO_LIBRARY_REPLACEMENT \ - 0x00000004 - -/* Special values for the st_other field in the symbol table. These - are used in an Irix 5 dynamic symbol table. */ - -#define STO_DEFAULT 0x00 -#define STO_INTERNAL 0x01 -#define STO_HIDDEN 0x02 -#define STO_PROTECTED 0x03 - -#endif /* _ELF_MIPS_H */ diff --git a/contrib/gdb/include/elf/ppc.h b/contrib/gdb/include/elf/ppc.h deleted file mode 100644 index 1da118ddd84..00000000000 --- a/contrib/gdb/include/elf/ppc.h +++ /dev/null @@ -1,54 +0,0 @@ -/* PPC ELF support for BFD. - Copyright (C) 1995 Free Software Foundation, Inc. - - By Michael Meissner, Cygnus Support, , from information - in the System V Application Binary Interface, PowerPC Processor Supplement - and the PowerPC Embedded Application Binary Interface (eabi). - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file holds definitions specific to the PPC ELF ABI. Note - that most of this is not actually implemented by BFD. */ - -#ifndef _ELF_PPC_H -#define _ELF_PPC_H - -/* Processor specific flags for the ELF header e_flags field. */ - -#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ - - /* CYGNUS local bits below */ -#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag */ -#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib flag */ - -/* Processor specific section headers, sh_type field */ - -#define SHT_ORDERED SHT_HIPROC /* Link editor is to sort the \ - entries in this section \ - based on the address \ - specified in the associated \ - symbol table entry. */ - -/* Processor specific section flags, sh_flags field */ - -#define SHF_EXCLUDE 0x80000000 /* Link editor is to exclude \ - this section from executable \ - and shared objects that it \ - builds when those objects \ - are not to be furhter \ - relocated. */ -#endif /* _ELF_PPC_H */ diff --git a/contrib/gdb/include/elf/sparc.h b/contrib/gdb/include/elf/sparc.h deleted file mode 100644 index 84408e31add..00000000000 --- a/contrib/gdb/include/elf/sparc.h +++ /dev/null @@ -1,73 +0,0 @@ -/* SPARC ELF support for BFD. - Copyright (C) 1996 Free Software Foundation, Inc. - - By Doug Evans, Cygnus Support, . - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _ELF_SPARC_H -#define _ELF_SPARC_H - -/* Processor specific flags for the ELF header e_flags field. */ - -/* These are defined by Sun. */ - -#define EF_SPARC_32PLUS_MASK 0xffff00 /* bits indicating V8+ type */ -#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ - -/* Relocation types. */ - -enum elf_sparc_reloc_type { - R_SPARC_NONE = 0, - R_SPARC_8, R_SPARC_16, R_SPARC_32, - R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32, - R_SPARC_WDISP30, R_SPARC_WDISP22, - R_SPARC_HI22, R_SPARC_22, - R_SPARC_13, R_SPARC_LO10, - R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22, - R_SPARC_PC10, R_SPARC_PC22, - R_SPARC_WPLT30, - R_SPARC_COPY, - R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT, - R_SPARC_RELATIVE, - R_SPARC_UA32, - - /* ??? These 6 relocs are new but not currently used. For binary - compatility in the sparc64-elf toolchain, we leave them out. - A non-binary upward compatible change is expected for sparc64-elf. */ -#ifndef SPARC64_OLD_RELOCS - /* ??? New relocs on the UltraSPARC. Not sure what they're for yet. */ - R_SPARC_PLT32, R_SPARC_HIPLT22, R_SPARC_LOPLT10, - R_SPARC_PCPLT32, R_SPARC_PCPLT22, R_SPARC_PCPLT10, -#endif - - /* v9 relocs */ - R_SPARC_10, R_SPARC_11, R_SPARC_64, - R_SPARC_OLO10, R_SPARC_HH22, R_SPARC_HM10, R_SPARC_LM22, - R_SPARC_PC_HH22, R_SPARC_PC_HM10, R_SPARC_PC_LM22, - R_SPARC_WDISP16, R_SPARC_WDISP19, - R_SPARC_GLOB_JMP, - R_SPARC_7, -#ifndef SPARC64_OLD_RELOCS - R_SPARC_5, R_SPARC_6, -#endif - - R_SPARC_max -}; - -#endif /* _ELF_SPARC_H */ diff --git a/contrib/gdb/include/floatformat.h b/contrib/gdb/include/floatformat.h deleted file mode 100644 index 01e3dcb2944..00000000000 --- a/contrib/gdb/include/floatformat.h +++ /dev/null @@ -1,88 +0,0 @@ -/* IEEE floating point support declarations, for GDB, the GNU Debugger. - Copyright (C) 1991 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if !defined (FLOATFORMAT_H) -#define FLOATFORMAT_H 1 - -#include "ansidecl.h" - -/* A floatformat consists of a sign bit, an exponent and a mantissa. Once the - bytes are concatenated according to the byteorder flag, then each of those - fields is contiguous. We number the bits with 0 being the most significant - (i.e. BITS_BIG_ENDIAN type numbering), and specify which bits each field - contains with the *_start and *_len fields. */ - -enum floatformat_byteorders { floatformat_little, floatformat_big }; - -enum floatformat_intbit { floatformat_intbit_yes, floatformat_intbit_no }; - -struct floatformat -{ - enum floatformat_byteorders byteorder; - unsigned int totalsize; /* Total size of number in bits */ - - /* Sign bit is always one bit long. 1 means negative, 0 means positive. */ - unsigned int sign_start; - - unsigned int exp_start; - unsigned int exp_len; - /* Amount added to "true" exponent. 0x3fff for many IEEE extendeds. */ - unsigned int exp_bias; - /* Exponent value which indicates NaN. This is the actual value stored in - the float, not adjusted by the exp_bias. This usually consists of all - one bits. */ - unsigned int exp_nan; - - unsigned int man_start; - unsigned int man_len; - - /* Is the integer bit explicit or implicit? */ - enum floatformat_intbit intbit; -}; - -/* floatformats for IEEE single and double, big and little endian. */ - -extern const struct floatformat floatformat_ieee_single_big; -extern const struct floatformat floatformat_ieee_single_little; -extern const struct floatformat floatformat_ieee_double_big; -extern const struct floatformat floatformat_ieee_double_little; - -/* floatformats for various extendeds. */ - -extern const struct floatformat floatformat_i387_ext; -extern const struct floatformat floatformat_m68881_ext; -extern const struct floatformat floatformat_i960_ext; -extern const struct floatformat floatformat_m88110_ext; -extern const struct floatformat floatformat_arm_ext; - -/* Convert from FMT to a double. - FROM is the address of the extended float. - Store the double in *TO. */ - -extern void -floatformat_to_double PARAMS ((const struct floatformat *, char *, double *)); - -/* The converse: convert the double *FROM to FMT - and store where TO points. */ - -extern void -floatformat_from_double PARAMS ((const struct floatformat *, - double *, char *)); - -#endif /* defined (FLOATFORMAT_H) */ diff --git a/contrib/gdb/include/fopen-bin.h b/contrib/gdb/include/fopen-bin.h deleted file mode 100644 index b868f63d46d..00000000000 --- a/contrib/gdb/include/fopen-bin.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Macros for the 'type' part of an fopen, freopen or fdopen. - - [Update] - - This version is for "binary" systems, where text and binary files are - different. An example is Mess-Dose. Many Unix systems could also - cope with a "b" in the string, indicating binary files, but some reject this - (and thereby don't conform to ANSI C, but what else is new?). - - This file is designed for inclusion by host-dependent .h files. No - user application should include it directly, since that would make - the application unable to be configured for both "same" and "binary" - variant systems. */ - -#define FOPEN_RB "rb" -#define FOPEN_WB "wb" -#define FOPEN_AB "ab" -#define FOPEN_RUB "r+b" -#define FOPEN_WUB "w+b" -#define FOPEN_AUB "a+b" - -#define FOPEN_RT "r" -#define FOPEN_WT "w" -#define FOPEN_AT "a" -#define FOPEN_RUT "r+" -#define FOPEN_WUT "w+" -#define FOPEN_AUT "a+" diff --git a/contrib/gdb/include/fopen-same.h b/contrib/gdb/include/fopen-same.h deleted file mode 100644 index 0f37529d33e..00000000000 --- a/contrib/gdb/include/fopen-same.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Macros for the 'type' part of an fopen, freopen or fdopen. - - [Update] - - This version is for "same" systems, where text and binary files are - the same. An example is Unix. Many Unix systems could also add a - "b" to the string, indicating binary files, but some reject this - (and thereby don't conform to ANSI C, but what else is new?). - - This file is designed for inclusion by host-dependent .h files. No - user application should include it directly, since that would make - the application unable to be configured for both "same" and "binary" - variant systems. */ - -#define FOPEN_RB "r" -#define FOPEN_WB "w" -#define FOPEN_AB "a" -#define FOPEN_RUB "r+" -#define FOPEN_WUB "w+" -#define FOPEN_AUB "a+" - -#define FOPEN_RT "r" -#define FOPEN_WT "w" -#define FOPEN_AT "a" -#define FOPEN_RUT "r+" -#define FOPEN_WUT "w+" -#define FOPEN_AUT "a+" diff --git a/contrib/gdb/include/gdbm.h b/contrib/gdb/include/gdbm.h deleted file mode 100644 index 3ebc26d198a..00000000000 --- a/contrib/gdb/include/gdbm.h +++ /dev/null @@ -1,91 +0,0 @@ -/* GNU DBM - DataBase Manager include file - Copyright 1989, 1991 Free Software Foundation, Inc. - Written by Philip A. Nelson. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* You may contact the author by: - e-mail: phil@wwu.edu - us-mail: Philip A. Nelson - Computer Science Department - Western Washington University - Bellingham, WA 98226 - phone: (206) 676-3035 - -*************************************************************************/ - -/* Parameters to gdbm_open for READERS, WRITERS, and WRITERS who - can create the database. */ -#define GDBM_READER 0 -#define GDBM_WRITER 1 -#define GDBM_WRCREAT 2 -#define GDBM_NEWDB 3 - -/* Parameters to gdbm_store for simple insertion or replacement. */ -#define GDBM_INSERT 0 -#define GDBM_REPLACE 1 - - -/* The data and key structure. This structure is defined for compatibility. */ -typedef struct { - char *dptr; - int dsize; - } datum; - - -/* The file information header. This is good enough for most applications. */ -typedef struct {int dummy[10];} *GDBM_FILE; - - -/* These are the routines! */ - -extern GDBM_FILE gdbm_open (); - -extern void gdbm_close (); - -extern datum gdbm_fetch (); - -extern int gdbm_store (); - -extern int gdbm_delete (); - -extern datum gdbm_firstkey (); - -extern datum gdbm_nextkey (); - -extern int gdbm_reorganize (); - - -/* gdbm sends back the following error codes in the variable gdbm_errno. */ -typedef enum { NO_ERROR, - MALLOC_ERROR, - BLOCK_SIZE_ERROR, - FILE_OPEN_ERROR, - FILE_WRITE_ERROR, - FILE_SEEK_ERROR, - FILE_READ_ERROR, - BAD_MAGIC_NUMBER, - EMPTY_DATABASE, - CANT_BE_READER, - CANT_BE_WRITER, - READER_CANT_RECOVER, - READER_CANT_DELETE, - READER_CANT_STORE, - READER_CANT_REORGANIZE, - UNKNOWN_UPDATE, - ITEM_NOT_FOUND, - REORGANIZE_FAILED, - CANNOT_REPLACE} - gdbm_error; diff --git a/contrib/gdb/include/getopt.h b/contrib/gdb/include/getopt.h deleted file mode 100644 index abf91538320..00000000000 --- a/contrib/gdb/include/getopt.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License - as published by the Free Software Foundation; either version 2, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if __STDC__ -#if defined(__GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ -extern int getopt (); -#endif /* not __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/contrib/gdb/include/hp-symtab.h b/contrib/gdb/include/hp-symtab.h deleted file mode 100644 index 051c4c63ed2..00000000000 --- a/contrib/gdb/include/hp-symtab.h +++ /dev/null @@ -1,983 +0,0 @@ -/* Definitions and structures for reading debug symbols from the - native HP C compiler. - - Written by the Center for Software Science at the University of Utah - and by Cygnus Support. - - Copyright 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef HP_SYMTAB_INCLUDED -#define HP_SYMTAB_INCLUDED - -/* General information: - - This header file defines and describes only the basic data structures - necessary to read debug symbols produced by the HP C compiler using the - SOM object file format. Definitions and structures used by other compilers - for other languages or object file formats may be missing. - (For a full description of the debug format, ftp hpux-symtab.h from - jaguar.cs.utah.edu:/dist). - - - Debug symbols are contained entirely within an unloadable space called - $DEBUG$. $DEBUG$ contains several subspaces which group related - debug symbols. - - $GNTT$ contains information for global variables, types and contants. - - $LNTT$ contains information for procedures (including nesting), scoping - information, local variables, types, and constants. - - $SLT$ contains source line information so that code addresses may be - mapped to source lines. - - $VT$ contains various strings and constants for named objects (variables, - typedefs, functions, etc). Strings are stored as null-terminated character - lists. Constants always begin on word boundaries. The first byte of - the VT must be zero (a null string). - - $XT$ is not currently used by GDB. - - Many structures within the subspaces point to other structures within - the same subspace, or to structures within a different subspace. These - pointers are represented as a structure index from the beginning of - the appropriate subspace. */ - -/* Used to describe where a constant is stored. */ -enum location_type -{ - LOCATION_IMMEDIATE, - LOCATION_PTR, - LOCATION_VT, -}; - -/* Languages supported by this debug format. Within the data structures - this type is limited to 4 bits for a maximum of 16 languages. */ -enum hp_language -{ - HP_LANGUAGE_UNKNOWN, - HP_LANGUAGE_C, - HP_LANGUAGE_F77, - HP_LANGUAGE_PASCAL, - HP_LANGUAGE_COBOL, - HP_LANGUAGE_BASIC, - HP_LANGUAGE_ADA, - HP_LANGUAGE_CPLUSPLUS, -}; - - -/* Basic data types available in this debug format. Within the data - structures this type is limited to 5 bits for a maximum of 32 basic - data types. */ -enum hp_type -{ - HP_TYPE_UNDEFINED, - HP_TYPE_BOOLEAN, - HP_TYPE_CHAR, - HP_TYPE_INT, - HP_TYPE_UNSIGNED_INT, - HP_TYPE_REAL, - HP_TYPE_COMPLEX, - HP_TYPE_STRING200, - HP_TYPE_LONGSTRING200, - HP_TYPE_TEXT, - HP_TYPE_FLABEL, - HP_TYPE_FTN_STRING_SPEC, - HP_TYPE_MOD_STRING_SPEC, - HP_TYPE_PACKED_DECIMAL, - HP_TYPE_REAL_3000, - HP_TYPE_MOD_STRING_3000, - HP_TYPE_ANYPOINTER, - HP_TYPE_GLOBAL_ANYPOINTER, - HP_TYPE_LOCAL_ANYPOINTER, - HP_TYPE_COMPLEXS3000, - HP_TYPE_FTN_STRING_S300_COMPAT, - HP_TYPE_FTN_STRING_VAX_COMPAT, - HP_TYPE_BOOLEAN_S300_COMPAT, - HP_TYPE_BOOLEAN_VAX_COMPAT, - HP_TYPE_WIDE_CHAR, - HP_TYPE_LONG, - HP_TYPE_UNSIGNED_LONG, - HP_TYPE_DOUBLE, - HP_TYPE_TEMPLATE_ARG, -}; - -/* An immediate name and type table entry. - - extension and immediate will always be one. - global will always be zero. - hp_type is the basic type this entry describes. - bitlength is the length in bits for the basic type. */ -struct dnttp_immediate -{ - unsigned int extension: 1; - unsigned int immediate: 1; - unsigned int global: 1; - unsigned int type: 5; - unsigned int bitlength: 24; -}; - -/* A nonimmediate name and type table entry. - - extension will always be one. - immediate will always be zero. - if global is zero, this entry points into the LNTT - if global is one, this entry points into the GNTT - index is the index within the GNTT or LNTT for this entry. */ -struct dnttp_nonimmediate -{ - unsigned int extension: 1; - unsigned int immediate: 1; - unsigned int global: 1; - unsigned int index: 29; -}; - -/* A pointer to an entry in the GNTT and LNTT tables. It has two - forms depending on the type being described. - - The immediate form is used for simple entries and is one - word. - - The nonimmediate form is used for complex entries and contains - an index into the LNTT or GNTT which describes the entire type. - - If a dnttpointer is -1, then it is a NIL entry. */ - -#define DNTTNIL (-1) -typedef union dnttpointer -{ - struct dnttp_immediate dntti; - struct dnttp_nonimmediate dnttp; - int word; -} dnttpointer; - -/* An index into the source line table. As with dnttpointers, a sltpointer - of -1 indicates a NIL entry. */ -#define SLTNIL (-1) -typedef int sltpointer; - -/* Unsigned byte offset into the VT. */ -typedef unsigned int vtpointer; - -/* A DNTT entry (used within the GNTT and LNTT). - - DNTT entries are variable sized objects, but are always a multiple - of 3 words (we call each group of 3 words a "block"). - - The first bit in each block is an extension bit. This bit is zero - for the first block of a DNTT entry. If the entry requires more - than one block, then this bit is set to one in all blocks after - the first one. */ - -/* Each DNTT entry describes a particular debug symbol (beginning of - a source file, a function, variables, structures, etc. - - The type of the DNTT entry is stored in the "kind" field within the - DNTT entry itself. */ - -enum dntt_entry_type -{ - DNTT_TYPE_NIL = -1, - DNTT_TYPE_SRCFILE, - DNTT_TYPE_MODULE, - DNTT_TYPE_FUNCTION, - DNTT_TYPE_ENTRY, - DNTT_TYPE_BEGIN, - DNTT_TYPE_END, - DNTT_TYPE_IMPORT, - DNTT_TYPE_LABEL, - DNTT_TYPE_FPARAM, - DNTT_TYPE_SVAR, - DNTT_TYPE_DVAR, - DNTT_TYPE_HOLE1, - DNTT_TYPE_CONST, - DNTT_TYPE_TYPEDEF, - DNTT_TYPE_TAGDEF, - DNTT_TYPE_POINTER, - DNTT_TYPE_ENUM, - DNTT_TYPE_MEMENUM, - DNTT_TYPE_SET, - DNTT_TYPE_SUBRANGE, - DNTT_TYPE_ARRAY, - DNTT_TYPE_STRUCT, - DNTT_TYPE_UNION, - DNTT_TYPE_FIELD, - DNTT_TYPE_VARIANT, - DNTT_TYPE_FILE, - DNTT_TYPE_FUNCTYPE, - DNTT_TYPE_WITH, - DNTT_TYPE_COMMON, - DNTT_TYPE_COBSTRUCT, - DNTT_TYPE_XREF, - DNTT_TYPE_SA, - DNTT_TYPE_MACRO, - DNTT_TYPE_BLOCKDATA, - DNTT_TYPE_CLASS_SCOPE, - DNTT_TYPE_REFERENCE, - DNTT_TYPE_PTRMEM, - DNTT_TYPE_PTRMEMFUNC, - DNTT_TYPE_CLASS, - DNTT_TYPE_GENFIELD, - DNTT_TYPE_VFUNC, - DNTT_TYPE_MEMACCESS, - DNTT_TYPE_INHERITANCE, - DNTT_TYPE_FRIEND_CLASS, - DNTT_TYPE_FRIEND_FUNC, - DNTT_TYPE_MODIFIER, - DNTT_TYPE_OBJECT_ID, - DNTT_TYPE_MEMFUNC, - DNTT_TYPE_TEMPLATE, - DNTT_TYPE_TEMPLATE_ARG, - DNTT_TYPE_FUNC_TEMPLATE, - DNTT_TYPE_LINK, - DNTT_TYPE_MAX, -}; - -/* DNTT_TYPE_SRCFILE: - - One DNTT_TYPE_SRCFILE symbol is output for the start of each source - file and at the begin and end of an included file. A DNTT_TYPE_SRCFILE - entry is also output before each DNTT_TYPE_FUNC symbol so that debuggers - can determine what file a function was defined in. - - LANGUAGE describes the source file's language. - - NAME points to an VT entry providing the source file's name. - - Note the name used for DNTT_TYPE_SRCFILE entries are exactly as seen - by the compiler (ie they may be relative or absolute). C include files - via <> inclusion must use absolute paths. - - ADDRESS points to an SLT entry from which line number and code locations - may be determined. */ - -struct dntt_type_srcfile -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int language: 4; - unsigned int unused: 17; - vtpointer name; - sltpointer address; -}; - -/* DNTT_TYPE_MODULE: - - A DNTT_TYPE_MODULE symbol is emitted for the start of a pascal - module or C source file. - - Each DNTT_TYPE_MODULE must have an associated DNTT_TYPE_END symbol. - - NAME points to a VT entry providing the module's name. Note C - source files are considered nameless modules. - - ALIAS point to a VT entry providing a secondary name. - - ADDRESS points to an SLT entry from which line number and code locations - may be determined. */ - -struct dntt_type_module -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int unused: 21; - vtpointer name; - vtpointer alias; - dnttpointer unused2; - sltpointer address; -}; - -/* DNTT_TYPE_FUNCTION: - - A DNTT_TYPE_FUNCTION symbol is emitted for each function definition; - a DNTT_TYPE_ENTRY symbols is used for secondary entry points. Both - symbols used the dntt_type_function structure. - - Each DNTT_TYPE_FUNCTION must have a matching DNTT_TYPE_END. - - GLOBAL is nonzero if the function has global scope. - - LANGUAGE describes the function's source language. - - OPT_LEVEL describes the optimization level the function was compiled - with. - - VARARGS is nonzero if the function uses varargs. - - NAME points to a VT entry providing the function's name. - - ALIAS points to a VT entry providing a secondary name for the function. - - FIRSTPARAM points to a LNTT entry which describes the parameter list. - - ADDRESS points to an SLT entry from which line number and code locations - may be determined. - - ENTRYADDR is the memory address corresponding the the function's entry point - - RETVAL points to a LNTT entry describing the function's return value. - - LOWADDR is the lowest memory address associated with this function. - - HIADDR is the highest memory address associated with this function. */ - -struct dntt_type_function -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int global: 1; - unsigned int language: 4; - unsigned int nest_level: 5; - unsigned int opt_level: 2; - unsigned int varargs: 1; - unsigned int lang_info: 4; - unsigned int inlined: 1; - unsigned int localalloc: 1; - unsigned int expansion: 1; - unsigned int unused: 1; - vtpointer name; - vtpointer alias; - dnttpointer firstparam; - sltpointer address; - CORE_ADDR entryaddr; - dnttpointer retval; - CORE_ADDR lowaddr; - CORE_ADDR hiaddr; -}; - -/* DNTT_TYPE_BEGIN: - - A DNTT_TYPE_BEGIN symbol is emitted to begin a new nested scope. - Every DNTT_TYPE_BEGIN symbol must have a matching DNTT_TYPE_END symbol. - - CLASSFLAG is nonzero if this is the beginning of a c++ class definition. - - ADDRESS points to an SLT entry from which line number and code locations - may be determined. */ - -struct dntt_type_begin -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int classflag: 1; - unsigned int unused: 20; - sltpointer address; -}; - -/* DNTT_TYPE_END: - - A DNTT_TYPE_END symbol is emitted when closing a scope started by - a DNTT_TYPE_MODULE, DNTT_TYPE_FUNCTION, and DNTT_TYPE_BEGIN symbols. - - ENDKIND describes what type of scope the DNTT_TYPE_END is closing - (DNTT_TYPE_MODULE, DNTT_TYPE_BEGIN, etc). - - CLASSFLAG is nonzero if this is the end of a c++ class definition. - - ADDRESS points to an SLT entry from which line number and code locations - may be determined. - - BEGINSCOPE points to the LNTT entry which opened the scope. */ - -struct dntt_type_end -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int endkind: 10; - unsigned int classflag: 1; - unsigned int unused: 10; - sltpointer address; - dnttpointer beginscope; -}; - -/* DNTT_TYPE_IMPORT is unused by GDB. */ -/* DNTT_TYPE_LABEL is unused by GDB. */ - -/* DNTT_TYPE_FPARAM: - - A DNTT_TYPE_FPARAM symbol is emitted for a function argument. When - chained together the symbols represent an argument list for a function. - - REGPARAM is nonzero if this parameter was passed in a register. - - INDIRECT is nonzero if this parameter is a pointer to the parameter - (pass by reference or pass by value for large items). - - LONGADDR is nonzero if the parameter is a 64bit pointer. - - NAME is a pointer into the VT for the parameter's name. - - LOCATION describes where the parameter is stored. Depending on the - parameter type LOCATION could be a register number, or an offset - from the stack pointer. - - TYPE points to a NTT entry describing the type of this parameter. - - NEXTPARAM points to the LNTT entry describing the next parameter. */ - -struct dntt_type_fparam -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int regparam: 1; - unsigned int indirect: 1; - unsigned int longaddr: 1; - unsigned int copyparam: 1; - unsigned int dflt: 1; - unsigned int unused: 16; - vtpointer name; - int location; - dnttpointer type; - dnttpointer nextparam; - int misc; -}; - -/* DNTT_TYPE_SVAR: - - A DNTT_TYPE_SVAR is emitted to describe a variable in static storage. - - GLOBAL is nonzero if the variable has global scope. - - INDIRECT is nonzero if the variable is a pointer to an object. - - LONGADDR is nonzero if the variable is in long pointer space. - - STATICMEM is nonzero if the variable is a member of a class. - - A_UNION is nonzero if the variable is an anonymous union member. - - NAME is a pointer into the VT for the variable's name. - - LOCATION provides the memory address for the variable. - - TYPE is a pointer into either the GNTT or LNTT which describes - the type of this variable. */ - -struct dntt_type_svar -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int global: 1; - unsigned int indirect: 1; - unsigned int longaddr: 1; - unsigned int staticmem: 1; - unsigned int a_union: 1; - unsigned int unused: 16; - vtpointer name; - CORE_ADDR location; - dnttpointer type; - unsigned int offset; - unsigned int displacement; -}; - -/* DNTT_TYPE_DVAR: - - A DNTT_TYPE_DVAR is emitted to describe automatic variables and variables - held in registers. - - GLOBAL is nonzero if the variable has global scope. - - INDIRECT is nonzero if the variable is a pointer to an object. - - REGVAR is nonzero if the variable is in a register. - - A_UNION is nonzero if the variable is an anonymous union member. - - NAME is a pointer into the VT for the variable's name. - - LOCATION provides the memory address or register number for the variable. - - TYPE is a pointer into either the GNTT or LNTT which describes - the type of this variable. */ - -struct dntt_type_dvar -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int global: 1; - unsigned int indirect: 1; - unsigned int regvar: 1; - unsigned int a_union: 1; - unsigned int unused: 17; - vtpointer name; - int location; - dnttpointer type; - unsigned int offset; -}; - -/* DNTT_TYPE_CONST: - - A DNTT_TYPE_CONST symbol is emitted for program constants. - - GLOBAL is nonzero if the constant has global scope. - - INDIRECT is nonzero if the constant is a pointer to an object. - - LOCATION_TYPE describes where to find the constant's value - (in the VT, memory, or embedded in an instruction). - - CLASSMEM is nonzero if the constant is a member of a class. - - NAME is a pointer into the VT for the constant's name. - - LOCATION provides the memory address, register number or pointer - into the VT for the constant's value. - - TYPE is a pointer into either the GNTT or LNTT which describes - the type of this variable. */ - -struct dntt_type_const -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int global: 1; - unsigned int indirect: 1; - unsigned int: 3; - unsigned int classmem: 1; - unsigned int unused: 15; - vtpointer name; - CORE_ADDR location; - dnttpointer type; - unsigned int offset; - unsigned int displacement; -}; - -/* DNTT_TYPE_TYPEDEF and DNTT_TYPE_TAGDEF: - - The same structure is used to describe typedefs and tagdefs. - - DNTT_TYPE_TYPEDEFS are associated with C "typedefs". - - DNTT_TYPE_TAGDEFs are associated with C "struct", "union", and "enum" - tags, which may have the same name as a typedef in the same scope. - - GLOBAL is nonzero if the typedef/tagdef has global scope. - - TYPEINFO is used to determine if full type information is available - for a tag. (usually 1, but can be zero for opaque types in C). - - NAME is a pointer into the VT for the constant's name. - - TYPE points to the underlying type for the typedef/tagdef in the - GNTT or LNTT. */ - -struct dntt_type_type -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int global: 1; - unsigned int typeinfo: 1; - unsigned int unused: 19; - vtpointer name; - dnttpointer type; -}; - -/* DNTT_TYPE_POINTER: - - Used to describe a pointer to an underlying type. - - POINTSTO is a pointer into the GNTT or LNTT for the type which this - pointer points to. - - BITLENGTH is the length of the pointer (not the underlying type). */ - -struct dntt_type_pointer -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int unused: 21; - dnttpointer pointsto; - unsigned int bitlength; -}; - - -/* DNTT_TYPE_ENUM: - - Used to describe enumerated types. - - FIRSTMEM is a pointer to a DNTT_TYPE_MEMENUM in the GNTT/LNTT which - describes the first member (and contains a pointer to the chain of - members). - - BITLENGTH is the number of bits used to hold the values of the enum's - members. */ - -struct dntt_type_enum -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int unused: 21; - dnttpointer firstmem; - unsigned int bitlength; -}; - -/* DNTT_TYPE_MEMENUM - - Used to describe members of an enumerated type. - - CLASSMEM is nonzero if this member is part of a class. - - NAME points into the VT for the name of this member. - - VALUE is the value of this enumeration member. - - NEXTMEM points to the next DNTT_TYPE_MEMENUM in the chain. */ - -struct dntt_type_memenum -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int classmem: 1; - unsigned int unused: 20; - vtpointer name; - unsigned int value; - dnttpointer nextmem; -}; - -/* DNTT_TYPE_SET - - DECLARATION describes the bitpacking of the set. - - SUBTYPE points to a DNTT entry describing the type of the members. - - BITLENGTH is the size of the set. */ - -struct dntt_type_set -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int declaration: 2; - unsigned int unused: 19; - dnttpointer subtype; - unsigned int bitlength; -}; - -/* DNTT_TYPE_SUBRANGE - - DYN_LOW describes the lower bound of the subrange: - - 00 for a constant lower bound (found in LOWBOUND). - - 01 for a dynamic lower bound with the lower bound found in the the - memory address pointed to by LOWBOUND. - - 10 for a dynamic lower bound described by an variable found in the - DNTT/LNTT (LOWBOUND would be a pointer into the DNTT/LNTT). - - DYN_HIGH is similar to DYN_LOW, except it describes the upper bound. - - SUBTYPE points to the type of the subrange. - - BITLENGTH is the length in bits needed to describe the subrange's - values. */ - -struct dntt_type_subrange -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int dyn_low: 2; - unsigned int dyn_high: 2; - unsigned int unused: 17; - int lowbound; - int highbound; - dnttpointer subtype; - unsigned int bitlength; -}; - -/* DNTT_TYPE_ARRAY - - DECLARATION describes the bit packing used in the array. - - ARRAYISBYTES is nonzero if the field in arraylength describes the - length in bytes rather than in bits. A value of zero is used to - describe an array with size 2**32. - - ELEMISBYTES is nonzero if the length if each element in the array - is describes in bytes rather than bits. A value of zero is used - to an element with size 2**32. - - ELEMORDER is nonzero if the elements are indexed in increasing order. - - JUSTIFIED if the elements are left justified to index zero. - - ARRAYLENGTH is the length of the array. - - INDEXTYPE is a DNTT pointer to the type used to index the array. - - ELEMTYPE is a DNTT pointer to the type for the array elements. - - ELEMLENGTH is the length of each element in the array (including - any padding). - - Multi-dimensional arrays are represented by ELEMTYPE pointing to - another DNTT_TYPE_ARRAY. */ - -struct dntt_type_array -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int declaration: 2; - unsigned int dyn_low: 2; - unsigned int dyn_high: 2; - unsigned int arrayisbytes: 1; - unsigned int elemisbytes: 1; - unsigned int elemorder: 1; - unsigned int justified: 1; - unsigned int unused: 11; - unsigned int arraylength; - dnttpointer indextype; - dnttpointer elemtype; - unsigned int elemlength; -}; - -/* DNTT_TYPE_STRUCT - - DNTT_TYPE_STRUCT is used to describe a C structure. - - DECLARATION describes the bitpacking used. - - FIRSTFIELD is a DNTT pointer to the first field of the structure - (each field contains a pointer to the next field, walk the list - to access all fields of the structure). - - VARTAGFIELD and VARLIST are used for Pascal variant records. - - BITLENGTH is the size of the structure in bits. */ - -struct dntt_type_struct -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int declaration: 2; - unsigned int unused: 19; - dnttpointer firstfield; - dnttpointer vartagfield; - dnttpointer varlist; - unsigned int bitlength; -}; - -/* DNTT_TYPE_UNION - - DNTT_TYPE_UNION is used to describe a C union. - - FIRSTFIELD is a DNTT pointer to the beginning of the field chain. - - BITLENGTH is the size of the union in bits. */ - -struct dntt_type_union -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int unused: 21; - dnttpointer firstfield; - unsigned int bitlength; -}; - -/* DNTT_TYPE_FIELD - - DNTT_TYPE_FIELD describes one field in a structure or union. - - VISIBILITY is used to describe the visibility of the field - (for c++. public = 0, protected = 1, private = 2). - - A_UNION is nonzero if this field is a member of an anonymous union. - - STATICMEM is nonzero if this field is a static member of a template. - - NAME is a pointer into the VT for the name of the field. - - BITOFFSET gives the offset of this field in bits from the beginning - of the structure or union this field is a member of. - - TYPE is a DNTT pointer to the type describing this field. - - BITLENGTH is the size of the entry in bits. - - NEXTFIELD is a DNTT pointer to the next field in the chain. */ - -struct dntt_type_field -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int visibility: 2; - unsigned int a_union: 1; - unsigned int staticmem: 1; - unsigned int unused: 17; - vtpointer name; - unsigned int bitoffset; - dnttpointer type; - unsigned int bitlength; - dnttpointer nextfield; -}; - -/* DNTT_TYPE_VARIANT is unused by GDB. */ -/* DNTT_TYPE_FILE is unused by GDB. */ - -/* DNTT_TYPE_COMMON is unused by GDB. */ -/* DNTT_TYPE_LINK is unused by GDB. */ -/* DNTT_TYPE_FFUNC_LINK is unused by GDB. */ -/* DNTT_TYPE_TEMPLATE is unused by GDB. */ - -/* DNTT_TYPE_FUNCTYPE - - VARARGS is nonzero if this function uses varargs. - - FIRSTPARAM is a DNTT pointer to the first entry in the parameter - chain. - - RETVAL is a DNTT pointer to the type of the return value. */ - -struct dntt_type_functype -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int varargs: 1; - unsigned int info: 4; - unsigned int unused: 16; - unsigned int bitlength; - dnttpointer firstparam; - dnttpointer retval; -}; - -/* DNTT_TYPE_WITH is unued by GDB. */ -/* DNTT_TYPE_COBSTRUCT is unused by GDB. */ -/* DNTT_TYPE_MODIFIER is unused by GDB. */ -/* DNTT_TYPE_GENFIELD is unused by GDB. */ -/* DNTT_TYPE_MEMACCESS is unused by GDB. */ -/* DNTT_TYPE_VFUNC is unused by GDB. */ -/* DNTT_TYPE_CLASS_SCOPE is unused by GDB. */ -/* DNTT_TYPE_FRIEND_CLASS is unused by GDB. */ -/* DNTT_TYPE_FRIEND_FUNC is unused by GDB. */ -/* DNTT_TYPE_CLASS unused by GDB. */ -/* DNTT_TYPE_TEMPLATE unused by GDB. */ -/* DNTT_TYPE_TEMPL_ARG is unused by GDB. */ -/* DNTT_TYPE_PTRMEM not used by GDB */ -/* DNTT_TYPE_INHERITANCE is unused by GDB. */ -/* DNTT_TYPE_OBJECT_ID is unused by GDB. */ -/* DNTT_TYPE_XREF is unused by GDB. */ -/* DNTT_TYPE_SA is unused by GDB. */ - -/* DNTT_TYPE_GENERIC and DNTT_TYPE_BLOCK are convience structures - so we can examine a DNTT entry in a generic fashion. */ -struct dntt_type_generic -{ - unsigned int word[9]; -}; - -struct dntt_type_block -{ - unsigned int extension: 1; - unsigned int kind: 10; - unsigned int unused: 21; - unsigned int word[2]; -}; - -/* One entry in a DNTT (either the LNTT or GNTT). */ -union dnttentry -{ - struct dntt_type_srcfile dsfile; - struct dntt_type_module dmodule; - struct dntt_type_function dfunc; - struct dntt_type_function dentry; - struct dntt_type_begin dbegin; - struct dntt_type_end dend; - struct dntt_type_fparam dfparam; - struct dntt_type_svar dsvar; - struct dntt_type_dvar ddvar; - struct dntt_type_const dconst; - struct dntt_type_type dtype; - struct dntt_type_type dtag; - struct dntt_type_pointer dptr; - struct dntt_type_enum denum; - struct dntt_type_memenum dmember; - struct dntt_type_set dset; - struct dntt_type_subrange dsubr; - struct dntt_type_array darray; - struct dntt_type_struct dstruct; - struct dntt_type_union dunion; - struct dntt_type_field dfield; - struct dntt_type_functype dfunctype; - struct dntt_type_generic dgeneric; - struct dntt_type_block dblock; -}; - -/* Source line entry types. */ -enum slttype -{ - SLT_NORMAL, - SLT_SRCFILE, - SLT_MODULE, - SLT_FUNCTION, - SLT_ENTRY, - SLT_BEGIN, - SLT_END, - SLT_WITH, - SLT_EXIT, - SLT_ASSIST, - SLT_MARKER, -}; - -/* A normal source line entry. Simply provides a mapping of a source - line number to a code address. - - SLTDESC will always be SLT_NORMAL or SLT_EXIT. */ - -struct slt_normal -{ - unsigned int sltdesc: 4; - unsigned int line: 28; - CORE_ADDR address; -}; - -/* A special source line entry. Provides a mapping of a declaration - to a line number. These entries point back into the DNTT which - references them. */ - -struct slt_special -{ - unsigned int sltdesc: 4; - unsigned int line: 28; - dnttpointer backptr; -}; - -/* Used to describe nesting. - - For nested languages, an slt_assist entry must follow each SLT_FUNC - entry in the SLT. The address field will point forward to the - first slt_normal entry within the function's scope. */ - -struct slt_assist -{ - unsigned int sltdesc: 4; - unsigned int unused: 28; - sltpointer address; -}; - -struct slt_generic -{ - unsigned int word[2]; -}; - -union sltentry -{ - struct slt_normal snorm; - struct slt_special sspec; - struct slt_assist sasst; - struct slt_generic sgeneric; -}; - -#endif /* HP_SYMTAB_INCLUDED */ diff --git a/contrib/gdb/include/ieee.h b/contrib/gdb/include/ieee.h deleted file mode 100644 index 5ade39d33e3..00000000000 --- a/contrib/gdb/include/ieee.h +++ /dev/null @@ -1,139 +0,0 @@ -/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file - Contributed by Cygnus Support. */ - -#define N_W_VARIABLES 8 -#define Module_Beginning 0xe0 - -typedef struct ieee_module { - char *processor; - char *module_name; -} ieee_module_begin_type; - -#define Address_Descriptor 0xec -typedef struct ieee_address { -bfd_vma number_of_bits_mau; - bfd_vma number_of_maus_in_address; - - unsigned char byte_order; -#define IEEE_LITTLE 0xcc -#define IEEE_BIG 0xcd -} ieee_address_descriptor_type; - -typedef union ieee_w_variable { - file_ptr offset[N_W_VARIABLES]; - struct { - file_ptr extension_record; - file_ptr environmental_record; - file_ptr section_part; - file_ptr external_part; - file_ptr debug_information_part; - file_ptr data_part; - file_ptr trailer_part; - file_ptr me_record; - } r; -} ieee_w_variable_type; - - - - - -typedef enum ieee_record -{ - ieee_number_start_enum = 0x00, - ieee_number_end_enum=0x7f, - ieee_number_repeat_start_enum = 0x80, - ieee_number_repeat_end_enum = 0x88, - ieee_number_repeat_4_enum = 0x84, - ieee_number_repeat_3_enum = 0x83, - ieee_number_repeat_2_enum = 0x82, - ieee_number_repeat_1_enum = 0x81, - ieee_module_beginning_enum = 0xe0, - ieee_module_end_enum = 0xe1, - ieee_extension_length_1_enum = 0xde, - ieee_extension_length_2_enum = 0xdf, - ieee_section_type_enum = 0xe6, - ieee_section_alignment_enum = 0xe7, - ieee_external_symbol_enum = 0xe8, - ieee_comma = 0x90, - ieee_external_reference_enum = 0xe9, - ieee_set_current_section_enum = 0xe5, - ieee_address_descriptor_enum = 0xec, - ieee_load_constant_bytes_enum = 0xed, - ieee_load_with_relocation_enum = 0xe4, - - ieee_variable_A_enum = 0xc1, - ieee_variable_B_enum = 0xc2, - ieee_variable_C_enum = 0xc3, - ieee_variable_D_enum = 0xc4, - ieee_variable_E_enum = 0xc5, - ieee_variable_F_enum = 0xc6, - ieee_variable_G_enum = 0xc7, - ieee_variable_H_enum = 0xc8, - ieee_variable_I_enum = 0xc9, - ieee_variable_J_enum = 0xca, - ieee_variable_K_enum = 0xcb, - ieee_variable_L_enum = 0xcc, - ieee_variable_M_enum = 0xcd, - ieee_variable_N_enum = 0xce, - ieee_variable_O_enum = 0xcf, - ieee_variable_P_enum = 0xd0, - ieee_variable_Q_enum = 0xd1, - ieee_variable_R_enum = 0xd2, - ieee_variable_S_enum = 0xd3, - ieee_variable_T_enum = 0xd4, - ieee_variable_U_enum = 0xd5, - ieee_variable_V_enum = 0xd6, - ieee_variable_W_enum = 0xd7, - ieee_variable_X_enum = 0xd8, - ieee_variable_Y_enum = 0xd9, - ieee_variable_Z_enum = 0xda, - ieee_function_plus_enum = 0xa5, - ieee_function_minus_enum = 0xa6, - ieee_function_signed_open_b_enum = 0xba, - ieee_function_signed_close_b_enum = 0xbb, - - ieee_function_unsigned_open_b_enum = 0xbc, - ieee_function_unsigned_close_b_enum = 0xbd, - - ieee_function_either_open_b_enum = 0xbe, - ieee_function_either_close_b_enum = 0xbf, - ieee_record_seperator_enum = 0xdb, - - ieee_e2_first_byte_enum = 0xe2, - ieee_section_size_enum = 0xe2d3, - ieee_physical_region_size_enum = 0xe2c1, - ieee_region_base_address_enum = 0xe2c2, - ieee_mau_size_enum = 0xe2c6, - ieee_m_value_enum = 0xe2cd, - ieee_section_base_address_enum = 0xe2cc, - ieee_asn_record_enum = 0xe2ce, - ieee_section_offset_enum = 0xe2d2, - ieee_value_starting_address_enum = 0xe2c7, - ieee_assign_value_to_variable_enum = 0xe2d7, - ieee_set_current_pc_enum = 0xe2d0, - ieee_value_record_enum = 0xe2c9, - ieee_nn_record = 0xf0, - ieee_at_record_enum = 0xf1, - ieee_ty_record_enum = 0xf2, - ieee_attribute_record_enum = 0xf1c9, - ieee_atn_record_enum = 0xf1ce, - ieee_external_reference_info_record_enum = 0xf1d8, - ieee_weak_external_reference_enum= 0xf4, - ieee_repeat_data_enum = 0xf7, - ieee_bb_record_enum = 0xf8, - ieee_be_record_enum = 0xf9 -} ieee_record_enum_type; - - -typedef struct ieee_section { - unsigned int section_index; - unsigned int section_type; - char *section_name; - unsigned int parent_section_index; - unsigned int sibling_section_index; - unsigned int context_index; -} ieee_section_type; -#define IEEE_REFERENCE_BASE 11 -#define IEEE_PUBLIC_BASE 32 -#define IEEE_SECTION_NUMBER_BASE 1 - diff --git a/contrib/gdb/include/libiberty.h b/contrib/gdb/include/libiberty.h deleted file mode 100644 index dc083c8fe38..00000000000 --- a/contrib/gdb/include/libiberty.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Function declarations for libiberty. - Written by Cygnus Support, 1994. - - The libiberty library provides a number of functions which are - missing on some operating systems. We do not declare those here, - to avoid conflicts with the system header files on operating - systems that do support those functions. In this file we only - declare those functions which are specific to libiberty. */ - -#ifndef LIBIBERTY_H -#define LIBIBERTY_H - -#include "ansidecl.h" - -/* Build an argument vector from a string. Allocates memory using - malloc. Use freeargv to free the vector. */ - -extern char **buildargv PARAMS ((char *)); - -/* Free a vector returned by buildargv. */ - -extern void freeargv PARAMS ((char **)); - -/* Return the last component of a path name. */ - -extern char *basename (); - -/* Concatenate an arbitrary number of strings, up to (char *) NULL. - Allocates memory using xmalloc. */ - -extern char *concat PARAMS ((const char *, ...)); - -/* Check whether two file descriptors refer to the same file. */ - -extern int fdmatch PARAMS ((int fd1, int fd2)); - -/* Get the amount of time the process has run, in microseconds. */ - -extern long get_run_time PARAMS ((void)); - -/* Allocate memory filled with spaces. Allocates using malloc. */ - -extern const char *spaces PARAMS ((int count)); - -/* Return the maximum error number for which strerror will return a - string. */ - -extern int errno_max PARAMS ((void)); - -/* Return the name of an errno value (e.g., strerrno (EINVAL) returns - "EINVAL"). */ - -extern const char *strerrno PARAMS ((int)); - -/* Given the name of an errno value, return the value. */ - -extern int strtoerrno PARAMS ((const char *)); - -/* ANSI's strerror(), but more robust. */ - -extern char *xstrerror PARAMS ((int)); - -/* Return the maximum signal number for which strsignal will return a - string. */ - -extern int signo_max PARAMS ((void)); - -/* Return a signal message string for a signal number - (e.g., strsignal (SIGHUP) returns something like "Hangup"). */ -/* This is commented out as it can conflict with one in system headers. - We still document its existence though. */ - -/*extern const char *strsignal PARAMS ((int));*/ - -/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns - "SIGHUP"). */ - -extern const char *strsigno PARAMS ((int)); - -/* Given the name of a signal, return its number. */ - -extern int strtosigno PARAMS ((const char *)); - -/* Register a function to be run by xexit. Returns 0 on success. */ - -extern int xatexit PARAMS ((void (*fn) (void))); - -/* Exit, calling all the functions registered with xatexit. */ - -#ifndef __GNUC__ -extern void xexit PARAMS ((int status)); -#else -typedef void libiberty_voidfn PARAMS ((int status)); -__volatile__ libiberty_voidfn xexit; -#endif - -/* Set the program name used by xmalloc. */ - -extern void xmalloc_set_program_name PARAMS ((const char *)); - -/* Allocate memory without fail. If malloc fails, this will print a - message to stderr (using the name set by xmalloc_set_program_name, - if any) and then call xexit. - - FIXME: We do not declare the parameter type (size_t) in order to - avoid conflicts with other declarations of xmalloc that exist in - programs which use libiberty. */ - -extern PTR xmalloc (); - -/* Reallocate memory without fail. This works like xmalloc. - - FIXME: We do not declare the parameter types for the same reason as - xmalloc. */ - -extern PTR xrealloc (); - -/* Copy a string into a memory buffer without fail. */ - -extern char *xstrdup PARAMS ((const char *)); - -/* hex character manipulation routines */ - -#define _hex_array_size 256 -#define _hex_bad 99 -extern char _hex_value[_hex_array_size]; -extern void hex_init PARAMS ((void)); -#define hex_p(c) (hex_value (c) != _hex_bad) -/* If you change this, note well: Some code relies on side effects in - the argument being performed exactly once. */ -#define hex_value(c) (_hex_value[(unsigned char) (c)]) - -#endif /* ! defined (LIBIBERTY_H) */ diff --git a/contrib/gdb/include/mpw/ChangeLog b/contrib/gdb/include/mpw/ChangeLog deleted file mode 100644 index 8dbad87eab4..00000000000 --- a/contrib/gdb/include/mpw/ChangeLog +++ /dev/null @@ -1,61 +0,0 @@ -Tue Feb 27 12:23:04 1996 Raymond Jou - - * mpw.h (HAVE_VPRINTF): Add and define to have the value 1. - -Fri Dec 29 14:40:46 1995 Stan Shebs - - * mpw.h (HAVE_STDLIB_H, etc): Define to have the value 1. - (HAVE_FCNTL_H): Define. - -Mon Dec 11 15:39:06 1995 Stan Shebs - - * mpw.h (open, access): Define as mpw_open and mpw_access. - -Thu Nov 9 15:38:37 1995 Stan Shebs - - * mpw.h: Include unix.h if USE_MW_HEADERS, otherwise include - various original MPW include files (ioctl.h, etc). - (EIO): Define if not defined. - * sys/ioctl.h: Remove, not needed. - -Wed Oct 25 12:30:44 1995 Stan Shebs - - * mpw.h: Don't include errno.h or ioctl.h. - (ENOENT, EACCES, ENOSYS): Define if not defined. - (fdopen): Declare if __STDC__. - (R_OK, W_OK, X_OK): Define if not defined. - -Tue Sep 26 14:57:21 1995 Stan Shebs - - * mpw.h: New file, universally useful MPW host definitions. - Many of these used to live in bfd/hosts/mpw.h. - * grp.h: Remove RCS comment. - * sys/ioctl.h: Add a comment line. - -Wed Dec 14 13:12:14 1994 Stan Shebs - - * spin.h: New file, cursor spinning for progress. - -Thu Jun 30 15:32:07 1994 Stan Shebs (shebs@andros.cygnus.com) - - * fcntl.h (open): Allow optional third arg. - -Thu Apr 14 12:54:51 1994 Stan Shebs (shebs@andros.cygnus.com) - - * dir.h, dirent.h, fcntl.h, grp.h, pwd.h, stat.h: New files. - * sys/ioctl.h: New file. - -Mon Feb 21 09:44:45 1994 Stan Shebs (shebs@andros.cygnus.com) - - * sys/stat.h (struct stat): New field st_rsize. - (S_IFMT, etc): Use different bit positions. - (fstat): Add parameter names to prototype. - -Mon Jan 31 19:30:16 1994 Stan Shebs (shebs@andros.cygnus.com) - - * README: New file. - * utime.h, varargs.h: New files, simulated Posix. - * sys/{file,param,resource,stat,time,types}.h: New files, more - simulated Posix. - - diff --git a/contrib/gdb/include/mpw/README b/contrib/gdb/include/mpw/README deleted file mode 100644 index 10e92de79f6..00000000000 --- a/contrib/gdb/include/mpw/README +++ /dev/null @@ -1 +0,0 @@ -This is a collection of include files that help imitate Posix in MPW. diff --git a/contrib/gdb/include/mpw/dir.h b/contrib/gdb/include/mpw/dir.h deleted file mode 100644 index e6ccd2d5922..00000000000 --- a/contrib/gdb/include/mpw/dir.h +++ /dev/null @@ -1,23 +0,0 @@ -/* The header gives the layout of a directory. */ - -#pragma once - -#ifndef _DIR_H -#define _DIR_H - -#ifndef _TYPES_H /* not quite right */ -#include -#endif - -#define DIRBLKSIZ 512 /* size of directory block */ - -#ifndef DIRSIZ -#define DIRSIZ 14 -#endif - -struct direct { - ino_t d_ino; - char d_name[DIRSIZ]; -}; - -#endif /* _DIR_H */ diff --git a/contrib/gdb/include/mpw/dirent.h b/contrib/gdb/include/mpw/dirent.h deleted file mode 100644 index 38000b2c5f3..00000000000 --- a/contrib/gdb/include/mpw/dirent.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __dirent_h -#define __dirent_h - -#include "sys/dir.h" - -struct dirent { - long d_ino; /* inode number of entry */ - off_t d_off; /* offset of disk directory entry */ - unsigned short d_reclen; /* length of this record */ - char d_name[1]; /* name of file */ -}; - -/* -#define DIRENTBASESIZE \ - (((struct dirent *) 0)->d_name - (char *) 0) -#define DIRENTSIZE(namelen) \ - ((DIRENTBASESIZE + (namelen) + NBPW) & ~(NBPW - 1)) -*/ - -/* from Mips posix/dirent.h */ - -/* -#undef rewinddir -*/ - -extern DIR *opendir(); -extern struct dirent *readdir(); -extern void rewinddir(); -extern int closedir(); - -#endif /* ! __dirent_h */ diff --git a/contrib/gdb/include/mpw/fcntl.h b/contrib/gdb/include/mpw/fcntl.h deleted file mode 100644 index 30999b4b17d..00000000000 --- a/contrib/gdb/include/mpw/fcntl.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * FCntl.h -- faccess(), fcntl(), and open() mode flags - * - * Portions copyright American Telephone & Telegraph - * Used with permission, Apple Computer Inc. (1985,1988,1990,1992) - * All rights reserved. - */ - -#ifndef __FCNTL__ -#define __FCNTL__ - -#ifndef __TYPES__ -#include -#endif - -/* - * For use by lseek(): - */ - -#ifndef __STDIO__ /* these defns exactly paralled in StdIO.h for fseek() */ -#define SEEK_CUR 1 -#define SEEK_END 2 -#define SEEK_SET 0 -#endif - -/* - * faccess() commands; for general use - */ - /* 'd' => "directory" ops */ -#define F_DELETE (('d'<<8)|0x01) -#define F_RENAME (('d'<<8)|0x02) - -/* - * more faccess() commands; for use only by MPW tools - */ - -#define F_OPEN (('d'<<8)|0x00) /* reserved for operating system use */ - /* 'e' => "editor" ops */ -#define F_GTABINFO (('e'<<8)|0x00) /* get tab offset for file */ -#define F_STABINFO (('e'<<8)|0x01) /* set " " " " */ -#define F_GFONTINFO (('e'<<8)|0x02) /* get font number and size for file */ -#define F_SFONTINFO (('e'<<8)|0x03) /* set " " " " " " */ -#define F_GPRINTREC (('e'<<8)|0x04) /* get print record for file */ -#define F_SPRINTREC (('e'<<8)|0x05) /* set " " " " */ -#define F_GSELINFO (('e'<<8)|0x06) /* get selection information for file */ -#define F_SSELINFO (('e'<<8)|0x07) /* set " " " " */ -#define F_GWININFO (('e'<<8)|0x08) /* get current window position */ -#define F_SWININFO (('e'<<8)|0x09) /* set " " " */ -#define F_GSCROLLINFO (('e'<<8)|0x0A) /* get scroll information */ -#define F_SSCROLLINFO (('e'<<8)|0x0B) /* set " " */ -#define F_GMARKER (('e'<<8)|0x0D) /* Get Marker */ -#define F_SMARKER (('e'<<8)|0x0C) /* Set " */ -#define F_GSAVEONCLOSE (('e'<<8)|0x0F) /* Get Save on close */ -#define F_SSAVEONCLOSE (('e'<<8)|0x0E) /* Set " " " */ - -/* - * argument structures used by various faccess() commands - */ - -struct MarkElement { - int start; /* start position of mark */ - int end; /* end position */ - unsigned char charCount; /* number of chars in mark name */ - char name[64]; /* mark name */ -} ; /* note: marker names may be up to 64 characters long */ - -#ifndef __cplusplus -typedef struct MarkElement MarkElement; -#endif - -struct SelectionRecord { - long startingPos; - long endingPos; - long displayTop; -}; - -#ifndef __cplusplus -typedef struct SelectionRecord SelectionRecord; -#endif - - -/* - * Mode values accessible to open() - */ -#define O_RDONLY 0 /* Bits 0 and 1 are used internally */ -#define O_WRONLY 1 /* Values 0..2 are historical */ -#define O_RDWR 2 /* NOTE: it goes 0, 1, 2, *!* 8, 16, 32, ... */ -#define O_APPEND (1<< 3) /* append (writes guaranteed at the end) */ -#define O_RSRC (1<< 4) /* Open the resource fork */ -#define O_ALIAS (1<< 5) /* Open alias file */ -#define O_CREAT (1<< 8) /* Open with file create */ -#define O_TRUNC (1<< 9) /* Open with truncation */ -#define O_EXCL (1<<10) /* w/ O_CREAT: Exclusive "create-only" */ -#define O_BINARY (1<<11) /* Open as a binary stream */ -#define O_NRESOLVE (1<<14) /* Don't resolve any aliases */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * function prototypes - */ -int close(int); -int creat(const char*); -int dup(int filedes); /* OBSOLETE: fcntl(filedes, F_DUPFD, 0) is preferred */ -int faccess(char*, unsigned int, long*); -int fcntl(int, unsigned int, int); -long lseek(int, long, int); -int open(const char*, int, ...); -int read(int, char*, unsigned); -int unlink(char*); -int write(int, const char*, unsigned); - -#ifdef __cplusplus -} -#endif - -/* - * fcntl() commands - */ -#define F_DUPFD 0 /* Duplicate files (file descriptor) */ - -#endif __FCNTL__ diff --git a/contrib/gdb/include/mpw/grp.h b/contrib/gdb/include/mpw/grp.h deleted file mode 100644 index faf2c6a6be9..00000000000 --- a/contrib/gdb/include/mpw/grp.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "sys/types.h" - -struct group { - char *gr_name; - gid_t gr_gid; - char *gr_passwd; - char **gr_mem; -}; diff --git a/contrib/gdb/include/mpw/mpw.h b/contrib/gdb/include/mpw/mpw.h deleted file mode 100644 index 58702e725ff..00000000000 --- a/contrib/gdb/include/mpw/mpw.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Mac MPW host-specific definitions. */ - -#ifndef __INCLUDE_MPW_H -#define __INCLUDE_MPW_H - -#ifndef MPW -#define MPW -#endif - -/* MPW C is basically ANSI, but doesn't actually enable __STDC__, - nor does it allow __STDC__ to be #defined. */ - -#ifndef ALMOST_STDC -#define ALMOST_STDC -#endif - -#include -#include -#include - -#define HAVE_TIME_T_IN_TIME_H 1 - -#define HAVE_STDLIB_H 1 - -#define HAVE_ERRNO_H 1 - -#define HAVE_STDDEF_H 1 - -#define HAVE_STRING_H 1 - -#define HAVE_STDARG_H 1 - -#define HAVE_VPRINTF 1 - -#ifdef USE_MW_HEADERS - -#include - -#else - -#include -#include -#include - -#define HAVE_FCNTL_H 1 - -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -#endif - -#ifndef fileno -#define fileno(fp) ((fp)->_file) -#endif - -/* stdio.h does not define this if __STDC__, so define here. */ - -#ifdef __STDC__ -FILE *fdopen(int fildes, const char *mode); -#endif - -#endif /* USE_MW_HEADERS */ - -/* Add ersatz definitions, for systems that lack them. */ - -#ifndef EIO -#define EIO 96 -#endif -#ifndef ENOENT -#define ENOENT 97 -#endif -#ifndef EACCES -#define EACCES 98 -#endif -#ifndef ENOSYS -#define ENOSYS 99 -#endif - -#ifndef R_OK -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -#endif - -/* Binary files have different characteristics; for instance, no cr/nl - translation. */ - -#define USE_BINARY_FOPEN - -#include - -#ifdef MPW_C -#undef __PTR_TO_INT -#define __PTR_TO_INT(P) ((int)(P)) -#undef __INT_TO_PTR -#define __INT_TO_PTR(P) ((char *)(P)) -#endif /* MPW_C */ - -#define NO_FCNTL - -int fstat (); - -FILE *mpw_fopen (); -int mpw_fseek (); -int mpw_fread (); -int mpw_fwrite (); -int mpw_access (); -int mpw_open (); -int mpw_creat (); -void mpw_abort (void); - -/* Map these standard functions to improved versions in libiberty. */ - -#define fopen mpw_fopen -#define fseek mpw_fseek -#define fread mpw_fread -#define fwrite mpw_fwrite -#define open mpw_open -#define access mpw_access -#define creat mpw_creat -#define abort mpw_abort - -#define POSIX_UTIME - -#define LOSING_TOTALLY - -/* Define this so that files will be closed before being unlinked. */ - -#define CLOSE_BEFORE_UNLINK - -#endif /* __INCLUDE_MPW_H */ diff --git a/contrib/gdb/include/mpw/pwd.h b/contrib/gdb/include/mpw/pwd.h deleted file mode 100644 index 2d4fb70401a..00000000000 --- a/contrib/gdb/include/mpw/pwd.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __pwd_h -#define __pwd_h - -#include - -struct passwd { - char *pw_name; - uid_t pw_uid; - gid_t pw_gid; - char *pw_dir; - char *pw_shell; - char *pw_passwd; -}; - -#endif /* ! __pwd_h */ diff --git a/contrib/gdb/include/mpw/spin.h b/contrib/gdb/include/mpw/spin.h deleted file mode 100644 index 867d14502c0..00000000000 --- a/contrib/gdb/include/mpw/spin.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Progress macros that use SpinCursor in MPW. - Copyright (C) 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 -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _SPIN_H -#define _SPIN_H - -/* For MPW, progress macros just need to "spin the cursor" frequently, - preferably several times per second on a 68K Mac. */ - -/* In order to determine if we're meeting the goal, define this macro - and information about frequency of spinning will be collected and - displayed. */ - -#define SPIN_MEASUREMENT - -#include - -/* Programs use this macro to indicate the start of a lengthy - activity. STR identifies the particular activity, while N - indicates the expected duration, in unspecified units. If N is - zero, then the expected time to completion is unknown. */ - -#undef START_PROGRESS -#define START_PROGRESS(STR,N) mpw_start_progress (STR, N, __FILE__, __LINE__); - -/* Programs use this macro to indicate that progress has been made on a - lengthy activity. */ - -#undef PROGRESS -#ifdef SPIN_MEASUREMENT -#define PROGRESS(X) mpw_progress_measured (X, __FILE__, __LINE__); -#else -#define PROGRESS(X) mpw_progress (X); -#endif - -/* Programs use this macro to indicate the end of a lengthy activity. - STR must match a STR passed to START_PROGRESS previously. */ - -#undef END_PROGRESS -#define END_PROGRESS(STR) mpw_end_progress (STR, __FILE__, __LINE__); - -extern void mpw_start_progress (char *, int, char *, int); - -extern void mpw_progress (int); - -extern void mpw_progress_measured (int, char *, int); - -extern void mpw_end_progress (char *, char *, int); - -#endif /* _SPIN_H */ diff --git a/contrib/gdb/include/mpw/stat.h b/contrib/gdb/include/mpw/stat.h deleted file mode 100644 index 057b8d53113..00000000000 --- a/contrib/gdb/include/mpw/stat.h +++ /dev/null @@ -1,75 +0,0 @@ -/* The header defines a struct that is used in the stat() and - * fstat functions. The information in this struct comes from the i-node of - * some file. These calls are the only approved way to inspect i-nodes. - */ - -#ifndef _STAT_H -#define _STAT_H - -#ifndef _TYPES_H /* not quite right */ -#include -#endif - -struct stat { - dev_t st_dev; /* major/minor device number */ - ino_t st_ino; /* i-node number */ - mode_t st_mode; /* file mode, protection bits, etc. */ - short int st_nlink; /* # links; TEMPORARY HACK: should be nlink_t*/ - uid_t st_uid; /* uid of the file's owner */ - short int st_gid; /* gid; TEMPORARY HACK: should be gid_t */ - dev_t st_rdev; - off_t st_size; /* file size */ - time_t st_atime; /* time of last access */ - time_t st_mtime; /* time of last data modification */ - time_t st_ctime; /* time of last file status change */ -}; - -/* Traditional mask definitions for st_mode. */ -#define S_IFMT 0170000 /* type of file */ -#define S_IFREG 0100000 /* regular */ -#define S_IFBLK 0060000 /* block special */ -#define S_IFDIR 0040000 /* directory */ -#define S_IFCHR 0020000 /* character special */ -#define S_IFIFO 0010000 /* this is a FIFO */ -#define S_ISUID 0004000 /* set user id on execution */ -#define S_ISGID 0002000 /* set group id on execution */ - /* next is reserved for future use */ -#define S_ISVTX 01000 /* save swapped text even after use */ - -/* POSIX masks for st_mode. */ -#define S_IRWXU 00700 /* owner: rwx------ */ -#define S_IRUSR 00400 /* owner: r-------- */ -#define S_IWUSR 00200 /* owner: -w------- */ -#define S_IXUSR 00100 /* owner: --x------ */ - -#define S_IRWXG 00070 /* group: ---rwx--- */ -#define S_IRGRP 00040 /* group: ---r----- */ -#define S_IWGRP 00020 /* group: ----w---- */ -#define S_IXGRP 00010 /* group: -----x--- */ - -#define S_IRWXO 00007 /* others: ------rwx */ -#define S_IROTH 00004 /* others: ------r-- */ -#define S_IWOTH 00002 /* others: -------w- */ -#define S_IXOTH 00001 /* others: --------x */ - -/* The following macros test st_mode (from POSIX Sec. 5.6.1.1. */ -#define S_ISREG(m) ((m & S_IFMT) == S_IFREG) /* is a reg file */ -#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) /* is a directory */ -#define S_ISCHR(m) ((m & S_IFMT) == S_IFCHR) /* is a char spec */ -#define S_ISBLK(m) ((m & S_IFMT) == S_IFBLK) /* is a block spec */ -#define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO) /* is a pipe/FIFO */ - - -/* Function Prototypes. */ -#ifndef _ANSI_H -#include -#endif - -_PROTOTYPE( int chmod, (const char *_path, int _mode) ); -_PROTOTYPE( int fstat, (int _fildes, struct stat *_buf) ); -_PROTOTYPE( int mkdir, (const char *_path, int _mode) ); -_PROTOTYPE( int mkfifo, (const char *_path, int _mode) ); -_PROTOTYPE( int stat , (const char *_path, struct stat *_buf) ); -_PROTOTYPE( mode_t umask, (int _cmask) ); - -#endif /* _STAT_H */ diff --git a/contrib/gdb/include/mpw/sys/file.h b/contrib/gdb/include/mpw/sys/file.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/contrib/gdb/include/mpw/sys/file.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/contrib/gdb/include/mpw/sys/param.h b/contrib/gdb/include/mpw/sys/param.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/contrib/gdb/include/mpw/sys/param.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/contrib/gdb/include/mpw/sys/resource.h b/contrib/gdb/include/mpw/sys/resource.h deleted file mode 100644 index d39439d61d5..00000000000 --- a/contrib/gdb/include/mpw/sys/resource.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SYS_RESOURCE_H__ -#define __SYS_RESOURCE_H__ - -struct rusage { - struct timeval ru_utime; - struct timeval ru_stime; -}; - -#endif /* __SYS_RESOURCE_H__ */ diff --git a/contrib/gdb/include/mpw/sys/stat.h b/contrib/gdb/include/mpw/sys/stat.h deleted file mode 100644 index b65c72e10c6..00000000000 --- a/contrib/gdb/include/mpw/sys/stat.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Imitation sys/stat.h. */ - -#ifndef __SYS_STAT_H__ -#define __SYS_STAT_H__ - -#include -#include - -struct stat { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - short st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - off_t st_size; - off_t st_rsize; - time_t st_atime; - int st_spare1; - time_t st_mtime; - int st_spare2; - time_t st_ctime; - int st_spare3; - long st_blksize; - long st_blocks; - long st_spare4[2]; -}; - -#define S_IFMT 0170000L -#define S_IFDIR 0040000L -#define S_IFREG 0100000L -#define S_IREAD 0400 -#define S_IWRITE 0200 -#define S_IEXEC 0100 - -#define S_IFIFO 010000 /* FIFO special */ -#define S_IFCHR 020000 /* character special */ -#define S_IFBLK 030000 /* block special */ - -int stat (char *path, struct stat *buf); -int fstat (int fd, struct stat *buf); - -#endif /* __SYS_STAT_H___ */ diff --git a/contrib/gdb/include/mpw/sys/time.h b/contrib/gdb/include/mpw/sys/time.h deleted file mode 100644 index f9e485232a2..00000000000 --- a/contrib/gdb/include/mpw/sys/time.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Imitation sys/time.h. */ - -#ifndef __SYS_TIME_H__ -#define __SYS_TIME_H__ - -#include - -struct timeval { - long tv_sec; - long tv_usec; -}; - -#endif /* __SYS_TIME_H__ */ diff --git a/contrib/gdb/include/mpw/sys/types.h b/contrib/gdb/include/mpw/sys/types.h deleted file mode 100644 index d7d9c9f44ba..00000000000 --- a/contrib/gdb/include/mpw/sys/types.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Imitation sys/types.h. */ - -#ifndef __SYS_TYPES_H__ -#define __SYS_TYPES_H__ - -#include - -typedef short dev_t; -typedef short ino_t; -typedef unsigned short mode_t; -typedef unsigned short uid_t; -typedef unsigned short gid_t; -typedef long off_t; - -#endif /* __SYS_TYPES_H__ */ diff --git a/contrib/gdb/include/mpw/utime.h b/contrib/gdb/include/mpw/utime.h deleted file mode 100644 index e8bf66f2ba5..00000000000 --- a/contrib/gdb/include/mpw/utime.h +++ /dev/null @@ -1,7 +0,0 @@ - -struct utimbuf { - time_t actime; - time_t modtime; -}; - -int utime (char *, struct utimbuf *); diff --git a/contrib/gdb/include/mpw/varargs.h b/contrib/gdb/include/mpw/varargs.h deleted file mode 100644 index acb9e4504a2..00000000000 --- a/contrib/gdb/include/mpw/varargs.h +++ /dev/null @@ -1,9 +0,0 @@ -/* varargs.h. */ -#ifndef __va_list__ -#define __va_list__ -typedef char *va_list; -#endif -#define va_dcl int va_alist; -#define va_start(list) list = (char *) &va_alist -#define va_end(list) -#define va_arg(list,mode) ((mode *)(list += sizeof(mode)))[-1] diff --git a/contrib/gdb/include/nlm/ChangeLog b/contrib/gdb/include/nlm/ChangeLog deleted file mode 100644 index d9ea3d09e0a..00000000000 --- a/contrib/gdb/include/nlm/ChangeLog +++ /dev/null @@ -1,83 +0,0 @@ -Fri May 6 13:31:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * external.h (nlmNAME(External_Custom_Header)): Add length, - dataOffset, and dataStamp field. - (nlmNAME(External_Cygnus_Ext_Header)): Remove. - * internal.h (Nlm_Internal_Custom_Header): Add hdrLength, - dataOffset, dataStamp and hdr fields. - -Fri Apr 22 11:12:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * external.h (struct nlmNAME(external_cygnus_ext_header)): Rename - from nlmNAME(external_cygnus_section_header). Change stamp field - to 8 bytes. Add bytes field. - * internal.h (nlm_internal_cygnus_ext_header): Rename from - nlm_internal_cygnus_section_header. Change stamp field to 8 - bytes. - -Thu Apr 21 11:57:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * internal.h (struct nlm_internal_cygnus_section_header): Define. - * external.h (struct nlmNAME(external_cygnus_section_header): - Define. - -Wed Apr 20 14:27:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * internal.h (struct nlm_internal_custom_header): Remove - debugRecOffset and debugRecLength fields. Add data field. - * external.h (struct nlmNAME(external_custom_header)): Remove - debugRecOffset and debugRecLength fields. - -Mon Feb 7 08:28:40 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * internal.h: Change HOST_64_BIT to BFD_HOST_64_BIT. - -Thu Dec 2 14:14:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * alpha-ext.h: New file describing formats of information in Alpha - NetWare files. - * common.h: Define some non-external Alpha information. - -Wed Nov 17 17:38:58 1993 Sean Eric Fagan (sef@cygnus.com) - - * external.h: Don't define external_fixed_header here. - * i386-ext.h, sparc32-ext.h: New header files to define - external_fixed_header for particular CPU's. - -Wed Oct 27 11:45:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * internal.h (Nlm_Internal_Extended_Header): Added fields - sharedDebugRecordOffset and sharedDebugRecordCount. - * external.h (NlmNAME(External_Extended_Header)): Likewise. - - * common.h (NLM_SIGNATURE): Do not define (it's different for each - backend). - -Tue Aug 31 13:24:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * internal.h: Change length fields of type char to type unsigned - char. - -Sat Jul 31 02:12:14 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * common.h (NLM_HIBIT, NLM_HEADER_VERSION): Define. - -Thu Jul 22 16:09:47 1993 Fred Fish (fnf@deneb.cygnus.com) - - * common.h (NLM_CAT*, NLM_ARCH_SIZE, NLM_TARGET_LONG_SIZE, - NLM_TARGET_ADDRESS_SIZE, NLM_NAME, NlmNAME, nlmNAME): New - macros. - * external.h (TARGET_LONG_SIZE, TARGET_ADDRESS_SIZE): Remove - macros, convert usages to NLM_ equivalents. - * external.h: Use nlmNAME and NlmNAME macros to derive both - 32 and 64 bit versions. - -Mon Jul 19 22:12:40 1993 Fred Fish (fnf@deneb.cygnus.com) - - * (common.h, external.h, internal.h): New files for NLM/NetWare - support. - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/include/nlm/alpha-ext.h b/contrib/gdb/include/nlm/alpha-ext.h deleted file mode 100644 index 37199dd1dc0..00000000000 --- a/contrib/gdb/include/nlm/alpha-ext.h +++ /dev/null @@ -1,166 +0,0 @@ -/* Alpha NLM (NetWare Loadable Module) support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - By Ian Lance Taylor, Cygnus Support - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* An Alpha NLM starts with an instance of this structure. */ - -struct nlm32_alpha_external_prefix_header -{ - /* Magic number. Must be NLM32_ALPHA_MAGIC. */ - unsigned char magic[4]; - /* Format descriptor. Current value is 2. */ - unsigned char format[4]; - /* Size of prefix header. */ - unsigned char size[4]; - /* Padding. */ - unsigned char pad1[4]; - /* More fields may be added later, supposedly. */ -}; - -/* The external format of an Alpha NLM reloc. This is the same as an - Alpha ECOFF reloc. */ - -struct nlm32_alpha_external_reloc -{ - unsigned char r_vaddr[8]; - unsigned char r_symndx[4]; - unsigned char r_bits[4]; -}; - -/* Constants to unpack the r_bits field of a reloc. */ - -#define RELOC_BITS0_TYPE_LITTLE 0xff -#define RELOC_BITS0_TYPE_SH_LITTLE 0 - -#define RELOC_BITS1_EXTERN_LITTLE 0x01 - -#define RELOC_BITS1_OFFSET_LITTLE 0x7e -#define RELOC_BITS1_OFFSET_SH_LITTLE 1 - -#define RELOC_BITS1_RESERVED_LITTLE 0x80 -#define RELOC_BITS1_RESERVED_SH_LITTLE 7 -#define RELOC_BITS2_RESERVED_LITTLE 0xff -#define RELOC_BITS2_RESERVED_SH_LEFT_LITTLE 1 -#define RELOC_BITS3_RESERVED_LITTLE 0x03 -#define RELOC_BITS3_RESERVED_SH_LEFT_LITTLE 9 - -#define RELOC_BITS3_SIZE_LITTLE 0xfc -#define RELOC_BITS3_SIZE_SH_LITTLE 2 - -/* The external format of the fixed header. */ - -typedef struct nlm32_alpha_external_fixed_header -{ - - /* The signature field identifies the file as an NLM. It must contain - the signature string, which depends upon the NLM target. */ - - unsigned char signature[24]; - - /* The version of the header. At this time, the highest version number - is 4. */ - - unsigned char version[4]; - - /* The name of the module, which must be a DOS name (1-8 characters followed - by a period and a 1-3 character extension). The first byte is the byte - length of the name and the last byte is a null terminator byte. This - field is fixed length, and any unused bytes should be null bytes. The - value is set by the OUTPUT keyword to NLMLINK. */ - - unsigned char moduleName[14]; - - /* Padding to make it come out correct. */ - - unsigned char pad1[2]; - - /* The byte offset of the code image from the start of the file. */ - - unsigned char codeImageOffset[4]; - - /* The size of the code image, in bytes. */ - - unsigned char codeImageSize[4]; - - /* The byte offset of the data image from the start of the file. */ - - unsigned char dataImageOffset[4]; - - /* The size of the data image, in bytes. */ - - unsigned char dataImageSize[4]; - - /* The size of the uninitialized data region that the loader is to be - allocated at load time. Uninitialized data follows the initialized - data in the NLM address space. */ - - unsigned char uninitializedDataSize[4]; - - /* The byte offset of the custom data from the start of the file. The - custom data is set by the CUSTOM keyword to NLMLINK. It is possible - for this to be EOF if there is no custom data. */ - - unsigned char customDataOffset[4]; - - /* The size of the custom data, in bytes. */ - - unsigned char customDataSize[4]; - - /* The byte offset of the module dependencies from the start of the file. - The module dependencies are determined by the MODULE keyword in - NLMLINK. */ - - unsigned char moduleDependencyOffset[4]; - - /* The number of module dependencies at the moduleDependencyOffset. */ - - unsigned char numberOfModuleDependencies[4]; - - /* The byte offset of the relocation fixup data from the start of the file */ - - unsigned char relocationFixupOffset[4]; - - unsigned char numberOfRelocationFixups[4]; - - unsigned char externalReferencesOffset[4]; - - unsigned char numberOfExternalReferences[4]; - - unsigned char publicsOffset[4]; - - unsigned char numberOfPublics[4]; - - /* The byte offset of the internal debug info from the start of the file. - It is possible for this to be EOF if there is no debug info. */ - - unsigned char debugInfoOffset[4]; - - unsigned char numberOfDebugRecords[4]; - - unsigned char codeStartOffset[4]; - - unsigned char exitProcedureOffset[4]; - - unsigned char checkUnloadProcedureOffset[4]; - - unsigned char moduleType[4]; - - unsigned char flags[4]; - -} Nlm32_alpha_External_Fixed_Header; diff --git a/contrib/gdb/include/nlm/common.h b/contrib/gdb/include/nlm/common.h deleted file mode 100644 index e96550a92f6..00000000000 --- a/contrib/gdb/include/nlm/common.h +++ /dev/null @@ -1,124 +0,0 @@ -/* NLM (NetWare Loadable Module) support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file is part of NLM support for BFD, and contains the portions - that are common to both the internal and external representations. */ - -/* Semi-portable string concatenation in cpp. - The NLM_CAT4 hack is to avoid a problem with some strict ANSI C - preprocessors. The problem is, "32_" or "64_" are not a valid - preprocessing tokens, and we don't want extra underscores (e.g., - "nlm_32_"). The XNLM_CAT2 macro will cause the inner NLM_CAT macros - to be evaluated first, producing still-valid pp-tokens. Then the - final concatenation can be done. (Sigh.) */ - -#ifdef SABER -# define NLM_CAT(a,b) a##b -# define NLM_CAT3(a,b,c) a##b##c -# define NLM_CAT4(a,b,c,d) a##b##c##d -#else -# ifdef __STDC__ -# define NLM_CAT(a,b) a##b -# define NLM_CAT3(a,b,c) a##b##c -# define XNLM_CAT2(a,b) NLM_CAT(a,b) -# define NLM_CAT4(a,b,c,d) XNLM_CAT2(NLM_CAT(a,b),NLM_CAT(c,d)) -# else -# define NLM_CAT(a,b) a/**/b -# define NLM_CAT3(a,b,c) a/**/b/**/c -# define NLM_CAT4(a,b,c,d) a/**/b/**/c/**/d -# endif -#endif - -/* If NLM_ARCH_SIZE is not defined, default to 32. NLM_ARCH_SIZE is - optionally defined by the application. */ - -#ifndef NLM_ARCH_SIZE -# define NLM_ARCH_SIZE 32 -#endif - -#if NLM_ARCH_SIZE == 32 -# define NLM_TARGET_LONG_SIZE 4 -# define NLM_TARGET_ADDRESS_SIZE 4 -# define NLM_NAME(x,y) NLM_CAT4(x,32,_,y) -# define NLM_HIBIT (((bfd_vma) 1) << 31) -#endif -#if NLM_ARCH_SIZE == 64 -# define NLM_TARGET_LONG_SIZE 8 -# define NLM_TARGET_ADDRESS_SIZE 8 -# define NLM_NAME(x,y) NLM_CAT4(x,64,_,y) -# define NLM_HIBIT (((bfd_vma) 1) << 63) -#endif - -#define NlmNAME(X) NLM_NAME(Nlm,X) -#define nlmNAME(X) NLM_NAME(nlm,X) - -/* Give names to things that should not change. */ - -#define NLM_MAX_DESCRIPTION_LENGTH 127 -#define NLM_MAX_SCREEN_NAME_LENGTH 71 -#define NLM_MAX_THREAD_NAME_LENGTH 71 -#define NLM_MAX_COPYRIGHT_MESSAGE_LENGTH 255 -#define NLM_OTHER_DATA_LENGTH 400 /* FIXME */ -#define NLM_OLD_THREAD_NAME_LENGTH 5 -#define NLM_SIGNATURE_SIZE 24 -#define NLM_HEADER_VERSION 4 -#define NLM_MODULE_NAME_SIZE 14 -#define NLM_DEFAULT_STACKSIZE (8 * 1024) - -/* Alpha information. This should probably be in a separate Alpha - header file, but it can't go in alpha-ext.h because some of it is - needed by nlmconv.c. */ - -/* Magic number in Alpha prefix header. */ -#define NLM32_ALPHA_MAGIC (0x83561840) - -/* The r_type field in an Alpha reloc is one of the following values. */ -#define ALPHA_R_IGNORE 0 -#define ALPHA_R_REFLONG 1 -#define ALPHA_R_REFQUAD 2 -#define ALPHA_R_GPREL32 3 -#define ALPHA_R_LITERAL 4 -#define ALPHA_R_LITUSE 5 -#define ALPHA_R_GPDISP 6 -#define ALPHA_R_BRADDR 7 -#define ALPHA_R_HINT 8 -#define ALPHA_R_SREL16 9 -#define ALPHA_R_SREL32 10 -#define ALPHA_R_SREL64 11 -#define ALPHA_R_OP_PUSH 12 -#define ALPHA_R_OP_STORE 13 -#define ALPHA_R_OP_PSUB 14 -#define ALPHA_R_OP_PRSHIFT 15 -#define ALPHA_R_GPVALUE 16 -#define ALPHA_R_NW_RELOC 250 - -/* A local reloc, other than ALPHA_R_GPDISP or ALPHA_R_IGNORE, must be - against one of these symbol indices. */ -#define ALPHA_RELOC_SECTION_TEXT 1 -#define ALPHA_RELOC_SECTION_DATA 3 - -/* An ALPHA_R_NW_RELOC has one of these values in the size field. If - it is SETGP, the r_vaddr field holds the GP value to use. If it is - LITA, the r_vaddr field holds the address of the .lita section and - the r_symndx field holds the size of the .lita section. */ -#define ALPHA_R_NW_RELOC_SETGP 1 -#define ALPHA_R_NW_RELOC_LITA 2 diff --git a/contrib/gdb/include/nlm/external.h b/contrib/gdb/include/nlm/external.h deleted file mode 100644 index f77a5bb3dda..00000000000 --- a/contrib/gdb/include/nlm/external.h +++ /dev/null @@ -1,174 +0,0 @@ -/* NLM (NetWare Loadable Module) support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file is part of NLM support for BFD, and contains the portions - that describe how NLM is represented externally by the BFD library. - I.E. it describes the in-file representation of NLM. It requires - the nlm/common.h file which contains the portions that are common to - both the internal and external representations. - - Note that an NLM header consists of three parts: - - (1) A fixed length header that has specific fields of known length, - at specific offsets in the file. - - (2) A variable length header that has specific fields in a specific - order, but some fields may be variable length. - - (3) A auxiliary header that has various optional fields in no specific - order. There is no way to identify the end of the auxiliary headers - except by finding a header without a recognized 'stamp'. - - The exact format of the fixed length header unfortunately varies - from one NLM target to another, due to padding. Each target - defines the correct external format in a separate header file. - -*/ - -/* NLM Header */ - -/* The version header is one of the optional auxiliary headers and - follows the fixed length and variable length NLM headers. */ - -typedef struct nlmNAME(external_version_header) -{ - - /* The header is recognized by "VeRsIoN#" in the stamp field. */ - char stamp[8]; - - unsigned char majorVersion[NLM_TARGET_LONG_SIZE]; - - unsigned char minorVersion[NLM_TARGET_LONG_SIZE]; - - unsigned char revision[NLM_TARGET_LONG_SIZE]; - - unsigned char year[NLM_TARGET_LONG_SIZE]; - - unsigned char month[NLM_TARGET_LONG_SIZE]; - - unsigned char day[NLM_TARGET_LONG_SIZE]; - -} NlmNAME(External_Version_Header); - - -typedef struct nlmNAME(external_copyright_header) -{ - - /* The header is recognized by "CoPyRiGhT=" in the stamp field. */ - - char stamp[10]; - - unsigned char copyrightMessageLength[1]; - - /* There is a variable length field here called 'copyrightMessage' - that is the length specified by copyrightMessageLength. */ - -} NlmNAME(External_Copyright_Header); - - -typedef struct nlmNAME(external_extended_header) -{ - - /* The header is recognized by "MeSsAgEs" in the stamp field. */ - - char stamp[8]; - - unsigned char languageID[NLM_TARGET_LONG_SIZE]; - - unsigned char messageFileOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char messageFileLength[NLM_TARGET_LONG_SIZE]; - - unsigned char messageCount[NLM_TARGET_LONG_SIZE]; - - unsigned char helpFileOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char helpFileLength[NLM_TARGET_LONG_SIZE]; - - unsigned char RPCDataOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char RPCDataLength[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedCodeOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedCodeLength[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedDataOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedDataLength[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedRelocationFixupOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedRelocationFixupCount[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedExternalReferenceOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedExternalReferenceCount[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedPublicsOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedPublicsCount[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedDebugRecordOffset[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedDebugRecordCount[NLM_TARGET_LONG_SIZE]; - - unsigned char sharedInitializationOffset[NLM_TARGET_ADDRESS_SIZE]; - - unsigned char SharedExitProcedureOffset[NLM_TARGET_ADDRESS_SIZE]; - - unsigned char productID[NLM_TARGET_LONG_SIZE]; - - unsigned char reserved0[NLM_TARGET_LONG_SIZE]; - - unsigned char reserved1[NLM_TARGET_LONG_SIZE]; - - unsigned char reserved2[NLM_TARGET_LONG_SIZE]; - - unsigned char reserved3[NLM_TARGET_LONG_SIZE]; - - unsigned char reserved4[NLM_TARGET_LONG_SIZE]; - - unsigned char reserved5[NLM_TARGET_LONG_SIZE]; - -} NlmNAME(External_Extended_Header); - - -typedef struct nlmNAME(external_custom_header) -{ - - /* The header is recognized by "CuStHeAd" in the stamp field. */ - char stamp[8]; - - /* Length of this header. */ - unsigned char length[NLM_TARGET_LONG_SIZE]; - - /* Offset to data. */ - unsigned char dataOffset[NLM_TARGET_LONG_SIZE]; - - /* Length of data. */ - unsigned char dataLength[NLM_TARGET_LONG_SIZE]; - - /* Stamp for this customer header--we recognize "CyGnUsEx". */ - char dataStamp[8]; - -} NlmNAME(External_Custom_Header); diff --git a/contrib/gdb/include/nlm/i386-ext.h b/contrib/gdb/include/nlm/i386-ext.h deleted file mode 100644 index d33ad2da770..00000000000 --- a/contrib/gdb/include/nlm/i386-ext.h +++ /dev/null @@ -1,116 +0,0 @@ -/* i386 NLM (NetWare Loadable Module) support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* The external format of the fixed header. */ - -typedef struct nlm32_i386_external_fixed_header -{ - - /* The signature field identifies the file as an NLM. It must contain - the signature string, which depends upon the NLM target. */ - - unsigned char signature[24]; - - /* The version of the header. At this time, the highest version number - is 4. */ - - unsigned char version[4]; - - /* The name of the module, which must be a DOS name (1-8 characters followed - by a period and a 1-3 character extension). The first byte is the byte - length of the name and the last byte is a null terminator byte. This - field is fixed length, and any unused bytes should be null bytes. The - value is set by the OUTPUT keyword to NLMLINK. */ - - unsigned char moduleName[14]; - - /* The byte offset of the code image from the start of the file. */ - - unsigned char codeImageOffset[4]; - - /* The size of the code image, in bytes. */ - - unsigned char codeImageSize[4]; - - /* The byte offset of the data image from the start of the file. */ - - unsigned char dataImageOffset[4]; - - /* The size of the data image, in bytes. */ - - unsigned char dataImageSize[4]; - - /* The size of the uninitialized data region that the loader is to be - allocated at load time. Uninitialized data follows the initialized - data in the NLM address space. */ - - unsigned char uninitializedDataSize[4]; - - /* The byte offset of the custom data from the start of the file. The - custom data is set by the CUSTOM keyword to NLMLINK. It is possible - for this to be EOF if there is no custom data. */ - - unsigned char customDataOffset[4]; - - /* The size of the custom data, in bytes. */ - - unsigned char customDataSize[4]; - - /* The byte offset of the module dependencies from the start of the file. - The module dependencies are determined by the MODULE keyword in - NLMLINK. */ - - unsigned char moduleDependencyOffset[4]; - - /* The number of module dependencies at the moduleDependencyOffset. */ - - unsigned char numberOfModuleDependencies[4]; - - /* The byte offset of the relocation fixup data from the start of the file */ - - unsigned char relocationFixupOffset[4]; - - unsigned char numberOfRelocationFixups[4]; - - unsigned char externalReferencesOffset[4]; - - unsigned char numberOfExternalReferences[4]; - - unsigned char publicsOffset[4]; - - unsigned char numberOfPublics[4]; - - /* The byte offset of the internal debug info from the start of the file. - It is possible for this to be EOF if there is no debug info. */ - - unsigned char debugInfoOffset[4]; - - unsigned char numberOfDebugRecords[4]; - - unsigned char codeStartOffset[4]; - - unsigned char exitProcedureOffset[4]; - - unsigned char checkUnloadProcedureOffset[4]; - - unsigned char moduleType[4]; - - unsigned char flags[4]; - -} Nlm32_i386_External_Fixed_Header; diff --git a/contrib/gdb/include/nlm/internal.h b/contrib/gdb/include/nlm/internal.h deleted file mode 100644 index dd27dc407f5..00000000000 --- a/contrib/gdb/include/nlm/internal.h +++ /dev/null @@ -1,309 +0,0 @@ -/* NLM (NetWare Loadable Module) support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file is part of NLM support for BFD, and contains the portions - that describe how NLM is represented internally in the BFD library. - I.E. it describes the in-memory representation of NLM. It requires - the nlm/common.h file which contains the portions that are common to - both the internal and external representations. */ - -#if 0 - -/* Types used by various structures, functions, etc. */ - -typedef unsigned long Nlm32_Addr; /* Unsigned program address */ -typedef unsigned long Nlm32_Off; /* Unsigned file offset */ -typedef long Nlm32_Sword; /* Signed large integer */ -typedef unsigned long Nlm32_Word; /* Unsigned large integer */ -typedef unsigned short Nlm32_Half; /* Unsigned medium integer */ -typedef unsigned char Nlm32_Char; /* Unsigned tiny integer */ - -#ifdef BFD_HOST_64_BIT -typedef unsigned BFD_HOST_64_BIT Nlm64_Addr; -typedef unsigned BFD_HOST_64_BIT Nlm64_Off; -typedef BFD_HOST_64_BIT Nlm64_Sxword; -typedef unsigned BFD_HOST_64_BIT Nlm64_Xword; -#endif -typedef long Nlm64_Sword; -typedef unsigned long Nlm64_Word; -typedef unsigned short Nlm64_Half; - -#endif /* 0 */ - -/* This structure contains the internal form of the portion of the NLM - header that is fixed length. */ - -typedef struct nlm_internal_fixed_header -{ - /* The signature field identifies the file as an NLM. It must contain - the signature string, which depends upon the NLM target. */ - - char signature[NLM_SIGNATURE_SIZE]; - - /* The version of the header. At this time, the highest version number - is 4. */ - - long version; - - /* The name of the module, which must be a DOS name (1-8 characters followed - by a period and a 1-3 character extension. The first byte is the byte - length of the name and the last byte is a null terminator byte. This - field is fixed length, and any unused bytes should be null bytes. The - value is set by the OUTPUT keyword to NLMLINK. */ - - char moduleName[NLM_MODULE_NAME_SIZE]; - - /* The byte offset of the code image from the start of the file. */ - - file_ptr codeImageOffset; - - /* The size of the code image, in bytes. */ - - bfd_size_type codeImageSize; - - /* The byte offset of the data image from the start of the file. */ - - file_ptr dataImageOffset; - - /* The size of the data image, in bytes. */ - - bfd_size_type dataImageSize; - - /* The size of the uninitialized data region that the loader is to be - allocated at load time. Uninitialized data follows the initialized - data in the NLM address space. */ - - bfd_size_type uninitializedDataSize; - - /* The byte offset of the custom data from the start of the file. The - custom data is set by the CUSTOM keyword to NLMLINK. */ - - file_ptr customDataOffset; - - /* The size of the custom data, in bytes. */ - - bfd_size_type customDataSize; - - /* The byte offset of the module dependencies from the start of the file. - The module dependencies are determined by the MODULE keyword in - NLMLINK. */ - - file_ptr moduleDependencyOffset; - - /* The number of module dependencies at the moduleDependencyOffset. */ - - long numberOfModuleDependencies; - - /* The byte offset of the relocation fixup data from the start of the file */ - - file_ptr relocationFixupOffset; - long numberOfRelocationFixups; - file_ptr externalReferencesOffset; - long numberOfExternalReferences; - file_ptr publicsOffset; - long numberOfPublics; - file_ptr debugInfoOffset; - long numberOfDebugRecords; - file_ptr codeStartOffset; - file_ptr exitProcedureOffset; - file_ptr checkUnloadProcedureOffset; - long moduleType; - long flags; -} Nlm_Internal_Fixed_Header; - -#define nlm32_internal_fixed_header nlm_internal_fixed_header -#define Nlm32_Internal_Fixed_Header Nlm_Internal_Fixed_Header -#define nlm64_internal_fixed_header nlm_internal_fixed_header -#define Nlm64_Internal_Fixed_Header Nlm_Internal_Fixed_Header - -/* This structure contains the portions of the NLM header that are either - variable in size in the external representation, or else are not at a - fixed offset relative to the start of the NLM header due to preceding - variable sized fields. - - Note that all the fields must exist in the external header, and in - the order used here (the same order is used in the internal form - for consistency, not out of necessity). */ - -typedef struct nlm_internal_variable_header -{ - - /* The descriptionLength field contains the length of the text in - descriptionText, excluding the null terminator. The descriptionText - field contains the NLM description obtained from the DESCRIPTION - keyword in NLMLINK plus the null byte terminator. The descriptionText - can be up to NLM_MAX_DESCRIPTION_LENGTH characters. */ - - unsigned char descriptionLength; - char descriptionText[NLM_MAX_DESCRIPTION_LENGTH + 1]; - - /* The stackSize field contains the size of the stack in bytes, as - specified by the STACK or STACKSIZE keyword in NLMLINK. If no size - is specified, the default is NLM_DEFAULT_STACKSIZE. */ - - long stackSize; - - /* The reserved field is included only for completeness. It should contain - zero. */ - - long reserved; - - /* This field is fixed length, should contain " LONG" (note leading - space), and is unused. */ - - char oldThreadName[NLM_OLD_THREAD_NAME_LENGTH]; - - /* The screenNameLength field contains the length of the actual text stored - in the screenName field, excluding the null byte terminator. The - screenName field contains the screen name as specified by the SCREENNAME - keyword in NLMLINK, and can be up to NLM_MAX_SCREEN_NAME_LENGTH - characters. */ - - unsigned char screenNameLength; - char screenName[NLM_MAX_SCREEN_NAME_LENGTH + 1]; - - /* The threadNameLength field contains the length of the actual text stored - in the threadName field, excluding the null byte terminator. The - threadName field contains the thread name as specified by the THREADNAME - keyword in NLMLINK, and can be up to NLM_MAX_THREAD_NAME_LENGTH - characters. */ - - unsigned char threadNameLength; - char threadName[NLM_MAX_THREAD_NAME_LENGTH + 1]; - -} Nlm_Internal_Variable_Header; - -#define nlm32_internal_variable_header nlm_internal_variable_header -#define Nlm32_Internal_Variable_Header Nlm_Internal_Variable_Header -#define nlm64_internal_variable_header nlm_internal_variable_header -#define Nlm64_Internal_Variable_Header Nlm_Internal_Variable_Header - -/* The version header is one of the optional auxiliary headers and - follows the fixed length and variable length NLM headers. */ - -typedef struct nlm_internal_version_header -{ - /* The header is recognized by "VeRsIoN#" in the stamp field. */ - char stamp[8]; - long majorVersion; - long minorVersion; - long revision; - long year; - long month; - long day; -} Nlm_Internal_Version_Header; - -#define nlm32_internal_version_header nlm_internal_version_header -#define Nlm32_Internal_Version_Header Nlm_Internal_Version_Header -#define nlm64_internal_version_header nlm_internal_version_header -#define Nlm64_Internal_Version_Header Nlm_Internal_Version_Header - -typedef struct nlm_internal_copyright_header -{ - /* The header is recognized by "CoPyRiGhT=" in the stamp field. */ - char stamp[10]; - unsigned char copyrightMessageLength; - char copyrightMessage[NLM_MAX_COPYRIGHT_MESSAGE_LENGTH]; -} Nlm_Internal_Copyright_Header; - -#define nlm32_internal_copyright_header nlm_internal_copyright_header -#define Nlm32_Internal_Copyright_Header Nlm_Internal_Copyright_Header -#define nlm64_internal_copyright_header nlm_internal_copyright_header -#define Nlm64_Internal_Copyright_Header Nlm_Internal_Copyright_Header - -typedef struct nlm_internal_extended_header -{ - /* The header is recognized by "MeSsAgEs" in the stamp field. */ - char stamp[8]; - long languageID; - file_ptr messageFileOffset; - bfd_size_type messageFileLength; - long messageCount; - file_ptr helpFileOffset; - bfd_size_type helpFileLength; - file_ptr RPCDataOffset; - bfd_size_type RPCDataLength; - file_ptr sharedCodeOffset; - bfd_size_type sharedCodeLength; - file_ptr sharedDataOffset; - bfd_size_type sharedDataLength; - file_ptr sharedRelocationFixupOffset; - long sharedRelocationFixupCount; - file_ptr sharedExternalReferenceOffset; - long sharedExternalReferenceCount; - file_ptr sharedPublicsOffset; - long sharedPublicsCount; - file_ptr sharedDebugRecordOffset; - long sharedDebugRecordCount; - bfd_vma SharedInitializationOffset; - bfd_vma SharedExitProcedureOffset; - long productID; - long reserved0; - long reserved1; - long reserved2; - long reserved3; - long reserved4; - long reserved5; -} Nlm_Internal_Extended_Header; - -#define nlm32_internal_extended_header nlm_internal_extended_header -#define Nlm32_Internal_Extended_Header Nlm_Internal_Extended_Header -#define nlm64_internal_extended_header nlm_internal_extended_header -#define Nlm64_Internal_Extended_Header Nlm_Internal_Extended_Header - -/* The format of a custom header as stored internally is different - from the external format. This is how we store a custom header - which we do not recognize. */ - -typedef struct nlm_internal_custom_header -{ - /* The header is recognized by "CuStHeAd" in the stamp field. */ - char stamp[8]; - bfd_size_type hdrLength; - file_ptr dataOffset; - bfd_size_type dataLength; - char dataStamp[8]; - PTR hdr; -} Nlm_Internal_Custom_Header; - -#define nlm32_internal_custom_header nlm_internal_custom_header -#define Nlm32_Internal_Custom_Header Nlm_Internal_Custom_Header -#define nlm64_internal_custom_header nlm_internal_custom_header -#define Nlm64_Internal_Custom_Header Nlm_Internal_Custom_Header - -/* The internal Cygnus header is written out externally as a custom - header. We don't try to replicate that structure here. */ - -typedef struct nlm_internal_cygnus_ext_header -{ - /* The header is recognized by "CyGnUsEx" in the stamp field. */ - char stamp[8]; - /* File location of debugging information. */ - file_ptr offset; - /* Length of debugging information. */ - bfd_size_type length; -} Nlm_Internal_Cygnus_Ext_Header; - -#define nlm32_internal_cygnus_ext_header nlm_internal_cygnus_ext_header -#define Nlm32_Internal_Cygnus_Ext_Header Nlm_Internal_Cygnus_Ext_Header -#define nlm64_internal_cygnus_ext_header nlm_internal_cygnus_ext_header -#define Nlm64_Internal_Cygnus_Ext_Header Nlm_Internal_Cygnus_Ext_Header diff --git a/contrib/gdb/include/nlm/ppc-ext.h b/contrib/gdb/include/nlm/ppc-ext.h deleted file mode 100644 index 0aae10772f5..00000000000 --- a/contrib/gdb/include/nlm/ppc-ext.h +++ /dev/null @@ -1,163 +0,0 @@ -/* PowerPC NLM (NetWare Loadable Module) support for BFD. - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef OLDFORMAT - -/* The format of a PowerPC NLM changed. These structures are only - used in the old format. */ - -/* A PowerPC NLM starts with an instance of this structure. */ - -struct nlm32_powerpc_external_prefix_header -{ - /* Signature. Must be "AppleNLM". */ - char signature[8]; - /* Version number. Current value is 1. */ - unsigned char headerVersion[4]; - /* ??. Should be set to 0. */ - unsigned char origins[4]; - /* File creation date in standard Unix time format (seconds since - 1/1/70). */ - unsigned char date[4]; -}; - -#define NLM32_POWERPC_SIGNATURE "AppleNLM" -#define NLM32_POWERPC_HEADER_VERSION 1 - -/* The external format of a PowerPC NLM reloc. This is the same as an - XCOFF dynamic reloc. */ - -struct nlm32_powerpc_external_reloc -{ - /* Address. */ - unsigned char l_vaddr[4]; - /* Symbol table index. This is 0 for .text and 1 for .data. 2 - means .bss, but I don't know if it is used. In XCOFF, larger - numbers are indices into the dynamic symbol table, but they are - presumably not used in an NLM. */ - unsigned char l_symndx[4]; - /* Relocation type. */ - unsigned char l_rtype[2]; - /* Section number being relocated. */ - unsigned char l_rsecnm[2]; -}; - -#endif /* OLDFORMAT */ - -/* The external format of the fixed header. */ - -typedef struct nlm32_powerpc_external_fixed_header -{ - - /* The signature field identifies the file as an NLM. It must contain - the signature string, which depends upon the NLM target. */ - - unsigned char signature[24]; - - /* The version of the header. At this time, the highest version number - is 4. */ - - unsigned char version[4]; - - /* The name of the module, which must be a DOS name (1-8 characters followed - by a period and a 1-3 character extension). The first byte is the byte - length of the name and the last byte is a null terminator byte. This - field is fixed length, and any unused bytes should be null bytes. The - value is set by the OUTPUT keyword to NLMLINK. */ - - unsigned char moduleName[14]; - - /* Padding to make it come out correct. */ - - unsigned char pad1[2]; - - /* The byte offset of the code image from the start of the file. */ - - unsigned char codeImageOffset[4]; - - /* The size of the code image, in bytes. */ - - unsigned char codeImageSize[4]; - - /* The byte offset of the data image from the start of the file. */ - - unsigned char dataImageOffset[4]; - - /* The size of the data image, in bytes. */ - - unsigned char dataImageSize[4]; - - /* The size of the uninitialized data region that the loader is to be - allocated at load time. Uninitialized data follows the initialized - data in the NLM address space. */ - - unsigned char uninitializedDataSize[4]; - - /* The byte offset of the custom data from the start of the file. The - custom data is set by the CUSTOM keyword to NLMLINK. It is possible - for this to be EOF if there is no custom data. */ - - unsigned char customDataOffset[4]; - - /* The size of the custom data, in bytes. */ - - unsigned char customDataSize[4]; - - /* The byte offset of the module dependencies from the start of the file. - The module dependencies are determined by the MODULE keyword in - NLMLINK. */ - - unsigned char moduleDependencyOffset[4]; - - /* The number of module dependencies at the moduleDependencyOffset. */ - - unsigned char numberOfModuleDependencies[4]; - - /* The byte offset of the relocation fixup data from the start of the file */ - - unsigned char relocationFixupOffset[4]; - - unsigned char numberOfRelocationFixups[4]; - - unsigned char externalReferencesOffset[4]; - - unsigned char numberOfExternalReferences[4]; - - unsigned char publicsOffset[4]; - - unsigned char numberOfPublics[4]; - - /* The byte offset of the internal debug info from the start of the file. - It is possible for this to be EOF if there is no debug info. */ - - unsigned char debugInfoOffset[4]; - - unsigned char numberOfDebugRecords[4]; - - unsigned char codeStartOffset[4]; - - unsigned char exitProcedureOffset[4]; - - unsigned char checkUnloadProcedureOffset[4]; - - unsigned char moduleType[4]; - - unsigned char flags[4]; - -} Nlm32_powerpc_External_Fixed_Header; diff --git a/contrib/gdb/include/nlm/sparc32-ext.h b/contrib/gdb/include/nlm/sparc32-ext.h deleted file mode 100644 index 0deb2dee923..00000000000 --- a/contrib/gdb/include/nlm/sparc32-ext.h +++ /dev/null @@ -1,120 +0,0 @@ -/* SPARC NLM (NetWare Loadable Module) support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* The external format of the fixed header. */ - -typedef struct nlm32_sparc_external_fixed_header -{ - - /* The signature field identifies the file as an NLM. It must contain - the signature string, which depends upon the NLM target. */ - - unsigned char signature[24]; - - /* The version of the header. At this time, the highest version number - is 4. */ - - unsigned char version[4]; - - /* The name of the module, which must be a DOS name (1-8 characters followed - by a period and a 1-3 character extension). The first byte is the byte - length of the name and the last byte is a null terminator byte. This - field is fixed length, and any unused bytes should be null bytes. The - value is set by the OUTPUT keyword to NLMLINK. */ - - unsigned char moduleName[14]; - - /* Padding to make it come out correct. */ - - unsigned char pad1[2]; - - /* The byte offset of the code image from the start of the file. */ - - unsigned char codeImageOffset[4]; - - /* The size of the code image, in bytes. */ - - unsigned char codeImageSize[4]; - - /* The byte offset of the data image from the start of the file. */ - - unsigned char dataImageOffset[4]; - - /* The size of the data image, in bytes. */ - - unsigned char dataImageSize[4]; - - /* The size of the uninitialized data region that the loader is to be - allocated at load time. Uninitialized data follows the initialized - data in the NLM address space. */ - - unsigned char uninitializedDataSize[4]; - - /* The byte offset of the custom data from the start of the file. The - custom data is set by the CUSTOM keyword to NLMLINK. It is possible - for this to be EOF if there is no custom data. */ - - unsigned char customDataOffset[4]; - - /* The size of the custom data, in bytes. */ - - unsigned char customDataSize[4]; - - /* The byte offset of the module dependencies from the start of the file. - The module dependencies are determined by the MODULE keyword in - NLMLINK. */ - - unsigned char moduleDependencyOffset[4]; - - /* The number of module dependencies at the moduleDependencyOffset. */ - - unsigned char numberOfModuleDependencies[4]; - - /* The byte offset of the relocation fixup data from the start of the file */ - - unsigned char relocationFixupOffset[4]; - - unsigned char numberOfRelocationFixups[4]; - - unsigned char externalReferencesOffset[4]; - - unsigned char numberOfExternalReferences[4]; - - unsigned char publicsOffset[4]; - - unsigned char numberOfPublics[4]; - - /* The byte offset of the internal debug info from the start of the file. - It is possible for this to be EOF if there is no debug info. */ - - unsigned char debugInfoOffset[4]; - - unsigned char numberOfDebugRecords[4]; - - unsigned char codeStartOffset[4]; - - unsigned char exitProcedureOffset[4]; - - unsigned char checkUnloadProcedureOffset[4]; - - unsigned char moduleType[4]; - - unsigned char flags[4]; - -} Nlm32_sparc_External_Fixed_Header; diff --git a/contrib/gdb/include/oasys.h b/contrib/gdb/include/oasys.h deleted file mode 100644 index 867d2503134..00000000000 --- a/contrib/gdb/include/oasys.h +++ /dev/null @@ -1,152 +0,0 @@ -/* Oasys object format header file for BFD. - Contributed by Cygnus Support. */ - -#define OASYS_MAX_SEC_COUNT 16 -/* **** */ - -typedef struct oasys_archive_header { - unsigned int version; - char create_date[12]; - char revision_date[12]; - unsigned int mod_count; - file_ptr mod_tbl_offset; - unsigned int sym_tbl_size; - unsigned int sym_count; - file_ptr sym_tbl_offset; - unsigned int xref_count; - file_ptr xref_lst_offset; -} oasys_archive_header_type; - -typedef struct oasys_extarchive_header { - bfd_byte version[4]; - bfd_byte create_date[12]; - bfd_byte revision_date[12]; - bfd_byte mod_count[4]; - bfd_byte mod_tbl_offset[4]; - bfd_byte sym_tbl_size[4]; - bfd_byte sym_count[4]; - bfd_byte sym_tbl_offset[4]; - bfd_byte xref_count[4]; - bfd_byte xref_lst_offset[4]; -} oasys_extarchive_header_type; - -typedef struct oasys_module_table { - int mod_number; - char mod_date[12]; - unsigned int mod_size; - unsigned int dep_count; - unsigned int depee_count; - file_ptr file_offset; - unsigned int sect_count; - char *module_name; - unsigned int module_name_size; -} oasys_module_table_type; - - -typedef struct oasys_extmodule_table_a { - bfd_byte mod_number[4]; - bfd_byte mod_date[12]; - bfd_byte mod_size[4]; - bfd_byte dep_count[4]; - bfd_byte depee_count[4]; - bfd_byte sect_count[4]; - bfd_byte file_offset[4]; - bfd_byte mod_name[32]; -} oasys_extmodule_table_type_a_type; - -typedef struct oasys_extmodule_table_b { - bfd_byte mod_number[4]; - bfd_byte mod_date[12]; - bfd_byte mod_size[4]; - bfd_byte dep_count[4]; - bfd_byte depee_count[4]; - bfd_byte sect_count[4]; - bfd_byte file_offset[4]; - bfd_byte mod_name_length[4]; -} oasys_extmodule_table_type_b_type; - - -typedef enum oasys_record { - oasys_record_is_end_enum = 0, - oasys_record_is_data_enum = 1, - oasys_record_is_symbol_enum = 2, - oasys_record_is_header_enum = 3, - oasys_record_is_named_section_enum = 4, - oasys_record_is_com_enum = 5, - oasys_record_is_debug_enum = 6, - oasys_record_is_section_enum = 7, - oasys_record_is_debug_file_enum = 8, - oasys_record_is_module_enum = 9, - oasys_record_is_local_enum = 10 -} oasys_record_enum_type; - - - -typedef struct oasys_record_header { - unsigned char length; - unsigned char check_sum; - unsigned char type; - unsigned char fill; -} oasys_record_header_type; - -typedef struct oasys_data_record { - oasys_record_header_type header; - unsigned char relb; - bfd_byte addr[4]; - /* maximum total size of data record is 255 bytes */ - bfd_byte data[246]; -} oasys_data_record_type; - -typedef struct oasys_header_record { - oasys_record_header_type header; - unsigned char version_number; - unsigned char rev_number; - char module_name[26-6]; - char description[64-26]; -} oasys_header_record_type; - -#define OASYS_VERSION_NUMBER 0 -#define OASYS_REV_NUMBER 0 - -typedef struct oasys_symbol_record { - oasys_record_header_type header; - unsigned char relb; - bfd_byte value[4]; - bfd_byte refno[2]; - char name[64]; -} oasys_symbol_record_type; - -#define RELOCATION_PCREL_BIT 0x80 -#define RELOCATION_32BIT_BIT 0x40 -#define RELOCATION_TYPE_BITS 0x30 -#define RELOCATION_TYPE_ABS 0x00 -#define RELOCATION_TYPE_REL 0x10 -#define RELOCATION_TYPE_UND 0x20 -#define RELOCATION_TYPE_COM 0x30 -#define RELOCATION_SECT_BITS 0x0f - -typedef struct oasys_section_record { - oasys_record_header_type header; - unsigned char relb; - bfd_byte value[4]; - bfd_byte vma[4]; - bfd_byte fill[3]; -} oasys_section_record_type; - -typedef struct oasys_end_record { - oasys_record_header_type header; - unsigned char relb; - bfd_byte entry[4]; - bfd_byte fill[2]; - bfd_byte zero; -} oasys_end_record_type; - -typedef union oasys_record_union { - oasys_record_header_type header; - oasys_data_record_type data; - oasys_section_record_type section; - oasys_symbol_record_type symbol; - oasys_header_record_type first; - oasys_end_record_type end; - bfd_byte pad[256]; -} oasys_record_union_type; diff --git a/contrib/gdb/include/obstack.h b/contrib/gdb/include/obstack.h deleted file mode 100644 index 416b8bf5315..00000000000 --- a/contrib/gdb/include/obstack.h +++ /dev/null @@ -1,518 +0,0 @@ -/* obstack.h - object stack macros - Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Library General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Library General Public License for more details. - -You should have received a copy of the GNU Library General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Summary: - -All the apparent functions defined here are macros. The idea -is that you would use these pre-tested macros to solve a -very specific set of problems, and they would run fast. -Caution: no side-effects in arguments please!! They may be -evaluated MANY times!! - -These macros operate a stack of objects. Each object starts life -small, and may grow to maturity. (Consider building a word syllable -by syllable.) An object can move while it is growing. Once it has -been "finished" it never changes address again. So the "top of the -stack" is typically an immature growing object, while the rest of the -stack is of mature, fixed size and fixed address objects. - -These routines grab large chunks of memory, using a function you -supply, called `obstack_chunk_alloc'. On occasion, they free chunks, -by calling `obstack_chunk_free'. You must define them and declare -them before using any obstack macros. - -Each independent stack is represented by a `struct obstack'. -Each of the obstack macros expects a pointer to such a structure -as the first argument. - -One motivation for this package is the problem of growing char strings -in symbol tables. Unless you are "fascist pig with a read-only mind" ---Gosper's immortal quote from HAKMEM item 154, out of context--you -would not like to put any arbitrary upper limit on the length of your -symbols. - -In practice this often means you will build many short symbols and a -few long symbols. At the time you are reading a symbol you don't know -how long it is. One traditional method is to read a symbol into a -buffer, realloc()ating the buffer every time you try to read a symbol -that is longer than the buffer. This is beaut, but you still will -want to copy the symbol from the buffer to a more permanent -symbol-table entry say about half the time. - -With obstacks, you can work differently. Use one obstack for all symbol -names. As you read a symbol, grow the name in the obstack gradually. -When the name is complete, finalize it. Then, if the symbol exists already, -free the newly read name. - -The way we do this is to take a large chunk, allocating memory from -low addresses. When you want to build a symbol in the chunk you just -add chars above the current "high water mark" in the chunk. When you -have finished adding chars, because you got to the end of the symbol, -you know how long the chars are, and you can create a new object. -Mostly the chars will not burst over the highest address of the chunk, -because you would typically expect a chunk to be (say) 100 times as -long as an average object. - -In case that isn't clear, when we have enough chars to make up -the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) -so we just point to it where it lies. No moving of chars is -needed and this is the second win: potentially long strings need -never be explicitly shuffled. Once an object is formed, it does not -change its address during its lifetime. - -When the chars burst over a chunk boundary, we allocate a larger -chunk, and then copy the partly formed object from the end of the old -chunk to the beginning of the new larger chunk. We then carry on -accreting characters to the end of the object as we normally would. - -A special macro is provided to add a single char at a time to a -growing object. This allows the use of register variables, which -break the ordinary 'growth' macro. - -Summary: - We allocate large chunks. - We carve out one object at a time from the current chunk. - Once carved, an object never moves. - We are free to append data of any size to the currently - growing object. - Exactly one object is growing in an obstack at any one time. - You can run one obstack per control block. - You may have as many control blocks as you dare. - Because of the way we do it, you can `unwind' an obstack - back to a previous state. (You may remove objects much - as you would with a stack.) -*/ - - -/* Don't do the contents of this file more than once. */ - -#ifndef __OBSTACK_H__ -#define __OBSTACK_H__ - -/* We use subtraction of (char *)0 instead of casting to int - because on word-addressable machines a simple cast to int - may ignore the byte-within-word field of the pointer. */ - -#ifndef __PTR_TO_INT -#define __PTR_TO_INT(P) ((P) - (char *)0) -#endif - -#ifndef __INT_TO_PTR -#define __INT_TO_PTR(P) ((P) + (char *)0) -#endif - -/* We need the type of the resulting object. In ANSI C it is ptrdiff_t - but in traditional C it is usually long. If we are in ANSI C and - don't already have ptrdiff_t get it. */ - -#if defined (__STDC__) && ! defined (offsetof) -#if defined (__GNUC__) && defined (IN_GCC) -/* On Next machine, the system's stddef.h screws up if included - after we have defined just ptrdiff_t, so include all of stddef.h. - Otherwise, define just ptrdiff_t, which is all we need. */ -#ifndef __NeXT__ -#define __need_ptrdiff_t -#endif -#endif - -#include -#endif - -#ifdef __STDC__ -#define PTR_INT_TYPE ptrdiff_t -#else -#define PTR_INT_TYPE long -#endif - -struct _obstack_chunk /* Lives at front of each chunk. */ -{ - char *limit; /* 1 past end of this chunk */ - struct _obstack_chunk *prev; /* address of prior chunk or NULL */ - char contents[4]; /* objects begin here */ -}; - -struct obstack /* control current object in current chunk */ -{ - long chunk_size; /* preferred size to allocate chunks in */ - struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */ - char *object_base; /* address of object we are building */ - char *next_free; /* where to add next char to current object */ - char *chunk_limit; /* address of char after current chunk */ - PTR_INT_TYPE temp; /* Temporary for some macros. */ - int alignment_mask; /* Mask of alignment for each object. */ - struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ - void (*freefun) (); /* User's function to free a chunk. */ - char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ - unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ - unsigned maybe_empty_object:1;/* There is a possibility that the current - chunk contains a zero-length object. This - prevents freeing the chunk if we allocate - a bigger chunk to replace it. */ - unsigned alloc_failed:1; /* chunk alloc func returned 0 */ -}; - -/* Declare the external functions we use; they are in obstack.c. */ - -#ifdef __STDC__ -extern void _obstack_newchunk (struct obstack *, int); -extern void _obstack_free (struct obstack *, void *); -extern int _obstack_begin (struct obstack *, int, int, - void *(*) (), void (*) ()); -extern int _obstack_begin_1 (struct obstack *, int, int, - void *(*) (), void (*) (), void *); -extern int _obstack_memory_used (struct obstack *); -#else -extern void _obstack_newchunk (); -extern void _obstack_free (); -extern int _obstack_begin (); -extern int _obstack_begin_1 (); -extern int _obstack_memory_used (); -#endif - -#ifdef __STDC__ - -/* Do the function-declarations after the structs - but before defining the macros. */ - -void obstack_init (struct obstack *obstack); - -void * obstack_alloc (struct obstack *obstack, int size); - -void * obstack_copy (struct obstack *obstack, void *address, int size); -void * obstack_copy0 (struct obstack *obstack, void *address, int size); - -void obstack_free (struct obstack *obstack, void *block); - -void obstack_blank (struct obstack *obstack, int size); - -void obstack_grow (struct obstack *obstack, void *data, int size); -void obstack_grow0 (struct obstack *obstack, void *data, int size); - -void obstack_1grow (struct obstack *obstack, int data_char); -void obstack_ptr_grow (struct obstack *obstack, void *data); -void obstack_int_grow (struct obstack *obstack, int data); - -void * obstack_finish (struct obstack *obstack); - -int obstack_object_size (struct obstack *obstack); - -int obstack_room (struct obstack *obstack); -void obstack_1grow_fast (struct obstack *obstack, int data_char); -void obstack_ptr_grow_fast (struct obstack *obstack, void *data); -void obstack_int_grow_fast (struct obstack *obstack, int data); -void obstack_blank_fast (struct obstack *obstack, int size); - -void * obstack_base (struct obstack *obstack); -void * obstack_next_free (struct obstack *obstack); -int obstack_alignment_mask (struct obstack *obstack); -int obstack_chunk_size (struct obstack *obstack); -int obstack_memory_used (struct obstack *obstack); - -#endif /* __STDC__ */ - -/* Non-ANSI C cannot really support alternative functions for these macros, - so we do not declare them. */ - -/* Pointer to beginning of object being allocated or to be allocated next. - Note that this might not be the final address of the object - because a new chunk might be needed to hold the final size. */ - -#define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base) - -/* Size for allocating ordinary chunks. */ - -#define obstack_chunk_size(h) ((h)->chunk_size) - -/* Pointer to next byte not yet allocated in current chunk. */ - -#define obstack_next_free(h) ((h)->alloc_failed ? 0 : (h)->next_free) - -/* Mask specifying low bits that should be clear in address of an object. */ - -#define obstack_alignment_mask(h) ((h)->alignment_mask) - -#define obstack_init(h) \ - _obstack_begin ((h), 0, 0, \ - (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) - -#define obstack_begin(h, size) \ - _obstack_begin ((h), (size), 0, \ - (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) - -#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ - _obstack_begin ((h), (size), (alignment), \ - (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) - -#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ - _obstack_begin_1 ((h), (size), (alignment), \ - (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) - -#define obstack_chunkfun(h, newchunkfun) \ - ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) - -#define obstack_freefun(h, newfreefun) \ - ((h) -> freefun = (void (*)()) (newfreefun)) - -#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) - -#define obstack_blank_fast(h,n) ((h)->next_free += (n)) - -#define obstack_memory_used(h) _obstack_memory_used (h) - -#if defined (__GNUC__) && defined (__STDC__) -#if __GNUC__ < 2 -#define __extension__ -#endif - -/* For GNU C, if not -traditional, - we can define these macros to compute all args only once - without using a global variable. - Also, we can avoid using the `temp' slot, to make faster code. */ - -#define obstack_object_size(OBSTACK) \ - __extension__ \ - ({ struct obstack *__o = (OBSTACK); \ - __o->alloc_failed ? 0 : \ - (unsigned) (__o->next_free - __o->object_base); }) - -#define obstack_room(OBSTACK) \ - __extension__ \ - ({ struct obstack *__o = (OBSTACK); \ - (unsigned) (__o->chunk_limit - __o->next_free); }) - -#define obstack_grow(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len > __o->chunk_limit) \ - _obstack_newchunk (__o, __len); \ - if (!__o->alloc_failed) \ - { \ - bcopy (where, __o->next_free, __len); \ - __o->next_free += __len; \ - } \ - (void) 0; }) - -#define obstack_grow0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, __len + 1); \ - if (!__o->alloc_failed) \ - { \ - bcopy (where, __o->next_free, __len); \ - __o->next_free += __len; \ - *(__o->next_free)++ = 0; \ - } \ - (void) 0; }) - -#define obstack_1grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, 1); \ - if (!__o->alloc_failed) \ - *(__o->next_free)++ = (datum); \ - (void) 0; }) - -/* These assume that the obstack alignment is good enough for pointers or ints, - and that the data added so far to the current object - shares that much alignment. */ - -#define obstack_ptr_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (void *)); \ - if (!__o->alloc_failed) \ - *((void **)__o->next_free)++ = ((void *)datum); \ - (void) 0; }) - -#define obstack_int_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (int) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (int)); \ - if (!__o->alloc_failed) \ - *((int *)__o->next_free)++ = ((int)datum); \ - (void) 0; }) - -#define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr) -#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) - -#define obstack_blank(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ - _obstack_newchunk (__o, __len); \ - if (!__o->alloc_failed) \ - __o->next_free += __len; \ - (void) 0; }) - -#define obstack_alloc(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_blank (__h, (length)); \ - obstack_finish (__h); }) - -#define obstack_copy(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow (__h, (where), (length)); \ - obstack_finish (__h); }) - -#define obstack_copy0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow0 (__h, (where), (length)); \ - obstack_finish (__h); }) - -/* The local variable is named __o1 to avoid a name conflict - when obstack_blank is called. */ -#define obstack_finish(OBSTACK) \ -__extension__ \ -({ struct obstack *__o1 = (OBSTACK); \ - void *value; \ - if (__o1->alloc_failed) \ - value = 0; \ - else \ - { \ - value = (void *) __o1->object_base; \ - if (__o1->next_free == value) \ - __o1->maybe_empty_object = 1; \ - __o1->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ - & ~ (__o1->alignment_mask)); \ - if (__o1->next_free - (char *)__o1->chunk \ - > __o1->chunk_limit - (char *)__o1->chunk) \ - __o1->next_free = __o1->chunk_limit; \ - __o1->object_base = __o1->next_free; \ - } \ - value; }) - -#define obstack_free(OBSTACK, OBJ) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - void *__obj = (OBJ); \ - if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ - __o->next_free = __o->object_base = __obj; \ - else (obstack_free) (__o, __obj); }) - -#else /* not __GNUC__ or not __STDC__ */ - -#define obstack_object_size(h) \ - (unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base) - -#define obstack_room(h) \ - (unsigned) ((h)->chunk_limit - (h)->next_free) - -/* Note that the call to _obstack_newchunk is enclosed in (..., 0) - so that we can avoid having void expressions - in the arms of the conditional expression. - Casting the third operand to void was tried before, - but some compilers won't accept it. */ - -#define obstack_grow(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (bcopy (where, (h)->next_free, (h)->temp), \ - (h)->next_free += (h)->temp))) - -#define obstack_grow0(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (bcopy (where, (h)->next_free, (h)->temp), \ - (h)->next_free += (h)->temp, \ - *((h)->next_free)++ = 0))) - -#define obstack_1grow(h,datum) \ -( (((h)->next_free + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), 1), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (*((h)->next_free)++ = (datum)))) - -#define obstack_ptr_grow(h,datum) \ -( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum)))) - -#define obstack_int_grow(h,datum) \ -( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum)))) - -#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr) -#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) - -#define obstack_blank(h,length) \ -( (h)->temp = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - ((h)->next_free += (h)->temp))) - -#define obstack_alloc(h,length) \ - (obstack_blank ((h), (length)), obstack_finish ((h))) - -#define obstack_copy(h,where,length) \ - (obstack_grow ((h), (where), (length)), obstack_finish ((h))) - -#define obstack_copy0(h,where,length) \ - (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) - -#define obstack_finish(h) \ -( (h)->alloc_failed ? 0 : \ - (((h)->next_free == (h)->object_base \ - ? (((h)->maybe_empty_object = 1), 0) \ - : 0), \ - (h)->temp = __PTR_TO_INT ((h)->object_base), \ - (h)->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ - & ~ ((h)->alignment_mask)), \ - (((h)->next_free - (char *)(h)->chunk \ - > (h)->chunk_limit - (char *)(h)->chunk) \ - ? ((h)->next_free = (h)->chunk_limit) : 0), \ - (h)->object_base = (h)->next_free, \ - __INT_TO_PTR ((h)->temp))) - -#ifdef __STDC__ -#define obstack_free(h,obj) \ -( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ - (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ - ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp + (char *) (h)->chunk) \ - : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) -#else -#define obstack_free(h,obj) \ -( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ - (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ - ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp + (char *) (h)->chunk) \ - : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) -#endif - -#endif /* not __GNUC__ or not __STDC__ */ - -#endif /* not __OBSTACK_H__ */ diff --git a/contrib/gdb/include/opcode/ChangeLog b/contrib/gdb/include/opcode/ChangeLog deleted file mode 100644 index f56df4bd598..00000000000 --- a/contrib/gdb/include/opcode/ChangeLog +++ /dev/null @@ -1,812 +0,0 @@ -Thu Mar 7 15:08:23 1996 Doug Evans - - * sparc.h (O): Mark operand letter as in use. - -Tue Feb 20 20:46:21 1996 Doug Evans - - * sparc.h (sparc_{encode,decode}_sparclet_cpreg): Declare. - Mark operand letters uU as in use. - -Mon Feb 19 01:59:08 1996 Doug Evans - - * sparc.h (sparc_opcode_arch_val): Add SPARC_OPCODE_ARCH_SPARCLET. - (sparc_opcode_arch): Delete member `conflicts'. Add `supported'. - (SPARC_OPCODE_SUPPORTED): New macro. - (SPARC_OPCODE_CONFLICT_P): Rewrite. - (F_NOTV9): Delete. - -Fri Feb 16 12:23:34 1996 Jeffrey A Law (law@cygnus.com) - - * sparc.h (sparc_opcode_lookup_arch) Make return type in - declaration consistent with return type in definition. - -Wed Feb 14 18:14:11 1996 Alan Modra - - * i386.h (i386_optab): Remove Data32 from pushf and popf. - -Thu Feb 8 14:27:21 1996 James Carlson - - * i386.h (i386_regtab): Add 80486 test registers. - -Mon Feb 5 18:35:46 1996 Ian Lance Taylor - - * i960.h (I_HX): Define. - (i960_opcodes): Add HX instruction. - -Mon Jan 29 12:43:39 1996 Ken Raeburn - - * i386.h: Fix waiting forms of finit, fstenv, fsave, fstsw, fstcw, - and fclex. - -Wed Jan 24 22:36:59 1996 Doug Evans - - * sparc.h (enum sparc_opcode_arch_val): Replaces sparc_architecture. - (SPARC_OPCODE_CONFLICT_P): Renamed from ARCHITECTURES_CONFLICT_P. - (bfd_* defines): Delete. - (sparc_opcode_archs): Replaces architecture_pname. - (sparc_opcode_lookup_arch): Declare. - (NUMOPCODES): Delete. - -Mon Jan 22 08:24:32 1996 Doug Evans - - * sparc.h (enum sparc_architecture): Add v9a. - (ARCHITECTURES_CONFLICT_P): Update. - -Thu Dec 28 13:27:53 1995 John Hassey - - * i386.h: Added Pentium Pro instructions. - -Thu Nov 2 22:59:22 1995 Ian Lance Taylor - - * m68k.h: Document new 'W' operand place. - -Tue Oct 24 10:49:10 1995 Jeffrey A Law (law@cygnus.com) - - * hppa.h: Add lci and syncdma instructions. - -Mon Oct 23 11:09:16 1995 James G. Smith - - * mips.h: Added INSN_4100 flag to mark NEC VR4100 specific - instructions. - -Mon Oct 16 10:28:15 1995 Michael Meissner - - * ppc.h (PPC_OPCODE_{COMMON,ANY}): New opcode flags for - assembler's -mcom and -many switches. - -Wed Oct 11 16:56:33 1995 Ken Raeburn - - * i386.h: Fix cmpxchg8b extension opcode description. - -Thu Oct 5 18:03:36 1995 Ken Raeburn - - * i386.h: Add Pentium instructions wrmsr, rdtsc, rdmsr, cmpxchg8b, - and register cr4. - -Tue Sep 19 15:26:43 1995 Ian Lance Taylor - - * m68k.h: Change comment: split type P into types 0, 1 and 2. - -Wed Aug 30 13:50:55 1995 Doug Evans - - * sparc.h (sparc_{encode,decode}_prefetch): Declare. - -Tue Aug 29 15:34:58 1995 Doug Evans - - * sparc.h (sparc_{encode,decode}_{asi,membar}): Declare. - -Wed Aug 2 18:32:19 1995 Ian Lance Taylor - - * m68kmri.h: Remove. - - * m68k.h: Move tables into opcodes/m68k-opc.c, leaving just the - declarations. Remove F_ALIAS and flag field of struct - m68k_opcode. Change arch field of struct m68k_opcode to unsigned - int. Make name and args fields of struct m68k_opcode const. - -Wed Aug 2 08:16:46 1995 Doug Evans - - * sparc.h (F_NOTV9): Define. - -Tue Jul 11 14:20:42 1995 Jeff Spiegel - - * mips.h (INSN_4010): Define. - -Wed Jun 21 18:49:51 1995 Ken Raeburn - - * m68k.h (TBL1): Reverse sense of "round" argument in result. - - Changes from Andreas Schwab : - * m68k.h: Fix argument descriptions of coprocessor - instructions to allow only alterable operands where appropriate. - [!NO_DEFAULT_SIZES]: An omitted size defaults to `w'. - (m68k_opcode_aliases): Add more aliases. - - -Fri Apr 14 22:15:34 1995 Ken Raeburn - - * m68k.h: Added explcitly short-sized conditional branches, and a - bunch of aliases (fmov*, ftest*, tdivul) to support gcc's - svr4-based configurations. - - -Mon Mar 13 21:30:01 1995 Ken Raeburn - - Mon Feb 27 08:36:39 1995 Bryan Ford - * i386.h: added missing Data16/Data32 flags to a few instructions. - -Wed Mar 8 15:19:53 1995 Ian Lance Taylor - - * mips.h (OP_MASK_FR, OP_SH_FR): Define. - (OP_MASK_BCC, OP_SH_BCC): Define. - (OP_MASK_PREFX, OP_SH_PREFX): Define. - (OP_MASK_CCC, OP_SH_CCC): Define. - (INSN_READ_FPR_R): Define. - (INSN_RFE): Delete. - -Wed Mar 8 03:13:23 1995 Ken Raeburn - - * m68k.h (enum m68k_architecture): Deleted. - (struct m68k_opcode_alias): New type. - (m68k_opcodes): Now const. Deleted opcode aliases with exactly - matching constraints, values and flags. As a side effect of this, - the MOTOROLA_SYNTAX_ONLY and MIT_SYNTAX_ONLY macros, which so far - as I know were never used, now may need re-examining. - (numopcodes): Now const. - (m68k_opcode_aliases, numaliases): New variables. - (endop): Deleted. - [DONT_DEFINE_TABLE]: Declare numopcodes, numaliases, and - m68k_opcode_aliases; update declaration of m68k_opcodes. - - -Mon Mar 6 10:02:00 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa.h (delay_type): Delete unused enumeration. - (pa_opcode): Replace unused delayed field with an architecture - field. - (pa_opcodes): Mark each instruction as either PA1.0 or PA1.1. - -Fri Mar 3 16:10:24 1995 Ian Lance Taylor - - * mips.h (INSN_ISA4): Define. - -Fri Feb 24 19:13:37 1995 Ian Lance Taylor - - * mips.h (M_DLA_AB, M_DLI): Define. - -Thu Feb 23 17:33:09 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa.h (fstwx): Fix single-bit error. - -Wed Feb 15 12:19:52 1995 Ian Lance Taylor - - * mips.h (M_ULD, M_ULD_A, M_USD, M_USD_A): Define. - - -Mon Feb 6 10:35:23 1995 J.T. Conklin - - * i386.h: added cpuid instruction , and dr[0-7] aliases for the - debug registers. From Charles Hannum (mycroft@netbsd.org). - -Mon Feb 6 03:31:54 1995 Ken Raeburn - - Changes from Bryan Ford for 16-bit - i386 support: - * i386.h (MOV_AX_DISP32): New macro. - (i386_optab): Added Data16 and Data32 as needed. Added "w" forms - of several call/return instructions. - (ADDR_PREFIX_OPCODE): New macro. - -Mon Jan 23 16:45:43 1995 Ken Raeburn - - Sat Jan 21 17:50:38 1995 Pat Rankin (rankin@eql.caltech.edu) - - * ../include/opcode/vax.h (struct vot_wot, field `args'): make - it pointer to const char; - (struct vot, field `name'): ditto. - -Thu Jan 19 14:47:53 1995 Ken Raeburn - - * vax.h: Supply and properly group all values in end sentinel. - -Tue Jan 17 10:55:30 1995 Ian Lance Taylor - - * mips.h (INSN_ISA, INSN_4650): Define. - - - -Wed Oct 19 13:34:17 1994 Ian Lance Taylor - - * a29k.h: Add operand type 'I' for `inv' and `iretinv'. On - systems with a separate instruction and data cache, such as the - 29040, these instructions take an optional argument. - -Wed Sep 14 17:44:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * mips.h (INSN_STORE_MEMORY): Correct value to not conflict with - INSN_TRAP. - -Tue Sep 6 11:39:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * mips.h (INSN_STORE_MEMORY): Define. - -Thu Jul 28 19:28:07 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * sparc.h: Document new operand type 'x'. - -Tue Jul 26 17:48:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * i960.h (I_CX2): New instruction category. It includes - instructions available on Cx and Jx processors. - (I_JX): New instruction category, for JX-only instructions. - (i960_opcodes): Put eshro and sysctl in I_CX2 category. Added - Jx-only instructions, in I_JX category. - -Wed Jul 13 18:43:47 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * ns32k.h (endop): Made pointer const too. - -Sun Jul 10 11:01:09 1994 Ian Dall (dall@hfrd.dsto.gov.au) - - * ns32k.h: Drop Q operand type as there is no correct use - for it. Add I and Z operand types which allow better checking. - -Thu Jul 7 12:34:48 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * h8300.h (xor.l) :fix bit pattern. - (L_2): New size of operand. - (trapa): Use it. - -Fri Jun 10 16:38:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m68k.h: Move "trap" before "tpcc" to change disassembly. - -Fri Jun 3 15:57:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * sparc.h: Include v9 definitions. - -Thu Jun 2 12:23:17 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * m68k.h (m68060): Defined. - (m68040up, mfloat, mmmu): Include it. - (struct m68k_opcode): Widen `arch' field. - (m68k_opcodes): Updated for M68060. Removed comments that were - instructions commented out by "JF" years ago. - -Thu Apr 28 18:31:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * m68k.h (struct m68k_opcode): Shorten `arch' field to 8 bits, and - add a one-bit `flags' field. - (F_ALIAS): New macro. - -Wed Apr 27 11:29:52 1994 Steve Chamberlain (sac@cygnus.com) - - * h8300.h (dec, inc): Get encoding right. - -Mon Apr 4 13:12:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc.h (struct powerpc_operand): Removed signedp field; just use - a flag instead. - (PPC_OPERAND_SIGNED): Define. - (PPC_OPERAND_SIGNOPT): Define. - -Thu Mar 31 19:34:08 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * i386.h (IS_JUMP_ON_ECX_ZERO, "jcxz" pattern): Operand size - prefix is 0x66, not 0x67. Patch from H.J. Lu (hlu@nynexst.com). - -Thu Mar 3 15:51:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * i386.h: Reverse last change. It'll be handled in gas instead. - -Thu Feb 24 15:29:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * i386.h (sar): Disabled the two-operand Imm1 form, since it was - slower on the 486 and used the implicit shift count despite the - explicit operand. The one-operand form is still available to get - the shorter form with the implicit shift count. - -Thu Feb 17 12:27:52 1994 Torbjorn Granlund (tege@mexican.cygnus.com) - - * hppa.h: Fix typo in fstws arg string. - -Wed Feb 9 21:23:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc.h (struct powerpc_opcode): Make operands field unsigned. - -Mon Feb 7 19:14:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc.h (PPC_OPCODE_601): Define. - -Fri Feb 4 23:43:50 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa.h (addb): Use '@' for addb and addib pseudo ops. - (so we can determine valid completers for both addb and addb[tf].) - - * hppa.h (xmpyu): No floating point format specifier for the - xmpyu instruction. - -Fri Feb 4 23:36:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc.h (PPC_OPERAND_NEXT): Define. - (PPC_OPERAND_NEGATIVE): Change value to make room for above. - (struct powerpc_macro): Define. - (powerpc_macros, powerpc_num_macros): Declare. - -Fri Jan 21 19:13:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc.h: New file. Header file for PowerPC opcode table. - -Mon Jan 17 00:14:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa.h: More minor template fixes for sfu and copr (to allow - for easier disassembly). - - * hppa.h: Fix templates for all the sfu and copr instructions. - -Wed Dec 15 15:12:42 1993 Ken Raeburn (raeburn@cujo.cygnus.com) - - * i386.h (push): Permit Imm16 operand too. - -Sat Dec 11 16:14:06 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * h8300.h (andc): Exists in base arch. - -Wed Dec 1 12:15:32 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * From Hisashi MINAMINO - * hppa.h: #undef NONE to avoid conflict with hiux include files. - -Sun Nov 21 22:06:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa.h: Add FP quadword store instructions. - -Wed Nov 17 17:13:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h: (M_J_A): Added. - (M_LA): Removed. - -Mon Nov 8 12:12:47 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (OP_MASK_CACHE, OP_SH_CACHE): Define. From Ted Lemon - . - -Sun Nov 7 00:30:11 1993 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa.h: Immediate field in probei instructions is unsigned, - not low-sign extended. - -Wed Nov 3 10:30:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m88k.h (RRI10MASK): Change from 0xfc00ffe0 to 0xfc00fc00. - -Tue Nov 2 12:41:30 1993 Ken Raeburn (raeburn@rover.cygnus.com) - - * i386.h: Add "fxch" without operand. - -Mon Nov 1 18:13:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (M_JAL_1, M_JAL_2, M_JAL_A): Added. - -Sat Oct 2 22:26:11 1993 Jeffrey A Law (law@snake.cs.utah.edu) - - * hppa.h: Add gfw and gfr to the opcode table. - -Wed Sep 29 16:23:00 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * m88k.h: extended to handle m88110. - -Tue Sep 28 19:19:08 1993 Jeffrey A Law (law@snake.cs.utah.edu) - - * hppa.h (be, ble): Use operand type 'z' to denote absolute branch - addresses. - -Tue Sep 14 14:04:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * i960.h (i960_opcodes): Properly bracket initializers. - -Mon Sep 13 12:50:52 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * m88k.h (BOFLAG): rewrite to avoid nested comment. - -Mon Sep 13 15:46:06 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m68k.h (two): Protect second argument with parentheses. - -Fri Sep 10 16:29:47 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * i386.h (i386_optab): Added new instruction "rsm" (for i386sl). - Deleted old in/out instructions in "#if 0" section. - -Thu Sep 9 17:42:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * i386.h (i386_optab): Properly bracket initializers. - -Wed Aug 25 13:50:56 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * hppa.h (pa_opcode): Use '|' for movb and movib insns. (From - Jeff Law, law@cs.utah.edu). - -Mon Aug 23 16:55:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * i386.h (lcall): Accept Imm32 operand also. - -Mon Aug 23 12:43:11 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (M_ABSU): Removed (absolute value of unsigned number??). - (M_DABS): Added. - -Thu Aug 19 15:08:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h (INSN_*): Changed values. Removed unused definitions. - Added INSN_COND_BRANCH_LIKELY, INSN_ISA2 and INSN_ISA3. Split - INSN_LOAD_DELAY into INSN_LOAD_MEMORY_DELAY and - INSN_LOAD_COPROC_DELAY. Split INSN_COPROC_DELAY into - INSN_COPROC_MOVE_DELAY and INSN_COPROC_MEMORY_DELAY. - (M_*): Added new values for r6000 and r4000 macros. - (ANY_DELAY): Removed. - -Wed Aug 18 15:37:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h: Added M_LI_S and M_LI_SS. - -Tue Aug 17 07:08:08 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * h8300.h: Get some rare mov.bs correct. - -Thu Aug 5 09:15:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * sparc.h: Don't define const ourself; rely on ansidecl.h having - been included. - -Fri Jul 30 18:41:11 1993 John Gilmore (gnu@cygnus.com) - - * sparc.h (F_JSR, F_UNBR, F_CONDBR): Add new flags to mark - jump instructions, for use in disassemblers. - -Thu Jul 22 07:25:27 1993 Ian Lance Taylor (ian@cygnus.com) - - * m88k.h: Make bitfields just unsigned, not unsigned long or - unsigned short. - -Wed Jul 21 11:55:31 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * hppa.h: New argument type 'y'. Use in various float instructions. - -Mon Jul 19 17:17:03 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * hppa.h (break): First immediate field is unsigned. - - * hppa.h: Add rfir instruction. - -Sun Jul 18 16:28:08 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * mips.h: Split the actual table out into ../../opcodes/mips-opc.c. - -Fri Jul 16 09:59:29 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h: Reworked the hazard information somewhat, and fixed some - bugs in the instruction hazard descriptions. - -Thu Jul 15 12:42:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m88k.h: Corrected a couple of opcodes. - -Tue Jul 6 15:17:35 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips.h: Replaced with version from Ralph Campbell and OSF. The - new version includes instruction hazard information, but is - otherwise reasonably similar. - -Thu Jul 1 20:36:17 1993 Doug Evans (dje@canuck.cygnus.com) - - * h8300.h: Fix typo in UNOP3 (affected sh[al][lr].l). - -Fri Jun 11 18:38:44 1993 Ken Raeburn (raeburn@cygnus.com) - - Patches from Jeff Law, law@cs.utah.edu: - * hppa.h: Clean up some of the OLD_TABLE, non-OLD_TABLE braindamage. - Make the tables be the same for the following instructions: - "bb", "addb[tf]", "addib[tf]", "add", "add[loc]", "addco", - "sh[123]add", "sh[123]add[lo]", "sub", "sub[obt]", "sub[bt]o", - "ds", "comclr", "addi", "addi[ot]", "addito", "subi", "subio", - "comiclr", "fadd", "fsub", "fmpy", "fdiv", "fsqrt", "fabs", - "frnd", "fcpy", "fcnvff", "fcnvxf", "fcnvfx", "fcnvfxt", - "fcmp", and "ftest". - - * hppa.h: Make new and old tables the same for "break", "mtctl", - "mfctl", "bb", "ssm", "rsm", "xmpyu", "fmpyadd", "fmpysub". - Fix typo in last patch. Collapse several #ifdefs into a - single #ifdef. - - * hppa.h: Delete remaining OLD_TABLE code. Bring some - of the comments up-to-date. - - * hppa.h: Update "free list" of letters and update - comments describing each letter's function. - -Fri Jun 4 15:41:37 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * h8300.h: checkpoint, includes H8/300-H opcodes. - -Thu Jun 3 15:42:59 1993 Stu Grossman (grossman@cygnus.com) - - * Patches from Jeffrey Law . - * hppa.h: Rework single precision FP - instructions so that they correctly disassemble code - PA1.1 code. - -Thu May 27 19:21:22 1993 Bruce Bauman (boot@osf.org) - - * i386.h (i386_optab, mov pattern): Remove Mem16 restriction from - mov to allow instructions like mov ss,xyz(ecx) to assemble. - -Tue May 25 00:39:40 1993 Ken Raeburn (raeburn@cygnus.com) - - * hppa.h: Use new version from Utah if OLD_TABLE isn't defined; - gdb will define it for now. - -Mon May 24 15:20:06 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * sparc.h: Don't end enumerator list with comma. - -Fri May 14 15:15:50 1993 Ian Lance Taylor (ian@cygnus.com) - - * Based on patches from davidj@ICSI.Berkeley.EDU (David Johnson): - * mips.h (OP_MASK_COPZ, OP_SH_COPZ): Define. - ("bc2t"): Correct typo. - ("[ls]wc[023]"): Use T rather than t. - ("c[0123]"): Define general coprocessor instructions. - -Mon May 10 06:02:25 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * m68k.h: Move split point for gcc compilation more towards - middle. - -Fri Apr 9 13:26:16 1993 Jim Kingdon (kingdon@cygnus.com) - - * rs6k.h: Clean up instructions for primary opcode 19 (many were - simply wrong, ics, rfi, & rfsvc were missing). - Add "a" to opr_ext for "bb". Doc fix. - -Thu Mar 18 13:45:31 1993 Per Bothner (bothner@rtl.cygnus.com) - - * i386.h: 486 extensions from John Hassey (hassey@dg-rtp.dg.com). - * mips.h: Add casts, to suppress warnings about shifting too much. - * m68k.h: Document the placement code '9'. - -Thu Feb 18 02:03:14 1993 John Gilmore (gnu@cygnus.com) - - * m68k.h (BREAK_UP_BIG_DECL, AND_OTHER_PART): Add kludge which - allows callers to break up the large initialized struct full of - opcodes into two half-sized ones. This permits GCC to compile - this module, since it takes exponential space for initializers. - (numopcodes, endop): Revise to use AND_OTHER_PART in size calcs. - -Thu Feb 4 02:06:56 1993 John Gilmore (gnu@cygnus.com) - - * a29k.h: Remove RCS crud, update GPL to v2, update copyrights. - * convex.h: Added, from GDB's convx-opcode.h. Added CONST to all - initialized structs in it. - -Thu Jan 28 21:32:22 1993 John Gilmore (gnu@cygnus.com) - - Delta 88 changes inspired by Carl Greco, : - * m88k.h (PMEM): Avoid previous definition from . - (AND): Change to AND_ to avoid ansidecl.h `AND' conflict. - -Sat Jan 23 18:10:49 PST 1993 Ralph Campbell (ralphc@pyramid.com) - - * mips.h: document "i" and "j" operands correctly. - -Thu Jan 7 15:58:13 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips.h: Removed endianness dependency. - -Sun Jan 3 14:13:35 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * h8300.h: include info on number of cycles per instruction. - -Mon Dec 21 21:29:08 1992 Stu Grossman (grossman at cygnus.com) - - * hppa.h: Move handy aliases to the front. Fix masks for extract - and deposit instructions. - -Sat Dec 12 16:09:48 1992 Ian Lance Taylor (ian@cygnus.com) - - * i386.h: accept shld and shrd both with and without the shift - count argument, which is always %cl. - -Fri Nov 27 17:13:18 1992 Ken Raeburn (raeburn at cygnus.com) - - * i386.h (i386_optab_end, i386_regtab_end): Now const. - (one_byte_segment_defaults, two_byte_segment_defaults, - i386_prefixtab_end): Ditto. - -Mon Nov 23 10:47:25 1992 Ken Raeburn (raeburn@cygnus.com) - - * vax.h (bb*): Use "v" (bitfield type), not "a" (address operand) - for operand 2; from John Carr, jfc@dsg.dec.com. - -Wed Nov 4 07:36:49 1992 Ken Raeburn (raeburn@cygnus.com) - - * m68k.h: Define FIXED_SIZE_BRANCH, so bsr and bra instructions - always use 16-bit offsets. Makes calculated-size jump tables - feasible. - -Fri Oct 16 22:52:43 1992 Ken Raeburn (raeburn@cygnus.com) - - * i386.h: Fix one-operand forms of in* and out* patterns. - -Tue Sep 22 14:08:14 1992 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * m68k.h: Added CPU32 support. - -Tue Sep 22 00:38:41 1992 John Gilmore (gnu@cygnus.com) - - * mips.h (break): Disassemble the argument. Patch from - jonathan@cs.stanford.edu (Jonathan Stone). - -Wed Sep 9 11:25:28 1992 Ian Lance Taylor (ian@cygnus.com) - - * m68k.h: merged Motorola and MIT syntax. - -Thu Sep 3 09:33:22 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * m68k.h (pmove): make the tests less strict, the 68k book is - wrong. - -Tue Aug 25 23:25:19 1992 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * m68k.h (m68ec030): Defined as alias for 68030. - (m68k_opcodes): New type characters "3" for 68030 MMU regs and "t" - for immediate 0-7 added. Set up some opcodes (ptest, bkpt) to use - them. Tightened description of "fmovex" to distinguish it from - some "pmove" encodings. Added "pmove" for 68030 MMU regs, cleaned - up descriptions that claimed versions were available for chips not - supporting them. Added "pmovefd". - -Mon Aug 24 12:04:51 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * m68k.h: fix where the . goes in divull - -Wed Aug 19 11:22:24 1992 Ian Lance Taylor (ian@cygnus.com) - - * m68k.h: the cas2 instruction is supposed to be written with - indirection on the last two operands, which can be either data or - address registers. Added a new operand type 'r' which accepts - either register type. Added new cases for cas2l and cas2w which - use them. Corrected masks for cas2 which failed to recognize use - of address register. - -Fri Aug 14 14:20:38 1992 Per Bothner (bothner@cygnus.com) - - * m68k.h: Merged in patches (mostly m68040-specific) from - Colin Smith . - - * m68k.h: Merged m68kmri.h and m68k.h (using the former as a - base). Also cleaned up duplicates, re-ordered instructions for - the sake of dis-assembling (so aliases come after standard names). - * m68kmri.h: Now just defines some macros, and #includes m68k.h. - -Wed Aug 12 16:38:15 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * m68kmri.h: added various opcodes. Moved jbxx to bxxes. Filled in - all missing .s - -Mon Aug 10 23:22:33 1992 Ken Raeburn (raeburn@cygnus.com) - - * sparc.h: Moved tables to BFD library. - - * i386.h (i386_optab): Add fildq, fistpq aliases used by gcc. - -Sun Jun 28 13:29:03 1992 Fred Fish (fnf@cygnus.com) - - * h8300.h: Finish filling in all the holes in the opcode table, - so that the Lucid C compiler can digest this as well... - -Fri Jun 26 21:27:17 1992 John Gilmore (gnu at cygnus.com) - - * i386.h: Add setc, setnc, addr16, data16, repz, repnz aliases. - Fix opcodes on various sizes of fild/fist instructions - (16bit=no suffix, 32bit="l" suffix, 64bit="ll" suffix). - Use tabs to indent for comments. Fixes suggested by Minh Tran-Le. - -Thu Jun 25 16:13:26 1992 Stu Grossman (grossman at cygnus.com) - - * h8300.h: Fill in all the holes in the opcode table so that the - losing HPUX C compiler can digest this... - -Thu Jun 11 12:15:25 1992 John Gilmore (gnu at cygnus.com) - - * mips.h: Fix decoding of coprocessor instructions, somewhat. - (Fix by Eric Anderson, 3jean@maas-neotek.arc.nasa.gov.) - -Thu May 28 11:17:44 1992 Jim Wilson (wilson@sphagnum.cygnus.com) - - * sparc.h: Add new architecture variant sparclite; add its scan - and divscc opcodes. Define ARCHITECTURES_CONFLICT_P macro. - -Tue May 5 14:23:27 1992 Per Bothner (bothner@rtl.cygnus.com) - - * mips.h: Add some more opcode synonyms (from Frank Yellin, - fy@lucid.com). - -Thu Apr 16 18:25:26 1992 Per Bothner (bothner@cygnus.com) - - * rs6k.h: New version from IBM (Metin). - -Thu Apr 9 00:31:19 1992 Per Bothner (bothner@rtl.cygnus.com) - - * rs6k.h: Fix incorrect extended opcode for instructions `fm' - and `fd'. (From metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik).) - -Tue Apr 7 13:38:47 1992 Stu Grossman (grossman at cygnus.com) - - * rs6k.h: Move from ../../gdb/rs6k-opcode.h. - -Fri Apr 3 11:30:20 1992 Fred Fish (fnf@cygnus.com) - - * m68k.h (one, two): Cast macro args to unsigned to suppress - complaints from compiler and lint about integer overflow during - shift. - -Sun Mar 29 12:22:08 1992 John Gilmore (gnu at cygnus.com) - - * sparc.h (OP): Avoid signed overflow when shifting to high order bit. - -Fri Mar 6 00:22:38 1992 John Gilmore (gnu at cygnus.com) - - * mips.h: Make bitfield layout depend on the HOST compiler, - not on the TARGET system. - -Fri Feb 21 01:29:51 1992 K. Richard Pixley (rich@cygnus.com) - - * i386.h: added inb, inw, outb, outw opcodes, added att syntax for - scmp, slod, smov, ssca, ssto. Curtesy Minh Tran-Le - . - -Thu Jan 30 07:31:44 1992 Steve Chamberlain (sac at rtl.cygnus.com) - - * h8300.h: turned op_type enum into #define list - -Thu Jan 30 01:07:24 1992 John Gilmore (gnu at cygnus.com) - - * sparc.h: Remove "cypress" architecture. Remove "fitox" and - similar instructions -- they've been renamed to "fitoq", etc. - REALLY fix tsubcctv. Fix "fcmpeq" and "fcmpq" which had wrong - number of arguments. - * h8300.h: Remove extra ; which produces compiler warning. - -Tue Jan 28 22:59:22 1992 Stu Grossman (grossman at cygnus.com) - - * sparc.h: fix opcode for tsubcctv. - -Tue Jan 7 17:19:39 1992 K. Richard Pixley (rich at cygnus.com) - - * sparc.h: fba and cba are now aliases for fb and cb respectively. - -Fri Dec 27 10:55:50 1991 Per Bothner (bothner at cygnus.com) - - * sparc.h (nop): Made the 'lose' field be even tighter, - so only a standard 'nop' is disassembled as a nop. - -Sun Dec 22 12:18:18 1991 Michael Tiemann (tiemann at cygnus.com) - - * sparc.h (nop): Add RD_GO to `lose' so that only %g0 in dest is - disassembled as a nop. - -Tue Dec 10 00:22:20 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * sparc.h: fix a typo. - -Sat Nov 30 20:40:51 1991 Steve Chamberlain (sac at rtl.cygnus.com) - - * a29k.h, arm.h, h8300.h, i386.h, i860.h, i960.h , m68k.h, - m88k.h, mips.h , np1.h, ns32k.h, pn.h, pyr.h, sparc.h, tahoe.h, - vax.h, ChangeLog: renamed from ../-opcode.h - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/include/opcode/a29k.h b/contrib/gdb/include/opcode/a29k.h deleted file mode 100644 index 002e127d15e..00000000000 --- a/contrib/gdb/include/opcode/a29k.h +++ /dev/null @@ -1,285 +0,0 @@ -/* Table of opcodes for the AMD 29000 family. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - -This file is part of GDB and GAS. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -struct a29k_opcode { - /* Name of the instruction. */ - char *name; - - /* Opcode word */ - unsigned long opcode; - - /* A string of characters which describe the operands. - Valid characters are: - , Itself. The character appears in the assembly code. - a RA. The register number is in bits 8-15 of the instruction. - b RB. The register number is in bits 0-7 of the instruction. - c RC. The register number is in bits 16-23 of the instruction. - i An immediate operand is in bits 0-7 of the instruction. - x Bits 0-7 and 16-23 of the instruction are bits 0-7 and 8-15 - (respectively) of the immediate operand. - h Same as x but the instruction contains bits 16-31 of the - immediate operand. - X Same as x but bits 16-31 of the signed immediate operand - are set to 1 (thus the operand is always negative). - P,A Bits 0-7 and 16-23 of the instruction are bits 2-9 and 10-17 - (respectively) of the immediate operand. - P=PC-relative, sign-extended to 32 bits. - A=Absolute, zero-extended to 32 bits. - e CE bit (bit 23) for a load/store instruction. - n Control field (bits 16-22) for a load/store instruction. - v Immediate operand in bits 16-23 of the instruction. - (used for trap numbers). - s SA. Special-purpose register number in bits 8-15 - of the instruction. - u UI--bit 7 of the instruction. - r RND--bits 4-6 of the instruction. - d FD--bits 2-3 of the instruction. - f FS--bits 0-1 of the instruction. - I ID--bits 16-17 of the instruction. - - Extensions for 29050: - - d FMT--bits 2-3 of the instruction (not really new). - f ACN--bits 0-1 of the instruction (not really new). - F FUNC--Special function in bits 18-21 of the instruction. - C ACN--bits 16-17 specifying the accumlator register. */ - char *args; -}; - -#ifndef CONST -#define CONST -#endif /* CONST */ - -static CONST struct a29k_opcode a29k_opcodes[] = -{ - -{ "add", 0x14000000, "c,a,b" }, -{ "add", 0x15000000, "c,a,i" }, -{ "addc", 0x1c000000, "c,a,b" }, -{ "addc", 0x1d000000, "c,a,i" }, -{ "addcs", 0x18000000, "c,a,b" }, -{ "addcs", 0x19000000, "c,a,i" }, -{ "addcu", 0x1a000000, "c,a,b" }, -{ "addcu", 0x1b000000, "c,a,i" }, -{ "adds", 0x10000000, "c,a,b" }, -{ "adds", 0x11000000, "c,a,i" }, -{ "addu", 0x12000000, "c,a,b" }, -{ "addu", 0x13000000, "c,a,i" }, -{ "and", 0x90000000, "c,a,b" }, -{ "and", 0x91000000, "c,a,i" }, -{ "andn", 0x9c000000, "c,a,b" }, -{ "andn", 0x9d000000, "c,a,i" }, -{ "aseq", 0x70000000, "v,a,b" }, -{ "aseq", 0x71000000, "v,a,i" }, -{ "asge", 0x5c000000, "v,a,b" }, -{ "asge", 0x5d000000, "v,a,i" }, -{ "asgeu", 0x5e000000, "v,a,b" }, -{ "asgeu", 0x5f000000, "v,a,i" }, -{ "asgt", 0x58000000, "v,a,b" }, -{ "asgt", 0x59000000, "v,a,i" }, -{ "asgtu", 0x5a000000, "v,a,b" }, -{ "asgtu", 0x5b000000, "v,a,i" }, -{ "asle", 0x54000000, "v,a,b" }, -{ "asle", 0x55000000, "v,a,i" }, -{ "asleu", 0x56000000, "v,a,b" }, -{ "asleu", 0x57000000, "v,a,i" }, -{ "aslt", 0x50000000, "v,a,b" }, -{ "aslt", 0x51000000, "v,a,i" }, -{ "asltu", 0x52000000, "v,a,b" }, -{ "asltu", 0x53000000, "v,a,i" }, -{ "asneq", 0x72000000, "v,a,b" }, -{ "asneq", 0x73000000, "v,a,i" }, -{ "call", 0xa8000000, "a,P" }, -{ "call", 0xa9000000, "a,A" }, -{ "calli", 0xc8000000, "a,b" }, -{ "class", 0xe6000000, "c,a,f" }, -{ "clz", 0x08000000, "c,b" }, -{ "clz", 0x09000000, "c,i" }, -{ "const", 0x03000000, "a,x" }, -{ "consth", 0x02000000, "a,h" }, -{ "consthz", 0x05000000, "a,h" }, -{ "constn", 0x01000000, "a,X" }, -{ "convert", 0xe4000000, "c,a,u,r,d,f" }, -{ "cpbyte", 0x2e000000, "c,a,b" }, -{ "cpbyte", 0x2f000000, "c,a,i" }, -{ "cpeq", 0x60000000, "c,a,b" }, -{ "cpeq", 0x61000000, "c,a,i" }, -{ "cpge", 0x4c000000, "c,a,b" }, -{ "cpge", 0x4d000000, "c,a,i" }, -{ "cpgeu", 0x4e000000, "c,a,b" }, -{ "cpgeu", 0x4f000000, "c,a,i" }, -{ "cpgt", 0x48000000, "c,a,b" }, -{ "cpgt", 0x49000000, "c,a,i" }, -{ "cpgtu", 0x4a000000, "c,a,b" }, -{ "cpgtu", 0x4b000000, "c,a,i" }, -{ "cple", 0x44000000, "c,a,b" }, -{ "cple", 0x45000000, "c,a,i" }, -{ "cpleu", 0x46000000, "c,a,b" }, -{ "cpleu", 0x47000000, "c,a,i" }, -{ "cplt", 0x40000000, "c,a,b" }, -{ "cplt", 0x41000000, "c,a,i" }, -{ "cpltu", 0x42000000, "c,a,b" }, -{ "cpltu", 0x43000000, "c,a,i" }, -{ "cpneq", 0x62000000, "c,a,b" }, -{ "cpneq", 0x63000000, "c,a,i" }, -{ "dadd", 0xf1000000, "c,a,b" }, -{ "ddiv", 0xf7000000, "c,a,b" }, -{ "deq", 0xeb000000, "c,a,b" }, -{ "dge", 0xef000000, "c,a,b" }, -{ "dgt", 0xed000000, "c,a,b" }, -{ "div", 0x6a000000, "c,a,b" }, -{ "div", 0x6b000000, "c,a,i" }, -{ "div0", 0x68000000, "c,b" }, -{ "div0", 0x69000000, "c,i" }, -{ "divide", 0xe1000000, "c,a,b" }, -{ "dividu", 0xe3000000, "c,a,b" }, -{ "divl", 0x6c000000, "c,a,b" }, -{ "divl", 0x6d000000, "c,a,i" }, -{ "divrem", 0x6e000000, "c,a,b" }, -{ "divrem", 0x6f000000, "c,a,i" }, -{ "dmac", 0xd9000000, "F,C,a,b" }, -{ "dmsm", 0xdb000000, "c,a,b" }, -{ "dmul", 0xf5000000, "c,a,b" }, -{ "dsub", 0xf3000000, "c,a,b" }, -{ "emulate", 0xd7000000, "v,a,b" }, -{ "exbyte", 0x0a000000, "c,a,b" }, -{ "exbyte", 0x0b000000, "c,a,i" }, -{ "exhw", 0x7c000000, "c,a,b" }, -{ "exhw", 0x7d000000, "c,a,i" }, -{ "exhws", 0x7e000000, "c,a" }, -{ "extract", 0x7a000000, "c,a,b" }, -{ "extract", 0x7b000000, "c,a,i" }, -{ "fadd", 0xf0000000, "c,a,b" }, -{ "fdiv", 0xf6000000, "c,a,b" }, -{ "fdmul", 0xf9000000, "c,a,b" }, -{ "feq", 0xea000000, "c,a,b" }, -{ "fge", 0xee000000, "c,a,b" }, -{ "fgt", 0xec000000, "c,a,b" }, -{ "fmac", 0xd8000000, "F,C,a,b" }, -{ "fmsm", 0xda000000, "c,a,b" }, -{ "fmul", 0xf4000000, "c,a,b" }, -{ "fsub", 0xf2000000, "c,a,b" }, -{ "halt", 0x89000000, "" }, -{ "inbyte", 0x0c000000, "c,a,b" }, -{ "inbyte", 0x0d000000, "c,a,i" }, -{ "inhw", 0x78000000, "c,a,b" }, -{ "inhw", 0x79000000, "c,a,i" }, -{ "inv", 0x9f000000, "I" }, -{ "iret", 0x88000000, "" }, -{ "iretinv", 0x8c000000, "I" }, -{ "jmp", 0xa0000000, "P" }, -{ "jmp", 0xa1000000, "A" }, -{ "jmpf", 0xa4000000, "a,P" }, -{ "jmpf", 0xa5000000, "a,A" }, -{ "jmpfdec", 0xb4000000, "a,P" }, -{ "jmpfdec", 0xb5000000, "a,A" }, -{ "jmpfi", 0xc4000000, "a,b" }, -{ "jmpi", 0xc0000000, "b" }, -{ "jmpt", 0xac000000, "a,P" }, -{ "jmpt", 0xad000000, "a,A" }, -{ "jmpti", 0xcc000000, "a,b" }, -{ "load", 0x16000000, "e,n,a,b" }, -{ "load", 0x17000000, "e,n,a,i" }, -{ "loadl", 0x06000000, "e,n,a,b" }, -{ "loadl", 0x07000000, "e,n,a,i" }, -{ "loadm", 0x36000000, "e,n,a,b" }, -{ "loadm", 0x37000000, "e,n,a,i" }, -{ "loadset", 0x26000000, "e,n,a,b" }, -{ "loadset", 0x27000000, "e,n,a,i" }, -{ "mfacc", 0xe9000100, "c,d,f" }, -{ "mfsr", 0xc6000000, "c,s" }, -{ "mftlb", 0xb6000000, "c,a" }, -{ "mtacc", 0xe8010000, "a,d,f" }, -{ "mtsr", 0xce000000, "s,b" }, -{ "mtsrim", 0x04000000, "s,x" }, -{ "mttlb", 0xbe000000, "a,b" }, -{ "mul", 0x64000000, "c,a,b" }, -{ "mul", 0x65000000, "c,a,i" }, -{ "mull", 0x66000000, "c,a,b" }, -{ "mull", 0x67000000, "c,a,i" }, -{ "multiplu", 0xe2000000, "c,a,b" }, -{ "multiply", 0xe0000000, "c,a,b" }, -{ "multm", 0xde000000, "c,a,b" }, -{ "multmu", 0xdf000000, "c,a,b" }, -{ "mulu", 0x74000000, "c,a,b" }, -{ "mulu", 0x75000000, "c,a,i" }, -{ "nand", 0x9a000000, "c,a,b" }, -{ "nand", 0x9b000000, "c,a,i" }, -{ "nop", 0x70400101, "" }, -{ "nor", 0x98000000, "c,a,b" }, -{ "nor", 0x99000000, "c,a,i" }, -{ "or", 0x92000000, "c,a,b" }, -{ "or", 0x93000000, "c,a,i" }, -{ "orn", 0xaa000000, "c,a,b" }, -{ "orn", 0xab000000, "c,a,i" }, - -/* The description of "setip" in Chapter 8 ("instruction set") of the user's - manual claims that these are absolute register numbers. But section - 7.2.1 explains that they are not. The latter is correct, so print - these normally ("lr0", "lr5", etc.). */ -{ "setip", 0x9e000000, "c,a,b" }, - -{ "sll", 0x80000000, "c,a,b" }, -{ "sll", 0x81000000, "c,a,i" }, -{ "sqrt", 0xe5000000, "c,a,f" }, -{ "sra", 0x86000000, "c,a,b" }, -{ "sra", 0x87000000, "c,a,i" }, -{ "srl", 0x82000000, "c,a,b" }, -{ "srl", 0x83000000, "c,a,i" }, -{ "store", 0x1e000000, "e,n,a,b" }, -{ "store", 0x1f000000, "e,n,a,i" }, -{ "storel", 0x0e000000, "e,n,a,b" }, -{ "storel", 0x0f000000, "e,n,a,i" }, -{ "storem", 0x3e000000, "e,n,a,b" }, -{ "storem", 0x3f000000, "e,n,a,i" }, -{ "sub", 0x24000000, "c,a,b" }, -{ "sub", 0x25000000, "c,a,i" }, -{ "subc", 0x2c000000, "c,a,b" }, -{ "subc", 0x2d000000, "c,a,i" }, -{ "subcs", 0x28000000, "c,a,b" }, -{ "subcs", 0x29000000, "c,a,i" }, -{ "subcu", 0x2a000000, "c,a,b" }, -{ "subcu", 0x2b000000, "c,a,i" }, -{ "subr", 0x34000000, "c,a,b" }, -{ "subr", 0x35000000, "c,a,i" }, -{ "subrc", 0x3c000000, "c,a,b" }, -{ "subrc", 0x3d000000, "c,a,i" }, -{ "subrcs", 0x38000000, "c,a,b" }, -{ "subrcs", 0x39000000, "c,a,i" }, -{ "subrcu", 0x3a000000, "c,a,b" }, -{ "subrcu", 0x3b000000, "c,a,i" }, -{ "subrs", 0x30000000, "c,a,b" }, -{ "subrs", 0x31000000, "c,a,i" }, -{ "subru", 0x32000000, "c,a,b" }, -{ "subru", 0x33000000, "c,a,i" }, -{ "subs", 0x20000000, "c,a,b" }, -{ "subs", 0x21000000, "c,a,i" }, -{ "subu", 0x22000000, "c,a,b" }, -{ "subu", 0x23000000, "c,a,i" }, -{ "xnor", 0x96000000, "c,a,b" }, -{ "xnor", 0x97000000, "c,a,i" }, -{ "xor", 0x94000000, "c,a,b" }, -{ "xor", 0x95000000, "c,a,i" }, - -{ "", 0x0, "" } /* Dummy entry, not included in NUM_OPCODES. This - lets code examine entry i+1 without checking - if we've run off the end of the table. */ -}; - -CONST unsigned int num_opcodes = (((sizeof a29k_opcodes) / (sizeof a29k_opcodes[0])) - 1); diff --git a/contrib/gdb/include/opcode/arm.h b/contrib/gdb/include/opcode/arm.h deleted file mode 100644 index c7087eb9ed4..00000000000 --- a/contrib/gdb/include/opcode/arm.h +++ /dev/null @@ -1,294 +0,0 @@ -/* ARM opcode list. - Copyright (C) 1989, Free Software Foundation, Inc. - -This file is part of GDB and GAS. - -GDB and GAS are free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GDB and GAS are distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GDB or GAS; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* types of instruction (encoded in bits 26 and 27 of the instruction) */ - -#define TYPE_ARITHMETIC 0 -#define TYPE_LDR_STR 1 -#define TYPE_BLOCK_BRANCH 2 -#define TYPE_SWI 3 - -/* bit 25 decides whether an instruction is a block move or a branch */ -#define SUBTYPE_BLOCK 0 -#define SUBTYPE_BRANCH 1 - -/* codes to distinguish the arithmetic instructions */ - -#define OPCODE_AND 0 -#define OPCODE_EOR 1 -#define OPCODE_SUB 2 -#define OPCODE_RSB 3 -#define OPCODE_ADD 4 -#define OPCODE_ADC 5 -#define OPCODE_SBC 6 -#define OPCODE_RSC 7 -#define OPCODE_TST 8 -#define OPCODE_TEQ 9 -#define OPCODE_CMP 10 -#define OPCODE_CMN 11 -#define OPCODE_ORR 12 -#define OPCODE_MOV 13 -#define OPCODE_BIC 14 -#define OPCODE_MVN 15 - -/* condition codes */ - -#define COND_EQ 0 -#define COND_NE 1 -#define COND_CS 2 -#define COND_CC 3 -#define COND_MI 4 -#define COND_PL 5 -#define COND_VS 6 -#define COND_VC 7 -#define COND_HI 8 -#define COND_LS 9 -#define COND_GE 10 -#define COND_LT 11 -#define COND_GT 12 -#define COND_LE 13 -#define COND_AL 14 -#define COND_NV 15 - -/* Describes the format of an ARM machine instruction */ - -struct generic_fmt { - unsigned rest :25; /* the rest of the instruction */ - unsigned subtype :1; /* used to decide between block and branch */ - unsigned type :2; /* one of TYPE_* */ - unsigned cond :4; /* one of COND_* defined above */ -}; - -struct arith_fmt { - unsigned operand2 :12; /* #nn or rn or rn shift #m or rn shift rm */ - unsigned dest :4; /* place where the answer goes */ - unsigned operand1 :4; /* first operand to instruction */ - unsigned set :1; /* == 1 means set processor flags */ - unsigned opcode :4; /* one of OPCODE_* defined above */ - unsigned immed :1; /* operand2 is an immediate value */ - unsigned type :2; /* == TYPE_ARITHMETIC */ - unsigned cond :4; /* one of COND_* defined above */ -}; - -struct ldr_str_fmt { - unsigned offset :12; /* #nn or rn or rn shift #m */ - unsigned reg :4; /* destination for LDR, source for STR */ - unsigned base :4; /* base register */ - unsigned is_load :1; /* == 1 for LDR */ - unsigned writeback :1; /* == 1 means write back (base+offset) into base */ - unsigned byte :1; /* == 1 means byte access else word */ - unsigned up :1; /* == 1 means add offset else subtract it */ - unsigned pre_index :1; /* == 1 means [a,b] form else [a],b form */ - unsigned immed :1; /* == 0 means immediate offset */ - unsigned type :2; /* == TYPE_LDR_STR */ - unsigned cond :4; /* one of COND_* defined above */ -}; - -struct block_fmt { - unsigned mask :16; /* register mask */ - unsigned base :4; /* register used as base of move */ - unsigned is_load :1; /* == 1 for LDM */ - unsigned writeback :1; /* == 1 means update base after move */ - unsigned set :1; /* == 1 means set flags in pc if included in mask */ - unsigned increment :1; /* == 1 means increment base register */ - unsigned before :1; /* == 1 means inc/dec before each move */ - unsigned is_block :1; /* == SUBTYPE_BLOCK */ - unsigned type :2; /* == TYPE_BLOCK_BRANCH */ - unsigned cond :4; /* one of COND_* defined above */ -}; - -struct branch_fmt { - unsigned dest :24; /* destination of the branch */ - unsigned link :1; /* branch with link (function call) */ - unsigned is_branch :1; /* == SUBTYPE_BRANCH */ - unsigned type :2; /* == TYPE_BLOCK_BRANCH */ - unsigned cond :4; /* one of COND_* defined above */ -}; - -#define ROUND_N 0 -#define ROUND_P 1 -#define ROUND_M 2 -#define ROUND_Z 3 - -#define FLOAT2_MVF 0 -#define FLOAT2_MNF 1 -#define FLOAT2_ABS 2 -#define FLOAT2_RND 3 -#define FLOAT2_SQT 4 -#define FLOAT2_LOG 5 -#define FLOAT2_LGN 6 -#define FLOAT2_EXP 7 -#define FLOAT2_SIN 8 -#define FLOAT2_COS 9 -#define FLOAT2_TAN 10 -#define FLOAT2_ASN 11 -#define FLOAT2_ACS 12 -#define FLOAT2_ATN 13 - -#define FLOAT3_ADF 0 -#define FLOAT3_MUF 1 -#define FLOAT3_SUF 2 -#define FLOAT3_RSF 3 -#define FLOAT3_DVF 4 -#define FLOAT3_RDF 5 -#define FLOAT3_POW 6 -#define FLOAT3_RPW 7 -#define FLOAT3_RMF 8 -#define FLOAT3_FML 9 -#define FLOAT3_FDV 10 -#define FLOAT3_FRD 11 -#define FLOAT3_POL 12 - -struct float2_fmt { - unsigned operand2 :3; /* second operand */ - unsigned immed :1; /* == 1 if second operand is a constant */ - unsigned pad1 :1; /* == 0 */ - unsigned rounding :2; /* ROUND_* */ - unsigned is_double :1; /* == 1 if precision is double (only if not extended) */ - unsigned pad2 :4; /* == 1 */ - unsigned dest :3; /* destination */ - unsigned is_2_op :1; /* == 1 if 2 operand ins */ - unsigned operand1 :3; /* first operand (only of is_2_op == 0) */ - unsigned is_extended :1; /* == 1 if precision is extended */ - unsigned opcode :4; /* FLOAT2_* or FLOAT3_* depending on is_2_op */ - unsigned must_be_2 :2; /* == 2 */ - unsigned type :2; /* == TYPE_SWI */ - unsigned cond :4; /* COND_* */ -}; - -struct swi_fmt { - unsigned argument :24; /* argument to SWI (syscall number) */ - unsigned must_be_3 :2; /* == 3 */ - unsigned type :2; /* == TYPE_SWI */ - unsigned cond :4; /* one of COND_* defined above */ -}; - -union insn_fmt { - struct generic_fmt generic; - struct arith_fmt arith; - struct ldr_str_fmt ldr_str; - struct block_fmt block; - struct branch_fmt branch; - struct swi_fmt swi; - unsigned long ins; -}; - -struct opcode { - unsigned long value, mask; /* recognise instruction if (op&mask)==value */ - char *assembler; /* how to disassemble this instruction */ -}; - -/* format of the assembler string : - - %% % - %d print the bitfield in decimal - %x print the bitfield in hex - %r print as an ARM register - %f print a floating point constant if >7 else an fp register - %c print condition code (always bits 28-31) - %P print floating point precision in arithmetic insn - %Q print floating point precision in ldf/stf insn - %R print floating point rounding mode - %'c print specified char iff bit is one - %`c print specified char iff bit is zero - %?ab print a if bit is one else print b - %p print 'p' iff bits 12-15 are 15 - %o print operand2 (immediate or register + shift) - %a print address for ldr/str instruction - %b print branch destination - %A print address for ldc/stc/ldf/stf instruction - %m print register mask for ldm/stm instruction -*/ - -static struct opcode opcodes[] = { - /* ARM instructions */ - 0x00000090, 0x0fe000f0, "mul%20's %12-15r, %16-19r, %0-3r", - 0x00200090, 0x0fe000f0, "mla%20's %12-15r, %16-19r, %0-3r, %8-11r", - 0x00000000, 0x0de00000, "and%c%20's %12-15r, %16-19r, %o", - 0x00200000, 0x0de00000, "eor%c%20's %12-15r, %16-19r, %o", - 0x00400000, 0x0de00000, "sub%c%20's %12-15r, %16-19r, %o", - 0x00600000, 0x0de00000, "rsb%c%20's %12-15r, %16-19r, %o", - 0x00800000, 0x0de00000, "add%c%20's %12-15r, %16-19r, %o", - 0x00a00000, 0x0de00000, "adc%c%20's %12-15r, %16-19r, %o", - 0x00c00000, 0x0de00000, "sbc%c%20's %12-15r, %16-19r, %o", - 0x00e00000, 0x0de00000, "rsc%c%20's %12-15r, %16-19r, %o", - 0x01000000, 0x0de00000, "tst%c%p %16-19r, %o", - 0x01200000, 0x0de00000, "teq%c%p %16-19r, %o", - 0x01400000, 0x0de00000, "cmp%c%p %16-19r, %o", - 0x01600000, 0x0de00000, "cmn%c%p %16-19r, %o", - 0x01800000, 0x0de00000, "orr%c%20's %12-15r, %16-19r, %o", - 0x01a00000, 0x0de00000, "mov%c%20's %12-15r, %o", - 0x01c00000, 0x0de00000, "bic%c%20's %12-15r, %16-19r, %o", - 0x01e00000, 0x0de00000, "mvn%c%20's %12-15r, %o", - 0x04000000, 0x0c100000, "str%c%22'b %12-15r, %a", - 0x04100000, 0x0c100000, "ldr%c%22'b %12-15r, %a", - 0x08000000, 0x0e100000, "stm%c%23?id%24?ba %16-19r%22`!, %m", - 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba %16-19r%22`!, %m%22'^", - 0x0a000000, 0x0e000000, "b%c%24'l %b", - 0x0f000000, 0x0f000000, "swi%c %0-23x", - /* Floating point coprocessor instructions */ - 0x0e000100, 0x0ff08f10, "adf%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e100100, 0x0ff08f10, "muf%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e200100, 0x0ff08f10, "suf%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e300100, 0x0ff08f10, "rsf%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e400100, 0x0ff08f10, "dvf%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e500100, 0x0ff08f10, "rdf%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e600100, 0x0ff08f10, "pow%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e700100, 0x0ff08f10, "rpw%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e800100, 0x0ff08f10, "rmf%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e900100, 0x0ff08f10, "fml%c%P%R %12-14f, %16-18f, %0-3f", - 0x0ea00100, 0x0ff08f10, "fdv%c%P%R %12-14f, %16-18f, %0-3f", - 0x0eb00100, 0x0ff08f10, "frd%c%P%R %12-14f, %16-18f, %0-3f", - 0x0ec00100, 0x0ff08f10, "pol%c%P%R %12-14f, %16-18f, %0-3f", - 0x0e008100, 0x0ff08f10, "mvf%c%P%R %12-14f, %0-3f", - 0x0e108100, 0x0ff08f10, "mnf%c%P%R %12-14f, %0-3f", - 0x0e208100, 0x0ff08f10, "abs%c%P%R %12-14f, %0-3f", - 0x0e308100, 0x0ff08f10, "rnd%c%P%R %12-14f, %0-3f", - 0x0e408100, 0x0ff08f10, "sqt%c%P%R %12-14f, %0-3f", - 0x0e508100, 0x0ff08f10, "log%c%P%R %12-14f, %0-3f", - 0x0e608100, 0x0ff08f10, "lgn%c%P%R %12-14f, %0-3f", - 0x0e708100, 0x0ff08f10, "exp%c%P%R %12-14f, %0-3f", - 0x0e808100, 0x0ff08f10, "sin%c%P%R %12-14f, %0-3f", - 0x0e908100, 0x0ff08f10, "cos%c%P%R %12-14f, %0-3f", - 0x0ea08100, 0x0ff08f10, "tan%c%P%R %12-14f, %0-3f", - 0x0eb08100, 0x0ff08f10, "asn%c%P%R %12-14f, %0-3f", - 0x0ec08100, 0x0ff08f10, "acs%c%P%R %12-14f, %0-3f", - 0x0ed08100, 0x0ff08f10, "atn%c%P%R %12-14f, %0-3f", - 0x0e000110, 0x0ff00f1f, "flt%c%P%R %16-18f, %12-15r", - 0x0e100110, 0x0fff0f98, "fix%c%R %12-15r, %0-2f", - 0x0e200110, 0x0fff0fff, "wfs%c %12-15r", - 0x0e300110, 0x0fff0fff, "rfs%c %12-15r", - 0x0e400110, 0x0fff0fff, "wfc%c %12-15r", - 0x0e500110, 0x0fff0fff, "rfc%c %12-15r", - 0x0e90f110, 0x0ff8fff0, "cmf%c %16-18f, %0-3f", - 0x0eb0f110, 0x0ff8fff0, "cnf%c %16-18f, %0-3f", - 0x0ed0f110, 0x0ff8fff0, "cmfe%c %16-18f, %0-3f", - 0x0ef0f110, 0x0ff8fff0, "cnfe%c %16-18f, %0-3f", - 0x0c000100, 0x0e100f00, "stf%c%Q %12-14f, %A", - 0x0c100100, 0x0e100f00, "ldf%c%Q %12-14f, %A", - /* Generic coprocessor instructions */ - 0x0e000000, 0x0f000010, "cdp%c %8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}", - 0x0e000010, 0x0f100010, "mrc%c %8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}", - 0x0e100010, 0x0f100010, "mcr%c %8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}", - 0x0c000000, 0x0e100000, "stc%c%22`l %8-11d, cr%12-15d, %A", - 0x0c100000, 0x0e100000, "ldc%c%22`l %8-11d, cr%12-15d, %A", - /* the rest */ - 0x00000000, 0x00000000, "undefined instruction %0-31x", -}; -#define N_OPCODES (sizeof opcodes / sizeof opcodes[0]) diff --git a/contrib/gdb/include/opcode/convex.h b/contrib/gdb/include/opcode/convex.h deleted file mode 100644 index efaeebb65a5..00000000000 --- a/contrib/gdb/include/opcode/convex.h +++ /dev/null @@ -1,1711 +0,0 @@ -/* Information for instruction disassembly on the Convex. - Copyright 1989, 1993 Free Software Foundation. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef CONST -#define CONST -#endif /* CONST */ - -#define xxx 0 -#define rrr 1 -#define rr 2 -#define rxr 3 -#define r 4 -#define nops 5 -#define nr 6 -#define pcrel 7 -#define lr 8 -#define rxl 9 -#define rlr 10 -#define rrl 11 -#define iml 12 -#define imr 13 -#define a1r 14 -#define a1l 15 -#define a2r 16 -#define a2l 17 -#define a3 18 -#define a4 19 -#define a5 20 -#define V 1 -#define S 2 -#define VM 3 -#define A 4 -#define VL 5 -#define VS 6 -#define VLS 7 -#define PSW 8 -/* Prevent an error during "make depend". */ -#if !defined (PC) -#define PC 9 -#endif -#define ITR 10 -#define VV 11 -#define ITSR 12 -#define TOC 13 -#define CIR 14 -#define TTR 15 -#define VMU 16 -#define VML 17 -#define ICR 18 -#define TCPU 19 -#define CPUID 20 -#define TID 21 - -CONST char *op[] = { - "", - "v0\0v1\0v2\0v3\0v4\0v5\0v6\0v7", - "s0\0s1\0s2\0s3\0s4\0s5\0s6\0s7", - "vm", - "sp\0a1\0a2\0a3\0a4\0a5\0ap\0fp", - "vl", - "vs", - "vls", - "psw", - "pc", - "itr", - "vv", - "itsr", - "toc", - "cir", - "ttr", - "vmu", - "vml", - "icr", - "tcpu", - "cpuid", - "tid", -}; - -CONST struct formstr format0[] = { - {0,0,rrr,V,S,S}, /* mov */ - {0,0,rrr,S,S,V}, /* mov */ - {1,1,rrr,V,V,V}, /* merg.t */ - {2,1,rrr,V,V,V}, /* mask.t */ - {1,2,rrr,V,S,V}, /* merg.f */ - {2,2,rrr,V,S,V}, /* mask.f */ - {1,1,rrr,V,S,V}, /* merg.t */ - {2,1,rrr,V,S,V}, /* mask.t */ - {3,3,rrr,V,V,V}, /* mul.s */ - {3,4,rrr,V,V,V}, /* mul.d */ - {4,3,rrr,V,V,V}, /* div.s */ - {4,4,rrr,V,V,V}, /* div.d */ - {3,3,rrr,V,S,V}, /* mul.s */ - {3,4,rrr,V,S,V}, /* mul.d */ - {4,3,rrr,V,S,V}, /* div.s */ - {4,4,rrr,V,S,V}, /* div.d */ - {5,0,rrr,V,V,V}, /* and */ - {6,0,rrr,V,V,V}, /* or */ - {7,0,rrr,V,V,V}, /* xor */ - {8,0,rrr,V,V,V}, /* shf */ - {5,0,rrr,V,S,V}, /* and */ - {6,0,rrr,V,S,V}, /* or */ - {7,0,rrr,V,S,V}, /* xor */ - {8,0,rrr,V,S,V}, /* shf */ - {9,3,rrr,V,V,V}, /* add.s */ - {9,4,rrr,V,V,V}, /* add.d */ - {10,3,rrr,V,V,V}, /* sub.s */ - {10,4,rrr,V,V,V}, /* sub.d */ - {9,3,rrr,V,S,V}, /* add.s */ - {9,4,rrr,V,S,V}, /* add.d */ - {10,3,rrr,V,S,V}, /* sub.s */ - {10,4,rrr,V,S,V}, /* sub.d */ - {9,5,rrr,V,V,V}, /* add.b */ - {9,6,rrr,V,V,V}, /* add.h */ - {9,7,rrr,V,V,V}, /* add.w */ - {9,8,rrr,V,V,V}, /* add.l */ - {9,5,rrr,V,S,V}, /* add.b */ - {9,6,rrr,V,S,V}, /* add.h */ - {9,7,rrr,V,S,V}, /* add.w */ - {9,8,rrr,V,S,V}, /* add.l */ - {10,5,rrr,V,V,V}, /* sub.b */ - {10,6,rrr,V,V,V}, /* sub.h */ - {10,7,rrr,V,V,V}, /* sub.w */ - {10,8,rrr,V,V,V}, /* sub.l */ - {10,5,rrr,V,S,V}, /* sub.b */ - {10,6,rrr,V,S,V}, /* sub.h */ - {10,7,rrr,V,S,V}, /* sub.w */ - {10,8,rrr,V,S,V}, /* sub.l */ - {3,5,rrr,V,V,V}, /* mul.b */ - {3,6,rrr,V,V,V}, /* mul.h */ - {3,7,rrr,V,V,V}, /* mul.w */ - {3,8,rrr,V,V,V}, /* mul.l */ - {3,5,rrr,V,S,V}, /* mul.b */ - {3,6,rrr,V,S,V}, /* mul.h */ - {3,7,rrr,V,S,V}, /* mul.w */ - {3,8,rrr,V,S,V}, /* mul.l */ - {4,5,rrr,V,V,V}, /* div.b */ - {4,6,rrr,V,V,V}, /* div.h */ - {4,7,rrr,V,V,V}, /* div.w */ - {4,8,rrr,V,V,V}, /* div.l */ - {4,5,rrr,V,S,V}, /* div.b */ - {4,6,rrr,V,S,V}, /* div.h */ - {4,7,rrr,V,S,V}, /* div.w */ - {4,8,rrr,V,S,V}, /* div.l */ -}; - -CONST struct formstr format1[] = { - {11,0,xxx,0,0,0}, /* exit */ - {12,0,a3,0,0,0}, /* jmp */ - {13,2,a3,0,0,0}, /* jmpi.f */ - {13,1,a3,0,0,0}, /* jmpi.t */ - {14,2,a3,0,0,0}, /* jmpa.f */ - {14,1,a3,0,0,0}, /* jmpa.t */ - {15,2,a3,0,0,0}, /* jmps.f */ - {15,1,a3,0,0,0}, /* jmps.t */ - {16,0,a3,0,0,0}, /* tac */ - {17,0,a1r,A,0,0}, /* ldea */ - {18,8,a1l,VLS,0,0}, /* ld.l */ - {18,9,a1l,VM,0,0}, /* ld.x */ - {19,0,a3,0,0,0}, /* tas */ - {20,0,a3,0,0,0}, /* pshea */ - {21,8,a2l,VLS,0,0}, /* st.l */ - {21,9,a2l,VM,0,0}, /* st.x */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {22,0,a3,0,0,0}, /* call */ - {23,0,a3,0,0,0}, /* calls */ - {24,0,a3,0,0,0}, /* callq */ - {25,0,a1r,A,0,0}, /* pfork */ - {26,5,a2r,S,0,0}, /* ste.b */ - {26,6,a2r,S,0,0}, /* ste.h */ - {26,7,a2r,S,0,0}, /* ste.w */ - {26,8,a2r,S,0,0}, /* ste.l */ - {18,5,a1r,A,0,0}, /* ld.b */ - {18,6,a1r,A,0,0}, /* ld.h */ - {18,7,a1r,A,0,0}, /* ld.w */ - {27,7,a1r,A,0,0}, /* incr.w */ - {21,5,a2r,A,0,0}, /* st.b */ - {21,6,a2r,A,0,0}, /* st.h */ - {21,7,a2r,A,0,0}, /* st.w */ - {27,8,a1r,S,0,0}, /* incr.l */ - {18,5,a1r,S,0,0}, /* ld.b */ - {18,6,a1r,S,0,0}, /* ld.h */ - {18,7,a1r,S,0,0}, /* ld.w */ - {18,8,a1r,S,0,0}, /* ld.l */ - {21,5,a2r,S,0,0}, /* st.b */ - {21,6,a2r,S,0,0}, /* st.h */ - {21,7,a2r,S,0,0}, /* st.w */ - {21,8,a2r,S,0,0}, /* st.l */ - {18,5,a1r,V,0,0}, /* ld.b */ - {18,6,a1r,V,0,0}, /* ld.h */ - {18,7,a1r,V,0,0}, /* ld.w */ - {18,8,a1r,V,0,0}, /* ld.l */ - {21,5,a2r,V,0,0}, /* st.b */ - {21,6,a2r,V,0,0}, /* st.h */ - {21,7,a2r,V,0,0}, /* st.w */ - {21,8,a2r,V,0,0}, /* st.l */ -}; - -CONST struct formstr format2[] = { - {28,5,rr,A,A,0}, /* cvtw.b */ - {28,6,rr,A,A,0}, /* cvtw.h */ - {29,7,rr,A,A,0}, /* cvtb.w */ - {30,7,rr,A,A,0}, /* cvth.w */ - {28,5,rr,S,S,0}, /* cvtw.b */ - {28,6,rr,S,S,0}, /* cvtw.h */ - {29,7,rr,S,S,0}, /* cvtb.w */ - {30,7,rr,S,S,0}, /* cvth.w */ - {28,3,rr,S,S,0}, /* cvtw.s */ - {31,7,rr,S,S,0}, /* cvts.w */ - {32,3,rr,S,S,0}, /* cvtd.s */ - {31,4,rr,S,S,0}, /* cvts.d */ - {31,8,rr,S,S,0}, /* cvts.l */ - {32,8,rr,S,S,0}, /* cvtd.l */ - {33,3,rr,S,S,0}, /* cvtl.s */ - {33,4,rr,S,S,0}, /* cvtl.d */ - {34,0,rr,A,A,0}, /* ldpa */ - {8,0,nr,A,0,0}, /* shf */ - {18,6,nr,A,0,0}, /* ld.h */ - {18,7,nr,A,0,0}, /* ld.w */ - {33,7,rr,S,S,0}, /* cvtl.w */ - {28,8,rr,S,S,0}, /* cvtw.l */ - {35,1,rr,S,S,0}, /* plc.t */ - {36,0,rr,S,S,0}, /* tzc */ - {37,6,rr,A,A,0}, /* eq.h */ - {37,7,rr,A,A,0}, /* eq.w */ - {37,6,nr,A,0,0}, /* eq.h */ - {37,7,nr,A,0,0}, /* eq.w */ - {37,5,rr,S,S,0}, /* eq.b */ - {37,6,rr,S,S,0}, /* eq.h */ - {37,7,rr,S,S,0}, /* eq.w */ - {37,8,rr,S,S,0}, /* eq.l */ - {38,6,rr,A,A,0}, /* leu.h */ - {38,7,rr,A,A,0}, /* leu.w */ - {38,6,nr,A,0,0}, /* leu.h */ - {38,7,nr,A,0,0}, /* leu.w */ - {38,5,rr,S,S,0}, /* leu.b */ - {38,6,rr,S,S,0}, /* leu.h */ - {38,7,rr,S,S,0}, /* leu.w */ - {38,8,rr,S,S,0}, /* leu.l */ - {39,6,rr,A,A,0}, /* ltu.h */ - {39,7,rr,A,A,0}, /* ltu.w */ - {39,6,nr,A,0,0}, /* ltu.h */ - {39,7,nr,A,0,0}, /* ltu.w */ - {39,5,rr,S,S,0}, /* ltu.b */ - {39,6,rr,S,S,0}, /* ltu.h */ - {39,7,rr,S,S,0}, /* ltu.w */ - {39,8,rr,S,S,0}, /* ltu.l */ - {40,6,rr,A,A,0}, /* le.h */ - {40,7,rr,A,A,0}, /* le.w */ - {40,6,nr,A,0,0}, /* le.h */ - {40,7,nr,A,0,0}, /* le.w */ - {40,5,rr,S,S,0}, /* le.b */ - {40,6,rr,S,S,0}, /* le.h */ - {40,7,rr,S,S,0}, /* le.w */ - {40,8,rr,S,S,0}, /* le.l */ - {41,6,rr,A,A,0}, /* lt.h */ - {41,7,rr,A,A,0}, /* lt.w */ - {41,6,nr,A,0,0}, /* lt.h */ - {41,7,nr,A,0,0}, /* lt.w */ - {41,5,rr,S,S,0}, /* lt.b */ - {41,6,rr,S,S,0}, /* lt.h */ - {41,7,rr,S,S,0}, /* lt.w */ - {41,8,rr,S,S,0}, /* lt.l */ - {9,7,rr,S,A,0}, /* add.w */ - {8,0,rr,A,A,0}, /* shf */ - {0,0,rr,A,A,0}, /* mov */ - {0,0,rr,S,A,0}, /* mov */ - {0,7,rr,S,S,0}, /* mov.w */ - {8,0,rr,S,S,0}, /* shf */ - {0,0,rr,S,S,0}, /* mov */ - {0,0,rr,A,S,0}, /* mov */ - {5,0,rr,A,A,0}, /* and */ - {6,0,rr,A,A,0}, /* or */ - {7,0,rr,A,A,0}, /* xor */ - {42,0,rr,A,A,0}, /* not */ - {5,0,rr,S,S,0}, /* and */ - {6,0,rr,S,S,0}, /* or */ - {7,0,rr,S,S,0}, /* xor */ - {42,0,rr,S,S,0}, /* not */ - {40,3,rr,S,S,0}, /* le.s */ - {40,4,rr,S,S,0}, /* le.d */ - {41,3,rr,S,S,0}, /* lt.s */ - {41,4,rr,S,S,0}, /* lt.d */ - {9,3,rr,S,S,0}, /* add.s */ - {9,4,rr,S,S,0}, /* add.d */ - {10,3,rr,S,S,0}, /* sub.s */ - {10,4,rr,S,S,0}, /* sub.d */ - {37,3,rr,S,S,0}, /* eq.s */ - {37,4,rr,S,S,0}, /* eq.d */ - {43,6,rr,A,A,0}, /* neg.h */ - {43,7,rr,A,A,0}, /* neg.w */ - {3,3,rr,S,S,0}, /* mul.s */ - {3,4,rr,S,S,0}, /* mul.d */ - {4,3,rr,S,S,0}, /* div.s */ - {4,4,rr,S,S,0}, /* div.d */ - {9,6,rr,A,A,0}, /* add.h */ - {9,7,rr,A,A,0}, /* add.w */ - {9,6,nr,A,0,0}, /* add.h */ - {9,7,nr,A,0,0}, /* add.w */ - {9,5,rr,S,S,0}, /* add.b */ - {9,6,rr,S,S,0}, /* add.h */ - {9,7,rr,S,S,0}, /* add.w */ - {9,8,rr,S,S,0}, /* add.l */ - {10,6,rr,A,A,0}, /* sub.h */ - {10,7,rr,A,A,0}, /* sub.w */ - {10,6,nr,A,0,0}, /* sub.h */ - {10,7,nr,A,0,0}, /* sub.w */ - {10,5,rr,S,S,0}, /* sub.b */ - {10,6,rr,S,S,0}, /* sub.h */ - {10,7,rr,S,S,0}, /* sub.w */ - {10,8,rr,S,S,0}, /* sub.l */ - {3,6,rr,A,A,0}, /* mul.h */ - {3,7,rr,A,A,0}, /* mul.w */ - {3,6,nr,A,0,0}, /* mul.h */ - {3,7,nr,A,0,0}, /* mul.w */ - {3,5,rr,S,S,0}, /* mul.b */ - {3,6,rr,S,S,0}, /* mul.h */ - {3,7,rr,S,S,0}, /* mul.w */ - {3,8,rr,S,S,0}, /* mul.l */ - {4,6,rr,A,A,0}, /* div.h */ - {4,7,rr,A,A,0}, /* div.w */ - {4,6,nr,A,0,0}, /* div.h */ - {4,7,nr,A,0,0}, /* div.w */ - {4,5,rr,S,S,0}, /* div.b */ - {4,6,rr,S,S,0}, /* div.h */ - {4,7,rr,S,S,0}, /* div.w */ - {4,8,rr,S,S,0}, /* div.l */ -}; - -CONST struct formstr format3[] = { - {32,3,rr,V,V,0}, /* cvtd.s */ - {31,4,rr,V,V,0}, /* cvts.d */ - {33,4,rr,V,V,0}, /* cvtl.d */ - {32,8,rr,V,V,0}, /* cvtd.l */ - {0,0,rrl,S,S,VM}, /* mov */ - {0,0,rlr,S,VM,S}, /* mov */ - {0,0,0,0,0,0}, - {44,0,rr,S,S,0}, /* lop */ - {36,0,rr,V,V,0}, /* tzc */ - {44,0,rr,V,V,0}, /* lop */ - {0,0,0,0,0,0}, - {42,0,rr,V,V,0}, /* not */ - {8,0,rr,S,V,0}, /* shf */ - {35,1,rr,V,V,0}, /* plc.t */ - {45,2,rr,V,V,0}, /* cprs.f */ - {45,1,rr,V,V,0}, /* cprs.t */ - {37,3,rr,V,V,0}, /* eq.s */ - {37,4,rr,V,V,0}, /* eq.d */ - {43,3,rr,V,V,0}, /* neg.s */ - {43,4,rr,V,V,0}, /* neg.d */ - {37,3,rr,S,V,0}, /* eq.s */ - {37,4,rr,S,V,0}, /* eq.d */ - {43,3,rr,S,S,0}, /* neg.s */ - {43,4,rr,S,S,0}, /* neg.d */ - {40,3,rr,V,V,0}, /* le.s */ - {40,4,rr,V,V,0}, /* le.d */ - {41,3,rr,V,V,0}, /* lt.s */ - {41,4,rr,V,V,0}, /* lt.d */ - {40,3,rr,S,V,0}, /* le.s */ - {40,4,rr,S,V,0}, /* le.d */ - {41,3,rr,S,V,0}, /* lt.s */ - {41,4,rr,S,V,0}, /* lt.d */ - {37,5,rr,V,V,0}, /* eq.b */ - {37,6,rr,V,V,0}, /* eq.h */ - {37,7,rr,V,V,0}, /* eq.w */ - {37,8,rr,V,V,0}, /* eq.l */ - {37,5,rr,S,V,0}, /* eq.b */ - {37,6,rr,S,V,0}, /* eq.h */ - {37,7,rr,S,V,0}, /* eq.w */ - {37,8,rr,S,V,0}, /* eq.l */ - {40,5,rr,V,V,0}, /* le.b */ - {40,6,rr,V,V,0}, /* le.h */ - {40,7,rr,V,V,0}, /* le.w */ - {40,8,rr,V,V,0}, /* le.l */ - {40,5,rr,S,V,0}, /* le.b */ - {40,6,rr,S,V,0}, /* le.h */ - {40,7,rr,S,V,0}, /* le.w */ - {40,8,rr,S,V,0}, /* le.l */ - {41,5,rr,V,V,0}, /* lt.b */ - {41,6,rr,V,V,0}, /* lt.h */ - {41,7,rr,V,V,0}, /* lt.w */ - {41,8,rr,V,V,0}, /* lt.l */ - {41,5,rr,S,V,0}, /* lt.b */ - {41,6,rr,S,V,0}, /* lt.h */ - {41,7,rr,S,V,0}, /* lt.w */ - {41,8,rr,S,V,0}, /* lt.l */ - {43,5,rr,V,V,0}, /* neg.b */ - {43,6,rr,V,V,0}, /* neg.h */ - {43,7,rr,V,V,0}, /* neg.w */ - {43,8,rr,V,V,0}, /* neg.l */ - {43,5,rr,S,S,0}, /* neg.b */ - {43,6,rr,S,S,0}, /* neg.h */ - {43,7,rr,S,S,0}, /* neg.w */ - {43,8,rr,S,S,0}, /* neg.l */ -}; - -CONST struct formstr format4[] = { - {46,0,nops,0,0,0}, /* nop */ - {47,0,pcrel,0,0,0}, /* br */ - {48,2,pcrel,0,0,0}, /* bri.f */ - {48,1,pcrel,0,0,0}, /* bri.t */ - {49,2,pcrel,0,0,0}, /* bra.f */ - {49,1,pcrel,0,0,0}, /* bra.t */ - {50,2,pcrel,0,0,0}, /* brs.f */ - {50,1,pcrel,0,0,0}, /* brs.t */ -}; - -CONST struct formstr format5[] = { - {51,5,rr,V,V,0}, /* ldvi.b */ - {51,6,rr,V,V,0}, /* ldvi.h */ - {51,7,rr,V,V,0}, /* ldvi.w */ - {51,8,rr,V,V,0}, /* ldvi.l */ - {28,3,rr,V,V,0}, /* cvtw.s */ - {31,7,rr,V,V,0}, /* cvts.w */ - {28,8,rr,V,V,0}, /* cvtw.l */ - {33,7,rr,V,V,0}, /* cvtl.w */ - {52,5,rxr,V,V,0}, /* stvi.b */ - {52,6,rxr,V,V,0}, /* stvi.h */ - {52,7,rxr,V,V,0}, /* stvi.w */ - {52,8,rxr,V,V,0}, /* stvi.l */ - {52,5,rxr,S,V,0}, /* stvi.b */ - {52,6,rxr,S,V,0}, /* stvi.h */ - {52,7,rxr,S,V,0}, /* stvi.w */ - {52,8,rxr,S,V,0}, /* stvi.l */ -}; - -CONST struct formstr format6[] = { - {53,0,r,A,0,0}, /* ldsdr */ - {54,0,r,A,0,0}, /* ldkdr */ - {55,3,r,S,0,0}, /* ln.s */ - {55,4,r,S,0,0}, /* ln.d */ - {56,0,nops,0,0,0}, /* patu */ - {57,0,r,A,0,0}, /* pate */ - {58,0,nops,0,0,0}, /* pich */ - {59,0,nops,0,0,0}, /* plch */ - {0,0,lr,PSW,A,0}, /* mov */ - {0,0,rxl,A,PSW,0}, /* mov */ - {0,0,lr,PC,A,0}, /* mov */ - {60,0,r,S,0,0}, /* idle */ - {0,0,lr,ITR,S,0}, /* mov */ - {0,0,rxl,S,ITR,0}, /* mov */ - {0,0,0,0,0,0}, - {0,0,rxl,S,ITSR,0}, /* mov */ - {61,0,nops,0,0,0}, /* rtnq */ - {62,0,nops,0,0,0}, /* cfork */ - {63,0,nops,0,0,0}, /* rtn */ - {64,0,nops,0,0,0}, /* wfork */ - {65,0,nops,0,0,0}, /* join */ - {66,0,nops,0,0,0}, /* rtnc */ - {67,3,r,S,0,0}, /* exp.s */ - {67,4,r,S,0,0}, /* exp.d */ - {68,3,r,S,0,0}, /* sin.s */ - {68,4,r,S,0,0}, /* sin.d */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {69,3,r,S,0,0}, /* cos.s */ - {69,4,r,S,0,0}, /* cos.d */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {70,7,r,A,0,0}, /* psh.w */ - {0,0,0,0,0,0}, - {71,7,r,A,0,0}, /* pop.w */ - {0,0,0,0,0,0}, - {70,7,r,S,0,0}, /* psh.w */ - {70,8,r,S,0,0}, /* psh.l */ - {71,7,r,S,0,0}, /* pop.w */ - {71,8,r,S,0,0}, /* pop.l */ - {72,0,nops,0,0,0}, /* eni */ - {73,0,nops,0,0,0}, /* dsi */ - {74,0,nops,0,0,0}, /* bkpt */ - {75,0,nops,0,0,0}, /* msync */ - {76,0,r,S,0,0}, /* mski */ - {77,0,r,S,0,0}, /* xmti */ - {0,0,rxl,S,VV,0}, /* mov */ - {78,0,nops,0,0,0}, /* tstvv */ - {0,0,lr,VS,A,0}, /* mov */ - {0,0,rxl,A,VS,0}, /* mov */ - {0,0,lr,VL,A,0}, /* mov */ - {0,0,rxl,A,VL,0}, /* mov */ - {0,7,lr,VS,S,0}, /* mov.w */ - {0,7,rxl,S,VS,0}, /* mov.w */ - {0,7,lr,VL,S,0}, /* mov.w */ - {0,7,rxl,S,VL,0}, /* mov.w */ - {79,0,r,A,0,0}, /* diag */ - {80,0,nops,0,0,0}, /* pbkpt */ - {81,3,r,S,0,0}, /* sqrt.s */ - {81,4,r,S,0,0}, /* sqrt.d */ - {82,0,nops,0,0,0}, /* casr */ - {0,0,0,0,0,0}, - {83,3,r,S,0,0}, /* atan.s */ - {83,4,r,S,0,0}, /* atan.d */ -}; - -CONST struct formstr format7[] = { - {84,5,r,V,0,0}, /* sum.b */ - {84,6,r,V,0,0}, /* sum.h */ - {84,7,r,V,0,0}, /* sum.w */ - {84,8,r,V,0,0}, /* sum.l */ - {85,0,r,V,0,0}, /* all */ - {86,0,r,V,0,0}, /* any */ - {87,0,r,V,0,0}, /* parity */ - {0,0,0,0,0,0}, - {88,5,r,V,0,0}, /* max.b */ - {88,6,r,V,0,0}, /* max.h */ - {88,7,r,V,0,0}, /* max.w */ - {88,8,r,V,0,0}, /* max.l */ - {89,5,r,V,0,0}, /* min.b */ - {89,6,r,V,0,0}, /* min.h */ - {89,7,r,V,0,0}, /* min.w */ - {89,8,r,V,0,0}, /* min.l */ - {84,3,r,V,0,0}, /* sum.s */ - {84,4,r,V,0,0}, /* sum.d */ - {90,3,r,V,0,0}, /* prod.s */ - {90,4,r,V,0,0}, /* prod.d */ - {88,3,r,V,0,0}, /* max.s */ - {88,4,r,V,0,0}, /* max.d */ - {89,3,r,V,0,0}, /* min.s */ - {89,4,r,V,0,0}, /* min.d */ - {90,5,r,V,0,0}, /* prod.b */ - {90,6,r,V,0,0}, /* prod.h */ - {90,7,r,V,0,0}, /* prod.w */ - {90,8,r,V,0,0}, /* prod.l */ - {35,2,lr,VM,S,0}, /* plc.f */ - {35,1,lr,VM,S,0}, /* plc.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr formatx[] = { - {0,0,0,0,0,0}, -}; - -CONST struct formstr format1a[] = { - {91,0,imr,A,0,0}, /* halt */ - {92,0,a4,0,0,0}, /* sysc */ - {18,6,imr,A,0,0}, /* ld.h */ - {18,7,imr,A,0,0}, /* ld.w */ - {5,0,imr,A,0,0}, /* and */ - {6,0,imr,A,0,0}, /* or */ - {7,0,imr,A,0,0}, /* xor */ - {8,0,imr,A,0,0}, /* shf */ - {9,6,imr,A,0,0}, /* add.h */ - {9,7,imr,A,0,0}, /* add.w */ - {10,6,imr,A,0,0}, /* sub.h */ - {10,7,imr,A,0,0}, /* sub.w */ - {3,6,imr,A,0,0}, /* mul.h */ - {3,7,imr,A,0,0}, /* mul.w */ - {4,6,imr,A,0,0}, /* div.h */ - {4,7,imr,A,0,0}, /* div.w */ - {18,7,iml,VL,0,0}, /* ld.w */ - {18,7,iml,VS,0,0}, /* ld.w */ - {0,0,0,0,0,0}, - {8,7,imr,S,0,0}, /* shf.w */ - {93,0,a5,0,0,0}, /* trap */ - {0,0,0,0,0,0}, - {37,6,imr,A,0,0}, /* eq.h */ - {37,7,imr,A,0,0}, /* eq.w */ - {38,6,imr,A,0,0}, /* leu.h */ - {38,7,imr,A,0,0}, /* leu.w */ - {39,6,imr,A,0,0}, /* ltu.h */ - {39,7,imr,A,0,0}, /* ltu.w */ - {40,6,imr,A,0,0}, /* le.h */ - {40,7,imr,A,0,0}, /* le.w */ - {41,6,imr,A,0,0}, /* lt.h */ - {41,7,imr,A,0,0}, /* lt.w */ -}; - -CONST struct formstr format1b[] = { - {18,4,imr,S,0,0}, /* ld.d */ - {18,10,imr,S,0,0}, /* ld.u */ - {18,8,imr,S,0,0}, /* ld.l */ - {18,7,imr,S,0,0}, /* ld.w */ - {5,0,imr,S,0,0}, /* and */ - {6,0,imr,S,0,0}, /* or */ - {7,0,imr,S,0,0}, /* xor */ - {8,0,imr,S,0,0}, /* shf */ - {9,6,imr,S,0,0}, /* add.h */ - {9,7,imr,S,0,0}, /* add.w */ - {10,6,imr,S,0,0}, /* sub.h */ - {10,7,imr,S,0,0}, /* sub.w */ - {3,6,imr,S,0,0}, /* mul.h */ - {3,7,imr,S,0,0}, /* mul.w */ - {4,6,imr,S,0,0}, /* div.h */ - {4,7,imr,S,0,0}, /* div.w */ - {9,3,imr,S,0,0}, /* add.s */ - {10,3,imr,S,0,0}, /* sub.s */ - {3,3,imr,S,0,0}, /* mul.s */ - {4,3,imr,S,0,0}, /* div.s */ - {40,3,imr,S,0,0}, /* le.s */ - {41,3,imr,S,0,0}, /* lt.s */ - {37,6,imr,S,0,0}, /* eq.h */ - {37,7,imr,S,0,0}, /* eq.w */ - {38,6,imr,S,0,0}, /* leu.h */ - {38,7,imr,S,0,0}, /* leu.w */ - {39,6,imr,S,0,0}, /* ltu.h */ - {39,7,imr,S,0,0}, /* ltu.w */ - {40,6,imr,S,0,0}, /* le.h */ - {40,7,imr,S,0,0}, /* le.w */ - {41,6,imr,S,0,0}, /* lt.h */ - {41,7,imr,S,0,0}, /* lt.w */ -}; - -CONST struct formstr e0_format0[] = { - {10,3,rrr,S,V,V}, /* sub.s */ - {10,4,rrr,S,V,V}, /* sub.d */ - {4,3,rrr,S,V,V}, /* div.s */ - {4,4,rrr,S,V,V}, /* div.d */ - {10,11,rrr,S,V,V}, /* sub.s.f */ - {10,12,rrr,S,V,V}, /* sub.d.f */ - {4,11,rrr,S,V,V}, /* div.s.f */ - {4,12,rrr,S,V,V}, /* div.d.f */ - {3,11,rrr,V,V,V}, /* mul.s.f */ - {3,12,rrr,V,V,V}, /* mul.d.f */ - {4,11,rrr,V,V,V}, /* div.s.f */ - {4,12,rrr,V,V,V}, /* div.d.f */ - {3,11,rrr,V,S,V}, /* mul.s.f */ - {3,12,rrr,V,S,V}, /* mul.d.f */ - {4,11,rrr,V,S,V}, /* div.s.f */ - {4,12,rrr,V,S,V}, /* div.d.f */ - {5,2,rrr,V,V,V}, /* and.f */ - {6,2,rrr,V,V,V}, /* or.f */ - {7,2,rrr,V,V,V}, /* xor.f */ - {8,2,rrr,V,V,V}, /* shf.f */ - {5,2,rrr,V,S,V}, /* and.f */ - {6,2,rrr,V,S,V}, /* or.f */ - {7,2,rrr,V,S,V}, /* xor.f */ - {8,2,rrr,V,S,V}, /* shf.f */ - {9,11,rrr,V,V,V}, /* add.s.f */ - {9,12,rrr,V,V,V}, /* add.d.f */ - {10,11,rrr,V,V,V}, /* sub.s.f */ - {10,12,rrr,V,V,V}, /* sub.d.f */ - {9,11,rrr,V,S,V}, /* add.s.f */ - {9,12,rrr,V,S,V}, /* add.d.f */ - {10,11,rrr,V,S,V}, /* sub.s.f */ - {10,12,rrr,V,S,V}, /* sub.d.f */ - {9,13,rrr,V,V,V}, /* add.b.f */ - {9,14,rrr,V,V,V}, /* add.h.f */ - {9,15,rrr,V,V,V}, /* add.w.f */ - {9,16,rrr,V,V,V}, /* add.l.f */ - {9,13,rrr,V,S,V}, /* add.b.f */ - {9,14,rrr,V,S,V}, /* add.h.f */ - {9,15,rrr,V,S,V}, /* add.w.f */ - {9,16,rrr,V,S,V}, /* add.l.f */ - {10,13,rrr,V,V,V}, /* sub.b.f */ - {10,14,rrr,V,V,V}, /* sub.h.f */ - {10,15,rrr,V,V,V}, /* sub.w.f */ - {10,16,rrr,V,V,V}, /* sub.l.f */ - {10,13,rrr,V,S,V}, /* sub.b.f */ - {10,14,rrr,V,S,V}, /* sub.h.f */ - {10,15,rrr,V,S,V}, /* sub.w.f */ - {10,16,rrr,V,S,V}, /* sub.l.f */ - {3,13,rrr,V,V,V}, /* mul.b.f */ - {3,14,rrr,V,V,V}, /* mul.h.f */ - {3,15,rrr,V,V,V}, /* mul.w.f */ - {3,16,rrr,V,V,V}, /* mul.l.f */ - {3,13,rrr,V,S,V}, /* mul.b.f */ - {3,14,rrr,V,S,V}, /* mul.h.f */ - {3,15,rrr,V,S,V}, /* mul.w.f */ - {3,16,rrr,V,S,V}, /* mul.l.f */ - {4,13,rrr,V,V,V}, /* div.b.f */ - {4,14,rrr,V,V,V}, /* div.h.f */ - {4,15,rrr,V,V,V}, /* div.w.f */ - {4,16,rrr,V,V,V}, /* div.l.f */ - {4,13,rrr,V,S,V}, /* div.b.f */ - {4,14,rrr,V,S,V}, /* div.h.f */ - {4,15,rrr,V,S,V}, /* div.w.f */ - {4,16,rrr,V,S,V}, /* div.l.f */ -}; - -CONST struct formstr e0_format1[] = { - {0,0,0,0,0,0}, - {94,0,a3,0,0,0}, /* tst */ - {95,0,a3,0,0,0}, /* lck */ - {96,0,a3,0,0,0}, /* ulk */ - {17,0,a1r,S,0,0}, /* ldea */ - {97,0,a1r,A,0,0}, /* spawn */ - {98,0,a1r,A,0,0}, /* ldcmr */ - {99,0,a2r,A,0,0}, /* stcmr */ - {100,0,a1r,A,0,0}, /* popr */ - {101,0,a2r,A,0,0}, /* pshr */ - {102,7,a1r,A,0,0}, /* rcvr.w */ - {103,7,a2r,A,0,0}, /* matm.w */ - {104,7,a2r,A,0,0}, /* sndr.w */ - {104,8,a2r,S,0,0}, /* sndr.l */ - {102,8,a1r,S,0,0}, /* rcvr.l */ - {103,8,a2r,S,0,0}, /* matm.l */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {105,7,a2r,A,0,0}, /* putr.w */ - {105,8,a2r,S,0,0}, /* putr.l */ - {106,7,a1r,A,0,0}, /* getr.w */ - {106,8,a1r,S,0,0}, /* getr.l */ - {26,13,a2r,S,0,0}, /* ste.b.f */ - {26,14,a2r,S,0,0}, /* ste.h.f */ - {26,15,a2r,S,0,0}, /* ste.w.f */ - {26,16,a2r,S,0,0}, /* ste.l.f */ - {107,7,a2r,A,0,0}, /* matr.w */ - {108,7,a2r,A,0,0}, /* mat.w */ - {109,7,a1r,A,0,0}, /* get.w */ - {110,7,a1r,A,0,0}, /* rcv.w */ - {0,0,0,0,0,0}, - {111,7,a1r,A,0,0}, /* inc.w */ - {112,7,a2r,A,0,0}, /* put.w */ - {113,7,a2r,A,0,0}, /* snd.w */ - {107,8,a2r,S,0,0}, /* matr.l */ - {108,8,a2r,S,0,0}, /* mat.l */ - {109,8,a1r,S,0,0}, /* get.l */ - {110,8,a1r,S,0,0}, /* rcv.l */ - {0,0,0,0,0,0}, - {111,8,a1r,S,0,0}, /* inc.l */ - {112,8,a2r,S,0,0}, /* put.l */ - {113,8,a2r,S,0,0}, /* snd.l */ - {18,13,a1r,V,0,0}, /* ld.b.f */ - {18,14,a1r,V,0,0}, /* ld.h.f */ - {18,15,a1r,V,0,0}, /* ld.w.f */ - {18,16,a1r,V,0,0}, /* ld.l.f */ - {21,13,a2r,V,0,0}, /* st.b.f */ - {21,14,a2r,V,0,0}, /* st.h.f */ - {21,15,a2r,V,0,0}, /* st.w.f */ - {21,16,a2r,V,0,0}, /* st.l.f */ -}; - -CONST struct formstr e0_format2[] = { - {28,5,rr,V,V,0}, /* cvtw.b */ - {28,6,rr,V,V,0}, /* cvtw.h */ - {29,7,rr,V,V,0}, /* cvtb.w */ - {30,7,rr,V,V,0}, /* cvth.w */ - {28,13,rr,V,V,0}, /* cvtw.b.f */ - {28,14,rr,V,V,0}, /* cvtw.h.f */ - {29,15,rr,V,V,0}, /* cvtb.w.f */ - {30,15,rr,V,V,0}, /* cvth.w.f */ - {31,8,rr,V,V,0}, /* cvts.l */ - {32,7,rr,V,V,0}, /* cvtd.w */ - {33,3,rr,V,V,0}, /* cvtl.s */ - {28,4,rr,V,V,0}, /* cvtw.d */ - {31,16,rr,V,V,0}, /* cvts.l.f */ - {32,15,rr,V,V,0}, /* cvtd.w.f */ - {33,11,rr,V,V,0}, /* cvtl.s.f */ - {28,12,rr,V,V,0}, /* cvtw.d.f */ - {114,0,rr,S,S,0}, /* enal */ - {8,7,rr,S,S,0}, /* shf.w */ - {115,0,rr,S,S,0}, /* enag */ - {0,0,0,0,0,0}, - {28,4,rr,S,S,0}, /* cvtw.d */ - {32,7,rr,S,S,0}, /* cvtd.w */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {116,3,rr,S,S,0}, /* frint.s */ - {116,4,rr,S,S,0}, /* frint.d */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {116,3,rr,V,V,0}, /* frint.s */ - {116,4,rr,V,V,0}, /* frint.d */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {116,11,rr,V,V,0}, /* frint.s.f */ - {116,12,rr,V,V,0}, /* frint.d.f */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {81,3,rr,V,V,0}, /* sqrt.s */ - {81,4,rr,V,V,0}, /* sqrt.d */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {81,11,rr,V,V,0}, /* sqrt.s.f */ - {81,12,rr,V,V,0}, /* sqrt.d.f */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e0_format3[] = { - {32,11,rr,V,V,0}, /* cvtd.s.f */ - {31,12,rr,V,V,0}, /* cvts.d.f */ - {33,12,rr,V,V,0}, /* cvtl.d.f */ - {32,16,rr,V,V,0}, /* cvtd.l.f */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {36,2,rr,V,V,0}, /* tzc.f */ - {44,2,rr,V,V,0}, /* lop.f */ - {117,2,rr,V,V,0}, /* xpnd.f */ - {42,2,rr,V,V,0}, /* not.f */ - {8,2,rr,S,V,0}, /* shf.f */ - {35,17,rr,V,V,0}, /* plc.t.f */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {37,11,rr,V,V,0}, /* eq.s.f */ - {37,12,rr,V,V,0}, /* eq.d.f */ - {43,11,rr,V,V,0}, /* neg.s.f */ - {43,12,rr,V,V,0}, /* neg.d.f */ - {37,11,rr,S,V,0}, /* eq.s.f */ - {37,12,rr,S,V,0}, /* eq.d.f */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {40,11,rr,V,V,0}, /* le.s.f */ - {40,12,rr,V,V,0}, /* le.d.f */ - {41,11,rr,V,V,0}, /* lt.s.f */ - {41,12,rr,V,V,0}, /* lt.d.f */ - {40,11,rr,S,V,0}, /* le.s.f */ - {40,12,rr,S,V,0}, /* le.d.f */ - {41,11,rr,S,V,0}, /* lt.s.f */ - {41,12,rr,S,V,0}, /* lt.d.f */ - {37,13,rr,V,V,0}, /* eq.b.f */ - {37,14,rr,V,V,0}, /* eq.h.f */ - {37,15,rr,V,V,0}, /* eq.w.f */ - {37,16,rr,V,V,0}, /* eq.l.f */ - {37,13,rr,S,V,0}, /* eq.b.f */ - {37,14,rr,S,V,0}, /* eq.h.f */ - {37,15,rr,S,V,0}, /* eq.w.f */ - {37,16,rr,S,V,0}, /* eq.l.f */ - {40,13,rr,V,V,0}, /* le.b.f */ - {40,14,rr,V,V,0}, /* le.h.f */ - {40,15,rr,V,V,0}, /* le.w.f */ - {40,16,rr,V,V,0}, /* le.l.f */ - {40,13,rr,S,V,0}, /* le.b.f */ - {40,14,rr,S,V,0}, /* le.h.f */ - {40,15,rr,S,V,0}, /* le.w.f */ - {40,16,rr,S,V,0}, /* le.l.f */ - {41,13,rr,V,V,0}, /* lt.b.f */ - {41,14,rr,V,V,0}, /* lt.h.f */ - {41,15,rr,V,V,0}, /* lt.w.f */ - {41,16,rr,V,V,0}, /* lt.l.f */ - {41,13,rr,S,V,0}, /* lt.b.f */ - {41,14,rr,S,V,0}, /* lt.h.f */ - {41,15,rr,S,V,0}, /* lt.w.f */ - {41,16,rr,S,V,0}, /* lt.l.f */ - {43,13,rr,V,V,0}, /* neg.b.f */ - {43,14,rr,V,V,0}, /* neg.h.f */ - {43,15,rr,V,V,0}, /* neg.w.f */ - {43,16,rr,V,V,0}, /* neg.l.f */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e0_format4[] = { - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e0_format5[] = { - {51,13,rr,V,V,0}, /* ldvi.b.f */ - {51,14,rr,V,V,0}, /* ldvi.h.f */ - {51,15,rr,V,V,0}, /* ldvi.w.f */ - {51,16,rr,V,V,0}, /* ldvi.l.f */ - {28,11,rr,V,V,0}, /* cvtw.s.f */ - {31,15,rr,V,V,0}, /* cvts.w.f */ - {28,16,rr,V,V,0}, /* cvtw.l.f */ - {33,15,rr,V,V,0}, /* cvtl.w.f */ - {52,13,rxr,V,V,0}, /* stvi.b.f */ - {52,14,rxr,V,V,0}, /* stvi.h.f */ - {52,15,rxr,V,V,0}, /* stvi.w.f */ - {52,16,rxr,V,V,0}, /* stvi.l.f */ - {52,13,rxr,S,V,0}, /* stvi.b.f */ - {52,14,rxr,S,V,0}, /* stvi.h.f */ - {52,15,rxr,S,V,0}, /* stvi.w.f */ - {52,16,rxr,S,V,0}, /* stvi.l.f */ -}; - -CONST struct formstr e0_format6[] = { - {0,0,rxl,S,CIR,0}, /* mov */ - {0,0,lr,CIR,S,0}, /* mov */ - {0,0,lr,TOC,S,0}, /* mov */ - {0,0,lr,CPUID,S,0}, /* mov */ - {0,0,rxl,S,TTR,0}, /* mov */ - {0,0,lr,TTR,S,0}, /* mov */ - {118,0,nops,0,0,0}, /* ctrsl */ - {119,0,nops,0,0,0}, /* ctrsg */ - {0,0,rxl,S,VMU,0}, /* mov */ - {0,0,lr,VMU,S,0}, /* mov */ - {0,0,rxl,S,VML,0}, /* mov */ - {0,0,lr,VML,S,0}, /* mov */ - {0,0,rxl,S,ICR,0}, /* mov */ - {0,0,lr,ICR,S,0}, /* mov */ - {0,0,rxl,S,TCPU,0}, /* mov */ - {0,0,lr,TCPU,S,0}, /* mov */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {120,0,nops,0,0,0}, /* stop */ - {0,0,0,0,0,0}, - {0,0,rxl,S,TID,0}, /* mov */ - {0,0,lr,TID,S,0}, /* mov */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e0_format7[] = { - {84,13,r,V,0,0}, /* sum.b.f */ - {84,14,r,V,0,0}, /* sum.h.f */ - {84,15,r,V,0,0}, /* sum.w.f */ - {84,16,r,V,0,0}, /* sum.l.f */ - {85,2,r,V,0,0}, /* all.f */ - {86,2,r,V,0,0}, /* any.f */ - {87,2,r,V,0,0}, /* parity.f */ - {0,0,0,0,0,0}, - {88,13,r,V,0,0}, /* max.b.f */ - {88,14,r,V,0,0}, /* max.h.f */ - {88,15,r,V,0,0}, /* max.w.f */ - {88,16,r,V,0,0}, /* max.l.f */ - {89,13,r,V,0,0}, /* min.b.f */ - {89,14,r,V,0,0}, /* min.h.f */ - {89,15,r,V,0,0}, /* min.w.f */ - {89,16,r,V,0,0}, /* min.l.f */ - {84,11,r,V,0,0}, /* sum.s.f */ - {84,12,r,V,0,0}, /* sum.d.f */ - {90,11,r,V,0,0}, /* prod.s.f */ - {90,12,r,V,0,0}, /* prod.d.f */ - {88,11,r,V,0,0}, /* max.s.f */ - {88,12,r,V,0,0}, /* max.d.f */ - {89,11,r,V,0,0}, /* min.s.f */ - {89,12,r,V,0,0}, /* min.d.f */ - {90,13,r,V,0,0}, /* prod.b.f */ - {90,14,r,V,0,0}, /* prod.h.f */ - {90,15,r,V,0,0}, /* prod.w.f */ - {90,16,r,V,0,0}, /* prod.l.f */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e1_format0[] = { - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {10,18,rrr,S,V,V}, /* sub.s.t */ - {10,19,rrr,S,V,V}, /* sub.d.t */ - {4,18,rrr,S,V,V}, /* div.s.t */ - {4,19,rrr,S,V,V}, /* div.d.t */ - {3,18,rrr,V,V,V}, /* mul.s.t */ - {3,19,rrr,V,V,V}, /* mul.d.t */ - {4,18,rrr,V,V,V}, /* div.s.t */ - {4,19,rrr,V,V,V}, /* div.d.t */ - {3,18,rrr,V,S,V}, /* mul.s.t */ - {3,19,rrr,V,S,V}, /* mul.d.t */ - {4,18,rrr,V,S,V}, /* div.s.t */ - {4,19,rrr,V,S,V}, /* div.d.t */ - {5,1,rrr,V,V,V}, /* and.t */ - {6,1,rrr,V,V,V}, /* or.t */ - {7,1,rrr,V,V,V}, /* xor.t */ - {8,1,rrr,V,V,V}, /* shf.t */ - {5,1,rrr,V,S,V}, /* and.t */ - {6,1,rrr,V,S,V}, /* or.t */ - {7,1,rrr,V,S,V}, /* xor.t */ - {8,1,rrr,V,S,V}, /* shf.t */ - {9,18,rrr,V,V,V}, /* add.s.t */ - {9,19,rrr,V,V,V}, /* add.d.t */ - {10,18,rrr,V,V,V}, /* sub.s.t */ - {10,19,rrr,V,V,V}, /* sub.d.t */ - {9,18,rrr,V,S,V}, /* add.s.t */ - {9,19,rrr,V,S,V}, /* add.d.t */ - {10,18,rrr,V,S,V}, /* sub.s.t */ - {10,19,rrr,V,S,V}, /* sub.d.t */ - {9,20,rrr,V,V,V}, /* add.b.t */ - {9,21,rrr,V,V,V}, /* add.h.t */ - {9,22,rrr,V,V,V}, /* add.w.t */ - {9,23,rrr,V,V,V}, /* add.l.t */ - {9,20,rrr,V,S,V}, /* add.b.t */ - {9,21,rrr,V,S,V}, /* add.h.t */ - {9,22,rrr,V,S,V}, /* add.w.t */ - {9,23,rrr,V,S,V}, /* add.l.t */ - {10,20,rrr,V,V,V}, /* sub.b.t */ - {10,21,rrr,V,V,V}, /* sub.h.t */ - {10,22,rrr,V,V,V}, /* sub.w.t */ - {10,23,rrr,V,V,V}, /* sub.l.t */ - {10,20,rrr,V,S,V}, /* sub.b.t */ - {10,21,rrr,V,S,V}, /* sub.h.t */ - {10,22,rrr,V,S,V}, /* sub.w.t */ - {10,23,rrr,V,S,V}, /* sub.l.t */ - {3,20,rrr,V,V,V}, /* mul.b.t */ - {3,21,rrr,V,V,V}, /* mul.h.t */ - {3,22,rrr,V,V,V}, /* mul.w.t */ - {3,23,rrr,V,V,V}, /* mul.l.t */ - {3,20,rrr,V,S,V}, /* mul.b.t */ - {3,21,rrr,V,S,V}, /* mul.h.t */ - {3,22,rrr,V,S,V}, /* mul.w.t */ - {3,23,rrr,V,S,V}, /* mul.l.t */ - {4,20,rrr,V,V,V}, /* div.b.t */ - {4,21,rrr,V,V,V}, /* div.h.t */ - {4,22,rrr,V,V,V}, /* div.w.t */ - {4,23,rrr,V,V,V}, /* div.l.t */ - {4,20,rrr,V,S,V}, /* div.b.t */ - {4,21,rrr,V,S,V}, /* div.h.t */ - {4,22,rrr,V,S,V}, /* div.w.t */ - {4,23,rrr,V,S,V}, /* div.l.t */ -}; - -CONST struct formstr e1_format1[] = { - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {26,20,a2r,S,0,0}, /* ste.b.t */ - {26,21,a2r,S,0,0}, /* ste.h.t */ - {26,22,a2r,S,0,0}, /* ste.w.t */ - {26,23,a2r,S,0,0}, /* ste.l.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {18,20,a1r,V,0,0}, /* ld.b.t */ - {18,21,a1r,V,0,0}, /* ld.h.t */ - {18,22,a1r,V,0,0}, /* ld.w.t */ - {18,23,a1r,V,0,0}, /* ld.l.t */ - {21,20,a2r,V,0,0}, /* st.b.t */ - {21,21,a2r,V,0,0}, /* st.h.t */ - {21,22,a2r,V,0,0}, /* st.w.t */ - {21,23,a2r,V,0,0}, /* st.l.t */ -}; - -CONST struct formstr e1_format2[] = { - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {28,20,rr,V,V,0}, /* cvtw.b.t */ - {28,21,rr,V,V,0}, /* cvtw.h.t */ - {29,22,rr,V,V,0}, /* cvtb.w.t */ - {30,22,rr,V,V,0}, /* cvth.w.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {31,23,rr,V,V,0}, /* cvts.l.t */ - {32,22,rr,V,V,0}, /* cvtd.w.t */ - {33,18,rr,V,V,0}, /* cvtl.s.t */ - {28,19,rr,V,V,0}, /* cvtw.d.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {116,18,rr,V,V,0}, /* frint.s.t */ - {116,19,rr,V,V,0}, /* frint.d.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {81,18,rr,V,V,0}, /* sqrt.s.t */ - {81,19,rr,V,V,0}, /* sqrt.d.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e1_format3[] = { - {32,18,rr,V,V,0}, /* cvtd.s.t */ - {31,19,rr,V,V,0}, /* cvts.d.t */ - {33,19,rr,V,V,0}, /* cvtl.d.t */ - {32,23,rr,V,V,0}, /* cvtd.l.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {36,1,rr,V,V,0}, /* tzc.t */ - {44,1,rr,V,V,0}, /* lop.t */ - {117,1,rr,V,V,0}, /* xpnd.t */ - {42,1,rr,V,V,0}, /* not.t */ - {8,1,rr,S,V,0}, /* shf.t */ - {35,24,rr,V,V,0}, /* plc.t.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {37,18,rr,V,V,0}, /* eq.s.t */ - {37,19,rr,V,V,0}, /* eq.d.t */ - {43,18,rr,V,V,0}, /* neg.s.t */ - {43,19,rr,V,V,0}, /* neg.d.t */ - {37,18,rr,S,V,0}, /* eq.s.t */ - {37,19,rr,S,V,0}, /* eq.d.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {40,18,rr,V,V,0}, /* le.s.t */ - {40,19,rr,V,V,0}, /* le.d.t */ - {41,18,rr,V,V,0}, /* lt.s.t */ - {41,19,rr,V,V,0}, /* lt.d.t */ - {40,18,rr,S,V,0}, /* le.s.t */ - {40,19,rr,S,V,0}, /* le.d.t */ - {41,18,rr,S,V,0}, /* lt.s.t */ - {41,19,rr,S,V,0}, /* lt.d.t */ - {37,20,rr,V,V,0}, /* eq.b.t */ - {37,21,rr,V,V,0}, /* eq.h.t */ - {37,22,rr,V,V,0}, /* eq.w.t */ - {37,23,rr,V,V,0}, /* eq.l.t */ - {37,20,rr,S,V,0}, /* eq.b.t */ - {37,21,rr,S,V,0}, /* eq.h.t */ - {37,22,rr,S,V,0}, /* eq.w.t */ - {37,23,rr,S,V,0}, /* eq.l.t */ - {40,20,rr,V,V,0}, /* le.b.t */ - {40,21,rr,V,V,0}, /* le.h.t */ - {40,22,rr,V,V,0}, /* le.w.t */ - {40,23,rr,V,V,0}, /* le.l.t */ - {40,20,rr,S,V,0}, /* le.b.t */ - {40,21,rr,S,V,0}, /* le.h.t */ - {40,22,rr,S,V,0}, /* le.w.t */ - {40,23,rr,S,V,0}, /* le.l.t */ - {41,20,rr,V,V,0}, /* lt.b.t */ - {41,21,rr,V,V,0}, /* lt.h.t */ - {41,22,rr,V,V,0}, /* lt.w.t */ - {41,23,rr,V,V,0}, /* lt.l.t */ - {41,20,rr,S,V,0}, /* lt.b.t */ - {41,21,rr,S,V,0}, /* lt.h.t */ - {41,22,rr,S,V,0}, /* lt.w.t */ - {41,23,rr,S,V,0}, /* lt.l.t */ - {43,20,rr,V,V,0}, /* neg.b.t */ - {43,21,rr,V,V,0}, /* neg.h.t */ - {43,22,rr,V,V,0}, /* neg.w.t */ - {43,23,rr,V,V,0}, /* neg.l.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e1_format4[] = { - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e1_format5[] = { - {51,20,rr,V,V,0}, /* ldvi.b.t */ - {51,21,rr,V,V,0}, /* ldvi.h.t */ - {51,22,rr,V,V,0}, /* ldvi.w.t */ - {51,23,rr,V,V,0}, /* ldvi.l.t */ - {28,18,rr,V,V,0}, /* cvtw.s.t */ - {31,22,rr,V,V,0}, /* cvts.w.t */ - {28,23,rr,V,V,0}, /* cvtw.l.t */ - {33,22,rr,V,V,0}, /* cvtl.w.t */ - {52,20,rxr,V,V,0}, /* stvi.b.t */ - {52,21,rxr,V,V,0}, /* stvi.h.t */ - {52,22,rxr,V,V,0}, /* stvi.w.t */ - {52,23,rxr,V,V,0}, /* stvi.l.t */ - {52,20,rxr,S,V,0}, /* stvi.b.t */ - {52,21,rxr,S,V,0}, /* stvi.h.t */ - {52,22,rxr,S,V,0}, /* stvi.w.t */ - {52,23,rxr,S,V,0}, /* stvi.l.t */ -}; - -CONST struct formstr e1_format6[] = { - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -CONST struct formstr e1_format7[] = { - {84,20,r,V,0,0}, /* sum.b.t */ - {84,21,r,V,0,0}, /* sum.h.t */ - {84,22,r,V,0,0}, /* sum.w.t */ - {84,23,r,V,0,0}, /* sum.l.t */ - {85,1,r,V,0,0}, /* all.t */ - {86,1,r,V,0,0}, /* any.t */ - {87,1,r,V,0,0}, /* parity.t */ - {0,0,0,0,0,0}, - {88,20,r,V,0,0}, /* max.b.t */ - {88,21,r,V,0,0}, /* max.h.t */ - {88,22,r,V,0,0}, /* max.w.t */ - {88,23,r,V,0,0}, /* max.l.t */ - {89,20,r,V,0,0}, /* min.b.t */ - {89,21,r,V,0,0}, /* min.h.t */ - {89,22,r,V,0,0}, /* min.w.t */ - {89,23,r,V,0,0}, /* min.l.t */ - {84,18,r,V,0,0}, /* sum.s.t */ - {84,19,r,V,0,0}, /* sum.d.t */ - {90,18,r,V,0,0}, /* prod.s.t */ - {90,19,r,V,0,0}, /* prod.d.t */ - {88,18,r,V,0,0}, /* max.s.t */ - {88,19,r,V,0,0}, /* max.d.t */ - {89,18,r,V,0,0}, /* min.s.t */ - {89,19,r,V,0,0}, /* min.d.t */ - {90,20,r,V,0,0}, /* prod.b.t */ - {90,21,r,V,0,0}, /* prod.h.t */ - {90,22,r,V,0,0}, /* prod.w.t */ - {90,23,r,V,0,0}, /* prod.l.t */ - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, - {0,0,0,0,0,0}, -}; - -char *lop[] = { - "mov", /* 0 */ - "merg", /* 1 */ - "mask", /* 2 */ - "mul", /* 3 */ - "div", /* 4 */ - "and", /* 5 */ - "or", /* 6 */ - "xor", /* 7 */ - "shf", /* 8 */ - "add", /* 9 */ - "sub", /* 10 */ - "exit", /* 11 */ - "jmp", /* 12 */ - "jmpi", /* 13 */ - "jmpa", /* 14 */ - "jmps", /* 15 */ - "tac", /* 16 */ - "ldea", /* 17 */ - "ld", /* 18 */ - "tas", /* 19 */ - "pshea", /* 20 */ - "st", /* 21 */ - "call", /* 22 */ - "calls", /* 23 */ - "callq", /* 24 */ - "pfork", /* 25 */ - "ste", /* 26 */ - "incr", /* 27 */ - "cvtw", /* 28 */ - "cvtb", /* 29 */ - "cvth", /* 30 */ - "cvts", /* 31 */ - "cvtd", /* 32 */ - "cvtl", /* 33 */ - "ldpa", /* 34 */ - "plc", /* 35 */ - "tzc", /* 36 */ - "eq", /* 37 */ - "leu", /* 38 */ - "ltu", /* 39 */ - "le", /* 40 */ - "lt", /* 41 */ - "not", /* 42 */ - "neg", /* 43 */ - "lop", /* 44 */ - "cprs", /* 45 */ - "nop", /* 46 */ - "br", /* 47 */ - "bri", /* 48 */ - "bra", /* 49 */ - "brs", /* 50 */ - "ldvi", /* 51 */ - "stvi", /* 52 */ - "ldsdr", /* 53 */ - "ldkdr", /* 54 */ - "ln", /* 55 */ - "patu", /* 56 */ - "pate", /* 57 */ - "pich", /* 58 */ - "plch", /* 59 */ - "idle", /* 60 */ - "rtnq", /* 61 */ - "cfork", /* 62 */ - "rtn", /* 63 */ - "wfork", /* 64 */ - "join", /* 65 */ - "rtnc", /* 66 */ - "exp", /* 67 */ - "sin", /* 68 */ - "cos", /* 69 */ - "psh", /* 70 */ - "pop", /* 71 */ - "eni", /* 72 */ - "dsi", /* 73 */ - "bkpt", /* 74 */ - "msync", /* 75 */ - "mski", /* 76 */ - "xmti", /* 77 */ - "tstvv", /* 78 */ - "diag", /* 79 */ - "pbkpt", /* 80 */ - "sqrt", /* 81 */ - "casr", /* 82 */ - "atan", /* 83 */ - "sum", /* 84 */ - "all", /* 85 */ - "any", /* 86 */ - "parity", /* 87 */ - "max", /* 88 */ - "min", /* 89 */ - "prod", /* 90 */ - "halt", /* 91 */ - "sysc", /* 92 */ - "trap", /* 93 */ - "tst", /* 94 */ - "lck", /* 95 */ - "ulk", /* 96 */ - "spawn", /* 97 */ - "ldcmr", /* 98 */ - "stcmr", /* 99 */ - "popr", /* 100 */ - "pshr", /* 101 */ - "rcvr", /* 102 */ - "matm", /* 103 */ - "sndr", /* 104 */ - "putr", /* 105 */ - "getr", /* 106 */ - "matr", /* 107 */ - "mat", /* 108 */ - "get", /* 109 */ - "rcv", /* 110 */ - "inc", /* 111 */ - "put", /* 112 */ - "snd", /* 113 */ - "enal", /* 114 */ - "enag", /* 115 */ - "frint", /* 116 */ - "xpnd", /* 117 */ - "ctrsl", /* 118 */ - "ctrsg", /* 119 */ - "stop", /* 120 */ -}; - -char *rop[] = { - "", /* 0 */ - ".t", /* 1 */ - ".f", /* 2 */ - ".s", /* 3 */ - ".d", /* 4 */ - ".b", /* 5 */ - ".h", /* 6 */ - ".w", /* 7 */ - ".l", /* 8 */ - ".x", /* 9 */ - ".u", /* 10 */ - ".s.f", /* 11 */ - ".d.f", /* 12 */ - ".b.f", /* 13 */ - ".h.f", /* 14 */ - ".w.f", /* 15 */ - ".l.f", /* 16 */ - ".t.f", /* 17 */ - ".s.t", /* 18 */ - ".d.t", /* 19 */ - ".b.t", /* 20 */ - ".h.t", /* 21 */ - ".w.t", /* 22 */ - ".l.t", /* 23 */ - ".t.t", /* 24 */ -}; diff --git a/contrib/gdb/include/opcode/h8300.h b/contrib/gdb/include/opcode/h8300.h deleted file mode 100644 index 9d726e2e38e..00000000000 --- a/contrib/gdb/include/opcode/h8300.h +++ /dev/null @@ -1,550 +0,0 @@ -/* Opcode table for the H8-300 - Copyright (C) 1991,1992 Free Software Foundation. - Written by Steve Chamberlain, sac@cygnus.com. - - This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Instructions are stored as a sequence of nibbles. - If the nibble has value 15 or less then the representation is complete. - Otherwise, we record what it contains with several flags. */ - -typedef int op_type; - -#define Hex0 0 -#define Hex1 1 -#define Hex2 2 -#define Hex3 3 -#define Hex4 4 -#define Hex5 5 -#define Hex6 6 -#define Hex7 7 -#define Hex8 8 -#define Hex9 9 -#define HexA 10 -#define HexB 11 -#define HexC 12 -#define HexD 13 -#define HexE 14 -#define HexF 15 - -#define START 0x20 -#define SRC 0x40 -#define DST 0x80 -#define L_8 0x01 -#define L_16 0x02 -#define L_32 0x04 -#define L_P 0x08 -#define L_24 0x10 - -#define REG 0x100 -#define IMM 0x1000 -#define DISP 0x2000 -#define IND 0x4000 -#define INC 0x8000 -#define DEC 0x10000 -#define L_3 0x20000 -#define KBIT 0x40000 -#define DBIT 0x80000 -#define DISPREG 0x100000 -#define IGNORE 0x200000 -#define E 0x400000 /* FIXME: end of nibble sequence? */ -#define L_2 0x800000 -#define CCR 0x4000000 -#define ABS 0x8000000 -#define B30 0x1000000 /* bit 3 must be low */ -#define B31 0x2000000 /* bit 3 must be high */ -#define ABSJMP 0x10000000 -#define ABSMOV 0x20000000 -#define PCREL 0x40000000 -#define MEMIND 0x80000000 - -#define IMM3 IMM|L_3 -#define IMM2 IMM|L_2 - -#define SIZE (L_2|L_3|L_8|L_16|L_32|L_P|L_24) -#define MODE (REG|IMM|DISP|IND|INC|DEC|CCR|ABS|MEMIND) - -#define RD8 (DST|L_8|REG) -#define RD16 (DST|L_16|REG) -#define RD32 (DST|L_32|REG) -#define RS8 (SRC|L_8|REG) -#define RS16 (SRC|L_16|REG) -#define RS32 (SRC|L_32|REG) - -#define RSP (SRC|L_P|REG) -#define RDP (DST|L_P|REG) - -#define IMM8 (IMM|SRC|L_8) -#define IMM16 (IMM|SRC|L_16) -#define IMM32 (IMM|SRC|L_32) - -#define ABS8SRC (SRC|ABS|L_8) -#define ABS8DST (DST|ABS|L_8) - -#define DISP8 (PCREL|L_8) -#define DISP16 (PCREL|L_16) - -#define DISP8SRC (DISP|L_8|SRC) -#define DISP16SRC (DISP|L_16|SRC) - -#define DISP8DST (DISP|L_8|DST) -#define DISP16DST (DISP|L_16|DST) - -#define ABS16SRC (SRC|ABS|L_16) -#define ABS16DST (DST|ABS|L_16) -#define ABS24SRC (SRC|ABS|L_24) -#define ABS24DST (DST|ABS|L_24) - -#define RDDEC (DST|DEC) -#define RSINC (SRC|INC) - -#define RDIND (DST|IND) -#define RSIND (SRC|IND) - -#if 1 -#define OR8 RS8 /* ??? OR as in One Register? */ -#define OR16 RS16 -#define OR32 RS32 -#else -#define OR8 RD8 -#define OR16 RD16 -#define OR32 RD32 -#endif - -struct code -{ - op_type nib[30]; -}; - -struct arg -{ - op_type nib[3]; -}; - -struct h8_opcode -{ - int how; - int inbase; - int time; - char *name; - struct arg args; - struct code data; - int length; - int noperands; - int idx; - int size; -}; - -#ifdef DEFINE_TABLE - -#define BITOP(code, imm, name, op00, op01,op10,op11, op20,op21)\ -{ code, 1, 2, name, {imm,RD8,E}, {op00, op01, imm, RD8, E, 0, 0, 0, 0}, 0, 0, 0, 0},\ -{ code, 1, 6, name, {imm,RDIND,E}, {op10, op11, B30|RDIND, 0, op00,op01, imm, 0, E}, 0, 0, 0, 0},\ -{ code, 1, 6, name, {imm,ABS8DST,E},{op20, op21, ABS8DST, IGNORE, op00,op01, imm, 0,E}, 0, 0, 0, 0} - -#define EBITOP(code, imm, name, op00, op01,op10,op11, op20,op21)\ - BITOP(code,imm, name, op00+1, op01, op10,op11, op20,op21),\ - BITOP(code,RS8, name, op00, op01, op10,op11, op20,op21) - -#define WTWOP(code,name, op1, op2) \ -{ code, 1, 2, name, {RS16, RD16, E}, { op1, op2, RS16, RD16, E, 0, 0, 0, 0}, 0, 0, 0, 0} - -#define BRANCH(code, name, op) \ -{ code, 1, 4,name,{DISP8,E,0}, { 0x4, op, DISP8, IGNORE, E, 0, 0, 0, 0}, 0, 0, 0, 0}, \ -{ code, 0, 6,name,{DISP16,E,0}, { 0x5, 0x8, op, 0x0, DISP16, IGNORE, IGNORE, IGNORE, E,0}, 0, 0, 0, 0} - -#define SOP(code, x,name) \ -{code, 1, x, name - -#define NEW_SOP(code, in,x,name) \ -{code, in, x, name -#define EOP ,0,0,0 } - -#define TWOOP(code, name, op1, op2,op3) \ -{ code,1, 2,name, {IMM8, RD8, E}, { op1, RD8, IMM8, IGNORE, E, 0, 0, 0, 0}, 0, 0, 0, 0},\ -{ code, 1, 2,name, {RS8, RD8, E}, { op2, op3, RS8, RD8, E, 0, 0, 0, 0}, 0, 0, 0, 0} - -#define UNOP(code,name, op1, op2) \ -{ code, 1, 2, name, {OR8, E, 0}, { op1, op2, 0, OR8, E, 0, 0, 0, 0}, 0, 0, 0, 0} - -#define UNOP3(code, name, op1, op2, op3) \ -{ O(code,SB), 1, 2, name, {OR8, E, 0}, {op1, op2, op3+0, OR8, E, 0, 0, 0, 0}, 0, 0, 0, 0}, \ -{ O(code,SW), 0, 2, name, {OR16, E, 0}, {op1, op2, op3+1, OR16, E, 0, 0, 0, 0}, 0, 0, 0, 0}, \ -{ O(code,SL), 0, 2, name, {OR32, E, 0}, {op1, op2, op3+3, OR32|B30, E, 0, 0, 0, 0}, 0, 0, 0, 0} - -#define IMM32LIST IMM32,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE -#define IMM24LIST IMM24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE -#define IMM16LIST IMM16,IGNORE,IGNORE,IGNORE -#define A16LIST L_16,IGNORE,IGNORE,IGNORE -#define DISP24LIST DISP|L_24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE -#define ABS24LIST ABS|L_24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE -#define A24LIST L_24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE -#define PREFIX32 0x0,0x1,0x0,0x0 -#define PREFIXLDC 0x0,0x1,0x4,0x0 - - -#define O(op, size) (op*4+size) - -#define O_RECOMPILE 0 -#define O_ADD 1 -#define O_ADDX 2 -#define O_AND 3 -#define O_BAND 4 -#define O_BRA 5 -#define O_BRN 6 -#define O_BHI 7 -#define O_BLS 8 -#define O_BCC 9 -#define O_BCS 10 -#define O_BNE 11 -#define O_BVC 12 -#define O_BVS 13 -#define O_BPL 14 -#define O_BMI 15 -#define O_BGE 16 -#define O_BLT 17 -#define O_BGT 18 -#define O_BLE 19 -#define O_ANDC 20 -#define O_BEQ 21 -#define O_BCLR 22 -#define O_BIAND 23 -#define O_BILD 24 -#define O_BIOR 25 -#define O_BIXOR 26 -#define O_BIST 27 -#define O_BLD 28 -#define O_BNOT 29 -#define O_BSET 30 -#define O_BSR 31 -#define O_BXOR 32 -#define O_CMP 33 -#define O_DAA 34 -#define O_DAS 35 -#define O_DEC 36 -#define O_DIVU 37 -#define O_DIVS 38 -#define O_INC 39 -#define O_LDC 40 -#define O_MOV_TO_MEM 41 -#define O_OR 42 -#define O_ROTL 43 -#define O_ROTR 44 -#define O_ROTXL 45 -#define O_ROTXR 46 -#define O_BPT 47 -#define O_SHAL 48 -#define O_SHAR 49 -#define O_SHLL 50 -#define O_SHLR 51 -#define O_SUB 52 -#define O_SUBS 53 -#define O_TRAPA 54 -#define O_XOR 55 -#define O_XORC 56 -#define O_BOR 57 -#define O_BST 58 -#define O_BTST 59 -#define O_EEPMOV 60 -#define O_EXTS 61 -#define O_EXTU 62 -#define O_JMP 63 -#define O_JSR 64 -#define O_MULU 65 -#define O_MULS 66 -#define O_NOP 67 -#define O_NOT 68 -#define O_ORC 69 -#define O_RTE 70 -#define O_STC 71 -#define O_SUBX 72 -#define O_NEG 73 -#define O_RTS 74 -#define O_SLEEP 75 -#define O_ILL 76 -#define O_ADDS 77 -#define O_SYSCALL 78 -#define O_MOV_TO_REG 79 -#define O_LAST 80 -#define SB 0 -#define SW 1 -#define SL 2 - - -/* FIXME: Lots of insns have "E, 0, 0, 0, 0" in the nibble code sequences. - Methinks the zeroes aren't necessary. Once confirmed, nuke 'em. */ - -struct h8_opcode h8_opcodes[] = -{ - TWOOP(O(O_ADD,SB),"add.b", 0x8, 0x0,0x8), - - NEW_SOP(O(O_ADD,SW),1,2,"add.w"),{RS16,RD16,E },{0x0,0x9,RS16,RD16,E} EOP, - NEW_SOP(O(O_ADD,SW),0,4,"add.w"),{IMM16,RD16,E },{0x7,0x9,0x1,RD16,IMM16,IGNORE,IGNORE,IGNORE,E} EOP, - NEW_SOP(O(O_ADD,SL),0,2,"add.l"),{RS32,RD32,E }, {0x0,0xA,B31|RS32,B30|RD32,E} EOP, - NEW_SOP(O(O_ADD,SL),0,6,"add.l"),{IMM32,RD32,E },{0x7,0xA,0x1,B30|RD32,IMM32LIST,E} EOP, - NEW_SOP(O(O_ADDS,SL),1,2,"adds"), {KBIT,RDP,E}, {0x0,0xB,KBIT,RDP,E,0,0,0,0} EOP, - - TWOOP(O(O_ADDX,SB),"addx",0x9,0x0,0xE), - TWOOP(O(O_AND,SB), "and.b",0xE,0x1,0x6), - - NEW_SOP(O(O_AND,SW),0,2,"and.w"),{RS16,RD16,E },{0x6,0x6,RS16,RD16,E} EOP, - NEW_SOP(O(O_AND,SW),0,4,"and.w"),{IMM16,RD16,E },{0x7,0x9,0x6,RD16,IMM16,IGNORE,IGNORE,IGNORE,E} EOP, - - NEW_SOP(O(O_AND,SL),0,6,"and.l"),{IMM32,RD32,E },{0x7,0xA,0x6,B30|RD32,IMM32LIST,E} EOP, - NEW_SOP(O(O_AND,SL),0,2,"and.l") ,{RS32,RD32,E },{0x0,0x1,0xF,0x0,0x6,0x6,B30|RS32,B30|RD32,E} EOP, - - NEW_SOP(O(O_ANDC,SB),1,2,"andc"), {IMM8,CCR,E},{ 0x0,0x6,IMM8,IGNORE,E,0,0,0,0} EOP, - - BITOP(O(O_BAND,SB), IMM3,"band",0x7,0x6,0x7,0xC,0x7,0xE), - BRANCH(O(O_BRA,SB),"bra",0x0), - BRANCH(O(O_BRA,SB),"bt",0x0), - BRANCH(O(O_BRN,SB),"brn",0x1), - BRANCH(O(O_BRN,SB),"bf",0x1), - BRANCH(O(O_BHI,SB),"bhi",0x2), - BRANCH(O(O_BLS,SB),"bls",0x3), - BRANCH(O(O_BCC,SB),"bcc",0x4), - BRANCH(O(O_BCC,SB),"bhs",0x4), - BRANCH(O(O_BCS,SB),"bcs",0x5), - BRANCH(O(O_BCS,SB),"blo",0x5), - BRANCH(O(O_BNE,SB),"bne",0x6), - BRANCH(O(O_BEQ,SB),"beq",0x7), - BRANCH(O(O_BVC,SB),"bvc",0x8), - BRANCH(O(O_BVS,SB),"bvs",0x9), - BRANCH(O(O_BPL,SB),"bpl",0xA), - BRANCH(O(O_BMI,SB),"bmi",0xB), - BRANCH(O(O_BGE,SB),"bge",0xC), - BRANCH(O(O_BLT,SB),"blt",0xD), - BRANCH(O(O_BGT,SB),"bgt",0xE), - BRANCH(O(O_BLE,SB),"ble",0xF), - - EBITOP(O(O_BCLR,SB),IMM3, "bclr", 0x6,0x2,0x7,0xD,0x7,0xF), - BITOP(O(O_BIAND,SB),IMM3|B31,"biand",0x7,0x6,0x7,0xC,0x7,0xE), - BITOP(O(O_BILD,SB), IMM3|B31,"bild", 0x7,0x7,0x7,0xC,0x7,0xE), - BITOP(O(O_BIOR,SB), IMM3|B31,"bior", 0x7,0x4,0x7,0xC,0x7,0xE), - BITOP(O(O_BIST,SB), IMM3|B31,"bist", 0x6,0x7,0x7,0xD,0x7,0xF), - BITOP(O(O_BIXOR,SB),IMM3|B31,"bixor",0x7,0x5,0x7,0xC,0x7,0xE), - BITOP(O(O_BLD,SB), IMM3|B30,"bld", 0x7,0x7,0x7,0xC,0x7,0xE), - EBITOP(O(O_BNOT,SB),IMM3|B30,"bnot", 0x6,0x1,0x7,0xD,0x7,0xF), - BITOP(O(O_BOR,SB), IMM3|B30,"bor", 0x7,0x4,0x7,0xC,0x7,0xE), - EBITOP(O(O_BSET,SB),IMM3|B30,"bset", 0x6,0x0,0x7,0xD,0x7,0xF), - - SOP(O(O_BSR,SB),6,"bsr"),{DISP8,E,0},{ 0x5,0x5,DISP8,IGNORE,E,0,0,0,0} EOP, - SOP(O(O_BSR,SB),6,"bsr"),{DISP16,E,0},{ 0x5,0xC,0x0,0x0,DISP16,IGNORE,IGNORE,IGNORE,E,0,0,0,0} EOP, - BITOP(O(O_BST,SB), IMM3|B30,"bst",0x6,0x7,0x7,0xD,0x7,0xF), - EBITOP(O(O_BTST,SB), IMM3|B30,"btst",0x6,0x3,0x7,0xC,0x7,0xE), - BITOP(O(O_BXOR,SB), IMM3|B30,"bxor",0x7,0x5,0x7,0xC,0x7,0xE), - - TWOOP(O(O_CMP,SB), "cmp.b",0xA,0x1,0xC), - WTWOP(O(O_CMP,SW), "cmp.w",0x1,0xD), - - NEW_SOP(O(O_CMP,SW),1,2,"cmp.w"),{RS16,RD16,E },{0x1,0xD,RS16,RD16,E} EOP, - NEW_SOP(O(O_CMP,SW),0,4,"cmp.w"),{IMM16,RD16,E },{0x7,0x9,0x2,RD16,IMM16,IGNORE,IGNORE,IGNORE,E} EOP, - - NEW_SOP(O(O_CMP,SL),0,6,"cmp.l"),{IMM32,RD32,E },{0x7,0xA,0x2,B30|RD32,IMM32LIST,E} EOP, - NEW_SOP(O(O_CMP,SL),0,2,"cmp.l") ,{RS32,RD32,E },{0x1,0xF,B31|RS32,B30|RD32,E} EOP, - - UNOP(O(O_DAA,SB), "daa",0x0,0xF), - UNOP(O(O_DAS,SB), "das",0x1,0xF), - UNOP(O(O_DEC,SB), "dec.b",0x1,0xA), - - NEW_SOP(O(O_DEC, SW),0,2,"dec.w") ,{DBIT,RD16,E },{0x1,0xB,0x5|DBIT,RD16,E} EOP, - NEW_SOP(O(O_DEC, SL),0,2,"dec.l") ,{DBIT,RD32,E },{0x1,0xB,0x7|DBIT,RD32|B30,E} EOP, - - NEW_SOP(O(O_DIVU,SB),1,6,"divxu.b"), {RS8,RD16,E}, {0x5,0x1,RS8,RD16,E,0,0,0,0}EOP, - NEW_SOP(O(O_DIVU,SW),0,20,"divxu.w"),{RS16,RD32,E},{0x5,0x3,RS16,B30|RD32,E}EOP, - - NEW_SOP(O(O_DIVS,SB),0,20,"divxs.b") ,{RS8,RD16,E },{0x0,0x1,0xD,0x0,0x5,0x1,RS8,RD16,E} EOP, - NEW_SOP(O(O_DIVS,SW),0,02,"divxs.w") ,{RS16,RD32,E },{0x0,0x1,0xD,0x0,0x5,0x3,RS16,B30|RD32,E} EOP, - - NEW_SOP(O(O_EEPMOV,SB),1,50,"eepmov"),{ E,0,0},{0x7,0xB,0x5,0xC,0x5,0x9,0x8,0xF,E}EOP, - NEW_SOP(O(O_EEPMOV,SW),0,50,"eepmovw"),{E,0,0},{0x7,0xB,0xD,0x4,0x5,0x9,0x8,0xF,E} EOP, - - NEW_SOP(O(O_EXTS,SW),0,2,"exts.w"),{OR16,E,0},{0x1,0x7,0xD,OR16,E }EOP, - NEW_SOP(O(O_EXTS,SL),0,2,"exts.l"),{OR32,E,0},{0x1,0x7,0xF,OR32|B30,E }EOP, - - NEW_SOP(O(O_EXTU,SW),0,2,"extu.w"),{OR16,E,0},{0x1,0x7,0x5,OR16,E }EOP, - NEW_SOP(O(O_EXTU,SL),0,2,"extu.l"),{OR32,E,0},{0x1,0x7,0x7,OR32|B30,E }EOP, - - UNOP(O(O_INC,SB), "inc",0x0,0xA), - - NEW_SOP(O(O_INC,SW),0,2,"inc.w") ,{DBIT,RD16,E },{0x0,0xB,0x5|DBIT,RD16,E} EOP, - NEW_SOP(O(O_INC,SL),0,2,"inc.l") ,{DBIT,RD32,E },{0x0,0xB,0x7|DBIT,RD32|B30,E} EOP, - - SOP(O(O_JMP,SB),4,"jmp"),{RSIND,E,0},{0x5,0x9,B30|RSIND,0x0,E,0,0,0,0}EOP, - SOP(O(O_JMP,SB),6,"jmp"),{SRC|ABSJMP,E,0},{0x5,0xA,SRC|ABSJMP,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_JMP,SB),8,"jmp"),{SRC|MEMIND,E,0},{0x5,0xB,SRC|MEMIND,IGNORE,E,0,0,0,0}EOP, - - SOP(O(O_JSR,SB),6,"jsr"),{SRC|RSIND,E,0}, {0x5,0xD,B30|RSIND,0x0,E,0,0,0,0}EOP, - SOP(O(O_JSR,SB),8,"jsr"),{SRC|ABSJMP,E,0},{0x5,0xE,SRC|ABSJMP,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_JSR,SB),8,"jsr"),{SRC|MEMIND,E,0},{0x5,0xF,SRC|MEMIND,IGNORE,E,0,0,0,0}EOP, - - NEW_SOP(O(O_LDC,SB),1,2,"ldc"),{IMM8,CCR,E}, { 0x0,0x7,IMM8,IGNORE,E,0,0,0,0}EOP, - NEW_SOP(O(O_LDC,SB),1,2,"ldc"),{OR8,CCR,E}, { 0x0,0x3,0x0,OR8,E,0,0,0,0}EOP, - NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{ABS16SRC,CCR,E}, {PREFIXLDC,0x6,0xB,0x0,0x0,ABS16SRC,IGNORE,IGNORE,IGNORE,E}EOP, - NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{ABS24SRC,CCR,E}, {PREFIXLDC,0x6,0xB,0x2,0x0,0x0,0x0,SRC|ABS24LIST,E}EOP, - NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{DISP|SRC|L_16,CCR,E},{PREFIXLDC,0x6,0x9,B30|DISPREG,0,DISP|L_16,IGNORE,IGNORE,IGNORE,E}EOP, - NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{DISP|SRC|L_24,CCR,E},{PREFIXLDC,0x7,0x8,B30|DISPREG,0,0x6,0xB,0x2,0x0,0x0,0x0,SRC|DISP24LIST,E}EOP, - NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{RSINC,CCR,E}, {PREFIXLDC,0x6,0xD,B30|RSINC,0x0,E}EOP, - NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{RSIND,CCR,E}, {PREFIXLDC,0x6,0x9,B30|RDIND,0x0,E} EOP, - - - SOP(O(O_MOV_TO_REG,SB),4,"mov.b"),{ABSMOV|ABS|SRC|L_16,RD8,E}, { 0x6,0xA,0x0,RD8,ABSMOV|SRC|ABS|A16LIST,E}EOP, - SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{ABSMOV|ABS|SRC|L_24,RD8,E }, { 0x6,0xA,0x2,RD8,0x0,0x0,SRC|ABSMOV|ABS|A24LIST,E }EOP, - SOP(O(O_MOV_TO_MEM,SB),4,"mov.b"),{RS8,ABSMOV|ABS|L_16|DST,E}, { 0x6,0xA,0x8,RS8,ABSMOV|DST|ABS|A16LIST,E}EOP, - SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{RS8,ABSMOV|ABS|DST|L_24,E }, { 0x6,0xA,0xA,RS8,0x0,0x0,DST|ABSMOV|ABS|A24LIST,E }EOP, - - SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{DISP|L_24|SRC,RD8,E}, { 0x7,0x8,B30|DISPREG,0x0,0x6,0xA,0x2,RD8,0x0,0x0,SRC|DISP24LIST,E}EOP, - SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{RS8,DISP|L_24|DST,E}, { 0x7,0x8,B30|DISPREG,0x0,0x6,0xA,0xA,RS8,0x0,0x0,DST|DISP24LIST,E}EOP, - - - - SOP(O(O_MOV_TO_REG,SB),2,"mov.b"),{RS8,RD8,E}, { 0x0,0xC,RS8,RD8,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_REG,SB),2,"mov.b"),{IMM8,RD8,E}, { 0xF,RD8,IMM8,IGNORE,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_REG,SB),4,"mov.b"),{RSIND,RD8,E}, { 0x6,0x8,B30|RSIND,RD8,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{DISP16SRC,RD8,E}, { 0x6,0xE,B30|DISPREG,RD8,DISP16SRC,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{RSINC,RD8,E}, { 0x6,0xC,B30|RSINC,RD8,E,0,0,0,0}EOP, - - SOP(O(O_MOV_TO_REG,SB),4,"mov.b"),{ABS8SRC,RD8,E}, { 0x2,RD8,ABS8SRC,IGNORE,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_MEM,SB),4,"mov.b"),{RS8,RDIND,E}, { 0x6,0x8,RDIND|B31,RS8,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{RS8,DISP16DST,E}, { 0x6,0xE,DISPREG|B31,RS8,DISP16DST,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{RS8,RDDEC|B31,E}, { 0x6,0xC,RDDEC|B31,RS8,E,0,0,0,0}EOP, - - SOP(O(O_MOV_TO_MEM,SB),4,"mov.b"),{RS8,ABS8DST,E}, { 0x3,RS8,ABS8DST,IGNORE,E,0,0,0,0}EOP, - - SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{RS16,RDIND,E}, { 0x6,0x9,RDIND|B31,RS16,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{DISP|L_24|SRC,RD16,E},{ 0x7,0x8,B30|DISPREG,0x0,0x6,0xB,0x2,RD16,0x0,0x0,SRC|DISP24LIST,E}EOP, - SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{RS16,DISP|L_24|DST,E},{ 0x7,0x8,B30|DISPREG,0x0,0x6,0xB,0xA,RS16,0x0,0x0,DST|DISP24LIST,E}EOP, - SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{ABS|L_24|SRC,RD16,E },{ 0x6,0xB,0x2,RD16,0x0,0x0,SRC|ABS24LIST,E }EOP, - SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{RS16,ABS|L_24|DST,E },{ 0x6,0xB,0xA,RS16,0x0,0x0,DST|ABS24LIST,E }EOP, - SOP(O(O_MOV_TO_REG,SW),2,"mov.w"),{RS16,RD16,E}, { 0x0,0xD,RS16, RD16,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_REG,SW),4,"mov.w"),{IMM16,RD16,E}, { 0x7,0x9,0x0,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_MOV_TO_REG,SW),4,"mov.w"),{RSIND,RD16,E}, { 0x6,0x9,B30|RSIND,RD16,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{DISP16SRC,RD16,E}, { 0x6,0xF,B30|DISPREG,RD16,DISP16SRC,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{RSINC,RD16,E}, { 0x6,0xD,B30|RSINC,RD16,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{ABS16SRC,RD16,E}, { 0x6,0xB,0x0,RD16,ABS16SRC,IGNORE,IGNORE,IGNORE,E}EOP, - - SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{RS16,DISP16DST,E}, { 0x6,0xF,DISPREG|B31,RS16,DISP16DST,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{RS16,RDDEC,E}, { 0x6,0xD,RDDEC|B31,RS16,E,0,0,0,0}EOP, - SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{RS16,ABS16DST,E}, { 0x6,0xB,0x8,RS16,ABS16DST,IGNORE,IGNORE,IGNORE,E}EOP, - - SOP(O(O_MOV_TO_REG,SL),4,"mov.l"),{IMM32,RD32,E}, { 0x7,0xA,0x0,B30|RD32,IMM32LIST,E}EOP, - SOP(O(O_MOV_TO_REG,SL),2,"mov.l"),{RS32,RD32,E}, { 0x0,0xF,B31|RS32,B30|RD32,E,0,0,0,0}EOP, - - SOP(O(O_MOV_TO_REG,SL),4,"mov.l"),{RSIND,RD32,E}, { PREFIX32,0x6,0x9,RSIND|B30,B30|RD32,E,0,0,0,0 }EOP, - SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{DISP16SRC,RD32,E}, { PREFIX32,0x6,0xF,DISPREG|B30,B30|RD32,DISP16SRC,IGNORE,IGNORE,IGNORE,E }EOP, - SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{DISP|L_24|SRC,RD32,E},{ PREFIX32,0x7,0x8,B30|DISPREG,0x0,0x6,0xB,0x2,B30|RD32,0x0,0x0,SRC|DISP24LIST,E }EOP, - SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{RSINC,RD32,E}, { PREFIX32,0x6,0xD,B30|RSINC,B30|RD32,E,0,0,0,0 }EOP, - SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{ABS16SRC,RD32,E}, { PREFIX32,0x6,0xB,0x0,B30|RD32,ABS16SRC,IGNORE,IGNORE,IGNORE,E }EOP, - SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{ABS24SRC,RD32,E }, { PREFIX32,0x6,0xB,0x2,B30|RD32,0x0,0x0,SRC|ABS24LIST,E }EOP, - SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{RS32,RDIND,E}, { PREFIX32,0x6,0x9,RDIND|B31,B30|RS32,E,0,0,0,0 }EOP, - SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{RS32,DISP16DST,E}, { PREFIX32,0x6,0xF,DISPREG|B31,B30|RS32,DISP16DST,IGNORE,IGNORE,IGNORE,E }EOP, - SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{RS32,DISP|L_24|DST,E},{ PREFIX32,0x7,0x8,B31|DISPREG,0x0,0x6,0xB,0xA,B30|RS32,0x0,0x0,DST|DISP24LIST,E }EOP, - SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{RS32,RDDEC,E}, { PREFIX32,0x6,0xD,RDDEC|B31,B30|RS32,E,0,0,0,0 }EOP, - SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{RS32,ABS16DST,E}, { PREFIX32,0x6,0xB,0x8,B30|RS32,ABS16DST,IGNORE,IGNORE,IGNORE,E }EOP, - SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{RS32,ABS24DST,E }, { PREFIX32,0x6,0xB,0xA,B30|RS32,0x0,0x0,DST|ABS24LIST,E }EOP, - - SOP(O(O_MOV_TO_REG,SB),10,"movfpe"),{ABS16SRC,RD8,E},{ 0x6,0xA,0x4,RD8,ABS16SRC,IGNORE,IGNORE,IGNORE,E}EOP, - SOP(O(O_MOV_TO_MEM,SB),10,"movtpe"),{RS8,ABS16DST,E},{ 0x6,0xA,0xC,RS8,ABS16DST,IGNORE,IGNORE,IGNORE,E}EOP, - - NEW_SOP(O(O_MULU,SB),1,14,"mulxu.b"),{RS8,RD16,E}, { 0x5,0x0,RS8,RD16,E,0,0,0,0}EOP, - NEW_SOP(O(O_MULU,SW),0,14,"mulxu.w"),{RS16,RD32,E},{ 0x5,0x2,RS16,B30|RD32,E,0,0,0,0}EOP, - - NEW_SOP(O(O_MULS,SB),0,20,"mulxs.b"),{RS8,RD16,E}, { 0x0,0x1,0xc,0x0,0x5,0x0,RS8,RD16,E}EOP, - NEW_SOP(O(O_MULS,SW),0,20,"mulxs.w"),{RS16,RD32,E},{ 0x0,0x1,0xc,0x0,0x5,0x2,RS16,B30|RD32,E}EOP, - - /* ??? This can use UNOP3. */ - NEW_SOP(O(O_NEG,SB),1,2,"neg.b"),{ OR8,E, 0},{ 0x1,0x7,0x8,OR8,E,0,0,0,0}EOP, - NEW_SOP(O(O_NEG,SW),0,2,"neg.w"),{ OR16,E,0},{ 0x1,0x7,0x9,OR16,E}EOP, - NEW_SOP(O(O_NEG,SL),0,2,"neg.l"),{ OR32,E,0},{ 0x1,0x7,0xB,B30|OR32,E}EOP, - - NEW_SOP(O(O_NOP,SB),1,2,"nop"),{E,0,0},{ 0x0,0x0,0x0,0x0,E,0,0,0,0}EOP, - - /* ??? This can use UNOP3. */ - NEW_SOP(O(O_NOT,SB),1,2,"not.b"),{ OR8,E, 0},{ 0x1,0x7,0x0,OR8,E,0,0,0,0}EOP, - NEW_SOP(O(O_NOT,SW),0,2,"not.w"),{ OR16,E,0},{ 0x1,0x7,0x1,OR16,E}EOP, - NEW_SOP(O(O_NOT,SL),0,2,"not.l"),{ OR32,E,0},{ 0x1,0x7,0x3,B30|OR32,E}EOP, - - TWOOP(O(O_OR, SB),"or.b",0xC,0x1,0x4), - NEW_SOP(O(O_OR,SW),0,4,"or.w"),{IMM16,RD16,E },{0x7,0x9,0x4,RD16,IMM16,IGNORE,IGNORE,IGNORE,E} EOP, - NEW_SOP(O(O_OR,SW),0,2,"or.w"),{RS16,RD16,E },{0x6,0x4,RS16,RD16,E} EOP, - - NEW_SOP(O(O_OR,SL),0,6,"or.l"),{IMM32,RD32,E },{0x7,0xA,0x4,B30|RD32,IMM32LIST,E} EOP, - NEW_SOP(O(O_OR,SL),0,2,"or.l"),{RS32,RD32,E },{0x0,0x1,0xF,0x0,0x6,0x4,B30|RS32,B30|RD32,E} EOP, - - NEW_SOP(O(O_ORC,SB),1,2,"orc"),{IMM8,CCR,E},{ 0x0,0x4,IMM8,IGNORE,E,0,0,0,0}EOP, - - NEW_SOP(O(O_MOV_TO_REG,SW),1,6,"pop.w"),{OR16,E,0},{ 0x6,0xD,0x7,OR16,E,0,0,0,0}EOP, - NEW_SOP(O(O_MOV_TO_REG,SL),0,6,"pop.l"),{OR32,E,0},{ PREFIX32,0x6,0xD,0x7,OR32|B30,E,0,0,0,0}EOP, - NEW_SOP(O(O_MOV_TO_MEM,SW),1,6,"push.w"),{OR16,E,0},{ 0x6,0xD,0xF,OR16,E,0,0,0,0}EOP, - NEW_SOP(O(O_MOV_TO_MEM,SL),0,6,"push.l"),{OR32,E,0},{ PREFIX32,0x6,0xD,0xF,OR32|B30,E,0,0,0,0}EOP, - - UNOP3(O_ROTL, "rotl", 0x1,0x2,0x8), - UNOP3(O_ROTR, "rotr", 0x1,0x3,0x8), - UNOP3(O_ROTXL, "rotxl",0x1,0x2,0x0), - UNOP3(O_ROTXR, "rotxr",0x1,0x3,0x0), - - SOP(O(O_BPT,SB), 10,"bpt"),{E,0,0},{ 0x7,0xA,0xF,0xF,E,0,0,0,0}EOP, - SOP(O(O_RTE,SB), 10,"rte"),{E,0,0},{ 0x5,0x6,0x7,0x0,E,0,0,0,0}EOP, - SOP(O(O_RTS,SB), 8,"rts"),{E,0,0},{ 0x5,0x4,0x7,0x0,E,0,0,0,0}EOP, - - UNOP3(O_SHAL, "shal",0x1,0x0,0x8), - UNOP3(O_SHAR, "shar",0x1,0x1,0x8), - UNOP3(O_SHLL, "shll",0x1,0x0,0x0), - UNOP3(O_SHLR, "shlr",0x1,0x1,0x0), - - SOP(O(O_SLEEP,SB),2,"sleep"),{E,0,0},{ 0x0,0x1,0x8,0x0,E,0,0,0,0} EOP, - - NEW_SOP(O(O_STC,SB), 1,2,"stc"),{CCR,RD8,E},{ 0x0,0x2,0x0,RD8,E,0,0,0,0} EOP, - - NEW_SOP(O(O_STC,SB),0,2,"stc"),{CCR,RSIND,E}, {PREFIXLDC,0x6,0x9,B31|RDIND,0x0,E} EOP, - NEW_SOP(O(O_STC,SB),0,2,"stc"),{CCR,DISP|DST|L_16,E},{PREFIXLDC,0x6,0x9,B31|DISPREG,0,DST|DISP|L_16,IGNORE,IGNORE,IGNORE,E}EOP, - NEW_SOP(O(O_STC,SB),0,2,"stc"),{CCR,DISP|DST|L_24,E},{PREFIXLDC,0x7,0x8,B31|DISPREG,0,0x6,0xB,0x2,0x0,0x0,0x0,DST|DISP24LIST,E}EOP, - NEW_SOP(O(O_STC,SB),0,2,"stc"),{CCR,RDDEC,E}, {PREFIXLDC,0x6,0xD,B31|RDDEC,0x0,E}EOP, - - NEW_SOP(O(O_STC,SB),0,2,"stc"),{CCR,ABS16SRC,E}, {PREFIXLDC,0x6,0xB,0x8,0x0,ABS16DST,IGNORE,IGNORE,IGNORE,E}EOP, - NEW_SOP(O(O_STC,SB),0,2,"stc"),{CCR,ABS24SRC,E}, {PREFIXLDC,0x6,0xB,0xA,0x0,0x0,0x0,DST|ABS24LIST,E}EOP, - - SOP(O(O_SUB,SB),2,"sub.b"),{RS8,RD8,E},{ 0x1,0x8,RS8,RD8,E,0,0,0,0}EOP, - - NEW_SOP(O(O_SUB,SW),1,2,"sub.w"),{RS16,RD16,E }, {0x1,0x9,RS16,RD16,E} EOP, - NEW_SOP(O(O_SUB,SW),0,4,"sub.w"),{IMM16,RD16,E }, {0x7,0x9,0x3,RD16,IMM16,IGNORE,IGNORE,IGNORE,E} EOP, - NEW_SOP(O(O_SUB,SL),0,2,"sub.l") ,{RS32,RD32,E }, {0x1,0xA,B31|RS32,B30|RD32,E} EOP, - NEW_SOP(O(O_SUB,SL),0,6,"sub.l"), {IMM32,RD32,E },{0x7,0xA,0x3,B30|RD32,IMM32LIST,E} EOP, - - SOP(O(O_SUBS,SL),2,"subs"),{KBIT,RDP,E},{ 0x1,0xB,KBIT,RDP,E,0,0,0,0}EOP, - TWOOP(O(O_SUBX,SB),"subx",0xB,0x1,0xE), - - NEW_SOP(O(O_TRAPA,SB),0,2,"trapa"),{ IMM2,E}, {0x5,0x7,IMM2,IGNORE,E }EOP, - - TWOOP(O(O_XOR, SB),"xor",0xD,0x1,0x5), - - NEW_SOP(O(O_XOR,SW),0,4,"xor.w"),{IMM16,RD16,E },{0x7,0x9,0x5,RD16,IMM16,IGNORE,IGNORE,IGNORE,E} EOP, - NEW_SOP(O(O_XOR,SW),0,2,"xor.w"),{RS16,RD16,E },{0x6,0x5,RS16,RD16,E} EOP, - - NEW_SOP(O(O_XOR,SL),0,6,"xor.l"),{IMM32,RD32,E },{0x7,0xA,0x5,B30|RD32,IMM32LIST,E} EOP, - NEW_SOP(O(O_XOR,SL),0,2,"xor.l") ,{RS32,RD32,E },{0x0,0x1,0xF,0x0,0x6,0x5,B30|RS32,B30|RD32,E} EOP, - - SOP(O(O_XORC,SB),2,"xorc"),{IMM8,CCR,E},{ 0x0,0x5,IMM8,IGNORE,E,0,0,0,0}EOP, - 0 -}; -#else -extern struct h8_opcode h8_opcodes[] ; -#endif - - - - diff --git a/contrib/gdb/include/opcode/hppa.h b/contrib/gdb/include/opcode/hppa.h deleted file mode 100644 index 6f50e6bbea6..00000000000 --- a/contrib/gdb/include/opcode/hppa.h +++ /dev/null @@ -1,471 +0,0 @@ -/* Table of opcodes for the PA-RISC. - Copyright (C) 1990, 1991, 1993, 1995 Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - -This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler. - -GAS/GDB is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GAS/GDB is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GAS or GDB; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if !defined(__STDC__) && !defined(const) -#define const -#endif - -/* - * Structure of an opcode table entry. - */ - -/* There are two kinds of delay slot nullification: normal which is - * controled by the nullification bit, and conditional, which depends - * on the direction of the branch and its success or failure. - * - * NONE is unfortunately #defined in the hiux system include files. - * #undef it away. - */ -#undef NONE -struct pa_opcode -{ - const char *name; - unsigned long int match; /* Bits that must be set... */ - unsigned long int mask; /* ... in these bits. */ - char *args; - enum pa_arch arch; -}; - -/* - All hppa opcodes are 32 bits. - - The match component is a mask saying which bits must match a - particular opcode in order for an instruction to be an instance - of that opcode. - - The args component is a string containing one character - for each operand of the instruction. - - Bit positions in this description follow HP usage of lsb = 31, - "at" is lsb of field. - - In the args field, the following characters must match exactly: - - '+,() ' - - In the args field, the following characters are unused: - - ' "#$% *+- ./ 3 :; = ' - ' B L [\] _' - ' e gh lm qr { } ' - - Here are all the characters: - - ' !"#$%&'()*+-,./0123456789:;<=>?@' - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' - 'abcdefghijklmnopqrstuvwxyz{|}~' - -Kinds of operands: - x integer register field at 15. - b integer register field at 10. - t integer register field at 31. - y floating point register field at 31 - 5 5 bit immediate at 15. - s 2 bit space specifier at 17. - S 3 bit space specifier at 18. - c indexed load completer. - C short load and store completer. - Y Store Bytes Short completer - < non-negated compare/subtract conditions. - a compare/subtract conditions - d non-negated add conditions - & logical instruction conditions - U unit instruction conditions - > shift/extract/deposit conditions. - ~ bvb,bb conditions - V 5 bit immediate value at 31 - i 11 bit immediate value at 31 - j 14 bit immediate value at 31 - k 21 bit immediate value at 31 - n nullification for branch instructions - N nullification for spop and copr instructions - w 12 bit branch displacement - W 17 bit branch displacement (PC relative) - z 17 bit branch displacement (just a number, not an address) - -Also these: - - p 5 bit shift count at 26 (to support the SHD instruction) encoded as - 31-p - P 5 bit bit position at 26 - T 5 bit field length at 31 (encoded as 32-T) - A 13 bit immediate at 18 (to support the BREAK instruction) - ^ like b, but describes a control register - Z System Control Completer (to support LPA, LHA, etc.) - D 26 bit immediate at 31 (to support the DIAG instruction) - - f 3 bit Special Function Unit identifier at 25 - O 20 bit Special Function Unit operation split between 15 bits at 20 - and 5 bits at 31 - o 15 bit Special Function Unit operation at 20 - 2 22 bit Special Function Unit operation split between 17 bits at 20 - and 5 bits at 31 - 1 15 bit Special Function Unit operation split between 10 bits at 20 - and 5 bits at 31 - 0 10 bit Special Function Unit operation split between 5 bits at 20 - and 5 bits at 31 - u 3 bit coprocessor unit identifier at 25 - F Source Floating Point Operand Format Completer encoded 2 bits at 20 - I Source Floating Point Operand Format Completer encoded 1 bits at 20 - (for 0xe format FP instructions) - G Destination Floating Point Operand Format Completer encoded 2 bits at 18 - M Floating-Point Compare Conditions (encoded as 5 bits at 31) - ? non-negated/negated compare/subtract conditions. - @ non-negated/negated add conditions. - ! non-negated add conditions. - - s 2 bit space specifier at 17. - b register field at 10. - r 5 bit immediate value at 31 (for the break instruction) - (very similar to V above, except the value is unsigned instead of - low_sign_ext) - R 5 bit immediate value at 15 (for the ssm, rsm, probei instructions) - (same as r above, except the value is in a different location) - Q 5 bit immediate value at 10 (a bit position specified in - the bb instruction. It's the same as r above, except the - value is in a different location) - | shift/extract/deposit conditions when used in a conditional branch - -And these (PJH) for PA-89 F.P. registers and instructions: - - v a 't' operand type extended to handle L/R register halves. - E a 'b' operand type extended to handle L/R register halves. - X an 'x' operand type extended to handle L/R register halves. - J a 'b' operand type further extended to handle extra 1.1 registers - K a 'x' operand type further extended to handle extra 1.1 registers - 4 a variation of the 'b' operand type for 'fmpyadd' and 'fmpysub' - 6 a variation of the 'x' operand type for 'fmpyadd' and 'fmpysub' - 7 a variation of the 't' operand type for 'fmpyadd' and 'fmpysub' - 8 5 bit register field at 20 (used in 'fmpyadd' and 'fmpysub') - 9 5 bit register field at 25 (used in 'fmpyadd' and 'fmpysub') - H Floating Point Operand Format at 26 for 'fmpyadd' and 'fmpysub' - (very similar to 'F') -*/ - -/* The order of the opcodes in this table is significant: - - * The assembler requires that all instances of the same mnemonic must be - consecutive. If they aren't, the assembler will bomb at runtime. - - * The disassembler should not care about the order of the opcodes. */ - -static const struct pa_opcode pa_opcodes[] = -{ - -/* pseudo-instructions */ - -{ "b", 0xe8000000, 0xffe0e000, "nW", pa10}, /* bl foo,r0 */ -{ "ldi", 0x34000000, 0xffe0c000, "j,x", pa10}, /* ldo val(r0),r */ -{ "comib", 0x84000000, 0xfc000000, "?n5,b,w", pa10}, /* comib{tf}*/ -{ "comb", 0x80000000, 0xfc000000, "?nx,b,w", pa10}, /* comb{tf} */ -{ "addb", 0xa0000000, 0xfc000000, "@nx,b,w", pa10}, /* addb{tf} */ -{ "addib", 0xa4000000, 0xfc000000, "@n5,b,w", pa10}, /* addib{tf}*/ -{ "nop", 0x08000240, 0xffffffff, "", pa10}, /* or 0,0,0 */ -{ "copy", 0x08000240, 0xffe0ffe0, "x,t", pa10}, /* or r,0,t */ -{ "mtsar", 0x01601840, 0xffe0ffff, "x", pa10}, /* mtctl r,cr11 */ - -/* Loads and Stores for integer registers. */ -{ "ldw", 0x48000000, 0xfc000000, "j(s,b),x", pa10}, -{ "ldw", 0x48000000, 0xfc000000, "j(b),x", pa10}, -{ "ldh", 0x44000000, 0xfc000000, "j(s,b),x", pa10}, -{ "ldh", 0x44000000, 0xfc000000, "j(b),x", pa10}, -{ "ldb", 0x40000000, 0xfc000000, "j(s,b),x", pa10}, -{ "ldb", 0x40000000, 0xfc000000, "j(b),x", pa10}, -{ "stw", 0x68000000, 0xfc000000, "x,j(s,b)", pa10}, -{ "stw", 0x68000000, 0xfc000000, "x,j(b)", pa10}, -{ "sth", 0x64000000, 0xfc000000, "x,j(s,b)", pa10}, -{ "sth", 0x64000000, 0xfc000000, "x,j(b)", pa10}, -{ "stb", 0x60000000, 0xfc000000, "x,j(s,b)", pa10}, -{ "stb", 0x60000000, 0xfc000000, "x,j(b)", pa10}, -{ "ldwm", 0x4c000000, 0xfc000000, "j(s,b),x", pa10}, -{ "ldwm", 0x4c000000, 0xfc000000, "j(b),x", pa10}, -{ "stwm", 0x6c000000, 0xfc000000, "x,j(s,b)", pa10}, -{ "stwm", 0x6c000000, 0xfc000000, "x,j(b)", pa10}, -{ "ldwx", 0x0c000080, 0xfc001fc0, "cx(s,b),t", pa10}, -{ "ldwx", 0x0c000080, 0xfc001fc0, "cx(b),t", pa10}, -{ "ldhx", 0x0c000040, 0xfc001fc0, "cx(s,b),t", pa10}, -{ "ldhx", 0x0c000040, 0xfc001fc0, "cx(b),t", pa10}, -{ "ldbx", 0x0c000000, 0xfc001fc0, "cx(s,b),t", pa10}, -{ "ldbx", 0x0c000000, 0xfc001fc0, "cx(b),t", pa10}, -{ "ldwax", 0x0c000180, 0xfc00dfc0, "cx(b),t", pa10}, -{ "ldcwx", 0x0c0001c0, 0xfc001fc0, "cx(s,b),t", pa10}, -{ "ldcwx", 0x0c0001c0, 0xfc001fc0, "cx(b),t", pa10}, -{ "ldws", 0x0c001080, 0xfc001fc0, "C5(s,b),t", pa10}, -{ "ldws", 0x0c001080, 0xfc001fc0, "C5(b),t", pa10}, -{ "ldhs", 0x0c001040, 0xfc001fc0, "C5(s,b),t", pa10}, -{ "ldhs", 0x0c001040, 0xfc001fc0, "C5(b),t", pa10}, -{ "ldbs", 0x0c001000, 0xfc001fc0, "C5(s,b),t", pa10}, -{ "ldbs", 0x0c001000, 0xfc001fc0, "C5(b),t", pa10}, -{ "ldwas", 0x0c001180, 0xfc00dfc0, "C5(b),t", pa10}, -{ "ldcws", 0x0c0011c0, 0xfc001fc0, "C5(s,b),t", pa10}, -{ "ldcws", 0x0c0011c0, 0xfc001fc0, "C5(b),t", pa10}, -{ "stws", 0x0c001280, 0xfc001fc0, "Cx,V(s,b)", pa10}, -{ "stws", 0x0c001280, 0xfc001fc0, "Cx,V(b)", pa10}, -{ "sths", 0x0c001240, 0xfc001fc0, "Cx,V(s,b)", pa10}, -{ "sths", 0x0c001240, 0xfc001fc0, "Cx,V(b)", pa10}, -{ "stbs", 0x0c001200, 0xfc001fc0, "Cx,V(s,b)", pa10}, -{ "stbs", 0x0c001200, 0xfc001fc0, "Cx,V(b)", pa10}, -{ "stwas", 0x0c001380, 0xfc00dfc0, "Cx,V(b)", pa10}, -{ "stbys", 0x0c001300, 0xfc001fc0, "Yx,V(s,b)", pa10}, -{ "stbys", 0x0c001300, 0xfc001fc0, "Yx,V(b)", pa10}, - -/* Immediate instructions. */ -{ "ldo", 0x34000000, 0xfc00c000, "j(b),x", pa10}, -{ "ldil", 0x20000000, 0xfc000000, "k,b", pa10}, -{ "addil", 0x28000000, 0xfc000000, "k,b", pa10}, - -/* Branching instructions. */ -{ "bl", 0xe8000000, 0xfc00e000, "nW,b", pa10}, -{ "gate", 0xe8002000, 0xfc00e000, "nW,b", pa10}, -{ "blr", 0xe8004000, 0xfc00e001, "nx,b", pa10}, -{ "bv", 0xe800c000, 0xfc00e001, "nx(b)", pa10}, -{ "bv", 0xe800c000, 0xfc00e001, "n(b)", pa10}, -{ "be", 0xe0000000, 0xfc000000, "nz(S,b)", pa10}, -{ "ble", 0xe4000000, 0xfc000000, "nz(S,b)", pa10}, -{ "movb", 0xc8000000, 0xfc000000, "|nx,b,w", pa10}, -{ "movib", 0xcc000000, 0xfc000000, "|n5,b,w", pa10}, -{ "combt", 0x80000000, 0xfc000000, "x,b,t", pa10}, -{ "shd", 0xd0000800, 0xfc001c00, ">x,b,p,t", pa10}, -{ "vextru", 0xd0001000, 0xfc001fe0, ">b,T,x", pa10}, -{ "vextrs", 0xd0001400, 0xfc001fe0, ">b,T,x", pa10}, -{ "extru", 0xd0001800, 0xfc001c00, ">b,P,T,x", pa10}, -{ "extrs", 0xd0001c00, 0xfc001c00, ">b,P,T,x", pa10}, -{ "zvdep", 0xd4000000, 0xfc001fe0, ">x,T,b", pa10}, -{ "vdep", 0xd4000400, 0xfc001fe0, ">x,T,b", pa10}, -{ "zdep", 0xd4000800, 0xfc001c00, ">x,p,T,b", pa10}, -{ "dep", 0xd4000c00, 0xfc001c00, ">x,p,T,b", pa10}, -{ "zvdepi", 0xd4001000, 0xfc001fe0, ">5,T,b", pa10}, -{ "vdepi", 0xd4001400, 0xfc001fe0, ">5,T,b", pa10}, -{ "zdepi", 0xd4001800, 0xfc001c00, ">5,p,T,b", pa10}, -{ "depi", 0xd4001c00, 0xfc001c00, ">5,p,T,b", pa10}, - -/* System Control Instructions */ - -{ "break", 0x00000000, 0xfc001fe0, "r,A", pa10}, -{ "rfi", 0x00000c00, 0xffffffff, "", pa10}, -{ "rfir", 0x00000ca0, 0xffffffff, "", pa11}, -{ "ssm", 0x00000d60, 0xffe0ffe0, "R,t", pa10}, -{ "rsm", 0x00000e60, 0xffe0ffe0, "R,t", pa10}, -{ "mtsm", 0x00001860, 0xffe0ffff, "x", pa10}, -{ "ldsid", 0x000010a0, 0xfc1f3fe0, "(s,b),t", pa10}, -{ "ldsid", 0x000010a0, 0xfc1f3fe0, "(b),t", pa10}, -{ "mtsp", 0x00001820, 0xffe01fff, "x,S", pa10}, -{ "mtctl", 0x00001840, 0xfc00ffff, "x,^", pa10}, -{ "mfsp", 0x000004a0, 0xffff1fe0, "S,t", pa10}, -{ "mfctl", 0x000008a0, 0xfc1fffe0, "^,t", pa10}, -{ "sync", 0x00000400, 0xffffffff, "", pa10}, -{ "syncdma", 0x00100400, 0xffffffff, "", pa10}, -{ "prober", 0x04001180, 0xfc003fe0, "(s,b),x,t", pa10}, -{ "prober", 0x04001180, 0xfc003fe0, "(b),x,t", pa10}, -{ "proberi", 0x04003180, 0xfc003fe0, "(s,b),R,t", pa10}, -{ "proberi", 0x04003180, 0xfc003fe0, "(b),R,t", pa10}, -{ "probew", 0x040011c0, 0xfc003fe0, "(s,b),x,t", pa10}, -{ "probew", 0x040011c0, 0xfc003fe0, "(b),x,t", pa10}, -{ "probewi", 0x040031c0, 0xfc003fe0, "(s,b),R,t", pa10}, -{ "probewi", 0x040031c0, 0xfc003fe0, "(b),R,t", pa10}, -{ "lpa", 0x04001340, 0xfc003fc0, "Zx(s,b),t", pa10}, -{ "lpa", 0x04001340, 0xfc003fc0, "Zx(b),t", pa10}, -{ "lha", 0x04001300, 0xfc003fc0, "Zx(s,b),t", pa10}, -{ "lha", 0x04001300, 0xfc003fc0, "Zx(b),t", pa10}, -{ "lci", 0x04001300, 0xfc003fe0, "x(s,b),t", pa10}, -{ "lci", 0x04001300, 0xfc003fe0, "x(b),t", pa10}, -{ "pdtlb", 0x04001200, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "pdtlb", 0x04001200, 0xfc003fdf, "Zx(b)", pa10}, -{ "pitlb", 0x04000200, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "pitlb", 0x04000200, 0xfc003fdf, "Zx(b)", pa10}, -{ "pdtlbe", 0x04001240, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "pdtlbe", 0x04001240, 0xfc003fdf, "Zx(b)", pa10}, -{ "pitlbe", 0x04000240, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "pitlbe", 0x04000240, 0xfc003fdf, "Zx(b)", pa10}, -{ "idtlba", 0x04001040, 0xfc003fff, "x,(s,b)", pa10}, -{ "idtlba", 0x04001040, 0xfc003fff, "x,(b)", pa10}, -{ "iitlba", 0x04000040, 0xfc003fff, "x,(s,b)", pa10}, -{ "iitlba", 0x04000040, 0xfc003fff, "x,(b)", pa10}, -{ "idtlbp", 0x04001000, 0xfc003fff, "x,(s,b)", pa10}, -{ "idtlbp", 0x04001000, 0xfc003fff, "x,(b)", pa10}, -{ "iitlbp", 0x04000000, 0xfc003fff, "x,(s,b)", pa10}, -{ "iitlbp", 0x04000000, 0xfc003fff, "x,(b)", pa10}, -{ "pdc", 0x04001380, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "pdc", 0x04001380, 0xfc003fdf, "Zx(b)", pa10}, -{ "fdc", 0x04001280, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "fdc", 0x04001280, 0xfc003fdf, "Zx(b)", pa10}, -{ "fic", 0x04000280, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "fic", 0x04000280, 0xfc003fdf, "Zx(b)", pa10}, -{ "fdce", 0x040012c0, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "fdce", 0x040012c0, 0xfc003fdf, "Zx(b)", pa10}, -{ "fice", 0x040002c0, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "fice", 0x040002c0, 0xfc003fdf, "Zx(b)", pa10}, -{ "diag", 0x14000000, 0xfc000000, "D", pa10}, - -/* gfw and gfr are not in the HP PA 1.1 manual, but they are in either - the Timex FPU or the Mustang ERS (not sure which) manual. */ -{ "gfw", 0x04001680, 0xfc003fdf, "Zx(s,b)", pa11}, -{ "gfw", 0x04001680, 0xfc003fdf, "Zx(b)", pa11}, -{ "gfr", 0x04001a80, 0xfc003fdf, "Zx(s,b)", pa11}, -{ "gfr", 0x04001a80, 0xfc003fdf, "Zx(b)", pa11}, - -/* Floating Point Coprocessor Instructions */ - -{ "fldwx", 0x24000000, 0xfc001f80, "cx(s,b),v", pa10}, -{ "fldwx", 0x24000000, 0xfc001f80, "cx(b),v", pa10}, -{ "flddx", 0x2c000000, 0xfc001fc0, "cx(s,b),y", pa10}, -{ "flddx", 0x2c000000, 0xfc001fc0, "cx(b),y", pa10}, -{ "fstwx", 0x24000200, 0xfc001f80, "cv,x(s,b)", pa10}, -{ "fstwx", 0x24000200, 0xfc001f80, "cv,x(b)", pa10}, -{ "fstdx", 0x2c000200, 0xfc001fc0, "cy,x(s,b)", pa10}, -{ "fstdx", 0x2c000200, 0xfc001fc0, "cy,x(b)", pa10}, -{ "fstqx", 0x3c000200, 0xfc001fc0, "cy,x(s,b)", pa10}, -{ "fstqx", 0x3c000200, 0xfc001fc0, "cy,x(b)", pa10}, -{ "fldws", 0x24001000, 0xfc001f80, "C5(s,b),v", pa10}, -{ "fldws", 0x24001000, 0xfc001f80, "C5(b),v", pa10}, -{ "fldds", 0x2c001000, 0xfc001fc0, "C5(s,b),y", pa10}, -{ "fldds", 0x2c001000, 0xfc001fc0, "C5(b),y", pa10}, -{ "fstws", 0x24001200, 0xfc001f80, "Cv,5(s,b)", pa10}, -{ "fstws", 0x24001200, 0xfc001f80, "Cv,5(b)", pa10}, -{ "fstds", 0x2c001200, 0xfc001fc0, "Cy,5(s,b)", pa10}, -{ "fstds", 0x2c001200, 0xfc001fc0, "Cy,5(b)", pa10}, -{ "fstqs", 0x3c001200, 0xfc001fc0, "Cy,5(s,b)", pa10}, -{ "fstqs", 0x3c001200, 0xfc001fc0, "Cy,5(b)", pa10}, -{ "fadd", 0x30000600, 0xfc00e7e0, "FE,X,v", pa10}, -{ "fadd", 0x38000600, 0xfc00e720, "IJ,K,v", pa10}, -{ "fsub", 0x30002600, 0xfc00e7e0, "FE,X,v", pa10}, -{ "fsub", 0x38002600, 0xfc00e720, "IJ,K,v", pa10}, -{ "fmpy", 0x30004600, 0xfc00e7e0, "FE,X,v", pa10}, -{ "fmpy", 0x38004600, 0xfc00e720, "IJ,K,v", pa10}, -{ "fdiv", 0x30006600, 0xfc00e7e0, "FE,X,v", pa10}, -{ "fdiv", 0x38006600, 0xfc00e720, "IJ,K,v", pa10}, -{ "fsqrt", 0x30008000, 0xfc1fe7e0, "FE,v", pa10}, -{ "fsqrt", 0x38008000, 0xfc1fe720, "FJ,v", pa10}, -{ "fabs", 0x30006000, 0xfc1fe7e0, "FE,v", pa10}, -{ "fabs", 0x38006000, 0xfc1fe720, "FJ,v", pa10}, -{ "frem", 0x30008600, 0xfc00e7e0, "FE,X,v", pa10}, -{ "frem", 0x38008600, 0xfc00e720, "FJ,K,v", pa10}, -{ "frnd", 0x3000a000, 0xfc1fe7e0, "FE,v", pa10}, -{ "frnd", 0x3800a000, 0xfc1fe720, "FJ,v", pa10}, -{ "fcpy", 0x30004000, 0xfc1fe7e0, "FE,v", pa10}, -{ "fcpy", 0x38004000, 0xfc1fe720, "FJ,v", pa10}, -{ "fcnvff", 0x30000200, 0xfc1f87e0, "FGE,v", pa10}, -{ "fcnvff", 0x38000200, 0xfc1f8720, "FGJ,v", pa10}, -{ "fcnvxf", 0x30008200, 0xfc1f87e0, "FGE,v", pa10}, -{ "fcnvxf", 0x38008200, 0xfc1f8720, "FGJ,v", pa10}, -{ "fcnvfx", 0x30010200, 0xfc1f87e0, "FGE,v", pa10}, -{ "fcnvfx", 0x38010200, 0xfc1f8720, "FGJ,v", pa10}, -{ "fcnvfxt", 0x30018200, 0xfc1f87e0, "FGE,v", pa10}, -{ "fcnvfxt", 0x38018200, 0xfc1f8720, "FGJ,v", pa10}, -{ "fcmp", 0x30000400, 0xfc00e7e0, "FME,X", pa10}, -{ "fcmp", 0x38000400, 0xfc00e720, "IMJ,K", pa10}, -{ "xmpyu", 0x38004700, 0xfc00e720, "E,X,v", pa11}, -{ "fmpyadd", 0x18000000, 0xfc000000, "H4,6,7,9,8", pa11}, -{ "fmpysub", 0x98000000, 0xfc000000, "H4,6,7,9,8", pa11}, -{ "ftest", 0x30002420, 0xffffffff, "", pa10}, - - -/* Assist Instructions */ - -{ "spop0", 0x10000000, 0xfc000600, "f,ON", pa10}, -{ "spop1", 0x10000200, 0xfc000600, "f,oNt", pa10}, -{ "spop2", 0x10000400, 0xfc000600, "f,1Nb", pa10}, -{ "spop3", 0x10000600, 0xfc000600, "f,0Nx,b", pa10}, -{ "copr", 0x30000000, 0xfc000000, "u,2N", pa10}, -{ "cldwx", 0x24000000, 0xfc001e00, "ucx(s,b),t", pa10}, -{ "cldwx", 0x24000000, 0xfc001e00, "ucx(b),t", pa10}, -{ "clddx", 0x2c000000, 0xfc001e00, "ucx(s,b),t", pa10}, -{ "clddx", 0x2c000000, 0xfc001e00, "ucx(b),t", pa10}, -{ "cstwx", 0x24000200, 0xfc001e00, "uct,x(s,b)", pa10}, -{ "cstwx", 0x24000200, 0xfc001e00, "uct,x(b)", pa10}, -{ "cstdx", 0x2c000200, 0xfc001e00, "uct,x(s,b)", pa10}, -{ "cstdx", 0x2c000200, 0xfc001e00, "uct,x(b)", pa10}, -{ "cldws", 0x24001000, 0xfc001e00, "uC5(s,b),t", pa10}, -{ "cldws", 0x24001000, 0xfc001e00, "uC5(b),t", pa10}, -{ "cldds", 0x2c001000, 0xfc001e00, "uC5(s,b),t", pa10}, -{ "cldds", 0x2c001000, 0xfc001e00, "uC5(b),t", pa10}, -{ "cstws", 0x24001200, 0xfc001e00, "uCt,5(s,b)", pa10}, -{ "cstws", 0x24001200, 0xfc001e00, "uCt,5(b)", pa10}, -{ "cstds", 0x2c001200, 0xfc001e00, "uCt,5(s,b)", pa10}, -{ "cstds", 0x2c001200, 0xfc001e00, "uCt,5(b)", pa10}, -}; - -#define NUMOPCODES ((sizeof pa_opcodes)/(sizeof pa_opcodes[0])) - -/* SKV 12/18/92. Added some denotations for various operands. */ - -#define PA_IMM11_AT_31 'i' -#define PA_IMM14_AT_31 'j' -#define PA_IMM21_AT_31 'k' -#define PA_DISP12 'w' -#define PA_DISP17 'W' - -#define N_HPPA_OPERAND_FORMATS 5 diff --git a/contrib/gdb/include/opcode/i386.h b/contrib/gdb/include/opcode/i386.h deleted file mode 100644 index 849a86fa7b2..00000000000 --- a/contrib/gdb/include/opcode/i386.h +++ /dev/null @@ -1,898 +0,0 @@ -/* i386-opcode.h -- Intel 80386 opcode table - Copyright 1989, 1991, 1992, 1995 Free Software Foundation. - -This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -static const template i386_optab[] = { - -#define _ None -/* move instructions */ -#define MOV_AX_DISP32 0xa0 -{ "mov", 2, 0xa0, _, DW|NoModrm, { Disp32, Acc, 0 } }, -{ "mov", 2, 0x88, _, DW|Modrm, { Reg, Reg|Mem, 0 } }, -{ "mov", 2, 0xb0, _, ShortFormW, { Imm, Reg, 0 } }, -{ "mov", 2, 0xc6, _, W|Modrm, { Imm, Reg|Mem, 0 } }, -{ "mov", 2, 0x8c, _, D|Modrm, { SReg3|SReg2, Reg16|Mem, 0 } }, -/* move to/from control debug registers */ -{ "mov", 2, 0x0f20, _, D|Modrm, { Control, Reg32, 0} }, -{ "mov", 2, 0x0f21, _, D|Modrm, { Debug, Reg32, 0} }, -{ "mov", 2, 0x0f24, _, D|Modrm, { Test, Reg32, 0} }, - -/* move with sign extend */ -/* "movsbl" & "movsbw" must not be unified into "movsb" to avoid - conflict with the "movs" string move instruction. Thus, - {"movsb", 2, 0x0fbe, _, ReverseRegRegmem|Modrm, { Reg8|Mem, Reg16|Reg32, 0} }, - is not kosher; we must seperate the two instructions. */ -{"movsbl", 2, 0x0fbe, _, ReverseRegRegmem|Modrm|Data32, { Reg8|Mem, Reg32, 0} }, -{"movsbw", 2, 0x0fbe, _, ReverseRegRegmem|Modrm|Data16, { Reg8|Mem, Reg16, 0} }, -{"movswl", 2, 0x0fbf, _, ReverseRegRegmem|Modrm, { Reg16|Mem, Reg32, 0} }, - -/* move with zero extend */ -{"movzb", 2, 0x0fb6, _, ReverseRegRegmem|Modrm, { Reg8|Mem, Reg16|Reg32, 0} }, -{"movzwl", 2, 0x0fb7, _, ReverseRegRegmem|Modrm, { Reg16|Mem, Reg32, 0} }, - -/* push instructions */ -{"push", 1, 0x50, _, ShortForm, { WordReg,0,0 } }, -{"push", 1, 0xff, 0x6, Modrm, { WordReg|WordMem, 0, 0 } }, -{"push", 1, 0x6a, _, NoModrm, { Imm8S, 0, 0} }, -{"push", 1, 0x68, _, NoModrm, { Imm16|Imm32, 0, 0} }, -{"push", 1, 0x06, _, Seg2ShortForm, { SReg2,0,0 } }, -{"push", 1, 0x0fa0, _, Seg3ShortForm, { SReg3,0,0 } }, -/* push all */ -{"pusha", 0, 0x60, _, NoModrm, { 0, 0, 0 } }, - -/* pop instructions */ -{"pop", 1, 0x58, _, ShortForm, { WordReg,0,0 } }, -{"pop", 1, 0x8f, 0x0, Modrm, { WordReg|WordMem, 0, 0 } }, -#define POP_SEG_SHORT 0x7 -{"pop", 1, 0x07, _, Seg2ShortForm, { SReg2,0,0 } }, -{"pop", 1, 0x0fa1, _, Seg3ShortForm, { SReg3,0,0 } }, -/* pop all */ -{"popa", 0, 0x61, _, NoModrm, { 0, 0, 0 } }, - -/* xchg exchange instructions - xchg commutes: we allow both operand orders */ -{"xchg", 2, 0x90, _, ShortForm, { WordReg, Acc, 0 } }, -{"xchg", 2, 0x90, _, ShortForm, { Acc, WordReg, 0 } }, -{"xchg", 2, 0x86, _, W|Modrm, { Reg, Reg|Mem, 0 } }, -{"xchg", 2, 0x86, _, W|Modrm, { Reg|Mem, Reg, 0 } }, - -/* in/out from ports */ -{"in", 2, 0xe4, _, W|NoModrm, { Imm8, Acc, 0 } }, -{"in", 2, 0xec, _, W|NoModrm, { InOutPortReg, Acc, 0 } }, -{"in", 1, 0xe4, _, W|NoModrm, { Imm8, 0, 0 } }, -{"in", 1, 0xec, _, W|NoModrm, { InOutPortReg, 0, 0 } }, -{"out", 2, 0xe6, _, W|NoModrm, { Acc, Imm8, 0 } }, -{"out", 2, 0xee, _, W|NoModrm, { Acc, InOutPortReg, 0 } }, -{"out", 1, 0xe6, _, W|NoModrm, { Imm8, 0, 0 } }, -{"out", 1, 0xee, _, W|NoModrm, { InOutPortReg, 0, 0 } }, - -/* load effective address */ -{"lea", 2, 0x8d, _, Modrm, { WordMem, WordReg, 0 } }, - -/* load segment registers from memory */ -{"lds", 2, 0xc5, _, Modrm, { Mem, Reg32, 0} }, -{"les", 2, 0xc4, _, Modrm, { Mem, Reg32, 0} }, -{"lfs", 2, 0x0fb4, _, Modrm, { Mem, Reg32, 0} }, -{"lgs", 2, 0x0fb5, _, Modrm, { Mem, Reg32, 0} }, -{"lss", 2, 0x0fb2, _, Modrm, { Mem, Reg32, 0} }, - -/* flags register instructions */ -{"clc", 0, 0xf8, _, NoModrm, { 0, 0, 0} }, -{"cld", 0, 0xfc, _, NoModrm, { 0, 0, 0} }, -{"cli", 0, 0xfa, _, NoModrm, { 0, 0, 0} }, -{"clts", 0, 0x0f06, _, NoModrm, { 0, 0, 0} }, -{"cmc", 0, 0xf5, _, NoModrm, { 0, 0, 0} }, -{"lahf", 0, 0x9f, _, NoModrm, { 0, 0, 0} }, -{"sahf", 0, 0x9e, _, NoModrm, { 0, 0, 0} }, -{"pushfl", 0, 0x9c, _, NoModrm|Data32, { 0, 0, 0} }, -{"popfl", 0, 0x9d, _, NoModrm|Data32, { 0, 0, 0} }, -{"pushfw", 0, 0x9c, _, NoModrm|Data16, { 0, 0, 0} }, -{"popfw", 0, 0x9d, _, NoModrm|Data16, { 0, 0, 0} }, -{"pushf", 0, 0x9c, _, NoModrm, { 0, 0, 0} }, -{"popf", 0, 0x9d, _, NoModrm, { 0, 0, 0} }, -{"stc", 0, 0xf9, _, NoModrm, { 0, 0, 0} }, -{"std", 0, 0xfd, _, NoModrm, { 0, 0, 0} }, -{"sti", 0, 0xfb, _, NoModrm, { 0, 0, 0} }, - -{"add", 2, 0x0, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"add", 2, 0x83, 0, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"add", 2, 0x4, _, W|NoModrm, { Imm, Acc, 0} }, -{"add", 2, 0x80, 0, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"inc", 1, 0x40, _, ShortForm, { WordReg, 0, 0} }, -{"inc", 1, 0xfe, 0, W|Modrm, { Reg|Mem, 0, 0} }, - -{"sub", 2, 0x28, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"sub", 2, 0x83, 5, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"sub", 2, 0x2c, _, W|NoModrm, { Imm, Acc, 0} }, -{"sub", 2, 0x80, 5, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"dec", 1, 0x48, _, ShortForm, { WordReg, 0, 0} }, -{"dec", 1, 0xfe, 1, W|Modrm, { Reg|Mem, 0, 0} }, - -{"sbb", 2, 0x18, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"sbb", 2, 0x83, 3, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"sbb", 2, 0x1c, _, W|NoModrm, { Imm, Acc, 0} }, -{"sbb", 2, 0x80, 3, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"cmp", 2, 0x38, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"cmp", 2, 0x83, 7, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"cmp", 2, 0x3c, _, W|NoModrm, { Imm, Acc, 0} }, -{"cmp", 2, 0x80, 7, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"test", 2, 0x84, _, W|Modrm, { Reg|Mem, Reg, 0} }, -{"test", 2, 0x84, _, W|Modrm, { Reg, Reg|Mem, 0} }, -{"test", 2, 0xa8, _, W|NoModrm, { Imm, Acc, 0} }, -{"test", 2, 0xf6, 0, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"and", 2, 0x20, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"and", 2, 0x83, 4, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"and", 2, 0x24, _, W|NoModrm, { Imm, Acc, 0} }, -{"and", 2, 0x80, 4, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"or", 2, 0x08, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"or", 2, 0x83, 1, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"or", 2, 0x0c, _, W|NoModrm, { Imm, Acc, 0} }, -{"or", 2, 0x80, 1, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"xor", 2, 0x30, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"xor", 2, 0x83, 6, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"xor", 2, 0x34, _, W|NoModrm, { Imm, Acc, 0} }, -{"xor", 2, 0x80, 6, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"adc", 2, 0x10, _, DW|Modrm, { Reg, Reg|Mem, 0} }, -{"adc", 2, 0x83, 2, Modrm, { Imm8S, WordReg|WordMem, 0} }, -{"adc", 2, 0x14, _, W|NoModrm, { Imm, Acc, 0} }, -{"adc", 2, 0x80, 2, W|Modrm, { Imm, Reg|Mem, 0} }, - -{"neg", 1, 0xf6, 3, W|Modrm, { Reg|Mem, 0, 0} }, -{"not", 1, 0xf6, 2, W|Modrm, { Reg|Mem, 0, 0} }, - -{"aaa", 0, 0x37, _, NoModrm, { 0, 0, 0} }, -{"aas", 0, 0x3f, _, NoModrm, { 0, 0, 0} }, -{"daa", 0, 0x27, _, NoModrm, { 0, 0, 0} }, -{"das", 0, 0x2f, _, NoModrm, { 0, 0, 0} }, -{"aad", 0, 0xd50a, _, NoModrm, { 0, 0, 0} }, -{"aam", 0, 0xd40a, _, NoModrm, { 0, 0, 0} }, - -/* conversion insns */ -/* conversion: intel naming */ -{"cbw", 0, 0x98, _, NoModrm|Data16, { 0, 0, 0} }, -{"cwd", 0, 0x99, _, NoModrm|Data16, { 0, 0, 0} }, -{"cwde", 0, 0x98, _, NoModrm|Data32, { 0, 0, 0} }, -{"cdq", 0, 0x99, _, NoModrm|Data32, { 0, 0, 0} }, -/* att naming */ -{"cbtw", 0, 0x98, _, NoModrm|Data16, { 0, 0, 0} }, -{"cwtl", 0, 0x98, _, NoModrm|Data32, { 0, 0, 0} }, -{"cwtd", 0, 0x99, _, NoModrm|Data16, { 0, 0, 0} }, -{"cltd", 0, 0x99, _, NoModrm|Data32, { 0, 0, 0} }, - -/* Warning! the mul/imul (opcode 0xf6) must only have 1 operand! They are - expanding 64-bit multiplies, and *cannot* be selected to accomplish - 'imul %ebx, %eax' (opcode 0x0faf must be used in this case) - These multiplies can only be selected with single operand forms. */ -{"mul", 1, 0xf6, 4, W|Modrm, { Reg|Mem, 0, 0} }, -{"imul", 1, 0xf6, 5, W|Modrm, { Reg|Mem, 0, 0} }, - - - - -/* imulKludge here is needed to reverse the i.rm.reg & i.rm.regmem fields. - These instructions are exceptions: 'imul $2, %eax, %ecx' would put - '%eax' in the reg field and '%ecx' in the regmem field if we did not - switch them. */ -{"imul", 2, 0x0faf, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, -{"imul", 3, 0x6b, _, Modrm|ReverseRegRegmem, { Imm8S, WordReg|Mem, WordReg} }, -{"imul", 3, 0x69, _, Modrm|ReverseRegRegmem, { Imm16|Imm32, WordReg|Mem, WordReg} }, -/* - imul with 2 operands mimicks imul with 3 by puting register both - in i.rm.reg & i.rm.regmem fields -*/ -{"imul", 2, 0x6b, _, Modrm|imulKludge, { Imm8S, WordReg, 0} }, -{"imul", 2, 0x69, _, Modrm|imulKludge, { Imm16|Imm32, WordReg, 0} }, -{"div", 1, 0xf6, 6, W|Modrm, { Reg|Mem, 0, 0} }, -{"div", 2, 0xf6, 6, W|Modrm, { Reg|Mem, Acc, 0} }, -{"idiv", 1, 0xf6, 7, W|Modrm, { Reg|Mem, 0, 0} }, -{"idiv", 2, 0xf6, 7, W|Modrm, { Reg|Mem, Acc, 0} }, - -{"rol", 2, 0xd0, 0, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"rol", 2, 0xc0, 0, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"rol", 2, 0xd2, 0, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"rol", 1, 0xd0, 0, W|Modrm, { Reg|Mem, 0, 0} }, - -{"ror", 2, 0xd0, 1, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"ror", 2, 0xc0, 1, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"ror", 2, 0xd2, 1, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"ror", 1, 0xd0, 1, W|Modrm, { Reg|Mem, 0, 0} }, - -{"rcl", 2, 0xd0, 2, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"rcl", 2, 0xc0, 2, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"rcl", 2, 0xd2, 2, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"rcl", 1, 0xd0, 2, W|Modrm, { Reg|Mem, 0, 0} }, - -{"rcr", 2, 0xd0, 3, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"rcr", 2, 0xc0, 3, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"rcr", 2, 0xd2, 3, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"rcr", 1, 0xd0, 3, W|Modrm, { Reg|Mem, 0, 0} }, - -{"sal", 2, 0xd0, 4, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"sal", 2, 0xc0, 4, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"sal", 2, 0xd2, 4, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"sal", 1, 0xd0, 4, W|Modrm, { Reg|Mem, 0, 0} }, -{"shl", 2, 0xd0, 4, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"shl", 2, 0xc0, 4, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"shl", 2, 0xd2, 4, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"shl", 1, 0xd0, 4, W|Modrm, { Reg|Mem, 0, 0} }, - -{"shld", 3, 0x0fa4, _, Modrm, { Imm8, WordReg, WordReg|Mem} }, -{"shld", 3, 0x0fa5, _, Modrm, { ShiftCount, WordReg, WordReg|Mem} }, -{"shld", 2, 0x0fa5, _, Modrm, { WordReg, WordReg|Mem, 0} }, - -{"shr", 2, 0xd0, 5, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"shr", 2, 0xc0, 5, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"shr", 2, 0xd2, 5, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"shr", 1, 0xd0, 5, W|Modrm, { Reg|Mem, 0, 0} }, - -{"shrd", 3, 0x0fac, _, Modrm, { Imm8, WordReg, WordReg|Mem} }, -{"shrd", 3, 0x0fad, _, Modrm, { ShiftCount, WordReg, WordReg|Mem} }, -{"shrd", 2, 0x0fad, _, Modrm, { WordReg, WordReg|Mem, 0} }, - -{"sar", 2, 0xd0, 7, W|Modrm, { Imm1, Reg|Mem, 0} }, -{"sar", 2, 0xc0, 7, W|Modrm, { Imm8, Reg|Mem, 0} }, -{"sar", 2, 0xd2, 7, W|Modrm, { ShiftCount, Reg|Mem, 0} }, -{"sar", 1, 0xd0, 7, W|Modrm, { Reg|Mem, 0, 0} }, - -/* control transfer instructions */ -#define CALL_PC_RELATIVE 0xe8 -{"call", 1, 0xe8, _, JumpDword, { Disp32, 0, 0} }, -{"call", 1, 0xff, 2, Modrm|Data32, { Reg|Mem|JumpAbsolute, 0, 0} }, -{"callw", 1, 0xff, 2, Modrm|Data16, { Reg|Mem|JumpAbsolute, 0, 0} }, -#define CALL_FAR_IMMEDIATE 0x9a -{"lcall", 2, 0x9a, _, JumpInterSegment, { Imm16, Abs32|Imm32, 0} }, -{"lcall", 1, 0xff, 3, Modrm|Data32, { Mem, 0, 0} }, -{"lcallw", 1, 0xff, 3, Modrm|Data16, { Mem, 0, 0} }, - -#define JUMP_PC_RELATIVE 0xeb -{"jmp", 1, 0xeb, _, Jump, { Disp, 0, 0} }, -{"jmp", 1, 0xff, 4, Modrm, { Reg32|Mem|JumpAbsolute, 0, 0} }, -#define JUMP_FAR_IMMEDIATE 0xea -{"ljmp", 2, 0xea, _, JumpInterSegment, { Imm16, Imm32, 0} }, -{"ljmp", 1, 0xff, 5, Modrm|Data32, { Mem, 0, 0} }, - -{"ret", 0, 0xc3, _, NoModrm|Data32, { 0, 0, 0} }, -{"ret", 1, 0xc2, _, NoModrm|Data32, { Imm16, 0, 0} }, -{"retw", 0, 0xc3, _, NoModrm|Data16, { 0, 0, 0} }, -{"retw", 1, 0xc2, _, NoModrm|Data16, { Imm16, 0, 0} }, -{"lret", 0, 0xcb, _, NoModrm|Data32, { 0, 0, 0} }, -{"lret", 1, 0xca, _, NoModrm|Data32, { Imm16, 0, 0} }, -{"lretw", 0, 0xcb, _, NoModrm|Data16, { 0, 0, 0} }, -{"lretw", 1, 0xca, _, NoModrm|Data16, { Imm16, 0, 0} }, -{"enter", 2, 0xc8, _, NoModrm|Data32, { Imm16, Imm8, 0} }, -{"leave", 0, 0xc9, _, NoModrm|Data32, { 0, 0, 0} }, -{"enterw", 2, 0xc8, _, NoModrm|Data16, { Imm16, Imm8, 0} }, -{"leavew", 0, 0xc9, _, NoModrm|Data16, { 0, 0, 0} }, - -/* conditional jumps */ -{"jo", 1, 0x70, _, Jump, { Disp, 0, 0} }, - -{"jno", 1, 0x71, _, Jump, { Disp, 0, 0} }, - -{"jb", 1, 0x72, _, Jump, { Disp, 0, 0} }, -{"jc", 1, 0x72, _, Jump, { Disp, 0, 0} }, -{"jnae", 1, 0x72, _, Jump, { Disp, 0, 0} }, - -{"jnb", 1, 0x73, _, Jump, { Disp, 0, 0} }, -{"jnc", 1, 0x73, _, Jump, { Disp, 0, 0} }, -{"jae", 1, 0x73, _, Jump, { Disp, 0, 0} }, - -{"je", 1, 0x74, _, Jump, { Disp, 0, 0} }, -{"jz", 1, 0x74, _, Jump, { Disp, 0, 0} }, - -{"jne", 1, 0x75, _, Jump, { Disp, 0, 0} }, -{"jnz", 1, 0x75, _, Jump, { Disp, 0, 0} }, - -{"jbe", 1, 0x76, _, Jump, { Disp, 0, 0} }, -{"jna", 1, 0x76, _, Jump, { Disp, 0, 0} }, - -{"jnbe", 1, 0x77, _, Jump, { Disp, 0, 0} }, -{"ja", 1, 0x77, _, Jump, { Disp, 0, 0} }, - -{"js", 1, 0x78, _, Jump, { Disp, 0, 0} }, - -{"jns", 1, 0x79, _, Jump, { Disp, 0, 0} }, - -{"jp", 1, 0x7a, _, Jump, { Disp, 0, 0} }, -{"jpe", 1, 0x7a, _, Jump, { Disp, 0, 0} }, - -{"jnp", 1, 0x7b, _, Jump, { Disp, 0, 0} }, -{"jpo", 1, 0x7b, _, Jump, { Disp, 0, 0} }, - -{"jl", 1, 0x7c, _, Jump, { Disp, 0, 0} }, -{"jnge", 1, 0x7c, _, Jump, { Disp, 0, 0} }, - -{"jnl", 1, 0x7d, _, Jump, { Disp, 0, 0} }, -{"jge", 1, 0x7d, _, Jump, { Disp, 0, 0} }, - -{"jle", 1, 0x7e, _, Jump, { Disp, 0, 0} }, -{"jng", 1, 0x7e, _, Jump, { Disp, 0, 0} }, - -{"jnle", 1, 0x7f, _, Jump, { Disp, 0, 0} }, -{"jg", 1, 0x7f, _, Jump, { Disp, 0, 0} }, - -#if 0 /* XXX where are these macros used? - To get them working again, they need to take - an entire template as the parameter, - and check for Data16/Data32 flags. */ -/* these turn into pseudo operations when disp is larger than 8 bits */ -#define IS_JUMP_ON_CX_ZERO(o) \ - (o == 0x66e3) -#define IS_JUMP_ON_ECX_ZERO(o) \ - (o == 0xe3) -#endif - -{"jcxz", 1, 0xe3, _, JumpByte|Data16, { Disp, 0, 0} }, -{"jecxz", 1, 0xe3, _, JumpByte|Data32, { Disp, 0, 0} }, - -#define IS_LOOP_ECX_TIMES(o) \ - (o == 0xe2 || o == 0xe1 || o == 0xe0) - -{"loop", 1, 0xe2, _, JumpByte, { Disp, 0, 0} }, - -{"loopz", 1, 0xe1, _, JumpByte, { Disp, 0, 0} }, -{"loope", 1, 0xe1, _, JumpByte, { Disp, 0, 0} }, - -{"loopnz", 1, 0xe0, _, JumpByte, { Disp, 0, 0} }, -{"loopne", 1, 0xe0, _, JumpByte, { Disp, 0, 0} }, - -/* set byte on flag instructions */ -{"seto", 1, 0x0f90, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setno", 1, 0x0f91, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setb", 1, 0x0f92, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setc", 1, 0x0f92, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setnae", 1, 0x0f92, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setnb", 1, 0x0f93, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setnc", 1, 0x0f93, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setae", 1, 0x0f93, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"sete", 1, 0x0f94, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setz", 1, 0x0f94, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setne", 1, 0x0f95, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setnz", 1, 0x0f95, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setbe", 1, 0x0f96, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setna", 1, 0x0f96, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setnbe", 1, 0x0f97, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"seta", 1, 0x0f97, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"sets", 1, 0x0f98, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setns", 1, 0x0f99, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setp", 1, 0x0f9a, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setpe", 1, 0x0f9a, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setnp", 1, 0x0f9b, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setpo", 1, 0x0f9b, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setl", 1, 0x0f9c, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setnge", 1, 0x0f9c, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setnl", 1, 0x0f9d, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setge", 1, 0x0f9d, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setle", 1, 0x0f9e, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setng", 1, 0x0f9e, 0, Modrm, { Reg8|Mem, 0, 0} }, - -{"setnle", 1, 0x0f9f, 0, Modrm, { Reg8|Mem, 0, 0} }, -{"setg", 1, 0x0f9f, 0, Modrm, { Reg8|Mem, 0, 0} }, - -#define IS_STRING_INSTRUCTION(o) \ - ((o) == 0xa6 || (o) == 0x6c || (o) == 0x6e || (o) == 0x6e || \ - (o) == 0xac || (o) == 0xa4 || (o) == 0xae || (o) == 0xaa || \ - (o) == 0xd7) - -/* string manipulation */ -{"cmps", 0, 0xa6, _, W|NoModrm, { 0, 0, 0} }, -{"scmp", 0, 0xa6, _, W|NoModrm, { 0, 0, 0} }, -{"ins", 0, 0x6c, _, W|NoModrm, { 0, 0, 0} }, -{"outs", 0, 0x6e, _, W|NoModrm, { 0, 0, 0} }, -{"lods", 0, 0xac, _, W|NoModrm, { 0, 0, 0} }, -{"slod", 0, 0xac, _, W|NoModrm, { 0, 0, 0} }, -{"movs", 0, 0xa4, _, W|NoModrm, { 0, 0, 0} }, -{"smov", 0, 0xa4, _, W|NoModrm, { 0, 0, 0} }, -{"scas", 0, 0xae, _, W|NoModrm, { 0, 0, 0} }, -{"ssca", 0, 0xae, _, W|NoModrm, { 0, 0, 0} }, -{"stos", 0, 0xaa, _, W|NoModrm, { 0, 0, 0} }, -{"ssto", 0, 0xaa, _, W|NoModrm, { 0, 0, 0} }, -{"xlat", 0, 0xd7, _, NoModrm, { 0, 0, 0} }, - -/* bit manipulation */ -{"bsf", 2, 0x0fbc, _, Modrm|ReverseRegRegmem, { Reg|Mem, Reg, 0} }, -{"bsr", 2, 0x0fbd, _, Modrm|ReverseRegRegmem, { Reg|Mem, Reg, 0} }, -{"bt", 2, 0x0fa3, _, Modrm, { Reg, Reg|Mem, 0} }, -{"bt", 2, 0x0fba, 4, Modrm, { Imm8, Reg|Mem, 0} }, -{"btc", 2, 0x0fbb, _, Modrm, { Reg, Reg|Mem, 0} }, -{"btc", 2, 0x0fba, 7, Modrm, { Imm8, Reg|Mem, 0} }, -{"btr", 2, 0x0fb3, _, Modrm, { Reg, Reg|Mem, 0} }, -{"btr", 2, 0x0fba, 6, Modrm, { Imm8, Reg|Mem, 0} }, -{"bts", 2, 0x0fab, _, Modrm, { Reg, Reg|Mem, 0} }, -{"bts", 2, 0x0fba, 5, Modrm, { Imm8, Reg|Mem, 0} }, - -/* interrupts & op. sys insns */ -/* See gas/config/tc-i386.c for conversion of 'int $3' into the special - int 3 insn. */ -#define INT_OPCODE 0xcd -#define INT3_OPCODE 0xcc -{"int", 1, 0xcd, _, NoModrm, { Imm8, 0, 0} }, -{"int3", 0, 0xcc, _, NoModrm, { 0, 0, 0} }, -{"into", 0, 0xce, _, NoModrm, { 0, 0, 0} }, -{"iret", 0, 0xcf, _, NoModrm|Data32, { 0, 0, 0} }, -{"iretw", 0, 0xcf, _, NoModrm|Data16, { 0, 0, 0} }, -/* i386sl, i486sl, later 486, and Pentium */ -{"rsm", 0, 0x0faa, _, NoModrm,{ 0, 0, 0} }, - -{"boundl", 2, 0x62, _, Modrm|Data32, { Reg32, Mem, 0} }, -{"boundw", 2, 0x62, _, Modrm|Data16, { Reg16, Mem, 0} }, - -{"hlt", 0, 0xf4, _, NoModrm, { 0, 0, 0} }, -{"wait", 0, 0x9b, _, NoModrm, { 0, 0, 0} }, -/* nop is actually 'xchgl %eax, %eax' */ -{"nop", 0, 0x90, _, NoModrm, { 0, 0, 0} }, - -/* protection control */ -{"arpl", 2, 0x63, _, Modrm, { Reg16, Reg16|Mem, 0} }, -{"lar", 2, 0x0f02, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, -{"lgdt", 1, 0x0f01, 2, Modrm, { Mem, 0, 0} }, -{"lidt", 1, 0x0f01, 3, Modrm, { Mem, 0, 0} }, -{"lldt", 1, 0x0f00, 2, Modrm, { WordReg|Mem, 0, 0} }, -{"lmsw", 1, 0x0f01, 6, Modrm, { WordReg|Mem, 0, 0} }, -{"lsl", 2, 0x0f03, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, -{"ltr", 1, 0x0f00, 3, Modrm, { WordReg|Mem, 0, 0} }, - -{"sgdt", 1, 0x0f01, 0, Modrm, { Mem, 0, 0} }, -{"sidt", 1, 0x0f01, 1, Modrm, { Mem, 0, 0} }, -{"sldt", 1, 0x0f00, 0, Modrm, { WordReg|Mem, 0, 0} }, -{"smsw", 1, 0x0f01, 4, Modrm, { WordReg|Mem, 0, 0} }, -{"str", 1, 0x0f00, 1, Modrm, { Reg16|Mem, 0, 0} }, - -{"verr", 1, 0x0f00, 4, Modrm, { WordReg|Mem, 0, 0} }, -{"verw", 1, 0x0f00, 5, Modrm, { WordReg|Mem, 0, 0} }, - -/* floating point instructions */ - -/* load */ -{"fld", 1, 0xd9c0, _, ShortForm, { FloatReg, 0, 0} }, /* register */ -{"flds", 1, 0xd9, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem float */ -{"fldl", 1, 0xdd, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem double */ -{"fldl", 1, 0xd9c0, _, ShortForm, { FloatReg, 0, 0} }, /* register */ -{"fild", 1, 0xdf, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem word (16) */ -{"fildl", 1, 0xdb, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem dword (32) */ -{"fildq",1, 0xdf, 5, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem qword (64) */ -{"fildll",1, 0xdf, 5, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem qword (64) */ -{"fldt", 1, 0xdb, 5, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem efloat */ -{"fbld", 1, 0xdf, 4, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem bcd */ - -/* store (no pop) */ -{"fst", 1, 0xddd0, _, ShortForm, { FloatReg, 0, 0} }, /* register */ -{"fsts", 1, 0xd9, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem float */ -{"fstl", 1, 0xdd, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem double */ -{"fstl", 1, 0xddd0, _, ShortForm, { FloatReg, 0, 0} }, /* register */ -{"fist", 1, 0xdf, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem word (16) */ -{"fistl", 1, 0xdb, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem dword (32) */ - -/* store (with pop) */ -{"fstp", 1, 0xddd8, _, ShortForm, { FloatReg, 0, 0} }, /* register */ -{"fstps", 1, 0xd9, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem float */ -{"fstpl", 1, 0xdd, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem double */ -{"fstpl", 1, 0xddd8, _, ShortForm, { FloatReg, 0, 0} }, /* register */ -{"fistp", 1, 0xdf, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem word (16) */ -{"fistpl",1, 0xdb, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem dword (32) */ -{"fistpq",1, 0xdf, 7, Modrm, { Mem, 0, 0} }, /* %st0 --> mem qword (64) */ -{"fistpll",1,0xdf, 7, Modrm, { Mem, 0, 0} }, /* %st0 --> mem qword (64) */ -{"fstpt", 1, 0xdb, 7, Modrm, { Mem, 0, 0} }, /* %st0 --> mem efloat */ -{"fbstp", 1, 0xdf, 6, Modrm, { Mem, 0, 0} }, /* %st0 --> mem bcd */ - -/* exchange %st with %st0 */ -{"fxch", 1, 0xd9c8, _, ShortForm, { FloatReg, 0, 0} }, -{"fxch", 0, 0xd9c9, _, NoModrm, { 0, 0, 0} }, /* alias for fxch %st, %st(1) */ - -/* comparison (without pop) */ -{"fcom", 1, 0xd8d0, _, ShortForm, { FloatReg, 0, 0} }, -{"fcoms", 1, 0xd8, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem float */ -{"ficoml", 1, 0xda, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem word */ -{"fcoml", 1, 0xdc, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem double */ -{"fcoml", 1, 0xd8d0, _, ShortForm, { FloatReg, 0, 0} }, -{"ficoms", 1, 0xde, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem dword */ - -/* comparison (with pop) */ -{"fcomp", 1, 0xd8d8, _, ShortForm, { FloatReg, 0, 0} }, -{"fcomps", 1, 0xd8, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem float */ -{"ficompl", 1, 0xda, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem word */ -{"fcompl", 1, 0xdc, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem double */ -{"fcompl", 1, 0xd8d8, _, ShortForm, { FloatReg, 0, 0} }, -{"ficomps", 1, 0xde, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem dword */ -{"fcompp", 0, 0xded9, _, NoModrm, { 0, 0, 0} }, /* compare %st0, %st1 & pop 2 */ - -/* unordered comparison (with pop) */ -{"fucom", 1, 0xdde0, _, ShortForm, { FloatReg, 0, 0} }, -{"fucomp", 1, 0xdde8, _, ShortForm, { FloatReg, 0, 0} }, -{"fucompp", 0, 0xdae9, _, NoModrm, { 0, 0, 0} }, /* ucompare %st0, %st1 & pop twice */ - -{"ftst", 0, 0xd9e4, _, NoModrm, { 0, 0, 0} }, /* test %st0 */ -{"fxam", 0, 0xd9e5, _, NoModrm, { 0, 0, 0} }, /* examine %st0 */ - -/* load constants into %st0 */ -{"fld1", 0, 0xd9e8, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- 1.0 */ -{"fldl2t", 0, 0xd9e9, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- log2(10) */ -{"fldl2e", 0, 0xd9ea, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- log2(e) */ -{"fldpi", 0, 0xd9eb, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- pi */ -{"fldlg2", 0, 0xd9ec, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- log10(2) */ -{"fldln2", 0, 0xd9ed, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- ln(2) */ -{"fldz", 0, 0xd9ee, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- 0.0 */ - -/* arithmetic */ - -/* add */ -{"fadd", 1, 0xd8c0, _, ShortForm, { FloatReg, 0, 0} }, -{"fadd", 2, 0xd8c0, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} }, -{"fadd", 0, 0xdcc1, _, NoModrm, { 0, 0, 0} }, /* alias for fadd %st, %st(1) */ -{"faddp", 1, 0xdac0, _, ShortForm, { FloatReg, 0, 0} }, -{"faddp", 2, 0xdac0, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} }, -{"faddp", 0, 0xdec1, _, NoModrm, { 0, 0, 0} }, /* alias for faddp %st, %st(1) */ -{"fadds", 1, 0xd8, 0, Modrm, { Mem, 0, 0} }, -{"fiaddl", 1, 0xda, 0, Modrm, { Mem, 0, 0} }, -{"faddl", 1, 0xdc, 0, Modrm, { Mem, 0, 0} }, -{"fiadds", 1, 0xde, 0, Modrm, { Mem, 0, 0} }, - -/* sub */ -/* Note: intel has decided that certain of these operations are reversed - in assembler syntax. */ -{"fsub", 1, 0xd8e0, _, ShortForm, { FloatReg, 0, 0} }, -{"fsub", 2, 0xd8e0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fsub", 2, 0xdce8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fsub", 2, 0xdce0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fsub", 0, 0xdce1, _, NoModrm, { 0, 0, 0} }, -{"fsubp", 1, 0xdae0, _, ShortForm, { FloatReg, 0, 0} }, -{"fsubp", 2, 0xdae0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fsubp", 2, 0xdee8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fsubp", 2, 0xdee0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fsubp", 0, 0xdee1, _, NoModrm, { 0, 0, 0} }, -{"fsubs", 1, 0xd8, 4, Modrm, { Mem, 0, 0} }, -{"fisubl", 1, 0xda, 4, Modrm, { Mem, 0, 0} }, -{"fsubl", 1, 0xdc, 4, Modrm, { Mem, 0, 0} }, -{"fisubs", 1, 0xde, 4, Modrm, { Mem, 0, 0} }, - -/* sub reverse */ -{"fsubr", 1, 0xd8e8, _, ShortForm, { FloatReg, 0, 0} }, -{"fsubr", 2, 0xd8e8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fsubr", 2, 0xdce0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fsubr", 2, 0xdce8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fsubr", 0, 0xdce9, _, NoModrm, { 0, 0, 0} }, -{"fsubrp", 1, 0xdae8, _, ShortForm, { FloatReg, 0, 0} }, -{"fsubrp", 2, 0xdae8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fsubrp", 2, 0xdee0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fsubrp", 2, 0xdee8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fsubrp", 0, 0xdee9, _, NoModrm, { 0, 0, 0} }, -{"fsubrs", 1, 0xd8, 5, Modrm, { Mem, 0, 0} }, -{"fisubrl", 1, 0xda, 5, Modrm, { Mem, 0, 0} }, -{"fsubrl", 1, 0xdc, 5, Modrm, { Mem, 0, 0} }, -{"fisubrs", 1, 0xde, 5, Modrm, { Mem, 0, 0} }, - -/* mul */ -{"fmul", 1, 0xd8c8, _, ShortForm, { FloatReg, 0, 0} }, -{"fmul", 2, 0xd8c8, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} }, -{"fmul", 0, 0xdcc9, _, NoModrm, { 0, 0, 0} }, -{"fmulp", 1, 0xdac8, _, ShortForm, { FloatReg, 0, 0} }, -{"fmulp", 2, 0xdac8, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} }, -{"fmulp", 0, 0xdec9, _, NoModrm, { 0, 0, 0} }, -{"fmuls", 1, 0xd8, 1, Modrm, { Mem, 0, 0} }, -{"fimull", 1, 0xda, 1, Modrm, { Mem, 0, 0} }, -{"fmull", 1, 0xdc, 1, Modrm, { Mem, 0, 0} }, -{"fimuls", 1, 0xde, 1, Modrm, { Mem, 0, 0} }, - -/* div */ -/* Note: intel has decided that certain of these operations are reversed - in assembler syntax. */ -{"fdiv", 1, 0xd8f0, _, ShortForm, { FloatReg, 0, 0} }, -{"fdiv", 2, 0xd8f0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fdiv", 2, 0xdcf8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fdiv", 2, 0xdcf0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fdiv", 0, 0xdcf1, _, NoModrm, { 0, 0, 0} }, -{"fdivp", 1, 0xdaf0, _, ShortForm, { FloatReg, 0, 0} }, -{"fdivp", 2, 0xdaf0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fdivp", 2, 0xdef8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fdivp", 2, 0xdef0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fdivp", 0, 0xdef1, _, NoModrm, { 0, 0, 0} }, -{"fdivs", 1, 0xd8, 6, Modrm, { Mem, 0, 0} }, -{"fidivl", 1, 0xda, 6, Modrm, { Mem, 0, 0} }, -{"fdivl", 1, 0xdc, 6, Modrm, { Mem, 0, 0} }, -{"fidivs", 1, 0xde, 6, Modrm, { Mem, 0, 0} }, - -/* div reverse */ -{"fdivr", 1, 0xd8f8, _, ShortForm, { FloatReg, 0, 0} }, -{"fdivr", 2, 0xd8f8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fdivr", 2, 0xdcf0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fdivr", 2, 0xdcf8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fdivr", 0, 0xdcf9, _, NoModrm, { 0, 0, 0} }, -{"fdivrp", 1, 0xdaf8, _, ShortForm, { FloatReg, 0, 0} }, -{"fdivrp", 2, 0xdaf8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -#ifdef NON_BROKEN_OPCODES -{"fdivrp", 2, 0xdef0, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#else -{"fdivrp", 2, 0xdef8, _, ShortForm, { FloatAcc, FloatReg, 0} }, -#endif -{"fdivrp", 0, 0xdef9, _, NoModrm, { 0, 0, 0} }, -{"fdivrs", 1, 0xd8, 7, Modrm, { Mem, 0, 0} }, -{"fidivrl", 1, 0xda, 7, Modrm, { Mem, 0, 0} }, -{"fdivrl", 1, 0xdc, 7, Modrm, { Mem, 0, 0} }, -{"fidivrs", 1, 0xde, 7, Modrm, { Mem, 0, 0} }, - -{"f2xm1", 0, 0xd9f0, _, NoModrm, { 0, 0, 0} }, -{"fyl2x", 0, 0xd9f1, _, NoModrm, { 0, 0, 0} }, -{"fptan", 0, 0xd9f2, _, NoModrm, { 0, 0, 0} }, -{"fpatan", 0, 0xd9f3, _, NoModrm, { 0, 0, 0} }, -{"fxtract", 0, 0xd9f4, _, NoModrm, { 0, 0, 0} }, -{"fprem1", 0, 0xd9f5, _, NoModrm, { 0, 0, 0} }, -{"fdecstp", 0, 0xd9f6, _, NoModrm, { 0, 0, 0} }, -{"fincstp", 0, 0xd9f7, _, NoModrm, { 0, 0, 0} }, -{"fprem", 0, 0xd9f8, _, NoModrm, { 0, 0, 0} }, -{"fyl2xp1", 0, 0xd9f9, _, NoModrm, { 0, 0, 0} }, -{"fsqrt", 0, 0xd9fa, _, NoModrm, { 0, 0, 0} }, -{"fsincos", 0, 0xd9fb, _, NoModrm, { 0, 0, 0} }, -{"frndint", 0, 0xd9fc, _, NoModrm, { 0, 0, 0} }, -{"fscale", 0, 0xd9fd, _, NoModrm, { 0, 0, 0} }, -{"fsin", 0, 0xd9fe, _, NoModrm, { 0, 0, 0} }, -{"fcos", 0, 0xd9ff, _, NoModrm, { 0, 0, 0} }, - -{"fchs", 0, 0xd9e0, _, NoModrm, { 0, 0, 0} }, -{"fabs", 0, 0xd9e1, _, NoModrm, { 0, 0, 0} }, - -/* processor control */ -{"fninit", 0, 0xdbe3, _, NoModrm, { 0, 0, 0} }, -{"finit", 0, 0x9bdbe3, _, NoModrm, { 0, 0, 0} }, -{"fldcw", 1, 0xd9, 5, Modrm, { Mem, 0, 0} }, -{"fnstcw", 1, 0xd9, 7, Modrm, { Mem, 0, 0} }, -{"fstcw", 1, 0x9bd9, 7, Modrm, { Mem, 0, 0} }, -{"fnstsw", 1, 0xdfe0, _, NoModrm, { Acc, 0, 0} }, -{"fnstsw", 1, 0xdd, 7, Modrm, { Mem, 0, 0} }, -{"fnstsw", 0, 0xdfe0, _, NoModrm, { 0, 0, 0} }, -{"fstsw", 1, 0x9bdfe0, _, NoModrm, { Acc, 0, 0} }, -{"fstsw", 1, 0x9bdd, 7, Modrm, { Mem, 0, 0} }, -{"fstsw", 0, 0x9bdfe0, _, NoModrm, { 0, 0, 0} }, -{"fnclex", 0, 0xdbe2, _, NoModrm, { 0, 0, 0} }, -{"fclex", 0, 0x9bdbe2, _, NoModrm, { 0, 0, 0} }, -/* - We ignore the short format (287) versions of fstenv/fldenv & fsave/frstor - instructions; i'm not sure how to add them or how they are different. - My 386/387 book offers no details about this. -*/ -{"fnstenv", 1, 0xd9, 6, Modrm, { Mem, 0, 0} }, -{"fstenv", 1, 0x9bd9, 6, Modrm, { Mem, 0, 0} }, -{"fldenv", 1, 0xd9, 4, Modrm, { Mem, 0, 0} }, -{"fnsave", 1, 0xdd, 6, Modrm, { Mem, 0, 0} }, -{"fsave", 1, 0x9bdd, 6, Modrm, { Mem, 0, 0} }, -{"frstor", 1, 0xdd, 4, Modrm, { Mem, 0, 0} }, - -{"ffree", 1, 0xddc0, _, ShortForm, { FloatReg, 0, 0} }, -{"fnop", 0, 0xd9d0, _, NoModrm, { 0, 0, 0} }, -{"fwait", 0, 0x9b, _, NoModrm, { 0, 0, 0} }, - -/* - opcode prefixes; we allow them as seperate insns too - (see prefix table below) -*/ -{"aword", 0, 0x67, _, NoModrm, { 0, 0, 0} }, -{"addr16", 0, 0x67, _, NoModrm, { 0, 0, 0} }, -{"word", 0, 0x66, _, NoModrm, { 0, 0, 0} }, -{"data16", 0, 0x66, _, NoModrm, { 0, 0, 0} }, -{"lock", 0, 0xf0, _, NoModrm, { 0, 0, 0} }, -{"cs", 0, 0x2e, _, NoModrm, { 0, 0, 0} }, -{"ds", 0, 0x3e, _, NoModrm, { 0, 0, 0} }, -{"es", 0, 0x26, _, NoModrm, { 0, 0, 0} }, -{"fs", 0, 0x64, _, NoModrm, { 0, 0, 0} }, -{"gs", 0, 0x65, _, NoModrm, { 0, 0, 0} }, -{"ss", 0, 0x36, _, NoModrm, { 0, 0, 0} }, -{"rep", 0, 0xf3, _, NoModrm, { 0, 0, 0} }, -{"repe", 0, 0xf3, _, NoModrm, { 0, 0, 0} }, -{"repz", 0, 0xf3, _, NoModrm, { 0, 0, 0} }, -{"repne", 0, 0xf2, _, NoModrm, { 0, 0, 0} }, -{"repnz", 0, 0xf2, _, NoModrm, { 0, 0, 0} }, - -/* 486 extensions */ - -{"bswap", 1, 0x0fc8, _, ShortForm, { Reg32,0,0 } }, -{"xadd", 2, 0x0fc0, _, DW|Modrm, { Reg, Reg|Mem, 0 } }, -{"cmpxchg", 2, 0x0fb0, _, DW|Modrm, { Reg, Reg|Mem, 0 } }, -{"invd", 0, 0x0f08, _, NoModrm, { 0, 0, 0} }, -{"wbinvd", 0, 0x0f09, _, NoModrm, { 0, 0, 0} }, -{"invlpg", 1, 0x0f01, 7, Modrm, { Mem, 0, 0} }, - -/* 586 and late 486 extensions */ -{"cpuid", 0, 0x0fa2, _, NoModrm, { 0, 0, 0} }, - -/* Pentium extensions */ -{"wrmsr", 0, 0x0f30, _, NoModrm, { 0, 0, 0} }, -{"rdtsc", 0, 0x0f31, _, NoModrm, { 0, 0, 0} }, -{"rdmsr", 0, 0x0f32, _, NoModrm, { 0, 0, 0} }, -{"cmpxchg8b", 1, 0x0fc7, 1, Modrm, { Mem, 0, 0} }, - -/* Pentium Pro extensions */ -{"rdpmc", 0, 0x0f33, _, NoModrm, { 0, 0, 0} }, - -{"cmovo", 2, 0x0f40, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovno", 2, 0x0f41, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovb", 2, 0x0f42, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovae", 2, 0x0f43, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmove", 2, 0x0f44, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovne", 2, 0x0f45, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovbe", 2, 0x0f46, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmova", 2, 0x0f47, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovs", 2, 0x0f48, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovns", 2, 0x0f49, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovp", 2, 0x0f4a, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovnp", 2, 0x0f4b, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovl", 2, 0x0f4c, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovge", 2, 0x0f4d, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovle", 2, 0x0f4e, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, -{"cmovg", 2, 0x0f4f, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} }, - -{"fcmovb", 2, 0xdac0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcmove", 2, 0xdac8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcmovbe",2, 0xdad0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcmovu", 2, 0xdad8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcmovnb", 2, 0xdbc0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcmovne", 2, 0xdbc8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcmovnbe",2, 0xdbd0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcmovnu", 2, 0xdbd8, _, ShortForm, { FloatReg, FloatAcc, 0} }, - -{"fcomi", 2, 0xdbf0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fucomi", 2, 0xdbe8, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fcomip", 2, 0xdff0, _, ShortForm, { FloatReg, FloatAcc, 0} }, -{"fucomip",2, 0xdfe8, _, ShortForm, { FloatReg, FloatAcc, 0} }, - -{"", 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */ -}; -#undef _ - -static const template *const i386_optab_end - = i386_optab + sizeof (i386_optab)/sizeof(i386_optab[0]); - -/* 386 register table */ - -static const reg_entry i386_regtab[] = { - /* 8 bit regs */ - {"al", Reg8|Acc, 0}, {"cl", Reg8|ShiftCount, 1}, {"dl", Reg8, 2}, - {"bl", Reg8, 3}, - {"ah", Reg8, 4}, {"ch", Reg8, 5}, {"dh", Reg8, 6}, {"bh", Reg8, 7}, - /* 16 bit regs */ - {"ax", Reg16|Acc, 0}, {"cx", Reg16, 1}, {"dx", Reg16|InOutPortReg, 2}, {"bx", Reg16, 3}, - {"sp", Reg16, 4}, {"bp", Reg16, 5}, {"si", Reg16, 6}, {"di", Reg16, 7}, - /* 32 bit regs */ - {"eax", Reg32|Acc, 0}, {"ecx", Reg32, 1}, {"edx", Reg32, 2}, {"ebx", Reg32, 3}, - {"esp", Reg32, 4}, {"ebp", Reg32, 5}, {"esi", Reg32, 6}, {"edi", Reg32, 7}, - /* segment registers */ - {"es", SReg2, 0}, {"cs", SReg2, 1}, {"ss", SReg2, 2}, - {"ds", SReg2, 3}, {"fs", SReg3, 4}, {"gs", SReg3, 5}, - /* control registers */ - {"cr0", Control, 0}, {"cr2", Control, 2}, {"cr3", Control, 3}, - {"cr4", Control, 4}, - /* debug registers */ - {"db0", Debug, 0}, {"db1", Debug, 1}, {"db2", Debug, 2}, - {"db3", Debug, 3}, {"db6", Debug, 6}, {"db7", Debug, 7}, - {"dr0", Debug, 0}, {"dr1", Debug, 1}, {"dr2", Debug, 2}, - {"dr3", Debug, 3}, {"dr6", Debug, 6}, {"dr7", Debug, 7}, - /* test registers */ - {"tr3", Test, 3}, {"tr4", Test, 4}, {"tr5", Test, 5}, - {"tr6", Test, 6}, {"tr7", Test, 7}, - /* float registers */ - {"st(0)", FloatReg|FloatAcc, 0}, - {"st", FloatReg|FloatAcc, 0}, - {"st(1)", FloatReg, 1}, {"st(2)", FloatReg, 2}, - {"st(3)", FloatReg, 3}, {"st(4)", FloatReg, 4}, {"st(5)", FloatReg, 5}, - {"st(6)", FloatReg, 6}, {"st(7)", FloatReg, 7} -}; - -#define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */ - -static const reg_entry *const i386_regtab_end - = i386_regtab + sizeof(i386_regtab)/sizeof(i386_regtab[0]); - -/* segment stuff */ -static const seg_entry cs = { "cs", 0x2e }; -static const seg_entry ds = { "ds", 0x3e }; -static const seg_entry ss = { "ss", 0x36 }; -static const seg_entry es = { "es", 0x26 }; -static const seg_entry fs = { "fs", 0x64 }; -static const seg_entry gs = { "gs", 0x65 }; -static const seg_entry null = { "", 0x0 }; - -/* - This table is used to store the default segment register implied by all - possible memory addressing modes. - It is indexed by the mode & modrm entries of the modrm byte as follows: - index = (mode<<3) | modrm; -*/ -static const seg_entry *const one_byte_segment_defaults[] = { - /* mode 0 */ - &ds, &ds, &ds, &ds, &null, &ds, &ds, &ds, - /* mode 1 */ - &ds, &ds, &ds, &ds, &null, &ss, &ds, &ds, - /* mode 2 */ - &ds, &ds, &ds, &ds, &null, &ss, &ds, &ds, - /* mode 3 --- not a memory reference; never referenced */ -}; - -static const seg_entry *const two_byte_segment_defaults[] = { - /* mode 0 */ - &ds, &ds, &ds, &ds, &ss, &ds, &ds, &ds, - /* mode 1 */ - &ds, &ds, &ds, &ds, &ss, &ds, &ds, &ds, - /* mode 2 */ - &ds, &ds, &ds, &ds, &ss, &ds, &ds, &ds, - /* mode 3 --- not a memory reference; never referenced */ -}; - -static const prefix_entry i386_prefixtab[] = { -#define ADDR_PREFIX_OPCODE 0x67 - { "addr16", 0x67 }, /* address size prefix ==> 16bit addressing - * (How is this useful?) */ -#define WORD_PREFIX_OPCODE 0x66 - { "data16", 0x66 }, /* operand size prefix */ - { "lock", 0xf0 }, /* bus lock prefix */ - { "wait", 0x9b }, /* wait for coprocessor */ - { "cs", 0x2e }, { "ds", 0x3e }, /* segment overrides ... */ - { "es", 0x26 }, { "fs", 0x64 }, - { "gs", 0x65 }, { "ss", 0x36 }, -/* REPE & REPNE used to detect rep/repne with a non-string instruction */ -#define REPNE 0xf2 -#define REPE 0xf3 - { "rep", 0xf3 }, /* repeat string instructions */ - { "repe", 0xf3 }, { "repz", 0xf3 }, - { "repne", 0xf2 }, { "repnz", 0xf2 } -}; - -static const prefix_entry *const i386_prefixtab_end - = i386_prefixtab + sizeof(i386_prefixtab)/sizeof(i386_prefixtab[0]); - -/* end of i386-opcode.h */ diff --git a/contrib/gdb/include/opcode/i860.h b/contrib/gdb/include/opcode/i860.h deleted file mode 100644 index b6ebd25c648..00000000000 --- a/contrib/gdb/include/opcode/i860.h +++ /dev/null @@ -1,491 +0,0 @@ -/* Table of opcodes for the i860. - Copyright (C) 1989 Free Software Foundation, Inc. - -This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler. - -GAS/GDB is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GAS/GDB is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GAS or GDB; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if !defined(__STDC__) && !defined(const) -#define const -#endif - -/* - * Structure of an opcode table entry. - */ -struct i860_opcode -{ - const char *name; - unsigned long match; /* Bits that must be set. */ - unsigned long lose; /* Bits that must not be set. */ - const char *args; - /* Nonzero if this is a possible expand-instruction. */ - char expand; -}; - -enum expand_type -{ - E_MOV = 1, E_ADDR, E_U32, E_AND, E_S32, E_DELAY -}; - -/* - All i860 opcodes are 32 bits, except for the pseudoinstructions - and the operations utilizing a 32-bit address expression, an - unsigned 32-bit constant, or a signed 32-bit constant. - These opcodes are expanded into a two-instruction sequence for - any situation where the immediate operand does not fit in 32 bits. - In the case of the add and subtract operations the expansion is - to a three-instruction sequence (ex: orh, or, adds). In cases - where the address is to be relocated, the instruction is - expanded to handle the worse case, this could be optimized at - the final link if the actual address were known. - - The pseudoinstructions are: mov, fmov, pmov, nop, and fnop. - These instructions are implemented as a one or two instruction - sequence of other operations. - - The match component is a mask saying which bits must match a - particular opcode in order for an instruction to be an instance - of that opcode. - - The args component is a string containing one character - for each operand of the instruction. - -Kinds of operands: - # Number used by optimizer. It is ignored. - 1 src1 integer register. - 2 src2 integer register. - d dest register. - c ctrlreg control register. - i 16 bit immediate. - I 16 bit immediate, aligned. - 5 5 bit immediate. - l lbroff 26 bit PC relative immediate. - r sbroff 16 bit PC relative immediate. - s split 16 bit immediate. - S split 16 bit immediate, aligned. - e src1 floating point register. - f src2 floating point register. - g dest floating point register. - -*/ - -/* The order of the opcodes in this table is significant: - - * The assembler requires that all instances of the same mnemonic must be - consecutive. If they aren't, the assembler will bomb at runtime. - - * The disassembler should not care about the order of the opcodes. */ - -static struct i860_opcode i860_opcodes[] = -{ - -/* REG-Format Instructions */ -{ "ld.c", 0x30000000, 0xcc000000, "c,d", 0 }, /* ld.c csrc2,idest */ -{ "ld.b", 0x00000000, 0xfc000000, "1(2),d", 0 }, /* ld.b isrc1(isrc2),idest */ -{ "ld.b", 0x04000000, 0xf8000000, "I(2),d", E_ADDR }, /* ld.b #const(isrc2),idest */ -{ "ld.s", 0x10000000, 0xec000001, "1(2),d", 0 }, /* ld.s isrc1(isrc2),idest */ -{ "ld.s", 0x14000001, 0xe8000000, "I(2),d", E_ADDR }, /* ld.s #const(isrc2),idest */ -{ "ld.l", 0x10000001, 0xec000000, "1(2),d", 0 }, /* ld.l isrc1(isrc2),idest */ -{ "ld.l", 0x14000001, 0xe8000000, "I(2),d", E_ADDR }, /* ld.l #const(isrc2),idest */ - -{ "st.c", 0x38000000, 0xc4000000, "1,c", 0 }, /* st.c isrc1ni,csrc2 */ -{ "st.b", 0x0c000000, 0xf0000000, "1,S(2)", E_ADDR }, /* st.b isrc1ni,#const(isrc2) */ -{ "st.s", 0x1c000000, 0xe0000000, "1,S(2)", E_ADDR }, /* st.s isrc1ni,#const(isrc2) */ -{ "st.l", 0x1c000001, 0xe0000000, "1,S(2)", E_ADDR }, /* st.l isrc1ni,#const(isrc2) */ - -{ "ixfr", 0x08000000, 0xf4000000, "1,g", 0 }, /* ixfr isrc1ni,fdest */ - -{ "fld.l", 0x20000002, 0xdc000001, "1(2),g", 0 }, /* fld.l isrc1(isrc2),fdest */ -{ "fld.l", 0x24000002, 0xd8000001, "i(2),g", E_ADDR }, /* fld.l #const(isrc2),fdest */ -{ "fld.l", 0x20000003, 0xdc000000, "1(2)++,g", 0 }, /* fld.l isrc1(isrc2)++,fdest */ -{ "fld.l", 0x24000003, 0xd8000000, "i(2)++,g", E_ADDR }, /* fld.l #const(isrc2)++,fdest */ -{ "fld.d", 0x20000000, 0xdc000007, "1(2),g", 0 }, /* fld.d isrc1(isrc2),fdest */ -{ "fld.d", 0x24000000, 0xd8000007, "i(2),g", E_ADDR }, /* fld.d #const(isrc2),fdest */ -{ "fld.d", 0x20000001, 0xdc000006, "1(2)++,g", 0 }, /* fld.d isrc1(isrc2)++,fdest */ -{ "fld.d", 0x24000001, 0xd8000006, "i(2)++,g", E_ADDR }, /* fld.d #const(isrc2)++,fdest */ -{ "fld.q", 0x20000004, 0xdc000003, "1(2),g", 0 }, /* fld.q isrc1(isrc2),fdest */ -{ "fld.q", 0x24000004, 0xd8000003, "i(2),g", E_ADDR }, /* fld.q #const(isrc2),fdest */ -{ "fld.q", 0x20000005, 0xdc000002, "1(2)++,g", 0 }, /* fld.q isrc1(isrc2)++,fdest */ -{ "fld.q", 0x24000005, 0xd8000002, "i(2)++,g", E_ADDR }, /* fld.q #const(isrc2)++,fdest */ - -{ "pfld.l", 0x60000000, 0x9c000003, "1(2),g", 0 }, /* pfld.l isrc1(isrc2),fdest */ -{ "pfld.l", 0x64000000, 0x98000003, "i(2),g", E_ADDR }, /* pfld.l #const(isrc2),fdest */ -{ "pfld.l", 0x60000001, 0x9c000002, "1(2)++,g", 0 }, /* pfld.l isrc1(isrc2)++,fdest */ -{ "pfld.l", 0x64000001, 0x98000002, "i(2)++,g", E_ADDR }, /* pfld.l #const(isrc2)++,fdest */ -{ "pfld.d", 0x60000000, 0x9c000007, "1(2),g", 0 }, /* pfld.d isrc1(isrc2),fdest */ -{ "pfld.d", 0x64000000, 0x98000007, "i(2),g", E_ADDR }, /* pfld.d #const(isrc2),fdest */ -{ "pfld.d", 0x60000001, 0x9c000006, "1(2)++,g", 0 }, /* pfld.d isrc1(isrc2)++,fdest */ -{ "pfld.d", 0x64000001, 0x98000006, "i(2)++,g", E_ADDR }, /* pfld.d #const(isrc2)++,fdest */ - -{ "fst.l", 0x28000002, 0xd4000001, "g,1(2)", 0 }, /* fst.l fdest,isrc1(isrc2) */ -{ "fst.l", 0x2c000002, 0xd0000001, "g,i(2)", E_ADDR }, /* fst.l fdest,#const(isrc2) */ -{ "fst.l", 0x28000003, 0xd4000000, "g,1(2)++", 0 }, /* fst.l fdest,isrc1(isrc2)++ */ -{ "fst.l", 0x2c000003, 0xd0000000, "g,i(2)++", E_ADDR }, /* fst.l fdest,#const(isrc2)++ */ -{ "fst.d", 0x28000000, 0xd4000007, "g,1(2)", 0 }, /* fst.d fdest,isrc1(isrc2) */ -{ "fst.d", 0x2c000000, 0xd0000007, "g,i(2)", E_ADDR }, /* fst.d fdest,#const(isrc2) */ -{ "fst.d", 0x28000001, 0xd4000006, "g,1(2)++", 0 }, /* fst.d fdest,isrc1(isrc2)++ */ -{ "fst.d", 0x2c000001, 0xd0000006, "g,i(2)++", E_ADDR }, /* fst.d fdest,#const(isrc2)++ */ - -{ "pst.d", 0x3c000000, 0xc0000007, "g,i(2)", E_ADDR }, /* pst.d fdest,#const(isrc2) */ -{ "pst.d", 0x3c000001, 0xc0000006, "g,i(2)++", E_ADDR }, /* pst.d fdest,#const(isrc2)++ */ - -{ "addu", 0x80000000, 0x7c000000, "1,2,d", 0 }, /* addu isrc1,isrc2,idest */ -{ "addu", 0x84000000, 0x78000000, "i,2,d", E_S32 }, /* addu #const,isrc2,idest */ -{ "adds", 0x90000000, 0x6c000000, "1,2,d", 0 }, /* adds isrc1,isrc2,idest */ -{ "adds", 0x94000000, 0x68000000, "i,2,d", E_S32 }, /* adds #const,isrc2,idest */ -{ "subu", 0x88000000, 0x74000000, "1,2,d", 0 }, /* subu isrc1,isrc2,idest */ -{ "subu", 0x8c000000, 0x70000000, "i,2,d", E_S32 }, /* subu #const,isrc2,idest */ -{ "subs", 0x98000000, 0x64000000, "1,2,d", 0 }, /* subs isrc1,isrc2,idest */ -{ "subs", 0x9c000000, 0x60000000, "i,2,d", E_S32 }, /* subs #const,isrc2,idest */ - -{ "shl", 0xa0000000, 0x5c000000, "1,2,d", 0 }, /* shl isrc1,isrc2,idest */ -{ "shl", 0xa4000000, 0x58000000, "i,2,d", 0 }, /* shl #const,isrc2,idest */ -{ "shr", 0xa8000000, 0x54000000, "1,2,d", 0 }, /* shr isrc1,isrc2,idest */ -{ "shr", 0xac000000, 0x50000000, "i,2,d", 0 }, /* shr #const,isrc2,idest */ -{ "shrd", 0xb0000000, 0x4c000000, "1,2,d", 0 }, /* shrd isrc1,isrc2,idest */ -{ "shra", 0xb8000000, 0x44000000, "1,2,d", 0 }, /* shra isrc1,isrc2,idest */ -{ "shra", 0xbc000000, 0x40000000, "i,2,d", 0 }, /* shra #const,isrc2,idest */ - -{ "mov", 0xa0000000, 0x5c00f800, "2,d", 0 }, /* shl r0,isrc2,idest */ -{ "mov", 0x94000000, 0x69e00000, "i,d", E_MOV }, /* adds #const,r0,idest */ -{ "nop", 0xa0000000, 0x5ffff800, "", 0 }, /* shl r0,r0,r0 */ -{ "fnop", 0xb0000000, 0x4ffff800, "", 0 }, /* shrd r0,r0,r0 */ - -{ "trap", 0x44000000, 0xb8000000, "1,2,d", 0 }, /* trap isrc1ni,isrc2,idest */ - -{ "flush", 0x34000000, 0xc81f0001, "i(2)", E_ADDR }, /* flush #const(isrc2) */ -{ "flush", 0x34000001, 0xc81f0000, "i(2)++", E_ADDR }, /* flush #const(isrc2)++ */ - -{ "and", 0xc0000000, 0x3c000000, "1,2,d", 0 }, /* and isrc1,isrc2,idest */ -{ "and", 0xc4000000, 0x38000000, "i,2,d", E_AND }, /* and #const,isrc2,idest */ -{ "andh", 0xc8000000, 0x34000000, "1,2,d", 0 }, /* andh isrc1,isrc2,idest */ -{ "andh", 0xcc000000, 0x30000000, "i,2,d", 0 }, /* andh #const,isrc2,idest */ -{ "andnot", 0xd0000000, 0x2c000000, "1,2,d", 0 }, /* andnot isrc1,isrc2,idest */ -{ "andnot", 0xd4000000, 0x28000000, "i,2,d", E_U32 }, /* andnot #const,isrc2,idest */ -{ "andnoth", 0xd8000000, 0x24000000, "1,2,d", 0 }, /* andnoth isrc1,isrc2,idest */ -{ "andnoth", 0xdc000000, 0x20000000, "i,2,d", 0 }, /* andnoth #const,isrc2,idest */ -{ "or", 0xe0000000, 0x1c000000, "1,2,d", 0 }, /* or isrc1,isrc2,idest */ -{ "or", 0xe4000000, 0x18000000, "i,2,d", E_U32 }, /* or #const,isrc2,idest */ -{ "orh", 0xe8000000, 0x14000000, "1,2,d", 0 }, /* orh isrc1,isrc2,idest */ -{ "orh", 0xec000000, 0x10000000, "i,2,d", 0 }, /* orh #const,isrc2,idest */ -{ "xor", 0xf0000000, 0x0c000000, "1,2,d", 0 }, /* xor isrc1,isrc2,idest */ -{ "xor", 0xf4000000, 0x08000000, "i,2,d", E_U32 }, /* xor #const,isrc2,idest */ -{ "xorh", 0xf8000000, 0x04000000, "1,2,d", 0 }, /* xorh isrc1,isrc2,idest */ -{ "xorh", 0xfc000000, 0x00000000, "i,2,d", 0 }, /* xorh #const,isrc2,idest */ - -{ "bte", 0x58000000, 0xa4000000, "1,2,s", 0 }, /* bte isrc1s,isrc2,sbroff */ -{ "bte", 0x5c000000, 0xa0000000, "5,2,s", 0 }, /* bte #const5,isrc2,sbroff */ -{ "btne", 0x50000000, 0xac000000, "1,2,s", 0 }, /* btne isrc1s,isrc2,sbroff */ -{ "btne", 0x54000000, 0xa8000000, "5,2,s", 0 }, /* btne #const5,isrc2,sbroff */ -{ "bla", 0xb4000000, 0x48000000, "1,2,s", E_DELAY }, /* bla isrc1s,isrc2,sbroff */ -{ "bri", 0x40000000, 0xbc000000, "1", E_DELAY }, /* bri isrc1ni */ - -/* Core Escape Instruction Format */ -{ "lock", 0x4c000001, 0xb000001e, "", 0 }, /* lock set BL in dirbase */ -{ "calli", 0x4c000002, 0xb000001d, "1", E_DELAY }, /* calli isrc1ni */ -{ "intovr", 0x4c000004, 0xb000001b, "", 0 }, /* intovr trap on integer overflow */ -{ "unlock", 0x4c000007, 0xb0000018, "", 0 }, /* unlock clear BL in dirbase */ - -/* CTRL-Format Instructions */ -{ "br", 0x68000000, 0x94000000, "l", E_DELAY }, /* br lbroff */ -{ "call", 0x6c000000, 0x90000000, "l", E_DELAY }, /* call lbroff */ -{ "bc", 0x70000000, 0x8c000000, "l", 0 }, /* bc lbroff */ -{ "bc.t", 0x74000000, 0x88000000, "l", E_DELAY }, /* bc.t lbroff */ -{ "bnc", 0x78000000, 0x84000000, "l", 0 }, /* bnc lbroff */ -{ "bnc.t", 0x7c000000, 0x80000000, "l", E_DELAY }, /* bnc.t lbroff */ - -/* Floating Point Escape Instruction Format - pfam.p fsrc1,fsrc2,fdest */ -{ "r2p1.ss", 0x48000400, 0xb40003ff, "e,f,g", 0 }, -{ "r2p1.sd", 0x48000480, 0xb400037f, "e,f,g", 0 }, -{ "r2p1.dd", 0x48000580, 0xb400027f, "e,f,g", 0 }, -{ "r2pt.ss", 0x48000401, 0xb40003fe, "e,f,g", 0 }, -{ "r2pt.sd", 0x48000481, 0xb400037e, "e,f,g", 0 }, -{ "r2pt.dd", 0x48000581, 0xb400027e, "e,f,g", 0 }, -{ "r2ap1.ss", 0x48000402, 0xb40003fd, "e,f,g", 0 }, -{ "r2ap1.sd", 0x48000482, 0xb400037d, "e,f,g", 0 }, -{ "r2ap1.dd", 0x48000582, 0xb400027d, "e,f,g", 0 }, -{ "r2apt.ss", 0x48000403, 0xb40003fc, "e,f,g", 0 }, -{ "r2apt.sd", 0x48000483, 0xb400037c, "e,f,g", 0 }, -{ "r2apt.dd", 0x48000583, 0xb400027c, "e,f,g", 0 }, -{ "i2p1.ss", 0x48000404, 0xb40003fb, "e,f,g", 0 }, -{ "i2p1.sd", 0x48000484, 0xb400037b, "e,f,g", 0 }, -{ "i2p1.dd", 0x48000584, 0xb400027b, "e,f,g", 0 }, -{ "i2pt.ss", 0x48000405, 0xb40003fa, "e,f,g", 0 }, -{ "i2pt.sd", 0x48000485, 0xb400037a, "e,f,g", 0 }, -{ "i2pt.dd", 0x48000585, 0xb400027a, "e,f,g", 0 }, -{ "i2ap1.ss", 0x48000406, 0xb40003f9, "e,f,g", 0 }, -{ "i2ap1.sd", 0x48000486, 0xb4000379, "e,f,g", 0 }, -{ "i2ap1.dd", 0x48000586, 0xb4000279, "e,f,g", 0 }, -{ "i2apt.ss", 0x48000407, 0xb40003f8, "e,f,g", 0 }, -{ "i2apt.sd", 0x48000487, 0xb4000378, "e,f,g", 0 }, -{ "i2apt.dd", 0x48000587, 0xb4000278, "e,f,g", 0 }, -{ "rat1p2.ss", 0x48000408, 0xb40003f7, "e,f,g", 0 }, -{ "rat1p2.sd", 0x48000488, 0xb4000377, "e,f,g", 0 }, -{ "rat1p2.dd", 0x48000588, 0xb4000277, "e,f,g", 0 }, -{ "m12apm.ss", 0x48000409, 0xb40003f6, "e,f,g", 0 }, -{ "m12apm.sd", 0x48000489, 0xb4000376, "e,f,g", 0 }, -{ "m12apm.dd", 0x48000589, 0xb4000276, "e,f,g", 0 }, -{ "ra1p2.ss", 0x4800040a, 0xb40003f5, "e,f,g", 0 }, -{ "ra1p2.sd", 0x4800048a, 0xb4000375, "e,f,g", 0 }, -{ "ra1p2.dd", 0x4800058a, 0xb4000275, "e,f,g", 0 }, -{ "m12ttpa.ss", 0x4800040b, 0xb40003f4, "e,f,g", 0 }, -{ "m12ttpa.sd", 0x4800048b, 0xb4000374, "e,f,g", 0 }, -{ "m12ttpa.dd", 0x4800058b, 0xb4000274, "e,f,g", 0 }, -{ "iat1p2.ss", 0x4800040c, 0xb40003f3, "e,f,g", 0 }, -{ "iat1p2.sd", 0x4800048c, 0xb4000373, "e,f,g", 0 }, -{ "iat1p2.dd", 0x4800058c, 0xb4000273, "e,f,g", 0 }, -{ "m12tpm.ss", 0x4800040d, 0xb40003f2, "e,f,g", 0 }, -{ "m12tpm.sd", 0x4800048d, 0xb4000372, "e,f,g", 0 }, -{ "m12tpm.dd", 0x4800058d, 0xb4000272, "e,f,g", 0 }, -{ "ia1p2.ss", 0x4800040e, 0xb40003f1, "e,f,g", 0 }, -{ "ia1p2.sd", 0x4800048e, 0xb4000371, "e,f,g", 0 }, -{ "ia1p2.dd", 0x4800058e, 0xb4000271, "e,f,g", 0 }, -{ "m12tpa.ss", 0x4800040f, 0xb40003f0, "e,f,g", 0 }, -{ "m12tpa.sd", 0x4800048f, 0xb4000370, "e,f,g", 0 }, -{ "m12tpa.dd", 0x4800058f, 0xb4000270, "e,f,g", 0 }, - -/* Floating Point Escape Instruction Format - pfsm.p fsrc1,fsrc2,fdest */ -{ "r2s1.ss", 0x48000410, 0xb40003ef, "e,f,g", 0 }, -{ "r2s1.sd", 0x48000490, 0xb400036f, "e,f,g", 0 }, -{ "r2s1.dd", 0x48000590, 0xb400026f, "e,f,g", 0 }, -{ "r2st.ss", 0x48000411, 0xb40003ee, "e,f,g", 0 }, -{ "r2st.sd", 0x48000491, 0xb400036e, "e,f,g", 0 }, -{ "r2st.dd", 0x48000591, 0xb400026e, "e,f,g", 0 }, -{ "r2as1.ss", 0x48000412, 0xb40003ed, "e,f,g", 0 }, -{ "r2as1.sd", 0x48000492, 0xb400036d, "e,f,g", 0 }, -{ "r2as1.dd", 0x48000592, 0xb400026d, "e,f,g", 0 }, -{ "r2ast.ss", 0x48000413, 0xb40003ec, "e,f,g", 0 }, -{ "r2ast.sd", 0x48000493, 0xb400036c, "e,f,g", 0 }, -{ "r2ast.dd", 0x48000593, 0xb400026c, "e,f,g", 0 }, -{ "i2s1.ss", 0x48000414, 0xb40003eb, "e,f,g", 0 }, -{ "i2s1.sd", 0x48000494, 0xb400036b, "e,f,g", 0 }, -{ "i2s1.dd", 0x48000594, 0xb400026b, "e,f,g", 0 }, -{ "i2st.ss", 0x48000415, 0xb40003ea, "e,f,g", 0 }, -{ "i2st.sd", 0x48000495, 0xb400036a, "e,f,g", 0 }, -{ "i2st.dd", 0x48000595, 0xb400026a, "e,f,g", 0 }, -{ "i2as1.ss", 0x48000416, 0xb40003e9, "e,f,g", 0 }, -{ "i2as1.sd", 0x48000496, 0xb4000369, "e,f,g", 0 }, -{ "i2as1.dd", 0x48000596, 0xb4000269, "e,f,g", 0 }, -{ "i2ast.ss", 0x48000417, 0xb40003e8, "e,f,g", 0 }, -{ "i2ast.sd", 0x48000497, 0xb4000368, "e,f,g", 0 }, -{ "i2ast.dd", 0x48000597, 0xb4000268, "e,f,g", 0 }, -{ "rat1s2.ss", 0x48000418, 0xb40003e7, "e,f,g", 0 }, -{ "rat1s2.sd", 0x48000498, 0xb4000367, "e,f,g", 0 }, -{ "rat1s2.dd", 0x48000598, 0xb4000267, "e,f,g", 0 }, -{ "m12asm.ss", 0x48000419, 0xb40003e6, "e,f,g", 0 }, -{ "m12asm.sd", 0x48000499, 0xb4000366, "e,f,g", 0 }, -{ "m12asm.dd", 0x48000599, 0xb4000266, "e,f,g", 0 }, -{ "ra1s2.ss", 0x4800041a, 0xb40003e5, "e,f,g", 0 }, -{ "ra1s2.sd", 0x4800049a, 0xb4000365, "e,f,g", 0 }, -{ "ra1s2.dd", 0x4800059a, 0xb4000265, "e,f,g", 0 }, -{ "m12ttsa.ss", 0x4800041b, 0xb40003e4, "e,f,g", 0 }, -{ "m12ttsa.sd", 0x4800049b, 0xb4000364, "e,f,g", 0 }, -{ "m12ttsa.dd", 0x4800059b, 0xb4000264, "e,f,g", 0 }, -{ "iat1s2.ss", 0x4800041c, 0xb40003e3, "e,f,g", 0 }, -{ "iat1s2.sd", 0x4800049c, 0xb4000363, "e,f,g", 0 }, -{ "iat1s2.dd", 0x4800059c, 0xb4000263, "e,f,g", 0 }, -{ "m12tsm.ss", 0x4800041d, 0xb40003e2, "e,f,g", 0 }, -{ "m12tsm.sd", 0x4800049d, 0xb4000362, "e,f,g", 0 }, -{ "m12tsm.dd", 0x4800059d, 0xb4000262, "e,f,g", 0 }, -{ "ia1s2.ss", 0x4800041e, 0xb40003e1, "e,f,g", 0 }, -{ "ia1s2.sd", 0x4800049e, 0xb4000361, "e,f,g", 0 }, -{ "ia1s2.dd", 0x4800059e, 0xb4000261, "e,f,g", 0 }, -{ "m12tsa.ss", 0x4800041f, 0xb40003e0, "e,f,g", 0 }, -{ "m12tsa.sd", 0x4800049f, 0xb4000360, "e,f,g", 0 }, -{ "m12tsa.dd", 0x4800059f, 0xb4000260, "e,f,g", 0 }, - -/* Floating Point Escape Instruction Format - pfmam.p fsrc1,fsrc2,fdest */ -{ "mr2p1.ss", 0x48000000, 0xb40007ff, "e,f,g", 0 }, -{ "mr2p1.sd", 0x48000080, 0xb400077f, "e,f,g", 0 }, -{ "mr2p1.dd", 0x48000180, 0xb400067f, "e,f,g", 0 }, -{ "mr2pt.ss", 0x48000001, 0xb40007fe, "e,f,g", 0 }, -{ "mr2pt.sd", 0x48000081, 0xb400077e, "e,f,g", 0 }, -{ "mr2pt.dd", 0x48000181, 0xb400067e, "e,f,g", 0 }, -{ "mr2mp1.ss", 0x48000002, 0xb40007fd, "e,f,g", 0 }, -{ "mr2mp1.sd", 0x48000082, 0xb400077d, "e,f,g", 0 }, -{ "mr2mp1.dd", 0x48000182, 0xb400067d, "e,f,g", 0 }, -{ "mr2mpt.ss", 0x48000003, 0xb40007fc, "e,f,g", 0 }, -{ "mr2mpt.sd", 0x48000083, 0xb400077c, "e,f,g", 0 }, -{ "mr2mpt.dd", 0x48000183, 0xb400067c, "e,f,g", 0 }, -{ "mi2p1.ss", 0x48000004, 0xb40007fb, "e,f,g", 0 }, -{ "mi2p1.sd", 0x48000084, 0xb400077b, "e,f,g", 0 }, -{ "mi2p1.dd", 0x48000184, 0xb400067b, "e,f,g", 0 }, -{ "mi2pt.ss", 0x48000005, 0xb40007fa, "e,f,g", 0 }, -{ "mi2pt.sd", 0x48000085, 0xb400077a, "e,f,g", 0 }, -{ "mi2pt.dd", 0x48000185, 0xb400067a, "e,f,g", 0 }, -{ "mi2mp1.ss", 0x48000006, 0xb40007f9, "e,f,g", 0 }, -{ "mi2mp1.sd", 0x48000086, 0xb4000779, "e,f,g", 0 }, -{ "mi2mp1.dd", 0x48000186, 0xb4000679, "e,f,g", 0 }, -{ "mi2mpt.ss", 0x48000007, 0xb40007f8, "e,f,g", 0 }, -{ "mi2mpt.sd", 0x48000087, 0xb4000778, "e,f,g", 0 }, -{ "mi2mpt.dd", 0x48000187, 0xb4000678, "e,f,g", 0 }, -{ "mrmt1p2.ss", 0x48000008, 0xb40007f7, "e,f,g", 0 }, -{ "mrmt1p2.sd", 0x48000088, 0xb4000777, "e,f,g", 0 }, -{ "mrmt1p2.dd", 0x48000188, 0xb4000677, "e,f,g", 0 }, -{ "mm12mpm.ss", 0x48000009, 0xb40007f6, "e,f,g", 0 }, -{ "mm12mpm.sd", 0x48000089, 0xb4000776, "e,f,g", 0 }, -{ "mm12mpm.dd", 0x48000189, 0xb4000676, "e,f,g", 0 }, -{ "mrm1p2.ss", 0x4800000a, 0xb40007f5, "e,f,g", 0 }, -{ "mrm1p2.sd", 0x4800008a, 0xb4000775, "e,f,g", 0 }, -{ "mrm1p2.dd", 0x4800018a, 0xb4000675, "e,f,g", 0 }, -{ "mm12ttpm.ss",0x4800000b, 0xb40007f4, "e,f,g", 0 }, -{ "mm12ttpm.sd",0x4800008b, 0xb4000774, "e,f,g", 0 }, -{ "mm12ttpm.dd",0x4800018b, 0xb4000674, "e,f,g", 0 }, -{ "mimt1p2.ss", 0x4800000c, 0xb40007f3, "e,f,g", 0 }, -{ "mimt1p2.sd", 0x4800008c, 0xb4000773, "e,f,g", 0 }, -{ "mimt1p2.dd", 0x4800018c, 0xb4000673, "e,f,g", 0 }, -{ "mm12tpm.ss", 0x4800000d, 0xb40007f2, "e,f,g", 0 }, -{ "mm12tpm.sd", 0x4800008d, 0xb4000772, "e,f,g", 0 }, -{ "mm12tpm.dd", 0x4800018d, 0xb4000672, "e,f,g", 0 }, -{ "mim1p2.ss", 0x4800000e, 0xb40007f1, "e,f,g", 0 }, -{ "mim1p2.sd", 0x4800008e, 0xb4000771, "e,f,g", 0 }, -{ "mim1p2.dd", 0x4800018e, 0xb4000671, "e,f,g", 0 }, - -/* Floating Point Escape Instruction Format - pfmsm.p fsrc1,fsrc2,fdest */ -{ "mr2s1.ss", 0x48000010, 0xb40007ef, "e,f,g", 0 }, -{ "mr2s1.sd", 0x48000090, 0xb400076f, "e,f,g", 0 }, -{ "mr2s1.dd", 0x48000190, 0xb400066f, "e,f,g", 0 }, -{ "mr2st.ss", 0x48000011, 0xb40007ee, "e,f,g", 0 }, -{ "mr2st.sd", 0x48000091, 0xb400076e, "e,f,g", 0 }, -{ "mr2st.dd", 0x48000191, 0xb400066e, "e,f,g", 0 }, -{ "mr2ms1.ss", 0x48000012, 0xb40007ed, "e,f,g", 0 }, -{ "mr2ms1.sd", 0x48000092, 0xb400076d, "e,f,g", 0 }, -{ "mr2ms1.dd", 0x48000192, 0xb400066d, "e,f,g", 0 }, -{ "mr2mst.ss", 0x48000013, 0xb40007ec, "e,f,g", 0 }, -{ "mr2mst.sd", 0x48000093, 0xb400076c, "e,f,g", 0 }, -{ "mr2mst.dd", 0x48000193, 0xb400066c, "e,f,g", 0 }, -{ "mi2s1.ss", 0x48000014, 0xb40007eb, "e,f,g", 0 }, -{ "mi2s1.sd", 0x48000094, 0xb400076b, "e,f,g", 0 }, -{ "mi2s1.dd", 0x48000194, 0xb400066b, "e,f,g", 0 }, -{ "mi2st.ss", 0x48000015, 0xb40007ea, "e,f,g", 0 }, -{ "mi2st.sd", 0x48000095, 0xb400076a, "e,f,g", 0 }, -{ "mi2st.dd", 0x48000195, 0xb400066a, "e,f,g", 0 }, -{ "mi2ms1.ss", 0x48000016, 0xb40007e9, "e,f,g", 0 }, -{ "mi2ms1.sd", 0x48000096, 0xb4000769, "e,f,g", 0 }, -{ "mi2ms1.dd", 0x48000196, 0xb4000669, "e,f,g", 0 }, -{ "mi2mst.ss", 0x48000017, 0xb40007e8, "e,f,g", 0 }, -{ "mi2mst.sd", 0x48000097, 0xb4000768, "e,f,g", 0 }, -{ "mi2mst.dd", 0x48000197, 0xb4000668, "e,f,g", 0 }, -{ "mrmt1s2.ss", 0x48000018, 0xb40007e7, "e,f,g", 0 }, -{ "mrmt1s2.sd", 0x48000098, 0xb4000767, "e,f,g", 0 }, -{ "mrmt1s2.dd", 0x48000198, 0xb4000667, "e,f,g", 0 }, -{ "mm12msm.ss", 0x48000019, 0xb40007e6, "e,f,g", 0 }, -{ "mm12msm.sd", 0x48000099, 0xb4000766, "e,f,g", 0 }, -{ "mm12msm.dd", 0x48000199, 0xb4000666, "e,f,g", 0 }, -{ "mrm1s2.ss", 0x4800001a, 0xb40007e5, "e,f,g", 0 }, -{ "mrm1s2.sd", 0x4800009a, 0xb4000765, "e,f,g", 0 }, -{ "mrm1s2.dd", 0x4800019a, 0xb4000665, "e,f,g", 0 }, -{ "mm12ttsm.ss",0x4800001b, 0xb40007e4, "e,f,g", 0 }, -{ "mm12ttsm.sd",0x4800009b, 0xb4000764, "e,f,g", 0 }, -{ "mm12ttsm.dd",0x4800019b, 0xb4000664, "e,f,g", 0 }, -{ "mimt1s2.ss", 0x4800001c, 0xb40007e3, "e,f,g", 0 }, -{ "mimt1s2.sd", 0x4800009c, 0xb4000763, "e,f,g", 0 }, -{ "mimt1s2.dd", 0x4800019c, 0xb4000663, "e,f,g", 0 }, -{ "mm12tsm.ss", 0x4800001d, 0xb40007e2, "e,f,g", 0 }, -{ "mm12tsm.sd", 0x4800009d, 0xb4000762, "e,f,g", 0 }, -{ "mm12tsm.dd", 0x4800019d, 0xb4000662, "e,f,g", 0 }, -{ "mim1s2.ss", 0x4800001e, 0xb40007e1, "e,f,g", 0 }, -{ "mim1s2.sd", 0x4800009e, 0xb4000761, "e,f,g", 0 }, -{ "mim1s2.dd", 0x4800019e, 0xb4000661, "e,f,g", 0 }, - - -{ "fmul.ss", 0x48000020, 0xb40007df, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */ -{ "fmul.sd", 0x480000a0, 0xb400075f, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */ -{ "fmul.dd", 0x480001a0, 0xb400065f, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */ -{ "pfmul.ss", 0x48000420, 0xb40003df, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */ -{ "pfmul.sd", 0x480004a0, 0xb400035f, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */ -{ "pfmul.dd", 0x480005a0, 0xb400025f, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */ -{ "pfmul3.dd", 0x480005a4, 0xb400025b, "e,f,g", 0 }, /* pfmul3.p fsrc1,fsrc2,fdest */ -{ "fmlow.dd", 0x480001a1, 0xb400065e, "e,f,g", 0 }, /* fmlow.dd fsrc1,fsrc2,fdest */ -{ "frcp.ss", 0x48000022, 0xb40007dd, "f,g", 0 }, /* frcp.p fsrc2,fdest */ -{ "frcp.sd", 0x480000a2, 0xb400075d, "f,g", 0 }, /* frcp.p fsrc2,fdest */ -{ "frcp.dd", 0x480001a2, 0xb400065d, "f,g", 0 }, /* frcp.p fsrc2,fdest */ -{ "frsqr.ss", 0x48000023, 0xb40007dc, "f,g", 0 }, /* frsqr.p fsrc2,fdest */ -{ "frsqr.sd", 0x480000a3, 0xb400075c, "f,g", 0 }, /* frsqr.p fsrc2,fdest */ -{ "frsqr.dd", 0x480001a3, 0xb400065c, "f,g", 0 }, /* frsqr.p fsrc2,fdest */ -{ "fadd.ss", 0x48000030, 0xb40007cf, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */ -{ "fadd.sd", 0x480000b0, 0xb400074f, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */ -{ "fadd.dd", 0x480001b0, 0xb400064f, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */ -{ "pfadd.ss", 0x48000430, 0xb40003cf, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */ -{ "pfadd.sd", 0x480004b0, 0xb400034f, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */ -{ "pfadd.dd", 0x480005b0, 0xb400024f, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */ -{ "fsub.ss", 0x48000031, 0xb40007ce, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */ -{ "fsub.sd", 0x480000b1, 0xb400074e, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */ -{ "fsub.dd", 0x480001b1, 0xb400064e, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */ -{ "pfsub.ss", 0x48000431, 0xb40003ce, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */ -{ "pfsub.sd", 0x480004b1, 0xb400034e, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */ -{ "pfsub.dd", 0x480005b1, 0xb400024e, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */ -{ "fix.ss", 0x48000032, 0xb40007cd, "e,g", 0 }, /* fix.p fsrc1,fdest */ -{ "fix.sd", 0x480000b2, 0xb400074d, "e,g", 0 }, /* fix.p fsrc1,fdest */ -{ "fix.dd", 0x480001b2, 0xb400064d, "e,g", 0 }, /* fix.p fsrc1,fdest */ -{ "pfix.ss", 0x48000432, 0xb40003cd, "e,g", 0 }, /* pfix.p fsrc1,fdest */ -{ "pfix.sd", 0x480004b2, 0xb400034d, "e,g", 0 }, /* pfix.p fsrc1,fdest */ -{ "pfix.dd", 0x480005b2, 0xb400024d, "e,g", 0 }, /* pfix.p fsrc1,fdest */ -{ "famov.ss", 0x48000033, 0xb40007cc, "e,g", 0 }, /* famov.p fsrc1,fdest */ -{ "famov.ds", 0x48000133, 0xb40006cc, "e,g", 0 }, /* famov.p fsrc1,fdest */ -{ "famov.sd", 0x480000b3, 0xb400074c, "e,g", 0 }, /* famov.p fsrc1,fdest */ -{ "famov.dd", 0x480001b3, 0xb400064c, "e,g", 0 }, /* famov.p fsrc1,fdest */ -{ "pfamov.ss", 0x48000433, 0xb40003cc, "e,g", 0 }, /* pfamov.p fsrc1,fdest */ -{ "pfamov.ds", 0x48000533, 0xb40002cc, "e,g", 0 }, /* pfamov.p fsrc1,fdest */ -{ "pfamov.sd", 0x480004b3, 0xb400034c, "e,g", 0 }, /* pfamov.p fsrc1,fdest */ -{ "pfamov.dd", 0x480005b3, 0xb400024c, "e,g", 0 }, /* pfamov.p fsrc1,fdest */ -/* pfgt has R bit cleared; pfle has R bit set */ -{ "pfgt.ss", 0x48000434, 0xb40003cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */ -{ "pfgt.sd", 0x48000434, 0xb40003cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */ -{ "pfgt.dd", 0x48000534, 0xb40002cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */ -/* pfgt has R bit cleared; pfle has R bit set */ -{ "pfle.ss", 0x480004b4, 0xb400034b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */ -{ "pfle.sd", 0x480004b4, 0xb400034b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */ -{ "pfle.dd", 0x480005b4, 0xb400024b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */ -{ "ftrunc.ss", 0x4800003a, 0xb40007c5, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */ -{ "ftrunc.sd", 0x480000ba, 0xb4000745, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */ -{ "ftrunc.dd", 0x480001ba, 0xb4000645, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */ -{ "pftrunc.ss", 0x4800043a, 0xb40003c5, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */ -{ "pftrunc.sd", 0x480004ba, 0xb4000345, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */ -{ "pftrunc.dd", 0x480005ba, 0xb4000245, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */ -{ "fxfr", 0x48000040, 0xb40007bf, "e,d", 0 }, /* fxfr fsrc1,idest */ -{ "fiadd.ss", 0x48000049, 0xb40007b6, "e,f,g", 0 }, /* fiadd.w fsrc1,fsrc2,fdest */ -{ "fiadd.dd", 0x480001c9, 0xb4000636, "e,f,g", 0 }, /* fiadd.w fsrc1,fsrc2,fdest */ -{ "pfiadd.ss", 0x48000449, 0xb40003b6, "e,f,g", 0 }, /* pfiadd.w fsrc1,fsrc2,fdest */ -{ "pfiadd.dd", 0x480005c9, 0xb4000236, "e,f,g", 0 }, /* pfiadd.w fsrc1,fsrc2,fdest */ -{ "fisub.ss", 0x4800004d, 0xb40007b2, "e,f,g", 0 }, /* fisub.w fsrc1,fsrc2,fdest */ -{ "fisub.dd", 0x480001cd, 0xb4000632, "e,f,g", 0 }, /* fisub.w fsrc1,fsrc2,fdest */ -{ "pfisub.ss", 0x4800044d, 0xb40003b2, "e,f,g", 0 }, /* pfisub.w fsrc1,fsrc2,fdest */ -{ "pfisub.dd", 0x480005cd, 0xb4000232, "e,f,g", 0 }, /* pfisub.w fsrc1,fsrc2,fdest */ -{ "fzchkl", 0x48000057, 0xb40007a8, "e,f,g", 0 }, /* fzchkl fsrc1,fsrc2,fdest */ -{ "pfzchkl", 0x48000457, 0xb40003a8, "e,f,g", 0 }, /* pfzchkl fsrc1,fsrc2,fdest */ -{ "fzchks", 0x4800005f, 0xb40007a0, "e,f,g", 0 }, /* fzchks fsrc1,fsrc2,fdest */ -{ "pfzchks", 0x4800045f, 0xb40003a0, "e,f,g", 0 }, /* pfzchks fsrc1,fsrc2,fdest */ -{ "faddp", 0x48000050, 0xb40007af, "e,f,g", 0 }, /* faddp fsrc1,fsrc2,fdest */ -{ "pfaddp", 0x48000450, 0xb40003af, "e,f,g", 0 }, /* pfaddp fsrc1,fsrc2,fdest */ -{ "faddz", 0x48000051, 0xb40007ae, "e,f,g", 0 }, /* faddz fsrc1,fsrc2,fdest */ -{ "pfaddz", 0x48000451, 0xb40003ae, "e,f,g", 0 }, /* pfaddz fsrc1,fsrc2,fdest */ -{ "form", 0x4800005a, 0xb40007a5, "e,g", 0 }, /* form fsrc1,fdest */ -{ "pform", 0x4800045a, 0xb40003a5, "e,g", 0 }, /* pform fsrc1,fdest */ - -/* Floating point pseudo-instructions */ -{ "fmov.ss", 0x48000049, 0xb7e007b6, "e,g", 0 }, /* fiadd.ss fsrc1,f0,fdest */ -{ "fmov.dd", 0x480001c9, 0xb7e00636, "e,g", 0 }, /* fiadd.dd fsrc1,f0,fdest */ -{ "fmov.sd", 0x480000b0, 0xb7e0074f, "e,g", 0 }, /* fadd.sd fsrc1,f0,fdest */ -{ "fmov.ds", 0x48000130, 0xb7e006cf, "e,g", 0 }, /* fadd.ds fsrc1,f0,fdest */ -{ "pfmov.ds", 0x48000530, 0xb73002cf, "e,g", 0 }, /* pfadd.ds fsrc1,f0,fdest */ -{ "pfmov.dd", 0x480005c9, 0xb7e00236, "e,g", 0 }, /* pfiadd.dd fsrc1,f0,fdest */ - - -}; - -#define NUMOPCODES ((sizeof i860_opcodes)/(sizeof i860_opcodes[0])) - - diff --git a/contrib/gdb/include/opcode/i960.h b/contrib/gdb/include/opcode/i960.h deleted file mode 100644 index 8030ad8a843..00000000000 --- a/contrib/gdb/include/opcode/i960.h +++ /dev/null @@ -1,509 +0,0 @@ -/* Basic 80960 instruction formats. - * - * The 'COJ' instructions are actually COBR instructions with the 'b' in - * the mnemonic replaced by a 'j'; they are ALWAYS "de-optimized" if necessary: - * if the displacement will not fit in 13 bits, the assembler will replace them - * with the corresponding compare and branch instructions. - * - * All of the 'MEMn' instructions are the same format; the 'n' in the name - * indicates the default index scale factor (the size of the datum operated on). - * - * The FBRA formats are not actually an instruction format. They are the - * "convenience directives" for branching on floating-point comparisons, - * each of which generates 2 instructions (a 'bno' and one other branch). - * - * The CALLJ format is not actually an instruction format. It indicates that - * the instruction generated (a CTRL-format 'call') should have its relocation - * specially flagged for link-time replacement with a 'bal' or 'calls' if - * appropriate. - */ - -#define CTRL 0 -#define COBR 1 -#define COJ 2 -#define REG 3 -#define MEM1 4 -#define MEM2 5 -#define MEM4 6 -#define MEM8 7 -#define MEM12 8 -#define MEM16 9 -#define FBRA 10 -#define CALLJ 11 - -/* Masks for the mode bits in REG format instructions */ -#define M1 0x0800 -#define M2 0x1000 -#define M3 0x2000 - -/* Generate the 12-bit opcode for a REG format instruction by placing the - * high 8 bits in instruction bits 24-31, the low 4 bits in instruction bits - * 7-10. - */ - -#define REG_OPC(opc) ((opc & 0xff0) << 20) | ((opc & 0xf) << 7) - -/* Generate a template for a REG format instruction: place the opcode bits - * in the appropriate fields and OR in mode bits for the operands that will not - * be used. I.e., - * set m1=1, if src1 will not be used - * set m2=1, if src2 will not be used - * set m3=1, if dst will not be used - * - * Setting the "unused" mode bits to 1 speeds up instruction execution(!). - * The information is also useful to us because some 1-operand REG instructions - * use the src1 field, others the dst field; and some 2-operand REG instructions - * use src1/src2, others src1/dst. The set mode bits enable us to distinguish. - */ -#define R_0(opc) ( REG_OPC(opc) | M1 | M2 | M3 ) /* No operands */ -#define R_1(opc) ( REG_OPC(opc) | M2 | M3 ) /* 1 operand: src1 */ -#define R_1D(opc) ( REG_OPC(opc) | M1 | M2 ) /* 1 operand: dst */ -#define R_2(opc) ( REG_OPC(opc) | M3 ) /* 2 ops: src1/src2 */ -#define R_2D(opc) ( REG_OPC(opc) | M2 ) /* 2 ops: src1/dst */ -#define R_3(opc) ( REG_OPC(opc) ) /* 3 operands */ - -/* DESCRIPTOR BYTES FOR REGISTER OPERANDS - * - * Interpret names as follows: - * R: global or local register only - * RS: global, local, or (if target allows) special-function register only - * RL: global or local register, or integer literal - * RSL: global, local, or (if target allows) special-function register; - * or integer literal - * F: global, local, or floating-point register - * FL: global, local, or floating-point register; or literal (including - * floating point) - * - * A number appended to a name indicates that registers must be aligned, - * as follows: - * 2: register number must be multiple of 2 - * 4: register number must be multiple of 4 - */ - -#define SFR 0x10 /* Mask for the "sfr-OK" bit */ -#define LIT 0x08 /* Mask for the "literal-OK" bit */ -#define FP 0x04 /* Mask for "floating-point-OK" bit */ - -/* This macro ors the bits together. Note that 'align' is a mask - * for the low 0, 1, or 2 bits of the register number, as appropriate. - */ -#define OP(align,lit,fp,sfr) ( align | lit | fp | sfr ) - -#define R OP( 0, 0, 0, 0 ) -#define RS OP( 0, 0, 0, SFR ) -#define RL OP( 0, LIT, 0, 0 ) -#define RSL OP( 0, LIT, 0, SFR ) -#define F OP( 0, 0, FP, 0 ) -#define FL OP( 0, LIT, FP, 0 ) -#define R2 OP( 1, 0, 0, 0 ) -#define RL2 OP( 1, LIT, 0, 0 ) -#define F2 OP( 1, 0, FP, 0 ) -#define FL2 OP( 1, LIT, FP, 0 ) -#define R4 OP( 3, 0, 0, 0 ) -#define RL4 OP( 3, LIT, 0, 0 ) -#define F4 OP( 3, 0, FP, 0 ) -#define FL4 OP( 3, LIT, FP, 0 ) - -#define M 0x7f /* Memory operand (MEMA & MEMB format instructions) */ - -/* Macros to extract info from the register operand descriptor byte 'od'. - */ -#define SFR_OK(od) (od & SFR) /* TRUE if sfr operand allowed */ -#define LIT_OK(od) (od & LIT) /* TRUE if literal operand allowed */ -#define FP_OK(od) (od & FP) /* TRUE if floating-point op allowed */ -#define REG_ALIGN(od,n) ((od & 0x3 & n) == 0) - /* TRUE if reg #n is properly aligned */ -#define MEMOP(od) (od == M) /* TRUE if operand is a memory operand*/ - -/* Description of a single i80960 instruction */ -struct i960_opcode { - long opcode; /* 32 bits, constant fields filled in, rest zeroed */ - char *name; /* Assembler mnemonic */ - short iclass; /* Class: see #defines below */ - char format; /* REG, COBR, CTRL, MEMn, COJ, FBRA, or CALLJ */ - char num_ops; /* Number of operands */ - char operand[3];/* Operand descriptors; same order as assembler instr */ -}; - -/* Classes of 960 intructions: - * - each instruction falls into one class. - * - each target architecture supports one or more classes. - * - * EACH CONSTANT MUST CONTAIN 1 AND ONLY 1 SET BIT!: see targ_has_iclass(). - */ -#define I_BASE 0x01 /* 80960 base instruction set */ -#define I_CX 0x02 /* 80960Cx instruction */ -#define I_DEC 0x04 /* Decimal instruction */ -#define I_FP 0x08 /* Floating point instruction */ -#define I_KX 0x10 /* 80960Kx instruction */ -#define I_MIL 0x20 /* Military instruction */ -#define I_CASIM 0x40 /* CA simulator instruction */ -#define I_CX2 0x80 /* Cx/Jx/Hx instructions */ -#define I_JX 0x100 /* Jx/Hx instruction */ -#define I_HX 0x200 /* Hx instructions */ - -/****************************************************************************** - * - * TABLE OF i960 INSTRUCTION DESCRIPTIONS - * - ******************************************************************************/ - -const struct i960_opcode i960_opcodes[] = { - - /* if a CTRL instruction has an operand, it's always a displacement */ - - /* callj default=='call' */ - { 0x09000000, "callj", I_BASE, CALLJ, 1, { 0, 0, 0 } }, - { 0x08000000, "b", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x09000000, "call", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x0a000000, "ret", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x0b000000, "bal", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x10000000, "bno", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* bf same as bno */ - { 0x10000000, "bf", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* bru same as bno */ - { 0x10000000, "bru", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x11000000, "bg", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* brg same as bg */ - { 0x11000000, "brg", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x12000000, "be", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* bre same as be */ - { 0x12000000, "bre", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x13000000, "bge", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* brge same as bge */ - { 0x13000000, "brge", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x14000000, "bl", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* brl same as bl */ - { 0x14000000, "brl", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x15000000, "bne", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* brlg same as bne */ - { 0x15000000, "brlg", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x16000000, "ble", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* brle same as ble */ - { 0x16000000, "brle", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x17000000, "bo", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* bt same as bo */ - { 0x17000000, "bt", I_BASE, CTRL, 1, { 0, 0, 0 } }, - /* bro same as bo */ - { 0x17000000, "bro", I_BASE, CTRL, 1, { 0, 0, 0 } }, - { 0x18000000, "faultno", I_BASE, CTRL, 0, { 0, 0, 0 } }, - /* faultf same as faultno */ - { 0x18000000, "faultf", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x19000000, "faultg", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x1a000000, "faulte", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x1b000000, "faultge", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x1c000000, "faultl", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x1d000000, "faultne", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x1e000000, "faultle", I_BASE, CTRL, 0, { 0, 0, 0 } }, - { 0x1f000000, "faulto", I_BASE, CTRL, 0, { 0, 0, 0 } }, - /* faultt syn for faulto */ - { 0x1f000000, "faultt", I_BASE, CTRL, 0, { 0, 0, 0 } }, - - { 0x01000000, "syscall", I_CASIM,CTRL, 0, { 0, 0, 0 } }, - - /* If a COBR (or COJ) has 3 operands, the last one is always a - * displacement and does not appear explicitly in the table. - */ - - { 0x20000000, "testno", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x21000000, "testg", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x22000000, "teste", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x23000000, "testge", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x24000000, "testl", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x25000000, "testne", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x26000000, "testle", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x27000000, "testo", I_BASE, COBR, 1, { R, 0, 0 } }, - { 0x30000000, "bbc", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x31000000, "cmpobg", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x32000000, "cmpobe", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x33000000, "cmpobge", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x34000000, "cmpobl", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x35000000, "cmpobne", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x36000000, "cmpoble", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x37000000, "bbs", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x38000000, "cmpibno", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x39000000, "cmpibg", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x3a000000, "cmpibe", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x3b000000, "cmpibge", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x3c000000, "cmpibl", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x3d000000, "cmpibne", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x3e000000, "cmpible", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x3f000000, "cmpibo", I_BASE, COBR, 3, { RL, RS, 0 } }, - { 0x31000000, "cmpojg", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x32000000, "cmpoje", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x33000000, "cmpojge", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x34000000, "cmpojl", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x35000000, "cmpojne", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x36000000, "cmpojle", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x38000000, "cmpijno", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x39000000, "cmpijg", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x3a000000, "cmpije", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x3b000000, "cmpijge", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x3c000000, "cmpijl", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x3d000000, "cmpijne", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x3e000000, "cmpijle", I_BASE, COJ, 3, { RL, RS, 0 } }, - { 0x3f000000, "cmpijo", I_BASE, COJ, 3, { RL, RS, 0 } }, - - { 0x80000000, "ldob", I_BASE, MEM1, 2, { M, R, 0 } }, - { 0x82000000, "stob", I_BASE, MEM1, 2, { R, M, 0 } }, - { 0x84000000, "bx", I_BASE, MEM1, 1, { M, 0, 0 } }, - { 0x85000000, "balx", I_BASE, MEM1, 2, { M, R, 0 } }, - { 0x86000000, "callx", I_BASE, MEM1, 1, { M, 0, 0 } }, - { 0x88000000, "ldos", I_BASE, MEM2, 2, { M, R, 0 } }, - { 0x8a000000, "stos", I_BASE, MEM2, 2, { R, M, 0 } }, - { 0x8c000000, "lda", I_BASE, MEM1, 2, { M, R, 0 } }, - { 0x90000000, "ld", I_BASE, MEM4, 2, { M, R, 0 } }, - { 0x92000000, "st", I_BASE, MEM4, 2, { R, M, 0 } }, - { 0x98000000, "ldl", I_BASE, MEM8, 2, { M, R2, 0 } }, - { 0x9a000000, "stl", I_BASE, MEM8, 2, { R2, M, 0 } }, - { 0xa0000000, "ldt", I_BASE, MEM12, 2, { M, R4, 0 } }, - { 0xa2000000, "stt", I_BASE, MEM12, 2, { R4, M, 0 } }, - { 0xb0000000, "ldq", I_BASE, MEM16, 2, { M, R4, 0 } }, - { 0xb2000000, "stq", I_BASE, MEM16, 2, { R4, M, 0 } }, - { 0xc0000000, "ldib", I_BASE, MEM1, 2, { M, R, 0 } }, - { 0xc2000000, "stib", I_BASE, MEM1, 2, { R, M, 0 } }, - { 0xc8000000, "ldis", I_BASE, MEM2, 2, { M, R, 0 } }, - { 0xca000000, "stis", I_BASE, MEM2, 2, { R, M, 0 } }, - - { R_3(0x580), "notbit", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x581), "and", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x582), "andnot", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x583), "setbit", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x584), "notand", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x586), "xor", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x587), "or", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x588), "nor", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x589), "xnor", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_2D(0x58a), "not", I_BASE, REG, 2, { RSL,RS, 0 } }, - { R_3(0x58b), "ornot", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x58c), "clrbit", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x58d), "notor", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x58e), "nand", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x58f), "alterbit", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x590), "addo", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x591), "addi", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x592), "subo", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x593), "subi", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x598), "shro", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x59a), "shrdi", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x59b), "shri", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x59c), "shlo", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x59d), "rotate", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x59e), "shli", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_2(0x5a0), "cmpo", I_BASE, REG, 2, { RSL,RSL, 0 } }, - { R_2(0x5a1), "cmpi", I_BASE, REG, 2, { RSL,RSL, 0 } }, - { R_2(0x5a2), "concmpo", I_BASE, REG, 2, { RSL,RSL, 0 } }, - { R_2(0x5a3), "concmpi", I_BASE, REG, 2, { RSL,RSL, 0 } }, - { R_3(0x5a4), "cmpinco", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x5a5), "cmpinci", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x5a6), "cmpdeco", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x5a7), "cmpdeci", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_2(0x5ac), "scanbyte", I_BASE, REG, 2, { RSL,RSL, 0 } }, - { R_2(0x5ae), "chkbit", I_BASE, REG, 2, { RSL,RSL, 0 } }, - { R_3(0x5b0), "addc", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x5b2), "subc", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_2D(0x5cc), "mov", I_BASE, REG, 2, { RSL,RS, 0 } }, - { R_2D(0x5dc), "movl", I_BASE, REG, 2, { RL2,R2, 0 } }, - { R_2D(0x5ec), "movt", I_BASE, REG, 2, { RL4,R4, 0 } }, - { R_2D(0x5fc), "movq", I_BASE, REG, 2, { RL4,R4, 0 } }, - { R_3(0x610), "atmod", I_BASE, REG, 3, { RS, RSL,R } }, - { R_3(0x612), "atadd", I_BASE, REG, 3, { RS, RSL,RS } }, - { R_2D(0x640), "spanbit", I_BASE, REG, 2, { RSL,RS, 0 } }, - { R_2D(0x641), "scanbit", I_BASE, REG, 2, { RSL,RS, 0 } }, - { R_3(0x645), "modac", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x650), "modify", I_BASE, REG, 3, { RSL,RSL,R } }, - { R_3(0x651), "extract", I_BASE, REG, 3, { RSL,RSL,R } }, - { R_3(0x654), "modtc", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x655), "modpc", I_BASE, REG, 3, { RSL,RSL,R } }, - { R_1(0x660), "calls", I_BASE, REG, 1, { RSL, 0, 0 } }, - { R_0(0x66b), "mark", I_BASE, REG, 0, { 0, 0, 0 } }, - { R_0(0x66c), "fmark", I_BASE, REG, 0, { 0, 0, 0 } }, - { R_0(0x66d), "flushreg", I_BASE, REG, 0, { 0, 0, 0 } }, - { R_0(0x66f), "syncf", I_BASE, REG, 0, { 0, 0, 0 } }, - { R_3(0x670), "emul", I_BASE, REG, 3, { RSL,RSL,R2 } }, - { R_3(0x671), "ediv", I_BASE, REG, 3, { RSL,RL2,RS } }, - { R_2D(0x672), "cvtadr", I_CASIM,REG, 2, { RL, R2, 0 } }, - { R_3(0x701), "mulo", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x708), "remo", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x70b), "divo", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x741), "muli", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x748), "remi", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x749), "modi", I_BASE, REG, 3, { RSL,RSL,RS } }, - { R_3(0x74b), "divi", I_BASE, REG, 3, { RSL,RSL,RS } }, - - /* Floating-point instructions */ - - { R_2D(0x674), "cvtir", I_FP, REG, 2, { RL, F, 0 } }, - { R_2D(0x675), "cvtilr", I_FP, REG, 2, { RL, F, 0 } }, - { R_3(0x676), "scalerl", I_FP, REG, 3, { RL, FL2,F2 } }, - { R_3(0x677), "scaler", I_FP, REG, 3, { RL, FL, F } }, - { R_3(0x680), "atanr", I_FP, REG, 3, { FL, FL, F } }, - { R_3(0x681), "logepr", I_FP, REG, 3, { FL, FL, F } }, - { R_3(0x682), "logr", I_FP, REG, 3, { FL, FL, F } }, - { R_3(0x683), "remr", I_FP, REG, 3, { FL, FL, F } }, - { R_2(0x684), "cmpor", I_FP, REG, 2, { FL, FL, 0 } }, - { R_2(0x685), "cmpr", I_FP, REG, 2, { FL, FL, 0 } }, - { R_2D(0x688), "sqrtr", I_FP, REG, 2, { FL, F, 0 } }, - { R_2D(0x689), "expr", I_FP, REG, 2, { FL, F, 0 } }, - { R_2D(0x68a), "logbnr", I_FP, REG, 2, { FL, F, 0 } }, - { R_2D(0x68b), "roundr", I_FP, REG, 2, { FL, F, 0 } }, - { R_2D(0x68c), "sinr", I_FP, REG, 2, { FL, F, 0 } }, - { R_2D(0x68d), "cosr", I_FP, REG, 2, { FL, F, 0 } }, - { R_2D(0x68e), "tanr", I_FP, REG, 2, { FL, F, 0 } }, - { R_1(0x68f), "classr", I_FP, REG, 1, { FL, 0, 0 } }, - { R_3(0x690), "atanrl", I_FP, REG, 3, { FL2,FL2,F2 } }, - { R_3(0x691), "logeprl", I_FP, REG, 3, { FL2,FL2,F2 } }, - { R_3(0x692), "logrl", I_FP, REG, 3, { FL2,FL2,F2 } }, - { R_3(0x693), "remrl", I_FP, REG, 3, { FL2,FL2,F2 } }, - { R_2(0x694), "cmporl", I_FP, REG, 2, { FL2,FL2, 0 } }, - { R_2(0x695), "cmprl", I_FP, REG, 2, { FL2,FL2, 0 } }, - { R_2D(0x698), "sqrtrl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_2D(0x699), "exprl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_2D(0x69a), "logbnrl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_2D(0x69b), "roundrl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_2D(0x69c), "sinrl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_2D(0x69d), "cosrl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_2D(0x69e), "tanrl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_1(0x69f), "classrl", I_FP, REG, 1, { FL2, 0, 0 } }, - { R_2D(0x6c0), "cvtri", I_FP, REG, 2, { FL, R, 0 } }, - { R_2D(0x6c1), "cvtril", I_FP, REG, 2, { FL, R2, 0 } }, - { R_2D(0x6c2), "cvtzri", I_FP, REG, 2, { FL, R, 0 } }, - { R_2D(0x6c3), "cvtzril", I_FP, REG, 2, { FL, R2, 0 } }, - { R_2D(0x6c9), "movr", I_FP, REG, 2, { FL, F, 0 } }, - { R_2D(0x6d9), "movrl", I_FP, REG, 2, { FL2,F2, 0 } }, - { R_2D(0x6e1), "movre", I_FP, REG, 2, { FL4,F4, 0 } }, - { R_3(0x6e2), "cpysre", I_FP, REG, 3, { FL4,FL4,F4 } }, - { R_3(0x6e3), "cpyrsre", I_FP, REG, 3, { FL4,FL4,F4 } }, - { R_3(0x78b), "divr", I_FP, REG, 3, { FL, FL, F } }, - { R_3(0x78c), "mulr", I_FP, REG, 3, { FL, FL, F } }, - { R_3(0x78d), "subr", I_FP, REG, 3, { FL, FL, F } }, - { R_3(0x78f), "addr", I_FP, REG, 3, { FL, FL, F } }, - { R_3(0x79b), "divrl", I_FP, REG, 3, { FL2,FL2,F2 } }, - { R_3(0x79c), "mulrl", I_FP, REG, 3, { FL2,FL2,F2 } }, - { R_3(0x79d), "subrl", I_FP, REG, 3, { FL2,FL2,F2 } }, - { R_3(0x79f), "addrl", I_FP, REG, 3, { FL2,FL2,F2 } }, - - /* These are the floating point branch instructions. Each actually - * generates 2 branch instructions: the first a CTRL instruction with - * the indicated opcode, and the second a 'bno'. - */ - - { 0x12000000, "brue", I_FP, FBRA, 1, { 0, 0, 0 } }, - { 0x11000000, "brug", I_FP, FBRA, 1, { 0, 0, 0 } }, - { 0x13000000, "bruge", I_FP, FBRA, 1, { 0, 0, 0 } }, - { 0x14000000, "brul", I_FP, FBRA, 1, { 0, 0, 0 } }, - { 0x16000000, "brule", I_FP, FBRA, 1, { 0, 0, 0 } }, - { 0x15000000, "brulg", I_FP, FBRA, 1, { 0, 0, 0 } }, - - - /* Decimal instructions */ - - { R_3(0x642), "daddc", I_DEC, REG, 3, { RSL,RSL,RS } }, - { R_3(0x643), "dsubc", I_DEC, REG, 3, { RSL,RSL,RS } }, - { R_2D(0x644), "dmovt", I_DEC, REG, 2, { RSL,RS, 0 } }, - - - /* KX extensions */ - - { R_2(0x600), "synmov", I_KX, REG, 2, { R, R, 0 } }, - { R_2(0x601), "synmovl", I_KX, REG, 2, { R, R, 0 } }, - { R_2(0x602), "synmovq", I_KX, REG, 2, { R, R, 0 } }, - { R_2D(0x615), "synld", I_KX, REG, 2, { R, R, 0 } }, - - - /* MC extensions */ - - { R_3(0x603), "cmpstr", I_MIL, REG, 3, { R, R, RL } }, - { R_3(0x604), "movqstr", I_MIL, REG, 3, { R, R, RL } }, - { R_3(0x605), "movstr", I_MIL, REG, 3, { R, R, RL } }, - { R_2D(0x613), "inspacc", I_MIL, REG, 2, { R, R, 0 } }, - { R_2D(0x614), "ldphy", I_MIL, REG, 2, { R, R, 0 } }, - { R_3(0x617), "fill", I_MIL, REG, 3, { R, RL, RL } }, - { R_2D(0x646), "condrec", I_MIL, REG, 2, { R, R, 0 } }, - { R_2D(0x656), "receive", I_MIL, REG, 2, { R, R, 0 } }, - { R_3(0x662), "send", I_MIL, REG, 3, { R, RL, R } }, - { R_1(0x663), "sendserv", I_MIL, REG, 1, { R, 0, 0 } }, - { R_1(0x664), "resumprcs", I_MIL, REG, 1, { R, 0, 0 } }, - { R_1(0x665), "schedprcs", I_MIL, REG, 1, { R, 0, 0 } }, - { R_0(0x666), "saveprcs", I_MIL, REG, 0, { 0, 0, 0 } }, - { R_1(0x668), "condwait", I_MIL, REG, 1, { R, 0, 0 } }, - { R_1(0x669), "wait", I_MIL, REG, 1, { R, 0, 0 } }, - { R_1(0x66a), "signal", I_MIL, REG, 1, { R, 0, 0 } }, - { R_1D(0x673), "ldtime", I_MIL, REG, 1, { R2, 0, 0 } }, - - - /* CX extensions */ - - { R_3(0x5d8), "eshro", I_CX2, REG, 3, { RSL,RSL,RS } }, - { R_3(0x630), "sdma", I_CX, REG, 3, { RSL,RSL,RL } }, - { R_3(0x631), "udma", I_CX, REG, 0, { 0, 0, 0 } }, - { R_3(0x659), "sysctl", I_CX2, REG, 3, { RSL,RSL,RL } }, - - - /* Jx extensions. */ - { R_3(0x780), "addono", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x790), "addog", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7a0), "addoe", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7b0), "addoge", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7c0), "addol", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7d0), "addone", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7e0), "addole", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7f0), "addoo", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x781), "addino", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x791), "addig", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7a1), "addie", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7b1), "addige", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7c1), "addil", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7d1), "addine", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7e1), "addile", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7f1), "addio", I_JX, REG, 3, { RSL,RSL,RS } }, - - { R_2D(0x5ad), "bswap", I_JX, REG, 2, { RSL, RS, 0 } }, - - { R_2(0x594), "cmpob", I_JX, REG, 2, { RSL,RSL, 0 } }, - { R_2(0x595), "cmpib", I_JX, REG, 2, { RSL,RSL, 0 } }, - { R_2(0x596), "cmpos", I_JX, REG, 2, { RSL,RSL, 0 } }, - { R_2(0x597), "cmpis", I_JX, REG, 2, { RSL,RSL, 0 } }, - - { R_3(0x784), "selno", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x794), "selg", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7a4), "sele", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7b4), "selge", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7c4), "sell", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7d4), "selne", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7e4), "selle", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7f4), "selo", I_JX, REG, 3, { RSL,RSL,RS } }, - - { R_3(0x782), "subono", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x792), "subog", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7a2), "suboe", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7b2), "suboge", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7c2), "subol", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7d2), "subone", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7e2), "subole", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7f2), "suboo", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x783), "subino", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x793), "subig", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7a3), "subie", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7b3), "subige", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7c3), "subil", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7d3), "subine", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7e3), "subile", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_3(0x7f3), "subio", I_JX, REG, 3, { RSL,RSL,RS } }, - - { R_3(0x65c), "dcctl", I_JX, REG, 3, { RSL,RSL,RL } }, - { R_3(0x65b), "icctl", I_JX, REG, 3, { RSL,RSL,RS } }, - { R_2D(0x658), "intctl", I_JX, REG, 2, { RSL, RS, 0 } }, - { R_0(0x5b4), "intdis", I_JX, REG, 0, { 0, 0, 0 } }, - { R_0(0x5b5), "inten", I_JX, REG, 0, { 0, 0, 0 } }, - { R_0(0x65d), "halt", I_JX, REG, 0, { 0, 0, 0 } }, - - /* Hx extensions. */ - { 0xac000000, "dcinva", I_HX, MEM1, 1, { M, 0, 0 } }, - - /* END OF TABLE */ - - { 0, NULL, 0, 0, 0, { 0, 0, 0 } } -}; - - /* end of i960-opcode.h */ diff --git a/contrib/gdb/include/opcode/m68k.h b/contrib/gdb/include/opcode/m68k.h deleted file mode 100644 index e0b371c92bb..00000000000 --- a/contrib/gdb/include/opcode/m68k.h +++ /dev/null @@ -1,297 +0,0 @@ -/* Opcode table header for m680[01234]0/m6888[12]/m68851. - Copyright 1989, 1991, 1992, 1993, 1994, 1995 Free Software Foundation. - -This file is part of GDB, GAS, and the GNU binutils. - -GDB, GAS, and the GNU binutils are free software; you can redistribute -them and/or modify them under the terms of the GNU General Public -License as published by the Free Software Foundation; either version -1, or (at your option) any later version. - -GDB, GAS, and the GNU binutils are distributed in the hope that they -will be useful, but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See -the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this file; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -/* These are used as bit flags for the arch field in the m68k_opcode - structure. */ -#define _m68k_undef 0 -#define m68000 0x001 -#define m68008 m68000 /* synonym for -m68000. otherwise unused. */ -#define m68010 0x002 -#define m68020 0x004 -#define m68030 0x008 -#define m68ec030 m68030 /* similar enough to -m68030 to ignore differences; - gas will deal with the few differences. */ -#define m68040 0x010 -/* there is no 68050 */ -#define m68060 0x020 -#define m68881 0x040 -#define m68882 m68881 /* synonym for -m68881. otherwise unused. */ -#define m68851 0x080 -#define cpu32 0x100 /* e.g., 68332 */ - - /* handy aliases */ -#define m68040up (m68040 | m68060) -#define m68030up (m68030 | m68040up) -#define m68020up (m68020 | m68030up) -#define m68010up (m68010 | cpu32 | m68020up) -#define m68000up (m68000 | m68010up) - -#define mfloat (m68881 | m68882 | m68040 | m68060) -#define mmmu (m68851 | m68030 | m68040 | m68060) - -/* The structure used to hold information for an opcode. */ - -struct m68k_opcode -{ - /* The opcode name. */ - const char *name; - /* The opcode itself. */ - unsigned long opcode; - /* The mask used by the disassembler. */ - unsigned long match; - /* The arguments. */ - const char *args; - /* The architectures which support this opcode. */ - unsigned int arch; -}; - -/* The structure used to hold information for an opcode alias. */ - -struct m68k_opcode_alias -{ - /* The alias name. */ - const char *alias; - /* The instruction for which this is an alias. */ - const char *primary; -}; - -/* We store four bytes of opcode for all opcodes because that is the - most any of them need. The actual length of an instruction is - always at least 2 bytes, and is as much longer as necessary to hold - the operands it has. - - The match field is a mask saying which bits must match particular - opcode in order for an instruction to be an instance of that - opcode. - - The args field is a string containing two characters for each - operand of the instruction. The first specifies the kind of - operand; the second, the place it is stored. */ - -/* Kinds of operands: - Characters used: AaBCcDdFfIJkLlMOQRrSsTtUVWXYZ0123|*~%;@!&$?/#^+- - - D data register only. Stored as 3 bits. - A address register only. Stored as 3 bits. - a address register indirect only. Stored as 3 bits. - R either kind of register. Stored as 4 bits. - r either kind of register indirect only. Stored as 4 bits. - At the moment, used only for cas2 instruction. - F floating point coprocessor register only. Stored as 3 bits. - O an offset (or width): immediate data 0-31 or data register. - Stored as 6 bits in special format for BF... insns. - + autoincrement only. Stored as 3 bits (number of the address register). - - autodecrement only. Stored as 3 bits (number of the address register). - Q quick immediate data. Stored as 3 bits. - This matches an immediate operand only when value is in range 1 .. 8. - M moveq immediate data. Stored as 8 bits. - This matches an immediate operand only when value is in range -128..127 - T trap vector immediate data. Stored as 4 bits. - - k K-factor for fmove.p instruction. Stored as a 7-bit constant or - a three bit register offset, depending on the field type. - - # immediate data. Stored in special places (b, w or l) - which say how many bits to store. - ^ immediate data for floating point instructions. Special places - are offset by 2 bytes from '#'... - B pc-relative address, converted to an offset - that is treated as immediate data. - d displacement and register. Stores the register as 3 bits - and stores the displacement in the entire second word. - - C the CCR. No need to store it; this is just for filtering validity. - S the SR. No need to store, just as with CCR. - U the USP. No need to store, just as with CCR. - - I Coprocessor ID. Not printed if 1. The Coprocessor ID is always - extracted from the 'd' field of word one, which means that an extended - coprocessor opcode can be skipped using the 'i' place, if needed. - - s System Control register for the floating point coprocessor. - - J Misc register for movec instruction, stored in 'j' format. - Possible values: - 0x000 SFC Source Function Code reg [60, 40, 30, 20, 10] - 0x001 DFC Data Function Code reg [60, 40, 30, 20, 10] - 0x002 CACR Cache Control Register [60, 40, 30, 20] - 0x003 TC MMU Translation Control [60, 40] - 0x004 ITT0 Instruction Transparent - Translation reg 0 [60, 40] - 0x005 ITT1 Instruction Transparent - Translation reg 1 [60, 40] - 0x006 DTT0 Data Transparent - Translation reg 0 [60, 40] - 0x007 DTT1 Data Transparent - Translation reg 1 [60, 40] - 0x008 BUSCR Bus Control Register [60] - 0x800 USP User Stack Pointer [60, 40, 30, 20, 10] - 0x801 VBR Vector Base reg [60, 40, 30, 20, 10] - 0x802 CAAR Cache Address Register [ 30, 20] - 0x803 MSP Master Stack Pointer [ 40, 30, 20] - 0x804 ISP Interrupt Stack Pointer [ 40, 30, 20] - 0x805 MMUSR MMU Status reg [ 40] - 0x806 URP User Root Pointer [60, 40] - 0x807 SRP Supervisor Root Pointer [60, 40] - 0x808 PCR Processor Configuration reg [60] - - L Register list of the type d0-d7/a0-a7 etc. - (New! Improved! Can also hold fp0-fp7, as well!) - The assembler tries to see if the registers match the insn by - looking at where the insn wants them stored. - - l Register list like L, but with all the bits reversed. - Used for going the other way. . . - - c cache identifier which may be "nc" for no cache, "ic" - for instruction cache, "dc" for data cache, or "bc" - for both caches. Used in cinv and cpush. Always - stored in position "d". - - The remainder are all stored as 6 bits using an address mode and a - register number; they differ in which addressing modes they match. - - * all (modes 0-6,7.*) - ~ alterable memory (modes 2-6,7.0,7.1) - (not 0,1,7.~) - % alterable (modes 0-6,7.0,7.1)(not 7.~) - ; data (modes 0,2-6,7.*)(not 1) - @ data, but not immediate (modes 0,2-6,7.? ? ?) - (not 1,7.?) - This may really be ;, - the 68020 book says it is - ! control (modes 2,5,6,7.*-) - (not 0,1,3,4,7.4) - & alterable control (modes 2,5,6,7.0,7.1) - (not 0,1,7.? ? ?) - $ alterable data (modes 0,2-6,7.0,7.1) - (not 1,7.~) - ? alterable control, or data register (modes 0,2,5,6,7.0,7.1) - (not 1,3,4,7.~) - / control, or data register (modes 0,2,5,6,7.0,7.1,7.2,7.3) - (not 1,3,4,7.4) - ` control, plus pre-dec, not simple indir. (modes 4,5,6,7.*-) - (not 0,1,2,3,7.4) */ - -/* For the 68851: */ -/* - I didn't use much imagination in choosing the - following codes, so many of them aren't very - mnemonic. -rab - - 0 32 bit pmmu register - Possible values: - 000 TC Translation Control Register (68030, 68851) - - 1 16 bit pmmu register - 111 AC Access Control (68851) - - 2 8 bit pmmu register - 100 CAL Current Access Level (68851) - 101 VAL Validate Access Level (68851) - 110 SCC Stack Change Control (68851) - - 3 68030-only pmmu registers (32 bit) - 010 TT0 Transparent Translation reg 0 - (aka Access Control reg 0 -- AC0 -- on 68ec030) - 011 TT1 Transparent Translation reg 1 - (aka Access Control reg 1 -- AC1 -- on 68ec030) - - W wide pmmu registers - Possible values: - 001 DRP Dma Root Pointer (68851) - 010 SRP Supervisor Root Pointer (68030, 68851) - 011 CRP Cpu Root Pointer (68030, 68851) - - f function code register (68030, 68851) - 0 SFC - 1 DFC - - V VAL register only (68851) - - X BADx, BACx (16 bit) - 100 BAD Breakpoint Acknowledge Data (68851) - 101 BAC Breakpoint Acknowledge Control (68851) - - Y PSR (68851) (MMUSR on 68030) (ACUSR on 68ec030) - Z PCSR (68851) - - | memory (modes 2-6, 7.*) - - t address test level (68030 only) - Stored as 3 bits, range 0-7. - Also used for breakpoint instruction now. - -*/ - -/* Places to put an operand, for non-general operands: - s source, low bits of first word. - d dest, shifted 9 in first word - 1 second word, shifted 12 - 2 second word, shifted 6 - 3 second word, shifted 0 - 4 third word, shifted 12 - 5 third word, shifted 6 - 6 third word, shifted 0 - 7 second word, shifted 7 - 8 second word, shifted 10 - 9 second word, shifted 5 - D store in both place 1 and place 3; for divul and divsl. - B first word, low byte, for branch displacements - W second word (entire), for branch displacements - L second and third words (entire), for branch displacements - (also overloaded for move16) - b second word, low byte - w second word (entire) [variable word/long branch offset for dbra] - W second word (entire) (must be signed 16 bit value) - l second and third word (entire) - g variable branch offset for bra and similar instructions. - The place to store depends on the magnitude of offset. - t store in both place 7 and place 8; for floating point operations - c branch offset for cpBcc operations. - The place to store is word two if bit six of word one is zero, - and words two and three if bit six of word one is one. - i Increment by two, to skip over coprocessor extended operands. Only - works with the 'I' format. - k Dynamic K-factor field. Bits 6-4 of word 2, used as a register number. - Also used for dynamic fmovem instruction. - C floating point coprocessor constant - 7 bits. Also used for static - K-factors... - j Movec register #, stored in 12 low bits of second word. - - Places to put operand, for general operands: - d destination, shifted 6 bits in first word - b source, at low bit of first word, and immediate uses one byte - w source, at low bit of first word, and immediate uses two bytes - l source, at low bit of first word, and immediate uses four bytes - s source, at low bit of first word. - Used sometimes in contexts where immediate is not allowed anyway. - f single precision float, low bit of 1st word, immediate uses 4 bytes - F double precision float, low bit of 1st word, immediate uses 8 bytes - x extended precision float, low bit of 1st word, immediate uses 12 bytes - p packed float, low bit of 1st word, immediate uses 12 bytes -*/ - -extern const struct m68k_opcode m68k_opcodes[]; -extern const struct m68k_opcode_alias m68k_opcode_aliases[]; - -extern const int m68k_numopcodes, m68k_numaliases; - -/* end of m68k-opcode.h */ diff --git a/contrib/gdb/include/opcode/m88k.h b/contrib/gdb/include/opcode/m88k.h deleted file mode 100644 index a17fa0361da..00000000000 --- a/contrib/gdb/include/opcode/m88k.h +++ /dev/null @@ -1,923 +0,0 @@ -/* Table of opcodes for the motorola 88k family. - Copyright 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - -This file is part of GDB and GAS. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - * Disassembler Instruction Table - * - * The first field of the table is the opcode field. If an opcode - * is specified which has any non-opcode bits on, a system error - * will occur when the system attempts the install it into the - * instruction table. The second parameter is a pointer to the - * instruction mnemonic. Each operand is specified by offset, width, - * and type. The offset is the bit number of the least significant - * bit of the operand with bit 0 being the least significant bit of - * the instruction. The width is the number of bits used to specify - * the operand. The type specifies the output format to be used for - * the operand. The valid formats are: register, register indirect, - * hex constant, and bit field specification. The last field is a - * pointer to the next instruction in the linked list. These pointers - * are initialized by init_disasm(). - * - * Structure Format - * - * struct INSTAB { - * UPINT opcode; - * char *mnemonic; - * struct OPSPEC op1,op2,op3; - * struct SIM_FLAGS flgs; - * struct INSTAB *next; - * } - * - * struct OPSPEC { - * UPINT offset:5; - * UPINT width:6; - * UPINT type:5; - * } - * - * Revision History - * - * Revision 1.0 11/08/85 Creation date - * 1.1 02/05/86 Updated instruction mnemonic table MD - * 1.2 06/16/86 Updated SIM_FLAGS for floating point - * 1.3 09/20/86 Updated for new encoding - * 05/11/89 R. Trawick adapted from Motorola disassembler - */ - -#include - - -/* - * This file contains the structures and constants needed to build the M88000 - * simulator. It is the main include file, containing all the - * structures, macros and definitions except for the floating point - * instruction set. - */ - -/* - * The following flag informs the Simulator as to what type of byte ordering - * will be used. For instance, a BOFLAG = 1 indicates a DEC VAX and IBM type - * of ordering shall be used. -*/ - -/* # define BOFLAG 1 */ /* BYTE ORDERING FLAG */ - -/* define the number of bits in the primary opcode field of the instruction, - * the destination field, the source 1 and source 2 fields. - */ -# define OP 8 /* size of opcode field */ -# define DEST 6 /* size of destination */ -# define SOURCE1 6 /* size of source1 */ -# define SOURCE2 6 /* size of source2 */ - -# define REGs 32 /* number of registers */ - -# define WORD long -# define FLAG unsigned -# define STATE short - -# define TRUE 1 -# define FALSE 0 - -# define READ 0 -# define WRITE 1 - -/* The next four equates define the priorities that the various classes - * of instructions have regarding writing results back into registers and - * signalling exceptions. - */ -/* PMEM is also defined in on Delta 88's. Sigh! */ -#undef PMEM - -# define PINT 0 /* Integer Priority */ -# define PFLT 1 /* Floating Point Priority */ -# define PMEM 2 /* Memory Priority */ -# define NA 3 /* Not Applicable, instruction doesnt write to regs */ -# define HIPRI 3 /* highest of these priorities */ - -/* The instruction registers are an artificial mechanism to speed up - * simulator execution. In the real processor, an instruction register - * is 32 bits wide. In the simulator, the 32 bit instruction is kept in - * a structure field called rawop, and the instruction is partially decoded, - * and split into various fields and flags which make up the other fields - * of the structure. - * The partial decode is done when the instructions are initially loaded - * into simulator memory. The simulator code memory is not an array of - * 32 bit words, but is an array of instruction register structures. - * Yes this wastes memory, but it executes much quicker. - */ - -struct IR_FIELDS { - unsigned op:OP, - dest: DEST, - src1: SOURCE1, - src2: SOURCE2; - int ltncy, - extime, - wb_pri; /* writeback priority */ - unsigned imm_flags:2,/* immediate size */ - rs1_used:1, /* register source 1 used */ - rs2_used:1, /* register source 2 used */ - rsd_used:1, /* register source/dest. used */ - c_flag:1, /* complement */ - u_flag:1, /* upper half word */ - n_flag:1, /* execute next */ - wb_flag:1, /* uses writeback slot */ - dest_64:1, /* dest size */ - s1_64:1, /* source 1 size */ - s2_64:1, /* source 2 size */ - scale_flag:1, /* scaled register */ - brk_flg:1; - }; - -struct mem_segs { - struct mem_wrd *seg; /* pointer (returned by calloc) to segment */ - unsigned long baseaddr; /* base load address from file headers */ - unsigned long endaddr; /* Ending address of segment */ - int flags; /* segment control flags (none defined 12/5/86) */ -}; - -#define MAXSEGS (10) /* max number of segment allowed */ -#define MEMSEGSIZE (sizeof(struct mem_segs))/* size of mem_segs structure */ - - -#define BRK_RD (0x01) /* break on memory read */ -#define BRK_WR (0x02) /* break on memory write */ -#define BRK_EXEC (0x04) /* break on execution */ -#define BRK_CNT (0x08) /* break on terminal count */ - - -struct mem_wrd { - struct IR_FIELDS opcode; /* simulator instruction break down */ - union { - unsigned long l; /* memory element break down */ - unsigned short s[2]; - unsigned char c[4]; - } mem; -}; - -#define MEMWRDSIZE (sizeof(struct mem_wrd)) /* size of each 32 bit memory model */ - -/* External declarations */ - -extern struct mem_segs memory[]; -extern struct PROCESSOR m78000; - -struct PROCESSOR { - unsigned WORD - ip, /* execute instruction pointer */ - vbr, /* vector base register */ - psr; /* processor status register */ - - WORD S1bus, /* source 1 */ - S2bus, /* source 2 */ - Dbus, /* destination */ - DAbus, /* data address bus */ - ALU, - Regs[REGs], /* data registers */ - time_left[REGs], /* max clocks before reg is available */ - wb_pri[REGs], /* writeback priority of reg */ - SFU0_regs[REGs], /* integer unit control regs */ - SFU1_regs[REGs], /* floating point control regs */ - Scoreboard[REGs], - Vbr; - unsigned WORD scoreboard, - Psw, - Tpsw; - FLAG jump_pending:1; /* waiting for a jump instr. */ - }; - -# define i26bit 1 /* size of immediate field */ -# define i16bit 2 -# define i10bit 3 - -/* Definitions for fields in psr */ - -# define mode 31 -# define rbo 30 -# define ser 29 -# define carry 28 -# define sf7m 11 -# define sf6m 10 -# define sf5m 9 -# define sf4m 8 -# define sf3m 7 -# define sf2m 6 -# define sf1m 5 -# define mam 4 -# define inm 3 -# define exm 2 -# define trm 1 -# define ovfm 0 - -#define MODEMASK (1<<(mode-1)) -# define SILENT 0 /* simulate without output to crt */ -# define VERBOSE 1 /* simulate in verbose mode */ -# define PR_INSTR 2 /* only print instructions */ - -# define RESET 16 /* reset phase */ - -# define PHASE1 0 /* data path phases */ -# define PHASE2 1 - -/* the 1 clock operations */ - -# define ADDU 1 -# define ADDC 2 -# define ADDUC 3 -# define ADD 4 - -# define SUBU ADD+1 -# define SUBB ADD+2 -# define SUBUB ADD+3 -# define SUB ADD+4 - -# define AND_ ADD+5 -# define OR ADD+6 -# define XOR ADD+7 -# define CMP ADD+8 - -/* the LOADS */ - -# define LDAB CMP+1 -# define LDAH CMP+2 -# define LDA CMP+3 -# define LDAD CMP+4 - -# define LDB LDAD+1 -# define LDH LDAD+2 -# define LD LDAD+3 -# define LDD LDAD+4 -# define LDBU LDAD+5 -# define LDHU LDAD+6 - -/* the STORES */ - -# define STB LDHU+1 -# define STH LDHU+2 -# define ST LDHU+3 -# define STD LDHU+4 - -/* the exchange */ - -# define XMEMBU LDHU+5 -# define XMEM LDHU+6 - -/* the branches */ -# define JSR STD+1 -# define BSR STD+2 -# define BR STD+3 -# define JMP STD+4 -# define BB1 STD+5 -# define BB0 STD+6 -# define RTN STD+7 -# define BCND STD+8 - -/* the TRAPS */ -# define TB1 BCND+1 -# define TB0 BCND+2 -# define TCND BCND+3 -# define RTE BCND+4 -# define TBND BCND+5 - -/* the MISC instructions */ -# define MUL TBND + 1 -# define DIV MUL +2 -# define DIVU MUL +3 -# define MASK MUL +4 -# define FF0 MUL +5 -# define FF1 MUL +6 -# define CLR MUL +7 -# define SET MUL +8 -# define EXT MUL +9 -# define EXTU MUL +10 -# define MAK MUL +11 -# define ROT MUL +12 - -/* control register manipulations */ - -# define LDCR ROT +1 -# define STCR ROT +2 -# define XCR ROT +3 - -# define FLDCR ROT +4 -# define FSTCR ROT +5 -# define FXCR ROT +6 - - -# define NOP XCR +1 - -/* floating point instructions */ - -# define FADD NOP +1 -# define FSUB NOP +2 -# define FMUL NOP +3 -# define FDIV NOP +4 -# define FSQRT NOP +5 -# define FCMP NOP +6 -# define FIP NOP +7 -# define FLT NOP +8 -# define INT NOP +9 -# define NINT NOP +10 -# define TRNC NOP +11 -# define FLDC NOP +12 -# define FSTC NOP +13 -# define FXC NOP +14 - -# define UEXT(src,off,wid) ((((unsigned int)(src))>>(off)) & ((1<<(wid)) - 1)) -# define SEXT(src,off,wid) (((((int)(src))<<(32-((off)+(wid)))) >>(32-(wid))) ) -# define MAKE(src,off,wid) \ - ((((unsigned int)(src)) & ((1<<(wid)) - 1)) << (off)) - -# define opword(n) (unsigned long) (memaddr->mem.l) - -/* Constants and Masks */ - -#define SFU0 0x80000000 -#define SFU1 0x84000000 -#define SFU7 0x9c000000 -#define RRI10 0xf0000000 -#define RRR 0xf4000000 -#define SFUMASK 0xfc00ffe0 -#define RRRMASK 0xfc00ffe0 -#define RRI10MASK 0xfc00fc00 -#define DEFMASK 0xfc000000 -#define CTRL 0x0000f000 -#define CTRLMASK 0xfc00f800 - -/* Operands types */ - -enum operand_type { - HEX = 1, - REG = 2, - CONT = 3, - IND = 3, - BF = 4, - REGSC = 5 /* scaled register */, - CRREG = 6 /* control register */, - FCRREG = 7 /* floating point control register */, - PCREL = 8, - CONDMASK = 9, - XREG = 10, /* extended register */ - DEC = 11, /* decimal */ -}; - -/* Hashing Specification */ - -#define HASHVAL 79 - -/* Type definitions */ - -typedef unsigned int UINT; - -/* Structure templates */ - -#if never -typedef struct { - unsigned int offset:5; - unsigned int width:6; - unsigned int type:5; -} OPSPEC; -#endif - -typedef struct { - unsigned int offset; - unsigned int width; - enum operand_type type; -} OPSPEC; - - struct SIM_FLAGS { - int ltncy, /* latency (max number of clocks needed to execute) */ - extime, /* execution time (min number of clocks needed to execute) */ - wb_pri; /* writeback slot priority */ - unsigned op:OP, /* simulator version of opcode */ - imm_flags:2, /* 10,16 or 26 bit immediate flags */ - rs1_used:1, /* register source 1 used */ - rs2_used:1, /* register source 2 used */ - rsd_used:1, /* register source/dest used */ - c_flag:1, /* complement */ - u_flag:1, /* upper half word */ - n_flag:1, /* execute next */ - wb_flag:1, /* uses writeback slot */ - dest_64:1, /* double precision dest */ - s1_64:1, /* double precision source 1 */ - s2_64:1, /* double precision source 2 */ - scale_flag:1; /* register is scaled */ -}; - -typedef struct INSTRUCTAB { - unsigned int opcode; - char *mnemonic; - OPSPEC op1,op2,op3; - struct SIM_FLAGS flgs; - struct INSTRUCTAB *next; -} INSTAB; - - -#define NO_OPERAND {0,0,0} - -/* Opcode Mnemonic Op 1 Spec Op 2 Spec Op 3 Spec Simflags Next */ - -static INSTAB instructions[] = { - {0xf400c800,"jsr ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {2,2,NA,JSR , 0,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xf400cc00,"jsr.n ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {1,1,NA,JSR , 0,0,1,0,0,0,1,1,0,0,0,0}, NULL }, - {0xf400c000,"jmp ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {2,2,NA,JMP , 0,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xf400c400,"jmp.n ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {1,1,NA,JMP , 0,0,1,0,0,0,1,1,0,0,0,0}, NULL }, - {0xc8000000,"bsr ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {2,2,NA,BSR , i26bit,0,0,0,0,0,0,1,0,0,0,0}, NULL }, - {0xcc000000,"bsr.n ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {1,1,NA,BSR , i26bit,0,0,0,0,0,1,1,0,0,0,0}, NULL }, - {0xc0000000,"br ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {2,2,NA,BR , i26bit,0,0,0,0,0,0,1,0,0,0,0}, NULL }, - {0xc4000000,"br.n ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {1,1,NA,BR , i26bit,0,0,0,0,0,1,1,0,0,0,0}, NULL }, - {0xd0000000,"bb0 ",{21,5,HEX} ,{16,5,REG} ,{0,16,PCREL},{2,2,NA,BB0, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xd4000000,"bb0.n ",{21,5,HEX} ,{16,5,REG} ,{0,16,PCREL},{1,1,NA,BB0, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL }, - {0xd8000000,"bb1 ",{21,5,HEX},{16,5,REG} ,{0,16,PCREL},{2,2,NA,BB1, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xdc000000,"bb1.n ",{21,5,HEX},{16,5,REG} ,{0,16,PCREL},{1,1,NA,BB1, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL }, - {0xf000d000,"tb0 ",{21,5,HEX} ,{16,5,REG} ,{0,10,HEX}, {2,2,NA,TB0 , i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xf000d800,"tb1 ",{21,5,HEX} ,{16,5,REG} ,{0,10,HEX}, {2,2,NA,TB1 , i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xe8000000,"bcnd ",{21,5,CONDMASK},{16,5,REG},{0,16,PCREL},{2,2,NA,BCND, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xec000000,"bcnd.n ",{21,5,CONDMASK},{16,5,REG},{0,16,PCREL},{1,1,NA,BCND, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL }, - {0xf000e800,"tcnd ",{21,5,CONDMASK},{16,5,REG},{0,10,HEX}, {2,2,NA,TCND, i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xf8000000,"tbnd ",{16,5,REG} ,{0,16,HEX} ,NO_OPERAND , {2,2,NA,TBND, i10bit,1,0,0,0,0,0,1,0,0,0,0}, NULL }, - {0xf400f800,"tbnd ",{16,5,REG} ,{0,5,REG} ,NO_OPERAND , {2,2,NA,TBND, 0,1,1,0,0,0,0,1,0,0,0,0}, NULL }, - {0xf400fc00,"rte ",NO_OPERAND ,NO_OPERAND ,NO_OPERAND , {2,2,NA,RTE , 0,0,0,0,0,0,0,1,0,0,0,0}, NULL }, - {0x1c000000,"ld.b ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDB ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001c00,"ld.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDB , 0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0x0c000000,"ld.bu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDBU, i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4000c00,"ld.bu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDBU ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0x18000000,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDH ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001800,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDH ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001a00,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDH ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL }, - {0x08000000,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDHU, i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4000800,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDHU ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4000a00,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDHU ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL }, - {0x14000000,"ld ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LD ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001400,"ld ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001600,"ld ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL }, - {0x10000000,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDD ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001000,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001200,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL }, - {0xf4001500,"ld.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4001700,"ld.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL }, - {0x2c000000,"st.b ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STB ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4002c00,"st.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STB ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0x28000000,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STH ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4002800,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STH ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4002a00,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,STH ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL }, - {0x24000000,"st ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,ST ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL }, - {0xf4002400,"st ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0xf4002600,"st ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL }, - {0x20000000,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STD ,i16bit,0,1,0,0,0,0,1,0,0,0,0} ,NULL }, - {0xf4002000,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STD ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0xf4002200,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,STD ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL }, - {0xf4002500,"st.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0xf4002700,"st.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL }, -/* m88100 only: - {0x00000000,"xmem.bu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,XMEMBU ,i16bit,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - */ - {0xf4000000,"xmem.bu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, -/* m88100 only: - {0x04000000,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,XMEM ,i16bit,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - */ - {0xf4000400,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0xf4000600,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL }, - {0xf4000500,"xmem.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0xf4000700,"xmem.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL }, -/* m88100 only: - {0xf4003e00,"lda.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL }, - */ - {0xf4003e00,"lda.x ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL }, - {0xf4003a00,"lda.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL }, - {0xf4003600,"lda ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDA , 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL }, - {0xf4003200,"lda.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAD, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL }, - - {0x80004000,"ldcr ",{21,5,REG} ,{5,6,CRREG} ,NO_OPERAND ,{1,1,PINT,LDCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x80008000,"stcr ",{16,5,REG} ,{5,6,CRREG} ,NO_OPERAND ,{1,1,PINT,STCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x8000c000,"xcr ",{21,5,REG} ,{16,5,REG} ,{5,6,CRREG},{1,1,PINT,XCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - - {0xf4006000,"addu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006200,"addu.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006100,"addu.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006300,"addu.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006400,"subu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006600,"subu.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006500,"subu.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006700,"subu.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006800,"divu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {32,32,PINT,DIVU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4006900,"divu.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, NULL }, - {0xf4006e00,"muls ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, NULL }, - {0xf4006c00,"mulu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,4,PINT,MUL, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007000,"add ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007200,"add.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007100,"add.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007300,"add.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007400,"sub ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007600,"sub.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007500,"sub.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007700,"sub.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007800,"divs ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {32,32,PINT,DIV , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4007c00,"cmp ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,CMP, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - - {0x60000000,"addu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,ADDU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x64000000,"subu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,SUBU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - - {0x68000000,"divu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {32,32,PINT,DIVU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x6c000000,"mulu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {4,1,PINT,MUL, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x70000000,"add ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,ADD, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x74000000,"sub ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,SUB, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x78000000,"divs ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {32,32,PINT,DIV, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x7c000000,"cmp ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,CMP, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - - {0xf4004000,"and ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,AND_ ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4004400,"and.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,AND_ ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL }, - {0xf4005800,"or ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,OR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4005c00,"or.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,OR ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL }, - {0xf4005000,"xor ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,XOR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4005400,"xor.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,XOR ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL }, - {0x40000000,"and ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,AND_ ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x44000000,"and.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,AND_ ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL }, - {0x58000000,"or ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,OR ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x5c000000,"or.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,OR ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL }, - {0x50000000,"xor ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,XOR ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x54000000,"xor.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,XOR ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL }, - {0x48000000,"mask ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,MASK ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0x4c000000,"mask.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,MASK ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL }, - {0xf400ec00,"ff0 ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {1,1,PINT,FF0 ,0,0,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf400e800,"ff1 ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {1,1,PINT,FF1 ,0,0,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf0008000,"clr ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,CLR ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf0008800,"set ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,SET ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf0009000,"ext ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,EXT ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf0009800,"extu ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,EXTU ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf000a000,"mak ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,MAK ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf000a800,"rot ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,ROT ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4008000,"clr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,CLR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4008800,"set ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SET ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4009000,"ext ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,EXT ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf4009800,"extu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,EXTU ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf400a000,"mak ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,MAK ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - {0xf400a800,"rot ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ROT ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL }, - - {0x84002800,"fadd.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FADD ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84002880,"fadd.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL }, - {0x84002a00,"fadd.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL }, - {0x84002a80,"fadd.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL }, - {0x84002820,"fadd.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x840028a0,"fadd.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL }, - {0x84002a20,"fadd.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL }, - {0x84002aa0,"fadd.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL }, - {0x84003000,"fsub.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84003080,"fsub.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL }, - {0x84003200,"fsub.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL }, - {0x84003280,"fsub.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL }, - {0x84003020,"fsub.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x840030a0,"fsub.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL }, - {0x84003220,"fsub.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL }, - {0x840032a0,"fsub.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL }, - {0x84000000,"fmul.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84000080,"fmul.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL }, - {0x84000200,"fmul.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL }, - {0x84000280,"fmul.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL }, - {0x84000020,"fmul.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x840000a0,"fmul.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL }, - {0x84000220,"fmul.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL }, - {0x840002a0,"fmul.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL }, - {0x84007000,"fdiv.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {30,30,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84007080,"fdiv.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL }, - {0x84007200,"fdiv.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL }, - {0x84007280,"fdiv.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL }, - {0x84007020,"fdiv.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x840070a0,"fdiv.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL }, - {0x84007220,"fdiv.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL }, - {0x840072a0,"fdiv.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL }, - {0x84007800,"fsqrt.ss ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84007820,"fsqrt.sd ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84007880,"fsqrt.ds ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x840078a0,"fsqrt.dd ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,FLT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x84003800,"fcmp.ss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84003880,"fcmp.sd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL }, - {0x84003a00,"fcmp.ds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x84003a80,"fcmp.dd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL }, - {0x84002000,"flt.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84002020,"flt.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,FLT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x84004800,"int.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,INT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84004880,"int.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,INT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x84005000,"nint.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,INT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84005080,"nint.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,INT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL }, - {0x84005800,"trnc.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,TRNC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x84005880,"trnc.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,TRNC ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL }, - - {0x80004800,"fldcr ",{21,5,REG} ,{5,6,FCRREG} ,NO_OPERAND , {1,1,PFLT,FLDC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x80008800,"fstcr ",{16,5,REG} ,{5,6,FCRREG} ,NO_OPERAND , {1,1,PFLT,FSTC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - {0x8000c800,"fxcr ",{21,5,REG} ,{16,5,REG} ,{5,6,FCRREG} , {1,1,PFLT,FXC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL }, - -/* The following are new for the 88110. */ - - {0x8400aaa0,"fadd.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400aa80,"fadd.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400aac0,"fadd.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400aa20,"fadd.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400aa00,"fadd.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400aa40,"fadd.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ab20,"fadd.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ab00,"fadd.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ab40,"fadd.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a8a0,"fadd.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a880,"fadd.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a8c0,"fadd.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a820,"fadd.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a800,"fadd.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a840,"fadd.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a920,"fadd.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a900,"fadd.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400a940,"fadd.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400aca0,"fadd.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ac80,"fadd.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400acc0,"fadd.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ac20,"fadd.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ac00,"fadd.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ac40,"fadd.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ad20,"fadd.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ad00,"fadd.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ad40,"fadd.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400ba80,"fcmp.sdd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ba00,"fcmp.sds ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bb00,"fcmp.sdx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b880,"fcmp.ssd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b800,"fcmp.sss ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b900,"fcmp.ssx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bc80,"fcmp.sxd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bc00,"fcmp.sxs ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bd00,"fcmp.sxx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400baa0,"fcmpu.sdd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400ba20,"fcmpu.sds ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bb20,"fcmpu.sdx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b8a0,"fcmpu.ssd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b820,"fcmpu.sss ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b920,"fcmpu.ssx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bca0,"fcmpu.sxd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bc20,"fcmpu.sxs ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400bd20,"fcmpu.sxx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x84000820,"fcvt.sd ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84000880,"fcvt.ds ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x84008880,"fcvt.ds ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x840088c0,"fcvt.dx ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008820,"fcvt.sd ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008840,"fcvt.sx ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008920,"fcvt.xd ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008900,"fcvt.xs ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400f2a0,"fdiv.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f280,"fdiv.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f2c0,"fdiv.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f220,"fdiv.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f200,"fdiv.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f240,"fdiv.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f320,"fdiv.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f300,"fdiv.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f340,"fdiv.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f0a0,"fdiv.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f080,"fdiv.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f0c0,"fdiv.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f020,"fdiv.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f000,"fdiv.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f040,"fdiv.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f120,"fdiv.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f100,"fdiv.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f140,"fdiv.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f4a0,"fdiv.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f480,"fdiv.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f4c0,"fdiv.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f420,"fdiv.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f400,"fdiv.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f440,"fdiv.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f520,"fdiv.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f500,"fdiv.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f540,"fdiv.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x84002220,"flt.ds ",{21,5,XREG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84002200,"flt.ss ",{21,5,XREG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84002240,"flt.xs ",{21,5,XREG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x840082a0,"fmul.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008280,"fmul.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x840082c0,"fmul.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008220,"fmul.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008200,"fmul.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008240,"fmul.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008320,"fmul.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008300,"fmul.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008340,"fmul.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x840080a0,"fmul.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008080,"fmul.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x840080c0,"fmul.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008020,"fmul.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008000,"fmul.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008040,"fmul.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008120,"fmul.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008100,"fmul.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008140,"fmul.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x840084a0,"fmul.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008480,"fmul.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x840084c0,"fmul.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008420,"fmul.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008400,"fmul.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008440,"fmul.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008520,"fmul.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008500,"fmul.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84008540,"fmul.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400f8a0,"fsqrt.dd ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f880,"fsqrt.ds ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f8c0,"fsqrt.dx ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f820,"fsqrt.sd ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f800,"fsqrt.ss ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f840,"fsqrt.sx ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f920,"fsqrt.xd ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f900,"fsqrt.xs ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400f940,"fsqrt.xx ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400b2a0,"fsub.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b280,"fsub.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b2c0,"fsub.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b220,"fsub.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b200,"fsub.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b240,"fsub.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b320,"fsub.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b300,"fsub.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b340,"fsub.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b0a0,"fsub.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b080,"fsub.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b0c0,"fsub.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b020,"fsub.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b000,"fsub.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b040,"fsub.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b120,"fsub.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b100,"fsub.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b140,"fsub.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b4a0,"fsub.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b480,"fsub.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b4c0,"fsub.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b420,"fsub.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b400,"fsub.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b440,"fsub.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b520,"fsub.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b500,"fsub.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400b540,"fsub.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400fc00,"illop", {0,2,DEC}, NO_OPERAND, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400c800,"int.ss ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400c880,"int.sd ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400c900,"int.sx ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x04000000,"ld ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x00000000,"ld.d ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x3c000000,"ld.x ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0xf0001400,"ld ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001000,"ld.d ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001800,"ld.x ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001500,"ld.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001100,"ld.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001900,"ld.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0xf0001600,"ld ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001200,"ld.d ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001a00,"ld.x ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001700,"ld.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001300,"ld.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0001b00,"ld.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400c000,"mov.s ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400c080,"mov.d ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84004200,"mov.s ", {21,5,XREG}, {0,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x84004280,"mov.d ", {21,5,XREG}, {0,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400c300,"mov ", {21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0xf4006d00,"mulu.d ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400d080,"nint.sd ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400d000,"nint.ss ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400d100,"nint.sx ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x88002020,"padd.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88002040,"padd.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88002060,"padd ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x880021e0,"padds.s ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880021a0,"padds.s.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880021c0,"padds.s.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880020e0,"padds.u ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880020a0,"padds.u.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880020c0,"padds.u.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88002160,"padds.us ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88002120,"padds.us.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88002140,"padds.us.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x88003860,"pcmp ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x88000000,"pmul ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x88006260,"ppack.16 ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88006240,"ppack.16.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88006460,"ppack.32 ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88006420,"ppack.32.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88006440,"ppack.32.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88006160,"ppack.8 ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x88007200,"prot ", {21,5,REG}, {16,5,REG}, {5,6,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88007800,"prot ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x88003020,"psub.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88003040,"psub.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88003060,"psub ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x880031e0,"psubs.s ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880031a0,"psubs.s.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880031c0,"psubs.s.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880030e0,"psubs.u ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880030a0,"psubs.u.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x880030c0,"psubs.u.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88003160,"psubs.us ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88003120,"psubs.us.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88003140,"psubs.us.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x88006800,"punpk.n ", {21,5,REG}, {16,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x88006820,"punpk.b ", {21,5,REG}, {16,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x34000000,"st ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x30000000,"st.d ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x38000000,"st.x ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0xf4002c80,"st.b.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002880,"st.h.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002480,"st.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002080,"st.d.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002d80,"st.b.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002980,"st.h.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002580,"st.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002180,"st.d.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0xf0002400,"st ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002000,"st.d ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002100,"st.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002180,"st.d.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002080,"st.d.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002500,"st.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002580,"st.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002480,"st.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002800,"st.x ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002900,"st.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002980,"st.x.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002880,"st.x.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0xf4002f80,"st.b.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002e80,"st.b.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002380,"st.d.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002280,"st.d.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002b80,"st.h.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002a80,"st.h.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002780,"st.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf4002680,"st.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0xf0002600,"st ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002200,"st.d ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002300,"st.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002380,"st.d.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002280,"st.d.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002700,"st.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002780,"st.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002680,"st.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002a00,"st.x ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002b00,"st.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002b80,"st.x.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0xf0002a80,"st.x.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - - {0x8400d880,"trnc.sd ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400d800,"trnc.ss ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - {0x8400d900,"trnc.sx ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL }, - -}; - -/* - * Local Variables: - * fill-column: 131 - * End: - */ diff --git a/contrib/gdb/include/opcode/mips.h b/contrib/gdb/include/opcode/mips.h deleted file mode 100644 index 14ceec96119..00000000000 --- a/contrib/gdb/include/opcode/mips.h +++ /dev/null @@ -1,481 +0,0 @@ -/* mips.h. Mips opcode list for GDB, the GNU debugger. - Copyright 1993, 1995 Free Software Foundation, Inc. - Contributed by Ralph Campbell and OSF - Commented and modified by Ian Lance Taylor, Cygnus Support - -This file is part of GDB, GAS, and the GNU binutils. - -GDB, GAS, and the GNU binutils are free software; you can redistribute -them and/or modify them under the terms of the GNU General Public -License as published by the Free Software Foundation; either version -1, or (at your option) any later version. - -GDB, GAS, and the GNU binutils are distributed in the hope that they -will be useful, but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See -the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this file; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* These are bit masks and shift counts to use to access the various - fields of an instruction. To retrieve the X field of an - instruction, use the expression - (i >> OP_SH_X) & OP_MASK_X - To set the same field (to j), use - i = (i &~ (OP_MASK_X << OP_SH_X)) | (j << OP_SH_X) - - Make sure you use fields that are appropriate for the instruction, - of course. - - The 'i' format uses OP, RS, RT and IMMEDIATE. - - The 'j' format uses OP and TARGET. - - The 'r' format uses OP, RS, RT, RD, SHAMT and FUNCT. - - The 'b' format uses OP, RS, RT and DELTA. - - The floating point 'i' format uses OP, RS, RT and IMMEDIATE. - - The floating point 'r' format uses OP, FMT, FT, FS, FD and FUNCT. - - A breakpoint instruction uses OP, CODE and SPEC (10 bits of the - breakpoint instruction are not defined; Kane says the breakpoint - code field in BREAK is 20 bits; yet MIPS assemblers and debuggers - only use ten bits). - - The syscall instruction uses SYSCALL. - - The general coprocessor instructions use COPZ. */ - -#define OP_MASK_OP 0x3f -#define OP_SH_OP 26 -#define OP_MASK_RS 0x1f -#define OP_SH_RS 21 -#define OP_MASK_FR 0x1f -#define OP_SH_FR 21 -#define OP_MASK_FMT 0x1f -#define OP_SH_FMT 21 -#define OP_MASK_BCC 0x7 -#define OP_SH_BCC 18 -#define OP_MASK_CODE 0x3ff -#define OP_SH_CODE 16 -#define OP_MASK_RT 0x1f -#define OP_SH_RT 16 -#define OP_MASK_FT 0x1f -#define OP_SH_FT 16 -#define OP_MASK_CACHE 0x1f -#define OP_SH_CACHE 16 -#define OP_MASK_RD 0x1f -#define OP_SH_RD 11 -#define OP_MASK_FS 0x1f -#define OP_SH_FS 11 -#define OP_MASK_PREFX 0x1f -#define OP_SH_PREFX 11 -#define OP_MASK_CCC 0x7 -#define OP_SH_CCC 8 -#define OP_MASK_SYSCALL 0xfffff -#define OP_SH_SYSCALL 6 -#define OP_MASK_SHAMT 0x1f -#define OP_SH_SHAMT 6 -#define OP_MASK_FD 0x1f -#define OP_SH_FD 6 -#define OP_MASK_TARGET 0x3ffffff -#define OP_SH_TARGET 0 -#define OP_MASK_COPZ 0x1ffffff -#define OP_SH_COPZ 0 -#define OP_MASK_IMMEDIATE 0xffff -#define OP_SH_IMMEDIATE 0 -#define OP_MASK_DELTA 0xffff -#define OP_SH_DELTA 0 -#define OP_MASK_FUNCT 0x3f -#define OP_SH_FUNCT 0 -#define OP_MASK_SPEC 0x3f -#define OP_SH_SPEC 0 - -/* This structure holds information for a particular instruction. */ - -struct mips_opcode -{ - /* The name of the instruction. */ - const char *name; - /* A string describing the arguments for this instruction. */ - const char *args; - /* The basic opcode for the instruction. When assembling, this - opcode is modified by the arguments to produce the actual opcode - that is used. If pinfo is INSN_MACRO, then this is instead the - ISA level of the macro (0 or 1 is always supported, 2 is ISA 2, - etc.). */ - unsigned long match; - /* If pinfo is not INSN_MACRO, then this is a bit mask for the - relevant portions of the opcode when disassembling. If the - actual opcode anded with the match field equals the opcode field, - then we have found the correct instruction. If pinfo is - INSN_MACRO, then this field is the macro identifier. */ - unsigned long mask; - /* For a macro, this is INSN_MACRO. Otherwise, it is a collection - of bits describing the instruction, notably any relevant hazard - information. */ - unsigned long pinfo; -}; - -/* These are the characters which may appears in the args field of an - instruction. They appear in the order in which the fields appear - when the instruction is used. Commas and parentheses in the args - string are ignored when assembling, and written into the output - when disassembling. - - Each of these characters corresponds to a mask field defined above. - - "<" 5 bit shift amount (OP_*_SHAMT) - ">" shift amount between 32 and 63, stored after subtracting 32 (OP_*_SHAMT) - "a" 26 bit target address (OP_*_TARGET) - "b" 5 bit base register (OP_*_RS) - "c" 10 bit breakpoint code (OP_*_CODE) - "d" 5 bit destination register specifier (OP_*_RD) - "h" 5 bit prefx hint (OP_*_PREFX) - "i" 16 bit unsigned immediate (OP_*_IMMEDIATE) - "j" 16 bit signed immediate (OP_*_DELTA) - "k" 5 bit cache opcode in target register position (OP_*_CACHE) - "o" 16 bit signed offset (OP_*_DELTA) - "p" 16 bit PC relative branch target address (OP_*_DELTA) - "r" 5 bit same register used as both source and target (OP_*_RS) - "s" 5 bit source register specifier (OP_*_RS) - "t" 5 bit target register (OP_*_RT) - "u" 16 bit upper 16 bits of address (OP_*_IMMEDIATE) - "v" 5 bit same register used as both source and destination (OP_*_RS) - "w" 5 bit same register used as both target and destination (OP_*_RT) - "C" 25 bit coprocessor function code (OP_*_COPZ) - "B" 20 bit syscall function code (OP_*_SYSCALL) - "x" accept and ignore register name - "z" must be zero register - - Floating point instructions: - "D" 5 bit destination register (OP_*_FD) - "M" 3 bit compare condition code (OP_*_CCC) (only used for mips4 and up) - "N" 3 bit branch condition code (OP_*_BCC) (only used for mips4 and up) - "S" 5 bit fs source 1 register (OP_*_FS) - "T" 5 bit ft source 2 register (OP_*_FT) - "R" 5 bit fr source 3 register (OP_*_FR) - "V" 5 bit same register used as floating source and destination (OP_*_FS) - "W" 5 bit same register used as floating target and destination (OP_*_FT) - - Coprocessor instructions: - "E" 5 bit target register (OP_*_RT) - "G" 5 bit destination register (OP_*_RD) - - Macro instructions: - "A" General 32 bit expression - "I" 32 bit immediate - "F" 64 bit floating point constant in .rdata - "L" 64 bit floating point constant in .lit8 - "f" 32 bit floating point constant - "l" 32 bit floating point constant in .lit4 -*/ - -/* These are the bits which may be set in the pinfo field of an - instructions, if it is not equal to INSN_MACRO. */ - -/* Modifies the general purpose register in OP_*_RD. */ -#define INSN_WRITE_GPR_D 0x00000001 -/* Modifies the general purpose register in OP_*_RT. */ -#define INSN_WRITE_GPR_T 0x00000002 -/* Modifies general purpose register 31. */ -#define INSN_WRITE_GPR_31 0x00000004 -/* Modifies the floating point register in OP_*_FD. */ -#define INSN_WRITE_FPR_D 0x00000008 -/* Modifies the floating point register in OP_*_FS. */ -#define INSN_WRITE_FPR_S 0x00000010 -/* Modifies the floating point register in OP_*_FT. */ -#define INSN_WRITE_FPR_T 0x00000020 -/* Reads the general purpose register in OP_*_RS. */ -#define INSN_READ_GPR_S 0x00000040 -/* Reads the general purpose register in OP_*_RT. */ -#define INSN_READ_GPR_T 0x00000080 -/* Reads the floating point register in OP_*_FS. */ -#define INSN_READ_FPR_S 0x00000100 -/* Reads the floating point register in OP_*_FT. */ -#define INSN_READ_FPR_T 0x00000200 -/* Reads the floating point register in OP_*_FR. */ -#define INSN_READ_FPR_R 0x00000400 -/* Modifies coprocessor condition code. */ -#define INSN_WRITE_COND_CODE 0x00000800 -/* Reads coprocessor condition code. */ -#define INSN_READ_COND_CODE 0x00001000 -/* TLB operation. */ -#define INSN_TLB 0x00002000 -/* Reads coprocessor register other than floating point register. */ -#define INSN_COP 0x00004000 -/* Instruction loads value from memory, requiring delay. */ -#define INSN_LOAD_MEMORY_DELAY 0x00008000 -/* Instruction loads value from coprocessor, requiring delay. */ -#define INSN_LOAD_COPROC_DELAY 0x00010000 -/* Instruction has unconditional branch delay slot. */ -#define INSN_UNCOND_BRANCH_DELAY 0x00020000 -/* Instruction has conditional branch delay slot. */ -#define INSN_COND_BRANCH_DELAY 0x00040000 -/* Conditional branch likely: if branch not taken, insn nullified. */ -#define INSN_COND_BRANCH_LIKELY 0x00080000 -/* Moves to coprocessor register, requiring delay. */ -#define INSN_COPROC_MOVE_DELAY 0x00100000 -/* Loads coprocessor register from memory, requiring delay. */ -#define INSN_COPROC_MEMORY_DELAY 0x00200000 -/* Reads the HI register. */ -#define INSN_READ_HI 0x00400000 -/* Reads the LO register. */ -#define INSN_READ_LO 0x00800000 -/* Modifies the HI register. */ -#define INSN_WRITE_HI 0x01000000 -/* Modifies the LO register. */ -#define INSN_WRITE_LO 0x02000000 -/* Takes a trap (easier to keep out of delay slot). */ -#define INSN_TRAP 0x04000000 -/* Instruction stores value into memory. */ -#define INSN_STORE_MEMORY 0x08000000 -/* MIPS ISA field--CPU level at which insn is supported. */ -#define INSN_ISA 0x70000000 -/* MIPS ISA 2 instruction (R6000 or R4000). */ -#define INSN_ISA2 0x10000000 -/* MIPS ISA 3 instruction (R4000). */ -#define INSN_ISA3 0x20000000 -/* MIPS R4650 instruction. */ -#define INSN_4650 0x30000000 -/* MIPS ISA 4 instruction (R8000). */ -#define INSN_ISA4 0x40000000 -/* LSI R4010 instruction. */ -#define INSN_4010 0x50000000 -/* NEC VR4100 instruction. */ -#define INSN_4100 0x60000000 - -/* Instruction is actually a macro. It should be ignored by the - disassembler, and requires special treatment by the assembler. */ -#define INSN_MACRO 0xffffffff - -/* This is a list of macro expanded instructions. - * - * _I appended means immediate - * _A appended means address - * _AB appended means address with base register - * _D appended means 64 bit floating point constant - * _S appended means 32 bit floating point constant - */ -enum { - M_ABS, - M_ADD_I, - M_ADDU_I, - M_AND_I, - M_BEQ_I, - M_BEQL_I, - M_BGE, - M_BGEL, - M_BGE_I, - M_BGEL_I, - M_BGEU, - M_BGEUL, - M_BGEU_I, - M_BGEUL_I, - M_BGT, - M_BGTL, - M_BGT_I, - M_BGTL_I, - M_BGTU, - M_BGTUL, - M_BGTU_I, - M_BGTUL_I, - M_BLE, - M_BLEL, - M_BLE_I, - M_BLEL_I, - M_BLEU, - M_BLEUL, - M_BLEU_I, - M_BLEUL_I, - M_BLT, - M_BLTL, - M_BLT_I, - M_BLTL_I, - M_BLTU, - M_BLTUL, - M_BLTU_I, - M_BLTUL_I, - M_BNE_I, - M_BNEL_I, - M_DABS, - M_DADD_I, - M_DADDU_I, - M_DDIV_3, - M_DDIV_3I, - M_DDIVU_3, - M_DDIVU_3I, - M_DIV_3, - M_DIV_3I, - M_DIVU_3, - M_DIVU_3I, - M_DLA_AB, - M_DLI, - M_DMUL, - M_DMUL_I, - M_DMULO, - M_DMULO_I, - M_DMULOU, - M_DMULOU_I, - M_DREM_3, - M_DREM_3I, - M_DREMU_3, - M_DREMU_3I, - M_DSUB_I, - M_DSUBU_I, - M_J_A, - M_JAL_1, - M_JAL_2, - M_JAL_A, - M_L_DOB, - M_L_DAB, - M_LA_AB, - M_LB_A, - M_LB_AB, - M_LBU_A, - M_LBU_AB, - M_LD_A, - M_LD_OB, - M_LD_AB, - M_LDC1_AB, - M_LDC2_AB, - M_LDC3_AB, - M_LDL_AB, - M_LDR_AB, - M_LH_A, - M_LH_AB, - M_LHU_A, - M_LHU_AB, - M_LI, - M_LI_D, - M_LI_DD, - M_LI_S, - M_LI_SS, - M_LL_AB, - M_LLD_AB, - M_LS_A, - M_LW_A, - M_LW_AB, - M_LWC0_A, - M_LWC0_AB, - M_LWC1_A, - M_LWC1_AB, - M_LWC2_A, - M_LWC2_AB, - M_LWC3_A, - M_LWC3_AB, - M_LWL_A, - M_LWL_AB, - M_LWR_A, - M_LWR_AB, - M_LWU_AB, - M_MUL, - M_MUL_I, - M_MULO, - M_MULO_I, - M_MULOU, - M_MULOU_I, - M_NOR_I, - M_OR_I, - M_REM_3, - M_REM_3I, - M_REMU_3, - M_REMU_3I, - M_ROL, - M_ROL_I, - M_ROR, - M_ROR_I, - M_S_DA, - M_S_DOB, - M_S_DAB, - M_S_S, - M_SC_AB, - M_SCD_AB, - M_SD_A, - M_SD_OB, - M_SD_AB, - M_SDC1_AB, - M_SDC2_AB, - M_SDC3_AB, - M_SDL_AB, - M_SDR_AB, - M_SEQ, - M_SEQ_I, - M_SGE, - M_SGE_I, - M_SGEU, - M_SGEU_I, - M_SGT, - M_SGT_I, - M_SGTU, - M_SGTU_I, - M_SLE, - M_SLE_I, - M_SLEU, - M_SLEU_I, - M_SLT_I, - M_SLTU_I, - M_SNE, - M_SNE_I, - M_SB_A, - M_SB_AB, - M_SH_A, - M_SH_AB, - M_SW_A, - M_SW_AB, - M_SWC0_A, - M_SWC0_AB, - M_SWC1_A, - M_SWC1_AB, - M_SWC2_A, - M_SWC2_AB, - M_SWC3_A, - M_SWC3_AB, - M_SWL_A, - M_SWL_AB, - M_SWR_A, - M_SWR_AB, - M_SUB_I, - M_SUBU_I, - M_TEQ_I, - M_TGE_I, - M_TGEU_I, - M_TLT_I, - M_TLTU_I, - M_TNE_I, - M_TRUNCWD, - M_TRUNCWS, - M_ULD, - M_ULD_A, - M_ULH, - M_ULH_A, - M_ULHU, - M_ULHU_A, - M_ULW, - M_ULW_A, - M_USH, - M_USH_A, - M_USW, - M_USW_A, - M_USD, - M_USD_A, - M_XOR_I -}; - -/* The order of overloaded instructions matters. Label arguments and - register arguments look the same. Instructions that can have either - for arguments must apear in the correct order in this table for the - assembler to pick the right one. In other words, entries with - immediate operands must apear after the same instruction with - registers. - - Many instructions are short hand for other instructions (i.e., The - jal instruction is short for jalr ). */ - -extern const struct mips_opcode mips_opcodes[]; -extern const int bfd_mips_num_opcodes; -#define NUMOPCODES bfd_mips_num_opcodes diff --git a/contrib/gdb/include/opcode/np1.h b/contrib/gdb/include/opcode/np1.h deleted file mode 100644 index d23adc7566c..00000000000 --- a/contrib/gdb/include/opcode/np1.h +++ /dev/null @@ -1,422 +0,0 @@ -/* Print GOULD NPL instructions for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. - -This file is part of GDB. - -GDB is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GDB is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GDB; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -struct gld_opcode -{ - char *name; - unsigned long opcode; - unsigned long mask; - char *args; - int length; -}; - -/* We store four bytes of opcode for all opcodes because that - is the most any of them need. The actual length of an instruction - is always at least 2 bytes, and at most four. The length of the - instruction is based on the opcode. - - The mask component is a mask saying which bits must match - particular opcode in order for an instruction to be an instance - of that opcode. - - The args component is a string containing characters - that are used to format the arguments to the instruction. */ - -/* Kinds of operands: - r Register in first field - R Register in second field - b Base register in first field - B Base register in second field - v Vector register in first field - V Vector register in first field - A Optional address register (base register) - X Optional index register - I Immediate data (16bits signed) - O Offset field (16bits signed) - h Offset field (15bits signed) - d Offset field (14bits signed) - S Shift count field - - any other characters are printed as is... -*/ - -/* The assembler requires that this array be sorted as follows: - all instances of the same mnemonic must be consecutive. - All instances of the same mnemonic with the same number of operands - must be consecutive. - */ -struct gld_opcode gld_opcodes[] = -{ -{ "lb", 0xb4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "lnb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "lbs", 0xec080000, 0xfc080000, "r,xOA,X", 4 }, -{ "lh", 0xb4000001, 0xfc080001, "r,xOA,X", 4 }, -{ "lnh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "lw", 0xb4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lnw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "ld", 0xb4000002, 0xfc080002, "r,xOA,X", 4 }, -{ "lnd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "li", 0xf8000000, 0xfc7f0000, "r,I", 4 }, -{ "lpa", 0x50080000, 0xfc080000, "r,xOA,X", 4 }, -{ "la", 0x50000000, 0xfc080000, "r,xOA,X", 4 }, -{ "labr", 0x58080000, 0xfc080000, "b,xOA,X", 4 }, -{ "lbp", 0x90080000, 0xfc080000, "r,xOA,X", 4 }, -{ "lhp", 0x90000001, 0xfc080001, "r,xOA,X", 4 }, -{ "lwp", 0x90000000, 0xfc080000, "r,xOA,X", 4 }, -{ "ldp", 0x90000002, 0xfc080002, "r,xOA,X", 4 }, -{ "suabr", 0x58000000, 0xfc080000, "b,xOA,X", 4 }, -{ "lf", 0xbc000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lfbr", 0xbc080000, 0xfc080000, "b,xOA,X", 4 }, -{ "lwbr", 0x5c000000, 0xfc080000, "b,xOA,X", 4 }, -{ "stb", 0xd4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "sth", 0xd4000001, 0xfc080001, "r,xOA,X", 4 }, -{ "stw", 0xd4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "std", 0xd4000002, 0xfc080002, "r,xOA,X", 4 }, -{ "stf", 0xdc000000, 0xfc080000, "r,xOA,X", 4 }, -{ "stfbr", 0xdc080000, 0xfc080000, "b,xOA,X", 4 }, -{ "stwbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 }, -{ "zmb", 0xd8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "zmh", 0xd8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "zmw", 0xd8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "zmd", 0xd8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "stbp", 0x94080000, 0xfc080000, "r,xOA,X", 4 }, -{ "sthp", 0x94000001, 0xfc080001, "r,xOA,X", 4 }, -{ "stwp", 0x94000000, 0xfc080000, "r,xOA,X", 4 }, -{ "stdp", 0x94000002, 0xfc080002, "r,xOA,X", 4 }, -{ "lil", 0xf80b0000, 0xfc7f0000, "r,D", 4 }, -{ "lwsl1", 0xec000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lwsl2", 0xfc000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lwsl3", 0xfc080000, 0xfc080000, "r,xOA,X", 4 }, - -{ "lvb", 0xb0080000, 0xfc080000, "v,xOA,X", 4 }, -{ "lvh", 0xb0000001, 0xfc080001, "v,xOA,X", 4 }, -{ "lvw", 0xb0000000, 0xfc080000, "v,xOA,X", 4 }, -{ "lvd", 0xb0000002, 0xfc080002, "v,xOA,X", 4 }, -{ "liv", 0x3c040000, 0xfc0f0000, "v,R", 2 }, -{ "livf", 0x3c080000, 0xfc0f0000, "v,R", 2 }, -{ "stvb", 0xd0080000, 0xfc080000, "v,xOA,X", 4 }, -{ "stvh", 0xd0000001, 0xfc080001, "v,xOA,X", 4 }, -{ "stvw", 0xd0000000, 0xfc080000, "v,xOA,X", 4 }, -{ "stvd", 0xd0000002, 0xfc080002, "v,xOA,X", 4 }, - -{ "trr", 0x2c000000, 0xfc0f0000, "r,R", 2 }, -{ "trn", 0x2c040000, 0xfc0f0000, "r,R", 2 }, -{ "trnd", 0x2c0c0000, 0xfc0f0000, "r,R", 2 }, -{ "trabs", 0x2c010000, 0xfc0f0000, "r,R", 2 }, -{ "trabsd", 0x2c090000, 0xfc0f0000, "r,R", 2 }, -{ "trc", 0x2c030000, 0xfc0f0000, "r,R", 2 }, -{ "xcr", 0x28040000, 0xfc0f0000, "r,R", 2 }, -{ "cxcr", 0x2c060000, 0xfc0f0000, "r,R", 2 }, -{ "cxcrd", 0x2c0e0000, 0xfc0f0000, "r,R", 2 }, -{ "tbrr", 0x2c020000, 0xfc0f0000, "r,B", 2 }, -{ "trbr", 0x28030000, 0xfc0f0000, "b,R", 2 }, -{ "xcbr", 0x28020000, 0xfc0f0000, "b,B", 2 }, -{ "tbrbr", 0x28010000, 0xfc0f0000, "b,B", 2 }, - -{ "trvv", 0x28050000, 0xfc0f0000, "v,V", 2 }, -{ "trvvn", 0x2c050000, 0xfc0f0000, "v,V", 2 }, -{ "trvvnd", 0x2c0d0000, 0xfc0f0000, "v,V", 2 }, -{ "trvab", 0x2c070000, 0xfc0f0000, "v,V", 2 }, -{ "trvabd", 0x2c0f0000, 0xfc0f0000, "v,V", 2 }, -{ "cmpv", 0x14060000, 0xfc0f0000, "v,V", 2 }, -{ "expv", 0x14070000, 0xfc0f0000, "v,V", 2 }, -{ "mrvvlt", 0x10030000, 0xfc0f0000, "v,V", 2 }, -{ "mrvvle", 0x10040000, 0xfc0f0000, "v,V", 2 }, -{ "mrvvgt", 0x14030000, 0xfc0f0000, "v,V", 2 }, -{ "mrvvge", 0x14040000, 0xfc0f0000, "v,V", 2 }, -{ "mrvveq", 0x10050000, 0xfc0f0000, "v,V", 2 }, -{ "mrvvne", 0x10050000, 0xfc0f0000, "v,V", 2 }, -{ "mrvrlt", 0x100d0000, 0xfc0f0000, "v,R", 2 }, -{ "mrvrle", 0x100e0000, 0xfc0f0000, "v,R", 2 }, -{ "mrvrgt", 0x140d0000, 0xfc0f0000, "v,R", 2 }, -{ "mrvrge", 0x140e0000, 0xfc0f0000, "v,R", 2 }, -{ "mrvreq", 0x100f0000, 0xfc0f0000, "v,R", 2 }, -{ "mrvrne", 0x140f0000, 0xfc0f0000, "v,R", 2 }, -{ "trvr", 0x140b0000, 0xfc0f0000, "r,V", 2 }, -{ "trrv", 0x140c0000, 0xfc0f0000, "v,R", 2 }, - -{ "bu", 0x40000000, 0xff880000, "xOA,X", 4 }, -{ "bns", 0x70080000, 0xff880000, "xOA,X", 4 }, -{ "bnco", 0x70880000, 0xff880000, "xOA,X", 4 }, -{ "bge", 0x71080000, 0xff880000, "xOA,X", 4 }, -{ "bne", 0x71880000, 0xff880000, "xOA,X", 4 }, -{ "bunge", 0x72080000, 0xff880000, "xOA,X", 4 }, -{ "bunle", 0x72880000, 0xff880000, "xOA,X", 4 }, -{ "bgt", 0x73080000, 0xff880000, "xOA,X", 4 }, -{ "bnany", 0x73880000, 0xff880000, "xOA,X", 4 }, -{ "bs" , 0x70000000, 0xff880000, "xOA,X", 4 }, -{ "bco", 0x70800000, 0xff880000, "xOA,X", 4 }, -{ "blt", 0x71000000, 0xff880000, "xOA,X", 4 }, -{ "beq", 0x71800000, 0xff880000, "xOA,X", 4 }, -{ "buge", 0x72000000, 0xff880000, "xOA,X", 4 }, -{ "bult", 0x72800000, 0xff880000, "xOA,X", 4 }, -{ "ble", 0x73000000, 0xff880000, "xOA,X", 4 }, -{ "bany", 0x73800000, 0xff880000, "xOA,X", 4 }, -{ "brlnk", 0x44000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bib", 0x48000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bih", 0x48080000, 0xfc080000, "r,xOA,X", 4 }, -{ "biw", 0x4c000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bid", 0x4c080000, 0xfc080000, "r,xOA,X", 4 }, -{ "bivb", 0x60000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bivh", 0x60080000, 0xfc080000, "r,xOA,X", 4 }, -{ "bivw", 0x64000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bivd", 0x64080000, 0xfc080000, "r,xOA,X", 4 }, -{ "bvsb", 0x68000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bvsh", 0x68080000, 0xfc080000, "r,xOA,X", 4 }, -{ "bvsw", 0x6c000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bvsd", 0x6c080000, 0xfc080000, "r,xOA,X", 4 }, - -{ "camb", 0x80080000, 0xfc080000, "r,xOA,X", 4 }, -{ "camh", 0x80000001, 0xfc080001, "r,xOA,X", 4 }, -{ "camw", 0x80000000, 0xfc080000, "r,xOA,X", 4 }, -{ "camd", 0x80000002, 0xfc080002, "r,xOA,X", 4 }, -{ "car", 0x10000000, 0xfc0f0000, "r,R", 2 }, -{ "card", 0x14000000, 0xfc0f0000, "r,R", 2 }, -{ "ci", 0xf8050000, 0xfc7f0000, "r,I", 4 }, -{ "chkbnd", 0x5c080000, 0xfc080000, "r,xOA,X", 4 }, - -{ "cavv", 0x10010000, 0xfc0f0000, "v,V", 2 }, -{ "cavr", 0x10020000, 0xfc0f0000, "v,R", 2 }, -{ "cavvd", 0x10090000, 0xfc0f0000, "v,V", 2 }, -{ "cavrd", 0x100b0000, 0xfc0f0000, "v,R", 2 }, - -{ "anmb", 0x84080000, 0xfc080000, "r,xOA,X", 4 }, -{ "anmh", 0x84000001, 0xfc080001, "r,xOA,X", 4 }, -{ "anmw", 0x84000000, 0xfc080000, "r,xOA,X", 4 }, -{ "anmd", 0x84000002, 0xfc080002, "r,xOA,X", 4 }, -{ "anr", 0x04000000, 0xfc0f0000, "r,R", 2 }, -{ "ani", 0xf8080000, 0xfc7f0000, "r,I", 4 }, -{ "ormb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "ormh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "ormw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "ormd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "orr", 0x08000000, 0xfc0f0000, "r,R", 2 }, -{ "oi", 0xf8090000, 0xfc7f0000, "r,I", 4 }, -{ "eomb", 0x8c080000, 0xfc080000, "r,xOA,X", 4 }, -{ "eomh", 0x8c000001, 0xfc080001, "r,xOA,X", 4 }, -{ "eomw", 0x8c000000, 0xfc080000, "r,xOA,X", 4 }, -{ "eomd", 0x8c000002, 0xfc080002, "r,xOA,X", 4 }, -{ "eor", 0x0c000000, 0xfc0f0000, "r,R", 2 }, -{ "eoi", 0xf80a0000, 0xfc7f0000, "r,I", 4 }, - -{ "anvv", 0x04010000, 0xfc0f0000, "v,V", 2 }, -{ "anvr", 0x04020000, 0xfc0f0000, "v,R", 2 }, -{ "orvv", 0x08010000, 0xfc0f0000, "v,V", 2 }, -{ "orvr", 0x08020000, 0xfc0f0000, "v,R", 2 }, -{ "eovv", 0x0c010000, 0xfc0f0000, "v,V", 2 }, -{ "eovr", 0x0c020000, 0xfc0f0000, "v,R", 2 }, - -{ "sacz", 0x100c0000, 0xfc0f0000, "r,R", 2 }, -{ "sla", 0x1c400000, 0xfc600000, "r,S", 2 }, -{ "sll", 0x1c600000, 0xfc600000, "r,S", 2 }, -{ "slc", 0x24400000, 0xfc600000, "r,S", 2 }, -{ "slad", 0x20400000, 0xfc600000, "r,S", 2 }, -{ "slld", 0x20600000, 0xfc600000, "r,S", 2 }, -{ "sra", 0x1c000000, 0xfc600000, "r,S", 2 }, -{ "srl", 0x1c200000, 0xfc600000, "r,S", 2 }, -{ "src", 0x24000000, 0xfc600000, "r,S", 2 }, -{ "srad", 0x20000000, 0xfc600000, "r,S", 2 }, -{ "srld", 0x20200000, 0xfc600000, "r,S", 2 }, -{ "sda", 0x3c030000, 0xfc0f0000, "r,R", 2 }, -{ "sdl", 0x3c020000, 0xfc0f0000, "r,R", 2 }, -{ "sdc", 0x3c010000, 0xfc0f0000, "r,R", 2 }, -{ "sdad", 0x3c0b0000, 0xfc0f0000, "r,R", 2 }, -{ "sdld", 0x3c0a0000, 0xfc0f0000, "r,R", 2 }, - -{ "svda", 0x3c070000, 0xfc0f0000, "v,R", 2 }, -{ "svdl", 0x3c060000, 0xfc0f0000, "v,R", 2 }, -{ "svdc", 0x3c050000, 0xfc0f0000, "v,R", 2 }, -{ "svdad", 0x3c0e0000, 0xfc0f0000, "v,R", 2 }, -{ "svdld", 0x3c0d0000, 0xfc0f0000, "v,R", 2 }, - -{ "sbm", 0xac080000, 0xfc080000, "f,xOA,X", 4 }, -{ "zbm", 0xac000000, 0xfc080000, "f,xOA,X", 4 }, -{ "tbm", 0xa8080000, 0xfc080000, "f,xOA,X", 4 }, -{ "incmb", 0xa0000000, 0xfc080000, "xOA,X", 4 }, -{ "incmh", 0xa0080000, 0xfc080000, "xOA,X", 4 }, -{ "incmw", 0xa4000000, 0xfc080000, "xOA,X", 4 }, -{ "incmd", 0xa4080000, 0xfc080000, "xOA,X", 4 }, -{ "sbmd", 0x7c080000, 0xfc080000, "r,xOA,X", 4 }, -{ "zbmd", 0x7c000000, 0xfc080000, "r,xOA,X", 4 }, -{ "tbmd", 0x78080000, 0xfc080000, "r,xOA,X", 4 }, - -{ "ssm", 0x9c080000, 0xfc080000, "f,xOA,X", 4 }, -{ "zsm", 0x9c000000, 0xfc080000, "f,xOA,X", 4 }, -{ "tsm", 0x98080000, 0xfc080000, "f,xOA,X", 4 }, - -{ "admb", 0xc8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "admh", 0xc8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "admw", 0xc8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "admd", 0xc8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "adr", 0x38000000, 0xfc0f0000, "r,R", 2 }, -{ "armb", 0xe8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "armh", 0xe8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "armw", 0xe8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "armd", 0xe8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "adi", 0xf8010000, 0xfc0f0000, "r,I", 4 }, -{ "sumb", 0xcc080000, 0xfc080000, "r,xOA,X", 4 }, -{ "sumh", 0xcc000001, 0xfc080001, "r,xOA,X", 4 }, -{ "sumw", 0xcc000000, 0xfc080000, "r,xOA,X", 4 }, -{ "sumd", 0xcc000002, 0xfc080002, "r,xOA,X", 4 }, -{ "sur", 0x3c000000, 0xfc0f0000, "r,R", 2 }, -{ "sui", 0xf8020000, 0xfc0f0000, "r,I", 4 }, -{ "mpmb", 0xc0080000, 0xfc080000, "r,xOA,X", 4 }, -{ "mpmh", 0xc0000001, 0xfc080001, "r,xOA,X", 4 }, -{ "mpmw", 0xc0000000, 0xfc080000, "r,xOA,X", 4 }, -{ "mpr", 0x38020000, 0xfc0f0000, "r,R", 2 }, -{ "mprd", 0x3c0f0000, 0xfc0f0000, "r,R", 2 }, -{ "mpi", 0xf8030000, 0xfc0f0000, "r,I", 4 }, -{ "dvmb", 0xc4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "dvmh", 0xc4000001, 0xfc080001, "r,xOA,X", 4 }, -{ "dvmw", 0xc4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "dvr", 0x380a0000, 0xfc0f0000, "r,R", 2 }, -{ "dvi", 0xf8040000, 0xfc0f0000, "r,I", 4 }, -{ "exs", 0x38080000, 0xfc0f0000, "r,R", 2 }, - -{ "advv", 0x30000000, 0xfc0f0000, "v,V", 2 }, -{ "advvd", 0x30080000, 0xfc0f0000, "v,V", 2 }, -{ "adrv", 0x34000000, 0xfc0f0000, "v,R", 2 }, -{ "adrvd", 0x34080000, 0xfc0f0000, "v,R", 2 }, -{ "suvv", 0x30010000, 0xfc0f0000, "v,V", 2 }, -{ "suvvd", 0x30090000, 0xfc0f0000, "v,V", 2 }, -{ "surv", 0x34010000, 0xfc0f0000, "v,R", 2 }, -{ "survd", 0x34090000, 0xfc0f0000, "v,R", 2 }, -{ "mpvv", 0x30020000, 0xfc0f0000, "v,V", 2 }, -{ "mprv", 0x34020000, 0xfc0f0000, "v,R", 2 }, - -{ "adfw", 0xe0080000, 0xfc080000, "r,xOA,X", 4 }, -{ "adfd", 0xe0080002, 0xfc080002, "r,xOA,X", 4 }, -{ "adrfw", 0x38010000, 0xfc0f0000, "r,R", 2 }, -{ "adrfd", 0x38090000, 0xfc0f0000, "r,R", 2 }, -{ "surfw", 0xe0000000, 0xfc080000, "r,xOA,X", 4 }, -{ "surfd", 0xe0000002, 0xfc080002, "r,xOA,X", 4 }, -{ "surfw", 0x38030000, 0xfc0f0000, "r,R", 2 }, -{ "surfd", 0x380b0000, 0xfc0f0000, "r,R", 2 }, -{ "mpfw", 0xe4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "mpfd", 0xe4080002, 0xfc080002, "r,xOA,X", 4 }, -{ "mprfw", 0x38060000, 0xfc0f0000, "r,R", 2 }, -{ "mprfd", 0x380e0000, 0xfc0f0000, "r,R", 2 }, -{ "rfw", 0xe4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "rfd", 0xe4000002, 0xfc080002, "r,xOA,X", 4 }, -{ "rrfw", 0x0c0e0000, 0xfc0f0000, "r", 2 }, -{ "rrfd", 0x0c0f0000, 0xfc0f0000, "r", 2 }, - -{ "advvfw", 0x30040000, 0xfc0f0000, "v,V", 2 }, -{ "advvfd", 0x300c0000, 0xfc0f0000, "v,V", 2 }, -{ "adrvfw", 0x34040000, 0xfc0f0000, "v,R", 2 }, -{ "adrvfd", 0x340c0000, 0xfc0f0000, "v,R", 2 }, -{ "suvvfw", 0x30050000, 0xfc0f0000, "v,V", 2 }, -{ "suvvfd", 0x300d0000, 0xfc0f0000, "v,V", 2 }, -{ "survfw", 0x34050000, 0xfc0f0000, "v,R", 2 }, -{ "survfd", 0x340d0000, 0xfc0f0000, "v,R", 2 }, -{ "mpvvfw", 0x30060000, 0xfc0f0000, "v,V", 2 }, -{ "mpvvfd", 0x300e0000, 0xfc0f0000, "v,V", 2 }, -{ "mprvfw", 0x34060000, 0xfc0f0000, "v,R", 2 }, -{ "mprvfd", 0x340e0000, 0xfc0f0000, "v,R", 2 }, -{ "rvfw", 0x30070000, 0xfc0f0000, "v", 2 }, -{ "rvfd", 0x300f0000, 0xfc0f0000, "v", 2 }, - -{ "fltw", 0x38070000, 0xfc0f0000, "r,R", 2 }, -{ "fltd", 0x380f0000, 0xfc0f0000, "r,R", 2 }, -{ "fixw", 0x38050000, 0xfc0f0000, "r,R", 2 }, -{ "fixd", 0x380d0000, 0xfc0f0000, "r,R", 2 }, -{ "cfpds", 0x3c090000, 0xfc0f0000, "r,R", 2 }, - -{ "fltvw", 0x080d0000, 0xfc0f0000, "v,V", 2 }, -{ "fltvd", 0x080f0000, 0xfc0f0000, "v,V", 2 }, -{ "fixvw", 0x080c0000, 0xfc0f0000, "v,V", 2 }, -{ "fixvd", 0x080e0000, 0xfc0f0000, "v,V", 2 }, -{ "cfpvds", 0x0c0d0000, 0xfc0f0000, "v,V", 2 }, - -{ "orvrn", 0x000a0000, 0xfc0f0000, "r,V", 2 }, -{ "andvrn", 0x00080000, 0xfc0f0000, "r,V", 2 }, -{ "frsteq", 0x04090000, 0xfc0f0000, "r,V", 2 }, -{ "sigma", 0x0c080000, 0xfc0f0000, "r,V", 2 }, -{ "sigmad", 0x0c0a0000, 0xfc0f0000, "r,V", 2 }, -{ "sigmf", 0x08080000, 0xfc0f0000, "r,V", 2 }, -{ "sigmfd", 0x080a0000, 0xfc0f0000, "r,V", 2 }, -{ "prodf", 0x04080000, 0xfc0f0000, "r,V", 2 }, -{ "prodfd", 0x040a0000, 0xfc0f0000, "r,V", 2 }, -{ "maxv", 0x10080000, 0xfc0f0000, "r,V", 2 }, -{ "maxvd", 0x100a0000, 0xfc0f0000, "r,V", 2 }, -{ "minv", 0x14080000, 0xfc0f0000, "r,V", 2 }, -{ "minvd", 0x140a0000, 0xfc0f0000, "r,V", 2 }, - -{ "lpsd", 0xf0000000, 0xfc080000, "xOA,X", 4 }, -{ "ldc", 0xf0080000, 0xfc080000, "xOA,X", 4 }, -{ "spm", 0x040c0000, 0xfc0f0000, "r", 2 }, -{ "rpm", 0x040d0000, 0xfc0f0000, "r", 2 }, -{ "tritr", 0x00070000, 0xfc0f0000, "r", 2 }, -{ "trrit", 0x00060000, 0xfc0f0000, "r", 2 }, -{ "rpswt", 0x04080000, 0xfc0f0000, "r", 2 }, -{ "exr", 0xf8070000, 0xfc0f0000, "", 4 }, -{ "halt", 0x00000000, 0xfc0f0000, "", 2 }, -{ "wait", 0x00010000, 0xfc0f0000, "", 2 }, -{ "nop", 0x00020000, 0xfc0f0000, "", 2 }, -{ "eiae", 0x00030000, 0xfc0f0000, "", 2 }, -{ "efae", 0x000d0000, 0xfc0f0000, "", 2 }, -{ "diae", 0x000e0000, 0xfc0f0000, "", 2 }, -{ "dfae", 0x000f0000, 0xfc0f0000, "", 2 }, -{ "spvc", 0xf8060000, 0xfc0f0000, "r,T,N", 4 }, -{ "rdsts", 0x00090000, 0xfc0f0000, "r", 2 }, -{ "setcpu", 0x000c0000, 0xfc0f0000, "r", 2 }, -{ "cmc", 0x000b0000, 0xfc0f0000, "r", 2 }, -{ "trrcu", 0x00040000, 0xfc0f0000, "r", 2 }, -{ "attnio", 0x00050000, 0xfc0f0000, "", 2 }, -{ "fudit", 0x28080000, 0xfc0f0000, "", 2 }, -{ "break", 0x28090000, 0xfc0f0000, "", 2 }, -{ "frzss", 0x280a0000, 0xfc0f0000, "", 2 }, -{ "ripi", 0x04040000, 0xfc0f0000, "r,R", 2 }, -{ "xcp", 0x04050000, 0xfc0f0000, "r", 2 }, -{ "block", 0x04060000, 0xfc0f0000, "", 2 }, -{ "unblock", 0x04070000, 0xfc0f0000, "", 2 }, -{ "trsc", 0x08060000, 0xfc0f0000, "r,R", 2 }, -{ "tscr", 0x08070000, 0xfc0f0000, "r,R", 2 }, -{ "fq", 0x04080000, 0xfc0f0000, "r", 2 }, -{ "flupte", 0x2c080000, 0xfc0f0000, "r", 2 }, -{ "rviu", 0x040f0000, 0xfc0f0000, "", 2 }, -{ "ldel", 0x280c0000, 0xfc0f0000, "r,R", 2 }, -{ "ldu", 0x280d0000, 0xfc0f0000, "r,R", 2 }, -{ "stdecc", 0x280b0000, 0xfc0f0000, "r,R", 2 }, -{ "trpc", 0x08040000, 0xfc0f0000, "r", 2 }, -{ "tpcr", 0x08050000, 0xfc0f0000, "r", 2 }, -{ "ghalt", 0x0c050000, 0xfc0f0000, "r", 2 }, -{ "grun", 0x0c040000, 0xfc0f0000, "", 2 }, -{ "tmpr", 0x2c0a0000, 0xfc0f0000, "r,R", 2 }, -{ "trmp", 0x2c0b0000, 0xfc0f0000, "r,R", 2 }, - -{ "trrve", 0x28060000, 0xfc0f0000, "r", 2 }, -{ "trver", 0x28070000, 0xfc0f0000, "r", 2 }, -{ "trvlr", 0x280f0000, 0xfc0f0000, "r", 2 }, - -{ "linkfl", 0x18000000, 0xfc0f0000, "r,R", 2 }, -{ "linkbl", 0x18020000, 0xfc0f0000, "r,R", 2 }, -{ "linkfp", 0x18010000, 0xfc0f0000, "r,R", 2 }, -{ "linkbp", 0x18030000, 0xfc0f0000, "r,R", 2 }, -{ "linkpl", 0x18040000, 0xfc0f0000, "r,R", 2 }, -{ "ulinkl", 0x18080000, 0xfc0f0000, "r,R", 2 }, -{ "ulinkp", 0x18090000, 0xfc0f0000, "r,R", 2 }, -{ "ulinktl", 0x180a0000, 0xfc0f0000, "r,R", 2 }, -{ "ulinktp", 0x180b0000, 0xfc0f0000, "r,R", 2 }, -}; - -int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]); - -struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) / - sizeof(gld_opcodes[0]); diff --git a/contrib/gdb/include/opcode/ns32k.h b/contrib/gdb/include/opcode/ns32k.h deleted file mode 100644 index 42bb8b87aad..00000000000 --- a/contrib/gdb/include/opcode/ns32k.h +++ /dev/null @@ -1,491 +0,0 @@ -/* ns32k-opcode.h -- Opcode table for National Semi 32k processor - Copyright (C) 1987 Free Software Foundation, Inc. - -This file is part of GAS, the GNU Assembler. - -GAS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GAS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GAS; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#ifdef SEQUENT_COMPATABILITY -#define DEF_MODEC 20 -#define DEF_MODEL 21 -#endif - -#ifndef DEF_MODEC -#define DEF_MODEC 20 -#endif - -#ifndef DEF_MODEL -#define DEF_MODEL 20 -#endif -/* - After deciding the instruction entry (via hash.c) the instruction parser - will try to match the operands after the instruction to the required set - given in the entry operandfield. Every operand will result in a change in - the opcode or the addition of data to the opcode. - The operands in the source instruction are checked for inconsistent - semantics. - - F : 32 bit float general form - L : 64 bit float " - B : byte " - W : word " - D : double-word " - A : double-word gen-address-form ie no regs, no immediate - I : integer writeable gen int except immediate (A + reg) - Z : floating writeable gen float except immediate (Z + freg) - d : displacement - b : displacement - pc relative addressing acb - p : displacement - pc relative addressing br bcond bsr cxp - q : quick - i : immediate (8 bits) - This is not a standard ns32k operandtype, it is used to build - instructions like svc arg1,arg2 - Svc is the instruction SuperVisorCall and is sometimes used to - call OS-routines from usermode. Some args might be handy! - r : register number (3 bits) - O : setcfg instruction optionslist - C : cinv instruction optionslist - S : stringinstruction optionslist - U : registerlist save,enter - u : registerlist restore,exit - M : mmu register - P : cpu register - g : 3:rd operand of inss or exts instruction - G : 4:th operand of inss or exts instruction - Those operands are encoded in the same byte. - This byte is placed last in the instruction. - f : operand of sfsr - H : sequent-hack for bsr (Warning) - -column 1 instructions - 2 number of bits in opcode. - 3 number of bits in opcode explicitly - determined by the instruction type. - 4 opcodeseed, the number we build our opcode - from. - 5 operandtypes, used by operandparser. - 6 size in bytes of immediate -*/ -struct ns32k_opcode { - char *name; - unsigned char opcode_id_size; /* not used by the assembler */ - unsigned char opcode_size; - unsigned long opcode_seed; - char *operands; - unsigned char im_size; /* not used by dissassembler */ - char *default_args; /* default to those args when none given */ - char default_modec; /* default to this addr-mode when ambigous - ie when the argument of a general addr-mode - is a plain constant */ - char default_model; /* is a plain label */ -}; - -#ifdef comment -/* This section was from the gdb version of this file. */ - -#ifndef ns32k_opcodeT -#define ns32k_opcodeT int -#endif /* no ns32k_opcodeT */ - -struct not_wot /* ns32k opcode table: wot to do with this */ - /* particular opcode */ -{ - int obits; /* number of opcode bits */ - int ibits; /* number of instruction bits */ - ns32k_opcodeT code; /* op-code (may be > 8 bits!) */ - char *args; /* how to compile said opcode */ -}; - -struct not /* ns32k opcode text */ -{ - char * name; /* opcode name: lowercase string [key] */ - struct not_wot detail; /* rest of opcode table [datum] */ -}; - -/* Instructions look like this: - - basic instruction--1, 2, or 3 bytes - index byte for operand A, if operand A is indexed--1 byte - index byte for operand B, if operand B is indexed--1 byte - addressing extension for operand A - addressing extension for operand B - implied operands - - Operand A is the operand listed first in the following opcode table. - Operand B is the operand listed second in the following opcode table. - All instructions have at most 2 general operands, so this is enough. - The implied operands are associated with operands other than A and B. - - Each operand has a digit and a letter. - - The digit gives the position in the assembly language. The letter, - one of the following, tells us what kind of operand it is. */ - -/* F : 32 bit float - * L : 64 bit float - * B : byte - * W : word - * D : double-word - * I : integer not immediate - * Z : floating not immediate - * d : displacement - * q : quick - * i : immediate (8 bits) - * r : register number (3 bits) - * p : displacement - pc relative addressing -*/ - - -#endif /* comment */ - -static const struct ns32k_opcode ns32k_opcodes[]= -{ - { "absf", 14,24, 0x35be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "absl", 14,24, 0x34be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "absb", 14,24, 0x304e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "absw", 14,24, 0x314e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "absd", 14,24, 0x334e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "acbb", 7,16, 0x4c, "2I1q3p", 1, "", DEF_MODEC,DEF_MODEL }, - { "acbw", 7,16, 0x4d, "2I1q3p", 2, "", DEF_MODEC,DEF_MODEL }, - { "acbd", 7,16, 0x4f, "2I1q3p", 4, "", DEF_MODEC,DEF_MODEL }, - { "addf", 14,24, 0x01be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "addl", 14,24, 0x00be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "addb", 6,16, 0x00, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "addw", 6,16, 0x01, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "addd", 6,16, 0x03, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "addcb", 6,16, 0x10, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "addcw", 6,16, 0x11, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "addcd", 6,16, 0x13, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "addpb", 14,24, 0x3c4e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "addpw", 14,24, 0x3d4e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "addpd", 14,24, 0x3f4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "addqb", 7,16, 0x0c, "2I1q", 1, "", DEF_MODEC,DEF_MODEL }, - { "addqw", 7,16, 0x0d, "2I1q", 2, "", DEF_MODEC,DEF_MODEL }, - { "addqd", 7,16, 0x0f, "2I1q", 4, "", DEF_MODEC,DEF_MODEL }, - { "addr", 6,16, 0x27, "1A2I", 4, "", 21,21 }, - { "adjspb", 11,16, 0x057c, "1B", 1, "", DEF_MODEC,DEF_MODEL }, - { "adjspw", 11,16, 0x057d, "1W", 2, "", DEF_MODEC,DEF_MODEL }, - { "adjspd", 11,16, 0x057f, "1D", 4, "", DEF_MODEC,DEF_MODEL }, - { "andb", 6,16, 0x28, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "andw", 6,16, 0x29, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "andd", 6,16, 0x2b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "ashb", 14,24, 0x044e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "ashw", 14,24, 0x054e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "ashd", 14,24, 0x074e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "beq", 8,8, 0x0a, "1p", 0, "", 21,21 }, - { "bne", 8,8, 0x1a, "1p", 0, "", 21,21 }, - { "bcs", 8,8, 0x2a, "1p", 0, "", 21,21 }, - { "bcc", 8,8, 0x3a, "1p", 0, "", 21,21 }, - { "bhi", 8,8, 0x4a, "1p", 0, "", 21,21 }, - { "bls", 8,8, 0x5a, "1p", 0, "", 21,21 }, - { "bgt", 8,8, 0x6a, "1p", 0, "", 21,21 }, - { "ble", 8,8, 0x7a, "1p", 0, "", 21,21 }, - { "bfs", 8,8, 0x8a, "1p", 0, "", 21,21 }, - { "bfc", 8,8, 0x9a, "1p", 0, "", 21,21 }, - { "blo", 8,8, 0xaa, "1p", 0, "", 21,21 }, - { "bhs", 8,8, 0xba, "1p", 0, "", 21,21 }, - { "blt", 8,8, 0xca, "1p", 0, "", 21,21 }, - { "bge", 8,8, 0xda, "1p", 0, "", 21,21 }, - { "but", 8,8, 0xea, "1p", 0, "", 21,21 }, - { "buf", 8,8, 0xfa, "1p", 0, "", 21,21 }, - { "bicb", 6,16, 0x08, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "bicw", 6,16, 0x09, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "bicd", 6,16, 0x0b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "bicpsrb", 11,16, 0x17c, "1B", 1, "", DEF_MODEC,DEF_MODEL }, - { "bicpsrw", 11,16, 0x17d, "1W", 2, "", DEF_MODEC,DEF_MODEL }, - { "bispsrb", 11,16, 0x37c, "1B", 1, "", DEF_MODEC,DEF_MODEL }, - { "bispsrw", 11,16, 0x37d, "1W", 2, "", DEF_MODEC,DEF_MODEL }, - { "bpt", 8,8, 0xf2, "", 0, "", DEF_MODEC,DEF_MODEL }, - { "br", 8,8, 0xea, "1p", 0, "", 21,21 }, -#ifdef SEQUENT_COMPATABILITY - { "bsr", 8,8, 0x02, "1H", 0, "", 21,21 }, -#else - { "bsr", 8,8, 0x02, "1p", 0, "", 21,21 }, -#endif - { "caseb", 11,16, 0x77c, "1B", 1, "", DEF_MODEC,DEF_MODEL }, - { "casew", 11,16, 0x77d, "1W", 2, "", DEF_MODEC,DEF_MODEL }, - { "cased", 11,16, 0x77f, "1D", 4, "", DEF_MODEC,DEF_MODEL }, - { "cbitb", 14,24, 0x084e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "cbitw", 14,24, 0x094e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "cbitd", 14,24, 0x0b4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "cbitib", 14,24, 0x0c4e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "cbitiw", 14,24, 0x0d4e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "cbitid", 14,24, 0x0f4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "checkb", 11,24, 0x0ee, "2A3B1r", 1, "", DEF_MODEC,DEF_MODEL }, - { "checkw", 11,24, 0x1ee, "2A3W1r", 2, "", DEF_MODEC,DEF_MODEL }, - { "checkd", 11,24, 0x3ee, "2A3D1r", 4, "", DEF_MODEC,DEF_MODEL }, - { "cinv", 14,24, 0x271e, "2D1C", 4, "", DEF_MODEC,DEF_MODEL }, - { "cmpf", 14,24, 0x09be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL }, - { "cmpl", 14,24, 0x08be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL }, - { "cmpb", 6,16, 0x04, "1B2B", 1, "", DEF_MODEC,DEF_MODEL }, - { "cmpw", 6,16, 0x05, "1W2W", 2, "", DEF_MODEC,DEF_MODEL }, - { "cmpd", 6,16, 0x07, "1D2D", 4, "", DEF_MODEC,DEF_MODEL }, - { "cmpmb", 14,24, 0x04ce, "1A2A3b", 1, "", DEF_MODEC,DEF_MODEL }, - { "cmpmw", 14,24, 0x05ce, "1A2A3b", 2, "", DEF_MODEC,DEF_MODEL }, - { "cmpmd", 14,24, 0x07ce, "1A2A3b", 4, "", DEF_MODEC,DEF_MODEL }, - { "cmpqb", 7,16, 0x1c, "2B1q", 1, "", DEF_MODEC,DEF_MODEL }, - { "cmpqw", 7,16, 0x1d, "2W1q", 2, "", DEF_MODEC,DEF_MODEL }, - { "cmpqd", 7,16, 0x1f, "2D1q", 4, "", DEF_MODEC,DEF_MODEL }, - { "cmpsb", 16,24, 0x040e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "cmpsw", 16,24, 0x050e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "cmpsd", 16,24, 0x070e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "cmpst", 16,24, 0x840e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "comb", 14,24, 0x344e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "comw", 14,24, 0x354e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "comd", 14,24, 0x374e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "cvtp", 11,24, 0x036e, "2A3D1r", 4, "", DEF_MODEC,DEF_MODEL }, - { "cxp", 8,8, 0x22, "1p", 0, "", 21,21 }, - { "cxpd", 11,16, 0x07f, "1A", 4, "", DEF_MODEC,DEF_MODEL }, - { "deib", 14,24, 0x2cce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "deiw", 14,24, 0x2dce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "deid", 14,24, 0x2fce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "dia", 8,8, 0xc2, "", 1, "", DEF_MODEC,DEF_MODEL }, - { "divf", 14,24, 0x21be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "divl", 14,24, 0x20be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "divb", 14,24, 0x3cce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "divw", 14,24, 0x3dce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "divd", 14,24, 0x3fce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "enter", 8,8, 0x82, "1U2d", 0, "", DEF_MODEC,DEF_MODEL }, - { "exit", 8,8, 0x92, "1u", 0, "", DEF_MODEC,DEF_MODEL }, - { "extb", 11,24, 0x02e, "2I3B1r4d", 1, "", DEF_MODEC,DEF_MODEL }, - { "extw", 11,24, 0x12e, "2I3W1r4d", 2, "", DEF_MODEC,DEF_MODEL }, - { "extd", 11,24, 0x32e, "2I3D1r4d", 4, "", DEF_MODEC,DEF_MODEL }, - { "extsb", 14,24, 0x0cce, "1I2I4G3g", 1, "", DEF_MODEC,DEF_MODEL }, - { "extsw", 14,24, 0x0dce, "1I2I4G3g", 2, "", DEF_MODEC,DEF_MODEL }, - { "extsd", 14,24, 0x0fce, "1I2I4G3g", 4, "", DEF_MODEC,DEF_MODEL }, - { "ffsb", 14,24, 0x046e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "ffsw", 14,24, 0x056e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "ffsd", 14,24, 0x076e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "flag", 8,8, 0xd2, "", 0, "", DEF_MODEC,DEF_MODEL }, - { "floorfb", 14,24, 0x3c3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "floorfw", 14,24, 0x3d3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "floorfd", 14,24, 0x3f3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "floorlb", 14,24, 0x383e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "floorlw", 14,24, 0x393e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "floorld", 14,24, 0x3b3e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "ibitb", 14,24, 0x384e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "ibitw", 14,24, 0x394e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "ibitd", 14,24, 0x3b4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "indexb", 11,24, 0x42e, "2B3B1r", 1, "", DEF_MODEC,DEF_MODEL }, - { "indexw", 11,24, 0x52e, "2W3W1r", 2, "", DEF_MODEC,DEF_MODEL }, - { "indexd", 11,24, 0x72e, "2D3D1r", 4, "", DEF_MODEC,DEF_MODEL }, - { "insb", 11,24, 0x0ae, "2B3I1r4d", 1, "", DEF_MODEC,DEF_MODEL }, - { "insw", 11,24, 0x1ae, "2W3I1r4d", 2, "", DEF_MODEC,DEF_MODEL }, - { "insd", 11,24, 0x3ae, "2D3I1r4d", 4, "", DEF_MODEC,DEF_MODEL }, - { "inssb", 14,24, 0x08ce, "1B2I4G3g", 1, "", DEF_MODEC,DEF_MODEL }, - { "inssw", 14,24, 0x09ce, "1W2I4G3g", 2, "", DEF_MODEC,DEF_MODEL }, - { "inssd", 14,24, 0x0bce, "1D2I4G3g", 4, "", DEF_MODEC,DEF_MODEL }, - { "jsr", 11,16, 0x67f, "1A", 4, "", 21,21 }, - { "jump", 11,16, 0x27f, "1A", 4, "", 21,21 }, - { "lfsr", 19,24, 0x00f3e,"1D", 4, "", DEF_MODEC,DEF_MODEL }, - { "lmr", 15,24, 0x0b1e, "2D1M", 4, "", DEF_MODEC,DEF_MODEL }, - { "lprb", 7,16, 0x6c, "2B1P", 1, "", DEF_MODEC,DEF_MODEL }, - { "lprw", 7,16, 0x6d, "2W1P", 2, "", DEF_MODEC,DEF_MODEL }, - { "lprd", 7,16, 0x6f, "2D1P", 4, "", DEF_MODEC,DEF_MODEL }, - { "lshb", 14,24, 0x144e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "lshw", 14,24, 0x154e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "lshd", 14,24, 0x174e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "meib", 14,24, 0x24ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "meiw", 14,24, 0x25ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "meid", 14,24, 0x27ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "modb", 14,24, 0x38ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "modw", 14,24, 0x39ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "modd", 14,24, 0x3bce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "movf", 14,24, 0x05be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "movl", 14,24, 0x04be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "movb", 6,16, 0x14, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "movw", 6,16, 0x15, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "movd", 6,16, 0x17, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "movbf", 14,24, 0x043e, "1B2Z", 1, "", DEF_MODEC,DEF_MODEL }, - { "movwf", 14,24, 0x053e, "1W2Z", 2, "", DEF_MODEC,DEF_MODEL }, - { "movdf", 14,24, 0x073e, "1D2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "movbl", 14,24, 0x003e, "1B2Z", 1, "", DEF_MODEC,DEF_MODEL }, - { "movwl", 14,24, 0x013e, "1W2Z", 2, "", DEF_MODEC,DEF_MODEL }, - { "movdl", 14,24, 0x033e, "1D2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "movfl", 14,24, 0x1b3e, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "movlf", 14,24, 0x163e, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "movmb", 14,24, 0x00ce, "1A2A3b", 1, "", DEF_MODEC,DEF_MODEL }, - { "movmw", 14,24, 0x01ce, "1A2A3b", 2, "", DEF_MODEC,DEF_MODEL }, - { "movmd", 14,24, 0x03ce, "1A2A3b", 4, "", DEF_MODEC,DEF_MODEL }, - { "movqb", 7,16, 0x5c, "2I1q", 1, "", DEF_MODEC,DEF_MODEL }, - { "movqw", 7,16, 0x5d, "2I1q", 2, "", DEF_MODEC,DEF_MODEL }, - { "movqd", 7,16, 0x5f, "2I1q", 4, "", DEF_MODEC,DEF_MODEL }, - { "movsb", 16,24, 0x000e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "movsw", 16,24, 0x010e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "movsd", 16,24, 0x030e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "movst", 16,24, 0x800e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "movsub", 14,24, 0x0cae, "1A2A", 1, "", DEF_MODEC,DEF_MODEL }, - { "movsuw", 14,24, 0x0dae, "1A2A", 2, "", DEF_MODEC,DEF_MODEL }, - { "movsud", 14,24, 0x0fae, "1A2A", 4, "", DEF_MODEC,DEF_MODEL }, - { "movusb", 14,24, 0x1cae, "1A2A", 1, "", DEF_MODEC,DEF_MODEL }, - { "movusw", 14,24, 0x1dae, "1A2A", 2, "", DEF_MODEC,DEF_MODEL }, - { "movusd", 14,24, 0x1fae, "1A2A", 4, "", DEF_MODEC,DEF_MODEL }, - { "movxbd", 14,24, 0x1cce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "movxwd", 14,24, 0x1dce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "movxbw", 14,24, 0x10ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "movzbd", 14,24, 0x18ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "movzwd", 14,24, 0x19ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "movzbw", 14,24, 0x14ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "mulf", 14,24, 0x31be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "mull", 14,24, 0x30be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "mulb", 14,24, 0x20ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "mulw", 14,24, 0x21ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "muld", 14,24, 0x23ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "negf", 14,24, 0x15be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "negl", 14,24, 0x14be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "negb", 14,24, 0x204e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "negw", 14,24, 0x214e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "negd", 14,24, 0x234e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "nop", 8,8, 0xa2, "", 0, "", DEF_MODEC,DEF_MODEL }, - { "notb", 14,24, 0x244e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "notw", 14,24, 0x254e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "notd", 14,24, 0x274e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "orb", 6,16, 0x18, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "orw", 6,16, 0x19, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "ord", 6,16, 0x1b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "quob", 14,24, 0x30ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "quow", 14,24, 0x31ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "quod", 14,24, 0x33ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "rdval", 19,24, 0x0031e,"1A", 4, "", DEF_MODEC,DEF_MODEL }, - { "remb", 14,24, 0x34ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "remw", 14,24, 0x35ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "remd", 14,24, 0x37ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "restore", 8,8, 0x72, "1u", 0, "", DEF_MODEC,DEF_MODEL }, - { "ret", 8,8, 0x12, "1d", 0, "", DEF_MODEC,DEF_MODEL }, - { "reti", 8,8, 0x52, "", 0, "", DEF_MODEC,DEF_MODEL }, - { "rett", 8,8, 0x42, "1d", 0, "", DEF_MODEC,DEF_MODEL }, - { "rotb", 14,24, 0x004e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "rotw", 14,24, 0x014e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "rotd", 14,24, 0x034e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "roundfb", 14,24, 0x243e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "roundfw", 14,24, 0x253e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "roundfd", 14,24, 0x273e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "roundlb", 14,24, 0x203e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "roundlw", 14,24, 0x213e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "roundld", 14,24, 0x233e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "rxp", 8,8, 0x32, "1d", 0, "", DEF_MODEC,DEF_MODEL }, - { "seqb", 11,16, 0x3c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "seqw", 11,16, 0x3d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "seqd", 11,16, 0x3f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sneb", 11,16, 0xbc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "snew", 11,16, 0xbd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sned", 11,16, 0xbf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "scsb", 11,16, 0x13c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "scsw", 11,16, 0x13d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "scsd", 11,16, 0x13f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sccb", 11,16, 0x1bc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sccw", 11,16, 0x1bd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sccd", 11,16, 0x1bf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "shib", 11,16, 0x23c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "shiw", 11,16, 0x23d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "shid", 11,16, 0x23f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "slsb", 11,16, 0x2bc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "slsw", 11,16, 0x2bd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "slsd", 11,16, 0x2bf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sgtb", 11,16, 0x33c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sgtw", 11,16, 0x33d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sgtd", 11,16, 0x33f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sleb", 11,16, 0x3bc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "slew", 11,16, 0x3bd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sled", 11,16, 0x3bf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sfsb", 11,16, 0x43c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sfsw", 11,16, 0x43d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sfsd", 11,16, 0x43f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sfcb", 11,16, 0x4bc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sfcw", 11,16, 0x4bd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sfcd", 11,16, 0x4bf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "slob", 11,16, 0x53c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "slow", 11,16, 0x53d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "slod", 11,16, 0x53f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "shsb", 11,16, 0x5bc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "shsw", 11,16, 0x5bd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "shsd", 11,16, 0x5bf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sltb", 11,16, 0x63c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sltw", 11,16, 0x63d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sltd", 11,16, 0x63f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sgeb", 11,16, 0x6bc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sgew", 11,16, 0x6bd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sged", 11,16, 0x6bf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sutb", 11,16, 0x73c, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sutw", 11,16, 0x73d, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sutd", 11,16, 0x73f, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "sufb", 11,16, 0x7bc, "1B", 0, "", DEF_MODEC,DEF_MODEL }, - { "sufw", 11,16, 0x7bd, "1W", 0, "", DEF_MODEC,DEF_MODEL }, - { "sufd", 11,16, 0x7bf, "1D", 0, "", DEF_MODEC,DEF_MODEL }, - { "save", 8,8, 0x62, "1U", 0, "", DEF_MODEC,DEF_MODEL }, - { "sbitb", 14,24, 0x184e, "1B2A", 1, "", DEF_MODEC,DEF_MODEL }, - { "sbitw", 14,24, 0x194e, "1W2A", 2, "", DEF_MODEC,DEF_MODEL }, - { "sbitd", 14,24, 0x1b4e, "1D2A", 4, "", DEF_MODEC,DEF_MODEL }, - { "sbitib", 14,24, 0x1c4e, "1B2A", 1, "", DEF_MODEC,DEF_MODEL }, - { "sbitiw", 14,24, 0x1d4e, "1W2A", 2, "", DEF_MODEC,DEF_MODEL }, - { "sbitid", 14,24, 0x1f4e, "1D2A", 4, "", DEF_MODEC,DEF_MODEL }, - { "setcfg", 15,24, 0x0b0e, "1O", 0, "", DEF_MODEC,DEF_MODEL }, - { "sfsr", 14,24, 0x373e, "1f", 0, "", DEF_MODEC,DEF_MODEL }, - { "skpsb", 16,24, 0x0c0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "skpsw", 16,24, 0x0d0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "skpsd", 16,24, 0x0f0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "skpst", 16,24, 0x8c0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL }, - { "smr", 15,24, 0x0f1e, "2I1M", 4, "", DEF_MODEC,DEF_MODEL }, - { "sprb", 7,16, 0x2c, "2I1P", 1, "", DEF_MODEC,DEF_MODEL }, - { "sprw", 7,16, 0x2d, "2I1P", 2, "", DEF_MODEC,DEF_MODEL }, - { "sprd", 7,16, 0x2f, "2I1P", 4, "", DEF_MODEC,DEF_MODEL }, - { "subf", 14,24, 0x11be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "subl", 14,24, 0x10be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "subb", 6,16, 0x20, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "subw", 6,16, 0x21, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "subd", 6,16, 0x23, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "subcb", 6,16, 0x30, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "subcw", 6,16, 0x31, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "subcd", 6,16, 0x33, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "subpb", 14,24, 0x2c4e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "subpw", 14,24, 0x2d4e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "subpd", 14,24, 0x2f4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, -#ifdef NS32K_SVC_IMMED_OPERANDS - { "svc", 8,8, 0xe2, "2i1i", 1, "", DEF_MODEC,DEF_MODEL }, /* not really, but some unix uses it */ -#else - { "svc", 8,8, 0xe2, "", 0, "", DEF_MODEC,DEF_MODEL }, -#endif - { "tbitb", 6,16, 0x34, "1B2A", 1, "", DEF_MODEC,DEF_MODEL }, - { "tbitw", 6,16, 0x35, "1W2A", 2, "", DEF_MODEC,DEF_MODEL }, - { "tbitd", 6,16, 0x37, "1D2A", 4, "", DEF_MODEC,DEF_MODEL }, - { "truncfb", 14,24, 0x2c3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "truncfw", 14,24, 0x2d3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "truncfd", 14,24, 0x2f3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "trunclb", 14,24, 0x283e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "trunclw", 14,24, 0x293e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "truncld", 14,24, 0x2b3e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL }, - { "wait", 8,8, 0xb2, "", 0, "", DEF_MODEC,DEF_MODEL }, - { "wrval", 19,24, 0x0071e,"1A", 0, "", DEF_MODEC,DEF_MODEL }, - { "xorb", 6,16, 0x38, "1B2I", 1, "", DEF_MODEC,DEF_MODEL }, - { "xorw", 6,16, 0x39, "1W2I", 2, "", DEF_MODEC,DEF_MODEL }, - { "xord", 6,16, 0x3b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL }, - { "dotf", 14,24, 0x0dfe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL }, - { "dotl", 14,24, 0x0cfe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL }, - { "logbf", 14,24, 0x15fe, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "logbl", 14,24, 0x14fe, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, - { "polyf", 14,24, 0x09fe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL }, - { "polyl", 14,24, 0x08fe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL }, - { "scalbf", 14,24, 0x11fe, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL }, - { "scalbl", 14,24, 0x10fe, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL }, -}; - -static const int numopcodes=sizeof(ns32k_opcodes)/sizeof(ns32k_opcodes[0]); - -static const struct ns32k_opcode *const endop = ns32k_opcodes+sizeof(ns32k_opcodes)/sizeof(ns32k_opcodes[0]); - -#define MAX_ARGS 4 -#define ARG_LEN 50 - diff --git a/contrib/gdb/include/opcode/pn.h b/contrib/gdb/include/opcode/pn.h deleted file mode 100644 index 0f59a2a53ce..00000000000 --- a/contrib/gdb/include/opcode/pn.h +++ /dev/null @@ -1,282 +0,0 @@ -/* Print GOULD PN (PowerNode) instructions for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. - -This file is part of GDB. - -GDB is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GDB is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GDB; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -struct gld_opcode -{ - char *name; - unsigned long opcode; - unsigned long mask; - char *args; - int length; -}; - -/* We store four bytes of opcode for all opcodes because that - is the most any of them need. The actual length of an instruction - is always at least 2 bytes, and at most four. The length of the - instruction is based on the opcode. - - The mask component is a mask saying which bits must match - particular opcode in order for an instruction to be an instance - of that opcode. - - The args component is a string containing characters - that are used to format the arguments to the instruction. */ - -/* Kinds of operands: - r Register in first field - R Register in second field - b Base register in first field - B Base register in second field - v Vector register in first field - V Vector register in first field - A Optional address register (base register) - X Optional index register - I Immediate data (16bits signed) - O Offset field (16bits signed) - h Offset field (15bits signed) - d Offset field (14bits signed) - S Shift count field - - any other characters are printed as is... -*/ - -/* The assembler requires that this array be sorted as follows: - all instances of the same mnemonic must be consecutive. - All instances of the same mnemonic with the same number of operands - must be consecutive. - */ -struct gld_opcode gld_opcodes[] = -{ -{ "abm", 0xa0080000, 0xfc080000, "f,xOA,X", 4 }, -{ "abr", 0x18080000, 0xfc0c0000, "r,f", 2 }, -{ "aci", 0xfc770000, 0xfc7f8000, "r,I", 4 }, -{ "adfd", 0xe0080002, 0xfc080002, "r,xOA,X", 4 }, -{ "adfw", 0xe0080000, 0xfc080000, "r,xOA,X", 4 }, -{ "adi", 0xc8010000, 0xfc7f0000, "r,I", 4 }, -{ "admb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "admd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "admh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "admw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "adr", 0x38000000, 0xfc0f0000, "r,R", 2 }, -{ "adrfd", 0x38090000, 0xfc0f0000, "r,R", 2 }, -{ "adrfw", 0x38010000, 0xfc0f0000, "r,R", 2 }, -{ "adrm", 0x38080000, 0xfc0f0000, "r,R", 2 }, -{ "ai", 0xfc030000, 0xfc07ffff, "I", 4 }, -{ "anmb", 0x84080000, 0xfc080000, "r,xOA,X", 4 }, -{ "anmd", 0x84000002, 0xfc080002, "r,xOA,X", 4 }, -{ "anmh", 0x84000001, 0xfc080001, "r,xOA,X", 4 }, -{ "anmw", 0x84000000, 0xfc080000, "r,xOA,X", 4 }, -{ "anr", 0x04000000, 0xfc0f0000, "r,R", 2 }, -{ "armb", 0xe8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "armd", 0xe8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "armh", 0xe8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "armw", 0xe8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "bcf", 0xf0000000, 0xfc080000, "I,xOA,X", 4 }, -{ "bct", 0xec000000, 0xfc080000, "I,xOA,X", 4 }, -{ "bei", 0x00060000, 0xffff0000, "", 2 }, -{ "bft", 0xf0000000, 0xff880000, "xOA,X", 4 }, -{ "bib", 0xf4000000, 0xfc780000, "r,xOA", 4 }, -{ "bid", 0xf4600000, 0xfc780000, "r,xOA", 4 }, -{ "bih", 0xf4200000, 0xfc780000, "r,xOA", 4 }, -{ "biw", 0xf4400000, 0xfc780000, "r,xOA", 4 }, -{ "bl", 0xf8800000, 0xff880000, "xOA,X", 4 }, -{ "bsub", 0x5c080000, 0xff8f0000, "", 2 }, -{ "bsubm", 0x28080000, 0xfc080000, "", 4 }, -{ "bu", 0xec000000, 0xff880000, "xOA,X", 4 }, -{ "call", 0x28080000, 0xfc0f0000, "", 2 }, -{ "callm", 0x5c080000, 0xff880000, "", 4 }, -{ "camb", 0x90080000, 0xfc080000, "r,xOA,X", 4 }, -{ "camd", 0x90000002, 0xfc080002, "r,xOA,X", 4 }, -{ "camh", 0x90000001, 0xfc080001, "r,xOA,X", 4 }, -{ "camw", 0x90000000, 0xfc080000, "r.xOA,X", 4 }, -{ "car", 0x10000000, 0xfc0f0000, "r,R", 2 }, -{ "cd", 0xfc060000, 0xfc070000, "r,f", 4 }, -{ "cea", 0x000f0000, 0xffff0000, "", 2 }, -{ "ci", 0xc8050000, 0xfc7f0000, "r,I", 4 }, -{ "cmc", 0x040a0000, 0xfc7f0000, "r", 2 }, -{ "cmmb", 0x94080000, 0xfc080000, "r,xOA,X", 4 }, -{ "cmmd", 0x94000002, 0xfc080002, "r,xOA,X", 4 }, -{ "cmmh", 0x94000001, 0xfc080001, "r,xOA,X", 4 }, -{ "cmmw", 0x94000000, 0xfc080000, "r,xOA,X", 4 }, -{ "cmr", 0x14000000, 0xfc0f0000, "r,R", 2 }, -{ "daci", 0xfc7f0000, 0xfc7f8000, "r,I", 4 }, -{ "dae", 0x000e0000, 0xffff0000, "", 2 }, -{ "dai", 0xfc040000, 0xfc07ffff, "I", 4 }, -{ "dci", 0xfc6f0000, 0xfc7f8000, "r,I", 4 }, -{ "di", 0xfc010000, 0xfc07ffff, "I", 4 }, -{ "dvfd", 0xe4000002, 0xfc080002, "r,xOA,X", 4 }, -{ "dvfw", 0xe4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "dvi", 0xc8040000, 0xfc7f0000, "r,I", 4 }, -{ "dvmb", 0xc4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "dvmh", 0xc4000001, 0xfc080001, "r,xOA,X", 4 }, -{ "dvmw", 0xc4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "dvr", 0x380a0000, 0xfc0f0000, "r,R", 2 }, -{ "dvrfd", 0x380c0000, 0xfc0f0000, "r,R", 4 }, -{ "dvrfw", 0x38040000, 0xfc0f0000, "r,xOA,X", 4 }, -{ "eae", 0x00080000, 0xffff0000, "", 2 }, -{ "eci", 0xfc670000, 0xfc7f8080, "r,I", 4 }, -{ "ecwcs", 0xfc4f0000, 0xfc7f8000, "", 4 }, -{ "ei", 0xfc000000, 0xfc07ffff, "I", 4 }, -{ "eomb", 0x8c080000, 0xfc080000, "r,xOA,X", 4 }, -{ "eomd", 0x8c000002, 0xfc080002, "r,xOA,X", 4 }, -{ "eomh", 0x8c000001, 0xfc080001, "r,xOA,X", 4 }, -{ "eomw", 0x8c000000, 0xfc080000, "r,xOA,X", 4 }, -{ "eor", 0x0c000000, 0xfc0f0000, "r,R", 2 }, -{ "eorm", 0x0c080000, 0xfc0f0000, "r,R", 2 }, -{ "es", 0x00040000, 0xfc7f0000, "r", 2 }, -{ "exm", 0xa8000000, 0xff880000, "xOA,X", 4 }, -{ "exr", 0xc8070000, 0xfc7f0000, "r", 2 }, -{ "exrr", 0xc8070002, 0xfc7f0002, "r", 2 }, -{ "fixd", 0x380d0000, 0xfc0f0000, "r,R", 2 }, -{ "fixw", 0x38050000, 0xfc0f0000, "r,R", 2 }, -{ "fltd", 0x380f0000, 0xfc0f0000, "r,R", 2 }, -{ "fltw", 0x38070000, 0xfc0f0000, "r,R", 2 }, -{ "grio", 0xfc3f0000, 0xfc7f8000, "r,I", 4 }, -{ "halt", 0x00000000, 0xffff0000, "", 2 }, -{ "hio", 0xfc370000, 0xfc7f8000, "r,I", 4 }, -{ "jwcs", 0xfa080000, 0xff880000, "xOA,X", 4 }, -{ "la", 0x50000000, 0xfc000000, "r,xOA,X", 4 }, -{ "labr", 0x58080000, 0xfc080000, "b,xOA,X", 4 }, -{ "lb", 0xac080000, 0xfc080000, "r,xOA,X", 4 }, -{ "lcs", 0x00030000, 0xfc7f0000, "r", 2 }, -{ "ld", 0xac000002, 0xfc080002, "r,xOA,X", 4 }, -{ "lear", 0x80000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lf", 0xcc000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lfbr", 0xcc080000, 0xfc080000, "b,xOA,X", 4 }, -{ "lh", 0xac000001, 0xfc080001, "r,xOA,X", 4 }, -{ "li", 0xc8000000, 0xfc7f0000, "r,I", 4 }, -{ "lmap", 0x2c070000, 0xfc7f0000, "r", 2 }, -{ "lmb", 0xb0080000, 0xfc080000, "r,xOA,X", 4 }, -{ "lmd", 0xb0000002, 0xfc080002, "r,xOA,X", 4 }, -{ "lmh", 0xb0000001, 0xfc080001, "r,xOA,X", 4 }, -{ "lmw", 0xb0000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lnb", 0xb4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "lnd", 0xb4000002, 0xfc080002, "r,xOA,X", 4 }, -{ "lnh", 0xb4000001, 0xfc080001, "r,xOA,X", 4 }, -{ "lnw", 0xb4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lpsd", 0xf9800000, 0xff880000, "r,xOA,X", 4 }, -{ "lpsdcm", 0xfa800000, 0xff880000, "r,xOA,X", 4 }, -{ "lw", 0xac000000, 0xfc080000, "r,xOA,X", 4 }, -{ "lwbr", 0x5c000000, 0xfc080000, "b,xOA,X", 4 }, -{ "mpfd", 0xe4080002, 0xfc080002, "r,xOA,X", 4 }, -{ "mpfw", 0xe4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "mpi", 0xc8030000, 0xfc7f0000, "r,I", 4 }, -{ "mpmb", 0xc0080000, 0xfc080000, "r,xOA,X", 4 }, -{ "mpmh", 0xc0000001, 0xfc080001, "r,xOA,X", 4 }, -{ "mpmw", 0xc0000000, 0xfc080000, "r,xOA,X", 4 }, -{ "mpr", 0x38020000, 0xfc0f0000, "r,R", 2 }, -{ "mprfd", 0x380e0000, 0xfc0f0000, "r,R", 2 }, -{ "mprfw", 0x38060000, 0xfc0f0000, "r,R", 2 }, -{ "nop", 0x00020000, 0xffff0000, "", 2 }, -{ "ormb", 0x88080000, 0xfc080000, "r,xOA,X", 4 }, -{ "ormd", 0x88000002, 0xfc080002, "r,xOA,X", 4 }, -{ "ormh", 0x88000001, 0xfc080001, "r,xOA,X", 4 }, -{ "ormw", 0x88000000, 0xfc080000, "r,xOA,X", 4 }, -{ "orr", 0x08000000, 0xfc0f0000, "r,R", 2 }, -{ "orrm", 0x08080000, 0xfc0f0000, "r,R", 2 }, -{ "rdsts", 0x00090000, 0xfc7f0000, "r", 2 }, -{ "return", 0x280e0000, 0xfc7f0000, "", 2 }, -{ "ri", 0xfc020000, 0xfc07ffff, "I", 4 }, -{ "rnd", 0x00050000, 0xfc7f0000, "r", 2 }, -{ "rpswt", 0x040b0000, 0xfc7f0000, "r", 2 }, -{ "rschnl", 0xfc2f0000, 0xfc7f8000, "r,I", 4 }, -{ "rsctl", 0xfc470000, 0xfc7f8000, "r,I", 4 }, -{ "rwcs", 0x000b0000, 0xfc0f0000, "r,R", 2 }, -{ "sacz", 0x10080000, 0xfc0f0000, "r,R", 2 }, -{ "sbm", 0x98080000, 0xfc080000, "f,xOA,X", 4 }, -{ "sbr", 0x18000000, 0xfc0c0000, "r,f", 4 }, -{ "sea", 0x000d0000, 0xffff0000, "", 2 }, -{ "setcpu", 0x2c090000, 0xfc7f0000, "r", 2 }, -{ "sio", 0xfc170000, 0xfc7f8000, "r,I", 4 }, -{ "sipu", 0x000a0000, 0xffff0000, "", 2 }, -{ "sla", 0x1c400000, 0xfc600000, "r,S", 2 }, -{ "slad", 0x20400000, 0xfc600000, "r,S", 2 }, -{ "slc", 0x24400000, 0xfc600000, "r,S", 2 }, -{ "sll", 0x1c600000, 0xfc600000, "r,S", 2 }, -{ "slld", 0x20600000, 0xfc600000, "r,S", 2 }, -{ "smc", 0x04070000, 0xfc070000, "", 2 }, -{ "sra", 0x1c000000, 0xfc600000, "r,S", 2 }, -{ "srad", 0x20000000, 0xfc600000, "r,S", 2 }, -{ "src", 0x24000000, 0xfc600000, "r,S", 2 }, -{ "srl", 0x1c200000, 0xfc600000, "r,S", 2 }, -{ "srld", 0x20200000, 0xfc600000, "r,S", 2 }, -{ "stb", 0xd4080000, 0xfc080000, "r,xOA,X", 4 }, -{ "std", 0xd4000002, 0xfc080002, "r,xOA,X", 4 }, -{ "stf", 0xdc000000, 0xfc080000, "r,xOA,X", 4 }, -{ "stfbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 }, -{ "sth", 0xd4000001, 0xfc080001, "r,xOA,X", 4 }, -{ "stmb", 0xd8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "stmd", 0xd8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "stmh", 0xd8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "stmw", 0xd8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "stpio", 0xfc270000, 0xfc7f8000, "r,I", 4 }, -{ "stw", 0xd4000000, 0xfc080000, "r,xOA,X", 4 }, -{ "stwbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 }, -{ "suabr", 0x58000000, 0xfc080000, "b,xOA,X", 4 }, -{ "sufd", 0xe0000002, 0xfc080002, "r,xOA,X", 4 }, -{ "sufw", 0xe0000000, 0xfc080000, "r,xOA,X", 4 }, -{ "sui", 0xc8020000, 0xfc7f0000, "r,I", 4 }, -{ "sumb", 0xbc080000, 0xfc080000, "r,xOA,X", 4 }, -{ "sumd", 0xbc000002, 0xfc080002, "r,xOA,X", 4 }, -{ "sumh", 0xbc000001, 0xfc080001, "r,xOA,X", 4 }, -{ "sumw", 0xbc000000, 0xfc080000, "r,xOA,X", 4 }, -{ "sur", 0x3c000000, 0xfc0f0000, "r,R", 2 }, -{ "surfd", 0x380b0000, 0xfc0f0000, "r,xOA,X", 4 }, -{ "surfw", 0x38030000, 0xfc0f0000, "r,R", 2 }, -{ "surm", 0x3c080000, 0xfc0f0000, "r,R", 2 }, -{ "svc", 0xc8060000, 0xffff0000, "", 4 }, -{ "tbm", 0xa4080000, 0xfc080000, "f,xOA,X", 4 }, -{ "tbr", 0x180c0000, 0xfc0c0000, "r,f", 2 }, -{ "tbrr", 0x2c020000, 0xfc0f0000, "r,B", 2 }, -{ "tccr", 0x28040000, 0xfc7f0000, "", 2 }, -{ "td", 0xfc050000, 0xfc070000, "r,f", 4 }, -{ "tio", 0xfc1f0000, 0xfc7f8000, "r,I", 4 }, -{ "tmapr", 0x2c0a0000, 0xfc0f0000, "r,R", 2 }, -{ "tpcbr", 0x280c0000, 0xfc7f0000, "r", 2 }, -{ "trbr", 0x2c010000, 0xfc0f0000, "b,R", 2 }, -{ "trc", 0x2c030000, 0xfc0f0000, "r,R", 2 }, -{ "trcc", 0x28050000, 0xfc7f0000, "", 2 }, -{ "trcm", 0x2c0b0000, 0xfc0f0000, "r,R", 2 }, -{ "trn", 0x2c040000, 0xfc0f0000, "r,R", 2 }, -{ "trnm", 0x2c0c0000, 0xfc0f0000, "r,R", 2 }, -{ "trr", 0x2c000000, 0xfc0f0000, "r,R", 2 }, -{ "trrm", 0x2c080000, 0xfc0f0000, "r,R", 2 }, -{ "trsc", 0x2c0e0000, 0xfc0f0000, "r,R", 2 }, -{ "trsw", 0x28000000, 0xfc7f0000, "r", 2 }, -{ "tscr", 0x2c0f0000, 0xfc0f0000, "r,R", 2 }, -{ "uei", 0x00070000, 0xffff0000, "", 2 }, -{ "wait", 0x00010000, 0xffff0000, "", 2 }, -{ "wcwcs", 0xfc5f0000, 0xfc7f8000, "", 4 }, -{ "wwcs", 0x000c0000, 0xfc0f0000, "r,R", 2 }, -{ "xcbr", 0x28020000, 0xfc0f0000, "b,B", 2 }, -{ "xcr", 0x2c050000, 0xfc0f0000, "r,R", 2 }, -{ "xcrm", 0x2c0d0000, 0xfc0f0000, "r,R", 2 }, -{ "zbm", 0x9c080000, 0xfc080000, "f,xOA,X", 4 }, -{ "zbr", 0x18040000, 0xfc0c0000, "r,f", 2 }, -{ "zmb", 0xf8080000, 0xfc080000, "r,xOA,X", 4 }, -{ "zmd", 0xf8000002, 0xfc080002, "r,xOA,X", 4 }, -{ "zmh", 0xf8000001, 0xfc080001, "r,xOA,X", 4 }, -{ "zmw", 0xf8000000, 0xfc080000, "r,xOA,X", 4 }, -{ "zr", 0x0c000000, 0xfc0f0000, "r", 2 }, -}; - -int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]); - -struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) / - sizeof(gld_opcodes[0]); diff --git a/contrib/gdb/include/opcode/ppc.h b/contrib/gdb/include/opcode/ppc.h deleted file mode 100644 index a9e3b24ab30..00000000000 --- a/contrib/gdb/include/opcode/ppc.h +++ /dev/null @@ -1,248 +0,0 @@ -/* ppc.h -- Header file for PowerPC opcode table - Copyright 1994, 1995 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support - -This file is part of GDB, GAS, and the GNU binutils. - -GDB, GAS, and the GNU binutils are free software; you can redistribute -them and/or modify them under the terms of the GNU General Public -License as published by the Free Software Foundation; either version -1, or (at your option) any later version. - -GDB, GAS, and the GNU binutils are distributed in the hope that they -will be useful, but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See -the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this file; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef PPC_H -#define PPC_H - -/* The opcode table is an array of struct powerpc_opcode. */ - -struct powerpc_opcode -{ - /* The opcode name. */ - const char *name; - - /* The opcode itself. Those bits which will be filled in with - operands are zeroes. */ - unsigned long opcode; - - /* The opcode mask. This is used by the disassembler. This is a - mask containing ones indicating those bits which must match the - opcode field, and zeroes indicating those bits which need not - match (and are presumably filled in by operands). */ - unsigned long mask; - - /* One bit flags for the opcode. These are used to indicate which - specific processors support the instructions. The defined values - are listed below. */ - unsigned long flags; - - /* An array of operand codes. Each code is an index into the - operand table. They appear in the order which the operands must - appear in assembly code, and are terminated by a zero. */ - unsigned char operands[8]; -}; - -/* The table itself is sorted by major opcode number, and is otherwise - in the order in which the disassembler should consider - instructions. */ -extern const struct powerpc_opcode powerpc_opcodes[]; -extern const int powerpc_num_opcodes; - -/* Values defined for the flags field of a struct powerpc_opcode. */ - -/* Opcode is defined for the PowerPC architecture. */ -#define PPC_OPCODE_PPC (01) - -/* Opcode is defined for the POWER (RS/6000) architecture. */ -#define PPC_OPCODE_POWER (02) - -/* Opcode is defined for the POWER2 (Rios 2) architecture. */ -#define PPC_OPCODE_POWER2 (04) - -/* Opcode is only defined on 32 bit architectures. */ -#define PPC_OPCODE_32 (010) - -/* Opcode is only defined on 64 bit architectures. */ -#define PPC_OPCODE_64 (020) - -/* Opcode is supported by the Motorola PowerPC 601 processor. The 601 - is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions, - but it also supports many additional POWER instructions. */ -#define PPC_OPCODE_601 (040) - -/* Opcode is supported in both the Power and PowerPC architectures - (ie, compiler's -mcpu=common or assembler's -mcom). */ -#define PPC_OPCODE_COMMON (0100) - -/* Opcode is supported for any Power or PowerPC platform (this is - for the assembler's -many option, and it eliminates duplicates). */ -#define PPC_OPCODE_ANY (0200) - -/* A macro to extract the major opcode from an instruction. */ -#define PPC_OP(i) (((i) >> 26) & 0x3f) - -/* The operands table is an array of struct powerpc_operand. */ - -struct powerpc_operand -{ - /* The number of bits in the operand. */ - int bits; - - /* How far the operand is left shifted in the instruction. */ - int shift; - - /* Insertion function. This is used by the assembler. To insert an - operand value into an instruction, check this field. - - If it is NULL, execute - i |= (op & ((1 << o->bits) - 1)) << o->shift; - (i is the instruction which we are filling in, o is a pointer to - this structure, and op is the opcode value; this assumes twos - complement arithmetic). - - If this field is not NULL, then simply call it with the - instruction and the operand value. It will return the new value - of the instruction. If the ERRMSG argument is not NULL, then if - the operand value is illegal, *ERRMSG will be set to a warning - string (the operand will be inserted in any case). If the - operand value is legal, *ERRMSG will be unchanged (most operands - can accept any value). */ - unsigned long (*insert) PARAMS ((unsigned long instruction, long op, - const char **errmsg)); - - /* Extraction function. This is used by the disassembler. To - extract this operand type from an instruction, check this field. - - If it is NULL, compute - op = ((i) >> o->shift) & ((1 << o->bits) - 1); - if ((o->flags & PPC_OPERAND_SIGNED) != 0 - && (op & (1 << (o->bits - 1))) != 0) - op -= 1 << o->bits; - (i is the instruction, o is a pointer to this structure, and op - is the result; this assumes twos complement arithmetic). - - If this field is not NULL, then simply call it with the - instruction value. It will return the value of the operand. If - the INVALID argument is not NULL, *INVALID will be set to - non-zero if this operand type can not actually be extracted from - this operand (i.e., the instruction does not match). If the - operand is valid, *INVALID will not be changed. */ - long (*extract) PARAMS ((unsigned long instruction, int *invalid)); - - /* One bit syntax flags. */ - unsigned long flags; -}; - -/* Elements in the table are retrieved by indexing with values from - the operands field of the powerpc_opcodes table. */ - -extern const struct powerpc_operand powerpc_operands[]; - -/* Values defined for the flags field of a struct powerpc_operand. */ - -/* This operand takes signed values. */ -#define PPC_OPERAND_SIGNED (01) - -/* This operand takes signed values, but also accepts a full positive - range of values when running in 32 bit mode. That is, if bits is - 16, it takes any value from -0x8000 to 0xffff. In 64 bit mode, - this flag is ignored. */ -#define PPC_OPERAND_SIGNOPT (02) - -/* This operand does not actually exist in the assembler input. This - is used to support extended mnemonics such as mr, for which two - operands fields are identical. The assembler should call the - insert function with any op value. The disassembler should call - the extract function, ignore the return value, and check the value - placed in the valid argument. */ -#define PPC_OPERAND_FAKE (04) - -/* The next operand should be wrapped in parentheses rather than - separated from this one by a comma. This is used for the load and - store instructions which want their operands to look like - reg,displacement(reg) - */ -#define PPC_OPERAND_PARENS (010) - -/* This operand may use the symbolic names for the CR fields, which - are - lt 0 gt 1 eq 2 so 3 un 3 - cr0 0 cr1 1 cr2 2 cr3 3 - cr4 4 cr5 5 cr6 6 cr7 7 - These may be combined arithmetically, as in cr2*4+gt. These are - only supported on the PowerPC, not the POWER. */ -#define PPC_OPERAND_CR (020) - -/* This operand names a register. The disassembler uses this to print - register names with a leading 'r'. */ -#define PPC_OPERAND_GPR (040) - -/* This operand names a floating point register. The disassembler - prints these with a leading 'f'. */ -#define PPC_OPERAND_FPR (0100) - -/* This operand is a relative branch displacement. The disassembler - prints these symbolically if possible. */ -#define PPC_OPERAND_RELATIVE (0200) - -/* This operand is an absolute branch address. The disassembler - prints these symbolically if possible. */ -#define PPC_OPERAND_ABSOLUTE (0400) - -/* This operand is optional, and is zero if omitted. This is used for - the optional BF and L fields in the comparison instructions. The - assembler must count the number of operands remaining on the line, - and the number of operands remaining for the opcode, and decide - whether this operand is present or not. The disassembler should - print this operand out only if it is not zero. */ -#define PPC_OPERAND_OPTIONAL (01000) - -/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand - is omitted, then for the next operand use this operand value plus - 1, ignoring the next operand field for the opcode. This wretched - hack is needed because the Power rotate instructions can take - either 4 or 5 operands. The disassembler should print this operand - out regardless of the PPC_OPERAND_OPTIONAL field. */ -#define PPC_OPERAND_NEXT (02000) - -/* This operand should be regarded as a negative number for the - purposes of overflow checking (i.e., the normal most negative - number is disallowed and one more than the normal most positive - number is allowed). This flag will only be set for a signed - operand. */ -#define PPC_OPERAND_NEGATIVE (04000) - -/* The POWER and PowerPC assemblers use a few macros. We keep them - with the operands table for simplicity. The macro table is an - array of struct powerpc_macro. */ - -struct powerpc_macro -{ - /* The macro name. */ - const char *name; - - /* The number of operands the macro takes. */ - unsigned int operands; - - /* One bit flags for the opcode. These are used to indicate which - specific processors support the instructions. The values are the - same as those for the struct powerpc_opcode flags field. */ - unsigned long flags; - - /* A format string to turn the macro into a normal instruction. - Each %N in the string is replaced with operand number N (zero - based). */ - const char *format; -}; - -extern const struct powerpc_macro powerpc_macros[]; -extern const int powerpc_num_macros; - -#endif /* PPC_H */ diff --git a/contrib/gdb/include/opcode/pyr.h b/contrib/gdb/include/opcode/pyr.h deleted file mode 100644 index 06632b8d919..00000000000 --- a/contrib/gdb/include/opcode/pyr.h +++ /dev/null @@ -1,287 +0,0 @@ -/* pyramid.opcode.h -- gdb initial attempt. */ - -/* pyramid opcode table: wot to do with this - particular opcode */ - -struct pyr_datum -{ - char nargs; - char * args; /* how to compile said opcode */ - unsigned long mask; /* Bit vector: which operand modes are valid - for this opcode */ - unsigned char code; /* op-code (always 6(?) bits */ -}; - -typedef struct pyr_insn_format { - unsigned int mode :4; - unsigned int operator :8; - unsigned int index_scale :2; - unsigned int index_reg :6; - unsigned int operand_1 :6; - unsigned int operand_2:6; -} pyr_insn_format; - - -/* We store four bytes of opcode for all opcodes. - Pyramid is sufficiently RISCy that: - - insns are always an integral number of words; - - the length of any insn can be told from the first word of - the insn. (ie, if there are zero, one, or two words of - immediate operand/offset). - - - The args component is a string containing two characters for each - operand of the instruction. The first specifies the kind of operand; - the second, the place it is stored. */ - -/* Kinds of operands: - mask assembler syntax description - 0x0001: movw Rn,Rn register to register - 0x0002: movw K,Rn quick immediate to register - 0x0004: movw I,Rn long immediate to register - 0x0008: movw (Rn),Rn register indirect to register - movw (Rn)[x],Rn register indirect to register - 0x0010: movw I(Rn),Rn offset register indirect to register - movw I(Rn)[x],Rn offset register indirect, indexed, to register - - 0x0020: movw Rn,(Rn) register to register indirect - 0x0040: movw K,(Rn) quick immediate to register indirect - 0x0080: movw I,(Rn) long immediate to register indirect - 0x0100: movw (Rn),(Rn) register indirect to-register indirect - 0x0100: movw (Rn),(Rn) register indirect to-register indirect - 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect - 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect - - 0x0400: movw Rn,I(Rn) register to register indirect+offset - 0x0800: movw K,I(Rn) quick immediate to register indirect+offset - 0x1000: movw I,I(Rn) long immediate to register indirect+offset - 0x1000: movw (Rn),I(Rn) register indirect to-register indirect+offset - 0x1000: movw I(Rn),I(Rn) register indirect+offset to register indirect - +offset - 0x0000: (irregular) ??? - - - Each insn has a four-bit field encoding the type(s) of its operands. -*/ - -/* Some common combinations - */ - -/* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/ -#define GEN_TO_REG (31) - -#define UNKNOWN ((unsigned long)-1) -#define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15)) - -#define CONVERT (1|8|0x10|0x20|0x200) - -#define K_TO_REG (2) -#define I_TO_REG (4) -#define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG) -#define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG) - -/* The assembler requires that this array be sorted as follows: - all instances of the same mnemonic must be consecutive. - All instances of the same mnemonic with the same number of operands - must be consecutive. - */ - -struct pyr_opcode /* pyr opcode text */ -{ - char * name; /* opcode name: lowercase string [key] */ - struct pyr_datum datum; /* rest of opcode table [datum] */ -}; - -#define pyr_how args -#define pyr_nargs nargs -#define pyr_mask mask -#define pyr_name name - -struct pyr_opcode pyr_opcodes[] = -{ - {"movb", { 2, "", UNKNOWN, 0x11}, }, - {"movh", { 2, "", UNKNOWN, 0x12} }, - {"movw", { 2, "", ANY, 0x10} }, - {"movl", { 2, "", ANY, 0x13} }, - {"mnegw", { 2, "", (0x1|0x8|0x10), 0x14} }, - {"mnegf", { 2, "", 0x1, 0x15} }, - {"mnegd", { 2, "", 0x1, 0x16} }, - {"mcomw", { 2, "", (0x1|0x8|0x10), 0x17} }, - {"mabsw", { 2, "", (0x1|0x8|0x10), 0x18} }, - {"mabsf", { 2, "", 0x1, 0x19} }, - {"mabsd", { 2, "", 0x1, 0x1a} }, - {"mtstw", { 2, "", (0x1|0x8|0x10), 0x1c} }, - {"mtstf", { 2, "", 0x1, 0x1d} }, - {"mtstd", { 2, "", 0x1, 0x1e} }, - {"mova", { 2, "", 0x8|0x10, 0x1f} }, - {"movzbw", { 2, "", (0x1|0x8|0x10), 0x20} }, - {"movzhw", { 2, "", (0x1|0x8|0x10), 0x21} }, - /* 2 insns out of order here */ - {"movbl", { 2, "", 1, 0x4f} }, - {"filbl", { 2, "", 1, 0x4e} }, - - {"cvtbw", { 2, "", CONVERT, 0x22} }, - {"cvthw", { 2, "", CONVERT, 0x23} }, - {"cvtwb", { 2, "", CONVERT, 0x24} }, - {"cvtwh", { 2, "", CONVERT, 0x25} }, - {"cvtwf", { 2, "", CONVERT, 0x26} }, - {"cvtwd", { 2, "", CONVERT, 0x27} }, - {"cvtfw", { 2, "", CONVERT, 0x28} }, - {"cvtfd", { 2, "", CONVERT, 0x29} }, - {"cvtdw", { 2, "", CONVERT, 0x2a} }, - {"cvtdf", { 2, "", CONVERT, 0x2b} }, - - {"addw", { 2, "", GEN_TO_REG, 0x40} }, - {"addwc", { 2, "", GEN_TO_REG, 0x41} }, - {"subw", { 2, "", GEN_TO_REG, 0x42} }, - {"subwb", { 2, "", GEN_TO_REG, 0x43} }, - {"rsubw", { 2, "", GEN_TO_REG, 0x44} }, - {"mulw", { 2, "", GEN_TO_REG, 0x45} }, - {"emul", { 2, "", GEN_TO_REG, 0x47} }, - {"umulw", { 2, "", GEN_TO_REG, 0x46} }, - {"divw", { 2, "", GEN_TO_REG, 0x48} }, - {"ediv", { 2, "", GEN_TO_REG, 0x4a} }, - {"rdivw", { 2, "", GEN_TO_REG, 0x4b} }, - {"udivw", { 2, "", GEN_TO_REG, 0x49} }, - {"modw", { 2, "", GEN_TO_REG, 0x4c} }, - {"umodw", { 2, "", GEN_TO_REG, 0x4d} }, - - - {"addf", { 2, "", 1, 0x50} }, - {"addd", { 2, "", 1, 0x51} }, - {"subf", { 2, "", 1, 0x52} }, - {"subd", { 2, "", 1, 0x53} }, - {"mulf", { 2, "", 1, 0x56} }, - {"muld", { 2, "", 1, 0x57} }, - {"divf", { 2, "", 1, 0x58} }, - {"divd", { 2, "", 1, 0x59} }, - - - {"cmpb", { 2, "", UNKNOWN, 0x61} }, - {"cmph", { 2, "", UNKNOWN, 0x62} }, - {"cmpw", { 2, "", UNKNOWN, 0x60} }, - {"ucmpb", { 2, "", UNKNOWN, 0x66} }, - /* WHY no "ucmph"??? */ - {"ucmpw", { 2, "", UNKNOWN, 0x65} }, - {"xchw", { 2, "", UNKNOWN, 0x0f} }, - - - {"andw", { 2, "", GEN_TO_REG, 0x30} }, - {"orw", { 2, "", GEN_TO_REG, 0x31} }, - {"xorw", { 2, "", GEN_TO_REG, 0x32} }, - {"bicw", { 2, "", GEN_TO_REG, 0x33} }, - {"lshlw", { 2, "", GEN_TO_REG, 0x38} }, - {"ashlw", { 2, "", GEN_TO_REG, 0x3a} }, - {"ashll", { 2, "", GEN_TO_REG, 0x3c} }, - {"ashrw", { 2, "", GEN_TO_REG, 0x3b} }, - {"ashrl", { 2, "", GEN_TO_REG, 0x3d} }, - {"rotlw", { 2, "", GEN_TO_REG, 0x3e} }, - {"rotrw", { 2, "", GEN_TO_REG, 0x3f} }, - - /* push and pop insns are "going away next release". */ - {"pushw", { 2, "", GEN_TO_REG, 0x0c} }, - {"popw", { 2, "", (0x1|0x8|0x10), 0x0d} }, - {"pusha", { 2, "", (0x8|0x10), 0x0e} }, - - {"bitsw", { 2, "", UNKNOWN, 0x35} }, - {"bitcw", { 2, "", UNKNOWN, 0x36} }, - /* some kind of ibra/dbra insns??*/ - {"icmpw", { 2, "", UNKNOWN, 0x67} }, - {"dcmpw", { 2, "", (1|4|0x20|0x80|0x400|0x1000), 0x69} },/*FIXME*/ - {"acmpw", { 2, "", 1, 0x6b} }, - - /* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op - insn with a 2nd op of tr14. The assembler will have to grok this. */ - {"call", { 2, "", GEN_TO_REG, 0x04} }, - {"call", { 1, "", GEN_TO_REG, 0x04} }, - - {"callk", { 1, "", UNKNOWN, 0x06} },/* system call?*/ - /* Ret is usually written as a 0-op insn, but gets disassembled as a - 1-op insn. The operand is always tr15. */ - {"ret", { 0, "", UNKNOWN, 0x09} }, - {"ret", { 1, "", UNKNOWN, 0x09} }, - {"adsf", { 2, "", (1|2|4), 0x08} }, - {"retd", { 2, "", UNKNOWN, 0x0a} }, - {"btc", { 2, "", UNKNOWN, 0x01} }, - {"bfc", { 2, "", UNKNOWN, 0x02} }, - /* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */ - {"jump", { 1, "", UNKNOWN, 0x00} }, - {"btp", { 2, "", UNKNOWN, 0xf00} }, - /* read control-stack pointer is another 1-or-2 operand insn. */ - {"rcsp", { 2, "", UNKNOWN, 0x01f} }, - {"rcsp", { 1, "", UNKNOWN, 0x01f} } -}; - -/* end: pyramid.opcode.h */ -/* One day I will have to take the time to find out what operands - are valid for these insns, and guess at what they mean. - - I can't imagine what the "I???" insns (iglob, etc) do. - - the arithmetic-sounding insns ending in "p" sound awfully like BCD - arithmetic insns: - dshlp -> Decimal SHift Left Packed - dshrp -> Decimal SHift Right Packed - and cvtlp would be convert long to packed. - I have no idea how the operands are interpreted; but having them be - a long register with (address, length) of an in-memory packed BCD operand - would not be surprising. - They are unlikely to be a packed bcd string: 64 bits of long give - is only 15 digits+sign, which isn't enough for COBOL. - */ -#if 0 - {"wcsp", { 2, "", UNKNOWN, 0x00} }, /*write csp?*/ - /* The OSx Operating System Porting Guide claims SSL does things - with tr12 (a register reserved to it) to do with static block-structure - references. SSL=Set Static Link? It's "Going away next release". */ - {"ssl", { 2, "", UNKNOWN, 0x00} }, - {"ccmps", { 2, "", UNKNOWN, 0x00} }, - {"lcd", { 2, "", UNKNOWN, 0x00} }, - {"uemul", { 2, "", UNKNOWN, 0x00} }, /*unsigned emul*/ - {"srf", { 2, "", UNKNOWN, 0x00} }, /*Gidget time???*/ - {"mnegp", { 2, "", UNKNOWN, 0x00} }, /move-neg phys?*/ - {"ldp", { 2, "", UNKNOWN, 0x00} }, /*load phys?*/ - {"ldti", { 2, "", UNKNOWN, 0x00} }, - {"ldb", { 2, "", UNKNOWN, 0x00} }, - {"stp", { 2, "", UNKNOWN, 0x00} }, - {"stti", { 2, "", UNKNOWN, 0x00} }, - {"stb", { 2, "", UNKNOWN, 0x00} }, - {"stu", { 2, "", UNKNOWN, 0x00} }, - {"addp", { 2, "", UNKNOWN, 0x00} }, - {"subp", { 2, "", UNKNOWN, 0x00} }, - {"mulp", { 2, "", UNKNOWN, 0x00} }, - {"divp", { 2, "", UNKNOWN, 0x00} }, - {"dshlp", { 2, "", UNKNOWN, 0x00} }, /* dec shl packed? */ - {"dshrp", { 2, "", UNKNOWN, 0x00} }, /* dec shr packed? */ - {"movs", { 2, "", UNKNOWN, 0x00} }, /*move (string?)?*/ - {"cmpp", { 2, "", UNKNOWN, 0x00} }, /* cmp phys?*/ - {"cmps", { 2, "", UNKNOWN, 0x00} }, /* cmp (string?)?*/ - {"cvtlp", { 2, "", UNKNOWN, 0x00} }, /* cvt long to p??*/ - {"cvtpl", { 2, "", UNKNOWN, 0x00} }, /* cvt p to l??*/ - {"dintr", { 2, "", UNKNOWN, 0x00} }, /* ?? intr ?*/ - {"rphysw", { 2, "", UNKNOWN, 0x00} }, /* read phys word?*/ - {"wphysw", { 2, "", UNKNOWN, 0x00} }, /* write phys word?*/ - {"cmovs", { 2, "", UNKNOWN, 0x00} }, - {"rsubw", { 2, "", UNKNOWN, 0x00} }, - {"bicpsw", { 2, "", UNKNOWN, 0x00} }, /* clr bit in psw? */ - {"bispsw", { 2, "", UNKNOWN, 0x00} }, /* set bit in psw? */ - {"eio", { 2, "", UNKNOWN, 0x00} }, /* ?? ?io ? */ - {"callp", { 2, "", UNKNOWN, 0x00} }, /* call phys?*/ - {"callr", { 2, "", UNKNOWN, 0x00} }, - {"lpcxt", { 2, "", UNKNOWN, 0x00} }, /*load proc context*/ - {"rei", { 2, "", UNKNOWN, 0x00} }, /*ret from intrpt*/ - {"rport", { 2, "", UNKNOWN, 0x00} }, /*read-port?*/ - {"rtod", { 2, "", UNKNOWN, 0x00} }, /*read-time-of-day?*/ - {"ssi", { 2, "", UNKNOWN, 0x00} }, - {"vtpa", { 2, "", UNKNOWN, 0x00} }, /*virt-to-phys-addr?*/ - {"wicl", { 2, "", UNKNOWN, 0x00} }, /* write icl ? */ - {"wport", { 2, "", UNKNOWN, 0x00} }, /*write-port?*/ - {"wtod", { 2, "", UNKNOWN, 0x00} }, /*write-time-of-day?*/ - {"flic", { 2, "", UNKNOWN, 0x00} }, - {"iglob", { 2, "", UNKNOWN, 0x00} }, /* I global? */ - {"iphys", { 2, "", UNKNOWN, 0x00} }, /* I physical? */ - {"ipid", { 2, "", UNKNOWN, 0x00} }, /* I pid? */ - {"ivect", { 2, "", UNKNOWN, 0x00} }, /* I vector? */ - {"lamst", { 2, "", UNKNOWN, 0x00} }, - {"tio", { 2, "", UNKNOWN, 0x00} }, -#endif diff --git a/contrib/gdb/include/opcode/rs6k.h b/contrib/gdb/include/opcode/rs6k.h deleted file mode 100644 index fac9cf43f35..00000000000 --- a/contrib/gdb/include/opcode/rs6k.h +++ /dev/null @@ -1,254 +0,0 @@ -/* IBM RS/6000 instruction set definitions, for GNU software. */ - -/* These are all possible instruction formats as used in IBM Assembler - Language Reference, Appendix A. */ - -typedef enum { A=0, B, D, I, M, SC, X, XL, XO, XFL, XFX } InsnFmt; - -/* Extended opcode masks. Used for extracting extended opcode values from - instructions. Each instruction's format decides which mask applies. - They *should* retain the same order as the above formats. */ - -static int eopMask[] = - { 0x1f, 0, 0, 0, 0, 0, 0x3ff, 0x3ff, 0x1ff, 0x3ff, 0x3ff }; - -/* All the things you need to know about an opcode. */ - -typedef struct rs6000_insn { - char *operator; /* opcode name */ - char *opr_ext; /* opcode name extension */ - InsnFmt format; /* opcode format */ - char p_opcode; /* primary opcode */ - int e_opcode; /* extended opcode */ - char oprnd_format[6]; /* operand format */ -} OPCODE; - -/* operand format specifiers */ - -#define TO 1 -#define RA 2 -#define SI 3 -#define RT 4 -#define UI 5 -#define BF 6 -#define BFA 7 -#define BT 8 -#define BA 9 -#define BB 10 -#define BO 11 -#define BI 12 -#define RB 13 -#define RS 14 -#define SH 15 -#define MB 16 -#define ME 17 -#define SPR 18 -#define DIS 19 -#define FXM 21 -#define FRT 22 -#define NB 23 -#define FRS 24 -#define FRA 25 -#define FRB 26 -#define FRC 27 -#define FLM 28 -#define I 29 -#define LI 30 -#define A2 31 -#define TA14 32 /* 14 bit representation of target address */ -#define TA24 33 /* 24 bit representation of target address */ -#define FL1 34 -#define FL2 35 -#define LEV 36 - -/* RS/6000 INSTRUCTION SET - (sorted on primary and extended opcode) - - oprtr primary ext. -operator ext format opcode opcode operand format -------- ------- ------ ------- ------ --------------- */ - -struct rs6000_insn rs6k_ops [] = { - -{"ti", 0, D, 3, -1, {TO,RA,SI,0} }, -{"muli", 0, D, 7, -1, {RT,RA,SI,0} }, -{"sfi", 0, D, 8, -1, {RT,RA,SI,0} }, -{"dozi", 0, D, 9, -1, {RT,RA,SI,0} }, -{"cmpli", 0, D, 10, -1, {BF,RA,UI,0} }, -{"cmpi", 0, D, 11, -1, {BF,RA,SI,0} }, -{"ai", 0, D, 12, -1, {RT,RA,SI,0} }, -{"ai.", 0, D, 13, -1, {RT,RA,SI,0} }, -{"lil", 0, D, 14, -1, {RT,SI,0} }, /* same as `cal' */ -{"cal", 0, D, 14, -1, {RT,DIS,RA,0} }, -{"liu", 0, D, 15, -1, {RT, UI,0} }, /* same as `cau' */ -{"cau", 0, D, 15, -1, {RT,RA,UI,0} }, - -/* "1" indicates an exception--"bb" is only usable for some values of - BO, so the disassembler first matches this instruction and then changes - it to "bc" if that is the case. */ -{"bb", "1tfla", B, 16, -1, {LI,A2,0} }, -{"bc", "la", B, 16, -1, {BO,BI,TA14,0} }, - -{"svc", "la", SC, 17, -1, {LEV,FL1,FL2,0} }, -{"b", "la", I, 18, -1, {TA24,0} }, -{"mcrf", 0, XL, 19, 0, {BF,BFA,0} }, -{"bcr", "l", XL, 19, 16, {BO,BI,0} }, -{"crnor", 0, XL, 19, 33, {BT,BA,BB,0} }, -{"rfi", 0, X, 19, 50, {0} }, -{"rfsvc", 0, X, 19, 82, {0} }, -{"crandc", 0, XL, 19, 129, {BT,BA,BB,0} }, -{"ics", 0, X, 19, 150, {0} }, -{"crxor", 0, XL, 19, 193, {BT,BA,BB,0} }, -{"crnand", 0, XL, 19, 225, {BT,BA,BB,0} }, -{"crand", 0, XL, 19, 257, {BT,BA,BB,0} }, -{"creqv", 0, XL, 19, 289, {BT,BA,BB,0} }, -{"crorc", 0, XL, 19, 417, {BT,BA,BB,0} }, -{"cror", 0, XL, 19, 449, {BT,BA,BB,0} }, -{"bcc", "l", XL, 19, 528, {BO,BI,0} }, -{"rlimi", ".", M, 20, -1, {RA,RS,SH,MB,ME,0} /*??*/}, -{"rlinm", ".", M, 21, -1, {RA,RS,SH,MB,ME,0} /*??*/}, -{"rlmi", ".", M, 22, -1, {RA,RS,RB,MB,ME,0} /*??*/}, -{"rlnm", ".", M, 23, -1, {RA,RS,RB,MB,ME,0} /*??*/}, -{"oril", 0, D, 24, -1, {RA,RS,UI,0} }, -{"oriu", 0, D, 25, -1, {RA,RS,UI,0} }, -{"xoril", 0, D, 26, -1, {RA,RS,UI,0} }, -{"xoriu", 0, D, 27, -1, {RA,RS,UI,0} }, -{"andil.", 0, D, 28, -1, {RA,RS,UI,0} }, -{"andiu.", 0, D, 29, -1, {RA,RS,UI,0} }, -{"cmp", 0, X, 31, 0, {BF,RA,RB,0} }, -{"t", 0, X, 31, 4, {TO,RA,RB,0} }, -{"sf", "o.", XO, 31, 8, {RT,RA,RB,0} }, -{"a", "o.", XO, 31, 10, {RT,RA,RB,0} }, -{"mfcr", 0, X, 31, 19, {RT,0} }, -{"lx", 0, X, 31, 23, {RT,RA,RB,0} }, -{"sl", ".", X, 31, 24, {RA,RS,RB,0} }, -{"cntlz", ".", XO, 31, 26, {RA,RS,0} }, -{"and", ".", X, 31, 28, {RA,RS,RB,0} }, -{"maskg", ".", X, 31, 29, {RA,RS,RB,0} }, -{"cmpl", 0, X, 31, 32, {BF,RA,RB,0} }, -{"sfe", "o.", XO, 31, 136, {RT,RA,RB,0} }, -{"lux", 0, X, 31, 55, {RT,RA,RB,0} }, -{"andc", ".", X, 31, 60, {RA,RS,RB,0} }, -{"mfmsr", 0, X, 31, 83, {RT,0} }, -{"lbzx", 0, X, 31, 87, {RT,RA,RB,0} }, -{"neg", "o.", XO, 31, 104, {RT,RA,0} }, -{"mul", "o.", XO, 31, 107, {RT,RA,RB,0} }, -{"lbzux", 0, X, 31, 119, {RT,RA,RB,0} }, -{"nor", ".", X, 31, 124, {RA,RS,RB,0} }, -{"ae", "o.", XO, 31, 138, {RT,RA,RB,0} }, -{"mtcrf", 0, XFX, 31, 144, {FXM,RS,0} }, -{"stx", 0, X, 31, 151, {RS,RA,RB,0} }, -{"slq", ".", X, 31, 152, {RA,RS,RB,0} }, -{"sle", ".", X, 31, 153, {RA,RS,RB,0} }, -{"stux", 0, X, 31, 183, {RS,RA,RB,0} }, -{"sliq", ".", X, 31, 184, {RA,RS,SH,0} }, -{"sfze", "o.", XO, 31, 200, {RT,RA,0} }, -{"aze", "o.", XO, 31, 202, {RT,RA,0} }, -{"stbx", 0, X, 31, 215, {RS,RA,RB,0} }, -{"sllq", ".", X, 31, 216, {RA,RS,RB,0} }, -{"sleq", ".", X, 31, 217, {RA,RS,RB,0} }, -{"sfme", "o.", XO, 31, 232, {RT,RA,0} }, -{"ame", "o.", XO, 31, 234, {RT,RA,0} }, -{"muls", "o.", XO, 31, 235, {RT,RA,RB,0} }, -{"stbux", 0, X, 31, 247, {RS,RA,RB,0} }, -{"slliq", ".", X, 31, 248, {RA,RS,SH,0} }, -{"doz", "o.", X, 31, 264, {RT,RA,RB,0} }, -{"cax", "o.", XO, 31, 266, {RT,RA,RB,0} }, -{"lscbx", ".", X, 31, 277, {RT,RA,RB,0} }, -{"lhzx", 0, X, 31, 279, {RT,RA,RB,0} }, -{"eqv", ".", X, 31, 284, {RA,RS,RB,0} }, -{"lhzux", 0, X, 31, 311, {RT,RA,RB,0} }, -{"xor", ".", X, 31, 316, {RA,RS,RB,0} }, -{"div", "o.", XO, 31, 331, {RT,RA,RB,0} }, -{"mfspr", 0, X, 31, 339, {RT,SPR,0} }, -{"lhax", 0, X, 31, 343, {RT,RA,RB,0} }, -{"abs", "o.", XO, 31, 360, {RT,RA,0} }, -{"divs", "o.", XO, 31, 363, {RT,RA,RB,0} }, -{"lhaux", 0, X, 31, 375, {RT,RA,RB,0} }, -{"sthx", 0, X, 31, 407, {RS,RA,RB,0} }, -{"orc", ".", X, 31, 412, {RA,RS,RB,0} }, -{"sthux", 0, X, 31, 439, {RS,RA,RB,0} }, -{"or", ".", X, 31, 444, {RA,RS,RB,0} }, -{"mtspr", 0, X, 31, 467, {SPR,RS,0} }, -{"nand", ".", X, 31, 476, {RA,RS,RB,0} }, -{"nabs", "o.", XO, 31, 488, {RT,RA,0} }, -{"mcrxr", 0, X, 31, 512, {BF,0} }, -{"lsx", 0, X, 31, 533, {RT,RA,RB,0} }, -{"lbrx", 0, X, 31, 534, {RT,RA,RB,0} }, -{"lfsx", 0, X, 31, 535, {FRT,RA,RB,0} }, -{"sr", ".", X, 31, 536, {RA,RS,RB,0} }, -{"rrib", ".", X, 31, 537, {RA,RS,RB,0} }, -{"maskir", ".", X, 31, 541, {RA,RS,RB,0} }, -{"lfsux", 0, X, 31, 567, {FRT,RA,RB,0} }, -{"lsi", 0, X, 31, 597, {RT,RA,NB,0} }, -{"lfdx", 0, X, 31, 599, {FRT,RA,RB,0} }, -{"lfdux", 0, X, 31, 631, {FRT,RA,RB,0} }, -{"stsx", 0, X, 31, 661, {RS,RA,RB,0} }, -{"stbrx", 0, X, 31, 662, {RS,RA,RB,0} }, -{"stfsx", 0, X, 31, 663, {FRS,RA,RB,0} }, -{"srq", ".", X, 31, 664, {RA,RS,RB,0} }, -{"sre", ".", X, 31, 665, {RA,RS,RB,0} }, -{"stfsux", 0, X, 31, 695, {FRS,RA,RB,0} }, -{"sriq", ".", X, 31, 696, {RA,RS,SH,0} }, -{"stsi", 0, X, 31, 725, {RS,RA,NB,0} }, -{"stfdx", 0, X, 31, 727, {FRS,RA,RB,0} }, -{"srlq", ".", X, 31, 728, {RA,RS,RB,0} }, -{"sreq", ".", X, 31, 729, {RA,RS,RB,0} }, -{"stfdux", 0, X, 31, 759, {FRS,RA,RB,0} }, -{"srliq", ".", X, 31, 760, {RA,RS,SH,0} }, -{"lhbrx", 0, X, 31, 790, {RT,RA,RB,0} }, -{"sra", ".", X, 31, 792, {RA,RS,RB,0} }, -{"srai", ".", X, 31, 824, {RA,RS,SH,0} }, -{"sthbrx", 0, X, 31, 918, {RS,RA,RB,0} }, -{"sraq", ".", X, 31, 920, {RA,RS,RB,0} }, -{"srea", ".", X, 31, 921, {RA,RS,RB,0} }, -{"exts", ".", X, 31, 922, {RA,RS,0} }, -{"sraiq", ".", X, 31, 952, {RA,RS,SH,0} }, -{"l", 0, D, 32, -1, {RT,DIS,RA,0} }, -{"lu", 0, D, 33, -1, {RT,DIS,RA,0} }, -{"lbz", 0, D, 34, -1, {RT,DIS,RA,0} }, -{"lbzu", 0, D, 35, -1, {RT,DIS,RA,0} }, -{"st", 0, D, 36, -1, {RS,DIS,RA,0} }, -{"stu", 0, D, 37, -1, {RS,DIS,RA,0} }, -{"stb", 0, D, 38, -1, {RS,DIS,RA,0} }, -{"stbu", 0, D, 39, -1, {RS,DIS,RA,0} }, -{"lhz", 0, D, 40, -1, {RT,DIS,RA,0} }, -{"lhzu", 0, D, 41, -1, {RT,DIS,RA,0} }, -{"lha", 0, D, 42, -1, {RT,DIS,RA,0} }, -{"lhau", 0, D, 43, -1, {RT,DIS,RA,0} }, -{"sth", 0, D, 44, -1, {RS,DIS,RA,0} }, -{"sthu", 0, D, 45, -1, {RS,DIS,RA,0} }, -{"lm", 0, D, 46, -1, {RT,DIS,RA,0} }, -{"stm", 0, D, 47, -1, {RS,DIS,RA,0} }, -{"lfs", 0, D, 48, -1, {FRT,DIS,RA,0} }, -{"lfsu", 0, D, 49, -1, {FRT,DIS,RA,0} }, -{"lfd", 0, D, 50, -1, {FRT,DIS,RA,0} }, -{"lfdu", 0, D, 51, -1, {FRT,DIS,RA,0} }, -{"stfs", 0, D, 52, -1, {FRS,DIS,RA,0} }, -{"stfsu", 0, D, 53, -1, {FRS,DIS,RA,0} }, -{"stfd", 0, D, 54, -1, {FRS,DIS,RA,0} }, -{"stfdu", 0, D, 55, -1, {FRS,DIS,RA,0} }, -{"fcmpu", 0, X, 63, 0, {BF,FRA,FRB,0} }, -{"frsp", ".", X, 63, 12, {FRT,FRB,0} }, -{"fd", ".", A, 63, 18, {FRT,FRA,FRB,0} }, -{"fs", ".", A, 63, 20, {FRT,FRA,FRB,0} }, -{"fa", ".", A, 63, 21, {FRT,FRA,FRB,0} }, -{"fm", ".", A, 63, 25, {FRT,FRA,FRC,0} }, -{"fms", ".", A, 63, 28, {FRT,FRA,FRC,FRB,0} }, -{"fma", ".", A, 63, 29, {FRT,FRA,FRC,FRB,0} }, -{"fnms", ".", A, 63, 30, {FRT,FRA,FRC,FRB,0} }, -{"fnma", ".", A, 63, 31, {FRT,FRA,FRC,FRB,0} }, -{"fcmpo", 0, X, 63, 32, {BF,FRA,FRB,0} }, -{"mtfsb1", ".", X, 63, 38, {BT,0} }, -{"fneg", ".", X, 63, 40, {FRT,FRB,0} }, -{"mcrfs", 0, X, 63, 64, {BF,BFA,0} }, -{"mtfsb0", ".", X, 63, 70, {BT,0} }, -{"fmr", ".", X, 63, 72, {FRT,FRB,0} }, -{"mtfsfi", ".", X, 63, 134, {BF,I,0} }, -{"fnabs", ".", X, 63, 136, {FRT,FRB,0} }, -{"fabs", ".", X, 63, 264, {FRT,FRB,0} }, -{"mffs", ".", X, 63, 583, {FRT,0} }, -{"mtfsf", ".", XFL, 63, 711, {FLM,FRB,0} }, -}; - -#define NOPCODES (sizeof (rs6k_ops) / sizeof (struct rs6000_insn)) diff --git a/contrib/gdb/include/opcode/sparc.h b/contrib/gdb/include/opcode/sparc.h deleted file mode 100644 index b9281e6070c..00000000000 --- a/contrib/gdb/include/opcode/sparc.h +++ /dev/null @@ -1,220 +0,0 @@ -/* Definitions for opcode table for the sparc. - Copyright (C) 1989, 1991, 1992, 1995, 1996 Free Software Foundation, Inc. - -This file is part of GAS, the GNU Assembler, GDB, the GNU debugger, and -the GNU Binutils. - -GAS/GDB is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GAS/GDB is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GAS or GDB; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* The SPARC opcode table (and other related data) is defined in - the opcodes library in sparc-opc.c. If you change anything here, make - sure you fix up that file, and vice versa. */ - - /* FIXME-someday: perhaps the ,a's and such should be embedded in the - instruction's name rather than the args. This would make gas faster, pinsn - slower, but would mess up some macros a bit. xoxorich. */ - -/* List of instruction sets variations. - These values are such that each element is either a superset of a - preceding each one or they conflict in which case SPARC_OPCODE_CONFLICT_P - returns non-zero. - The values are indices into `sparc_opcode_archs' defined in sparc-opc.c. - Don't change this without updating sparc-opc.c. */ - -enum sparc_opcode_arch_val { - SPARC_OPCODE_ARCH_V6 = 0, - SPARC_OPCODE_ARCH_V7, - SPARC_OPCODE_ARCH_V8, - SPARC_OPCODE_ARCH_SPARCLET, - SPARC_OPCODE_ARCH_SPARCLITE, - /* v9 variants must appear last */ - SPARC_OPCODE_ARCH_V9, - SPARC_OPCODE_ARCH_V9A, /* v9 with ultrasparc additions */ - SPARC_OPCODE_ARCH_BAD /* error return from sparc_opcode_lookup_arch */ -}; - -/* The highest architecture in the table. */ -#define SPARC_OPCODE_ARCH_MAX (SPARC_OPCODE_ARCH_BAD - 1) - -/* Table of cpu variants. */ - -struct sparc_opcode_arch { - const char *name; - /* Mask of sparc_opcode_arch_val's supported. - EG: For v7 this would be ((1 << v6) | (1 << v7)). */ - /* These are short's because sparc_opcode.architecture is. */ - short supported; -}; - -extern const struct sparc_opcode_arch sparc_opcode_archs[]; - -/* Given architecture name, look up it's sparc_opcode_arch_val value. */ -extern enum sparc_opcode_arch_val sparc_opcode_lookup_arch (); - -/* Return the bitmask of supported architectures for ARCH. */ -#define SPARC_OPCODE_SUPPORTED(ARCH) (sparc_opcode_archs[ARCH].supported) - -/* Non-zero if ARCH1 conflicts with ARCH2. - IE: ARCH1 as a supported bit set that ARCH2 doesn't, and vice versa. */ -#define SPARC_OPCODE_CONFLICT_P(ARCH1, ARCH2) \ -(((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \ - != SPARC_OPCODE_SUPPORTED (ARCH1)) \ - && ((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \ - != SPARC_OPCODE_SUPPORTED (ARCH2))) - -/* Structure of an opcode table entry. */ - -struct sparc_opcode { - const char *name; - unsigned long match; /* Bits that must be set. */ - unsigned long lose; /* Bits that must not be set. */ - const char *args; - /* This was called "delayed" in versions before the flags. */ - char flags; - short architecture; /* Bitmask of sparc_opcode_arch_val's. */ -}; - -#define F_DELAYED 1 /* Delayed branch */ -#define F_ALIAS 2 /* Alias for a "real" instruction */ -#define F_UNBR 4 /* Unconditional branch */ -#define F_CONDBR 8 /* Conditional branch */ -#define F_JSR 16 /* Subroutine call */ -/* FIXME: Add F_ANACHRONISTIC flag for v9. */ - -/* - -All sparc opcodes are 32 bits, except for the `set' instruction (really a -macro), which is 64 bits. It is handled as a special case. - -The match component is a mask saying which bits must match a particular -opcode in order for an instruction to be an instance of that opcode. - -The args component is a string containing one character for each operand of the -instruction. - -Kinds of operands: - # Number used by optimizer. It is ignored. - 1 rs1 register. - 2 rs2 register. - d rd register. - e frs1 floating point register. - v frs1 floating point register (double/even). - V frs1 floating point register (quad/multiple of 4). - f frs2 floating point register. - B frs2 floating point register (double/even). - R frs2 floating point register (quad/multiple of 4). - g frsd floating point register. - H frsd floating point register (double/even). - J frsd floating point register (quad/multiple of 4). - b crs1 coprocessor register - c crs2 coprocessor register - D crsd coprocessor register - m alternate space register (asr) in rd - M alternate space register (asr) in rs1 - h 22 high bits. - K MEMBAR mask (7 bits). (v9) - j 10 bit Immediate. (v9) - I 11 bit Immediate. (v9) - i 13 bit Immediate. - n 22 bit immediate. - k 2+14 bit PC relative immediate. (v9) - G 19 bit PC relative immediate. (v9) - l 22 bit PC relative immediate. - L 30 bit PC relative immediate. - a Annul. The annul bit is set. - A Alternate address space. Stored as 8 bits. - C Coprocessor state register. - F floating point state register. - p Processor state register. - N Branch predict clear ",pn" (v9) - T Branch predict set ",pt" (v9) - z %icc. (v9) - Z %xcc. (v9) - q Floating point queue. - r Single register that is both rs1 and rd. - O Single register that is both rs2 and rd. - Q Coprocessor queue. - S Special case. - t Trap base register. - w Window invalid mask register. - y Y register. - u sparclet coprocessor registers in rd position - U sparclet coprocessor registers in rs1 position - E %ccr. (v9) - s %fprs. (v9) - P %pc. (v9) - W %tick. (v9) - o %asi. (v9) - 6 %fcc0. (v9) - 7 %fcc1. (v9) - 8 %fcc2. (v9) - 9 %fcc3. (v9) - ! Privileged Register in rd (v9) - ? Privileged Register in rs1 (v9) - * Prefetch function constant. (v9) - x OPF field (v9 impdep). - -The following chars are unused: (note: ,[] are used as punctuation) -[XY3450] - -*/ - -#define OP2(x) (((x)&0x7) << 22) /* op2 field of format2 insns */ -#define OP3(x) (((x)&0x3f) << 19) /* op3 field of format3 insns */ -#define OP(x) ((unsigned)((x)&0x3) << 30) /* op field of all insns */ -#define OPF(x) (((x)&0x1ff) << 5) /* opf field of float insns */ -#define OPF_LOW5(x) OPF((x)&0x1f) /* v9 */ -#define F3F(x, y, z) (OP(x) | OP3(y) | OPF(z)) /* format3 float insns */ -#define F3I(x) (((x)&0x1) << 13) /* immediate field of format 3 insns */ -#define F2(x, y) (OP(x) | OP2(y)) /* format 2 insns */ -#define F3(x, y, z) (OP(x) | OP3(y) | F3I(z)) /* format3 insns */ -#define F1(x) (OP(x)) -#define DISP30(x) ((x)&0x3fffffff) -#define ASI(x) (((x)&0xff) << 5) /* asi field of format3 insns */ -#define RS2(x) ((x)&0x1f) /* rs2 field */ -#define SIMM13(x) ((x)&0x1fff) /* simm13 field */ -#define RD(x) (((x)&0x1f) << 25) /* destination register field */ -#define RS1(x) (((x)&0x1f) << 14) /* rs1 field */ -#define ASI_RS2(x) (SIMM13(x)) -#define MEMBAR(x) ((x)&0x7f) - -#define ANNUL (1<<29) -#define BPRED (1<<19) /* v9 */ -#define IMMED F3I(1) -#define RD_G0 RD(~0) -#define RS1_G0 RS1(~0) -#define RS2_G0 RS2(~0) - -extern struct sparc_opcode sparc_opcodes[]; -extern const int sparc_num_opcodes; - -int sparc_encode_asi (); -char *sparc_decode_asi (); -int sparc_encode_membar (); -char *sparc_decode_membar (); -int sparc_encode_prefetch (); -char *sparc_decode_prefetch (); -int sparc_encode_sparclet_cpreg (); -char *sparc_decode_sparclet_cpreg (); - -/* - * Local Variables: - * fill-column: 131 - * comment-column: 0 - * End: - */ - -/* end of sparc.h */ diff --git a/contrib/gdb/include/opcode/tahoe.h b/contrib/gdb/include/opcode/tahoe.h deleted file mode 100644 index b5cee249ee4..00000000000 --- a/contrib/gdb/include/opcode/tahoe.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Ported by the State University of New York at Buffalo by the Distributed - * Computer Systems Lab, Department of Computer Science, 1991. - */ - -#ifndef tahoe_opcodeT -#define tahoe_opcodeT int -#endif /* no tahoe_opcodeT */ - -struct vot_wot /* tahoe opcode table: wot to do with this */ - /* particular opcode */ -{ - char * args; /* how to compile said opcode */ - tahoe_opcodeT code; /* op-code (may be > 8 bits!) */ -}; - -struct vot /* tahoe opcode text */ -{ - char * name; /* opcode name: lowercase string [key] */ - struct vot_wot detail; /* rest of opcode table [datum] */ -}; - -#define vot_how args -#define vot_code code -#define vot_detail detail -#define vot_name name - -static struct vot -votstrs[] = -{ -{ "halt", {"", 0x00 } }, -{ "sinf", {"", 0x05 } }, -{ "ldf", {"rl", 0x06 } }, -{ "ldd", {"rq", 0x07 } }, -{ "addb2", {"rbmb", 0x08 } }, -{ "movb", {"rbwb", 0x09 } }, -{ "addw2", {"rwmw", 0x0a } }, -{ "movw", {"rwww", 0x0b } }, -{ "addl2", {"rlml", 0x0c } }, -{ "movl", {"rlwl", 0x0d } }, -{ "bbs", {"rlvlbw", 0x0e } }, -{ "nop", {"", 0x10 } }, -{ "brb", {"bb", 0x11 } }, -{ "brw", {"bw", 0x13 } }, -{ "cosf", {"", 0x15 } }, -{ "lnf", {"rl", 0x16 } }, -{ "lnd", {"rq", 0x17 } }, -{ "addb3", {"rbrbwb", 0x18 } }, -{ "cmpb", {"rbwb", 0x19 } }, -{ "addw3", {"rwrwww", 0x1a } }, -{ "cmpw", {"rwww", 0x1b } }, -{ "addl3", {"rlrlwl", 0x1c } }, -{ "cmpl", {"rlwl", 0x1d } }, -{ "bbc", {"rlvlbw", 0x1e } }, -{ "rei", {"", 0x20 } }, -{ "bneq", {"bb", 0x21 } }, -{ "bnequ", {"bb", 0x21 } }, -{ "cvtwl", {"rwwl", 0x23 } }, -{ "stf", {"wl", 0x26 } }, -{ "std", {"wq", 0x27 } }, -{ "subb2", {"rbmb", 0x28 } }, -{ "mcomb", {"rbwb", 0x29 } }, -{ "subw2", {"rwmw", 0x2a } }, -{ "mcomw", {"rwww", 0x2b } }, -{ "subl2", {"rlml", 0x2c } }, -{ "mcoml", {"rlwl", 0x2d } }, -{ "emul", {"rlrlrlwq", 0x2e } }, -{ "aoblss", {"rlmlbw", 0x2f } }, -{ "bpt", {"", 0x30 } }, -{ "beql", {"bb", 0x31 } }, -{ "beqlu", {"bb", 0x31 } }, -{ "cvtwb", {"rwwb", 0x33 } }, -{ "logf", {"", 0x35 } }, -{ "cmpf", {"rl", 0x36 } }, -{ "cmpd", {"rq", 0x37 } }, -{ "subb3", {"rbrbwb", 0x38 } }, -{ "bitb", {"rbrb", 0x39 } }, -{ "subw3", {"rwrwww", 0x3a } }, -{ "bitw", {"rwrw", 0x3b } }, -{ "subl3", {"rlrlwl", 0x3c } }, -{ "bitl", {"rlrl", 0x3d } }, -{ "ediv", {"rlrqwlwl", 0x3e } }, -{ "aobleq", {"rlmlbw", 0x3f } }, -{ "ret", {"", 0x40 } }, -{ "bgtr", {"bb", 0x41 } }, -{ "sqrtf", {"", 0x45 } }, -{ "cmpf2", {"rl", 0x46 } }, -{ "cmpd2", {"rqrq", 0x47 } }, -{ "shll", {"rbrlwl", 0x48 } }, -{ "clrb", {"wb", 0x49 } }, -{ "shlq", {"rbrqwq", 0x4a } }, -{ "clrw", {"ww", 0x4b } }, -{ "mull2", {"rlml", 0x4c } }, -{ "clrl", {"wl", 0x4d } }, -{ "shal", {"rbrlwl", 0x4e } }, -{ "bleq", {"bb", 0x51 } }, -{ "expf", {"", 0x55 } }, -{ "tstf", {"", 0x56 } }, -{ "tstd", {"", 0x57 } }, -{ "shrl", {"rbrlwl", 0x58 } }, -{ "tstb", {"rb", 0x59 } }, -{ "shrq", {"rbrqwq", 0x5a } }, -{ "tstw", {"rw", 0x5b } }, -{ "mull3", {"rlrlwl", 0x5c } }, -{ "tstl", {"rl", 0x5d } }, -{ "shar", {"rbrlwl", 0x5e } }, -{ "bbssi", {"rlmlbw", 0x5f } }, -{ "ldpctx", {"", 0x60 } }, -{ "pushd", {"", 0x67 } }, -{ "incb", {"mb", 0x69 } }, -{ "incw", {"mw", 0x6b } }, -{ "divl2", {"rlml", 0x6c } }, -{ "incl", {"ml", 0x6d } }, -{ "cvtlb", {"rlwb", 0x6f } }, -{ "svpctx", {"", 0x70 } }, -{ "jmp", {"ab", 0x71 } }, -{ "cvlf", {"rl", 0x76 } }, -{ "cvld", {"rl", 0x77 } }, -{ "decb", {"mb", 0x79 } }, -{ "decw", {"mw", 0x7b } }, -{ "divl3", {"rlrlwl", 0x7c } }, -{ "decl", {"ml", 0x7d } }, -{ "cvtlw", {"rlww", 0x7f } }, -{ "bgeq", {"bb", 0x81 } }, -{ "movs2", {"abab", 0x82 } }, -{ "cvfl", {"wl", 0x86 } }, -{ "cvdl", {"wl", 0x87 } }, -{ "orb2", {"rbmb", 0x88 } }, -{ "cvtbl", {"rbwl", 0x89 } }, -{ "orw2", {"rwmw", 0x8a } }, -{ "bispsw", {"rw", 0x8b } }, -{ "orl2", {"rlml", 0x8c } }, -{ "adwc", {"rlml", 0x8d } }, -{ "adda", {"rlml", 0x8e } }, -{ "blss", {"bb", 0x91 } }, -{ "cmps2", {"abab", 0x92 } }, -{ "ldfd", {"rl", 0x97 } }, -{ "orb3", {"rbrbwb", 0x98 } }, -{ "cvtbw", {"rbww", 0x99 } }, -{ "orw3", {"rwrwww", 0x9a } }, -{ "bicpsw", {"rw", 0x9b } }, -{ "orl3", {"rlrlwl", 0x9c } }, -{ "sbwc", {"rlml", 0x9d } }, -{ "suba", {"rlml", 0x9e } }, -{ "bgtru", {"bb", 0xa1 } }, -{ "cvdf", {"", 0xa6 } }, -{ "andb2", {"rbmb", 0xa8 } }, -{ "movzbl", {"rbwl", 0xa9 } }, -{ "andw2", {"rwmw", 0xaa } }, -{ "loadr", {"rwal", 0xab } }, -{ "andl2", {"rlml", 0xac } }, -{ "mtpr", {"rlrl", 0xad } }, -{ "ffs", {"rlwl", 0xae } }, -{ "blequ", {"bb", 0xb1 } }, -{ "negf", {"", 0xb6 } }, -{ "negd", {"", 0xb7 } }, -{ "andb3", {"rbrbwb", 0xb8 } }, -{ "movzbw", {"rbww", 0xb9 } }, -{ "andw3", {"rwrwww", 0xba } }, -{ "storer", {"rwal", 0xbb } }, -{ "andl3", {"rlrlwl", 0xbc } }, -{ "mfpr", {"rlwl", 0xbd } }, -{ "ffc", {"rlwl", 0xbe } }, -{ "calls", {"rbab", 0xbf } }, -{ "prober", {"rbabrl", 0xc0 } }, -{ "bvc", {"bb", 0xc1 } }, -{ "movs3", {"ababrw", 0xc2 } }, -{ "movzwl", {"rwwl", 0xc3 } }, -{ "addf", {"rl", 0xc6 } }, -{ "addd", {"rq", 0xc7 } }, -{ "xorb2", {"rbmb", 0xc8 } }, -{ "movob", {"rbwb", 0xc9 } }, -{ "xorw2", {"rwmw", 0xca } }, -{ "movow", {"rwww", 0xcb } }, -{ "xorl2", {"rlml", 0xcc } }, -{ "movpsl", {"wl", 0xcd } }, -{ "kcall", {"rw", 0xcf } }, -{ "probew", {"rbabrl", 0xd0 } }, -{ "bvs", {"bb", 0xd1 } }, -{ "cmps3", {"ababrw", 0xd2 } }, -{ "subf", {"rq", 0xd6 } }, -{ "subd", {"rq", 0xd7 } }, -{ "xorb3", {"rbrbwb", 0xd8 } }, -{ "pushb", {"rb", 0xd9 } }, -{ "xorw3", {"rwrwww", 0xda } }, -{ "pushw", {"rw", 0xdb } }, -{ "xorl3", {"rlrlwl", 0xdc } }, -{ "pushl", {"rl", 0xdd } }, -{ "insque", {"abab", 0xe0 } }, -{ "bcs", {"bb", 0xe1 } }, -{ "bgequ", {"bb", 0xe1 } }, -{ "mulf", {"rq", 0xe6 } }, -{ "muld", {"rq", 0xe7 } }, -{ "mnegb", {"rbwb", 0xe8 } }, -{ "movab", {"abwl", 0xe9 } }, -{ "mnegw", {"rwww", 0xea } }, -{ "movaw", {"awwl", 0xeb } }, -{ "mnegl", {"rlwl", 0xec } }, -{ "moval", {"alwl", 0xed } }, -{ "remque", {"ab", 0xf0 } }, -{ "bcc", {"bb", 0xf1 } }, -{ "blssu", {"bb", 0xf1 } }, -{ "divf", {"rq", 0xf6 } }, -{ "divd", {"rq", 0xf7 } }, -{ "movblk", {"alalrw", 0xf8 } }, -{ "pushab", {"ab", 0xf9 } }, -{ "pushaw", {"aw", 0xfb } }, -{ "casel", {"rlrlrl", 0xfc } }, -{ "pushal", {"al", 0xfd } }, -{ "callf", {"rbab", 0xfe } }, -{ "" , "" } /* empty is end sentinel */ - -}; diff --git a/contrib/gdb/include/opcode/vax.h b/contrib/gdb/include/opcode/vax.h deleted file mode 100644 index f3afebde7e3..00000000000 --- a/contrib/gdb/include/opcode/vax.h +++ /dev/null @@ -1,382 +0,0 @@ -/* Vax opcde list. - Copyright (C) 1989, 1995 Free Software Foundation, Inc. - -This file is part of GDB and GAS. - -GDB and GAS are free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GDB and GAS are distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GDB or GAS; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef vax_opcodeT -#define vax_opcodeT int -#endif /* no vax_opcodeT */ - -struct vot_wot /* vax opcode table: wot to do with this */ - /* particular opcode */ -{ - const char *args; /* how to compile said opcode */ - vax_opcodeT code; /* op-code (may be > 8 bits!) */ -}; - -struct vot /* vax opcode text */ -{ - const char *name; /* opcode name: lowercase string [key] */ - struct vot_wot detail; /* rest of opcode table [datum] */ -}; - -#define vot_how args -#define vot_code code -#define vot_detail detail -#define vot_name name - -static const struct vot -votstrs[] = -{ -{ "halt", {"", 0x00 } }, -{ "nop", {"", 0x01 } }, -{ "rei", {"", 0x02 } }, -{ "bpt", {"", 0x03 } }, -{ "ret", {"", 0x04 } }, -{ "rsb", {"", 0x05 } }, -{ "ldpctx", {"", 0x06 } }, -{ "svpctx", {"", 0x07 } }, -{ "cvtps", {"rwabrwab", 0x08 } }, -{ "cvtsp", {"rwabrwab", 0x09 } }, -{ "index", {"rlrlrlrlrlwl", 0x0a } }, -{ "crc", {"abrlrwab", 0x0b } }, -{ "prober", {"rbrwab", 0x0c } }, -{ "probew", {"rbrwab", 0x0d } }, -{ "insque", {"abab", 0x0e } }, -{ "remque", {"abwl", 0x0f } }, -{ "bsbb", {"bb", 0x10 } }, -{ "brb", {"bb", 0x11 } }, -{ "bneq", {"bb", 0x12 } }, -{ "bnequ", {"bb", 0x12 } }, -{ "beql", {"bb", 0x13 } }, -{ "beqlu", {"bb", 0x13 } }, -{ "bgtr", {"bb", 0x14 } }, -{ "bleq", {"bb", 0x15 } }, -{ "jsb", {"ab", 0x16 } }, -{ "jmp", {"ab", 0x17 } }, -{ "bgeq", {"bb", 0x18 } }, -{ "blss", {"bb", 0x19 } }, -{ "bgtru", {"bb", 0x1a } }, -{ "blequ", {"bb", 0x1b } }, -{ "bvc", {"bb", 0x1c } }, -{ "bvs", {"bb", 0x1d } }, -{ "bcc", {"bb", 0x1e } }, -{ "bgequ", {"bb", 0x1e } }, -{ "blssu", {"bb", 0x1f } }, -{ "bcs", {"bb", 0x1f } }, -{ "addp4", {"rwabrwab", 0x20 } }, -{ "addp6", {"rwabrwabrwab", 0x21 } }, -{ "subp4", {"rwabrwab", 0x22 } }, -{ "subp6", {"rwabrwabrwab", 0x23 } }, -{ "cvtpt", {"rwababrwab", 0x24 } }, -{ "mulp", {"rwabrwabrwab", 0x25 } }, -{ "cvttp", {"rwababrwab", 0x26 } }, -{ "divp", {"rwabrwabrwab", 0x27 } }, -{ "movc3", {"rwabab", 0x28 } }, -{ "cmpc3", {"rwabab", 0x29 } }, -{ "scanc", {"rwababrb", 0x2a } }, -{ "spanc", {"rwababrb", 0x2b } }, -{ "movc5", {"rwabrbrwab", 0x2c } }, -{ "cmpc5", {"rwabrbrwab", 0x2d } }, -{ "movtc", {"rwabrbabrwab", 0x2e } }, -{ "movtuc", {"rwabrbabrwab", 0x2f } }, -{ "bsbw", {"bw", 0x30 } }, -{ "brw", {"bw", 0x31 } }, -{ "cvtwl", {"rwwl", 0x32 } }, -{ "cvtwb", {"rwwb", 0x33 } }, -{ "movp", {"rwabab", 0x34 } }, -{ "cmpp3", {"rwabab", 0x35 } }, -{ "cvtpl", {"rwabwl", 0x36 } }, -{ "cmpp4", {"rwabrwab", 0x37 } }, -{ "editpc", {"rwababab", 0x38 } }, -{ "matchc", {"rwabrwab", 0x39 } }, -{ "locc", {"rbrwab", 0x3a } }, -{ "skpc", {"rbrwab", 0x3b } }, -{ "movzwl", {"rwwl", 0x3c } }, -{ "acbw", {"rwrwmwbw", 0x3d } }, -{ "movaw", {"awwl", 0x3e } }, -{ "pushaw", {"aw", 0x3f } }, -{ "addf2", {"rfmf", 0x40 } }, -{ "addf3", {"rfrfwf", 0x41 } }, -{ "subf2", {"rfmf", 0x42 } }, -{ "subf3", {"rfrfwf", 0x43 } }, -{ "mulf2", {"rfmf", 0x44 } }, -{ "mulf3", {"rfrfwf", 0x45 } }, -{ "divf2", {"rfmf", 0x46 } }, -{ "divf3", {"rfrfwf", 0x47 } }, -{ "cvtfb", {"rfwb", 0x48 } }, -{ "cvtfw", {"rfww", 0x49 } }, -{ "cvtfl", {"rfwl", 0x4a } }, -{ "cvtrfl", {"rfwl", 0x4b } }, -{ "cvtbf", {"rbwf", 0x4c } }, -{ "cvtwf", {"rwwf", 0x4d } }, -{ "cvtlf", {"rlwf", 0x4e } }, -{ "acbf", {"rfrfmfbw", 0x4f } }, -{ "movf", {"rfwf", 0x50 } }, -{ "cmpf", {"rfrf", 0x51 } }, -{ "mnegf", {"rfwf", 0x52 } }, -{ "tstf", {"rf", 0x53 } }, -{ "emodf", {"rfrbrfwlwf", 0x54 } }, -{ "polyf", {"rfrwab", 0x55 } }, -{ "cvtfd", {"rfwd", 0x56 } }, - /* opcode 57 is not defined yet */ -{ "adawi", {"rwmw", 0x58 } }, - /* opcode 59 is not defined yet */ - /* opcode 5a is not defined yet */ - /* opcode 5b is not defined yet */ -{ "insqhi", {"abaq", 0x5c } }, -{ "insqti", {"abaq", 0x5d } }, -{ "remqhi", {"aqwl", 0x5e } }, -{ "remqti", {"aqwl", 0x5f } }, -{ "addd2", {"rdmd", 0x60 } }, -{ "addd3", {"rdrdwd", 0x61 } }, -{ "subd2", {"rdmd", 0x62 } }, -{ "subd3", {"rdrdwd", 0x63 } }, -{ "muld2", {"rdmd", 0x64 } }, -{ "muld3", {"rdrdwd", 0x65 } }, -{ "divd2", {"rdmd", 0x66 } }, -{ "divd3", {"rdrdwd", 0x67 } }, -{ "cvtdb", {"rdwb", 0x68 } }, -{ "cvtdw", {"rdww", 0x69 } }, -{ "cvtdl", {"rdwl", 0x6a } }, -{ "cvtrdl", {"rdwl", 0x6b } }, -{ "cvtbd", {"rbwd", 0x6c } }, -{ "cvtwd", {"rwwd", 0x6d } }, -{ "cvtld", {"rlwd", 0x6e } }, -{ "acbd", {"rdrdmdbw", 0x6f } }, -{ "movd", {"rdwd", 0x70 } }, -{ "cmpd", {"rdrd", 0x71 } }, -{ "mnegd", {"rdwd", 0x72 } }, -{ "tstd", {"rd", 0x73 } }, -{ "emodd", {"rdrbrdwlwd", 0x74 } }, -{ "polyd", {"rdrwab", 0x75 } }, -{ "cvtdf", {"rdwf", 0x76 } }, - /* opcode 77 is not defined yet */ -{ "ashl", {"rbrlwl", 0x78 } }, -{ "ashq", {"rbrqwq", 0x79 } }, -{ "emul", {"rlrlrlwq", 0x7a } }, -{ "ediv", {"rlrqwlwl", 0x7b } }, -{ "clrd", {"wd", 0x7c } }, -{ "clrg", {"wg", 0x7c } }, -{ "clrq", {"wd", 0x7c } }, -{ "movq", {"rqwq", 0x7d } }, -{ "movaq", {"aqwl", 0x7e } }, -{ "movad", {"adwl", 0x7e } }, -{ "pushaq", {"aq", 0x7f } }, -{ "pushad", {"ad", 0x7f } }, -{ "addb2", {"rbmb", 0x80 } }, -{ "addb3", {"rbrbwb", 0x81 } }, -{ "subb2", {"rbmb", 0x82 } }, -{ "subb3", {"rbrbwb", 0x83 } }, -{ "mulb2", {"rbmb", 0x84 } }, -{ "mulb3", {"rbrbwb", 0x85 } }, -{ "divb2", {"rbmb", 0x86 } }, -{ "divb3", {"rbrbwb", 0x87 } }, -{ "bisb2", {"rbmb", 0x88 } }, -{ "bisb3", {"rbrbwb", 0x89 } }, -{ "bicb2", {"rbmb", 0x8a } }, -{ "bicb3", {"rbrbwb", 0x8b } }, -{ "xorb2", {"rbmb", 0x8c } }, -{ "xorb3", {"rbrbwb", 0x8d } }, -{ "mnegb", {"rbwb", 0x8e } }, -{ "caseb", {"rbrbrb", 0x8f } }, -{ "movb", {"rbwb", 0x90 } }, -{ "cmpb", {"rbrb", 0x91 } }, -{ "mcomb", {"rbwb", 0x92 } }, -{ "bitb", {"rbrb", 0x93 } }, -{ "clrb", {"wb", 0x94 } }, -{ "tstb", {"rb", 0x95 } }, -{ "incb", {"mb", 0x96 } }, -{ "decb", {"mb", 0x97 } }, -{ "cvtbl", {"rbwl", 0x98 } }, -{ "cvtbw", {"rbww", 0x99 } }, -{ "movzbl", {"rbwl", 0x9a } }, -{ "movzbw", {"rbww", 0x9b } }, -{ "rotl", {"rbrlwl", 0x9c } }, -{ "acbb", {"rbrbmbbw", 0x9d } }, -{ "movab", {"abwl", 0x9e } }, -{ "pushab", {"ab", 0x9f } }, -{ "addw2", {"rwmw", 0xa0 } }, -{ "addw3", {"rwrwww", 0xa1 } }, -{ "subw2", {"rwmw", 0xa2 } }, -{ "subw3", {"rwrwww", 0xa3 } }, -{ "mulw2", {"rwmw", 0xa4 } }, -{ "mulw3", {"rwrwww", 0xa5 } }, -{ "divw2", {"rwmw", 0xa6 } }, -{ "divw3", {"rwrwww", 0xa7 } }, -{ "bisw2", {"rwmw", 0xa8 } }, -{ "bisw3", {"rwrwww", 0xa9 } }, -{ "bicw2", {"rwmw", 0xaa } }, -{ "bicw3", {"rwrwww", 0xab } }, -{ "xorw2", {"rwmw", 0xac } }, -{ "xorw3", {"rwrwww", 0xad } }, -{ "mnegw", {"rwww", 0xae } }, -{ "casew", {"rwrwrw", 0xaf } }, -{ "movw", {"rwww", 0xb0 } }, -{ "cmpw", {"rwrw", 0xb1 } }, -{ "mcomw", {"rwww", 0xb2 } }, -{ "bitw", {"rwrw", 0xb3 } }, -{ "clrw", {"ww", 0xb4 } }, -{ "tstw", {"rw", 0xb5 } }, -{ "incw", {"mw", 0xb6 } }, -{ "decw", {"mw", 0xb7 } }, -{ "bispsw", {"rw", 0xb8 } }, -{ "bicpsw", {"rw", 0xb9 } }, -{ "popr", {"rw", 0xba } }, -{ "pushr", {"rw", 0xbb } }, -{ "chmk", {"rw", 0xbc } }, -{ "chme", {"rw", 0xbd } }, -{ "chms", {"rw", 0xbe } }, -{ "chmu", {"rw", 0xbf } }, -{ "addl2", {"rlml", 0xc0 } }, -{ "addl3", {"rlrlwl", 0xc1 } }, -{ "subl2", {"rlml", 0xc2 } }, -{ "subl3", {"rlrlwl", 0xc3 } }, -{ "mull2", {"rlml", 0xc4 } }, -{ "mull3", {"rlrlwl", 0xc5 } }, -{ "divl2", {"rlml", 0xc6 } }, -{ "divl3", {"rlrlwl", 0xc7 } }, -{ "bisl2", {"rlml", 0xc8 } }, -{ "bisl3", {"rlrlwl", 0xc9 } }, -{ "bicl2", {"rlml", 0xca } }, -{ "bicl3", {"rlrlwl", 0xcb } }, -{ "xorl2", {"rlml", 0xcc } }, -{ "xorl3", {"rlrlwl", 0xcd } }, -{ "mnegl", {"rlwl", 0xce } }, -{ "casel", {"rlrlrl", 0xcf } }, -{ "movl", {"rlwl", 0xd0 } }, -{ "cmpl", {"rlrl", 0xd1 } }, -{ "mcoml", {"rlwl", 0xd2 } }, -{ "bitl", {"rlrl", 0xd3 } }, -{ "clrf", {"wf", 0xd4 } }, -{ "clrl", {"wl", 0xd4 } }, -{ "tstl", {"rl", 0xd5 } }, -{ "incl", {"ml", 0xd6 } }, -{ "decl", {"ml", 0xd7 } }, -{ "adwc", {"rlml", 0xd8 } }, -{ "sbwc", {"rlml", 0xd9 } }, -{ "mtpr", {"rlrl", 0xda } }, -{ "mfpr", {"rlwl", 0xdb } }, -{ "movpsl", {"wl", 0xdc } }, -{ "pushl", {"rl", 0xdd } }, -{ "moval", {"alwl", 0xde } }, -{ "movaf", {"afwl", 0xde } }, -{ "pushal", {"al", 0xdf } }, -{ "pushaf", {"af", 0xdf } }, -{ "bbs", {"rlvbbb", 0xe0 } }, -{ "bbc", {"rlvbbb", 0xe1 } }, -{ "bbss", {"rlvbbb", 0xe2 } }, -{ "bbcs", {"rlvbbb", 0xe3 } }, -{ "bbsc", {"rlvbbb", 0xe4 } }, -{ "bbcc", {"rlvbbb", 0xe5 } }, -{ "bbssi", {"rlvbbb", 0xe6 } }, -{ "bbcci", {"rlvbbb", 0xe7 } }, -{ "blbs", {"rlbb", 0xe8 } }, -{ "blbc", {"rlbb", 0xe9 } }, -{ "ffs", {"rlrbvbwl", 0xea } }, -{ "ffc", {"rlrbvbwl", 0xeb } }, -{ "cmpv", {"rlrbvbrl", 0xec } }, -{ "cmpzv", {"rlrbvbrl", 0xed } }, -{ "extv", {"rlrbvbwl", 0xee } }, -{ "extzv", {"rlrbvbwl", 0xef } }, -{ "insv", {"rlrlrbvb", 0xf0 } }, -{ "acbl", {"rlrlmlbw", 0xf1 } }, -{ "aoblss", {"rlmlbb", 0xf2 } }, -{ "aobleq", {"rlmlbb", 0xf3 } }, -{ "sobgeq", {"mlbb", 0xf4 } }, -{ "sobgtr", {"mlbb", 0xf5 } }, -{ "cvtlb", {"rlwb", 0xf6 } }, -{ "cvtlw", {"rlww", 0xf7 } }, -{ "ashp", {"rbrwabrbrwab", 0xf8 } }, -{ "cvtlp", {"rlrwab", 0xf9 } }, -{ "callg", {"abab", 0xfa } }, -{ "calls", {"rlab", 0xfb } }, -{ "xfc", {"", 0xfc } }, - /* undefined opcodes here */ -{ "cvtdh", {"rdwh", 0x32fd } }, -{ "cvtgf", {"rgwh", 0x33fd } }, -{ "addg2", {"rgmg", 0x40fd } }, -{ "addg3", {"rgrgwg", 0x41fd } }, -{ "subg2", {"rgmg", 0x42fd } }, -{ "subg3", {"rgrgwg", 0x43fd } }, -{ "mulg2", {"rgmg", 0x44fd } }, -{ "mulg3", {"rgrgwg", 0x45fd } }, -{ "divg2", {"rgmg", 0x46fd } }, -{ "divg3", {"rgrgwg", 0x47fd } }, -{ "cvtgb", {"rgwb", 0x48fd } }, -{ "cvtgw", {"rgww", 0x49fd } }, -{ "cvtgl", {"rgwl", 0x4afd } }, -{ "cvtrgl", {"rgwl", 0x4bfd } }, -{ "cvtbg", {"rbwg", 0x4cfd } }, -{ "cvtwg", {"rwwg", 0x4dfd } }, -{ "cvtlg", {"rlwg", 0x4efd } }, -{ "acbg", {"rgrgmgbw", 0x4ffd } }, -{ "movg", {"rgwg", 0x50fd } }, -{ "cmpg", {"rgrg", 0x51fd } }, -{ "mnegg", {"rgwg", 0x52fd } }, -{ "tstg", {"rg", 0x53fd } }, -{ "emodg", {"rgrwrgwlwg", 0x54fd } }, -{ "polyg", {"rgrwab", 0x55fd } }, -{ "cvtgh", {"rgwh", 0x56fd } }, - /* undefined opcodes here */ -{ "addh2", {"rhmh", 0x60fd } }, -{ "addh3", {"rhrhwh", 0x61fd } }, -{ "subh2", {"rhmh", 0x62fd } }, -{ "subh3", {"rhrhwh", 0x63fd } }, -{ "mulh2", {"rhmh", 0x64fd } }, -{ "mulh3", {"rhrhwh", 0x65fd } }, -{ "divh2", {"rhmh", 0x66fd } }, -{ "divh3", {"rhrhwh", 0x67fd } }, -{ "cvthb", {"rhwb", 0x68fd } }, -{ "cvthw", {"rhww", 0x69fd } }, -{ "cvthl", {"rhwl", 0x6afd } }, -{ "cvtrhl", {"rhwl", 0x6bfd } }, -{ "cvtbh", {"rbwh", 0x6cfd } }, -{ "cvtwh", {"rwwh", 0x6dfd } }, -{ "cvtlh", {"rlwh", 0x6efd } }, -{ "acbh", {"rhrhmhbw", 0x6ffd } }, -{ "movh", {"rhwh", 0x70fd } }, -{ "cmph", {"rhrh", 0x71fd } }, -{ "mnegh", {"rhwh", 0x72fd } }, -{ "tsth", {"rh", 0x73fd } }, -{ "emodh", {"rhrwrhwlwh", 0x74fd } }, -{ "polyh", {"rhrwab", 0x75fd } }, -{ "cvthg", {"rhwg", 0x76fd } }, - /* undefined opcodes here */ -{ "clrh", {"wh", 0x7cfd } }, -{ "clro", {"wo", 0x7cfd } }, -{ "movo", {"rowo", 0x7dfd } }, -{ "movah", {"ahwl", 0x7efd } }, -{ "movao", {"aowl", 0x7efd } }, -{ "pushah", {"ah", 0x7ffd } }, -{ "pushao", {"ao", 0x7ffd } }, - /* undefined opcodes here */ -{ "cvtfh", {"rfwh", 0x98fd } }, -{ "cvtfg", {"rfwg", 0x99fd } }, - /* undefined opcodes here */ -{ "cvthf", {"rhwf", 0xf6fd } }, -{ "cvthd", {"rhwd", 0xf7fd } }, - /* undefined opcodes here */ -{ "bugl", {"rl", 0xfdff } }, -{ "bugw", {"rw", 0xfeff } }, - /* undefined opcodes here */ - -{ "", {"", 0} } /* empty is end sentinel */ - -}; /* votstrs */ - -/* end: vax.opcode.h */ diff --git a/contrib/gdb/include/os9k.h b/contrib/gdb/include/os9k.h deleted file mode 100644 index 0f2eed2d3b1..00000000000 --- a/contrib/gdb/include/os9k.h +++ /dev/null @@ -1,169 +0,0 @@ -#if !defined(_MODULE_H) -#define _MODULE_H - -/* OS-9000 i386 module header definitions */ -#define _MPF386 - -/* sizeof common header less parity field */ -#define N_M_PARITY (sizeof(mh_com)-sizeof(unisgned short)) -#define OLD_M_PARITY 46 -#define M_PARITY N_M_PARITY - -#ifdef _MPF68K -#define MODSYNC 0x4afd /* module header sync code for 680x0 processors */ -#endif - -#ifdef _MPF386 -#define MODSYNC 0x4afc /* module header sync code for 80386 processors */ -#endif - -#define MODREV 1 /* module format revision 1 */ -#define CRCCON 0x800fe3 /* crc polynomial constant */ - -/* Module access permission values */ -#define MP_OWNER_READ 0x0001 -#define MP_OWNER_WRITE 0x0002 -#define MP_OWNER_EXEC 0x0004 -#define MP_GROUP_READ 0x0010 -#define MP_GROUP_WRITE 0x0020 -#define MP_GROUP_EXEC 0x0040 -#define MP_WORLD_READ 0x0100 -#define MP_WORLD_WRITE 0x0200 -#define MP_WORLD_EXEC 0x0400 -#define MP_WORLD_ACCESS 0x0777 -#define MP_OWNER_MASK 0x000f -#define MP_GROUP_MASK 0x00f0 -#define MP_WORLD_MASK 0x0f00 -#define MP_SYSTM_MASK 0xf000 - -/* Module Type/Language values */ -#define MT_ANY 0 -#define MT_PROGRAM 0x0001 -#define MT_SUBROUT 0x0002 -#define MT_MULTI 0x0003 -#define MT_DATA 0x0004 -#define MT_TRAPLIB 0x000b -#define MT_SYSTEM 0x000c -#define MT_FILEMAN 0x000d -#define MT_DEVDRVR 0x000e -#define MT_DEVDESC 0x000f -#define MT_MASK 0xff00 - -#define ML_ANY 0 -#define ML_OBJECT 1 -#define ML_ICODE 2 -#define ML_PCODE 3 -#define ML_CCODE 4 -#define ML_CBLCODE 5 -#define ML_FRTNCODE 6 -#define ML_MASK 0x00ff - -#define mktypelang(type,lang) (((type)<<8)|(lang)) - -/* Module Attribute values */ -#define MA_REENT 0x80 -#define MA_GHOST 0x40 -#define MA_SUPER 0x20 -#define MA_MASK 0xff00 -#define MR_MASK 0x00ff - -#define mkattrevs(attr, revs) (((attr)<<8)|(revs)) - -#define m_user m_owner.grp_usr.usr -#define m_group m_owner.grp_usr.grp -#define m_group_user m_owner.group_user - -/* macro definitions for accessing module header fields */ -#define MODNAME(mod) ((u_char*)((u_char*)mod + ((Mh_com)mod)->m_name)) -#if 0 -/* Appears not to be used, and the u_int32 typedef is gone (because it - conflicted with a Mach header. */ -#define MODSIZE(mod) ((u_int32)((Mh_com)mod)->m_size) -#endif /* 0 */ -#define MHCOM_BYTES_SIZE 80 -#define N_BADMAG(a) (((a).a_info) != MODSYNC) - -typedef struct mh_com { - /* sync bytes ($4afc). */ - unsigned char m_sync[2]; - unsigned char m_sysrev[2]; /* system revision check value */ - unsigned char - m_size[4]; /* module size */ - unsigned char - m_owner[4]; /* group/user id */ - unsigned char - m_name[4]; /* offset to module name */ - unsigned char - m_access[2], /* access permissions */ - m_tylan[2], /* type/lang */ - m_attrev[2], /* rev/attr */ - m_edit[2]; /* edition */ - unsigned char - m_needs[4], /* module hardware requirements flags. (reserved) */ - m_usage[4], /* comment string offset */ - m_symbol[4], /* symbol table offset */ - m_exec[4], /* offset to execution entry point */ - m_excpt[4], /* offset to exception entry point */ - m_data[4], /* data storage requirement */ - m_stack[4], /* stack size */ - m_idata[4], /* offset to initialized data */ - m_idref[4], /* offset to data reference lists */ - m_init[4], /* initialization routine offset */ - m_term[4]; /* termination routine offset */ - unsigned char - m_ident[2]; /* ident code for ident program */ - char - m_spare[8]; /* reserved bytes */ - unsigned char - m_parity[2]; /* header parity */ -} mh_com,*Mh_com; - -/* Executable memory module */ -typedef mh_com *Mh_exec,mh_exec; - -/* Data memory module */ -typedef mh_com *Mh_data,mh_data; - -/* File manager memory module */ -typedef mh_com *Mh_fman,mh_fman; - -/* device driver module */ -typedef mh_com *Mh_drvr,mh_drvr; - -/* trap handler module */ -typedef mh_com mh_trap, *Mh_trap; - -/* Device descriptor module */ -typedef mh_com *Mh_dev,mh_dev; - -/* Configuration module */ -typedef mh_com *Mh_config, mh_config; - -#if 0 - -#if !defined(_MODDIR_H) -/* go get _os_fmod (and others) */ -#include -#endif - -error_code _os_crc(void *, u_int32, int *); -error_code _os_datmod(char *, u_int32, u_int16 *, u_int16 *, u_int32, void **, mh_data **); -error_code _os_get_moddir(void *, u_int32 *); -error_code _os_initdata(mh_com *, void *); -error_code _os_link(char **, mh_com **, void **, u_int16 *, u_int16 *); -error_code _os_linkm(mh_com *, void **, u_int16 *, u_int16 *); -error_code _os_load(char *, mh_com **, void **, u_int32, u_int16 *, u_int16 *, u_int32); -error_code _os_mkmodule(char *, u_int32, u_int16 *, u_int16 *, u_int32, void **, mh_com **, u_int32); -error_code _os_modaddr(void *, mh_com **); -error_code _os_setcrc(mh_com *); -error_code _os_slink(u_int32, char *, void **, void **, mh_com **); -error_code _os_slinkm(u_int32, mh_com *, void **, void **); -error_code _os_unlink(mh_com *); -error_code _os_unload(char *, u_int32); -error_code _os_tlink(u_int32, char *, void **, mh_trap **, void *, u_int32); -error_code _os_tlinkm(u_int32, mh_com *, void **, void *, u_int32); -error_code _os_iodel(mh_com *); -error_code _os_vmodul(mh_com *, mh_com *, u_int32); -#endif /* 0 */ - -#endif diff --git a/contrib/gdb/include/progress.h b/contrib/gdb/include/progress.h deleted file mode 100644 index f18318a4514..00000000000 --- a/contrib/gdb/include/progress.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Default definitions for progress macros. - Copyright (C) 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 -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* The default definitions below are intended to be replaced by real - definitions, if building the tools for an interactive programming - environment. */ - -#ifndef _PROGRESS_H -#define _PROGRESS_H - -#ifndef START_PROGRESS -#define START_PROGRESS(STR,N) -#endif - -#ifndef PROGRESS -#define PROGRESS(X) -#endif - -#ifndef END_PROGRESS -#define END_PROGRESS(STR) -#endif - -#endif /* _PROGRESS_H */ diff --git a/contrib/gdb/include/wait.h b/contrib/gdb/include/wait.h deleted file mode 100644 index fa3c9ccb1d7..00000000000 --- a/contrib/gdb/include/wait.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Define how to access the int that the wait system call stores. - This has been compatible in all Unix systems since time immemorial, - but various well-meaning people have defined various different - words for the same old bits in the same old int (sometimes claimed - to be a struct). We just know it's an int and we use these macros - to access the bits. */ - -/* The following macros are defined equivalently to their definitions - in POSIX.1. We fail to define WNOHANG and WUNTRACED, which POSIX.1 - defines, since our code does not use waitpid(). We - also fail to declare wait() and waitpid(). */ - -#ifndef WIFEXITED -#define WIFEXITED(w) (((w)&0377) == 0) -#endif - -#ifndef WIFSIGNALED -#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0) -#endif - -#ifndef WIFSTOPPED -#ifdef IBM6000 - -/* Unfortunately, the above comment (about being compatible in all Unix - systems) is not quite correct for AIX, sigh. And AIX 3.2 can generate - status words like 0x57c (sigtrap received after load), and gdb would - choke on it. */ - -#define WIFSTOPPED(w) ((w)&0x40) - -#else -#define WIFSTOPPED(w) (((w)&0377) == 0177) -#endif -#endif - -#ifndef WEXITSTATUS -#define WEXITSTATUS(w) (((w) >> 8) & 0377) /* same as WRETCODE */ -#endif - -#ifndef WTERMSIG -#define WTERMSIG(w) ((w) & 0177) -#endif - -#ifndef WSTOPSIG -#define WSTOPSIG WEXITSTATUS -#endif - -/* These are not defined in POSIX, but are used by our programs. */ - -#define WAITTYPE int - -#ifndef WCOREDUMP -#define WCOREDUMP(w) (((w)&0200) != 0) -#endif - -#ifndef WSETEXIT -#define WSETEXIT(w,status) ((w) = (0 | ((status) << 8))) -#endif - -#ifndef WSETSTOP -#define WSETSTOP(w,sig) ((w) = (0177 | ((sig) << 8))) -#endif - diff --git a/contrib/gdb/libiberty/COPYING.LIB b/contrib/gdb/libiberty/COPYING.LIB deleted file mode 100644 index eb685a5ec98..00000000000 --- a/contrib/gdb/libiberty/COPYING.LIB +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/contrib/gdb/libiberty/ChangeLog b/contrib/gdb/libiberty/ChangeLog deleted file mode 100644 index b28ef2f6ed5..00000000000 --- a/contrib/gdb/libiberty/ChangeLog +++ /dev/null @@ -1,1815 +0,0 @@ -Tue Mar 19 22:02:07 1996 Jason Merrill - - * cplus-dem.c (demangle_template): Fix for non-mangled pointer - arguments. - -Fri Mar 8 17:24:18 1996 Ian Lance Taylor - - * configure.in: If srcdir is `.' and with_target_subdir is not - `.', then set MULTISRCTOP before calling config-ml.in. - -Thu Mar 7 13:37:10 1996 Stan Shebs - - * mpw.c (mpw_open): Add debugging output option. - -Wed Mar 6 17:36:03 1996 Jason Merrill - - * cplus-dem.c (demangle_template): Fix for address-of-extern arguments. - -Tue Feb 27 12:00:50 1996 Raymond Jou - - * mpw.c (mpwify_filename): Change 6 to 5 in - strncmp (unixname, "/tmp/", 5). - -Tue Feb 20 10:55:53 1996 Ian Lance Taylor - - * cplus-dem.c (demangle_template): Initialize is_bool. Correctly - handle 0 as a pointer value parameter. - -Mon Feb 5 16:41:44 1996 Ian Lance Taylor - - * Makefile.in (all): Depend upon required-list. - (required-list): New target. - (clean): Remove required-list. - -Wed Jan 31 10:19:41 1996 Steve Chamberlain - - * win32.c: Deleted. - * config.table (i386-*-win32): Deleted. - * config/mh-i386win32: Deleted. - -Thu Jan 18 11:34:17 1996 Ian Lance Taylor - - * cplus-dem.c (cplus_demangle_opname): Change opname parameter to - const char *. - (cplus_mangle_opname): Change return type and opname parameter to - const char *. Don't cast return value. - -Tue Jan 16 12:13:11 1996 Stan Shebs - - * mpw.c: Include Timer.h, in order to get m68k Microseconds trap - definition. - -Wed Jan 3 13:15:04 1996 Fred Fish - - * obstack.c: Update copyright to 1996. - (_obstack_memory_used): Define new function. Called via - obstack_memory_used macro. - -Thu Dec 28 11:39:40 1995 Ian Lance Taylor - - * xstrdup.c: New file. - * Makefile.in (CFILES): Add xstrdup.c. - (REQUIRED_OFILES): Add xstrdup.o. - (xstrdup.o): New target. - -Mon Dec 11 18:18:52 1995 Mike Stump - - * atexit.c: New stub to provide atexit on systems that have - on_exit, like SunOS 4.1.x systems. - * functions.def (on_exit, atexit): Ditto. - -Mon Dec 11 15:42:14 1995 Stan Shebs - - * mpw.c (mpw_abort): Remove decl. - (mpw_access): Move debugging printf. - -Sat Dec 2 01:25:23 1995 Ian Lance Taylor - - * config.table: Consistently use ${host} rather than ${xhost} or - ${target}. - * configure.in: Don't bother to set ${xhost} before calling - config.table. - -Tue Nov 28 14:16:57 1995 Brendan Kehoe - - * Makefile.in (.c.o): Use test instead of the left bracket, to - avoid problems with some versions of make. - -Tue Nov 28 11:45:17 1995 Stan Shebs - - * mpw-make.sed: Fix INCDIR edit to work with Nov 14 change. - -Tue Nov 21 11:26:34 1995 Fred Fish - - * config/mh-hpux: Remove. It was only used to define EXTRA_OFILES, - which was set to just alloca.o, which is now automatically marked - as needed by the autoconfiguration process. - -Tue Nov 21 14:15:06 1995 Ian Lance Taylor - - * config.table: Check ${with_cross_host} rather than comparing - ${host} and ${target}. - -Thu Nov 16 14:34:42 1995 Ian Lance Taylor - - * configure.in: If with_target_subdir is empty, set xhost to - ${host} rather than ${target} before calling config.table. - -Tue Nov 14 01:38:30 1995 Doug Evans - - * Makefile.in (MULTITOP): Deleted. - (MULTISRCTOP, MULTIBUILDTOP): New. - (FLAGS_TO_PASS): Delete INCDIR. - (INCDIR): Add $(MULTISRCTOP). - (install_to_libdir): Add $(MULTISUBDIR). Call $(MULTIDO). - * configure.in: Delete call to cfg-ml-com.in. Call config-ml.in - instead of cfg-ml-pos.in. - (cross-compile check): Change to test for with_target_subdir. - (EXTRA_LINKS): Delete. - -Sun Nov 12 12:13:04 1995 Stan Shebs - - * mpw-make.sed: Add getpagesize.c.o to needed-list. - * mpw.c [USE_MW_HEADERS]: Conditionalize compiling of - functions that are supplied by Metrowerks libraries. - (fstat): Clean up descriptor->pointer conversion code. - (InstallConsole, etc): Empty definitions, for when linking - with SIOUX. - -Sun Nov 5 19:25:27 1995 Per Bothner - - * Makefile.in (FLAGS_TO_PASS): Also pass PICFLAGS. - (.c.o): Stylistic change. - -Thu Nov 2 12:06:29 1995 Ian Lance Taylor - - * strtol.c, strtoul.c: Don't include . From - phdm@info.ucl.ac.be (Philippe De Muyter). - -Wed Nov 1 11:59:36 1995 Ian Lance Taylor - - * configure.in: Correct sed call. - -Mon Oct 30 13:03:45 1995 Per Bothner - - * configure.in: Clean up / simplify for native. - - * configure.in: Merge in stuff from ../xiberty/configure.in. - * Makefile.in (CC): Add definition (so it can be overrridden - by ../configure). - -Tue Oct 24 17:57:27 1995 Stan Shebs - - * mpw-make.sed: Leave strerror.c.o in standard list of functions. - * mpw.c (R_OK, ENOENT, EACCESS, ENOSYS): Remove. - (link): Remove useless definition with error return. - (last_microseconds, warn_if_spin_delay, record_for_spin_delay): - Use UnsignedWide type for microsecond counts. - -Thu Oct 19 10:52:07 1995 Michael Meissner - - * memcmp.c (memcmp): Argument types are const void *, not void - *const. - - * strncasecmp.c (strncasecmp): Include ansidecl.h/stdarg.h, not - sys/types.h. - * strcasecmp.c (strcasecmp): Ditto. - -Tue Oct 10 11:03:24 1995 Fred Fish - - * Makefile.in (BISON): Remove macro. - -Tue Sep 26 15:06:46 1995 Stan Shebs - - * Makefile.in (HFILES): Add default empty definition. - * mpw-config.in (config.h): Only update if changed. - * mpw-make.in: Remove. - * mpw-make.sed: New file, edits Makefile.in into MPW makefile. - * mpw.c: Remove semi-clone of strerror code. - (sys_nerr, sys_errlist): Define here. - (Microseconds): Only define as A-line trap if m68k Mac. - -Wed Sep 20 12:53:32 1995 Ian Lance Taylor - - * Makefile.in (maintainer-clean): New synonym for distclean. - -Mon Aug 28 19:47:52 1995 Per Bothner - - * config.table: For host, generalize rs6000-ibm-aix* - to *-ibm-aix* so we also include powerpc. - -Tue Aug 22 03:18:05 1995 Ken Raeburn - - Fri Jun 16 18:35:40 1995 Pat Rankin (rankin@eql.caltech.edu) - - * xstrerror.c: New file. - * Makefile.in, vmsbuild.com: Compile it. - -Mon Jul 31 12:16:32 1995 steve chamberlain - - * config.table (i386-*-win32): New. - -Fri Jul 21 11:35:52 1995 Doug Evans - - * Makefile.in (MULTITOP): New variable. - (MULTIDIRS, MULTISUBDIR, MULTIDO, MULTICLEAN): Likewise. - (all): Add multilib support. - (install_to_tooldir, *clean): Likewise. - -Mon Jul 10 11:47:27 1995 Ken Raeburn - - * makefile.dos (OBJS): Add hex.o. From DJ Delorie. - -Fri Jun 30 17:28:59 1995 Pat Rankin (rankin@eql.caltech.edu) - - * vmsbuild.com: create "new-lib.olb", build libiberty under that - name, and then make it become "liberty.olb" when done, so that an - incomplete build attempt never leaves behind something which looks - like a complete library. - -Thu Jun 29 00:22:02 1995 Steve Chamberlain - - * config/mh-i386pe: New file for PE hosts. - * config.table: Understand PE hosts. - -Wed Jun 28 19:13:23 1995 Jason Merrill - - * cplus-dem.c: Update from gcc. - - * argv.c, dummy.c: If __STDC__, #include "alloca-conf.h" after - . - * alloca-norm.h: If __STDC__, declare alloca with its parameter. - -Thu Jun 22 18:57:47 1995 Stan Shebs - - * mpw-make.in (ALL_CFLAGS): Define NEED_basename. - * mpw.c: Only test DebugPI once whenever printing debug info. - (mpwify_filename): If filename is /tmp/foo, change it into :_foo, - also fix to not write on input filename buffer. - (mpw_access): Use stat() instead of open(), works for directories - as well as files. - -Mon Jun 19 00:33:22 1995 Jason Merrill - - * Makefile.in: Massage broken shells that require 'else true'. - -Sat Jun 17 23:21:58 1995 Fred Fish - - * alloca-norm.h: Declare alloca as type "PTR" to match functions.def. - Declare __builtin_alloca in the sparc case, as argv.c did. - * argv.c: Replace inline version of alloca-norm.h at start of file with - a #include of alloca-conf.h. Precede it with an include of ansidecl.h - because alloca-norm.h needs to declare alloca as "PTR". - -Mon Jun 12 14:24:26 1995 Steve Chamberlain - - * win32.c: New file. - -Fri Jun 9 15:16:14 1995 Jason Merrill - - * dummy.c: #include "alloca-conf.h". - -Wed Jun 7 11:46:23 1995 Jason Merrill - - * Makefile.in (mostlyclean): Remove stamp-picdir. - (clean): Don't. - -Mon Jun 5 18:46:06 1995 Jason Merrill - - * config.table (frags): Use toplevel pic frags. - - * Makefile.in (PICFLAG): New macro. - (all): Depend on stamp-picdir. - (needed-list): Ditto. - (.c.o): Also build pic object. - (stamp-picdir): New rule. - (mostlyclean): Remove pic. - (clean): Remove stamp-picdir. - -Fri Mar 24 16:55:48 1995 Pat Rankin (rankin@eql.caltech.edu) - - * vmsbuild.com (config.h): Add `#define NEED_basename'. - -Tue May 23 10:12:46 1995 Per Bothner - - * clock.c, getopt.c, strtod.c, vsprintf.c: Change from using LGPL - to libio-style copyright. - * getpagesize.c: Remove FSF copyright. - -Sat May 20 12:30:23 1995 Ken Raeburn - - Added improved VMS support from Pat Rankin: - - Fri Mar 17 18:40:36 1995 Pat Rankin (rankin@eql.caltech.edu) - - * vmsbuild.com: new file. - - * getpagesize.c (getpagesize): implement for VMS; - * strerror.c (strerror, strerrno, strtoerrno): add rudimentary - support for EVMSERR. - -Thu May 18 17:01:42 1995 Ken Raeburn - - Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk) - - * floatformat.c (floatformat_arm_ext): Define. - -Tue May 16 13:30:59 1995 Per Bothner - - * basename.c, bcmp.c, getcwd.c, insque.c, rename.c, sigsetmask.c, - strerror.c, strsignal.c: Remove FSF copyright. - * sigsetmask.c: #include - seems to be needed by ISC. - -Mon May 15 19:53:17 1995 Per Bothner - - * bcopy.c, bzero.c, memcmp.c, memcpy.c, memset.c, strchr.c, - strrchr.c, strstr.c, vfork.c: Remove FSF Copyright, because this - might contaminate libstdc++ with the LGPL. (OK'd by RMS 11 Oct 94.) - * strchr.c, strrchr.c: Add cast to suppress const warning. - -Thu May 4 14:36:42 1995 Jason Merrill - - * cplus-dem.c: Use const instead of CONST. Don't include - ansidecl.h directly. - -Wed Apr 19 01:30:27 1995 Jason Merrill - - * cplus-dem.c: Don't include libiberty.h. Do declare xmalloc and - xrealloc. - (-DMAIN): Don't rely on an externally-defined version number; - instead, require the version number to be defined as a - preprocessor macro. Handle the RS/6000 leading dot. Define - xmalloc, xrealloc and fatal. Don't strip a leading underscore - if we couldn't demangle the word. - -Tue Apr 4 13:03:51 1995 Stan Shebs - - (Old mpw.c change descriptions retained for informational value.) - * mpw.c (warning_threshold): Default to .4 sec. - (overflow_count, current_progress): New globals. - (warn_if_spin_delay): Include current progress type, - such as program name, in message. - (mpw_start_progress): Set current_progress variable from arg. - (mpw_end_progress): Report spin delays by power-of-two-size - buckets instead of constant-size buckets. - - * mpw.c: Clean up formatting, types, returns, etc. - (ENOSYS): Define. - (mpw_fread, mpw_fwrite): Define. - (sleep): Define correctly. - - * mpw.c: New code to implement cursor spinning support. - (umask): New function. - (mpw_fopen, mpw_fseek, stat, fstat): Call PROGRESS. - - * mpw.c (mpw_basename, mpw_mixed_basename): New functions, find - basenames for MPW and MPW/Unix filenames. - (mpw_special_init): New function, calls Macsbug if desired. - - * mpw.c: Add GPL notice. - (mpwify_filename): Add more transformations. - (mpw_fopen): Call mpwify_filename on file names. - (rename): Remove. - (chdir, getcwd): Add simple definitions. - - * mpw.c: Random cleanups, remove unused code bits. - Added copy of strerror.c for gcc's use. - (stat, fstat, _stat): New versions based on Guido van Rossum code. - - * mpw.c (mpw_fseek): Make it work correctly when doing SEEK_CUR. - - * mpw.c (stat): Remove hack definition, get from sys/stat.h. - (fork, vfork, etc): Print error messages if called. - (getrusage, sbrk, environ, isatty, link, utime, mkdir, rmdir, - rename, chown): Define. - - * mpw-config.in: New file, MPW version of configure.in. - * mpw-make.in: New file, MPW version of Makefile.in. - * mpw.c: New file, MPW compatibility routines. - -Fri Mar 24 14:10:30 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * basename.c: Include config.h before checking for NEED_basename. - -Thu Mar 23 19:09:54 1995 Jason Merrill - - * functions.def: Add DEFFUNC for basename. - - * basename.c: Only define basename if NEED_basename. - -Thu Mar 16 13:36:05 1995 Jason Merrill - - * config.table: Fix --enable-shared logic for native builds. - -Mon Mar 13 11:05:11 1995 Jason Merrill - - * cplus-dem.c (demangle_template): Demangle bool literals properly. - -Mon Mar 6 23:57:28 1995 Stu Grossman (grossman@cygnus.com) - - * strtol.c strtoul.c: Replace these with less buggy versions from - NetBSD. (strtoul in particular couldn't handle base 16.) - -Wed Mar 1 15:59:01 1995 Ian Lance Taylor - - * config/mt-vxworks5 (HDEFINES): Define NO_SYS_PARAM_H. - - * clock.c: If NO_SYS_PARAM_H is defined, don't include - . - * getcwd.c, getpagesize.c, getruntime.c: Likewise. - -Fri Feb 17 15:40:55 1995 Ian Lance Taylor - - * getruntime.c (get_run_time): Don't assume that CLOCKS_PER_SEC is - a number; ANSI appears to permit any expression, including a - function call. - - * config.table (*-*-vxworks5*): Use mt-vxworks5 when configuring - xiberty. - * config/mt-vxworks5: New file. - -Thu Feb 9 14:19:45 1995 Ian Lance Taylor - - * basename.c (basename): Change argument to be const. - -Wed Feb 8 18:06:52 1995 Jason Merrill - - * Makefile.in (lneeded-list): Don't worry about xmalloc. - -Sun Jan 15 00:40:36 1995 Jeff Law (law@snake.cs.utah.edu) - - * Makefile.in (distclean): Delete xhost-mkfrag. - -Thu Jan 12 16:54:18 1995 Jason Merrill - - * Makefile.in (lneeded-list): If alloca.o is needed, so is xmalloc.o. - -Wed Jan 11 22:39:56 1995 Ken Raeburn - - * hex.c: New file. - * Makefile.in (REQUIRED_OFILES, CFILES): List it. - (hex.o): Add dependencies. - - * cplus-dem.c (demangle_prefix): For GNU style constructor and - destructor names, try demangling the remainder of the string. - -Wed Dec 28 00:49:15 1994 Ian Lance Taylor - - * vasprintf.c (int_vasprintf): New static function. - (vasprintf): Use int_vasprintf. Removes assumption that va_list - is assignment compatible. - -Sat Nov 5 19:29:12 1994 Jason Merrill (jason@phydeaux.cygnus.com) - - * Makefile.in (LIBCFLAGS): New variable. - (FLAGS_TO_PASS): Pass it. - (.c.o): Use it. - -Thu Nov 3 19:09:47 1994 Ken Raeburn - - * getopt.c, getopt1.c: Do compile these functions under Linux, - since many native versions are based on glibc but are buggy. - -Mon Oct 24 15:16:46 1994 Per Bothner - - * vasprintf.c: Make 'format' arg be const, to avoid a mismatch - with prototype in GNU libc. Support stdarg.h as well as varargs.h. - -Tue Oct 11 17:48:27 1994 Jason Merrill (jason@phydeaux.cygnus.com) - - * Makefile.in (REQUIRED_OFILES): Add vasprintf.o. - * functions.def: Remove vasprintf. - -Wed Sep 14 17:04:55 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * xmalloc.c (first_break): New static variable. - (xmalloc_set_program_name): Record sbrk (0) in first_break. - (xmalloc): If memory allocation fails, try to report how much - memory was allocated by the program up to this point. - (xrealloc): Likewise. - -Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org) - - * Makefile.in (ERRORS_CC): New variable, defaulted to $(CC). Use it - when linking dummy. - * config.table: Add host RISCiX Makefile frag. - * config/mh-riscix: New file. - -Thu Aug 25 17:29:44 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * Makefile.in (FLAGS_TO_PASS): Define. - ($(RULE1)): Use $(FLAGS_TO_PASS). - -Wed Aug 24 17:08:47 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * vasprintf.c: Include . - (vasprintf): Add casts to void for va_arg to avoid gcc warnings. - * xatexit.c: Declare malloc. - -Fri Aug 19 15:29:12 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (demangle_args): Fix a bug in previous patch (the - one below). - -Thu Aug 18 14:37:14 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (demangle args): Handle ARM repeat encoding where - the type index is greater than 9. - -Wed Aug 17 16:13:49 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (demangle_qualified): accept optional '_' between - qualified name. This is baecause the template name may end with - numeric and can mixed up with the length of next qualified name. - -Wed Aug 3 05:52:14 1994 D. V. Henkel-Wallace (gumby@cygnus.com) - - * config/mt-sunos4: Use our standard location for cross-includes - and cross-libs when the target is also a "host" environment (ie no - newlib; includes and such don't belong to us). This is specific - to the Cygnus Support environment. - -Tue Aug 2 15:25:12 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (demangle_template): demangle as xxx<'Q'> not - xxx. - -Mon Aug 1 17:02:48 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (main): flush stdout to make pipe work. - -Sat Jul 16 12:56:32 1994 Stan Shebs (shebs@andros.cygnus.com) - - * config.table (*-*-cxux7*): Recognize. - * floatformat.c (floatformat_m88110_ext) [HARRIS_FLOAT_FORMAT]: - Harris-specific float format. - * config/mh-cxux7: New file. - -Wed Jun 29 00:26:17 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * cplus-dem.c (demangle_template): Make sure that the result of - consume_count doesn't index beyond the end of the string. - -Mon Jun 20 23:54:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * cplus-dem.c (gnu_special): Handle vtable mangling of gcc-2.4.5 and - earlier. Improve test for new vtable mangling. Change output back - to `virtual table'. - -Mon Jun 20 11:37:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * obstack.c: Always compile this code, even if using the GNU - library. Avoids problems with relatively recent binary - incompatibility. - -Thu Jun 16 17:54:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * cplus-dem.c: Include libiberty.h. - (xmalloc, xrealloc, free): Don't declare. - (strstr): Don't declare parameters. - (xmalloc, xrealloc): Don't define. - (long_options): Add no-strip-underscores. - (main): Call xmalloc_set_program_name. Pass n in short options to - getopt_long. Handle option 'n' to not strip underscores. - (usage): Mention -n and --no-strip-underscores. - -Sun Jun 12 01:37:09 1994 Jason Merrill (jason@deneb.cygnus.com) - - * cplus-dem.c (demangle_template): Separate consecutive >'s with a - space. - (gnu_special): Demangle template and qualified names in a vtable name. - -Fri May 27 12:27:52 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - From gas-2.3 and binutils-2.4 net releases: - - Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com) - - * makefile.dos: [new] Makefile for dos/go32 - * configure.bat: update for latest files - * msdos.c: remove some functions now in libc.a - -Fri May 20 18:53:32 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * cplus-dem.c (gnu_special): Recognize thunks, as well as - the new naming style for vtables (when -fvtable-thunks). - -Wed May 18 13:34:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * Makefile.in (XTRAFLAGS): Don't define. - (.c.o, dummy.o): Don't use XTRAFLAGS. - ($(RULE1)): Don't pass XTRAFLAGS down in recursive call. - -Fri May 13 16:02:12 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * vasprintf.c: New file. - * Makefile.in, functions.def: Add it. - -Fri May 13 16:20:28 1994 Jason Merrill (jason@deneb.cygnus.com) - - * cplus-dem.c (demangle_fund_type): Grok bool. - -Fri May 6 14:44:21 1994 Steve Chamberlain (sac@cygnus.com) - - * config.table: Add go32 - * config/mh-go32: New template. - -Fri May 6 11:01:59 1994 D. V. Henkel-Wallace (gumby@rtl.cygnus.com) - - * config.table, config/mt-sunos4: config for when sun4 is cross target. - -Mon Apr 11 00:54:33 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu) - - * getopt.c [not __GNU_LIBRARY__] [__GCC__] [not __STDC__]: - Declare strlen to return int. Don't include stddef.h. - -Fri Apr 1 00:38:17 1994 Jim Wilson (wilson@mole.gnu.ai.mit.edu) - - * getopt.c: Delete use of IN_GCC to control whether - stddef.h or gstddef.h is included. - -Thu Apr 14 14:00:56 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (demangle_signature): Fix a bug in template function - type numbering. - -Wed Apr 13 17:23:03 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (demangle_signature): Fix template function with arm - style argument type number, Tn. - -Wed Apr 13 17:11:15 1994 Jason Merrill (jason@deneb.cygnus.com) - - * cplus-dem.c (optable): Add new[] and delete[]. - -Fri Apr 8 11:21:42 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * argv.c (buildargv): Don't produce empty argument just because - there is trailing whitespace. - -Wed Apr 6 11:42:14 1994 Kung Hsu (kung@mexican.cygnus.com) - - * cplus-dem.c (demangle_template): fix 'Q' qualified name bug. - Handle 'p' same as 'P'. - * cplus-dem.c (do_type): Handle 'p' same as 'P'. - -Sat Mar 26 12:00:13 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * floatformat.c (get_field, put_field): Fix off by one error in - little endian case. - -Thu Mar 24 10:40:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * floatformat.c (floatformat_from_double): Pass unsigned char *, - not char *, to put_field. - -Fri Mar 18 12:34:33 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * memmove.c: Re-wrote; placed in public domain. - -Wed Mar 16 10:33:07 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cplus-dem.c (demangle_prefix): If ARM demangling, don't treat - __Q* as a constructor. - -Mon Mar 14 12:26:02 1994 Ian Lance Taylor (ian@cygnus.com) - - * ieee-float.c: Removed; no longer used. - * Makefile.in: Changed accordingly. - -Mon Mar 7 12:28:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * floatformat.c (get_field): Removed unused local variable i. - (put_field): Removed unused local variable i. - -Sun Feb 27 21:50:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * floatformat.c: New file, intended to replace ieee-float.c. - * Makefile.in: Change accordingly. - -Thu Feb 24 11:51:12 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * getopt.c: Remove #ifdef GETOPT_COMPAT and #if 0 code. - (_getopt_initialize): New function, broken out of _getopt_internal. - (_getopt_internal): - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - -Thu Feb 10 14:44:16 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu) - - * getopt.c [not __GNU_LIBRARY__] [__GNUC__] [not IN_GCC]: - Test just __STDC__, not emacs. - -Wed Feb 9 00:14:00 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu) - - * getopt.c [not __GNU_LIBRARY__] [__GNUC__] [not IN_GCC] - [emacs] [not __STDC__]: Don't include stddef.h. Don't declare strlen. - -Fri Dec 24 19:43:00 1993 Noah Friedman (friedman@nutrimat.gnu.ai.mit.edu) - - * getopt.c (_NO_PROTO): Define before config.h is included. - -Mon Sep 20 15:59:03 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * getopt.c, getopt1.c [emacs || CONFIG_BROKETS]: Include - only under these, else "config.h". - -Thu Aug 12 18:16:49 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * getopt.c, getopt1.c [HAVE_CONFIG_H]: Include - instead of "config.h". - -Sun Feb 20 17:17:01 1994 Ian Lance Taylor (ian@lisa.cygnus.com) - - * concat.c: Check ANSI_PROTOTYPES rather than __STDC__ to decide - whether to use prototypes or not. - * strerror.c (const): Never undefine; let ansidecl.h handle it. - * strsignal.c (const): Likewise. - -Thu Feb 17 13:27:35 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * xatexit.c (_xexit_cleanup): Declare as extern; don't initialize. - Merging common and initialized variables need not be supported by - ANSI C compilers. - (xatexit): Initialize _xexit_cleanup if not already set. - * xexit.c: Comment fix. - -Wed Feb 16 01:15:36 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * xmalloc.c: Don't declare xexit; it's declared in libiberty.h. - (xrealloc): If oldmem is NULL, allocate with malloc, rather than - assuming that realloc works correctly. - -Tue Feb 15 09:26:16 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * concat.c, ieee-float.c: Replace inclusion of - with explicit function declarations, as recommended by Ian Taylor. - -Sat Feb 12 10:31:11 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * xmalloc.c (xmalloc, xrealloc): Use PTR and size_t throughout. - (malloc, realloc): Declare. - -Thu Feb 10 17:08:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * argv.c, basename.c: Include ansidecl.h and libiberty.h. - * concat.c, fdmatch.c, getruntime.c, spaces.c: Likewise. - * strerror.c, strsignal.c, xatexit.c, xexit.c: Likewise. - * xmalloc.c: Likewise. - * concat.c: Don't declare xmalloc. If __STDC__, use - macros, not macros. - * spaces.c (spaces): Make return type const. Don't crash if - malloc returns NULL. - * strerror.c (struct error_info): Make name and msg fields const. - (error_names): Make const. - (strerrno): Make const. - (strtoerrno): Make argument const. - * strsignal.c (struct signal_info): Make name and msg fields - const. - (signal_names, sys_siglist): Make const. - (strsignal, strsigno): Make const. - (strtosigno): Make argument const. - * xatexit.c: Declare parameter types. - * xmalloc.c (name): Make const. - (xmalloc_set_program_name): Make argument const. - * Makefile.in (INCDIR): Define. - (.c.o): Use $(INCDIR). - (dummy.o): Likewise. - (argv.o, basename.o): New targets; depend on libiberty.h. - (concat.o, fdmatch.o, getruntime.o, spaces.o): Likewise. - (strerror.o, strsignal.o, xatexit.o, xexit.o): Likewise. - (xmalloc.o): Likewise. - (cplus-dem.o): New target; depend on demangle.h. - (getopt.o, getopt1.o): New targets; depend on getopt.h. - (ieee-float.o): New target; depend on ieee-float.h. - (obstack.o): New target; depend on obstack.h. - -Tue Feb 8 05:29:08 1994 David J. Mackenzie (djm@thepub.cygnus.com) - - Handle obstack_chunk_alloc returning NULL. This allows - obstacks to be used by libraries, without forcing them - to call exit or longjmp. - * obstack.c (_obstack_begin, _obstack_begin_1, _obstack_newchunk): - If CALL_CHUNKFUN returns NULL, set alloc_failed, else clear it. - (_obstack_begin, _obstack_begin_1): Return 1 if successful, 0 if not. - -Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * concat.c, ieee-float.c: Include . - -Sun Feb 6 21:28:46 1994 David J. Mackenzie (djm@thepub.cygnus.com) - - * xmalloc.c (xmalloc_set_program_name): New function. - (xmalloc, xrealloc): Include the name in the error message, if set. - - * Replace atexit.c with xatexit.c. - * Makefile.in (CFILES), functions.def: Change references. - -Sat Feb 5 14:02:32 1994 Stan Shebs (shebs@andros.cygnus.com) - - * getruntime.c (get_run_time): Use getrusage or times if - HAVE_GETRUSAGE or HAVE_TIMES are defined. - -Fri Feb 4 15:49:38 1994 David J. Mackenzie (djm@thepub.cygnus.com) - - * atexit.c: New file. - * Makefile.in (CFILES), functions.def: Add it. - * xexit.c: New file. - * Makefile.in (CFILES, REQUIRED_OFILES): Add it. - * xmalloc.c (xmalloc, xrealloc): Call xexit instead of exit. - Change request for 0 bytes into request for 1 byte. - -Wed Feb 2 11:36:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * xmalloc.c (xmalloc, xrealloc): Print size using %lu, and cast to - unsigned long, to avoid warnings. - -Fri Jan 28 17:49:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * dummy.c: Don't include time.h ever; always define clock_t as - "unsigned long". Until gcc/fixincludes ensures that clock_t - exists, __STDC__ isn't a sufficient test. And if clock() doesn't - exist, clock_t probably doesn't either. - -Mon Jan 24 11:52:31 1994 Stan Shebs (shebs@andros.cygnus.com) - - * clock.c, getruntime.c: New files. - * Makefile.in: Add to file lists. - * functions.def (clock): Add to list. - * dummy.c (time.h): Add if __STDC__. - (clock_t): #define as "unsigned long" if not __STDC__. - -Tue Jan 11 11:27:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * strtod.c: Declare atof. From edler@jan.ultra.nyu.edu (Jan - Edler). - -Tue Dec 28 14:17:30 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * Makefile.in (errors): Use CFLAGS as well as LDFLAGS when - linking. - -Fri Dec 17 12:26:07 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c (demangle_arm_pt): New function. Common code - for ARM template demangling. - * cplus-dem.c (demangle_class_name): Use demangle_arm_pt. - * cplus-dem.c (demangle_prefix): Likewise. - -Tue Nov 30 15:47:48 1993 Jason Merrill (jason@deneb.cygnus.com) - - * cplus-dem.c (cplus_demangle_opname): Add CONST to please gcc. - -Sat Nov 27 11:05:50 1993 Fred Fish (fnf@cygnus.com) - - Merge changes from tom@basil.icce.rug.nl (Tom R.Hageman) - * strerror.c, strsignal.c: As a small space optimization, don't - include messages when they aren't actually used. - - Merge changes from takefive.co.at!joe (Josef Leherbauer) - * cplus-dem.c (demangle_prefix, demangle_function_name, - cplus_demangle_opname): Fixes for systems where cplus_marker - is something other than '$'. - -Fri Nov 26 13:51:11 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * waitpid.c: Simple-minded approcimation to waitpid - using vanilla wait. - * functions.def, Makefile.in: Update accordingly, - -Thu Nov 18 18:01:15 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c(demangle_template): fix bug template instantiation - with value of user defined type. - -Wed Nov 17 18:30:21 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c(cplus_demangle_opname): add the subject new function - to support unified search of operator in class. - -Wed Nov 10 09:47:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - gcc -Wall lint: - * strtoul.c (strtoul): use "(digit = *s) != '\0'" not just - "digit = *s" as condition in while loop. - -Tue Nov 9 15:52:22 1993 Mark Eichin (eichin@cygnus.com) - - * Makefile.in: pass SHELL to recursive make - -Thu Nov 4 12:09:26 1993 Per Bothner (bothner@kalessin.cygnus.com) - - * vfprintf.c, vprintf.c, vsprintf.c: Make format arg - be (const char*), for ANSI (and gcc w/fixproto) consistency. - -Thu Nov 4 08:29:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.table: Make *-*-hiux* use mh-hpux. - -Fri Oct 22 07:53:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * config.table: Add * to end of all OS names. - -Tue Oct 19 17:12:01 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * Makefile.in (lneeded-list): ensure that object file names are - not duplicated, as multiple instances of the same object file in - a library causes problems on some machines - -Mon Oct 18 21:59:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * strcasecmp.c, strncasecmp.c: Change u_char to unsigned char. - -Fri Oct 15 22:17:11 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * strncasecmp.c: new file, implements strncasecmp - * strcasecmp.c: new file, implement strcasecmp - - * Makefile.in (CFILES): list these two new source files - - * functions.def: add strcasecmp and strncasecmp entries - -Fri Oct 15 14:53:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * strtoul.c (strtoul), strtol.c (strtol): Handle overflow - according to ANSI C. - -Thu Oct 14 16:34:19 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c: add support of ARM global constructor/destructor, - and 'G' for passing record or union in parameter. - -Wed Oct 13 13:36:19 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Fix comment to clarify that stuff in REQUIRED_OFILES - should not be in functions.def. - -Wed Oct 13 13:13:38 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * functions.def: Removed xmalloc. Stuff in REQUIRED_OFILES should - not be in functions.def. - -Mon Oct 4 18:26:39 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c: change globl constructor/destructor to proper name - -Tue Sep 28 18:11:07 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c: fix bug in constructor/destructor - -Tue Sep 28 16:20:49 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c: support both old and new _vt$... vtbl mangled names - -Fri Sep 24 19:07:16 1993 Jason Merrill (jason@deneb.cygnus.com) - - * cplus-dem.c: Fix demangle_template prototype - -Fri Sep 24 17:32:55 1993 Kung Hsu (kung@cirdan.cygnus.com) - - * cplus-dem.c: fix template demangling - * cplus-dem.c: fix const type demangling - * cplus-dem.c: fix constructor/destructor, virtual table, - qualifier, global constructor/destructor demangling - -Wed Sep 1 23:13:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * strsignal.c, strerror.c: Use fully-bracketed initializer to - keep gcc -Wall happy. - -Fri Aug 27 10:30:09 1993 Jason Merrill (jason@deneb.cygnus.com) - - * cplus-dem.c (do_type): Add CONSTS to make gcc happy with last - patch. - -Fri Aug 27 11:24:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - Patch from Paul Flinders: - * cplus-dem.c (do_type): Deal with arrays. - -Tue Aug 24 14:23:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cplus-dem.c (demangle_qualified: Deal with GNU format for more - than 9 classes. - -Wed Aug 18 19:50:29 1993 Jason Merrill (jason@deneb.cygnus.com) - - * Makefile.in (dummy.o): Redirect to /dev/null to avoid "variable - not initialized" warnings under HP/UX - -Sun Aug 15 20:42:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * strerror.c: Move include of stdio.h after sys_errlist #define. - Also remove NULL definition (stdio.h always defines NULL, so it - never did anything but clutter up the code). - -Sat Aug 14 14:21:49 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * Makefile.in, functions.def: handle xmalloc.c - - * xmalloc.c: provide xmalloc and xrealloc functions - -Thu Aug 12 17:38:57 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * cplus-dem.c: Fix a comment. - -Sat Aug 7 13:56:35 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * getopt1.c: Declare const the way getopt.c does. - -Fri Aug 6 17:03:13 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * obstack.c, alloca.c: Update from FSF. - * getopt.c, getopt1.c: Update to current FSF version, which - doesn't use alloca. - -Tue Jul 27 14:03:57 1993 Brendan Kehoe (brendan@lisa.cygnus.com) - - * Makefile.in (demangle): Add the target with a message saying - where demangle went. - -Mon Jul 26 15:49:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Remove obsolete `demangle' target. - -Thu Jul 22 08:31:01 1993 Fred Fish (fnf@deneb.cygnus.com) - - * cplus-dem.c (arm_special): Apply patch from arg@lucid.com to - avoid infinite loop on vtbl symbols with disambiguating "junk" - tacked on the end. - -Mon Jul 19 14:10:37 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * strsignal.c: work around some systems losing definitions of - sys_siglist - - * config/mh-lynxos: this system has a losing definition of - sys_siglist - - * config.table: use mh-lynxos for *-*-lynxos - -Mon Jul 19 17:08:52 1993 Ken Raeburn (raeburn@rtl.cygnus.com) - - * config.table: Add support for HPPA BSD hosts. - - * config/mh-hpbsd: New file. - -Mon Jul 12 18:00:40 1993 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in (TAGS): make work when srcdir != objdir. - -Sun Jun 27 15:35:31 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * cplus-dem.c (main): Add long options, including --help and - --version. - (usage): New function from code in main. - -Tue Jun 22 11:37:38 1993 Per Bothner (bothner@deneb.cygnus.com) - - * config.table: New shell scipt, sourced by both ./configure,in - and ../xiberty/configure.in, to avoid maintainance lossages. - * configure.in and ../xiberty/configure.in: Use config.table. - - * configure.in: Don't use mh-aix for AIX 3.2, only for 3.1. - * configure.in: Map *-*-irix* (except irix4) to mh-sysv. - * ../xiberty/configure.in: Update from ./configure.in. - -Tue Jun 15 17:05:31 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: remove parentdir support - -Wed May 26 12:59:09 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * cplus-dem.c (xrealloc): Match definition with prototype. - -Tue May 25 14:27:51 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * cplus-dem.c (demangle_prefix): Demangle cfront - local variables as an extension to ARM demangling. - -Fri May 21 09:53:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * ieee-float.c: Don't require pointers to double to be aligned. - -Tue May 18 17:12:10 1993 Fred Fish (fnf@cygnus.com) - - (merge changes from dlong@cse.ucsc.edu) - * cplus-dem.c (consume_count): Simplify. - * cplus-dem.c (arm_pt, demangle_class_name): New functions. - * cplus-dem.c (various): Calls to arm_pt, demangle_class_name. - - * cplus-dem.c (xmalloc, xrealloc, strstr): Make extern decls into - full prototypes. - * cplus-dem.c (free): Add prototype. - * cplus-dem.c (optable): Fully bracketize initializer. - -Fri May 14 17:13:05 1993 Per Bothner (bothner@cygnus.com) - - * cplus-dem.c: Whether initial underscores are stripped - depends on the external variable prepends_underscore - (which is generated by the binutils Makefile). - -Fri May 14 07:32:20 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * cplus-dem.c (mop_up, arm_special): Remove some unused variables. - -Tue May 4 20:31:59 1993 Fred Fish (fnf@cygnus.com) - - * cplus-dem.c (consume_count): Return zero if arg does not - start with digit, and don't consume any input. - -Tue May 4 08:10:28 1993 Jim Kingdon (kingdon@cygnus.com) - - * Makefile.in (demangle): Use ${srcdir} not $^. - - * strtod.c: New file, needed at least for BSD 4.3. - -Sun May 2 11:30:42 1993 Fred Fish (fnf@cygnus.com) - - * strsignal.c (sys_siglist): For ANSI compilations, type is - "const char *const". Also remove conditionalization on __STDC__ - since const is defined away for non-ANSI. - -Wed Apr 28 19:29:55 1993 Ken Raeburn (raeburn@deneb.cygnus.com) - - * configure.in: Recognize *-*-hpux. - * config/mh-hpux: New file. - -Tue Apr 27 15:22:19 1993 Per Bothner (bothner@cygnus.com) - - * tmpnam.c: Added ANSI tmpnam() function. - * functions.def, Makefile.in: Update accordingly. - -Tue Apr 27 13:38:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * cplus-dem.c (demangle_function_name): Get the demangling of - stop__1A right. - -Fri Apr 16 23:48:24 1993 Jim Kingdon (kingdon at calvin) - - * cplus-dem.c: Declare strstr return type. - -Fri Mar 26 12:01:26 1993 Jim Kingdon (kingdon@cygnus.com) - - * strsignal.c: Add some AIX signals. - -Thu Mar 25 15:17:23 1993 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in (MAKEOVERRIDES): Define to be empty. - -Wed Mar 24 01:59:25 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com) - - * Makefile.in: add installcheck & dvi targets - -Thu Mar 18 14:05:44 1993 Per Bothner (bothner@rtl.cygnus.com) - - * ieee-float.c: New file, moved from ../gdb (since it is - needed by ../opcode/m68k-dis.c). - -Tue Mar 2 17:47:31 1993 Fred Fish (fnf@cygnus.com) - - * cplus-dem.c: Replace all references to cfront with ARM. - -Fri Feb 26 00:17:07 1993 Per Bothner (bothner@rtl.cygnus.com) - - * cplus-dem.c: Fix main program (when compiled with -DMAIN) - to be more useful as a filter. - -Sat Feb 20 21:41:39 1993 Brendan Kehoe (brendan@lisa.cygnus.com) - - * Makefile.in (install_to_libdir, install_to_tooldir): Go into the - destination directory before running $(RANLIB), in case that - program tries to create a file in the current directory as part of - its work. - -Thu Feb 18 23:00:19 1993 John Gilmore (gnu@cygnus.com) - - * strsignal.c (sys_siglist): Remove yet another *%^&%&$# "const" - because BSD 4.4 lacks one. Isn't this fun? - -Thu Feb 18 11:24:25 1993 Fred Fish (fnf@cygnus.com) - - * cplus-dem.c (demangle_signature): Set func_done after - demangling a template. - * cplus-dem.c (demangle_template): Fix several small bugs - in demangling GNU style templates. - * cplus-dem.c (demangle_prefix): Fix for templates in GNU - style constructors. - * cplus-dem.c (gnu_special): Fix for templates in GNU style - static data members. - -Tue Feb 16 17:28:35 1993 Fred Fish (fnf@cygnus.com) - - * cplus-dem.c (demangle_signature): Modify to include type - modifiers like static and const in remembered types. - -Thu Feb 11 22:20:47 1993 Fred Fish (fnf@cygnus.com) - - * cplus-dem.c (demangled_qualified): Add new parameter that tells - whether to prepend or append the qualifiers. - * cplus-dem.c (string_prepends): Used now, remove #if 0. - * cplus-dem.c (demangle_signature): Call demangle_qualified - with prepending. - * cplus_dem.c (gnu_special): Recognize static data members that - use qualified names. - * cplus-dem.c (demangle_qualified): Accumulate qualifiers in a - temporary buffer and the prepend or append them to the result, - as specified by the new "append" flag. - * cplus-dem.c (do_type): Call demangled_qualified with - appending. - -Mon Dec 28 10:47:19 1992 Ken Raeburn (raeburn@cygnus.com) - - * strsignal.c (signal_table): Now const. - (init_signal_tables): Variable eip now points to const. - - * strerror.c (error_table): Now const. - (init_error_tables): Variable eip now points to const. - -Tue Dec 15 15:36:50 1992 Per Bothner (bothner@cygnus.com) - - * memchr.c (memchr): New (ANSI standard) function. - * Makefile.in, functions.def: Added memchr. - * Makefile.in (AR_FLAGS): Use rc instad of non-standard cq. - -Wed Dec 2 22:49:10 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * getopt.c: remove use of USG around , which never meant - anything anyway - - * config/mh-{aix,apollo68,ncr3000,sysv,sysv4}: removed definitions - of USG and USGr4 - -Thu Nov 19 03:09:33 1992 Brendan Kehoe (brendan@lisa.cygnus.com) - - * cplus-dem.c (demangle_fund_type): Recognize `w', a wide character; - it's now a type according to the ANSI X3J16 working paper; output - "wchar_t" for it. - (demangle_template): Accept `w' as an integral type. - (xmalloc, xrealloc): Use `char *', not `PTR'. Cast calls to their - counterparts malloc and realloc to `char *'. - (main): Exit with a 0 status. - * Makefile.in (demangle): Don't expect the user to define - DEMANGLE, instead force to be cplus-dem.c. Look in $(srcdir)/../include - for demangle.h. Pass it any HDEFINES or XTRAFLAGS. - -Wed Nov 18 18:56:20 1992 John Gilmore (gnu@cygnus.com) - - * Makefile.in (AR_FLAGS): Avoid verbosity. - * config/mh-sysv4: Remove AR_FLAGS override, use INSTALL=cp, - replace USGr4 with HAVE_SYSCONF. - * config/mh-solaris: Remove; mh-sysv4 works now. - * getpagesize.c: Replace USGr4 with HAVE_SYSCONF. - * configure.in: Simplify host matching table, remove separate - solaris config file. - -Sun Nov 15 09:35:16 1992 Fred Fish (fnf@cygnus.com) - - * configure.in (i[34]86-*-solaris2*): Add, use mh-sysv4. - -Tue Nov 3 21:27:03 1992 Brendan Kehoe (brendan@cygnus.com) - - * cplus-dem.c (xmalloc, xrealloc): Add decls. - (remember_type): Don't cast xmalloc. - (string_need): Likewise; don't cast xrealloc either. - -Fri Oct 23 08:52:01 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in, functions.defs, rename.c: added simple - implementation of rename, since some binutils programs use it. - -Thu Oct 15 15:18:22 1992 Per Bothner (bothner@cygnus.com) - - * strsignal.c: Add appropriate 'const' to sys_siglist - extern declaration (if __STDC__). (Needed for Linux.) - * strsignal.c (strsignal): Add cast to remove const-ness. - -Fri Oct 9 03:22:55 1992 John Gilmore (gnu@cygnus.com) - - * Makefile.in (needed.awk, needed2.awk): Remove erroneous \'s - before "'s, diagnosed by BSD 4.4 awk. - -Thu Oct 8 15:25:12 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: create config.h and needed-list through $(CONFIG_H) - and $(NEEDED_LIST), to give some hooks for xiberty. - -Thu Oct 1 23:31:42 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: use cpu-vendor-triple instead of nested cases - -Wed Sep 30 11:26:59 1992 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in, argv.c, basename.c, bcmp.c, bcopy.c, bzero.c, - concat.c, cplus-dem.c, fdmatch.c, getcwd.c, getopt.c, getopt1.c, - getpagesize.c, insque.c, memcmp.c, memcpy.c, memmove.c, memset.c, - obstack.c, sigsetmask.c, spaces.c, strchr.c, strerror.c, - strrchr.c, strsignal.c, strstr.c, vfork.c, vsprintf.c: - Convert from using GPL to LGPL. - -Sat Sep 26 04:01:30 1992 John Gilmore (gnu@cygnus.com) - - * Makefile.in (errors): Leave dummy.o and dummy around so that - we can see how the needed list was generated (it's sometimes wrong). - (mostlyclean): Remove them. - -Mon Sep 21 14:50:42 1992 Ian Lance Taylor (ian@cygnus.com) - - * getcwd.c: supply a default if MAXPATHLEN is not defined. - - * config/mh-irix4: set EXTRA_OFILES to alloca.o, from WRS. - -Wed Sep 9 12:41:48 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: Use XTRAFLAGS when compiling, so that xiberty works - when cross-compiling. - -Thu Sep 3 13:29:39 1992 K. Richard Pixley (rich@sendai.cygnus.com) - - * cplus-dem.c: (demangle_prefix): reduction in strength of strstr - as a time optimization. - - * cplus-dem.c (cplus_demangle): remove strpbrk test. Appears to - be more expensive than simply demangling. - - * cplus-dem.c (cplus_match): new function. - -Tue Sep 1 15:24:04 1992 Per Bothner (bothner@rtl.cygnus.com) - - * cplus-dem.c: #include , to define NULL. - Define current_demangling_style. - -Sun Aug 30 17:58:19 1992 Per Bothner (bothner@rtl.cygnus.com) - - * cplus-dem.c: New file, moved from ../gdb. - * cplus-dem.c (set_cplus_marker_for_demangling): New exported - function, to avoid compiling in target-dependency for CPLUS_MARKER. - * cplus-dem.c (cplus_demangle): Allow demangling style option - to be passed as a parameter, but using the global variable - current_demangling_style as a default. - * Makefile.in: Update for cplus-dem.c - -Sat Aug 29 10:44:09 1992 Fred Fish (fnf@cygnus.com) - - * obstack.c: Merge in comment changes from FSF version. Now - matches the FSF version exactly. - -Fri Aug 28 18:39:08 1992 John Gilmore (gnu@cygnus.com) - - * obstack.c (CALL_FREEFUN): Can't use ?: with void values (at - least on losing DECstations!); use if-then-else instead. - -Wed Aug 19 14:40:34 1992 Ian Lance Taylor (ian@cygnus.com) - - * Makefile.in: always create installation directories. - -Mon Aug 10 17:33:40 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: clean up definition of CFILES, more comments - -Sat Aug 8 23:10:59 1992 Fred Fish (fnf@cygnus.com) - - * getopt.c (my_index): Make first arg const to match strchr, - which it sometimes is remapped to. - -Sat Aug 1 13:48:50 1992 Fred Fish (fnf@cygnus.com) - - * obstack.c (DEFAULT_ALIGNMENT): Update to match FSF version. - * obstack.c (_obstack_begin): Initialize use_extra_arg. - * obstack.c (_obstack_begin_1): New, from FSF version. - -Mon Jul 20 21:07:58 1992 Fred Fish (fnf@cygnus.com) - - * obstack.c (CALL_CHECKFUN, CALL_FREEFUN): Use use_extra_arg and - extra_arg. - * obstack.c (_obstack_begin): Remove area_id and flags arguments - (previously added for mmalloc support, interface has changed). - Also convert flags usage to use use_extra_arg and maybe_empty_object. - -Fri Jul 10 00:41:53 1992 Fred Fish (fnf@cygnus.com) - - * argv.c: Move expandargv inline and eliminate static variables. - Rewrite to always allocate in powers of two. Fix to return an - argv with a single null string arg if passed a null string. - -Fri Jul 3 20:27:29 1992 Fred Fish (fnf@cygnus.com) - - * random.c, sigsetmask.c, strerror.c, strsignal.c: Remove - "(void)" casts from function calls where the return value is - ignored, in accordance with GNU coding standards. - -Mon Jun 29 10:54:19 1992 Fred Fish (fnf at cygnus.com) - - * bcopy.c, strerror.c, strsignal.c: Lint. - -Thu Jun 25 09:18:41 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * getopt.c: merge changes from make. - -Thu Jun 25 04:43:22 1992 John Gilmore (gnu at cygnus.com) - - * alloca.c: Incorporate fixes from gdb/alloca.c. - FIXME: Eventually move gdb's alloca configuration files here, - and remove gdb/alloca.c and its Makefile.in support. - -Tue Jun 23 21:56:30 1992 Fred Fish (fnf@cygnus.com) - - * dummy.c: Define NOTHING to /*nothing*/, change return type - of main to int and return zero. - * functions.def: Supply NOTHING as the fourth arg to macros - that don't have an explicit arg, to satisfy picky preprocessors. - -Wed Jun 17 18:13:58 1992 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in: Clean up *clean rules, as per standards.texi. - -Tue Jun 16 16:11:59 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - * getopt.c, getopt1.c: merged largely gratuitous, mostly - whitespace diffs from other prep distributions. - -Mon Jun 15 12:25:46 1992 Fred Fish (fnf@cygnus.com) - - * config/mh-ncr3000 (INSTALL): Don't use /usr/ucb/install, - it is broken on ncr 3000's. - -Mon Jun 15 01:03:26 1992 John Gilmore (gnu at cygnus.com) - - * sigsetmask.c: Rewrite. Old one was very confused about its - arguments and result. New one can't do much, but at least knows - what it can't do, and it's good enough for GDB's use. - -Sun Jun 14 15:17:40 1992 Stu Grossman (grossman at cygnus.com) - - * functions.def: Use proper prototype for strtoul. - -Fri Jun 12 19:22:40 1992 John Gilmore (gnu at cygnus.com) - - * Makefile.in: Add random.c. - * config/mh-*: Use "true" rather than "echo >/dev/null" for ranlib. - * configure.in: update solaris2 config. - -Wed Jun 10 16:31:29 1992 Fred Fish (fnf@cygnus.com) - - * random.c: Add for random() and srandom(). - * functions.def: Add random - -Tue Jun 9 17:27:18 1992 Fred Fish (fnf@cygnus.com) - - * config/{mh-ncr3000, mh-sysv4}: Add definition for INSTALL - using /usr/ucb/install. - -Mon Jun 1 13:20:17 1992 Per Bothner (bothner@rtl.cygnus.com) - - * strerror.c: Kludge to guard against a conflict with - possible declaration of sys_errlist in errno.h. - -Sun May 31 15:07:47 1992 Mark Eichin (eichin at cygnus.com) - - * configure.in, config/mh-solaris: add solaris2 config support. - -Fri May 29 17:23:23 1992 Per Bothner (bothner@rtl.cygnus.com) - - * sigsetmask.c: #ifdef out sigsetmask if SIG_SETMASK - is not defined (should be defined in signal.h, says Posix.). - -Mon May 18 17:35:04 1992 K. Richard Pixley (rich@cygnus.com) - - * getopt.c: merged changes from make-3.62.11. - -Fri May 8 14:53:07 1992 K. Richard Pixley (rich@cygnus.com) - - * getopt.c: merged changes from bison-1.18. - -Tue May 5 11:51:40 1992 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in: Don't have $(EXTRA_OFILES) depend on config.h, - since that introduces a circular dependency. - ($(EXTRA_OFILES) are used to build config.h.) - - * strtoul.c: Fixes to handle non-decimal bases better. - -Wed Apr 22 09:27:51 1992 Fred Fish (fnf@cygnus.com) - - * config/mh-ncr3000: Replace MINUS_G with CFLAGS. - * Makefile.dos: Finish MINUS_G eradication. - * Makefile.in (CFILES): Add strsignal.c. - * Makefile.in (REQUIRED_OFILES): Add strerror.o strsignal.o - * Makefile.in (needed-list): Split creation of errors file to - separate make target. - * Makefile.in (config.h, needed2.awk, errors): New targets. - * Makefile.in (clean): Split to multiple lines, add needed2.awk - and config.h. - * dummy.c (DEFFUNC, DEFVAR): Add defines and undefs. - * functions.def (strerror): Remove from optional list. - * functions.def (sys_nerr, sys_errlist, sys_siglist): DEFVAR's - * functions.def (strerror, psignal): DEFFUNC's - * strerror.c: Rewrite from scratch to use sys_errlist only if - available, add errno_max(), add strerrno(), add strtoerrno(), - add test driver. - * strsignal.c: New file, signal equivalent to strerror.c. - Uses sys_siglist if available, defines signo_max(), strsignal(), - strsigno(), strtosigno(), psignal(), and test driver. - -Mon Apr 20 20:49:32 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in: do not print recursion line. - - * Makefile.in: allow CFLAGS to be passed in from command line. - Removed MINUS_G. Default CFLAGS to -g. - -Mon Apr 20 12:57:46 1992 Per Bothner (bothner@rtl.cygnus.com) - - * config/mh-aix: New. EXTRA_OFILES lists copysign.o, - so libg++ users don't have to be inconvenienced by a - libc.a bug (libc.a needs copysign, but doesn't define it!). - * configure.in: Use config/mh-aix. - * strtoul.c: Handle '-' as required by ANSI. - Clean up radix handling. - * strstr.c: Fix buggy algorithm. - * Makefile.in: Change so that ${EXTRA_OFILES} is - appended to needed-list (which is used by libg++). - -Fri Apr 10 22:51:41 1992 Fred Fish (fnf@cygnus.com) - - * configure.in: Recognize new ncr3000 config. - * config/mh-ncr3000: New config file. - -Wed Apr 1 23:31:43 1992 John Gilmore (gnu at cygnus.com) - - * argv.c, dummy.c: Lint. - -Tue Mar 31 18:46:44 1992 Fred Fish (fnf@cygnus.com) - - * config/mh-sysv4: New config file. - * configure.in (host_makefile_frag): Set to config/mh-sysv4 for - host_os == sysv4. - * getpagesize.c: For SVR4, use sysconf(_SC_PAGESIZE) to get - pagesize. - -Sun Mar 29 12:26:42 1992 John Gilmore (gnu at cygnus.com) - - * getopt.c: Lint. - -Fri Mar 27 08:32:55 1992 Fred Fish (fnf@cygnus.com) - - * functions.def (alloca): Fix return type and args to avoid - type clash with gcc's builtin alloca. - -Tue Mar 24 23:33:42 1992 K. Richard Pixley (rich@cygnus.com) - - * configure.in, config/mh-irix4: irix4 support. - - * Makefile.in, functions.def, alloca.c: added alloca. - -Tue Mar 24 17:34:46 1992 Stu Grossman (grossman at cygnus.com) - - * obstack.c (CALL_FREEFUN): Make it compile on DECstations. - -Thu Mar 19 13:57:42 1992 Fred Fish (fnf@cygnus.com) - - * argv.c: Fix various external function definitions to be - correct in an ANSI compilation environment. - -Sat Mar 14 17:28:17 1992 Fred Fish (fnf@cygnus.com) - - * obstack.c: Changes to support calling mmalloc functions, - which take an additional argument over malloc functions. - -Fri Mar 6 22:01:10 1992 K. Richard Pixley (rich@cygnus.com) - - * added check target. - -Thu Feb 27 22:19:39 1992 Per Bothner (bothner@cygnus.com) - - * argv.c: #include alloca-conf.h (needed by AIX). - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - -Sat Feb 22 01:09:21 1992 Stu Grossman (grossman at cygnus.com) - - * argv.c: Check in Fred's version which fixes problems with - alloca(). - -Fri Feb 7 21:46:08 1992 Stu Grossman (grossman at cygnus.com) - - * makefile.dos: Remove NUL to keep patch from failing. - -Thu Jan 30 22:48:41 1992 Stu Grossman (grossman at cygnus.com) - - * getopt.c (_getopt_internal): Fix usage of enum has_arg. - -Mon Jan 20 18:53:23 1992 Stu Grossman (grossman at cygnus.com) - - * getopt.c, getopt1.c, ../include/getopt.h: Get latest versions. - -Sat Jan 18 16:53:01 1992 Fred Fish (fnf at cygnus.com) - - * argv.c: New file to build and destroy standard argument - vectors from a command string. - - * Makefile.in: Add argv.c and argv.o to appropriate macros. - -Fri Dec 20 12:12:57 1991 Fred Fish (fnf at cygnus.com) - - * configure.in: Change svr4 references to sysv4. - - * rindex.c: Declare return type of externally used function - strrchr(). - -Thu Dec 19 18:35:03 1991 John Gilmore (gnu at cygnus.com) - - * Makefile.in: Remove "***" in normal output, since Make produces - this on errors, and it's convenient to search for. - -Tue Dec 17 23:21:30 1991 Per Bothner (bothner at cygnus.com) - - * memcmp.c, memcpy.c, memmove.c, memset.c, strchr.c, strrchr.c: - New ANSI functions. The old non-ANSI functions (such as bcopy) - should be avoided. - * bcopy.c: Fix to correctly handle overlapping regions. - * index.c, rindex.c: Re-write in terms of strchr() and strrchr(). - * functions.def: Add the new functions. - * functions.def: Add 4th parameter to DEF macro, - an ansidecl.h-style prototype. - * dummy.c: Use expanded DEF macro to create a dummy function - call, with correct parameter types. (This avoids some - complaints from gcc about predefined builtins.) - - Move the functionality of config/mh-default into Makefile.in. - This avoid duplication, and simplifies things slightly. - * Makefile.in: Tweak so we don't need config/mh-default. - * README: Update. - * configure.in: No longer need config/mh-default. - * config/mh-default: Deleted. - * config/mh-sysv: Remove lines copied from old mh-default. - -Tue Dec 17 05:46:46 1991 John Gilmore (gnu at cygnus.com) - - * fdmatch.c (fdmatch): Don't compare st_rdev, which is for - 'mknod' device numbers. - -Mon Dec 16 12:25:34 1991 Fred Fish (fnf at cygnus.com) - - * fdmatch.c, Makefile.in: Add new function that takes two - open file descriptors and returns nonzero if they refer to - the same file, zero otherwise. (used in gdb) - -Wed Dec 11 17:40:39 1991 Steve Chamberlain (sac at rtl.cygnus.com) - From DJ: - * msdos.c: stub functions for dos. - * makefile.dos, configdj.bat: new. - * getopt.c: Don't include alloca-conf.h in a GO32 world. - - -Tue Dec 10 04:14:49 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: infodir belongs in datadir. - -Fri Dec 6 23:26:45 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: remove spaces following hyphens because bsd make - can't cope. added standards.text support. install using - INSTALL_DATA. - - * configure.in: remove commontargets as it is no longer a - recognized hook. - -Thu Dec 5 22:46:46 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: idestdir and ddestdir go away. Added copyrights - and shift gpl to v2. Added ChangeLog if it didn't exist. docdir - and mandir now keyed off datadir by default. - -Fri Nov 22 19:15:29 1991 John Gilmore (gnu at cygnus.com) - - * Makefile.in: find-needed.awk does not fit in 14 chars. - - * Makefile.in: Suppress error checking when compiling the test - program, because Ultrix make/sh aborts there due to a bug. - -Fri Nov 22 12:23:17 1991 Per Bothner (bothner at cygnus.com) - - * Makefile.in: Re-did how EXTRA_OFILES is used to be more useful. - * README: Explained how the auto-configuration works, - and how to add new files and/or configurations. - -Fri Nov 22 09:45:23 1991 John Gilmore (gnu at cygnus.com) - - * strtoul.c: Avoid defining ULONG_MAX if already defined; - cast a const char * to char * for pedants. - - * getopt.c: Only define "const" after local include files get to, - and only if they haven't defined it. - -Thu Nov 21 16:58:53 1991 John Gilmore (gnu at cygnus.com) - - * getcwd.c (remove getwd.c): GNU code should call getcwd(). We - emulate it with getwd() if available. This avoids callers having - to find a MAXPATHLEN or PATH_MAX value from somewhere. - * Makefile.in, functions.def: getwd->getcwd. - * configure.in: Use generic case for every system. - * config/mh-{delta88,mach,rs6000,svr4}: Remove. - * config/mh-sysv: Use default handling, just add -DUSG. - -Thu Nov 14 10:58:05 1991 Per Bothner (bothner at cygnus.com) - - * Makefile.in, config/mh-default: Re-do make magic - so that for the default ("automatic") mode we only - compile the files we actually need. Do this using - a recursive make: The top-level generates the list - of needed files (loosely, the ones missing in libc), - and then passes that list to the recursive make. - * config/mh-mach: Remove obsolete STRERROR-{C,O} macros. - -Tue Nov 12 19:10:57 1991 John Gilmore (gnu at cygnus.com) - - RS/6000 host support (grumble). - - * configure.in: Build alloca-conf.h file from alloca-norm.h - (everything else) or alloca-botch.h (rs/6000). - * Makefile.in: Include . on the include path. - * getopt.c: Use alloca-conf.h. - * alloca-norm.h: How to declare alloca on reasonable machines. - * alloca-botch.h: How to declare alloca on braindead machines. - -Tue Nov 12 09:21:48 1991 Fred Fish (fnf at cygnus.com) - - * concat.c : New file, like concat() in gdb but can take a - variable number of arguments rather than fixed at 3 args. For - now, client applications must supply an xmalloc(), which is a - front end function to malloc() that deals with out-of-memory - conditions. - - * Makefile.in: Add concat.c and concat.o to appropriate macros. - -Sat Nov 9 13:29:59 1991 Fred Fish (fnf at cygnus.com) - - * config/mh-svr4: Add sigsetmask to list of required functions. - -Sun Nov 3 11:57:56 1991 Per Bothner (bothner at cygnus.com) - - * vsprintf.c: New file. - * functions.def, Makefile.in: Add vsprintf. - -Sun Oct 27 16:31:22 1991 John Gilmore (gnu at cygnus.com) - - * configure.in, config/mh-rs6000: Add rs/6000 host support. - * Makefile.in: Compile with debug info. - -Fri Oct 25 17:01:12 1991 Per Bothner (bothner at cygnus.com) - - * Makefile.in, configure.in, and new files: dummy.c, functions.def, - config/mf-default: Added a default configuration mode, - which includes into libiberty.a functions that are "missing" in libc. - * strdup.c, vprintf.c, vfprintf.c: New files. - -Thu Oct 24 02:29:26 1991 Fred Fish (fnf at cygnus.com) - - * config/hmake-svr4: New file. - - * config/hmake-sysv: Add HOST_CFILES and HOST_OFILES. - - * basename.c, bcmp.c, bcopy.c, bzero.c, getpagesize.c getwd.c, - index.c, insque.c, rindex.c, spaces.c, strstr.c, vfork.c: New - files containing either portable C versions or emulations using - native library calls. - - * strerror.c: Add copyright, internal documentation, etc. - - * strtol.c: Replace hardwired hex constants with some more - portable macros. Remove illegal (according to gcc) cast. - - * strtoul.c: Replace hardwired hex constant with more portable - macro. - - * Makefile.in: Move TARGETLIB and CFLAGS where makefile fragments - can override them. Add new source and object file names to CFILES - and OFILES respectively. - - * configure.in: Add support for SVR4 makefile fragments. - -Tue Oct 22 19:00:23 1991 Steve Chamberlain (steve at cygnus.com) - - * Makefile.in: Move RANLIB, AR and AR_FLAGS to where they can be - over-ridden by config/hmake-* - * configure.in: added m88kcvs to sysv list - -Fri Oct 4 01:29:08 1991 John Gilmore (gnu at cygnus.com) - - * Makefile.in: Most hosts need strerror, but one or two don't, - and they override these definitions in the host-dependent makefile - fragment. - * config/hmake-mach: The odd man out on strerror -- it's supplied. - * strerror.c: New file. - - * strtol.c, strtoul.c: Add strtol to libiberty, since Mach lacks - it and bfd uses it. - * configure.in, Makefile.in, config/hmake-mach: Only configure - strtol & strotoul in on Mach. - -Tue Sep 3 06:36:23 1991 John Gilmore (gnu at cygint.cygnus.com) - - * obstack.c: Merge with latest FSF version. - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/libiberty/Makefile.in b/contrib/gdb/libiberty/Makefile.in deleted file mode 100644 index 7f11d51439d..00000000000 --- a/contrib/gdb/libiberty/Makefile.in +++ /dev/null @@ -1,321 +0,0 @@ -# -# Makefile -# Copyright (C) 1990, 1991, 1992, 1995 Free Software Foundation -# -# This file is part of the libiberty library. -# Libiberty is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# Libiberty is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with libiberty; see the file COPYING.LIB. If -# not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# - -# This file was written, and is maintained by K. Richard Pixley -# . - -# -# Makefile for libiberty directory -# - -srcdir = . - -prefix = /usr/local - -exec_prefix = $(prefix) -bindir = $(exec_prefix)/bin -libdir = $(exec_prefix)/lib - -datadir = $(prefix)/lib - -mandir = $(prefix)/man -man1dir = $(mandir)/man1 -man2dir = $(mandir)/man2 -man3dir = $(mandir)/man3 -man4dir = $(mandir)/man4 -man5dir = $(mandir)/man5 -man6dir = $(mandir)/man6 -man7dir = $(mandir)/man7 -man8dir = $(mandir)/man8 -man9dir = $(mandir)/man9 -infodir = $(prefix)/info -includedir = $(prefix)/include -oldincludedir = -docdir = $(datadir)/doc - -SHELL = /bin/sh - -# Multilib support variables. -MULTISRCTOP = -MULTIBUILDTOP = -MULTIDIRS = -MULTISUBDIR = -MULTIDO = true -MULTICLEAN = true - -INSTALL = install -c -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) - -AR = ar -AR_FLAGS = rc - -ERRORS_CC = $(CC) -CC = cc -CFLAGS = -g -LIBCFLAGS = $(CFLAGS) -MAKEINFO = makeinfo -RANLIB = ranlib - -PICFLAG = - -MAKEOVERRIDES = - -TARGETLIB = libiberty.a - -CONFIG_H = lconfig.h -NEEDED_LIST = lneeded-list - -# HOST_OFILES contains the list of objects that should be in the -# library (in addition to the REQUIRED_OFILES and EXTRA_OFILES). -# A configuration may override this with a fixed list a object files -# names (hard to maintain), or some other way to generate a list. -HOST_OFILES=`cat needed-list` - -# Extra targets that the top-level target depends on. -# Specifically, what needs to be made before HOST_OFILES can be used. -# Can be empty if HOST_OFILES is just a list of file names. -DO_ALSO = needed-list - -# A configuration can specify extra .o files that should be included, -# even if they are in libc. (Perhaps the libc version is buggy.) -EXTRA_OFILES = - -# Flags to pass to a recursive make. -FLAGS_TO_PASS = \ - "AR=$(AR)" \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC=$(CC)" \ - "CFLAGS=$(CFLAGS)" \ - "LIBCFLAGS=$(LIBCFLAGS)" \ - "EXTRA_OFILES=$(EXTRA_OFILES)" \ - "HDEFINES=$(HDEFINES)" \ - "LDFLAGS=$(LDFLAGS)" \ - "LOADLIBES=$(LOADLIBES)" \ - "PICFLAG=$(PICFLAG)" \ - "RANLIB=$(RANLIB)" \ - "SHELL=$(SHELL)" - -all: stamp-picdir $(TARGETLIB) required-list - @if [ "$(RULE1)" != "not-used" ]; then \ - $(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=all; \ - else true; \ - fi - -.PHONY: check installcheck -check installcheck: - - -#### Host, target, and site specific Makefile fragments come in here. -### - -INCDIR=$(srcdir)/$(MULTISRCTOP)../include - -COMPILE.c = $(CC) -c $(LIBCFLAGS) -I. -I$(INCDIR) $(HDEFINES) -.c.o: - test -z "$(PICFLAG)" || \ - $(COMPILE.c) $(PICFLAG) $< -o pic/$@ - $(COMPILE.c) $< - -# The default target just invokes make recursively. -# However, the automatic configuration (in config/mh_default). -# first causes it to figure out the objects missing in libc. -info install-info clean-info dvi: - -# Include files that are in this directory. -HFILES = - -# NOTE: If you add new files to the library, add them to this list -# (alphabetical), and add them to REQUIRED_OFILES or 'functions.def'. -CFILES = alloca.c argv.c basename.c bcmp.c bcopy.c bzero.c \ - clock.c concat.c cplus-dem.c fdmatch.c \ - getcwd.c getopt.c getopt1.c getpagesize.c getruntime.c \ - floatformat.c hex.c index.c insque.c \ - memchr.c memcmp.c memcpy.c memmove.c memset.c \ - obstack.c random.c rename.c rindex.c sigsetmask.c spaces.c \ - strcasecmp.c strncasecmp.c \ - strchr.c strdup.c strerror.c strrchr.c strsignal.c \ - strstr.c strtod.c strtol.c strtoul.c tmpnam.c \ - vasprintf.c vfork.c vfprintf.c vprintf.c vsprintf.c waitpid.c \ - xatexit.c xexit.c xmalloc.c xstrdup.c xstrerror.c -# These are always included in the library. -REQUIRED_OFILES = argv.o basename.o concat.o cplus-dem.o fdmatch.o \ - getopt.o getopt1.o getruntime.o hex.o \ - floatformat.o obstack.o spaces.o strerror.o strsignal.o \ - vasprintf.o xatexit.o xexit.o xmalloc.o xstrdup.o xstrerror.o - -# Do we want/need any config overrides? -# - -STAGESTUFF = $(TARGETLIB) *.o - -INSTALL_DEST = libdir -install: install_to_$(INSTALL_DEST) - -install_to_libdir: all - $(INSTALL_DATA) $(TARGETLIB) $(libdir)/$(TARGETLIB).n - ( cd $(libdir) ; $(RANLIB) $(libdir)/$(TARGETLIB).n ) - mv -f $(libdir)/$(TARGETLIB).n $(libdir)$(MULTISUBDIR)/$(TARGETLIB) - @$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install - -install_to_tooldir: all - $(INSTALL_DATA) $(TARGETLIB) $(tooldir)/lib/$(TARGETLIB).n - ( cd $(tooldir) ; $(RANLIB) $(tooldir)/lib/$(TARGETLIB).n ) - mv -f $(tooldir)/lib/$(TARGETLIB).n $(tooldir)/lib$(MULTISUBDIR)/$(TARGETLIB) - @$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install - -# The default configuration adds to libiberty all those functions that are -# missing in libc. More precisely, it includes whatever $(CC) fails to find. -# Then a sed+awk combination translates the ld error messages into -# a list of .o files. - -needed-list: stamp-picdir $(NEEDED_LIST) - cp $(NEEDED_LIST) needed-list - -lneeded-list: $(EXTRA_OFILES) needed.awk errors - rm -f lneeded-list - f=""; \ - for i in `awk -f needed.awk >lneeded-list - -# Generate an awk script that looks for functions in functions.def - -needed.awk: $(srcdir)/functions.def Makefile - echo "# !Automatically generated from $(srcdir)/functions.def"\ - "- DO NOT EDIT!" >needed.awk - grep '^DEF(' < $(srcdir)/functions.def \ - | sed -e '/DEF/s|DEF.\([^,]*\).*|/\1/ { printf "\1.o " }|' \ - >>needed.awk - -config.h: $(CONFIG_H) - cp $(CONFIG_H) config.h - -lconfig.h: needed2.awk errors - echo "/* !Automatically generated from $(srcdir)/functions.def"\ - "- DO NOT EDIT! */" >lconfig.h - awk -f needed2.awk >lconfig.h - -# Generate an awk script that looks for variables in functions.def - -needed2.awk: $(srcdir)/functions.def Makefile - echo "# !Automatically generated from $(srcdir)/functions.def"\ - "- DO NOT EDIT!" >needed2.awk - grep '^DEFVAR(' < $(srcdir)/functions.def \ - | sed -e '/DEFVAR/s|DEFVAR.\([^,]*\).*|/\1/ { printf "#ifndef NEED_\1\\n#define NEED_\1\\n#endif\\n" }|' \ - >>needed2.awk - grep '^DEFFUNC(' < $(srcdir)/functions.def \ - | sed -e '/DEFFUNC/s|DEFFUNC.\([^,]*\).*|/\1/ { printf "#ifndef NEED_\1\\n#define NEED_\1\\n#endif\\n" }|' \ - >>needed2.awk - -dummy.o: $(srcdir)/dummy.c $(srcdir)/functions.def - $(CC) -c $(CFLAGS) -I. -I$(INCDIR) $(HDEFINES) $(srcdir)/dummy.c 2>/dev/null - -errors: dummy.o $(EXTRA_OFILES) - -($(ERRORS_CC) -o dummy $(CFLAGS) $(LDFLAGS) $(ERRORS_LDFLAGS) dummy.o $(EXTRA_OFILES) $(LOADLIBES)) >errors 2>&1 || true - -# required-list is used when building a shared bfd/opcodes/libiberty library. -required-list: Makefile - echo $(REQUIRED_OFILES) > required-list - -$(HOST_OFILES) $(REQUIRED_OFILES) : config.h - -RULE1 = $(TARGETLIB) -$(RULE1): $(REQUIRED_OFILES) $(DO_ALSO) .always. - @$(MAKE) RULE1=not-used RULE2=$(TARGETLIB) $(FLAGS_TO_PASS) \ - "HOST_OFILES=$(HOST_OFILES)" - -# Rule invoked by recursive make in $(RULE1). -RULE2 = not-used -$(RULE2): $(REQUIRED_OFILES) $(HOST_OFILES) - rm -rf $(TARGETLIB) - $(AR) $(AR_FLAGS) $(TARGETLIB) \ - $(REQUIRED_OFILES) $(HOST_OFILES) - $(RANLIB) $(TARGETLIB) - -stamp-picdir: - if [ -n "$(PICFLAG)" ] && [ ! -d pic ]; then \ - mkdir pic; \ - else true; fi - touch stamp-picdir - -.always.: -# Do nothing. - -.PHONY: all etags tags ls clean stage1 stage2 .always. - -etags tags: TAGS - -TAGS: $(CFILES) $(HFILES) - etags `for i in $(HFILES) $(CFILES); do echo $(srcdir)/$$i ; done` - -# The standalone demangler (c++filt) has been moved to binutils. -demangle: - @echo "The standalone demangler, now named c++filt, is now" - @echo "a part of binutils." - @false - -ls: - @echo Makefile $(HFILES) $(CFILES) - -# Need to deal with profiled libraries, too. - -mostlyclean: - rm -rf *.o pic core errs \#* *.E a.out - rm -f needed.awk needed2.awk errors dummy needed-list config.h - rm -f $(CONFIG_H) $(NEEDED_LIST) stamp-picdir - @$(MULTICLEAN) multi-clean DO=mostlyclean -clean: mostlyclean - rm -f *.a required-list - @$(MULTICLEAN) multi-clean DO=clean -distclean: clean - rm -f *~ Makefile config.status alloca-conf.h xhost-mkfrag TAGS - @$(MULTICLEAN) multi-clean DO=distclean -maintainer-clean realclean: distclean - -force: - -Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag) - $(SHELL) ./config.status - -argv.o: $(INCDIR)/libiberty.h -basename.o: $(INCDIR)/libiberty.h -concat.o: $(INCDIR)/libiberty.h -cplus-dem.o: $(INCDIR)/demangle.h -fdmatch.o: $(INCDIR)/libiberty.h -getopt.o: $(INCDIR)/getopt.h -getopt1.o: $(INCDIR)/getopt.h -getruntime.o: $(INCDIR)/libiberty.h -hex.o: $(INCDIR)/libiberty.h -floatformat.o: $(INCDIR)/floatformat.h -obstack.o: $(INCDIR)/obstack.h -spaces.o: $(INCDIR)/libiberty.h -strerror.o: $(INCDIR)/libiberty.h -strsignal.o: $(INCDIR)/libiberty.h -xatexit.o: $(INCDIR)/libiberty.h -xexit.o: $(INCDIR)/libiberty.h -xmalloc.o: $(INCDIR)/libiberty.h -xstrdup.o: $(INCDIR)/libiberty.h -xstrerror.o: $(INCDIR)/libiberty.h diff --git a/contrib/gdb/libiberty/README b/contrib/gdb/libiberty/README deleted file mode 100644 index 5081bbac196..00000000000 --- a/contrib/gdb/libiberty/README +++ /dev/null @@ -1,129 +0,0 @@ -This directory contains the -liberty library of free software. -It is a collection of subroutines used by various GNU programs. -Current members include: - - getopt -- get options from command line - obstack -- stacks of arbitrarily-sized objects - strerror -- error message strings corresponding to errno - strtol -- string-to-long conversion - strtoul -- string-to-unsigned-long conversion - -We expect many of the GNU subroutines that are floating around to -eventually arrive here. - -To build the library, do: - - ./configure HOSTTYPE - make - -Please report bugs and fixes to "bug-gnu-utils@prep.ai.mit.edu". Thank you. - -ADDING A NEW FILE -================= - -There are two sets of files: Those that are "required" will be -included in the library for all configurations, while those -that are "optional" will be included in the library only if "needed." - -To add a new required file, edit Makefile to add the source file -name to CFILES and the object file to REQUIRED_OFILES. - -Adding a new optional file is more fragile. As a general rule, -an optional file will be included in the library if it provides -functionality missing in the "standard" C library. -For most hosts, the Makefile automatically figures out which -functionality is missing by compiling and linking a dummy test -program, and examining the error messages. - -So to get this to work, you should do the following: - -1) Select one function defined in the file you're adding. -For example, the getcwd function. -2) Add that function to the list in the file functions.def. -3) The name of the new file must be the same as the function -you've chosen with the .c suffix added. E.g. getcwd() must be -defined in getcwd.c. (The file can define other functions as well.) -4) In Makefile.in, add the name of the source file (e.g. getcwd.c) -to CFILES. - -The file you've added (e.g. getcwd.c) should compile and work -on all hosts where it is needed (e.g. not found when linking -the dummy.c program). It does not have to work or even -compile on hosts where it is not needed. - -HOW THE AUTOMATIC CONFIGURATION WORKS -===================================== - -The libiberty.a target (in RULE1) depends on $(DO_ALSO). -For normal configurations, DO_ALSO=needed-list. - -So needed-list is first made. The needed-list rule compiles -dummy.c. Because dummy.c includes functions.def, the -resulting object file will contain a call to each of the -optional functions (for simplicity assume each optional file -defines a single function). This object file will be linked -against the standard libraries (as defined by using $(CC) -and various flags). Any function missing will causes the -linker to emit an error message. We assume the name -of the missing function(s) are in the error message(s). -The awk script find-needed.awk has been generated from -functions.def. It is used to search the linker output -messages for words that match the functions listed in -functions.def. The list of functions found is written -on a single line to the file needed-list. - -After needed-list has been generated, the libiberty.a -target (in RULE1) just calls 'make' recursively. -It passes the contents of needed-list using the -definition (expanded) HOST_OFILES="`cat needed-list`". -It also tells the inferior 'make' to use RULE2. - -The inferior 'make' is very conventional: The main -rule is $(RULE2) (which is libiberty.a). It depends -on a list of object files: $(REQUIRED_OFILES) $(HOST_OFILES) -(and $(EXTRA_OFILES), which is usually empty). The superior -'make' passes in $(HOST_OFILES); the others are fixed -in the Makefile. - -ADDING A NEW CONFIGURATION -========================== - -On most hosts you should be able to use the scheme for automatically -figuring out which files are needed. In that case, you probably -don't need a special Makefile stub for that configuration. - -If the fully automatic scheme doesn't work, you may be able to get -by with defining EXTRA_OFILES in your Makefile stub. This is -a list of object file names that should be treated as required -for this configuration - they will be included in libiberty.a, -regardless of whatever might be in the C library. Moreover, -when the dummy.c program is linked, it will be linked with -$(EXTRA_OFILES). Therefore, if a function in functions.def -is defined by one of the EXTRA_OFILES, it will not be listed as -"needed". Thus if your hal9000 host needs a special implementation -of getcwd, you can just create hal9000-getcwd.c, and define: - EXTRA_OFILES=hal9000-getcwd.o -Or if you want to use the libiberty version of strstr(), -even though there is a version in the C library (it might be -buggy or slow), just define: - EXTRA_OFILES=strstr.o - -You can create a "manual" host configuration FOO with a file -config/mh-FOO. In it, the HOST_OFILES macro should explicitly -list that subset of the optional files that should be in the -library. You should also set: - DO_ALSO = -This overrides all of the magic needed to automatically -determine which files are "needed." However, keeping that list -up to date is another matter... - -HOW THE MANUAL CONFIGURATION WORKS -================================== - -This also uses a recursive make, but the superior make -does not do anything interesting - it just calls the -inferior make with HOST_OFILES defined as $(HOST_OFILES), -which is the list you created in your configuration. - -You probably don't want to depend on manual configuration, -because keeping the HOST_OFILES list up-to-date will be a pain. diff --git a/contrib/gdb/libiberty/alloca-botch.h b/contrib/gdb/libiberty/alloca-botch.h deleted file mode 100644 index c909573f58c..00000000000 --- a/contrib/gdb/libiberty/alloca-botch.h +++ /dev/null @@ -1,5 +0,0 @@ -/* RS/6000 AIX botched alloca and requires a pragma, which ordinary compilers - throw up about, so we have to put it in a specially-configured file. - Like this one. */ - -#pragma alloca diff --git a/contrib/gdb/libiberty/alloca-norm.h b/contrib/gdb/libiberty/alloca-norm.h deleted file mode 100644 index 8d91b5ad429..00000000000 --- a/contrib/gdb/libiberty/alloca-norm.h +++ /dev/null @@ -1,16 +0,0 @@ -/* "Normal" configuration for alloca. */ - -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not __GNUC__ */ -#ifdef sparc -#include -extern char *__builtin_alloca(); /* Stupid include file doesn't declare it */ -#else -#ifdef __STDC__ -PTR alloca (size_t); -#else -PTR alloca (); /* must agree with functions.def */ -#endif -#endif /* sparc */ -#endif /* not __GNUC__ */ diff --git a/contrib/gdb/libiberty/alloca.c b/contrib/gdb/libiberty/alloca.c deleted file mode 100644 index 9c472ead6df..00000000000 --- a/contrib/gdb/libiberty/alloca.c +++ /dev/null @@ -1,475 +0,0 @@ -/* alloca.c -- allocate automatically reclaimed memory - (Mostly) portable public-domain implementation -- D A Gwyn - - This implementation of the PWB library alloca function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - J.Otto Tennant contributed the Cray support. - - There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* If compiling with GCC, this file's not needed. */ -#ifndef alloca - -#ifdef emacs -#ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -#ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -#endif /* STACK_DIRECTION undefined */ -#endif /* static */ -#endif /* emacs */ - -/* If your stack is a linked list of frames, you have to - provide an "address metric" ADDRESS_FUNCTION macro. */ - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) -long i00afunc (); -#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) -#else -#define ADDRESS_FUNCTION(arg) &(arg) -#endif - -#if __STDC__ -typedef void *pointer; -#else -typedef char *pointer; -#endif - -#define NULL 0 - -/* Different portions of Emacs need to call different versions of - malloc. The Emacs executable needs alloca to call xmalloc, because - ordinary malloc isn't protected from input signals. On the other - hand, the utilities in lib-src need alloca to call malloc; some of - them are very simple, and don't have an xmalloc routine. - - Non-Emacs programs expect this to call use xmalloc. - - Callers below should use malloc. */ - -#ifndef emacs -#define malloc xmalloc -extern pointer xmalloc (); -#endif - -/* Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ - -#ifndef STACK_DIRECTION -#define STACK_DIRECTION 0 /* Direction unknown. */ -#endif - -#if STACK_DIRECTION != 0 - -#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ - -#else /* STACK_DIRECTION == 0; need run-time code. */ - -static int stack_dir; /* 1 or -1 once known. */ -#define STACK_DIR stack_dir - -static void -find_stack_direction () -{ - static char *addr = NULL; /* Address of first `dummy', once known. */ - auto char dummy; /* To get stack address. */ - - if (addr == NULL) - { /* Initial entry. */ - addr = ADDRESS_FUNCTION (dummy); - - find_stack_direction (); /* Recurse once. */ - } - else - { - /* Second entry. */ - if (ADDRESS_FUNCTION (dummy) > addr) - stack_dir = 1; /* Stack grew upward. */ - else - stack_dir = -1; /* Stack grew downward. */ - } -} - -#endif /* STACK_DIRECTION == 0 */ - -/* An "alloca header" is used to: - (a) chain together all alloca'ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc - alignment chunk size. The following default should work okay. */ - -#ifndef ALIGN_SIZE -#define ALIGN_SIZE sizeof(double) -#endif - -typedef union hdr -{ - char align[ALIGN_SIZE]; /* To force sizeof(header). */ - struct - { - union hdr *next; /* For chaining headers. */ - char *deep; /* For stack depth measure. */ - } h; -} header; - -static header *last_alloca_header = NULL; /* -> last alloca header. */ - -/* Return a pointer to at least SIZE bytes of storage, - which will be automatically reclaimed upon exit from - the procedure that called alloca. Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. */ - -pointer -alloca (size) - unsigned size; -{ - auto char probe; /* Probes stack depth: */ - register char *depth = ADDRESS_FUNCTION (probe); - -#if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* Unknown growth direction. */ - find_stack_direction (); -#endif - - /* Reclaim garbage, defined as all alloca'd storage that - was allocated from deeper in the stack than currently. */ - - { - register header *hp; /* Traverses linked list. */ - - for (hp = last_alloca_header; hp != NULL;) - if ((STACK_DIR > 0 && hp->h.deep > depth) - || (STACK_DIR < 0 && hp->h.deep < depth)) - { - register header *np = hp->h.next; - - free ((pointer) hp); /* Collect garbage. */ - - hp = np; /* -> next header. */ - } - else - break; /* Rest are not deeper. */ - - last_alloca_header = hp; /* -> last valid storage. */ - } - - if (size == 0) - return NULL; /* No allocation required. */ - - /* Allocate combined header + user data storage. */ - - { - register pointer new = malloc (sizeof (header) + size); - /* Address of header. */ - - ((header *) new)->h.next = last_alloca_header; - ((header *) new)->h.deep = depth; - - last_alloca_header = (header *) new; - - /* User storage begins just after header. */ - - return (pointer) ((char *) new + sizeof (header)); - } -} - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) - -#ifdef DEBUG_I00AFUNC -#include -#endif - -#ifndef CRAY_STACK -#define CRAY_STACK -#ifndef CRAY2 -/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ -struct stack_control_header - { - long shgrow:32; /* Number of times stack has grown. */ - long shaseg:32; /* Size of increments to stack. */ - long shhwm:32; /* High water mark of stack. */ - long shsize:32; /* Current size of stack (all segments). */ - }; - -/* The stack segment linkage control information occurs at - the high-address end of a stack segment. (The stack - grows from low addresses to high addresses.) The initial - part of the stack segment linkage control information is - 0200 (octal) words. This provides for register storage - for the routine which overflows the stack. */ - -struct stack_segment_linkage - { - long ss[0200]; /* 0200 overflow words. */ - long sssize:32; /* Number of words in this segment. */ - long ssbase:32; /* Offset to stack base. */ - long:32; - long sspseg:32; /* Offset to linkage control of previous - segment of stack. */ - long:32; - long sstcpt:32; /* Pointer to task common address block. */ - long sscsnm; /* Private control structure number for - microtasking. */ - long ssusr1; /* Reserved for user. */ - long ssusr2; /* Reserved for user. */ - long sstpid; /* Process ID for pid based multi-tasking. */ - long ssgvup; /* Pointer to multitasking thread giveup. */ - long sscray[7]; /* Reserved for Cray Research. */ - long ssa0; - long ssa1; - long ssa2; - long ssa3; - long ssa4; - long ssa5; - long ssa6; - long ssa7; - long sss0; - long sss1; - long sss2; - long sss3; - long sss4; - long sss5; - long sss6; - long sss7; - }; - -#else /* CRAY2 */ -/* The following structure defines the vector of words - returned by the STKSTAT library routine. */ -struct stk_stat - { - long now; /* Current total stack size. */ - long maxc; /* Amount of contiguous space which would - be required to satisfy the maximum - stack demand to date. */ - long high_water; /* Stack high-water mark. */ - long overflows; /* Number of stack overflow ($STKOFEN) calls. */ - long hits; /* Number of internal buffer hits. */ - long extends; /* Number of block extensions. */ - long stko_mallocs; /* Block allocations by $STKOFEN. */ - long underflows; /* Number of stack underflow calls ($STKRETN). */ - long stko_free; /* Number of deallocations by $STKRETN. */ - long stkm_free; /* Number of deallocations by $STKMRET. */ - long segments; /* Current number of stack segments. */ - long maxs; /* Maximum number of stack segments so far. */ - long pad_size; /* Stack pad size. */ - long current_address; /* Current stack segment address. */ - long current_size; /* Current stack segment size. This - number is actually corrupted by STKSTAT to - include the fifteen word trailer area. */ - long initial_address; /* Address of initial segment. */ - long initial_size; /* Size of initial segment. */ - }; - -/* The following structure describes the data structure which trails - any stack segment. I think that the description in 'asdef' is - out of date. I only describe the parts that I am sure about. */ - -struct stk_trailer - { - long this_address; /* Address of this block. */ - long this_size; /* Size of this block (does not include - this trailer). */ - long unknown2; - long unknown3; - long link; /* Address of trailer block of previous - segment. */ - long unknown5; - long unknown6; - long unknown7; - long unknown8; - long unknown9; - long unknown10; - long unknown11; - long unknown12; - long unknown13; - long unknown14; - }; - -#endif /* CRAY2 */ -#endif /* not CRAY_STACK */ - -#ifdef CRAY2 -/* Determine a "stack measure" for an arbitrary ADDRESS. - I doubt that "lint" will like this much. */ - -static long -i00afunc (long *address) -{ - struct stk_stat status; - struct stk_trailer *trailer; - long *block, size; - long result = 0; - - /* We want to iterate through all of the segments. The first - step is to get the stack status structure. We could do this - more quickly and more directly, perhaps, by referencing the - $LM00 common block, but I know that this works. */ - - STKSTAT (&status); - - /* Set up the iteration. */ - - trailer = (struct stk_trailer *) (status.current_address - + status.current_size - - 15); - - /* There must be at least one stack segment. Therefore it is - a fatal error if "trailer" is null. */ - - if (trailer == 0) - abort (); - - /* Discard segments that do not contain our argument address. */ - - while (trailer != 0) - { - block = (long *) trailer->this_address; - size = trailer->this_size; - if (block == 0 || size == 0) - abort (); - trailer = (struct stk_trailer *) trailer->link; - if ((block <= address) && (address < (block + size))) - break; - } - - /* Set the result to the offset in this segment and add the sizes - of all predecessor segments. */ - - result = address - block; - - if (trailer == 0) - { - return result; - } - - do - { - if (trailer->this_size <= 0) - abort (); - result += trailer->this_size; - trailer = (struct stk_trailer *) trailer->link; - } - while (trailer != 0); - - /* We are done. Note that if you present a bogus address (one - not in any segment), you will get a different number back, formed - from subtracting the address of the first block. This is probably - not what you want. */ - - return (result); -} - -#else /* not CRAY2 */ -/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. - Determine the number of the cell within the stack, - given the address of the cell. The purpose of this - routine is to linearize, in some sense, stack addresses - for alloca. */ - -static long -i00afunc (long address) -{ - long stkl = 0; - - long size, pseg, this_segment, stack; - long result = 0; - - struct stack_segment_linkage *ssptr; - - /* Register B67 contains the address of the end of the - current stack segment. If you (as a subprogram) store - your registers on the stack and find that you are past - the contents of B67, you have overflowed the segment. - - B67 also points to the stack segment linkage control - area, which is what we are really interested in. */ - - stkl = CRAY_STACKSEG_END (); - ssptr = (struct stack_segment_linkage *) stkl; - - /* If one subtracts 'size' from the end of the segment, - one has the address of the first word of the segment. - - If this is not the first segment, 'pseg' will be - nonzero. */ - - pseg = ssptr->sspseg; - size = ssptr->sssize; - - this_segment = stkl - size; - - /* It is possible that calling this routine itself caused - a stack overflow. Discard stack segments which do not - contain the target address. */ - - while (!(this_segment <= address && address <= stkl)) - { -#ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); -#endif - if (pseg == 0) - break; - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - this_segment = stkl - size; - } - - result = address - this_segment; - - /* If you subtract pseg from the current end of the stack, - you get the address of the previous stack segment's end. - This seems a little convoluted to me, but I'll bet you save - a cycle somewhere. */ - - while (pseg != 0) - { -#ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o\n", pseg, size); -#endif - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - result += size; - } - return (result); -} - -#endif /* not CRAY2 */ -#endif /* CRAY */ - -#endif /* no alloca */ diff --git a/contrib/gdb/libiberty/argv.c b/contrib/gdb/libiberty/argv.c deleted file mode 100644 index 40582abe408..00000000000 --- a/contrib/gdb/libiberty/argv.c +++ /dev/null @@ -1,328 +0,0 @@ -/* Create and destroy argument vectors (argv's) - Copyright (C) 1992 Free Software Foundation, Inc. - Written by Fred Fish @ Cygnus Support - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Create and destroy argument vectors. An argument vector is simply an - array of string pointers, terminated by a NULL pointer. */ - -#include "ansidecl.h" -#include "libiberty.h" - -#define isspace(ch) ((ch) == ' ' || (ch) == '\t') - -/* Routines imported from standard C runtime libraries. */ - -#ifdef __STDC__ - -#include -extern void *memcpy (void *s1, const void *s2, size_t n); /* 4.11.2.1 */ -extern size_t strlen (const char *s); /* 4.11.6.3 */ -extern void *malloc (size_t size); /* 4.10.3.3 */ -extern void *realloc (void *ptr, size_t size); /* 4.10.3.4 */ -extern void free (void *ptr); /* 4.10.3.2 */ -extern char *strdup (const char *s); /* Non-ANSI */ - -#else /* !__STDC__ */ - -extern char *memcpy (); /* Copy memory region */ -extern int strlen (); /* Count length of string */ -extern char *malloc (); /* Standard memory allocater */ -extern char *realloc (); /* Standard memory reallocator */ -extern void free (); /* Free malloc'd memory */ -extern char *strdup (); /* Duplicate a string */ - -#endif /* __STDC__ */ - -#include "alloca-conf.h" - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef EOS -#define EOS '\0' -#endif - -#define INITIAL_MAXARGC 8 /* Number of args + NULL in initial argv */ - - -/* - -NAME - - freeargv -- free an argument vector - -SYNOPSIS - - void freeargv (vector) - char **vector; - -DESCRIPTION - - Free an argument vector that was built using buildargv. Simply scans - through the vector, freeing the memory for each argument until the - terminating NULL is found, and then frees the vector itself. - -RETURNS - - No value. - -*/ - -void freeargv (vector) -char **vector; -{ - register char **scan; - - if (vector != NULL) - { - for (scan = vector; *scan != NULL; scan++) - { - free (*scan); - } - free (vector); - } -} - -/* - -NAME - - buildargv -- build an argument vector from a string - -SYNOPSIS - - char **buildargv (sp) - char *sp; - -DESCRIPTION - - Given a pointer to a string, parse the string extracting fields - separated by whitespace and optionally enclosed within either single - or double quotes (which are stripped off), and build a vector of - pointers to copies of the string for each field. The input string - remains unchanged. - - All of the memory for the pointer array and copies of the string - is obtained from malloc. All of the memory can be returned to the - system with the single function call freeargv, which takes the - returned result of buildargv, as it's argument. - - The memory for the argv array is dynamically expanded as necessary. - -RETURNS - - Returns a pointer to the argument vector if successful. Returns NULL - if the input string pointer is NULL or if there is insufficient - memory to complete building the argument vector. - -NOTES - - In order to provide a working buffer for extracting arguments into, - with appropriate stripping of quotes and translation of backslash - sequences, we allocate a working buffer at least as long as the input - string. This ensures that we always have enough space in which to - work, since the extracted arg is never larger than the input string. - - If the input is a null string (as opposed to a NULL pointer), then - buildarg returns an argv that has one arg, a null string. - - Argv is always kept terminated with a NULL arg pointer, so it can - be passed to freeargv at any time, or returned, as appropriate. -*/ - -char **buildargv (input) -char *input; -{ - char *arg; - char *copybuf; - int squote = 0; - int dquote = 0; - int bsquote = 0; - int argc = 0; - int maxargc = 0; - char **argv = NULL; - char **nargv; - - if (input != NULL) - { - copybuf = alloca (strlen (input) + 1); - /* Is a do{}while to always execute the loop once. Always return an - argv, even for null strings. See NOTES above, test case below. */ - do - { - /* Pick off argv[argc] */ - while (isspace (*input)) - { - input++; - } - if ((maxargc == 0) || (argc >= (maxargc - 1))) - { - /* argv needs initialization, or expansion */ - if (argv == NULL) - { - maxargc = INITIAL_MAXARGC; - nargv = (char **) malloc (maxargc * sizeof (char *)); - } - else - { - maxargc *= 2; - nargv = (char **) realloc (argv, maxargc * sizeof (char *)); - } - if (nargv == NULL) - { - if (argv != NULL) - { - freeargv (argv); - argv = NULL; - } - break; - } - argv = nargv; - argv[argc] = NULL; - } - /* Begin scanning arg */ - arg = copybuf; - while (*input != EOS) - { - if (isspace (*input) && !squote && !dquote && !bsquote) - { - break; - } - else - { - if (bsquote) - { - bsquote = 0; - *arg++ = *input; - } - else if (*input == '\\') - { - bsquote = 1; - } - else if (squote) - { - if (*input == '\'') - { - squote = 0; - } - else - { - *arg++ = *input; - } - } - else if (dquote) - { - if (*input == '"') - { - dquote = 0; - } - else - { - *arg++ = *input; - } - } - else - { - if (*input == '\'') - { - squote = 1; - } - else if (*input == '"') - { - dquote = 1; - } - else - { - *arg++ = *input; - } - } - input++; - } - } - *arg = EOS; - argv[argc] = strdup (copybuf); - if (argv[argc] == NULL) - { - freeargv (argv); - argv = NULL; - break; - } - argc++; - argv[argc] = NULL; - - while (isspace (*input)) - { - input++; - } - } - while (*input != EOS); - } - return (argv); -} - -#ifdef MAIN - -/* Simple little test driver. */ - -static char *tests[] = -{ - "a simple command line", - "arg 'foo' is single quoted", - "arg \"bar\" is double quoted", - "arg \"foo bar\" has embedded whitespace", - "arg 'Jack said \\'hi\\'' has single quotes", - "arg 'Jack said \\\"hi\\\"' has double quotes", - "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9", - - /* This should be expanded into only one argument. */ - "trailing-whitespace ", - - "", - NULL -}; - -main () -{ - char **argv; - char **test; - char **targs; - - for (test = tests; *test != NULL; test++) - { - printf ("buildargv(\"%s\")\n", *test); - if ((argv = buildargv (*test)) == NULL) - { - printf ("failed!\n\n"); - } - else - { - for (targs = argv; *targs != NULL; targs++) - { - printf ("\t\"%s\"\n", *targs); - } - printf ("\n"); - } - freeargv (argv); - } - -} - -#endif /* MAIN */ diff --git a/contrib/gdb/libiberty/atexit.c b/contrib/gdb/libiberty/atexit.c deleted file mode 100644 index 4463cb69501..00000000000 --- a/contrib/gdb/libiberty/atexit.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Wrapper to implement ANSI C's atexit using SunOS's on_exit. */ -/* This function is in the public domain. --Mike Stump. */ - -#ifndef NEED_on_exit -int -atexit(f) - void (*f)(); -{ - /* If the system doesn't provide a definition for atexit, use on_exit - if the system provides that. */ - on_exit (f, 0); - return 0; -} -#endif diff --git a/contrib/gdb/libiberty/basename.c b/contrib/gdb/libiberty/basename.c deleted file mode 100644 index 689b0c2d39a..00000000000 --- a/contrib/gdb/libiberty/basename.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Return the basename of a pathname. - This file is in the public domain. */ - -/* -NAME - basename -- return pointer to last component of a pathname - -SYNOPSIS - char *basename (const char *name) - -DESCRIPTION - Given a pointer to a string containing a typical pathname - (/usr/src/cmd/ls/ls.c for example), returns a pointer to the - last component of the pathname ("ls.c" in this case). - -BUGS - Presumes a UNIX style path with UNIX style separators. -*/ - -#include "ansidecl.h" -#include "libiberty.h" - -#include "config.h" - -#ifdef NEED_basename - -char * -basename (name) - const char *name; -{ - const char *base = name; - - while (*name) - { - if (*name++ == '/') - { - base = name; - } - } - return (char *) base; -} - -#endif diff --git a/contrib/gdb/libiberty/bcmp.c b/contrib/gdb/libiberty/bcmp.c deleted file mode 100644 index 11e4417db15..00000000000 --- a/contrib/gdb/libiberty/bcmp.c +++ /dev/null @@ -1,49 +0,0 @@ -/* bcmp - This function is in the public domain. */ - -/* - -NAME - - bcmp -- compare two memory regions - -SYNOPSIS - - int bcmp (char *from, char *to, int count) - -DESCRIPTION - - Compare two memory regions and return zero if they are identical, - non-zero otherwise. If count is zero, return zero. - -NOTES - - No guarantee is made about the non-zero returned value. In - particular, the results may be signficantly different than - strcmp(), where the return value is guaranteed to be less than, - equal to, or greater than zero, according to lexicographical - sorting of the compared regions. - -BUGS - -*/ - - -int -bcmp (from, to, count) - char *from, *to; - int count; -{ - int rtnval = 0; - - while (count-- > 0) - { - if (*from++ != *to++) - { - rtnval = 1; - break; - } - } - return (rtnval); -} - diff --git a/contrib/gdb/libiberty/bcopy.c b/contrib/gdb/libiberty/bcopy.c deleted file mode 100644 index b655363d879..00000000000 --- a/contrib/gdb/libiberty/bcopy.c +++ /dev/null @@ -1,35 +0,0 @@ -/* bcopy -- copy memory regions of arbitary length - -NAME - bcopy -- copy memory regions of arbitrary length - -SYNOPSIS - void bcopy (char *in, char *out, int length) - -DESCRIPTION - Copy LENGTH bytes from memory region pointed to by IN to memory - region pointed to by OUT. - -BUGS - Significant speed improvements can be made in some cases by - implementing copies of multiple bytes simultaneously, or unrolling - the copy loop. - -*/ - -void -bcopy (src, dest, len) - register char *src, *dest; - int len; -{ - if (dest < src) - while (len--) - *dest++ = *src++; - else - { - char *lasts = src + (len-1); - char *lastd = dest + (len-1); - while (len--) - *(char *)lastd-- = *(char *)lasts--; - } -} diff --git a/contrib/gdb/libiberty/bzero.c b/contrib/gdb/libiberty/bzero.c deleted file mode 100644 index d01644b7f4b..00000000000 --- a/contrib/gdb/libiberty/bzero.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Portable version of bzero for systems without it. - This function is in the public domain. */ - -/* -NAME - bzero -- zero the contents of a specified memory region - -SYNOPSIS - void bzero (char *to, int count) - -DESCRIPTION - Zero COUNT bytes of memory pointed to by TO. - -BUGS - Significant speed enhancements may be made in some environments - by zeroing more than a single byte at a time, or by unrolling the - loop. - -*/ - - -void -bzero (to, count) - char *to; - int count; -{ - while (count-- > 0) - { - *to++ = 0; - } -} diff --git a/contrib/gdb/libiberty/clock.c b/contrib/gdb/libiberty/clock.c deleted file mode 100644 index b60de1657a4..00000000000 --- a/contrib/gdb/libiberty/clock.c +++ /dev/null @@ -1,73 +0,0 @@ -/* ANSI-compatible clock function. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - -This file is part of the libiberty library. This library is free -software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) -any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As a special exception, if you link this library with files -compiled with a GNU compiler to produce an executable, this does not cause -the resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why -the executable file might be covered by the GNU General Public License. */ - -#ifdef HAVE_GETRUSAGE -#include -#include -#endif - -#ifdef HAVE_TIMES -#ifndef NO_SYS_PARAM_H -#include -#endif -#include -#endif - -/* FIXME: should be able to declare as clock_t. */ - -long -clock () -{ -#ifdef HAVE_GETRUSAGE - struct rusage rusage; - - getrusage (0, &rusage); - return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec - + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); -#else -#ifdef HAVE_TIMES - struct tms tms; - - times (&tms); - return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ); -#else -#ifdef VMS - struct - { - int proc_user_time; - int proc_system_time; - int child_user_time; - int child_system_time; - } vms_times; - - times (&vms_times); - return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000; -#else - /* A fallback, if nothing else available. */ - return 0; -#endif /* VMS */ -#endif /* HAVE_TIMES */ -#endif /* HAVE_GETRUSAGE */ -} - diff --git a/contrib/gdb/libiberty/concat.c b/contrib/gdb/libiberty/concat.c deleted file mode 100644 index 5b132c85764..00000000000 --- a/contrib/gdb/libiberty/concat.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Concatenate variable number of strings. - Copyright (C) 1991, 1994 Free Software Foundation, Inc. - Written by Fred Fish @ Cygnus Support - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* - -NAME - - concat -- concatenate a variable number of strings - -SYNOPSIS - - #include - - char *concat (s1, s2, s3, ..., NULL) - -DESCRIPTION - - Concatenate a variable number of strings and return the result - in freshly malloc'd memory. - - Returns NULL if insufficient memory is available. The argument - list is terminated by the first NULL pointer encountered. Pointers - to empty strings are ignored. - -NOTES - - This function uses xmalloc() which is expected to be a front end - function to malloc() that deals with low memory situations. In - typical use, if malloc() returns NULL then xmalloc() diverts to an - error handler routine which never returns, and thus xmalloc will - never return a NULL pointer. If the client application wishes to - deal with low memory situations itself, it should supply an xmalloc - that just directly invokes malloc and blindly returns whatever - malloc returns. -*/ - - -#include "ansidecl.h" -#include "libiberty.h" - -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - -#ifdef __STDC__ -#include -extern size_t strlen (const char *s); -#else -extern int strlen (); -#endif - -#define NULLP (char *)0 - -/* VARARGS */ -#ifdef ANSI_PROTOTYPES -char * -concat (const char *first, ...) -#else -char * -concat (va_alist) - va_dcl -#endif -{ - register int length; - register char *newstr; - register char *end; - register const char *arg; - va_list args; -#ifndef ANSI_PROTOTYPES - const char *first; -#endif - - /* First compute the size of the result and get sufficient memory. */ - -#ifdef ANSI_PROTOTYPES - va_start (args, first); -#else - va_start (args); - first = va_arg (args, const char *); -#endif - - if (first == NULLP) - length = 0; - else - { - length = strlen (first); - while ((arg = va_arg (args, const char *)) != NULLP) - { - length += strlen (arg); - } - } - newstr = (char *) xmalloc (length + 1); - va_end (args); - - /* Now copy the individual pieces to the result string. */ - - if (newstr != NULLP) - { -#ifdef ANSI_PROTOTYPES - va_start (args, first); -#else - va_start (args); - first = va_arg (args, const char *); -#endif - end = newstr; - if (first != NULLP) - { - arg = first; - while (*arg) - { - *end++ = *arg++; - } - while ((arg = va_arg (args, const char *)) != NULLP) - { - while (*arg) - { - *end++ = *arg++; - } - } - } - *end = '\000'; - va_end (args); - } - - return (newstr); -} - -#ifdef MAIN - -/* Simple little test driver. */ - -#include - -int -main () -{ - printf ("\"\" = \"%s\"\n", concat (NULLP)); - printf ("\"a\" = \"%s\"\n", concat ("a", NULLP)); - printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP)); - printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP)); - printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP)); - printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP)); - printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP)); - return 0; -} - -#endif diff --git a/contrib/gdb/libiberty/config.table b/contrib/gdb/libiberty/config.table deleted file mode 100644 index 1b67dd5ae88..00000000000 --- a/contrib/gdb/libiberty/config.table +++ /dev/null @@ -1,63 +0,0 @@ -case "${host}" in - rs6000-ibm-aix3.1 | rs6000-ibm-aix) - frag=mh-aix - files=${xsrcdir}alloca-botch.h ;; - *-ibm-aix*) files=${xsrcdir}alloca-botch.h ;; - arm-*-riscix*) frag=mh-riscix ;; - m68k-apollo-bsd*) frag=mh-a68bsd ;; - m68k-apollo-sysv*) frag=mh-apollo68 ;; - i[345]86-ncr-sysv4*) frag=mh-ncr3000 ;; - *-*-cxux7*) frag=mh-cxux7 ;; - *-*-lynxos*) frag=mh-lynxos ;; - *-*-dgux*) frag=mh-sysv ;; - hppa*-hp-bsd*) frag=mh-hpbsd ;; - *-*-hpux*) frag=mh-hpux ;; - *-*-hiux*) frag=mh-hpux ;; - *-*-irix4*) frag=mh-irix4 ;; - *-*-irix*) frag=mh-sysv ;; - *-*-m88kbcs*) frag=mh-sysv ;; - *-*-solaris2*) frag=mh-sysv4 ;; - *-*-sysv4*) frag=mh-sysv4 ;; - *-*-sysv*) frag=mh-sysv ;; - *-*-go32) frag=mh-go32 ;; - - *-*-vxworks5*) - # VxWorks 5 needs special action, because the usual - # autoconfiguration scheme does not work. - frag=mt-vxworks5 - ;; -esac - -# Try to handle funky case of solaris 2 -> sun 4. -case "${host}" in - sparc-sun-sunos4.1.3) - if [ "${with_cross_host}" != "${host}" ] ; then - frag=mt-sunos4 - fi - ;; -esac - -frags=$frag - -# If they didn't specify --enable-shared, don't generate shared libs. -if [ "${enable_shared}" = "yes" ]; then - case "${host}" in - hppa*-*-*) frags="${frags} ../../config/mh-papic" ;; - i[345]86-*-*) frags="${frags} ../../config/mh-x86pic" ;; - *-*-*) frags="${frags} ../../config/mh-${host_cpu}pic" ;; - esac -fi - -echo "# Warning: this fragment is automatically generated" > temp-frag - -for frag in ${frags}; do - frag=${srcdir}/${xsrcdir}config/$frag - if [ -f ${frag} ]; then - echo "Appending ${frag} to xhost-mkfrag" - echo "# Following fragment copied from ${frag}" >> temp-frag - cat ${frag} >> temp-frag - fi -done - -frag=xhost-mkfrag -${moveifchange} temp-frag xhost-mkfrag diff --git a/contrib/gdb/libiberty/config/mh-a68bsd b/contrib/gdb/libiberty/config/mh-a68bsd deleted file mode 100644 index 3c5a237e60b..00000000000 --- a/contrib/gdb/libiberty/config/mh-a68bsd +++ /dev/null @@ -1,2 +0,0 @@ -RANLIB=ranlib -CC= cc -A ansi -A runtype,any -A systype,any -U__STDC__ diff --git a/contrib/gdb/libiberty/config/mh-aix b/contrib/gdb/libiberty/config/mh-aix deleted file mode 100644 index c7b848d976a..00000000000 --- a/contrib/gdb/libiberty/config/mh-aix +++ /dev/null @@ -1,10 +0,0 @@ -HDEFINES = -D__IEEE_BIG_ENDIAN -RANLIB=true -INSTALL=cp - -# Most releases of AIX 3.1 include an incorrect internal version of copysign -# in libc.a for use by some libc public functions including modf. The public -# version of copysign in libm.a is usable. For the sake of libg++ (which -# uses modf), we add copysign here. Supposedly, this problem is fixed in AIX -# 3.1.8 and above, including all releases of AIX 3.2. -EXTRA_OFILES = copysign.o diff --git a/contrib/gdb/libiberty/config/mh-apollo68 b/contrib/gdb/libiberty/config/mh-apollo68 deleted file mode 100644 index 651770ce31c..00000000000 --- a/contrib/gdb/libiberty/config/mh-apollo68 +++ /dev/null @@ -1,2 +0,0 @@ -RANLIB=true -CC= cc -A ansi -A runtype,any -A systype,any -U__STDC__ diff --git a/contrib/gdb/libiberty/config/mh-cxux7 b/contrib/gdb/libiberty/config/mh-cxux7 deleted file mode 100644 index 6d4d30bf46f..00000000000 --- a/contrib/gdb/libiberty/config/mh-cxux7 +++ /dev/null @@ -1,3 +0,0 @@ -HDEFINES = -DHAVE_SYSCONF -DHARRIS_FLOAT_FORMAT -RANLIB=true -INSTALL = cp diff --git a/contrib/gdb/libiberty/config/mh-go32 b/contrib/gdb/libiberty/config/mh-go32 deleted file mode 100644 index 7c9fe4fa0bf..00000000000 --- a/contrib/gdb/libiberty/config/mh-go32 +++ /dev/null @@ -1,4 +0,0 @@ -HDEFINES=-DHAVE_GETRUSAGE -CC=i386-go32-gcc -O2 -fno-omit-frame-pointer -AR=i386-go32-ar -RANLIB=i386-go32-ranlib diff --git a/contrib/gdb/libiberty/config/mh-hpbsd b/contrib/gdb/libiberty/config/mh-hpbsd deleted file mode 100644 index ce11dcd6ac9..00000000000 --- a/contrib/gdb/libiberty/config/mh-hpbsd +++ /dev/null @@ -1,2 +0,0 @@ -# HPPA hosts using BSD -RANLIB=true diff --git a/contrib/gdb/libiberty/config/mh-irix4 b/contrib/gdb/libiberty/config/mh-irix4 deleted file mode 100644 index ace76782712..00000000000 --- a/contrib/gdb/libiberty/config/mh-irix4 +++ /dev/null @@ -1,4 +0,0 @@ -CC = cc -cckr -RANLIB = true -INSTALL = cp -EXTRA_OFILES = alloca.o diff --git a/contrib/gdb/libiberty/config/mh-lynxos b/contrib/gdb/libiberty/config/mh-lynxos deleted file mode 100644 index 2f22110e880..00000000000 --- a/contrib/gdb/libiberty/config/mh-lynxos +++ /dev/null @@ -1 +0,0 @@ -HDEFINES = -DLOSING_SYS_SIGLIST diff --git a/contrib/gdb/libiberty/config/mh-ncr3000 b/contrib/gdb/libiberty/config/mh-ncr3000 deleted file mode 100644 index 3a45c22b128..00000000000 --- a/contrib/gdb/libiberty/config/mh-ncr3000 +++ /dev/null @@ -1,19 +0,0 @@ -# Host configuration file for an NCR 3000 (i486/SVR4) system. - -# The NCR 3000 ships with a MetaWare compiler installed as /bin/cc. -# This compiler not only emits obnoxious copyright messages every time -# you run it, but it chokes and dies on a whole bunch of GNU source -# files. Default to using the AT&T compiler installed in /usr/ccs/ATT/cc. -# Unfortunately though, the AT&T compiler sometimes generates code that -# the assembler barfs on if -g is used, so disable it by default as well. -CC = /usr/ccs/ATT/cc -CFLAGS = - -RANLIB = true - -# The /usr/ucb/install program is incompatible (complains about unknown -# group staff). Use good old cp... -INSTALL = cp - -# The l flag generates a warning from the SVR4 archiver, remove it. -AR_FLAGS = cq diff --git a/contrib/gdb/libiberty/config/mh-riscix b/contrib/gdb/libiberty/config/mh-riscix deleted file mode 100644 index 0209279de56..00000000000 --- a/contrib/gdb/libiberty/config/mh-riscix +++ /dev/null @@ -1,6 +0,0 @@ -# The native linker only reports the first undefined symbol if linking with a -# shared library. So build using gcc and link statically (this requires -# gcc 2.6.0 or above). - -ERRORS_CC = gcc -ERRORS_LDFLAGS = -static diff --git a/contrib/gdb/libiberty/config/mh-sysv b/contrib/gdb/libiberty/config/mh-sysv deleted file mode 100644 index eb102d55010..00000000000 --- a/contrib/gdb/libiberty/config/mh-sysv +++ /dev/null @@ -1 +0,0 @@ -RANLIB=true diff --git a/contrib/gdb/libiberty/config/mh-sysv4 b/contrib/gdb/libiberty/config/mh-sysv4 deleted file mode 100644 index 4d1aa3cd61d..00000000000 --- a/contrib/gdb/libiberty/config/mh-sysv4 +++ /dev/null @@ -1,3 +0,0 @@ -HDEFINES = -DHAVE_SYSCONF -RANLIB=true -INSTALL = cp diff --git a/contrib/gdb/libiberty/config/mt-sunos4 b/contrib/gdb/libiberty/config/mt-sunos4 deleted file mode 100644 index c25baa6ead6..00000000000 --- a/contrib/gdb/libiberty/config/mt-sunos4 +++ /dev/null @@ -1,2 +0,0 @@ -XTRAFLAGS = -isystem /s1/cygnus/dejagnu/sparc-sun-sunos4.1.3/include/ -LOADLIBES = -L/s1/cygnus/dejagnu/sparc-sun-sunos4.1.3/lib diff --git a/contrib/gdb/libiberty/config/mt-vxworks5 b/contrib/gdb/libiberty/config/mt-vxworks5 deleted file mode 100644 index f1a46d361ae..00000000000 --- a/contrib/gdb/libiberty/config/mt-vxworks5 +++ /dev/null @@ -1,27 +0,0 @@ -# VxWorks 5.x target Makefile fragment. -# The autoconfiguration fails for a VxWorks target, because the -# libraries are actually on the target board, not in the file system. -# Therefore, we compute the dependencies by hand. - -HDEFINES = -DNO_SYS_PARAM_H -CONFIG_H = vxconfig.h -NEEDED_LIST = vxneeded-list - -vxconfig.h: Makefile - if [ -f ../newlib/Makefile ]; then \ - $(MAKE) $(FLAGS_TO_PASS) xconfig.h; \ - cp xconfig.h vxconfig.h; \ - else \ - echo "#define NEED_sys_nerr 1" >vxconfig.h; \ - echo "#define NEED_sys_errlist 1" >>vxconfig.h; \ - echo "#define NEED_sys_siglist 1" >>vxconfig.h; \ - echo "#define NEED_psignal 1" >>vxconfig.h; \ - fi - -vxneeded-list: Makefile - if [ -f ../newlib/Makefile ]; then \ - $(MAKE) $(FLAGS_TO_PASS) xneeded-list; \ - cp xneeded-list vxneeded-list; \ - else \ - echo getopt.o getpagesize.o insque.o random.o strcasecmp.o strncasecmp.o strdup.o vfork.o sigsetmask.o waitpid.o >vxneeded-list; \ - fi diff --git a/contrib/gdb/libiberty/configure.bat b/contrib/gdb/libiberty/configure.bat deleted file mode 100644 index ed33777174b..00000000000 --- a/contrib/gdb/libiberty/configure.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo off -if "%1" == "h8/300" goto h8300 - -echo Configuring libiberty for go32 -copy Makefile.dos Makefile -echo #define NEED_sys_siglist 1 >> config.h -echo #define NEED_psignal 1 >> config.h -update alloca-normal.h alloca-conf.h -goto exit - -:h8300 -echo Configuring libiberty for H8/300 -copy Makefile.dos Makefile - -:exit diff --git a/contrib/gdb/libiberty/configure.in b/contrib/gdb/libiberty/configure.in deleted file mode 100644 index 84e4eac6c89..00000000000 --- a/contrib/gdb/libiberty/configure.in +++ /dev/null @@ -1,77 +0,0 @@ -# This file is a shell script fragment that supplies the information -# necessary for a configure script to process the program in -# this directory. For more information, look at ../configure. - -configdirs= -srctrigger=getopt1.c -srcname="-liberty library" - -# per-host: - -files="alloca-norm.h" -links="alloca-conf.h" - -. ${srcdir}/config.table -host_makefile_frag=${frag} - -# per-target: - -# post-target: - -# If this is the target libiberty, check at compile time whether we are using -# newlib. If we are, we already know the files we need, since the linker -# will fail when run on some of the newlib targets. -if [ -n "${with_target_subdir}" ] ; then - cat > Makefile.tem <<'!EOF!' -CONFIG_H = xconfig.h -NEEDED_LIST = xneeded-list - -xconfig.h: Makefile - if [ -f ../newlib/Makefile ]; then \ - echo "#define NEED_sys_nerr 1" >xconfig.h; \ - echo "#define NEED_sys_errlist 1" >>xconfig.h; \ - echo "#define NEED_sys_siglist 1" >>xconfig.h; \ - echo "#define NEED_psignal 1" >>xconfig.h; \ - else \ - $(MAKE) $(FLAGS_TO_PASS) lconfig.h; \ - cp lconfig.h xconfig.h; \ - fi - -xneeded-list: Makefile - if [ -f ../newlib/Makefile ]; then \ - echo insque.o random.o strdup.o alloca.o >xneeded-list; \ - else \ - $(MAKE) $(FLAGS_TO_PASS) lneeded-list; \ - cp lneeded-list xneeded-list; \ - fi -!EOF! -sed -e "/^####/ r Makefile.tem" \ - -e '/INSTALL_DEST =/s/libdir/tooldir/' ${Makefile} > Makefile.tem3 -mv Makefile.tem3 ${Makefile} -rm -f Makefile.tem -fi - -# We need multilib support, but only if configuring for the target. -if [ -n "${with_target_subdir}" ] ; then - case ${srcdir} in - .) - if [ "${with_target_subdir}" != "." ] ; then - - # Set MULTISRCTOP to the value we need if we are not doing - # multilib. This will be overridden if --enable-multilib was - # used. - sed -e "s:^MULTISRCTOP[ ]*=.*$:MULTISRCTOP = ../:" \ - ${Makefile} > Makefile.tem - rm -f ${Makefile} - mv Makefile.tem ${Makefile} - - . ${srcdir}/${with_multisrctop}../../config-ml.in - else - . ${srcdir}/${with_multisrctop}../config-ml.in - fi - ;; - *) - . ${srcdir}/../config-ml.in - ;; - esac -fi diff --git a/contrib/gdb/libiberty/copysign.c b/contrib/gdb/libiberty/copysign.c deleted file mode 100644 index 0b5f8c3d9df..00000000000 --- a/contrib/gdb/libiberty/copysign.c +++ /dev/null @@ -1,140 +0,0 @@ -#include - -#ifdef __IEEE_BIG_ENDIAN - -typedef union -{ - double value; - struct - { - unsigned int sign : 1; - unsigned int exponent: 11; - unsigned int fraction0:4; - unsigned int fraction1:16; - unsigned int fraction2:16; - unsigned int fraction3:16; - - } number; - struct - { - unsigned int sign : 1; - unsigned int exponent: 11; - unsigned int quiet:1; - unsigned int function0:3; - unsigned int function1:16; - unsigned int function2:16; - unsigned int function3:16; - } nan; - struct - { - unsigned long msw; - unsigned long lsw; - } parts; - long aslong[2]; -} __ieee_double_shape_type; - -#endif - -#ifdef __IEEE_LITTLE_ENDIAN - -typedef union -{ - double value; - struct - { -#ifdef __SMALL_BITFIELDS - unsigned int fraction3:16; - unsigned int fraction2:16; - unsigned int fraction1:16; - unsigned int fraction0: 4; -#else - unsigned int fraction1:32; - unsigned int fraction0:20; -#endif - unsigned int exponent :11; - unsigned int sign : 1; - } number; - struct - { -#ifdef __SMALL_BITFIELDS - unsigned int function3:16; - unsigned int function2:16; - unsigned int function1:16; - unsigned int function0:3; -#else - unsigned int function1:32; - unsigned int function0:19; -#endif - unsigned int quiet:1; - unsigned int exponent: 11; - unsigned int sign : 1; - } nan; - struct - { - unsigned long lsw; - unsigned long msw; - } parts; - - long aslong[2]; - -} __ieee_double_shape_type; - -#endif - -#ifdef __IEEE_BIG_ENDIAN -typedef union -{ - float value; - struct - { - unsigned int sign : 1; - unsigned int exponent: 8; - unsigned int fraction0: 7; - unsigned int fraction1: 16; - } number; - struct - { - unsigned int sign:1; - unsigned int exponent:8; - unsigned int quiet:1; - unsigned int function0:6; - unsigned int function1:16; - } nan; - long p1; - -} __ieee_float_shape_type; -#endif - -#ifdef __IEEE_LITTLE_ENDIAN -typedef union -{ - float value; - struct - { - unsigned int fraction0: 7; - unsigned int fraction1: 16; - unsigned int exponent: 8; - unsigned int sign : 1; - } number; - struct - { - unsigned int function1:16; - unsigned int function0:6; - unsigned int quiet:1; - unsigned int exponent:8; - unsigned int sign:1; - } nan; - long p1; - -} __ieee_float_shape_type; -#endif - - -double DEFUN(copysign, (x, y), double x AND double y) -{ - __ieee_double_shape_type a,b; - b.value = y; - a.value = x; - a.number.sign =b.number.sign; - return a.value; -} diff --git a/contrib/gdb/libiberty/cplus-dem.c b/contrib/gdb/libiberty/cplus-dem.c deleted file mode 100644 index a7f86802278..00000000000 --- a/contrib/gdb/libiberty/cplus-dem.c +++ /dev/null @@ -1,3019 +0,0 @@ -/* Demangler for GNU C++ - Copyright 1989, 1991, 1994, 1995, 1996 Free Software Foundation, Inc. - Written by James Clark (jjc@jclark.uucp) - Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file exports two functions; cplus_mangle_opname and cplus_demangle. - - This file imports xmalloc and xrealloc, which are like malloc and - realloc except that they generate a fatal error if there is no - available memory. */ - -#include -#include -#include - -#include -#undef CURRENT_DEMANGLING_STYLE -#define CURRENT_DEMANGLING_STYLE work->options - -extern char *xmalloc PARAMS((unsigned)); -extern char *xrealloc PARAMS((char *, unsigned)); - -char * -mystrstr (s1, s2) - char *s1, *s2; -{ - register char *p = s1; - register int len = strlen (s2); - - for (; (p = strchr (p, *s2)) != 0; p++) - { - if (strncmp (p, s2, len) == 0) - { - return (p); - } - } - return (0); -} - -/* In order to allow a single demangler executable to demangle strings - using various common values of CPLUS_MARKER, as well as any specific - one set at compile time, we maintain a string containing all the - commonly used ones, and check to see if the marker we are looking for - is in that string. CPLUS_MARKER is usually '$' on systems where the - assembler can deal with that. Where the assembler can't, it's usually - '.' (but on many systems '.' is used for other things). We put the - current defined CPLUS_MARKER first (which defaults to '$'), followed - by the next most common value, followed by an explicit '$' in case - the value of CPLUS_MARKER is not '$'. - - We could avoid this if we could just get g++ to tell us what the actual - cplus marker character is as part of the debug information, perhaps by - ensuring that it is the character that terminates the gcc_compiled - marker symbol (FIXME). */ - -#if !defined (CPLUS_MARKER) -#define CPLUS_MARKER '$' -#endif - -enum demangling_styles current_demangling_style = gnu_demangling; - -static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; - -void -set_cplus_marker_for_demangling (ch) - int ch; -{ - cplus_markers[0] = ch; -} - -/* Stuff that is shared between sub-routines. - * Using a shared structure allows cplus_demangle to be reentrant. */ - -struct work_stuff -{ - int options; - char **typevec; - int ntypes; - int typevec_size; - int constructor; - int destructor; - int static_type; /* A static member function */ - int const_type; /* A const member function */ -}; - -#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) -#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS) - -static const struct optable -{ - const char *in; - const char *out; - int flags; -} optable[] = { - {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ - {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ - {"new", " new", 0}, /* old (1.91, and 1.x) */ - {"delete", " delete", 0}, /* old (1.91, and 1.x) */ - {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */ - {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */ - {"as", "=", DMGL_ANSI}, /* ansi */ - {"ne", "!=", DMGL_ANSI}, /* old, ansi */ - {"eq", "==", DMGL_ANSI}, /* old, ansi */ - {"ge", ">=", DMGL_ANSI}, /* old, ansi */ - {"gt", ">", DMGL_ANSI}, /* old, ansi */ - {"le", "<=", DMGL_ANSI}, /* old, ansi */ - {"lt", "<", DMGL_ANSI}, /* old, ansi */ - {"plus", "+", 0}, /* old */ - {"pl", "+", DMGL_ANSI}, /* ansi */ - {"apl", "+=", DMGL_ANSI}, /* ansi */ - {"minus", "-", 0}, /* old */ - {"mi", "-", DMGL_ANSI}, /* ansi */ - {"ami", "-=", DMGL_ANSI}, /* ansi */ - {"mult", "*", 0}, /* old */ - {"ml", "*", DMGL_ANSI}, /* ansi */ - {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */ - {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */ - {"convert", "+", 0}, /* old (unary +) */ - {"negate", "-", 0}, /* old (unary -) */ - {"trunc_mod", "%", 0}, /* old */ - {"md", "%", DMGL_ANSI}, /* ansi */ - {"amd", "%=", DMGL_ANSI}, /* ansi */ - {"trunc_div", "/", 0}, /* old */ - {"dv", "/", DMGL_ANSI}, /* ansi */ - {"adv", "/=", DMGL_ANSI}, /* ansi */ - {"truth_andif", "&&", 0}, /* old */ - {"aa", "&&", DMGL_ANSI}, /* ansi */ - {"truth_orif", "||", 0}, /* old */ - {"oo", "||", DMGL_ANSI}, /* ansi */ - {"truth_not", "!", 0}, /* old */ - {"nt", "!", DMGL_ANSI}, /* ansi */ - {"postincrement","++", 0}, /* old */ - {"pp", "++", DMGL_ANSI}, /* ansi */ - {"postdecrement","--", 0}, /* old */ - {"mm", "--", DMGL_ANSI}, /* ansi */ - {"bit_ior", "|", 0}, /* old */ - {"or", "|", DMGL_ANSI}, /* ansi */ - {"aor", "|=", DMGL_ANSI}, /* ansi */ - {"bit_xor", "^", 0}, /* old */ - {"er", "^", DMGL_ANSI}, /* ansi */ - {"aer", "^=", DMGL_ANSI}, /* ansi */ - {"bit_and", "&", 0}, /* old */ - {"ad", "&", DMGL_ANSI}, /* ansi */ - {"aad", "&=", DMGL_ANSI}, /* ansi */ - {"bit_not", "~", 0}, /* old */ - {"co", "~", DMGL_ANSI}, /* ansi */ - {"call", "()", 0}, /* old */ - {"cl", "()", DMGL_ANSI}, /* ansi */ - {"alshift", "<<", 0}, /* old */ - {"ls", "<<", DMGL_ANSI}, /* ansi */ - {"als", "<<=", DMGL_ANSI}, /* ansi */ - {"arshift", ">>", 0}, /* old */ - {"rs", ">>", DMGL_ANSI}, /* ansi */ - {"ars", ">>=", DMGL_ANSI}, /* ansi */ - {"component", "->", 0}, /* old */ - {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */ - {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */ - {"indirect", "*", 0}, /* old */ - {"method_call", "->()", 0}, /* old */ - {"addr", "&", 0}, /* old (unary &) */ - {"array", "[]", 0}, /* old */ - {"vc", "[]", DMGL_ANSI}, /* ansi */ - {"compound", ", ", 0}, /* old */ - {"cm", ", ", DMGL_ANSI}, /* ansi */ - {"cond", "?:", 0}, /* old */ - {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */ - {"max", ">?", 0}, /* old */ - {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */ - {"min", "*", DMGL_ANSI} /* ansi */ -}; - - -typedef struct string /* Beware: these aren't required to be */ -{ /* '\0' terminated. */ - char *b; /* pointer to start of string */ - char *p; /* pointer after last character */ - char *e; /* pointer after end of allocated space */ -} string; - -#define STRING_EMPTY(str) ((str) -> b == (str) -> p) -#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_prepend(str, " ");} -#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_append(str, " ");} - -#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ -#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ - -/* Prototypes for local functions */ - -static char * -mop_up PARAMS ((struct work_stuff *, string *, int)); - -#if 0 -static int -demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *)); -#endif - -static int -demangle_template PARAMS ((struct work_stuff *work, const char **, string *, - string *)); - -static int -demangle_qualified PARAMS ((struct work_stuff *, const char **, string *, - int, int)); - -static int -demangle_class PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_signature PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_prefix PARAMS ((struct work_stuff *, const char **, string *)); - -static int -gnu_special PARAMS ((struct work_stuff *, const char **, string *)); - -static int -arm_special PARAMS ((struct work_stuff *, const char **, string *)); - -static void -string_need PARAMS ((string *, int)); - -static void -string_delete PARAMS ((string *)); - -static void -string_init PARAMS ((string *)); - -static void -string_clear PARAMS ((string *)); - -#if 0 -static int -string_empty PARAMS ((string *)); -#endif - -static void -string_append PARAMS ((string *, const char *)); - -static void -string_appends PARAMS ((string *, string *)); - -static void -string_appendn PARAMS ((string *, const char *, int)); - -static void -string_prepend PARAMS ((string *, const char *)); - -static void -string_prependn PARAMS ((string *, const char *, int)); - -static int -get_count PARAMS ((const char **, int *)); - -static int -consume_count PARAMS ((const char **)); - -static int -demangle_args PARAMS ((struct work_stuff *, const char **, string *)); - -static int -do_type PARAMS ((struct work_stuff *, const char **, string *)); - -static int -do_arg PARAMS ((struct work_stuff *, const char **, string *)); - -static void -demangle_function_name PARAMS ((struct work_stuff *, const char **, string *, - const char *)); - -static void -remember_type PARAMS ((struct work_stuff *, const char *, int)); - -static void -forget_types PARAMS ((struct work_stuff *)); - -static void -string_prepends PARAMS ((string *, string *)); - -/* Translate count to integer, consuming tokens in the process. - Conversion terminates on the first non-digit character. - Trying to consume something that isn't a count results in - no consumption of input and a return of 0. */ - -static int -consume_count (type) - const char **type; -{ - int count = 0; - - while (isdigit (**type)) - { - count *= 10; - count += **type - '0'; - (*type)++; - } - return (count); -} - -int -cplus_demangle_opname (opname, result, options) - const char *opname; - char *result; - int options; -{ - int len, i, len1, ret; - string type; - struct work_stuff work[1]; - const char *tem; - - len = strlen(opname); - result[0] = '\0'; - ret = 0; - work->options = options; - - if (opname[0] == '_' && opname[1] == '_' - && opname[2] == 'o' && opname[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = opname + 4; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - else if (opname[0] == '_' && opname[1] == '_' - && opname[2] >= 'a' && opname[2] <= 'z' - && opname[3] >= 'a' && opname[3] <= 'z') - { - if (opname[4] == '\0') - { - /* Operator. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, opname + 2, 2) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - else - { - if (opname[2] == 'a' && opname[5] == '\0') - { - /* Assignment. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, opname + 2, 3) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - } - else if (len >= 3 - && opname[0] == 'o' - && opname[1] == 'p' - && strchr (cplus_markers, opname[2]) != NULL) - { - /* see if it's an assignment expression */ - if (len >= 10 /* op$assign_ */ - && memcmp (opname + 3, "assign_", 7) == 0) - { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - len1 = len - 10; - if (strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 10, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - strcat (result, "="); - ret = 1; - break; - } - } - } - else - { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - len1 = len - 3; - if (strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 3, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - else if (len >= 5 && memcmp (opname, "type", 4) == 0 - && strchr (cplus_markers, opname[4]) != NULL) - { - /* type conversion operator */ - tem = opname + 5; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - return ret; - -} -/* Takes operator name as e.g. "++" and returns mangled - operator name (e.g. "postincrement_expr"), or NULL if not found. - - If OPTIONS & DMGL_ANSI == 1, return the ANSI name; - if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ - -const char * -cplus_mangle_opname (opname, options) - const char *opname; - int options; -{ - int i; - int len; - - len = strlen (opname); - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].out) == len - && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) - && memcmp (optable[i].out, opname, len) == 0) - return optable[i].in; - } - return (0); -} - -/* check to see whether MANGLED can match TEXT in the first TEXT_LEN - characters. */ - -int cplus_match (mangled, text, text_len) - const char *mangled; - char *text; - int text_len; -{ - if (strncmp (mangled, text, text_len) != 0) { - return(0); /* cannot match either */ - } else { - return(1); /* matches mangled, may match demangled */ - } -} - -/* char *cplus_demangle (const char *mangled, int options) - - If MANGLED is a mangled function name produced by GNU C++, then - a pointer to a malloced string giving a C++ representation - of the name will be returned; otherwise NULL will be returned. - It is the caller's responsibility to free the string which - is returned. - - The OPTIONS arg may contain one or more of the following bits: - - DMGL_ANSI ANSI qualifiers such as `const' and `void' are - included. - DMGL_PARAMS Function parameters are included. - - For example, - - cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" - cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" - cplus_demangle ("foo__1Ai", 0) => "A::foo" - - cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" - cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" - cplus_demangle ("foo__1Afe", 0) => "A::foo" - - Note that any leading underscores, or other such characters prepended by - the compilation system, are presumed to have already been stripped from - MANGLED. */ - -char * -cplus_demangle (mangled, options) - const char *mangled; - int options; -{ - string decl; - int success = 0; - struct work_stuff work[1]; - char *demangled = NULL; - - if ((mangled != NULL) && (*mangled != '\0')) - { - memset ((char *) work, 0, sizeof (work)); - work -> options = options; - if ((work->options & DMGL_STYLE_MASK) == 0) - work->options |= (int)current_demangling_style & DMGL_STYLE_MASK; - - string_init (&decl); - - /* First check to see if gnu style demangling is active and if the - string to be demangled contains a CPLUS_MARKER. If so, attempt to - recognize one of the gnu special forms rather than looking for a - standard prefix. In particular, don't worry about whether there - is a "__" string in the mangled string. Consider "_$_5__foo" for - example. */ - - if ((AUTO_DEMANGLING || GNU_DEMANGLING)) - { - success = gnu_special (work, &mangled, &decl); - } - if (!success) - { - success = demangle_prefix (work, &mangled, &decl); - } - if (success && (*mangled != '\0')) - { - success = demangle_signature (work, &mangled, &decl); - } - if (work->constructor == 2) - { - string_prepend(&decl, "global constructors keyed to "); - work->constructor = 0; - } - else if (work->destructor == 2) - { - string_prepend(&decl, "global destructors keyed to "); - work->destructor = 0; - } - demangled = mop_up (work, &decl, success); - } - return (demangled); -} - -static char * -mop_up (work, declp, success) - struct work_stuff *work; - string *declp; - int success; -{ - char *demangled = NULL; - - /* Discard the remembered types, if any. */ - - forget_types (work); - if (work -> typevec != NULL) - { - free ((char *) work -> typevec); - } - - /* If demangling was successful, ensure that the demangled string is null - terminated and return it. Otherwise, free the demangling decl. */ - - if (!success) - { - string_delete (declp); - } - else - { - string_appendn (declp, "", 1); - demangled = declp -> b; - } - return (demangled); -} - -/* - -LOCAL FUNCTION - - demangle_signature -- demangle the signature part of a mangled name - -SYNOPSIS - - static int - demangle_signature (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the signature portion of the mangled name. - - DECLP is the string where demangled output is being built. At - entry it contains the demangled root name from the mangled name - prefix. I.E. either a demangled operator name or the root function - name. In some special cases, it may contain nothing. - - *MANGLED points to the current unconsumed location in the mangled - name. As tokens are consumed and demangling is performed, the - pointer is updated to continuously point at the next token to - be consumed. - - Demangling GNU style mangled names is nasty because there is no - explicit token that marks the start of the outermost function - argument list. -*/ - -static int -demangle_signature (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 1; - int func_done = 0; - int expect_func = 0; - const char *oldmangled = NULL; - string trawname; - string tname; - - while (success && (**mangled != '\0')) - { - switch (**mangled) - { - case 'Q': - oldmangled = *mangled; - success = demangle_qualified (work, mangled, declp, 1, 0); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'S': - /* Static member function */ - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - (*mangled)++; - work -> static_type = 1; - break; - - case 'C': - /* a const member function */ - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - (*mangled)++; - work -> const_type = 1; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - success = demangle_class (work, mangled, declp); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'F': - /* Function */ - /* ARM style demangling includes a specific 'F' character after - the class name. For GNU style, it is just implied. So we can - safely just consume any 'F' at this point and be compatible - with either style. */ - - oldmangled = NULL; - func_done = 1; - (*mangled)++; - - /* For lucid/ARM style we have to forget any types we might - have remembered up to this point, since they were not argument - types. GNU style considers all types seen as available for - back references. See comment in demangle_args() */ - - if (LUCID_DEMANGLING || ARM_DEMANGLING) - { - forget_types (work); - } - success = demangle_args (work, mangled, declp); - break; - - case 't': - /* G++ Template */ - string_init(&trawname); - string_init(&tname); - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - success = demangle_template (work, mangled, &tname, &trawname); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - string_append(&tname, "::"); - string_prepends(declp, &tname); - if (work -> destructor & 1) - { - string_prepend (&trawname, "~"); - string_appends (declp, &trawname); - work->destructor -= 1; - } - if ((work->constructor & 1) || (work->destructor & 1)) - { - string_appends (declp, &trawname); - work->constructor -= 1; - } - string_delete(&trawname); - string_delete(&tname); - oldmangled = NULL; - expect_func = 1; - break; - - case '_': - /* At the outermost level, we cannot have a return type specified, - so if we run into another '_' at this point we are dealing with - a mangled name that is either bogus, or has been mangled by - some algorithm we don't know how to deal with. So just - reject the entire demangling. */ - success = 0; - break; - - default: - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = 1; - success = demangle_args (work, mangled, declp); - } - else - { - /* Non-GNU demanglers use a specific token to mark the start - of the outermost function argument tokens. Typically 'F', - for ARM-demangling, for example. So if we find something - we are not prepared for, it must be an error. */ - success = 0; - } - break; - } -/* - if (AUTO_DEMANGLING || GNU_DEMANGLING) -*/ - { - if (success && expect_func) - { - func_done = 1; - success = demangle_args (work, mangled, declp); - } - } - } - if (success && !func_done) - { - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added to - the current declp. Note that with ARM, the first case - represents the name of a static data member 'foo::bar', - which is in the current declp, so we leave it alone. */ - success = demangle_args (work, mangled, declp); - } - } - if (success && work -> static_type && PRINT_ARG_TYPES) - { - string_append (declp, " static"); - } - if (success && work -> const_type && PRINT_ARG_TYPES) - { - string_append (declp, " const"); - } - return (success); -} - -#if 0 - -static int -demangle_method_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 0; - - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - return (success); -} - -#endif - -static int -demangle_template (work, mangled, tname, trawname) - struct work_stuff *work; - const char **mangled; - string *tname; - string *trawname; -{ - int i; - int is_pointer; - int is_real; - int is_integral; - int is_char; - int is_bool; - int r; - int need_comma = 0; - int success = 0; - int done; - const char *old_p; - const char *start; - int symbol_len; - string temp; - - (*mangled)++; - start = *mangled; - /* get template name */ - if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r) - { - return (0); - } - if (trawname) - string_appendn (trawname, *mangled, r); - string_appendn (tname, *mangled, r); - *mangled += r; - string_append (tname, "<"); - /* get size of template parameter list */ - if (!get_count (mangled, &r)) - { - return (0); - } - for (i = 0; i < r; i++) - { - if (need_comma) - { - string_append (tname, ", "); - } - /* Z for type parameters */ - if (**mangled == 'Z') - { - (*mangled)++; - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - if (success) - { - string_appends (tname, &temp); - } - string_delete(&temp); - if (!success) - { - break; - } - } - else - { - /* otherwise, value parameter */ - old_p = *mangled; - is_pointer = 0; - is_real = 0; - is_integral = 0; - is_char = 0; - is_bool = 0; - done = 0; - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); -/* - if (success) - { - string_appends (tname, &temp); - } -*/ - string_delete(&temp); - if (!success) - { - break; - } -/* - string_append (tname, "="); -*/ - while (*old_p && !done) - { - switch (*old_p) - { - case 'P': - case 'p': - case 'R': - done = is_pointer = 1; - break; - case 'C': /* const */ - case 'S': /* explicitly signed [char] */ - case 'U': /* unsigned */ - case 'V': /* volatile */ - case 'F': /* function */ - case 'M': /* member function */ - case 'O': /* ??? */ - old_p++; - continue; - case 'Q': /* qualified name */ - done = is_integral = 1; - break; - case 'T': /* remembered type */ - abort (); - break; - case 'v': /* void */ - abort (); - break; - case 'x': /* long long */ - case 'l': /* long */ - case 'i': /* int */ - case 's': /* short */ - case 'w': /* wchar_t */ - done = is_integral = 1; - break; - case 'b': /* bool */ - done = is_bool = 1; - break; - case 'c': /* char */ - done = is_char = 1; - break; - case 'r': /* long double */ - case 'd': /* double */ - case 'f': /* float */ - done = is_real = 1; - break; - default: - /* it's probably user defined type, let's assume - it's integral, it seems hard to figure out - what it really is */ - done = is_integral = 1; - } - } - if (is_integral) - { - if (**mangled == 'm') - { - string_appendn (tname, "-", 1); - (*mangled)++; - } - while (isdigit (**mangled)) - { - string_appendn (tname, *mangled, 1); - (*mangled)++; - } - } - else if (is_char) - { - char tmp[2]; - int val; - if (**mangled == 'm') - { - string_appendn (tname, "-", 1); - (*mangled)++; - } - string_appendn (tname, "'", 1); - val = consume_count(mangled); - if (val == 0) - { - success = 0; - break; - } - tmp[0] = (char)val; - tmp[1] = '\0'; - string_appendn (tname, &tmp[0], 1); - string_appendn (tname, "'", 1); - } - else if (is_bool) - { - int val = consume_count (mangled); - if (val == 0) - string_appendn (tname, "false", 5); - else if (val == 1) - string_appendn (tname, "true", 4); - else - success = 0; - } - else if (is_real) - { - if (**mangled == 'm') - { - string_appendn (tname, "-", 1); - (*mangled)++; - } - while (isdigit (**mangled)) - { - string_appendn (tname, *mangled, 1); - (*mangled)++; - } - if (**mangled == '.') /* fraction */ - { - string_appendn (tname, ".", 1); - (*mangled)++; - while (isdigit (**mangled)) - { - string_appendn (tname, *mangled, 1); - (*mangled)++; - } - } - if (**mangled == 'e') /* exponent */ - { - string_appendn (tname, "e", 1); - (*mangled)++; - while (isdigit (**mangled)) - { - string_appendn (tname, *mangled, 1); - (*mangled)++; - } - } - } - else if (is_pointer) - { - if (!get_count (mangled, &symbol_len)) - { - success = 0; - break; - } - if (symbol_len == 0) - string_appendn (tname, "0", 1); - else - { - char *p = xmalloc (symbol_len + 1), *q; - strncpy (p, *mangled, symbol_len); - p [symbol_len] = '\0'; - q = cplus_demangle (p, work->options); - string_appendn (tname, "&", 1); - if (q) - { - string_append (tname, q); - free (q); - } - else - string_append (tname, p); - free (p); - } - *mangled += symbol_len; - } - } - need_comma = 1; - } - if (tname->p[-1] == '>') - string_append (tname, " "); - string_append (tname, ">"); - -/* - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - } -*/ - return (success); -} - -static int -arm_pt (work, mangled, n, anchor, args) - struct work_stuff *work; - const char *mangled; - int n; - const char **anchor, **args; -{ - /* ARM template? */ - if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__"))) - { - int len; - *args = *anchor + 6; - len = consume_count (args); - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - return 0; -} - -static void -demangle_arm_pt (work, mangled, n, declp) - struct work_stuff *work; - const char **mangled; - int n; - string *declp; -{ - const char *p; - const char *args; - const char *e = *mangled + n; - - /* ARM template? */ - if (arm_pt (work, *mangled, n, &p, &args)) - { - string arg; - string_init (&arg); - string_appendn (declp, *mangled, p - *mangled); - string_append (declp, "<"); - /* should do error checking here */ - while (args < e) { - string_clear (&arg); - do_type (work, &args, &arg); - string_appends (declp, &arg); - string_append (declp, ","); - } - string_delete (&arg); - --declp->p; - string_append (declp, ">"); - } - else - { - string_appendn (declp, *mangled, n); - } - *mangled += n; -} - -static int -demangle_class_name (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int n; - int success = 0; - - n = consume_count (mangled); - if (strlen (*mangled) >= n) - { - demangle_arm_pt (work, mangled, n, declp); - success = 1; - } - - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_class -- demangle a mangled class sequence - -SYNOPSIS - - static int - demangle_class (struct work_stuff *work, const char **mangled, - strint *declp) - -DESCRIPTION - - DECLP points to the buffer into which demangling is being done. - - *MANGLED points to the current token to be demangled. On input, - it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) - On exit, it points to the next token after the mangled class on - success, or the first unconsumed token on failure. - - If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then - we are demangling a constructor or destructor. In this case - we prepend "class::class" or "class::~class" to DECLP. - - Otherwise, we prepend "class::" to the current DECLP. - - Reset the constructor/destructor flags once they have been - "consumed". This allows demangle_class to be called later during - the same demangling, to do normal class demangling. - - Returns 1 if demangling is successful, 0 otherwise. - -*/ - -static int -demangle_class (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 0; - string class_name; - - string_init (&class_name); - if (demangle_class_name (work, mangled, &class_name)) - { - if ((work->constructor & 1) || (work->destructor & 1)) - { - string_prepends (declp, &class_name); - if (work -> destructor & 1) - { - string_prepend (declp, "~"); - work -> destructor -= 1; - } - else - { - work -> constructor -= 1; - } - } - string_prepend (declp, "::"); - string_prepends (declp, &class_name); - success = 1; - } - string_delete (&class_name); - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_prefix -- consume the mangled name prefix and find signature - -SYNOPSIS - - static int - demangle_prefix (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the prefix of the mangled name. - - DECLP points to the string buffer into which demangled output is - placed. On entry, the buffer is empty. On exit it contains - the root function name, the demangled operator name, or in some - special cases either nothing or the completely demangled result. - - MANGLED points to the current pointer into the mangled name. As each - token of the mangled name is consumed, it is updated. Upon entry - the current mangled name pointer points to the first character of - the mangled name. Upon exit, it should point to the first character - of the signature if demangling was successful, or to the first - unconsumed character if demangling of the prefix was unsuccessful. - - Returns 1 on success, 0 otherwise. - */ - -static int -demangle_prefix (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 1; - const char *scan; - int i; - - if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0) - { - char *marker = strchr (cplus_markers, (*mangled)[8]); - if (marker != NULL && *marker == (*mangled)[10]) - { - if ((*mangled)[9] == 'D') - { - /* it's a GNU global destructor to be executed at program exit */ - (*mangled) += 11; - work->destructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - else if ((*mangled)[9] == 'I') - { - /* it's a GNU global constructor to be executed at program init */ - (*mangled) += 11; - work->constructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - } - } - else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0) - { - /* it's a ARM global destructor to be executed at program exit */ - (*mangled) += 7; - work->destructor = 2; - } - else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0) - { - /* it's a ARM global constructor to be executed at program initial */ - (*mangled) += 7; - work->constructor = 2; - } - -/* This block of code is a reduction in strength time optimization - of: - scan = mystrstr (*mangled, "__"); */ - - { - scan = *mangled; - - do { - scan = strchr (scan, '_'); - } while (scan != NULL && *++scan != '_'); - - if (scan != NULL) --scan; - } - - if (scan != NULL) - { - /* We found a sequence of two or more '_', ensure that we start at - the last pair in the sequence. */ - i = strspn (scan, "_"); - if (i > 2) - { - scan += (i - 2); - } - } - - if (scan == NULL) - { - success = 0; - } - else if (work -> static_type) - { - if (!isdigit (scan[0]) && (scan[0] != 't')) - { - success = 0; - } - } - else if ((scan == *mangled) && - (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't'))) - { - /* The ARM says nothing about the mangling of local variables. - But cfront mangles local variables by prepending __ - to them. As an extension to ARM demangling we handle this case. */ - if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2])) - { - *mangled = scan + 2; - consume_count (mangled); - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - else - { - /* A GNU style constructor starts with __[0-9Qt]. But cfront uses - names like __Q2_3foo3bar for nested type names. So don't accept - this style of constructor for cfront demangling. */ - if (!(LUCID_DEMANGLING || ARM_DEMANGLING)) - work -> constructor += 1; - *mangled = scan + 2; - } - } - else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't')) - { - /* Mangled name starts with "__". Skip over any leading '_' characters, - then find the next "__" that separates the prefix from the signature. - */ - if (!(ARM_DEMANGLING || LUCID_DEMANGLING) - || (arm_special (work, mangled, declp) == 0)) - { - while (*scan == '_') - { - scan++; - } - if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) - { - /* No separator (I.E. "__not_mangled"), or empty signature - (I.E. "__not_mangled_either__") */ - success = 0; - } - else - { - demangle_function_name (work, mangled, declp, scan); - } - } - } - else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't') - { - /* Cfront-style parameterized type. Handled later as a signature. */ - success = 1; - - /* ARM template? */ - demangle_arm_pt (work, mangled, strlen (*mangled), declp); - } - else if (*(scan + 2) != '\0') - { - /* Mangled name does not start with "__" but does have one somewhere - in there with non empty stuff after it. Looks like a global - function name. */ - demangle_function_name (work, mangled, declp, scan); - } - else - { - /* Doesn't look like a mangled name */ - success = 0; - } - - if (!success && (work->constructor == 2 || work->destructor == 2)) - { - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - return (success); -} - -/* - -LOCAL FUNCTION - - gnu_special -- special handling of gnu mangled strings - -SYNOPSIS - - static int - gnu_special (struct work_stuff *work, const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special GNU style mangling forms that don't fit - the normal pattern. For example: - - _$_3foo (destructor for class foo) - _vt$foo (foo virtual table) - _vt$foo$bar (foo::bar virtual table) - __vt_foo (foo virtual table, new style with thunks) - _3foo$varname (static data member) - _Q22rs2tu$vw (static data member) - __t6vector1Zii (constructor with template) - __thunk_4__$_7ostream (virtual function thunk) - */ - -static int -gnu_special (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int n; - int success = 1; - const char *p; - - if ((*mangled)[0] == '_' - && strchr (cplus_markers, (*mangled)[1]) != NULL - && (*mangled)[2] == '_') - { - /* Found a GNU style destructor, get past "__" */ - (*mangled) += 3; - work -> destructor += 1; - } - else if ((*mangled)[0] == '_' - && (((*mangled)[1] == '_' - && (*mangled)[2] == 'v' - && (*mangled)[3] == 't' - && (*mangled)[4] == '_') - || ((*mangled)[1] == 'v' - && (*mangled)[2] == 't' - && strchr (cplus_markers, (*mangled)[3]) != NULL))) - { - /* Found a GNU style virtual table, get past "_vt" - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - if ((*mangled)[2] == 'v') - (*mangled) += 5; /* New style, with thunks: "__vt_" */ - else - (*mangled) += 4; /* Old style, no thunks: "_vt" */ - while (**mangled != '\0') - { - p = strpbrk (*mangled, cplus_markers); - switch (**mangled) - { - case 'Q': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0); - break; - default: - if (isdigit(*mangled[0])) - { - n = consume_count(mangled); - } - else - { - n = strcspn (*mangled, cplus_markers); - } - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - - if (success && ((p == NULL) || (p == *mangled))) - { - if (p != NULL) - { - string_append (declp, "::"); - (*mangled)++; - } - } - else - { - success = 0; - break; - } - } - if (success) - string_append (declp, " virtual table"); - } - else if ((*mangled)[0] == '_' - && (strchr("0123456789Qt", (*mangled)[1]) != NULL) - && (p = strpbrk (*mangled, cplus_markers)) != NULL) - { - /* static data member, "_3foo$varname" for example */ - (*mangled)++; - switch (**mangled) - { - case 'Q': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0); - break; - default: - n = consume_count (mangled); - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - if (success && (p == *mangled)) - { - /* Consumed everything up to the cplus_marker, append the - variable name. */ - (*mangled)++; - string_append (declp, "::"); - n = strlen (*mangled); - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - else - { - success = 0; - } - } - else if (strncmp (*mangled, "__thunk_", 8) == 0) - { - int delta = ((*mangled) += 8, consume_count (mangled)); - char *method = cplus_demangle (++*mangled, work->options); - if (method) - { - char buf[50]; - sprintf (buf, "virtual function thunk (delta:%d) for ", -delta); - string_append (declp, buf); - string_append (declp, method); - free (method); - n = strlen (*mangled); - (*mangled) += n; - } - else - { - success = 0; - } - } - else - { - success = 0; - } - return (success); -} - -/* - -LOCAL FUNCTION - - arm_special -- special handling of ARM/lucid mangled strings - -SYNOPSIS - - static int - arm_special (struct work_stuff *work, const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special ARM style mangling forms that don't fit - the normal pattern. For example: - - __vtbl__3foo (foo virtual table) - __vtbl__3foo__3bar (bar::foo virtual table) - - */ - -static int -arm_special (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int n; - int success = 1; - const char *scan; - - if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0) - { - /* Found a ARM style virtual table, get past ARM_VTABLE_STRING - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - scan = *mangled + ARM_VTABLE_STRLEN; - while (*scan != '\0') /* first check it can be demangled */ - { - n = consume_count (&scan); - if (n==0) - { - return (0); /* no good */ - } - scan += n; - if (scan[0] == '_' && scan[1] == '_') - { - scan += 2; - } - } - (*mangled) += ARM_VTABLE_STRLEN; - while (**mangled != '\0') - { - n = consume_count (mangled); - string_prependn (declp, *mangled, n); - (*mangled) += n; - if ((*mangled)[0] == '_' && (*mangled)[1] == '_') - { - string_prepend (declp, "::"); - (*mangled) += 2; - } - } - string_append (declp, " virtual table"); - } - else - { - success = 0; - } - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_qualified -- demangle 'Q' qualified name strings - -SYNOPSIS - - static int - demangle_qualified (struct work_stuff *, const char *mangled, - string *result, int isfuncname, int append); - -DESCRIPTION - - Demangle a qualified name, such as "Q25Outer5Inner" which is - the mangled form of "Outer::Inner". The demangled output is - prepended or appended to the result string according to the - state of the append flag. - - If isfuncname is nonzero, then the qualified name we are building - is going to be used as a member function name, so if it is a - constructor or destructor function, append an appropriate - constructor or destructor name. I.E. for the above example, - the result for use as a constructor is "Outer::Inner::Inner" - and the result for use as a destructor is "Outer::Inner::~Inner". - -BUGS - - Numeric conversion is ASCII dependent (FIXME). - - */ - -static int -demangle_qualified (work, mangled, result, isfuncname, append) - struct work_stuff *work; - const char **mangled; - string *result; - int isfuncname; - int append; -{ - int qualifiers; - int namelength; - int success = 1; - const char *p; - char num[2]; - string temp; - - string_init (&temp); - switch ((*mangled)[1]) - { - case '_': - /* GNU mangled name with more than 9 classes. The count is preceded - by an underscore (to distinguish it from the <= 9 case) and followed - by an underscore. */ - p = *mangled + 2; - qualifiers = atoi (p); - if (!isdigit (*p) || *p == '0') - success = 0; - - /* Skip the digits. */ - while (isdigit (*p)) - ++p; - - if (*p != '_') - success = 0; - - *mangled = p + 1; - break; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* The count is in a single digit. */ - num[0] = (*mangled)[1]; - num[1] = '\0'; - qualifiers = atoi (num); - - /* If there is an underscore after the digit, skip it. This is - said to be for ARM-qualified names, but the ARM makes no - mention of such an underscore. Perhaps cfront uses one. */ - if ((*mangled)[2] == '_') - { - (*mangled)++; - } - (*mangled) += 2; - break; - - case '0': - default: - success = 0; - } - - if (!success) - return success; - - /* Pick off the names and collect them in the temp buffer in the order - in which they are found, separated by '::'. */ - - while (qualifiers-- > 0) - { - if (*mangled[0] == '_') - *mangled = *mangled + 1; - if (*mangled[0] == 't') - { - success = demangle_template(work, mangled, &temp, 0); - if (!success) break; - } - else - { - namelength = consume_count (mangled); - if (strlen (*mangled) < namelength) - { - /* Simple sanity check failed */ - success = 0; - break; - } - string_appendn (&temp, *mangled, namelength); - *mangled += namelength; - } - if (qualifiers > 0) - { - string_appendn (&temp, "::", 2); - } - } - - /* If we are using the result as a function name, we need to append - the appropriate '::' separated constructor or destructor name. - We do this here because this is the most convenient place, where - we already have a pointer to the name and the length of the name. */ - - if (isfuncname && (work->constructor & 1 || work->destructor & 1)) - { - string_appendn (&temp, "::", 2); - if (work -> destructor & 1) - { - string_append (&temp, "~"); - } - string_appendn (&temp, (*mangled) - namelength, namelength); - } - - /* Now either prepend the temp buffer to the result, or append it, - depending upon the state of the append flag. */ - - if (append) - { - string_appends (result, &temp); - } - else - { - if (!STRING_EMPTY (result)) - { - string_appendn (&temp, "::", 2); - } - string_prepends (result, &temp); - } - - string_delete (&temp); - return (success); -} - -/* - -LOCAL FUNCTION - - get_count -- convert an ascii count to integer, consuming tokens - -SYNOPSIS - - static int - get_count (const char **type, int *count) - -DESCRIPTION - - Return 0 if no conversion is performed, 1 if a string is converted. -*/ - -static int -get_count (type, count) - const char **type; - int *count; -{ - const char *p; - int n; - - if (!isdigit (**type)) - { - return (0); - } - else - { - *count = **type - '0'; - (*type)++; - if (isdigit (**type)) - { - p = *type; - n = *count; - do - { - n *= 10; - n += *p - '0'; - p++; - } - while (isdigit (*p)); - if (*p == '_') - { - *type = p + 1; - *count = n; - } - } - } - return (1); -} - -/* result will be initialised here; it will be freed on failure */ - -static int -do_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int n; - int done; - int success; - string decl; - const char *remembered_type; - int constp; - int volatilep; - - string_init (&decl); - string_init (result); - - done = 0; - success = 1; - while (success && !done) - { - int member; - switch (**mangled) - { - - /* A pointer type */ - case 'P': - case 'p': - (*mangled)++; - string_prepend (&decl, "*"); - break; - - /* A reference type */ - case 'R': - (*mangled)++; - string_prepend (&decl, "&"); - break; - - /* An array */ - case 'A': - { - const char *p = ++(*mangled); - - string_prepend (&decl, "("); - string_append (&decl, ")["); - /* Copy anything up until the next underscore (the size of the - array). */ - while (**mangled && **mangled != '_') - ++(*mangled); - if (**mangled == '_') - { - string_appendn (&decl, p, *mangled - p); - string_append (&decl, "]"); - *mangled += 1; - } - else - success = 0; - break; - } - - /* A back reference to a previously seen type */ - case 'T': - (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> ntypes) - { - success = 0; - } - else - { - remembered_type = work -> typevec[n]; - mangled = &remembered_type; - } - break; - - /* A function */ - case 'F': - (*mangled)++; - if (!STRING_EMPTY (&decl) && decl.b[0] == '*') - { - string_prepend (&decl, "("); - string_append (&decl, ")"); - } - /* After picking off the function args, we expect to either find the - function return type (preceded by an '_') or the end of the - string. */ - if (!demangle_args (work, mangled, &decl) - || (**mangled != '_' && **mangled != '\0')) - { - success = 0; - } - if (success && (**mangled == '_')) - { - (*mangled)++; - } - break; - - case 'M': - case 'O': - { - constp = 0; - volatilep = 0; - - member = **mangled == 'M'; - (*mangled)++; - if (!isdigit (**mangled)) - { - success = 0; - break; - } - n = consume_count (mangled); - if (strlen (*mangled) < n) - { - success = 0; - break; - } - string_append (&decl, ")"); - string_prepend (&decl, "::"); - string_prependn (&decl, *mangled, n); - string_prepend (&decl, "("); - *mangled += n; - if (member) - { - if (**mangled == 'C') - { - (*mangled)++; - constp = 1; - } - if (**mangled == 'V') - { - (*mangled)++; - volatilep = 1; - } - if (*(*mangled)++ != 'F') - { - success = 0; - break; - } - } - if ((member && !demangle_args (work, mangled, &decl)) - || **mangled != '_') - { - success = 0; - break; - } - (*mangled)++; - if (! PRINT_ANSI_QUALIFIERS) - { - break; - } - if (constp) - { - APPEND_BLANK (&decl); - string_append (&decl, "const"); - } - if (volatilep) - { - APPEND_BLANK (&decl); - string_append (&decl, "volatile"); - } - break; - } - case 'G': - (*mangled)++; - break; - - case 'C': - (*mangled)++; -/* - if ((*mangled)[1] == 'P') - { -*/ - if (PRINT_ANSI_QUALIFIERS) - { - if (!STRING_EMPTY (&decl)) - { - string_prepend (&decl, " "); - } - string_prepend (&decl, "const"); - } - break; -/* - } -*/ - - /* fall through */ - default: - done = 1; - break; - } - } - - switch (**mangled) - { - /* A qualified name, such as "Outer::Inner". */ - case 'Q': - success = demangle_qualified (work, mangled, result, 0, 1); - break; - - default: - success = demangle_fund_type (work, mangled, result); - break; - } - - if (success) - { - if (!STRING_EMPTY (&decl)) - { - string_append (result, " "); - string_appends (result, &decl); - } - } - else - { - string_delete (result); - } - string_delete (&decl); - return (success); -} - -/* Given a pointer to a type string that represents a fundamental type - argument (int, long, unsigned int, etc) in TYPE, a pointer to the - string in which the demangled output is being built in RESULT, and - the WORK structure, decode the types and add them to the result. - - For example: - - "Ci" => "const int" - "Sl" => "signed long" - "CUs" => "const unsigned short" - - */ - -static int -demangle_fund_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int done = 0; - int success = 1; - - /* First pick off any type qualifiers. There can be more than one. */ - - while (!done) - { - switch (**mangled) - { - case 'C': - (*mangled)++; - if (PRINT_ANSI_QUALIFIERS) - { - APPEND_BLANK (result); - string_append (result, "const"); - } - break; - case 'U': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "unsigned"); - break; - case 'S': /* signed char only */ - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "signed"); - break; - case 'V': - (*mangled)++; - if (PRINT_ANSI_QUALIFIERS) - { - APPEND_BLANK (result); - string_append (result, "volatile"); - } - break; - default: - done = 1; - break; - } - } - - /* Now pick off the fundamental type. There can be only one. */ - - switch (**mangled) - { - case '\0': - case '_': - break; - case 'v': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "void"); - break; - case 'x': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long long"); - break; - case 'l': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long"); - break; - case 'i': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "int"); - break; - case 's': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "short"); - break; - case 'b': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "bool"); - break; - case 'c': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "char"); - break; - case 'w': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "wchar_t"); - break; - case 'r': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long double"); - break; - case 'd': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "double"); - break; - case 'f': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "float"); - break; - case 'G': - (*mangled)++; - if (!isdigit (**mangled)) - { - success = 0; - break; - } - /* fall through */ - /* An explicit type, such as "6mytype" or "7integer" */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - APPEND_BLANK (result); - if (!demangle_class_name (work, mangled, result)) { - --result->p; - success = 0; - } - break; - case 't': - success = demangle_template(work,mangled, result, 0); - break; - default: - success = 0; - break; - } - - return (success); -} - -/* `result' will be initialized in do_type; it will be freed on failure */ - -static int -do_arg (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - const char *start = *mangled; - - if (!do_type (work, mangled, result)) - { - return (0); - } - else - { - remember_type (work, start, *mangled - start); - return (1); - } -} - -static void -remember_type (work, start, len) - struct work_stuff *work; - const char *start; - int len; -{ - char *tem; - - if (work -> ntypes >= work -> typevec_size) - { - if (work -> typevec_size == 0) - { - work -> typevec_size = 3; - work -> typevec = - (char **) xmalloc (sizeof (char *) * work -> typevec_size); - } - else - { - work -> typevec_size *= 2; - work -> typevec = - (char **) xrealloc ((char *)work -> typevec, - sizeof (char *) * work -> typevec_size); - } - } - tem = xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> typevec[work -> ntypes++] = tem; -} - -/* Forget the remembered types, but not the type vector itself. */ - -static void -forget_types (work) - struct work_stuff *work; -{ - int i; - - while (work -> ntypes > 0) - { - i = --(work -> ntypes); - if (work -> typevec[i] != NULL) - { - free (work -> typevec[i]); - work -> typevec[i] = NULL; - } - } -} - -/* Process the argument list part of the signature, after any class spec - has been consumed, as well as the first 'F' character (if any). For - example: - - "__als__3fooRT0" => process "RT0" - "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" - - DECLP must be already initialised, usually non-empty. It won't be freed - on failure. - - Note that g++ differs significantly from ARM and lucid style mangling - with regards to references to previously seen types. For example, given - the source fragment: - - class foo { - public: - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); - }; - - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - - g++ produces the names: - - __3fooiRT0iT2iT2 - foo__FiR3fooiT1iT1 - - while lcc (and presumably other ARM style compilers as well) produces: - - foo__FiR3fooT1T2T1T2 - __ct__3fooFiR3fooT1T2T1T2 - - Note that g++ bases it's type numbers starting at zero and counts all - previously seen types, while lucid/ARM bases it's type numbers starting - at one and only considers types after it has seen the 'F' character - indicating the start of the function args. For lucid/ARM style, we - account for this difference by discarding any previously seen types when - we see the 'F' character, and subtracting one from the type number - reference. - - */ - -static int -demangle_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - string arg; - int need_comma = 0; - int r; - int t; - const char *tem; - char temptype; - - if (PRINT_ARG_TYPES) - { - string_append (declp, "("); - if (**mangled == '\0') - { - string_append (declp, "void"); - } - } - - while (**mangled != '_' && **mangled != '\0' && **mangled != 'e') - { - if ((**mangled == 'N') || (**mangled == 'T')) - { - temptype = *(*mangled)++; - - if (temptype == 'N') - { - if (!get_count (mangled, &r)) - { - return (0); - } - } - else - { - r = 1; - } - if (ARM_DEMANGLING && work -> ntypes >= 10) - { - /* If we have 10 or more types we might have more than a 1 digit - index so we'll have to consume the whole count here. This - will lose if the next thing is a type name preceded by a - count but it's impossible to demangle that case properly - anyway. Eg if we already have 12 types is T12Pc "(..., type1, - Pc, ...)" or "(..., type12, char *, ...)" */ - if ((t = consume_count(mangled)) == 0) - { - return (0); - } - } - else - { - if (!get_count (mangled, &t)) - { - return (0); - } - } - if (LUCID_DEMANGLING || ARM_DEMANGLING) - { - t--; - } - /* Validate the type index. Protect against illegal indices from - malformed type strings. */ - if ((t < 0) || (t >= work -> ntypes)) - { - return (0); - } - while (--r >= 0) - { - tem = work -> typevec[t]; - if (need_comma && PRINT_ARG_TYPES) - { - string_append (declp, ", "); - } - if (!do_arg (work, &tem, &arg)) - { - return (0); - } - if (PRINT_ARG_TYPES) - { - string_appends (declp, &arg); - } - string_delete (&arg); - need_comma = 1; - } - } - else - { - if (need_comma & PRINT_ARG_TYPES) - { - string_append (declp, ", "); - } - if (!do_arg (work, mangled, &arg)) - { - return (0); - } - if (PRINT_ARG_TYPES) - { - string_appends (declp, &arg); - } - string_delete (&arg); - need_comma = 1; - } - } - - if (**mangled == 'e') - { - (*mangled)++; - if (PRINT_ARG_TYPES) - { - if (need_comma) - { - string_append (declp, ","); - } - string_append (declp, "..."); - } - } - - if (PRINT_ARG_TYPES) - { - string_append (declp, ")"); - } - return (1); -} - -static void -demangle_function_name (work, mangled, declp, scan) - struct work_stuff *work; - const char **mangled; - string *declp; - const char *scan; -{ - int i; - int len; - string type; - const char *tem; - - string_appendn (declp, (*mangled), scan - (*mangled)); - string_need (declp, 1); - *(declp -> p) = '\0'; - - /* Consume the function name, including the "__" separating the name - from the signature. We are guaranteed that SCAN points to the - separator. */ - - (*mangled) = scan + 2; - - if (LUCID_DEMANGLING || ARM_DEMANGLING) - { - - /* See if we have an ARM style constructor or destructor operator. - If so, then just record it, clear the decl, and return. - We can't build the actual constructor/destructor decl until later, - when we recover the class name from the signature. */ - - if (strcmp (declp -> b, "__ct") == 0) - { - work -> constructor += 1; - string_clear (declp); - return; - } - else if (strcmp (declp -> b, "__dt") == 0) - { - work -> destructor += 1; - string_clear (declp); - return; - } - } - - if (declp->p - declp->b >= 3 - && declp->b[0] == 'o' - && declp->b[1] == 'p' - && strchr (cplus_markers, declp->b[2]) != NULL) - { - /* see if it's an assignment expression */ - if (declp->p - declp->b >= 10 /* op$assign_ */ - && memcmp (declp->b + 3, "assign_", 7) == 0) - { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - len = declp->p - declp->b - 10; - if (strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 10, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - string_append (declp, "="); - break; - } - } - } - else - { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - int len = declp->p - declp->b - 3; - if (strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 3, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0 - && strchr (cplus_markers, declp->b[4]) != NULL) - { - /* type conversion operator */ - tem = declp->b + 5; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && declp->b[2] == 'o' && declp->b[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = declp->b + 4; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && declp->b[2] >= 'a' && declp->b[2] <= 'z' - && declp->b[3] >= 'a' && declp->b[3] <= 'z') - { - if (declp->b[4] == '\0') - { - /* Operator. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, declp->b + 2, 2) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - else - { - if (declp->b[2] == 'a' && declp->b[5] == '\0') - { - /* Assignment. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, declp->b + 2, 3) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - } -} - -/* a mini string-handling package */ - -static void -string_need (s, n) - string *s; - int n; -{ - int tem; - - if (s->b == NULL) - { - if (n < 32) - { - n = 32; - } - s->p = s->b = xmalloc (n); - s->e = s->b + n; - } - else if (s->e - s->p < n) - { - tem = s->p - s->b; - n += tem; - n *= 2; - s->b = xrealloc (s->b, n); - s->p = s->b + tem; - s->e = s->b + n; - } -} - -static void -string_delete (s) - string *s; -{ - if (s->b != NULL) - { - free (s->b); - s->b = s->e = s->p = NULL; - } -} - -static void -string_init (s) - string *s; -{ - s->b = s->p = s->e = NULL; -} - -static void -string_clear (s) - string *s; -{ - s->p = s->b; -} - -#if 0 - -static int -string_empty (s) - string *s; -{ - return (s->b == s->p); -} - -#endif - -static void -string_append (p, s) - string *p; - const char *s; -{ - int n; - if (s == NULL || *s == '\0') - return; - n = strlen (s); - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; -} - -static void -string_appends (p, s) - string *p, *s; -{ - int n; - - if (s->b != s->p) - { - n = s->p - s->b; - string_need (p, n); - memcpy (p->p, s->b, n); - p->p += n; - } -} - -static void -string_appendn (p, s, n) - string *p; - const char *s; - int n; -{ - if (n != 0) - { - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; - } -} - -static void -string_prepend (p, s) - string *p; - const char *s; -{ - if (s != NULL && *s != '\0') - { - string_prependn (p, s, strlen (s)); - } -} - -static void -string_prepends (p, s) - string *p, *s; -{ - if (s->b != s->p) - { - string_prependn (p, s->b, s->p - s->b); - } -} - -static void -string_prependn (p, s, n) - string *p; - const char *s; - int n; -{ - char *q; - - if (n != 0) - { - string_need (p, n); - for (q = p->p - 1; q >= p->b; q--) - { - q[n] = q[0]; - } - memcpy (p->b, s, n); - p->p += n; - } -} - -/* To generate a standalone demangler program for testing purposes, - just compile and link this file with -DMAIN and libiberty.a. When - run, it demangles each command line arg, or each stdin string, and - prints the result on stdout. */ - -#ifdef MAIN - -static void -demangle_it (mangled_name) - char *mangled_name; -{ - char *result; - - result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI); - if (result == NULL) - { - printf ("%s\n", mangled_name); - } - else - { - printf ("%s\n", result); - free (result); - } -} - -#include "getopt.h" - -static char *program_name; -static char *program_version = VERSION; - -static void -usage (stream, status) - FILE *stream; - int status; -{ - fprintf (stream, "\ -Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\ - [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\ - [--help] [--version] [arg...]\n", - program_name); - exit (status); -} - -#define MBUF_SIZE 512 -char mbuffer[MBUF_SIZE]; - -/* Defined in the automatically-generated underscore.c. */ -extern int prepends_underscore; - -int strip_underscore = 0; - -static struct option long_options[] = { - {"strip-underscores", no_argument, 0, '_'}, - {"format", required_argument, 0, 's'}, - {"help", no_argument, 0, 'h'}, - {"no-strip-underscores", no_argument, 0, 'n'}, - {"version", no_argument, 0, 'v'}, - {0, no_argument, 0, 0} -}; - -int -main (argc, argv) - int argc; - char **argv; -{ - char *result; - int c; - - program_name = argv[0]; - - strip_underscore = prepends_underscore; - - while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF) - { - switch (c) - { - case '?': - usage (stderr, 1); - break; - case 'h': - usage (stdout, 0); - case 'n': - strip_underscore = 0; - break; - case 'v': - printf ("GNU %s version %s\n", program_name, program_version); - exit (0); - case '_': - strip_underscore = 1; - break; - case 's': - if (strcmp (optarg, "gnu") == 0) - { - current_demangling_style = gnu_demangling; - } - else if (strcmp (optarg, "lucid") == 0) - { - current_demangling_style = lucid_demangling; - } - else if (strcmp (optarg, "arm") == 0) - { - current_demangling_style = arm_demangling; - } - else - { - fprintf (stderr, "%s: unknown demangling style `%s'\n", - program_name, optarg); - exit (1); - } - break; - } - } - - if (optind < argc) - { - for ( ; optind < argc; optind++) - { - demangle_it (argv[optind]); - } - } - else - { - for (;;) - { - int i = 0; - c = getchar (); - /* Try to read a label. */ - while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.')) - { - if (i >= MBUF_SIZE-1) - break; - mbuffer[i++] = c; - c = getchar (); - } - if (i > 0) - { - int skip_first = 0; - - if (mbuffer[0] == '.') - ++skip_first; - if (strip_underscore && mbuffer[skip_first] == '_') - ++skip_first; - - if (skip_first > i) - skip_first = i; - - mbuffer[i] = 0; - - result = cplus_demangle (mbuffer + skip_first, - DMGL_PARAMS | DMGL_ANSI); - if (result) - { - if (mbuffer[0] == '.') - putc ('.', stdout); - fputs (result, stdout); - free (result); - } - else - fputs (mbuffer, stdout); - - fflush (stdout); - } - if (c == EOF) - break; - putchar (c); - } - } - - exit (0); -} - -static void -fatal (str) - char *str; -{ - fprintf (stderr, "%s: %s\n", program_name, str); - exit (1); -} - -char * malloc (); -char * realloc (); - -char * -xmalloc (size) - unsigned size; -{ - register char *value = (char *) malloc (size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - register char *value = (char *) realloc (ptr, size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} -#endif /* main */ diff --git a/contrib/gdb/libiberty/dummy.c b/contrib/gdb/libiberty/dummy.c deleted file mode 100644 index 08da647e30e..00000000000 --- a/contrib/gdb/libiberty/dummy.c +++ /dev/null @@ -1,49 +0,0 @@ -#include - -#ifdef __STDC__ -#include -#define clock_t unsigned long -#define DEF(NAME, RETURN_TYPE, ARGLIST, ARGS) extern RETURN_TYPE NAME (ARGS); -#define DEFFUNC(NAME, RETURN_TYPE, ARGLIST, ARGS) extern RETURN_TYPE NAME (ARGS); -#else -#define void int -#define size_t unsigned long -#define clock_t unsigned long -#define DEF(NAME, RETURN_TYPE, ARGLIST, ARGS) extern RETURN_TYPE NAME (); -#define DEFFUNC(NAME, RETURN_TYPE, ARGLIST, ARGS) extern RETURN_TYPE NAME (); -#endif - -#define DEFVAR(NAME,DECL,USE) extern DECL; - -#define NOTHING /*nothing*/ - -#include "alloca-conf.h" -#include "functions.def" - -/* Always use our: getopt.o getopt1.o obstack.o spaces.o */ - -int -main (argc, argv) - int argc; char **argv; -{ - -/* Create a dummy function call for each DEF-defined function. */ - -#undef DEF -#undef DEFVAR -#undef DEFFUNC -#undef AND -#define AND = 0; -/* ARGS expands into a set of declaration. NAME ARG_LIST expands - info a function call that uses those variables as actual parameters. - If the function has been DEF'ed correctly, we can pass the right - number and types of parameters, which is nice. (E.g. gcc may - otherwise complain about the wrong number of parameters to certain - builtins.) */ -#define DEF(NAME, RETURN_TYPE, ARG_LIST, ARGS) { ARGS; NAME ARG_LIST; } -#define DEFVAR(NAME, DECL, USE) { USE; } -#define DEFFUNC(NAME, RETURN_TYPE, ARG_LIST, ARGS) { ARGS; NAME ARG_LIST; } -#include "functions.def" - - return (0); -} diff --git a/contrib/gdb/libiberty/fdmatch.c b/contrib/gdb/libiberty/fdmatch.c deleted file mode 100644 index 7af039f5a2b..00000000000 --- a/contrib/gdb/libiberty/fdmatch.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Compare two open file descriptors to see if they refer to the same file. - Copyright (C) 1991 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* - -NAME - - fdmatch -- see if two file descriptors refer to same file - -SYNOPSIS - - int fdmatch (int fd1, int fd2) - -DESCRIPTION - - Check to see if two open file descriptors refer to the same file. - This is useful, for example, when we have an open file descriptor - for an unnamed file, and the name of a file that we believe to - correspond to that fd. This can happen when we are exec'd with - an already open file (stdout for example) or from the SVR4 /proc - calls that return open file descriptors for mapped address spaces. - All we have to do is open the file by name and check the two file - descriptors for a match, which is done by comparing major&minor - device numbers and inode numbers. - -BUGS - - (FIXME: does this work for networks?) - It works for NFS, which assigns a device number to each mount. - -*/ - -#include "ansidecl.h" -#include "libiberty.h" -#include -#include - -int fdmatch (fd1, fd2) - int fd1; - int fd2; -{ - struct stat sbuf1; - struct stat sbuf2; - - if ((fstat (fd1, &sbuf1) == 0) && - (fstat (fd2, &sbuf2) == 0) && - (sbuf1.st_dev == sbuf2.st_dev) && - (sbuf1.st_ino == sbuf2.st_ino)) - { - return (1); - } - else - { - return (0); - } -} diff --git a/contrib/gdb/libiberty/floatformat.c b/contrib/gdb/libiberty/floatformat.c deleted file mode 100644 index 655f4ea9264..00000000000 --- a/contrib/gdb/libiberty/floatformat.c +++ /dev/null @@ -1,385 +0,0 @@ -/* IEEE floating point support routines, for GDB, the GNU Debugger. - Copyright (C) 1991, 1994 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "floatformat.h" -#include /* ldexp */ -#ifdef __STDC__ -#include -extern void *memcpy (void *s1, const void *s2, size_t n); -extern void *memset (void *s, int c, size_t n); -#else -extern char *memcpy (); -extern char *memset (); -#endif - -/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not - going to bother with trying to muck around with whether it is defined in - a system header, what we do if not, etc. */ -#define FLOATFORMAT_CHAR_BIT 8 - -/* floatformats for IEEE single and double, big and little endian. */ -const struct floatformat floatformat_ieee_single_big = -{ - floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, floatformat_intbit_no -}; -const struct floatformat floatformat_ieee_single_little = -{ - floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23, floatformat_intbit_no -}; -const struct floatformat floatformat_ieee_double_big = -{ - floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no -}; -const struct floatformat floatformat_ieee_double_little = -{ - floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no -}; - -const struct floatformat floatformat_i387_ext = -{ - floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, - floatformat_intbit_yes -}; -const struct floatformat floatformat_m68881_ext = -{ - /* Note that the bits from 16 to 31 are unused. */ - floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64, floatformat_intbit_yes -}; -const struct floatformat floatformat_i960_ext = -{ - /* Note that the bits from 0 to 15 are unused. */ - floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64, - floatformat_intbit_yes -}; -const struct floatformat floatformat_m88110_ext = -{ -#ifdef HARRIS_FLOAT_FORMAT - /* Harris uses raw format 128 bytes long, but the number is just an ieee - double, and the last 64 bits are wasted. */ - floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52, - floatformat_intbit_no -#else - floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, - floatformat_intbit_yes -#endif /* HARRIS_FLOAT_FORMAT */ -}; -const struct floatformat floatformat_arm_ext = -{ - /* Bits 1 to 16 are unused. */ - floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, - floatformat_intbit_yes -}; - -static unsigned long get_field PARAMS ((unsigned char *, - enum floatformat_byteorders, - unsigned int, - unsigned int, - unsigned int)); - -/* Extract a field which starts at START and is LEN bytes long. DATA and - TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ -static unsigned long -get_field (data, order, total_len, start, len) - unsigned char *data; - enum floatformat_byteorders order; - unsigned int total_len; - unsigned int start; - unsigned int len; -{ - unsigned long result; - unsigned int cur_byte; - int cur_bitshift; - - /* Start at the least significant part of the field. */ - cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1; - cur_bitshift = - ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; - result = *(data + cur_byte) >> (-cur_bitshift); - cur_bitshift += FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - ++cur_byte; - else - --cur_byte; - - /* Move towards the most significant part of the field. */ - while (cur_bitshift < len) - { - if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT) - /* This is the last byte; zero out the bits which are not part of - this field. */ - result |= - (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1)) - << cur_bitshift; - else - result |= *(data + cur_byte) << cur_bitshift; - cur_bitshift += FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - ++cur_byte; - else - --cur_byte; - } - return result; -} - -/* Convert from FMT to a double. - FROM is the address of the extended float. - Store the double in *TO. */ - -void -floatformat_to_double (fmt, from, to) - const struct floatformat *fmt; - char *from; - double *to; -{ - unsigned char *ufrom = (unsigned char *)from; - double dto; - long exponent; - unsigned long mant; - unsigned int mant_bits, mant_off; - int mant_bits_left; - - exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, - fmt->exp_start, fmt->exp_len); - /* Note that if exponent indicates a NaN, we can't really do anything useful - (not knowing if the host has NaN's, or how to build one). So it will - end up as an infinity or something close; that is OK. */ - - mant_bits_left = fmt->man_len; - mant_off = fmt->man_start; - dto = 0.0; - exponent -= fmt->exp_bias; - - /* Build the result algebraically. Might go infinite, underflow, etc; - who cares. */ - while (mant_bits_left > 0) - { - int exp_bits; - exp_bits = mant_bits_left < 32 ? mant_bits_left : 32; - if (mant_bits_left == fmt->man_len - && exp_bits == 32 - && fmt->intbit == floatformat_intbit_no) - { - /* If there is no integer bit, we need to get only 31 bits - so we have room for an integer bit that we create. */ - mant_bits = 31; - } - else - mant_bits = exp_bits; - - mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, - mant_off, mant_bits); - if (mant_bits_left == fmt->man_len) - mant |= 0x80000000; - dto += ldexp ((double)mant, exponent - (exp_bits - 1)); - exponent -= exp_bits; - mant_off += mant_bits; - mant_bits_left -= mant_bits; - } - - /* Negate it if negative. */ - if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) - dto = -dto; - memcpy (to, &dto, sizeof (dto)); -} - -static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders, - unsigned int, - unsigned int, - unsigned int, - unsigned long)); - -/* Set a field which starts at START and is LEN bytes long. DATA and - TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ -static void -put_field (data, order, total_len, start, len, stuff_to_put) - unsigned char *data; - enum floatformat_byteorders order; - unsigned int total_len; - unsigned int start; - unsigned int len; - unsigned long stuff_to_put; -{ - unsigned int cur_byte; - int cur_bitshift; - - /* Start at the least significant part of the field. */ - cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1; - cur_bitshift = - ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; - *(data + cur_byte) &= - ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift)); - *(data + cur_byte) |= - (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift); - cur_bitshift += FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - ++cur_byte; - else - --cur_byte; - - /* Move towards the most significant part of the field. */ - while (cur_bitshift < len) - { - if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT) - { - /* This is the last byte. */ - *(data + cur_byte) &= - ~((1 << (len - cur_bitshift)) - 1); - *(data + cur_byte) |= (stuff_to_put >> cur_bitshift); - } - else - *(data + cur_byte) = ((stuff_to_put >> cur_bitshift) - & ((1 << FLOATFORMAT_CHAR_BIT) - 1)); - cur_bitshift += FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - ++cur_byte; - else - --cur_byte; - } -} - -/* The converse: convert the double *FROM to an extended float - and store where TO points. Neither FROM nor TO have any alignment - restrictions. */ - -void -floatformat_from_double (fmt, from, to) - CONST struct floatformat *fmt; - double *from; - char *to; -{ - double dfrom; - int exponent; - double mant; - unsigned int mant_bits, mant_off; - int mant_bits_left; - unsigned char *uto = (unsigned char *)to; - - memcpy (&dfrom, from, sizeof (dfrom)); - memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT); - if (dfrom == 0) - return; /* Result is zero */ - if (dfrom != dfrom) - { - /* From is NaN */ - put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, - fmt->exp_len, fmt->exp_nan); - /* Be sure it's not infinity, but NaN value is irrel */ - put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start, - 32, 1); - return; - } - - /* If negative, set the sign bit. */ - if (dfrom < 0) - { - put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1); - dfrom = -dfrom; - } - - /* How to tell an infinity from an ordinary number? FIXME-someday */ - - mant = frexp (dfrom, &exponent); - put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len, - exponent + fmt->exp_bias - 1); - - mant_bits_left = fmt->man_len; - mant_off = fmt->man_start; - while (mant_bits_left > 0) - { - unsigned long mant_long; - mant_bits = mant_bits_left < 32 ? mant_bits_left : 32; - - mant *= 4294967296.0; - mant_long = (unsigned long)mant; - mant -= mant_long; - - /* If the integer bit is implicit, then we need to discard it. - If we are discarding a zero, we should be (but are not) creating - a denormalized number which means adjusting the exponent - (I think). */ - if (mant_bits_left == fmt->man_len - && fmt->intbit == floatformat_intbit_no) - { - mant_long &= 0x7fffffff; - mant_bits -= 1; - } - else if (mant_bits < 32) - { - /* The bits we want are in the most significant MANT_BITS bits of - mant_long. Move them to the least significant. */ - mant_long >>= 32 - mant_bits; - } - - put_field (uto, fmt->byteorder, fmt->totalsize, - mant_off, mant_bits, mant_long); - mant_off += mant_bits; - mant_bits_left -= mant_bits; - } -} - - -#ifdef IEEE_DEBUG - -/* This is to be run on a host which uses IEEE floating point. */ - -void -ieee_test (n) - double n; -{ - double result; - char exten[16]; - - floatformat_to_double (&floatformat_ieee_double_big, &n, &result); - if (n != result) - printf ("Differ(to): %.20g -> %.20g\n", n, result); - floatformat_from_double (&floatformat_ieee_double_big, &n, &result); - if (n != result) - printf ("Differ(from): %.20g -> %.20g\n", n, result); - - floatformat_from_double (&floatformat_m68881_ext, &n, exten); - floatformat_to_double (&floatformat_m68881_ext, exten, &result); - if (n != result) - printf ("Differ(to+from): %.20g -> %.20g\n", n, result); - -#if IEEE_DEBUG > 1 - /* This is to be run on a host which uses 68881 format. */ - { - long double ex = *(long double *)exten; - if (ex != n) - printf ("Differ(from vs. extended): %.20g\n", n); - } -#endif -} - -int -main () -{ - ieee_test (0.5); - ieee_test (256.0); - ieee_test (0.12345); - ieee_test (234235.78907234); - ieee_test (-512.0); - ieee_test (-0.004321); - return 0; -} -#endif diff --git a/contrib/gdb/libiberty/functions.def b/contrib/gdb/libiberty/functions.def deleted file mode 100644 index 8becc89fc64..00000000000 --- a/contrib/gdb/libiberty/functions.def +++ /dev/null @@ -1,67 +0,0 @@ -/* - * List of function definitions that may *optionally* be included - * in libiberty.a. The function names must match the filenames, - * e.g. bzero() is defined in bzero.c. (While each file can contain - * extra functions, do not list them.) - * - * In the default libiberty configuration, these object files - * (e.g bzero.o) are included if and only if cc fails to find - * the corresponding function in libc. - */ - -DEF(atexit, int, (f), void (*f)()) -DEF(bcmp, int, (s1, s2, length), char *s1 AND char *s2 AND int length ) -DEF(bcopy, void, (s1, s2, length), char *s1 AND char *s2 AND int length ) -DEF(bzero, void, (s, length), char *s AND int length) -DEF(clock, clock_t, (), NOTHING) -DEF(getopt, int, (argc, argv, optstring), - int argc AND char **argv AND CONST char *optstring) -DEF(getpagesize, int , (), NOTHING) -DEF(getcwd, char*, (buf, len), char *buf AND int len) -DEF(index, char*, (s, c), char *s AND int c) -DEF(insque, void, (), NOTHING) -DEF(memchr, PTR, (s, c, length), CONST PTR s AND int c AND size_t length) -DEF(memcmp, int, (s1, s2, length), - CONST PTR s1 AND CONST PTR s2 AND size_t length) -DEF(memcpy, PTR, (s1, s2, length), PTR s1 AND CONST PTR s2 AND size_t length) -DEF(memmove, PTR, (s1, s2, length), PTR s1 AND CONST PTR s2 AND size_t length) -DEF(memset, PTR, (s, val, length), PTR s AND int val AND size_t length ) -DEF(random, long int, (), NOTHING) -DEF(rename, int, (f, t), char *f AND char *t) -DEF(rindex, char*, (s, c), char *s AND int c) -DEF(strcasecmp, int, (s1, s2), char *s1 AND char *s2) -DEF(strncasecmp, int, (s1, s2, n), char *s1 AND char *s2 AND int n) -DEF(strchr, char*, (s, c), CONST char *s AND int c) -DEF(strdup, char*, (s1), char * s1) -DEF(strrchr, char*, (s, c), CONST char *s AND int c) -DEF(strstr, char*, (), NOTHING) -DEF(strtod, double, (), NOTHING) -DEF(strtol, long, (), NOTHING) -DEF(strtoul, unsigned long, (), NOTHING) -DEF(tmpnam, char *, (s), char * s) -DEF(vfork, int, (), NOTHING) -DEF(vfprintf, int, (), NOTHING) -DEF(vprintf, int, (), NOTHING) -DEF(vsprintf, int, (), NOTHING) -DEF(sigsetmask, int, (), NOTHING) -DEF(alloca, PTR, (size), size_t size) -DEF(waitpid, int, (pid, statp, opts), int pid AND int* statp AND int opts ) - -/* List of global variables that we want to look for in the host - environment, and to generate an entry NEED_ in config.h - if they are not found. The first arg is the variable name, the - second arg is how to declare the variable, and the third is how to - use it. */ - -DEFVAR(sys_nerr, int sys_nerr, sys_nerr = 0) -DEFVAR(sys_errlist, char *sys_errlist[], sys_errlist[0] = 0) -DEFVAR(sys_siglist, char *sys_siglist[], sys_siglist[0] = 0) - -/* List of global functions that we want to look for in the host - environment, and to generate an entry NEED_ in config.h - if they are not found. */ - -DEFFUNC(strerror, char*, (), NOTHING) -DEFFUNC(psignal, void, (signo, message), unsigned signo AND char *message) -DEFFUNC(basename, char *, (name), CONST char *name) -DEFFUNC(on_exit, void, (f, arg), void (*f)() AND char *arg) diff --git a/contrib/gdb/libiberty/getcwd.c b/contrib/gdb/libiberty/getcwd.c deleted file mode 100644 index 60c1dd84eed..00000000000 --- a/contrib/gdb/libiberty/getcwd.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Emulate getcwd using getwd. - This function is in the public domain. */ - -/* -NAME - getcwd -- get absolute pathname for current working directory - -SYNOPSIS - char *getcwd (char pathname[len], len) - -DESCRIPTION - Copy the absolute pathname for the current working directory into - the supplied buffer and return a pointer to the buffer. If the - current directory's path doesn't fit in LEN characters, the result - is NULL and errno is set. - -BUGS - Emulated via the getwd() call, which is reasonable for most - systems that do not have getcwd(). - -*/ - -#ifndef NO_SYS_PARAM_H -#include -#endif -#include - -extern char *getwd (); -extern int errno; - -#ifndef MAXPATHLEN -#define MAXPATHLEN 1024 -#endif - -char * -getcwd (buf, len) - char *buf; - int len; -{ - char ourbuf[MAXPATHLEN]; - char *result; - - result = getwd (ourbuf); - if (result) { - if (strlen (ourbuf) >= len) { - errno = ERANGE; - return 0; - } - strcpy (buf, ourbuf); - } - return buf; -} diff --git a/contrib/gdb/libiberty/getopt.c b/contrib/gdb/libiberty/getopt.c deleted file mode 100644 index 458dca22b44..00000000000 --- a/contrib/gdb/libiberty/getopt.c +++ /dev/null @@ -1,757 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95 - Free Software Foundation, Inc. - -This file is part of the libiberty library. This library is free -software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) -any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As a special exception, if you link this library with files -compiled with a GNU compiler to produce an executable, this does not cause -the resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why -the executable file might be covered by the GNU General Public License. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -#define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -#if defined (emacs) || defined (CONFIG_BROKETS) -/* We use instead of "config.h" so that a compilation - using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h - (which it would do because it found this file in $srcdir). */ -#include -#else -#include "config.h" -#endif -#endif - -#ifndef __STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ -/* Many versions of the Linux C library include older, broken versions - of these routines, which will break the linker's command-line - parsing. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -#include -#endif /* GNU C library. */ - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg = NULL; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -#include -#define my_index strchr -#else - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -char *getenv (); - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -#ifndef __STDC__ -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -#endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (argv) - char **argv; -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Initialize the internal data when the first call is made. */ - -static const char * -_getopt_initialize (optstring) - const char *optstring; -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - optarg = NULL; - - if (optind == 0) - optstring = _getopt_initialize (optstring); - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0')) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if (nameend - nextchar == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); - } - optopt = c; - return '?'; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/contrib/gdb/libiberty/getopt1.c b/contrib/gdb/libiberty/getopt1.c deleted file mode 100644 index c3400e5b643..00000000000 --- a/contrib/gdb/libiberty/getopt1.c +++ /dev/null @@ -1,190 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License - as published by the Free Software Foundation; either version 2, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#if defined (emacs) || defined (CONFIG_BROKETS) -/* We use instead of "config.h" so that a compilation - using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h - (which it would do because it found this file in $srcdir). */ -#include -#else -#include "config.h" -#endif -#endif - -#include "getopt.h" - -#ifndef __STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ -/* Many versions of the Linux C library include older, broken versions - of these routines, which will break the linker's command-line - parsing. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#else -char *getenv (); -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == EOF) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/contrib/gdb/libiberty/getpagesize.c b/contrib/gdb/libiberty/getpagesize.c deleted file mode 100644 index e9784b8520b..00000000000 --- a/contrib/gdb/libiberty/getpagesize.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Emulation of getpagesize() for systems that need it. */ - -/* - -NAME - - getpagesize -- return the number of bytes in page of memory - -SYNOPSIS - - int getpagesize (void) - -DESCRIPTION - - Returns the number of bytes in a page of memory. This is the - granularity of many of the system memory management routines. - No guarantee is made as to whether or not it is the same as the - basic memory management hardware page size. - -BUGS - - Is intended as a reasonable replacement for systems where this - is not provided as a system call. The value of 4096 may or may - not be correct for the systems where it is returned as the default - value. - -*/ - -#ifndef VMS - -#include -#ifndef NO_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYSCONF -#include -#define GNU_OUR_PAGESIZE sysconf(_SC_PAGESIZE) -#else -#ifdef PAGESIZE -#define GNU_OUR_PAGESIZE PAGESIZE -#else /* no PAGESIZE */ -#ifdef EXEC_PAGESIZE -#define GNU_OUR_PAGESIZE EXEC_PAGESIZE -#else /* no EXEC_PAGESIZE */ -#ifdef NBPG -#define GNU_OUR_PAGESIZE (NBPG * CLSIZE) -#ifndef CLSIZE -#define CLSIZE 1 -#endif /* CLSIZE */ -#else /* no NBPG */ -#ifdef NBPC -#define GNU_OUR_PAGESIZE NBPC -#else /* no NBPC */ -#define GNU_OUR_PAGESIZE 4096 /* Just punt and use reasonable value */ -#endif /* NBPC */ -#endif /* NBPG */ -#endif /* EXEC_PAGESIZE */ -#endif /* PAGESIZE */ -#endif /* HAVE_SYSCONF */ - -int -getpagesize () -{ - return (GNU_OUR_PAGESIZE); -} - -#else /* VMS */ - -#if 0 /* older distributions of gcc-vms are missing */ -#include -#endif -#ifndef SYI$_PAGE_SIZE /* VMS V5.4 and earlier didn't have this yet */ -#define SYI$_PAGE_SIZE 4452 -#endif -extern unsigned long lib$getsyi(const unsigned short *,...); - -int getpagesize () -{ - long pagsiz = 0L; - unsigned short itmcod = SYI$_PAGE_SIZE; - - (void) lib$getsyi (&itmcod, (void *) &pagsiz); - if (pagsiz == 0L) - pagsiz = 512L; /* VAX default */ - return (int) pagsiz; -} - -#endif /* VMS */ diff --git a/contrib/gdb/libiberty/getruntime.c b/contrib/gdb/libiberty/getruntime.c deleted file mode 100644 index 1be3b4c4a2a..00000000000 --- a/contrib/gdb/libiberty/getruntime.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Return time used so far, in microseconds. - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "ansidecl.h" -#include "libiberty.h" - -/* There are several ways to get elapsed execution time; unfortunately no - single way is available for all host systems, nor are there reliable - ways to find out which way is correct for a given host. */ - -#include - -/* These should go away when libiberty uses autoconf. */ - -#if defined(__sun__) && !defined(__svr4__) -#define HAVE_GETRUSAGE -#endif - -#ifdef HAVE_SYSCONF -#define HAVE_TIMES -#endif - -#ifdef HAVE_GETRUSAGE -#include -#include -#endif - -#ifdef HAVE_TIMES -#ifndef NO_SYS_PARAM_H -#include -#endif -#include -#endif - -/* This is a fallback; if wrong, it will likely make obviously wrong - results. */ - -#ifndef CLOCKS_PER_SEC -#define CLOCKS_PER_SEC 1 -#endif - -long -get_run_time () -{ -#ifdef HAVE_GETRUSAGE - struct rusage rusage; - - getrusage (0, &rusage); - return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec - + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); -#else /* ! HAVE_GETRUSAGE */ -#ifdef HAVE_TIMES - struct tms tms; - - times (&tms); - return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ); -#else /* ! HAVE_TIMES */ - /* Fall back on clock and hope it's correctly implemented. */ - const long clocks_per_sec = CLOCKS_PER_SEC; - if (clocks_per_sec <= 1000000) - return clock () * (1000000 / clocks_per_sec); - else - return clock () / clocks_per_sec; -#endif /* HAVE_TIMES */ -#endif /* HAVE_GETRUSAGE */ -} diff --git a/contrib/gdb/libiberty/hex.c b/contrib/gdb/libiberty/hex.c deleted file mode 100644 index 3a2eef03d4c..00000000000 --- a/contrib/gdb/libiberty/hex.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Hex character manipulation support. - Copyright (C) 1995 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "libiberty.h" - -char _hex_value[_hex_array_size]; - -void hex_init () -{ - int i; - for (i = 0; i < _hex_array_size; i++) - _hex_value[i] = _hex_bad; - for (i = 0; i < 10; i++) - _hex_value['0' + i] = i; - for (i = 0; i < 6; i++) - _hex_value['a' + i] = _hex_value['A' + i] = 10 + i; -} diff --git a/contrib/gdb/libiberty/index.c b/contrib/gdb/libiberty/index.c deleted file mode 100644 index e5a00f54d94..00000000000 --- a/contrib/gdb/libiberty/index.c +++ /dev/null @@ -1,11 +0,0 @@ -/* Stub implementation of (obsolete) index(). */ - -extern char * strchr(); - -char * -index (s, c) - char *s; - int c; -{ - return strchr (s, c); -} diff --git a/contrib/gdb/libiberty/insque.c b/contrib/gdb/libiberty/insque.c deleted file mode 100644 index 775019f8fff..00000000000 --- a/contrib/gdb/libiberty/insque.c +++ /dev/null @@ -1,50 +0,0 @@ -/* insque(3C) routines - This file is in the public domain. */ - -/* -NAME - insque, remque -- insert, remove an element from a queue - -SYNOPSIS - struct qelem { - struct qelem *q_forw; - struct qelem *q_back; - char q_data[]; - }; - - void insque (struct qelem *elem, struct qelem *pred) - - void remque (struct qelem *elem) - -DESCRIPTION - Routines to manipulate queues built from doubly linked lists. - The insque routine inserts ELEM in the queue immediately after - PRED. The remque routine removes ELEM from its containing queue. -*/ - - -struct qelem { - struct qelem *q_forw; - struct qelem *q_back; -}; - - -void -insque (elem, pred) - struct qelem *elem; - struct qelem *pred; -{ - elem -> q_forw = pred -> q_forw; - pred -> q_forw -> q_back = elem; - elem -> q_back = pred; - pred -> q_forw = elem; -} - - -void -remque (elem) - struct qelem *elem; -{ - elem -> q_forw -> q_back = elem -> q_back; - elem -> q_back -> q_forw = elem -> q_forw; -} diff --git a/contrib/gdb/libiberty/makefile.dos b/contrib/gdb/libiberty/makefile.dos deleted file mode 100644 index 7eba62c3395..00000000000 --- a/contrib/gdb/libiberty/makefile.dos +++ /dev/null @@ -1,29 +0,0 @@ -CFLAGS=-O2 - -OBJS = \ - argv.o \ - basename.o \ - concat.o \ - cplus-dem.o \ - fdmatch.o \ - floatformat.o \ - getopt.o \ - getopt1.o \ - getruntime.o \ - hex.o \ - msdos.o \ - obstack.o \ - spaces.o \ - strerror.o \ - strsignal.o \ - xatexit.o \ - xexit.o \ - xmalloc.o \ - $E - -.c.o: - gcc -I../include $(CFLAGS) -c $< - -libiberty.a : $(OBJS) - -rm libiberty.a - ar rvs libiberty.a $(OBJS) diff --git a/contrib/gdb/libiberty/memchr.c b/contrib/gdb/libiberty/memchr.c deleted file mode 100644 index 93ef43d3f88..00000000000 --- a/contrib/gdb/libiberty/memchr.c +++ /dev/null @@ -1,60 +0,0 @@ -/* -FUNCTION - <>---find character in memory - -INDEX - memchr - -ANSI_SYNOPSIS - #include - void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>); - -TRAD_SYNOPSIS - #include - void *memchr(<[src]>, <[c]>, <[length]>) - void *<[src]>; - void *<[c]>; - size_t <[length]>; - -DESCRIPTION - This function searches memory starting at <<*<[src]>>> for the - character <[c]>. The search only ends with the first - occurrence of <[c]>, or after <[length]> characters; in - particular, <> does not terminate the search. - -RETURNS - If the character <[c]> is found within <[length]> characters - of <<*<[src]>>>, a pointer to the character is returned. If - <[c]> is not found, then <> is returned. - -PORTABILITY -<> requires no supporting OS subroutines. - -QUICKREF - memchr ansi pure - -*/ - -#include -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -PTR -memchr (src_void, c, length) - register CONST PTR src_void; - int c; - size_t length; -{ - CONST unsigned char *src = (CONST unsigned char *)src_void; - - while (--length >= 0) - { - if (*src == c) - return (PTR)src; - src++; - } - return NULL; -} diff --git a/contrib/gdb/libiberty/memcmp.c b/contrib/gdb/libiberty/memcmp.c deleted file mode 100644 index 127ae0c8019..00000000000 --- a/contrib/gdb/libiberty/memcmp.c +++ /dev/null @@ -1,38 +0,0 @@ -/* memcmp -- compare two memory regions. - This function is in the public domain. */ - -/* -NAME - memcmp -- compare two memory regions - -SYNOPSIS - int memcmp (const void *from, const void *to, size_t count) - -DESCRIPTION - Compare two memory regions and return less than, - equal to, or greater than zero, according to lexicographical - ordering of the compared regions. -*/ - -#include -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -int -DEFUN(memcmp, (str1, str2, count), - const PTR str1 AND const PTR str2 AND size_t count) -{ - register unsigned char *s1 = (unsigned char*)str1; - register unsigned char *s2 = (unsigned char*)str2; - - while (count-- > 0) - { - if (*s1++ != *s2++) - return s1[-1] < s2[-1] ? -1 : 1; - } - return 0; -} - diff --git a/contrib/gdb/libiberty/memcpy.c b/contrib/gdb/libiberty/memcpy.c deleted file mode 100644 index c28208a0f7e..00000000000 --- a/contrib/gdb/libiberty/memcpy.c +++ /dev/null @@ -1,28 +0,0 @@ -/* memcpy (the standard C function) - This function is in the public domain. */ - -/* -NAME - memcpy -- copy memory regions of arbitary length - -SYNOPSIS - void* memcpy (void *out, const void *in, size_t n); - -DESCRIPTION - Copy LENGTH bytes from memory region pointed to by IN to memory - region pointed to by OUT. -*/ - -#include -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -PTR -DEFUN(memcpy, (out, in, length), PTR out AND CONST PTR in AND size_t length) -{ - bcopy(in, out, length); - return out; -} diff --git a/contrib/gdb/libiberty/memmove.c b/contrib/gdb/libiberty/memmove.c deleted file mode 100644 index 818fc249662..00000000000 --- a/contrib/gdb/libiberty/memmove.c +++ /dev/null @@ -1,18 +0,0 @@ -/* Wrapper to implement ANSI C's memmove using BSD's bcopy. */ -/* This function is in the public domain. --Per Bothner. */ -#include -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -PTR -memmove (s1, s2, n) - PTR s1; - CONST PTR s2; - size_t n; -{ - bcopy (s2, s1, n); - return s1; -} diff --git a/contrib/gdb/libiberty/memset.c b/contrib/gdb/libiberty/memset.c deleted file mode 100644 index 5f54831e83c..00000000000 --- a/contrib/gdb/libiberty/memset.c +++ /dev/null @@ -1,19 +0,0 @@ -/* memset - This implementation is in the public domain. */ - -#include -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -PTR -DEFUN(memset, (dest, val, len), - PTR dest AND register int val AND register size_t len) -{ - register unsigned char *ptr = (unsigned char*)dest; - while (len-- > 0) - *ptr++ = val; - return dest; -} diff --git a/contrib/gdb/libiberty/mpw-config.in b/contrib/gdb/libiberty/mpw-config.in deleted file mode 100644 index 829d8e730d4..00000000000 --- a/contrib/gdb/libiberty/mpw-config.in +++ /dev/null @@ -1,9 +0,0 @@ -# MPW configuration fragment for libiberty. - -forward-include "{srcdir}"alloca-norm.h alloca-conf.h - -Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new - -MoveIfChange "{o}"config.new "{o}"config.h - - diff --git a/contrib/gdb/libiberty/mpw-make.sed b/contrib/gdb/libiberty/mpw-make.sed deleted file mode 100644 index f99eb1a4407..00000000000 --- a/contrib/gdb/libiberty/mpw-make.sed +++ /dev/null @@ -1,49 +0,0 @@ -# Sed commands to finish translating libiberty's Unix makefile to MPW syntax. - -# Comment out a useless thing. -/^\.always\./s/^/#/ - -# Replace the auto-generated list with the list of what we know we need. -s/`cat needed-list`/"{o}"alloca.c.o "{o}"bcopy.c.o "{o}"getpagesize.c.o "{o}"insque.c.o "{o}"mpw.c.o "{o}"strcasecmp.c.o "{o}"strdup.c.o "{o}"strncasecmp.c.o/ - -# Paste in some desirable definitions. -/^###$/a\ -\ -HDEFINES = -d NEED_sys_siglist -d NEED_sys_errlist -d NEED_basename -d NEED_strcasecmp -d NEED_strncasecmp\ -INCLUDES = -i : -i {INCDIR}: -i {INCDIR}:mpw: -i ::extra-include: -i "{s}"\ -\ -.c.o \\Option-f .c\ - {CC} {DepDir}{Default}.c {LIBCFLAGS} {INCLUDES} {HDEFINES} @SEGMENT_FLAG@ -o {TargDir}{Default}.c.o\ - -# Remove dependency on needed-list, which we don't use. -/DO_ALSO =/s/needed-list// - -/INCDIR=/s/"{srcdir}"{MULTISRCTOP}::/"{topsrcdir}"/ - -# Whack out the COMPILE.c trickiness. -/^COMPILE.c /,/^$/d - -# Remove the multido trickiness from the "all" target. -/^all \\Option-f/,/^$/c\ -all \\Option-f {TARGETLIB}\ - - -# Remove the RULE1/RULE2 crud. -/if \[/,/fi/d -/^RULE1 =/,/RULE2 =/d -/RULE2/s/RULE2/TARGETLIB/ - -# Don't want fdmatch ever. -s/ "{o}"fdmatch.c.o// - -# Fix paths to generated files. -/config.h/s/"{s}"config.h/"{o}"config.h/ - -# Whack out config rebuild rules. -/^"{o}"config.h \\Option-f/,/^$/d - - - - - - diff --git a/contrib/gdb/libiberty/mpw.c b/contrib/gdb/libiberty/mpw.c deleted file mode 100644 index b93e1008697..00000000000 --- a/contrib/gdb/libiberty/mpw.c +++ /dev/null @@ -1,1010 +0,0 @@ -/* MPW-Unix compatibility library. - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This should only be compiled and linked under MPW. */ - -#include "mpw.h" - -#include - -#ifndef USE_MW_HEADERS -#include -#include -#endif - -#include -#include - -#include - -/* Initialize to 0 at first, then set to errno_max() later. */ - -int sys_nerr = 0; - -/* Debug flag for pathname hacking. Set this to one and rebuild. */ - -int DebugPI = 0; - -void -mpwify_filename(char *unixname, char *macname) -{ - int i, j, in_middle, terminate = 0; - - /* (should truncate 255 chars from end of name, not beginning) */ - if (strlen (unixname) > 255) - { - fprintf (stderr, "Pathname \"%s\" is too long for Macs, truncating\n", - unixname); - terminate = 1; - } - /* Abs Unix path to abs Mac path. */ - if (*unixname == '/') - { - if (strncmp (unixname, "/tmp/", 5) == 0) - { - /* A temporary name, make a more Mac-flavored tmpname. */ - /* A better choice would be {Boot}Trash:foo, but that would - require being able to identify the boot disk's and trashcan's - name. Another option would be to have an env var, so user - can point it at a ramdisk. */ - strncpy (macname, unixname, 255); - if (terminate) - macname[255] = '\0'; - macname[0] = ':'; - macname[4] = '_'; - } - else - { - /* Assume that the leading component is a valid disk name. */ - strncpy (macname, unixname + 1, 255); - } - } - else - { - /* If this is a "Unix-only" pathname, assume relative. */ - if (strchr (unixname, '/') && ! strchr (unixname, ':')) - { - macname[0] = ':'; - strncpy (macname + 1, unixname, 255); - } - else - { - /* Otherwise copy it verbatim. */ - /* ... but if of the form ":/foo", lose the extra colon; - the slash will be made into a colon shortly. */ - if (unixname[0] == ':' && unixname[1] == '/') - ++unixname; - strncpy (macname, unixname, 255); - } - } - if (terminate) - macname[255] = '\0'; - for (i = 0; macname[i] != '\0'; ++i) - { - if (macname[i] == '/') - macname[i] = ':'; - } - in_middle = 0; - j = 0; - for (i = 0; macname[i] != '\0'; ++i) - { - /* We're in the middle of the name when a char is not a colon. */ - if (macname[i] != ':') - in_middle = 1; - /* Copy chars verbatim, *unless* the char is the first of a pair - of colons in the middle of a pathname. */ - if (!(in_middle && macname[i] == ':' && macname[i+1] == ':')) - macname[j++] = macname[i]; - } - macname[j] = '\0'; - /* If we have a trailing ":.", make it into a ":". */ - if (j >= 2 && macname[j-2] == ':' && macname[j-1] == '.') - macname[j-1] = '\0'; - if (DebugPI) - { - fprintf (stderr, "# Made \"%s\"\n", unixname); - fprintf (stderr, "# into \"%s\"\n", macname); - } -} - -/* MPW-flavored basename finder. */ - -char * -mpw_basename (name) - char *name; -{ - char *base = name; - - while (*name) - { - if (*name++ == ':') - { - base = name; - } - } - return base; -} - -/* Mixed MPW/Unix basename finder. This can be led astray by - filenames with slashes in them and come up with a basename that - either corresponds to no file or (worse) to some other file, so - should only be tried if other methods of finding a file via a - basename have failed. */ - -char * -mpw_mixed_basename (name) - char *name; -{ - char *base = name; - - while (*name) - { - if (*name == '/' || *name == ':') - { - base = name + 1; - } - ++name; - } - return base; -} - -/* This function is fopen() modified to create files that are type TEXT - or 'BIN ', and always of type 'MPS '. */ - -FILE * -mpw_fopen (char *name, char *mode) -{ -#undef fopen - int errnum; - FILE *fp; - char tmpname[256]; - - mpwify_filename (name, tmpname); - PROGRESS (1); - fp = fopen (tmpname, mode); - errnum = errno; - - /* If writing, need to set type and creator usefully. */ - if (strchr (mode, 'w')) - { - char *pname = (char *) malloc (strlen (tmpname) + 2); - OSErr e; - struct FInfo fi; - - pname[0] = strlen (tmpname); - strcpy (pname+1, tmpname); - - e = GetFInfo ((ConstStr255Param) pname, 0, &fi); - /* should do spiffier error handling */ - if (e != 0) - fprintf(stderr, "GetFInfo returns %d\n", e); - if (strchr (mode, 'b')) - { - fi.fdType = (OSType) 'BIN '; - } - else - { - fi.fdType = (OSType) 'TEXT'; - } - fi.fdCreator = (OSType) 'MPS '; - e = SetFInfo ((ConstStr255Param) pname, 0, &fi); - if (e != 0) - fprintf(stderr, "SetFInfo returns %d\n", e); - free (pname); - } - if (fp == NULL) - errno = errnum; - return fp; -} - -/* This is a version of fseek() modified to fill the file with zeros - if seeking past the end of it. */ - -#define ZEROBLKSIZE 4096 - -char zeros[ZEROBLKSIZE]; - -int -mpw_fseek (FILE *fp, int offset, int whence) -{ -#undef fseek - int cursize, numleft; - - PROGRESS (1); - if (whence == SEEK_SET) - { - fseek (fp, 0, SEEK_END); - cursize = ftell (fp); - if (offset > cursize) - { - numleft = offset - cursize; - while (numleft > ZEROBLKSIZE) - { - /* This might fail, should check for that. */ - PROGRESS (1); - fwrite (zeros, 1, ZEROBLKSIZE, fp); - numleft -= ZEROBLKSIZE; - } - PROGRESS (1); - fwrite (zeros, 1, numleft, fp); - fflush (fp); - } - } - return fseek (fp, offset, whence); -} - -int -mpw_fread (char *ptr, int size, int nitems, FILE *stream) -{ -#undef fread - int rslt; - - PROGRESS (1); - rslt = fread (ptr, size, nitems, stream); - PROGRESS (1); - return rslt; -} - -int -mpw_fwrite (char *ptr, int size, int nitems, FILE *stream) -{ -#undef fwrite - int rslt; - - PROGRESS (1); - rslt = fwrite (ptr, size, nitems, stream); - PROGRESS (1); - return rslt; -} - -int -link () -{ - fprintf (stderr, "link not available!\n"); - mpw_abort (); -} - -int -fork () -{ - fprintf (stderr, "fork not available!\n"); - mpw_abort (); -} - -int -vfork () -{ - fprintf (stderr, "vfork not available!\n"); - mpw_abort (); - return (-1); -} - -int -pipe (int *fd) -{ - fprintf (stderr, "pipe not available!\n"); - mpw_abort (); - return (-1); -} - -#ifndef USE_MW_HEADERS -int -execvp (char *file, char **argv) -{ - fprintf (stderr, "execvp not available!\n"); - mpw_abort (); - return (-1); -} - -int -execv (char *path, char **argv) -{ - fprintf (stderr, "execv not available!\n"); - mpw_abort (); - return (-1); -} -#endif - -int -kill (int pid, int sig) -{ - fprintf (stderr, "kill not available!\n"); - mpw_abort (); - return (-1); -} - -int -wait (int *status) -{ - *status = 0; - return 0; -} - -#ifndef USE_MW_HEADERS -int -sleep (int seconds) -{ - unsigned long start_time, now; - - time (&start_time); - - while (1) - { - PROGRESS (1); - time (&now); - if (now > start_time + seconds) - return 0; - } -} -#endif - -void -putenv (char *str) -{ - /* The GCC driver calls this to do things for collect2, but we - don't care about collect2. */ -} - -int -chmod (char *path, int mode) -{ - /* Pretend it was all OK. */ - return 0; -} - -#ifndef USE_MW_HEADERS -int -getuid () -{ - /* One value is as good as another... */ - return 0; -} - -int -getgid () -{ - /* One value is as good as another... */ - return 0; -} -#endif - -/* Instead of coredumping, which is not a normal Mac facility, we - drop into Macsbug. If we then "g" from Macsbug, the program will - exit cleanly. */ - -void -mpw_abort () -{ - /* Make sure no output still buffered up, then zap into MacsBug. */ - fflush(stdout); - fflush(stderr); - printf("## Abort! ##\n"); -#ifdef MPW_SADE - SysError(8005); -#else - Debugger(); -#endif - /* "g" in MacsBug will then cause a regular error exit. */ - exit (1); -} - -/* Imitation getrusage based on the ANSI clock() function. */ - -int -getrusage (int who, struct rusage *rusage) -{ - int clk = clock (); - -#if 0 - rusage->ru_utime.tv_sec = clk / CLOCKS_PER_SEC; - rusage->ru_utime.tv_usec = ((clk * 1000) / CLOCKS_PER_SEC) * 1000; - rusage->ru_stime.tv_sec = 0; - rusage->ru_stime.tv_usec = 0; -#endif -} - -int -sbrk () -{ - return 0; -} - -#ifndef USE_MW_HEADERS -int -isatty (int fd) -{ - return 0; -} - -/* This is inherited from Timothy Murray's Posix library. */ - -#include "utime.h" - -int -utime (char *filename, struct utimbuf *times) -{ - CInfoPBRec cipbr; - HFileInfo *fpb = (HFileInfo *) &cipbr; - DirInfo *dpb = (DirInfo *) &cipbr; - unsigned char pname[256]; - short err; - - strcpy ((char *) pname, filename); - c2pstr (pname); - - dpb->ioDrDirID = 0L; - fpb->ioNamePtr = pname; - fpb->ioVRefNum = 0; - fpb->ioFDirIndex = 0; - fpb->ioFVersNum = 0; - err = PBGetCatInfo (&cipbr, 0); - if (err != noErr) { - errno = ENOENT; - return -1; - } - dpb->ioDrDirID = 0L; - fpb->ioFlMdDat = times->modtime; - fpb->ioFlCrDat = times->actime; - err = PBSetCatInfo (&cipbr, 0); - if (err != noErr) { - errno = EACCES; - return -1; - } - return 0; -} - -int -mkdir (char *path, int mode) -{ - errno = ENOSYS; - return -1; -} - -int -rmdir () -{ - errno = ENOSYS; - return -1; -} -#endif - -chown () -{ - errno = ENOSYS; - return -1; -} - -char *myenviron[] = {NULL}; - -char **environ = myenviron; - -#ifndef USE_MW_HEADERS - -/* Minimal 'stat' emulation: tells directories from files and - gives length and mtime. - - Derived from code written by Guido van Rossum, CWI, Amsterdam - and placed by him in the public domain. */ - -extern int __uid, __gid; - -int __uid = 0; -int __gid = 0; - -/* Bits in ioFlAttrib: */ -#define LOCKBIT (1<<0) /* File locked */ -#define DIRBIT (1<<4) /* It's a directory */ - -/* Macified "stat" in which filename is given relative to a directory, - specified by long DirID. */ - -static int -_stat (char *name, long dirid, struct stat *buf) -{ - CInfoPBRec cipbr; - HFileInfo *fpb = (HFileInfo*) &cipbr; - DirInfo *dpb = (DirInfo*) &cipbr; - Str255 pname; - short err; - - /* Make a temp copy of the name and pascalize. */ - strcpy ((char *) pname, name); - c2pstr (pname); - - cipbr.dirInfo.ioDrDirID = dirid; - cipbr.hFileInfo.ioNamePtr = pname; - cipbr.hFileInfo.ioVRefNum = 0; - cipbr.hFileInfo.ioFDirIndex = 0; - cipbr.hFileInfo.ioFVersNum = 0; - err = PBGetCatInfo (&cipbr, 0); - if (err != noErr) - { - errno = ENOENT; - return -1; - } - /* Mac files are readable if they can be accessed at all. */ - buf->st_mode = 0444; - /* Mark unlocked files as writeable. */ - if (!(fpb->ioFlAttrib & LOCKBIT)) - buf->st_mode |= 0222; - if (fpb->ioFlAttrib & DIRBIT) - { - /* Mark directories as "executable". */ - buf->st_mode |= 0111 | S_IFDIR; - buf->st_size = dpb->ioDrNmFls; - buf->st_rsize = 0; - } - else - { - buf->st_mode |= S_IFREG; - /* Mark apps as "executable". */ - if (fpb->ioFlFndrInfo.fdType == 'APPL') - buf->st_mode |= 0111; - /* Fill in the sizes of data and resource forks. */ - buf->st_size = fpb->ioFlLgLen; - buf->st_rsize = fpb->ioFlRLgLen; - } - /* Fill in various times. */ - buf->st_atime = fpb->ioFlCrDat; - buf->st_mtime = fpb->ioFlMdDat; - buf->st_ctime = fpb->ioFlCrDat; - /* Set up an imitation inode number. */ - buf->st_ino = (unsigned short) fpb->ioDirID; - /* Set up an imitation device. */ - GetVRefNum (buf->st_ino, &buf->st_dev); - buf->st_uid = __uid; - buf->st_gid = __gid; -/* buf->st_FlFndrInfo = fpb->ioFlFndrInfo; */ - return 0; -} - -/* stat() sets up an empty dirid. */ - -int -stat (char *path, struct stat *buf) -{ - long rslt, errnum; - char tmpname[256]; - - mpwify_filename (path, tmpname); - if (DebugPI) - fprintf (stderr, "# stat (%s, %x)", tmpname, buf); - PROGRESS (1); - rslt = _stat (tmpname, 0L, buf); - errnum = errno; - if (DebugPI) - { - fprintf (stderr, " -> %d", rslt); - if (rslt != 0) - fprintf (stderr, " (errno is %d)", errnum); - fprintf (stderr, "\n"); - fflush (stderr); - } - if (rslt != 0) - errno = errnum; - return rslt; -} - -int -fstat (int fd, struct stat *buf) -{ - FCBPBRec fcb; - FILE *fp; - Str255 pathname; - long dirid = 0L, temp; - long rslt, errnum; - short err; - - if (DebugPI) - fprintf (stderr, "# fstat (%d, %x)", fd, buf); - PROGRESS (1); - pathname[0] = 0; -#ifdef FIOFNAME - /* Use an MPW-specific ioctl to get the pathname associated with - the file descriptor. */ - ioctl (fd, FIOFNAME, (long *) pathname); -#else - you lose -#endif - if (DebugPI) - fprintf (stderr, " (name is %s)", pathname); - dirid = 0L /* fcb.ioFCBParID */ ; - rslt = _stat ((char *) pathname, dirid, buf); - errnum = errno; - if (DebugPI) - { - fprintf (stderr, " -> %d", rslt); - if (rslt != 0) - fprintf (stderr, " (errno is %d)", errnum); - fprintf (stderr, "\n"); - fflush (stderr); - } - if (rslt != 0) - errno = errnum; - return rslt; -} - -#endif /* n USE_MW_HEADERS */ - -chdir () -{ - errno = ENOSYS; - return (-1); -} - -char * -getcwd (char *buf, int size) -{ - if (buf == NULL) - buf = (char *) malloc (size); - strcpy(buf, ":"); - return buf; -} - -/* This should probably be more elaborate for MPW. */ - -char * -getpwd () -{ - return ":"; -} - -int -mpw_open (char *filename, int arg2, int arg3) -{ -#undef open - int fd, errnum = 0; - char tmpname[256]; - - mpwify_filename (filename, tmpname); - fd = open (tmpname, arg2); - errnum = errno; - - if (DebugPI) - { - fprintf (stderr, "# open (%s, %d, %d)", tmpname, arg2, arg3); - fprintf (stderr, " -> %d", fd); - if (fd == -1) - fprintf (stderr, " (errno is %d)", errnum); - fprintf (stderr, "\n"); - } - if (fd == -1) - errno = errnum; - return fd; -} - -int -mpw_access (char *filename, unsigned int cmd) -{ -#undef access - - int rslt, errnum = 0; - struct stat st; - char tmpname[256]; - - mpwify_filename (filename, tmpname); - if (cmd & R_OK || cmd & X_OK) - { - rslt = stat (tmpname, &st); - errnum = errno; - if (rslt >= 0) - { - if (((st.st_mode & 004 == 0) && (cmd & R_OK)) - || ((st.st_mode & 002 == 0) && (cmd & W_OK)) - || ((st.st_mode & 001 == 0) && (cmd & X_OK))) - { - rslt = -1; - errnum = EACCES; - } - } - } - if (DebugPI) - { - fprintf (stderr, "# mpw_access (%s, %d)", tmpname, cmd); - fprintf (stderr, " -> %d", rslt); - if (rslt != 0) - fprintf (stderr, " (errno is %d)", errnum); - fprintf (stderr, "\n"); - } - if (rslt != 0) - errno = errnum; - return rslt; -} - -/* The MPW library creat() has no mode argument. */ - -int -mpw_creat (char *path, /* mode_t */ int mode) -{ -#undef creat - -#ifdef USE_MW_HEADERS - return creat (path, mode); -#else - return creat (path); -#endif -} - -/* This is a hack to get control in an MPW tool before it crashes the - machine. */ - -mpw_special_init (name) - char *name; -{ - if (strstr (name, "DEBUG")) - DebugStr("\pat beginning of program"); -} - -static int current_umask; - -int -umask(int mask) -{ - int oldmask = current_umask; - - current_umask = mask; - return oldmask; -} - -/* Cursor-spinning stuff that includes metering of spin rate and delays. */ - -/* Nonzero when cursor spinning has been set up properly. */ - -int cursor_inited; - -/* Nonzero if spin should be measured and excessive delays reported. */ - -int measure_spin; - -/* Nonzero if spin histogram and rate data should be written out. */ - -int dump_spin_data; - -long warning_threshold = 400000; - -long bucket_size = 1024; - -long bucket_power = 10; - -long numbuckets = 300; - -int *delay_counts; - -int overflow_count; - -char *current_progress; - -static UnsignedWide last_microseconds; - -static char *last_spin_file = ""; - -static int last_spin_line; - -void -warn_if_spin_delay (char *file, int line) -{ - long diff, ix; - UnsignedWide now; - - Microseconds(&now); - - diff = now.lo - last_microseconds.lo; - - if (diff > warning_threshold) - fprintf (stderr, "# %s: %ld.%06ld sec delay getting from %s:%d to %s:%d\n", - (current_progress ? current_progress : ""), - diff / 1000000, diff % 1000000, - last_spin_file, last_spin_line, file, line); - if (dump_spin_data) - { - if (diff >= 0) - { - ix = diff >> bucket_power; - if (ix >= 0 && ix < numbuckets && delay_counts != NULL) - ++delay_counts[ix]; - else - ++overflow_count; - } - else - fprintf (stderr, "raw diff is %ld (?)\n", diff); - } -} - -void -record_for_spin_delay (char *file, int line) -{ - Microseconds (&last_microseconds); - last_spin_file = file; - last_spin_line = line; -} - -void -mpw_start_progress (char *str, int n, char *file, int line) -{ - int i; - char *measure, *threshold; - - if (!cursor_inited) - { - InitCursorCtl (nil); - cursor_inited = 1; - record_for_spin_delay (file, line); - measure = getenv ("MEASURE_SPIN"); - if (measure != NULL && measure[0] != '\0') - { - measure_spin = 1; - if (strcmp (measure, "all") == 0) - dump_spin_data = 1; - } - threshold = getenv ((const char *) "SPIN_WARN_THRESHOLD"); - if (threshold != NULL && threshold[0] != '\0') - warning_threshold = atol (threshold); - if (dump_spin_data) - { - if (delay_counts == NULL) - delay_counts = (int *) malloc (numbuckets * sizeof (int)); - for (i = 0; i < numbuckets; ++i) - delay_counts[i] = 0; - overflow_count = 0; - } - } - current_progress = str; - - sys_nerr = errno_max (); - - mpw_special_init (str); -} - -void -mpw_progress (int n) -{ - SpinCursor (32); -} - -void -mpw_progress_measured (int n, char *file, int line) -{ - if (measure_spin) - warn_if_spin_delay (file, line); - SpinCursor (32); - if (measure_spin) - record_for_spin_delay (file, line); -} - -void -mpw_end_progress (char *str, char *file, int line) -{ - long i, delay, count = 0, sum = 0, avgdelay, spinrate; - long curpower = 0, curgroup = 0; - - /* Warn if it's been a while since the last spin. */ - if (measure_spin) - warn_if_spin_delay (file, line); - - /* Dump all the nonzero delay counts and an approximation of the delay. */ - if (dump_spin_data && delay_counts != NULL) - { - for (i = 0; i < numbuckets; ++i) - { - delay = (i + 1) * bucket_size; - sum += delay_counts[i] * (i + 1); - count += delay_counts[i]; - if (delay <= (1 << curpower)) - { - curgroup += delay_counts[i]; - } - else - { - if (curgroup > 0) - fprintf (stderr, - "# %s: %d delays between %ld.%06ld and %ld.%06ld sec\n", - (str ? str : ""), - curgroup, - (1 << curpower) / 1000000, - (1 << curpower) % 1000000, - (1 << (curpower + 1)) / 1000000, - (1 << (curpower + 1)) % 1000000); - ++curpower; - curgroup = 0; - } - } - if (count > 0) - { - avgdelay = (sum * bucket_size) / count; - spinrate = 1000000 / avgdelay; - fprintf (stderr, "# %s: Average spin rate is %d times/sec\n", - (str ? str : ""), spinrate); - } - } -} - -#ifdef PROGRESS_TEST - -/* Test program. */ - -main () -{ - int i, j; - double x = 1.0, y = 2.4; - long start = Microseconds (), tm; FIXME - - START_PROGRESS ("hi", 0); - - for (i = 0; i < 1000; ++i) - { - PROGRESS (1); - - for (j = 0; j < (i * 100); ++j) - { - x += (x * y) / j; - } - } - - END_PROGRESS ("hi"); - - tm = Microseconds () - start; - - printf ("Total time is %d.%d secs\n", tm / 1000000, tm % 1000000); -} - -#endif - -#ifdef USE_MW_HEADERS -/* Empty definitions for Metrowerks' SIOUX console library. */ - -#ifndef __CONSOLE__ -#include -#endif - -short -InstallConsole(short fd) -{ -#pragma unused (fd) - return 0; -} - -void -RemoveConsole(void) -{ -} - -long -WriteCharsToConsole(char *buf, long n) -{ -#pragma unused (buf, n) - return 0; -} - -long ReadCharsFromConsole(char *buf, long n) -{ -#pragma unused (buf, n) - return 0; -} - -extern char * -__ttyname(long fd) -{ - static char *__devicename = "null device"; - - if (fd >= 0 && fd <= 2) - return (__devicename); - return NULL; -} - -#endif diff --git a/contrib/gdb/libiberty/msdos.c b/contrib/gdb/libiberty/msdos.c deleted file mode 100644 index 923e64d4ede..00000000000 --- a/contrib/gdb/libiberty/msdos.c +++ /dev/null @@ -1,15 +0,0 @@ -char msg[] = "No vfork available - aborting\n"; -vfork() -{ - write(1, msg, sizeof(msg)); -} - -sigsetmask() -{ - /* no signals support in go32 (yet) */ -} - -waitpid() -{ - return -1; -} diff --git a/contrib/gdb/libiberty/obstack.c b/contrib/gdb/libiberty/obstack.c deleted file mode 100644 index 2d380940efc..00000000000 --- a/contrib/gdb/libiberty/obstack.c +++ /dev/null @@ -1,507 +0,0 @@ -/* obstack.c - subroutines used implicitly by object stack macros - Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Library General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Library General Public License for more details. - -You should have received a copy of the GNU Library General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "obstack.h" - -/* This is just to get __GNU_LIBRARY__ defined. */ -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -/* CYGNUS LOCAL. No, don't comment the code out. We will be using - ../include/obstack.h, which was changed relatively recently in a - way that is not binary compatible. Until we feel confident that - nobody is using the old obstack.c code, force the use of this code. - This issue will arise anytime a change is made which is not binary - compatible. -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) -*/ -#if 1 - - -#ifdef __STDC__ -#define POINTER void * -#else -#define POINTER char * -#endif - -/* Determine default alignment. */ -struct fooalign {char x; double d;}; -#define DEFAULT_ALIGNMENT \ - ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0)) -/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. - But in fact it might be less smart and round addresses to as much as - DEFAULT_ROUNDING. So we prepare for it to do that. */ -union fooround {long x; double d;}; -#define DEFAULT_ROUNDING (sizeof (union fooround)) - -/* When we copy a long block of data, this is the unit to do it with. - On some machines, copying successive ints does not work; - in such a case, redefine COPYING_UNIT to `long' (if that works) - or `char' as a last resort. */ -#ifndef COPYING_UNIT -#define COPYING_UNIT int -#endif - -/* The non-GNU-C macros copy the obstack into this global variable - to avoid multiple evaluation. */ - -struct obstack *_obstack; - -/* Define a macro that either calls functions with the traditional malloc/free - calling interface, or calls functions with the mmalloc/mfree interface - (that adds an extra first argument), based on the state of use_extra_arg. - For free, do not use ?:, since some compilers, like the MIPS compilers, - do not allow (expr) ? void : void. */ - -#define CALL_CHUNKFUN(h, size) \ - (((h) -> use_extra_arg) \ - ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ - : (*(h)->chunkfun) ((size))) - -#define CALL_FREEFUN(h, old_chunk) \ - do { \ - if ((h) -> use_extra_arg) \ - (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ - else \ - (*(h)->freefun) ((old_chunk)); \ - } while (0) - - -/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). - Objects start on multiples of ALIGNMENT (0 means use default). - CHUNKFUN is the function to use to allocate chunks, - and FREEFUN the function to free them. - - Return nonzero if successful, zero if out of memory. - To recover from an out of memory error, - free up some memory, then call this again. */ - -int -_obstack_begin (h, size, alignment, chunkfun, freefun) - struct obstack *h; - int size; - int alignment; - POINTER (*chunkfun) (); - void (*freefun) (); -{ - register struct _obstack_chunk* chunk; /* points to new chunk */ - - if (alignment == 0) - alignment = DEFAULT_ALIGNMENT; - if (size == 0) - /* Default size is what GNU malloc can fit in a 4096-byte block. */ - { - /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. - Use the values for range checking, because if range checking is off, - the extra bytes won't be missed terribly, but if range checking is on - and we used a larger request, a whole extra 4096 bytes would be - allocated. - - These number are irrelevant to the new GNU malloc. I suspect it is - less sensitive to the size of the request. */ - int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) - + 4 + DEFAULT_ROUNDING - 1) - & ~(DEFAULT_ROUNDING - 1)); - size = 4096 - extra; - } - - h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; - h->freefun = freefun; - h->chunk_size = size; - h->alignment_mask = alignment - 1; - h->use_extra_arg = 0; - - chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); - if (!chunk) - { - h->alloc_failed = 1; - return 0; - } - h->alloc_failed = 0; - h->next_free = h->object_base = chunk->contents; - h->chunk_limit = chunk->limit - = (char *) chunk + h->chunk_size; - chunk->prev = 0; - /* The initial chunk now contains no empty object. */ - h->maybe_empty_object = 0; - return 1; -} - -int -_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) - struct obstack *h; - int size; - int alignment; - POINTER (*chunkfun) (); - void (*freefun) (); - POINTER arg; -{ - register struct _obstack_chunk* chunk; /* points to new chunk */ - - if (alignment == 0) - alignment = DEFAULT_ALIGNMENT; - if (size == 0) - /* Default size is what GNU malloc can fit in a 4096-byte block. */ - { - /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. - Use the values for range checking, because if range checking is off, - the extra bytes won't be missed terribly, but if range checking is on - and we used a larger request, a whole extra 4096 bytes would be - allocated. - - These number are irrelevant to the new GNU malloc. I suspect it is - less sensitive to the size of the request. */ - int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) - + 4 + DEFAULT_ROUNDING - 1) - & ~(DEFAULT_ROUNDING - 1)); - size = 4096 - extra; - } - - h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; - h->freefun = freefun; - h->chunk_size = size; - h->alignment_mask = alignment - 1; - h->extra_arg = arg; - h->use_extra_arg = 1; - - chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); - if (!chunk) - { - h->alloc_failed = 1; - return 0; - } - h->alloc_failed = 0; - h->next_free = h->object_base = chunk->contents; - h->chunk_limit = chunk->limit - = (char *) chunk + h->chunk_size; - chunk->prev = 0; - /* The initial chunk now contains no empty object. */ - h->maybe_empty_object = 0; - return 1; -} - -/* Allocate a new current chunk for the obstack *H - on the assumption that LENGTH bytes need to be added - to the current object, or a new object of length LENGTH allocated. - Copies any partial object from the end of the old chunk - to the beginning of the new one. */ - -void -_obstack_newchunk (h, length) - struct obstack *h; - int length; -{ - register struct _obstack_chunk* old_chunk = h->chunk; - register struct _obstack_chunk* new_chunk; - register long new_size; - register int obj_size = h->next_free - h->object_base; - register int i; - int already; - - /* Compute size for new chunk. */ - new_size = (obj_size + length) + (obj_size >> 3) + 100; - if (new_size < h->chunk_size) - new_size = h->chunk_size; - - /* Allocate and initialize the new chunk. */ - new_chunk = CALL_CHUNKFUN (h, new_size); - if (!new_chunk) - { - h->alloc_failed = 1; - return; - } - h->alloc_failed = 0; - h->chunk = new_chunk; - new_chunk->prev = old_chunk; - new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; - - /* Move the existing object to the new chunk. - Word at a time is fast and is safe if the object - is sufficiently aligned. */ - if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) - { - for (i = obj_size / sizeof (COPYING_UNIT) - 1; - i >= 0; i--) - ((COPYING_UNIT *)new_chunk->contents)[i] - = ((COPYING_UNIT *)h->object_base)[i]; - /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, - but that can cross a page boundary on a machine - which does not do strict alignment for COPYING_UNITS. */ - already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); - } - else - already = 0; - /* Copy remaining bytes one by one. */ - for (i = already; i < obj_size; i++) - new_chunk->contents[i] = h->object_base[i]; - - /* If the object just copied was the only data in OLD_CHUNK, - free that chunk and remove it from the chain. - But not if that chunk might contain an empty object. */ - if (h->object_base == old_chunk->contents && ! h->maybe_empty_object) - { - new_chunk->prev = old_chunk->prev; - CALL_FREEFUN (h, old_chunk); - } - - h->object_base = new_chunk->contents; - h->next_free = h->object_base + obj_size; - /* The new chunk certainly contains no empty object yet. */ - h->maybe_empty_object = 0; -} - -/* Return nonzero if object OBJ has been allocated from obstack H. - This is here for debugging. - If you use it in a program, you are probably losing. */ - -#ifdef __STDC__ -/* Suppress -Wmissing-prototypes warning. We don't want to declare this in - obstack.h because it is just for debugging. */ -int _obstack_allocated_p (struct obstack *h, POINTER obj); -#endif - -int -_obstack_allocated_p (h, obj) - struct obstack *h; - POINTER obj; -{ - register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk* plp; /* point to previous chunk if any */ - - lp = (h)->chunk; - /* We use >= rather than > since the object cannot be exactly at - the beginning of the chunk but might be an empty object exactly - at the end of an adjacent chunk. */ - while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) - { - plp = lp->prev; - lp = plp; - } - return lp != 0; -} - -/* Free objects in obstack H, including OBJ and everything allocate - more recently than OBJ. If OBJ is zero, free everything in H. */ - -#undef obstack_free - -/* This function has two names with identical definitions. - This is the first one, called from non-ANSI code. */ - -void -_obstack_free (h, obj) - struct obstack *h; - POINTER obj; -{ - register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk* plp; /* point to previous chunk if any */ - - lp = h->chunk; - /* We use >= because there cannot be an object at the beginning of a chunk. - But there can be an empty object at that address - at the end of another chunk. */ - while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) - { - plp = lp->prev; - CALL_FREEFUN (h, lp); - lp = plp; - /* If we switch chunks, we can't tell whether the new current - chunk contains an empty object, so assume that it may. */ - h->maybe_empty_object = 1; - } - if (lp) - { - h->object_base = h->next_free = (char *)(obj); - h->chunk_limit = lp->limit; - h->chunk = lp; - } - else if (obj != 0) - /* obj is not in any of the chunks! */ - abort (); -} - -/* This function is used from ANSI code. */ - -void -obstack_free (h, obj) - struct obstack *h; - POINTER obj; -{ - register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk* plp; /* point to previous chunk if any */ - - lp = h->chunk; - /* We use >= because there cannot be an object at the beginning of a chunk. - But there can be an empty object at that address - at the end of another chunk. */ - while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) - { - plp = lp->prev; - CALL_FREEFUN (h, lp); - lp = plp; - /* If we switch chunks, we can't tell whether the new current - chunk contains an empty object, so assume that it may. */ - h->maybe_empty_object = 1; - } - if (lp) - { - h->object_base = h->next_free = (char *)(obj); - h->chunk_limit = lp->limit; - h->chunk = lp; - } - else if (obj != 0) - /* obj is not in any of the chunks! */ - abort (); -} - -int -_obstack_memory_used (h) - struct obstack *h; -{ - register struct _obstack_chunk* lp; - register int nbytes = 0; - - for (lp = h->chunk; lp != 0; lp = lp->prev) - { - nbytes += lp->limit - (char *) lp; - } - return nbytes; -} - -#if 0 -/* These are now turned off because the applications do not use it - and it uses bcopy via obstack_grow, which causes trouble on sysV. */ - -/* Now define the functional versions of the obstack macros. - Define them to simply use the corresponding macros to do the job. */ - -#ifdef __STDC__ -/* These function definitions do not work with non-ANSI preprocessors; - they won't pass through the macro names in parentheses. */ - -/* The function names appear in parentheses in order to prevent - the macro-definitions of the names from being expanded there. */ - -POINTER (obstack_base) (obstack) - struct obstack *obstack; -{ - return obstack_base (obstack); -} - -POINTER (obstack_next_free) (obstack) - struct obstack *obstack; -{ - return obstack_next_free (obstack); -} - -int (obstack_object_size) (obstack) - struct obstack *obstack; -{ - return obstack_object_size (obstack); -} - -int (obstack_room) (obstack) - struct obstack *obstack; -{ - return obstack_room (obstack); -} - -void (obstack_grow) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - obstack_grow (obstack, pointer, length); -} - -void (obstack_grow0) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - obstack_grow0 (obstack, pointer, length); -} - -void (obstack_1grow) (obstack, character) - struct obstack *obstack; - int character; -{ - obstack_1grow (obstack, character); -} - -void (obstack_blank) (obstack, length) - struct obstack *obstack; - int length; -{ - obstack_blank (obstack, length); -} - -void (obstack_1grow_fast) (obstack, character) - struct obstack *obstack; - int character; -{ - obstack_1grow_fast (obstack, character); -} - -void (obstack_blank_fast) (obstack, length) - struct obstack *obstack; - int length; -{ - obstack_blank_fast (obstack, length); -} - -POINTER (obstack_finish) (obstack) - struct obstack *obstack; -{ - return obstack_finish (obstack); -} - -POINTER (obstack_alloc) (obstack, length) - struct obstack *obstack; - int length; -{ - return obstack_alloc (obstack, length); -} - -POINTER (obstack_copy) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - return obstack_copy (obstack, pointer, length); -} - -POINTER (obstack_copy0) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - return obstack_copy0 (obstack, pointer, length); -} - -#endif /* __STDC__ */ - -#endif /* 0 */ - -#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/contrib/gdb/libiberty/random.c b/contrib/gdb/libiberty/random.c deleted file mode 100644 index e205719832b..00000000000 --- a/contrib/gdb/libiberty/random.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * This is derived from the Berkeley source: - * @(#)random.c 5.5 (Berkeley) 7/6/88 - * It was reworked for the GNU C Library by Roland McGrath. - */ - -#include - -#if 0 - -#include -#include -#include -#include - -#else - -#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF for 32-bits */ -#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits*/ - -#ifdef __STDC__ -# define PTR void * -# define NULL (void *) 0 -#else -# define PTR char * -# define NULL 0 -#endif - -#endif - -long int random (); - -/* An improved random number generation package. In addition to the standard - rand()/srand() like interface, this package also has a special state info - interface. The initstate() routine is called with a seed, an array of - bytes, and a count of how many bytes are being passed in; this array is - then initialized to contain information for random number generation with - that much state information. Good sizes for the amount of state - information are 32, 64, 128, and 256 bytes. The state can be switched by - calling the setstate() function with the same array as was initiallized - with initstate(). By default, the package runs with 128 bytes of state - information and generates far better random numbers than a linear - congruential generator. If the amount of state information is less than - 32 bytes, a simple linear congruential R.N.G. is used. Internally, the - state information is treated as an array of longs; the zeroeth element of - the array is the type of R.N.G. being used (small integer); the remainder - of the array is the state information for the R.N.G. Thus, 32 bytes of - state information will give 7 longs worth of state information, which will - allow a degree seven polynomial. (Note: The zeroeth word of state - information also has some other information stored in it; see setstate - for details). The random number generation technique is a linear feedback - shift register approach, employing trinomials (since there are fewer terms - to sum up that way). In this approach, the least significant bit of all - the numbers in the state table will act as a linear feedback shift register, - and will have period 2^deg - 1 (where deg is the degree of the polynomial - being used, assuming that the polynomial is irreducible and primitive). - The higher order bits will have longer periods, since their values are - also influenced by pseudo-random carries out of the lower bits. The - total period of the generator is approximately deg*(2**deg - 1); thus - doubling the amount of state information has a vast influence on the - period of the generator. Note: The deg*(2**deg - 1) is an approximation - only good for large deg, when the period of the shift register is the - dominant factor. With deg equal to seven, the period is actually much - longer than the 7*(2**7 - 1) predicted by this formula. */ - - - -/* For each of the currently supported random number generators, we have a - break value on the amount of state information (you need at least thi - bytes of state info to support this random number generator), a degree for - the polynomial (actually a trinomial) that the R.N.G. is based on, and - separation between the two lower order coefficients of the trinomial. */ - -/* Linear congruential. */ -#define TYPE_0 0 -#define BREAK_0 8 -#define DEG_0 0 -#define SEP_0 0 - -/* x**7 + x**3 + 1. */ -#define TYPE_1 1 -#define BREAK_1 32 -#define DEG_1 7 -#define SEP_1 3 - -/* x**15 + x + 1. */ -#define TYPE_2 2 -#define BREAK_2 64 -#define DEG_2 15 -#define SEP_2 1 - -/* x**31 + x**3 + 1. */ -#define TYPE_3 3 -#define BREAK_3 128 -#define DEG_3 31 -#define SEP_3 3 - -/* x**63 + x + 1. */ -#define TYPE_4 4 -#define BREAK_4 256 -#define DEG_4 63 -#define SEP_4 1 - - -/* Array versions of the above information to make code run faster. - Relies on fact that TYPE_i == i. */ - -#define MAX_TYPES 5 /* Max number of types above. */ - -static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; -static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; - - - -/* Initially, everything is set up as if from: - initstate(1, randtbl, 128); - Note that this initialization takes advantage of the fact that srandom - advances the front and rear pointers 10*rand_deg times, and hence the - rear pointer which starts at 0 will also end up at zero; thus the zeroeth - element of the state information, which contains info about the current - position of the rear pointer is just - (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */ - -static long int randtbl[DEG_3 + 1] = - { TYPE_3, - 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, - 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, - 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, - 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, - 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, - 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, - 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, - 0xf5ad9d0e, 0x8999220b, 0x27fb47b9 - }; - -/* FPTR and RPTR are two pointers into the state info, a front and a rear - pointer. These two pointers are always rand_sep places aparts, as they - cycle through the state information. (Yes, this does mean we could get - away with just one pointer, but the code for random is more efficient - this way). The pointers are left positioned as they would be from the call: - initstate(1, randtbl, 128); - (The position of the rear pointer, rptr, is really 0 (as explained above - in the initialization of randtbl) because the state table pointer is set - to point to randtbl[1] (as explained below).) */ - -static long int *fptr = &randtbl[SEP_3 + 1]; -static long int *rptr = &randtbl[1]; - - - -/* The following things are the pointer to the state information table, - the type of the current generator, the degree of the current polynomial - being used, and the separation between the two pointers. - Note that for efficiency of random, we remember the first location of - the state information, not the zeroeth. Hence it is valid to access - state[-1], which is used to store the type of the R.N.G. - Also, we remember the last location, since this is more efficient than - indexing every time to find the address of the last element to see if - the front and rear pointers have wrapped. */ - -static long int *state = &randtbl[1]; - -static int rand_type = TYPE_3; -static int rand_deg = DEG_3; -static int rand_sep = SEP_3; - -static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])]; - -/* Initialize the random number generator based on the given seed. If the - type is the trivial no-state-information type, just remember the seed. - Otherwise, initializes state[] based on the given "seed" via a linear - congruential generator. Then, the pointers are set to known locations - that are exactly rand_sep places apart. Lastly, it cycles the state - information a given number of times to get rid of any initial dependencies - introduced by the L.C.R.N.G. Note that the initialization of randtbl[] - for default usage relies on values produced by this routine. */ -void -srandom (x) - unsigned int x; -{ - state[0] = x; - if (rand_type != TYPE_0) - { - register long int i; - for (i = 1; i < rand_deg; ++i) - state[i] = (1103515145 * state[i - 1]) + 12345; - fptr = &state[rand_sep]; - rptr = &state[0]; - for (i = 0; i < 10 * rand_deg; ++i) - random(); - } -} - -/* Initialize the state information in the given array of N bytes for - future random number generation. Based on the number of bytes we - are given, and the break values for the different R.N.G.'s, we choose - the best (largest) one we can and set things up for it. srandom is - then called to initialize the state information. Note that on return - from srandom, we set state[-1] to be the type multiplexed with the current - value of the rear pointer; this is so successive calls to initstate won't - lose this information and will be able to restart with setstate. - Note: The first thing we do is save the current state, if any, just like - setstate so that it doesn't matter when initstate is called. - Returns a pointer to the old state. */ -PTR -initstate (seed, arg_state, n) - unsigned int seed; - PTR arg_state; - unsigned long n; -{ - PTR ostate = (PTR) &state[-1]; - - if (rand_type == TYPE_0) - state[-1] = rand_type; - else - state[-1] = (MAX_TYPES * (rptr - state)) + rand_type; - if (n < BREAK_1) - { - if (n < BREAK_0) - { - errno = EINVAL; - return NULL; - } - rand_type = TYPE_0; - rand_deg = DEG_0; - rand_sep = SEP_0; - } - else if (n < BREAK_2) - { - rand_type = TYPE_1; - rand_deg = DEG_1; - rand_sep = SEP_1; - } - else if (n < BREAK_3) - { - rand_type = TYPE_2; - rand_deg = DEG_2; - rand_sep = SEP_2; - } - else if (n < BREAK_4) - { - rand_type = TYPE_3; - rand_deg = DEG_3; - rand_sep = SEP_3; - } - else - { - rand_type = TYPE_4; - rand_deg = DEG_4; - rand_sep = SEP_4; - } - - state = &((long int *) arg_state)[1]; /* First location. */ - /* Must set END_PTR before srandom. */ - end_ptr = &state[rand_deg]; - srandom(seed); - if (rand_type == TYPE_0) - state[-1] = rand_type; - else - state[-1] = (MAX_TYPES * (rptr - state)) + rand_type; - - return ostate; -} - -/* Restore the state from the given state array. - Note: It is important that we also remember the locations of the pointers - in the current state information, and restore the locations of the pointers - from the old state information. This is done by multiplexing the pointer - location into the zeroeth word of the state information. Note that due - to the order in which things are done, it is OK to call setstate with the - same state as the current state - Returns a pointer to the old state information. */ - -PTR -setstate (arg_state) - PTR arg_state; -{ - register long int *new_state = (long int *) arg_state; - register int type = new_state[0] % MAX_TYPES; - register int rear = new_state[0] / MAX_TYPES; - PTR ostate = (PTR) &state[-1]; - - if (rand_type == TYPE_0) - state[-1] = rand_type; - else - state[-1] = (MAX_TYPES * (rptr - state)) + rand_type; - - switch (type) - { - case TYPE_0: - case TYPE_1: - case TYPE_2: - case TYPE_3: - case TYPE_4: - rand_type = type; - rand_deg = degrees[type]; - rand_sep = seps[type]; - break; - default: - /* State info munged. */ - errno = EINVAL; - return NULL; - } - - state = &new_state[1]; - if (rand_type != TYPE_0) - { - rptr = &state[rear]; - fptr = &state[(rear + rand_sep) % rand_deg]; - } - /* Set end_ptr too. */ - end_ptr = &state[rand_deg]; - - return ostate; -} - -/* If we are using the trivial TYPE_0 R.N.G., just do the old linear - congruential bit. Otherwise, we do our fancy trinomial stuff, which is the - same in all ther other cases due to all the global variables that have been - set up. The basic operation is to add the number at the rear pointer into - the one at the front pointer. Then both pointers are advanced to the next - location cyclically in the table. The value returned is the sum generated, - reduced to 31 bits by throwing away the "least random" low bit. - Note: The code takes advantage of the fact that both the front and - rear pointers can't wrap on the same call by not testing the rear - pointer if the front one has wrapped. Returns a 31-bit random number. */ - -long int -random () -{ - if (rand_type == TYPE_0) - { - state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX; - return state[0]; - } - else - { - long int i; - *fptr += *rptr; - /* Chucking least random bit. */ - i = (*fptr >> 1) & LONG_MAX; - ++fptr; - if (fptr >= end_ptr) - { - fptr = state; - ++rptr; - } - else - { - ++rptr; - if (rptr >= end_ptr) - rptr = state; - } - return i; - } -} diff --git a/contrib/gdb/libiberty/rename.c b/contrib/gdb/libiberty/rename.c deleted file mode 100644 index ae26e2d0040..00000000000 --- a/contrib/gdb/libiberty/rename.c +++ /dev/null @@ -1,22 +0,0 @@ -/* rename -- rename a file - This function is in the public domain. */ - -/* Rename a file. */ - -#include - -int -rename (zfrom, zto) - char *zfrom; - char *zto; -{ - if (link (zfrom, zto) < 0) - { - if (errno != EEXIST) - return -1; - if (unlink (zto) < 0 - || link (zfrom, zto) < 0) - return -1; - } - return unlink (zfrom); -} diff --git a/contrib/gdb/libiberty/rindex.c b/contrib/gdb/libiberty/rindex.c deleted file mode 100644 index 061d1269f17..00000000000 --- a/contrib/gdb/libiberty/rindex.c +++ /dev/null @@ -1,11 +0,0 @@ -/* Stub implementation of (obsolete) rindex(). */ - -extern char *strrchr (); - -char * -rindex (s, c) - char *s; - int c; -{ - return strrchr (s, c); -} diff --git a/contrib/gdb/libiberty/sigsetmask.c b/contrib/gdb/libiberty/sigsetmask.c deleted file mode 100644 index 2a09e6a6c5a..00000000000 --- a/contrib/gdb/libiberty/sigsetmask.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Version of sigsetmask.c - Written by Steve Chamberlain (sac@cygnus.com). - Contributed by Cygnus Support. - This file is in the public doamin. */ - -/* Set the current signal mask to the set provided, and return the - previous value */ - -#define _POSIX_SOURCE -#include -/* Including seems to be needed by ISC. */ -#include -#include - -#ifdef SIG_SETMASK -int -DEFUN(sigsetmask,(set), - int set) -{ - sigset_t new; - sigset_t old; - - sigemptyset (&new); - if (set != 0) { - abort(); /* FIXME, we don't know how to translate old mask to new */ - } - sigprocmask(SIG_SETMASK, &new, &old); - return 1; /* FIXME, we always return 1 as old value. */ -} -#endif diff --git a/contrib/gdb/libiberty/spaces.c b/contrib/gdb/libiberty/spaces.c deleted file mode 100644 index 7ea8532d7f6..00000000000 --- a/contrib/gdb/libiberty/spaces.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Allocate memory region filled with spaces. - Copyright (C) 1991 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* - -NAME - - spaces -- return a pointer to a buffer full of spaces - -SYNOPSIS - - char *spaces (int count) - -DESCRIPTION - - Returns a pointer to a memory region filled with the specified - number of spaces and null terminated. The returned pointer is - valid until at least the next call. - -BUGS - -*/ - -#include "ansidecl.h" -#include "libiberty.h" - -const char * -spaces (count) - int count; -{ - register char *t; - static char *buf; - static int maxsize; - extern char *malloc (); - extern void free (); - - if (count > maxsize) - { - if (buf) - { - free (buf); - } - buf = malloc (count + 1); - if (buf == (char *) 0) - return 0; - for (t = buf + count ; t != buf ; ) - { - *--t = ' '; - } - maxsize = count; - buf[count] = '\0'; - } - return (const char *) (buf + maxsize - count); -} - diff --git a/contrib/gdb/libiberty/strcasecmp.c b/contrib/gdb/libiberty/strcasecmp.c deleted file mode 100644 index 53387ca1b3e..00000000000 --- a/contrib/gdb/libiberty/strcasecmp.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is given - * to the University of California at Berkeley. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific written prior permission. This software - * is provided ``as is'' without express or implied warranty. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87"; -#endif /* LIBC_SCCS and not lint */ - -#include -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static unsigned char charmap[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', - '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', - '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', - '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', - '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', - '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', - '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', - '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', - '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', - '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', - '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', - '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', - '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', - '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', - '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', -}; - -int -strcasecmp(s1, s2) - const char *s1, *s2; -{ - register unsigned char u1, u2; - - for (;;) { - u1 = (unsigned char) *s1++; - u2 = (unsigned char) *s2++; - if (charmap[u1] != charmap[u2]) { - return charmap[u1] - charmap[u2]; - } - if (u1 == '\0') { - return 0; - } - } -} - diff --git a/contrib/gdb/libiberty/strchr.c b/contrib/gdb/libiberty/strchr.c deleted file mode 100644 index 22976ce248a..00000000000 --- a/contrib/gdb/libiberty/strchr.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Portable version of strchr() - This function is in the public domain. */ - -/* -NAME - strchr -- return pointer to first occurance of a character - -SYNOPSIS - char *strchr (const char *s, int c) - -DESCRIPTION - Returns a pointer to the first occurance of character C in - string S, or a NULL pointer if no occurance is found. - -BUGS - Behavior when character is the null character is implementation - dependent. -*/ - -#include - -char * -strchr (s, c) - register CONST char *s; - int c; -{ - do { - if (*s == c) - { - return (char*)s; - } - } while (*s++); - return (0); -} diff --git a/contrib/gdb/libiberty/strdup.c b/contrib/gdb/libiberty/strdup.c deleted file mode 100644 index 1785b34f274..00000000000 --- a/contrib/gdb/libiberty/strdup.c +++ /dev/null @@ -1,10 +0,0 @@ -char * -strdup(s) - char *s; -{ - char *result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} diff --git a/contrib/gdb/libiberty/strerror.c b/contrib/gdb/libiberty/strerror.c deleted file mode 100644 index 9f3f92b3d1a..00000000000 --- a/contrib/gdb/libiberty/strerror.c +++ /dev/null @@ -1,829 +0,0 @@ -/* Extended support for using errno values. - Written by Fred Fish. fnf@cygnus.com - This file is in the public domain. --Per Bothner. */ - -#include "ansidecl.h" -#include "libiberty.h" - -#include "config.h" - -#ifndef NEED_sys_errlist -/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least) - might declare sys_errlist in a way that the compiler might consider - incompatible with our later declaration, perhaps by using const - attributes. So we hide the declaration in errno.h (if any) using a - macro. */ -#define sys_errlist sys_errlist__ -#endif - -#include -#include - -#ifndef NEED_sys_errlist -#undef sys_errlist -#endif - -/* Routines imported from standard C runtime libraries. */ - -#ifdef __STDC__ -#include -extern void *malloc (size_t size); /* 4.10.3.3 */ -extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ -#else /* !__STDC__ */ -extern char *malloc (); /* Standard memory allocater */ -extern char *memset (); -#endif /* __STDC__ */ - -#ifndef MAX -# define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -/* Translation table for errno values. See intro(2) in most UNIX systems - Programmers Reference Manuals. - - Note that this table is generally only accessed when it is used at runtime - to initialize errno name and message tables that are indexed by errno - value. - - Not all of these errnos will exist on all systems. This table is the only - thing that should have to be updated as new error numbers are introduced. - It's sort of ugly, but at least its portable. */ - -struct error_info -{ - int value; /* The numeric value from */ - const char *name; /* The equivalent symbolic value */ -#ifdef NEED_sys_errlist - const char *msg; /* Short message about this value */ -#endif -}; - -#ifdef NEED_sys_errlist -# define ENTRY(value, name, msg) {value, name, msg} -#else -# define ENTRY(value, name, msg) {value, name} -#endif - -static const struct error_info error_table[] = -{ -#if defined (EPERM) - ENTRY(EPERM, "EPERM", "Not owner"), -#endif -#if defined (ENOENT) - ENTRY(ENOENT, "ENOENT", "No such file or directory"), -#endif -#if defined (ESRCH) - ENTRY(ESRCH, "ESRCH", "No such process"), -#endif -#if defined (EINTR) - ENTRY(EINTR, "EINTR", "Interrupted system call"), -#endif -#if defined (EIO) - ENTRY(EIO, "EIO", "I/O error"), -#endif -#if defined (ENXIO) - ENTRY(ENXIO, "ENXIO", "No such device or address"), -#endif -#if defined (E2BIG) - ENTRY(E2BIG, "E2BIG", "Arg list too long"), -#endif -#if defined (ENOEXEC) - ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"), -#endif -#if defined (EBADF) - ENTRY(EBADF, "EBADF", "Bad file number"), -#endif -#if defined (ECHILD) - ENTRY(ECHILD, "ECHILD", "No child processes"), -#endif -#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */ - ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"), -#endif -#if defined (EAGAIN) - ENTRY(EAGAIN, "EAGAIN", "No more processes"), -#endif -#if defined (ENOMEM) - ENTRY(ENOMEM, "ENOMEM", "Not enough space"), -#endif -#if defined (EACCES) - ENTRY(EACCES, "EACCES", "Permission denied"), -#endif -#if defined (EFAULT) - ENTRY(EFAULT, "EFAULT", "Bad address"), -#endif -#if defined (ENOTBLK) - ENTRY(ENOTBLK, "ENOTBLK", "Block device required"), -#endif -#if defined (EBUSY) - ENTRY(EBUSY, "EBUSY", "Device busy"), -#endif -#if defined (EEXIST) - ENTRY(EEXIST, "EEXIST", "File exists"), -#endif -#if defined (EXDEV) - ENTRY(EXDEV, "EXDEV", "Cross-device link"), -#endif -#if defined (ENODEV) - ENTRY(ENODEV, "ENODEV", "No such device"), -#endif -#if defined (ENOTDIR) - ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"), -#endif -#if defined (EISDIR) - ENTRY(EISDIR, "EISDIR", "Is a directory"), -#endif -#if defined (EINVAL) - ENTRY(EINVAL, "EINVAL", "Invalid argument"), -#endif -#if defined (ENFILE) - ENTRY(ENFILE, "ENFILE", "File table overflow"), -#endif -#if defined (EMFILE) - ENTRY(EMFILE, "EMFILE", "Too many open files"), -#endif -#if defined (ENOTTY) - ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"), -#endif -#if defined (ETXTBSY) - ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"), -#endif -#if defined (EFBIG) - ENTRY(EFBIG, "EFBIG", "File too large"), -#endif -#if defined (ENOSPC) - ENTRY(ENOSPC, "ENOSPC", "No space left on device"), -#endif -#if defined (ESPIPE) - ENTRY(ESPIPE, "ESPIPE", "Illegal seek"), -#endif -#if defined (EROFS) - ENTRY(EROFS, "EROFS", "Read-only file system"), -#endif -#if defined (EMLINK) - ENTRY(EMLINK, "EMLINK", "Too many links"), -#endif -#if defined (EPIPE) - ENTRY(EPIPE, "EPIPE", "Broken pipe"), -#endif -#if defined (EDOM) - ENTRY(EDOM, "EDOM", "Math argument out of domain of func"), -#endif -#if defined (ERANGE) - ENTRY(ERANGE, "ERANGE", "Math result not representable"), -#endif -#if defined (ENOMSG) - ENTRY(ENOMSG, "ENOMSG", "No message of desired type"), -#endif -#if defined (EIDRM) - ENTRY(EIDRM, "EIDRM", "Identifier removed"), -#endif -#if defined (ECHRNG) - ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"), -#endif -#if defined (EL2NSYNC) - ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"), -#endif -#if defined (EL3HLT) - ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"), -#endif -#if defined (EL3RST) - ENTRY(EL3RST, "EL3RST", "Level 3 reset"), -#endif -#if defined (ELNRNG) - ENTRY(ELNRNG, "ELNRNG", "Link number out of range"), -#endif -#if defined (EUNATCH) - ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"), -#endif -#if defined (ENOCSI) - ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"), -#endif -#if defined (EL2HLT) - ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"), -#endif -#if defined (EDEADLK) - ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"), -#endif -#if defined (ENOLCK) - ENTRY(ENOLCK, "ENOLCK", "No record locks available"), -#endif -#if defined (EBADE) - ENTRY(EBADE, "EBADE", "Invalid exchange"), -#endif -#if defined (EBADR) - ENTRY(EBADR, "EBADR", "Invalid request descriptor"), -#endif -#if defined (EXFULL) - ENTRY(EXFULL, "EXFULL", "Exchange full"), -#endif -#if defined (ENOANO) - ENTRY(ENOANO, "ENOANO", "No anode"), -#endif -#if defined (EBADRQC) - ENTRY(EBADRQC, "EBADRQC", "Invalid request code"), -#endif -#if defined (EBADSLT) - ENTRY(EBADSLT, "EBADSLT", "Invalid slot"), -#endif -#if defined (EDEADLOCK) - ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"), -#endif -#if defined (EBFONT) - ENTRY(EBFONT, "EBFONT", "Bad font file format"), -#endif -#if defined (ENOSTR) - ENTRY(ENOSTR, "ENOSTR", "Device not a stream"), -#endif -#if defined (ENODATA) - ENTRY(ENODATA, "ENODATA", "No data available"), -#endif -#if defined (ETIME) - ENTRY(ETIME, "ETIME", "Timer expired"), -#endif -#if defined (ENOSR) - ENTRY(ENOSR, "ENOSR", "Out of streams resources"), -#endif -#if defined (ENONET) - ENTRY(ENONET, "ENONET", "Machine is not on the network"), -#endif -#if defined (ENOPKG) - ENTRY(ENOPKG, "ENOPKG", "Package not installed"), -#endif -#if defined (EREMOTE) - ENTRY(EREMOTE, "EREMOTE", "Object is remote"), -#endif -#if defined (ENOLINK) - ENTRY(ENOLINK, "ENOLINK", "Link has been severed"), -#endif -#if defined (EADV) - ENTRY(EADV, "EADV", "Advertise error"), -#endif -#if defined (ESRMNT) - ENTRY(ESRMNT, "ESRMNT", "Srmount error"), -#endif -#if defined (ECOMM) - ENTRY(ECOMM, "ECOMM", "Communication error on send"), -#endif -#if defined (EPROTO) - ENTRY(EPROTO, "EPROTO", "Protocol error"), -#endif -#if defined (EMULTIHOP) - ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"), -#endif -#if defined (EDOTDOT) - ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"), -#endif -#if defined (EBADMSG) - ENTRY(EBADMSG, "EBADMSG", "Not a data message"), -#endif -#if defined (ENAMETOOLONG) - ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"), -#endif -#if defined (EOVERFLOW) - ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"), -#endif -#if defined (ENOTUNIQ) - ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"), -#endif -#if defined (EBADFD) - ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"), -#endif -#if defined (EREMCHG) - ENTRY(EREMCHG, "EREMCHG", "Remote address changed"), -#endif -#if defined (ELIBACC) - ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"), -#endif -#if defined (ELIBBAD) - ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"), -#endif -#if defined (ELIBSCN) - ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"), -#endif -#if defined (ELIBMAX) - ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"), -#endif -#if defined (ELIBEXEC) - ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"), -#endif -#if defined (EILSEQ) - ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"), -#endif -#if defined (ENOSYS) - ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"), -#endif -#if defined (ELOOP) - ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"), -#endif -#if defined (ERESTART) - ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"), -#endif -#if defined (ESTRPIPE) - ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"), -#endif -#if defined (ENOTEMPTY) - ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"), -#endif -#if defined (EUSERS) - ENTRY(EUSERS, "EUSERS", "Too many users"), -#endif -#if defined (ENOTSOCK) - ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"), -#endif -#if defined (EDESTADDRREQ) - ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"), -#endif -#if defined (EMSGSIZE) - ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"), -#endif -#if defined (EPROTOTYPE) - ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"), -#endif -#if defined (ENOPROTOOPT) - ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"), -#endif -#if defined (EPROTONOSUPPORT) - ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"), -#endif -#if defined (ESOCKTNOSUPPORT) - ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"), -#endif -#if defined (EOPNOTSUPP) - ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"), -#endif -#if defined (EPFNOSUPPORT) - ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"), -#endif -#if defined (EAFNOSUPPORT) - ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"), -#endif -#if defined (EADDRINUSE) - ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"), -#endif -#if defined (EADDRNOTAVAIL) - ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"), -#endif -#if defined (ENETDOWN) - ENTRY(ENETDOWN, "ENETDOWN", "Network is down"), -#endif -#if defined (ENETUNREACH) - ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"), -#endif -#if defined (ENETRESET) - ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"), -#endif -#if defined (ECONNABORTED) - ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"), -#endif -#if defined (ECONNRESET) - ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"), -#endif -#if defined (ENOBUFS) - ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"), -#endif -#if defined (EISCONN) - ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"), -#endif -#if defined (ENOTCONN) - ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"), -#endif -#if defined (ESHUTDOWN) - ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"), -#endif -#if defined (ETOOMANYREFS) - ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"), -#endif -#if defined (ETIMEDOUT) - ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"), -#endif -#if defined (ECONNREFUSED) - ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"), -#endif -#if defined (EHOSTDOWN) - ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"), -#endif -#if defined (EHOSTUNREACH) - ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"), -#endif -#if defined (EALREADY) - ENTRY(EALREADY, "EALREADY", "Operation already in progress"), -#endif -#if defined (EINPROGRESS) - ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"), -#endif -#if defined (ESTALE) - ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"), -#endif -#if defined (EUCLEAN) - ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"), -#endif -#if defined (ENOTNAM) - ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"), -#endif -#if defined (ENAVAIL) - ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"), -#endif -#if defined (EISNAM) - ENTRY(EISNAM, "EISNAM", "Is a named type file"), -#endif -#if defined (EREMOTEIO) - ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"), -#endif - ENTRY(0, NULL, NULL) -}; - -#ifdef EVMSERR -/* This is not in the table, because the numeric value of EVMSERR (32767) - lies outside the range of sys_errlist[]. */ -static struct { int value; const char *name, *msg; } - evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" }; -#endif - -/* Translation table allocated and initialized at runtime. Indexed by the - errno value to find the equivalent symbolic value. */ - -static const char **error_names; -static int num_error_names = 0; - -/* Translation table allocated and initialized at runtime, if it does not - already exist in the host environment. Indexed by the errno value to find - the descriptive string. - - We don't export it for use in other modules because even though it has the - same name, it differs from other implementations in that it is dynamically - initialized rather than statically initialized. */ - -#ifdef NEED_sys_errlist - -static int sys_nerr; -static const char **sys_errlist; - -#else - -extern int sys_nerr; -extern char *sys_errlist[]; - -#endif - - -/* - -NAME - - init_error_tables -- initialize the name and message tables - -SYNOPSIS - - static void init_error_tables (); - -DESCRIPTION - - Using the error_table, which is initialized at compile time, generate - the error_names and the sys_errlist (if needed) tables, which are - indexed at runtime by a specific errno value. - -BUGS - - The initialization of the tables may fail under low memory conditions, - in which case we don't do anything particularly useful, but we don't - bomb either. Who knows, it might succeed at a later point if we free - some memory in the meantime. In any case, the other routines know - how to deal with lack of a table after trying to initialize it. This - may or may not be considered to be a bug, that we don't specifically - warn about this particular failure mode. - -*/ - -static void -init_error_tables () -{ - const struct error_info *eip; - int nbytes; - - /* If we haven't already scanned the error_table once to find the maximum - errno value, then go find it now. */ - - if (num_error_names == 0) - { - for (eip = error_table; eip -> name != NULL; eip++) - { - if (eip -> value >= num_error_names) - { - num_error_names = eip -> value + 1; - } - } - } - - /* Now attempt to allocate the error_names table, zero it out, and then - initialize it from the statically initialized error_table. */ - - if (error_names == NULL) - { - nbytes = num_error_names * sizeof (char *); - if ((error_names = (const char **) malloc (nbytes)) != NULL) - { - memset (error_names, 0, nbytes); - for (eip = error_table; eip -> name != NULL; eip++) - { - error_names[eip -> value] = eip -> name; - } - } - } - -#ifdef NEED_sys_errlist - - /* Now attempt to allocate the sys_errlist table, zero it out, and then - initialize it from the statically initialized error_table. */ - - if (sys_errlist == NULL) - { - nbytes = num_error_names * sizeof (char *); - if ((sys_errlist = (const char **) malloc (nbytes)) != NULL) - { - memset (sys_errlist, 0, nbytes); - sys_nerr = num_error_names; - for (eip = error_table; eip -> name != NULL; eip++) - { - sys_errlist[eip -> value] = eip -> msg; - } - } - } - -#endif - -} - -/* - -NAME - - errno_max -- return the max errno value - -SYNOPSIS - - int errno_max (); - -DESCRIPTION - - Returns the maximum errno value for which a corresponding symbolic - name or message is available. Note that in the case where - we use the sys_errlist supplied by the system, it is possible for - there to be more symbolic names than messages, or vice versa. - In fact, the manual page for perror(3C) explicitly warns that one - should check the size of the table (sys_nerr) before indexing it, - since new error codes may be added to the system before they are - added to the table. Thus sys_nerr might be smaller than value - implied by the largest errno value defined in . - - We return the maximum value that can be used to obtain a meaningful - symbolic name or message. - -*/ - -int -errno_max () -{ - int maxsize; - - if (error_names == NULL) - { - init_error_tables (); - } - maxsize = MAX (sys_nerr, num_error_names); - return (maxsize - 1); -} - -#ifdef NEED_strerror - -/* - -NAME - - strerror -- map an error number to an error message string - -SYNOPSIS - - char *strerror (int errnoval) - -DESCRIPTION - - Maps an errno number to an error message string, the contents of - which are implementation defined. On systems which have the external - variables sys_nerr and sys_errlist, these strings will be the same - as the ones used by perror(). - - If the supplied error number is within the valid range of indices - for the sys_errlist, but no message is available for the particular - error number, then returns the string "Error NUM", where NUM is the - error number. - - If the supplied error number is not a valid index into sys_errlist, - returns NULL. - - The returned string is only guaranteed to be valid only until the - next call to strerror. - -*/ - -char * -strerror (errnoval) - int errnoval; -{ - char *msg; - static char buf[32]; - -#ifdef NEED_sys_errlist - - if (error_names == NULL) - { - init_error_tables (); - } - -#endif - - if ((errnoval < 0) || (errnoval >= sys_nerr)) - { -#ifdef EVMSERR - if (errnoval == evmserr.value) - msg = evmserr.msg; - else -#endif - /* Out of range, just return NULL */ - msg = NULL; - } - else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL)) - { - /* In range, but no sys_errlist or no entry at this index. */ - sprintf (buf, "Error %d", errnoval); - msg = buf; - } - else - { - /* In range, and a valid message. Just return the message. */ - msg = (char *) sys_errlist[errnoval]; - } - - return (msg); -} - -#endif /* NEED_strerror */ - - -/* - -NAME - - strerrno -- map an error number to a symbolic name string - -SYNOPSIS - - const char *strerrno (int errnoval) - -DESCRIPTION - - Given an error number returned from a system call (typically - returned in errno), returns a pointer to a string containing the - symbolic name of that error number, as found in . - - If the supplied error number is within the valid range of indices - for symbolic names, but no name is available for the particular - error number, then returns the string "Error NUM", where NUM is - the error number. - - If the supplied error number is not within the range of valid - indices, then returns NULL. - -BUGS - - The contents of the location pointed to are only guaranteed to be - valid until the next call to strerrno. - -*/ - -const char * -strerrno (errnoval) - int errnoval; -{ - const char *name; - static char buf[32]; - - if (error_names == NULL) - { - init_error_tables (); - } - - if ((errnoval < 0) || (errnoval >= num_error_names)) - { -#ifdef EVMSERR - if (errnoval == evmserr.value) - name = evmserr.name; - else -#endif - /* Out of range, just return NULL */ - name = NULL; - } - else if ((error_names == NULL) || (error_names[errnoval] == NULL)) - { - /* In range, but no error_names or no entry at this index. */ - sprintf (buf, "Error %d", errnoval); - name = (const char *) buf; - } - else - { - /* In range, and a valid name. Just return the name. */ - name = error_names[errnoval]; - } - - return (name); -} - -/* - -NAME - - strtoerrno -- map a symbolic errno name to a numeric value - -SYNOPSIS - - int strtoerrno (char *name) - -DESCRIPTION - - Given the symbolic name of a error number, map it to an errno value. - If no translation is found, returns 0. - -*/ - -int -strtoerrno (name) - const char *name; -{ - int errnoval = 0; - - if (name != NULL) - { - if (error_names == NULL) - { - init_error_tables (); - } - for (errnoval = 0; errnoval < num_error_names; errnoval++) - { - if ((error_names[errnoval] != NULL) && - (strcmp (name, error_names[errnoval]) == 0)) - { - break; - } - } - if (errnoval == num_error_names) - { -#ifdef EVMSERR - if (strcmp (name, evmserr.name) == 0) - errnoval = evmserr.value; - else -#endif - errnoval = 0; - } - } - return (errnoval); -} - - -/* A simple little main that does nothing but print all the errno translations - if MAIN is defined and this file is compiled and linked. */ - -#ifdef MAIN - -#include - -int -main () -{ - int errn; - int errnmax; - const char *name; - char *msg; - char *strerror (); - - errnmax = errno_max (); - printf ("%d entries in names table.\n", num_error_names); - printf ("%d entries in messages table.\n", sys_nerr); - printf ("%d is max useful index.\n", errnmax); - - /* Keep printing values until we get to the end of *both* tables, not - *either* table. Note that knowing the maximum useful index does *not* - relieve us of the responsibility of testing the return pointer for - NULL. */ - - for (errn = 0; errn <= errnmax; errn++) - { - name = strerrno (errn); - name = (name == NULL) ? "" : name; - msg = strerror (errn); - msg = (msg == NULL) ? "" : msg; - printf ("%-4d%-18s%s\n", errn, name, msg); - } - - return 0; -} - -#endif diff --git a/contrib/gdb/libiberty/strncasecmp.c b/contrib/gdb/libiberty/strncasecmp.c deleted file mode 100644 index 4485cac7a6a..00000000000 --- a/contrib/gdb/libiberty/strncasecmp.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is given - * to the University of California at Berkeley. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific written prior permission. This software - * is provided ``as is'' without express or implied warranty. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87"; -#endif /* LIBC_SCCS and not lint */ - -#include -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static unsigned char charmap[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', - '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', - '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', - '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', - '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', - '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', - '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', - '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', - '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', - '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', - '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', - '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', - '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', - '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', - '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', -}; - -int -strncasecmp(s1, s2, n) - const char *s1, *s2; - register size_t n; -{ - register unsigned char u1, u2; - - for (; n != 0; --n) { - u1 = (unsigned char) *s1++; - u2 = (unsigned char) *s2++; - if (charmap[u1] != charmap[u2]) { - return charmap[u1] - charmap[u2]; - } - if (u1 == '\0') { - return 0; - } - } - return 0; -} diff --git a/contrib/gdb/libiberty/strrchr.c b/contrib/gdb/libiberty/strrchr.c deleted file mode 100644 index 30f9e8a3658..00000000000 --- a/contrib/gdb/libiberty/strrchr.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Portable version of strrchr(). - This function is in the public domain. */ - -/* -NAME - strrchr -- return pointer to last occurance of a character - -SYNOPSIS - char *strrchr (const char *s, int c) - -DESCRIPTION - Returns a pointer to the last occurance of character C in - string S, or a NULL pointer if no occurance is found. - -BUGS - Behavior when character is the null character is implementation - dependent. -*/ - -#include - -char * -strrchr (s, c) - register CONST char *s; - int c; -{ - char *rtnval = 0; - - do { - if (*s == c) - rtnval = (char*) s; - } while (*s++); - return (rtnval); -} diff --git a/contrib/gdb/libiberty/strsignal.c b/contrib/gdb/libiberty/strsignal.c deleted file mode 100644 index c4dd63c8098..00000000000 --- a/contrib/gdb/libiberty/strsignal.c +++ /dev/null @@ -1,627 +0,0 @@ -/* Extended support for using signal values. - Written by Fred Fish. fnf@cygnus.com - This file is in the public domain. */ - -#include "ansidecl.h" -#include "libiberty.h" - -#include "config.h" - -#ifdef LOSING_SYS_SIGLIST -#define sys_siglist no_such_symbol -#endif - -#include -#include - -/* Routines imported from standard C runtime libraries. */ - -#ifdef __STDC__ -#include -extern void *malloc (size_t size); /* 4.10.3.3 */ -extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ -#else /* !__STDC__ */ -extern char *malloc (); /* Standard memory allocater */ -extern char *memset (); -#endif /* __STDC__ */ - -#ifdef LOSING_SYS_SIGLIST -#undef sys_siglist -#endif - - -#ifndef NULL -# ifdef __STDC__ -# define NULL (void *) 0 -# else -# define NULL 0 -# endif -#endif - -#ifndef MAX -# define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -/* Translation table for signal values. - - Note that this table is generally only accessed when it is used at runtime - to initialize signal name and message tables that are indexed by signal - value. - - Not all of these signals will exist on all systems. This table is the only - thing that should have to be updated as new signal numbers are introduced. - It's sort of ugly, but at least its portable. */ - -struct signal_info -{ - int value; /* The numeric value from */ - const char *name; /* The equivalent symbolic value */ -#ifdef NEED_sys_siglist - const char *msg; /* Short message about this value */ -#endif -}; - -#ifdef NEED_sys_siglist -# define ENTRY(value, name, msg) {value, name, msg} -#else -# define ENTRY(value, name, msg) {value, name} -#endif - -static const struct signal_info signal_table[] = -{ -#if defined (SIGHUP) - ENTRY(SIGHUP, "SIGHUP", "Hangup"), -#endif -#if defined (SIGINT) - ENTRY(SIGINT, "SIGINT", "Interrupt"), -#endif -#if defined (SIGQUIT) - ENTRY(SIGQUIT, "SIGQUIT", "Quit"), -#endif -#if defined (SIGILL) - ENTRY(SIGILL, "SIGILL", "Illegal instruction"), -#endif -#if defined (SIGTRAP) - ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"), -#endif -/* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT - overrides SIGIOT. SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */ -#if defined (SIGIOT) - ENTRY(SIGIOT, "SIGIOT", "IOT trap"), -#endif -#if defined (SIGABRT) - ENTRY(SIGABRT, "SIGABRT", "Aborted"), -#endif -#if defined (SIGEMT) - ENTRY(SIGEMT, "SIGEMT", "Emulation trap"), -#endif -#if defined (SIGFPE) - ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"), -#endif -#if defined (SIGKILL) - ENTRY(SIGKILL, "SIGKILL", "Killed"), -#endif -#if defined (SIGBUS) - ENTRY(SIGBUS, "SIGBUS", "Bus error"), -#endif -#if defined (SIGSEGV) - ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"), -#endif -#if defined (SIGSYS) - ENTRY(SIGSYS, "SIGSYS", "Bad system call"), -#endif -#if defined (SIGPIPE) - ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"), -#endif -#if defined (SIGALRM) - ENTRY(SIGALRM, "SIGALRM", "Alarm clock"), -#endif -#if defined (SIGTERM) - ENTRY(SIGTERM, "SIGTERM", "Terminated"), -#endif -#if defined (SIGUSR1) - ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"), -#endif -#if defined (SIGUSR2) - ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"), -#endif -/* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD - overrides SIGCLD. SIGCHLD is in POXIX.1 */ -#if defined (SIGCLD) - ENTRY(SIGCLD, "SIGCLD", "Child status changed"), -#endif -#if defined (SIGCHLD) - ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"), -#endif -#if defined (SIGPWR) - ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"), -#endif -#if defined (SIGWINCH) - ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"), -#endif -#if defined (SIGURG) - ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"), -#endif -#if defined (SIGIO) - /* "I/O pending" has also been suggested, but is misleading since the - signal only happens when the process has asked for it, not everytime - I/O is pending. */ - ENTRY(SIGIO, "SIGIO", "I/O possible"), -#endif -#if defined (SIGPOLL) - ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"), -#endif -#if defined (SIGSTOP) - ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"), -#endif -#if defined (SIGTSTP) - ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"), -#endif -#if defined (SIGCONT) - ENTRY(SIGCONT, "SIGCONT", "Continued"), -#endif -#if defined (SIGTTIN) - ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"), -#endif -#if defined (SIGTTOU) - ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"), -#endif -#if defined (SIGVTALRM) - ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"), -#endif -#if defined (SIGPROF) - ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"), -#endif -#if defined (SIGXCPU) - ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"), -#endif -#if defined (SIGXFSZ) - ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"), -#endif -#if defined (SIGWIND) - ENTRY(SIGWIND, "SIGWIND", "SIGWIND"), -#endif -#if defined (SIGPHONE) - ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"), -#endif -#if defined (SIGLOST) - ENTRY(SIGLOST, "SIGLOST", "Resource lost"), -#endif -#if defined (SIGWAITING) - ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"), -#endif -#if defined (SIGLWP) - ENTRY(SIGLWP, "SIGLWP", "Signal LWP"), -#endif -#if defined (SIGDANGER) - ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"), -#endif -#if defined (SIGGRANT) - ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"), -#endif -#if defined (SIGRETRACT) - ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"), -#endif -#if defined (SIGMSG) - ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"), -#endif -#if defined (SIGSOUND) - ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"), -#endif -#if defined (SIGSAK) - ENTRY(SIGSAK, "SIGSAK", "Secure attention"), -#endif - ENTRY(0, NULL, NULL) -}; - -/* Translation table allocated and initialized at runtime. Indexed by the - signal value to find the equivalent symbolic value. */ - -static const char **signal_names; -static int num_signal_names = 0; - -/* Translation table allocated and initialized at runtime, if it does not - already exist in the host environment. Indexed by the signal value to find - the descriptive string. - - We don't export it for use in other modules because even though it has the - same name, it differs from other implementations in that it is dynamically - initialized rather than statically initialized. */ - -#ifdef NEED_sys_siglist - -static int sys_nsig; -static const char **sys_siglist; - -#else - -static int sys_nsig = NSIG; -extern const char * const sys_siglist[]; - -#endif - - -/* - -NAME - - init_signal_tables -- initialize the name and message tables - -SYNOPSIS - - static void init_signal_tables (); - -DESCRIPTION - - Using the signal_table, which is initialized at compile time, generate - the signal_names and the sys_siglist (if needed) tables, which are - indexed at runtime by a specific signal value. - -BUGS - - The initialization of the tables may fail under low memory conditions, - in which case we don't do anything particularly useful, but we don't - bomb either. Who knows, it might succeed at a later point if we free - some memory in the meantime. In any case, the other routines know - how to deal with lack of a table after trying to initialize it. This - may or may not be considered to be a bug, that we don't specifically - warn about this particular failure mode. - -*/ - -static void -init_signal_tables () -{ - const struct signal_info *eip; - int nbytes; - - /* If we haven't already scanned the signal_table once to find the maximum - signal value, then go find it now. */ - - if (num_signal_names == 0) - { - for (eip = signal_table; eip -> name != NULL; eip++) - { - if (eip -> value >= num_signal_names) - { - num_signal_names = eip -> value + 1; - } - } - } - - /* Now attempt to allocate the signal_names table, zero it out, and then - initialize it from the statically initialized signal_table. */ - - if (signal_names == NULL) - { - nbytes = num_signal_names * sizeof (char *); - if ((signal_names = (const char **) malloc (nbytes)) != NULL) - { - memset (signal_names, 0, nbytes); - for (eip = signal_table; eip -> name != NULL; eip++) - { - signal_names[eip -> value] = eip -> name; - } - } - } - -#ifdef NEED_sys_siglist - - /* Now attempt to allocate the sys_siglist table, zero it out, and then - initialize it from the statically initialized signal_table. */ - - if (sys_siglist == NULL) - { - nbytes = num_signal_names * sizeof (char *); - if ((sys_siglist = (const char **) malloc (nbytes)) != NULL) - { - memset (sys_siglist, 0, nbytes); - sys_nsig = num_signal_names; - for (eip = signal_table; eip -> name != NULL; eip++) - { - sys_siglist[eip -> value] = eip -> msg; - } - } - } - -#endif - -} - - -/* - -NAME - - signo_max -- return the max signo value - -SYNOPSIS - - int signo_max (); - -DESCRIPTION - - Returns the maximum signo value for which a corresponding symbolic - name or message is available. Note that in the case where - we use the sys_siglist supplied by the system, it is possible for - there to be more symbolic names than messages, or vice versa. - In fact, the manual page for psignal(3b) explicitly warns that one - should check the size of the table (NSIG) before indexing it, - since new signal codes may be added to the system before they are - added to the table. Thus NSIG might be smaller than value - implied by the largest signo value defined in . - - We return the maximum value that can be used to obtain a meaningful - symbolic name or message. - -*/ - -int -signo_max () -{ - int maxsize; - - if (signal_names == NULL) - { - init_signal_tables (); - } - maxsize = MAX (sys_nsig, num_signal_names); - return (maxsize - 1); -} - - -/* - -NAME - - strsignal -- map a signal number to a signal message string - -SYNOPSIS - - const char *strsignal (int signo) - -DESCRIPTION - - Maps an signal number to an signal message string, the contents of - which are implementation defined. On systems which have the external - variable sys_siglist, these strings will be the same as the ones used - by psignal(). - - If the supplied signal number is within the valid range of indices - for the sys_siglist, but no message is available for the particular - signal number, then returns the string "Signal NUM", where NUM is the - signal number. - - If the supplied signal number is not a valid index into sys_siglist, - returns NULL. - - The returned string is only guaranteed to be valid only until the - next call to strsignal. - -*/ - -const char * -strsignal (signo) - int signo; -{ - const char *msg; - static char buf[32]; - -#ifdef NEED_sys_siglist - - if (signal_names == NULL) - { - init_signal_tables (); - } - -#endif - - if ((signo < 0) || (signo >= sys_nsig)) - { - /* Out of range, just return NULL */ - msg = NULL; - } - else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL)) - { - /* In range, but no sys_siglist or no entry at this index. */ - sprintf (buf, "Signal %d", signo); - msg = (const char *) buf; - } - else - { - /* In range, and a valid message. Just return the message. */ - msg = (const char *) sys_siglist[signo]; - } - - return (msg); -} - - -/* - -NAME - - strsigno -- map an signal number to a symbolic name string - -SYNOPSIS - - const char *strsigno (int signo) - -DESCRIPTION - - Given an signal number, returns a pointer to a string containing - the symbolic name of that signal number, as found in . - - If the supplied signal number is within the valid range of indices - for symbolic names, but no name is available for the particular - signal number, then returns the string "Signal NUM", where NUM is - the signal number. - - If the supplied signal number is not within the range of valid - indices, then returns NULL. - -BUGS - - The contents of the location pointed to are only guaranteed to be - valid until the next call to strsigno. - -*/ - -const char * -strsigno (signo) - int signo; -{ - const char *name; - static char buf[32]; - - if (signal_names == NULL) - { - init_signal_tables (); - } - - if ((signo < 0) || (signo >= num_signal_names)) - { - /* Out of range, just return NULL */ - name = NULL; - } - else if ((signal_names == NULL) || (signal_names[signo] == NULL)) - { - /* In range, but no signal_names or no entry at this index. */ - sprintf (buf, "Signal %d", signo); - name = (const char *) buf; - } - else - { - /* In range, and a valid name. Just return the name. */ - name = signal_names[signo]; - } - - return (name); -} - - -/* - -NAME - - strtosigno -- map a symbolic signal name to a numeric value - -SYNOPSIS - - int strtosigno (char *name) - -DESCRIPTION - - Given the symbolic name of a signal, map it to a signal number. - If no translation is found, returns 0. - -*/ - -int -strtosigno (name) - const char *name; -{ - int signo = 0; - - if (name != NULL) - { - if (signal_names == NULL) - { - init_signal_tables (); - } - for (signo = 0; signo < num_signal_names; signo++) - { - if ((signal_names[signo] != NULL) && - (strcmp (name, signal_names[signo]) == 0)) - { - break; - } - } - if (signo == num_signal_names) - { - signo = 0; - } - } - return (signo); -} - - -/* - -NAME - - psignal -- print message about signal to stderr - -SYNOPSIS - - void psignal (unsigned signo, char *message); - -DESCRIPTION - - Print to the standard error the message, followed by a colon, - followed by the description of the signal specified by signo, - followed by a newline. -*/ - -#ifdef NEED_psignal - -void -psignal (signo, message) - unsigned signo; - char *message; -{ - if (signal_names == NULL) - { - init_signal_tables (); - } - if ((signo <= 0) || (signo >= sys_nsig)) - { - fprintf (stderr, "%s: unknown signal\n", message); - } - else - { - fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]); - } -} - -#endif /* NEED_psignal */ - - -/* A simple little main that does nothing but print all the signal translations - if MAIN is defined and this file is compiled and linked. */ - -#ifdef MAIN - -#include - -int -main () -{ - int signo; - int maxsigno; - const char *name; - const char *msg; - - maxsigno = signo_max (); - printf ("%d entries in names table.\n", num_signal_names); - printf ("%d entries in messages table.\n", sys_nsig); - printf ("%d is max useful index.\n", maxsigno); - - /* Keep printing values until we get to the end of *both* tables, not - *either* table. Note that knowing the maximum useful index does *not* - relieve us of the responsibility of testing the return pointer for - NULL. */ - - for (signo = 0; signo <= maxsigno; signo++) - { - name = strsigno (signo); - name = (name == NULL) ? "" : name; - msg = strsignal (signo); - msg = (msg == NULL) ? "" : msg; - printf ("%-4d%-18s%s\n", signo, name, msg); - } - - return 0; -} - -#endif diff --git a/contrib/gdb/libiberty/strstr.c b/contrib/gdb/libiberty/strstr.c deleted file mode 100644 index fab36e3fb3d..00000000000 --- a/contrib/gdb/libiberty/strstr.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Simple implementation of strstr for systems without it. - This function is in the public domain. */ - -/* - -NAME - - strstr -- locate first occurance of a substring - -SYNOPSIS - - #include - - char *strstr (char *s1, char *s2) - -DESCRIPTION - - Locates the first occurance in the string pointed to by S1 of - the string pointed to by S2. Returns a pointer to the substring - found, or a NULL pointer if not found. If S2 points to a string - with zero length, the function returns S1. - -BUGS - -*/ - - -/* FIXME: The above description is ANSI compiliant. This routine has not - been validated to comply with it. -fnf */ - -char * -strstr (s1, s2) - char *s1, *s2; -{ - register char *p = s1; - extern char *strchr (); - extern int strncmp (); -#if __GNUC__==2 - extern __SIZE_TYPE__ strlen (); -#endif - register int len = strlen (s2); - - for (; (p = strchr (p, *s2)) != 0; p++) - { - if (strncmp (p, s2, len) == 0) - { - return (p); - } - } - return (0); -} diff --git a/contrib/gdb/libiberty/strtod.c b/contrib/gdb/libiberty/strtod.c deleted file mode 100644 index c86c73de9b3..00000000000 --- a/contrib/gdb/libiberty/strtod.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Implementation of strtod for systems with atof. - Copyright (C) 1991, 1995 Free Software Foundation, Inc. - -This file is part of the libiberty library. This library is free -software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) -any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As a special exception, if you link this library with files -compiled with a GNU compiler to produce an executable, this does not cause -the resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why -the executable file might be covered by the GNU General Public License. */ - -#include - -extern double atof (); - -/* Disclaimer: this is currently just used by CHILL in GDB and therefore - has not been tested well. It may have been tested for nothing except - that it compiles. */ - -double -strtod (str, ptr) - char *str; - char **ptr; -{ - char *p; - - if (ptr == (char **)0) - return atof (str); - - p = str; - - while (isspace (*p)) - ++p; - - if (*p == '+' || *p == '-') - ++p; - - /* INF or INFINITY. */ - if ((p[0] == 'i' || p[0] == 'I') - && (p[1] == 'n' || p[1] == 'N') - && (p[2] == 'f' || p[2] == 'F')) - { - if ((p[3] == 'i' || p[3] == 'I') - && (p[4] == 'n' || p[4] == 'N') - && (p[5] == 'i' || p[5] == 'I') - && (p[6] == 't' || p[6] == 'T') - && (p[7] == 'y' || p[7] == 'Y')) - { - *ptr = p + 7; - return atof (str); - } - else - { - *ptr = p + 3; - return atof (str); - } - } - - /* NAN or NAN(foo). */ - if ((p[0] == 'n' || p[0] == 'N') - && (p[1] == 'a' || p[1] == 'A') - && (p[2] == 'n' || p[2] == 'N')) - { - p += 3; - if (*p == '(') - { - ++p; - while (*p != '\0' && *p != ')') - ++p; - if (*p == ')') - ++p; - } - *ptr = p; - return atof (str); - } - - /* digits, with 0 or 1 periods in it. */ - if (isdigit (*p) || *p == '.') - { - int got_dot = 0; - while (isdigit (*p) || (!got_dot && *p == '.')) - { - if (*p == '.') - got_dot = 1; - ++p; - } - - /* Exponent. */ - if (*p == 'e' || *p == 'E') - { - int i; - i = 1; - if (p[i] == '+' || p[i] == '-') - ++i; - if (isdigit (p[i])) - { - while (isdigit (p[i])) - ++i; - *ptr = p + i; - return atof (str); - } - } - *ptr = p; - return atof (str); - } - /* Didn't find any digits. Doesn't look like a number. */ - *ptr = str; - return 0.0; -} diff --git a/contrib/gdb/libiberty/strtol.c b/contrib/gdb/libiberty/strtol.c deleted file mode 100644 index db27ee0a875..00000000000 --- a/contrib/gdb/libiberty/strtol.c +++ /dev/null @@ -1,143 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#if 0 -#include -#endif -#include "ansidecl.h" - -/* FIXME: It'd be nice to configure around these, but the include files are too - painful. These macros should at least be more portable than hardwired hex - constants. */ - -#ifndef ULONG_MAX -#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ -#endif - -#ifndef LONG_MAX -#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */ -#endif - -#ifndef LONG_MIN -#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */ -#endif - -/* - * Convert a string to a long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long -strtol(nptr, endptr, base) - CONST char *nptr; - char **endptr; - register int base; -{ - register CONST char *s = nptr; - register unsigned long acc; - register int c; - register unsigned long cutoff; - register int neg = 0, any, cutlim; - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else if (c == '+') - c = *s++; - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for longs is - * [-2147483648..2147483647] and the input base is 10, - * cutoff will be set to 214748364 and cutlim to either - * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated - * a value > 214748364, or equal but the next digit is > 7 (or 8), - * the number is too big, and we will return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; - cutlim = cutoff % (unsigned long)base; - cutoff /= (unsigned long)base; - for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = neg ? LONG_MIN : LONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} diff --git a/contrib/gdb/libiberty/strtoul.c b/contrib/gdb/libiberty/strtoul.c deleted file mode 100644 index 40902452fed..00000000000 --- a/contrib/gdb/libiberty/strtoul.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#if 0 -#include -#endif -#include "ansidecl.h" - -#ifndef ULONG_MAX -#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ -#endif - -/* - * Convert a string to an unsigned long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long -strtoul(nptr, endptr, base) - CONST char *nptr; - char **endptr; - register int base; -{ - register CONST char *s = nptr; - register unsigned long acc; - register int c; - register unsigned long cutoff; - register int neg = 0, any, cutlim; - - /* - * See strtol for comments as to the logic used. - */ - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else if (c == '+') - c = *s++; - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; - cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; - for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = ULONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} diff --git a/contrib/gdb/libiberty/tmpnam.c b/contrib/gdb/libiberty/tmpnam.c deleted file mode 100644 index c0614677425..00000000000 --- a/contrib/gdb/libiberty/tmpnam.c +++ /dev/null @@ -1,39 +0,0 @@ -#include - -#ifndef L_tmpnam -#define L_tmpname 100 -#endif -#ifndef P_tmpdir -#define P_tmpdir "/usr/tmp" -#endif - -static char tmpnam_buffer[L_tmpnam]; -static int tmpnam_counter; - -extern int getpid (); - -char * -tmpnam (s) - char *s; -{ - int pid = getpid (); - - if (s == NULL) - s = tmpnam_buffer; - - /* Generate the filename and make sure that there isn't one called - it already. */ - - while (1) - { - FILE *f; - sprintf (s, "%s/%s%x.%x", P_tmpdir, "t", pid, tmpnam_counter); - f = fopen (s, "r"); - if (f == NULL) - break; - tmpnam_counter++; - fclose (f); - } - - return s; -} diff --git a/contrib/gdb/libiberty/vasprintf.c b/contrib/gdb/libiberty/vasprintf.c deleted file mode 100644 index 3794cbd2c4f..00000000000 --- a/contrib/gdb/libiberty/vasprintf.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Like vsprintf but provides a pointer to malloc'd storage, which must - be freed by the caller. - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include -#include -#include -#ifdef __STDC__ -#include -#else -#include -#endif - -#ifdef TEST -int global_total_width; -#endif - -unsigned long strtoul (); -char *malloc (); - -static int -int_vasprintf (result, format, args) - char **result; - const char *format; - va_list *args; -{ - const char *p = format; - /* Add one to make sure that it is never zero, which might cause malloc - to return NULL. */ - int total_width = strlen (format) + 1; - va_list ap; - - memcpy ((PTR) &ap, (PTR) args, sizeof (va_list)); - - while (*p != '\0') - { - if (*p++ == '%') - { - while (strchr ("-+ #0", *p)) - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, &p, 10); - if (*p == '.') - { - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, &p, 10); - } - while (strchr ("hlL", *p)) - ++p; - /* Should be big enough for any format specifier except %s. */ - total_width += 30; - switch (*p) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - (void) va_arg (ap, int); - break; - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - (void) va_arg (ap, double); - break; - case 's': - total_width += strlen (va_arg (ap, char *)); - break; - case 'p': - case 'n': - (void) va_arg (ap, char *); - break; - } - } - } -#ifdef TEST - global_total_width = total_width; -#endif - *result = malloc (total_width); - if (*result != NULL) - return vsprintf (*result, format, *args); - else - return 0; -} - -int -vasprintf (result, format, args) - char **result; - const char *format; - va_list args; -{ - return int_vasprintf (result, format, &args); -} - -#ifdef TEST -void -checkit -#ifdef __STDC__ - (const char* format, ...) -#else - (va_alist) - va_dcl -#endif -{ - va_list args; - char *result; - -#ifdef __STDC__ - va_start (args, format); -#else - char *format; - va_start (args); - format = va_arg (args, char *); -#endif - vasprintf (&result, format, args); - if (strlen (result) < global_total_width) - printf ("PASS: "); - else - printf ("FAIL: "); - printf ("%d %s\n", global_total_width, result); -} - -int -main () -{ - checkit ("%d", 0x12345678); - checkit ("%200d", 5); - checkit ("%.300d", 6); - checkit ("%100.150d", 7); - checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ -777777777777777777333333333333366666666666622222222222777777777777733333"); - checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); -} -#endif /* TEST */ diff --git a/contrib/gdb/libiberty/vfork.c b/contrib/gdb/libiberty/vfork.c deleted file mode 100644 index 86c45919f66..00000000000 --- a/contrib/gdb/libiberty/vfork.c +++ /dev/null @@ -1,8 +0,0 @@ -/* Emulate vfork using just plain fork, for systems without a real vfork. - This function is in the public domain. */ - -int -vfork () -{ - return (fork ()); -} diff --git a/contrib/gdb/libiberty/vfprintf.c b/contrib/gdb/libiberty/vfprintf.c deleted file mode 100644 index ce3fdf9c474..00000000000 --- a/contrib/gdb/libiberty/vfprintf.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include -#undef vfprintf - -int -vfprintf (file, format, ap) - FILE *file; - const char *format; - va_list ap; -{ - return _doprnt (format, ap, file); -} diff --git a/contrib/gdb/libiberty/vmsbuild.com b/contrib/gdb/libiberty/vmsbuild.com deleted file mode 100644 index e1c203f9f47..00000000000 --- a/contrib/gdb/libiberty/vmsbuild.com +++ /dev/null @@ -1,142 +0,0 @@ -$! libiberty/vmsbuild.com -- build liberty.olb for VMS host, VMS target -$! -$ CC = "gcc /noVerbose/Debug/Incl=([],[-.include])" -$ LIBR = "library /Obj" -$ LINK = "link" -$ DELETE= "delete /noConfirm" -$ SEARCH= "search /Exact" -$ ECHO = "write sys$output" -$ ABORT = "exit %x002C" -$! -$ LIB_NAME = "liberty.olb" !this is what we're going to construct -$ WORK_LIB = "new-lib.olb" !used to guard against an incomplete build -$ -$! manually copied from Makefile.in -$ REQUIRED_OFILES = "argv.o basename.o concat.o cplus-dem.o fdmatch.o "- - + "getopt.o getopt1.o getruntime.o hex.o "- - + "floatformat.o obstack.o spaces.o strerror.o strsignal.o "- - + "vasprintf.o xatexit.o xexit.o xmalloc.o xstrerror.o" -$! anything not caught by link+search of dummy.* should be added here -$ EXTRA_OFILES = "" -$! -$! move to the directory which contains this command procedure -$ old_dir = f$environ("DEFAULT") -$ new_dir = f$parse("_._;",f$environ("PROCEDURE")) - "_._;" -$ set default 'new_dir' -$ -$ ECHO "Starting libiberty build..." -$ create config.h -/* libiberty config.h for VMS */ -#define NEED_sys_siglist -#define NEED_psignal -#define NEED_basename -$ if f$search("alloca-conf.h").eqs."" then - - copy alloca-norm.h alloca-conf.h -$ LIBR 'WORK_LIB' /Create -$ -$! first pass: compile "required" modules -$ ofiles = REQUIRED_OFILES + " " + EXTRA_OFILES -$ gosub do_ofiles -$ -$! second pass: process dummy.c, using the first pass' results -$ ECHO " now checking run-time library for missing functionality" -$ if f$search("dummy.obj").nes."" then DELETE dummy.obj;* -$ define/noLog sys$error _NL: !can't use /User_Mode here due to gcc -$ define/noLog sys$output _NL: ! driver's use of multiple image activation -$ on error then continue -$ 'CC' dummy.c -$ deassign sys$error !restore, more or less -$ deassign sys$output -$ if f$search("dummy.obj").eqs."" then goto pass2_failure1 -$! link dummy.obj, capturing full linker feedback in dummy.map -$ oldmsg = f$environ("MESSAGE") -$ set message /Facility/Severity/Identification/Text -$ define/User sys$output _NL: -$ define/User sys$error _NL: -$ LINK/Map=dummy.map/noExe dummy.obj,'WORK_LIB'/Libr,- - gnu_cc:[000000]gcclib.olb/Libr,sys$library:vaxcrtl.olb/Libr -$ set message 'oldmsg' -$ if f$search("dummy.map").eqs."" then goto pass2_failure2 -$ DELETE dummy.obj;* -$ SEARCH dummy.map "%LINK-I-UDFSYM" /Output=dummy.list -$ DELETE dummy.map;* -$ ECHO " check completed" -$! we now have a file with one entry per line of unresolvable symbols -$ ofiles = "" -$ if f$trnlnm("IFILE$").nes."" then close/noLog ifile$ -$ open/Read ifile$ dummy.list -$iloop: read/End=idone ifile$ iline -$ iline = f$edit(iline,"COMPRESS,TRIM,LOWERCASE") -$ ofiles = ofiles + " " + f$element(1," ",iline) + ".o" -$ goto iloop -$idone: close ifile$ -$ DELETE dummy.list;* -$ -$! third pass: compile "missing" modules collected in pass 2 -$ gosub do_ofiles -$ -$! finish up -$ LIBR 'WORK_LIB' /Compress /Output='LIB_NAME' !new-lib.olb -> liberty.olb -$ DELETE 'WORK_LIB';* -$ -$! all done -$ ECHO "Completed libiberty build." -$ type sys$input: - - You many wish to do - $ COPY LIBERTY.OLB GNU_CC:[000000] - so that this run-time library resides in the same location as gcc's - support library. When building gas, be sure to leave the original - copy of liberty.olb here so that gas's build procedure can find it. - -$ set default 'old_dir' -$ exit -$ -$! -$! compile each element of the space-delimited list 'ofiles' -$! -$do_ofiles: -$ ofiles = f$edit(ofiles,"COMPRESS,TRIM") -$ i = 0 -$oloop: -$ f = f$element(i," ",ofiles) -$ if f.eqs." " then goto odone -$ f = f - ".o" !strip dummy suffix -$ ECHO " ''f'" -$ 'CC' 'f'.c -$ LIBR 'WORK_LIB' 'f'.obj /Insert -$ DELETE 'f'.obj;* -$ i = i + 1 -$ goto oloop -$odone: -$ return -$ -$! -$pass2_failure1: -$! if we reach here, dummy.c failed to compile and we're really stuck -$ type sys$input: - - Cannot compile the library contents checker (dummy.c + functions.def), - so cannot continue! - -$! attempt the compile again, without suppressing diagnostic messages this time -$ on error then ABORT +0*f$verify(v) -$ v = f$verify(1) -$ 'CC' dummy.c -$ ABORT +0*f$verify(v) !'f$verify(0)' -$! -$pass2_failure2: -$! should never reach here.. -$ type sys$input: - - Cannot link the library contents checker (dummy.obj), so cannot continue! - -$! attempt the link again, without suppressing diagnostic messages this time -$ on error then ABORT +0*f$verify(v) -$ v = f$verify(1) -$ LINK/Map=dummy.map/noExe dummy.obj,'WORK_LIB'/Libr,- - gnu_cc:[000000]gcclib.olb/Libr,sys$library:vaxcrtl.olb/Libr -$ ABORT +0*f$verify(v) !'f$verify(0)' -$ -$! not reached -$ exit diff --git a/contrib/gdb/libiberty/vprintf.c b/contrib/gdb/libiberty/vprintf.c deleted file mode 100644 index 63ac53c965a..00000000000 --- a/contrib/gdb/libiberty/vprintf.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include -#undef vprintf -int -vprintf (format, ap) - const char *format; - va_list ap; -{ - return vfprintf (stdout, format, ap); -} diff --git a/contrib/gdb/libiberty/vsprintf.c b/contrib/gdb/libiberty/vsprintf.c deleted file mode 100644 index bf0760cf6d3..00000000000 --- a/contrib/gdb/libiberty/vsprintf.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Simple implementation of vsprintf for systems without it. - Highly system-dependent, but should work on most "traditional" - implementations of stdio; newer ones should already have vsprintf. - Written by Per Bothner of Cygnus Support. - Based on libg++'s "form" (written by Doug Lea; dl@rocky.oswego.edu). - Copyright (C) 1991, 1995 Free Software Foundation, Inc. - -This file is part of the libiberty library. This library is free -software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) -any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -As a special exception, if you link this library with files -compiled with a GNU compiler to produce an executable, this does not cause -the resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why -the executable file might be covered by the GNU General Public License. */ - -#include -#include -#include -#undef vsprintf - -int -vsprintf (buf, format, ap) - char *buf; - const char *format; - va_list ap; -{ - FILE b; - int ret; -#ifdef VMS - b->_flag = _IOWRT|_IOSTRG; - b->_ptr = buf; - b->_cnt = 12000; -#else - b._flag = _IOWRT|_IOSTRG; - b._ptr = buf; - b._cnt = 12000; -#endif - ret = _doprnt(format, ap, &b); - putc('\0', &b); - return ret; - -} diff --git a/contrib/gdb/libiberty/waitpid.c b/contrib/gdb/libiberty/waitpid.c deleted file mode 100644 index 23db0b932d2..00000000000 --- a/contrib/gdb/libiberty/waitpid.c +++ /dev/null @@ -1,11 +0,0 @@ -int -waitpid (pid, stat_loc, options) - int pid, *stat_loc, options; -{ - for (;;) - { - int wpid = wait(stat_loc); - if (wpid == pid || wpid == -1) - return wpid; - } -} diff --git a/contrib/gdb/libiberty/xatexit.c b/contrib/gdb/libiberty/xatexit.c deleted file mode 100644 index 7dd27e143f8..00000000000 --- a/contrib/gdb/libiberty/xatexit.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * %sccs.include.redist.c% - */ - -/* Adapted from newlib/libc/stdlib/{,at}exit.[ch]. - If you use xatexit, you must call xexit instead of exit. */ - -#include "ansidecl.h" -#include "libiberty.h" - -#include - -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -/* For systems with larger pointers than ints, this must be declared. */ -PTR malloc PARAMS ((size_t)); - -static void xatexit_cleanup PARAMS ((void)); - -/* Pointer to function run by xexit. */ -extern void (*_xexit_cleanup) (); - -#define XATEXIT_SIZE 32 - -struct xatexit { - struct xatexit *next; /* next in list */ - int ind; /* next index in this table */ - void (*fns[XATEXIT_SIZE]) PARAMS ((void)); /* the table itself */ -}; - -/* Allocate one struct statically to guarantee that we can register - at least a few handlers. */ -static struct xatexit xatexit_first; - -/* Points to head of LIFO stack. */ -static struct xatexit *xatexit_head = &xatexit_first; - -/* Register function FN to be run by xexit. - Return 0 if successful, -1 if not. */ - -int -xatexit (fn) - void (*fn) PARAMS ((void)); -{ - register struct xatexit *p; - - /* Tell xexit to call xatexit_cleanup. */ - if (!_xexit_cleanup) - _xexit_cleanup = xatexit_cleanup; - - p = xatexit_head; - if (p->ind >= XATEXIT_SIZE) - { - if ((p = (struct xatexit *) malloc (sizeof *p)) == NULL) - return -1; - p->ind = 0; - p->next = xatexit_head; - xatexit_head = p; - } - p->fns[p->ind++] = fn; - return 0; -} - -/* Call any cleanup functions. */ - -static void -xatexit_cleanup () -{ - register struct xatexit *p; - register int n; - - for (p = xatexit_head; p; p = p->next) - for (n = p->ind; --n >= 0;) - (*p->fns[n]) (); -} diff --git a/contrib/gdb/libiberty/xexit.c b/contrib/gdb/libiberty/xexit.c deleted file mode 100644 index 98baeca475d..00000000000 --- a/contrib/gdb/libiberty/xexit.c +++ /dev/null @@ -1,36 +0,0 @@ -/* xexit.c -- Run any exit handlers, then exit. - Copyright (C) 1994 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "ansidecl.h" -#include "libiberty.h" - -#include - -/* This variable is set by xatexit if it is called. This way, xmalloc - doesn't drag xatexit into the link. */ -void (*_xexit_cleanup) (); - -void -xexit (code) - int code; -{ - if (_xexit_cleanup != NULL) - (*_xexit_cleanup) (); - exit (code); -} diff --git a/contrib/gdb/libiberty/xmalloc.c b/contrib/gdb/libiberty/xmalloc.c deleted file mode 100644 index 95967abe300..00000000000 --- a/contrib/gdb/libiberty/xmalloc.c +++ /dev/null @@ -1,106 +0,0 @@ -/* memory allocation routines with error checking. - Copyright 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "ansidecl.h" -#include "libiberty.h" - -#include - -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -/* For systems with larger pointers than ints, these must be declared. */ -PTR malloc PARAMS ((size_t)); -PTR realloc PARAMS ((PTR, size_t)); - -/* The program name if set. */ -static const char *name = ""; - -/* The initial sbrk, set when the program name is set. */ -static char *first_break = NULL; - -void -xmalloc_set_program_name (s) - const char *s; -{ - name = s; - if (first_break == NULL) - first_break = (char *) sbrk (0); -} - -PTR -xmalloc (size) - size_t size; -{ - PTR newmem; - - if (size == 0) - size = 1; - newmem = malloc (size); - if (!newmem) - { - extern char **environ; - size_t allocated; - - if (first_break != NULL) - allocated = (char *) sbrk (0) - first_break; - else - allocated = (char *) sbrk (0) - (char *) &environ; - fprintf (stderr, - "\n%s%sCan not allocate %lu bytes after allocating %lu bytes\n", - name, *name ? ": " : "", - (unsigned long) size, (unsigned long) allocated); - xexit (1); - } - return (newmem); -} - -PTR -xrealloc (oldmem, size) - PTR oldmem; - size_t size; -{ - PTR newmem; - - if (size == 0) - size = 1; - if (!oldmem) - newmem = malloc (size); - else - newmem = realloc (oldmem, size); - if (!newmem) - { - extern char **environ; - size_t allocated; - - if (first_break != NULL) - allocated = (char *) sbrk (0) - first_break; - else - allocated = (char *) sbrk (0) - (char *) &environ; - fprintf (stderr, - "\n%s%sCan not reallocate %lu bytes after allocating %lu bytes\n", - name, *name ? ": " : "", - (unsigned long) size, (unsigned long) allocated); - xexit (1); - } - return (newmem); -} diff --git a/contrib/gdb/libiberty/xstrdup.c b/contrib/gdb/libiberty/xstrdup.c deleted file mode 100644 index 9d08bc70405..00000000000 --- a/contrib/gdb/libiberty/xstrdup.c +++ /dev/null @@ -1,17 +0,0 @@ -/* xstrdup.c -- Duplicate a string in memory, using xmalloc. - This trivial function is in the public domain. - Ian Lance Taylor, Cygnus Support, December 1995. */ - -#include "ansidecl.h" -#include "libiberty.h" - -char * -xstrdup (s) - const char *s; -{ - char *ret; - - ret = xmalloc (strlen (s) + 1); - strcpy (ret, s); - return ret; -} diff --git a/contrib/gdb/libiberty/xstrerror.c b/contrib/gdb/libiberty/xstrerror.c deleted file mode 100644 index d05369ac972..00000000000 --- a/contrib/gdb/libiberty/xstrerror.c +++ /dev/null @@ -1,54 +0,0 @@ -/* xstrerror.c -- jacket routine for more robust strerror() usage. - Fri Jun 16 18:30:00 1995 Pat Rankin - This code is in the public domain. */ - -#include "libiberty.h" -#include "config.h" - -#ifdef VMS -#include -#if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES) -extern char *strerror PARAMS ((int,...)); -#define DONT_DECLARE_STRERROR -#endif -#endif /* VMS */ - -#ifndef DONT_DECLARE_STRERROR -extern char *strerror PARAMS ((int)); -#endif - -/* If strerror returns NULL, we'll format the number into a static buffer. */ - -#define ERRSTR_FMT "undocumented error #%d" -static char xstrerror_buf[sizeof ERRSTR_FMT + 20]; - -/* Like strerror, but result is never a null pointer. */ - -char * -xstrerror (errnum) - int errnum; -{ - char *errstr; -#ifdef VMS - char *(*vmslib_strerror) PARAMS ((int,...)); - - /* Override any possibly-conflicting declaration from system header. */ - vmslib_strerror = (char *(*) PARAMS ((int,...))) strerror; - /* Second argument matters iff first is EVMSERR, but it's simpler to - pass it unconditionally. `vaxc$errno' is declared in - and maintained by the run-time library in parallel to `errno'. - We assume that `errnum' corresponds to the last value assigned to - errno by the run-time library, hence vaxc$errno will be relevant. */ - errstr = (*vmslib_strerror) (errnum, vaxc$errno); -#else - errstr = strerror (errnum); -#endif - - /* If `errnum' is out of range, result might be NULL. We'll fix that. */ - if (!errstr) - { - sprintf (xstrerror_buf, ERRSTR_FMT, errnum); - errstr = xstrerror_buf; - } - return errstr; -} From 9706b0c96fe2e3e22da291b7513ff7d77b69fd13 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 20 Jun 2004 02:30:48 +0000 Subject: [PATCH 4/5] This file was not part of the GDB 5.2.1 import and should have been deleted from the vendor branch. --- contrib/gdb/opcodes/ChangeLog | 1772 -------------------- contrib/gdb/opcodes/Makefile.in | 305 ---- contrib/gdb/opcodes/config.in | 7 - contrib/gdb/opcodes/configure | 1538 ----------------- contrib/gdb/opcodes/configure.in | 216 --- contrib/gdb/opcodes/dis-buf.c | 70 - contrib/gdb/opcodes/disassemble.c | 166 -- contrib/gdb/opcodes/i386-dis.c | 2031 ----------------------- contrib/gdb/opcodes/sysdep.h | 38 - contrib/gdb/opcodes/z8k-dis.c | 571 ------- contrib/gdb/readline/doc/ChangeLog | 12 - contrib/gdb/readline/doc/Makefile.in | 94 -- contrib/gdb/readline/doc/configure.in | 8 - contrib/gdb/readline/doc/hist.texinfo | 106 -- contrib/gdb/readline/doc/hstech.texinfo | 311 ---- contrib/gdb/readline/doc/hsuser.texinfo | 153 -- contrib/gdb/readline/doc/inc-hist.texi | 159 -- contrib/gdb/readline/doc/rlman.texinfo | 103 -- contrib/gdb/readline/doc/rltech.texinfo | 1012 ----------- contrib/gdb/readline/doc/rluser.texinfo | 566 ------- 20 files changed, 9238 deletions(-) delete mode 100644 contrib/gdb/opcodes/ChangeLog delete mode 100644 contrib/gdb/opcodes/Makefile.in delete mode 100644 contrib/gdb/opcodes/config.in delete mode 100755 contrib/gdb/opcodes/configure delete mode 100644 contrib/gdb/opcodes/configure.in delete mode 100644 contrib/gdb/opcodes/dis-buf.c delete mode 100644 contrib/gdb/opcodes/disassemble.c delete mode 100644 contrib/gdb/opcodes/i386-dis.c delete mode 100644 contrib/gdb/opcodes/sysdep.h delete mode 100644 contrib/gdb/opcodes/z8k-dis.c delete mode 100644 contrib/gdb/readline/doc/ChangeLog delete mode 100644 contrib/gdb/readline/doc/Makefile.in delete mode 100644 contrib/gdb/readline/doc/configure.in delete mode 100644 contrib/gdb/readline/doc/hist.texinfo delete mode 100644 contrib/gdb/readline/doc/hstech.texinfo delete mode 100644 contrib/gdb/readline/doc/hsuser.texinfo delete mode 100644 contrib/gdb/readline/doc/inc-hist.texi delete mode 100644 contrib/gdb/readline/doc/rlman.texinfo delete mode 100644 contrib/gdb/readline/doc/rltech.texinfo delete mode 100644 contrib/gdb/readline/doc/rluser.texinfo diff --git a/contrib/gdb/opcodes/ChangeLog b/contrib/gdb/opcodes/ChangeLog deleted file mode 100644 index 589c1a234ac..00000000000 --- a/contrib/gdb/opcodes/ChangeLog +++ /dev/null @@ -1,1772 +0,0 @@ -Sun Apr 7 15:06:17 1996 Fred Fish - - From: Miles Bader - * configure.in: Use AC_CHECK_TOOL to find AR & RANLIB. - * configure: Regenerate with autoconf. - -Sat Mar 16 13:04:07 1996 Fred Fish - - * z8kgen.c (internal, gas): Call xmalloc rather than unchecked - malloc. - -Tue Mar 12 12:14:10 1996 Ian Lance Taylor - - * configure: Rebuild with autoconf 2.8. - -Thu Mar 7 15:11:10 1996 Doug Evans - - * sparc-dis.c (print_insn_sparc): Handle 'O' operand char like 'r'. - * sparc-opc.c (sparc_opcodes): Use 'O' operand char for `neg reg'. - -Tue Mar 5 15:51:57 1996 Ian Lance Taylor - - * configure.in: Don't set SHLIB or SHLINK to an empty string, - since they appear as targets in Makefile.in. - * configure: Rebuild. - -Mon Feb 26 13:03:40 1996 Stan Shebs - - * mpw-make.sed: Edit out shared library support bits. - -Tue Feb 20 20:48:28 1996 Doug Evans - - * sparc-opc.c (v8,v6notv9): Add MASK_SPARCLET. - (sparc_opcode_archs): Add MASK_V8 to sparclet entry. - (sparc_opcodes): Add sparclet insns. - (sparclet_cpreg_table): New static local. - (sparc_{encode,decode}_sparclet_cpreg): New functions. - * sparc-dis.c (print_insn_sparc): Handle sparclet cpregs. - -Tue Feb 20 11:02:44 1996 Alan Modra - - * i386-dis.c (index16): New static variable. - (putop): Print jecxz for 32 bit case, jcxz for 16 bit, not the - other way around. - (OP_indirE): Return result of OP_E. - (OP_E): Check for 16 bit addressing mode, and disassemble - correctly. Optimised 32 bit case a little. Don't print - "(base,index,scale)" when sib specifies only an offset. - -Mon Feb 19 12:32:17 1996 Ian Lance Taylor - - * configure.in: Set and substitute SHLIB_DEP. - * configure: Rebuild. - * Makefile.in (SHLIB_DEP): New variable. - (LIBIBERTY_LISTS, BFD_LIST): New variables. - (stamp-piclist): Depend upon LIBIBERTY_LISTS and BFD_LIST. If - COMMON_SHLIB, add them to piclist with appropriate modifications. - ($(SHLIB)): Depend upon $(SHLIB_DEP). Don't check COMMON_SHLIB - here: just use piclist. - -Mon Feb 19 02:03:50 1996 Doug Evans - - * sparc-dis.c (MASK_V9,V9_ONLY_P,V9_P): Define. - (print_insn_sparc): Rewrite v9/not-v9 tests. - (compare_opcodes): Likewise. - * sparc-opc.c (MASK_): Define. - (v6,v7,v8,sparclite,v9,v9a): Redefine. - (sparclet,v6notv9): Define. - (sparc_opcode_archs): Delete member `conflicts'. Add `supported'. - (sparc_opcodes): Delete F_NOTV9, use v6notv9 instead. - -Thu Feb 15 14:45:05 1996 Ian Lance Taylor - - * configure.in: Call AC_PROG_CC before configure.host. - * configure: Rebuild. - - * Makefile.in (SONAME): Remove leading ../bfd/ from $(SHLIB). - -Wed Feb 14 19:01:27 1996 Alan Modra - - * i386-dis.c (onebyte_has_modrm): New static array. - (twobyte_has_modrm): New static array. - (print_insn_i386): Only fetch the mod/reg/rm byte if it is needed. - -Tue Feb 13 15:15:01 1996 Ian Lance Taylor - - * Makefile.in ($(SHLINK)): Check ts against $(SHLIB), not - $(SHLINK). - -Mon Feb 12 16:26:06 1996 Michael Meissner - - * ppc-opc.c (PPC): Undef, so default defination on Windows NT - doesn't conflict. - -Wed Feb 7 13:59:54 1996 Ian Lance Taylor - - * m68k-opc.c (m68k_opcodes): The bkpt instruction is supported on - m68010up, not just m68020up | cpu32. - - * Makefile.in (SONAME): New variable. - ($(SHLINK)): Make a link to the transformed name, as well. - (stamp-tshlink): New target. - (install): Skip stamp-tshlink during install. - -Tue Feb 6 12:28:54 1996 Ian Lance Taylor - - * configure.in: Call AC_ARG_PROGRAM. - * configure: Rebuild. - * Makefile.in (program_transform_name): New variable. - (install): Transform library name before installing it. - -Mon Feb 5 16:14:42 1996 Ian Lance Taylor - - * i960-dis.c (mem): Add HX dcinva instruction. - - Support for building as a shared library, based on patches from - Alan Modra : - * configure.in: Add AC_ARG_ENABLE for shared and commonbfdlib. - New substitutions: ALLLIBS, PICFLAG, SHLIB, SHLIB_CC, - SHLIB_CFLAGS, COMMON_SHLIB, SHLINK. - * configure: Rebuild. - * Makefile.in (ALLLIBS): New variable. - (PICFLAG, SHLIB, SHLIB_CC, SHLIB_CFLAGS): New variables. - (COMMON_SHLIB, SHLINK): New variables. - (.c.o): If PICFLAG is set, compile twice, once PIC, once normal. - (STAGESTUFF): Remove variable. - (all): Depend upon $(ALLLIBS) rather than $(TARGETLIB). - (stamp-piclist, piclist): New targets. - ($(SHLIB), $(SHLINK)): New targets. - ($(OFILES)): Depend upon stamp-picdir. - (disassemble.o): Build twice if PICFLAG is set. - (MOSTLYCLEAN): Add pic/*.o. - (clean): Remove $(SHLIB), $(SHLINK), piclist, and stamp-piclist. - (distclean): Remove pic and stamp-picdir. - (install): Install shared libraries. - (stamp-picdir): New target. - -Fri Feb 2 17:15:25 1996 Doug Evans - - * sparc-dis.c (print_insn_sparc): Delete DISASM_RAW_INSN support. - Print unknown instruction as "unknown", rather than in hex. - -Tue Jan 30 14:06:08 1996 Ian Lance Taylor - - * dis-buf.c: Include "sysdep.h" before "dis-asm.h". - -Thu Jan 25 20:24:07 1996 Doug Evans - - * sparc-opc.c (sparc_opcode_archs): Mark v8/sparclite as conflicting. - -Thu Jan 25 11:56:49 1996 Ian Lance Taylor - - * i386-dis.c (print_insn_i386): Only fetch the mod/reg/rm byte - when necessary. From Ulrich Drepper - . - -Thu Jan 25 03:39:10 1996 Doug Evans - - * sparc-dis.c (print_insn_sparc): NUMOPCODES replaced with - sparc_num_opcodes. Update architecture enum values. - * sparc-opc.c (sparc_opcode_archs): Replaces architecture_pname. - (sparc_opcode_lookup_arch): New function. - (sparc_num_opcodes): Renamed from bfd_sparc_num_opcodes. - (sparc_opcodes): Add v9a shutdown insn. - -Mon Jan 22 08:29:59 1996 Doug Evans - - * sparc-dis.c (print_insn_sparc): Renamed from print_insn. - If DISASM_RAW_INSN, print insn in hex. Handle v9a as opcode - architecture. - (print_insn_sparc64): Deleted. - * disassemble.c (disassembler, case bfd_arch_sparc): Always use - print_insn_sparc. - - * sparc-opc.c (architecture_pname): Add v9a. - -Fri Jan 12 14:35:58 1996 David Mosberger-Tang - - * alpha-opc.h (alpha_insn_set): VAX floating point opcode was - incorrectly defined as 0x16 when it should be 0x15. - (FLOAT_FORMAT_MASK): function code is 11 bits, not just 7 bits! - (alpha_insn_set): added cvtst and cvttq float ops. Also added - excb (exception barrier) which is defined in the Alpha - Architecture Handbook version 2. - * alpha-dis.c (print_insn_alpha): Fixed special-case decoding for - OPERATE_FORMAT_CODE type instructions. The bug caused mulq to be - disassembled as or, for example. - -Wed Jan 10 12:37:22 1996 Ian Lance Taylor - - * mips-dis.c (print_insn_arg): Print cases 'i' and 'u' in hex. - (_print_insn_mips): Change i from int to unsigned int. - -Thu Jan 4 17:21:10 1996 David Edelsohn - - * ppc-opc.c (powerpc_opcodes): tlbi POWER opcode form different - from tlbie PowerPC opcode. Add PPC603 tlbld and tlbli. - -Thu Dec 28 13:29:19 1995 John Hassey - - * i386-dis.c: Added Pentium Pro instructions. - -Tue Dec 19 22:56:35 1995 Michael Meissner - - * ppc-opc.c (fsqrt{,.}): Duplicate for PowerPC in addition to - being for Power2. - -Fri Dec 15 14:14:15 1995 J.T. Conklin - - * sh-opc.h (sh_nibble_type): Added REG_B. - (sh_arg_type): Added A_REG_B. - (sh_table): Added pref and bank reg versions of ldc, ldc.l, stc - and stc.l opcodes. - * sh-dis.c (print_insn_shx): Added cases for REG_B and A_REG_B. - -Fri Dec 15 16:44:31 1995 Ian Lance Taylor - - * disassemble.c (disassembler): Use new bfd_big_endian macro. - -Tue Dec 12 12:22:24 1995 Ian Lance Taylor - - * Makefile.in (distclean): Remove stamp-h. From Ronald - F. Guilmette . - -Tue Dec 5 13:42:44 1995 Stan Shebs - - From David Mosberger-Tang : - * alpha-dis.c (print_insn_alpha): fixed decoding of cpys - instruction. - -Mon Dec 4 12:29:05 1995 J.T. Conklin - - * sh-opc.h (sh_arg_type): Added A_SSR and A_SPC. - (sh_table): Added many SH3 opcodes. - * sh-dis.c (print_insn_shx): Added cases for A_SSR and A_SPC. - -Fri Dec 1 07:42:18 1995 Michael Meissner - - * ppc-opc.c (subfc., subfco): Mark this PPCCOM, not PPC. - (subco,subco.): Mark this PPC, not PPCCOM. - -Mon Nov 27 13:09:52 1995 Ian Lance Taylor - - * configure: Rebuild with autoconf 2.7. - -Tue Nov 21 18:28:06 1995 Ian Lance Taylor - - * configure: Rebuild with autoconf 2.6. - -Wed Nov 15 19:02:53 1995 Ken Raeburn - - * configure.in: Sort list of architectures. Accept but do nothing - for alliant, convex, pyramid, romp, and tahoe. - -Wed Nov 8 20:18:59 1995 Ian Lance Taylor - - * a29k-dis.c (print_special): Change num to unsigned int. - -Wed Nov 8 20:10:35 1995 Eric Freudenthal - - * a29k-dis.c (print_insn): Cast insn24 to unsigned long when - shifting it. - -Tue Nov 7 15:21:06 1995 Ian Lance Taylor - - * configure.in: Call AC_CHECK_PROG to find and cache AR. - * configure: Rebuilt. - -Mon Nov 6 17:39:47 1995 Harry Dolan - - * configure.in: Add case for bfd_i860_arch. - * configure: Rebuild. - -Fri Nov 3 12:45:31 1995 Ian Lance Taylor - - * m68k-opc.c (m68k_opcodes): Correct fmoveml operands. - * m68k-dis.c (NEXTSINGLE): Change i to unsigned int. - (NEXTDOUBLE): Likewise. - (print_insn_m68k): Don't match fmoveml if there is more than one - register in the list. - (print_insn_arg): Handle a place of '8' for a type of 'L'. - -Thu Nov 2 23:06:33 1995 Ian Lance Taylor - - * m68k-opc.c: Use #W rather than #w. - * m68k-dis.c (print_insn_arg): Handle new 'W' place. - -Wed Nov 1 13:30:24 1995 Ian Lance Taylor - - * m68k-opc.c (m68k_opcode_aliases): Add dbfw as an alias for dbf, - and likewise for all the dbxx opcodes. - -Mon Oct 30 20:50:40 1995 Fred Fish - - * arc-dis.c: Include elf-bfd.h rather than libelf.h. - -Mon Oct 23 11:11:34 1995 James G. Smith - - * mips-opc.c: Added shorthand (V1) for INSN_4100 manifest. Added - the VR4100 specific instructions to the mips_opcodes structure. - -Thu Oct 19 11:05:23 1995 Stan Shebs - - * mpw-config.in, mpw-make.sed: Remove ugly workaround for - ugly Metrowerks bug in CW6, is fixed in CW7. - -Mon Oct 16 12:59:01 1995 Michael Meissner - - * ppc-opc.c (whole file): Add flags for common/any support. - -Tue Oct 10 11:06:07 1995 Fred Fish - - * Makefile.in (BISON): Remove macro. - (FLAGS_TO_PASS): Remove BISON. - -Fri Oct 6 16:26:45 1995 Ken Raeburn - - Mon Sep 25 22:49:32 1995 Andreas Schwab - - * m68k-dis.c (print_insn_m68k): Recognize all two-word - instructions that take no args by looking at the match mask. - (print_insn_arg): Always print "%" before register names. - [case 'c']: Use "nc" for the no-cache case, as recognized by gas. - [case '_']: Don't print "@#" before address. - [case 'J']: Use "%s" as format string, not register name. - [case 'B']: Treat place == 'C' like 'l' and 'L'. - -Thu Oct 5 22:16:20 1995 Ken Raeburn - - * i386-dis.c: Describe cmpxchg8b operand, and spell the opcode - name correctly. - -Tue Oct 3 08:30:20 1995 steve chamberlain - - From David Mosberger-Tang - - * alpha-opc.h (MEMORY_FUNCTION_FORMAT_MASK): added. - (alpha_insn_set): added definitions for VAX floating point - instructions (Unix compilers don't generate these, but handcoded - assembly might still use them). - - * alpha-dis.c (print_insn_alpha): added support for disassembling - the miscellaneous instructions in the Alpha instruction set. - -Tue Sep 26 18:47:20 1995 Stan Shebs - - * mpw-config.in: Add m68k-opc.c.o to BFD_MACHINES for m68k, - no longer create sysdep.h, sed ppc-opc.c to work around a - serious Metrowerks C bug. - * mpw-make.in: Remove. - * mpw-make.sed: New file, used by mpw-configure to edit - Makefile.in into an MPW makefile. - -Wed Sep 20 12:55:28 1995 Ian Lance Taylor - - * Makefile.in (maintainer-clean): New synonym for realclean. - -Tue Sep 19 15:28:36 1995 Ian Lance Taylor - - * m68k-opc.c: Split pmove patterns which use 'P' into patterns - which use '0', '1', and '2' instead. Specify the proper size for - a pmove immediate operand. Correct the pmovefd patterns to be - moves to a register, not from a register. - * m68k-dis.c (print_insn_arg): Replace 'P' with '0', '1', '2'. - -Thu Sep 14 11:58:22 1995 Doug Evans - - * sparc-opc.c (sparc_opcodes): Mark all insns that reference - %psr, %wim, %tbr as F_NOTV9. - -Fri Sep 8 01:07:38 1995 Ian Lance Taylor - - * Makefile.in (Makefile): Just rebuild Makefile when running - config.status. - (config.h, stamp-h): New targets. - * configure.in: Call AC_CONFIG_HEADER and AC_CANONICAL_SYSTEM - earlier. Don't bother to call AC_ARG_PROGRAM. Touch stamp-h when - rebuilding config.h. - * configure: Rebuild. - - * mips-opc.c: Change unaligned loads and stores with "t,A" - operands to use "t,A(b)". - -Thu Sep 7 19:02:46 1995 Jim Wilson - - * sh-dis.c (print_insn_shx): Add F_FR0 support. - -Thu Sep 7 19:02:46 1995 Jim Wilson - - * sh-dis.c (print_insn_shx): Change loop over op->arg[n] to iterate - until 3 instead of until 2. - -Wed Sep 6 21:21:33 1995 Ian Lance Taylor - - * Makefile.in (ALL_CFLAGS): Define. - (.c.o, disassemble.o): Use $(ALL_CFLAGS). - (MOSTLYCLEAN): Add config.log. - (distclean): Don't remove config.log. - * configure.in: Substitute HDEFINES. - * configure: Rebuild. - -Wed Sep 6 15:08:09 1995 Jim Wilson - - * sh-opc.h (sh_arg_type): Add F_FR0. - (sh_table, case fmac): Add F_FR0 as first argument. - -Wed Sep 6 15:08:09 1995 Jim Wilson - - * sh-opc.h (sh_opcode_info): Increase arg array size to 4. - -Tue Sep 5 18:28:10 1995 Doug Evans - - * sparc-dis.c: Remove all references to NO_V9. - -Tue Sep 5 20:03:26 1995 Ian Lance Taylor - - * aclocal.m4: Just include ../bfd/aclocal.m4. - * configure: Rebuild. - -Tue Sep 5 16:09:59 1995 Doug Evans - - * sparc-dis.c (X_DISP19): Define. - (print_insn, case 'G'): Use it. - (print_insn, case 'L'): Sign extend displacement. - -Mon Sep 4 14:28:46 1995 Ian Lance Taylor - - * configure.in: Run ../bfd/configure.host before AC_PROG_CC. - Subsitute CFLAGS and AR. Call AC_PROG_INSTALL. Don't substitute - host_makefile_frag or frags. - * aclocal.m4: New file. - * configure: Rebuild. - * Makefile.in (INSTALL): Set to @INSTALL@. - (INSTALL_PROGRAM): Set to @INSTALL_PROGRAM@. - (INSTALL_DATA): Set to @INSTALL_DATA@. - (AR): Set to @AR@. - (AR_FLAGS): Set to rc rather than qc. - (CC): Define as @CC@. - (CFLAGS): Set to @CFLAGS@. - (@host_makefile_frag@): Remove. - (config.status): Remove dependency upon @frags@. - - * configure.in: ../bfd/config.bfd now just sets shell variables. - Use them rather than looking through target Makefile fragments. - * configure: Rebuild. - -Thu Aug 31 12:35:32 1995 Jim Wilson - - * sh-opc.h (ftrc): Change FPUL_N to FPUL_M. - -Wed Aug 30 13:52:28 1995 Doug Evans - - * sparc-opc.c (sparc_opcodes): Delete duplicate wr %y insn. - Add clrx, iprefetch, signx, clruw, cas, casl, casx, casxl synthetic - sparc64 insns. - - * sparc-opc.c (sparc_opcodes): Fix prefetcha insn. - (lookup_{name,value}): New functions. - (prefetch_table): New static local. - (sparc_{encode,decode}_prefetch): New functions. - * sparc-dis.c (print_insn): Handle '*' arg (prefetch function). - -Wed Aug 30 11:11:58 1995 Jim Wilson - - * sh-opc.h: Add blank lines to improve readabililty of sh3e - instructions. - -Wed Aug 30 11:09:38 1995 Jim Wilson - - * sh-dis.c: Correct comment on first line of file. - -Tue Aug 29 15:37:18 1995 Doug Evans - - * disassemble.c (disassembler): Handle bfd_mach_sparc64. - - * sparc-opc.c (asi, membar): New static locals. - (sparc_{encode,decode}_{asi,membar}): New functions. - (sparc_opcodes, membar insn): Fix. - * sparc-dis.c (print_insn): Call sparc_decode_asi. - Support decoding of membar masks. - (X_MEMBAR): Define. - -Sat Aug 26 21:22:48 1995 Ian Lance Taylor - - * m68k-opc.c (m68k_opcode_aliases): Add br, brs, brb, brw, brl. - -Mon Aug 21 17:33:36 1995 Ian Lance Taylor - - * m68k-opc.c (m68k_opcode_aliases): Add bhib as an alias for bhis, - and likewise for the other branches. Add bhs as an alias for bcc, - and likewise for the size variants. Add dbhs as an alias for - dbcc. - -Fri Aug 11 13:40:24 1995 Jeff Law (law@snake.cs.utah.edu) - - * sh-opc.h (FP sts instructions): Update to match reality. - -Mon Aug 7 16:12:58 1995 Ian Lance Taylor - - * m68k-dis.c: (fpcr_names): Add % before all register names. - (reg_names): Likewise. - (print_insn_arg): Don't explicitly print % before register names. - Add % before register names in static array names. In case 'r', - print data registers as `@(Dn)', not `Dn@'. When printing a - memory address, don't print @# before it. - (print_indexed): Change base_disp and outer_disp from int to - bfd_vma. Print using MIT syntax, not mutant invalid Motorola - syntax. Sign extend 8 byte displacement correctly. - (print_base): Print using MIT syntax. Print zpc when appropriate. - Change parameter disp from int to bfd_vma. - - * m68k-opc.c (m68k_opcode_aliases): Add jsrl and jsrs as aliases - for jsr. - -Mon Aug 7 02:21:40 1995 Jeff Law (law@snake.cs.utah.edu) - - * sh-dis.c (print_insn_shx): Handle new operand types F_REG_N, - F_REG_M, FPSCR_M, FPSCR_N, FPUL_M and FPUL_N. - * sh-opc.h (sh_arg_type): Add new operand types. - (sh_table): Add new opcodes from SH3E Floating Point ISA. - -Sat Aug 5 16:50:14 1995 Fred Fish - - * Makefile.in (distclean): Remove generated file config.h. - -Sat Aug 5 16:50:14 1995 Fred Fish - - * Makefile.in (distclean): Remove generated file config.h. - -Wed Aug 2 18:33:40 1995 Ian Lance Taylor - - * m68k-opc.c: New file, holding tables from include/opcode/m68k.h. - Clean up tables. - * m68k-dis.c: Remove BREAK_UP_BIG_DECL stuff. - (opcode): Remove. - (print_insn_m68k): Change d to be const. Use m68k_numopcodes - rather than numopcodes. Use m68k_opcodes rather than removed - opcode function. Don't check F_ALIAS. - (print_insn_arg): Change first parameter to be const char *. - * Makefile.in (ALL_MACHINES): Add m68k-opc.o. - (m68k-opc.o): New target. - * configure.in: Build m68k-opc.o for bfd_m68k_arch. - * configure: Rebuild. - -Wed Aug 2 08:23:38 1995 Doug Evans - - * sparc-dis.c (HASH_SIZE, HASH_INSN): Define. - (opcode_bits, opcode_hash_table): New variables. - (opcodes_initialized): Renamed from opcodes_sorted. - (build_hash_table): New function. - (is_delayed_branch): Use hash table. - (print_insn): Renamed from print_insn_sparc, made static. - Build and use hash table. If !sparc64, ignore sparc64 insns, - and vice-versa if sparc64. - (print_insn_sparc, print_insn_sparc64): New functions. - (compare_opcodes): Move sparc64 opcodes to end. - Print commutative insns with constant second. - * sparc-opc.c (all non-v9 insns): Use flag F_NOTV9 instead of F_ALIAS. - -Tue Aug 1 00:12:49 1995 Ian Lance Taylor - - * sh-dis.c (print_insn_shx): Remove unused local dslot. Use - print_address_func for A_BDISP12 and A_BDISP8. Correct test which - avoids printing a delay slot in a delay slot. - * sh-opc.h (sh_table): Fully bracket last entry. - -Mon Jul 31 12:04:47 1995 Doug Evans - - * sparc-opc.c (sllx, srax, srlx): Fix disassembly. - -Wed Jul 12 00:59:34 1995 Ken Raeburn - - * configure.in: Get host_makefile_frag from ${srcdir}. - - * configure.in: Autoconfiscated. Check for string[s].h. Create - config.h from config.in. Don't set up sysdep.h link. - * sysdep.h: New file. - * configure, config.in: New files, generated from configure.in. - * Makefile.in: Updated to be processed autoconf-style. - (distclean): Keep sysdep.h. Remove config.log and config.cache. - (Makefile): Depend on config.status. - (config.status): New rule. - * configure.bat: Update Makefile substitutions. - -Tue Jul 11 14:23:37 1995 Jeff Spiegel - - * mips-opc.c (L1): Define. - (mips_opcodes): Add R4010 instructions: flushi, flushd, flushid, - addciu, madd, maddu, ffc, ffs, msub, msubu, selsi, selsr, waiti, - and wb. - -Tue Jul 11 11:49:49 1995 Ian Lance Taylor - - * mips-opc.c (mips_opcodes): For the move pseudo-op, prefer daddu - if ISA 3 and addu otherwise, replacing or, since some MIPS chips - have multiple add units but only a single logical unit. - - * ppc-opc.c (powerpc_operands): Change CR to use a bitsize of 3, - shifted by 18, without any insertion or extraction function. - (insert_cr, extract_cr): Remove. - -Wed Jun 21 20:05:39 1995 Ken Raeburn - - * m68k-dis.c (print_insn_arg, print_indexed): Print "%" before - register names. - -Thu Jun 15 17:23:31 1995 Stan Shebs - - * mpw-config.in: Add sh and i386 configs, remove sparc config. - * sh-opc.h: Add copyright. - -Mon Jun 5 03:30:43 1995 Ken Raeburn - - * Makefile.in (crunch-m68k): Delete extra target accidentally - checked in a while ago. - -Wed May 24 16:22:13 1995 Jim Wilson - - * sh-opc.h (sh_table): Add SH3 support. - -Wed May 24 14:16:08 1995 Steve Chamberlain - - * sh-opc.h: Added bsrf and braf. - -Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk) - - * arm-opc.h (arm_opcodes): Add 64-bit multiply patterns. Delete - bogus [ls]fm{ea,fd} patterns. - - * arm-opc.h (arm_opcodes): Correct typos in stm, ldm, std, and ldc. - * arm-dis.c (print_insn_arm): Make GIVEN a parameter, don't try and - initialize it from memory. Make function static. - (print_insn_{big,little}_arm): New functions. - * disassemble.c (disassembler, case bfd_arch_arm): Disassemble for - the correct endianness. - - -Mon Apr 24 14:18:05 1995 Jason Molenda (crash@phydeaux.cygnus.com> - - * sh-opc.h (sh_nibble_type, sh_arg_type): remove trailing , from - enum list. - -Wed Apr 19 14:07:03 1995 Michael Meissner - - * m68k-dis.c (opcode): Finish change made by Kung Hsu on April - 17th, so that it builds again using GCC as the compiler. - -Tue Apr 18 12:14:51 1995 Ken Raeburn - - * mips-dis.c (print_insn_little_mips): Cast return value from - bfd_getl32 from bfd_vma to unsigned long, because _print_insn_mips - expects an unsigned long, and that might be fewer words of - argument storage (e.g., if bfd_vma is long long on a 32-bit - machine). - (print_insn_big_mips): Likewise with bfd_getb32 value. - (_print_insn_mips): Now static. - -Mon Apr 17 12:23:28 1995 Kung Hsu - - * m68k-dis.c: Take out #define BREAK_UP_BIG_DECL kludge, because - gcc memory hog problem with initializer is fixed. - - -Mon Apr 10 15:55:01 1995 Stan Shebs - - Merge in support for Mac MPW as a host. - (Old change descriptions retained for informational value.) - - * mpw-config.in (archname): Compute from the config. - (BFD_MACHINES, ARCHDEFS): Put into mk.tmp. - - * mpw-config.in (target_arch): Compute from canonical target. - (m68k, mips, powerpc, sparc): Add architectures. - * mpw-make.in (disassemble.c.o): Add. - (ALL_CFLAGS): Remove special flags (-mc68020 -mc68881 -model far). - - * mpw-config.in (BFD_MACHINES): Set to a default value. - * mpw-make.in (BFD_MACHINES): Remove wired-in value. - - * mpw-make.in (CSEARCH): Add extra-include to search path. - - * mpw-config.in (varargs.h): Don't create. - (sysdep.h): Create using forward-include. - * mpw-make.in (CSEARCH): Add include/mpw to search path. - - * mpw-config.in: New file, MPW version of configure.in. - * mpw-make.in: New file, MPW version of Makefile.in. - - -Fri Mar 31 14:23:38 1995 Ken Raeburn - - * alpha-dis.c (print_insn_alpha): Put empty statement after - default label. - -Tue Mar 21 10:51:40 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa-dis.c (sign_extend): Delete, redundant with libhppa.h version. - (low_sign_extend): Likewise. - (get_field): Delete unused function. - (set_field, deposit_14, deposit_21): Likewise. - -Fri Mar 17 15:55:53 1995 J.T. Conklin - - * i386-dis.c: Support for more pentium opcodes. From Guy Harris - (guy@netapp.com). - -Tue Mar 14 00:52:57 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - Sat Feb 11 17:22:41 1995 Klaus Kaempf (kkaempf@didymus.rmi.de) - - * alpha-opc.h (OSF_ASMCODE): define - print pal-code names as defined in App C of the - Alpha Architecture Reference Manual - - * alpha-dis.c: cleaned up output - print stylized code forms as defined in App A.4.3 of the - Alpha Architecture Reference Manual - -Wed Mar 8 15:21:14 1995 Ian Lance Taylor - - * mips-opc.c: Add new mips4 instructions. Don't set INSN_RFE for - `rfe'. - * mips-dis.c (print_insn_arg): Handle new argument types 'h', 'R', - 'N', and 'M'. - -Wed Mar 8 02:54:05 1995 Ken Raeburn - - * m68k-dis.c (opcode): New function. Returns address of opcode - table entry given index, even if the opcode table was split to - work around gcc bugs. - (print_insn_m68k): Call opcode instead of referencing m68k_opcodes - directly. - (BREAK_UP_BIG_DECL): Make secondary array static and const. - (reg_names): Now const. - (print_insn_arg): Arrays cacheFieldName and names now const. - (print_indexed): Array scales now const. - - -Tue Mar 7 16:41:21 1995 Ian Lance Taylor - - * ppc-opc.c: Sort recently added instructions by minor opcode - number within major opcode number. - -Mon Mar 6 10:04:36 1995 Jeff Law (law@snake.cs.utah.edu) - - * hppa-dis.c: Include libhppa.h. - -Fri Feb 24 19:15:36 1995 Ian Lance Taylor - - * mips-opc.c: Change dli to use M_DLI, and add dla. - -Mon Feb 20 23:54:38 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * Makefile.in (ALL_MACHINES): Add w65-dis.o. - - -Thu Feb 16 17:34:41 1995 Ian Lance Taylor - - * mips-opc.c: Add r4650 mul instruction. - -Wed Feb 15 15:45:20 1995 Ian Lance Taylor - - * mips-opc.c: Add uld and usd macros for unaligned double load and - store. - -Tue Feb 14 13:17:37 1995 Michael Meissner - - * ppc-opc.c (powerpc_opcodes): Add 403GA opcodes rfci, dccci, - mfdcr, mtdcr, icbt, iccci. - - -Thu Feb 9 12:28:13 1995 Stan Shebs - - * i960-dis.c (struct tabent, struct sparse_tabent): Change the - signed char fields to shorts, more portable. - -Wed Feb 8 17:29:29 1995 Stan Shebs - - * i960-dis.c (struct tabent, struct sparse_tabent): Declare the - char fields as signed chars, since they may have negative values. - -Mon Feb 6 10:52:06 1995 J.T. Conklin - - * i386-dis.c (dis386_twobyte): Add cpuid, From Charles Hannum - (mycroft@netbsd.org). - -Mon Jan 30 12:38:00 1995 Ian Lance Taylor - - From "Logg, Ed" : - * ppc-opc.c (extract_bdm): Correct parenthezisation. - * ppc-dis.c (print_insn_powerpc): Print .long before unrecognized - value. - -Thu Jan 26 18:32:08 1995 Ian Lance Taylor - - * ppc-opc.c: Changes based on patch from David Edelsohn - . - (powerpc_operands): Add operands SPRBAT and SPRG. Split TBR out of - SPR. - (FXM_MASK): Define. - (insert_tbr): New static function. - (extract_tbr): New static function. - (XFXFXM_MASK, XFXM): Define. - (XSPRBAT_MASK, XSPRG_MASK): Define. - (powerpc_opcodes): Add instructions to access special registers by - name. Add mtcr and mftbu. - -Tue Jan 17 10:56:43 1995 Ian Lance Taylor - - * mips-opc.c (P3): Define. - (mips_opcodes): Add mad and madu. - -Sun Jan 15 16:32:59 1995 Steve Chamberlain - - * configure.in: Add W65 support. - * disassemble.c: Likewise. - * w65-opc.h, w65-dis.c: New files. - -Wed Dec 28 22:15:33 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * h8300-dis.c (bfd_h8_disassemble): Add support for 2 bit - immediates. - - -Tue Dec 20 11:25:12 1994 Ian Lance Taylor - - * mips-opc.c: Add dli as a synonym for li. - - -Thu Dec 8 18:23:31 1994 Ken Raeburn - - * alpha-dis.c (print_insn_alpha): Handle call_pal instruction, and - print something for reserved opcode values, even if it won't - assemble again. - - * mips-dis.c (_print_insn_mips): When initializing, shift right - and mask, to avoid sign extension problems on the Alpha. - - * m68k-dis.c (print_insn_arg, case 'J'): Handle buscr and pcr - control registers. - - -Wed Nov 23 22:34:51 1994 Steve Chamberlain (sac@jonny.cygnus.com) - - * sh-opc.h (mov.l gbr): Get direction right. - * sh-dis.c (print_insn_shx): New function. - (print_insn_shl, print_insn_sh): Call print_insn_shx to - print opcodes with right byte order. - -Thu Nov 3 19:32:22 1994 Ken Raeburn - - * ns32k-dis.c (struct ns32k_option): Renamed from struct option, - to avoid conflicts with getopt. - -Mon Oct 31 18:48:10 1994 Ian Lance Taylor - - * hppa-dis.c (print_insn_hppa): Read the instruction using - bfd_getb32, so that it works on a little endian or 64 bit host. - Remove unused local variable op. - -Tue Oct 25 17:07:57 1994 Ian Lance Taylor - - * mips-opc.c: Use or instead of addu for pseudo-op move, since - addu does not work correctly if -mips3. - -Wed Oct 19 13:40:16 1994 Ian Lance Taylor - - * a29k-dis.c (print_special): Add special register names defined - on 29030, 29040 and 29050. - (print_insn): Handle new operand type 'I'. - -Wed Oct 12 11:59:55 1994 Ian Lance Taylor - - * Makefile.in (INSTALL): Use top level install.sh script. - -Wed Oct 5 19:16:29 1994 Ian Lance Taylor - - * sparc-dis.c: Rewrite to use bitfields, rather than a union, so - that it works on a little endian host. - -Tue Oct 4 12:14:21 1994 Ian Lance Taylor - - * configure.in: Use ${config_shell} when running config.bfd. - -Wed Sep 21 18:49:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * mips-opc.c (mips_opcodes): "dabs" is only available with -mips3. - -Thu Sep 15 16:30:22 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * a29k-dis.c (print_insn): Print the opcode. - -Wed Sep 14 17:52:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * mips-opc.c (mips_opcodes): Set WR_t for sc and scd. - -Sun Sep 11 22:32:17 1994 Jeff Law (law@snake.cs.utah.edu) - - * hppa-dis.c (reg_names): Use r26-r23 for arg0-arg3. - -Tue Sep 6 11:37:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * mips-opc.c: Set INSN_STORE_MEMORY flag for all instructions - which store a value into memory. - -Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org) - - * configure.in, Makefile.in, disassemble.c: Add support for the ARM. - * arm-dis.c, arm-opc.h: New files. - -Fri Aug 5 14:00:05 1994 Stan Shebs (shebs@andros.cygnus.com) - - * Makefile.in (ns32k-dis.o): Add dependency. - * ns32k-dis.c (print_insn_arg): Declare initialized local as - string, not as array of chars. - -Thu Jul 28 18:14:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * sparc-dis.c (print_insn_sparc): Handle new operand type 'x'. - - * sparc-opc.c: Added sparclite extended FP operations, and - versions of v9 impdep* instructions permitting specification of - the OPF field. - -Tue Jul 26 16:36:03 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * i960-dis.c (reg_names): Now const. - (struct sparse_tabent): New type, copied from array type in mem - function. - (ctrl): Local static array ctrl_tab now const. - (cobr): Local static array cobr_tab now const. - (mem): Local variables reg1, reg2, reg3 now point to const. Local - static variable mem_tab no longer explicitly initialized. Changed - mem_init to const array of struct sparse_tabent. - (reg): Local static variable reg_tab no longer explicitly - initialized. Changed reg_init to const array of struct - sparse_tabent. - (ea): Local static array scale_tab now const. - - * i960-dis.c (reg): Added i960JX instructions to reg_init table. - (REG_MAX): Updated. - -Tue Jul 19 21:00:00 1994 DJ Delorie (dj@ctron.com) - - * configure.bat: the disassember needs to be enabled for - "objdump -d" to work in djgpp. - -Wed Jul 13 18:01:58 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * ns32k-dis.c: Deleted all code in "#ifdef GDB". - (invalid_float): Enabled general version, doesn't require running - on ns32k host. Changed to take char* argument, and test for - explicitly specified sizes, instead of using sizeof() on host CPU - types. - (INVALID_FLOAT): Cast first argument. - (opt_u, opt_U, opt_O, opt_C, opt_S, list_P532, list_M532, - list_P032, list_M032): Now const. - (optlist, list_search): Made appropriate arguments now point to - const. - (print_insn_arg): Changed static array of one-character-string - pointers into a static const array of characters; fixed sprintf - statement accordingly. - -Sun Jul 10 00:27:47 1994 Ian Dall (dall@hfrd.dsto.gov.au) - - * opcodes/ns32k-dis.c: Semi-new file. Had apparently been dropped - from distribution. A ns32k-dis.c from a previous distribution has - been brought up to date and supports the new interface. - - * disassemble.c: define ARCH_ns32k and add case bfd_arch_ns32k. - - * configure.in: add bfd_ns32k_arch target support. - - * Makefile.in: add ns32k-dis.o to ALL_MACHINES. - Add ns32k-dis.c to CFILES. Add dependencies for ns32k-dis.o. - -Wed Jun 29 22:10:37 1994 Steve Chamberlain (sac@cygnus.com) - - * h8300-dis.c (bfd_h8_disassemble): Get 16bit branch - disassembly right. - -Tue Jun 28 13:22:06 1994 Stan Shebs (shebs@andros.cygnus.com) - - * h8300-dis.c, mips-dis.c: Don't use true and false. - -Thu Jun 23 12:53:19 1994 David J. Mackenzie (djm@rtl.cygnus.com) - - * configure.in: Change --with-targets to --enable-targets. - -Wed Jun 22 13:38:32 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * mips-dis.c (_print_insn_mips): Build a static hash table mapping - opcodes to the first instruction with that opcode, to speed - disassembly of large files. From ralphc@pyramid.com (Ralph - Campbell). - -Tue Jun 7 12:49:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * Makefile.in (mostlyclean): Fix typo (was mostyclean). - -Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com) - - * configure.bat: update to latest makefile.in - -Sat May 7 17:13:21 1994 Steve Chamberlain (sac@cygnus.com) - - * a29k-dis.c (print_insn): Print 'x' type operand in hex. - * h8300-dis.c (bfd_h8_disassemble): Print 16bit rels correctly. - * sh-dis.c (print_insn_sh): Don't recur endlessly if delay - slot insn is in a delay slot. - * z8k-opc.h: (resflg): Fix patterns. - * h8500-opc.h Fix CR insn patterns. - -Fri May 6 14:34:46 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc-opc.c (powerpc_opcodes): Put PowerPC versions of "cmp" and - "cmpl" before POWER versions, so that gas -many uses them. - -Thu Apr 28 18:32:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * disassemble.c: New file. - * Makefile.in (OFILES): Add disassemble.o. - (disassemble.o): Provide dependencies; compile with $(ARCHDEFS). - * configure.in: Define ARCHDEFS in Makefile. Code taken from - binutils/configure.in. - - * m68k-dis.c (print_insn_m68k): If F_ALIAS flag is set, skip the - opcode being examined. - -Thu Apr 21 17:08:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc-opc.c (powerpc_operands): Added RAL, RAM and RAS. - (insert_ral, insert_ram, insert_ras): New functions. - (powerpc_opcodes): Use RAL for load with update, RAM for lmw, and - RAS for store with update. - -Sat Apr 16 23:41:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc-opc.c (powerpc_opcodes): Correct fcir. From David Edelsohn - (edelsohn@npac.syr.edu). - -Wed Apr 6 17:11:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c (mips_opcodes): Correct operands of "nor" with an - immediate argument. - -Mon Apr 4 16:30:46 1994 Doug Evans (dje@canuck.cygnus.com) - - * sparc-opc.c (sparc_opcodes): Fix "rd %fprs,%l0". - -Mon Apr 4 13:22:00 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc-opc.c (powerpc_operands): The signedp field has been - removed, so don't initialize it. Set the PPC_OPERAND_SIGNED flag - instead. Add new operand SISIGNOPT. - (powerpc_opcodes): For lis, liu, addis, and cau use SISIGNOPT. - Based on patch from David Edelsohn (edelsohn@npac.syr.edu). - * ppc-dis.c (print_insn_powerpc): Check PPC_OPERAND_SIGNED rather - than signedp field. - -Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * i386-dis.c (struct private): Renamed to dis_private. `private' - is a reserved word for dynix cc. - -Mon Mar 28 13:00:15 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Change error message to refer to bfd/config.bfd - rather than bfd/configure.in. - -Mon Mar 28 12:28:30 1994 David Edelsohn (edelsohn@npac.syr.edu) - - * ppc-opc.c: Define POWER2 as short alias flag. - (powerpc_opcodes): Add POWER/2 opcodes lfq*, stfq*, fcir[z], and - fsqrt. - -Wed Mar 23 12:23:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * i960-dis.c (print_insn_i960): Don't read a second word for - opcodes 0, 1, 2 and 3. - -Wed Mar 16 15:37:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Don't build m68881-ext.o for bfd_m68k_arch. - -Mon Mar 14 14:53:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m68881-ext.c: Removed; no longer used. - * Makefile.in: Changed accordingly. - - * m68k-dis.c (ext_format_68881): Don't declare. - (print_insn_m68k): If an instruction uses place 'i', it uses at - least four fixed bytes. - (print_insn_arg): Don't bump p by 2 for case 'I', place 'i'. For - extended float, convert to double using floatformat_to_double, not - ieee_extended_to_double, and fetch the data before converting it. - -Tue Mar 8 18:12:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: It's sqrt.s, not sqrt.w. From - davidj@ICSI.Berkeley.EDU (David Johnson). - -Tue Feb 8 16:55:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc-opc.c (powerpc_opcodes): The POWER uses bdn[l][a] where the - PowerPC uses bdnz[l][a]. - -Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * dis-buf.c, i386-dis.c: Include sysdep.h. - -Mon Feb 7 19:22:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in (bfd_powerpc_arch): Use ppc-dis.o and ppc-opc.o. - - * ppc-opc.c (powerpc_opcodes): Mark POWER instructions supported - by Motorola PowerPC 601 with PPC_OPCODE_601. - * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc): - Disassemble Motorola PowerPC 601 instructions as well as normal - PowerPC instructions. - -Sun Feb 6 07:45:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * i960-dis.c (reg, mem): Just use a static array instead of - calling xmalloc. - -Sat Feb 5 00:04:02 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-dis.c (print_insn_hppa): For '?' and '@' only adjust the - condition name index if this is for a negated condition. - - * hppa-dis.c (print_insn_hppa): No space before 'H' operand. - Floating point format for 'H' operand is backwards from normal - case (0 == double, 1 == single). For '4', '6', '7', '9', and '8' - operands (fmpyadd and fmpysub), handle bizarre register - translation correctly for single precision format. - - * hppa-dis.c (print_insn_hppa): Do not emit a space after 'F' - or 'I' operands if the next format specifier is 'M' (fcmp - condition completer). - -Feb 4 23:38:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc-opc.c (powerpc_operands): New operand type MBE to handle a - single number giving a bitmask for the MB and ME fields of an M - form instruction. Change NB to accept 32, and turn it into 0; - also turn 0 into 32 when disassembling. Seperated SH from NB. - (insert_mbe, extract_mbe): New functions. - (insert_nb, extract_nb): New functions. - (SC_MASK): Mask out SA and LK bits. - (powerpc_opcodes): Change "cal" to use RT, D, RA rather than RT, - RA, SI. Change "liu" and "cau" to use UI rather than SI. Mark - "bctr" and "bctrl" as accepted by POWER. Change "rlwimi", - "rlimi", "rlwimi.", "rlimi.", "rlwinm", "rlinm", "rlwinm.", - "rlinm.", "rlmi", "rlmi.", "rlwnm", "rlnm", "rlwnm.", "rlnm." to - use MBE rather than MB. Add "mfmq" and "mtmq" POWER instructions. - (powerpc_macros): Define table of macro definitions. - (powerpc_num_macros): Define. - - * ppc-dis.c (print_insn_powerpc): Don't skip optional operands - if PPC_OPERAND_NEXT is set. - -Sat Jan 22 23:10:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * i960-dis.c (print_insn_i960): Make buffer bfd_byte instead of - char. Retrieve contents using bfd_getl32 instead of shifting. - -Fri Jan 21 19:01:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * ppc-opc.c: New file. Opcode table for PowerPC, including - opcodes for POWER (RS/6000). - * ppc-dis.c: New file. PowerPC and Power (RS/6000) disassembler. - * Makefile.in (ALL_MACHINES): Add ppc-dis.o and ppc-opc.o. - (CFILES): Add ppc-dis.c. - (ppc-dis.o, ppc-opc.o): New targets. - * configure.in: Build ppc-dis.o and ppc-opc.o for bfd_rs6000_arch. - -Mon Jan 17 20:05:49 1994 Jeffrey A. Law (law@snake.cs.utah.edu) - - * hppa-dis.c (print_insn_hppa): Handle 'N' in assembler template. - No space before 'u', 'f', or 'N'. - -Sun Jan 16 14:20:16 1994 Jim Kingdon (kingdon@deneb.cygnus.com) - - * i386-dis.c (print_insn_i386): Add FIXME comment regarding reading - farther than we should. - - * i386-dis.c (dis386): Use Yb and Yv for scasb and scasS. - -Thu Jan 6 12:38:05 1994 David J. Mackenzie (djm@thepub.cygnus.com) - - * sparc-dis.c m68k-dis.c alpha-dis.c a29k-dis.c: Fix comments. - -Wed Jan 5 11:56:21 1994 David J. Mackenzie (djm@thepub.cygnus.com) - - * i960-dis.c (print_insn_i960): Only read word2 if the instruction - needs it, to prevent reading past the end of a section. - -Wed Nov 17 17:20:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.h: Use macro for j instruction, to support SVR4 PIC. - Removed t,A case for la; always use t,A(b) case. - -Mon Nov 8 12:37:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - From Ted Lemen - * mips-dis.c (print_insn_arg): Handle 'k'. - * mips-opc.c: Make cache use k, not t. - -Sun Nov 7 23:52:34 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-opc.h, alpha-dis.c (print_insn_alpha): Add - FLOAT_MEMORY_FORMAT_CODE, FLOAT_BRANCH_FORMAT_CODE, correct - FLOAT_FORMAT_CODE to put out floating point register names. - -Mon Nov 1 18:17:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Use macros for jal variants, to support SVR4 PIC. - -Thu Oct 28 17:42:23 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * a29k-dis.c (print_insn): Use 0x%08x, not 0x%8x. - -Wed Oct 27 11:48:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c (dsll, dsra, dsrl): Added '>' cases for shift counts - larger than 32. Moved dsxx32 variants first for disassembler. - -Mon Oct 25 11:33:14 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * z8kgen.c, z8k-opc.h: Add full lda information. - -Tue Oct 19 12:39:25 1993 Jeffrey A Law (law@cs.utah.edu) - - * hppa-dis.c (print_insn_hppa): Do not emit a space after - movb instructions. Any necessary space will be emitted by - the code to handle nullification completers. - -Wed Oct 13 16:19:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Moved l.d down so that it disassembles as ldc1. - -Fri Oct 8 02:34:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-opc.h: Add ldl_l, fix typo for ldq_u. - * alpha-dis.c (print_insn_alpha): Add code for PAL_FORMAT_CODE. - -Tue Oct 5 17:47:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Correct lwu opcode value (book had it wrong). - -Thu Sep 30 11:26:18 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * z8k-dis.c (FETCH_DATA): get just the right amount of data. - (unpack_instr): Cope with ARG_IMM4M1 type instructions. - -Wed Sep 29 16:24:49 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * m88k-dis.c (m88kdis): comment change. Remove space after - printing mnemonic. - (printop): handle new arg types DEC and XREG for m88110. - -Tue Sep 28 19:20:16 1993 Jeffrey A Law (law@snake.cs.utah.edu) - - * hppa-dis.c (print_insn_hppa): Handle 'z' operand - type for absolute branch addresses. Delete special - "ble" and "be" code in 'W' operand code. - -Fri Sep 24 14:08:33 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Set hazard information correctly for branch - likely instructions. - -Fri Sep 17 04:41:17 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * alpha-dis.c (print_insn_alpha), alpha-opc.h: Fix bugs, use - info->fprintf_func for printing and info->print_address_func for - address output. - -Wed Sep 15 12:12:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Set INSN_TRAP for tXX instructions. - -Thu Sep 9 10:11:27 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: From davidj@ICSI.Berkeley.EDU (David Johnson): - Corrected second case of "b" for disassembler. - -Tue Sep 7 14:25:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-dis.c, m88k-dis.c: Don't include libbfd.h. Changed calls - to BFD swapping routines to correspond to BFD name changes. - -Thu Sep 2 10:35:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Change div machine instruction to be z,s,t rather - than s,t. Change div macro to be d,v,t rather than d,s,t. - Likewise for divu, ddiv, ddivu. Added z,s,t case for drem, dremu, - rem and remu which generates only the corresponding div - instruction. This is for compatibility with the MIPS assembler, - which only generates the simple machine instruction when an - explicit destination of $0 is used. - * mips-dis.c (print_insn_arg): Handle 'z' (always register zero). - -Thu Aug 26 17:41:44 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: From davidj@ICSI.Berkeley.EDU (David Johnson): Set - WR_31 hazard for bal, bgezal, bltzal. - -Thu Aug 26 17:20:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * hppa-dis.c (print_insn_hppa): Use print function - from within the disassemble_info, not fprintf_filtered. - -Wed Aug 25 13:51:40 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * hppa-dis.c (print_insn_hppa): Handle '|' like '>'. (From Jeff - Law, law@cs.utah.edu.) - -Mon Aug 23 12:44:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c ("absu"): Removed. - ("dabs"): Added. - -Fri Aug 20 10:52:52 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Added r6000 and r4000 instructions and macros. - Changed hazard information to distinguish between memory load - delays and coprocessor load delays. - -Wed Aug 18 15:39:23 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: li.d uses "T,L", not "S,F". Added li.s. - -Tue Aug 17 09:44:42 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * configure.in: Don't pass cpu to config.bfd. - -Tue Aug 17 12:23:52 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m88k-dis.c (m88kdis): Make class unsigned. - -Thu Aug 12 15:08:18 1993 Ian Lance Taylor (ian@cygnus.com) - - * alpha-dis.c (print_insn_alpha): One branch format case was - missing the instruction name. - -Wed Aug 11 19:29:39 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * Makefile.in (ALL_MACHINES): Renamed from DIS_LIBS. - Add the arch-specific auxiliary files. - (OFILES): Remove the arch-specific auxiliary files - and use BFD_MACHINES instead of DIS_LIBS. - * configure.in: Set BFD_MACHINES based on --with-targets option. - -Thu Aug 12 12:04:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: Added lwc1 E,A(b) to go with lwc1 T,A(b). Similarly - for swc1. - -Sun Aug 8 15:09:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * sparc-opc.c: Change CONST to const to deal with gcc - -Dconst=__const -traditional. - -Fri Aug 6 10:58:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-opc.c: From davidj@ICSI.Berkeley.EDU (David Johnson): Took - coprocessor instructions out of #if 0, and made them use new - argument type "C". - -Thu Aug 5 17:11:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * sparc-dis.c: Include ansidecl.h before opcodes/sparc.h. - -Fri Jul 30 18:48:15 1993 John Gilmore (gnu@cygnus.com) - - * sparc-opc.c: Add F_JSR, F_UNBR, or F_CONDBR flags to each branch - instruction, for use by the disassembler. - - * sparc-dis.c (SEX): Add sign extension macro. Replace many - hand-coded sign extensions that depended on 32-bit host ints. - FIXME, we still depend on big-endian host bitfield ordering. - (sparc_print_insn): Set the insn_info_valid field, and the - other fields that describe the instruction being printed. - -Tue Jul 27 17:04:58 1993 Jim Wilson (wilson@sphagnum.cygnus.com) - - * sparc-opc.c (call): Accept all 6 addressing modes valid for - `jmp' instead of just one of them. - -Wed Jul 21 11:43:32 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * hppa-dis.c: Move floating registers from reg_names to fp_reg_names. - (fput_fp_reg_r): Renamed from fput_reg_r. - (fput_fp_reg): New function. - (print_insn_hppa): Use fput_fp_reg{,_r} where appropriate. - - * hppa-dis.c (print_insn_hppa, cases 'a', 'd'): Print space afterwards. - - * hppa-dis.c (print_insn_hppa, case 'd'): Use GET_COND not GET_FIELD. - -Mon Jul 19 13:52:21 1993 Jim Kingdon (kingdon@deneb.cygnus.com) - - * hppa-dis.c (print_insn_hppa): Use extract_5r_store for 'r'. - - * hppa-dis.c (print_insn_hppa, case '>'): If next character is 'n', - don't output a space. - - * hppa-dis.c (float_format_names): 10 is undefined, and 11 is quad. - -Sun Jul 18 16:30:02 1993 Jim Kingdon (kingdon@rtl.cygnus.com) - - * mips-opc.c: New file, containing opcode table from - ../include/opcode/mips.h. - * Makefile.in: Add it. - -Thu Jul 15 12:37:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * m88k-dis.c: New file, moved in from gdb and changed to use the - new dis-asm.h disassembler interface. - * Makefile.in (DIS_LIBS): Added m88k-dis.o. - (m88k-dis.o): New target. - -Tue Jul 13 10:04:16 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips-dis.c (print_insn_arg, _print_insn_mips): Made pointer to - argument string const char * to correspond to opcode/mips.h. - -Tue Jul 6 15:18:37 1993 Ian Lance Taylor (ian@cygnus.com) - - * mips-dis.c: Updated to account for name changes in new version - of opcode/mips.h. - * Makefile.in: Added header file dependencies. - -Sat Jul 3 23:47:56 1993 Doug Evans (dje@canuck.cygnus.com) - - * h8300-dis.c (bfd_h8_disassemble): Correct fetching of instruction. - -Thu Jul 1 12:23:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * m68k-dis.c (NEXTWORD, NEXTLONG): Use ((x) ^ 0x8000) - 0x8000 to sign - extend, rather than shifts. - -Sun Jun 20 20:56:56 1993 Ken Raeburn (raeburn@poseidon.cygnus.com) - - * Makefile.in: Undo 15 June change. - -Fri Jun 18 14:15:15 1993 Per Bothner (bothner@deneb.cygnus.com) - - * m68k-dis.c (print_insn_arg): Change return value to byte count - or error code. - * m68k-dis.c: Re-write to detect invalid operands before - printing anything, so we can handle this the same way we - handle invalid opcodes. - -Thu Jun 17 15:01:36 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * sh-dis.c, sh-opc.h: Understand some more opcodes. - -Wed Jun 16 13:48:05 1993 Ian Lance Taylor (ian@cygnus.com) - - * hppa-dis.c: Include and sysdep.h before other - header files. - -Tue Jun 15 21:45:26 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * sparc-dis.c: Don't declare qsort, since sysdep.h might. - - * configure.in: Do make sysdep.h link. - * Makefile.in: Search ../include. Don't search ../bfd. - -Tue Jun 15 13:36:10 1993 Stu Grossman (grossman@cygnus.com) - - Changes from Jeff Law, law@cs.utah.edu: - * hppa-dis.c: Fix typo. 'a' and 'd' were reversed. - Do not print a space before the completers specified by - 'a' and 'd'. - -Fri Jun 11 18:40:21 1993 Ken Raeburn (raeburn@cygnus.com) - - * mips-dis.c: No longer need to bomb out if HOST_64_BIT is - defined, since gdb has been fixed. - - Changes from Jeff Law, law@cs.utah.edu: - * hppa-dis.c (print_insn_hppa): Last argument to fput_reg, - fput_reg_r, fput_creg, fput_const, and fputs_filtered should - be a *disassemble_info, not a *FILE. - * hppa-dis.c: Support 'd', '!', and 'a'. - * hppa-dis.c: Support 's' to extract a 2 bit space register. - * hppa-dis.c: Delete cases which are no longer needed. - -Fri Jun 11 07:53:48 1993 Jim Kingdon (kingdon@cygnus.com) - - * m68k-dis.c (print_insn_{m68k,arg}): Add MMU codes. - -Tue Jun 8 12:25:01 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) - - * h8300-dis.c: New file, removed from bfd/cpu-h8300.c, with - H8/300-H opcodes. - -Mon Jun 7 12:58:49 1993 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in (CSEARCH): Add -I../bfd for sysdep.h and bfd.h. - * configure.in: No longer need to configure to get sysdep.h. - -Thu Jun 3 15:56:49 1993 Stu Grossman (grossman@cygnus.com) - - * Patches from Jeffrey Law . - * hppa-dis.c: Support 'I', 'J', and 'K' in output - templates for 1.1 FP computational instructions. - -Tue May 25 13:05:48 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * h8500-dis.c (print_insn_h8500): Address argument is type - bfd_vma. - * z8k-dis.c (print_insn_z8k, print_insn_z8001, print_insn_z8002): - Ditto. - - * h8500-opc.h (addr_class_type): No comma at end of enumerator. - * sh-opc.h (sh_nibble_type, sh_arg_type): Ditto. - - * sparc-dis.c (compare_opcodes): Move static declaration to - top-level. - -Fri May 21 14:17:37 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * sparc-dis.c (print_insn_sparc): Implement 'n' argument for unimp - instruction, remove unimp hack from 'l' argument. - -Wed May 19 15:35:54 1993 Stu Grossman (grossman@cygnus.com) - - * z8k-dis.c (fetch_data): Use unsigned char to make ancient gcc's - happy. - -Fri May 14 15:22:46 1993 Ian Lance Taylor (ian@cygnus.com) - - * Based on patches from davidj@ICSI.Berkeley.EDU (David Johnson): - * mips-dis.c (print_insn_arg): Handle 'C' for general coprocessor - instructions. - -Fri May 14 00:09:14 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * hppa-dis.c: Include dis-asm.h before sysdep.h. Changed some - arrays of string pointers to 2-d arrays of chars, to save - space. - -Thu May 6 20:51:17 1993 Fred Fish (fnf@cygnus.com) - - * a29k-dis.c, alpha-dis.c, i960-dis.c, sparc-dis.c, z8k-dis.c: - Cast second arg to read_memory_func to "bfd_byte *", as necessary. - -Tue May 4 20:31:10 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * hppa-dis.c: New file from Utah, adapted to new disassembler - calling interface. - * Makefile.in: Include it. - -Mon Apr 26 18:17:42 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * sh-dis.c, sh-opc.h: New files. - -Fri Apr 23 18:51:22 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * alpha-dis.c, alpha-opc.h: New files. - -Tue Apr 6 12:54:08 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) - - * mips-dis.c: Sign extend 'j' and 'b' arguments, delta is a signed - value. - -Mon Apr 5 17:37:37 1993 John Gilmore (gnu@cygnus.com) - - * sparc-dis.c: Make "ta" the default trap instruction, "t" the alias. - -Fri Apr 2 07:24:27 1993 Ian Lance Taylor (ian@cygnus.com) - - * a29k-dis.c, sparc-dis.c, sparc-opc.c: Use CONST rather than - const. - -Thu Apr 1 11:20:43 1993 Jim Kingdon (kingdon@cygnus.com) - - * sparc-dis.c: Use fprintf_func a few places where I forgot, - and double percent signs a few places. - - * a29k-dis.c, i960-dis.c: New, merged from gdb and binutils. - - * i386-dis.c, m68k-dis.c, mips-dis.c, sparc-dis.c: - Use info->print_address_func not print_address. - - * dis-buf.c (generic_print_address): New function. - -Wed Mar 31 10:07:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Add sparc-dis.c. - sparc-dis.c: New file, merges binutils and gdb versions as follows: - From GDB: - Add `add' instruction to the set that get checked - for a preceding `sethi' in order to print an absolute address. - * (print_insn): Disassembly prefers real instructions. - (is_delayed_branch): Speed up. - * sparc-opcode.h: Add ALIAS bit to aliases. Fix up opcode tables. - Still missing some float ops, and needs testing. - * sparc-pinsn.c (print_insn): Eliminate 'set' test, subsumed by - F_ALIAS. Use printf, not fprintf, when not passing a file - pointer... - (compare_opcodes): Check that identical instructions have - identical opcodes, complain otherwise. - From binutils: - * New 'm' arg. - * Include reg_names. - From neither: - Use dis-asm.h/read_memory_func interface. - -Wed Mar 31 20:49:06 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * h8500-dis.c, i386-dis.c, m68k-dis.c, z8k-dis.c (fetch_data): - deliberately return non-zero to setjmp from longjmp. Otherwise - this code fails to compile. - -Wed Mar 31 17:04:31 1993 Stu Grossman (grossman@cygnus.com) - - * m68k-dis.c: Fix prototype for fetch_arg(). - -Wed Mar 31 10:07:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * dis-buf.c: New file, for new read_memory_func interface. - Makefile.in (OFILES): Include it. - m68k-dis.c, i386-dis.c, h8500-dis.c, mips-dis.c, z8k-dis.c: - Use new read_memory_func interface. - -Mon Mar 29 14:02:17 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * h8500-dis.c (print_insn_h8500): Get sign of fp offsets right. - * h8500-opc.h: Fix couple of opcodes. - -Wed Mar 24 02:03:36 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com) - - * Makefile.in: add dvi & installcheck targets - -Mon Mar 22 18:55:04 1993 John Gilmore (gnu@cygnus.com) - - * Makefile.in: Update for h8500-dis.c. - -Fri Mar 19 14:27:17 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * h8500-dis.c, h8500-opc.h: New files - -Thu Mar 18 14:12:37 1993 Per Bothner (bothner@rtl.cygnus.com) - - * mips-dis.c, z8k-dis.c: Converted to use interface defined in - ../include/dis-asm.h. - * m68k-dis.c: New file (merge of ../binutils/m68k-pinsn.c - and ../gdb/m68k-pinsn.c). - * i386-dis.c: New file (merge of ../binutils/i386-pinsn.c - and ../gdb/i386-pinsn.c). - * m68881-ext.c: New file. Moved definition of - ext_format ext_format_68881 from ../gdb/m68k-tdep.c. - * Makefile.in: Adjust for new files. - * i386-dis.c: Patches from John Hassey (hassey@dg-rtp.dg.com). - * m68k-dis.c: Recognize '9' placement code, so (say) pflush - can be dis-assembled. - -Wed Feb 17 09:19:47 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * mips-dis.c (print_insn_arg): Now returns void. - -Mon Jan 11 16:09:16 1993 Fred Fish (fnf@cygnus.com) - - * mips-dis.c (ansidecl.h): Include for benefit of sysdep.h - files that use the macros. - -Thu Jan 7 13:15:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * mips-dis.c: New file, from gdb/mips-pinsn.c. - * Makefile.in (DIS_LIBS): Added mips-dis.o. - (CFILES): Added mips-dis.c. - -Thu Jan 7 07:36:33 1993 Steve Chamberlain (sac@thepub.cygnus.com) - - * z8k-dis.c (print_insn_z8001, print_insn_z8002): new routines - * z8kgen.c, z8k-opc.h: fix sizes of some shifts. - -Tue Dec 22 15:42:44 1992 Per Bothner (bothner@rtl.cygnus.com) - - * Makefile.in: Improve *clean rules. - * configure.in: Allow a default host. - -Tue Nov 17 19:53:54 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: also use -I$(srcdir)/../bfd, since some sysdep - files include other sysdep files - -Thu Nov 12 16:10:37 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * z8k-dis.c z8k-opc.h z8kgen.c: checkpoint - -Fri Oct 9 04:56:05 1992 John Gilmore (gnu@cygnus.com) - - * configure.in: For host support, use ../bfd/configure.host - so it stays in sync with the ../bfd/hosts database. - -Thu Oct 1 23:38:54 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure.in: use cpu-vendor-os triple instead of nested cases - -Wed Sep 30 16:09:20 1992 Michael Werner (mtw@cygnus.com) - - * z8k-dis.c (unparse_instr): fix bug where opcode returned was - *always* the wrong one. - -Wed Sep 30 07:42:17 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * z8kgen.c: added copyright info - -Tue Sep 29 12:20:21 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * z8k-dis.c (unparse_instr): prettier tabs - * z8kgen.c -> z8k-opc.h: bug fixes in tables - -Fri Sep 25 12:50:32 1992 Stu Grossman (grossman at cygnus.com) - - * configure.in: Add ncr* configuration. - * z8k-dis.c (struct instr_data_s): Make instr_asmsrc char to make - picayune ANSI compilers happy. - -Sep 20 08:50:55 1992 Fred Fish (fnf@cygnus.com) - - * configure.in (i386): Make i386 and i486 synonymous for now. - * configure.in (i[34]86-*-sysv4): Add my_host definition. - -Fri Sep 18 17:01:23 1992 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (install): Fix typo. - -Fri Sep 18 02:04:24 1992 John Gilmore (gnu@cygnus.com) - - * Makefile.in (make): Remove obsolete crud. - (sparc-opc.o): Avoid Sun Make VPATH bug. - -Tue Sep 8 17:29:27 1992 K. Richard Pixley (rich@sendai.cygnus.com) - - * Makefile.in: since there are no SUBDIRS, remove rule and - references of subdir_do. - -Tue Sep 8 17:02:58 1992 Ken Raeburn (raeburn@cambridge.cygnus.com) - - * Makefile.in (install): Get the library name right here too. - Don't install bfd.h, since it's unrelated to this library. No - subdirs to recurse into, either. - (CFILES): The source file has a .c suffix, not .o. - - * sparc-opc.c: New file, moved from BFD. - * Makefile.in (OFILES): Build it. - -Thu Sep 3 16:59:20 1992 Michael Werner (mtw@cygnus.com) - - * z8k-dis.c: fixed forward refferences of some declarations. - -Mon Aug 31 16:09:45 1992 Michael Werner (mtw@cygnus.com) - - * Makefile.in: get the name of the library right - -Mon Aug 31 13:47:35 1992 Steve Chamberlain (sac@thepub.cygnus.com) - - * z8k-dis.c: knows how to disassemble z8k stuff - * z8k-opc.h: new file full of z8000 opcodes - - -Local Variables: -version-control: never -End: diff --git a/contrib/gdb/opcodes/Makefile.in b/contrib/gdb/opcodes/Makefile.in deleted file mode 100644 index c274cb173a4..00000000000 --- a/contrib/gdb/opcodes/Makefile.in +++ /dev/null @@ -1,305 +0,0 @@ -# Makefile template for Configure for the opcodes library. -# Copyright (C) 1990, 1991, 1992, 1995 Free Software Foundation, Inc. -# Written by Cygnus Support. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -VPATH = @srcdir@ -srcdir = @srcdir@ - -prefix = @prefix@ - -program_transform_name = @program_transform_name@ -exec_prefix = @exec_prefix@ -bindir = $(exec_prefix)/bin -libdir = $(exec_prefix)/lib - -datadir = $(prefix)/lib -mandir = $(prefix)/man -man1dir = $(mandir)/man1 -man2dir = $(mandir)/man2 -man3dir = $(mandir)/man3 -man4dir = $(mandir)/man4 -man5dir = $(mandir)/man5 -man6dir = $(mandir)/man6 -man7dir = $(mandir)/man7 -man8dir = $(mandir)/man8 -man9dir = $(mandir)/man9 -infodir = $(prefix)/info -includedir = $(prefix)/include -oldincludedir = -docdir = $(srcdir)/doc - -SHELL = /bin/sh - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ - -AR = @AR@ -AR_FLAGS = rc -CC = @CC@ -CFLAGS = @CFLAGS@ -MAKEINFO = makeinfo -RANLIB = @RANLIB@ - -ALLLIBS = @ALLLIBS@ - -PICFLAG = @PICFLAG@ -SHLIB = @SHLIB@ -SHLIB_CC = @SHLIB_CC@ -SHLIB_CFLAGS = @SHLIB_CFLAGS@ -COMMON_SHLIB = @COMMON_SHLIB@ -SHLIB_DEP = @SHLIB_DEP@ -SHLINK = @SHLINK@ - -SONAME = lib`echo $(SHLIB) | sed -e 's,^\.\./bfd/,,' -e 's/^lib//' | sed '$(program_transform_name)'` - -INCDIR = $(srcdir)/../include -BFDDIR = $(srcdir)/../bfd -CSEARCH = -I. -I$(srcdir) -I../bfd -I$(INCDIR) -I$(BFDDIR) -DEP = mkdep - -TARGETLIB = libopcodes.a - -# To circumvent a Sun make VPATH bug, each file listed here -# should also have a foo.o: foo.c line further along in this file. - -ALL_MACHINES = a29k-dis.o alpha-dis.o h8300-dis.o h8500-dis.o \ - hppa-dis.o i386-dis.o i960-dis.o m68k-dis.o m68k-opc.o \ - m88k-dis.o mips-dis.o mips-opc.o sh-dis.o sparc-dis.o \ - sparc-opc.o z8k-dis.o ns32k-dis.o ppc-dis.o ppc-opc.o \ - arm-dis.o w65-dis.o - -OFILES = @BFD_MACHINES@ dis-buf.o disassemble.o - -FLAGS_TO_PASS = \ - "against=$(against)" \ - "AR=$(AR)" \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC=$(CC)" \ - "CFLAGS=$(CFLAGS)" \ - "RANLIB=$(RANLIB)" \ - "MAKEINFO=$(MAKEINFO)" \ - "INSTALL=$(INSTALL)" \ - "INSTALL_DATA=$(INSTALL_DATA)" \ - "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" - -ALL_CFLAGS = $(CSEARCH) @HDEFINES@ $(CFLAGS) - -.c.o: - if [ -n "$(PICFLAG)" ]; then \ - $(CC) -c $(PICFLAG) $(ALL_CFLAGS) $< -o pic/$@; \ - else true; fi - $(CC) -c $(ALL_CFLAGS) $< - -# C source files that correspond to .o's. -CFILES = i386-dis.c z8k-dis.c m68k-dis.c mips-dis.c ns32k-dis.c ppc-dis.c - -all: $(ALLLIBS) - -.NOEXPORT: - -installcheck check: - -info: -clean-info: -install-info: -dvi: - -# HDEPFILES comes from the host config; TDEPFILES from the target config. - - -$(TARGETLIB): $(OFILES) - rm -f $(TARGETLIB) - $(AR) $(AR_FLAGS) $(TARGETLIB) $(OFILES) - $(RANLIB) $(TARGETLIB) - -LIBIBERTY_LISTS = ../libiberty/required-list ../libiberty/needed-list -BFD_LIST = ../bfd/piclist - -stamp-piclist: Makefile $(LIBIBERTY_LISTS) $(BFD_LIST) - rm -f tpiclist - if [ -n "$(PICFLAG)" ]; then \ - echo $(OFILES) | sed -e 's,\([^ ][^ ]*\),pic/\1,g' > tpiclist; \ - else \ - echo $(OFILES) > tpiclist; \ - fi - if [ "$(COMMON_SHLIB)" = "yes" ]; then \ - lobjs=`cat $(LIBIBERTY_LISTS)`; \ - if [ -n "$(PICFLAG)" ]; then \ - lobjs=`echo $$lobjs | sed -e 's,\([^ ][^ ]*\),pic/\1,g'`; \ - fi; \ - lobjs=`echo $$lobjs | sed -e 's,\([^ ][^ ]*\),../libiberty/\1,g'`; \ - echo $$lobjs >> tpiclist; \ - sed -e 's,\([^ ][^ ]*\),../bfd/\1,g' $(BFD_LIST) >> tpiclist; \ - else true; fi - $(srcdir)/../move-if-change tpiclist piclist - touch stamp-piclist - -piclist: stamp-piclist ; @true - -$(SHLIB): stamp-picdir $(OFILES) piclist $(SHLIB_DEP) - rm -f $(SHLIB) - $(SHLIB_CC) $(SHLIB_CFLAGS) -o $(SHLIB) `cat piclist` - -$(SHLINK): $(SHLIB) - ts=lib`echo $(SHLIB) | sed -e 's,^\.\./bfd/,,' -e 's/^lib//' | sed -e '$(program_transform_name)'`; \ - if [ "$(COMMON_SHLIB)" = "yes" ]; then \ - ts=../bfd/$$ts; \ - fi; \ - if [ "$$ts" != "$(SHLIB)" ]; then \ - rm -f $$ts; \ - ln -sf `echo $(SHLIB) | sed -e 's,^\.\./bfd/,,'` $$ts; \ - else true; fi - rm -f $(SHLINK) - ln -sf `echo $(SHLIB) | sed -e 's,^\.\./bfd/,,'` $(SHLINK) - -# This target creates libTARGET-opcodes.so.VERSION as a symlink to -# libopcodes.so.VERSION. It is used on SunOS, which does not have SONAME. -stamp-tshlink: $(SHLIB) - tf=lib`echo $(SHLIB) | sed -e 's,\.\./bfd/,,' -e 's/^lib//' | sed '$(program_transform_name)'`; \ - if [ "$(COMMON_SHLIB)" = "yes" ]; then \ - tf=../bfd/$$tf; \ - fi; \ - if [ "$$tf" != "$(SHLIB)" ]; then \ - rm -f $$tf; \ - ln -sf $(SHLIB) $$tf; \ - else true; fi - if [ "$(COMMON_SHLIB)" = "yes" ]; then \ - tf=lib`echo $(TARGETLIB) | sed -e 's/^lib//' | sed '$(program_transform_name)'`; \ - if [ "$$tf" != "$(TARGETLIB)" ]; then \ - rm -f $$tf; \ - ln -sf $(TARGETLIB) $$tf; \ - else true; fi; \ - else true; fi - touch stamp-tshlink - -$(OFILES): stamp-picdir - -disassemble.o: disassemble.c $(INCDIR)/dis-asm.h - if [ -n "$(PICFLAG)" ]; then \ - $(CC) -c @archdefs@ $(PICFLAG) $(ALL_CFLAGS) $(srcdir)/disassemble.c -o pic/disassemble.o; \ - else true; fi - $(CC) -c @archdefs@ $(ALL_CFLAGS) $(srcdir)/disassemble.c - -a29k-dis.o: a29k-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/a29k.h -dis-buf.o: dis-buf.c $(INCDIR)/dis-asm.h -h8500-dis.o: h8500-dis.c h8500-opc.h $(INCDIR)/dis-asm.h -h8300-dis.o: h8300-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/h8300.h -i386-dis.o: i386-dis.c $(INCDIR)/dis-asm.h -i960-dis.o: i960-dis.c $(INCDIR)/dis-asm.h -w65-dis.o: w65-dis.c -m68k-dis.o: m68k-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/floatformat.h \ - $(INCDIR)/opcode/m68k.h -m68k-opc.o: m68k-opc.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/m68k.h -mips-dis.o: mips-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/mips.h -mips-opc.o: mips-opc.c $(INCDIR)/opcode/mips.h -ppc-dis.o: ppc-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/ppc.h -ppc-opc.o: ppc-opc.c $(INCDIR)/opcode/ppc.h -sparc-dis.o: sparc-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/sparc.h -sparc-opc.o: sparc-opc.c $(INCDIR)/opcode/sparc.h -z8k-dis.o: z8k-dis.c z8k-opc.h $(INCDIR)/dis-asm.h -ns32k-dis.o: ns32k-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/ns32k.h -sh-dis.o: sh-dis.c sh-opc.h $(INCDIR)/dis-asm.h -alpha-dis.o: alpha-dis.c alpha-opc.h $(INCDIR)/dis-asm.h -hppa-dis.o: hppa-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/hppa.h -m88k-dis.o: m88k-dis.c $(INCDIR)/dis-asm.h $(INCDIR)/opcode/m88k.h -arm-dis.o: arm-dis.c arm-opc.h $(INCDIR)/dis-asm.h - -tags etags: TAGS - -TAGS: force - etags $(INCDIR)/*.h $(srcdir)/*.h $(srcdir)/*.c - -MOSTLYCLEAN = *.o core *.E *.p *.ip config.log pic/*.o -mostlyclean: - rm -rf $(MOSTLYCLEAN) -clean: - rm -f *.a $(MOSTLYCLEAN) $(SHLIB) $(SHLINK) piclist stamp-piclist -distclean: clean - rm -rf Makefile config.status TAGS config.cache config.h stamp-h \ - pic stamp-picdir -clobber realclean maintainer-clean: distclean - -# Mark everything as depending on config.status, since the timestamp on -# sysdep.h might actually move backwards if we reconfig and relink it -# to a different hosts/h-xxx.h file. This will force a recompile anyway. -RECONFIG = config.status - - - -# This target should be invoked before building a new release. -# 'VERSION' file must be present and contain a string of the form "x.y" -# -roll: - @V=`cat VERSION` ; \ - MAJ=`sed 's/\..*//' VERSION` ; \ - MIN=`sed 's/.*\.//' VERSION` ; \ - V=$$MAJ.`expr $$MIN + 1` ; \ - rm -f VERSION ; \ - echo $$V >VERSION ; \ - echo Version $$V - -# Dummy target to force execution of dependent targets. -# -force: - -install: $(ALLLIBS) - for f in $(ALLLIBS); do \ - if [ "$$f" = "stamp-tshlink" ]; then \ - continue; \ - fi; \ - tf=lib`echo $$f | sed -e 's,^\.\./bfd/,,' -e 's/^lib//' | sed '$(program_transform_name)'`; \ - rm -f $(libdir)/$$tf; \ - if [ "$$f" = "$(SHLINK)" ]; then \ - ts=lib`echo $(SHLIB) | sed -e 's,^\.\./bfd/,,' -e 's/^lib//' | sed '$(program_transform_name)'`; \ - ln -sf $$ts $(libdir)/$$tf; \ - elif [ "$$f" = "$(SHLIB)" ]; then \ - $(INSTALL_PROGRAM) $$f $(libdir)/$$tf; \ - else \ - $(INSTALL_DATA) $$f $(libdir)/$$tf; \ - $(RANLIB) $(libdir)/$$tf; \ - chmod a-x $(libdir)/$$tf; \ - fi; \ - done - -Makefile: Makefile.in config.status - CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status - -config.h: stamp-h ; @true -stamp-h: config.in config.status - CONFIG_FILES= CONFIG_HEADERS=config.h:config.in $(SHELL) ./config.status - -config.status : configure $(srcdir)/../bfd/configure.host $(srcdir)/../bfd/config.bfd - $(SHELL) config.status --recheck - -dep: $(CFILES) - mkdep $(CFLAGS) $? - -stamp-picdir: - if [ -n "$(PICFLAG)" ] && [ ! -d pic ]; then \ - mkdir pic; \ - else true; fi - touch stamp-picdir - -# What appears below is generated by a hacked mkdep using gcc -MM. - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. - - -# IF YOU PUT ANYTHING HERE IT WILL GO AWAY - diff --git a/contrib/gdb/opcodes/config.in b/contrib/gdb/opcodes/config.in deleted file mode 100644 index ea534ec66ce..00000000000 --- a/contrib/gdb/opcodes/config.in +++ /dev/null @@ -1,7 +0,0 @@ -/* config.in. Generated automatically from configure.in by autoheader. */ - -/* Define if you have the header file. */ -#undef HAVE_STRING_H - -/* Define if you have the header file. */ -#undef HAVE_STRINGS_H diff --git a/contrib/gdb/opcodes/configure b/contrib/gdb/opcodes/configure deleted file mode 100755 index 5f19335a3af..00000000000 --- a/contrib/gdb/opcodes/configure +++ /dev/null @@ -1,1538 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.8 -# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --enable-targets alternative target configurations" -ac_help="$ac_help - --enable-shared build shared opcodes library" -ac_help="$ac_help - --enable-commonbfdlib build shared BFD/opcodes/libiberty library" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.8" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set LANG and LC_ALL to C if already set. -# These must not be set unconditionally because not all systems understand -# e.g. LANG=C (notably SCO). -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LANG+set}" = set; then LANG=C; export LANG; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=z8k-dis.c - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' - -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - -# configure.in script for the opcodes library. -# Copyright (C) 1995, 1996 Free Software Foundation, Inc. -# Written by Cygnus Support. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# Check whether --enable-targets or --disable-targets was given. -if test "${enable_targets+set}" = set; then - enableval="$enable_targets" - case "${enableval}" in - yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; } - ;; - no) enable_targets= ;; - *) enable_targets=$enableval ;; -esac -fi -# Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - case "${enableval}" in - yes) shared=true ;; - no) shared=false ;; - *) { echo "configure: error: bad value ${enableval} for opcodes shared option" 1>&2; exit 1; } ;; -esac -fi -# Check whether --enable-commonbfdlib or --disable-commonbfdlib was given. -if test "${enable_commonbfdlib+set}" = set; then - enableval="$enable_commonbfdlib" - case "${enableval}" in - yes) commonbfdlib=true ;; - no) commonbfdlib=false ;; - *) { echo "configure: error: bad value ${enableval} for opcodes commonbfdlib option" 1>&2; exit 1; } ;; -esac -fi - - - -ac_aux_dir= -for ac_dir in `cd $srcdir/..;pwd` $srcdir/`cd $srcdir/..;pwd`; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir/..;pwd` $srcdir/`cd $srcdir/..;pwd`" 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - - -# Do some error checking and defaulting for the host and target type. -# The inputs are: -# configure --host=HOST --target=TARGET --build=BUILD NONOPT -# -# The rules are: -# 1. You are not allowed to specify --host, --target, and nonopt at the -# same time. -# 2. Host defaults to nonopt. -# 3. If nonopt is not specified, then host defaults to the current host, -# as determined by config.guess. -# 4. Target and build default to nonopt. -# 5. If nonopt is not specified, then target and build default to host. - -# The aliases save the names the user supplied, while $host etc. -# will get canonicalized. -case $host---$target---$nonopt in -NONE---*---* | *---NONE---* | *---*---NONE) ;; -*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; -esac - - -# Make sure we can run config.sub. -if $ac_config_sub sun4 >/dev/null 2>&1; then : -else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } -fi - -echo $ac_n "checking host system type""... $ac_c" 1>&6 - -host_alias=$host -case "$host_alias" in -NONE) - case $nonopt in - NONE) - if host_alias=`$ac_config_guess`; then : - else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } - fi ;; - *) host_alias=$nonopt ;; - esac ;; -esac - -host=`$ac_config_sub $host_alias` -host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` -echo "$ac_t""$host" 1>&6 - -echo $ac_n "checking target system type""... $ac_c" 1>&6 - -target_alias=$target -case "$target_alias" in -NONE) - case $nonopt in - NONE) target_alias=$host_alias ;; - *) target_alias=$nonopt ;; - esac ;; -esac - -target=`$ac_config_sub $target_alias` -target_cpu=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` -target_vendor=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` -target_os=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` -echo "$ac_t""$target" 1>&6 - -echo $ac_n "checking build system type""... $ac_c" 1>&6 - -build_alias=$build -case "$build_alias" in -NONE) - case $nonopt in - NONE) build_alias=$host_alias ;; - *) build_alias=$nonopt ;; - esac ;; -esac - -build=`$ac_config_sub $build_alias` -build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` -build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` -build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` -echo "$ac_t""$build" 1>&6 - -test "$host_alias" != "$target_alias" && - test "$program_prefix$program_suffix$program_transform_name" = \ - NONENONEs,x,x, && - program_prefix=${target_alias}- - -if test -z "$target" ; then - { echo "configure: error: Unrecognized target system type; please check config.sub." 1>&2; exit 1; } -fi -if test "$program_transform_name" = s,x,x,; then - program_transform_name= -else - # Double any \ or $. echo might interpret backslashes. - cat <<\EOF_SED > conftestsed -s,\\,\\\\,g; s,\$,$$,g -EOF_SED - program_transform_name="`echo $program_transform_name|sed -f conftestsed`" - rm -f conftestsed -fi -test "$program_prefix" != NONE && - program_transform_name="s,^,${program_prefix},; $program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" - -# sed with no file args requires a program. -test "$program_transform_name" = "" && program_transform_name="s,x,x," - - -# host-specific stuff: - -ALLLIBS='$(TARGETLIB)' -PICFLAG= -SHLIB=unused-shlib -SHLINK=unused-shlink -if test "${shared}" = "true"; then - ALLLIBS='$(TARGETLIB) $(SHLIB) $(SHLINK)' - PICFLAG=-fpic - if test "${commonbfdlib}" = "true"; then - SHLIB=../bfd/libbfd.so.`sed -e 's/[^0-9]*\([0-9.]*\).*/\1/' ${srcdir}/../bfd/VERSION` - SHLINK=../bfd/libbfd.so - else - SHLIB=libopcodes.so.`sed -e 's/[^0-9]*\([0-9.]*\).*/\1/' ${srcdir}/../bfd/VERSION` - SHLINK=libopcodes.so - fi -fi - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - ac_prog_rejected=no - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 -if test $ac_cv_prog_gcc = yes; then - GCC=yes - if test "${CFLAGS+set}" != set; then - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_gcc_g=yes -else - ac_cv_prog_gcc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 - if test $ac_cv_prog_gcc_g = yes; then - CFLAGS="-g -O" - else - CFLAGS="-O" - fi - fi -else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" -fi - - -. ${srcdir}/../bfd/configure.host - - -if test $host != $build; then - ac_tool_prefix=${host_alias}- -else - ac_tool_prefix= -fi - -# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" -fi -fi -AR="$ac_cv_prog_AR" -if test -n "$AR"; then - echo "$ac_t""$AR" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - - -# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -if test -z "$ac_cv_prog_RANLIB"; then -if test -n "$ac_tool_prefix"; then - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="ranlib" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -else - RANLIB=":" -fi -fi - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_ifs" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -if test "${shared}" = "true"; then - if test "${GCC}" != "yes" && test "${shared_non_gcc}" != "yes"; then - echo "configure: warning: opcodes --enable-shared only supported when using gcc" 1>&2 - shared=false - ALLLIBS='$(TARGETLIB)' - PICFLAG= - SHLIB=unused-shlib - fi -fi - - - - - - -if test "${commonbfdlib}" = "true"; then - COMMON_SHLIB=yes - # Rebuild the shared library if libiberty or libbfd changes. - SHLIB_DEP="../libiberty/libiberty.a ../bfd/libbfd.a" -else - COMMON_SHLIB= - SHLIB_DEP= -fi - - - - -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1051: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -for ac_hdr in string.h strings.h -do -ac_safe=`echo "$ac_hdr" | tr './\055' '___'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1099: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'` - cat >> confdefs.h <&6 -fi -done - - -# target-specific stuff: - -# Canonicalize the secondary target names. -if test -n "$enable_targets" ; then - for targ in `echo $enable_targets | sed 's/,/ /g'` - do - result=`$ac_config_sub $targ 2>/dev/null` - if test -n "$result" ; then - canon_targets="$canon_targets $result" - else - # Allow targets that config.sub doesn't recognize, like "all". - canon_targets="$canon_targets $targ" - fi - done -fi - -all_targets=false -selarchs= -for targ in $target $canon_targets -do - if test "x$targ" = "xall" ; then - all_targets=true - else - . $srcdir/../bfd/config.bfd - selarchs="$selarchs $targ_archs" - fi -done - -# We don't do any links based on the target system, just makefile config. - -if test x${all_targets} = xfalse ; then - - # Target architecture .o files. - ta= - - for arch in $selarchs - do - ad=`echo $arch | sed -e s/bfd_//g -e s/_arch//g` - archdefs="$archdefs -DARCH_$ad" - case "$arch" in - bfd_a29k_arch) ta="$ta a29k-dis.o" ;; - bfd_alliant_arch) ;; - bfd_alpha_arch) ta="$ta alpha-dis.o" ;; - bfd_arm_arch) ta="$ta arm-dis.o" ;; - bfd_convex_arch) ;; - bfd_h8300_arch) ta="$ta h8300-dis.o" ;; - bfd_h8500_arch) ta="$ta h8500-dis.o" ;; - bfd_hppa_arch) ta="$ta hppa-dis.o" ;; - bfd_i386_arch) ta="$ta i386-dis.o" ;; - bfd_i860_arch) ;; - bfd_i960_arch) ta="$ta i960-dis.o" ;; - bfd_m68k_arch) ta="$ta m68k-dis.o m68k-opc.o" ;; - bfd_m88k_arch) ta="$ta m88k-dis.o" ;; - bfd_mips_arch) ta="$ta mips-dis.o mips-opc.o" ;; - bfd_ns32k_arch) ta="$ta ns32k-dis.o" ;; - bfd_powerpc_arch) ta="$ta ppc-dis.o ppc-opc.o" ;; - bfd_pyramid_arch) ;; - bfd_romp_arch) ;; - bfd_rs6000_arch) ta="$ta ppc-dis.o ppc-opc.o" ;; - bfd_sh_arch) ta="$ta sh-dis.o" ;; - bfd_sparc_arch) ta="$ta sparc-dis.o sparc-opc.o" ;; - bfd_tahoe_arch) ;; - bfd_vax_arch) ;; - bfd_w65_arch) ta="$ta w65-dis.o" ;; - bfd_we32k_arch) ;; - bfd_z8k_arch) ta="$ta z8k-dis.o" ;; - - "") ;; - *) { echo "configure: error: *** unknown target architecture $arch" 1>&2; exit 1; } ;; - esac - done - - # Weed out duplicate .o files. - f="" - for i in $ta ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac - done - ta="$f" - - # And duplicate -D flags. - f="" - for i in $archdefs ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac - done - archdefs="$f" - - BFD_MACHINES="$ta" - -else # all_targets is true - archdefs=-DARCH_all - BFD_MACHINES='$(ALL_MACHINES)' -fi - - - - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ - >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -DEFS=-DHAVE_CONFIG_H - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.8" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@host@%$host%g -s%@host_alias@%$host_alias%g -s%@host_cpu@%$host_cpu%g -s%@host_vendor@%$host_vendor%g -s%@host_os@%$host_os%g -s%@target@%$target%g -s%@target_alias@%$target_alias%g -s%@target_cpu@%$target_cpu%g -s%@target_vendor@%$target_vendor%g -s%@target_os@%$target_os%g -s%@build@%$build%g -s%@build_alias@%$build_alias%g -s%@build_cpu@%$build_cpu%g -s%@build_vendor@%$build_vendor%g -s%@build_os@%$build_os%g -s%@CC@%$CC%g -s%@HDEFINES@%$HDEFINES%g -s%@AR@%$AR%g -s%@RANLIB@%$RANLIB%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@ALLLIBS@%$ALLLIBS%g -s%@PICFLAG@%$PICFLAG%g -s%@SHLIB@%$SHLIB%g -s%@SHLIB_CC@%$SHLIB_CC%g -s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g -s%@COMMON_SHLIB@%$COMMON_SHLIB%g -s%@SHLIB_DEP@%$SHLIB_DEP%g -s%@SHLINK@%$SHLINK%g -s%@CPP@%$CPP%g -s%@archdefs@%$archdefs%g -s%@BFD_MACHINES@%$BFD_MACHINES%g - -CEOF -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust relative srcdir, etc. for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file -fi; done -rm -f conftest.subs - -# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where -# NAME is the cpp macro being defined and VALUE is the value it is being given. -# -# ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' -ac_dC='\3' -ac_dD='%g' -# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". -ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_uB='\([ ]\)%\1#\2define\3' -ac_uC=' ' -ac_uD='\4%g' -# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_eB='$%\1#\2define\3' -ac_eC=' ' -ac_eD='%g' - -CONFIG_HEADERS=${CONFIG_HEADERS-"config.h:config.in"} -for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then - # Support "outfile[:infile]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - echo creating $ac_file - - rm -f conftest.frag conftest.in conftest.out - cp $ac_given_srcdir/$ac_file_in conftest.in - -EOF - -# Transform confdefs.h into a sed script conftest.vals that substitutes -# the proper values into config.h.in to produce config.h. And first: -# Protect against being on the right side of a sed subst in config.status. -# Protect against being in an unquoted here document in config.status. -rm -f conftest.vals -cat > conftest.hdr <<\EOF -s/[\\&%]/\\&/g -s%[\\$`]%\\&%g -s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp -s%ac_d%ac_u%gp -s%ac_u%ac_e%gp -EOF -sed -n -f conftest.hdr confdefs.h > conftest.vals -rm -f conftest.hdr - -# This sed command replaces #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -cat >> conftest.vals <<\EOF -s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% -EOF - -# Break up conftest.vals because some shells have a limit on -# the size of here documents, and old seds have small limits too. -# Maximum number of lines to put in a single here document. -ac_max_here_lines=12 - -rm -f conftest.tail -while : -do - ac_lines=`grep -c . conftest.vals` - # grep -c gives empty output for an empty file on some AIX systems. - if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi - # Write a limited-size here document to conftest.frag. - echo ' cat > conftest.frag <> $CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS - echo 'CEOF - sed -f conftest.frag conftest.in > conftest.out - rm -f conftest.in - mv conftest.out conftest.in -' >> $CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail - rm -f conftest.vals - mv conftest.tail conftest.vals -done -rm -f conftest.vals - -cat >> $CONFIG_STATUS <<\EOF - rm -f conftest.frag conftest.h - echo "/* $ac_file. Generated automatically by configure. */" > conftest.h - cat conftest.in >> conftest.h - rm -f conftest.in - if cmp -s $ac_file conftest.h 2>/dev/null; then - echo "$ac_file is unchanged" - rm -f conftest.h - else - rm -f $ac_file - mv conftest.h $ac_file - fi -fi; done - - -case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - diff --git a/contrib/gdb/opcodes/configure.in b/contrib/gdb/opcodes/configure.in deleted file mode 100644 index e0c4f58e7c2..00000000000 --- a/contrib/gdb/opcodes/configure.in +++ /dev/null @@ -1,216 +0,0 @@ -AC_PREREQ(2.0) -AC_INIT(z8k-dis.c) -# configure.in script for the opcodes library. -# Copyright (C) 1995, 1996 Free Software Foundation, Inc. -# Written by Cygnus Support. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -AC_ARG_ENABLE(targets, -[ --enable-targets alternative target configurations], -[case "${enableval}" in - yes | "") AC_ERROR(enable-targets option must specify target names or 'all') - ;; - no) enable_targets= ;; - *) enable_targets=$enableval ;; -esac])dnl -AC_ARG_ENABLE(shared, -[ --enable-shared build shared opcodes library], -[case "${enableval}" in - yes) shared=true ;; - no) shared=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for opcodes shared option]) ;; -esac])dnl -AC_ARG_ENABLE(commonbfdlib, -[ --enable-commonbfdlib build shared BFD/opcodes/libiberty library], -[case "${enableval}" in - yes) commonbfdlib=true ;; - no) commonbfdlib=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for opcodes commonbfdlib option]) ;; -esac])dnl - -AC_CONFIG_HEADER(config.h:config.in) - -AC_CONFIG_AUX_DIR(`cd $srcdir/..;pwd`) -AC_CANONICAL_SYSTEM -if test -z "$target" ; then - AC_MSG_ERROR(Unrecognized target system type; please check config.sub.) -fi -AC_ARG_PROGRAM - -# host-specific stuff: - -ALLLIBS='$(TARGETLIB)' -PICFLAG= -SHLIB=unused-shlib -SHLINK=unused-shlink -if test "${shared}" = "true"; then - ALLLIBS='$(TARGETLIB) $(SHLIB) $(SHLINK)' - PICFLAG=-fpic - if test "${commonbfdlib}" = "true"; then -changequote(,)dnl - SHLIB=../bfd/libbfd.so.`sed -e 's/[^0-9]*\([0-9.]*\).*/\1/' ${srcdir}/../bfd/VERSION` -changequote([,])dnl - SHLINK=../bfd/libbfd.so - else -changequote(,)dnl - SHLIB=libopcodes.so.`sed -e 's/[^0-9]*\([0-9.]*\).*/\1/' ${srcdir}/../bfd/VERSION` -changequote([,])dnl - SHLINK=libopcodes.so - fi -fi - -AC_PROG_CC - -. ${srcdir}/../bfd/configure.host - -AC_SUBST(HDEFINES) -AC_CHECK_TOOL(AR, ar) -AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_PROG_INSTALL - -if test "${shared}" = "true"; then - if test "${GCC}" != "yes" && test "${shared_non_gcc}" != "yes"; then - AC_MSG_WARN([opcodes --enable-shared only supported when using gcc]) - shared=false - ALLLIBS='$(TARGETLIB)' - PICFLAG= - SHLIB=unused-shlib - fi -fi - -AC_SUBST(ALLLIBS) -AC_SUBST(PICFLAG) -AC_SUBST(SHLIB) -AC_SUBST(SHLIB_CC) -AC_SUBST(SHLIB_CFLAGS) -if test "${commonbfdlib}" = "true"; then - COMMON_SHLIB=yes - # Rebuild the shared library if libiberty or libbfd changes. - SHLIB_DEP="../libiberty/libiberty.a ../bfd/libbfd.a" -else - COMMON_SHLIB= - SHLIB_DEP= -fi -AC_SUBST(COMMON_SHLIB) -AC_SUBST(SHLIB_DEP) -AC_SUBST(SHLINK) - -AC_CHECK_HEADERS(string.h strings.h) - -# target-specific stuff: - -# Canonicalize the secondary target names. -if test -n "$enable_targets" ; then - for targ in `echo $enable_targets | sed 's/,/ /g'` - do - result=`$ac_config_sub $targ 2>/dev/null` - if test -n "$result" ; then - canon_targets="$canon_targets $result" - else - # Allow targets that config.sub doesn't recognize, like "all". - canon_targets="$canon_targets $targ" - fi - done -fi - -all_targets=false -selarchs= -for targ in $target $canon_targets -do - if test "x$targ" = "xall" ; then - all_targets=true - else - . $srcdir/../bfd/config.bfd - selarchs="$selarchs $targ_archs" - fi -done - -# We don't do any links based on the target system, just makefile config. - -if test x${all_targets} = xfalse ; then - - # Target architecture .o files. - ta= - - for arch in $selarchs - do - ad=`echo $arch | sed -e s/bfd_//g -e s/_arch//g` - archdefs="$archdefs -DARCH_$ad" - case "$arch" in - bfd_a29k_arch) ta="$ta a29k-dis.o" ;; - bfd_alliant_arch) ;; - bfd_alpha_arch) ta="$ta alpha-dis.o" ;; - bfd_arm_arch) ta="$ta arm-dis.o" ;; - bfd_convex_arch) ;; - bfd_h8300_arch) ta="$ta h8300-dis.o" ;; - bfd_h8500_arch) ta="$ta h8500-dis.o" ;; - bfd_hppa_arch) ta="$ta hppa-dis.o" ;; - bfd_i386_arch) ta="$ta i386-dis.o" ;; - bfd_i860_arch) ;; - bfd_i960_arch) ta="$ta i960-dis.o" ;; - bfd_m68k_arch) ta="$ta m68k-dis.o m68k-opc.o" ;; - bfd_m88k_arch) ta="$ta m88k-dis.o" ;; - bfd_mips_arch) ta="$ta mips-dis.o mips-opc.o" ;; - bfd_ns32k_arch) ta="$ta ns32k-dis.o" ;; - bfd_powerpc_arch) ta="$ta ppc-dis.o ppc-opc.o" ;; - bfd_pyramid_arch) ;; - bfd_romp_arch) ;; - bfd_rs6000_arch) ta="$ta ppc-dis.o ppc-opc.o" ;; - bfd_sh_arch) ta="$ta sh-dis.o" ;; - bfd_sparc_arch) ta="$ta sparc-dis.o sparc-opc.o" ;; - bfd_tahoe_arch) ;; - bfd_vax_arch) ;; - bfd_w65_arch) ta="$ta w65-dis.o" ;; - bfd_we32k_arch) ;; - bfd_z8k_arch) ta="$ta z8k-dis.o" ;; - - "") ;; - *) AC_MSG_ERROR(*** unknown target architecture $arch) ;; - esac - done - - # Weed out duplicate .o files. - f="" - for i in $ta ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac - done - ta="$f" - - # And duplicate -D flags. - f="" - for i in $archdefs ; do - case " $f " in - *" $i "*) ;; - *) f="$f $i" ;; - esac - done - archdefs="$f" - - BFD_MACHINES="$ta" - -else # all_targets is true - archdefs=-DARCH_all - BFD_MACHINES='$(ALL_MACHINES)' -fi - -AC_SUBST(archdefs) -AC_SUBST(BFD_MACHINES) - -AC_OUTPUT(Makefile, -[case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac]) diff --git a/contrib/gdb/opcodes/dis-buf.c b/contrib/gdb/opcodes/dis-buf.c deleted file mode 100644 index 47a2e33ef44..00000000000 --- a/contrib/gdb/opcodes/dis-buf.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Disassemble from a buffer, for GNU. - 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 -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "sysdep.h" -#include "dis-asm.h" -#include - -/* Get LENGTH bytes from info's buffer, at target address memaddr. - Transfer them to myaddr. */ -int -buffer_read_memory (memaddr, myaddr, length, info) - bfd_vma memaddr; - bfd_byte *myaddr; - int length; - struct disassemble_info *info; -{ - if (memaddr < info->buffer_vma - || memaddr + length > info->buffer_vma + info->buffer_length) - /* Out of bounds. Use EIO because GDB uses it. */ - return EIO; - memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length); - return 0; -} - -/* Print an error message. We can assume that this is in response to - an error return from buffer_read_memory. */ -void -perror_memory (status, memaddr, info) - int status; - bfd_vma memaddr; - struct disassemble_info *info; -{ - if (status != EIO) - /* Can't happen. */ - (*info->fprintf_func) (info->stream, "Unknown error %d\n", status); - else - /* Actually, address between memaddr and memaddr + len was - out of bounds. */ - (*info->fprintf_func) (info->stream, - "Address 0x%x is out of bounds.\n", memaddr); -} - -/* This could be in a separate file, to save miniscule amounts of space - in statically linked executables. */ - -/* Just print the address is hex. This is included for completeness even - though both GDB and objdump provide their own (to print symbolic - addresses). */ - -void -generic_print_address (addr, info) - bfd_vma addr; - struct disassemble_info *info; -{ - (*info->fprintf_func) (info->stream, "0x%x", addr); -} diff --git a/contrib/gdb/opcodes/disassemble.c b/contrib/gdb/opcodes/disassemble.c deleted file mode 100644 index b5d37aed476..00000000000 --- a/contrib/gdb/opcodes/disassemble.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Select disassembly routine for specified architecture. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "ansidecl.h" -#include "dis-asm.h" - -#ifdef ARCH_all -#define ARCH_a29k -#define ARCH_alpha -#define ARCH_arm -#define ARCH_h8300 -#define ARCH_h8500 -#define ARCH_hppa -#define ARCH_i386 -#define ARCH_i960 -#define ARCH_m68k -#define ARCH_m88k -#define ARCH_mips -#define ARCH_ns32k -#define ARCH_powerpc -#define ARCH_rs6000 -#define ARCH_sh -#define ARCH_sparc -#define ARCH_w65 -#define ARCH_z8k -#endif - -disassembler_ftype -disassembler (abfd) - bfd *abfd; -{ - enum bfd_architecture a = bfd_get_arch (abfd); - disassembler_ftype disassemble; - - switch (a) - { - /* If you add a case to this table, also add it to the - ARCH_all definition right above this function. */ -#ifdef ARCH_a29k - case bfd_arch_a29k: - /* As far as I know we only handle big-endian 29k objects. */ - disassemble = print_insn_big_a29k; - break; -#endif -#ifdef ARCH_alpha - case bfd_arch_alpha: - disassemble = print_insn_alpha; - break; -#endif -#ifdef ARCH_arm - case bfd_arch_arm: - if (bfd_big_endian (abfd)) - disassemble = print_insn_big_arm; - else - disassemble = print_insn_little_arm; - break; -#endif -#ifdef ARCH_h8300 - case bfd_arch_h8300: - if (bfd_get_mach(abfd) == bfd_mach_h8300h) - disassemble = print_insn_h8300h; - else - disassemble = print_insn_h8300; - break; -#endif -#ifdef ARCH_h8500 - case bfd_arch_h8500: - disassemble = print_insn_h8500; - break; -#endif -#ifdef ARCH_hppa - case bfd_arch_hppa: - disassemble = print_insn_hppa; - break; -#endif -#ifdef ARCH_i386 - case bfd_arch_i386: - disassemble = print_insn_i386; - break; -#endif -#ifdef ARCH_i960 - case bfd_arch_i960: - disassemble = print_insn_i960; - break; -#endif -#ifdef ARCH_m68k - case bfd_arch_m68k: - disassemble = print_insn_m68k; - break; -#endif -#ifdef ARCH_m88k - case bfd_arch_m88k: - disassemble = print_insn_m88k; - break; -#endif -#ifdef ARCH_ns32k - case bfd_arch_ns32k: - disassemble = print_insn_ns32k; - break; -#endif -#ifdef ARCH_mips - case bfd_arch_mips: - if (bfd_big_endian (abfd)) - disassemble = print_insn_big_mips; - else - disassemble = print_insn_little_mips; - break; -#endif -#ifdef ARCH_powerpc - case bfd_arch_powerpc: - if (bfd_big_endian (abfd)) - disassemble = print_insn_big_powerpc; - else - disassemble = print_insn_little_powerpc; - break; -#endif -#ifdef ARCH_rs6000 - case bfd_arch_rs6000: - disassemble = print_insn_rs6000; - break; -#endif -#ifdef ARCH_sh - case bfd_arch_sh: - if (bfd_big_endian (abfd)) - disassemble = print_insn_sh; - else - disassemble = print_insn_shl; - break; -#endif -#ifdef ARCH_sparc - case bfd_arch_sparc: - disassemble = print_insn_sparc; - break; -#endif -#ifdef ARCH_w65 - case bfd_arch_w65: - disassemble = print_insn_w65; - break; -#endif -#ifdef ARCH_z8k - case bfd_arch_z8k: - if (bfd_get_mach(abfd) == bfd_mach_z8001) - disassemble = print_insn_z8001; - else - disassemble = print_insn_z8002; - break; -#endif - default: - return 0; - } - return disassemble; -} diff --git a/contrib/gdb/opcodes/i386-dis.c b/contrib/gdb/opcodes/i386-dis.c deleted file mode 100644 index b781edc3207..00000000000 --- a/contrib/gdb/opcodes/i386-dis.c +++ /dev/null @@ -1,2031 +0,0 @@ -/* Print i386 instructions for GDB, the GNU debugger. - Copyright (C) 1988, 89, 91, 93, 94, 95, 1996 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) - * July 1988 - * modified by John Hassey (hassey@dg-rtp.dg.com) - */ - -/* - * The main tables describing the instructions is essentially a copy - * of the "Opcode Map" chapter (Appendix A) of the Intel 80386 - * Programmers Manual. Usually, there is a capital letter, followed - * by a small letter. The capital letter tell the addressing mode, - * and the small letter tells about the operand size. Refer to - * the Intel manual for details. - */ - -#include "dis-asm.h" -#include "sysdep.h" - -#define MAXLEN 20 - -#include - -struct dis_private -{ - /* Points to first byte not fetched. */ - bfd_byte *max_fetched; - bfd_byte the_buffer[MAXLEN]; - bfd_vma insn_start; - jmp_buf bailout; -}; - -/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) - to ADDR (exclusive) are valid. Returns 1 for success, longjmps - on error. */ -#define FETCH_DATA(info, addr) \ - ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \ - ? 1 : fetch_data ((info), (addr))) - -static int -fetch_data (info, addr) - struct disassemble_info *info; - bfd_byte *addr; -{ - int status; - 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, - priv->max_fetched, - addr - priv->max_fetched, - info); - if (status != 0) - { - (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); - } - else - priv->max_fetched = addr; - return 1; -} - -#define Eb OP_E, b_mode -#define indirEb OP_indirE, b_mode -#define Gb OP_G, b_mode -#define Ev OP_E, v_mode -#define indirEv OP_indirE, v_mode -#define Ew OP_E, w_mode -#define Ma OP_E, v_mode -#define M OP_E, 0 -#define Mp OP_E, 0 /* ? */ -#define Gv OP_G, v_mode -#define Gw OP_G, w_mode -#define Rw OP_rm, w_mode -#define Rd OP_rm, d_mode -#define Ib OP_I, b_mode -#define sIb OP_sI, b_mode /* sign extened byte */ -#define Iv OP_I, v_mode -#define Iw OP_I, w_mode -#define Jb OP_J, b_mode -#define Jv OP_J, v_mode -#define ONE OP_ONE, 0 -#define Cd OP_C, d_mode -#define Dd OP_D, d_mode -#define Td OP_T, d_mode - -#define eAX OP_REG, eAX_reg -#define eBX OP_REG, eBX_reg -#define eCX OP_REG, eCX_reg -#define eDX OP_REG, eDX_reg -#define eSP OP_REG, eSP_reg -#define eBP OP_REG, eBP_reg -#define eSI OP_REG, eSI_reg -#define eDI OP_REG, eDI_reg -#define AL OP_REG, al_reg -#define CL OP_REG, cl_reg -#define DL OP_REG, dl_reg -#define BL OP_REG, bl_reg -#define AH OP_REG, ah_reg -#define CH OP_REG, ch_reg -#define DH OP_REG, dh_reg -#define BH OP_REG, bh_reg -#define AX OP_REG, ax_reg -#define DX OP_REG, dx_reg -#define indirDX OP_REG, indir_dx_reg - -#define Sw OP_SEG, w_mode -#define Ap OP_DIR, lptr -#define Av OP_DIR, v_mode -#define Ob OP_OFF, b_mode -#define Ov OP_OFF, v_mode -#define Xb OP_DSSI, b_mode -#define Xv OP_DSSI, v_mode -#define Yb OP_ESDI, b_mode -#define Yv OP_ESDI, v_mode - -#define es OP_REG, es_reg -#define ss OP_REG, ss_reg -#define cs OP_REG, cs_reg -#define ds OP_REG, ds_reg -#define fs OP_REG, fs_reg -#define gs OP_REG, gs_reg - -int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG(); -int OP_J(), OP_SEG(); -int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C(); -int OP_D(), OP_T(), OP_rm(); - -static void dofloat (), putop (), append_prefix (), set_op (); -static int get16 (), get32 (); - -#define b_mode 1 -#define v_mode 2 -#define w_mode 3 -#define d_mode 4 - -#define es_reg 100 -#define cs_reg 101 -#define ss_reg 102 -#define ds_reg 103 -#define fs_reg 104 -#define gs_reg 105 -#define eAX_reg 107 -#define eCX_reg 108 -#define eDX_reg 109 -#define eBX_reg 110 -#define eSP_reg 111 -#define eBP_reg 112 -#define eSI_reg 113 -#define eDI_reg 114 - -#define lptr 115 - -#define al_reg 116 -#define cl_reg 117 -#define dl_reg 118 -#define bl_reg 119 -#define ah_reg 120 -#define ch_reg 121 -#define dh_reg 122 -#define bh_reg 123 - -#define ax_reg 124 -#define cx_reg 125 -#define dx_reg 126 -#define bx_reg 127 -#define sp_reg 128 -#define bp_reg 129 -#define si_reg 130 -#define di_reg 131 - -#define indir_dx_reg 150 - -#define GRP1b NULL, NULL, 0 -#define GRP1S NULL, NULL, 1 -#define GRP1Ss NULL, NULL, 2 -#define GRP2b NULL, NULL, 3 -#define GRP2S NULL, NULL, 4 -#define GRP2b_one NULL, NULL, 5 -#define GRP2S_one NULL, NULL, 6 -#define GRP2b_cl NULL, NULL, 7 -#define GRP2S_cl NULL, NULL, 8 -#define GRP3b NULL, NULL, 9 -#define GRP3S NULL, NULL, 10 -#define GRP4 NULL, NULL, 11 -#define GRP5 NULL, NULL, 12 -#define GRP6 NULL, NULL, 13 -#define GRP7 NULL, NULL, 14 -#define GRP8 NULL, NULL, 15 -#define GRP9 NULL, NULL, 16 - -#define FLOATCODE 50 -#define FLOAT NULL, NULL, FLOATCODE - -struct dis386 { - char *name; - int (*op1)(); - int bytemode1; - int (*op2)(); - int bytemode2; - int (*op3)(); - int bytemode3; -}; - -struct dis386 dis386[] = { - /* 00 */ - { "addb", Eb, Gb }, - { "addS", Ev, Gv }, - { "addb", Gb, Eb }, - { "addS", Gv, Ev }, - { "addb", AL, Ib }, - { "addS", eAX, Iv }, - { "pushl", es }, - { "popl", es }, - /* 08 */ - { "orb", Eb, Gb }, - { "orS", Ev, Gv }, - { "orb", Gb, Eb }, - { "orS", Gv, Ev }, - { "orb", AL, Ib }, - { "orS", eAX, Iv }, - { "pushl", cs }, - { "(bad)" }, /* 0x0f extended opcode escape */ - /* 10 */ - { "adcb", Eb, Gb }, - { "adcS", Ev, Gv }, - { "adcb", Gb, Eb }, - { "adcS", Gv, Ev }, - { "adcb", AL, Ib }, - { "adcS", eAX, Iv }, - { "pushl", ss }, - { "popl", ss }, - /* 18 */ - { "sbbb", Eb, Gb }, - { "sbbS", Ev, Gv }, - { "sbbb", Gb, Eb }, - { "sbbS", Gv, Ev }, - { "sbbb", AL, Ib }, - { "sbbS", eAX, Iv }, - { "pushl", ds }, - { "popl", ds }, - /* 20 */ - { "andb", Eb, Gb }, - { "andS", Ev, Gv }, - { "andb", Gb, Eb }, - { "andS", Gv, Ev }, - { "andb", AL, Ib }, - { "andS", eAX, Iv }, - { "(bad)" }, /* SEG ES prefix */ - { "daa" }, - /* 28 */ - { "subb", Eb, Gb }, - { "subS", Ev, Gv }, - { "subb", Gb, Eb }, - { "subS", Gv, Ev }, - { "subb", AL, Ib }, - { "subS", eAX, Iv }, - { "(bad)" }, /* SEG CS prefix */ - { "das" }, - /* 30 */ - { "xorb", Eb, Gb }, - { "xorS", Ev, Gv }, - { "xorb", Gb, Eb }, - { "xorS", Gv, Ev }, - { "xorb", AL, Ib }, - { "xorS", eAX, Iv }, - { "(bad)" }, /* SEG SS prefix */ - { "aaa" }, - /* 38 */ - { "cmpb", Eb, Gb }, - { "cmpS", Ev, Gv }, - { "cmpb", Gb, Eb }, - { "cmpS", Gv, Ev }, - { "cmpb", AL, Ib }, - { "cmpS", eAX, Iv }, - { "(bad)" }, /* SEG DS prefix */ - { "aas" }, - /* 40 */ - { "incS", eAX }, - { "incS", eCX }, - { "incS", eDX }, - { "incS", eBX }, - { "incS", eSP }, - { "incS", eBP }, - { "incS", eSI }, - { "incS", eDI }, - /* 48 */ - { "decS", eAX }, - { "decS", eCX }, - { "decS", eDX }, - { "decS", eBX }, - { "decS", eSP }, - { "decS", eBP }, - { "decS", eSI }, - { "decS", eDI }, - /* 50 */ - { "pushS", eAX }, - { "pushS", eCX }, - { "pushS", eDX }, - { "pushS", eBX }, - { "pushS", eSP }, - { "pushS", eBP }, - { "pushS", eSI }, - { "pushS", eDI }, - /* 58 */ - { "popS", eAX }, - { "popS", eCX }, - { "popS", eDX }, - { "popS", eBX }, - { "popS", eSP }, - { "popS", eBP }, - { "popS", eSI }, - { "popS", eDI }, - /* 60 */ - { "pusha" }, - { "popa" }, - { "boundS", Gv, Ma }, - { "arpl", Ew, Gw }, - { "(bad)" }, /* seg fs */ - { "(bad)" }, /* seg gs */ - { "(bad)" }, /* op size prefix */ - { "(bad)" }, /* adr size prefix */ - /* 68 */ - { "pushS", Iv }, /* 386 book wrong */ - { "imulS", Gv, Ev, Iv }, - { "pushl", sIb }, /* push of byte really pushes 4 bytes */ - { "imulS", Gv, Ev, Ib }, - { "insb", Yb, indirDX }, - { "insS", Yv, indirDX }, - { "outsb", indirDX, Xb }, - { "outsS", indirDX, Xv }, - /* 70 */ - { "jo", Jb }, - { "jno", Jb }, - { "jb", Jb }, - { "jae", Jb }, - { "je", Jb }, - { "jne", Jb }, - { "jbe", Jb }, - { "ja", Jb }, - /* 78 */ - { "js", Jb }, - { "jns", Jb }, - { "jp", Jb }, - { "jnp", Jb }, - { "jl", Jb }, - { "jnl", Jb }, - { "jle", Jb }, - { "jg", Jb }, - /* 80 */ - { GRP1b }, - { GRP1S }, - { "(bad)" }, - { GRP1Ss }, - { "testb", Eb, Gb }, - { "testS", Ev, Gv }, - { "xchgb", Eb, Gb }, - { "xchgS", Ev, Gv }, - /* 88 */ - { "movb", Eb, Gb }, - { "movS", Ev, Gv }, - { "movb", Gb, Eb }, - { "movS", Gv, Ev }, - { "movw", Ew, Sw }, - { "leaS", Gv, M }, - { "movw", Sw, Ew }, - { "popS", Ev }, - /* 90 */ - { "nop" }, - { "xchgS", eCX, eAX }, - { "xchgS", eDX, eAX }, - { "xchgS", eBX, eAX }, - { "xchgS", eSP, eAX }, - { "xchgS", eBP, eAX }, - { "xchgS", eSI, eAX }, - { "xchgS", eDI, eAX }, - /* 98 */ - { "cwtl" }, - { "cltd" }, - { "lcall", Ap }, - { "(bad)" }, /* fwait */ - { "pushf" }, - { "popf" }, - { "sahf" }, - { "lahf" }, - /* a0 */ - { "movb", AL, Ob }, - { "movS", eAX, Ov }, - { "movb", Ob, AL }, - { "movS", Ov, eAX }, - { "movsb", Yb, Xb }, - { "movsS", Yv, Xv }, - { "cmpsb", Yb, Xb }, - { "cmpsS", Yv, Xv }, - /* a8 */ - { "testb", AL, Ib }, - { "testS", eAX, Iv }, - { "stosb", Yb, AL }, - { "stosS", Yv, eAX }, - { "lodsb", AL, Xb }, - { "lodsS", eAX, Xv }, - { "scasb", AL, Yb }, - { "scasS", eAX, Yv }, - /* b0 */ - { "movb", AL, Ib }, - { "movb", CL, Ib }, - { "movb", DL, Ib }, - { "movb", BL, Ib }, - { "movb", AH, Ib }, - { "movb", CH, Ib }, - { "movb", DH, Ib }, - { "movb", BH, Ib }, - /* b8 */ - { "movS", eAX, Iv }, - { "movS", eCX, Iv }, - { "movS", eDX, Iv }, - { "movS", eBX, Iv }, - { "movS", eSP, Iv }, - { "movS", eBP, Iv }, - { "movS", eSI, Iv }, - { "movS", eDI, Iv }, - /* c0 */ - { GRP2b }, - { GRP2S }, - { "ret", Iw }, - { "ret" }, - { "lesS", Gv, Mp }, - { "ldsS", Gv, Mp }, - { "movb", Eb, Ib }, - { "movS", Ev, Iv }, - /* c8 */ - { "enter", Iw, Ib }, - { "leave" }, - { "lret", Iw }, - { "lret" }, - { "int3" }, - { "int", Ib }, - { "into" }, - { "iret" }, - /* d0 */ - { GRP2b_one }, - { GRP2S_one }, - { GRP2b_cl }, - { GRP2S_cl }, - { "aam", Ib }, - { "aad", Ib }, - { "(bad)" }, - { "xlat" }, - /* d8 */ - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - /* e0 */ - { "loopne", Jb }, - { "loope", Jb }, - { "loop", Jb }, - { "jCcxz", Jb }, - { "inb", AL, Ib }, - { "inS", eAX, Ib }, - { "outb", Ib, AL }, - { "outS", Ib, eAX }, - /* e8 */ - { "call", Av }, - { "jmp", Jv }, - { "ljmp", Ap }, - { "jmp", Jb }, - { "inb", AL, indirDX }, - { "inS", eAX, indirDX }, - { "outb", indirDX, AL }, - { "outS", indirDX, eAX }, - /* f0 */ - { "(bad)" }, /* lock prefix */ - { "(bad)" }, - { "(bad)" }, /* repne */ - { "(bad)" }, /* repz */ - { "hlt" }, - { "cmc" }, - { GRP3b }, - { GRP3S }, - /* f8 */ - { "clc" }, - { "stc" }, - { "cli" }, - { "sti" }, - { "cld" }, - { "std" }, - { GRP4 }, - { GRP5 }, -}; - -struct dis386 dis386_twobyte[] = { - /* 00 */ - { GRP6 }, - { GRP7 }, - { "larS", Gv, Ew }, - { "lslS", Gv, Ew }, - { "(bad)" }, - { "(bad)" }, - { "clts" }, - { "(bad)" }, - /* 08 */ - { "invd" }, - { "wbinvd" }, - { "(bad)" }, { "ud2a" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 10 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 18 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 20 */ - /* these are all backward in appendix A of the intel book */ - { "movl", Rd, Cd }, - { "movl", Rd, Dd }, - { "movl", Cd, Rd }, - { "movl", Dd, Rd }, - { "movl", Rd, Td }, - { "(bad)" }, - { "movl", Td, Rd }, - { "(bad)" }, - /* 28 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 30 */ - { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 38 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 40 */ - { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev }, - { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev }, - /* 48 */ - { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev }, - { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev }, - /* 50 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 58 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 60 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 68 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 70 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 78 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 80 */ - { "jo", Jv }, - { "jno", Jv }, - { "jb", Jv }, - { "jae", Jv }, - { "je", Jv }, - { "jne", Jv }, - { "jbe", Jv }, - { "ja", Jv }, - /* 88 */ - { "js", Jv }, - { "jns", Jv }, - { "jp", Jv }, - { "jnp", Jv }, - { "jl", Jv }, - { "jge", Jv }, - { "jle", Jv }, - { "jg", Jv }, - /* 90 */ - { "seto", Eb }, - { "setno", Eb }, - { "setb", Eb }, - { "setae", Eb }, - { "sete", Eb }, - { "setne", Eb }, - { "setbe", Eb }, - { "seta", Eb }, - /* 98 */ - { "sets", Eb }, - { "setns", Eb }, - { "setp", Eb }, - { "setnp", Eb }, - { "setl", Eb }, - { "setge", Eb }, - { "setle", Eb }, - { "setg", Eb }, - /* a0 */ - { "pushl", fs }, - { "popl", fs }, - { "cpuid" }, - { "btS", Ev, Gv }, - { "shldS", Ev, Gv, Ib }, - { "shldS", Ev, Gv, CL }, - { "(bad)" }, - { "(bad)" }, - /* a8 */ - { "pushl", gs }, - { "popl", gs }, - { "rsm" }, - { "btsS", Ev, Gv }, - { "shrdS", Ev, Gv, Ib }, - { "shrdS", Ev, Gv, CL }, - { "(bad)" }, - { "imulS", Gv, Ev }, - /* b0 */ - { "cmpxchgb", Eb, Gb }, - { "cmpxchgS", Ev, Gv }, - { "lssS", Gv, Mp }, /* 386 lists only Mp */ - { "btrS", Ev, Gv }, - { "lfsS", Gv, Mp }, /* 386 lists only Mp */ - { "lgsS", Gv, Mp }, /* 386 lists only Mp */ - { "movzbS", Gv, Eb }, - { "movzwS", Gv, Ew }, - /* b8 */ - { "ud2b" }, - { "(bad)" }, - { GRP8 }, - { "btcS", Ev, Gv }, - { "bsfS", Gv, Ev }, - { "bsrS", Gv, Ev }, - { "movsbS", Gv, Eb }, - { "movswS", Gv, Ew }, - /* c0 */ - { "xaddb", Eb, Gb }, - { "xaddS", Ev, Gv }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { GRP9 }, - /* c8 */ - { "bswap", eAX }, - { "bswap", eCX }, - { "bswap", eDX }, - { "bswap", eBX }, - { "bswap", eSP }, - { "bswap", eBP }, - { "bswap", eSI }, - { "bswap", eDI }, - /* d0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* d8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* e0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* e8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* f0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* f8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, -}; - -static const unsigned char onebyte_has_modrm[256] = { - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 -}; - -static const unsigned char twobyte_has_modrm[256] = { - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, - 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -static char obuf[100]; -static char *obufp; -static char scratchbuf[100]; -static unsigned char *start_codep; -static unsigned char *codep; -static disassemble_info *the_info; -static int mod; -static int rm; -static int reg; -static void oappend (); - -static char *names32[]={ - "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", -}; -static char *names16[] = { - "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di", -}; -static char *names8[] = { - "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh", -}; -static char *names_seg[] = { - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", -}; -static char *index16[] = { - "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx" -}; - -struct dis386 grps[][8] = { - /* GRP1b */ - { - { "addb", Eb, Ib }, - { "orb", Eb, Ib }, - { "adcb", Eb, Ib }, - { "sbbb", Eb, Ib }, - { "andb", Eb, Ib }, - { "subb", Eb, Ib }, - { "xorb", Eb, Ib }, - { "cmpb", Eb, Ib } - }, - /* GRP1S */ - { - { "addS", Ev, Iv }, - { "orS", Ev, Iv }, - { "adcS", Ev, Iv }, - { "sbbS", Ev, Iv }, - { "andS", Ev, Iv }, - { "subS", Ev, Iv }, - { "xorS", Ev, Iv }, - { "cmpS", Ev, Iv } - }, - /* GRP1Ss */ - { - { "addS", Ev, sIb }, - { "orS", Ev, sIb }, - { "adcS", Ev, sIb }, - { "sbbS", Ev, sIb }, - { "andS", Ev, sIb }, - { "subS", Ev, sIb }, - { "xorS", Ev, sIb }, - { "cmpS", Ev, sIb } - }, - /* GRP2b */ - { - { "rolb", Eb, Ib }, - { "rorb", Eb, Ib }, - { "rclb", Eb, Ib }, - { "rcrb", Eb, Ib }, - { "shlb", Eb, Ib }, - { "shrb", Eb, Ib }, - { "(bad)" }, - { "sarb", Eb, Ib }, - }, - /* GRP2S */ - { - { "rolS", Ev, Ib }, - { "rorS", Ev, Ib }, - { "rclS", Ev, Ib }, - { "rcrS", Ev, Ib }, - { "shlS", Ev, Ib }, - { "shrS", Ev, Ib }, - { "(bad)" }, - { "sarS", Ev, Ib }, - }, - /* GRP2b_one */ - { - { "rolb", Eb }, - { "rorb", Eb }, - { "rclb", Eb }, - { "rcrb", Eb }, - { "shlb", Eb }, - { "shrb", Eb }, - { "(bad)" }, - { "sarb", Eb }, - }, - /* GRP2S_one */ - { - { "rolS", Ev }, - { "rorS", Ev }, - { "rclS", Ev }, - { "rcrS", Ev }, - { "shlS", Ev }, - { "shrS", Ev }, - { "(bad)" }, - { "sarS", Ev }, - }, - /* GRP2b_cl */ - { - { "rolb", Eb, CL }, - { "rorb", Eb, CL }, - { "rclb", Eb, CL }, - { "rcrb", Eb, CL }, - { "shlb", Eb, CL }, - { "shrb", Eb, CL }, - { "(bad)" }, - { "sarb", Eb, CL }, - }, - /* GRP2S_cl */ - { - { "rolS", Ev, CL }, - { "rorS", Ev, CL }, - { "rclS", Ev, CL }, - { "rcrS", Ev, CL }, - { "shlS", Ev, CL }, - { "shrS", Ev, CL }, - { "(bad)" }, - { "sarS", Ev, CL } - }, - /* GRP3b */ - { - { "testb", Eb, Ib }, - { "(bad)", Eb }, - { "notb", Eb }, - { "negb", Eb }, - { "mulb", AL, Eb }, - { "imulb", AL, Eb }, - { "divb", AL, Eb }, - { "idivb", AL, Eb } - }, - /* GRP3S */ - { - { "testS", Ev, Iv }, - { "(bad)" }, - { "notS", Ev }, - { "negS", Ev }, - { "mulS", eAX, Ev }, - { "imulS", eAX, Ev }, - { "divS", eAX, Ev }, - { "idivS", eAX, Ev }, - }, - /* GRP4 */ - { - { "incb", Eb }, - { "decb", Eb }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - }, - /* GRP5 */ - { - { "incS", Ev }, - { "decS", Ev }, - { "call", indirEv }, - { "lcall", indirEv }, - { "jmp", indirEv }, - { "ljmp", indirEv }, - { "pushS", Ev }, - { "(bad)" }, - }, - /* GRP6 */ - { - { "sldt", Ew }, - { "str", Ew }, - { "lldt", Ew }, - { "ltr", Ew }, - { "verr", Ew }, - { "verw", Ew }, - { "(bad)" }, - { "(bad)" } - }, - /* GRP7 */ - { - { "sgdt", Ew }, - { "sidt", Ew }, - { "lgdt", Ew }, - { "lidt", Ew }, - { "smsw", Ew }, - { "(bad)" }, - { "lmsw", Ew }, - { "invlpg", Ew }, - }, - /* GRP8 */ - { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "btS", Ev, Ib }, - { "btsS", Ev, Ib }, - { "btrS", Ev, Ib }, - { "btcS", Ev, Ib }, - }, - /* GRP9 */ - { - { "(bad)" }, - { "cmpxchg8b", Ev }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - } -}; - -#define PREFIX_REPZ 1 -#define PREFIX_REPNZ 2 -#define PREFIX_LOCK 4 -#define PREFIX_CS 8 -#define PREFIX_SS 0x10 -#define PREFIX_DS 0x20 -#define PREFIX_ES 0x40 -#define PREFIX_FS 0x80 -#define PREFIX_GS 0x100 -#define PREFIX_DATA 0x200 -#define PREFIX_ADR 0x400 -#define PREFIX_FWAIT 0x800 - -static int prefixes; - -static void -ckprefix () -{ - prefixes = 0; - while (1) - { - FETCH_DATA (the_info, codep + 1); - switch (*codep) - { - case 0xf3: - prefixes |= PREFIX_REPZ; - break; - case 0xf2: - prefixes |= PREFIX_REPNZ; - break; - case 0xf0: - prefixes |= PREFIX_LOCK; - break; - case 0x2e: - prefixes |= PREFIX_CS; - break; - case 0x36: - prefixes |= PREFIX_SS; - break; - case 0x3e: - prefixes |= PREFIX_DS; - break; - case 0x26: - prefixes |= PREFIX_ES; - break; - case 0x64: - prefixes |= PREFIX_FS; - break; - case 0x65: - prefixes |= PREFIX_GS; - break; - case 0x66: - prefixes |= PREFIX_DATA; - break; - case 0x67: - prefixes |= PREFIX_ADR; - break; - case 0x9b: - prefixes |= PREFIX_FWAIT; - break; - default: - return; - } - codep++; - } -} - -static int dflag; -static int aflag; - -static char op1out[100], op2out[100], op3out[100]; -static int op_address[3], op_ad, op_index[3]; -static int start_pc; - - -/* - * On the 386's of 1988, the maximum length of an instruction is 15 bytes. - * (see topic "Redundant prefixes" in the "Differences from 8086" - * section of the "Virtual 8086 Mode" chapter.) - * 'pc' should be the address of this instruction, it will - * be used to print the target address if this is a relative jump or call - * The function returns the length of this instruction in bytes. - */ - -int -print_insn_i386 (pc, info) - bfd_vma pc; - disassemble_info *info; -{ - struct dis386 *dp; - int i; - int enter_instruction; - char *first, *second, *third; - int needcomma; - unsigned char need_modrm; - - struct dis_private priv; - bfd_byte *inbuf = priv.the_buffer; - - info->private_data = (PTR) &priv; - priv.max_fetched = priv.the_buffer; - priv.insn_start = pc; - if (setjmp (priv.bailout) != 0) - /* Error return. */ - return -1; - - obuf[0] = 0; - op1out[0] = 0; - op2out[0] = 0; - op3out[0] = 0; - - op_index[0] = op_index[1] = op_index[2] = -1; - - the_info = info; - start_pc = pc; - start_codep = inbuf; - codep = inbuf; - - ckprefix (); - - FETCH_DATA (info, codep + 1); - if (*codep == 0xc8) - enter_instruction = 1; - else - enter_instruction = 0; - - obufp = obuf; - - if (prefixes & PREFIX_REPZ) - oappend ("repz "); - if (prefixes & PREFIX_REPNZ) - oappend ("repnz "); - if (prefixes & PREFIX_LOCK) - oappend ("lock "); - - if ((prefixes & PREFIX_FWAIT) - && ((*codep < 0xd8) || (*codep > 0xdf))) - { - /* fwait not followed by floating point instruction */ - (*info->fprintf_func) (info->stream, "fwait"); - return (1); - } - - /* these would be initialized to 0 if disassembling for 8086 or 286 */ - dflag = 1; - aflag = 1; - - if (prefixes & PREFIX_DATA) - dflag ^= 1; - - if (prefixes & PREFIX_ADR) - { - aflag ^= 1; - oappend ("addr16 "); - } - - if (*codep == 0x0f) - { - FETCH_DATA (info, codep + 2); - dp = &dis386_twobyte[*++codep]; - need_modrm = twobyte_has_modrm[*codep]; - } - else - { - dp = &dis386[*codep]; - need_modrm = onebyte_has_modrm[*codep]; - } - codep++; - - if (need_modrm) - { - FETCH_DATA (info, codep + 1); - mod = (*codep >> 6) & 3; - reg = (*codep >> 3) & 7; - rm = *codep & 7; - } - - if (dp->name == NULL && dp->bytemode1 == FLOATCODE) - { - dofloat (); - } - else - { - if (dp->name == NULL) - dp = &grps[dp->bytemode1][reg]; - - putop (dp->name); - - obufp = op1out; - op_ad = 2; - if (dp->op1) - (*dp->op1)(dp->bytemode1); - - obufp = op2out; - op_ad = 1; - if (dp->op2) - (*dp->op2)(dp->bytemode2); - - obufp = op3out; - op_ad = 0; - if (dp->op3) - (*dp->op3)(dp->bytemode3); - } - - obufp = obuf + strlen (obuf); - for (i = strlen (obuf); i < 6; i++) - oappend (" "); - oappend (" "); - (*info->fprintf_func) (info->stream, "%s", obuf); - - /* enter instruction is printed with operands in the - * same order as the intel book; everything else - * is printed in reverse order - */ - if (enter_instruction) - { - first = op1out; - second = op2out; - third = op3out; - op_ad = op_index[0]; - op_index[0] = op_index[2]; - op_index[2] = op_ad; - } - else - { - first = op3out; - second = op2out; - third = op1out; - } - needcomma = 0; - if (*first) - { - if (op_index[0] != -1) - (*info->print_address_func) (op_address[op_index[0]], info); - else - (*info->fprintf_func) (info->stream, "%s", first); - needcomma = 1; - } - if (*second) - { - if (needcomma) - (*info->fprintf_func) (info->stream, ","); - if (op_index[1] != -1) - (*info->print_address_func) (op_address[op_index[1]], info); - else - (*info->fprintf_func) (info->stream, "%s", second); - needcomma = 1; - } - if (*third) - { - if (needcomma) - (*info->fprintf_func) (info->stream, ","); - if (op_index[2] != -1) - (*info->print_address_func) (op_address[op_index[2]], info); - else - (*info->fprintf_func) (info->stream, "%s", third); - } - return (codep - inbuf); -} - -char *float_mem[] = { - /* d8 */ - "fadds", - "fmuls", - "fcoms", - "fcomps", - "fsubs", - "fsubrs", - "fdivs", - "fdivrs", - /* d9 */ - "flds", - "(bad)", - "fsts", - "fstps", - "fldenv", - "fldcw", - "fNstenv", - "fNstcw", - /* da */ - "fiaddl", - "fimull", - "ficoml", - "ficompl", - "fisubl", - "fisubrl", - "fidivl", - "fidivrl", - /* db */ - "fildl", - "(bad)", - "fistl", - "fistpl", - "(bad)", - "fldt", - "(bad)", - "fstpt", - /* dc */ - "faddl", - "fmull", - "fcoml", - "fcompl", - "fsubl", - "fsubrl", - "fdivl", - "fdivrl", - /* dd */ - "fldl", - "(bad)", - "fstl", - "fstpl", - "frstor", - "(bad)", - "fNsave", - "fNstsw", - /* de */ - "fiadd", - "fimul", - "ficom", - "ficomp", - "fisub", - "fisubr", - "fidiv", - "fidivr", - /* df */ - "fild", - "(bad)", - "fist", - "fistp", - "fbld", - "fildll", - "fbstp", - "fistpll", -}; - -#define ST OP_ST, 0 -#define STi OP_STi, 0 -int OP_ST(), OP_STi(); - -#define FGRPd9_2 NULL, NULL, 0 -#define FGRPd9_4 NULL, NULL, 1 -#define FGRPd9_5 NULL, NULL, 2 -#define FGRPd9_6 NULL, NULL, 3 -#define FGRPd9_7 NULL, NULL, 4 -#define FGRPda_5 NULL, NULL, 5 -#define FGRPdb_4 NULL, NULL, 6 -#define FGRPde_3 NULL, NULL, 7 -#define FGRPdf_4 NULL, NULL, 8 - -struct dis386 float_reg[][8] = { - /* d8 */ - { - { "fadd", ST, STi }, - { "fmul", ST, STi }, - { "fcom", STi }, - { "fcomp", STi }, - { "fsub", ST, STi }, - { "fsubr", ST, STi }, - { "fdiv", ST, STi }, - { "fdivr", ST, STi }, - }, - /* d9 */ - { - { "fld", STi }, - { "fxch", STi }, - { FGRPd9_2 }, - { "(bad)" }, - { FGRPd9_4 }, - { FGRPd9_5 }, - { FGRPd9_6 }, - { FGRPd9_7 }, - }, - /* da */ - { - { "fcmovb", ST, STi }, - { "fcmove", ST, STi }, - { "fcmovbe",ST, STi }, - { "fcmovu", ST, STi }, - { "(bad)" }, - { FGRPda_5 }, - { "(bad)" }, - { "(bad)" }, - }, - /* db */ - { - { "fcmovnb",ST, STi }, - { "fcmovne",ST, STi }, - { "fcmovnbe",ST, STi }, - { "fcmovnu",ST, STi }, - { FGRPdb_4 }, - { "fucomi", ST, STi }, - { "fcomi", ST, STi }, - { "(bad)" }, - }, - /* dc */ - { - { "fadd", STi, ST }, - { "fmul", STi, ST }, - { "(bad)" }, - { "(bad)" }, - { "fsub", STi, ST }, - { "fsubr", STi, ST }, - { "fdiv", STi, ST }, - { "fdivr", STi, ST }, - }, - /* dd */ - { - { "ffree", STi }, - { "(bad)" }, - { "fst", STi }, - { "fstp", STi }, - { "fucom", STi }, - { "fucomp", STi }, - { "(bad)" }, - { "(bad)" }, - }, - /* de */ - { - { "faddp", STi, ST }, - { "fmulp", STi, ST }, - { "(bad)" }, - { FGRPde_3 }, - { "fsubp", STi, ST }, - { "fsubrp", STi, ST }, - { "fdivp", STi, ST }, - { "fdivrp", STi, ST }, - }, - /* df */ - { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { FGRPdf_4 }, - { "fucomip",ST, STi }, - { "fcomip", ST, STi }, - { "(bad)" }, - }, -}; - - -char *fgrps[][8] = { - /* d9_2 0 */ - { - "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* d9_4 1 */ - { - "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", - }, - - /* d9_5 2 */ - { - "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", - }, - - /* d9_6 3 */ - { - "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", - }, - - /* d9_7 4 */ - { - "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", - }, - - /* da_5 5 */ - { - "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* db_4 6 */ - { - "feni(287 only)","fdisi(287 only)","fNclex","fNinit", - "fNsetpm(287 only)","(bad)","(bad)","(bad)", - }, - - /* de_3 7 */ - { - "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* df_4 8 */ - { - "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, -}; - -static void -dofloat () -{ - struct dis386 *dp; - unsigned char floatop; - - floatop = codep[-1]; - - if (mod != 3) - { - putop (float_mem[(floatop - 0xd8) * 8 + reg]); - obufp = op1out; - OP_E (v_mode); - return; - } - codep++; - - dp = &float_reg[floatop - 0xd8][reg]; - if (dp->name == NULL) - { - putop (fgrps[dp->bytemode1][rm]); - /* instruction fnstsw is only one with strange arg */ - if (floatop == 0xdf - && FETCH_DATA (the_info, codep + 1) - && *codep == 0xe0) - strcpy (op1out, "%eax"); - } - else - { - putop (dp->name); - obufp = op1out; - if (dp->op1) - (*dp->op1)(dp->bytemode1); - obufp = op2out; - if (dp->op2) - (*dp->op2)(dp->bytemode2); - } -} - -/* ARGSUSED */ -int -OP_ST (ignore) - int ignore; -{ - oappend ("%st"); - return (0); -} - -/* ARGSUSED */ -int -OP_STi (ignore) - int ignore; -{ - sprintf (scratchbuf, "%%st(%d)", rm); - oappend (scratchbuf); - return (0); -} - - -/* capital letters in template are macros */ -static void -putop (template) - char *template; -{ - char *p; - - for (p = template; *p; p++) - { - switch (*p) - { - default: - *obufp++ = *p; - break; - case 'C': /* For jcxz/jecxz */ - if (aflag) - *obufp++ = 'e'; - break; - case 'N': - if ((prefixes & PREFIX_FWAIT) == 0) - *obufp++ = 'n'; - break; - case 'S': - /* operand size flag */ - if (dflag) - *obufp++ = 'l'; - else - *obufp++ = 'w'; - break; - } - } - *obufp = 0; -} - -static void -oappend (s) - char *s; -{ - strcpy (obufp, s); - obufp += strlen (s); - *obufp = 0; -} - -static void -append_prefix () -{ - if (prefixes & PREFIX_CS) - oappend ("%cs:"); - if (prefixes & PREFIX_DS) - oappend ("%ds:"); - if (prefixes & PREFIX_SS) - oappend ("%ss:"); - if (prefixes & PREFIX_ES) - oappend ("%es:"); - if (prefixes & PREFIX_FS) - oappend ("%fs:"); - if (prefixes & PREFIX_GS) - oappend ("%gs:"); -} - -int -OP_indirE (bytemode) - int bytemode; -{ - oappend ("*"); - return OP_E (bytemode); -} - -int -OP_E (bytemode) - int bytemode; -{ - int disp; - - /* skip mod/rm byte */ - codep++; - - if (mod == 3) - { - switch (bytemode) - { - case b_mode: - oappend (names8[rm]); - break; - case w_mode: - oappend (names16[rm]); - break; - case v_mode: - if (dflag) - oappend (names32[rm]); - else - oappend (names16[rm]); - break; - default: - oappend (""); - break; - } - return 0; - } - - disp = 0; - append_prefix (); - - if (aflag) /* 32 bit address mode */ - { - int havesib; - int havebase; - int base; - int index; - int scale; - - havesib = 0; - havebase = 1; - base = rm; - - if (base == 4) - { - havesib = 1; - FETCH_DATA (the_info, codep + 1); - scale = (*codep >> 6) & 3; - index = (*codep >> 3) & 7; - base = *codep & 7; - codep++; - } - - switch (mod) - { - case 0: - if (base == 5) - { - havebase = 0; - disp = get32 (); - } - break; - case 1: - FETCH_DATA (the_info, codep + 1); - disp = *(char *)codep++; - break; - case 2: - disp = get32 (); - break; - } - - if (mod != 0 || base == 5) - { - sprintf (scratchbuf, "0x%x", disp); - oappend (scratchbuf); - } - - if (havebase || (havesib && (index != 4 || scale != 0))) - { - oappend ("("); - if (havebase) - oappend (names32[base]); - if (havesib) - { - if (index != 4) - { - sprintf (scratchbuf, ",%s", names32[index]); - oappend (scratchbuf); - } - sprintf (scratchbuf, ",%d", 1 << scale); - oappend (scratchbuf); - } - oappend (")"); - } - } - else - { /* 16 bit address mode */ - switch (mod) - { - case 0: - if (rm == 6) - disp = (short) get16 (); - break; - case 1: - FETCH_DATA (the_info, codep + 1); - disp = *(char *)codep++; - break; - case 2: - disp = (short) get16 (); - break; - } - - if (mod != 0 || rm == 6) - { - sprintf (scratchbuf, "0x%x", disp); - oappend (scratchbuf); - } - - if (mod != 0 || rm != 6) - { - oappend ("("); - oappend (index16[rm]); - oappend (")"); - } - } - return 0; -} - -int -OP_G (bytemode) - int bytemode; -{ - switch (bytemode) - { - case b_mode: - oappend (names8[reg]); - break; - case w_mode: - oappend (names16[reg]); - break; - case d_mode: - oappend (names32[reg]); - break; - case v_mode: - if (dflag) - oappend (names32[reg]); - else - oappend (names16[reg]); - break; - default: - oappend (""); - break; - } - return (0); -} - -static int -get32 () -{ - int x = 0; - - FETCH_DATA (the_info, codep + 4); - x = *codep++ & 0xff; - x |= (*codep++ & 0xff) << 8; - x |= (*codep++ & 0xff) << 16; - x |= (*codep++ & 0xff) << 24; - return (x); -} - -static int -get16 () -{ - int x = 0; - - FETCH_DATA (the_info, codep + 2); - x = *codep++ & 0xff; - x |= (*codep++ & 0xff) << 8; - return (x); -} - -static void -set_op (op) - int op; -{ - op_index[op_ad] = op_ad; - op_address[op_ad] = op; -} - -int -OP_REG (code) - int code; -{ - char *s; - - switch (code) - { - case indir_dx_reg: s = "(%dx)"; break; - case ax_reg: case cx_reg: case dx_reg: case bx_reg: - case sp_reg: case bp_reg: case si_reg: case di_reg: - s = names16[code - ax_reg]; - break; - case es_reg: case ss_reg: case cs_reg: - case ds_reg: case fs_reg: case gs_reg: - s = names_seg[code - es_reg]; - break; - case al_reg: case ah_reg: case cl_reg: case ch_reg: - case dl_reg: case dh_reg: case bl_reg: case bh_reg: - s = names8[code - al_reg]; - break; - case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: - case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: - if (dflag) - s = names32[code - eAX_reg]; - else - s = names16[code - eAX_reg]; - break; - default: - s = ""; - break; - } - oappend (s); - return (0); -} - -int -OP_I (bytemode) - int bytemode; -{ - int op; - - switch (bytemode) - { - case b_mode: - FETCH_DATA (the_info, codep + 1); - op = *codep++ & 0xff; - break; - case v_mode: - if (dflag) - op = get32 (); - else - op = get16 (); - break; - case w_mode: - op = get16 (); - break; - default: - oappend (""); - return (0); - } - sprintf (scratchbuf, "$0x%x", op); - oappend (scratchbuf); - return (0); -} - -int -OP_sI (bytemode) - int bytemode; -{ - int op; - - switch (bytemode) - { - case b_mode: - FETCH_DATA (the_info, codep + 1); - op = *(char *)codep++; - break; - case v_mode: - if (dflag) - op = get32 (); - else - op = (short)get16(); - break; - case w_mode: - op = (short)get16 (); - break; - default: - oappend (""); - return (0); - } - sprintf (scratchbuf, "$0x%x", op); - oappend (scratchbuf); - return (0); -} - -int -OP_J (bytemode) - int bytemode; -{ - int disp; - int mask = -1; - - switch (bytemode) - { - case b_mode: - FETCH_DATA (the_info, codep + 1); - disp = *(char *)codep++; - break; - case v_mode: - if (dflag) - disp = get32 (); - else - { - disp = (short)get16 (); - /* for some reason, a data16 prefix on a jump instruction - means that the pc is masked to 16 bits after the - displacement is added! */ - mask = 0xffff; - } - break; - default: - oappend (""); - return (0); - } - disp = (start_pc + codep - start_codep + disp) & mask; - set_op (disp); - sprintf (scratchbuf, "0x%x", disp); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_SEG (dummy) - int dummy; -{ - static char *sreg[] = { - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", - }; - - oappend (sreg[reg]); - return (0); -} - -int -OP_DIR (size) - int size; -{ - int seg, offset; - - switch (size) - { - case lptr: - if (aflag) - { - offset = get32 (); - seg = get16 (); - } - else - { - offset = get16 (); - seg = get16 (); - } - sprintf (scratchbuf, "0x%x,0x%x", seg, offset); - oappend (scratchbuf); - break; - case v_mode: - if (aflag) - offset = get32 (); - else - offset = (short)get16 (); - - offset = start_pc + codep - start_codep + offset; - set_op (offset); - sprintf (scratchbuf, "0x%x", offset); - oappend (scratchbuf); - break; - default: - oappend (""); - break; - } - return (0); -} - -/* ARGSUSED */ -int -OP_OFF (bytemode) - int bytemode; -{ - int off; - - if (aflag) - off = get32 (); - else - off = get16 (); - - sprintf (scratchbuf, "0x%x", off); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_ESDI (dummy) - int dummy; -{ - oappend ("%es:("); - oappend (aflag ? "%edi" : "%di"); - oappend (")"); - return (0); -} - -/* ARGSUSED */ -int -OP_DSSI (dummy) - int dummy; -{ - oappend ("%ds:("); - oappend (aflag ? "%esi" : "%si"); - oappend (")"); - return (0); -} - -/* ARGSUSED */ -int -OP_ONE (dummy) - int dummy; -{ - oappend ("1"); - return (0); -} - -/* ARGSUSED */ -int -OP_C (dummy) - int dummy; -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%cr%d", reg); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_D (dummy) - int dummy; -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%db%d", reg); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_T (dummy) - int dummy; -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%tr%d", reg); - oappend (scratchbuf); - return (0); -} - -int -OP_rm (bytemode) - int bytemode; -{ - switch (bytemode) - { - case d_mode: - oappend (names32[rm]); - break; - case w_mode: - oappend (names16[rm]); - break; - } - return (0); -} diff --git a/contrib/gdb/opcodes/sysdep.h b/contrib/gdb/opcodes/sysdep.h deleted file mode 100644 index f1556da1f2e..00000000000 --- a/contrib/gdb/opcodes/sysdep.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Random host-dependent support code. - Copyright (C) 1995 Free Software Foundation, Inc. - Written by Ken Raeburn. - -This file is part of libopcodes, the opcodes library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Do system-dependent stuff, mainly driven by autoconf-detected info. - - Well, some generic common stuff is done here too, like including - ansidecl.h. That's because the .h files in bfd/hosts files I'm - trying to replace often did that. If it can be dropped from this - file (check in a non-ANSI environment!), it should be. */ - -#include "config.h" - -#include - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif diff --git a/contrib/gdb/opcodes/z8k-dis.c b/contrib/gdb/opcodes/z8k-dis.c deleted file mode 100644 index 8890e123120..00000000000 --- a/contrib/gdb/opcodes/z8k-dis.c +++ /dev/null @@ -1,571 +0,0 @@ -/* -This file is part of GNU Binutils. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include -#include "sysdep.h" -#include "dis-asm.h" - -#define DEFINE_TABLE -#include "z8k-opc.h" - - -#include - - -typedef struct -{ - /* These are all indexed by nibble number (i.e only every other entry - of bytes is used, and every 4th entry of words). */ - unsigned char nibbles[24]; - unsigned char bytes[24]; - unsigned short words[24]; - - /* Nibble number of first word not yet fetched. */ - int max_fetched; - bfd_vma insn_start; - jmp_buf bailout; - - long tabl_index; - char instr_asmsrc[80]; - unsigned long arg_reg[0x0f]; - unsigned long immediate; - unsigned long displacement; - unsigned long address; - unsigned long cond_code; - unsigned long ctrl_code; - unsigned long flags; - unsigned long interrupts; -} -instr_data_s; - -/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) - to ADDR (exclusive) are valid. Returns 1 for success, longjmps - on error. */ -#define FETCH_DATA(info, nibble) \ - ((nibble) < ((instr_data_s *)(info->private_data))->max_fetched \ - ? 1 : fetch_data ((info), (nibble))) - -static int -fetch_data (info, nibble) - struct disassemble_info *info; - int nibble; -{ - unsigned char mybuf[20]; - int status; - instr_data_s *priv = (instr_data_s *)info->private_data; - bfd_vma start; - - if ((nibble % 4) != 0) - abort (); - - status = (*info->read_memory_func) (priv->insn_start, - (bfd_byte *) mybuf, - nibble / 2, - info); - if (status != 0) - { - (*info->memory_error_func) (status, priv->insn_start, info); - longjmp (priv->bailout, 1); - } - - { - int i; - unsigned char *p = mybuf ; - - for (i = 0; i < nibble;) - { - priv->words[i] = (p[0] << 8) | p[1]; - - priv->bytes[i] = *p; - priv->nibbles[i++] = *p >> 4; - priv->nibbles[i++] = *p &0xf; - - ++p; - priv->bytes[i] = *p; - priv->nibbles[i++] = *p >> 4; - priv->nibbles[i++] = *p & 0xf; - - ++p; - } - } - priv->max_fetched = nibble; - return 1; -} - -static char *codes[16] = -{ - "f", - "lt", - "le", - "ule", - "ov/pe", - "mi", - "eq", - "c/ult", - "t", - "ge", - "gt", - "ugt", - "nov/po", - "pl", - "ne", - "nc/uge" -}; - -int z8k_lookup_instr PARAMS ((unsigned char*, disassemble_info *)); -static void output_instr - PARAMS ((instr_data_s *, unsigned long, disassemble_info *)); -static void unpack_instr PARAMS ((instr_data_s *, int, disassemble_info *)); -static void unparse_instr PARAMS ((instr_data_s *)); - -static int -print_insn_z8k (addr, info, is_segmented) - bfd_vma addr; - disassemble_info *info; - int is_segmented; -{ - instr_data_s instr_data; - - info->private_data = (PTR) &instr_data; - instr_data.max_fetched = 0; - instr_data.insn_start = addr; - if (setjmp (instr_data.bailout) != 0) - /* Error return. */ - return -1; - - instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info); - if (instr_data.tabl_index > 0) - { - unpack_instr (&instr_data, is_segmented, info); - unparse_instr (&instr_data); - output_instr (&instr_data, addr, info); - return z8k_table[instr_data.tabl_index].length; - } - else - { - FETCH_DATA (info, 4); - (*info->fprintf_func) (info->stream, ".word %02x%02x", - instr_data.bytes[0], instr_data.bytes[2]); - return 2; - } -} - -print_insn_z8001 (addr, info) - bfd_vma addr; - disassemble_info *info; -{ - return print_insn_z8k (addr, info, 1); -} - -print_insn_z8002 (addr, info) - bfd_vma addr; - disassemble_info *info; -{ - return print_insn_z8k (addr, info, 0); -} - -int -z8k_lookup_instr (nibbles, info) - unsigned char *nibbles; - disassemble_info *info; -{ - - int nibl_index, tabl_index; - int nibl_matched; - unsigned short instr_nibl; - unsigned short tabl_datum, datum_class, datum_value; - - nibl_matched = 0; - tabl_index = 0; - while (!nibl_matched && z8k_table[tabl_index].name) - { - nibl_matched = 1; - for (nibl_index = 0; nibl_index < z8k_table[tabl_index].length * 2 && nibl_matched; nibl_index++) - { - if ((nibl_index % 4) == 0) - /* Fetch one word at a time. */ - FETCH_DATA (info, nibl_index + 4); - instr_nibl = nibbles[nibl_index]; - - tabl_datum = z8k_table[tabl_index].byte_info[nibl_index]; - datum_class = tabl_datum & CLASS_MASK; - datum_value = ~CLASS_MASK & tabl_datum; - - switch (datum_class) - { - case CLASS_BIT: - if (datum_value != instr_nibl) - nibl_matched = 0; - break; - case CLASS_00II: - if (!((~instr_nibl) & 0x4)) - nibl_matched = 0; - break; - case CLASS_01II: - if (!(instr_nibl & 0x4)) - nibl_matched = 0; - break; - case CLASS_0CCC: - if (!((~instr_nibl) & 0x8)) - nibl_matched = 0; - break; - case CLASS_1CCC: - if (!(instr_nibl & 0x8)) - nibl_matched = 0; - break; - case CLASS_0DISP7: - if (!((~instr_nibl) & 0x8)) - nibl_matched = 0; - nibl_index += 1; - break; - case CLASS_1DISP7: - if (!(instr_nibl & 0x8)) - nibl_matched = 0; - nibl_index += 1; - break; - case CLASS_REGN0: - if (instr_nibl == 0) - nibl_matched = 0; - break; - case CLASS_BIT_1OR2: - if ((instr_nibl | 0x2) != (datum_value | 0x2)) - nibl_matched = 0; - break; - default: - break; - } - } - if (nibl_matched) - { - return tabl_index; - } - - tabl_index++; - } - return -1; - -} - -static void -output_instr (instr_data, addr, info) - instr_data_s *instr_data; - unsigned long addr; - disassemble_info *info; -{ - int loop, loop_limit; - char tmp_str[20]; - char out_str[100]; - - strcpy (out_str, "\t"); - - loop_limit = z8k_table[instr_data->tabl_index].length * 2; - FETCH_DATA (info, loop_limit); - for (loop = 0; loop < loop_limit; loop++) - { - sprintf (tmp_str, "%x", instr_data->nibbles[loop]); - strcat (out_str, tmp_str); - } - - while (loop++ < 8) - { - strcat (out_str, " "); - } - - strcat (out_str, instr_data->instr_asmsrc); - - (*info->fprintf_func) (info->stream, "%s", out_str); -} - -static void -unpack_instr (instr_data, is_segmented, info) - instr_data_s *instr_data; - int is_segmented; - disassemble_info *info; -{ - int nibl_count, loop; - unsigned short instr_nibl, instr_byte, instr_word; - long instr_long; - unsigned short tabl_datum, datum_class, datum_value; - - nibl_count = 0; - loop = 0; - while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0) - { - FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4)); - instr_nibl = instr_data->nibbles[nibl_count]; - instr_byte = instr_data->bytes[nibl_count]; - instr_word = instr_data->words[nibl_count]; - - tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop]; - datum_class = tabl_datum & CLASS_MASK; - datum_value = tabl_datum & ~CLASS_MASK; - - switch (datum_class) - { - case CLASS_X: - instr_data->address = instr_nibl; - break; - case CLASS_BA: - instr_data->displacement = instr_nibl; - break; - case CLASS_BX: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - case CLASS_DISP: - switch (datum_value) - { - case ARG_DISP16: - instr_data->displacement = instr_word; - nibl_count += 3; - break; - case ARG_DISP12: - instr_data->displacement = instr_word & 0x0fff; - nibl_count += 2; - break; - default: - break; - } - break; - case CLASS_IMM: - switch (datum_value) - { - case ARG_IMM4: - instr_data->immediate = instr_nibl; - break; - case ARG_NIM8: - instr_data->immediate = (-instr_byte); - nibl_count += 1; - break; - case ARG_IMM8: - instr_data->immediate = instr_byte; - nibl_count += 1; - break; - case ARG_IMM16: - instr_data->immediate = instr_word; - nibl_count += 3; - break; - case ARG_IMM32: - FETCH_DATA (info, nibl_count + 8); - instr_long = (instr_data->words[nibl_count] << 16) - | (instr_data->words[nibl_count + 4]); - instr_data->immediate = instr_long; - nibl_count += 7; - break; - case ARG_IMMN: - instr_data->immediate = instr_nibl - 1; - break; - case ARG_IMM4M1: - instr_data->immediate = instr_nibl + 1; - break; - case ARG_IMM_1: - instr_data->immediate = 1; - break; - case ARG_IMM_2: - instr_data->immediate = 2; - break; - case ARG_IMM2: - instr_data->immediate = instr_nibl & 0x3; - break; - default: - break; - } - break; - case CLASS_CC: - instr_data->cond_code = instr_nibl; - break; - case CLASS_CTRL: - instr_data->ctrl_code = instr_nibl; - break; - case CLASS_DA: - case CLASS_ADDRESS: - if (is_segmented) - { - if (instr_nibl & 0x8) - { - FETCH_DATA (info, nibl_count + 8); - instr_long = (instr_data->words[nibl_count] << 16) - | (instr_data->words[nibl_count + 4]); - instr_data->address = ((instr_word & 0x7f00) << 8) + - (instr_long & 0xffff); - nibl_count += 7; - } - else - { - instr_data->address = ((instr_word & 0x7f00) << 8) + - (instr_word & 0x00ff); - nibl_count += 3; - } - } - else - { - instr_data->address = instr_word; - nibl_count += 3; - } - break; - case CLASS_0CCC: - instr_data->cond_code = instr_nibl & 0x7; - break; - case CLASS_1CCC: - instr_data->cond_code = instr_nibl & 0x7; - break; - case CLASS_0DISP7: - instr_data->displacement = instr_byte & 0x7f; - nibl_count += 1; - break; - case CLASS_1DISP7: - instr_data->displacement = instr_byte & 0x7f; - nibl_count += 1; - break; - case CLASS_01II: - instr_data->interrupts = instr_nibl & 0x3; - break; - case CLASS_00II: - instr_data->interrupts = instr_nibl & 0x3; - break; - case CLASS_BIT: - /* do nothing */ - break; - case CLASS_IR: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - case CLASS_FLAGS: - instr_data->flags = instr_nibl; - break; - case CLASS_REG: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - case CLASS_REG_BYTE: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - case CLASS_REG_WORD: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - case CLASS_REG_QUAD: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - case CLASS_REG_LONG: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - case CLASS_REGN0: - instr_data->arg_reg[datum_value] = instr_nibl; - break; - default: - break; - } - - loop += 1; - nibl_count += 1; - } -} - -static void -unparse_instr (instr_data) - instr_data_s *instr_data; -{ - unsigned short tabl_datum, datum_class, datum_value; - int loop, loop_limit; - char out_str[80], tmp_str[25]; - - sprintf (out_str, "\t%s\t", z8k_table[instr_data->tabl_index].name); - - loop_limit = z8k_table[instr_data->tabl_index].noperands; - for (loop = 0; loop < loop_limit; loop++) - { - if (loop) - strcat (out_str, ","); - - tabl_datum = z8k_table[instr_data->tabl_index].arg_info[loop]; - datum_class = tabl_datum & CLASS_MASK; - datum_value = tabl_datum & ~CLASS_MASK; - - switch (datum_class) - { - case CLASS_X: - sprintf (tmp_str, "0x%0x(R%d)", instr_data->address, - instr_data->arg_reg[datum_value]); - strcat (out_str, tmp_str); - break; - case CLASS_BA: - sprintf (tmp_str, "r%d(#%x)", instr_data->arg_reg[datum_value], - instr_data->immediate); - strcat (out_str, tmp_str); - break; - case CLASS_BX: - sprintf (tmp_str, "r%d(R%d)", instr_data->arg_reg[datum_value], - instr_data->arg_reg[ARG_RX]); - strcat (out_str, tmp_str); - break; - case CLASS_DISP: - sprintf (tmp_str, "#0x%0x", instr_data->displacement); - strcat (out_str, tmp_str); - break; - case CLASS_IMM: - sprintf (tmp_str, "#0x%0x", instr_data->immediate); - strcat (out_str, tmp_str); - break; - case CLASS_CC: - sprintf (tmp_str, "%s", codes[instr_data->cond_code]); - strcat (out_str, tmp_str); - break; - case CLASS_CTRL: - sprintf (tmp_str, "0x%0x", instr_data->ctrl_code); - strcat (out_str, tmp_str); - break; - case CLASS_DA: - case CLASS_ADDRESS: - sprintf (tmp_str, "#0x%0x", instr_data->address); - strcat (out_str, tmp_str); - break; - case CLASS_IR: - sprintf (tmp_str, "@R%d", instr_data->arg_reg[datum_value]); - strcat (out_str, tmp_str); - break; - case CLASS_FLAGS: - sprintf (tmp_str, "0x%0x", instr_data->flags); - strcat (out_str, tmp_str); - break; - case CLASS_REG_BYTE: - if (instr_data->arg_reg[datum_value] >= 0x8) - { - sprintf (tmp_str, "rl%d", - instr_data->arg_reg[datum_value] - 0x8); - } - else - { - sprintf (tmp_str, "rh%d", instr_data->arg_reg[datum_value]); - } - strcat (out_str, tmp_str); - break; - case CLASS_REG_WORD: - sprintf (tmp_str, "r%d", instr_data->arg_reg[datum_value]); - strcat (out_str, tmp_str); - break; - case CLASS_REG_QUAD: - sprintf (tmp_str, "rq%d", instr_data->arg_reg[datum_value]); - strcat (out_str, tmp_str); - break; - case CLASS_REG_LONG: - sprintf (tmp_str, "rr%d", instr_data->arg_reg[datum_value]); - strcat (out_str, tmp_str); - break; - default: - break; - } - } - - strcpy (instr_data->instr_asmsrc, out_str); -} diff --git a/contrib/gdb/readline/doc/ChangeLog b/contrib/gdb/readline/doc/ChangeLog deleted file mode 100644 index 2520a8522cd..00000000000 --- a/contrib/gdb/readline/doc/ChangeLog +++ /dev/null @@ -1,12 +0,0 @@ -Wed Sep 20 12:57:29 1995 Ian Lance Taylor - - * Makefile.in (maintainer-clean): New synonym for realclean. - -Tue Feb 2 11:40:04 1993 Roland H. Pesch (pesch@fowanton.cygnus.com) - - * Makefile.in: configurable (and useable) Makefile template - * Makefile: removed, replaced with configurable Makefile.in - * texindex.c texinfo.tex: remove, replacing w/refs to tools - elsewhere in distribution tree - * configure.in: pro forma configure stub - * ChangeLog: new file diff --git a/contrib/gdb/readline/doc/Makefile.in b/contrib/gdb/readline/doc/Makefile.in deleted file mode 100644 index 451b9fec336..00000000000 --- a/contrib/gdb/readline/doc/Makefile.in +++ /dev/null @@ -1,94 +0,0 @@ -## Copyright (C) 1993 Free Software Foundation, Inc. - -# Makefile for Readline documentation. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -srcdir = . - -prefix = /usr/local - -infodir = $(prefix)/info - -SHELL = /bin/sh - -INSTALL = install -c -INSTALL_DATA = $(INSTALL) - -# where to find texinfo -TEXIDIR=$(srcdir)/../../texinfo - -# where to find makeinfo, preferably one designed for texinfo-2 -MAKEINFO=makeinfo - -# auxiliary program for sorting Texinfo indices -TEXINDEX=texindex - -# Don Knuth's TeX formatter -TEX=tex - -#### Host, target, and site specific Makefile fragments come in here. -### - -all: info dvi - -install: install-info - -info: history.info readline.info - -dvi: history.dvi readline.dvi - -install-info: info - -parent=`echo $(infodir)|sed -e 's@/[^/]*$$@@'`; \ - if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi - -if [ -d $(infodir) ] ; then true ; else mkdir $(infodir) ; fi - for i in *.info* ; do \ - $(INSTALL_DATA) $$i $(infodir)/$$i ; \ - done - -history.info: hist.texinfo hsuser.texinfo hstech.texinfo - $(MAKEINFO) -I $(srcdir) -o ./history.info $(srcdir)/hist.texinfo - -history.dvi: hist.texinfo hsuser.texinfo hstech.texinfo $(TEXIDIR)/texinfo.tex - TEXINPUTS=${TEXIDIR}:$(srcdir):$$TEXINPUTS $(TEX) hist.texinfo - $(TEXINDEX) hist.?? - TEXINPUTS=${TEXIDIR}:$(srcdir):$$TEXINPUTS $(TEX) hist.texinfo - -readline.info: rlman.texinfo rluser.texinfo rltech.texinfo - $(MAKEINFO) -I $(srcdir) -o ./readline.info $(srcdir)/rlman.texinfo - -readline.dvi: rlman.texinfo rluser.texinfo rltech.texinfo - TEXINPUTS=${TEXIDIR}:$(srcdir):$$TEXINPUTS $(TEX) rlman.texinfo - $(TEXINDEX) rlman.?? - TEXINPUTS=${TEXIDIR}:$(srcdir):$$TEXINPUTS $(TEX) rlman.texinfo - -distclean: clean - rm -f Makefile config.status - -mostlyclean: clean - -realclean maintainer-clean: distclean - -clean: clean-info clean-dvi - -clean-info: - rm -f history.info* readline.info* - -clean-dvi: - rm -f hist.?? hist.??? - rm -f rlman.?? rlman.??? - -Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag) - $(SHELL) ./config.status diff --git a/contrib/gdb/readline/doc/configure.in b/contrib/gdb/readline/doc/configure.in deleted file mode 100644 index c082c568c65..00000000000 --- a/contrib/gdb/readline/doc/configure.in +++ /dev/null @@ -1,8 +0,0 @@ -srcname="READLINE doc" -srctrigger=rlman.texinfo -# per-host: - -# per-target: - -files="" -links="" diff --git a/contrib/gdb/readline/doc/hist.texinfo b/contrib/gdb/readline/doc/hist.texinfo deleted file mode 100644 index 62927381044..00000000000 --- a/contrib/gdb/readline/doc/hist.texinfo +++ /dev/null @@ -1,106 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@comment %**start of header (This is for running Texinfo on a region.) -@setfilename history.info -@settitle GNU Readline Library -@comment %**end of header (This is for running Texinfo on a region.) -@synindex vr fn -@setchapternewpage odd - -@ifinfo -This document describes the GNU History library, a programming tool that -provides a consistent user interface for recalling lines of previously -typed input. - -Copyright (C) 1988, 1991 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -pare preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. -@end ifinfo - -@titlepage -@sp 10 -@center @titlefont{GNU History Library} -@center Brian Fox -@center Free Software Foundation -@center Version 1.1 -@center April 1991 - -@c Include the Distribution inside the titlepage environment so -@c that headings are turned off. - -@page - -This document describes the GNU History library, a programming tool that -provides a consistent user interface for recalling lines of previously -typed input. - -Published by the Free Software Foundation @* -675 Massachusetts Avenue, @* -Cambridge, MA 02139 USA - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. - -@vskip 0pt plus 1filll -Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. -@end titlepage - -@ifinfo -@node Top -@top GNU History Library - -This document describes the GNU History library, a programming tool that -provides a consistent user interface for recalling lines of previously -typed input. - -@menu -* Using History Interactively:: GNU History User's Manual. -* Programming with GNU History:: GNU History Programmer's Manual. -* Concept Index:: Index of concepts described in this manual. -* Function and Variable Index:: Index of externally visible functions - and variables. -@end menu -@end ifinfo - -@include hsuser.texinfo -@include hstech.texinfo - -@node Concept Index -@appendix Concept Index -@printindex cp - -@node Function and Variable Index -@appendix Function and Variable Index -@printindex vr -@contents - -@bye diff --git a/contrib/gdb/readline/doc/hstech.texinfo b/contrib/gdb/readline/doc/hstech.texinfo deleted file mode 100644 index c3fe3f6a11f..00000000000 --- a/contrib/gdb/readline/doc/hstech.texinfo +++ /dev/null @@ -1,311 +0,0 @@ -@ignore -This file documents the user interface to the GNU History library. - -Copyright (C) 1988, 1991 Free Software Foundation, Inc. -Authored by Brian Fox. - -Permission is granted to make and distribute verbatim copies of this manual -provided the copyright notice and this permission notice are preserved on -all copies. - -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission notice -identical to this one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -GNU Copyright statement is available to the distributee, and provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ignore - -@node Programming with GNU History -@chapter Programming with GNU History - -This chapter describes how to interface the GNU History Library with -programs that you write. It should be considered a technical guide. -For information on the interactive use of GNU History, @pxref{Using -History Interactively}. - -@menu -* Introduction to History:: What is the GNU History library for? -* History Storage:: How information is stored. -* History Functions:: Functions that you can use. -* History Variables:: Variables that control behaviour. -* History Programming Example:: Example of using the GNU History Library. -@end menu - -@node Introduction to History -@section Introduction to History - -Many programs read input from the user a line at a time. The GNU history -library is able to keep track of those lines, associate arbitrary data with -each line, and utilize information from previous lines in making up new -ones. - -The programmer using the History library has available to him functions -for remembering lines on a history stack, associating arbitrary data -with a line, removing lines from the stack, searching through the stack -for a line containing an arbitrary text string, and referencing any line -on the stack directly. In addition, a history @dfn{expansion} function -is available which provides for a consistent user interface across many -different programs. - -The end-user using programs written with the History library has the -benifit of a consistent user interface, with a set of well-known -commands for manipulating the text of previous lines and using that text -in new commands. The basic history manipulation commands are similar to -the history substitution used by @code{Csh}. - -If the programmer desires, he can use the Readline library, which -includes some history manipulation by default, and has the added -advantage of Emacs style command line editing. - -@node History Storage -@section History Storage - -@example -typedef struct _hist_entry @{ - char *line; - char *data; -@} HIST_ENTRY; -@end example - -@node History Functions -@section History Functions - -This section describes the calling sequence for the various functions -present in GNU History. - -@defun {void using_history} () -Begin a session in which the history functions might be used. This -just initializes the interactive variables. -@end defun - -@defun {void add_history} (char *string) -Place @var{string} at the end of the history list. The associated data -field (if any) is set to @code{NULL}. -@end defun - -@defun {int where_history} () -Returns the number which says what history element we are now looking -at. -@end defun - -@defun {int history_set_pos} (int pos) -Set the position in the history list to @var{pos}. -@end defun - -@defun {int history_search_pos} (char *string, int direction, int pos) -Search for @var{string} in the history list, starting at @var{pos}, an -absolute index into the list. @var{direction}, if negative, says to search -backwards from @var{pos}, else forwards. Returns the absolute index of -the history element where @var{string} was found, or -1 otherwise. -@end defun - -@defun {HIST_ENTRY *remove_history} (); -Remove history element @var{which} from the history. The removed -element is returned to you so you can free the line, data, -and containing structure. -@end defun - -@defun {void stifle_history} (int max) -Stifle the history list, remembering only @var{max} number of entries. -@end defun - -@defun {int unstifle_history} (); -Stop stifling the history. This returns the previous amount the -history was stifled by. The value is positive if the history was -stifled, negative if it wasn't. -@end defun - -@defun {int read_history} (char *filename) -Add the contents of @var{filename} to the history list, a line at a -time. If @var{filename} is @code{NULL}, then read from -@file{~/.history}. Returns 0 if successful, or errno if not. -@end defun - -@defun {int read_history_range} (char *filename, int from, int to) -Read a range of lines from @var{filename}, adding them to the history list. -Start reading at the @var{from}'th line and end at the @var{to}'th. If -@var{from} is zero, start at the beginning. If @var{to} is less than -@var{from}, then read until the end of the file. If @var{filename} is -@code{NULL}, then read from @file{~/.history}. Returns 0 if successful, -or @code{errno} if not. -@end defun - -@defun {int write_history} (char *filename) -Append the current history to @var{filename}. If @var{filename} is -@code{NULL}, then append the history list to @file{~/.history}. Values -returned are as in @code{read_history ()}. -@end defun - -@defun {int append_history} (int nelements, char *filename) -Append @var{nelement} entries to @var{filename}. The entries appended -are from the end of the list minus @var{nelements} up to the end of the -list. -@end defun - -@defun {HIST_ENTRY *replace_history_entry} () -Make the history entry at @var{which} have @var{line} and @var{data}. -This returns the old entry so you can dispose of the data. In the case -of an invalid @var{which}, a @code{NULL} pointer is returned. -@end defun - -@defun {HIST_ENTRY *current_history} () -Return the history entry at the current position, as determined by -@code{history_offset}. If there is no entry there, return a @code{NULL} -pointer. -@end defun - -@defun {HIST_ENTRY *previous_history} () -Back up @var{history_offset} to the previous history entry, and return a -pointer to that entry. If there is no previous entry, return a -@code{NULL} pointer. -@end defun - -@defun {HIST_ENTRY *next_history} () -Move @code{history_offset} forward to the next history entry, and return -the a pointer to that entry. If there is no next entry, return a -@code{NULL} pointer. -@end defun - -@defun {HIST_ENTRY **history_list} () -Return a @code{NULL} terminated array of @code{HIST_ENTRY} which is the -current input history. Element 0 of this list is the beginning of time. -If there is no history, return @code{NULL}. -@end defun - -@defun {int history_search} (char *string, int direction) -Search the history for @var{string}, starting at @code{history_offset}. -If @var{direction} < 0, then the search is through previous entries, -else through subsequent. If @var{string} is found, then -@code{current_history ()} is the history entry, and the value of this -function is the offset in the line of that history entry that the -@var{string} was found in. Otherwise, nothing is changed, and a -1 is -returned. -@end defun - -@defun {int history_expand} (char *string, char **output) -Expand @var{string}, placing the result into @var{output}, a pointer -to a string. Returns: -@table @code -@item 0 -If no expansions took place (or, if the only change in -the text was the de-slashifying of the history expansion -character), -@item 1 -if expansions did take place, or -@item -1 -if there was an error in expansion. -@end table - -If an error ocurred in expansion, then @var{output} contains a descriptive -error message. -@end defun - -@defun {char *history_arg_extract} (int first, int last, char *string) -Extract a string segment consisting of the @var{first} through @var{last} -arguments present in @var{string}. Arguments are broken up as in -the GNU Bash shell. -@end defun - -@defun {int history_total_bytes} (); -Return the number of bytes that the primary history entries are using. -This just adds up the lengths of @code{the_history->lines}. -@end defun - -@node History Variables -@section History Variables - -This section describes the variables in GNU History that are externally -visible. - -@defvar {int history_base} -For convenience only. You set this when interpreting history commands. -It is the logical offset of the first history element. -@end defvar - -@node History Programming Example -@section History Programming Example - -The following snippet of code demonstrates simple use of the GNU History -Library. - -@smallexample -main () -@{ - char line[1024], *t; - int done = 0; - - line[0] = 0; - - while (!done) - @{ - fprintf (stdout, "history%% "); - t = gets (line); - - if (!t) - strcpy (line, "quit"); - - if (line[0]) - @{ - char *expansion; - int result; - - using_history (); - - result = history_expand (line, &expansion); - strcpy (line, expansion); - free (expansion); - if (result) - fprintf (stderr, "%s\n", line); - - if (result < 0) - continue; - - add_history (line); - @} - - if (strcmp (line, "quit") == 0) done = 1; - if (strcmp (line, "save") == 0) write_history (0); - if (strcmp (line, "read") == 0) read_history (0); - if (strcmp (line, "list") == 0) - @{ - register HIST_ENTRY **the_list = history_list (); - register int i; - - if (the_list) - for (i = 0; the_list[i]; i++) - fprintf (stdout, "%d: %s\n", - i + history_base, the_list[i]->line); - @} - if (strncmp (line, "delete", strlen ("delete")) == 0) - @{ - int which; - if ((sscanf (line + strlen ("delete"), "%d", &which)) == 1) - @{ - HIST_ENTRY *entry = remove_history (which); - if (!entry) - fprintf (stderr, "No such entry %d\n", which); - else - @{ - free (entry->line); - free (entry); - @} - @} - else - @{ - fprintf (stderr, "non-numeric arg given to `delete'\n"); - @} - @} - @} -@} -@end smallexample - - - diff --git a/contrib/gdb/readline/doc/hsuser.texinfo b/contrib/gdb/readline/doc/hsuser.texinfo deleted file mode 100644 index cda0a688c74..00000000000 --- a/contrib/gdb/readline/doc/hsuser.texinfo +++ /dev/null @@ -1,153 +0,0 @@ -@ignore -This file documents the user interface to the GNU History library. - -Copyright (C) 1988, 1991 Free Software Foundation, Inc. -Authored by Brian Fox. - -Permission is granted to make and distribute verbatim copies of this manual -provided the copyright notice and this permission notice are preserved on -all copies. - -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission notice -identical to this one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -GNU Copyright statement is available to the distributee, and provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ignore - -@node Using History Interactively -@chapter Using History Interactively - -This chapter describes how to use the GNU History Library interactively, -from a user's standpoint. It should be considered a user's guide. For -information on using the GNU History Library in your own programs, -@pxref{Programming with GNU History}. - -@menu -* History Interaction:: What it feels like using History as a user. -@end menu - -@node History Interaction -@section History Interaction -@cindex expansion - -The History library provides a history expansion feature that is similar -to the history expansion in Csh. The following text describes the sytax -that you use to manipulate the history information. - -History expansion takes place in two parts. The first is to determine -which line from the previous history should be used during substitution. -The second is to select portions of that line for inclusion into the -current one. The line selected from the previous history is called the -@dfn{event}, and the portions of that line that are acted upon are -called @dfn{words}. The line is broken into words in the same fashion -that the Bash shell does, so that several English (or Unix) words -surrounded by quotes are considered as one word. - -@menu -* Event Designators:: How to specify which history line to use. -* Word Designators:: Specifying which words are of interest. -* Modifiers:: Modifying the results of susbstitution. -@end menu - -@node Event Designators -@subsection Event Designators -@cindex event designators - -An event designator is a reference to a command line entry in the -history list. - -@table @asis - -@item @code{!} -Start a history subsititution, except when followed by a space, tab, or -the end of the line... @key{=} or @key{(}. - -@item @code{!!} -Refer to the previous command. This is a synonym for @code{!-1}. - -@item @code{!n} -Refer to command line @var{n}. - -@item @code{!-n} -Refer to the command line @var{n} lines back. - -@item @code{!string} -Refer to the most recent command starting with @var{string}. - -@item @code{!?string}[@code{?}] -Refer to the most recent command containing @var{string}. - -@end table - -@node Word Designators -@subsection Word Designators - -A @key{:} separates the event specification from the word designator. It -can be omitted if the word designator begins with a @key{^}, @key{$}, -@key{*} or @key{%}. Words are numbered from the beginning of the line, -with the first word being denoted by a 0 (zero). - -@table @code - -@item 0 (zero) -The zero'th word. For many applications, this is the command word. - -@item n -The @var{n}'th word. - -@item ^ -The first argument. that is, word 1. - -@item $ -The last argument. - -@item % -The word matched by the most recent @code{?string?} search. - -@item x-y -A range of words; @code{-@var{y}} Abbreviates @code{0-@var{y}}. - -@item * -All of the words, excepting the zero'th. This is a synonym for @code{1-$}. -It is not an error to use @key{*} if there is just one word in the event. -The empty string is returned in that case. - -@end table - -@node Modifiers -@subsection Modifiers - -After the optional word designator, you can add a sequence of one or more -of the following modifiers, each preceded by a @key{:}. - -@table @code - -@item # -The entire command line typed so far. This means the current command, -not the previous command, so it really isn't a word designator, and doesn't -belong in this section. - -@item h -Remove a trailing pathname component, leaving only the head. - -@item r -Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename. - -@item e -Remove all but the suffix. - -@item t -Remove all leading pathname components, leaving the tail. - -@item p -Print the new command but do not execute it. -@end table diff --git a/contrib/gdb/readline/doc/inc-hist.texi b/contrib/gdb/readline/doc/inc-hist.texi deleted file mode 100644 index 9cdde401cd2..00000000000 --- a/contrib/gdb/readline/doc/inc-hist.texi +++ /dev/null @@ -1,159 +0,0 @@ -@ignore -This file is completely identical to hsuser.texinfo, except that it has the -reference to the programming manual removed. There are definately better ways -to do this! - -This file documents the user interface to the GNU History library. - -Copyright (C) 1988, 1991 Free Software Foundation, Inc. -Authored by Brian Fox. - -Permission is granted to make and distribute verbatim copies of this manual -provided the copyright notice and this permission notice are preserved on -all copies. - -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission notice -identical to this one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -GNU Copyright statement is available to the distributee, and provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ignore - -@node Using History Interactively -@appendix Using History Interactively - -This chapter describes how to use the GNU History Library interactively, -from a user's standpoint. - -@menu -* History Interaction:: What it feels like using History as a user. -@end menu - -@node History Interaction -@section History Interaction -@cindex expansion - -The History library provides a history expansion feature similar -to the history expansion in @code{csh}. The following text describes the -syntax you use to manipulate history information. - -History expansion takes two parts. In the first part, determine -which line from the previous history will be used for substitution. -This line is called the @dfn{event}. -In the second part, select portions of that line for inclusion into the -current line. These portions are called @dfn{words}. -@value{GDBN} breaks the line into words in the same -way that the Bash shell does, so that several English (or Unix) words -surrounded by quotes are considered one word. - -@menu -* Event Designators:: How to specify which history line to use. -* Word Designators:: Specifying which words are of interest. -* Modifiers:: Modifying the results of susbstitution. -@end menu - -@node Event Designators -@subsection Event Designators -@cindex event designators - -An @dfn{event designator} is a reference to a command line entry in the -history list. - -@table @asis - -@item @code{!} -Start a history subsititution, except when followed by a space, tab, or -the end of the line... @key{=} or @key{(}. - -@item @code{!!} -Refer to the previous command. This is a synonym for @code{!-1}. - -@item @code{!n} -Refer to command line @var{n}. - -@item @code{!-n} -Refer to the command line @var{n} lines back. - -@item @code{!string} -Refer to the most recent command starting with @var{string}. - -@item @code{!?string}[@code{?}] -Refer to the most recent command containing @var{string}. - -@end table - -@node Word Designators -@subsection Word Designators - -A @key{:} separates the event designator from the @dfn{word designator}. -It can be omitted if the word designator begins with a @key{^}, @key{$}, -@key{*} or @key{%}. Words are numbered from the beginning of the line, -with the first word being denoted by a 0 (zero). - -@table @code - -@item 0 (zero) -The zero'th word. For many applications, this is the command word. - -@item n -The @var{n}'th word. - -@item ^ -The first argument. that is, word 1. - -@item $ -The last argument. - -@item % -The word matched by the most recent @code{?string?} search. - -@item x-y -A range of words; @code{-@var{y}} Abbreviates @code{0-@var{y}}. - -@item * -All of the words, excepting the zero'th. This is a synonym for @code{1-$}. -It is not an error to use @key{*} if there is just one word in the event. -The empty string is returned in that case. - -@end table - -@node Modifiers -@subsection Modifiers - -After the optional word designator, you can add a sequence of one or more -of the following @dfn{modifiers}, each preceded by a @key{:}. - -@table @code - -@item # -The entire command line typed so far. This means the current command, -not the previous command. -@c -@c FIXME: If it doesn't belong here, let's put it where it does. -@c -@c so it technically isn't a word designator and doesn't belong in -@c this section. - -@item h -Remove a trailing pathname component, leaving only the head. - -@item r -Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename. - -@item e -Remove all but the suffix. - -@item t -Remove all leading pathname components, leaving the tail. - -@item p -Print the new command but do not execute it. -@end table diff --git a/contrib/gdb/readline/doc/rlman.texinfo b/contrib/gdb/readline/doc/rlman.texinfo deleted file mode 100644 index f2e7fb6db91..00000000000 --- a/contrib/gdb/readline/doc/rlman.texinfo +++ /dev/null @@ -1,103 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@comment %**start of header (This is for running Texinfo on a region.) -@setfilename readline.info -@settitle GNU Readline Library -@comment %**end of header (This is for running Texinfo on a region.) -@synindex vr fn -@setchapternewpage odd - -@ifinfo -This document describes the GNU Readline Library, a utility which aids -in the consistency of user interface across discrete programs that need -to provide a command line interface. - -Copyright (C) 1988, 1991 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -pare preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. -@end ifinfo - -@titlepage -@sp 10 -@center @titlefont{GNU Readline Library} -@center Brian Fox -@center Free Software Foundation -@center Version 1.1 -@center April 1991 - -@page -This document describes the GNU Readline Library, a utility which aids -in the consistency of user interface across discrete programs that need -to provide a command line interface. - -Published by the Free Software Foundation @* -675 Massachusetts Avenue, @* -Cambridge, MA 02139 USA - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. - -@vskip 0pt plus 1filll -Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. -@end titlepage - -@ifinfo -@node Top -@top GNU Readline Library - -This document describes the GNU Readline Library, a utility which aids -in the consistency of user interface across discrete programs that need -to provide a command line interface. - -@menu -* Command Line Editing:: GNU Readline User's Manual. -* Programming with GNU Readline:: GNU Readline Programmer's Manual. -* Concept Index:: Index of concepts described in this manual. -* Function and Variable Index:: Index of externally visible functions - and variables. -@end menu -@end ifinfo - -@include rluser.texinfo -@include rltech.texinfo - -@node Concept Index -@unnumbered Concept Index -@printindex cp - -@node Function and Variable Index -@unnumbered Function and Variable Index -@printindex fn - -@contents -@bye - diff --git a/contrib/gdb/readline/doc/rltech.texinfo b/contrib/gdb/readline/doc/rltech.texinfo deleted file mode 100644 index 2048b7c29df..00000000000 --- a/contrib/gdb/readline/doc/rltech.texinfo +++ /dev/null @@ -1,1012 +0,0 @@ -@comment %**start of header (This is for running Texinfo on a region.) -@setfilename rltech.info -@comment %**end of header (This is for running Texinfo on a region.) -@setchapternewpage odd - -@ifinfo -This document describes the GNU Readline Library, a utility for aiding -in the consitency of user interface across discrete programs that need -to provide a command line interface. - -Copyright (C) 1988 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -pare preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. -@end ifinfo - -@node Programming with GNU Readline -@chapter Programming with GNU Readline - -This manual describes the interface between the GNU Readline Library and -user programs. If you are a programmer, and you wish to include the -features found in GNU Readline in your own programs, such as completion, -line editing, and interactive history manipulation, this documentation -is for you. - -@menu -* Default Behaviour:: Using the default behaviour of Readline. -* Custom Functions:: Adding your own functions to Readline. -* Custom Completers:: Supplanting or supplementing Readline's - completion functions. -@end menu - -@node Default Behaviour -@section Default Behaviour - -Many programs provide a command line interface, such as @code{mail}, -@code{ftp}, and @code{sh}. For such programs, the default behaviour of -Readline is sufficient. This section describes how to use Readline in -the simplest way possible, perhaps to replace calls in your code to -@code{gets ()}. - -@findex readline () -@cindex readline, function -The function @code{readline} prints a prompt and then reads and returns -a single line of text from the user. The line which @code{readline ()} -returns is allocated with @code{malloc ()}; you should @code{free ()} -the line when you are done with it. The declaration for @code{readline} -in ANSI C is - -@example -@code{char *readline (char *@var{prompt});} -@end example - -So, one might say -@example -@code{char *line = readline ("Enter a line: ");} -@end example -in order to read a line of text from the user. - -The line which is returned has the final newline removed, so only the -text of the line remains. - -If readline encounters an @code{EOF} while reading the line, and the -line is empty at that point, then @code{(char *)NULL} is returned. -Otherwise, the line is ended just as if a newline was typed. - -If you want the user to be able to get at the line later, (with -@key{C-p} for example), you must call @code{add_history ()} to save the -line away in a @dfn{history} list of such lines. - -@example -@code{add_history (line)}; -@end example - -For full details on the GNU History Library, see the associated manual. - -It is polite to avoid saving empty lines on the history list, since it -is rare than someone has a burning need to reuse a blank line. Here is -a function which usefully replaces the standard @code{gets ()} library -function: - -@example -/* A static variable for holding the line. */ -static char *line_read = (char *)NULL; - -/* Read a string, and return a pointer to it. Returns NULL on EOF. */ -char * -do_gets () -@{ - /* If the buffer has already been allocated, return the memory - to the free pool. */ - if (line_read != (char *)NULL) - @{ - free (line_read); - line_read = (char *)NULL; - @} - - /* Get a line from the user. */ - line_read = readline (""); - - /* If the line has any text in it, save it on the history. */ - if (line_read && *line_read) - add_history (line_read); - - return (line_read); -@} -@end example - -The above code gives the user the default behaviour of @key{TAB} -completion: completion on file names. If you do not want readline to -complete on filenames, you can change the binding of the @key{TAB} key -with @code{rl_bind_key ()}. - -@findex rl_bind_key () -@example -@code{int rl_bind_key (int @var{key}, int (*@var{function})());} -@end example - -@code{rl_bind_key ()} takes 2 arguments; @var{key} is the character that -you want to bind, and @var{function} is the address of the function to -run when @var{key} is pressed. Binding @key{TAB} to @code{rl_insert ()} -makes @key{TAB} just insert itself. - -@code{rl_bind_key ()} returns non-zero if @var{key} is not a valid -ASCII character code (between 0 and 255). - -@example -@code{rl_bind_key ('\t', rl_insert);} -@end example - -This code should be executed once at the start of your program; you -might write a function called @code{initialize_readline ()} which -performs this and other desired initializations, such as installing -custom completers, etc. - -@node Custom Functions -@section Custom Functions - -Readline provides a great many functions for manipulating the text of -the line. But it isn't possible to anticipate the needs of all -programs. This section describes the various functions and variables -defined in within the Readline library which allow a user program to add -customized functionality to Readline. - -@menu -* The Function Type:: C declarations to make code readable. -* Function Naming:: How to give a function you write a name. -* Keymaps:: Making keymaps. -* Binding Keys:: Changing Keymaps. -* Function Writing:: Variables and calling conventions. -* Allowing Undoing:: How to make your functions undoable. -@end menu - -@node The Function Type -@subsection The Function Type - -For the sake of readabilty, we declare a new type of object, called -@dfn{Function}. A @code{Function} is a C language function which -returns an @code{int}. The type declaration for @code{Function} is: - -@noindent -@code{typedef int Function ();} - -The reason for declaring this new type is to make it easier to write -code describing pointers to C functions. Let us say we had a variable -called @var{func} which was a pointer to a function. Instead of the -classic C declaration - -@code{int (*)()func;} - -we have - -@code{Function *func;} - -@node Function Naming -@subsection Naming a Function - -The user can dynamically change the bindings of keys while using -Readline. This is done by representing the function with a descriptive -name. The user is able to type the descriptive name when referring to -the function. Thus, in an init file, one might find - -@example -Meta-Rubout: backward-kill-word -@end example - -This binds the keystroke @key{Meta-Rubout} to the function -@emph{descriptively} named @code{backward-kill-word}. You, as the -programmer, should bind the functions you write to descriptive names as -well. Readline provides a function for doing that: - -@defun rl_add_defun (char *name, Function *function, int key) -Add @var{name} to the list of named functions. Make @var{function} be -the function that gets called. If @var{key} is not -1, then bind it to -@var{function} using @code{rl_bind_key ()}. -@end defun - -Using this function alone is sufficient for most applications. It is -the recommended way to add a few functions to the default functions that -Readline has built in already. If you need to do more or different -things than adding a function to Readline, you may need to use the -underlying functions described below. - -@node Keymaps -@subsection Selecting a Keymap - -Key bindings take place on a @dfn{keymap}. The keymap is the -association between the keys that the user types and the functions that -get run. You can make your own keymaps, copy existing keymaps, and tell -Readline which keymap to use. - -@defun {Keymap rl_make_bare_keymap} () -Returns a new, empty keymap. The space for the keymap is allocated with -@code{malloc ()}; you should @code{free ()} it when you are done. -@end defun - -@defun {Keymap rl_copy_keymap} (Keymap map) -Return a new keymap which is a copy of @var{map}. -@end defun - -@defun {Keymap rl_make_keymap} () -Return a new keymap with the printing characters bound to rl_insert, -the lowercase Meta characters bound to run their equivalents, and -the Meta digits bound to produce numeric arguments. -@end defun - -@node Binding Keys -@subsection Binding Keys - -You associate keys with functions through the keymap. Here are -functions for doing that. - -@defun {int rl_bind_key} (int key, Function *function) -Binds @var{key} to @var{function} in the currently selected keymap. -Returns non-zero in the case of an invalid @var{key}. -@end defun - -@defun {int rl_bind_key_in_map} (int key, Function *function, Keymap map) -Bind @var{key} to @var{function} in @var{map}. Returns non-zero in the case -of an invalid @var{key}. -@end defun - -@defun {int rl_unbind_key} (int key) -Make @var{key} do nothing in the currently selected keymap. -Returns non-zero in case of error. -@end defun - -@defun {int rl_unbind_key_in_map} (int key, Keymap map) -Make @var{key} be bound to the null function in @var{map}. -Returns non-zero in case of error. -@end defun - -@defun rl_generic_bind (int type, char *keyseq, char *data, Keymap map) -Bind the key sequence represented by the string @var{keyseq} to the arbitrary -pointer @var{data}. @var{type} says what kind of data is pointed to by -@var{data}; right now this can be a function (@code{ISFUNC}), a macro -(@code{ISMACR}), or a keymap (@code{ISKMAP}). This makes new keymaps as -necessary. The initial place to do bindings is in @var{map}. -@end defun - -@node Function Writing -@subsection Writing a New Function - -In order to write new functions for Readline, you need to know the -calling conventions for keyboard invoked functions, and the names of the -variables that describe the current state of the line gathered so far. - -@defvar {char *rl_line_buffer} -This is the line gathered so far. You are welcome to modify the -contents of this, but see Undoing, below. -@end defvar - -@defvar {int rl_point} -The offset of the current cursor position in @var{rl_line_buffer}. -@end defvar - -@defvar {int rl_end} -The number of characters present in @code{rl_line_buffer}. When -@code{rl_point} is at the end of the line, then @code{rl_point} and -@code{rl_end} are equal. -@end defvar - -The calling sequence for a command @code{foo} looks like - -@example -@code{foo (int count, int key)} -@end example - -where @var{count} is the numeric argument (or 1 if defaulted) and -@var{key} is the key that invoked this function. - -It is completely up to the function as to what should be done with the -numeric argument; some functions use it as a repeat count, other -functions as a flag, and some choose to ignore it. In general, if a -function uses the numeric argument as a repeat count, it should be able -to do something useful with a negative argument as well as a positive -argument. At the very least, it should be aware that it can be passed a -negative argument. - -@node Allowing Undoing -@subsection Allowing Undoing - -Supporting the undo command is a painless thing to do, and makes your -functions much more useful to the end user. It is certainly easy to try -something if you know you can undo it. I could use an undo function for -the stock market. - -If your function simply inserts text once, or deletes text once, and it -calls @code{rl_insert_text ()} or @code{rl_delete_text ()} to do it, then -undoing is already done for you automatically, and you can safely skip -this section. - -If you do multiple insertions or multiple deletions, or any combination -of these operations, you should group them together into one operation. -This can be done with @code{rl_begin_undo_group ()} and -@code{rl_end_undo_group ()}. - -@defun rl_begin_undo_group () -Begins saving undo information in a group construct. The undo -information usually comes from calls to @code{rl_insert_text ()} and -@code{rl_delete_text ()}, but they could be direct calls to -@code{rl_add_undo ()}. -@end defun - -@defun rl_end_undo_group () -Closes the current undo group started with @code{rl_begin_undo_group -()}. There should be exactly one call to @code{rl_end_undo_group ()} -for every call to @code{rl_begin_undo_group ()}. -@end defun - -Finally, if you neither insert nor delete text, but directly modify the -existing text (e.g. change its case), you call @code{rl_modifying ()} -once, just before you modify the text. You must supply the indices of -the text range that you are going to modify. - -@defun rl_modifying (int start, int end) -Tell Readline to save the text between @var{start} and @var{end} as a -single undo unit. It is assumed that subsequent to this call you will -modify that range of text in some way. -@end defun - -@subsection An Example - -Here is a function which changes lowercase characters to the uppercase -equivalents, and uppercase characters to the lowercase equivalents. If -this function was bound to @samp{M-c}, then typing @samp{M-c} would -change the case of the character under point. Typing @samp{10 M-c} -would change the case of the following 10 characters, leaving the cursor on -the last character changed. - -@example -/* Invert the case of the COUNT following characters. */ -invert_case_line (count, key) - int count, key; -@{ - register int start, end; - - start = rl_point; - - if (count < 0) - @{ - direction = -1; - count = -count; - @} - else - direction = 1; - - /* Find the end of the range to modify. */ - end = start + (count * direction); - - /* Force it to be within range. */ - if (end > rl_end) - end = rl_end; - else if (end < 0) - end = -1; - - if (start > end) - @{ - int temp = start; - start = end; - end = temp; - @} - - if (start == end) - return; - - /* Tell readline that we are modifying the line, so save the undo - information. */ - rl_modifying (start, end); - - for (; start != end; start += direction) - @{ - if (uppercase_p (rl_line_buffer[start])) - rl_line_buffer[start] = to_lower (rl_line_buffer[start]); - else if (lowercase_p (rl_line_buffer[start])) - rl_line_buffer[start] = to_upper (rl_line_buffer[start]); - @} - /* Move point to on top of the last character changed. */ - rl_point = end - direction; -@} -@end example - -@node Custom Completers -@section Custom Completers - -Typically, a program that reads commands from the user has a way of -disambiguating commands and data. If your program is one of these, then -it can provide completion for either commands, or data, or both commands -and data. The following sections describe how your program and Readline -cooperate to provide this service to end users. - -@menu -* How Completing Works:: The logic used to do completion. -* Completion Functions:: Functions provided by Readline. -* Completion Variables:: Variables which control completion. -* A Short Completion Example:: An example of writing completer subroutines. -@end menu - -@node How Completing Works -@subsection How Completing Works - -In order to complete some text, the full list of possible completions -must be available. That is to say, it is not possible to accurately -expand a partial word without knowing what all of the possible words -that make sense in that context are. The GNU Readline library provides -the user interface to completion, and additionally, two of the most common -completion functions; filename and username. For completing other types -of text, you must write your own completion function. This section -describes exactly what those functions must do, and provides an example -function. - -There are three major functions used to perform completion: - -@enumerate -@item -The user-interface function @code{rl_complete ()}. This function is -called interactively with the same calling conventions as other -functions in readline intended for interactive use; i.e. @var{count}, -and @var{invoking-key}. It isolates the word to be completed and calls -@code{completion_matches ()} to generate a list of possible completions. -It then either lists the possible completions or actually performs the -completion, depending on which behaviour is desired. - -@item -The internal function @code{completion_matches ()} uses your -@dfn{generator} function to generate the list of possible matches, and -then returns the array of these matches. You should place the address -of your generator function in @code{rl_completion_entry_function}. - -@item -The generator function is called repeatedly from -@code{completion_matches ()}, returning a string each time. The -arguments to the generator function are @var{text} and @var{state}. -@var{text} is the partial word to be completed. @var{state} is zero the -first time the function is called, and a positive non-zero integer for -each subsequent call. When the generator function returns @code{(char -*)NULL} this signals @code{completion_matches ()} that there are no more -possibilities left. - -@end enumerate - -@defun rl_complete (int ignore, int invoking_key) -Complete the word at or before point. You have supplied the function -that does the initial simple matching selection algorithm (see -@code{completion_matches ()}). The default is to do filename completion. -@end defun - -Note that @code{rl_complete ()} has the identical calling conventions as -any other key-invokable function; this is because by default it is bound -to the @samp{TAB} key. - -@defvar {Function *rl_completion_entry_function} -This is a pointer to the generator function for @code{completion_matches -()}. If the value of @code{rl_completion_entry_function} is -@code{(Function *)NULL} then the default filename generator function is -used, namely @code{filename_entry_function ()}. -@end defvar - -@node Completion Functions -@subsection Completion Functions - -Here is the complete list of callable completion functions present in -Readline. - -@defun rl_complete_internal (int what_to_do) -Complete the word at or before point. @var{what_to_do} says what to do -with the completion. A value of @samp{?} means list the possible -completions. @samp{TAB} means do standard completion. @samp{*} means -insert all of the possible completions. -@end defun - -@defun rl_complete (int ignore, int invoking_key) -Complete the word at or before point. You have supplied the function -that does the initial simple matching selection algorithm (see -@code{completion_matches ()}). The default is to do filename -completion. This just calls @code{rl_complete_internal ()} with an -argument of @samp{TAB}. -@end defun - -@defun rl_possible_completions () -List the possible completions. See description of @code{rl_complete -()}. This just calls @code{rl_complete_internal ()} with an argument of -@samp{?}. -@end defun - -@defun {char **completion_matches} (char *text, char *(*entry_function) ()) -Returns an array of @code{(char *)} which is a list of completions for -@var{text}. If there are no completions, returns @code{(char **)NULL}. -The first entry in the returned array is the substitution for @var{text}. -The remaining entries are the possible completions. The array is -terminated with a @code{NULL} pointer. - -@var{entry_function} is a function of two args, and returns a -@code{(char *)}. The first argument is @var{text}. The second is a -state argument; it is zero on the first call, and non-zero on subsequent -calls. It returns a @code{NULL} pointer to the caller when there are -no more matches. -@end defun - -@defun {char *filename_completion_function} (char *text, int state) -A generator function for filename completion in the general case. Note -that completion in the Bash shell is a little different because of all -the pathnames that must be followed when looking up the completion for a -command. -@end defun - -@defun {char *username_completion_function} (char *text, int state) -A completion generator for usernames. @var{text} contains a partial -username preceded by a random character (usually @samp{~}). -@end defun - -@node Completion Variables -@subsection Completion Variables - -@defvar {Function *rl_completion_entry_function} -A pointer to the generator function for @code{completion_matches ()}. -@code{NULL} means to use @code{filename_entry_function ()}, the default -filename completer. -@end defvar - -@defvar {Function *rl_attempted_completion_function} -A pointer to an alternative function to create matches. -The function is called with @var{text}, @var{start}, and @var{end}. -@var{start} and @var{end} are indices in @code{rl_line_buffer} saying -what the boundaries of @var{text} are. If this function exists and -returns @code{NULL} then @code{rl_complete ()} will call the value of -@code{rl_completion_entry_function} to generate matches, otherwise the -array of strings returned will be used. -@end defvar - -@defvar {int rl_completion_query_items} -Up to this many items will be displayed in response to a -possible-completions call. After that, we ask the user if she is sure -she wants to see them all. The default value is 100. -@end defvar - -@defvar {char *rl_basic_word_break_characters} -The basic list of characters that signal a break between words for the -completer routine. The contents of this variable is what breaks words -in the Bash shell, i.e. " \t\n\"\\'`@@$><=;|&@{(". -@end defvar - -@defvar {char *rl_completer_word_break_characters} -The list of characters that signal a break between words for -@code{rl_complete_internal ()}. The default list is the contents of -@code{rl_basic_word_break_characters}. -@end defvar - -@defvar {char *rl_special_prefixes} -The list of characters that are word break characters, but should be -left in @var{text} when it is passed to the completion function. -Programs can use this to help determine what kind of completing to do. -@end defvar - -@defvar {int rl_ignore_completion_duplicates} -If non-zero, then disallow duplicates in the matches. Default is 1. -@end defvar - -@defvar {int rl_filename_completion_desired} -Non-zero means that the results of the matches are to be treated as -filenames. This is @emph{always} zero on entry, and can only be changed -within a completion entry generator function. -@end defvar - -@defvar {Function *rl_ignore_some_completions_function} -This function, if defined, is called by the completer when real filename -completion is done, after all the matching names have been generated. -It is passed a @code{NULL} terminated array of @code{(char *)} known as -@var{matches} in the code. The 1st element (@code{matches[0]}) is the -maximal substring that is common to all matches. This function can -re-arrange the list of matches as required, but each deleted element of -the array must be @code{free()}'d. -@end defvar - -@node A Short Completion Example -@subsection A Short Completion Example - -Here is a small application demonstrating the use of the GNU Readline -library. It is called @code{fileman}, and the source code resides in -@file{readline/examples/fileman.c}. This sample application provides -completion of command names, line editing features, and access to the -history list. - -@page -@smallexample -/* fileman.c -- A tiny application which demonstrates how to use the - GNU Readline library. This application interactively allows users - to manipulate files and their modes. */ - -#include -#include -#include -#include -#include -#include -#include - -/* The names of functions that actually do the manipulation. */ -int com_list (), com_view (), com_rename (), com_stat (), com_pwd (); -int com_delete (), com_help (), com_cd (), com_quit (); - -/* A structure which contains information on the commands this program - can understand. */ - -typedef struct @{ - char *name; /* User printable name of the function. */ - Function *func; /* Function to call to do the job. */ - char *doc; /* Documentation for this function. */ -@} COMMAND; - -COMMAND commands[] = @{ - @{ "cd", com_cd, "Change to directory DIR" @}, - @{ "delete", com_delete, "Delete FILE" @}, - @{ "help", com_help, "Display this text" @}, - @{ "?", com_help, "Synonym for `help'" @}, - @{ "list", com_list, "List files in DIR" @}, - @{ "ls", com_list, "Synonym for `list'" @}, - @{ "pwd", com_pwd, "Print the current working directory" @}, - @{ "quit", com_quit, "Quit using Fileman" @}, - @{ "rename", com_rename, "Rename FILE to NEWNAME" @}, - @{ "stat", com_stat, "Print out statistics on FILE" @}, - @{ "view", com_view, "View the contents of FILE" @}, - @{ (char *)NULL, (Function *)NULL, (char *)NULL @} -@}; - -/* The name of this program, as taken from argv[0]. */ -char *progname; - -/* When non-zero, this global means the user is done using this program. */ -int done = 0; -@page -main (argc, argv) - int argc; - char **argv; -@{ - progname = argv[0]; - - initialize_readline (); /* Bind our completer. */ - - /* Loop reading and executing lines until the user quits. */ - while (!done) - @{ - char *line; - - line = readline ("FileMan: "); - - if (!line) - @{ - done = 1; /* Encountered EOF at top level. */ - @} - else - @{ - /* Remove leading and trailing whitespace from the line. - Then, if there is anything left, add it to the history list - and execute it. */ - stripwhite (line); - - if (*line) - @{ - add_history (line); - execute_line (line); - @} - @} - - if (line) - free (line); - @} - exit (0); -@} - -/* Execute a command line. */ -execute_line (line) - char *line; -@{ - register int i; - COMMAND *find_command (), *command; - char *word; - - /* Isolate the command word. */ - i = 0; - while (line[i] && !whitespace (line[i])) - i++; - - word = line; - - if (line[i]) - line[i++] = '\0'; - - command = find_command (word); - - if (!command) - @{ - fprintf (stderr, "%s: No such command for FileMan.\n", word); - return; - @} - - /* Get argument to command, if any. */ - while (whitespace (line[i])) - i++; - - word = line + i; - - /* Call the function. */ - (*(command->func)) (word); -@} - -/* Look up NAME as the name of a command, and return a pointer to that - command. Return a NULL pointer if NAME isn't a command name. */ -COMMAND * -find_command (name) - char *name; -@{ - register int i; - - for (i = 0; commands[i].name; i++) - if (strcmp (name, commands[i].name) == 0) - return (&commands[i]); - - return ((COMMAND *)NULL); -@} - -/* Strip whitespace from the start and end of STRING. */ -stripwhite (string) - char *string; -@{ - register int i = 0; - - while (whitespace (string[i])) - i++; - - if (i) - strcpy (string, string + i); - - i = strlen (string) - 1; - - while (i > 0 && whitespace (string[i])) - i--; - - string[++i] = '\0'; -@} -@page -/* **************************************************************** */ -/* */ -/* Interface to Readline Completion */ -/* */ -/* **************************************************************** */ - -/* Tell the GNU Readline library how to complete. We want to try to complete - on command names if this is the first word in the line, or on filenames - if not. */ -initialize_readline () -@{ - char **fileman_completion (); - - /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = "FileMan"; - - /* Tell the completer that we want a crack first. */ - rl_attempted_completion_function = (Function *)fileman_completion; -@} - -/* Attempt to complete on the contents of TEXT. START and END show the - region of TEXT that contains the word to complete. We can use the - entire line in case we want to do some simple parsing. Return the - array of matches, or NULL if there aren't any. */ -char ** -fileman_completion (text, start, end) - char *text; - int start, end; -@{ - char **matches; - char *command_generator (); - - matches = (char **)NULL; - - /* If this word is at the start of the line, then it is a command - to complete. Otherwise it is the name of a file in the current - directory. */ - if (start == 0) - matches = completion_matches (text, command_generator); - - return (matches); -@} - -/* Generator function for command completion. STATE lets us know whether - to start from scratch; without any state (i.e. STATE == 0), then we - start at the top of the list. */ -char * -command_generator (text, state) - char *text; - int state; -@{ - static int list_index, len; - char *name; - - /* If this is a new word to complete, initialize now. This includes - saving the length of TEXT for efficiency, and initializing the index - variable to 0. */ - if (!state) - @{ - list_index = 0; - len = strlen (text); - @} - - /* Return the next name which partially matches from the command list. */ - while (name = commands[list_index].name) - @{ - list_index++; - - if (strncmp (name, text, len) == 0) - return (name); - @} - - /* If no names matched, then return NULL. */ - return ((char *)NULL); -@} -@page -/* **************************************************************** */ -/* */ -/* FileMan Commands */ -/* */ -/* **************************************************************** */ - -/* String to pass to system (). This is for the LIST, VIEW and RENAME - commands. */ -static char syscom[1024]; - -/* List the file(s) named in arg. */ -com_list (arg) - char *arg; -@{ - if (!arg) - arg = "*"; - - sprintf (syscom, "ls -FClg %s", arg); - system (syscom); -@} - -com_view (arg) - char *arg; -@{ - if (!valid_argument ("view", arg)) - return; - - sprintf (syscom, "cat %s | more", arg); - system (syscom); -@} - -com_rename (arg) - char *arg; -@{ - too_dangerous ("rename"); -@} - -com_stat (arg) - char *arg; -@{ - struct stat finfo; - - if (!valid_argument ("stat", arg)) - return; - - if (stat (arg, &finfo) == -1) - @{ - perror (arg); - return; - @} - - printf ("Statistics for `%s':\n", arg); - - printf ("%s has %d link%s, and is %d bytes in length.\n", arg, - finfo.st_nlink, (finfo.st_nlink == 1) ? "" : "s", finfo.st_size); - printf (" Created on: %s", ctime (&finfo.st_ctime)); - printf (" Last access at: %s", ctime (&finfo.st_atime)); - printf ("Last modified at: %s", ctime (&finfo.st_mtime)); -@} - -com_delete (arg) - char *arg; -@{ - too_dangerous ("delete"); -@} - -/* Print out help for ARG, or for all of the commands if ARG is - not present. */ -com_help (arg) - char *arg; -@{ - register int i; - int printed = 0; - - for (i = 0; commands[i].name; i++) - @{ - if (!*arg || (strcmp (arg, commands[i].name) == 0)) - @{ - printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); - printed++; - @} - @} - - if (!printed) - @{ - printf ("No commands match `%s'. Possibilties are:\n", arg); - - for (i = 0; commands[i].name; i++) - @{ - /* Print in six columns. */ - if (printed == 6) - @{ - printed = 0; - printf ("\n"); - @} - - printf ("%s\t", commands[i].name); - printed++; - @} - - if (printed) - printf ("\n"); - @} -@} - -/* Change to the directory ARG. */ -com_cd (arg) - char *arg; -@{ - if (chdir (arg) == -1) - perror (arg); - - com_pwd (""); -@} - -/* Print out the current working directory. */ -com_pwd (ignore) - char *ignore; -@{ - char dir[1024]; - - (void) getwd (dir); - - printf ("Current directory is %s\n", dir); -@} - -/* The user wishes to quit using this program. Just set DONE non-zero. */ -com_quit (arg) - char *arg; -@{ - done = 1; -@} - -/* Function which tells you that you can't do this. */ -too_dangerous (caller) - char *caller; -@{ - fprintf (stderr, - "%s: Too dangerous for me to distribute. Write it yourself.\n", - caller); -@} - -/* Return non-zero if ARG is a valid argument for CALLER, else print - an error message and return zero. */ -int -valid_argument (caller, arg) - char *caller, *arg; -@{ - if (!arg || !*arg) - @{ - fprintf (stderr, "%s: Argument required.\n", caller); - return (0); - @} - - return (1); -@} -@end smallexample diff --git a/contrib/gdb/readline/doc/rluser.texinfo b/contrib/gdb/readline/doc/rluser.texinfo deleted file mode 100644 index da1111148bf..00000000000 --- a/contrib/gdb/readline/doc/rluser.texinfo +++ /dev/null @@ -1,566 +0,0 @@ -@ignore -This file documents the end user interface to the GNU command line -editing feautres. It is to be an appendix to manuals for programs which -use these features. There is a document entitled "readline.texinfo" -which contains both end-user and programmer documentation for the GNU -Readline Library. - -Copyright (C) 1988 Free Software Foundation, Inc. - -Authored by Brian Fox. - -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission notice -identical to this one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -Permission is granted to make and distribute verbatim copies of this manual -provided the copyright notice and this permission notice are preserved on -all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -GNU Copyright statement is available to the distributee, and provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ignore - -@node Command Line Editing -@appendix Command Line Editing - -This text describes GNU's command line editing interface. - -@menu -* Introduction and Notation:: Notation used in this text. -* Readline Interaction:: The minimum set of commands for editing a line. -* Readline Init File:: Customizing Readline from a user's view. -@end menu - -@node Introduction and Notation -@section Introduction to Line Editing - -The following paragraphs describe the notation we use to represent -keystrokes. - -The text @key{C-k} is read as `Control-K' and describes the character -produced when the Control key is depressed and the @key{k} key is struck. - -The text @key{M-k} is read as `Meta-K' and describes the character -produced when the meta key (if you have one) is depressed, and the @key{k} -key is struck. If you do not have a meta key, the identical keystroke -can be generated by typing @key{ESC} @i{first}, and then typing @key{k}. -Either process is known as @dfn{metafying} the @key{k} key. - -The text @key{M-C-k} is read as `Meta-Control-k' and describes the -character produced by @dfn{metafying} @key{C-k}. - -In addition, several keys have their own names. Specifically, -@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all -stand for themselves when seen in this text, or in an init file -(@pxref{Readline Init File}, for more info). - -@node Readline Interaction -@section Readline Interaction -@cindex interaction, readline - -Often during an interactive session you type in a long line of text, -only to notice that the first word on the line is misspelled. The -Readline library gives you a set of commands for manipulating the text -as you type it in, allowing you to just fix your typo, and not forcing -you to retype the majority of the line. Using these editing commands, -you move the cursor to the place that needs correction, and delete or -insert the text of the corrections. Then, when you are satisfied with -the line, you simply press @key{RET}. You do not have to be at the -end of the line to press @key{RET}; the entire line is accepted -regardless of the location of the cursor within the line. - -@menu -* Readline Bare Essentials:: The least you need to know about Readline. -* Readline Movement Commands:: Moving about the input line. -* Readline Killing Commands:: How to delete text, and how to get it back! -* Readline Arguments:: Giving numeric arguments to commands. -@end menu - -@node Readline Bare Essentials -@subsection Readline Bare Essentials - -In order to enter characters into the line, simply type them. The typed -character appears where the cursor was, and then the cursor moves one -space to the right. If you mistype a character, you can use @key{DEL} to -back up, and delete the mistyped character. - -Sometimes you may miss typing a character that you wanted to type, and -not notice your error until you have typed several other characters. In -that case, you can type @key{C-b} to move the cursor to the left, and then -correct your mistake. Aftwerwards, you can move the cursor to the right -with @key{C-f}. - -When you add text in the middle of a line, you will notice that characters -to the right of the cursor get `pushed over' to make room for the text -that you have inserted. Likewise, when you delete text behind the cursor, -characters to the right of the cursor get `pulled back' to fill in the -blank space created by the removal of the text. A list of the basic bare -essentials for editing the text of an input line follows. - -@table @asis -@item @key{C-b} -Move back one character. -@item @key{C-f} -Move forward one character. -@item @key{DEL} -Delete the character to the left of the cursor. -@item @key{C-d} -Delete the character underneath the cursor. -@item @w{Printing characters} -Insert itself into the line at the cursor. -@item @key{C-_} -Undo the last thing that you did. You can undo all the way back to an -empty line. -@end table - -@node Readline Movement Commands -@subsection Readline Movement Commands - -The above table describes the most basic possible keystrokes that you need -in order to do editing of the input line. For your convenience, many -other commands have been added in addition to @key{C-b}, @key{C-f}, -@key{C-d}, and @key{DEL}. Here are some commands for moving more rapidly -about the line. - -@table @key -@item C-a -Move to the start of the line. -@item C-e -Move to the end of the line. -@item M-f -Move forward a word. -@item M-b -Move backward a word. -@item C-l -Clear the screen, reprinting the current line at the top. -@end table - -Notice how @key{C-f} moves forward a character, while @key{M-f} moves -forward a word. It is a loose convention that control keystrokes -operate on characters while meta keystrokes operate on words. - -@node Readline Killing Commands -@subsection Readline Killing Commands - -@dfn{Killing} text means to delete the text from the line, but to save -it away for later use, usually by @dfn{yanking} it back into the line. -If the description for a command says that it `kills' text, then you can -be sure that you can get the text back in a different (or the same) -place later. - -Here is the list of commands for killing text. - -@table @key -@item C-k -Kill the text from the current cursor position to the end of the line. - -@item M-d -Kill from the cursor to the end of the current word, or if between -words, to the end of the next word. - -@item M-DEL -Kill from the cursor to the start of the previous word, or if between -words, to the start of the previous word. - -@item C-w -Kill from the cursor to the previous whitespace. This is different than -@key{M-DEL} because the word boundaries differ. - -@end table - -And, here is how to @dfn{yank} the text back into the line. - -@table @key -@item C-y -Yank the most recently killed text back into the buffer at the cursor. - -@item M-y -Rotate the kill-ring, and yank the new top. You can only do this if -the prior command is @key{C-y} or @key{M-y}. -@end table - -When you use a kill command, the text is saved in a @dfn{kill-ring}. -Any number of consecutive kills save all of the killed text together, so -that when you yank it back, you get it in one clean sweep. The kill -ring is not line specific; the text that you killed on a previously -typed line is available to be yanked back later, when you are typing -another line. - -@node Readline Arguments -@subsection Readline Arguments - -You can pass numeric arguments to Readline commands. Sometimes the -argument acts as a repeat count, other times it is the @i{sign} of the -argument that is significant. If you pass a negative argument to a -command which normally acts in a forward direction, that command will -act in a backward direction. For example, to kill text back to the -start of the line, you might type @key{M--} @key{C-k}. - -The general way to pass numeric arguments to a command is to type meta -digits before the command. If the first `digit' you type is a minus -sign (@key{-}), then the sign of the argument will be negative. Once -you have typed one meta digit to get the argument started, you can type -the remainder of the digits, and then the command. For example, to give -the @key{C-d} command an argument of 10, you could type @key{M-1 0 C-d}. - - -@node Readline Init File -@section Readline Init File - -Although the Readline library comes with a set of @sc{gnu} Emacs-like -keybindings, it is possible that you would like to use a different set -of keybindings. You can customize programs that use Readline by putting -commands in an @dfn{init} file in your home directory. The name of this -file is @file{~/.inputrc}. - -When a program which uses the Readline library starts up, the -@file{~/.inputrc} file is read, and the keybindings are set. - -In addition, the @key{C-x C-r} command re-reads this init file, thus -incorporating any changes that you might have made to it. - -@menu -* Readline Init Syntax:: Syntax for the commands in @file{~/.inputrc}. -* Readline vi Mode:: Switching to @code{vi} mode in Readline. -@end menu - -@node Readline Init Syntax -@subsection Readline Init Syntax - -There are only four constructs allowed in the @file{~/.inputrc} -file: - -@table @asis -@item Variable Settings -You can change the state of a few variables in Readline. You do this by -using the @code{set} command within the init file. Here is how you -would specify that you wish to use @code{vi} line editing commands: - -@example -set editing-mode vi -@end example - -Right now, there are only a few variables which can be set; so few in -fact, that we just iterate them here: - -@table @code - -@item editing-mode -@vindex editing-mode -The @code{editing-mode} variable controls which editing mode you are -using. By default, @sc{gnu} Readline starts up in Emacs editing mode, where -the keystrokes are most similar to Emacs. This variable can either be -set to @code{emacs} or @code{vi}. - -@item horizontal-scroll-mode -@vindex horizontal-scroll-mode -This variable can either be set to @code{On} or @code{Off}. Setting it -to @code{On} means that the text of the lines that you edit will scroll -horizontally on a single screen line when they are larger than the width -of the screen, instead of wrapping onto a new screen line. By default, -this variable is set to @code{Off}. - -@item mark-modified-lines -@vindex mark-modified-lines -This variable when set to @code{On}, says to display an asterisk -(@samp{*}) at the starts of history lines which have been modified. -This variable is off by default. - -@item prefer-visible-bell -@vindex prefer-visible-bell -If this variable is set to @code{On} it means to use a visible bell if -one is available, rather than simply ringing the terminal bell. By -default, the value is @code{Off}. -@end table - -@item Key Bindings -The syntax for controlling keybindings in the @file{~/.inputrc} file is -simple. First you have to know the @i{name} of the command that you -want to change. The following pages contain tables of the command name, -the default keybinding, and a short description of what the command -does. - -Once you know the name of the command, simply place the name of the key -you wish to bind the command to, a colon, and then the name of the -command on a line in the @file{~/.inputrc} file. The name of the key -can be expressed in different ways, depending on which is most -comfortable for you. - -@table @asis -@item @w{@var{keyname}: @var{function-name} or @var{macro}} -@var{keyname} is the name of a key spelled out in English. For example: -@example -Control-u: universal-argument -Meta-Rubout: backward-kill-word -Control-o: ">&output" -@end example - -In the above example, @key{C-u} is bound to the function -@code{universal-argument}, and @key{C-o} is bound to run the macro -expressed on the right hand side (that is, to insert the text -@samp{>&output} into the line). - -@item @w{"@var{keyseq}": @var{function-name} or @var{macro}} -@var{keyseq} differs from @var{keyname} above in that strings denoting -an entire key sequence can be specified. Simply place the key sequence -in double quotes. @sc{gnu} Emacs style key escapes can be used, as in the -following example: - -@example -"\C-u": universal-argument -"\C-x\C-r": re-read-init-file -"\e[11~": "Function Key 1" -@end example - -In the above example, @key{C-u} is bound to the function -@code{universal-argument} (just as it was in the first example), -@key{C-x C-r} is bound to the function @code{re-read-init-file}, and -@key{ESC [ 1 1 ~} is bound to insert the text @samp{Function Key 1}. - -@end table -@end table - -@menu -* Commands For Moving:: Moving about the line. -* Commands For History:: Getting at previous lines. -* Commands For Text:: Commands for changing text. -* Commands For Killing:: Commands for killing and yanking. -* Numeric Arguments:: Specifying numeric arguments, repeat counts. -* Commands For Completion:: Getting Readline to do the typing for you. -* Miscellaneous Commands:: Other miscillaneous commands. -@end menu - -@need 2000 -@node Commands For Moving -@subsubsection Commands For Moving - -@ftable @code -@item beginning-of-line (@key{C-a}) -Move to the start of the current line. - -@item end-of-line (@key{C-e}) -Move to the end of the line. - -@item forward-char (@key{C-f}) -Move forward a character. - -@item backward-char (@key{C-b}) -Move back a character. - -@item forward-word (@key{M-f}) -Move forward to the end of the next word. - -@item backward-word (@key{M-b}) -Move back to the start of this, or the previous, word. - -@item clear-screen (@key{C-l}) -Clear the screen leaving the current line at the top of the screen. - -@end ftable - -@need 2000 -@node Commands For History -@subsubsection Commands For Manipulating The History - -@ftable @code -@item accept-line (Newline, Return) -Accept the line regardless of where the cursor is. If this line is -non-empty, add it to the history list. If this line was a history -line, then restore the history line to its original state. - -@item previous-history (@key{C-p}) -Move `up' through the history list. - -@item next-history (@key{C-n}) -Move `down' through the history list. - -@item beginning-of-history (@key{M-<}) -Move to the first line in the history. - -@item end-of-history (@key{M->}) -Move to the end of the input history, i.e., the line you are entering. - -@item reverse-search-history (@key{C-r}) -Search backward starting at the current line and moving `up' through -the history as necessary. This is an incremental search. - -@item forward-search-history (@key{C-s}) -Search forward starting at the current line and moving `down' through -the the history as necessary. - -@end ftable - -@need 2000 -@node Commands For Text -@subsubsection Commands For Changing Text - -@ftable @code -@item delete-char (@key{C-d}) -Delete the character under the cursor. If the cursor is at the -beginning of the line, and there are no characters in the line, and -the last character typed was not @key{C-d}, then return EOF. - -@item backward-delete-char (Rubout) -Delete the character behind the cursor. A numeric argument says to kill -the characters instead of deleting them. - -@item quoted-insert (@key{C-q}, @key{C-v}) -Add the next character that you type to the line verbatim. This is -how to insert things like @key{C-q} for example. - -@item tab-insert (@key{M-TAB}) -Insert a tab character. - -@item self-insert (a, b, A, 1, !, ...) -Insert yourself. - -@item transpose-chars (@key{C-t}) -Drag the character before point forward over the character at point. -Point moves forward as well. If point is at the end of the line, then -transpose the two characters before point. Negative arguments don't work. - -@item transpose-words (@key{M-t}) -Drag the word behind the cursor past the word in front of the cursor -moving the cursor over that word as well. - -@item upcase-word (@key{M-u}) -Uppercase all letters in the current (or following) word. With a -negative argument, do the previous word, but do not move point. - -@item downcase-word (@key{M-l}) -Lowercase all letters in the current (or following) word. With a -negative argument, do the previous word, but do not move point. - -@item capitalize-word (@key{M-c}) -Uppercase the first letter in the current (or following) word. With a -negative argument, do the previous word, but do not move point. - -@end ftable - -@need 2000 -@node Commands For Killing -@subsubsection Killing And Yanking - -@ftable @code -@item kill-line (@key{C-k}) -Kill the text from the current cursor position to the end of the line. - -@item backward-kill-line () -Kill backward to the beginning of the line. This is normally unbound. - -@item kill-word (@key{M-d}) -Kill from the cursor to the end of the current word, or if between -words, to the end of the next word. - -@item backward-kill-word (@key{M-DEL}) -Kill the word behind the cursor. - -@item unix-line-discard (@key{C-u}) -Kill the whole line the way @key{C-u} used to in Unix line input. -The killed text is saved on the kill-ring. - -@item unix-word-rubout (@key{C-w}) -Kill the word the way @key{C-w} used to in Unix line input. -The killed text is saved on the kill-ring. This is different than -backward-kill-word because the word boundaries differ. - -@item yank (@key{C-y}) -Yank the top of the kill ring into the buffer at point. - -@item yank-pop (@key{M-y}) -Rotate the kill-ring, and yank the new top. You can only do this if -the prior command is yank or yank-pop. -@end ftable - -@need 2000 -@node Numeric Arguments -@subsubsection Specifying Numeric Arguments - -@ftable @code - -@item digit-argument (@key{M-0}, @key{M-1}, ... @key{M--}) -Add this digit to the argument already accumulating, or start a new -argument. @key{M--} starts a negative argument. - -@item universal-argument () -Do what @key{C-u} does in @sc{gnu} Emacs. By default, this is not bound. -@end ftable - - -@need 2000 -@node Commands For Completion -@subsubsection Letting Readline Type For You - -@ftable @code -@item complete (TAB) -Attempt to do completion on the text before point. This is -implementation defined. Generally, if you are typing a filename -argument, you can do filename completion; if you are typing a command, -you can do command completion, if you are typing in a symbol to GDB, you -can do symbol name completion, if you are typing in a variable to Bash, -you can do variable name completion. - -@item possible-completions (M-?) -List the possible completions of the text before point. -@end ftable - -@need 2000 -@node Miscellaneous Commands -@subsubsection Some Miscellaneous Commands - -@ftable @code - -@item re-read-init-file (@key{C-x} @key{C-r}) -Read in the contents of your @file{~/.inputrc} file, and incorporate -any bindings found there. - -@item abort (@key{C-g}) -Stop running the current editing command. - -@ignore -@c I have no idea what this means, and can't figure it out by -@c experiment, and can't find it in the readline source. -@c doc@cygnus.com, 20may1993. -@item do-uppercase-version (@key{M-a}, @key{M-b}, ...) -Run the command that is bound to your uppercase brother. -@end ignore - -@item prefix-meta (ESC) -Make the next character that you type be metafied. This is for people -without a meta key. Typing @key{ESC f} is equivalent to typing -@key{M-f}. - -@item undo (@key{C-_}) -Incremental undo, separately remembered for each line. - -@item revert-line (@key{M-r}) -Undo all changes made to this line. This is like typing the `undo' -command enough times to get back to the beginning. -@end ftable - -@need 2000 -@node Readline vi Mode -@subsection Readline @code{vi} Mode - -@cindex @code{vi} style command editing -@kindex toggle-editing-mode -While the Readline library does not have a full set of @code{vi} editing -functions, it does contain enough to allow simple editing of the line. - -In order to switch interactively between @sc{gnu} Emacs and @code{vi} -editing modes, use the command @key{M-C-j} (toggle-editing-mode). - -When you enter a line in @code{vi} mode, you are already placed in `insertion' -mode, as if you had typed an `i'. Pressing @key{ESC} switches you into -`edit' mode, where you can edit the text of the line with the standard -@code{vi} movement keys, move to previous history lines with `k', and following -lines with `j', and so forth. - From f759f84884543e1580c6ae61d59096c8b3f2dcf3 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 20 Jun 2004 18:26:14 +0000 Subject: [PATCH 5/5] Import of GDB version 6.1.1 (stripped; see FREEBSD-Xlist rev. 1.6). --- contrib/gdb/config-ml.in | 143 +- contrib/gdb/djunpack.bat | 52 + contrib/gdb/gdb/MAINTAINERS | 258 +- contrib/gdb/gdb/NEWS | 433 + contrib/gdb/gdb/PROBLEMS | 117 +- contrib/gdb/gdb/README | 127 +- contrib/gdb/gdb/TODO | 18 - contrib/gdb/gdb/abug-rom.c | 182 + contrib/gdb/gdb/acinclude.m4 | 272 +- contrib/gdb/gdb/aclocal.m4 | 272 +- contrib/gdb/gdb/ada-exp.c | 2642 ++++ contrib/gdb/gdb/ada-exp.y | 969 ++ contrib/gdb/gdb/ada-lang.c | 8254 +++++++++++++ contrib/gdb/gdb/ada-lang.h | 392 + contrib/gdb/gdb/ada-lex.l | 928 ++ contrib/gdb/gdb/ada-tasks.c | 819 ++ contrib/gdb/gdb/ada-typeprint.c | 852 ++ contrib/gdb/gdb/ada-valprint.c | 987 ++ contrib/gdb/gdb/alpha-mdebug-tdep.c | 386 + contrib/gdb/gdb/alpha-nat.c | 272 + contrib/gdb/gdb/alpha-tdep.c | 2470 ++-- contrib/gdb/gdb/alpha-tdep.h | 110 + contrib/gdb/gdb/alphabsd-nat.c | 104 +- contrib/gdb/gdb/alphabsd-tdep.c | 55 + contrib/gdb/gdb/alphabsd-tdep.h | 33 + contrib/gdb/gdb/alphafbsd-tdep.c | 77 +- contrib/gdb/gdb/alphanbsd-tdep.c | 234 + contrib/gdb/gdb/amd64-nat.c | 163 + contrib/gdb/gdb/amd64-nat.h | 53 + contrib/gdb/gdb/amd64-tdep.c | 1199 ++ contrib/gdb/gdb/amd64-tdep.h | 93 + contrib/gdb/gdb/amd64bsd-nat.c | 107 + contrib/gdb/gdb/amd64fbsd-nat.c | 235 + contrib/gdb/gdb/amd64fbsd-tdep.c | 155 + contrib/gdb/gdb/amd64nbsd-nat.c | 68 + contrib/gdb/gdb/amd64nbsd-tdep.c | 135 + contrib/gdb/gdb/amd64obsd-nat.c | 68 + contrib/gdb/gdb/amd64obsd-tdep.c | 224 + contrib/gdb/gdb/annotate.c | 96 +- contrib/gdb/gdb/arch-utils.c | 735 +- contrib/gdb/gdb/arch-utils.h | 152 +- contrib/gdb/gdb/arm-tdep.c | 3018 +++++ contrib/gdb/gdb/arm-tdep.h | 95 +- contrib/gdb/gdb/armnbsd-tdep.c | 36 +- contrib/gdb/gdb/auxv.c | 300 + contrib/gdb/gdb/auxv.h | 75 + contrib/gdb/gdb/ax-gdb.c | 115 +- contrib/gdb/gdb/ax-gdb.h | 3 +- contrib/gdb/gdb/ax-general.c | 1 + contrib/gdb/gdb/bcache.c | 186 +- contrib/gdb/gdb/bcache.h | 152 +- contrib/gdb/gdb/bfd-target.c | 131 + contrib/gdb/gdb/bfd-target.h | 39 + contrib/gdb/gdb/block.c | 295 + contrib/gdb/gdb/block.h | 174 + contrib/gdb/gdb/blockframe.c | 1174 +- contrib/gdb/gdb/breakpoint.c | 3757 +++--- contrib/gdb/gdb/breakpoint.h | 158 +- contrib/gdb/gdb/buildsym.c | 230 +- contrib/gdb/gdb/buildsym.h | 38 +- contrib/gdb/gdb/c-exp.c | 3443 ++++++ contrib/gdb/gdb/c-exp.y | 369 +- contrib/gdb/gdb/c-lang.c | 291 +- contrib/gdb/gdb/c-lang.h | 13 +- contrib/gdb/gdb/c-typeprint.c | 176 +- contrib/gdb/gdb/c-valprint.c | 28 +- contrib/gdb/gdb/charset.c | 1277 ++ contrib/gdb/gdb/charset.h | 109 + contrib/gdb/gdb/cli-out.c | 80 +- contrib/gdb/gdb/cli-out.h | 5 + contrib/gdb/gdb/cli/cli-cmds.c | 562 +- contrib/gdb/gdb/cli/cli-decode.c | 351 +- contrib/gdb/gdb/cli/cli-decode.h | 108 +- contrib/gdb/gdb/cli/cli-dump.c | 796 ++ contrib/gdb/gdb/cli/cli-dump.h | 40 + contrib/gdb/gdb/cli/cli-interp.c | 157 + contrib/gdb/gdb/cli/cli-logging.c | 205 + contrib/gdb/gdb/cli/cli-script.c | 150 +- contrib/gdb/gdb/cli/cli-script.h | 8 + contrib/gdb/gdb/cli/cli-setshow.c | 47 +- contrib/gdb/gdb/cli/cli-setshow.h | 2 + contrib/gdb/gdb/coff-pe-read.c | 346 + contrib/gdb/gdb/coff-pe-read.h | 32 + contrib/gdb/gdb/coff-solib.c | 134 + contrib/gdb/gdb/coff-solib.h | 186 + contrib/gdb/gdb/coffread.c | 337 +- contrib/gdb/gdb/command.h | 276 +- contrib/gdb/gdb/complaints.c | 359 +- contrib/gdb/gdb/complaints.h | 46 +- contrib/gdb/gdb/completer.c | 67 +- contrib/gdb/gdb/completer.h | 12 +- contrib/gdb/gdb/config/alpha/alpha.mt | 2 + contrib/gdb/gdb/config/alpha/fbsd.mt | 2 +- contrib/gdb/gdb/config/alpha/nbsd.mh | 4 + contrib/gdb/gdb/config/alpha/nbsd.mt | 4 + contrib/gdb/gdb/config/alpha/nm-fbsd.h | 4 +- contrib/gdb/gdb/config/alpha/nm-nbsd.h | 31 + contrib/gdb/gdb/config/alpha/nm-osf.h | 22 +- contrib/gdb/gdb/config/alpha/nm-osf2.h | 3 - contrib/gdb/gdb/config/alpha/tm-alpha.h | 409 +- contrib/gdb/gdb/config/alpha/tm-fbsd.h | 22 +- contrib/gdb/gdb/config/alpha/tm-nbsd.h | 28 + contrib/gdb/gdb/config/arm/nbsd.mt | 3 +- contrib/gdb/gdb/config/arm/nbsdaout.mh | 5 + contrib/gdb/gdb/config/arm/nbsdelf.mh | 4 + contrib/gdb/gdb/config/arm/nm-nbsd.h | 8 +- contrib/gdb/gdb/config/arm/nm-nbsdaout.h | 29 + contrib/gdb/gdb/config/arm/tm-arm.h | 2 - contrib/gdb/gdb/config/arm/tm-nbsd.h | 26 + contrib/gdb/gdb/config/arm/wince.mt | 2 +- contrib/gdb/gdb/config/arm/xm-nbsd.h | 2 +- contrib/gdb/gdb/config/i386/fbsd.mh | 10 +- contrib/gdb/gdb/config/i386/fbsd.mt | 5 +- contrib/gdb/gdb/config/i386/fbsd64.mh | 5 + contrib/gdb/gdb/config/i386/fbsd64.mt | 5 + contrib/gdb/gdb/config/i386/go32.mh | 8 +- contrib/gdb/gdb/config/i386/i386aout.mt | 4 +- contrib/gdb/gdb/config/i386/i386gnu.mh | 10 +- contrib/gdb/gdb/config/i386/i386gnu.mt | 6 +- contrib/gdb/gdb/config/i386/i386lynx.mh | 3 - contrib/gdb/gdb/config/i386/i386nw.mt | 2 +- contrib/gdb/gdb/config/i386/i386sol2.mh | 8 +- contrib/gdb/gdb/config/i386/i386sol2.mt | 4 +- contrib/gdb/gdb/config/i386/i386v.mt | 2 +- contrib/gdb/gdb/config/i386/i386v42mp.mh | 4 +- contrib/gdb/gdb/config/i386/nbsd.mt | 7 +- contrib/gdb/gdb/config/i386/nbsd64.mh | 5 + contrib/gdb/gdb/config/i386/nbsd64.mt | 4 + contrib/gdb/gdb/config/i386/nbsdaout.mh | 5 + contrib/gdb/gdb/config/i386/nbsdelf.mh | 6 +- contrib/gdb/gdb/config/i386/ncr3000.mt | 2 +- contrib/gdb/gdb/config/i386/nm-fbsd.h | 26 +- contrib/gdb/gdb/config/i386/nm-fbsd64.h | 37 + contrib/gdb/gdb/config/i386/nm-go32.h | 4 +- contrib/gdb/gdb/config/i386/nm-i386.h | 6 +- contrib/gdb/gdb/config/i386/nm-i386gnu.h | 38 + contrib/gdb/gdb/config/i386/nm-i386lynx.h | 2 +- contrib/gdb/gdb/config/i386/nm-i386sco.h | 19 +- contrib/gdb/gdb/config/i386/nm-i386sco5.h | 52 +- contrib/gdb/gdb/config/i386/nm-i386sol2.h | 5 +- contrib/gdb/gdb/config/i386/nm-i386v.h | 37 +- contrib/gdb/gdb/config/i386/nm-i386v4.h | 2 +- contrib/gdb/gdb/config/i386/nm-i386v42mp.h | 71 +- contrib/gdb/gdb/config/i386/nm-nbsd.h | 14 +- contrib/gdb/gdb/config/i386/nm-nbsdaout.h | 31 + contrib/gdb/gdb/config/i386/nm-nto.h | 6 + contrib/gdb/gdb/config/i386/nm-obsd.h | 8 +- contrib/gdb/gdb/config/i386/nto.mh | 7 + contrib/gdb/gdb/config/i386/nto.mt | 4 + contrib/gdb/gdb/config/i386/obsd.mh | 9 +- contrib/gdb/gdb/config/i386/obsd.mt | 7 +- contrib/gdb/gdb/config/i386/obsd64.mh | 5 + contrib/gdb/gdb/config/i386/obsd64.mt | 5 + contrib/gdb/gdb/config/i386/obsdaout.mh | 5 + contrib/gdb/gdb/config/i386/tm-fbsd.h | 70 +- contrib/gdb/gdb/config/i386/tm-go32.h | 40 - contrib/gdb/gdb/config/i386/tm-i386.h | 354 - contrib/gdb/gdb/config/i386/tm-i386lynx.h | 9 +- contrib/gdb/gdb/config/i386/tm-i386sol2.h | 27 +- contrib/gdb/gdb/config/i386/tm-nbsd.h | 53 +- contrib/gdb/gdb/config/i386/tm-nto.h | 33 + contrib/gdb/gdb/config/i386/tm-vxworks.h | 4 +- contrib/gdb/gdb/config/i386/xm-i386.h | 7 +- contrib/gdb/gdb/config/i386/xm-i386sco.h | 9 - contrib/gdb/gdb/config/i386/xm-i386v4.h | 2 +- contrib/gdb/gdb/config/i386/xm-nbsd.h | 11 +- contrib/gdb/gdb/config/ia64/ia64.mt | 2 + contrib/gdb/gdb/config/ia64/tm-ia64.h | 51 - contrib/gdb/gdb/config/mips/decstation.mh | 4 + contrib/gdb/gdb/config/mips/embed.mt | 4 + contrib/gdb/gdb/config/mips/littlemips.mh | 3 + contrib/gdb/gdb/config/mips/mipsv4.mh | 6 + contrib/gdb/gdb/config/mips/mipsv4.mt | 3 + contrib/gdb/gdb/config/mips/nbsd.mh | 4 + contrib/gdb/gdb/config/mips/nbsd.mt | 7 + contrib/gdb/gdb/config/mips/news-mips.mh | 3 + contrib/gdb/gdb/config/mips/nm-mips.h | 34 + contrib/gdb/gdb/config/mips/nm-nbsd.h | 28 + contrib/gdb/gdb/config/mips/nm-news-mips.h | 43 + contrib/gdb/gdb/config/mips/nm-riscos.h | 60 + contrib/gdb/gdb/config/mips/riscos.mh | 16 + contrib/gdb/gdb/config/mips/tm-mips.h | 119 + contrib/gdb/gdb/config/mips/tm-mipsv4.h | 37 + contrib/gdb/gdb/config/mips/tm-nbsd.h | 37 + contrib/gdb/gdb/config/mips/tm-vxmips.h | 23 + contrib/gdb/gdb/config/mips/tm-wince.h | 33 + contrib/gdb/gdb/config/mips/vxmips.mt | 3 + contrib/gdb/gdb/config/mips/wince.mt | 5 + contrib/gdb/gdb/config/mips/xm-mips.h | 59 + contrib/gdb/gdb/config/mips/xm-mipsv4.h | 22 + contrib/gdb/gdb/config/mips/xm-riscos.h | 25 + contrib/gdb/gdb/config/nm-gnu.h | 43 + contrib/gdb/gdb/config/nm-lynx.h | 86 + contrib/gdb/gdb/config/nm-nbsd.h | 27 + contrib/gdb/gdb/config/nm-nbsdaout.h | 72 + contrib/gdb/gdb/config/nm-sysv4.h | 34 + contrib/gdb/gdb/config/powerpc/nbsd.mh | 2 +- contrib/gdb/gdb/config/powerpc/nbsd.mt | 5 +- contrib/gdb/gdb/config/powerpc/nm-nbsd.h | 6 +- contrib/gdb/gdb/config/powerpc/ppc-eabi.mt | 2 +- contrib/gdb/gdb/config/powerpc/ppc-sim.mt | 2 +- contrib/gdb/gdb/config/powerpc/tm-nbsd.h | 3 +- contrib/gdb/gdb/config/powerpc/tm-ppc-eabi.h | 9 - contrib/gdb/gdb/config/powerpc/tm-vxworks.h | 2 +- contrib/gdb/gdb/config/powerpc/vxworks.mt | 2 +- contrib/gdb/gdb/config/s390/s390.mh | 5 + contrib/gdb/gdb/config/s390/s390.mt | 5 + contrib/gdb/gdb/config/sparc/fbsd.mh | 24 +- contrib/gdb/gdb/config/sparc/fbsd.mt | 22 +- contrib/gdb/gdb/config/sparc/nbsd.mt | 5 +- contrib/gdb/gdb/config/sparc/nbsd64.mh | 4 + contrib/gdb/gdb/config/sparc/nbsd64.mt | 5 + contrib/gdb/gdb/config/sparc/nbsdaout.mh | 4 + contrib/gdb/gdb/config/sparc/nbsdelf.mh | 9 +- contrib/gdb/gdb/config/sparc/nm-fbsd.h | 36 +- contrib/gdb/gdb/config/sparc/nm-nbsd.h | 51 +- contrib/gdb/gdb/config/sparc/nm-nbsdaout.h | 30 + contrib/gdb/gdb/config/sparc/nm-sol2.h | 65 + contrib/gdb/gdb/config/sparc/obsd.mt | 4 + contrib/gdb/gdb/config/sparc/obsd64.mt | 5 + contrib/gdb/gdb/config/sparc/sol2-64.mt | 3 + contrib/gdb/gdb/config/sparc/sol2.mh | 6 + contrib/gdb/gdb/config/sparc/sol2.mt | 3 + contrib/gdb/gdb/config/sparc/sparc.mt | 2 + contrib/gdb/gdb/config/sparc/sparc64.mt | 2 + contrib/gdb/gdb/config/sparc/tm-fbsd.h | 15 +- contrib/gdb/gdb/config/sparc/tm-nbsd.h | 12 +- contrib/gdb/gdb/config/sparc/tm-nbsd64.h | 27 + contrib/gdb/gdb/config/sparc/tm-sol2.h | 40 + contrib/gdb/gdb/config/sparc/tm-vxworks.h | 31 + contrib/gdb/gdb/config/sparc/vxworks.mt | 4 + contrib/gdb/gdb/config/tm-lynx.h | 32 + contrib/gdb/gdb/config/tm-nto.h | 61 + contrib/gdb/gdb/config/tm-sunos.h | 32 + contrib/gdb/gdb/config/tm-sysv4.h | 37 + contrib/gdb/gdb/config/xm-nbsd.h | 26 + contrib/gdb/gdb/config/xm-sysv4.h | 29 + contrib/gdb/gdb/core-regset.c | 109 +- contrib/gdb/gdb/corefile.c | 64 +- contrib/gdb/gdb/corelow.c | 146 +- contrib/gdb/gdb/cp-abi.c | 175 +- contrib/gdb/gdb/cp-abi.h | 9 +- contrib/gdb/gdb/cp-namespace.c | 871 ++ contrib/gdb/gdb/cp-support.c | 757 ++ contrib/gdb/gdb/cp-support.h | 120 + contrib/gdb/gdb/cp-valprint.c | 79 +- contrib/gdb/gdb/cpu32bug-rom.c | 180 + contrib/gdb/gdb/dbug-rom.c | 35 +- contrib/gdb/gdb/dbxread.c | 636 +- contrib/gdb/gdb/dcache.c | 17 +- contrib/gdb/gdb/defs.h | 505 +- contrib/gdb/gdb/delta68-nat.c | 90 + contrib/gdb/gdb/demangle.c | 37 +- contrib/gdb/gdb/dictionary.c | 836 ++ contrib/gdb/gdb/dictionary.h | 156 + contrib/gdb/gdb/dink32-rom.c | 18 +- contrib/gdb/gdb/disasm.c | 395 + contrib/gdb/gdb/disasm.h | 38 + contrib/gdb/gdb/doc/GDBvn.texi | 2 +- contrib/gdb/gdb/doc/agentexpr.texi | 22 +- contrib/gdb/gdb/doc/all-cfg.texi | 8 +- contrib/gdb/gdb/doc/annotate.texinfo | 834 ++ contrib/gdb/gdb/doc/fdl.texi | 374 +- contrib/gdb/gdb/doc/gdb.info-1 | 7636 ++++++++++++ contrib/gdb/gdb/doc/gdb.info-2 | 9133 ++++++++++++++ contrib/gdb/gdb/doc/gdb.info-3 | 6665 ++++++++++ contrib/gdb/gdb/doc/gdb.texinfo | 10922 +++++++++++++---- contrib/gdb/gdb/doc/gdbint.texinfo | 2816 +++-- contrib/gdb/gdb/doc/observer.texi | 70 + contrib/gdb/gdb/doc/stabs.texinfo | 155 +- contrib/gdb/gdb/doublest.c | 64 +- contrib/gdb/gdb/doublest.h | 23 +- contrib/gdb/gdb/dpx2-nat.c | 83 + contrib/gdb/gdb/dsrec.c | 16 +- contrib/gdb/gdb/dummy-frame.c | 466 + contrib/gdb/gdb/dummy-frame.h | 86 + contrib/gdb/gdb/dve3900-rom.c | 1069 ++ contrib/gdb/gdb/dwarf2-frame.c | 1621 +++ contrib/gdb/gdb/dwarf2-frame.h | 98 + contrib/gdb/gdb/dwarf2expr.c | 670 + contrib/gdb/gdb/dwarf2expr.h | 96 + contrib/gdb/gdb/dwarf2loc.c | 548 + contrib/gdb/gdb/dwarf2loc.h | 70 + contrib/gdb/gdb/dwarf2read.c | 4860 +++++--- contrib/gdb/gdb/dwarfread.c | 454 +- contrib/gdb/gdb/elfread.c | 249 +- contrib/gdb/gdb/environ.c | 45 +- contrib/gdb/gdb/eval.c | 412 +- contrib/gdb/gdb/event-loop.c | 101 +- contrib/gdb/gdb/event-loop.h | 1 + contrib/gdb/gdb/event-top.c | 104 +- contrib/gdb/gdb/event-top.h | 17 +- contrib/gdb/gdb/exec.c | 144 +- contrib/gdb/gdb/exec.h | 39 + contrib/gdb/gdb/expprint.c | 212 +- contrib/gdb/gdb/expression.h | 84 +- contrib/gdb/gdb/f-exp.c | 2564 ++++ contrib/gdb/gdb/f-exp.y | 47 +- contrib/gdb/gdb/f-lang.c | 65 +- contrib/gdb/gdb/f-typeprint.c | 18 +- contrib/gdb/gdb/f-valprint.c | 135 +- contrib/gdb/gdb/fbsd-proc.c | 166 + contrib/gdb/gdb/findvar.c | 432 +- contrib/gdb/gdb/fork-child.c | 160 +- contrib/gdb/gdb/frame-base.c | 150 + contrib/gdb/gdb/frame-base.h | 93 + contrib/gdb/gdb/frame-unwind.c | 99 + contrib/gdb/gdb/frame-unwind.h | 141 + contrib/gdb/gdb/frame.c | 2426 +++- contrib/gdb/gdb/frame.h | 765 +- contrib/gdb/gdb/gcore.c | 432 +- contrib/gdb/gdb/gdb-events.c | 99 +- contrib/gdb/gdb/gdb-events.h | 20 +- contrib/gdb/gdb/gdb-events.sh | 31 +- contrib/gdb/gdb/gdb-stabs.h | 9 +- contrib/gdb/gdb/gdb.1 | 8 +- contrib/gdb/gdb/gdb.c | 36 + contrib/gdb/gdb/gdb.h | 2 + contrib/gdb/gdb/gdb_assert.h | 11 +- contrib/gdb/gdb/gdb_curses.h | 31 + contrib/gdb/gdb/gdb_dirent.h | 18 +- contrib/gdb/gdb/gdb_gcore.sh | 81 + contrib/gdb/gdb/gdb_indent.sh | 36 +- contrib/gdb/gdb/gdb_locale.h | 46 + contrib/gdb/gdb/gdb_mbuild.sh | 333 + contrib/gdb/gdb/gdb_obstack.h | 39 + contrib/gdb/gdb/gdb_regex.h | 14 +- contrib/gdb/gdb/gdb_thread_db.h | 13 +- contrib/gdb/gdb/gdbarch.c | 6056 +++++---- contrib/gdb/gdb/gdbarch.h | 2948 +++-- contrib/gdb/gdb/gdbarch.sh | 1248 +- contrib/gdb/gdb/gdbcore.h | 8 + contrib/gdb/gdb/gdbinit.in | 5 +- contrib/gdb/gdb/gdbserver/acinclude.m4 | 41 + contrib/gdb/gdb/gdbserver/aclocal.m4 | 124 +- contrib/gdb/gdb/gdbserver/gdbreplay.c | 13 +- contrib/gdb/gdb/gdbserver/i387-fp.c | 6 +- contrib/gdb/gdb/gdbserver/i387-fp.h | 4 +- contrib/gdb/gdb/gdbserver/inferiors.c | 199 + contrib/gdb/gdb/gdbserver/mem-break.c | 278 + contrib/gdb/gdb/gdbserver/mem-break.h | 71 + contrib/gdb/gdb/gdbserver/proc-service.c | 256 + contrib/gdb/gdb/gdbserver/regcache.c | 118 +- contrib/gdb/gdb/gdbserver/regcache.h | 27 +- contrib/gdb/gdb/gdbserver/remote-utils.c | 225 +- contrib/gdb/gdb/gdbserver/server.c | 339 +- contrib/gdb/gdb/gdbserver/server.h | 107 +- contrib/gdb/gdb/gdbserver/target.c | 112 + contrib/gdb/gdb/gdbserver/target.h | 171 + contrib/gdb/gdb/gdbserver/thread-db.c | 342 + contrib/gdb/gdb/gdbserver/utils.c | 13 +- contrib/gdb/gdb/gdbthread.h | 19 +- contrib/gdb/gdb/gdbtypes.c | 1284 +- contrib/gdb/gdb/gdbtypes.h | 611 +- contrib/gdb/gdb/glibc-tdep.c | 101 + contrib/gdb/gdb/glibc-tdep.h | 30 + contrib/gdb/gdb/gnu-nat.c | 3409 +++++ contrib/gdb/gdb/gnu-nat.h | 101 + contrib/gdb/gdb/gnu-v2-abi.c | 52 +- contrib/gdb/gdb/gnu-v3-abi.c | 91 +- contrib/gdb/gdb/go32-nat.c | 1963 +++ contrib/gdb/gdb/gregset.h | 13 + contrib/gdb/gdb/hpacc-abi.c | 3 +- contrib/gdb/gdb/hpread.c | 6327 ++++++++++ contrib/gdb/gdb/i386-nat.c | 221 +- contrib/gdb/gdb/i386-nto-tdep.c | 306 + contrib/gdb/gdb/i386-sol2-tdep.c | 120 + contrib/gdb/gdb/i386-stub.c | 952 ++ contrib/gdb/gdb/i386-tdep.c | 2429 ++-- contrib/gdb/gdb/i386-tdep.h | 161 +- contrib/gdb/gdb/i386bsd-nat.c | 102 +- contrib/gdb/gdb/i386bsd-tdep.c | 170 +- contrib/gdb/gdb/i386fbsd-nat.c | 19 +- contrib/gdb/gdb/i386fbsd-tdep.c | 175 + contrib/gdb/gdb/i386gnu-nat.c | 293 + contrib/gdb/gdb/i386gnu-tdep.c | 44 + contrib/gdb/gdb/i386ly-tdep.c | 81 + contrib/gdb/gdb/i386nbsd-tdep.c | 272 +- contrib/gdb/gdb/i386obsd-nat.c | 60 + contrib/gdb/gdb/i386obsd-tdep.c | 277 + contrib/gdb/gdb/i386v-nat.c | 277 + contrib/gdb/gdb/i386v4-nat.c | 160 + contrib/gdb/gdb/i387-tdep.c | 834 +- contrib/gdb/gdb/i387-tdep.h | 118 + contrib/gdb/gdb/ia64-tdep.c | 2760 +++-- contrib/gdb/gdb/ia64-tdep.h | 31 + contrib/gdb/gdb/infcall.c | 1103 ++ contrib/gdb/gdb/infcall.h | 43 + contrib/gdb/gdb/infcmd.c | 805 +- contrib/gdb/gdb/inferior.h | 245 +- contrib/gdb/gdb/inflow.c | 53 +- contrib/gdb/gdb/inflow.h | 51 + contrib/gdb/gdb/infptrace.c | 56 +- contrib/gdb/gdb/infrun.c | 4086 +++--- contrib/gdb/gdb/inftarg.c | 338 +- contrib/gdb/gdb/infttrace.c | 253 +- contrib/gdb/gdb/infttrace.h | 28 + contrib/gdb/gdb/interps.c | 486 + contrib/gdb/gdb/interps.h | 76 + contrib/gdb/gdb/jv-exp.c | 2842 +++++ contrib/gdb/gdb/jv-exp.y | 122 +- contrib/gdb/gdb/jv-lang.c | 137 +- contrib/gdb/gdb/jv-typeprint.c | 10 +- contrib/gdb/gdb/jv-valprint.c | 46 +- contrib/gdb/gdb/kod.c | 28 +- contrib/gdb/gdb/language.c | 415 +- contrib/gdb/gdb/language.h | 84 +- contrib/gdb/gdb/libunwind-frame.c | 387 + contrib/gdb/gdb/libunwind-frame.h | 64 + contrib/gdb/gdb/lin-lwp.c | 929 +- contrib/gdb/gdb/linespec.c | 2053 ++-- contrib/gdb/gdb/linespec.h | 4 +- contrib/gdb/gdb/lynx-nat.c | 624 + contrib/gdb/gdb/m2-exp.c | 2600 ++++ contrib/gdb/gdb/m2-exp.y | 60 +- contrib/gdb/gdb/m2-lang.c | 17 +- contrib/gdb/gdb/macrocmd.c | 289 + contrib/gdb/gdb/macroexp.c | 1169 ++ contrib/gdb/gdb/macroexp.h | 90 + contrib/gdb/gdb/macroscope.c | 132 + contrib/gdb/gdb/macroscope.h | 63 + contrib/gdb/gdb/macrotab.c | 892 ++ contrib/gdb/gdb/macrotab.h | 304 + contrib/gdb/gdb/main.c | 311 +- contrib/gdb/gdb/main.h | 35 + contrib/gdb/gdb/maint.c | 148 +- contrib/gdb/gdb/mdebugread.c | 788 +- contrib/gdb/gdb/mem-break.c | 57 +- contrib/gdb/gdb/memattr.c | 38 +- contrib/gdb/gdb/mi/mi-cmd-break.c | 5 - contrib/gdb/gdb/mi/mi-cmd-disas.c | 368 +- contrib/gdb/gdb/mi/mi-cmd-env.c | 259 + contrib/gdb/gdb/mi/mi-cmd-file.c | 67 + contrib/gdb/gdb/mi/mi-cmd-stack.c | 106 +- contrib/gdb/gdb/mi/mi-cmd-var.c | 87 +- contrib/gdb/gdb/mi/mi-cmds.c | 266 +- contrib/gdb/gdb/mi/mi-cmds.h | 53 +- contrib/gdb/gdb/mi/mi-console.c | 27 +- contrib/gdb/gdb/mi/mi-console.h | 4 +- contrib/gdb/gdb/mi/mi-getopt.c | 16 + contrib/gdb/gdb/mi/mi-getopt.h | 20 + contrib/gdb/gdb/mi/mi-interp.c | 406 + contrib/gdb/gdb/mi/mi-main.c | 435 +- contrib/gdb/gdb/mi/mi-main.h | 33 + contrib/gdb/gdb/mi/mi-out.c | 115 +- contrib/gdb/gdb/mi/mi-out.h | 3 + contrib/gdb/gdb/mi/mi-parse.c | 14 +- contrib/gdb/gdb/mi/mi-symbol-cmds.c | 67 + contrib/gdb/gdb/minimon.h | 601 + contrib/gdb/gdb/minsyms.c | 273 +- contrib/gdb/gdb/mips-nat.c | 254 + contrib/gdb/gdb/mips-tdep.c | 6190 ++++++++++ contrib/gdb/gdb/mips-tdep.h | 77 + contrib/gdb/gdb/mipsnbsd-nat.c | 101 + contrib/gdb/gdb/mipsnbsd-tdep.c | 370 + contrib/gdb/gdb/mipsnbsd-tdep.h | 33 + contrib/gdb/gdb/mipsread.c | 21 +- contrib/gdb/gdb/mipsv4-nat.c | 168 + contrib/gdb/gdb/monitor.c | 2310 ++++ contrib/gdb/gdb/monitor.h | 260 + contrib/gdb/gdb/nbsd-tdep.c | 109 + contrib/gdb/gdb/nbsd-tdep.h | 30 + contrib/gdb/gdb/nlmread.c | 16 +- contrib/gdb/gdb/nto-procfs.c | 1389 +++ contrib/gdb/gdb/nto-tdep.c | 337 + contrib/gdb/gdb/nto-tdep.h | 156 + contrib/gdb/gdb/objc-exp.c | 3464 ++++++ contrib/gdb/gdb/objc-exp.y | 1820 +++ contrib/gdb/gdb/objc-lang.c | 1929 +++ contrib/gdb/gdb/objc-lang.h | 68 + contrib/gdb/gdb/objfiles.c | 622 +- contrib/gdb/gdb/objfiles.h | 176 +- contrib/gdb/gdb/observer.c | 222 + contrib/gdb/gdb/observer.h | 35 + contrib/gdb/gdb/ocd.c | 235 +- contrib/gdb/gdb/ocd.h | 3 + contrib/gdb/gdb/osabi.c | 630 + contrib/gdb/gdb/osabi.h | 55 + contrib/gdb/gdb/p-exp.c | 2974 +++++ contrib/gdb/gdb/p-exp.y | 299 +- contrib/gdb/gdb/p-lang.c | 58 +- contrib/gdb/gdb/p-lang.h | 3 +- contrib/gdb/gdb/p-typeprint.c | 32 +- contrib/gdb/gdb/p-valprint.c | 65 +- contrib/gdb/gdb/pa64solib.c | 1247 ++ contrib/gdb/gdb/pa64solib.h | 149 + contrib/gdb/gdb/parse.c | 377 +- contrib/gdb/gdb/parser-defs.h | 91 +- contrib/gdb/gdb/ppc-bdm.c | 43 +- contrib/gdb/gdb/ppc-sysv-tdep.c | 1002 ++ contrib/gdb/gdb/ppc-tdep.h | 52 +- contrib/gdb/gdb/ppcbug-rom.c | 225 + contrib/gdb/gdb/ppcnbsd-nat.c | 182 +- contrib/gdb/gdb/ppcnbsd-tdep.c | 250 + contrib/gdb/gdb/ppcnbsd-tdep.h | 30 + contrib/gdb/gdb/printcmd.c | 640 +- contrib/gdb/gdb/proc-api.c | 38 +- contrib/gdb/gdb/proc-utils.h | 43 +- contrib/gdb/gdb/procfs.c | 5960 +++++++++ contrib/gdb/gdb/regcache.c | 1547 ++- contrib/gdb/gdb/regcache.h | 227 +- contrib/gdb/gdb/regformats/reg-m68k.dat | 33 + contrib/gdb/gdb/regformats/reg-ppc.dat | 2 +- contrib/gdb/gdb/regformats/reg-s390.dat | 53 + contrib/gdb/gdb/regformats/reg-s390x.dat | 53 + contrib/gdb/gdb/regformats/reg-x86-64.dat | 10 +- contrib/gdb/gdb/reggroups.c | 288 + contrib/gdb/gdb/reggroups.h | 64 + contrib/gdb/gdb/regset.h | 41 + contrib/gdb/gdb/remote-e7000.c | 2194 ++++ contrib/gdb/gdb/remote-est.c | 186 + contrib/gdb/gdb/remote-fileio.c | 1384 +++ contrib/gdb/gdb/remote-fileio.h | 38 + contrib/gdb/gdb/remote-hms.c | 159 + contrib/gdb/gdb/remote-mips.c | 3421 ++++++ contrib/gdb/gdb/remote-rdi.c | 237 +- contrib/gdb/gdb/remote-rdp.c | 1431 +++ contrib/gdb/gdb/remote-sds.c | 1130 ++ contrib/gdb/gdb/remote-sim.c | 900 ++ contrib/gdb/gdb/remote-st.c | 803 ++ contrib/gdb/gdb/remote-utils.c | 2 +- contrib/gdb/gdb/remote-utils.h | 2 + contrib/gdb/gdb/remote-vx.c | 1409 +++ contrib/gdb/gdb/remote-vx68.c | 160 + contrib/gdb/gdb/remote-vxmips.c | 201 + contrib/gdb/gdb/remote-vxsparc.c | 128 + contrib/gdb/gdb/remote.c | 2094 ++-- contrib/gdb/gdb/remote.h | 7 + contrib/gdb/gdb/rom68k-rom.c | 264 + contrib/gdb/gdb/s390-nat.c | 359 + contrib/gdb/gdb/s390-tdep.c | 3102 +++++ contrib/gdb/gdb/s390-tdep.h | 105 + contrib/gdb/gdb/scm-exp.c | 5 +- contrib/gdb/gdb/scm-lang.c | 42 +- contrib/gdb/gdb/scm-lang.h | 6 +- contrib/gdb/gdb/sentinel-frame.c | 92 + contrib/gdb/gdb/sentinel-frame.h | 41 + contrib/gdb/gdb/ser-e7kpc.c | 436 + contrib/gdb/gdb/ser-go32.c | 964 ++ contrib/gdb/gdb/ser-pipe.c | 4 +- contrib/gdb/gdb/ser-tcp.c | 55 +- contrib/gdb/gdb/ser-unix.c | 9 +- contrib/gdb/gdb/ser-unix.h | 7 +- contrib/gdb/gdb/serial.c | 7 +- contrib/gdb/gdb/serial.h | 2 + contrib/gdb/gdb/signals/signals.c | 86 +- contrib/gdb/gdb/sim-regno.h | 45 + contrib/gdb/gdb/sol-thread.c | 160 +- contrib/gdb/gdb/solib-legacy.c | 3 +- contrib/gdb/gdb/solib-osf.c | 15 +- contrib/gdb/gdb/solib-sunos.c | 47 +- contrib/gdb/gdb/solib-svr4.c | 349 +- contrib/gdb/gdb/solib-svr4.h | 14 +- contrib/gdb/gdb/solib.c | 82 +- contrib/gdb/gdb/solib.h | 101 +- contrib/gdb/gdb/solist.h | 8 + contrib/gdb/gdb/somread.c | 736 ++ contrib/gdb/gdb/somsolib.c | 1624 +++ contrib/gdb/gdb/somsolib.h | 178 + contrib/gdb/gdb/source.c | 475 +- contrib/gdb/gdb/source.h | 34 + contrib/gdb/gdb/sparc-nat.c | 581 +- contrib/gdb/gdb/sparc-nat.h | 40 + contrib/gdb/gdb/sparc-sol2-nat.c | 98 + contrib/gdb/gdb/sparc-sol2-tdep.c | 201 + contrib/gdb/gdb/sparc-tdep.c | 4315 ++----- contrib/gdb/gdb/sparc-tdep.h | 204 + contrib/gdb/gdb/sparc64-nat.c | 87 + contrib/gdb/gdb/sparc64-sol2-tdep.c | 182 + contrib/gdb/gdb/sparc64-tdep.c | 1433 +++ contrib/gdb/gdb/sparc64-tdep.h | 123 + contrib/gdb/gdb/sparc64fbsd-nat.c | 34 + contrib/gdb/gdb/sparc64fbsd-tdep.c | 225 + contrib/gdb/gdb/sparc64nbsd-nat.c | 139 + contrib/gdb/gdb/sparc64nbsd-tdep.c | 256 + contrib/gdb/gdb/sparc64obsd-tdep.c | 210 + contrib/gdb/gdb/sparcnbsd-nat.c | 34 + contrib/gdb/gdb/sparcnbsd-tdep.c | 358 + contrib/gdb/gdb/sparcobsd-tdep.c | 171 + contrib/gdb/gdb/srec.h | 39 + contrib/gdb/gdb/stabsread.c | 2197 +--- contrib/gdb/gdb/stabsread.h | 39 +- contrib/gdb/gdb/stack.c | 1196 +- contrib/gdb/gdb/stack.h | 27 + contrib/gdb/gdb/standalone.c | 580 + contrib/gdb/gdb/std-regs.c | 160 + contrib/gdb/gdb/stop-gdb.c | 109 + contrib/gdb/gdb/sun3-nat.c | 166 + contrib/gdb/gdb/symfile.c | 1131 +- contrib/gdb/gdb/symfile.h | 296 +- contrib/gdb/gdb/symmisc.c | 335 +- contrib/gdb/gdb/symtab.c | 2247 ++-- contrib/gdb/gdb/symtab.h | 1559 ++- contrib/gdb/gdb/target.c | 1074 +- contrib/gdb/gdb/target.h | 523 +- contrib/gdb/gdb/thread-db.c | 612 +- contrib/gdb/gdb/thread.c | 109 +- contrib/gdb/gdb/top.c | 511 +- contrib/gdb/gdb/top.h | 12 +- contrib/gdb/gdb/tracepoint.c | 128 +- contrib/gdb/gdb/trad-frame.c | 134 + contrib/gdb/gdb/trad-frame.h | 88 + contrib/gdb/gdb/tui/tui-command.c | 131 + contrib/gdb/gdb/tui/tui-command.h | 30 + contrib/gdb/gdb/tui/tui-data.c | 924 ++ contrib/gdb/gdb/tui/tui-data.h | 351 + contrib/gdb/gdb/tui/tui-disasm.c | 397 + contrib/gdb/gdb/tui/tui-disasm.h | 37 + contrib/gdb/gdb/tui/tui-file.c | 238 + contrib/gdb/gdb/tui/tui-file.h | 29 + contrib/gdb/gdb/tui/tui-hooks.c | 320 + contrib/gdb/gdb/tui/tui-hooks.h | 28 + contrib/gdb/gdb/tui/tui-interp.c | 210 + contrib/gdb/gdb/tui/tui-io.c | 708 ++ contrib/gdb/gdb/tui/tui-io.h | 55 + contrib/gdb/gdb/tui/tui-layout.c | 1072 ++ contrib/gdb/gdb/tui/tui-layout.h | 38 + contrib/gdb/gdb/tui/tui-main.c | 37 + contrib/gdb/gdb/tui/tui-out.c | 413 + contrib/gdb/gdb/tui/tui-regs.c | 754 ++ contrib/gdb/gdb/tui/tui-regs.h | 39 + contrib/gdb/gdb/tui/tui-source.c | 352 + contrib/gdb/gdb/tui/tui-source.h | 40 + contrib/gdb/gdb/tui/tui-stack.c | 427 + contrib/gdb/gdb/tui/tui-stack.h | 34 + contrib/gdb/gdb/tui/tui-win.c | 1520 +++ contrib/gdb/gdb/tui/tui-win.h | 59 + contrib/gdb/gdb/tui/tui-windata.c | 304 + contrib/gdb/gdb/tui/tui-windata.h | 41 + contrib/gdb/gdb/tui/tui-wingeneral.c | 276 + contrib/gdb/gdb/tui/tui-wingeneral.h | 45 + contrib/gdb/gdb/tui/tui-winsource.c | 654 + contrib/gdb/gdb/tui/tui-winsource.h | 73 + contrib/gdb/gdb/tui/tui.c | 590 + contrib/gdb/gdb/tui/tui.h | 100 + contrib/gdb/gdb/typeprint.c | 45 +- contrib/gdb/gdb/typeprint.h | 2 + contrib/gdb/gdb/ui-file.c | 136 +- contrib/gdb/gdb/ui-file.h | 12 + contrib/gdb/gdb/ui-out.c | 114 +- contrib/gdb/gdb/ui-out.h | 31 +- contrib/gdb/gdb/user-regs.c | 211 + contrib/gdb/gdb/user-regs.h | 71 + contrib/gdb/gdb/utils.c | 1406 ++- contrib/gdb/gdb/uw-thread.c | 8 + contrib/gdb/gdb/valarith.c | 102 +- contrib/gdb/gdb/valops.c | 1892 ++- contrib/gdb/gdb/valprint.c | 198 +- contrib/gdb/gdb/valprint.h | 12 + contrib/gdb/gdb/value.h | 378 +- contrib/gdb/gdb/values.c | 361 +- contrib/gdb/gdb/varobj.c | 284 +- contrib/gdb/gdb/version.in | 2 +- contrib/gdb/gdb/win32-nat.c | 2460 ++++ contrib/gdb/gdb/wince-stub.c | 592 + contrib/gdb/gdb/wince-stub.h | 48 + contrib/gdb/gdb/wince.c | 2049 ++++ contrib/gdb/gdb/wrapper.h | 2 + contrib/gdb/gdb/xcoffread.c | 3033 +++++ contrib/gdb/gdb/xcoffsolib.c | 196 + contrib/gdb/gdb/xmodem.c | 275 + contrib/gdb/gdb/xmodem.h | 32 + contrib/gdb/gettext.m4 | 344 + contrib/gdb/include/COPYING | 340 + contrib/gdb/include/MAINTAINERS | 1 + contrib/gdb/include/alloca-conf.h | 24 + contrib/gdb/include/ansidecl.h | 315 + contrib/gdb/include/bfdlink.h | 686 ++ contrib/gdb/include/bin-bugs.h | 3 + contrib/gdb/include/bout.h | 191 + contrib/gdb/include/demangle.h | 533 + contrib/gdb/include/dis-asm.h | 317 + contrib/gdb/include/dyn-string.h | 63 + contrib/gdb/include/fibheap.h | 86 + contrib/gdb/include/filenames.h | 51 + contrib/gdb/include/floatformat.h | 133 + contrib/gdb/include/fnmatch.h | 70 + contrib/gdb/include/fopen-bin.h | 27 + contrib/gdb/include/fopen-same.h | 27 + contrib/gdb/include/fopen-vms.h | 24 + contrib/gdb/include/gdb/callback.h | 272 + contrib/gdb/include/gdb/fileio.h | 146 + contrib/gdb/include/gdb/remote-sim.h | 282 + contrib/gdb/include/gdb/signals.h | 24 +- contrib/gdb/include/gdb/sim-arm.h | 114 + contrib/gdb/include/gdb/sim-d10v.h | 142 + contrib/gdb/include/gdb/sim-frv.h | 53 + contrib/gdb/include/gdb/sim-h8300.h | 78 + contrib/gdb/include/gdb/sim-sh.h | 161 + contrib/gdb/include/gdbm.h | 91 + contrib/gdb/include/getopt.h | 144 + contrib/gdb/include/hashtab.h | 195 + contrib/gdb/include/hp-symtab.h | 1866 +++ contrib/gdb/include/ieee.h | 165 + contrib/gdb/include/libiberty.h | 335 + contrib/gdb/include/md5.h | 142 + contrib/gdb/include/oasys.h | 192 + contrib/gdb/include/objalloc.h | 115 + contrib/gdb/include/obstack.h | 611 + contrib/gdb/include/os9k.h | 181 + contrib/gdb/include/partition.h | 85 + contrib/gdb/include/progress.h | 37 + contrib/gdb/include/safe-ctype.h | 119 + contrib/gdb/include/sort.h | 48 + contrib/gdb/include/splay-tree.h | 159 + contrib/gdb/include/symcat.h | 49 + contrib/gdb/include/ternary.h | 51 + contrib/gdb/include/xregex.h | 28 + contrib/gdb/include/xregex2.h | 571 + contrib/gdb/include/xtensa-isa-internal.h | 114 + contrib/gdb/include/xtensa-isa.h | 230 + contrib/gdb/install-sh | 316 + contrib/gdb/libtool.m4 | 893 ++ contrib/gdb/ltcf-c.sh | 824 ++ contrib/gdb/ltcf-cxx.sh | 1021 ++ contrib/gdb/ltcf-gcj.sh | 651 + contrib/gdb/ltconfig | 2833 +++++ contrib/gdb/ltmain.sh | 5469 +++++++++ contrib/gdb/md5.sum | 5330 ++++++++ contrib/gdb/missing | 336 + contrib/gdb/mkinstalldirs | 150 + contrib/gdb/move-if-change | 32 + contrib/gdb/src-release | 336 + contrib/gdb/symlink-tree | 78 + contrib/gdb/ylwrap | 123 + 725 files changed, 266375 insertions(+), 45247 deletions(-) create mode 100644 contrib/gdb/djunpack.bat create mode 100644 contrib/gdb/gdb/abug-rom.c create mode 100644 contrib/gdb/gdb/ada-exp.c create mode 100644 contrib/gdb/gdb/ada-exp.y create mode 100644 contrib/gdb/gdb/ada-lang.c create mode 100644 contrib/gdb/gdb/ada-lang.h create mode 100644 contrib/gdb/gdb/ada-lex.l create mode 100644 contrib/gdb/gdb/ada-tasks.c create mode 100644 contrib/gdb/gdb/ada-typeprint.c create mode 100644 contrib/gdb/gdb/ada-valprint.c create mode 100644 contrib/gdb/gdb/alpha-mdebug-tdep.c create mode 100644 contrib/gdb/gdb/alpha-nat.c create mode 100644 contrib/gdb/gdb/alpha-tdep.h create mode 100644 contrib/gdb/gdb/alphabsd-tdep.c create mode 100644 contrib/gdb/gdb/alphabsd-tdep.h create mode 100644 contrib/gdb/gdb/alphanbsd-tdep.c create mode 100644 contrib/gdb/gdb/amd64-nat.c create mode 100644 contrib/gdb/gdb/amd64-nat.h create mode 100644 contrib/gdb/gdb/amd64-tdep.c create mode 100644 contrib/gdb/gdb/amd64-tdep.h create mode 100644 contrib/gdb/gdb/amd64bsd-nat.c create mode 100644 contrib/gdb/gdb/amd64fbsd-nat.c create mode 100644 contrib/gdb/gdb/amd64fbsd-tdep.c create mode 100644 contrib/gdb/gdb/amd64nbsd-nat.c create mode 100644 contrib/gdb/gdb/amd64nbsd-tdep.c create mode 100644 contrib/gdb/gdb/amd64obsd-nat.c create mode 100644 contrib/gdb/gdb/amd64obsd-tdep.c create mode 100644 contrib/gdb/gdb/arm-tdep.c create mode 100644 contrib/gdb/gdb/auxv.c create mode 100644 contrib/gdb/gdb/auxv.h create mode 100644 contrib/gdb/gdb/bfd-target.c create mode 100644 contrib/gdb/gdb/bfd-target.h create mode 100644 contrib/gdb/gdb/block.c create mode 100644 contrib/gdb/gdb/block.h create mode 100644 contrib/gdb/gdb/c-exp.c create mode 100644 contrib/gdb/gdb/charset.c create mode 100644 contrib/gdb/gdb/charset.h create mode 100644 contrib/gdb/gdb/cli/cli-dump.c create mode 100644 contrib/gdb/gdb/cli/cli-dump.h create mode 100644 contrib/gdb/gdb/cli/cli-interp.c create mode 100644 contrib/gdb/gdb/cli/cli-logging.c create mode 100644 contrib/gdb/gdb/coff-pe-read.c create mode 100644 contrib/gdb/gdb/coff-pe-read.h create mode 100644 contrib/gdb/gdb/coff-solib.c create mode 100644 contrib/gdb/gdb/coff-solib.h create mode 100644 contrib/gdb/gdb/config/alpha/alpha.mt create mode 100644 contrib/gdb/gdb/config/alpha/nbsd.mh create mode 100644 contrib/gdb/gdb/config/alpha/nbsd.mt create mode 100644 contrib/gdb/gdb/config/alpha/nm-nbsd.h create mode 100644 contrib/gdb/gdb/config/alpha/tm-nbsd.h create mode 100644 contrib/gdb/gdb/config/arm/nbsdaout.mh create mode 100644 contrib/gdb/gdb/config/arm/nbsdelf.mh create mode 100644 contrib/gdb/gdb/config/arm/nm-nbsdaout.h create mode 100644 contrib/gdb/gdb/config/arm/tm-nbsd.h create mode 100644 contrib/gdb/gdb/config/i386/fbsd64.mh create mode 100644 contrib/gdb/gdb/config/i386/fbsd64.mt create mode 100644 contrib/gdb/gdb/config/i386/nbsd64.mh create mode 100644 contrib/gdb/gdb/config/i386/nbsd64.mt create mode 100644 contrib/gdb/gdb/config/i386/nbsdaout.mh create mode 100644 contrib/gdb/gdb/config/i386/nm-fbsd64.h create mode 100644 contrib/gdb/gdb/config/i386/nm-i386gnu.h create mode 100644 contrib/gdb/gdb/config/i386/nm-nbsdaout.h create mode 100755 contrib/gdb/gdb/config/i386/nm-nto.h create mode 100755 contrib/gdb/gdb/config/i386/nto.mh create mode 100755 contrib/gdb/gdb/config/i386/nto.mt create mode 100644 contrib/gdb/gdb/config/i386/obsd64.mh create mode 100644 contrib/gdb/gdb/config/i386/obsd64.mt create mode 100644 contrib/gdb/gdb/config/i386/obsdaout.mh create mode 100755 contrib/gdb/gdb/config/i386/tm-nto.h create mode 100644 contrib/gdb/gdb/config/ia64/ia64.mt create mode 100644 contrib/gdb/gdb/config/mips/decstation.mh create mode 100644 contrib/gdb/gdb/config/mips/embed.mt create mode 100644 contrib/gdb/gdb/config/mips/littlemips.mh create mode 100644 contrib/gdb/gdb/config/mips/mipsv4.mh create mode 100644 contrib/gdb/gdb/config/mips/mipsv4.mt create mode 100644 contrib/gdb/gdb/config/mips/nbsd.mh create mode 100644 contrib/gdb/gdb/config/mips/nbsd.mt create mode 100644 contrib/gdb/gdb/config/mips/news-mips.mh create mode 100644 contrib/gdb/gdb/config/mips/nm-mips.h create mode 100644 contrib/gdb/gdb/config/mips/nm-nbsd.h create mode 100644 contrib/gdb/gdb/config/mips/nm-news-mips.h create mode 100644 contrib/gdb/gdb/config/mips/nm-riscos.h create mode 100644 contrib/gdb/gdb/config/mips/riscos.mh create mode 100644 contrib/gdb/gdb/config/mips/tm-mips.h create mode 100644 contrib/gdb/gdb/config/mips/tm-mipsv4.h create mode 100644 contrib/gdb/gdb/config/mips/tm-nbsd.h create mode 100644 contrib/gdb/gdb/config/mips/tm-vxmips.h create mode 100644 contrib/gdb/gdb/config/mips/tm-wince.h create mode 100644 contrib/gdb/gdb/config/mips/vxmips.mt create mode 100644 contrib/gdb/gdb/config/mips/wince.mt create mode 100644 contrib/gdb/gdb/config/mips/xm-mips.h create mode 100644 contrib/gdb/gdb/config/mips/xm-mipsv4.h create mode 100644 contrib/gdb/gdb/config/mips/xm-riscos.h create mode 100644 contrib/gdb/gdb/config/nm-gnu.h create mode 100644 contrib/gdb/gdb/config/nm-lynx.h create mode 100644 contrib/gdb/gdb/config/nm-nbsd.h create mode 100644 contrib/gdb/gdb/config/nm-nbsdaout.h create mode 100644 contrib/gdb/gdb/config/nm-sysv4.h create mode 100644 contrib/gdb/gdb/config/s390/s390.mh create mode 100644 contrib/gdb/gdb/config/s390/s390.mt create mode 100644 contrib/gdb/gdb/config/sparc/nbsd64.mh create mode 100644 contrib/gdb/gdb/config/sparc/nbsd64.mt create mode 100644 contrib/gdb/gdb/config/sparc/nbsdaout.mh create mode 100644 contrib/gdb/gdb/config/sparc/nm-nbsdaout.h create mode 100644 contrib/gdb/gdb/config/sparc/nm-sol2.h create mode 100644 contrib/gdb/gdb/config/sparc/obsd.mt create mode 100644 contrib/gdb/gdb/config/sparc/obsd64.mt create mode 100644 contrib/gdb/gdb/config/sparc/sol2-64.mt create mode 100644 contrib/gdb/gdb/config/sparc/sol2.mh create mode 100644 contrib/gdb/gdb/config/sparc/sol2.mt create mode 100644 contrib/gdb/gdb/config/sparc/sparc.mt create mode 100644 contrib/gdb/gdb/config/sparc/sparc64.mt create mode 100644 contrib/gdb/gdb/config/sparc/tm-nbsd64.h create mode 100644 contrib/gdb/gdb/config/sparc/tm-sol2.h create mode 100644 contrib/gdb/gdb/config/sparc/tm-vxworks.h create mode 100644 contrib/gdb/gdb/config/sparc/vxworks.mt create mode 100644 contrib/gdb/gdb/config/tm-lynx.h create mode 100755 contrib/gdb/gdb/config/tm-nto.h create mode 100644 contrib/gdb/gdb/config/tm-sunos.h create mode 100644 contrib/gdb/gdb/config/tm-sysv4.h create mode 100644 contrib/gdb/gdb/config/xm-nbsd.h create mode 100644 contrib/gdb/gdb/config/xm-sysv4.h create mode 100644 contrib/gdb/gdb/cp-namespace.c create mode 100644 contrib/gdb/gdb/cp-support.c create mode 100644 contrib/gdb/gdb/cp-support.h create mode 100644 contrib/gdb/gdb/cpu32bug-rom.c create mode 100644 contrib/gdb/gdb/delta68-nat.c create mode 100644 contrib/gdb/gdb/dictionary.c create mode 100644 contrib/gdb/gdb/dictionary.h create mode 100644 contrib/gdb/gdb/disasm.c create mode 100644 contrib/gdb/gdb/disasm.h create mode 100644 contrib/gdb/gdb/doc/annotate.texinfo create mode 100644 contrib/gdb/gdb/doc/gdb.info-1 create mode 100644 contrib/gdb/gdb/doc/gdb.info-2 create mode 100644 contrib/gdb/gdb/doc/gdb.info-3 create mode 100644 contrib/gdb/gdb/doc/observer.texi create mode 100644 contrib/gdb/gdb/dpx2-nat.c create mode 100644 contrib/gdb/gdb/dummy-frame.c create mode 100644 contrib/gdb/gdb/dummy-frame.h create mode 100644 contrib/gdb/gdb/dve3900-rom.c create mode 100644 contrib/gdb/gdb/dwarf2-frame.c create mode 100644 contrib/gdb/gdb/dwarf2-frame.h create mode 100644 contrib/gdb/gdb/dwarf2expr.c create mode 100644 contrib/gdb/gdb/dwarf2expr.h create mode 100644 contrib/gdb/gdb/dwarf2loc.c create mode 100644 contrib/gdb/gdb/dwarf2loc.h create mode 100644 contrib/gdb/gdb/exec.h create mode 100644 contrib/gdb/gdb/f-exp.c create mode 100644 contrib/gdb/gdb/fbsd-proc.c create mode 100644 contrib/gdb/gdb/frame-base.c create mode 100644 contrib/gdb/gdb/frame-base.h create mode 100644 contrib/gdb/gdb/frame-unwind.c create mode 100644 contrib/gdb/gdb/frame-unwind.h create mode 100644 contrib/gdb/gdb/gdb.c create mode 100644 contrib/gdb/gdb/gdb_curses.h create mode 100755 contrib/gdb/gdb/gdb_gcore.sh create mode 100644 contrib/gdb/gdb/gdb_locale.h create mode 100755 contrib/gdb/gdb/gdb_mbuild.sh create mode 100644 contrib/gdb/gdb/gdb_obstack.h create mode 100644 contrib/gdb/gdb/gdbserver/acinclude.m4 create mode 100644 contrib/gdb/gdb/gdbserver/inferiors.c create mode 100644 contrib/gdb/gdb/gdbserver/mem-break.c create mode 100644 contrib/gdb/gdb/gdbserver/mem-break.h create mode 100644 contrib/gdb/gdb/gdbserver/proc-service.c create mode 100644 contrib/gdb/gdb/gdbserver/target.c create mode 100644 contrib/gdb/gdb/gdbserver/target.h create mode 100644 contrib/gdb/gdb/gdbserver/thread-db.c create mode 100644 contrib/gdb/gdb/glibc-tdep.c create mode 100644 contrib/gdb/gdb/glibc-tdep.h create mode 100644 contrib/gdb/gdb/gnu-nat.c create mode 100644 contrib/gdb/gdb/gnu-nat.h create mode 100644 contrib/gdb/gdb/go32-nat.c create mode 100644 contrib/gdb/gdb/hpread.c create mode 100755 contrib/gdb/gdb/i386-nto-tdep.c create mode 100644 contrib/gdb/gdb/i386-sol2-tdep.c create mode 100644 contrib/gdb/gdb/i386-stub.c create mode 100644 contrib/gdb/gdb/i386fbsd-tdep.c create mode 100644 contrib/gdb/gdb/i386gnu-nat.c create mode 100644 contrib/gdb/gdb/i386gnu-tdep.c create mode 100644 contrib/gdb/gdb/i386ly-tdep.c create mode 100644 contrib/gdb/gdb/i386obsd-nat.c create mode 100644 contrib/gdb/gdb/i386obsd-tdep.c create mode 100644 contrib/gdb/gdb/i386v-nat.c create mode 100644 contrib/gdb/gdb/i386v4-nat.c create mode 100644 contrib/gdb/gdb/i387-tdep.h create mode 100644 contrib/gdb/gdb/ia64-tdep.h create mode 100644 contrib/gdb/gdb/infcall.c create mode 100644 contrib/gdb/gdb/infcall.h create mode 100644 contrib/gdb/gdb/inflow.h create mode 100644 contrib/gdb/gdb/infttrace.h create mode 100644 contrib/gdb/gdb/interps.c create mode 100644 contrib/gdb/gdb/interps.h create mode 100644 contrib/gdb/gdb/jv-exp.c create mode 100644 contrib/gdb/gdb/libunwind-frame.c create mode 100644 contrib/gdb/gdb/libunwind-frame.h create mode 100644 contrib/gdb/gdb/lynx-nat.c create mode 100644 contrib/gdb/gdb/m2-exp.c create mode 100644 contrib/gdb/gdb/macrocmd.c create mode 100644 contrib/gdb/gdb/macroexp.c create mode 100644 contrib/gdb/gdb/macroexp.h create mode 100644 contrib/gdb/gdb/macroscope.c create mode 100644 contrib/gdb/gdb/macroscope.h create mode 100644 contrib/gdb/gdb/macrotab.c create mode 100644 contrib/gdb/gdb/macrotab.h create mode 100644 contrib/gdb/gdb/main.h create mode 100644 contrib/gdb/gdb/mi/mi-cmd-env.c create mode 100644 contrib/gdb/gdb/mi/mi-cmd-file.c create mode 100644 contrib/gdb/gdb/mi/mi-interp.c create mode 100644 contrib/gdb/gdb/mi/mi-main.h create mode 100644 contrib/gdb/gdb/mi/mi-symbol-cmds.c create mode 100644 contrib/gdb/gdb/minimon.h create mode 100644 contrib/gdb/gdb/mips-nat.c create mode 100644 contrib/gdb/gdb/mips-tdep.c create mode 100644 contrib/gdb/gdb/mips-tdep.h create mode 100644 contrib/gdb/gdb/mipsnbsd-nat.c create mode 100644 contrib/gdb/gdb/mipsnbsd-tdep.c create mode 100644 contrib/gdb/gdb/mipsnbsd-tdep.h create mode 100644 contrib/gdb/gdb/mipsv4-nat.c create mode 100644 contrib/gdb/gdb/monitor.c create mode 100644 contrib/gdb/gdb/monitor.h create mode 100644 contrib/gdb/gdb/nbsd-tdep.c create mode 100644 contrib/gdb/gdb/nbsd-tdep.h create mode 100755 contrib/gdb/gdb/nto-procfs.c create mode 100755 contrib/gdb/gdb/nto-tdep.c create mode 100755 contrib/gdb/gdb/nto-tdep.h create mode 100644 contrib/gdb/gdb/objc-exp.c create mode 100644 contrib/gdb/gdb/objc-exp.y create mode 100644 contrib/gdb/gdb/objc-lang.c create mode 100644 contrib/gdb/gdb/objc-lang.h create mode 100644 contrib/gdb/gdb/observer.c create mode 100644 contrib/gdb/gdb/observer.h create mode 100644 contrib/gdb/gdb/osabi.c create mode 100644 contrib/gdb/gdb/osabi.h create mode 100644 contrib/gdb/gdb/p-exp.c create mode 100644 contrib/gdb/gdb/pa64solib.c create mode 100644 contrib/gdb/gdb/pa64solib.h create mode 100644 contrib/gdb/gdb/ppc-sysv-tdep.c create mode 100644 contrib/gdb/gdb/ppcbug-rom.c create mode 100644 contrib/gdb/gdb/ppcnbsd-tdep.c create mode 100644 contrib/gdb/gdb/ppcnbsd-tdep.h create mode 100644 contrib/gdb/gdb/procfs.c create mode 100644 contrib/gdb/gdb/regformats/reg-m68k.dat create mode 100644 contrib/gdb/gdb/regformats/reg-s390.dat create mode 100644 contrib/gdb/gdb/regformats/reg-s390x.dat create mode 100644 contrib/gdb/gdb/reggroups.c create mode 100644 contrib/gdb/gdb/reggroups.h create mode 100644 contrib/gdb/gdb/regset.h create mode 100644 contrib/gdb/gdb/remote-e7000.c create mode 100644 contrib/gdb/gdb/remote-est.c create mode 100644 contrib/gdb/gdb/remote-fileio.c create mode 100644 contrib/gdb/gdb/remote-fileio.h create mode 100644 contrib/gdb/gdb/remote-hms.c create mode 100644 contrib/gdb/gdb/remote-mips.c create mode 100644 contrib/gdb/gdb/remote-rdp.c create mode 100644 contrib/gdb/gdb/remote-sds.c create mode 100644 contrib/gdb/gdb/remote-sim.c create mode 100644 contrib/gdb/gdb/remote-st.c create mode 100644 contrib/gdb/gdb/remote-vx.c create mode 100644 contrib/gdb/gdb/remote-vx68.c create mode 100644 contrib/gdb/gdb/remote-vxmips.c create mode 100644 contrib/gdb/gdb/remote-vxsparc.c create mode 100644 contrib/gdb/gdb/rom68k-rom.c create mode 100644 contrib/gdb/gdb/s390-nat.c create mode 100644 contrib/gdb/gdb/s390-tdep.c create mode 100644 contrib/gdb/gdb/s390-tdep.h create mode 100644 contrib/gdb/gdb/sentinel-frame.c create mode 100644 contrib/gdb/gdb/sentinel-frame.h create mode 100644 contrib/gdb/gdb/ser-e7kpc.c create mode 100644 contrib/gdb/gdb/ser-go32.c create mode 100644 contrib/gdb/gdb/sim-regno.h create mode 100644 contrib/gdb/gdb/somread.c create mode 100644 contrib/gdb/gdb/somsolib.c create mode 100644 contrib/gdb/gdb/somsolib.h create mode 100644 contrib/gdb/gdb/sparc-nat.h create mode 100644 contrib/gdb/gdb/sparc-sol2-nat.c create mode 100644 contrib/gdb/gdb/sparc-sol2-tdep.c create mode 100644 contrib/gdb/gdb/sparc-tdep.h create mode 100644 contrib/gdb/gdb/sparc64-nat.c create mode 100644 contrib/gdb/gdb/sparc64-sol2-tdep.c create mode 100644 contrib/gdb/gdb/sparc64-tdep.c create mode 100644 contrib/gdb/gdb/sparc64-tdep.h create mode 100644 contrib/gdb/gdb/sparc64fbsd-nat.c create mode 100644 contrib/gdb/gdb/sparc64fbsd-tdep.c create mode 100644 contrib/gdb/gdb/sparc64nbsd-nat.c create mode 100644 contrib/gdb/gdb/sparc64nbsd-tdep.c create mode 100644 contrib/gdb/gdb/sparc64obsd-tdep.c create mode 100644 contrib/gdb/gdb/sparcnbsd-nat.c create mode 100644 contrib/gdb/gdb/sparcnbsd-tdep.c create mode 100644 contrib/gdb/gdb/sparcobsd-tdep.c create mode 100644 contrib/gdb/gdb/srec.h create mode 100644 contrib/gdb/gdb/stack.h create mode 100644 contrib/gdb/gdb/standalone.c create mode 100644 contrib/gdb/gdb/std-regs.c create mode 100644 contrib/gdb/gdb/stop-gdb.c create mode 100644 contrib/gdb/gdb/sun3-nat.c create mode 100644 contrib/gdb/gdb/trad-frame.c create mode 100644 contrib/gdb/gdb/trad-frame.h create mode 100644 contrib/gdb/gdb/tui/tui-command.c create mode 100644 contrib/gdb/gdb/tui/tui-command.h create mode 100644 contrib/gdb/gdb/tui/tui-data.c create mode 100644 contrib/gdb/gdb/tui/tui-data.h create mode 100644 contrib/gdb/gdb/tui/tui-disasm.c create mode 100644 contrib/gdb/gdb/tui/tui-disasm.h create mode 100644 contrib/gdb/gdb/tui/tui-file.c create mode 100644 contrib/gdb/gdb/tui/tui-file.h create mode 100644 contrib/gdb/gdb/tui/tui-hooks.c create mode 100644 contrib/gdb/gdb/tui/tui-hooks.h create mode 100644 contrib/gdb/gdb/tui/tui-interp.c create mode 100644 contrib/gdb/gdb/tui/tui-io.c create mode 100644 contrib/gdb/gdb/tui/tui-io.h create mode 100644 contrib/gdb/gdb/tui/tui-layout.c create mode 100644 contrib/gdb/gdb/tui/tui-layout.h create mode 100644 contrib/gdb/gdb/tui/tui-main.c create mode 100644 contrib/gdb/gdb/tui/tui-out.c create mode 100644 contrib/gdb/gdb/tui/tui-regs.c create mode 100644 contrib/gdb/gdb/tui/tui-regs.h create mode 100644 contrib/gdb/gdb/tui/tui-source.c create mode 100644 contrib/gdb/gdb/tui/tui-source.h create mode 100644 contrib/gdb/gdb/tui/tui-stack.c create mode 100644 contrib/gdb/gdb/tui/tui-stack.h create mode 100644 contrib/gdb/gdb/tui/tui-win.c create mode 100644 contrib/gdb/gdb/tui/tui-win.h create mode 100644 contrib/gdb/gdb/tui/tui-windata.c create mode 100644 contrib/gdb/gdb/tui/tui-windata.h create mode 100644 contrib/gdb/gdb/tui/tui-wingeneral.c create mode 100644 contrib/gdb/gdb/tui/tui-wingeneral.h create mode 100644 contrib/gdb/gdb/tui/tui-winsource.c create mode 100644 contrib/gdb/gdb/tui/tui-winsource.h create mode 100644 contrib/gdb/gdb/tui/tui.c create mode 100644 contrib/gdb/gdb/tui/tui.h create mode 100644 contrib/gdb/gdb/user-regs.c create mode 100644 contrib/gdb/gdb/user-regs.h create mode 100644 contrib/gdb/gdb/win32-nat.c create mode 100644 contrib/gdb/gdb/wince-stub.c create mode 100644 contrib/gdb/gdb/wince-stub.h create mode 100644 contrib/gdb/gdb/wince.c create mode 100644 contrib/gdb/gdb/xcoffread.c create mode 100644 contrib/gdb/gdb/xcoffsolib.c create mode 100644 contrib/gdb/gdb/xmodem.c create mode 100644 contrib/gdb/gdb/xmodem.h create mode 100644 contrib/gdb/gettext.m4 create mode 100644 contrib/gdb/include/COPYING create mode 100644 contrib/gdb/include/MAINTAINERS create mode 100644 contrib/gdb/include/alloca-conf.h create mode 100644 contrib/gdb/include/ansidecl.h create mode 100644 contrib/gdb/include/bfdlink.h create mode 100644 contrib/gdb/include/bin-bugs.h create mode 100644 contrib/gdb/include/bout.h create mode 100644 contrib/gdb/include/demangle.h create mode 100644 contrib/gdb/include/dis-asm.h create mode 100644 contrib/gdb/include/dyn-string.h create mode 100644 contrib/gdb/include/fibheap.h create mode 100644 contrib/gdb/include/filenames.h create mode 100644 contrib/gdb/include/floatformat.h create mode 100644 contrib/gdb/include/fnmatch.h create mode 100644 contrib/gdb/include/fopen-bin.h create mode 100644 contrib/gdb/include/fopen-same.h create mode 100644 contrib/gdb/include/fopen-vms.h create mode 100644 contrib/gdb/include/gdb/callback.h create mode 100644 contrib/gdb/include/gdb/fileio.h create mode 100644 contrib/gdb/include/gdb/remote-sim.h create mode 100644 contrib/gdb/include/gdb/sim-arm.h create mode 100644 contrib/gdb/include/gdb/sim-d10v.h create mode 100644 contrib/gdb/include/gdb/sim-frv.h create mode 100644 contrib/gdb/include/gdb/sim-h8300.h create mode 100644 contrib/gdb/include/gdb/sim-sh.h create mode 100644 contrib/gdb/include/gdbm.h create mode 100644 contrib/gdb/include/getopt.h create mode 100644 contrib/gdb/include/hashtab.h create mode 100644 contrib/gdb/include/hp-symtab.h create mode 100644 contrib/gdb/include/ieee.h create mode 100644 contrib/gdb/include/libiberty.h create mode 100644 contrib/gdb/include/md5.h create mode 100644 contrib/gdb/include/oasys.h create mode 100644 contrib/gdb/include/objalloc.h create mode 100644 contrib/gdb/include/obstack.h create mode 100644 contrib/gdb/include/os9k.h create mode 100644 contrib/gdb/include/partition.h create mode 100644 contrib/gdb/include/progress.h create mode 100644 contrib/gdb/include/safe-ctype.h create mode 100644 contrib/gdb/include/sort.h create mode 100644 contrib/gdb/include/splay-tree.h create mode 100644 contrib/gdb/include/symcat.h create mode 100644 contrib/gdb/include/ternary.h create mode 100644 contrib/gdb/include/xregex.h create mode 100644 contrib/gdb/include/xregex2.h create mode 100644 contrib/gdb/include/xtensa-isa-internal.h create mode 100644 contrib/gdb/include/xtensa-isa.h create mode 100755 contrib/gdb/install-sh create mode 100644 contrib/gdb/libtool.m4 create mode 100644 contrib/gdb/ltcf-c.sh create mode 100644 contrib/gdb/ltcf-cxx.sh create mode 100644 contrib/gdb/ltcf-gcj.sh create mode 100755 contrib/gdb/ltconfig create mode 100644 contrib/gdb/ltmain.sh create mode 100644 contrib/gdb/md5.sum create mode 100755 contrib/gdb/missing create mode 100755 contrib/gdb/mkinstalldirs create mode 100755 contrib/gdb/move-if-change create mode 100644 contrib/gdb/src-release create mode 100755 contrib/gdb/symlink-tree create mode 100755 contrib/gdb/ylwrap diff --git a/contrib/gdb/config-ml.in b/contrib/gdb/config-ml.in index c968bf0d719..b2e4ea9cf97 100644 --- a/contrib/gdb/config-ml.in +++ b/contrib/gdb/config-ml.in @@ -1,6 +1,32 @@ # Configure fragment invoked in the post-target section for subdirs # wanting multilib support. # +# Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Please report bugs to +# and send patches to . + # It is advisable to support a few --enable/--disable options to let the # user select which libraries s/he really wants. # @@ -17,8 +43,6 @@ # . ${srcdir}/../config-ml.in # fi # -# See librx/configure.in in the libg++ distribution for an example of how -# to handle autoconf'd libraries. # # Things are complicated because 6 separate cases must be handled: # 2 (native, cross) x 3 (absolute-path, relative-not-dot, dot) = 6. @@ -30,13 +54,10 @@ # The build tree is layed out as # # ./ -# libg++ # newlib # m68020/ -# libg++ # newlib # m68881/ -# libg++ # newlib # # The nice feature about this arrangement is that inter-library references @@ -69,11 +90,6 @@ # newlib. It is up to each target to turn on multilib support for the other # libraries as desired. -# We have to handle being invoked by both Cygnus configure and Autoconf. -# -# Cygnus configure incoming variables: -# srcdir, subdir, host, arguments -# # Autoconf incoming variables: # srcdir, host, ac_configure_args # @@ -83,26 +99,14 @@ # Note that `host' in this case is GCC's `target'. Target libraries are # configured for a particular host. -if [ -n "${ac_configure_args}" ]; then - Makefile=${ac_file-Makefile} - ml_config_shell=${CONFIG_SHELL-/bin/sh} - ml_arguments="${ac_configure_args}" - ml_realsrcdir=${srcdir} -else - Makefile=${Makefile-Makefile} - ml_config_shell=${config_shell-/bin/sh} - ml_arguments="${arguments}" - if [ -n "${subdir}" -a "${subdir}" != "." ] ; then - ml_realsrcdir=${srcdir}/${subdir} - else - ml_realsrcdir=${srcdir} - fi -fi +Makefile=${ac_file-Makefile} +ml_config_shell=${CONFIG_SHELL-/bin/sh} +ml_realsrcdir=${srcdir} # Scan all the arguments and set all the ones we need. ml_verbose=--verbose -for option in ${ml_arguments} +for option in ${ac_configure_args} do case $option in --*) ;; @@ -128,7 +132,7 @@ do enableopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'` eval $enableopt="$optarg" ;; - --norecursion | --no*) + --norecursion | --no-recursion) ml_norecursion=yes ;; --silent | --sil* | --quiet | --q*) @@ -156,7 +160,7 @@ done if [ "${enable_multilib}" = yes ]; then # Compute whether this is the library's top level directory -# (ie: not a multilib subdirectory, and not a subdirectory like libg++/src). +# (ie: not a multilib subdirectory, and not a subdirectory like newlib/src). # ${with_multisubdir} tells us we're in the right branch, but we could be # in a subdir of that. # ??? The previous version could void this test by separating the process into @@ -397,6 +401,28 @@ mips*-*-*) esac ;; powerpc*-*-* | rs6000*-*-*) + if [ x$enable_aix64 = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *ppc64* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_pthread = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *pthread* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi if [ x$enable_softfloat = xno ] then old_multidirs="${multidirs}" @@ -463,17 +489,6 @@ powerpc*-*-* | rs6000*-*-*) esac done fi - if [ x$enable_aix = xno ] - then - old_multidirs="${multidirs}" - multidirs="" - for x in ${old_multidirs}; do - case "$x" in - *mcall-aix* ) : ;; - *) multidirs="${multidirs} ${x}" ;; - esac - done - fi ;; sparc*-*-*) case " $multidirs " in @@ -510,14 +525,16 @@ multidirs=`echo "$multidirs" | sed -e 's/^[ ][ ]*//' -e 's/[ ][ ]*$//' -e 's/[ ] cat > Multi.tem <<\EOF +PWD_COMMAND=$${PWDCMD-pwd} + # FIXME: There should be an @-sign in front of the `if'. # Leave out until this is tested a bit more. multi-do: if [ -z "$(MULTIDIRS)" ]; then \ true; \ else \ - rootpre=`pwd`/; export rootpre; \ - srcrootpre=`cd $(srcdir); pwd`/; export srcrootpre; \ + rootpre=`${PWD_COMMAND}`/; export rootpre; \ + srcrootpre=`cd $(srcdir); ${PWD_COMMAND}`/; export srcrootpre; \ lib=`echo $${rootpre} | sed -e 's,^.*/\([^/][^/]*\)/$$,\1,'`; \ compiler="$(CC)"; \ for i in `$${compiler} --print-multi-lib 2>/dev/null`; do \ @@ -531,10 +548,17 @@ multi-do: CFLAGS="$(CFLAGS) $${flags}" \ prefix="$(prefix)" \ exec_prefix="$(exec_prefix)" \ + GCJFLAGS="$(GCJFLAGS) $${flags}" \ CXXFLAGS="$(CXXFLAGS) $${flags}" \ LIBCFLAGS="$(LIBCFLAGS) $${flags}" \ LIBCXXFLAGS="$(LIBCXXFLAGS) $${flags}" \ LDFLAGS="$(LDFLAGS) $${flags}" \ + MULTIFLAGS="$${flags}" \ + DESTDIR="$(DESTDIR)" \ + INSTALL="$(INSTALL)" \ + INSTALL_DATA="$(INSTALL_DATA)" \ + INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \ + INSTALL_SCRIPT="$(INSTALL_SCRIPT)" \ $(DO)); then \ true; \ else \ @@ -552,7 +576,7 @@ multi-clean: if [ -z "$(MULTIDIRS)" ]; then \ true; \ else \ - lib=`pwd | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \ + lib=`${PWD_COMMAND} | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \ for dir in Makefile $(MULTIDIRS); do \ if [ -f ../$${dir}/$${lib}/Makefile ]; then \ if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) $(DO)); \ @@ -659,10 +683,10 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then if [ "${ml_verbose}" = --verbose ]; then echo "Running configure in multilib subdirs ${multidirs}" - echo "pwd: `pwd`" + echo "pwd: `${PWDCMD-pwd}`" fi - ml_origdir=`pwd` + ml_origdir=`${PWDCMD-pwd}` ml_libdir=`echo $ml_origdir | sed -e 's,^.*/,,'` # cd to top-level-build-dir/${with_target_subdir} cd .. @@ -671,7 +695,7 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then if [ "${ml_verbose}" = --verbose ]; then echo "Running configure in multilib subdir ${ml_dir}" - echo "pwd: `pwd`" + echo "pwd: `${PWDCMD-pwd}`" fi if [ -d ${ml_dir} ]; then true; else @@ -699,7 +723,7 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then case ${srcdir} in ".") - echo Building symlink tree in `pwd`/${ml_dir}/${ml_libdir} + echo Building symlink tree in `${PWDCMD-pwd}`/${ml_dir}/${ml_libdir} if [ "${with_target_subdir}" != "." ]; then ml_unsubdir="../" else @@ -720,7 +744,7 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then ;; *) case "${srcdir}" in - /*) # absolute path + /* | [A-Za-z]:[\\/]* ) # absolute path ml_newsrcdir=${srcdir} ;; *) # otherwise relative @@ -733,31 +757,32 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then esac case "${progname}" in - /*) ml_recprog=${progname} ;; + /* | [A-Za-z]:[\\/]* ) ml_recprog=${progname} ;; *) ml_recprog=${dotdot}${progname} ;; esac # FIXME: POPDIR=${PWD=`pwd`} doesn't work here. - ML_POPDIR=`pwd` + ML_POPDIR=`${PWDCMD-pwd}` cd ${ml_dir}/${ml_libdir} if [ -f ${ml_newsrcdir}/configure ]; then - ml_recprog="${ml_newsrcdir}/configure --cache-file=../config.cache" + ml_recprog="${ml_newsrcdir}/configure" fi # find compiler flag corresponding to ${ml_dir} - for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do + for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do dir=`echo $i | sed -e 's/;.*$//'` if [ "${dir}" = "${ml_dir}" ]; then flags=`echo $i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'` break fi done - ml_config_env='CC="${CC_}$flags" CXX="${CXX_}$flags"' + ml_config_env='CC="${CC_}$flags" CXX="${CXX_}$flags" GCJ="${GCJ_}$flags"' if [ "${with_target_subdir}" = "." ]; then CC_=$CC' ' CXX_=$CXX' ' + GCJ_=$GCJ' ' else # Create a regular expression that matches any string as long # as ML_POPDIR. @@ -786,6 +811,18 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then esac done + GCJ_= + for arg in ${GCJ}; do + case $arg in + -[BIL]"${ML_POPDIR}"/*) + GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;; + "${ML_POPDIR}"/*) + GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;; + *) + GCJ_="${GCJ_}${arg} " ;; + esac + done + if test "x${LD_LIBRARY_PATH+set}" = xset; then LD_LIBRARY_PATH_= for arg in `echo "$LD_LIBRARY_PATH" | tr ':' ' '`; do @@ -823,7 +860,7 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then if eval ${ml_config_env} ${ml_config_shell} ${ml_recprog} \ --with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \ - ${ml_arguments} ${ml_srcdiroption} ; then + ${ac_configure_args} ${ml_srcdiroption} ; then true else exit 1 diff --git a/contrib/gdb/djunpack.bat b/contrib/gdb/djunpack.bat new file mode 100644 index 00000000000..04b45c3d15b --- /dev/null +++ b/contrib/gdb/djunpack.bat @@ -0,0 +1,52 @@ +@echo off +Rem +Rem WARNING WARNING WARNING: This file needs to have DOS CRLF end-of-line +Rem format, or else stock DOS/Windows shells will refuse to run it. +Rem +Rem This batch file unpacks the GDB distribution while simultaneously +Rem renaming some of the files whose names are invalid on DOS or conflict +Rem with other file names after truncation to DOS 8+3 namespace. +Rem +Rem Invoke like this: +Rem +Rem djunpack gdb-XYZ.tar +Rem +Rem where XYZ is the version number. If the argument includes leading +Rem directories, it MUST use backslashes, not forward slashes. +Rem +Rem The following 2 lines need to be changed with each new GDB release, to +Rem be identical to the name of the top-level directory where the GDB +Rem distribution unpacks itself. +set GDBVER=gdb-6.1.1 +if "%GDBVER%"=="gdb-6.1.1" GoTo EnvOk +Rem If their environment space is too small, re-exec with a larger one +command.com /e:4096 /c %0 %1 +GoTo End +:EnvOk +if not exist %1 GoTo NoArchive +djtar -x -p -o %GDBVER%/gdb/config/djgpp/fnchange.lst %1 > fnchange.tmp +Rem The following uses a feature of COPY whereby it does not copy +Rem empty files. We need that because the previous line will create +Rem an empty fnchange.tmp even if the command failed for some reason. +copy fnchange.tmp junk.tmp > nul +if not exist junk.tmp GoTo NoDjTar +del junk.tmp +sed -e 's,@V@,%GDBVER%,g' < fnchange.tmp > fnchange.lst +Rem See the comment above about the reason for using COPY. +copy fnchange.lst junk.tmp > nul +if not exist junk.tmp GoTo NoSed +del junk.tmp +djtar -x -n fnchange.lst %1 +GoTo End +:NoSed +echo FAIL: Sed is not available. +GoTo End +:NoDjTar +echo FAIL: DJTAR is not available or no fnchange.lst file in %1. +GoTo End +:NoArchive +echo FAIL: the file %1 does not seem to exist. +echo Remember that %1 cannot use forward slashes, only backslashes. +GoTo End +:End +set GDBVER= diff --git a/contrib/gdb/gdb/MAINTAINERS b/contrib/gdb/gdb/MAINTAINERS index 5941946b9f9..95328a45f6d 100644 --- a/contrib/gdb/gdb/MAINTAINERS +++ b/contrib/gdb/gdb/MAINTAINERS @@ -1,14 +1,15 @@ GDB Maintainers - Blanket Write Privs + Global Maintainers (alphabetic) Jim Blandy jimb@redhat.com Kevin Buettner kevinb@redhat.com -Andrew Cagney ac131313@redhat.com -J.T. Conklin jtc@redback.com +Andrew Cagney cagney@gnu.org +J.T. Conklin jtc@acorntoolworks.com Fred Fish fnf@ninemoons.com +Daniel Jacobowitz dan@debian.org Mark Kettenis kettenis@gnu.org Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de Stan Shebs shebs@apple.com @@ -23,7 +24,7 @@ Note individuals who maintain parts of the debugger need approval to check in changes outside of the immediate domain that they maintain. If there is no maintainer for a given domain then the responsibility -falls to the head maintainer. +falls to a global maintainer. If there are several maintainers for a given domain then responsibility falls to the first maintainer. The first maintainer is @@ -47,142 +48,110 @@ fix, since such a change without discussion will result in instantaneous and loud complaints. -Target/Architecture: +Target Instruction Set Architectures: Generic ISA (Instruction Set Architecture) issues, API variants, CPU variants. *-tdep.c. The Target/Architecture maintainer works with the host maintainer when resolving build issues. The Target/Architecture maintainer works with the native maintainer when resolving API issues. - a29k OBSOLETE + a29k Deleted. - alpha --target=alpha-dec-osf4.0a -Werror + alpha --target=alpha-elf ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch - arc --target=arc-elf ,-Werror - Maintenance only - OBSOLETE candidate, not multi-arch + arc Deleted. - arm --target=arm-elf -w - Fernando Nasser fnasser@redhat.com + arm --target=arm-elf ,-Werror Scott Bambrough scottb@netwinder.org Richard Earnshaw rearnsha@arm.com - Not multi-arch avr --target=avr ,-Werror - Theodore A. Roth troth@verinet.com + Theodore A. Roth troth@openavr.org - cris --target=cris-elf -w + cris --target=cris-elf ,-Werror Orjan Friberg orjanf@axis.com d10v --target=d10v-elf ,-Werror Maintenance only - d30v --target=d30v-elf ,-Werror + d30v Deleted. + + fr30 Deleted. + + frv --target=frv-elf ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch - djgpp --target=i586-pc-msdosdjgpp ,-Werror - (See native and host) - - fr30 --target=fr30-elf -Werror + h8300 --target=h8300hms ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch - h8300 --target=h8300hms -Werror - Maintenance only - Not multi-arch, work in progress + h8500 Deleted. - h8500 --target=h8500hms -Werror - Maintenance only - Not multi-arch, work in progress - - i386 --target=i386-elf,i386-aout ,-Werror + i386 --target=i386-elf ,-Werror Mark Kettenis kettenis@gnu.org - i960 --target=i960-coff ,-Werror - Maintenance only - OBSOLETE candidate, not multi-arch + i960 Deleted. - ia64 --target=ia64-linux ,-Werror + ia64 --target=ia64-linux-gnu ,-Werror + (--target=ia64-elf broken) Kevin Buettner kevinb@redhat.com - m32r --target=m32r-elf -Werror - Michael Snyder msnyder@redhat.com - Not multi-arch + m32r --target=m32r-elf ,-Werror - m68hc11 --target=m68hc11-elf ,-Werror - Stephane Carrez Stephane.Carrez@worldnet.fr + m68hc11 --target=m68hc11-elf ,-Werror , + Stephane Carrez stcarrez@nerim.fr m68k --target=m68k-elf ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch - m88k --target=m88k ,-Werror - Known problem in 5.1 + m88k Deleted. + + mcore --target=mcore-elf ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch - mcore --target=mcore-elf,mcore-pe ,-Werror - Maintenance only - OBSOLETE candidate, not multi-arch - - mips --target=mips-elf,mips64-elf ,-Werror + mips --target=mips-elf ,-Werror Andrew Cagney cagney@redhat.com - mn10200 --target=mn10200-elf ,-Werror - Maintenance only - OBSOLETE candidate, not multi-arch + mn10200 Deleted. mn10300 --target=mn10300-elf ,-Werror Maintenance only ns32k --target=ns32k-netbsd ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch - pa (--target=hppa1.1-hp-proelf broken) + pa (--target=hppa-elf broken) Maintenance only - OBSOLETE candidate, not multi-arch powerpc --target=powerpc-eabi ,-Werror Kevin Buettner kevinb@redhat.com - rs6000 --target=rs6000-ibm-aix4.1 ,-Werror - (see rs6000 native and ppc target) - - s390 --target=s390-linux ,-Werror + s390 --target=s390-linux-gnu ,-Werror (contact DJ Barrow djbarrow@de.ibm.com) - sh --target=sh-hms,sh-elf ,-Werror + sh --target=sh-elf ,-Werror Elena Zannoni ezannoni@redhat.com - sparc --target=sparc-elf,sparc64-elf ,-Werror + sparc --target=sparc-elf ,-Werror Maintenance only tic80 Deleted. v850 --target=v850-elf ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch - vax --target=vax-dec-vms5.5 ,-Werror + vax --target=vax-netbsd ,-Werror Maintenance only - OBSOLETE candidate, not multi-arch w65 Deleted. - x86-64 (--target=x86_64-linux-gnu broken) + x86-64 --target=x86_64-linux-gnu ,-Werror Maintenance only xstormy16 --target=xstormy16-elf ,-Werror Corinna Vinschen vinschen@redhat.com - z8k --target=z8k-coff ,-Werror - Known problem in 5.1 - Maintenance only - OBSOLETE candidate, not multi-arch + z8k Deleted. All developers recognized by this file can make arbitrary changes to OBSOLETE targets. @@ -194,21 +163,8 @@ All recognized developers can make mechanical changes (by virtue of the obvious fix rule) to ``maintenance only'' targets. The change shall be sanity checked by compiling with one of the listed targets. -The GAWK segment: - - awk < "${maintainers}" ' - $2 ~ /--target=.*/ { - targets = gensub (/^.*--target=/, "", 1, $2) - warnings = gensub (/[)]*$/, "", 1, $3) - split (targets, targ, /,/) - for (i in targ) { - print targ[i], warnings - } - }' - -can be used to generate a full list of --target= ---enable-gdb-build-warning= pairs. - +The Bourne shell script gdb_mbuild.sh can be used to rebuild all the +above targets. Host/Native: @@ -218,19 +174,19 @@ support - typically shared libraries and quirks to procfs/ptrace/... The Native maintainer works with the Arch and Core maintainers when resolving more generic problems. -The host maintainer ensures that gdb (including mmalloc) can be built -as a cross debugger on their platform. +The host maintainer ensures that gdb can be built as a cross debugger on +their platform. AIX Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de Kevin Buettner kevinb@redhat.com + Joel Brobecker brobecker@gnat.com djgpp native Eli Zaretskii eliz@gnu.org DJ Delorie dj@redhat.com -MS Windows (NT, CE, '00, 9x, Me) host & native - Chris Faylor cgf@redhat.com +MS Windows (NT, '00, 9x, Me, XP) host & native + Chris Faylor cgf@alum.bu.edu GNU/Linux/x86 native & host Mark Kettenis kettenis@gnu.org - Jim Blandy jimb@redhat.com GNU/Linux PPC native Kevin Buettner kevinb@redhat.com GNU/Linux MIPS native & host Daniel Jacobowitz dan@debian.org @@ -238,12 +194,13 @@ GNU/Linux m68k Andreas Schwab schwab@suse.de FreeBSD native & host Mark Kettenis kettenis@gnu.org David O'Brien obrien@freebsd.org hurd native Mark Kettenis kettenis@gnu.org +NetBSD native & host Jason Thorpe thorpej@wasabisystems.com SCO/Unixware Robert Lipe rjl@sco.com GNU/Linux ARM native Scott Bambrough scottb@netwinder.org Solaris/x86 native & host (devolved) Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de Solaris/SPARC native & host (devolved) - Michael Snyder msnyder@redhat.com + (Global Maintainers) @@ -253,8 +210,10 @@ generic arch support Andrew Cagney cagney@redhat.com Any host/target maintainer can add to gdbarch.{c,h,sh}. Send tricky ones to cagney. target vector Andrew Cagney cagney@redhat.com -main (main.c, top.c) Elena Zannoni ezannoni@redhat.com + event loop Elena Zannoni ezannoni@redhat.com + For the part of top.c related to the event loop, + send questions to ezannoni@redhat.com generic symtabs Jim Blandy jimb@redhat.com Elena Zannoni ezannoni@redhat.com @@ -267,42 +226,39 @@ generic symtabs Jim Blandy jimb@redhat.com coff reader Philippe De Muyter phdm@macqel.be xcoff reader Any maintainer can modify this; please send tricky ones to Kevin Buettner - linespec Jim Blandy jimb@redhat.com - Elena Zannoni ezannoni@redhat.com - Fernando Nasser fnasser@redhat.com + HP/UX readers Any [past] maintainer can modify this. + Please send tricky ones to the symtabs maintainers. tracing bytecode stuff Jim Blandy jimb@redhat.com + (Global Maintainers) tracing Michael Snyder msnyder@redhat.com threads Michael Snyder msnyder@redhat.com Mark Kettenis kettenis@gnu.org -breakpoints Michael Snyder msnyder@redhat.com - Jim Blandy jimb@redhat.com +breakpoints (Global Maintainers) language support (Blanket Write Privs Maintainers) C++ Daniel Jacobowitz dan@debian.org - Java support (devolved) - Per Bothner per@bothner.com - Anthony Green green@redhat.com + Java support (Global Maintainers) Pascal support Pierre Muller muller@sources.redhat.com - Scheme support Jim Blandy jimb@redhat.com - -shared libs (devolved) Jim Blandy jimb@redhat.com - Kevin Buettner kevinb@redhat.com + Objective C support Adam Fedor fedor@gnu.org +shared libs (devolved) Kevin Buettner kevinb@redhat.com xcoffsolib Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de remote.c Andrew Cagney cagney@redhat.com include/remote-sim.h, remote-sim.c Andrew Cagney cagney@redhat.com -sds protocol Fernando Nasser fnasser@redhat.com -rdi/adp protocol Fernando Nasser fnasser@redhat.com +sds protocol (vacant) +rdi/adp protocol (vacant) documentation Eli Zaretskii eliz@gnu.org -testsuite Fernando Nasser fnasser@redhat.com - config Mark Salter msalter@redhat.com - lib Mark Salter msalter@redhat.com +testsuite Michael Chastain mec.gnu@mindspring.com + (Global Maintainers) + lib/, config/, gdb.base/, ... + Michael Chastain mec.gnu@mindspring.com + (Global Maintainers) gdbtk (gdb.gdbtk) Keith Seitz keiths@redhat.com - c++ (gdb.c++) Michael Chastain mec@shout.net + c++ (gdb.cp) Michael Chastain mec.gnu@mindspring.com + David Carlton carlton@bactrian.org mi tests (gdb.mi) Elena Zannoni ezannoni@redhat.com Andrew Cagney cagney@redhat.com - stabs (gdb.stabs) Elena Zannoni ezannoni@redhat.com threads (gdb.threads) Michael Snyder msnyder@redhat.com trace (gdb.trace) Michael Snyder msnyder@redhat.com hp tests (gdb.hp) (vacant) @@ -312,7 +268,7 @@ Kernel Object Display Fernando Nasser fnasser@redhat.com UI: External (user) interfaces. -command interpreter Fernando Nasser fnasser@redhat.com +command interpreter (Global Maintainers) gdbtk (c & tcl) Jim Ingham jingham@apple.com Fernando Nasser fnasser@redhat.com Keith Seitz keiths@redhat.com @@ -321,8 +277,8 @@ libgui (w/foundry, sn) Jim Ingham jingham@apple.com mi (gdb/mi) Andrew Cagney cagney@redhat.com Elena Zannoni ezannoni@redhat.com Fernando Nasser fnasser@redhat.com -tui (vacant) - Technical Contact Point wdb@cup.hp.com +tui Stephane Carrez stcarrez@nerim.fr + (Global Maintainers) Misc: @@ -336,6 +292,8 @@ Makefile.in, configure* ALL mmalloc/ ALL Host maintainers +NEWS ALL + sim/ See sim/MAINTAINERS readline/ Master version: ftp://ftp.cwru.edu/pub/bash/ @@ -352,49 +310,109 @@ To get recommended for the Write After Approval list you need a valid FSF assignment and have submitted one good patch. David Anderson davea@sgi.com +Shrinivas Atre shrinivasa@kpitcummins.com +Scott Bambrough scottb@netwinder.org +Jim Blandy jimb@redhat.com Philip Blundell philb@gnu.org -Joel Brobecker brobecker@act-europe.fr +Per Bothner per@bothner.com +Joel Brobecker brobecker@gnat.com +Dave Brolley brolley@redhat.com +Paul Brook paul@codesourcery.com +Kevin Buettner kevinb@redhat.com +Andrew Cagney cagney@gnu.org +David Carlton carlton@bactrian.org +Stephane Carrez stcarrez@nerim.fr +Michael Chastain mec.gnu@mindspring.com +Eric Christopher echristo@redhat.com +Randolph Chung tausq@debian.org Nick Clifton nickc@redhat.com +Brendan Conoboy blc@redhat.com +DJ Delorie dj@redhat.com Chris G. Demetriou cgd@broadcom.com +Philippe De Muyter phdm@macqel.be +Dhananjay Deshpande dhananjayd@kpitcummins.com Klee Dienes kdienes@apple.com Richard Earnshaw rearnsha@arm.com +Frank Ch. Eigler fche@redhat.com +Ben Elliston bje@gnu.org +Brian Ford ford@vss.fsi.com +Raoul Gough RaoulGough@yahoo.co.uk +Anthony Green green@redhat.com Matthew Green mrg@eterna.com.au +Jerome Guitton guitton@act-europe.fr +Adam Fedor fedor@gnu.org +Fred Fish fnf@ninemoons.com Orjan Friberg orjanf@axis.com Ben Harris bjh21@netbsd.org +Richard Henderson rth@redhat.com +Aldy Hernandez aldyh@redhat.com Paul Hilfinger hilfinger@gnat.com Matt Hiller hiller@redhat.com -Kazu Hirata kazu@hxi.com +Kazu Hirata kazu@cs.umass.edu Jeff Holcomb jeffh@redhat.com Don Howard dhoward@redhat.com Martin Hunt hunt@redhat.com Jim Ingham jingham@apple.com Daniel Jacobowitz dan@debian.org Andreas Jaeger aj@suse.de +Jeff Johnston jjohnstn@redhat.com Geoff Keating geoffk@redhat.com +Mark Kettenis kettenis@gnu.org Jim Kingdon jkingdon@engr.sgi.com ++ Jonathan Larmour jlarmour@redhat.co.uk +Jeff Law law@redhat.com +David Lecomber david@streamline-computing.com +Robert Lipe rjl@sco.com H.J. Lu hjl@lucon.org +Michal Ludvig mludvig@suse.cz Glen McCready gkm@redhat.com Greg McGary greg@mcgary.org +Roland McGrath roland@redhat.com +Bryce McKinlay mckinlay@redhat.com Jason Merrill jason@redhat.com +David S. Miller davem@redhat.com +Mark Mitchell mark@codesourcery.com +Marko Mlinar markom@opencores.org +Alan Modra amodra@bigpond.net.au Jason Molenda jmolenda@apple.com Pierre Muller muller@sources.redhat.com +Fernando Nasser fnasser@redhat.com +Hans-Peter Nilsson hp@bitrange.com +David O'Brien obrien@freebsd.org Alexandre Oliva aoliva@redhat.com Tom Rix trix@redhat.com -Theodore A. Roth troth@verinet.com +Nick Roberts nick@nick.uklinux.net +Bob Rossi bob_rossi@cox.net +Theodore A. Roth troth@openavr.org +Ian Roxborough irox@redhat.com +Grace Sainsbury graces@redhat.com +Kei Sakamoto sakamoto.kei@renesas.com Mark Salter msalter@redhat.com +Richard Sandiford rsandifo@redhat.com +Peter Schauer Peter.Schauer@regent Andreas Schwab schwab@suse.de Keith Seitz keiths@redhat.com +Stan Shebs shebs@apple.com +Aidan Skinner aidan@velvet.net Jiri Smid smid@suse.cz David Smith dsmith@redhat.com -Stephen P. Smith ischis2@home.com +Stephen P. Smith ischis2@cox.net Jackie Smith Cashion jsmith@redhat.com +Michael Snyder msnyder@redhat.com Petr Sorfa petrs@caldera.com +Ian Lance Taylor ian@wasabisystems.com Gary Thomas gthomas@redhat.com Jason Thorpe thorpej@wasabisystems.com Tom Tromey tromey@redhat.com +D Venkatasubramanian dvenkat@noida.hcltech.com Corinna Vinschen vinschen@redhat.com Keith Walker keith.walker@arm.com +Kris Warkentin kewarken@qnx.com +Ulrich Weigand uweigand@de.ibm.com +Nathan Williams nathanw@wasabisystems.com +Jim Wilson wilson@specifixinc.com +Elena Zannoni ezannoni@redhat.com +Eli Zaretskii eliz@gnu.org @@ -408,12 +426,18 @@ David Taylor (d10v, sparc, utils, defs, expression evaluator, language support) taylor at candd dot org J.T. Conklin (dcache, NetBSD, remote) jtc at redback dot com Frank Ch. Eigler (sim) fche at redhat dot com +Per Bothner (Java) per at bothner dot com +Anthony Green (Java) green at redhat dot com +Fernando Nasser (testsuite/, mi, cli) fnasser at redhat dot com +Mark Salter (testsuite/lib+config) msalter at redhat dot com Folks that have been caught up in a paper trail: +Chris Faylor cgf@alum.bu.edu Jim Kingdon jkingdon@engr.sgi.com +David Carlton carlton@bactrian.org -- diff --git a/contrib/gdb/gdb/NEWS b/contrib/gdb/gdb/NEWS index f3acc60ffc5..abba0e760cc 100644 --- a/contrib/gdb/gdb/NEWS +++ b/contrib/gdb/gdb/NEWS @@ -1,6 +1,439 @@ What has changed in GDB? (Organized release by release) +*** Changes in GDB 6.1.1: + +* TUI (Text-mode User Interface) built-in (also included in GDB 6.1) + +The TUI (Text-mode User Interface) is now built as part of a default +GDB configuration. It is enabled by either selecting the TUI with the +command line option "-i=tui" or by running the separate "gdbtui" +program. For more information on the TUI, see the manual "Debugging +with GDB". + +* Pending breakpoint support (also included in GDB 6.1) + +Support has been added to allow you to specify breakpoints in shared +libraries that have not yet been loaded. If a breakpoint location +cannot be found, and the "breakpoint pending" option is set to auto, +GDB queries you if you wish to make the breakpoint pending on a future +shared-library load. If and when GDB resolves the breakpoint symbol, +the pending breakpoint is removed as one or more regular breakpoints +are created. + +Pending breakpoints are very useful for GCJ Java debugging. + +* Fixed ISO-C build problems + +The files bfd/elf-bfd.h, gdb/dictionary.c and gdb/types.c contained +non ISO-C code that stopped them being built using a more strict ISO-C +compiler (e.g., IBM's C compiler). + +* Fixed build problem on IRIX 5 + +Due to header problems with , the file gdb/proc-api.c +wasn't able to compile compile on an IRIX 5 system. + +* Added execute permission to gdb/gdbserver/configure + +The shell script gdb/testsuite/gdb.stabs/configure lacked execute +permission. This bug would cause configure to fail on a number of +systems (Solaris, IRIX). Ref: server/519. + +* Fixed build problem on hpux2.0w-hp-hpux11.00 using the HP ANSI C compiler + +Older HPUX ANSI C compilers did not accept variable array sizes. somsolib.c +has been updated to use constant array sizes. + +* Fixed a panic in the DWARF Call Frame Info code on Solaris 2.7 + +GCC 3.3.2, on Solaris 2.7, includes the DW_EH_PE_funcrel encoding in +its generated DWARF Call Frame Info. This encoding was causing GDB to +panic, that panic has been fixed. Ref: gdb/1628. + +* Fixed a problem when examining parameters in shared library code. + +When examining parameters in optimized shared library code generated +by a mainline GCC, GDB would incorrectly report ``Variable "..." is +not available''. GDB now correctly displays the variable's value. + +*** Changes in GDB 6.1: + +* Removed --with-mmalloc + +Support for the mmalloc memory manager has been removed, as it +conflicted with the internal gdb byte cache. + +* Changes in AMD64 configurations + +The AMD64 target now includes the %cs and %ss registers. As a result +the AMD64 remote protocol has changed; this affects the floating-point +and SSE registers. If you rely on those registers for your debugging, +you should upgrade gdbserver on the remote side. + +* Revised SPARC target + +The SPARC target has been completely revised, incorporating the +FreeBSD/sparc64 support that was added for GDB 6.0. As a result +support for LynxOS and SunOS 4 has been dropped. Calling functions +from within GDB on operating systems with a non-executable stack +(Solaris, OpenBSD) now works. + +* New C++ demangler + +GDB has a new C++ demangler which does a better job on the mangled +names generated by current versions of g++. It also runs faster, so +with this and other changes gdb should now start faster on large C++ +programs. + +* DWARF 2 Location Expressions + +GDB support for location expressions has been extended to support function +arguments and frame bases. Older versions of GDB could crash when they +encountered these. + +* C++ nested types and namespaces + +GDB's support for nested types and namespaces in C++ has been +improved, especially if you use the DWARF 2 debugging format. (This +is the default for recent versions of GCC on most platforms.) +Specifically, if you have a class "Inner" defined within a class or +namespace "Outer", then GDB realizes that the class's name is +"Outer::Inner", not simply "Inner". This should greatly reduce the +frequency of complaints about not finding RTTI symbols. In addition, +if you are stopped at inside of a function defined within a namespace, +GDB modifies its name lookup accordingly. + +* New native configurations + +NetBSD/amd64 x86_64-*-netbsd* +OpenBSD/amd64 x86_64-*-openbsd* +OpenBSD/alpha alpha*-*-openbsd* +OpenBSD/sparc sparc-*-openbsd* +OpenBSD/sparc64 sparc64-*-openbsd* + +* New debugging protocols + +M32R with SDI protocol m32r-*-elf* + +* "set prompt-escape-char" command deleted. + +The command "set prompt-escape-char" has been deleted. This command, +and its very obscure effet on GDB's prompt, was never documented, +tested, nor mentioned in the NEWS file. + +* OBSOLETE configurations and files + +Configurations that have been declared obsolete in this release have +been commented out. Unless there is activity to revive these +configurations, the next release of GDB will have their sources +permanently REMOVED. + +Sun 3, running SunOS 3 m68*-*-sunos3* +Sun 3, running SunOS 4 m68*-*-sunos4* +Sun 2, running SunOS 3 m68000-*-sunos3* +Sun 2, running SunOS 4 m68000-*-sunos4* +Motorola 680x0 running LynxOS m68*-*-lynxos* +AT&T 3b1/Unix pc m68*-att-* +Bull DPX2 (68k, System V release 3) m68*-bull-sysv* +decstation mips-dec-* mips-little-* +riscos mips-*-riscos* mips-*-sysv* +sonymips mips-sony-* +sysv mips*-*-sysv4* (IRIX 5/6 not included) + +* REMOVED configurations and files + +SGI Irix-4.x mips-sgi-irix4 or iris4 +SGI Iris (MIPS) running Irix V3: mips-sgi-irix or iris +Z8000 simulator z8k-zilog-none or z8ksim +Matsushita MN10200 w/simulator mn10200-*-* +H8/500 simulator h8500-hitachi-hms or h8500hms +HP/PA running BSD hppa*-*-bsd* +HP/PA running OSF/1 hppa*-*-osf* +HP/PA Pro target hppa*-*-pro* +PMAX (MIPS) running Mach 3.0 mips*-*-mach3* +386BSD i[3456]86-*-bsd* +Sequent family i[3456]86-sequent-sysv4* + i[3456]86-sequent-sysv* + i[3456]86-sequent-bsd* +SPARC running LynxOS sparc-*-lynxos* +SPARC running SunOS 4 sparc-*-sunos4* +Tsqware Sparclet sparclet-*-* +Fujitsu SPARClite sparclite-fujitsu-none or sparclite + +*** Changes in GDB 6.0: + +* Objective-C + +Support for debugging the Objective-C programming language has been +integrated into GDB. + +* New backtrace mechanism (includes DWARF 2 Call Frame Information). + +DWARF 2's Call Frame Information makes available compiler generated +information that more exactly describes the program's run-time stack. +By using this information, GDB is able to provide more robust stack +backtraces. + +The i386, amd64 (nee, x86-64), Alpha, m68hc11, ia64, and m32r targets +have been updated to use a new backtrace mechanism which includes +DWARF 2 CFI support. + +* Hosted file I/O. + +GDB's remote protocol has been extended to include support for hosted +file I/O (where the remote target uses GDB's file system). See GDB's +remote protocol documentation for details. + +* All targets using the new architecture framework. + +All of GDB's targets have been updated to use the new internal +architecture framework. The way is now open for future GDB releases +to include cross-architecture native debugging support (i386 on amd64, +ppc32 on ppc64). + +* GNU/Linux's Thread Local Storage (TLS) + +GDB now includes support for for the GNU/Linux implementation of +per-thread variables. + +* GNU/Linux's Native POSIX Thread Library (NPTL) + +GDB's thread code has been updated to work with either the new +GNU/Linux NPTL thread library or the older "LinuxThreads" library. + +* Separate debug info. + +GDB, in conjunction with BINUTILS, now supports a mechanism for +automatically loading debug information from a separate file. Instead +of shipping full debug and non-debug versions of system libraries, +system integrators can now instead ship just the stripped libraries +and optional debug files. + +* DWARF 2 Location Expressions + +DWARF 2 Location Expressions allow the compiler to more completely +describe the location of variables (even in optimized code) to the +debugger. + +GDB now includes preliminary support for location expressions (support +for DW_OP_piece is still missing). + +* Java + +A number of long standing bugs that caused GDB to die while starting a +Java application have been fixed. GDB's Java support is now +considered "useable". + +* GNU/Linux support for fork, vfork, and exec. + +The "catch fork", "catch exec", "catch vfork", and "set follow-fork-mode" +commands are now implemented for GNU/Linux. They require a 2.5.x or later +kernel. + +* GDB supports logging output to a file + +There are two new commands, "set logging" and "show logging", which can be +used to capture GDB's output to a file. + +* The meaning of "detach" has changed for gdbserver + +The "detach" command will now resume the application, as documented. To +disconnect from gdbserver and leave it stopped, use the new "disconnect" +command. + +* d10v, m68hc11 `regs' command deprecated + +The `info registers' command has been updated so that it displays the +registers using a format identical to the old `regs' command. + +* Profiling support + +A new command, "maint set profile on/off", has been added. This command can +be used to enable or disable profiling while running GDB, to profile a +session or a set of commands. In addition there is a new configure switch, +"--enable-profiling", which will cause GDB to be compiled with profiling +data, for more informative profiling results. + +* Default MI syntax changed to "mi2". + +The default MI (machine interface) syntax, enabled by the command line +option "-i=mi", has been changed to "mi2". The previous MI syntax, +"mi1", can be enabled by specifying the option "-i=mi1". + +Support for the original "mi0" syntax (included in GDB 5.0) has been +removed. + +Fix for gdb/192: removed extraneous space when displaying frame level. +Fix for gdb/672: update changelist is now output in mi list format. +Fix for gdb/702: a -var-assign that updates the value now shows up + in a subsequent -var-update. + +* New native configurations. + +FreeBSD/amd64 x86_64-*-freebsd* + +* Multi-arched targets. + +HP/PA HPUX11 hppa*-*-hpux* +Renesas M32R/D w/simulator m32r-*-elf* + +* OBSOLETE configurations and files + +Configurations that have been declared obsolete in this release have +been commented out. Unless there is activity to revive these +configurations, the next release of GDB will have their sources +permanently REMOVED. + +Z8000 simulator z8k-zilog-none or z8ksim +Matsushita MN10200 w/simulator mn10200-*-* +H8/500 simulator h8500-hitachi-hms or h8500hms +HP/PA running BSD hppa*-*-bsd* +HP/PA running OSF/1 hppa*-*-osf* +HP/PA Pro target hppa*-*-pro* +PMAX (MIPS) running Mach 3.0 mips*-*-mach3* +Sequent family i[3456]86-sequent-sysv4* + i[3456]86-sequent-sysv* + i[3456]86-sequent-bsd* +Tsqware Sparclet sparclet-*-* +Fujitsu SPARClite sparclite-fujitsu-none or sparclite + +* REMOVED configurations and files + +V850EA ISA +Motorola Delta 88000 running Sys V m88k-motorola-sysv or delta88 +IBM AIX PS/2 i[3456]86-*-aix +i386 running Mach 3.0 i[3456]86-*-mach3* +i386 running Mach i[3456]86-*-mach* +i386 running OSF/1 i[3456]86-*osf1mk* +HP/Apollo 68k Family m68*-apollo*-sysv*, + m68*-apollo*-bsd*, + m68*-hp-bsd*, m68*-hp-hpux* +Argonaut Risc Chip (ARC) arc-*-* +Mitsubishi D30V d30v-*-* +Fujitsu FR30 fr30-*-elf* +OS/9000 i[34]86-*-os9k +I960 with MON960 i960-*-coff + +* MIPS $fp behavior changed + +The convenience variable $fp, for the MIPS, now consistently returns +the address of the current frame's base. Previously, depending on the +context, $fp could refer to either $sp or the current frame's base +address. See ``8.10 Registers'' in the manual ``Debugging with GDB: +The GNU Source-Level Debugger''. + +*** Changes in GDB 5.3: + +* GNU/Linux shared library multi-threaded performance improved. + +When debugging a multi-threaded application on GNU/Linux, GDB now uses +`/proc', in preference to `ptrace' for memory reads. This may result +in an improvement in the start-up time of multi-threaded, shared +library applications when run under GDB. One GDB user writes: ``loads +shared libs like mad''. + +* ``gdbserver'' now supports multi-threaded applications on some targets + +Support for debugging multi-threaded applications which use +the GNU/Linux LinuxThreads package has been added for +arm*-*-linux*-gnu*, i[3456]86-*-linux*-gnu*, mips*-*-linux*-gnu*, +powerpc*-*-linux*-gnu*, and sh*-*-linux*-gnu*. + +* GDB now supports C/C++ preprocessor macros. + +GDB now expands preprocessor macro invocations in C/C++ expressions, +and provides various commands for showing macro definitions and how +they expand. + +The new command `macro expand EXPRESSION' expands any macro +invocations in expression, and shows the result. + +The new command `show macro MACRO-NAME' shows the definition of the +macro named MACRO-NAME, and where it was defined. + +Most compilers don't include information about macros in the debugging +information by default. In GCC 3.1, for example, you need to compile +your program with the options `-gdwarf-2 -g3'. If the macro +information is present in the executable, GDB will read it. + +* Multi-arched targets. + +DEC Alpha (partial) alpha*-*-* +DEC VAX (partial) vax-*-* +NEC V850 v850-*-* +National Semiconductor NS32000 (partial) ns32k-*-* +Motorola 68000 (partial) m68k-*-* +Motorola MCORE mcore-*-* + +* New targets. + +Fujitsu FRV architecture added by Red Hat frv*-*-* + + +* New native configurations + +Alpha NetBSD alpha*-*-netbsd* +SH NetBSD sh*-*-netbsdelf* +MIPS NetBSD mips*-*-netbsd* +UltraSPARC NetBSD sparc64-*-netbsd* + +* OBSOLETE configurations and files + +Configurations that have been declared obsolete in this release have +been commented out. Unless there is activity to revive these +configurations, the next release of GDB will have their sources +permanently REMOVED. + +Mitsubishi D30V d30v-*-* +OS/9000 i[34]86-*-os9k +IBM AIX PS/2 i[3456]86-*-aix +Fujitsu FR30 fr30-*-elf* +Motorola Delta 88000 running Sys V m88k-motorola-sysv or delta88 +Argonaut Risc Chip (ARC) arc-*-* +i386 running Mach 3.0 i[3456]86-*-mach3* +i386 running Mach i[3456]86-*-mach* +i386 running OSF/1 i[3456]86-*osf1mk* +HP/Apollo 68k Family m68*-apollo*-sysv*, + m68*-apollo*-bsd*, + m68*-hp-bsd*, m68*-hp-hpux* +I960 with MON960 i960-*-coff + +* OBSOLETE languages + +CHILL, a Pascal like language used by telecommunications companies. + +* REMOVED configurations and files + +AMD 29k family via UDI a29k-amd-udi, udi29k +A29K VxWorks a29k-*-vxworks +AMD 29000 embedded, using EBMON a29k-none-none +AMD 29000 embedded with COFF a29k-none-coff +AMD 29000 embedded with a.out a29k-none-aout + +testsuite/gdb.hp/gdb.threads-hp/ directory + +* New command "set max-user-call-depth " + +This command allows the user to limit the call depth of user-defined +commands. The default is 1024. + +* Changes in FreeBSD/i386 native debugging. + +Support for the "generate-core-file" has been added. + +* New commands "dump", "append", and "restore". + +These commands allow data to be copied from target memory +to a bfd-format or binary file (dump and append), and back +from a file into memory (restore). + +* Improved "next/step" support on multi-processor Alpha Tru64. + +The previous single-step mechanism could cause unpredictable problems, +including the random appearance of SIGSEGV or SIGTRAP signals. The use +of a software single-step mechanism prevents this. + *** Changes in GDB 5.2.1: * New targets. diff --git a/contrib/gdb/gdb/PROBLEMS b/contrib/gdb/gdb/PROBLEMS index 49d27967daa..2f533135ac0 100644 --- a/contrib/gdb/gdb/PROBLEMS +++ b/contrib/gdb/gdb/PROBLEMS @@ -1,32 +1,113 @@ - Known problems in GDB 5.2 + Known problems in GDB 6.1 See also: http://www.gnu.org/software/gdb/bugs/ -hppa2.0-hp-hpux10.20 --------------------- +*** Build problems -gdb/487: The top level make files used to build GDB are not compatible -with HP/UX make. As a workaround, use GNU make. +build/1458: comple failed on hpux11 -gdb/486: The HP/UX C compiler defaults to K&R mode but GDB only builds -with an ISO C compiler. The top level configuration incorrectly sets -CC to `cc' instead of `cc -Ae'. As a workaround, the correct compiler -can be specified as part of the configuration vis: +GDB 6.1 is known to have build problems on HP/UX 11.00 using the +vendor supplied compilers (GDB does build on HP/UX 11.11, and using +GCC). - $ 'CC=cc -Ae' ./configure +*** Misc +gdb/1560: Control-C does not always interrupt GDB. -s390*-*-* ---------- +When GDB is busy processing a command which takes a long time to +complete, hitting Control-C does not have the expected effect. +The command execution is not aborted, and the "QUIT" message confirming +the abortion is displayed only after the command has been completed. -gdb/513: GDB does not build on s390 GNU/Linux. The problem should be -fixed in more recent sources. +*** C++ support +gdb/931: GDB could be more generous when reading types C++ templates on input -i386-*-freebsd4.4* ------------------- +When the user types a template, GDB frequently requires the type to be +typed in a certain way (e.g. "const char*" as opposed to "const char *" +or "char const *" or "char const*"). -gdb/455: GDB doesn't build on a FreeBSD 4.4-STABLE system. The -problem is still being investigated. +gdb/1512: no canonical way to output names of C++ types + +We currently don't have any canonical way to output names of C++ types. +E.g. "const char *" versus "char const *"; more subtleties arise when +dealing with templates. + +gdb/1516: [regression] local classes, gcc 2.95.3, dwarf-2 + +With gcc 2.95.3 and the dwarf-2 debugging format, classes which are +defined locally to a function include the demangled name of the function +as part of their name. For example, if a function "foobar" contains a +local class definition "Local", gdb will say that the name of the class +type is "foobar__Fi.0:Local". + +This applies only to classes where the class type is defined inside a +function, not to variables defined with types that are defined somewhere +outside any function (which most types are). + +gdb/1588: names of c++ nested types in casts must be enclosed in quotes + +You must type + (gdb) print ('Foo::Bar') x +or + (gdb) print ('Foo::Bar' *) y +instead of + (gdb) print (Foo::Bar) x +or + (gdb) print (Foo::Bar *) y +respectively. + +gdb/1091: Constructor breakpoints ignored +gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set breakpoints + +When gcc 3.x compiles a C++ constructor or C++ destructor, it generates +2 or 3 different versions of the object code. These versions have +unique mangled names (they have to, in order for linking to work), but +they have identical source code names, which leads to a great deal of +confusion. Specifically, if you set a breakpoint in a constructor or a +destructor, gdb will put a breakpoint in one of the versions, but your +program may execute the other version. This makes it impossible to set +breakpoints reliably in constructors or destructors. + +gcc 3.x generates these multiple object code functions in order to +implement virtual base classes. gcc 2.x generated just one object code +function with a hidden parameter, but gcc 3.x conforms to a multi-vendor +ABI for C++ which requires multiple object code functions. + +*** Stack backtraces + +GDB's core code base has been updated to use a new backtrace +mechanism. This mechanism makes it possible to support new features +such DWARF 2 Call Frame Information (which in turn makes possible +backtraces through optimized code). + +Since this code is new, it is known to still have a few problems: + +gdb/1505: [regression] gdb prints a bad backtrace for a thread + +When backtracing a thread, gdb does not stop when it reaches the +outermost frame, instead continuing until it hits garbage. This is +sensitive to the operating system and thread library. + +hppa*-*-* +mips*-*-* + +The MIPS and HPPA backtrace code has only very recently been updated +to use GDB's new frame mechanism. At present there are still a few +problems, in particular backtraces through signal handlers do not +work. + +People encountering problems with these architectures should consult +GDB's web pages and mailing lists (http://www.gnu.org/software/gdb/) +to see if there are updates. + +powerpc*-*-* + +PowerPC architecture support, in 6.1, does not use the new frame code. + +Fortunately, PowerPC architecture support, in GDB's mainline sources, +have been updated. People encountering problems should consider +downloading a more current snapshot of GDB +(http://www.gnu.org/software/gdb/current/). diff --git a/contrib/gdb/gdb/README b/contrib/gdb/gdb/README index 47c490c2f0d..9a7cc05404c 100644 --- a/contrib/gdb/gdb/README +++ b/contrib/gdb/gdb/README @@ -1,5 +1,5 @@ - README for gdb-5.2.1 release - Updated 19 July, 2002 by Andrew Cagney + README for gdb-6.1 release + Updated 29 February, 2004 by Andrew Cagney This is GDB, the GNU source-level debugger. @@ -20,7 +20,7 @@ Unpacking and Installation -- quick overview In this release, the GDB debugger sources, the generic GNU include files, the BFD ("binary file description") library, the readline library, and other libraries all have directories of their own -underneath the gdb-5.2.1 directory. The idea is that a variety of GNU +underneath the gdb-6.1 directory. The idea is that a variety of GNU tools can share a common copy of these things. Be aware of variation over time--for example don't try to build gdb with a copy of bfd from a release other than the gdb release (such as a binutils release), @@ -29,8 +29,8 @@ Configuration scripts and makefiles exist to cruise up and down this directory tree and automatically build all the pieces in the right order. - When you unpack the gdb-5.2.1.tar.gz file, you'll find a directory -called `gdb-5.2.1', which contains: + When you unpack the gdb-6.1.tar.gz file, you'll find a directory +called `gdb-6.1', which contains: COPYING config.sub intl missing opcodes COPYING.LIB configure libiberty mkinstalldirs readline @@ -44,7 +44,7 @@ called `gdb-5.2.1', which contains: You can build GDB right in the source directory: - cd gdb-5.2.1 + cd gdb-6.1 ./configure make cp gdb/gdb /usr/local/bin/gdb (or wherever you want) @@ -58,18 +58,31 @@ You can build GDB in any empty build directory: mkdir build cd build - /gdb-5.2.1/configure + /gdb-6.1/configure make cp gdb/gdb /usr/local/bin/gdb (or wherever you want) (Building GDB with DJGPP tools for MS-DOS/MS-Windows is slightly -different; see the file gdb-5.2.1/gdb/config/djgpp/README for details.) +different; see the file gdb-6.1/gdb/config/djgpp/README for details.) This will configure and build all the libraries as well as GDB. If `configure' can't determine your system type, specify one as its argument, e.g., `./configure sun4' or `./configure decstation'. - If you get compiler errors during this stage, see the `Reporting + Make sure that your 'configure' line ends in 'gdb-6.1/configure': + + /berman/migchain/source/gdb-6.1/configure # RIGHT + /berman/migchain/source/gdb-6.1/gdb/configure # WRONG + + The gdb package contains several subdirectories, such as 'gdb', +'bfd', and 'readline'. If your 'configure' line ends in +'gdb-6.1/gdb/configure', then you are configuring only the gdb +subdirectory, not the whole gdb package. This leads to build errors +such as: + + make: *** No rule to make target `../bfd/bfd.h', needed by `gdb.o'. Stop. + + If you get other compiler errors during this stage, see the `Reporting Bugs' section below; there are a few known problems. GDB requires an ISO C (ANSI C) compiler. If you do not have an ISO @@ -94,7 +107,7 @@ documentation and TeX (or `texi2roff') to typeset the printed version. GDB includes an already formatted copy of the on-line Info version of this manual in the `gdb/doc' subdirectory. The main Info file is -`gdb-5.2.1/gdb/doc/gdb.info', and it refers to subordinate files +`gdb-6.1/gdb/doc/gdb.info', and it refers to subordinate files matching `gdb.info*' in the same directory. If necessary, you can print out these files, or read them with any editor; but they are easier to read using the `info' subsystem in GNU Emacs or the @@ -106,7 +119,7 @@ Info formatting programs, such as `texinfo-format-buffer' or `makeinfo'. If you have `makeinfo' installed, and are in the top level GDB -source directory (`gdb-5.2.1', in the case of version 5.2.1), you can make +source directory (`gdb-6.1', in the case of version 6.1), you can make the Info file by typing: cd gdb/doc @@ -115,7 +128,7 @@ the Info file by typing: If you want to typeset and print copies of this manual, you need TeX, a program to print its DVI output files, and `texinfo.tex', the Texinfo definitions file. This file is included in the GDB -distribution, in the directory `gdb-5.2.1/texinfo'. +distribution, in the directory `gdb-6.1/texinfo'. TeX is a typesetting program; it does not print files directly, but produces output files called DVI files. To print a typeset document, @@ -129,11 +142,11 @@ without any extension or a `.dvi' extension. This file tells TeX how to typeset a document written in Texinfo format. On its own, TeX cannot read, much less typeset a Texinfo file. `texinfo.tex' is distributed with GDB and is located in the -`gdb-5.2.1/texinfo' directory. +`gdb-6.1/texinfo' directory. If you have TeX and a DVI printer program installed, you can typeset and print this manual. First switch to the the `gdb' subdirectory of -the main source directory (for example, to `gdb-5.2.1/gdb') and then type: +the main source directory (for example, to `gdb-6.1/gdb') and then type: make doc/gdb.dvi @@ -156,55 +169,55 @@ preparing GDB for installation; you can then use `make' to build the a single directory, whose name is usually composed by appending the version number to `gdb'. - For example, the GDB version 5.2.1 distribution is in the `gdb-5.2.1' + For example, the GDB version 6.1 distribution is in the `gdb-6.1' directory. That directory contains: -`gdb-5.2.1/{COPYING,COPYING.LIB}' +`gdb-6.1/{COPYING,COPYING.LIB}' Standard GNU license files. Please read them. -`gdb-5.2.1/bfd' +`gdb-6.1/bfd' source for the Binary File Descriptor library -`gdb-5.2.1/config*' +`gdb-6.1/config*' script for configuring GDB, along with other support files -`gdb-5.2.1/gdb' +`gdb-6.1/gdb' the source specific to GDB itself -`gdb-5.2.1/include' +`gdb-6.1/include' GNU include files -`gdb-5.2.1/libiberty' +`gdb-6.1/libiberty' source for the `-liberty' free software library -`gdb-5.2.1/mmalloc' +`gdb-6.1/mmalloc' source for the GNU memory-mapped malloc package -`gdb-5.2.1/opcodes' +`gdb-6.1/opcodes' source for the library of opcode tables and disassemblers -`gdb-5.2.1/readline' +`gdb-6.1/readline' source for the GNU command-line interface NOTE: The readline library is compiled for use by GDB, but will not be installed on your system when "make install" is issued. -`gdb-5.2.1/sim' +`gdb-6.1/sim' source for some simulators (ARM, D10V, SPARC, M32R, MIPS, PPC, V850, etc) -`gdb-5.2.1/intl' +`gdb-6.1/intl' source for the GNU gettext library, for internationalization. This is slightly modified from the standalone gettext distribution you can get from GNU. -`gdb-5.2.1/texinfo' +`gdb-6.1/texinfo' The `texinfo.tex' file, which you need in order to make a printed manual using TeX. -`gdb-5.2.1/etc' +`gdb-6.1/etc' Coding standards, useful files for editing GDB, and other miscellanea. -`gdb-5.2.1/utils' +`gdb-6.1/utils' A grab bag of random utilities. Note: the following instructions are for building GDB on Unix or @@ -213,14 +226,14 @@ MS-DOS/MS-Windows are in the file gdb/config/djgpp/README. The simplest way to configure and build GDB is to run `configure' from the `gdb-VERSION-NUMBER' source directory, which in this example -is the `gdb-5.2.1' directory. +is the `gdb-6.1' directory. First switch to the `gdb-VERSION-NUMBER' source directory if you are not already in it; then run `configure'. For example: - cd gdb-5.2.1 + cd gdb-6.1 ./configure make @@ -236,8 +249,8 @@ you may need to run `sh' on it explicitly: sh configure If you run `configure' from a directory that contains source -directories for multiple libraries or programs, such as the `gdb-5.2.1' -source directory for version 5.2.1, `configure' creates configuration +directories for multiple libraries or programs, such as the `gdb-6.1' +source directory for version 6.1, `configure' creates configuration files for every directory level underneath (unless you tell it not to, with the `--norecursion' option). @@ -245,10 +258,10 @@ with the `--norecursion' option). directories in the GDB distribution, if you only want to configure that subdirectory; but be sure to specify a path to it. - For example, with version 5.2.1, type the following to configure only + For example, with version 6.1, type the following to configure only the `bfd' subdirectory: - cd gdb-5.2.1/bfd + cd gdb-6.1/bfd ../configure You can install `gdb' anywhere; it has no hardwired paths. However, @@ -277,13 +290,13 @@ directory. If the path to `configure' would be the same as the argument to `--srcdir', you can leave out the `--srcdir' option; it will be assumed.) - For example, with version 5.2.1, you can build GDB in a separate + For example, with version 6.1, you can build GDB in a separate directory for a Sun 4 like this: - cd gdb-5.2.1 + cd gdb-6.1 mkdir ../gdb-sun4 cd ../gdb-sun4 - ../gdb-5.2.1/configure + ../gdb-6.1/configure make When `configure' builds a configuration using a remote source @@ -304,8 +317,8 @@ called `configure' (or one of its subdirectories). The `Makefile' that `configure' generates in each source directory also runs recursively. If you type `make' in a source directory such -as `gdb-5.2.1' (or in a separate configured directory configured with -`--srcdir=PATH/gdb-5.2.1'), you will build all the required libraries, +as `gdb-6.1' (or in a separate configured directory configured with +`--srcdir=PATH/gdb-6.1'), you will build all the required libraries, and then build GDB. When you have multiple hosts or targets configured in separate @@ -348,7 +361,7 @@ you can use it to test your guesses on abbreviations--for example: Invalid configuration `i786v': machine `i786v' not recognized `config.sub' is also distributed in the GDB source directory -(`gdb-5.2.1', for version 5.2.1). +(`gdb-6.1', for version 6.1). `configure' options @@ -449,25 +462,15 @@ Linux. There are a number of remote interfaces for talking to existing ROM monitors and other hardware: - remote-adapt.c AMD 29000 "Adapt" - remote-array.c Array Tech RAID controller - remote-bug.c Motorola BUG monitor - remote-e7000.c Hitachi E7000 ICE - remote-eb.c AMD 29000 "EBMON" - remote-es.c Ericsson 1800 monitor + remote-e7000.c Renesas E7000 ICE remote-est.c EST emulator - remote-hms.c Hitachi Micro Systems H8/300 monitor + remote-hms.c Renesas Micro Systems H8/300 monitor remote-mips.c MIPS remote debugging protocol - remote-mm.c AMD 29000 "minimon" - remote-nindy.c Intel 960 "Nindy" - remote-nrom.c NetROM ROM emulator - remote-os9k.c PC running OS/9000 remote-rdi.c ARM with Angel monitor remote-rdp.c ARM with Demon monitor remote-sds.c PowerPC SDS monitor remote-sim.c Generalized simulator protocol remote-st.c Tandem ST-2000 monitor - remote-udi.c AMD 29000 using the AMD "Universal Debug Interface" remote-vx.c VxWorks realtime kernel Remote-vx.c and the vx-share subdirectory contain a remote @@ -475,14 +478,6 @@ interface for the VxWorks realtime kernel, which communicates over TCP using the Sun RPC library. This would be a useful starting point for other remote- via-ethernet back ends. - Remote-udi.c and the 29k-share subdirectory contain a remote -interface for AMD 29000 programs, which uses the AMD "Universal Debug -Interface". This allows GDB to talk to software simulators, -emulators, and/or bare hardware boards, via network or serial -interfaces. Note that GDB only provides an interface that speaks UDI, -not a complete solution. You will need something on the other end -that also speaks UDI. - Reporting Bugs in GDB ===================== @@ -496,7 +491,7 @@ As an alternative, the bug report can be submitted, via e-mail, to the address "bug-gdb@gnu.org". When submitting a bug, please include the GDB version number (e.g., -gdb-5.2.1), and how you configured it (e.g., "sun4" or "mach386 host, +gdb-6.1), and how you configured it (e.g., "sun4" or "mach386 host, i586-intel-synopsys target"). Since GDB now supports so many different configurations, it is important that you be precise about this. If at all possible, you should include the actual banner that @@ -513,7 +508,7 @@ Graphical interface to GDB -- X Windows, MS Windows Several graphical interfaces to GDB are available. You should check: - http://www.gnu.org/software/gdb/gui/ + http://www.gnu.org/software/gdb/links/ for an up-to-date list. @@ -551,17 +546,17 @@ ftp://sources.redhat.com/pub/dejagnu/ will contain a recent snapshot. Once DejaGNU is installed, you can run the tests in one of the following ways: - (1) cd gdb-5.2.1 + (1) cd gdb-6.1 make check-gdb or - (2) cd gdb-5.2.1/gdb + (2) cd gdb-6.1/gdb make check or - (3) cd gdb-5.2.1/gdb/testsuite + (3) cd gdb-6.1/gdb/testsuite make site.exp (builds the site specific file) runtest -tool gdb GDB=../gdb (or GDB= as appropriate) diff --git a/contrib/gdb/gdb/TODO b/contrib/gdb/gdb/TODO index ea46e9b3241..1ef9c22b0f2 100644 --- a/contrib/gdb/gdb/TODO +++ b/contrib/gdb/gdb/TODO @@ -114,12 +114,6 @@ The following cleanups have been identified as part of GDB 5.2. -- -Remove old code that does not use ui_out functions and all the related -"ifdef"s. This also allows the elimination of -DUI_OUT from -Makefile.in and configure.in. - --- - Compiler warnings. Eliminate warnings for all targets on at least one host for one of the @@ -177,14 +171,6 @@ Deprecate, if not delete, the following: how it relates to rawreg and the regnum is clear. - REGISTER_BYTES - The size of the cache can be computed - on the fly. - - IS_TRAPPED_INTERNALVAR - The pseudo registers should eventually make - this redundant. - -- Obsolete the targets: @@ -247,10 +233,6 @@ New languages come onto the scene all the time. Re: Various C++ things -value_headof/value_from_vtable_info are worthless, and should be -removed. The one place in printcmd.c that uses it should use the RTTI -functions. - RTTI for g++ should be using the typeinfo functions rather than the vtables. The typeinfo functions are always at offset 4 from the beginning of the vtable, and are always right. The vtables will have diff --git a/contrib/gdb/gdb/abug-rom.c b/contrib/gdb/gdb/abug-rom.c new file mode 100644 index 00000000000..543f70213f4 --- /dev/null +++ b/contrib/gdb/gdb/abug-rom.c @@ -0,0 +1,182 @@ +/* Remote debugging interface for ABug Rom monitor for GDB, the GNU debugger. + Copyright 1995, 1996, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + + Written by Rob Savoye of Cygnus Support + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "monitor.h" +#include "serial.h" +#include "regcache.h" + +#include "m68k-tdep.h" + +/* Prototypes for local functions. */ + +static void abug_open (char *args, int from_tty); + +static void +abug_supply_register (char *regname, int regnamelen, char *val, int vallen) +{ + int regno; + + if (regnamelen != 2) + return; + + switch (regname[0]) + { + case 'S': + if (regname[1] != 'R') + return; + regno = PS_REGNUM; + break; + case 'P': + if (regname[1] != 'C') + return; + regno = PC_REGNUM; + break; + case 'D': + if (regname[1] < '0' || regname[1] > '7') + return; + regno = regname[1] - '0' + M68K_D0_REGNUM; + break; + case 'A': + if (regname[1] < '0' || regname[1] > '7') + return; + regno = regname[1] - '0' + M68K_A0_REGNUM; + break; + default: + return; + } + + monitor_supply_register (regno, val); +} + +/* + * This array of registers needs to match the indexes used by GDB. The + * whole reason this exists is because the various ROM monitors use + * different names than GDB does, and don't support all the + * registers either. So, typing "info reg sp" becomes an "A7". + */ + +static const char * +abug_regname (int index) +{ + static char *regnames[] = + { + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", + "PC", + }; + + if ((index >= (sizeof (regnames) / sizeof (regnames[0]))) + || (index < 0) || (index >= NUM_REGS)) + return NULL; + else + return regnames[index]; +} + +/* + * Define the monitor command strings. Since these are passed directly + * through to a printf style function, we need can include formatting + * strings. We also need a CR or LF on the end. + */ + +static struct target_ops abug_ops; + +static char *abug_inits[] = +{"\r", NULL}; + +static struct monitor_ops abug_cmds; + +static void +init_abug_cmds (void) +{ + abug_cmds.flags = MO_CLR_BREAK_USES_ADDR; + abug_cmds.init = abug_inits; /* Init strings */ + abug_cmds.cont = "g\r"; /* continue command */ + abug_cmds.step = "t\r"; /* single step */ + abug_cmds.stop = NULL; /* interrupt command */ + abug_cmds.set_break = "br %x\r"; /* set a breakpoint */ + abug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */ + abug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */ + abug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */ + abug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */ + abug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */ + abug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */ + abug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ + abug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ + abug_cmds.setmem.term = NULL; /* setreg.term */ + abug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ + abug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */ + abug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */ + abug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */ + abug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ + abug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */ + abug_cmds.getmem.term = NULL; /* getmem.term */ + abug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ + abug_cmds.setreg.cmd = "rm %s %x\r"; /* setreg.cmd (name, value) */ + abug_cmds.setreg.resp_delim = "="; /* setreg.resp_delim */ + abug_cmds.setreg.term = "? "; /* setreg.term */ + abug_cmds.setreg.term_cmd = ".\r"; /* setreg.term_cmd */ + abug_cmds.getreg.cmd = "rm %s\r"; /* getreg.cmd (name) */ + abug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */ + abug_cmds.getreg.term = "? "; /* getreg.term */ + abug_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */ + abug_cmds.dump_registers = "rd\r"; /* dump_registers */ + abug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ + abug_cmds.supply_register = abug_supply_register; /* supply_register */ + abug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ + abug_cmds.load = "lo 0\r"; /* download command */ + abug_cmds.loadresp = "\n"; /* load response */ + abug_cmds.prompt = "135Bug>"; /* monitor command prompt */ + abug_cmds.line_term = "\r"; /* end-of-line terminator */ + abug_cmds.cmd_end = NULL; /* optional command terminator */ + abug_cmds.target = &abug_ops; /* target operations */ + abug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ + abug_cmds.regnames = NULL; /* registers names */ + abug_cmds.regname = abug_regname; + abug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ +}; + +static void +abug_open (char *args, int from_tty) +{ + monitor_open (args, &abug_cmds, from_tty); +} + +extern initialize_file_ftype _initialize_abug_rom; /* -Wmissing-prototypes */ + +void +_initialize_abug_rom (void) +{ + init_abug_cmds (); + init_monitor_ops (&abug_ops); + + abug_ops.to_shortname = "abug"; + abug_ops.to_longname = "ABug monitor"; + abug_ops.to_doc = "Debug via the ABug monitor.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + abug_ops.to_open = abug_open; + + add_target (&abug_ops); +} diff --git a/contrib/gdb/gdb/acinclude.m4 b/contrib/gdb/gdb/acinclude.m4 index 12f4c483a6b..a85ce024f2f 100644 --- a/contrib/gdb/gdb/acinclude.m4 +++ b/contrib/gdb/gdb/acinclude.m4 @@ -259,6 +259,7 @@ dnl not used, don't export to save symbols AC_SUBST(TCL_LD_FLAGS) dnl don't export, not used outside of configure AC_SUBST(TCL_LD_SEARCH_FLAGS) + AC_SUBST(TCL_CC_SEARCH_FLAGS) AC_SUBST(TCL_COMPAT_OBJS) AC_SUBST(TCL_RANLIB) AC_SUBST(TCL_BUILD_LIB_SPEC) @@ -733,132 +734,6 @@ AC_SUBST(ITKHDIR) #AC_SUBST(ITKLIB) ]) -# check for Tix headers. - -AC_DEFUN(CY_AC_PATH_TIXH, [ -AC_MSG_CHECKING(for Tix private headers. srcdir=${srcdir}) -if test x"${ac_cv_c_tixh}" = x ; then - for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do - if test -f $i/generic/tix.h ; then - ac_cv_c_tixh=`(cd $i/generic; pwd)` - break - fi - done -fi -if test x"${ac_cv_c_tixh}" = x ; then - TIXHDIR="# no Tix private headers found" - AC_MSG_ERROR([Can't find Tix private headers]) -fi -if test x"${ac_cv_c_tixh}" != x ; then - TIXHDIR="-I${ac_cv_c_tixh}" -fi -AC_SUBST(TIXHDIR) -]) - -AC_DEFUN(CY_AC_PATH_TIXCONFIG, [ -# -# Ok, lets find the tix configuration -# First, look for one uninstalled. -# the alternative search directory is invoked by --with-itkconfig -# - -if test x"${no_tix}" = x ; then - # we reset no_tix in case something fails here - no_tix=true - AC_ARG_WITH(tixconfig, [ --with-tixconfig Directory containing tix configuration (tixConfig.sh)], - with_tixconfig=${withval}) - AC_MSG_CHECKING([for Tix configuration]) - AC_CACHE_VAL(ac_cv_c_tixconfig,[ - - # First check to see if --with-tixconfig was specified. - if test x"${with_tixconfig}" != x ; then - if test -f "${with_tixconfig}/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)` - else - AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh]) - fi - fi - - # then check for a private Tix library - if test x"${ac_cv_c_tixconfig}" = x ; then - for i in \ - ../tix \ - `ls -dr ../tix 2>/dev/null` \ - ../../tix \ - `ls -dr ../../tix 2>/dev/null` \ - ../../../tix \ - `ls -dr ../../../tix 2>/dev/null` ; do - echo "**** Looking at $i - with ${configdir}" - if test -f "$i/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd $i; pwd)` - break - fi - done - fi - # check in a few common install locations - if test x"${ac_cv_c_tixconfig}" = x ; then - for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do - echo "**** Looking at $i" - if test -f "$i/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd $i; pwd)` - break - fi - done - fi - # check in a few other private locations - echo "**** Other private locations" - if test x"${ac_cv_c_tixconfig}" = x ; then - for i in \ - ${srcdir}/../tix \ - `ls -dr ${srcdir}/../tix 2>/dev/null` ; do - echo "**** Looking at $i - with ${configdir}" - if test -f "$i/${configdir}/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)` - break - fi - done - fi - ]) - if test x"${ac_cv_c_tixconfig}" = x ; then - TIXCONFIG="# no Tix configs found" - AC_MSG_WARN(Can't find Tix configuration definitions) - else - no_tix= - TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh - AC_MSG_RESULT(found $TIXCONFIG) - fi -fi - -]) - -# Defined as a separate macro so we don't have to cache the values -# from PATH_TIXCONFIG (because this can also be cached). -AC_DEFUN(CY_AC_LOAD_TIXCONFIG, [ - if test -f "$TIXCONFIG" ; then - . $TIXCONFIG - fi - - AC_SUBST(TIX_VERSION) -dnl not actually used, don't export to save symbols -dnl AC_SUBST(TIX_MAJOR_VERSION) -dnl AC_SUBST(TIX_MINOR_VERSION) -dnl AC_SUBST(TIX_DEFS) - -dnl not used, don't export to save symbols -dnl dnl AC_SUBST(TIX_LIB_FILE) - -dnl not used outside of configure -dnl AC_SUBST(TIX_LIBS) -dnl not used, don't export to save symbols -dnl AC_SUBST(TIX_PREFIX) - -dnl not used, don't export to save symbols -dnl AC_SUBST(TIX_EXEC_PREFIX) - -dnl AC_SUBST(TIX_BUILD_INCLUDES) - AC_SUBST(TIX_BUILD_LIB_SPEC) -dnl AC_SUBST(TIX_LIB_SPEC) -]) dnl sinclude(../gettext.m4) already included by bfd/acinclude.m4 dnl The lines below arrange for aclocal not to bring gettext.m4's @@ -976,3 +851,148 @@ case "x$am_cv_prog_cc_stdc" in *) CC="$CC $am_cv_prog_cc_stdc" ;; esac ]) + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + AC_ARG_WITH([libiconv-prefix], +[ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib], [ + for dir in `echo "$withval" | tr : ' '`; do + if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi + if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi + done + ]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS -liconv" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi + LIBICONV= + if test "$am_cv_lib_iconv" = yes; then + LIBICONV="-liconv" + fi + AC_SUBST(LIBICONV) +]) + +# AC_GNU_SOURCE +# ------------- +# FIXME: Remove thise once we start using Autoconf 2.5x (x>=4). +AC_DEFUN([AC_GNU_SOURCE], +[AC_BEFORE([$0], [AC_TRY_COMPILE])dnl +AC_BEFORE([$0], [AC_TRY_RUN])dnl +AC_DEFINE([_GNU_SOURCE]) +]) + +dnl written by Guido Draheim , original by Alexandre Oliva +dnl Version 1.3 (2001/03/02) +dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html + +AC_DEFUN([AC_DEFINE_DIR], [ + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo [$]$2` + ac_define_dir=`eval echo [$]ac_define_dir` + ifelse($3, , + AC_DEFINE_UNQUOTED($1, "$ac_define_dir"), + AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3)) +]) + +dnl See whether we need a declaration for a function. +dnl The result is highly dependent on the INCLUDES passed in, so make sure +dnl to use a different cache variable name in this macro if it is invoked +dnl in a different context somewhere else. +dnl gcc_AC_CHECK_DECL(SYMBOL, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]]) +AC_DEFUN(gcc_AC_CHECK_DECL, +[AC_MSG_CHECKING([whether $1 is declared]) +AC_CACHE_VAL(gcc_cv_have_decl_$1, +[AC_TRY_COMPILE([$4], +[#ifndef $1 +char *(*pfn) = (char *(*)) $1 ; +#endif], eval "gcc_cv_have_decl_$1=yes", eval "gcc_cv_have_decl_$1=no")]) +if eval "test \"`echo '$gcc_cv_have_decl_'$1`\" = yes"; then + AC_MSG_RESULT(yes) ; ifelse([$2], , :, [$2]) +else + AC_MSG_RESULT(no) ; ifelse([$3], , :, [$3]) +fi +])dnl + +dnl Check multiple functions to see whether each needs a declaration. +dnl Arrange to define HAVE_DECL_ to 0 or 1 as appropriate. +dnl gcc_AC_CHECK_DECLS(SYMBOLS, +dnl [ACTION-IF-NEEDED [, ACTION-IF-NOT-NEEDED [, INCLUDES]]]) +AC_DEFUN(gcc_AC_CHECK_DECLS, +[for ac_func in $1 +do +changequote(, )dnl + ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` +changequote([, ])dnl +gcc_AC_CHECK_DECL($ac_func, + [AC_DEFINE_UNQUOTED($ac_tr_decl, 1) $2], + [AC_DEFINE_UNQUOTED($ac_tr_decl, 0) $3], +dnl It is possible that the include files passed in here are local headers +dnl which supply a backup declaration for the relevant prototype based on +dnl the definition of (or lack of) the HAVE_DECL_ macro. If so, this test +dnl will always return success. E.g. see libiberty.h's handling of +dnl `basename'. To avoid this, we define the relevant HAVE_DECL_ macro to +dnl 1 so that any local headers used do not provide their own prototype +dnl during this test. +#undef $ac_tr_decl +#define $ac_tr_decl 1 + $4 +) +done +dnl Automatically generate config.h entries via autoheader. +if test x = y ; then + patsubst(translit([$1], [a-z], [A-Z]), [\w+], + [AC_DEFINE([HAVE_DECL_\&], 1, + [Define to 1 if we found this declaration otherwise define to 0.])])dnl +fi +]) + diff --git a/contrib/gdb/gdb/aclocal.m4 b/contrib/gdb/gdb/aclocal.m4 index 5b9d643f04d..40399a65d09 100644 --- a/contrib/gdb/gdb/aclocal.m4 +++ b/contrib/gdb/gdb/aclocal.m4 @@ -271,6 +271,7 @@ dnl not used, don't export to save symbols AC_SUBST(TCL_LD_FLAGS) dnl don't export, not used outside of configure AC_SUBST(TCL_LD_SEARCH_FLAGS) + AC_SUBST(TCL_CC_SEARCH_FLAGS) AC_SUBST(TCL_COMPAT_OBJS) AC_SUBST(TCL_RANLIB) AC_SUBST(TCL_BUILD_LIB_SPEC) @@ -745,132 +746,6 @@ AC_SUBST(ITKHDIR) #AC_SUBST(ITKLIB) ]) -# check for Tix headers. - -AC_DEFUN(CY_AC_PATH_TIXH, [ -AC_MSG_CHECKING(for Tix private headers. srcdir=${srcdir}) -if test x"${ac_cv_c_tixh}" = x ; then - for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do - if test -f $i/generic/tix.h ; then - ac_cv_c_tixh=`(cd $i/generic; pwd)` - break - fi - done -fi -if test x"${ac_cv_c_tixh}" = x ; then - TIXHDIR="# no Tix private headers found" - AC_MSG_ERROR([Can't find Tix private headers]) -fi -if test x"${ac_cv_c_tixh}" != x ; then - TIXHDIR="-I${ac_cv_c_tixh}" -fi -AC_SUBST(TIXHDIR) -]) - -AC_DEFUN(CY_AC_PATH_TIXCONFIG, [ -# -# Ok, lets find the tix configuration -# First, look for one uninstalled. -# the alternative search directory is invoked by --with-itkconfig -# - -if test x"${no_tix}" = x ; then - # we reset no_tix in case something fails here - no_tix=true - AC_ARG_WITH(tixconfig, [ --with-tixconfig Directory containing tix configuration (tixConfig.sh)], - with_tixconfig=${withval}) - AC_MSG_CHECKING([for Tix configuration]) - AC_CACHE_VAL(ac_cv_c_tixconfig,[ - - # First check to see if --with-tixconfig was specified. - if test x"${with_tixconfig}" != x ; then - if test -f "${with_tixconfig}/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)` - else - AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh]) - fi - fi - - # then check for a private Tix library - if test x"${ac_cv_c_tixconfig}" = x ; then - for i in \ - ../tix \ - `ls -dr ../tix 2>/dev/null` \ - ../../tix \ - `ls -dr ../../tix 2>/dev/null` \ - ../../../tix \ - `ls -dr ../../../tix 2>/dev/null` ; do - echo "**** Looking at $i - with ${configdir}" - if test -f "$i/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd $i; pwd)` - break - fi - done - fi - # check in a few common install locations - if test x"${ac_cv_c_tixconfig}" = x ; then - for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do - echo "**** Looking at $i" - if test -f "$i/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd $i; pwd)` - break - fi - done - fi - # check in a few other private locations - echo "**** Other private locations" - if test x"${ac_cv_c_tixconfig}" = x ; then - for i in \ - ${srcdir}/../tix \ - `ls -dr ${srcdir}/../tix 2>/dev/null` ; do - echo "**** Looking at $i - with ${configdir}" - if test -f "$i/${configdir}/tixConfig.sh" ; then - ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)` - break - fi - done - fi - ]) - if test x"${ac_cv_c_tixconfig}" = x ; then - TIXCONFIG="# no Tix configs found" - AC_MSG_WARN(Can't find Tix configuration definitions) - else - no_tix= - TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh - AC_MSG_RESULT(found $TIXCONFIG) - fi -fi - -]) - -# Defined as a separate macro so we don't have to cache the values -# from PATH_TIXCONFIG (because this can also be cached). -AC_DEFUN(CY_AC_LOAD_TIXCONFIG, [ - if test -f "$TIXCONFIG" ; then - . $TIXCONFIG - fi - - AC_SUBST(TIX_VERSION) -dnl not actually used, don't export to save symbols -dnl AC_SUBST(TIX_MAJOR_VERSION) -dnl AC_SUBST(TIX_MINOR_VERSION) -dnl AC_SUBST(TIX_DEFS) - -dnl not used, don't export to save symbols -dnl dnl AC_SUBST(TIX_LIB_FILE) - -dnl not used outside of configure -dnl AC_SUBST(TIX_LIBS) -dnl not used, don't export to save symbols -dnl AC_SUBST(TIX_PREFIX) - -dnl not used, don't export to save symbols -dnl AC_SUBST(TIX_EXEC_PREFIX) - -dnl AC_SUBST(TIX_BUILD_INCLUDES) - AC_SUBST(TIX_BUILD_LIB_SPEC) -dnl AC_SUBST(TIX_LIB_SPEC) -]) dnl sinclude(../gettext.m4) already included by bfd/acinclude.m4 dnl The lines below arrange for aclocal not to bring gettext.m4's @@ -985,6 +860,151 @@ case "x$am_cv_prog_cc_stdc" in esac ]) +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + AC_ARG_WITH([libiconv-prefix], +[ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib], [ + for dir in `echo "$withval" | tr : ' '`; do + if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi + if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi + done + ]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS -liconv" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi + LIBICONV= + if test "$am_cv_lib_iconv" = yes; then + LIBICONV="-liconv" + fi + AC_SUBST(LIBICONV) +]) + +# AC_GNU_SOURCE +# ------------- +# FIXME: Remove thise once we start using Autoconf 2.5x (x>=4). +AC_DEFUN([AC_GNU_SOURCE], +[AC_BEFORE([$0], [AC_TRY_COMPILE])dnl +AC_BEFORE([$0], [AC_TRY_RUN])dnl +AC_DEFINE([_GNU_SOURCE]) +]) + +dnl written by Guido Draheim , original by Alexandre Oliva +dnl Version 1.3 (2001/03/02) +dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html + +AC_DEFUN([AC_DEFINE_DIR], [ + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo [$]$2` + ac_define_dir=`eval echo [$]ac_define_dir` + ifelse($3, , + AC_DEFINE_UNQUOTED($1, "$ac_define_dir"), + AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3)) +]) + +dnl See whether we need a declaration for a function. +dnl The result is highly dependent on the INCLUDES passed in, so make sure +dnl to use a different cache variable name in this macro if it is invoked +dnl in a different context somewhere else. +dnl gcc_AC_CHECK_DECL(SYMBOL, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]]) +AC_DEFUN(gcc_AC_CHECK_DECL, +[AC_MSG_CHECKING([whether $1 is declared]) +AC_CACHE_VAL(gcc_cv_have_decl_$1, +[AC_TRY_COMPILE([$4], +[#ifndef $1 +char *(*pfn) = (char *(*)) $1 ; +#endif], eval "gcc_cv_have_decl_$1=yes", eval "gcc_cv_have_decl_$1=no")]) +if eval "test \"`echo '$gcc_cv_have_decl_'$1`\" = yes"; then + AC_MSG_RESULT(yes) ; ifelse([$2], , :, [$2]) +else + AC_MSG_RESULT(no) ; ifelse([$3], , :, [$3]) +fi +])dnl + +dnl Check multiple functions to see whether each needs a declaration. +dnl Arrange to define HAVE_DECL_ to 0 or 1 as appropriate. +dnl gcc_AC_CHECK_DECLS(SYMBOLS, +dnl [ACTION-IF-NEEDED [, ACTION-IF-NOT-NEEDED [, INCLUDES]]]) +AC_DEFUN(gcc_AC_CHECK_DECLS, +[for ac_func in $1 +do +changequote(, )dnl + ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` +changequote([, ])dnl +gcc_AC_CHECK_DECL($ac_func, + [AC_DEFINE_UNQUOTED($ac_tr_decl, 1) $2], + [AC_DEFINE_UNQUOTED($ac_tr_decl, 0) $3], +dnl It is possible that the include files passed in here are local headers +dnl which supply a backup declaration for the relevant prototype based on +dnl the definition of (or lack of) the HAVE_DECL_ macro. If so, this test +dnl will always return success. E.g. see libiberty.h's handling of +dnl `basename'. To avoid this, we define the relevant HAVE_DECL_ macro to +dnl 1 so that any local headers used do not provide their own prototype +dnl during this test. +#undef $ac_tr_decl +#define $ac_tr_decl 1 + $4 +) +done +dnl Automatically generate config.h entries via autoheader. +if test x = y ; then + patsubst(translit([$1], [a-z], [A-Z]), [\w+], + [AC_DEFINE([HAVE_DECL_\&], 1, + [Define to 1 if we found this declaration otherwise define to 0.])])dnl +fi +]) + + # Add --enable-maintainer-mode option to configure. # From Jim Meyering diff --git a/contrib/gdb/gdb/ada-exp.c b/contrib/gdb/gdb/ada-exp.c new file mode 100644 index 00000000000..b8dad7a43a6 --- /dev/null +++ b/contrib/gdb/gdb/ada-exp.c @@ -0,0 +1,2642 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + INT = 258, + NULL_PTR = 259, + CHARLIT = 260, + FLOAT = 261, + TYPENAME = 262, + BLOCKNAME = 263, + STRING = 264, + NAME = 265, + DOT_ID = 266, + OBJECT_RENAMING = 267, + DOT_ALL = 268, + LAST = 269, + REGNAME = 270, + INTERNAL_VARIABLE = 271, + ASSIGN = 272, + ELSE = 273, + THEN = 274, + XOR = 275, + OR = 276, + _AND_ = 277, + DOTDOT = 278, + IN = 279, + GEQ = 280, + LEQ = 281, + NOTEQUAL = 282, + UNARY = 283, + REM = 284, + MOD = 285, + NOT = 286, + ABS = 287, + STARSTAR = 288, + TICK_LENGTH = 289, + TICK_LAST = 290, + TICK_FIRST = 291, + TICK_ADDRESS = 292, + TICK_ACCESS = 293, + TICK_MODULUS = 294, + TICK_MIN = 295, + TICK_MAX = 296, + TICK_VAL = 297, + TICK_TAG = 298, + TICK_SIZE = 299, + TICK_RANGE = 300, + TICK_POS = 301, + ARROW = 302, + NEW = 303 + }; +#endif +#define INT 258 +#define NULL_PTR 259 +#define CHARLIT 260 +#define FLOAT 261 +#define TYPENAME 262 +#define BLOCKNAME 263 +#define STRING 264 +#define NAME 265 +#define DOT_ID 266 +#define OBJECT_RENAMING 267 +#define DOT_ALL 268 +#define LAST 269 +#define REGNAME 270 +#define INTERNAL_VARIABLE 271 +#define ASSIGN 272 +#define ELSE 273 +#define THEN 274 +#define XOR 275 +#define OR 276 +#define _AND_ 277 +#define DOTDOT 278 +#define IN 279 +#define GEQ 280 +#define LEQ 281 +#define NOTEQUAL 282 +#define UNARY 283 +#define REM 284 +#define MOD 285 +#define NOT 286 +#define ABS 287 +#define STARSTAR 288 +#define TICK_LENGTH 289 +#define TICK_LAST 290 +#define TICK_FIRST 291 +#define TICK_ADDRESS 292 +#define TICK_ACCESS 293 +#define TICK_MODULUS 294 +#define TICK_MIN 295 +#define TICK_MAX 296 +#define TICK_VAL 297 +#define TICK_TAG 298 +#define TICK_SIZE 299 +#define TICK_RANGE 300 +#define TICK_POS 301 +#define ARROW 302 +#define NEW 303 + + + + +/* Copy the first part of user declarations. */ +#line 38 "ada-exp.y" + + +#include "defs.h" +#include +#include +#include "expression.h" +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "ada-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "frame.h" +#include "block.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in gdb. These are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +/* NOTE: This is clumsy, especially since BISON and FLEX provide --prefix + options. I presume we are maintaining it to accommodate systems + without BISON? (PNH) */ + +#define yymaxdepth ada_maxdepth +#define yyparse _ada_parse /* ada_parse calls this after initialization */ +#define yylex ada_lex +#define yyerror ada_error +#define yylval ada_lval +#define yychar ada_char +#define yydebug ada_debug +#define yypact ada_pact +#define yyr1 ada_r1 +#define yyr2 ada_r2 +#define yydef ada_def +#define yychk ada_chk +#define yypgo ada_pgo +#define yyact ada_act +#define yyexca ada_exca +#define yyerrflag ada_errflag +#define yynerrs ada_nerrs +#define yyps ada_ps +#define yypv ada_pv +#define yys ada_s +#define yy_yys ada_yys +#define yystate ada_state +#define yytmp ada_tmp +#define yyv ada_v +#define yy_yyv ada_yyv +#define yyval ada_val +#define yylloc ada_lloc +#define yyreds ada_reds /* With YYDEBUG defined */ +#define yytoks ada_toks /* With YYDEBUG defined */ +#define yyname ada_name /* With YYDEBUG defined */ +#define yyrule ada_rule /* With YYDEBUG defined */ + +#ifndef YYDEBUG +#define YYDEBUG 1 /* Default to yydebug support */ +#endif + +#define YYFPRINTF parser_fprintf + +struct name_info { + struct symbol* sym; + struct minimal_symbol* msym; + struct block* block; + struct stoken stoken; +}; + +/* If expression is in the context of TYPE'(...), then TYPE, else + * NULL. */ +static struct type* type_qualifier; + +int yyparse (void); + +static int yylex (void); + +void yyerror (char *); + +static struct stoken string_to_operator (struct stoken); + +static void write_attribute_call0 (enum ada_attribute); + +static void write_attribute_call1 (enum ada_attribute, LONGEST); + +static void write_attribute_calln (enum ada_attribute, int); + +static void write_object_renaming (struct block*, struct symbol*); + +static void write_var_from_name (struct block*, struct name_info); + +static LONGEST +convert_char_literal (struct type*, LONGEST); + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 137 "ada-exp.y" +typedef union YYSTYPE { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; + struct type *tval; + struct stoken sval; + struct name_info ssym; + int voidval; + struct block *bval; + struct internalvar *ivar; + + } YYSTYPE; +/* Line 191 of yacc.c. */ +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or xmalloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC xmalloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 44 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 1067 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 68 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 15 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 98 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 184 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 303 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 34, 63, + 57, 62, 36, 32, 64, 33, 56, 37, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, + 24, 23, 25, 2, 31, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 58, 2, 67, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 65, 2, 66, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 26, 27, + 28, 29, 30, 35, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 59, 60 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 13, 16, 19, 24, + 29, 30, 38, 39, 46, 50, 52, 54, 56, 58, + 60, 64, 67, 70, 73, 76, 77, 79, 83, 87, + 93, 98, 102, 106, 110, 114, 118, 122, 126, 130, + 134, 138, 142, 146, 152, 158, 162, 169, 176, 181, + 185, 189, 193, 197, 202, 206, 211, 215, 218, 221, + 225, 229, 233, 236, 239, 247, 255, 261, 265, 269, + 273, 279, 282, 283, 287, 289, 291, 292, 294, 296, + 298, 300, 302, 305, 307, 310, 312, 315, 317, 319, + 321, 323, 326, 328, 331, 334, 338, 341, 344 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 69, 0, -1, 70, -1, 82, -1, 74, -1, 70, + 61, 74, -1, 71, 13, -1, 71, 11, -1, 71, + 57, 75, 62, -1, 82, 57, 74, 62, -1, -1, + 82, 63, 73, 72, 57, 74, 62, -1, -1, 71, + 57, 74, 26, 74, 62, -1, 57, 70, 62, -1, + 79, -1, 15, -1, 16, -1, 71, -1, 14, -1, + 74, 17, 74, -1, 33, 74, -1, 32, 74, -1, + 40, 74, -1, 41, 74, -1, -1, 74, -1, 80, + 59, 74, -1, 75, 64, 74, -1, 75, 64, 80, + 59, 74, -1, 65, 82, 66, 74, -1, 74, 42, + 74, -1, 74, 36, 74, -1, 74, 37, 74, -1, + 74, 38, 74, -1, 74, 39, 74, -1, 74, 31, + 74, -1, 74, 32, 74, -1, 74, 34, 74, -1, + 74, 33, 74, -1, 74, 23, 74, -1, 74, 30, + 74, -1, 74, 29, 74, -1, 74, 27, 74, 26, + 74, -1, 74, 27, 74, 54, 76, -1, 74, 27, + 7, -1, 74, 40, 27, 74, 26, 74, -1, 74, + 40, 27, 74, 54, 76, -1, 74, 40, 27, 7, + -1, 74, 28, 74, -1, 74, 24, 74, -1, 74, + 25, 74, -1, 74, 22, 74, -1, 74, 22, 19, + 74, -1, 74, 21, 74, -1, 74, 21, 18, 74, + -1, 74, 20, 74, -1, 71, 47, -1, 71, 46, + -1, 71, 45, 76, -1, 71, 44, 76, -1, 71, + 43, 76, -1, 71, 53, -1, 71, 52, -1, 78, + 49, 57, 74, 64, 74, 62, -1, 78, 50, 57, + 74, 64, 74, 62, -1, 78, 55, 57, 74, 62, + -1, 77, 45, 76, -1, 77, 44, 76, -1, 77, + 43, 76, -1, 77, 51, 57, 74, 62, -1, 77, + 48, -1, -1, 57, 3, 62, -1, 7, -1, 77, + -1, -1, 3, -1, 5, -1, 6, -1, 4, -1, + 9, -1, 60, 7, -1, 10, -1, 81, 10, -1, + 12, -1, 81, 12, -1, 10, -1, 7, -1, 12, + -1, 8, -1, 81, 8, -1, 7, -1, 81, 7, + -1, 7, 47, -1, 81, 7, 47, -1, 36, 74, + -1, 34, 74, -1, 74, 58, 74, 67, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 208, 208, 209, 215, 216, 221, 225, 232, 240, + 248, 248, 259, 263, 267, 270, 273, 280, 288, 291, + 298, 302, 306, 310, 314, 318, 321, 323, 325, 327, + 331, 341, 345, 349, 353, 357, 361, 365, 369, 373, + 377, 381, 385, 389, 393, 399, 406, 411, 419, 429, + 433, 437, 441, 445, 449, 453, 457, 461, 463, 469, + 471, 473, 475, 477, 479, 481, 483, 485, 487, 489, + 491, 493, 497, 499, 504, 511, 513, 519, 527, 539, + 547, 555, 582, 586, 587, 589, 590, 594, 595, 596, + 599, 601, 606, 607, 608, 610, 617, 619, 621 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "INT", "NULL_PTR", "CHARLIT", "FLOAT", + "TYPENAME", "BLOCKNAME", "STRING", "NAME", "DOT_ID", "OBJECT_RENAMING", + "DOT_ALL", "LAST", "REGNAME", "INTERNAL_VARIABLE", "ASSIGN", "ELSE", + "THEN", "XOR", "OR", "_AND_", "'='", "'<'", "'>'", "DOTDOT", "IN", + "GEQ", "LEQ", "NOTEQUAL", "'@'", "'+'", "'-'", "'&'", "UNARY", "'*'", + "'/'", "REM", "MOD", "NOT", "ABS", "STARSTAR", "TICK_LENGTH", + "TICK_LAST", "TICK_FIRST", "TICK_ADDRESS", "TICK_ACCESS", + "TICK_MODULUS", "TICK_MIN", "TICK_MAX", "TICK_VAL", "TICK_TAG", + "TICK_SIZE", "TICK_RANGE", "TICK_POS", "'.'", "'('", "'['", "ARROW", + "NEW", "';'", "')'", "'''", "','", "'{'", "'}'", "']'", "$accept", + "start", "exp1", "simple_exp", "@1", "save_qualifier", "exp", "arglist", + "tick_arglist", "type_prefix", "opt_type_prefix", "variable", + "any_name", "block", "type", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 61, 60, 62, 278, 279, 280, 281, + 282, 64, 43, 45, 38, 283, 42, 47, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 46, 40, 91, 302, + 303, 59, 41, 39, 44, 123, 125, 93 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 68, 69, 69, 70, 70, 71, 71, 71, 71, + 72, 71, 73, 71, 71, 71, 71, 71, 74, 71, + 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 76, 76, 77, 78, 78, 74, 74, 74, + 74, 74, 74, 79, 79, 79, 79, 80, 80, 80, + 81, 81, 82, 82, 82, 82, 74, 74, 74 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 1, 3, 2, 2, 4, 4, + 0, 7, 0, 6, 3, 1, 1, 1, 1, 1, + 3, 2, 2, 2, 2, 0, 1, 3, 3, 5, + 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 5, 3, 6, 6, 4, 3, + 3, 3, 3, 4, 3, 4, 3, 2, 2, 3, + 3, 3, 2, 2, 7, 7, 5, 3, 3, 3, + 5, 2, 0, 3, 1, 1, 0, 1, 1, 1, + 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 2, 2, 3, 2, 2, 4 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 76, 77, 80, 78, 79, 74, 90, 81, 83, 85, + 19, 16, 17, 76, 76, 76, 76, 76, 76, 76, + 0, 0, 0, 2, 18, 4, 75, 0, 15, 0, + 3, 94, 22, 0, 21, 97, 96, 23, 24, 0, + 82, 92, 0, 0, 1, 76, 7, 6, 72, 72, + 72, 58, 57, 63, 62, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 0, 76, 76, 72, 72, + 72, 71, 0, 0, 0, 0, 93, 91, 84, 86, + 76, 12, 14, 76, 5, 0, 61, 60, 59, 74, + 83, 85, 26, 0, 0, 20, 56, 76, 54, 76, + 52, 40, 50, 51, 45, 0, 49, 42, 41, 36, + 37, 39, 38, 32, 33, 34, 35, 76, 31, 0, + 69, 68, 67, 76, 76, 76, 76, 95, 0, 10, + 30, 0, 76, 8, 76, 76, 55, 53, 76, 72, + 48, 0, 98, 0, 0, 0, 0, 9, 0, 73, + 0, 28, 0, 27, 43, 44, 76, 72, 70, 76, + 76, 66, 76, 13, 76, 46, 47, 0, 0, 0, + 29, 64, 65, 11 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 22, 23, 24, 158, 139, 25, 103, 96, 26, + 27, 28, 104, 29, 33 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -44 +static const short yypact[] = +{ + 251, -44, -44, -44, -44, 15, -44, -44, -44, -44, + -44, -44, -44, 251, 251, 251, 251, 251, 251, 251, + 17, 2, 31, 10, 55, 947, -18, 20, -44, 118, + -29, -44, 374, -29, 374, 18, 18, 374, 374, -21, + -44, 32, 66, 16, -44, 251, -44, -44, 24, 24, + 24, -44, -44, -44, -44, 133, 251, 251, 173, 212, + 251, 251, 251, 290, 251, 251, 251, 251, 251, 251, + 251, 251, 251, 251, 251, 59, 251, 251, 24, 24, + 24, -44, 35, 38, 40, 47, 58, -44, -44, -44, + 251, -44, -44, 251, 947, 107, -44, -44, -44, 56, + 52, 57, 915, 3, 68, 979, 1002, 251, 1002, 251, + 1002, -20, -20, -20, 1004, 837, -20, -20, -20, 51, + 374, 374, 374, -19, -19, -19, -19, 329, -19, 414, + -44, -44, -44, 251, 251, 251, 251, -44, 536, -44, + 18, 71, 251, -44, 368, 251, 1002, 1002, 251, 24, + 1004, 876, -44, 579, 446, 491, 622, -44, 60, -44, + 665, 947, 75, 947, -20, -44, 251, 24, -44, 251, + 251, -44, 251, -44, 251, -20, -44, 708, 751, 794, + 947, -44, -44, -44 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -44, -44, 99, -44, -44, -44, -13, -44, -43, -44, + -44, -44, 0, 125, 8 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -93 +static const short yytable[] = +{ + 32, 34, 35, 36, 37, 38, 97, 98, 30, 41, + 6, 67, 68, 69, 70, -92, 71, 72, 73, 74, + 75, 75, 76, 76, 40, 78, 79, 80, 90, 43, + 81, 44, 94, 82, 91, 130, 131, 132, 77, 77, + 45, 92, 102, 105, 106, 108, 110, 111, 112, 113, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 31, 128, 129, 143, 46, 144, 47, 83, + 84, 45, -92, 86, 87, 85, 77, 138, -92, 31, + 140, 95, 93, 68, 69, 70, 127, 71, 72, 73, + 74, 75, 133, 76, 146, 134, 147, 135, 48, 49, + 50, 51, 52, 31, 136, 137, 165, 53, 54, 77, + 141, -87, 55, -92, 151, -88, -89, 172, 39, -92, + 153, 154, 155, 156, 176, 86, 87, 145, 88, 160, + 89, 161, 163, 159, 174, 164, 1, 2, 3, 4, + 99, 6, 7, 100, 162, 101, 42, 10, 11, 12, + 0, 0, 0, 175, 0, 0, 177, 178, 0, 179, + 0, 180, 0, 0, 0, 13, 14, 15, 0, 16, + 0, 0, 0, 17, 18, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 0, 9, 0, 10, 11, 12, + 19, 107, 0, 20, 0, -25, 0, -25, 21, 0, + 0, 0, 0, 0, 0, 13, 14, 15, 0, 16, + 0, 0, 0, 17, 18, 1, 2, 3, 4, 5, + 6, 7, 8, 0, 9, 0, 10, 11, 12, 0, + 19, 109, 0, 20, 0, 0, 0, 0, 21, 0, + 0, 0, 0, 0, 13, 14, 15, 0, 16, 0, + 0, 0, 17, 18, 1, 2, 3, 4, 5, 6, + 7, 8, 0, 9, 0, 10, 11, 12, 0, 19, + 0, 0, 20, 0, 0, 0, 0, 21, 0, 0, + 0, 0, 0, 13, 14, 15, 0, 16, 0, 0, + 0, 17, 18, 1, 2, 3, 4, 114, 6, 7, + 8, 0, 9, 0, 10, 11, 12, 0, 19, 0, + 0, 20, 0, 0, 0, 0, 21, 0, 0, 0, + 0, 0, 13, 14, 15, 0, 16, 0, 0, 0, + 17, 18, 1, 2, 3, 4, 150, 6, 7, 8, + 0, 9, 0, 10, 11, 12, 0, 19, 0, 0, + 20, 0, 0, 0, 0, 21, 0, 0, 0, 0, + 0, 13, 14, 15, 0, 16, 0, 0, 0, 17, + 18, 1, 2, 3, 4, 99, 6, 7, 100, 0, + 101, 0, 10, 11, 12, 0, 19, 0, 0, 20, + 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, + 13, 14, 15, 0, 16, 0, 0, 0, 17, 18, + 71, 72, 73, 74, 75, 0, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, + 0, 56, 77, 21, 57, 58, 59, 60, 61, 62, + 0, 63, 64, 65, 66, 67, 68, 69, 70, 0, + 71, 72, 73, 74, 75, 0, 76, 0, 0, 0, + 0, 0, 0, 56, 0, 0, 57, 58, 59, 60, + 61, 62, 77, 63, 64, 65, 66, 67, 68, 69, + 70, 152, 71, 72, 73, 74, 75, 0, 76, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 0, 0, 0, 56, 0, + 169, 57, 58, 59, 60, 61, 62, 0, 63, 64, + 65, 66, 67, 68, 69, 70, 0, 71, 72, 73, + 74, 75, 0, 76, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, + 0, 0, 0, 56, 0, 170, 57, 58, 59, 60, + 61, 62, 0, 63, 64, 65, 66, 67, 68, 69, + 70, 0, 71, 72, 73, 74, 75, 0, 76, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 0, 56, 0, 157, 57, + 58, 59, 60, 61, 62, 0, 63, 64, 65, 66, + 67, 68, 69, 70, 0, 71, 72, 73, 74, 75, + 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 77, 0, 56, + 0, 168, 57, 58, 59, 60, 61, 62, 0, 63, + 64, 65, 66, 67, 68, 69, 70, 0, 71, 72, + 73, 74, 75, 0, 76, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 77, 0, 56, 0, 171, 57, 58, 59, 60, 61, + 62, 0, 63, 64, 65, 66, 67, 68, 69, 70, + 0, 71, 72, 73, 74, 75, 0, 76, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 77, 0, 56, 0, 173, 57, 58, + 59, 60, 61, 62, 0, 63, 64, 65, 66, 67, + 68, 69, 70, 0, 71, 72, 73, 74, 75, 0, + 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 77, 0, 56, 0, + 181, 57, 58, 59, 60, 61, 62, 0, 63, 64, + 65, 66, 67, 68, 69, 70, 0, 71, 72, 73, + 74, 75, 0, 76, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, + 0, 56, 0, 182, 57, 58, 59, 60, 61, 62, + 0, 63, 64, 65, 66, 67, 68, 69, 70, 0, + 71, 72, 73, 74, 75, 0, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 56, 0, 183, 57, 58, 59, + 60, 61, 62, 148, 63, 64, 65, 66, 67, 68, + 69, 70, 0, 71, 72, 73, 74, 75, 0, 76, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 149, 0, 56, 0, 77, 57, 58, 59, 60, + 61, 62, 166, 63, 64, 65, 66, 67, 68, 69, + 70, 0, 71, 72, 73, 74, 75, 0, 76, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 167, 0, 56, 0, 77, 57, 58, 59, 60, 61, + 62, 142, 63, 64, 65, 66, 67, 68, 69, 70, + 0, 71, 72, 73, 74, 75, 0, 76, 0, 0, + 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, + 60, 61, 62, 77, 63, 64, 65, 66, 67, 68, + 69, 70, 0, 71, 72, 73, 74, 75, 0, 76, + 0, 0, 0, 0, 0, 0, -93, 0, 0, 57, + 58, 59, 60, 61, 62, 77, 63, 64, 65, 66, + 67, 68, 69, 70, 0, 71, 72, 73, 74, 75, + 0, 76, 0, 0, 0, 60, 61, 62, 0, 63, + 64, 65, 66, 67, 68, 69, 70, 77, 71, 72, + 73, 74, 75, 0, 76, 0, 0, -74, -74, -74, + 0, 31, -74, -74, -74, -74, 0, 0, 0, -74, + 77, -92, 0, 0, 0, 0, 0, -92 +}; + +static const short yycheck[] = +{ + 13, 14, 15, 16, 17, 18, 49, 50, 0, 7, + 8, 31, 32, 33, 34, 0, 36, 37, 38, 39, + 40, 40, 42, 42, 7, 43, 44, 45, 57, 21, + 48, 0, 45, 51, 63, 78, 79, 80, 58, 58, + 61, 62, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 47, 76, 77, 62, 11, 64, 13, 49, + 50, 61, 57, 7, 8, 55, 58, 90, 63, 47, + 93, 57, 66, 32, 33, 34, 27, 36, 37, 38, + 39, 40, 57, 42, 107, 57, 109, 57, 43, 44, + 45, 46, 47, 47, 57, 47, 149, 52, 53, 58, + 3, 59, 57, 57, 127, 59, 59, 57, 19, 63, + 133, 134, 135, 136, 167, 7, 8, 59, 10, 142, + 12, 144, 145, 62, 59, 148, 3, 4, 5, 6, + 7, 8, 9, 10, 144, 12, 21, 14, 15, 16, + -1, -1, -1, 166, -1, -1, 169, 170, -1, 172, + -1, 174, -1, -1, -1, 32, 33, 34, -1, 36, + -1, -1, -1, 40, 41, -1, 3, 4, 5, 6, + 7, 8, 9, 10, -1, 12, -1, 14, 15, 16, + 57, 18, -1, 60, -1, 62, -1, 64, 65, -1, + -1, -1, -1, -1, -1, 32, 33, 34, -1, 36, + -1, -1, -1, 40, 41, 3, 4, 5, 6, 7, + 8, 9, 10, -1, 12, -1, 14, 15, 16, -1, + 57, 19, -1, 60, -1, -1, -1, -1, 65, -1, + -1, -1, -1, -1, 32, 33, 34, -1, 36, -1, + -1, -1, 40, 41, 3, 4, 5, 6, 7, 8, + 9, 10, -1, 12, -1, 14, 15, 16, -1, 57, + -1, -1, 60, -1, -1, -1, -1, 65, -1, -1, + -1, -1, -1, 32, 33, 34, -1, 36, -1, -1, + -1, 40, 41, 3, 4, 5, 6, 7, 8, 9, + 10, -1, 12, -1, 14, 15, 16, -1, 57, -1, + -1, 60, -1, -1, -1, -1, 65, -1, -1, -1, + -1, -1, 32, 33, 34, -1, 36, -1, -1, -1, + 40, 41, 3, 4, 5, 6, 7, 8, 9, 10, + -1, 12, -1, 14, 15, 16, -1, 57, -1, -1, + 60, -1, -1, -1, -1, 65, -1, -1, -1, -1, + -1, 32, 33, 34, -1, 36, -1, -1, -1, 40, + 41, 3, 4, 5, 6, 7, 8, 9, 10, -1, + 12, -1, 14, 15, 16, -1, 57, -1, -1, 60, + -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, + 32, 33, 34, -1, 36, -1, -1, -1, 40, 41, + 36, 37, 38, 39, 40, -1, 42, -1, -1, -1, + -1, -1, -1, -1, -1, 57, -1, -1, 60, -1, + -1, 17, 58, 65, 20, 21, 22, 23, 24, 25, + -1, 27, 28, 29, 30, 31, 32, 33, 34, -1, + 36, 37, 38, 39, 40, -1, 42, -1, -1, -1, + -1, -1, -1, 17, -1, -1, 20, 21, 22, 23, + 24, 25, 58, 27, 28, 29, 30, 31, 32, 33, + 34, 67, 36, 37, 38, 39, 40, -1, 42, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 58, -1, -1, -1, 17, -1, + 64, 20, 21, 22, 23, 24, 25, -1, 27, 28, + 29, 30, 31, 32, 33, 34, -1, 36, 37, 38, + 39, 40, -1, 42, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, + -1, -1, -1, 17, -1, 64, 20, 21, 22, 23, + 24, 25, -1, 27, 28, 29, 30, 31, 32, 33, + 34, -1, 36, 37, 38, 39, 40, -1, 42, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 58, -1, 17, -1, 62, 20, + 21, 22, 23, 24, 25, -1, 27, 28, 29, 30, + 31, 32, 33, 34, -1, 36, 37, 38, 39, 40, + -1, 42, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 58, -1, 17, + -1, 62, 20, 21, 22, 23, 24, 25, -1, 27, + 28, 29, 30, 31, 32, 33, 34, -1, 36, 37, + 38, 39, 40, -1, 42, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 58, -1, 17, -1, 62, 20, 21, 22, 23, 24, + 25, -1, 27, 28, 29, 30, 31, 32, 33, 34, + -1, 36, 37, 38, 39, 40, -1, 42, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 58, -1, 17, -1, 62, 20, 21, + 22, 23, 24, 25, -1, 27, 28, 29, 30, 31, + 32, 33, 34, -1, 36, 37, 38, 39, 40, -1, + 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 58, -1, 17, -1, + 62, 20, 21, 22, 23, 24, 25, -1, 27, 28, + 29, 30, 31, 32, 33, 34, -1, 36, 37, 38, + 39, 40, -1, 42, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, + -1, 17, -1, 62, 20, 21, 22, 23, 24, 25, + -1, 27, 28, 29, 30, 31, 32, 33, 34, -1, + 36, 37, 38, 39, 40, -1, 42, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 58, -1, 17, -1, 62, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, -1, 36, 37, 38, 39, 40, -1, 42, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 54, -1, 17, -1, 58, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, -1, 36, 37, 38, 39, 40, -1, 42, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 54, -1, 17, -1, 58, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + -1, 36, 37, 38, 39, 40, -1, 42, -1, -1, + -1, -1, -1, -1, 17, -1, -1, 20, 21, 22, + 23, 24, 25, 58, 27, 28, 29, 30, 31, 32, + 33, 34, -1, 36, 37, 38, 39, 40, -1, 42, + -1, -1, -1, -1, -1, -1, 17, -1, -1, 20, + 21, 22, 23, 24, 25, 58, 27, 28, 29, 30, + 31, 32, 33, 34, -1, 36, 37, 38, 39, 40, + -1, 42, -1, -1, -1, 23, 24, 25, -1, 27, + 28, 29, 30, 31, 32, 33, 34, 58, 36, 37, + 38, 39, 40, -1, 42, -1, -1, 43, 44, 45, + -1, 47, 48, 49, 50, 51, -1, -1, -1, 55, + 58, 57, -1, -1, -1, -1, -1, 63 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 12, + 14, 15, 16, 32, 33, 34, 36, 40, 41, 57, + 60, 65, 69, 70, 71, 74, 77, 78, 79, 81, + 82, 47, 74, 82, 74, 74, 74, 74, 74, 70, + 7, 7, 81, 82, 0, 61, 11, 13, 43, 44, + 45, 46, 47, 52, 53, 57, 17, 20, 21, 22, + 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, + 34, 36, 37, 38, 39, 40, 42, 58, 43, 44, + 45, 48, 51, 49, 50, 55, 7, 8, 10, 12, + 57, 63, 62, 66, 74, 57, 76, 76, 76, 7, + 10, 12, 74, 75, 80, 74, 74, 18, 74, 19, + 74, 74, 74, 74, 7, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 27, 74, 74, + 76, 76, 76, 57, 57, 57, 57, 47, 74, 73, + 74, 3, 26, 62, 64, 59, 74, 74, 26, 54, + 7, 74, 67, 74, 74, 74, 74, 62, 72, 62, + 74, 74, 80, 74, 74, 76, 26, 54, 62, 64, + 64, 62, 57, 62, 59, 74, 76, 74, 74, 74, + 74, 62, 62, 62 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to xreallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to xreallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: +#line 209 "ada-exp.y" + { write_exp_elt_opcode (OP_TYPE); + write_exp_elt_type (yyvsp[0].tval); + write_exp_elt_opcode (OP_TYPE); } + break; + + case 5: +#line 217 "ada-exp.y" + { write_exp_elt_opcode (BINOP_COMMA); } + break; + + case 6: +#line 222 "ada-exp.y" + { write_exp_elt_opcode (UNOP_IND); } + break; + + case 7: +#line 226 "ada-exp.y" + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (yyvsp[0].ssym.stoken); + write_exp_elt_opcode (STRUCTOP_STRUCT); + } + break; + + case 8: +#line 233 "ada-exp.y" + { + write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst (yyvsp[-1].lval); + write_exp_elt_opcode (OP_FUNCALL); + } + break; + + case 9: +#line 241 "ada-exp.y" + { + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (yyvsp[-3].tval); + write_exp_elt_opcode (UNOP_CAST); + } + break; + + case 10: +#line 248 "ada-exp.y" + { type_qualifier = yyvsp[-2].tval; } + break; + + case 11: +#line 249 "ada-exp.y" + { + /* write_exp_elt_opcode (UNOP_QUAL); */ + /* FIXME: UNOP_QUAL should be defined in expression.h */ + write_exp_elt_type (yyvsp[-6].tval); + /* write_exp_elt_opcode (UNOP_QUAL); */ + /* FIXME: UNOP_QUAL should be defined in expression.h */ + type_qualifier = yyvsp[-4].tval; + } + break; + + case 12: +#line 259 "ada-exp.y" + { yyval.tval = type_qualifier; } + break; + + case 13: +#line 264 "ada-exp.y" + { write_exp_elt_opcode (TERNOP_SLICE); } + break; + + case 14: +#line 267 "ada-exp.y" + { } + break; + + case 16: +#line 274 "ada-exp.y" + { write_exp_elt_opcode (OP_REGISTER); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_REGISTER); + } + break; + + case 17: +#line 281 "ada-exp.y" + { write_exp_elt_opcode (OP_INTERNALVAR); + write_exp_elt_intern (yyvsp[0].ivar); + write_exp_elt_opcode (OP_INTERNALVAR); + } + break; + + case 19: +#line 292 "ada-exp.y" + { write_exp_elt_opcode (OP_LAST); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_LAST); + } + break; + + case 20: +#line 299 "ada-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN); } + break; + + case 21: +#line 303 "ada-exp.y" + { write_exp_elt_opcode (UNOP_NEG); } + break; + + case 22: +#line 307 "ada-exp.y" + { write_exp_elt_opcode (UNOP_PLUS); } + break; + + case 23: +#line 311 "ada-exp.y" + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + break; + + case 24: +#line 315 "ada-exp.y" + { write_exp_elt_opcode (UNOP_ABS); } + break; + + case 25: +#line 318 "ada-exp.y" + { yyval.lval = 0; } + break; + + case 26: +#line 322 "ada-exp.y" + { yyval.lval = 1; } + break; + + case 27: +#line 324 "ada-exp.y" + { yyval.lval = 1; } + break; + + case 28: +#line 326 "ada-exp.y" + { yyval.lval = yyvsp[-2].lval + 1; } + break; + + case 29: +#line 328 "ada-exp.y" + { yyval.lval = yyvsp[-4].lval + 1; } + break; + + case 30: +#line 333 "ada-exp.y" + { write_exp_elt_opcode (UNOP_MEMVAL); + write_exp_elt_type (yyvsp[-2].tval); + write_exp_elt_opcode (UNOP_MEMVAL); + } + break; + + case 31: +#line 342 "ada-exp.y" + { write_exp_elt_opcode (BINOP_EXP); } + break; + + case 32: +#line 346 "ada-exp.y" + { write_exp_elt_opcode (BINOP_MUL); } + break; + + case 33: +#line 350 "ada-exp.y" + { write_exp_elt_opcode (BINOP_DIV); } + break; + + case 34: +#line 354 "ada-exp.y" + { write_exp_elt_opcode (BINOP_REM); } + break; + + case 35: +#line 358 "ada-exp.y" + { write_exp_elt_opcode (BINOP_MOD); } + break; + + case 36: +#line 362 "ada-exp.y" + { write_exp_elt_opcode (BINOP_REPEAT); } + break; + + case 37: +#line 366 "ada-exp.y" + { write_exp_elt_opcode (BINOP_ADD); } + break; + + case 38: +#line 370 "ada-exp.y" + { write_exp_elt_opcode (BINOP_CONCAT); } + break; + + case 39: +#line 374 "ada-exp.y" + { write_exp_elt_opcode (BINOP_SUB); } + break; + + case 40: +#line 378 "ada-exp.y" + { write_exp_elt_opcode (BINOP_EQUAL); } + break; + + case 41: +#line 382 "ada-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 42: +#line 386 "ada-exp.y" + { write_exp_elt_opcode (BINOP_LEQ); } + break; + + case 43: +#line 390 "ada-exp.y" + { /*write_exp_elt_opcode (TERNOP_MBR); */ } + break; + + case 44: +#line 394 "ada-exp.y" + { /*write_exp_elt_opcode (BINOP_MBR); */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + /*write_exp_elt_opcode (BINOP_MBR); */ + } + break; + + case 45: +#line 400 "ada-exp.y" + { /*write_exp_elt_opcode (UNOP_MBR); */ + /* FIXME: UNOP_QUAL should be defined in expression.h */ + write_exp_elt_type (yyvsp[0].tval); + /* write_exp_elt_opcode (UNOP_MBR); */ + /* FIXME: UNOP_MBR should be defined in expression.h */ + } + break; + + case 46: +#line 407 "ada-exp.y" + { /*write_exp_elt_opcode (TERNOP_MBR); */ + /* FIXME: TERNOP_MBR should be defined in expression.h */ + write_exp_elt_opcode (UNOP_LOGICAL_NOT); + } + break; + + case 47: +#line 412 "ada-exp.y" + { /* write_exp_elt_opcode (BINOP_MBR); */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + /*write_exp_elt_opcode (BINOP_MBR);*/ + /* FIXME: BINOP_MBR should be defined in expression.h */ + write_exp_elt_opcode (UNOP_LOGICAL_NOT); + } + break; + + case 48: +#line 420 "ada-exp.y" + { /*write_exp_elt_opcode (UNOP_MBR);*/ + /* FIXME: UNOP_MBR should be defined in expression.h */ + write_exp_elt_type (yyvsp[0].tval); + /* write_exp_elt_opcode (UNOP_MBR);*/ + /* FIXME: UNOP_MBR should be defined in expression.h */ + write_exp_elt_opcode (UNOP_LOGICAL_NOT); + } + break; + + case 49: +#line 430 "ada-exp.y" + { write_exp_elt_opcode (BINOP_GEQ); } + break; + + case 50: +#line 434 "ada-exp.y" + { write_exp_elt_opcode (BINOP_LESS); } + break; + + case 51: +#line 438 "ada-exp.y" + { write_exp_elt_opcode (BINOP_GTR); } + break; + + case 52: +#line 442 "ada-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + break; + + case 53: +#line 446 "ada-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + break; + + case 54: +#line 450 "ada-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + break; + + case 55: +#line 454 "ada-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + break; + + case 56: +#line 458 "ada-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + break; + + case 57: +#line 462 "ada-exp.y" + { write_exp_elt_opcode (UNOP_ADDR); } + break; + + case 58: +#line 464 "ada-exp.y" + { write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (builtin_type_ada_system_address); + write_exp_elt_opcode (UNOP_CAST); + } + break; + + case 59: +#line 470 "ada-exp.y" + { write_attribute_call1 (ATR_FIRST, yyvsp[0].lval); } + break; + + case 60: +#line 472 "ada-exp.y" + { write_attribute_call1 (ATR_LAST, yyvsp[0].lval); } + break; + + case 61: +#line 474 "ada-exp.y" + { write_attribute_call1 (ATR_LENGTH, yyvsp[0].lval); } + break; + + case 62: +#line 476 "ada-exp.y" + { write_attribute_call0 (ATR_SIZE); } + break; + + case 63: +#line 478 "ada-exp.y" + { write_attribute_call0 (ATR_TAG); } + break; + + case 64: +#line 480 "ada-exp.y" + { write_attribute_calln (ATR_MIN, 2); } + break; + + case 65: +#line 482 "ada-exp.y" + { write_attribute_calln (ATR_MAX, 2); } + break; + + case 66: +#line 484 "ada-exp.y" + { write_attribute_calln (ATR_POS, 1); } + break; + + case 67: +#line 486 "ada-exp.y" + { write_attribute_call1 (ATR_FIRST, yyvsp[0].lval); } + break; + + case 68: +#line 488 "ada-exp.y" + { write_attribute_call1 (ATR_LAST, yyvsp[0].lval); } + break; + + case 69: +#line 490 "ada-exp.y" + { write_attribute_call1 (ATR_LENGTH, yyvsp[0].lval); } + break; + + case 70: +#line 492 "ada-exp.y" + { write_attribute_calln (ATR_VAL, 1); } + break; + + case 71: +#line 494 "ada-exp.y" + { write_attribute_call0 (ATR_MODULUS); } + break; + + case 72: +#line 498 "ada-exp.y" + { yyval.lval = 1; } + break; + + case 73: +#line 500 "ada-exp.y" + { yyval.lval = yyvsp[-1].typed_val.val; } + break; + + case 74: +#line 505 "ada-exp.y" + { write_exp_elt_opcode (OP_TYPE); + write_exp_elt_type (yyvsp[0].tval); + write_exp_elt_opcode (OP_TYPE); } + break; + + case 76: +#line 513 "ada-exp.y" + { write_exp_elt_opcode (OP_TYPE); + write_exp_elt_type (builtin_type_void); + write_exp_elt_opcode (OP_TYPE); } + break; + + case 77: +#line 520 "ada-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (yyvsp[0].typed_val.type); + write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val.val)); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 78: +#line 528 "ada-exp.y" + { write_exp_elt_opcode (OP_LONG); + if (type_qualifier == NULL) + write_exp_elt_type (yyvsp[0].typed_val.type); + else + write_exp_elt_type (type_qualifier); + write_exp_elt_longcst + (convert_char_literal (type_qualifier, yyvsp[0].typed_val.val)); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 79: +#line 540 "ada-exp.y" + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type (yyvsp[0].typed_val_float.type); + write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval); + write_exp_elt_opcode (OP_DOUBLE); + } + break; + + case 80: +#line 548 "ada-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst ((LONGEST)(0)); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 81: +#line 556 "ada-exp.y" + { /* Ada strings are converted into array constants + a lower bound of 1. Thus, the array upper bound + is the string length. */ + char *sp = yyvsp[0].sval.ptr; int count; + if (yyvsp[0].sval.length == 0) + { /* One dummy character for the type */ + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_ada_char); + write_exp_elt_longcst ((LONGEST)(0)); + write_exp_elt_opcode (OP_LONG); + } + for (count = yyvsp[0].sval.length; count > 0; count -= 1) + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_ada_char); + write_exp_elt_longcst ((LONGEST)(*sp)); + sp += 1; + write_exp_elt_opcode (OP_LONG); + } + write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 1); + write_exp_elt_longcst ((LONGEST) (yyvsp[0].sval.length)); + write_exp_elt_opcode (OP_ARRAY); + } + break; + + case 82: +#line 583 "ada-exp.y" + { error ("NEW not implemented."); } + break; + + case 83: +#line 586 "ada-exp.y" + { write_var_from_name (NULL, yyvsp[0].ssym); } + break; + + case 84: +#line 588 "ada-exp.y" + { write_var_from_name (yyvsp[-1].bval, yyvsp[0].ssym); } + break; + + case 85: +#line 589 "ada-exp.y" + { write_object_renaming (NULL, yyvsp[0].ssym.sym); } + break; + + case 86: +#line 591 "ada-exp.y" + { write_object_renaming (yyvsp[-1].bval, yyvsp[0].ssym.sym); } + break; + + case 87: +#line 594 "ada-exp.y" + { } + break; + + case 88: +#line 595 "ada-exp.y" + { } + break; + + case 89: +#line 596 "ada-exp.y" + { } + break; + + case 90: +#line 600 "ada-exp.y" + { yyval.bval = yyvsp[0].bval; } + break; + + case 91: +#line 602 "ada-exp.y" + { yyval.bval = yyvsp[0].bval; } + break; + + case 92: +#line 606 "ada-exp.y" + { yyval.tval = yyvsp[0].tval; } + break; + + case 93: +#line 607 "ada-exp.y" + { yyval.tval = yyvsp[0].tval; } + break; + + case 94: +#line 609 "ada-exp.y" + { yyval.tval = lookup_pointer_type (yyvsp[-1].tval); } + break; + + case 95: +#line 611 "ada-exp.y" + { yyval.tval = lookup_pointer_type (yyvsp[-1].tval); } + break; + + case 96: +#line 618 "ada-exp.y" + { write_exp_elt_opcode (UNOP_IND); } + break; + + case 97: +#line 620 "ada-exp.y" + { write_exp_elt_opcode (UNOP_ADDR); } + break; + + case 98: +#line 622 "ada-exp.y" + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + break; + + + } + +/* Line 991 of yacc.c. */ + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. Doesn't work in C++ */ +#ifndef __cplusplus +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 625 "ada-exp.y" + + +/* yylex defined in ada-lex.c: Reads one token, getting characters */ +/* through lexptr. */ + +/* Remap normal flex interface names (yylex) as well as gratuitiously */ +/* global symbol names, so we can have multiple flex-generated parsers */ +/* in gdb. */ + +/* (See note above on previous definitions for YACC.) */ + +#define yy_create_buffer ada_yy_create_buffer +#define yy_delete_buffer ada_yy_delete_buffer +#define yy_init_buffer ada_yy_init_buffer +#define yy_load_buffer_state ada_yy_load_buffer_state +#define yy_switch_to_buffer ada_yy_switch_to_buffer +#define yyrestart ada_yyrestart +#define yytext ada_yytext +#define yywrap ada_yywrap + +/* The following kludge was found necessary to prevent conflicts between */ +/* defs.h and non-standard stdlib.h files. */ +#define qsort __qsort__dummy +#include "ada-lex.c" + +int +ada_parse () +{ + lexer_init (yyin); /* (Re-)initialize lexer. */ + left_block_context = NULL; + type_qualifier = NULL; + + return _ada_parse (); +} + +void +yyerror (msg) + char *msg; +{ + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); +} + +/* The operator name corresponding to operator symbol STRING (adds + quotes and maps to lower-case). Destroys the previous contents of + the array pointed to by STRING.ptr. Error if STRING does not match + a valid Ada operator. Assumes that STRING.ptr points to a + null-terminated string and that, if STRING is a valid operator + symbol, the array pointed to by STRING.ptr contains at least + STRING.length+3 characters. */ + +static struct stoken +string_to_operator (string) + struct stoken string; +{ + int i; + + for (i = 0; ada_opname_table[i].mangled != NULL; i += 1) + { + if (string.length == strlen (ada_opname_table[i].demangled)-2 + && strncasecmp (string.ptr, ada_opname_table[i].demangled+1, + string.length) == 0) + { + strncpy (string.ptr, ada_opname_table[i].demangled, + string.length+2); + string.length += 2; + return string; + } + } + error ("Invalid operator symbol `%s'", string.ptr); +} + +/* Emit expression to access an instance of SYM, in block BLOCK (if + * non-NULL), and with :: qualification ORIG_LEFT_CONTEXT. */ +static void +write_var_from_sym (orig_left_context, block, sym) + struct block* orig_left_context; + struct block* block; + struct symbol* sym; +{ + if (orig_left_context == NULL && symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block, innermost_block)) + innermost_block = block; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not another more inner frame + which happens to be in the same block */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); +} + +/* Emit expression to access an instance of NAME. */ +static void +write_var_from_name (orig_left_context, name) + struct block* orig_left_context; + struct name_info name; +{ + if (name.msym != NULL) + { + write_exp_msymbol (name.msym, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (name.sym == NULL) + { + /* Multiple matches: record name and starting block for later + resolution by ada_resolve. */ + /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */ + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + write_exp_elt_block (name.block); + /* write_exp_elt_name (name.stoken.ptr); */ + /* FIXME: write_exp_elt_name should be defined in defs.h, located in parse.c */ + /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */ + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + } + else + write_var_from_sym (orig_left_context, name.block, name.sym); +} + +/* Write a call on parameterless attribute ATR. */ + +static void +write_attribute_call0 (atr) + enum ada_attribute atr; +{ + /* write_exp_elt_opcode (OP_ATTRIBUTE); */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) atr); + /* write_exp_elt_opcode (OP_ATTRIBUTE); */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ +} + +/* Write a call on an attribute ATR with one constant integer + * parameter. */ + +static void +write_attribute_call1 (atr, arg) + enum ada_attribute atr; + LONGEST arg; +{ + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst (arg); + write_exp_elt_opcode (OP_LONG); + /*write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) 1); + write_exp_elt_longcst ((LONGEST) atr); + /*write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ +} + +/* Write a call on an attribute ATR with N parameters, whose code must have + * been generated previously. */ + +static void +write_attribute_calln (atr, n) + enum ada_attribute atr; + int n; +{ + /*write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) n); + write_exp_elt_longcst ((LONGEST) atr); + /* write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ +} + +/* Emit expression corresponding to the renamed object designated by + * the type RENAMING, which must be the referent of an object renaming + * type, in the context of ORIG_LEFT_CONTEXT (?). */ +static void +write_object_renaming (orig_left_context, renaming) + struct block* orig_left_context; + struct symbol* renaming; +{ + const char* qualification = DEPRECATED_SYMBOL_NAME (renaming); + const char* simple_tail; + const char* expr = TYPE_FIELD_NAME (SYMBOL_TYPE (renaming), 0); + const char* suffix; + char* name; + struct symbol* sym; + enum { SIMPLE_INDEX, LOWER_BOUND, UPPER_BOUND } slice_state; + + /* if orig_left_context is null, then use the currently selected + block, otherwise we might fail our symbol lookup below */ + if (orig_left_context == NULL) + orig_left_context = get_selected_block (NULL); + + for (simple_tail = qualification + strlen (qualification); + simple_tail != qualification; simple_tail -= 1) + { + if (*simple_tail == '.') + { + simple_tail += 1; + break; + } + else if (DEPRECATED_STREQN (simple_tail, "__", 2)) + { + simple_tail += 2; + break; + } + } + + suffix = strstr (expr, "___XE"); + if (suffix == NULL) + goto BadEncoding; + + name = (char*) xmalloc (suffix - expr + 1); + /* add_name_string_cleanup (name); */ + /* FIXME: add_name_string_cleanup should be defined in + parser-defs.h, implemented in parse.c */ + strncpy (name, expr, suffix-expr); + name[suffix-expr] = '\000'; + sym = lookup_symbol (name, orig_left_context, VAR_DOMAIN, 0, NULL); + /* if (sym == NULL) + error ("Could not find renamed variable: %s", ada_demangle (name)); + */ + /* FIXME: ada_demangle should be defined in defs.h, implemented in ada-lang.c */ + write_var_from_sym (orig_left_context, block_found, sym); + + suffix += 5; + slice_state = SIMPLE_INDEX; + while (*suffix == 'X') + { + suffix += 1; + + switch (*suffix) { + case 'L': + slice_state = LOWER_BOUND; + case 'S': + suffix += 1; + if (isdigit (*suffix)) + { + char* next; + long val = strtol (suffix, &next, 10); + if (next == suffix) + goto BadEncoding; + suffix = next; + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_ada_int); + write_exp_elt_longcst ((LONGEST) val); + write_exp_elt_opcode (OP_LONG); + } + else + { + const char* end; + char* index_name; + int index_len; + struct symbol* index_sym; + + end = strchr (suffix, 'X'); + if (end == NULL) + end = suffix + strlen (suffix); + + index_len = simple_tail - qualification + 2 + (suffix - end) + 1; + index_name = (char*) xmalloc (index_len); + memset (index_name, '\000', index_len); + /* add_name_string_cleanup (index_name);*/ + /* FIXME: add_name_string_cleanup should be defined in + parser-defs.h, implemented in parse.c */ + strncpy (index_name, qualification, simple_tail - qualification); + index_name[simple_tail - qualification] = '\000'; + strncat (index_name, suffix, suffix-end); + suffix = end; + + index_sym = + lookup_symbol (index_name, NULL, VAR_DOMAIN, 0, NULL); + if (index_sym == NULL) + error ("Could not find %s", index_name); + write_var_from_sym (NULL, block_found, sym); + } + if (slice_state == SIMPLE_INDEX) + { + write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) 1); + write_exp_elt_opcode (OP_FUNCALL); + } + else if (slice_state == LOWER_BOUND) + slice_state = UPPER_BOUND; + else if (slice_state == UPPER_BOUND) + { + write_exp_elt_opcode (TERNOP_SLICE); + slice_state = SIMPLE_INDEX; + } + break; + + case 'R': + { + struct stoken field_name; + const char* end; + suffix += 1; + + if (slice_state != SIMPLE_INDEX) + goto BadEncoding; + end = strchr (suffix, 'X'); + if (end == NULL) + end = suffix + strlen (suffix); + field_name.length = end - suffix; + field_name.ptr = (char*) xmalloc (end - suffix + 1); + strncpy (field_name.ptr, suffix, end - suffix); + field_name.ptr[end - suffix] = '\000'; + suffix = end; + write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (field_name); + write_exp_elt_opcode (STRUCTOP_STRUCT); + break; + } + + default: + goto BadEncoding; + } + } + if (slice_state == SIMPLE_INDEX) + return; + + BadEncoding: + error ("Internal error in encoding of renaming declaration: %s", + DEPRECATED_SYMBOL_NAME (renaming)); +} + +/* Convert the character literal whose ASCII value would be VAL to the + appropriate value of type TYPE, if there is a translation. + Otherwise return VAL. Hence, in an enumeration type ('A', 'B'), + the literal 'A' (VAL == 65), returns 0. */ +static LONGEST +convert_char_literal (struct type* type, LONGEST val) +{ + char name[7]; + int f; + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM) + return val; + sprintf (name, "QU%02x", (int) val); + for (f = 0; f < TYPE_NFIELDS (type); f += 1) + { + if (DEPRECATED_STREQ (name, TYPE_FIELD_NAME (type, f))) + return TYPE_FIELD_BITPOS (type, f); + } + return val; +} + + diff --git a/contrib/gdb/gdb/ada-exp.y b/contrib/gdb/gdb/ada-exp.y new file mode 100644 index 00000000000..f4cbb37316a --- /dev/null +++ b/contrib/gdb/gdb/ada-exp.y @@ -0,0 +1,969 @@ +/* YACC parser for Ada expressions, for GDB. + Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994, 1997, 2000, 2003 + Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Parse an Ada expression from text in a string, + and return the result as a struct expression pointer. + That structure contains arithmetic operations in reverse polish, + with constants represented by operations that are followed by special data. + See expression.h for the details of the format. + What is important here is that it can be built up sequentially + during the process of parsing; the lower levels of the tree always + come first in the result. + + malloc's and realloc's in this file are transformed to + xmalloc and xrealloc respectively by the same sed command in the + makefile that remaps any other malloc/realloc inserted by the parser + generator. Doing this with #defines and trying to control the interaction + with include files ( and for example) just became + too messy, particularly when such includes can be inserted at random + times by the parser generator. */ + +%{ + +#include "defs.h" +#include +#include +#include "expression.h" +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "ada-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "frame.h" +#include "block.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in gdb. These are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +/* NOTE: This is clumsy, especially since BISON and FLEX provide --prefix + options. I presume we are maintaining it to accommodate systems + without BISON? (PNH) */ + +#define yymaxdepth ada_maxdepth +#define yyparse _ada_parse /* ada_parse calls this after initialization */ +#define yylex ada_lex +#define yyerror ada_error +#define yylval ada_lval +#define yychar ada_char +#define yydebug ada_debug +#define yypact ada_pact +#define yyr1 ada_r1 +#define yyr2 ada_r2 +#define yydef ada_def +#define yychk ada_chk +#define yypgo ada_pgo +#define yyact ada_act +#define yyexca ada_exca +#define yyerrflag ada_errflag +#define yynerrs ada_nerrs +#define yyps ada_ps +#define yypv ada_pv +#define yys ada_s +#define yy_yys ada_yys +#define yystate ada_state +#define yytmp ada_tmp +#define yyv ada_v +#define yy_yyv ada_yyv +#define yyval ada_val +#define yylloc ada_lloc +#define yyreds ada_reds /* With YYDEBUG defined */ +#define yytoks ada_toks /* With YYDEBUG defined */ +#define yyname ada_name /* With YYDEBUG defined */ +#define yyrule ada_rule /* With YYDEBUG defined */ + +#ifndef YYDEBUG +#define YYDEBUG 1 /* Default to yydebug support */ +#endif + +#define YYFPRINTF parser_fprintf + +struct name_info { + struct symbol* sym; + struct minimal_symbol* msym; + struct block* block; + struct stoken stoken; +}; + +/* If expression is in the context of TYPE'(...), then TYPE, else + * NULL. */ +static struct type* type_qualifier; + +int yyparse (void); + +static int yylex (void); + +void yyerror (char *); + +static struct stoken string_to_operator (struct stoken); + +static void write_attribute_call0 (enum ada_attribute); + +static void write_attribute_call1 (enum ada_attribute, LONGEST); + +static void write_attribute_calln (enum ada_attribute, int); + +static void write_object_renaming (struct block*, struct symbol*); + +static void write_var_from_name (struct block*, struct name_info); + +static LONGEST +convert_char_literal (struct type*, LONGEST); +%} + +%union + { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; + struct type *tval; + struct stoken sval; + struct name_info ssym; + int voidval; + struct block *bval; + struct internalvar *ivar; + + } + +%type exp exp1 simple_exp start variable +%type type + +%token INT NULL_PTR CHARLIT +%token FLOAT +%token TYPENAME +%token BLOCKNAME + +/* Both NAME and TYPENAME tokens represent symbols in the input, + and both convey their data as strings. + But a TYPENAME is a string that happens to be defined as a typedef + or builtin type name (such as int or char) + and a NAME is any other symbol. + Contexts where this distinction is not important can use the + nonterminal "name", which matches either NAME or TYPENAME. */ + +%token STRING +%token NAME DOT_ID OBJECT_RENAMING +%type block +%type arglist tick_arglist + +%type save_qualifier + +%token DOT_ALL + +/* Special type cases, put in to allow the parser to distinguish different + legal basetypes. */ +%token LAST REGNAME + +%token INTERNAL_VARIABLE + +%nonassoc ASSIGN +%left _AND_ OR XOR THEN ELSE +%left '=' NOTEQUAL '<' '>' LEQ GEQ IN DOTDOT +%left '@' +%left '+' '-' '&' +%left UNARY +%left '*' '/' MOD REM +%right STARSTAR ABS NOT + /* The following are right-associative only so that reductions at this + precedence have lower precedence than '.' and '('. The syntax still + forces a.b.c, e.g., to be LEFT-associated. */ +%right TICK_ACCESS TICK_ADDRESS TICK_FIRST TICK_LAST TICK_LENGTH +%right TICK_MAX TICK_MIN TICK_MODULUS +%right TICK_POS TICK_RANGE TICK_SIZE TICK_TAG TICK_VAL +%right '.' '(' '[' DOT_ID DOT_ALL + +%token ARROW NEW + + +%% + +start : exp1 + | type { write_exp_elt_opcode (OP_TYPE); + write_exp_elt_type ($1); + write_exp_elt_opcode (OP_TYPE); } + ; + +/* Expressions, including the sequencing operator. */ +exp1 : exp + | exp1 ';' exp + { write_exp_elt_opcode (BINOP_COMMA); } + ; + +/* Expressions, not including the sequencing operator. */ +simple_exp : simple_exp DOT_ALL + { write_exp_elt_opcode (UNOP_IND); } + ; + +simple_exp : simple_exp DOT_ID + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string ($2.stoken); + write_exp_elt_opcode (STRUCTOP_STRUCT); + } + ; + +simple_exp : simple_exp '(' arglist ')' + { + write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ($3); + write_exp_elt_opcode (OP_FUNCALL); + } + ; + +simple_exp : type '(' exp ')' + { + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type ($1); + write_exp_elt_opcode (UNOP_CAST); + } + ; + +simple_exp : type '\'' save_qualifier { type_qualifier = $1; } '(' exp ')' + { + /* write_exp_elt_opcode (UNOP_QUAL); */ + /* FIXME: UNOP_QUAL should be defined in expression.h */ + write_exp_elt_type ($1); + /* write_exp_elt_opcode (UNOP_QUAL); */ + /* FIXME: UNOP_QUAL should be defined in expression.h */ + type_qualifier = $3; + } + ; + +save_qualifier : { $$ = type_qualifier; } + ; + +simple_exp : + simple_exp '(' exp DOTDOT exp ')' + { write_exp_elt_opcode (TERNOP_SLICE); } + ; + +simple_exp : '(' exp1 ')' { } + ; + +simple_exp : variable + ; + +simple_exp: REGNAME /* GDB extension */ + { write_exp_elt_opcode (OP_REGISTER); + write_exp_elt_longcst ((LONGEST) $1); + write_exp_elt_opcode (OP_REGISTER); + } + ; + +simple_exp: INTERNAL_VARIABLE /* GDB extension */ + { write_exp_elt_opcode (OP_INTERNALVAR); + write_exp_elt_intern ($1); + write_exp_elt_opcode (OP_INTERNALVAR); + } + ; + + +exp : simple_exp + ; + +simple_exp: LAST + { write_exp_elt_opcode (OP_LAST); + write_exp_elt_longcst ((LONGEST) $1); + write_exp_elt_opcode (OP_LAST); + } + ; + +exp : exp ASSIGN exp /* Extension for convenience */ + { write_exp_elt_opcode (BINOP_ASSIGN); } + ; + +exp : '-' exp %prec UNARY + { write_exp_elt_opcode (UNOP_NEG); } + ; + +exp : '+' exp %prec UNARY + { write_exp_elt_opcode (UNOP_PLUS); } + ; + +exp : NOT exp %prec UNARY + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + ; + +exp : ABS exp %prec UNARY + { write_exp_elt_opcode (UNOP_ABS); } + ; + +arglist : { $$ = 0; } + ; + +arglist : exp + { $$ = 1; } + | any_name ARROW exp + { $$ = 1; } + | arglist ',' exp + { $$ = $1 + 1; } + | arglist ',' any_name ARROW exp + { $$ = $1 + 1; } + ; + +exp : '{' type '}' exp %prec '.' + /* GDB extension */ + { write_exp_elt_opcode (UNOP_MEMVAL); + write_exp_elt_type ($2); + write_exp_elt_opcode (UNOP_MEMVAL); + } + ; + +/* Binary operators in order of decreasing precedence. */ + +exp : exp STARSTAR exp + { write_exp_elt_opcode (BINOP_EXP); } + ; + +exp : exp '*' exp + { write_exp_elt_opcode (BINOP_MUL); } + ; + +exp : exp '/' exp + { write_exp_elt_opcode (BINOP_DIV); } + ; + +exp : exp REM exp /* May need to be fixed to give correct Ada REM */ + { write_exp_elt_opcode (BINOP_REM); } + ; + +exp : exp MOD exp + { write_exp_elt_opcode (BINOP_MOD); } + ; + +exp : exp '@' exp /* GDB extension */ + { write_exp_elt_opcode (BINOP_REPEAT); } + ; + +exp : exp '+' exp + { write_exp_elt_opcode (BINOP_ADD); } + ; + +exp : exp '&' exp + { write_exp_elt_opcode (BINOP_CONCAT); } + ; + +exp : exp '-' exp + { write_exp_elt_opcode (BINOP_SUB); } + ; + +exp : exp '=' exp + { write_exp_elt_opcode (BINOP_EQUAL); } + ; + +exp : exp NOTEQUAL exp + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + ; + +exp : exp LEQ exp + { write_exp_elt_opcode (BINOP_LEQ); } + ; + +exp : exp IN exp DOTDOT exp + { /*write_exp_elt_opcode (TERNOP_MBR); */ } + /* FIXME: TERNOP_MBR should be defined in + expression.h */ + | exp IN exp TICK_RANGE tick_arglist + { /*write_exp_elt_opcode (BINOP_MBR); */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) $5); + /*write_exp_elt_opcode (BINOP_MBR); */ + } + | exp IN TYPENAME %prec TICK_ACCESS + { /*write_exp_elt_opcode (UNOP_MBR); */ + /* FIXME: UNOP_QUAL should be defined in expression.h */ + write_exp_elt_type ($3); + /* write_exp_elt_opcode (UNOP_MBR); */ + /* FIXME: UNOP_MBR should be defined in expression.h */ + } + | exp NOT IN exp DOTDOT exp + { /*write_exp_elt_opcode (TERNOP_MBR); */ + /* FIXME: TERNOP_MBR should be defined in expression.h */ + write_exp_elt_opcode (UNOP_LOGICAL_NOT); + } + | exp NOT IN exp TICK_RANGE tick_arglist + { /* write_exp_elt_opcode (BINOP_MBR); */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) $6); + /*write_exp_elt_opcode (BINOP_MBR);*/ + /* FIXME: BINOP_MBR should be defined in expression.h */ + write_exp_elt_opcode (UNOP_LOGICAL_NOT); + } + | exp NOT IN TYPENAME %prec TICK_ACCESS + { /*write_exp_elt_opcode (UNOP_MBR);*/ + /* FIXME: UNOP_MBR should be defined in expression.h */ + write_exp_elt_type ($4); + /* write_exp_elt_opcode (UNOP_MBR);*/ + /* FIXME: UNOP_MBR should be defined in expression.h */ + write_exp_elt_opcode (UNOP_LOGICAL_NOT); + } + ; + +exp : exp GEQ exp + { write_exp_elt_opcode (BINOP_GEQ); } + ; + +exp : exp '<' exp + { write_exp_elt_opcode (BINOP_LESS); } + ; + +exp : exp '>' exp + { write_exp_elt_opcode (BINOP_GTR); } + ; + +exp : exp _AND_ exp /* Fix for Ada elementwise AND. */ + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + ; + +exp : exp _AND_ THEN exp %prec _AND_ + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + ; + +exp : exp OR exp /* Fix for Ada elementwise OR */ + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + ; + +exp : exp OR ELSE exp + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + ; + +exp : exp XOR exp /* Fix for Ada elementwise XOR */ + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + ; + +simple_exp : simple_exp TICK_ACCESS + { write_exp_elt_opcode (UNOP_ADDR); } + | simple_exp TICK_ADDRESS + { write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (builtin_type_ada_system_address); + write_exp_elt_opcode (UNOP_CAST); + } + | simple_exp TICK_FIRST tick_arglist + { write_attribute_call1 (ATR_FIRST, $3); } + | simple_exp TICK_LAST tick_arglist + { write_attribute_call1 (ATR_LAST, $3); } + | simple_exp TICK_LENGTH tick_arglist + { write_attribute_call1 (ATR_LENGTH, $3); } + | simple_exp TICK_SIZE + { write_attribute_call0 (ATR_SIZE); } + | simple_exp TICK_TAG + { write_attribute_call0 (ATR_TAG); } + | opt_type_prefix TICK_MIN '(' exp ',' exp ')' + { write_attribute_calln (ATR_MIN, 2); } + | opt_type_prefix TICK_MAX '(' exp ',' exp ')' + { write_attribute_calln (ATR_MAX, 2); } + | opt_type_prefix TICK_POS '(' exp ')' + { write_attribute_calln (ATR_POS, 1); } + | type_prefix TICK_FIRST tick_arglist + { write_attribute_call1 (ATR_FIRST, $3); } + | type_prefix TICK_LAST tick_arglist + { write_attribute_call1 (ATR_LAST, $3); } + | type_prefix TICK_LENGTH tick_arglist + { write_attribute_call1 (ATR_LENGTH, $3); } + | type_prefix TICK_VAL '(' exp ')' + { write_attribute_calln (ATR_VAL, 1); } + | type_prefix TICK_MODULUS + { write_attribute_call0 (ATR_MODULUS); } + ; + +tick_arglist : %prec '(' + { $$ = 1; } + | '(' INT ')' + { $$ = $2.val; } + ; + +type_prefix : + TYPENAME + { write_exp_elt_opcode (OP_TYPE); + write_exp_elt_type ($1); + write_exp_elt_opcode (OP_TYPE); } + ; + +opt_type_prefix : + type_prefix + | /* EMPTY */ + { write_exp_elt_opcode (OP_TYPE); + write_exp_elt_type (builtin_type_void); + write_exp_elt_opcode (OP_TYPE); } + ; + + +exp : INT + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type ($1.type); + write_exp_elt_longcst ((LONGEST)($1.val)); + write_exp_elt_opcode (OP_LONG); + } + ; + +exp : CHARLIT + { write_exp_elt_opcode (OP_LONG); + if (type_qualifier == NULL) + write_exp_elt_type ($1.type); + else + write_exp_elt_type (type_qualifier); + write_exp_elt_longcst + (convert_char_literal (type_qualifier, $1.val)); + write_exp_elt_opcode (OP_LONG); + } + ; + +exp : FLOAT + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type ($1.type); + write_exp_elt_dblcst ($1.dval); + write_exp_elt_opcode (OP_DOUBLE); + } + ; + +exp : NULL_PTR + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst ((LONGEST)(0)); + write_exp_elt_opcode (OP_LONG); + } + ; + +exp : STRING + { /* Ada strings are converted into array constants + a lower bound of 1. Thus, the array upper bound + is the string length. */ + char *sp = $1.ptr; int count; + if ($1.length == 0) + { /* One dummy character for the type */ + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_ada_char); + write_exp_elt_longcst ((LONGEST)(0)); + write_exp_elt_opcode (OP_LONG); + } + for (count = $1.length; count > 0; count -= 1) + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_ada_char); + write_exp_elt_longcst ((LONGEST)(*sp)); + sp += 1; + write_exp_elt_opcode (OP_LONG); + } + write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 1); + write_exp_elt_longcst ((LONGEST) ($1.length)); + write_exp_elt_opcode (OP_ARRAY); + } + ; + +exp : NEW TYPENAME + { error ("NEW not implemented."); } + ; + +variable: NAME { write_var_from_name (NULL, $1); } + | block NAME /* GDB extension */ + { write_var_from_name ($1, $2); } + | OBJECT_RENAMING { write_object_renaming (NULL, $1.sym); } + | block OBJECT_RENAMING + { write_object_renaming ($1, $2.sym); } + ; + +any_name : NAME { } + | TYPENAME { } + | OBJECT_RENAMING { } + ; + +block : BLOCKNAME /* GDB extension */ + { $$ = $1; } + | block BLOCKNAME /* GDB extension */ + { $$ = $2; } + ; + + +type : TYPENAME { $$ = $1; } + | block TYPENAME { $$ = $2; } + | TYPENAME TICK_ACCESS + { $$ = lookup_pointer_type ($1); } + | block TYPENAME TICK_ACCESS + { $$ = lookup_pointer_type ($2); } + ; + +/* Some extensions borrowed from C, for the benefit of those who find they + can't get used to Ada notation in GDB. */ + +exp : '*' exp %prec '.' + { write_exp_elt_opcode (UNOP_IND); } + | '&' exp %prec '.' + { write_exp_elt_opcode (UNOP_ADDR); } + | exp '[' exp ']' + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + ; + +%% + +/* yylex defined in ada-lex.c: Reads one token, getting characters */ +/* through lexptr. */ + +/* Remap normal flex interface names (yylex) as well as gratuitiously */ +/* global symbol names, so we can have multiple flex-generated parsers */ +/* in gdb. */ + +/* (See note above on previous definitions for YACC.) */ + +#define yy_create_buffer ada_yy_create_buffer +#define yy_delete_buffer ada_yy_delete_buffer +#define yy_init_buffer ada_yy_init_buffer +#define yy_load_buffer_state ada_yy_load_buffer_state +#define yy_switch_to_buffer ada_yy_switch_to_buffer +#define yyrestart ada_yyrestart +#define yytext ada_yytext +#define yywrap ada_yywrap + +/* The following kludge was found necessary to prevent conflicts between */ +/* defs.h and non-standard stdlib.h files. */ +#define qsort __qsort__dummy +#include "ada-lex.c" + +int +ada_parse () +{ + lexer_init (yyin); /* (Re-)initialize lexer. */ + left_block_context = NULL; + type_qualifier = NULL; + + return _ada_parse (); +} + +void +yyerror (msg) + char *msg; +{ + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); +} + +/* The operator name corresponding to operator symbol STRING (adds + quotes and maps to lower-case). Destroys the previous contents of + the array pointed to by STRING.ptr. Error if STRING does not match + a valid Ada operator. Assumes that STRING.ptr points to a + null-terminated string and that, if STRING is a valid operator + symbol, the array pointed to by STRING.ptr contains at least + STRING.length+3 characters. */ + +static struct stoken +string_to_operator (string) + struct stoken string; +{ + int i; + + for (i = 0; ada_opname_table[i].mangled != NULL; i += 1) + { + if (string.length == strlen (ada_opname_table[i].demangled)-2 + && strncasecmp (string.ptr, ada_opname_table[i].demangled+1, + string.length) == 0) + { + strncpy (string.ptr, ada_opname_table[i].demangled, + string.length+2); + string.length += 2; + return string; + } + } + error ("Invalid operator symbol `%s'", string.ptr); +} + +/* Emit expression to access an instance of SYM, in block BLOCK (if + * non-NULL), and with :: qualification ORIG_LEFT_CONTEXT. */ +static void +write_var_from_sym (orig_left_context, block, sym) + struct block* orig_left_context; + struct block* block; + struct symbol* sym; +{ + if (orig_left_context == NULL && symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block, innermost_block)) + innermost_block = block; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not another more inner frame + which happens to be in the same block */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); +} + +/* Emit expression to access an instance of NAME. */ +static void +write_var_from_name (orig_left_context, name) + struct block* orig_left_context; + struct name_info name; +{ + if (name.msym != NULL) + { + write_exp_msymbol (name.msym, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (name.sym == NULL) + { + /* Multiple matches: record name and starting block for later + resolution by ada_resolve. */ + /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */ + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + write_exp_elt_block (name.block); + /* write_exp_elt_name (name.stoken.ptr); */ + /* FIXME: write_exp_elt_name should be defined in defs.h, located in parse.c */ + /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */ + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + } + else + write_var_from_sym (orig_left_context, name.block, name.sym); +} + +/* Write a call on parameterless attribute ATR. */ + +static void +write_attribute_call0 (atr) + enum ada_attribute atr; +{ + /* write_exp_elt_opcode (OP_ATTRIBUTE); */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) atr); + /* write_exp_elt_opcode (OP_ATTRIBUTE); */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ +} + +/* Write a call on an attribute ATR with one constant integer + * parameter. */ + +static void +write_attribute_call1 (atr, arg) + enum ada_attribute atr; + LONGEST arg; +{ + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst (arg); + write_exp_elt_opcode (OP_LONG); + /*write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) 1); + write_exp_elt_longcst ((LONGEST) atr); + /*write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ +} + +/* Write a call on an attribute ATR with N parameters, whose code must have + * been generated previously. */ + +static void +write_attribute_calln (atr, n) + enum ada_attribute atr; + int n; +{ + /*write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + write_exp_elt_longcst ((LONGEST) n); + write_exp_elt_longcst ((LONGEST) atr); + /* write_exp_elt_opcode (OP_ATTRIBUTE);*/ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ +} + +/* Emit expression corresponding to the renamed object designated by + * the type RENAMING, which must be the referent of an object renaming + * type, in the context of ORIG_LEFT_CONTEXT (?). */ +static void +write_object_renaming (orig_left_context, renaming) + struct block* orig_left_context; + struct symbol* renaming; +{ + const char* qualification = DEPRECATED_SYMBOL_NAME (renaming); + const char* simple_tail; + const char* expr = TYPE_FIELD_NAME (SYMBOL_TYPE (renaming), 0); + const char* suffix; + char* name; + struct symbol* sym; + enum { SIMPLE_INDEX, LOWER_BOUND, UPPER_BOUND } slice_state; + + /* if orig_left_context is null, then use the currently selected + block, otherwise we might fail our symbol lookup below */ + if (orig_left_context == NULL) + orig_left_context = get_selected_block (NULL); + + for (simple_tail = qualification + strlen (qualification); + simple_tail != qualification; simple_tail -= 1) + { + if (*simple_tail == '.') + { + simple_tail += 1; + break; + } + else if (DEPRECATED_STREQN (simple_tail, "__", 2)) + { + simple_tail += 2; + break; + } + } + + suffix = strstr (expr, "___XE"); + if (suffix == NULL) + goto BadEncoding; + + name = (char*) malloc (suffix - expr + 1); + /* add_name_string_cleanup (name); */ + /* FIXME: add_name_string_cleanup should be defined in + parser-defs.h, implemented in parse.c */ + strncpy (name, expr, suffix-expr); + name[suffix-expr] = '\000'; + sym = lookup_symbol (name, orig_left_context, VAR_DOMAIN, 0, NULL); + /* if (sym == NULL) + error ("Could not find renamed variable: %s", ada_demangle (name)); + */ + /* FIXME: ada_demangle should be defined in defs.h, implemented in ada-lang.c */ + write_var_from_sym (orig_left_context, block_found, sym); + + suffix += 5; + slice_state = SIMPLE_INDEX; + while (*suffix == 'X') + { + suffix += 1; + + switch (*suffix) { + case 'L': + slice_state = LOWER_BOUND; + case 'S': + suffix += 1; + if (isdigit (*suffix)) + { + char* next; + long val = strtol (suffix, &next, 10); + if (next == suffix) + goto BadEncoding; + suffix = next; + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_ada_int); + write_exp_elt_longcst ((LONGEST) val); + write_exp_elt_opcode (OP_LONG); + } + else + { + const char* end; + char* index_name; + int index_len; + struct symbol* index_sym; + + end = strchr (suffix, 'X'); + if (end == NULL) + end = suffix + strlen (suffix); + + index_len = simple_tail - qualification + 2 + (suffix - end) + 1; + index_name = (char*) malloc (index_len); + memset (index_name, '\000', index_len); + /* add_name_string_cleanup (index_name);*/ + /* FIXME: add_name_string_cleanup should be defined in + parser-defs.h, implemented in parse.c */ + strncpy (index_name, qualification, simple_tail - qualification); + index_name[simple_tail - qualification] = '\000'; + strncat (index_name, suffix, suffix-end); + suffix = end; + + index_sym = + lookup_symbol (index_name, NULL, VAR_DOMAIN, 0, NULL); + if (index_sym == NULL) + error ("Could not find %s", index_name); + write_var_from_sym (NULL, block_found, sym); + } + if (slice_state == SIMPLE_INDEX) + { + write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) 1); + write_exp_elt_opcode (OP_FUNCALL); + } + else if (slice_state == LOWER_BOUND) + slice_state = UPPER_BOUND; + else if (slice_state == UPPER_BOUND) + { + write_exp_elt_opcode (TERNOP_SLICE); + slice_state = SIMPLE_INDEX; + } + break; + + case 'R': + { + struct stoken field_name; + const char* end; + suffix += 1; + + if (slice_state != SIMPLE_INDEX) + goto BadEncoding; + end = strchr (suffix, 'X'); + if (end == NULL) + end = suffix + strlen (suffix); + field_name.length = end - suffix; + field_name.ptr = (char*) malloc (end - suffix + 1); + strncpy (field_name.ptr, suffix, end - suffix); + field_name.ptr[end - suffix] = '\000'; + suffix = end; + write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (field_name); + write_exp_elt_opcode (STRUCTOP_STRUCT); + break; + } + + default: + goto BadEncoding; + } + } + if (slice_state == SIMPLE_INDEX) + return; + + BadEncoding: + error ("Internal error in encoding of renaming declaration: %s", + DEPRECATED_SYMBOL_NAME (renaming)); +} + +/* Convert the character literal whose ASCII value would be VAL to the + appropriate value of type TYPE, if there is a translation. + Otherwise return VAL. Hence, in an enumeration type ('A', 'B'), + the literal 'A' (VAL == 65), returns 0. */ +static LONGEST +convert_char_literal (struct type* type, LONGEST val) +{ + char name[7]; + int f; + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM) + return val; + sprintf (name, "QU%02x", (int) val); + for (f = 0; f < TYPE_NFIELDS (type); f += 1) + { + if (DEPRECATED_STREQ (name, TYPE_FIELD_NAME (type, f))) + return TYPE_FIELD_BITPOS (type, f); + } + return val; +} diff --git a/contrib/gdb/gdb/ada-lang.c b/contrib/gdb/gdb/ada-lang.c new file mode 100644 index 00000000000..b97321b31e9 --- /dev/null +++ b/contrib/gdb/gdb/ada-lang.c @@ -0,0 +1,8254 @@ +/* Ada language support routines for GDB, the GNU debugger. Copyright + 1992, 1993, 1994, 1997, 1998, 1999, 2000, 2003, 2004 + Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include "gdb_string.h" +#include +#include +#include "demangle.h" +#include "defs.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "gdbcmd.h" +#include "expression.h" +#include "parser-defs.h" +#include "language.h" +#include "c-lang.h" +#include "inferior.h" +#include "symfile.h" +#include "objfiles.h" +#include "breakpoint.h" +#include "gdbcore.h" +#include "ada-lang.h" +#include "ui-out.h" +#include "block.h" +#include "infcall.h" +#include "dictionary.h" + +struct cleanup *unresolved_names; + +void extract_string (CORE_ADDR addr, char *buf); + +static struct type *ada_create_fundamental_type (struct objfile *, int); + +static void modify_general_field (char *, LONGEST, int, int); + +static struct type *desc_base_type (struct type *); + +static struct type *desc_bounds_type (struct type *); + +static struct value *desc_bounds (struct value *); + +static int fat_pntr_bounds_bitpos (struct type *); + +static int fat_pntr_bounds_bitsize (struct type *); + +static struct type *desc_data_type (struct type *); + +static struct value *desc_data (struct value *); + +static int fat_pntr_data_bitpos (struct type *); + +static int fat_pntr_data_bitsize (struct type *); + +static struct value *desc_one_bound (struct value *, int, int); + +static int desc_bound_bitpos (struct type *, int, int); + +static int desc_bound_bitsize (struct type *, int, int); + +static struct type *desc_index_type (struct type *, int); + +static int desc_arity (struct type *); + +static int ada_type_match (struct type *, struct type *, int); + +static int ada_args_match (struct symbol *, struct value **, int); + +static struct value *place_on_stack (struct value *, CORE_ADDR *); + +static struct value *convert_actual (struct value *, struct type *, + CORE_ADDR *); + +static struct value *make_array_descriptor (struct type *, struct value *, + CORE_ADDR *); + +static void ada_add_block_symbols (struct block *, const char *, + domain_enum, struct objfile *, int); + +static void fill_in_ada_prototype (struct symbol *); + +static int is_nonfunction (struct symbol **, int); + +static void add_defn_to_vec (struct symbol *, struct block *); + +static struct partial_symbol *ada_lookup_partial_symbol (struct partial_symtab + *, const char *, int, + domain_enum, int); + +static struct symtab *symtab_for_sym (struct symbol *); + +static struct value *ada_resolve_subexp (struct expression **, int *, int, + struct type *); + +static void replace_operator_with_call (struct expression **, int, int, int, + struct symbol *, struct block *); + +static int possible_user_operator_p (enum exp_opcode, struct value **); + +static const char *ada_op_name (enum exp_opcode); + +static int numeric_type_p (struct type *); + +static int integer_type_p (struct type *); + +static int scalar_type_p (struct type *); + +static int discrete_type_p (struct type *); + +static char *extended_canonical_line_spec (struct symtab_and_line, + const char *); + +static struct value *evaluate_subexp (struct type *, struct expression *, + int *, enum noside); + +static struct value *evaluate_subexp_type (struct expression *, int *); + +static struct type *ada_create_fundamental_type (struct objfile *, int); + +static int is_dynamic_field (struct type *, int); + +static struct type *to_fixed_variant_branch_type (struct type *, char *, + CORE_ADDR, struct value *); + +static struct type *to_fixed_range_type (char *, struct value *, + struct objfile *); + +static struct type *to_static_fixed_type (struct type *); + +static struct value *unwrap_value (struct value *); + +static struct type *packed_array_type (struct type *, long *); + +static struct type *decode_packed_array_type (struct type *); + +static struct value *decode_packed_array (struct value *); + +static struct value *value_subscript_packed (struct value *, int, + struct value **); + +static struct value *coerce_unspec_val_to_type (struct value *, long, + struct type *); + +static struct value *get_var_value (char *, char *); + +static int lesseq_defined_than (struct symbol *, struct symbol *); + +static int equiv_types (struct type *, struct type *); + +static int is_name_suffix (const char *); + +static int wild_match (const char *, int, const char *); + +static struct symtabs_and_lines find_sal_from_funcs_and_line (const char *, + int, + struct symbol + **, int); + +static int find_line_in_linetable (struct linetable *, int, struct symbol **, + int, int *); + +static int find_next_line_in_linetable (struct linetable *, int, int, int); + +static struct symtabs_and_lines all_sals_for_line (const char *, int, + char ***); + +static void read_all_symtabs (const char *); + +static int is_plausible_func_for_line (struct symbol *, int); + +static struct value *ada_coerce_ref (struct value *); + +static struct value *value_pos_atr (struct value *); + +static struct value *value_val_atr (struct type *, struct value *); + +static struct symbol *standard_lookup (const char *, domain_enum); + +extern void markTimeStart (int index); +extern void markTimeStop (int index); + + + +/* Maximum-sized dynamic type. */ +static unsigned int varsize_limit; + +static const char *ada_completer_word_break_characters = + " \t\n!@#$%^&*()+=|~`}{[]\";:?/,-"; + +/* The name of the symbol to use to get the name of the main subprogram */ +#define ADA_MAIN_PROGRAM_SYMBOL_NAME "__gnat_ada_main_program_name" + + /* Utilities */ + +/* extract_string + * + * read the string located at ADDR from the inferior and store the + * result into BUF + */ +void +extract_string (CORE_ADDR addr, char *buf) +{ + int char_index = 0; + + /* Loop, reading one byte at a time, until we reach the '\000' + end-of-string marker */ + do + { + target_read_memory (addr + char_index * sizeof (char), + buf + char_index * sizeof (char), sizeof (char)); + char_index++; + } + while (buf[char_index - 1] != '\000'); +} + +/* Assuming *OLD_VECT points to an array of *SIZE objects of size + ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, + updating *OLD_VECT and *SIZE as necessary. */ + +void +grow_vect (void **old_vect, size_t * size, size_t min_size, int element_size) +{ + if (*size < min_size) + { + *size *= 2; + if (*size < min_size) + *size = min_size; + *old_vect = xrealloc (*old_vect, *size * element_size); + } +} + +/* True (non-zero) iff TARGET matches FIELD_NAME up to any trailing + suffix of FIELD_NAME beginning "___" */ + +static int +field_name_match (const char *field_name, const char *target) +{ + int len = strlen (target); + return + DEPRECATED_STREQN (field_name, target, len) + && (field_name[len] == '\0' + || (DEPRECATED_STREQN (field_name + len, "___", 3) + && !DEPRECATED_STREQ (field_name + strlen (field_name) - 6, "___XVN"))); +} + + +/* The length of the prefix of NAME prior to any "___" suffix. */ + +int +ada_name_prefix_len (const char *name) +{ + if (name == NULL) + return 0; + else + { + const char *p = strstr (name, "___"); + if (p == NULL) + return strlen (name); + else + return p - name; + } +} + +/* SUFFIX is a suffix of STR. False if STR is null. */ +static int +is_suffix (const char *str, const char *suffix) +{ + int len1, len2; + if (str == NULL) + return 0; + len1 = strlen (str); + len2 = strlen (suffix); + return (len1 >= len2 && DEPRECATED_STREQ (str + len1 - len2, suffix)); +} + +/* Create a value of type TYPE whose contents come from VALADDR, if it + * is non-null, and whose memory address (in the inferior) is + * ADDRESS. */ +struct value * +value_from_contents_and_address (struct type *type, char *valaddr, + CORE_ADDR address) +{ + struct value *v = allocate_value (type); + if (valaddr == NULL) + VALUE_LAZY (v) = 1; + else + memcpy (VALUE_CONTENTS_RAW (v), valaddr, TYPE_LENGTH (type)); + VALUE_ADDRESS (v) = address; + if (address != 0) + VALUE_LVAL (v) = lval_memory; + return v; +} + +/* The contents of value VAL, beginning at offset OFFSET, treated as a + value of type TYPE. The result is an lval in memory if VAL is. */ + +static struct value * +coerce_unspec_val_to_type (struct value *val, long offset, struct type *type) +{ + CHECK_TYPEDEF (type); + if (VALUE_LVAL (val) == lval_memory) + return value_at_lazy (type, + VALUE_ADDRESS (val) + VALUE_OFFSET (val) + offset, + NULL); + else + { + struct value *result = allocate_value (type); + VALUE_LVAL (result) = not_lval; + if (VALUE_ADDRESS (val) == 0) + memcpy (VALUE_CONTENTS_RAW (result), VALUE_CONTENTS (val) + offset, + TYPE_LENGTH (type) > TYPE_LENGTH (VALUE_TYPE (val)) + ? TYPE_LENGTH (VALUE_TYPE (val)) : TYPE_LENGTH (type)); + else + { + VALUE_ADDRESS (result) = + VALUE_ADDRESS (val) + VALUE_OFFSET (val) + offset; + VALUE_LAZY (result) = 1; + } + return result; + } +} + +static char * +cond_offset_host (char *valaddr, long offset) +{ + if (valaddr == NULL) + return NULL; + else + return valaddr + offset; +} + +static CORE_ADDR +cond_offset_target (CORE_ADDR address, long offset) +{ + if (address == 0) + return 0; + else + return address + offset; +} + +/* Perform execute_command on the result of concatenating all + arguments up to NULL. */ +static void +do_command (const char *arg, ...) +{ + int len; + char *cmd; + const char *s; + va_list ap; + + va_start (ap, arg); + len = 0; + s = arg; + cmd = ""; + for (; s != NULL; s = va_arg (ap, const char *)) + { + char *cmd1; + len += strlen (s); + cmd1 = alloca (len + 1); + strcpy (cmd1, cmd); + strcat (cmd1, s); + cmd = cmd1; + } + va_end (ap); + execute_command (cmd, 0); +} + + + /* Language Selection */ + +/* If the main program is in Ada, return language_ada, otherwise return LANG + (the main program is in Ada iif the adainit symbol is found). + + MAIN_PST is not used. */ + +enum language +ada_update_initial_language (enum language lang, + struct partial_symtab *main_pst) +{ + if (lookup_minimal_symbol ("adainit", (const char *) NULL, + (struct objfile *) NULL) != NULL) + /* return language_ada; */ + /* FIXME: language_ada should be defined in defs.h */ + return language_unknown; + + return lang; +} + + + /* Symbols */ + +/* Table of Ada operators and their GNAT-mangled names. Last entry is pair + of NULLs. */ + +const struct ada_opname_map ada_opname_table[] = { + {"Oadd", "\"+\"", BINOP_ADD}, + {"Osubtract", "\"-\"", BINOP_SUB}, + {"Omultiply", "\"*\"", BINOP_MUL}, + {"Odivide", "\"/\"", BINOP_DIV}, + {"Omod", "\"mod\"", BINOP_MOD}, + {"Orem", "\"rem\"", BINOP_REM}, + {"Oexpon", "\"**\"", BINOP_EXP}, + {"Olt", "\"<\"", BINOP_LESS}, + {"Ole", "\"<=\"", BINOP_LEQ}, + {"Ogt", "\">\"", BINOP_GTR}, + {"Oge", "\">=\"", BINOP_GEQ}, + {"Oeq", "\"=\"", BINOP_EQUAL}, + {"One", "\"/=\"", BINOP_NOTEQUAL}, + {"Oand", "\"and\"", BINOP_BITWISE_AND}, + {"Oor", "\"or\"", BINOP_BITWISE_IOR}, + {"Oxor", "\"xor\"", BINOP_BITWISE_XOR}, + {"Oconcat", "\"&\"", BINOP_CONCAT}, + {"Oabs", "\"abs\"", UNOP_ABS}, + {"Onot", "\"not\"", UNOP_LOGICAL_NOT}, + {"Oadd", "\"+\"", UNOP_PLUS}, + {"Osubtract", "\"-\"", UNOP_NEG}, + {NULL, NULL} +}; + +/* True if STR should be suppressed in info listings. */ +static int +is_suppressed_name (const char *str) +{ + if (DEPRECATED_STREQN (str, "_ada_", 5)) + str += 5; + if (str[0] == '_' || str[0] == '\000') + return 1; + else + { + const char *p; + const char *suffix = strstr (str, "___"); + if (suffix != NULL && suffix[3] != 'X') + return 1; + if (suffix == NULL) + suffix = str + strlen (str); + for (p = suffix - 1; p != str; p -= 1) + if (isupper (*p)) + { + int i; + if (p[0] == 'X' && p[-1] != '_') + goto OK; + if (*p != 'O') + return 1; + for (i = 0; ada_opname_table[i].mangled != NULL; i += 1) + if (DEPRECATED_STREQN (ada_opname_table[i].mangled, p, + strlen (ada_opname_table[i].mangled))) + goto OK; + return 1; + OK:; + } + return 0; + } +} + +/* The "mangled" form of DEMANGLED, according to GNAT conventions. + * The result is valid until the next call to ada_mangle. */ +char * +ada_mangle (const char *demangled) +{ + static char *mangling_buffer = NULL; + static size_t mangling_buffer_size = 0; + const char *p; + int k; + + if (demangled == NULL) + return NULL; + + GROW_VECT (mangling_buffer, mangling_buffer_size, + 2 * strlen (demangled) + 10); + + k = 0; + for (p = demangled; *p != '\0'; p += 1) + { + if (*p == '.') + { + mangling_buffer[k] = mangling_buffer[k + 1] = '_'; + k += 2; + } + else if (*p == '"') + { + const struct ada_opname_map *mapping; + + for (mapping = ada_opname_table; + mapping->mangled != NULL && + !DEPRECATED_STREQN (mapping->demangled, p, strlen (mapping->demangled)); + p += 1) + ; + if (mapping->mangled == NULL) + error ("invalid Ada operator name: %s", p); + strcpy (mangling_buffer + k, mapping->mangled); + k += strlen (mapping->mangled); + break; + } + else + { + mangling_buffer[k] = *p; + k += 1; + } + } + + mangling_buffer[k] = '\0'; + return mangling_buffer; +} + +/* Return NAME folded to lower case, or, if surrounded by single + * quotes, unfolded, but with the quotes stripped away. Result good + * to next call. */ +char * +ada_fold_name (const char *name) +{ + static char *fold_buffer = NULL; + static size_t fold_buffer_size = 0; + + int len = strlen (name); + GROW_VECT (fold_buffer, fold_buffer_size, len + 1); + + if (name[0] == '\'') + { + strncpy (fold_buffer, name + 1, len - 2); + fold_buffer[len - 2] = '\000'; + } + else + { + int i; + for (i = 0; i <= len; i += 1) + fold_buffer[i] = tolower (name[i]); + } + + return fold_buffer; +} + +/* Demangle: + 1. Discard final __{DIGIT}+ or ${DIGIT}+ + 2. Convert other instances of embedded "__" to `.'. + 3. Discard leading _ada_. + 4. Convert operator names to the appropriate quoted symbols. + 5. Remove everything after first ___ if it is followed by + 'X'. + 6. Replace TK__ with __, and a trailing B or TKB with nothing. + 7. Put symbols that should be suppressed in <...> brackets. + 8. Remove trailing X[bn]* suffix (indicating names in package bodies). + The resulting string is valid until the next call of ada_demangle. + */ + +char * +ada_demangle (const char *mangled) +{ + int i, j; + int len0; + const char *p; + char *demangled; + int at_start_name; + static char *demangling_buffer = NULL; + static size_t demangling_buffer_size = 0; + + if (DEPRECATED_STREQN (mangled, "_ada_", 5)) + mangled += 5; + + if (mangled[0] == '_' || mangled[0] == '<') + goto Suppress; + + p = strstr (mangled, "___"); + if (p == NULL) + len0 = strlen (mangled); + else + { + if (p[3] == 'X') + len0 = p - mangled; + else + goto Suppress; + } + if (len0 > 3 && DEPRECATED_STREQ (mangled + len0 - 3, "TKB")) + len0 -= 3; + if (len0 > 1 && DEPRECATED_STREQ (mangled + len0 - 1, "B")) + len0 -= 1; + + /* Make demangled big enough for possible expansion by operator name. */ + GROW_VECT (demangling_buffer, demangling_buffer_size, 2 * len0 + 1); + demangled = demangling_buffer; + + if (isdigit (mangled[len0 - 1])) + { + for (i = len0 - 2; i >= 0 && isdigit (mangled[i]); i -= 1) + ; + if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_') + len0 = i - 1; + else if (mangled[i] == '$') + len0 = i; + } + + for (i = 0, j = 0; i < len0 && !isalpha (mangled[i]); i += 1, j += 1) + demangled[j] = mangled[i]; + + at_start_name = 1; + while (i < len0) + { + if (at_start_name && mangled[i] == 'O') + { + int k; + for (k = 0; ada_opname_table[k].mangled != NULL; k += 1) + { + int op_len = strlen (ada_opname_table[k].mangled); + if (DEPRECATED_STREQN + (ada_opname_table[k].mangled + 1, mangled + i + 1, + op_len - 1) && !isalnum (mangled[i + op_len])) + { + strcpy (demangled + j, ada_opname_table[k].demangled); + at_start_name = 0; + i += op_len; + j += strlen (ada_opname_table[k].demangled); + break; + } + } + if (ada_opname_table[k].mangled != NULL) + continue; + } + at_start_name = 0; + + if (i < len0 - 4 && DEPRECATED_STREQN (mangled + i, "TK__", 4)) + i += 2; + if (mangled[i] == 'X' && i != 0 && isalnum (mangled[i - 1])) + { + do + i += 1; + while (i < len0 && (mangled[i] == 'b' || mangled[i] == 'n')); + if (i < len0) + goto Suppress; + } + else if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_') + { + demangled[j] = '.'; + at_start_name = 1; + i += 2; + j += 1; + } + else + { + demangled[j] = mangled[i]; + i += 1; + j += 1; + } + } + demangled[j] = '\000'; + + for (i = 0; demangled[i] != '\0'; i += 1) + if (isupper (demangled[i]) || demangled[i] == ' ') + goto Suppress; + + return demangled; + +Suppress: + GROW_VECT (demangling_buffer, demangling_buffer_size, strlen (mangled) + 3); + demangled = demangling_buffer; + if (mangled[0] == '<') + strcpy (demangled, mangled); + else + sprintf (demangled, "<%s>", mangled); + return demangled; + +} + +/* Returns non-zero iff SYM_NAME matches NAME, ignoring any trailing + * suffixes that encode debugging information or leading _ada_ on + * SYM_NAME (see is_name_suffix commentary for the debugging + * information that is ignored). If WILD, then NAME need only match a + * suffix of SYM_NAME minus the same suffixes. Also returns 0 if + * either argument is NULL. */ + +int +ada_match_name (const char *sym_name, const char *name, int wild) +{ + if (sym_name == NULL || name == NULL) + return 0; + else if (wild) + return wild_match (name, strlen (name), sym_name); + else + { + int len_name = strlen (name); + return (DEPRECATED_STREQN (sym_name, name, len_name) + && is_name_suffix (sym_name + len_name)) + || (DEPRECATED_STREQN (sym_name, "_ada_", 5) + && DEPRECATED_STREQN (sym_name + 5, name, len_name) + && is_name_suffix (sym_name + len_name + 5)); + } +} + +/* True (non-zero) iff in Ada mode, the symbol SYM should be + suppressed in info listings. */ + +int +ada_suppress_symbol_printing (struct symbol *sym) +{ + if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN) + return 1; + else + return is_suppressed_name (DEPRECATED_SYMBOL_NAME (sym)); +} + + + /* Arrays */ + +/* Names of MAX_ADA_DIMENS bounds in P_BOUNDS fields of + array descriptors. */ + +static char *bound_name[] = { + "LB0", "UB0", "LB1", "UB1", "LB2", "UB2", "LB3", "UB3", + "LB4", "UB4", "LB5", "UB5", "LB6", "UB6", "LB7", "UB7" +}; + +/* Maximum number of array dimensions we are prepared to handle. */ + +#define MAX_ADA_DIMENS (sizeof(bound_name) / (2*sizeof(char*))) + +/* Like modify_field, but allows bitpos > wordlength. */ + +static void +modify_general_field (char *addr, LONGEST fieldval, int bitpos, int bitsize) +{ + modify_field (addr + sizeof (LONGEST) * bitpos / (8 * sizeof (LONGEST)), + fieldval, bitpos % (8 * sizeof (LONGEST)), bitsize); +} + + +/* The desc_* routines return primitive portions of array descriptors + (fat pointers). */ + +/* The descriptor or array type, if any, indicated by TYPE; removes + level of indirection, if needed. */ +static struct type * +desc_base_type (struct type *type) +{ + if (type == NULL) + return NULL; + CHECK_TYPEDEF (type); + if (type != NULL && TYPE_CODE (type) == TYPE_CODE_PTR) + return check_typedef (TYPE_TARGET_TYPE (type)); + else + return type; +} + +/* True iff TYPE indicates a "thin" array pointer type. */ +static int +is_thin_pntr (struct type *type) +{ + return + is_suffix (ada_type_name (desc_base_type (type)), "___XUT") + || is_suffix (ada_type_name (desc_base_type (type)), "___XUT___XVE"); +} + +/* The descriptor type for thin pointer type TYPE. */ +static struct type * +thin_descriptor_type (struct type *type) +{ + struct type *base_type = desc_base_type (type); + if (base_type == NULL) + return NULL; + if (is_suffix (ada_type_name (base_type), "___XVE")) + return base_type; + else + { + struct type *alt_type = ada_find_parallel_type (base_type, "___XVE"); + if (alt_type == NULL) + return base_type; + else + return alt_type; + } +} + +/* A pointer to the array data for thin-pointer value VAL. */ +static struct value * +thin_data_pntr (struct value *val) +{ + struct type *type = VALUE_TYPE (val); + if (TYPE_CODE (type) == TYPE_CODE_PTR) + return value_cast (desc_data_type (thin_descriptor_type (type)), + value_copy (val)); + else + return value_from_longest (desc_data_type (thin_descriptor_type (type)), + VALUE_ADDRESS (val) + VALUE_OFFSET (val)); +} + +/* True iff TYPE indicates a "thick" array pointer type. */ +static int +is_thick_pntr (struct type *type) +{ + type = desc_base_type (type); + return (type != NULL && TYPE_CODE (type) == TYPE_CODE_STRUCT + && lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL); +} + +/* If TYPE is the type of an array descriptor (fat or thin pointer) or a + pointer to one, the type of its bounds data; otherwise, NULL. */ +static struct type * +desc_bounds_type (struct type *type) +{ + struct type *r; + + type = desc_base_type (type); + + if (type == NULL) + return NULL; + else if (is_thin_pntr (type)) + { + type = thin_descriptor_type (type); + if (type == NULL) + return NULL; + r = lookup_struct_elt_type (type, "BOUNDS", 1); + if (r != NULL) + return check_typedef (r); + } + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + r = lookup_struct_elt_type (type, "P_BOUNDS", 1); + if (r != NULL) + return check_typedef (TYPE_TARGET_TYPE (check_typedef (r))); + } + return NULL; +} + +/* If ARR is an array descriptor (fat or thin pointer), or pointer to + one, a pointer to its bounds data. Otherwise NULL. */ +static struct value * +desc_bounds (struct value *arr) +{ + struct type *type = check_typedef (VALUE_TYPE (arr)); + if (is_thin_pntr (type)) + { + struct type *bounds_type = + desc_bounds_type (thin_descriptor_type (type)); + LONGEST addr; + + if (desc_bounds_type == NULL) + error ("Bad GNAT array descriptor"); + + /* NOTE: The following calculation is not really kosher, but + since desc_type is an XVE-encoded type (and shouldn't be), + the correct calculation is a real pain. FIXME (and fix GCC). */ + if (TYPE_CODE (type) == TYPE_CODE_PTR) + addr = value_as_long (arr); + else + addr = VALUE_ADDRESS (arr) + VALUE_OFFSET (arr); + + return + value_from_longest (lookup_pointer_type (bounds_type), + addr - TYPE_LENGTH (bounds_type)); + } + + else if (is_thick_pntr (type)) + return value_struct_elt (&arr, NULL, "P_BOUNDS", NULL, + "Bad GNAT array descriptor"); + else + return NULL; +} + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + position of the field containing the address of the bounds data. */ +static int +fat_pntr_bounds_bitpos (struct type *type) +{ + return TYPE_FIELD_BITPOS (desc_base_type (type), 1); +} + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + size of the field containing the address of the bounds data. */ +static int +fat_pntr_bounds_bitsize (struct type *type) +{ + type = desc_base_type (type); + + if (TYPE_FIELD_BITSIZE (type, 1) > 0) + return TYPE_FIELD_BITSIZE (type, 1); + else + return 8 * TYPE_LENGTH (check_typedef (TYPE_FIELD_TYPE (type, 1))); +} + +/* If TYPE is the type of an array descriptor (fat or thin pointer) or a + pointer to one, the type of its array data (a + pointer-to-array-with-no-bounds type); otherwise, NULL. Use + ada_type_of_array to get an array type with bounds data. */ +static struct type * +desc_data_type (struct type *type) +{ + type = desc_base_type (type); + + /* NOTE: The following is bogus; see comment in desc_bounds. */ + if (is_thin_pntr (type)) + return lookup_pointer_type + (desc_base_type (TYPE_FIELD_TYPE (thin_descriptor_type (type), 1))); + else if (is_thick_pntr (type)) + return lookup_struct_elt_type (type, "P_ARRAY", 1); + else + return NULL; +} + +/* If ARR is an array descriptor (fat or thin pointer), a pointer to + its array data. */ +static struct value * +desc_data (struct value *arr) +{ + struct type *type = VALUE_TYPE (arr); + if (is_thin_pntr (type)) + return thin_data_pntr (arr); + else if (is_thick_pntr (type)) + return value_struct_elt (&arr, NULL, "P_ARRAY", NULL, + "Bad GNAT array descriptor"); + else + return NULL; +} + + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + position of the field containing the address of the data. */ +static int +fat_pntr_data_bitpos (struct type *type) +{ + return TYPE_FIELD_BITPOS (desc_base_type (type), 0); +} + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + size of the field containing the address of the data. */ +static int +fat_pntr_data_bitsize (struct type *type) +{ + type = desc_base_type (type); + + if (TYPE_FIELD_BITSIZE (type, 0) > 0) + return TYPE_FIELD_BITSIZE (type, 0); + else + return TARGET_CHAR_BIT * TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)); +} + +/* If BOUNDS is an array-bounds structure (or pointer to one), return + the Ith lower bound stored in it, if WHICH is 0, and the Ith upper + bound, if WHICH is 1. The first bound is I=1. */ +static struct value * +desc_one_bound (struct value *bounds, int i, int which) +{ + return value_struct_elt (&bounds, NULL, bound_name[2 * i + which - 2], NULL, + "Bad GNAT array descriptor bounds"); +} + +/* If BOUNDS is an array-bounds structure type, return the bit position + of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper + bound, if WHICH is 1. The first bound is I=1. */ +static int +desc_bound_bitpos (struct type *type, int i, int which) +{ + return TYPE_FIELD_BITPOS (desc_base_type (type), 2 * i + which - 2); +} + +/* If BOUNDS is an array-bounds structure type, return the bit field size + of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper + bound, if WHICH is 1. The first bound is I=1. */ +static int +desc_bound_bitsize (struct type *type, int i, int which) +{ + type = desc_base_type (type); + + if (TYPE_FIELD_BITSIZE (type, 2 * i + which - 2) > 0) + return TYPE_FIELD_BITSIZE (type, 2 * i + which - 2); + else + return 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, 2 * i + which - 2)); +} + +/* If TYPE is the type of an array-bounds structure, the type of its + Ith bound (numbering from 1). Otherwise, NULL. */ +static struct type * +desc_index_type (struct type *type, int i) +{ + type = desc_base_type (type); + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + return lookup_struct_elt_type (type, bound_name[2 * i - 2], 1); + else + return NULL; +} + +/* The number of index positions in the array-bounds type TYPE. 0 + if TYPE is NULL. */ +static int +desc_arity (struct type *type) +{ + type = desc_base_type (type); + + if (type != NULL) + return TYPE_NFIELDS (type) / 2; + return 0; +} + + +/* Non-zero iff type is a simple array type (or pointer to one). */ +int +ada_is_simple_array (struct type *type) +{ + if (type == NULL) + return 0; + CHECK_TYPEDEF (type); + return (TYPE_CODE (type) == TYPE_CODE_ARRAY + || (TYPE_CODE (type) == TYPE_CODE_PTR + && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY)); +} + +/* Non-zero iff type belongs to a GNAT array descriptor. */ +int +ada_is_array_descriptor (struct type *type) +{ + struct type *data_type = desc_data_type (type); + + if (type == NULL) + return 0; + CHECK_TYPEDEF (type); + return + data_type != NULL + && ((TYPE_CODE (data_type) == TYPE_CODE_PTR + && TYPE_TARGET_TYPE (data_type) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (data_type)) == TYPE_CODE_ARRAY) + || + TYPE_CODE (data_type) == TYPE_CODE_ARRAY) + && desc_arity (desc_bounds_type (type)) > 0; +} + +/* Non-zero iff type is a partially mal-formed GNAT array + descriptor. (FIXME: This is to compensate for some problems with + debugging output from GNAT. Re-examine periodically to see if it + is still needed. */ +int +ada_is_bogus_array_descriptor (struct type *type) +{ + return + type != NULL + && TYPE_CODE (type) == TYPE_CODE_STRUCT + && (lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL + || lookup_struct_elt_type (type, "P_ARRAY", 1) != NULL) + && !ada_is_array_descriptor (type); +} + + +/* If ARR has a record type in the form of a standard GNAT array descriptor, + (fat pointer) returns the type of the array data described---specifically, + a pointer-to-array type. If BOUNDS is non-zero, the bounds data are filled + in from the descriptor; otherwise, they are left unspecified. If + the ARR denotes a null array descriptor and BOUNDS is non-zero, + returns NULL. The result is simply the type of ARR if ARR is not + a descriptor. */ +struct type * +ada_type_of_array (struct value *arr, int bounds) +{ + if (ada_is_packed_array_type (VALUE_TYPE (arr))) + return decode_packed_array_type (VALUE_TYPE (arr)); + + if (!ada_is_array_descriptor (VALUE_TYPE (arr))) + return VALUE_TYPE (arr); + + if (!bounds) + return + check_typedef (TYPE_TARGET_TYPE (desc_data_type (VALUE_TYPE (arr)))); + else + { + struct type *elt_type; + int arity; + struct value *descriptor; + struct objfile *objf = TYPE_OBJFILE (VALUE_TYPE (arr)); + + elt_type = ada_array_element_type (VALUE_TYPE (arr), -1); + arity = ada_array_arity (VALUE_TYPE (arr)); + + if (elt_type == NULL || arity == 0) + return check_typedef (VALUE_TYPE (arr)); + + descriptor = desc_bounds (arr); + if (value_as_long (descriptor) == 0) + return NULL; + while (arity > 0) + { + struct type *range_type = alloc_type (objf); + struct type *array_type = alloc_type (objf); + struct value *low = desc_one_bound (descriptor, arity, 0); + struct value *high = desc_one_bound (descriptor, arity, 1); + arity -= 1; + + create_range_type (range_type, VALUE_TYPE (low), + (int) value_as_long (low), + (int) value_as_long (high)); + elt_type = create_array_type (array_type, elt_type, range_type); + } + + return lookup_pointer_type (elt_type); + } +} + +/* If ARR does not represent an array, returns ARR unchanged. + Otherwise, returns either a standard GDB array with bounds set + appropriately or, if ARR is a non-null fat pointer, a pointer to a standard + GDB array. Returns NULL if ARR is a null fat pointer. */ +struct value * +ada_coerce_to_simple_array_ptr (struct value *arr) +{ + if (ada_is_array_descriptor (VALUE_TYPE (arr))) + { + struct type *arrType = ada_type_of_array (arr, 1); + if (arrType == NULL) + return NULL; + return value_cast (arrType, value_copy (desc_data (arr))); + } + else if (ada_is_packed_array_type (VALUE_TYPE (arr))) + return decode_packed_array (arr); + else + return arr; +} + +/* If ARR does not represent an array, returns ARR unchanged. + Otherwise, returns a standard GDB array describing ARR (which may + be ARR itself if it already is in the proper form). */ +struct value * +ada_coerce_to_simple_array (struct value *arr) +{ + if (ada_is_array_descriptor (VALUE_TYPE (arr))) + { + struct value *arrVal = ada_coerce_to_simple_array_ptr (arr); + if (arrVal == NULL) + error ("Bounds unavailable for null array pointer."); + return value_ind (arrVal); + } + else if (ada_is_packed_array_type (VALUE_TYPE (arr))) + return decode_packed_array (arr); + else + return arr; +} + +/* If TYPE represents a GNAT array type, return it translated to an + ordinary GDB array type (possibly with BITSIZE fields indicating + packing). For other types, is the identity. */ +struct type * +ada_coerce_to_simple_array_type (struct type *type) +{ + struct value *mark = value_mark (); + struct value *dummy = value_from_longest (builtin_type_long, 0); + struct type *result; + VALUE_TYPE (dummy) = type; + result = ada_type_of_array (dummy, 0); + value_free_to_mark (dummy); + return result; +} + +/* Non-zero iff TYPE represents a standard GNAT packed-array type. */ +int +ada_is_packed_array_type (struct type *type) +{ + if (type == NULL) + return 0; + CHECK_TYPEDEF (type); + return + ada_type_name (type) != NULL + && strstr (ada_type_name (type), "___XP") != NULL; +} + +/* Given that TYPE is a standard GDB array type with all bounds filled + in, and that the element size of its ultimate scalar constituents + (that is, either its elements, or, if it is an array of arrays, its + elements' elements, etc.) is *ELT_BITS, return an identical type, + but with the bit sizes of its elements (and those of any + constituent arrays) recorded in the BITSIZE components of its + TYPE_FIELD_BITSIZE values, and with *ELT_BITS set to its total size + in bits. */ +static struct type * +packed_array_type (struct type *type, long *elt_bits) +{ + struct type *new_elt_type; + struct type *new_type; + LONGEST low_bound, high_bound; + + CHECK_TYPEDEF (type); + if (TYPE_CODE (type) != TYPE_CODE_ARRAY) + return type; + + new_type = alloc_type (TYPE_OBJFILE (type)); + new_elt_type = packed_array_type (check_typedef (TYPE_TARGET_TYPE (type)), + elt_bits); + create_array_type (new_type, new_elt_type, TYPE_FIELD_TYPE (type, 0)); + TYPE_FIELD_BITSIZE (new_type, 0) = *elt_bits; + TYPE_NAME (new_type) = ada_type_name (type); + + if (get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), + &low_bound, &high_bound) < 0) + low_bound = high_bound = 0; + if (high_bound < low_bound) + *elt_bits = TYPE_LENGTH (new_type) = 0; + else + { + *elt_bits *= (high_bound - low_bound + 1); + TYPE_LENGTH (new_type) = + (*elt_bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; + } + + /* TYPE_FLAGS (new_type) |= TYPE_FLAG_FIXED_INSTANCE; */ + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + return new_type; +} + +/* The array type encoded by TYPE, where ada_is_packed_array_type (TYPE). + */ +static struct type * +decode_packed_array_type (struct type *type) +{ + struct symbol **syms; + struct block **blocks; + const char *raw_name = ada_type_name (check_typedef (type)); + char *name = (char *) alloca (strlen (raw_name) + 1); + char *tail = strstr (raw_name, "___XP"); + struct type *shadow_type; + long bits; + int i, n; + + memcpy (name, raw_name, tail - raw_name); + name[tail - raw_name] = '\000'; + + /* NOTE: Use ada_lookup_symbol_list because of bug in some versions + * of gcc (Solaris, e.g.). FIXME when compiler is fixed. */ + n = ada_lookup_symbol_list (name, get_selected_block (NULL), + VAR_DOMAIN, &syms, &blocks); + for (i = 0; i < n; i += 1) + if (syms[i] != NULL && SYMBOL_CLASS (syms[i]) == LOC_TYPEDEF + && DEPRECATED_STREQ (name, ada_type_name (SYMBOL_TYPE (syms[i])))) + break; + if (i >= n) + { + warning ("could not find bounds information on packed array"); + return NULL; + } + shadow_type = SYMBOL_TYPE (syms[i]); + + if (TYPE_CODE (shadow_type) != TYPE_CODE_ARRAY) + { + warning ("could not understand bounds information on packed array"); + return NULL; + } + + if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1) + { + warning ("could not understand bit size information on packed array"); + return NULL; + } + + return packed_array_type (shadow_type, &bits); +} + +/* Given that ARR is a struct value* indicating a GNAT packed array, + returns a simple array that denotes that array. Its type is a + standard GDB array type except that the BITSIZEs of the array + target types are set to the number of bits in each element, and the + type length is set appropriately. */ + +static struct value * +decode_packed_array (struct value *arr) +{ + struct type *type = decode_packed_array_type (VALUE_TYPE (arr)); + + if (type == NULL) + { + error ("can't unpack array"); + return NULL; + } + else + return coerce_unspec_val_to_type (arr, 0, type); +} + + +/* The value of the element of packed array ARR at the ARITY indices + given in IND. ARR must be a simple array. */ + +static struct value * +value_subscript_packed (struct value *arr, int arity, struct value **ind) +{ + int i; + int bits, elt_off, bit_off; + long elt_total_bit_offset; + struct type *elt_type; + struct value *v; + + bits = 0; + elt_total_bit_offset = 0; + elt_type = check_typedef (VALUE_TYPE (arr)); + for (i = 0; i < arity; i += 1) + { + if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY + || TYPE_FIELD_BITSIZE (elt_type, 0) == 0) + error + ("attempt to do packed indexing of something other than a packed array"); + else + { + struct type *range_type = TYPE_INDEX_TYPE (elt_type); + LONGEST lowerbound, upperbound; + LONGEST idx; + + if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0) + { + warning ("don't know bounds of array"); + lowerbound = upperbound = 0; + } + + idx = value_as_long (value_pos_atr (ind[i])); + if (idx < lowerbound || idx > upperbound) + warning ("packed array index %ld out of bounds", (long) idx); + bits = TYPE_FIELD_BITSIZE (elt_type, 0); + elt_total_bit_offset += (idx - lowerbound) * bits; + elt_type = check_typedef (TYPE_TARGET_TYPE (elt_type)); + } + } + elt_off = elt_total_bit_offset / HOST_CHAR_BIT; + bit_off = elt_total_bit_offset % HOST_CHAR_BIT; + + v = ada_value_primitive_packed_val (arr, NULL, elt_off, bit_off, + bits, elt_type); + if (VALUE_LVAL (arr) == lval_internalvar) + VALUE_LVAL (v) = lval_internalvar_component; + else + VALUE_LVAL (v) = VALUE_LVAL (arr); + return v; +} + +/* Non-zero iff TYPE includes negative integer values. */ + +static int +has_negatives (struct type *type) +{ + switch (TYPE_CODE (type)) + { + default: + return 0; + case TYPE_CODE_INT: + return !TYPE_UNSIGNED (type); + case TYPE_CODE_RANGE: + return TYPE_LOW_BOUND (type) < 0; + } +} + + +/* Create a new value of type TYPE from the contents of OBJ starting + at byte OFFSET, and bit offset BIT_OFFSET within that byte, + proceeding for BIT_SIZE bits. If OBJ is an lval in memory, then + assigning through the result will set the field fetched from. OBJ + may also be NULL, in which case, VALADDR+OFFSET must address the + start of storage containing the packed value. The value returned + in this case is never an lval. + Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */ + +struct value * +ada_value_primitive_packed_val (struct value *obj, char *valaddr, long offset, + int bit_offset, int bit_size, + struct type *type) +{ + struct value *v; + int src, /* Index into the source area. */ + targ, /* Index into the target area. */ + i, srcBitsLeft, /* Number of source bits left to move. */ + nsrc, ntarg, /* Number of source and target bytes. */ + unusedLS, /* Number of bits in next significant + * byte of source that are unused. */ + accumSize; /* Number of meaningful bits in accum */ + unsigned char *bytes; /* First byte containing data to unpack. */ + unsigned char *unpacked; + unsigned long accum; /* Staging area for bits being transferred */ + unsigned char sign; + int len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8; + /* Transmit bytes from least to most significant; delta is the + * direction the indices move. */ + int delta = BITS_BIG_ENDIAN ? -1 : 1; + + CHECK_TYPEDEF (type); + + if (obj == NULL) + { + v = allocate_value (type); + bytes = (unsigned char *) (valaddr + offset); + } + else if (VALUE_LAZY (obj)) + { + v = value_at (type, + VALUE_ADDRESS (obj) + VALUE_OFFSET (obj) + offset, NULL); + bytes = (unsigned char *) alloca (len); + read_memory (VALUE_ADDRESS (v), bytes, len); + } + else + { + v = allocate_value (type); + bytes = (unsigned char *) VALUE_CONTENTS (obj) + offset; + } + + if (obj != NULL) + { + VALUE_LVAL (v) = VALUE_LVAL (obj); + if (VALUE_LVAL (obj) == lval_internalvar) + VALUE_LVAL (v) = lval_internalvar_component; + VALUE_ADDRESS (v) = VALUE_ADDRESS (obj) + VALUE_OFFSET (obj) + offset; + VALUE_BITPOS (v) = bit_offset + VALUE_BITPOS (obj); + VALUE_BITSIZE (v) = bit_size; + if (VALUE_BITPOS (v) >= HOST_CHAR_BIT) + { + VALUE_ADDRESS (v) += 1; + VALUE_BITPOS (v) -= HOST_CHAR_BIT; + } + } + else + VALUE_BITSIZE (v) = bit_size; + unpacked = (unsigned char *) VALUE_CONTENTS (v); + + srcBitsLeft = bit_size; + nsrc = len; + ntarg = TYPE_LENGTH (type); + sign = 0; + if (bit_size == 0) + { + memset (unpacked, 0, TYPE_LENGTH (type)); + return v; + } + else if (BITS_BIG_ENDIAN) + { + src = len - 1; + if (has_negatives (type) && + ((bytes[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1)))) + sign = ~0; + + unusedLS = + (HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT) + % HOST_CHAR_BIT; + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + case TYPE_CODE_UNION: + case TYPE_CODE_STRUCT: + /* Non-scalar values must be aligned at a byte boundary. */ + accumSize = + (HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT; + /* And are placed at the beginning (most-significant) bytes + * of the target. */ + targ = src; + break; + default: + accumSize = 0; + targ = TYPE_LENGTH (type) - 1; + break; + } + } + else + { + int sign_bit_offset = (bit_size + bit_offset - 1) % 8; + + src = targ = 0; + unusedLS = bit_offset; + accumSize = 0; + + if (has_negatives (type) && (bytes[len - 1] & (1 << sign_bit_offset))) + sign = ~0; + } + + accum = 0; + while (nsrc > 0) + { + /* Mask for removing bits of the next source byte that are not + * part of the value. */ + unsigned int unusedMSMask = + (1 << (srcBitsLeft >= HOST_CHAR_BIT ? HOST_CHAR_BIT : srcBitsLeft)) - + 1; + /* Sign-extend bits for this byte. */ + unsigned int signMask = sign & ~unusedMSMask; + accum |= + (((bytes[src] >> unusedLS) & unusedMSMask) | signMask) << accumSize; + accumSize += HOST_CHAR_BIT - unusedLS; + if (accumSize >= HOST_CHAR_BIT) + { + unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT); + accumSize -= HOST_CHAR_BIT; + accum >>= HOST_CHAR_BIT; + ntarg -= 1; + targ += delta; + } + srcBitsLeft -= HOST_CHAR_BIT - unusedLS; + unusedLS = 0; + nsrc -= 1; + src += delta; + } + while (ntarg > 0) + { + accum |= sign << accumSize; + unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT); + accumSize -= HOST_CHAR_BIT; + accum >>= HOST_CHAR_BIT; + ntarg -= 1; + targ += delta; + } + + return v; +} + +/* Move N bits from SOURCE, starting at bit offset SRC_OFFSET to + TARGET, starting at bit offset TARG_OFFSET. SOURCE and TARGET must + not overlap. */ +static void +move_bits (char *target, int targ_offset, char *source, int src_offset, int n) +{ + unsigned int accum, mask; + int accum_bits, chunk_size; + + target += targ_offset / HOST_CHAR_BIT; + targ_offset %= HOST_CHAR_BIT; + source += src_offset / HOST_CHAR_BIT; + src_offset %= HOST_CHAR_BIT; + if (BITS_BIG_ENDIAN) + { + accum = (unsigned char) *source; + source += 1; + accum_bits = HOST_CHAR_BIT - src_offset; + + while (n > 0) + { + int unused_right; + accum = (accum << HOST_CHAR_BIT) + (unsigned char) *source; + accum_bits += HOST_CHAR_BIT; + source += 1; + chunk_size = HOST_CHAR_BIT - targ_offset; + if (chunk_size > n) + chunk_size = n; + unused_right = HOST_CHAR_BIT - (chunk_size + targ_offset); + mask = ((1 << chunk_size) - 1) << unused_right; + *target = + (*target & ~mask) + | ((accum >> (accum_bits - chunk_size - unused_right)) & mask); + n -= chunk_size; + accum_bits -= chunk_size; + target += 1; + targ_offset = 0; + } + } + else + { + accum = (unsigned char) *source >> src_offset; + source += 1; + accum_bits = HOST_CHAR_BIT - src_offset; + + while (n > 0) + { + accum = accum + ((unsigned char) *source << accum_bits); + accum_bits += HOST_CHAR_BIT; + source += 1; + chunk_size = HOST_CHAR_BIT - targ_offset; + if (chunk_size > n) + chunk_size = n; + mask = ((1 << chunk_size) - 1) << targ_offset; + *target = (*target & ~mask) | ((accum << targ_offset) & mask); + n -= chunk_size; + accum_bits -= chunk_size; + accum >>= chunk_size; + target += 1; + targ_offset = 0; + } + } +} + + +/* Store the contents of FROMVAL into the location of TOVAL. + Return a new value with the location of TOVAL and contents of + FROMVAL. Handles assignment into packed fields that have + floating-point or non-scalar types. */ + +static struct value * +ada_value_assign (struct value *toval, struct value *fromval) +{ + struct type *type = VALUE_TYPE (toval); + int bits = VALUE_BITSIZE (toval); + + if (!toval->modifiable) + error ("Left operand of assignment is not a modifiable lvalue."); + + COERCE_REF (toval); + + if (VALUE_LVAL (toval) == lval_memory + && bits > 0 + && (TYPE_CODE (type) == TYPE_CODE_FLT + || TYPE_CODE (type) == TYPE_CODE_STRUCT)) + { + int len = + (VALUE_BITPOS (toval) + bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; + char *buffer = (char *) alloca (len); + struct value *val; + + if (TYPE_CODE (type) == TYPE_CODE_FLT) + fromval = value_cast (type, fromval); + + read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), buffer, len); + if (BITS_BIG_ENDIAN) + move_bits (buffer, VALUE_BITPOS (toval), + VALUE_CONTENTS (fromval), + TYPE_LENGTH (VALUE_TYPE (fromval)) * TARGET_CHAR_BIT - + bits, bits); + else + move_bits (buffer, VALUE_BITPOS (toval), VALUE_CONTENTS (fromval), + 0, bits); + write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), buffer, + len); + + val = value_copy (toval); + memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval), + TYPE_LENGTH (type)); + VALUE_TYPE (val) = type; + + return val; + } + + return value_assign (toval, fromval); +} + + +/* The value of the element of array ARR at the ARITY indices given in IND. + ARR may be either a simple array, GNAT array descriptor, or pointer + thereto. */ + +struct value * +ada_value_subscript (struct value *arr, int arity, struct value **ind) +{ + int k; + struct value *elt; + struct type *elt_type; + + elt = ada_coerce_to_simple_array (arr); + + elt_type = check_typedef (VALUE_TYPE (elt)); + if (TYPE_CODE (elt_type) == TYPE_CODE_ARRAY + && TYPE_FIELD_BITSIZE (elt_type, 0) > 0) + return value_subscript_packed (elt, arity, ind); + + for (k = 0; k < arity; k += 1) + { + if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY) + error ("too many subscripts (%d expected)", k); + elt = value_subscript (elt, value_pos_atr (ind[k])); + } + return elt; +} + +/* Assuming ARR is a pointer to a standard GDB array of type TYPE, the + value of the element of *ARR at the ARITY indices given in + IND. Does not read the entire array into memory. */ + +struct value * +ada_value_ptr_subscript (struct value *arr, struct type *type, int arity, + struct value **ind) +{ + int k; + + for (k = 0; k < arity; k += 1) + { + LONGEST lwb, upb; + struct value *idx; + + if (TYPE_CODE (type) != TYPE_CODE_ARRAY) + error ("too many subscripts (%d expected)", k); + arr = value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), + value_copy (arr)); + get_discrete_bounds (TYPE_INDEX_TYPE (type), &lwb, &upb); + if (lwb == 0) + idx = ind[k]; + else + idx = value_sub (ind[k], value_from_longest (builtin_type_int, lwb)); + arr = value_add (arr, idx); + type = TYPE_TARGET_TYPE (type); + } + + return value_ind (arr); +} + +/* If type is a record type in the form of a standard GNAT array + descriptor, returns the number of dimensions for type. If arr is a + simple array, returns the number of "array of"s that prefix its + type designation. Otherwise, returns 0. */ + +int +ada_array_arity (struct type *type) +{ + int arity; + + if (type == NULL) + return 0; + + type = desc_base_type (type); + + arity = 0; + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + return desc_arity (desc_bounds_type (type)); + else + while (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + arity += 1; + type = check_typedef (TYPE_TARGET_TYPE (type)); + } + + return arity; +} + +/* If TYPE is a record type in the form of a standard GNAT array + descriptor or a simple array type, returns the element type for + TYPE after indexing by NINDICES indices, or by all indices if + NINDICES is -1. Otherwise, returns NULL. */ + +struct type * +ada_array_element_type (struct type *type, int nindices) +{ + type = desc_base_type (type); + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + int k; + struct type *p_array_type; + + p_array_type = desc_data_type (type); + + k = ada_array_arity (type); + if (k == 0) + return NULL; + + /* Initially p_array_type = elt_type(*)[]...(k times)...[] */ + if (nindices >= 0 && k > nindices) + k = nindices; + p_array_type = TYPE_TARGET_TYPE (p_array_type); + while (k > 0 && p_array_type != NULL) + { + p_array_type = check_typedef (TYPE_TARGET_TYPE (p_array_type)); + k -= 1; + } + return p_array_type; + } + else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + while (nindices != 0 && TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + type = TYPE_TARGET_TYPE (type); + nindices -= 1; + } + return type; + } + + return NULL; +} + +/* The type of nth index in arrays of given type (n numbering from 1). Does + not examine memory. */ + +struct type * +ada_index_type (struct type *type, int n) +{ + type = desc_base_type (type); + + if (n > ada_array_arity (type)) + return NULL; + + if (ada_is_simple_array (type)) + { + int i; + + for (i = 1; i < n; i += 1) + type = TYPE_TARGET_TYPE (type); + + return TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)); + } + else + return desc_index_type (desc_bounds_type (type), n); +} + +/* Given that arr is an array type, returns the lower bound of the + Nth index (numbering from 1) if WHICH is 0, and the upper bound if + WHICH is 1. This returns bounds 0 .. -1 if ARR_TYPE is an + array-descriptor type. If TYPEP is non-null, *TYPEP is set to the + bounds type. It works for other arrays with bounds supplied by + run-time quantities other than discriminants. */ + +LONGEST +ada_array_bound_from_type (struct type * arr_type, int n, int which, + struct type ** typep) +{ + struct type *type; + struct type *index_type_desc; + + if (ada_is_packed_array_type (arr_type)) + arr_type = decode_packed_array_type (arr_type); + + if (arr_type == NULL || !ada_is_simple_array (arr_type)) + { + if (typep != NULL) + *typep = builtin_type_int; + return (LONGEST) - which; + } + + if (TYPE_CODE (arr_type) == TYPE_CODE_PTR) + type = TYPE_TARGET_TYPE (arr_type); + else + type = arr_type; + + index_type_desc = ada_find_parallel_type (type, "___XA"); + if (index_type_desc == NULL) + { + struct type *range_type; + struct type *index_type; + + while (n > 1) + { + type = TYPE_TARGET_TYPE (type); + n -= 1; + } + + range_type = TYPE_INDEX_TYPE (type); + index_type = TYPE_TARGET_TYPE (range_type); + if (TYPE_CODE (index_type) == TYPE_CODE_UNDEF) + index_type = builtin_type_long; + if (typep != NULL) + *typep = index_type; + return + (LONGEST) (which == 0 + ? TYPE_LOW_BOUND (range_type) + : TYPE_HIGH_BOUND (range_type)); + } + else + { + struct type *index_type = + to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, n - 1), + NULL, TYPE_OBJFILE (arr_type)); + if (typep != NULL) + *typep = TYPE_TARGET_TYPE (index_type); + return + (LONGEST) (which == 0 + ? TYPE_LOW_BOUND (index_type) + : TYPE_HIGH_BOUND (index_type)); + } +} + +/* Given that arr is an array value, returns the lower bound of the + nth index (numbering from 1) if which is 0, and the upper bound if + which is 1. This routine will also work for arrays with bounds + supplied by run-time quantities other than discriminants. */ + +struct value * +ada_array_bound (struct value *arr, int n, int which) +{ + struct type *arr_type = VALUE_TYPE (arr); + + if (ada_is_packed_array_type (arr_type)) + return ada_array_bound (decode_packed_array (arr), n, which); + else if (ada_is_simple_array (arr_type)) + { + struct type *type; + LONGEST v = ada_array_bound_from_type (arr_type, n, which, &type); + return value_from_longest (type, v); + } + else + return desc_one_bound (desc_bounds (arr), n, which); +} + +/* Given that arr is an array value, returns the length of the + nth index. This routine will also work for arrays with bounds + supplied by run-time quantities other than discriminants. Does not + work for arrays indexed by enumeration types with representation + clauses at the moment. */ + +struct value * +ada_array_length (struct value *arr, int n) +{ + struct type *arr_type = check_typedef (VALUE_TYPE (arr)); + struct type *index_type_desc; + + if (ada_is_packed_array_type (arr_type)) + return ada_array_length (decode_packed_array (arr), n); + + if (ada_is_simple_array (arr_type)) + { + struct type *type; + LONGEST v = + ada_array_bound_from_type (arr_type, n, 1, &type) - + ada_array_bound_from_type (arr_type, n, 0, NULL) + 1; + return value_from_longest (type, v); + } + else + return + value_from_longest (builtin_type_ada_int, + value_as_long (desc_one_bound (desc_bounds (arr), + n, 1)) + - value_as_long (desc_one_bound (desc_bounds (arr), + n, 0)) + 1); +} + + + /* Name resolution */ + +/* The "demangled" name for the user-definable Ada operator corresponding + to op. */ + +static const char * +ada_op_name (enum exp_opcode op) +{ + int i; + + for (i = 0; ada_opname_table[i].mangled != NULL; i += 1) + { + if (ada_opname_table[i].op == op) + return ada_opname_table[i].demangled; + } + error ("Could not find operator name for opcode"); +} + + +/* Same as evaluate_type (*EXP), but resolves ambiguous symbol + references (OP_UNRESOLVED_VALUES) and converts operators that are + user-defined into appropriate function calls. If CONTEXT_TYPE is + non-null, it provides a preferred result type [at the moment, only + type void has any effect---causing procedures to be preferred over + functions in calls]. A null CONTEXT_TYPE indicates that a non-void + return type is preferred. The variable unresolved_names contains a list + of character strings referenced by expout that should be freed. + May change (expand) *EXP. */ + +void +ada_resolve (struct expression **expp, struct type *context_type) +{ + int pc; + pc = 0; + ada_resolve_subexp (expp, &pc, 1, context_type); +} + +/* Resolve the operator of the subexpression beginning at + position *POS of *EXPP. "Resolving" consists of replacing + OP_UNRESOLVED_VALUE with an appropriate OP_VAR_VALUE, replacing + built-in operators with function calls to user-defined operators, + where appropriate, and (when DEPROCEDURE_P is non-zero), converting + function-valued variables into parameterless calls. May expand + EXP. The CONTEXT_TYPE functions as in ada_resolve, above. */ + +static struct value * +ada_resolve_subexp (struct expression **expp, int *pos, int deprocedure_p, + struct type *context_type) +{ + int pc = *pos; + int i; + struct expression *exp; /* Convenience: == *expp */ + enum exp_opcode op = (*expp)->elts[pc].opcode; + struct value **argvec; /* Vector of operand types (alloca'ed). */ + int nargs; /* Number of operands */ + + argvec = NULL; + nargs = 0; + exp = *expp; + + /* Pass one: resolve operands, saving their types and updating *pos. */ + switch (op) + { + case OP_VAR_VALUE: + /* case OP_UNRESOLVED_VALUE: */ + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + *pos += 4; + break; + + case OP_FUNCALL: + nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1; + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* if (exp->elts[pc+3].opcode == OP_UNRESOLVED_VALUE) + { + *pos += 7; + + argvec = (struct value* *) alloca (sizeof (struct value*) * (nargs + 1)); + for (i = 0; i < nargs-1; i += 1) + argvec[i] = ada_resolve_subexp (expp, pos, 1, NULL); + argvec[i] = NULL; + } + else + { + *pos += 3; + ada_resolve_subexp (expp, pos, 0, NULL); + for (i = 1; i < nargs; i += 1) + ada_resolve_subexp (expp, pos, 1, NULL); + } + */ + exp = *expp; + break; + + /* FIXME: UNOP_QUAL should be defined in expression.h */ + /* case UNOP_QUAL: + nargs = 1; + *pos += 3; + ada_resolve_subexp (expp, pos, 1, exp->elts[pc + 1].type); + exp = *expp; + break; + */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + /* case OP_ATTRIBUTE: + nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1; + *pos += 4; + for (i = 0; i < nargs; i += 1) + ada_resolve_subexp (expp, pos, 1, NULL); + exp = *expp; + break; + */ + case UNOP_ADDR: + nargs = 1; + *pos += 1; + ada_resolve_subexp (expp, pos, 0, NULL); + exp = *expp; + break; + + case BINOP_ASSIGN: + { + struct value *arg1; + nargs = 2; + *pos += 1; + arg1 = ada_resolve_subexp (expp, pos, 0, NULL); + if (arg1 == NULL) + ada_resolve_subexp (expp, pos, 1, NULL); + else + ada_resolve_subexp (expp, pos, 1, VALUE_TYPE (arg1)); + break; + } + + default: + switch (op) + { + default: + error ("Unexpected operator during name resolution"); + case UNOP_CAST: + /* case UNOP_MBR: + nargs = 1; + *pos += 3; + break; + */ + case BINOP_ADD: + case BINOP_SUB: + case BINOP_MUL: + case BINOP_DIV: + case BINOP_REM: + case BINOP_MOD: + case BINOP_EXP: + case BINOP_CONCAT: + case BINOP_LOGICAL_AND: + case BINOP_LOGICAL_OR: + case BINOP_BITWISE_AND: + case BINOP_BITWISE_IOR: + case BINOP_BITWISE_XOR: + + case BINOP_EQUAL: + case BINOP_NOTEQUAL: + case BINOP_LESS: + case BINOP_GTR: + case BINOP_LEQ: + case BINOP_GEQ: + + case BINOP_REPEAT: + case BINOP_SUBSCRIPT: + case BINOP_COMMA: + nargs = 2; + *pos += 1; + break; + + case UNOP_NEG: + case UNOP_PLUS: + case UNOP_LOGICAL_NOT: + case UNOP_ABS: + case UNOP_IND: + nargs = 1; + *pos += 1; + break; + + case OP_LONG: + case OP_DOUBLE: + case OP_VAR_VALUE: + *pos += 4; + break; + + case OP_TYPE: + case OP_BOOL: + case OP_LAST: + case OP_REGISTER: + case OP_INTERNALVAR: + *pos += 3; + break; + + case UNOP_MEMVAL: + *pos += 3; + nargs = 1; + break; + + case STRUCTOP_STRUCT: + case STRUCTOP_PTR: + nargs = 1; + *pos += 4 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1); + break; + + case OP_ARRAY: + *pos += 4; + nargs = longest_to_int (exp->elts[pc + 2].longconst) + 1; + nargs -= longest_to_int (exp->elts[pc + 1].longconst); + /* A null array contains one dummy element to give the type. */ + /* if (nargs == 0) + nargs = 1; + break; */ + + case TERNOP_SLICE: + /* FIXME: TERNOP_MBR should be defined in expression.h */ + /* case TERNOP_MBR: + *pos += 1; + nargs = 3; + break; + */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + /* case BINOP_MBR: + *pos += 3; + nargs = 2; + break; */ + } + + argvec = + (struct value * *) alloca (sizeof (struct value *) * (nargs + 1)); + for (i = 0; i < nargs; i += 1) + argvec[i] = ada_resolve_subexp (expp, pos, 1, NULL); + argvec[i] = NULL; + exp = *expp; + break; + } + + /* Pass two: perform any resolution on principal operator. */ + switch (op) + { + default: + break; + + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* case OP_UNRESOLVED_VALUE: + { + struct symbol** candidate_syms; + struct block** candidate_blocks; + int n_candidates; + + n_candidates = ada_lookup_symbol_list (exp->elts[pc + 2].name, + exp->elts[pc + 1].block, + VAR_DOMAIN, + &candidate_syms, + &candidate_blocks); + + if (n_candidates > 1) + { */ + /* Types tend to get re-introduced locally, so if there + are any local symbols that are not types, first filter + out all types. *//* + int j; + for (j = 0; j < n_candidates; j += 1) + switch (SYMBOL_CLASS (candidate_syms[j])) + { + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_LOCAL_ARG: + case LOC_BASEREG: + case LOC_BASEREG_ARG: + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + goto FoundNonType; + default: + break; + } + FoundNonType: + if (j < n_candidates) + { + j = 0; + while (j < n_candidates) + { + if (SYMBOL_CLASS (candidate_syms[j]) == LOC_TYPEDEF) + { + candidate_syms[j] = candidate_syms[n_candidates-1]; + candidate_blocks[j] = candidate_blocks[n_candidates-1]; + n_candidates -= 1; + } + else + j += 1; + } + } + } + + if (n_candidates == 0) + error ("No definition found for %s", + ada_demangle (exp->elts[pc + 2].name)); + else if (n_candidates == 1) + i = 0; + else if (deprocedure_p + && ! is_nonfunction (candidate_syms, n_candidates)) + { + i = ada_resolve_function (candidate_syms, candidate_blocks, + n_candidates, NULL, 0, + exp->elts[pc + 2].name, context_type); + if (i < 0) + error ("Could not find a match for %s", + ada_demangle (exp->elts[pc + 2].name)); + } + else + { + printf_filtered ("Multiple matches for %s\n", + ada_demangle (exp->elts[pc+2].name)); + user_select_syms (candidate_syms, candidate_blocks, + n_candidates, 1); + i = 0; + } + + exp->elts[pc].opcode = exp->elts[pc + 3].opcode = OP_VAR_VALUE; + exp->elts[pc + 1].block = candidate_blocks[i]; + exp->elts[pc + 2].symbol = candidate_syms[i]; + if (innermost_block == NULL || + contained_in (candidate_blocks[i], innermost_block)) + innermost_block = candidate_blocks[i]; + } */ + /* FALL THROUGH */ + + case OP_VAR_VALUE: + if (deprocedure_p && + TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 2].symbol)) == + TYPE_CODE_FUNC) + { + replace_operator_with_call (expp, pc, 0, 0, + exp->elts[pc + 2].symbol, + exp->elts[pc + 1].block); + exp = *expp; + } + break; + + case OP_FUNCALL: + { + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* if (exp->elts[pc+3].opcode == OP_UNRESOLVED_VALUE) + { + struct symbol** candidate_syms; + struct block** candidate_blocks; + int n_candidates; + + n_candidates = ada_lookup_symbol_list (exp->elts[pc + 5].name, + exp->elts[pc + 4].block, + VAR_DOMAIN, + &candidate_syms, + &candidate_blocks); + if (n_candidates == 1) + i = 0; + else + { + i = ada_resolve_function (candidate_syms, candidate_blocks, + n_candidates, argvec, nargs-1, + exp->elts[pc + 5].name, context_type); + if (i < 0) + error ("Could not find a match for %s", + ada_demangle (exp->elts[pc + 5].name)); + } + + exp->elts[pc + 3].opcode = exp->elts[pc + 6].opcode = OP_VAR_VALUE; + exp->elts[pc + 4].block = candidate_blocks[i]; + exp->elts[pc + 5].symbol = candidate_syms[i]; + if (innermost_block == NULL || + contained_in (candidate_blocks[i], innermost_block)) + innermost_block = candidate_blocks[i]; + } */ + + } + break; + case BINOP_ADD: + case BINOP_SUB: + case BINOP_MUL: + case BINOP_DIV: + case BINOP_REM: + case BINOP_MOD: + case BINOP_CONCAT: + case BINOP_BITWISE_AND: + case BINOP_BITWISE_IOR: + case BINOP_BITWISE_XOR: + case BINOP_EQUAL: + case BINOP_NOTEQUAL: + case BINOP_LESS: + case BINOP_GTR: + case BINOP_LEQ: + case BINOP_GEQ: + case BINOP_EXP: + case UNOP_NEG: + case UNOP_PLUS: + case UNOP_LOGICAL_NOT: + case UNOP_ABS: + if (possible_user_operator_p (op, argvec)) + { + struct symbol **candidate_syms; + struct block **candidate_blocks; + int n_candidates; + + n_candidates = + ada_lookup_symbol_list (ada_mangle (ada_op_name (op)), + (struct block *) NULL, VAR_DOMAIN, + &candidate_syms, &candidate_blocks); + i = + ada_resolve_function (candidate_syms, candidate_blocks, + n_candidates, argvec, nargs, + ada_op_name (op), NULL); + if (i < 0) + break; + + replace_operator_with_call (expp, pc, nargs, 1, + candidate_syms[i], candidate_blocks[i]); + exp = *expp; + } + break; + } + + *pos = pc; + return evaluate_subexp_type (exp, pos); +} + +/* Return non-zero if formal type FTYPE matches actual type ATYPE. If + MAY_DEREF is non-zero, the formal may be a pointer and the actual + a non-pointer. */ +/* The term "match" here is rather loose. The match is heuristic and + liberal. FIXME: TOO liberal, in fact. */ + +static int +ada_type_match (struct type *ftype, struct type *atype, int may_deref) +{ + CHECK_TYPEDEF (ftype); + CHECK_TYPEDEF (atype); + + if (TYPE_CODE (ftype) == TYPE_CODE_REF) + ftype = TYPE_TARGET_TYPE (ftype); + if (TYPE_CODE (atype) == TYPE_CODE_REF) + atype = TYPE_TARGET_TYPE (atype); + + if (TYPE_CODE (ftype) == TYPE_CODE_VOID + || TYPE_CODE (atype) == TYPE_CODE_VOID) + return 1; + + switch (TYPE_CODE (ftype)) + { + default: + return 1; + case TYPE_CODE_PTR: + if (TYPE_CODE (atype) == TYPE_CODE_PTR) + return ada_type_match (TYPE_TARGET_TYPE (ftype), + TYPE_TARGET_TYPE (atype), 0); + else + return (may_deref && + ada_type_match (TYPE_TARGET_TYPE (ftype), atype, 0)); + case TYPE_CODE_INT: + case TYPE_CODE_ENUM: + case TYPE_CODE_RANGE: + switch (TYPE_CODE (atype)) + { + case TYPE_CODE_INT: + case TYPE_CODE_ENUM: + case TYPE_CODE_RANGE: + return 1; + default: + return 0; + } + + case TYPE_CODE_ARRAY: + return (TYPE_CODE (atype) == TYPE_CODE_ARRAY + || ada_is_array_descriptor (atype)); + + case TYPE_CODE_STRUCT: + if (ada_is_array_descriptor (ftype)) + return (TYPE_CODE (atype) == TYPE_CODE_ARRAY + || ada_is_array_descriptor (atype)); + else + return (TYPE_CODE (atype) == TYPE_CODE_STRUCT + && !ada_is_array_descriptor (atype)); + + case TYPE_CODE_UNION: + case TYPE_CODE_FLT: + return (TYPE_CODE (atype) == TYPE_CODE (ftype)); + } +} + +/* Return non-zero if the formals of FUNC "sufficiently match" the + vector of actual argument types ACTUALS of size N_ACTUALS. FUNC + may also be an enumeral, in which case it is treated as a 0- + argument function. */ + +static int +ada_args_match (struct symbol *func, struct value **actuals, int n_actuals) +{ + int i; + struct type *func_type = SYMBOL_TYPE (func); + + if (SYMBOL_CLASS (func) == LOC_CONST && + TYPE_CODE (func_type) == TYPE_CODE_ENUM) + return (n_actuals == 0); + else if (func_type == NULL || TYPE_CODE (func_type) != TYPE_CODE_FUNC) + return 0; + + if (TYPE_NFIELDS (func_type) != n_actuals) + return 0; + + for (i = 0; i < n_actuals; i += 1) + { + struct type *ftype = check_typedef (TYPE_FIELD_TYPE (func_type, i)); + struct type *atype = check_typedef (VALUE_TYPE (actuals[i])); + + if (!ada_type_match (TYPE_FIELD_TYPE (func_type, i), + VALUE_TYPE (actuals[i]), 1)) + return 0; + } + return 1; +} + +/* False iff function type FUNC_TYPE definitely does not produce a value + compatible with type CONTEXT_TYPE. Conservatively returns 1 if + FUNC_TYPE is not a valid function type with a non-null return type + or an enumerated type. A null CONTEXT_TYPE indicates any non-void type. */ + +static int +return_match (struct type *func_type, struct type *context_type) +{ + struct type *return_type; + + if (func_type == NULL) + return 1; + + /* FIXME: base_type should be declared in gdbtypes.h, implemented in valarith.c */ + /* if (TYPE_CODE (func_type) == TYPE_CODE_FUNC) + return_type = base_type (TYPE_TARGET_TYPE (func_type)); + else + return_type = base_type (func_type); */ + if (return_type == NULL) + return 1; + + /* FIXME: base_type should be declared in gdbtypes.h, implemented in valarith.c */ + /* context_type = base_type (context_type); */ + + if (TYPE_CODE (return_type) == TYPE_CODE_ENUM) + return context_type == NULL || return_type == context_type; + else if (context_type == NULL) + return TYPE_CODE (return_type) != TYPE_CODE_VOID; + else + return TYPE_CODE (return_type) == TYPE_CODE (context_type); +} + + +/* Return the index in SYMS[0..NSYMS-1] of symbol for the + function (if any) that matches the types of the NARGS arguments in + ARGS. If CONTEXT_TYPE is non-null, and there is at least one match + that returns type CONTEXT_TYPE, then eliminate other matches. If + CONTEXT_TYPE is null, prefer a non-void-returning function. + Asks the user if there is more than one match remaining. Returns -1 + if there is no such symbol or none is selected. NAME is used + solely for messages. May re-arrange and modify SYMS in + the process; the index returned is for the modified vector. BLOCKS + is modified in parallel to SYMS. */ + +int +ada_resolve_function (struct symbol *syms[], struct block *blocks[], + int nsyms, struct value **args, int nargs, + const char *name, struct type *context_type) +{ + int k; + int m; /* Number of hits */ + struct type *fallback; + struct type *return_type; + + return_type = context_type; + if (context_type == NULL) + fallback = builtin_type_void; + else + fallback = NULL; + + m = 0; + while (1) + { + for (k = 0; k < nsyms; k += 1) + { + struct type *type = check_typedef (SYMBOL_TYPE (syms[k])); + + if (ada_args_match (syms[k], args, nargs) + && return_match (SYMBOL_TYPE (syms[k]), return_type)) + { + syms[m] = syms[k]; + if (blocks != NULL) + blocks[m] = blocks[k]; + m += 1; + } + } + if (m > 0 || return_type == fallback) + break; + else + return_type = fallback; + } + + if (m == 0) + return -1; + else if (m > 1) + { + printf_filtered ("Multiple matches for %s\n", name); + user_select_syms (syms, blocks, m, 1); + return 0; + } + return 0; +} + +/* Returns true (non-zero) iff demangled name N0 should appear before N1 */ +/* in a listing of choices during disambiguation (see sort_choices, below). */ +/* The idea is that overloadings of a subprogram name from the */ +/* same package should sort in their source order. We settle for ordering */ +/* such symbols by their trailing number (__N or $N). */ +static int +mangled_ordered_before (char *N0, char *N1) +{ + if (N1 == NULL) + return 0; + else if (N0 == NULL) + return 1; + else + { + int k0, k1; + for (k0 = strlen (N0) - 1; k0 > 0 && isdigit (N0[k0]); k0 -= 1) + ; + for (k1 = strlen (N1) - 1; k1 > 0 && isdigit (N1[k1]); k1 -= 1) + ; + if ((N0[k0] == '_' || N0[k0] == '$') && N0[k0 + 1] != '\000' + && (N1[k1] == '_' || N1[k1] == '$') && N1[k1 + 1] != '\000') + { + int n0, n1; + n0 = k0; + while (N0[n0] == '_' && n0 > 0 && N0[n0 - 1] == '_') + n0 -= 1; + n1 = k1; + while (N1[n1] == '_' && n1 > 0 && N1[n1 - 1] == '_') + n1 -= 1; + if (n0 == n1 && DEPRECATED_STREQN (N0, N1, n0)) + return (atoi (N0 + k0 + 1) < atoi (N1 + k1 + 1)); + } + return (strcmp (N0, N1) < 0); + } +} + +/* Sort SYMS[0..NSYMS-1] to put the choices in a canonical order by their */ +/* mangled names, rearranging BLOCKS[0..NSYMS-1] according to the same */ +/* permutation. */ +static void +sort_choices (struct symbol *syms[], struct block *blocks[], int nsyms) +{ + int i, j; + for (i = 1; i < nsyms; i += 1) + { + struct symbol *sym = syms[i]; + struct block *block = blocks[i]; + int j; + + for (j = i - 1; j >= 0; j -= 1) + { + if (mangled_ordered_before (DEPRECATED_SYMBOL_NAME (syms[j]), + DEPRECATED_SYMBOL_NAME (sym))) + break; + syms[j + 1] = syms[j]; + blocks[j + 1] = blocks[j]; + } + syms[j + 1] = sym; + blocks[j + 1] = block; + } +} + +/* Given a list of NSYMS symbols in SYMS and corresponding blocks in */ +/* BLOCKS, select up to MAX_RESULTS>0 by asking the user (if */ +/* necessary), returning the number selected, and setting the first */ +/* elements of SYMS and BLOCKS to the selected symbols and */ +/* corresponding blocks. Error if no symbols selected. BLOCKS may */ +/* be NULL, in which case it is ignored. */ + +/* NOTE: Adapted from decode_line_2 in symtab.c, with which it ought + to be re-integrated one of these days. */ + +int +user_select_syms (struct symbol *syms[], struct block *blocks[], int nsyms, + int max_results) +{ + int i; + int *chosen = (int *) alloca (sizeof (int) * nsyms); + int n_chosen; + int first_choice = (max_results == 1) ? 1 : 2; + + if (max_results < 1) + error ("Request to select 0 symbols!"); + if (nsyms <= 1) + return nsyms; + + printf_unfiltered ("[0] cancel\n"); + if (max_results > 1) + printf_unfiltered ("[1] all\n"); + + sort_choices (syms, blocks, nsyms); + + for (i = 0; i < nsyms; i += 1) + { + if (syms[i] == NULL) + continue; + + if (SYMBOL_CLASS (syms[i]) == LOC_BLOCK) + { + struct symtab_and_line sal = find_function_start_sal (syms[i], 1); + printf_unfiltered ("[%d] %s at %s:%d\n", + i + first_choice, + SYMBOL_PRINT_NAME (syms[i]), + sal.symtab == NULL + ? "" + : sal.symtab->filename, sal.line); + continue; + } + else + { + int is_enumeral = + (SYMBOL_CLASS (syms[i]) == LOC_CONST + && SYMBOL_TYPE (syms[i]) != NULL + && TYPE_CODE (SYMBOL_TYPE (syms[i])) == TYPE_CODE_ENUM); + struct symtab *symtab = symtab_for_sym (syms[i]); + + if (SYMBOL_LINE (syms[i]) != 0 && symtab != NULL) + printf_unfiltered ("[%d] %s at %s:%d\n", + i + first_choice, + SYMBOL_PRINT_NAME (syms[i]), + symtab->filename, SYMBOL_LINE (syms[i])); + else if (is_enumeral && TYPE_NAME (SYMBOL_TYPE (syms[i])) != NULL) + { + printf_unfiltered ("[%d] ", i + first_choice); + ada_print_type (SYMBOL_TYPE (syms[i]), NULL, gdb_stdout, -1, 0); + printf_unfiltered ("'(%s) (enumeral)\n", + SYMBOL_PRINT_NAME (syms[i])); + } + else if (symtab != NULL) + printf_unfiltered (is_enumeral + ? "[%d] %s in %s (enumeral)\n" + : "[%d] %s at %s:?\n", + i + first_choice, + SYMBOL_PRINT_NAME (syms[i]), + symtab->filename); + else + printf_unfiltered (is_enumeral + ? "[%d] %s (enumeral)\n" + : "[%d] %s at ?\n", + i + first_choice, + SYMBOL_PRINT_NAME (syms[i])); + } + } + + n_chosen = get_selections (chosen, nsyms, max_results, max_results > 1, + "overload-choice"); + + for (i = 0; i < n_chosen; i += 1) + { + syms[i] = syms[chosen[i]]; + if (blocks != NULL) + blocks[i] = blocks[chosen[i]]; + } + + return n_chosen; +} + +/* Read and validate a set of numeric choices from the user in the + range 0 .. N_CHOICES-1. Place the results in increasing + order in CHOICES[0 .. N-1], and return N. + + The user types choices as a sequence of numbers on one line + separated by blanks, encoding them as follows: + + + A choice of 0 means to cancel the selection, throwing an error. + + If IS_ALL_CHOICE, a choice of 1 selects the entire set 0 .. N_CHOICES-1. + + The user chooses k by typing k+IS_ALL_CHOICE+1. + + The user is not allowed to choose more than MAX_RESULTS values. + + ANNOTATION_SUFFIX, if present, is used to annotate the input + prompts (for use with the -f switch). */ + +int +get_selections (int *choices, int n_choices, int max_results, + int is_all_choice, char *annotation_suffix) +{ + int i; + char *args; + const char *prompt; + int n_chosen; + int first_choice = is_all_choice ? 2 : 1; + + prompt = getenv ("PS2"); + if (prompt == NULL) + prompt = ">"; + + printf_unfiltered ("%s ", prompt); + gdb_flush (gdb_stdout); + + args = command_line_input ((char *) NULL, 0, annotation_suffix); + + if (args == NULL) + error_no_arg ("one or more choice numbers"); + + n_chosen = 0; + + /* Set choices[0 .. n_chosen-1] to the users' choices in ascending + order, as given in args. Choices are validated. */ + while (1) + { + char *args2; + int choice, j; + + while (isspace (*args)) + args += 1; + if (*args == '\0' && n_chosen == 0) + error_no_arg ("one or more choice numbers"); + else if (*args == '\0') + break; + + choice = strtol (args, &args2, 10); + if (args == args2 || choice < 0 + || choice > n_choices + first_choice - 1) + error ("Argument must be choice number"); + args = args2; + + if (choice == 0) + error ("cancelled"); + + if (choice < first_choice) + { + n_chosen = n_choices; + for (j = 0; j < n_choices; j += 1) + choices[j] = j; + break; + } + choice -= first_choice; + + for (j = n_chosen - 1; j >= 0 && choice < choices[j]; j -= 1) + { + } + + if (j < 0 || choice != choices[j]) + { + int k; + for (k = n_chosen - 1; k > j; k -= 1) + choices[k + 1] = choices[k]; + choices[j + 1] = choice; + n_chosen += 1; + } + } + + if (n_chosen > max_results) + error ("Select no more than %d of the above", max_results); + + return n_chosen; +} + +/* Replace the operator of length OPLEN at position PC in *EXPP with a call */ +/* on the function identified by SYM and BLOCK, and taking NARGS */ +/* arguments. Update *EXPP as needed to hold more space. */ + +static void +replace_operator_with_call (struct expression **expp, int pc, int nargs, + int oplen, struct symbol *sym, + struct block *block) +{ + /* A new expression, with 6 more elements (3 for funcall, 4 for function + symbol, -oplen for operator being replaced). */ + struct expression *newexp = (struct expression *) + xmalloc (sizeof (struct expression) + + EXP_ELEM_TO_BYTES ((*expp)->nelts + 7 - oplen)); + struct expression *exp = *expp; + + newexp->nelts = exp->nelts + 7 - oplen; + newexp->language_defn = exp->language_defn; + memcpy (newexp->elts, exp->elts, EXP_ELEM_TO_BYTES (pc)); + memcpy (newexp->elts + pc + 7, exp->elts + pc + oplen, + EXP_ELEM_TO_BYTES (exp->nelts - pc - oplen)); + + newexp->elts[pc].opcode = newexp->elts[pc + 2].opcode = OP_FUNCALL; + newexp->elts[pc + 1].longconst = (LONGEST) nargs; + + newexp->elts[pc + 3].opcode = newexp->elts[pc + 6].opcode = OP_VAR_VALUE; + newexp->elts[pc + 4].block = block; + newexp->elts[pc + 5].symbol = sym; + + *expp = newexp; + xfree (exp); +} + +/* Type-class predicates */ + +/* True iff TYPE is numeric (i.e., an INT, RANGE (of numeric type), or */ +/* FLOAT.) */ + +static int +numeric_type_p (struct type *type) +{ + if (type == NULL) + return 0; + else + { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_FLT: + return 1; + case TYPE_CODE_RANGE: + return (type == TYPE_TARGET_TYPE (type) + || numeric_type_p (TYPE_TARGET_TYPE (type))); + default: + return 0; + } + } +} + +/* True iff TYPE is integral (an INT or RANGE of INTs). */ + +static int +integer_type_p (struct type *type) +{ + if (type == NULL) + return 0; + else + { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + return 1; + case TYPE_CODE_RANGE: + return (type == TYPE_TARGET_TYPE (type) + || integer_type_p (TYPE_TARGET_TYPE (type))); + default: + return 0; + } + } +} + +/* True iff TYPE is scalar (INT, RANGE, FLOAT, ENUM). */ + +static int +scalar_type_p (struct type *type) +{ + if (type == NULL) + return 0; + else + { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_RANGE: + case TYPE_CODE_ENUM: + case TYPE_CODE_FLT: + return 1; + default: + return 0; + } + } +} + +/* True iff TYPE is discrete (INT, RANGE, ENUM). */ + +static int +discrete_type_p (struct type *type) +{ + if (type == NULL) + return 0; + else + { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_RANGE: + case TYPE_CODE_ENUM: + return 1; + default: + return 0; + } + } +} + +/* Returns non-zero if OP with operatands in the vector ARGS could be + a user-defined function. Errs on the side of pre-defined operators + (i.e., result 0). */ + +static int +possible_user_operator_p (enum exp_opcode op, struct value *args[]) +{ + struct type *type0 = check_typedef (VALUE_TYPE (args[0])); + struct type *type1 = + (args[1] == NULL) ? NULL : check_typedef (VALUE_TYPE (args[1])); + + switch (op) + { + default: + return 0; + + case BINOP_ADD: + case BINOP_SUB: + case BINOP_MUL: + case BINOP_DIV: + return (!(numeric_type_p (type0) && numeric_type_p (type1))); + + case BINOP_REM: + case BINOP_MOD: + case BINOP_BITWISE_AND: + case BINOP_BITWISE_IOR: + case BINOP_BITWISE_XOR: + return (!(integer_type_p (type0) && integer_type_p (type1))); + + case BINOP_EQUAL: + case BINOP_NOTEQUAL: + case BINOP_LESS: + case BINOP_GTR: + case BINOP_LEQ: + case BINOP_GEQ: + return (!(scalar_type_p (type0) && scalar_type_p (type1))); + + case BINOP_CONCAT: + return ((TYPE_CODE (type0) != TYPE_CODE_ARRAY && + (TYPE_CODE (type0) != TYPE_CODE_PTR || + TYPE_CODE (TYPE_TARGET_TYPE (type0)) + != TYPE_CODE_ARRAY)) + || (TYPE_CODE (type1) != TYPE_CODE_ARRAY && + (TYPE_CODE (type1) != TYPE_CODE_PTR || + TYPE_CODE (TYPE_TARGET_TYPE (type1)) != TYPE_CODE_ARRAY))); + + case BINOP_EXP: + return (!(numeric_type_p (type0) && integer_type_p (type1))); + + case UNOP_NEG: + case UNOP_PLUS: + case UNOP_LOGICAL_NOT: + case UNOP_ABS: + return (!numeric_type_p (type0)); + + } +} + + /* Renaming */ + +/** NOTE: In the following, we assume that a renaming type's name may + * have an ___XD suffix. It would be nice if this went away at some + * point. */ + +/* If TYPE encodes a renaming, returns the renaming suffix, which + * is XR for an object renaming, XRP for a procedure renaming, XRE for + * an exception renaming, and XRS for a subprogram renaming. Returns + * NULL if NAME encodes none of these. */ +const char * +ada_renaming_type (struct type *type) +{ + if (type != NULL && TYPE_CODE (type) == TYPE_CODE_ENUM) + { + const char *name = type_name_no_tag (type); + const char *suffix = (name == NULL) ? NULL : strstr (name, "___XR"); + if (suffix == NULL + || (suffix[5] != '\000' && strchr ("PES_", suffix[5]) == NULL)) + return NULL; + else + return suffix + 3; + } + else + return NULL; +} + +/* Return non-zero iff SYM encodes an object renaming. */ +int +ada_is_object_renaming (struct symbol *sym) +{ + const char *renaming_type = ada_renaming_type (SYMBOL_TYPE (sym)); + return renaming_type != NULL + && (renaming_type[2] == '\0' || renaming_type[2] == '_'); +} + +/* Assuming that SYM encodes a non-object renaming, returns the original + * name of the renamed entity. The name is good until the end of + * parsing. */ +const char * +ada_simple_renamed_entity (struct symbol *sym) +{ + struct type *type; + const char *raw_name; + int len; + char *result; + + type = SYMBOL_TYPE (sym); + if (type == NULL || TYPE_NFIELDS (type) < 1) + error ("Improperly encoded renaming."); + + raw_name = TYPE_FIELD_NAME (type, 0); + len = (raw_name == NULL ? 0 : strlen (raw_name)) - 5; + if (len <= 0) + error ("Improperly encoded renaming."); + + result = xmalloc (len + 1); + /* FIXME: add_name_string_cleanup should be defined in parse.c */ + /* add_name_string_cleanup (result); */ + strncpy (result, raw_name, len); + result[len] = '\000'; + return result; +} + + + /* Evaluation: Function Calls */ + +/* Copy VAL onto the stack, using and updating *SP as the stack + pointer. Return VAL as an lvalue. */ + +static struct value * +place_on_stack (struct value *val, CORE_ADDR *sp) +{ + CORE_ADDR old_sp = *sp; + +#ifdef DEPRECATED_STACK_ALIGN + *sp = push_bytes (*sp, VALUE_CONTENTS_RAW (val), + DEPRECATED_STACK_ALIGN (TYPE_LENGTH + (check_typedef (VALUE_TYPE (val))))); +#else + *sp = push_bytes (*sp, VALUE_CONTENTS_RAW (val), + TYPE_LENGTH (check_typedef (VALUE_TYPE (val)))); +#endif + + VALUE_LVAL (val) = lval_memory; + if (INNER_THAN (1, 2)) + VALUE_ADDRESS (val) = *sp; + else + VALUE_ADDRESS (val) = old_sp; + + return val; +} + +/* Return the value ACTUAL, converted to be an appropriate value for a + formal of type FORMAL_TYPE. Use *SP as a stack pointer for + allocating any necessary descriptors (fat pointers), or copies of + values not residing in memory, updating it as needed. */ + +static struct value * +convert_actual (struct value *actual, struct type *formal_type0, + CORE_ADDR *sp) +{ + struct type *actual_type = check_typedef (VALUE_TYPE (actual)); + struct type *formal_type = check_typedef (formal_type0); + struct type *formal_target = + TYPE_CODE (formal_type) == TYPE_CODE_PTR + ? check_typedef (TYPE_TARGET_TYPE (formal_type)) : formal_type; + struct type *actual_target = + TYPE_CODE (actual_type) == TYPE_CODE_PTR + ? check_typedef (TYPE_TARGET_TYPE (actual_type)) : actual_type; + + if (ada_is_array_descriptor (formal_target) + && TYPE_CODE (actual_target) == TYPE_CODE_ARRAY) + return make_array_descriptor (formal_type, actual, sp); + else if (TYPE_CODE (formal_type) == TYPE_CODE_PTR) + { + if (TYPE_CODE (formal_target) == TYPE_CODE_ARRAY + && ada_is_array_descriptor (actual_target)) + return desc_data (actual); + else if (TYPE_CODE (actual_type) != TYPE_CODE_PTR) + { + if (VALUE_LVAL (actual) != lval_memory) + { + struct value *val; + actual_type = check_typedef (VALUE_TYPE (actual)); + val = allocate_value (actual_type); + memcpy ((char *) VALUE_CONTENTS_RAW (val), + (char *) VALUE_CONTENTS (actual), + TYPE_LENGTH (actual_type)); + actual = place_on_stack (val, sp); + } + return value_addr (actual); + } + } + else if (TYPE_CODE (actual_type) == TYPE_CODE_PTR) + return ada_value_ind (actual); + + return actual; +} + + +/* Push a descriptor of type TYPE for array value ARR on the stack at + *SP, updating *SP to reflect the new descriptor. Return either + an lvalue representing the new descriptor, or (if TYPE is a pointer- + to-descriptor type rather than a descriptor type), a struct value* + representing a pointer to this descriptor. */ + +static struct value * +make_array_descriptor (struct type *type, struct value *arr, CORE_ADDR *sp) +{ + struct type *bounds_type = desc_bounds_type (type); + struct type *desc_type = desc_base_type (type); + struct value *descriptor = allocate_value (desc_type); + struct value *bounds = allocate_value (bounds_type); + CORE_ADDR bounds_addr; + int i; + + for (i = ada_array_arity (check_typedef (VALUE_TYPE (arr))); i > 0; i -= 1) + { + modify_general_field (VALUE_CONTENTS (bounds), + value_as_long (ada_array_bound (arr, i, 0)), + desc_bound_bitpos (bounds_type, i, 0), + desc_bound_bitsize (bounds_type, i, 0)); + modify_general_field (VALUE_CONTENTS (bounds), + value_as_long (ada_array_bound (arr, i, 1)), + desc_bound_bitpos (bounds_type, i, 1), + desc_bound_bitsize (bounds_type, i, 1)); + } + + bounds = place_on_stack (bounds, sp); + + modify_general_field (VALUE_CONTENTS (descriptor), + arr, + fat_pntr_data_bitpos (desc_type), + fat_pntr_data_bitsize (desc_type)); + modify_general_field (VALUE_CONTENTS (descriptor), + VALUE_ADDRESS (bounds), + fat_pntr_bounds_bitpos (desc_type), + fat_pntr_bounds_bitsize (desc_type)); + + descriptor = place_on_stack (descriptor, sp); + + if (TYPE_CODE (type) == TYPE_CODE_PTR) + return value_addr (descriptor); + else + return descriptor; +} + + +/* Assuming a dummy frame has been established on the target, perform any + conversions needed for calling function FUNC on the NARGS actual + parameters in ARGS, other than standard C conversions. Does + nothing if FUNC does not have Ada-style prototype data, or if NARGS + does not match the number of arguments expected. Use *SP as a + stack pointer for additional data that must be pushed, updating its + value as needed. */ + +void +ada_convert_actuals (struct value *func, int nargs, struct value *args[], + CORE_ADDR *sp) +{ + int i; + + if (TYPE_NFIELDS (VALUE_TYPE (func)) == 0 + || nargs != TYPE_NFIELDS (VALUE_TYPE (func))) + return; + + for (i = 0; i < nargs; i += 1) + args[i] = + convert_actual (args[i], TYPE_FIELD_TYPE (VALUE_TYPE (func), i), sp); +} + + + /* Symbol Lookup */ + + +/* The vectors of symbols and blocks ultimately returned from */ +/* ada_lookup_symbol_list. */ + +/* Current size of defn_symbols and defn_blocks */ +static size_t defn_vector_size = 0; + +/* Current number of symbols found. */ +static int ndefns = 0; + +static struct symbol **defn_symbols = NULL; +static struct block **defn_blocks = NULL; + +/* Return the result of a standard (literal, C-like) lookup of NAME in + * given DOMAIN. */ + +static struct symbol * +standard_lookup (const char *name, domain_enum domain) +{ + struct symbol *sym; + sym = lookup_symbol (name, (struct block *) NULL, domain, 0, NULL); + return sym; +} + + +/* Non-zero iff there is at least one non-function/non-enumeral symbol */ +/* in SYMS[0..N-1]. We treat enumerals as functions, since they */ +/* contend in overloading in the same way. */ +static int +is_nonfunction (struct symbol *syms[], int n) +{ + int i; + + for (i = 0; i < n; i += 1) + if (TYPE_CODE (SYMBOL_TYPE (syms[i])) != TYPE_CODE_FUNC + && TYPE_CODE (SYMBOL_TYPE (syms[i])) != TYPE_CODE_ENUM) + return 1; + + return 0; +} + +/* If true (non-zero), then TYPE0 and TYPE1 represent equivalent + struct types. Otherwise, they may not. */ + +static int +equiv_types (struct type *type0, struct type *type1) +{ + if (type0 == type1) + return 1; + if (type0 == NULL || type1 == NULL + || TYPE_CODE (type0) != TYPE_CODE (type1)) + return 0; + if ((TYPE_CODE (type0) == TYPE_CODE_STRUCT + || TYPE_CODE (type0) == TYPE_CODE_ENUM) + && ada_type_name (type0) != NULL && ada_type_name (type1) != NULL + && DEPRECATED_STREQ (ada_type_name (type0), ada_type_name (type1))) + return 1; + + return 0; +} + +/* True iff SYM0 represents the same entity as SYM1, or one that is + no more defined than that of SYM1. */ + +static int +lesseq_defined_than (struct symbol *sym0, struct symbol *sym1) +{ + if (sym0 == sym1) + return 1; + if (SYMBOL_DOMAIN (sym0) != SYMBOL_DOMAIN (sym1) + || SYMBOL_CLASS (sym0) != SYMBOL_CLASS (sym1)) + return 0; + + switch (SYMBOL_CLASS (sym0)) + { + case LOC_UNDEF: + return 1; + case LOC_TYPEDEF: + { + struct type *type0 = SYMBOL_TYPE (sym0); + struct type *type1 = SYMBOL_TYPE (sym1); + char *name0 = DEPRECATED_SYMBOL_NAME (sym0); + char *name1 = DEPRECATED_SYMBOL_NAME (sym1); + int len0 = strlen (name0); + return + TYPE_CODE (type0) == TYPE_CODE (type1) + && (equiv_types (type0, type1) + || (len0 < strlen (name1) && DEPRECATED_STREQN (name0, name1, len0) + && DEPRECATED_STREQN (name1 + len0, "___XV", 5))); + } + case LOC_CONST: + return SYMBOL_VALUE (sym0) == SYMBOL_VALUE (sym1) + && equiv_types (SYMBOL_TYPE (sym0), SYMBOL_TYPE (sym1)); + default: + return 0; + } +} + +/* Append SYM to the end of defn_symbols, and BLOCK to the end of + defn_blocks, updating ndefns, and expanding defn_symbols and + defn_blocks as needed. Do not include SYM if it is a duplicate. */ + +static void +add_defn_to_vec (struct symbol *sym, struct block *block) +{ + int i; + size_t tmp; + + if (SYMBOL_TYPE (sym) != NULL) + CHECK_TYPEDEF (SYMBOL_TYPE (sym)); + for (i = 0; i < ndefns; i += 1) + { + if (lesseq_defined_than (sym, defn_symbols[i])) + return; + else if (lesseq_defined_than (defn_symbols[i], sym)) + { + defn_symbols[i] = sym; + defn_blocks[i] = block; + return; + } + } + + tmp = defn_vector_size; + GROW_VECT (defn_symbols, tmp, ndefns + 2); + GROW_VECT (defn_blocks, defn_vector_size, ndefns + 2); + + defn_symbols[ndefns] = sym; + defn_blocks[ndefns] = block; + ndefns += 1; +} + +/* Look, in partial_symtab PST, for symbol NAME in given domain. + Check the global symbols if GLOBAL, the static symbols if not. Do + wild-card match if WILD. */ + +static struct partial_symbol * +ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, + int global, domain_enum domain, int wild) +{ + struct partial_symbol **start; + int name_len = strlen (name); + int length = (global ? pst->n_global_syms : pst->n_static_syms); + int i; + + if (length == 0) + { + return (NULL); + } + + start = (global ? + pst->objfile->global_psymbols.list + pst->globals_offset : + pst->objfile->static_psymbols.list + pst->statics_offset); + + if (wild) + { + for (i = 0; i < length; i += 1) + { + struct partial_symbol *psym = start[i]; + + if (SYMBOL_DOMAIN (psym) == domain && + wild_match (name, name_len, DEPRECATED_SYMBOL_NAME (psym))) + return psym; + } + return NULL; + } + else + { + if (global) + { + int U; + i = 0; + U = length - 1; + while (U - i > 4) + { + int M = (U + i) >> 1; + struct partial_symbol *psym = start[M]; + if (DEPRECATED_SYMBOL_NAME (psym)[0] < name[0]) + i = M + 1; + else if (DEPRECATED_SYMBOL_NAME (psym)[0] > name[0]) + U = M - 1; + else if (strcmp (DEPRECATED_SYMBOL_NAME (psym), name) < 0) + i = M + 1; + else + U = M; + } + } + else + i = 0; + + while (i < length) + { + struct partial_symbol *psym = start[i]; + + if (SYMBOL_DOMAIN (psym) == domain) + { + int cmp = strncmp (name, DEPRECATED_SYMBOL_NAME (psym), name_len); + + if (cmp < 0) + { + if (global) + break; + } + else if (cmp == 0 + && is_name_suffix (DEPRECATED_SYMBOL_NAME (psym) + name_len)) + return psym; + } + i += 1; + } + + if (global) + { + int U; + i = 0; + U = length - 1; + while (U - i > 4) + { + int M = (U + i) >> 1; + struct partial_symbol *psym = start[M]; + if (DEPRECATED_SYMBOL_NAME (psym)[0] < '_') + i = M + 1; + else if (DEPRECATED_SYMBOL_NAME (psym)[0] > '_') + U = M - 1; + else if (strcmp (DEPRECATED_SYMBOL_NAME (psym), "_ada_") < 0) + i = M + 1; + else + U = M; + } + } + else + i = 0; + + while (i < length) + { + struct partial_symbol *psym = start[i]; + + if (SYMBOL_DOMAIN (psym) == domain) + { + int cmp; + + cmp = (int) '_' - (int) DEPRECATED_SYMBOL_NAME (psym)[0]; + if (cmp == 0) + { + cmp = strncmp ("_ada_", DEPRECATED_SYMBOL_NAME (psym), 5); + if (cmp == 0) + cmp = strncmp (name, DEPRECATED_SYMBOL_NAME (psym) + 5, name_len); + } + + if (cmp < 0) + { + if (global) + break; + } + else if (cmp == 0 + && is_name_suffix (DEPRECATED_SYMBOL_NAME (psym) + name_len + 5)) + return psym; + } + i += 1; + } + + } + return NULL; +} + + +/* Find a symbol table containing symbol SYM or NULL if none. */ +static struct symtab * +symtab_for_sym (struct symbol *sym) +{ + struct symtab *s; + struct objfile *objfile; + struct block *b; + struct symbol *tmp_sym; + struct dict_iterator iter; + int j; + + ALL_SYMTABS (objfile, s) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_CONST: + case LOC_STATIC: + case LOC_TYPEDEF: + case LOC_REGISTER: + case LOC_LABEL: + case LOC_BLOCK: + case LOC_CONST_BYTES: + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); + ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym) + return s; + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); + ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym) + return s; + break; + default: + break; + } + switch (SYMBOL_CLASS (sym)) + { + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_TYPEDEF: + case LOC_LOCAL_ARG: + case LOC_BASEREG: + case LOC_BASEREG_ARG: + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + for (j = FIRST_LOCAL_BLOCK; + j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1) + { + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j); + ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym) + return s; + } + break; + default: + break; + } + } + return NULL; +} + +/* Return a minimal symbol matching NAME according to Ada demangling + rules. Returns NULL if there is no such minimal symbol. */ + +struct minimal_symbol * +ada_lookup_minimal_symbol (const char *name) +{ + struct objfile *objfile; + struct minimal_symbol *msymbol; + int wild_match = (strstr (name, "__") == NULL); + + ALL_MSYMBOLS (objfile, msymbol) + { + if (ada_match_name (DEPRECATED_SYMBOL_NAME (msymbol), name, wild_match) + && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline) + return msymbol; + } + + return NULL; +} + +/* For all subprograms that statically enclose the subprogram of the + * selected frame, add symbols matching identifier NAME in DOMAIN + * and their blocks to vectors *defn_symbols and *defn_blocks, as for + * ada_add_block_symbols (q.v.). If WILD, treat as NAME with a + * wildcard prefix. At the moment, this function uses a heuristic to + * find the frames of enclosing subprograms: it treats the + * pointer-sized value at location 0 from the local-variable base of a + * frame as a static link, and then searches up the call stack for a + * frame with that same local-variable base. */ +static void +add_symbols_from_enclosing_procs (const char *name, domain_enum domain, + int wild_match) +{ +#ifdef i386 + static struct symbol static_link_sym; + static struct symbol *static_link; + + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); + struct frame_info *frame; + struct frame_info *target_frame; + + if (static_link == NULL) + { + /* Initialize the local variable symbol that stands for the + * static link (when it exists). */ + static_link = &static_link_sym; + DEPRECATED_SYMBOL_NAME (static_link) = ""; + SYMBOL_LANGUAGE (static_link) = language_unknown; + SYMBOL_CLASS (static_link) = LOC_LOCAL; + SYMBOL_DOMAIN (static_link) = VAR_DOMAIN; + SYMBOL_TYPE (static_link) = lookup_pointer_type (builtin_type_void); + SYMBOL_VALUE (static_link) = + -(long) TYPE_LENGTH (SYMBOL_TYPE (static_link)); + } + + frame = deprecated_selected_frame; + while (frame != NULL && ndefns == 0) + { + struct block *block; + struct value *target_link_val = read_var_value (static_link, frame); + CORE_ADDR target_link; + + if (target_link_val == NULL) + break; + QUIT; + + target_link = target_link_val; + do + { + QUIT; + frame = get_prev_frame (frame); + } + while (frame != NULL && DEPRECATED_FRAME_LOCALS_ADDRESS (frame) != target_link); + + if (frame == NULL) + break; + + block = get_frame_block (frame, 0); + while (block != NULL && block_function (block) != NULL && ndefns == 0) + { + ada_add_block_symbols (block, name, domain, NULL, wild_match); + + block = BLOCK_SUPERBLOCK (block); + } + } + + do_cleanups (old_chain); +#endif +} + +/* True if TYPE is definitely an artificial type supplied to a symbol + * for which no debugging information was given in the symbol file. */ +static int +is_nondebugging_type (struct type *type) +{ + char *name = ada_type_name (type); + return (name != NULL && DEPRECATED_STREQ (name, "")); +} + +/* Remove any non-debugging symbols in SYMS[0 .. NSYMS-1] that definitely + * duplicate other symbols in the list. (The only case I know of where + * this happens is when object files containing stabs-in-ecoff are + * linked with files containing ordinary ecoff debugging symbols (or no + * debugging symbols)). Modifies SYMS to squeeze out deleted symbols, + * and applies the same modification to BLOCKS to maintain the + * correspondence between SYMS[i] and BLOCKS[i]. Returns the number + * of symbols in the modified list. */ +static int +remove_extra_symbols (struct symbol **syms, struct block **blocks, int nsyms) +{ + int i, j; + + i = 0; + while (i < nsyms) + { + if (DEPRECATED_SYMBOL_NAME (syms[i]) != NULL + && SYMBOL_CLASS (syms[i]) == LOC_STATIC + && is_nondebugging_type (SYMBOL_TYPE (syms[i]))) + { + for (j = 0; j < nsyms; j += 1) + { + if (i != j + && DEPRECATED_SYMBOL_NAME (syms[j]) != NULL + && DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (syms[i]), DEPRECATED_SYMBOL_NAME (syms[j])) + && SYMBOL_CLASS (syms[i]) == SYMBOL_CLASS (syms[j]) + && SYMBOL_VALUE_ADDRESS (syms[i]) + == SYMBOL_VALUE_ADDRESS (syms[j])) + { + int k; + for (k = i + 1; k < nsyms; k += 1) + { + syms[k - 1] = syms[k]; + blocks[k - 1] = blocks[k]; + } + nsyms -= 1; + goto NextSymbol; + } + } + } + i += 1; + NextSymbol: + ; + } + return nsyms; +} + +/* Find symbols in DOMAIN matching NAME, in BLOCK0 and enclosing + scope and in global scopes, returning the number of matches. Sets + *SYMS to point to a vector of matching symbols, with *BLOCKS + pointing to the vector of corresponding blocks in which those + symbols reside. These two vectors are transient---good only to the + next call of ada_lookup_symbol_list. Any non-function/non-enumeral symbol + match within the nest of blocks whose innermost member is BLOCK0, + is the outermost match returned (no other matches in that or + enclosing blocks is returned). If there are any matches in or + surrounding BLOCK0, then these alone are returned. */ + +int +ada_lookup_symbol_list (const char *name, struct block *block0, + domain_enum domain, struct symbol ***syms, + struct block ***blocks) +{ + struct symbol *sym; + struct symtab *s; + struct partial_symtab *ps; + struct blockvector *bv; + struct objfile *objfile; + struct block *b; + struct block *block; + struct minimal_symbol *msymbol; + int wild_match = (strstr (name, "__") == NULL); + int cacheIfUnique; + +#ifdef TIMING + markTimeStart (0); +#endif + + ndefns = 0; + cacheIfUnique = 0; + + /* Search specified block and its superiors. */ + + block = block0; + while (block != NULL) + { + ada_add_block_symbols (block, name, domain, NULL, wild_match); + + /* If we found a non-function match, assume that's the one. */ + if (is_nonfunction (defn_symbols, ndefns)) + goto done; + + block = BLOCK_SUPERBLOCK (block); + } + + /* If we found ANY matches in the specified BLOCK, we're done. */ + + if (ndefns > 0) + goto done; + + cacheIfUnique = 1; + + /* Now add symbols from all global blocks: symbol tables, minimal symbol + tables, and psymtab's */ + + ALL_SYMTABS (objfile, s) + { + QUIT; + if (!s->primary) + continue; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + ada_add_block_symbols (block, name, domain, objfile, wild_match); + } + + if (domain == VAR_DOMAIN) + { + ALL_MSYMBOLS (objfile, msymbol) + { + if (ada_match_name (DEPRECATED_SYMBOL_NAME (msymbol), name, wild_match)) + { + switch (MSYMBOL_TYPE (msymbol)) + { + case mst_solib_trampoline: + break; + default: + s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)); + if (s != NULL) + { + int old_ndefns = ndefns; + QUIT; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + ada_add_block_symbols (block, + DEPRECATED_SYMBOL_NAME (msymbol), + domain, objfile, wild_match); + if (ndefns == old_ndefns) + { + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + ada_add_block_symbols (block, + DEPRECATED_SYMBOL_NAME (msymbol), + domain, objfile, + wild_match); + } + } + } + } + } + } + + ALL_PSYMTABS (objfile, ps) + { + QUIT; + if (!ps->readin + && ada_lookup_partial_symbol (ps, name, 1, domain, wild_match)) + { + s = PSYMTAB_TO_SYMTAB (ps); + if (!s->primary) + continue; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + ada_add_block_symbols (block, name, domain, objfile, wild_match); + } + } + + /* Now add symbols from all per-file blocks if we've gotten no hits. + (Not strictly correct, but perhaps better than an error). + Do the symtabs first, then check the psymtabs */ + + if (ndefns == 0) + { + + ALL_SYMTABS (objfile, s) + { + QUIT; + if (!s->primary) + continue; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + ada_add_block_symbols (block, name, domain, objfile, wild_match); + } + + ALL_PSYMTABS (objfile, ps) + { + QUIT; + if (!ps->readin + && ada_lookup_partial_symbol (ps, name, 0, domain, wild_match)) + { + s = PSYMTAB_TO_SYMTAB (ps); + bv = BLOCKVECTOR (s); + if (!s->primary) + continue; + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + ada_add_block_symbols (block, name, domain, + objfile, wild_match); + } + } + } + + /* Finally, we try to find NAME as a local symbol in some lexically + enclosing block. We do this last, expecting this case to be + rare. */ + if (ndefns == 0) + { + add_symbols_from_enclosing_procs (name, domain, wild_match); + if (ndefns > 0) + goto done; + } + +done: + ndefns = remove_extra_symbols (defn_symbols, defn_blocks, ndefns); + + + *syms = defn_symbols; + *blocks = defn_blocks; +#ifdef TIMING + markTimeStop (0); +#endif + return ndefns; +} + +/* Return a symbol in DOMAIN matching NAME, in BLOCK0 and enclosing + * scope and in global scopes, or NULL if none. NAME is folded to + * lower case first, unless it is surrounded in single quotes. + * Otherwise, the result is as for ada_lookup_symbol_list, but is + * disambiguated by user query if needed. */ + +struct symbol * +ada_lookup_symbol (const char *name, struct block *block0, + domain_enum domain) +{ + struct symbol **candidate_syms; + struct block **candidate_blocks; + int n_candidates; + + n_candidates = ada_lookup_symbol_list (name, + block0, domain, + &candidate_syms, &candidate_blocks); + + if (n_candidates == 0) + return NULL; + else if (n_candidates != 1) + user_select_syms (candidate_syms, candidate_blocks, n_candidates, 1); + + return candidate_syms[0]; +} + + +/* True iff STR is a possible encoded suffix of a normal Ada name + * that is to be ignored for matching purposes. Suffixes of parallel + * names (e.g., XVE) are not included here. Currently, the possible suffixes + * are given by the regular expression: + * (X[nb]*)?(__[0-9]+|\$[0-9]+|___(LJM|X([FDBUP].*|R[^T]?)))?$ + * + */ +static int +is_name_suffix (const char *str) +{ + int k; + if (str[0] == 'X') + { + str += 1; + while (str[0] != '_' && str[0] != '\0') + { + if (str[0] != 'n' && str[0] != 'b') + return 0; + str += 1; + } + } + if (str[0] == '\000') + return 1; + if (str[0] == '_') + { + if (str[1] != '_' || str[2] == '\000') + return 0; + if (str[2] == '_') + { + if (DEPRECATED_STREQ (str + 3, "LJM")) + return 1; + if (str[3] != 'X') + return 0; + if (str[4] == 'F' || str[4] == 'D' || str[4] == 'B' || + str[4] == 'U' || str[4] == 'P') + return 1; + if (str[4] == 'R' && str[5] != 'T') + return 1; + return 0; + } + for (k = 2; str[k] != '\0'; k += 1) + if (!isdigit (str[k])) + return 0; + return 1; + } + if (str[0] == '$' && str[1] != '\000') + { + for (k = 1; str[k] != '\0'; k += 1) + if (!isdigit (str[k])) + return 0; + return 1; + } + return 0; +} + +/* True if NAME represents a name of the form A1.A2....An, n>=1 and + * PATN[0..PATN_LEN-1] = Ak.Ak+1.....An for some k >= 1. Ignores + * informational suffixes of NAME (i.e., for which is_name_suffix is + * true). */ +static int +wild_match (const char *patn, int patn_len, const char *name) +{ + int name_len; + int s, e; + + name_len = strlen (name); + if (name_len >= patn_len + 5 && DEPRECATED_STREQN (name, "_ada_", 5) + && DEPRECATED_STREQN (patn, name + 5, patn_len) + && is_name_suffix (name + patn_len + 5)) + return 1; + + while (name_len >= patn_len) + { + if (DEPRECATED_STREQN (patn, name, patn_len) && is_name_suffix (name + patn_len)) + return 1; + do + { + name += 1; + name_len -= 1; + } + while (name_len > 0 + && name[0] != '.' && (name[0] != '_' || name[1] != '_')); + if (name_len <= 0) + return 0; + if (name[0] == '_') + { + if (!islower (name[2])) + return 0; + name += 2; + name_len -= 2; + } + else + { + if (!islower (name[1])) + return 0; + name += 1; + name_len -= 1; + } + } + + return 0; +} + + +/* Add symbols from BLOCK matching identifier NAME in DOMAIN to + vector *defn_symbols, updating *defn_symbols (if necessary), *SZ (the size of + the vector *defn_symbols), and *ndefns (the number of symbols + currently stored in *defn_symbols). If WILD, treat as NAME with a + wildcard prefix. OBJFILE is the section containing BLOCK. */ + +static void +ada_add_block_symbols (struct block *block, const char *name, + domain_enum domain, struct objfile *objfile, + int wild) +{ + struct dict_iterator iter; + int name_len = strlen (name); + /* A matching argument symbol, if any. */ + struct symbol *arg_sym; + /* Set true when we find a matching non-argument symbol */ + int found_sym; + struct symbol *sym; + + arg_sym = NULL; + found_sym = 0; + if (wild) + { + struct symbol *sym; + ALL_BLOCK_SYMBOLS (block, iter, sym) + { + if (SYMBOL_DOMAIN (sym) == domain && + wild_match (name, name_len, DEPRECATED_SYMBOL_NAME (sym))) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: + case LOC_LOCAL_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_BASEREG_ARG: + case LOC_COMPUTED_ARG: + arg_sym = sym; + break; + case LOC_UNRESOLVED: + continue; + default: + found_sym = 1; + fill_in_ada_prototype (sym); + add_defn_to_vec (fixup_symbol_section (sym, objfile), block); + break; + } + } + } + } + else + { + ALL_BLOCK_SYMBOLS (block, iter, sym) + { + if (SYMBOL_DOMAIN (sym) == domain) + { + int cmp = strncmp (name, DEPRECATED_SYMBOL_NAME (sym), name_len); + + if (cmp == 0 + && is_name_suffix (DEPRECATED_SYMBOL_NAME (sym) + name_len)) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: + case LOC_LOCAL_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_BASEREG_ARG: + case LOC_COMPUTED_ARG: + arg_sym = sym; + break; + case LOC_UNRESOLVED: + break; + default: + found_sym = 1; + fill_in_ada_prototype (sym); + add_defn_to_vec (fixup_symbol_section (sym, objfile), + block); + break; + } + } + } + } + } + + if (!found_sym && arg_sym != NULL) + { + fill_in_ada_prototype (arg_sym); + add_defn_to_vec (fixup_symbol_section (arg_sym, objfile), block); + } + + if (!wild) + { + arg_sym = NULL; + found_sym = 0; + + ALL_BLOCK_SYMBOLS (block, iter, sym) + { + if (SYMBOL_DOMAIN (sym) == domain) + { + int cmp; + + cmp = (int) '_' - (int) DEPRECATED_SYMBOL_NAME (sym)[0]; + if (cmp == 0) + { + cmp = strncmp ("_ada_", DEPRECATED_SYMBOL_NAME (sym), 5); + if (cmp == 0) + cmp = strncmp (name, DEPRECATED_SYMBOL_NAME (sym) + 5, name_len); + } + + if (cmp == 0 + && is_name_suffix (DEPRECATED_SYMBOL_NAME (sym) + name_len + 5)) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: + case LOC_LOCAL_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_BASEREG_ARG: + case LOC_COMPUTED_ARG: + arg_sym = sym; + break; + case LOC_UNRESOLVED: + break; + default: + found_sym = 1; + fill_in_ada_prototype (sym); + add_defn_to_vec (fixup_symbol_section (sym, objfile), + block); + break; + } + } + } + } + + /* NOTE: This really shouldn't be needed for _ada_ symbols. + They aren't parameters, right? */ + if (!found_sym && arg_sym != NULL) + { + fill_in_ada_prototype (arg_sym); + add_defn_to_vec (fixup_symbol_section (arg_sym, objfile), block); + } + } +} + + + /* Function Types */ + +/* Assuming that SYM is the symbol for a function, fill in its type + with prototype information, if it is not already there. */ + +static void +fill_in_ada_prototype (struct symbol *func) +{ + struct block *b; + int nargs, nsyms; + struct dict_iterator iter; + struct type *ftype; + struct type *rtype; + size_t max_fields; + struct symbol *sym; + + if (func == NULL + || TYPE_CODE (SYMBOL_TYPE (func)) != TYPE_CODE_FUNC + || TYPE_FIELDS (SYMBOL_TYPE (func)) != NULL) + return; + + /* We make each function type unique, so that each may have its own */ + /* parameter types. This particular way of doing so wastes space: */ + /* it would be nicer to build the argument types while the original */ + /* function type is being built (FIXME). */ + rtype = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (func))); + ftype = alloc_type (TYPE_OBJFILE (SYMBOL_TYPE (func))); + make_function_type (rtype, &ftype); + SYMBOL_TYPE (func) = ftype; + + b = SYMBOL_BLOCK_VALUE (func); + + nargs = 0; + max_fields = 8; + TYPE_FIELDS (ftype) = + (struct field *) xmalloc (sizeof (struct field) * max_fields); + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + GROW_VECT (TYPE_FIELDS (ftype), max_fields, nargs + 1); + + switch (SYMBOL_CLASS (sym)) + { + case LOC_REF_ARG: + case LOC_REGPARM_ADDR: + TYPE_FIELD_BITPOS (ftype, nargs) = nargs; + TYPE_FIELD_BITSIZE (ftype, nargs) = 0; + TYPE_FIELD_STATIC_KIND (ftype, nargs) = 0; + TYPE_FIELD_TYPE (ftype, nargs) = + lookup_pointer_type (check_typedef (SYMBOL_TYPE (sym))); + TYPE_FIELD_NAME (ftype, nargs) = DEPRECATED_SYMBOL_NAME (sym); + nargs += 1; + + break; + + case LOC_ARG: + case LOC_REGPARM: + case LOC_LOCAL_ARG: + case LOC_BASEREG_ARG: + case LOC_COMPUTED_ARG: + TYPE_FIELD_BITPOS (ftype, nargs) = nargs; + TYPE_FIELD_BITSIZE (ftype, nargs) = 0; + TYPE_FIELD_STATIC_KIND (ftype, nargs) = 0; + TYPE_FIELD_TYPE (ftype, nargs) = check_typedef (SYMBOL_TYPE (sym)); + TYPE_FIELD_NAME (ftype, nargs) = DEPRECATED_SYMBOL_NAME (sym); + nargs += 1; + + break; + + default: + break; + } + } + + /* Re-allocate fields vector; if there are no fields, make the */ + /* fields pointer non-null anyway, to mark that this function type */ + /* has been filled in. */ + + TYPE_NFIELDS (ftype) = nargs; + if (nargs == 0) + { + static struct field dummy_field = { 0, 0, 0, 0 }; + xfree (TYPE_FIELDS (ftype)); + TYPE_FIELDS (ftype) = &dummy_field; + } + else + { + struct field *fields = + (struct field *) TYPE_ALLOC (ftype, nargs * sizeof (struct field)); + memcpy ((char *) fields, + (char *) TYPE_FIELDS (ftype), nargs * sizeof (struct field)); + xfree (TYPE_FIELDS (ftype)); + TYPE_FIELDS (ftype) = fields; + } +} + + + /* Breakpoint-related */ + +char no_symtab_msg[] = + "No symbol table is loaded. Use the \"file\" command."; + +/* Assuming that LINE is pointing at the beginning of an argument to + 'break', return a pointer to the delimiter for the initial segment + of that name. This is the first ':', ' ', or end of LINE. +*/ +char * +ada_start_decode_line_1 (char *line) +{ + /* [NOTE: strpbrk would be more elegant, but I am reluctant to be + the first to use such a library function in GDB code.] */ + char *p; + for (p = line; *p != '\000' && *p != ' ' && *p != ':'; p += 1) + ; + return p; +} + +/* *SPEC points to a function and line number spec (as in a break + command), following any initial file name specification. + + Return all symbol table/line specfications (sals) consistent with the + information in *SPEC and FILE_TABLE in the + following sense: + + FILE_TABLE is null, or the sal refers to a line in the file + named by FILE_TABLE. + + If *SPEC points to an argument with a trailing ':LINENUM', + then the sal refers to that line (or one following it as closely as + possible). + + If *SPEC does not start with '*', the sal is in a function with + that name. + + Returns with 0 elements if no matching non-minimal symbols found. + + If *SPEC begins with a function name of the form , then NAME + is taken as a literal name; otherwise the function name is subject + to the usual mangling. + + *SPEC is updated to point after the function/line number specification. + + FUNFIRSTLINE is non-zero if we desire the first line of real code + in each function (this is ignored in the presence of a LINENUM spec.). + + If CANONICAL is non-NULL, and if any of the sals require a + 'canonical line spec', then *CANONICAL is set to point to an array + of strings, corresponding to and equal in length to the returned + list of sals, such that (*CANONICAL)[i] is non-null and contains a + canonical line spec for the ith returned sal, if needed. If no + canonical line specs are required and CANONICAL is non-null, + *CANONICAL is set to NULL. + + A 'canonical line spec' is simply a name (in the format of the + breakpoint command) that uniquely identifies a breakpoint position, + with no further contextual information or user selection. It is + needed whenever the file name, function name, and line number + information supplied is insufficient for this unique + identification. Currently overloaded functions, the name '*', + or static functions without a filename yield a canonical line spec. + The array and the line spec strings are allocated on the heap; it + is the caller's responsibility to free them. */ + +struct symtabs_and_lines +ada_finish_decode_line_1 (char **spec, struct symtab *file_table, + int funfirstline, char ***canonical) +{ + struct symbol **symbols; + struct block **blocks; + struct block *block; + int n_matches, i, line_num; + struct symtabs_and_lines selected; + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); + char *name; + + int len; + char *lower_name; + char *unquoted_name; + + if (file_table == NULL) + block = get_selected_block (NULL); + else + block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_table), STATIC_BLOCK); + + if (canonical != NULL) + *canonical = (char **) NULL; + + name = *spec; + if (**spec == '*') + *spec += 1; + else + { + while (**spec != '\000' && + !strchr (ada_completer_word_break_characters, **spec)) + *spec += 1; + } + len = *spec - name; + + line_num = -1; + if (file_table != NULL && (*spec)[0] == ':' && isdigit ((*spec)[1])) + { + line_num = strtol (*spec + 1, spec, 10); + while (**spec == ' ' || **spec == '\t') + *spec += 1; + } + + if (name[0] == '*') + { + if (line_num == -1) + error ("Wild-card function with no line number or file name."); + + return all_sals_for_line (file_table->filename, line_num, canonical); + } + + if (name[0] == '\'') + { + name += 1; + len -= 2; + } + + if (name[0] == '<') + { + unquoted_name = (char *) alloca (len - 1); + memcpy (unquoted_name, name + 1, len - 2); + unquoted_name[len - 2] = '\000'; + lower_name = NULL; + } + else + { + unquoted_name = (char *) alloca (len + 1); + memcpy (unquoted_name, name, len); + unquoted_name[len] = '\000'; + lower_name = (char *) alloca (len + 1); + for (i = 0; i < len; i += 1) + lower_name[i] = tolower (name[i]); + lower_name[len] = '\000'; + } + + n_matches = 0; + if (lower_name != NULL) + n_matches = ada_lookup_symbol_list (ada_mangle (lower_name), block, + VAR_DOMAIN, &symbols, &blocks); + if (n_matches == 0) + n_matches = ada_lookup_symbol_list (unquoted_name, block, + VAR_DOMAIN, &symbols, &blocks); + if (n_matches == 0 && line_num >= 0) + error ("No line number information found for %s.", unquoted_name); + else if (n_matches == 0) + { +#ifdef HPPA_COMPILER_BUG + /* FIXME: See comment in symtab.c::decode_line_1 */ +#undef volatile + volatile struct symtab_and_line val; +#define volatile /*nothing */ +#else + struct symtab_and_line val; +#endif + struct minimal_symbol *msymbol; + + init_sal (&val); + + msymbol = NULL; + if (lower_name != NULL) + msymbol = ada_lookup_minimal_symbol (ada_mangle (lower_name)); + if (msymbol == NULL) + msymbol = ada_lookup_minimal_symbol (unquoted_name); + if (msymbol != NULL) + { + val.pc = SYMBOL_VALUE_ADDRESS (msymbol); + val.section = SYMBOL_BFD_SECTION (msymbol); + if (funfirstline) + { + val.pc += FUNCTION_START_OFFSET; + SKIP_PROLOGUE (val.pc); + } + selected.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + selected.sals[0] = val; + selected.nelts = 1; + return selected; + } + + if (!have_full_symbols () && + !have_partial_symbols () && !have_minimal_symbols ()) + error (no_symtab_msg); + + error ("Function \"%s\" not defined.", unquoted_name); + return selected; /* for lint */ + } + + if (line_num >= 0) + { + return + find_sal_from_funcs_and_line (file_table->filename, line_num, + symbols, n_matches); + } + else + { + selected.nelts = + user_select_syms (symbols, blocks, n_matches, n_matches); + } + + selected.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line) * selected.nelts); + memset (selected.sals, 0, selected.nelts * sizeof (selected.sals[i])); + make_cleanup (xfree, selected.sals); + + i = 0; + while (i < selected.nelts) + { + if (SYMBOL_CLASS (symbols[i]) == LOC_BLOCK) + selected.sals[i] = find_function_start_sal (symbols[i], funfirstline); + else if (SYMBOL_LINE (symbols[i]) != 0) + { + selected.sals[i].symtab = symtab_for_sym (symbols[i]); + selected.sals[i].line = SYMBOL_LINE (symbols[i]); + } + else if (line_num >= 0) + { + /* Ignore this choice */ + symbols[i] = symbols[selected.nelts - 1]; + blocks[i] = blocks[selected.nelts - 1]; + selected.nelts -= 1; + continue; + } + else + error ("Line number not known for symbol \"%s\"", unquoted_name); + i += 1; + } + + if (canonical != NULL && (line_num >= 0 || n_matches > 1)) + { + *canonical = (char **) xmalloc (sizeof (char *) * selected.nelts); + for (i = 0; i < selected.nelts; i += 1) + (*canonical)[i] = + extended_canonical_line_spec (selected.sals[i], + SYMBOL_PRINT_NAME (symbols[i])); + } + + discard_cleanups (old_chain); + return selected; +} + +/* The (single) sal corresponding to line LINE_NUM in a symbol table + with file name FILENAME that occurs in one of the functions listed + in SYMBOLS[0 .. NSYMS-1]. */ +static struct symtabs_and_lines +find_sal_from_funcs_and_line (const char *filename, int line_num, + struct symbol **symbols, int nsyms) +{ + struct symtabs_and_lines sals; + int best_index, best; + struct linetable *best_linetable; + struct objfile *objfile; + struct symtab *s; + struct symtab *best_symtab; + + read_all_symtabs (filename); + + best_index = 0; + best_linetable = NULL; + best_symtab = NULL; + best = 0; + ALL_SYMTABS (objfile, s) + { + struct linetable *l; + int ind, exact; + + QUIT; + + if (!DEPRECATED_STREQ (filename, s->filename)) + continue; + l = LINETABLE (s); + ind = find_line_in_linetable (l, line_num, symbols, nsyms, &exact); + if (ind >= 0) + { + if (exact) + { + best_index = ind; + best_linetable = l; + best_symtab = s; + goto done; + } + if (best == 0 || l->item[ind].line < best) + { + best = l->item[ind].line; + best_index = ind; + best_linetable = l; + best_symtab = s; + } + } + } + + if (best == 0) + error ("Line number not found in designated function."); + +done: + + sals.nelts = 1; + sals.sals = (struct symtab_and_line *) xmalloc (sizeof (sals.sals[0])); + + init_sal (&sals.sals[0]); + + sals.sals[0].line = best_linetable->item[best_index].line; + sals.sals[0].pc = best_linetable->item[best_index].pc; + sals.sals[0].symtab = best_symtab; + + return sals; +} + +/* Return the index in LINETABLE of the best match for LINE_NUM whose + pc falls within one of the functions denoted by SYMBOLS[0..NSYMS-1]. + Set *EXACTP to the 1 if the match is exact, and 0 otherwise. */ +static int +find_line_in_linetable (struct linetable *linetable, int line_num, + struct symbol **symbols, int nsyms, int *exactp) +{ + int i, len, best_index, best; + + if (line_num <= 0 || linetable == NULL) + return -1; + + len = linetable->nitems; + for (i = 0, best_index = -1, best = 0; i < len; i += 1) + { + int k; + struct linetable_entry *item = &(linetable->item[i]); + + for (k = 0; k < nsyms; k += 1) + { + if (symbols[k] != NULL && SYMBOL_CLASS (symbols[k]) == LOC_BLOCK + && item->pc >= BLOCK_START (SYMBOL_BLOCK_VALUE (symbols[k])) + && item->pc < BLOCK_END (SYMBOL_BLOCK_VALUE (symbols[k]))) + goto candidate; + } + continue; + + candidate: + + if (item->line == line_num) + { + *exactp = 1; + return i; + } + + if (item->line > line_num && (best == 0 || item->line < best)) + { + best = item->line; + best_index = i; + } + } + + *exactp = 0; + return best_index; +} + +/* Find the smallest k >= LINE_NUM such that k is a line number in + LINETABLE, and k falls strictly within a named function that begins at + or before LINE_NUM. Return -1 if there is no such k. */ +static int +nearest_line_number_in_linetable (struct linetable *linetable, int line_num) +{ + int i, len, best; + + if (line_num <= 0 || linetable == NULL || linetable->nitems == 0) + return -1; + len = linetable->nitems; + + i = 0; + best = INT_MAX; + while (i < len) + { + int k; + struct linetable_entry *item = &(linetable->item[i]); + + if (item->line >= line_num && item->line < best) + { + char *func_name; + CORE_ADDR start, end; + + func_name = NULL; + find_pc_partial_function (item->pc, &func_name, &start, &end); + + if (func_name != NULL && item->pc < end) + { + if (item->line == line_num) + return line_num; + else + { + struct symbol *sym = + standard_lookup (func_name, VAR_DOMAIN); + if (is_plausible_func_for_line (sym, line_num)) + best = item->line; + else + { + do + i += 1; + while (i < len && linetable->item[i].pc < end); + continue; + } + } + } + } + + i += 1; + } + + return (best == INT_MAX) ? -1 : best; +} + + +/* Return the next higher index, k, into LINETABLE such that k > IND, + entry k in LINETABLE has a line number equal to LINE_NUM, k + corresponds to a PC that is in a function different from that + corresponding to IND, and falls strictly within a named function + that begins at a line at or preceding STARTING_LINE. + Return -1 if there is no such k. + IND == -1 corresponds to no function. */ + +static int +find_next_line_in_linetable (struct linetable *linetable, int line_num, + int starting_line, int ind) +{ + int i, len; + + if (line_num <= 0 || linetable == NULL || ind >= linetable->nitems) + return -1; + len = linetable->nitems; + + if (ind >= 0) + { + CORE_ADDR start, end; + + if (find_pc_partial_function (linetable->item[ind].pc, + (char **) NULL, &start, &end)) + { + while (ind < len && linetable->item[ind].pc < end) + ind += 1; + } + else + ind += 1; + } + else + ind = 0; + + i = ind; + while (i < len) + { + int k; + struct linetable_entry *item = &(linetable->item[i]); + + if (item->line >= line_num) + { + char *func_name; + CORE_ADDR start, end; + + func_name = NULL; + find_pc_partial_function (item->pc, &func_name, &start, &end); + + if (func_name != NULL && item->pc < end) + { + if (item->line == line_num) + { + struct symbol *sym = + standard_lookup (func_name, VAR_DOMAIN); + if (is_plausible_func_for_line (sym, starting_line)) + return i; + else + { + while ((i + 1) < len && linetable->item[i + 1].pc < end) + i += 1; + } + } + } + } + i += 1; + } + + return -1; +} + +/* True iff function symbol SYM starts somewhere at or before line # + LINE_NUM. */ +static int +is_plausible_func_for_line (struct symbol *sym, int line_num) +{ + struct symtab_and_line start_sal; + + if (sym == NULL) + return 0; + + start_sal = find_function_start_sal (sym, 0); + + return (start_sal.line != 0 && line_num >= start_sal.line); +} + +static void +debug_print_lines (struct linetable *lt) +{ + int i; + + if (lt == NULL) + return; + + fprintf (stderr, "\t"); + for (i = 0; i < lt->nitems; i += 1) + fprintf (stderr, "(%d->%p) ", lt->item[i].line, (void *) lt->item[i].pc); + fprintf (stderr, "\n"); +} + +static void +debug_print_block (struct block *b) +{ + struct dict_iterator iter; + struct symbol *sym; + + fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]", + b, BLOCK_START (b), BLOCK_END (b)); + if (BLOCK_FUNCTION (b) != NULL) + fprintf (stderr, " Function: %s", DEPRECATED_SYMBOL_NAME (BLOCK_FUNCTION (b))); + fprintf (stderr, "\n"); + fprintf (stderr, "\t Superblock: %p\n", BLOCK_SUPERBLOCK (b)); + fprintf (stderr, "\t Symbols:"); + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + fprintf (stderr, " %s", DEPRECATED_SYMBOL_NAME (sym)); + } + fprintf (stderr, "\n"); +} + +static void +debug_print_blocks (struct blockvector *bv) +{ + int i; + + if (bv == NULL) + return; + for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i += 1) + { + fprintf (stderr, "%6d. ", i); + debug_print_block (BLOCKVECTOR_BLOCK (bv, i)); + } +} + +static void +debug_print_symtab (struct symtab *s) +{ + fprintf (stderr, "Symtab %p\n File: %s; Dir: %s\n", s, + s->filename, s->dirname); + fprintf (stderr, " Blockvector: %p, Primary: %d\n", + BLOCKVECTOR (s), s->primary); + debug_print_blocks (BLOCKVECTOR (s)); + fprintf (stderr, " Line table: %p\n", LINETABLE (s)); + debug_print_lines (LINETABLE (s)); +} + +/* Read in all symbol tables corresponding to partial symbol tables + with file name FILENAME. */ +static void +read_all_symtabs (const char *filename) +{ + struct partial_symtab *ps; + struct objfile *objfile; + + ALL_PSYMTABS (objfile, ps) + { + QUIT; + + if (DEPRECATED_STREQ (filename, ps->filename)) + PSYMTAB_TO_SYMTAB (ps); + } +} + +/* All sals corresponding to line LINE_NUM in a symbol table from file + FILENAME, as filtered by the user. If CANONICAL is not null, set + it to a corresponding array of canonical line specs. */ +static struct symtabs_and_lines +all_sals_for_line (const char *filename, int line_num, char ***canonical) +{ + struct symtabs_and_lines result; + struct objfile *objfile; + struct symtab *s; + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); + size_t len; + + read_all_symtabs (filename); + + result.sals = + (struct symtab_and_line *) xmalloc (4 * sizeof (result.sals[0])); + result.nelts = 0; + len = 4; + make_cleanup (free_current_contents, &result.sals); + + ALL_SYMTABS (objfile, s) + { + int ind, target_line_num; + + QUIT; + + if (!DEPRECATED_STREQ (s->filename, filename)) + continue; + + target_line_num = + nearest_line_number_in_linetable (LINETABLE (s), line_num); + if (target_line_num == -1) + continue; + + ind = -1; + while (1) + { + ind = + find_next_line_in_linetable (LINETABLE (s), + target_line_num, line_num, ind); + + if (ind < 0) + break; + + GROW_VECT (result.sals, len, result.nelts + 1); + init_sal (&result.sals[result.nelts]); + result.sals[result.nelts].line = LINETABLE (s)->item[ind].line; + result.sals[result.nelts].pc = LINETABLE (s)->item[ind].pc; + result.sals[result.nelts].symtab = s; + result.nelts += 1; + } + } + + if (canonical != NULL || result.nelts > 1) + { + int k; + char **func_names = (char **) alloca (result.nelts * sizeof (char *)); + int first_choice = (result.nelts > 1) ? 2 : 1; + int n; + int *choices = (int *) alloca (result.nelts * sizeof (int)); + + for (k = 0; k < result.nelts; k += 1) + { + find_pc_partial_function (result.sals[k].pc, &func_names[k], + (CORE_ADDR *) NULL, (CORE_ADDR *) NULL); + if (func_names[k] == NULL) + error ("Could not find function for one or more breakpoints."); + } + + if (result.nelts > 1) + { + printf_unfiltered ("[0] cancel\n"); + if (result.nelts > 1) + printf_unfiltered ("[1] all\n"); + for (k = 0; k < result.nelts; k += 1) + printf_unfiltered ("[%d] %s\n", k + first_choice, + ada_demangle (func_names[k])); + + n = get_selections (choices, result.nelts, result.nelts, + result.nelts > 1, "instance-choice"); + + for (k = 0; k < n; k += 1) + { + result.sals[k] = result.sals[choices[k]]; + func_names[k] = func_names[choices[k]]; + } + result.nelts = n; + } + + if (canonical != NULL) + { + *canonical = (char **) xmalloc (result.nelts * sizeof (char **)); + make_cleanup (xfree, *canonical); + for (k = 0; k < result.nelts; k += 1) + { + (*canonical)[k] = + extended_canonical_line_spec (result.sals[k], func_names[k]); + if ((*canonical)[k] == NULL) + error ("Could not locate one or more breakpoints."); + make_cleanup (xfree, (*canonical)[k]); + } + } + } + + discard_cleanups (old_chain); + return result; +} + + +/* A canonical line specification of the form FILE:NAME:LINENUM for + symbol table and line data SAL. NULL if insufficient + information. The caller is responsible for releasing any space + allocated. */ + +static char * +extended_canonical_line_spec (struct symtab_and_line sal, const char *name) +{ + char *r; + + if (sal.symtab == NULL || sal.symtab->filename == NULL || sal.line <= 0) + return NULL; + + r = (char *) xmalloc (strlen (name) + strlen (sal.symtab->filename) + + sizeof (sal.line) * 3 + 3); + sprintf (r, "%s:'%s':%d", sal.symtab->filename, name, sal.line); + return r; +} + +#if 0 +int begin_bnum = -1; +#endif +int begin_annotate_level = 0; + +static void +begin_cleanup (void *dummy) +{ + begin_annotate_level = 0; +} + +static void +begin_command (char *args, int from_tty) +{ + struct minimal_symbol *msym; + CORE_ADDR main_program_name_addr; + char main_program_name[1024]; + struct cleanup *old_chain = make_cleanup (begin_cleanup, NULL); + begin_annotate_level = 2; + + /* Check that there is a program to debug */ + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + + /* Check that we are debugging an Ada program */ + /* if (ada_update_initial_language (language_unknown, NULL) != language_ada) + error ("Cannot find the Ada initialization procedure. Is this an Ada main program?"); + */ + /* FIXME: language_ada should be defined in defs.h */ + + /* Get the address of the name of the main procedure */ + msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL); + + if (msym != NULL) + { + main_program_name_addr = SYMBOL_VALUE_ADDRESS (msym); + if (main_program_name_addr == 0) + error ("Invalid address for Ada main program name."); + + /* Read the name of the main procedure */ + extract_string (main_program_name_addr, main_program_name); + + /* Put a temporary breakpoint in the Ada main program and run */ + do_command ("tbreak ", main_program_name, 0); + do_command ("run ", args, 0); + } + else + { + /* If we could not find the symbol containing the name of the + main program, that means that the compiler that was used to build + was not recent enough. In that case, we fallback to the previous + mechanism, which is a little bit less reliable, but has proved to work + in most cases. The only cases where it will fail is when the user + has set some breakpoints which will be hit before the end of the + begin command processing (eg in the initialization code). + + The begining of the main Ada subprogram is located by breaking + on the adainit procedure. Since we know that the binder generates + the call to this procedure exactly 2 calls before the call to the + Ada main subprogram, it is then easy to put a breakpoint on this + Ada main subprogram once we hit adainit. + */ + do_command ("tbreak adainit", 0); + do_command ("run ", args, 0); + do_command ("up", 0); + do_command ("tbreak +2", 0); + do_command ("continue", 0); + do_command ("step", 0); + } + + do_cleanups (old_chain); +} + +int +is_ada_runtime_file (char *filename) +{ + return (DEPRECATED_STREQN (filename, "s-", 2) || + DEPRECATED_STREQN (filename, "a-", 2) || + DEPRECATED_STREQN (filename, "g-", 2) || DEPRECATED_STREQN (filename, "i-", 2)); +} + +/* find the first frame that contains debugging information and that is not + part of the Ada run-time, starting from fi and moving upward. */ + +int +find_printable_frame (struct frame_info *fi, int level) +{ + struct symtab_and_line sal; + + for (; fi != NULL; level += 1, fi = get_prev_frame (fi)) + { + find_frame_sal (fi, &sal); + if (sal.symtab && !is_ada_runtime_file (sal.symtab->filename)) + { +#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET) + /* libpthread.so contains some debugging information that prevents us + from finding the right frame */ + + if (sal.symtab->objfile && + DEPRECATED_STREQ (sal.symtab->objfile->name, "/usr/shlib/libpthread.so")) + continue; +#endif + deprecated_selected_frame = fi; + break; + } + } + + return level; +} + +void +ada_report_exception_break (struct breakpoint *b) +{ + /* FIXME: break_on_exception should be defined in breakpoint.h */ + /* if (b->break_on_exception == 1) + { + /* Assume that cond has 16 elements, the 15th + being the exception *//* + if (b->cond && b->cond->nelts == 16) + { + ui_out_text (uiout, "on "); + ui_out_field_string (uiout, "exception", + SYMBOL_NAME (b->cond->elts[14].symbol)); + } + else + ui_out_text (uiout, "on all exceptions"); + } + else if (b->break_on_exception == 2) + ui_out_text (uiout, "on unhandled exception"); + else if (b->break_on_exception == 3) + ui_out_text (uiout, "on assert failure"); + #else + if (b->break_on_exception == 1) + { */ + /* Assume that cond has 16 elements, the 15th + being the exception *//* + if (b->cond && b->cond->nelts == 16) + { + fputs_filtered ("on ", gdb_stdout); + fputs_filtered (SYMBOL_NAME + (b->cond->elts[14].symbol), gdb_stdout); + } + else + fputs_filtered ("on all exceptions", gdb_stdout); + } + else if (b->break_on_exception == 2) + fputs_filtered ("on unhandled exception", gdb_stdout); + else if (b->break_on_exception == 3) + fputs_filtered ("on assert failure", gdb_stdout); + */ +} + +int +ada_is_exception_sym (struct symbol *sym) +{ + char *type_name = type_name_no_tag (SYMBOL_TYPE (sym)); + + return (SYMBOL_CLASS (sym) != LOC_TYPEDEF + && SYMBOL_CLASS (sym) != LOC_BLOCK + && SYMBOL_CLASS (sym) != LOC_CONST + && type_name != NULL && DEPRECATED_STREQ (type_name, "exception")); +} + +int +ada_maybe_exception_partial_symbol (struct partial_symbol *sym) +{ + return (SYMBOL_CLASS (sym) != LOC_TYPEDEF + && SYMBOL_CLASS (sym) != LOC_BLOCK + && SYMBOL_CLASS (sym) != LOC_CONST); +} + +/* If ARG points to an Ada exception or assert breakpoint, rewrite + into equivalent form. Return resulting argument string. Set + *BREAK_ON_EXCEPTIONP to 1 for ordinary break on exception, 2 for + break on unhandled, 3 for assert, 0 otherwise. */ +char * +ada_breakpoint_rewrite (char *arg, int *break_on_exceptionp) +{ + if (arg == NULL) + return arg; + *break_on_exceptionp = 0; + /* FIXME: language_ada should be defined in defs.h */ + /* if (current_language->la_language == language_ada + && DEPRECATED_STREQN (arg, "exception", 9) && + (arg[9] == ' ' || arg[9] == '\t' || arg[9] == '\0')) + { + char *tok, *end_tok; + int toklen; + + *break_on_exceptionp = 1; + + tok = arg+9; + while (*tok == ' ' || *tok == '\t') + tok += 1; + + end_tok = tok; + + while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') + end_tok += 1; + + toklen = end_tok - tok; + + arg = (char*) xmalloc (sizeof ("__gnat_raise_nodefer_with_msg if " + "long_integer(e) = long_integer(&)") + + toklen + 1); + make_cleanup (xfree, arg); + if (toklen == 0) + strcpy (arg, "__gnat_raise_nodefer_with_msg"); + else if (DEPRECATED_STREQN (tok, "unhandled", toklen)) + { + *break_on_exceptionp = 2; + strcpy (arg, "__gnat_unhandled_exception"); + } + else + { + sprintf (arg, "__gnat_raise_nodefer_with_msg if " + "long_integer(e) = long_integer(&%.*s)", + toklen, tok); + } + } + else if (current_language->la_language == language_ada + && DEPRECATED_STREQN (arg, "assert", 6) && + (arg[6] == ' ' || arg[6] == '\t' || arg[6] == '\0')) + { + char *tok = arg + 6; + + *break_on_exceptionp = 3; + + arg = (char*) + xmalloc (sizeof ("system__assertions__raise_assert_failure") + + strlen (tok) + 1); + make_cleanup (xfree, arg); + sprintf (arg, "system__assertions__raise_assert_failure%s", tok); + } + */ + return arg; +} + + + /* Field Access */ + +/* True if field number FIELD_NUM in struct or union type TYPE is supposed + to be invisible to users. */ + +int +ada_is_ignored_field (struct type *type, int field_num) +{ + if (field_num < 0 || field_num > TYPE_NFIELDS (type)) + return 1; + else + { + const char *name = TYPE_FIELD_NAME (type, field_num); + return (name == NULL + || (name[0] == '_' && !DEPRECATED_STREQN (name, "_parent", 7))); + } +} + +/* True iff structure type TYPE has a tag field. */ + +int +ada_is_tagged_type (struct type *type) +{ + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT) + return 0; + + return (ada_lookup_struct_elt_type (type, "_tag", 1, NULL) != NULL); +} + +/* The type of the tag on VAL. */ + +struct type * +ada_tag_type (struct value *val) +{ + return ada_lookup_struct_elt_type (VALUE_TYPE (val), "_tag", 0, NULL); +} + +/* The value of the tag on VAL. */ + +struct value * +ada_value_tag (struct value *val) +{ + return ada_value_struct_elt (val, "_tag", "record"); +} + +/* The parent type of TYPE, or NULL if none. */ + +struct type * +ada_parent_type (struct type *type) +{ + int i; + + CHECK_TYPEDEF (type); + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT) + return NULL; + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + if (ada_is_parent_field (type, i)) + return check_typedef (TYPE_FIELD_TYPE (type, i)); + + return NULL; +} + +/* True iff field number FIELD_NUM of structure type TYPE contains the + parent-type (inherited) fields of a derived type. Assumes TYPE is + a structure type with at least FIELD_NUM+1 fields. */ + +int +ada_is_parent_field (struct type *type, int field_num) +{ + const char *name = TYPE_FIELD_NAME (check_typedef (type), field_num); + return (name != NULL && + (DEPRECATED_STREQN (name, "PARENT", 6) || DEPRECATED_STREQN (name, "_parent", 7))); +} + +/* True iff field number FIELD_NUM of structure type TYPE is a + transparent wrapper field (which should be silently traversed when doing + field selection and flattened when printing). Assumes TYPE is a + structure type with at least FIELD_NUM+1 fields. Such fields are always + structures. */ + +int +ada_is_wrapper_field (struct type *type, int field_num) +{ + const char *name = TYPE_FIELD_NAME (type, field_num); + return (name != NULL + && (DEPRECATED_STREQN (name, "PARENT", 6) || DEPRECATED_STREQ (name, "REP") + || DEPRECATED_STREQN (name, "_parent", 7) + || name[0] == 'S' || name[0] == 'R' || name[0] == 'O')); +} + +/* True iff field number FIELD_NUM of structure or union type TYPE + is a variant wrapper. Assumes TYPE is a structure type with at least + FIELD_NUM+1 fields. */ + +int +ada_is_variant_part (struct type *type, int field_num) +{ + struct type *field_type = TYPE_FIELD_TYPE (type, field_num); + return (TYPE_CODE (field_type) == TYPE_CODE_UNION + || (is_dynamic_field (type, field_num) + && TYPE_CODE (TYPE_TARGET_TYPE (field_type)) == + TYPE_CODE_UNION)); +} + +/* Assuming that VAR_TYPE is a variant wrapper (type of the variant part) + whose discriminants are contained in the record type OUTER_TYPE, + returns the type of the controlling discriminant for the variant. */ + +struct type * +ada_variant_discrim_type (struct type *var_type, struct type *outer_type) +{ + char *name = ada_variant_discrim_name (var_type); + struct type *type = ada_lookup_struct_elt_type (outer_type, name, 1, NULL); + if (type == NULL) + return builtin_type_int; + else + return type; +} + +/* Assuming that TYPE is the type of a variant wrapper, and FIELD_NUM is a + valid field number within it, returns 1 iff field FIELD_NUM of TYPE + represents a 'when others' clause; otherwise 0. */ + +int +ada_is_others_clause (struct type *type, int field_num) +{ + const char *name = TYPE_FIELD_NAME (type, field_num); + return (name != NULL && name[0] == 'O'); +} + +/* Assuming that TYPE0 is the type of the variant part of a record, + returns the name of the discriminant controlling the variant. The + value is valid until the next call to ada_variant_discrim_name. */ + +char * +ada_variant_discrim_name (struct type *type0) +{ + static char *result = NULL; + static size_t result_len = 0; + struct type *type; + const char *name; + const char *discrim_end; + const char *discrim_start; + + if (TYPE_CODE (type0) == TYPE_CODE_PTR) + type = TYPE_TARGET_TYPE (type0); + else + type = type0; + + name = ada_type_name (type); + + if (name == NULL || name[0] == '\000') + return ""; + + for (discrim_end = name + strlen (name) - 6; discrim_end != name; + discrim_end -= 1) + { + if (DEPRECATED_STREQN (discrim_end, "___XVN", 6)) + break; + } + if (discrim_end == name) + return ""; + + for (discrim_start = discrim_end; discrim_start != name + 3; + discrim_start -= 1) + { + if (discrim_start == name + 1) + return ""; + if ((discrim_start > name + 3 && DEPRECATED_STREQN (discrim_start - 3, "___", 3)) + || discrim_start[-1] == '.') + break; + } + + GROW_VECT (result, result_len, discrim_end - discrim_start + 1); + strncpy (result, discrim_start, discrim_end - discrim_start); + result[discrim_end - discrim_start] = '\0'; + return result; +} + +/* Scan STR for a subtype-encoded number, beginning at position K. Put the + position of the character just past the number scanned in *NEW_K, + if NEW_K!=NULL. Put the scanned number in *R, if R!=NULL. Return 1 + if there was a valid number at the given position, and 0 otherwise. A + "subtype-encoded" number consists of the absolute value in decimal, + followed by the letter 'm' to indicate a negative number. Assumes 0m + does not occur. */ + +int +ada_scan_number (const char str[], int k, LONGEST * R, int *new_k) +{ + ULONGEST RU; + + if (!isdigit (str[k])) + return 0; + + /* Do it the hard way so as not to make any assumption about + the relationship of unsigned long (%lu scan format code) and + LONGEST. */ + RU = 0; + while (isdigit (str[k])) + { + RU = RU * 10 + (str[k] - '0'); + k += 1; + } + + if (str[k] == 'm') + { + if (R != NULL) + *R = (-(LONGEST) (RU - 1)) - 1; + k += 1; + } + else if (R != NULL) + *R = (LONGEST) RU; + + /* NOTE on the above: Technically, C does not say what the results of + - (LONGEST) RU or (LONGEST) -RU are for RU == largest positive + number representable as a LONGEST (although either would probably work + in most implementations). When RU>0, the locution in the then branch + above is always equivalent to the negative of RU. */ + + if (new_k != NULL) + *new_k = k; + return 1; +} + +/* Assuming that TYPE is a variant part wrapper type (a VARIANTS field), + and FIELD_NUM is a valid field number within it, returns 1 iff VAL is + in the range encoded by field FIELD_NUM of TYPE; otherwise 0. */ + +int +ada_in_variant (LONGEST val, struct type *type, int field_num) +{ + const char *name = TYPE_FIELD_NAME (type, field_num); + int p; + + p = 0; + while (1) + { + switch (name[p]) + { + case '\0': + return 0; + case 'S': + { + LONGEST W; + if (!ada_scan_number (name, p + 1, &W, &p)) + return 0; + if (val == W) + return 1; + break; + } + case 'R': + { + LONGEST L, U; + if (!ada_scan_number (name, p + 1, &L, &p) + || name[p] != 'T' || !ada_scan_number (name, p + 1, &U, &p)) + return 0; + if (val >= L && val <= U) + return 1; + break; + } + case 'O': + return 1; + default: + return 0; + } + } +} + +/* Given a value ARG1 (offset by OFFSET bytes) + of a struct or union type ARG_TYPE, + extract and return the value of one of its (non-static) fields. + FIELDNO says which field. Differs from value_primitive_field only + in that it can handle packed values of arbitrary type. */ + +struct value * +ada_value_primitive_field (struct value *arg1, int offset, int fieldno, + struct type *arg_type) +{ + struct value *v; + struct type *type; + + CHECK_TYPEDEF (arg_type); + type = TYPE_FIELD_TYPE (arg_type, fieldno); + + /* Handle packed fields */ + + if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0) + { + int bit_pos = TYPE_FIELD_BITPOS (arg_type, fieldno); + int bit_size = TYPE_FIELD_BITSIZE (arg_type, fieldno); + + return ada_value_primitive_packed_val (arg1, VALUE_CONTENTS (arg1), + offset + bit_pos / 8, + bit_pos % 8, bit_size, type); + } + else + return value_primitive_field (arg1, offset, fieldno, arg_type); +} + + +/* Look for a field NAME in ARG. Adjust the address of ARG by OFFSET bytes, + and search in it assuming it has (class) type TYPE. + If found, return value, else return NULL. + + Searches recursively through wrapper fields (e.g., '_parent'). */ + +struct value * +ada_search_struct_field (char *name, struct value *arg, int offset, + struct type *type) +{ + int i; + CHECK_TYPEDEF (type); + + for (i = TYPE_NFIELDS (type) - 1; i >= 0; i -= 1) + { + char *t_field_name = TYPE_FIELD_NAME (type, i); + + if (t_field_name == NULL) + continue; + + else if (field_name_match (t_field_name, name)) + return ada_value_primitive_field (arg, offset, i, type); + + else if (ada_is_wrapper_field (type, i)) + { + struct value *v = ada_search_struct_field (name, arg, + offset + + TYPE_FIELD_BITPOS (type, + i) / + 8, + TYPE_FIELD_TYPE (type, + i)); + if (v != NULL) + return v; + } + + else if (ada_is_variant_part (type, i)) + { + int j; + struct type *field_type = check_typedef (TYPE_FIELD_TYPE (type, i)); + int var_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8; + + for (j = TYPE_NFIELDS (field_type) - 1; j >= 0; j -= 1) + { + struct value *v = ada_search_struct_field (name, arg, + var_offset + + + TYPE_FIELD_BITPOS + (field_type, j) / 8, + TYPE_FIELD_TYPE + (field_type, j)); + if (v != NULL) + return v; + } + } + } + return NULL; +} + +/* Given ARG, a value of type (pointer to a)* structure/union, + extract the component named NAME from the ultimate target structure/union + and return it as a value with its appropriate type. + + The routine searches for NAME among all members of the structure itself + and (recursively) among all members of any wrapper members + (e.g., '_parent'). + + ERR is a name (for use in error messages) that identifies the class + of entity that ARG is supposed to be. */ + +struct value * +ada_value_struct_elt (struct value *arg, char *name, char *err) +{ + struct type *t; + struct value *v; + + arg = ada_coerce_ref (arg); + t = check_typedef (VALUE_TYPE (arg)); + + /* Follow pointers until we get to a non-pointer. */ + + while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF) + { + arg = ada_value_ind (arg); + t = check_typedef (VALUE_TYPE (arg)); + } + + if (TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION) + error ("Attempt to extract a component of a value that is not a %s.", + err); + + v = ada_search_struct_field (name, arg, 0, t); + if (v == NULL) + error ("There is no member named %s.", name); + + return v; +} + +/* Given a type TYPE, look up the type of the component of type named NAME. + If DISPP is non-null, add its byte displacement from the beginning of a + structure (pointed to by a value) of type TYPE to *DISPP (does not + work for packed fields). + + Matches any field whose name has NAME as a prefix, possibly + followed by "___". + + TYPE can be either a struct or union, or a pointer or reference to + a struct or union. If it is a pointer or reference, its target + type is automatically used. + + Looks recursively into variant clauses and parent types. + + If NOERR is nonzero, return NULL if NAME is not suitably defined. */ + +struct type * +ada_lookup_struct_elt_type (struct type *type, char *name, int noerr, + int *dispp) +{ + int i; + + if (name == NULL) + goto BadName; + + while (1) + { + CHECK_TYPEDEF (type); + if (TYPE_CODE (type) != TYPE_CODE_PTR + && TYPE_CODE (type) != TYPE_CODE_REF) + break; + type = TYPE_TARGET_TYPE (type); + } + + if (TYPE_CODE (type) != TYPE_CODE_STRUCT && + TYPE_CODE (type) != TYPE_CODE_UNION) + { + target_terminal_ours (); + gdb_flush (gdb_stdout); + fprintf_unfiltered (gdb_stderr, "Type "); + type_print (type, "", gdb_stderr, -1); + error (" is not a structure or union type"); + } + + type = to_static_fixed_type (type); + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + { + char *t_field_name = TYPE_FIELD_NAME (type, i); + struct type *t; + int disp; + + if (t_field_name == NULL) + continue; + + else if (field_name_match (t_field_name, name)) + { + if (dispp != NULL) + *dispp += TYPE_FIELD_BITPOS (type, i) / 8; + return check_typedef (TYPE_FIELD_TYPE (type, i)); + } + + else if (ada_is_wrapper_field (type, i)) + { + disp = 0; + t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (type, i), name, + 1, &disp); + if (t != NULL) + { + if (dispp != NULL) + *dispp += disp + TYPE_FIELD_BITPOS (type, i) / 8; + return t; + } + } + + else if (ada_is_variant_part (type, i)) + { + int j; + struct type *field_type = check_typedef (TYPE_FIELD_TYPE (type, i)); + + for (j = TYPE_NFIELDS (field_type) - 1; j >= 0; j -= 1) + { + disp = 0; + t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (field_type, j), + name, 1, &disp); + if (t != NULL) + { + if (dispp != NULL) + *dispp += disp + TYPE_FIELD_BITPOS (type, i) / 8; + return t; + } + } + } + + } + +BadName: + if (!noerr) + { + target_terminal_ours (); + gdb_flush (gdb_stdout); + fprintf_unfiltered (gdb_stderr, "Type "); + type_print (type, "", gdb_stderr, -1); + fprintf_unfiltered (gdb_stderr, " has no component named "); + error ("%s", name == NULL ? "" : name); + } + + return NULL; +} + +/* Assuming that VAR_TYPE is the type of a variant part of a record (a union), + within a value of type OUTER_TYPE that is stored in GDB at + OUTER_VALADDR, determine which variant clause (field number in VAR_TYPE, + numbering from 0) is applicable. Returns -1 if none are. */ + +int +ada_which_variant_applies (struct type *var_type, struct type *outer_type, + char *outer_valaddr) +{ + int others_clause; + int i; + int disp; + struct type *discrim_type; + char *discrim_name = ada_variant_discrim_name (var_type); + LONGEST discrim_val; + + disp = 0; + discrim_type = + ada_lookup_struct_elt_type (outer_type, discrim_name, 1, &disp); + if (discrim_type == NULL) + return -1; + discrim_val = unpack_long (discrim_type, outer_valaddr + disp); + + others_clause = -1; + for (i = 0; i < TYPE_NFIELDS (var_type); i += 1) + { + if (ada_is_others_clause (var_type, i)) + others_clause = i; + else if (ada_in_variant (discrim_val, var_type, i)) + return i; + } + + return others_clause; +} + + + + /* Dynamic-Sized Records */ + +/* Strategy: The type ostensibly attached to a value with dynamic size + (i.e., a size that is not statically recorded in the debugging + data) does not accurately reflect the size or layout of the value. + Our strategy is to convert these values to values with accurate, + conventional types that are constructed on the fly. */ + +/* There is a subtle and tricky problem here. In general, we cannot + determine the size of dynamic records without its data. However, + the 'struct value' data structure, which GDB uses to represent + quantities in the inferior process (the target), requires the size + of the type at the time of its allocation in order to reserve space + for GDB's internal copy of the data. That's why the + 'to_fixed_xxx_type' routines take (target) addresses as parameters, + rather than struct value*s. + + However, GDB's internal history variables ($1, $2, etc.) are + struct value*s containing internal copies of the data that are not, in + general, the same as the data at their corresponding addresses in + the target. Fortunately, the types we give to these values are all + conventional, fixed-size types (as per the strategy described + above), so that we don't usually have to perform the + 'to_fixed_xxx_type' conversions to look at their values. + Unfortunately, there is one exception: if one of the internal + history variables is an array whose elements are unconstrained + records, then we will need to create distinct fixed types for each + element selected. */ + +/* The upshot of all of this is that many routines take a (type, host + address, target address) triple as arguments to represent a value. + The host address, if non-null, is supposed to contain an internal + copy of the relevant data; otherwise, the program is to consult the + target at the target address. */ + +/* Assuming that VAL0 represents a pointer value, the result of + dereferencing it. Differs from value_ind in its treatment of + dynamic-sized types. */ + +struct value * +ada_value_ind (struct value *val0) +{ + struct value *val = unwrap_value (value_ind (val0)); + return ada_to_fixed_value (VALUE_TYPE (val), 0, + VALUE_ADDRESS (val) + VALUE_OFFSET (val), val); +} + +/* The value resulting from dereferencing any "reference to" + * qualifiers on VAL0. */ +static struct value * +ada_coerce_ref (struct value *val0) +{ + if (TYPE_CODE (VALUE_TYPE (val0)) == TYPE_CODE_REF) + { + struct value *val = val0; + COERCE_REF (val); + val = unwrap_value (val); + return ada_to_fixed_value (VALUE_TYPE (val), 0, + VALUE_ADDRESS (val) + VALUE_OFFSET (val), + val); + } + else + return val0; +} + +/* Return OFF rounded upward if necessary to a multiple of + ALIGNMENT (a power of 2). */ + +static unsigned int +align_value (unsigned int off, unsigned int alignment) +{ + return (off + alignment - 1) & ~(alignment - 1); +} + +/* Return the additional bit offset required by field F of template + type TYPE. */ + +static unsigned int +field_offset (struct type *type, int f) +{ + int n = TYPE_FIELD_BITPOS (type, f); + /* Kludge (temporary?) to fix problem with dwarf output. */ + if (n < 0) + return (unsigned int) n & 0xffff; + else + return n; +} + + +/* Return the bit alignment required for field #F of template type TYPE. */ + +static unsigned int +field_alignment (struct type *type, int f) +{ + const char *name = TYPE_FIELD_NAME (type, f); + int len = (name == NULL) ? 0 : strlen (name); + int align_offset; + + if (len < 8 || !isdigit (name[len - 1])) + return TARGET_CHAR_BIT; + + if (isdigit (name[len - 2])) + align_offset = len - 2; + else + align_offset = len - 1; + + if (align_offset < 7 || !DEPRECATED_STREQN ("___XV", name + align_offset - 6, 5)) + return TARGET_CHAR_BIT; + + return atoi (name + align_offset) * TARGET_CHAR_BIT; +} + +/* Find a type named NAME. Ignores ambiguity. */ +struct type * +ada_find_any_type (const char *name) +{ + struct symbol *sym; + + sym = standard_lookup (name, VAR_DOMAIN); + if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + return SYMBOL_TYPE (sym); + + sym = standard_lookup (name, STRUCT_DOMAIN); + if (sym != NULL) + return SYMBOL_TYPE (sym); + + return NULL; +} + +/* Because of GNAT encoding conventions, several GDB symbols may match a + given type name. If the type denoted by TYPE0 is to be preferred to + that of TYPE1 for purposes of type printing, return non-zero; + otherwise return 0. */ +int +ada_prefer_type (struct type *type0, struct type *type1) +{ + if (type1 == NULL) + return 1; + else if (type0 == NULL) + return 0; + else if (TYPE_CODE (type1) == TYPE_CODE_VOID) + return 1; + else if (TYPE_CODE (type0) == TYPE_CODE_VOID) + return 0; + else if (ada_is_packed_array_type (type0)) + return 1; + else if (ada_is_array_descriptor (type0) + && !ada_is_array_descriptor (type1)) + return 1; + else if (ada_renaming_type (type0) != NULL + && ada_renaming_type (type1) == NULL) + return 1; + return 0; +} + +/* The name of TYPE, which is either its TYPE_NAME, or, if that is + null, its TYPE_TAG_NAME. Null if TYPE is null. */ +char * +ada_type_name (struct type *type) +{ + if (type == NULL) + return NULL; + else if (TYPE_NAME (type) != NULL) + return TYPE_NAME (type); + else + return TYPE_TAG_NAME (type); +} + +/* Find a parallel type to TYPE whose name is formed by appending + SUFFIX to the name of TYPE. */ + +struct type * +ada_find_parallel_type (struct type *type, const char *suffix) +{ + static char *name; + static size_t name_len = 0; + struct symbol **syms; + struct block **blocks; + int nsyms; + int len; + char *typename = ada_type_name (type); + + if (typename == NULL) + return NULL; + + len = strlen (typename); + + GROW_VECT (name, name_len, len + strlen (suffix) + 1); + + strcpy (name, typename); + strcpy (name + len, suffix); + + return ada_find_any_type (name); +} + + +/* If TYPE is a variable-size record type, return the corresponding template + type describing its fields. Otherwise, return NULL. */ + +static struct type * +dynamic_template_type (struct type *type) +{ + CHECK_TYPEDEF (type); + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT + || ada_type_name (type) == NULL) + return NULL; + else + { + int len = strlen (ada_type_name (type)); + if (len > 6 && DEPRECATED_STREQ (ada_type_name (type) + len - 6, "___XVE")) + return type; + else + return ada_find_parallel_type (type, "___XVE"); + } +} + +/* Assuming that TEMPL_TYPE is a union or struct type, returns + non-zero iff field FIELD_NUM of TEMPL_TYPE has dynamic size. */ + +static int +is_dynamic_field (struct type *templ_type, int field_num) +{ + const char *name = TYPE_FIELD_NAME (templ_type, field_num); + return name != NULL + && TYPE_CODE (TYPE_FIELD_TYPE (templ_type, field_num)) == TYPE_CODE_PTR + && strstr (name, "___XVL") != NULL; +} + +/* Assuming that TYPE is a struct type, returns non-zero iff TYPE + contains a variant part. */ + +static int +contains_variant_part (struct type *type) +{ + int f; + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT + || TYPE_NFIELDS (type) <= 0) + return 0; + return ada_is_variant_part (type, TYPE_NFIELDS (type) - 1); +} + +/* A record type with no fields, . */ +static struct type * +empty_record (struct objfile *objfile) +{ + struct type *type = alloc_type (objfile); + TYPE_CODE (type) = TYPE_CODE_STRUCT; + TYPE_NFIELDS (type) = 0; + TYPE_FIELDS (type) = NULL; + TYPE_NAME (type) = ""; + TYPE_TAG_NAME (type) = NULL; + TYPE_FLAGS (type) = 0; + TYPE_LENGTH (type) = 0; + return type; +} + +/* An ordinary record type (with fixed-length fields) that describes + the value of type TYPE at VALADDR or ADDRESS (see comments at + the beginning of this section) VAL according to GNAT conventions. + DVAL0 should describe the (portion of a) record that contains any + necessary discriminants. It should be NULL if VALUE_TYPE (VAL) is + an outer-level type (i.e., as opposed to a branch of a variant.) A + variant field (unless unchecked) is replaced by a particular branch + of the variant. */ +/* NOTE: Limitations: For now, we assume that dynamic fields and + * variants occupy whole numbers of bytes. However, they need not be + * byte-aligned. */ + +static struct type * +template_to_fixed_record_type (struct type *type, char *valaddr, + CORE_ADDR address, struct value *dval0) +{ + struct value *mark = value_mark (); + struct value *dval; + struct type *rtype; + int nfields, bit_len; + long off; + int f; + + nfields = TYPE_NFIELDS (type); + rtype = alloc_type (TYPE_OBJFILE (type)); + TYPE_CODE (rtype) = TYPE_CODE_STRUCT; + INIT_CPLUS_SPECIFIC (rtype); + TYPE_NFIELDS (rtype) = nfields; + TYPE_FIELDS (rtype) = (struct field *) + TYPE_ALLOC (rtype, nfields * sizeof (struct field)); + memset (TYPE_FIELDS (rtype), 0, sizeof (struct field) * nfields); + TYPE_NAME (rtype) = ada_type_name (type); + TYPE_TAG_NAME (rtype) = NULL; + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in + gdbtypes.h */ + /* TYPE_FLAGS (rtype) |= TYPE_FLAG_FIXED_INSTANCE; */ + + off = 0; + bit_len = 0; + for (f = 0; f < nfields; f += 1) + { + int fld_bit_len, bit_incr; + off = + align_value (off, + field_alignment (type, f)) + TYPE_FIELD_BITPOS (type, f); + /* NOTE: used to use field_offset above, but that causes + * problems with really negative bit positions. So, let's + * rediscover why we needed field_offset and fix it properly. */ + TYPE_FIELD_BITPOS (rtype, f) = off; + TYPE_FIELD_BITSIZE (rtype, f) = 0; + TYPE_FIELD_STATIC_KIND (rtype, f) = 0; + + if (ada_is_variant_part (type, f)) + { + struct type *branch_type; + + if (dval0 == NULL) + dval = value_from_contents_and_address (rtype, valaddr, address); + else + dval = dval0; + + branch_type = + to_fixed_variant_branch_type + (TYPE_FIELD_TYPE (type, f), + cond_offset_host (valaddr, off / TARGET_CHAR_BIT), + cond_offset_target (address, off / TARGET_CHAR_BIT), dval); + if (branch_type == NULL) + TYPE_NFIELDS (rtype) -= 1; + else + { + TYPE_FIELD_TYPE (rtype, f) = branch_type; + TYPE_FIELD_NAME (rtype, f) = "S"; + } + bit_incr = 0; + fld_bit_len = + TYPE_LENGTH (TYPE_FIELD_TYPE (rtype, f)) * TARGET_CHAR_BIT; + } + else if (is_dynamic_field (type, f)) + { + if (dval0 == NULL) + dval = value_from_contents_and_address (rtype, valaddr, address); + else + dval = dval0; + + TYPE_FIELD_TYPE (rtype, f) = + ada_to_fixed_type + (ada_get_base_type + (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, f))), + cond_offset_host (valaddr, off / TARGET_CHAR_BIT), + cond_offset_target (address, off / TARGET_CHAR_BIT), dval); + TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f); + bit_incr = fld_bit_len = + TYPE_LENGTH (TYPE_FIELD_TYPE (rtype, f)) * TARGET_CHAR_BIT; + } + else + { + TYPE_FIELD_TYPE (rtype, f) = TYPE_FIELD_TYPE (type, f); + TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f); + if (TYPE_FIELD_BITSIZE (type, f) > 0) + bit_incr = fld_bit_len = + TYPE_FIELD_BITSIZE (rtype, f) = TYPE_FIELD_BITSIZE (type, f); + else + bit_incr = fld_bit_len = + TYPE_LENGTH (TYPE_FIELD_TYPE (type, f)) * TARGET_CHAR_BIT; + } + if (off + fld_bit_len > bit_len) + bit_len = off + fld_bit_len; + off += bit_incr; + TYPE_LENGTH (rtype) = bit_len / TARGET_CHAR_BIT; + } + TYPE_LENGTH (rtype) = align_value (TYPE_LENGTH (rtype), TYPE_LENGTH (type)); + + value_free_to_mark (mark); + if (TYPE_LENGTH (rtype) > varsize_limit) + error ("record type with dynamic size is larger than varsize-limit"); + return rtype; +} + +/* As for template_to_fixed_record_type, but uses no run-time values. + As a result, this type can only be approximate, but that's OK, + since it is used only for type determinations. Works on both + structs and unions. + Representation note: to save space, we memoize the result of this + function in the TYPE_TARGET_TYPE of the template type. */ + +static struct type * +template_to_static_fixed_type (struct type *templ_type) +{ + struct type *type; + int nfields; + int f; + + if (TYPE_TARGET_TYPE (templ_type) != NULL) + return TYPE_TARGET_TYPE (templ_type); + + nfields = TYPE_NFIELDS (templ_type); + TYPE_TARGET_TYPE (templ_type) = type = + alloc_type (TYPE_OBJFILE (templ_type)); + TYPE_CODE (type) = TYPE_CODE (templ_type); + INIT_CPLUS_SPECIFIC (type); + TYPE_NFIELDS (type) = nfields; + TYPE_FIELDS (type) = (struct field *) + TYPE_ALLOC (type, nfields * sizeof (struct field)); + memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields); + TYPE_NAME (type) = ada_type_name (templ_type); + TYPE_TAG_NAME (type) = NULL; + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* TYPE_FLAGS (type) |= TYPE_FLAG_FIXED_INSTANCE; */ + TYPE_LENGTH (type) = 0; + + for (f = 0; f < nfields; f += 1) + { + TYPE_FIELD_BITPOS (type, f) = 0; + TYPE_FIELD_BITSIZE (type, f) = 0; + TYPE_FIELD_STATIC_KIND (type, f) = 0; + + if (is_dynamic_field (templ_type, f)) + { + TYPE_FIELD_TYPE (type, f) = + to_static_fixed_type (TYPE_TARGET_TYPE + (TYPE_FIELD_TYPE (templ_type, f))); + TYPE_FIELD_NAME (type, f) = TYPE_FIELD_NAME (templ_type, f); + } + else + { + TYPE_FIELD_TYPE (type, f) = + check_typedef (TYPE_FIELD_TYPE (templ_type, f)); + TYPE_FIELD_NAME (type, f) = TYPE_FIELD_NAME (templ_type, f); + } + } + + return type; +} + +/* A revision of TYPE0 -- a non-dynamic-sized record with a variant + part -- in which the variant part is replaced with the appropriate + branch. */ +static struct type * +to_record_with_fixed_variant_part (struct type *type, char *valaddr, + CORE_ADDR address, struct value *dval) +{ + struct value *mark = value_mark (); + struct type *rtype; + struct type *branch_type; + int nfields = TYPE_NFIELDS (type); + + if (dval == NULL) + return type; + + rtype = alloc_type (TYPE_OBJFILE (type)); + TYPE_CODE (rtype) = TYPE_CODE_STRUCT; + INIT_CPLUS_SPECIFIC (type); + TYPE_NFIELDS (rtype) = TYPE_NFIELDS (type); + TYPE_FIELDS (rtype) = + (struct field *) TYPE_ALLOC (rtype, nfields * sizeof (struct field)); + memcpy (TYPE_FIELDS (rtype), TYPE_FIELDS (type), + sizeof (struct field) * nfields); + TYPE_NAME (rtype) = ada_type_name (type); + TYPE_TAG_NAME (rtype) = NULL; + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* TYPE_FLAGS (rtype) |= TYPE_FLAG_FIXED_INSTANCE; */ + TYPE_LENGTH (rtype) = TYPE_LENGTH (type); + + branch_type = + to_fixed_variant_branch_type + (TYPE_FIELD_TYPE (type, nfields - 1), + cond_offset_host (valaddr, + TYPE_FIELD_BITPOS (type, + nfields - 1) / TARGET_CHAR_BIT), + cond_offset_target (address, + TYPE_FIELD_BITPOS (type, + nfields - 1) / TARGET_CHAR_BIT), + dval); + if (branch_type == NULL) + { + TYPE_NFIELDS (rtype) -= 1; + TYPE_LENGTH (rtype) -= + TYPE_LENGTH (TYPE_FIELD_TYPE (type, nfields - 1)); + } + else + { + TYPE_FIELD_TYPE (rtype, nfields - 1) = branch_type; + TYPE_FIELD_NAME (rtype, nfields - 1) = "S"; + TYPE_FIELD_BITSIZE (rtype, nfields - 1) = 0; + TYPE_FIELD_STATIC_KIND (rtype, nfields - 1) = 0; + TYPE_LENGTH (rtype) += TYPE_LENGTH (branch_type); + -TYPE_LENGTH (TYPE_FIELD_TYPE (type, nfields - 1)); + } + + return rtype; +} + +/* An ordinary record type (with fixed-length fields) that describes + the value at (TYPE0, VALADDR, ADDRESS) [see explanation at + beginning of this section]. Any necessary discriminants' values + should be in DVAL, a record value; it should be NULL if the object + at ADDR itself contains any necessary discriminant values. A + variant field (unless unchecked) is replaced by a particular branch + of the variant. */ + +static struct type * +to_fixed_record_type (struct type *type0, char *valaddr, CORE_ADDR address, + struct value *dval) +{ + struct type *templ_type; + + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* if (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE) + return type0; + */ + templ_type = dynamic_template_type (type0); + + if (templ_type != NULL) + return template_to_fixed_record_type (templ_type, valaddr, address, dval); + else if (contains_variant_part (type0)) + return to_record_with_fixed_variant_part (type0, valaddr, address, dval); + else + { + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* TYPE_FLAGS (type0) |= TYPE_FLAG_FIXED_INSTANCE; */ + return type0; + } + +} + +/* An ordinary record type (with fixed-length fields) that describes + the value at (VAR_TYPE0, VALADDR, ADDRESS), where VAR_TYPE0 is a + union type. Any necessary discriminants' values should be in DVAL, + a record value. That is, this routine selects the appropriate + branch of the union at ADDR according to the discriminant value + indicated in the union's type name. */ + +static struct type * +to_fixed_variant_branch_type (struct type *var_type0, char *valaddr, + CORE_ADDR address, struct value *dval) +{ + int which; + struct type *templ_type; + struct type *var_type; + + if (TYPE_CODE (var_type0) == TYPE_CODE_PTR) + var_type = TYPE_TARGET_TYPE (var_type0); + else + var_type = var_type0; + + templ_type = ada_find_parallel_type (var_type, "___XVU"); + + if (templ_type != NULL) + var_type = templ_type; + + which = + ada_which_variant_applies (var_type, + VALUE_TYPE (dval), VALUE_CONTENTS (dval)); + + if (which < 0) + return empty_record (TYPE_OBJFILE (var_type)); + else if (is_dynamic_field (var_type, which)) + return + to_fixed_record_type + (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (var_type, which)), + valaddr, address, dval); + else if (contains_variant_part (TYPE_FIELD_TYPE (var_type, which))) + return + to_fixed_record_type + (TYPE_FIELD_TYPE (var_type, which), valaddr, address, dval); + else + return TYPE_FIELD_TYPE (var_type, which); +} + +/* Assuming that TYPE0 is an array type describing the type of a value + at ADDR, and that DVAL describes a record containing any + discriminants used in TYPE0, returns a type for the value that + contains no dynamic components (that is, no components whose sizes + are determined by run-time quantities). Unless IGNORE_TOO_BIG is + true, gives an error message if the resulting type's size is over + varsize_limit. +*/ + +static struct type * +to_fixed_array_type (struct type *type0, struct value *dval, + int ignore_too_big) +{ + struct type *index_type_desc; + struct type *result; + + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ +/* if (ada_is_packed_array_type (type0) /* revisit? *//* + || (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE)) + return type0; */ + + index_type_desc = ada_find_parallel_type (type0, "___XA"); + if (index_type_desc == NULL) + { + struct type *elt_type0 = check_typedef (TYPE_TARGET_TYPE (type0)); + /* NOTE: elt_type---the fixed version of elt_type0---should never + * depend on the contents of the array in properly constructed + * debugging data. */ + struct type *elt_type = ada_to_fixed_type (elt_type0, 0, 0, dval); + + if (elt_type0 == elt_type) + result = type0; + else + result = create_array_type (alloc_type (TYPE_OBJFILE (type0)), + elt_type, TYPE_INDEX_TYPE (type0)); + } + else + { + int i; + struct type *elt_type0; + + elt_type0 = type0; + for (i = TYPE_NFIELDS (index_type_desc); i > 0; i -= 1) + elt_type0 = TYPE_TARGET_TYPE (elt_type0); + + /* NOTE: result---the fixed version of elt_type0---should never + * depend on the contents of the array in properly constructed + * debugging data. */ + result = ada_to_fixed_type (check_typedef (elt_type0), 0, 0, dval); + for (i = TYPE_NFIELDS (index_type_desc) - 1; i >= 0; i -= 1) + { + struct type *range_type = + to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, i), + dval, TYPE_OBJFILE (type0)); + result = create_array_type (alloc_type (TYPE_OBJFILE (type0)), + result, range_type); + } + if (!ignore_too_big && TYPE_LENGTH (result) > varsize_limit) + error ("array type with dynamic size is larger than varsize-limit"); + } + +/* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ +/* TYPE_FLAGS (result) |= TYPE_FLAG_FIXED_INSTANCE; */ + return result; +} + + +/* A standard type (containing no dynamically sized components) + corresponding to TYPE for the value (TYPE, VALADDR, ADDRESS) + DVAL describes a record containing any discriminants used in TYPE0, + and may be NULL if there are none. */ + +struct type * +ada_to_fixed_type (struct type *type, char *valaddr, CORE_ADDR address, + struct value *dval) +{ + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) + { + default: + return type; + case TYPE_CODE_STRUCT: + return to_fixed_record_type (type, valaddr, address, NULL); + case TYPE_CODE_ARRAY: + return to_fixed_array_type (type, dval, 0); + case TYPE_CODE_UNION: + if (dval == NULL) + return type; + else + return to_fixed_variant_branch_type (type, valaddr, address, dval); + } +} + +/* A standard (static-sized) type corresponding as well as possible to + TYPE0, but based on no runtime data. */ + +static struct type * +to_static_fixed_type (struct type *type0) +{ + struct type *type; + + if (type0 == NULL) + return NULL; + + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* if (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE) + return type0; + */ + CHECK_TYPEDEF (type0); + + switch (TYPE_CODE (type0)) + { + default: + return type0; + case TYPE_CODE_STRUCT: + type = dynamic_template_type (type0); + if (type != NULL) + return template_to_static_fixed_type (type); + return type0; + case TYPE_CODE_UNION: + type = ada_find_parallel_type (type0, "___XVU"); + if (type != NULL) + return template_to_static_fixed_type (type); + return type0; + } +} + +/* A static approximation of TYPE with all type wrappers removed. */ +static struct type * +static_unwrap_type (struct type *type) +{ + if (ada_is_aligner_type (type)) + { + struct type *type1 = TYPE_FIELD_TYPE (check_typedef (type), 0); + if (ada_type_name (type1) == NULL) + TYPE_NAME (type1) = ada_type_name (type); + + return static_unwrap_type (type1); + } + else + { + struct type *raw_real_type = ada_get_base_type (type); + if (raw_real_type == type) + return type; + else + return to_static_fixed_type (raw_real_type); + } +} + +/* In some cases, incomplete and private types require + cross-references that are not resolved as records (for example, + type Foo; + type FooP is access Foo; + V: FooP; + type Foo is array ...; + ). In these cases, since there is no mechanism for producing + cross-references to such types, we instead substitute for FooP a + stub enumeration type that is nowhere resolved, and whose tag is + the name of the actual type. Call these types "non-record stubs". */ + +/* A type equivalent to TYPE that is not a non-record stub, if one + exists, otherwise TYPE. */ +struct type * +ada_completed_type (struct type *type) +{ + CHECK_TYPEDEF (type); + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM + || (TYPE_FLAGS (type) & TYPE_FLAG_STUB) == 0 + || TYPE_TAG_NAME (type) == NULL) + return type; + else + { + char *name = TYPE_TAG_NAME (type); + struct type *type1 = ada_find_any_type (name); + return (type1 == NULL) ? type : type1; + } +} + +/* A value representing the data at VALADDR/ADDRESS as described by + type TYPE0, but with a standard (static-sized) type that correctly + describes it. If VAL0 is not NULL and TYPE0 already is a standard + type, then return VAL0 [this feature is simply to avoid redundant + creation of struct values]. */ + +struct value * +ada_to_fixed_value (struct type *type0, char *valaddr, CORE_ADDR address, + struct value *val0) +{ + struct type *type = ada_to_fixed_type (type0, valaddr, address, NULL); + if (type == type0 && val0 != NULL) + return val0; + else + return value_from_contents_and_address (type, valaddr, address); +} + +/* A value representing VAL, but with a standard (static-sized) type + chosen to approximate the real type of VAL as well as possible, but + without consulting any runtime values. For Ada dynamic-sized + types, therefore, the type of the result is likely to be inaccurate. */ + +struct value * +ada_to_static_fixed_value (struct value *val) +{ + struct type *type = + to_static_fixed_type (static_unwrap_type (VALUE_TYPE (val))); + if (type == VALUE_TYPE (val)) + return val; + else + return coerce_unspec_val_to_type (val, 0, type); +} + + + + + +/* Attributes */ + +/* Table mapping attribute numbers to names */ +/* NOTE: Keep up to date with enum ada_attribute definition in ada-lang.h */ + +static const char *attribute_names[] = { + "", + + "first", + "last", + "length", + "image", + "img", + "max", + "min", + "pos" "tag", + "val", + + 0 +}; + +const char * +ada_attribute_name (int n) +{ + if (n > 0 && n < (int) ATR_END) + return attribute_names[n]; + else + return attribute_names[0]; +} + +/* Evaluate the 'POS attribute applied to ARG. */ + +static struct value * +value_pos_atr (struct value *arg) +{ + struct type *type = VALUE_TYPE (arg); + + if (!discrete_type_p (type)) + error ("'POS only defined on discrete types"); + + if (TYPE_CODE (type) == TYPE_CODE_ENUM) + { + int i; + LONGEST v = value_as_long (arg); + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + { + if (v == TYPE_FIELD_BITPOS (type, i)) + return value_from_longest (builtin_type_ada_int, i); + } + error ("enumeration value is invalid: can't find 'POS"); + } + else + return value_from_longest (builtin_type_ada_int, value_as_long (arg)); +} + +/* Evaluate the TYPE'VAL attribute applied to ARG. */ + +static struct value * +value_val_atr (struct type *type, struct value *arg) +{ + if (!discrete_type_p (type)) + error ("'VAL only defined on discrete types"); + if (!integer_type_p (VALUE_TYPE (arg))) + error ("'VAL requires integral argument"); + + if (TYPE_CODE (type) == TYPE_CODE_ENUM) + { + long pos = value_as_long (arg); + if (pos < 0 || pos >= TYPE_NFIELDS (type)) + error ("argument to 'VAL out of range"); + return value_from_longest (type, TYPE_FIELD_BITPOS (type, pos)); + } + else + return value_from_longest (type, value_as_long (arg)); +} + + + /* Evaluation */ + +/* True if TYPE appears to be an Ada character type. + * [At the moment, this is true only for Character and Wide_Character; + * It is a heuristic test that could stand improvement]. */ + +int +ada_is_character_type (struct type *type) +{ + const char *name = ada_type_name (type); + return + name != NULL + && (TYPE_CODE (type) == TYPE_CODE_CHAR + || TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_RANGE) + && (DEPRECATED_STREQ (name, "character") || DEPRECATED_STREQ (name, "wide_character") + || DEPRECATED_STREQ (name, "unsigned char")); +} + +/* True if TYPE appears to be an Ada string type. */ + +int +ada_is_string_type (struct type *type) +{ + CHECK_TYPEDEF (type); + if (type != NULL + && TYPE_CODE (type) != TYPE_CODE_PTR + && (ada_is_simple_array (type) || ada_is_array_descriptor (type)) + && ada_array_arity (type) == 1) + { + struct type *elttype = ada_array_element_type (type, 1); + + return ada_is_character_type (elttype); + } + else + return 0; +} + + +/* True if TYPE is a struct type introduced by the compiler to force the + alignment of a value. Such types have a single field with a + distinctive name. */ + +int +ada_is_aligner_type (struct type *type) +{ + CHECK_TYPEDEF (type); + return (TYPE_CODE (type) == TYPE_CODE_STRUCT + && TYPE_NFIELDS (type) == 1 + && DEPRECATED_STREQ (TYPE_FIELD_NAME (type, 0), "F")); +} + +/* If there is an ___XVS-convention type parallel to SUBTYPE, return + the parallel type. */ + +struct type * +ada_get_base_type (struct type *raw_type) +{ + struct type *real_type_namer; + struct type *raw_real_type; + struct type *real_type; + + if (raw_type == NULL || TYPE_CODE (raw_type) != TYPE_CODE_STRUCT) + return raw_type; + + real_type_namer = ada_find_parallel_type (raw_type, "___XVS"); + if (real_type_namer == NULL + || TYPE_CODE (real_type_namer) != TYPE_CODE_STRUCT + || TYPE_NFIELDS (real_type_namer) != 1) + return raw_type; + + raw_real_type = ada_find_any_type (TYPE_FIELD_NAME (real_type_namer, 0)); + if (raw_real_type == NULL) + return raw_type; + else + return raw_real_type; +} + +/* The type of value designated by TYPE, with all aligners removed. */ + +struct type * +ada_aligned_type (struct type *type) +{ + if (ada_is_aligner_type (type)) + return ada_aligned_type (TYPE_FIELD_TYPE (type, 0)); + else + return ada_get_base_type (type); +} + + +/* The address of the aligned value in an object at address VALADDR + having type TYPE. Assumes ada_is_aligner_type (TYPE). */ + +char * +ada_aligned_value_addr (struct type *type, char *valaddr) +{ + if (ada_is_aligner_type (type)) + return ada_aligned_value_addr (TYPE_FIELD_TYPE (type, 0), + valaddr + + TYPE_FIELD_BITPOS (type, + 0) / TARGET_CHAR_BIT); + else + return valaddr; +} + +/* The printed representation of an enumeration literal with encoded + name NAME. The value is good to the next call of ada_enum_name. */ +const char * +ada_enum_name (const char *name) +{ + char *tmp; + + while (1) + { + if ((tmp = strstr (name, "__")) != NULL) + name = tmp + 2; + else if ((tmp = strchr (name, '.')) != NULL) + name = tmp + 1; + else + break; + } + + if (name[0] == 'Q') + { + static char result[16]; + int v; + if (name[1] == 'U' || name[1] == 'W') + { + if (sscanf (name + 2, "%x", &v) != 1) + return name; + } + else + return name; + + if (isascii (v) && isprint (v)) + sprintf (result, "'%c'", v); + else if (name[1] == 'U') + sprintf (result, "[\"%02x\"]", v); + else + sprintf (result, "[\"%04x\"]", v); + + return result; + } + else + return name; +} + +static struct value * +evaluate_subexp (struct type *expect_type, struct expression *exp, int *pos, + enum noside noside) +{ + return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside); +} + +/* Evaluate the subexpression of EXP starting at *POS as for + evaluate_type, updating *POS to point just past the evaluated + expression. */ + +static struct value * +evaluate_subexp_type (struct expression *exp, int *pos) +{ + return (*exp->language_defn->evaluate_exp) + (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); +} + +/* If VAL is wrapped in an aligner or subtype wrapper, return the + value it wraps. */ + +static struct value * +unwrap_value (struct value *val) +{ + struct type *type = check_typedef (VALUE_TYPE (val)); + if (ada_is_aligner_type (type)) + { + struct value *v = value_struct_elt (&val, NULL, "F", + NULL, "internal structure"); + struct type *val_type = check_typedef (VALUE_TYPE (v)); + if (ada_type_name (val_type) == NULL) + TYPE_NAME (val_type) = ada_type_name (type); + + return unwrap_value (v); + } + else + { + struct type *raw_real_type = + ada_completed_type (ada_get_base_type (type)); + + if (type == raw_real_type) + return val; + + return + coerce_unspec_val_to_type + (val, 0, ada_to_fixed_type (raw_real_type, 0, + VALUE_ADDRESS (val) + VALUE_OFFSET (val), + NULL)); + } +} + +static struct value * +cast_to_fixed (struct type *type, struct value *arg) +{ + LONGEST val; + + if (type == VALUE_TYPE (arg)) + return arg; + else if (ada_is_fixed_point_type (VALUE_TYPE (arg))) + val = ada_float_to_fixed (type, + ada_fixed_to_float (VALUE_TYPE (arg), + value_as_long (arg))); + else + { + DOUBLEST argd = + value_as_double (value_cast (builtin_type_double, value_copy (arg))); + val = ada_float_to_fixed (type, argd); + } + + return value_from_longest (type, val); +} + +static struct value * +cast_from_fixed_to_double (struct value *arg) +{ + DOUBLEST val = ada_fixed_to_float (VALUE_TYPE (arg), + value_as_long (arg)); + return value_from_double (builtin_type_double, val); +} + +/* Coerce VAL as necessary for assignment to an lval of type TYPE, and + * return the converted value. */ +static struct value * +coerce_for_assign (struct type *type, struct value *val) +{ + struct type *type2 = VALUE_TYPE (val); + if (type == type2) + return val; + + CHECK_TYPEDEF (type2); + CHECK_TYPEDEF (type); + + if (TYPE_CODE (type2) == TYPE_CODE_PTR + && TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + val = ada_value_ind (val); + type2 = VALUE_TYPE (val); + } + + if (TYPE_CODE (type2) == TYPE_CODE_ARRAY + && TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + if (TYPE_LENGTH (type2) != TYPE_LENGTH (type) + || TYPE_LENGTH (TYPE_TARGET_TYPE (type2)) + != TYPE_LENGTH (TYPE_TARGET_TYPE (type2))) + error ("Incompatible types in assignment"); + VALUE_TYPE (val) = type; + } + return val; +} + +struct value * +ada_evaluate_subexp (struct type *expect_type, struct expression *exp, + int *pos, enum noside noside) +{ + enum exp_opcode op; + enum ada_attribute atr; + int tem, tem2, tem3; + int pc; + struct value *arg1 = NULL, *arg2 = NULL, *arg3; + struct type *type; + int nargs; + struct value **argvec; + + pc = *pos; + *pos += 1; + op = exp->elts[pc].opcode; + + switch (op) + { + default: + *pos -= 1; + return + unwrap_value (evaluate_subexp_standard + (expect_type, exp, pos, noside)); + + case UNOP_CAST: + (*pos) += 2; + type = exp->elts[pc + 1].type; + arg1 = evaluate_subexp (type, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (type != check_typedef (VALUE_TYPE (arg1))) + { + if (ada_is_fixed_point_type (type)) + arg1 = cast_to_fixed (type, arg1); + else if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + arg1 = value_cast (type, cast_from_fixed_to_double (arg1)); + else if (VALUE_LVAL (arg1) == lval_memory) + { + /* This is in case of the really obscure (and undocumented, + but apparently expected) case of (Foo) Bar.all, where Bar + is an integer constant and Foo is a dynamic-sized type. + If we don't do this, ARG1 will simply be relabeled with + TYPE. */ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (to_static_fixed_type (type), not_lval); + arg1 = + ada_to_fixed_value + (type, 0, VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1), 0); + } + else + arg1 = value_cast (type, arg1); + } + return arg1; + + /* FIXME: UNOP_QUAL should be defined in expression.h */ + /* case UNOP_QUAL: + (*pos) += 2; + type = exp->elts[pc + 1].type; + return ada_evaluate_subexp (type, exp, pos, noside); + */ + case BINOP_ASSIGN: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); + if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) + return arg1; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + { + if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + arg2 = cast_to_fixed (VALUE_TYPE (arg1), arg2); + else if (ada_is_fixed_point_type (VALUE_TYPE (arg2))) + error + ("Fixed-point values must be assigned to fixed-point variables"); + else + arg2 = coerce_for_assign (VALUE_TYPE (arg1), arg2); + return ada_value_assign (arg1, arg2); + } + + case BINOP_ADD: + arg1 = evaluate_subexp_with_coercion (exp, pos, noside); + arg2 = evaluate_subexp_with_coercion (exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + { + if ((ada_is_fixed_point_type (VALUE_TYPE (arg1)) + || ada_is_fixed_point_type (VALUE_TYPE (arg2))) + && VALUE_TYPE (arg1) != VALUE_TYPE (arg2)) + error + ("Operands of fixed-point addition must have the same type"); + return value_cast (VALUE_TYPE (arg1), value_add (arg1, arg2)); + } + + case BINOP_SUB: + arg1 = evaluate_subexp_with_coercion (exp, pos, noside); + arg2 = evaluate_subexp_with_coercion (exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + { + if ((ada_is_fixed_point_type (VALUE_TYPE (arg1)) + || ada_is_fixed_point_type (VALUE_TYPE (arg2))) + && VALUE_TYPE (arg1) != VALUE_TYPE (arg2)) + error + ("Operands of fixed-point subtraction must have the same type"); + return value_cast (VALUE_TYPE (arg1), value_sub (arg1, arg2)); + } + + case BINOP_MUL: + case BINOP_DIV: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + if (noside == EVAL_AVOID_SIDE_EFFECTS + && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD)) + return value_zero (VALUE_TYPE (arg1), not_lval); + else + { + if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + arg1 = cast_from_fixed_to_double (arg1); + if (ada_is_fixed_point_type (VALUE_TYPE (arg2))) + arg2 = cast_from_fixed_to_double (arg2); + return value_binop (arg1, arg2, op); + } + + case UNOP_NEG: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (unop_user_defined_p (op, arg1)) + return value_x_unop (arg1, op, EVAL_NORMAL); + else if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + return value_cast (VALUE_TYPE (arg1), value_neg (arg1)); + else + return value_neg (arg1); + + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* case OP_UNRESOLVED_VALUE: + /* Only encountered when an unresolved symbol occurs in a + context other than a function call, in which case, it is + illegal. *//* + (*pos) += 3; + if (noside == EVAL_SKIP) + goto nosideret; + else + error ("Unexpected unresolved symbol, %s, during evaluation", + ada_demangle (exp->elts[pc + 2].name)); + */ + case OP_VAR_VALUE: + *pos -= 1; + if (noside == EVAL_SKIP) + { + *pos += 4; + goto nosideret; + } + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + *pos += 4; + return value_zero + (to_static_fixed_type + (static_unwrap_type (SYMBOL_TYPE (exp->elts[pc + 2].symbol))), + not_lval); + } + else + { + arg1 = + unwrap_value (evaluate_subexp_standard + (expect_type, exp, pos, noside)); + return ada_to_fixed_value (VALUE_TYPE (arg1), 0, + VALUE_ADDRESS (arg1) + + VALUE_OFFSET (arg1), arg1); + } + + case OP_ARRAY: + (*pos) += 3; + tem2 = longest_to_int (exp->elts[pc + 1].longconst); + tem3 = longest_to_int (exp->elts[pc + 2].longconst); + nargs = tem3 - tem2 + 1; + type = expect_type ? check_typedef (expect_type) : NULL_TYPE; + + argvec = + (struct value * *) alloca (sizeof (struct value *) * (nargs + 1)); + for (tem = 0; tem == 0 || tem < nargs; tem += 1) + /* At least one element gets inserted for the type */ + { + /* Ensure that array expressions are coerced into pointer objects. */ + argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); + } + if (noside == EVAL_SKIP) + goto nosideret; + return value_array (tem2, tem3, argvec); + + case OP_FUNCALL: + (*pos) += 2; + + /* Allocate arg vector, including space for the function to be + called in argvec[0] and a terminating NULL */ + nargs = longest_to_int (exp->elts[pc + 1].longconst); + argvec = + (struct value * *) alloca (sizeof (struct value *) * (nargs + 2)); + + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* FIXME: name should be defined in expresion.h */ + /* if (exp->elts[*pos].opcode == OP_UNRESOLVED_VALUE) + error ("Unexpected unresolved symbol, %s, during evaluation", + ada_demangle (exp->elts[pc + 5].name)); + */ + if (0) + { + error ("unexpected code path, FIXME"); + } + else + { + for (tem = 0; tem <= nargs; tem += 1) + argvec[tem] = evaluate_subexp (NULL_TYPE, exp, pos, noside); + argvec[tem] = 0; + + if (noside == EVAL_SKIP) + goto nosideret; + } + + if (TYPE_CODE (VALUE_TYPE (argvec[0])) == TYPE_CODE_REF) + argvec[0] = value_addr (argvec[0]); + + if (ada_is_packed_array_type (VALUE_TYPE (argvec[0]))) + argvec[0] = ada_coerce_to_simple_array (argvec[0]); + + type = check_typedef (VALUE_TYPE (argvec[0])); + if (TYPE_CODE (type) == TYPE_CODE_PTR) + { + switch (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (type)))) + { + case TYPE_CODE_FUNC: + type = check_typedef (TYPE_TARGET_TYPE (type)); + break; + case TYPE_CODE_ARRAY: + break; + case TYPE_CODE_STRUCT: + if (noside != EVAL_AVOID_SIDE_EFFECTS) + argvec[0] = ada_value_ind (argvec[0]); + type = check_typedef (TYPE_TARGET_TYPE (type)); + break; + default: + error ("cannot subscript or call something of type `%s'", + ada_type_name (VALUE_TYPE (argvec[0]))); + break; + } + } + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_FUNC: + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return allocate_value (TYPE_TARGET_TYPE (type)); + return call_function_by_hand (argvec[0], nargs, argvec + 1); + case TYPE_CODE_STRUCT: + { + int arity = ada_array_arity (type); + type = ada_array_element_type (type, nargs); + if (type == NULL) + error ("cannot subscript or call a record"); + if (arity != nargs) + error ("wrong number of subscripts; expecting %d", arity); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return allocate_value (ada_aligned_type (type)); + return + unwrap_value (ada_value_subscript + (argvec[0], nargs, argvec + 1)); + } + case TYPE_CODE_ARRAY: + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_array_element_type (type, nargs); + if (type == NULL) + error ("element type of array unknown"); + else + return allocate_value (ada_aligned_type (type)); + } + return + unwrap_value (ada_value_subscript + (ada_coerce_to_simple_array (argvec[0]), + nargs, argvec + 1)); + case TYPE_CODE_PTR: /* Pointer to array */ + type = to_fixed_array_type (TYPE_TARGET_TYPE (type), NULL, 1); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_array_element_type (type, nargs); + if (type == NULL) + error ("element type of array unknown"); + else + return allocate_value (ada_aligned_type (type)); + } + return + unwrap_value (ada_value_ptr_subscript (argvec[0], type, + nargs, argvec + 1)); + + default: + error ("Internal error in evaluate_subexp"); + } + + case TERNOP_SLICE: + { + struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside); + int lowbound + = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); + int upper + = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); + if (noside == EVAL_SKIP) + goto nosideret; + + /* If this is a reference to an array, then dereference it */ + if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_REF + && TYPE_TARGET_TYPE (VALUE_TYPE (array)) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (array))) == + TYPE_CODE_ARRAY + && !ada_is_array_descriptor (check_typedef (VALUE_TYPE (array)))) + { + array = ada_coerce_ref (array); + } + + if (noside == EVAL_AVOID_SIDE_EFFECTS && + ada_is_array_descriptor (check_typedef (VALUE_TYPE (array)))) + { + /* Try to dereference the array, in case it is an access to array */ + struct type *arrType = ada_type_of_array (array, 0); + if (arrType != NULL) + array = value_at_lazy (arrType, 0, NULL); + } + if (ada_is_array_descriptor (VALUE_TYPE (array))) + array = ada_coerce_to_simple_array (array); + + /* If at this point we have a pointer to an array, it means that + it is a pointer to a simple (non-ada) array. We just then + dereference it */ + if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_PTR + && TYPE_TARGET_TYPE (VALUE_TYPE (array)) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (array))) == + TYPE_CODE_ARRAY) + { + array = ada_value_ind (array); + } + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + /* The following will get the bounds wrong, but only in contexts + where the value is not being requested (FIXME?). */ + return array; + else + return value_slice (array, lowbound, upper - lowbound + 1); + } + + /* FIXME: UNOP_MBR should be defined in expression.h */ + /* case UNOP_MBR: + (*pos) += 2; + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + type = exp->elts[pc + 1].type; + + if (noside == EVAL_SKIP) + goto nosideret; + + switch (TYPE_CODE (type)) + { + default: + warning ("Membership test incompletely implemented; always returns true"); + return value_from_longest (builtin_type_int, (LONGEST) 1); + + case TYPE_CODE_RANGE: + arg2 = value_from_longest (builtin_type_int, + (LONGEST) TYPE_LOW_BOUND (type)); + arg3 = value_from_longest (builtin_type_int, + (LONGEST) TYPE_HIGH_BOUND (type)); + return + value_from_longest (builtin_type_int, + (value_less (arg1,arg3) + || value_equal (arg1,arg3)) + && (value_less (arg2,arg1) + || value_equal (arg2,arg1))); + } + */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + /* case BINOP_MBR: + (*pos) += 2; + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + + if (noside == EVAL_SKIP) + goto nosideret; + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (builtin_type_int, not_lval); + + tem = longest_to_int (exp->elts[pc + 1].longconst); + + if (tem < 1 || tem > ada_array_arity (VALUE_TYPE (arg2))) + error ("invalid dimension number to '%s", "range"); + + arg3 = ada_array_bound (arg2, tem, 1); + arg2 = ada_array_bound (arg2, tem, 0); + + return + value_from_longest (builtin_type_int, + (value_less (arg1,arg3) + || value_equal (arg1,arg3)) + && (value_less (arg2,arg1) + || value_equal (arg2,arg1))); + */ + /* FIXME: TERNOP_MBR should be defined in expression.h */ + /* case TERNOP_MBR: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg3 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + + if (noside == EVAL_SKIP) + goto nosideret; + + return + value_from_longest (builtin_type_int, + (value_less (arg1,arg3) + || value_equal (arg1,arg3)) + && (value_less (arg2,arg1) + || value_equal (arg2,arg1))); + */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + /* case OP_ATTRIBUTE: + *pos += 3; + atr = (enum ada_attribute) longest_to_int (exp->elts[pc + 2].longconst); + switch (atr) + { + default: + error ("unexpected attribute encountered"); + + case ATR_FIRST: + case ATR_LAST: + case ATR_LENGTH: + { + struct type* type_arg; + if (exp->elts[*pos].opcode == OP_TYPE) + { + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = NULL; + type_arg = exp->elts[pc + 5].type; + } + else + { + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + type_arg = NULL; + } + + if (exp->elts[*pos].opcode != OP_LONG) + error ("illegal operand to '%s", ada_attribute_name (atr)); + tem = longest_to_int (exp->elts[*pos+2].longconst); + *pos += 4; + + if (noside == EVAL_SKIP) + goto nosideret; + + if (type_arg == NULL) + { + arg1 = ada_coerce_ref (arg1); + + if (ada_is_packed_array_type (VALUE_TYPE (arg1))) + arg1 = ada_coerce_to_simple_array (arg1); + + if (tem < 1 || tem > ada_array_arity (VALUE_TYPE (arg1))) + error ("invalid dimension number to '%s", + ada_attribute_name (atr)); + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_index_type (VALUE_TYPE (arg1), tem); + if (type == NULL) + error ("attempt to take bound of something that is not an array"); + return allocate_value (type); + } + + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + return ada_array_bound (arg1, tem, 0); + case ATR_LAST: + return ada_array_bound (arg1, tem, 1); + case ATR_LENGTH: + return ada_array_length (arg1, tem); + } + } + else if (TYPE_CODE (type_arg) == TYPE_CODE_RANGE + || TYPE_CODE (type_arg) == TYPE_CODE_INT) + { + struct type* range_type; + char* name = ada_type_name (type_arg); + if (name == NULL) + { + if (TYPE_CODE (type_arg) == TYPE_CODE_RANGE) + range_type = type_arg; + else + error ("unimplemented type attribute"); + } + else + range_type = + to_fixed_range_type (name, NULL, TYPE_OBJFILE (type_arg)); + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + return value_from_longest (TYPE_TARGET_TYPE (range_type), + TYPE_LOW_BOUND (range_type)); + case ATR_LAST: + return value_from_longest (TYPE_TARGET_TYPE (range_type), + TYPE_HIGH_BOUND (range_type)); + } + } + else if (TYPE_CODE (type_arg) == TYPE_CODE_ENUM) + { + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + return value_from_longest + (type_arg, TYPE_FIELD_BITPOS (type_arg, 0)); + case ATR_LAST: + return value_from_longest + (type_arg, + TYPE_FIELD_BITPOS (type_arg, + TYPE_NFIELDS (type_arg) - 1)); + } + } + else if (TYPE_CODE (type_arg) == TYPE_CODE_FLT) + error ("unimplemented type attribute"); + else + { + LONGEST low, high; + + if (ada_is_packed_array_type (type_arg)) + type_arg = decode_packed_array_type (type_arg); + + if (tem < 1 || tem > ada_array_arity (type_arg)) + error ("invalid dimension number to '%s", + ada_attribute_name (atr)); + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_index_type (type_arg, tem); + if (type == NULL) + error ("attempt to take bound of something that is not an array"); + return allocate_value (type); + } + + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + low = ada_array_bound_from_type (type_arg, tem, 0, &type); + return value_from_longest (type, low); + case ATR_LAST: + high = ada_array_bound_from_type (type_arg, tem, 1, &type); + return value_from_longest (type, high); + case ATR_LENGTH: + low = ada_array_bound_from_type (type_arg, tem, 0, &type); + high = ada_array_bound_from_type (type_arg, tem, 1, NULL); + return value_from_longest (type, high-low+1); + } + } + } + + case ATR_TAG: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return + value_zero (ada_tag_type (arg1), not_lval); + + return ada_value_tag (arg1); + + case ATR_MIN: + case ATR_MAX: + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (VALUE_TYPE (arg1), not_lval); + else + return value_binop (arg1, arg2, + atr == ATR_MIN ? BINOP_MIN : BINOP_MAX); + + case ATR_MODULUS: + { + struct type* type_arg = exp->elts[pc + 5].type; + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + *pos += 4; + + if (noside == EVAL_SKIP) + goto nosideret; + + if (! ada_is_modular_type (type_arg)) + error ("'modulus must be applied to modular type"); + + return value_from_longest (TYPE_TARGET_TYPE (type_arg), + ada_modulus (type_arg)); + } + + + case ATR_POS: + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (builtin_type_ada_int, not_lval); + else + return value_pos_atr (arg1); + + case ATR_SIZE: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (builtin_type_ada_int, not_lval); + else + return value_from_longest (builtin_type_ada_int, + TARGET_CHAR_BIT + * TYPE_LENGTH (VALUE_TYPE (arg1))); + + case ATR_VAL: + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + type = exp->elts[pc + 5].type; + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (type, not_lval); + else + return value_val_atr (type, arg1); + } */ + case BINOP_EXP: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return unwrap_value (value_x_binop (arg1, arg2, op, OP_NULL, + EVAL_NORMAL)); + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (VALUE_TYPE (arg1), not_lval); + else + return value_binop (arg1, arg2, op); + + case UNOP_PLUS: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (unop_user_defined_p (op, arg1)) + return unwrap_value (value_x_unop (arg1, op, EVAL_NORMAL)); + else + return arg1; + + case UNOP_ABS: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (value_less (arg1, value_zero (VALUE_TYPE (arg1), not_lval))) + return value_neg (arg1); + else + return arg1; + + case UNOP_IND: + if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR) + expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type)); + arg1 = evaluate_subexp (expect_type, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + type = check_typedef (VALUE_TYPE (arg1)); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + if (ada_is_array_descriptor (type)) + /* GDB allows dereferencing GNAT array descriptors. */ + { + struct type *arrType = ada_type_of_array (arg1, 0); + if (arrType == NULL) + error ("Attempt to dereference null array pointer."); + return value_at_lazy (arrType, 0, NULL); + } + else if (TYPE_CODE (type) == TYPE_CODE_PTR + || TYPE_CODE (type) == TYPE_CODE_REF + /* In C you can dereference an array to get the 1st elt. */ + || TYPE_CODE (type) == TYPE_CODE_ARRAY) + return + value_zero + (to_static_fixed_type + (ada_aligned_type (check_typedef (TYPE_TARGET_TYPE (type)))), + lval_memory); + else if (TYPE_CODE (type) == TYPE_CODE_INT) + /* GDB allows dereferencing an int. */ + return value_zero (builtin_type_int, lval_memory); + else + error ("Attempt to take contents of a non-pointer value."); + } + arg1 = ada_coerce_ref (arg1); + type = check_typedef (VALUE_TYPE (arg1)); + + if (ada_is_array_descriptor (type)) + /* GDB allows dereferencing GNAT array descriptors. */ + return ada_coerce_to_simple_array (arg1); + else + return ada_value_ind (arg1); + + case STRUCTOP_STRUCT: + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (ada_aligned_type + (ada_lookup_struct_elt_type (VALUE_TYPE (arg1), + &exp->elts[pc + + 2].string, + 0, NULL)), + lval_memory); + else + return unwrap_value (ada_value_struct_elt (arg1, + &exp->elts[pc + 2].string, + "record")); + case OP_TYPE: + /* The value is not supposed to be used. This is here to make it + easier to accommodate expressions that contain types. */ + (*pos) += 2; + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return allocate_value (builtin_type_void); + else + error ("Attempt to use a type name as an expression"); + + case STRUCTOP_PTR: + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (ada_aligned_type + (ada_lookup_struct_elt_type (VALUE_TYPE (arg1), + &exp->elts[pc + + 2].string, + 0, NULL)), + lval_memory); + else + return unwrap_value (ada_value_struct_elt (arg1, + &exp->elts[pc + 2].string, + "record access")); + } + +nosideret: + return value_from_longest (builtin_type_long, (LONGEST) 1); +} + + + /* Fixed point */ + +/* If TYPE encodes an Ada fixed-point type, return the suffix of the + type name that encodes the 'small and 'delta information. + Otherwise, return NULL. */ + +static const char * +fixed_type_info (struct type *type) +{ + const char *name = ada_type_name (type); + enum type_code code = (type == NULL) ? TYPE_CODE_UNDEF : TYPE_CODE (type); + + if ((code == TYPE_CODE_INT || code == TYPE_CODE_RANGE) && name != NULL) + { + const char *tail = strstr (name, "___XF_"); + if (tail == NULL) + return NULL; + else + return tail + 5; + } + else if (code == TYPE_CODE_RANGE && TYPE_TARGET_TYPE (type) != type) + return fixed_type_info (TYPE_TARGET_TYPE (type)); + else + return NULL; +} + +/* Returns non-zero iff TYPE represents an Ada fixed-point type. */ + +int +ada_is_fixed_point_type (struct type *type) +{ + return fixed_type_info (type) != NULL; +} + +/* Assuming that TYPE is the representation of an Ada fixed-point + type, return its delta, or -1 if the type is malformed and the + delta cannot be determined. */ + +DOUBLEST +ada_delta (struct type *type) +{ + const char *encoding = fixed_type_info (type); + long num, den; + + if (sscanf (encoding, "_%ld_%ld", &num, &den) < 2) + return -1.0; + else + return (DOUBLEST) num / (DOUBLEST) den; +} + +/* Assuming that ada_is_fixed_point_type (TYPE), return the scaling + factor ('SMALL value) associated with the type. */ + +static DOUBLEST +scaling_factor (struct type *type) +{ + const char *encoding = fixed_type_info (type); + unsigned long num0, den0, num1, den1; + int n; + + n = sscanf (encoding, "_%lu_%lu_%lu_%lu", &num0, &den0, &num1, &den1); + + if (n < 2) + return 1.0; + else if (n == 4) + return (DOUBLEST) num1 / (DOUBLEST) den1; + else + return (DOUBLEST) num0 / (DOUBLEST) den0; +} + + +/* Assuming that X is the representation of a value of fixed-point + type TYPE, return its floating-point equivalent. */ + +DOUBLEST +ada_fixed_to_float (struct type *type, LONGEST x) +{ + return (DOUBLEST) x *scaling_factor (type); +} + +/* The representation of a fixed-point value of type TYPE + corresponding to the value X. */ + +LONGEST +ada_float_to_fixed (struct type *type, DOUBLEST x) +{ + return (LONGEST) (x / scaling_factor (type) + 0.5); +} + + + /* VAX floating formats */ + +/* Non-zero iff TYPE represents one of the special VAX floating-point + types. */ +int +ada_is_vax_floating_type (struct type *type) +{ + int name_len = + (ada_type_name (type) == NULL) ? 0 : strlen (ada_type_name (type)); + return + name_len > 6 + && (TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_RANGE) + && DEPRECATED_STREQN (ada_type_name (type) + name_len - 6, "___XF", 5); +} + +/* The type of special VAX floating-point type this is, assuming + ada_is_vax_floating_point */ +int +ada_vax_float_type_suffix (struct type *type) +{ + return ada_type_name (type)[strlen (ada_type_name (type)) - 1]; +} + +/* A value representing the special debugging function that outputs + VAX floating-point values of the type represented by TYPE. Assumes + ada_is_vax_floating_type (TYPE). */ +struct value * +ada_vax_float_print_function (struct type *type) +{ + switch (ada_vax_float_type_suffix (type)) + { + case 'F': + return get_var_value ("DEBUG_STRING_F", 0); + case 'D': + return get_var_value ("DEBUG_STRING_D", 0); + case 'G': + return get_var_value ("DEBUG_STRING_G", 0); + default: + error ("invalid VAX floating-point type"); + } +} + + + /* Range types */ + +/* Scan STR beginning at position K for a discriminant name, and + return the value of that discriminant field of DVAL in *PX. If + PNEW_K is not null, put the position of the character beyond the + name scanned in *PNEW_K. Return 1 if successful; return 0 and do + not alter *PX and *PNEW_K if unsuccessful. */ + +static int +scan_discrim_bound (char *str, int k, struct value *dval, LONGEST * px, + int *pnew_k) +{ + static char *bound_buffer = NULL; + static size_t bound_buffer_len = 0; + char *bound; + char *pend; + struct value *bound_val; + + if (dval == NULL || str == NULL || str[k] == '\0') + return 0; + + pend = strstr (str + k, "__"); + if (pend == NULL) + { + bound = str + k; + k += strlen (bound); + } + else + { + GROW_VECT (bound_buffer, bound_buffer_len, pend - (str + k) + 1); + bound = bound_buffer; + strncpy (bound_buffer, str + k, pend - (str + k)); + bound[pend - (str + k)] = '\0'; + k = pend - str; + } + + bound_val = ada_search_struct_field (bound, dval, 0, VALUE_TYPE (dval)); + if (bound_val == NULL) + return 0; + + *px = value_as_long (bound_val); + if (pnew_k != NULL) + *pnew_k = k; + return 1; +} + +/* Value of variable named NAME in the current environment. If + no such variable found, then if ERR_MSG is null, returns 0, and + otherwise causes an error with message ERR_MSG. */ +static struct value * +get_var_value (char *name, char *err_msg) +{ + struct symbol **syms; + struct block **blocks; + int nsyms; + + nsyms = + ada_lookup_symbol_list (name, get_selected_block (NULL), VAR_DOMAIN, + &syms, &blocks); + + if (nsyms != 1) + { + if (err_msg == NULL) + return 0; + else + error ("%s", err_msg); + } + + return value_of_variable (syms[0], blocks[0]); +} + +/* Value of integer variable named NAME in the current environment. If + no such variable found, then if ERR_MSG is null, returns 0, and sets + *FLAG to 0. If successful, sets *FLAG to 1. */ +LONGEST +get_int_var_value (char *name, char *err_msg, int *flag) +{ + struct value *var_val = get_var_value (name, err_msg); + + if (var_val == 0) + { + if (flag != NULL) + *flag = 0; + return 0; + } + else + { + if (flag != NULL) + *flag = 1; + return value_as_long (var_val); + } +} + + +/* Return a range type whose base type is that of the range type named + NAME in the current environment, and whose bounds are calculated + from NAME according to the GNAT range encoding conventions. + Extract discriminant values, if needed, from DVAL. If a new type + must be created, allocate in OBJFILE's space. The bounds + information, in general, is encoded in NAME, the base type given in + the named range type. */ + +static struct type * +to_fixed_range_type (char *name, struct value *dval, struct objfile *objfile) +{ + struct type *raw_type = ada_find_any_type (name); + struct type *base_type; + LONGEST low, high; + char *subtype_info; + + if (raw_type == NULL) + base_type = builtin_type_int; + else if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE) + base_type = TYPE_TARGET_TYPE (raw_type); + else + base_type = raw_type; + + subtype_info = strstr (name, "___XD"); + if (subtype_info == NULL) + return raw_type; + else + { + static char *name_buf = NULL; + static size_t name_len = 0; + int prefix_len = subtype_info - name; + LONGEST L, U; + struct type *type; + char *bounds_str; + int n; + + GROW_VECT (name_buf, name_len, prefix_len + 5); + strncpy (name_buf, name, prefix_len); + name_buf[prefix_len] = '\0'; + + subtype_info += 5; + bounds_str = strchr (subtype_info, '_'); + n = 1; + + if (*subtype_info == 'L') + { + if (!ada_scan_number (bounds_str, n, &L, &n) + && !scan_discrim_bound (bounds_str, n, dval, &L, &n)) + return raw_type; + if (bounds_str[n] == '_') + n += 2; + else if (bounds_str[n] == '.') /* FIXME? SGI Workshop kludge. */ + n += 1; + subtype_info += 1; + } + else + { + strcpy (name_buf + prefix_len, "___L"); + L = get_int_var_value (name_buf, "Index bound unknown.", NULL); + } + + if (*subtype_info == 'U') + { + if (!ada_scan_number (bounds_str, n, &U, &n) + && !scan_discrim_bound (bounds_str, n, dval, &U, &n)) + return raw_type; + } + else + { + strcpy (name_buf + prefix_len, "___U"); + U = get_int_var_value (name_buf, "Index bound unknown.", NULL); + } + + if (objfile == NULL) + objfile = TYPE_OBJFILE (base_type); + type = create_range_type (alloc_type (objfile), base_type, L, U); + TYPE_NAME (type) = name; + return type; + } +} + +/* True iff NAME is the name of a range type. */ +int +ada_is_range_type_name (const char *name) +{ + return (name != NULL && strstr (name, "___XD")); +} + + + /* Modular types */ + +/* True iff TYPE is an Ada modular type. */ +int +ada_is_modular_type (struct type *type) +{ + /* FIXME: base_type should be declared in gdbtypes.h, implemented in + valarith.c */ + struct type *subranged_type; /* = base_type (type); */ + + return (subranged_type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE + && TYPE_CODE (subranged_type) != TYPE_CODE_ENUM + && TYPE_UNSIGNED (subranged_type)); +} + +/* Assuming ada_is_modular_type (TYPE), the modulus of TYPE. */ +LONGEST +ada_modulus (struct type * type) +{ + return TYPE_HIGH_BOUND (type) + 1; +} + + + + /* Operators */ + +/* Table mapping opcodes into strings for printing operators + and precedences of the operators. */ + +static const struct op_print ada_op_print_tab[] = { + {":=", BINOP_ASSIGN, PREC_ASSIGN, 1}, + {"or else", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, + {"and then", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, + {"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0}, + {"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0}, + {"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0}, + {"=", BINOP_EQUAL, PREC_EQUAL, 0}, + {"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0}, + {"<=", BINOP_LEQ, PREC_ORDER, 0}, + {">=", BINOP_GEQ, PREC_ORDER, 0}, + {">", BINOP_GTR, PREC_ORDER, 0}, + {"<", BINOP_LESS, PREC_ORDER, 0}, + {">>", BINOP_RSH, PREC_SHIFT, 0}, + {"<<", BINOP_LSH, PREC_SHIFT, 0}, + {"+", BINOP_ADD, PREC_ADD, 0}, + {"-", BINOP_SUB, PREC_ADD, 0}, + {"&", BINOP_CONCAT, PREC_ADD, 0}, + {"*", BINOP_MUL, PREC_MUL, 0}, + {"/", BINOP_DIV, PREC_MUL, 0}, + {"rem", BINOP_REM, PREC_MUL, 0}, + {"mod", BINOP_MOD, PREC_MUL, 0}, + {"**", BINOP_EXP, PREC_REPEAT, 0}, + {"@", BINOP_REPEAT, PREC_REPEAT, 0}, + {"-", UNOP_NEG, PREC_PREFIX, 0}, + {"+", UNOP_PLUS, PREC_PREFIX, 0}, + {"not ", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, + {"not ", UNOP_COMPLEMENT, PREC_PREFIX, 0}, + {"abs ", UNOP_ABS, PREC_PREFIX, 0}, + {".all", UNOP_IND, PREC_SUFFIX, 1}, /* FIXME: postfix .ALL */ + {"'access", UNOP_ADDR, PREC_SUFFIX, 1}, /* FIXME: postfix 'ACCESS */ + {NULL, 0, 0, 0} +}; + + /* Assorted Types and Interfaces */ + +struct type *builtin_type_ada_int; +struct type *builtin_type_ada_short; +struct type *builtin_type_ada_long; +struct type *builtin_type_ada_long_long; +struct type *builtin_type_ada_char; +struct type *builtin_type_ada_float; +struct type *builtin_type_ada_double; +struct type *builtin_type_ada_long_double; +struct type *builtin_type_ada_natural; +struct type *builtin_type_ada_positive; +struct type *builtin_type_ada_system_address; + +struct type **const (ada_builtin_types[]) = +{ + + &builtin_type_ada_int, + &builtin_type_ada_long, + &builtin_type_ada_short, + &builtin_type_ada_char, + &builtin_type_ada_float, + &builtin_type_ada_double, + &builtin_type_ada_long_long, + &builtin_type_ada_long_double, + &builtin_type_ada_natural, &builtin_type_ada_positive, + /* The following types are carried over from C for convenience. */ +&builtin_type_int, + &builtin_type_long, + &builtin_type_short, + &builtin_type_char, + &builtin_type_float, + &builtin_type_double, + &builtin_type_long_long, + &builtin_type_void, + &builtin_type_signed_char, + &builtin_type_unsigned_char, + &builtin_type_unsigned_short, + &builtin_type_unsigned_int, + &builtin_type_unsigned_long, + &builtin_type_unsigned_long_long, + &builtin_type_long_double, + &builtin_type_complex, &builtin_type_double_complex, 0}; + +/* Not really used, but needed in the ada_language_defn. */ +static void +emit_char (int c, struct ui_file *stream, int quoter) +{ + ada_emit_char (c, stream, quoter, 1); +} + +const struct language_defn ada_language_defn = { + "ada", /* Language name */ + /* language_ada, */ + language_unknown, + /* FIXME: language_ada should be defined in defs.h */ + ada_builtin_types, + range_check_off, + type_check_off, + case_sensitive_on, /* Yes, Ada is case-insensitive, but + * that's not quite what this means. */ + ada_parse, + ada_error, + ada_evaluate_subexp, + ada_printchar, /* Print a character constant */ + ada_printstr, /* Function to print string constant */ + emit_char, /* Function to print single char (not used) */ + ada_create_fundamental_type, /* Create fundamental type in this language */ + ada_print_type, /* Print a type using appropriate syntax */ + ada_val_print, /* Print a value using appropriate syntax */ + ada_value_print, /* Print a top-level value */ + NULL, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ + {"", "", "", ""}, /* Binary format info */ +#if 0 + {"8#%lo#", "8#", "o", "#"}, /* Octal format info */ + {"%ld", "", "d", ""}, /* Decimal format info */ + {"16#%lx#", "16#", "x", "#"}, /* Hex format info */ +#else + /* Copied from c-lang.c. */ + {"0%lo", "0", "o", ""}, /* Octal format info */ + {"%ld", "", "d", ""}, /* Decimal format info */ + {"0x%lx", "0x", "x", ""}, /* Hex format info */ +#endif + ada_op_print_tab, /* expression operators for printing */ + 1, /* c-style arrays (FIXME?) */ + 0, /* String lower bound (FIXME?) */ + &builtin_type_ada_char, + default_word_break_characters, + LANG_MAGIC +}; + +void +_initialize_ada_language (void) +{ + builtin_type_ada_int = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "integer", (struct objfile *) NULL); + builtin_type_ada_long = + init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_integer", (struct objfile *) NULL); + builtin_type_ada_short = + init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, "short_integer", (struct objfile *) NULL); + builtin_type_ada_char = + init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "character", (struct objfile *) NULL); + builtin_type_ada_float = + init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT, + 0, "float", (struct objfile *) NULL); + builtin_type_ada_double = + init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long_float", (struct objfile *) NULL); + builtin_type_ada_long_long = + init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_long_integer", (struct objfile *) NULL); + builtin_type_ada_long_double = + init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long_long_float", (struct objfile *) NULL); + builtin_type_ada_natural = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "natural", (struct objfile *) NULL); + builtin_type_ada_positive = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "positive", (struct objfile *) NULL); + + + builtin_type_ada_system_address = + lookup_pointer_type (init_type (TYPE_CODE_VOID, 1, 0, "void", + (struct objfile *) NULL)); + TYPE_NAME (builtin_type_ada_system_address) = "system__address"; + + add_language (&ada_language_defn); + + add_show_from_set + (add_set_cmd ("varsize-limit", class_support, var_uinteger, + (char *) &varsize_limit, + "Set maximum bytes in dynamic-sized object.", + &setlist), &showlist); + varsize_limit = 65536; + + add_com ("begin", class_breakpoint, begin_command, + "Start the debugged program, stopping at the beginning of the\n\ +main program. You may specify command-line arguments to give it, as for\n\ +the \"run\" command (q.v.)."); +} + + +/* Create a fundamental Ada type using default reasonable for the current + target machine. + + Some object/debugging file formats (DWARF version 1, COFF, etc) do not + define fundamental types such as "int" or "double". Others (stabs or + DWARF version 2, etc) do define fundamental types. For the formats which + don't provide fundamental types, gdb can create such types using this + function. + + FIXME: Some compilers distinguish explicitly signed integral types + (signed short, signed int, signed long) from "regular" integral types + (short, int, long) in the debugging information. There is some dis- + agreement as to how useful this feature is. In particular, gcc does + not support this. Also, only some debugging formats allow the + distinction to be passed on to a debugger. For now, we always just + use "short", "int", or "long" as the type name, for both the implicit + and explicitly signed types. This also makes life easier for the + gdb test suite since we don't have to account for the differences + in output depending upon what the compiler and debugging format + support. We will probably have to re-examine the issue when gdb + starts taking it's fundamental type information directly from the + debugging information supplied by the compiler. fnf@cygnus.com */ + +static struct type * +ada_create_fundamental_type (struct objfile *objfile, int typeid) +{ + struct type *type = NULL; + + switch (typeid) + { + default: + /* FIXME: For now, if we are asked to produce a type not in this + language, create the equivalent of a C integer type with the + name "". When all the dust settles from the type + reconstruction work, this should probably become an error. */ + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "", objfile); + warning ("internal error: no Ada fundamental type %d", typeid); + break; + case FT_VOID: + type = init_type (TYPE_CODE_VOID, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "void", objfile); + break; + case FT_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "character", objfile); + break; + case FT_SIGNED_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "signed char", objfile); + break; + case FT_UNSIGNED_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned char", objfile); + break; + case FT_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, "short_integer", objfile); + break; + case FT_SIGNED_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, "short_integer", objfile); + break; + case FT_UNSIGNED_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned short", objfile); + break; + case FT_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "integer", objfile); + break; + case FT_SIGNED_INTEGER: + type = init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, 0, "integer", objfile); /* FIXME -fnf */ + break; + case FT_UNSIGNED_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned int", objfile); + break; + case FT_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_integer", objfile); + break; + case FT_SIGNED_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_integer", objfile); + break; + case FT_UNSIGNED_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned long", objfile); + break; + case FT_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_long_integer", objfile); + break; + case FT_SIGNED_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_long_integer", objfile); + break; + case FT_UNSIGNED_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned long long", objfile); + break; + case FT_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_FLOAT_BIT / TARGET_CHAR_BIT, + 0, "float", objfile); + break; + case FT_DBL_PREC_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long_float", objfile); + break; + case FT_EXT_PREC_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long_long_float", objfile); + break; + } + return (type); +} + +void +ada_dump_symtab (struct symtab *s) +{ + int i; + fprintf (stderr, "New symtab: [\n"); + fprintf (stderr, " Name: %s/%s;\n", + s->dirname ? s->dirname : "?", s->filename ? s->filename : "?"); + fprintf (stderr, " Format: %s;\n", s->debugformat); + if (s->linetable != NULL) + { + fprintf (stderr, " Line table (section %d):\n", s->block_line_section); + for (i = 0; i < s->linetable->nitems; i += 1) + { + struct linetable_entry *e = s->linetable->item + i; + fprintf (stderr, " %4ld: %8lx\n", (long) e->line, (long) e->pc); + } + } + fprintf (stderr, "]\n"); +} diff --git a/contrib/gdb/gdb/ada-lang.h b/contrib/gdb/gdb/ada-lang.h new file mode 100644 index 00000000000..54e56bb0529 --- /dev/null +++ b/contrib/gdb/gdb/ada-lang.h @@ -0,0 +1,392 @@ +/* Ada language support definitions for GDB, the GNU debugger. + Copyright 1992, 1997 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if !defined (ADA_LANG_H) +#define ADA_LANG_H 1 + +struct partial_symbol; + +#include "value.h" +#include "gdbtypes.h" + +struct block; + +/* A macro to reorder the bytes of an address depending on the + endiannes of the target. */ +#define EXTRACT_ADDRESS(x) ((void *) extract_unsigned_integer (&(x), sizeof (x))) +/* A macro to reorder the bytes of an int depending on the endiannes + of the target */ +#define EXTRACT_INT(x) ((int) extract_signed_integer (&(x), sizeof (x))) + +/* Chain of cleanups for arguments of OP_UNRESOLVED_VALUE names. Created in + yyparse and freed in ada_resolve. */ +extern struct cleanup *unresolved_names; + +/* Corresponding mangled/demangled names and opcodes for Ada user-definable + operators. */ +struct ada_opname_map +{ + const char *mangled; + const char *demangled; + enum exp_opcode op; +}; + +/* Table of Ada operators in mangled and demangled forms. */ +/* Defined in ada-lang.c */ +extern const struct ada_opname_map ada_opname_table[]; + +/* The maximum number of tasks known to the Ada runtime */ +extern const int MAX_NUMBER_OF_KNOWN_TASKS; + +/* Identifiers for Ada attributes that need special processing. Be sure + to update the table attribute_names in ada-lang.c whenever you change this. + */ + +enum ada_attribute +{ + /* Invalid attribute for error checking. */ + ATR_INVALID, + + ATR_FIRST, + ATR_LAST, + ATR_LENGTH, + ATR_IMAGE, + ATR_IMG, + ATR_MAX, + ATR_MIN, + ATR_MODULUS, + ATR_POS, + ATR_SIZE, + ATR_TAG, + ATR_VAL, + + /* Dummy last attribute. */ + ATR_END +}; + +enum task_states +{ + Unactivated, + Runnable, + Terminated, + Activator_Sleep, + Acceptor_Sleep, + Entry_Caller_Sleep, + Async_Select_Sleep, + Delay_Sleep, + Master_Completion_Sleep, + Master_Phase_2_Sleep +}; + +extern char *ada_task_states[]; + +typedef struct +{ + char *P_ARRAY; + int *P_BOUNDS; +} +fat_string; + +typedef struct entry_call +{ + void *self; +} + *entry_call_link; + +struct task_fields +{ + int entry_num; +#if (defined (VXWORKS_TARGET) || !defined (i386)) \ + && !(defined (VXWORKS_TARGET) && defined (M68K_TARGET)) + int pad1; +#endif + char state; +#if (defined (VXWORKS_TARGET) && defined (M68K_TARGET)) + char pad_8bits; +#endif + void *parent; + int priority; + int current_priority; + fat_string image; + entry_call_link call; +#if (defined (sun) && defined (__SVR4)) && !defined (VXWORKS_TARGET) + int pad2; + unsigned thread; + unsigned lwp; +#else + void *thread; + void *lwp; +#endif +} +#if (defined (VXWORKS_TARGET) && defined (M68K_TARGET)) +__attribute__ ((packed)) +#endif + ; + +struct task_entry +{ + void *task_id; + int task_num; + int known_tasks_index; + struct task_entry *next_task; + void *thread; + void *lwp; + int stack_per; +}; + +extern struct type *builtin_type_ada_int; +extern struct type *builtin_type_ada_short; +extern struct type *builtin_type_ada_long; +extern struct type *builtin_type_ada_long_long; +extern struct type *builtin_type_ada_char; +extern struct type *builtin_type_ada_float; +extern struct type *builtin_type_ada_double; +extern struct type *builtin_type_ada_long_double; +extern struct type *builtin_type_ada_natural; +extern struct type *builtin_type_ada_positive; +extern struct type *builtin_type_ada_system_address; + +/* Assuming V points to an array of S objects, make sure that it contains at + least M objects, updating V and S as necessary. */ + +#define GROW_VECT(v, s, m) \ + if ((s) < (m)) grow_vect ((void**) &(v), &(s), (m), sizeof(*(v))); + +extern void grow_vect (void **, size_t *, size_t, int); + +extern int ada_parse (void); /* Defined in ada-exp.y */ + +extern void ada_error (char *); /* Defined in ada-exp.y */ + + /* Defined in ada-typeprint.c */ +extern void ada_print_type (struct type *, char *, struct ui_file *, int, + int); + +extern int ada_val_print (struct type *, char *, int, CORE_ADDR, + struct ui_file *, int, int, int, + enum val_prettyprint); + +extern int ada_value_print (struct value *, struct ui_file *, int, + enum val_prettyprint); + + /* Defined in ada-lang.c */ + +extern struct value *value_from_contents_and_address (struct type *, char *, + CORE_ADDR); + +extern void ada_emit_char (int, struct ui_file *, int, int); + +extern void ada_printchar (int, struct ui_file *); + +extern void ada_printstr (struct ui_file *, char *, unsigned int, int, int); + +extern void ada_convert_actuals (struct value *, int, struct value **, + CORE_ADDR *); + +extern struct value *ada_value_subscript (struct value *, int, + struct value **); + +extern struct type *ada_array_element_type (struct type *, int); + +extern int ada_array_arity (struct type *); + +struct type *ada_type_of_array (struct value *, int); + +extern struct value *ada_coerce_to_simple_array (struct value *); + +extern struct value *ada_coerce_to_simple_array_ptr (struct value *); + +extern int ada_is_simple_array (struct type *); + +extern int ada_is_array_descriptor (struct type *); + +extern int ada_is_bogus_array_descriptor (struct type *); + +extern struct type *ada_index_type (struct type *, int); + +extern struct value *ada_array_bound (struct value *, int, int); + +extern int ada_lookup_symbol_list (const char *, struct block *, + domain_enum, struct symbol ***, + struct block ***); + +extern char *ada_fold_name (const char *); + +extern struct symbol *ada_lookup_symbol (const char *, struct block *, + domain_enum); + +extern struct minimal_symbol *ada_lookup_minimal_symbol (const char *); + +extern void ada_resolve (struct expression **, struct type *); + +extern int ada_resolve_function (struct symbol **, struct block **, int, + struct value **, int, const char *, + struct type *); + +extern void ada_fill_in_ada_prototype (struct symbol *); + +extern int user_select_syms (struct symbol **, struct block **, int, int); + +extern int get_selections (int *, int, int, int, char *); + +extern char *ada_start_decode_line_1 (char *); + +extern struct symtabs_and_lines ada_finish_decode_line_1 (char **, + struct symtab *, + int, char ***); + +extern int ada_scan_number (const char *, int, LONGEST *, int *); + +extern struct type *ada_parent_type (struct type *); + +extern int ada_is_ignored_field (struct type *, int); + +extern int ada_is_packed_array_type (struct type *); + +extern struct value *ada_value_primitive_packed_val (struct value *, char *, + long, int, int, + struct type *); + +extern struct type *ada_coerce_to_simple_array_type (struct type *); + +extern int ada_is_character_type (struct type *); + +extern int ada_is_string_type (struct type *); + +extern int ada_is_tagged_type (struct type *); + +extern struct type *ada_tag_type (struct value *); + +extern struct value *ada_value_tag (struct value *); + +extern int ada_is_parent_field (struct type *, int); + +extern int ada_is_wrapper_field (struct type *, int); + +extern int ada_is_variant_part (struct type *, int); + +extern struct type *ada_variant_discrim_type (struct type *, struct type *); + +extern int ada_is_others_clause (struct type *, int); + +extern int ada_in_variant (LONGEST, struct type *, int); + +extern char *ada_variant_discrim_name (struct type *); + +extern struct type *ada_lookup_struct_elt_type (struct type *, char *, int, + int *); + +extern struct value *ada_value_struct_elt (struct value *, char *, char *); + +extern struct value *ada_search_struct_field (char *, struct value *, int, + struct type *); + +extern int ada_is_aligner_type (struct type *); + +extern struct type *ada_aligned_type (struct type *); + +extern char *ada_aligned_value_addr (struct type *, char *); + +extern const char *ada_attribute_name (int); + +extern int ada_is_fixed_point_type (struct type *); + +extern DOUBLEST ada_delta (struct type *); + +extern DOUBLEST ada_fixed_to_float (struct type *, LONGEST); + +extern LONGEST ada_float_to_fixed (struct type *, DOUBLEST); + +extern int ada_is_vax_floating_type (struct type *); + +extern int ada_vax_float_type_suffix (struct type *); + +extern struct value *ada_vax_float_print_function (struct type *); + +extern struct type *ada_system_address_type (void); + +extern int ada_which_variant_applies (struct type *, struct type *, char *); + +extern struct value *ada_to_fixed_value (struct type *, char *, CORE_ADDR, + struct value *); + +extern struct type *ada_to_fixed_type (struct type *, char *, CORE_ADDR, + struct value *); + +extern int ada_name_prefix_len (const char *); + +extern char *ada_type_name (struct type *); + +extern struct type *ada_find_parallel_type (struct type *, + const char *suffix); + +extern LONGEST get_int_var_value (char *, char *, int *); + +extern struct type *ada_find_any_type (const char *name); + +extern int ada_prefer_type (struct type *, struct type *); + +extern struct type *ada_get_base_type (struct type *); + +extern struct type *ada_completed_type (struct type *); + +extern char *ada_mangle (const char *); + +extern const char *ada_enum_name (const char *); + +extern int ada_is_modular_type (struct type *); + +extern LONGEST ada_modulus (struct type *); + +extern struct value *ada_value_ind (struct value *); + +extern void ada_print_scalar (struct type *, LONGEST, struct ui_file *); + +extern int ada_is_range_type_name (const char *); + +extern const char *ada_renaming_type (struct type *); + +extern int ada_is_object_renaming (struct symbol *); + +extern const char *ada_simple_renamed_entity (struct symbol *); + +extern char *ada_breakpoint_rewrite (char *, int *); + +/* Tasking-related: ada-tasks.c */ + +extern int valid_task_id (int); + +extern int get_current_task (void); + +extern void init_task_list (void); + +extern void *get_self_id (void); + +extern int get_current_task (void); + +extern int get_entry_number (void *); + +extern void ada_report_exception_break (struct breakpoint *); + +extern int ada_maybe_exception_partial_symbol (struct partial_symbol *sym); + +extern int ada_is_exception_sym (struct symbol *sym); + + +#endif diff --git a/contrib/gdb/gdb/ada-lex.l b/contrib/gdb/gdb/ada-lex.l new file mode 100644 index 00000000000..139e3aad3dd --- /dev/null +++ b/contrib/gdb/gdb/ada-lex.l @@ -0,0 +1,928 @@ +/* FLEX lexer for Ada expressions, for GDB. + Copyright (C) 1994, 1997, 2000 + Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/*----------------------------------------------------------------------*/ + +/* The converted version of this file is to be included in ada-exp.y, */ +/* the Ada parser for gdb. The function yylex obtains characters from */ +/* the global pointer lexptr. It returns a syntactic category for */ +/* each successive token and places a semantic value into yylval */ +/* (ada-lval), defined by the parser. */ + +/* Run flex with (at least) the -i option (case-insensitive), and the -I */ +/* option (interactive---no unnecessary lookahead). */ + +DIG [0-9] +NUM10 ({DIG}({DIG}|_)*) +HEXDIG [0-9a-f] +NUM16 ({HEXDIG}({HEXDIG}|_)*) +OCTDIG [0-7] +LETTER [a-z_] +ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">") +WHITE [ \t\n] +TICK ("'"{WHITE}*) +GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~] +OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs") + +EXP (e[+-]{NUM10}) +POSEXP (e"+"?{NUM10}) + +%{ +#define NUMERAL_WIDTH 256 +#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1)) + +/* Temporary staging for numeric literals. */ +static char numbuf[NUMERAL_WIDTH]; + static void canonicalizeNumeral (char* s1, const char*); +static int processInt (const char*, const char*, const char*); +static int processReal (const char*); +static int processId (const char*, int); +static int processAttribute (const char*); +static int find_dot_all (const char*); + +#undef YY_DECL +#define YY_DECL static int yylex ( void ) + +#undef YY_INPUT +#define YY_INPUT(BUF, RESULT, MAX_SIZE) \ + if ( *lexptr == '\000' ) \ + (RESULT) = YY_NULL; \ + else \ + { \ + *(BUF) = *lexptr; \ + (RESULT) = 1; \ + lexptr += 1; \ + } + +static char *tempbuf = NULL; +static int tempbufsize = 0; +static int tempbuf_len; +static struct block* left_block_context; + +static void resize_tempbuf (unsigned int); + +static void block_lookup (char*, char*); + +static int name_lookup (char*, char*, int*); + +static int find_dot_all (const char*); + +%} + +%s IN_STRING BEFORE_QUAL_QUOTE + +%% + +{WHITE} { } + +"--".* { yyterminate(); } + +{NUM10}{POSEXP} { + canonicalizeNumeral (numbuf, yytext); + return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1); + } + +{NUM10} { + canonicalizeNumeral (numbuf, yytext); + return processInt (NULL, numbuf, NULL); + } + +{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} { + canonicalizeNumeral (numbuf, yytext); + return processInt (numbuf, + strchr (numbuf, '#') + 1, + strrchr(numbuf, '#') + 1); + } + +{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" { + canonicalizeNumeral (numbuf, yytext); + return processInt (numbuf, strchr (numbuf, '#') + 1, NULL); + } + +"0x"{HEXDIG}+ { + canonicalizeNumeral (numbuf, yytext+2); + return processInt ("16#", numbuf, NULL); + } + + +{NUM10}"."{NUM10}{EXP} { + canonicalizeNumeral (numbuf, yytext); + return processReal (numbuf); + } + +{NUM10}"."{NUM10} { + canonicalizeNumeral (numbuf, yytext); + return processReal (numbuf); + } + +{NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} { + error ("Based real literals not implemented yet."); + } + +{NUM10}"#"{NUM16}"."{NUM16}"#" { + error ("Based real literals not implemented yet."); + } + +"'"({GRAPHIC}|\")"'" { + yylval.typed_val.type = builtin_type_ada_char; + yylval.typed_val.val = yytext[1]; + return CHARLIT; + } + +"'[\""{HEXDIG}{2}"\"]'" { + int v; + yylval.typed_val.type = builtin_type_ada_char; + sscanf (yytext+3, "%2x", &v); + yylval.typed_val.val = v; + return CHARLIT; + } + +\"{OPER}\"/{WHITE}*"(" { return processId (yytext, yyleng); } + +\" { + tempbuf_len = 0; + BEGIN IN_STRING; + } + +{GRAPHIC}*\" { + resize_tempbuf (yyleng+tempbuf_len); + strncpy (tempbuf+tempbuf_len, yytext, yyleng-1); + tempbuf_len += yyleng-1; + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbuf_len; + BEGIN INITIAL; + return STRING; + } + +{GRAPHIC}*"[\""{HEXDIG}{2}"\"]" { + int n; + resize_tempbuf (yyleng-5+tempbuf_len+1); + strncpy (tempbuf+tempbuf_len, yytext, yyleng-6); + sscanf(yytext+yyleng-4, "%2x", &n); + tempbuf[yyleng-6+tempbuf_len] = (char) n; + tempbuf_len += yyleng-5; + } + +{GRAPHIC}*"[\"\"\"]" { + int n; + resize_tempbuf (yyleng-4+tempbuf_len+1); + strncpy (tempbuf+tempbuf_len, yytext, yyleng-6); + tempbuf[yyleng-5+tempbuf_len] = '"'; + tempbuf_len += yyleng-4; + } + +if { + while (*lexptr != 'i' && *lexptr != 'I') + lexptr -= 1; + yyrestart(NULL); + return 0; + } + + /* ADA KEYWORDS */ + +abs { return ABS; } +and { return _AND_; } +else { return ELSE; } +in { return IN; } +mod { return MOD; } +new { return NEW; } +not { return NOT; } +null { return NULL_PTR; } +or { return OR; } +rem { return REM; } +then { return THEN; } +xor { return XOR; } + + /* ATTRIBUTES */ + +{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); } + + /* PUNCTUATION */ + +"=>" { return ARROW; } +".." { return DOTDOT; } +"**" { return STARSTAR; } +":=" { return ASSIGN; } +"/=" { return NOTEQUAL; } +"<=" { return LEQ; } +">=" { return GEQ; } + +"'" { BEGIN INITIAL; return '\''; } + +[-&*+./:<>=|;\[\]] { return yytext[0]; } + +"," { if (paren_depth == 0 && comma_terminates) + { + lexptr -= 1; + yyrestart(NULL); + return 0; + } + else + return ','; + } + +"(" { paren_depth += 1; return '('; } +")" { if (paren_depth == 0) + { + lexptr -= 1; + yyrestart(NULL); + return 0; + } + else + { + paren_depth -= 1; + return ')'; + } + } + +"."{WHITE}*all { return DOT_ALL; } + +"."{WHITE}*{ID} { + processId (yytext+1, yyleng-1); + return DOT_ID; + } + +{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? { + int all_posn = find_dot_all (yytext); + int token_type, segments, k; + int quote_follows; + + if (all_posn == -1 && yytext[yyleng-1] == '\'') + { + quote_follows = 1; + do { + yyless (yyleng-1); + } while (yytext[yyleng-1] == ' '); + } + else + quote_follows = 0; + + if (all_posn >= 0) + yyless (all_posn); + processId(yytext, yyleng); + segments = name_lookup (ada_mangle (yylval.ssym.stoken.ptr), + yylval.ssym.stoken.ptr, &token_type); + left_block_context = NULL; + for (k = yyleng; segments > 0 && k > 0; k -= 1) + { + if (yytext[k-1] == '.') + segments -= 1; + quote_follows = 0; + } + if (k <= 0) + error ("confused by name %s", yytext); + yyless (k); + if (quote_follows) + BEGIN BEFORE_QUAL_QUOTE; + return token_type; + } + + /* GDB EXPRESSION CONSTRUCTS */ + + +"'"[^']+"'"{WHITE}*:: { + processId(yytext, yyleng-2); + block_lookup (yylval.ssym.stoken.ptr, yylval.ssym.stoken.ptr); + return BLOCKNAME; + } + +{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*{WHITE}*:: { + processId(yytext, yyleng-2); + block_lookup (ada_mangle (yylval.ssym.stoken.ptr), + yylval.ssym.stoken.ptr); + return BLOCKNAME; + } + +[{}@] { return yytext[0]; } + +"$$" { yylval.lval = -1; return LAST; } +"$$"{DIG}+ { yylval.lval = -atoi(yytext+2); return LAST; } +"$" { yylval.lval = 0; return LAST; } +"$"{DIG}+ { yylval.lval = atoi(yytext+1); return LAST; } + + + /* REGISTERS AND GDB CONVENIENCE VARIABLES */ + +"$"({LETTER}|{DIG}|"$")+ { + int c; + for (c = 0; c < NUM_REGS; c++) + if (REGISTER_NAME (c) && + strcmp (yytext + 1, REGISTER_NAME (c)) == 0) + { + yylval.lval = c; + return REGNAME; + } + yylval.sval.ptr = yytext; + yylval.sval.length = yyleng; + yylval.ivar = + lookup_internalvar (copy_name (yylval.sval) + 1); + return INTERNAL_VARIABLE; + } + + /* CATCH-ALL ERROR CASE */ + +. { error ("Invalid character '%s' in expression.", yytext); } +%% + +#include +#include + +/* Initialize the lexer for processing new expression */ +void +lexer_init (FILE* inp) +{ + BEGIN INITIAL; + yyrestart (inp); +} + + +/* Make sure that tempbuf points at an array at least N characters long. */ + +static void +resize_tempbuf (n) + unsigned int n; +{ + if (tempbufsize < n) + { + tempbufsize = (n+63) & ~63; + tempbuf = (char*) xrealloc (tempbuf, tempbufsize); + } +} + +/* Copy S2 to S1, removing all underscores, and downcasing all letters. */ + +static void +canonicalizeNumeral (s1,s2) + char* s1; + const char* s2; +{ + for (; *s2 != '\000'; s2 += 1) + { + if (*s2 != '_') + { + *s1 = tolower(*s2); + s1 += 1; + } + } + s1[0] = '\000'; +} + +#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT) + +/* True (non-zero) iff DIGIT is a valid digit in radix BASE, + where 2 <= BASE <= 16. */ + +static int +is_digit_in_base (digit, base) + unsigned char digit; + int base; +{ + if (!isxdigit (digit)) + return 0; + if (base <= 10) + return (isdigit (digit) && digit < base + '0'); + else + return (isdigit (digit) || tolower (digit) < base - 10 + 'a'); +} + +static int +digit_to_int (c) + unsigned char c; +{ + if (isdigit (c)) + return c - '0'; + else + return tolower (c) - 'a' + 10; +} + +/* As for strtoul, but for ULONGEST results. */ +ULONGEST +strtoulst (num, trailer, base) + const char *num; + const char **trailer; + int base; +{ + unsigned int high_part; + ULONGEST result; + int i; + unsigned char lim; + + if (base < 2 || base > 16) + { + errno = EINVAL; + return 0; + } + lim = base - 1 + '0'; + + result = high_part = 0; + for (i = 0; is_digit_in_base (num[i], base); i += 1) + { + result = result*base + digit_to_int (num[i]); + high_part = high_part*base + (unsigned int) (result >> HIGH_BYTE_POSN); + result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1; + if (high_part > 0xff) + { + errno = ERANGE; + result = high_part = 0; + break; + } + } + + if (trailer != NULL) + *trailer = &num[i]; + + return result + ((ULONGEST) high_part << HIGH_BYTE_POSN); +} + + + +/* Interprets the prefix of NUM that consists of digits of the given BASE + as an integer of that BASE, with the string EXP as an exponent. + Puts value in yylval, and returns INT, if the string is valid. Causes + an error if the number is improperly formated. BASE, if NULL, defaults + to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'. */ + +static int +processInt (base0, num0, exp0) + const char* num0; + const char* base0; + const char* exp0; +{ + ULONGEST result; + long exp; + int base; + + char* trailer; + + if (base0 == NULL) + base = 10; + else + { + base = strtol (base0, (char**) NULL, 10); + if (base < 2 || base > 16) + error ("Invalid base: %d.", base); + } + + if (exp0 == NULL) + exp = 0; + else + exp = strtol(exp0, (char**) NULL, 10); + + errno = 0; + result = strtoulst (num0, &trailer, base); + if (errno == ERANGE) + error ("Integer literal out of range"); + if (isxdigit(*trailer)) + error ("Invalid digit `%c' in based literal", *trailer); + + while (exp > 0) + { + if (result > (ULONG_MAX / base)) + error ("Integer literal out of range"); + result *= base; + exp -= 1; + } + + if ((result >> (TARGET_INT_BIT-1)) == 0) + yylval.typed_val.type = builtin_type_ada_int; + else if ((result >> (TARGET_LONG_BIT-1)) == 0) + yylval.typed_val.type = builtin_type_ada_long; + else if (((result >> (TARGET_LONG_BIT-1)) >> 1) == 0) + { + /* We have a number representable as an unsigned integer quantity. + For consistency with the C treatment, we will treat it as an + anonymous modular (unsigned) quantity. Alas, the types are such + that we need to store .val as a signed quantity. Sorry + for the mess, but C doesn't officially guarantee that a simple + assignment does the trick (no, it doesn't; read the reference manual). + */ + yylval.typed_val.type = builtin_type_unsigned_long; + if (result & LONGEST_SIGN) + yylval.typed_val.val = + (LONGEST) (result & ~LONGEST_SIGN) + - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1); + else + yylval.typed_val.val = (LONGEST) result; + return INT; + } + else + yylval.typed_val.type = builtin_type_ada_long_long; + + yylval.typed_val.val = (LONGEST) result; + return INT; +} + +static int +processReal (num0) + const char* num0; +{ + if (sizeof (DOUBLEST) <= sizeof (float)) + sscanf (num0, "%g", &yylval.typed_val_float.dval); + else if (sizeof (DOUBLEST) <= sizeof (double)) + sscanf (num0, "%lg", &yylval.typed_val_float.dval); + else + { +#ifdef PRINTF_HAS_LONG_DOUBLE + sscanf (num0, "%Lg", &yylval.typed_val_float.dval); +#else + /* Scan it into a double, then convert and assign it to the + long double. This at least wins with values representable + in the range of doubles. */ + double temp; + sscanf (num0, "%lg", &temp); + yylval.typed_val_float.dval = temp; +#endif + } + + yylval.typed_val_float.type = builtin_type_ada_float; + if (sizeof(DOUBLEST) >= TARGET_DOUBLE_BIT / TARGET_CHAR_BIT) + yylval.typed_val_float.type = builtin_type_ada_double; + if (sizeof(DOUBLEST) >= TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT) + yylval.typed_val_float.type = builtin_type_ada_long_double; + + return FLOAT; +} + +static int +processId (name0, len) + const char *name0; + int len; +{ + char* name = xmalloc (len + 11); + int i0, i; + +/* add_name_string_cleanup (name); */ +/* FIXME: add_name_string_cleanup should be defined in parse.c */ + while (len > 0 && isspace (name0[len-1])) + len -= 1; + i = i0 = 0; + while (i0 < len) + { + if (isalnum (name0[i0])) + { + name[i] = tolower (name0[i0]); + i += 1; i0 += 1; + } + else switch (name0[i0]) + { + default: + name[i] = name0[i0]; + i += 1; i0 += 1; + break; + case ' ': case '\t': + i0 += 1; + break; + case '\'': + i0 += 1; + while (i0 < len && name0[i0] != '\'') + { + name[i] = name0[i0]; + i += 1; i0 += 1; + } + i0 += 1; + break; + case '<': + i0 += 1; + while (i0 < len && name0[i0] != '>') + { + name[i] = name0[i0]; + i += 1; i0 += 1; + } + i0 += 1; + break; + } + } + name[i] = '\000'; + + yylval.ssym.sym = NULL; + yylval.ssym.stoken.ptr = name; + yylval.ssym.stoken.length = i; + return NAME; +} + +static void +block_lookup (name, err_name) + char* name; + char* err_name; +{ + struct symbol** syms; + struct block** blocks; + int nsyms; + struct symtab *symtab; + nsyms = ada_lookup_symbol_list (name, left_block_context, + VAR_DOMAIN, &syms, &blocks); + if (left_block_context == NULL && + (nsyms == 0 || SYMBOL_CLASS (syms[0]) != LOC_BLOCK)) + symtab = lookup_symtab (name); + else + symtab = NULL; + + if (symtab != NULL) + left_block_context = yylval.bval = + BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); + else if (nsyms == 0 || SYMBOL_CLASS (syms[0]) != LOC_BLOCK) + { + if (left_block_context == NULL) + error ("No file or function \"%s\".", err_name); + else + error ("No function \"%s\" in specified context.", err_name); + } + else + { + left_block_context = yylval.bval = SYMBOL_BLOCK_VALUE (syms[0]); + if (nsyms > 1) + warning ("Function name \"%s\" ambiguous here", err_name); + } +} + +/* Look up NAME0 (assumed to be mangled) as a name in VAR_DOMAIN, + setting *TOKEN_TYPE to NAME or TYPENAME, depending on what is + found. Try first the entire name, then the name without the last + segment (i.e., after the last .id), etc., and return the number of + segments that had to be removed to get a match. Calls error if no + matches are found, using ERR_NAME in any error message. When + exactly one symbol match is found, it is placed in yylval. */ + +static int +name_lookup (name0, err_name, token_type) + char* name0; + char* err_name; + int* token_type; +{ + struct symbol** syms; + struct block** blocks; + struct type* type; + int len0 = strlen (name0); + char* name = savestring (name0, len0); + int nsyms; + int segments; + +/* add_name_string_cleanup (name);*/ +/* FIXME: add_name_string_cleanup should be defined in parse.c */ + yylval.ssym.stoken.ptr = name; + yylval.ssym.stoken.length = strlen (name); + for (segments = 0; ; segments += 1) + { + struct type* preferred_type; + int i, preferred_index; + + if (left_block_context == NULL) + nsyms = ada_lookup_symbol_list (name, expression_context_block, + VAR_DOMAIN, &syms, &blocks); + else + nsyms = ada_lookup_symbol_list (name, left_block_context, + VAR_DOMAIN, &syms, &blocks); + + /* Check for a type definition. */ + + /* Look for a symbol that doesn't denote void. This is (I think) a */ + /* temporary kludge to get around problems in GNAT output. */ + preferred_index = -1; preferred_type = NULL; + for (i = 0; i < nsyms; i += 1) + switch (SYMBOL_CLASS (syms[i])) + { + case LOC_TYPEDEF: + if (ada_prefer_type (SYMBOL_TYPE (syms[i]), preferred_type)) + { + preferred_index = i; + preferred_type = SYMBOL_TYPE (syms[i]); + } + break; + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_LOCAL_ARG: + case LOC_BASEREG: + case LOC_BASEREG_ARG: + goto NotType; + default: + break; + } + if (preferred_type != NULL) + { +/* if (TYPE_CODE (preferred_type) == TYPE_CODE_VOID) + error ("`%s' matches only void type name(s)", + ada_demangle (name)); +*/ +/* FIXME: ada_demangle should be defined in defs.h, and is located in ada-lang.c */ +/* else*/ if (ada_is_object_renaming (syms[preferred_index])) + { + yylval.ssym.sym = syms[preferred_index]; + *token_type = OBJECT_RENAMING; + return segments; + } + else if (ada_renaming_type (SYMBOL_TYPE (syms[preferred_index])) + != NULL) + { + int result; + const char* renaming = + ada_simple_renamed_entity (syms[preferred_index]); + char* new_name = xmalloc (strlen (renaming) + len0 + - yylval.ssym.stoken.length + 1); +/* add_name_string_cleanup (new_name);*/ +/* FIXME: add_name_string_cleanup should be defined in parse.c */ + strcpy (new_name, renaming); + strcat (new_name, name0 + yylval.ssym.stoken.length); + result = name_lookup (new_name, err_name, token_type); + if (result > segments) + error ("Confused by renamed symbol."); + return result; + } + else if (segments == 0) + { + yylval.tval = preferred_type; + *token_type = TYPENAME; + return 0; + } + } + + if (segments == 0) + { + type = lookup_primitive_typename (name); + if (type == NULL && DEPRECATED_STREQ ("system__address", name)) + type = builtin_type_ada_system_address; + if (type != NULL) + { + yylval.tval = type; + *token_type = TYPENAME; + return 0; + } + } + + NotType: + if (nsyms == 1) + { + *token_type = NAME; + yylval.ssym.sym = syms[0]; + yylval.ssym.msym = NULL; + yylval.ssym.block = blocks[0]; + return segments; + } + else if (nsyms == 0) { + int i; + yylval.ssym.msym = ada_lookup_minimal_symbol (name); + if (yylval.ssym.msym != NULL) + { + yylval.ssym.sym = NULL; + yylval.ssym.block = NULL; + *token_type = NAME; + return segments; + } + + for (i = yylval.ssym.stoken.length - 1; i > 0; i -= 1) + { + if (name[i] == '.') + { + name[i] = '\0'; + yylval.ssym.stoken.length = i; + break; + } + else if (name[i] == '_' && name[i-1] == '_') + { + i -= 1; + name[i] = '\0'; + yylval.ssym.stoken.length = i; + break; + } + } + if (i <= 0) + { + if (!have_full_symbols () && !have_partial_symbols () + && left_block_context == NULL) + error ("No symbol table is loaded. Use the \"file\" command."); + if (left_block_context == NULL) + error ("No definition of \"%s\" in current context.", + err_name); + else + error ("No definition of \"%s\" in specified context.", + err_name); + } + } + else + { + *token_type = NAME; + yylval.ssym.sym = NULL; + yylval.ssym.msym = NULL; + if (left_block_context == NULL) + yylval.ssym.block = expression_context_block; + else + yylval.ssym.block = left_block_context; + return segments; + } + } +} + +/* Returns the position within STR of the '.' in a + '.{WHITE}*all' component of a dotted name, or -1 if there is none. */ +static int +find_dot_all (str) + const char* str; +{ + int i; + for (i = 0; str[i] != '\000'; i += 1) + { + if (str[i] == '.') + { + int i0 = i; + do + i += 1; + while (isspace (str[i])); + if (strcmp (str+i, "all") == 0 + && ! isalnum (str[i+3]) && str[i+3] != '_') + return i0; + } + } + return -1; +} + +/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring + case. */ + +static int +subseqMatch (subseq, str) + const char* subseq; + const char* str; +{ + if (subseq[0] == '\0') + return 1; + else if (str[0] == '\0') + return 0; + else if (tolower (subseq[0]) == tolower (str[0])) + return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1); + else + return subseqMatch (subseq, str+1); +} + + +static struct { const char* name; int code; } +attributes[] = { + { "address", TICK_ADDRESS }, + { "unchecked_access", TICK_ACCESS }, + { "unrestricted_access", TICK_ACCESS }, + { "access", TICK_ACCESS }, + { "first", TICK_FIRST }, + { "last", TICK_LAST }, + { "length", TICK_LENGTH }, + { "max", TICK_MAX }, + { "min", TICK_MIN }, + { "modulus", TICK_MODULUS }, + { "pos", TICK_POS }, + { "range", TICK_RANGE }, + { "size", TICK_SIZE }, + { "tag", TICK_TAG }, + { "val", TICK_VAL }, + { NULL, -1 } +}; + +/* Return the syntactic code corresponding to the attribute name or + abbreviation STR. */ + +static int +processAttribute (str) + const char* str; +{ + int i, k; + + for (i = 0; attributes[i].code != -1; i += 1) + if (strcasecmp (str, attributes[i].name) == 0) + return attributes[i].code; + + for (i = 0, k = -1; attributes[i].code != -1; i += 1) + if (subseqMatch (str, attributes[i].name)) + { + if (k == -1) + k = i; + else + error ("ambiguous attribute name: `%s'", str); + } + if (k == -1) + error ("unrecognized attribute: `%s'", str); + + return attributes[k].code; +} + +int +yywrap() +{ + return 1; +} diff --git a/contrib/gdb/gdb/ada-tasks.c b/contrib/gdb/gdb/ada-tasks.c new file mode 100644 index 00000000000..c8830151145 --- /dev/null +++ b/contrib/gdb/gdb/ada-tasks.c @@ -0,0 +1,819 @@ +/* file ada-tasks.c: Ada tasking control for GDB + Copyright 1997 Free Software Foundation, Inc. + Contributed by Ada Core Technologies, Inc +. + This file is part of GDB. + + [$Id: ada-tasks.c,v 1.7 2003/06/17 20:58:32 ciceron Exp $] + Authors: Roch-Alexandre Nomine Beguin, Arnaud Charlet + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +*/ + +#include +#include "defs.h" +#include "command.h" +#include "value.h" +#include "language.h" +#include "inferior.h" +#include "symtab.h" +#include "target.h" +#include "regcache.h" +#include "gdbcore.h" + +#if (defined(__alpha__) && defined(__osf__) && !defined(__alpha_vxworks)) +#include +#endif + +#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)) +#include "gregset.h" +#endif + +#include "ada-lang.h" + +/* FIXME: move all this conditional compilation in description + files or in configure.in */ + +#if defined (VXWORKS_TARGET) +#define THREAD_TO_PID(tid,lwpid) (tid) + +#elif defined (linux) +#define THREAD_TO_PID(tid,lwpid) (0) + +#elif (defined (sun) && defined (__SVR4)) +#define THREAD_TO_PID thread_to_pid + +#elif defined (sgi) || defined (__WIN32__) || defined (hpux) +#define THREAD_TO_PID(tid,lwpid) ((int)lwpid) + +#else +#define THREAD_TO_PID(tid,lwpid) (0) +#endif + +#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET) +#define THREAD_FETCH_REGISTERS dec_thread_fetch_registers +#define GET_CURRENT_THREAD dec_thread_get_current_thread +extern int dec_thread_get_registers (gdb_gregset_t *, gdb_fpregset_t *); +#endif + +#if defined (_AIX) +#define THREAD_FETCH_REGISTERS aix_thread_fetch_registers +#define GET_CURRENT_THREAD aix_thread_get_current_thread +#endif + +#if defined(VXWORKS_TARGET) +#define GET_CURRENT_THREAD() ((void*)inferior_pid) +#define THREAD_FETCH_REGISTERS() (-1) + +#elif defined (sun) && defined (__SVR4) +#define GET_CURRENT_THREAD solaris_thread_get_current_thread +#define THREAD_FETCH_REGISTERS() (-1) +extern void *GET_CURRENT_THREAD (); + +#elif defined (_AIX) || (defined(__alpha__) && defined(__osf__)) +extern void *GET_CURRENT_THREAD (); + +#elif defined (__WIN32__) || defined (hpux) +#define GET_CURRENT_THREAD() (inferior_pid) +#define THREAD_FETCH_REGISTERS() (-1) + +#else +#define GET_CURRENT_THREAD() (NULL) +#define THREAD_FETCH_REGISTERS() (-1) +#endif + +#define KNOWN_TASKS_NAME "system__tasking__debug__known_tasks" + +#define READ_MEMORY(addr, var) read_memory (addr, (char*) &var, sizeof (var)) +/* external declarations */ + +/* Global visible variables */ + +struct task_entry *task_list = NULL; +int ada__tasks_check_symbol_table = 1; +void *pthread_kern_addr = NULL; + +#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)) +gdb_gregset_t gregset_saved; +gdb_fpregset_t fpregset_saved; +#endif + +/* The maximum number of tasks known to the Ada runtime */ +const int MAX_NUMBER_OF_KNOWN_TASKS = 1000; + +/* the current task */ +int current_task = -1, current_task_id = -1, current_task_index; +void *current_thread, *current_lwp; + +char *ada_task_states[] = { + "Unactivated", + "Runnable", + "Terminated", + "Child Activation Wait", + "Accept Statement", + "Waiting on entry call", + "Async Select Wait", + "Delay Sleep", + "Child Termination Wait", + "Wait Child in Term Alt", + "", + "", + "", + "", + "Asynchronous Hold" +}; + +/* Global internal types */ + +static char *ada_long_task_states[] = { + "Unactivated", + "Runnable", + "Terminated", + "Waiting for child activation", + "Blocked in accept statement", + "Waiting on entry call", + "Asynchronous Selective Wait", + "Delay Sleep", + "Waiting for children termination", + "Waiting for children in terminate alternative", + "", + "", + "", + "", + "Asynchronous Hold" +}; + +/* Global internal variables */ + +static int highest_task_num = 0; +int thread_support = 0; /* 1 if the thread library in use is supported */ +static int gdbtk_task_initialization = 0; + +static int +add_task_entry (void *p_task_id, int index) +{ + struct task_entry *new_task_entry = NULL; + struct task_entry *pt; + + highest_task_num++; + new_task_entry = xmalloc (sizeof (struct task_entry)); + new_task_entry->task_num = highest_task_num; + new_task_entry->task_id = p_task_id; + new_task_entry->known_tasks_index = index; + new_task_entry->next_task = NULL; + pt = task_list; + if (pt) + { + while (pt->next_task) + pt = pt->next_task; + pt->next_task = new_task_entry; + pt->stack_per = 0; + } + else + task_list = new_task_entry; + return new_task_entry->task_num; +} + +int +get_entry_number (void *p_task_id) +{ + struct task_entry *pt; + + pt = task_list; + while (pt != NULL) + { + if (pt->task_id == p_task_id) + return pt->task_num; + pt = pt->next_task; + } + return 0; +} + +static struct task_entry * +get_thread_entry_vptr (void *thread) +{ + struct task_entry *pt; + + pt = task_list; + while (pt != NULL) + { + if (pt->thread == thread) + return pt; + pt = pt->next_task; + } + return 0; +} + +static struct task_entry * +get_entry_vptr (int p_task_num) +{ + struct task_entry *pt; + + pt = task_list; + while (pt) + { + if (pt->task_num == p_task_num) + return pt; + pt = pt->next_task; + } + return NULL; +} + +void +init_task_list (void) +{ + struct task_entry *pt, *old_pt; + + pt = task_list; + while (pt) + { + old_pt = pt; + pt = pt->next_task; + xfree (old_pt); + }; + task_list = NULL; + highest_task_num = 0; +} + +int +valid_task_id (int task) +{ + return get_entry_vptr (task) != NULL; +} + +void * +get_self_id (void) +{ + struct value *val; + void *self_id; + int result; + struct task_entry *ent; + extern int do_not_insert_breakpoints; + +#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__)) + if (thread_support) +#endif + { + ent = get_thread_entry_vptr (GET_CURRENT_THREAD ()); + return ent ? ent->task_id : 0; + } + + /* FIXME: calling a function in the inferior with a multithreaded application + is not reliable, so return NULL if there is no safe way to get the current + task */ + return NULL; +} + +int +get_current_task (void) +{ + int result; + + /* FIXME: language_ada should be defined in defs.h */ + /* if (current_language->la_language != language_ada) return -1; */ + + result = get_entry_number (get_self_id ()); + + /* return -1 if not found */ + return result == 0 ? -1 : result; +} + +/* Print detailed information about specified task */ + +static void +info_task (char *arg, int from_tty) +{ + void *temp_task; + struct task_entry *pt, *pt2; + void *self_id, *caller; + struct task_fields atcb, atcb2; + struct entry_call call; + int bounds[2]; + char image[256]; + int num; + + /* FIXME: language_ada should be defined in defs.h */ + /* if (current_language->la_language != language_ada) + { + printf_filtered ("The current language does not support tasks.\n"); + return; + } + */ + pt = get_entry_vptr (atoi (arg)); + if (pt == NULL) + { + printf_filtered ("Task %s not found.\n", arg); + return; + } + + temp_task = pt->task_id; + + /* read the atcb in the inferior */ + READ_MEMORY ((CORE_ADDR) temp_task, atcb); + + /* print the Ada task id */ + printf_filtered ("Ada Task: %p\n", temp_task); + + /* print the name of the task */ + if (atcb.image.P_ARRAY != NULL) + { + READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_BOUNDS), bounds); + bounds[1] = EXTRACT_INT (bounds[1]); + read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_ARRAY), + (char *) &image, bounds[1]); + printf_filtered ("Name: %.*s\n", bounds[1], image); + } + else + printf_filtered ("\n"); + + /* print the thread id */ + + if ((long) pt->thread < 65536) + printf_filtered ("Thread: %ld\n", (long int) pt->thread); + else + printf_filtered ("Thread: %p\n", pt->thread); + + if ((long) pt->lwp != 0) + { + if ((long) pt->lwp < 65536) + printf_filtered ("LWP: %ld\n", (long int) pt->lwp); + else + printf_filtered ("LWP: %p\n", pt->lwp); + } + + /* print the parent gdb task id */ + num = get_entry_number (EXTRACT_ADDRESS (atcb.parent)); + if (num != 0) + { + printf_filtered ("Parent: %d", num); + pt2 = get_entry_vptr (num); + READ_MEMORY ((CORE_ADDR) pt2->task_id, atcb2); + + /* print the name of the task */ + if (atcb2.image.P_ARRAY != NULL) + { + READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_BOUNDS), + bounds); + bounds[1] = EXTRACT_INT (bounds[1]); + read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_ARRAY), + (char *) &image, bounds[1]); + printf_filtered (" (%.*s)\n", bounds[1], image); + } + else + printf_filtered ("\n"); + } + else + printf_filtered ("No parent\n"); + + /* print the base priority of the task */ + printf_filtered ("Base Priority: %d\n", EXTRACT_INT (atcb.priority)); + + /* print the current state of the task */ + + /* check if this task is accepting a rendezvous */ + if (atcb.call == NULL) + caller = NULL; + else + { + READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.call), call); + caller = EXTRACT_ADDRESS (call.self); + } + + if (caller != NULL) + { + num = get_entry_number (caller); + printf_filtered ("Accepting rendezvous with %d", num); + + if (num != 0) + { + pt2 = get_entry_vptr (num); + READ_MEMORY ((CORE_ADDR) pt2->task_id, atcb2); + + /* print the name of the task */ + if (atcb2.image.P_ARRAY != NULL) + { + READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_BOUNDS), + bounds); + bounds[1] = EXTRACT_INT (bounds[1]); + read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_ARRAY), + (char *) &image, bounds[1]); + printf_filtered (" (%.*s)\n", bounds[1], image); + } + else + printf_filtered ("\n"); + } + else + printf_filtered ("\n"); + } + else + printf_filtered ("State: %s\n", ada_long_task_states[atcb.state]); +} + +#if 0 + +/* A useful function that shows the alignment of all the fields in the + tasks_fields structure + */ + +print_align (void) +{ + struct task_fields tf; + void *tf_base = &(tf); + void *tf_state = &(tf.state); + void *tf_entry_num = &(tf.entry_num); + void *tf_parent = &(tf.parent); + void *tf_priority = &(tf.priority); + void *tf_current_priority = &(tf.current_priority); + void *tf_image = &(tf.image); + void *tf_call = &(tf.call); + void *tf_thread = &(tf.thread); + void *tf_lwp = &(tf.lwp); + printf_filtered ("\n"); + printf_filtered ("(tf_base = 0x%x)\n", tf_base); + printf_filtered ("task_fields.entry_num at %3d (0x%x)\n", + tf_entry_num - tf_base, tf_entry_num); + printf_filtered ("task_fields.state at %3d (0x%x)\n", + tf_state - tf_base, tf_state); + printf_filtered ("task_fields.parent at %3d (0x%x)\n", + tf_parent - tf_base, tf_parent); + printf_filtered ("task_fields.priority at %3d (0x%x)\n", + tf_priority - tf_base, tf_priority); + printf_filtered ("task_fields.current_priority at %3d (0x%x)\n", + tf_current_priority - tf_base, tf_current_priority); + printf_filtered ("task_fields.image at %3d (0x%x)\n", + tf_image - tf_base, tf_image); + printf_filtered ("task_fields.call at %3d (0x%x)\n", + tf_call - tf_base, tf_call); + printf_filtered ("task_fields.thread at %3d (0x%x)\n", + tf_thread - tf_base, tf_thread); + printf_filtered ("task_fields.lwp at %3d (0x%x)\n", + tf_lwp - tf_base, tf_lwp); + printf_filtered ("\n"); +} +#endif + +/* Print information about currently known tasks */ + +static void +info_tasks (char *arg, int from_tty) +{ + struct value *val; + int i, task_number, state; + void *temp_task, *temp_tasks[MAX_NUMBER_OF_KNOWN_TASKS]; + struct task_entry *pt; + void *self_id, *caller, *thread_id = NULL; + struct task_fields atcb; + struct entry_call call; + int bounds[2]; + char image[256]; + int size; + char car; + +#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET) + pthreadTeb_t thr; + gdb_gregset_t regs; +#endif + + static struct symbol *sym; + static struct minimal_symbol *msym; + static void *known_tasks_addr = NULL; + + int init_only = gdbtk_task_initialization; + gdbtk_task_initialization = 0; + + task_number = 0; + + if (PIDGET (inferior_ptid) == 0) + { + printf_filtered ("The program is not being run under gdb. "); + printf_filtered ("Use 'run' or 'attach' first.\n"); + return; + } + + if (ada__tasks_check_symbol_table) + { + thread_support = 0; +#if (defined(__alpha__) && defined(__osf__) & !defined(VXWORKS_TARGET)) || \ + defined (_AIX) + thread_support = 1; +#endif + + msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL); + if (msym != NULL) + known_tasks_addr = (void *) SYMBOL_VALUE_ADDRESS (msym); + else +#ifndef VXWORKS_TARGET + return; +#else + { + if (target_lookup_symbol (KNOWN_TASKS_NAME, &known_tasks_addr) != 0) + return; + } +#endif + + ada__tasks_check_symbol_table = 0; + } + + if (known_tasks_addr == NULL) + return; + +#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__) || defined (hpux)) + if (thread_support) +#endif + thread_id = GET_CURRENT_THREAD (); + + /* then we get a list of tasks created */ + + init_task_list (); + + READ_MEMORY ((CORE_ADDR) known_tasks_addr, temp_tasks); + + for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++) + { + temp_task = EXTRACT_ADDRESS (temp_tasks[i]); + + if (temp_task != NULL) + { + task_number = get_entry_number (temp_task); + if (task_number == 0) + task_number = add_task_entry (temp_task, i); + } + } + + /* Return without printing anything if this function was called in + order to init GDBTK tasking. */ + + if (init_only) + return; + + /* print the header */ + +#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET) + printf_filtered + (" ID TID P-ID Pri Stack %% State Name\n"); +#else + printf_filtered (" ID TID P-ID Pri State Name\n"); +#endif + + /* Now that we have a list of task id's, we can print them */ + pt = task_list; + while (pt) + { + temp_task = pt->task_id; + + /* read the atcb in the inferior */ + READ_MEMORY ((CORE_ADDR) temp_task, atcb); + + /* store the thread id for future use */ + pt->thread = EXTRACT_ADDRESS (atcb.thread); + +#if defined (linux) + pt->lwp = (void *) THREAD_TO_PID (atcb.thread, 0); +#else + pt->lwp = EXTRACT_ADDRESS (atcb.lwp); +#endif + + /* print a star if this task is the current one */ + if (thread_id) +#if defined (__WIN32__) || defined (SGI) || defined (hpux) + printf_filtered (pt->lwp == thread_id ? "*" : " "); +#else + printf_filtered (pt->thread == thread_id ? "*" : " "); +#endif + + /* print the gdb task id */ + printf_filtered ("%3d", pt->task_num); + + /* print the Ada task id */ +#ifndef VXWORKS_TARGET + printf_filtered (" %9lx", (long) temp_task); +#else +#ifdef TARGET_64 + printf_filtered (" %#9lx", (unsigned long) pt->thread & 0x3ffffffffff); +#else + printf_filtered (" %#9lx", (long) pt->thread); +#endif +#endif + + /* print the parent gdb task id */ + printf_filtered + (" %4d", get_entry_number (EXTRACT_ADDRESS (atcb.parent))); + + /* print the base priority of the task */ + printf_filtered (" %3d", EXTRACT_INT (atcb.priority)); + +#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET) + if (pt->task_num == 1 || atcb.state == Terminated) + { + printf_filtered (" Unknown"); + goto next; + } + + read_memory ((CORE_ADDR) atcb.thread, &thr, sizeof (thr)); + current_thread = atcb.thread; + regs.regs[SP_REGNUM] = 0; + if (dec_thread_get_registers (®s, NULL) == 0) + { + pt->stack_per = (100 * ((long) thr.__stack_base - + regs.regs[SP_REGNUM])) / thr.__stack_size; + /* if the thread is terminated but still there, the + stack_base/size values are erroneous. Try to patch it */ + if (pt->stack_per < 0 || pt->stack_per > 100) + pt->stack_per = 0; + } + + /* print information about stack space used in the thread */ + if (thr.__stack_size < 1024 * 1024) + { + size = thr.__stack_size / 1024; + car = 'K'; + } + else if (thr.__stack_size < 1024 * 1024 * 1024) + { + size = thr.__stack_size / 1024 / 1024; + car = 'M'; + } + else /* Who knows... */ + { + size = thr.__stack_size / 1024 / 1024 / 1024; + car = 'G'; + } + printf_filtered (" %4d%c %2d", size, car, pt->stack_per); + next: +#endif + + /* print the current state of the task */ + + /* check if this task is accepting a rendezvous */ + if (atcb.call == NULL) + caller = NULL; + else + { + READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.call), call); + caller = EXTRACT_ADDRESS (call.self); + } + + if (caller != NULL) + printf_filtered (" Accepting RV with %-4d", + get_entry_number (caller)); + else + { + state = atcb.state; +#if defined (__WIN32__) || defined (SGI) || defined (hpux) + if (state == Runnable && (thread_id && pt->lwp == thread_id)) +#else + if (state == Runnable && (thread_id && pt->thread == thread_id)) +#endif + /* Replace "Runnable" by "Running" if this is the current task */ + printf_filtered (" %-22s", "Running"); + else + printf_filtered (" %-22s", ada_task_states[state]); + } + + /* finally, print the name of the task */ + if (atcb.image.P_ARRAY != NULL) + { + READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_BOUNDS), + bounds); + bounds[1] = EXTRACT_INT (bounds[1]); + read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_ARRAY), + (char *) &image, bounds[1]); + printf_filtered (" %.*s\n", bounds[1], image); + } + else + printf_filtered (" \n"); + + pt = pt->next_task; + } +} + +/* Task list initialization for GDB-Tk. We basically use info_tasks() + to initialize our variables, but abort that function before we + actually print anything. */ + +int +gdbtk_tcl_tasks_initialize (void) +{ + gdbtk_task_initialization = 1; + info_tasks ("", gdb_stdout); + + return (task_list != NULL); +} + +static void +info_tasks_command (char *arg, int from_tty) +{ + if (arg == NULL || *arg == '\000') + info_tasks (arg, from_tty); + else + info_task (arg, from_tty); +} + +/* Switch from one thread to another. */ + +static void +switch_to_thread (ptid_t ptid) +{ + if (ptid_equal (ptid, inferior_ptid)) + return; + + inferior_ptid = ptid; + flush_cached_frames (); + registers_changed (); + stop_pc = read_pc (); + select_frame (get_current_frame ()); +} + +/* Switch to a specified task. */ + +static int +task_switch (void *tid, void *lwpid) +{ + int res = 0, pid; + + if (thread_support) + { + flush_cached_frames (); + + if (current_task != current_task_id) + { + res = THREAD_FETCH_REGISTERS (); + } + else + { +#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)) + supply_gregset (&gregset_saved); + supply_fpregset (&fpregset_saved); +#endif + } + + if (res == 0) + stop_pc = read_pc (); + select_frame (get_current_frame ()); + return res; + } + + return -1; +} + +static void +task_command (char *tidstr, int from_tty) +{ + int num; + struct task_entry *e; + + if (!tidstr) + error ("Please specify a task ID. Use the \"info tasks\" command to\n" + "see the IDs of currently known tasks."); + + num = atoi (tidstr); + e = get_entry_vptr (num); + + if (e == NULL) + error ("Task ID %d not known. Use the \"info tasks\" command to\n" + "see the IDs of currently known tasks.", num); + + if (current_task_id == -1) + { +#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)) + fill_gregset (&gregset_saved, -1); + fill_fpregset (&fpregset_saved, -1); +#endif + current_task_id = get_current_task (); + } + + current_task = num; + current_task_index = e->known_tasks_index; + current_thread = e->thread; + current_lwp = e->lwp; + if (task_switch (e->thread, e->lwp) == 0) + { + /* FIXME: find_printable_frame should be defined in frame.h, and + implemented in ada-lang.c */ + /* find_printable_frame (deprecated_selected_frame, frame_relative_level (deprecated_selected_frame)); */ + printf_filtered ("[Switching to task %d]\n", num); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); + } + else + printf_filtered ("Unable to switch to task %d\n", num); +} + +void +_initialize_tasks (void) +{ + static struct cmd_list_element *task_cmd_list = NULL; + extern struct cmd_list_element *cmdlist; + + add_info ("tasks", info_tasks_command, + "Without argument: list all known Ada tasks, with status information.\n" + "info tasks n: print detailed information of task n.\n"); + + add_prefix_cmd ("task", class_run, task_command, + "Use this command to switch between tasks.\n\ + The new task ID must be currently known.", &task_cmd_list, "task ", 1, &cmdlist); +} diff --git a/contrib/gdb/gdb/ada-typeprint.c b/contrib/gdb/gdb/ada-typeprint.c new file mode 100644 index 00000000000..19393541d5c --- /dev/null +++ b/contrib/gdb/gdb/ada-typeprint.c @@ -0,0 +1,852 @@ +/* Support for printing Ada types for GDB, the GNU debugger. + Copyright 1986, 1988, 1989, 1991, 1997, 2003 Free Software + Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "gdb_obstack.h" +#include "bfd.h" /* Binary File Description */ +#include "symtab.h" +#include "gdbtypes.h" +#include "expression.h" +#include "value.h" +#include "gdbcore.h" +#include "target.h" +#include "command.h" +#include "gdbcmd.h" +#include "language.h" +#include "demangle.h" +#include "c-lang.h" +#include "typeprint.h" +#include "ada-lang.h" + +#include +#include "gdb_string.h" +#include + +static int print_record_field_types (struct type *, struct type *, + struct ui_file *, int, int); + +static void print_array_type (struct type *, struct ui_file *, int, int); + +static void print_choices (struct type *, int, struct ui_file *, + struct type *); + +static void print_range (struct type *, struct ui_file *); + +static void print_range_bound (struct type *, char *, int *, + struct ui_file *); + +static void +print_dynamic_range_bound (struct type *, const char *, int, + const char *, struct ui_file *); + +static void print_range_type_named (char *, struct ui_file *); + + + +static char *name_buffer; +static int name_buffer_len; + +/* The (demangled) Ada name of TYPE. This value persists until the + next call. */ + +static char * +demangled_type_name (struct type *type) +{ + if (ada_type_name (type) == NULL) + return NULL; + else + { + char *raw_name = ada_type_name (type); + char *s, *q; + + if (name_buffer == NULL || name_buffer_len <= strlen (raw_name)) + { + name_buffer_len = 16 + 2 * strlen (raw_name); + name_buffer = xrealloc (name_buffer, name_buffer_len); + } + strcpy (name_buffer, raw_name); + + s = (char *) strstr (name_buffer, "___"); + if (s != NULL) + *s = '\0'; + + s = name_buffer + strlen (name_buffer) - 1; + while (s > name_buffer && (s[0] != '_' || s[-1] != '_')) + s -= 1; + + if (s == name_buffer) + return name_buffer; + + if (!islower (s[1])) + return NULL; + + for (s = q = name_buffer; *s != '\0'; q += 1) + { + if (s[0] == '_' && s[1] == '_') + { + *q = '.'; + s += 2; + } + else + { + *q = *s; + s += 1; + } + } + *q = '\0'; + return name_buffer; + } +} + + +/* Print a description of a type in the format of a + typedef for the current language. + NEW is the new name for a type TYPE. */ + +void +ada_typedef_print (struct type *type, struct symbol *new, + struct ui_file *stream) +{ + fprintf_filtered (stream, "type %.*s is ", + ada_name_prefix_len (SYMBOL_PRINT_NAME (new)), + SYMBOL_PRINT_NAME (new)); + type_print (type, "", stream, 1); +} + +/* Print range type TYPE on STREAM. */ + +static void +print_range (struct type *type, struct ui_file *stream) +{ + struct type *target_type; + target_type = TYPE_TARGET_TYPE (type); + if (target_type == NULL) + target_type = type; + + switch (TYPE_CODE (target_type)) + { + case TYPE_CODE_RANGE: + case TYPE_CODE_INT: + case TYPE_CODE_BOOL: + case TYPE_CODE_CHAR: + case TYPE_CODE_ENUM: + break; + default: + target_type = builtin_type_ada_int; + break; + } + + if (TYPE_NFIELDS (type) < 2) + { + /* A range needs at least 2 bounds to be printed. If there are less + than 2, just print the type name instead of the range itself. + This check handles cases such as characters, for example. + + Note that if the name is not defined, then we don't print anything. + */ + fprintf_filtered (stream, "%.*s", + ada_name_prefix_len (TYPE_NAME (type)), + TYPE_NAME (type)); + } + else + { + /* We extract the range type bounds respectively from the first element + and the last element of the type->fields array */ + const LONGEST lower_bound = (LONGEST) TYPE_LOW_BOUND (type); + const LONGEST upper_bound = + (LONGEST) TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1); + + ada_print_scalar (target_type, lower_bound, stream); + fprintf_filtered (stream, " .. "); + ada_print_scalar (target_type, upper_bound, stream); + } +} + +/* Print the number or discriminant bound at BOUNDS+*N on STREAM, and + set *N past the bound and its delimiter, if any. */ + +static void +print_range_bound (struct type *type, char *bounds, int *n, + struct ui_file *stream) +{ + LONGEST B; + if (ada_scan_number (bounds, *n, &B, n)) + { + ada_print_scalar (type, B, stream); + if (bounds[*n] == '_') + *n += 2; + } + else + { + int bound_len; + char *bound = bounds + *n; + char *pend; + + pend = strstr (bound, "__"); + if (pend == NULL) + *n += bound_len = strlen (bound); + else + { + bound_len = pend - bound; + *n += bound_len + 2; + } + fprintf_filtered (stream, "%.*s", bound_len, bound); + } +} + +/* Assuming NAME[0 .. NAME_LEN-1] is the name of a range type, print + the value (if found) of the bound indicated by SUFFIX ("___L" or + "___U") according to the ___XD conventions. */ + +static void +print_dynamic_range_bound (struct type *type, const char *name, int name_len, + const char *suffix, struct ui_file *stream) +{ + static char *name_buf = NULL; + static size_t name_buf_len = 0; + LONGEST B; + int OK; + + GROW_VECT (name_buf, name_buf_len, name_len + strlen (suffix) + 1); + strncpy (name_buf, name, name_len); + strcpy (name_buf + name_len, suffix); + + B = get_int_var_value (name_buf, 0, &OK); + if (OK) + ada_print_scalar (type, B, stream); + else + fprintf_filtered (stream, "?"); +} + +/* Print the range type named NAME. */ + +static void +print_range_type_named (char *name, struct ui_file *stream) +{ + struct type *raw_type = ada_find_any_type (name); + struct type *base_type; + LONGEST low, high; + char *subtype_info; + + if (raw_type == NULL) + base_type = builtin_type_int; + else if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE) + base_type = TYPE_TARGET_TYPE (raw_type); + else + base_type = raw_type; + + subtype_info = strstr (name, "___XD"); + if (subtype_info == NULL && raw_type == NULL) + fprintf_filtered (stream, "? .. ?"); + else if (subtype_info == NULL) + print_range (raw_type, stream); + else + { + int prefix_len = subtype_info - name; + char *bounds_str; + int n; + + subtype_info += 5; + bounds_str = strchr (subtype_info, '_'); + n = 1; + + if (*subtype_info == 'L') + { + print_range_bound (raw_type, bounds_str, &n, stream); + subtype_info += 1; + } + else + print_dynamic_range_bound (raw_type, name, prefix_len, "___L", + stream); + + fprintf_filtered (stream, " .. "); + + if (*subtype_info == 'U') + print_range_bound (raw_type, bounds_str, &n, stream); + else + print_dynamic_range_bound (raw_type, name, prefix_len, "___U", + stream); + } +} + +/* Print enumerated type TYPE on STREAM. */ + +static void +print_enum_type (struct type *type, struct ui_file *stream) +{ + int len = TYPE_NFIELDS (type); + int i, lastval; + + fprintf_filtered (stream, "("); + wrap_here (" "); + + lastval = 0; + for (i = 0; i < len; i++) + { + QUIT; + if (i) + fprintf_filtered (stream, ", "); + wrap_here (" "); + fputs_filtered (ada_enum_name (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 += 1; + } + fprintf_filtered (stream, ")"); +} + +/* Print representation of Ada fixed-point type TYPE on STREAM. */ + +static void +print_fixed_point_type (struct type *type, struct ui_file *stream) +{ + DOUBLEST delta = ada_delta (type); + DOUBLEST small = ada_fixed_to_float (type, 1.0); + + if (delta < 0.0) + fprintf_filtered (stream, "delta ??"); + else + { + fprintf_filtered (stream, "delta %g", (double) delta); + if (delta != small) + fprintf_filtered (stream, " <'small = %g>", (double) small); + } +} + +/* Print representation of special VAX floating-point type TYPE on STREAM. */ + +static void +print_vax_floating_point_type (struct type *type, struct ui_file *stream) +{ + fprintf_filtered (stream, "", + ada_vax_float_type_suffix (type)); +} + +/* Print simple (constrained) array type TYPE on STREAM. LEVEL is the + recursion (indentation) level, in case the element type itself has + nested structure, and SHOW is the number of levels of internal + structure to show (see ada_print_type). */ + +static void +print_array_type (struct type *type, struct ui_file *stream, int show, + int level) +{ + int bitsize; + int n_indices; + + bitsize = 0; + fprintf_filtered (stream, "array ("); + + n_indices = -1; + if (show < 0) + fprintf_filtered (stream, "..."); + else + { + if (ada_is_packed_array_type (type)) + type = ada_coerce_to_simple_array_type (type); + if (ada_is_simple_array (type)) + { + struct type *range_desc_type = + ada_find_parallel_type (type, "___XA"); + struct type *arr_type; + + bitsize = 0; + if (range_desc_type == NULL) + { + for (arr_type = type; TYPE_CODE (arr_type) == TYPE_CODE_ARRAY; + arr_type = TYPE_TARGET_TYPE (arr_type)) + { + if (arr_type != type) + fprintf_filtered (stream, ", "); + print_range (TYPE_INDEX_TYPE (arr_type), stream); + if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0) + bitsize = TYPE_FIELD_BITSIZE (arr_type, 0); + } + } + else + { + int k; + n_indices = TYPE_NFIELDS (range_desc_type); + for (k = 0, arr_type = type; + k < n_indices; + k += 1, arr_type = TYPE_TARGET_TYPE (arr_type)) + { + if (k > 0) + fprintf_filtered (stream, ", "); + print_range_type_named (TYPE_FIELD_NAME + (range_desc_type, k), stream); + if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0) + bitsize = TYPE_FIELD_BITSIZE (arr_type, 0); + } + } + } + else + { + int i, i0; + for (i = i0 = ada_array_arity (type); i > 0; i -= 1) + fprintf_filtered (stream, "%s<>", i == i0 ? "" : ", "); + } + } + + fprintf_filtered (stream, ") of "); + wrap_here (""); + ada_print_type (ada_array_element_type (type, n_indices), "", stream, + show == 0 ? 0 : show - 1, level + 1); + if (bitsize > 0) + fprintf_filtered (stream, " ", bitsize); +} + +/* Print the choices encoded by field FIELD_NUM of variant-part TYPE on + STREAM, assuming the VAL_TYPE is the type of the values. */ + +static void +print_choices (struct type *type, int field_num, struct ui_file *stream, + struct type *val_type) +{ + int have_output; + int p; + const char *name = TYPE_FIELD_NAME (type, field_num); + + have_output = 0; + + /* Skip over leading 'V': NOTE soon to be obsolete. */ + if (name[0] == 'V') + { + if (!ada_scan_number (name, 1, NULL, &p)) + goto Huh; + } + else + p = 0; + + while (1) + { + switch (name[p]) + { + default: + return; + case 'S': + case 'R': + case 'O': + if (have_output) + fprintf_filtered (stream, " | "); + have_output = 1; + break; + } + + switch (name[p]) + { + case 'S': + { + LONGEST W; + if (!ada_scan_number (name, p + 1, &W, &p)) + goto Huh; + ada_print_scalar (val_type, W, stream); + break; + } + case 'R': + { + LONGEST L, U; + if (!ada_scan_number (name, p + 1, &L, &p) + || name[p] != 'T' || !ada_scan_number (name, p + 1, &U, &p)) + goto Huh; + ada_print_scalar (val_type, L, stream); + fprintf_filtered (stream, " .. "); + ada_print_scalar (val_type, U, stream); + break; + } + case 'O': + fprintf_filtered (stream, "others"); + p += 1; + break; + } + } + +Huh: + fprintf_filtered (stream, "??"); + +} + +/* Assuming that field FIELD_NUM of TYPE is a VARIANTS field whose + discriminant is contained in OUTER_TYPE, print its variants on STREAM. + LEVEL is the recursion + (indentation) level, in case any of the fields themselves have + nested structure, and SHOW is the number of levels of internal structure + to show (see ada_print_type). For this purpose, fields nested in a + variant part are taken to be at the same level as the fields + immediately outside the variant part. */ + +static void +print_variant_clauses (struct type *type, int field_num, + struct type *outer_type, struct ui_file *stream, + int show, int level) +{ + int i; + struct type *var_type; + struct type *discr_type; + + var_type = TYPE_FIELD_TYPE (type, field_num); + discr_type = ada_variant_discrim_type (var_type, outer_type); + + if (TYPE_CODE (var_type) == TYPE_CODE_PTR) + { + var_type = TYPE_TARGET_TYPE (var_type); + if (TYPE_FLAGS (var_type) & TYPE_FLAG_STUB) + { + var_type = ada_find_parallel_type (var_type, "___XVU"); + if (var_type == NULL) + return; + } + } + + for (i = 0; i < TYPE_NFIELDS (var_type); i += 1) + { + fprintf_filtered (stream, "\n%*swhen ", level + 4, ""); + print_choices (var_type, i, stream, discr_type); + fprintf_filtered (stream, " =>"); + if (print_record_field_types (TYPE_FIELD_TYPE (var_type, i), + outer_type, stream, show, level + 4) <= 0) + fprintf_filtered (stream, " null;"); + } +} + +/* Assuming that field FIELD_NUM of TYPE is a variant part whose + discriminants are contained in OUTER_TYPE, print a description of it + on STREAM. LEVEL is the recursion (indentation) level, in case any of + the fields themselves have nested structure, and SHOW is the number of + levels of internal structure to show (see ada_print_type). For this + purpose, fields nested in a variant part are taken to be at the same + level as the fields immediately outside the variant part. */ + +static void +print_variant_part (struct type *type, int field_num, struct type *outer_type, + struct ui_file *stream, int show, int level) +{ + fprintf_filtered (stream, "\n%*scase %s is", level + 4, "", + ada_variant_discrim_name + (TYPE_FIELD_TYPE (type, field_num))); + print_variant_clauses (type, field_num, outer_type, stream, show, + level + 4); + fprintf_filtered (stream, "\n%*send case;", level + 4, ""); +} + +/* Print a description on STREAM of the fields in record type TYPE, whose + discriminants are in OUTER_TYPE. LEVEL is the recursion (indentation) + level, in case any of the fields themselves have nested structure, + and SHOW is the number of levels of internal structure to show + (see ada_print_type). Does not print parent type information of TYPE. + Returns 0 if no fields printed, -1 for an incomplete type, else > 0. + Prints each field beginning on a new line, but does not put a new line at + end. */ + +static int +print_record_field_types (struct type *type, struct type *outer_type, + struct ui_file *stream, int show, int level) +{ + int len, i, flds; + + flds = 0; + len = TYPE_NFIELDS (type); + + if (len == 0 && (TYPE_FLAGS (type) & TYPE_FLAG_STUB) != 0) + return -1; + + for (i = 0; i < len; i += 1) + { + QUIT; + + if (ada_is_parent_field (type, i) || ada_is_ignored_field (type, i)) + ; + else if (ada_is_wrapper_field (type, i)) + flds += print_record_field_types (TYPE_FIELD_TYPE (type, i), type, + stream, show, level); + else if (ada_is_variant_part (type, i)) + { + print_variant_part (type, i, outer_type, stream, show, level); + flds = 1; + } + else + { + flds += 1; + fprintf_filtered (stream, "\n%*s", level + 4, ""); + ada_print_type (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), + stream, show - 1, level + 4); + fprintf_filtered (stream, ";"); + } + } + + return flds; +} + +/* Print record type TYPE on STREAM. LEVEL is the recursion (indentation) + level, in case the element type itself has nested structure, and SHOW is + the number of levels of internal structure to show (see ada_print_type). */ + +static void +print_record_type (struct type *type0, struct ui_file *stream, int show, + int level) +{ + struct type *parent_type; + struct type *type; + + type = type0; + if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) + { + struct type *type1 = ada_find_parallel_type (type, "___XVE"); + if (type1 != NULL) + type = type1; + } + + parent_type = ada_parent_type (type); + if (ada_type_name (parent_type) != NULL) + fprintf_filtered (stream, "new %s with ", + demangled_type_name (parent_type)); + else if (parent_type == NULL && ada_is_tagged_type (type)) + fprintf_filtered (stream, "tagged "); + + fprintf_filtered (stream, "record"); + + if (show < 0) + fprintf_filtered (stream, " ... end record"); + else + { + int flds; + + flds = 0; + if (parent_type != NULL && ada_type_name (parent_type) == NULL) + flds += print_record_field_types (parent_type, parent_type, + stream, show, level); + flds += print_record_field_types (type, type, stream, show, level); + + if (flds > 0) + fprintf_filtered (stream, "\n%*send record", level, ""); + else if (flds < 0) + fprintf_filtered (stream, " end record"); + else + fprintf_filtered (stream, " null; end record"); + } +} + +/* Print the unchecked union type TYPE in something resembling Ada + format on STREAM. LEVEL is the recursion (indentation) level + in case the element type itself has nested structure, and SHOW is the + number of levels of internal structure to show (see ada_print_type). */ +static void +print_unchecked_union_type (struct type *type, struct ui_file *stream, + int show, int level) +{ + fprintf_filtered (stream, "record (?) is"); + + if (show < 0) + fprintf_filtered (stream, " ... end record"); + else if (TYPE_NFIELDS (type) == 0) + fprintf_filtered (stream, " null; end record"); + else + { + int i; + + fprintf_filtered (stream, "\n%*scase ? is", level + 4, ""); + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + { + fprintf_filtered (stream, "\n%*swhen ? =>\n%*s", level + 8, "", + level + 12, ""); + ada_print_type (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), + stream, show - 1, level + 12); + fprintf_filtered (stream, ";"); + } + + fprintf_filtered (stream, "\n%*send case;\n%*send record", + level + 4, "", level, ""); + } +} + + + +/* Print function or procedure type TYPE on STREAM. Make it a header + for function or procedure NAME if NAME is not null. */ + +static void +print_func_type (struct type *type, struct ui_file *stream, char *name) +{ + int i, len = TYPE_NFIELDS (type); + + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID) + fprintf_filtered (stream, "procedure"); + else + fprintf_filtered (stream, "function"); + + if (name != NULL && name[0] != '\0') + fprintf_filtered (stream, " %s", name); + + if (len > 0) + { + fprintf_filtered (stream, " ("); + for (i = 0; i < len; i += 1) + { + if (i > 0) + { + fputs_filtered ("; ", stream); + wrap_here (" "); + } + fprintf_filtered (stream, "a%d: ", i + 1); + ada_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); + } + fprintf_filtered (stream, ")"); + } + + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) + { + fprintf_filtered (stream, " return "); + ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0); + } +} + + +/* Print a description of a type TYPE0. + Output goes to STREAM (via stdio). + If VARSTRING is a non-empty string, print as an Ada variable/field + declaration. + SHOW+1 is the maximum number of levels of internal type structure + to show (this applies to record types, enumerated types, and + array types). + SHOW is the number of levels of internal type structure to show + when there is a type name for the SHOWth deepest level (0th is + outer level). + When SHOW<0, no inner structure is shown. + LEVEL indicates level of recursion (for nested definitions). */ + +void +ada_print_type (struct type *type0, char *varstring, struct ui_file *stream, + int show, int level) +{ + enum type_code code; + int demangled_args; + struct type *type = ada_completed_type (ada_get_base_type (type0)); + char *type_name = demangled_type_name (type); + int is_var_decl = (varstring != NULL && varstring[0] != '\0'); + + if (type == NULL) + { + if (is_var_decl) + fprintf_filtered (stream, "%.*s: ", + ada_name_prefix_len (varstring), varstring); + fprintf_filtered (stream, ""); + return; + } + + if (show > 0) + CHECK_TYPEDEF (type); + + if (is_var_decl && TYPE_CODE (type) != TYPE_CODE_FUNC) + fprintf_filtered (stream, "%.*s: ", + ada_name_prefix_len (varstring), varstring); + + if (type_name != NULL && show <= 0) + { + fprintf_filtered (stream, "%.*s", + ada_name_prefix_len (type_name), type_name); + return; + } + + if (ada_is_aligner_type (type)) + ada_print_type (ada_aligned_type (type), "", stream, show, level); + else if (ada_is_packed_array_type (type)) + print_array_type (type, stream, show, level); + else + switch (TYPE_CODE (type)) + { + default: + fprintf_filtered (stream, "<"); + c_print_type (type, "", stream, show, level); + fprintf_filtered (stream, ">"); + break; + case TYPE_CODE_PTR: + fprintf_filtered (stream, "access "); + ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level); + break; + case TYPE_CODE_REF: + fprintf_filtered (stream, " "); + ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level); + break; + case TYPE_CODE_ARRAY: + print_array_type (type, stream, show, level); + break; + case TYPE_CODE_INT: + if (ada_is_fixed_point_type (type)) + print_fixed_point_type (type, stream); + else if (ada_is_vax_floating_type (type)) + print_vax_floating_point_type (type, stream); + else + { + char *name = ada_type_name (type); + if (!ada_is_range_type_name (name)) + fprintf_filtered (stream, "<%d-byte integer>", + TYPE_LENGTH (type)); + else + { + fprintf_filtered (stream, "range "); + print_range_type_named (name, stream); + } + } + break; + case TYPE_CODE_RANGE: + if (ada_is_fixed_point_type (type)) + print_fixed_point_type (type, stream); + else if (ada_is_vax_floating_type (type)) + print_vax_floating_point_type (type, stream); + else if (ada_is_modular_type (type)) + fprintf_filtered (stream, "mod %ld", (long) ada_modulus (type)); + else + { + fprintf_filtered (stream, "range "); + print_range (type, stream); + } + break; + case TYPE_CODE_FLT: + fprintf_filtered (stream, "<%d-byte float>", TYPE_LENGTH (type)); + break; + case TYPE_CODE_ENUM: + if (show < 0) + fprintf_filtered (stream, "(...)"); + else + print_enum_type (type, stream); + break; + case TYPE_CODE_STRUCT: + if (ada_is_array_descriptor (type)) + print_array_type (type, stream, show, level); + else if (ada_is_bogus_array_descriptor (type)) + fprintf_filtered (stream, + "array (?) of ? ()"); + else + print_record_type (type, stream, show, level); + break; + case TYPE_CODE_UNION: + print_unchecked_union_type (type, stream, show, level); + break; + case TYPE_CODE_FUNC: + print_func_type (type, stream, varstring); + break; + } +} diff --git a/contrib/gdb/gdb/ada-valprint.c b/contrib/gdb/gdb/ada-valprint.c new file mode 100644 index 00000000000..f5f411898b2 --- /dev/null +++ b/contrib/gdb/gdb/ada-valprint.c @@ -0,0 +1,987 @@ +/* Support for printing Ada values for GDB, the GNU debugger. + Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1997, 2001 + Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include "defs.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "expression.h" +#include "value.h" +#include "demangle.h" +#include "valprint.h" +#include "language.h" +#include "annotate.h" +#include "ada-lang.h" +#include "c-lang.h" +#include "infcall.h" + +/* Encapsulates arguments to ada_val_print. */ +struct ada_val_print_args +{ + struct type *type; + char *valaddr0; + int embedded_offset; + CORE_ADDR address; + struct ui_file *stream; + int format; + int deref_ref; + int recurse; + enum val_prettyprint pretty; +}; + +static void print_record (struct type *, char *, struct ui_file *, int, + int, enum val_prettyprint); + +static int print_field_values (struct type *, char *, struct ui_file *, + int, int, enum val_prettyprint, + int, struct type *, char *); + +static int print_variant_part (struct type *, int, char *, + struct ui_file *, int, int, + enum val_prettyprint, int, struct type *, + char *); + +static void val_print_packed_array_elements (struct type *, char *valaddr, + int, struct ui_file *, int, int, + enum val_prettyprint); + +static void adjust_type_signedness (struct type *); + +static int ada_val_print_stub (void *args0); + +static int ada_val_print_1 (struct type *, char *, int, CORE_ADDR, + struct ui_file *, int, int, int, + enum val_prettyprint); + + +/* Make TYPE unsigned if its range of values includes no negatives. */ +static void +adjust_type_signedness (struct type *type) +{ + if (type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE + && TYPE_LOW_BOUND (type) >= 0) + TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; +} + +/* Assuming TYPE is a simple array type, prints its lower bound on STREAM, + if non-standard (i.e., other than 1 for numbers, other than lower bound + of index type for enumerated type). Returns 1 if something printed, + otherwise 0. */ + +static int +print_optional_low_bound (struct ui_file *stream, struct type *type) +{ + struct type *index_type; + long low_bound; + + index_type = TYPE_INDEX_TYPE (type); + low_bound = 0; + + if (index_type == NULL) + return 0; + if (TYPE_CODE (index_type) == TYPE_CODE_RANGE) + { + low_bound = TYPE_LOW_BOUND (index_type); + index_type = TYPE_TARGET_TYPE (index_type); + } + else + return 0; + + switch (TYPE_CODE (index_type)) + { + case TYPE_CODE_ENUM: + if (low_bound == TYPE_FIELD_BITPOS (index_type, 0)) + return 0; + break; + case TYPE_CODE_UNDEF: + index_type = builtin_type_long; + /* FALL THROUGH */ + default: + if (low_bound == 1) + return 0; + break; + } + + ada_print_scalar (index_type, (LONGEST) low_bound, stream); + fprintf_filtered (stream, " => "); + return 1; +} + +/* Version of val_print_array_elements for GNAT-style packed arrays. + Prints elements of packed array of type TYPE at bit offset + BITOFFSET from VALADDR on STREAM. Formats according to FORMAT and + separates with commas. RECURSE is the recursion (nesting) level. + If PRETTY, uses "prettier" format. TYPE must have been decoded (as + by ada_coerce_to_simple_array). */ + +static void +val_print_packed_array_elements (struct type *type, char *valaddr, + int bitoffset, struct ui_file *stream, + int format, int recurse, + enum val_prettyprint pretty) +{ + unsigned int i; + unsigned int things_printed = 0; + unsigned len; + struct type *elttype; + 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; + unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0); + struct value *mark = value_mark (); + + elttype = TYPE_TARGET_TYPE (type); + eltlen = TYPE_LENGTH (check_typedef (elttype)); + + { + LONGEST low, high; + if (get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), &low, &high) < 0) + len = 1; + else + len = high - low + 1; + } + + i = 0; + annotate_array_section_begin (i, elttype); + + while (i < len && things_printed < print_max) + { + struct value *v0, *v1; + int i0; + + 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)); + + i0 = i; + v0 = ada_value_primitive_packed_val (NULL, valaddr, + (i0 * bitsize) / HOST_CHAR_BIT, + (i0 * bitsize) % HOST_CHAR_BIT, + bitsize, elttype); + while (1) + { + i += 1; + if (i >= len) + break; + v1 = ada_value_primitive_packed_val (NULL, valaddr, + (i * bitsize) / HOST_CHAR_BIT, + (i * bitsize) % HOST_CHAR_BIT, + bitsize, elttype); + if (memcmp (VALUE_CONTENTS (v0), VALUE_CONTENTS (v1), eltlen) != 0) + break; + } + + if (i - i0 > repeat_count_threshold) + { + val_print (elttype, VALUE_CONTENTS (v0), 0, 0, stream, format, + 0, recurse + 1, pretty); + annotate_elt_rep (i - i0); + fprintf_filtered (stream, " ", i - i0); + annotate_elt_rep_end (); + + } + else + { + int j; + for (j = i0; j < i; j += 1) + { + if (j > i0) + { + 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)); + } + val_print (elttype, VALUE_CONTENTS (v0), 0, 0, stream, format, + 0, recurse + 1, pretty); + annotate_elt (); + } + } + things_printed += i - i0; + } + annotate_array_section_end (); + if (i < len) + { + fprintf_filtered (stream, "..."); + } + + value_free_to_mark (mark); +} + +static struct type * +printable_val_type (struct type *type, char *valaddr) +{ + return ada_to_fixed_type (ada_aligned_type (type), valaddr, 0, NULL); +} + +/* Print the character C on STREAM as part of the contents of a literal + string whose delimiter is QUOTER. TYPE_LEN is the length in bytes + (1 or 2) of the character. */ + +void +ada_emit_char (int c, struct ui_file *stream, int quoter, int type_len) +{ + if (type_len != 2) + type_len = 1; + + c &= (1 << (type_len * TARGET_CHAR_BIT)) - 1; + + if (isascii (c) && isprint (c)) + { + if (c == quoter && c == '"') + fprintf_filtered (stream, "[\"%c\"]", quoter); + else + fprintf_filtered (stream, "%c", c); + } + else + fprintf_filtered (stream, "[\"%0*x\"]", type_len * 2, c); +} + +/* Character #I of STRING, given that TYPE_LEN is the size in bytes (1 + or 2) of a character. */ + +static int +char_at (char *string, int i, int type_len) +{ + if (type_len == 1) + return string[i]; + else + return (int) extract_unsigned_integer (string + 2 * i, 2); +} + +void +ada_printchar (int c, struct ui_file *stream) +{ + fputs_filtered ("'", stream); + ada_emit_char (c, stream, '\'', 1); + fputs_filtered ("'", stream); +} + +/* [From print_type_scalar in typeprint.c]. Print VAL on STREAM in a + form appropriate for TYPE. */ + +void +ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream) +{ + unsigned int i; + unsigned len; + + CHECK_TYPEDEF (type); + + switch (TYPE_CODE (type)) + { + + case TYPE_CODE_ENUM: + len = TYPE_NFIELDS (type); + for (i = 0; i < len; i++) + { + if (TYPE_FIELD_BITPOS (type, i) == val) + { + break; + } + } + if (i < len) + { + fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream); + } + else + { + print_longest (stream, 'd', 0, val); + } + break; + + case TYPE_CODE_INT: + print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, val); + break; + + case TYPE_CODE_CHAR: + LA_PRINT_CHAR ((unsigned char) val, stream); + break; + + case TYPE_CODE_BOOL: + fprintf_filtered (stream, val ? "true" : "false"); + break; + + case TYPE_CODE_RANGE: + ada_print_scalar (TYPE_TARGET_TYPE (type), val, stream); + return; + + case TYPE_CODE_UNDEF: + case TYPE_CODE_PTR: + case TYPE_CODE_ARRAY: + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_FUNC: + case TYPE_CODE_FLT: + case TYPE_CODE_VOID: + case TYPE_CODE_SET: + case TYPE_CODE_STRING: + case TYPE_CODE_ERROR: + case TYPE_CODE_MEMBER: + case TYPE_CODE_METHOD: + case TYPE_CODE_REF: + warning ("internal error: unhandled type in ada_print_scalar"); + break; + + default: + error ("Invalid type code in symbol table."); + } + gdb_flush (stream); +} + +/* Print the character string STRING, printing at most LENGTH characters. + Printing stops early if the number hits print_max; repeat counts + are printed as appropriate. Print ellipses at the end if we + had to stop before printing LENGTH characters, or if + FORCE_ELLIPSES. TYPE_LEN is the length (1 or 2) of the character type. + */ + +static void +printstr (struct ui_file *stream, char *string, unsigned int length, + int force_ellipses, int type_len) +{ + unsigned int i; + unsigned int things_printed = 0; + int in_quotes = 0; + int need_comma = 0; + + if (length == 0) + { + fputs_filtered ("\"\"", stream); + return; + } + + for (i = 0; i < length && things_printed < print_max; i += 1) + { + /* Position of the character we are examining + to see whether it is repeated. */ + unsigned int rep1; + /* Number of repetitions we have detected so far. */ + unsigned int reps; + + QUIT; + + if (need_comma) + { + fputs_filtered (", ", stream); + need_comma = 0; + } + + rep1 = i + 1; + reps = 1; + while (rep1 < length && + char_at (string, rep1, type_len) == char_at (string, i, + type_len)) + { + rep1 += 1; + reps += 1; + } + + if (reps > repeat_count_threshold) + { + if (in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\", ", stream); + else + fputs_filtered ("\", ", stream); + in_quotes = 0; + } + fputs_filtered ("'", stream); + ada_emit_char (char_at (string, i, type_len), stream, '\'', + type_len); + fputs_filtered ("'", stream); + fprintf_filtered (stream, " ", reps); + i = rep1 - 1; + things_printed += repeat_count_threshold; + need_comma = 1; + } + else + { + if (!in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + in_quotes = 1; + } + ada_emit_char (char_at (string, i, type_len), stream, '"', + type_len); + things_printed += 1; + } + } + + /* Terminate the quotes if necessary. */ + if (in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + } + + if (force_ellipses || i < length) + fputs_filtered ("...", stream); +} + +void +ada_printstr (struct ui_file *stream, char *string, unsigned int length, + int force_ellipses, int width) +{ + printstr (stream, string, length, force_ellipses, width); +} + + +/* 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 as for the printf % codes or 0 for natural format). + The data at VALADDR is in target byte order. + + If the data is printed as a string, returns the number of string characters + printed. + + If DEREF_REF is nonzero, then dereference references, otherwise just print + them like pointers. + + RECURSE indicates the amount of indentation to supply before + continuation lines; this amount is roughly twice the value of RECURSE. + + When PRETTY is non-zero, prints record fields on separate lines. + (For some reason, the current version of gdb instead uses a global + variable---prettyprint_arrays--- to causes a similar effect on + arrays.) */ + +int +ada_val_print (struct type *type, char *valaddr0, int embedded_offset, + CORE_ADDR address, struct ui_file *stream, int format, + int deref_ref, int recurse, enum val_prettyprint pretty) +{ + struct ada_val_print_args args; + args.type = type; + args.valaddr0 = valaddr0; + args.embedded_offset = embedded_offset; + args.address = address; + args.stream = stream; + args.format = format; + args.deref_ref = deref_ref; + args.recurse = recurse; + args.pretty = pretty; + + return catch_errors (ada_val_print_stub, &args, NULL, RETURN_MASK_ALL); +} + +/* Helper for ada_val_print; used as argument to catch_errors to + unmarshal the arguments to ada_val_print_1, which does the work. */ +static int +ada_val_print_stub (void * args0) +{ + struct ada_val_print_args *argsp = (struct ada_val_print_args *) args0; + return ada_val_print_1 (argsp->type, argsp->valaddr0, + argsp->embedded_offset, argsp->address, + argsp->stream, argsp->format, argsp->deref_ref, + argsp->recurse, argsp->pretty); +} + +/* See the comment on ada_val_print. This function differs in that it + * does not catch evaluation errors (leaving that to ada_val_print). */ + +static int +ada_val_print_1 (struct type *type, char *valaddr0, int embedded_offset, + CORE_ADDR address, struct ui_file *stream, int format, + int deref_ref, int recurse, enum val_prettyprint pretty) +{ + unsigned int len; + int i; + struct type *elttype; + unsigned int eltlen; + LONGEST val; + CORE_ADDR addr; + char *valaddr = valaddr0 + embedded_offset; + + CHECK_TYPEDEF (type); + + if (ada_is_array_descriptor (type) || ada_is_packed_array_type (type)) + { + int retn; + struct value *mark = value_mark (); + struct value *val; + val = value_from_contents_and_address (type, valaddr, address); + val = ada_coerce_to_simple_array_ptr (val); + if (val == NULL) + { + fprintf_filtered (stream, "(null)"); + retn = 0; + } + else + retn = ada_val_print_1 (VALUE_TYPE (val), VALUE_CONTENTS (val), 0, + VALUE_ADDRESS (val), stream, format, + deref_ref, recurse, pretty); + value_free_to_mark (mark); + return retn; + } + + valaddr = ada_aligned_value_addr (type, valaddr); + embedded_offset -= valaddr - valaddr0 - embedded_offset; + type = printable_val_type (type, valaddr); + + switch (TYPE_CODE (type)) + { + default: + return c_val_print (type, valaddr0, embedded_offset, address, stream, + format, deref_ref, recurse, pretty); + + case TYPE_CODE_INT: + case TYPE_CODE_RANGE: + if (ada_is_fixed_point_type (type)) + { + LONGEST v = unpack_long (type, valaddr); + int len = TYPE_LENGTH (type); + + fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g", + (double) ada_fixed_to_float (type, v)); + return 0; + } + else if (ada_is_vax_floating_type (type)) + { + struct value *val = + value_from_contents_and_address (type, valaddr, address); + struct value *func = ada_vax_float_print_function (type); + if (func != 0) + { + static struct type *parray_of_char = NULL; + struct value *printable_val; + + if (parray_of_char == NULL) + parray_of_char = + make_pointer_type + (create_array_type + (NULL, builtin_type_char, + create_range_type (NULL, builtin_type_int, 0, 32)), NULL); + + printable_val = + value_ind (value_cast (parray_of_char, + call_function_by_hand (func, 1, + &val))); + + fprintf_filtered (stream, "%s", VALUE_CONTENTS (printable_val)); + return 0; + } + /* No special printing function. Do as best we can. */ + } + else if (TYPE_CODE (type) == TYPE_CODE_RANGE) + { + struct type *target_type = TYPE_TARGET_TYPE (type); + if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type)) + { + /* Obscure case of range type that has different length from + its base type. Perform a conversion, or we will get a + nonsense value. Actually, we could use the same + code regardless of lengths; I'm just avoiding a cast. */ + struct value *v = value_cast (target_type, + value_from_contents_and_address + (type, valaddr, 0)); + return ada_val_print_1 (target_type, VALUE_CONTENTS (v), 0, 0, + stream, format, 0, recurse + 1, pretty); + } + else + return ada_val_print_1 (TYPE_TARGET_TYPE (type), + valaddr0, embedded_offset, + address, stream, format, deref_ref, + recurse, pretty); + } + else + { + format = format ? format : output_format; + if (format) + { + print_scalar_formatted (valaddr, type, format, 0, stream); + } + else + { + val_print_type_code_int (type, valaddr, stream); + if (ada_is_character_type (type)) + { + fputs_filtered (" ", stream); + ada_printchar ((unsigned char) unpack_long (type, valaddr), + stream); + } + } + return 0; + } + + case TYPE_CODE_ENUM: + if (format) + { + print_scalar_formatted (valaddr, type, format, 0, stream); + break; + } + len = TYPE_NFIELDS (type); + val = unpack_long (type, valaddr); + for (i = 0; i < len; i++) + { + QUIT; + if (val == TYPE_FIELD_BITPOS (type, i)) + { + break; + } + } + if (i < len) + { + const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i)); + if (name[0] == '\'') + fprintf_filtered (stream, "%ld %s", (long) val, name); + else + fputs_filtered (name, stream); + } + else + { + print_longest (stream, 'd', 0, val); + } + break; + + case TYPE_CODE_UNION: + case TYPE_CODE_STRUCT: + if (ada_is_bogus_array_descriptor (type)) + { + fprintf_filtered (stream, "(...?)"); + return 0; + } + else + { + print_record (type, valaddr, stream, format, recurse, pretty); + return 0; + } + + case TYPE_CODE_ARRAY: + if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) + { + elttype = TYPE_TARGET_TYPE (type); + eltlen = TYPE_LENGTH (elttype); + len = TYPE_LENGTH (type) / eltlen; + + /* For an array of chars, print with string syntax. */ + if (ada_is_string_type (type) && (format == 0 || format == 's')) + { + if (prettyprint_arrays) + { + print_spaces_filtered (2 + 2 * recurse, stream); + } + /* 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; + temp_len < len && temp_len < print_max + && char_at (valaddr, temp_len, eltlen) != 0; + temp_len += 1); + len = temp_len; + } + + printstr (stream, valaddr, len, 0, eltlen); + } + else + { + len = 0; + fprintf_filtered (stream, "("); + print_optional_low_bound (stream, type); + if (TYPE_FIELD_BITSIZE (type, 0) > 0) + val_print_packed_array_elements (type, valaddr, 0, stream, + format, recurse, pretty); + else + val_print_array_elements (type, valaddr, address, stream, + format, deref_ref, recurse, + pretty, 0); + fprintf_filtered (stream, ")"); + } + gdb_flush (stream); + return len; + } + + case TYPE_CODE_REF: + elttype = check_typedef (TYPE_TARGET_TYPE (type)); + if (addressprint) + { + fprintf_filtered (stream, "@"); + /* Extract an address, assume that the address is unsigned. */ + print_address_numeric + (extract_unsigned_integer (valaddr, + TARGET_PTR_BIT / HOST_CHAR_BIT), + 1, stream); + if (deref_ref) + fputs_filtered (": ", stream); + } + /* De-reference the reference */ + if (deref_ref) + { + if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) + { + LONGEST deref_val_int = (LONGEST) + unpack_pointer (lookup_pointer_type (builtin_type_void), + valaddr); + if (deref_val_int != 0) + { + struct value *deref_val = + ada_value_ind (value_from_longest + (lookup_pointer_type (elttype), + deref_val_int)); + val_print (VALUE_TYPE (deref_val), + VALUE_CONTENTS (deref_val), 0, + VALUE_ADDRESS (deref_val), stream, format, + deref_ref, recurse + 1, pretty); + } + else + fputs_filtered ("(null)", stream); + } + else + fputs_filtered ("???", stream); + } + break; + } + return 0; +} + +static int +print_variant_part (struct type *type, int field_num, char *valaddr, + struct ui_file *stream, int format, int recurse, + enum val_prettyprint pretty, int comma_needed, + struct type *outer_type, char *outer_valaddr) +{ + struct type *var_type = TYPE_FIELD_TYPE (type, field_num); + int which = ada_which_variant_applies (var_type, outer_type, outer_valaddr); + + if (which < 0) + return 0; + else + return print_field_values + (TYPE_FIELD_TYPE (var_type, which), + valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT + + TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT, + stream, format, recurse, pretty, + comma_needed, outer_type, outer_valaddr); +} + +int +ada_value_print (struct value *val0, struct ui_file *stream, int format, + enum val_prettyprint pretty) +{ + char *valaddr = VALUE_CONTENTS (val0); + CORE_ADDR address = VALUE_ADDRESS (val0) + VALUE_OFFSET (val0); + struct type *type = + ada_to_fixed_type (VALUE_TYPE (val0), valaddr, address, NULL); + struct value *val = + value_from_contents_and_address (type, valaddr, address); + + /* If it is a pointer, indicate what it points to. */ + 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, ") "); + } + } + else if (ada_is_array_descriptor (type)) + { + fprintf_filtered (stream, "("); + type_print (type, "", stream, -1); + fprintf_filtered (stream, ") "); + } + else if (ada_is_bogus_array_descriptor (type)) + { + fprintf_filtered (stream, "("); + type_print (type, "", stream, -1); + fprintf_filtered (stream, ") (...?)"); + return 0; + } + return (val_print (type, VALUE_CONTENTS (val), 0, address, + stream, format, 1, 0, pretty)); +} + +static void +print_record (struct type *type, char *valaddr, struct ui_file *stream, + int format, int recurse, enum val_prettyprint pretty) +{ + CHECK_TYPEDEF (type); + + fprintf_filtered (stream, "("); + + if (print_field_values (type, valaddr, stream, format, recurse, pretty, + 0, type, valaddr) != 0 && pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 * recurse, stream); + } + + fprintf_filtered (stream, ")"); +} + +/* Print out fields of value at VALADDR having structure type TYPE. + + TYPE, VALADDR, STREAM, FORMAT, RECURSE, and PRETTY have the + same meanings as in ada_print_value and ada_val_print. + + OUTER_TYPE and OUTER_VALADDR give type and address of enclosing record + (used to get discriminant values when printing variant parts). + + COMMA_NEEDED is 1 if fields have been printed at the current recursion + level, so that a comma is needed before any field printed by this + call. + + Returns 1 if COMMA_NEEDED or any fields were printed. */ + +static int +print_field_values (struct type *type, char *valaddr, struct ui_file *stream, + int format, int recurse, enum val_prettyprint pretty, + int comma_needed, struct type *outer_type, + char *outer_valaddr) +{ + int i, len; + + len = TYPE_NFIELDS (type); + + for (i = 0; i < len; i += 1) + { + if (ada_is_ignored_field (type, i)) + continue; + + if (ada_is_wrapper_field (type, i)) + { + comma_needed = + print_field_values (TYPE_FIELD_TYPE (type, i), + valaddr + + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, + stream, format, recurse, pretty, + comma_needed, type, valaddr); + continue; + } + else if (ada_is_variant_part (type, i)) + { + comma_needed = + print_variant_part (type, i, valaddr, + stream, format, recurse, pretty, comma_needed, + outer_type, outer_valaddr); + continue; + } + + if (comma_needed) + fprintf_filtered (stream, ", "); + comma_needed = 1; + + if (pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 + 2 * recurse, stream); + } + else + { + wrap_here (n_spaces (2 + 2 * recurse)); + } + if (inspect_it) + { + if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) + fputs_filtered ("\"( ptr \"", stream); + else + fputs_filtered ("\"( nodef \"", stream); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, DMGL_NO_OPTS); + fputs_filtered ("\" \"", stream); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, DMGL_NO_OPTS); + fputs_filtered ("\") \"", stream); + } + else + { + annotate_field_begin (TYPE_FIELD_TYPE (type, i)); + fprintf_filtered (stream, "%.*s", + ada_name_prefix_len (TYPE_FIELD_NAME (type, i)), + TYPE_FIELD_NAME (type, i)); + annotate_field_name_end (); + fputs_filtered (" => ", stream); + annotate_field_value (); + } + + if (TYPE_FIELD_PACKED (type, i)) + { + struct value *v; + + /* Bitfields require special handling, especially due to byte + order problems. */ + if (TYPE_CPLUS_SPECIFIC (type) != NULL + && TYPE_FIELD_IGNORE (type, i)) + { + fputs_filtered ("", stream); + } + else + { + int bit_pos = TYPE_FIELD_BITPOS (type, i); + int bit_size = TYPE_FIELD_BITSIZE (type, i); + + adjust_type_signedness (TYPE_FIELD_TYPE (type, i)); + v = ada_value_primitive_packed_val (NULL, valaddr, + bit_pos / HOST_CHAR_BIT, + bit_pos % HOST_CHAR_BIT, + bit_size, + TYPE_FIELD_TYPE (type, i)); + val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0, + stream, format, 0, recurse + 1, pretty); + } + } + else + ada_val_print (TYPE_FIELD_TYPE (type, i), + valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, + 0, 0, stream, format, 0, recurse + 1, pretty); + annotate_field_end (); + } + + return comma_needed; +} diff --git a/contrib/gdb/gdb/alpha-mdebug-tdep.c b/contrib/gdb/gdb/alpha-mdebug-tdep.c new file mode 100644 index 00000000000..153ed11ce7d --- /dev/null +++ b/contrib/gdb/gdb/alpha-mdebug-tdep.c @@ -0,0 +1,386 @@ +/* Target-dependent mdebug code for the ALPHA architecture. + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "symtab.h" +#include "gdbcore.h" +#include "block.h" +#include "gdb_assert.h" + +#include "alpha-tdep.h" + +/* FIXME: Some of this code should perhaps be merged with mips. */ + +/* *INDENT-OFF* */ +/* Layout of a stack frame on the alpha: + + | | + pdr members: | 7th ... nth arg, | + | `pushed' by caller. | + | | +----------------|-------------------------------|<-- old_sp == vfp + ^ ^ ^ ^ | | + | | | | | | + | |localoff | Copies of 1st .. 6th | + | | | | | argument if necessary. | + | | | v | | + | | | --- |-------------------------------|<-- LOCALS_ADDRESS + | | | | | + | | | | Locals and temporaries. | + | | | | | + | | | |-------------------------------| + | | | | | + |-fregoffset | Saved float registers. | + | | | | F9 | + | | | | . | + | | | | . | + | | | | F2 | + | | v | | + | | -------|-------------------------------| + | | | | + | | | Saved registers. | + | | | S6 | + |-regoffset | . | + | | | . | + | | | S0 | + | | | pdr.pcreg | + | v | | + | ----------|-------------------------------| + | | | + frameoffset | Argument build area, gets | + | | 7th ... nth arg for any | + | | called procedure. | + v | | + -------------|-------------------------------|<-- sp + | | +*/ +/* *INDENT-ON* */ + +#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) +#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset) +#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg) +#define PROC_REG_MASK(proc) ((proc)->pdr.regmask) +#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask) +#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset) +#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset) +#define PROC_PC_REG(proc) ((proc)->pdr.pcreg) +#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff) + +/* Locate the mdebug PDR for the given PC. Return null if one can't + be found; you'll have to fall back to other methods in that case. */ + +static alpha_extra_func_info_t +find_proc_desc (CORE_ADDR pc) +{ + struct block *b = block_for_pc (pc); + alpha_extra_func_info_t proc_desc = NULL; + struct symbol *sym = NULL; + + if (b) + { + CORE_ADDR startaddr; + find_pc_partial_function (pc, NULL, &startaddr, NULL); + + if (startaddr > BLOCK_START (b)) + /* This is the "pathological" case referred to in a comment in + print_frame_info. It might be better to move this check into + symbol reading. */ + sym = NULL; + else + sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL); + } + + if (sym) + { + proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym); + + /* If we never found a PDR for this function in symbol reading, + then examine prologues to find the information. */ + if (proc_desc->pdr.framereg == -1) + proc_desc = NULL; + } + + return proc_desc; +} + +/* This returns the PC of the first inst after the prologue. If we can't + find the prologue, then return 0. */ + +static CORE_ADDR +alpha_mdebug_after_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc) +{ + if (proc_desc) + { + /* If function is frameless, then we need to do it the hard way. I + strongly suspect that frameless always means prologueless... */ + if (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM + && PROC_FRAME_OFFSET (proc_desc) == 0) + return 0; + } + + return alpha_after_prologue (pc); +} + +/* Return non-zero if we *might* be in a function prologue. Return zero + if we are definitively *not* in a function prologue. */ + +static int +alpha_mdebug_in_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc) +{ + CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc); + return (after_prologue_pc == 0 || pc < after_prologue_pc); +} + + +/* Frame unwinder that reads mdebug PDRs. */ + +struct alpha_mdebug_unwind_cache +{ + alpha_extra_func_info_t proc_desc; + CORE_ADDR vfp; + CORE_ADDR *saved_regs; +}; + +/* Extract all of the information about the frame from PROC_DESC + and store the resulting register save locations in the structure. */ + +static struct alpha_mdebug_unwind_cache * +alpha_mdebug_frame_unwind_cache (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct alpha_mdebug_unwind_cache *info; + alpha_extra_func_info_t proc_desc; + ULONGEST vfp; + CORE_ADDR pc, reg_position; + unsigned long mask; + int ireg, returnreg; + + if (*this_prologue_cache) + return *this_prologue_cache; + + info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache); + *this_prologue_cache = info; + pc = frame_pc_unwind (next_frame); + + /* ??? We don't seem to be able to cache the lookup of the PDR + from alpha_mdebug_frame_p. It'd be nice if we could change + the arguments to that function. Oh well. */ + proc_desc = find_proc_desc (pc); + info->proc_desc = proc_desc; + gdb_assert (proc_desc != NULL); + + info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS); + + /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET. */ + frame_unwind_unsigned_register (next_frame, PROC_FRAME_REG (proc_desc), &vfp); + vfp += PROC_FRAME_OFFSET (info->proc_desc); + info->vfp = vfp; + + /* Fill in the offsets for the registers which gen_mask says were saved. */ + + reg_position = vfp + PROC_REG_OFFSET (proc_desc); + mask = PROC_REG_MASK (proc_desc); + returnreg = PROC_PC_REG (proc_desc); + + /* Note that RA is always saved first, regardless of its actual + register number. */ + if (mask & (1 << returnreg)) + { + /* Clear bit for RA so we don't save it again later. */ + mask &= ~(1 << returnreg); + + info->saved_regs[returnreg] = reg_position; + reg_position += 8; + } + + for (ireg = 0; ireg <= 31; ++ireg) + if (mask & (1 << ireg)) + { + info->saved_regs[ireg] = reg_position; + reg_position += 8; + } + + reg_position = vfp + PROC_FREG_OFFSET (proc_desc); + mask = PROC_FREG_MASK (proc_desc); + + for (ireg = 0; ireg <= 31; ++ireg) + if (mask & (1 << ireg)) + { + info->saved_regs[ALPHA_FP0_REGNUM + ireg] = reg_position; + reg_position += 8; + } + + return info; +} + +/* Given a GDB frame, determine the address of the calling function's + frame. This will be used to create a new GDB frame struct. */ + +static void +alpha_mdebug_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct alpha_mdebug_unwind_cache *info + = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); + + *this_id = frame_id_build (info->vfp, frame_func_unwind (next_frame)); +} + +/* Retrieve the value of REGNUM in FRAME. Don't give up! */ + +static void +alpha_mdebug_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) +{ + struct alpha_mdebug_unwind_cache *info + = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); + + /* The PC of the previous frame is stored in the link register of + the current frame. Frob regnum so that we pull the value from + the correct place. */ + if (regnum == ALPHA_PC_REGNUM) + regnum = PROC_PC_REG (info->proc_desc); + + /* For all registers known to be saved in the current frame, + do the obvious and pull the value out. */ + if (info->saved_regs[regnum]) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = info->saved_regs[regnum]; + *realnump = -1; + if (bufferp != NULL) + get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE); + return; + } + + /* The stack pointer of the previous frame is computed by popping + the current stack frame. */ + if (regnum == ALPHA_SP_REGNUM) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (bufferp != NULL) + store_unsigned_integer (bufferp, ALPHA_REGISTER_SIZE, info->vfp); + return; + } + + /* Otherwise assume the next frame has the same register value. */ + frame_register (next_frame, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); +} + +static const struct frame_unwind alpha_mdebug_frame_unwind = { + NORMAL_FRAME, + alpha_mdebug_frame_this_id, + alpha_mdebug_frame_prev_register +}; + +const struct frame_unwind * +alpha_mdebug_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + alpha_extra_func_info_t proc_desc; + + /* If this PC does not map to a PDR, then clearly this isn't an + mdebug frame. */ + proc_desc = find_proc_desc (pc); + if (proc_desc == NULL) + return NULL; + + /* If we're in the prologue, the PDR for this frame is not yet valid. + Say no here and we'll fall back on the heuristic unwinder. */ + if (alpha_mdebug_in_prologue (pc, proc_desc)) + return NULL; + + return &alpha_mdebug_frame_unwind; +} + +static CORE_ADDR +alpha_mdebug_frame_base_address (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct alpha_mdebug_unwind_cache *info + = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); + + return info->vfp; +} + +static CORE_ADDR +alpha_mdebug_frame_locals_address (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct alpha_mdebug_unwind_cache *info + = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); + + return info->vfp - PROC_LOCALOFF (info->proc_desc); +} + +static CORE_ADDR +alpha_mdebug_frame_args_address (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct alpha_mdebug_unwind_cache *info + = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); + + return info->vfp - ALPHA_NUM_ARG_REGS * 8; +} + +static const struct frame_base alpha_mdebug_frame_base = { + &alpha_mdebug_frame_unwind, + alpha_mdebug_frame_base_address, + alpha_mdebug_frame_locals_address, + alpha_mdebug_frame_args_address +}; + +static const struct frame_base * +alpha_mdebug_frame_base_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + alpha_extra_func_info_t proc_desc; + + /* If this PC does not map to a PDR, then clearly this isn't an + mdebug frame. */ + proc_desc = find_proc_desc (pc); + if (proc_desc == NULL) + return NULL; + + return &alpha_mdebug_frame_base; +} + + +void +alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + frame_unwind_append_sniffer (gdbarch, alpha_mdebug_frame_sniffer); + frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer); +} diff --git a/contrib/gdb/gdb/alpha-nat.c b/contrib/gdb/gdb/alpha-nat.c new file mode 100644 index 00000000000..0a78d949170 --- /dev/null +++ b/contrib/gdb/gdb/alpha-nat.c @@ -0,0 +1,272 @@ +/* Low level Alpha interface, for GDB when running native. + Copyright 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_string.h" +#include "inferior.h" +#include "gdbcore.h" +#include "target.h" +#include "regcache.h" + +#include "alpha-tdep.h" + +#include +#ifdef __linux__ +#include +#include +#else +#include +#endif +#include + +/* Prototypes for local functions. */ + +static void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR); +static void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR); + +/* Extract the register values out of the core file and store + them where `read_register' will find them. + + CORE_REG_SECT points to the register values themselves, read into memory. + CORE_REG_SIZE is the size of that area. + WHICH says which set of registers we are handling (0 = int, 2 = float + on machines where they are discontiguous). + REG_ADDR is the offset from u.u_ar0 to the register values relative to + core_reg_sect. This is used with old-fashioned core files to + locate the registers in a large upage-plus-stack ".reg" section. + Original upage address X is at location core_reg_sect+x+reg_addr. + */ + +static void +fetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size, + int which, CORE_ADDR reg_addr) +{ + int regno; + int addr; + int bad_reg = -1; + + /* Table to map a gdb regnum to an index in the core register + section. The floating point register values are garbage in + OSF/1.2 core files. OSF5 uses different names for the register + enum list, need to handle two cases. The actual values are the + same. */ + static int const core_reg_mapping[ALPHA_NUM_REGS] = + { +#ifdef NCF_REGS +#define EFL NCF_REGS + CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6, + CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6, + CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9, + CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1, + EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7, + EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15, + EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23, + EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31, + CF_PC, -1 +#else +#define EFL (EF_SIZE / 8) + EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6, + EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6, + EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9, + EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1, + EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7, + EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15, + EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23, + EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31, + EF_PC, -1 +#endif + }; + + for (regno = 0; regno < ALPHA_NUM_REGS; regno++) + { + if (CANNOT_FETCH_REGISTER (regno)) + { + supply_register (regno, NULL); + continue; + } + addr = 8 * core_reg_mapping[regno]; + if (addr < 0 || addr >= core_reg_size) + { + /* ??? UNIQUE is a new addition. Don't generate an error. */ + if (regno == ALPHA_UNIQUE_REGNUM) + { + supply_register (regno, NULL); + continue; + } + if (bad_reg < 0) + bad_reg = regno; + } + else + { + supply_register (regno, core_reg_sect + addr); + } + } + if (bad_reg >= 0) + { + error ("Register %s not found in core file.", REGISTER_NAME (bad_reg)); + } +} + +static void +fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size, + int which, CORE_ADDR reg_addr) +{ + if (core_reg_size < 32 * 8) + { + error ("Core file register section too small (%u bytes).", core_reg_size); + return; + } + + switch (which) + { + case 0: /* integer registers */ + /* PC is in slot 32; UNIQUE is in slot 33, if present. */ + alpha_supply_int_regs (-1, core_reg_sect, core_reg_sect + 31*8, + (core_reg_size >= 33 * 8 + ? core_reg_sect + 32*8 : NULL)); + break; + + case 2: /* floating-point registers */ + /* FPCR is in slot 32. */ + alpha_supply_fp_regs (-1, core_reg_sect, core_reg_sect + 31*8); + break; + + default: + break; + } +} + + +/* Map gdb internal register number to a ptrace ``address''. + These ``addresses'' are defined in , with + the exception of ALPHA_UNIQUE_PTRACE_ADDR. */ + +#ifndef ALPHA_UNIQUE_PTRACE_ADDR +#define ALPHA_UNIQUE_PTRACE_ADDR 0 +#endif + +CORE_ADDR +register_addr (int regno, CORE_ADDR blockend) +{ + if (regno == PC_REGNUM) + return PC; + if (regno == ALPHA_UNIQUE_REGNUM) + return ALPHA_UNIQUE_PTRACE_ADDR; + if (regno < FP0_REGNUM) + return GPR_BASE + regno; + else + return FPR_BASE + regno - FP0_REGNUM; +} + +int +kernel_u_size (void) +{ + return (sizeof (struct user)); +} + +#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T) +#include + +/* Prototypes for supply_gregset etc. */ +#include "gregset.h" + +/* Locate the UNIQUE value within the gregset_t. */ +#ifndef ALPHA_REGSET_UNIQUE +#define ALPHA_REGSET_UNIQUE(ptr) NULL +#endif + +/* + * See the comment in m68k-tdep.c regarding the utility of these functions. + */ + +void +supply_gregset (gdb_gregset_t *gregsetp) +{ + long *regp = ALPHA_REGSET_BASE (gregsetp); + void *unique = ALPHA_REGSET_UNIQUE (gregsetp); + + /* PC is in slot 32. */ + alpha_supply_int_regs (-1, regp, regp + 31, unique); +} + +void +fill_gregset (gdb_gregset_t *gregsetp, int regno) +{ + long *regp = ALPHA_REGSET_BASE (gregsetp); + void *unique = ALPHA_REGSET_UNIQUE (gregsetp); + + /* PC is in slot 32. */ + alpha_fill_int_regs (regno, regp, regp + 31, unique); +} + +/* + * Now we do the same thing for floating-point registers. + * Again, see the comments in m68k-tdep.c. + */ + +void +supply_fpregset (gdb_fpregset_t *fpregsetp) +{ + long *regp = ALPHA_REGSET_BASE (fpregsetp); + + /* FPCR is in slot 32. */ + alpha_supply_fp_regs (-1, regp, regp + 31); +} + +void +fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) +{ + long *regp = ALPHA_REGSET_BASE (fpregsetp); + + /* FPCR is in slot 32. */ + alpha_fill_fp_regs (regno, regp, regp + 31); +} +#endif + + +/* Register that we are able to handle alpha core file formats. */ + +static struct core_fns alpha_osf_core_fns = +{ + /* This really is bfd_target_unknown_flavour. */ + + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_osf_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +static struct core_fns alpha_elf_core_fns = +{ + bfd_target_elf_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_elf_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +void +_initialize_core_alpha (void) +{ + add_core_fns (&alpha_osf_core_fns); + add_core_fns (&alpha_elf_core_fns); +} diff --git a/contrib/gdb/gdb/alpha-tdep.c b/contrib/gdb/gdb/alpha-tdep.c index 4ca6bcc3884..1599eb2a371 100644 --- a/contrib/gdb/gdb/alpha-tdep.c +++ b/contrib/gdb/gdb/alpha-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger. - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -20,7 +20,11 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "doublest.h" #include "frame.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "dwarf2-frame.h" #include "inferior.h" #include "symtab.h" #include "value.h" @@ -32,253 +36,20 @@ #include "gdb_string.h" #include "linespec.h" #include "regcache.h" -#include "doublest.h" +#include "reggroups.h" +#include "arch-utils.h" +#include "osabi.h" +#include "block.h" -struct frame_extra_info - { - alpha_extra_func_info_t proc_desc; - int localoff; - int pc_reg; - }; +#include "elf-bfd.h" -/* FIXME: Some of this code should perhaps be merged with mips-tdep.c. */ +#include "alpha-tdep.h" -/* Prototypes for local functions. */ - -static void alpha_find_saved_regs (struct frame_info *); - -static alpha_extra_func_info_t push_sigtramp_desc (CORE_ADDR low_addr); - -static CORE_ADDR read_next_frame_reg (struct frame_info *, int); - -static CORE_ADDR heuristic_proc_start (CORE_ADDR); - -static alpha_extra_func_info_t heuristic_proc_desc (CORE_ADDR, - CORE_ADDR, - struct frame_info *); - -static alpha_extra_func_info_t find_proc_desc (CORE_ADDR, - struct frame_info *); - -#if 0 -static int alpha_in_lenient_prologue (CORE_ADDR, CORE_ADDR); -#endif - -static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *); - -static CORE_ADDR after_prologue (CORE_ADDR pc, - alpha_extra_func_info_t proc_desc); - -static int alpha_in_prologue (CORE_ADDR pc, - alpha_extra_func_info_t proc_desc); - -static int alpha_about_to_return (CORE_ADDR pc); - -void _initialize_alpha_tdep (void); - -/* Heuristic_proc_start may hunt through the text section for a long - time across a 2400 baud serial line. Allows the user to limit this - search. */ -static unsigned int heuristic_fence_post = 0; -/* *INDENT-OFF* */ -/* Layout of a stack frame on the alpha: - - | | - pdr members: | 7th ... nth arg, | - | `pushed' by caller. | - | | -----------------|-------------------------------|<-- old_sp == vfp - ^ ^ ^ ^ | | - | | | | | | - | |localoff | Copies of 1st .. 6th | - | | | | | argument if necessary. | - | | | v | | - | | | --- |-------------------------------|<-- FRAME_LOCALS_ADDRESS - | | | | | - | | | | Locals and temporaries. | - | | | | | - | | | |-------------------------------| - | | | | | - |-fregoffset | Saved float registers. | - | | | | F9 | - | | | | . | - | | | | . | - | | | | F2 | - | | v | | - | | -------|-------------------------------| - | | | | - | | | Saved registers. | - | | | S6 | - |-regoffset | . | - | | | . | - | | | S0 | - | | | pdr.pcreg | - | v | | - | ----------|-------------------------------| - | | | - frameoffset | Argument build area, gets | - | | 7th ... nth arg for any | - | | called procedure. | - v | | - -------------|-------------------------------|<-- sp - | | -*/ -/* *INDENT-ON* */ - - - -#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */ -/* These next two fields are kind of being hijacked. I wonder if - iline is too small for the values it needs to hold, if GDB is - running on a 32-bit host. */ -#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline) /* upper address bound */ -#define PROC_DUMMY_FRAME(proc) ((proc)->pdr.cbLineOffset) /*CALL_DUMMY frame */ -#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset) -#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg) -#define PROC_REG_MASK(proc) ((proc)->pdr.regmask) -#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask) -#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset) -#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset) -#define PROC_PC_REG(proc) ((proc)->pdr.pcreg) -#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff) -#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym) -#define _PROC_MAGIC_ 0x0F0F0F0F -#define PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym == _PROC_MAGIC_) -#define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_) - -struct linked_proc_info - { - struct alpha_extra_func_info info; - struct linked_proc_info *next; - } - *linked_proc_desc_table = NULL; -int -alpha_osf_in_sigtramp (CORE_ADDR pc, char *func_name) -{ - return (func_name != NULL && STREQ ("__sigtramp", func_name)); -} - -/* Under GNU/Linux, signal handler invocations can be identified by the - designated code sequence that is used to return from a signal - handler. In particular, the return address of a signal handler - points to the following sequence (the first instruction is quadword - aligned): - - bis $30,$30,$16 - addq $31,0x67,$0 - call_pal callsys - - Each instruction has a unique encoding, so we simply attempt to - match the instruction the pc is pointing to with any of the above - instructions. If there is a hit, we know the offset to the start - of the designated sequence and can then check whether we really are - executing in a designated sequence. If not, -1 is returned, - otherwise the offset from the start of the desingated sequence is - returned. - - There is a slight chance of false hits: code could jump into the - middle of the designated sequence, in which case there is no - guarantee that we are in the middle of a sigreturn syscall. Don't - think this will be a problem in praxis, though. - */ - -#ifndef TM_LINUXALPHA_H -/* HACK: Provide a prototype when compiling this file for non - linuxalpha targets. */ -long alpha_linux_sigtramp_offset (CORE_ADDR pc); -#endif -long -alpha_linux_sigtramp_offset (CORE_ADDR pc) -{ - unsigned int i[3], w; - long off; - - if (read_memory_nobpt (pc, (char *) &w, 4) != 0) - return -1; - - off = -1; - switch (w) - { - case 0x47de0410: - off = 0; - break; /* bis $30,$30,$16 */ - case 0x43ecf400: - off = 4; - break; /* addq $31,0x67,$0 */ - case 0x00000083: - off = 8; - break; /* call_pal callsys */ - default: - return -1; - } - pc -= off; - if (pc & 0x7) - { - /* designated sequence is not quadword aligned */ - return -1; - } - - if (read_memory_nobpt (pc, (char *) i, sizeof (i)) != 0) - return -1; - - if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083) - return off; - - return -1; -} - - -/* Under OSF/1, the __sigtramp routine is frameless and has a frame - size of zero, but we are able to backtrace through it. */ -CORE_ADDR -alpha_osf_skip_sigtramp_frame (struct frame_info *frame, CORE_ADDR pc) -{ - char *name; - find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL); - if (IN_SIGTRAMP (pc, name)) - return frame->frame; - else - return 0; -} - - -/* Dynamically create a signal-handler caller procedure descriptor for - the signal-handler return code starting at address LOW_ADDR. The - descriptor is added to the linked_proc_desc_table. */ - -static alpha_extra_func_info_t -push_sigtramp_desc (CORE_ADDR low_addr) -{ - struct linked_proc_info *link; - alpha_extra_func_info_t proc_desc; - - link = (struct linked_proc_info *) - xmalloc (sizeof (struct linked_proc_info)); - link->next = linked_proc_desc_table; - linked_proc_desc_table = link; - - proc_desc = &link->info; - - proc_desc->numargs = 0; - PROC_LOW_ADDR (proc_desc) = low_addr; - PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4; - PROC_DUMMY_FRAME (proc_desc) = 0; - PROC_FRAME_OFFSET (proc_desc) = 0x298; /* sizeof(struct sigcontext_struct) */ - PROC_FRAME_REG (proc_desc) = SP_REGNUM; - PROC_REG_MASK (proc_desc) = 0xffff; - PROC_FREG_MASK (proc_desc) = 0xffff; - PROC_PC_REG (proc_desc) = 26; - PROC_LOCALOFF (proc_desc) = 0; - SET_PROC_DESC_IS_DYN_SIGTRAMP (proc_desc); - return (proc_desc); -} - - -char * +static const char * alpha_register_name (int regno) { - static char *register_names[] = + static const char * const register_names[] = { "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp", @@ -288,768 +59,242 @@ alpha_register_name (int regno) "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "fpcr", - "pc", "vfp", + "pc", "", "unique" }; if (regno < 0) - return (NULL); + return NULL; if (regno >= (sizeof(register_names) / sizeof(*register_names))) - return (NULL); - return (register_names[regno]); + return NULL; + return register_names[regno]; } -int +static int alpha_cannot_fetch_register (int regno) { - return (regno == FP_REGNUM || regno == ZERO_REGNUM); + return regno == ALPHA_ZERO_REGNUM; } -int +static int alpha_cannot_store_register (int regno) { - return (regno == FP_REGNUM || regno == ZERO_REGNUM); + return regno == ALPHA_ZERO_REGNUM; } -int -alpha_register_convertible (int regno) +static struct type * +alpha_register_type (struct gdbarch *gdbarch, int regno) { - return (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31); + if (regno == ALPHA_SP_REGNUM || regno == ALPHA_GP_REGNUM) + return builtin_type_void_data_ptr; + if (regno == ALPHA_PC_REGNUM) + return builtin_type_void_func_ptr; + + /* Don't need to worry about little vs big endian until + some jerk tries to port to alpha-unicosmk. */ + if (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31) + return builtin_type_ieee_double_little; + + return builtin_type_int64; } -struct type * -alpha_register_virtual_type (int regno) +/* Is REGNUM a member of REGGROUP? */ + +static int +alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) { - return ((regno >= FP0_REGNUM && regno < (FP0_REGNUM+31)) - ? builtin_type_double : builtin_type_long); + /* Filter out any registers eliminated, but whose regnum is + reserved for backward compatibility, e.g. the vfp. */ + if (REGISTER_NAME (regnum) == NULL || *REGISTER_NAME (regnum) == '\0') + return 0; + + if (group == all_reggroup) + return 1; + + /* Zero should not be saved or restored. Technically it is a general + register (just as $f31 would be a float if we represented it), but + there's no point displaying it during "info regs", so leave it out + of all groups except for "all". */ + if (regnum == ALPHA_ZERO_REGNUM) + return 0; + + /* All other registers are saved and restored. */ + if (group == save_reggroup || group == restore_reggroup) + return 1; + + /* All other groups are non-overlapping. */ + + /* Since this is really a PALcode memory slot... */ + if (regnum == ALPHA_UNIQUE_REGNUM) + return group == system_reggroup; + + /* Force the FPCR to be considered part of the floating point state. */ + if (regnum == ALPHA_FPCR_REGNUM) + return group == float_reggroup; + + if (regnum >= ALPHA_FP0_REGNUM && regnum < ALPHA_FP0_REGNUM + 31) + return group == float_reggroup; + else + return group == general_reggroup; } -int +static int alpha_register_byte (int regno) { return (regno * 8); } -int +static int alpha_register_raw_size (int regno) { return 8; } -int +static int alpha_register_virtual_size (int regno) { return 8; } - -/* Guaranteed to set frame->saved_regs to some values (it never leaves it - NULL). */ +/* The following represents exactly the conversion performed by + the LDS instruction. This applies to both single-precision + floating point and 32-bit integers. */ static void -alpha_find_saved_regs (struct frame_info *frame) +alpha_lds (void *out, const void *in) { - int ireg; - CORE_ADDR reg_position; - unsigned long mask; - alpha_extra_func_info_t proc_desc; - int returnreg; + ULONGEST mem = extract_unsigned_integer (in, 4); + ULONGEST frac = (mem >> 0) & 0x7fffff; + ULONGEST sign = (mem >> 31) & 1; + ULONGEST exp_msb = (mem >> 30) & 1; + ULONGEST exp_low = (mem >> 23) & 0x7f; + ULONGEST exp, reg; - frame_saved_regs_zalloc (frame); - - /* If it is the frame for __sigtramp, the saved registers are located - in a sigcontext structure somewhere on the stack. __sigtramp - passes a pointer to the sigcontext structure on the stack. - If the stack layout for __sigtramp changes, or if sigcontext offsets - change, we might have to update this code. */ -#ifndef SIGFRAME_PC_OFF -#define SIGFRAME_PC_OFF (2 * 8) -#define SIGFRAME_REGSAVE_OFF (4 * 8) -#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8) -#endif - if (frame->signal_handler_caller) + exp = (exp_msb << 10) | exp_low; + if (exp_msb) { - CORE_ADDR sigcontext_addr; - - sigcontext_addr = SIGCONTEXT_ADDR (frame); - for (ireg = 0; ireg < 32; ireg++) - { - reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8; - frame->saved_regs[ireg] = reg_position; - } - for (ireg = 0; ireg < 32; ireg++) - { - reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8; - frame->saved_regs[FP0_REGNUM + ireg] = reg_position; - } - frame->saved_regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF; - return; + if (exp_low == 0x7f) + exp = 0x7ff; } - - proc_desc = frame->extra_info->proc_desc; - if (proc_desc == NULL) - /* I'm not sure how/whether this can happen. Normally when we can't - find a proc_desc, we "synthesize" one using heuristic_proc_desc - and set the saved_regs right away. */ - return; - - /* Fill in the offsets for the registers which gen_mask says - were saved. */ - - reg_position = frame->frame + PROC_REG_OFFSET (proc_desc); - mask = PROC_REG_MASK (proc_desc); - - returnreg = PROC_PC_REG (proc_desc); - - /* Note that RA is always saved first, regardless of its actual - register number. */ - if (mask & (1 << returnreg)) - { - frame->saved_regs[returnreg] = reg_position; - reg_position += 8; - mask &= ~(1 << returnreg); /* Clear bit for RA so we - don't save again later. */ - } - - for (ireg = 0; ireg <= 31; ++ireg) - if (mask & (1 << ireg)) - { - frame->saved_regs[ireg] = reg_position; - reg_position += 8; - } - - /* Fill in the offsets for the registers which float_mask says - were saved. */ - - reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc); - mask = PROC_FREG_MASK (proc_desc); - - for (ireg = 0; ireg <= 31; ++ireg) - if (mask & (1 << ireg)) - { - frame->saved_regs[FP0_REGNUM + ireg] = reg_position; - reg_position += 8; - } - - frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg]; -} - -void -alpha_frame_init_saved_regs (struct frame_info *fi) -{ - if (fi->saved_regs == NULL) - alpha_find_saved_regs (fi); - fi->saved_regs[SP_REGNUM] = fi->frame; -} - -void -alpha_init_frame_pc_first (int fromleaf, struct frame_info *prev) -{ - prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : - prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ()); -} - -static CORE_ADDR -read_next_frame_reg (struct frame_info *fi, int regno) -{ - for (; fi; fi = fi->next) - { - /* We have to get the saved sp from the sigcontext - if it is a signal handler frame. */ - if (regno == SP_REGNUM && !fi->signal_handler_caller) - return fi->frame; - else - { - if (fi->saved_regs == NULL) - alpha_find_saved_regs (fi); - if (fi->saved_regs[regno]) - return read_memory_integer (fi->saved_regs[regno], 8); - } - } - return read_register (regno); -} - -CORE_ADDR -alpha_frame_saved_pc (struct frame_info *frame) -{ - alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc; - /* We have to get the saved pc from the sigcontext - if it is a signal handler frame. */ - int pcreg = frame->signal_handler_caller ? PC_REGNUM - : frame->extra_info->pc_reg; - - if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc)) - return read_memory_integer (frame->frame - 8, 8); - - return read_next_frame_reg (frame, pcreg); -} - -CORE_ADDR -alpha_saved_pc_after_call (struct frame_info *frame) -{ - CORE_ADDR pc = frame->pc; - CORE_ADDR tmp; - alpha_extra_func_info_t proc_desc; - int pcreg; - - /* Skip over shared library trampoline if necessary. */ - tmp = SKIP_TRAMPOLINE_CODE (pc); - if (tmp != 0) - pc = tmp; - - proc_desc = find_proc_desc (pc, frame->next); - pcreg = proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM; - - if (frame->signal_handler_caller) - return alpha_frame_saved_pc (frame); else - return read_register (pcreg); + { + if (exp_low != 0x00) + exp |= 0x380; + } + + reg = (sign << 63) | (exp << 52) | (frac << 29); + store_unsigned_integer (out, 8, reg); } +/* Similarly, this represents exactly the conversion performed by + the STS instruction. */ -static struct alpha_extra_func_info temp_proc_desc; -static CORE_ADDR temp_saved_regs[NUM_REGS]; +static void +alpha_sts (void *out, const void *in) +{ + ULONGEST reg, mem; -/* Nonzero if instruction at PC is a return instruction. "ret - $zero,($ra),1" on alpha. */ + reg = extract_unsigned_integer (in, 8); + mem = ((reg >> 32) & 0xc0000000) | ((reg >> 29) & 0x3fffffff); + store_unsigned_integer (out, 4, mem); +} + +/* The alpha needs a conversion between register and memory format if the + register is a floating point register and memory format is float, as the + register format must be double or memory format is an integer with 4 + bytes or less, as the representation of integers in floating point + registers is different. */ static int -alpha_about_to_return (CORE_ADDR pc) +alpha_convert_register_p (int regno, struct type *type) { - return read_memory_integer (pc, 4) == 0x6bfa8001; + return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31); } - - -/* This fencepost looks highly suspicious to me. Removing it also - seems suspicious as it could affect remote debugging across serial - lines. */ - -static CORE_ADDR -heuristic_proc_start (CORE_ADDR pc) +static void +alpha_register_to_value (struct frame_info *frame, int regnum, + struct type *valtype, void *out) { - CORE_ADDR start_pc = pc; - CORE_ADDR fence = start_pc - heuristic_fence_post; - - if (start_pc == 0) - return 0; - - if (heuristic_fence_post == UINT_MAX - || fence < VM_MIN_ADDRESS) - fence = VM_MIN_ADDRESS; - - /* search back for previous return */ - for (start_pc -= 4;; start_pc -= 4) - if (start_pc < fence) - { - /* It's not clear to me why we reach this point when - stop_soon_quietly, but with this test, at least we - don't print out warnings for every child forked (eg, on - decstation). 22apr93 rich@cygnus.com. */ - if (!stop_soon_quietly) - { - static int blurb_printed = 0; - - if (fence == VM_MIN_ADDRESS) - warning ("Hit beginning of text section without finding"); - else - warning ("Hit heuristic-fence-post without finding"); - - warning ("enclosing function for address 0x%s", paddr_nz (pc)); - if (!blurb_printed) - { - printf_filtered ("\ -This warning occurs if you are debugging a function without any symbols\n\ -(for example, in a stripped executable). In that case, you may wish to\n\ -increase the size of the search with the `set heuristic-fence-post' command.\n\ -\n\ -Otherwise, you told GDB there was a function where there isn't one, or\n\ -(more likely) you have encountered a bug in GDB.\n"); - blurb_printed = 1; - } - } - - return 0; - } - else if (alpha_about_to_return (start_pc)) + char in[MAX_REGISTER_SIZE]; + frame_register_read (frame, regnum, in); + switch (TYPE_LENGTH (valtype)) + { + case 4: + alpha_sts (out, in); break; - - start_pc += 4; /* skip return */ - return start_pc; -} - -static alpha_extra_func_info_t -heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, - struct frame_info *next_frame) -{ - CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM); - CORE_ADDR cur_pc; - int frame_size; - int has_frame_reg = 0; - unsigned long reg_mask = 0; - int pcreg = -1; - - if (start_pc == 0) - return NULL; - memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc)); - memset (&temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS); - PROC_LOW_ADDR (&temp_proc_desc) = start_pc; - - if (start_pc + 200 < limit_pc) - limit_pc = start_pc + 200; - frame_size = 0; - for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) - { - char buf[4]; - unsigned long word; - int status; - - status = read_memory_nobpt (cur_pc, buf, 4); - if (status) - memory_error (status, cur_pc); - word = extract_unsigned_integer (buf, 4); - - if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */ - { - if (word & 0x8000) - frame_size += (-word) & 0xffff; - else - /* Exit loop if a positive stack adjustment is found, which - usually means that the stack cleanup code in the function - epilogue is reached. */ - break; - } - else if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */ - && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */ - { - int reg = (word & 0x03e00000) >> 21; - reg_mask |= 1 << reg; - temp_saved_regs[reg] = sp + (short) word; - - /* Starting with OSF/1-3.2C, the system libraries are shipped - without local symbols, but they still contain procedure - descriptors without a symbol reference. GDB is currently - unable to find these procedure descriptors and uses - heuristic_proc_desc instead. - As some low level compiler support routines (__div*, __add*) - use a non-standard return address register, we have to - add some heuristics to determine the return address register, - or stepping over these routines will fail. - Usually the return address register is the first register - saved on the stack, but assembler optimization might - rearrange the register saves. - So we recognize only a few registers (t7, t9, ra) within - the procedure prologue as valid return address registers. - If we encounter a return instruction, we extract the - the return address register from it. - - FIXME: Rewriting GDB to access the procedure descriptors, - e.g. via the minimal symbol table, might obviate this hack. */ - if (pcreg == -1 - && cur_pc < (start_pc + 80) - && (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM)) - pcreg = reg; - } - else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ - pcreg = (word >> 16) & 0x1f; - else if (word == 0x47de040f) /* bis sp,sp fp */ - has_frame_reg = 1; - } - if (pcreg == -1) - { - /* If we haven't found a valid return address register yet, - keep searching in the procedure prologue. */ - while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80)) - { - char buf[4]; - unsigned long word; - - if (read_memory_nobpt (cur_pc, buf, 4)) - break; - cur_pc += 4; - word = extract_unsigned_integer (buf, 4); - - if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */ - && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */ - { - int reg = (word & 0x03e00000) >> 21; - if (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM) - { - pcreg = reg; - break; - } - } - else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ - { - pcreg = (word >> 16) & 0x1f; - break; - } - } - } - - if (has_frame_reg) - PROC_FRAME_REG (&temp_proc_desc) = GCC_FP_REGNUM; - else - PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM; - PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size; - PROC_REG_MASK (&temp_proc_desc) = reg_mask; - PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? RA_REGNUM : pcreg; - PROC_LOCALOFF (&temp_proc_desc) = 0; /* XXX - bogus */ - return &temp_proc_desc; -} - -/* This returns the PC of the first inst after the prologue. If we can't - find the prologue, then return 0. */ - -static CORE_ADDR -after_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc) -{ - struct symtab_and_line sal; - CORE_ADDR func_addr, func_end; - - if (!proc_desc) - proc_desc = find_proc_desc (pc, NULL); - - if (proc_desc) - { - if (PROC_DESC_IS_DYN_SIGTRAMP (proc_desc)) - return PROC_LOW_ADDR (proc_desc); /* "prologue" is in kernel */ - - /* If function is frameless, then we need to do it the hard way. I - strongly suspect that frameless always means prologueless... */ - if (PROC_FRAME_REG (proc_desc) == SP_REGNUM - && PROC_FRAME_OFFSET (proc_desc) == 0) - return 0; - } - - if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - return 0; /* Unknown */ - - sal = find_pc_line (func_addr, 0); - - if (sal.end < func_end) - return sal.end; - - /* The line after the prologue is after the end of the function. In this - case, tell the caller to find the prologue the hard way. */ - - return 0; -} - -/* Return non-zero if we *might* be in a function prologue. Return zero if we - are definitively *not* in a function prologue. */ - -static int -alpha_in_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc) -{ - CORE_ADDR after_prologue_pc; - - after_prologue_pc = after_prologue (pc, proc_desc); - - if (after_prologue_pc == 0 - || pc < after_prologue_pc) - return 1; - else - return 0; -} - -static alpha_extra_func_info_t -find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame) -{ - alpha_extra_func_info_t proc_desc; - struct block *b; - struct symbol *sym; - CORE_ADDR startaddr; - - /* Try to get the proc_desc from the linked call dummy proc_descs - if the pc is in the call dummy. - This is hairy. In the case of nested dummy calls we have to find the - right proc_desc, but we might not yet know the frame for the dummy - as it will be contained in the proc_desc we are searching for. - So we have to find the proc_desc whose frame is closest to the current - stack pointer. */ - - if (PC_IN_CALL_DUMMY (pc, 0, 0)) - { - struct linked_proc_info *link; - CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM); - alpha_extra_func_info_t found_proc_desc = NULL; - long min_distance = LONG_MAX; - - for (link = linked_proc_desc_table; link; link = link->next) - { - long distance = (CORE_ADDR) PROC_DUMMY_FRAME (&link->info) - sp; - if (distance > 0 && distance < min_distance) - { - min_distance = distance; - found_proc_desc = &link->info; - } - } - if (found_proc_desc != NULL) - return found_proc_desc; - } - - b = block_for_pc (pc); - - find_pc_partial_function (pc, NULL, &startaddr, NULL); - if (b == NULL) - sym = NULL; - else - { - if (startaddr > BLOCK_START (b)) - /* This is the "pathological" case referred to in a comment in - print_frame_info. It might be better to move this check into - symbol reading. */ - sym = NULL; - else - sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, - 0, NULL); - } - - /* If we never found a PDR for this function in symbol reading, then - examine prologues to find the information. */ - if (sym && ((mips_extra_func_info_t) SYMBOL_VALUE (sym))->pdr.framereg == -1) - sym = NULL; - - if (sym) - { - /* IF this is the topmost frame AND - * (this proc does not have debugging information OR - * the PC is in the procedure prologue) - * THEN create a "heuristic" proc_desc (by analyzing - * the actual code) to replace the "official" proc_desc. - */ - proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym); - if (next_frame == NULL) - { - if (PROC_DESC_IS_DUMMY (proc_desc) || alpha_in_prologue (pc, proc_desc)) - { - alpha_extra_func_info_t found_heuristic = - heuristic_proc_desc (PROC_LOW_ADDR (proc_desc), - pc, next_frame); - if (found_heuristic) - { - PROC_LOCALOFF (found_heuristic) = - PROC_LOCALOFF (proc_desc); - PROC_PC_REG (found_heuristic) = PROC_PC_REG (proc_desc); - proc_desc = found_heuristic; - } - } - } - } - else - { - long offset; - - /* Is linked_proc_desc_table really necessary? It only seems to be used - by procedure call dummys. However, the procedures being called ought - to have their own proc_descs, and even if they don't, - heuristic_proc_desc knows how to create them! */ - - register struct linked_proc_info *link; - for (link = linked_proc_desc_table; link; link = link->next) - if (PROC_LOW_ADDR (&link->info) <= pc - && PROC_HIGH_ADDR (&link->info) > pc) - return &link->info; - - /* If PC is inside a dynamically generated sigtramp handler, - create and push a procedure descriptor for that code: */ - offset = DYNAMIC_SIGTRAMP_OFFSET (pc); - if (offset >= 0) - return push_sigtramp_desc (pc - offset); - - /* If heuristic_fence_post is non-zero, determine the procedure - start address by examining the instructions. - This allows us to find the start address of static functions which - have no symbolic information, as startaddr would have been set to - the preceding global function start address by the - find_pc_partial_function call above. */ - if (startaddr == 0 || heuristic_fence_post != 0) - startaddr = heuristic_proc_start (pc); - - proc_desc = - heuristic_proc_desc (startaddr, pc, next_frame); - } - return proc_desc; -} - -alpha_extra_func_info_t cached_proc_desc; - -CORE_ADDR -alpha_frame_chain (struct frame_info *frame) -{ - alpha_extra_func_info_t proc_desc; - CORE_ADDR saved_pc = FRAME_SAVED_PC (frame); - - if (saved_pc == 0 || inside_entry_file (saved_pc)) - return 0; - - proc_desc = find_proc_desc (saved_pc, frame); - if (!proc_desc) - return 0; - - cached_proc_desc = proc_desc; - - /* Fetch the frame pointer for a dummy frame from the procedure - descriptor. */ - if (PROC_DESC_IS_DUMMY (proc_desc)) - return (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc); - - /* If no frame pointer and frame size is zero, we must be at end - of stack (or otherwise hosed). If we don't check frame size, - we loop forever if we see a zero size frame. */ - if (PROC_FRAME_REG (proc_desc) == SP_REGNUM - && PROC_FRAME_OFFSET (proc_desc) == 0 - /* The previous frame from a sigtramp frame might be frameless - and have frame size zero. */ - && !frame->signal_handler_caller) - return FRAME_PAST_SIGTRAMP_FRAME (frame, saved_pc); - else - return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc)) - + PROC_FRAME_OFFSET (proc_desc); -} - -void -alpha_print_extra_frame_info (struct frame_info *fi) -{ - if (fi - && fi->extra_info - && fi->extra_info->proc_desc - && fi->extra_info->proc_desc->pdr.framereg < NUM_REGS) - printf_filtered (" frame pointer is at %s+%s\n", - REGISTER_NAME (fi->extra_info->proc_desc->pdr.framereg), - paddr_d (fi->extra_info->proc_desc->pdr.frameoffset)); -} - -void -alpha_init_extra_frame_info (int fromleaf, struct frame_info *frame) -{ - /* Use proc_desc calculated in frame_chain */ - alpha_extra_func_info_t proc_desc = - frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next); - - frame->extra_info = (struct frame_extra_info *) - frame_obstack_alloc (sizeof (struct frame_extra_info)); - - frame->saved_regs = NULL; - frame->extra_info->localoff = 0; - frame->extra_info->pc_reg = RA_REGNUM; - frame->extra_info->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc; - if (proc_desc) - { - /* Get the locals offset and the saved pc register from the - procedure descriptor, they are valid even if we are in the - middle of the prologue. */ - frame->extra_info->localoff = PROC_LOCALOFF (proc_desc); - frame->extra_info->pc_reg = PROC_PC_REG (proc_desc); - - /* Fixup frame-pointer - only needed for top frame */ - - /* Fetch the frame pointer for a dummy frame from the procedure - descriptor. */ - if (PROC_DESC_IS_DUMMY (proc_desc)) - frame->frame = (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc); - - /* This may not be quite right, if proc has a real frame register. - Get the value of the frame relative sp, procedure might have been - interrupted by a signal at it's very start. */ - else if (frame->pc == PROC_LOW_ADDR (proc_desc) - && !PROC_DESC_IS_DYN_SIGTRAMP (proc_desc)) - frame->frame = read_next_frame_reg (frame->next, SP_REGNUM); - else - frame->frame = read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc)) - + PROC_FRAME_OFFSET (proc_desc); - - if (proc_desc == &temp_proc_desc) - { - char *name; - - /* Do not set the saved registers for a sigtramp frame, - alpha_find_saved_registers will do that for us. - We can't use frame->signal_handler_caller, it is not yet set. */ - find_pc_partial_function (frame->pc, &name, - (CORE_ADDR *) NULL, (CORE_ADDR *) NULL); - if (!IN_SIGTRAMP (frame->pc, name)) - { - frame->saved_regs = (CORE_ADDR *) - frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS); - memcpy (frame->saved_regs, temp_saved_regs, - SIZEOF_FRAME_SAVED_REGS); - frame->saved_regs[PC_REGNUM] - = frame->saved_regs[RA_REGNUM]; - } - } + case 8: + memcpy (out, in, 8); + break; + default: + error ("Cannot retrieve value from floating point register"); } } -CORE_ADDR -alpha_frame_locals_address (struct frame_info *fi) +static void +alpha_value_to_register (struct frame_info *frame, int regnum, + struct type *valtype, const void *in) { - return (fi->frame - fi->extra_info->localoff); -} - -CORE_ADDR -alpha_frame_args_address (struct frame_info *fi) -{ - return (fi->frame - (ALPHA_NUM_ARG_REGS * 8)); -} - -/* ALPHA stack frames are almost impenetrable. When execution stops, - we basically have to look at symbol information for the function - that we stopped in, which tells us *which* register (if any) is - the base of the frame pointer, and what offset from that register - the frame itself is at. - - This presents a problem when trying to examine a stack in memory - (that isn't executing at the moment), using the "frame" command. We - don't have a PC, nor do we have any registers except SP. - - This routine takes two arguments, SP and PC, and tries to make the - cached frames look as if these two arguments defined a frame on the - cache. This allows the rest of info frame to extract the important - arguments without difficulty. */ - -struct frame_info * -setup_arbitrary_frame (int argc, CORE_ADDR *argv) -{ - if (argc != 2) - error ("ALPHA frame specifications require two arguments: sp and pc"); - - return create_new_frame (argv[0], argv[1]); + char out[MAX_REGISTER_SIZE]; + switch (TYPE_LENGTH (valtype)) + { + case 4: + alpha_lds (out, in); + break; + case 8: + memcpy (out, in, 8); + break; + default: + error ("Cannot store value in floating point register"); + } + put_frame_register (frame, regnum, out); } + /* The alpha passes the first six arguments in the registers, the rest on - the stack. The register arguments are eventually transferred to the - argument transfer area immediately below the stack by the called function - anyway. So we `push' at least six arguments on the stack, `reload' the - argument registers and then adjust the stack pointer to point past the - sixth argument. This algorithm simplifies the passing of a large struct - which extends from the registers to the stack. + the stack. The register arguments are stored in ARG_REG_BUFFER, and + then moved into the register file; this simplifies the passing of a + large struct which extends from the registers to the stack, plus avoids + three ptrace invocations per word. + + We don't bother tracking which register values should go in integer + regs or fp regs; we load the same values into both. + If the called function is returning a structure, the address of the structure to be returned is passed as a hidden first argument. */ -CORE_ADDR -alpha_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) +static CORE_ADDR +alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) { int i; int accumulate_size = struct_return ? 8 : 0; - int arg_regs_size = ALPHA_NUM_ARG_REGS * 8; struct alpha_arg { char *contents; int len; int offset; }; - struct alpha_arg *alpha_args = - (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg)); - register struct alpha_arg *m_arg; - char raw_buffer[sizeof (CORE_ADDR)]; + struct alpha_arg *alpha_args + = (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg)); + struct alpha_arg *m_arg; + char arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS]; int required_arg_regs; + /* The ABI places the address of the called function in T12. */ + regcache_cooked_write_signed (regcache, ALPHA_T12_REGNUM, func_addr); + + /* Set the return address register to point to the entry point + of the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, ALPHA_RA_REGNUM, bp_addr); + + /* Lay out the arguments in memory. */ for (i = 0, m_arg = alpha_args; i < nargs; i++, m_arg++) { struct value *arg = args[i]; struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + /* Cast argument to long if necessary as the compiler does it too. */ switch (TYPE_CODE (arg_type)) { @@ -1058,12 +303,66 @@ alpha_push_arguments (int nargs, struct value **args, CORE_ADDR sp, case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: case TYPE_CODE_ENUM: - if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long)) + if (TYPE_LENGTH (arg_type) == 4) { - arg_type = builtin_type_long; + /* 32-bit values must be sign-extended to 64 bits + even if the base data type is unsigned. */ + arg_type = builtin_type_int32; + arg = value_cast (arg_type, arg); + } + if (TYPE_LENGTH (arg_type) < ALPHA_REGISTER_SIZE) + { + arg_type = builtin_type_int64; arg = value_cast (arg_type, arg); } break; + + case TYPE_CODE_FLT: + /* "float" arguments loaded in registers must be passed in + register format, aka "double". */ + if (accumulate_size < sizeof (arg_reg_buffer) + && TYPE_LENGTH (arg_type) == 4) + { + arg_type = builtin_type_ieee_double_little; + arg = value_cast (arg_type, arg); + } + /* Tru64 5.1 has a 128-bit long double, and passes this by + invisible reference. No one else uses this data type. */ + else if (TYPE_LENGTH (arg_type) == 16) + { + /* Allocate aligned storage. */ + sp = (sp & -16) - 16; + + /* Write the real data into the stack. */ + write_memory (sp, VALUE_CONTENTS (arg), 16); + + /* Construct the indirection. */ + arg_type = lookup_pointer_type (arg_type); + arg = value_from_pointer (arg_type, sp); + } + break; + + case TYPE_CODE_COMPLEX: + /* ??? The ABI says that complex values are passed as two + separate scalar values. This distinction only matters + for complex float. However, GCC does not implement this. */ + + /* Tru64 5.1 has a 128-bit long double, and passes this by + invisible reference. */ + if (TYPE_LENGTH (arg_type) == 32) + { + /* Allocate aligned storage. */ + sp = (sp & -16) - 16; + + /* Write the real data into the stack. */ + write_memory (sp, VALUE_CONTENTS (arg), 32); + + /* Construct the indirection. */ + arg_type = lookup_pointer_type (arg_type); + arg = value_from_pointer (arg_type, sp); + } + break; + default: break; } @@ -1080,246 +379,289 @@ alpha_push_arguments (int nargs, struct value **args, CORE_ADDR sp, required_arg_regs = ALPHA_NUM_ARG_REGS; /* Make room for the arguments on the stack. */ - if (accumulate_size < arg_regs_size) - accumulate_size = arg_regs_size; + if (accumulate_size < sizeof(arg_reg_buffer)) + accumulate_size = 0; + else + accumulate_size -= sizeof(arg_reg_buffer); sp -= accumulate_size; - /* Keep sp aligned to a multiple of 16 as the compiler does it too. */ + /* Keep sp aligned to a multiple of 16 as the ABI requires. */ sp &= ~15; /* `Push' arguments on the stack. */ for (i = nargs; m_arg--, --i >= 0;) - write_memory (sp + m_arg->offset, m_arg->contents, m_arg->len); - if (struct_return) { - store_address (raw_buffer, sizeof (CORE_ADDR), struct_addr); - write_memory (sp, raw_buffer, sizeof (CORE_ADDR)); + char *contents = m_arg->contents; + int offset = m_arg->offset; + int len = m_arg->len; + + /* Copy the bytes destined for registers into arg_reg_buffer. */ + if (offset < sizeof(arg_reg_buffer)) + { + if (offset + len <= sizeof(arg_reg_buffer)) + { + memcpy (arg_reg_buffer + offset, contents, len); + continue; + } + else + { + int tlen = sizeof(arg_reg_buffer) - offset; + memcpy (arg_reg_buffer + offset, contents, tlen); + offset += tlen; + contents += tlen; + len -= tlen; + } + } + + /* Everything else goes to the stack. */ + write_memory (sp + offset - sizeof(arg_reg_buffer), contents, len); } + if (struct_return) + store_unsigned_integer (arg_reg_buffer, ALPHA_REGISTER_SIZE, struct_addr); /* Load the argument registers. */ for (i = 0; i < required_arg_regs; i++) { - LONGEST val; - - val = read_memory_integer (sp + i * 8, 8); - write_register (A0_REGNUM + i, val); - write_register (FPA0_REGNUM + i, val); + regcache_cooked_write (regcache, ALPHA_A0_REGNUM + i, + arg_reg_buffer + i*ALPHA_REGISTER_SIZE); + regcache_cooked_write (regcache, ALPHA_FPA0_REGNUM + i, + arg_reg_buffer + i*ALPHA_REGISTER_SIZE); } - return sp + arg_regs_size; + /* Finally, update the stack pointer. */ + regcache_cooked_write_signed (regcache, ALPHA_SP_REGNUM, sp); + + return sp; } -void -alpha_push_dummy_frame (void) +/* Extract from REGCACHE the value about to be returned from a function + and copy it into VALBUF. */ + +static void +alpha_extract_return_value (struct type *valtype, struct regcache *regcache, + void *valbuf) { - int ireg; - struct linked_proc_info *link; - alpha_extra_func_info_t proc_desc; - CORE_ADDR sp = read_register (SP_REGNUM); - CORE_ADDR save_address; - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - unsigned long mask; + int length = TYPE_LENGTH (valtype); + char raw_buffer[ALPHA_REGISTER_SIZE]; + ULONGEST l; - link = (struct linked_proc_info *) xmalloc (sizeof (struct linked_proc_info)); - link->next = linked_proc_desc_table; - linked_proc_desc_table = link; - - proc_desc = &link->info; - - /* - * The registers we must save are all those not preserved across - * procedure calls. - * In addition, we must save the PC and RA. - * - * Dummy frame layout: - * (high memory) - * Saved PC - * Saved F30 - * ... - * Saved F0 - * Saved R29 - * ... - * Saved R0 - * Saved R26 (RA) - * Parameter build area - * (low memory) - */ - -/* MASK(i,j) == (1<>= 1) - if (mask & 1) - { - if (ireg == RA_REGNUM) - continue; - store_address (raw_buffer, 8, read_register (ireg)); - write_memory (save_address, raw_buffer, 8); - save_address += 8; - } - - store_address (raw_buffer, 8, read_register (PC_REGNUM)); - write_memory (sp - 8, raw_buffer, 8); - - /* Save floating point registers. */ - save_address = sp + PROC_FREG_OFFSET (proc_desc); - mask = PROC_FREG_MASK (proc_desc) & 0xffffffffL; - for (ireg = 0; mask; ireg++, mask >>= 1) - if (mask & 1) - { - store_address (raw_buffer, 8, read_register (ireg + FP0_REGNUM)); - write_memory (save_address, raw_buffer, 8); - save_address += 8; - } - - /* Set and save the frame address for the dummy. - This is tricky. The only registers that are suitable for a frame save - are those that are preserved across procedure calls (s0-s6). But if - a read system call is interrupted and then a dummy call is made - (see testsuite/gdb.t17/interrupt.exp) the dummy call hangs till the read - is satisfied. Then it returns with the s0-s6 registers set to the values - on entry to the read system call and our dummy frame pointer would be - destroyed. So we save the dummy frame in the proc_desc and handle the - retrieval of the frame pointer of a dummy specifically. The frame register - is set to the virtual frame (pseudo) register, it's value will always - be read as zero and will help us to catch any errors in the dummy frame - retrieval code. */ - PROC_DUMMY_FRAME (proc_desc) = sp; - PROC_FRAME_REG (proc_desc) = FP_REGNUM; - PROC_FRAME_OFFSET (proc_desc) = 0; - sp += PROC_REG_OFFSET (proc_desc); - write_register (SP_REGNUM, sp); - - PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS (); - PROC_HIGH_ADDR (proc_desc) = PROC_LOW_ADDR (proc_desc) + 4; - - SET_PROC_DESC_IS_DUMMY (proc_desc); - PROC_PC_REG (proc_desc) = RA_REGNUM; -} - -void -alpha_pop_frame (void) -{ - register int regnum; - struct frame_info *frame = get_current_frame (); - CORE_ADDR new_sp = frame->frame; - - alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc; - - /* we need proc_desc to know how to restore the registers; - if it is NULL, construct (a temporary) one */ - if (proc_desc == NULL) - proc_desc = find_proc_desc (frame->pc, frame->next); - - /* Question: should we copy this proc_desc and save it in - frame->proc_desc? If we do, who will free it? - For now, we don't save a copy... */ - - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - if (frame->saved_regs == NULL) - alpha_find_saved_regs (frame); - if (proc_desc) + switch (TYPE_CODE (valtype)) { - for (regnum = 32; --regnum >= 0;) - if (PROC_REG_MASK (proc_desc) & (1 << regnum)) - write_register (regnum, - read_memory_integer (frame->saved_regs[regnum], - 8)); - for (regnum = 32; --regnum >= 0;) - if (PROC_FREG_MASK (proc_desc) & (1 << regnum)) - write_register (regnum + FP0_REGNUM, - read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8)); - } - write_register (SP_REGNUM, new_sp); - flush_cached_frames (); - - if (proc_desc && (PROC_DESC_IS_DUMMY (proc_desc) - || PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))) - { - struct linked_proc_info *pi_ptr, *prev_ptr; - - for (pi_ptr = linked_proc_desc_table, prev_ptr = NULL; - pi_ptr != NULL; - prev_ptr = pi_ptr, pi_ptr = pi_ptr->next) + case TYPE_CODE_FLT: + switch (length) { - if (&pi_ptr->info == proc_desc) - break; + case 4: + regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, raw_buffer); + alpha_sts (valbuf, raw_buffer); + break; + + case 8: + regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf); + break; + + case 16: + regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l); + read_memory (l, valbuf, 16); + break; + + default: + internal_error (__FILE__, __LINE__, "unknown floating point width"); } + break; - if (pi_ptr == NULL) - error ("Can't locate dummy extra frame info\n"); + case TYPE_CODE_COMPLEX: + switch (length) + { + case 8: + /* ??? This isn't correct wrt the ABI, but it's what GCC does. */ + regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf); + break; - if (prev_ptr != NULL) - prev_ptr->next = pi_ptr->next; - else - linked_proc_desc_table = pi_ptr->next; + case 16: + regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf); + regcache_cooked_read (regcache, ALPHA_FP0_REGNUM+1, + (char *)valbuf + 8); + break; - xfree (pi_ptr); + case 32: + regcache_cooked_read_signed (regcache, ALPHA_V0_REGNUM, &l); + read_memory (l, valbuf, 32); + break; + + default: + internal_error (__FILE__, __LINE__, "unknown floating point width"); + } + break; + + default: + /* Assume everything else degenerates to an integer. */ + regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l); + store_unsigned_integer (valbuf, length, l); + break; } } + +/* Extract from REGCACHE the address of a structure about to be returned + from a function. */ + +static CORE_ADDR +alpha_extract_struct_value_address (struct regcache *regcache) +{ + ULONGEST addr; + regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &addr); + return addr; +} + +/* Insert the given value into REGCACHE as if it was being + returned by a function. */ + +static void +alpha_store_return_value (struct type *valtype, struct regcache *regcache, + const void *valbuf) +{ + int length = TYPE_LENGTH (valtype); + char raw_buffer[ALPHA_REGISTER_SIZE]; + ULONGEST l; + + switch (TYPE_CODE (valtype)) + { + case TYPE_CODE_FLT: + switch (length) + { + case 4: + alpha_lds (raw_buffer, valbuf); + regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, raw_buffer); + break; + + case 8: + regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf); + break; + + case 16: + /* FIXME: 128-bit long doubles are returned like structures: + by writing into indirect storage provided by the caller + as the first argument. */ + error ("Cannot set a 128-bit long double return value."); + + default: + internal_error (__FILE__, __LINE__, "unknown floating point width"); + } + break; + + case TYPE_CODE_COMPLEX: + switch (length) + { + case 8: + /* ??? This isn't correct wrt the ABI, but it's what GCC does. */ + regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf); + break; + + case 16: + regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf); + regcache_cooked_write (regcache, ALPHA_FP0_REGNUM+1, + (const char *)valbuf + 8); + break; + + case 32: + /* FIXME: 128-bit long doubles are returned like structures: + by writing into indirect storage provided by the caller + as the first argument. */ + error ("Cannot set a 128-bit long double return value."); + + default: + internal_error (__FILE__, __LINE__, "unknown floating point width"); + } + break; + + default: + /* Assume everything else degenerates to an integer. */ + /* 32-bit values must be sign-extended to 64 bits + even if the base data type is unsigned. */ + if (length == 4) + valtype = builtin_type_int32; + l = unpack_long (valtype, valbuf); + regcache_cooked_write_unsigned (regcache, ALPHA_V0_REGNUM, l); + break; + } +} + +static const unsigned char * +alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +{ + static const unsigned char alpha_breakpoint[] = + { 0x80, 0, 0, 0 }; /* call_pal bpt */ + + *lenptr = sizeof(alpha_breakpoint); + return (alpha_breakpoint); +} + + +/* This returns the PC of the first insn after the prologue. + If we can't find the prologue, then return 0. */ + +CORE_ADDR +alpha_after_prologue (CORE_ADDR pc) +{ + struct symtab_and_line sal; + CORE_ADDR func_addr, func_end; + + if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) + return 0; + + sal = find_pc_line (func_addr, 0); + if (sal.end < func_end) + return sal.end; + + /* The line after the prologue is after the end of the function. In this + case, tell the caller to find the prologue the hard way. */ + return 0; +} + +/* Read an instruction from memory at PC, looking through breakpoints. */ + +unsigned int +alpha_read_insn (CORE_ADDR pc) +{ + char buf[4]; + int status; + + status = read_memory_nobpt (pc, buf, 4); + if (status) + memory_error (status, pc); + return extract_unsigned_integer (buf, 4); +} + /* To skip prologues, I use this predicate. Returns either PC itself if the code at PC does not look like a function prologue; otherwise returns an address that (if we're lucky) follows the prologue. If LENIENT, then we must skip everything which is involved in setting up the frame (it's OK to skip more, just so long as we don't skip - anything which might clobber the registers which are being saved. - Currently we must not skip more on the alpha, but we might need the - lenient stuff some day. */ + anything which might clobber the registers which are being saved. */ static CORE_ADDR -alpha_skip_prologue_internal (CORE_ADDR pc, int lenient) +alpha_skip_prologue (CORE_ADDR pc) { unsigned long inst; int offset; CORE_ADDR post_prologue_pc; char buf[4]; -#ifdef GDB_TARGET_HAS_SHARED_LIBS /* Silently return the unaltered pc upon memory errors. This could happen on OSF/1 if decode_line_1 tries to skip the prologue for quickstarted shared library functions when the shared library is not yet mapped in. Reading target memory is slow over serial lines, so we perform - this check only if the target has shared libraries. */ + this check only if the target has shared libraries (which all + Alpha targets do). */ if (target_read_memory (pc, buf, 4)) return pc; -#endif /* See if we can determine the end of the prologue via the symbol table. If so, then return either PC, or the PC after the prologue, whichever is greater. */ - post_prologue_pc = after_prologue (pc, NULL); - + post_prologue_pc = alpha_after_prologue (pc); if (post_prologue_pc != 0) return max (pc, post_prologue_pc); @@ -1331,17 +673,7 @@ alpha_skip_prologue_internal (CORE_ADDR pc, int lenient) or in the gcc frame. */ for (offset = 0; offset < 100; offset += 4) { - int status; - - status = read_memory_nobpt (pc + offset, buf, 4); - if (status) - memory_error (status, pc + offset); - inst = extract_unsigned_integer (buf, 4); - - /* The alpha has no delay slots. But let's keep the lenient stuff, - we might need it for something else in the future. */ - if (lenient && 0) - continue; + inst = alpha_read_insn (pc + offset); if ((inst & 0xffff0000) == 0x27bb0000) /* ldah $gp,n($t12) */ continue; @@ -1352,15 +684,14 @@ alpha_skip_prologue_internal (CORE_ADDR pc, int lenient) if ((inst & 0xffe01fff) == 0x43c0153e) /* subq $sp,n,$sp */ continue; - if ((inst & 0xfc1f0000) == 0xb41e0000 - && (inst & 0xffff0000) != 0xb7fe0000) - continue; /* stq reg,n($sp) */ - /* reg != $zero */ - if ((inst & 0xfc1f0000) == 0x9c1e0000 - && (inst & 0xffff0000) != 0x9ffe0000) - continue; /* stt reg,n($sp) */ - /* reg != $zero */ - if (inst == 0x47de040f) /* bis sp,sp,fp */ + if (((inst & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */ + || (inst & 0xfc1f0000) == 0x9c1e0000) /* stt reg,n($sp) */ + && (inst & 0x03e00000) != 0x03e00000) /* reg != $zero */ + continue; + + if (inst == 0x47de040f) /* bis sp,sp,fp */ + continue; + if (inst == 0x47fe040f) /* bis zero,sp,fp */ continue; break; @@ -1368,124 +699,536 @@ alpha_skip_prologue_internal (CORE_ADDR pc, int lenient) return pc + offset; } -CORE_ADDR -alpha_skip_prologue (CORE_ADDR addr) -{ - return (alpha_skip_prologue_internal (addr, 0)); -} - -#if 0 -/* Is address PC in the prologue (loosely defined) for function at - STARTADDR? */ + +/* Figure out where the longjmp will land. + We expect the first arg to be a pointer to the jmp_buf structure from + which we extract the PC (JB_PC) that we will land at. The PC is copied + into the "pc". This routine returns true on success. */ static int -alpha_in_lenient_prologue (CORE_ADDR startaddr, CORE_ADDR pc) +alpha_get_longjmp_target (CORE_ADDR *pc) { - CORE_ADDR end_prologue = alpha_skip_prologue_internal (startaddr, 1); - return pc >= startaddr && pc < end_prologue; -} -#endif + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + CORE_ADDR jb_addr; + char raw_buffer[ALPHA_REGISTER_SIZE]; -/* The alpha needs a conversion between register and memory format if - the register is a floating point register and - memory format is float, as the register format must be double - or - memory format is an integer with 4 bytes or less, as the representation - of integers in floating point registers is different. */ -void -alpha_register_convert_to_virtual (int regnum, struct type *valtype, - char *raw_buffer, char *virtual_buffer) -{ - if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum)) - { - memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum)); - return; - } + jb_addr = read_register (ALPHA_A0_REGNUM); - if (TYPE_CODE (valtype) == TYPE_CODE_FLT) - { - double d = extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum)); - store_floating (virtual_buffer, TYPE_LENGTH (valtype), d); - } - else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4) - { - ULONGEST l; - l = extract_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum)); - l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff); - store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l); - } - else - error ("Cannot retrieve value from floating point register"); + if (target_read_memory (jb_addr + (tdep->jb_pc * tdep->jb_elt_size), + raw_buffer, tdep->jb_elt_size)) + return 0; + + *pc = extract_unsigned_integer (raw_buffer, tdep->jb_elt_size); + return 1; } -void -alpha_register_convert_to_raw (struct type *valtype, int regnum, - char *virtual_buffer, char *raw_buffer) -{ - if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum)) - { - memcpy (raw_buffer, virtual_buffer, REGISTER_RAW_SIZE (regnum)); - return; - } + +/* Frame unwinder for signal trampolines. We use alpha tdep bits that + describe the location and shape of the sigcontext structure. After + that, all registers are in memory, so it's easy. */ +/* ??? Shouldn't we be able to do this generically, rather than with + OSABI data specific to Alpha? */ - if (TYPE_CODE (valtype) == TYPE_CODE_FLT) +struct alpha_sigtramp_unwind_cache +{ + CORE_ADDR sigcontext_addr; +}; + +static struct alpha_sigtramp_unwind_cache * +alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct alpha_sigtramp_unwind_cache *info; + struct gdbarch_tdep *tdep; + + if (*this_prologue_cache) + return *this_prologue_cache; + + info = FRAME_OBSTACK_ZALLOC (struct alpha_sigtramp_unwind_cache); + *this_prologue_cache = info; + + tdep = gdbarch_tdep (current_gdbarch); + info->sigcontext_addr = tdep->sigcontext_addr (next_frame); + + return info; +} + +/* Return the address of REGNUM in a sigtramp frame. Since this is + all arithmetic, it doesn't seem worthwhile to cache it. */ + +static CORE_ADDR +alpha_sigtramp_register_address (CORE_ADDR sigcontext_addr, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (regnum >= 0 && regnum < 32) + return sigcontext_addr + tdep->sc_regs_offset + regnum * 8; + else if (regnum >= ALPHA_FP0_REGNUM && regnum < ALPHA_FP0_REGNUM + 32) + return sigcontext_addr + tdep->sc_fpregs_offset + regnum * 8; + else if (regnum == ALPHA_PC_REGNUM) + return sigcontext_addr + tdep->sc_pc_offset; + + return 0; +} + +/* Given a GDB frame, determine the address of the calling function's + frame. This will be used to create a new GDB frame struct. */ + +static void +alpha_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct alpha_sigtramp_unwind_cache *info + = alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache); + struct gdbarch_tdep *tdep; + CORE_ADDR stack_addr, code_addr; + + /* If the OSABI couldn't locate the sigcontext, give up. */ + if (info->sigcontext_addr == 0) + return; + + /* If we have dynamic signal trampolines, find their start. + If we do not, then we must assume there is a symbol record + that can provide the start address. */ + tdep = gdbarch_tdep (current_gdbarch); + if (tdep->dynamic_sigtramp_offset) { - double d = extract_floating (virtual_buffer, TYPE_LENGTH (valtype)); - store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d); - } - else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4) - { - ULONGEST l; - if (TYPE_UNSIGNED (valtype)) - l = extract_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype)); + int offset; + code_addr = frame_pc_unwind (next_frame); + offset = tdep->dynamic_sigtramp_offset (code_addr); + if (offset >= 0) + code_addr -= offset; else - l = extract_signed_integer (virtual_buffer, TYPE_LENGTH (valtype)); - l = ((l & 0xc0000000) << 32) | ((l & 0x3fffffff) << 29); - store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), l); + code_addr = 0; } else - error ("Cannot store value in floating point register"); + code_addr = frame_func_unwind (next_frame); + + /* The stack address is trivially read from the sigcontext. */ + stack_addr = alpha_sigtramp_register_address (info->sigcontext_addr, + ALPHA_SP_REGNUM); + stack_addr = get_frame_memory_unsigned (next_frame, stack_addr, + ALPHA_REGISTER_SIZE); + + *this_id = frame_id_build (stack_addr, code_addr); } -/* Given a return value in `regbuf' with a type `valtype', - extract and copy its value into `valbuf'. */ +/* Retrieve the value of REGNUM in FRAME. Don't give up! */ -void -alpha_extract_return_value (struct type *valtype, - char regbuf[REGISTER_BYTES], char *valbuf) +static void +alpha_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) { - if (TYPE_CODE (valtype) == TYPE_CODE_FLT) - alpha_register_convert_to_virtual (FP0_REGNUM, valtype, - regbuf + REGISTER_BYTE (FP0_REGNUM), - valbuf); - else - memcpy (valbuf, regbuf + REGISTER_BYTE (V0_REGNUM), TYPE_LENGTH (valtype)); -} + struct alpha_sigtramp_unwind_cache *info + = alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache); + CORE_ADDR addr; -/* Given a return value in `regbuf' with a type `valtype', - write its value into the appropriate register. */ - -void -alpha_store_return_value (struct type *valtype, char *valbuf) -{ - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - int regnum = V0_REGNUM; - int length = TYPE_LENGTH (valtype); - - if (TYPE_CODE (valtype) == TYPE_CODE_FLT) + if (info->sigcontext_addr != 0) { - regnum = FP0_REGNUM; - length = REGISTER_RAW_SIZE (regnum); - alpha_register_convert_to_raw (valtype, regnum, valbuf, raw_buffer); + /* All integer and fp registers are stored in memory. */ + addr = alpha_sigtramp_register_address (info->sigcontext_addr, regnum); + if (addr != 0) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = addr; + *realnump = -1; + if (bufferp != NULL) + get_frame_memory (next_frame, addr, bufferp, ALPHA_REGISTER_SIZE); + return; + } } - else - memcpy (raw_buffer, valbuf, length); - write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, length); + /* This extra register may actually be in the sigcontext, but our + current description of it in alpha_sigtramp_frame_unwind_cache + doesn't include it. Too bad. Fall back on whatever's in the + outer frame. */ + frame_register (next_frame, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); } +static const struct frame_unwind alpha_sigtramp_frame_unwind = { + SIGTRAMP_FRAME, + alpha_sigtramp_frame_this_id, + alpha_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +alpha_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + /* We shouldn't even bother to try if the OSABI didn't register + a sigcontext_addr handler. */ + if (!gdbarch_tdep (current_gdbarch)->sigcontext_addr) + return NULL; + + /* Otherwise we should be in a signal frame. */ + find_pc_partial_function (pc, &name, NULL, NULL); + if (PC_IN_SIGTRAMP (pc, name)) + return &alpha_sigtramp_frame_unwind; + + return NULL; +} + +/* Fallback alpha frame unwinder. Uses instruction scanning and knows + something about the traditional layout of alpha stack frames. */ + +struct alpha_heuristic_unwind_cache +{ + CORE_ADDR *saved_regs; + CORE_ADDR vfp; + CORE_ADDR start_pc; + int return_reg; +}; + +/* Heuristic_proc_start may hunt through the text section for a long + time across a 2400 baud serial line. Allows the user to limit this + search. */ +static unsigned int heuristic_fence_post = 0; + +/* Attempt to locate the start of the function containing PC. We assume that + the previous function ends with an about_to_return insn. Not foolproof by + any means, since gcc is happy to put the epilogue in the middle of a + function. But we're guessing anyway... */ + +static CORE_ADDR +alpha_heuristic_proc_start (CORE_ADDR pc) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + CORE_ADDR last_non_nop = pc; + CORE_ADDR fence = pc - heuristic_fence_post; + CORE_ADDR orig_pc = pc; + CORE_ADDR func; + + if (pc == 0) + return 0; + + /* First see if we can find the start of the function from minimal + symbol information. This can succeed with a binary that doesn't + have debug info, but hasn't been stripped. */ + func = get_pc_function_start (pc); + if (func) + return func; + + if (heuristic_fence_post == UINT_MAX + || fence < tdep->vm_min_address) + fence = tdep->vm_min_address; + + /* Search back for previous return; also stop at a 0, which might be + seen for instance before the start of a code section. Don't include + nops, since this usually indicates padding between functions. */ + for (pc -= 4; pc >= fence; pc -= 4) + { + unsigned int insn = alpha_read_insn (pc); + switch (insn) + { + case 0: /* invalid insn */ + case 0x6bfa8001: /* ret $31,($26),1 */ + return last_non_nop; + + case 0x2ffe0000: /* unop: ldq_u $31,0($30) */ + case 0x47ff041f: /* nop: bis $31,$31,$31 */ + break; + + default: + last_non_nop = pc; + break; + } + } + + /* It's not clear to me why we reach this point when stopping quietly, + but with this test, at least we don't print out warnings for every + child forked (eg, on decstation). 22apr93 rich@cygnus.com. */ + if (stop_soon == NO_STOP_QUIETLY) + { + static int blurb_printed = 0; + + if (fence == tdep->vm_min_address) + warning ("Hit beginning of text section without finding"); + else + warning ("Hit heuristic-fence-post without finding"); + warning ("enclosing function for address 0x%s", paddr_nz (orig_pc)); + + if (!blurb_printed) + { + printf_filtered ("\ +This warning occurs if you are debugging a function without any symbols\n\ +(for example, in a stripped executable). In that case, you may wish to\n\ +increase the size of the search with the `set heuristic-fence-post' command.\n\ +\n\ +Otherwise, you told GDB there was a function where there isn't one, or\n\ +(more likely) you have encountered a bug in GDB.\n"); + blurb_printed = 1; + } + } + + return 0; +} + +static struct alpha_heuristic_unwind_cache * +alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, + void **this_prologue_cache, + CORE_ADDR start_pc) +{ + struct alpha_heuristic_unwind_cache *info; + ULONGEST val; + CORE_ADDR limit_pc, cur_pc; + int frame_reg, frame_size, return_reg, reg; + + if (*this_prologue_cache) + return *this_prologue_cache; + + info = FRAME_OBSTACK_ZALLOC (struct alpha_heuristic_unwind_cache); + *this_prologue_cache = info; + info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS); + + limit_pc = frame_pc_unwind (next_frame); + if (start_pc == 0) + start_pc = alpha_heuristic_proc_start (limit_pc); + info->start_pc = start_pc; + + frame_reg = ALPHA_SP_REGNUM; + frame_size = 0; + return_reg = -1; + + /* If we've identified a likely place to start, do code scanning. */ + if (start_pc != 0) + { + /* Limit the forward search to 50 instructions. */ + if (start_pc + 200 < limit_pc) + limit_pc = start_pc + 200; + + for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) + { + unsigned int word = alpha_read_insn (cur_pc); + + if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */ + { + if (word & 0x8000) + { + /* Consider only the first stack allocation instruction + to contain the static size of the frame. */ + if (frame_size == 0) + frame_size = (-word) & 0xffff; + } + else + { + /* Exit loop if a positive stack adjustment is found, which + usually means that the stack cleanup code in the function + epilogue is reached. */ + break; + } + } + else if ((word & 0xfc1f0000) == 0xb41e0000) /* stq reg,n($sp) */ + { + reg = (word & 0x03e00000) >> 21; + + /* Ignore this instruction if we have already encountered + an instruction saving the same register earlier in the + function code. The current instruction does not tell + us where the original value upon function entry is saved. + All it says is that the function we are scanning reused + that register for some computation of its own, and is now + saving its result. */ + if (info->saved_regs[reg]) + continue; + + if (reg == 31) + continue; + + /* Do not compute the address where the register was saved yet, + because we don't know yet if the offset will need to be + relative to $sp or $fp (we can not compute the address + relative to $sp if $sp is updated during the execution of + the current subroutine, for instance when doing some alloca). + So just store the offset for the moment, and compute the + address later when we know whether this frame has a frame + pointer or not. */ + /* Hack: temporarily add one, so that the offset is non-zero + and we can tell which registers have save offsets below. */ + info->saved_regs[reg] = (word & 0xffff) + 1; + + /* Starting with OSF/1-3.2C, the system libraries are shipped + without local symbols, but they still contain procedure + descriptors without a symbol reference. GDB is currently + unable to find these procedure descriptors and uses + heuristic_proc_desc instead. + As some low level compiler support routines (__div*, __add*) + use a non-standard return address register, we have to + add some heuristics to determine the return address register, + or stepping over these routines will fail. + Usually the return address register is the first register + saved on the stack, but assembler optimization might + rearrange the register saves. + So we recognize only a few registers (t7, t9, ra) within + the procedure prologue as valid return address registers. + If we encounter a return instruction, we extract the + the return address register from it. + + FIXME: Rewriting GDB to access the procedure descriptors, + e.g. via the minimal symbol table, might obviate this hack. */ + if (return_reg == -1 + && cur_pc < (start_pc + 80) + && (reg == ALPHA_T7_REGNUM + || reg == ALPHA_T9_REGNUM + || reg == ALPHA_RA_REGNUM)) + return_reg = reg; + } + else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ + return_reg = (word >> 16) & 0x1f; + else if (word == 0x47de040f) /* bis sp,sp,fp */ + frame_reg = ALPHA_GCC_FP_REGNUM; + else if (word == 0x47fe040f) /* bis zero,sp,fp */ + frame_reg = ALPHA_GCC_FP_REGNUM; + } + + /* If we haven't found a valid return address register yet, keep + searching in the procedure prologue. */ + if (return_reg == -1) + { + while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80)) + { + unsigned int word = alpha_read_insn (cur_pc); + + if ((word & 0xfc1f0000) == 0xb41e0000) /* stq reg,n($sp) */ + { + reg = (word & 0x03e00000) >> 21; + if (reg == ALPHA_T7_REGNUM + || reg == ALPHA_T9_REGNUM + || reg == ALPHA_RA_REGNUM) + { + return_reg = reg; + break; + } + } + else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ + { + return_reg = (word >> 16) & 0x1f; + break; + } + + cur_pc += 4; + } + } + } + + /* Failing that, do default to the customary RA. */ + if (return_reg == -1) + return_reg = ALPHA_RA_REGNUM; + info->return_reg = return_reg; + + frame_unwind_unsigned_register (next_frame, frame_reg, &val); + info->vfp = val + frame_size; + + /* Convert offsets to absolute addresses. See above about adding + one to the offsets to make all detected offsets non-zero. */ + for (reg = 0; reg < ALPHA_NUM_REGS; ++reg) + if (info->saved_regs[reg]) + info->saved_regs[reg] += val - 1; + + return info; +} + +/* Given a GDB frame, determine the address of the calling function's + frame. This will be used to create a new GDB frame struct. */ + +static void +alpha_heuristic_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct alpha_heuristic_unwind_cache *info + = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0); + + *this_id = frame_id_build (info->vfp, info->start_pc); +} + +/* Retrieve the value of REGNUM in FRAME. Don't give up! */ + +static void +alpha_heuristic_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) +{ + struct alpha_heuristic_unwind_cache *info + = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0); + + /* The PC of the previous frame is stored in the link register of + the current frame. Frob regnum so that we pull the value from + the correct place. */ + if (regnum == ALPHA_PC_REGNUM) + regnum = info->return_reg; + + /* For all registers known to be saved in the current frame, + do the obvious and pull the value out. */ + if (info->saved_regs[regnum]) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = info->saved_regs[regnum]; + *realnump = -1; + if (bufferp != NULL) + get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE); + return; + } + + /* The stack pointer of the previous frame is computed by popping + the current stack frame. */ + if (regnum == ALPHA_SP_REGNUM) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (bufferp != NULL) + store_unsigned_integer (bufferp, ALPHA_REGISTER_SIZE, info->vfp); + return; + } + + /* Otherwise assume the next frame has the same register value. */ + frame_register (next_frame, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); +} + +static const struct frame_unwind alpha_heuristic_frame_unwind = { + NORMAL_FRAME, + alpha_heuristic_frame_this_id, + alpha_heuristic_frame_prev_register +}; + +static const struct frame_unwind * +alpha_heuristic_frame_sniffer (struct frame_info *next_frame) +{ + return &alpha_heuristic_frame_unwind; +} + +static CORE_ADDR +alpha_heuristic_frame_base_address (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct alpha_heuristic_unwind_cache *info + = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0); + + return info->vfp; +} + +static const struct frame_base alpha_heuristic_frame_base = { + &alpha_heuristic_frame_unwind, + alpha_heuristic_frame_base_address, + alpha_heuristic_frame_base_address, + alpha_heuristic_frame_base_address +}; + /* Just like reinit_frame_cache, but with the right arguments to be - callable as an sfunc. */ + callable as an sfunc. Used by the "set heuristic-fence-post" command. */ static void reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c) @@ -1493,68 +1236,120 @@ reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c) reinit_frame_cache (); } -/* This is the definition of CALL_DUMMY_ADDRESS. It's a heuristic that is used - to find a convenient place in the text segment to stick a breakpoint to - detect the completion of a target function call (ala call_function_by_hand). - */ + +/* ALPHA stack frames are almost impenetrable. When execution stops, + we basically have to look at symbol information for the function + that we stopped in, which tells us *which* register (if any) is + the base of the frame pointer, and what offset from that register + the frame itself is at. -CORE_ADDR -alpha_call_dummy_address (void) + This presents a problem when trying to examine a stack in memory + (that isn't executing at the moment), using the "frame" command. We + don't have a PC, nor do we have any registers except SP. + + This routine takes two arguments, SP and PC, and tries to make the + cached frames look as if these two arguments defined a frame on the + cache. This allows the rest of info frame to extract the important + arguments without difficulty. */ + +struct frame_info * +alpha_setup_arbitrary_frame (int argc, CORE_ADDR *argv) { - CORE_ADDR entry; - struct minimal_symbol *sym; + if (argc != 2) + error ("ALPHA frame specifications require two arguments: sp and pc"); - entry = entry_point_address (); + return create_new_frame (argv[0], argv[1]); +} - if (entry != 0) - return entry; +/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that + dummy frame. The frame ID's base needs to match the TOS value + saved by save_dummy_frame_tos(), and the PC match the dummy frame's + breakpoint. */ - sym = lookup_minimal_symbol ("_Prelude", NULL, symfile_objfile); +static struct frame_id +alpha_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST base; + frame_unwind_unsigned_register (next_frame, ALPHA_SP_REGNUM, &base); + return frame_id_build (base, frame_pc_unwind (next_frame)); +} - if (!sym || MSYMBOL_TYPE (sym) != mst_text) - return 0; - else - return SYMBOL_VALUE_ADDRESS (sym) + 4; +static CORE_ADDR +alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST pc; + frame_unwind_unsigned_register (next_frame, ALPHA_PC_REGNUM, &pc); + return pc; +} + + +/* Helper routines for alpha*-nat.c files to move register sets to and + from core files. The UNIQUE pointer is allowed to be NULL, as most + targets don't supply this value in their core files. */ + +void +alpha_supply_int_regs (int regno, const void *r0_r30, + const void *pc, const void *unique) +{ + int i; + + for (i = 0; i < 31; ++i) + if (regno == i || regno == -1) + supply_register (i, (const char *)r0_r30 + i*8); + + if (regno == ALPHA_ZERO_REGNUM || regno == -1) + supply_register (ALPHA_ZERO_REGNUM, NULL); + + if (regno == ALPHA_PC_REGNUM || regno == -1) + supply_register (ALPHA_PC_REGNUM, pc); + + if (regno == ALPHA_UNIQUE_REGNUM || regno == -1) + supply_register (ALPHA_UNIQUE_REGNUM, unique); } void -alpha_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) +alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique) { - CORE_ADDR bp_address = CALL_DUMMY_ADDRESS (); + int i; - if (bp_address == 0) - error ("no place to put call"); - write_register (RA_REGNUM, bp_address); - write_register (T12_REGNUM, fun); -} + for (i = 0; i < 31; ++i) + if (regno == i || regno == -1) + regcache_collect (i, (char *)r0_r30 + i*8); -/* On the Alpha, the call dummy code is nevery copied to user space - (see alpha_fix_call_dummy() above). The contents of this do not - matter. */ -LONGEST alpha_call_dummy_words[] = { 0 }; + if (regno == ALPHA_PC_REGNUM || regno == -1) + regcache_collect (ALPHA_PC_REGNUM, pc); -int -alpha_use_struct_convention (int gcc_p, struct type *type) -{ - /* Structures are returned by ref in extra arg0. */ - return 1; + if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1)) + regcache_collect (ALPHA_UNIQUE_REGNUM, unique); } void -alpha_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) +alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr) { - /* Store the address of the place in which to copy the structure the - subroutine will return. Handled by alpha_push_arguments. */ + int i; + + for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) + if (regno == i || regno == -1) + supply_register (i, (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + + if (regno == ALPHA_FPCR_REGNUM || regno == -1) + supply_register (ALPHA_FPCR_REGNUM, fpcr); } -CORE_ADDR -alpha_extract_struct_value_address (char *regbuf) +void +alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr) { - return (extract_address (regbuf + REGISTER_BYTE (V0_REGNUM), - REGISTER_RAW_SIZE (V0_REGNUM))); + int i; + + for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) + if (regno == i || regno == -1) + regcache_collect (i, (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + + if (regno == ALPHA_FPCR_REGNUM || regno == -1) + regcache_collect (ALPHA_FPCR_REGNUM, fpcr); } + /* alpha_software_single_step() is called just before we want to resume the inferior, if we want to single-step it but there is no hardware or kernel single-step support (NetBSD on Alpha, for example). We find @@ -1571,7 +1366,7 @@ alpha_next_pc (CORE_ADDR pc) int offset; LONGEST rav; - insn = read_memory_unsigned_integer (pc, sizeof (insn)); + insn = alpha_read_insn (pc); /* Opcode is top 6 bits. */ op = (insn >> 26) & 0x3f; @@ -1634,6 +1429,8 @@ alpha_next_pc (CORE_ADDR pc) if (rav >= 0) goto branch_taken; break; + + /* ??? Missing floating-point branches. */ } } @@ -1664,12 +1461,139 @@ alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) } } + +/* Initialize the current architecture based on INFO. If possible, re-use an + architecture from ARCHES, which is a list of architectures already created + during this debugging session. + + Called e.g. at program startup, when reading a core file, and when reading + a binary file. */ + +static struct gdbarch * +alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + struct gdbarch_tdep *tdep; + struct gdbarch *gdbarch; + + /* Try to determine the ABI of the object we are loading. */ + if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN) + { + /* If it's an ECOFF file, assume it's OSF/1. */ + if (bfd_get_flavour (info.abfd) == bfd_target_ecoff_flavour) + info.osabi = GDB_OSABI_OSF1; + } + + /* Find a candidate among extant architectures. */ + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != NULL) + return arches->gdbarch; + + tdep = xmalloc (sizeof (struct gdbarch_tdep)); + gdbarch = gdbarch_alloc (&info, tdep); + + /* Lowest text address. This is used by heuristic_proc_start() + to decide when to stop looking. */ + tdep->vm_min_address = (CORE_ADDR) 0x120000000; + + tdep->dynamic_sigtramp_offset = NULL; + tdep->sigcontext_addr = NULL; + tdep->sc_pc_offset = 2 * 8; + tdep->sc_regs_offset = 4 * 8; + tdep->sc_fpregs_offset = tdep->sc_regs_offset + 32 * 8 + 8; + + tdep->jb_pc = -1; /* longjmp support not enabled by default */ + + /* Type sizes */ + set_gdbarch_short_bit (gdbarch, 16); + set_gdbarch_int_bit (gdbarch, 32); + set_gdbarch_long_bit (gdbarch, 64); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_float_bit (gdbarch, 32); + set_gdbarch_double_bit (gdbarch, 64); + set_gdbarch_long_double_bit (gdbarch, 64); + set_gdbarch_ptr_bit (gdbarch, 64); + + /* Register info */ + set_gdbarch_num_regs (gdbarch, ALPHA_NUM_REGS); + set_gdbarch_sp_regnum (gdbarch, ALPHA_SP_REGNUM); + set_gdbarch_pc_regnum (gdbarch, ALPHA_PC_REGNUM); + set_gdbarch_fp0_regnum (gdbarch, ALPHA_FP0_REGNUM); + + set_gdbarch_register_name (gdbarch, alpha_register_name); + set_gdbarch_deprecated_register_byte (gdbarch, alpha_register_byte); + set_gdbarch_deprecated_register_raw_size (gdbarch, alpha_register_raw_size); + set_gdbarch_deprecated_register_virtual_size (gdbarch, alpha_register_virtual_size); + set_gdbarch_register_type (gdbarch, alpha_register_type); + + set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register); + set_gdbarch_cannot_store_register (gdbarch, alpha_cannot_store_register); + + set_gdbarch_convert_register_p (gdbarch, alpha_convert_register_p); + set_gdbarch_register_to_value (gdbarch, alpha_register_to_value); + set_gdbarch_value_to_register (gdbarch, alpha_value_to_register); + + set_gdbarch_register_reggroup_p (gdbarch, alpha_register_reggroup_p); + + /* Prologue heuristics. */ + set_gdbarch_skip_prologue (gdbarch, alpha_skip_prologue); + + /* Disassembler. */ + set_gdbarch_print_insn (gdbarch, print_insn_alpha); + + /* Call info. */ + + set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention); + set_gdbarch_extract_return_value (gdbarch, alpha_extract_return_value); + set_gdbarch_store_return_value (gdbarch, alpha_store_return_value); + set_gdbarch_deprecated_extract_struct_value_address (gdbarch, alpha_extract_struct_value_address); + + /* Settings for calling functions in the inferior. */ + set_gdbarch_push_dummy_call (gdbarch, alpha_push_dummy_call); + + /* Methods for saving / extracting a dummy frame's ID. */ + set_gdbarch_unwind_dummy_id (gdbarch, alpha_unwind_dummy_id); + + /* Return the unwound PC value. */ + set_gdbarch_unwind_pc (gdbarch, alpha_unwind_pc); + + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + + set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc); + set_gdbarch_decr_pc_after_break (gdbarch, 4); + + /* Hook in ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); + + /* Now that we have tuned the configuration, set a few final things + based on what the OS ABI has told us. */ + + if (tdep->jb_pc >= 0) + set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target); + + frame_unwind_append_sniffer (gdbarch, alpha_sigtramp_frame_sniffer); + frame_unwind_append_sniffer (gdbarch, alpha_heuristic_frame_sniffer); + + frame_base_set_default (gdbarch, &alpha_heuristic_frame_base); + + return gdbarch; +} + +void +alpha_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); + frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer); +} + +extern initialize_file_ftype _initialize_alpha_tdep; /* -Wmissing-prototypes */ + void _initialize_alpha_tdep (void) { struct cmd_list_element *c; - tm_print_insn = print_insn_alpha; + gdbarch_register (bfd_arch_alpha, alpha_gdbarch_init, NULL); /* Let the user set the fence post for heuristic_proc_start. */ diff --git a/contrib/gdb/gdb/alpha-tdep.h b/contrib/gdb/gdb/alpha-tdep.h new file mode 100644 index 00000000000..828a3c6b2f7 --- /dev/null +++ b/contrib/gdb/gdb/alpha-tdep.h @@ -0,0 +1,110 @@ +/* Common target dependent code for GDB on Alpha systems. + Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003 Free + Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef ALPHA_TDEP_H +#define ALPHA_TDEP_H + +/* Say how long (ordinary) registers are. This is a piece of bogosity + used in push_word and a few other places; + DEPRECATED_REGISTER_RAW_SIZE is the real way to know how big a + register is. */ +#define ALPHA_REGISTER_SIZE 8 + +/* Number of machine registers. */ +#define ALPHA_NUM_REGS 67 + +/* Total amount of space needed to store our copies of the machine's + register state. */ +#define ALPHA_REGISTER_BYTES (ALPHA_NUM_REGS * 8) + +/* Register numbers of various important registers. Note that most of + these values are "real" register numbers, and correspond to the + general registers of the machine. */ + +#define ALPHA_V0_REGNUM 0 /* Function integer return value */ +#define ALPHA_T7_REGNUM 8 /* Return address register for OSF/1 __add* */ +#define ALPHA_GCC_FP_REGNUM 15 /* Used by gcc as frame register */ +#define ALPHA_A0_REGNUM 16 /* Loc of first arg during a subr call */ +#define ALPHA_T9_REGNUM 23 /* Return address register for OSF/1 __div* */ +#define ALPHA_RA_REGNUM 26 /* Contains return address value */ +#define ALPHA_T12_REGNUM 27 /* Contains start addr of current proc */ +#define ALPHA_GP_REGNUM 29 /* Contains the global pointer */ +#define ALPHA_SP_REGNUM 30 /* Contains address of top of stack */ +#define ALPHA_ZERO_REGNUM 31 /* Read-only register, always 0 */ +#define ALPHA_FP0_REGNUM 32 /* Floating point register 0 */ +#define ALPHA_FPA0_REGNUM 48 /* First float arg during a subr call */ +#define ALPHA_FPCR_REGNUM 63 /* Floating point control register */ +#define ALPHA_PC_REGNUM 64 /* Contains program counter */ +#define ALPHA_UNIQUE_REGNUM 66 /* PAL_rduniq value */ + +/* The alpha has two different virtual pointers for arguments and locals. + + The virtual argument pointer is pointing to the bottom of the argument + transfer area, which is located immediately below the virtual frame + pointer. Its size is fixed for the native compiler, it is either zero + (for the no arguments case) or large enough to hold all argument registers. + gcc uses a variable sized argument transfer area. As it has + to stay compatible with the native debugging tools it has to use the same + virtual argument pointer and adjust the argument offsets accordingly. + + The virtual local pointer is localoff bytes below the virtual frame + pointer, the value of localoff is obtained from the PDR. */ +#define ALPHA_NUM_ARG_REGS 6 + +/* Target-dependent structure in gdbarch. */ +struct gdbarch_tdep +{ + CORE_ADDR vm_min_address; /* Used by alpha_heuristic_proc_start. */ + + /* If PC is inside a dynamically-generated signal trampoline function + (i.e. one copied onto the user stack at run-time), return how many + bytes PC is beyond the start of that function. Otherwise, return -1. */ + LONGEST (*dynamic_sigtramp_offset) (CORE_ADDR); + + /* Translate a signal handler stack base address into the address of + the sigcontext structure for that signal handler. */ + CORE_ADDR (*sigcontext_addr) (struct frame_info *); + + /* Offset of registers in `struct sigcontext'. */ + int sc_pc_offset; + int sc_regs_offset; + int sc_fpregs_offset; + + int jb_pc; /* Offset to PC value in jump buffer. + If htis is negative, longjmp support + will be disabled. */ + size_t jb_elt_size; /* And the size of each entry in the buf. */ +}; + +extern unsigned int alpha_read_insn (CORE_ADDR pc); +extern void alpha_software_single_step (enum target_signal, int); +extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc); + +extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); +extern void alpha_dwarf2_init_abi (struct gdbarch_info, struct gdbarch *); + +extern void alpha_supply_int_regs (int, const void *, const void *, + const void *); +extern void alpha_fill_int_regs (int, void *, void *, void *); +extern void alpha_supply_fp_regs (int, const void *, const void *); +extern void alpha_fill_fp_regs (int, void *, void *); + +#endif /* ALPHA_TDEP_H */ diff --git a/contrib/gdb/gdb/alphabsd-nat.c b/contrib/gdb/gdb/alphabsd-nat.c index d7ad3a73f37..0781698710f 100644 --- a/contrib/gdb/gdb/alphabsd-nat.c +++ b/contrib/gdb/gdb/alphabsd-nat.c @@ -22,6 +22,9 @@ #include "inferior.h" #include "regcache.h" +#include "alpha-tdep.h" +#include "alphabsd-tdep.h" + #include #include #include @@ -34,103 +37,45 @@ typedef struct reg gregset_t; #endif -#ifndef HAVE_FPREGSET_T -typedef struct fpreg fpregset_t; -#endif +#ifndef HAVE_FPREGSET_T +typedef struct fpreg fpregset_t; +#endif #include "gregset.h" -/* Number of general-purpose registers. */ -#define NUM_GREGS 32 - -/* Number of floating point registers. */ -#define NUM_FPREGS 31 - - -/* Transfering the registers between GDB, inferiors and core files. */ - -/* Fill GDB's register array with the general-purpose register values - in *GREGSETP. */ +/* Provide *regset() wrappers around the generic Alpha BSD register + supply/fill routines. */ void supply_gregset (gregset_t *gregsetp) { - int i; - - for (i = 0; i < NUM_GREGS; i++) - { - if (CANNOT_FETCH_REGISTER (i)) - supply_register (i, NULL); - else - supply_register (i, (char *) &gregsetp->r_regs[i]); - } - - /* The PC travels in the R_ZERO slot. */ - supply_register (PC_REGNUM, (char *) &gregsetp->r_regs[R_ZERO]); + alphabsd_supply_reg ((char *) gregsetp, -1); } -/* Fill register REGNO (if it is a general-purpose register) in - *GREGSETPS with the value in GDB's register array. If REGNO is -1, - do this for all registers. */ - void fill_gregset (gregset_t *gregsetp, int regno) { - int i; - - for (i = 0; i < NUM_GREGS; i++) - if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i)) - regcache_collect (i, (char *) &gregsetp->r_regs[i]); - - /* The PC travels in the R_ZERO slot. */ - if (regno == -1 || regno == PC_REGNUM) - regcache_collect (PC_REGNUM, (char *) &gregsetp->r_regs[R_ZERO]); + alphabsd_fill_reg ((char *) gregsetp, regno); } -/* Fill GDB's register array with the floating-point register values - in *FPREGSETP. */ - void supply_fpregset (fpregset_t *fpregsetp) { - int i; - - for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++) - { - if (CANNOT_FETCH_REGISTER (i)) - supply_register (i, NULL); - else - supply_register (i, (char *) &fpregsetp->fpr_regs[i - FP0_REGNUM]); - } - - supply_register (FPCR_REGNUM, (char *) &fpregsetp->fpr_cr); + alphabsd_supply_fpreg ((char *) fpregsetp, -1); } -/* Fill register REGNO (if it is a floating-point register) in - *FPREGSETP with the value in GDB's register array. If REGNO is -1, - do this for all registers. */ - void fill_fpregset (fpregset_t *fpregsetp, int regno) { - int i; - - for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++) - if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i)) - regcache_collect (i, (char *) &fpregsetp->fpr_regs[i - FP0_REGNUM]); - - if (regno == -1 || regno == FPCR_REGNUM) - regcache_collect (FPCR_REGNUM, (char *) &fpregsetp->fpr_cr); + alphabsd_fill_fpreg ((char *) fpregsetp, regno); } - - + /* Determine if PT_GETREGS fetches this register. */ static int getregs_supplies (int regno) { - - return ((regno >= V0_REGNUM && regno <= ZERO_REGNUM) + return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM) || regno >= PC_REGNUM); } @@ -141,33 +86,29 @@ getregs_supplies (int regno) void fetch_inferior_registers (int regno) { - if (regno == -1 || getregs_supplies (regno)) { - gregset_t gregs; + struct reg gregs; if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &gregs, 0) == -1) perror_with_name ("Couldn't get registers"); - supply_gregset (&gregs); + alphabsd_supply_reg ((char *) &gregs, regno); if (regno != -1) return; } if (regno == -1 || regno >= FP0_REGNUM) { - fpregset_t fpregs; + struct fpreg fpregs; if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) perror_with_name ("Couldn't get floating point status"); - supply_fpregset (&fpregs); + alphabsd_supply_fpreg ((char *) &fpregs, regno); } - - /* Reset virtual frame pointer. */ - supply_register (FP_REGNUM, NULL); } /* Store register REGNO back into the inferior. If REGNO is -1, do @@ -176,15 +117,14 @@ fetch_inferior_registers (int regno) void store_inferior_registers (int regno) { - if (regno == -1 || getregs_supplies (regno)) { - gregset_t gregs; + struct reg gregs; if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &gregs, 0) == -1) perror_with_name ("Couldn't get registers"); - fill_gregset (&gregs, regno); + alphabsd_fill_reg ((char *) &gregs, regno); if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &gregs, 0) == -1) @@ -196,13 +136,13 @@ store_inferior_registers (int regno) if (regno == -1 || regno >= FP0_REGNUM) { - fpregset_t fpregs; + struct fpreg fpregs; if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) perror_with_name ("Couldn't get floating point status"); - fill_fpregset (&fpregs, regno); + alphabsd_fill_fpreg ((char *) &fpregs, regno); if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) diff --git a/contrib/gdb/gdb/alphabsd-tdep.c b/contrib/gdb/gdb/alphabsd-tdep.c new file mode 100644 index 00000000000..3e0f2272787 --- /dev/null +++ b/contrib/gdb/gdb/alphabsd-tdep.c @@ -0,0 +1,55 @@ +/* Common target dependent code for GDB on Alpha systems running BSD. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "alpha-tdep.h" +#include "alphabsd-tdep.h" + +/* Conviently, GDB uses the same register numbering as the + ptrace register structure used by BSD on Alpha. */ + +void +alphabsd_supply_reg (char *regs, int regno) +{ + /* PC is at slot 32; UNIQUE not present. */ + alpha_supply_int_regs (regno, regs, regs + 31*8, NULL); +} + +void +alphabsd_fill_reg (char *regs, int regno) +{ + /* PC is at slot 32; UNIQUE not present. */ + alpha_fill_int_regs (regno, regs, regs + 31*8, NULL); +} + +void +alphabsd_supply_fpreg (char *fpregs, int regno) +{ + /* FPCR is at slot 33; slot 32 unused. */ + alpha_supply_fp_regs (regno, fpregs, fpregs + 32*8); +} + +void +alphabsd_fill_fpreg (char *fpregs, int regno) +{ + /* FPCR is at slot 33; slot 32 unused. */ + alpha_fill_fp_regs (regno, fpregs, fpregs + 32*8); +} diff --git a/contrib/gdb/gdb/alphabsd-tdep.h b/contrib/gdb/gdb/alphabsd-tdep.h new file mode 100644 index 00000000000..48d87988ff6 --- /dev/null +++ b/contrib/gdb/gdb/alphabsd-tdep.h @@ -0,0 +1,33 @@ +/* Common target dependent code for GDB on Alpha systems running BSD. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef ALPHABSD_TDEP_H +#define ALPHABSD_TDEP_H + +void alphabsd_supply_reg (char *, int); +void alphabsd_fill_reg (char *, int); + +void alphabsd_supply_fpreg (char *, int); +void alphabsd_fill_fpreg (char *, int); + +#define SIZEOF_STRUCT_REG (32 * 8) +#define SIZEOF_STRUCT_FPREG (33 * 8) + +#endif /* ALPHABSD_TDEP_H */ diff --git a/contrib/gdb/gdb/alphafbsd-tdep.c b/contrib/gdb/gdb/alphafbsd-tdep.c index e2d47491067..cc5f0e00e55 100644 --- a/contrib/gdb/gdb/alphafbsd-tdep.c +++ b/contrib/gdb/gdb/alphafbsd-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for FreeBSD/Alpha. - Copyright 2001 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -20,8 +20,11 @@ #include "defs.h" #include "value.h" +#include "osabi.h" -int +#include "alpha-tdep.h" + +static int alphafbsd_use_struct_convention (int gcc_p, struct type *type) { enum type_code code; @@ -29,7 +32,7 @@ alphafbsd_use_struct_convention (int gcc_p, struct type *type) /* All aggregate types that won't fit in a register must be returned in memory. */ - if (TYPE_LENGTH (type) > REGISTER_SIZE) + if (TYPE_LENGTH (type) > ALPHA_REGISTER_SIZE) return 1; /* The only aggregate types that can be returned in a register are @@ -51,3 +54,71 @@ alphafbsd_use_struct_convention (int gcc_p, struct type *type) return 0; } + + +/* Support for signal handlers. */ + +/* Return whether PC is in a BSD sigtramp routine. */ + +CORE_ADDR alphafbsd_sigtramp_start = 0x11ffff68; +CORE_ADDR alphafbsd_sigtramp_end = 0x11ffffe0; + +static int +alphafbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) +{ + return (pc >= alphafbsd_sigtramp_start && pc < alphafbsd_sigtramp_end); +} + +static LONGEST +alphafbsd_sigtramp_offset (CORE_ADDR pc) +{ + return pc - alphafbsd_sigtramp_start; +} + +/* Assuming NEXT_FRAME is for a frame following a BSD sigtramp + routine, return the address of the associated sigcontext structure. */ + +static CORE_ADDR +alphafbsd_sigcontext_addr (struct frame_info *next_frame) +{ + return frame_unwind_register_unsigned (next_frame, ALPHA_SP_REGNUM) + 24; +} + +/* FreeBSD 5.0-RELEASE or later. */ + +static void +alphafbsd_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Hook into the DWARF CFI frame unwinder. */ + alpha_dwarf2_init_abi (info, gdbarch); + + /* Hook into the MDEBUG frame unwinder. */ + alpha_mdebug_init_abi (info, gdbarch); + + set_gdbarch_use_struct_convention (gdbarch, alphafbsd_use_struct_convention); + + set_gdbarch_pc_in_sigtramp (gdbarch, alphafbsd_pc_in_sigtramp); + + tdep->dynamic_sigtramp_offset = alphafbsd_sigtramp_offset; + tdep->sigcontext_addr = alphafbsd_sigcontext_addr; + tdep->sc_pc_offset = 288; + tdep->sc_regs_offset = 24; + tdep->sc_fpregs_offset = 320; + + tdep->jb_pc = 2; + tdep->jb_elt_size = 8; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_alphafbsd_tdep (void); + +void +_initialize_alphafbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_FREEBSD_ELF, + alphafbsd_init_abi); +} diff --git a/contrib/gdb/gdb/alphanbsd-tdep.c b/contrib/gdb/gdb/alphanbsd-tdep.c new file mode 100644 index 00000000000..28d1bb506b7 --- /dev/null +++ b/contrib/gdb/gdb/alphanbsd-tdep.c @@ -0,0 +1,234 @@ +/* Target-dependent code for NetBSD/Alpha. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "frame.h" +#include "regcache.h" +#include "value.h" +#include "osabi.h" + +#include "solib-svr4.h" + +#include "alpha-tdep.h" +#include "alphabsd-tdep.h" +#include "nbsd-tdep.h" + +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR ignore) +{ + char *regs, *fpregs; + int regno; + + /* Table to map a gdb register number to a trapframe register index. */ + static const int regmap[] = + { + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 30, 31, 32, 16, + 17, 18, 19, 20, + 21, 22, 23, 24, + 25, 29, 26 + }; +#define SIZEOF_TRAPFRAME (33 * 8) + + /* We get everything from one section. */ + if (which != 0) + return; + + regs = core_reg_sect; + fpregs = core_reg_sect + SIZEOF_TRAPFRAME; + + if (core_reg_size < (SIZEOF_TRAPFRAME + SIZEOF_STRUCT_FPREG)) + { + warning ("Wrong size register set in core file."); + return; + } + + /* Integer registers. */ + for (regno = 0; regno < ALPHA_ZERO_REGNUM; regno++) + supply_register (regno, regs + (regmap[regno] * 8)); + supply_register (ALPHA_ZERO_REGNUM, NULL); + supply_register (PC_REGNUM, regs + (28 * 8)); + + /* Floating point registers. */ + alphabsd_supply_fpreg (fpregs, -1); +} + +static void +fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR ignore) +{ + switch (which) + { + case 0: /* Integer registers. */ + if (core_reg_size != SIZEOF_STRUCT_REG) + warning ("Wrong size register set in core file."); + else + alphabsd_supply_reg (core_reg_sect, -1); + break; + + case 2: /* Floating point registers. */ + if (core_reg_size != SIZEOF_STRUCT_FPREG) + warning ("Wrong size FP register set in core file."); + else + alphabsd_supply_fpreg (core_reg_sect, -1); + break; + + default: + /* Don't know what kind of register request this is; just ignore it. */ + break; + } +} + +static struct core_fns alphanbsd_core_fns = +{ + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +static struct core_fns alphanbsd_elfcore_fns = +{ + bfd_target_elf_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_elfcore_registers, /* core_read_registers */ + NULL /* next */ +}; + +/* Under NetBSD/alpha, signal handler invocations can be identified by the + designated code sequence that is used to return from a signal handler. + In particular, the return address of a signal handler points to the + following code sequence: + + ldq a0, 0(sp) + lda sp, 16(sp) + lda v0, 295(zero) # __sigreturn14 + call_pal callsys + + Each instruction has a unique encoding, so we simply attempt to match + the instruction the PC is pointing to with any of the above instructions. + If there is a hit, we know the offset to the start of the designated + sequence and can then check whether we really are executing in the + signal trampoline. If not, -1 is returned, otherwise the offset from the + start of the return sequence is returned. */ +static const unsigned char sigtramp_retcode[] = +{ + 0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */ + 0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */ + 0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */ + 0x83, 0x00, 0x00, 0x00, /* call_pal callsys */ +}; +#define RETCODE_NWORDS 4 +#define RETCODE_SIZE (RETCODE_NWORDS * 4) + +LONGEST +alphanbsd_sigtramp_offset (CORE_ADDR pc) +{ + unsigned char ret[RETCODE_SIZE], w[4]; + LONGEST off; + int i; + + if (read_memory_nobpt (pc, (char *) w, 4) != 0) + return -1; + + for (i = 0; i < RETCODE_NWORDS; i++) + { + if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0) + break; + } + if (i == RETCODE_NWORDS) + return (-1); + + off = i * 4; + pc -= off; + + if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0) + return -1; + + if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0) + return off; + + return -1; +} + +static int +alphanbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) +{ + return (nbsd_pc_in_sigtramp (pc, func_name) + || alphanbsd_sigtramp_offset (pc) >= 0); +} + +static CORE_ADDR +alphanbsd_sigcontext_addr (struct frame_info *frame) +{ + /* FIXME: This is not correct for all versions of NetBSD/alpha. + We will probably need to disassemble the trampoline to figure + out which trampoline frame type we have. */ + return get_frame_base (frame); +} + +static void +alphanbsd_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Hook into the DWARF CFI frame unwinder. */ + alpha_dwarf2_init_abi (info, gdbarch); + + /* Hook into the MDEBUG frame unwinder. */ + alpha_mdebug_init_abi (info, gdbarch); + + set_gdbarch_pc_in_sigtramp (gdbarch, alphanbsd_pc_in_sigtramp); + + /* NetBSD/alpha does not provide single step support via ptrace(2); we + must use software single-stepping. */ + set_gdbarch_software_single_step (gdbarch, alpha_software_single_step); + + set_solib_svr4_fetch_link_map_offsets (gdbarch, + nbsd_lp64_solib_svr4_fetch_link_map_offsets); + + tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset; + tdep->sigcontext_addr = alphanbsd_sigcontext_addr; + + tdep->jb_pc = 2; + tdep->jb_elt_size = 8; +} + +void +_initialize_alphanbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_NETBSD_ELF, + alphanbsd_init_abi); + gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD_ELF, + alphanbsd_init_abi); + + add_core_fns (&alphanbsd_core_fns); + add_core_fns (&alphanbsd_elfcore_fns); +} diff --git a/contrib/gdb/gdb/amd64-nat.c b/contrib/gdb/gdb/amd64-nat.c new file mode 100644 index 00000000000..31b360377be --- /dev/null +++ b/contrib/gdb/gdb/amd64-nat.c @@ -0,0 +1,163 @@ +/* Native-dependent code for AMD64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbarch.h" +#include "regcache.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "i386-tdep.h" +#include "amd64-tdep.h" + +/* The following bits of code help with implementing debugging 32-bit + code natively on AMD64. The idea is to define two mappings between + the register number as used by GDB and the register set used by the + host to represent the general-purpose registers; one for 32-bit + code and one for 64-bit code. The mappings are specified by the + follwing variables and consist of an array of offsets within the + register set indexed by register number, and the number of + registers supported by the mapping. We don't need mappings for the + floating-point and SSE registers, since the difference between + 64-bit and 32-bit variants are negligable. The difference in the + number of SSE registers is already handled by the target code. */ + +/* General-purpose register mapping for native 32-bit code. */ +int *amd64_native_gregset32_reg_offset; +int amd64_native_gregset32_num_regs = I386_NUM_GREGS; + +/* General-purpose register mapping for native 64-bit code. */ +int *amd64_native_gregset64_reg_offset; +int amd64_native_gregset64_num_regs = AMD64_NUM_GREGS; + +/* Return the offset of REGNUM within the appropriate native + general-purpose register set. */ + +static int +amd64_native_gregset_reg_offset (int regnum) +{ + int *reg_offset = amd64_native_gregset64_reg_offset; + int num_regs = amd64_native_gregset64_num_regs; + + gdb_assert (regnum >= 0); + + if (gdbarch_ptr_bit (current_gdbarch) == 32) + { + reg_offset = amd64_native_gregset32_reg_offset; + num_regs = amd64_native_gregset32_num_regs; + } + + if (num_regs > NUM_REGS) + num_regs = NUM_REGS; + + if (regnum < num_regs && regnum < NUM_REGS) + return reg_offset[regnum]; + + return -1; +} + +/* Return whether the native general-purpose register set supplies + register REGNUM. */ + +int +amd64_native_gregset_supplies_p (int regnum) +{ + return (amd64_native_gregset_reg_offset (regnum) != -1); +} + + +/* Supply register REGNUM, whose contents are store in BUF, to + REGCACHE. If REGNUM is -1, supply all appropriate registers. */ + +void +amd64_supply_native_gregset (struct regcache *regcache, + const void *gregs, int regnum) +{ + const char *regs = gregs; + struct gdbarch *gdbarch = get_regcache_arch (regcache); + int num_regs = amd64_native_gregset64_num_regs; + int i; + + if (gdbarch_ptr_bit (gdbarch) == 32) + num_regs = amd64_native_gregset32_num_regs; + + if (num_regs > NUM_REGS) + num_regs = NUM_REGS; + + for (i = 0; i < num_regs; i++) + { + if (regnum == -1 || regnum == i) + { + int offset = amd64_native_gregset_reg_offset (i); + + if (offset != -1) + regcache_raw_supply (regcache, i, regs + offset); + } + } +} + +/* Collect register REGNUM from REGCACHE and store its contents in + GREGS. If REGNUM is -1, collect and store all appropriate + registers. */ + +void +amd64_collect_native_gregset (const struct regcache *regcache, + void *gregs, int regnum) +{ + char *regs = gregs; + struct gdbarch *gdbarch = get_regcache_arch (regcache); + int num_regs = amd64_native_gregset64_num_regs; + int i; + + if (gdbarch_ptr_bit (gdbarch) == 32) + { + num_regs = amd64_native_gregset32_num_regs; + + /* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and + %eip get zero-extended to 64 bits. */ + for (i = 0; i <= I386_EIP_REGNUM; i++) + { + if (regnum == -1 || regnum == i) + memset (regs + amd64_native_gregset_reg_offset (i), 0, 8); + } + /* Ditto for %cs, %ss, %ds, %es, %fs, and %gs. */ + for (i = I386_CS_REGNUM; i <= I386_GS_REGNUM; i++) + { + if (regnum == -1 || regnum == i) + memset (regs + amd64_native_gregset_reg_offset (i), 0, 8); + } + } + + if (num_regs > NUM_REGS) + num_regs = NUM_REGS; + + for (i = 0; i < num_regs; i++) + { + if (regnum == -1 || regnum == i) + { + int offset = amd64_native_gregset_reg_offset (i); + + if (offset != -1) + regcache_raw_collect (regcache, i, regs + offset); + } + } +} diff --git a/contrib/gdb/gdb/amd64-nat.h b/contrib/gdb/gdb/amd64-nat.h new file mode 100644 index 00000000000..edf6df8de87 --- /dev/null +++ b/contrib/gdb/gdb/amd64-nat.h @@ -0,0 +1,53 @@ +/* Native-dependent code for AMD64. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef AMD64_NAT_H +#define AMD64_NAT_H 1 + +struct regcache; + +/* General-purpose register set description for native 32-bit code. */ +extern int *amd64_native_gregset32_reg_offset; +extern int amd64_native_gregset32_num_regs; + +/* General-purpose register set description for native 64-bit code. */ +extern int *amd64_native_gregset64_reg_offset; +extern int amd64_native_gregset64_num_regs; + +/* Return whether the native general-purpose register set supplies + register REGNUM. */ + +extern int amd64_native_gregset_supplies_p (int regnum); + +/* Supply register REGNUM, whose contents are store in BUF, to + REGCACHE. If REGNUM is -1, supply all appropriate registers. */ + +extern void amd64_supply_native_gregset (struct regcache *regcache, + const void *gregs, int regnum); + +/* Collect register REGNUM from REGCACHE and store its contents in + GREGS. If REGNUM is -1, collect and store all appropriate + registers. */ + +extern void amd64_collect_native_gregset (const struct regcache *regcache, + void *gregs, int regnum); + +#endif /* amd64-nat.h */ diff --git a/contrib/gdb/gdb/amd64-tdep.c b/contrib/gdb/gdb/amd64-tdep.c new file mode 100644 index 00000000000..e0b2ca046f5 --- /dev/null +++ b/contrib/gdb/gdb/amd64-tdep.c @@ -0,0 +1,1199 @@ +/* Target-dependent code for AMD64. + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Jiri Smid, SuSE Labs. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "block.h" +#include "dummy-frame.h" +#include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" +#include "inferior.h" +#include "gdbcmd.h" +#include "gdbcore.h" +#include "objfiles.h" +#include "regcache.h" +#include "regset.h" +#include "symfile.h" + +#include "gdb_assert.h" + +#include "amd64-tdep.h" +#include "i387-tdep.h" + +/* Note that the AMD64 architecture was previously known as x86-64. + The latter is (forever) engraved into the canonical system name as + returned by config.guess, and used as the name for the AMD64 port + of GNU/Linux. The BSD's have renamed their ports to amd64; they + don't like to shout. For GDB we prefer the amd64_-prefix over the + x86_64_-prefix since it's so much easier to type. */ + +/* Register information. */ + +struct amd64_register_info +{ + char *name; + struct type **type; +}; + +static struct amd64_register_info amd64_register_info[] = +{ + { "rax", &builtin_type_int64 }, + { "rbx", &builtin_type_int64 }, + { "rcx", &builtin_type_int64 }, + { "rdx", &builtin_type_int64 }, + { "rsi", &builtin_type_int64 }, + { "rdi", &builtin_type_int64 }, + { "rbp", &builtin_type_void_data_ptr }, + { "rsp", &builtin_type_void_data_ptr }, + + /* %r8 is indeed register number 8. */ + { "r8", &builtin_type_int64 }, + { "r9", &builtin_type_int64 }, + { "r10", &builtin_type_int64 }, + { "r11", &builtin_type_int64 }, + { "r12", &builtin_type_int64 }, + { "r13", &builtin_type_int64 }, + { "r14", &builtin_type_int64 }, + { "r15", &builtin_type_int64 }, + { "rip", &builtin_type_void_func_ptr }, + { "eflags", &builtin_type_int32 }, + { "cs", &builtin_type_int32 }, + { "ss", &builtin_type_int32 }, + { "ds", &builtin_type_int32 }, + { "es", &builtin_type_int32 }, + { "fs", &builtin_type_int32 }, + { "gs", &builtin_type_int32 }, + + /* %st0 is register number 24. */ + { "st0", &builtin_type_i387_ext }, + { "st1", &builtin_type_i387_ext }, + { "st2", &builtin_type_i387_ext }, + { "st3", &builtin_type_i387_ext }, + { "st4", &builtin_type_i387_ext }, + { "st5", &builtin_type_i387_ext }, + { "st6", &builtin_type_i387_ext }, + { "st7", &builtin_type_i387_ext }, + { "fctrl", &builtin_type_int32 }, + { "fstat", &builtin_type_int32 }, + { "ftag", &builtin_type_int32 }, + { "fiseg", &builtin_type_int32 }, + { "fioff", &builtin_type_int32 }, + { "foseg", &builtin_type_int32 }, + { "fooff", &builtin_type_int32 }, + { "fop", &builtin_type_int32 }, + + /* %xmm0 is register number 40. */ + { "xmm0", &builtin_type_v4sf }, + { "xmm1", &builtin_type_v4sf }, + { "xmm2", &builtin_type_v4sf }, + { "xmm3", &builtin_type_v4sf }, + { "xmm4", &builtin_type_v4sf }, + { "xmm5", &builtin_type_v4sf }, + { "xmm6", &builtin_type_v4sf }, + { "xmm7", &builtin_type_v4sf }, + { "xmm8", &builtin_type_v4sf }, + { "xmm9", &builtin_type_v4sf }, + { "xmm10", &builtin_type_v4sf }, + { "xmm11", &builtin_type_v4sf }, + { "xmm12", &builtin_type_v4sf }, + { "xmm13", &builtin_type_v4sf }, + { "xmm14", &builtin_type_v4sf }, + { "xmm15", &builtin_type_v4sf }, + { "mxcsr", &builtin_type_int32 } +}; + +/* Total number of registers. */ +#define AMD64_NUM_REGS \ + (sizeof (amd64_register_info) / sizeof (amd64_register_info[0])) + +/* Return the name of register REGNUM. */ + +static const char * +amd64_register_name (int regnum) +{ + if (regnum >= 0 && regnum < AMD64_NUM_REGS) + return amd64_register_info[regnum].name; + + return NULL; +} + +/* Return the GDB type object for the "standard" data type of data in + register REGNUM. */ + +static struct type * +amd64_register_type (struct gdbarch *gdbarch, int regnum) +{ + gdb_assert (regnum >= 0 && regnum < AMD64_NUM_REGS); + + return *amd64_register_info[regnum].type; +} + +/* DWARF Register Number Mapping as defined in the System V psABI, + section 3.6. */ + +static int amd64_dwarf_regmap[] = +{ + /* General Purpose Registers RAX, RDX, RCX, RBX, RSI, RDI. */ + AMD64_RAX_REGNUM, AMD64_RDX_REGNUM, + AMD64_RCX_REGNUM, AMD64_RBX_REGNUM, + AMD64_RSI_REGNUM, AMD64_RDI_REGNUM, + + /* Frame Pointer Register RBP. */ + AMD64_RBP_REGNUM, + + /* Stack Pointer Register RSP. */ + AMD64_RSP_REGNUM, + + /* Extended Integer Registers 8 - 15. */ + 8, 9, 10, 11, 12, 13, 14, 15, + + /* Return Address RA. Mapped to RIP. */ + AMD64_RIP_REGNUM, + + /* SSE Registers 0 - 7. */ + AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM, + AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3, + AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5, + AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7, + + /* Extended SSE Registers 8 - 15. */ + AMD64_XMM0_REGNUM + 8, AMD64_XMM0_REGNUM + 9, + AMD64_XMM0_REGNUM + 10, AMD64_XMM0_REGNUM + 11, + AMD64_XMM0_REGNUM + 12, AMD64_XMM0_REGNUM + 13, + AMD64_XMM0_REGNUM + 14, AMD64_XMM0_REGNUM + 15, + + /* Floating Point Registers 0-7. */ + AMD64_ST0_REGNUM + 0, AMD64_ST0_REGNUM + 1, + AMD64_ST0_REGNUM + 2, AMD64_ST0_REGNUM + 3, + AMD64_ST0_REGNUM + 4, AMD64_ST0_REGNUM + 5, + AMD64_ST0_REGNUM + 6, AMD64_ST0_REGNUM + 7 +}; + +static const int amd64_dwarf_regmap_len = + (sizeof (amd64_dwarf_regmap) / sizeof (amd64_dwarf_regmap[0])); + +/* Convert DWARF register number REG to the appropriate register + number used by GDB. */ + +static int +amd64_dwarf_reg_to_regnum (int reg) +{ + int regnum = -1; + + if (reg >= 0 || reg < amd64_dwarf_regmap_len) + regnum = amd64_dwarf_regmap[reg]; + + if (regnum == -1) + warning ("Unmapped DWARF Register #%d encountered\n", reg); + + return regnum; +} + +/* Return nonzero if a value of type TYPE stored in register REGNUM + needs any special handling. */ + +static int +amd64_convert_register_p (int regnum, struct type *type) +{ + return i386_fp_regnum_p (regnum); +} + + +/* Register classes as defined in the psABI. */ + +enum amd64_reg_class +{ + AMD64_INTEGER, + AMD64_SSE, + AMD64_SSEUP, + AMD64_X87, + AMD64_X87UP, + AMD64_COMPLEX_X87, + AMD64_NO_CLASS, + AMD64_MEMORY +}; + +/* Return the union class of CLASS1 and CLASS2. See the psABI for + details. */ + +static enum amd64_reg_class +amd64_merge_classes (enum amd64_reg_class class1, enum amd64_reg_class class2) +{ + /* Rule (a): If both classes are equal, this is the resulting class. */ + if (class1 == class2) + return class1; + + /* Rule (b): If one of the classes is NO_CLASS, the resulting class + is the other class. */ + if (class1 == AMD64_NO_CLASS) + return class2; + if (class2 == AMD64_NO_CLASS) + return class1; + + /* Rule (c): If one of the classes is MEMORY, the result is MEMORY. */ + if (class1 == AMD64_MEMORY || class2 == AMD64_MEMORY) + return AMD64_MEMORY; + + /* Rule (d): If one of the classes is INTEGER, the result is INTEGER. */ + if (class1 == AMD64_INTEGER || class2 == AMD64_INTEGER) + return AMD64_INTEGER; + + /* Rule (e): If one of the classes is X87, X87UP, COMPLEX_X87 class, + MEMORY is used as class. */ + if (class1 == AMD64_X87 || class1 == AMD64_X87UP + || class1 == AMD64_COMPLEX_X87 || class2 == AMD64_X87 + || class2 == AMD64_X87UP || class2 == AMD64_COMPLEX_X87) + return AMD64_MEMORY; + + /* Rule (f): Otherwise class SSE is used. */ + return AMD64_SSE; +} + +static void amd64_classify (struct type *type, enum amd64_reg_class class[2]); + +/* Return non-zero if TYPE is a non-POD structure or union type. */ + +static int +amd64_non_pod_p (struct type *type) +{ + /* ??? A class with a base class certainly isn't POD, but does this + catch all non-POD structure types? */ + if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_N_BASECLASSES (type) > 0) + return 1; + + return 0; +} + +/* Classify TYPE according to the rules for aggregate (structures and + arrays) and union types, and store the result in CLASS. */ + +static void +amd64_classify_aggregate (struct type *type, enum amd64_reg_class class[2]) +{ + int len = TYPE_LENGTH (type); + + /* 1. If the size of an object is larger than two eightbytes, or in + C++, is a non-POD structure or union type, or contains + unaligned fields, it has class memory. */ + if (len > 16 || amd64_non_pod_p (type)) + { + class[0] = class[1] = AMD64_MEMORY; + return; + } + + /* 2. Both eightbytes get initialized to class NO_CLASS. */ + class[0] = class[1] = AMD64_NO_CLASS; + + /* 3. Each field of an object is classified recursively so that + always two fields are considered. The resulting class is + calculated according to the classes of the fields in the + eightbyte: */ + + if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + struct type *subtype = check_typedef (TYPE_TARGET_TYPE (type)); + + /* All fields in an array have the same type. */ + amd64_classify (subtype, class); + if (len > 8 && class[1] == AMD64_NO_CLASS) + class[1] = class[0]; + } + else + { + int i; + + /* Structure or union. */ + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION); + + for (i = 0; i < TYPE_NFIELDS (type); i++) + { + struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i)); + int pos = TYPE_FIELD_BITPOS (type, i) / 64; + enum amd64_reg_class subclass[2]; + + /* Ignore static fields. */ + if (TYPE_FIELD_STATIC (type, i)) + continue; + + gdb_assert (pos == 0 || pos == 1); + + amd64_classify (subtype, subclass); + class[pos] = amd64_merge_classes (class[pos], subclass[0]); + if (pos == 0) + class[1] = amd64_merge_classes (class[1], subclass[1]); + } + } + + /* 4. Then a post merger cleanup is done: */ + + /* Rule (a): If one of the classes is MEMORY, the whole argument is + passed in memory. */ + if (class[0] == AMD64_MEMORY || class[1] == AMD64_MEMORY) + class[0] = class[1] = AMD64_MEMORY; + + /* Rule (b): If SSEUP is not preceeded by SSE, it is converted to + SSE. */ + if (class[0] == AMD64_SSEUP) + class[0] = AMD64_SSE; + if (class[1] == AMD64_SSEUP && class[0] != AMD64_SSE) + class[1] = AMD64_SSE; +} + +/* Classify TYPE, and store the result in CLASS. */ + +static void +amd64_classify (struct type *type, enum amd64_reg_class class[2]) +{ + enum type_code code = TYPE_CODE (type); + int len = TYPE_LENGTH (type); + + class[0] = class[1] = AMD64_NO_CLASS; + + /* Arguments of types (signed and unsigned) _Bool, char, short, int, + long, long long, and pointers are in the INTEGER class. */ + if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM + || code == TYPE_CODE_PTR || code == TYPE_CODE_REF) + && (len == 1 || len == 2 || len == 4 || len == 8)) + class[0] = AMD64_INTEGER; + + /* Arguments of types float, double and __m64 are in class SSE. */ + else if (code == TYPE_CODE_FLT && (len == 4 || len == 8)) + /* FIXME: __m64 . */ + class[0] = AMD64_SSE; + + /* Arguments of types __float128 and __m128 are split into two + halves. The least significant ones belong to class SSE, the most + significant one to class SSEUP. */ + /* FIXME: __float128, __m128. */ + + /* The 64-bit mantissa of arguments of type long double belongs to + class X87, the 16-bit exponent plus 6 bytes of padding belongs to + class X87UP. */ + else if (code == TYPE_CODE_FLT && len == 16) + /* Class X87 and X87UP. */ + class[0] = AMD64_X87, class[1] = AMD64_X87UP; + + /* Aggregates. */ + else if (code == TYPE_CODE_ARRAY || code == TYPE_CODE_STRUCT + || code == TYPE_CODE_UNION) + amd64_classify_aggregate (type, class); +} + +static enum return_value_convention +amd64_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, + void *readbuf, const void *writebuf) +{ + enum amd64_reg_class class[2]; + int len = TYPE_LENGTH (type); + static int integer_regnum[] = { AMD64_RAX_REGNUM, AMD64_RDX_REGNUM }; + static int sse_regnum[] = { AMD64_XMM0_REGNUM, AMD64_XMM1_REGNUM }; + int integer_reg = 0; + int sse_reg = 0; + int i; + + gdb_assert (!(readbuf && writebuf)); + + /* 1. Classify the return type with the classification algorithm. */ + amd64_classify (type, class); + + /* 2. If the type has class MEMORY, then the caller provides space + for the return value and passes the address of this storage in + %rdi as if it were the first argument to the function. In + effect, this address becomes a hidden first argument. */ + if (class[0] == AMD64_MEMORY) + return RETURN_VALUE_STRUCT_CONVENTION; + + gdb_assert (class[1] != AMD64_MEMORY); + gdb_assert (len <= 16); + + for (i = 0; len > 0; i++, len -= 8) + { + int regnum = -1; + int offset = 0; + + switch (class[i]) + { + case AMD64_INTEGER: + /* 3. If the class is INTEGER, the next available register + of the sequence %rax, %rdx is used. */ + regnum = integer_regnum[integer_reg++]; + break; + + case AMD64_SSE: + /* 4. If the class is SSE, the next available SSE register + of the sequence %xmm0, %xmm1 is used. */ + regnum = sse_regnum[sse_reg++]; + break; + + case AMD64_SSEUP: + /* 5. If the class is SSEUP, the eightbyte is passed in the + upper half of the last used SSE register. */ + gdb_assert (sse_reg > 0); + regnum = sse_regnum[sse_reg - 1]; + offset = 8; + break; + + case AMD64_X87: + /* 6. If the class is X87, the value is returned on the X87 + stack in %st0 as 80-bit x87 number. */ + regnum = AMD64_ST0_REGNUM; + if (writebuf) + i387_return_value (gdbarch, regcache); + break; + + case AMD64_X87UP: + /* 7. If the class is X87UP, the value is returned together + with the previous X87 value in %st0. */ + gdb_assert (i > 0 && class[0] == AMD64_X87); + regnum = AMD64_ST0_REGNUM; + offset = 8; + len = 2; + break; + + case AMD64_NO_CLASS: + continue; + + default: + gdb_assert (!"Unexpected register class."); + } + + gdb_assert (regnum != -1); + + if (readbuf) + regcache_raw_read_part (regcache, regnum, offset, min (len, 8), + (char *) readbuf + i * 8); + if (writebuf) + regcache_raw_write_part (regcache, regnum, offset, min (len, 8), + (const char *) writebuf + i * 8); + } + + return RETURN_VALUE_REGISTER_CONVENTION; +} + + +static CORE_ADDR +amd64_push_arguments (struct regcache *regcache, int nargs, + struct value **args, CORE_ADDR sp, int struct_return) +{ + static int integer_regnum[] = + { + AMD64_RDI_REGNUM, /* %rdi */ + AMD64_RSI_REGNUM, /* %rsi */ + AMD64_RDX_REGNUM, /* %rdx */ + AMD64_RCX_REGNUM, /* %rcx */ + 8, /* %r8 */ + 9 /* %r9 */ + }; + static int sse_regnum[] = + { + /* %xmm0 ... %xmm7 */ + AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM, + AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3, + AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5, + AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7, + }; + struct value **stack_args = alloca (nargs * sizeof (struct value *)); + int num_stack_args = 0; + int num_elements = 0; + int element = 0; + int integer_reg = 0; + int sse_reg = 0; + int i; + + /* Reserve a register for the "hidden" argument. */ + if (struct_return) + integer_reg++; + + for (i = 0; i < nargs; i++) + { + struct type *type = VALUE_TYPE (args[i]); + int len = TYPE_LENGTH (type); + enum amd64_reg_class class[2]; + int needed_integer_regs = 0; + int needed_sse_regs = 0; + int j; + + /* Classify argument. */ + amd64_classify (type, class); + + /* Calculate the number of integer and SSE registers needed for + this argument. */ + for (j = 0; j < 2; j++) + { + if (class[j] == AMD64_INTEGER) + needed_integer_regs++; + else if (class[j] == AMD64_SSE) + needed_sse_regs++; + } + + /* Check whether enough registers are available, and if the + argument should be passed in registers at all. */ + if (integer_reg + needed_integer_regs > ARRAY_SIZE (integer_regnum) + || sse_reg + needed_sse_regs > ARRAY_SIZE (sse_regnum) + || (needed_integer_regs == 0 && needed_sse_regs == 0)) + { + /* The argument will be passed on the stack. */ + num_elements += ((len + 7) / 8); + stack_args[num_stack_args++] = args[i]; + } + else + { + /* The argument will be passed in registers. */ + char *valbuf = VALUE_CONTENTS (args[i]); + char buf[8]; + + gdb_assert (len <= 16); + + for (j = 0; len > 0; j++, len -= 8) + { + int regnum = -1; + int offset = 0; + + switch (class[j]) + { + case AMD64_INTEGER: + regnum = integer_regnum[integer_reg++]; + break; + + case AMD64_SSE: + regnum = sse_regnum[sse_reg++]; + break; + + case AMD64_SSEUP: + gdb_assert (sse_reg > 0); + regnum = sse_regnum[sse_reg - 1]; + offset = 8; + break; + + default: + gdb_assert (!"Unexpected register class."); + } + + gdb_assert (regnum != -1); + memset (buf, 0, sizeof buf); + memcpy (buf, valbuf + j * 8, min (len, 8)); + regcache_raw_write_part (regcache, regnum, offset, 8, buf); + } + } + } + + /* Allocate space for the arguments on the stack. */ + sp -= num_elements * 8; + + /* The psABI says that "The end of the input argument area shall be + aligned on a 16 byte boundary." */ + sp &= ~0xf; + + /* Write out the arguments to the stack. */ + for (i = 0; i < num_stack_args; i++) + { + struct type *type = VALUE_TYPE (stack_args[i]); + char *valbuf = VALUE_CONTENTS (stack_args[i]); + int len = TYPE_LENGTH (type); + + write_memory (sp + element * 8, valbuf, len); + element += ((len + 7) / 8); + } + + /* The psABI says that "For calls that may call functions that use + varargs or stdargs (prototype-less calls or calls to functions + containing ellipsis (...) in the declaration) %al is used as + hidden argument to specify the number of SSE registers used. */ + regcache_raw_write_unsigned (regcache, AMD64_RAX_REGNUM, sse_reg); + return sp; +} + +static CORE_ADDR +amd64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + char buf[8]; + + /* Pass arguments. */ + sp = amd64_push_arguments (regcache, nargs, args, sp, struct_return); + + /* Pass "hidden" argument". */ + if (struct_return) + { + store_unsigned_integer (buf, 8, struct_addr); + regcache_cooked_write (regcache, AMD64_RDI_REGNUM, buf); + } + + /* Store return address. */ + sp -= 8; + store_unsigned_integer (buf, 8, bp_addr); + write_memory (sp, buf, 8); + + /* Finally, update the stack pointer... */ + store_unsigned_integer (buf, 8, sp); + regcache_cooked_write (regcache, AMD64_RSP_REGNUM, buf); + + /* ...and fake a frame pointer. */ + regcache_cooked_write (regcache, AMD64_RBP_REGNUM, buf); + + return sp + 16; +} + + +/* The maximum number of saved registers. This should include %rip. */ +#define AMD64_NUM_SAVED_REGS AMD64_NUM_GREGS + +struct amd64_frame_cache +{ + /* Base address. */ + CORE_ADDR base; + CORE_ADDR sp_offset; + CORE_ADDR pc; + + /* Saved registers. */ + CORE_ADDR saved_regs[AMD64_NUM_SAVED_REGS]; + CORE_ADDR saved_sp; + + /* Do we have a frame? */ + int frameless_p; +}; + +/* Allocate and initialize a frame cache. */ + +static struct amd64_frame_cache * +amd64_alloc_frame_cache (void) +{ + struct amd64_frame_cache *cache; + int i; + + cache = FRAME_OBSTACK_ZALLOC (struct amd64_frame_cache); + + /* Base address. */ + cache->base = 0; + cache->sp_offset = -8; + cache->pc = 0; + + /* Saved registers. We initialize these to -1 since zero is a valid + offset (that's where %rbp is supposed to be stored). */ + for (i = 0; i < AMD64_NUM_SAVED_REGS; i++) + cache->saved_regs[i] = -1; + cache->saved_sp = 0; + + /* Frameless until proven otherwise. */ + cache->frameless_p = 1; + + return cache; +} + +/* Do a limited analysis of the prologue at PC and update CACHE + accordingly. Bail out early if CURRENT_PC is reached. Return the + address where the analysis stopped. + + We will handle only functions beginning with: + + pushq %rbp 0x55 + movq %rsp, %rbp 0x48 0x89 0xe5 + + Any function that doesn't start with this sequence will be assumed + to have no prologue and thus no valid frame pointer in %rbp. */ + +static CORE_ADDR +amd64_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, + struct amd64_frame_cache *cache) +{ + static unsigned char proto[3] = { 0x48, 0x89, 0xe5 }; + unsigned char buf[3]; + unsigned char op; + + if (current_pc <= pc) + return current_pc; + + op = read_memory_unsigned_integer (pc, 1); + + if (op == 0x55) /* pushq %rbp */ + { + /* Take into account that we've executed the `pushq %rbp' that + starts this instruction sequence. */ + cache->saved_regs[AMD64_RBP_REGNUM] = 0; + cache->sp_offset += 8; + + /* If that's all, return now. */ + if (current_pc <= pc + 1) + return current_pc; + + /* Check for `movq %rsp, %rbp'. */ + read_memory (pc + 1, buf, 3); + if (memcmp (buf, proto, 3) != 0) + return pc + 1; + + /* OK, we actually have a frame. */ + cache->frameless_p = 0; + return pc + 4; + } + + return pc; +} + +/* Return PC of first real instruction. */ + +static CORE_ADDR +amd64_skip_prologue (CORE_ADDR start_pc) +{ + struct amd64_frame_cache cache; + CORE_ADDR pc; + + pc = amd64_analyze_prologue (start_pc, 0xffffffffffffffff, &cache); + if (cache.frameless_p) + return start_pc; + + return pc; +} + + +/* Normal frames. */ + +static struct amd64_frame_cache * +amd64_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct amd64_frame_cache *cache; + char buf[8]; + int i; + + if (*this_cache) + return *this_cache; + + cache = amd64_alloc_frame_cache (); + *this_cache = cache; + + cache->pc = frame_func_unwind (next_frame); + if (cache->pc != 0) + amd64_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache); + + if (cache->frameless_p) + { + /* We didn't find a valid frame. If we're at the start of a + function, or somewhere half-way its prologue, the function's + frame probably hasn't been fully setup yet. Try to + reconstruct the base address for the stack frame by looking + at the stack pointer. For truly "frameless" functions this + might work too. */ + + frame_unwind_register (next_frame, AMD64_RSP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 8) + cache->sp_offset; + } + else + { + frame_unwind_register (next_frame, AMD64_RBP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 8); + } + + /* Now that we have the base address for the stack frame we can + calculate the value of %rsp in the calling frame. */ + cache->saved_sp = cache->base + 16; + + /* For normal frames, %rip is stored at 8(%rbp). If we don't have a + frame we find it at the same offset from the reconstructed base + address. */ + cache->saved_regs[AMD64_RIP_REGNUM] = 8; + + /* Adjust all the saved registers such that they contain addresses + instead of offsets. */ + for (i = 0; i < AMD64_NUM_SAVED_REGS; i++) + if (cache->saved_regs[i] != -1) + cache->saved_regs[i] += cache->base; + + return cache; +} + +static void +amd64_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct amd64_frame_cache *cache = + amd64_frame_cache (next_frame, this_cache); + + /* This marks the outermost frame. */ + if (cache->base == 0) + return; + + (*this_id) = frame_id_build (cache->base + 16, cache->pc); +} + +static void +amd64_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct amd64_frame_cache *cache = + amd64_frame_cache (next_frame, this_cache); + + gdb_assert (regnum >= 0); + + if (regnum == SP_REGNUM && cache->saved_sp) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + /* Store the value. */ + store_unsigned_integer (valuep, 8, cache->saved_sp); + } + return; + } + + if (regnum < AMD64_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = cache->saved_regs[regnum]; + *realnump = -1; + if (valuep) + { + /* Read the value in from memory. */ + read_memory (*addrp, valuep, + register_size (current_gdbarch, regnum)); + } + return; + } + + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind amd64_frame_unwind = +{ + NORMAL_FRAME, + amd64_frame_this_id, + amd64_frame_prev_register +}; + +static const struct frame_unwind * +amd64_frame_sniffer (struct frame_info *next_frame) +{ + return &amd64_frame_unwind; +} + + +/* Signal trampolines. */ + +/* FIXME: kettenis/20030419: Perhaps, we can unify the 32-bit and + 64-bit variants. This would require using identical frame caches + on both platforms. */ + +static struct amd64_frame_cache * +amd64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct amd64_frame_cache *cache; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + CORE_ADDR addr; + char buf[8]; + int i; + + if (*this_cache) + return *this_cache; + + cache = amd64_alloc_frame_cache (); + + frame_unwind_register (next_frame, AMD64_RSP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 8) - 8; + + addr = tdep->sigcontext_addr (next_frame); + gdb_assert (tdep->sc_reg_offset); + gdb_assert (tdep->sc_num_regs <= AMD64_NUM_SAVED_REGS); + for (i = 0; i < tdep->sc_num_regs; i++) + if (tdep->sc_reg_offset[i] != -1) + cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; + + *this_cache = cache; + return cache; +} + +static void +amd64_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_cache, struct frame_id *this_id) +{ + struct amd64_frame_cache *cache = + amd64_sigtramp_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base + 16, frame_pc_unwind (next_frame)); +} + +static void +amd64_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + /* Make sure we've initialized the cache. */ + amd64_sigtramp_frame_cache (next_frame, this_cache); + + amd64_frame_prev_register (next_frame, this_cache, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind amd64_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + amd64_sigtramp_frame_this_id, + amd64_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +amd64_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (PC_IN_SIGTRAMP (pc, name)) + { + gdb_assert (gdbarch_tdep (current_gdbarch)->sigcontext_addr); + + return &amd64_sigtramp_frame_unwind; + } + + return NULL; +} + + +static CORE_ADDR +amd64_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct amd64_frame_cache *cache = + amd64_frame_cache (next_frame, this_cache); + + return cache->base; +} + +static const struct frame_base amd64_frame_base = +{ + &amd64_frame_unwind, + amd64_frame_base_address, + amd64_frame_base_address, + amd64_frame_base_address +}; + +static struct frame_id +amd64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + char buf[8]; + CORE_ADDR fp; + + frame_unwind_register (next_frame, AMD64_RBP_REGNUM, buf); + fp = extract_unsigned_integer (buf, 8); + + return frame_id_build (fp + 16, frame_pc_unwind (next_frame)); +} + +/* 16 byte align the SP per frame requirements. */ + +static CORE_ADDR +amd64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) +{ + return sp & -(CORE_ADDR)16; +} + + +/* Supply register REGNUM from the floating-point register set REGSET + to register cache REGCACHE. If REGNUM is -1, do this for all + registers in REGSET. */ + +static void +amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *fpregs, size_t len) +{ + const struct gdbarch_tdep *tdep = regset->descr; + + gdb_assert (len == tdep->sizeof_fpregset); + amd64_supply_fxsave (regcache, regnum, fpregs); +} + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ + +static const struct regset * +amd64_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset) + { + if (tdep->fpregset == NULL) + { + tdep->fpregset = XMALLOC (struct regset); + tdep->fpregset->descr = tdep; + tdep->fpregset->supply_regset = amd64_supply_fpregset; + } + + return tdep->fpregset; + } + + return i386_regset_from_core_section (gdbarch, sect_name, sect_size); +} + + +void +amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* AMD64 generally uses `fxsave' instead of `fsave' for saving its + floating-point registers. */ + tdep->sizeof_fpregset = I387_SIZEOF_FXSAVE; + + /* AMD64 has an FPU and 16 SSE registers. */ + tdep->st0_regnum = AMD64_ST0_REGNUM; + tdep->num_xmm_regs = 16; + + /* This is what all the fuss is about. */ + set_gdbarch_long_bit (gdbarch, 64); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_ptr_bit (gdbarch, 64); + + /* In contrast to the i386, on AMD64 a `long double' actually takes + up 128 bits, even though it's still based on the i387 extended + floating-point format which has only 80 significant bits. */ + set_gdbarch_long_double_bit (gdbarch, 128); + + set_gdbarch_num_regs (gdbarch, AMD64_NUM_REGS); + set_gdbarch_register_name (gdbarch, amd64_register_name); + set_gdbarch_register_type (gdbarch, amd64_register_type); + + /* Register numbers of various important registers. */ + set_gdbarch_sp_regnum (gdbarch, AMD64_RSP_REGNUM); /* %rsp */ + set_gdbarch_pc_regnum (gdbarch, AMD64_RIP_REGNUM); /* %rip */ + set_gdbarch_ps_regnum (gdbarch, AMD64_EFLAGS_REGNUM); /* %eflags */ + set_gdbarch_fp0_regnum (gdbarch, AMD64_ST0_REGNUM); /* %st(0) */ + + /* The "default" register numbering scheme for AMD64 is referred to + as the "DWARF Register Number Mapping" in the System V psABI. + The preferred debugging format for all known AMD64 targets is + actually DWARF2, and GCC doesn't seem to support DWARF (that is + DWARF-1), but we provide the same mapping just in case. This + mapping is also used for stabs, which GCC does support. */ + set_gdbarch_stab_reg_to_regnum (gdbarch, amd64_dwarf_reg_to_regnum); + set_gdbarch_dwarf_reg_to_regnum (gdbarch, amd64_dwarf_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, amd64_dwarf_reg_to_regnum); + + /* We don't override SDB_REG_RO_REGNUM, since COFF doesn't seem to + be in use on any of the supported AMD64 targets. */ + + /* Call dummy code. */ + set_gdbarch_push_dummy_call (gdbarch, amd64_push_dummy_call); + set_gdbarch_frame_align (gdbarch, amd64_frame_align); + set_gdbarch_frame_red_zone_size (gdbarch, 128); + + set_gdbarch_convert_register_p (gdbarch, amd64_convert_register_p); + set_gdbarch_register_to_value (gdbarch, i387_register_to_value); + set_gdbarch_value_to_register (gdbarch, i387_value_to_register); + + set_gdbarch_return_value (gdbarch, amd64_return_value); + + set_gdbarch_skip_prologue (gdbarch, amd64_skip_prologue); + + /* Avoid wiring in the MMX registers for now. */ + set_gdbarch_num_pseudo_regs (gdbarch, 0); + tdep->mm0_regnum = -1; + + set_gdbarch_unwind_dummy_id (gdbarch, amd64_unwind_dummy_id); + + /* FIXME: kettenis/20021026: This is ELF-specific. Fine for now, + since all supported AMD64 targets are ELF, but that might change + in the future. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); + + frame_unwind_append_sniffer (gdbarch, amd64_sigtramp_frame_sniffer); + frame_unwind_append_sniffer (gdbarch, amd64_frame_sniffer); + frame_base_set_default (gdbarch, &amd64_frame_base); + + /* If we have a register mapping, enable the generic core file support. */ + if (tdep->gregset_reg_offset) + set_gdbarch_regset_from_core_section (gdbarch, + amd64_regset_from_core_section); +} + + +#define I387_ST0_REGNUM AMD64_ST0_REGNUM + +/* The 64-bit FXSAVE format differs from the 32-bit format in the + sense that the instruction pointer and data pointer are simply + 64-bit offsets into the code segment and the data segment instead + of a selector offset pair. The functions below store the upper 32 + bits of these pointers (instead of just the 16-bits of the segment + selector). */ + +/* Fill register REGNUM in REGCACHE with the appropriate + floating-point or SSE register value from *FXSAVE. If REGNUM is + -1, do this for all registers. This function masks off any of the + reserved bits in *FXSAVE. */ + +void +amd64_supply_fxsave (struct regcache *regcache, int regnum, + const void *fxsave) +{ + i387_supply_fxsave (regcache, regnum, fxsave); + + if (fxsave) + { + const char *regs = fxsave; + + if (regnum == -1 || regnum == I387_FISEG_REGNUM) + regcache_raw_supply (regcache, I387_FISEG_REGNUM, regs + 12); + if (regnum == -1 || regnum == I387_FOSEG_REGNUM) + regcache_raw_supply (regcache, I387_FOSEG_REGNUM, regs + 20); + } +} + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for + all registers. This function doesn't touch any of the reserved + bits in *FXSAVE. */ + +void +amd64_collect_fxsave (const struct regcache *regcache, int regnum, + void *fxsave) +{ + char *regs = fxsave; + + i387_collect_fxsave (regcache, regnum, fxsave); + + if (regnum == -1 || regnum == I387_FISEG_REGNUM) + regcache_raw_collect (regcache, I387_FISEG_REGNUM, regs + 12); + if (regnum == -1 || regnum == I387_FOSEG_REGNUM) + regcache_raw_collect (regcache, I387_FOSEG_REGNUM, regs + 20); +} + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value in GDB's register cache. If REGNUM is -1, do + this for all registers. This function doesn't touch any of the + reserved bits in *FXSAVE. */ + +void +amd64_fill_fxsave (char *fxsave, int regnum) +{ + amd64_collect_fxsave (current_regcache, regnum, fxsave); +} diff --git a/contrib/gdb/gdb/amd64-tdep.h b/contrib/gdb/gdb/amd64-tdep.h new file mode 100644 index 00000000000..042618b3e09 --- /dev/null +++ b/contrib/gdb/gdb/amd64-tdep.h @@ -0,0 +1,93 @@ +/* Target-dependent definitions for AMD64. + + Copyright 2001, 2003, 2004 Free Software Foundation, Inc. + Contributed by Jiri Smid, SuSE Labs. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef AMD64_TDEP_H +#define AMD64_TDEP_H + +struct gdbarch; +struct frame_info; +struct regcache; + +#include "i386-tdep.h" + +/* Register numbers of various important registers. */ + +enum amd64_regnum +{ + AMD64_RAX_REGNUM, /* %rax */ + AMD64_RBX_REGNUM, /* %rbx */ + AMD64_RCX_REGNUM, /* %rcx */ + AMD64_RDX_REGNUM, /* %rdx */ + AMD64_RSI_REGNUM, /* %rsi */ + AMD64_RDI_REGNUM, /* %rdi */ + AMD64_RBP_REGNUM, /* %rbp */ + AMD64_RSP_REGNUM, /* %rsp */ + AMD64_R8_REGNUM = 8, /* %r8 */ + AMD64_R15_REGNUM = 15, /* %r15 */ + AMD64_RIP_REGNUM, /* %rip */ + AMD64_EFLAGS_REGNUM, /* %eflags */ + AMD64_ST0_REGNUM = 24, /* %st0 */ + AMD64_XMM0_REGNUM = 40, /* %xmm0 */ + AMD64_XMM1_REGNUM /* %xmm1 */ +}; + +/* Number of general purpose registers. */ +#define AMD64_NUM_GREGS 24 + +extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); + +/* Fill register REGNUM in REGCACHE with the appropriate + floating-point or SSE register value from *FXSAVE. If REGNUM is + -1, do this for all registers. This function masks off any of the + reserved bits in *FXSAVE. */ + +extern void amd64_supply_fxsave (struct regcache *regcache, int regnum, + const void *fxsave); + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for + all registers. This function doesn't touch any of the reserved + bits in *FXSAVE. */ + +extern void amd64_collect_fxsave (const struct regcache *regcache, int regnum, + void *fxsave); + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value in GDB's register cache. If REGNUM is -1, do + this for all registers. This function doesn't touch any of the + reserved bits in *FXSAVE. */ + +extern void amd64_fill_fxsave (char *fxsave, int regnum); + + +/* Variables exported from amd64nbsd-tdep.c. */ +extern int amd64nbsd_r_reg_offset[]; + +/* Variables exported from amd64obsd-tdep.c. */ +extern int amd64obsd_r_reg_offset[]; + +/* Variables exported from amd64fbsd-tdep.c. */ +extern CORE_ADDR amd64fbsd_sigtramp_start_addr; +extern CORE_ADDR amd64fbsd_sigtramp_end_addr; +extern int amd64fbsd_sc_reg_offset[]; + +#endif /* amd64-tdep.h */ diff --git a/contrib/gdb/gdb/amd64bsd-nat.c b/contrib/gdb/gdb/amd64bsd-nat.c new file mode 100644 index 00000000000..4c7c04a881d --- /dev/null +++ b/contrib/gdb/gdb/amd64bsd-nat.c @@ -0,0 +1,107 @@ +/* Native-dependent code for AMD64 BSD's. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "regcache.h" + +/* We include to make sure `struct fxsave64' is defined on + NetBSD, since NetBSD's needs it. */ +#include "gdb_assert.h" +#include +#include +#include +#include + +#include "amd64-tdep.h" +#include "amd64-nat.h" + + +/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this + for all registers (including the floating-point registers). */ + +void +fetch_inferior_registers (int regnum) +{ + if (regnum == -1 || amd64_native_gregset_supplies_p (regnum)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + amd64_supply_native_gregset (current_regcache, ®s, -1); + if (regnum != -1) + return; + } + + if (regnum == -1 || regnum >= AMD64_ST0_REGNUM) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + amd64_supply_fxsave (current_regcache, -1, &fpregs); + } +} + +/* Store register REGNUM back into the inferior. If REGNUM is -1, do + this for all registers (including the floating-point registers). */ + +void +store_inferior_registers (int regnum) +{ + if (regnum == -1 || amd64_native_gregset_supplies_p (regnum)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + amd64_collect_native_gregset (current_regcache, ®s, regnum); + + if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't write registers"); + + if (regnum != -1) + return; + } + + if (regnum == -1 || regnum >= AMD64_ST0_REGNUM) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + amd64_fill_fxsave ((char *) &fpregs, regnum); + + if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't write floating point status"); + } +} diff --git a/contrib/gdb/gdb/amd64fbsd-nat.c b/contrib/gdb/gdb/amd64fbsd-nat.c new file mode 100644 index 00000000000..f08373422c2 --- /dev/null +++ b/contrib/gdb/gdb/amd64fbsd-nat.c @@ -0,0 +1,235 @@ +/* Native-dependent code for FreeBSD/amd64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "regcache.h" + +#include "gdb_assert.h" +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_PROCFS_H +#include +#endif + +#ifndef HAVE_GREGSET_T +typedef struct reg gregset_t; +#endif + +#ifndef HAVE_FPREGSET_T +typedef struct fpreg fpregset_t; +#endif + +#include "gregset.h" +#include "amd64-tdep.h" +#include "amd64-nat.h" + + +/* Offset to the gregset_t location where REG is stored. */ +#define REG_OFFSET(reg) offsetof (gregset_t, reg) + +/* At reg_offset[REGNUM] you'll find the offset to the gregset_t + location where the GDB register REGNUM is stored. Unsupported + registers are marked with `-1'. */ +static int reg_offset[] = +{ + REG_OFFSET (r_rax), + REG_OFFSET (r_rbx), + REG_OFFSET (r_rcx), + REG_OFFSET (r_rdx), + REG_OFFSET (r_rsi), + REG_OFFSET (r_rdi), + REG_OFFSET (r_rbp), + REG_OFFSET (r_rsp), + REG_OFFSET (r_r8), + REG_OFFSET (r_r9), + REG_OFFSET (r_r10), + REG_OFFSET (r_r11), + REG_OFFSET (r_r12), + REG_OFFSET (r_r13), + REG_OFFSET (r_r14), + REG_OFFSET (r_r15), + REG_OFFSET (r_rip), + REG_OFFSET (r_rflags), + REG_OFFSET (r_cs), + REG_OFFSET (r_ss), + -1, + -1, + -1, + -1 +}; + + +/* Mapping between the general-purpose registers in FreeBSD/amd64 + `struct reg' format and GDB's register cache layout for + FreeBSD/i386. + + Note that most FreeBSD/amd64 registers are 64-bit, while the + FreeBSD/i386 registers are all 32-bit, but since we're + little-endian we get away with that. */ + +/* From . */ +static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] = +{ + 14 * 8, 13 * 8, /* %eax, %ecx */ + 12 * 8, 11 * 8, /* %edx, %ebx */ + 20 * 8, 10 * 8, /* %esp, %ebp */ + 9 * 8, 8 * 8, /* %esi, %edi */ + 17 * 8, 19 * 8, /* %eip, %eflags */ + 18 * 8, 21 * 8, /* %cs, %ss */ + -1, -1, -1, -1 /* %ds, %es, %fs, %gs */ +}; + + +/* Transfering the registers between GDB, inferiors and core files. */ + +/* Fill GDB's register array with the general-purpose register values + in *GREGSETP. */ + +void +supply_gregset (gregset_t *gregsetp) +{ + amd64_supply_native_gregset (current_regcache, gregsetp, -1); +} + +/* Fill register REGNUM (if it is a general-purpose register) in + *GREGSETPS with the value in GDB's register array. If REGNUM is -1, + do this for all registers. */ + +void +fill_gregset (gregset_t *gregsetp, int regnum) +{ + amd64_collect_native_gregset (current_regcache, gregsetp, regnum); +} + +/* Fill GDB's register array with the floating-point register values + in *FPREGSETP. */ + +void +supply_fpregset (fpregset_t *fpregsetp) +{ + amd64_supply_fxsave (current_regcache, -1, fpregsetp); +} + +/* Fill register REGNUM (if it is a floating-point register) in + *FPREGSETP with the value in GDB's register array. If REGNUM is -1, + do this for all registers. */ + +void +fill_fpregset (fpregset_t *fpregsetp, int regnum) +{ + amd64_fill_fxsave ((char *) fpregsetp, regnum); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64fbsd_nat (void); + +void +_initialize_amd64fbsd_nat (void) +{ + int offset; + + amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset; + amd64_native_gregset64_reg_offset = reg_offset; + + /* To support the recognition of signal handlers, i386bsd-tdep.c + hardcodes some constants. Inclusion of this file means that we + are compiling a native debugger, which means that we can use the + system header files and sysctl(3) to get at the relevant + information. */ + +#define SC_REG_OFFSET amd64fbsd_sc_reg_offset + + /* We only check the program counter, stack pointer and frame + pointer since these members of `struct sigcontext' are essential + for providing backtraces. */ + +#define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM] +#define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM] +#define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM] + + /* Override the default value for the offset of the program counter + in the sigcontext structure. */ + offset = offsetof (struct sigcontext, sc_rip); + + if (SC_RIP_OFFSET != offset) + { + warning ("\ +offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\ +Please report this to .", + offset, SC_RIP_OFFSET); + } + + SC_RIP_OFFSET = offset; + + /* Likewise for the stack pointer. */ + offset = offsetof (struct sigcontext, sc_rsp); + + if (SC_RSP_OFFSET != offset) + { + warning ("\ +offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\ +Please report this to .", + offset, SC_RSP_OFFSET); + } + + SC_RSP_OFFSET = offset; + + /* And the frame pointer. */ + offset = offsetof (struct sigcontext, sc_rbp); + + if (SC_RBP_OFFSET != offset) + { + warning ("\ +offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\ +Please report this to .", + offset, SC_RBP_OFFSET); + } + + SC_RBP_OFFSET = offset; + + /* FreeBSD provides a kern.ps_strings sysctl that we can use to + locate the sigtramp. That way we can still recognize a sigtramp + if its location is changed in a new kernel. Of course this is + still based on the assumption that the sigtramp is placed + directly under the location where the program arguments and + environment can be found. */ + { + int mib[2]; + long ps_strings; + size_t len; + + mib[0] = CTL_KERN; + mib[1] = KERN_PS_STRINGS; + len = sizeof (ps_strings); + if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0) + { + amd64fbsd_sigtramp_start_addr = ps_strings - 32; + amd64fbsd_sigtramp_end_addr = ps_strings; + } + } +} diff --git a/contrib/gdb/gdb/amd64fbsd-tdep.c b/contrib/gdb/gdb/amd64fbsd-tdep.c new file mode 100644 index 00000000000..e4e02abb61c --- /dev/null +++ b/contrib/gdb/gdb/amd64fbsd-tdep.c @@ -0,0 +1,155 @@ +/* Target-dependent code for FreeBSD/amd64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "frame.h" +#include "gdbcore.h" +#include "regcache.h" +#include "osabi.h" + +#include "gdb_string.h" + +#include "amd64-tdep.h" +#include "solib-svr4.h" + +/* Support for signal handlers. */ + +/* Assuming NEXT_FRAME is for a frame following a BSD sigtramp + routine, return the address of the associated sigcontext structure. */ + +static CORE_ADDR +amd64fbsd_sigcontext_addr (struct frame_info *next_frame) +{ + CORE_ADDR sp; + + /* The `struct sigcontext' (which really is an `ucontext_t' on + FreeBSD/amd64) lives at a fixed offset in the signal frame. See + . */ + sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM); + return sp + 16; +} + +/* FreeBSD 5.1-RELEASE or later. */ + +/* Mapping between the general-purpose registers in `struct reg' + format and GDB's register cache layout. + + Note that some registers are 32-bit, but since we're little-endian + we get away with that. */ + +/* From . */ +static int amd64fbsd_r_reg_offset[] = +{ + 14 * 8, /* %rax */ + 11 * 8, /* %rbx */ + 13 * 8, /* %rcx */ + 12 * 8, /* %rdx */ + 9 * 8, /* %rsi */ + 8 * 8, /* %rdi */ + 10 * 8, /* %rbp */ + 20 * 8, /* %rsp */ + 7 * 8, /* %r8 ... */ + 6 * 8, + 5 * 8, + 4 * 8, + 3 * 8, + 2 * 8, + 1 * 8, + 0 * 8, /* ... %r15 */ + 17 * 8, /* %rip */ + 19 * 8, /* %eflags */ + 18 * 8, /* %cs */ + 21 * 8, /* %ss */ + -1, /* %ds */ + -1, /* %es */ + -1, /* %fs */ + -1 /* %gs */ +}; + +/* Location of the signal trampoline. */ +CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0; +CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0; + +/* From . */ +int amd64fbsd_sc_reg_offset[] = +{ + 24 + 6 * 8, /* %rax */ + 24 + 7 * 8, /* %rbx */ + 24 + 3 * 8, /* %rcx */ + 24 + 2 * 8, /* %rdx */ + 24 + 1 * 8, /* %rsi */ + 24 + 0 * 8, /* %rdi */ + 24 + 8 * 8, /* %rbp */ + 24 + 22 * 8, /* %rsp */ + 24 + 4 * 8, /* %r8 ... */ + 24 + 5 * 8, + 24 + 9 * 8, + 24 + 10 * 8, + 24 + 11 * 8, + 24 + 12 * 8, + 24 + 13 * 8, + 24 + 14 * 8, /* ... %r15 */ + 24 + 19 * 8, /* %rip */ + 24 + 21 * 8, /* %eflags */ + 24 + 20 * 8, /* %cs */ + 24 + 23 * 8, /* %ss */ + -1, /* %ds */ + -1, /* %es */ + -1, /* %fs */ + -1 /* %gs */ +}; + +void +amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Obviously FreeBSD is BSD-based. */ + i386bsd_init_abi (info, gdbarch); + + tdep->gregset_reg_offset = amd64fbsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset); + tdep->sizeof_gregset = 22 * 8; + + amd64_init_abi (info, gdbarch); + + tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr; + tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr; + tdep->sigcontext_addr = amd64fbsd_sigcontext_addr; + tdep->sc_reg_offset = amd64fbsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset); + + /* FreeBSD uses SVR4-style shared libraries. */ + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_lp64_fetch_link_map_offsets); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64fbsd_tdep (void); + +void +_initialize_amd64fbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, + GDB_OSABI_FREEBSD_ELF, amd64fbsd_init_abi); +} diff --git a/contrib/gdb/gdb/amd64nbsd-nat.c b/contrib/gdb/gdb/amd64nbsd-nat.c new file mode 100644 index 00000000000..df7ceb9e861 --- /dev/null +++ b/contrib/gdb/gdb/amd64nbsd-nat.c @@ -0,0 +1,68 @@ +/* Native-dependent code for NetBSD/amd64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "gdb_assert.h" + +#include "amd64-tdep.h" +#include "amd64-nat.h" + +/* Mapping between the general-purpose registers in NetBSD/amd64 + `struct reg' format and GDB's register cache layout for + NetBSD/i386. + + Note that most (if not all) NetBSD/amd64 registers are 64-bit, + while the NetBSD/i386 registers are all 32-bit, but since we're + little-endian we get away with that. */ + +/* From . */ +static int amd64nbsd32_r_reg_offset[] = +{ + 14 * 8, /* %eax */ + 3 * 8, /* %ecx */ + 2 * 8, /* %edx */ + 13 * 8, /* %ebx */ + 24 * 8, /* %esp */ + 12 * 8, /* %ebp */ + 1 * 8, /* %esi */ + 0 * 8, /* %edi */ + 21 * 8, /* %eip */ + 23 * 8, /* %eflags */ + 22 * 8, /* %cs */ + 25 * 8, /* %ss */ + 18 * 8, /* %ds */ + 17 * 8, /* %es */ + 16 * 8, /* %fs */ + 15 * 8 /* %gs */ +}; + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64nbsd_nat (void); + +void +_initialize_amd64nbsd_nat (void) +{ + amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset; + amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset); + amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset; +} diff --git a/contrib/gdb/gdb/amd64nbsd-tdep.c b/contrib/gdb/gdb/amd64nbsd-tdep.c new file mode 100644 index 00000000000..a04e04fa34b --- /dev/null +++ b/contrib/gdb/gdb/amd64nbsd-tdep.c @@ -0,0 +1,135 @@ +/* Target-dependent code for NetBSD/amd64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "frame.h" +#include "gdbcore.h" +#include "osabi.h" + +#include "gdb_assert.h" + +#include "amd64-tdep.h" +#include "nbsd-tdep.h" +#include "solib-svr4.h" + +/* Support for signal handlers. */ + +/* Assuming NEXT_FRAME is for a frame following a BSD sigtramp + routine, return the address of the associated sigcontext structure. */ + +static CORE_ADDR +amd64nbsd_sigcontext_addr (struct frame_info *next_frame) +{ + CORE_ADDR sp; + + /* The stack pointer points at `struct sigcontext' upon entry of a + signal trampoline. */ + sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM); + return sp; +} + +/* NetBSD 2.0 or later. */ + +/* Mapping between the general-purpose registers in `struct reg' + format and GDB's register cache layout. */ + +/* From . */ +int amd64nbsd_r_reg_offset[] = +{ + 14 * 8, /* %rax */ + 13 * 8, /* %rbx */ + 3 * 8, /* %rcx */ + 2 * 8, /* %rdx */ + 1 * 8, /* %rsi */ + 0 * 8, /* %rdi */ + 12 * 8, /* %rbp */ + 24 * 8, /* %rsp */ + 4 * 8, /* %r8 .. */ + 5 * 8, + 6 * 8, + 7 * 8, + 8 * 8, + 9 * 8, + 10 * 8, + 11 * 8, /* ... %r15 */ + 21 * 8, /* %rip */ + 23 * 8, /* %eflags */ + 22 * 8, /* %cs */ + 25 * 8, /* %ss */ + 18 * 8, /* %ds */ + 17 * 8, /* %es */ + 16 * 8, /* %fs */ + 15 * 8 /* %gs */ +}; + +static void +amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int *sc_reg_offset; + int i; + + /* Initialize general-purpose register set details first. */ + tdep->gregset_reg_offset = amd64nbsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset); + tdep->sizeof_gregset = 26 * 8; + + amd64_init_abi (info, gdbarch); + + tdep->jb_pc_offset = 7 * 8; + + /* NetBSD has its own convention for signal trampolines. */ + set_gdbarch_pc_in_sigtramp (gdbarch, nbsd_pc_in_sigtramp); + tdep->sigcontext_addr = amd64nbsd_sigcontext_addr; + + /* Initialize the array with register offsets in `struct + sigcontext'. This `struct sigcontext' has an sc_mcontext member + at offset 32, and in we have an explicit comment + saying that `struct reg' is the same as mcontext.__gregs. */ + tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset); + tdep->sc_reg_offset = XCALLOC (tdep->sc_num_regs, int); + for (i = 0; i < tdep->sc_num_regs; i++) + { + if (amd64nbsd_r_reg_offset[i] < 0) + tdep->sc_reg_offset[i] = -1; + else + tdep->sc_reg_offset[i] = 32 + amd64nbsd_r_reg_offset[i]; + } + + /* NetBSD uses SVR4-style shared libraries. */ + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_lp64_fetch_link_map_offsets); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64nbsd_tdep (void); + +void +_initialize_amd64nbsd_ndep (void) +{ + /* The NetBSD/amd64 native dependent code makes this assumption. */ + gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS); + + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, + GDB_OSABI_NETBSD_ELF, amd64nbsd_init_abi); +} diff --git a/contrib/gdb/gdb/amd64obsd-nat.c b/contrib/gdb/gdb/amd64obsd-nat.c new file mode 100644 index 00000000000..e8d92fefa80 --- /dev/null +++ b/contrib/gdb/gdb/amd64obsd-nat.c @@ -0,0 +1,68 @@ +/* Native-dependent code for OpenBSD/amd64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "gdb_assert.h" + +#include "amd64-tdep.h" +#include "amd64-nat.h" + +/* Mapping between the general-purpose registers in OpenBSD/amd64 + `struct reg' format and GDB's register cache layout for + OpenBSD/i386. + + Note that most (if not all) OpenBSD/amd64 registers are 64-bit, + while the OpenBSD/i386 registers are all 32-bit, but since we're + little-endian we get away with that. */ + +/* From . */ +static int amd64obsd32_r_reg_offset[] = +{ + 14 * 8, /* %eax */ + 3 * 8, /* %ecx */ + 2 * 8, /* %edx */ + 13 * 8, /* %ebx */ + 15 * 8, /* %esp */ + 12 * 8, /* %ebp */ + 1 * 8, /* %esi */ + 0 * 8, /* %edi */ + 16 * 8, /* %eip */ + 17 * 8, /* %eflags */ + 18 * 8, /* %cs */ + 19 * 8, /* %ss */ + 20 * 8, /* %ds */ + 21 * 8, /* %es */ + 22 * 8, /* %fs */ + 23 * 8 /* %gs */ +}; + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64obsd_nat (void); + +void +_initialize_amd64obsd_nat (void) +{ + amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset; + amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset); + amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset; +} diff --git a/contrib/gdb/gdb/amd64obsd-tdep.c b/contrib/gdb/gdb/amd64obsd-tdep.c new file mode 100644 index 00000000000..198c87e4a28 --- /dev/null +++ b/contrib/gdb/gdb/amd64obsd-tdep.c @@ -0,0 +1,224 @@ +/* Target-dependent code for OpenBSD/amd64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "gdbcore.h" +#include "osabi.h" +#include "regset.h" +#include "target.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "amd64-tdep.h" +#include "i387-tdep.h" +#include "solib-svr4.h" + +/* Support for core dumps. */ + +static void +amd64obsd_supply_regset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *regs, size_t len) +{ + const struct gdbarch_tdep *tdep = regset->descr; + + gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE); + + i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset); + amd64_supply_fxsave (regcache, regnum, (char *)regs + tdep->sizeof_gregset); +} + +static const struct regset * +amd64obsd_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* OpenBSD core dumps don't use seperate register sets for the + general-purpose and floating-point registers. */ + + if (strcmp (sect_name, ".reg") == 0 + && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE) + { + if (tdep->gregset == NULL) + { + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = tdep; + tdep->gregset->supply_regset = amd64obsd_supply_regset; + } + return tdep->gregset; + } + + return NULL; +} + + +/* Support for signal handlers. */ + +static const int amd64obsd_page_size = 4096; + +static int +amd64obsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1)); + const char sigreturn[] = + { + 0x48, 0xc7, 0xc0, + 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ + 0xcd, 0x80 /* int $0x80 */ + }; + char *buf; + + if (name) + return 0; + + /* If we can't read the instructions at START_PC, return zero. */ + buf = alloca (sizeof sigreturn); + if (target_read_memory (start_pc + 0x7, buf, sizeof sigreturn)) + return 0; + + /* Check for sigreturn(2). */ + if (memcmp (buf, sigreturn, sizeof sigreturn)) + return 0; + + return 1; +} + +/* Assuming NEXT_FRAME is for a frame following a BSD sigtramp + routine, return the address of the associated sigcontext structure. */ + +static CORE_ADDR +amd64obsd_sigcontext_addr (struct frame_info *next_frame) +{ + /* The %rsp register points at `struct sigcontext' upon entry of a + signal trampoline. */ + return frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM); +} + +/* OpenBSD 3.5 or later. */ + +/* Mapping between the general-purpose registers in `struct reg' + format and GDB's register cache layout. */ + +/* From . */ +int amd64obsd_r_reg_offset[] = +{ + 14 * 8, /* %rax */ + 13 * 8, /* %rbx */ + 3 * 8, /* %rcx */ + 2 * 8, /* %rdx */ + 1 * 8, /* %rsi */ + 0 * 8, /* %rdi */ + 12 * 8, /* %rbp */ + 15 * 8, /* %rsp */ + 4 * 8, /* %r8 .. */ + 5 * 8, + 6 * 8, + 7 * 8, + 8 * 8, + 9 * 8, + 10 * 8, + 11 * 8, /* ... %r15 */ + 16 * 8, /* %rip */ + 17 * 8, /* %eflags */ + 18 * 8, /* %cs */ + 19 * 8, /* %ss */ + 20 * 8, /* %ds */ + 21 * 8, /* %es */ + 22 * 8, /* %fs */ + 23 * 8 /* %gs */ +}; + +/* From . */ +static int amd64obsd_sc_reg_offset[] = +{ + 14 * 8, /* %rax */ + 13 * 8, /* %rbx */ + 3 * 8, /* %rcx */ + 2 * 8, /* %rdx */ + 1 * 8, /* %rsi */ + 0 * 8, /* %rdi */ + 12 * 8, /* %rbp */ + 24 * 8, /* %rsp */ + 4 * 8, /* %r8 ... */ + 5 * 8, + 6 * 8, + 7 * 8, + 8 * 8, + 9 * 8, + 10 * 8, + 11 * 8, /* ... %r15 */ + 21 * 8, /* %rip */ + 23 * 8, /* %eflags */ + 22 * 8, /* %cs */ + 25 * 8, /* %ss */ + 18 * 8, /* %ds */ + 17 * 8, /* %es */ + 16 * 8, /* %fs */ + 15 * 8 /* %gs */ +}; + +static void +amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + amd64_init_abi (info, gdbarch); + + /* Initialize general-purpose register set details. */ + tdep->gregset_reg_offset = amd64obsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset); + tdep->sizeof_gregset = 24 * 8; + + set_gdbarch_regset_from_core_section (gdbarch, + amd64obsd_regset_from_core_section); + + tdep->jb_pc_offset = 7 * 8; + + set_gdbarch_pc_in_sigtramp (gdbarch, amd64obsd_pc_in_sigtramp); + tdep->sigcontext_addr = amd64obsd_sigcontext_addr; + tdep->sc_reg_offset = amd64obsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset); + + /* OpenBSD uses SVR4-style shared libraries. */ + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_lp64_fetch_link_map_offsets); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64obsd_tdep (void); + +void +_initialize_amd64obsd_tdep (void) +{ + /* The OpenBSD/amd64 native dependent code makes this assumption. */ + gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == AMD64_NUM_GREGS); + + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, + GDB_OSABI_OPENBSD_ELF, amd64obsd_init_abi); + + /* OpenBSD uses traditional (a.out) NetBSD-style core dumps. */ + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, + GDB_OSABI_NETBSD_AOUT, amd64obsd_init_abi); +} diff --git a/contrib/gdb/gdb/annotate.c b/contrib/gdb/gdb/annotate.c index 66211e91f36..0ba9b42f6cd 100644 --- a/contrib/gdb/gdb/annotate.c +++ b/contrib/gdb/gdb/annotate.c @@ -155,28 +155,28 @@ annotate_signalled (void) void annotate_signal_name (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032signal-name\n"); } void annotate_signal_name_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032signal-name-end\n"); } void annotate_signal_string (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032signal-string\n"); } void annotate_signal_string_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032signal-string-end\n"); } @@ -193,35 +193,35 @@ annotate_signal (void) void annotate_breakpoints_headers (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032breakpoints-headers\n"); } void annotate_field (int num) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032field %d\n", num); } void annotate_breakpoints_table (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032breakpoints-table\n"); } void annotate_record (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032record\n"); } void annotate_breakpoints_table_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032breakpoints-table-end\n"); } @@ -238,7 +238,7 @@ annotate_frames_invalid (void) void annotate_field_begin (struct type *type) { - if (annotation_level > 1) + if (annotation_level == 2) { printf_filtered ("\n\032\032field-begin "); print_value_flags (type); @@ -249,21 +249,21 @@ annotate_field_begin (struct type *type) void annotate_field_name_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032field-name-end\n"); } void annotate_field_value (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032field-value\n"); } void annotate_field_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032field-end\n"); } @@ -291,7 +291,7 @@ annotate_error_begin (void) void annotate_value_history_begin (int histindex, struct type *type) { - if (annotation_level > 1) + if (annotation_level == 2) { printf_filtered ("\n\032\032value-history-begin %d ", histindex); print_value_flags (type); @@ -302,7 +302,7 @@ annotate_value_history_begin (int histindex, struct type *type) void annotate_value_begin (struct type *type) { - if (annotation_level > 1) + if (annotation_level == 2) { printf_filtered ("\n\032\032value-begin "); print_value_flags (type); @@ -313,91 +313,91 @@ annotate_value_begin (struct type *type) void annotate_value_history_value (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032value-history-value\n"); } void annotate_value_history_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032value-history-end\n"); } void annotate_value_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032value-end\n"); } void annotate_display_begin (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032display-begin\n"); } void annotate_display_number_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032display-number-end\n"); } void annotate_display_format (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032display-format\n"); } void annotate_display_expression (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032display-expression\n"); } void annotate_display_expression_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032display-expression-end\n"); } void annotate_display_value (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032display-value\n"); } void annotate_display_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032display-end\n"); } void annotate_arg_begin (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032arg-begin\n"); } void annotate_arg_name_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032arg-name-end\n"); } void annotate_arg_value (struct type *type) { - if (annotation_level > 1) + if (annotation_level == 2) { printf_filtered ("\n\032\032arg-value "); print_value_flags (type); @@ -408,7 +408,7 @@ annotate_arg_value (struct type *type) void annotate_arg_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032arg-end\n"); } @@ -430,7 +430,7 @@ annotate_source (char *filename, int line, int character, int mid, CORE_ADDR pc) void annotate_frame_begin (int level, CORE_ADDR pc) { - if (annotation_level > 1) + if (annotation_level == 2) { printf_filtered ("\n\032\032frame-begin %d 0x", level); print_address_numeric (pc, 0, gdb_stdout); @@ -441,98 +441,98 @@ annotate_frame_begin (int level, CORE_ADDR pc) void annotate_function_call (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032function-call\n"); } void annotate_signal_handler_caller (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032signal-handler-caller\n"); } void annotate_frame_address (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-address\n"); } void annotate_frame_address_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-address-end\n"); } void annotate_frame_function_name (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-function-name\n"); } void annotate_frame_args (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-args\n"); } void annotate_frame_source_begin (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-source-begin\n"); } void annotate_frame_source_file (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-source-file\n"); } void annotate_frame_source_file_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-source-file-end\n"); } void annotate_frame_source_line (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-source-line\n"); } void annotate_frame_source_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-source-end\n"); } void annotate_frame_where (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-where\n"); } void annotate_frame_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032frame-end\n"); } void annotate_array_section_begin (int index, struct type *elttype) { - if (annotation_level > 1) + if (annotation_level == 2) { printf_filtered ("\n\032\032array-section-begin %d ", index); print_value_flags (elttype); @@ -543,28 +543,28 @@ annotate_array_section_begin (int index, struct type *elttype) void annotate_elt_rep (unsigned int repcount) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032elt-rep %u\n", repcount); } void annotate_elt_rep_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032elt-rep-end\n"); } void annotate_elt (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032elt\n"); } void annotate_array_section_end (void) { - if (annotation_level > 1) + if (annotation_level == 2) printf_filtered ("\n\032\032array-section-end\n"); } diff --git a/contrib/gdb/gdb/arch-utils.c b/contrib/gdb/gdb/arch-utils.c index 5612ddf841c..94ba59be853 100644 --- a/contrib/gdb/gdb/arch-utils.c +++ b/contrib/gdb/gdb/arch-utils.c @@ -1,5 +1,7 @@ /* Dynamic architecture support for GDB, the GNU debugger. - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -20,78 +22,66 @@ #include "defs.h" -#if GDB_MULTI_ARCH #include "arch-utils.h" +#include "buildsym.h" #include "gdbcmd.h" #include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */ -#else -/* Just include everything in sight so that the every old definition - of macro is visible. */ #include "gdb_string.h" -#include "symtab.h" -#include "frame.h" -#include "inferior.h" -#include "breakpoint.h" -#include "gdb_wait.h" -#include "gdbcore.h" -#include "gdbcmd.h" -#include "target.h" -#include "annotate.h" -#endif #include "regcache.h" #include "gdb_assert.h" +#include "sim-regno.h" + +#include "osabi.h" #include "version.h" #include "floatformat.h" -/* Use the program counter to determine the contents and size - of a breakpoint instruction. If no target-dependent macro - BREAKPOINT_FROM_PC has been defined to implement this function, - assume that the breakpoint doesn't depend on the PC, and - use the values of the BIG_BREAKPOINT and LITTLE_BREAKPOINT macros. - Return a pointer to a string of bytes that encode a breakpoint - instruction, stores the length of the string to *lenptr, - and optionally adjust the pc to point to the correct memory location - for inserting the breakpoint. */ - -unsigned char * -legacy_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr) +/* Implementation of extract return value that grubs around in the + register cache. */ +void +legacy_extract_return_value (struct type *type, struct regcache *regcache, + void *valbuf) { - /* {BIG_,LITTLE_}BREAKPOINT is the sequence of bytes we insert for a - breakpoint. On some machines, breakpoints are handled by the - target environment and we don't have to worry about them here. */ -#ifdef BIG_BREAKPOINT - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - { - static unsigned char big_break_insn[] = BIG_BREAKPOINT; - *lenptr = sizeof (big_break_insn); - return big_break_insn; - } -#endif -#ifdef LITTLE_BREAKPOINT - if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG) - { - static unsigned char little_break_insn[] = LITTLE_BREAKPOINT; - *lenptr = sizeof (little_break_insn); - return little_break_insn; - } -#endif -#ifdef BREAKPOINT - { - static unsigned char break_insn[] = BREAKPOINT; - *lenptr = sizeof (break_insn); - return break_insn; - } -#endif - *lenptr = 0; - return NULL; + char *registers = deprecated_grub_regcache_for_registers (regcache); + bfd_byte *buf = valbuf; + DEPRECATED_EXTRACT_RETURN_VALUE (type, registers, buf); /* OK */ } -int -generic_frameless_function_invocation_not (struct frame_info *fi) +/* Implementation of store return value that grubs the register cache. + Takes a local copy of the buffer to avoid const problems. */ +void +legacy_store_return_value (struct type *type, struct regcache *regcache, + const void *buf) { - return 0; + bfd_byte *b = alloca (TYPE_LENGTH (type)); + gdb_assert (regcache == current_regcache); + memcpy (b, buf, TYPE_LENGTH (type)); + DEPRECATED_STORE_RETURN_VALUE (type, b); +} + + +int +always_use_struct_convention (int gcc_p, struct type *value_type) +{ + return 1; +} + + +int +legacy_register_sim_regno (int regnum) +{ + /* Only makes sense to supply raw registers. */ + gdb_assert (regnum >= 0 && regnum < NUM_REGS); + /* NOTE: cagney/2002-05-13: The old code did it this way and it is + suspected that some GDB/SIM combinations may rely on this + behavour. The default should be one2one_register_sim_regno + (below). */ + if (REGISTER_NAME (regnum) != NULL + && REGISTER_NAME (regnum)[0] != '\0') + return regnum; + else + return LEGACY_SIM_REGNO_IGNORE; } int @@ -106,34 +96,30 @@ generic_skip_trampoline_code (CORE_ADDR pc) return 0; } +CORE_ADDR +generic_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + return 0; +} + int generic_in_solib_call_trampoline (CORE_ADDR pc, char *name) { return 0; } +int +generic_in_solib_return_trampoline (CORE_ADDR pc, char *name) +{ + return 0; +} + int generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) { return 0; } -char * -legacy_register_name (int i) -{ -#ifdef REGISTER_NAMES - static char *names[] = REGISTER_NAMES; - if (i < 0 || i >= (sizeof (names) / sizeof (*names))) - return NULL; - else - return names[i]; -#else - internal_error (__FILE__, __LINE__, - "legacy_register_name: called."); - return NULL; -#endif -} - #if defined (CALL_DUMMY) LONGEST legacy_call_dummy_words[] = CALL_DUMMY; #else @@ -142,31 +128,15 @@ LONGEST legacy_call_dummy_words[1]; int legacy_sizeof_call_dummy_words = sizeof (legacy_call_dummy_words); void -generic_remote_translate_xfer_address (CORE_ADDR gdb_addr, int gdb_len, +generic_remote_translate_xfer_address (struct gdbarch *gdbarch, + struct regcache *regcache, + CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR * rem_addr, int *rem_len) { *rem_addr = gdb_addr; *rem_len = gdb_len; } -int -generic_prologue_frameless_p (CORE_ADDR ip) -{ -#ifdef SKIP_PROLOGUE_FRAMELESS_P - return ip == SKIP_PROLOGUE_FRAMELESS_P (ip); -#else - return ip == SKIP_PROLOGUE (ip); -#endif -} - -/* New/multi-arched targets should use the correct gdbarch field - instead of using this global pointer. */ -int -legacy_print_insn (bfd_vma vma, disassemble_info *info) -{ - return (*tm_print_insn) (vma, info); -} - /* Helper functions for INNER_THAN */ int @@ -187,11 +157,7 @@ core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs) const struct floatformat * default_float_format (struct gdbarch *gdbarch) { -#if GDB_MULTI_ARCH int byte_order = gdbarch_byte_order (gdbarch); -#else - int byte_order = TARGET_BYTE_ORDER; -#endif switch (byte_order) { case BFD_ENDIAN_BIG: @@ -208,11 +174,7 @@ default_float_format (struct gdbarch *gdbarch) const struct floatformat * default_double_format (struct gdbarch *gdbarch) { -#if GDB_MULTI_ARCH int byte_order = gdbarch_byte_order (gdbarch); -#else - int byte_order = TARGET_BYTE_ORDER; -#endif switch (byte_order) { case BFD_ENDIAN_BIG: @@ -225,151 +187,36 @@ default_double_format (struct gdbarch *gdbarch) } } -void -default_print_float_info (void) -{ -#ifdef FLOAT_INFO -#if GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL -#error "FLOAT_INFO defined in multi-arch" -#endif - FLOAT_INFO; -#else - printf_filtered ("No floating point info available for this processor.\n"); -#endif -} - /* Misc helper functions for targets. */ -int -frame_num_args_unknown (struct frame_info *fi) -{ - return -1; -} - - -int -generic_register_convertible_not (int num) -{ - return 0; -} - - -/* Under some ABI's that specify the `struct convention' for returning - structures by value, by the time we've returned from the function, - the return value is sitting there in the caller's buffer, but GDB - has no way to find the address of that buffer. - - On such architectures, use this function as your - extract_struct_value_address method. When asked to a struct - returned by value in this fashion, GDB will print a nice error - message, instead of garbage. */ -CORE_ADDR -generic_cannot_extract_struct_value_address (char *dummy) -{ - return 0; -} - -int -default_register_sim_regno (int num) -{ - return num; -} - - CORE_ADDR core_addr_identity (CORE_ADDR addr) { return addr; } +CORE_ADDR +convert_from_func_ptr_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr, + struct target_ops *targ) +{ + return addr; +} + int no_op_reg_to_regnum (int reg) { return reg; } -/* For use by frame_args_address and frame_locals_address. */ CORE_ADDR -default_frame_address (struct frame_info *fi) +deprecated_init_frame_pc_default (int fromleaf, struct frame_info *prev) { - return fi->frame; -} - -/* Default prepare_to_procced(). */ -int -default_prepare_to_proceed (int select_it) -{ - return 0; -} - -/* Generic prepare_to_proceed(). This one should be suitable for most - targets that support threads. */ -int -generic_prepare_to_proceed (int select_it) -{ - ptid_t wait_ptid; - struct target_waitstatus wait_status; - - /* Get the last target status returned by target_wait(). */ - get_last_target_status (&wait_ptid, &wait_status); - - /* Make sure we were stopped either at a breakpoint, or because - of a Ctrl-C. */ - if (wait_status.kind != TARGET_WAITKIND_STOPPED - || (wait_status.value.sig != TARGET_SIGNAL_TRAP && - wait_status.value.sig != TARGET_SIGNAL_INT)) - { - return 0; - } - - if (!ptid_equal (wait_ptid, minus_one_ptid) - && !ptid_equal (inferior_ptid, wait_ptid)) - { - /* Switched over from WAIT_PID. */ - CORE_ADDR wait_pc = read_pc_pid (wait_ptid); - - if (wait_pc != read_pc ()) - { - if (select_it) - { - /* Switch back to WAIT_PID thread. */ - inferior_ptid = wait_ptid; - - /* FIXME: This stuff came from switch_to_thread() in - thread.c (which should probably be a public function). */ - flush_cached_frames (); - registers_changed (); - stop_pc = wait_pc; - select_frame (get_current_frame (), 0); - } - /* We return 1 to indicate that there is a breakpoint here, - so we need to step over it before continuing to avoid - hitting it straight away. */ - if (breakpoint_here_p (wait_pc)) - { - return 1; - } - } - } - return 0; - -} - -void -init_frame_pc_noop (int fromleaf, struct frame_info *prev) -{ - return; -} - -void -init_frame_pc_default (int fromleaf, struct frame_info *prev) -{ - if (fromleaf) - prev->pc = SAVED_PC_AFTER_CALL (prev->next); - else if (prev->next != NULL) - prev->pc = FRAME_SAVED_PC (prev->next); + if (fromleaf && DEPRECATED_SAVED_PC_AFTER_CALL_P ()) + return DEPRECATED_SAVED_PC_AFTER_CALL (get_next_frame (prev)); + else if (get_next_frame (prev) != NULL) + return DEPRECATED_FRAME_SAVED_PC (get_next_frame (prev)); else - prev->pc = read_pc (); + return read_pc (); } void @@ -391,34 +238,118 @@ cannot_register_not (int regnum) } /* Legacy version of target_virtual_frame_pointer(). Assumes that - there is an FP_REGNUM and that it is the same, cooked or raw. */ + there is an DEPRECATED_FP_REGNUM and that it is the same, cooked or + raw. */ void legacy_virtual_frame_pointer (CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset) { - gdb_assert (FP_REGNUM >= 0); - *frame_regnum = FP_REGNUM; + /* FIXME: cagney/2002-09-13: This code is used when identifying the + frame pointer of the current PC. It is assuming that a single + register and an offset can determine this. I think it should + instead generate a byte code expression as that would work better + with things like Dwarf2's CFI. */ + if (DEPRECATED_FP_REGNUM >= 0 && DEPRECATED_FP_REGNUM < NUM_REGS) + *frame_regnum = DEPRECATED_FP_REGNUM; + else if (SP_REGNUM >= 0 && SP_REGNUM < NUM_REGS) + *frame_regnum = SP_REGNUM; + else + /* Should this be an internal error? I guess so, it is reflecting + an architectural limitation in the current design. */ + internal_error (__FILE__, __LINE__, "No virtual frame pointer available"); *frame_offset = 0; } -/* Assume the world is flat. Every register is large enough to fit a - target integer. */ +/* Assume the world is sane, every register's virtual and real size + is identical. */ int -generic_register_raw_size (int regnum) +generic_register_size (int regnum) { gdb_assert (regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS); - return TARGET_INT_BIT / HOST_CHAR_BIT; + if (gdbarch_register_type_p (current_gdbarch)) + return TYPE_LENGTH (gdbarch_register_type (current_gdbarch, regnum)); + else + /* FIXME: cagney/2003-03-01: Once all architectures implement + gdbarch_register_type(), this entire function can go away. It + is made obsolete by register_size(). */ + return TYPE_LENGTH (DEPRECATED_REGISTER_VIRTUAL_TYPE (regnum)); /* OK */ } -/* Assume the virtual size corresponds to the virtual type. */ +/* Assume all registers are adjacent. */ int -generic_register_virtual_size (int regnum) +generic_register_byte (int regnum) { - return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum)); + int byte; + int i; + gdb_assert (regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS); + byte = 0; + for (i = 0; i < regnum; i++) + { + byte += generic_register_size (i); + } + return byte; +} + + +int +legacy_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ +#if !defined (IN_SIGTRAMP) + if (SIGTRAMP_START_P ()) + return (pc) >= SIGTRAMP_START (pc) && (pc) < SIGTRAMP_END (pc); + else + return name && strcmp ("_sigtramp", name) == 0; +#else + return IN_SIGTRAMP (pc, name); +#endif +} + +int +legacy_convert_register_p (int regnum, struct type *type) +{ + return (DEPRECATED_REGISTER_CONVERTIBLE_P () + && DEPRECATED_REGISTER_CONVERTIBLE (regnum)); +} + +void +legacy_register_to_value (struct frame_info *frame, int regnum, + struct type *type, void *to) +{ + char from[MAX_REGISTER_SIZE]; + get_frame_register (frame, regnum, from); + DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to); +} + +void +legacy_value_to_register (struct frame_info *frame, int regnum, + struct type *type, const void *tmp) +{ + char to[MAX_REGISTER_SIZE]; + char *from = alloca (TYPE_LENGTH (type)); + memcpy (from, from, TYPE_LENGTH (type)); + DEPRECATED_REGISTER_CONVERT_TO_RAW (type, regnum, from, to); + put_frame_register (frame, regnum, to); +} + +int +default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type) +{ + if (DEPRECATED_REG_STRUCT_HAS_ADDR_P () + && DEPRECATED_REG_STRUCT_HAS_ADDR (processing_gcc_compilation, type)) + { + CHECK_TYPEDEF (type); + + return (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_CODE (type) == TYPE_CODE_SET + || TYPE_CODE (type) == TYPE_CODE_BITSTRING); + } + + return 0; } @@ -431,8 +362,17 @@ generic_register_virtual_size (int regnum) The choice of initial value is entirely arbitrary. During startup, the function initialize_current_architecture() updates this value based on default byte-order information extracted from BFD. */ -int target_byte_order = BFD_ENDIAN_BIG; -int target_byte_order_auto = 1; +static int target_byte_order = BFD_ENDIAN_BIG; +static int target_byte_order_auto = 1; + +enum bfd_endian +selected_byte_order (void) +{ + if (target_byte_order_auto) + return BFD_ENDIAN_UNKNOWN; + else + return target_byte_order; +} static const char endian_big[] = "big"; static const char endian_little[] = "little"; @@ -451,7 +391,7 @@ static const char *set_endian_string; static void show_endian (char *args, int from_tty) { - if (TARGET_BYTE_ORDER_AUTO) + if (target_byte_order_auto) printf_unfiltered ("The target endianness is set automatically (currently %s endian)\n", (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little")); else @@ -468,39 +408,21 @@ set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c) } else if (set_endian_string == endian_little) { + struct gdbarch_info info; target_byte_order_auto = 0; - if (GDB_MULTI_ARCH) - { - struct gdbarch_info info; - gdbarch_info_init (&info); - info.byte_order = BFD_ENDIAN_LITTLE; - if (! gdbarch_update_p (info)) - { - printf_unfiltered ("Little endian target not supported by GDB\n"); - } - } - else - { - target_byte_order = BFD_ENDIAN_LITTLE; - } + gdbarch_info_init (&info); + info.byte_order = BFD_ENDIAN_LITTLE; + if (! gdbarch_update_p (info)) + printf_unfiltered ("Little endian target not supported by GDB\n"); } else if (set_endian_string == endian_big) { + struct gdbarch_info info; target_byte_order_auto = 0; - if (GDB_MULTI_ARCH) - { - struct gdbarch_info info; - gdbarch_info_init (&info); - info.byte_order = BFD_ENDIAN_BIG; - if (! gdbarch_update_p (info)) - { - printf_unfiltered ("Big endian target not supported by GDB\n"); - } - } - else - { - target_byte_order = BFD_ENDIAN_BIG; - } + gdbarch_info_init (&info); + info.byte_order = BFD_ENDIAN_BIG; + if (! gdbarch_update_p (info)) + printf_unfiltered ("Big endian target not supported by GDB\n"); } else internal_error (__FILE__, __LINE__, @@ -508,126 +430,23 @@ set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c) show_endian (NULL, from_tty); } -/* Set the endianness from a BFD. */ - -static void -set_endian_from_file (bfd *abfd) -{ - int want; - if (GDB_MULTI_ARCH) - internal_error (__FILE__, __LINE__, - "set_endian_from_file: not for multi-arch"); - if (bfd_big_endian (abfd)) - want = BFD_ENDIAN_BIG; - else - want = BFD_ENDIAN_LITTLE; - if (TARGET_BYTE_ORDER_AUTO) - target_byte_order = want; - else if (TARGET_BYTE_ORDER != want) - warning ("%s endian file does not match %s endian target.", - want == BFD_ENDIAN_BIG ? "big" : "little", - TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"); -} - - /* Functions to manipulate the architecture of the target */ enum set_arch { set_arch_auto, set_arch_manual }; -int target_architecture_auto = 1; +static int target_architecture_auto = 1; -const char *set_architecture_string; +static const char *set_architecture_string; -/* Old way of changing the current architecture. */ - -extern const struct bfd_arch_info bfd_default_arch_struct; -const struct bfd_arch_info *target_architecture = &bfd_default_arch_struct; -int (*target_architecture_hook) (const struct bfd_arch_info *ap); - -static int -arch_ok (const struct bfd_arch_info *arch) +const char * +selected_architecture_name (void) { - if (GDB_MULTI_ARCH) - internal_error (__FILE__, __LINE__, - "arch_ok: not multi-arched"); - /* Should be performing the more basic check that the binary is - compatible with GDB. */ - /* Check with the target that the architecture is valid. */ - return (target_architecture_hook == NULL - || target_architecture_hook (arch)); -} - -static void -set_arch (const struct bfd_arch_info *arch, - enum set_arch type) -{ - if (GDB_MULTI_ARCH) - internal_error (__FILE__, __LINE__, - "set_arch: not multi-arched"); - switch (type) - { - case set_arch_auto: - if (!arch_ok (arch)) - warning ("Target may not support %s architecture", - arch->printable_name); - target_architecture = arch; - break; - case set_arch_manual: - if (!arch_ok (arch)) - { - printf_unfiltered ("Target does not support `%s' architecture.\n", - arch->printable_name); - } - else - { - target_architecture_auto = 0; - target_architecture = arch; - } - break; - } - if (gdbarch_debug) - gdbarch_dump (current_gdbarch, gdb_stdlog); -} - -/* Set the architecture from arch/machine (deprecated) */ - -void -set_architecture_from_arch_mach (enum bfd_architecture arch, - unsigned long mach) -{ - const struct bfd_arch_info *wanted = bfd_lookup_arch (arch, mach); - if (GDB_MULTI_ARCH) - internal_error (__FILE__, __LINE__, - "set_architecture_from_arch_mach: not multi-arched"); - if (wanted != NULL) - set_arch (wanted, set_arch_manual); - else - internal_error (__FILE__, __LINE__, - "gdbarch: hardwired architecture/machine not recognized"); -} - -/* Set the architecture from a BFD (deprecated) */ - -static void -set_architecture_from_file (bfd *abfd) -{ - const struct bfd_arch_info *wanted = bfd_get_arch_info (abfd); - if (GDB_MULTI_ARCH) - internal_error (__FILE__, __LINE__, - "set_architecture_from_file: not multi-arched"); if (target_architecture_auto) - { - set_arch (wanted, set_arch_auto); - } - else if (wanted != target_architecture) - { - warning ("%s architecture file may be incompatible with %s target.", - wanted->printable_name, - target_architecture->printable_name); - } + return NULL; + else + return set_architecture_string; } - /* Called if the user enters ``show architecture'' without an argument. */ @@ -653,7 +472,7 @@ set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c) { target_architecture_auto = 1; } - else if (GDB_MULTI_ARCH) + else { struct gdbarch_info info; gdbarch_info_init (&info); @@ -667,37 +486,75 @@ set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c) printf_unfiltered ("Architecture `%s' not recognized.\n", set_architecture_string); } - else - { - const struct bfd_arch_info *arch - = bfd_scan_arch (set_architecture_string); - if (arch == NULL) - internal_error (__FILE__, __LINE__, - "set_architecture: bfd_scan_arch failed"); - set_arch (arch, set_arch_manual); - } show_architecture (NULL, from_tty); } +/* Try to select a global architecture that matches "info". Return + non-zero if the attempt succeds. */ +int +gdbarch_update_p (struct gdbarch_info info) +{ + struct gdbarch *new_gdbarch = gdbarch_find_by_info (info); + + /* If there no architecture by that name, reject the request. */ + if (new_gdbarch == NULL) + { + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: " + "Architecture not found\n"); + return 0; + } + + /* If it is the same old architecture, accept the request (but don't + swap anything). */ + if (new_gdbarch == current_gdbarch) + { + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: " + "Architecture 0x%08lx (%s) unchanged\n", + (long) new_gdbarch, + gdbarch_bfd_arch_info (new_gdbarch)->printable_name); + return 1; + } + + /* It's a new architecture, swap it in. */ + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: " + "New architecture 0x%08lx (%s) selected\n", + (long) new_gdbarch, + gdbarch_bfd_arch_info (new_gdbarch)->printable_name); + deprecated_current_gdbarch_select_hack (new_gdbarch); + + return 1; +} + +/* Return the architecture for ABFD. If no suitable architecture + could be find, return NULL. */ + +struct gdbarch * +gdbarch_from_bfd (bfd *abfd) +{ + struct gdbarch *old_gdbarch = current_gdbarch; + struct gdbarch *new_gdbarch; + struct gdbarch_info info; + + gdbarch_info_init (&info); + info.abfd = abfd; + return gdbarch_find_by_info (info); +} + /* Set the dynamic target-system-dependent parameters (architecture, byte-order) using information found in the BFD */ void set_gdbarch_from_file (bfd *abfd) { - if (GDB_MULTI_ARCH) - { - struct gdbarch_info info; - gdbarch_info_init (&info); - info.abfd = abfd; - if (! gdbarch_update_p (info)) - error ("Architecture of file not recognized.\n"); - } - else - { - set_architecture_from_file (abfd); - set_endian_from_file (abfd); - } + struct gdbarch *gdbarch; + + gdbarch = gdbarch_from_bfd (abfd); + if (gdbarch == NULL) + error ("Architecture of file not recognized.\n"); + deprecated_current_gdbarch_select_hack (gdbarch); } /* Initialize the current architecture. Update the ``set @@ -784,22 +641,9 @@ initialize_current_architecture (void) info.byte_order = BFD_ENDIAN_BIG; } - if (GDB_MULTI_ARCH) - { - if (! gdbarch_update_p (info)) - { - internal_error (__FILE__, __LINE__, - "initialize_current_architecture: Selection of initial architecture failed"); - } - } - else - { - /* If the multi-arch logic comes up with a byte-order (from BFD) - use it for the non-multi-arch case. */ - if (info.byte_order != BFD_ENDIAN_UNKNOWN) - target_byte_order = info.byte_order; - initialize_non_multiarch (); - } + if (! gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, + "initialize_current_architecture: Selection of initial architecture failed"); /* Create the ``set architecture'' command appending ``auto'' to the list of architectures. */ @@ -830,7 +674,7 @@ initialize_current_architecture (void) /* Initialize a gdbarch info to values that will be automatically overridden. Note: Originally, this ``struct info'' was initialized - using memset(0). Unfortunatly, that ran into problems, namely + using memset(0). Unfortunately, that ran into problems, namely BFD_ENDIAN_BIG is zero. An explicit initialization function that can explicitly set each field to a well defined value is used. */ @@ -839,11 +683,60 @@ gdbarch_info_init (struct gdbarch_info *info) { memset (info, 0, sizeof (struct gdbarch_info)); info->byte_order = BFD_ENDIAN_UNKNOWN; + info->osabi = GDB_OSABI_UNINITIALIZED; +} + +/* Similar to init, but this time fill in the blanks. Information is + obtained from the specified architecture, global "set ..." options, + and explicitly initialized INFO fields. */ + +void +gdbarch_info_fill (struct gdbarch *gdbarch, struct gdbarch_info *info) +{ + /* "(gdb) set architecture ...". */ + if (info->bfd_arch_info == NULL + && !target_architecture_auto + && gdbarch != NULL) + info->bfd_arch_info = gdbarch_bfd_arch_info (gdbarch); + if (info->bfd_arch_info == NULL + && info->abfd != NULL + && bfd_get_arch (info->abfd) != bfd_arch_unknown + && bfd_get_arch (info->abfd) != bfd_arch_obscure) + info->bfd_arch_info = bfd_get_arch_info (info->abfd); + if (info->bfd_arch_info == NULL + && gdbarch != NULL) + info->bfd_arch_info = gdbarch_bfd_arch_info (gdbarch); + + /* "(gdb) set byte-order ...". */ + if (info->byte_order == BFD_ENDIAN_UNKNOWN + && !target_byte_order_auto + && gdbarch != NULL) + info->byte_order = gdbarch_byte_order (gdbarch); + /* From the INFO struct. */ + if (info->byte_order == BFD_ENDIAN_UNKNOWN + && info->abfd != NULL) + info->byte_order = (bfd_big_endian (info->abfd) ? BFD_ENDIAN_BIG + : bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE + : BFD_ENDIAN_UNKNOWN); + /* From the current target. */ + if (info->byte_order == BFD_ENDIAN_UNKNOWN + && gdbarch != NULL) + info->byte_order = gdbarch_byte_order (gdbarch); + + /* "(gdb) set osabi ...". Handled by gdbarch_lookup_osabi. */ + if (info->osabi == GDB_OSABI_UNINITIALIZED) + info->osabi = gdbarch_lookup_osabi (info->abfd); + if (info->osabi == GDB_OSABI_UNINITIALIZED + && gdbarch != NULL) + info->osabi = gdbarch_osabi (gdbarch); + + /* Must have at least filled in the architecture. */ + gdb_assert (info->bfd_arch_info != NULL); } /* */ -extern initialize_file_ftype _initialize_gdbarch_utils; +extern initialize_file_ftype _initialize_gdbarch_utils; /* -Wmissing-prototypes */ void _initialize_gdbarch_utils (void) diff --git a/contrib/gdb/gdb/arch-utils.h b/contrib/gdb/gdb/arch-utils.h index 96d1b8b6174..0f7a23d517b 100644 --- a/contrib/gdb/gdb/arch-utils.h +++ b/contrib/gdb/gdb/arch-utils.h @@ -1,5 +1,7 @@ /* Dynamic architecture support for GDB, the GNU debugger. - Copyright 1998, 1999, 2000 Free Software Foundation, Inc. + + Copyright 1998, 1999, 2000, 2002, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -21,37 +23,31 @@ #ifndef GDBARCH_UTILS_H #define GDBARCH_UTILS_H +struct gdbarch; +struct frame_info; +struct minimal_symbol; +struct type; +struct gdbarch_info; + /* gdbarch trace variable */ extern int gdbarch_debug; -/* Fallback for register convertible. */ -extern gdbarch_register_convertible_ftype generic_register_convertible_not; +/* Implementation of extract return value that grubs around in the + register cache. */ +extern gdbarch_extract_return_value_ftype legacy_extract_return_value; -extern CORE_ADDR generic_cannot_extract_struct_value_address (char *dummy); +/* Implementation of store return value that grubs the register cache. */ +extern gdbarch_store_return_value_ftype legacy_store_return_value; -/* Helper function for targets that don't know how my arguments are - being passed */ -extern gdbarch_frame_num_args_ftype frame_num_args_unknown; - -/* Implementation of breakpoint from PC using any of the deprecated - macros BREAKPOINT, LITTLE_BREAKPOINT, BIG_BREAPOINT. For legacy - targets that don't yet implement their own breakpoint_from_pc(). */ -extern gdbarch_breakpoint_from_pc_ftype legacy_breakpoint_from_pc; - -/* Frameless functions not identifable. */ -extern gdbarch_frameless_function_invocation_ftype generic_frameless_function_invocation_not; +/* To return any structure or union type by value, store it at the + address passed as an invisible first argument to the function. */ +extern gdbarch_use_struct_convention_ftype always_use_struct_convention; /* Only structures, unions, and arrays are returned using the struct convention. Note that arrays are never passed by value in the C language family, so that case is irrelevant for C. */ extern gdbarch_return_value_on_stack_ftype generic_return_value_on_stack_not; -/* Map onto old REGISTER_NAMES. */ -extern char *legacy_register_name (int i); - -/* Accessor for old global function pointer for disassembly. */ -extern int legacy_print_insn (bfd_vma vma, disassemble_info *info); - /* Backward compatible call_dummy_words. */ extern LONGEST legacy_call_dummy_words[]; extern int legacy_sizeof_call_dummy_words; @@ -59,11 +55,6 @@ extern int legacy_sizeof_call_dummy_words; /* Typical remote_translate_xfer_address */ extern gdbarch_remote_translate_xfer_address_ftype generic_remote_translate_xfer_address; -/* Generic implementation of prologue_frameless_p. Just calls - SKIP_PROLOG and checks the return value to see if it actually - changed. */ -extern gdbarch_prologue_frameless_p_ftype generic_prologue_frameless_p; - /* The only possible cases for inner_than. */ extern int core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs); extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs); @@ -72,55 +63,18 @@ extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs); extern const struct floatformat *default_float_format (struct gdbarch *gdbarch); extern const struct floatformat *default_double_format (struct gdbarch *gdbarch); -/* Helper function for targets that don't know how my arguments are - being passed */ -extern int frame_num_args_unknown (struct frame_info *fi); - - -/* The following DEPRECATED interfaces are for pre- multi-arch legacy - targets. */ - -/* DEPRECATED pre- multi-arch interface. Explicitly set the dynamic - target-system-dependent parameters based on bfd_architecture and - machine. This function is deprecated, use - set_gdbarch_from_arch_machine(). */ - -extern void set_architecture_from_arch_mach (enum bfd_architecture, unsigned long); - -/* DEPRECATED pre- multi-arch interface. Notify the target dependent - backend of a change to the selected architecture. A zero return - status indicates that the target did not like the change. */ - -extern int (*target_architecture_hook) (const struct bfd_arch_info *); - - -/* Default raw->sim register re-numbering - does nothing. */ - -extern int default_register_sim_regno (int reg_nr); - -/* Identity function on a CORE_ADDR. Just returns its parameter. */ +/* Identity functions on a CORE_ADDR. Just return the "addr". */ extern CORE_ADDR core_addr_identity (CORE_ADDR addr); +extern gdbarch_convert_from_func_ptr_addr_ftype convert_from_func_ptr_addr_identity; /* No-op conversion of reg to regnum. */ extern int no_op_reg_to_regnum (int reg); -/* Default frame_args_address and frame_locals_address. */ - -extern CORE_ADDR default_frame_address (struct frame_info *); - -/* Default prepare_to_procced. */ - -extern int default_prepare_to_proceed (int select_it); - -extern int generic_prepare_to_proceed (int select_it); - /* Versions of init_frame_pc(). Do nothing; do the default. */ -void init_frame_pc_noop (int fromleaf, struct frame_info *prev); - -void init_frame_pc_default (int fromleaf, struct frame_info *prev); +extern CORE_ADDR deprecated_init_frame_pc_default (int fromleaf, struct frame_info *prev); /* Do nothing version of elf_make_msymbol_special. */ @@ -136,28 +90,78 @@ void default_coff_make_msymbol_special (int val, struct minimal_symbol *msym); int cannot_register_not (int regnum); /* Legacy version of target_virtual_frame_pointer(). Assumes that - there is an FP_REGNUM and that it is the same, cooked or raw. */ + there is an DEPRECATED_FP_REGNUM and that it is the same, cooked or + raw. */ extern gdbarch_virtual_frame_pointer_ftype legacy_virtual_frame_pointer; extern CORE_ADDR generic_skip_trampoline_code (CORE_ADDR pc); +extern CORE_ADDR generic_skip_solib_resolver (struct gdbarch *gdbarch, + CORE_ADDR pc); + extern int generic_in_solib_call_trampoline (CORE_ADDR pc, char *name); +extern int generic_in_solib_return_trampoline (CORE_ADDR pc, char *name); + extern int generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc); -extern void default_print_float_info (void); +/* Assume that the world is sane, a registers raw and virtual size + both match its type. */ -/* Assume all registers are the same size and a size identical to that - of the integer type. */ -extern int generic_register_raw_size (int regnum); +extern int generic_register_size (int regnum); -/* Assume the virtual size of registers corresponds to the virtual type. */ +/* Assume that the world is sane, the registers are all adjacent. */ +extern int generic_register_byte (int regnum); -extern int generic_register_virtual_size (int regnum); +/* Prop up old targets that use various IN_SIGTRAMP() macros. */ +extern int legacy_pc_in_sigtramp (CORE_ADDR pc, char *name); + +/* The orginal register_convert*() functions were overloaded. They + were used to both: convert between virtual and raw register formats + (something that is discouraged); and to convert a register to the + type of a corresponding variable. These legacy functions preserve + that overloaded behavour in existing targets. */ +extern int legacy_convert_register_p (int regnum, struct type *type); +extern void legacy_register_to_value (struct frame_info *frame, int regnum, + struct type *type, void *to); +extern void legacy_value_to_register (struct frame_info *frame, int regnum, + struct type *type, const void *from); + +extern int default_stabs_argument_has_addr (struct gdbarch *gdbarch, + struct type *type); + +/* For compatibility with older architectures, returns + (LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid + name. */ + +extern int legacy_register_sim_regno (int regnum); + +/* Return the selected byte order, or BFD_ENDIAN_UNKNOWN if no byte + order was explicitly selected. */ +extern enum bfd_endian selected_byte_order (void); + +/* Return the selected architecture's name, or NULL if no architecture + was explicitly selected. */ +extern const char *selected_architecture_name (void); /* Initialize a ``struct info''. Can't use memset(0) since some - default values are not zero. */ + default values are not zero. "fill" takes all available + information and fills in any unspecified fields. */ + extern void gdbarch_info_init (struct gdbarch_info *info); +extern void gdbarch_info_fill (struct gdbarch *gdbarch, + struct gdbarch_info *info); + +/* Similar to init, but this time fill in the blanks. Information is + obtained from the specified architecture, global "set ..." options, + and explicitly initialized INFO fields. */ +extern void gdbarch_info_fill (struct gdbarch *gdbarch, + struct gdbarch_info *info); + +/* Return the architecture for ABFD. If no suitable architecture + could be find, return NULL. */ + +extern struct gdbarch *gdbarch_from_bfd (bfd *abfd); #endif diff --git a/contrib/gdb/gdb/arm-tdep.c b/contrib/gdb/gdb/arm-tdep.c new file mode 100644 index 00000000000..00346908548 --- /dev/null +++ b/contrib/gdb/gdb/arm-tdep.c @@ -0,0 +1,3018 @@ +/* Common target dependent code for GDB on ARM systems. + Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998, 1999, 2000, + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include /* XXX for isupper () */ + +#include "defs.h" +#include "frame.h" +#include "inferior.h" +#include "gdbcmd.h" +#include "gdbcore.h" +#include "gdb_string.h" +#include "dis-asm.h" /* For register styles. */ +#include "regcache.h" +#include "doublest.h" +#include "value.h" +#include "arch-utils.h" +#include "osabi.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "trad-frame.h" + +#include "arm-tdep.h" +#include "gdb/sim-arm.h" + +#include "elf-bfd.h" +#include "coff/internal.h" +#include "elf/arm.h" + +#include "gdb_assert.h" + +static int arm_debug; + +/* Each OS has a different mechanism for accessing the various + registers stored in the sigcontext structure. + + SIGCONTEXT_REGISTER_ADDRESS should be defined to the name (or + function pointer) which may be used to determine the addresses + of the various saved registers in the sigcontext structure. + + For the ARM target, there are three parameters to this function. + The first is the pc value of the frame under consideration, the + second the stack pointer of this frame, and the last is the + register number to fetch. + + If the tm.h file does not define this macro, then it's assumed that + no mechanism is needed and we define SIGCONTEXT_REGISTER_ADDRESS to + be 0. + + When it comes time to multi-arching this code, see the identically + named machinery in ia64-tdep.c for an example of how it could be + done. It should not be necessary to modify the code below where + this macro is used. */ + +#ifdef SIGCONTEXT_REGISTER_ADDRESS +#ifndef SIGCONTEXT_REGISTER_ADDRESS_P +#define SIGCONTEXT_REGISTER_ADDRESS_P() 1 +#endif +#else +#define SIGCONTEXT_REGISTER_ADDRESS(SP,PC,REG) 0 +#define SIGCONTEXT_REGISTER_ADDRESS_P() 0 +#endif + +/* Macros for setting and testing a bit in a minimal symbol that marks + it as Thumb function. The MSB of the minimal symbol's "info" field + is used for this purpose. + + MSYMBOL_SET_SPECIAL Actually sets the "special" bit. + MSYMBOL_IS_SPECIAL Tests the "special" bit in a minimal symbol. */ + +#define MSYMBOL_SET_SPECIAL(msym) \ + MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) \ + | 0x80000000) + +#define MSYMBOL_IS_SPECIAL(msym) \ + (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0) + +/* The list of available "set arm ..." and "show arm ..." commands. */ +static struct cmd_list_element *setarmcmdlist = NULL; +static struct cmd_list_element *showarmcmdlist = NULL; + +/* The type of floating-point to use. Keep this in sync with enum + arm_float_model, and the help string in _initialize_arm_tdep. */ +static const char *fp_model_strings[] = +{ + "auto", + "softfpa", + "fpa", + "softvfp", + "vfp" +}; + +/* A variable that can be configured by the user. */ +static enum arm_float_model arm_fp_model = ARM_FLOAT_AUTO; +static const char *current_fp_model = "auto"; + +/* Number of different reg name sets (options). */ +static int num_disassembly_options; + +/* We have more registers than the disassembler as gdb can print the value + of special registers as well. + The general register names are overwritten by whatever is being used by + the disassembler at the moment. We also adjust the case of cpsr and fps. */ + +/* Initial value: Register names used in ARM's ISA documentation. */ +static char * arm_register_name_strings[] = +{"r0", "r1", "r2", "r3", /* 0 1 2 3 */ + "r4", "r5", "r6", "r7", /* 4 5 6 7 */ + "r8", "r9", "r10", "r11", /* 8 9 10 11 */ + "r12", "sp", "lr", "pc", /* 12 13 14 15 */ + "f0", "f1", "f2", "f3", /* 16 17 18 19 */ + "f4", "f5", "f6", "f7", /* 20 21 22 23 */ + "fps", "cpsr" }; /* 24 25 */ +static char **arm_register_names = arm_register_name_strings; + +/* Valid register name styles. */ +static const char **valid_disassembly_styles; + +/* Disassembly style to use. Default to "std" register names. */ +static const char *disassembly_style; +/* Index to that option in the opcodes table. */ +static int current_option; + +/* This is used to keep the bfd arch_info in sync with the disassembly + style. */ +static void set_disassembly_style_sfunc(char *, int, + struct cmd_list_element *); +static void set_disassembly_style (void); + +static void convert_from_extended (const struct floatformat *, const void *, + void *); +static void convert_to_extended (const struct floatformat *, void *, + const void *); + +struct arm_prologue_cache +{ + /* The stack pointer at the time this frame was created; i.e. the + caller's stack pointer when this function was called. It is used + to identify this frame. */ + CORE_ADDR prev_sp; + + /* The frame base for this frame is just prev_sp + frame offset - + frame size. FRAMESIZE is the size of this stack frame, and + FRAMEOFFSET if the initial offset from the stack pointer (this + frame's stack pointer, not PREV_SP) to the frame base. */ + + int framesize; + int frameoffset; + + /* The register used to hold the frame pointer for this frame. */ + int framereg; + + /* Saved register offsets. */ + struct trad_frame_saved_reg *saved_regs; +}; + +/* Addresses for calling Thumb functions have the bit 0 set. + Here are some macros to test, set, or clear bit 0 of addresses. */ +#define IS_THUMB_ADDR(addr) ((addr) & 1) +#define MAKE_THUMB_ADDR(addr) ((addr) | 1) +#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1) + +/* Set to true if the 32-bit mode is in use. */ + +int arm_apcs_32 = 1; + +/* Flag set by arm_fix_call_dummy that tells whether the target + function is a Thumb function. This flag is checked by + arm_push_arguments. FIXME: Change the PUSH_ARGUMENTS macro (and + its use in valops.c) to pass the function address as an additional + parameter. */ + +static int target_is_thumb; + +/* Flag set by arm_fix_call_dummy that tells whether the calling + function is a Thumb function. This flag is checked by + arm_pc_is_thumb and arm_call_dummy_breakpoint_offset. */ + +static int caller_is_thumb; + +/* Determine if the program counter specified in MEMADDR is in a Thumb + function. */ + +int +arm_pc_is_thumb (CORE_ADDR memaddr) +{ + struct minimal_symbol *sym; + + /* If bit 0 of the address is set, assume this is a Thumb address. */ + if (IS_THUMB_ADDR (memaddr)) + return 1; + + /* Thumb functions have a "special" bit set in minimal symbols. */ + sym = lookup_minimal_symbol_by_pc (memaddr); + if (sym) + { + return (MSYMBOL_IS_SPECIAL (sym)); + } + else + { + return 0; + } +} + +/* Determine if the program counter specified in MEMADDR is in a call + dummy being called from a Thumb function. */ + +int +arm_pc_is_thumb_dummy (CORE_ADDR memaddr) +{ + CORE_ADDR sp = read_sp (); + + /* FIXME: Until we switch for the new call dummy macros, this heuristic + is the best we can do. We are trying to determine if the pc is on + the stack, which (hopefully) will only happen in a call dummy. + We hope the current stack pointer is not so far alway from the dummy + frame location (true if we have not pushed large data structures or + gone too many levels deep) and that our 1024 is not enough to consider + code regions as part of the stack (true for most practical purposes). */ + if (DEPRECATED_PC_IN_CALL_DUMMY (memaddr, sp, sp + 1024)) + return caller_is_thumb; + else + return 0; +} + +/* Remove useless bits from addresses in a running program. */ +static CORE_ADDR +arm_addr_bits_remove (CORE_ADDR val) +{ + if (arm_apcs_32) + return (val & (arm_pc_is_thumb (val) ? 0xfffffffe : 0xfffffffc)); + else + return (val & 0x03fffffc); +} + +/* When reading symbols, we need to zap the low bit of the address, + which may be set to 1 for Thumb functions. */ +static CORE_ADDR +arm_smash_text_address (CORE_ADDR val) +{ + return val & ~1; +} + +/* Immediately after a function call, return the saved pc. Can't + always go through the frames for this because on some machines the + new frame is not set up until the new function executes some + instructions. */ + +static CORE_ADDR +arm_saved_pc_after_call (struct frame_info *frame) +{ + return ADDR_BITS_REMOVE (read_register (ARM_LR_REGNUM)); +} + +/* Determine whether the function invocation represented by FI has a + frame on the stack associated with it. If it does return zero, + otherwise return 1. */ + +static int +arm_frameless_function_invocation (struct frame_info *fi) +{ + CORE_ADDR func_start, after_prologue; + int frameless; + + /* Sometimes we have functions that do a little setup (like saving the + vN registers with the stmdb instruction, but DO NOT set up a frame. + The symbol table will report this as a prologue. However, it is + important not to try to parse these partial frames as frames, or we + will get really confused. + + So I will demand 3 instructions between the start & end of the + prologue before I call it a real prologue, i.e. at least + mov ip, sp, + stmdb sp!, {} + sub sp, ip, #4. */ + + func_start = (get_frame_func (fi) + FUNCTION_START_OFFSET); + after_prologue = SKIP_PROLOGUE (func_start); + + /* There are some frameless functions whose first two instructions + follow the standard APCS form, in which case after_prologue will + be func_start + 8. */ + + frameless = (after_prologue < func_start + 12); + return frameless; +} + +/* A typical Thumb prologue looks like this: + push {r7, lr} + add sp, sp, #-28 + add r7, sp, #12 + Sometimes the latter instruction may be replaced by: + mov r7, sp + + or like this: + push {r7, lr} + mov r7, sp + sub sp, #12 + + or, on tpcs, like this: + sub sp,#16 + push {r7, lr} + (many instructions) + mov r7, sp + sub sp, #12 + + There is always one instruction of three classes: + 1 - push + 2 - setting of r7 + 3 - adjusting of sp + + When we have found at least one of each class we are done with the prolog. + Note that the "sub sp, #NN" before the push does not count. + */ + +static CORE_ADDR +thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end) +{ + CORE_ADDR current_pc; + /* findmask: + bit 0 - push { rlist } + bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7) + bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp) + */ + int findmask = 0; + + for (current_pc = pc; + current_pc + 2 < func_end && current_pc < pc + 40; + current_pc += 2) + { + unsigned short insn = read_memory_unsigned_integer (current_pc, 2); + + if ((insn & 0xfe00) == 0xb400) /* push { rlist } */ + { + findmask |= 1; /* push found */ + } + else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR + sub sp, #simm */ + { + if ((findmask & 1) == 0) /* before push ? */ + continue; + else + findmask |= 4; /* add/sub sp found */ + } + else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */ + { + findmask |= 2; /* setting of r7 found */ + } + else if (insn == 0x466f) /* mov r7, sp */ + { + findmask |= 2; /* setting of r7 found */ + } + else if (findmask == (4+2+1)) + { + /* We have found one of each type of prologue instruction */ + break; + } + else + /* Something in the prolog that we don't care about or some + instruction from outside the prolog scheduled here for + optimization. */ + continue; + } + + return current_pc; +} + +/* Advance the PC across any function entry prologue instructions to + reach some "real" code. + + The APCS (ARM Procedure Call Standard) defines the following + prologue: + + mov ip, sp + [stmfd sp!, {a1,a2,a3,a4}] + stmfd sp!, {...,fp,ip,lr,pc} + [stfe f7, [sp, #-12]!] + [stfe f6, [sp, #-12]!] + [stfe f5, [sp, #-12]!] + [stfe f4, [sp, #-12]!] + sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn */ + +static CORE_ADDR +arm_skip_prologue (CORE_ADDR pc) +{ + unsigned long inst; + CORE_ADDR skip_pc; + CORE_ADDR func_addr, func_end = 0; + char *func_name; + struct symtab_and_line sal; + + /* If we're in a dummy frame, don't even try to skip the prologue. */ + if (DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0)) + return pc; + + /* See what the symbol table says. */ + + if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end)) + { + struct symbol *sym; + + /* Found a function. */ + sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL); + if (sym && SYMBOL_LANGUAGE (sym) != language_asm) + { + /* Don't use this trick for assembly source files. */ + sal = find_pc_line (func_addr, 0); + if ((sal.line != 0) && (sal.end < func_end)) + return sal.end; + } + } + + /* Check if this is Thumb code. */ + if (arm_pc_is_thumb (pc)) + return thumb_skip_prologue (pc, func_end); + + /* Can't find the prologue end in the symbol table, try it the hard way + by disassembling the instructions. */ + + /* Like arm_scan_prologue, stop no later than pc + 64. */ + if (func_end == 0 || func_end > pc + 64) + func_end = pc + 64; + + for (skip_pc = pc; skip_pc < func_end; skip_pc += 4) + { + inst = read_memory_integer (skip_pc, 4); + + /* "mov ip, sp" is no longer a required part of the prologue. */ + if (inst == 0xe1a0c00d) /* mov ip, sp */ + continue; + + if ((inst & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */ + continue; + + if ((inst & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */ + continue; + + /* Some prologues begin with "str lr, [sp, #-4]!". */ + if (inst == 0xe52de004) /* str lr, [sp, #-4]! */ + continue; + + if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ + continue; + + if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */ + continue; + + /* Any insns after this point may float into the code, if it makes + for better instruction scheduling, so we skip them only if we + find them, but still consider the function to be frame-ful. */ + + /* We may have either one sfmfd instruction here, or several stfe + insns, depending on the version of floating point code we + support. */ + if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, , [sp]! */ + continue; + + if ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ + continue; + + if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ + continue; + + if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ + continue; + + if ((inst & 0xffffc000) == 0xe54b0000 || /* strb r(0123),[r11,#-nn] */ + (inst & 0xffffc0f0) == 0xe14b00b0 || /* strh r(0123),[r11,#-nn] */ + (inst & 0xffffc000) == 0xe50b0000) /* str r(0123),[r11,#-nn] */ + continue; + + if ((inst & 0xffffc000) == 0xe5cd0000 || /* strb r(0123),[sp,#nn] */ + (inst & 0xffffc0f0) == 0xe1cd00b0 || /* strh r(0123),[sp,#nn] */ + (inst & 0xffffc000) == 0xe58d0000) /* str r(0123),[sp,#nn] */ + continue; + + /* Un-recognized instruction; stop scanning. */ + break; + } + + return skip_pc; /* End of prologue */ +} + +/* *INDENT-OFF* */ +/* Function: thumb_scan_prologue (helper function for arm_scan_prologue) + This function decodes a Thumb function prologue to determine: + 1) the size of the stack frame + 2) which registers are saved on it + 3) the offsets of saved regs + 4) the offset from the stack pointer to the frame pointer + + A typical Thumb function prologue would create this stack frame + (offsets relative to FP) + old SP -> 24 stack parameters + 20 LR + 16 R7 + R7 -> 0 local variables (16 bytes) + SP -> -12 additional stack space (12 bytes) + The frame size would thus be 36 bytes, and the frame offset would be + 12 bytes. The frame register is R7. + + The comments for thumb_skip_prolog() describe the algorithm we use + to detect the end of the prolog. */ +/* *INDENT-ON* */ + +static void +thumb_scan_prologue (CORE_ADDR prev_pc, struct arm_prologue_cache *cache) +{ + CORE_ADDR prologue_start; + CORE_ADDR prologue_end; + CORE_ADDR current_pc; + /* Which register has been copied to register n? */ + int saved_reg[16]; + /* findmask: + bit 0 - push { rlist } + bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7) + bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp) + */ + int findmask = 0; + int i; + + if (find_pc_partial_function (prev_pc, NULL, &prologue_start, &prologue_end)) + { + struct symtab_and_line sal = find_pc_line (prologue_start, 0); + + if (sal.line == 0) /* no line info, use current PC */ + prologue_end = prev_pc; + else if (sal.end < prologue_end) /* next line begins after fn end */ + prologue_end = sal.end; /* (probably means no prologue) */ + } + else + /* We're in the boondocks: allow for + 16 pushes, an add, and "mv fp,sp". */ + prologue_end = prologue_start + 40; + + prologue_end = min (prologue_end, prev_pc); + + /* Initialize the saved register map. When register H is copied to + register L, we will put H in saved_reg[L]. */ + for (i = 0; i < 16; i++) + saved_reg[i] = i; + + /* Search the prologue looking for instructions that set up the + frame pointer, adjust the stack pointer, and save registers. + Do this until all basic prolog instructions are found. */ + + cache->framesize = 0; + for (current_pc = prologue_start; + (current_pc < prologue_end) && ((findmask & 7) != 7); + current_pc += 2) + { + unsigned short insn; + int regno; + int offset; + + insn = read_memory_unsigned_integer (current_pc, 2); + + if ((insn & 0xfe00) == 0xb400) /* push { rlist } */ + { + int mask; + findmask |= 1; /* push found */ + /* Bits 0-7 contain a mask for registers R0-R7. Bit 8 says + whether to save LR (R14). */ + mask = (insn & 0xff) | ((insn & 0x100) << 6); + + /* Calculate offsets of saved R0-R7 and LR. */ + for (regno = ARM_LR_REGNUM; regno >= 0; regno--) + if (mask & (1 << regno)) + { + cache->framesize += 4; + cache->saved_regs[saved_reg[regno]].addr = -cache->framesize; + /* Reset saved register map. */ + saved_reg[regno] = regno; + } + } + else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR + sub sp, #simm */ + { + if ((findmask & 1) == 0) /* before push? */ + continue; + else + findmask |= 4; /* add/sub sp found */ + + offset = (insn & 0x7f) << 2; /* get scaled offset */ + if (insn & 0x80) /* is it signed? (==subtracting) */ + { + cache->frameoffset += offset; + offset = -offset; + } + cache->framesize -= offset; + } + else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */ + { + findmask |= 2; /* setting of r7 found */ + cache->framereg = THUMB_FP_REGNUM; + /* get scaled offset */ + cache->frameoffset = (insn & 0xff) << 2; + } + else if (insn == 0x466f) /* mov r7, sp */ + { + findmask |= 2; /* setting of r7 found */ + cache->framereg = THUMB_FP_REGNUM; + cache->frameoffset = 0; + saved_reg[THUMB_FP_REGNUM] = ARM_SP_REGNUM; + } + else if ((insn & 0xffc0) == 0x4640) /* mov r0-r7, r8-r15 */ + { + int lo_reg = insn & 7; /* dest. register (r0-r7) */ + int hi_reg = ((insn >> 3) & 7) + 8; /* source register (r8-15) */ + saved_reg[lo_reg] = hi_reg; /* remember hi reg was saved */ + } + else + /* Something in the prolog that we don't care about or some + instruction from outside the prolog scheduled here for + optimization. */ + continue; + } +} + +/* This function decodes an ARM function prologue to determine: + 1) the size of the stack frame + 2) which registers are saved on it + 3) the offsets of saved regs + 4) the offset from the stack pointer to the frame pointer + This information is stored in the "extra" fields of the frame_info. + + There are two basic forms for the ARM prologue. The fixed argument + function call will look like: + + mov ip, sp + stmfd sp!, {fp, ip, lr, pc} + sub fp, ip, #4 + [sub sp, sp, #4] + + Which would create this stack frame (offsets relative to FP): + IP -> 4 (caller's stack) + FP -> 0 PC (points to address of stmfd instruction + 8 in callee) + -4 LR (return address in caller) + -8 IP (copy of caller's SP) + -12 FP (caller's FP) + SP -> -28 Local variables + + The frame size would thus be 32 bytes, and the frame offset would be + 28 bytes. The stmfd call can also save any of the vN registers it + plans to use, which increases the frame size accordingly. + + Note: The stored PC is 8 off of the STMFD instruction that stored it + because the ARM Store instructions always store PC + 8 when you read + the PC register. + + A variable argument function call will look like: + + mov ip, sp + stmfd sp!, {a1, a2, a3, a4} + stmfd sp!, {fp, ip, lr, pc} + sub fp, ip, #20 + + Which would create this stack frame (offsets relative to FP): + IP -> 20 (caller's stack) + 16 A4 + 12 A3 + 8 A2 + 4 A1 + FP -> 0 PC (points to address of stmfd instruction + 8 in callee) + -4 LR (return address in caller) + -8 IP (copy of caller's SP) + -12 FP (caller's FP) + SP -> -28 Local variables + + The frame size would thus be 48 bytes, and the frame offset would be + 28 bytes. + + There is another potential complication, which is that the optimizer + will try to separate the store of fp in the "stmfd" instruction from + the "sub fp, ip, #NN" instruction. Almost anything can be there, so + we just key on the stmfd, and then scan for the "sub fp, ip, #NN"... + + Also, note, the original version of the ARM toolchain claimed that there + should be an + + instruction at the end of the prologue. I have never seen GCC produce + this, and the ARM docs don't mention it. We still test for it below in + case it happens... + + */ + +static void +arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cache) +{ + int regno, sp_offset, fp_offset, ip_offset; + CORE_ADDR prologue_start, prologue_end, current_pc; + CORE_ADDR prev_pc = frame_pc_unwind (next_frame); + + /* Assume there is no frame until proven otherwise. */ + cache->framereg = ARM_SP_REGNUM; + cache->framesize = 0; + cache->frameoffset = 0; + + /* Check for Thumb prologue. */ + if (arm_pc_is_thumb (prev_pc)) + { + thumb_scan_prologue (prev_pc, cache); + return; + } + + /* Find the function prologue. If we can't find the function in + the symbol table, peek in the stack frame to find the PC. */ + if (find_pc_partial_function (prev_pc, NULL, &prologue_start, &prologue_end)) + { + /* One way to find the end of the prologue (which works well + for unoptimized code) is to do the following: + + struct symtab_and_line sal = find_pc_line (prologue_start, 0); + + if (sal.line == 0) + prologue_end = prev_pc; + else if (sal.end < prologue_end) + prologue_end = sal.end; + + This mechanism is very accurate so long as the optimizer + doesn't move any instructions from the function body into the + prologue. If this happens, sal.end will be the last + instruction in the first hunk of prologue code just before + the first instruction that the scheduler has moved from + the body to the prologue. + + In order to make sure that we scan all of the prologue + instructions, we use a slightly less accurate mechanism which + may scan more than necessary. To help compensate for this + lack of accuracy, the prologue scanning loop below contains + several clauses which'll cause the loop to terminate early if + an implausible prologue instruction is encountered. + + The expression + + prologue_start + 64 + + is a suitable endpoint since it accounts for the largest + possible prologue plus up to five instructions inserted by + the scheduler. */ + + if (prologue_end > prologue_start + 64) + { + prologue_end = prologue_start + 64; /* See above. */ + } + } + else + { + /* We have no symbol information. Our only option is to assume this + function has a standard stack frame and the normal frame register. + Then, we can find the value of our frame pointer on entrance to + the callee (or at the present moment if this is the innermost frame). + The value stored there should be the address of the stmfd + 8. */ + CORE_ADDR frame_loc; + LONGEST return_value; + + frame_loc = frame_unwind_register_unsigned (next_frame, ARM_FP_REGNUM); + if (!safe_read_memory_integer (frame_loc, 4, &return_value)) + return; + else + { + prologue_start = ADDR_BITS_REMOVE (return_value) - 8; + prologue_end = prologue_start + 64; /* See above. */ + } + } + + if (prev_pc < prologue_end) + prologue_end = prev_pc; + + /* Now search the prologue looking for instructions that set up the + frame pointer, adjust the stack pointer, and save registers. + + Be careful, however, and if it doesn't look like a prologue, + don't try to scan it. If, for instance, a frameless function + begins with stmfd sp!, then we will tell ourselves there is + a frame, which will confuse stack traceback, as well as "finish" + and other operations that rely on a knowledge of the stack + traceback. + + In the APCS, the prologue should start with "mov ip, sp" so + if we don't see this as the first insn, we will stop. + + [Note: This doesn't seem to be true any longer, so it's now an + optional part of the prologue. - Kevin Buettner, 2001-11-20] + + [Note further: The "mov ip,sp" only seems to be missing in + frameless functions at optimization level "-O2" or above, + in which case it is often (but not always) replaced by + "str lr, [sp, #-4]!". - Michael Snyder, 2002-04-23] */ + + sp_offset = fp_offset = ip_offset = 0; + + for (current_pc = prologue_start; + current_pc < prologue_end; + current_pc += 4) + { + unsigned int insn = read_memory_unsigned_integer (current_pc, 4); + + if (insn == 0xe1a0c00d) /* mov ip, sp */ + { + ip_offset = 0; + continue; + } + else if ((insn & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */ + { + unsigned imm = insn & 0xff; /* immediate value */ + unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */ + imm = (imm >> rot) | (imm << (32 - rot)); + ip_offset = imm; + continue; + } + else if ((insn & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */ + { + unsigned imm = insn & 0xff; /* immediate value */ + unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */ + imm = (imm >> rot) | (imm << (32 - rot)); + ip_offset = -imm; + continue; + } + else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */ + { + sp_offset -= 4; + cache->saved_regs[ARM_LR_REGNUM].addr = sp_offset; + continue; + } + else if ((insn & 0xffff0000) == 0xe92d0000) + /* stmfd sp!, {..., fp, ip, lr, pc} + or + stmfd sp!, {a1, a2, a3, a4} */ + { + int mask = insn & 0xffff; + + /* Calculate offsets of saved registers. */ + for (regno = ARM_PC_REGNUM; regno >= 0; regno--) + if (mask & (1 << regno)) + { + sp_offset -= 4; + cache->saved_regs[regno].addr = sp_offset; + } + } + else if ((insn & 0xffffc000) == 0xe54b0000 || /* strb rx,[r11,#-n] */ + (insn & 0xffffc0f0) == 0xe14b00b0 || /* strh rx,[r11,#-n] */ + (insn & 0xffffc000) == 0xe50b0000) /* str rx,[r11,#-n] */ + { + /* No need to add this to saved_regs -- it's just an arg reg. */ + continue; + } + else if ((insn & 0xffffc000) == 0xe5cd0000 || /* strb rx,[sp,#n] */ + (insn & 0xffffc0f0) == 0xe1cd00b0 || /* strh rx,[sp,#n] */ + (insn & 0xffffc000) == 0xe58d0000) /* str rx,[sp,#n] */ + { + /* No need to add this to saved_regs -- it's just an arg reg. */ + continue; + } + else if ((insn & 0xfffff000) == 0xe24cb000) /* sub fp, ip #n */ + { + unsigned imm = insn & 0xff; /* immediate value */ + unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */ + imm = (imm >> rot) | (imm << (32 - rot)); + fp_offset = -imm + ip_offset; + cache->framereg = ARM_FP_REGNUM; + } + else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */ + { + unsigned imm = insn & 0xff; /* immediate value */ + unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */ + imm = (imm >> rot) | (imm << (32 - rot)); + sp_offset -= imm; + } + else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */ + { + sp_offset -= 12; + regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07); + cache->saved_regs[regno].addr = sp_offset; + } + else if ((insn & 0xffbf0fff) == 0xec2d0200) /* sfmfd f0, 4, [sp!] */ + { + int n_saved_fp_regs; + unsigned int fp_start_reg, fp_bound_reg; + + if ((insn & 0x800) == 0x800) /* N0 is set */ + { + if ((insn & 0x40000) == 0x40000) /* N1 is set */ + n_saved_fp_regs = 3; + else + n_saved_fp_regs = 1; + } + else + { + if ((insn & 0x40000) == 0x40000) /* N1 is set */ + n_saved_fp_regs = 2; + else + n_saved_fp_regs = 4; + } + + fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7); + fp_bound_reg = fp_start_reg + n_saved_fp_regs; + for (; fp_start_reg < fp_bound_reg; fp_start_reg++) + { + sp_offset -= 12; + cache->saved_regs[fp_start_reg++].addr = sp_offset; + } + } + else if ((insn & 0xf0000000) != 0xe0000000) + break; /* Condition not true, exit early */ + else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ + break; /* Don't scan past a block load */ + else + /* The optimizer might shove anything into the prologue, + so we just skip what we don't recognize. */ + continue; + } + + /* The frame size is just the negative of the offset (from the + original SP) of the last thing thing we pushed on the stack. + The frame offset is [new FP] - [new SP]. */ + cache->framesize = -sp_offset; + if (cache->framereg == ARM_FP_REGNUM) + cache->frameoffset = fp_offset - sp_offset; + else + cache->frameoffset = 0; +} + +static struct arm_prologue_cache * +arm_make_prologue_cache (struct frame_info *next_frame) +{ + int reg; + struct arm_prologue_cache *cache; + CORE_ADDR unwound_fp; + + cache = frame_obstack_zalloc (sizeof (struct arm_prologue_cache)); + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + arm_scan_prologue (next_frame, cache); + + unwound_fp = frame_unwind_register_unsigned (next_frame, cache->framereg); + if (unwound_fp == 0) + return cache; + + cache->prev_sp = unwound_fp + cache->framesize - cache->frameoffset; + + /* Calculate actual addresses of saved registers using offsets + determined by arm_scan_prologue. */ + for (reg = 0; reg < NUM_REGS; reg++) + if (trad_frame_addr_p (cache->saved_regs, reg)) + cache->saved_regs[reg].addr += cache->prev_sp; + + return cache; +} + +/* Our frame ID for a normal frame is the current function's starting PC + and the caller's SP when we were called. */ + +static void +arm_prologue_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct arm_prologue_cache *cache; + struct frame_id id; + CORE_ADDR func; + + if (*this_cache == NULL) + *this_cache = arm_make_prologue_cache (next_frame); + cache = *this_cache; + + func = frame_func_unwind (next_frame); + + /* This is meant to halt the backtrace at "_start". Make sure we + don't halt it at a generic dummy frame. */ + if (func <= LOWEST_PC) + return; + + /* If we've hit a wall, stop. */ + if (cache->prev_sp == 0) + return; + + id = frame_id_build (cache->prev_sp, func); + + /* Check that we're not going round in circles with the same frame + ID (but avoid applying the test to sentinel frames which do go + round in circles). */ + if (frame_relative_level (next_frame) >= 0 + && get_frame_type (next_frame) == NORMAL_FRAME + && frame_id_eq (get_frame_id (next_frame), id)) + return; + + *this_id = id; +} + +static void +arm_prologue_prev_register (struct frame_info *next_frame, + void **this_cache, + int prev_regnum, + int *optimized, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, + void *valuep) +{ + struct arm_prologue_cache *cache; + + if (*this_cache == NULL) + *this_cache = arm_make_prologue_cache (next_frame); + cache = *this_cache; + + /* If we are asked to unwind the PC, then we need to return the LR + instead. The saved value of PC points into this frame's + prologue, not the next frame's resume location. */ + if (prev_regnum == ARM_PC_REGNUM) + prev_regnum = ARM_LR_REGNUM; + + /* SP is generally not saved to the stack, but this frame is + identified by NEXT_FRAME's stack pointer at the time of the call. + The value was already reconstructed into PREV_SP. */ + if (prev_regnum == ARM_SP_REGNUM) + { + *lvalp = not_lval; + if (valuep) + store_unsigned_integer (valuep, 4, cache->prev_sp); + return; + } + + trad_frame_prev_register (next_frame, cache->saved_regs, prev_regnum, + optimized, lvalp, addrp, realnump, valuep); +} + +struct frame_unwind arm_prologue_unwind = { + NORMAL_FRAME, + arm_prologue_this_id, + arm_prologue_prev_register +}; + +static const struct frame_unwind * +arm_prologue_unwind_sniffer (struct frame_info *next_frame) +{ + return &arm_prologue_unwind; +} + +static CORE_ADDR +arm_normal_frame_base (struct frame_info *next_frame, void **this_cache) +{ + struct arm_prologue_cache *cache; + + if (*this_cache == NULL) + *this_cache = arm_make_prologue_cache (next_frame); + cache = *this_cache; + + return cache->prev_sp + cache->frameoffset - cache->framesize; +} + +struct frame_base arm_normal_base = { + &arm_prologue_unwind, + arm_normal_frame_base, + arm_normal_frame_base, + arm_normal_frame_base +}; + +static struct arm_prologue_cache * +arm_make_sigtramp_cache (struct frame_info *next_frame) +{ + struct arm_prologue_cache *cache; + int reg; + + cache = frame_obstack_zalloc (sizeof (struct arm_prologue_cache)); + + cache->prev_sp = frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM); + + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + for (reg = 0; reg < NUM_REGS; reg++) + cache->saved_regs[reg].addr + = SIGCONTEXT_REGISTER_ADDRESS (cache->prev_sp, + frame_pc_unwind (next_frame), reg); + + /* FIXME: What about thumb mode? */ + cache->framereg = ARM_SP_REGNUM; + cache->prev_sp + = read_memory_integer (cache->saved_regs[cache->framereg].addr, + register_size (current_gdbarch, cache->framereg)); + + return cache; +} + +static void +arm_sigtramp_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct arm_prologue_cache *cache; + + if (*this_cache == NULL) + *this_cache = arm_make_sigtramp_cache (next_frame); + cache = *this_cache; + + /* FIXME drow/2003-07-07: This isn't right if we single-step within + the sigtramp frame; the PC should be the beginning of the trampoline. */ + *this_id = frame_id_build (cache->prev_sp, frame_pc_unwind (next_frame)); +} + +static void +arm_sigtramp_prev_register (struct frame_info *next_frame, + void **this_cache, + int prev_regnum, + int *optimized, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, + void *valuep) +{ + struct arm_prologue_cache *cache; + + if (*this_cache == NULL) + *this_cache = arm_make_sigtramp_cache (next_frame); + cache = *this_cache; + + trad_frame_prev_register (next_frame, cache->saved_regs, prev_regnum, + optimized, lvalp, addrp, realnump, valuep); +} + +struct frame_unwind arm_sigtramp_unwind = { + SIGTRAMP_FRAME, + arm_sigtramp_this_id, + arm_sigtramp_prev_register +}; + +static const struct frame_unwind * +arm_sigtramp_unwind_sniffer (struct frame_info *next_frame) +{ + /* Note: If an ARM PC_IN_SIGTRAMP method ever needs to compare + against the name of the function, the code below will have to be + changed to first fetch the name of the function and then pass + this name to PC_IN_SIGTRAMP. */ + + if (SIGCONTEXT_REGISTER_ADDRESS_P () + && PC_IN_SIGTRAMP (frame_pc_unwind (next_frame), (char *) 0)) + return &arm_sigtramp_unwind; + + return NULL; +} + +/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that + dummy frame. The frame ID's base needs to match the TOS value + saved by save_dummy_frame_tos() and returned from + arm_push_dummy_call, and the PC needs to match the dummy frame's + breakpoint. */ + +static struct frame_id +arm_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + return frame_id_build (frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM), + frame_pc_unwind (next_frame)); +} + +/* Given THIS_FRAME, find the previous frame's resume PC (which will + be used to construct the previous frame's ID, after looking up the + containing function). */ + +static CORE_ADDR +arm_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame) +{ + CORE_ADDR pc; + pc = frame_unwind_register_unsigned (this_frame, ARM_PC_REGNUM); + return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc; +} + +static CORE_ADDR +arm_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame) +{ + return frame_unwind_register_unsigned (this_frame, ARM_SP_REGNUM); +} + +/* DEPRECATED_CALL_DUMMY_WORDS: + This sequence of words is the instructions + + mov lr,pc + mov pc,r4 + illegal + + Note this is 12 bytes. */ + +static LONGEST arm_call_dummy_words[] = +{ + 0xe1a0e00f, 0xe1a0f004, 0xe7ffdefe +}; + +/* When arguments must be pushed onto the stack, they go on in reverse + order. The code below implements a FILO (stack) to do this. */ + +struct stack_item +{ + int len; + struct stack_item *prev; + void *data; +}; + +static struct stack_item * +push_stack_item (struct stack_item *prev, void *contents, int len) +{ + struct stack_item *si; + si = xmalloc (sizeof (struct stack_item)); + si->data = xmalloc (len); + si->len = len; + si->prev = prev; + memcpy (si->data, contents, len); + return si; +} + +static struct stack_item * +pop_stack_item (struct stack_item *si) +{ + struct stack_item *dead = si; + si = si->prev; + xfree (dead->data); + xfree (dead); + return si; +} + +/* We currently only support passing parameters in integer registers. This + conforms with GCC's default model. Several other variants exist and + we should probably support some of them based on the selected ABI. */ + +static CORE_ADDR +arm_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr) +{ + int argnum; + int argreg; + int nstack; + struct stack_item *si = NULL; + + /* Set the return address. For the ARM, the return breakpoint is + always at BP_ADDR. */ + /* XXX Fix for Thumb. */ + regcache_cooked_write_unsigned (regcache, ARM_LR_REGNUM, bp_addr); + + /* Walk through the list of args and determine how large a temporary + stack is required. Need to take care here as structs may be + passed on the stack, and we have to to push them. */ + nstack = 0; + + argreg = ARM_A1_REGNUM; + nstack = 0; + + /* Some platforms require a double-word aligned stack. Make sure sp + is correctly aligned before we start. We always do this even if + it isn't really needed -- it can never hurt things. */ + sp &= ~(CORE_ADDR)(2 * DEPRECATED_REGISTER_SIZE - 1); + + /* The struct_return pointer occupies the first parameter + passing register. */ + if (struct_return) + { + if (arm_debug) + fprintf_unfiltered (gdb_stdlog, "struct return in %s = 0x%s\n", + REGISTER_NAME (argreg), paddr (struct_addr)); + regcache_cooked_write_unsigned (regcache, argreg, struct_addr); + argreg++; + } + + for (argnum = 0; argnum < nargs; argnum++) + { + int len; + struct type *arg_type; + struct type *target_type; + enum type_code typecode; + char *val; + + arg_type = check_typedef (VALUE_TYPE (args[argnum])); + len = TYPE_LENGTH (arg_type); + target_type = TYPE_TARGET_TYPE (arg_type); + typecode = TYPE_CODE (arg_type); + val = VALUE_CONTENTS (args[argnum]); + + /* If the argument is a pointer to a function, and it is a + Thumb function, create a LOCAL copy of the value and set + the THUMB bit in it. */ + if (TYPE_CODE_PTR == typecode + && target_type != NULL + && TYPE_CODE_FUNC == TYPE_CODE (target_type)) + { + CORE_ADDR regval = extract_unsigned_integer (val, len); + if (arm_pc_is_thumb (regval)) + { + val = alloca (len); + store_unsigned_integer (val, len, MAKE_THUMB_ADDR (regval)); + } + } + + /* Copy the argument to general registers or the stack in + register-sized pieces. Large arguments are split between + registers and stack. */ + while (len > 0) + { + int partial_len = len < DEPRECATED_REGISTER_SIZE ? len : DEPRECATED_REGISTER_SIZE; + + if (argreg <= ARM_LAST_ARG_REGNUM) + { + /* The argument is being passed in a general purpose + register. */ + CORE_ADDR regval = extract_unsigned_integer (val, partial_len); + if (arm_debug) + fprintf_unfiltered (gdb_stdlog, "arg %d in %s = 0x%s\n", + argnum, REGISTER_NAME (argreg), + phex (regval, DEPRECATED_REGISTER_SIZE)); + regcache_cooked_write_unsigned (regcache, argreg, regval); + argreg++; + } + else + { + /* Push the arguments onto the stack. */ + if (arm_debug) + fprintf_unfiltered (gdb_stdlog, "arg %d @ sp + %d\n", + argnum, nstack); + si = push_stack_item (si, val, DEPRECATED_REGISTER_SIZE); + nstack += DEPRECATED_REGISTER_SIZE; + } + + len -= partial_len; + val += partial_len; + } + } + /* If we have an odd number of words to push, then decrement the stack + by one word now, so first stack argument will be dword aligned. */ + if (nstack & 4) + sp -= 4; + + while (si) + { + sp -= si->len; + write_memory (sp, si->data, si->len); + si = pop_stack_item (si); + } + + /* Finally, update teh SP register. */ + regcache_cooked_write_unsigned (regcache, ARM_SP_REGNUM, sp); + + return sp; +} + +static void +print_fpu_flags (int flags) +{ + if (flags & (1 << 0)) + fputs ("IVO ", stdout); + if (flags & (1 << 1)) + fputs ("DVZ ", stdout); + if (flags & (1 << 2)) + fputs ("OFL ", stdout); + if (flags & (1 << 3)) + fputs ("UFL ", stdout); + if (flags & (1 << 4)) + fputs ("INX ", stdout); + putchar ('\n'); +} + +/* Print interesting information about the floating point processor + (if present) or emulator. */ +static void +arm_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) +{ + unsigned long status = read_register (ARM_FPS_REGNUM); + int type; + + type = (status >> 24) & 127; + printf ("%s FPU type %d\n", + (status & (1 << 31)) ? "Hardware" : "Software", + type); + fputs ("mask: ", stdout); + print_fpu_flags (status >> 16); + fputs ("flags: ", stdout); + print_fpu_flags (status); +} + +/* Return the GDB type object for the "standard" data type of data in + register N. */ + +static struct type * +arm_register_type (struct gdbarch *gdbarch, int regnum) +{ + if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS) + { + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + return builtin_type_arm_ext_big; + else + return builtin_type_arm_ext_littlebyte_bigword; + } + else + return builtin_type_int32; +} + +/* Index within `registers' of the first byte of the space for + register N. */ + +static int +arm_register_byte (int regnum) +{ + if (regnum < ARM_F0_REGNUM) + return regnum * INT_REGISTER_SIZE; + else if (regnum < ARM_PS_REGNUM) + return (NUM_GREGS * INT_REGISTER_SIZE + + (regnum - ARM_F0_REGNUM) * FP_REGISTER_SIZE); + else + return (NUM_GREGS * INT_REGISTER_SIZE + + NUM_FREGS * FP_REGISTER_SIZE + + (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE); +} + +/* Map GDB internal REGNUM onto the Arm simulator register numbers. */ +static int +arm_register_sim_regno (int regnum) +{ + int reg = regnum; + gdb_assert (reg >= 0 && reg < NUM_REGS); + + if (reg < NUM_GREGS) + return SIM_ARM_R0_REGNUM + reg; + reg -= NUM_GREGS; + + if (reg < NUM_FREGS) + return SIM_ARM_FP0_REGNUM + reg; + reg -= NUM_FREGS; + + if (reg < NUM_SREGS) + return SIM_ARM_FPS_REGNUM + reg; + reg -= NUM_SREGS; + + internal_error (__FILE__, __LINE__, "Bad REGNUM %d", regnum); +} + +/* NOTE: cagney/2001-08-20: Both convert_from_extended() and + convert_to_extended() use floatformat_arm_ext_littlebyte_bigword. + It is thought that this is is the floating-point register format on + little-endian systems. */ + +static void +convert_from_extended (const struct floatformat *fmt, const void *ptr, + void *dbl) +{ + DOUBLEST d; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + floatformat_to_doublest (&floatformat_arm_ext_big, ptr, &d); + else + floatformat_to_doublest (&floatformat_arm_ext_littlebyte_bigword, + ptr, &d); + floatformat_from_doublest (fmt, &d, dbl); +} + +static void +convert_to_extended (const struct floatformat *fmt, void *dbl, const void *ptr) +{ + DOUBLEST d; + floatformat_to_doublest (fmt, ptr, &d); + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + floatformat_from_doublest (&floatformat_arm_ext_big, &d, dbl); + else + floatformat_from_doublest (&floatformat_arm_ext_littlebyte_bigword, + &d, dbl); +} + +static int +condition_true (unsigned long cond, unsigned long status_reg) +{ + if (cond == INST_AL || cond == INST_NV) + return 1; + + switch (cond) + { + case INST_EQ: + return ((status_reg & FLAG_Z) != 0); + case INST_NE: + return ((status_reg & FLAG_Z) == 0); + case INST_CS: + return ((status_reg & FLAG_C) != 0); + case INST_CC: + return ((status_reg & FLAG_C) == 0); + case INST_MI: + return ((status_reg & FLAG_N) != 0); + case INST_PL: + return ((status_reg & FLAG_N) == 0); + case INST_VS: + return ((status_reg & FLAG_V) != 0); + case INST_VC: + return ((status_reg & FLAG_V) == 0); + case INST_HI: + return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C); + case INST_LS: + return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C); + case INST_GE: + return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)); + case INST_LT: + return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)); + case INST_GT: + return (((status_reg & FLAG_Z) == 0) && + (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0))); + case INST_LE: + return (((status_reg & FLAG_Z) != 0) || + (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0))); + } + return 1; +} + +/* Support routines for single stepping. Calculate the next PC value. */ +#define submask(x) ((1L << ((x) + 1)) - 1) +#define bit(obj,st) (((obj) >> (st)) & 1) +#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) +#define sbits(obj,st,fn) \ + ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st)))) +#define BranchDest(addr,instr) \ + ((CORE_ADDR) (((long) (addr)) + 8 + (sbits (instr, 0, 23) << 2))) +#define ARM_PC_32 1 + +static unsigned long +shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val, + unsigned long status_reg) +{ + unsigned long res, shift; + int rm = bits (inst, 0, 3); + unsigned long shifttype = bits (inst, 5, 6); + + if (bit (inst, 4)) + { + int rs = bits (inst, 8, 11); + shift = (rs == 15 ? pc_val + 8 : read_register (rs)) & 0xFF; + } + else + shift = bits (inst, 7, 11); + + res = (rm == 15 + ? ((pc_val | (ARM_PC_32 ? 0 : status_reg)) + + (bit (inst, 4) ? 12 : 8)) + : read_register (rm)); + + switch (shifttype) + { + case 0: /* LSL */ + res = shift >= 32 ? 0 : res << shift; + break; + + case 1: /* LSR */ + res = shift >= 32 ? 0 : res >> shift; + break; + + case 2: /* ASR */ + if (shift >= 32) + shift = 31; + res = ((res & 0x80000000L) + ? ~((~res) >> shift) : res >> shift); + break; + + case 3: /* ROR/RRX */ + shift &= 31; + if (shift == 0) + res = (res >> 1) | (carry ? 0x80000000L : 0); + else + res = (res >> shift) | (res << (32 - shift)); + break; + } + + return res & 0xffffffff; +} + +/* Return number of 1-bits in VAL. */ + +static int +bitcount (unsigned long val) +{ + int nbits; + for (nbits = 0; val != 0; nbits++) + val &= val - 1; /* delete rightmost 1-bit in val */ + return nbits; +} + +CORE_ADDR +thumb_get_next_pc (CORE_ADDR pc) +{ + unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */ + unsigned short inst1 = read_memory_integer (pc, 2); + CORE_ADDR nextpc = pc + 2; /* default is next instruction */ + unsigned long offset; + + if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */ + { + CORE_ADDR sp; + + /* Fetch the saved PC from the stack. It's stored above + all of the other registers. */ + offset = bitcount (bits (inst1, 0, 7)) * DEPRECATED_REGISTER_SIZE; + sp = read_register (ARM_SP_REGNUM); + nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4); + nextpc = ADDR_BITS_REMOVE (nextpc); + if (nextpc == pc) + error ("Infinite loop detected"); + } + else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */ + { + unsigned long status = read_register (ARM_PS_REGNUM); + unsigned long cond = bits (inst1, 8, 11); + if (cond != 0x0f && condition_true (cond, status)) /* 0x0f = SWI */ + nextpc = pc_val + (sbits (inst1, 0, 7) << 1); + } + else if ((inst1 & 0xf800) == 0xe000) /* unconditional branch */ + { + nextpc = pc_val + (sbits (inst1, 0, 10) << 1); + } + else if ((inst1 & 0xf800) == 0xf000) /* long branch with link, and blx */ + { + unsigned short inst2 = read_memory_integer (pc + 2, 2); + offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1); + nextpc = pc_val + offset; + /* For BLX make sure to clear the low bits. */ + if (bits (inst2, 11, 12) == 1) + nextpc = nextpc & 0xfffffffc; + } + else if ((inst1 & 0xff00) == 0x4700) /* bx REG, blx REG */ + { + if (bits (inst1, 3, 6) == 0x0f) + nextpc = pc_val; + else + nextpc = read_register (bits (inst1, 3, 6)); + + nextpc = ADDR_BITS_REMOVE (nextpc); + if (nextpc == pc) + error ("Infinite loop detected"); + } + + return nextpc; +} + +CORE_ADDR +arm_get_next_pc (CORE_ADDR pc) +{ + unsigned long pc_val; + unsigned long this_instr; + unsigned long status; + CORE_ADDR nextpc; + + if (arm_pc_is_thumb (pc)) + return thumb_get_next_pc (pc); + + pc_val = (unsigned long) pc; + this_instr = read_memory_integer (pc, 4); + status = read_register (ARM_PS_REGNUM); + nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */ + + if (condition_true (bits (this_instr, 28, 31), status)) + { + switch (bits (this_instr, 24, 27)) + { + case 0x0: + case 0x1: /* data processing */ + case 0x2: + case 0x3: + { + unsigned long operand1, operand2, result = 0; + unsigned long rn; + int c; + + if (bits (this_instr, 12, 15) != 15) + break; + + if (bits (this_instr, 22, 25) == 0 + && bits (this_instr, 4, 7) == 9) /* multiply */ + error ("Illegal update to pc in instruction"); + + /* BX , BLX */ + if (bits (this_instr, 4, 28) == 0x12fff1 + || bits (this_instr, 4, 28) == 0x12fff3) + { + rn = bits (this_instr, 0, 3); + result = (rn == 15) ? pc_val + 8 : read_register (rn); + nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result); + + if (nextpc == pc) + error ("Infinite loop detected"); + + return nextpc; + } + + /* Multiply into PC */ + c = (status & FLAG_C) ? 1 : 0; + rn = bits (this_instr, 16, 19); + operand1 = (rn == 15) ? pc_val + 8 : read_register (rn); + + if (bit (this_instr, 25)) + { + unsigned long immval = bits (this_instr, 0, 7); + unsigned long rotate = 2 * bits (this_instr, 8, 11); + operand2 = ((immval >> rotate) | (immval << (32 - rotate))) + & 0xffffffff; + } + else /* operand 2 is a shifted register */ + operand2 = shifted_reg_val (this_instr, c, pc_val, status); + + switch (bits (this_instr, 21, 24)) + { + case 0x0: /*and */ + result = operand1 & operand2; + break; + + case 0x1: /*eor */ + result = operand1 ^ operand2; + break; + + case 0x2: /*sub */ + result = operand1 - operand2; + break; + + case 0x3: /*rsb */ + result = operand2 - operand1; + break; + + case 0x4: /*add */ + result = operand1 + operand2; + break; + + case 0x5: /*adc */ + result = operand1 + operand2 + c; + break; + + case 0x6: /*sbc */ + result = operand1 - operand2 + c; + break; + + case 0x7: /*rsc */ + result = operand2 - operand1 + c; + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: /* tst, teq, cmp, cmn */ + result = (unsigned long) nextpc; + break; + + case 0xc: /*orr */ + result = operand1 | operand2; + break; + + case 0xd: /*mov */ + /* Always step into a function. */ + result = operand2; + break; + + case 0xe: /*bic */ + result = operand1 & ~operand2; + break; + + case 0xf: /*mvn */ + result = ~operand2; + break; + } + nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result); + + if (nextpc == pc) + error ("Infinite loop detected"); + break; + } + + case 0x4: + case 0x5: /* data transfer */ + case 0x6: + case 0x7: + if (bit (this_instr, 20)) + { + /* load */ + if (bits (this_instr, 12, 15) == 15) + { + /* rd == pc */ + unsigned long rn; + unsigned long base; + + if (bit (this_instr, 22)) + error ("Illegal update to pc in instruction"); + + /* byte write to PC */ + rn = bits (this_instr, 16, 19); + base = (rn == 15) ? pc_val + 8 : read_register (rn); + if (bit (this_instr, 24)) + { + /* pre-indexed */ + int c = (status & FLAG_C) ? 1 : 0; + unsigned long offset = + (bit (this_instr, 25) + ? shifted_reg_val (this_instr, c, pc_val, status) + : bits (this_instr, 0, 11)); + + if (bit (this_instr, 23)) + base += offset; + else + base -= offset; + } + nextpc = (CORE_ADDR) read_memory_integer ((CORE_ADDR) base, + 4); + + nextpc = ADDR_BITS_REMOVE (nextpc); + + if (nextpc == pc) + error ("Infinite loop detected"); + } + } + break; + + case 0x8: + case 0x9: /* block transfer */ + if (bit (this_instr, 20)) + { + /* LDM */ + if (bit (this_instr, 15)) + { + /* loading pc */ + int offset = 0; + + if (bit (this_instr, 23)) + { + /* up */ + unsigned long reglist = bits (this_instr, 0, 14); + offset = bitcount (reglist) * 4; + if (bit (this_instr, 24)) /* pre */ + offset += 4; + } + else if (bit (this_instr, 24)) + offset = -4; + + { + unsigned long rn_val = + read_register (bits (this_instr, 16, 19)); + nextpc = + (CORE_ADDR) read_memory_integer ((CORE_ADDR) (rn_val + + offset), + 4); + } + nextpc = ADDR_BITS_REMOVE (nextpc); + if (nextpc == pc) + error ("Infinite loop detected"); + } + } + break; + + case 0xb: /* branch & link */ + case 0xa: /* branch */ + { + nextpc = BranchDest (pc, this_instr); + + /* BLX */ + if (bits (this_instr, 28, 31) == INST_NV) + nextpc |= bit (this_instr, 24) << 1; + + nextpc = ADDR_BITS_REMOVE (nextpc); + if (nextpc == pc) + error ("Infinite loop detected"); + break; + } + + case 0xc: + case 0xd: + case 0xe: /* coproc ops */ + case 0xf: /* SWI */ + break; + + default: + fprintf_filtered (gdb_stderr, "Bad bit-field extraction\n"); + return (pc); + } + } + + return nextpc; +} + +/* single_step() is called just before we want to resume the inferior, + if we want to single-step it but there is no hardware or kernel + single-step support. We find the target of the coming instruction + and breakpoint it. + + single_step() is also called just after the inferior stops. If we + had set up a simulated single-step, we undo our damage. */ + +static void +arm_software_single_step (enum target_signal sig, int insert_bpt) +{ + static int next_pc; /* State between setting and unsetting. */ + static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ + + if (insert_bpt) + { + next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); + target_insert_breakpoint (next_pc, break_mem); + } + else + target_remove_breakpoint (next_pc, break_mem); +} + +#include "bfd-in2.h" +#include "libcoff.h" + +static int +gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info) +{ + if (arm_pc_is_thumb (memaddr)) + { + static asymbol *asym; + static combined_entry_type ce; + static struct coff_symbol_struct csym; + static struct bfd fake_bfd; + static bfd_target fake_target; + + if (csym.native == NULL) + { + /* Create a fake symbol vector containing a Thumb symbol. + This is solely so that the code in print_insn_little_arm() + and print_insn_big_arm() in opcodes/arm-dis.c will detect + the presence of a Thumb symbol and switch to decoding + Thumb instructions. */ + + fake_target.flavour = bfd_target_coff_flavour; + fake_bfd.xvec = &fake_target; + ce.u.syment.n_sclass = C_THUMBEXTFUNC; + csym.native = &ce; + csym.symbol.the_bfd = &fake_bfd; + csym.symbol.name = "fake"; + asym = (asymbol *) & csym; + } + + memaddr = UNMAKE_THUMB_ADDR (memaddr); + info->symbols = &asym; + } + else + info->symbols = NULL; + + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + return print_insn_big_arm (memaddr, info); + else + return print_insn_little_arm (memaddr, info); +} + +/* The following define instruction sequences that will cause ARM + cpu's to take an undefined instruction trap. These are used to + signal a breakpoint to GDB. + + The newer ARMv4T cpu's are capable of operating in ARM or Thumb + modes. A different instruction is required for each mode. The ARM + cpu's can also be big or little endian. Thus four different + instructions are needed to support all cases. + + Note: ARMv4 defines several new instructions that will take the + undefined instruction trap. ARM7TDMI is nominally ARMv4T, but does + not in fact add the new instructions. The new undefined + instructions in ARMv4 are all instructions that had no defined + behaviour in earlier chips. There is no guarantee that they will + raise an exception, but may be treated as NOP's. In practice, it + may only safe to rely on instructions matching: + + 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + C C C C 0 1 1 x x x x x x x x x x x x x x x x x x x x 1 x x x x + + Even this may only true if the condition predicate is true. The + following use a condition predicate of ALWAYS so it is always TRUE. + + There are other ways of forcing a breakpoint. GNU/Linux, RISC iX, + and NetBSD all use a software interrupt rather than an undefined + instruction to force a trap. This can be handled by by the + abi-specific code during establishment of the gdbarch vector. */ + + +/* NOTE rearnsha 2002-02-18: for now we allow a non-multi-arch gdb to + override these definitions. */ +#ifndef ARM_LE_BREAKPOINT +#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} +#endif +#ifndef ARM_BE_BREAKPOINT +#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} +#endif +#ifndef THUMB_LE_BREAKPOINT +#define THUMB_LE_BREAKPOINT {0xfe,0xdf} +#endif +#ifndef THUMB_BE_BREAKPOINT +#define THUMB_BE_BREAKPOINT {0xdf,0xfe} +#endif + +static const char arm_default_arm_le_breakpoint[] = ARM_LE_BREAKPOINT; +static const char arm_default_arm_be_breakpoint[] = ARM_BE_BREAKPOINT; +static const char arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT; +static const char arm_default_thumb_be_breakpoint[] = THUMB_BE_BREAKPOINT; + +/* Determine the type and size of breakpoint to insert at PCPTR. Uses + the program counter value to determine whether a 16-bit or 32-bit + breakpoint should be used. It returns a pointer to a string of + bytes that encode a breakpoint instruction, stores the length of + the string to *lenptr, and adjusts the program counter (if + necessary) to point to the actual memory location where the + breakpoint should be inserted. */ + +/* XXX ??? from old tm-arm.h: if we're using RDP, then we're inserting + breakpoints and storing their handles instread of what was in + memory. It is nice that this is the same size as a handle - + otherwise remote-rdp will have to change. */ + +static const unsigned char * +arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr)) + { + *pcptr = UNMAKE_THUMB_ADDR (*pcptr); + *lenptr = tdep->thumb_breakpoint_size; + return tdep->thumb_breakpoint; + } + else + { + *lenptr = tdep->arm_breakpoint_size; + return tdep->arm_breakpoint; + } +} + +/* Extract from an array REGBUF containing the (raw) register state a + function return value of type TYPE, and copy that, in virtual + format, into VALBUF. */ + +static void +arm_extract_return_value (struct type *type, + struct regcache *regs, + void *dst) +{ + bfd_byte *valbuf = dst; + + if (TYPE_CODE_FLT == TYPE_CODE (type)) + { + switch (arm_get_fp_model (current_gdbarch)) + { + case ARM_FLOAT_FPA: + { + /* The value is in register F0 in internal format. We need to + extract the raw value and then convert it to the desired + internal type. */ + bfd_byte tmpbuf[FP_REGISTER_SIZE]; + + regcache_cooked_read (regs, ARM_F0_REGNUM, tmpbuf); + convert_from_extended (floatformat_from_type (type), tmpbuf, + valbuf); + } + break; + + case ARM_FLOAT_SOFT_FPA: + case ARM_FLOAT_SOFT_VFP: + regcache_cooked_read (regs, ARM_A1_REGNUM, valbuf); + if (TYPE_LENGTH (type) > 4) + regcache_cooked_read (regs, ARM_A1_REGNUM + 1, + valbuf + INT_REGISTER_SIZE); + break; + + default: + internal_error + (__FILE__, __LINE__, + "arm_extract_return_value: Floating point model not supported"); + break; + } + } + else if (TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_CHAR + || TYPE_CODE (type) == TYPE_CODE_BOOL + || TYPE_CODE (type) == TYPE_CODE_PTR + || TYPE_CODE (type) == TYPE_CODE_REF + || TYPE_CODE (type) == TYPE_CODE_ENUM) + { + /* If the the type is a plain integer, then the access is + straight-forward. Otherwise we have to play around a bit more. */ + int len = TYPE_LENGTH (type); + int regno = ARM_A1_REGNUM; + ULONGEST tmp; + + while (len > 0) + { + /* By using store_unsigned_integer we avoid having to do + anything special for small big-endian values. */ + regcache_cooked_read_unsigned (regs, regno++, &tmp); + store_unsigned_integer (valbuf, + (len > INT_REGISTER_SIZE + ? INT_REGISTER_SIZE : len), + tmp); + len -= INT_REGISTER_SIZE; + valbuf += INT_REGISTER_SIZE; + } + } + else + { + /* For a structure or union the behaviour is as if the value had + been stored to word-aligned memory and then loaded into + registers with 32-bit load instruction(s). */ + int len = TYPE_LENGTH (type); + int regno = ARM_A1_REGNUM; + bfd_byte tmpbuf[INT_REGISTER_SIZE]; + + while (len > 0) + { + regcache_cooked_read (regs, regno++, tmpbuf); + memcpy (valbuf, tmpbuf, + len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len); + len -= INT_REGISTER_SIZE; + valbuf += INT_REGISTER_SIZE; + } + } +} + +/* Extract from an array REGBUF containing the (raw) register state + the address in which a function should return its structure value. */ + +static CORE_ADDR +arm_extract_struct_value_address (struct regcache *regcache) +{ + ULONGEST ret; + + regcache_cooked_read_unsigned (regcache, ARM_A1_REGNUM, &ret); + return ret; +} + +/* Will a function return an aggregate type in memory or in a + register? Return 0 if an aggregate type can be returned in a + register, 1 if it must be returned in memory. */ + +static int +arm_use_struct_convention (int gcc_p, struct type *type) +{ + int nRc; + enum type_code code; + + CHECK_TYPEDEF (type); + + /* In the ARM ABI, "integer" like aggregate types are returned in + registers. For an aggregate type to be integer like, its size + must be less than or equal to DEPRECATED_REGISTER_SIZE and the + offset of each addressable subfield must be zero. Note that bit + fields are not addressable, and all addressable subfields of + unions always start at offset zero. + + This function is based on the behaviour of GCC 2.95.1. + See: gcc/arm.c: arm_return_in_memory() for details. + + Note: All versions of GCC before GCC 2.95.2 do not set up the + parameters correctly for a function returning the following + structure: struct { float f;}; This should be returned in memory, + not a register. Richard Earnshaw sent me a patch, but I do not + know of any way to detect if a function like the above has been + compiled with the correct calling convention. */ + + /* All aggregate types that won't fit in a register must be returned + in memory. */ + if (TYPE_LENGTH (type) > DEPRECATED_REGISTER_SIZE) + { + return 1; + } + + /* The only aggregate types that can be returned in a register are + structs and unions. Arrays must be returned in memory. */ + code = TYPE_CODE (type); + if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code)) + { + return 1; + } + + /* Assume all other aggregate types can be returned in a register. + Run a check for structures, unions and arrays. */ + nRc = 0; + + if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code)) + { + int i; + /* Need to check if this struct/union is "integer" like. For + this to be true, its size must be less than or equal to + DEPRECATED_REGISTER_SIZE and the offset of each addressable + subfield must be zero. Note that bit fields are not + addressable, and unions always start at offset zero. If any + of the subfields is a floating point type, the struct/union + cannot be an integer type. */ + + /* For each field in the object, check: + 1) Is it FP? --> yes, nRc = 1; + 2) Is it addressable (bitpos != 0) and + not packed (bitsize == 0)? + --> yes, nRc = 1 + */ + + for (i = 0; i < TYPE_NFIELDS (type); i++) + { + enum type_code field_type_code; + field_type_code = TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, i))); + + /* Is it a floating point type field? */ + if (field_type_code == TYPE_CODE_FLT) + { + nRc = 1; + break; + } + + /* If bitpos != 0, then we have to care about it. */ + if (TYPE_FIELD_BITPOS (type, i) != 0) + { + /* Bitfields are not addressable. If the field bitsize is + zero, then the field is not packed. Hence it cannot be + a bitfield or any other packed type. */ + if (TYPE_FIELD_BITSIZE (type, i) == 0) + { + nRc = 1; + break; + } + } + } + } + + return nRc; +} + +/* Write into appropriate registers a function return value of type + TYPE, given in virtual format. */ + +static void +arm_store_return_value (struct type *type, struct regcache *regs, + const void *src) +{ + const bfd_byte *valbuf = src; + + if (TYPE_CODE (type) == TYPE_CODE_FLT) + { + char buf[MAX_REGISTER_SIZE]; + + switch (arm_get_fp_model (current_gdbarch)) + { + case ARM_FLOAT_FPA: + + convert_to_extended (floatformat_from_type (type), buf, valbuf); + regcache_cooked_write (regs, ARM_F0_REGNUM, buf); + break; + + case ARM_FLOAT_SOFT_FPA: + case ARM_FLOAT_SOFT_VFP: + regcache_cooked_write (regs, ARM_A1_REGNUM, valbuf); + if (TYPE_LENGTH (type) > 4) + regcache_cooked_write (regs, ARM_A1_REGNUM + 1, + valbuf + INT_REGISTER_SIZE); + break; + + default: + internal_error + (__FILE__, __LINE__, + "arm_store_return_value: Floating point model not supported"); + break; + } + } + else if (TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_CHAR + || TYPE_CODE (type) == TYPE_CODE_BOOL + || TYPE_CODE (type) == TYPE_CODE_PTR + || TYPE_CODE (type) == TYPE_CODE_REF + || TYPE_CODE (type) == TYPE_CODE_ENUM) + { + if (TYPE_LENGTH (type) <= 4) + { + /* Values of one word or less are zero/sign-extended and + returned in r0. */ + bfd_byte tmpbuf[INT_REGISTER_SIZE]; + LONGEST val = unpack_long (type, valbuf); + + store_signed_integer (tmpbuf, INT_REGISTER_SIZE, val); + regcache_cooked_write (regs, ARM_A1_REGNUM, tmpbuf); + } + else + { + /* Integral values greater than one word are stored in consecutive + registers starting with r0. This will always be a multiple of + the regiser size. */ + int len = TYPE_LENGTH (type); + int regno = ARM_A1_REGNUM; + + while (len > 0) + { + regcache_cooked_write (regs, regno++, valbuf); + len -= INT_REGISTER_SIZE; + valbuf += INT_REGISTER_SIZE; + } + } + } + else + { + /* For a structure or union the behaviour is as if the value had + been stored to word-aligned memory and then loaded into + registers with 32-bit load instruction(s). */ + int len = TYPE_LENGTH (type); + int regno = ARM_A1_REGNUM; + bfd_byte tmpbuf[INT_REGISTER_SIZE]; + + while (len > 0) + { + memcpy (tmpbuf, valbuf, + len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len); + regcache_cooked_write (regs, regno++, tmpbuf); + len -= INT_REGISTER_SIZE; + valbuf += INT_REGISTER_SIZE; + } + } +} + +static int +arm_get_longjmp_target (CORE_ADDR *pc) +{ + CORE_ADDR jb_addr; + char buf[INT_REGISTER_SIZE]; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + jb_addr = read_register (ARM_A1_REGNUM); + + if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf, + INT_REGISTER_SIZE)) + return 0; + + *pc = extract_unsigned_integer (buf, INT_REGISTER_SIZE); + return 1; +} + +/* Return non-zero if the PC is inside a thumb call thunk. */ + +int +arm_in_call_stub (CORE_ADDR pc, char *name) +{ + CORE_ADDR start_addr; + + /* Find the starting address of the function containing the PC. If + the caller didn't give us a name, look it up at the same time. */ + if (0 == find_pc_partial_function (pc, name ? NULL : &name, + &start_addr, NULL)) + return 0; + + return strncmp (name, "_call_via_r", 11) == 0; +} + +/* If PC is in a Thumb call or return stub, return the address of the + target PC, which is in a register. The thunk functions are called + _called_via_xx, where x is the register name. The possible names + are r0-r9, sl, fp, ip, sp, and lr. */ + +CORE_ADDR +arm_skip_stub (CORE_ADDR pc) +{ + char *name; + CORE_ADDR start_addr; + + /* Find the starting address and name of the function containing the PC. */ + if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0) + return 0; + + /* Call thunks always start with "_call_via_". */ + if (strncmp (name, "_call_via_", 10) == 0) + { + /* Use the name suffix to determine which register contains the + target PC. */ + static char *table[15] = + {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "sl", "fp", "ip", "sp", "lr" + }; + int regno; + + for (regno = 0; regno <= 14; regno++) + if (strcmp (&name[10], table[regno]) == 0) + return read_register (regno); + } + + return 0; /* not a stub */ +} + +static void +set_arm_command (char *args, int from_tty) +{ + printf_unfiltered ("\"set arm\" must be followed by an apporpriate subcommand.\n"); + help_list (setarmcmdlist, "set arm ", all_commands, gdb_stdout); +} + +static void +show_arm_command (char *args, int from_tty) +{ + cmd_show_list (showarmcmdlist, from_tty, ""); +} + +enum arm_float_model +arm_get_fp_model (struct gdbarch *gdbarch) +{ + if (arm_fp_model == ARM_FLOAT_AUTO) + return gdbarch_tdep (gdbarch)->fp_model; + + return arm_fp_model; +} + +static void +arm_set_fp (struct gdbarch *gdbarch) +{ + enum arm_float_model fp_model = arm_get_fp_model (gdbarch); + + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE + && (fp_model == ARM_FLOAT_SOFT_FPA || fp_model == ARM_FLOAT_FPA)) + { + set_gdbarch_double_format (gdbarch, + &floatformat_ieee_double_littlebyte_bigword); + set_gdbarch_long_double_format + (gdbarch, &floatformat_ieee_double_littlebyte_bigword); + } + else + { + set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little); + set_gdbarch_long_double_format (gdbarch, + &floatformat_ieee_double_little); + } +} + +static void +set_fp_model_sfunc (char *args, int from_tty, + struct cmd_list_element *c) +{ + enum arm_float_model fp_model; + + for (fp_model = ARM_FLOAT_AUTO; fp_model != ARM_FLOAT_LAST; fp_model++) + if (strcmp (current_fp_model, fp_model_strings[fp_model]) == 0) + { + arm_fp_model = fp_model; + break; + } + + if (fp_model == ARM_FLOAT_LAST) + internal_error (__FILE__, __LINE__, "Invalid fp model accepted: %s.", + current_fp_model); + + if (gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm) + arm_set_fp (current_gdbarch); +} + +static void +show_fp_model (char *args, int from_tty, + struct cmd_list_element *c) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (arm_fp_model == ARM_FLOAT_AUTO + && gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm) + printf_filtered (" - the default for the current ABI is \"%s\".\n", + fp_model_strings[tdep->fp_model]); +} + +/* If the user changes the register disassembly style used for info + register and other commands, we have to also switch the style used + in opcodes for disassembly output. This function is run in the "set + arm disassembly" command, and does that. */ + +static void +set_disassembly_style_sfunc (char *args, int from_tty, + struct cmd_list_element *c) +{ + set_disassembly_style (); +} + +/* Return the ARM register name corresponding to register I. */ +static const char * +arm_register_name (int i) +{ + return arm_register_names[i]; +} + +static void +set_disassembly_style (void) +{ + const char *setname, *setdesc, **regnames; + int numregs, j; + + /* Find the style that the user wants in the opcodes table. */ + int current = 0; + numregs = get_arm_regnames (current, &setname, &setdesc, ®names); + while ((disassembly_style != setname) + && (current < num_disassembly_options)) + get_arm_regnames (++current, &setname, &setdesc, ®names); + current_option = current; + + /* Fill our copy. */ + for (j = 0; j < numregs; j++) + arm_register_names[j] = (char *) regnames[j]; + + /* Adjust case. */ + if (isupper (*regnames[ARM_PC_REGNUM])) + { + arm_register_names[ARM_FPS_REGNUM] = "FPS"; + arm_register_names[ARM_PS_REGNUM] = "CPSR"; + } + else + { + arm_register_names[ARM_FPS_REGNUM] = "fps"; + arm_register_names[ARM_PS_REGNUM] = "cpsr"; + } + + /* Synchronize the disassembler. */ + set_arm_regname_option (current); +} + +/* arm_othernames implements the "othernames" command. This is deprecated + by the "set arm disassembly" command. */ + +static void +arm_othernames (char *names, int n) +{ + /* Circle through the various flavors. */ + current_option = (current_option + 1) % num_disassembly_options; + + disassembly_style = valid_disassembly_styles[current_option]; + set_disassembly_style (); +} + +/* Test whether the coff symbol specific value corresponds to a Thumb + function. */ + +static int +coff_sym_is_thumb (int val) +{ + return (val == C_THUMBEXT || + val == C_THUMBSTAT || + val == C_THUMBEXTFUNC || + val == C_THUMBSTATFUNC || + val == C_THUMBLABEL); +} + +/* arm_coff_make_msymbol_special() + arm_elf_make_msymbol_special() + + These functions test whether the COFF or ELF symbol corresponds to + an address in thumb code, and set a "special" bit in a minimal + symbol to indicate that it does. */ + +static void +arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym) +{ + /* Thumb symbols are of type STT_LOPROC, (synonymous with + STT_ARM_TFUNC). */ + if (ELF_ST_TYPE (((elf_symbol_type *)sym)->internal_elf_sym.st_info) + == STT_LOPROC) + MSYMBOL_SET_SPECIAL (msym); +} + +static void +arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym) +{ + if (coff_sym_is_thumb (val)) + MSYMBOL_SET_SPECIAL (msym); +} + +static void +arm_write_pc (CORE_ADDR pc, ptid_t ptid) +{ + write_register_pid (ARM_PC_REGNUM, pc, ptid); + + /* If necessary, set the T bit. */ + if (arm_apcs_32) + { + CORE_ADDR val = read_register_pid (ARM_PS_REGNUM, ptid); + if (arm_pc_is_thumb (pc)) + write_register_pid (ARM_PS_REGNUM, val | 0x20, ptid); + else + write_register_pid (ARM_PS_REGNUM, val & ~(CORE_ADDR) 0x20, ptid); + } +} + +static enum gdb_osabi +arm_elf_osabi_sniffer (bfd *abfd) +{ + unsigned int elfosabi, eflags; + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; + + elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; + + switch (elfosabi) + { + case ELFOSABI_NONE: + /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the + file are conforming to the base specification for that machine + (there are no OS-specific extensions). In order to determine the + real OS in use we must look for OS notes that have been added. */ + bfd_map_over_sections (abfd, + generic_elf_osabi_sniff_abi_tag_sections, + &osabi); + if (osabi == GDB_OSABI_UNKNOWN) + { + /* Existing ARM tools don't set this field, so look at the EI_FLAGS + field for more information. */ + eflags = EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags); + switch (eflags) + { + case EF_ARM_EABI_VER1: + osabi = GDB_OSABI_ARM_EABI_V1; + break; + + case EF_ARM_EABI_VER2: + osabi = GDB_OSABI_ARM_EABI_V2; + break; + + case EF_ARM_EABI_UNKNOWN: + /* Assume GNU tools. */ + osabi = GDB_OSABI_ARM_APCS; + break; + + default: + internal_error (__FILE__, __LINE__, + "arm_elf_osabi_sniffer: Unknown ARM EABI " + "version 0x%x", eflags); + } + } + break; + + case ELFOSABI_ARM: + /* GNU tools use this value. Check note sections in this case, + as well. */ + bfd_map_over_sections (abfd, + generic_elf_osabi_sniff_abi_tag_sections, + &osabi); + if (osabi == GDB_OSABI_UNKNOWN) + { + /* Assume APCS ABI. */ + osabi = GDB_OSABI_ARM_APCS; + } + break; + + case ELFOSABI_FREEBSD: + osabi = GDB_OSABI_FREEBSD_ELF; + break; + + case ELFOSABI_NETBSD: + osabi = GDB_OSABI_NETBSD_ELF; + break; + + case ELFOSABI_LINUX: + osabi = GDB_OSABI_LINUX; + break; + } + + return osabi; +} + + +/* Initialize the current architecture based on INFO. If possible, + re-use an architecture from ARCHES, which is a list of + architectures already created during this debugging session. + + Called e.g. at program startup, when reading a core file, and when + reading a binary file. */ + +static struct gdbarch * +arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + struct gdbarch_tdep *tdep; + struct gdbarch *gdbarch; + + /* Try to deterimine the ABI of the object we are loading. */ + + if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN) + { + switch (bfd_get_flavour (info.abfd)) + { + case bfd_target_aout_flavour: + /* Assume it's an old APCS-style ABI. */ + info.osabi = GDB_OSABI_ARM_APCS; + break; + + case bfd_target_coff_flavour: + /* Assume it's an old APCS-style ABI. */ + /* XXX WinCE? */ + info.osabi = GDB_OSABI_ARM_APCS; + break; + + default: + /* Leave it as "unknown". */ + break; + } + } + + /* If there is already a candidate, use it. */ + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != NULL) + return arches->gdbarch; + + tdep = xmalloc (sizeof (struct gdbarch_tdep)); + gdbarch = gdbarch_alloc (&info, tdep); + + /* We used to default to FPA for generic ARM, but almost nobody uses that + now, and we now provide a way for the user to force the model. So + default to the most useful variant. */ + tdep->fp_model = ARM_FLOAT_SOFT_FPA; + + /* Breakpoints. */ + switch (info.byte_order) + { + case BFD_ENDIAN_BIG: + tdep->arm_breakpoint = arm_default_arm_be_breakpoint; + tdep->arm_breakpoint_size = sizeof (arm_default_arm_be_breakpoint); + tdep->thumb_breakpoint = arm_default_thumb_be_breakpoint; + tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_be_breakpoint); + + break; + + case BFD_ENDIAN_LITTLE: + tdep->arm_breakpoint = arm_default_arm_le_breakpoint; + tdep->arm_breakpoint_size = sizeof (arm_default_arm_le_breakpoint); + tdep->thumb_breakpoint = arm_default_thumb_le_breakpoint; + tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_le_breakpoint); + + break; + + default: + internal_error (__FILE__, __LINE__, + "arm_gdbarch_init: bad byte order for float format"); + } + + /* On ARM targets char defaults to unsigned. */ + set_gdbarch_char_signed (gdbarch, 0); + + /* This should be low enough for everything. */ + tdep->lowest_pc = 0x20; + tdep->jb_pc = -1; /* Longjump support not enabled by default. */ + + set_gdbarch_deprecated_call_dummy_words (gdbarch, arm_call_dummy_words); + set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0); + + set_gdbarch_push_dummy_call (gdbarch, arm_push_dummy_call); + + set_gdbarch_write_pc (gdbarch, arm_write_pc); + + /* Frame handling. */ + set_gdbarch_unwind_dummy_id (gdbarch, arm_unwind_dummy_id); + set_gdbarch_unwind_pc (gdbarch, arm_unwind_pc); + set_gdbarch_unwind_sp (gdbarch, arm_unwind_sp); + + set_gdbarch_deprecated_frameless_function_invocation (gdbarch, arm_frameless_function_invocation); + + frame_base_set_default (gdbarch, &arm_normal_base); + + /* Address manipulation. */ + set_gdbarch_smash_text_address (gdbarch, arm_smash_text_address); + set_gdbarch_addr_bits_remove (gdbarch, arm_addr_bits_remove); + + /* Advance PC across function entry code. */ + set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue); + + /* Get the PC when a frame might not be available. */ + set_gdbarch_deprecated_saved_pc_after_call (gdbarch, arm_saved_pc_after_call); + + /* The stack grows downward. */ + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + + /* Breakpoint manipulation. */ + set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc); + + /* Information about registers, etc. */ + set_gdbarch_print_float_info (gdbarch, arm_print_float_info); + set_gdbarch_deprecated_fp_regnum (gdbarch, ARM_FP_REGNUM); /* ??? */ + set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM); + set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM); + set_gdbarch_deprecated_register_byte (gdbarch, arm_register_byte); + set_gdbarch_deprecated_register_bytes (gdbarch, + (NUM_GREGS * INT_REGISTER_SIZE + + NUM_FREGS * FP_REGISTER_SIZE + + NUM_SREGS * STATUS_REGISTER_SIZE)); + set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS); + set_gdbarch_register_type (gdbarch, arm_register_type); + + /* Internal <-> external register number maps. */ + set_gdbarch_register_sim_regno (gdbarch, arm_register_sim_regno); + + /* Integer registers are 4 bytes. */ + set_gdbarch_deprecated_register_size (gdbarch, 4); + set_gdbarch_register_name (gdbarch, arm_register_name); + + /* Returning results. */ + set_gdbarch_extract_return_value (gdbarch, arm_extract_return_value); + set_gdbarch_store_return_value (gdbarch, arm_store_return_value); + set_gdbarch_use_struct_convention (gdbarch, arm_use_struct_convention); + set_gdbarch_deprecated_extract_struct_value_address (gdbarch, arm_extract_struct_value_address); + + /* Single stepping. */ + /* XXX For an RDI target we should ask the target if it can single-step. */ + set_gdbarch_software_single_step (gdbarch, arm_software_single_step); + + /* Disassembly. */ + set_gdbarch_print_insn (gdbarch, gdb_print_insn_arm); + + /* Minsymbol frobbing. */ + set_gdbarch_elf_make_msymbol_special (gdbarch, arm_elf_make_msymbol_special); + set_gdbarch_coff_make_msymbol_special (gdbarch, + arm_coff_make_msymbol_special); + + /* Hook in the ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); + + /* Add some default predicates. */ + frame_unwind_append_sniffer (gdbarch, arm_sigtramp_unwind_sniffer); + frame_unwind_append_sniffer (gdbarch, arm_prologue_unwind_sniffer); + + /* Now we have tuned the configuration, set a few final things, + based on what the OS ABI has told us. */ + + if (tdep->jb_pc >= 0) + set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target); + + /* Floating point sizes and format. */ + switch (info.byte_order) + { + case BFD_ENDIAN_BIG: + set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big); + set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big); + set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); + + break; + + case BFD_ENDIAN_LITTLE: + set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little); + arm_set_fp (gdbarch); + break; + + default: + internal_error (__FILE__, __LINE__, + "arm_gdbarch_init: bad byte order for float format"); + } + + return gdbarch; +} + +static void +arm_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (tdep == NULL) + return; + + fprintf_unfiltered (file, "arm_dump_tdep: Lowest pc = 0x%lx", + (unsigned long) tdep->lowest_pc); +} + +static void +arm_init_abi_eabi_v1 (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + /* Place-holder. */ +} + +static void +arm_init_abi_eabi_v2 (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + /* Place-holder. */ +} + +static void +arm_init_abi_apcs (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + /* Place-holder. */ +} + +extern initialize_file_ftype _initialize_arm_tdep; /* -Wmissing-prototypes */ + +void +_initialize_arm_tdep (void) +{ + struct ui_file *stb; + long length; + struct cmd_list_element *new_set, *new_show; + const char *setname; + const char *setdesc; + const char **regnames; + int numregs, i, j; + static char *helptext; + + gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep); + + /* Register an ELF OS ABI sniffer for ARM binaries. */ + gdbarch_register_osabi_sniffer (bfd_arch_arm, + bfd_target_elf_flavour, + arm_elf_osabi_sniffer); + + /* Register some ABI variants for embedded systems. */ + gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_EABI_V1, + arm_init_abi_eabi_v1); + gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_EABI_V2, + arm_init_abi_eabi_v2); + gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_APCS, + arm_init_abi_apcs); + + /* Get the number of possible sets of register names defined in opcodes. */ + num_disassembly_options = get_arm_regname_num_options (); + + /* Add root prefix command for all "set arm"/"show arm" commands. */ + add_prefix_cmd ("arm", no_class, set_arm_command, + "Various ARM-specific commands.", + &setarmcmdlist, "set arm ", 0, &setlist); + + add_prefix_cmd ("arm", no_class, show_arm_command, + "Various ARM-specific commands.", + &showarmcmdlist, "show arm ", 0, &showlist); + + /* Sync the opcode insn printer with our register viewer. */ + parse_arm_disassembler_option ("reg-names-std"); + + /* Begin creating the help text. */ + stb = mem_fileopen (); + fprintf_unfiltered (stb, "Set the disassembly style.\n" + "The valid values are:\n"); + + /* Initialize the array that will be passed to add_set_enum_cmd(). */ + valid_disassembly_styles + = xmalloc ((num_disassembly_options + 1) * sizeof (char *)); + for (i = 0; i < num_disassembly_options; i++) + { + numregs = get_arm_regnames (i, &setname, &setdesc, ®names); + valid_disassembly_styles[i] = setname; + fprintf_unfiltered (stb, "%s - %s\n", setname, + setdesc); + /* Copy the default names (if found) and synchronize disassembler. */ + if (!strcmp (setname, "std")) + { + disassembly_style = setname; + current_option = i; + for (j = 0; j < numregs; j++) + arm_register_names[j] = (char *) regnames[j]; + set_arm_regname_option (i); + } + } + /* Mark the end of valid options. */ + valid_disassembly_styles[num_disassembly_options] = NULL; + + /* Finish the creation of the help text. */ + fprintf_unfiltered (stb, "The default is \"std\"."); + helptext = ui_file_xstrdup (stb, &length); + ui_file_delete (stb); + + /* Add the deprecated disassembly-flavor command. */ + new_set = add_set_enum_cmd ("disassembly-flavor", no_class, + valid_disassembly_styles, + &disassembly_style, + helptext, + &setlist); + set_cmd_sfunc (new_set, set_disassembly_style_sfunc); + deprecate_cmd (new_set, "set arm disassembly"); + deprecate_cmd (add_show_from_set (new_set, &showlist), + "show arm disassembly"); + + /* And now add the new interface. */ + new_set = add_set_enum_cmd ("disassembler", no_class, + valid_disassembly_styles, &disassembly_style, + helptext, &setarmcmdlist); + + set_cmd_sfunc (new_set, set_disassembly_style_sfunc); + add_show_from_set (new_set, &showarmcmdlist); + + add_setshow_cmd_full ("apcs32", no_class, + var_boolean, (char *) &arm_apcs_32, + "Set usage of ARM 32-bit mode.", + "Show usage of ARM 32-bit mode.", + NULL, NULL, + &setlist, &showlist, &new_set, &new_show); + deprecate_cmd (new_set, "set arm apcs32"); + deprecate_cmd (new_show, "show arm apcs32"); + + add_setshow_boolean_cmd ("apcs32", no_class, &arm_apcs_32, + "Set usage of ARM 32-bit mode. " + "When off, a 26-bit PC will be used.", + "Show usage of ARM 32-bit mode. " + "When off, a 26-bit PC will be used.", + NULL, NULL, + &setarmcmdlist, &showarmcmdlist); + + /* Add a command to allow the user to force the FPU model. */ + new_set = add_set_enum_cmd + ("fpu", no_class, fp_model_strings, ¤t_fp_model, + "Set the floating point type.\n" + "auto - Determine the FP typefrom the OS-ABI.\n" + "softfpa - Software FP, mixed-endian doubles on little-endian ARMs.\n" + "fpa - FPA co-processor (GCC compiled).\n" + "softvfp - Software FP with pure-endian doubles.\n" + "vfp - VFP co-processor.", + &setarmcmdlist); + set_cmd_sfunc (new_set, set_fp_model_sfunc); + set_cmd_sfunc (add_show_from_set (new_set, &showarmcmdlist), show_fp_model); + + /* Add the deprecated "othernames" command. */ + deprecate_cmd (add_com ("othernames", class_obscure, arm_othernames, + "Switch to the next set of register names."), + "set arm disassembly"); + + /* Debugging flag. */ + add_setshow_boolean_cmd ("arm", class_maintenance, &arm_debug, + "Set ARM debugging. " + "When on, arm-specific debugging is enabled.", + "Show ARM debugging. " + "When on, arm-specific debugging is enabled.", + NULL, NULL, + &setdebuglist, &showdebuglist); +} diff --git a/contrib/gdb/gdb/arm-tdep.h b/contrib/gdb/gdb/arm-tdep.h index a4c52dc6f6b..bb30455a314 100644 --- a/contrib/gdb/gdb/arm-tdep.h +++ b/contrib/gdb/gdb/arm-tdep.h @@ -1,5 +1,5 @@ /* Common target dependent code for GDB on ARM systems. - Copyright 2002 Free Software Foundation, Inc. + Copyright 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -25,39 +25,33 @@ the user is concerned but do serve to get the desired values when passed to read_register. */ -#define ARM_A1_REGNUM 0 /* first integer-like argument */ -#define ARM_A4_REGNUM 3 /* last integer-like argument */ -#define ARM_AP_REGNUM 11 -#define ARM_SP_REGNUM 13 /* Contains address of top of stack */ -#define ARM_LR_REGNUM 14 /* address to return to from a function call */ -#define ARM_PC_REGNUM 15 /* Contains program counter */ -#define ARM_F0_REGNUM 16 /* first floating point register */ -#define ARM_F3_REGNUM 19 /* last floating point argument register */ -#define ARM_F7_REGNUM 23 /* last floating point register */ -#define ARM_FPS_REGNUM 24 /* floating point status register */ -#define ARM_PS_REGNUM 25 /* Contains processor status */ - -#define ARM_FP_REGNUM 11 /* Frame register in ARM code, if used. */ -#define THUMB_FP_REGNUM 7 /* Frame register in Thumb code, if used. */ - -#define ARM_NUM_ARG_REGS 4 -#define ARM_LAST_ARG_REGNUM ARM_A4_REGNUM -#define ARM_NUM_FP_ARG_REGS 4 -#define ARM_LAST_FP_ARG_REGNUM ARM_F3_REGNUM +enum gdb_regnum { + ARM_A1_REGNUM = 0, /* first integer-like argument */ + ARM_A4_REGNUM = 3, /* last integer-like argument */ + ARM_AP_REGNUM = 11, + ARM_SP_REGNUM = 13, /* Contains address of top of stack */ + ARM_LR_REGNUM = 14, /* address to return to from a function call */ + ARM_PC_REGNUM = 15, /* Contains program counter */ + ARM_F0_REGNUM = 16, /* first floating point register */ + ARM_F3_REGNUM = 19, /* last floating point argument register */ + ARM_F7_REGNUM = 23, /* last floating point register */ + ARM_FPS_REGNUM = 24, /* floating point status register */ + ARM_PS_REGNUM = 25, /* Contains processor status */ + ARM_FP_REGNUM = 11, /* Frame register in ARM code, if used. */ + THUMB_FP_REGNUM = 7, /* Frame register in Thumb code, if used. */ + ARM_NUM_ARG_REGS = 4, + ARM_LAST_ARG_REGNUM = ARM_A4_REGNUM, + ARM_NUM_FP_ARG_REGS = 4, + ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM +}; /* Size of integer registers. */ -#define INT_REGISTER_RAW_SIZE 4 -#define INT_REGISTER_VIRTUAL_SIZE 4 +#define INT_REGISTER_SIZE 4 /* Say how long FP registers are. Used for documentation purposes and code readability in this header. IEEE extended doubles are 80 bits. DWORD aligned they use 96 bits. */ -#define FP_REGISTER_RAW_SIZE 12 - -/* GCC doesn't support long doubles (extended IEEE values). The FP - register virtual size is therefore 64 bits. Used for documentation - purposes and code readability in this header. */ -#define FP_REGISTER_VIRTUAL_SIZE 8 +#define FP_REGISTER_SIZE 12 /* Status registers are the same size as general purpose registers. Used for documentation purposes and code readability in this @@ -99,44 +93,32 @@ #define FLAG_C 0x20000000 #define FLAG_V 0x10000000 -/* ABI variants that we know about. If you add to this enum, please - update the table of names in tm-arm.c. */ -enum arm_abi -{ - ARM_ABI_UNKNOWN = 0, - ARM_ABI_EABI_V1, - ARM_ABI_EABI_V2, - ARM_ABI_LINUX, - ARM_ABI_NETBSD_AOUT, - ARM_ABI_NETBSD_ELF, - ARM_ABI_APCS, - ARM_ABI_FREEBSD, - ARM_ABI_WINCE, - - ARM_ABI_INVALID /* Keep this last. */ -}; - /* Type of floating-point code in use by inferior. There are really 3 models that are traditionally supported (plus the endianness issue), but gcc can only generate 2 of those. The third is APCS_FLOAT, where arguments to functions are passed in floating-point registers. - In addition to the traditional models, VFP adds two more. */ + In addition to the traditional models, VFP adds two more. + + If you update this enum, don't forget to update fp_model_strings in + arm-tdep.c. */ enum arm_float_model { - ARM_FLOAT_SOFT, - ARM_FLOAT_FPA, - ARM_FLOAT_SOFT_VFP, - ARM_FLOAT_VFP + ARM_FLOAT_AUTO, /* Automatic detection. Do not set in tdep. */ + ARM_FLOAT_SOFT_FPA, /* Traditional soft-float (mixed-endian on LE ARM). */ + ARM_FLOAT_FPA, /* FPA co-processor. GCC calling convention. */ + ARM_FLOAT_SOFT_VFP, /* Soft-float with pure-endian doubles. */ + ARM_FLOAT_VFP, /* Full VFP calling convention. */ + ARM_FLOAT_LAST /* Keep at end. */ }; +/* A method to the setting based on user's choice and ABI setting. */ +enum arm_float_model arm_get_fp_model (struct gdbarch *); + /* Target-dependent structure in gdbarch. */ struct gdbarch_tdep { - enum arm_abi arm_abi; /* OS/ABI of inferior. */ - const char *abi_name; /* Name of the above. */ - enum arm_float_model fp_model; /* Floating point calling conventions. */ CORE_ADDR lowest_pc; /* Lowest address at which instructions @@ -165,10 +147,3 @@ int arm_pc_is_thumb (CORE_ADDR); CORE_ADDR thumb_get_next_pc (CORE_ADDR); CORE_ADDR arm_get_next_pc (CORE_ADDR); - -/* How a OS variant tells the ARM generic code that it can handle an ABI - type. */ -void -arm_gdbarch_register_os_abi (enum arm_abi abi, - void (*init_abi)(struct gdbarch_info, - struct gdbarch *)); diff --git a/contrib/gdb/gdb/armnbsd-tdep.c b/contrib/gdb/gdb/armnbsd-tdep.c index 7f6e63992e2..0ce46e653df 100644 --- a/contrib/gdb/gdb/armnbsd-tdep.c +++ b/contrib/gdb/gdb/armnbsd-tdep.c @@ -1,5 +1,5 @@ /* Target-specific functions for ARM running under NetBSD. - Copyright 2002 Free Software Foundation, Inc. + Copyright 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -19,12 +19,15 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "osabi.h" #include "arm-tdep.h" +#include "nbsd-tdep.h" +#include "solib-svr4.h" /* Description of the longjmp buffer. */ -#define JB_PC 24 -#define JB_ELEMENT_SIZE INT_REGISTER_RAW_SIZE +#define ARM_NBSD_JB_PC 24 +#define ARM_NBSD_JB_ELEMENT_SIZE INT_REGISTER_SIZE /* For compatibility with previous implemenations of GDB on arm/NetBSD, override the default little-endian breakpoint. */ @@ -49,8 +52,8 @@ arm_netbsd_init_abi_common (struct gdbarch_info info, tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint; tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint); - tdep->jb_pc = JB_PC; - tdep->jb_elt_size = JB_ELEMENT_SIZE; + tdep->jb_pc = ARM_NBSD_JB_PC; + tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE; } static void @@ -63,7 +66,7 @@ arm_netbsd_aout_init_abi (struct gdbarch_info info, set_gdbarch_in_solib_call_trampoline (gdbarch, arm_netbsd_aout_in_solib_call_trampoline); - tdep->fp_model = ARM_FLOAT_SOFT; + tdep->fp_model = ARM_FLOAT_SOFT_FPA; } static void @@ -74,12 +77,29 @@ arm_netbsd_elf_init_abi (struct gdbarch_info info, arm_netbsd_init_abi_common (info, gdbarch); + set_solib_svr4_fetch_link_map_offsets (gdbarch, + nbsd_ilp32_solib_svr4_fetch_link_map_offsets); + tdep->fp_model = ARM_FLOAT_SOFT_VFP; } +static enum gdb_osabi +arm_netbsd_aout_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "a.out-arm-netbsd") == 0) + return GDB_OSABI_NETBSD_AOUT; + + return GDB_OSABI_UNKNOWN; +} + void _initialize_arm_netbsd_tdep (void) { - arm_gdbarch_register_os_abi (ARM_ABI_NETBSD_AOUT, arm_netbsd_aout_init_abi); - arm_gdbarch_register_os_abi (ARM_ABI_NETBSD_ELF, arm_netbsd_elf_init_abi); + gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_aout_flavour, + arm_netbsd_aout_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_AOUT, + arm_netbsd_aout_init_abi); + gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_ELF, + arm_netbsd_elf_init_abi); } diff --git a/contrib/gdb/gdb/auxv.c b/contrib/gdb/gdb/auxv.c new file mode 100644 index 00000000000..a2516b68528 --- /dev/null +++ b/contrib/gdb/gdb/auxv.c @@ -0,0 +1,300 @@ +/* Auxiliary vector support for GDB, the GNU debugger. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "target.h" +#include "gdbtypes.h" +#include "command.h" +#include "inferior.h" +#include "valprint.h" +#include "gdb_assert.h" + +#include "auxv.h" +#include "elf/common.h" + +#include +#include + + +/* This function is called like a to_xfer_partial hook, + but must be called with TARGET_OBJECT_AUXV. + It handles access via /proc/PID/auxv, which is the common method. + This function is appropriate for doing: + #define NATIVE_XFER_AUXV procfs_xfer_auxv + for a native target that uses inftarg.c's child_xfer_partial hook. */ + +LONGEST +procfs_xfer_auxv (struct target_ops *ops, + int /* enum target_object */ object, + const char *annex, + void *readbuf, + const void *writebuf, + ULONGEST offset, + LONGEST len) +{ + char *pathname; + int fd; + LONGEST n; + + gdb_assert (object == TARGET_OBJECT_AUXV); + gdb_assert (readbuf || writebuf); + + pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid)); + fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY); + xfree (pathname); + if (fd < 0) + return -1; + + if (offset != (ULONGEST) 0 + && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) + n = -1; + else if (readbuf != NULL) + n = read (fd, readbuf, len); + else + n = write (fd, writebuf, len); + + (void) close (fd); + + return n; +} + +/* Read all the auxv data into a contiguous xmalloc'd buffer, + stored in *DATA. Return the size in bytes of this data. + If zero, there is no data and *DATA is null. + if < 0, there was an error and *DATA is null. */ +LONGEST +target_auxv_read (struct target_ops *ops, char **data) +{ + size_t auxv_alloc = 512, auxv_pos = 0; + char *auxv = xmalloc (auxv_alloc); + int n; + + while (1) + { + n = target_read_partial (ops, TARGET_OBJECT_AUXV, + NULL, &auxv[auxv_pos], 0, + auxv_alloc - auxv_pos); + if (n <= 0) + break; + auxv_pos += n; + if (auxv_pos < auxv_alloc) /* Read all there was. */ + break; + gdb_assert (auxv_pos == auxv_alloc); + auxv_alloc *= 2; + auxv = xrealloc (auxv, auxv_alloc); + } + + if (auxv_pos == 0) + { + xfree (auxv); + *data = NULL; + return n; + } + + *data = auxv; + return auxv_pos; +} + +/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. + Return 0 if *READPTR is already at the end of the buffer. + Return -1 if there is insufficient buffer for a whole entry. + Return 1 if an entry was read into *TYPEP and *VALP. */ +int +target_auxv_parse (struct target_ops *ops, char **readptr, char *endptr, + CORE_ADDR *typep, CORE_ADDR *valp) +{ + const int sizeof_auxv_field = TYPE_LENGTH (builtin_type_void_data_ptr); + char *ptr = *readptr; + + if (endptr == ptr) + return 0; + + if (endptr - ptr < sizeof_auxv_field * 2) + return -1; + + *typep = extract_unsigned_integer (ptr, sizeof_auxv_field); + ptr += sizeof_auxv_field; + *valp = extract_unsigned_integer (ptr, sizeof_auxv_field); + ptr += sizeof_auxv_field; + + *readptr = ptr; + return 1; +} + +/* Extract the auxiliary vector entry with a_type matching MATCH. + Return zero if no such entry was found, or -1 if there was + an error getting the information. On success, return 1 after + storing the entry's value field in *VALP. */ +int +target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp) +{ + CORE_ADDR type, val; + char *data; + int n = target_auxv_read (ops, &data); + char *ptr = data; + int ents = 0; + + if (n <= 0) + return n; + + while (1) + switch (target_auxv_parse (ops, &ptr, data + n, &type, &val)) + { + case 1: /* Here's an entry, check it. */ + if (type == match) + { + xfree (data); + *valp = val; + return 1; + } + break; + case 0: /* End of the vector. */ + xfree (data); + return 0; + default: /* Bogosity. */ + xfree (data); + return -1; + } + + /*NOTREACHED*/ +} + + +/* Print the contents of the target's AUXV on the specified file. */ +int +fprint_target_auxv (struct ui_file *file, struct target_ops *ops) +{ + CORE_ADDR type, val; + char *data; + int len = target_auxv_read (ops, &data); + char *ptr = data; + int ents = 0; + + if (len <= 0) + return len; + + while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0) + { + extern int addressprint; + const char *name = "???"; + const char *description = ""; + enum { dec, hex, str } flavor = hex; + + switch (type) + { +#define TAG(tag, text, kind) \ + case tag: name = #tag; description = text; flavor = kind; break + TAG (AT_NULL, "End of vector", hex); + TAG (AT_IGNORE, "Entry should be ignored", hex); + TAG (AT_EXECFD, "File descriptor of program", dec); + TAG (AT_PHDR, "Program headers for program", hex); + TAG (AT_PHENT, "Size of program header entry", dec); + TAG (AT_PHNUM, "Number of program headers", dec); + TAG (AT_PAGESZ, "System page size", dec); + TAG (AT_BASE, "Base address of interpreter", hex); + TAG (AT_FLAGS, "Flags", hex); + TAG (AT_ENTRY, "Entry point of program", hex); + TAG (AT_NOTELF, "Program is not ELF", dec); + TAG (AT_UID, "Real user ID", dec); + TAG (AT_EUID, "Effective user ID", dec); + TAG (AT_GID, "Real group ID", dec); + TAG (AT_EGID, "Effective group ID", dec); + TAG (AT_CLKTCK, "Frequency of times()", dec); + TAG (AT_PLATFORM, "String identifying platform", str); + TAG (AT_HWCAP, "Machine-dependent CPU capability hints", hex); + TAG (AT_FPUCW, "Used FPU control word", dec); + TAG (AT_DCACHEBSIZE, "Data cache block size", dec); + TAG (AT_ICACHEBSIZE, "Instruction cache block size", dec); + TAG (AT_UCACHEBSIZE, "Unified cache block size", dec); + TAG (AT_IGNOREPPC, "Entry should be ignored", dec); + TAG (AT_SYSINFO, "Special system info/entry points", hex); + TAG (AT_SYSINFO_EHDR, "System-supplied DSO's ELF header", hex); + TAG (AT_SECURE, "Boolean, was exec setuid-like?", dec); + TAG (AT_SUN_UID, "Effective user ID", dec); + TAG (AT_SUN_RUID, "Real user ID", dec); + TAG (AT_SUN_GID, "Effective group ID", dec); + TAG (AT_SUN_RGID, "Real group ID", dec); + TAG (AT_SUN_LDELF, "Dynamic linker's ELF header", hex); + TAG (AT_SUN_LDSHDR, "Dynamic linker's section headers", hex); + TAG (AT_SUN_LDNAME, "String giving name of dynamic linker", str); + TAG (AT_SUN_LPAGESZ, "Large pagesize", dec); + TAG (AT_SUN_PLATFORM, "Platform name string", str); + TAG (AT_SUN_HWCAP, "Machine-dependent CPU capability hints", hex); + TAG (AT_SUN_IFLUSH, "Should flush icache?", dec); + TAG (AT_SUN_CPU, "CPU name string", str); + TAG (AT_SUN_EMUL_ENTRY, "COFF entry point address", hex); + TAG (AT_SUN_EMUL_EXECFD, "COFF executable file descriptor", dec); + TAG (AT_SUN_EXECNAME, + "Canonicalized file name given to execve", str); + TAG (AT_SUN_MMU, "String for name of MMU module", str); + TAG (AT_SUN_LDDATA, "Dynamic linker's data segment address", hex); + } + + fprintf_filtered (file, "%-4s %-20s %-30s ", + paddr_d (type), name, description); + switch (flavor) + { + case dec: + fprintf_filtered (file, "%s\n", paddr_d (val)); + break; + case hex: + fprintf_filtered (file, "0x%s\n", paddr_nz (val)); + break; + case str: + if (addressprint) + fprintf_filtered (file, "0x%s", paddr_nz (val)); + val_print_string (val, -1, 1, file); + fprintf_filtered (file, "\n"); + break; + } + ++ents; + } + + xfree (data); + + return ents; +} + +static void +info_auxv_command (char *cmd, int from_tty) +{ + if (! target_has_stack) + error ("The program has no auxiliary information now."); + else + { + int ents = fprint_target_auxv (gdb_stdout, ¤t_target); + if (ents < 0) + error ("No auxiliary vector found, or failed reading it."); + else if (ents == 0) + error ("Auxiliary vector is empty."); + } +} + + +extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */ + +void +_initialize_auxv (void) +{ + add_info ("auxv", info_auxv_command, + "Display the inferior's auxiliary vector.\n\ +This is information provided by the operating system at program startup."); +} diff --git a/contrib/gdb/gdb/auxv.h b/contrib/gdb/gdb/auxv.h new file mode 100644 index 00000000000..4ce0569a591 --- /dev/null +++ b/contrib/gdb/gdb/auxv.h @@ -0,0 +1,75 @@ +/* Auxiliary vector support for GDB, the GNU debugger. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef AUXV_H +#define AUXV_H + +/* See "include/elf/common.h" for the definition of valid AT_* values. */ + + +/* Avoid miscellaneous includes in this file, so that it can be + included by nm-*.h for the procfs_xfer_auxv decl if that is + used in NATIVE_XFER_AUXV. */ +struct target_ops; /* Forward declaration. */ + + +/* Read all the auxv data into a contiguous xmalloc'd buffer, + stored in *DATA. Return the size in bytes of this data. + If zero, there is no data and *DATA is null. + if < 0, there was an error and *DATA is null. */ +extern LONGEST target_auxv_read (struct target_ops *ops, char **data); + +/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. + Return 0 if *READPTR is already at the end of the buffer. + Return -1 if there is insufficient buffer for a whole entry. + Return 1 if an entry was read into *TYPEP and *VALP. */ +extern int target_auxv_parse (struct target_ops *ops, + char **readptr, char *endptr, + CORE_ADDR *typep, CORE_ADDR *valp); + +/* Extract the auxiliary vector entry with a_type matching MATCH. + Return zero if no such entry was found, or -1 if there was + an error getting the information. On success, return 1 after + storing the entry's value field in *VALP. */ +extern int target_auxv_search (struct target_ops *ops, + CORE_ADDR match, CORE_ADDR *valp); + +/* Print the contents of the target's AUXV on the specified file. */ +extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops); + + +/* This function is called like a to_xfer_partial hook, + but must be called with TARGET_OBJECT_AUXV. + It handles access via /proc/PID/auxv, which is the common method. + This function is appropriate for doing: + #define NATIVE_XFER_AUXV procfs_xfer_auxv + for a native target that uses inftarg.c's child_xfer_partial hook. */ + +extern LONGEST procfs_xfer_auxv (struct target_ops *ops, + int /* enum target_object */ object, + const char *annex, + void *readbuf, + const void *writebuf, + ULONGEST offset, + LONGEST len); + + +#endif diff --git a/contrib/gdb/gdb/ax-gdb.c b/contrib/gdb/gdb/ax-gdb.c index aa9f92a9610..dadad8e2549 100644 --- a/contrib/gdb/gdb/ax-gdb.c +++ b/contrib/gdb/gdb/ax-gdb.c @@ -1,5 +1,7 @@ -/* GDB-specific functions for operating on agent expressions - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* GDB-specific functions for operating on agent expressions. + + Copyright 1998, 1999, 2000, 2001, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -30,6 +32,9 @@ #include "target.h" #include "ax.h" #include "ax-gdb.h" +#include "gdb_string.h" +#include "block.h" +#include "regcache.h" /* To make sense of this file, you should read doc/agentexpr.texi. Then look at the types and enums in ax-gdb.h. For the code itself, @@ -129,7 +134,6 @@ static void gen_sizeof (union exp_element **pc, static void gen_expr (union exp_element **pc, struct agent_expr *ax, struct axs_value *value); -static void print_axs_value (struct ui_file *f, struct axs_value * value); static void agent_command (char *exp, int from_tty); @@ -353,7 +357,7 @@ gen_sign_extend (struct agent_expr *ax, struct type *type) { /* Do we need to sign-extend this? */ if (!TYPE_UNSIGNED (type)) - ax_ext (ax, type->length * TARGET_CHAR_BIT); + ax_ext (ax, TYPE_LENGTH (type) * TARGET_CHAR_BIT); } @@ -363,7 +367,7 @@ gen_sign_extend (struct agent_expr *ax, struct type *type) static void gen_extend (struct agent_expr *ax, struct type *type) { - int bits = type->length * TARGET_CHAR_BIT; + int bits = TYPE_LENGTH (type) * TARGET_CHAR_BIT; /* I just had to. */ ((TYPE_UNSIGNED (type) ? ax_zero_ext : ax_ext) (ax, bits)); } @@ -381,7 +385,7 @@ gen_fetch (struct agent_expr *ax, struct type *type) ax_trace_quick (ax, TYPE_LENGTH (type)); } - switch (type->code) + switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: case TYPE_CODE_ENUM: @@ -389,7 +393,7 @@ gen_fetch (struct agent_expr *ax, struct type *type) case TYPE_CODE_CHAR: /* It's a scalar value, so we know how to dereference it. How many bytes long is it? */ - switch (type->length) + switch (TYPE_LENGTH (type)) { case 8 / TARGET_CHAR_BIT: ax_simple (ax, aop_ref8); @@ -575,7 +579,7 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) case LOC_TYPEDEF: error ("Cannot compute value of typedef `%s'.", - SYMBOL_SOURCE_NAME (var)); + SYMBOL_PRINT_NAME (var)); break; case LOC_BLOCK: @@ -604,9 +608,9 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) case LOC_UNRESOLVED: { struct minimal_symbol *msym - = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL); + = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (var), NULL, NULL); if (!msym) - error ("Couldn't resolve symbol `%s'.", SYMBOL_SOURCE_NAME (var)); + error ("Couldn't resolve symbol `%s'.", SYMBOL_PRINT_NAME (var)); /* Push the address of the variable. */ ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym)); @@ -614,14 +618,24 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) } break; + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + /* FIXME: cagney/2004-01-26: It should be possible to + unconditionally call the SYMBOL_OPS method when available. + Unfortunately DWARF 2 stores the frame-base (instead of the + function) location in a function's symbol. Oops! For the + moment enable this when/where applicable. */ + SYMBOL_OPS (var)->tracepoint_var_ref (var, ax, value); + break; + case LOC_OPTIMIZED_OUT: error ("The variable `%s' has been optimized out.", - SYMBOL_SOURCE_NAME (var)); + SYMBOL_PRINT_NAME (var)); break; default: error ("Cannot find value of botched symbol `%s'.", - SYMBOL_SOURCE_NAME (var)); + SYMBOL_PRINT_NAME (var)); break; } } @@ -699,7 +713,7 @@ gen_usual_unary (struct agent_expr *ax, struct axs_value *value) the stack. Should we tweak the type? */ /* Some types require special handling. */ - switch (value->type->code) + switch (TYPE_CODE (value->type)) { /* Functions get converted to a pointer to the function. */ case TYPE_CODE_FUNC: @@ -874,7 +888,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type) /* Dereference typedefs. */ type = check_typedef (type); - switch (type->code) + switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: /* It's implementation-defined, and I'll bet this is what GCC @@ -925,9 +939,9 @@ gen_scale (struct agent_expr *ax, enum agent_op op, struct type *type) { struct type *element = TYPE_TARGET_TYPE (type); - if (element->length != 1) + if (TYPE_LENGTH (element) != 1) { - ax_const_l (ax, element->length); + ax_const_l (ax, TYPE_LENGTH (element)); ax_simple (ax, op); } } @@ -943,8 +957,8 @@ gen_add (struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2, char *name) { /* Is it INT+PTR? */ - if (value1->type->code == TYPE_CODE_INT - && value2->type->code == TYPE_CODE_PTR) + if (TYPE_CODE (value1->type) == TYPE_CODE_INT + && TYPE_CODE (value2->type) == TYPE_CODE_PTR) { /* Swap the values and proceed normally. */ ax_simple (ax, aop_swap); @@ -955,8 +969,8 @@ gen_add (struct agent_expr *ax, struct axs_value *value, } /* Is it PTR+INT? */ - else if (value1->type->code == TYPE_CODE_PTR - && value2->type->code == TYPE_CODE_INT) + else if (TYPE_CODE (value1->type) == TYPE_CODE_PTR + && TYPE_CODE (value2->type) == TYPE_CODE_INT) { gen_scale (ax, aop_mul, value1->type); ax_simple (ax, aop_add); @@ -966,8 +980,8 @@ gen_add (struct agent_expr *ax, struct axs_value *value, /* Must be number + number; the usual binary conversions will have brought them both to the same width. */ - else if (value1->type->code == TYPE_CODE_INT - && value2->type->code == TYPE_CODE_INT) + else if (TYPE_CODE (value1->type) == TYPE_CODE_INT + && TYPE_CODE (value2->type) == TYPE_CODE_INT) { ax_simple (ax, aop_add); gen_extend (ax, value1->type); /* Catch overflow. */ @@ -989,10 +1003,10 @@ static void gen_sub (struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2) { - if (value1->type->code == TYPE_CODE_PTR) + if (TYPE_CODE (value1->type) == TYPE_CODE_PTR) { /* Is it PTR - INT? */ - if (value2->type->code == TYPE_CODE_INT) + if (TYPE_CODE (value2->type) == TYPE_CODE_INT) { gen_scale (ax, aop_mul, value1->type); ax_simple (ax, aop_sub); @@ -1003,7 +1017,7 @@ gen_sub (struct agent_expr *ax, struct axs_value *value, /* Is it PTR - PTR? Strictly speaking, the types ought to match, but this is what the normal GDB expression evaluator tests for. */ - else if (value2->type->code == TYPE_CODE_PTR + else if (TYPE_CODE (value2->type) == TYPE_CODE_PTR && (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type)) == TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type)))) { @@ -1018,8 +1032,8 @@ an integer nor a pointer of the same type."); } /* Must be number + number. */ - else if (value1->type->code == TYPE_CODE_INT - && value2->type->code == TYPE_CODE_INT) + else if (TYPE_CODE (value1->type) == TYPE_CODE_INT + && TYPE_CODE (value2->type) == TYPE_CODE_INT) { ax_simple (ax, aop_sub); gen_extend (ax, value1->type); /* Catch overflow. */ @@ -1044,8 +1058,8 @@ gen_binop (struct agent_expr *ax, struct axs_value *value, enum agent_op op_unsigned, int may_carry, char *name) { /* We only handle INT op INT. */ - if ((value1->type->code != TYPE_CODE_INT) - || (value2->type->code != TYPE_CODE_INT)) + if ((TYPE_CODE (value1->type) != TYPE_CODE_INT) + || (TYPE_CODE (value2->type) != TYPE_CODE_INT)) error ("Illegal combination of types in %s.", name); ax_simple (ax, @@ -1092,7 +1106,7 @@ gen_deref (struct agent_expr *ax, struct axs_value *value) { /* The caller should check the type, because several operators use this, and we don't know what error message to generate. */ - if (value->type->code != TYPE_CODE_PTR) + if (TYPE_CODE (value->type) != TYPE_CODE_PTR) internal_error (__FILE__, __LINE__, "gen_deref: expected a pointer"); @@ -1102,7 +1116,7 @@ gen_deref (struct agent_expr *ax, struct axs_value *value) T" to "T", and mark the value as an lvalue in memory. Leave it to the consumer to actually dereference it. */ value->type = check_typedef (TYPE_TARGET_TYPE (value->type)); - value->kind = ((value->type->code == TYPE_CODE_FUNC) + value->kind = ((TYPE_CODE (value->type) == TYPE_CODE_FUNC) ? axs_rvalue : axs_lvalue_memory); } @@ -1114,7 +1128,7 @@ gen_address_of (struct agent_expr *ax, struct axs_value *value) /* Special case for taking the address of a function. The ANSI standard describes this as a special case, too, so this arrangement is not without motivation. */ - if (value->type->code == TYPE_CODE_FUNC) + if (TYPE_CODE (value->type) == TYPE_CODE_FUNC) /* The value's already an rvalue on the stack, so we just need to change the type. */ value->type = lookup_pointer_type (value->type); @@ -1156,7 +1170,7 @@ find_field (struct type *type, char *name) { char *this_name = TYPE_FIELD_NAME (type, i); - if (this_name && STREQ (name, this_name)) + if (this_name && strcmp (name, this_name) == 0) return i; if (this_name[0] == '\0') @@ -1346,7 +1360,7 @@ gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field, /* Follow pointers until we reach a non-pointer. These aren't the C semantics, but they're what the normal GDB evaluator does, so we should at least be consistent. */ - while (value->type->code == TYPE_CODE_PTR) + while (TYPE_CODE (value->type) == TYPE_CODE_PTR) { gen_usual_unary (ax, value); gen_deref (ax, value); @@ -1410,7 +1424,7 @@ gen_repeat (union exp_element **pc, struct agent_expr *ax, if (!v) error ("Right operand of `@' must be a constant, in agent expressions."); - if (v->type->code != TYPE_CODE_INT) + if (TYPE_CODE (v->type) != TYPE_CODE_INT) error ("Right operand of `@' must be an integer."); length = value_as_long (v); if (length <= 0) @@ -1586,7 +1600,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, (*pc) += 3; value->kind = axs_lvalue_register; value->u.reg = reg; - value->type = REGISTER_VIRTUAL_TYPE (reg); + value->type = register_type (current_gdbarch, reg); } break; @@ -1787,33 +1801,6 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr) discard_cleanups (old_chain); return ax; } - - - -/* The "agent" command, for testing: compile and disassemble an expression. */ - -static void -print_axs_value (struct ui_file *f, struct axs_value *value) -{ - switch (value->kind) - { - case axs_rvalue: - fputs_filtered ("rvalue", f); - break; - - case axs_lvalue_memory: - fputs_filtered ("memory lvalue", f); - break; - - case axs_lvalue_register: - fprintf_filtered (f, "register %d lvalue", value->u.reg); - break; - } - - fputs_filtered (" : ", f); - type_print (value->type, "", f, -1); -} - static void agent_command (char *exp, int from_tty) @@ -1835,7 +1822,7 @@ agent_command (char *exp, int from_tty) expr = parse_expression (exp); old_chain = make_cleanup (free_current_contents, &expr); - agent = gen_trace_for_expr (fi->pc, expr); + agent = gen_trace_for_expr (get_frame_pc (fi), expr); make_cleanup_free_agent_expr (agent); ax_print (gdb_stdout, agent); diff --git a/contrib/gdb/gdb/ax-gdb.h b/contrib/gdb/gdb/ax-gdb.h index 3e1006a3112..b0913840306 100644 --- a/contrib/gdb/gdb/ax-gdb.h +++ b/contrib/gdb/gdb/ax-gdb.h @@ -20,7 +20,8 @@ #ifndef AX_GDB_H #define AX_GDB_H - + +struct expression; /* Types and enums */ diff --git a/contrib/gdb/gdb/ax-general.c b/contrib/gdb/gdb/ax-general.c index 9451837b97e..c36c76ddf10 100644 --- a/contrib/gdb/gdb/ax-general.c +++ b/contrib/gdb/gdb/ax-general.c @@ -27,6 +27,7 @@ #include "ax.h" #include "value.h" +#include "gdb_string.h" static void grow_expr (struct agent_expr *x, int n); diff --git a/contrib/gdb/gdb/bcache.c b/contrib/gdb/gdb/bcache.c index 73b86e8cf53..cadadb5cce6 100644 --- a/contrib/gdb/gdb/bcache.c +++ b/contrib/gdb/gdb/bcache.c @@ -2,7 +2,7 @@ Written by Fred Fish Rewritten by Jim Blandy - Copyright 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -22,13 +22,76 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "bcache.h" #include "gdb_string.h" /* For memcpy declaration */ +#include "gdb_assert.h" #include #include +/* The type used to hold a single bcache string. The user data is + stored in d.data. Since it can be any type, it needs to have the + same alignment as the most strict alignment of any type on the host + machine. I don't know of any really correct way to do this in + stock ANSI C, so just do it the same way obstack.h does. */ + +struct bstring +{ + /* Hash chain. */ + struct bstring *next; + /* Assume the data length is no more than 64k. */ + unsigned short length; + /* The half hash hack. This contains the upper 16 bits of the hash + value and is used as a pre-check when comparing two strings and + avoids the need to do length or memcmp calls. It proves to be + roughly 100% effective. */ + unsigned short half_hash; + + union + { + char data[1]; + double dummy; + } + d; +}; + + +/* The structure for a bcache itself. The bcache is initialized, in + bcache_xmalloc(), by filling it with zeros and then setting the + corresponding obstack's malloc() and free() methods. */ + +struct bcache +{ + /* All the bstrings are allocated here. */ + struct obstack cache; + + /* How many hash buckets we're using. */ + unsigned int num_buckets; + + /* Hash buckets. This table is allocated using malloc, so when we + grow the table we can return the old table to the system. */ + struct bstring **bucket; + + /* Statistics. */ + unsigned long unique_count; /* number of unique strings */ + long total_count; /* total number of strings cached, including dups */ + long unique_size; /* size of unique strings, in bytes */ + long total_size; /* total number of bytes cached, including dups */ + long structure_size; /* total size of bcache, including infrastructure */ + /* Number of times that the hash table is expanded and hence + re-built, and the corresponding number of times that a string is + [re]hashed as part of entering it into the expanded table. The + total number of hashes can be computed by adding TOTAL_COUNT to + expand_hash_count. */ + unsigned long expand_count; + unsigned long expand_hash_count; + /* Number of times that the half-hash compare hit (compare the upper + 16 bits of hash values) hit, but the corresponding combined + length/data compare missed. */ + unsigned long half_hash_miss_count; +}; + /* The old hash function was stolen from SDBM. This is what DB 3.0 uses now, * and is better than the old one. */ @@ -73,6 +136,11 @@ expand_hash_table (struct bcache *bcache) struct bstring **new_buckets; unsigned int i; + /* Count the stats. Every unique item needs to be re-hashed and + re-entered. */ + bcache->expand_count++; + bcache->expand_hash_count += bcache->unique_count; + /* Find the next size. */ new_num_buckets = bcache->num_buckets * 2; for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++) @@ -127,9 +195,11 @@ expand_hash_table (struct bcache *bcache) /* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has never seen those bytes before, add a copy of them to BCACHE. In either case, return a pointer to BCACHE's copy of that string. */ -void * -bcache (const void *addr, int length, struct bcache *bcache) +static void * +bcache_data (const void *addr, int length, struct bcache *bcache) { + unsigned long full_hash; + unsigned short half_hash; int hash_index; struct bstring *s; @@ -140,13 +210,24 @@ bcache (const void *addr, int length, struct bcache *bcache) bcache->total_count++; bcache->total_size += length; - hash_index = hash (addr, length) % bcache->num_buckets; + full_hash = hash (addr, length); + half_hash = (full_hash >> 16); + hash_index = full_hash % bcache->num_buckets; - /* Search the hash bucket for a string identical to the caller's. */ + /* Search the hash bucket for a string identical to the caller's. + As a short-circuit first compare the upper part of each hash + values. */ for (s = bcache->bucket[hash_index]; s; s = s->next) - if (s->length == length - && ! memcmp (&s->d.data, addr, length)) - return &s->d.data; + { + if (s->half_hash == half_hash) + { + if (s->length == length + && ! memcmp (&s->d.data, addr, length)) + return &s->d.data; + else + bcache->half_hash_miss_count++; + } + } /* The user's string isn't in the list. Insert it after *ps. */ { @@ -155,6 +236,7 @@ bcache (const void *addr, int length, struct bcache *bcache) memcpy (&new->d.data, addr, length); new->length = length; new->next = bcache->bucket[hash_index]; + new->half_hash = half_hash; bcache->bucket[hash_index] = new; bcache->unique_count++; @@ -165,20 +247,41 @@ bcache (const void *addr, int length, struct bcache *bcache) } } +void * +deprecated_bcache (const void *addr, int length, struct bcache *bcache) +{ + return bcache_data (addr, length, bcache); +} + +const void * +bcache (const void *addr, int length, struct bcache *bcache) +{ + return bcache_data (addr, length, bcache); +} -/* Freeing bcaches. */ +/* Allocating and freeing bcaches. */ + +struct bcache * +bcache_xmalloc (void) +{ + /* Allocate the bcache pre-zeroed. */ + struct bcache *b = XCALLOC (1, struct bcache); + /* We could use obstack_specify_allocation here instead, but + gdb_obstack.h specifies the allocation/deallocation + functions. */ + obstack_init (&b->cache); + return b; +} /* Free all the storage associated with BCACHE. */ void -free_bcache (struct bcache *bcache) +bcache_xfree (struct bcache *bcache) { + if (bcache == NULL) + return; obstack_free (&bcache->cache, 0); - if (bcache->bucket) - xfree (bcache->bucket); - - /* This isn't necessary, but at least the bcache is always in a - consistent state. */ - memset (bcache, 0, sizeof (*bcache)); + xfree (bcache->bucket); + xfree (bcache); } @@ -214,12 +317,16 @@ print_bcache_statistics (struct bcache *c, char *type) int occupied_buckets; int max_chain_length; int median_chain_length; + int max_entry_size; + int median_entry_size; - /* Count the number of occupied buckets, and measure chain lengths. */ + /* Count the number of occupied buckets, tally the various string + lengths, and measure chain lengths. */ { unsigned int b; - int *chain_length - = (int *) alloca (c->num_buckets * sizeof (*chain_length)); + int *chain_length = XCALLOC (c->num_buckets + 1, int); + int *entry_size = XCALLOC (c->unique_count + 1, int); + int stringi = 0; occupied_buckets = 0; @@ -235,7 +342,10 @@ print_bcache_statistics (struct bcache *c, char *type) while (s) { + gdb_assert (b < c->num_buckets); chain_length[b]++; + gdb_assert (stringi < c->unique_count); + entry_size[stringi++] = s->length; s = s->next; } } @@ -244,6 +354,8 @@ print_bcache_statistics (struct bcache *c, char *type) /* To compute the median, we need the set of chain lengths sorted. */ qsort (chain_length, c->num_buckets, sizeof (chain_length[0]), compare_ints); + qsort (entry_size, c->unique_count, sizeof (entry_size[0]), + compare_ints); if (c->num_buckets > 0) { @@ -255,6 +367,19 @@ print_bcache_statistics (struct bcache *c, char *type) max_chain_length = 0; median_chain_length = 0; } + if (c->unique_count > 0) + { + max_entry_size = entry_size[c->unique_count - 1]; + median_entry_size = entry_size[c->unique_count / 2]; + } + else + { + max_entry_size = 0; + median_entry_size = 0; + } + + xfree (chain_length); + xfree (entry_size); } printf_filtered (" Cached '%s' statistics:\n", type); @@ -270,6 +395,15 @@ print_bcache_statistics (struct bcache *c, char *type) print_percentage (c->total_size - c->unique_size, c->total_size); printf_filtered ("\n"); + printf_filtered (" Max entry size: %d\n", max_entry_size); + printf_filtered (" Average entry size: "); + if (c->unique_count > 0) + printf_filtered ("%ld\n", c->unique_size / c->unique_count); + else + printf_filtered ("(not applicable)\n"); + printf_filtered (" Median entry size: %d\n", median_entry_size); + printf_filtered ("\n"); + printf_filtered (" Total memory used by bcache, including overhead: %ld\n", c->structure_size); printf_filtered (" Percentage memory overhead: "); @@ -279,6 +413,12 @@ print_bcache_statistics (struct bcache *c, char *type) printf_filtered ("\n"); printf_filtered (" Hash table size: %3d\n", c->num_buckets); + printf_filtered (" Hash table expands: %lu\n", + c->expand_count); + printf_filtered (" Hash table hashes: %lu\n", + c->total_count + c->expand_hash_count); + printf_filtered (" Half hash misses: %lu\n", + c->half_hash_miss_count); printf_filtered (" Hash table population: "); print_percentage (occupied_buckets, c->num_buckets); printf_filtered (" Median hash chain length: %3d\n", @@ -291,3 +431,9 @@ print_bcache_statistics (struct bcache *c, char *type) printf_filtered (" Maximum hash chain length: %3d\n", max_chain_length); printf_filtered ("\n"); } + +int +bcache_memory_used (struct bcache *bcache) +{ + return obstack_memory_used (&bcache->cache); +} diff --git a/contrib/gdb/gdb/bcache.h b/contrib/gdb/gdb/bcache.h index 2b03ead5a34..bf69853f21d 100644 --- a/contrib/gdb/gdb/bcache.h +++ b/contrib/gdb/gdb/bcache.h @@ -1,7 +1,8 @@ /* Include file cached obstack implementation. Written by Fred Fish Rewritten by Jim Blandy - Copyright 1999, 2000 Free Software Foundation, Inc. + + Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -47,84 +48,123 @@ You shouldn't modify the strings you get from a bcache, because: - You don't necessarily know who you're sharing space with. If I - stick eight bytes of text in a bcache, and then stick an - eight-byte structure in the same bcache, there's no guarantee - those two objects don't actually comprise the same sequence of - bytes. If they happen to, the bcache will use a single byte - string for both of them. Then, modifying the structure will - change the string. In bizarre ways. + stick eight bytes of text in a bcache, and then stick an eight-byte + structure in the same bcache, there's no guarantee those two + objects don't actually comprise the same sequence of bytes. If + they happen to, the bcache will use a single byte string for both + of them. Then, modifying the structure will change the string. In + bizarre ways. - Even if you know for some other reason that all that's okay, - there's another problem. A bcache stores all its strings in a - hash table. If you modify a string's contents, you will probably - change its hash value. This means that the modified string is - now in the wrong place in the hash table, and future bcache - probes will never find it. So by mutating a string, you give up - any chance of sharing its space with future duplicates. */ + there's another problem. A bcache stores all its strings in a hash + table. If you modify a string's contents, you will probably change + its hash value. This means that the modified string is now in the + wrong place in the hash table, and future bcache probes will never + find it. So by mutating a string, you give up any chance of + sharing its space with future duplicates. -/* The type used to hold a single bcache string. The user data is - stored in d.data. Since it can be any type, it needs to have the - same alignment as the most strict alignment of any type on the host - machine. I don't know of any really correct way to do this in - stock ANSI C, so just do it the same way obstack.h does. + Size of bcache VS hashtab: - It would be nicer to have this stuff hidden away in bcache.c, but - struct objstack contains a struct bcache directly --- not a pointer - to one --- and then the memory-mapped stuff makes this a real pain. - We don't strictly need to expose struct bstring, but it's better to - have it all in one place. */ + For bcache, the most critical cost is size (or more exactly the + overhead added by the bcache). It turns out that the bcache is + remarkably efficient. -struct bstring { - struct bstring *next; - size_t length; + Assuming a 32-bit system (the hash table slots are 4 bytes), + ignoring alignment, and limit strings to 255 bytes (1 byte length) + we get ... - union - { - char data[1]; - double dummy; - } - d; -}; + bcache: This uses a separate linked list to track the hash chain. + The numbers show roughly 100% occupancy of the hash table and an + average chain length of 4. Spreading the slot cost over the 4 + chain elements: + + 4 (slot) / 4 (chain length) + 1 (length) + 4 (chain) = 6 bytes + + hashtab: This uses a more traditional re-hash algorithm where the + chain is maintained within the hash table. The table occupancy is + kept below 75% but we'll assume its perfect: + + 4 (slot) x 4/3 (occupancy) + 1 (length) = 6 1/3 bytes + + So a perfect hashtab has just slightly larger than an average + bcache. + + It turns out that an average hashtab is far worse. Two things + hurt: + + - Hashtab's occupancy is more like 50% (it ranges between 38% and + 75%) giving a per slot cost of 4x2 vs 4x4/3. + + - the string structure needs to be aligned to 8 bytes which for + hashtab wastes 7 bytes, while for bcache wastes only 3. + + This gives: + + hashtab: 4 x 2 + 1 + 7 = 16 bytes + + bcache 4 / 4 + 1 + 4 + 3 = 9 bytes + + The numbers of GDB debugging GDB support this. ~40% vs ~70% overhead. -/* The structure for a bcache itself. - To initialize a bcache, just fill it with zeros. */ -struct bcache { - /* All the bstrings are allocated here. */ - struct obstack cache; + Speed of bcache VS hashtab (the half hash hack): - /* How many hash buckets we're using. */ - unsigned int num_buckets; + While hashtab has a typical chain length of 1, bcache has a chain + length of round 4. This means that the bcache will require + something like double the number of compares after that initial + hash. In both cases the comparison takes the form: + + a.length == b.length && memcmp (a.data, b.data, a.length) == 0 + + That is lengths are checked before doing the memcmp. + + For GDB debugging GDB, it turned out that all lengths were 24 bytes + (no C++ so only psymbols were cached) and hence, all compares + required a call to memcmp. As a hack, two bytes of padding + (mentioned above) are used to store the upper 16 bits of the + string's hash value and then that is used in the comparison vis: + + a.half_hash == b.half_hash && a.length == b.length && memcmp + (a.data, b.data, a.length) + + The numbers from GDB debugging GDB show this to be a remarkable + 100% effective (only necessary length and memcmp tests being + performed). + + Mind you, looking at the wall clock, the same GDB debugging GDB + showed only marginal speed up (0.780 vs 0.773s). Seems GDB is too + busy doing something else :-( - /* Hash buckets. This table is allocated using malloc, so when we - grow the table we can return the old table to the system. */ - struct bstring **bucket; +*/ - /* Statistics. */ - unsigned long unique_count; /* number of unique strings */ - long total_count; /* total number of strings cached, including dups */ - long unique_size; /* size of unique strings, in bytes */ - long total_size; /* total number of bytes cached, including dups */ - long structure_size; /* total size of bcache, including infrastructure */ -}; +struct bcache; /* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has never seen those bytes before, add a copy of them to BCACHE. In - either case, return a pointer to BCACHE's copy of that string. */ -extern void *bcache (const void *addr, int length, struct bcache *bcache); + either case, return a pointer to BCACHE's copy of that string. + Since the cached value is ment to be read-only, return a const + buffer. */ +extern void *deprecated_bcache (const void *addr, int length, + struct bcache *bcache); +extern const void *bcache (const void *addr, int length, + struct bcache *bcache); -/* Free all the storage that BCACHE refers to. The result is a valid, - but empty, bcache. This does not free BCACHE itself, since that - might be part of some larger object. */ -extern void free_bcache (struct bcache *bcache); +/* Free all the storage used by BCACHE. */ +extern void bcache_xfree (struct bcache *bcache); + +/* Create a new bcache object. */ +extern struct bcache *bcache_xmalloc (void); /* Print statistics on BCACHE's memory usage and efficacity at eliminating duplication. TYPE should be a string describing the kind of data BCACHE holds. Statistics are printed using `printf_filtered' and its ilk. */ extern void print_bcache_statistics (struct bcache *bcache, char *type); +extern int bcache_memory_used (struct bcache *bcache); + /* The hash function */ extern unsigned long hash(const void *addr, int length); + #endif /* BCACHE_H */ diff --git a/contrib/gdb/gdb/bfd-target.c b/contrib/gdb/gdb/bfd-target.c new file mode 100644 index 00000000000..ee16d85f52a --- /dev/null +++ b/contrib/gdb/gdb/bfd-target.c @@ -0,0 +1,131 @@ +/* Very simple "bfd" target, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "target.h" +#include "bfd-target.h" +#include "gdb_assert.h" +#include "gdb_string.h" + +/* Locate all mappable sections of a BFD file, filling in a target + section for each. */ + +struct section_closure +{ + struct section_table *end; +}; + +static void +add_to_section_table (struct bfd *abfd, struct bfd_section *asect, + void *closure) +{ + struct section_closure *pp = closure; + flagword aflag; + + /* NOTE: cagney/2003-10-22: Is this pruning useful? */ + aflag = bfd_get_section_flags (abfd, asect); + if (!(aflag & SEC_ALLOC)) + return; + if (bfd_section_size (abfd, asect) == 0) + return; + pp->end->bfd = abfd; + pp->end->the_bfd_section = asect; + pp->end->addr = bfd_section_vma (abfd, asect); + pp->end->endaddr = pp->end->addr + bfd_section_size (abfd, asect); + pp->end++; +} + +void +build_target_sections_from_bfd (struct target_ops *targ, struct bfd *abfd) +{ + unsigned count; + struct section_table *start; + struct section_closure cl; + + count = bfd_count_sections (abfd); + target_resize_to_sections (targ, count); + start = targ->to_sections; + cl.end = targ->to_sections; + bfd_map_over_sections (abfd, add_to_section_table, &cl); + gdb_assert (cl.end - start <= count); +} + +LONGEST +target_bfd_xfer_partial (struct target_ops *ops, + enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + switch (object) + { + case TARGET_OBJECT_MEMORY: + { + struct section_table *s = target_section_by_addr (ops, offset); + if (s == NULL) + return -1; + /* If the length extends beyond the section, truncate it. Be + careful to not suffer from overflow (wish S contained a + length). */ + if ((offset - s->addr + len) > (s->endaddr - s->addr)) + len = (s->endaddr - s->addr) - (offset - s->addr); + if (readbuf != NULL + && !bfd_get_section_contents (s->bfd, s->the_bfd_section, + readbuf, offset - s->addr, len)) + return -1; +#if 1 + if (writebuf != NULL) + return -1; +#else + /* FIXME: cagney/2003-10-31: The BFD interface doesn't yet + take a const buffer. */ + if (writebuf != NULL + && !bfd_set_section_contents (s->bfd, s->the_bfd_section, + writebuf, offset - s->addr, len)) + return -1; +#endif + return len; + } + default: + return -1; + } +} + +void +target_bfd_xclose (struct target_ops *t, int quitting) +{ + bfd_close (t->to_data); + xfree (t->to_sections); + xfree (t); +} + +struct target_ops * +target_bfd_reopen (struct bfd *bfd) +{ + struct target_ops *t = XZALLOC (struct target_ops); + t->to_shortname = "bfd"; + t->to_longname = "BFD backed target"; + t->to_doc = "You should never see this"; + t->to_xfer_partial = target_bfd_xfer_partial; + t->to_xclose = target_bfd_xclose; + t->to_data = bfd; + build_target_sections_from_bfd (t, bfd); + return t; +} diff --git a/contrib/gdb/gdb/bfd-target.h b/contrib/gdb/gdb/bfd-target.h new file mode 100644 index 00000000000..61a51c8a88a --- /dev/null +++ b/contrib/gdb/gdb/bfd-target.h @@ -0,0 +1,39 @@ +/* Very simple "bfd" target, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef BFD_TARGET_H +#define BFD_TARGET_H + +struct bfd; +struct target_ops; + +/* Given an existing BFD, re-open it as a "struct target_ops". On + close, it will also close the corresponding BFD (which is like + freopen and fdopen). */ +struct target_ops *target_bfd_reopen (struct bfd *bfd); + +/* Map over ABFD's sections, creating corresponding entries in the + target's section table. */ + +void build_target_sections_from_bfd (struct target_ops *targ, + struct bfd *abfd); + +#endif diff --git a/contrib/gdb/gdb/block.c b/contrib/gdb/gdb/block.c new file mode 100644 index 00000000000..28b1181ffe8 --- /dev/null +++ b/contrib/gdb/gdb/block.c @@ -0,0 +1,295 @@ +/* Block-related functions for the GNU debugger, GDB. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "block.h" +#include "symtab.h" +#include "symfile.h" +#include "gdb_obstack.h" +#include "cp-support.h" + +/* This is used by struct block to store namespace-related info for + C++ files, namely using declarations and the current namespace in + scope. */ + +struct block_namespace_info +{ + const char *scope; + struct using_direct *using; +}; + +static void block_initialize_namespace (struct block *block, + struct obstack *obstack); + +/* Return Nonzero if block a is lexically nested within block b, + or if a and b have the same pc range. + Return zero otherwise. */ + +int +contained_in (const struct block *a, const struct block *b) +{ + if (!a || !b) + return 0; + return BLOCK_START (a) >= BLOCK_START (b) + && BLOCK_END (a) <= BLOCK_END (b); +} + + +/* Return the symbol for the function which contains a specified + lexical block, described by a struct block BL. */ + +struct symbol * +block_function (const struct block *bl) +{ + while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0) + bl = BLOCK_SUPERBLOCK (bl); + + return BLOCK_FUNCTION (bl); +} + +/* Return the blockvector immediately containing the innermost lexical block + containing the specified pc value and section, or 0 if there is none. + PINDEX is a pointer to the index value of the block. If PINDEX + is NULL, we don't pass this information back to the caller. */ + +struct blockvector * +blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section, + int *pindex, struct symtab *symtab) +{ + struct block *b; + int bot, top, half; + struct blockvector *bl; + + if (symtab == 0) /* if no symtab specified by caller */ + { + /* First search all symtabs for one whose file contains our pc */ + symtab = find_pc_sect_symtab (pc, section); + if (symtab == 0) + return 0; + } + + bl = BLOCKVECTOR (symtab); + b = BLOCKVECTOR_BLOCK (bl, 0); + + /* Then search that symtab for the smallest block that wins. */ + /* Use binary search to find the last block that starts before PC. */ + + bot = 0; + top = BLOCKVECTOR_NBLOCKS (bl); + + while (top - bot > 1) + { + half = (top - bot + 1) >> 1; + b = BLOCKVECTOR_BLOCK (bl, bot + half); + if (BLOCK_START (b) <= pc) + bot += half; + else + top = bot + half; + } + + /* Now search backward for a block that ends after PC. */ + + while (bot >= 0) + { + b = BLOCKVECTOR_BLOCK (bl, bot); + if (BLOCK_END (b) > pc) + { + if (pindex) + *pindex = bot; + return bl; + } + bot--; + } + return 0; +} + +/* Return the blockvector immediately containing the innermost lexical block + containing the specified pc value, or 0 if there is none. + Backward compatibility, no section. */ + +struct blockvector * +blockvector_for_pc (CORE_ADDR pc, int *pindex) +{ + return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc), + pindex, NULL); +} + +/* Return the innermost lexical block containing the specified pc value + in the specified section, or 0 if there is none. */ + +struct block * +block_for_pc_sect (CORE_ADDR pc, struct bfd_section *section) +{ + struct blockvector *bl; + int index; + + bl = blockvector_for_pc_sect (pc, section, &index, NULL); + if (bl) + return BLOCKVECTOR_BLOCK (bl, index); + return 0; +} + +/* Return the innermost lexical block containing the specified pc value, + or 0 if there is none. Backward compatibility, no section. */ + +struct block * +block_for_pc (CORE_ADDR pc) +{ + return block_for_pc_sect (pc, find_pc_mapped_section (pc)); +} + +/* Now come some functions designed to deal with C++ namespace issues. + The accessors are safe to use even in the non-C++ case. */ + +/* This returns the namespace that BLOCK is enclosed in, or "" if it + isn't enclosed in a namespace at all. This travels the chain of + superblocks looking for a scope, if necessary. */ + +const char * +block_scope (const struct block *block) +{ + for (; block != NULL; block = BLOCK_SUPERBLOCK (block)) + { + if (BLOCK_NAMESPACE (block) != NULL + && BLOCK_NAMESPACE (block)->scope != NULL) + return BLOCK_NAMESPACE (block)->scope; + } + + return ""; +} + +/* Set BLOCK's scope member to SCOPE; if needed, allocate memory via + OBSTACK. (It won't make a copy of SCOPE, however, so that already + has to be allocated correctly.) */ + +void +block_set_scope (struct block *block, const char *scope, + struct obstack *obstack) +{ + block_initialize_namespace (block, obstack); + + BLOCK_NAMESPACE (block)->scope = scope; +} + +/* This returns the first using directives associated to BLOCK, if + any. */ + +/* FIXME: carlton/2003-04-23: This uses the fact that we currently + only have using directives in static blocks, because we only + generate using directives from anonymous namespaces. Eventually, + when we support using directives everywhere, we'll want to replace + this by some iterator functions. */ + +struct using_direct * +block_using (const struct block *block) +{ + const struct block *static_block = block_static_block (block); + + if (static_block == NULL + || BLOCK_NAMESPACE (static_block) == NULL) + return NULL; + else + return BLOCK_NAMESPACE (static_block)->using; +} + +/* Set BLOCK's using member to USING; if needed, allocate memory via + OBSTACK. (It won't make a copy of USING, however, so that already + has to be allocated correctly.) */ + +void +block_set_using (struct block *block, + struct using_direct *using, + struct obstack *obstack) +{ + block_initialize_namespace (block, obstack); + + BLOCK_NAMESPACE (block)->using = using; +} + +/* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and + ititialize its members to zero. */ + +static void +block_initialize_namespace (struct block *block, struct obstack *obstack) +{ + if (BLOCK_NAMESPACE (block) == NULL) + { + BLOCK_NAMESPACE (block) + = obstack_alloc (obstack, sizeof (struct block_namespace_info)); + BLOCK_NAMESPACE (block)->scope = NULL; + BLOCK_NAMESPACE (block)->using = NULL; + } +} + +/* Return the static block associated to BLOCK. Return NULL if block + is NULL or if block is a global block. */ + +const struct block * +block_static_block (const struct block *block) +{ + if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL) + return NULL; + + while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL) + block = BLOCK_SUPERBLOCK (block); + + return block; +} + +/* Return the static block associated to BLOCK. Return NULL if block + is NULL. */ + +const struct block * +block_global_block (const struct block *block) +{ + if (block == NULL) + return NULL; + + while (BLOCK_SUPERBLOCK (block) != NULL) + block = BLOCK_SUPERBLOCK (block); + + return block; +} + +/* Allocate a block on OBSTACK, and initialize its elements to + zero/NULL. This is useful for creating "dummy" blocks that don't + correspond to actual source files. + + Warning: it sets the block's BLOCK_DICT to NULL, which isn't a + valid value. If you really don't want the block to have a + dictionary, then you should subsequently set its BLOCK_DICT to + dict_create_linear (obstack, NULL). */ + +struct block * +allocate_block (struct obstack *obstack) +{ + struct block *bl = obstack_alloc (obstack, sizeof (struct block)); + + BLOCK_START (bl) = 0; + BLOCK_END (bl) = 0; + BLOCK_FUNCTION (bl) = NULL; + BLOCK_SUPERBLOCK (bl) = NULL; + BLOCK_DICT (bl) = NULL; + BLOCK_NAMESPACE (bl) = NULL; + BLOCK_GCC_COMPILED (bl) = 0; + + return bl; +} diff --git a/contrib/gdb/gdb/block.h b/contrib/gdb/gdb/block.h new file mode 100644 index 00000000000..a36821305ca --- /dev/null +++ b/contrib/gdb/gdb/block.h @@ -0,0 +1,174 @@ +/* Code dealing with blocks for GDB. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef BLOCK_H +#define BLOCK_H + +/* Opaque declarations. */ + +struct symbol; +struct symtab; +struct block_namespace_info; +struct using_direct; +struct obstack; +struct dictionary; + +/* All of the name-scope contours of the program + are represented by `struct block' objects. + All of these objects are pointed to by the blockvector. + + Each block represents one name scope. + Each lexical context has its own block. + + The blockvector begins with some special blocks. + The GLOBAL_BLOCK contains all the symbols defined in this compilation + whose scope is the entire program linked together. + The STATIC_BLOCK contains all the symbols whose scope is the + entire compilation excluding other separate compilations. + Blocks starting with the FIRST_LOCAL_BLOCK are not special. + + Each block records a range of core addresses for the code that + is in the scope of the block. The STATIC_BLOCK and GLOBAL_BLOCK + give, for the range of code, the entire range of code produced + by the compilation that the symbol segment belongs to. + + The blocks appear in the blockvector + in order of increasing starting-address, + and, within that, in order of decreasing ending-address. + + This implies that within the body of one function + the blocks appear in the order of a depth-first tree walk. */ + +struct block +{ + + /* Addresses in the executable code that are in this block. */ + + CORE_ADDR startaddr; + CORE_ADDR endaddr; + + /* The symbol that names this block, if the block is the body of a + function; otherwise, zero. */ + + struct symbol *function; + + /* The `struct block' for the containing block, or 0 if none. + + The superblock of a top-level local block (i.e. a function in the + case of C) is the STATIC_BLOCK. The superblock of the + STATIC_BLOCK is the GLOBAL_BLOCK. */ + + struct block *superblock; + + /* This is used to store the symbols in the block. */ + + struct dictionary *dict; + + /* Used for language-specific info. */ + + union + { + struct + { + /* Contains information about namespace-related info relevant to + this block: using directives and the current namespace + scope. */ + + struct block_namespace_info *namespace; + } + cplus_specific; + } + language_specific; + + /* Version of GCC used to compile the function corresponding + to this block, or 0 if not compiled with GCC. When possible, + GCC should be compatible with the native compiler, or if that + is not feasible, the differences should be fixed during symbol + reading. As of 16 Apr 93, this flag is never used to distinguish + between gcc2 and the native compiler. + + If there is no function corresponding to this block, this meaning + of this flag is undefined. */ + + unsigned char gcc_compile_flag; +}; + +#define BLOCK_START(bl) (bl)->startaddr +#define BLOCK_END(bl) (bl)->endaddr +#define BLOCK_FUNCTION(bl) (bl)->function +#define BLOCK_SUPERBLOCK(bl) (bl)->superblock +#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag +#define BLOCK_DICT(bl) (bl)->dict +#define BLOCK_NAMESPACE(bl) (bl)->language_specific.cplus_specific.namespace + +/* Macro to loop through all symbols in a block BL, in no particular + order. ITER helps keep track of the iteration, and should be a + struct dict_iterator. SYM points to the current symbol. */ + +#define ALL_BLOCK_SYMBOLS(block, iter, sym) \ + ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym) + +struct blockvector +{ + /* Number of blocks in the list. */ + int nblocks; + /* The blocks themselves. */ + struct block *block[1]; +}; + +#define BLOCKVECTOR_NBLOCKS(blocklist) (blocklist)->nblocks +#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n] + +/* Special block numbers */ + +enum { GLOBAL_BLOCK = 0, STATIC_BLOCK = 1, FIRST_LOCAL_BLOCK = 2 }; + +extern struct symbol *block_function (const struct block *); + +extern int contained_in (const struct block *, const struct block *); + +extern struct blockvector *blockvector_for_pc (CORE_ADDR, int *); + +extern struct blockvector *blockvector_for_pc_sect (CORE_ADDR, asection *, + int *, struct symtab *); + +extern struct block *block_for_pc (CORE_ADDR); + +extern struct block *block_for_pc_sect (CORE_ADDR, asection *); + +extern const char *block_scope (const struct block *block); + +extern void block_set_scope (struct block *block, const char *scope, + struct obstack *obstack); + +extern struct using_direct *block_using (const struct block *block); + +extern void block_set_using (struct block *block, + struct using_direct *using, + struct obstack *obstack); + +extern const struct block *block_static_block (const struct block *block); + +extern const struct block *block_global_block (const struct block *block); + +extern struct block *allocate_block (struct obstack *obstack); + +#endif /* BLOCK_H */ diff --git a/contrib/gdb/gdb/blockframe.c b/contrib/gdb/gdb/blockframe.c index 1f10381a7e6..265bd2e82f1 100644 --- a/contrib/gdb/gdb/blockframe.c +++ b/contrib/gdb/gdb/blockframe.c @@ -1,7 +1,9 @@ -/* Get info from stack frames; - convert between frames, blocks, functions and pc values. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* Get info from stack frames; convert between frames, blocks, + functions and pc values. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GDB. @@ -23,7 +25,6 @@ #include "defs.h" #include "symtab.h" #include "bfd.h" -#include "symfile.h" #include "objfiles.h" #include "frame.h" #include "gdbcore.h" @@ -32,95 +33,76 @@ #include "inferior.h" /* for read_pc */ #include "annotate.h" #include "regcache.h" +#include "gdb_assert.h" +#include "dummy-frame.h" +#include "command.h" +#include "gdbcmd.h" +#include "block.h" /* Prototypes for exported functions. */ void _initialize_blockframe (void); -/* A default FRAME_CHAIN_VALID, in the form that is suitable for most - targets. If FRAME_CHAIN_VALID returns zero it means that the given - frame is the outermost one and has no caller. */ - -int -file_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - return ((chain) != 0 - && !inside_entry_file (FRAME_SAVED_PC (thisframe))); -} - -/* Use the alternate method of avoiding running up off the end of the - frame chain or following frames back into the startup code. See - the comments in objfiles.h. */ - -int -func_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - return ((chain) != 0 - && !inside_main_func ((thisframe)->pc) - && !inside_entry_func ((thisframe)->pc)); -} - -/* A very simple method of determining a valid frame */ - -int -nonnull_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - return ((chain) != 0); -} - -/* 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 - to call this function from FRAME_CHAIN_VALID; the reason for - doing so is that some machines have no way of detecting bottom - of stack. +/* 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 to call + this function from DEPRECATED_FRAME_CHAIN_VALID; the reason for + doing so is that some machines have no way of detecting bottom of + stack. A PC of zero is always considered to be the bottom of the stack. */ int -inside_entry_file (CORE_ADDR addr) +deprecated_inside_entry_file (CORE_ADDR addr) { if (addr == 0) return 1; if (symfile_objfile == 0) return 0; - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) + if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT + || CALL_DUMMY_LOCATION == AT_SYMBOL) { /* Do not stop backtracing if the pc is in the call dummy at the entry point. */ /* FIXME: Won't always work with zeros for the last two arguments */ - if (PC_IN_CALL_DUMMY (addr, 0, 0)) + if (DEPRECATED_PC_IN_CALL_DUMMY (addr, 0, 0)) return 0; } - return (addr >= symfile_objfile->ei.entry_file_lowpc && - addr < symfile_objfile->ei.entry_file_highpc); + return (addr >= symfile_objfile->ei.deprecated_entry_file_lowpc && + addr < symfile_objfile->ei.deprecated_entry_file_highpc); } -/* Test a specified PC value to see if it is in the range of addresses - that correspond to the main() function. See comments above for why - we might want to do this. - - Typically called from FRAME_CHAIN_VALID. - - A PC of zero is always considered to be the bottom of the stack. */ +/* Test whether PC is in the range of addresses that corresponds to + the "main" function. */ int inside_main_func (CORE_ADDR pc) { - if (pc == 0) - return 1; + struct minimal_symbol *msymbol; + if (symfile_objfile == 0) return 0; - /* If the addr range is not set up at symbol reading time, set it up now. - This is for FRAME_CHAIN_VALID_ALTERNATE. I do this for coff, because - it is unable to set it up and symbol reading time. */ + msymbol = lookup_minimal_symbol (main_name (), NULL, symfile_objfile); - if (symfile_objfile->ei.main_func_lowpc == INVALID_ENTRY_LOWPC && - symfile_objfile->ei.main_func_highpc == INVALID_ENTRY_HIGHPC) + /* If the address range hasn't been set up at symbol reading time, + set it up now. */ + + if (msymbol != NULL + && symfile_objfile->ei.main_func_lowpc == INVALID_ENTRY_LOWPC + && symfile_objfile->ei.main_func_highpc == INVALID_ENTRY_HIGHPC) { - struct symbol *mainsym; + /* brobecker/2003-10-10: We used to rely on lookup_symbol() to + search the symbol associated to the "main" function. + Unfortunately, lookup_symbol() uses the current-language + la_lookup_symbol_nonlocal function to do the global symbol + search. Depending on the language, this can introduce + certain side-effects, because certain languages, for instance + Ada, may find more than one match. Therefore we prefer to + search the "main" function symbol using its address rather + than its name. */ + struct symbol *mainsym = + find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol)); - mainsym = lookup_symbol (main_name (), NULL, VAR_NAMESPACE, NULL, NULL); if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK) { symfile_objfile->ei.main_func_lowpc = @@ -129,165 +111,105 @@ inside_main_func (CORE_ADDR pc) BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym)); } } - return (symfile_objfile->ei.main_func_lowpc <= pc && - symfile_objfile->ei.main_func_highpc > pc); + + /* Not in the normal symbol tables, see if "main" is in the partial + symbol table. If it's not, then give up. */ + if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_text) + { + CORE_ADDR maddr = SYMBOL_VALUE_ADDRESS (msymbol); + asection *msect = SYMBOL_BFD_SECTION (msymbol); + struct obj_section *osect = find_pc_sect_section (maddr, msect); + + if (osect != NULL) + { + int i; + + /* Step over other symbols at this same address, and symbols + in other sections, to find the next symbol in this + section with a different address. */ + for (i = 1; SYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++) + { + if (SYMBOL_VALUE_ADDRESS (msymbol + i) != maddr + && SYMBOL_BFD_SECTION (msymbol + i) == msect) + break; + } + + symfile_objfile->ei.main_func_lowpc = maddr; + + /* Use the lesser of the next minimal symbol in the same + section, or the end of the section, as the end of the + function. */ + if (SYMBOL_LINKAGE_NAME (msymbol + i) != NULL + && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr) + symfile_objfile->ei.main_func_highpc = + SYMBOL_VALUE_ADDRESS (msymbol + i); + else + /* We got the start address from the last msymbol in the + objfile. So the end address is the end of the + section. */ + symfile_objfile->ei.main_func_highpc = osect->endaddr; + } + } + + return (symfile_objfile->ei.main_func_lowpc <= pc + && symfile_objfile->ei.main_func_highpc > pc); } -/* Test a specified PC value to see if it is in the range of addresses - that correspond to the process entry point function. See comments - in objfiles.h for why we might want to do this. - - Typically called from FRAME_CHAIN_VALID. - - A PC of zero is always considered to be the bottom of the stack. */ +/* Test whether THIS_FRAME is inside the process entry point function. */ int -inside_entry_func (CORE_ADDR pc) +inside_entry_func (struct frame_info *this_frame) +{ + return (get_frame_func (this_frame) == entry_point_address ()); +} + +/* Similar to inside_entry_func, but accomodating legacy frame code. */ + +static int +legacy_inside_entry_func (CORE_ADDR pc) { - if (pc == 0) - return 1; if (symfile_objfile == 0) return 0; + if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) { - /* Do not stop backtracing if the pc is in the call dummy - at the entry point. */ - /* FIXME: Won't always work with zeros for the last two arguments */ - if (PC_IN_CALL_DUMMY (pc, 0, 0)) + /* Do not stop backtracing if the program counter is in the call + dummy at the entry point. */ + /* FIXME: This won't always work with zeros for the last two + arguments. */ + if (DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0)) return 0; } - return (symfile_objfile->ei.entry_func_lowpc <= pc && - symfile_objfile->ei.entry_func_highpc > pc); + + return (symfile_objfile->ei.entry_func_lowpc <= pc + && symfile_objfile->ei.entry_func_highpc > pc); } -/* Info about the innermost stack frame (contents of FP register) */ - -static struct frame_info *current_frame; - -/* Cache for frame addresses already read by gdb. Valid only while - inferior is stopped. Control variables for the frame cache should - be local to this module. */ - -static struct obstack frame_cache_obstack; - -void * -frame_obstack_alloc (unsigned long size) -{ - return obstack_alloc (&frame_cache_obstack, size); -} - -void -frame_saved_regs_zalloc (struct frame_info *fi) -{ - fi->saved_regs = (CORE_ADDR *) - frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS); - memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS); -} - - -/* Return the innermost (currently executing) stack frame. */ - -struct frame_info * -get_current_frame (void) -{ - if (current_frame == NULL) - { - if (target_has_stack) - current_frame = create_new_frame (read_fp (), read_pc ()); - else - error ("No stack."); - } - return current_frame; -} - -void -set_current_frame (struct frame_info *frame) -{ - current_frame = frame; -} - -/* Create an arbitrary (i.e. address specified by user) or innermost frame. - Always returns a non-NULL value. */ - -struct frame_info * -create_new_frame (CORE_ADDR addr, CORE_ADDR pc) -{ - struct frame_info *fi; - char *name; - - fi = (struct frame_info *) - obstack_alloc (&frame_cache_obstack, - sizeof (struct frame_info)); - - /* Zero all fields by default. */ - memset (fi, 0, sizeof (struct frame_info)); - - fi->frame = addr; - fi->pc = pc; - find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL); - fi->signal_handler_caller = IN_SIGTRAMP (fi->pc, name); - - if (INIT_EXTRA_FRAME_INFO_P ()) - INIT_EXTRA_FRAME_INFO (0, fi); - - return fi; -} - -/* Return the frame that FRAME calls (NULL if FRAME is the innermost - frame). */ - -struct frame_info * -get_next_frame (struct frame_info *frame) -{ - return frame->next; -} - -/* Flush the entire frame cache. */ - -void -flush_cached_frames (void) -{ - /* Since we can't really be sure what the first object allocated was */ - obstack_free (&frame_cache_obstack, 0); - obstack_init (&frame_cache_obstack); - - current_frame = NULL; /* Invalidate cache */ - select_frame (NULL, -1); - annotate_frames_invalid (); -} - -/* Flush the frame cache, and start a new one if necessary. */ - -void -reinit_frame_cache (void) -{ - flush_cached_frames (); - - /* FIXME: The inferior_ptid test is wrong if there is a corefile. */ - if (PIDGET (inferior_ptid) != 0) - { - select_frame (get_current_frame (), 0); - } -} - -/* Return nonzero if the function for this frame lacks a prologue. Many - machines can define FRAMELESS_FUNCTION_INVOCATION to just call this - function. */ +/* Return nonzero if the function for this frame lacks a prologue. + Many machines can define DEPRECATED_FRAMELESS_FUNCTION_INVOCATION + to just call this function. */ int -frameless_look_for_prologue (struct frame_info *frame) +legacy_frameless_look_for_prologue (struct frame_info *frame) { - CORE_ADDR func_start, after_prologue; + CORE_ADDR func_start; - func_start = get_pc_function_start (frame->pc); + func_start = get_frame_func (frame); if (func_start) { func_start += FUNCTION_START_OFFSET; - /* This is faster, since only care whether there *is* a - prologue, not how long it is. */ - return PROLOGUE_FRAMELESS_P (func_start); + /* NOTE: cagney/2004-02-09: Eliminated per-architecture + PROLOGUE_FRAMELESS_P call as architectures with custom + implementations had all been deleted. Eventually even this + function can go - GDB no longer tries to differentiate + between framed, frameless and stackless functions. They are + all now considered equally evil :-^. */ + /* If skipping the prologue ends up skips nothing, there must be + no prologue and hence no code creating a frame. There for + the function is "frameless" :-/. */ + return func_start == SKIP_PROLOGUE (func_start); } - else if (frame->pc == 0) + else if (get_frame_pc (frame) == 0) /* A frame with a zero PC is usually created by dereferencing a NULL function pointer, normally causing an immediate core dump of the inferior. Mark function as frameless, as the inferior @@ -301,257 +223,61 @@ frameless_look_for_prologue (struct frame_info *frame) return 0; } -/* Default a few macros that people seldom redefine. */ - -#ifndef FRAME_CHAIN_COMBINE -#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) -#endif - -/* Return a structure containing various interesting information - about the frame that called NEXT_FRAME. Returns NULL - if there is no such frame. */ - -struct frame_info * -get_prev_frame (struct frame_info *next_frame) -{ - CORE_ADDR address = 0; - struct frame_info *prev; - int fromleaf = 0; - char *name; - - /* If the requested entry is in the cache, return it. - Otherwise, figure out what the address should be for the entry - we're about to add to the cache. */ - - if (!next_frame) - { -#if 0 - /* This screws value_of_variable, which just wants a nice clean - NULL return from block_innermost_frame if there are no frames. - I don't think I've ever seen this message happen otherwise. - And returning NULL here is a perfectly legitimate thing to do. */ - if (!current_frame) - { - error ("You haven't set up a process's stack to examine."); - } -#endif - - return current_frame; - } - - /* If we have the prev one, return it */ - if (next_frame->prev) - return next_frame->prev; - - /* On some machines it is possible to call a function without - setting up a stack frame for it. On these machines, we - define this macro to take two args; a frameinfo pointer - identifying a frame and a variable to set or clear if it is - or isn't leafless. */ - - /* Still don't want to worry about this except on the innermost - frame. This macro will set FROMLEAF if NEXT_FRAME is a - frameless function invocation. */ - if (!(next_frame->next)) - { - fromleaf = FRAMELESS_FUNCTION_INVOCATION (next_frame); - if (fromleaf) - address = FRAME_FP (next_frame); - } - - if (!fromleaf) - { - /* Two macros defined in tm.h specify the machine-dependent - actions to be performed here. - First, get the frame's chain-pointer. - If that is zero, the frame is the outermost frame or a leaf - called by the outermost frame. This means that if start - calls main without a frame, we'll return 0 (which is fine - anyway). - - Nope; there's a problem. This also returns when the current - routine is a leaf of main. This is unacceptable. We move - this to after the ffi test; I'd rather have backtraces from - start go curfluy than have an abort called from main not show - main. */ - address = FRAME_CHAIN (next_frame); - if (!FRAME_CHAIN_VALID (address, next_frame)) - return 0; - address = FRAME_CHAIN_COMBINE (address, next_frame); - } - if (address == 0) - return 0; - - prev = (struct frame_info *) - obstack_alloc (&frame_cache_obstack, - sizeof (struct frame_info)); - - /* Zero all fields by default. */ - memset (prev, 0, sizeof (struct frame_info)); - - if (next_frame) - next_frame->prev = prev; - prev->next = next_frame; - prev->frame = address; - -/* This change should not be needed, FIXME! We should - determine whether any targets *need* INIT_FRAME_PC to happen - after INIT_EXTRA_FRAME_INFO and come up with a simple way to - express what goes on here. - - INIT_EXTRA_FRAME_INFO is called from two places: create_new_frame - (where the PC is already set up) and here (where it isn't). - INIT_FRAME_PC is only called from here, always after - INIT_EXTRA_FRAME_INFO. - - The catch is the MIPS, where INIT_EXTRA_FRAME_INFO requires the PC - value (which hasn't been set yet). Some other machines appear to - require INIT_EXTRA_FRAME_INFO before they can do INIT_FRAME_PC. Phoo. - - We shouldn't need INIT_FRAME_PC_FIRST to add more complication to - an already overcomplicated part of GDB. gnu@cygnus.com, 15Sep92. - - Assuming that some machines need INIT_FRAME_PC after - INIT_EXTRA_FRAME_INFO, one possible scheme: - - SETUP_INNERMOST_FRAME() - Default version is just create_new_frame (read_fp ()), - read_pc ()). Machines with extra frame info would do that (or the - local equivalent) and then set the extra fields. - SETUP_ARBITRARY_FRAME(argc, argv) - 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. 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, 31Jan94, 14Dec94. */ - - INIT_FRAME_PC_FIRST (fromleaf, prev); - - if (INIT_EXTRA_FRAME_INFO_P ()) - INIT_EXTRA_FRAME_INFO (fromleaf, prev); - - /* This entry is in the frame queue now, which is good since - 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)) - prev->signal_handler_caller = 1; - - return prev; -} - -CORE_ADDR -get_frame_pc (struct frame_info *frame) -{ - return frame->pc; -} - - -#ifdef FRAME_FIND_SAVED_REGS -/* XXX - deprecated. This is a compatibility function for targets - that do not yet implement FRAME_INIT_SAVED_REGS. */ -/* Find the addresses in which registers are saved in FRAME. */ - -void -get_frame_saved_regs (struct frame_info *frame, - struct frame_saved_regs *saved_regs_addr) -{ - if (frame->saved_regs == NULL) - { - frame->saved_regs = (CORE_ADDR *) - frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS); - } - if (saved_regs_addr == NULL) - { - struct frame_saved_regs saved_regs; - FRAME_FIND_SAVED_REGS (frame, saved_regs); - memcpy (frame->saved_regs, &saved_regs, SIZEOF_FRAME_SAVED_REGS); - } - else - { - FRAME_FIND_SAVED_REGS (frame, *saved_regs_addr); - memcpy (frame->saved_regs, saved_regs_addr, SIZEOF_FRAME_SAVED_REGS); - } -} -#endif - /* Return the innermost lexical block in execution - in a specified stack frame. The frame address is assumed valid. */ + in a specified stack frame. The frame address is assumed valid. + + If ADDR_IN_BLOCK is non-zero, set *ADDR_IN_BLOCK to the exact code + address we used to choose the block. We use this to find a source + line, to decide which macro definitions are in scope. + + The value returned in *ADDR_IN_BLOCK isn't necessarily the frame's + PC, and may not really be a valid PC at all. For example, in the + caller of a function declared to never return, the code at the + return address will never be reached, so the call instruction may + be the very last instruction in the block. So the address we use + to choose the block is actually one byte before the return address + --- hopefully pointing us at the call instruction, or its delay + slot instruction. */ struct block * -get_frame_block (struct frame_info *frame) +get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block) { - CORE_ADDR pc; + const CORE_ADDR pc = get_frame_address_in_block (frame); + + if (addr_in_block) + *addr_in_block = pc; - pc = frame->pc; - if (frame->next != 0 && frame->next->signal_handler_caller == 0) - /* We are not in the innermost frame and we were not interrupted - by a signal. We need to subtract one to get the correct block, - in case the call instruction was the last instruction of the block. - If there are any machines on which the saved pc does not point to - after the call insn, we probably want to make frame->pc point after - the call insn anyway. */ - --pc; return block_for_pc (pc); } -struct block * -get_current_block (void) -{ - return block_for_pc (read_pc ()); -} - CORE_ADDR get_pc_function_start (CORE_ADDR pc) { - register struct block *bl; - register struct symbol *symbol; - register struct minimal_symbol *msymbol; - CORE_ADDR fstart; + struct block *bl; + struct minimal_symbol *msymbol; - if ((bl = block_for_pc (pc)) != NULL && - (symbol = block_function (bl)) != NULL) + bl = block_for_pc (pc); + if (bl) { - bl = SYMBOL_BLOCK_VALUE (symbol); - fstart = BLOCK_START (bl); + struct symbol *symbol = block_function (bl); + + if (symbol) + { + bl = SYMBOL_BLOCK_VALUE (symbol); + return BLOCK_START (bl); + } } - else if ((msymbol = lookup_minimal_symbol_by_pc (pc)) != NULL) + + msymbol = lookup_minimal_symbol_by_pc (pc); + if (msymbol) { - fstart = SYMBOL_VALUE_ADDRESS (msymbol); + CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol); + + if (find_pc_section (fstart)) + return fstart; } - else - { - fstart = 0; - } - return (fstart); + + return 0; } /* Return the symbol for the function executing in frame FRAME. */ @@ -559,110 +285,20 @@ get_pc_function_start (CORE_ADDR pc) struct symbol * get_frame_function (struct frame_info *frame) { - register struct block *bl = get_frame_block (frame); + struct block *bl = get_frame_block (frame, 0); if (bl == 0) return 0; return block_function (bl); } -/* Return the blockvector immediately containing the innermost lexical block - containing the specified pc value and section, or 0 if there is none. - PINDEX is a pointer to the index value of the block. If PINDEX - is NULL, we don't pass this information back to the caller. */ - -struct blockvector * -blockvector_for_pc_sect (register CORE_ADDR pc, struct sec *section, - int *pindex, struct symtab *symtab) -{ - register struct block *b; - register int bot, top, half; - struct blockvector *bl; - - if (symtab == 0) /* if no symtab specified by caller */ - { - /* First search all symtabs for one whose file contains our pc */ - if ((symtab = find_pc_sect_symtab (pc, section)) == 0) - return 0; - } - - bl = BLOCKVECTOR (symtab); - b = BLOCKVECTOR_BLOCK (bl, 0); - - /* Then search that symtab for the smallest block that wins. */ - /* Use binary search to find the last block that starts before PC. */ - - bot = 0; - top = BLOCKVECTOR_NBLOCKS (bl); - - while (top - bot > 1) - { - half = (top - bot + 1) >> 1; - b = BLOCKVECTOR_BLOCK (bl, bot + half); - if (BLOCK_START (b) <= pc) - bot += half; - else - top = bot + half; - } - - /* Now search backward for a block that ends after PC. */ - - while (bot >= 0) - { - b = BLOCKVECTOR_BLOCK (bl, bot); - if (BLOCK_END (b) > pc) - { - if (pindex) - *pindex = bot; - return bl; - } - bot--; - } - return 0; -} - -/* Return the blockvector immediately containing the innermost lexical block - containing the specified pc value, or 0 if there is none. - Backward compatibility, no section. */ - -struct blockvector * -blockvector_for_pc (register CORE_ADDR pc, int *pindex) -{ - return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc), - pindex, NULL); -} - -/* Return the innermost lexical block containing the specified pc value - in the specified section, or 0 if there is none. */ - -struct block * -block_for_pc_sect (register CORE_ADDR pc, struct sec *section) -{ - register struct blockvector *bl; - int index; - - bl = blockvector_for_pc_sect (pc, section, &index, NULL); - if (bl) - return BLOCKVECTOR_BLOCK (bl, index); - return 0; -} - -/* Return the innermost lexical block containing the specified pc value, - or 0 if there is none. Backward compatibility, no section. */ - -struct block * -block_for_pc (register CORE_ADDR pc) -{ - return block_for_pc_sect (pc, find_pc_mapped_section (pc)); -} - /* Return the function containing pc value PC in section SECTION. Returns 0 if function is not known. */ struct symbol * -find_pc_sect_function (CORE_ADDR pc, struct sec *section) +find_pc_sect_function (CORE_ADDR pc, struct bfd_section *section) { - register struct block *b = block_for_pc_sect (pc, section); + struct block *b = block_for_pc_sect (pc, section); if (b == 0) return 0; return block_function (b); @@ -683,7 +319,7 @@ find_pc_function (CORE_ADDR pc) static CORE_ADDR cache_pc_function_low = 0; static CORE_ADDR cache_pc_function_high = 0; static char *cache_pc_function_name = 0; -static struct sec *cache_pc_function_section = NULL; +static struct bfd_section *cache_pc_function_section = NULL; /* Clear cache, e.g. when symbol table is discarded. */ @@ -721,15 +357,14 @@ find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name, mapped_pc = overlay_mapped_address (pc, section); - if (mapped_pc >= cache_pc_function_low && - mapped_pc < cache_pc_function_high && - section == cache_pc_function_section) + if (mapped_pc >= cache_pc_function_low + && mapped_pc < cache_pc_function_high + && section == cache_pc_function_section) goto return_cached_value; /* If sigtramp is in the u area, it counts as a function (especially important for step_1). */ -#if defined SIGTRAMP_START - if (IN_SIGTRAMP (mapped_pc, (char *) NULL)) + if (SIGTRAMP_START_P () && PC_IN_SIGTRAMP (mapped_pc, (char *) NULL)) { cache_pc_function_low = SIGTRAMP_START (mapped_pc); cache_pc_function_high = SIGTRAMP_END (mapped_pc); @@ -737,7 +372,6 @@ find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name, cache_pc_function_section = section; goto return_cached_value; } -#endif msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section); pst = find_pc_sect_psymtab (mapped_pc, section); @@ -764,7 +398,7 @@ find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name, { cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f)); cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f)); - cache_pc_function_name = SYMBOL_NAME (f); + cache_pc_function_name = DEPRECATED_SYMBOL_NAME (f); cache_pc_function_section = section; goto return_cached_value; } @@ -785,7 +419,7 @@ find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name, if (address) *address = SYMBOL_VALUE_ADDRESS (psb); if (name) - *name = SYMBOL_NAME (psb); + *name = DEPRECATED_SYMBOL_NAME (psb); /* endaddr non-NULL can't happen here. */ return 1; } @@ -816,7 +450,7 @@ find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name, } cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol); - cache_pc_function_name = SYMBOL_NAME (msymbol); + cache_pc_function_name = DEPRECATED_SYMBOL_NAME (msymbol); cache_pc_function_section = section; /* Use the lesser of the next minimal symbol in the same section, or @@ -826,14 +460,14 @@ find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name, other sections, to find the next symbol in this section with a different address. */ - for (i = 1; SYMBOL_NAME (msymbol + i) != NULL; i++) + for (i = 1; DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL; i++) { if (SYMBOL_VALUE_ADDRESS (msymbol + i) != SYMBOL_VALUE_ADDRESS (msymbol) - && SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol)) + && SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol)) break; } - if (SYMBOL_NAME (msymbol + i) != NULL + if (DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr) cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i); else @@ -841,7 +475,7 @@ find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name, So the end address is the end of the section. */ cache_pc_function_high = osect->endaddr; -return_cached_value: + return_cached_value: if (address) { @@ -860,8 +494,8 @@ return_cached_value: { /* Because the high address is actually beyond the end of the function (and therefore possibly beyond the end of - the overlay), we must actually convert (high - 1) - and then add one to that. */ + the overlay), we must actually convert (high - 1) and + then add one to that. */ *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1, section); @@ -873,16 +507,30 @@ return_cached_value: return 1; } -/* Backward compatibility, no section argument */ +/* Backward compatibility, no section argument. */ int find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address, CORE_ADDR *endaddr) { - asection *section; + struct bfd_section *bfd_section; - section = find_pc_overlay (pc); - return find_pc_sect_partial_function (pc, section, name, address, endaddr); + /* To ensure that the symbol returned belongs to the correct setion + (and that the last [random] symbol from the previous section + isn't returned) try to find the section containing PC. First try + the overlay code (which by default returns NULL); and second try + the normal section code (which almost always succeeds). */ + bfd_section = find_pc_overlay (pc); + if (bfd_section == NULL) + { + struct obj_section *obj_section = find_pc_section (pc); + if (obj_section == NULL) + bfd_section = NULL; + else + bfd_section = obj_section->the_bfd_section; + } + return find_pc_sect_partial_function (pc, bfd_section, name, address, + endaddr); } /* Return the innermost stack frame executing inside of BLOCK, @@ -892,8 +540,9 @@ struct frame_info * block_innermost_frame (struct block *block) { struct frame_info *frame; - register CORE_ADDR start; - register CORE_ADDR end; + CORE_ADDR start; + CORE_ADDR end; + CORE_ADDR calling_pc; if (block == NULL) return NULL; @@ -907,97 +556,28 @@ block_innermost_frame (struct block *block) frame = get_prev_frame (frame); if (frame == NULL) return NULL; - if (frame->pc >= start && frame->pc < end) + calling_pc = get_frame_address_in_block (frame); + if (calling_pc >= start && calling_pc < end) return frame; } } -/* Return the full FRAME which corresponds to the given CORE_ADDR - or NULL if no FRAME on the chain corresponds to CORE_ADDR. */ - -struct frame_info * -find_frame_addr_in_frame_chain (CORE_ADDR frame_addr) -{ - struct frame_info *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. */ - -CORE_ADDR -sigtramp_saved_pc (struct frame_info *frame) -{ - CORE_ADDR sigcontext_addr; - char *buf; - int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT; - int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT; - - buf = alloca (ptrbytes); - /* Get sigcontext address, it is the third parameter on the stack. */ - if (frame->next) - sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next) - + FRAME_ARGS_SKIP - + sigcontext_offs, - ptrbytes); - else - sigcontext_addr = read_memory_integer (read_register (SP_REGNUM) - + sigcontext_offs, - ptrbytes); - - /* Don't cause a memory_error when accessing sigcontext in case the stack - layout has changed or the stack is corrupt. */ - target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes); - return extract_unsigned_integer (buf, ptrbytes); -} -#endif /* SIGCONTEXT_PC_OFFSET */ - - /* Are we in a call dummy? The code below which allows DECR_PC_AFTER_BREAK below is for infrun.c, which may give the macro a pc without that subtracted out. */ -extern CORE_ADDR text_end; - -int -pc_in_call_dummy_before_text_end (CORE_ADDR pc, CORE_ADDR sp, - CORE_ADDR frame_address) -{ - return ((pc) >= text_end - CALL_DUMMY_LENGTH - && (pc) <= text_end + DECR_PC_AFTER_BREAK); -} - -int -pc_in_call_dummy_after_text_end (CORE_ADDR pc, CORE_ADDR sp, - CORE_ADDR frame_address) -{ - return ((pc) >= text_end - && (pc) <= text_end + CALL_DUMMY_LENGTH + DECR_PC_AFTER_BREAK); -} - /* Is the PC in a call dummy? SP and FRAME_ADDRESS are the bottom and top of the stack frame which we are checking, where "bottom" and "top" refer to some section of memory which contains the code for the call dummy. Calls to this macro assume that the contents of - SP_REGNUM and FP_REGNUM (or the saved values thereof), respectively, - are the things to pass. + SP_REGNUM and DEPRECATED_FP_REGNUM (or the saved values thereof), + respectively, are the things to pass. - This won't work on the 29k, where SP_REGNUM and FP_REGNUM don't - have that meaning, but the 29k doesn't use ON_STACK. This could be - fixed by generalizing this scheme, perhaps by passing in a frame - and adding a few fields, at least on machines which need them for - PC_IN_CALL_DUMMY. + This won't work on the 29k, where SP_REGNUM and + DEPRECATED_FP_REGNUM don't have that meaning, but the 29k doesn't + use ON_STACK. This could be fixed by generalizing this scheme, + perhaps by passing in a frame and adding a few fields, at least on + machines which need them for DEPRECATED_PC_IN_CALL_DUMMY. Something simpler, like checking for the stack segment, doesn't work, since various programs (threads implementations, gcc nested function @@ -1005,7 +585,8 @@ pc_in_call_dummy_after_text_end (CORE_ADDR pc, CORE_ADDR sp, allocate other kinds of code on the stack. */ int -pc_in_call_dummy_on_stack (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address) +deprecated_pc_in_call_dummy_on_stack (CORE_ADDR pc, CORE_ADDR sp, + CORE_ADDR frame_address) { return (INNER_THAN ((sp), (pc)) && (frame_address != 0) @@ -1013,313 +594,50 @@ pc_in_call_dummy_on_stack (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address) } int -pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp, - CORE_ADDR frame_address) +deprecated_pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp, + CORE_ADDR frame_address) { - return ((pc) >= CALL_DUMMY_ADDRESS () - && (pc) <= (CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK)); + CORE_ADDR addr = entry_point_address (); + return ((pc) >= addr && (pc) <= (addr + DECR_PC_AFTER_BREAK)); } +/* Returns true for a user frame or a call_function_by_hand dummy + frame, and false for the CRT0 start-up frame. Purpose is to + terminate backtrace. */ -/* - * GENERIC DUMMY FRAMES - * - * The following code serves to maintain the dummy stack frames for - * inferior function calls (ie. when gdb calls into the inferior via - * call_function_by_hand). This code saves the machine state before - * the call in host memory, so we must maintain an independent stack - * and keep it consistant etc. I am attempting to make this code - * generic enough to be used by many targets. - * - * The cheapest and most generic way to do CALL_DUMMY on a new target - * is probably to define CALL_DUMMY to be empty, CALL_DUMMY_LENGTH to - * zero, and CALL_DUMMY_LOCATION to AT_ENTRY. Then you must remember - * to define PUSH_RETURN_ADDRESS, because no call instruction will be - * being executed by the target. Also FRAME_CHAIN_VALID as - * generic_{file,func}_frame_chain_valid and FIX_CALL_DUMMY as - * generic_fix_call_dummy. */ - -/* Dummy frame. This saves the processor state just prior to setting - up the inferior function call. Older targets save the registers - on the target stack (but that really slows down function calls). */ - -struct dummy_frame +int +legacy_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) { - struct dummy_frame *next; + /* Don't prune CALL_DUMMY frames. */ + if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES + && DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0)) + return 1; - CORE_ADDR pc; - CORE_ADDR fp; - CORE_ADDR sp; - CORE_ADDR top; - char *registers; -}; + /* If the new frame pointer is zero, then it isn't valid. */ + if (fp == 0) + return 0; + + /* If the new frame would be inside (younger than) the previous frame, + then it isn't valid. */ + if (INNER_THAN (fp, get_frame_base (fi))) + return 0; + + /* If the architecture has a custom DEPRECATED_FRAME_CHAIN_VALID, + call it now. */ + if (DEPRECATED_FRAME_CHAIN_VALID_P ()) + return DEPRECATED_FRAME_CHAIN_VALID (fp, fi); -static struct dummy_frame *dummy_frame_stack = NULL; - -/* Function: find_dummy_frame(pc, fp, sp) - Search the stack of dummy frames for one matching the given PC, FP and SP. - This is the work-horse for pc_in_call_dummy and read_register_dummy */ - -char * -generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp) -{ - struct dummy_frame *dummyframe; - - if (pc != entry_point_address ()) + /* If we're already inside the entry function for the main objfile, then it + isn't valid. */ + if (legacy_inside_entry_func (get_frame_pc (fi))) return 0; - for (dummyframe = dummy_frame_stack; dummyframe != NULL; - dummyframe = dummyframe->next) - if (fp == dummyframe->fp - || fp == dummyframe->sp - || fp == dummyframe->top) - /* The frame in question lies between the saved fp and sp, inclusive */ - return dummyframe->registers; + /* If we're inside the entry file, it isn't valid. */ + /* NOTE/drow 2002-12-25: should there be a way to disable this check? It + assumes a single small entry file, and the way some debug readers (e.g. + dbxread) figure out which object is the entry file is somewhat hokey. */ + if (deprecated_inside_entry_file (frame_pc_unwind (fi))) + return 0; - return 0; -} - -/* Function: pc_in_call_dummy (pc, fp) - Return true if this is a dummy frame created by gdb for an inferior call */ - -int -generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp) -{ - /* if find_dummy_frame succeeds, then PC is in a call dummy */ - /* Note: SP and not FP is passed on. */ - return (generic_find_dummy_frame (pc, sp) != 0); -} - -/* Function: read_register_dummy - Find a saved register from before GDB calls a function in the inferior */ - -CORE_ADDR -generic_read_register_dummy (CORE_ADDR pc, CORE_ADDR fp, int regno) -{ - char *dummy_regs = generic_find_dummy_frame (pc, fp); - - if (dummy_regs) - return extract_address (&dummy_regs[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno)); - else - return 0; -} - -/* Save all the registers on the dummy frame stack. Most ports save the - registers on the target stack. This results in lots of unnecessary memory - references, which are slow when debugging via a serial line. Instead, we - save all the registers internally, and never write them to the stack. The - registers get restored when the called function returns to the entry point, - where a breakpoint is laying in wait. */ - -void -generic_push_dummy_frame (void) -{ - struct dummy_frame *dummy_frame; - CORE_ADDR fp = (get_current_frame ())->frame; - - /* check to see if there are stale dummy frames, - perhaps left over from when a longjump took us out of a - function that was called by the debugger */ - - dummy_frame = dummy_frame_stack; - while (dummy_frame) - if (INNER_THAN (dummy_frame->fp, fp)) /* stale -- destroy! */ - { - dummy_frame_stack = dummy_frame->next; - xfree (dummy_frame->registers); - xfree (dummy_frame); - dummy_frame = dummy_frame_stack; - } - else - dummy_frame = dummy_frame->next; - - dummy_frame = xmalloc (sizeof (struct dummy_frame)); - dummy_frame->registers = xmalloc (REGISTER_BYTES); - - dummy_frame->pc = read_pc (); - dummy_frame->sp = read_sp (); - dummy_frame->top = dummy_frame->sp; - dummy_frame->fp = fp; - read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES); - dummy_frame->next = dummy_frame_stack; - dummy_frame_stack = dummy_frame; -} - -void -generic_save_dummy_frame_tos (CORE_ADDR sp) -{ - dummy_frame_stack->top = sp; -} - -/* Restore the machine state from either the saved dummy stack or a - real stack frame. */ - -void -generic_pop_current_frame (void (*popper) (struct frame_info * frame)) -{ - struct frame_info *frame = get_current_frame (); - - if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - generic_pop_dummy_frame (); - else - (*popper) (frame); -} - -/* Function: pop_dummy_frame - Restore the machine state from a saved dummy stack frame. */ - -void -generic_pop_dummy_frame (void) -{ - struct dummy_frame *dummy_frame = dummy_frame_stack; - - /* FIXME: what if the first frame isn't the right one, eg.. - because one call-by-hand function has done a longjmp into another one? */ - - if (!dummy_frame) - error ("Can't pop dummy frame!"); - dummy_frame_stack = dummy_frame->next; - write_register_bytes (0, dummy_frame->registers, REGISTER_BYTES); - flush_cached_frames (); - - xfree (dummy_frame->registers); - xfree (dummy_frame); -} - -/* Function: frame_chain_valid - Returns true for a user frame or a call_function_by_hand dummy frame, - and false for the CRT0 start-up frame. Purpose is to terminate backtrace */ - -int -generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) -{ - if (PC_IN_CALL_DUMMY (FRAME_SAVED_PC (fi), fp, fp)) - return 1; /* don't prune CALL_DUMMY frames */ - else /* fall back to default algorithm (see frame.h) */ - return (fp != 0 - && (INNER_THAN (fi->frame, fp) || fi->frame == fp) - && !inside_entry_file (FRAME_SAVED_PC (fi))); -} - -int -generic_func_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) -{ - if (PC_IN_CALL_DUMMY ((fi)->pc, fp, fp)) - return 1; /* don't prune CALL_DUMMY frames */ - else /* fall back to default algorithm (see frame.h) */ - return (fp != 0 - && (INNER_THAN (fi->frame, fp) || fi->frame == fp) - && !inside_main_func ((fi)->pc) - && !inside_entry_func ((fi)->pc)); -} - -/* Function: fix_call_dummy - Stub function. Generic dummy frames typically do not need to fix - the frame being created */ - -void -generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - return; -} - -/* Function: get_saved_register - Find register number REGNUM relative to FRAME and put its (raw, - target format) contents in *RAW_BUFFER. - - Set *OPTIMIZED if the variable was optimized out (and thus can't be - fetched). Note that this is never set to anything other than zero - in this implementation. - - Set *LVAL to lval_memory, lval_register, or not_lval, depending on - whether the value was fetched from memory, from a register, or in a - strange and non-modifiable way (e.g. a frame pointer which was - calculated rather than fetched). We will use not_lval for values - fetched from generic dummy frames. - - Set *ADDRP to the address, either in memory or as a REGISTER_BYTE - offset into the registers array. If the value is stored in a dummy - frame, set *ADDRP to zero. - - To use this implementation, define a function called - "get_saved_register" in your target code, which simply passes all - of its arguments to this function. - - The argument RAW_BUFFER must point to aligned memory. */ - -void -generic_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp, - struct frame_info *frame, int regnum, - enum lval_type *lval) -{ - if (!target_has_registers) - error ("No registers."); - - /* Normal systems don't optimize out things with register numbers. */ - if (optimized != NULL) - *optimized = 0; - - if (addrp) /* default assumption: not found in memory */ - *addrp = 0; - - /* Note: since the current frame's registers could only have been - saved by frames INTERIOR TO the current frame, we skip examining - the current frame itself: otherwise, we would be getting the - previous frame's registers which were saved by the current frame. */ - - while (frame && ((frame = frame->next) != NULL)) - { - if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - { - if (lval) /* found it in a CALL_DUMMY frame */ - *lval = not_lval; - if (raw_buffer) - memcpy (raw_buffer, - generic_find_dummy_frame (frame->pc, frame->frame) + - REGISTER_BYTE (regnum), - REGISTER_RAW_SIZE (regnum)); - return; - } - - FRAME_INIT_SAVED_REGS (frame); - if (frame->saved_regs != NULL - && frame->saved_regs[regnum] != 0) - { - if (lval) /* found it saved on the stack */ - *lval = lval_memory; - if (regnum == SP_REGNUM) - { - if (raw_buffer) /* SP register treated specially */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), - frame->saved_regs[regnum]); - } - else - { - if (addrp) /* any other register */ - *addrp = frame->saved_regs[regnum]; - if (raw_buffer) - read_memory (frame->saved_regs[regnum], raw_buffer, - REGISTER_RAW_SIZE (regnum)); - } - return; - } - } - - /* If we get thru the loop to this point, it means the register was - not saved in any frame. Return the actual live-register value. */ - - if (lval) /* found it in a live register */ - *lval = lval_register; - if (addrp) - *addrp = REGISTER_BYTE (regnum); - if (raw_buffer) - read_register_gen (regnum, raw_buffer); -} - -void -_initialize_blockframe (void) -{ - obstack_init (&frame_cache_obstack); + return 1; } diff --git a/contrib/gdb/gdb/breakpoint.c b/contrib/gdb/gdb/breakpoint.c index 640505eab58..933d90226dd 100644 --- a/contrib/gdb/gdb/breakpoint.c +++ b/contrib/gdb/gdb/breakpoint.c @@ -1,8 +1,8 @@ /* Everything about breakpoints, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GDB. @@ -41,10 +41,14 @@ #include "annotate.h" #include "symfile.h" #include "objfiles.h" +#include "source.h" #include "linespec.h" #include "completer.h" #include "gdb.h" #include "ui-out.h" +#include "cli/cli-script.h" +#include "gdb_assert.h" +#include "block.h" #include "gdb-events.h" @@ -70,16 +74,12 @@ static void map_breakpoint_numbers (char *, void (*)(struct breakpoint *)); static void ignore_command (char *, int); -static int breakpoint_re_set_one (PTR); +static int breakpoint_re_set_one (void *); static void clear_command (char *, int); static void catch_command (char *, int); -static void handle_gnu_4_16_catch_command (char *, int, int); - -static struct symtabs_and_lines get_catch_sals (int); - static void watch_command (char *, int); static int can_use_hardware_watchpoint (struct value *); @@ -89,7 +89,7 @@ extern void break_at_finish_at_depth_command (char *, int); extern void tbreak_at_finish_command (char *, int); -static void break_command_1 (char *, int, int); +static int break_command_1 (char *, int, int, struct breakpoint *); static void mention (struct breakpoint *); @@ -97,6 +97,10 @@ struct breakpoint *set_raw_breakpoint (struct symtab_and_line, enum bptype); static void check_duplicates (struct breakpoint *); +static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int); + +static CORE_ADDR adjust_breakpoint_address (CORE_ADDR bpaddr); + static void describe_other_breakpoints (CORE_ADDR, asection *); static void breakpoints_info (char *, int); @@ -105,9 +109,9 @@ static void breakpoint_1 (int, int); static bpstat bpstat_alloc (struct breakpoint *, bpstat); -static int breakpoint_cond_eval (PTR); +static int breakpoint_cond_eval (void *); -static void cleanup_executing_breakpoints (PTR); +static void cleanup_executing_breakpoints (void *); static void commands_command (char *, int); @@ -115,6 +119,8 @@ static void condition_command (char *, int); static int get_number_trailer (char **, int); +static int do_captured_parse_breakpoint (struct ui_out *, void *); + void set_breakpoint_count (int); typedef enum @@ -124,7 +130,7 @@ typedef enum } insertion_state_t; -static int remove_breakpoint (struct breakpoint *, insertion_state_t); +static int remove_breakpoint (struct bp_location *, insertion_state_t); static enum print_stop_action print_it_typical (bpstat); @@ -137,9 +143,9 @@ typedef struct } args_for_catchpoint_enable; -static int watchpoint_check (PTR); +static int watchpoint_check (void *); -static int cover_target_enable_exception_callback (PTR); +static int cover_target_enable_exception_callback (void *); static void maintenance_info_breakpoints (char *, int); @@ -189,10 +195,6 @@ static char *ep_parse_optional_if_clause (char **arg); static char *ep_parse_optional_filename (char **arg); -#if defined(CHILD_INSERT_EXEC_CATCHPOINT) -static void catch_exec_command_1 (char *arg, int tempflag, int from_tty); -#endif - static void create_exception_catchpoint (int tempflag, char *cond_string, enum exception_event_kind ex_event, struct symtab_and_line *sal); @@ -210,6 +212,12 @@ static void ep_skip_leading_whitespace (char **s); if such is available. */ static int can_use_hw_watchpoints; +/* If AUTO_BOOLEAN_FALSE, gdb will not attempt to create pending breakpoints. + If AUTO_BOOLEAN_TRUE, gdb will automatically create pending breakpoints + for unrecognized breakpoint locations. + If AUTO_BOOLEAN_AUTO, gdb will query when breakpoints are unrecognized. */ +static enum auto_boolean pending_break_support; + void _initialize_breakpoint (void); extern int addressprint; /* Print machine addresses? */ @@ -217,6 +225,9 @@ extern int addressprint; /* Print machine addresses? */ /* Are we executing breakpoint commands? */ static int executing_breakpoint_commands; +/* Are overlay event breakpoints enabled? */ +static int overlay_events_enabled; + /* Walk the following statement or block through all breakpoints. ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current breakpoint. */ @@ -228,24 +239,25 @@ static int executing_breakpoint_commands; B ? (TMP=B->next, 1): 0; \ B = TMP) -/* True if SHIFT_INST_REGS defined, false otherwise. */ +/* Similar iterators for the low-level breakpoints. */ -int must_shift_inst_regs = -#if defined(SHIFT_INST_REGS) -1 -#else -0 -#endif - ; +#define ALL_BP_LOCATIONS(B) for (B = bp_location_chain; B; B = B->next) + +#define ALL_BP_LOCATIONS_SAFE(B,TMP) \ + for (B = bp_location_chain; \ + B ? (TMP=B->next, 1): 0; \ + B = TMP) /* True if breakpoint hit counts should be displayed in breakpoint info. */ int show_breakpoint_hit_counts = 1; -/* Chain of all breakpoints defined. */ +/* Chains of all breakpoints defined. */ struct breakpoint *breakpoint_chain; +struct bp_location *bp_location_chain; + /* Number of last breakpoint made. */ int breakpoint_count; @@ -314,6 +326,13 @@ int exception_support_initialized = 0; error ("catch of library unloads not yet implemented on this platform") #endif +/* Return whether a breakpoint is an active enabled breakpoint. */ +static int +breakpoint_enabled (struct breakpoint *b) +{ + return (b->enable_state == bp_enabled && !b->pending); +} + /* Set breakpoint count to NUM. */ void @@ -509,9 +528,9 @@ get_number_or_range (char **pp) static void condition_command (char *arg, int from_tty) { - register struct breakpoint *b; + struct breakpoint *b; char *p; - register int bnum; + int bnum; if (arg == 0) error_no_arg ("breakpoint number"); @@ -545,24 +564,27 @@ condition_command (char *arg, int from_tty) /* I don't know if it matters whether this is the string the user typed in or the decompiled expression. */ b->cond_string = savestring (arg, strlen (arg)); - b->cond = parse_exp_1 (&arg, block_for_pc (b->address), 0); - if (*arg) - error ("Junk at end of expression"); + if (!b->pending) + { + b->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0); + if (*arg) + error ("Junk at end of expression"); + } } breakpoints_changed (); + breakpoint_modify_event (b->number); return; } error ("No breakpoint number %d.", bnum); } -/* ARGSUSED */ static void commands_command (char *arg, int from_tty) { - register struct breakpoint *b; + struct breakpoint *b; char *p; - register int bnum; + int bnum; struct command_line *l; /* If we allowed this, we would have problems with when to @@ -580,16 +602,17 @@ commands_command (char *arg, int from_tty) ALL_BREAKPOINTS (b) if (b->number == bnum) - { - char tmpbuf[128]; - sprintf (tmpbuf, - "Type commands for when breakpoint %d is hit, one per line.", - bnum); - l = read_command_lines (tmpbuf, from_tty); - free_command_lines (&b->commands); - b->commands = l; - breakpoints_changed (); - return; + { + char *tmpbuf = xstrprintf ("Type commands for when breakpoint %d is hit, one per line.", + bnum); + struct cleanup *cleanups = make_cleanup (xfree, tmpbuf); + l = read_command_lines (tmpbuf, from_tty); + do_cleanups (cleanups); + free_command_lines (&b->commands); + b->commands = l; + breakpoints_changed (); + breakpoint_modify_event (b->number); + return; } error ("No breakpoint number %d.", bnum); } @@ -606,7 +629,7 @@ int read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len) { int status; - struct breakpoint *b; + struct bp_location *b; CORE_ADDR bp_addr = 0; int bp_size = 0; @@ -614,19 +637,14 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len) /* No breakpoints on this machine. */ return target_read_memory (memaddr, myaddr, len); - ALL_BREAKPOINTS (b) + ALL_BP_LOCATIONS (b) { - if (b->type == bp_none) - warning ("reading through apparently deleted breakpoint #%d?", - b->number); + if (b->owner->type == bp_none) + warning ("reading through apparently deleted breakpoint #%d?", + b->owner->number); - /* memory breakpoint? */ - if (b->type == bp_watchpoint - || b->type == bp_hardware_watchpoint - || b->type == bp_read_watchpoint - || b->type == bp_access_watchpoint) + if (b->loc_type != bp_loc_software_breakpoint) continue; - /* bp in memory? */ if (!b->inserted) continue; /* Addresses and length of the part of the breakpoint that @@ -698,6 +716,375 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len) } +/* A wrapper function for inserting catchpoints. */ +static int +insert_catchpoint (struct ui_out *uo, void *args) +{ + struct breakpoint *b = (struct breakpoint *) args; + int val = -1; + + switch (b->type) + { + case bp_catch_fork: + val = target_insert_fork_catchpoint (PIDGET (inferior_ptid)); + break; + case bp_catch_vfork: + val = target_insert_vfork_catchpoint (PIDGET (inferior_ptid)); + break; + case bp_catch_exec: + val = target_insert_exec_catchpoint (PIDGET (inferior_ptid)); + break; + default: + internal_error (__FILE__, __LINE__, "unknown breakpoint type"); + break; + } + + if (val < 0) + throw_exception (RETURN_ERROR); + + return 0; +} + +/* Insert a low-level "breakpoint" of some type. BPT is the breakpoint. + Any error messages are printed to TMP_ERROR_STREAM; and DISABLED_BREAKS, + PROCESS_WARNING, and HW_BREAKPOINT_ERROR are used to report problems. + + NOTE drow/2003-09-09: This routine could be broken down to an object-style + method for each breakpoint or catchpoint type. */ +static int +insert_bp_location (struct bp_location *bpt, + struct ui_file *tmp_error_stream, + int *disabled_breaks, int *process_warning, + int *hw_breakpoint_error) +{ + int val = 0; + + /* Permanent breakpoints cannot be inserted or removed. Disabled + breakpoints should not be inserted. */ + if (!breakpoint_enabled (bpt->owner)) + return 0; + + if (bpt->inserted || bpt->duplicate) + return 0; + + if (bpt->loc_type == bp_loc_software_breakpoint + || bpt->loc_type == bp_loc_hardware_breakpoint) + { + /* First check to see if we have to handle an overlay. */ + if (overlay_debugging == ovly_off + || bpt->section == NULL + || !(section_is_overlay (bpt->section))) + { + /* No overlay handling: just set the breakpoint. */ + + if (bpt->loc_type == bp_loc_hardware_breakpoint) + val = target_insert_hw_breakpoint (bpt->address, + bpt->shadow_contents); + else + val = target_insert_breakpoint (bpt->address, + bpt->shadow_contents); + } + else + { + /* This breakpoint is in an overlay section. + Shall we set a breakpoint at the LMA? */ + if (!overlay_events_enabled) + { + /* Yes -- overlay event support is not active, + so we must try to set a breakpoint at the LMA. + This will not work for a hardware breakpoint. */ + if (bpt->loc_type == bp_loc_hardware_breakpoint) + warning ("hardware breakpoint %d not supported in overlay!\n", + bpt->owner->number); + else + { + CORE_ADDR addr = overlay_unmapped_address (bpt->address, + bpt->section); + /* Set a software (trap) breakpoint at the LMA. */ + val = target_insert_breakpoint (addr, bpt->shadow_contents); + if (val != 0) + fprintf_unfiltered (tmp_error_stream, + "Overlay breakpoint %d failed: in ROM?", + bpt->owner->number); + } + } + /* Shall we set a breakpoint at the VMA? */ + if (section_is_mapped (bpt->section)) + { + /* Yes. This overlay section is mapped into memory. */ + if (bpt->loc_type == bp_loc_hardware_breakpoint) + val = target_insert_hw_breakpoint (bpt->address, + bpt->shadow_contents); + else + val = target_insert_breakpoint (bpt->address, + bpt->shadow_contents); + } + else + { + /* No. This breakpoint will not be inserted. + No error, but do not mark the bp as 'inserted'. */ + return 0; + } + } + + if (val) + { + /* Can't set the breakpoint. */ +#if defined (DISABLE_UNSETTABLE_BREAK) + if (DISABLE_UNSETTABLE_BREAK (bpt->address)) + { + /* See also: disable_breakpoints_in_shlibs. */ + val = 0; + bpt->owner->enable_state = bp_shlib_disabled; + if (!*disabled_breaks) + { + fprintf_unfiltered (tmp_error_stream, + "Cannot insert breakpoint %d.\n", + bpt->owner->number); + fprintf_unfiltered (tmp_error_stream, + "Temporarily disabling shared library breakpoints:\n"); + } + *disabled_breaks = 1; + fprintf_unfiltered (tmp_error_stream, + "breakpoint #%d\n", bpt->owner->number); + } + else +#endif + { +#ifdef ONE_PROCESS_WRITETEXT + *process_warning = 1; +#endif + if (bpt->loc_type == bp_loc_hardware_breakpoint) + { + *hw_breakpoint_error = 1; + fprintf_unfiltered (tmp_error_stream, + "Cannot insert hardware breakpoint %d.\n", + bpt->owner->number); + } + else + { + fprintf_unfiltered (tmp_error_stream, + "Cannot insert breakpoint %d.\n", + bpt->owner->number); + fprintf_filtered (tmp_error_stream, + "Error accessing memory address "); + print_address_numeric (bpt->address, 1, tmp_error_stream); + fprintf_filtered (tmp_error_stream, ": %s.\n", + safe_strerror (val)); + } + + } + } + else + bpt->inserted = 1; + + return val; + } + + else if (bpt->loc_type == bp_loc_hardware_watchpoint + /* NOTE drow/2003-09-08: This state only exists for removing + watchpoints. It's not clear that it's necessary... */ + && bpt->owner->disposition != disp_del_at_next_stop) + { + /* FIXME drow/2003-09-08: This code sets multiple hardware watchpoints + based on the expression. Ideally this should happen at a higher level, + and there should be one bp_location for each computed address we + must watch. As soon as a many-to-one mapping is available I'll + convert this. */ + + struct frame_info *saved_frame; + int saved_level, within_current_scope; + struct value *mark = value_mark (); + struct value *v; + + /* Save the current frame and level so we can restore it after + evaluating the watchpoint expression on its own frame. */ + /* FIXME drow/2003-09-09: It would be nice if evaluate_expression + took a frame parameter, so that we didn't have to change the + selected frame. */ + saved_frame = deprecated_selected_frame; + saved_level = frame_relative_level (deprecated_selected_frame); + + /* Determine if the watchpoint is within scope. */ + if (bpt->owner->exp_valid_block == NULL) + within_current_scope = 1; + else + { + struct frame_info *fi; + fi = frame_find_by_id (bpt->owner->watchpoint_frame); + within_current_scope = (fi != NULL); + if (within_current_scope) + select_frame (fi); + } + + if (within_current_scope) + { + /* Evaluate the expression and cut the chain of values + produced off from the value chain. + + Make sure the value returned isn't lazy; we use + laziness to determine what memory GDB actually needed + in order to compute the value of the expression. */ + v = evaluate_expression (bpt->owner->exp); + VALUE_CONTENTS (v); + value_release_to_mark (mark); + + bpt->owner->val_chain = v; + bpt->inserted = 1; + + /* Look at each value on the value chain. */ + for (; v; v = v->next) + { + /* If it's a memory location, and GDB actually needed + its contents to evaluate the expression, then we + must watch it. */ + if (VALUE_LVAL (v) == lval_memory + && ! VALUE_LAZY (v)) + { + struct type *vtype = check_typedef (VALUE_TYPE (v)); + + /* We only watch structs and arrays if user asked + for it explicitly, never if they just happen to + appear in the middle of some value chain. */ + if (v == bpt->owner->val_chain + || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT + && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) + { + CORE_ADDR addr; + int len, type; + + addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + len = TYPE_LENGTH (VALUE_TYPE (v)); + type = hw_write; + if (bpt->owner->type == bp_read_watchpoint) + type = hw_read; + else if (bpt->owner->type == bp_access_watchpoint) + type = hw_access; + + val = target_insert_watchpoint (addr, len, type); + if (val == -1) + { + /* Don't exit the loop, try to insert + every value on the value chain. That's + because we will be removing all the + watches below, and removing a + watchpoint we didn't insert could have + adverse effects. */ + bpt->inserted = 0; + } + val = 0; + } + } + } + /* Failure to insert a watchpoint on any memory value in the + value chain brings us here. */ + if (!bpt->inserted) + { + remove_breakpoint (bpt, mark_uninserted); + *hw_breakpoint_error = 1; + fprintf_unfiltered (tmp_error_stream, + "Could not insert hardware watchpoint %d.\n", + bpt->owner->number); + val = -1; + } + } + else + { + printf_filtered ("Hardware watchpoint %d deleted ", bpt->owner->number); + printf_filtered ("because the program has left the block \n"); + printf_filtered ("in which its expression is valid.\n"); + if (bpt->owner->related_breakpoint) + bpt->owner->related_breakpoint->disposition = disp_del_at_next_stop; + bpt->owner->disposition = disp_del_at_next_stop; + } + + /* Restore the frame and level. */ + if (saved_frame != deprecated_selected_frame + || saved_level != frame_relative_level (deprecated_selected_frame)) + select_frame (saved_frame); + + return val; + } + + else if (ep_is_exception_catchpoint (bpt->owner)) + { + /* FIXME drow/2003-09-09: This code sets both a catchpoint and a + breakpoint. Once again, it would be better if this was represented + as two bp_locations. */ + + /* If we get here, we must have a callback mechanism for exception + events -- with g++ style embedded label support, we insert + ordinary breakpoints and not catchpoints. */ + val = target_insert_breakpoint (bpt->address, bpt->shadow_contents); + if (val) + { + /* Couldn't set breakpoint for some reason */ + fprintf_unfiltered (tmp_error_stream, + "Cannot insert catchpoint %d; disabling it.\n", + bpt->owner->number); + fprintf_filtered (tmp_error_stream, + "Error accessing memory address "); + print_address_numeric (bpt->address, 1, tmp_error_stream); + fprintf_filtered (tmp_error_stream, ": %s.\n", + safe_strerror (val)); + bpt->owner->enable_state = bp_disabled; + } + else + { + /* Bp set, now make sure callbacks are enabled */ + /* Format possible error msg */ + char *message = xstrprintf ("Error inserting catchpoint %d:\n", + bpt->owner->number); + struct cleanup *cleanups = make_cleanup (xfree, message); + int val; + args_for_catchpoint_enable args; + args.kind = bpt->owner->type == bp_catch_catch ? + EX_EVENT_CATCH : EX_EVENT_THROW; + args.enable_p = 1; + val = catch_errors (cover_target_enable_exception_callback, + &args, message, RETURN_MASK_ALL); + do_cleanups (cleanups); + if (val != 0 && val != -1) + bpt->inserted = 1; + + /* Check if something went wrong; val == 0 can be ignored */ + if (val == -1) + { + /* something went wrong */ + fprintf_unfiltered (tmp_error_stream, + "Cannot insert catchpoint %d; disabling it.\n", + bpt->owner->number); + bpt->owner->enable_state = bp_disabled; + } + } + + return val; + } + + else if (bpt->owner->type == bp_catch_fork + || bpt->owner->type == bp_catch_vfork + || bpt->owner->type == bp_catch_exec) + { + char *prefix = xstrprintf ("warning: inserting catchpoint %d: ", + bpt->owner->number); + struct cleanup *cleanups = make_cleanup (xfree, prefix); + val = catch_exceptions (uiout, insert_catchpoint, bpt->owner, prefix, + RETURN_MASK_ERROR); + do_cleanups (cleanups); + if (val < 0) + bpt->owner->enable_state = bp_disabled; + else + bpt->inserted = 1; + + /* We've already printed an error message if there was a problem + inserting this catchpoint, and we've disabled the catchpoint, + so just return success. */ + return 0; + } + + return 0; +} + /* insert_breakpoints is used when starting or continuing the program. remove_breakpoints is used when the program stops. Both return zero if successful, @@ -706,320 +1093,75 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len) int insert_breakpoints (void) { - register struct breakpoint *b, *temp; + struct bp_location *b, *temp; int return_val = 0; /* return success code. */ int val = 0; int disabled_breaks = 0; + int hw_breakpoint_error = 0; + int process_warning = 0; - static char message1[] = "Error inserting catchpoint %d:\n"; - static char message[sizeof (message1) + 30]; + struct ui_file *tmp_error_stream = mem_fileopen (); + make_cleanup_ui_file_delete (tmp_error_stream); + /* Explicitly mark the warning -- this will only be printed if + there was an error. */ + fprintf_unfiltered (tmp_error_stream, "Warning:\n"); - ALL_BREAKPOINTS_SAFE (b, temp) - { - if (b->enable_state == bp_permanent) - /* Permanent breakpoints cannot be inserted or removed. */ - continue; - else if (b->type != bp_watchpoint - && b->type != bp_hardware_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint - && b->type != bp_catch_fork - && b->type != bp_catch_vfork - && b->type != bp_catch_exec - && b->type != bp_catch_throw - && b->type != bp_catch_catch - && b->enable_state != bp_disabled - && b->enable_state != bp_shlib_disabled - && b->enable_state != bp_call_disabled - && !b->inserted - && !b->duplicate) - { - if (b->type == bp_hardware_breakpoint) - val = target_insert_hw_breakpoint (b->address, b->shadow_contents); - else - { - /* Check to see if breakpoint is in an overlay section; - if so, we should set the breakpoint at the LMA address. - Only if the section is currently mapped should we ALSO - set a break at the VMA address. */ - if (overlay_debugging && b->section - && section_is_overlay (b->section)) - { - CORE_ADDR addr; + ALL_BP_LOCATIONS_SAFE (b, temp) + { + /* Permanent breakpoints cannot be inserted or removed. Disabled + breakpoints should not be inserted. */ + if (!breakpoint_enabled (b->owner)) + continue; - addr = overlay_unmapped_address (b->address, b->section); - val = target_insert_breakpoint (addr, b->shadow_contents); - /* This would be the time to check val, to see if the - breakpoint write to the load address succeeded. - However, this might be an ordinary occurrance, eg. if - the unmapped overlay is in ROM. */ - val = 0; /* in case unmapped address failed */ - if (section_is_mapped (b->section)) - val = target_insert_breakpoint (b->address, - b->shadow_contents); - } - else /* ordinary (non-overlay) address */ - val = target_insert_breakpoint (b->address, b->shadow_contents); - } - if (val) - { - /* Can't set the breakpoint. */ -#if defined (DISABLE_UNSETTABLE_BREAK) - if (DISABLE_UNSETTABLE_BREAK (b->address)) - { - /* See also: disable_breakpoints_in_shlibs. */ - val = 0; - b->enable_state = bp_shlib_disabled; - if (!disabled_breaks) - { - target_terminal_ours_for_output (); - warning ("Cannot insert breakpoint %d:", b->number); - warning ("Temporarily disabling shared library breakpoints:"); - } - disabled_breaks = 1; - warning ("breakpoint #%d ", b->number); - } - else -#endif - { - target_terminal_ours_for_output (); - warning ("Cannot insert breakpoint %d:", b->number); + /* FIXME drow/2003-10-07: This code should be pushed elsewhere when + hardware watchpoints are split into multiple loc breakpoints. */ + if ((b->loc_type == bp_loc_hardware_watchpoint + || b->owner->type == bp_watchpoint) && !b->owner->val) + { + struct value *val; + val = evaluate_expression (b->owner->exp); + release_value (val); + if (VALUE_LAZY (val)) + value_fetch_lazy (val); + b->owner->val = val; + } + + val = insert_bp_location (b, tmp_error_stream, + &disabled_breaks, &process_warning, + &hw_breakpoint_error); + if (val) + return_val = val; + } + + if (return_val) + { + /* If a hardware breakpoint or watchpoint was inserted, add a + message about possibly exhausted resources. */ + if (hw_breakpoint_error) + { + fprintf_unfiltered (tmp_error_stream, + "Could not insert hardware breakpoints:\n\ +You may have requested too many hardware breakpoints/watchpoints.\n"); + } #ifdef ONE_PROCESS_WRITETEXT - warning ("The same program may be running in another process."); + if (process_warning) + fprintf_unfiltered (tmp_error_stream, + "The same program may be running in another process."); #endif - memory_error (val, b->address); /* which bombs us out */ - } - } - else - b->inserted = 1; - - if (val) - return_val = val; /* remember failure */ - } - else if (ep_is_exception_catchpoint (b) - && b->enable_state != bp_disabled - && b->enable_state != bp_shlib_disabled - && b->enable_state != bp_call_disabled - && !b->inserted - && !b->duplicate) - - { - /* If we get here, we must have a callback mechanism for exception - events -- with g++ style embedded label support, we insert - ordinary breakpoints and not catchpoints. */ - /* Format possible error message */ - sprintf (message, message1, b->number); - - val = target_insert_breakpoint (b->address, b->shadow_contents); - if (val) - { - /* Couldn't set breakpoint for some reason */ - target_terminal_ours_for_output (); - warning ("Cannot insert catchpoint %d; disabling it.", - b->number); - b->enable_state = bp_disabled; - } - else - { - /* Bp set, now make sure callbacks are enabled */ - int val; - args_for_catchpoint_enable args; - args.kind = b->type == bp_catch_catch ? - EX_EVENT_CATCH : EX_EVENT_THROW; - args.enable_p = 1; - val = catch_errors (cover_target_enable_exception_callback, - &args, - message, RETURN_MASK_ALL); - if (val != 0 && val != -1) - { - b->inserted = 1; - } - /* Check if something went wrong; val == 0 can be ignored */ - if (val == -1) - { - /* something went wrong */ - target_terminal_ours_for_output (); - warning ("Cannot insert catchpoint %d; disabling it.", - b->number); - b->enable_state = bp_disabled; - } - } - - if (val) - return_val = val; /* remember failure */ - } - - else if ((b->type == bp_hardware_watchpoint || - b->type == bp_read_watchpoint || - b->type == bp_access_watchpoint) - && b->enable_state == bp_enabled - && b->disposition != disp_del_at_next_stop - && !b->inserted - && !b->duplicate) - { - struct frame_info *saved_frame; - int saved_level, within_current_scope; - struct value *mark = value_mark (); - struct value *v; - - /* Save the current frame and level so we can restore it after - evaluating the watchpoint expression on its own frame. */ - saved_frame = selected_frame; - saved_level = selected_frame_level; - - /* Determine if the watchpoint is within scope. */ - if (b->exp_valid_block == NULL) - within_current_scope = 1; - else - { - struct frame_info *fi; - - /* There might be no current frame at this moment if we are - resuming from a step over a breakpoint. - Set up current frame before trying to find the watchpoint - frame. */ - get_current_frame (); - fi = find_frame_addr_in_frame_chain (b->watchpoint_frame); - within_current_scope = (fi != NULL); - if (within_current_scope) - select_frame (fi, -1); - } - - if (within_current_scope) - { - /* Evaluate the expression and cut the chain of values - produced off from the value chain. - - Make sure the value returned isn't lazy; we use - laziness to determine what memory GDB actually needed - in order to compute the value of the expression. */ - v = evaluate_expression (b->exp); - VALUE_CONTENTS(v); - value_release_to_mark (mark); - - b->val_chain = v; - b->inserted = 1; - - /* Look at each value on the value chain. */ - for (; v; v = v->next) - { - /* If it's a memory location, and GDB actually needed - its contents to evaluate the expression, then we - must watch it. */ - if (VALUE_LVAL (v) == lval_memory - && ! VALUE_LAZY (v)) - { - struct type *vtype = check_typedef (VALUE_TYPE (v)); - - /* We only watch structs and arrays if user asked - for it explicitly, never if they just happen to - appear in the middle of some value chain. */ - if (v == b->val_chain - || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT - && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) - { - CORE_ADDR addr; - int len, type; - - addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - len = TYPE_LENGTH (VALUE_TYPE (v)); - type = hw_write; - if (b->type == bp_read_watchpoint) - type = hw_read; - else if (b->type == bp_access_watchpoint) - type = hw_access; - - val = target_insert_watchpoint (addr, len, type); - if (val == -1) - { - /* Don't exit the loop, try to insert - every value on the value chain. That's - because we will be removing all the - watches below, and removing a - watchpoint we didn't insert could have - adverse effects. */ - b->inserted = 0; - } - val = 0; - } - } - } - /* Failure to insert a watchpoint on any memory value in the - value chain brings us here. */ - if (!b->inserted) - { - remove_breakpoint (b, mark_uninserted); - warning ("Could not insert hardware watchpoint %d.", - b->number); - val = -1; - } - } - else - { - printf_filtered ("Hardware watchpoint %d deleted ", b->number); - printf_filtered ("because the program has left the block \n"); - printf_filtered ("in which its expression is valid.\n"); - if (b->related_breakpoint) - b->related_breakpoint->disposition = disp_del_at_next_stop; - b->disposition = disp_del_at_next_stop; - } - - /* Restore the frame and level. */ - if ((saved_frame != selected_frame) || - (saved_level != selected_frame_level)) - select_frame (saved_frame, saved_level); - - if (val) - return_val = val; /* remember failure */ - } - else if ((b->type == bp_catch_fork - || b->type == bp_catch_vfork - || b->type == bp_catch_exec) - && b->enable_state == bp_enabled - && !b->inserted - && !b->duplicate) - { - val = -1; - switch (b->type) - { - case bp_catch_fork: - val = target_insert_fork_catchpoint (PIDGET (inferior_ptid)); - break; - case bp_catch_vfork: - val = target_insert_vfork_catchpoint (PIDGET (inferior_ptid)); - break; - case bp_catch_exec: - val = target_insert_exec_catchpoint (PIDGET (inferior_ptid)); - break; - default: - warning ("Internal error, %s line %d.", __FILE__, __LINE__); - break; - } - if (val < 0) - { - target_terminal_ours_for_output (); - warning ("Cannot insert catchpoint %d.", b->number); - } - else - b->inserted = 1; - - if (val) - return_val = val; /* remember failure */ - } - } - + target_terminal_ours_for_output (); + error_stream (tmp_error_stream); + } return return_val; } - int remove_breakpoints (void) { - register struct breakpoint *b; + struct bp_location *b; int val; - ALL_BREAKPOINTS (b) + ALL_BP_LOCATIONS (b) { if (b->inserted) { @@ -1034,15 +1176,12 @@ remove_breakpoints (void) int remove_hw_watchpoints (void) { - register struct breakpoint *b; + struct bp_location *b; int val; - ALL_BREAKPOINTS (b) + ALL_BP_LOCATIONS (b) { - if (b->inserted - && (b->type == bp_hardware_watchpoint - || b->type == bp_read_watchpoint - || b->type == bp_access_watchpoint)) + if (b->inserted && b->loc_type == bp_loc_hardware_watchpoint) { val = remove_breakpoint (b, mark_uninserted); if (val != 0) @@ -1055,21 +1194,23 @@ remove_hw_watchpoints (void) int reattach_breakpoints (int pid) { - register struct breakpoint *b; + struct bp_location *b; int val; struct cleanup *old_chain = save_inferior_ptid (); /* Set inferior_ptid; remove_breakpoint uses this global. */ inferior_ptid = pid_to_ptid (pid); - ALL_BREAKPOINTS (b) + ALL_BP_LOCATIONS (b) { if (b->inserted) { remove_breakpoint (b, mark_inserted); - if (b->type == bp_hardware_breakpoint) + if (b->loc_type == bp_loc_hardware_breakpoint) val = target_insert_hw_breakpoint (b->address, b->shadow_contents); else val = target_insert_breakpoint (b->address, b->shadow_contents); + /* FIXME drow/2003-10-07: This doesn't handle any other kinds of + breakpoints. It's wrong for watchpoints, for example. */ if (val != 0) { do_cleanups (old_chain); @@ -1144,11 +1285,11 @@ update_breakpoints_after_exec (void) automagically. Certainly on HP-UX that's true. Jim Blandy : Actually, zero is a perfectly - valid code address on some platforms (like the mn10200 and - mn10300 simulators). We shouldn't assign any special - interpretation to a breakpoint with a zero address. And in - fact, GDB doesn't --- I can't see what that comment above is - talking about. As far as I can tell, setting the address of a + valid code address on some platforms (like the mn10300 + simulators). We shouldn't assign any special interpretation to + a breakpoint with a zero address. And in fact, GDB doesn't --- + I can't see what that comment above is talking about. As far + as I can tell, setting the address of a bp_catch_exec/bp_catch_vfork/bp_catch_fork breakpoint to zero is meaningless, since those are implemented with HP-UX kernel hackery, not by storing breakpoint instructions somewhere. */ @@ -1156,7 +1297,7 @@ update_breakpoints_after_exec (void) (b->type == bp_catch_vfork) || (b->type == bp_catch_fork)) { - b->address = (CORE_ADDR) NULL; + b->loc->address = (CORE_ADDR) NULL; continue; } @@ -1209,7 +1350,7 @@ update_breakpoints_after_exec (void) unnecessary. A call to breakpoint_re_set_one always recomputes the breakpoint's address from scratch, or deletes it if it can't. So I think this assignment could be deleted without effect. */ - b->address = (CORE_ADDR) NULL; + b->loc->address = (CORE_ADDR) NULL; } /* FIXME what about longjmp breakpoints? Re-create them here? */ create_overlay_event_breakpoint ("_ovly_debug_event"); @@ -1218,7 +1359,7 @@ update_breakpoints_after_exec (void) int detach_breakpoints (int pid) { - register struct breakpoint *b; + struct bp_location *b; int val; struct cleanup *old_chain = save_inferior_ptid (); @@ -1227,7 +1368,7 @@ detach_breakpoints (int pid) /* Set inferior_ptid; remove_breakpoint uses this global. */ inferior_ptid = pid_to_ptid (pid); - ALL_BREAKPOINTS (b) + ALL_BP_LOCATIONS (b) { if (b->inserted) { @@ -1244,63 +1385,83 @@ detach_breakpoints (int pid) } static int -remove_breakpoint (struct breakpoint *b, insertion_state_t is) +remove_breakpoint (struct bp_location *b, insertion_state_t is) { int val; - if (b->enable_state == bp_permanent) + if (b->owner->enable_state == bp_permanent) /* Permanent breakpoints cannot be inserted or removed. */ return 0; - if (b->type == bp_none) + if (b->owner->type == bp_none) warning ("attempted to remove apparently deleted breakpoint #%d?", - b->number); + b->owner->number); - if (b->type != bp_watchpoint - && b->type != bp_hardware_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint - && b->type != bp_catch_fork - && b->type != bp_catch_vfork - && b->type != bp_catch_exec - && b->type != bp_catch_catch - && b->type != bp_catch_throw) + if (b->loc_type == bp_loc_software_breakpoint + || b->loc_type == bp_loc_hardware_breakpoint) { - if (b->type == bp_hardware_breakpoint) - val = target_remove_hw_breakpoint (b->address, b->shadow_contents); + /* "Normal" instruction breakpoint: either the standard + trap-instruction bp (bp_breakpoint), or a + bp_hardware_breakpoint. */ + + /* First check to see if we have to handle an overlay. */ + if (overlay_debugging == ovly_off + || b->section == NULL + || !(section_is_overlay (b->section))) + { + /* No overlay handling: just remove the breakpoint. */ + + if (b->loc_type == bp_loc_hardware_breakpoint) + val = target_remove_hw_breakpoint (b->address, + b->shadow_contents); + else + val = target_remove_breakpoint (b->address, b->shadow_contents); + } else { - /* Check to see if breakpoint is in an overlay section; - if so, we should remove the breakpoint at the LMA address. - If that is not equal to the raw address, then we should - presumably remove the breakpoint there as well. */ - if (overlay_debugging && b->section - && section_is_overlay (b->section)) + /* This breakpoint is in an overlay section. + Did we set a breakpoint at the LMA? */ + if (!overlay_events_enabled) + { + /* Yes -- overlay event support is not active, so we + should have set a breakpoint at the LMA. Remove it. + */ + CORE_ADDR addr = overlay_unmapped_address (b->address, + b->section); + /* Ignore any failures: if the LMA is in ROM, we will + have already warned when we failed to insert it. */ + if (b->loc_type == bp_loc_hardware_breakpoint) + target_remove_hw_breakpoint (addr, b->shadow_contents); + else + target_remove_breakpoint (addr, b->shadow_contents); + } + /* Did we set a breakpoint at the VMA? + If so, we will have marked the breakpoint 'inserted'. */ + if (b->inserted) { - CORE_ADDR addr; - - addr = overlay_unmapped_address (b->address, b->section); - val = target_remove_breakpoint (addr, b->shadow_contents); - /* This would be the time to check val, to see if the - shadow breakpoint write to the load address succeeded. - However, this might be an ordinary occurrance, eg. if - the unmapped overlay is in ROM. */ - val = 0; /* in case unmapped address failed */ - if (section_is_mapped (b->section)) + /* Yes -- remove it. Previously we did not bother to + remove the breakpoint if the section had been + unmapped, but let's not rely on that being safe. We + don't know what the overlay manager might do. */ + if (b->loc_type == bp_loc_hardware_breakpoint) + val = target_remove_hw_breakpoint (b->address, + b->shadow_contents); + else val = target_remove_breakpoint (b->address, b->shadow_contents); } - else /* ordinary (non-overlay) address */ - val = target_remove_breakpoint (b->address, b->shadow_contents); + else + { + /* No -- not inserted, so no need to remove. No error. */ + val = 0; + } } if (val) return val; b->inserted = (is == mark_inserted); } - else if ((b->type == bp_hardware_watchpoint || - b->type == bp_read_watchpoint || - b->type == bp_access_watchpoint) - && b->enable_state == bp_enabled + else if (b->loc_type == bp_loc_hardware_watchpoint + && breakpoint_enabled (b->owner) && !b->duplicate) { struct value *v; @@ -1308,7 +1469,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is) b->inserted = (is == mark_inserted); /* Walk down the saved value chain. */ - for (v = b->val_chain; v; v = v->next) + for (v = b->owner->val_chain; v; v = v->next) { /* For each memory reference remove the watchpoint at that address. */ @@ -1317,7 +1478,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is) { struct type *vtype = check_typedef (VALUE_TYPE (v)); - if (v == b->val_chain + if (v == b->owner->val_chain || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) { @@ -1327,9 +1488,9 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is) addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); len = TYPE_LENGTH (VALUE_TYPE (v)); type = hw_write; - if (b->type == bp_read_watchpoint) + if (b->owner->type == bp_read_watchpoint) type = hw_read; - else if (b->type == bp_access_watchpoint) + else if (b->owner->type == bp_access_watchpoint) type = hw_access; val = target_remove_watchpoint (addr, len, type); @@ -1342,25 +1503,25 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is) /* Failure to remove any of the hardware watchpoints comes here. */ if ((is == mark_uninserted) && (b->inserted)) warning ("Could not remove hardware watchpoint %d.", - b->number); + b->owner->number); /* Free the saved value chain. We will construct a new one the next time the watchpoint is inserted. */ - for (v = b->val_chain; v; v = n) + for (v = b->owner->val_chain; v; v = n) { n = v->next; value_free (v); } - b->val_chain = NULL; + b->owner->val_chain = NULL; } - else if ((b->type == bp_catch_fork || - b->type == bp_catch_vfork || - b->type == bp_catch_exec) - && b->enable_state == bp_enabled + else if ((b->owner->type == bp_catch_fork || + b->owner->type == bp_catch_vfork || + b->owner->type == bp_catch_exec) + && breakpoint_enabled (b->owner) && !b->duplicate) { val = -1; - switch (b->type) + switch (b->owner->type) { case bp_catch_fork: val = target_remove_fork_catchpoint (PIDGET (inferior_ptid)); @@ -1379,9 +1540,9 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is) return val; b->inserted = (is == mark_inserted); } - else if ((b->type == bp_catch_catch || - b->type == bp_catch_throw) - && b->enable_state == bp_enabled + else if ((b->owner->type == bp_catch_catch || + b->owner->type == bp_catch_throw) + && breakpoint_enabled (b->owner) && !b->duplicate) { @@ -1390,9 +1551,9 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is) return val; b->inserted = (is == mark_inserted); } - else if (ep_is_exception_catchpoint (b) + else if (ep_is_exception_catchpoint (b->owner) && b->inserted /* sometimes previous insert doesn't happen */ - && b->enable_state == bp_enabled + && breakpoint_enabled (b->owner) && !b->duplicate) { @@ -1411,10 +1572,10 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is) void mark_breakpoints_out (void) { - register struct breakpoint *b; + struct bp_location *bpt; - ALL_BREAKPOINTS (b) - b->inserted = 0; + ALL_BP_LOCATIONS (bpt) + bpt->inserted = 0; } /* Clear the "inserted" flag in all breakpoints and delete any @@ -1432,13 +1593,15 @@ mark_breakpoints_out (void) void breakpoint_init_inferior (enum inf_context context) { - register struct breakpoint *b, *temp; + struct breakpoint *b, *temp; + struct bp_location *bpt; static int warning_needed = 0; + ALL_BP_LOCATIONS (bpt) + bpt->inserted = 0; + ALL_BREAKPOINTS_SAFE (b, temp) { - b->inserted = 0; - switch (b->type) { case bp_call_dummy: @@ -1460,6 +1623,14 @@ breakpoint_init_inferior (enum inf_context context) /* Likewise for watchpoints on local expressions. */ if (b->exp_valid_block != NULL) delete_breakpoint (b); + if (context == inf_starting) + { + /* Reset val field to force reread of starting value + in insert_breakpoints. */ + if (b->val) + value_free (b->val); + b->val = NULL; + } break; default: /* Likewise for exception catchpoints in dynamic-linked @@ -1499,23 +1670,29 @@ breakpoint_init_inferior (enum inf_context context) enum breakpoint_here breakpoint_here_p (CORE_ADDR pc) { - register struct breakpoint *b; + struct bp_location *bpt; int any_breakpoint_here = 0; - ALL_BREAKPOINTS (b) - if ((b->enable_state == bp_enabled - || b->enable_state == bp_permanent) - && b->address == pc) /* bp is enabled and matches pc */ - { - if (overlay_debugging - && section_is_overlay (b->section) - && !section_is_mapped (b->section)) - continue; /* unmapped overlay -- can't be a match */ - else if (b->enable_state == bp_permanent) - return permanent_breakpoint_here; - else - any_breakpoint_here = 1; - } + ALL_BP_LOCATIONS (bpt) + { + if (bpt->loc_type != bp_loc_software_breakpoint + && bpt->loc_type != bp_loc_hardware_breakpoint) + continue; + + if ((breakpoint_enabled (bpt->owner) + || bpt->owner->enable_state == bp_permanent) + && bpt->address == pc) /* bp is enabled and matches pc */ + { + if (overlay_debugging + && section_is_overlay (bpt->section) + && !section_is_mapped (bpt->section)) + continue; /* unmapped overlay -- can't be a match */ + else if (bpt->owner->enable_state == bp_permanent) + return permanent_breakpoint_here; + else + any_breakpoint_here = 1; + } + } return any_breakpoint_here ? ordinary_breakpoint_here : 0; } @@ -1528,79 +1705,120 @@ breakpoint_here_p (CORE_ADDR pc) int breakpoint_inserted_here_p (CORE_ADDR pc) { - register struct breakpoint *b; + struct bp_location *bpt; - ALL_BREAKPOINTS (b) - if (b->inserted - && b->address == pc) /* bp is inserted and matches pc */ + ALL_BP_LOCATIONS (bpt) { - if (overlay_debugging - && section_is_overlay (b->section) - && !section_is_mapped (b->section)) - continue; /* unmapped overlay -- can't be a match */ - else - return 1; + if (bpt->loc_type != bp_loc_software_breakpoint + && bpt->loc_type != bp_loc_hardware_breakpoint) + continue; + + if (bpt->inserted + && bpt->address == pc) /* bp is inserted and matches pc */ + { + if (overlay_debugging + && section_is_overlay (bpt->section) + && !section_is_mapped (bpt->section)) + continue; /* unmapped overlay -- can't be a match */ + else + return 1; + } + } + + return 0; +} + +/* This function returns non-zero iff there is a software breakpoint + inserted at PC. */ + +int +software_breakpoint_inserted_here_p (CORE_ADDR pc) +{ + struct bp_location *bpt; + int any_breakpoint_here = 0; + + ALL_BP_LOCATIONS (bpt) + { + if (bpt->loc_type != bp_loc_software_breakpoint) + continue; + + if ((breakpoint_enabled (bpt->owner) + || bpt->owner->enable_state == bp_permanent) + && bpt->inserted + && bpt->address == pc) /* bp is enabled and matches pc */ + { + if (overlay_debugging + && section_is_overlay (bpt->section) + && !section_is_mapped (bpt->section)) + continue; /* unmapped overlay -- can't be a match */ + else + return 1; + } } return 0; } /* Return nonzero if FRAME is a dummy frame. We can't use - PC_IN_CALL_DUMMY because figuring out the saved SP would take too - much time, at least using get_saved_register on the 68k. This - means that for this function to work right a port must use the + DEPRECATED_PC_IN_CALL_DUMMY because figuring out the saved SP would + take too much time, at least using frame_register() on the 68k. + This means that for this function to work right a port must use the bp_call_dummy breakpoint. */ int -frame_in_dummy (struct frame_info *frame) +deprecated_frame_in_dummy (struct frame_info *frame) { struct breakpoint *b; - if (!CALL_DUMMY_P) - return 0; - - if (USE_GENERIC_DUMMY_FRAMES) - return generic_pc_in_call_dummy (frame->pc, frame->frame, frame->frame); + /* This function is used by two files: get_frame_type(), after first + checking that !DEPRECATED_USE_GENERIC_DUMMY_FRAMES; and + sparc-tdep.c, which doesn't yet use generic dummy frames anyway. */ + gdb_assert (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES); ALL_BREAKPOINTS (b) { if (b->type == bp_call_dummy - && b->frame == frame->frame + && frame_id_eq (b->frame_id, get_frame_id (frame)) /* We need to check the PC as well as the frame on the sparc, for signals.exp in the testsuite. */ - && (frame->pc - >= (b->address - - SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * REGISTER_SIZE)) - && frame->pc <= b->address) + && (get_frame_pc (frame) + >= (b->loc->address + - DEPRECATED_SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * DEPRECATED_REGISTER_SIZE)) + && get_frame_pc (frame) <= b->loc->address) return 1; } return 0; } -/* breakpoint_thread_match (PC, PID) returns true if the breakpoint at - PC is valid for process/thread PID. */ +/* breakpoint_thread_match (PC, PTID) returns true if the breakpoint at + PC is valid for process/thread PTID. */ int breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid) { - struct breakpoint *b; + struct bp_location *bpt; int thread; thread = pid_to_thread_id (ptid); - ALL_BREAKPOINTS (b) - if (b->enable_state != bp_disabled - && b->enable_state != bp_shlib_disabled - && b->enable_state != bp_call_disabled - && b->address == pc - && (b->thread == -1 || b->thread == thread)) + ALL_BP_LOCATIONS (bpt) { - if (overlay_debugging - && section_is_overlay (b->section) - && !section_is_mapped (b->section)) - continue; /* unmapped overlay -- can't be a match */ - else - return 1; + if (bpt->loc_type != bp_loc_software_breakpoint + && bpt->loc_type != bp_loc_hardware_breakpoint) + continue; + + if ((breakpoint_enabled (bpt->owner) + || bpt->owner->enable_state == bp_permanent) + && bpt->address == pc + && (bpt->owner->thread == -1 || bpt->owner->thread == thread)) + { + if (overlay_debugging + && section_is_overlay (bpt->section) + && !section_is_mapped (bpt->section)) + continue; /* unmapped overlay -- can't be a match */ + else + return 1; + } } return 0; @@ -1658,6 +1876,7 @@ bpstat_clear (bpstat *bsp) q = p->next; if (p->old_val != NULL) value_free (p->old_val); + free_command_lines (&p->commands); xfree (p); p = q; } @@ -1681,6 +1900,11 @@ bpstat_copy (bpstat bs) { tmp = (bpstat) xmalloc (sizeof (*tmp)); memcpy (tmp, bs, sizeof (*tmp)); + if (bs->commands != NULL) + tmp->commands = copy_command_lines (bs->commands); + if (bs->old_val != NULL) + tmp->old_val = value_copy (bs->old_val); + if (p == NULL) /* This is the first thing in the chain. */ retval = tmp; @@ -1770,7 +1994,7 @@ bpstat_clear_actions (bpstat bs) { for (; bs != NULL; bs = bs->next) { - bs->commands = NULL; + free_command_lines (&bs->commands); if (bs->old_val != NULL) { value_free (bs->old_val); @@ -1780,9 +2004,8 @@ bpstat_clear_actions (bpstat bs) } /* Stub for cleaning up our state if we error-out of a breakpoint command */ -/* ARGSUSED */ static void -cleanup_executing_breakpoints (PTR ignore) +cleanup_executing_breakpoints (void *ignore) { executing_breakpoint_commands = 0; } @@ -1797,7 +2020,6 @@ bpstat_do_actions (bpstat *bsp) { bpstat bs; struct cleanup *old_chain; - struct command_line *cmd; /* Avoid endless recursion if a `source' command is contained in bs->commands. */ @@ -1822,7 +2044,23 @@ top: breakpoint_proceeded = 0; for (; bs != NULL; bs = bs->next) { + struct command_line *cmd; + struct cleanup *this_cmd_tree_chain; + + /* Take ownership of the BSP's command tree, if it has one. + + The command tree could legitimately contain commands like + 'step' and 'next', which call clear_proceed_status, which + frees stop_bpstat's command tree. To make sure this doesn't + free the tree we're executing out from under us, we need to + take ownership of the tree ourselves. Since a given bpstat's + commands are only executed once, we don't need to copy it; we + can clear the pointer in the bpstat, and make sure we free + the tree when we're done. */ cmd = bs->commands; + bs->commands = 0; + this_cmd_tree_chain = make_cleanup_free_command_lines (&cmd); + while (cmd != NULL) { execute_control_command (cmd); @@ -1832,18 +2070,18 @@ top: else cmd = cmd->next; } + + /* We can free this command tree now. */ + do_cleanups (this_cmd_tree_chain); + if (breakpoint_proceeded) /* The inferior is proceeded by the command; bomb out now. The bpstat chain has been blown away by wait_for_inferior. But since execution has stopped again, there is a new bpstat to look at, so start over. */ goto top; - else - bs->commands = NULL; } - - executing_breakpoint_commands = 0; - discard_cleanups (old_chain); + do_cleanups (old_chain); } /* This is the normal print function for a bpstat. In the future, @@ -1870,7 +2108,7 @@ top: static enum print_stop_action print_it_typical (bpstat bs) { - struct cleanup *old_chain; + struct cleanup *old_chain, *ui_out_chain; struct ui_stream *stb; stb = ui_out_stream_new (uiout); old_chain = make_cleanup_ui_out_stream_delete (stb); @@ -1883,6 +2121,10 @@ print_it_typical (bpstat bs) { case bp_breakpoint: case bp_hardware_breakpoint: + if (bs->breakpoint_at->loc->address != bs->breakpoint_at->loc->requested_address) + breakpoint_adjustment_warning (bs->breakpoint_at->loc->requested_address, + bs->breakpoint_at->loc->address, + bs->breakpoint_at->number, 1); annotate_breakpoint (bs->breakpoint_at->number); ui_out_text (uiout, "\nBreakpoint "); if (ui_out_is_mi_like_p (uiout)) @@ -2031,14 +2273,14 @@ print_it_typical (bpstat bs) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "watchpoint-trigger"); mention (bs->breakpoint_at); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nOld value = "); value_print (bs->old_val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "old", stb); ui_out_text (uiout, "\nNew value = "); value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "new", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); value_free (bs->old_val); bs->old_val = NULL; @@ -2051,11 +2293,11 @@ print_it_typical (bpstat bs) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "read-watchpoint-trigger"); mention (bs->breakpoint_at); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nValue = "); value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "value", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); return PRINT_UNKNOWN; break; @@ -2067,7 +2309,7 @@ print_it_typical (bpstat bs) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "access-watchpoint-trigger"); mention (bs->breakpoint_at); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nOld value = "); value_print (bs->old_val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "old", stb); @@ -2080,12 +2322,12 @@ print_it_typical (bpstat bs) mention (bs->breakpoint_at); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "access-watchpoint-trigger"); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nValue = "); } value_print (bs->breakpoint_at->val, stb->stream, 0,Val_pretty_default); ui_out_field_stream (uiout, "new", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); return PRINT_UNKNOWN; break; @@ -2140,9 +2382,15 @@ print_bp_stop_message (bpstat bs) break; case print_it_normal: - /* Normal case, we handle everything in print_it_typical. */ - return print_it_typical (bs); + /* Normal case. Call the breakpoint's print_it method, or + print_it_typical. */ + if (bs->breakpoint_at != NULL && bs->breakpoint_at->ops != NULL + && bs->breakpoint_at->ops->print_it != NULL) + return bs->breakpoint_at->ops->print_it (bs->breakpoint_at); + else + return print_it_typical (bs); break; + default: internal_error (__FILE__, __LINE__, "print_bp_stop_message: unrecognized enum value"); @@ -2199,7 +2447,7 @@ bpstat_print (bpstat bs) make it pass through catch_errors. */ static int -breakpoint_cond_eval (PTR exp) +breakpoint_cond_eval (void *exp) { struct value *mark = value_mark (); int i = !value_true (evaluate_expression ((struct expression *) exp)); @@ -2239,7 +2487,7 @@ bpstat_alloc (struct breakpoint *b, bpstat cbs /* Current "bs" value */ ) /* Check watchpoint condition. */ static int -watchpoint_check (PTR p) +watchpoint_check (void *p) { bpstat bs = (bpstat) p; struct breakpoint *b; @@ -2256,21 +2504,26 @@ watchpoint_check (PTR p) any chance of handling watchpoints on local variables, we'll need the frame chain (so we can determine if we're in scope). */ reinit_frame_cache (); - fr = find_frame_addr_in_frame_chain (b->watchpoint_frame); + fr = frame_find_by_id (b->watchpoint_frame); within_current_scope = (fr != NULL); /* in_function_epilogue_p() returns a non-zero value if we're still in the function but the stack frame has already been invalidated. Since we can't rely on the values of local variables after the stack has been destroyed, we are treating the watchpoint in that - state as `not changed' without further checking. */ - if (within_current_scope && fr == get_current_frame () + state as `not changed' without further checking. + + vinschen/2003-09-04: The former implementation left out the case + that the watchpoint frame couldn't be found by frame_find_by_id() + because the current PC is currently in an epilogue. Calling + gdbarch_in_function_epilogue_p() also when fr == NULL fixes that. */ + if ((!within_current_scope || fr == get_current_frame ()) && gdbarch_in_function_epilogue_p (current_gdbarch, read_pc ())) return WP_VALUE_NOT_CHANGED; - if (within_current_scope) + if (fr && within_current_scope) /* If we end up stopping, the current frame will get selected in normal_stop. So this call to select_frame won't affect the user. */ - select_frame (fr, -1); + select_frame (fr); } if (within_current_scope) @@ -2328,11 +2581,8 @@ which its expression is valid.\n"); } } -/* Get a bpstat associated with having just stopped at address *PC - and frame address CORE_ADDRESS. Update *PC to point at the - breakpoint (if we hit a breakpoint). NOT_A_BREAKPOINT is nonzero - if this is known to not be a real breakpoint (it could still be a - watchpoint, though). */ +/* Get a bpstat associated with having just stopped at address + BP_ADDR. */ /* Determine whether we stopped at a breakpoint, etc, or whether we don't understand this stop. Result is a chain of bpstat's such that: @@ -2349,34 +2599,20 @@ which its expression is valid.\n"); commands, FIXME??? fields. */ bpstat -bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) +bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid) { - register struct breakpoint *b, *temp; - CORE_ADDR bp_addr; + struct breakpoint *b, *temp; /* True if we've hit a breakpoint (as opposed to a watchpoint). */ int real_breakpoint = 0; /* Root of the chain of bpstat's */ struct bpstats root_bs[1]; /* Pointer to the last thing in the chain currently. */ bpstat bs = root_bs; - static char message1[] = - "Error evaluating expression for watchpoint %d\n"; - char message[sizeof (message1) + 30 /* slop */ ]; - - /* Get the address where the breakpoint would have been. - The "not_a_breakpoint" argument is meant to distinguish - between a breakpoint trap event and a trace/singlestep - trap event. For a trace/singlestep trap event, we would - not want to subtract DECR_PC_AFTER_BREAK from the PC. */ - - bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P () ? - 0 : DECR_PC_AFTER_BREAK); + int thread_id = pid_to_thread_id (ptid); ALL_BREAKPOINTS_SAFE (b, temp) { - if (b->enable_state == bp_disabled - || b->enable_state == bp_shlib_disabled - || b->enable_state == bp_call_disabled) + if (!breakpoint_enabled (b) && b->enable_state != bp_permanent) continue; if (b->type != bp_watchpoint @@ -2390,17 +2626,23 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) && b->type != bp_catch_catch && b->type != bp_catch_throw) /* a non-watchpoint bp */ { - if (b->address != bp_addr) /* address doesn't match */ + if (b->loc->address != bp_addr) /* address doesn't match */ continue; if (overlay_debugging /* unmapped overlay section */ - && section_is_overlay (b->section) - && !section_is_mapped (b->section)) + && section_is_overlay (b->loc->section) + && !section_is_mapped (b->loc->section)) continue; } - if (b->type == bp_hardware_breakpoint - && b->address != (*pc - DECR_PC_AFTER_HW_BREAK)) - continue; + if (b->type == bp_hardware_breakpoint) + { + if (b->loc->address != bp_addr) + continue; + if (overlay_debugging /* unmapped overlay section */ + && section_is_overlay (b->loc->section) + && !section_is_mapped (b->loc->section)) + continue; + } /* Is this a catchpoint of a load or unload? If so, did we get a load or unload of the specified library? If not, @@ -2430,17 +2672,17 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) continue; if ((b->type == bp_catch_fork) - && !target_has_forked (PIDGET (inferior_ptid), - &b->forked_inferior_pid)) + && !inferior_has_forked (PIDGET (inferior_ptid), + &b->forked_inferior_pid)) continue; if ((b->type == bp_catch_vfork) - && !target_has_vforked (PIDGET (inferior_ptid), - &b->forked_inferior_pid)) + && !inferior_has_vforked (PIDGET (inferior_ptid), + &b->forked_inferior_pid)) continue; if ((b->type == bp_catch_exec) - && !target_has_execd (PIDGET (inferior_ptid), &b->exec_pathname)) + && !inferior_has_execd (PIDGET (inferior_ptid), &b->exec_pathname)) continue; if (ep_is_exception_catchpoint (b) && @@ -2455,12 +2697,16 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) bs->stop = 1; bs->print = 1; - sprintf (message, message1, b->number); if (b->type == bp_watchpoint || b->type == bp_hardware_watchpoint) { - switch (catch_errors (watchpoint_check, bs, message, - RETURN_MASK_ALL)) + char *message = xstrprintf ("Error evaluating expression for watchpoint %d\n", + b->number); + struct cleanup *cleanups = make_cleanup (xfree, message); + int e = catch_errors (watchpoint_check, bs, message, + RETURN_MASK_ALL); + do_cleanups (cleanups); + switch (e) { case WP_DELETED: /* We've already printed what needs to be printed. */ @@ -2528,42 +2774,49 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) } } if (found) - switch (catch_errors (watchpoint_check, bs, message, - RETURN_MASK_ALL)) - { - case WP_DELETED: - /* We've already printed what needs to be printed. */ - bs->print_it = print_it_done; - /* Stop. */ - break; - case WP_VALUE_CHANGED: - if (b->type == bp_read_watchpoint) - { - /* Don't stop: read watchpoints shouldn't fire if - the value has changed. This is for targets which - cannot set read-only watchpoints. */ - bs->print_it = print_it_noop; - bs->stop = 0; - continue; - } - ++(b->hit_count); - break; - case WP_VALUE_NOT_CHANGED: - /* Stop. */ - ++(b->hit_count); - break; - default: - /* Can't happen. */ - case 0: - /* Error from catch_errors. */ - printf_filtered ("Watchpoint %d deleted.\n", b->number); - if (b->related_breakpoint) - b->related_breakpoint->disposition = disp_del_at_next_stop; - b->disposition = disp_del_at_next_stop; - /* We've already printed what needs to be printed. */ - bs->print_it = print_it_done; - break; - } + { + char *message = xstrprintf ("Error evaluating expression for watchpoint %d\n", + b->number); + struct cleanup *cleanups = make_cleanup (xfree, message); + int e = catch_errors (watchpoint_check, bs, message, + RETURN_MASK_ALL); + do_cleanups (cleanups); + switch (e) + { + case WP_DELETED: + /* We've already printed what needs to be printed. */ + bs->print_it = print_it_done; + /* Stop. */ + break; + case WP_VALUE_CHANGED: + if (b->type == bp_read_watchpoint) + { + /* Don't stop: read watchpoints shouldn't fire if + the value has changed. This is for targets + which cannot set read-only watchpoints. */ + bs->print_it = print_it_noop; + bs->stop = 0; + continue; + } + ++(b->hit_count); + break; + case WP_VALUE_NOT_CHANGED: + /* Stop. */ + ++(b->hit_count); + break; + default: + /* Can't happen. */ + case 0: + /* Error from catch_errors. */ + printf_filtered ("Watchpoint %d deleted.\n", b->number); + if (b->related_breakpoint) + b->related_breakpoint->disposition = disp_del_at_next_stop; + b->disposition = disp_del_at_next_stop; + /* We've already printed what needs to be printed. */ + bs->print_it = print_it_done; + break; + } + } else /* found == 0 */ { /* This is a case where some watchpoint(s) triggered, @@ -2584,8 +2837,8 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) real_breakpoint = 1; } - if (b->frame && - b->frame != (get_current_frame ())->frame) + if (frame_id_p (b->frame_id) + && !frame_id_eq (b->frame_id, get_frame_id (get_current_frame ()))) bs->stop = 0; else { @@ -2595,7 +2848,7 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) { /* Need to select the frame, with all that implies so that the conditions will have the right context. */ - select_frame (get_current_frame (), 0); + select_frame (get_current_frame ()); value_is_zero = catch_errors (breakpoint_cond_eval, (b->cond), "Error in testing breakpoint condition:\n", @@ -2609,6 +2862,12 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) /* Don't consider this a hit. */ --(b->hit_count); } + else if (b->thread != -1 && b->thread != thread_id) + { + bs->stop = 0; + /* Don't consider this a hit. */ + --(b->hit_count); + } else if (b->ignore_count > 0) { b->ignore_count--; @@ -2620,16 +2879,17 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) /* We will stop here */ if (b->disposition == disp_disable) b->enable_state = bp_disabled; - bs->commands = b->commands; if (b->silent) bs->print = 0; + bs->commands = b->commands; if (bs->commands && - (STREQ ("silent", bs->commands->line) || - (xdb_commands && STREQ ("Q", bs->commands->line)))) + (strcmp ("silent", bs->commands->line) == 0 + || (xdb_commands && strcmp ("Q", bs->commands->line) == 0))) { bs->commands = bs->commands->next; bs->print = 0; } + bs->commands = copy_command_lines (bs->commands); } } /* Print nothing for this entry if we dont stop or if we dont print. */ @@ -2640,30 +2900,6 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) bs->next = NULL; /* Terminate the chain */ bs = root_bs->next; /* Re-grab the head of the chain */ - if (real_breakpoint && bs) - { - if (bs->breakpoint_at->type == bp_hardware_breakpoint) - { - if (DECR_PC_AFTER_HW_BREAK != 0) - { - *pc = *pc - DECR_PC_AFTER_HW_BREAK; - write_pc (*pc); - } - } - else - { - if (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs) - { - *pc = bp_addr; -#if defined (SHIFT_INST_REGS) - SHIFT_INST_REGS (); -#else /* No SHIFT_INST_REGS. */ - write_pc (bp_addr); -#endif /* No SHIFT_INST_REGS. */ - } - } - } - /* The value of a hardware watchpoint hasn't changed, but the intermediate memory locations we are watching may have. */ if (bs && !bs->stop && @@ -2780,7 +3016,7 @@ bpstat_what (bpstat bs) /* step_resume entries: a step resume breakpoint overrides another breakpoint of signal handling (see comment in wait_for_inferior - at first IN_SIGTRAMP where we set the step_resume breakpoint). */ + at first PC_IN_SIGTRAMP where we set the step_resume breakpoint). */ /* We handle the through_sigtramp_breakpoint the same way; having both one of those and a step_resume_breakpoint is probably very rare (?). */ @@ -2961,7 +3197,7 @@ bpstat_should_step (void) { struct breakpoint *b; ALL_BREAKPOINTS (b) - if (b->enable_state == bp_enabled && b->type == bp_watchpoint) + if (breakpoint_enabled (b) && b->type == bp_watchpoint) return 1; return 0; } @@ -2970,13 +3206,11 @@ bpstat_should_step (void) int bpstat_have_active_hw_watchpoints (void) { - struct breakpoint *b; - ALL_BREAKPOINTS (b) - if ((b->enable_state == bp_enabled) && - (b->inserted) && - ((b->type == bp_hardware_watchpoint) || - (b->type == bp_read_watchpoint) || - (b->type == bp_access_watchpoint))) + struct bp_location *bpt; + ALL_BP_LOCATIONS (bpt) + if (breakpoint_enabled (bpt->owner) + && bpt->inserted + && bpt->loc_type == bp_loc_hardware_watchpoint) return 1; return 0; } @@ -3050,8 +3284,8 @@ static void print_one_breakpoint (struct breakpoint *b, CORE_ADDR *last_addr) { - register struct command_line *l; - register struct symbol *sym; + struct command_line *l; + struct symbol *sym; struct ep_type_description { enum bptype type; @@ -3092,9 +3326,10 @@ print_one_breakpoint (struct breakpoint *b, char wrap_indent[80]; struct ui_stream *stb = ui_out_stream_new (uiout); struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb); + struct cleanup *bkpt_chain; annotate_record (); - ui_out_tuple_begin (uiout, "bkpt"); + bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt"); /* 1 */ annotate_field (0); @@ -3127,143 +3362,154 @@ print_one_breakpoint (struct breakpoint *b, else strcat (wrap_indent, " "); } - switch (b->type) - { - case bp_none: - internal_error (__FILE__, __LINE__, - "print_one_breakpoint: bp_none encountered\n"); - break; - case bp_watchpoint: - case bp_hardware_watchpoint: - case bp_read_watchpoint: - case bp_access_watchpoint: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - if (addressprint) - ui_out_field_skip (uiout, "addr"); - annotate_field (5); - print_expression (b->exp, stb->stream); - ui_out_field_stream (uiout, "what", stb); - break; - - case bp_catch_load: - case bp_catch_unload: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - if (addressprint) - ui_out_field_skip (uiout, "addr"); - annotate_field (5); - if (b->dll_pathname == NULL) - { - ui_out_field_string (uiout, "what", ""); - ui_out_spaces (uiout, 1); - } - else - { - ui_out_text (uiout, "library \""); - ui_out_field_string (uiout, "what", b->dll_pathname); - ui_out_text (uiout, "\" "); - } - break; - - case bp_catch_fork: - case bp_catch_vfork: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - if (addressprint) - ui_out_field_skip (uiout, "addr"); - annotate_field (5); - if (b->forked_inferior_pid != 0) - { - ui_out_text (uiout, "process "); - ui_out_field_int (uiout, "what", b->forked_inferior_pid); - ui_out_spaces (uiout, 1); - } - - case bp_catch_exec: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - if (addressprint) - ui_out_field_skip (uiout, "addr"); - annotate_field (5); - if (b->exec_pathname != NULL) - { - ui_out_text (uiout, "program \""); - ui_out_field_string (uiout, "what", b->exec_pathname); - ui_out_text (uiout, "\" "); - } - break; + if (b->ops != NULL && b->ops->print_one != NULL) + b->ops->print_one (b, last_addr); + else + switch (b->type) + { + case bp_none: + internal_error (__FILE__, __LINE__, + "print_one_breakpoint: bp_none encountered\n"); + break; - case bp_catch_catch: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - if (addressprint) - ui_out_field_skip (uiout, "addr"); - annotate_field (5); - ui_out_field_string (uiout, "what", "exception catch"); - ui_out_spaces (uiout, 1); - break; + case bp_watchpoint: + case bp_hardware_watchpoint: + case bp_read_watchpoint: + case bp_access_watchpoint: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + if (addressprint) + ui_out_field_skip (uiout, "addr"); + annotate_field (5); + print_expression (b->exp, stb->stream); + ui_out_field_stream (uiout, "what", stb); + break; + + case bp_catch_load: + case bp_catch_unload: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + if (addressprint) + ui_out_field_skip (uiout, "addr"); + annotate_field (5); + if (b->dll_pathname == NULL) + { + ui_out_field_string (uiout, "what", ""); + ui_out_spaces (uiout, 1); + } + else + { + ui_out_text (uiout, "library \""); + ui_out_field_string (uiout, "what", b->dll_pathname); + ui_out_text (uiout, "\" "); + } + break; + + case bp_catch_fork: + case bp_catch_vfork: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + if (addressprint) + ui_out_field_skip (uiout, "addr"); + annotate_field (5); + if (b->forked_inferior_pid != 0) + { + ui_out_text (uiout, "process "); + ui_out_field_int (uiout, "what", b->forked_inferior_pid); + ui_out_spaces (uiout, 1); + } + + case bp_catch_exec: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + if (addressprint) + ui_out_field_skip (uiout, "addr"); + annotate_field (5); + if (b->exec_pathname != NULL) + { + ui_out_text (uiout, "program \""); + ui_out_field_string (uiout, "what", b->exec_pathname); + ui_out_text (uiout, "\" "); + } + break; + + case bp_catch_catch: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + if (addressprint) + ui_out_field_skip (uiout, "addr"); + annotate_field (5); + ui_out_field_string (uiout, "what", "exception catch"); + ui_out_spaces (uiout, 1); + break; + + case bp_catch_throw: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + if (addressprint) + ui_out_field_skip (uiout, "addr"); + annotate_field (5); + ui_out_field_string (uiout, "what", "exception throw"); + ui_out_spaces (uiout, 1); + break; + + case bp_breakpoint: + case bp_hardware_breakpoint: + case bp_until: + case bp_finish: + case bp_longjmp: + case bp_longjmp_resume: + case bp_step_resume: + case bp_through_sigtramp: + case bp_watchpoint_scope: + case bp_call_dummy: + case bp_shlib_event: + case bp_thread_event: + case bp_overlay_event: + if (addressprint) + { + annotate_field (4); + if (b->pending) + ui_out_field_string (uiout, "addr", ""); + else + ui_out_field_core_addr (uiout, "addr", b->loc->address); + } + annotate_field (5); + *last_addr = b->loc->address; + if (b->source_file) + { + sym = find_pc_sect_function (b->loc->address, b->loc->section); + if (sym) + { + ui_out_text (uiout, "in "); + ui_out_field_string (uiout, "func", + SYMBOL_PRINT_NAME (sym)); + ui_out_wrap_hint (uiout, wrap_indent); + ui_out_text (uiout, " at "); + } + ui_out_field_string (uiout, "file", b->source_file); + ui_out_text (uiout, ":"); + ui_out_field_int (uiout, "line", b->line_number); + } + else if (b->pending) + { + ui_out_field_string (uiout, "pending", b->addr_string); + } + else + { + print_address_symbolic (b->loc->address, stb->stream, demangle, ""); + ui_out_field_stream (uiout, "at", stb); + } + break; + } - case bp_catch_throw: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - if (addressprint) - ui_out_field_skip (uiout, "addr"); - annotate_field (5); - ui_out_field_string (uiout, "what", "exception throw"); - ui_out_spaces (uiout, 1); - break; - - case bp_breakpoint: - case bp_hardware_breakpoint: - case bp_until: - case bp_finish: - case bp_longjmp: - case bp_longjmp_resume: - case bp_step_resume: - case bp_through_sigtramp: - case bp_watchpoint_scope: - case bp_call_dummy: - case bp_shlib_event: - case bp_thread_event: - case bp_overlay_event: - if (addressprint) - { - annotate_field (4); - ui_out_field_core_addr (uiout, "addr", b->address); - } - annotate_field (5); - *last_addr = b->address; - if (b->source_file) - { - sym = find_pc_sect_function (b->address, b->section); - if (sym) - { - ui_out_text (uiout, "in "); - ui_out_field_string (uiout, "func", - SYMBOL_SOURCE_NAME (sym)); - ui_out_wrap_hint (uiout, wrap_indent); - ui_out_text (uiout, " at "); - } - ui_out_field_string (uiout, "file", b->source_file); - ui_out_text (uiout, ":"); - ui_out_field_int (uiout, "line", b->line_number); - } - else - { - print_address_symbolic (b->address, stb->stream, demangle, ""); - ui_out_field_stream (uiout, "at", stb); - } - break; - } - if (b->thread != -1) { /* FIXME: This seems to be redundant and lost here; see the @@ -3274,11 +3520,13 @@ print_one_breakpoint (struct breakpoint *b, ui_out_text (uiout, "\n"); - if (b->frame) + if (frame_id_p (b->frame_id)) { annotate_field (6); ui_out_text (uiout, "\tstop only in stack frame at "); - ui_out_field_core_addr (uiout, "frame", b->frame); + /* FIXME: cagney/2002-12-01: Shouldn't be poeking around inside + the frame ID. */ + ui_out_field_core_addr (uiout, "frame", b->frame_id.stack_addr); ui_out_text (uiout, "\n"); } @@ -3290,7 +3538,15 @@ print_one_breakpoint (struct breakpoint *b, ui_out_field_stream (uiout, "cond", stb); ui_out_text (uiout, "\n"); } - + + if (b->pending && b->cond_string) + { + annotate_field (7); + ui_out_text (uiout, "\tstop only if "); + ui_out_field_string (uiout, "cond", b->cond_string); + ui_out_text (uiout, "\n"); + } + if (b->thread != -1) { /* FIXME should make an annotation for this */ @@ -3330,12 +3586,14 @@ print_one_breakpoint (struct breakpoint *b, if ((l = b->commands)) { + struct cleanup *script_chain; + annotate_field (9); - ui_out_tuple_begin (uiout, "script"); + script_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "script"); print_command_lines (uiout, l, 4); - ui_out_tuple_end (uiout); + do_cleanups (script_chain); } - ui_out_tuple_end (uiout); + do_cleanups (bkpt_chain); do_cleanups (old_chain); } @@ -3348,7 +3606,7 @@ static int do_captured_breakpoint_query (struct ui_out *uiout, void *data) { struct captured_breakpoint_query_args *args = data; - register struct breakpoint *b; + struct breakpoint *b; CORE_ADDR dummy_addr = 0; ALL_BREAKPOINTS (b) { @@ -3400,9 +3658,10 @@ user_settable_breakpoint (const struct breakpoint *b) static void breakpoint_1 (int bnum, int allflag) { - register struct breakpoint *b; + struct breakpoint *b; CORE_ADDR last_addr = (CORE_ADDR) -1; int nr_printable_breakpoints; + struct cleanup *bkpttbl_chain; /* Compute the number of rows in the table. */ nr_printable_breakpoints = 0; @@ -3415,9 +3674,13 @@ breakpoint_1 (int bnum, int allflag) } if (addressprint) - ui_out_table_begin (uiout, 6, nr_printable_breakpoints, "BreakpointTable"); + bkpttbl_chain + = make_cleanup_ui_out_table_begin_end (uiout, 6, nr_printable_breakpoints, + "BreakpointTable"); else - ui_out_table_begin (uiout, 5, nr_printable_breakpoints, "BreakpointTable"); + bkpttbl_chain + = make_cleanup_ui_out_table_begin_end (uiout, 5, nr_printable_breakpoints, + "BreakpointTable"); if (nr_printable_breakpoints > 0) annotate_breakpoints_headers (); @@ -3459,7 +3722,7 @@ breakpoint_1 (int bnum, int allflag) print_one_breakpoint (b, &last_addr); } - ui_out_table_end (uiout); + do_cleanups (bkpttbl_chain); if (nr_printable_breakpoints == 0) { @@ -3482,7 +3745,6 @@ breakpoint_1 (int bnum, int allflag) annotate_breakpoints_table_end (); } -/* ARGSUSED */ static void breakpoints_info (char *bnum_exp, int from_tty) { @@ -3494,7 +3756,6 @@ breakpoints_info (char *bnum_exp, int from_tty) breakpoint_1 (bnum, 0); } -/* ARGSUSED */ static void maintenance_info_breakpoints (char *bnum_exp, int from_tty) { @@ -3511,19 +3772,19 @@ maintenance_info_breakpoints (char *bnum_exp, int from_tty) static void describe_other_breakpoints (CORE_ADDR pc, asection *section) { - register int others = 0; - register struct breakpoint *b; + int others = 0; + struct breakpoint *b; ALL_BREAKPOINTS (b) - if (b->address == pc) /* address match / overlay match */ - if (!overlay_debugging || b->section == section) + if (b->loc->address == pc) /* address match / overlay match */ + if (!b->pending && (!overlay_debugging || b->loc->section == section)) others++; if (others > 0) { printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : ""); ALL_BREAKPOINTS (b) - if (b->address == pc) /* address match / overlay match */ - if (!overlay_debugging || b->section == section) + if (b->loc->address == pc) /* address match / overlay match */ + if (!b->pending && (!overlay_debugging || b->loc->section == section)) { others--; printf_filtered ("%d%s%s ", @@ -3600,25 +3861,26 @@ breakpoint_address_is_meaningful (struct breakpoint *bpt) static void check_duplicates (struct breakpoint *bpt) { - register struct breakpoint *b; - register int count = 0; - struct breakpoint *perm_bp = 0; - CORE_ADDR address = bpt->address; - asection *section = bpt->section; + struct bp_location *b; + int count = 0; + struct bp_location *perm_bp = 0; + CORE_ADDR address = bpt->loc->address; + asection *section = bpt->loc->section; if (! breakpoint_address_is_meaningful (bpt)) return; - ALL_BREAKPOINTS (b) - if (b->enable_state != bp_disabled - && b->enable_state != bp_shlib_disabled - && b->enable_state != bp_call_disabled + ALL_BP_LOCATIONS (b) + if (b->owner->enable_state != bp_disabled + && b->owner->enable_state != bp_shlib_disabled + && !b->owner->pending + && b->owner->enable_state != bp_call_disabled && b->address == address /* address / overlay match */ && (!overlay_debugging || b->section == section) - && breakpoint_address_is_meaningful (b)) + && breakpoint_address_is_meaningful (b->owner)) { /* Have we found a permanent breakpoint? */ - if (b->enable_state == bp_permanent) + if (b->owner->enable_state == bp_permanent) { perm_bp = b; break; @@ -3641,25 +3903,141 @@ check_duplicates (struct breakpoint *bpt) "allegedly permanent breakpoint is not " "actually inserted"); - ALL_BREAKPOINTS (b) + ALL_BP_LOCATIONS (b) if (b != perm_bp) { - if (b->inserted) - internal_error (__FILE__, __LINE__, - "another breakpoint was inserted on top of " - "a permanent breakpoint"); - - if (b->enable_state != bp_disabled - && b->enable_state != bp_shlib_disabled - && b->enable_state != bp_call_disabled + if (b->owner->enable_state != bp_disabled + && b->owner->enable_state != bp_shlib_disabled + && !b->owner->pending + && b->owner->enable_state != bp_call_disabled && b->address == address /* address / overlay match */ && (!overlay_debugging || b->section == section) - && breakpoint_address_is_meaningful (b)) - b->duplicate = 1; + && breakpoint_address_is_meaningful (b->owner)) + { + if (b->inserted) + internal_error (__FILE__, __LINE__, + "another breakpoint was inserted on top of " + "a permanent breakpoint"); + + b->duplicate = 1; + } } } } +static void +breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr, + int bnum, int have_bnum) +{ + char astr1[40]; + char astr2[40]; + + strcpy (astr1, local_hex_string_custom ((unsigned long) from_addr, "08l")); + strcpy (astr2, local_hex_string_custom ((unsigned long) to_addr, "08l")); + if (have_bnum) + warning ("Breakpoint %d address previously adjusted from %s to %s.", + bnum, astr1, astr2); + else + warning ("Breakpoint address adjusted from %s to %s.", astr1, astr2); +} + +/* Adjust a breakpoint's address to account for architectural constraints + on breakpoint placement. Return the adjusted address. Note: Very + few targets require this kind of adjustment. For most targets, + this function is simply the identity function. */ + +static CORE_ADDR +adjust_breakpoint_address (CORE_ADDR bpaddr) +{ + if (!gdbarch_adjust_breakpoint_address_p (current_gdbarch)) + { + /* Very few targets need any kind of breakpoint adjustment. */ + return bpaddr; + } + else + { + CORE_ADDR adjusted_bpaddr; + + /* Some targets have architectural constraints on the placement + of breakpoint instructions. Obtain the adjusted address. */ + adjusted_bpaddr = gdbarch_adjust_breakpoint_address (current_gdbarch, + bpaddr); + + /* An adjusted breakpoint address can significantly alter + a user's expectations. Print a warning if an adjustment + is required. */ + if (adjusted_bpaddr != bpaddr) + breakpoint_adjustment_warning (bpaddr, adjusted_bpaddr, 0, 0); + + return adjusted_bpaddr; + } +} + +/* Allocate a struct bp_location. */ + +static struct bp_location * +allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type) +{ + struct bp_location *loc, *loc_p; + + loc = xmalloc (sizeof (struct bp_location)); + memset (loc, 0, sizeof (*loc)); + + loc->owner = bpt; + + switch (bp_type) + { + case bp_breakpoint: + case bp_until: + case bp_finish: + case bp_longjmp: + case bp_longjmp_resume: + case bp_step_resume: + case bp_through_sigtramp: + case bp_watchpoint_scope: + case bp_call_dummy: + case bp_shlib_event: + case bp_thread_event: + case bp_overlay_event: + case bp_catch_load: + case bp_catch_unload: + loc->loc_type = bp_loc_software_breakpoint; + break; + case bp_hardware_breakpoint: + loc->loc_type = bp_loc_hardware_breakpoint; + break; + case bp_hardware_watchpoint: + case bp_read_watchpoint: + case bp_access_watchpoint: + loc->loc_type = bp_loc_hardware_watchpoint; + break; + case bp_watchpoint: + case bp_catch_fork: + case bp_catch_vfork: + case bp_catch_exec: + case bp_catch_catch: + case bp_catch_throw: + loc->loc_type = bp_loc_other; + break; + default: + internal_error (__FILE__, __LINE__, "unknown breakpoint type"); + } + + /* Add this breakpoint to the end of the chain. */ + + loc_p = bp_location_chain; + if (loc_p == 0) + bp_location_chain = loc; + else + { + while (loc_p->next) + loc_p = loc_p->next; + loc_p->next = loc; + } + + return loc; +} + /* set_raw_breakpoint() is a low level routine for allocating and partially initializing a breakpoint of type BPTYPE. The newly created breakpoint's address, section, source file name, and line @@ -3678,17 +4056,19 @@ check_duplicates (struct breakpoint *bpt) struct breakpoint * set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype) { - register struct breakpoint *b, *b1; + struct breakpoint *b, *b1; b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint)); memset (b, 0, sizeof (*b)); - b->address = sal.pc; + b->loc = allocate_bp_location (b, bptype); + b->loc->requested_address = sal.pc; + b->loc->address = adjust_breakpoint_address (b->loc->requested_address); if (sal.symtab == NULL) b->source_file = NULL; else b->source_file = savestring (sal.symtab->filename, strlen (sal.symtab->filename)); - b->section = sal.section; + b->loc->section = sal.section; b->type = bptype; b->language = current_language->la_language; b->input_radix = input_radix; @@ -3699,11 +4079,13 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype) b->silent = 0; b->ignore_count = 0; b->commands = NULL; - b->frame = 0; + b->frame_id = null_frame_id; b->dll_pathname = NULL; b->triggered_dll_pathname = NULL; b->forked_inferior_pid = 0; b->exec_pathname = NULL; + b->ops = NULL; + b->pending = 0; /* Add this breakpoint to the end of the chain so that a list of breakpoints will come out in order @@ -3734,7 +4116,7 @@ make_breakpoint_permanent (struct breakpoint *b) b->enable_state = bp_permanent; /* By definition, permanent breakpoints are already present in the code. */ - b->inserted = 1; + b->loc->inserted = 1; } static struct breakpoint * @@ -3744,7 +4126,7 @@ create_internal_breakpoint (CORE_ADDR address, enum bptype type) struct symtab_and_line sal; struct breakpoint *b; - INIT_SAL (&sal); /* initialize to zeroes */ + init_sal (&sal); /* initialize to zeroes */ sal.pc = address; sal.section = find_pc_overlay (sal.pc); @@ -3767,7 +4149,7 @@ create_longjmp_breakpoint (char *func_name) b = create_internal_breakpoint (0, bp_longjmp_resume); else { - if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL) + if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL) return; b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp); @@ -3786,7 +4168,7 @@ create_longjmp_breakpoint (char *func_name) void enable_longjmp_breakpoint (void) { - register struct breakpoint *b; + struct breakpoint *b; ALL_BREAKPOINTS (b) if (b->type == bp_longjmp) @@ -3799,7 +4181,7 @@ enable_longjmp_breakpoint (void) void disable_longjmp_breakpoint (void) { - register struct breakpoint *b; + struct breakpoint *b; ALL_BREAKPOINTS (b) if (b->type == bp_longjmp @@ -3816,7 +4198,7 @@ create_overlay_event_breakpoint (char *func_name) struct breakpoint *b; struct minimal_symbol *m; - if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL) + if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL) return; b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), @@ -3824,34 +4206,42 @@ create_overlay_event_breakpoint (char *func_name) b->addr_string = xstrdup (func_name); if (overlay_debugging == ovly_auto) - b->enable_state = bp_enabled; + { + b->enable_state = bp_enabled; + overlay_events_enabled = 1; + } else - b->enable_state = bp_disabled; + { + b->enable_state = bp_disabled; + overlay_events_enabled = 0; + } } void enable_overlay_breakpoints (void) { - register struct breakpoint *b; + struct breakpoint *b; ALL_BREAKPOINTS (b) if (b->type == bp_overlay_event) { b->enable_state = bp_enabled; check_duplicates (b); + overlay_events_enabled = 1; } } void disable_overlay_breakpoints (void) { - register struct breakpoint *b; + struct breakpoint *b; ALL_BREAKPOINTS (b) if (b->type == bp_overlay_event) { b->enable_state = bp_disabled; check_duplicates (b); + overlay_events_enabled = 0; } } @@ -3859,14 +4249,12 @@ struct breakpoint * create_thread_event_breakpoint (CORE_ADDR address) { struct breakpoint *b; - char addr_string[80]; /* Surely an addr can't be longer than that. */ b = create_internal_breakpoint (address, bp_thread_event); b->enable_state = bp_enabled; /* addr_string has to be used or breakpoint_re_set will delete me. */ - sprintf (addr_string, "*0x%s", paddr (b->address)); - b->addr_string = xstrdup (addr_string); + xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address)); return b; } @@ -3881,11 +4269,71 @@ remove_thread_event_breakpoints (void) delete_breakpoint (b); } +struct captured_parse_breakpoint_args + { + char **arg_p; + struct symtabs_and_lines *sals_p; + char ***addr_string_p; + int *not_found_ptr; + }; + +struct lang_and_radix + { + enum language lang; + int radix; + }; + +/* Cleanup helper routine to restore the current language and + input radix. */ +static void +do_restore_lang_radix_cleanup (void *old) +{ + struct lang_and_radix *p = old; + set_language (p->lang); + input_radix = p->radix; +} + +/* Try and resolve a pending breakpoint. */ +static int +resolve_pending_breakpoint (struct breakpoint *b) +{ + /* Try and reparse the breakpoint in case the shared library + is now loaded. */ + struct symtabs_and_lines sals; + struct symtab_and_line pending_sal; + char **cond_string = (char **) NULL; + char *copy_arg = b->addr_string; + char **addr_string; + char *errmsg; + int rc; + int not_found = 0; + struct ui_file *old_gdb_stderr; + struct lang_and_radix old_lr; + struct cleanup *old_chain; + + /* Set language, input-radix, then reissue breakpoint command. + Ensure the language and input-radix are restored afterwards. */ + old_lr.lang = current_language->la_language; + old_lr.radix = input_radix; + old_chain = make_cleanup (do_restore_lang_radix_cleanup, &old_lr); + + set_language (b->language); + input_radix = b->input_radix; + rc = break_command_1 (b->addr_string, b->flag, b->from_tty, b); + + if (rc == GDB_RC_OK) + /* Pending breakpoint has been resolved. */ + printf_filtered ("Pending breakpoint \"%s\" resolved\n", b->addr_string); + + do_cleanups (old_chain); + return rc; +} + #ifdef SOLIB_ADD void remove_solib_event_breakpoints (void) { - register struct breakpoint *b, *temp; + struct breakpoint *b, *temp; ALL_BREAKPOINTS_SAFE (b, temp) if (b->type == bp_shlib_event) @@ -3916,9 +4364,9 @@ disable_breakpoints_in_shlibs (int silent) #if defined (PC_SOLIB) if (((b->type == bp_breakpoint) || (b->type == bp_hardware_breakpoint)) && - b->enable_state == bp_enabled && - !b->duplicate && - PC_SOLIB (b->address)) + breakpoint_enabled (b) && + !b->loc->duplicate && + PC_SOLIB (b->loc->address)) { b->enable_state = bp_shlib_disabled; if (!silent) @@ -3940,18 +4388,26 @@ disable_breakpoints_in_shlibs (int silent) void re_enable_breakpoints_in_shlibs (void) { - struct breakpoint *b; + struct breakpoint *b, *tmp; - ALL_BREAKPOINTS (b) + ALL_BREAKPOINTS_SAFE (b, tmp) + { if (b->enable_state == bp_shlib_disabled) - { - char buf[1]; - - /* Do not reenable the breakpoint if the shared library - is still not mapped in. */ - if (target_read_memory (b->address, buf, 1) == 0) - b->enable_state = bp_enabled; - } + { + char buf[1], *lib; + + /* Do not reenable the breakpoint if the shared library + is still not mapped in. */ + lib = PC_SOLIB (b->loc->address); + if (lib != NULL && target_read_memory (b->loc->address, buf, 1) == 0) + b->enable_state = bp_enabled; + } + else if (b->pending && (b->enable_state == bp_enabled)) + { + if (resolve_pending_breakpoint (b) == GDB_RC_OK) + delete_breakpoint (b); + } + } } #endif @@ -3970,7 +4426,7 @@ solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname, int thread = -1; /* All threads. */ /* Set a breakpoint on the specified hook. */ - sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical); + sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical, NULL); addr_end = hookname; if (sals.nelts == 0) @@ -4056,7 +4512,7 @@ create_fork_vfork_event_catchpoint (int tempflag, char *cond_string, struct breakpoint *b; int thread = -1; /* All threads. */ - INIT_SAL (&sal); + init_sal (&sal); sal.pc = 0; sal.symtab = NULL; sal.line = 0; @@ -4095,7 +4551,7 @@ create_exec_event_catchpoint (int tempflag, char *cond_string) struct breakpoint *b; int thread = -1; /* All threads. */ - INIT_SAL (&sal); + init_sal (&sal); sal.pc = 0; sal.symtab = NULL; sal.line = 0; @@ -4117,7 +4573,7 @@ create_exec_event_catchpoint (int tempflag, char *cond_string) static int hw_breakpoint_used_count (void) { - register struct breakpoint *b; + struct breakpoint *b; int i = 0; ALL_BREAKPOINTS (b) @@ -4132,20 +4588,19 @@ hw_breakpoint_used_count (void) static int hw_watchpoint_used_count (enum bptype type, int *other_type_used) { - register struct breakpoint *b; + struct breakpoint *b; int i = 0; *other_type_used = 0; ALL_BREAKPOINTS (b) { - if (b->enable_state == bp_enabled) + if (breakpoint_enabled (b)) { if (b->type == type) i++; else if ((b->type == bp_hardware_watchpoint || b->type == bp_read_watchpoint || - b->type == bp_access_watchpoint) - && b->enable_state == bp_enabled) + b->type == bp_access_watchpoint)) *other_type_used = 1; } } @@ -4159,19 +4614,17 @@ hw_watchpoint_used_count (enum bptype type, int *other_type_used) that gets deleted automatically... */ void -set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_info *frame) +set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id) { - register struct breakpoint *b; + struct breakpoint *b; ALL_BREAKPOINTS (b) if (b->type == bp_longjmp_resume) { - b->address = pc; + b->loc->requested_address = pc; + b->loc->address = adjust_breakpoint_address (b->loc->requested_address); b->enable_state = bp_enabled; - if (frame != NULL) - b->frame = frame->frame; - else - b->frame = 0; + b->frame_id = frame_id; check_duplicates (b); return; } @@ -4189,7 +4642,7 @@ disable_watchpoints_before_interactive_call_start (void) || (b->type == bp_read_watchpoint) || (b->type == bp_access_watchpoint) || ep_is_exception_catchpoint (b)) - && (b->enable_state == bp_enabled)) + && breakpoint_enabled (b)) { b->enable_state = bp_call_disabled; check_duplicates (b); @@ -4223,14 +4676,14 @@ enable_watchpoints_after_interactive_call_stop (void) Restrict it to frame FRAME if FRAME is nonzero. */ struct breakpoint * -set_momentary_breakpoint (struct symtab_and_line sal, struct frame_info *frame, +set_momentary_breakpoint (struct symtab_and_line sal, struct frame_id frame_id, enum bptype type) { - register struct breakpoint *b; + struct breakpoint *b; b = set_raw_breakpoint (sal, type); b->enable_state = bp_enabled; b->disposition = disp_donttouch; - b->frame = (frame ? frame->frame : 0); + b->frame_id = frame_id; /* If we're debugging a multi-threaded program, then we want momentary breakpoints to be active in only a @@ -4248,7 +4701,7 @@ static void mention (struct breakpoint *b) { int say_where = 0; - struct cleanup *old_chain; + struct cleanup *old_chain, *ui_out_chain; struct ui_stream *stb; stb = ui_out_stream_new (uiout); @@ -4263,113 +4716,124 @@ mention (struct breakpoint *b) create_breakpoint_hook (b); breakpoint_create_event (b->number); - switch (b->type) - { - case bp_none: - printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number); - break; - case bp_watchpoint: - ui_out_text (uiout, "Watchpoint "); - ui_out_tuple_begin (uiout, "wpt"); - ui_out_field_int (uiout, "number", b->number); - ui_out_text (uiout, ": "); - print_expression (b->exp, stb->stream); - ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); - break; - case bp_hardware_watchpoint: - ui_out_text (uiout, "Hardware watchpoint "); - ui_out_tuple_begin (uiout, "wpt"); - ui_out_field_int (uiout, "number", b->number); - ui_out_text (uiout, ": "); - print_expression (b->exp, stb->stream); - ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); - break; - case bp_read_watchpoint: - ui_out_text (uiout, "Hardware read watchpoint "); - ui_out_tuple_begin (uiout, "hw-rwpt"); - ui_out_field_int (uiout, "number", b->number); - ui_out_text (uiout, ": "); - print_expression (b->exp, stb->stream); - ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); - break; - case bp_access_watchpoint: - ui_out_text (uiout, "Hardware access (read/write) watchpoint "); - ui_out_tuple_begin (uiout, "hw-awpt"); - ui_out_field_int (uiout, "number", b->number); - ui_out_text (uiout, ": "); - print_expression (b->exp, stb->stream); - ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); - break; - case bp_breakpoint: - if (ui_out_is_mi_like_p (uiout)) - { - say_where = 0; - break; - } - printf_filtered ("Breakpoint %d", b->number); - say_where = 1; - break; - case bp_hardware_breakpoint: - if (ui_out_is_mi_like_p (uiout)) - { - say_where = 0; - break; - } - printf_filtered ("Hardware assisted breakpoint %d", b->number); - say_where = 1; - break; - case bp_catch_load: - case bp_catch_unload: - printf_filtered ("Catchpoint %d (%s %s)", - b->number, - (b->type == bp_catch_load) ? "load" : "unload", - (b->dll_pathname != NULL) ? - b->dll_pathname : ""); - break; - case bp_catch_fork: - case bp_catch_vfork: - printf_filtered ("Catchpoint %d (%s)", - b->number, - (b->type == bp_catch_fork) ? "fork" : "vfork"); - break; - case bp_catch_exec: - printf_filtered ("Catchpoint %d (exec)", - b->number); - break; - case bp_catch_catch: - case bp_catch_throw: - printf_filtered ("Catchpoint %d (%s)", - b->number, - (b->type == bp_catch_catch) ? "catch" : "throw"); - break; + if (b->ops != NULL && b->ops->print_mention != NULL) + b->ops->print_mention (b); + else + switch (b->type) + { + case bp_none: + printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number); + break; + case bp_watchpoint: + ui_out_text (uiout, "Watchpoint "); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt"); + ui_out_field_int (uiout, "number", b->number); + ui_out_text (uiout, ": "); + print_expression (b->exp, stb->stream); + ui_out_field_stream (uiout, "exp", stb); + do_cleanups (ui_out_chain); + break; + case bp_hardware_watchpoint: + ui_out_text (uiout, "Hardware watchpoint "); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt"); + ui_out_field_int (uiout, "number", b->number); + ui_out_text (uiout, ": "); + print_expression (b->exp, stb->stream); + ui_out_field_stream (uiout, "exp", stb); + do_cleanups (ui_out_chain); + break; + case bp_read_watchpoint: + ui_out_text (uiout, "Hardware read watchpoint "); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt"); + ui_out_field_int (uiout, "number", b->number); + ui_out_text (uiout, ": "); + print_expression (b->exp, stb->stream); + ui_out_field_stream (uiout, "exp", stb); + do_cleanups (ui_out_chain); + break; + case bp_access_watchpoint: + ui_out_text (uiout, "Hardware access (read/write) watchpoint "); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt"); + ui_out_field_int (uiout, "number", b->number); + ui_out_text (uiout, ": "); + print_expression (b->exp, stb->stream); + ui_out_field_stream (uiout, "exp", stb); + do_cleanups (ui_out_chain); + break; + case bp_breakpoint: + if (ui_out_is_mi_like_p (uiout)) + { + say_where = 0; + break; + } + printf_filtered ("Breakpoint %d", b->number); + say_where = 1; + break; + case bp_hardware_breakpoint: + if (ui_out_is_mi_like_p (uiout)) + { + say_where = 0; + break; + } + printf_filtered ("Hardware assisted breakpoint %d", b->number); + say_where = 1; + break; + case bp_catch_load: + case bp_catch_unload: + printf_filtered ("Catchpoint %d (%s %s)", + b->number, + (b->type == bp_catch_load) ? "load" : "unload", + (b->dll_pathname != NULL) ? + b->dll_pathname : ""); + break; + case bp_catch_fork: + case bp_catch_vfork: + printf_filtered ("Catchpoint %d (%s)", + b->number, + (b->type == bp_catch_fork) ? "fork" : "vfork"); + break; + case bp_catch_exec: + printf_filtered ("Catchpoint %d (exec)", + b->number); + break; + case bp_catch_catch: + case bp_catch_throw: + printf_filtered ("Catchpoint %d (%s)", + b->number, + (b->type == bp_catch_catch) ? "catch" : "throw"); + break; + + case bp_until: + case bp_finish: + case bp_longjmp: + case bp_longjmp_resume: + case bp_step_resume: + case bp_through_sigtramp: + case bp_call_dummy: + case bp_watchpoint_scope: + case bp_shlib_event: + case bp_thread_event: + case bp_overlay_event: + break; + } - case bp_until: - case bp_finish: - case bp_longjmp: - case bp_longjmp_resume: - case bp_step_resume: - case bp_through_sigtramp: - case bp_call_dummy: - case bp_watchpoint_scope: - case bp_shlib_event: - case bp_thread_event: - case bp_overlay_event: - break; - } if (say_where) { - if (addressprint || b->source_file == NULL) + if (b->pending) { - printf_filtered (" at "); - print_address_numeric (b->address, 1, gdb_stdout); + printf_filtered (" (%s) pending.", b->addr_string); + } + else + { + if (addressprint || b->source_file == NULL) + { + printf_filtered (" at "); + print_address_numeric (b->loc->address, 1, gdb_stdout); + } + if (b->source_file) + printf_filtered (": file %s, line %d.", + b->source_file, b->line_number); } - if (b->source_file) - printf_filtered (": file %s, line %d.", - b->source_file, b->line_number); } do_cleanups (old_chain); if (ui_out_is_mi_like_p (uiout)) @@ -4382,6 +4846,11 @@ mention (struct breakpoint *b) SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i], COND[i] and COND_STRING[i] values. + The parameter PENDING_BP points to a pending breakpoint that is + the basis of the breakpoints currently being created. The pending + breakpoint may contain a separate condition string or commands + that were added after the initial pending breakpoint was created. + NOTE: If the function succeeds, the caller is expected to cleanup the arrays ADDR_STRING, COND_STRING, COND and SALS (but not the array contents). If the function fails (error() is called), the @@ -4392,7 +4861,8 @@ static void create_breakpoints (struct symtabs_and_lines sals, char **addr_string, struct expression **cond, char **cond_string, enum bptype type, enum bpdisp disposition, - int thread, int ignore_count, int from_tty) + int thread, int ignore_count, int from_tty, + struct breakpoint *pending_bp) { if (type == bp_hardware_breakpoint) { @@ -4422,11 +4892,40 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string, b->number = breakpoint_count; b->cond = cond[i]; b->thread = thread; - b->addr_string = addr_string[i]; + if (addr_string[i]) + b->addr_string = addr_string[i]; + else + /* addr_string has to be used or breakpoint_re_set will delete + me. */ + xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address)); b->cond_string = cond_string[i]; b->ignore_count = ignore_count; b->enable_state = bp_enabled; b->disposition = disposition; + /* If resolving a pending breakpoint, a check must be made to see if + the user has specified a new condition or commands for the + breakpoint. A new condition will override any condition that was + initially specified with the initial breakpoint command. */ + if (pending_bp) + { + char *arg; + if (pending_bp->cond_string) + { + arg = pending_bp->cond_string; + b->cond_string = savestring (arg, strlen (arg)); + b->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0); + if (*arg) + error ("Junk at end of pending breakpoint condition expression"); + } + /* If there are commands associated with the breakpoint, they should + be copied too. */ + if (pending_bp->commands) + b->commands = copy_command_lines (pending_bp->commands); + + /* We have to copy over the ignore_count and thread as well. */ + b->ignore_count = pending_bp->ignore_count; + b->thread = pending_bp->thread; + } mention (b); } } @@ -4437,10 +4936,11 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string, addresses found. ADDR_STRING contains a vector of (canonical) address strings. ARG points to the end of the SAL. */ -void +static void parse_breakpoint_sals (char **address, struct symtabs_and_lines *sals, - char ***addr_string) + char ***addr_string, + int *not_found_ptr) { char *addr_start = *address; *addr_string = NULL; @@ -4452,7 +4952,7 @@ parse_breakpoint_sals (char **address, if (default_breakpoint_valid) { struct symtab_and_line sal; - INIT_SAL (&sal); /* initialize to zeroes */ + init_sal (&sal); /* initialize to zeroes */ sals->sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); sal.pc = default_breakpoint_address; @@ -4470,14 +4970,22 @@ parse_breakpoint_sals (char **address, /* Force almost all breakpoints to be in terms of the current_source_symtab (which is decode_line_1's default). This should produce the results we want almost all of the time while - leaving default_breakpoint_* alone. */ + leaving default_breakpoint_* alone. + ObjC: However, don't match an Objective-C method name which + may have a '+' or '-' succeeded by a '[' */ + + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + if (default_breakpoint_valid - && (!current_source_symtab - || (strchr ("+-", (*address)[0]) != NULL))) + && (!cursal.symtab + || ((strchr ("+-", (*address)[0]) != NULL) + && ((*address)[1] != '[')))) *sals = decode_line_1 (address, 1, default_breakpoint_symtab, - default_breakpoint_line, addr_string); + default_breakpoint_line, addr_string, + not_found_ptr); else - *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string); + *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, + addr_string, not_found_ptr); } /* For any SAL that didn't have a canonical string, fill one in. */ if (sals->nelts > 0 && *addr_string == NULL) @@ -4498,7 +5006,7 @@ parse_breakpoint_sals (char **address, /* Convert each SAL into a real PC. Verify that the PC can be inserted as a breakpoint. If it can't throw an error. */ -void +static void breakpoint_sals_to_pc (struct symtabs_and_lines *sals, char *address) { @@ -4531,26 +5039,44 @@ breakpoint_sals_to_pc (struct symtabs_and_lines *sals, } } +static int +do_captured_parse_breakpoint (struct ui_out *ui, void *data) +{ + struct captured_parse_breakpoint_args *args = data; + + parse_breakpoint_sals (args->arg_p, args->sals_p, args->addr_string_p, + args->not_found_ptr); + + return GDB_RC_OK; +} + /* Set a breakpoint according to ARG (function, linenum or *address) flag: first bit : 0 non-temporary, 1 temporary. - second bit : 0 normal breakpoint, 1 hardware breakpoint. */ + second bit : 0 normal breakpoint, 1 hardware breakpoint. -static void -break_command_1 (char *arg, int flag, int from_tty) + PENDING_BP is non-NULL when this function is being called to resolve + a pending breakpoint. */ + +static int +break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_bp) { int tempflag, hardwareflag; struct symtabs_and_lines sals; - register struct expression **cond = 0; - /* Pointers in arg to the start, and one past the end, of the - condition. */ + struct expression **cond = 0; + struct symtab_and_line pending_sal; char **cond_string = (char **) NULL; + char *copy_arg; + char *err_msg; char *addr_start = arg; char **addr_string; struct cleanup *old_chain; struct cleanup *breakpoint_chain = NULL; - int i; + struct captured_parse_breakpoint_args parse_args; + int i, rc; + int pending = 0; int thread = -1; int ignore_count = 0; + int not_found = 0; hardwareflag = flag & BP_HARDWAREFLAG; tempflag = flag & BP_TEMPFLAG; @@ -4558,19 +5084,69 @@ break_command_1 (char *arg, int flag, int from_tty) sals.sals = NULL; sals.nelts = 0; addr_string = NULL; - parse_breakpoint_sals (&arg, &sals, &addr_string); - if (!sals.nelts) - return; + parse_args.arg_p = &arg; + parse_args.sals_p = &sals; + parse_args.addr_string_p = &addr_string; + parse_args.not_found_ptr = ¬_found; + + rc = catch_exceptions_with_msg (uiout, do_captured_parse_breakpoint, + &parse_args, NULL, &err_msg, + RETURN_MASK_ALL); + + /* If caller is interested in rc value from parse, set value. */ + + if (rc != GDB_RC_OK) + { + /* Check for file or function not found. */ + if (not_found) + { + /* If called to resolve pending breakpoint, just return error code. */ + if (pending_bp) + return rc; + + error_output_message (NULL, err_msg); + xfree (err_msg); + + /* If pending breakpoint support is turned off, throw error. */ + + if (pending_break_support == AUTO_BOOLEAN_FALSE) + throw_exception (RETURN_ERROR); + + /* If pending breakpoint support is auto query and the user selects + no, then simply return the error code. */ + if (pending_break_support == AUTO_BOOLEAN_AUTO && + !nquery ("Make breakpoint pending on future shared library load? ")) + return rc; + + /* At this point, either the user was queried about setting a + pending breakpoint and selected yes, or pending breakpoint + behavior is on and thus a pending breakpoint is defaulted + on behalf of the user. */ + copy_arg = xstrdup (addr_start); + addr_string = ©_arg; + sals.nelts = 1; + sals.sals = &pending_sal; + pending_sal.pc = 0; + pending = 1; + } + else + return rc; + } + else if (!sals.nelts) + return GDB_RC_FAIL; /* Create a chain of things that always need to be cleaned up. */ old_chain = make_cleanup (null_cleanup, 0); - /* Make sure that all storage allocated to SALS gets freed. */ - make_cleanup (xfree, sals.sals); - - /* Cleanup the addr_string array but not its contents. */ - make_cleanup (xfree, addr_string); + if (!pending) + { + /* Make sure that all storage allocated to SALS gets freed. */ + make_cleanup (xfree, sals.sals); + + /* Cleanup the addr_string array but not its contents. */ + make_cleanup (xfree, addr_string); + } /* Allocate space for all the cond expressions. */ cond = xcalloc (sals.nelts, sizeof (struct expression *)); @@ -4597,62 +5173,94 @@ break_command_1 (char *arg, int flag, int from_tty) /* Resolve all line numbers to PC's and verify that the addresses are ok for the target. */ - breakpoint_sals_to_pc (&sals, addr_start); + if (!pending) + breakpoint_sals_to_pc (&sals, addr_start); /* Verify that condition can be parsed, before setting any breakpoints. Allocate a separate condition expression for each breakpoint. */ thread = -1; /* No specific thread yet */ - for (i = 0; i < sals.nelts; i++) + if (!pending) { - char *tok = arg; - while (tok && *tok) + for (i = 0; i < sals.nelts; i++) { - char *end_tok; - int toklen; - char *cond_start = NULL; - char *cond_end = NULL; - while (*tok == ' ' || *tok == '\t') - tok++; - - end_tok = tok; - - while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') - end_tok++; - - toklen = end_tok - tok; - - if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) + char *tok = arg; + while (tok && *tok) { - tok = cond_start = end_tok + 1; - cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0); - make_cleanup (xfree, cond[i]); - cond_end = tok; - cond_string[i] = savestring (cond_start, cond_end - cond_start); - make_cleanup (xfree, cond_string[i]); + char *end_tok; + int toklen; + char *cond_start = NULL; + char *cond_end = NULL; + while (*tok == ' ' || *tok == '\t') + tok++; + + end_tok = tok; + + while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') + end_tok++; + + toklen = end_tok - tok; + + if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) + { + tok = cond_start = end_tok + 1; + cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), + 0); + make_cleanup (xfree, cond[i]); + cond_end = tok; + cond_string[i] = savestring (cond_start, + cond_end - cond_start); + make_cleanup (xfree, cond_string[i]); + } + else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0) + { + char *tmptok; + + tok = end_tok + 1; + tmptok = tok; + thread = strtol (tok, &tok, 0); + if (tok == tmptok) + error ("Junk after thread keyword."); + if (!valid_thread_id (thread)) + error ("Unknown thread %d\n", thread); + } + else + error ("Junk at end of arguments."); } - else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0) - { - char *tmptok; - - tok = end_tok + 1; - tmptok = tok; - thread = strtol (tok, &tok, 0); - if (tok == tmptok) - error ("Junk after thread keyword."); - if (!valid_thread_id (thread)) - error ("Unknown thread %d\n", thread); - } - else - error ("Junk at end of arguments."); } + create_breakpoints (sals, addr_string, cond, cond_string, + hardwareflag ? bp_hardware_breakpoint + : bp_breakpoint, + tempflag ? disp_del : disp_donttouch, + thread, ignore_count, from_tty, + pending_bp); } + else + { + struct symtab_and_line sal; + struct breakpoint *b; - create_breakpoints (sals, addr_string, cond, cond_string, - hardwareflag ? bp_hardware_breakpoint : bp_breakpoint, - tempflag ? disp_del : disp_donttouch, - thread, ignore_count, from_tty); + sal.symtab = NULL; + sal.pc = 0; + make_cleanup (xfree, copy_arg); + + b = set_raw_breakpoint (sal, hardwareflag ? bp_hardware_breakpoint + : bp_breakpoint); + set_breakpoint_count (breakpoint_count + 1); + b->number = breakpoint_count; + b->cond = *cond; + b->thread = thread; + b->addr_string = *addr_string; + b->cond_string = *cond_string; + b->ignore_count = ignore_count; + b->pending = 1; + b->disposition = tempflag ? disp_del : disp_donttouch; + b->from_tty = from_tty; + b->flag = flag; + mention (b); + } + if (sals.nelts > 1) { warning ("Multiple breakpoints were set."); @@ -4663,6 +5271,8 @@ break_command_1 (char *arg, int flag, int from_tty) discard_cleanups (breakpoint_chain); /* But cleanup everything else. */ do_cleanups (old_chain); + + return GDB_RC_OK; } /* Set a breakpoint of TYPE/DISPOSITION according to ARG (function, @@ -4683,7 +5293,7 @@ do_captured_breakpoint (void *data) { struct captured_breakpoint_args *args = data; struct symtabs_and_lines sals; - register struct expression **cond; + struct expression **cond; struct cleanup *old_chain; struct cleanup *breakpoint_chain = NULL; int i; @@ -4699,7 +5309,7 @@ do_captured_breakpoint (void *data) sals.nelts = 0; address_end = args->address; addr_string = NULL; - parse_breakpoint_sals (&address_end, &sals, &addr_string); + parse_breakpoint_sals (&address_end, &sals, &addr_string, 0); if (!sals.nelts) return GDB_RC_NONE; @@ -4763,7 +5373,8 @@ do_captured_breakpoint (void *data) create_breakpoints (sals, addr_string, cond, cond_string, args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint, args->tempflag ? disp_del : disp_donttouch, - args->thread, args->ignore_count, 0/*from-tty*/); + args->thread, args->ignore_count, 0/*from-tty*/, + NULL/*pending_bp*/); /* That's it. Discard the cleanups for data inserted into the breakpoint. */ @@ -4797,7 +5408,6 @@ break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty) CORE_ADDR low, high, selected_pc = 0; char *extra_args = NULL; char *level_arg; - char *addr_string; int extra_args_len = 0, if_arg = 0; if (!arg || @@ -4806,9 +5416,9 @@ break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty) if (default_breakpoint_valid) { - if (selected_frame) + if (deprecated_selected_frame) { - selected_pc = selected_frame->pc; + selected_pc = get_frame_pc (deprecated_selected_frame); if (arg) if_arg = 1; } @@ -4837,7 +5447,7 @@ break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty) frame = parse_frame_specification (level_arg); if (frame) - selected_pc = frame->pc; + selected_pc = get_frame_pc (frame); else selected_pc = 0; } @@ -4851,12 +5461,12 @@ break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty) { if (find_pc_partial_function (selected_pc, (char **) NULL, &low, &high)) { - addr_string = (char *) xmalloc (26 + extra_args_len); + char *addr_string; if (extra_args_len) - sprintf (addr_string, "*0x%s %s", paddr_nz (high), extra_args); + addr_string = xstrprintf ("*0x%s %s", paddr_nz (high), extra_args); else - sprintf (addr_string, "*0x%s", paddr_nz (high)); - break_command_1 (addr_string, flag, from_tty); + addr_string = xstrprintf ("*0x%s", paddr_nz (high)); + break_command_1 (addr_string, flag, from_tty, NULL); xfree (addr_string); } else @@ -4884,10 +5494,10 @@ break_at_finish_command_1 (char *arg, int flag, int from_tty) { if (default_breakpoint_valid) { - if (selected_frame) + if (deprecated_selected_frame) { - addr_string = (char *) xmalloc (15); - sprintf (addr_string, "*0x%s", paddr_nz (selected_frame->pc)); + addr_string = xstrprintf ("*0x%s", + paddr_nz (get_frame_pc (deprecated_selected_frame))); if (arg) if_arg = 1; } @@ -4924,7 +5534,7 @@ break_at_finish_command_1 (char *arg, int flag, int from_tty) beg_addr_string = addr_string; sals = decode_line_1 (&addr_string, 1, (struct symtab *) NULL, 0, - (char ***) NULL); + (char ***) NULL, NULL); xfree (beg_addr_string); old_chain = make_cleanup (xfree, sals.sals); @@ -4933,12 +5543,13 @@ break_at_finish_command_1 (char *arg, int flag, int from_tty) sal = sals.sals[i]; if (find_pc_partial_function (sal.pc, (char **) NULL, &low, &high)) { - break_string = (char *) xmalloc (extra_args_len + 26); + break_string; if (extra_args_len) - sprintf (break_string, "*0x%s %s", paddr_nz (high), extra_args); + break_string = xstrprintf ("*0x%s %s", paddr_nz (high), + extra_args); else - sprintf (break_string, "*0x%s", paddr_nz (high)); - break_command_1 (break_string, flag, from_tty); + break_string = xstrprintf ("*0x%s", paddr_nz (high)); + break_command_1 (break_string, flag, from_tty, NULL); xfree (break_string); } else @@ -5005,7 +5616,7 @@ resolve_sal_pc (struct symtab_and_line *sal) void break_command (char *arg, int from_tty) { - break_command_1 (arg, 0, from_tty); + break_command_1 (arg, 0, from_tty, NULL); } void @@ -5023,7 +5634,7 @@ break_at_finish_at_depth_command (char *arg, int from_tty) void tbreak_command (char *arg, int from_tty) { - break_command_1 (arg, BP_TEMPFLAG, from_tty); + break_command_1 (arg, BP_TEMPFLAG, from_tty, NULL); } void @@ -5035,13 +5646,13 @@ tbreak_at_finish_command (char *arg, int from_tty) static void hbreak_command (char *arg, int from_tty) { - break_command_1 (arg, BP_HARDWAREFLAG, from_tty); + break_command_1 (arg, BP_HARDWAREFLAG, from_tty, NULL); } static void thbreak_command (char *arg, int from_tty) { - break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty); + break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty, NULL); } static void @@ -5082,7 +5693,7 @@ stopin_command (char *arg, int from_tty) if (badInput) printf_filtered ("Usage: stop in \n"); else - break_command_1 (arg, 0, from_tty); + break_command_1 (arg, 0, from_tty, NULL); } static void @@ -5114,10 +5725,9 @@ stopat_command (char *arg, int from_tty) if (badInput) printf_filtered ("Usage: stop at \n"); else - break_command_1 (arg, 0, from_tty); + break_command_1 (arg, 0, from_tty, NULL); } -/* ARGSUSED */ /* accessflag: hw_write: watch write, hw_read: watch read, hw_access: watch access (read or write) */ @@ -5142,7 +5752,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty) enum bptype bp_type; int mem_cnt = 0; - INIT_SAL (&sal); /* initialize to zeroes */ + init_sal (&sal); /* initialize to zeroes */ /* Parse arguments. */ innermost_block = NULL; @@ -5243,10 +5853,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty) if (frame) { prev_frame = get_prev_frame (frame); - b->watchpoint_frame = frame->frame; + b->watchpoint_frame = get_frame_id (frame); } else - b->watchpoint_frame = (CORE_ADDR) 0; + { + memset (&b->watchpoint_frame, 0, sizeof (b->watchpoint_frame)); + } /* If the expression is "local", then set up a "watchpoint scope" breakpoint at the point where we've left the scope of the watchpoint @@ -5256,16 +5868,8 @@ watch_command_1 (char *arg, int accessflag, int from_tty) if (prev_frame) { struct breakpoint *scope_breakpoint; - struct symtab_and_line scope_sal; - - INIT_SAL (&scope_sal); /* initialize to zeroes */ - scope_sal.pc = get_frame_pc (prev_frame); - scope_sal.section = find_pc_overlay (scope_sal.pc); - - scope_breakpoint = set_raw_breakpoint (scope_sal, - bp_watchpoint_scope); - set_breakpoint_count (breakpoint_count + 1); - scope_breakpoint->number = breakpoint_count; + scope_breakpoint = create_internal_breakpoint (get_frame_pc (prev_frame), + bp_watchpoint_scope); scope_breakpoint->enable_state = bp_enabled; @@ -5273,10 +5877,13 @@ watch_command_1 (char *arg, int accessflag, int from_tty) scope_breakpoint->disposition = disp_del; /* Only break in the proper frame (help with recursion). */ - scope_breakpoint->frame = prev_frame->frame; + scope_breakpoint->frame_id = get_frame_id (prev_frame); /* Set the address at which we will stop. */ - scope_breakpoint->address = get_frame_pc (prev_frame); + scope_breakpoint->loc->requested_address + = get_frame_pc (prev_frame); + scope_breakpoint->loc->address + = adjust_breakpoint_address (scope_breakpoint->loc->requested_address); /* The scope breakpoint is related to the watchpoint. We will need to act on them together. */ @@ -5293,7 +5900,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty) #if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT) #define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(BYTE_SIZE) \ - ((BYTE_SIZE) <= (REGISTER_SIZE)) + ((BYTE_SIZE) <= (DEPRECATED_REGISTER_SIZE)) #endif #if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT) @@ -5426,13 +6033,12 @@ until_break_command_continuation (struct continuation_arg *arg) do_exec_cleanups (cleanups); } -/* ARGSUSED */ void -until_break_command (char *arg, int from_tty) +until_break_command (char *arg, int from_tty, int anywhere) { struct symtabs_and_lines sals; struct symtab_and_line sal; - struct frame_info *prev_frame = get_prev_frame (selected_frame); + struct frame_info *prev_frame = get_prev_frame (deprecated_selected_frame); struct breakpoint *breakpoint; struct cleanup *old_chain; struct continuation_arg *arg1; @@ -5445,10 +6051,10 @@ until_break_command (char *arg, int from_tty) if (default_breakpoint_valid) sals = decode_line_1 (&arg, 1, default_breakpoint_symtab, - default_breakpoint_line, (char ***) NULL); + default_breakpoint_line, (char ***) NULL, NULL); else sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, - 0, (char ***) NULL); + 0, (char ***) NULL, NULL); if (sals.nelts != 1) error ("Couldn't get information on specified line."); @@ -5461,7 +6067,16 @@ until_break_command (char *arg, int from_tty) resolve_sal_pc (&sal); - breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until); + if (anywhere) + /* If the user told us to continue until a specified location, + we don't specify a frame at which we need to stop. */ + breakpoint = set_momentary_breakpoint (sal, null_frame_id, bp_until); + else + /* Otherwise, specify the current frame, because we want to stop only + at the very same frame. */ + breakpoint = set_momentary_breakpoint (sal, + get_frame_id (deprecated_selected_frame), + bp_until); if (!event_loop_p || !target_can_async_p ()) old_chain = make_cleanup_delete_breakpoint (breakpoint); @@ -5489,13 +6104,14 @@ until_break_command (char *arg, int from_tty) add_continuation (until_break_command_continuation, arg1); } - /* Keep within the current frame */ - + /* Keep within the current frame, or in frames called by the current + one. */ if (prev_frame) { - sal = find_pc_line (prev_frame->pc, 0); - sal.pc = prev_frame->pc; - breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until); + sal = find_pc_line (get_frame_pc (prev_frame), 0); + sal.pc = get_frame_pc (prev_frame); + breakpoint = set_momentary_breakpoint (sal, get_frame_id (prev_frame), + bp_until); if (!event_loop_p || !target_can_async_p ()) make_cleanup_delete_breakpoint (breakpoint); else @@ -5508,211 +6124,6 @@ until_break_command (char *arg, int from_tty) if (!event_loop_p || !target_can_async_p ()) do_cleanups (old_chain); } - -#if 0 -/* These aren't used; I don't konw what they were for. */ -/* Set a breakpoint at the catch clause for NAME. */ -static int -catch_breakpoint (char *name) -{ -} - -static int -disable_catch_breakpoint (void) -{ -} - -static int -delete_catch_breakpoint (void) -{ -} - -static int -enable_catch_breakpoint (void) -{ -} -#endif /* 0 */ - -struct sal_chain -{ - struct sal_chain *next; - struct symtab_and_line sal; -}; - -#if 0 -/* Not really used -- invocation in handle_gnu_4_16_catch_command - had been commented out in the v.4.16 sources, and stays - disabled there now because "catch NAME" syntax isn't allowed. - pai/1997-07-11 */ -/* This isn't used; I don't know what it was for. */ -/* For each catch clause identified in ARGS, run FUNCTION - with that clause as an argument. */ -static struct symtabs_and_lines -map_catch_names (char *args, int (*function) ()) -{ - register char *p = args; - register char *p1; - struct symtabs_and_lines sals; -#if 0 - struct sal_chain *sal_chain = 0; -#endif - - if (p == 0) - error_no_arg ("one or more catch names"); - - sals.nelts = 0; - sals.sals = NULL; - - while (*p) - { - p1 = p; - /* Don't swallow conditional part. */ - if (p1[0] == 'i' && p1[1] == 'f' - && (p1[2] == ' ' || p1[2] == '\t')) - break; - - if (isalpha (*p1)) - { - p1++; - while (isalnum (*p1) || *p1 == '_' || *p1 == '$') - p1++; - } - - if (*p1 && *p1 != ' ' && *p1 != '\t') - error ("Arguments must be catch names."); - - *p1 = 0; -#if 0 - if (function (p)) - { - struct sal_chain *next = (struct sal_chain *) - alloca (sizeof (struct sal_chain)); - next->next = sal_chain; - next->sal = get_catch_sal (p); - sal_chain = next; - goto win; - } -#endif - printf_unfiltered ("No catch clause for exception %s.\n", p); -#if 0 - win: -#endif - p = p1; - while (*p == ' ' || *p == '\t') - p++; - } -} -#endif - -/* This shares a lot of code with `print_frame_label_vars' from stack.c. */ - -static struct symtabs_and_lines -get_catch_sals (int this_level_only) -{ - register struct blockvector *bl; - register struct block *block; - int index, have_default = 0; - CORE_ADDR pc; - struct symtabs_and_lines sals; - struct sal_chain *sal_chain = 0; - char *blocks_searched; - - /* Not sure whether an error message is always the correct response, - but it's better than a core dump. */ - if (selected_frame == NULL) - error ("No selected frame."); - block = get_frame_block (selected_frame); - pc = selected_frame->pc; - - sals.nelts = 0; - sals.sals = NULL; - - if (block == 0) - error ("No symbol table info available.\n"); - - bl = blockvector_for_pc (BLOCK_END (block) - 4, &index); - blocks_searched = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); - memset (blocks_searched, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); - - while (block != 0) - { - CORE_ADDR end = BLOCK_END (block) - 4; - int last_index; - - if (bl != blockvector_for_pc (end, &index)) - error ("blockvector blotch"); - if (BLOCKVECTOR_BLOCK (bl, index) != block) - error ("blockvector botch"); - last_index = BLOCKVECTOR_NBLOCKS (bl); - index += 1; - - /* Don't print out blocks that have gone by. */ - while (index < last_index - && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < pc) - index++; - - while (index < last_index - && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < end) - { - if (blocks_searched[index] == 0) - { - struct block *b = BLOCKVECTOR_BLOCK (bl, index); - register int i; - register struct symbol *sym; - - ALL_BLOCK_SYMBOLS (b, i, sym) - { - if (STREQ (SYMBOL_NAME (sym), "default")) - { - if (have_default) - continue; - have_default = 1; - } - if (SYMBOL_CLASS (sym) == LOC_LABEL) - { - struct sal_chain *next = (struct sal_chain *) - alloca (sizeof (struct sal_chain)); - next->next = sal_chain; - next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), - 0); - sal_chain = next; - } - } - blocks_searched[index] = 1; - } - index++; - } - if (have_default) - break; - if (sal_chain && this_level_only) - break; - - /* After handling the function's top-level block, stop. - Don't continue to its superblock, the block of - per-file symbols. */ - if (BLOCK_FUNCTION (block)) - break; - block = BLOCK_SUPERBLOCK (block); - } - - if (sal_chain) - { - struct sal_chain *tmp_chain; - - /* Count the number of entries. */ - for (index = 0, tmp_chain = sal_chain; tmp_chain; - tmp_chain = tmp_chain->next) - index++; - - sals.nelts = index; - sals.sals = (struct symtab_and_line *) - xmalloc (index * sizeof (struct symtab_and_line)); - for (index = 0; sal_chain; sal_chain = sal_chain->next, index++) - sals.sals[index] = sal_chain->sal; - } - - return sals; -} static void ep_skip_leading_whitespace (char **s) @@ -5828,10 +6239,6 @@ typedef enum } catch_fork_kind; -#if defined(CHILD_INSERT_FORK_CATCHPOINT) || defined(CHILD_INSERT_VFORK_CATCHPOINT) -static void catch_fork_command_1 (catch_fork_kind fork_kind, - char *arg, int tempflag, int from_tty); - static void catch_fork_command_1 (catch_fork_kind fork_kind, char *arg, int tempflag, int from_tty) @@ -5865,9 +6272,7 @@ catch_fork_command_1 (catch_fork_kind fork_kind, char *arg, int tempflag, break; } } -#endif -#if defined(CHILD_INSERT_EXEC_CATCHPOINT) static void catch_exec_command_1 (char *arg, int tempflag, int from_tty) { @@ -5889,9 +6294,7 @@ catch_exec_command_1 (char *arg, int tempflag, int from_tty) and enable reporting of such events. */ create_exec_event_catchpoint (tempflag, cond_string); } -#endif -#if defined(SOLIB_ADD) static void catch_load_command_1 (char *arg, int tempflag, int from_tty) { @@ -5975,7 +6378,6 @@ catch_unload_command_1 (char *arg, int tempflag, int from_tty) SOLIB_CREATE_CATCH_UNLOAD_HOOK (PIDGET (inferior_ptid), tempflag, dll_pathname, cond_string); } -#endif /* SOLIB_ADD */ /* Commands to deal with catching exceptions. */ @@ -6019,6 +6421,90 @@ create_exception_catchpoint (int tempflag, char *cond_string, mention (b); } +static enum print_stop_action +print_exception_catchpoint (struct breakpoint *b) +{ + annotate_catchpoint (b->number); + + if (strstr (b->addr_string, "throw") != NULL) + printf_filtered ("\nCatchpoint %d (exception thrown)\n", + b->number); + else + printf_filtered ("\nCatchpoint %d (exception caught)\n", + b->number); + + return PRINT_SRC_AND_LOC; +} + +static void +print_one_exception_catchpoint (struct breakpoint *b, CORE_ADDR *last_addr) +{ + if (addressprint) + { + annotate_field (4); + ui_out_field_core_addr (uiout, "addr", b->loc->address); + } + annotate_field (5); + *last_addr = b->loc->address; + if (strstr (b->addr_string, "throw") != NULL) + ui_out_field_string (uiout, "what", "exception throw"); + else + ui_out_field_string (uiout, "what", "exception catch"); +} + +static void +print_mention_exception_catchpoint (struct breakpoint *b) +{ + if (strstr (b->addr_string, "throw") != NULL) + printf_filtered ("Catchpoint %d (throw)", b->number); + else + printf_filtered ("Catchpoint %d (catch)", b->number); +} + +static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = { + print_exception_catchpoint, + print_one_exception_catchpoint, + print_mention_exception_catchpoint +}; + +static int +handle_gnu_v3_exceptions (int tempflag, char *cond_string, + enum exception_event_kind ex_event, int from_tty) +{ + char *trigger_func_name, *nameptr; + struct symtabs_and_lines sals; + struct breakpoint *b; + + if (ex_event == EX_EVENT_CATCH) + trigger_func_name = xstrdup ("__cxa_begin_catch"); + else + trigger_func_name = xstrdup ("__cxa_throw"); + + nameptr = trigger_func_name; + sals = decode_line_1 (&nameptr, 1, NULL, 0, NULL, NULL); + if (sals.nelts == 0) + { + xfree (trigger_func_name); + return 0; + } + + b = set_raw_breakpoint (sals.sals[0], bp_breakpoint); + set_breakpoint_count (breakpoint_count + 1); + b->number = breakpoint_count; + b->cond = NULL; + b->cond_string = (cond_string == NULL) ? + NULL : savestring (cond_string, strlen (cond_string)); + b->thread = -1; + b->addr_string = trigger_func_name; + b->enable_state = bp_enabled; + b->disposition = tempflag ? disp_del : disp_donttouch; + b->ops = &gnu_v3_exception_catchpoint_ops; + + xfree (sals.sals); + mention (b); + return 1; +} + /* Deal with "catch catch" and "catch throw" commands */ static void @@ -6039,6 +6525,9 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg, (ex_event != EX_EVENT_CATCH)) error ("Unsupported or unknown exception event; cannot catch it"); + if (handle_gnu_v3_exceptions (tempflag, cond_string, ex_event, from_tty)) + return; + /* See if we can find a callback routine */ sal = target_enable_exception_callback (ex_event, 1); @@ -6051,30 +6540,15 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg, else return; /* something went wrong with setting up callbacks */ } - else - { - /* No callbacks from runtime system for exceptions. - Try GNU C++ exception breakpoints using labels in debug info. */ - if (ex_event == EX_EVENT_CATCH) - { - handle_gnu_4_16_catch_command (arg, tempflag, from_tty); - } - else if (ex_event == EX_EVENT_THROW) - { - /* Set a breakpoint on __raise_exception () */ - warning ("Unsupported with this platform/compiler combination."); - warning ("Perhaps you can achieve the effect you want by setting"); - warning ("a breakpoint on __raise_exception()."); - } - } + warning ("Unsupported with this platform/compiler combination."); } /* Cover routine to allow wrapping target_enable_exception_catchpoints inside a catch_errors */ static int -cover_target_enable_exception_callback (PTR arg) +cover_target_enable_exception_callback (void *arg) { args_for_catchpoint_enable *args = arg; struct symtab_and_line *sal; @@ -6087,111 +6561,6 @@ cover_target_enable_exception_callback (PTR arg) return 1; /*is valid */ } - - -/* This is the original v.4.16 and earlier version of the - catch_command_1() function. Now that other flavours of "catch" - have been introduced, and since exception handling can be handled - in other ways (through target ops) also, this is used only for the - GNU C++ exception handling system. - Note: Only the "catch" flavour of GDB 4.16 is handled here. The - "catch NAME" is now no longer allowed in catch_command_1(). Also, - there was no code in GDB 4.16 for "catch throw". - - Called from catch_exception_command_1 () */ - - -static void -handle_gnu_4_16_catch_command (char *arg, int tempflag, int from_tty) -{ - /* First, translate ARG into something we can deal with in terms - of breakpoints. */ - - struct symtabs_and_lines sals; - struct symtab_and_line sal; - register struct expression *cond = 0; - register struct breakpoint *b; - char *save_arg; - int i; - - INIT_SAL (&sal); /* initialize to zeroes */ - - /* If no arg given, or if first arg is 'if ', all active catch clauses - are breakpointed. */ - - if (!arg || (arg[0] == 'i' && arg[1] == 'f' - && (arg[2] == ' ' || arg[2] == '\t'))) - { - /* Grab all active catch clauses. */ - sals = get_catch_sals (0); - } - else - { - /* Grab selected catch clauses. */ - error ("catch NAME not implemented"); - -#if 0 - /* Not sure why this code has been disabled. I'm leaving - it disabled. We can never come here now anyway - since we don't allow the "catch NAME" syntax. - pai/1997-07-11 */ - - /* This isn't used; I don't know what it was for. */ - sals = map_catch_names (arg, catch_breakpoint); -#endif - } - - if (!sals.nelts) - return; - - save_arg = arg; - for (i = 0; i < sals.nelts; i++) - { - resolve_sal_pc (&sals.sals[i]); - - while (arg && *arg) - { - if (arg[0] == 'i' && arg[1] == 'f' - && (arg[2] == ' ' || arg[2] == '\t')) - cond = parse_exp_1 ((arg += 2, &arg), - block_for_pc (sals.sals[i].pc), 0); - else - error ("Junk at end of arguments."); - } - arg = save_arg; - } - - for (i = 0; i < sals.nelts; i++) - { - sal = sals.sals[i]; - - if (from_tty) - describe_other_breakpoints (sal.pc, sal.section); - - /* Important -- this is an ordinary breakpoint. For platforms - with callback support for exceptions, - create_exception_catchpoint() will create special bp types - (bp_catch_catch and bp_catch_throw), and there is code in - insert_breakpoints() and elsewhere that depends on that. */ - b = set_raw_breakpoint (sal, bp_breakpoint); - set_breakpoint_count (breakpoint_count + 1); - b->number = breakpoint_count; - - b->cond = cond; - b->enable_state = bp_enabled; - b->disposition = tempflag ? disp_del : disp_donttouch; - - mention (b); - } - - if (sals.nelts > 1) - { - warning ("Multiple breakpoints were set."); - warning ("Use the \"delete\" command to delete unwanted breakpoints."); - } - xfree (sals.sals); -} - static void catch_command_1 (char *arg, int tempflag, int from_tty) { @@ -6257,43 +6626,23 @@ catch_command_1 (char *arg, int tempflag, int from_tty) } else if (strncmp (arg1_start, "fork", arg1_length) == 0) { -#if defined(CHILD_INSERT_FORK_CATCHPOINT) catch_fork_command_1 (catch_fork, arg1_end + 1, tempflag, from_tty); -#else - error ("Catch of fork not yet implemented"); -#endif } else if (strncmp (arg1_start, "vfork", arg1_length) == 0) { -#if defined(CHILD_INSERT_VFORK_CATCHPOINT) catch_fork_command_1 (catch_vfork, arg1_end + 1, tempflag, from_tty); -#else - error ("Catch of vfork not yet implemented"); -#endif } else if (strncmp (arg1_start, "exec", arg1_length) == 0) { -#if defined(CHILD_INSERT_EXEC_CATCHPOINT) catch_exec_command_1 (arg1_end + 1, tempflag, from_tty); -#else - error ("Catch of exec not yet implemented"); -#endif } else if (strncmp (arg1_start, "load", arg1_length) == 0) { -#if defined(SOLIB_ADD) catch_load_command_1 (arg1_end + 1, tempflag, from_tty); -#else - error ("Catch of load not implemented"); -#endif } else if (strncmp (arg1_start, "unload", arg1_length) == 0) { -#if defined(SOLIB_ADD) catch_unload_command_1 (arg1_end + 1, tempflag, from_tty); -#else - error ("Catch of load not implemented"); -#endif } else if (strncmp (arg1_start, "stop", arg1_length) == 0) { @@ -6327,30 +6676,6 @@ set_breakpoint_sal (struct symtab_and_line sal) return b; } -#if 0 -/* These aren't used; I don't know what they were for. */ -/* Disable breakpoints on all catch clauses described in ARGS. */ -static void -disable_catch (char *args) -{ - /* Map the disable command to catch clauses described in ARGS. */ -} - -/* Enable breakpoints on all catch clauses described in ARGS. */ -static void -enable_catch (char *args) -{ - /* Map the disable command to catch clauses described in ARGS. */ -} - -/* Delete breakpoints on all catch clauses in the active scope. */ -static void -delete_catch (char *args) -{ - /* Map the delete command to catch clauses described in ARGS. */ -} -#endif /* 0 */ - static void catch_command (char *arg, int from_tty) { @@ -6364,15 +6689,15 @@ tcatch_command (char *arg, int from_tty) catch_command_1 (arg, 1, from_tty); } +/* Delete breakpoints by address or line. */ static void clear_command (char *arg, int from_tty) { - register struct breakpoint *b, *b1; + struct breakpoint *b, *tmp, *prev, *found; int default_match; struct symtabs_and_lines sals; struct symtab_and_line sal; - register struct breakpoint *found; int i; if (arg) @@ -6384,7 +6709,8 @@ clear_command (char *arg, int from_tty) { sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); - INIT_SAL (&sal); /* initialize to zeroes */ + make_cleanup (xfree, sals.sals); + init_sal (&sal); /* initialize to zeroes */ sal.line = default_breakpoint_line; sal.symtab = default_breakpoint_symtab; sal.pc = default_breakpoint_address; @@ -6398,13 +6724,11 @@ clear_command (char *arg, int from_tty) } /* For each line spec given, delete bps which correspond - to it. We do this in two loops: the first loop looks at - the initial bp(s) in the chain which should be deleted, - the second goes down the rest of the chain looking ahead - one so it can take those bps off the chain without messing - up the chain. */ - + to it. Do it in two passes, solely to preserve the current + behavior that from_tty is forced true if we delete more than + one breakpoint. */ + found = NULL; for (i = 0; i < sals.nelts; i++) { /* If exact pc given, clear bpts at that pc. @@ -6420,81 +6744,75 @@ clear_command (char *arg, int from_tty) 1 0 */ sal = sals.sals[i]; - found = (struct breakpoint *) 0; - - - while (breakpoint_chain - /* Why don't we check here that this is not - a watchpoint, etc., as we do below? - I can't make it fail, but don't know - what's stopping the failure: a watchpoint - of the same address as "sal.pc" should - wind up being deleted. */ - - && (((sal.pc && (breakpoint_chain->address == sal.pc)) - && (!overlay_debugging - || breakpoint_chain->section == sal.section)) - || ((default_match || (0 == sal.pc)) - && breakpoint_chain->source_file != NULL - && sal.symtab != NULL - && STREQ (breakpoint_chain->source_file, sal.symtab->filename) - && breakpoint_chain->line_number == sal.line))) + prev = NULL; + /* Find all matching breakpoints, remove them from the + breakpoint chain, and add them to the 'found' chain. */ + ALL_BREAKPOINTS_SAFE (b, tmp) { - b1 = breakpoint_chain; - breakpoint_chain = b1->next; - b1->next = found; - found = b1; - } - - ALL_BREAKPOINTS (b) - while (b->next - && b->next->type != bp_none - && b->next->type != bp_watchpoint - && b->next->type != bp_hardware_watchpoint - && b->next->type != bp_read_watchpoint - && b->next->type != bp_access_watchpoint - && (((sal.pc && (b->next->address == sal.pc)) - && (!overlay_debugging || b->next->section == sal.section)) - || ((default_match || (0 == sal.pc)) - && b->next->source_file != NULL - && sal.symtab != NULL - && STREQ (b->next->source_file, sal.symtab->filename) - && b->next->line_number == sal.line))) - - - { - b1 = b->next; - b->next = b1->next; - b1->next = found; - found = b1; - } - - if (found == 0) - { - if (arg) - error ("No breakpoint at %s.", arg); + /* Are we going to delete b? */ + if (b->type != bp_none + && b->type != bp_watchpoint + && b->type != bp_hardware_watchpoint + && b->type != bp_read_watchpoint + && b->type != bp_access_watchpoint + /* Not if b is a watchpoint of any sort... */ + && (((sal.pc && (b->loc->address == sal.pc)) + && (!section_is_overlay (b->loc->section) + || b->loc->section == sal.section)) + /* Yes, if sal.pc matches b (modulo overlays). */ + || ((default_match || (0 == sal.pc)) + && b->source_file != NULL + && sal.symtab != NULL + && strcmp (b->source_file, sal.symtab->filename) == 0 + && b->line_number == sal.line))) + /* Yes, if sal source file and line matches b. */ + { + /* Remove it from breakpoint_chain... */ + if (b == breakpoint_chain) + { + /* b is at the head of the list */ + breakpoint_chain = b->next; + } + else + { + prev->next = b->next; + } + /* And add it to 'found' chain. */ + b->next = found; + found = b; + } else - error ("No breakpoint at this line."); + { + /* Keep b, and keep a pointer to it. */ + prev = b; + } } - - if (found->next) - from_tty = 1; /* Always report if deleted more than one */ - if (from_tty) - printf_unfiltered ("Deleted breakpoint%s ", found->next ? "s" : ""); - breakpoints_changed (); - while (found) - { - if (from_tty) - printf_unfiltered ("%d ", found->number); - b1 = found->next; - delete_breakpoint (found); - found = b1; - } - if (from_tty) - putchar_unfiltered ('\n'); } - xfree (sals.sals); + /* Now go thru the 'found' chain and delete them. */ + if (found == 0) + { + if (arg) + error ("No breakpoint at %s.", arg); + else + error ("No breakpoint at this line."); + } + + if (found->next) + from_tty = 1; /* Always report if deleted more than one */ + if (from_tty) + printf_unfiltered ("Deleted breakpoint%s ", found->next ? "s" : ""); + breakpoints_changed (); + while (found) + { + if (from_tty) + printf_unfiltered ("%d ", found->number); + tmp = found->next; + delete_breakpoint (found); + found = tmp; + } + if (from_tty) + putchar_unfiltered ('\n'); } /* Delete breakpoint in BS if they are `delete' breakpoints and @@ -6524,8 +6842,9 @@ breakpoint_auto_delete (bpstat bs) void delete_breakpoint (struct breakpoint *bpt) { - register struct breakpoint *b; - register bpstat bs; + struct breakpoint *b; + bpstat bs; + struct bp_location *loc; if (bpt == NULL) error ("Internal error (attempted to delete a NULL breakpoint)"); @@ -6551,12 +6870,15 @@ delete_breakpoint (struct breakpoint *bpt) delete_breakpoint_hook (bpt); breakpoint_delete_event (bpt->number); - if (bpt->inserted) - remove_breakpoint (bpt, mark_inserted); + if (bpt->loc->inserted) + remove_breakpoint (bpt->loc, mark_inserted); if (breakpoint_chain == bpt) breakpoint_chain = bpt->next; + if (bp_location_chain == bpt->loc) + bp_location_chain = bpt->loc->next; + /* If we have callback-style exception catchpoints, don't go through the adjustments to the C++ runtime library etc. if the inferior isn't actually running. target_enable_exception_callback for a @@ -6565,17 +6887,17 @@ delete_breakpoint (struct breakpoint *bpt) exceptions are supported in this way, it's OK for now. FIXME */ if (ep_is_exception_catchpoint (bpt) && target_has_execution) { - static char message1[] = "Error in deleting catchpoint %d:\n"; - static char message[sizeof (message1) + 30]; - args_for_catchpoint_enable args; - /* Format possible error msg */ - sprintf (message, message1, bpt->number); + char *message = xstrprintf ("Error in deleting catchpoint %d:\n", + bpt->number); + struct cleanup *cleanups = make_cleanup (xfree, message); + args_for_catchpoint_enable args; args.kind = bpt->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW; args.enable_p = 0; catch_errors (cover_target_enable_exception_callback, &args, message, RETURN_MASK_ALL); + do_cleanups (cleanups); } @@ -6586,10 +6908,17 @@ delete_breakpoint (struct breakpoint *bpt) break; } + ALL_BP_LOCATIONS (loc) + if (loc->next == bpt->loc) + { + loc->next = bpt->loc->next; + break; + } + check_duplicates (bpt); /* If this breakpoint was inserted, and there is another breakpoint at the same address, we need to insert the other breakpoint. */ - if (bpt->inserted + if (bpt->loc->inserted && bpt->type != bp_hardware_watchpoint && bpt->type != bp_read_watchpoint && bpt->type != bp_access_watchpoint @@ -6598,11 +6927,12 @@ delete_breakpoint (struct breakpoint *bpt) && bpt->type != bp_catch_exec) { ALL_BREAKPOINTS (b) - if (b->address == bpt->address - && b->section == bpt->section - && !b->duplicate + if (b->loc->address == bpt->loc->address + && b->loc->section == bpt->loc->section + && !b->loc->duplicate && b->enable_state != bp_disabled && b->enable_state != bp_shlib_disabled + && !b->pending && b->enable_state != bp_call_disabled) { int val; @@ -6617,18 +6947,39 @@ delete_breakpoint (struct breakpoint *bpt) "a permanent breakpoint"); if (b->type == bp_hardware_breakpoint) - val = target_insert_hw_breakpoint (b->address, b->shadow_contents); + val = target_insert_hw_breakpoint (b->loc->address, b->loc->shadow_contents); else - val = target_insert_breakpoint (b->address, b->shadow_contents); + val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents); + /* If there was an error in the insert, print a message, then stop execution. */ if (val != 0) { + struct ui_file *tmp_error_stream = mem_fileopen (); + make_cleanup_ui_file_delete (tmp_error_stream); + + + if (b->type == bp_hardware_breakpoint) + { + fprintf_unfiltered (tmp_error_stream, + "Cannot insert hardware breakpoint %d.\n" + "You may have requested too many hardware breakpoints.\n", + b->number); + } + else + { + fprintf_unfiltered (tmp_error_stream, "Cannot insert breakpoint %d.\n", b->number); + fprintf_filtered (tmp_error_stream, "Error accessing memory address "); + print_address_numeric (b->loc->address, 1, tmp_error_stream); + fprintf_filtered (tmp_error_stream, ": %s.\n", + safe_strerror (val)); + } + + fprintf_unfiltered (tmp_error_stream,"The same program may be running in another process."); target_terminal_ours_for_output (); - warning ("Cannot insert breakpoint %d:", b->number); - memory_error (val, b->address); /* which bombs us out */ + error_stream(tmp_error_stream); } else - b->inserted = 1; + b->loc->inserted = 1; } } @@ -6661,19 +7012,14 @@ delete_breakpoint (struct breakpoint *bpt) if (bs->breakpoint_at == bpt) { bs->breakpoint_at = NULL; - - /* we'd call bpstat_clear_actions, but that free's stuff and due - to the multiple pointers pointing to one item with no - reference counts found anywhere through out the bpstat's (how - do you spell fragile?), we don't want to free things twice -- - better a memory leak than a corrupt malloc pool! */ - bs->commands = NULL; bs->old_val = NULL; + /* bs->commands will be freed later. */ } /* On the chance that someone will soon try again to delete this same bp, we mark it as deleted before freeing its storage. */ bpt->type = bp_none; + xfree (bpt->loc); xfree (bpt); } @@ -6700,6 +7046,8 @@ delete_command (char *arg, int from_tty) { struct breakpoint *b, *temp; + dont_repeat (); + if (arg == 0) { int breaks_to_delete = 0; @@ -6741,7 +7089,7 @@ delete_command (char *arg, int from_tty) Unused in this case. */ static int -breakpoint_re_set_one (PTR bint) +breakpoint_re_set_one (void *bint) { /* get past catch_errs */ struct breakpoint *b = (struct breakpoint *) bint; @@ -6790,6 +7138,10 @@ breakpoint_re_set_one (PTR bint) shlib_disabled breakpoint though. There's a fair chance we can't re-set it if the shared library it's in hasn't been loaded yet. */ + + if (b->pending) + break; + save_enable = b->enable_state; if (b->enable_state != bp_shlib_disabled) b->enable_state = bp_disabled; @@ -6797,7 +7149,7 @@ breakpoint_re_set_one (PTR bint) set_language (b->language); input_radix = b->input_radix; s = b->addr_string; - sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL); + sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, NULL); for (i = 0; i < sals.nelts; i++) { resolve_sal_pc (&sals.sals[i]); @@ -6808,17 +7160,22 @@ breakpoint_re_set_one (PTR bint) { s = b->cond_string; if (b->cond) - xfree (b->cond); + { + xfree (b->cond); + /* Avoid re-freeing b->exp if an error during the call + to parse_exp_1. */ + b->cond = NULL; + } b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0); } /* We need to re-set the breakpoint if the address changes... */ - if (b->address != sals.sals[i].pc + if (b->loc->address != sals.sals[i].pc /* ...or new and old breakpoints both have source files, and the source file name or the line number changes... */ || (b->source_file != NULL && sals.sals[i].symtab != NULL - && (!STREQ (b->source_file, sals.sals[i].symtab->filename) + && (strcmp (b->source_file, sals.sals[i].symtab->filename) != 0 || b->line_number != sals.sals[i].line) ) /* ...or we switch between having a source file and not having @@ -6835,7 +7192,9 @@ breakpoint_re_set_one (PTR bint) savestring (sals.sals[i].symtab->filename, strlen (sals.sals[i].symtab->filename)); b->line_number = sals.sals[i].line; - b->address = sals.sals[i].pc; + b->loc->requested_address = sals.sals[i].pc; + b->loc->address + = adjust_breakpoint_address (b->loc->requested_address); /* Used to check for duplicates here, but that can cause trouble, as it doesn't check for disabled @@ -6847,7 +7206,7 @@ breakpoint_re_set_one (PTR bint) rather than once for every breakpoint. */ breakpoints_changed (); } - b->section = sals.sals[i].section; + b->loc->section = sals.sals[i].section; b->enable_state = save_enable; /* Restore it, this worked. */ @@ -6874,25 +7233,40 @@ breakpoint_re_set_one (PTR bint) /* So for now, just use a global context. */ if (b->exp) - xfree (b->exp); + { + xfree (b->exp); + /* Avoid re-freeing b->exp if an error during the call to + parse_expression. */ + b->exp = NULL; + } b->exp = parse_expression (b->exp_string); b->exp_valid_block = innermost_block; mark = value_mark (); if (b->val) - value_free (b->val); + { + value_free (b->val); + /* Avoid re-freeing b->val if an error during the call to + evaluate_expression. */ + b->val = NULL; + } b->val = evaluate_expression (b->exp); release_value (b->val); - if (VALUE_LAZY (b->val)) + if (VALUE_LAZY (b->val) && breakpoint_enabled (b)) value_fetch_lazy (b->val); if (b->cond_string != NULL) { s = b->cond_string; if (b->cond) - xfree (b->cond); + { + xfree (b->cond); + /* Avoid re-freeing b->exp if an error during the call + to parse_exp_1. */ + b->cond = NULL; + } b->cond = parse_exp_1 (&s, (struct block *) 0, 0); } - if (b->enable_state == bp_enabled) + if (breakpoint_enabled (b)) mention (b); value_free_to_mark (mark); break; @@ -6948,16 +7322,17 @@ breakpoint_re_set (void) struct breakpoint *b, *temp; enum language save_language; int save_input_radix; - static char message1[] = "Error in re-setting breakpoint %d:\n"; - char message[sizeof (message1) + 30 /* slop */ ]; save_language = current_language->la_language; save_input_radix = input_radix; ALL_BREAKPOINTS_SAFE (b, temp) { /* Format possible error msg */ - sprintf (message, message1, b->number); + char *message = xstrprintf ("Error in re-setting breakpoint %d:\n", + b->number); + struct cleanup *cleanups = make_cleanup (xfree, message); catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL); + do_cleanups (cleanups); } set_language (save_language); input_radix = save_input_radix; @@ -6995,7 +7370,7 @@ breakpoint_re_set_thread (struct breakpoint *b) void set_ignore_count (int bptnum, int count, int from_tty) { - register struct breakpoint *b; + struct breakpoint *b; if (count < 0) count = 0; @@ -7004,18 +7379,20 @@ set_ignore_count (int bptnum, int count, int from_tty) if (b->number == bptnum) { b->ignore_count = count; - if (!from_tty) - return; - else if (count == 0) - printf_filtered ("Will stop next time breakpoint %d is reached.", - bptnum); - else if (count == 1) - printf_filtered ("Will ignore next crossing of breakpoint %d.", - bptnum); - else - printf_filtered ("Will ignore next %d crossings of breakpoint %d.", - count, bptnum); + if (from_tty) + { + if (count == 0) + printf_filtered ("Will stop next time breakpoint %d is reached.", + bptnum); + else if (count == 1) + printf_filtered ("Will ignore next crossing of breakpoint %d.", + bptnum); + else + printf_filtered ("Will ignore next %d crossings of breakpoint %d.", + count, bptnum); + } breakpoints_changed (); + breakpoint_modify_event (b->number); return; } @@ -7038,7 +7415,7 @@ static void ignore_command (char *args, int from_tty) { char *p = args; - register int num; + int num; if (p == 0) error_no_arg ("a breakpoint number"); @@ -7052,8 +7429,8 @@ ignore_command (char *args, int from_tty) set_ignore_count (num, longest_to_int (value_as_long (parse_and_eval (p))), from_tty); - printf_filtered ("\n"); - breakpoints_changed (); + if (from_tty) + printf_filtered ("\n"); } /* Call FUNCTION on each of the breakpoints @@ -7062,10 +7439,10 @@ ignore_command (char *args, int from_tty) static void map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *)) { - register char *p = args; + char *p = args; char *p1; - register int num; - register struct breakpoint *b, *tmp; + int num; + struct breakpoint *b, *tmp; int match; if (p == 0) @@ -7126,11 +7503,10 @@ disable_breakpoint (struct breakpoint *bpt) breakpoint_modify_event (bpt->number); } -/* ARGSUSED */ static void disable_command (char *args, int from_tty) { - register struct breakpoint *bpt; + struct breakpoint *bpt; if (args == 0) ALL_BREAKPOINTS (bpt) switch (bpt->type) @@ -7181,75 +7557,91 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition) error ("Hardware breakpoints used exceeds limit."); } - if (bpt->enable_state != bp_permanent) - bpt->enable_state = bp_enabled; - bpt->disposition = disposition; - check_duplicates (bpt); - breakpoints_changed (); - - if (bpt->type == bp_watchpoint || - bpt->type == bp_hardware_watchpoint || - bpt->type == bp_read_watchpoint || - bpt->type == bp_access_watchpoint) + if (bpt->pending) { - if (bpt->exp_valid_block != NULL) + if (bpt->enable_state != bp_enabled) { - struct frame_info *fr = - - /* Ensure that we have the current frame. Else, this - next query may pessimistically be answered as, "No, - not within current scope". */ - get_current_frame (); - fr = find_frame_addr_in_frame_chain (bpt->watchpoint_frame); - if (fr == NULL) + /* When enabling a pending breakpoint, we need to check if the breakpoint + is resolvable since shared libraries could have been loaded + after the breakpoint was disabled. */ + breakpoints_changed (); + if (resolve_pending_breakpoint (bpt) == GDB_RC_OK) { - printf_filtered ("\ -Cannot enable watchpoint %d because the block in which its expression\n\ -is valid is not currently in scope.\n", bpt->number); - bpt->enable_state = bp_disabled; + delete_breakpoint (bpt); return; } - - save_selected_frame = selected_frame; - save_selected_frame_level = selected_frame_level; - select_frame (fr, -1); + bpt->enable_state = bp_enabled; + bpt->disposition = disposition; } - - value_free (bpt->val); - mark = value_mark (); - bpt->val = evaluate_expression (bpt->exp); - release_value (bpt->val); - if (VALUE_LAZY (bpt->val)) - value_fetch_lazy (bpt->val); - - if (bpt->type == bp_hardware_watchpoint || - bpt->type == bp_read_watchpoint || + } + else /* Not a pending breakpoint. */ + { + if (bpt->enable_state != bp_permanent) + bpt->enable_state = bp_enabled; + bpt->disposition = disposition; + check_duplicates (bpt); + breakpoints_changed (); + + if (bpt->type == bp_watchpoint || + bpt->type == bp_hardware_watchpoint || + bpt->type == bp_read_watchpoint || bpt->type == bp_access_watchpoint) { - int i = hw_watchpoint_used_count (bpt->type, &other_type_used); - int mem_cnt = can_use_hardware_watchpoint (bpt->val); - - /* Hack around 'unused var' error for some targets here */ - (void) mem_cnt, i; - target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT ( - bpt->type, i + mem_cnt, other_type_used); - /* we can consider of type is bp_hardware_watchpoint, convert to - bp_watchpoint in the following condition */ - if (target_resources_ok < 0) + if (bpt->exp_valid_block != NULL) { - printf_filtered ("\ + struct frame_info *fr = + fr = frame_find_by_id (bpt->watchpoint_frame); + if (fr == NULL) + { + printf_filtered ("\ +Cannot enable watchpoint %d because the block in which its expression\n\ +is valid is not currently in scope.\n", bpt->number); + bpt->enable_state = bp_disabled; + return; + } + + save_selected_frame = deprecated_selected_frame; + save_selected_frame_level = frame_relative_level (deprecated_selected_frame); + select_frame (fr); + } + + value_free (bpt->val); + mark = value_mark (); + bpt->val = evaluate_expression (bpt->exp); + release_value (bpt->val); + if (VALUE_LAZY (bpt->val)) + value_fetch_lazy (bpt->val); + + if (bpt->type == bp_hardware_watchpoint || + bpt->type == bp_read_watchpoint || + bpt->type == bp_access_watchpoint) + { + int i = hw_watchpoint_used_count (bpt->type, &other_type_used); + int mem_cnt = can_use_hardware_watchpoint (bpt->val); + + /* Hack around 'unused var' error for some targets here */ + (void) mem_cnt, i; + target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT ( + bpt->type, i + mem_cnt, other_type_used); + /* we can consider of type is bp_hardware_watchpoint, convert to + bp_watchpoint in the following condition */ + if (target_resources_ok < 0) + { + printf_filtered ("\ Cannot enable watchpoint %d because target watch resources\n\ have been allocated for other watchpoints.\n", bpt->number); - bpt->enable_state = bp_disabled; - value_free_to_mark (mark); - return; + bpt->enable_state = bp_disabled; + value_free_to_mark (mark); + return; + } } + + if (save_selected_frame_level >= 0) + select_frame (save_selected_frame); + value_free_to_mark (mark); } - - if (save_selected_frame_level >= 0) - select_frame (save_selected_frame, save_selected_frame_level); - value_free_to_mark (mark); } + if (modify_breakpoint_hook) modify_breakpoint_hook (bpt); breakpoint_modify_event (bpt->number); @@ -7265,11 +7657,10 @@ enable_breakpoint (struct breakpoint *bpt) breakpoints) so they once again become (or continue to be) effective in stopping the inferior. */ -/* ARGSUSED */ static void enable_command (char *args, int from_tty) { - register struct breakpoint *bpt; + struct breakpoint *bpt; if (args == 0) ALL_BREAKPOINTS (bpt) switch (bpt->type) @@ -7305,7 +7696,6 @@ enable_once_breakpoint (struct breakpoint *bpt) do_enable_breakpoint (bpt, disp_disable); } -/* ARGSUSED */ static void enable_once_command (char *args, int from_tty) { @@ -7318,13 +7708,22 @@ enable_delete_breakpoint (struct breakpoint *bpt) do_enable_breakpoint (bpt, disp_del); } -/* ARGSUSED */ static void enable_delete_command (char *args, int from_tty) { map_breakpoint_numbers (args, enable_delete_breakpoint); } +static void +set_breakpoint_cmd (char *args, int from_tty) +{ +} + +static void +show_breakpoint_cmd (char *args, int from_tty) +{ +} + /* Use default_breakpoint_'s, or nothing if they aren't valid. */ struct symtabs_and_lines @@ -7337,10 +7736,10 @@ decode_line_spec_1 (char *string, int funfirstline) sals = decode_line_1 (&string, funfirstline, default_breakpoint_symtab, default_breakpoint_line, - (char ***) NULL); + (char ***) NULL, NULL); else sals = decode_line_1 (&string, funfirstline, - (struct symtab *) NULL, 0, (char ***) NULL); + (struct symtab *) NULL, 0, (char ***) NULL, NULL); if (*string) error ("Junk at end of line specification: %s", string); return sals; @@ -7349,6 +7748,8 @@ decode_line_spec_1 (char *string, int funfirstline) void _initialize_breakpoint (void) { + static struct cmd_list_element *breakpoint_set_cmdlist; + static struct cmd_list_element *breakpoint_show_cmdlist; struct cmd_list_element *c; breakpoint_chain = 0; @@ -7374,26 +7775,26 @@ then no output is printed when it is hit, except what the commands print."); add_com ("condition", class_breakpoint, condition_command, "Specify breakpoint number N to break only if COND is true.\n\ Usage is `condition N COND', where N is an integer and COND is an\n\ -expression to be evaluated whenever breakpoint N is reached. "); +expression to be evaluated whenever breakpoint N is reached."); c = add_com ("tbreak", class_breakpoint, tbreak_command, "Set a temporary breakpoint. Args like \"break\" command.\n\ Like \"break\" except the breakpoint is only temporary,\n\ so it will be deleted when hit. Equivalent to \"break\" followed\n\ by using \"enable delete\" on the breakpoint number."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); c = add_com ("hbreak", class_breakpoint, hbreak_command, "Set a hardware assisted breakpoint. Args like \"break\" command.\n\ Like \"break\" except the breakpoint requires hardware support,\n\ some target hardware may not have this support."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); c = add_com ("thbreak", class_breakpoint, thbreak_command, "Set a temporary hardware assisted breakpoint. Args like \"break\" command.\n\ Like \"hbreak\" except the breakpoint is only temporary,\n\ so it will be deleted when hit."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); add_prefix_cmd ("enable", class_breakpoint, enable_command, "Enable some breakpoints.\n\ @@ -7507,7 +7908,7 @@ This is useful for breaking on return to a stack frame.\n\ Multiple breakpoints at one place are permitted, and useful if conditional.\n\ \n\ Do \"help breakpoints\" for info on other commands dealing with breakpoints.", NULL)); - c->completer = location_completer; + set_cmd_completer (c, location_completer); add_com_alias ("b", "break", class_run, 1); add_com_alias ("br", "break", class_run, 1); @@ -7638,19 +8039,19 @@ by using \"enable delete\" on the catchpoint number."); "Set a watchpoint for an expression.\n\ A watchpoint stops execution of your program whenever the value of\n\ an expression changes."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); c = add_com ("rwatch", class_breakpoint, rwatch_command, "Set a read watchpoint for an expression.\n\ A watchpoint stops execution of your program whenever the value of\n\ an expression is read."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); c = add_com ("awatch", class_breakpoint, awatch_command, "Set a watchpoint for an expression.\n\ A watchpoint stops execution of your program whenever the value of\n\ an expression is either read or written."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); add_info ("watchpoints", breakpoints_info, "Synonym for ``info breakpoints''."); @@ -7667,4 +8068,34 @@ hardware.)", add_show_from_set (c, &showlist); can_use_hw_watchpoints = 1; + + add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, "\ +Breakpoint specific settings\n\ +Configure various breakpoint-specific variables such as\n\ +pending breakpoint behavior", + &breakpoint_set_cmdlist, "set breakpoint ", + 0/*allow-unknown*/, &setlist); + add_prefix_cmd ("breakpoint", class_maintenance, show_breakpoint_cmd, "\ +Breakpoint specific settings\n\ +Configure various breakpoint-specific variables such as\n\ +pending breakpoint behavior", + &breakpoint_show_cmdlist, "show breakpoint ", + 0/*allow-unknown*/, &showlist); + + add_setshow_auto_boolean_cmd ("pending", no_class, &pending_break_support, "\ +Set debugger's behavior regarding pending breakpoints.\n\ +If on, an unrecognized breakpoint location will cause gdb to create a\n\ +pending breakpoint. If off, an unrecognized breakpoint location results in\n\ +an error. If auto, an unrecognized breakpoint location results in a\n\ +user-query to see if a pending breakpoint should be created.","\ +Show debugger's behavior regarding pending breakpoints.\n\ +If on, an unrecognized breakpoint location will cause gdb to create a\n\ +pending breakpoint. If off, an unrecognized breakpoint location results in\n\ +an error. If auto, an unrecognized breakpoint location results in a\n\ +user-query to see if a pending breakpoint should be created.", + NULL, NULL, + &breakpoint_set_cmdlist, + &breakpoint_show_cmdlist); + + pending_break_support = AUTO_BOOLEAN_AUTO; } diff --git a/contrib/gdb/gdb/breakpoint.h b/contrib/gdb/gdb/breakpoint.h index 3a58aad2487..41bcb0c3ce1 100644 --- a/contrib/gdb/gdb/breakpoint.h +++ b/contrib/gdb/gdb/breakpoint.h @@ -1,5 +1,6 @@ /* Data structures associated with breakpoints in GDB. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -28,6 +29,7 @@ #include "gdb-events.h" struct value; +struct block; /* This is the maximum number of bytes a breakpoint instruction can take. Feel free to increase it. It's just used in a few places to size @@ -183,6 +185,97 @@ enum target_hw_bp_type hw_execute = 3 /* Execute HW breakpoint */ }; +/* GDB maintains two types of information about each breakpoint (or + watchpoint, or other related event). The first type corresponds + to struct breakpoint; this is a relatively high-level structure + which contains the source location(s), stopping conditions, user + commands to execute when the breakpoint is hit, and so forth. + + The second type of information corresponds to struct bp_location. + Each breakpoint has one or (eventually) more locations associated + with it, which represent target-specific and machine-specific + mechanisms for stopping the program. For instance, a watchpoint + expression may require multiple hardware watchpoints in order to + catch all changes in the value of the expression being watched. */ + +enum bp_loc_type +{ + bp_loc_software_breakpoint, + bp_loc_hardware_breakpoint, + bp_loc_hardware_watchpoint, + bp_loc_other /* Miscellaneous... */ +}; + +struct bp_location +{ + /* Chain pointer to the next breakpoint location. */ + struct bp_location *next; + + /* Type of this breakpoint location. */ + enum bp_loc_type loc_type; + + /* Each breakpoint location must belong to exactly one higher-level + breakpoint. This and the DUPLICATE flag are more straightforward + than reference counting. */ + struct breakpoint *owner; + + /* Nonzero if this breakpoint is now inserted. */ + char inserted; + + /* Nonzero if this is not the first breakpoint in the list + for the given address. */ + char duplicate; + + /* If we someday support real thread-specific breakpoints, then + the breakpoint location will need a thread identifier. */ + + /* Data for specific breakpoint types. These could be a union, but + simplicity is more important than memory usage for breakpoints. */ + + /* Note that zero is a perfectly valid code address on some platforms + (for example, the mn10200 (OBSOLETE) and mn10300 simulators). NULL + is not a special value for this field. Valid for all types except + bp_loc_other. */ + CORE_ADDR address; + + /* For any breakpoint type with an address, this is the BFD section + associated with the address. Used primarily for overlay debugging. */ + asection *section; + + /* "Real" contents of byte where breakpoint has been inserted. + Valid only when breakpoints are in the program. Under the complete + control of the target insert_breakpoint and remove_breakpoint routines. + No other code should assume anything about the value(s) here. + Valid only for bp_loc_software_breakpoint. */ + char shadow_contents[BREAKPOINT_MAX]; + + /* Address at which breakpoint was requested, either by the user or + by GDB for internal breakpoints. This will usually be the same + as ``address'' (above) except for cases in which + ADJUST_BREAKPOINT_ADDRESS has computed a different address at + which to place the breakpoint in order to comply with a + processor's architectual constraints. */ + CORE_ADDR requested_address; +}; + +/* This structure is a collection of function pointers that, if available, + will be called instead of the performing the default action for this + bptype. */ + +struct breakpoint_ops +{ + /* The normal print routine for this breakpoint, called when we + hit it. */ + enum print_stop_action (*print_it) (struct breakpoint *); + + /* Display information about this breakpoint, for "info breakpoints". */ + void (*print_one) (struct breakpoint *, CORE_ADDR *); + + /* Display information about this breakpoint after setting it (roughly + speaking; this is called from "mention"). */ + void (*print_mention) (struct breakpoint *); +}; + /* Note that the ->silent field is not currently used by any commands (though the code is in there if it was to be, and set_raw_breakpoint does set it to 0). I implemented it because I thought it would be @@ -203,11 +296,8 @@ struct breakpoint /* Number assigned to distinguish breakpoints. */ int number; - /* Address to break at. - Note that zero is a perfectly valid code address on some - platforms (for example, the mn10200 and mn10300 simulators). - NULL is not a special value for this field. */ - CORE_ADDR address; + /* Location(s) associated with this high-level breakpoint. */ + struct bp_location *loc; /* Line number of this address. */ @@ -223,21 +313,11 @@ struct breakpoint /* Number of stops at this breakpoint that should be continued automatically before really stopping. */ int ignore_count; - /* "Real" contents of byte where breakpoint has been inserted. - Valid only when breakpoints are in the program. Under the complete - control of the target insert_breakpoint and remove_breakpoint routines. - No other code should assume anything about the value(s) here. */ - char shadow_contents[BREAKPOINT_MAX]; - /* Nonzero if this breakpoint is now inserted. */ - char inserted; - /* Nonzero if this is not the first breakpoint in the list - for the given address. */ - char duplicate; /* Chain of command lines to execute when this breakpoint is hit. */ struct command_line *commands; /* Stack depth (address of frame). If nonzero, break only if fp equals this. */ - CORE_ADDR frame; + struct frame_id frame_id; /* Conditional. Break only if this expression's value is nonzero. */ struct expression *cond; @@ -270,10 +350,10 @@ struct breakpoint 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. */ - CORE_ADDR watchpoint_frame; + /* 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. */ + struct frame_id watchpoint_frame; /* Thread number for thread-specific breakpoint, or -1 if don't care */ int thread; @@ -304,7 +384,19 @@ struct breakpoint triggered. */ char *exec_pathname; - asection *section; + /* Methods associated with this breakpoint. */ + struct breakpoint_ops *ops; + + /* Was breakpoint issued from a tty? Saved for the use of pending breakpoints. */ + int from_tty; + + /* Flag value for pending breakpoint. + first bit : 0 non-temporary, 1 temporary. + second bit : 0 normal breakpoint, 1 hardware breakpoint. */ + int flag; + + /* Is breakpoint pending on shlib loads? */ + int pending; }; /* The following stuff is an abstract data type "bpstat" ("breakpoint @@ -322,7 +414,7 @@ extern void bpstat_clear (bpstat *); is part of the bpstat is copied as well. */ extern bpstat bpstat_copy (bpstat); -extern bpstat bpstat_stop_status (CORE_ADDR *, int); +extern bpstat bpstat_stop_status (CORE_ADDR pc, ptid_t ptid); /* This bpstat_what stuff tells wait_for_inferior what to do with a breakpoint (a challenging task). */ @@ -521,18 +613,22 @@ enum breakpoint_here /* Prototypes for breakpoint-related functions. */ -/* Forward declarations for prototypes */ -struct frame_info; - extern enum breakpoint_here breakpoint_here_p (CORE_ADDR); extern int breakpoint_inserted_here_p (CORE_ADDR); -extern int frame_in_dummy (struct frame_info *); +extern int software_breakpoint_inserted_here_p (CORE_ADDR); + +/* FIXME: cagney/2002-11-10: The current [generic] dummy-frame code + implements a functional superset of this function. The only reason + it hasn't been removed is because some architectures still don't + use the new framework. Once they have been fixed, this can go. */ +struct frame_info; +extern int deprecated_frame_in_dummy (struct frame_info *); extern int breakpoint_thread_match (CORE_ADDR, ptid_t); -extern void until_break_command (char *, int); +extern void until_break_command (char *, int, int); extern void breakpoint_re_set (void); @@ -541,7 +637,7 @@ extern void breakpoint_re_set_thread (struct breakpoint *); extern int ep_is_exception_catchpoint (struct breakpoint *); extern struct breakpoint *set_momentary_breakpoint - (struct symtab_and_line, struct frame_info *, enum bptype); + (struct symtab_and_line, struct frame_id, enum bptype); extern void set_ignore_count (int, int, int); @@ -615,12 +711,12 @@ extern void disable_longjmp_breakpoint (void); extern void enable_overlay_breakpoints (void); extern void disable_overlay_breakpoints (void); -extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_info *); +extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_id); /* These functions respectively disable or reenable all currently enabled watchpoints. When disabled, the watchpoints are marked call_disabled. When reenabled, they are marked enabled. - The intended client of these functions is infcmd.c\run_stack_dummy. + The intended client of these functions is call_function_by_hand. The inferior must be stopped, and all breakpoints removed, when these functions are used. diff --git a/contrib/gdb/gdb/buildsym.c b/contrib/gdb/gdb/buildsym.c index 0e4f9b8eca0..4b362e08a2e 100644 --- a/contrib/gdb/gdb/buildsym.c +++ b/contrib/gdb/gdb/buildsym.c @@ -1,6 +1,7 @@ /* Support routines for building symbol tables in GDB's internal format. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GDB. @@ -28,17 +29,24 @@ #include "defs.h" #include "bfd.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "symtab.h" -#include "symfile.h" /* Needed for "struct complaint" */ +#include "symfile.h" #include "objfiles.h" #include "gdbtypes.h" +#include "gdb_assert.h" #include "complaints.h" #include "gdb_string.h" #include "expression.h" /* For "enum exp_opcode" used by... */ -#include "language.h" /* For "longest_local_hex_string_custom" */ +#include "language.h" /* For "local_hex_string" */ #include "bcache.h" #include "filenames.h" /* For DOSish file names */ +#include "macrotab.h" +#include "demangle.h" /* Needed by SYMBOL_INIT_DEMANGLED_NAME. */ +#include "block.h" +#include "cp-support.h" +#include "dictionary.h" + /* Ask buildsym.h to define the vars it normally declares `extern'. */ #define EXTERN /**/ @@ -70,30 +78,13 @@ static int compare_line_numbers (const void *ln1p, const void *ln2p); #define INITIAL_LINE_VECTOR_LENGTH 1000 -/* Complaints about the symbols we have encountered. */ - -struct complaint block_end_complaint = -{"block end address less than block start address in %s (patched it)", 0, 0}; - -struct complaint anon_block_end_complaint = -{"block end address 0x%lx less than block start address 0x%lx (patched it)", 0, 0}; - -struct complaint innerblock_complaint = -{"inner block not inside outer block in %s", 0, 0}; - -struct complaint innerblock_anon_complaint = -{"inner block (0x%lx-0x%lx) not inside outer block (0x%lx-0x%lx)", 0, 0}; - -struct complaint blockvector_complaint = -{"block at %s out of order", 0, 0}; - /* maintain the lists of symbols and blocks */ /* Add a pending list to free_pendings. */ void add_free_pendings (struct pending *list) { - register struct pending *link = list; + struct pending *link = list; if (list) { @@ -103,12 +94,15 @@ add_free_pendings (struct pending *list) } } -/* Add a symbol to one of the lists of symbols. */ +/* Add a symbol to one of the lists of symbols. While we're at it, if + we're in the C++ case and don't have full namespace debugging info, + check to see if it references an anonymous namespace; if so, add an + appropriate using directive. */ void add_symbol_to_list (struct symbol *symbol, struct pending **listhead) { - register struct pending *link; + struct pending *link; /* If this is an alias for another symbol, don't add it. */ if (symbol->ginfo.name && symbol->ginfo.name[0] == '#') @@ -134,6 +128,12 @@ add_symbol_to_list (struct symbol *symbol, struct pending **listhead) } (*listhead)->symbol[(*listhead)->nsyms++] = symbol; + + /* Check to see if we might need to look for a mention of anonymous + namespaces. */ + + if (SYMBOL_LANGUAGE (symbol) == language_cplus) + cp_scan_for_anonymous_namespaces (symbol); } /* Find a symbol named NAME on a LIST. NAME need not be @@ -149,7 +149,7 @@ find_symbol_in_list (struct pending *list, char *name, int length) { for (j = list->nsyms; --j >= 0;) { - pp = SYMBOL_NAME (list->symbol[j]); + pp = DEPRECATED_SYMBOL_NAME (list->symbol[j]); if (*pp == *name && strncmp (pp, name, length) == 0 && pp[length] == '\0') { @@ -164,9 +164,8 @@ find_symbol_in_list (struct pending *list, char *name, int length) /* At end of reading syms, or in case of quit, really free as many `struct pending's as we can easily find. */ -/* ARGSUSED */ void -really_free_pendings (PTR dummy) +really_free_pendings (void *dummy) { struct pending *next, *next1; @@ -192,6 +191,9 @@ really_free_pendings (PTR dummy) xfree ((void *) next); } global_symbols = NULL; + + if (pending_macros) + free_macro_table (pending_macros); } /* This function is called to discard any pending blocks. */ @@ -200,7 +202,7 @@ void free_pending_blocks (void) { #if 0 /* Now we make the links in the - symbol_obstack, so don't free + objfile_obstack, so don't free them. */ struct pending_block *bnext, *bnext1; @@ -223,40 +225,29 @@ finish_block (struct symbol *symbol, struct pending **listhead, CORE_ADDR start, CORE_ADDR end, struct objfile *objfile) { - register struct pending *next, *next1; - register struct block *block; - register struct pending_block *pblock; + struct pending *next, *next1; + struct block *block; + struct pending_block *pblock; struct pending_block *opblock; - register int i; - register int j; - /* Count the length of the list of symbols. */ + block = allocate_block (&objfile->objfile_obstack); - for (next = *listhead, i = 0; - next; - i += next->nsyms, next = next->next) + if (symbol) { - /* EMPTY */ ; + BLOCK_DICT (block) = dict_create_linear (&objfile->objfile_obstack, + *listhead); } - - block = (struct block *) obstack_alloc (&objfile->symbol_obstack, - (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *)))); - - /* Copy the symbols into the block. */ - - BLOCK_NSYMS (block) = i; - for (next = *listhead; next; next = next->next) + else { - for (j = next->nsyms - 1; j >= 0; j--) - { - BLOCK_SYM (block, --i) = next->symbol[j]; - } + BLOCK_DICT (block) = dict_create_hashed (&objfile->objfile_obstack, + *listhead); } BLOCK_START (block) = start; BLOCK_END (block) = end; /* Superblock filled in when containing block is made */ BLOCK_SUPERBLOCK (block) = NULL; + BLOCK_NAMESPACE (block) = NULL; BLOCK_GCC_COMPILED (block) = processing_gcc_compilation; @@ -265,6 +256,7 @@ finish_block (struct symbol *symbol, struct pending **listhead, if (symbol) { struct type *ftype = SYMBOL_TYPE (symbol); + struct dict_iterator iter; SYMBOL_BLOCK_VALUE (symbol) = block; BLOCK_FUNCTION (block) = symbol; @@ -275,7 +267,7 @@ finish_block (struct symbol *symbol, struct pending **listhead, parameter symbols. */ int nparams = 0, iparams; struct symbol *sym; - ALL_BLOCK_SYMBOLS (block, i, sym) + ALL_BLOCK_SYMBOLS (block, iter, sym) { switch (SYMBOL_CLASS (sym)) { @@ -285,6 +277,7 @@ finish_block (struct symbol *symbol, struct pending **listhead, case LOC_REGPARM_ADDR: case LOC_BASEREG_ARG: case LOC_LOCAL_ARG: + case LOC_COMPUTED_ARG: nparams++; break; case LOC_UNDEF: @@ -300,6 +293,7 @@ finish_block (struct symbol *symbol, struct pending **listhead, case LOC_BASEREG: case LOC_UNRESOLVED: case LOC_OPTIMIZED_OUT: + case LOC_COMPUTED: default: break; } @@ -310,9 +304,12 @@ finish_block (struct symbol *symbol, struct pending **listhead, TYPE_FIELDS (ftype) = (struct field *) TYPE_ALLOC (ftype, nparams * sizeof (struct field)); - for (i = iparams = 0; iparams < nparams; i++) + iparams = 0; + ALL_BLOCK_SYMBOLS (block, iter, sym) { - sym = BLOCK_SYM (block, i); + if (iparams == nparams) + break; + switch (SYMBOL_CLASS (sym)) { case LOC_ARG: @@ -321,6 +318,7 @@ finish_block (struct symbol *symbol, struct pending **listhead, case LOC_REGPARM_ADDR: case LOC_BASEREG_ARG: case LOC_LOCAL_ARG: + case LOC_COMPUTED_ARG: TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym); TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0; iparams++; @@ -338,12 +336,19 @@ finish_block (struct symbol *symbol, struct pending **listhead, case LOC_BASEREG: case LOC_UNRESOLVED: case LOC_OPTIMIZED_OUT: + case LOC_COMPUTED: default: break; } } } } + + /* If we're in the C++ case, set the block's scope. */ + if (SYMBOL_LANGUAGE (symbol) == language_cplus) + { + cp_set_block_scope (symbol, block, &objfile->objfile_obstack); + } } else { @@ -368,11 +373,15 @@ finish_block (struct symbol *symbol, struct pending **listhead, { if (symbol) { - complain (&block_end_complaint, SYMBOL_SOURCE_NAME (symbol)); + complaint (&symfile_complaints, + "block end address less than block start address in %s (patched it)", + SYMBOL_PRINT_NAME (symbol)); } else { - complain (&anon_block_end_complaint, BLOCK_END (block), BLOCK_START (block)); + complaint (&symfile_complaints, + "block end address 0x%s less than block start address 0x%s (patched it)", + paddr_nz (BLOCK_END (block)), paddr_nz (BLOCK_START (block))); } /* Better than nothing */ BLOCK_END (block) = BLOCK_START (block); @@ -383,7 +392,9 @@ finish_block (struct symbol *symbol, struct pending **listhead, start of this scope that don't have superblocks yet. */ opblock = NULL; - for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next) + for (pblock = pending_blocks; + pblock && pblock != old_blocks; + pblock = pblock->next) { if (BLOCK_SUPERBLOCK (pblock->block) == NULL) { @@ -396,14 +407,18 @@ finish_block (struct symbol *symbol, struct pending **listhead, { if (symbol) { - complain (&innerblock_complaint, - SYMBOL_SOURCE_NAME (symbol)); + complaint (&symfile_complaints, + "inner block not inside outer block in %s", + SYMBOL_PRINT_NAME (symbol)); } else { - complain (&innerblock_anon_complaint, BLOCK_START (pblock->block), - BLOCK_END (pblock->block), BLOCK_START (block), - BLOCK_END (block)); + complaint (&symfile_complaints, + "inner block (0x%s-0x%s) not inside outer block (0x%s-0x%s)", + paddr_nz (BLOCK_START (pblock->block)), + paddr_nz (BLOCK_END (pblock->block)), + paddr_nz (BLOCK_START (block)), + paddr_nz (BLOCK_END (block))); } if (BLOCK_START (pblock->block) < BLOCK_START (block)) BLOCK_START (pblock->block) = BLOCK_START (block); @@ -419,21 +434,22 @@ finish_block (struct symbol *symbol, struct pending **listhead, record_pending_block (objfile, block, opblock); } + /* Record BLOCK on the list of all blocks in the file. Put it after OPBLOCK, or at the beginning if opblock is NULL. This puts the block in the list after all its subblocks. - Allocate the pending block struct in the symbol_obstack to save + Allocate the pending block struct in the objfile_obstack to save time. This wastes a little space. FIXME: Is it worth it? */ void record_pending_block (struct objfile *objfile, struct block *block, struct pending_block *opblock) { - register struct pending_block *pblock; + struct pending_block *pblock; pblock = (struct pending_block *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct pending_block)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct pending_block)); pblock->block = block; if (opblock) { @@ -447,16 +463,12 @@ record_pending_block (struct objfile *objfile, struct block *block, } } -/* Note that this is only used in this file and in dstread.c, which - should be fixed to not need direct access to this function. When - that is done, it can be made static again. */ - -struct blockvector * +static struct blockvector * make_blockvector (struct objfile *objfile) { - register struct pending_block *next; - register struct blockvector *blockvector; - register int i; + struct pending_block *next; + struct blockvector *blockvector; + int i; /* Count the length of the list of blocks. */ @@ -465,7 +477,7 @@ make_blockvector (struct objfile *objfile) } blockvector = (struct blockvector *) - obstack_alloc (&objfile->symbol_obstack, + obstack_alloc (&objfile->objfile_obstack, (sizeof (struct blockvector) + (i - 1) * sizeof (struct block *))); @@ -508,8 +520,8 @@ make_blockvector (struct objfile *objfile) CORE_ADDR start = BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i)); - complain (&blockvector_complaint, - longest_local_hex_string ((LONGEST) start)); + complaint (&symfile_complaints, "block at %s out of order", + local_hex_string ((LONGEST) start)); } } } @@ -526,7 +538,7 @@ make_blockvector (struct objfile *objfile) void start_subfile (char *name, char *dirname) { - register struct subfile *subfile; + struct subfile *subfile; /* See if this subfile is already known as a subfile of the current main source file. */ @@ -580,15 +592,9 @@ start_subfile (char *name, char *dirname) later via a call to record_debugformat. */ subfile->debugformat = NULL; - /* cfront output is a C program, so in most ways it looks like a C - program. But to demangle we need to set the language to C++. We - can distinguish cfront code by the fact that it has #line - directives which specify a file name ending in .C. - - So if the filename of this subfile ends in .C, then change the + /* If the filename of this subfile ends in .C, then change the language of any pending subfiles from C to C++. We also accept - any other C++ suffixes accepted by deduce_language_from_filename - (in particular, some people use .cxx with cfront). */ + any other C++ suffixes accepted by deduce_language_from_filename. */ /* Likewise for f2c. */ if (subfile->name) @@ -662,7 +668,7 @@ patch_subfile_names (struct subfile *subfile, char *name) void push_subfile (void) { - register struct subfile_stack *tem + struct subfile_stack *tem = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack)); tem->next = subfile_stack; @@ -677,8 +683,8 @@ push_subfile (void) char * pop_subfile (void) { - register char *name; - register struct subfile_stack *link = subfile_stack; + char *name; + struct subfile_stack *link = subfile_stack; if (link == NULL) { @@ -694,7 +700,7 @@ pop_subfile (void) line vector for SUBFILE. */ void -record_line (register struct subfile *subfile, int line, CORE_ADDR pc) +record_line (struct subfile *subfile, int line, CORE_ADDR pc) { struct linetable_entry *e; /* Ignore the dummy line number in libg.o */ @@ -777,6 +783,10 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr) } context_stack_depth = 0; + /* Set up support for C++ namespace support, in case we need it. */ + + cp_initialize_namespace (); + /* Initialize the list of sub source files with one entry for this file (the top-level source file). */ @@ -805,10 +815,10 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr) struct symtab * end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) { - register struct symtab *symtab = NULL; - register struct blockvector *blockvector; - register struct subfile *subfile; - register struct context_stack *cstk; + struct symtab *symtab = NULL; + struct blockvector *blockvector; + struct subfile *subfile; + struct context_stack *cstk; struct subfile *nextsub; /* Finish the lexical context of the last function in the file; pop @@ -828,9 +838,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) same. FIXME: Find out why it is happening. This is not believed to happen in most cases (even for coffread.c); it used to be an abort(). */ - static struct complaint msg = - {"Context stack not empty in end_symtab", 0, 0}; - complain (&msg); + complaint (&symfile_complaints, + "Context stack not empty in end_symtab"); context_stack_depth = 0; } } @@ -883,7 +892,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) if (pending_blocks == NULL && file_symbols == NULL && global_symbols == NULL - && have_line_numbers == 0) + && have_line_numbers == 0 + && pending_macros == NULL) { /* Ignore symtabs that have no functions with real debugging info. */ @@ -898,6 +908,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr, objfile); blockvector = make_blockvector (objfile); + cp_finalize_namespace (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK), + &objfile->objfile_obstack); } #ifndef PROCESS_LINENUMBER_HOOK @@ -944,11 +956,12 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) /* Fill in its components. */ symtab->blockvector = blockvector; + symtab->macro_table = pending_macros; if (subfile->line_vector) { /* Reallocate the line table on the symbol obstack */ symtab->linetable = (struct linetable *) - obstack_alloc (&objfile->symbol_obstack, linetablesize); + obstack_alloc (&objfile->objfile_obstack, linetablesize); memcpy (symtab->linetable, subfile->line_vector, linetablesize); } else @@ -960,7 +973,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) { /* Reallocate the dirname on the symbol obstack */ symtab->dirname = (char *) - obstack_alloc (&objfile->symbol_obstack, + obstack_alloc (&objfile->objfile_obstack, strlen (subfile->dirname) + 1); strcpy (symtab->dirname, subfile->dirname); } @@ -969,7 +982,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) symtab->dirname = NULL; } symtab->free_code = free_linetable; - symtab->free_ptr = NULL; + symtab->free_func = NULL; /* Use whatever language we have been using for this subfile, not the one that was deduced in allocate_symtab @@ -984,7 +997,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) { symtab->debugformat = obsavestring (subfile->debugformat, strlen (subfile->debugformat), - &objfile->symbol_obstack); + &objfile->objfile_obstack); } /* All symtabs for the main file and the subfiles share a @@ -1022,6 +1035,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) last_source_file = NULL; current_subfile = NULL; + pending_macros = NULL; return symtab; } @@ -1033,7 +1047,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) struct context_stack * push_context (int desc, CORE_ADDR valu) { - register struct context_stack *new; + struct context_stack *new; if (context_stack_depth == context_stack_size) { @@ -1056,6 +1070,17 @@ push_context (int desc, CORE_ADDR valu) return new; } + +/* Pop a context block. Returns the address of the context block just + popped. */ + +struct context_stack * +pop_context (void) +{ + gdb_assert (context_stack_depth > 0); + return (&context_stack[--context_stack_depth]); +} + /* Compute a small integer hash code for the given name. */ @@ -1084,7 +1109,7 @@ record_debugformat (char *format) void merge_symbol_lists (struct pending **srclist, struct pending **targetlist) { - register int i; + int i; if (!srclist || !*srclist) return; @@ -1112,6 +1137,7 @@ buildsym_init (void) file_symbols = NULL; global_symbols = NULL; pending_blocks = NULL; + pending_macros = NULL; } /* Initialize anything that needs initializing when a completely new diff --git a/contrib/gdb/gdb/buildsym.h b/contrib/gdb/gdb/buildsym.h index 40a339deae7..e80d8c6743e 100644 --- a/contrib/gdb/gdb/buildsym.h +++ b/contrib/gdb/gdb/buildsym.h @@ -1,6 +1,6 @@ /* Build symbol tables in GDB's internal format. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1996, - 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + 1997, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -22,6 +22,9 @@ #if !defined (BUILDSYM_H) #define BUILDSYM_H 1 +struct objfile; +struct symbol; + /* This module provides definitions used for creating and adding to the symbol table. These routines are called from various symbol- file-reading routines. @@ -34,6 +37,8 @@ normally extern, but which get defined in a single module using this technique. */ +struct block; + #ifndef EXTERN #define EXTERN extern #endif @@ -83,16 +88,6 @@ EXTERN unsigned char processing_gcc_compilation; EXTERN unsigned char processing_acc_compilation; -/* elz: added this flag to know when a block is compiled with HP - compilers (cc, aCC). This is necessary because of the macro - COERCE_FLOAT_TO_DOUBLE defined in tm_hppa.h, which causes a - coercion of float to double to always occur in parameter passing - for a function called by gdb (see the function value_arg_coerce in - valops.c). This is necessary only if the target was compiled with - gcc, not with HP compilers or with g++ */ - -EXTERN unsigned char processing_hp_compilation; - /* Count symbols as they are processed, for error messages. */ EXTERN unsigned int symnum; @@ -173,11 +168,8 @@ EXTERN int context_stack_depth; EXTERN int context_stack_size; -/* Macro "function" for popping contexts from the stack. Pushing is - done by a real function, push_context. This returns a pointer to a - struct context_stack. */ - -#define pop_context() (&context_stack[--context_stack_depth]); +/* Non-zero if the context stack is empty. */ +#define outermost_context_p() (context_stack_depth == 0) /* Nonzero if within a function (so symbols should be local, if nothing says specifically). */ @@ -246,7 +238,7 @@ extern void finish_block (struct symbol *symbol, CORE_ADDR start, CORE_ADDR end, struct objfile *objfile); -extern void really_free_pendings (PTR dummy); +extern void really_free_pendings (void *dummy); extern void start_subfile (char *name, char *dirname); @@ -269,6 +261,8 @@ extern void buildsym_init (void); extern struct context_stack *push_context (int desc, CORE_ADDR valu); +extern struct context_stack *pop_context (void); + extern void record_line (struct subfile *subfile, int line, CORE_ADDR pc); extern void start_symtab (char *name, char *dirname, CORE_ADDR start_addr); @@ -277,12 +271,6 @@ extern int hashname (char *name); extern void free_pending_blocks (void); -/* FIXME: Note that this is used only in buildsym.c and dstread.c, - which should be fixed to not need direct access to - make_blockvector. */ - -extern struct blockvector *make_blockvector (struct objfile *objfile); - /* FIXME: Note that this is used only in buildsym.c and dstread.c, which should be fixed to not need direct access to record_pending_block. */ @@ -296,6 +284,10 @@ extern void record_debugformat (char *format); extern void merge_symbol_lists (struct pending **srclist, struct pending **targetlist); +/* The macro table for the compilation unit whose symbols we're + currently reading. All the symtabs for this CU will point to this. */ +EXTERN struct macro_table *pending_macros; + #undef EXTERN #endif /* defined (BUILDSYM_H) */ diff --git a/contrib/gdb/gdb/c-exp.c b/contrib/gdb/gdb/c-exp.c new file mode 100644 index 00000000000..7ee5a4538df --- /dev/null +++ b/contrib/gdb/gdb/c-exp.c @@ -0,0 +1,3443 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + INT = 258, + FLOAT = 259, + STRING = 260, + NAME = 261, + TYPENAME = 262, + NAME_OR_INT = 263, + STRUCT = 264, + CLASS = 265, + UNION = 266, + ENUM = 267, + SIZEOF = 268, + UNSIGNED = 269, + COLONCOLON = 270, + TEMPLATE = 271, + ERROR = 272, + SIGNED_KEYWORD = 273, + LONG = 274, + SHORT = 275, + INT_KEYWORD = 276, + CONST_KEYWORD = 277, + VOLATILE_KEYWORD = 278, + DOUBLE_KEYWORD = 279, + VARIABLE = 280, + ASSIGN_MODIFY = 281, + TRUEKEYWORD = 282, + FALSEKEYWORD = 283, + ABOVE_COMMA = 284, + OROR = 285, + ANDAND = 286, + NOTEQUAL = 287, + EQUAL = 288, + GEQ = 289, + LEQ = 290, + RSH = 291, + LSH = 292, + DECREMENT = 293, + INCREMENT = 294, + UNARY = 295, + ARROW = 296, + BLOCKNAME = 297, + FILENAME = 298 + }; +#endif +#define INT 258 +#define FLOAT 259 +#define STRING 260 +#define NAME 261 +#define TYPENAME 262 +#define NAME_OR_INT 263 +#define STRUCT 264 +#define CLASS 265 +#define UNION 266 +#define ENUM 267 +#define SIZEOF 268 +#define UNSIGNED 269 +#define COLONCOLON 270 +#define TEMPLATE 271 +#define ERROR 272 +#define SIGNED_KEYWORD 273 +#define LONG 274 +#define SHORT 275 +#define INT_KEYWORD 276 +#define CONST_KEYWORD 277 +#define VOLATILE_KEYWORD 278 +#define DOUBLE_KEYWORD 279 +#define VARIABLE 280 +#define ASSIGN_MODIFY 281 +#define TRUEKEYWORD 282 +#define FALSEKEYWORD 283 +#define ABOVE_COMMA 284 +#define OROR 285 +#define ANDAND 286 +#define NOTEQUAL 287 +#define EQUAL 288 +#define GEQ 289 +#define LEQ 290 +#define RSH 291 +#define LSH 292 +#define DECREMENT 293 +#define INCREMENT 294 +#define UNARY 295 +#define ARROW 296 +#define BLOCKNAME 297 +#define FILENAME 298 + + + + +/* Copy the first part of user declarations. */ +#line 39 "c-exp.y" + + +#include "defs.h" +#include "gdb_string.h" +#include +#include "expression.h" +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "c-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "charset.h" +#include "block.h" +#include "cp-support.h" + +/* Flag indicating we're dealing with HP-compiled objects */ +extern int hp_som_som_object_present; + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in gdb. Note that these are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +#define yymaxdepth c_maxdepth +#define yyparse c_parse +#define yylex c_lex +#define yyerror c_error +#define yylval c_lval +#define yychar c_char +#define yydebug c_debug +#define yypact c_pact +#define yyr1 c_r1 +#define yyr2 c_r2 +#define yydef c_def +#define yychk c_chk +#define yypgo c_pgo +#define yyact c_act +#define yyexca c_exca +#define yyerrflag c_errflag +#define yynerrs c_nerrs +#define yyps c_ps +#define yypv c_pv +#define yys c_s +#define yy_yys c_yys +#define yystate c_state +#define yytmp c_tmp +#define yyv c_v +#define yy_yyv c_yyv +#define yyval c_val +#define yylloc c_lloc +#define yyreds c_reds /* With YYDEBUG defined */ +#define yytoks c_toks /* With YYDEBUG defined */ +#define yyname c_name /* With YYDEBUG defined */ +#define yyrule c_rule /* With YYDEBUG defined */ +#define yylhs c_yylhs +#define yylen c_yylen +#define yydefred c_yydefred +#define yydgoto c_yydgoto +#define yysindex c_yysindex +#define yyrindex c_yyrindex +#define yygindex c_yygindex +#define yytable c_yytable +#define yycheck c_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 1 /* Default to yydebug support */ +#endif + +#define YYFPRINTF parser_fprintf + +int yyparse (void); + +static int yylex (void); + +void yyerror (char *); + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 126 "c-exp.y" +typedef union YYSTYPE { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val_int; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; + struct symbol *sym; + struct type *tval; + struct stoken sval; + struct ttype tsym; + struct symtoken ssym; + int voidval; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + + struct type **tvec; + int *ivec; + } YYSTYPE; +/* Line 191 of yacc.c. */ +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ +#line 150 "c-exp.y" + +/* YYSTYPE gets defined by %union */ +static int parse_number (char *, int, int, YYSTYPE *); + + +/* Line 214 of yacc.c. */ + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or xmalloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC xmalloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 94 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 804 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 68 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 31 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 159 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 242 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 298 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 61, 2, 2, 2, 51, 37, 2, + 57, 64, 49, 47, 29, 48, 55, 50, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 67, 2, + 40, 31, 41, 32, 46, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 56, 2, 63, 36, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 65, 35, 66, 62, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 30, 33, 34, 38, 39, 42, + 43, 44, 45, 52, 53, 54, 58, 59, 60 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 11, 15, 18, 21, + 24, 27, 30, 33, 36, 39, 42, 45, 49, 53, + 58, 62, 66, 71, 76, 77, 83, 85, 86, 88, + 92, 94, 98, 103, 108, 112, 116, 120, 124, 128, + 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, + 172, 176, 180, 184, 188, 194, 198, 202, 204, 206, + 208, 210, 212, 217, 219, 221, 223, 225, 227, 231, + 235, 239, 244, 246, 249, 251, 254, 256, 257, 261, + 263, 265, 267, 268, 270, 273, 275, 278, 280, 284, + 287, 289, 292, 294, 297, 301, 304, 308, 310, 314, + 316, 318, 320, 322, 325, 329, 332, 336, 340, 344, + 347, 350, 354, 359, 363, 367, 372, 376, 381, 385, + 390, 393, 397, 400, 404, 407, 411, 413, 416, 419, + 422, 425, 428, 431, 433, 436, 438, 444, 447, 450, + 452, 456, 458, 460, 462, 464, 466, 470, 472, 477, + 480, 483, 485, 487, 489, 491, 493, 495, 497, 499 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 69, 0, -1, 71, -1, 70, -1, 89, -1, 72, + -1, 71, 29, 72, -1, 49, 72, -1, 37, 72, + -1, 48, 72, -1, 61, 72, -1, 62, 72, -1, + 53, 72, -1, 52, 72, -1, 72, 53, -1, 72, + 52, -1, 13, 72, -1, 72, 58, 97, -1, 72, + 58, 79, -1, 72, 58, 49, 72, -1, 72, 55, + 97, -1, 72, 55, 79, -1, 72, 55, 49, 72, + -1, 72, 56, 71, 63, -1, -1, 72, 57, 73, + 75, 64, -1, 65, -1, -1, 72, -1, 75, 29, + 72, -1, 66, -1, 74, 75, 76, -1, 74, 89, + 76, 72, -1, 57, 89, 64, 72, -1, 57, 71, + 64, -1, 72, 46, 72, -1, 72, 49, 72, -1, + 72, 50, 72, -1, 72, 51, 72, -1, 72, 47, + 72, -1, 72, 48, 72, -1, 72, 45, 72, -1, + 72, 44, 72, -1, 72, 39, 72, -1, 72, 38, + 72, -1, 72, 43, 72, -1, 72, 42, 72, -1, + 72, 40, 72, -1, 72, 41, 72, -1, 72, 37, + 72, -1, 72, 36, 72, -1, 72, 35, 72, -1, + 72, 34, 72, -1, 72, 33, 72, -1, 72, 32, + 72, 67, 72, -1, 72, 31, 72, -1, 72, 26, + 72, -1, 3, -1, 8, -1, 4, -1, 78, -1, + 25, -1, 13, 57, 89, 64, -1, 5, -1, 27, + -1, 28, -1, 59, -1, 60, -1, 77, 15, 97, + -1, 77, 15, 97, -1, 90, 15, 97, -1, 90, + 15, 62, 97, -1, 79, -1, 15, 97, -1, 98, + -1, 46, 6, -1, 96, -1, -1, 81, 80, 81, + -1, 82, -1, 96, -1, 83, -1, -1, 49, -1, + 49, 85, -1, 37, -1, 37, 85, -1, 86, -1, + 57, 85, 64, -1, 86, 87, -1, 87, -1, 86, + 88, -1, 88, -1, 56, 63, -1, 56, 3, 63, + -1, 57, 64, -1, 57, 93, 64, -1, 94, -1, + 90, 15, 49, -1, 7, -1, 21, -1, 19, -1, + 20, -1, 19, 21, -1, 19, 18, 21, -1, 19, + 18, -1, 18, 19, 21, -1, 14, 19, 21, -1, + 19, 14, 21, -1, 19, 14, -1, 19, 19, -1, + 19, 19, 21, -1, 19, 19, 18, 21, -1, 19, + 19, 18, -1, 18, 19, 19, -1, 18, 19, 19, + 21, -1, 14, 19, 19, -1, 14, 19, 19, 21, + -1, 19, 19, 14, -1, 19, 19, 14, 21, -1, + 20, 21, -1, 20, 18, 21, -1, 20, 18, -1, + 14, 20, 21, -1, 20, 14, -1, 20, 14, 21, + -1, 24, -1, 19, 24, -1, 9, 97, -1, 10, + 97, -1, 11, 97, -1, 12, 97, -1, 14, 92, + -1, 14, -1, 18, 92, -1, 18, -1, 16, 97, + 40, 89, 41, -1, 83, 90, -1, 90, 83, -1, + 91, -1, 90, 15, 97, -1, 7, -1, 21, -1, + 19, -1, 20, -1, 89, -1, 93, 29, 89, -1, + 90, -1, 94, 84, 85, 84, -1, 22, 23, -1, + 23, 22, -1, 95, -1, 22, -1, 23, -1, 6, + -1, 59, -1, 7, -1, 8, -1, 6, -1, 59, + -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 233, 233, 234, 237, 244, 245, 250, 254, 258, + 262, 266, 270, 274, 278, 282, 286, 290, 296, 304, + 308, 314, 322, 326, 333, 330, 340, 344, 347, 351, + 355, 358, 365, 371, 377, 383, 387, 391, 395, 399, + 403, 407, 411, 415, 419, 423, 427, 431, 435, 439, + 443, 447, 451, 455, 459, 463, 467, 473, 480, 491, + 498, 501, 505, 513, 538, 545, 554, 562, 568, 579, + 595, 609, 634, 635, 669, 726, 732, 733, 736, 739, + 740, 744, 745, 748, 750, 752, 754, 756, 759, 761, + 766, 773, 775, 779, 781, 785, 787, 799, 800, 805, + 807, 809, 811, 813, 815, 817, 819, 821, 823, 825, + 827, 829, 831, 833, 835, 837, 839, 841, 843, 845, + 847, 849, 851, 853, 855, 857, 859, 861, 863, 866, + 869, 872, 875, 877, 879, 881, 886, 890, 892, 894, + 942, 967, 968, 974, 980, 989, 994, 1001, 1002, 1006, + 1007, 1010, 1014, 1016, 1020, 1021, 1022, 1023, 1026, 1027 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "INT", "FLOAT", "STRING", "NAME", + "TYPENAME", "NAME_OR_INT", "STRUCT", "CLASS", "UNION", "ENUM", "SIZEOF", + "UNSIGNED", "COLONCOLON", "TEMPLATE", "ERROR", "SIGNED_KEYWORD", "LONG", + "SHORT", "INT_KEYWORD", "CONST_KEYWORD", "VOLATILE_KEYWORD", + "DOUBLE_KEYWORD", "VARIABLE", "ASSIGN_MODIFY", "TRUEKEYWORD", + "FALSEKEYWORD", "','", "ABOVE_COMMA", "'='", "'?'", "OROR", "ANDAND", + "'|'", "'^'", "'&'", "NOTEQUAL", "EQUAL", "'<'", "'>'", "GEQ", "LEQ", + "RSH", "LSH", "'@'", "'+'", "'-'", "'*'", "'/'", "'%'", "DECREMENT", + "INCREMENT", "UNARY", "'.'", "'['", "'('", "ARROW", "BLOCKNAME", + "FILENAME", "'!'", "'~'", "']'", "')'", "'{'", "'}'", "':'", "$accept", + "start", "type_exp", "exp1", "exp", "@1", "lcurly", "arglist", "rcurly", + "block", "variable", "qualified_name", "space_identifier", + "const_or_volatile", "cv_with_space_id", + "const_or_volatile_or_space_identifier_noopt", + "const_or_volatile_or_space_identifier", "abs_decl", "direct_abs_decl", + "array_mod", "func_mod", "type", "typebase", "qualified_type", + "typename", "nonempty_typelist", "ptype", "const_and_volatile", + "const_or_volatile_noopt", "name", "name_not_typename", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 44, + 284, 61, 63, 285, 286, 124, 94, 38, 287, 288, + 60, 62, 289, 290, 291, 292, 64, 43, 45, 42, + 47, 37, 293, 294, 295, 46, 91, 40, 296, 297, + 298, 33, 126, 93, 41, 123, 125, 58 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 68, 69, 69, 70, 71, 71, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 73, 72, 74, 75, 75, 75, + 76, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 77, 77, 77, 78, + 79, 79, 78, 78, 78, 80, 81, 81, 82, 83, + 83, 84, 84, 85, 85, 85, 85, 85, 86, 86, + 86, 86, 86, 87, 87, 88, 88, 89, 89, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 91, 92, 92, 92, 92, 93, 93, 94, 94, 95, + 95, 96, 96, 96, 97, 97, 97, 97, 98, 98 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 3, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, + 3, 3, 4, 4, 0, 5, 1, 0, 1, 3, + 1, 3, 4, 4, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 5, 3, 3, 1, 1, 1, + 1, 1, 4, 1, 1, 1, 1, 1, 3, 3, + 3, 4, 1, 2, 1, 2, 1, 0, 3, 1, + 1, 1, 0, 1, 2, 1, 2, 1, 3, 2, + 1, 2, 1, 2, 3, 2, 3, 1, 3, 1, + 1, 1, 1, 2, 3, 2, 3, 3, 3, 2, + 2, 3, 4, 3, 3, 4, 3, 4, 3, 4, + 2, 3, 2, 3, 2, 3, 1, 2, 2, 2, + 2, 2, 2, 1, 2, 1, 5, 2, 2, 1, + 3, 1, 1, 1, 1, 1, 3, 1, 4, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 77, 57, 59, 63, 158, 99, 58, 0, 0, 0, + 0, 77, 133, 0, 0, 135, 101, 102, 100, 152, + 153, 126, 61, 64, 65, 77, 77, 77, 77, 77, + 77, 159, 67, 77, 77, 26, 0, 3, 2, 5, + 27, 0, 60, 72, 0, 79, 77, 4, 147, 139, + 97, 151, 80, 74, 154, 156, 157, 155, 128, 129, + 130, 131, 77, 16, 77, 141, 143, 144, 142, 132, + 73, 0, 143, 144, 134, 109, 105, 110, 103, 127, + 124, 122, 120, 149, 150, 8, 9, 7, 13, 12, + 0, 0, 10, 11, 1, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 15, 14, + 77, 77, 24, 77, 28, 0, 0, 0, 0, 77, + 137, 0, 138, 81, 0, 0, 0, 116, 107, 123, + 77, 114, 106, 108, 104, 118, 113, 111, 125, 121, + 34, 77, 6, 56, 55, 0, 53, 52, 51, 50, + 49, 44, 43, 47, 48, 46, 45, 42, 41, 35, + 39, 40, 36, 37, 38, 156, 77, 21, 20, 0, + 27, 77, 18, 17, 77, 30, 31, 77, 69, 75, + 78, 76, 0, 98, 0, 70, 85, 83, 0, 77, + 82, 87, 90, 92, 62, 117, 0, 147, 115, 119, + 112, 33, 77, 22, 23, 0, 19, 29, 32, 140, + 71, 86, 84, 0, 93, 95, 0, 145, 0, 148, + 77, 89, 91, 136, 0, 54, 25, 94, 88, 77, + 96, 146 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 36, 37, 90, 39, 180, 40, 125, 186, 41, + 42, 43, 129, 44, 45, 46, 134, 200, 201, 202, + 203, 227, 64, 49, 69, 228, 50, 51, 52, 195, + 53 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -101 +static const short yypact[] = +{ + 320, -101, -101, -101, -101, -101, -101, 30, 30, 30, + 30, 383, 45, 30, 30, 200, 152, 36, -101, -11, + 17, -101, -101, -101, -101, 320, 320, 320, 320, 320, + 320, 29, -101, 320, 320, -101, 84, -101, 39, 597, + 257, 56, -101, -101, 57, -101, 172, -101, 68, -101, + 55, -101, 67, -101, -101, -101, -101, -101, -101, -101, + -101, -101, 320, 460, 87, -101, 40, 95, -101, -101, + -101, 99, 190, -101, -101, 156, 159, 223, -101, -101, + 164, 176, -101, -101, -101, 460, 460, 460, 460, 460, + -15, 158, 460, 460, -101, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, -101, -101, + 194, 320, -101, 531, 597, -19, 160, 30, 218, -1, + 71, 20, -101, -101, -14, 171, 26, 215, -101, -101, + 172, 217, -101, -101, -101, 221, 224, -101, -101, -101, + -101, 320, 597, 597, 597, 560, 622, 646, 669, 691, + 712, 731, 731, 746, 746, 746, 746, 240, 240, 303, + 366, 366, 460, 460, 460, 83, 320, -101, -101, -18, + 257, 320, -101, -101, 320, -101, -101, 320, 231, -101, + -101, -101, 30, -101, 30, 210, 118, 63, 4, 472, + 2, 112, -101, -101, 446, -101, 206, 85, -101, -101, + -101, 460, 320, 460, -101, -13, 460, 597, 460, -101, + -101, -101, -101, 185, -101, -101, 186, -101, -9, -101, + 114, -101, -101, -101, 11, 526, -101, -101, -101, 172, + -101, -101 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short yypgoto[] = +{ + -101, -101, -101, 6, 47, -101, -101, 69, 126, -101, + -101, -67, -101, 125, -101, -35, 58, -100, -101, 54, + 73, 1, 0, -101, 241, -101, -101, -101, 128, -5, + -101 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -141 +static const short yytable[] = +{ + 48, 47, 58, 59, 60, 61, 38, 223, 70, 71, + 184, 95, 83, 132, 95, 133, 184, 54, 55, 56, + 239, 19, 20, 196, 19, 20, 54, 55, 56, 132, + 48, 91, 54, 55, 56, 197, 54, 55, 56, 84, + 48, 126, 198, 199, -66, 214, 130, 185, -77, 150, + 80, 236, 65, 177, 81, 240, 182, 82, 63, 137, + 193, 138, 48, 135, 66, 67, 68, 224, 95, 193, + 57, 127, 85, 86, 87, 88, 89, 19, 20, 57, + 92, 93, 194, 131, 94, 57, 192, 124, 194, 57, + 19, 20, -82, 19, 20, 132, 221, 222, -99, 226, + 234, -77, 136, 128, -82, -99, -99, 19, 20, 19, + 20, -82, -82, -76, -77, 178, 139, -77, 183, 198, + 199, 5, 188, 7, 8, 9, 10, 179, 12, -99, + 14, -77, 15, 16, 17, 18, 19, 20, 21, 140, + 207, 206, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 133, 75, 197, 198, 230, + 76, 77, 132, 78, 198, 199, 79, 143, 225, 5, + 144, 7, 8, 9, 10, 148, 12, 219, 14, 220, + 15, 16, 17, 18, 19, 20, 21, 149, 211, 207, + 54, 175, 56, 7, 8, 9, 10, 65, 12, 141, + 14, 142, 15, 16, 17, 18, 19, 20, 21, 72, + 73, 68, 151, 213, 189, -140, 185, 124, 216, 219, + 207, 217, -140, -140, 218, 204, 205, 145, 208, 207, + 241, 146, 209, 176, 147, 210, -68, 233, 237, 215, + 238, 211, 187, 57, 190, 231, 74, 191, 229, 235, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 232, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 23, 24, 112, 113, 114, 115, + 116, 117, 118, 119, 25, 120, 121, 122, 123, 0, + 0, 0, 0, -77, 0, 26, 27, 0, 0, 28, + 29, 0, 0, 0, 30, 0, 31, 32, 33, 34, + 0, 0, 35, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 0, 15, 16, + 17, 18, 19, 20, 21, 22, 0, 23, 24, 0, + 113, 114, 115, 116, 117, 118, 119, 25, 120, 121, + 122, 123, 0, 0, 0, 0, 0, 0, 26, 27, + 0, 0, 28, 29, 0, 0, 0, 30, 0, 31, + 32, 33, 34, 0, 0, 35, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 0, 15, 16, 17, 18, 19, 20, 21, 22, 0, + 23, 24, 0, 0, 0, 115, 116, 117, 118, 119, + 25, 120, 121, 122, 123, 0, 0, 0, 0, 0, + 0, 26, 27, 0, 0, 28, 29, 0, 0, 0, + 62, 0, 31, 32, 33, 34, 0, 0, 35, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 0, 15, 16, 17, 18, 19, 20, + 21, 22, 0, 23, 24, 0, 0, 0, 0, 5, + 0, 7, 8, 9, 10, 0, 12, 0, 14, 0, + 15, 16, 17, 18, 19, 20, 21, 0, 28, 29, + 0, 0, 0, 30, 0, 31, 32, 33, 34, 196, + 0, 35, 118, 119, 0, 120, 121, 122, 123, 0, + 0, 197, 0, 0, 0, 0, 0, 0, 198, 199, + 0, 0, 0, 0, 0, 0, 225, 54, 175, 56, + 7, 8, 9, 10, 0, 12, 0, 14, 0, 15, + 16, 17, 18, 19, 20, 21, 0, 0, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 181, 120, 121, 122, 123, 0, 96, 0, 0, 0, + 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 0, 120, 121, 122, 123, 0, + 0, 0, 0, 96, 0, 0, 0, 212, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 0, 120, 121, 122, 123, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 0, 120, 121, 122, + 123, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 0, 120, 121, 122, 123, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 0, 120, 121, 122, 123, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 0, 120, 121, 122, 123, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 0, 120, 121, 122, + 123, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 0, 120, 121, 122, 123, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 0, 120, 121, 122, 123 +}; + +static const short yycheck[] = +{ + 0, 0, 7, 8, 9, 10, 0, 3, 13, 14, + 29, 29, 23, 48, 29, 50, 29, 6, 7, 8, + 29, 22, 23, 37, 22, 23, 6, 7, 8, 64, + 30, 30, 6, 7, 8, 49, 6, 7, 8, 22, + 40, 40, 56, 57, 15, 63, 46, 66, 46, 64, + 14, 64, 7, 120, 18, 64, 123, 21, 11, 19, + 49, 21, 62, 62, 19, 20, 21, 63, 29, 49, + 59, 15, 25, 26, 27, 28, 29, 22, 23, 59, + 33, 34, 62, 15, 0, 59, 15, 40, 62, 59, + 22, 23, 37, 22, 23, 130, 196, 197, 15, 199, + 15, 46, 15, 46, 49, 22, 23, 22, 23, 22, + 23, 56, 57, 46, 46, 120, 21, 46, 123, 56, + 57, 7, 127, 9, 10, 11, 12, 121, 14, 46, + 16, 46, 18, 19, 20, 21, 22, 23, 24, 40, + 140, 140, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 200, 14, 49, 56, 57, + 18, 19, 207, 21, 56, 57, 24, 21, 64, 7, + 21, 9, 10, 11, 12, 21, 14, 192, 16, 194, + 18, 19, 20, 21, 22, 23, 24, 21, 151, 199, + 6, 7, 8, 9, 10, 11, 12, 7, 14, 19, + 16, 21, 18, 19, 20, 21, 22, 23, 24, 19, + 20, 21, 64, 176, 6, 15, 66, 180, 181, 234, + 230, 184, 22, 23, 187, 64, 21, 14, 21, 239, + 239, 18, 21, 49, 21, 21, 15, 41, 63, 180, + 64, 204, 126, 59, 129, 201, 15, 129, 200, 212, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 201, 18, 19, 20, 21, 22, + 23, 24, 25, -1, 27, 28, 46, 47, 48, 49, + 50, 51, 52, 53, 37, 55, 56, 57, 58, -1, + -1, -1, -1, 46, -1, 48, 49, -1, -1, 52, + 53, -1, -1, -1, 57, -1, 59, 60, 61, 62, + -1, -1, 65, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, -1, 18, 19, + 20, 21, 22, 23, 24, 25, -1, 27, 28, -1, + 47, 48, 49, 50, 51, 52, 53, 37, 55, 56, + 57, 58, -1, -1, -1, -1, -1, -1, 48, 49, + -1, -1, 52, 53, -1, -1, -1, 57, -1, 59, + 60, 61, 62, -1, -1, 65, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, + 27, 28, -1, -1, -1, 49, 50, 51, 52, 53, + 37, 55, 56, 57, 58, -1, -1, -1, -1, -1, + -1, 48, 49, -1, -1, 52, 53, -1, -1, -1, + 57, -1, 59, 60, 61, 62, -1, -1, 65, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, -1, 18, 19, 20, 21, 22, 23, + 24, 25, -1, 27, 28, -1, -1, -1, -1, 7, + -1, 9, 10, 11, 12, -1, 14, -1, 16, -1, + 18, 19, 20, 21, 22, 23, 24, -1, 52, 53, + -1, -1, -1, 57, -1, 59, 60, 61, 62, 37, + -1, 65, 52, 53, -1, 55, 56, 57, 58, -1, + -1, 49, -1, -1, -1, -1, -1, -1, 56, 57, + -1, -1, -1, -1, -1, -1, 64, 6, 7, 8, + 9, 10, 11, 12, -1, 14, -1, 16, -1, 18, + 19, 20, 21, 22, 23, 24, -1, -1, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 49, 55, 56, 57, 58, -1, 26, -1, -1, -1, + 59, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, -1, 55, 56, 57, 58, -1, + -1, -1, -1, 26, -1, -1, -1, 67, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, -1, 55, 56, 57, 58, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, -1, 55, 56, 57, + 58, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + -1, 55, 56, 57, 58, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, -1, 55, 56, 57, 58, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, -1, 55, 56, 57, 58, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, -1, 55, 56, 57, + 58, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, -1, 55, 56, 57, 58, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + -1, 55, 56, 57, 58 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, + 23, 24, 25, 27, 28, 37, 48, 49, 52, 53, + 57, 59, 60, 61, 62, 65, 69, 70, 71, 72, + 74, 77, 78, 79, 81, 82, 83, 89, 90, 91, + 94, 95, 96, 98, 6, 7, 8, 59, 97, 97, + 97, 97, 57, 72, 90, 7, 19, 20, 21, 92, + 97, 97, 19, 20, 92, 14, 18, 19, 21, 24, + 14, 18, 21, 23, 22, 72, 72, 72, 72, 72, + 71, 89, 72, 72, 0, 29, 26, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 55, 56, 57, 58, 72, 75, 89, 15, 46, 80, + 90, 15, 83, 83, 84, 89, 15, 19, 21, 21, + 40, 19, 21, 21, 21, 14, 18, 21, 21, 21, + 64, 64, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 7, 49, 79, 97, 71, + 73, 49, 79, 97, 29, 66, 76, 76, 97, 6, + 81, 96, 15, 49, 62, 97, 37, 49, 56, 57, + 85, 86, 87, 88, 64, 21, 89, 90, 21, 21, + 21, 72, 67, 72, 63, 75, 72, 72, 72, 97, + 97, 85, 85, 3, 63, 64, 85, 89, 93, 84, + 57, 87, 88, 41, 15, 72, 64, 63, 64, 29, + 64, 89 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to xreallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to xreallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: +#line 238 "c-exp.y" + { write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(yyvsp[0].tval); + write_exp_elt_opcode(OP_TYPE);} + break; + + case 6: +#line 246 "c-exp.y" + { write_exp_elt_opcode (BINOP_COMMA); } + break; + + case 7: +#line 251 "c-exp.y" + { write_exp_elt_opcode (UNOP_IND); } + break; + + case 8: +#line 255 "c-exp.y" + { write_exp_elt_opcode (UNOP_ADDR); } + break; + + case 9: +#line 259 "c-exp.y" + { write_exp_elt_opcode (UNOP_NEG); } + break; + + case 10: +#line 263 "c-exp.y" + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + break; + + case 11: +#line 267 "c-exp.y" + { write_exp_elt_opcode (UNOP_COMPLEMENT); } + break; + + case 12: +#line 271 "c-exp.y" + { write_exp_elt_opcode (UNOP_PREINCREMENT); } + break; + + case 13: +#line 275 "c-exp.y" + { write_exp_elt_opcode (UNOP_PREDECREMENT); } + break; + + case 14: +#line 279 "c-exp.y" + { write_exp_elt_opcode (UNOP_POSTINCREMENT); } + break; + + case 15: +#line 283 "c-exp.y" + { write_exp_elt_opcode (UNOP_POSTDECREMENT); } + break; + + case 16: +#line 287 "c-exp.y" + { write_exp_elt_opcode (UNOP_SIZEOF); } + break; + + case 17: +#line 291 "c-exp.y" + { write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (STRUCTOP_PTR); } + break; + + case 18: +#line 297 "c-exp.y" + { /* exp->type::name becomes exp->*(&type::name) */ + /* Note: this doesn't work if name is a + static member! FIXME */ + write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (STRUCTOP_MPTR); } + break; + + case 19: +#line 305 "c-exp.y" + { write_exp_elt_opcode (STRUCTOP_MPTR); } + break; + + case 20: +#line 309 "c-exp.y" + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (STRUCTOP_STRUCT); } + break; + + case 21: +#line 315 "c-exp.y" + { /* exp.type::name becomes exp.*(&type::name) */ + /* Note: this doesn't work if name is a + static member! FIXME */ + write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (STRUCTOP_MEMBER); } + break; + + case 22: +#line 323 "c-exp.y" + { write_exp_elt_opcode (STRUCTOP_MEMBER); } + break; + + case 23: +#line 327 "c-exp.y" + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + break; + + case 24: +#line 333 "c-exp.y" + { start_arglist (); } + break; + + case 25: +#line 335 "c-exp.y" + { write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) end_arglist ()); + write_exp_elt_opcode (OP_FUNCALL); } + break; + + case 26: +#line 341 "c-exp.y" + { start_arglist (); } + break; + + case 28: +#line 348 "c-exp.y" + { arglist_len = 1; } + break; + + case 29: +#line 352 "c-exp.y" + { arglist_len++; } + break; + + case 30: +#line 356 "c-exp.y" + { yyval.lval = end_arglist () - 1; } + break; + + case 31: +#line 359 "c-exp.y" + { write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_ARRAY); } + break; + + case 32: +#line 366 "c-exp.y" + { write_exp_elt_opcode (UNOP_MEMVAL); + write_exp_elt_type (yyvsp[-2].tval); + write_exp_elt_opcode (UNOP_MEMVAL); } + break; + + case 33: +#line 372 "c-exp.y" + { write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (yyvsp[-2].tval); + write_exp_elt_opcode (UNOP_CAST); } + break; + + case 34: +#line 378 "c-exp.y" + { } + break; + + case 35: +#line 384 "c-exp.y" + { write_exp_elt_opcode (BINOP_REPEAT); } + break; + + case 36: +#line 388 "c-exp.y" + { write_exp_elt_opcode (BINOP_MUL); } + break; + + case 37: +#line 392 "c-exp.y" + { write_exp_elt_opcode (BINOP_DIV); } + break; + + case 38: +#line 396 "c-exp.y" + { write_exp_elt_opcode (BINOP_REM); } + break; + + case 39: +#line 400 "c-exp.y" + { write_exp_elt_opcode (BINOP_ADD); } + break; + + case 40: +#line 404 "c-exp.y" + { write_exp_elt_opcode (BINOP_SUB); } + break; + + case 41: +#line 408 "c-exp.y" + { write_exp_elt_opcode (BINOP_LSH); } + break; + + case 42: +#line 412 "c-exp.y" + { write_exp_elt_opcode (BINOP_RSH); } + break; + + case 43: +#line 416 "c-exp.y" + { write_exp_elt_opcode (BINOP_EQUAL); } + break; + + case 44: +#line 420 "c-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 45: +#line 424 "c-exp.y" + { write_exp_elt_opcode (BINOP_LEQ); } + break; + + case 46: +#line 428 "c-exp.y" + { write_exp_elt_opcode (BINOP_GEQ); } + break; + + case 47: +#line 432 "c-exp.y" + { write_exp_elt_opcode (BINOP_LESS); } + break; + + case 48: +#line 436 "c-exp.y" + { write_exp_elt_opcode (BINOP_GTR); } + break; + + case 49: +#line 440 "c-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + break; + + case 50: +#line 444 "c-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + break; + + case 51: +#line 448 "c-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + break; + + case 52: +#line 452 "c-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + break; + + case 53: +#line 456 "c-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + break; + + case 54: +#line 460 "c-exp.y" + { write_exp_elt_opcode (TERNOP_COND); } + break; + + case 55: +#line 464 "c-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN); } + break; + + case 56: +#line 468 "c-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode (yyvsp[-1].opcode); + write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } + break; + + case 57: +#line 474 "c-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (yyvsp[0].typed_val_int.type); + write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 58: +#line 481 "c-exp.y" + { YYSTYPE val; + parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (val.typed_val_int.type); + write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 59: +#line 492 "c-exp.y" + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type (yyvsp[0].typed_val_float.type); + write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval); + write_exp_elt_opcode (OP_DOUBLE); } + break; + + case 62: +#line 506 "c-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + CHECK_TYPEDEF (yyvsp[-1].tval); + write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 63: +#line 514 "c-exp.y" + { /* C strings are converted into array constants with + an explicit null byte added at the end. Thus + the array upper bound is the string length. + There is no such thing in C as a completely empty + string. */ + char *sp = yyvsp[0].sval.ptr; int count = yyvsp[0].sval.length; + while (count-- > 0) + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)(*sp++)); + write_exp_elt_opcode (OP_LONG); + } + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)'\0'); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) (yyvsp[0].sval.length)); + write_exp_elt_opcode (OP_ARRAY); } + break; + + case 64: +#line 539 "c-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_bool); + write_exp_elt_longcst ((LONGEST) 1); + write_exp_elt_opcode (OP_LONG); } + break; + + case 65: +#line 546 "c-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_bool); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_opcode (OP_LONG); } + break; + + case 66: +#line 555 "c-exp.y" + { + if (yyvsp[0].ssym.sym) + yyval.bval = SYMBOL_BLOCK_VALUE (yyvsp[0].ssym.sym); + else + error ("No file or function \"%s\".", + copy_name (yyvsp[0].ssym.stoken)); + } + break; + + case 67: +#line 563 "c-exp.y" + { + yyval.bval = yyvsp[0].bval; + } + break; + + case 68: +#line 569 "c-exp.y" + { struct symbol *tem + = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) + error ("No function \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + yyval.bval = SYMBOL_BLOCK_VALUE (tem); } + break; + + case 69: +#line 580 "c-exp.y" + { struct symbol *sym; + sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym == 0) + error ("No symbol \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + + write_exp_elt_opcode (OP_VAR_VALUE); + /* block_found is set by lookup_symbol. */ + write_exp_elt_block (block_found); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); } + break; + + case 70: +#line 596 "c-exp.y" + { + struct type *type = yyvsp[-2].tval; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (type); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_SCOPE); + } + break; + + case 71: +#line 610 "c-exp.y" + { + struct type *type = yyvsp[-3].tval; + struct stoken tmp_token; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + tmp_token.ptr = (char*) alloca (yyvsp[0].sval.length + 2); + tmp_token.length = yyvsp[0].sval.length + 1; + tmp_token.ptr[0] = '~'; + memcpy (tmp_token.ptr+1, yyvsp[0].sval.ptr, yyvsp[0].sval.length); + tmp_token.ptr[tmp_token.length] = 0; + + /* Check for valid destructor name. */ + destructor_name_p (tmp_token.ptr, type); + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (type); + write_exp_string (tmp_token); + write_exp_elt_opcode (OP_SCOPE); + } + break; + + case 73: +#line 636 "c-exp.y" + { + char *name = copy_name (yyvsp[0].sval); + struct symbol *sym; + struct minimal_symbol *msymbol; + + sym = + lookup_symbol (name, (const struct block *) NULL, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym) + { + write_exp_elt_opcode (OP_VAR_VALUE); + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + break; + } + + msymbol = lookup_minimal_symbol (name, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", name); + } + break; + + case 74: +#line 670 "c-exp.y" + { struct symbol *sym = yyvsp[0].ssym.sym; + + if (sym) + { + if (symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block_found, + innermost_block)) + innermost_block = block_found; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not + another more inner frame which happens to + be in the same block. */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + } + else if (yyvsp[0].ssym.is_a_field_of_this) + { + /* C++: it hangs off of `this'. Must + not inadvertently convert from a method call + to data ref. */ + if (innermost_block == 0 || + contained_in (block_found, innermost_block)) + innermost_block = block_found; + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string (yyvsp[0].ssym.stoken); + write_exp_elt_opcode (STRUCTOP_PTR); + } + else + { + struct minimal_symbol *msymbol; + char *arg = copy_name (yyvsp[0].ssym.stoken); + + msymbol = + lookup_minimal_symbol (arg, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", + copy_name (yyvsp[0].ssym.stoken)); + } + } + break; + + case 75: +#line 727 "c-exp.y" + { push_type_address_space (copy_name (yyvsp[0].ssym.stoken)); + push_type (tp_space_identifier); + } + break; + + case 83: +#line 749 "c-exp.y" + { push_type (tp_pointer); yyval.voidval = 0; } + break; + + case 84: +#line 751 "c-exp.y" + { push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; } + break; + + case 85: +#line 753 "c-exp.y" + { push_type (tp_reference); yyval.voidval = 0; } + break; + + case 86: +#line 755 "c-exp.y" + { push_type (tp_reference); yyval.voidval = yyvsp[0].voidval; } + break; + + case 88: +#line 760 "c-exp.y" + { yyval.voidval = yyvsp[-1].voidval; } + break; + + case 89: +#line 762 "c-exp.y" + { + push_type_int (yyvsp[0].lval); + push_type (tp_array); + } + break; + + case 90: +#line 767 "c-exp.y" + { + push_type_int (yyvsp[0].lval); + push_type (tp_array); + yyval.voidval = 0; + } + break; + + case 91: +#line 774 "c-exp.y" + { push_type (tp_function); } + break; + + case 92: +#line 776 "c-exp.y" + { push_type (tp_function); } + break; + + case 93: +#line 780 "c-exp.y" + { yyval.lval = -1; } + break; + + case 94: +#line 782 "c-exp.y" + { yyval.lval = yyvsp[-1].typed_val_int.val; } + break; + + case 95: +#line 786 "c-exp.y" + { yyval.voidval = 0; } + break; + + case 96: +#line 788 "c-exp.y" + { free (yyvsp[-1].tvec); yyval.voidval = 0; } + break; + + case 98: +#line 801 "c-exp.y" + { yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); } + break; + + case 99: +#line 806 "c-exp.y" + { yyval.tval = yyvsp[0].tsym.type; } + break; + + case 100: +#line 808 "c-exp.y" + { yyval.tval = builtin_type_int; } + break; + + case 101: +#line 810 "c-exp.y" + { yyval.tval = builtin_type_long; } + break; + + case 102: +#line 812 "c-exp.y" + { yyval.tval = builtin_type_short; } + break; + + case 103: +#line 814 "c-exp.y" + { yyval.tval = builtin_type_long; } + break; + + case 104: +#line 816 "c-exp.y" + { yyval.tval = builtin_type_long; } + break; + + case 105: +#line 818 "c-exp.y" + { yyval.tval = builtin_type_long; } + break; + + case 106: +#line 820 "c-exp.y" + { yyval.tval = builtin_type_long; } + break; + + case 107: +#line 822 "c-exp.y" + { yyval.tval = builtin_type_unsigned_long; } + break; + + case 108: +#line 824 "c-exp.y" + { yyval.tval = builtin_type_unsigned_long; } + break; + + case 109: +#line 826 "c-exp.y" + { yyval.tval = builtin_type_unsigned_long; } + break; + + case 110: +#line 828 "c-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 111: +#line 830 "c-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 112: +#line 832 "c-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 113: +#line 834 "c-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 114: +#line 836 "c-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 115: +#line 838 "c-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 116: +#line 840 "c-exp.y" + { yyval.tval = builtin_type_unsigned_long_long; } + break; + + case 117: +#line 842 "c-exp.y" + { yyval.tval = builtin_type_unsigned_long_long; } + break; + + case 118: +#line 844 "c-exp.y" + { yyval.tval = builtin_type_unsigned_long_long; } + break; + + case 119: +#line 846 "c-exp.y" + { yyval.tval = builtin_type_unsigned_long_long; } + break; + + case 120: +#line 848 "c-exp.y" + { yyval.tval = builtin_type_short; } + break; + + case 121: +#line 850 "c-exp.y" + { yyval.tval = builtin_type_short; } + break; + + case 122: +#line 852 "c-exp.y" + { yyval.tval = builtin_type_short; } + break; + + case 123: +#line 854 "c-exp.y" + { yyval.tval = builtin_type_unsigned_short; } + break; + + case 124: +#line 856 "c-exp.y" + { yyval.tval = builtin_type_unsigned_short; } + break; + + case 125: +#line 858 "c-exp.y" + { yyval.tval = builtin_type_unsigned_short; } + break; + + case 126: +#line 860 "c-exp.y" + { yyval.tval = builtin_type_double; } + break; + + case 127: +#line 862 "c-exp.y" + { yyval.tval = builtin_type_long_double; } + break; + + case 128: +#line 864 "c-exp.y" + { yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 129: +#line 867 "c-exp.y" + { yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 130: +#line 870 "c-exp.y" + { yyval.tval = lookup_union (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 131: +#line 873 "c-exp.y" + { yyval.tval = lookup_enum (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 132: +#line 876 "c-exp.y" + { yyval.tval = lookup_unsigned_typename (TYPE_NAME(yyvsp[0].tsym.type)); } + break; + + case 133: +#line 878 "c-exp.y" + { yyval.tval = builtin_type_unsigned_int; } + break; + + case 134: +#line 880 "c-exp.y" + { yyval.tval = lookup_signed_typename (TYPE_NAME(yyvsp[0].tsym.type)); } + break; + + case 135: +#line 882 "c-exp.y" + { yyval.tval = builtin_type_int; } + break; + + case 136: +#line 887 "c-exp.y" + { yyval.tval = lookup_template_type(copy_name(yyvsp[-3].sval), yyvsp[-1].tval, + expression_context_block); + } + break; + + case 137: +#line 891 "c-exp.y" + { yyval.tval = follow_types (yyvsp[0].tval); } + break; + + case 138: +#line 893 "c-exp.y" + { yyval.tval = follow_types (yyvsp[-1].tval); } + break; + + case 140: +#line 943 "c-exp.y" + { + struct type *type = yyvsp[-2].tval; + struct type *new_type; + char *ncopy = alloca (yyvsp[0].sval.length + 1); + + memcpy (ncopy, yyvsp[0].sval.ptr, yyvsp[0].sval.length); + ncopy[yyvsp[0].sval.length] = '\0'; + + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + new_type = cp_lookup_nested_type (type, ncopy, + expression_context_block); + if (new_type == NULL) + error ("No type \"%s\" within class or namespace \"%s\".", + ncopy, TYPE_NAME (type)); + + yyval.tval = new_type; + } + break; + + case 142: +#line 969 "c-exp.y" + { + yyval.tsym.stoken.ptr = "int"; + yyval.tsym.stoken.length = 3; + yyval.tsym.type = builtin_type_int; + } + break; + + case 143: +#line 975 "c-exp.y" + { + yyval.tsym.stoken.ptr = "long"; + yyval.tsym.stoken.length = 4; + yyval.tsym.type = builtin_type_long; + } + break; + + case 144: +#line 981 "c-exp.y" + { + yyval.tsym.stoken.ptr = "short"; + yyval.tsym.stoken.length = 5; + yyval.tsym.type = builtin_type_short; + } + break; + + case 145: +#line 990 "c-exp.y" + { yyval.tvec = (struct type **) xmalloc (sizeof (struct type *) * 2); + yyval.ivec[0] = 1; /* Number of types in vector */ + yyval.tvec[1] = yyvsp[0].tval; + } + break; + + case 146: +#line 995 "c-exp.y" + { int len = sizeof (struct type *) * (++(yyvsp[-2].ivec[0]) + 1); + yyval.tvec = (struct type **) xrealloc ((char *) yyvsp[-2].tvec, len); + yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval; + } + break; + + case 148: +#line 1003 "c-exp.y" + { yyval.tval = follow_types (yyvsp[-3].tval); } + break; + + case 151: +#line 1011 "c-exp.y" + { push_type (tp_const); + push_type (tp_volatile); + } + break; + + case 152: +#line 1015 "c-exp.y" + { push_type (tp_const); } + break; + + case 153: +#line 1017 "c-exp.y" + { push_type (tp_volatile); } + break; + + case 154: +#line 1020 "c-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + case 155: +#line 1021 "c-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + case 156: +#line 1022 "c-exp.y" + { yyval.sval = yyvsp[0].tsym.stoken; } + break; + + case 157: +#line 1023 "c-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + + } + +/* Line 991 of yacc.c. */ + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. Doesn't work in C++ */ +#ifndef __cplusplus +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 1037 "c-exp.y" + + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. + LEN is the number of characters in it. */ + +/*** Needs some error checking for the float case ***/ + +static int +parse_number (p, len, parsed_float, putithere) + char *p; + int len; + int parsed_float; + YYSTYPE *putithere; +{ + /* FIXME: Shouldn't these be unsigned? We don't deal with negative values + here, and we do kind of silly things like cast to unsigned. */ + LONGEST n = 0; + LONGEST prevn = 0; + ULONGEST un; + + int i = 0; + int c; + int base = input_radix; + int unsigned_p = 0; + + /* Number of "L" suffixes encountered. */ + int long_p = 0; + + /* We have found a "L" or "U" suffix. */ + int found_suffix = 0; + + ULONGEST high_bit; + struct type *signed_type; + struct type *unsigned_type; + + if (parsed_float) + { + /* It's a float since it contains a point or an exponent. */ + char c; + int num = 0; /* number of tokens scanned by scanf */ + char saved_char = p[len]; + + p[len] = 0; /* null-terminate the token */ + if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) + num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c); + else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) + num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c); + else + { +#ifdef SCANF_HAS_LONG_DOUBLE + num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c); +#else + /* Scan it into a double, then assign it to the long double. + This at least wins with values representable in the range + of doubles. */ + double temp; + num = sscanf (p, "%lg%c", &temp,&c); + putithere->typed_val_float.dval = temp; +#endif + } + p[len] = saved_char; /* restore the input stream */ + if (num != 1) /* check scanf found ONLY a float ... */ + return ERROR; + /* See if it has `f' or `l' suffix (float or long double). */ + + c = tolower (p[len - 1]); + + if (c == 'f') + putithere->typed_val_float.type = builtin_type_float; + else if (c == 'l') + putithere->typed_val_float.type = builtin_type_long_double; + else if (isdigit (c) || c == '.') + putithere->typed_val_float.type = builtin_type_double; + else + return ERROR; + + return FLOAT; + } + + /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ + if (p[0] == '0') + switch (p[1]) + { + case 'x': + case 'X': + if (len >= 3) + { + p += 2; + base = 16; + len -= 2; + } + break; + + case 't': + case 'T': + case 'd': + case 'D': + if (len >= 3) + { + p += 2; + base = 10; + len -= 2; + } + break; + + default: + base = 8; + break; + } + + while (len-- > 0) + { + c = *p++; + if (c >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != 'l' && c != 'u') + n *= base; + if (c >= '0' && c <= '9') + { + if (found_suffix) + return ERROR; + n += i = c - '0'; + } + else + { + if (base > 10 && c >= 'a' && c <= 'f') + { + if (found_suffix) + return ERROR; + n += i = c - 'a' + 10; + } + else if (c == 'l') + { + ++long_p; + found_suffix = 1; + } + else if (c == 'u') + { + unsigned_p = 1; + found_suffix = 1; + } + else + return ERROR; /* Char not a digit */ + } + if (i >= base) + return ERROR; /* Invalid digit in this base */ + + /* Portably test for overflow (only works for nonzero values, so make + a second check for zero). FIXME: Can't we just make n and prevn + unsigned and avoid this? */ + if (c != 'l' && c != 'u' && (prevn >= n) && n != 0) + unsigned_p = 1; /* Try something unsigned */ + + /* Portably test for unsigned overflow. + FIXME: This check is wrong; for example it doesn't find overflow + on 0x123456789 when LONGEST is 32 bits. */ + if (c != 'l' && c != 'u' && n != 0) + { + if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n)) + error ("Numeric constant too large."); + } + prevn = n; + } + + /* An integer constant is an int, a long, or a long long. An L + suffix forces it to be long; an LL suffix forces it to be long + long. If not forced to a larger size, it gets the first type of + the above that it fits in. To figure out whether it fits, we + shift it right and see whether anything remains. Note that we + can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one + operation, because many compilers will warn about such a shift + (which always produces a zero result). Sometimes TARGET_INT_BIT + or TARGET_LONG_BIT will be that big, sometimes not. To deal with + the case where it is we just always shift the value more than + once, with fewer bits each time. */ + + un = (ULONGEST)n >> 2; + if (long_p == 0 + && (un >> (TARGET_INT_BIT - 2)) == 0) + { + high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1); + + /* A large decimal (not hex or octal) constant (between INT_MAX + and UINT_MAX) is a long or unsigned long, according to ANSI, + never an unsigned int, but this code treats it as unsigned + int. This probably should be fixed. GCC gives a warning on + such constants. */ + + unsigned_type = builtin_type_unsigned_int; + signed_type = builtin_type_int; + } + else if (long_p <= 1 + && (un >> (TARGET_LONG_BIT - 2)) == 0) + { + high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1); + unsigned_type = builtin_type_unsigned_long; + signed_type = builtin_type_long; + } + else + { + int shift; + if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT) + /* A long long does not fit in a LONGEST. */ + shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1); + else + shift = (TARGET_LONG_LONG_BIT - 1); + high_bit = (ULONGEST) 1 << shift; + unsigned_type = builtin_type_unsigned_long_long; + signed_type = builtin_type_long_long; + } + + putithere->typed_val_int.val = n; + + /* If the high bit of the worked out type is set then this number + has to be unsigned. */ + + if (unsigned_p || (n & high_bit)) + { + putithere->typed_val_int.type = unsigned_type; + } + else + { + putithere->typed_val_int.type = signed_type; + } + + return INT; +} + +struct token +{ + char *operator; + int token; + enum exp_opcode opcode; +}; + +static const struct token tokentab3[] = + { + {">>=", ASSIGN_MODIFY, BINOP_RSH}, + {"<<=", ASSIGN_MODIFY, BINOP_LSH} + }; + +static const struct token tokentab2[] = + { + {"+=", ASSIGN_MODIFY, BINOP_ADD}, + {"-=", ASSIGN_MODIFY, BINOP_SUB}, + {"*=", ASSIGN_MODIFY, BINOP_MUL}, + {"/=", ASSIGN_MODIFY, BINOP_DIV}, + {"%=", ASSIGN_MODIFY, BINOP_REM}, + {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR}, + {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND}, + {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR}, + {"++", INCREMENT, BINOP_END}, + {"--", DECREMENT, BINOP_END}, + {"->", ARROW, BINOP_END}, + {"&&", ANDAND, BINOP_END}, + {"||", OROR, BINOP_END}, + {"::", COLONCOLON, BINOP_END}, + {"<<", LSH, BINOP_END}, + {">>", RSH, BINOP_END}, + {"==", EQUAL, BINOP_END}, + {"!=", NOTEQUAL, BINOP_END}, + {"<=", LEQ, BINOP_END}, + {">=", GEQ, BINOP_END} + }; + +/* Read one token, getting characters through lexptr. */ + +static int +yylex () +{ + int c; + int namelen; + unsigned int i; + char *tokstart; + char *tokptr; + int tempbufindex; + static char *tempbuf; + static int tempbufsize; + struct symbol * sym_class = NULL; + char * token_string = NULL; + int class_prefix = 0; + int unquoted_expr; + + retry: + + /* Check if this is a macro invocation that we need to expand. */ + if (! scanning_macro_expansion ()) + { + char *expanded = macro_expand_next (&lexptr, + expression_macro_lookup_func, + expression_macro_lookup_baton); + + if (expanded) + scan_macro_expansion (expanded); + } + + prev_lexptr = lexptr; + unquoted_expr = 1; + + tokstart = lexptr; + /* See if it is a special token of length 3. */ + for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) + if (strncmp (tokstart, tokentab3[i].operator, 3) == 0) + { + lexptr += 3; + yylval.opcode = tokentab3[i].opcode; + return tokentab3[i].token; + } + + /* See if it is a special token of length 2. */ + for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) + if (strncmp (tokstart, tokentab2[i].operator, 2) == 0) + { + lexptr += 2; + yylval.opcode = tokentab2[i].opcode; + return tokentab2[i].token; + } + + switch (c = *tokstart) + { + case 0: + /* If we were just scanning the result of a macro expansion, + then we need to resume scanning the original text. + Otherwise, we were already scanning the original text, and + we're really done. */ + if (scanning_macro_expansion ()) + { + finished_macro_expansion (); + goto retry; + } + else + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '\'': + /* We either have a character constant ('0' or '\177' for example) + or we have a quoted symbol reference ('foo(int,int)' in C++ + for example). */ + lexptr++; + c = *lexptr++; + if (c == '\\') + c = parse_escape (&lexptr); + else if (c == '\'') + error ("Empty character constant."); + else if (! host_char_to_target (c, &c)) + { + int toklen = lexptr - tokstart + 1; + char *tok = alloca (toklen + 1); + memcpy (tok, tokstart, toklen); + tok[toklen] = '\0'; + error ("There is no character corresponding to %s in the target " + "character set `%s'.", tok, target_charset ()); + } + + yylval.typed_val_int.val = c; + yylval.typed_val_int.type = builtin_type_char; + + c = *lexptr++; + if (c != '\'') + { + namelen = skip_quoted (tokstart) - tokstart; + if (namelen > 2) + { + lexptr = tokstart + namelen; + unquoted_expr = 0; + if (lexptr[-1] != '\'') + error ("Unmatched single quote."); + namelen -= 2; + tokstart++; + goto tryname; + } + error ("Invalid character constant."); + } + return INT; + + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates + && paren_depth == 0 + && ! scanning_macro_expansion ()) + return 0; + lexptr++; + return c; + + case '.': + /* Might be a floating point number. */ + if (lexptr[1] < '0' || lexptr[1] > '9') + goto symbol; /* Nope, must be a symbol. */ + /* FALL THRU into number case. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + /* It's a number. */ + int got_dot = 0, got_e = 0, toktype; + char *p = tokstart; + int hex = input_radix > 10; + + if (c == '0' && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + hex = 1; + } + else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) + { + p += 2; + hex = 0; + } + + for (;; ++p) + { + /* This test includes !hex because 'e' is a valid hex digit + and thus does not indicate a floating point number when + the radix is hex. */ + if (!hex && !got_e && (*p == 'e' || *p == 'E')) + got_dot = got_e = 1; + /* This test does not include !hex, because a '.' always indicates + a decimal floating point number regardless of the radix. */ + else if (!got_dot && *p == '.') + got_dot = 1; + else if (got_e && (p[-1] == 'e' || p[-1] == 'E') + && (*p == '-' || *p == '+')) + /* This is the sign of the exponent, not the end of the + number. */ + continue; + /* We will take any letters or digits. parse_number will + complain if past the radix, or if L or U are not final. */ + else if ((*p < '0' || *p > '9') + && ((*p < 'a' || *p > 'z') + && (*p < 'A' || *p > 'Z'))) + break; + } + toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval); + if (toktype == ERROR) + { + char *err_copy = (char *) alloca (p - tokstart + 1); + + memcpy (err_copy, tokstart, p - tokstart); + err_copy[p - tokstart] = 0; + error ("Invalid number \"%s\".", err_copy); + } + lexptr = p; + return toktype; + } + + case '+': + case '-': + case '*': + case '/': + case '%': + case '|': + case '&': + case '^': + case '~': + case '!': + case '@': + case '<': + case '>': + case '[': + case ']': + case '?': + case ':': + case '=': + case '{': + case '}': + symbol: + lexptr++; + return c; + + case '"': + + /* Build the gdb internal form of the input string in tempbuf, + translating any standard C escape forms seen. Note that the + buffer is null byte terminated *only* for the convenience of + debugging gdb itself and printing the buffer contents when + the buffer contains no embedded nulls. Gdb does not depend + upon the buffer being null byte terminated, it uses the length + string instead. This allows gdb to handle C strings (as well + as strings in other languages) with embedded null bytes */ + + tokptr = ++tokstart; + tempbufindex = 0; + + do { + char *char_start_pos = tokptr; + + /* Grow the static temp buffer if necessary, including allocating + the first one on demand. */ + if (tempbufindex + 1 >= tempbufsize) + { + tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64); + } + switch (*tokptr) + { + case '\0': + case '"': + /* Do nothing, loop will terminate. */ + break; + case '\\': + tokptr++; + c = parse_escape (&tokptr); + if (c == -1) + { + continue; + } + tempbuf[tempbufindex++] = c; + break; + default: + c = *tokptr++; + if (! host_char_to_target (c, &c)) + { + int len = tokptr - char_start_pos; + char *copy = alloca (len + 1); + memcpy (copy, char_start_pos, len); + copy[len] = '\0'; + + error ("There is no character corresponding to `%s' " + "in the target character set `%s'.", + copy, target_charset ()); + } + tempbuf[tempbufindex++] = c; + break; + } + } while ((*tokptr != '"') && (*tokptr != '\0')); + if (*tokptr++ != '"') + { + error ("Unterminated string in expression."); + } + tempbuf[tempbufindex] = '\0'; /* See note above */ + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = tokptr; + return (STRING); + } + + if (!(c == '_' || c == '$' + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + /* We must have come across a bad character (e.g. ';'). */ + error ("Invalid character '%c' in expression.", c); + + /* It's a name. See how long it is. */ + namelen = 0; + for (c = tokstart[namelen]; + (c == '_' || c == '$' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) + { + /* Template parameter lists are part of the name. + FIXME: This mishandles `print $a<4&&$a>3'. */ + + if (c == '<') + { + /* Scan ahead to get rest of the template specification. Note + that we look ahead only when the '<' adjoins non-whitespace + characters; for comparison expressions, e.g. "a < b > c", + there must be spaces before the '<', etc. */ + + char * p = find_template_name_end (tokstart + namelen); + if (p) + namelen = p - tokstart; + break; + } + c = tokstart[++namelen]; + } + + /* The token "if" terminates the expression and is NOT removed from + the input stream. It doesn't count if it appears in the + expansion of a macro. */ + if (namelen == 2 + && tokstart[0] == 'i' + && tokstart[1] == 'f' + && ! scanning_macro_expansion ()) + { + return 0; + } + + lexptr += namelen; + + tryname: + + /* Catch specific keywords. Should be done with a data structure. */ + switch (namelen) + { + case 8: + if (strncmp (tokstart, "unsigned", 8) == 0) + return UNSIGNED; + if (current_language->la_language == language_cplus + && strncmp (tokstart, "template", 8) == 0) + return TEMPLATE; + if (strncmp (tokstart, "volatile", 8) == 0) + return VOLATILE_KEYWORD; + break; + case 6: + if (strncmp (tokstart, "struct", 6) == 0) + return STRUCT; + if (strncmp (tokstart, "signed", 6) == 0) + return SIGNED_KEYWORD; + if (strncmp (tokstart, "sizeof", 6) == 0) + return SIZEOF; + if (strncmp (tokstart, "double", 6) == 0) + return DOUBLE_KEYWORD; + break; + case 5: + if (current_language->la_language == language_cplus) + { + if (strncmp (tokstart, "false", 5) == 0) + return FALSEKEYWORD; + if (strncmp (tokstart, "class", 5) == 0) + return CLASS; + } + if (strncmp (tokstart, "union", 5) == 0) + return UNION; + if (strncmp (tokstart, "short", 5) == 0) + return SHORT; + if (strncmp (tokstart, "const", 5) == 0) + return CONST_KEYWORD; + break; + case 4: + if (strncmp (tokstart, "enum", 4) == 0) + return ENUM; + if (strncmp (tokstart, "long", 4) == 0) + return LONG; + if (current_language->la_language == language_cplus) + { + if (strncmp (tokstart, "true", 4) == 0) + return TRUEKEYWORD; + } + break; + case 3: + if (strncmp (tokstart, "int", 3) == 0) + return INT_KEYWORD; + break; + default: + break; + } + + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + if (*tokstart == '$') + { + write_dollar_variable (yylval.sval); + return VARIABLE; + } + + /* Look ahead and see if we can consume more of the input + string to get a reasonable class/namespace spec or a + fully-qualified name. This is a kludge to get around the + HP aCC compiler's generation of symbol names with embedded + colons for namespace and nested classes. */ + + /* NOTE: carlton/2003-09-24: I don't entirely understand the + HP-specific code, either here or in linespec. Having said that, + I suspect that we're actually moving towards their model: we want + symbols whose names are fully qualified, which matches the + description above. */ + if (unquoted_expr) + { + /* Only do it if not inside single quotes */ + sym_class = parse_nested_classes_for_hpacc (yylval.sval.ptr, yylval.sval.length, + &token_string, &class_prefix, &lexptr); + if (sym_class) + { + /* Replace the current token with the bigger one we found */ + yylval.sval.ptr = token_string; + yylval.sval.length = strlen (token_string); + } + } + + /* Use token-type BLOCKNAME for symbols that happen to be defined as + functions or symtabs. If this is not so, then ... + Use token-type TYPENAME for symbols that happen to be defined + currently as names of types; NAME for other symbols. + The caller is not constrained to care about the distinction. */ + { + char *tmp = copy_name (yylval.sval); + struct symbol *sym; + int is_a_field_of_this = 0; + int hextype; + + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + current_language->la_language == language_cplus + ? &is_a_field_of_this : (int *) NULL, + (struct symtab **) NULL); + /* Call lookup_symtab, not lookup_partial_symtab, in case there are + no psymtabs (coff, xcoff, or some future change to blow away the + psymtabs once once symbols are read). */ + if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return BLOCKNAME; + } + else if (!sym) + { /* See if it's a file name. */ + struct symtab *symtab; + + symtab = lookup_symtab (tmp); + + if (symtab) + { + yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); + return FILENAME; + } + } + + if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + { + /* NOTE: carlton/2003-09-25: There used to be code here to + handle nested types. It didn't work very well. See the + comment before qualified_type for more info. */ + yylval.tsym.type = SYMBOL_TYPE (sym); + return TYPENAME; + } + if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) + return TYPENAME; + + /* Input names that aren't symbols but ARE valid hex numbers, + when the input radix permits them, can be names or numbers + depending on the parse. Note we support radixes > 16 here. */ + if (!sym && + ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || + (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) + { + YYSTYPE newlval; /* Its value is ignored. */ + hextype = parse_number (tokstart, namelen, 0, &newlval); + if (hextype == INT) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME_OR_INT; + } + } + + /* Any other kind of symbol */ + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME; + } +} + +void +yyerror (msg) + char *msg; +{ + if (prev_lexptr) + lexptr = prev_lexptr; + + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); +} + + diff --git a/contrib/gdb/gdb/c-exp.y b/contrib/gdb/gdb/c-exp.y index 3d2d1aa661f..f11b93e3a2b 100644 --- a/contrib/gdb/gdb/c-exp.y +++ b/contrib/gdb/gdb/c-exp.y @@ -1,6 +1,6 @@ /* YACC parser for C expressions, for GDB. Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000 + 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -49,6 +49,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" /* Required by objfiles.h. */ #include "symfile.h" /* Required by objfiles.h. */ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "charset.h" +#include "block.h" +#include "cp-support.h" /* Flag indicating we're dealing with HP-compiled objects */ extern int hp_som_som_object_present; @@ -89,6 +92,8 @@ extern int hp_som_som_object_present; #define yylloc c_lloc #define yyreds c_reds /* With YYDEBUG defined */ #define yytoks c_toks /* With YYDEBUG defined */ +#define yyname c_name /* With YYDEBUG defined */ +#define yyrule c_rule /* With YYDEBUG defined */ #define yylhs c_yylhs #define yylen c_yylen #define yydefred c_yydefred @@ -100,9 +105,11 @@ extern int hp_som_som_object_present; #define yycheck c_yycheck #ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ +#define YYDEBUG 1 /* Default to yydebug support */ #endif +#define YYFPRINTF parser_fprintf + int yyparse (void); static int yylex (void); @@ -147,7 +154,7 @@ static int parse_number (char *, int, int, YYSTYPE *); %type exp exp1 type_exp start variable qualified_name lcurly %type rcurly -%type type typebase +%type type typebase qualified_type %type nonempty_typelist /* %type block */ @@ -194,7 +201,6 @@ static int parse_number (char *, int, int, YYSTYPE *); %token ASSIGN_MODIFY /* C++ */ -%token THIS %token TRUEKEYWORD %token FALSEKEYWORD @@ -243,9 +249,11 @@ exp1 : exp /* Expressions, not including the comma operator. */ exp : '*' exp %prec UNARY { write_exp_elt_opcode (UNOP_IND); } + ; exp : '&' exp %prec UNARY { write_exp_elt_opcode (UNOP_ADDR); } + ; exp : '-' exp %prec UNARY { write_exp_elt_opcode (UNOP_NEG); } @@ -527,11 +535,6 @@ exp : STRING ; /* C++. */ -exp : THIS - { write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); } - ; - exp : TRUEKEYWORD { write_exp_elt_opcode (OP_LONG); write_exp_elt_type (builtin_type_bool); @@ -565,7 +568,7 @@ block : BLOCKNAME block : block COLONCOLON name { struct symbol *tem = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) error ("No function \"%s\" in specified context.", @@ -576,7 +579,7 @@ block : block COLONCOLON name variable: block COLONCOLON name { struct symbol *sym; sym = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (sym == 0) error ("No symbol \"%s\" in specified context.", @@ -593,7 +596,8 @@ qualified_name: typebase COLONCOLON name { struct type *type = $1; if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) error ("`%s' is not defined as an aggregate type.", TYPE_NAME (type)); @@ -607,7 +611,8 @@ qualified_name: typebase COLONCOLON name struct type *type = $1; struct stoken tmp_token; if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) error ("`%s' is not defined as an aggregate type.", TYPE_NAME (type)); @@ -635,7 +640,7 @@ variable: qualified_name sym = lookup_symbol (name, (const struct block *) NULL, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (sym) { @@ -699,7 +704,7 @@ variable: name_not_typename else { struct minimal_symbol *msymbol; - register char *arg = copy_name ($1.stoken); + char *arg = copy_name ($1.stoken); msymbol = lookup_minimal_symbol (arg, NULL, NULL); @@ -780,7 +785,7 @@ array_mod: '[' ']' func_mod: '(' ')' { $$ = 0; } | '(' nonempty_typelist ')' - { free ((PTR)$2); $$ = 0; } + { free ($2); $$ = 0; } ; /* We used to try to recognize more pointer to member types here, but @@ -807,24 +812,50 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = builtin_type_short; } | LONG INT_KEYWORD { $$ = builtin_type_long; } + | LONG SIGNED_KEYWORD INT_KEYWORD + { $$ = builtin_type_long; } + | LONG SIGNED_KEYWORD + { $$ = builtin_type_long; } + | SIGNED_KEYWORD LONG INT_KEYWORD + { $$ = builtin_type_long; } | UNSIGNED LONG INT_KEYWORD { $$ = builtin_type_unsigned_long; } + | LONG UNSIGNED INT_KEYWORD + { $$ = builtin_type_unsigned_long; } + | LONG UNSIGNED + { $$ = builtin_type_unsigned_long; } | LONG LONG { $$ = builtin_type_long_long; } | LONG LONG INT_KEYWORD { $$ = builtin_type_long_long; } + | LONG LONG SIGNED_KEYWORD INT_KEYWORD + { $$ = builtin_type_long_long; } + | LONG LONG SIGNED_KEYWORD + { $$ = builtin_type_long_long; } + | SIGNED_KEYWORD LONG LONG + { $$ = builtin_type_long_long; } + | SIGNED_KEYWORD LONG LONG INT_KEYWORD + { $$ = builtin_type_long_long; } | UNSIGNED LONG LONG { $$ = builtin_type_unsigned_long_long; } | UNSIGNED LONG LONG INT_KEYWORD { $$ = builtin_type_unsigned_long_long; } - | SIGNED_KEYWORD LONG LONG - { $$ = lookup_signed_typename ("long long"); } - | SIGNED_KEYWORD LONG LONG INT_KEYWORD - { $$ = lookup_signed_typename ("long long"); } + | LONG LONG UNSIGNED + { $$ = builtin_type_unsigned_long_long; } + | LONG LONG UNSIGNED INT_KEYWORD + { $$ = builtin_type_unsigned_long_long; } | SHORT INT_KEYWORD { $$ = builtin_type_short; } + | SHORT SIGNED_KEYWORD INT_KEYWORD + { $$ = builtin_type_short; } + | SHORT SIGNED_KEYWORD + { $$ = builtin_type_short; } | UNSIGNED SHORT INT_KEYWORD { $$ = builtin_type_unsigned_short; } + | SHORT UNSIGNED + { $$ = builtin_type_unsigned_short; } + | SHORT UNSIGNED INT_KEYWORD + { $$ = builtin_type_unsigned_short; } | DOUBLE_KEYWORD { $$ = builtin_type_double; } | LONG DOUBLE_KEYWORD @@ -860,6 +891,77 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = follow_types ($2); } | typebase const_or_volatile_or_space_identifier_noopt { $$ = follow_types ($1); } + | qualified_type + ; + +/* FIXME: carlton/2003-09-25: This next bit leads to lots of + reduce-reduce conflicts, because the parser doesn't know whether or + not to use qualified_name or qualified_type: the rules are + identical. If the parser is parsing 'A::B::x', then, when it sees + the second '::', it knows that the expression to the left of it has + to be a type, so it uses qualified_type. But if it is parsing just + 'A::B', then it doesn't have any way of knowing which rule to use, + so there's a reduce-reduce conflict; it picks qualified_name, since + that occurs earlier in this file than qualified_type. + + There's no good way to fix this with the grammar as it stands; as + far as I can tell, some of the problems arise from ambiguities that + GDB introduces ('start' can be either an expression or a type), but + some of it is inherent to the nature of C++ (you want to treat the + input "(FOO)" fairly differently depending on whether FOO is an + expression or a type, and if FOO is a complex expression, this can + be hard to determine at the right time). Fortunately, it works + pretty well in most cases. For example, if you do 'ptype A::B', + where A::B is a nested type, then the parser will mistakenly + misidentify it as an expression; but evaluate_subexp will get + called with 'noside' set to EVAL_AVOID_SIDE_EFFECTS, and everything + will work out anyways. But there are situations where the parser + will get confused: the most common one that I've run into is when + you want to do + + print *((A::B *) x)" + + where the parser doesn't realize that A::B has to be a type until + it hits the first right paren, at which point it's too late. (The + workaround is to type "print *(('A::B' *) x)" instead.) (And + another solution is to fix our symbol-handling code so that the + user never wants to type something like that in the first place, + because we get all the types right without the user's help!) + + Perhaps we could fix this by making the lexer smarter. Some of + this functionality used to be in the lexer, but in a way that + worked even less well than the current solution: that attempt + involved having the parser sometimes handle '::' and having the + lexer sometimes handle it, and without a clear division of + responsibility, it quickly degenerated into a big mess. Probably + the eventual correct solution will give more of a role to the lexer + (ideally via code that is shared between the lexer and + decode_line_1), but I'm not holding my breath waiting for somebody + to get around to cleaning this up... */ + +qualified_type: typebase COLONCOLON name + { + struct type *type = $1; + struct type *new_type; + char *ncopy = alloca ($3.length + 1); + + memcpy (ncopy, $3.ptr, $3.length); + ncopy[$3.length] = '\0'; + + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + new_type = cp_lookup_nested_type (type, ncopy, + expression_context_block); + if (new_type == NULL) + error ("No type \"%s\" within class or namespace \"%s\".", + ncopy, TYPE_NAME (type)); + + $$ = new_type; + } ; typename: TYPENAME @@ -942,20 +1044,20 @@ name_not_typename : NAME static int parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; + char *p; + int len; int parsed_float; YYSTYPE *putithere; { /* FIXME: Shouldn't these be unsigned? We don't deal with negative values here, and we do kind of silly things like cast to unsigned. */ - register LONGEST n = 0; - register LONGEST prevn = 0; + LONGEST n = 0; + LONGEST prevn = 0; ULONGEST un; - register int i = 0; - register int c; - register int base = input_radix; + int i = 0; + int c; + int base = input_radix; int unsigned_p = 0; /* Number of "L" suffixes encountered. */ @@ -1218,12 +1320,24 @@ yylex () retry: + /* Check if this is a macro invocation that we need to expand. */ + if (! scanning_macro_expansion ()) + { + char *expanded = macro_expand_next (&lexptr, + expression_macro_lookup_func, + expression_macro_lookup_baton); + + if (expanded) + scan_macro_expansion (expanded); + } + + prev_lexptr = lexptr; unquoted_expr = 1; tokstart = lexptr; /* See if it is a special token of length 3. */ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) - if (STREQN (tokstart, tokentab3[i].operator, 3)) + if (strncmp (tokstart, tokentab3[i].operator, 3) == 0) { lexptr += 3; yylval.opcode = tokentab3[i].opcode; @@ -1232,7 +1346,7 @@ yylex () /* See if it is a special token of length 2. */ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) - if (STREQN (tokstart, tokentab2[i].operator, 2)) + if (strncmp (tokstart, tokentab2[i].operator, 2) == 0) { lexptr += 2; yylval.opcode = tokentab2[i].opcode; @@ -1242,7 +1356,17 @@ yylex () switch (c = *tokstart) { case 0: - return 0; + /* If we were just scanning the result of a macro expansion, + then we need to resume scanning the original text. + Otherwise, we were already scanning the original text, and + we're really done. */ + if (scanning_macro_expansion ()) + { + finished_macro_expansion (); + goto retry; + } + else + return 0; case ' ': case '\t': @@ -1260,6 +1384,15 @@ yylex () c = parse_escape (&lexptr); else if (c == '\'') error ("Empty character constant."); + else if (! host_char_to_target (c, &c)) + { + int toklen = lexptr - tokstart + 1; + char *tok = alloca (toklen + 1); + memcpy (tok, tokstart, toklen); + tok[toklen] = '\0'; + error ("There is no character corresponding to %s in the target " + "character set `%s'.", tok, target_charset ()); + } yylval.typed_val_int.val = c; yylval.typed_val_int.type = builtin_type_char; @@ -1295,7 +1428,9 @@ yylex () return c; case ',': - if (comma_terminates && paren_depth == 0) + if (comma_terminates + && paren_depth == 0 + && ! scanning_macro_expansion ()) return 0; lexptr++; return c; @@ -1319,7 +1454,7 @@ yylex () { /* It's a number. */ int got_dot = 0, got_e = 0, toktype; - register char *p = tokstart; + char *p = tokstart; int hex = input_radix > 10; if (c == '0' && (p[1] == 'x' || p[1] == 'X')) @@ -1408,6 +1543,8 @@ yylex () tempbufindex = 0; do { + char *char_start_pos = tokptr; + /* Grow the static temp buffer if necessary, including allocating the first one on demand. */ if (tempbufindex + 1 >= tempbufsize) @@ -1430,7 +1567,19 @@ yylex () tempbuf[tempbufindex++] = c; break; default: - tempbuf[tempbufindex++] = *tokptr++; + c = *tokptr++; + if (! host_char_to_target (c, &c)) + { + int len = tokptr - char_start_pos; + char *copy = alloca (len + 1); + memcpy (copy, char_start_pos, len); + copy[len] = '\0'; + + error ("There is no character corresponding to `%s' " + "in the target character set `%s'.", + copy, target_charset ()); + } + tempbuf[tempbufindex++] = c; break; } } while ((*tokptr != '"') && (*tokptr != '\0')); @@ -1474,9 +1623,13 @@ yylex () c = tokstart[++namelen]; } - /* The token "if" terminates the expression and is NOT - removed from the input stream. */ - if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') + /* The token "if" terminates the expression and is NOT removed from + the input stream. It doesn't count if it appears in the + expansion of a macro. */ + if (namelen == 2 + && tokstart[0] == 'i' + && tokstart[1] == 'f' + && ! scanning_macro_expansion ()) { return 0; } @@ -1489,63 +1642,52 @@ yylex () switch (namelen) { case 8: - if (STREQN (tokstart, "unsigned", 8)) + if (strncmp (tokstart, "unsigned", 8) == 0) return UNSIGNED; if (current_language->la_language == language_cplus - && STREQN (tokstart, "template", 8)) + && strncmp (tokstart, "template", 8) == 0) return TEMPLATE; - if (STREQN (tokstart, "volatile", 8)) + if (strncmp (tokstart, "volatile", 8) == 0) return VOLATILE_KEYWORD; break; case 6: - if (STREQN (tokstart, "struct", 6)) + if (strncmp (tokstart, "struct", 6) == 0) return STRUCT; - if (STREQN (tokstart, "signed", 6)) + if (strncmp (tokstart, "signed", 6) == 0) return SIGNED_KEYWORD; - if (STREQN (tokstart, "sizeof", 6)) + if (strncmp (tokstart, "sizeof", 6) == 0) return SIZEOF; - if (STREQN (tokstart, "double", 6)) + if (strncmp (tokstart, "double", 6) == 0) return DOUBLE_KEYWORD; break; case 5: if (current_language->la_language == language_cplus) { - if (STREQN (tokstart, "false", 5)) + if (strncmp (tokstart, "false", 5) == 0) return FALSEKEYWORD; - if (STREQN (tokstart, "class", 5)) + if (strncmp (tokstart, "class", 5) == 0) return CLASS; } - if (STREQN (tokstart, "union", 5)) + if (strncmp (tokstart, "union", 5) == 0) return UNION; - if (STREQN (tokstart, "short", 5)) + if (strncmp (tokstart, "short", 5) == 0) return SHORT; - if (STREQN (tokstart, "const", 5)) + if (strncmp (tokstart, "const", 5) == 0) return CONST_KEYWORD; break; case 4: - if (STREQN (tokstart, "enum", 4)) + if (strncmp (tokstart, "enum", 4) == 0) return ENUM; - if (STREQN (tokstart, "long", 4)) + if (strncmp (tokstart, "long", 4) == 0) return LONG; if (current_language->la_language == language_cplus) { - if (STREQN (tokstart, "true", 4)) + if (strncmp (tokstart, "true", 4) == 0) return TRUEKEYWORD; - - if (STREQN (tokstart, "this", 4)) - { - static const char this_name[] = - { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' }; - - if (lookup_symbol (this_name, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL)) - return THIS; - } } break; case 3: - if (STREQN (tokstart, "int", 3)) + if (strncmp (tokstart, "int", 3) == 0) return INT_KEYWORD; break; default: @@ -1565,7 +1707,13 @@ yylex () string to get a reasonable class/namespace spec or a fully-qualified name. This is a kludge to get around the HP aCC compiler's generation of symbol names with embedded - colons for namespace and nested classes. */ + colons for namespace and nested classes. */ + + /* NOTE: carlton/2003-09-24: I don't entirely understand the + HP-specific code, either here or in linespec. Having said that, + I suspect that we're actually moving towards their model: we want + symbols whose names are fully qualified, which matches the + description above. */ if (unquoted_expr) { /* Only do it if not inside single quotes */ @@ -1591,7 +1739,7 @@ yylex () int hextype; sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, + VAR_DOMAIN, current_language->la_language == language_cplus ? &is_a_field_of_this : (int *) NULL, (struct symtab **) NULL); @@ -1619,92 +1767,10 @@ yylex () if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) { -#if 1 - /* Despite the following flaw, we need to keep this code enabled. - Because we can get called from check_stub_method, if we don't - handle nested types then it screws many operations in any - program which uses nested types. */ - /* In "A::x", if x is a member function of A and there happens - to be a type (nested or not, since the stabs don't make that - distinction) named x, then this code incorrectly thinks we - are dealing with nested types rather than a member function. */ - - char *p; - char *namestart; - struct symbol *best_sym; - - /* Look ahead to detect nested types. This probably should be - done in the grammar, but trying seemed to introduce a lot - of shift/reduce and reduce/reduce conflicts. It's possible - that it could be done, though. Or perhaps a non-grammar, but - less ad hoc, approach would work well. */ - - /* Since we do not currently have any way of distinguishing - a nested type from a non-nested one (the stabs don't tell - us whether a type is nested), we just ignore the - containing type. */ - - p = lexptr; - best_sym = sym; - while (1) - { - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - if (*p == ':' && p[1] == ':') - { - /* Skip the `::'. */ - p += 2; - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - namestart = p; - while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9') - || (*p >= 'a' && *p <= 'z') - || (*p >= 'A' && *p <= 'Z')) - ++p; - if (p != namestart) - { - struct symbol *cur_sym; - /* As big as the whole rest of the expression, which is - at least big enough. */ - char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3); - char *tmp1; - - tmp1 = ncopy; - memcpy (tmp1, tmp, strlen (tmp)); - tmp1 += strlen (tmp); - memcpy (tmp1, "::", 2); - tmp1 += 2; - memcpy (tmp1, namestart, p - namestart); - tmp1[p - namestart] = '\0'; - cur_sym = lookup_symbol (ncopy, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (cur_sym) - { - if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) - { - best_sym = cur_sym; - lexptr = p; - } - else - break; - } - else - break; - } - else - break; - } - else - break; - } - - yylval.tsym.type = SYMBOL_TYPE (best_sym); -#else /* not 0 */ + /* NOTE: carlton/2003-09-25: There used to be code here to + handle nested types. It didn't work very well. See the + comment before qualified_type for more info. */ yylval.tsym.type = SYMBOL_TYPE (sym); -#endif /* not 0 */ return TYPENAME; } if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) @@ -1738,5 +1804,8 @@ void yyerror (msg) char *msg; { + if (prev_lexptr) + lexptr = prev_lexptr; + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); } diff --git a/contrib/gdb/gdb/c-lang.c b/contrib/gdb/gdb/c-lang.c index fa977cdd859..ba34540f386 100644 --- a/contrib/gdb/gdb/c-lang.c +++ b/contrib/gdb/gdb/c-lang.c @@ -1,5 +1,5 @@ /* C language support routines for GDB, the GNU debugger. - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002 + Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -27,6 +27,12 @@ #include "language.h" #include "c-lang.h" #include "valprint.h" +#include "macroscope.h" +#include "gdb_assert.h" +#include "charset.h" +#include "gdb_string.h" +#include "demangle.h" +#include "cp-support.h" extern void _initialize_c_language (void); static void c_emit_char (int c, struct ui_file * stream, int quoter); @@ -36,54 +42,32 @@ static void c_emit_char (int c, struct ui_file * stream, int quoter); characters and strings is language specific. */ static void -c_emit_char (register int c, struct ui_file *stream, int quoter) +c_emit_char (int c, struct ui_file *stream, int quoter) { + const char *escape; + int host_char; + c &= 0xFF; /* Avoid sign bit follies */ - if (PRINT_LITERAL_FORM (c)) + escape = c_target_char_has_backslash_escape (c); + if (escape) { - if (c == '\\' || c == quoter) - { - fputs_filtered ("\\", stream); - } - fprintf_filtered (stream, "%c", c); + if (quoter == '"' && strcmp (escape, "0") == 0) + /* Print nulls embedded in double quoted strings as \000 to + prevent ambiguity. */ + fprintf_filtered (stream, "\\000"); + else + fprintf_filtered (stream, "\\%s", escape); + } + else if (target_char_to_host (c, &host_char) + && host_char_print_literally (host_char)) + { + if (host_char == '\\' || host_char == quoter) + fputs_filtered ("\\", stream); + fprintf_filtered (stream, "%c", host_char); } else - { - switch (c) - { - case '\n': - fputs_filtered ("\\n", stream); - break; - case '\b': - fputs_filtered ("\\b", stream); - break; - case '\t': - fputs_filtered ("\\t", stream); - break; - case '\f': - fputs_filtered ("\\f", stream); - break; - case '\r': - fputs_filtered ("\\r", stream); - break; - case '\013': - fputs_filtered ("\\v", stream); - break; - case '\033': - fputs_filtered ("\\e", stream); - break; - case '\007': - fputs_filtered ("\\a", stream); - break; - case '\0': - fputs_filtered ("\\0", stream); - break; - default: - fprintf_filtered (stream, "\\%.3o", (unsigned int) c); - break; - } - } + fprintf_filtered (stream, "\\%.3o", (unsigned int) c); } void @@ -104,11 +88,10 @@ void c_printstr (struct ui_file *stream, char *string, unsigned int length, int width, int force_ellipses) { - register unsigned int i; + unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; - extern int inspect_it; /* If the string was not truncated due to `set print elements', and the last byte of it is a null, we don't print that, in traditional C @@ -224,7 +207,7 @@ c_printstr (struct ui_file *stream, char *string, unsigned int length, struct type * c_create_fundamental_type (struct objfile *objfile, int typeid) { - register struct type *type = NULL; + struct type *type = NULL; switch (typeid) { @@ -338,6 +321,30 @@ c_create_fundamental_type (struct objfile *objfile, int typeid) TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, 0, "long double", objfile); break; + case FT_COMPLEX: + type = init_type (TYPE_CODE_FLT, + 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT, + 0, "complex float", objfile); + TYPE_TARGET_TYPE (type) + = init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT, + 0, "float", objfile); + break; + case FT_DBL_PREC_COMPLEX: + type = init_type (TYPE_CODE_FLT, + 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "complex double", objfile); + TYPE_TARGET_TYPE (type) + = init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "double", objfile); + break; + case FT_EXT_PREC_COMPLEX: + type = init_type (TYPE_CODE_FLT, + 2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "complex long double", objfile); + TYPE_TARGET_TYPE (type) + = init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long double", objfile); + break; case FT_TEMPLATE_ARG: type = init_type (TYPE_CODE_TEMPLATE_ARG, 0, @@ -347,7 +354,128 @@ c_create_fundamental_type (struct objfile *objfile, int typeid) return (type); } +/* Preprocessing and parsing C and C++ expressions. */ + +/* When we find that lexptr (the global var defined in parse.c) is + pointing at a macro invocation, we expand the invocation, and call + scan_macro_expansion to save the old lexptr here and point lexptr + into the expanded text. When we reach the end of that, we call + end_macro_expansion to pop back to the value we saved here. The + macro expansion code promises to return only fully-expanded text, + so we don't need to "push" more than one level. + + This is disgusting, of course. It would be cleaner to do all macro + expansion beforehand, and then hand that to lexptr. But we don't + really know where the expression ends. Remember, in a command like + + (gdb) break *ADDRESS if CONDITION + + we evaluate ADDRESS in the scope of the current frame, but we + evaluate CONDITION in the scope of the breakpoint's location. So + it's simply wrong to try to macro-expand the whole thing at once. */ +static char *macro_original_text; +static char *macro_expanded_text; + + +void +scan_macro_expansion (char *expansion) +{ + /* We'd better not be trying to push the stack twice. */ + gdb_assert (! macro_original_text); + gdb_assert (! macro_expanded_text); + + /* Save the old lexptr value, so we can return to it when we're done + parsing the expanded text. */ + macro_original_text = lexptr; + lexptr = expansion; + + /* Save the expanded text, so we can free it when we're finished. */ + macro_expanded_text = expansion; +} + + +int +scanning_macro_expansion (void) +{ + return macro_original_text != 0; +} + + +void +finished_macro_expansion (void) +{ + /* There'd better be something to pop back to, and we better have + saved a pointer to the start of the expanded text. */ + gdb_assert (macro_original_text); + gdb_assert (macro_expanded_text); + + /* Pop back to the original text. */ + lexptr = macro_original_text; + macro_original_text = 0; + + /* Free the expanded text. */ + xfree (macro_expanded_text); + macro_expanded_text = 0; +} + + +static void +scan_macro_cleanup (void *dummy) +{ + if (macro_original_text) + finished_macro_expansion (); +} + + +/* We set these global variables before calling c_parse, to tell it + how it to find macro definitions for the expression at hand. */ +macro_lookup_ftype *expression_macro_lookup_func; +void *expression_macro_lookup_baton; + + +static struct macro_definition * +null_macro_lookup (const char *name, void *baton) +{ + return 0; +} + + +static int +c_preprocess_and_parse (void) +{ + /* Set up a lookup function for the macro expander. */ + struct macro_scope *scope = 0; + struct cleanup *back_to = make_cleanup (free_current_contents, &scope); + + if (expression_context_block) + scope = sal_macro_scope (find_pc_line (expression_context_pc, 0)); + else + scope = default_macro_scope (); + + if (scope) + { + expression_macro_lookup_func = standard_macro_lookup; + expression_macro_lookup_baton = (void *) scope; + } + else + { + expression_macro_lookup_func = null_macro_lookup; + expression_macro_lookup_baton = 0; + } + + gdb_assert (! macro_original_text); + make_cleanup (scan_macro_cleanup, 0); + + { + int result = c_parse (); + do_cleanups (back_to); + return result; + } +} + + + /* Table mapping opcodes into strings for printing operators and precedences of the operators. */ @@ -415,9 +543,9 @@ const struct language_defn c_language_defn = range_check_off, type_check_off, case_sensitive_on, - c_parse, + &exp_descriptor_standard, + c_preprocess_and_parse, c_error, - evaluate_subexp_standard, c_printchar, /* Print a character constant */ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ @@ -425,6 +553,11 @@ const struct language_defn c_language_defn = 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 */ + NULL, /* Language specific skip_trampoline */ + NULL, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -433,6 +566,7 @@ const struct language_defn c_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; @@ -467,9 +601,9 @@ const struct language_defn cplus_language_defn = range_check_off, type_check_off, case_sensitive_on, - c_parse, + &exp_descriptor_standard, + c_preprocess_and_parse, c_error, - evaluate_subexp_standard, c_printchar, /* Print a character constant */ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ @@ -477,6 +611,11 @@ const struct language_defn cplus_language_defn = 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 */ + NULL, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + cp_lookup_transparent_type, /* lookup_transparent_type */ + cplus_demangle, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -485,6 +624,7 @@ const struct language_defn cplus_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; @@ -496,9 +636,9 @@ const struct language_defn asm_language_defn = range_check_off, type_check_off, case_sensitive_on, - c_parse, + &exp_descriptor_standard, + c_preprocess_and_parse, c_error, - evaluate_subexp_standard, c_printchar, /* Print a character constant */ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ @@ -506,6 +646,11 @@ const struct language_defn asm_language_defn = 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 */ + NULL, /* Language specific skip_trampoline */ + NULL, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -514,6 +659,47 @@ const struct language_defn asm_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, + LANG_MAGIC +}; + +/* The following language_defn does not represent a real language. + It just provides a minimal support a-la-C that should allow users + to do some simple operations when debugging applications that use + a language currently not supported by GDB. */ + +const struct language_defn minimal_language_defn = +{ + "minimal", /* Language name */ + language_minimal, + c_builtin_types, + range_check_off, + type_check_off, + case_sensitive_on, + &exp_descriptor_standard, + c_preprocess_and_parse, + c_error, + c_printchar, /* Print a character constant */ + c_printstr, /* Function to print string constant */ + c_emit_char, /* Print a single char */ + 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 */ + NULL, /* Language specific skip_trampoline */ + NULL, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ + {"", "", "", ""}, /* 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 */ + 1, /* c-style arrays */ + 0, /* String lower bound */ + &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; @@ -523,4 +709,5 @@ _initialize_c_language (void) add_language (&c_language_defn); add_language (&cplus_language_defn); add_language (&asm_language_defn); + add_language (&minimal_language_defn); } diff --git a/contrib/gdb/gdb/c-lang.h b/contrib/gdb/gdb/c-lang.h index b1925e1e2d6..dd8f2311702 100644 --- a/contrib/gdb/gdb/c-lang.h +++ b/contrib/gdb/gdb/c-lang.h @@ -23,7 +23,10 @@ #if !defined (C_LANG_H) #define C_LANG_H 1 +struct ui_file; + #include "value.h" +#include "macroexp.h" extern int c_parse (void); /* Defined in c-exp.y */ @@ -49,6 +52,13 @@ extern void c_printstr (struct ui_file * stream, char *string, unsigned int length, int width, int force_ellipses); +extern void scan_macro_expansion (char *expansion); +extern int scanning_macro_expansion (void); +extern void finished_macro_expansion (void); + +extern macro_lookup_ftype *expression_macro_lookup_func; +extern void *expression_macro_lookup_baton; + extern struct type *c_create_fundamental_type (struct objfile *, int); extern struct type **const (c_builtin_types[]); @@ -57,9 +67,6 @@ extern struct type **const (c_builtin_types[]); extern void c_type_print_base (struct type *, struct ui_file *, int, int); -extern void c_type_print_varspec_prefix (struct type *, struct ui_file *, - int, int); - /* These are in cp-valprint.c */ extern int vtblprint; /* Controls printing of vtbl's */ diff --git a/contrib/gdb/gdb/c-typeprint.c b/contrib/gdb/gdb/c-typeprint.c index 0c460e9dd5f..2d2ad850c3f 100644 --- a/contrib/gdb/gdb/c-typeprint.c +++ b/contrib/gdb/gdb/c-typeprint.c @@ -1,6 +1,6 @@ /* Support for printing C and C++ types for GDB, the GNU debugger. Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001, 2002 + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -21,7 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "bfd.h" /* Binary File Description */ #include "symtab.h" #include "gdbtypes.h" @@ -41,7 +41,7 @@ /* Flag indicating target was compiled by HP compiler */ extern int hp_som_som_object_present; -static void cp_type_print_method_args (struct type ** args, char *prefix, +static void cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring, int staticp, struct ui_file *stream); @@ -49,8 +49,8 @@ static void c_type_print_args (struct type *, struct ui_file *); static void cp_type_print_derivation_info (struct ui_file *, struct type *); -void c_type_print_varspec_prefix (struct type *, struct ui_file *, int, - int); +static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int, + int, int); /* Print "const", "volatile", or address space modifiers. */ static void c_type_print_modifier (struct type *, struct ui_file *, @@ -65,8 +65,9 @@ void c_print_type (struct type *type, char *varstring, struct ui_file *stream, int show, int level) { - register enum type_code code; + enum type_code code; int demangled_args; + int need_post_space; if (show > 0) CHECK_TYPEDEF (type); @@ -85,7 +86,8 @@ c_print_type (struct type *type, char *varstring, struct ui_file *stream, || code == TYPE_CODE_MEMBER || code == TYPE_CODE_REF))) fputs_filtered (" ", stream); - c_type_print_varspec_prefix (type, stream, show, 0); + need_post_space = (varstring != NULL && strcmp (varstring, "") != 0); + c_type_print_varspec_prefix (type, stream, show, 0, need_post_space); if (varstring != NULL) { @@ -147,40 +149,40 @@ cp_type_print_derivation_info (struct ui_file *stream, struct type *type) fputs_filtered (" ", stream); } } + /* Print the C++ method arguments ARGS to the file STREAM. */ static void -cp_type_print_method_args (struct type **args, char *prefix, char *varstring, +cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring, int staticp, struct ui_file *stream) { + struct field *args = TYPE_FIELDS (mtype); + int nargs = TYPE_NFIELDS (mtype); + int varargs = TYPE_VARARGS (mtype); int i; fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI); fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI); fputs_filtered ("(", stream); - if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID) + + /* Skip the class variable. */ + i = staticp ? 0 : 1; + if (nargs > i) { - i = !staticp; /* skip the class variable */ - while (1) + while (i < nargs) { - type_print (args[i++], "", stream, 0); - if (!args[i]) - { - fprintf_filtered (stream, " ..."); - break; - } - else if (args[i]->code != TYPE_CODE_VOID) - { - fprintf_filtered (stream, ", "); - } - else - break; + type_print (args[i++].type, "", stream, 0); + + if (i == nargs && varargs) + fprintf_filtered (stream, ", ..."); + else if (i < nargs) + fprintf_filtered (stream, ", "); } } + else if (varargs) + fprintf_filtered (stream, "..."); else if (current_language->la_language == language_cplus) - { - fprintf_filtered (stream, "void"); - } + fprintf_filtered (stream, "void"); fprintf_filtered (stream, ")"); } @@ -192,11 +194,15 @@ cp_type_print_method_args (struct type **args, char *prefix, char *varstring, On outermost call, pass 0 for PASSED_A_PTR. On outermost call, SHOW > 0 means should ignore any typename for TYPE and show its details. - SHOW is always zero on recursive calls. */ + SHOW is always zero on recursive calls. + + NEED_POST_SPACE is non-zero when a space will be be needed + between a trailing qualifier and a field, variable, or function + name. */ void c_type_print_varspec_prefix (struct type *type, struct ui_file *stream, - int show, int passed_a_ptr) + int show, int passed_a_ptr, int need_post_space) { char *name; if (type == 0) @@ -210,15 +216,15 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream, switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); + c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 1, 1); fprintf_filtered (stream, "*"); - c_type_print_modifier (type, stream, 1, 0); + c_type_print_modifier (type, stream, 1, need_post_space); break; case TYPE_CODE_MEMBER: if (passed_a_ptr) fprintf_filtered (stream, "("); - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); + c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); fprintf_filtered (stream, " "); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); if (name) @@ -231,7 +237,7 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream, case TYPE_CODE_METHOD: if (passed_a_ptr) fprintf_filtered (stream, "("); - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); + c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); if (passed_a_ptr) { fprintf_filtered (stream, " "); @@ -241,23 +247,27 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream, break; case TYPE_CODE_REF: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); + c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 1, 0); fprintf_filtered (stream, "&"); - c_type_print_modifier (type, stream, 1, 0); + c_type_print_modifier (type, stream, 1, need_post_space); break; case TYPE_CODE_FUNC: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); + c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); if (passed_a_ptr) fprintf_filtered (stream, "("); break; case TYPE_CODE_ARRAY: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); + c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); if (passed_a_ptr) fprintf_filtered (stream, "("); break; + case TYPE_CODE_TYPEDEF: + c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); + break; + case TYPE_CODE_UNDEF: case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: @@ -273,8 +283,8 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream, case TYPE_CODE_STRING: case TYPE_CODE_BITSTRING: case TYPE_CODE_COMPLEX: - case TYPE_CODE_TYPEDEF: case TYPE_CODE_TEMPLATE: + case TYPE_CODE_NAMESPACE: /* These types need no prefix. They are listed here so that gcc -Wall will reveal any types that haven't been handled. */ break; @@ -294,7 +304,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream, int need_pre_space, int need_post_space) { int did_print_modifier = 0; - char *address_space_id; + const char *address_space_id; /* We don't print `const' qualifiers for references --- since all operators affect the thing referenced, not the reference itself, @@ -316,7 +326,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream, did_print_modifier = 1; } - address_space_id = address_space_int_to_name (TYPE_FLAGS (type)); + address_space_id = address_space_int_to_name (TYPE_INSTANCE_FLAGS (type)); if (address_space_id) { if (did_print_modifier || need_pre_space) @@ -336,39 +346,31 @@ static void c_type_print_args (struct type *type, struct ui_file *stream) { int i; - struct type **args; + struct field *args; fprintf_filtered (stream, "("); - args = TYPE_ARG_TYPES (type); + args = TYPE_FIELDS (type); if (args != NULL) { - if (args[1] == NULL) + int i; + + /* FIXME drow/2002-05-31: Always skips the first argument, + should we be checking for static members? */ + + for (i = 1; i < TYPE_NFIELDS (type); i++) { - fprintf_filtered (stream, "..."); - } - else if ((args[1]->code == TYPE_CODE_VOID) && - (current_language->la_language == language_cplus)) - { - fprintf_filtered (stream, "void"); - } - else - { - for (i = 1; - args[i] != NULL && args[i]->code != TYPE_CODE_VOID; - i++) + c_print_type (args[i].type, "", stream, -1, 0); + if (i != TYPE_NFIELDS (type)) { - c_print_type (args[i], "", stream, -1, 0); - if (args[i + 1] == NULL) - { - fprintf_filtered (stream, "..."); - } - else if (args[i + 1]->code != TYPE_CODE_VOID) - { - fprintf_filtered (stream, ","); - wrap_here (" "); - } + fprintf_filtered (stream, ","); + wrap_here (" "); } } + if (TYPE_VARARGS (type)) + fprintf_filtered (stream, "..."); + else if (i == 1 + && (current_language->la_language == language_cplus)) + fprintf_filtered (stream, "void"); } else if (current_language->la_language == language_cplus) { @@ -545,19 +547,22 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, / TYPE_LENGTH (TYPE_TARGET_TYPE (type)))); fprintf_filtered (stream, "]"); - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); + c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, + 0, 0); break; case TYPE_CODE_MEMBER: if (passed_a_ptr) fprintf_filtered (stream, ")"); - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); + c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, + 0, 0); break; case TYPE_CODE_METHOD: if (passed_a_ptr) fprintf_filtered (stream, ")"); - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); + c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, + 0, 0); if (passed_a_ptr) { c_type_print_args (type, stream); @@ -566,7 +571,8 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, case TYPE_CODE_PTR: case TYPE_CODE_REF: - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0); + c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, + 1, 0); break; case TYPE_CODE_FUNC: @@ -594,7 +600,12 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, } fprintf_filtered (stream, ")"); } - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, + c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, + passed_a_ptr, 0); + break; + + case TYPE_CODE_TYPEDEF: + c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; @@ -613,8 +624,8 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, case TYPE_CODE_STRING: case TYPE_CODE_BITSTRING: case TYPE_CODE_COMPLEX: - case TYPE_CODE_TYPEDEF: case TYPE_CODE_TEMPLATE: + case TYPE_CODE_NAMESPACE: /* These types do not need a suffix. They are listed so that gcc -Wall will report types that may not have been considered. */ break; @@ -848,10 +859,11 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show, QUIT; /* Don't print out virtual function table. */ /* HP ANSI C++ case */ - if (TYPE_HAS_VTABLE (type) && (STREQN (TYPE_FIELD_NAME (type, i), "__vfp", 5))) + if (TYPE_HAS_VTABLE (type) + && (strncmp (TYPE_FIELD_NAME (type, i), "__vfp", 5) == 0)) continue; /* Other compilers */ - if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5) + if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0 && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; @@ -933,7 +945,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show, int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); char *method_name = TYPE_FN_FIELDLIST_NAME (type, i); char *name = type_name_no_tag (type); - int is_constructor = name && STREQ (method_name, name); + int is_constructor = name && strcmp (method_name, name) == 0; for (j = 0; j < len2; j++) { char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); @@ -1010,10 +1022,15 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show, Let's try to reconstruct the function signature from the symbol information */ if (!TYPE_FN_FIELD_STUB (f, j)) - cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "", - method_name, - TYPE_FN_FIELD_STATIC_P (f, j), - stream); + { + int staticp = TYPE_FN_FIELD_STATIC_P (f, j); + struct type *mtype = TYPE_FN_FIELD_TYPE (f, j); + cp_type_print_method_args (mtype, + "", + method_name, + staticp, + stream); + } else fprintf_filtered (stream, "", mangled_name); @@ -1168,6 +1185,11 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show, } break; + case TYPE_CODE_NAMESPACE: + fputs_filtered ("namespace ", stream); + fputs_filtered (TYPE_TAG_NAME (type), stream); + break; + default: /* Handle types not explicitly handled by the other cases, such as fundamental types. For these, just print whatever diff --git a/contrib/gdb/gdb/c-valprint.c b/contrib/gdb/gdb/c-valprint.c index 9361067ceaa..fd42ae0b908 100644 --- a/contrib/gdb/gdb/c-valprint.c +++ b/contrib/gdb/gdb/c-valprint.c @@ -1,7 +1,7 @@ /* Support for printing C values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "gdb_string.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" @@ -29,6 +30,7 @@ #include "language.h" #include "c-lang.h" #include "cp-abi.h" +#include "target.h" /* Print function pointer with inferior address ADDRESS onto stdio @@ -37,7 +39,9 @@ static void print_function_pointer_address (CORE_ADDR address, struct ui_file *stream) { - CORE_ADDR func_addr = CONVERT_FROM_FUNC_PTR_ADDR (address); + CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, + address, + ¤t_target); /* If the function pointer is represented by a description, print the address of the description. */ @@ -69,7 +73,7 @@ c_val_print (struct type *type, char *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { - register unsigned int i = 0; /* Number of characters printed */ + unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype; unsigned eltlen; @@ -204,7 +208,7 @@ c_val_print (struct type *type, char *valaddr, int embedded_offset, (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) { fputs_filtered (" <", stream); - fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream); + fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); fputs_filtered (">", stream); } if (vt_address && vtblprint) @@ -212,13 +216,12 @@ c_val_print (struct type *type, char *valaddr, int embedded_offset, struct value *vt_val; struct symbol *wsym = (struct symbol *) NULL; struct type *wtype; - struct symtab *s; struct block *block = (struct block *) NULL; int is_this_fld; if (msymbol != NULL) - wsym = lookup_symbol (SYMBOL_NAME (msymbol), block, - VAR_NAMESPACE, &is_this_fld, &s); + wsym = lookup_symbol (DEPRECATED_SYMBOL_NAME (msymbol), block, + VAR_DOMAIN, &is_this_fld, NULL); if (wsym) { @@ -514,7 +517,7 @@ c_value_print (struct value *val, struct ui_file *stream, int format, if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_NAME (type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL && - STREQ (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char")) + strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0) { /* Print nothing */ } @@ -592,7 +595,8 @@ c_value_print (struct value *val, struct ui_file *stream, int format, /* Otherwise, we end up at the return outside this "if" */ } - return val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), - VALUE_ADDRESS (val), + return val_print (type, VALUE_CONTENTS_ALL (val), + VALUE_EMBEDDED_OFFSET (val), + VALUE_ADDRESS (val) + VALUE_OFFSET (val), stream, format, 1, 0, pretty); } diff --git a/contrib/gdb/gdb/charset.c b/contrib/gdb/gdb/charset.c new file mode 100644 index 00000000000..2005a49e009 --- /dev/null +++ b/contrib/gdb/gdb/charset.c @@ -0,0 +1,1277 @@ +/* Character set conversion support for GDB. + + Copyright 2001, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "charset.h" +#include "gdbcmd.h" +#include "gdb_assert.h" + +#include +#include "gdb_string.h" +#include + +#ifdef HAVE_ICONV +#include +#endif + + +/* How GDB's character set support works + + GDB has two global settings: + + - The `current host character set' is the character set GDB should + use in talking to the user, and which (hopefully) the user's + terminal knows how to display properly. + + - The `current target character set' is the character set the + program being debugged uses. + + There are commands to set each of these, and mechanisms for + choosing reasonable default values. GDB has a global list of + character sets that it can use as its host or target character + sets. + + The header file `charset.h' declares various functions that + different pieces of GDB need to perform tasks like: + + - printing target strings and characters to the user's terminal + (mostly target->host conversions), + + - building target-appropriate representations of strings and + characters the user enters in expressions (mostly host->target + conversions), + + and so on. + + Now, many of these operations are specific to a particular + host/target character set pair. If GDB supports N character sets, + there are N^2 possible pairs. This means that, the larger GDB's + repertoire of character sets gets, the more expensive it gets to add + new character sets. + + To make sure that GDB can do the right thing for every possible + pairing of host and target character set, while still allowing + GDB's repertoire to scale, we use a two-tiered approach: + + - We maintain a global table of "translations" --- groups of + functions specific to a particular pair of character sets. + + - However, a translation can be incomplete: some functions can be + omitted. Where there is not a translation to specify exactly + what function to use, we provide reasonable defaults. The + default behaviors try to use the "iconv" library functions, which + support a wide range of character sets. However, even if iconv + is not available, there are fallbacks to support trivial + translations: when the host and target character sets are the + same. */ + + +/* The character set and translation structures. */ + + +/* A character set GDB knows about. GDB only supports character sets + with stateless encodings, in which every character is one byte + long. */ +struct charset { + + /* A singly-linked list of all known charsets. */ + struct charset *next; + + /* The name of the character set. Comparisons on character set + names are case-sensitive. */ + const char *name; + + /* Non-zero iff this character set can be used as a host character + set. At present, GDB basically assumes that the host character + set is a superset of ASCII. */ + int valid_host_charset; + + /* Pointers to charset-specific functions that depend only on a + single character set, and data pointers to pass to them. */ + int (*host_char_print_literally) (void *baton, + int host_char); + void *host_char_print_literally_baton; + + int (*target_char_to_control_char) (void *baton, + int target_char, + int *target_ctrl_char); + void *target_char_to_control_char_baton; +}; + + +/* A translation from one character set to another. */ +struct translation { + + /* A singly-linked list of all known translations. */ + struct translation *next; + + /* This structure describes functions going from the FROM character + set to the TO character set. Comparisons on character set names + are case-sensitive. */ + const char *from, *to; + + /* Pointers to translation-specific functions, and data pointers to + pass to them. These pointers can be zero, indicating that GDB + should fall back on the default behavior. We hope the default + behavior will be correct for many from/to pairs, reducing the + number of translations that need to be registered explicitly. */ + + /* TARGET_CHAR is in the `from' charset. + Returns a string in the `to' charset. */ + const char *(*c_target_char_has_backslash_escape) (void *baton, + int target_char); + void *c_target_char_has_backslash_escape_baton; + + /* HOST_CHAR is in the `from' charset. + TARGET_CHAR points to a char in the `to' charset. */ + int (*c_parse_backslash) (void *baton, int host_char, int *target_char); + void *c_parse_backslash_baton; + + /* This is used for the host_char_to_target and target_char_to_host + functions. */ + int (*convert_char) (void *baton, int from, int *to); + void *convert_char_baton; +}; + + + +/* The global lists of character sets and translations. */ + + +#ifndef GDB_DEFAULT_HOST_CHARSET +#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1" +#endif + +#ifndef GDB_DEFAULT_TARGET_CHARSET +#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1" +#endif + +static const char *host_charset_name = GDB_DEFAULT_HOST_CHARSET; +static const char *target_charset_name = GDB_DEFAULT_TARGET_CHARSET; + +static const char *host_charset_enum[] = +{ + "ASCII", + "ISO-8859-1", + 0 +}; + +static const char *target_charset_enum[] = +{ + "ASCII", + "ISO-8859-1", + "EBCDIC-US", + "IBM1047", + 0 +}; + +/* The global list of all the charsets GDB knows about. */ +static struct charset *all_charsets; + + +static void +register_charset (struct charset *cs) +{ + struct charset **ptr; + + /* Put the new charset on the end, so that the list ends up in the + same order as the registrations in the _initialize function. */ + for (ptr = &all_charsets; *ptr; ptr = &(*ptr)->next) + ; + + cs->next = 0; + *ptr = cs; +} + + +static struct charset * +lookup_charset (const char *name) +{ + struct charset *cs; + + for (cs = all_charsets; cs; cs = cs->next) + if (! strcmp (name, cs->name)) + return cs; + + return NULL; +} + + +/* The global list of translations. */ +static struct translation *all_translations; + + +static void +register_translation (struct translation *t) +{ + t->next = all_translations; + all_translations = t; +} + + +static struct translation * +lookup_translation (const char *from, const char *to) +{ + struct translation *t; + + for (t = all_translations; t; t = t->next) + if (! strcmp (from, t->from) + && ! strcmp (to, t->to)) + return t; + + return 0; +} + + + +/* Constructing charsets. */ + +/* Allocate, initialize and return a straightforward charset. + Use this function, rather than creating the structures yourself, + so that we can add new fields to the structure in the future without + having to tweak all the old charset descriptions. */ +static struct charset * +simple_charset (const char *name, + int valid_host_charset, + int (*host_char_print_literally) (void *baton, int host_char), + void *host_char_print_literally_baton, + int (*target_char_to_control_char) (void *baton, + int target_char, + int *target_ctrl_char), + void *target_char_to_control_char_baton) +{ + struct charset *cs = xmalloc (sizeof (*cs)); + + memset (cs, 0, sizeof (*cs)); + cs->name = name; + cs->valid_host_charset = valid_host_charset; + cs->host_char_print_literally = host_char_print_literally; + cs->host_char_print_literally_baton = host_char_print_literally_baton; + cs->target_char_to_control_char = target_char_to_control_char; + cs->target_char_to_control_char_baton = target_char_to_control_char_baton; + + return cs; +} + + + +/* ASCII functions. */ + +static int +ascii_print_literally (void *baton, int c) +{ + c &= 0xff; + + return (0x20 <= c && c <= 0x7e); +} + + +static int +ascii_to_control (void *baton, int c, int *ctrl_char) +{ + *ctrl_char = (c & 037); + return 1; +} + + +/* ISO-8859 family functions. */ + + +static int +iso_8859_print_literally (void *baton, int c) +{ + c &= 0xff; + + return ((0x20 <= c && c <= 0x7e) /* ascii printables */ + || (! sevenbit_strings && 0xA0 <= c)); /* iso 8859 printables */ +} + + +static int +iso_8859_to_control (void *baton, int c, int *ctrl_char) +{ + *ctrl_char = (c & 0200) | (c & 037); + return 1; +} + + +/* Construct an ISO-8859-like character set. */ +static struct charset * +iso_8859_family_charset (const char *name) +{ + return simple_charset (name, 1, + iso_8859_print_literally, 0, + iso_8859_to_control, 0); +} + + + +/* EBCDIC family functions. */ + + +static int +ebcdic_print_literally (void *baton, int c) +{ + c &= 0xff; + + return (64 <= c && c <= 254); +} + + +static int +ebcdic_to_control (void *baton, int c, int *ctrl_char) +{ + /* There are no control character equivalents in EBCDIC. Use + numeric escapes. */ + return 0; +} + + +/* Construct an EBCDIC-like character set. */ +static struct charset * +ebcdic_family_charset (const char *name) +{ + return simple_charset (name, 0, + ebcdic_print_literally, 0, + ebcdic_to_control, 0); +} + + + + + +/* Fallback functions using iconv. */ + +#if defined(HAVE_ICONV) + +struct cached_iconv { + struct charset *from, *to; + iconv_t i; +}; + + +/* Make sure the iconv cache *CI contains an iconv descriptor + translating from FROM to TO. If it already does, fine; otherwise, + close any existing descriptor, and open up a new one. On success, + return zero; on failure, return -1 and set errno. */ +static int +check_iconv_cache (struct cached_iconv *ci, + struct charset *from, + struct charset *to) +{ + iconv_t i; + + /* Does the cached iconv descriptor match the conversion we're trying + to do now? */ + if (ci->from == from + && ci->to == to + && ci->i != (iconv_t) 0) + return 0; + + /* It doesn't. If we actually had any iconv descriptor open at + all, close it now. */ + if (ci->i != (iconv_t) 0) + { + i = ci->i; + ci->i = (iconv_t) 0; + + if (iconv_close (i) == -1) + error ("Error closing `iconv' descriptor for " + "`%s'-to-`%s' character conversion: %s", + ci->from->name, ci->to->name, safe_strerror (errno)); + } + + /* Open a new iconv descriptor for the required conversion. */ + i = iconv_open (to->name, from->name); + if (i == (iconv_t) -1) + return -1; + + ci->i = i; + ci->from = from; + ci->to = to; + + return 0; +} + + +/* Convert FROM_CHAR using the cached iconv conversion *CI. Return + non-zero if the conversion was successful, zero otherwise. */ +static int +cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char) +{ + char from; + ICONV_CONST char *from_ptr = &from; + char to, *to_ptr = &to; + size_t from_left = sizeof (from), to_left = sizeof (to); + + gdb_assert (ci->i != (iconv_t) 0); + + from = from_char; + if (iconv (ci->i, &from_ptr, &from_left, &to_ptr, &to_left) + == (size_t) -1) + { + /* These all suggest that the input or output character sets + have multi-byte encodings of some characters, which means + it's unsuitable for use as a GDB character set. We should + never have selected it. */ + gdb_assert (errno != E2BIG && errno != EINVAL); + + /* This suggests a bug in the code managing *CI. */ + gdb_assert (errno != EBADF); + + /* This seems to mean that there is no equivalent character in + the `to' character set. */ + if (errno == EILSEQ) + return 0; + + /* Anything else is mysterious. */ + internal_error (__FILE__, __LINE__, + "Error converting character `%d' from `%s' to `%s' " + "character set: %s", + from_char, ci->from->name, ci->to->name, + safe_strerror (errno)); + } + + /* If the pointers weren't advanced across the input, that also + suggests something was wrong. */ + gdb_assert (from_left == 0 && to_left == 0); + + *to_char = (unsigned char) to; + return 1; +} + + +static void +register_iconv_charsets (void) +{ + /* Here we should check whether various character sets were + recognized by the local iconv implementation. + + The first implementation registered a bunch of character sets + recognized by iconv, but then we discovered that iconv on Solaris + and iconv on GNU/Linux had no character sets in common. So we + replaced them with the hard-coded tables that appear later in the + file. */ +} + +#endif /* defined (HAVE_ICONV) */ + + +/* Fallback routines for systems without iconv. */ + +#if ! defined (HAVE_ICONV) +struct cached_iconv { char nothing; }; + +static int +check_iconv_cache (struct cached_iconv *ci, + struct charset *from, + struct charset *to) +{ + errno = EINVAL; + return -1; +} + +static int +cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char) +{ + /* This function should never be called. */ + gdb_assert (0); +} + +static void +register_iconv_charsets (void) +{ +} + +#endif /* ! defined(HAVE_ICONV) */ + + +/* Default trivial conversion functions. */ + +static int +identity_either_char_to_other (void *baton, int either_char, int *other_char) +{ + *other_char = either_char; + return 1; +} + + + +/* Default non-trivial conversion functions. */ + + +static char backslashable[] = "abfnrtv"; +static char *backslashed[] = {"a", "b", "f", "n", "r", "t", "v", "0"}; +static char represented[] = "\a\b\f\n\r\t\v"; + + +/* Translate TARGET_CHAR into the host character set, and see if it + matches any of our standard escape sequences. */ +static const char * +default_c_target_char_has_backslash_escape (void *baton, int target_char) +{ + int host_char; + const char *ix; + + /* If target_char has no equivalent in the host character set, + assume it doesn't have a backslashed form. */ + if (! target_char_to_host (target_char, &host_char)) + return NULL; + + ix = strchr (represented, host_char); + if (ix) + return backslashed[ix - represented]; + else + return NULL; +} + + +/* Translate the backslash the way we would in the host character set, + and then try to translate that into the target character set. */ +static int +default_c_parse_backslash (void *baton, int host_char, int *target_char) +{ + const char *ix; + + ix = strchr (backslashable, host_char); + + if (! ix) + return 0; + else + return host_char_to_target (represented[ix - backslashable], + target_char); +} + + +/* Convert using a cached iconv descriptor. */ +static int +iconv_convert (void *baton, int from_char, int *to_char) +{ + struct cached_iconv *ci = baton; + return cached_iconv_convert (ci, from_char, to_char); +} + + + +/* Conversion tables. */ + + +/* I'd much rather fall back on iconv whenever possible. But the + character set names you use with iconv aren't standardized at all, + a lot of platforms have really meager character set coverage, etc. + I wanted to have at least something we could use to exercise the + test suite on all platforms. + + In the long run, we should have a configure-time process explore + somehow which character sets the host platform supports, and some + arrangement that allows GDB users to use platform-indepedent names + for character sets. */ + + +/* We generated these tables using iconv on a GNU/Linux machine. */ + + +static int ascii_to_iso_8859_1_table[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */ + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */ + 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */ + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ +}; + + +static int ascii_to_ebcdic_us_table[] = { + 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ + 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ + 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ + 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ + 215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */ + 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ + 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ +}; + + +static int ascii_to_ibm1047_table[] = { + 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ + 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ + 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ + 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ + 215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */ + 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ + 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ +}; + + +static int iso_8859_1_to_ascii_table[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */ + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */ + 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */ + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ +}; + + +static int iso_8859_1_to_ebcdic_us_table[] = { + 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ + 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ + 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ + 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ + 215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */ + 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ + 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ + 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, /* 144 */ + 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255, /* 160 */ + -1, -1, 74, -1, -1, -1,106, -1, -1, -1, -1, -1, 95, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ +}; + + +static int iso_8859_1_to_ibm1047_table[] = { + 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ + 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ + 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ + 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ + 215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */ + 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ + 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ + 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, /* 144 */ + 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255, /* 160 */ + 65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188, /* 176 */ + 144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171, /* 192 */ + 100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119, /* 208 */ + 172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89, /* 224 */ + 68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87, /* 240 */ + 140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223 /* 256 */ +}; + + +static int ebcdic_us_to_ascii_table[] = { + 0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */ + -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7, /* 48 */ + -1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */ + 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */ + 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, -1, /* 96 */ + 45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */ + -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */ + -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */ + -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */ + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */ + 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1 /* 256 */ +}; + + +static int ebcdic_us_to_iso_8859_1_table[] = { + 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */ + 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, /* 48 */ + 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, /* 64 */ + 32, -1, -1, -1, -1, -1, -1, -1, -1, -1,162, 46, 60, 40, 43,124, /* 80 */ + 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59,172, /* 96 */ + 45, 47, -1, -1, -1, -1, -1, -1, -1, -1,166, 44, 37, 95, 62, 63, /* 112 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */ + -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */ + -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */ + -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */ + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */ + 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,159 /* 256 */ +}; + + +static int ebcdic_us_to_ibm1047_table[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ + 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */ + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94,176, /* 96 */ + 96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */ + -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */ + -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */ + -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + 192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */ + 208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */ + 224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */ + 240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255 /* 256 */ +}; + + +static int ibm1047_to_ascii_table[] = { + 0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */ + -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7, /* 48 */ + -1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */ + 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */ + 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, 94, /* 96 */ + 45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */ + -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */ + -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */ + -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, 91, -1, -1, /* 176 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, /* 192 */ + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */ + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */ + 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1 /* 256 */ +}; + + +static int ibm1047_to_iso_8859_1_table[] = { + 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */ + 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, /* 48 */ + 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, /* 64 */ + 32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124, /* 80 */ + 38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94, /* 96 */ + 45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63, /* 112 */ + 248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34, /* 128 */ + 216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177, /* 144 */ + 176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164, /* 160 */ + 181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174, /* 176 */ + 172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215, /* 192 */ + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245, /* 208 */ + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255, /* 224 */ + 92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213, /* 240 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159 /* 256 */ +}; + + +static int ibm1047_to_ebcdic_us_table[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ + 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */ + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94, -1, /* 96 */ + 96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */ + -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */ + -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */ + -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */ + 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ + 192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */ + 208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */ + 224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */ + 240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255 /* 256 */ +}; + + +static int +table_convert_char (void *baton, int from, int *to) +{ + int *table = (int *) baton; + + if (0 <= from && from <= 255 + && table[from] != -1) + { + *to = table[from]; + return 1; + } + else + return 0; +} + + +static struct translation * +table_translation (const char *from, const char *to, int *table, + const char *(*c_target_char_has_backslash_escape) + (void *baton, int target_char), + void *c_target_char_has_backslash_escape_baton, + int (*c_parse_backslash) (void *baton, + int host_char, + int *target_char), + void *c_parse_backslash_baton) +{ + struct translation *t = xmalloc (sizeof (*t)); + + memset (t, 0, sizeof (*t)); + t->from = from; + t->to = to; + t->c_target_char_has_backslash_escape = c_target_char_has_backslash_escape; + t->c_target_char_has_backslash_escape_baton + = c_target_char_has_backslash_escape_baton; + t->c_parse_backslash = c_parse_backslash; + t->c_parse_backslash_baton = c_parse_backslash_baton; + t->convert_char = table_convert_char; + t->convert_char_baton = (void *) table; + + return t; +} + + +static struct translation * +simple_table_translation (const char *from, const char *to, int *table) +{ + return table_translation (from, to, table, 0, 0, 0, 0); +} + + + +/* Setting and retrieving the host and target charsets. */ + + +/* The current host and target character sets. */ +static struct charset *current_host_charset, *current_target_charset; + +/* The current functions and batons we should use for the functions in + charset.h. */ + +static const char *(*c_target_char_has_backslash_escape_func) + (void *baton, int target_char); +static void *c_target_char_has_backslash_escape_baton; + +static int (*c_parse_backslash_func) (void *baton, + int host_char, + int *target_char); +static void *c_parse_backslash_baton; + +static int (*host_char_to_target_func) (void *baton, + int host_char, + int *target_char); +static void *host_char_to_target_baton; + +static int (*target_char_to_host_func) (void *baton, + int target_char, + int *host_char); +static void *target_char_to_host_baton; + + +/* Cached iconv conversions, that might be useful to fallback + routines. */ +static struct cached_iconv cached_iconv_host_to_target; +static struct cached_iconv cached_iconv_target_to_host; + + +/* Charset structures manipulation functions. */ + +static struct charset * +lookup_charset_or_error (const char *name) +{ + struct charset *cs = lookup_charset (name); + + if (! cs) + error ("GDB doesn't know of any character set named `%s'.", name); + + return cs; +} + +static void +check_valid_host_charset (struct charset *cs) +{ + if (! cs->valid_host_charset) + error ("GDB can't use `%s' as its host character set.", cs->name); +} + +/* Set the host and target character sets to HOST and TARGET. */ +static void +set_host_and_target_charsets (struct charset *host, struct charset *target) +{ + struct translation *h2t, *t2h; + + /* If they're not both initialized yet, then just do nothing for + now. As soon as we're done running our initialize function, + everything will be initialized. */ + if (! host || ! target) + { + current_host_charset = host; + current_target_charset = target; + return; + } + + h2t = lookup_translation (host->name, target->name); + t2h = lookup_translation (target->name, host->name); + + /* If the translations don't provide conversion functions, make sure + iconv can back them up. Do this *before* modifying any state. */ + if (host != target) + { + if (! h2t || ! h2t->convert_char) + { + if (check_iconv_cache (&cached_iconv_host_to_target, host, target) + < 0) + error ("GDB can't convert from the `%s' character set to `%s'.", + host->name, target->name); + } + if (! t2h || ! t2h->convert_char) + { + if (check_iconv_cache (&cached_iconv_target_to_host, target, host) + < 0) + error ("GDB can't convert from the `%s' character set to `%s'.", + target->name, host->name); + } + } + + if (t2h && t2h->c_target_char_has_backslash_escape) + { + c_target_char_has_backslash_escape_func + = t2h->c_target_char_has_backslash_escape; + c_target_char_has_backslash_escape_baton + = t2h->c_target_char_has_backslash_escape_baton; + } + else + c_target_char_has_backslash_escape_func + = default_c_target_char_has_backslash_escape; + + if (h2t && h2t->c_parse_backslash) + { + c_parse_backslash_func = h2t->c_parse_backslash; + c_parse_backslash_baton = h2t->c_parse_backslash_baton; + } + else + c_parse_backslash_func = default_c_parse_backslash; + + if (h2t && h2t->convert_char) + { + host_char_to_target_func = h2t->convert_char; + host_char_to_target_baton = h2t->convert_char_baton; + } + else if (host == target) + host_char_to_target_func = identity_either_char_to_other; + else + { + host_char_to_target_func = iconv_convert; + host_char_to_target_baton = &cached_iconv_host_to_target; + } + + if (t2h && t2h->convert_char) + { + target_char_to_host_func = t2h->convert_char; + target_char_to_host_baton = t2h->convert_char_baton; + } + else if (host == target) + target_char_to_host_func = identity_either_char_to_other; + else + { + target_char_to_host_func = iconv_convert; + target_char_to_host_baton = &cached_iconv_target_to_host; + } + + current_host_charset = host; + current_target_charset = target; +} + +/* Do the real work of setting the host charset. */ +static void +set_host_charset (const char *charset) +{ + struct charset *cs = lookup_charset_or_error (charset); + check_valid_host_charset (cs); + set_host_and_target_charsets (cs, current_target_charset); +} + +/* Do the real work of setting the target charset. */ +static void +set_target_charset (const char *charset) +{ + struct charset *cs = lookup_charset_or_error (charset); + + set_host_and_target_charsets (current_host_charset, cs); +} + + +/* 'Set charset', 'set host-charset', 'set target-charset', 'show + charset' sfunc's. */ + +/* This is the sfunc for the 'set charset' command. */ +static void +set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c) +{ + struct charset *cs = lookup_charset_or_error (host_charset_name); + check_valid_host_charset (cs); + /* CAREFUL: set the target charset here as well. */ + target_charset_name = host_charset_name; + set_host_and_target_charsets (cs, cs); +} + +/* 'set host-charset' command sfunc. We need a wrapper here because + the function needs to have a specific signature. */ +static void +set_host_charset_sfunc (char *charset, int from_tty, + struct cmd_list_element *c) +{ + set_host_charset (host_charset_name); +} + +/* Wrapper for the 'set target-charset' command. */ +static void +set_target_charset_sfunc (char *charset, int from_tty, + struct cmd_list_element *c) +{ + set_target_charset (target_charset_name); +} + +/* sfunc for the 'show charset' command. */ +static void +show_charset (char *arg, int from_tty) +{ + if (current_host_charset == current_target_charset) + { + printf_filtered ("The current host and target character set is `%s'.\n", + host_charset ()); + } + else + { + printf_filtered ("The current host character set is `%s'.\n", + host_charset ()); + printf_filtered ("The current target character set is `%s'.\n", + target_charset ()); + } +} + + +/* Accessor functions. */ + +const char * +host_charset (void) +{ + return current_host_charset->name; +} + +const char * +target_charset (void) +{ + return current_target_charset->name; +} + + + +/* Public character management functions. */ + + +const char * +c_target_char_has_backslash_escape (int target_char) +{ + return ((*c_target_char_has_backslash_escape_func) + (c_target_char_has_backslash_escape_baton, target_char)); +} + + +int +c_parse_backslash (int host_char, int *target_char) +{ + return (*c_parse_backslash_func) (c_parse_backslash_baton, + host_char, target_char); +} + + +int +host_char_print_literally (int host_char) +{ + return ((*current_host_charset->host_char_print_literally) + (current_host_charset->host_char_print_literally_baton, + host_char)); +} + + +int +target_char_to_control_char (int target_char, int *target_ctrl_char) +{ + return ((*current_target_charset->target_char_to_control_char) + (current_target_charset->target_char_to_control_char_baton, + target_char, target_ctrl_char)); +} + + +int +host_char_to_target (int host_char, int *target_char) +{ + return ((*host_char_to_target_func) + (host_char_to_target_baton, host_char, target_char)); +} + + +int +target_char_to_host (int target_char, int *host_char) +{ + return ((*target_char_to_host_func) + (target_char_to_host_baton, target_char, host_char)); +} + + + +/* The charset.c module initialization function. */ + +extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */ + +void +_initialize_charset (void) +{ + struct cmd_list_element *new_cmd; + + /* Register all the character set GDB knows about. + + You should use the same names that iconv does, where possible, to + take advantage of the iconv-based default behaviors. + + CAUTION: if you register a character set, you must also register + as many translations as are necessary to make that character set + interoperate correctly with all the other character sets. We do + provide default behaviors when no translation is available, or + when a translation's function pointer for a particular operation + is zero. Hopefully, these defaults will be correct often enough + that we won't need to provide too many translations. */ + register_charset (simple_charset ("ASCII", 1, + ascii_print_literally, 0, + ascii_to_control, 0)); + register_charset (iso_8859_family_charset ("ISO-8859-1")); + register_charset (ebcdic_family_charset ("EBCDIC-US")); + register_charset (ebcdic_family_charset ("IBM1047")); + register_iconv_charsets (); + + { + struct { char *from; char *to; int *table; } tlist[] = { + { "ASCII", "ISO-8859-1", ascii_to_iso_8859_1_table }, + { "ASCII", "EBCDIC-US", ascii_to_ebcdic_us_table }, + { "ASCII", "IBM1047", ascii_to_ibm1047_table }, + { "ISO-8859-1", "ASCII", iso_8859_1_to_ascii_table }, + { "ISO-8859-1", "EBCDIC-US", iso_8859_1_to_ebcdic_us_table }, + { "ISO-8859-1", "IBM1047", iso_8859_1_to_ibm1047_table }, + { "EBCDIC-US", "ASCII", ebcdic_us_to_ascii_table }, + { "EBCDIC-US", "ISO-8859-1", ebcdic_us_to_iso_8859_1_table }, + { "EBCDIC-US", "IBM1047", ebcdic_us_to_ibm1047_table }, + { "IBM1047", "ASCII", ibm1047_to_ascii_table }, + { "IBM1047", "ISO-8859-1", ibm1047_to_iso_8859_1_table }, + { "IBM1047", "EBCDIC-US", ibm1047_to_ebcdic_us_table } + }; + + int i; + + for (i = 0; i < (sizeof (tlist) / sizeof (tlist[0])); i++) + register_translation (simple_table_translation (tlist[i].from, + tlist[i].to, + tlist[i].table)); + } + + set_host_charset (host_charset_name); + set_target_charset (target_charset_name); + + new_cmd = add_set_enum_cmd ("charset", + class_support, + host_charset_enum, + &host_charset_name, + "Set the host and target character sets.\n" + "The `host character set' is the one used by the system GDB is running on.\n" + "The `target character set' is the one used by the program being debugged.\n" + "You may only use supersets of ASCII for your host character set; GDB does\n" + "not support any others.\n" + "To see a list of the character sets GDB supports, type `set charset '.", + &setlist); + + /* Note that the sfunc below needs to set target_charset_name, because + the 'set charset' command sets two variables. */ + set_cmd_sfunc (new_cmd, set_charset_sfunc); + /* Don't use set_from_show - need to print some extra info. */ + add_cmd ("charset", class_support, show_charset, + "Show the host and target character sets.\n" + "The `host character set' is the one used by the system GDB is running on.\n" + "The `target character set' is the one used by the program being debugged.\n" + "You may only use supersets of ASCII for your host character set; GDB does\n" + "not support any others.\n" + "To see a list of the character sets GDB supports, type `set charset '.", + &showlist); + + + new_cmd = add_set_enum_cmd ("host-charset", + class_support, + host_charset_enum, + &host_charset_name, + "Set the host character set.\n" + "The `host character set' is the one used by the system GDB is running on.\n" + "You may only use supersets of ASCII for your host character set; GDB does\n" + "not support any others.\n" + "To see a list of the character sets GDB supports, type `set host-charset '.", + &setlist); + + set_cmd_sfunc (new_cmd, set_host_charset_sfunc); + + add_show_from_set (new_cmd, &showlist); + + + + new_cmd = add_set_enum_cmd ("target-charset", + class_support, + target_charset_enum, + &target_charset_name, + "Set the target character set.\n" + "The `target character set' is the one used by the program being debugged.\n" + "GDB translates characters and strings between the host and target\n" + "character sets as needed.\n" + "To see a list of the character sets GDB supports, type `set target-charset'", + &setlist); + + set_cmd_sfunc (new_cmd, set_target_charset_sfunc); + add_show_from_set (new_cmd, &showlist); +} diff --git a/contrib/gdb/gdb/charset.h b/contrib/gdb/gdb/charset.h new file mode 100644 index 00000000000..31dbe6f9f3d --- /dev/null +++ b/contrib/gdb/gdb/charset.h @@ -0,0 +1,109 @@ +/* Character set conversion support for GDB. + Copyright 2001 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef CHARSET_H +#define CHARSET_H + + +/* If the target program uses a different character set than the host, + GDB has some support for translating between the two; GDB converts + characters and strings to the host character set before displaying + them, and converts characters and strings appearing in expressions + entered by the user to the target character set. + + At the moment, GDB only supports single-byte, stateless character + sets. This includes the ISO-8859 family (ASCII extended with + accented characters, and (I think) Cyrillic, for European + languages), and the EBCDIC family (used on IBM's mainframes). + Unfortunately, it excludes many Asian scripts, the fixed- and + variable-width Unicode encodings, and other desireable things. + Patches are welcome! (For example, it would be nice if the Java + string support could simply get absorbed into some more general + multi-byte encoding support.) + + Furthermore, GDB's code pretty much assumes that the host character + set is some superset of ASCII; there are plenty if ('0' + n) + expressions and the like. + + When the `iconv' library routine supports a character set meeting + the requirements above, it's easy to plug an entry into GDB's table + that uses iconv to handle the details. */ + +/* Return the name of the current host/target character set. The + result is owned by the charset module; the caller should not free + it. */ +const char *host_charset (void); +const char *target_charset (void); + +/* In general, the set of C backslash escapes (\n, \f) is specific to + the character set. Not all character sets will have form feed + characters, for example. + + The following functions allow GDB to parse and print control + characters in a character-set-independent way. They are both + language-specific (to C and C++) and character-set-specific. + Putting them here is a compromise. */ + + +/* If the target character TARGET_CHAR have a backslash escape in the + C language (i.e., a character like 'n' or 't'), return the host + character string that should follow the backslash. Otherwise, + return zero. + + When this function returns non-zero, the string it returns is + statically allocated; the caller is not responsible for freeing it. */ +const char *c_target_char_has_backslash_escape (int target_char); + + +/* If the host character HOST_CHAR is a valid backslash escape in the + C language for the target character set, return non-zero, and set + *TARGET_CHAR to the target character the backslash escape represents. + Otherwise, return zero. */ +int c_parse_backslash (int host_char, int *target_char); + + +/* Return non-zero if the host character HOST_CHAR can be printed + literally --- that is, if it can be readably printed as itself in a + character or string constant. Return zero if it should be printed + using some kind of numeric escape, like '\031' in C, '^(25)' in + Chill, or #25 in Pascal. */ +int host_char_print_literally (int host_char); + + +/* If the host character HOST_CHAR has an equivalent in the target + character set, set *TARGET_CHAR to that equivalent, and return + non-zero. Otherwise, return zero. */ +int host_char_to_target (int host_char, int *target_char); + + +/* If the target character TARGET_CHAR has an equivalent in the host + character set, set *HOST_CHAR to that equivalent, and return + non-zero. Otherwise, return zero. */ +int target_char_to_host (int target_char, int *host_char); + + +/* If the target character TARGET_CHAR has a corresponding control + character (also in the target character set), set *TARGET_CTRL_CHAR + to the control character, and return non-zero. Otherwise, return + zero. */ +int target_char_to_control_char (int target_char, int *target_ctrl_char); + + +#endif /* CHARSET_H */ diff --git a/contrib/gdb/gdb/cli-out.c b/contrib/gdb/gdb/cli-out.c index 9bcfa4684a1..9f48a0aa391 100644 --- a/contrib/gdb/gdb/cli-out.c +++ b/contrib/gdb/gdb/cli-out.c @@ -1,5 +1,7 @@ /* Output generating routines for GDB CLI. - Copyright 1999, 2000 Free Software Foundation, Inc. + + Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc. + Contributed by Cygnus Solutions. Written by Fernando Nasser for Cygnus. @@ -26,17 +28,13 @@ #include "gdb_string.h" #include "gdb_assert.h" -/* Convenience macro for allocting typesafe memory. */ - -#ifndef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) -#endif - struct ui_out_data { struct ui_file *stream; + struct ui_file *original_stream; int suppress_output; }; +typedef struct ui_out_data cli_out_data; /* These are the CLI output functions */ @@ -67,6 +65,7 @@ static void cli_message (struct ui_out *uiout, int verbosity, const char *format, va_list args); static void cli_wrap_hint (struct ui_out *uiout, char *identstring); static void cli_flush (struct ui_out *uiout); +static int cli_redirect (struct ui_out *uiout, struct ui_file *outstream); /* This is the CLI ui-out implementation functions vector */ @@ -90,6 +89,7 @@ static struct ui_out_impl cli_ui_out_impl = cli_message, cli_wrap_hint, cli_flush, + cli_redirect, 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ }; @@ -114,11 +114,11 @@ cli_table_begin (struct ui_out *uiout, int nbrofcols, int nr_rows, const char *tblid) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (nr_rows == 0) data->suppress_output = 1; else - /* Only the table suppresses the output and, fortunatly, a table + /* Only the table suppresses the output and, fortunately, a table is not a recursive data structure. */ gdb_assert (data->suppress_output == 0); } @@ -128,7 +128,7 @@ cli_table_begin (struct ui_out *uiout, int nbrofcols, void cli_table_body (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; /* first, close the table header line */ @@ -140,7 +140,7 @@ cli_table_body (struct ui_out *uiout) void cli_table_end (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); data->suppress_output = 0; } @@ -151,7 +151,7 @@ cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment, const char *col_name, const char *colhdr) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; cli_field_string (uiout, 0, width, alignment, 0, colhdr); @@ -165,7 +165,7 @@ cli_begin (struct ui_out *uiout, int level, const char *id) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; } @@ -177,7 +177,7 @@ cli_end (struct ui_out *uiout, enum ui_out_type type, int level) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; } @@ -191,7 +191,7 @@ cli_field_int (struct ui_out *uiout, int fldno, int width, { char buffer[20]; /* FIXME: how many chars long a %d can become? */ - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; sprintf (buffer, "%d", value); @@ -205,7 +205,7 @@ cli_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align alignment, const char *fldname) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; cli_field_string (uiout, fldno, width, alignment, fldname, ""); @@ -225,7 +225,7 @@ cli_field_string (struct ui_out *uiout, int before = 0; int after = 0; - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; @@ -272,7 +272,7 @@ cli_field_fmt (struct ui_out *uiout, int fldno, const char *format, va_list args) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; @@ -285,7 +285,7 @@ cli_field_fmt (struct ui_out *uiout, int fldno, void cli_spaces (struct ui_out *uiout, int numspaces) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; print_spaces_filtered (numspaces, data->stream); @@ -294,7 +294,7 @@ cli_spaces (struct ui_out *uiout, int numspaces) void cli_text (struct ui_out *uiout, const char *string) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; fputs_filtered (string, data->stream); @@ -304,7 +304,7 @@ void cli_message (struct ui_out *uiout, int verbosity, const char *format, va_list args) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; if (ui_out_get_verblvl (uiout) >= verbosity) @@ -314,7 +314,7 @@ cli_message (struct ui_out *uiout, int verbosity, void cli_wrap_hint (struct ui_out *uiout, char *identstring) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; wrap_here (identstring); @@ -323,10 +323,28 @@ cli_wrap_hint (struct ui_out *uiout, char *identstring) void cli_flush (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); gdb_flush (data->stream); } +int +cli_redirect (struct ui_out *uiout, struct ui_file *outstream) +{ + struct ui_out_data *data = ui_out_data (uiout); + if (outstream != NULL) + { + data->original_stream = data->stream; + data->stream = outstream; + } + else if (data->original_stream != NULL) + { + data->stream = data->original_stream; + data->original_stream = NULL; + } + + return 0; +} + /* local functions */ /* Like cli_field_fmt, but takes a variable number of args @@ -338,7 +356,7 @@ out_field_fmt (struct ui_out *uiout, int fldno, const char *fldname, const char *format,...) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); va_list args; va_start (args, format); @@ -352,7 +370,7 @@ out_field_fmt (struct ui_out *uiout, int fldno, static void field_separator (void) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = ui_out_data (uiout); fputc_filtered (' ', data->stream); } @@ -363,12 +381,22 @@ cli_out_new (struct ui_file *stream) { int flags = ui_source_list; - struct ui_out_data *data = XMALLOC (struct ui_out_data); + cli_out_data *data = XMALLOC (cli_out_data); data->stream = stream; + data->original_stream = NULL; data->suppress_output = 0; return ui_out_new (&cli_ui_out_impl, data, flags); } +struct ui_file * +cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream) +{ + cli_out_data *data = ui_out_data (uiout); + struct ui_file *old = data->stream; + data->stream = stream; + return old; +} + /* standard gdb initialization hook */ void _initialize_cli_out (void) diff --git a/contrib/gdb/gdb/cli-out.h b/contrib/gdb/gdb/cli-out.h index 723b7260cbf..8bca872fb05 100644 --- a/contrib/gdb/gdb/cli-out.h +++ b/contrib/gdb/gdb/cli-out.h @@ -22,6 +22,11 @@ #ifndef CLI_OUT_H #define CLI_OUT_H +struct ui_file; + extern struct ui_out *cli_out_new (struct ui_file *stream); +extern struct ui_file *cli_out_set_stream (struct ui_out *uiout, + struct ui_file *stream); + #endif diff --git a/contrib/gdb/gdb/cli/cli-cmds.c b/contrib/gdb/gdb/cli/cli-cmds.c index 16cc9890437..9378ac87064 100644 --- a/contrib/gdb/gdb/cli/cli-cmds.c +++ b/contrib/gdb/gdb/cli/cli-cmds.c @@ -1,6 +1,6 @@ /* GDB CLI commands. - Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -20,11 +20,23 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "readline/readline.h" +#include "readline/tilde.h" #include "completer.h" #include "target.h" /* For baud_rate, remote_debug and remote_timeout */ #include "gdb_wait.h" /* For shell escape implementation */ #include "gdb_regex.h" /* Used by apropos_command */ +#include "gdb_string.h" +#include "gdb_vfork.h" +#include "linespec.h" +#include "expression.h" +#include "frame.h" +#include "value.h" +#include "language.h" #include "filenames.h" /* for DOSish file names */ +#include "objfiles.h" +#include "source.h" +#include "disasm.h" #include "ui-out.h" @@ -34,23 +46,15 @@ #include "cli/cli-setshow.h" #include "cli/cli-cmds.h" +#ifdef TUI +#include "tui/tui.h" /* For tui_active et.al. */ +#endif + #ifndef GDBINIT_FILENAME #define GDBINIT_FILENAME ".gdbinit" #endif -/* From gdb/top.c */ - -extern void dont_repeat (void); - -extern void set_verbose (char *, int, struct cmd_list_element *); - -extern void show_history (char *, int); - -extern void set_history (char *, int); - -extern void show_commands (char *, int); - -/* Prototypes for local functions */ +/* Prototypes for local command functions */ static void complete_command (char *, int); @@ -60,8 +64,6 @@ static void pwd_command (char *, int); static void show_version (char *, int); -static void validate_comname (char *); - static void help_command (char *, int); static void show_command (char *, int); @@ -78,8 +80,19 @@ static void make_command (char *, int); static void shell_escape (char *, int); +static void edit_command (char *, int); + +static void list_command (char *, int); + void apropos_command (char *, int); + +/* Prototypes for local utility functions */ + +static void ambiguous_line_spec (struct symtabs_and_lines *); +/* Limit the call depth of user-defined commands */ +int max_user_call_depth; + /* Define all cmd_list_elements. */ /* Chain containing all defined commands. */ @@ -174,7 +187,6 @@ error_no_arg (char *why) /* The "info" command is defined as a prefix, with allow_unknown = 0. Therefore, its own definition is called only for "info" with no args. */ -/* ARGSUSED */ static void info_command (char *arg, int from_tty) { @@ -184,7 +196,6 @@ info_command (char *arg, int from_tty) /* The "show" command with no arguments shows all the settings. */ -/* ARGSUSED */ static void show_command (char *arg, int from_tty) { @@ -194,7 +205,6 @@ show_command (char *arg, int from_tty) /* Provide documentation on command or list given by COMMAND. FROM_TTY is ignored. */ -/* ARGSUSED */ static void help_command (char *command, int from_tty) { @@ -212,13 +222,12 @@ compare_strings (const void *arg1, const void *arg2) /* The "complete" command is used by Emacs to implement completion. */ -/* ARGSUSED */ static void complete_command (char *arg, int from_tty) { int i; int argpoint; - char **completions; + char **completions, *point, *arg_prefix; dont_repeat (); @@ -226,7 +235,23 @@ complete_command (char *arg, int from_tty) arg = ""; argpoint = strlen (arg); - completions = complete_line (arg, arg, argpoint); + /* complete_line assumes that its first argument is somewhere within, + and except for filenames at the beginning of, the word to be completed. + The following crude imitation of readline's word-breaking tries to + accomodate this. */ + point = arg + argpoint; + while (point > arg) + { + if (strchr (rl_completer_word_break_characters, point[-1]) != 0) + break; + point--; + } + + arg_prefix = alloca (point - arg + 1); + memcpy (arg_prefix, arg, point - arg); + arg_prefix[point - arg] = 0; + + completions = complete_line (point, arg, argpoint); if (completions) { @@ -242,7 +267,7 @@ complete_command (char *arg, int from_tty) while (item < size) { int next_item; - printf_unfiltered ("%s\n", completions[item]); + printf_unfiltered ("%s%s\n", arg_prefix, completions[item]); next_item = item + 1; while (next_item < size && ! strcmp (completions[item], completions[next_item])) @@ -265,7 +290,6 @@ is_complete_command (struct cmd_list_element *c) return cmd_cfunc_eq (c, complete_command); } -/* ARGSUSED */ static void show_version (char *args, int from_tty) { @@ -285,7 +309,6 @@ quit_command (char *args, int from_tty) quit_force (args, from_tty); } -/* ARGSUSED */ static void pwd_command (char *args, int from_tty) { @@ -293,7 +316,7 @@ pwd_command (char *args, int from_tty) error ("The \"pwd\" command does not take an argument: %s", args); getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); - if (!STREQ (gdb_dirbuf, current_directory)) + if (strcmp (gdb_dirbuf, current_directory) != 0) printf_unfiltered ("Working directory %s\n (canonically %s).\n", current_directory, gdb_dirbuf); else @@ -429,12 +452,11 @@ source_command (char *args, int from_tty) do_cleanups (old_cleanups); } -/* ARGSUSED */ static void echo_command (char *text, int from_tty) { char *p = text; - register int c; + int c; if (text) while ((c = *p++) != '\0') @@ -459,7 +481,6 @@ echo_command (char *text, int from_tty) gdb_flush (gdb_stdout); } -/* ARGSUSED */ static void shell_escape (char *arg, int from_tty) { @@ -489,23 +510,24 @@ shell_escape (char *arg, int from_tty) #endif #else /* Can fork. */ int rc, status, pid; - char *p, *user_shell; - if ((user_shell = (char *) getenv ("SHELL")) == NULL) - user_shell = "/bin/sh"; - - /* Get the name of the shell for arg0 */ - if ((p = strrchr (user_shell, '/')) == NULL) - p = user_shell; - else - p++; /* Get past '/' */ - - if ((pid = fork ()) == 0) + if ((pid = vfork ()) == 0) { - if (!arg) - execl (user_shell, p, 0); + char *p, *user_shell; + + if ((user_shell = (char *) getenv ("SHELL")) == NULL) + user_shell = "/bin/sh"; + + /* Get the name of the shell for arg0 */ + if ((p = strrchr (user_shell, '/')) == NULL) + p = user_shell; else - execl (user_shell, p, "-c", arg, 0); + p++; /* Get past '/' */ + + if (!arg) + execl (user_shell, p, (char *) 0); + else + execl (user_shell, p, "-c", arg, (char *) 0); fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell, safe_strerror (errno)); @@ -521,6 +543,378 @@ shell_escape (char *arg, int from_tty) #endif /* Can fork. */ } +static void +edit_command (char *arg, int from_tty) +{ + struct symtabs_and_lines sals; + struct symtab_and_line sal; + struct symbol *sym; + char *arg1; + int cmdlen, log10; + unsigned m; + char *editor; + char *p; + + /* Pull in the current default source line if necessary */ + if (arg == 0) + { + set_default_source_symtab_and_line (); + sal = get_current_source_symtab_and_line (); + } + + /* bare "edit" edits file with present line. */ + + if (arg == 0) + { + if (sal.symtab == 0) + error ("No default source file yet."); + sal.line += get_lines_to_list () / 2; + } + else + { + + /* Now should only be one argument -- decode it in SAL */ + + arg1 = arg; + sals = decode_line_1 (&arg1, 0, 0, 0, 0, 0); + + if (! sals.nelts) return; /* C++ */ + if (sals.nelts > 1) { + ambiguous_line_spec (&sals); + xfree (sals.sals); + return; + } + + sal = sals.sals[0]; + xfree (sals.sals); + + if (*arg1) + error ("Junk at end of line specification."); + + /* if line was specified by address, + first print exactly which line, and which file. + In this case, sal.symtab == 0 means address is outside + of all known source files, not that user failed to give a filename. */ + if (*arg == '*') + { + if (sal.symtab == 0) + /* FIXME-32x64--assumes sal.pc fits in long. */ + error ("No source file for address %s.", + local_hex_string((unsigned long) sal.pc)); + sym = find_pc_function (sal.pc); + if (sym) + { + print_address_numeric (sal.pc, 1, gdb_stdout); + printf_filtered (" is in "); + fputs_filtered (SYMBOL_PRINT_NAME (sym), gdb_stdout); + printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line); + } + else + { + print_address_numeric (sal.pc, 1, gdb_stdout); + printf_filtered (" is at %s:%d.\n", + sal.symtab->filename, sal.line); + } + } + + /* If what was given does not imply a symtab, it must be an undebuggable + symbol which means no source code. */ + + if (sal.symtab == 0) + error ("No line number known for %s.", arg); + } + + if ((editor = (char *) getenv ("EDITOR")) == NULL) + editor = "/bin/ex"; + + /* Approximate base-10 log of line to 1 unit for digit count */ + for(log10=32, m=0x80000000; !(sal.line & m) && log10>0; log10--, m=m>>1); + log10 = 1 + (int)((log10 + (0 == ((m-1) & sal.line)))/3.32192809); + + cmdlen = strlen(editor) + 1 + + (NULL == sal.symtab->dirname ? 0 : strlen(sal.symtab->dirname) + 1) + + (NULL == sal.symtab->filename? 0 : strlen(sal.symtab->filename)+ 1) + + log10 + 2; + + p = xmalloc(cmdlen); + sprintf(p,"%s +%d %s%s",editor,sal.line, + (NULL == sal.symtab->dirname ? "./" : + (NULL != sal.symtab->filename && *(sal.symtab->filename) != '/') ? + sal.symtab->dirname : ""), + (NULL == sal.symtab->filename ? "unknown" : sal.symtab->filename) + ); + shell_escape(p, from_tty); + + xfree(p); +} + +static void +list_command (char *arg, int from_tty) +{ + struct symtabs_and_lines sals, sals_end; + struct symtab_and_line sal, sal_end, cursal; + struct symbol *sym; + char *arg1; + int no_end = 1; + int dummy_end = 0; + int dummy_beg = 0; + int linenum_beg = 0; + char *p; + + /* Pull in the current default source line if necessary */ + if (arg == 0 || arg[0] == '+' || arg[0] == '-') + { + set_default_source_symtab_and_line (); + cursal = get_current_source_symtab_and_line (); + } + + /* "l" or "l +" lists next ten lines. */ + + if (arg == 0 || strcmp (arg, "+") == 0) + { + print_source_lines (cursal.symtab, cursal.line, + cursal.line + get_lines_to_list (), 0); + return; + } + + /* "l -" lists previous ten lines, the ones before the ten just listed. */ + if (strcmp (arg, "-") == 0) + { + print_source_lines (cursal.symtab, + max (get_first_line_listed () - get_lines_to_list (), 1), + get_first_line_listed (), 0); + return; + } + + /* Now if there is only one argument, decode it in SAL + and set NO_END. + If there are two arguments, decode them in SAL and SAL_END + and clear NO_END; however, if one of the arguments is blank, + set DUMMY_BEG or DUMMY_END to record that fact. */ + + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + + arg1 = arg; + if (*arg1 == ',') + dummy_beg = 1; + else + { + sals = decode_line_1 (&arg1, 0, 0, 0, 0, 0); + + if (!sals.nelts) + return; /* C++ */ + if (sals.nelts > 1) + { + ambiguous_line_spec (&sals); + xfree (sals.sals); + return; + } + + sal = sals.sals[0]; + xfree (sals.sals); + } + + /* Record whether the BEG arg is all digits. */ + + for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++); + linenum_beg = (p == arg1); + + while (*arg1 == ' ' || *arg1 == '\t') + arg1++; + if (*arg1 == ',') + { + no_end = 0; + arg1++; + while (*arg1 == ' ' || *arg1 == '\t') + arg1++; + if (*arg1 == 0) + dummy_end = 1; + else + { + if (dummy_beg) + sals_end = decode_line_1 (&arg1, 0, 0, 0, 0, 0); + else + sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0, 0); + if (sals_end.nelts == 0) + return; + if (sals_end.nelts > 1) + { + ambiguous_line_spec (&sals_end); + xfree (sals_end.sals); + return; + } + sal_end = sals_end.sals[0]; + xfree (sals_end.sals); + } + } + + if (*arg1) + error ("Junk at end of line specification."); + + if (!no_end && !dummy_beg && !dummy_end + && sal.symtab != sal_end.symtab) + error ("Specified start and end are in different files."); + if (dummy_beg && dummy_end) + error ("Two empty args do not say what lines to list."); + + /* if line was specified by address, + first print exactly which line, and which file. + In this case, sal.symtab == 0 means address is outside + of all known source files, not that user failed to give a filename. */ + if (*arg == '*') + { + if (sal.symtab == 0) + /* FIXME-32x64--assumes sal.pc fits in long. */ + error ("No source file for address %s.", + local_hex_string ((unsigned long) sal.pc)); + sym = find_pc_function (sal.pc); + if (sym) + { + print_address_numeric (sal.pc, 1, gdb_stdout); + printf_filtered (" is in "); + fputs_filtered (SYMBOL_PRINT_NAME (sym), gdb_stdout); + printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line); + } + else + { + print_address_numeric (sal.pc, 1, gdb_stdout); + printf_filtered (" is at %s:%d.\n", + sal.symtab->filename, sal.line); + } + } + + /* If line was not specified by just a line number, + and it does not imply a symtab, it must be an undebuggable symbol + which means no source code. */ + + if (!linenum_beg && sal.symtab == 0) + error ("No line number known for %s.", arg); + + /* If this command is repeated with RET, + turn it into the no-arg variant. */ + + if (from_tty) + *arg = 0; + + if (dummy_beg && sal_end.symtab == 0) + error ("No default source file yet. Do \"help list\"."); + if (dummy_beg) + print_source_lines (sal_end.symtab, + max (sal_end.line - (get_lines_to_list () - 1), 1), + sal_end.line + 1, 0); + else if (sal.symtab == 0) + error ("No default source file yet. Do \"help list\"."); + else if (no_end) + { + int first_line = sal.line - get_lines_to_list () / 2; + + if (first_line < 1) first_line = 1; + + print_source_lines (sal.symtab, + first_line, + first_line + get_lines_to_list (), + 0); + } + else + print_source_lines (sal.symtab, sal.line, + (dummy_end + ? sal.line + get_lines_to_list () + : sal_end.line + 1), + 0); +} + +/* Dump a specified section of assembly code. With no command line + arguments, this command will dump the assembly code for the + function surrounding the pc value in the selected frame. With one + argument, it will dump the assembly code surrounding that pc value. + Two arguments are interpeted as bounds within which to dump + assembly. */ + +static void +disassemble_command (char *arg, int from_tty) +{ + CORE_ADDR low, high; + char *name; + CORE_ADDR pc, pc_masked; + char *space_index; +#if 0 + asection *section; +#endif + + name = NULL; + if (!arg) + { + if (!deprecated_selected_frame) + error ("No frame selected.\n"); + + pc = get_frame_pc (deprecated_selected_frame); + if (find_pc_partial_function (pc, &name, &low, &high) == 0) + error ("No function contains program counter for selected frame.\n"); +#if defined(TUI) + /* NOTE: cagney/2003-02-13 The `tui_active' was previously + `tui_version'. */ + if (tui_active) + /* FIXME: cagney/2004-02-07: This should be an observer. */ + low = tui_get_low_disassembly_address (low, pc); +#endif + low += FUNCTION_START_OFFSET; + } + else if (!(space_index = (char *) strchr (arg, ' '))) + { + /* One argument. */ + pc = parse_and_eval_address (arg); + if (find_pc_partial_function (pc, &name, &low, &high) == 0) + error ("No function contains specified address.\n"); +#if defined(TUI) + /* NOTE: cagney/2003-02-13 The `tui_active' was previously + `tui_version'. */ + if (tui_active) + /* FIXME: cagney/2004-02-07: This should be an observer. */ + low = tui_get_low_disassembly_address (low, pc); +#endif + low += FUNCTION_START_OFFSET; + } + else + { + /* Two arguments. */ + *space_index = '\0'; + low = parse_and_eval_address (arg); + high = parse_and_eval_address (space_index + 1); + } + +#if defined(TUI) + if (!tui_is_window_visible (DISASSEM_WIN)) +#endif + { + printf_filtered ("Dump of assembler code "); + if (name != NULL) + { + printf_filtered ("for function %s:\n", name); + } + else + { + printf_filtered ("from "); + print_address_numeric (low, 1, gdb_stdout); + printf_filtered (" to "); + print_address_numeric (high, 1, gdb_stdout); + printf_filtered (":\n"); + } + + /* Dump the specified range. */ + gdb_disassembly (uiout, 0, 0, 0, -1, low, high); + + printf_filtered ("End of assembler dump.\n"); + gdb_flush (gdb_stdout); + } +#if defined(TUI) + else + { + tui_show_assembly (low); + } +#endif +} + static void make_command (char *arg, int from_tty) { @@ -538,7 +932,6 @@ make_command (char *arg, int from_tty) shell_escape (p, from_tty); } -/* ARGSUSED */ static void show_user (char *args, int from_tty) { @@ -590,6 +983,21 @@ apropos_command (char *searchstr, int from_tty) xfree (pattern_fastmap); } +/* Print a list of files and line numbers which a user may choose from + in order to list a function which was specified ambiguously (as with + `list classname::overloadedfuncname', for example). The vector in + SALS provides the filenames and line numbers. */ + +static void +ambiguous_line_spec (struct symtabs_and_lines *sals) +{ + int i; + + for (i = 0; i < sals->nelts; ++i) + printf_filtered ("file: \"%s\", line number: %d\n", + sals->sals[i].symtab->filename, sals->sals[i].line); +} + static void set_debug (char *arg, int from_tty) { @@ -606,6 +1014,8 @@ show_debug (char *args, int from_tty) void init_cmd_lists (void) { + max_user_call_depth = 1024; + cmdlist = NULL; infolist = NULL; enablelist = NULL; @@ -673,7 +1083,7 @@ The commands below can be used to select other frames by number or address.", "Set working directory to DIR for debugger and program being debugged.\n\ The change does not take effect for the program being debugged\n\ until the next time it is started.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_com ("echo", class_support, echo_command, "Print a constant string. Give string as argument.\n\ @@ -698,11 +1108,11 @@ Commands defined in this way may have up to ten arguments."); "Read commands from a file named FILE.\n\ Note that the file \"" GDBINIT_FILENAME "\" is read automatically in this way\n\ when gdb is started.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_com ("quit", class_support, quit_command, "Exit gdb."); c = add_com ("help", class_support, help_command, "Print list of commands."); - c->completer = command_completer; + set_cmd_completer (c, command_completer); add_com_alias ("q", "quit", class_support, 1); add_com_alias ("h", "help", class_support, 1); @@ -802,9 +1212,54 @@ from the target.", &setlist), &showdebuglist, "show debug ", 0, &showlist); c = add_com ("shell", class_support, shell_escape, - "Execute the rest of the line as a shell command. \n\ + "Execute the rest of the line as a shell command.\n\ With no arguments, run an inferior shell."); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); + + c = add_com ("edit", class_files, edit_command, + concat ("Edit specified file or function.\n\ +With no argument, edits file containing most recent line listed.\n\ +", "\ +Editing targets can be specified in these ways:\n\ + FILE:LINENUM, to edit at that line in that file,\n\ + FUNCTION, to edit at the beginning of that function,\n\ + FILE:FUNCTION, to distinguish among like-named static functions.\n\ + *ADDRESS, to edit at the line containing that address.\n\ +Uses EDITOR environment variable contents as editor (or ex as default).",NULL)); + + c->completer = location_completer; + + add_com ("list", class_files, list_command, + concat ("List specified function or line.\n\ +With no argument, lists ten more lines after or around previous listing.\n\ +\"list -\" lists the ten lines before a previous ten-line listing.\n\ +One argument specifies a line, and ten lines are listed around that line.\n\ +Two arguments with comma between specify starting and ending lines to list.\n\ +", "\ +Lines can be specified in these ways:\n\ + LINENUM, to list around that line in current file,\n\ + FILE:LINENUM, to list around that line in that file,\n\ + FUNCTION, to list around beginning of that function,\n\ + FILE:FUNCTION, to distinguish among like-named static functions.\n\ + *ADDRESS, to list around the line containing that address.\n\ +With two args if one is empty it stands for ten lines away from the other arg.", NULL)); + + if (!xdb_commands) + add_com_alias ("l", "list", class_files, 1); + else + add_com_alias ("v", "list", class_files, 1); + + if (dbx_commands) + add_com_alias ("file", "list", class_files, 1); + + c = add_com ("disassemble", class_vars, disassemble_command, + "Disassemble a specified section of memory.\n\ +Default is the function surrounding the pc of the selected frame.\n\ +With a single argument, the function surrounding that address is dumped.\n\ +Two arguments are taken as a range of memory to dump."); + set_cmd_completer (c, location_completer); + if (xdb_commands) + add_com_alias ("va", "disassemble", class_xdb, 0); /* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would be a really useful feature. Unfortunately, the below wont do @@ -817,10 +1272,17 @@ With no arguments, run an inferior shell."); c = add_com ("make", class_support, make_command, "Run the ``make'' program using the rest of the line as arguments."); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_cmd ("user", no_class, show_user, "Show definitions of user defined commands.\n\ Argument is the name of the user defined command.\n\ With no argument, show definitions of all user defined commands.", &showlist); add_com ("apropos", class_support, apropos_command, "Search for commands matching a REGEXP"); + + add_show_from_set ( + add_set_cmd ("max-user-call-depth", no_class, var_integer, + (char *) &max_user_call_depth, + "Set the max call depth for user-defined commands.\n", + &setlist), + &showlist); } diff --git a/contrib/gdb/gdb/cli/cli-decode.c b/contrib/gdb/gdb/cli/cli-decode.c index a13b7b8eecd..43f2f257304 100644 --- a/contrib/gdb/gdb/cli/cli-decode.c +++ b/contrib/gdb/gdb/cli/cli-decode.c @@ -22,12 +22,19 @@ #include "symtab.h" #include #include "gdb_regex.h" +#include "gdb_string.h" #include "ui-out.h" #include "cli/cli-cmds.h" #include "cli/cli-decode.h" +#ifdef TUI +#include "tui/tui.h" /* For tui_active et.al. */ +#endif + +#include "gdb_assert.h" + /* Prototypes for local functions */ static void undef_cmd_error (char *, char *); @@ -51,8 +58,7 @@ do_cfunc (struct cmd_list_element *c, char *args, int from_tty) } void -set_cmd_cfunc (struct cmd_list_element *cmd, - void (*cfunc) (char *args, int from_tty)) +set_cmd_cfunc (struct cmd_list_element *cmd, cmd_cfunc_ftype *cfunc) { if (cfunc == NULL) cmd->func = NULL; @@ -68,9 +74,7 @@ do_sfunc (struct cmd_list_element *c, char *args, int from_tty) } void -set_cmd_sfunc (struct cmd_list_element *cmd, - void (*sfunc) (char *args, int from_tty, - struct cmd_list_element * c)) +set_cmd_sfunc (struct cmd_list_element *cmd, cmd_sfunc_ftype *sfunc) { if (sfunc == NULL) cmd->func = NULL; @@ -86,6 +90,31 @@ cmd_cfunc_eq (struct cmd_list_element *cmd, return cmd->func == do_cfunc && cmd->function.cfunc == cfunc; } +void +set_cmd_context (struct cmd_list_element *cmd, void *context) +{ + cmd->context = context; +} + +void * +get_cmd_context (struct cmd_list_element *cmd) +{ + return cmd->context; +} + +enum cmd_types +cmd_type (struct cmd_list_element *cmd) +{ + return cmd->type; +} + +void +set_cmd_completer (struct cmd_list_element *cmd, + char **(*completer) (char *text, char *word)) +{ + cmd->completer = completer; /* Ok. */ +} + /* Add element named NAME. CLASS is the top level category into which commands are broken down @@ -108,7 +137,7 @@ struct cmd_list_element * add_cmd (char *name, enum command_class class, void (*fun) (char *, int), char *doc, struct cmd_list_element **list) { - register struct cmd_list_element *c + struct cmd_list_element *c = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); struct cmd_list_element *p; @@ -133,6 +162,7 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int), c->name = name; c->class = class; set_cmd_cfunc (c, fun); + set_cmd_context (c, NULL); c->doc = doc; c->flags = 0; c->replacement = NULL; @@ -144,7 +174,7 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int), c->prefixname = NULL; c->allow_unknown = 0; c->abbrev_flag = 0; - c->completer = make_symbol_completion_list; + set_cmd_completer (c, make_symbol_completion_list); c->type = not_set_cmd; c->var = NULL; c->var_type = var_boolean; @@ -157,20 +187,6 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int), return c; } -/* Same as above, except that the abbrev_flag is set. */ -/* Note: Doesn't seem to be used anywhere currently. */ - -struct cmd_list_element * -add_abbrev_cmd (char *name, enum command_class class, void (*fun) (char *, int), - char *doc, struct cmd_list_element **list) -{ - register struct cmd_list_element *c - = add_cmd (name, class, fun, doc, list); - - c->abbrev_flag = 1; - return c; -} - /* Deprecates a command CMD. REPLACEMENT is the name of the command which should be used in place of this command, or NULL if no such command exists. @@ -200,8 +216,8 @@ add_alias_cmd (char *name, char *oldname, enum command_class class, { /* Must do this since lookup_cmd tries to side-effect its first arg */ char *copied_name; - register struct cmd_list_element *old; - register struct cmd_list_element *c; + struct cmd_list_element *old; + struct cmd_list_element *c; copied_name = (char *) alloca (strlen (oldname) + 1); strcpy (copied_name, oldname); old = lookup_cmd (&copied_name, *list, "", 1, 1); @@ -235,7 +251,7 @@ add_prefix_cmd (char *name, enum command_class class, void (*fun) (char *, int), char *prefixname, int allow_unknown, struct cmd_list_element **list) { - register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); + struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); c->prefixlist = prefixlist; c->prefixname = prefixname; c->allow_unknown = allow_unknown; @@ -250,7 +266,7 @@ add_abbrev_prefix_cmd (char *name, enum command_class class, struct cmd_list_element **prefixlist, char *prefixname, int allow_unknown, struct cmd_list_element **list) { - register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); + struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); c->prefixlist = prefixlist; c->prefixname = prefixname; c->allow_unknown = allow_unknown; @@ -272,13 +288,90 @@ empty_sfunc (char *args, int from_tty, struct cmd_list_element *c) { } -/* Add element named NAME to command list LIST (the list for set +/* Add element named NAME to command list LIST (the list for set/show or some sublist thereof). + TYPE is set_cmd or show_cmd. CLASS is as in add_cmd. VAR_TYPE is the kind of thing we are setting. VAR is address of the variable being controlled by this command. DOC is the documentation string. */ +static struct cmd_list_element * +add_set_or_show_cmd (char *name, + enum cmd_types type, + enum command_class class, + var_types var_type, + void *var, + char *doc, + struct cmd_list_element **list) +{ + struct cmd_list_element *c = add_cmd (name, class, NULL, doc, list); + gdb_assert (type == set_cmd || type == show_cmd); + c->type = type; + c->var_type = var_type; + c->var = var; + /* This needs to be something besides NULL so that this isn't + treated as a help class. */ + set_cmd_sfunc (c, empty_sfunc); + return c; +} + +/* Add element named NAME to both the command SET_LIST and SHOW_LIST. + CLASS is as in add_cmd. VAR_TYPE is the kind of thing we are + setting. VAR is address of the variable being controlled by this + command. SET_FUNC and SHOW_FUNC are the callback functions (if + non-NULL). SET_DOC and SHOW_DOC are the documentation strings. + SET_RESULT and SHOW_RESULT, if not NULL, are set to the resulting + command structures. */ + +void +add_setshow_cmd_full (char *name, + enum command_class class, + var_types var_type, void *var, + char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list, + struct cmd_list_element **set_result, + struct cmd_list_element **show_result) +{ + struct cmd_list_element *set; + struct cmd_list_element *show; + set = add_set_or_show_cmd (name, set_cmd, class, var_type, var, + set_doc, set_list); + if (set_func != NULL) + set_cmd_sfunc (set, set_func); + show = add_set_or_show_cmd (name, show_cmd, class, var_type, var, + show_doc, show_list); + if (show_func != NULL) + set_cmd_sfunc (show, show_func); + + if (set_result != NULL) + *set_result = set; + if (show_result != NULL) + *show_result = show; +} + +/* Add element named NAME to both the command SET_LIST and SHOW_LIST. + CLASS is as in add_cmd. VAR_TYPE is the kind of thing we are + setting. VAR is address of the variable being controlled by this + command. SET_FUNC and SHOW_FUNC are the callback functions (if + non-NULL). SET_DOC and SHOW_DOC are the documentation strings. */ + +void +add_setshow_cmd (char *name, + enum command_class class, + var_types var_type, void *var, + char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list) +{ + add_setshow_cmd_full (name, class, var_type, var, set_doc, show_doc, + set_func, show_func, set_list, show_list, + NULL, NULL); +} + struct cmd_list_element * add_set_cmd (char *name, enum command_class class, @@ -287,15 +380,7 @@ add_set_cmd (char *name, char *doc, struct cmd_list_element **list) { - struct cmd_list_element *c = add_cmd (name, class, NULL, doc, list); - - c->type = set_cmd; - c->var_type = var_type; - c->var = var; - /* This needs to be something besides NULL so that this isn't - treated as a help class. */ - set_cmd_sfunc (c, empty_sfunc); - return c; + return add_set_or_show_cmd (name, set_cmd, class, var_type, var, doc, list); } /* Add element named NAME to command list LIST (the list for set @@ -321,83 +406,97 @@ add_set_enum_cmd (char *name, return c; } -/* Add element named NAME to command list LIST (the list for set - or some sublist thereof). - CLASS is as in add_cmd. - VAR is address of the variable which will contain the value. - DOC is the documentation string. */ -struct cmd_list_element * -add_set_auto_boolean_cmd (char *name, - enum command_class class, - enum cmd_auto_boolean *var, - char *doc, - struct cmd_list_element **list) +/* Add an auto-boolean command named NAME to both the set and show + command list lists. CLASS is as in add_cmd. VAR is address of the + variable which will contain the value. DOC is the documentation + string. FUNC is the corresponding callback. */ +void +add_setshow_auto_boolean_cmd (char *name, + enum command_class class, + enum auto_boolean *var, + char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list) { static const char *auto_boolean_enums[] = { "on", "off", "auto", NULL }; struct cmd_list_element *c; - c = add_set_cmd (name, class, var_auto_boolean, var, doc, list); + add_setshow_cmd_full (name, class, var_auto_boolean, var, + set_doc, show_doc, set_func, show_func, + set_list, show_list, + &c, NULL); c->enums = auto_boolean_enums; - return c; } -/* Add element named NAME to command list LIST (the list for set - or some sublist thereof). - CLASS is as in add_cmd. - VAR is address of the variable which will contain the value. - DOC is the documentation string. */ -struct cmd_list_element * -add_set_boolean_cmd (char *name, - enum command_class class, - int *var, - char *doc, - struct cmd_list_element **list) +/* Add element named NAME to both the set and show command LISTs (the + list for set/show or some sublist thereof). CLASS is as in + add_cmd. VAR is address of the variable which will contain the + value. SET_DOC and SHOW_DOR are the documentation strings. */ +void +add_setshow_boolean_cmd (char *name, + enum command_class class, + int *var, char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list) { static const char *boolean_enums[] = { "on", "off", NULL }; struct cmd_list_element *c; - c = add_set_cmd (name, class, var_boolean, var, doc, list); + add_setshow_cmd_full (name, class, var_boolean, var, + set_doc, show_doc, + set_func, show_func, + set_list, show_list, + &c, NULL); c->enums = boolean_enums; - return c; +} + +/* Add element named NAME to both the set and show command LISTs (the + list for set/show or some sublist thereof). CLASS is as in + add_cmd. VAR is address of the variable which will contain the + value. SET_DOC and SHOW_DOR are the documentation strings. */ +void +add_setshow_uinteger_cmd (char *name, + enum command_class class, + unsigned int *var, char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list) +{ + add_setshow_cmd_full (name, class, var_uinteger, var, + set_doc, show_doc, + set_func, show_func, + set_list, show_list, + NULL, NULL); } /* Where SETCMD has already been added, add the corresponding show - command to LIST and return a pointer to the added command (not + command to LIST and return a pointer to the added command (not necessarily the head of LIST). */ +/* NOTE: cagney/2002-03-17: The original version of add_show_from_set + used memcpy() to clone `set' into `show'. This meant that in + addition to all the needed fields (var, name, et.al.) some + unnecessary fields were copied (namely the callback function). The + function explictly copies relevant fields. For a `set' and `show' + command to share the same callback, the caller must set both + explicitly. */ struct cmd_list_element * add_show_from_set (struct cmd_list_element *setcmd, struct cmd_list_element **list) { - struct cmd_list_element *showcmd = - (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); - struct cmd_list_element *p; + char *doc; + const static char setstring[] = "Set "; - memcpy (showcmd, setcmd, sizeof (struct cmd_list_element)); - delete_cmd (showcmd->name, list); - showcmd->type = show_cmd; + /* Create a doc string by replacing "Set " at the start of the + `set'' command's doco with "Show ". */ + gdb_assert (strncmp (setcmd->doc, setstring, sizeof (setstring) - 1) == 0); + doc = concat ("Show ", setcmd->doc + sizeof (setstring) - 1, NULL); - /* Replace "set " at start of docstring with "show ". */ - if (setcmd->doc[0] == 'S' && setcmd->doc[1] == 'e' - && setcmd->doc[2] == 't' && setcmd->doc[3] == ' ') - showcmd->doc = concat ("Show ", setcmd->doc + 4, NULL); - else - fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n"); - - if (*list == NULL || strcmp ((*list)->name, showcmd->name) >= 0) - { - showcmd->next = *list; - *list = showcmd; - } - else - { - p = *list; - while (p->next && strcmp (p->next->name, showcmd->name) <= 0) - { - p = p->next; - } - showcmd->next = p->next; - p->next = showcmd; - } - - return showcmd; + /* Insert the basic command. */ + return add_set_or_show_cmd (setcmd->name, show_cmd, setcmd->class, + setcmd->var_type, setcmd->var, doc, list); } /* Remove the command named NAME from the command list. */ @@ -405,10 +504,10 @@ add_show_from_set (struct cmd_list_element *setcmd, void delete_cmd (char *name, struct cmd_list_element **list) { - register struct cmd_list_element *c; + struct cmd_list_element *c; struct cmd_list_element *p; - while (*list && STREQ ((*list)->name, name)) + while (*list && strcmp ((*list)->name, name) == 0) { if ((*list)->hookee_pre) (*list)->hookee_pre->hook_pre = 0; /* Hook slips out of its mouth */ @@ -422,7 +521,7 @@ delete_cmd (char *name, struct cmd_list_element **list) if (*list) for (c = *list; c->next;) { - if (STREQ (c->next->name, name)) + if (strcmp (c->next->name, name) == 0) { if (c->next->hookee_pre) c->next->hookee_pre->hook_pre = 0; /* hooked cmd gets away. */ @@ -482,7 +581,7 @@ void apropos_cmd (struct ui_file *stream, struct cmd_list_element *commandlist, struct re_pattern_buffer *regex, char *prefix) { - register struct cmd_list_element *c; + struct cmd_list_element *c; int returnvalue=1; /*Needed to avoid double printing*/ /* Walk through the commands */ for (c=commandlist;c;c=c->next) @@ -645,14 +744,24 @@ help_list (struct cmd_list_element *list, char *cmdtype, help_cmd_list (list, class, cmdtype, (int) class >= 0, stream); if (class == all_classes) - fprintf_filtered (stream, "\n\ -Type \"help%s\" followed by a class name for a list of commands in that class.", - cmdtype1); + { + fprintf_filtered (stream, "\n\ +Type \"help%s\" followed by a class name for a list of commands in ", + cmdtype1); + wrap_here (""); + fprintf_filtered (stream, "that class."); + } - fprintf_filtered (stream, "\n\ -Type \"help%s\" followed by %scommand name for full documentation.\n\ -Command name abbreviations are allowed if unambiguous.\n", + fprintf_filtered (stream, "\nType \"help%s\" followed by %scommand name ", cmdtype1, cmdtype2); + wrap_here (""); + fputs_filtered ("for ", stream); + wrap_here (""); + fputs_filtered ("full ", stream); + wrap_here (""); + fputs_filtered ("documentation.\n", stream); + fputs_filtered ("Command name abbreviations are allowed if unambiguous.\n", + stream); } static void @@ -681,7 +790,7 @@ print_doc_line (struct ui_file *stream, char *str) { static char *line_buffer = 0; static int line_size; - register char *p; + char *p; if (!line_buffer) { @@ -725,7 +834,7 @@ void help_cmd_list (struct cmd_list_element *list, enum command_class class, char *prefix, int recurse, struct ui_file *stream) { - register struct cmd_list_element *c; + struct cmd_list_element *c; for (c = list; c; c = c->next) { @@ -824,10 +933,14 @@ lookup_cmd_1 (char **text, struct cmd_list_element *clist, /* Treating underscores as part of command words is important so that "set args_foo()" doesn't get interpreted as "set args _foo()". */ + /* NOTE: cagney/2003-02-13 The `tui_active' was previously + `tui_version'. */ for (p = *text; *p && (isalnum (*p) || *p == '-' || *p == '_' || - (tui_version && +#if defined(TUI) + (tui_active && (*p == '+' || *p == '<' || *p == '>' || *p == '$')) || +#endif (xdb_commands && (*p == '!' || *p == '/' || *p == '?'))); p++) ; @@ -949,7 +1062,7 @@ undef_cmd_error (char *cmdtype, char *q) cmdtype, q, *cmdtype ? " " : "", - strlen (cmdtype) - 1, + (int) strlen (cmdtype) - 1, cmdtype); } @@ -1194,10 +1307,14 @@ lookup_cmd_composition (char *text, /* Treating underscores as part of command words is important so that "set args_foo()" doesn't get interpreted as "set args _foo()". */ + /* NOTE: cagney/2003-02-13 The `tui_active' was previously + `tui_version'. */ for (p = text; *p && (isalnum (*p) || *p == '-' || *p == '_' || - (tui_version && +#if defined(TUI) + (tui_active && (*p == '+' || *p == '<' || *p == '>' || *p == '$')) || +#endif (xdb_commands && (*p == '!' || *p == '/' || *p == '?'))); p++) ; @@ -1407,3 +1524,23 @@ complete_on_enum (const char *enumlist[], return matchlist; } + +/* check function pointer */ +int +cmd_func_p (struct cmd_list_element *cmd) +{ + return (cmd->func != NULL); +} + + +/* call the command function */ +void +cmd_func (struct cmd_list_element *cmd, char *args, int from_tty) +{ + if (cmd_func_p (cmd)) + (*cmd->func) (cmd, args, from_tty); + else + error ("Invalid command"); +} + + diff --git a/contrib/gdb/gdb/cli/cli-decode.h b/contrib/gdb/gdb/cli/cli-decode.h index e4b7c5566ad..d8ab67d49f0 100644 --- a/contrib/gdb/gdb/cli/cli-decode.h +++ b/contrib/gdb/gdb/cli/cli-decode.h @@ -1,5 +1,6 @@ /* Header file for GDB command decoding library. - Copyright 2000 Free Software Foundation, Inc. + + Copyright 2000, 2003 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 @@ -19,25 +20,13 @@ #if !defined (CLI_DECODE_H) #define CLI_DECODE_H 1 -#include "gdb_regex.h" /* Needed by apropos_cmd. */ +#include "command.h" -/* Command classes are top-level categories into which commands are broken - down for "help" purposes. - Notes on classes: class_alias is for alias commands which are not - abbreviations of the original command. class-pseudo is for - commands which are not really commands nor help topics ("stop"). */ - -enum command_class -{ - /* Special args to help_list */ - class_deprecated, all_classes = -2, all_commands = -1, - /* Classes of commands */ - no_class = -1, class_run = 0, class_vars, class_stack, - class_files, class_support, class_info, class_breakpoint, class_trace, - class_alias, class_obscure, class_user, class_maintenance, - class_pseudo, class_tui, class_xdb -}; +struct re_pattern_buffer; +#if 0 +/* FIXME: cagney/2002-03-17: Once cmd_type() has been removed, ``enum + cmd_types'' can be moved from "command.h" to "cli-decode.h". */ /* Not a set/show command. Note that some commands which begin with "set" or "show" might be in this category, if their syntax does not fall into one of the following categories. */ @@ -48,55 +37,7 @@ typedef enum cmd_types show_cmd } cmd_types; - -/* Reasonable values for an AUTO_BOOLEAN variable. */ -enum cmd_auto_boolean -{ - CMD_AUTO_BOOLEAN_TRUE, - CMD_AUTO_BOOLEAN_FALSE, - CMD_AUTO_BOOLEAN_AUTO -}; - -/* Types of "set" or "show" command. */ -typedef enum var_types - { - /* "on" or "off". *VAR is an integer which is nonzero for on, - zero for off. */ - var_boolean, - - /* "on" / "true" / "enable" or "off" / "false" / "disable" or - "auto. *VAR is an ``enum cmd_auto_boolean''. NOTE: In general - a custom show command will need to be implemented - one that - for "auto" prints both the "auto" and the current auto-selected - value. */ - var_auto_boolean, - - /* Unsigned Integer. *VAR is an unsigned int. The user can type 0 - to mean "unlimited", which is stored in *VAR as UINT_MAX. */ - var_uinteger, - - /* Like var_uinteger but signed. *VAR is an int. The user can type 0 - to mean "unlimited", which is stored in *VAR as INT_MAX. */ - var_integer, - - /* String which the user enters with escapes (e.g. the user types \n and - it is a real newline in the stored string). - *VAR is a malloc'd string, or NULL if the string is empty. */ - var_string, - /* String which stores what the user types verbatim. - *VAR is a malloc'd string, or NULL if the string is empty. */ - var_string_noescape, - /* String which stores a filename. - *VAR is a malloc'd string, or NULL if the string is empty. */ - var_filename, - /* ZeroableInteger. *VAR is an int. Like Unsigned Integer except - that zero really means zero. */ - var_zinteger, - /* Enumerated type. Can only have one of the specified values. *VAR is a - char pointer to the name of the element that we find. */ - var_enum - } -var_types; +#endif /* This structure records one command'd definition. */ @@ -130,15 +71,17 @@ struct cmd_list_element to one of the below. */ union { - /* If type is not_set_cmd, call it like this: */ - void (*cfunc) (char *args, int from_tty); - - /* If type is set_cmd or show_cmd, first set the variables, and - then call this. */ - void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c); + /* If type is not_set_cmd, call it like this: */ + cmd_cfunc_ftype *cfunc; + /* If type is set_cmd or show_cmd, first set the variables, + and then call this: */ + cmd_sfunc_ftype *sfunc; } function; + /* Local state (context) for this command. This can be anything. */ + void *context; + /* Documentation of this command (or help topic). First line is brief documentation; remaining lines form, with it, the full documentation. First line should end with a period. @@ -286,11 +229,18 @@ extern void set_cmd_sfunc (struct cmd_list_element *cmd, void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c)); +extern void set_cmd_completer (struct cmd_list_element *cmd, + char **(*completer) (char *text, char *word)); + /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs around in cmd objects to test the value of the commands sfunc(). */ extern int cmd_cfunc_eq (struct cmd_list_element *cmd, void (*cfunc) (char *args, int from_tty)); +/* Access to the command's local context. */ +extern void set_cmd_context (struct cmd_list_element *cmd, void *context); +extern void *get_cmd_context (struct cmd_list_element *cmd); + extern struct cmd_list_element *lookup_cmd (char **, struct cmd_list_element *, char *, int, int); @@ -345,18 +295,6 @@ extern struct cmd_list_element *add_set_enum_cmd (char *name, char *doc, struct cmd_list_element **list); -extern struct cmd_list_element *add_set_auto_boolean_cmd (char *name, - enum command_class class, - enum cmd_auto_boolean *var, - char *doc, - struct cmd_list_element **list); - -extern struct cmd_list_element *add_set_boolean_cmd (char *name, - enum command_class class, - int *var, - char *doc, - struct cmd_list_element **list); - extern struct cmd_list_element *add_show_from_set (struct cmd_list_element *, struct cmd_list_element **); diff --git a/contrib/gdb/gdb/cli/cli-dump.c b/contrib/gdb/gdb/cli/cli-dump.c new file mode 100644 index 00000000000..ac54aa675b9 --- /dev/null +++ b/contrib/gdb/gdb/cli/cli-dump.c @@ -0,0 +1,796 @@ +/* Dump-to-file commands, for GDB, the GNU debugger. + + Copyright 2002 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_string.h" +#include "cli/cli-decode.h" +#include "cli/cli-cmds.h" +#include "value.h" +#include "completer.h" +#include "cli/cli-dump.h" +#include "gdb_assert.h" +#include +#include "target.h" +#include "readline/readline.h" + +#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) + + +char * +skip_spaces (char *chp) +{ + if (chp == NULL) + return NULL; + while (isspace (*chp)) + chp++; + return chp; +} + +char * +scan_expression_with_cleanup (char **cmd, const char *def) +{ + if ((*cmd) == NULL || (**cmd) == '\0') + { + char *exp = xstrdup (def); + make_cleanup (xfree, exp); + return exp; + } + else + { + char *exp; + char *end; + + end = (*cmd) + strcspn (*cmd, " \t"); + exp = savestring ((*cmd), end - (*cmd)); + make_cleanup (xfree, exp); + (*cmd) = skip_spaces (end); + return exp; + } +} + + +static void +do_fclose_cleanup (void *arg) +{ + FILE *file = arg; + fclose (arg); +} + +static struct cleanup * +make_cleanup_fclose (FILE *file) +{ + return make_cleanup (do_fclose_cleanup, file); +} + +char * +scan_filename_with_cleanup (char **cmd, const char *defname) +{ + char *filename; + char *fullname; + + /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */ + + /* File. */ + if ((*cmd) == NULL) + { + if (defname == NULL) + error ("Missing filename."); + filename = xstrdup (defname); + make_cleanup (xfree, filename); + } + else + { + /* FIXME: should parse a possibly quoted string. */ + char *end; + + (*cmd) = skip_spaces (*cmd); + end = *cmd + strcspn (*cmd, " \t"); + filename = savestring ((*cmd), end - (*cmd)); + make_cleanup (xfree, filename); + (*cmd) = skip_spaces (end); + } + gdb_assert (filename != NULL); + + fullname = tilde_expand (filename); + make_cleanup (xfree, fullname); + + return fullname; +} + +FILE * +fopen_with_cleanup (char *filename, const char *mode) +{ + FILE *file = fopen (filename, mode); + if (file == NULL) + perror_with_name (filename); + make_cleanup_fclose (file); + return file; +} + +static bfd * +bfd_openr_with_cleanup (const char *filename, const char *target) +{ + bfd *ibfd; + + ibfd = bfd_openr (filename, target); + if (ibfd == NULL) + error ("Failed to open %s: %s.", filename, + bfd_errmsg (bfd_get_error ())); + + make_cleanup_bfd_close (ibfd); + if (!bfd_check_format (ibfd, bfd_object)) + error ("'%s' is not a recognized file format.", filename); + + return ibfd; +} + +static bfd * +bfd_openw_with_cleanup (char *filename, const char *target, char *mode) +{ + bfd *obfd; + + if (*mode == 'w') /* Write: create new file */ + { + obfd = bfd_openw (filename, target); + if (obfd == NULL) + error ("Failed to open %s: %s.", filename, + bfd_errmsg (bfd_get_error ())); + make_cleanup_bfd_close (obfd); + if (!bfd_set_format (obfd, bfd_object)) + error ("bfd_openw_with_cleanup: %s.", bfd_errmsg (bfd_get_error ())); + } + else if (*mode == 'a') /* Append to existing file */ + { /* FIXME -- doesn't work... */ + error ("bfd_openw does not work with append."); + } + else + error ("bfd_openw_with_cleanup: unknown mode %s.", mode); + + return obfd; +} + +struct cmd_list_element *dump_cmdlist; +struct cmd_list_element *append_cmdlist; +struct cmd_list_element *srec_cmdlist; +struct cmd_list_element *ihex_cmdlist; +struct cmd_list_element *tekhex_cmdlist; +struct cmd_list_element *binary_dump_cmdlist; +struct cmd_list_element *binary_append_cmdlist; + +static void +dump_command (char *cmd, int from_tty) +{ + printf_unfiltered ("\"dump\" must be followed by a subcommand.\n\n"); + help_list (dump_cmdlist, "dump ", -1, gdb_stdout); +} + +static void +append_command (char *cmd, int from_tty) +{ + printf_unfiltered ("\"append\" must be followed by a subcommand.\n\n"); + help_list (dump_cmdlist, "append ", -1, gdb_stdout); +} + +static void +dump_binary_file (char *filename, char *mode, + char *buf, int len) +{ + FILE *file; + int status; + + file = fopen_with_cleanup (filename, mode); + status = fwrite (buf, len, 1, file); + if (status != 1) + perror_with_name (filename); +} + +static void +dump_bfd_file (char *filename, char *mode, + char *target, CORE_ADDR vaddr, + char *buf, int len) +{ + bfd *obfd; + asection *osection; + + obfd = bfd_openw_with_cleanup (filename, target, mode); + osection = bfd_make_section_anyway (obfd, ".newsec"); + bfd_set_section_size (obfd, osection, len); + bfd_set_section_vma (obfd, osection, vaddr); + bfd_set_section_alignment (obfd, osection, 0); + bfd_set_section_flags (obfd, osection, 0x203); + osection->entsize = 0; + bfd_set_section_contents (obfd, osection, buf, 0, len); +} + +static void +dump_memory_to_file (char *cmd, char *mode, char *file_format) +{ + struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); + CORE_ADDR lo; + CORE_ADDR hi; + ULONGEST count; + char *filename; + void *buf; + char *lo_exp; + char *hi_exp; + int len; + + /* Open the file. */ + filename = scan_filename_with_cleanup (&cmd, NULL); + + /* Find the low address. */ + if (cmd == NULL || *cmd == '\0') + error ("Missing start address."); + lo_exp = scan_expression_with_cleanup (&cmd, NULL); + + /* Find the second address - rest of line. */ + if (cmd == NULL || *cmd == '\0') + error ("Missing stop address."); + hi_exp = cmd; + + lo = parse_and_eval_address (lo_exp); + hi = parse_and_eval_address (hi_exp); + if (hi <= lo) + error ("Invalid memory address range (start >= end)."); + count = hi - lo; + + /* FIXME: Should use read_memory_partial() and a magic blocking + value. */ + buf = xmalloc (count); + make_cleanup (xfree, buf); + target_read_memory (lo, buf, count); + + /* Have everything. Open/write the data. */ + if (file_format == NULL || strcmp (file_format, "binary") == 0) + { + dump_binary_file (filename, mode, buf, count); + } + else + { + dump_bfd_file (filename, mode, file_format, lo, buf, count); + } + + do_cleanups (old_cleanups); +} + +static void +dump_memory_command (char *cmd, char *mode) +{ + dump_memory_to_file (cmd, mode, "binary"); +} + +static void +dump_value_to_file (char *cmd, char *mode, char *file_format) +{ + struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); + struct value *val; + char *filename; + + /* Open the file. */ + filename = scan_filename_with_cleanup (&cmd, NULL); + + /* Find the value. */ + if (cmd == NULL || *cmd == '\0') + error ("No value to %s.", *mode == 'a' ? "append" : "dump"); + val = parse_and_eval (cmd); + if (val == NULL) + error ("Invalid expression."); + + /* Have everything. Open/write the data. */ + if (file_format == NULL || strcmp (file_format, "binary") == 0) + { + dump_binary_file (filename, mode, VALUE_CONTENTS (val), + TYPE_LENGTH (VALUE_TYPE (val))); + } + else + { + CORE_ADDR vaddr; + + if (VALUE_LVAL (val)) + { + vaddr = VALUE_ADDRESS (val); + } + else + { + vaddr = 0; + warning ("value is not an lval: address assumed to be zero"); + } + + dump_bfd_file (filename, mode, file_format, vaddr, + VALUE_CONTENTS (val), + TYPE_LENGTH (VALUE_TYPE (val))); + } + + do_cleanups (old_cleanups); +} + +static void +dump_value_command (char *cmd, char *mode) +{ + dump_value_to_file (cmd, mode, "binary"); +} + +static void +dump_srec_memory (char *args, int from_tty) +{ + dump_memory_to_file (args, FOPEN_WB, "srec"); +} + +static void +dump_srec_value (char *args, int from_tty) +{ + dump_value_to_file (args, FOPEN_WB, "srec"); +} + +static void +dump_ihex_memory (char *args, int from_tty) +{ + dump_memory_to_file (args, FOPEN_WB, "ihex"); +} + +static void +dump_ihex_value (char *args, int from_tty) +{ + dump_value_to_file (args, FOPEN_WB, "ihex"); +} + +static void +dump_tekhex_memory (char *args, int from_tty) +{ + dump_memory_to_file (args, FOPEN_WB, "tekhex"); +} + +static void +dump_tekhex_value (char *args, int from_tty) +{ + dump_value_to_file (args, FOPEN_WB, "tekhex"); +} + +static void +dump_binary_memory (char *args, int from_tty) +{ + dump_memory_to_file (args, FOPEN_WB, "binary"); +} + +static void +dump_binary_value (char *args, int from_tty) +{ + dump_value_to_file (args, FOPEN_WB, "binary"); +} + +static void +append_binary_memory (char *args, int from_tty) +{ + dump_memory_to_file (args, FOPEN_AB, "binary"); +} + +static void +append_binary_value (char *args, int from_tty) +{ + dump_value_to_file (args, FOPEN_AB, "binary"); +} + +struct dump_context +{ + void (*func) (char *cmd, char *mode); + char *mode; +}; + +static void +call_dump_func (struct cmd_list_element *c, char *args, int from_tty) +{ + struct dump_context *d = get_cmd_context (c); + d->func (args, d->mode); +} + +void +add_dump_command (char *name, void (*func) (char *args, char *mode), + char *descr) + +{ + struct cmd_list_element *c; + struct dump_context *d; + + c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist); + c->completer = filename_completer; + d = XMALLOC (struct dump_context); + d->func = func; + d->mode = FOPEN_WB; + set_cmd_context (c, d); + c->func = call_dump_func; + + c = add_cmd (name, all_commands, NULL, descr, &append_cmdlist); + c->completer = filename_completer; + d = XMALLOC (struct dump_context); + d->func = func; + d->mode = FOPEN_AB; + set_cmd_context (c, d); + c->func = call_dump_func; + + /* Replace "Dump " at start of docstring with "Append " + (borrowed from add_show_from_set). */ + if ( c->doc[0] == 'W' + && c->doc[1] == 'r' + && c->doc[2] == 'i' + && c->doc[3] == 't' + && c->doc[4] == 'e' + && c->doc[5] == ' ') + c->doc = concat ("Append ", c->doc + 6, NULL); +} + +/* Opaque data for restore_section_callback. */ +struct callback_data { + unsigned long load_offset; + CORE_ADDR load_start; + CORE_ADDR load_end; +}; + +/* Function: restore_section_callback. + + Callback function for bfd_map_over_sections. + Selectively loads the sections into memory. */ + +static void +restore_section_callback (bfd *ibfd, asection *isec, void *args) +{ + struct callback_data *data = args; + bfd_vma sec_start = bfd_section_vma (ibfd, isec); + bfd_size_type size = bfd_section_size (ibfd, isec); + bfd_vma sec_end = sec_start + size; + bfd_size_type sec_offset = 0; + bfd_size_type sec_load_count = size; + struct cleanup *old_chain; + char *buf; + int ret; + + /* Ignore non-loadable sections, eg. from elf files. */ + if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD)) + return; + + /* Does the section overlap with the desired restore range? */ + if (sec_end <= data->load_start + || (data->load_end > 0 && sec_start >= data->load_end)) + { + /* No, no useable data in this section. */ + printf_filtered ("skipping section %s...\n", + bfd_section_name (ibfd, isec)); + return; + } + + /* Compare section address range with user-requested + address range (if any). Compute where the actual + transfer should start and end. */ + if (sec_start < data->load_start) + sec_offset = data->load_start - sec_start; + /* Size of a partial transfer: */ + sec_load_count -= sec_offset; + if (data->load_end > 0 && sec_end > data->load_end) + sec_load_count -= sec_end - data->load_end; + + /* Get the data. */ + buf = xmalloc (size); + old_chain = make_cleanup (xfree, buf); + if (!bfd_get_section_contents (ibfd, isec, buf, 0, size)) + error ("Failed to read bfd file %s: '%s'.", bfd_get_filename (ibfd), + bfd_errmsg (bfd_get_error ())); + + printf_filtered ("Restoring section %s (0x%lx to 0x%lx)", + bfd_section_name (ibfd, isec), + (unsigned long) sec_start, + (unsigned long) sec_end); + + if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0) + printf_filtered (" into memory (0x%s to 0x%s)\n", + paddr_nz ((unsigned long) sec_start + + sec_offset + data->load_offset), + paddr_nz ((unsigned long) sec_start + sec_offset + + data->load_offset + sec_load_count)); + else + puts_filtered ("\n"); + + /* Write the data. */ + ret = target_write_memory (sec_start + sec_offset + data->load_offset, + buf + sec_offset, sec_load_count); + if (ret != 0) + warning ("restore: memory write failed (%s).", safe_strerror (ret)); + do_cleanups (old_chain); + return; +} + +static void +restore_binary_file (char *filename, struct callback_data *data) +{ + FILE *file = fopen_with_cleanup (filename, FOPEN_RB); + int status; + char *buf; + long len; + + /* Get the file size for reading. */ + if (fseek (file, 0, SEEK_END) == 0) + len = ftell (file); + else + perror_with_name (filename); + + if (len <= data->load_start) + error ("Start address is greater than length of binary file %s.", + filename); + + /* Chop off "len" if it exceeds the requested load_end addr. */ + if (data->load_end != 0 && data->load_end < len) + len = data->load_end; + /* Chop off "len" if the requested load_start addr skips some bytes. */ + if (data->load_start > 0) + len -= data->load_start; + + printf_filtered + ("Restoring binary file %s into memory (0x%lx to 0x%lx)\n", + filename, + (unsigned long) data->load_start + data->load_offset, + (unsigned long) data->load_start + data->load_offset + len); + + /* Now set the file pos to the requested load start pos. */ + if (fseek (file, data->load_start, SEEK_SET) != 0) + perror_with_name (filename); + + /* Now allocate a buffer and read the file contents. */ + buf = xmalloc (len); + make_cleanup (xfree, buf); + if (fread (buf, 1, len, file) != len) + perror_with_name (filename); + + /* Now write the buffer into target memory. */ + len = target_write_memory (data->load_start + data->load_offset, buf, len); + if (len != 0) + warning ("restore: memory write failed (%s).", safe_strerror (len)); + return; +} + +static void +restore_command (char *args, int from_tty) +{ + char *filename; + struct callback_data data; + bfd *ibfd; + int binary_flag = 0; + + if (!target_has_execution) + noprocess (); + + data.load_offset = 0; + data.load_start = 0; + data.load_end = 0; + + /* Parse the input arguments. First is filename (required). */ + filename = scan_filename_with_cleanup (&args, NULL); + if (args != NULL && *args != '\0') + { + char *binary_string = "binary"; + + /* Look for optional "binary" flag. */ + if (strncmp (args, binary_string, strlen (binary_string)) == 0) + { + binary_flag = 1; + args += strlen (binary_string); + args = skip_spaces (args); + } + /* Parse offset (optional). */ + if (args != NULL && *args != '\0') + data.load_offset = + parse_and_eval_long (scan_expression_with_cleanup (&args, NULL)); + if (args != NULL && *args != '\0') + { + /* Parse start address (optional). */ + data.load_start = + parse_and_eval_long (scan_expression_with_cleanup (&args, NULL)); + if (args != NULL && *args != '\0') + { + /* Parse end address (optional). */ + data.load_end = parse_and_eval_long (args); + if (data.load_end <= data.load_start) + error ("Start must be less than end."); + } + } + } + + if (info_verbose) + printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n", + filename, (unsigned long) data.load_offset, + (unsigned long) data.load_start, + (unsigned long) data.load_end); + + if (binary_flag) + { + restore_binary_file (filename, &data); + } + else + { + /* Open the file for loading. */ + ibfd = bfd_openr_with_cleanup (filename, NULL); + + /* Process the sections. */ + bfd_map_over_sections (ibfd, restore_section_callback, &data); + } + return; +} + +static void +srec_dump_command (char *cmd, int from_tty) +{ + printf_unfiltered ("\"dump srec\" must be followed by a subcommand.\n"); + help_list (srec_cmdlist, "dump srec ", -1, gdb_stdout); +} + +static void +ihex_dump_command (char *cmd, int from_tty) +{ + printf_unfiltered ("\"dump ihex\" must be followed by a subcommand.\n"); + help_list (ihex_cmdlist, "dump ihex ", -1, gdb_stdout); +} + +static void +tekhex_dump_command (char *cmd, int from_tty) +{ + printf_unfiltered ("\"dump tekhex\" must be followed by a subcommand.\n"); + help_list (tekhex_cmdlist, "dump tekhex ", -1, gdb_stdout); +} + +static void +binary_dump_command (char *cmd, int from_tty) +{ + printf_unfiltered ("\"dump binary\" must be followed by a subcommand.\n"); + help_list (binary_dump_cmdlist, "dump binary ", -1, gdb_stdout); +} + +static void +binary_append_command (char *cmd, int from_tty) +{ + printf_unfiltered ("\"append binary\" must be followed by a subcommand.\n"); + help_list (binary_append_cmdlist, "append binary ", -1, gdb_stdout); +} + +extern initialize_file_ftype _initialize_cli_dump; /* -Wmissing-prototypes */ + +void +_initialize_cli_dump (void) +{ + struct cmd_list_element *c; + add_prefix_cmd ("dump", class_vars, dump_command, "\ +Dump target code/data to a local file.", + &dump_cmdlist, "dump ", + 0/*allow-unknown*/, + &cmdlist); + add_prefix_cmd ("append", class_vars, append_command, "\ +Append target code/data to a local file.", + &append_cmdlist, "append ", + 0/*allow-unknown*/, + &cmdlist); + + add_dump_command ("memory", dump_memory_command, "\ +Write contents of memory to a raw binary file.\n\ +Arguments are FILE START STOP. Writes the contents of memory within the\n\ +range [START .. STOP) to the specifed FILE in raw target ordered bytes."); + + add_dump_command ("value", dump_value_command, "\ +Write the value of an expression to a raw binary file.\n\ +Arguments are FILE EXPRESSION. Writes the value of EXPRESSION to\n\ +the specified FILE in raw target ordered bytes."); + + add_prefix_cmd ("srec", all_commands, srec_dump_command, "\ +Write target code/data to an srec file.", + &srec_cmdlist, "dump srec ", + 0 /*allow-unknown*/, + &dump_cmdlist); + + add_prefix_cmd ("ihex", all_commands, ihex_dump_command, "\ +Write target code/data to an intel hex file.", + &ihex_cmdlist, "dump ihex ", + 0 /*allow-unknown*/, + &dump_cmdlist); + + add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command, "\ +Write target code/data to a tekhex file.", + &tekhex_cmdlist, "dump tekhex ", + 0 /*allow-unknown*/, + &dump_cmdlist); + + add_prefix_cmd ("binary", all_commands, binary_dump_command, "\ +Write target code/data to a raw binary file.", + &binary_dump_cmdlist, "dump binary ", + 0 /*allow-unknown*/, + &dump_cmdlist); + + add_prefix_cmd ("binary", all_commands, binary_append_command, "\ +Append target code/data to a raw binary file.", + &binary_append_cmdlist, "append binary ", + 0 /*allow-unknown*/, + &append_cmdlist); + + add_cmd ("memory", all_commands, dump_srec_memory, "\ +Write contents of memory to an srec file.\n\ +Arguments are FILE START STOP. Writes the contents of memory\n\ +within the range [START .. STOP) to the specifed FILE in srec format.", + &srec_cmdlist); + + add_cmd ("value", all_commands, dump_srec_value, "\ +Write the value of an expression to an srec file.\n\ +Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\ +to the specified FILE in srec format.", + &srec_cmdlist); + + add_cmd ("memory", all_commands, dump_ihex_memory, "\ +Write contents of memory to an ihex file.\n\ +Arguments are FILE START STOP. Writes the contents of memory within\n\ +the range [START .. STOP) to the specifed FILE in intel hex format.", + &ihex_cmdlist); + + add_cmd ("value", all_commands, dump_ihex_value, "\ +Write the value of an expression to an ihex file.\n\ +Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\ +to the specified FILE in intel hex format.", + &ihex_cmdlist); + + add_cmd ("memory", all_commands, dump_tekhex_memory, "\ +Write contents of memory to a tekhex file.\n\ +Arguments are FILE START STOP. Writes the contents of memory\n\ +within the range [START .. STOP) to the specifed FILE in tekhex format.", + &tekhex_cmdlist); + + add_cmd ("value", all_commands, dump_tekhex_value, "\ +Write the value of an expression to a tekhex file.\n\ +Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\ +to the specified FILE in tekhex format.", + &tekhex_cmdlist); + + add_cmd ("memory", all_commands, dump_binary_memory, "\ +Write contents of memory to a raw binary file.\n\ +Arguments are FILE START STOP. Writes the contents of memory\n\ +within the range [START .. STOP) to the specifed FILE in binary format.", + &binary_dump_cmdlist); + + add_cmd ("value", all_commands, dump_binary_value, "\ +Write the value of an expression to a raw binary file.\n\ +Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\ +to the specified FILE in raw target ordered bytes.", + &binary_dump_cmdlist); + + add_cmd ("memory", all_commands, append_binary_memory, "\ +Append contents of memory to a raw binary file.\n\ +Arguments are FILE START STOP. Writes the contents of memory within the\n\ +range [START .. STOP) to the specifed FILE in raw target ordered bytes.", + &binary_append_cmdlist); + + add_cmd ("value", all_commands, append_binary_value, "\ +Append the value of an expression to a raw binary file.\n\ +Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\ +to the specified FILE in raw target ordered bytes.", + &binary_append_cmdlist); + + c = add_com ("restore", class_vars, restore_command, + "Restore the contents of FILE to target memory.\n\ +Arguments are FILE OFFSET START END where all except FILE are optional.\n\ +OFFSET will be added to the base address of the file (default zero).\n\ +If START and END are given, only the file contents within that range\n\ +(file relative) will be restored to target memory."); + c->completer = filename_completer; + /* FIXME: completers for other commands. */ +} diff --git a/contrib/gdb/gdb/cli/cli-dump.h b/contrib/gdb/gdb/cli/cli-dump.h new file mode 100644 index 00000000000..187e0e0a12e --- /dev/null +++ b/contrib/gdb/gdb/cli/cli-dump.h @@ -0,0 +1,40 @@ +/* Dump-to-file commands, for GDB, the GNU debugger. + + Copyright 2001 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef CLI_DUMP_H +#define CLI_DUMP_H + +extern void add_dump_command (char *name, + void (*func) (char *args, char *mode), + char *descr); + +/* Utilities for doing the dump. */ +extern char *scan_filename_with_cleanup (char **cmd, const char *defname); + +extern char *scan_expression_with_cleanup (char **cmd, const char *defname); + +extern FILE *fopen_with_cleanup (char *filename, const char *mode); + +extern char *skip_spaces (char *inp); + +extern struct value *parse_and_eval_with_error (char *exp, const char *fmt, ...) ATTR_FORMAT (printf, 2, 3); + +#endif diff --git a/contrib/gdb/gdb/cli/cli-interp.c b/contrib/gdb/gdb/cli/cli-interp.c new file mode 100644 index 00000000000..6abb24ddffe --- /dev/null +++ b/contrib/gdb/gdb/cli/cli-interp.c @@ -0,0 +1,157 @@ +/* CLI Definitions for GDB, the GNU debugger. + + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "interps.h" +#include "wrapper.h" +#include "event-top.h" +#include "ui-out.h" +#include "cli-out.h" +#include "top.h" /* for "execute_command" */ +#include "gdb_string.h" + +struct ui_out *cli_uiout; + +/* These are the ui_out and the interpreter for the console interpreter. */ + +/* Longjmp-safe wrapper for "execute_command" */ +static int do_captured_execute_command (struct ui_out *uiout, void *data); +static enum gdb_rc safe_execute_command (struct ui_out *uiout, char *command, + int from_tty); +struct captured_execute_command_args +{ + char *command; + int from_tty; +}; + +/* These implement the cli out interpreter: */ + +static void * +cli_interpreter_init (void) +{ + return NULL; +} + +static int +cli_interpreter_resume (void *data) +{ + struct ui_file *stream; + + /*sync_execution = 1; */ + + /* gdb_setup_readline will change gdb_stdout. If the CLI was previously + writing to gdb_stdout, then set it to the new gdb_stdout afterwards. */ + + stream = cli_out_set_stream (cli_uiout, gdb_stdout); + if (stream != gdb_stdout) + { + cli_out_set_stream (cli_uiout, stream); + stream = NULL; + } + + gdb_setup_readline (); + + if (stream != NULL) + cli_out_set_stream (cli_uiout, gdb_stdout); + + return 1; +} + +static int +cli_interpreter_suspend (void *data) +{ + gdb_disable_readline (); + return 1; +} + +/* Don't display the prompt if we are set quiet. */ +static int +cli_interpreter_display_prompt_p (void *data) +{ + if (interp_quiet_p (NULL)) + return 0; + else + return 1; +} + +static int +cli_interpreter_exec (void *data, const char *command_str) +{ + int result; + struct ui_file *old_stream; + + /* FIXME: cagney/2003-02-01: Need to const char *propogate + safe_execute_command. */ + char *str = strcpy (alloca (strlen (command_str) + 1), command_str); + + /* gdb_stdout could change between the time cli_uiout was initialized + and now. Since we're probably using a different interpreter which has + a new ui_file for gdb_stdout, use that one instead of the default. + + It is important that it gets reset everytime, since the user could + set gdb to use a different interpreter. */ + old_stream = cli_out_set_stream (cli_uiout, gdb_stdout); + result = safe_execute_command (cli_uiout, str, 1); + cli_out_set_stream (cli_uiout, old_stream); + return result; +} + +static int +do_captured_execute_command (struct ui_out *uiout, void *data) +{ + struct captured_execute_command_args *args = + (struct captured_execute_command_args *) data; + execute_command (args->command, args->from_tty); + return GDB_RC_OK; +} + +static enum gdb_rc +safe_execute_command (struct ui_out *uiout, char *command, int from_tty) +{ + struct captured_execute_command_args args; + args.command = command; + args.from_tty = from_tty; + return catch_exceptions (uiout, do_captured_execute_command, &args, + NULL, RETURN_MASK_ALL); +} + + +/* standard gdb initialization hook */ +extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */ + +void +_initialize_cli_interp (void) +{ + static const struct interp_procs procs = { + cli_interpreter_init, /* init_proc */ + cli_interpreter_resume, /* resume_proc */ + cli_interpreter_suspend, /* suspend_proc */ + cli_interpreter_exec, /* exec_proc */ + cli_interpreter_display_prompt_p /* prompt_proc_p */ + }; + struct interp *cli_interp; + + /* Create a default uiout builder for the CLI. */ + cli_uiout = cli_out_new (gdb_stdout); + cli_interp = interp_new (INTERP_CONSOLE, NULL, cli_uiout, &procs); + + interp_add (cli_interp); +} diff --git a/contrib/gdb/gdb/cli/cli-logging.c b/contrib/gdb/gdb/cli/cli-logging.c new file mode 100644 index 00000000000..db34b0d9c07 --- /dev/null +++ b/contrib/gdb/gdb/cli/cli-logging.c @@ -0,0 +1,205 @@ +/* Command-line output logging for GDB, the GNU debugger. + + Copyright 2003 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcmd.h" +#include "ui-out.h" + +#include "gdb_string.h" + +/* These hold the pushed copies of the gdb output files. + If NULL then nothing has yet been pushed. */ +struct saved_output_files +{ + struct ui_file *out; + struct ui_file *err; + struct ui_file *log; + struct ui_file *targ; +}; +static struct saved_output_files saved_output; +static char *saved_filename; + +static char *logging_filename; +int logging_overwrite, logging_redirect; + +/* If we've pushed output files, close them and pop them. */ +static void +pop_output_files (void) +{ + /* Only delete one of the files -- they are all set to the same + value. */ + ui_file_delete (gdb_stdout); + gdb_stdout = saved_output.out; + gdb_stderr = saved_output.err; + gdb_stdlog = saved_output.log; + gdb_stdtarg = saved_output.targ; + saved_output.out = NULL; + saved_output.err = NULL; + saved_output.log = NULL; + saved_output.targ = NULL; + + ui_out_redirect (uiout, NULL); +} + +/* This is a helper for the `set logging' command. */ +static void +handle_redirections (int from_tty) +{ + struct ui_file *output; + + if (saved_filename != NULL) + { + fprintf_unfiltered (gdb_stdout, "Already logging to %s.\n", + saved_filename); + return; + } + + output = gdb_fopen (logging_filename, logging_overwrite ? "w" : "a"); + if (output == NULL) + perror_with_name ("set logging"); + + /* Redirects everything to gdb_stdout while this is running. */ + if (!logging_redirect) + { + output = tee_file_new (gdb_stdout, 0, output, 1); + if (output == NULL) + perror_with_name ("set logging"); + if (from_tty) + fprintf_unfiltered (gdb_stdout, "Copying output to %s.\n", + logging_filename); + } + else if (from_tty) + fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n", + logging_filename); + + saved_filename = xstrdup (logging_filename); + saved_output.out = gdb_stdout; + saved_output.err = gdb_stderr; + saved_output.log = gdb_stdlog; + saved_output.targ = gdb_stdtarg; + + gdb_stdout = output; + gdb_stderr = output; + gdb_stdlog = output; + gdb_stdtarg = output; + + if (ui_out_redirect (uiout, gdb_stdout) < 0) + warning ("Current output protocol does not support redirection"); +} + +static void +set_logging_on (char *args, int from_tty) +{ + char *rest = args; + if (rest && *rest) + { + xfree (logging_filename); + logging_filename = xstrdup (rest); + } + handle_redirections (from_tty); +} + +static void +set_logging_off (char *args, int from_tty) +{ + if (saved_filename == NULL) + return; + + pop_output_files (); + if (from_tty) + fprintf_unfiltered (gdb_stdout, "Done logging to %s.\n", saved_filename); + xfree (saved_filename); + saved_filename = NULL; +} + +static void +set_logging_command (char *args, int from_tty) +{ + printf_unfiltered ("\"set logging\" lets you log output to a file.\n"); + printf_unfiltered ("Usage: set logging on [FILENAME]\n"); + printf_unfiltered (" set logging off\n"); + printf_unfiltered (" set logging file FILENAME\n"); + printf_unfiltered (" set logging overwrite [on|off]\n"); + printf_unfiltered (" set logging redirect [on|off]\n"); +} + +void +show_logging_command (char *args, int from_tty) +{ + if (saved_filename) + printf_unfiltered ("Currently logging to \"%s\".\n", saved_filename); + if (saved_filename == NULL + || strcmp (logging_filename, saved_filename) != 0) + printf_unfiltered ("Future logs will be written to %s.\n", + logging_filename); + + if (logging_overwrite) + printf_unfiltered ("Logs will overwrite the log file.\n"); + else + printf_unfiltered ("Logs will be appended to the log file.\n"); + + if (logging_redirect) + printf_unfiltered ("Output will be sent only to the log file.\n"); + else + printf_unfiltered ("Output will be logged and displayed.\n"); +} + +void +_initialize_cli_logging (void) +{ + static struct cmd_list_element *set_logging_cmdlist, *show_logging_cmdlist; + + + add_prefix_cmd ("logging", class_support, set_logging_command, + "Set logging options", &set_logging_cmdlist, + "set logging ", 0, &setlist); + add_prefix_cmd ("logging", class_support, show_logging_command, + "Show logging options", &show_logging_cmdlist, + "show logging ", 0, &showlist); + add_setshow_boolean_cmd ("overwrite", class_support, &logging_overwrite, + "Set whether logging overwrites or appends " + "to the log file.\n", + "Show whether logging overwrites or appends " + "to the log file.\n", + NULL, NULL, &set_logging_cmdlist, &show_logging_cmdlist); + add_setshow_boolean_cmd ("redirect", class_support, &logging_redirect, + "Set the logging output mode.\n" + "If redirect is off, output will go to both the " + "screen and the log file.\n" + "If redirect is on, output will go only to the log " + "file.", + "Show the logging output mode.\n" + "If redirect is off, output will go to both the " + "screen and the log file.\n" + "If redirect is on, output will go only to the log " + "file.", + NULL, NULL, &set_logging_cmdlist, &show_logging_cmdlist); + add_setshow_cmd ("file", class_support, var_filename, &logging_filename, + "Set the current logfile.", "Show the current logfile.", + NULL, NULL, &set_logging_cmdlist, &show_logging_cmdlist); + add_cmd ("on", class_support, set_logging_on, + "Enable logging.", &set_logging_cmdlist); + add_cmd ("off", class_support, set_logging_off, + "Disable logging.", &set_logging_cmdlist); + + logging_filename = xstrdup ("gdb.txt"); +} diff --git a/contrib/gdb/gdb/cli/cli-script.c b/contrib/gdb/gdb/cli/cli-script.c index 45451175560..ca0c14f043b 100644 --- a/contrib/gdb/gdb/cli/cli-script.c +++ b/contrib/gdb/gdb/cli/cli-script.c @@ -27,23 +27,15 @@ #include #include "ui-out.h" +#include "gdb_string.h" #include "top.h" #include "cli/cli-cmds.h" #include "cli/cli-decode.h" #include "cli/cli-script.h" -/* From gdb/top.c */ - -extern void dont_repeat (void); - -extern void do_restore_instream_cleanup (void *stream); - /* Prototypes for local functions */ -static struct cleanup * - make_cleanup_free_command_lines (struct command_line **arg); - static enum command_control_type recurse_read_control_structure (struct command_line *current_cmd); @@ -213,14 +205,58 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd, } /* while (list) */ } +/* Handle pre-post hooks. */ + +static void +clear_hook_in_cleanup (void *data) +{ + struct cmd_list_element *c = data; + c->hook_in = 0; /* Allow hook to work again once it is complete */ +} + +void +execute_cmd_pre_hook (struct cmd_list_element *c) +{ + if ((c->hook_pre) && (!c->hook_in)) + { + struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c); + c->hook_in = 1; /* Prevent recursive hooking */ + execute_user_command (c->hook_pre, (char *) 0); + do_cleanups (cleanups); + } +} + +void +execute_cmd_post_hook (struct cmd_list_element *c) +{ + if ((c->hook_post) && (!c->hook_in)) + { + struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c); + c->hook_in = 1; /* Prevent recursive hooking */ + execute_user_command (c->hook_post, (char *) 0); + do_cleanups (cleanups); + } +} + /* Execute the command in CMD. */ +static void +do_restore_user_call_depth (void * call_depth) +{ + int * depth = call_depth; + /* We will be returning_to_top_level() at this point, so we want to + reset our depth. */ + (*depth) = 0; +} + void execute_user_command (struct cmd_list_element *c, char *args) { - register struct command_line *cmdlines; + struct command_line *cmdlines; struct cleanup *old_chain; enum command_control_type ret; + static int user_call_depth = 0; + extern int max_user_call_depth; old_chain = setup_user_args (args); @@ -229,6 +265,11 @@ execute_user_command (struct cmd_list_element *c, char *args) /* Null command */ return; + if (++user_call_depth > max_user_call_depth) + error ("Max user call depth exceeded -- command aborted\n"); + + old_chain = make_cleanup (do_restore_user_call_depth, &user_call_depth); + /* Set the instream to 0, indicating execution of a user-defined function. */ old_chain = make_cleanup (do_restore_instream_cleanup, instream); @@ -244,6 +285,8 @@ execute_user_command (struct cmd_list_element *c, char *args) cmdlines = cmdlines->next; } do_cleanups (old_chain); + + user_call_depth--; } enum command_control_type @@ -251,21 +294,25 @@ execute_control_command (struct command_line *cmd) { struct expression *expr; struct command_line *current; - struct cleanup *old_chain = 0; + struct cleanup *old_chain = make_cleanup (null_cleanup, 0); struct value *val; struct value *val_mark; int loop; enum command_control_type ret; char *new_line; + /* Start by assuming failure, if a problem is detected, the code + below will simply "break" out of the switch. */ + ret = invalid_control; + switch (cmd->control_type) { case simple_control: /* A simple command, execute it and return. */ new_line = insert_args (cmd->line); if (!new_line) - return invalid_control; - old_chain = make_cleanup (free_current_contents, &new_line); + break; + make_cleanup (free_current_contents, &new_line); execute_command (new_line, 0); ret = cmd->control_type; break; @@ -282,8 +329,8 @@ execute_control_command (struct command_line *cmd) /* Parse the loop control expression for the while statement. */ new_line = insert_args (cmd->line); if (!new_line) - return invalid_control; - old_chain = make_cleanup (free_current_contents, &new_line); + break; + make_cleanup (free_current_contents, &new_line); expr = parse_expression (new_line); make_cleanup (free_current_contents, &expr); @@ -342,8 +389,8 @@ execute_control_command (struct command_line *cmd) { new_line = insert_args (cmd->line); if (!new_line) - return invalid_control; - old_chain = make_cleanup (free_current_contents, &new_line); + break; + make_cleanup (free_current_contents, &new_line); /* Parse the conditional for the if statement. */ expr = parse_expression (new_line); make_cleanup (free_current_contents, &expr); @@ -381,11 +428,10 @@ execute_control_command (struct command_line *cmd) default: warning ("Invalid control type in command structure."); - return invalid_control; + break; } - if (old_chain) - do_cleanups (old_chain); + do_cleanups (old_chain); return ret; } @@ -928,8 +974,8 @@ read_command_lines (char *prompt_arg, int from_tty) void free_command_lines (struct command_line **lptr) { - register struct command_line *l = *lptr; - register struct command_line *next; + struct command_line *l = *lptr; + struct command_line *next; struct command_line **blist; int i; @@ -955,16 +1001,46 @@ do_free_command_lines_cleanup (void *arg) free_command_lines (arg); } -static struct cleanup * +struct cleanup * make_cleanup_free_command_lines (struct command_line **arg) { return make_cleanup (do_free_command_lines_cleanup, arg); } + +struct command_line * +copy_command_lines (struct command_line *cmds) +{ + struct command_line *result = NULL; + + if (cmds) + { + result = (struct command_line *) xmalloc (sizeof (struct command_line)); + + result->next = copy_command_lines (cmds->next); + result->line = xstrdup (cmds->line); + result->control_type = cmds->control_type; + result->body_count = cmds->body_count; + if (cmds->body_count > 0) + { + int i; + + result->body_list = (struct command_line **) + xmalloc (sizeof (struct command_line *) * cmds->body_count); + + for (i = 0; i < cmds->body_count; i++) + result->body_list[i] = copy_command_lines (cmds->body_list[i]); + } + else + result->body_list = NULL; + } + + return result; +} static void validate_comname (char *comname) { - register char *p; + char *p; if (comname == 0) error_no_arg ("name of command to define"); @@ -994,8 +1070,8 @@ define_command (char *comname, int from_tty) CMD_PRE_HOOK, CMD_POST_HOOK }; - register struct command_line *cmds; - register struct cmd_list_element *c, *newc, *oldc, *hookc = 0; + struct command_line *cmds; + struct cmd_list_element *c, *newc, *oldc, *hookc = 0; char *tem = comname; char *tem2; char tmpbuf[MAX_TMPBUF]; @@ -1011,16 +1087,17 @@ define_command (char *comname, int from_tty) /* Look it up, and verify that we got an exact match. */ c = lookup_cmd (&tem, cmdlist, "", -1, 1); - if (c && !STREQ (comname, c->name)) + if (c && strcmp (comname, c->name) != 0) c = 0; if (c) { + int q; if (c->class == class_user || c->class == class_alias) - tem = "Redefine command \"%s\"? "; + q = query ("Redefine command \"%s\"? ", c->name); else - tem = "Really redefine built-in command \"%s\"? "; - if (!query (tem, c->name)) + q = query ("Really redefine built-in command \"%s\"? ", c->name); + if (!q) error ("Command \"%s\" not redefined.", c->name); } @@ -1044,7 +1121,7 @@ define_command (char *comname, int from_tty) /* Look up cmd it hooks, and verify that we got an exact match. */ tem = comname + hook_name_size; hookc = lookup_cmd (&tem, cmdlist, "", -1, 0); - if (hookc && !STREQ (comname + hook_name_size, hookc->name)) + if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0) hookc = 0; if (!hookc) { @@ -1099,7 +1176,7 @@ void document_command (char *comname, int from_tty) { struct command_line *doclines; - register struct cmd_list_element *c; + struct cmd_list_element *c; char *tem = comname; char tmpbuf[128]; @@ -1117,8 +1194,8 @@ document_command (char *comname, int from_tty) xfree (c->doc); { - register struct command_line *cl1; - register int len = 0; + struct command_line *cl1; + int len = 0; for (cl1 = doclines; cl1; cl1 = cl1->next) len += strlen (cl1->line) + 1; @@ -1146,7 +1223,7 @@ struct source_cleanup_lines_args }; static void -source_cleanup_lines (PTR args) +source_cleanup_lines (void *args) { struct source_cleanup_lines_args *p = (struct source_cleanup_lines_args *) args; @@ -1156,7 +1233,6 @@ source_cleanup_lines (PTR args) error_pre_print = p->old_error_pre_print; } -/* ARGSUSED */ static void do_fclose_cleanup (void *stream) { @@ -1213,7 +1289,7 @@ script_from_file (FILE *stream, char *file) void show_user_1 (struct cmd_list_element *c, struct ui_file *stream) { - register struct command_line *cmdlines; + struct command_line *cmdlines; cmdlines = c->user_commands; if (!cmdlines) diff --git a/contrib/gdb/gdb/cli/cli-script.h b/contrib/gdb/gdb/cli/cli-script.h index f8604c6cb71..fc5c20301e8 100644 --- a/contrib/gdb/gdb/cli/cli-script.h +++ b/contrib/gdb/gdb/cli/cli-script.h @@ -19,6 +19,10 @@ #if !defined (CLI_SCRIPT_H) #define CLI_SCRIPT_H 1 +struct ui_file; +struct command_line; +struct cmd_list_element; + /* Exported to cli/cli-cmds.c */ extern void script_from_file (FILE *stream, char *file); @@ -41,6 +45,10 @@ extern enum command_control_type extern void print_command_lines (struct ui_out *, struct command_line *, unsigned int); +extern struct command_line * copy_command_lines (struct command_line *cmds); + +struct cleanup *make_cleanup_free_command_lines (struct command_line **arg); + /* Exported to gdb/infrun.c */ extern void execute_user_command (struct cmd_list_element *c, char *args); diff --git a/contrib/gdb/gdb/cli/cli-setshow.c b/contrib/gdb/gdb/cli/cli-setshow.c index f967b0c3eba..62fe36f360b 100644 --- a/contrib/gdb/gdb/cli/cli-setshow.c +++ b/contrib/gdb/gdb/cli/cli-setshow.c @@ -1,6 +1,6 @@ /* Handle set and show GDB commands. - Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002, 2003 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 @@ -18,11 +18,10 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "readline/tilde.h" #include "value.h" #include -#if 0 #include "gdb_string.h" -#endif #include "ui-out.h" @@ -34,9 +33,8 @@ static int parse_binary_operation (char *); -static enum cmd_auto_boolean parse_auto_binary_operation (const char *arg); -static enum cmd_auto_boolean +static enum auto_boolean parse_auto_binary_operation (const char *arg) { if (arg != NULL && *arg != '\0') @@ -48,18 +46,18 @@ parse_auto_binary_operation (const char *arg) || strncmp (arg, "1", length) == 0 || strncmp (arg, "yes", length) == 0 || strncmp (arg, "enable", length) == 0) - return CMD_AUTO_BOOLEAN_TRUE; + return AUTO_BOOLEAN_TRUE; else if (strncmp (arg, "off", length) == 0 || strncmp (arg, "0", length) == 0 || strncmp (arg, "no", length) == 0 || strncmp (arg, "disable", length) == 0) - return CMD_AUTO_BOOLEAN_FALSE; + return AUTO_BOOLEAN_FALSE; else if (strncmp (arg, "auto", length) == 0 || (strncmp (arg, "-1", length) == 0 && length > 1)) - return CMD_AUTO_BOOLEAN_AUTO; + return AUTO_BOOLEAN_AUTO; } error ("\"on\", \"off\" or \"auto\" expected."); - return CMD_AUTO_BOOLEAN_AUTO; /* pacify GCC */ + return AUTO_BOOLEAN_AUTO; /* pacify GCC */ } static int @@ -167,7 +165,7 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c) *(int *) c->var = parse_binary_operation (arg); break; case var_auto_boolean: - *(enum cmd_auto_boolean *) c->var = parse_auto_binary_operation (arg); + *(enum auto_boolean *) c->var = parse_auto_binary_operation (arg); break; case var_uinteger: if (arg == NULL) @@ -215,7 +213,7 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c) strcat (msg, c->enums[i]); } strcat (msg, "."); - error (msg); + error ("%s", msg); } p = strchr (arg, ' '); @@ -296,15 +294,15 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c) fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream); break; case var_auto_boolean: - switch (*(enum cmd_auto_boolean*) c->var) + switch (*(enum auto_boolean*) c->var) { - case CMD_AUTO_BOOLEAN_TRUE: + case AUTO_BOOLEAN_TRUE: fputs_filtered ("on", stb->stream); break; - case CMD_AUTO_BOOLEAN_FALSE: + case AUTO_BOOLEAN_FALSE: fputs_filtered ("off", stb->stream); break; - case CMD_AUTO_BOOLEAN_AUTO: + case AUTO_BOOLEAN_AUTO: fputs_filtered ("auto", stb->stream); break; default: @@ -355,28 +353,35 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c) void cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix) { - ui_out_tuple_begin (uiout, "showlist"); + struct cleanup *showlist_chain; + + showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist"); for (; list != NULL; list = list->next) { /* If we find a prefix, run its list, prefixing our output by its prefix (with "show " skipped). */ if (list->prefixlist && !list->abbrev_flag) { - ui_out_tuple_begin (uiout, "optionlist"); + struct cleanup *optionlist_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist"); ui_out_field_string (uiout, "prefix", list->prefixname + 5); cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5); - ui_out_tuple_end (uiout); + /* Close the tuple. */ + do_cleanups (optionlist_chain); } if (list->type == show_cmd) { - ui_out_tuple_begin (uiout, "option"); + struct cleanup *option_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "option"); ui_out_text (uiout, prefix); ui_out_field_string (uiout, "name", list->name); ui_out_text (uiout, ": "); do_setshow_command ((char *) NULL, from_tty, list); - ui_out_tuple_end (uiout); + /* Close the tuple. */ + do_cleanups (option_chain); } } - ui_out_tuple_end (uiout); + /* Close the tuple. */ + do_cleanups (showlist_chain); } diff --git a/contrib/gdb/gdb/cli/cli-setshow.h b/contrib/gdb/gdb/cli/cli-setshow.h index 393612a8177..470b8b754c6 100644 --- a/contrib/gdb/gdb/cli/cli-setshow.h +++ b/contrib/gdb/gdb/cli/cli-setshow.h @@ -19,6 +19,8 @@ #if !defined (CLI_SETSHOW_H) #define CLI_SETSHOW_H 1 +struct cmd_list_element; + /* Exported to cli/cli-cmds.c and gdb/top.c */ /* Do a "set" or "show" command. ARG is NULL if no argument, or the text diff --git a/contrib/gdb/gdb/coff-pe-read.c b/contrib/gdb/gdb/coff-pe-read.c new file mode 100644 index 00000000000..2d1e8541fbe --- /dev/null +++ b/contrib/gdb/gdb/coff-pe-read.c @@ -0,0 +1,346 @@ +/* Read the export table symbols from a portable executable and + convert to internal format, for GDB. Used as a last resort if no + debugging symbols recognized. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Contributed by Raoul M. Gough (RaoulGough@yahoo.co.uk). */ + +#include "coff-pe-read.h" + +#include "bfd.h" + +#include "defs.h" +#include "gdbtypes.h" + +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" + +/* Internal section information */ + +struct read_pe_section_data +{ + CORE_ADDR vma_offset; /* Offset to loaded address of section. */ + unsigned long rva_start; /* Start offset within the pe. */ + unsigned long rva_end; /* End offset within the pe. */ + enum minimal_symbol_type ms_type; /* Type to assign symbols in section. */ +}; + +#define PE_SECTION_INDEX_TEXT 0 +#define PE_SECTION_INDEX_DATA 1 +#define PE_SECTION_INDEX_BSS 2 +#define PE_SECTION_TABLE_SIZE 3 +#define PE_SECTION_INDEX_INVALID -1 + +/* Get the index of the named section in our own array, which contains + text, data and bss in that order. Return PE_SECTION_INDEX_INVALID + if passed an unrecognised section name. */ + +static int +read_pe_section_index (const char *section_name) +{ + if (strcmp (section_name, ".text") == 0) + { + return PE_SECTION_INDEX_TEXT; + } + + else if (strcmp (section_name, ".data") == 0) + { + return PE_SECTION_INDEX_DATA; + } + + else if (strcmp (section_name, ".bss") == 0) + { + return PE_SECTION_INDEX_BSS; + } + + else + { + return PE_SECTION_INDEX_INVALID; + } +} + +/* Record the virtual memory address of a section. */ + +static void +get_section_vmas (bfd *abfd, asection *sectp, void *context) +{ + struct read_pe_section_data *sections = context; + int sectix = read_pe_section_index (sectp->name); + + if (sectix != PE_SECTION_INDEX_INVALID) + { + /* Data within the section start at rva_start in the pe and at + bfd_get_section_vma() within memory. Store the offset. */ + + sections[sectix].vma_offset + = bfd_get_section_vma (abfd, sectp) - sections[sectix].rva_start; + } +} + +/* Create a minimal symbol entry for an exported symbol. */ + +static void +add_pe_exported_sym (char *sym_name, + unsigned long func_rva, + const struct read_pe_section_data *section_data, + const char *dll_name, struct objfile *objfile) +{ + /* Add the stored offset to get the loaded address of the symbol. */ + + CORE_ADDR vma = func_rva + section_data->vma_offset; + + char *qualified_name = 0; + int dll_name_len = strlen (dll_name); + int count; + + /* Generate a (hopefully unique) qualified name using the first part + of the dll name, e.g. KERNEL32!AddAtomA. This matches the style + used by windbg from the "Microsoft Debugging Tools for Windows". */ + + qualified_name = xmalloc (dll_name_len + strlen (sym_name) + 2); + + strncpy (qualified_name, dll_name, dll_name_len); + qualified_name[dll_name_len] = '!'; + strcpy (qualified_name + dll_name_len + 1, sym_name); + + prim_record_minimal_symbol (qualified_name, + vma, section_data->ms_type, objfile); + + xfree (qualified_name); + + /* Enter the plain name as well, which might not be unique. */ + prim_record_minimal_symbol (sym_name, vma, section_data->ms_type, objfile); +} + +/* Truncate a dll_name at the first dot character. */ + +static void +read_pe_truncate_name (char *dll_name) +{ + while (*dll_name) + { + if ((*dll_name) == '.') + { + *dll_name = '\0'; /* truncates and causes loop exit. */ + } + + else + { + ++dll_name; + } + } +} + +/* Low-level support functions, direct from the ld module pe-dll.c. */ +static unsigned int +pe_get16 (bfd *abfd, int where) +{ + unsigned char b[2]; + + bfd_seek (abfd, (file_ptr) where, SEEK_SET); + bfd_bread (b, (bfd_size_type) 2, abfd); + return b[0] + (b[1] << 8); +} + +static unsigned int +pe_get32 (bfd *abfd, int where) +{ + unsigned char b[4]; + + bfd_seek (abfd, (file_ptr) where, SEEK_SET); + bfd_bread (b, (bfd_size_type) 4, abfd); + return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); +} + +static unsigned int +pe_as32 (void *ptr) +{ + unsigned char *b = ptr; + + return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); +} + +/* Read the (non-debug) export symbol table from a portable + executable. Code originally lifted from the ld function + pe_implied_import_dll in pe-dll.c. */ + +void +read_pe_exported_syms (struct objfile *objfile) +{ + bfd *dll = objfile->obfd; + unsigned long pe_header_offset, opthdr_ofs, num_entries, i; + unsigned long export_rva, export_size, nsections, secptr, expptr; + unsigned long exp_funcbase; + unsigned char *expdata, *erva; + unsigned long name_rvas, ordinals, nexp, ordbase; + char *dll_name; + + /* Array elements are for text, data and bss in that order + Initialization with start_rva > end_rva guarantees that + unused sections won't be matched. */ + struct read_pe_section_data section_data[PE_SECTION_TABLE_SIZE] + = { {0, 1, 0, mst_text}, + {0, 1, 0, mst_data}, + {0, 1, 0, mst_bss} + }; + + struct cleanup *back_to = 0; + + char const *target = bfd_get_target (objfile->obfd); + + if ((strcmp (target, "pe-i386") != 0) && (strcmp (target, "pei-i386") != 0)) + { + /* This is not an i386 format file. Abort now, because the code + is untested on anything else. *FIXME* test on further + architectures and loosen or remove this test. */ + return; + } + + /* Get pe_header, optional header and numbers of export entries. */ + pe_header_offset = pe_get32 (dll, 0x3c); + opthdr_ofs = pe_header_offset + 4 + 20; + num_entries = pe_get32 (dll, opthdr_ofs + 92); + + if (num_entries < 1) /* No exports. */ + { + return; + } + + export_rva = pe_get32 (dll, opthdr_ofs + 96); + export_size = pe_get32 (dll, opthdr_ofs + 100); + nsections = pe_get16 (dll, pe_header_offset + 4 + 2); + secptr = (pe_header_offset + 4 + 20 + + pe_get16 (dll, pe_header_offset + 4 + 16)); + expptr = 0; + + /* Get the rva and size of the export section. */ + for (i = 0; i < nsections; i++) + { + char sname[8]; + unsigned long secptr1 = secptr + 40 * i; + unsigned long vaddr = pe_get32 (dll, secptr1 + 12); + unsigned long vsize = pe_get32 (dll, secptr1 + 16); + unsigned long fptr = pe_get32 (dll, secptr1 + 20); + + bfd_seek (dll, (file_ptr) secptr1, SEEK_SET); + bfd_bread (sname, (bfd_size_type) 8, dll); + + if (vaddr <= export_rva && vaddr + vsize > export_rva) + { + expptr = fptr + (export_rva - vaddr); + if (export_rva + export_size > vaddr + vsize) + export_size = vsize - (export_rva - vaddr); + break; + } + } + + if (export_size == 0) + { + /* Empty export table. */ + return; + } + + /* Scan sections and store the base and size of the relevant sections. */ + for (i = 0; i < nsections; i++) + { + unsigned long secptr1 = secptr + 40 * i; + unsigned long vsize = pe_get32 (dll, secptr1 + 8); + unsigned long vaddr = pe_get32 (dll, secptr1 + 12); + unsigned long flags = pe_get32 (dll, secptr1 + 36); + char sec_name[9]; + int sectix; + + sec_name[8] = '\0'; + bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET); + bfd_bread (sec_name, (bfd_size_type) 8, dll); + + sectix = read_pe_section_index (sec_name); + + if (sectix != PE_SECTION_INDEX_INVALID) + { + section_data[sectix].rva_start = vaddr; + section_data[sectix].rva_end = vaddr + vsize; + } + } + + expdata = (unsigned char *) xmalloc (export_size); + back_to = make_cleanup (xfree, expdata); + + bfd_seek (dll, (file_ptr) expptr, SEEK_SET); + bfd_bread (expdata, (bfd_size_type) export_size, dll); + erva = expdata - export_rva; + + nexp = pe_as32 (expdata + 24); + name_rvas = pe_as32 (expdata + 32); + ordinals = pe_as32 (expdata + 36); + ordbase = pe_as32 (expdata + 16); + exp_funcbase = pe_as32 (expdata + 28); + + /* Use internal dll name instead of full pathname. */ + dll_name = pe_as32 (expdata + 12) + erva; + + bfd_map_over_sections (dll, get_section_vmas, section_data); + + /* Adjust the vma_offsets in case this PE got relocated. This + assumes that *all* sections share the same relocation offset + as the text section. */ + for (i = 0; i < PE_SECTION_TABLE_SIZE; i++) + { + section_data[i].vma_offset + += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + } + + printf_filtered ("Minimal symbols from %s...", dll_name); + wrap_here (""); + + /* Truncate name at first dot. Should maybe also convert to all + lower case for convenience on Windows. */ + read_pe_truncate_name (dll_name); + + /* Iterate through the list of symbols. */ + for (i = 0; i < nexp; i++) + { + /* Pointer to the names vector. */ + unsigned long name_rva = pe_as32 (erva + name_rvas + i * 4); + + /* Pointer to the function address vector. */ + unsigned long func_rva = pe_as32 (erva + exp_funcbase + i * 4); + + /* Find this symbol's section in our own array. */ + int sectix = 0; + + for (sectix = 0; sectix < PE_SECTION_TABLE_SIZE; ++sectix) + { + if ((func_rva >= section_data[sectix].rva_start) + && (func_rva < section_data[sectix].rva_end)) + { + add_pe_exported_sym (erva + name_rva, + func_rva, + section_data + sectix, dll_name, objfile); + break; + } + } + } + + /* discard expdata. */ + do_cleanups (back_to); +} diff --git a/contrib/gdb/gdb/coff-pe-read.h b/contrib/gdb/gdb/coff-pe-read.h new file mode 100644 index 00000000000..c5d4e68bc17 --- /dev/null +++ b/contrib/gdb/gdb/coff-pe-read.h @@ -0,0 +1,32 @@ +/* Interface to coff-pe-read.c (portable-executable-specific symbol reader). + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Contributed by Raoul M. Gough (RaoulGough@yahoo.co.uk). */ + +#if !defined (COFF_PE_READ_H) +#define COFF_PE_READ_H + +struct objfile; + +/* Read the export table and convert it to minimal symbol table entries */ +extern void read_pe_exported_syms (struct objfile *objfile); + +#endif /* !defined (COFF_PE_READ_H) */ diff --git a/contrib/gdb/gdb/coff-solib.c b/contrib/gdb/gdb/coff-solib.c new file mode 100644 index 00000000000..64dca7bbefd --- /dev/null +++ b/contrib/gdb/gdb/coff-solib.c @@ -0,0 +1,134 @@ +/* Handle COFF SVR3 shared libraries for GDB, the GNU Debugger. + Copyright 1993, 1994, 1998, 1999, 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#include "defs.h" + +#include "frame.h" +#include "bfd.h" +#include "gdbcore.h" +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" + +/* + + GLOBAL FUNCTION + + coff_solib_add -- add a shared library files to the symtab list. We + examine the `.lib' section of the exec file and determine the names of + the shared libraries. + + This function is responsible for discovering those names and + addresses, and saving sufficient information about them to allow + their symbols to be read at a later time. + + SYNOPSIS + + void coff_solib_add (char *arg_string, int from_tty, + struct target_ops *target, int readsyms) + + DESCRIPTION + + */ + +void +coff_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) +{ + asection *libsect; + + if (!readsyms) + return; + + libsect = bfd_get_section_by_name (exec_bfd, ".lib"); + + if (libsect) + { + int libsize; + unsigned char *lib; + struct libent + { + bfd_byte len[4]; + bfd_byte nameoffset[4]; + }; + + libsize = bfd_section_size (exec_bfd, libsect); + + lib = (unsigned char *) alloca (libsize); + + bfd_get_section_contents (exec_bfd, libsect, lib, 0, libsize); + + while (libsize > 0) + { + struct libent *ent; + struct objfile *objfile; + int len, nameoffset; + char *filename; + + ent = (struct libent *) lib; + + len = bfd_get_32 (exec_bfd, ent->len); + + nameoffset = bfd_get_32 (exec_bfd, ent->nameoffset); + + if (len <= 0) + break; + + filename = (char *) ent + nameoffset * 4; + + objfile = symbol_file_add (filename, from_tty, + NULL, /* no offsets */ + 0, /* not mainline */ + OBJF_SHARED); /* flags */ + + libsize -= len * 4; + lib += len * 4; + } + + /* Getting new symbols may change our opinion about what is + frameless. */ + reinit_frame_cache (); + } +} + +/* + + GLOBAL FUNCTION + + coff_solib_create_inferior_hook -- shared library startup support + + SYNOPSIS + + void coff_solib_create_inferior_hook() + + DESCRIPTION + + When gdb starts up the inferior, the kernel maps in the shared + libraries. We get here with the target stopped at it's first + instruction, and the libraries already mapped. At this point, this + function gets called via expansion of the macro + SOLIB_CREATE_INFERIOR_HOOK. + */ + +void +coff_solib_create_inferior_hook (void) +{ + coff_solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); +} diff --git a/contrib/gdb/gdb/coff-solib.h b/contrib/gdb/gdb/coff-solib.h new file mode 100644 index 00000000000..d29f96a0981 --- /dev/null +++ b/contrib/gdb/gdb/coff-solib.h @@ -0,0 +1,186 @@ +/* COFF (SVR3) Shared library declarations for GDB, the GNU Debugger. + Copyright 1992, 1993, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Forward decl's for prototypes */ +struct target_ops; + +/* Called when we free all symtabs, to free the shared library information + as well. */ + +#if 0 +#define CLEAR_SOLIB coff_clear_solib + +extern void coff_clear_solib (void); +#endif + +/* Called to add symbols from a shared library to gdb's symbol table. */ + +#define SOLIB_ADD(filename, from_tty, targ, readsyms) \ + coff_solib_add (filename, from_tty, targ, readsyms) + +extern void coff_solib_add (char *, int, struct target_ops *, int); + +/* Function to be called when the inferior starts up, to discover the names + of shared libraries that are dynamically linked, the base addresses to + which they are linked, and sufficient information to read in their symbols + at a later time. */ + +#define SOLIB_CREATE_INFERIOR_HOOK(PID) coff_solib_create_inferior_hook() + +extern void coff_solib_create_inferior_hook (void); /* solib.c */ + +/* Function to be called to remove the connection between debugger and + dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK. + (This operation does not remove shared library information from + the debugger, as CLEAR_SOLIB does.) + + This functionality is presently not implemented for this target. + */ +#define SOLIB_REMOVE_INFERIOR_HOOK(PID) (0) + +/* This function is called by the "catch load" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is loaded. + + Presently, this functionality is not implemented. + */ +#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \ + error("catch of library loads/unloads not yet implemented on this platform") + +/* This function is called by the "catch unload" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is unloaded. + + Presently, this functionality is not implemented. + */ +#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \ + error("catch of library loads/unloads not yet implemented on this platform") + +/* This function returns TRUE if the dynamic linker has just reported + a load of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. + + Presently, this functionality is not implemented. + */ +/* + #define SOLIB_HAVE_LOAD_EVENT(pid) \ + error("catch of library loads/unloads not yet implemented on this platform") + */ + +#define SOLIB_HAVE_LOAD_EVENT(pid) \ +(0) + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been loaded. + + This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. + + Presently, this functionality is not implemented. + */ + +/* + #define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ + error("catch of library loads/unloads not yet implemented on this platform") + */ + +#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ +"" + +/* This function returns TRUE if the dynamic linker has just reported + an unload of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. + + Presently, this functionality is not implemented. + */ +/* + #define SOLIB_HAVE_UNLOAD_EVENT(pid) \ + error("catch of library loads/unloads not yet implemented on this platform") + */ + +#define SOLIB_HAVE_UNLOAD_EVENT(pid) \ +(0) + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been unloaded. + + This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. + + Presently, this functionality is not implemented. + */ +/* + #define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ + error("catch of library loads/unloads not yet implemented on this platform") + */ + +#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ +(0) + +/* This function returns TRUE if pc is the address of an instruction that + lies within the dynamic linker (such as the event hook, or the dld + itself). + + This function must be used only when a dynamic linker event has been + caught, and the inferior is being stepped out of the hook, or undefined + results are guaranteed. + + Presently, this functionality is not implemented. + */ + +/* + #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ + error("catch of library loads/unloads not yet implemented on this platform") + */ + +#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ +(0) + +/* This function must be called when the inferior is killed, and the program + restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard + any symbol tables. + + Presently, this functionality is not implemented. + */ +#define SOLIB_RESTART() \ + (0) + +/* If we can't set a breakpoint, and it's in a shared library, just + disable it. */ + +#if 0 +#define DISABLE_UNSETTABLE_BREAK(addr) coff_solib_address(addr) + +extern int solib_address (CORE_ADDR); /* solib.c */ +#endif diff --git a/contrib/gdb/gdb/coffread.c b/contrib/gdb/gdb/coffread.c index 84b3761cf55..056ba137471 100644 --- a/contrib/gdb/gdb/coffread.c +++ b/contrib/gdb/gdb/coffread.c @@ -1,6 +1,6 @@ /* Read coff symbol tables and convert to internal format, for GDB. Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002 + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). @@ -28,15 +28,13 @@ #include "breakpoint.h" #include "bfd.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "gdb_string.h" #include #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" @@ -44,6 +42,10 @@ #include "complaints.h" #include "target.h" #include "gdb_assert.h" +#include "block.h" +#include "dictionary.h" + +#include "coff-pe-read.h" extern void _initialize_coffread (void); @@ -122,41 +124,6 @@ static int pe_file; static struct symbol *opaque_type_chain[HASHSIZE]; -/* Complaints about various problems in the file being read */ - -struct complaint ef_complaint = -{"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0}; - -struct complaint ef_stack_complaint = -{"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", 0, 0}; - -struct complaint eb_stack_complaint = -{"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", 0, 0}; - -struct complaint bf_no_aux_complaint = -{"`.bf' symbol %d has no aux entry", 0, 0}; - -struct complaint ef_no_aux_complaint = -{"`.ef' symbol %d has no aux entry", 0, 0}; - -struct complaint lineno_complaint = -{"Line number pointer %d lower than start of line numbers", 0, 0}; - -struct complaint unexpected_type_complaint = -{"Unexpected type for symbol %s", 0, 0}; - -struct complaint bad_sclass_complaint = -{"Bad n_sclass for symbol %s", 0, 0}; - -struct complaint misordered_blocks_complaint = -{"Blocks out of order at address %x", 0, 0}; - -struct complaint tagndx_bad_complaint = -{"Symbol table entry for %s has bad tagndx value", 0, 0}; - -struct complaint eb_complaint = -{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0}; - /* Simplified internal version of coff symbol table information */ struct coff_symbol @@ -228,12 +195,12 @@ static void coff_symtab_read (long, unsigned int, struct objfile *); static void coff_locate_sections (bfd *abfd, asection *sectp, void *csip) { - register struct coff_symfile_info *csi; + struct coff_symfile_info *csi; const char *name; csi = (struct coff_symfile_info *) csip; name = bfd_get_section_name (abfd, sectp); - if (STREQ (name, ".text")) + if (DEPRECATED_STREQ (name, ".text")) { csi->textaddr = bfd_section_vma (abfd, sectp); csi->textsize += bfd_section_size (abfd, sectp); @@ -242,7 +209,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip) { csi->textsize += bfd_section_size (abfd, sectp); } - else if (STREQ (name, ".stabstr")) + else if (DEPRECATED_STREQ (name, ".stabstr")) { csi->stabstrsect = sectp; } @@ -344,7 +311,7 @@ cs_section_address (struct coff_symbol *cs, bfd *abfd) or for associating a new type with the index. */ static struct type ** -coff_lookup_type (register int index) +coff_lookup_type (int index) { if (index >= type_vector_length) { @@ -370,8 +337,8 @@ coff_lookup_type (register int index) static struct type * coff_alloc_type (int index) { - register struct type **type_addr = coff_lookup_type (index); - register struct type *type = *type_addr; + struct type **type_addr = coff_lookup_type (index); + struct type *type = *type_addr; /* If we are referring to a type not known at all yet, allocate an empty type for it. @@ -422,8 +389,8 @@ complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size) if (current_objfile->ei.entry_point >= current_source_start_addr && current_objfile->ei.entry_point < current_source_end_addr) { - current_objfile->ei.entry_file_lowpc = current_source_start_addr; - current_objfile->ei.entry_file_highpc = current_source_end_addr; + current_objfile->ei.deprecated_entry_file_lowpc = current_source_start_addr; + current_objfile->ei.deprecated_entry_file_highpc = current_source_end_addr; } } @@ -500,9 +467,8 @@ coff_symfile_init (struct objfile *objfile) of the line table (minimum and maximum file offset) so that the mainline code can read the whole thing for efficiency. */ -/* ARGSUSED */ static void -find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo) +find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo) { struct coff_symfile_info *info; int size, count; @@ -537,7 +503,6 @@ static bfd *symfile_bfd; /* Read a symbol file, after initialization by coff_symfile_init. */ -/* ARGSUSED */ static void coff_symfile_read (struct objfile *objfile, int mainline) { @@ -546,11 +511,11 @@ coff_symfile_read (struct objfile *objfile, int mainline) bfd *abfd = objfile->obfd; coff_data_type *cdata = coff_data (abfd); char *name = bfd_get_filename (abfd); - register int val; + int val; unsigned int num_symbols; int symtab_offset; int stringtab_offset; - struct cleanup *back_to; + struct cleanup *back_to, *cleanup_minimal_symbols; int stabstrsize; int len; char * target; @@ -593,16 +558,34 @@ coff_symfile_read (struct objfile *objfile, int mainline) /* End of warning */ - /* Read the line number table, all at once. */ info->min_lineno_offset = 0; info->max_lineno_offset = 0; - bfd_map_over_sections (abfd, find_linenos, (void *) info); - make_cleanup (free_linetab_cleanup, 0 /*ignore*/); - val = init_lineno (abfd, info->min_lineno_offset, - info->max_lineno_offset - info->min_lineno_offset); - if (val < 0) - error ("\"%s\": error reading line numbers\n", name); + /* Only read line number information if we have symbols. + + On Windows NT, some of the system's DLL's have sections with + PointerToLinenumbers fields that are non-zero, but point at + random places within the image file. (In the case I found, + KERNEL32.DLL's .text section has a line number info pointer that + points into the middle of the string `lib\\i386\kernel32.dll'.) + + However, these DLL's also have no symbols. The line number + tables are meaningless without symbols. And in fact, GDB never + uses the line number information unless there are symbols. So we + can avoid spurious error messages (and maybe run a little + faster!) by not even reading the line number table unless we have + symbols. */ + if (num_symbols > 0) + { + /* Read the line number table, all at once. */ + bfd_map_over_sections (abfd, find_linenos, (void *) info); + + make_cleanup (free_linetab_cleanup, 0 /*ignore*/); + val = init_lineno (abfd, info->min_lineno_offset, + info->max_lineno_offset - info->min_lineno_offset); + if (val < 0) + error ("\"%s\": error reading line numbers\n", name); + } /* Now read the string table, all at once. */ @@ -612,27 +595,21 @@ coff_symfile_read (struct objfile *objfile, int mainline) error ("\"%s\": can't get string table", name); init_minimal_symbol_collection (); - make_cleanup_discard_minimal_symbols (); + cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols (); /* Now that the executable file is positioned at symbol table, process it and define symbols accordingly. */ coff_symtab_read ((long) symtab_offset, num_symbols, objfile); - /* Sort symbols alphabetically within each block. */ - - { - 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. */ install_minimal_symbols (objfile); + /* Free the installed minimal symbol data. */ + do_cleanups (cleanup_minimal_symbols); + bfd_map_over_sections (abfd, coff_locate_sections, (void *) info); if (info->stabsects) @@ -698,9 +675,9 @@ static void coff_symtab_read (long symtab_offset, unsigned int nsyms, struct objfile *objfile) { - register struct context_stack *new; + struct context_stack *new; struct coff_symbol coff_symbol; - register struct coff_symbol *cs = &coff_symbol; + struct coff_symbol *cs = &coff_symbol; static struct internal_syment main_sym; static union internal_auxent main_aux; struct coff_symbol fcn_cs_saved; @@ -803,7 +780,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, case C_LINE: case C_ALIAS: case C_HIDDEN: - complain (&bad_sclass_complaint, cs->c_name); + complaint (&symfile_complaints, "Bad n_sclass for symbol %s", + cs->c_name); break; case C_FILE: @@ -839,7 +817,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, case C_THUMBSTATFUNC: if (cs->c_name[0] == '.') { - if (STREQ (cs->c_name, ".text")) + if (DEPRECATED_STREQ (cs->c_name, ".text")) { /* FIXME: don't wire in ".text" as section name or symbol name! */ @@ -879,7 +857,6 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, print_address_symbolic work right without the (now gone) "set fast-symbolic-addr off" kludge. */ - /* FIXME: should use mst_abs, and not relocate, if absolute. */ enum minimal_symbol_type ms_type; int sec; @@ -901,12 +878,23 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, || cs->c_sclass == C_THUMBEXT ? mst_bss : mst_file_bss; } + else if (cs->c_secnum == N_ABS) + { + /* Use the correct minimal symbol type (and don't + relocate) for absolute values. */ + ms_type = mst_abs; + sec = cs_to_section (cs, objfile); + tmpaddr = cs->c_value; + } else { sec = cs_to_section (cs, objfile); tmpaddr = cs->c_value; - if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC - || cs->c_sclass == C_THUMBEXT) + /* Statics in a PE file also get relocated */ + if (cs->c_sclass == C_EXT + || cs->c_sclass == C_THUMBEXTFUNC + || cs->c_sclass == C_THUMBEXT + || (pe_file && (cs->c_sclass == C_STAT))) tmpaddr += ANOFFSET (objfile->section_offsets, sec); if (sec == SECT_OFF_TEXT (objfile)) @@ -936,15 +924,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, if (cs->c_name[0] != '@' /* Skip tdesc symbols */ ) { struct minimal_symbol *msym; - - /* FIXME: cagney/2001-02-01: The nasty (int) -> (long) - -> (void*) cast is to ensure that that the value of - cs->c_sclass can be correctly stored in a void - pointer in MSYMBOL_INFO. Better solutions - welcome. */ - gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass)); msym = prim_record_minimal_symbol_and_info - (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass, + (cs->c_name, tmpaddr, ms_type, NULL, sec, NULL, objfile); if (msym) COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym); @@ -961,7 +942,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, break; case C_FCN: - if (STREQ (cs->c_name, ".bf")) + if (DEPRECATED_STREQ (cs->c_name, ".bf")) { within_function = 1; @@ -969,7 +950,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, /* main_aux.x_sym.x_misc.x_lnsz.x_lnno contains line number of '{' } */ if (cs->c_naux != 1) - complain (&bf_no_aux_complaint, cs->c_symnum); + complaint (&symfile_complaints, + "`.bf' symbol %d has no aux entry", cs->c_symnum); fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; fcn_first_line_addr = cs->c_value; @@ -982,7 +964,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, new->name = process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile); } - else if (STREQ (cs->c_name, ".ef")) + else if (DEPRECATED_STREQ (cs->c_name, ".ef")) { if (!within_function) error ("Bad coff function information\n"); @@ -993,7 +975,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, if (context_stack_depth <= 0) { /* We attempted to pop an empty context stack */ - complain (&ef_stack_complaint, cs->c_symnum); + complaint (&symfile_complaints, + "`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", + cs->c_symnum); within_function = 0; break; } @@ -1002,13 +986,16 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, /* Stack must be empty now. */ if (context_stack_depth > 0 || new == NULL) { - complain (&ef_complaint, cs->c_symnum); + complaint (&symfile_complaints, + "Unmatched .ef symbol(s) ignored starting at symnum %d", + cs->c_symnum); within_function = 0; break; } if (cs->c_naux != 1) { - complain (&ef_no_aux_complaint, cs->c_symnum); + complaint (&symfile_complaints, + "`.ef' symbol %d has no aux entry", cs->c_symnum); fcn_last_line = 0x7FFFFFFF; } else @@ -1053,24 +1040,28 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, break; case C_BLOCK: - if (STREQ (cs->c_name, ".bb")) + if (DEPRECATED_STREQ (cs->c_name, ".bb")) { tmpaddr = cs->c_value; tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); push_context (++depth, tmpaddr); } - else if (STREQ (cs->c_name, ".eb")) + else if (DEPRECATED_STREQ (cs->c_name, ".eb")) { if (context_stack_depth <= 0) { /* We attempted to pop an empty context stack */ - complain (&eb_stack_complaint, cs->c_symnum); + complaint (&symfile_complaints, + "`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", + cs->c_symnum); break; } new = pop_context (); if (depth-- != new->depth) { - complain (&eb_complaint, symnum); + complaint (&symfile_complaints, + "Mismatched .eb symbol ignored starting at symnum %d", + symnum); break; } if (local_symbols && context_stack_depth > 0) @@ -1092,6 +1083,13 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, } } + if ((nsyms == 0) && (pe_file)) + { + /* We've got no debugging symbols, but it's is a portable + executable, so try to read the export table */ + read_pe_exported_syms (objfile); + } + if (last_source_file) coff_end_symtab (objfile); @@ -1110,9 +1108,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, in internal_auxent form, and skip any other auxents. */ static void -read_one_sym (register struct coff_symbol *cs, - register struct internal_syment *sym, - register union internal_auxent *aux) +read_one_sym (struct coff_symbol *cs, + struct internal_syment *sym, + union internal_auxent *aux) { int i; @@ -1261,7 +1259,7 @@ static char * coff_getfilename (union internal_auxent *aux_entry) { static char buffer[BUFSIZ]; - register char *temp; + char *temp; char *result; if (aux_entry->x_file.x_n.x_zeroes == 0) @@ -1339,17 +1337,19 @@ free_linetab_cleanup (void *ignore) #endif static void -enter_linenos (long file_offset, register int first_line, - register int last_line, struct objfile *objfile) +enter_linenos (long file_offset, int first_line, + int last_line, struct objfile *objfile) { - register char *rawptr; + char *rawptr; struct internal_lineno lptr; if (!linetab) return; if (file_offset < linetab_offset) { - complain (&lineno_complaint, file_offset); + complaint (&symfile_complaints, + "Line number pointer %ld lower than start of line numbers", + file_offset); if (file_offset > linetab_size) /* Too big to be an offset? */ return; file_offset += linetab_offset; /* Try reading at that linetab offset */ @@ -1362,11 +1362,15 @@ enter_linenos (long file_offset, register int first_line, /* line numbers start at one for the first line of the function */ first_line--; - for (;;) + /* If the line number table is full (e.g. 64K lines in COFF debug + info), the next function's L_LNNO32 might not be zero, so don't + overstep the table's end in any case. */ + while (rawptr <= &linetab[0] + linetab_size) { bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr); rawptr += local_linesz; - /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */ + /* The next function, or the sentinel, will have L_LNNO32 zero; + we exit. */ if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line) record_line (current_subfile, first_line + L_LNNO32 (&lptr), lptr.l_addr.l_paddr @@ -1379,8 +1383,8 @@ enter_linenos (long file_offset, register int first_line, static void patch_type (struct type *type, struct type *real_type) { - register struct type *target = TYPE_TARGET_TYPE (type); - register struct type *real_target = TYPE_TARGET_TYPE (real_type); + struct type *target = TYPE_TARGET_TYPE (type); + struct type *real_target = TYPE_TARGET_TYPE (real_type); int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field); TYPE_LENGTH (target) = TYPE_LENGTH (real_target); @@ -1403,33 +1407,32 @@ patch_type (struct type *type, struct type *real_type) static void patch_opaque_types (struct symtab *s) { - register struct block *b; - register int i; - register struct symbol *real_sym; + struct block *b; + struct dict_iterator iter; + struct symbol *real_sym; /* Go through the per-file symbols only */ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); - for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--) + ALL_BLOCK_SYMBOLS (b, iter, real_sym) { /* Find completed typedefs to use to fix opaque ones. Remove syms from the chain when their types are stored, but search the whole chain, as there may be several syms from different files with the same name. */ - real_sym = BLOCK_SYM (b, i); if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF && - SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE && + SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN && TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0) { - register char *name = SYMBOL_NAME (real_sym); - register int hash = hashname (name); - register struct symbol *sym, *prev; + char *name = DEPRECATED_SYMBOL_NAME (real_sym); + int hash = hashname (name); + struct symbol *sym, *prev; prev = 0; for (sym = opaque_type_chain[hash]; sym;) { - if (name[0] == SYMBOL_NAME (sym)[0] && - STREQ (name + 1, SYMBOL_NAME (sym) + 1)) + if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] && + strcmp (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0) { if (prev) { @@ -1462,26 +1465,24 @@ patch_opaque_types (struct symtab *s) } static struct symbol * -process_coff_symbol (register struct coff_symbol *cs, - register union internal_auxent *aux, +process_coff_symbol (struct coff_symbol *cs, + union internal_auxent *aux, struct objfile *objfile) { - register struct symbol *sym - = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, + struct symbol *sym + = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); char *name; memset (sym, 0, sizeof (struct symbol)); name = cs->c_name; name = EXTERNAL_NAME (name, objfile->obfd); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - &objfile->symbol_obstack); SYMBOL_LANGUAGE (sym) = language_auto; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); /* default assumptions */ SYMBOL_VALUE (sym) = cs->c_value; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_SECTION (sym) = cs_to_section (cs, objfile); if (ISFCN (cs->c_type)) @@ -1603,7 +1604,7 @@ process_coff_symbol (register struct coff_symbol *cs, case C_TPDEF: SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; /* If type has no name, give it one */ if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) @@ -1633,13 +1634,8 @@ process_coff_symbol (register struct coff_symbol *cs, } else TYPE_NAME (SYMBOL_TYPE (sym)) = - concat (SYMBOL_NAME (sym), NULL); + concat (DEPRECATED_SYMBOL_NAME (sym), NULL); } -#ifdef CXUX_TARGET - /* Ignore vendor section for Harris CX/UX targets. */ - else if (cs->c_name[0] == '$') - break; -#endif /* CXUX_TARGET */ /* Keep track of any type which points to empty structured type, so it can be filled from a definition from another file. A @@ -1651,7 +1647,7 @@ process_coff_symbol (register struct coff_symbol *cs, TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) != TYPE_CODE_UNDEF) { - register int i = hashname (SYMBOL_NAME (sym)); + int i = hashname (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i]; opaque_type_chain[i] = sym; @@ -1663,17 +1659,17 @@ process_coff_symbol (register struct coff_symbol *cs, case C_UNTAG: case C_ENTAG: SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; /* Some compilers try to be helpful by inventing "fake" names for anonymous enums, structures, and unions, like "~0fake" or ".0fake". Thanks, but no thanks... */ if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0) - if (SYMBOL_NAME (sym) != NULL - && *SYMBOL_NAME (sym) != '~' - && *SYMBOL_NAME (sym) != '.') + if (DEPRECATED_SYMBOL_NAME (sym) != NULL + && *DEPRECATED_SYMBOL_NAME (sym) != '~' + && *DEPRECATED_SYMBOL_NAME (sym) != '.') TYPE_TAG_NAME (SYMBOL_TYPE (sym)) = - concat (SYMBOL_NAME (sym), NULL); + concat (DEPRECATED_SYMBOL_NAME (sym), NULL); add_symbol_to_list (sym, &file_symbols); break; @@ -1688,10 +1684,10 @@ process_coff_symbol (register struct coff_symbol *cs, /* Decode a coff type specifier; return the type that is meant. */ static struct type * -decode_type (register struct coff_symbol *cs, unsigned int c_type, - register union internal_auxent *aux) +decode_type (struct coff_symbol *cs, unsigned int c_type, + union internal_auxent *aux) { - register struct type *type = 0; + struct type *type = 0; unsigned int new_c_type; if (c_type & ~N_BTMASK) @@ -1710,7 +1706,7 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type, else if (ISARY (c_type)) { int i, n; - register unsigned short *dim; + unsigned short *dim; struct type *base_type, *index_type, *range_type; /* Define an array type. */ @@ -1755,7 +1751,9 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type, } else { - complain (&tagndx_bad_complaint, cs->c_name); + complaint (&symfile_complaints, + "Symbol table entry for %s has bad tagndx value", + cs->c_name); /* And fall through to decode_base_type... */ } } @@ -1767,8 +1765,8 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type, return the type that the function returns. */ static struct type * -decode_function_type (register struct coff_symbol *cs, unsigned int c_type, - register union internal_auxent *aux) +decode_function_type (struct coff_symbol *cs, unsigned int c_type, + union internal_auxent *aux) { if (aux->x_sym.x_tagndx.l == 0) cs->c_naux = 0; /* auxent refers to function, not base type */ @@ -1779,8 +1777,8 @@ decode_function_type (register struct coff_symbol *cs, unsigned int c_type, /* basic C types */ static struct type * -decode_base_type (register struct coff_symbol *cs, unsigned int c_type, - register union internal_auxent *aux) +decode_base_type (struct coff_symbol *cs, unsigned int c_type, + union internal_auxent *aux) { struct type *type; @@ -1790,15 +1788,6 @@ decode_base_type (register struct coff_symbol *cs, unsigned int c_type, /* shows up with "void (*foo)();" structure members */ return lookup_fundamental_type (current_objfile, FT_VOID); -#if 0 -/* DGUX actually defines both T_ARG and T_VOID to the same value. */ -#ifdef T_ARG - case T_ARG: - /* Shows up in DGUX, I think. Not sure where. */ - return lookup_fundamental_type (current_objfile, FT_VOID); /* shouldn't show up here */ -#endif -#endif /* 0 */ - #ifdef T_VOID case T_VOID: /* Intel 960 COFF has this symbol and meaning. */ @@ -1921,7 +1910,7 @@ decode_base_type (register struct coff_symbol *cs, unsigned int c_type, else return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG); } - complain (&unexpected_type_complaint, cs->c_name); + complaint (&symfile_complaints, "Unexpected type for symbol %s", cs->c_name); return lookup_fundamental_type (current_objfile, FT_VOID); } @@ -1939,14 +1928,14 @@ coff_read_struct_type (int index, int length, int lastsym) struct field field; }; - register struct type *type; - register struct nextfield *list = 0; + struct type *type; + struct nextfield *list = 0; struct nextfield *new; int nfields = 0; - register int n; + int n; char *name; struct coff_symbol member_sym; - register struct coff_symbol *ms = &member_sym; + struct coff_symbol *ms = &member_sym; struct internal_syment sub_sym; union internal_auxent sub_aux; int done = 0; @@ -1976,10 +1965,11 @@ coff_read_struct_type (int index, int length, int lastsym) list->field.name = obsavestring (name, strlen (name), - ¤t_objfile->symbol_obstack); + ¤t_objfile->objfile_obstack); FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux); FIELD_BITPOS (list->field) = 8 * ms->c_value; FIELD_BITSIZE (list->field) = 0; + FIELD_STATIC_KIND (list->field) = 0; nfields++; break; @@ -1994,10 +1984,11 @@ coff_read_struct_type (int index, int length, int lastsym) list->field.name = obsavestring (name, strlen (name), - ¤t_objfile->symbol_obstack); + ¤t_objfile->objfile_obstack); FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux); FIELD_BITPOS (list->field) = ms->c_value; FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size; + FIELD_STATIC_KIND (list->field) = 0; nfields++; break; @@ -2024,22 +2015,21 @@ coff_read_struct_type (int index, int length, int lastsym) and create and return a suitable type object. Also defines the symbols that represent the values of the type. */ -/* ARGSUSED */ static struct type * coff_read_enum_type (int index, int length, int lastsym) { - register struct symbol *sym; - register struct type *type; + struct symbol *sym; + struct type *type; int nsyms = 0; int done = 0; struct pending **symlist; struct coff_symbol member_sym; - register struct coff_symbol *ms = &member_sym; + struct coff_symbol *ms = &member_sym; struct internal_syment sub_sym; union internal_auxent sub_aux; struct pending *osyms, *syms; int o_nsyms; - register int n; + int n; char *name; int unsigned_enum = 1; @@ -2061,15 +2051,15 @@ coff_read_enum_type (int index, int length, int lastsym) { case C_MOE: sym = (struct symbol *) obstack_alloc - (¤t_objfile->symbol_obstack, + (¤t_objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = + DEPRECATED_SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - ¤t_objfile->symbol_obstack); + ¤t_objfile->objfile_obstack); SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_VALUE (sym) = ms->c_value; add_symbol_to_list (sym, symlist); nsyms++; @@ -2113,11 +2103,12 @@ coff_read_enum_type (int index, int length, int lastsym) { struct symbol *xsym = syms->symbol[j]; SYMBOL_TYPE (xsym) = type; - TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym); + TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym); TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); if (SYMBOL_VALUE (xsym) < 0) unsigned_enum = 0; TYPE_FIELD_BITSIZE (type, n) = 0; + TYPE_FIELD_STATIC_KIND (type, n) = 0; } if (syms == osyms) break; diff --git a/contrib/gdb/gdb/command.h b/contrib/gdb/gdb/command.h index 7c20a429078..c4a5f20edd3 100644 --- a/contrib/gdb/gdb/command.h +++ b/contrib/gdb/gdb/command.h @@ -1,13 +1,7 @@ -/* ***DEPRECATED*** The gdblib files must not be calling/using things in any - of the possible command languages. If necessary, a hook (that may be - present or not) must be used and set to the appropriate routine by any - command language that cares about it. If you are having to include this - file you are possibly doing things the old way. This file will disapear. - 2000-12-01 fnasser@redhat.com */ - /* Header file for command-reading library command.c. - Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000 - Free Software Foundation, Inc. + + Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1999, + 2000, 2002 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 @@ -44,6 +38,8 @@ enum command_class class_pseudo, class_tui, class_xdb }; +/* FIXME: cagney/2002-03-17: Once cmd_type() has been removed, ``enum + cmd_types'' can be moved from "command.h" to "cli-decode.h". */ /* Not a set/show command. Note that some commands which begin with "set" or "show" might be in this category, if their syntax does not fall into one of the following categories. */ @@ -55,14 +51,6 @@ typedef enum cmd_types } cmd_types; -/* Reasonable values for an AUTO_BOOLEAN variable. */ -enum cmd_auto_boolean -{ - CMD_AUTO_BOOLEAN_TRUE, - CMD_AUTO_BOOLEAN_FALSE, - CMD_AUTO_BOOLEAN_AUTO -}; - /* Types of "set" or "show" command. */ typedef enum var_types { @@ -71,9 +59,9 @@ typedef enum var_types var_boolean, /* "on" / "true" / "enable" or "off" / "false" / "disable" or - "auto. *VAR is an ``enum cmd_auto_boolean''. NOTE: In general - a custom show command will need to be implemented - one that - for "auto" prints both the "auto" and the current auto-selected + "auto. *VAR is an ``enum auto_boolean''. NOTE: In general a + custom show command will need to be implemented - one that for + "auto" prints both the "auto" and the current auto-selected value. */ var_auto_boolean, @@ -105,156 +93,7 @@ typedef enum var_types var_types; /* This structure records one command'd definition. */ - - -/* This flag is used by the code executing commands to warn the user - the first time a deprecated command is used, see the 'flags' field in - the following struct. -*/ -#define CMD_DEPRECATED 0x1 -#define DEPRECATED_WARN_USER 0x2 -#define MALLOCED_REPLACEMENT 0x4 - -struct cmd_list_element - { - /* Points to next command in this list. */ - struct cmd_list_element *next; - - /* Name of this command. */ - char *name; - - /* Command class; class values are chosen by application program. */ - enum command_class class; - - /* Function definition of this command. NULL for command class - names and for help topics that are not really commands. NOTE: - cagney/2002-02-02: This function signature is evolving. For - the moment suggest sticking with either set_cmd_cfunc() or - set_cmd_sfunc(). */ - void (*func) (struct cmd_list_element *c, char *args, int from_tty); - /* The command's real callback. At present func() bounces through - to one of the below. */ - union - { - /* If type is not_set_cmd, call it like this: */ - void (*cfunc) (char *args, int from_tty); - - /* If type is set_cmd or show_cmd, first set the variables, and - then call this. */ - void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c); - } - function; - - /* Documentation of this command (or help topic). - First line is brief documentation; remaining lines form, with it, - the full documentation. First line should end with a period. - Entire string should also end with a period, not a newline. */ - char *doc; - - /* flags : a bitfield - - bit 0: (LSB) CMD_DEPRECATED, when 1 indicated that this command - is deprecated. It may be removed from gdb's command set in the - future. - - bit 1: DEPRECATED_WARN_USER, the user needs to be warned that - this is a deprecated command. The user should only be warned - the first time a command is used. - - bit 2: MALLOCED_REPLACEMENT, when functions are deprecated at - compile time (this is the way it should, in general, be done) - the memory containing the replacement string is statically - allocated. In some cases it makes sense to deprecate commands - at runtime (the testsuite is one example). In this case the - memory for replacement is malloc'ed. When a command is - undeprecated or re-deprecated at runtime we don't want to risk - calling free on statically allocated memory, so we check this - flag. - */ - int flags; - - /* if this command is deprecated, this is the replacement name */ - char *replacement; - - /* If this command represents a show command, then this function - is called before the variable's value is examined. */ - void (*pre_show_hook) (struct cmd_list_element *c); - - /* Hook for another command to be executed before this command. */ - struct cmd_list_element *hook_pre; - - /* Hook for another command to be executed after this command. */ - struct cmd_list_element *hook_post; - - /* Flag that specifies if this command is already running it's hook. */ - /* Prevents the possibility of hook recursion. */ - int hook_in; - - /* Nonzero identifies a prefix command. For them, the address - of the variable containing the list of subcommands. */ - struct cmd_list_element **prefixlist; - - /* For prefix commands only: - String containing prefix commands to get here: this one - plus any others needed to get to it. Should end in a space. - It is used before the word "command" in describing the - commands reached through this prefix. */ - char *prefixname; - - /* For prefix commands only: - nonzero means do not get an error if subcommand is not - recognized; call the prefix's own function in that case. */ - char allow_unknown; - - /* Nonzero says this is an abbreviation, and should not - be mentioned in lists of commands. - This allows "br" to complete to "break", which it - otherwise wouldn't. */ - char abbrev_flag; - - /* Completion routine for this command. TEXT is the text beyond - what was matched for the command itself (leading whitespace is - skipped). It stops where we are supposed to stop completing - (rl_point) and is '\0' terminated. - - Return value is a malloc'd vector of pointers to possible completions - terminated with NULL. If there are no completions, returning a pointer - to a NULL would work but returning NULL itself is also valid. - WORD points in the same buffer as TEXT, and completions should be - returned relative to this position. For example, suppose TEXT is "foo" - and we want to complete to "foobar". If WORD is "oo", return - "oobar"; if WORD is "baz/foo", return "baz/foobar". */ - char **(*completer) (char *text, char *word); - - /* Type of "set" or "show" command (or SET_NOT_SET if not "set" - or "show"). */ - cmd_types type; - - /* Pointer to variable affected by "set" and "show". Doesn't matter - if type is not_set. */ - void *var; - - /* What kind of variable is *VAR? */ - var_types var_type; - - /* Pointer to NULL terminated list of enumerated values (like argv). */ - const char **enums; - - /* Pointer to command strings of user-defined commands */ - struct command_line *user_commands; - - /* Pointer to command that is hooked by this one, (by hook_pre) - so the hook can be removed when this one is deleted. */ - struct cmd_list_element *hookee_pre; - - /* Pointer to command that is hooked by this one, (by hook_post) - so the hook can be removed when this one is deleted. */ - struct cmd_list_element *hookee_post; - - /* Pointer to command that is aliased by this one, so the - aliased command can be located in case it has been hooked. */ - struct cmd_list_element *cmd_pointer; - }; +struct cmd_list_element; /* Forward-declarations of the entry-points of cli/cli-decode.c. */ @@ -285,18 +124,46 @@ extern struct cmd_list_element *add_abbrev_prefix_cmd (char *, /* Set the commands corresponding callback. */ +typedef void cmd_cfunc_ftype (char *args, int from_tty); extern void set_cmd_cfunc (struct cmd_list_element *cmd, - void (*cfunc) (char *args, int from_tty)); + cmd_cfunc_ftype *cfunc); +typedef void cmd_sfunc_ftype (char *args, int from_tty, + struct cmd_list_element *c); extern void set_cmd_sfunc (struct cmd_list_element *cmd, - void (*sfunc) (char *args, int from_tty, - struct cmd_list_element * c)); + cmd_sfunc_ftype *sfunc); + +extern void set_cmd_completer (struct cmd_list_element *cmd, + char **(*completer) (char *text, char *word)); /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs around in cmd objects to test the value of the commands sfunc(). */ extern int cmd_cfunc_eq (struct cmd_list_element *cmd, void (*cfunc) (char *args, int from_tty)); +/* Each command object has a local context attached to it. . */ +extern void set_cmd_context (struct cmd_list_element *cmd, void *context); +extern void *get_cmd_context (struct cmd_list_element *cmd); + + +/* Execute CMD's pre/post hook. Throw an error if the command fails. + If already executing this pre/post hook, or there is no pre/post + hook, the call is silently ignored. */ +extern void execute_cmd_pre_hook (struct cmd_list_element *cmd); +extern void execute_cmd_post_hook (struct cmd_list_element *cmd); + +/* Return the type of the command. */ +/* NOTE: cagney/2002-03-17: The add_show_from_set() function clones + the set command passed as a parameter. The clone operation will + include (BUG?) any ``set'' command callback, if present. Commands + like ``info set'' call all the ``show'' command callbacks. + Unfortunately, for ``show'' commands cloned from ``set'', this + includes callbacks belonging to ``set'' commands. Making this + worse, this only occures if add_show_from_set() is called after + add_cmd_sfunc() (BUG?). */ +extern enum cmd_types cmd_type (struct cmd_list_element *cmd); + + extern struct cmd_list_element *lookup_cmd (char **, struct cmd_list_element *, char *, int, int); @@ -343,6 +210,26 @@ extern void help_list (struct cmd_list_element *, char *, extern void help_cmd_list (struct cmd_list_element *, enum command_class, char *, int, struct ui_file *); +extern void add_setshow_cmd (char *name, + enum command_class class, + var_types var_type, void *var, + char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list); + +extern void add_setshow_cmd_full (char *name, + enum command_class class, + var_types var_type, void *var, + char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list, + struct cmd_list_element **set_result, + struct cmd_list_element **show_result); + extern struct cmd_list_element *add_set_cmd (char *name, enum command_class class, var_types var_type, void *var, @@ -356,17 +243,34 @@ extern struct cmd_list_element *add_set_enum_cmd (char *name, char *doc, struct cmd_list_element **list); -extern struct cmd_list_element *add_set_auto_boolean_cmd (char *name, - enum command_class class, - enum cmd_auto_boolean *var, - char *doc, - struct cmd_list_element **list); +extern void add_setshow_auto_boolean_cmd (char *name, + enum command_class class, + enum auto_boolean *var, + char *set_doc, char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list); -extern struct cmd_list_element *add_set_boolean_cmd (char *name, - enum command_class class, - int *var, - char *doc, - struct cmd_list_element **list); +extern void add_setshow_boolean_cmd (char *name, + enum command_class class, + int *var, + char *set_doc, + char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list); + +extern void add_setshow_uinteger_cmd (char *name, + enum command_class class, + unsigned int *var, + char *set_doc, + char *show_doc, + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, + struct cmd_list_element **set_list, + struct cmd_list_element **show_list); extern struct cmd_list_element *add_show_from_set (struct cmd_list_element *, struct cmd_list_element @@ -386,4 +290,10 @@ extern void dont_repeat (void); extern void not_just_help_class_command (char *, int); +/* check function pointer */ +extern int cmd_func_p (struct cmd_list_element *cmd); + +/* call the command function */ +extern void cmd_func (struct cmd_list_element *cmd, char *args, int from_tty); + #endif /* !defined (COMMAND_H) */ diff --git a/contrib/gdb/gdb/complaints.c b/contrib/gdb/gdb/complaints.c index 04e49a23979..ed24f432406 100644 --- a/contrib/gdb/gdb/complaints.c +++ b/contrib/gdb/gdb/complaints.c @@ -1,6 +1,7 @@ /* Support for complaint handling during symbol reading in GDB. - Copyright 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000 - Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000, 2002 Free + Software Foundation, Inc. This file is part of GDB. @@ -21,148 +22,300 @@ #include "defs.h" #include "complaints.h" +#include "gdb_assert.h" +#include "command.h" #include "gdbcmd.h" extern void _initialize_complaints (void); -/* Structure to manage complaints about symbol file contents. */ +/* Should each complaint message be self explanatory, or should we assume that + a series of complaints is being produced? */ -struct complaint complaint_root[1] = -{ - { - (char *) NULL, /* Complaint message */ - 0, /* Complaint counter */ - complaint_root /* Next complaint. */ - } +/* case 1: First message of a series that must + start off with explanation. case 2: Subsequent message of a series + that needs no explanation (the user already knows we have a problem + so we can just state our piece). */ +enum complaint_series { + /* Isolated self explanatory message. */ + ISOLATED_MESSAGE, + /* First message of a series, includes an explanation. */ + FIRST_MESSAGE, + /* First message of a series, but does not need to include any sort + of explanation. */ + SHORT_FIRST_MESSAGE, + /* Subsequent message of a series that needs no explanation (the + user already knows we have a problem so we can just state our + piece). */ + SUBSEQUENT_MESSAGE }; -/* How many complaints about a particular thing should be printed before - we stop whining about it? Default is no whining at all, since so many - systems have ill-constructed symbol files. */ +/* Structure to manage complaints about symbol file contents. */ + +struct complain +{ + const char *file; + int line; + const char *fmt; + int counter; + struct complain *next; +}; + +/* The explanatory message that should accompany the complaint. The + message is in two parts - pre and post - that are printed around + the complaint text. */ +struct explanation +{ + const char *prefix; + const char *postfix; +}; + +struct complaints +{ + struct complain *root; + + /* Should each complaint be self explanatory, or should we assume + that a series of complaints is being produced? case 0: Isolated + self explanatory message. case 1: First message of a series that + must start off with explanation. case 2: Subsequent message of a + series that needs no explanation (the user already knows we have + a problem so we can just state our piece). */ + int series; + + /* The explanatory messages that should accompany the complaint. + NOTE: cagney/2002-08-14: In a desperate attempt at being vaguely + i18n friendly, this is an array of two messages. When present, + the PRE and POST EXPLANATION[SERIES] are used to wrap the + message. */ + const struct explanation *explanation; +}; + +static struct complain complaint_sentinel; + +/* The symbol table complaint table. */ + +static struct explanation symfile_explanations[] = { + { "During symbol reading, ", "." }, + { "During symbol reading...", "..."}, + { "", "..."}, + { "", "..."}, + { NULL, NULL } +}; + +static struct complaints symfile_complaint_book = { + &complaint_sentinel, + 0, + symfile_explanations +}; +struct complaints *symfile_complaints = &symfile_complaint_book; + +/* Wrapper function to, on-demand, fill in a complaints object. */ + +static struct complaints * +get_complaints (struct complaints **c) +{ + if ((*c) != NULL) + return (*c); + (*c) = XMALLOC (struct complaints); + (*c)->root = &complaint_sentinel; + (*c)->series = ISOLATED_MESSAGE; + (*c)->explanation = NULL; + return (*c); +} + +static struct complain * +find_complaint (struct complaints *complaints, const char *file, + int line, const char *fmt) +{ + struct complain *complaint; + + /* Find the complaint in the table. A more efficient search + algorithm (based on hash table or something) could be used. But + that can wait until someone shows evidence that this lookup is + a real bottle neck. */ + for (complaint = complaints->root; + complaint != NULL; + complaint = complaint->next) + { + if (complaint->fmt == fmt + && complaint->file == file + && complaint->line == line) + return complaint; + } + + /* Oops not seen before, fill in a new complaint. */ + complaint = XMALLOC (struct complain); + complaint->fmt = fmt; + complaint->file = file; + complaint->line = line; + complaint->counter = 0; + complaint->next = NULL; + + /* File it, return it. */ + complaint->next = complaints->root; + complaints->root = complaint; + return complaint; +} + + +/* How many complaints about a particular thing should be printed + before we stop whining about it? Default is no whining at all, + since so many systems have ill-constructed symbol files. */ static unsigned int stop_whining = 0; -/* Should each complaint be self explanatory, or should we assume that - a series of complaints is being produced? - case 0: self explanatory message. - case 1: First message of a series that must start off with explanation. - case 2: Subsequent message, when user already knows we are reading - symbols and we can just state our piece. */ +/* Print a complaint, and link the complaint block into a chain for + later handling. */ -static int complaint_series = 0; - - - -/* Functions to handle complaints during symbol reading. */ - -/* Print a complaint about the input symbols, and link the complaint block - into a chain for later handling. */ - -void -complain (struct complaint *complaint,...) +static void +vcomplaint (struct complaints **c, const char *file, int line, const char *fmt, + va_list args) { - va_list args; - va_start (args, complaint); + struct complaints *complaints = get_complaints (c); + struct complain *complaint = find_complaint (complaints, file, line, fmt); + enum complaint_series series; + gdb_assert (complaints != NULL); complaint->counter++; - if (complaint->next == NULL) - { - complaint->next = complaint_root->next; - complaint_root->next = complaint; - } if (complaint->counter > stop_whining) + return; + + if (info_verbose) + series = SUBSEQUENT_MESSAGE; + else + series = complaints->series; + + if (complaint->file != NULL) + internal_vwarning (complaint->file, complaint->line, complaint->fmt, args); + else if (warning_hook) + (*warning_hook) (complaint->fmt, args); + else { - return; + if (complaints->explanation == NULL) + /* A [v]warning() call always appends a newline. */ + vwarning (complaint->fmt, args); + else + { + char *msg; + struct cleanup *cleanups; + xvasprintf (&msg, complaint->fmt, args); + cleanups = make_cleanup (xfree, msg); + wrap_here (""); + if (series != SUBSEQUENT_MESSAGE) + begin_line (); + fprintf_filtered (gdb_stderr, "%s%s%s", + complaints->explanation[series].prefix, msg, + complaints->explanation[series].postfix); + /* Force a line-break after any isolated message. For the + other cases, clear_complaints() takes care of any missing + trailing newline, the wrap_here() is just a hint. */ + if (series == ISOLATED_MESSAGE) + /* It would be really nice to use begin_line() here. + Unfortunately that function doesn't track GDB_STDERR and + consequently will sometimes supress a line when it + shouldn't. */ + fputs_filtered ("\n", gdb_stderr); + else + wrap_here (""); + do_cleanups (cleanups); + } } - wrap_here (""); - switch (complaint_series + (info_verbose << 1)) + switch (series) { - - /* Isolated messages, must be self-explanatory. */ - case 0: - if (warning_hook) - (*warning_hook) (complaint->message, args); - else - { - begin_line (); - fputs_filtered ("During symbol reading, ", gdb_stderr); - wrap_here (""); - vfprintf_filtered (gdb_stderr, complaint->message, args); - fputs_filtered (".\n", gdb_stderr); - } + case ISOLATED_MESSAGE: break; - - /* First of a series, without `set verbose'. */ - case 1: - if (warning_hook) - (*warning_hook) (complaint->message, args); - else - { - begin_line (); - fputs_filtered ("During symbol reading...", gdb_stderr); - vfprintf_filtered (gdb_stderr, complaint->message, args); - fputs_filtered ("...", gdb_stderr); - wrap_here (""); - complaint_series++; - } + case FIRST_MESSAGE: + complaints->series = SUBSEQUENT_MESSAGE; + break; + case SUBSEQUENT_MESSAGE: + case SHORT_FIRST_MESSAGE: + complaints->series = SUBSEQUENT_MESSAGE; break; - - /* Subsequent messages of a series, or messages under `set verbose'. - (We'll already have produced a "Reading in symbols for XXX..." - message and will clean up at the end with a newline.) */ - default: - if (warning_hook) - (*warning_hook) (complaint->message, args); - else - { - vfprintf_filtered (gdb_stderr, complaint->message, args); - fputs_filtered ("...", gdb_stderr); - wrap_here (""); - } } - /* 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. */ + + /* 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. */ + gdb_flush (gdb_stderr); +} + +void +complaint (struct complaints **complaints, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + vcomplaint (complaints, NULL/*file*/, 0/*line*/, fmt, args); va_end (args); } -/* Clear out all complaint counters that have ever been incremented. - If sym_reading is 1, be less verbose about successive complaints, - since the messages are appearing all together during a command that - reads symbols (rather than scattered around as psymtabs get fleshed - out into symtabs at random times). If noisy is 1, we are in a - noisy symbol reading command, and our caller will print enough - context for the user to figure it out. */ +void +internal_complaint (struct complaints **complaints, const char *file, + int line, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + vcomplaint (complaints, file, line, fmt, args); + va_end (args); +} + +/* Clear out / initialize all complaint counters that have ever been + incremented. If LESS_VERBOSE is 1, be less verbose about + successive complaints, since the messages are appearing all + together during a command that is reporting a contiguous block of + complaints (rather than being interleaved with other messages). If + noisy is 1, we are in a noisy command, and our caller will print + enough context for the user to figure it out. */ void -clear_complaints (int sym_reading, int noisy) +clear_complaints (struct complaints **c, int less_verbose, int noisy) { - struct complaint *p; + struct complaints *complaints = get_complaints (c); + struct complain *p; - for (p = complaint_root->next; p != complaint_root; p = p->next) + for (p = complaints->root; p != NULL; p = p->next) { p->counter = 0; } - if (!sym_reading && !noisy && complaint_series > 1 && !warning_hook) + switch (complaints->series) { - /* Terminate previous series, since caller won't. */ - puts_filtered ("\n"); + case FIRST_MESSAGE: + /* Haven't yet printed anything. */ + break; + case SHORT_FIRST_MESSAGE: + /* Haven't yet printed anything. */ + break; + case ISOLATED_MESSAGE: + /* The code above, always forces a line-break. No need to do it + here. */ + break; + case SUBSEQUENT_MESSAGE: + /* It would be really nice to use begin_line() here. + Unfortunately that function doesn't track GDB_STDERR and + consequently will sometimes supress a line when it shouldn't. */ + fputs_unfiltered ("\n", gdb_stderr); + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); } - complaint_series = sym_reading ? 1 + noisy : 0; + if (!less_verbose) + complaints->series = ISOLATED_MESSAGE; + else if (!noisy) + complaints->series = FIRST_MESSAGE; + else + complaints->series = SHORT_FIRST_MESSAGE; } void _initialize_complaints (void) { - add_show_from_set - (add_set_cmd ("complaints", class_support, var_zinteger, - (char *) &stop_whining, - "Set max number of complaints about incorrect symbols.", - &setlist), - &showlist); + add_setshow_cmd ("complaints", class_support, var_zinteger, + &stop_whining, + "Set max number of complaints about incorrect symbols.", + "Show max number of complaints about incorrect symbols.", + NULL, NULL, + &setlist, &showlist); } diff --git a/contrib/gdb/gdb/complaints.h b/contrib/gdb/gdb/complaints.h index ecd822f5b04..0168b524195 100644 --- a/contrib/gdb/gdb/complaints.h +++ b/contrib/gdb/gdb/complaints.h @@ -1,6 +1,7 @@ /* Definitions for complaint handling during symbol reading in GDB. - Copyright 1990, 1991, 1992, 1995, 1998, 2000 - Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1995, 1998, 2000, 2002 Free Software + Foundation, Inc. This file is part of GDB. @@ -23,31 +24,30 @@ #if !defined (COMPLAINTS_H) #define COMPLAINTS_H +/* Opaque object used to track the number of complaints of a + particular category. */ +struct complaints; -/* Support for complaining about things in the symbol file that aren't - catastrophic. +/* Predefined categories. */ +extern struct complaints *symfile_complaints; - Each such thing gets a counter. The first time we have the problem, - during a symbol read, we report it. At the end of symbol reading, - if verbose, we report how many of each problem we had. */ +/* Register a complaint. */ +extern void complaint (struct complaints **complaints, const char *fmt, + ...) ATTR_FORMAT (printf, 2, 3); +extern void internal_complaint (struct complaints **complaints, + const char *file, int line, const char *fmt, + ...) ATTR_FORMAT (printf, 4, 5); -struct complaint - { - char *message; - unsigned counter; - struct complaint *next; - }; +/* Clear out / initialize all complaint counters that have ever been + incremented. If LESS_VERBOSE is 1, be less verbose about + successive complaints, since the messages are appearing all + together during a command that is reporting a contiguous block of + complaints (rather than being interleaved with other messages). If + noisy is 1, we are in a noisy command, and our caller will print + enough context for the user to figure it out. */ -/* Root of the chain of complaints that have at some point been issued. - This is used to reset the counters, and/or report the total counts. */ - -extern struct complaint complaint_root[1]; - -/* Functions that handle complaints. (in complaints.c) */ - -extern void complain (struct complaint *, ...); - -extern void clear_complaints (int, int); +extern void clear_complaints (struct complaints **complaints, + int less_verbose, int noisy); #endif /* !defined (COMPLAINTS_H) */ diff --git a/contrib/gdb/gdb/completer.c b/contrib/gdb/gdb/completer.c index 30a84d69e74..bcd7239cea3 100644 --- a/contrib/gdb/gdb/completer.c +++ b/contrib/gdb/gdb/completer.c @@ -23,14 +23,17 @@ #include "gdbtypes.h" #include "expression.h" #include "filenames.h" /* for DOSish file names */ +#include "language.h" + +#include "cli/cli-decode.h" /* FIXME: This is needed because of lookup_cmd_1(). We should be calling a hook instead so we eliminate the CLI dependency. */ #include "gdbcmd.h" /* Needed for rl_completer_word_break_characters() and for - filename_completion_function. */ -#include + rl_filename_completion_function. */ +#include "readline/readline.h" /* readline defines this. */ #undef savestring @@ -38,7 +41,8 @@ #include "completer.h" /* Prototypes for local functions */ -char *line_completion_function (char *text, int matches, char *line_buffer, +static +char *line_completion_function (const char *text, int matches, char *line_buffer, int point); /* readline uses the word breaks for two things: @@ -48,13 +52,11 @@ char *line_completion_function (char *text, int matches, char *line_buffer, it does affect how much stuff M-? lists. (2) If one of the matches contains a word break character, readline will quote it. That's why we switch between - gdb_completer_word_break_characters and + current_language->la_word_break_characters() and gdb_completer_command_word_break_characters. I'm not sure when we need this behavior (perhaps for funky characters in C++ symbols?). */ /* Variables which are necessary for fancy command line editing. */ -static char *gdb_completer_word_break_characters = -" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-"; /* When completing on command names, we remove '-' from the list of word break characters, since we use it in command names. If the @@ -87,12 +89,6 @@ static char *gdb_completer_quote_characters = "'"; /* Accessor for some completer data that may interest other files. */ -char * -get_gdb_completer_word_break_characters (void) -{ - return gdb_completer_word_break_characters; -} - char * get_gdb_completer_quote_characters (void) { @@ -102,7 +98,7 @@ get_gdb_completer_quote_characters (void) /* Line completion interface function for readline. */ char * -readline_line_completion_function (char *text, int matches) +readline_line_completion_function (const char *text, int matches) { return line_completion_function (text, matches, rl_line_buffer, rl_point); } @@ -133,7 +129,7 @@ filename_completer (char *text, char *word) while (1) { char *p; - p = filename_completion_function (text, subsequent_name); + p = rl_filename_completion_function (text, subsequent_name); if (return_val_used >= return_val_alloced) { return_val_alloced *= 2; @@ -248,7 +244,7 @@ location_completer (char *text, char *word) colon = p; symbol_start = p + 1; } - else if (strchr (gdb_completer_word_break_characters, *p)) + else if (strchr (current_language->la_word_break_characters(), *p)) symbol_start = p + 1; } @@ -380,7 +376,7 @@ command_completer (char *text, char *word) should pretend that the line ends at POINT. */ char ** -complete_line (char *text, char *line_buffer, int point) +complete_line (const char *text, char *line_buffer, int point) { char **list = NULL; char *tmp_command, *p; @@ -396,7 +392,7 @@ complete_line (char *text, char *line_buffer, int point) '-' character used in some commands. */ rl_completer_word_break_characters = - gdb_completer_word_break_characters; + current_language->la_word_break_characters(); /* Decide whether to complete on a list of gdb commands or on symbols. */ tmp_command = (char *) alloca (point + 1); @@ -626,8 +622,8 @@ complete_line (char *text, char *line_buffer, int point) which is a possible completion, it is the caller's responsibility to free the string. */ -char * -line_completion_function (char *text, int matches, char *line_buffer, int point) +static char * +line_completion_function (const char *text, int matches, char *line_buffer, int point) { static char **list = (char **) NULL; /* Cache of completions */ static int index; /* Next cached completion */ @@ -671,21 +667,30 @@ line_completion_function (char *text, int matches, char *line_buffer, int point) /* Make sure the word break characters are set back to normal for the next time that readline tries to complete something. */ rl_completer_word_break_characters = - gdb_completer_word_break_characters; + current_language->la_word_break_characters(); #endif return (output); } -/* Skip over a possibly quoted word (as defined by the quote characters - and word break characters the completer uses). Returns pointer to the - location after the "word". */ + +/* Skip over the possibly quoted word STR (as defined by the quote + characters QUOTECHARS and the the word break characters + BREAKCHARS). Returns pointer to the location after the "word". If + either QUOTECHARS or BREAKCHARS is NULL, use the same values used + by the completer. */ char * -skip_quoted (char *str) +skip_quoted_chars (char *str, char *quotechars, char *breakchars) { char quote_char = '\0'; char *scan; + if (quotechars == NULL) + quotechars = gdb_completer_quote_characters; + + if (breakchars == NULL) + breakchars = current_language->la_word_break_characters(); + for (scan = str; *scan != '\0'; scan++) { if (quote_char != '\0') @@ -698,16 +703,26 @@ skip_quoted (char *str) break; } } - else if (strchr (gdb_completer_quote_characters, *scan)) + else if (strchr (quotechars, *scan)) { /* Found start of a quoted string. */ quote_char = *scan; } - else if (strchr (gdb_completer_word_break_characters, *scan)) + else if (strchr (breakchars, *scan)) { break; } } + return (scan); } +/* Skip over the possibly quoted word STR (as defined by the quote + characters and word break characters used by the completer). + Returns pointer to the location after the "word". */ + +char * +skip_quoted (char *str) +{ + return skip_quoted_chars (str, NULL, NULL); +} diff --git a/contrib/gdb/gdb/completer.h b/contrib/gdb/gdb/completer.h index 98b9ed83745..0a8e9fa8cfe 100644 --- a/contrib/gdb/gdb/completer.h +++ b/contrib/gdb/gdb/completer.h @@ -19,11 +19,9 @@ #if !defined (COMPLETER_H) #define COMPLETER_H 1 -extern char **complete_line (char *text, char *line_buffer, int point); +extern char **complete_line (const char *text, char *line_buffer, int point); -extern char *line_completion_function (char *, int, char *, int); - -extern char *readline_line_completion_function (char *text, int matches); +extern char *readline_line_completion_function (const char *text, int matches); extern char **noop_completer (char *, char *); @@ -33,12 +31,12 @@ extern char **location_completer (char *, char *); extern char **command_completer (char *, char *); -extern char *get_gdb_completer_word_break_characters (void); - extern char *get_gdb_completer_quote_characters (void); /* Exported to linespec.c */ -extern char *skip_quoted (char *str); +extern char *skip_quoted_chars (char *, char *, char *); + +extern char *skip_quoted (char *); #endif /* defined (COMPLETER_H) */ diff --git a/contrib/gdb/gdb/config/alpha/alpha.mt b/contrib/gdb/gdb/config/alpha/alpha.mt new file mode 100644 index 00000000000..dfff657cbcc --- /dev/null +++ b/contrib/gdb/gdb/config/alpha/alpha.mt @@ -0,0 +1,2 @@ +TDEPFILES= alpha-tdep.o +TM_FILE= tm-alpha.h diff --git a/contrib/gdb/gdb/config/alpha/fbsd.mt b/contrib/gdb/gdb/config/alpha/fbsd.mt index 48e54fa818b..24d2fd80b84 100644 --- a/contrib/gdb/gdb/config/alpha/fbsd.mt +++ b/contrib/gdb/gdb/config/alpha/fbsd.mt @@ -1,3 +1,3 @@ # Target: FreeBSD/Alpha -TDEPFILES= alpha-tdep.o alphafbsd-tdep.o +TDEPFILES= alpha-tdep.o alpha-mdebug-tdep.o alphabsd-tdep.o alphafbsd-tdep.o TM_FILE= tm-fbsd.h diff --git a/contrib/gdb/gdb/config/alpha/nbsd.mh b/contrib/gdb/gdb/config/alpha/nbsd.mh new file mode 100644 index 00000000000..52754a3065d --- /dev/null +++ b/contrib/gdb/gdb/config/alpha/nbsd.mh @@ -0,0 +1,4 @@ +# Host: Alpha running NetBSD +NAT_CLIBS= +NATDEPFILES= infptrace.o inftarg.o fork-child.o alphabsd-nat.o +NAT_FILE= nm-nbsd.h diff --git a/contrib/gdb/gdb/config/alpha/nbsd.mt b/contrib/gdb/gdb/config/alpha/nbsd.mt new file mode 100644 index 00000000000..065a28c9a01 --- /dev/null +++ b/contrib/gdb/gdb/config/alpha/nbsd.mt @@ -0,0 +1,4 @@ +# Target: Alpha running NetBSD +TDEPFILES= alpha-tdep.o alpha-mdebug-tdep.o alphabsd-tdep.o alphanbsd-tdep.o \ + corelow.o nbsd-tdep.o solib.o solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/alpha/nm-fbsd.h b/contrib/gdb/gdb/config/alpha/nm-fbsd.h index f3fb129997c..2b3975a76f8 100644 --- a/contrib/gdb/gdb/config/alpha/nm-fbsd.h +++ b/contrib/gdb/gdb/config/alpha/nm-fbsd.h @@ -32,13 +32,11 @@ #define ATTACH_DETACH /* The Alpha does not step over a breakpoint. */ -#define CANNOT_STEP_BREAKPOINT +#define CANNOT_STEP_BREAKPOINT 1 /* Shared library support. */ -#define SVR4_SHARED_LIBS - #include "solib.h" /* Support for shared libraries. */ #include "elf/common.h" /* Additional ELF shared library info. */ diff --git a/contrib/gdb/gdb/config/alpha/nm-nbsd.h b/contrib/gdb/gdb/config/alpha/nm-nbsd.h new file mode 100644 index 00000000000..10fab6ec3b0 --- /dev/null +++ b/contrib/gdb/gdb/config/alpha/nm-nbsd.h @@ -0,0 +1,31 @@ +/* Native-dependent definitions for Alpha running NetBSD, for GDB. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_NBSD_H +#define NM_NBSD_H + +/* Get generic NetBSD native definitions. */ +#include "config/nm-nbsd.h" + +/* The Alpha does not step over a breakpoint. */ +#define CANNOT_STEP_BREAKPOINT 1 + +#endif /* NM_NBSD_H */ diff --git a/contrib/gdb/gdb/config/alpha/nm-osf.h b/contrib/gdb/gdb/config/alpha/nm-osf.h index 5fc99e4ad57..326bb3005ca 100644 --- a/contrib/gdb/gdb/config/alpha/nm-osf.h +++ b/contrib/gdb/gdb/config/alpha/nm-osf.h @@ -1,5 +1,7 @@ /* Native definitions for alpha running OSF/1. - Copyright 1993, 1994, 1995, 1998, 2000 Free Software Foundation, Inc. + + Copyright 1993, 1994, 1995, 1998, 2000, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -18,14 +20,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Figure out where the longjmp will land. We expect that we have just entered - longjmp and haven't yet setup the stack frame, so the args are still in the - argument regs. A0_REGNUM points at the jmp_buf structure from which we - extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. - This routine returns true on success */ - -#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR) -extern int get_longjmp_target (CORE_ADDR *); +/* Number of traps that happen between exec'ing the shell + to run an inferior, and when we finally get to + the inferior code. This is 2 on most implementations. */ +#define START_INFERIOR_TRAPS_EXPECTED 3 /* ptrace register ``addresses'' are absolute. */ @@ -41,11 +39,7 @@ extern int get_longjmp_target (CORE_ADDR *); /* The alpha does not step over a breakpoint, the manpage is lying again. */ -#define CANNOT_STEP_BREAKPOINT - -/* OSF/1 has shared libraries. */ - -#define GDB_TARGET_HAS_SHARED_LIBS +#define CANNOT_STEP_BREAKPOINT 1 /* Support for shared libraries. */ diff --git a/contrib/gdb/gdb/config/alpha/nm-osf2.h b/contrib/gdb/gdb/config/alpha/nm-osf2.h index 4b225af237f..1f3932df59b 100644 --- a/contrib/gdb/gdb/config/alpha/nm-osf2.h +++ b/contrib/gdb/gdb/config/alpha/nm-osf2.h @@ -25,9 +25,6 @@ #define USE_PROC_FS #define HAVE_OPTIONAL_PROC_FS -/* OSF/1 doesn't provide the standard fault definitions, so don't use them. */ -#define FAULTED_USE_SIGINFO - /* Don't trace faults under OSF/1, rely on the posting of the appropriate signal if fault tracing is disabled. Tracing T_IFAULT under Alpha OSF/1 causes a `floating point enable' diff --git a/contrib/gdb/gdb/config/alpha/tm-alpha.h b/contrib/gdb/gdb/config/alpha/tm-alpha.h index 58412d095ae..0b7878c58a0 100644 --- a/contrib/gdb/gdb/config/alpha/tm-alpha.h +++ b/contrib/gdb/gdb/config/alpha/tm-alpha.h @@ -1,7 +1,7 @@ /* Definitions to make GDB run on an Alpha box under OSF1. This is also used by the Alpha/Netware and Alpha GNU/Linux targets. - Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002 Free + Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -24,353 +24,21 @@ #ifndef TM_ALPHA_H #define TM_ALPHA_H -#include "regcache.h" #include "bfd.h" #include "coff/sym.h" /* Needed for PDR below. */ #include "coff/symconst.h" struct frame_info; -struct type; -struct value; struct symbol; -/* Redefine some target bit sizes from the default. */ - -#define TARGET_LONG_BIT 64 -#define TARGET_LONG_LONG_BIT 64 -#define TARGET_PTR_BIT 64 - -/* Number of traps that happen between exec'ing the shell - * to run an inferior, and when we finally get to - * the inferior code. This is 2 on most implementations. - */ -#define START_INFERIOR_TRAPS_EXPECTED 3 - -/* Offset from address of function to start of its code. - Zero on most machines. */ - -#define FUNCTION_START_OFFSET 0 - -/* Advance PC across any function entry prologue instructions - to reach some "real" code. */ - -#define SKIP_PROLOGUE(pc) alpha_skip_prologue((pc)) -extern CORE_ADDR alpha_skip_prologue (CORE_ADDR addr); - -/* Immediately after a function call, return the saved pc. - Can't always go through the frames for this because on some machines - the new frame is not set up until the new function executes - some instructions. */ - -#define SAVED_PC_AFTER_CALL(frame) alpha_saved_pc_after_call(frame) -extern CORE_ADDR alpha_saved_pc_after_call (struct frame_info *); - -/* Are we currently handling a signal ? */ - -#define IN_SIGTRAMP(pc, name) alpha_osf_in_sigtramp ((pc), (name)) -extern int alpha_osf_in_sigtramp (CORE_ADDR, char *); - -/* Stack grows downward. */ - -#define INNER_THAN(lhs,rhs) core_addr_lessthan ((lhs), (rhs)) - -#define BREAKPOINT {0x80, 0, 0, 0} /* call_pal bpt */ - -/* Amount PC must be decremented by after a breakpoint. - This is often the number of bytes in BREAKPOINT - but not always. */ - -#ifndef DECR_PC_AFTER_BREAK -#define DECR_PC_AFTER_BREAK 4 -#endif - -/* Say how long (ordinary) registers are. This is a piece of bogosity - used in push_word and a few other places; REGISTER_RAW_SIZE is the - real way to know how big a register is. */ - -#define REGISTER_SIZE 8 - -/* Number of machine registers */ - -#define NUM_REGS 66 - - -/* Return the name of register REGNO. */ - -#define REGISTER_NAME(regno) alpha_register_name ((regno)) -extern char *alpha_register_name (int); - - -/* Register numbers of various important registers. - Note that most of these values are "real" register numbers, - and correspond to the general registers of the machine, - and FP_REGNUM is a "phony" register number which is too large - to be an actual register number as far as the user is concerned - but serves to get the desired value when passed to read_register. */ - -#define V0_REGNUM 0 /* Function integer return value */ -#define T7_REGNUM 8 /* Return address register for OSF/1 __add* */ -#define GCC_FP_REGNUM 15 /* Used by gcc as frame register */ -#define A0_REGNUM 16 /* Loc of first arg during a subr call */ -#define T9_REGNUM 23 /* Return address register for OSF/1 __div* */ -#define T12_REGNUM 27 /* Contains start addr of current proc */ -#define SP_REGNUM 30 /* Contains address of top of stack */ -#define RA_REGNUM 26 /* Contains return address value */ -#define ZERO_REGNUM 31 /* Read-only register, always 0 */ -#define FP0_REGNUM 32 /* Floating point register 0 */ -#define FPA0_REGNUM 48 /* First float arg during a subr call */ -#define FPCR_REGNUM 63 /* Floating point control register */ -#define PC_REGNUM 64 /* Contains program counter */ -#define FP_REGNUM 65 /* Virtual frame pointer */ - -#define CANNOT_FETCH_REGISTER(regno) \ - alpha_cannot_fetch_register ((regno)) -extern int alpha_cannot_fetch_register (int); - -#define CANNOT_STORE_REGISTER(regno) \ - alpha_cannot_store_register ((regno)) -extern int alpha_cannot_store_register (int); - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ -#define REGISTER_BYTES (NUM_REGS * 8) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) alpha_register_byte ((N)) -extern int alpha_register_byte (int); - -/* Number of bytes of storage in the actual machine representation - for register N. On Alphas, all regs are 8 bytes. */ - -#define REGISTER_RAW_SIZE(N) alpha_register_raw_size ((N)) -extern int alpha_register_raw_size (int); - -/* Number of bytes of storage in the program's representation - for register N. On Alphas, all regs are 8 bytes. */ - -#define REGISTER_VIRTUAL_SIZE(N) alpha_register_virtual_size ((N)) -extern int alpha_register_virtual_size (int); - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 8 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 8 - -/* Nonzero if register N requires conversion - from raw format to virtual format. - The alpha needs a conversion between register and memory format if - the register is a floating point register and - memory format is float, as the register format must be double - or - memory format is an integer with 4 bytes or less, as the representation - of integers in floating point registers is different. */ - -#define REGISTER_CONVERTIBLE(N) alpha_register_convertible ((N)) -extern int alpha_register_convertible (int); - -/* Convert data from raw format for register REGNUM in buffer FROM - to virtual format with type TYPE in buffer TO. */ - -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM, TYPE, FROM, TO) \ - alpha_register_convert_to_virtual (REGNUM, TYPE, FROM, TO) -extern void -alpha_register_convert_to_virtual (int, struct type *, char *, char *); - -/* Convert data from virtual format with type TYPE in buffer FROM - to raw format for register REGNUM in buffer TO. */ - -#define REGISTER_CONVERT_TO_RAW(TYPE, REGNUM, FROM, TO) \ - alpha_register_convert_to_raw (TYPE, REGNUM, FROM, TO) -extern void -alpha_register_convert_to_raw (struct type *, int, char *, char *); - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#define REGISTER_VIRTUAL_TYPE(N) alpha_register_virtual_type ((N)) -extern struct type * alpha_register_virtual_type (int); - -/* Store the address of the place in which to copy the structure the - subroutine will return. Handled by alpha_push_arguments. */ - -#define STORE_STRUCT_RETURN(addr, sp) \ - alpha_store_struct_return ((addr), (sp)) -extern void alpha_store_struct_return (CORE_ADDR, CORE_ADDR); -/**/ - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - alpha_extract_return_value(TYPE, REGBUF, VALBUF) -extern void alpha_extract_return_value (struct type *, char *, char *); - -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. */ - -#define STORE_RETURN_VALUE(TYPE,VALBUF) \ - alpha_store_return_value(TYPE, VALBUF) -extern void alpha_store_return_value (struct type *, char *); - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR (or an expression that can be used as one). */ -/* The address is passed in a0 upon entry to the function, but when - the function exits, the compiler has copied the value to v0. This - convention is specified by the System V ABI, so I think we can rely - on it. */ - -#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \ - alpha_extract_struct_value_address (REGBUF) -extern CORE_ADDR alpha_extract_struct_value_address (char *); - -/* Structures are returned by ref in extra arg0 */ -#define USE_STRUCT_CONVENTION(gcc_p, type) \ - alpha_use_struct_convention ((gcc_p), (type)) -extern int alpha_use_struct_convention (int, struct type *); - - -/* Describe the pointer in each stack frame to the previous stack frame - (its caller). */ - -/* FRAME_CHAIN takes a frame's nominal address - and produces the frame's chain-pointer. */ - -#define FRAME_CHAIN(thisframe) alpha_frame_chain (thisframe) -extern CORE_ADDR alpha_frame_chain (struct frame_info *); - -/* Define other aspects of the stack frame. */ - - -/* An expression that tells us whether the function invocation represented - by FI does not have a frame on the stack associated with it. */ -/* We handle this differently for alpha, and maybe we should not */ - -#define FRAMELESS_FUNCTION_INVOCATION(FI) \ - generic_frameless_function_invocation_not ((FI)) - -/* Saved Pc. */ - -#define FRAME_SAVED_PC(FRAME) alpha_frame_saved_pc(FRAME) -extern CORE_ADDR alpha_frame_saved_pc (struct frame_info *); - -/* The alpha has two different virtual pointers for arguments and locals. - - The virtual argument pointer is pointing to the bottom of the argument - transfer area, which is located immediately below the virtual frame - pointer. Its size is fixed for the native compiler, it is either zero - (for the no arguments case) or large enough to hold all argument registers. - gcc uses a variable sized argument transfer area. As it has - to stay compatible with the native debugging tools it has to use the same - virtual argument pointer and adjust the argument offsets accordingly. - - The virtual local pointer is localoff bytes below the virtual frame - pointer, the value of localoff is obtained from the PDR. */ - -#define ALPHA_NUM_ARG_REGS 6 - -#define FRAME_ARGS_ADDRESS(fi) alpha_frame_args_address ((fi)) -extern CORE_ADDR alpha_frame_args_address (struct frame_info *); - -#define FRAME_LOCALS_ADDRESS(fi) alpha_frame_locals_address ((fi)) -extern CORE_ADDR alpha_frame_locals_address (struct frame_info *); - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -#define FRAME_NUM_ARGS(fi) frame_num_args_unknown ((fi)) - -/* Return number of bytes at start of arglist that are not really args. */ - -#define FRAME_ARGS_SKIP 0 - -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ - -#define FRAME_INIT_SAVED_REGS(frame_info) \ - alpha_frame_init_saved_regs (frame_info) -extern void alpha_frame_init_saved_regs (struct frame_info *); - - -/* Things needed for making the inferior call functions. */ - -#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \ - (alpha_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))) -extern CORE_ADDR -alpha_push_arguments (int, struct value **, CORE_ADDR, int, CORE_ADDR); - -/* Push an empty stack frame, to record the current PC, etc. */ - -#define PUSH_DUMMY_FRAME alpha_push_dummy_frame() -extern void alpha_push_dummy_frame (void); - -/* Discard from the stack the innermost frame, restoring all registers. */ - -#define POP_FRAME alpha_pop_frame() -extern void alpha_pop_frame (void); - -/* Alpha OSF/1 inhibits execution of code on the stack. - But there is no need for a dummy on the alpha. PUSH_ARGUMENTS - takes care of all argument handling and bp_call_dummy takes care - of stopping the dummy. */ - -#define CALL_DUMMY_LOCATION AT_ENTRY_POINT - -/* On the Alpha the call dummy code is never copied to user space, - stopping the user call is achieved via a bp_call_dummy breakpoint. - But we need a fake CALL_DUMMY definition to enable the proper - call_function_by_hand and to avoid zero length array warnings - in valops.c */ - -#define CALL_DUMMY_P (1) - -#define CALL_DUMMY_WORDS alpha_call_dummy_words -extern LONGEST alpha_call_dummy_words[]; - -#define SIZEOF_CALL_DUMMY_WORDS 0 - -#define CALL_DUMMY_START_OFFSET (0) - -#define CALL_DUMMY_BREAKPOINT_OFFSET (0) - -#define CALL_DUMMY_ADDRESS() alpha_call_dummy_address() -extern CORE_ADDR alpha_call_dummy_address (void); - -/* Insert the specified number of args and function address - into a call sequence of the above form stored at DUMMYNAME. - We only have to set RA_REGNUM to the dummy breakpoint address - and T12_REGNUM (the `procedure value register') to the function address. */ - -#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \ - alpha_fix_call_dummy ((dummyname), (pc), (fun), (nargs), (args), \ - (type), (gcc_p)) -extern void alpha_fix_call_dummy (char *, CORE_ADDR, CORE_ADDR, int, - struct value **, struct type *, int); - -/* There's a mess in stack frame creation. See comments in blockframe.c - near reference to INIT_FRAME_PC_FIRST. */ - -#define INIT_FRAME_PC(fromleaf, prev) init_frame_pc_noop ((fromleaf), (prev)) - -#define INIT_FRAME_PC_FIRST(fromleaf, prev) \ - alpha_init_frame_pc_first ((fromleaf), (prev)) -extern void alpha_init_frame_pc_first (int, struct frame_info *); - /* Special symbol found in blocks associated with routines. We can hang alpha_extra_func_info_t's off of this. */ #define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__" extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR); +#define RA_REGNUM 26 /* XXXJRT needed by mdebugread.c */ + /* Specific information about a procedure. This overlays the ALPHA's PDR records, alpharead.c (ab)uses this to save memory */ @@ -389,15 +57,6 @@ typedef struct alpha_extra_func_info #define mips_extra_func_info alpha_extra_func_info #define mips_extra_func_info_t alpha_extra_func_info_t - -#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) \ - alpha_init_extra_frame_info(fromleaf, fci) -extern void alpha_init_extra_frame_info (int, struct frame_info *); - -#define PRINT_EXTRA_FRAME_INFO(fi) alpha_print_extra_frame_info ((fi)) -extern void alpha_print_extra_frame_info (struct frame_info *); - - /* It takes two values to specify a frame on the ALPHA. Sigh. In fact, at the moment, the *PC* is the primary value that sets up @@ -408,64 +67,8 @@ extern void alpha_print_extra_frame_info (struct frame_info *); up so that the primary value is the SP, and the PC is used to disambiguate multiple functions with the same SP that are at different stack levels. */ -#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv) -extern struct frame_info *setup_arbitrary_frame (int, CORE_ADDR *); - -/* This is used by heuristic_proc_start. It should be shot it the head. */ -#ifndef VM_MIN_ADDRESS -#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000 -#endif - -/* If PC is in a shared library trampoline code, return the PC - where the function itself actually starts. If not, return 0. */ -#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc) - -/* If the current gcc for for this target does not produce correct debugging - information for float parameters, both prototyped and unprototyped, then - define this macro. This forces gdb to always assume that floats are - passed as doubles and then converted in the callee. - - For the alpha, it appears that the debug info marks the parameters as - floats regardless of whether the function is prototyped, but the actual - values are always passed in as doubles. Thus by setting this to 1, both - types of calls will work. */ - -#define COERCE_FLOAT_TO_DOUBLE(formal, actual) \ - standard_coerce_float_to_double ((formal), (actual)) - -/* Return TRUE if procedure descriptor PROC is a procedure descriptor - that refers to a dynamically generated sigtramp function. - - OSF/1 doesn't use dynamic sigtramp functions, so this is always - FALSE. */ - -#define PROC_DESC_IS_DYN_SIGTRAMP(proc) (0) -#define SET_PROC_DESC_IS_DYN_SIGTRAMP(proc) - -/* If PC is inside a dynamically generated sigtramp function, return - how many bytes the program counter is beyond the start of that - function. Otherwise, return a negative value. - - OSF/1 doesn't use dynamic sigtramp functions, so this always - returns -1. */ - -#define DYNAMIC_SIGTRAMP_OFFSET(pc) (-1) - -/* Translate a signal handler frame into the address of the sigcontext - structure. */ - -#define SIGCONTEXT_ADDR(frame) \ - (read_memory_integer ((frame)->next ? frame->next->frame : frame->frame, 8)) - -/* If FRAME refers to a sigtramp frame, return the address of the next - frame. */ - -#define FRAME_PAST_SIGTRAMP_FRAME(frame, pc) \ - (alpha_osf_skip_sigtramp_frame (frame, pc)) -extern CORE_ADDR alpha_osf_skip_sigtramp_frame (struct frame_info *, - CORE_ADDR); - -/* Single step based on where the current instruction will take us. */ -extern void alpha_software_single_step (enum target_signal, int); +#define SETUP_ARBITRARY_FRAME(argc, argv) \ + alpha_setup_arbitrary_frame (argc, argv) +extern struct frame_info *alpha_setup_arbitrary_frame (int, CORE_ADDR *); #endif /* TM_ALPHA_H */ diff --git a/contrib/gdb/gdb/config/alpha/tm-fbsd.h b/contrib/gdb/gdb/config/alpha/tm-fbsd.h index 00d3c27dc0b..c154366cc19 100644 --- a/contrib/gdb/gdb/config/alpha/tm-fbsd.h +++ b/contrib/gdb/gdb/config/alpha/tm-fbsd.h @@ -1,5 +1,6 @@ /* Target-dependent definitions for FreeBSD/Alpha. - Copyright 2000, 2001 Free Software Foundation, Inc. + + Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -23,23 +24,4 @@ #include "alpha/tm-alpha.h" -/* FreeBSD uses the old gcc convention for struct returns. */ - -#undef USE_STRUCT_CONVENTION -#define USE_STRUCT_CONVENTION(gcc_p, type) \ - alphafbsd_use_struct_convention (gcc_p, type) - -/* FreeBSD doesn't mark the outermost frame. While some FreeBSD/Alpha - releases include (a minimal amount of) debugging info in its - startup code (crt1.o), the safest thing is to consider the user - code entry point as the outermost frame. */ -#define FRAME_CHAIN_VALID(chain, thisframe) \ - func_frame_chain_valid(chain, thisframe) - -/* Number of traps that happen between exec'ing the shell to run an - inferior, and when we finally get to the inferior code. The - default is right for FreeBSD. */ - -#undef START_INFERIOR_TRAPS_EXPECTED - #endif /* TM_FBSD_H */ diff --git a/contrib/gdb/gdb/config/alpha/tm-nbsd.h b/contrib/gdb/gdb/config/alpha/tm-nbsd.h new file mode 100644 index 00000000000..aaad48ce508 --- /dev/null +++ b/contrib/gdb/gdb/config/alpha/tm-nbsd.h @@ -0,0 +1,28 @@ +/* Target-dependent definitions for NetBSD/Alpha. + + Copyright 2002, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_NBSD_H +#define TM_NBSD_H + +#include "alpha/tm-alpha.h" +#include "solib.h" + +#endif /* TM_NBSD_H */ diff --git a/contrib/gdb/gdb/config/arm/nbsd.mt b/contrib/gdb/gdb/config/arm/nbsd.mt index dad2717bfc8..1e7d4fa3e61 100644 --- a/contrib/gdb/gdb/config/arm/nbsd.mt +++ b/contrib/gdb/gdb/config/arm/nbsd.mt @@ -1,2 +1,3 @@ # Target: ARM running NetBSD -TDEPFILES= arm-tdep.o armnbsd-tdep.o solib.o solib-svr4.o solib-sunos.o +TDEPFILES= arm-tdep.o armnbsd-tdep.o solib.o solib-svr4.o nbsd-tdep.o +TM_FILE=tm-nbsd.h diff --git a/contrib/gdb/gdb/config/arm/nbsdaout.mh b/contrib/gdb/gdb/config/arm/nbsdaout.mh new file mode 100644 index 00000000000..100e40b42bb --- /dev/null +++ b/contrib/gdb/gdb/config/arm/nbsdaout.mh @@ -0,0 +1,5 @@ +# Host ARM running NetBSD +NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o armnbsd-nat.o \ + solib-sunos.o +XM_FILE=xm-nbsd.h +NAT_FILE=nm-nbsdaout.h diff --git a/contrib/gdb/gdb/config/arm/nbsdelf.mh b/contrib/gdb/gdb/config/arm/nbsdelf.mh new file mode 100644 index 00000000000..481d5cc92a5 --- /dev/null +++ b/contrib/gdb/gdb/config/arm/nbsdelf.mh @@ -0,0 +1,4 @@ +# Host ARM running NetBSD +NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o armnbsd-nat.o +XM_FILE=xm-nbsd.h +NAT_FILE=nm-nbsd.h diff --git a/contrib/gdb/gdb/config/arm/nm-nbsd.h b/contrib/gdb/gdb/config/arm/nm-nbsd.h index 431a695ae41..63be920092f 100644 --- a/contrib/gdb/gdb/config/arm/nm-nbsd.h +++ b/contrib/gdb/gdb/config/arm/nm-nbsd.h @@ -22,12 +22,6 @@ #define NM_NBSD_H /* Get generic NetBSD native definitions. */ -#include "nm-nbsd.h" - -#define REGISTER_U_ADDR(addr, blockend, regno) \ - (addr) = arm_register_u_addr ((blockend),(regno)); - -extern int -arm_register_u_addr (int, int); +#include "config/nm-nbsd.h" #endif /* NM_NBSD_H */ diff --git a/contrib/gdb/gdb/config/arm/nm-nbsdaout.h b/contrib/gdb/gdb/config/arm/nm-nbsdaout.h new file mode 100644 index 00000000000..3f7fee9de1a --- /dev/null +++ b/contrib/gdb/gdb/config/arm/nm-nbsdaout.h @@ -0,0 +1,29 @@ +/* Native-dependent definitions for ARM running NetBSD, for GDB. + Copyright 1986, 1987, 1989, 1992, 1994, 1999 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_NBSDAOUT_H +#define NM_NBSDAOUT_H + +#include "arm/nm-nbsd.h" + +/* Get generic NetBSD a.out native definitions. */ +#include "config/nm-nbsdaout.h" + +#endif /* NM_NBSDAOUT_H */ diff --git a/contrib/gdb/gdb/config/arm/tm-arm.h b/contrib/gdb/gdb/config/arm/tm-arm.h index 369917524d4..c62a75d6c39 100644 --- a/contrib/gdb/gdb/config/arm/tm-arm.h +++ b/contrib/gdb/gdb/config/arm/tm-arm.h @@ -22,9 +22,7 @@ #ifndef TM_ARM_H #define TM_ARM_H -#ifndef GDB_MULTI_ARCH #define GDB_MULTI_ARCH 1 -#endif /* Specify that for the native compiler variables for a particular lexical context are listed after the beginning LBRAC instead of diff --git a/contrib/gdb/gdb/config/arm/tm-nbsd.h b/contrib/gdb/gdb/config/arm/tm-nbsd.h new file mode 100644 index 00000000000..97bca68bc18 --- /dev/null +++ b/contrib/gdb/gdb/config/arm/tm-nbsd.h @@ -0,0 +1,26 @@ +/* Macro definitions for ARM running under NetBSD. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_NBSD_H +#define TM_NBSD_H + +#include "solib.h" + +#endif /* TM_NBSD_H */ diff --git a/contrib/gdb/gdb/config/arm/wince.mt b/contrib/gdb/gdb/config/arm/wince.mt index 10fe0eb3f38..92a77ae0ad0 100644 --- a/contrib/gdb/gdb/config/arm/wince.mt +++ b/contrib/gdb/gdb/config/arm/wince.mt @@ -2,4 +2,4 @@ TDEPFILES= arm-tdep.o wince.o TM_FILE= tm-wince.h MT_CFLAGS=-DARM -U_X86_ -U_M_IX86 -U__i386__ -U__i486__ -U__i586__ -U__i686__ -DUNICODE -D_WIN32_WCE -DWINCE_STUB='"${target_alias}-stub.exe"' -WIN32LIBS=-lrapi +TM_CLIBS=-lrapi diff --git a/contrib/gdb/gdb/config/arm/xm-nbsd.h b/contrib/gdb/gdb/config/arm/xm-nbsd.h index c5348d39629..d3f76a7dd01 100644 --- a/contrib/gdb/gdb/config/arm/xm-nbsd.h +++ b/contrib/gdb/gdb/config/arm/xm-nbsd.h @@ -19,4 +19,4 @@ Boston, MA 02111-1307, USA. */ /* Get generic NetBSD host definitions. */ -#include "xm-nbsd.h" +#include "config/xm-nbsd.h" diff --git a/contrib/gdb/gdb/config/i386/fbsd.mh b/contrib/gdb/gdb/config/i386/fbsd.mh index 364dfa61ec2..2d0500e565d 100644 --- a/contrib/gdb/gdb/config/i386/fbsd.mh +++ b/contrib/gdb/gdb/config/i386/fbsd.mh @@ -1,7 +1,5 @@ -# Host: Intel 386 running FreeBSD - -XM_FILE= xm-i386.h - +# Host: FreeBSD/i386 +NATDEPFILES= fork-child.o infptrace.o inftarg.o \ + i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o NAT_FILE= nm-fbsd.h -# NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. -NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i387-nat.o i386bsd-nat.o i386fbsd-nat.o +XM_FILE= xm-i386.h diff --git a/contrib/gdb/gdb/config/i386/fbsd.mt b/contrib/gdb/gdb/config/i386/fbsd.mt index 7a95e00d6b9..be095e987a8 100644 --- a/contrib/gdb/gdb/config/i386/fbsd.mt +++ b/contrib/gdb/gdb/config/i386/fbsd.mt @@ -1,3 +1,4 @@ -# Target: Intel 386 running FreeBSD -TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o +# Target: FreeBSD/i386 +TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \ + corelow.o solib.o solib-svr4.o TM_FILE= tm-fbsd.h diff --git a/contrib/gdb/gdb/config/i386/fbsd64.mh b/contrib/gdb/gdb/config/i386/fbsd64.mh new file mode 100644 index 00000000000..6c30e3072df --- /dev/null +++ b/contrib/gdb/gdb/config/i386/fbsd64.mh @@ -0,0 +1,5 @@ +# Host: FreeBSD/amd64 +NATDEPFILES= fork-child.o infptrace.o inftarg.o \ + amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o gcore.o fbsd-proc.o +NAT_FILE= nm-fbsd64.h +XM_FILE= xm-i386.h diff --git a/contrib/gdb/gdb/config/i386/fbsd64.mt b/contrib/gdb/gdb/config/i386/fbsd64.mt new file mode 100644 index 00000000000..d4cb24b76b8 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/fbsd64.mt @@ -0,0 +1,5 @@ +# Target: FreeBSD/amd64 +TDEPFILES= amd64-tdep.o amd64fbsd-tdep.o \ + i386-tdep.o i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \ + corelow.o solib.o solib-svr4.o +TM_FILE= tm-fbsd.h diff --git a/contrib/gdb/gdb/config/i386/go32.mh b/contrib/gdb/gdb/config/i386/go32.mh index 3d3bdfd7511..0de5a9fdef9 100644 --- a/contrib/gdb/gdb/config/i386/go32.mh +++ b/contrib/gdb/gdb/config/i386/go32.mh @@ -1,15 +1,11 @@ # Host: Intel x86 running DJGPP -# we don't need mmalloc on DJGPP -MH_CFLAGS= -DNO_MMALLOC -MMALLOC= -MMALLOC_CFLAGS= +MH_CFLAGS= XM_FILE= xm-go32.h NAT_FILE= nm-go32.h -NATDEPFILES= go32-nat.o i386-nat.o i387-nat.o +NATDEPFILES= go32-nat.o i386-nat.o -TERMCAP= HOST_IPC= CC= gcc XM_CLIBS= -ldbg diff --git a/contrib/gdb/gdb/config/i386/i386aout.mt b/contrib/gdb/gdb/config/i386/i386aout.mt index 1c94ba5216c..2a33369b462 100644 --- a/contrib/gdb/gdb/config/i386/i386aout.mt +++ b/contrib/gdb/gdb/config/i386/i386aout.mt @@ -1,3 +1,3 @@ # Target: Intel 386 with a.out -TDEPFILES= i386-tdep.o -TM_FILE= tm-i386v.h +TDEPFILES= i386-tdep.o i387-tdep.o +TM_FILE= tm-i386.h diff --git a/contrib/gdb/gdb/config/i386/i386gnu.mh b/contrib/gdb/gdb/config/i386/i386gnu.mh index 252b2e5945b..c2eb7af96ea 100644 --- a/contrib/gdb/gdb/config/i386/i386gnu.mh +++ b/contrib/gdb/gdb/config/i386/i386gnu.mh @@ -1,7 +1,11 @@ # Host: Intel 386 running the GNU Hurd -NATDEPFILES= i386gnu-nat.o i387-nat.o gnu-nat.o fork-child.o solib.o solib-svr4.o solib-legacy.o corelow.o notify_S.o process_reply_S.o msg_reply_S.o msg_U.o exc_request_U.o exc_request_S.o -XM_FILE= xm-i386gnu.h -NAT_FILE= nm-gnu.h +NATDEPFILES= i386gnu-nat.o gnu-nat.o corelow.o core-regset.o \ + fork-child.o solib.o solib-svr4.o solib-legacy.o \ + notify_S.o process_reply_S.o msg_reply_S.o \ + msg_U.o exc_request_U.o exc_request_S.o + +XM_FILE= xm-i386.h +NAT_FILE= nm-i386gnu.h MH_CFLAGS = -D_GNU_SOURCE XM_CLIBS = -lshouldbeinlibc diff --git a/contrib/gdb/gdb/config/i386/i386gnu.mt b/contrib/gdb/gdb/config/i386/i386gnu.mt index e08e2a25f91..2029e99bbfc 100644 --- a/contrib/gdb/gdb/config/i386/i386gnu.mt +++ b/contrib/gdb/gdb/config/i386/i386gnu.mt @@ -1,3 +1,3 @@ -# Target: Intel 386/elf/GNU Hurd -TDEPFILES= i386-tdep.o i387-tdep.o -TM_FILE= tm-i386gnu.h +# Target: Intel 386 running the GNU Hurd +TDEPFILES= i386-tdep.o i387-tdep.o i386gnu-tdep.o +TM_FILE= tm-i386.h diff --git a/contrib/gdb/gdb/config/i386/i386lynx.mh b/contrib/gdb/gdb/config/i386/i386lynx.mh index 0552b4d2639..edfb1b0752b 100644 --- a/contrib/gdb/gdb/config/i386/i386lynx.mh +++ b/contrib/gdb/gdb/config/i386/i386lynx.mh @@ -4,6 +4,3 @@ XM_CLIBS= -lbsd NAT_FILE= nm-i386lynx.h NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o lynx-nat.o - -## OBSOLETE ## GDBSERVER_LIBS= -lbsd -## OBSOLETE ## GDBSERVER_DEPFILES= low-lynx.o diff --git a/contrib/gdb/gdb/config/i386/i386nw.mt b/contrib/gdb/gdb/config/i386/i386nw.mt index 3109c42149e..9eafe7dcfd7 100644 --- a/contrib/gdb/gdb/config/i386/i386nw.mt +++ b/contrib/gdb/gdb/config/i386/i386nw.mt @@ -1,3 +1,3 @@ # Target: Intel 386 running NetWare TDEPFILES= i386-tdep.o i387-tdep.o -TM_FILE= tm-i386nw.h +TM_FILE= tm-i386.h diff --git a/contrib/gdb/gdb/config/i386/i386sol2.mh b/contrib/gdb/gdb/config/i386/i386sol2.mh index ab7f474b178..1245ca7a4bd 100644 --- a/contrib/gdb/gdb/config/i386/i386sol2.mh +++ b/contrib/gdb/gdb/config/i386/i386sol2.mh @@ -1,8 +1,8 @@ # Host: Intel 386 running Solaris 2 (SVR4) -XM_FILE= xm-i386v4.h -XM_CLIBS= -lsocket -lnsl +XM_FILE= xm-i386.h NAT_FILE= nm-i386sol2.h -NATDEPFILES= core-regset.o fork-child.o i386v4-nat.o i387-nat.o corelow.o \ - procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o +NATDEPFILES= fork-child.o i386v4-nat.o \ + procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o \ + solib.o solib-svr4.o solib-legacy.o diff --git a/contrib/gdb/gdb/config/i386/i386sol2.mt b/contrib/gdb/gdb/config/i386/i386sol2.mt index 86d93a378b1..863f61500d7 100644 --- a/contrib/gdb/gdb/config/i386/i386sol2.mt +++ b/contrib/gdb/gdb/config/i386/i386sol2.mt @@ -1,3 +1,3 @@ -# Target: Intel 386 running SVR4 -TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-svr4.o solib-legacy.o +# Target: Intel 386 running Solaris 2 (SVR4) +TDEPFILES= i386-tdep.o i387-tdep.o i386-sol2-tdep.o corelow.o TM_FILE= tm-i386sol2.h diff --git a/contrib/gdb/gdb/config/i386/i386v.mt b/contrib/gdb/gdb/config/i386/i386v.mt index 7242d3e8f38..1ee53057979 100644 --- a/contrib/gdb/gdb/config/i386/i386v.mt +++ b/contrib/gdb/gdb/config/i386/i386v.mt @@ -1,3 +1,3 @@ # Target: Intel 386 running System V TDEPFILES= i386-tdep.o i387-tdep.o -TM_FILE= tm-i386v.h +TM_FILE= tm-i386.h diff --git a/contrib/gdb/gdb/config/i386/i386v42mp.mh b/contrib/gdb/gdb/config/i386/i386v42mp.mh index 007a8bf1e05..4aac5d97b84 100644 --- a/contrib/gdb/gdb/config/i386/i386v42mp.mh +++ b/contrib/gdb/gdb/config/i386/i386v42mp.mh @@ -14,5 +14,7 @@ NAT_FILE= nm-i386v42mp.h # continuation character (backslash) to extend a commented line. As a # consequence, make considers subsequent tab-indented lines to be # some sort of error. -NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o i387-nat.o solib.o solib-svr4.o solib-legacy.o procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o uw-thread.o +NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o \ + gcore.o solib.o solib-svr4.o solib-legacy.o procfs.o proc-api.o \ + proc-events.o proc-flags.o proc-why.o uw-thread.o diff --git a/contrib/gdb/gdb/config/i386/nbsd.mt b/contrib/gdb/gdb/config/i386/nbsd.mt index 8ab606e15c6..d6699b54ec2 100644 --- a/contrib/gdb/gdb/config/i386/nbsd.mt +++ b/contrib/gdb/gdb/config/i386/nbsd.mt @@ -1,5 +1,4 @@ -# Target: Intel 386 running NetBSD -TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386nbsd-tdep.o +# Target: NetBSD/i386 +TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386nbsd-tdep.o nbsd-tdep.o \ + corelow.o solib.o solib-svr4.o TM_FILE= tm-nbsd.h - -## OBSOLETE ## GDBSERVER_DEPFILES= low-nbsd.o diff --git a/contrib/gdb/gdb/config/i386/nbsd64.mh b/contrib/gdb/gdb/config/i386/nbsd64.mh new file mode 100644 index 00000000000..e10ae7a2be4 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nbsd64.mh @@ -0,0 +1,5 @@ +# Host: NetBSD/amd64 +NATDEPFILES= fork-child.o infptrace.o inftarg.o \ + amd64-nat.o amd64bsd-nat.o amd64nbsd-nat.o +NAT_FILE= nm-nbsd.h +XM_FILE= xm-i386.h diff --git a/contrib/gdb/gdb/config/i386/nbsd64.mt b/contrib/gdb/gdb/config/i386/nbsd64.mt new file mode 100644 index 00000000000..3c982116a4c --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nbsd64.mt @@ -0,0 +1,4 @@ +# Target: NetBSD/amd64 +TDEPFILES= amd64-tdep.o amd64nbsd-tdep.o i386-tdep.o i387-tdep.o nbsd-tdep.o \ + corelow.o solib.o solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/i386/nbsdaout.mh b/contrib/gdb/gdb/config/i386/nbsdaout.mh new file mode 100644 index 00000000000..98e69c4c97b --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nbsdaout.mh @@ -0,0 +1,5 @@ +# Host: NetBSD/i386 a.out +NATDEPFILES= fork-child.o infptrace.o inftarg.o i386bsd-nat.o \ + solib.o solib-sunos.o +NAT_FILE= nm-nbsdaout.h +XM_FILE= xm-nbsd.h diff --git a/contrib/gdb/gdb/config/i386/nbsdelf.mh b/contrib/gdb/gdb/config/i386/nbsdelf.mh index f25a4069ae6..0d313ddac82 100644 --- a/contrib/gdb/gdb/config/i386/nbsdelf.mh +++ b/contrib/gdb/gdb/config/i386/nbsdelf.mh @@ -1,4 +1,4 @@ -# Host: Intel 386 running NetBSD -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i387-nat.o i386bsd-nat.o i386nbsd-nat.o solib.o solib-svr4.o solib-legacy.o +# Host: NetBSD/i386 ELF +NATDEPFILES= fork-child.o infptrace.o inftarg.o i386bsd-nat.o +NAT_FILE= nm-nbsd.h XM_FILE= xm-nbsd.h -NAT_FILE= nm-nbsdelf.h diff --git a/contrib/gdb/gdb/config/i386/ncr3000.mt b/contrib/gdb/gdb/config/i386/ncr3000.mt index 11bc47426e6..4773daec1b6 100644 --- a/contrib/gdb/gdb/config/i386/ncr3000.mt +++ b/contrib/gdb/gdb/config/i386/ncr3000.mt @@ -1,3 +1,3 @@ # Target: Intel 386 running SVR4 TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-svr4.o solib-legacy.o -TM_FILE= tm-i386v4.h +TM_FILE= tm-i386.h diff --git a/contrib/gdb/gdb/config/i386/nm-fbsd.h b/contrib/gdb/gdb/config/i386/nm-fbsd.h index a06ce955d6c..314e3a0f2f1 100644 --- a/contrib/gdb/gdb/config/i386/nm-fbsd.h +++ b/contrib/gdb/gdb/config/i386/nm-fbsd.h @@ -1,5 +1,6 @@ /* Native-dependent definitions for FreeBSD/i386. - Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1997, 2000, 2001 + + Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1997, 2000, 2001, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -60,6 +61,9 @@ extern unsigned long i386bsd_dr_get_status (void); /* Override child_resume in `infptrace.c' to work around a kernel bug. */ #define CHILD_RESUME +/* Override child_pid_to_exec_file in 'inftarg.c'. */ +#define CHILD_PID_TO_EXEC_FILE + /* We can attach and detach. */ #define ATTACH_DETACH @@ -84,20 +88,10 @@ extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regno); /* Shared library support. */ -/* The FreeBSD uses the same condition to distinguish ELF - from a.out. ELF implies SVR4 shared libraries. */ -#if (defined (FREEBSD_ELF) || defined (__ELF__)) && !defined (FREEBSD_AOUT) -#define SVR4_SHARED_LIBS -#endif +#include "solib.h" -#include "solib.h" /* Support for shared libraries. */ -#ifdef SVR4_SHARED_LIBS -#include "elf/common.h" /* Additional ELF shared library info. */ -#endif - -#ifndef SVR4_SHARED_LIBS - -/* Make structure definitions match up with those expected in `solib.c'. */ +/* Make structure definitions match up with those expected in + `solib-sunos.c'. */ #define link_object sod #define lo_name sod_name @@ -151,6 +145,4 @@ extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regno); #define ld_un d_un #define ld_2 d_sdt -#endif /* !SVR4_SHARED_LIBS */ - -#endif /* NM_FBSD_H */ +#endif /* nm-fbsd.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-fbsd64.h b/contrib/gdb/gdb/config/i386/nm-fbsd64.h new file mode 100644 index 00000000000..4c27aff6d74 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nm-fbsd64.h @@ -0,0 +1,37 @@ +/* Native-dependent definitions for FreeBSD/amd64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_FBSD64_H +#define NM_FBSD64_H + +/* Type of the third argument to the `ptrace' system call. */ +#define PTRACE_ARG3_TYPE caddr_t + +/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */ +#define FETCH_INFERIOR_REGISTERS + +/* Override child_pid_to_exec_file in 'inftarg.c'. */ +#define CHILD_PID_TO_EXEC_FILE + +/* We can attach and detach. */ +#define ATTACH_DETACH + +#endif /* nm-fbsd64.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-go32.h b/contrib/gdb/gdb/config/i386/nm-go32.h index 70b1907b67e..5947b745c0e 100644 --- a/contrib/gdb/gdb/config/i386/nm-go32.h +++ b/contrib/gdb/gdb/config/i386/nm-go32.h @@ -1,5 +1,5 @@ /* Native definitions for Intel x86 running DJGPP. - Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. + Copyright 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define NO_PTRACE_H - #define I386_USE_GENERIC_WATCHPOINTS #include "i386/nm-i386.h" diff --git a/contrib/gdb/gdb/config/i386/nm-i386.h b/contrib/gdb/gdb/config/i386/nm-i386.h index eed05a476fa..88eacc8852b 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386.h +++ b/contrib/gdb/gdb/config/i386/nm-i386.h @@ -1,5 +1,5 @@ /* Native macro definitions for GDB on an Intel i[3456]86. - Copyright 2001 Free Software Foundation, Inc. + Copyright 2001, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -93,7 +93,7 @@ extern int i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow); one that caused the trap. Therefore we don't need to step over it. But we do need to reset the status register to avoid another trap. */ -#define HAVE_CONTINUABLE_WATCHPOINT +#define HAVE_CONTINUABLE_WATCHPOINT 1 #define STOPPED_BY_WATCHPOINT(W) (i386_stopped_data_address () != 0) @@ -113,8 +113,6 @@ extern int i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow); #define target_remove_hw_breakpoint(addr, shadow) \ i386_remove_hw_breakpoint (addr, shadow) -#define DECR_PC_AFTER_HW_BREAK 0 - /* child_post_startup_inferior used to reset all debug registers by calling i386_cleanup_dregs (). */ #define CHILD_POST_STARTUP_INFERIOR diff --git a/contrib/gdb/gdb/config/i386/nm-i386gnu.h b/contrib/gdb/gdb/config/i386/nm-i386gnu.h new file mode 100644 index 00000000000..4fef763ca16 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nm-i386gnu.h @@ -0,0 +1,38 @@ +/* Native-dependent definitions for Intel 386 running the GNU Hurd + Copyright 1994, 1995, 1996, 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_I386GNU_H +#define NM_I386GNU_H + +/* Include common definitions for GNU systems. */ +#include "config/nm-gnu.h" + +/* Thread flavors used in re-setting the T bit. */ +#define THREAD_STATE_FLAVOR i386_REGS_SEGS_STATE +#define THREAD_STATE_SIZE i386_THREAD_STATE_COUNT +#define THREAD_STATE_SET_TRACED(state) \ + ((struct i386_thread_state *) (state))->efl |= 0x100 +#define THREAD_STATE_CLEAR_TRACED(state) \ + ((((struct i386_thread_state *) (state))->efl &= ~0x100), 1) + +/* We can attach and detach. */ +#define ATTACH_DETACH 1 + +#endif /* nm-i386gnu.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-i386lynx.h b/contrib/gdb/gdb/config/i386/nm-i386lynx.h index 5d0d41de267..bc6a23410f2 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386lynx.h +++ b/contrib/gdb/gdb/config/i386/nm-i386lynx.h @@ -21,6 +21,6 @@ #ifndef NM_I386LYNX_H #define NM_I386LYNX_H -#include "nm-lynx.h" +#include "config/nm-lynx.h" #endif /* NM_I386LYNX_H */ diff --git a/contrib/gdb/gdb/config/i386/nm-i386sco.h b/contrib/gdb/gdb/config/i386/nm-i386sco.h index b46776151b3..ec7a3bd97d9 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386sco.h +++ b/contrib/gdb/gdb/config/i386/nm-i386sco.h @@ -20,23 +20,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if 0 -/* code to execute to print interesting information about the - floating point processor (if any) - No need to define if there is nothing to do. - On the 386, unfortunately this code is host-dependent (and lives - in the i386-xdep.c file), so we can't - do this unless we *know* we aren't cross-debugging. FIXME. - */ -#define FLOAT_INFO { i386_float_info (); } -#endif /*0 */ +#ifndef NM_I386SCO_H +#define NM_I386SCO_H -#define REGISTER_U_ADDR(addr, blockend, regno) \ - (addr) = i386_register_u_addr ((blockend),(regno)); - -extern int i386_register_u_addr (int, int); +#include "i386/nm-i386v.h" /* When calling functions on SCO, sometimes we get an error writing some of the segment registers. This would appear to be a kernel bug/non-feature. */ #define CANNOT_STORE_REGISTER(regno) ((regno) == 14 || (regno) == 15) + +#endif /* nm-i386sco.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-i386sco5.h b/contrib/gdb/gdb/config/i386/nm-i386sco5.h index db2880c01ba..65f317621e6 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386sco5.h +++ b/contrib/gdb/gdb/config/i386/nm-i386sco5.h @@ -1,5 +1,5 @@ -/* Native support for SCO OpenServer 5 - Copyright 1996, 1998 Free Software Foundation, Inc. +/* Native support for SCO OpenServer 5. + Copyright 1996, 1998, 2002 Free Software Foundation, Inc. Re-written by J. Kean Johnston . Originally written by Robert Lipe , based on work by Ian Lance Taylor and @@ -22,17 +22,57 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef NM_I386SCO5_H +#define NM_I386SCO5_H + /* Basically, its a lot like the older versions ... */ #include "i386/nm-i386sco.h" -/* ... but it can do a lot of SVR4 type stuff too. */ +/* ... but it can do a lot of SVR4 type stuff too. */ #define SVR4_SHARED_LIBS -#include "solib.h" /* Pick up shared library support */ +#include "solib.h" /* Pick up shared library support. */ -#define ATTACH_DETACH +/* SCO is unlike other SVR4 systems in that it has SVR4 style shared + libs, with a slight twist. We expect 3 traps (2 for the exec and + one for the dynamic loader). After the third trap we insert the + shared library breakpoints, then wait for the 4th trap. */ -/* SCO does not provide . infptrace.c does not +#undef START_INFERIOR_TRAPS_EXPECTED +#define START_INFERIOR_TRAPS_EXPECTED 3 + +/* SCO does not provide . However, infptrace.c does not have defaults for these values. */ #define PTRACE_ATTACH 10 #define PTRACE_DETACH 11 + +/* Return the size of the user struct. */ + +#define KERNEL_U_SIZE kernel_u_size () +extern int kernel_u_size (void); + +/* We can attach and detach. */ +#define ATTACH_DETACH + +/* Hardware-assisted breakpoints and watchpoints. */ + +/* We can also do hardware watchpoints. */ +#define TARGET_HAS_HARDWARE_WATCHPOINTS +#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1 + +/* After a watchpoint trap, the PC points to the instruction which + caused the trap. But we can continue over it without disabling the + trap. */ +#define HAVE_CONTINUABLE_WATCHPOINT 1 +#define HAVE_STEPPABLE_WATCHPOINT + +#define STOPPED_BY_WATCHPOINT(W) \ + i386_stopped_by_watchpoint (PIDGET (inferior_ptid)) + +#define target_insert_watchpoint(addr, len, type) \ + i386_insert_watchpoint (PIDGET (inferior_ptid), addr, len, type) + +#define target_remove_watchpoint(addr, len, type) \ + i386_remove_watchpoint (PIDGET (inferior_ptid), addr, len) + +#endif /* nm-i386sco5.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-i386sol2.h b/contrib/gdb/gdb/config/i386/nm-i386sol2.h index 0e6b3ef4c7f..18afa04af1e 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386sol2.h +++ b/contrib/gdb/gdb/config/i386/nm-i386sol2.h @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "nm-sysv4.h" +#include "config/nm-sysv4.h" #ifdef NEW_PROC_API /* Solaris 6 and above can do HW watchpoints */ @@ -28,11 +28,12 @@ can support "thousands" of hardware watchpoints, but gives no method for finding out how many. So just tell GDB 'yes'. */ #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE, CNT, OT) 1 +#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(SIZE) 1 /* When a hardware watchpoint fires off the PC will be left at the instruction following the one which caused the watchpoint. It will *NOT* be necessary for GDB to step over the watchpoint. */ -#define HAVE_CONTINUABLE_WATCHPOINT +#define HAVE_CONTINUABLE_WATCHPOINT 1 /* Solaris x86 2.6 and 2.7 targets have a kernel bug when stepping over an instruction that causes a page fault without triggering diff --git a/contrib/gdb/gdb/config/i386/nm-i386v.h b/contrib/gdb/gdb/config/i386/nm-i386v.h index e7bfca4ea57..f94c5bb8b35 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386v.h +++ b/contrib/gdb/gdb/config/i386/nm-i386v.h @@ -1,5 +1,6 @@ -/* Native support for i386. - Copyright 1986, 1987, 1989, 1992, 1993, 1998, 2000 +/* Native support for i386 running System V (pre-SVR4). + + Copyright 1986, 1987, 1989, 1992, 1993, 1998, 2000, 2002 Free Software Foundation, Inc. Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988. @@ -20,18 +21,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if 0 -/* code to execute to print interesting information about the - floating point processor (if any) - No need to define if there is nothing to do. - On the 386, unfortunately this code is host-dependent (and lives - in the i386-xdep.c file), so we can't - do this unless we *know* we aren't cross-debugging. FIXME. - */ -#define FLOAT_INFO { i386_float_info (); } -#endif /*0 */ +#ifndef NM_I386V_H +#define NM_I386V_H -#define REGISTER_U_ADDR(addr, blockend, regno) \ - (addr) = i386_register_u_addr ((blockend),(regno)); +/* Support for the user struct. */ -extern int i386_register_u_addr (int, int); +/* This is the amount to subtract from u.u_ar0 + to get the offset in the core file of the register values. */ + +#define REGISTER_U_ADDR(addr, blockend, regnum) \ + (addr) = register_u_addr ((blockend), (regnum)) +extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum); + + +/* Number of traps that happen between exec'ing the shell to run an + inferior, and when we finally get to the inferior code. This is 2 + on most implementations. Override here to 4. */ + +#undef START_INFERIOR_TRAPS_EXPECTED +#define START_INFERIOR_TRAPS_EXPECTED 4 + +#endif /* nm-i386v.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-i386v4.h b/contrib/gdb/gdb/config/i386/nm-i386v4.h index 02d445e8bc3..356d3cba0ca 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386v4.h +++ b/contrib/gdb/gdb/config/i386/nm-i386v4.h @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "nm-sysv4.h" +#include "config/nm-sysv4.h" /* Poll causes GDB to hang, at least under Unixware 1.1.2. */ #define LOSING_POLL diff --git a/contrib/gdb/gdb/config/i386/nm-i386v42mp.h b/contrib/gdb/gdb/config/i386/nm-i386v42mp.h index 72e440d0cc4..f6fced506e8 100644 --- a/contrib/gdb/gdb/config/i386/nm-i386v42mp.h +++ b/contrib/gdb/gdb/config/i386/nm-i386v42mp.h @@ -20,4 +20,73 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "nm-sysv4.h" +#ifndef NM_I386V42MP_H +#define NM_I386V42MP_H + +#include "config/nm-sysv4.h" + +/* define to select for other sysv4.2mp weirdness (see procfs.c) */ + +#define UNIXWARE + +#if 0 +/* The following macros extract process and lwp/thread ids from a + composite id. + + For consistency with UnixWare core files, allocate bits 0-15 for + process ids and bits 16 and up for lwp ids. Reserve bit 31 for + negative return values to indicate exceptions, and use bit 30 as a + flag to indicate a user-mode thread, leaving 14 bits for lwp + ids. */ + +/* Number of bits in composite id allocated to process number. */ +#define PIDBITS 16 + +/* Return the process id stored in composite PID. */ +#define PIDGET(PID) (((PID) & ((1 << PIDBITS) - 1))) + +/* Return the thread or lwp id stored in composite PID. */ +#define TIDGET(PID) (((PID) & 0x3fffffff) >> PIDBITS) +#define LIDGET(PID) TIDGET(PID) + +/* Construct a composite id from lwp LID and the process portion of + composite PID. */ +#define MERGEPID(PID, LID) (PIDGET(PID) | ((LID) << PIDBITS)) +#define MKLID(PID, LID) MERGEPID(PID, LID) + +/* Construct a composite id from thread TID and the process portion of + composite PID. */ +#define MKTID(PID, TID) (MERGEPID(PID, TID) | 0x40000000) + +/* Return whether PID contains a user-space thread id. */ +#define ISTID(PID) ((PID) & 0x40000000) +#endif + +/* New definitions of the ptid stuff. Due to the way the + code is structured in uw-thread.c, I'm overloading the thread id + and lwp id onto the lwp field. The tid field is used to indicate + whether the lwp is a tid or not. + + FIXME: Check that core file support is not broken. (See original + #if 0'd comments above.) + FIXME: Restructure uw-thread.c so that the struct ptid fields + can be used as intended. */ + +/* Return the process id stored in composite PID. */ +#define PIDGET(PID) (ptid_get_pid (PID)) + +/* Return the thread or lwp id stored in composite PID. */ +#define TIDGET(PID) (ptid_get_lwp (PID)) +#define LIDGET(PID) TIDGET(PID) + +#define MERGEPID(PID, LID) (ptid_build ((PID), (LID), 0)) +#define MKLID(PID, LID) (ptid_build ((PID), (LID), 0)) + +/* Construct a composite id from thread TID and the process portion of + composite PID. */ +#define MKTID(PID, TID) (ptid_build ((PID), (TID), 1)) + +/* Return whether PID contains a user-space thread id. */ +#define ISTID(PID) (ptid_get_tid (PID)) + +#endif /* NM_I386V42MP_H */ diff --git a/contrib/gdb/gdb/config/i386/nm-nbsd.h b/contrib/gdb/gdb/config/i386/nm-nbsd.h index f926f9bc273..fef50f37bf5 100644 --- a/contrib/gdb/gdb/config/i386/nm-nbsd.h +++ b/contrib/gdb/gdb/config/i386/nm-nbsd.h @@ -1,5 +1,6 @@ -/* Native-dependent definitions for Intel 386 running NetBSD, for GDB. - Copyright 1986, 1987, 1989, 1992, 1994, 1996, 2000 +/* Native-dependent definitions for NetBSD/i386. + + Copyright 1986, 1987, 1989, 1992, 1994, 2000, 2002, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -22,12 +23,7 @@ #ifndef NM_NBSD_H #define NM_NBSD_H -/* Get generic NetBSD native definitions. */ +/* Get generic NetBSD native definitions. */ #include "config/nm-nbsd.h" -#define REGISTER_U_ADDR(addr, blockend, regno) \ - (addr) = i386_register_u_addr ((blockend),(regno)); - -extern int i386_register_u_addr (int, int); - -#endif /* NM_NBSD_H */ +#endif /* nm-nbsd.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-nbsdaout.h b/contrib/gdb/gdb/config/i386/nm-nbsdaout.h new file mode 100644 index 00000000000..375a6a02d95 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nm-nbsdaout.h @@ -0,0 +1,31 @@ +/* Native-dependent definitions for NetBSD/i386 a.out. + + Copyright 1986, 1987, 1989, 1992, 1994, 1996, 2000, 2004 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_NBSDAOUT_H +#define NM_NBSDAOUT_H + +#include "i386/nm-nbsd.h" + +/* Get generic NetBSD a.out native definitions. */ +#include "config/nm-nbsdaout.h" + +#endif /* nm-nbsdaout.h */ diff --git a/contrib/gdb/gdb/config/i386/nm-nto.h b/contrib/gdb/gdb/config/i386/nm-nto.h new file mode 100755 index 00000000000..34d99033e70 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nm-nto.h @@ -0,0 +1,6 @@ +#ifndef _NM_NTO_H +#define _NM_NTO_H + +/* This file needed to build a native debugger. */ + +#endif diff --git a/contrib/gdb/gdb/config/i386/nm-obsd.h b/contrib/gdb/gdb/config/i386/nm-obsd.h index 6113e140088..4d10b539d86 100644 --- a/contrib/gdb/gdb/config/i386/nm-obsd.h +++ b/contrib/gdb/gdb/config/i386/nm-obsd.h @@ -1,5 +1,6 @@ /* Native-dependent definitions for OpenBSD/i386. - Copyright 2001 Free Software Foundation, Inc. + + Copyright 2001, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -51,9 +52,10 @@ extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regno); /* Shared library support. */ -#include "solib.h" /* Support for shared libraries. */ +#include "solib.h" -/* Make structure definitions match up with those expected in `solib.c'. */ +/* Make structure definitions match up with those expected in + `solib-sunos.c'. */ #define link_object sod #define lo_name sod_name diff --git a/contrib/gdb/gdb/config/i386/nto.mh b/contrib/gdb/gdb/config/i386/nto.mh new file mode 100755 index 00000000000..f412579334d --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nto.mh @@ -0,0 +1,7 @@ +# Host: Intel 386 running QNX. + +NAT_FILE= nm-nto.h + +NATDEPFILES= nto-procfs.o + +XM_FILE= xm-i386.h diff --git a/contrib/gdb/gdb/config/i386/nto.mt b/contrib/gdb/gdb/config/i386/nto.mt new file mode 100755 index 00000000000..6655f3eee74 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/nto.mt @@ -0,0 +1,4 @@ +# Target: Intel 386 running qnx6. +TDEPFILES = i386-tdep.o i387-tdep.o corelow.o solib.o solib-svr4.o \ + i386-nto-tdep.o nto-tdep.o remote-nto.o +TM_FILE = tm-nto.h diff --git a/contrib/gdb/gdb/config/i386/obsd.mh b/contrib/gdb/gdb/config/i386/obsd.mh index 2bfd732b608..50a4fb71062 100644 --- a/contrib/gdb/gdb/config/i386/obsd.mh +++ b/contrib/gdb/gdb/config/i386/obsd.mh @@ -1,7 +1,4 @@ -# Host: Intel 386 running OpenBSD - -XM_FILE= xm-i386.h - +# Host: OpenBSD/i386 ELF +NATDEPFILES= fork-child.o infptrace.o inftarg.o i386bsd-nat.o i386obsd-nat.o NAT_FILE= nm-obsd.h -# NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. -NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-sunos.o corelow.o core-aout.o i386-nat.o i387-nat.o i386bsd-nat.o +XM_FILE= xm-i386.h diff --git a/contrib/gdb/gdb/config/i386/obsd.mt b/contrib/gdb/gdb/config/i386/obsd.mt index 5c96426b96d..58e0fc0ebc8 100644 --- a/contrib/gdb/gdb/config/i386/obsd.mt +++ b/contrib/gdb/gdb/config/i386/obsd.mt @@ -1,3 +1,4 @@ -# Target: Intel 386 running OpenBSD -TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o -TM_FILE= tm-obsd.h +# Target: OpenBSD/i386 +TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386obsd-tdep.o \ + corelow.o solib.o solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/i386/obsd64.mh b/contrib/gdb/gdb/config/i386/obsd64.mh new file mode 100644 index 00000000000..99ccfa2023f --- /dev/null +++ b/contrib/gdb/gdb/config/i386/obsd64.mh @@ -0,0 +1,5 @@ +# Host: OpenBSD/amd64 +NATDEPFILES= fork-child.o infptrace.o inftarg.o \ + amd64-nat.o amd64bsd-nat.o amd64obsd-nat.o +NAT_FILE= nm-nbsd.h +XM_FILE= xm-i386.h diff --git a/contrib/gdb/gdb/config/i386/obsd64.mt b/contrib/gdb/gdb/config/i386/obsd64.mt new file mode 100644 index 00000000000..16be0798e7f --- /dev/null +++ b/contrib/gdb/gdb/config/i386/obsd64.mt @@ -0,0 +1,5 @@ +# Target: OpenBSD/amd64 +TDEPFILES= amd64-tdep.o amd64obsd-tdep.o \ + i386-tdep.o i387-tdep.o i386bsd-tdep.o \ + corelow.o solib.o solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/i386/obsdaout.mh b/contrib/gdb/gdb/config/i386/obsdaout.mh new file mode 100644 index 00000000000..3577178946a --- /dev/null +++ b/contrib/gdb/gdb/config/i386/obsdaout.mh @@ -0,0 +1,5 @@ +# Host: OpenBSD/i386 a.out +NATDEPFILES= fork-child.o infptrace.o inftarg.o i386bsd-nat.o i386obsd-nat.o \ + solib.o solib-sunos.o +NAT_FILE= nm-obsd.h +XM_FILE= xm-i386.h diff --git a/contrib/gdb/gdb/config/i386/tm-fbsd.h b/contrib/gdb/gdb/config/i386/tm-fbsd.h index 5c819ce5250..98a2702175c 100644 --- a/contrib/gdb/gdb/config/i386/tm-fbsd.h +++ b/contrib/gdb/gdb/config/i386/tm-fbsd.h @@ -1,5 +1,6 @@ /* Target-dependent definitions for FreeBSD/i386. - Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1997, 1999, 2000, 2001, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -21,73 +22,10 @@ #ifndef TM_FBSD_H #define TM_FBSD_H -#define HAVE_I387_REGS -#include "i386/tm-i386.h" +#include "solib.h" #ifdef HAVE_SYS_PARAM_H #include #endif -/* FreeBSD/ELF uses stabs-in-ELF with the DWARF register numbering - scheme by default, so we must redefine STAB_REG_TO_REGNUM. This - messes up the floating-point registers for a.out, but there is not - much we can do about that. */ - -#undef STAB_REG_TO_REGNUM -#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg)) - -/* FreeBSD uses the old gcc convention for struct returns. */ - -#define USE_STRUCT_CONVENTION(gcc_p, type) \ - generic_use_struct_convention (1, type) - - -/* Support for longjmp. */ - -/* Details about jmp_buf. It's supposed to be an array of integers. */ - -#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */ -#define JB_PC 0 /* Array index of saved PC. */ - -/* Figure out where the longjmp will land. Store the address that - longjmp will jump to in *ADDR, and return non-zero if successful. */ - -#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr) -extern int get_longjmp_target (CORE_ADDR *addr); - - -/* Support for signal handlers. */ - -#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name) -extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name); - -/* These defines allow the recognition of sigtramps as a function name - . - - FIXME: kettenis/2001-07-13: These should be added to the target - vector and turned into functions when we go "multi-arch". */ - -#define SIGTRAMP_START(pc) i386bsd_sigtramp_start -#define SIGTRAMP_END(pc) i386bsd_sigtramp_end -extern CORE_ADDR i386bsd_sigtramp_start; -extern CORE_ADDR i386bsd_sigtramp_end; - -/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */ - -#undef FRAME_SAVED_PC -#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame) -extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame); - - -/* Shared library support. */ - -#ifndef SVR4_SHARED_LIBS - -/* Return non-zero if we are in a shared library trampoline code stub. */ - -#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \ - (name && !strcmp(name, "_DYNAMIC")) - -#endif /* !SVR4_SHARED_LIBS */ - -#endif /* TM_FBSD_H */ +#endif /* tm-fbsd.h */ diff --git a/contrib/gdb/gdb/config/i386/tm-go32.h b/contrib/gdb/gdb/config/i386/tm-go32.h index b660827bd66..85e0888ef80 100644 --- a/contrib/gdb/gdb/config/i386/tm-go32.h +++ b/contrib/gdb/gdb/config/i386/tm-go32.h @@ -22,47 +22,7 @@ #define TM_GO32_H #undef HAVE_SSE_REGS /* FIXME! go32-nat.c needs to support XMMi registers */ -#define HAVE_I387_REGS #include "i386/tm-i386.h" -/* FRAME_CHAIN takes a frame's nominal address and produces the frame's - chain-pointer. - In the case of the i386, the frame's nominal address - is the address of a 4-byte word containing the calling frame's address. - DJGPP doesn't have any special frames for signal handlers, they are - just normal C functions. */ -#undef FRAME_CHAIN -#define FRAME_CHAIN(thisframe) \ - (!inside_entry_file ((thisframe)->pc) ? \ - read_memory_integer ((thisframe)->frame, 4) :\ - 0) - -/* A macro that tells us whether the function invocation represented - by FI does not have a frame on the stack associated with it. If it - does not, FRAMELESS is set to 1, else 0. */ -#undef FRAMELESS_FUNCTION_INVOCATION -#define FRAMELESS_FUNCTION_INVOCATION(FI) \ - (frameless_look_for_prologue(FI)) - -extern CORE_ADDR i386go32_frame_saved_pc (struct frame_info *frame); -#undef FRAME_SAVED_PC -#define FRAME_SAVED_PC(FRAME) (i386go32_frame_saved_pc ((FRAME))) - -/* Support for longjmp. */ - -/* Details about jmp_buf. It's supposed to be an array of integers. */ - -#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */ -#define JB_PC 8 /* Array index of saved PC inside jmp_buf. */ - -/* Figure out where the longjmp will land. Slurp the args out of the - stack. We expect the first arg to be a pointer to the jmp_buf - structure from which we extract the pc (JB_PC) that we will land - at. The pc is copied into ADDR. This routine returns true on - success. */ - -#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr) -extern int get_longjmp_target (CORE_ADDR *addr); - #endif /* TM_GO32_H */ diff --git a/contrib/gdb/gdb/config/i386/tm-i386.h b/contrib/gdb/gdb/config/i386/tm-i386.h index f9326fecb9a..e2bd81fdaa8 100644 --- a/contrib/gdb/gdb/config/i386/tm-i386.h +++ b/contrib/gdb/gdb/config/i386/tm-i386.h @@ -22,358 +22,4 @@ #ifndef TM_I386_H #define TM_I386_H 1 -#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL - -#include "regcache.h" - -/* Forward declarations for prototypes. */ -struct frame_info; -struct frame_saved_regs; -struct value; -struct type; - -/* The format used for `long double' on almost all i386 targets is the - i387 extended floating-point format. In fact, of all targets in the - GCC 2.95 tree, only OSF/1 does it different, and insists on having - a `long double' that's not `long' at all. */ - -#define TARGET_LONG_DOUBLE_FORMAT &floatformat_i387_ext - -/* Although the i386 extended floating-point has only 80 significant - bits, a `long double' actually takes up 96, probably to enforce - alignment. */ - -#define TARGET_LONG_DOUBLE_BIT 96 - -/* Number of traps that happen between exec'ing the shell to run an - inferior, and when we finally get to the inferior code. This is 2 - on most implementations. */ - -#define START_INFERIOR_TRAPS_EXPECTED 2 - -/* Offset from address of function to start of its code. - Zero on most machines. */ - -#define FUNCTION_START_OFFSET 0 - -/* Advance PC across any function entry prologue instructions to reach some - "real" code. */ - -#define SKIP_PROLOGUE(frompc) (i386_skip_prologue (frompc)) - -extern int i386_skip_prologue (int); - -/* Immediately after a function call, return the saved pc. */ - -#define SAVED_PC_AFTER_CALL(frame) i386_saved_pc_after_call (frame) -extern CORE_ADDR i386_saved_pc_after_call (struct frame_info *frame); - -/* Stack grows downward. */ - -#define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) - -/* Sequence of bytes for breakpoint instruction. */ - -#define BREAKPOINT {0xcc} - -/* Amount PC must be decremented by after a breakpoint. This is often the - number of bytes in BREAKPOINT but not always. */ - -#define DECR_PC_AFTER_BREAK 1 - -/* Say how long (ordinary) registers are. This is a piece of bogosity - used in push_word and a few other places; REGISTER_RAW_SIZE is the - real way to know how big a register is. */ - -#define REGISTER_SIZE 4 - -/* This register file is parameterized by two macros: - HAVE_I387_REGS --- register file should include i387 registers - HAVE_SSE_REGS --- register file should include SSE registers - If HAVE_SSE_REGS is #defined, then HAVE_I387_REGS must also be #defined. - - However, GDB code should not test those macros with #ifdef, since - that makes code which is annoying to multi-arch. Instead, GDB code - should check the values of NUM_GREGS, NUM_FREGS, and NUM_SSE_REGS, - which will eventually get mapped onto architecture vector entries. - - It's okay to use the macros in tm-*.h files, though, since those - files will get completely replaced when we multi-arch anyway. */ - -/* Number of general registers, present on every 32-bit x86 variant. */ -#define NUM_GREGS (16) - -/* Number of floating-point unit registers. */ -#ifdef HAVE_I387_REGS -#define NUM_FREGS (16) -#else -#define NUM_FREGS (0) -#endif - -/* Number of SSE registers. */ -#ifdef HAVE_SSE_REGS -#define NUM_SSE_REGS (9) -#else -#define NUM_SSE_REGS (0) -#endif - -/* Largest number of registers we could have in any configuration. */ -#define MAX_NUM_REGS (16 + 16 + 9) - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -#define FP_REGNUM 5 /* (ebp) Contains address of executing stack - frame */ -#define SP_REGNUM 4 /* (usp) Contains address of top of stack */ -#define PC_REGNUM 8 /* (eip) Contains program counter */ -#define PS_REGNUM 9 /* (ps) Contains processor status */ - -/* First FPU data register. */ -#ifdef HAVE_I387_REGS -#define FP0_REGNUM 16 -#else -#define FP0_REGNUM 0 -#endif - -/* Return the name of register REG. */ - -#define REGISTER_NAME(reg) i386_register_name ((reg)) -extern char *i386_register_name (int reg); - -/* Use the "default" register numbering scheme for stabs and COFF. */ - -#define STAB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg)) -#define SDB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg)) -extern int i386_stab_reg_to_regnum (int reg); - -/* Use the DWARF register numbering scheme for DWARF and DWARF 2. */ - -#define DWARF_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg)) -#define DWARF2_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg)) -extern int i386_dwarf_reg_to_regnum (int reg); - -/* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to be - in use on any of the supported i386 targets. */ - - -/* Sizes of individual register sets. These cover the entire register - file, so summing up the sizes of those portions actually present - yields REGISTER_BYTES. */ -#define SIZEOF_GREGS (NUM_GREGS * 4) -#define SIZEOF_FPU_REGS (8 * 10) -#define SIZEOF_FPU_CTRL_REGS (8 * 4) -#define SIZEOF_SSE_REGS (8 * 16 + 4) - - -/* Total amount of space needed to store our copies of the machine's register - state, the array `registers'. */ -#ifdef HAVE_SSE_REGS -#define REGISTER_BYTES \ - (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS) -#else -#ifdef HAVE_I387_REGS -#define REGISTER_BYTES (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS) -#else -#define REGISTER_BYTES (SIZEOF_GREGS) -#endif -#endif - -/* Return the offset into the register array of the start of register - number REG. */ -#define REGISTER_BYTE(reg) i386_register_byte ((reg)) -extern int i386_register_byte (int reg); - -/* Return the number of bytes of storage in GDB's register array - occupied by register REG. */ -#define REGISTER_RAW_SIZE(reg) i386_register_raw_size ((reg)) -extern int i386_register_raw_size (int reg); - -/* Largest value REGISTER_RAW_SIZE can have. */ -#define MAX_REGISTER_RAW_SIZE 16 - -/* Return the size in bytes of the virtual type of register REG. */ -#define REGISTER_VIRTUAL_SIZE(reg) i386_register_virtual_size ((reg)) -extern int i386_register_virtual_size (int reg); - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ -#define MAX_REGISTER_VIRTUAL_SIZE 16 - -/* Return the GDB type object for the "standard" data type of data in - register REGNUM. */ - -#define REGISTER_VIRTUAL_TYPE(regnum) i386_register_virtual_type (regnum) -extern struct type *i386_register_virtual_type (int regnum); - -/* Return true iff register REGNUM's virtual format is different from - its raw format. */ - -#define REGISTER_CONVERTIBLE(regnum) i386_register_convertible (regnum) -extern int i386_register_convertible (int regnum); - -/* Convert data from raw format for register REGNUM in buffer FROM to - virtual format with type TYPE in buffer TO. */ - -#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) \ - i386_register_convert_to_virtual ((regnum), (type), (from), (to)) -extern void i386_register_convert_to_virtual (int regnum, struct type *type, - char *from, char *to); - -/* Convert data from virtual format with type TYPE in buffer FROM to - raw format for register REGNUM in buffer TO. */ - -#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) \ - i386_register_convert_to_raw ((type), (regnum), (from), (to)) -extern void i386_register_convert_to_raw (struct type *type, int regnum, - char *from, char *to); - -/* Print out the i387 floating point state. */ -#ifdef HAVE_I387_REGS -extern void i387_float_info (void); -#define FLOAT_INFO { i387_float_info (); } -#endif - - -#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \ - i386_push_arguments ((nargs), (args), (sp), (struct_return), (struct_addr)) -extern CORE_ADDR i386_push_arguments (int nargs, struct value **args, - CORE_ADDR sp, int struct_return, - CORE_ADDR struct_addr); - -/* Store the address of the place in which to copy the structure the - subroutine will return. This is called from call_function. */ - -#define STORE_STRUCT_RETURN(addr, sp) \ - i386_store_struct_return ((addr), (sp)) -extern void i386_store_struct_return (CORE_ADDR addr, CORE_ADDR sp); - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -#define EXTRACT_RETURN_VALUE(type, regbuf, valbuf) \ - i386_extract_return_value ((type), (regbuf), (valbuf)) -extern void i386_extract_return_value (struct type *type, char *regbuf, - char *valbuf); - -/* Write into the appropriate registers a function return value stored - in VALBUF of type TYPE, given in virtual format. */ - -#define STORE_RETURN_VALUE(type, valbuf) \ - i386_store_return_value ((type), (valbuf)) -extern void i386_store_return_value (struct type *type, char *valbuf); - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR. */ - -#define EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) \ - i386_extract_struct_value_address ((regbuf)) -extern CORE_ADDR i386_extract_struct_value_address (char *regbuf); - -/* The following redefines make backtracing through sigtramp work. - They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp - from the sigcontext structure which is pushed by the kernel on the - user stack, along with a pointer to it. */ - -/* Return the chain-pointer for FRAME. In the case of the i386, the - frame's nominal address is the address of a 4-byte word containing - the calling frame's address. */ - -#define FRAME_CHAIN(frame) i386_frame_chain ((frame)) -extern CORE_ADDR i386_frame_chain (struct frame_info *frame); - -/* Determine whether the function invocation represented by FRAME does - not have a from on the stack associated with it. If it does not, - return non-zero, otherwise return zero. */ - -#define FRAMELESS_FUNCTION_INVOCATION(frame) \ - i386_frameless_function_invocation (frame) -extern int i386_frameless_function_invocation (struct frame_info *frame); - -/* Return the saved program counter for FRAME. */ - -#define FRAME_SAVED_PC(frame) i386_frame_saved_pc (frame) -extern CORE_ADDR i386_frame_saved_pc (struct frame_info *frame); - -#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame) - -#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) - -/* Return number of args passed to a frame. Can return -1, meaning no way - to tell, which is typical now that the C compiler delays popping them. */ - -#define FRAME_NUM_ARGS(fi) (i386_frame_num_args(fi)) - -extern int i386_frame_num_args (struct frame_info *); - -/* Return number of bytes at start of arglist that are not really args. */ - -#define FRAME_ARGS_SKIP 8 - -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ - -extern void i386_frame_init_saved_regs (struct frame_info *); -#define FRAME_INIT_SAVED_REGS(FI) i386_frame_init_saved_regs (FI) - - - -/* Things needed for making the inferior call functions. */ - -/* "An argument's size is increased, if necessary, to make it a - multiple of [32 bit] words. This may require tail padding, - depending on the size of the argument" - from the x86 ABI. */ -#define PARM_BOUNDARY 32 - -/* Push an empty stack frame, to record the current PC, etc. */ - -#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); } - -extern void i386_push_dummy_frame (void); - -/* Discard from the stack the innermost frame, restoring all registers. */ - -#define POP_FRAME { i386_pop_frame (); } - -extern void i386_pop_frame (void); - - -/* this is - * call 11223344 (32 bit relative) - * int3 - */ - -#define CALL_DUMMY { 0x223344e8, 0xcc11 } - -#define CALL_DUMMY_LENGTH 8 - -#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */ - -#define CALL_DUMMY_BREAKPOINT_OFFSET 5 - -/* Insert the specified number of args and function address - into a call sequence of the above form stored at DUMMYNAME. */ - -#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \ - i386_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p) -extern void i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, - int nargs, struct value **args, - struct type *type, int gcc_p); - -/* FIXME: kettenis/2000-06-12: These do not belong here. */ -extern void print_387_control_word (unsigned int); -extern void print_387_status_word (unsigned int); - -/* Offset from SP to first arg on stack at first instruction of a function */ - -#define SP_ARG0 (1 * 4) - #endif /* ifndef TM_I386_H */ diff --git a/contrib/gdb/gdb/config/i386/tm-i386lynx.h b/contrib/gdb/gdb/config/i386/tm-i386lynx.h index 842f9a7738d..03fe4ff8bf7 100644 --- a/contrib/gdb/gdb/config/i386/tm-i386lynx.h +++ b/contrib/gdb/gdb/config/i386/tm-i386lynx.h @@ -1,5 +1,5 @@ /* Macro definitions for Intel 386 running under LynxOS. - Copyright 1993, 1995 Free Software Foundation, Inc. + Copyright 1993, 1995, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -21,14 +21,9 @@ #ifndef TM_I386LYNX_H #define TM_I386LYNX_H -#include "tm-lynx.h" +#include "config/tm-lynx.h" /* Most definitions from sysv could be used. */ #include "i386/tm-i386.h" -#undef SAVED_PC_AFTER_CALL - -#define SAVED_PC_AFTER_CALL i386lynx_saved_pc_after_call -CORE_ADDR i386lynx_saved_pc_after_call (); - #endif /* TM_I386LYNX_H */ diff --git a/contrib/gdb/gdb/config/i386/tm-i386sol2.h b/contrib/gdb/gdb/config/i386/tm-i386sol2.h index c90e0d475ae..921df26dc07 100644 --- a/contrib/gdb/gdb/config/i386/tm-i386sol2.h +++ b/contrib/gdb/gdb/config/i386/tm-i386sol2.h @@ -21,30 +21,7 @@ #ifndef TM_I386SOL2_H #define TM_I386SOL2_H 1 -#define HAVE_I387_REGS -#include "i386/tm-i386v4.h" - -/* We use stabs-in-ELF with the DWARF register numbering scheme. */ - -#undef STAB_REG_TO_REGNUM -#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg)) - -/* If the current gcc for for this target does not produce correct - debugging information for float parameters, both prototyped and - unprototyped, then define this macro. This forces gdb to always - assume that floats are passed as doubles and then converted in the - callee. */ - -#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1) - -/* Signal handler frames under Solaris 2 are recognized by a return address - of 0xFFFFFFFF, the third parameter on the signal handler stack is - a pointer to an ucontext. */ -#undef sigtramp_saved_pc -#undef I386V4_SIGTRAMP_SAVED_PC -#define SIGCONTEXT_PC_OFFSET (36 + 14 * 4) -#undef IN_SIGTRAMP -#define IN_SIGTRAMP(pc, name) (pc == 0xFFFFFFFF) +#include "i386/tm-i386.h" /* The SunPRO compiler puts out 0 instead of the address in N_SO symbols, and for SunPRO 3.0, N_FUN symbols too. */ @@ -54,6 +31,4 @@ extern char *sunpro_static_transform_name (char *); #define STATIC_TRANSFORM_NAME(x) sunpro_static_transform_name (x) #define IS_STATIC_TRANSFORM_NAME(name) ((name)[0] == '.') -#define FAULTED_USE_SIGINFO - #endif /* ifndef TM_I386SOL2_H */ diff --git a/contrib/gdb/gdb/config/i386/tm-nbsd.h b/contrib/gdb/gdb/config/i386/tm-nbsd.h index ff67a5e62ea..8fd41580765 100644 --- a/contrib/gdb/gdb/config/i386/tm-nbsd.h +++ b/contrib/gdb/gdb/config/i386/tm-nbsd.h @@ -1,5 +1,6 @@ -/* Macro definitions for i386 running under NetBSD. - Copyright 1994, 1996, 2000, 2002 Free Software Foundation, Inc. +/* Target-dependent definitions for NetBSD/i386. + + Copyright 1994, 1996, 2000, 2002, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -21,50 +22,6 @@ #ifndef TM_NBSD_H #define TM_NBSD_H -#define HAVE_I387_REGS -#define HAVE_SSE_REGS +#include "solib.h" -#include "i386/tm-i386.h" -#include "config/tm-nbsd.h" - -extern use_struct_convention_fn i386nbsd_use_struct_convention; -#define USE_STRUCT_CONVENTION(gcc_p, type) \ - i386nbsd_use_struct_convention(gcc_p, type) - - -#define JB_ELEMENT_SIZE sizeof(int) /* jmp_buf[_JBLEN] is array of ints */ -#define JB_PC 0 /* Setjmp()'s return PC saved here */ - -/* Figure out where the longjmp will land. Slurp the args out of the stack. - We expect the first arg to be a pointer to the jmp_buf structure from which - we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. - This routine returns true on success */ - -extern int get_longjmp_target (CORE_ADDR *); - -#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR) - - -/* Support for signal handlers. */ - -#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name) -extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name); - -/* These defines allow the recognition of sigtramps as a function name - . - - FIXME: kettenis/2001-07-13: These should be added to the target - vector and turned into functions when we go "multi-arch". */ - -#define SIGTRAMP_START(pc) i386bsd_sigtramp_start -#define SIGTRAMP_END(pc) i386bsd_sigtramp_end -extern CORE_ADDR i386bsd_sigtramp_start; -extern CORE_ADDR i386bsd_sigtramp_end; - -/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */ - -#undef FRAME_SAVED_PC -#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame) -extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame); - -#endif /* TM_NBSD_H */ +#endif /* tm-nbsd.h */ diff --git a/contrib/gdb/gdb/config/i386/tm-nto.h b/contrib/gdb/gdb/config/i386/tm-nto.h new file mode 100755 index 00000000000..ff5eb7837e0 --- /dev/null +++ b/contrib/gdb/gdb/config/i386/tm-nto.h @@ -0,0 +1,33 @@ +/* QNX Neutrino target header. + + Copyright 2003 Free Software Foundation, Inc. + + This code was donated by QNX Software Systems Ltd. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_NTO_H +#define TM_NTO_H 1 + +/* Pick up most of what we need from the generic i386 target include file. */ +#include "i386/tm-i386.h" +#include "tm-nto.h" + +#include "solib.h" + +#endif /* TM_NTO_H */ diff --git a/contrib/gdb/gdb/config/i386/tm-vxworks.h b/contrib/gdb/gdb/config/i386/tm-vxworks.h index 6434a6ea2f5..f9b6be453cb 100644 --- a/contrib/gdb/gdb/config/i386/tm-vxworks.h +++ b/contrib/gdb/gdb/config/i386/tm-vxworks.h @@ -22,7 +22,7 @@ #ifndef TM_VXWORKS_H #define TM_VXWORKS_H -#include "i386/tm-i386v.h" -#include "tm-vxworks.h" +#include "i386/tm-i386.h" +#include "config/tm-vxworks.h" #endif /* ifndef TM_VXWORKS_H */ diff --git a/contrib/gdb/gdb/config/i386/xm-i386.h b/contrib/gdb/gdb/config/i386/xm-i386.h index 151e7a6b556..de29b265998 100644 --- a/contrib/gdb/gdb/config/i386/xm-i386.h +++ b/contrib/gdb/gdb/config/i386/xm-i386.h @@ -1,5 +1,6 @@ -/* Host-dependent definitions for i386. - Copyright 2001 Free Software Foundation, Inc. +/* Host-dependent definitions for the i386. + + Copyright 2001, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -27,4 +28,4 @@ #define HOST_DOUBLE_FORMAT &floatformat_ieee_double_little #define HOST_LONG_DOUBLE_FORMAT &floatformat_i387_ext -#endif /* XM_386_H */ +#endif /* xm-i386.h */ diff --git a/contrib/gdb/gdb/config/i386/xm-i386sco.h b/contrib/gdb/gdb/config/i386/xm-i386sco.h index 920ebbb3c4d..18b64bf4207 100644 --- a/contrib/gdb/gdb/config/i386/xm-i386sco.h +++ b/contrib/gdb/gdb/config/i386/xm-i386sco.h @@ -24,17 +24,8 @@ #include "i386/xm-i386v.h" -/* Apparently there is inconsistency among various System V's about what - the name of this field is. */ -#define U_FPSTATE(u) u.u_fps.u_fpstate - /* SCO 3.2v2 and later have job control. */ /* SCO 3.2v4 I know has termios; I'm not sure about earlier versions. GDB does not currently support the termio/job control combination. */ #undef HAVE_TERMIO #define HAVE_TERMIOS - -/* SCO's assembler doesn't grok dollar signs in identifiers. - So we use dots instead. This item must be coordinated with G++. */ -#undef CPLUS_MARKER -#define CPLUS_MARKER '.' diff --git a/contrib/gdb/gdb/config/i386/xm-i386v4.h b/contrib/gdb/gdb/config/i386/xm-i386v4.h index c3241100bf7..154986c1880 100644 --- a/contrib/gdb/gdb/config/i386/xm-i386v4.h +++ b/contrib/gdb/gdb/config/i386/xm-i386v4.h @@ -25,4 +25,4 @@ /* Pick up more stuff from the generic SVR4 host include file. */ -#include "xm-sysv4.h" +#include "config/xm-sysv4.h" diff --git a/contrib/gdb/gdb/config/i386/xm-nbsd.h b/contrib/gdb/gdb/config/i386/xm-nbsd.h index 415d0fa4ffd..703c261ebe8 100644 --- a/contrib/gdb/gdb/config/i386/xm-nbsd.h +++ b/contrib/gdb/gdb/config/i386/xm-nbsd.h @@ -1,5 +1,6 @@ -/* Parameters for execution on a i386 running NetBSD, for GDB. - Copyright 1994, 2000 Free Software Foundation, Inc. +/* Host-dependent definitions for NetBSD/i386. + + Copyright 1994, 2000, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -18,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Get generic NetBSD host definitions. */ -#include "xm-nbsd.h" +#include "i386/xm-i386.h" -#define HOST_LONG_DOUBLE_FORMAT &floatformat_i387_ext +/* Get generic NetBSD host definitions. */ +#include "config/xm-nbsd.h" diff --git a/contrib/gdb/gdb/config/ia64/ia64.mt b/contrib/gdb/gdb/config/ia64/ia64.mt new file mode 100644 index 00000000000..c0f85a4c285 --- /dev/null +++ b/contrib/gdb/gdb/config/ia64/ia64.mt @@ -0,0 +1,2 @@ +TDEPFILES= ia64-tdep.o +TM_FILE= tm-ia64.h diff --git a/contrib/gdb/gdb/config/ia64/tm-ia64.h b/contrib/gdb/gdb/config/ia64/tm-ia64.h index d08e59bccd5..1b2baacd5a0 100644 --- a/contrib/gdb/gdb/config/ia64/tm-ia64.h +++ b/contrib/gdb/gdb/config/ia64/tm-ia64.h @@ -21,59 +21,8 @@ #ifndef TM_IA64_H #define TM_IA64_H -#if !defined(GDBSERVER) - #define GDB_MULTI_ARCH 1 -#else /* defines needed for GDBSERVER */ - -/* Say how long (ordinary) registers are. This is a piece of bogosity - used in push_word and a few other places; REGISTER_RAW_SIZE is the - real way to know how big a register is. */ - -#define REGISTER_SIZE 8 - -#undef NUM_REGS -#define NUM_REGS 590 - -/* Some pseudo register numbers */ - -#define PC_REGNUM IA64_IP_REGNUM -#define SP_REGNUM IA64_GR12_REGNUM -#define FP_REGNUM IA64_VFP_REGNUM - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. On the ia64, all registers - fit in 64 bits except for the floating point registers which require - 84 bits. But 84 isn't a nice number, so we'll just allocate 128 - bits for each of these. The expression below says that we - need 8 bytes for each register, plus an additional 8 bytes for each - of the 128 floating point registers. */ - -#define REGISTER_BYTES (NUM_REGS*8+128*8) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) (((N) * 8) \ - + ((N) <= IA64_FR0_REGNUM ? 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM))) - -/* Number of bytes of storage in the actual machine representation - for register N. */ - -#define REGISTER_RAW_SIZE(N) \ - ((IA64_FR0_REGNUM <= (N) && (N) <= IA64_FR127_REGNUM) ? 16 : 8) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 16 - - -#define GDBSERVER_RESUME_REGS { IA64_IP_REGNUM, IA64_PSR_REGNUM, SP_REGNUM, IA64_BSP_REGNUM, IA64_CFM_REGNUM } - -#endif /* GDBSERVER */ - - /* Register numbers of various important registers */ /* General registers; there are 128 of these 64 bit wide registers. The diff --git a/contrib/gdb/gdb/config/mips/decstation.mh b/contrib/gdb/gdb/config/mips/decstation.mh new file mode 100644 index 00000000000..63de3da10b5 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/decstation.mh @@ -0,0 +1,4 @@ +# OBSOLETE # Host: Little-endian MIPS machine such as DECstation. +# OBSOLETE XM_FILE= xm-mips.h +# OBSOLETE NAT_FILE= nm-mips.h +# OBSOLETE NATDEPFILES= infptrace.o inftarg.o corelow.o mips-nat.o fork-child.o diff --git a/contrib/gdb/gdb/config/mips/embed.mt b/contrib/gdb/gdb/config/mips/embed.mt new file mode 100644 index 00000000000..3dad52bd920 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/embed.mt @@ -0,0 +1,4 @@ +TDEPFILES= mips-tdep.o remote-mips.o +TM_FILE= tm-mips.h +SIM_OBS = remote-sim.o +SIM = ../sim/mips/libsim.a diff --git a/contrib/gdb/gdb/config/mips/littlemips.mh b/contrib/gdb/gdb/config/mips/littlemips.mh new file mode 100644 index 00000000000..30c40ad847c --- /dev/null +++ b/contrib/gdb/gdb/config/mips/littlemips.mh @@ -0,0 +1,3 @@ +# OBSOLETE # Host: Little-endian MIPS machine such as DECstation. +# OBSOLETE NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o +# OBSOLETE XM_FILE= xm-mips.h diff --git a/contrib/gdb/gdb/config/mips/mipsv4.mh b/contrib/gdb/gdb/config/mips/mipsv4.mh new file mode 100644 index 00000000000..1a6104b3f94 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/mipsv4.mh @@ -0,0 +1,6 @@ +# Host: Mips running SVR4 +XM_FILE= xm-mipsv4.h +NAT_FILE= ../nm-sysv4.h +NATDEPFILES= fork-child.o mipsv4-nat.o corelow.o core-regset.o \ + solib.o solib-svr4.o solib-legacy.o \ + procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o diff --git a/contrib/gdb/gdb/config/mips/mipsv4.mt b/contrib/gdb/gdb/config/mips/mipsv4.mt new file mode 100644 index 00000000000..13320c20ae6 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/mipsv4.mt @@ -0,0 +1,3 @@ +# OBSOLETE # Target: MIPS running SVR4 +# OBSOLETE TDEPFILES= mips-tdep.o +# OBSOLETE TM_FILE= tm-mipsv4.h diff --git a/contrib/gdb/gdb/config/mips/nbsd.mh b/contrib/gdb/gdb/config/mips/nbsd.mh new file mode 100644 index 00000000000..4556fc60b27 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/nbsd.mh @@ -0,0 +1,4 @@ +# Host: MIPS running NetBSD +NAT_CLIBS= +NATDEPFILES= infptrace.o inftarg.o fork-child.o mipsnbsd-nat.o +NAT_FILE= nm-nbsd.h diff --git a/contrib/gdb/gdb/config/mips/nbsd.mt b/contrib/gdb/gdb/config/mips/nbsd.mt new file mode 100644 index 00000000000..eb5d8871d79 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/nbsd.mt @@ -0,0 +1,7 @@ +# Target: MIPS running NetBSD +TDEPFILES= mips-tdep.o mipsnbsd-tdep.o corelow.o solib.o solib-svr4.o \ + nbsd-tdep.o +TM_FILE= tm-nbsd.h + +SIM_OBS = remote-sim.o +SIM = ../sim/mips/libsim.a diff --git a/contrib/gdb/gdb/config/mips/news-mips.mh b/contrib/gdb/gdb/config/mips/news-mips.mh new file mode 100644 index 00000000000..f2c7f89b3ed --- /dev/null +++ b/contrib/gdb/gdb/config/mips/news-mips.mh @@ -0,0 +1,3 @@ +# OBSOLETE # Host: Big-endian MIPS machine such as Sony News +# OBSOLETE NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o mips-nat.o +# OBSOLETE NAT_FILE= nm-news-mips.h diff --git a/contrib/gdb/gdb/config/mips/nm-mips.h b/contrib/gdb/gdb/config/mips/nm-mips.h new file mode 100644 index 00000000000..f20ddf1d466 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/nm-mips.h @@ -0,0 +1,34 @@ +// OBSOLETE /* Native definitions for GDB on DECstations, Sony News. and MIPS Riscos systems +// OBSOLETE Copyright 1986, 1987, 1989, 1992, 1995, 1996, 2000 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin +// OBSOLETE and by Alessandro Forin(af@cs.cmu.edu) at CMU +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ +// OBSOLETE #define FETCH_INFERIOR_REGISTERS +// OBSOLETE +// OBSOLETE /* Figure out where the longjmp will land. We expect that we have just entered +// OBSOLETE longjmp and haven't yet setup the stack frame, so the args are still in the +// OBSOLETE argument regs. a0 (CALL_ARG0) points at the jmp_buf structure from which we +// OBSOLETE extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. +// OBSOLETE This routine returns true on success */ +// OBSOLETE +// OBSOLETE #define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR) +// OBSOLETE extern int get_longjmp_target (CORE_ADDR *); diff --git a/contrib/gdb/gdb/config/mips/nm-nbsd.h b/contrib/gdb/gdb/config/mips/nm-nbsd.h new file mode 100644 index 00000000000..67628c2fa97 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/nm-nbsd.h @@ -0,0 +1,28 @@ +/* Native-dependent definitions for NetBSD/mips. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_NBSD_H +#define NM_NBSD_H + +/* Get generic NetBSD native definitions. */ +#include "config/nm-nbsd.h" + +#endif /* NM_NBSD_H */ diff --git a/contrib/gdb/gdb/config/mips/nm-news-mips.h b/contrib/gdb/gdb/config/mips/nm-news-mips.h new file mode 100644 index 00000000000..15d9b7b2c36 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/nm-news-mips.h @@ -0,0 +1,43 @@ +// OBSOLETE /* Definitions to make GDB run on a mips box under 4.3bsd. +// OBSOLETE Copyright 1986, 1987, 1989, 1993, 1996 Free Software Foundation, Inc. +// OBSOLETE Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin +// OBSOLETE and by Alessandro Forin(af@cs.cmu.edu) at CMU +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #ifndef NM_NEWS_MIPS_H +// OBSOLETE #define NM_NEWS_MIPS_H 1 +// OBSOLETE +// OBSOLETE /* Needed for RISC NEWS core files. */ +// OBSOLETE #include +// OBSOLETE #include +// OBSOLETE #define KERNEL_U_ADDR UADDR +// OBSOLETE +// OBSOLETE #define REGISTER_U_ADDR(addr, blockend, regno) \ +// OBSOLETE if (regno < 38) addr = (NBPG*UPAGES) + (regno - 38)*sizeof(int);\ +// OBSOLETE else addr = 0; /* ..somewhere in the pcb */ +// OBSOLETE +// OBSOLETE /* Kernel is a bit tenacious about sharing text segments, disallowing bpts. */ +// OBSOLETE #define ONE_PROCESS_WRITETEXT +// OBSOLETE +// OBSOLETE #include "mips/nm-mips.h" +// OBSOLETE +// OBSOLETE /* Apparently not in */ +// OBSOLETE typedef int pid_t; +// OBSOLETE +// OBSOLETE #endif /* NM_NEWS_MIPS_H */ diff --git a/contrib/gdb/gdb/config/mips/nm-riscos.h b/contrib/gdb/gdb/config/mips/nm-riscos.h new file mode 100644 index 00000000000..dba51b2775c --- /dev/null +++ b/contrib/gdb/gdb/config/mips/nm-riscos.h @@ -0,0 +1,60 @@ +// OBSOLETE /* This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* MIPS running RISC/os 4.52C. */ +// OBSOLETE +// OBSOLETE #define PCB_OFFSET(FIELD) ((int)&((struct user*)0)->u_pcb.FIELD) +// OBSOLETE +// OBSOLETE /* RISC/os 5.0 defines this in machparam.h. */ +// OBSOLETE #include +// OBSOLETE #define NBPG BSD43_NBPG +// OBSOLETE #define UPAGES BSD43_UPAGES +// OBSOLETE +// OBSOLETE /* Where is this used? I don't see any uses in mips-nat.c, and I don't think +// OBSOLETE the uses in infptrace.c are used if FETCH_INFERIOR_REGISTERS is defined. +// OBSOLETE Does the compiler react badly to "extern CORE_ADDR kernel_u_addr" (even +// OBSOLETE if never referenced)? */ +// OBSOLETE #define KERNEL_U_ADDR BSD43_UADDR +// OBSOLETE +// OBSOLETE #define REGISTER_U_ADDR(addr, blockend, regno) \ +// OBSOLETE if (regno < FP0_REGNUM) \ +// OBSOLETE addr = UPAGES*NBPG-EF_SIZE+4*((regno)+EF_AT-1); \ +// OBSOLETE else if (regno < PC_REGNUM) \ +// OBSOLETE addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-FP0_REGNUM); \ +// OBSOLETE else if (regno == PS_REGNUM) \ +// OBSOLETE addr = UPAGES*NBPG-EF_SIZE+4*EF_SR; \ +// OBSOLETE else if (regno == mips_regnum (current_gdbarch)->badvaddr) \ +// OBSOLETE addr = UPAGES*NBPG-EF_SIZE+4*EF_BADVADDR; \ +// OBSOLETE else if (regno == mips_regnum (current_gdbarch)->lo) \ +// OBSOLETE addr = UPAGES*NBPG-EF_SIZE+4*EF_MDLO; \ +// OBSOLETE else if (regno == mips_regnum (current_gdbarch)->hi) \ +// OBSOLETE addr = UPAGES*NBPG-EF_SIZE+4*EF_MDHI; \ +// OBSOLETE else if (regno == mips_regnum (current_gdbarch)->cause) \ +// OBSOLETE addr = UPAGES*NBPG-EF_SIZE+4*EF_CAUSE; \ +// OBSOLETE else if (regno == mips_regnum (current_gdbarch)->pc) \ +// OBSOLETE addr = UPAGES*NBPG-EF_SIZE+4*EF_EPC; \ +// OBSOLETE else if (regno < mips_regnum (current_gdbarch)->fp_control_status) \ +// OBSOLETE addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-FP0_REGNUM); \ +// OBSOLETE else if (regno == mips_regnum (current_gdbarch)->fp_control_status) \ +// OBSOLETE addr = PCB_OFFSET(pcb_fpc_csr); \ +// OBSOLETE else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision) \ +// OBSOLETE addr = PCB_OFFSET(pcb_fpc_eir); \ +// OBSOLETE else \ +// OBSOLETE addr = 0; +// OBSOLETE +// OBSOLETE #include "mips/nm-mips.h" +// OBSOLETE +// OBSOLETE /* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ +// OBSOLETE #define FETCH_INFERIOR_REGISTERS diff --git a/contrib/gdb/gdb/config/mips/riscos.mh b/contrib/gdb/gdb/config/mips/riscos.mh new file mode 100644 index 00000000000..0a1c31c65f1 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/riscos.mh @@ -0,0 +1,16 @@ +# OBSOLETE # Host: MIPS running RISC/os +# OBSOLETE +# OBSOLETE XM_FILE= xm-riscos.h +# OBSOLETE +# OBSOLETE NAT_FILE= nm-riscos.h +# OBSOLETE NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o mips-nat.o +# OBSOLETE +# OBSOLETE MH_CFLAGS=-Wf,-XNh10000 +# OBSOLETE +# OBSOLETE # ptrace(2) apparently has problems in the BSD environment. No workaround is +# OBSOLETE # known except to select the sysv environment. Could we use /proc instead? +# OBSOLETE # These "sysv environments" and "bsd environments" often end up being a pain. +# OBSOLETE # +# OBSOLETE # This is not part of CFLAGS because perhaps not all C compilers have this +# OBSOLETE # option. +# OBSOLETE CC= cc -systype sysv diff --git a/contrib/gdb/gdb/config/mips/tm-mips.h b/contrib/gdb/gdb/config/mips/tm-mips.h new file mode 100644 index 00000000000..be0d6b75eb1 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/tm-mips.h @@ -0,0 +1,119 @@ +/* Definitions to make GDB run on a mips box under 4.3bsd. + + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. + + Contributed by Per Bothner (bothner@cs.wisc.edu) at U.Wisconsin + and by Alessandro Forin (af@cs.cmu.edu) at CMU.. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_MIPS_H +#define TM_MIPS_H 1 + +#define GDB_MULTI_ARCH 1 + +#include "regcache.h" + +struct frame_info; +struct symbol; +struct type; +struct value; + +#include +#include "coff/sym.h" /* Needed for PDR below. */ +#include "coff/symconst.h" + +/* Return non-zero if PC points to an instruction which will cause a step + to execute both the instruction at PC and an instruction at PC+4. */ +extern int mips_step_skips_delay (CORE_ADDR); +#define STEP_SKIPS_DELAY_P (1) +#define STEP_SKIPS_DELAY(pc) (mips_step_skips_delay (pc)) + +/* Register numbers of various important registers. + Note that some of these values are "real" register numbers, + and correspond to the general registers of the machine, + and some are "phony" register numbers which are too large + to be actual register numbers as far as the user is concerned + but do serve to get the desired values when passed to read_register. */ + +#define ZERO_REGNUM 0 /* read-only register, always 0 */ +#define V0_REGNUM 2 /* Function integer return value */ +#define A0_REGNUM 4 /* Loc of first arg during a subr call */ +#define T9_REGNUM 25 /* Contains address of callee in PIC */ +#define SP_REGNUM 29 /* Contains address of top of stack */ +#define RA_REGNUM 31 /* Contains return address value */ +#define PS_REGNUM 32 /* Contains processor status */ +#define UNUSED_REGNUM 73 /* Never used, FIXME */ +#define FIRST_EMBED_REGNUM 74 /* First CP0 register for embedded use */ +#define PRID_REGNUM 89 /* Processor ID */ +#define LAST_EMBED_REGNUM 89 /* Last one */ + +/* Special symbol found in blocks associated with routines. We can hang + mips_extra_func_info_t's off of this. */ + +#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__" +extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR); + +/* Specific information about a procedure. + This overlays the MIPS's PDR records, + mipsread.c (ab)uses this to save memory */ + +typedef struct mips_extra_func_info + { + long numargs; /* number of args to procedure (was iopt) */ + bfd_vma high_addr; /* upper address bound */ + long frame_adjust; /* offset of FP from SP (used on MIPS16) */ + PDR pdr; /* Procedure descriptor record */ + } + *mips_extra_func_info_t; + +/* It takes two values to specify a frame on the MIPS. + + In fact, the *PC* is the primary value that sets up a frame. The + PC is looked up to see what function it's in; symbol information + from that function tells us which register is the frame pointer + base, and what offset from there is the "virtual frame pointer". + (This is usually an offset from SP.) On most non-MIPS machines, + the primary value is the SP, and the PC, if needed, disambiguates + multiple functions with the same SP. But on the MIPS we can't do + that since the PC is not stored in the same part of the frame every + time. This does not seem to be a very clever way to set up frames, + but there is nothing we can do about that. */ + +#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv) +extern struct frame_info *setup_arbitrary_frame (int, CORE_ADDR *); + +/* These are defined in mdebugread.c and are used in mips-tdep.c */ +extern CORE_ADDR sigtramp_address, sigtramp_end; +extern void fixup_sigtramp (void); + +/* Functions for dealing with MIPS16 call and return stubs. */ +#define IGNORE_HELPER_CALL(pc) mips_ignore_helper (pc) +extern int mips_ignore_helper (CORE_ADDR pc); + +/* Definitions and declarations used by mips-tdep.c and remote-mips.c */ +#define MIPS_INSTLEN 4 /* Length of an instruction */ +#define MIPS16_INSTLEN 2 /* Length of an instruction on MIPS16 */ +#define MIPS_NUMREGS 32 /* Number of integer or float registers */ +typedef unsigned long t_inst; /* Integer big enough to hold an instruction */ + +#endif /* TM_MIPS_H */ + +/* Single step based on where the current instruction will take us. */ +extern void mips_software_single_step (enum target_signal, int); diff --git a/contrib/gdb/gdb/config/mips/tm-mipsv4.h b/contrib/gdb/gdb/config/mips/tm-mipsv4.h new file mode 100644 index 00000000000..94607414f3b --- /dev/null +++ b/contrib/gdb/gdb/config/mips/tm-mipsv4.h @@ -0,0 +1,37 @@ +// OBSOLETE /* Target machine description for MIPS running SVR4, for GDB. +// OBSOLETE Copyright 1994, 1995, 1998, 1999, 2000 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "mips/tm-mips.h" +// OBSOLETE #include "config/tm-sysv4.h" +// OBSOLETE +// OBSOLETE /* The signal handler trampoline is called _sigtramp. */ +// OBSOLETE #undef IN_SIGTRAMP +// OBSOLETE #define IN_SIGTRAMP(pc, name) ((name) && DEPRECATED_STREQ ("_sigtramp", name)) +// OBSOLETE +// OBSOLETE /* On entry to the signal handler trampoline, an ucontext is already +// OBSOLETE pushed on the stack. We can get at the saved registers via the +// OBSOLETE mcontext which is contained within the ucontext. */ +// OBSOLETE #define SIGFRAME_BASE 0 +// OBSOLETE #define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 40) +// OBSOLETE #define SIGFRAME_PC_OFF (SIGFRAME_BASE + 40 + 35 * 4) +// OBSOLETE #define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_BASE + 40 + 36 * 4) +// OBSOLETE +// OBSOLETE /* Convert a DWARF register number to a gdb REGNUM. */ +// OBSOLETE #define DWARF_REG_TO_REGNUM(num) ((num) < 32 ? (num) : (num)+FP0_REGNUM-32) diff --git a/contrib/gdb/gdb/config/mips/tm-nbsd.h b/contrib/gdb/gdb/config/mips/tm-nbsd.h new file mode 100644 index 00000000000..fb30761111c --- /dev/null +++ b/contrib/gdb/gdb/config/mips/tm-nbsd.h @@ -0,0 +1,37 @@ +/* Target-dependent definitions for NetBSD/mips. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_NBSD_H +#define TM_NBSD_H + +#include "mips/tm-mips.h" +#include "solib.h" + +/* We don't want to inherit tm-mips.h's shared library trampoline code. */ +#undef IN_SOLIB_CALL_TRAMPOLINE +#undef IN_SOLIB_RETURN_TRAMPOLINE +#undef SKIP_TRAMPOLINE_CODE +#undef IGNORE_HELPER_CALL + +/* XXX undef a bunch of stuff we want to use multi-arch */ +#undef IN_SIGTRAMP + +#endif /* TM_NBSD_H */ diff --git a/contrib/gdb/gdb/config/mips/tm-vxmips.h b/contrib/gdb/gdb/config/mips/tm-vxmips.h new file mode 100644 index 00000000000..5eb10438303 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/tm-vxmips.h @@ -0,0 +1,23 @@ +/* Target machine description for VxWorks MIPS's, for GDB, the GNU debugger. + Copyright 1996, 1999 Free Software Foundation, Inc. + Contributed by Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "mips/tm-mips.h" +#include "config/tm-vxworks.h" diff --git a/contrib/gdb/gdb/config/mips/tm-wince.h b/contrib/gdb/gdb/config/mips/tm-wince.h new file mode 100644 index 00000000000..3ea179b56e6 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/tm-wince.h @@ -0,0 +1,33 @@ +/* Definitions to make GDB run on a Windows CE system. + + Copyright 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_WINCE_H +#define TM_WINCE_H 1 + +#include "mips/tm-mips.h" + +#undef SOFTWARE_SINGLE_STEP_P +#define SOFTWARE_SINGLE_STEP_P() 1 +#define SOFTWARE_SINGLE_STEP(sig, bp_p) wince_software_single_step (sig, bp_p) + +void wince_software_single_step (unsigned int, int); + +#endif /* TM_WINCE_H */ diff --git a/contrib/gdb/gdb/config/mips/vxmips.mt b/contrib/gdb/gdb/config/mips/vxmips.mt new file mode 100644 index 00000000000..a20cf96ab72 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/vxmips.mt @@ -0,0 +1,3 @@ +# Target: MIPS running VxWorks +TDEPFILES= mips-tdep.o remote-vx.o remote-vxmips.o xdr_ld.o xdr_ptrace.o xdr_rdb.o +TM_FILE= tm-vxmips.h diff --git a/contrib/gdb/gdb/config/mips/wince.mt b/contrib/gdb/gdb/config/mips/wince.mt new file mode 100644 index 00000000000..6aa5733808a --- /dev/null +++ b/contrib/gdb/gdb/config/mips/wince.mt @@ -0,0 +1,5 @@ +# Target: Little-endian MIPS machine such as DECstation. +TDEPFILES= mips-tdep.o wince.o +TM_FILE= tm-wince.h +MT_CFLAGS=-DMIPS -U_X86_ -U_M_IX86 -U__i386__ -U__i486__ -U__i586__ -U__i686__ -DUNICODE -D_WIN32_WCE -DWINCE_STUB='"${target_alias}-stub.exe"' +TM_CLIBS=-lrapi diff --git a/contrib/gdb/gdb/config/mips/xm-mips.h b/contrib/gdb/gdb/config/mips/xm-mips.h new file mode 100644 index 00000000000..bc3aa6e40c4 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/xm-mips.h @@ -0,0 +1,59 @@ +// OBSOLETE /* Definitions to make GDB run on a mips box under 4.3bsd. +// OBSOLETE Copyright 1986, 1987, 1989, 1993, 1994, 1995, 1996, 1998 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin +// OBSOLETE and by Alessandro Forin(af@cs.cmu.edu) at CMU +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #ifdef ultrix +// OBSOLETE /* Needed for DECstation core files. */ +// OBSOLETE #include +// OBSOLETE #define KERNEL_U_ADDR UADDR +// OBSOLETE +// OBSOLETE /* Native Ultrix cc has broken long long support. */ +// OBSOLETE #ifndef __GNUC__ +// OBSOLETE #undef CC_HAS_LONG_LONG +// OBSOLETE #endif +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE #if ! defined (__GNUC__) && ! defined (offsetof) +// OBSOLETE #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Only used for core files on DECstations. +// OBSOLETE First four registers at u.u_ar0 are saved arguments, and +// OBSOLETE there is no r0 saved. Float registers are saved +// OBSOLETE in u_pcb.pcb_fpregs, not relative to u.u_ar0. */ +// OBSOLETE +// OBSOLETE #define REGISTER_U_ADDR(addr, blockend, regno) \ +// OBSOLETE { \ +// OBSOLETE if (regno < FP0_REGNUM) \ +// OBSOLETE addr = blockend + sizeof(int) * (4 + regno - 1); \ +// OBSOLETE else \ +// OBSOLETE addr = offsetof (struct user, u_pcb.pcb_fpregs[0]) + \ +// OBSOLETE sizeof (int) * (regno - FP0_REGNUM); \ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Kernel is a bit tenacious about sharing text segments, disallowing bpts. */ +// OBSOLETE #define ONE_PROCESS_WRITETEXT +// OBSOLETE +// OBSOLETE /* HAVE_SGTTY also works, last we tried. +// OBSOLETE +// OBSOLETE But we have termios, at least as of Ultrix 4.2A, so use it. */ +// OBSOLETE #define HAVE_TERMIOS diff --git a/contrib/gdb/gdb/config/mips/xm-mipsv4.h b/contrib/gdb/gdb/config/mips/xm-mipsv4.h new file mode 100644 index 00000000000..1f39e31ae1d --- /dev/null +++ b/contrib/gdb/gdb/config/mips/xm-mipsv4.h @@ -0,0 +1,22 @@ +// OBSOLETE /* Definitions for MIPS running SVR4 hosting support. +// OBSOLETE +// OBSOLETE Copyright 1994 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "config/xm-sysv4.h" diff --git a/contrib/gdb/gdb/config/mips/xm-riscos.h b/contrib/gdb/gdb/config/mips/xm-riscos.h new file mode 100644 index 00000000000..d8a65334a66 --- /dev/null +++ b/contrib/gdb/gdb/config/mips/xm-riscos.h @@ -0,0 +1,25 @@ +// OBSOLETE /* Copyright 1993, 1994, 1995 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #define HAVE_TERMIO +// OBSOLETE +// OBSOLETE #define USG 1 +// OBSOLETE +// OBSOLETE /* setjmp.h requires uid_t. */ +// OBSOLETE #include diff --git a/contrib/gdb/gdb/config/nm-gnu.h b/contrib/gdb/gdb/config/nm-gnu.h new file mode 100644 index 00000000000..73a41803cf8 --- /dev/null +++ b/contrib/gdb/gdb/config/nm-gnu.h @@ -0,0 +1,43 @@ +/* Common declarations for the GNU Hurd + + Copyright 1995, 1996, 1998, 1999 Free Software Foundation, Inc. + + Written by Miles Bader + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef __NM_GNU_H__ +#define __NM_GNU_H__ + +#include +#include +#include +#include "regcache.h" + +extern char *gnu_target_pid_to_str (int pid); + +/* Before storing, we need to read all the registers. */ +#define CHILD_PREPARE_TO_STORE() deprecated_read_register_bytes (0, NULL, DEPRECATED_REGISTER_BYTES) + +/* Don't do wait_for_inferior on attach. */ +#define ATTACH_NO_WAIT + +/* Use SVR4 style shared library support */ +#define SVR4_SHARED_LIBS +#include "solib.h" +#define NO_CORE_OPS + +#endif /* __NM_GNU_H__ */ diff --git a/contrib/gdb/gdb/config/nm-lynx.h b/contrib/gdb/gdb/config/nm-lynx.h new file mode 100644 index 00000000000..4a55a13c960 --- /dev/null +++ b/contrib/gdb/gdb/config/nm-lynx.h @@ -0,0 +1,86 @@ +/* Native-dependent definitions for LynxOS. + + Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2003 Free Software + Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_LYNX_H +#define NM_LYNX_H + +struct target_waitstatus; + +#include +#include +/* sys/kernel.h should define this, but doesn't always, sigh. */ +#ifndef __LYNXOS +#define __LYNXOS +#endif +#include +#include +#include +#include +#include +#include +#include +#include "gdbthread.h" + +/* This is the amount to subtract from u.u_ar0 to get the offset in + the core file of the register values. */ + +#define KERNEL_U_ADDR USRSTACK + +/* As of LynxOS 2.2.2 (beta 8/15/94), this is int. Previous versions seem to + have had no prototype, so I'm not sure why GDB used to define this to + char *. */ +#define PTRACE_ARG3_TYPE int + +/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ + +#define FETCH_INFERIOR_REGISTERS + +/* Thread ID of stopped thread. */ + +#define WIFTID(x) (((union wait *)&x)->w_tid) + +/* Override child_wait in inftarg.c */ + +#define CHILD_WAIT + +/* Override child_resume in infptrace.c */ + +#define CHILD_RESUME + +/* Override child_thread_alive in intarg.c */ + +#define CHILD_THREAD_ALIVE + +#include "target.h" + +extern ptid_t child_wait (ptid_t ptid, + struct target_waitstatus *status); + +/* Lynx needs a special definition of this so that we can + print out the pid and thread number seperately. */ + + +/* override child_pid_to_str in inftarg.c */ +#define CHILD_PID_TO_STR +extern char *lynx_pid_to_str (ptid_t ptid); + +#endif /* NM_LYNX_H */ diff --git a/contrib/gdb/gdb/config/nm-nbsd.h b/contrib/gdb/gdb/config/nm-nbsd.h new file mode 100644 index 00000000000..5078c567968 --- /dev/null +++ b/contrib/gdb/gdb/config/nm-nbsd.h @@ -0,0 +1,27 @@ +/* Native-dependent definitions for NetBSD. + Copyright 1994, 1996, 1999 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#define PTRACE_ARG3_TYPE char* + +#define FETCH_INFERIOR_REGISTERS + +#define ATTACH_DETACH + +#include "solib.h" /* Support for shared libraries. */ diff --git a/contrib/gdb/gdb/config/nm-nbsdaout.h b/contrib/gdb/gdb/config/nm-nbsdaout.h new file mode 100644 index 00000000000..026f1ed8d50 --- /dev/null +++ b/contrib/gdb/gdb/config/nm-nbsdaout.h @@ -0,0 +1,72 @@ +/* Native-dependent definitions for NetBSD a.out. + Copyright 1994, 1996, 1999 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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 diff --git a/contrib/gdb/gdb/config/nm-sysv4.h b/contrib/gdb/gdb/config/nm-sysv4.h new file mode 100644 index 00000000000..4b4f09897bc --- /dev/null +++ b/contrib/gdb/gdb/config/nm-sysv4.h @@ -0,0 +1,34 @@ +/* Definitions for running gdb on a host machine running any flavor of SVR4. + Copyright 1991, 1992, 1993, 1998 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support (fnf@cygnus.com). + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Use SVR4 style shared library support */ + +#define SVR4_SHARED_LIBS +#include "solib.h" + +/* SVR4 has /proc support, so use it instead of ptrace. */ + +#define USE_PROC_FS + +/* SVR4 machines can easily do attach and detach via /proc (procfs.c) + support */ + +#define ATTACH_DETACH diff --git a/contrib/gdb/gdb/config/powerpc/nbsd.mh b/contrib/gdb/gdb/config/powerpc/nbsd.mh index dcb0f7abb4b..26ba24d9860 100644 --- a/contrib/gdb/gdb/config/powerpc/nbsd.mh +++ b/contrib/gdb/gdb/config/powerpc/nbsd.mh @@ -1,3 +1,3 @@ # Host: PowerPC, running NetBSD -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o ppcnbsd-nat.o solib.o solib-svr4.o solib-legacy.o +NATDEPFILES= fork-child.o infptrace.o inftarg.o ppcnbsd-nat.o NAT_FILE= nm-nbsd.h diff --git a/contrib/gdb/gdb/config/powerpc/nbsd.mt b/contrib/gdb/gdb/config/powerpc/nbsd.mt index 164abfef9ad..d492f9d763c 100644 --- a/contrib/gdb/gdb/config/powerpc/nbsd.mt +++ b/contrib/gdb/gdb/config/powerpc/nbsd.mt @@ -1,8 +1,7 @@ # Target: PowerPC, running NetBSD -TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o solib.o solib-svr4.o +TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o nbsd-tdep.o corelow.o \ + solib.o solib-svr4.o TM_FILE= tm-nbsd.h -## OBSOLETE ## GDBSERVER_DEPFILES= low-nbsd.o - SIM_OBS = remote-sim.o SIM = ../sim/ppc/libsim.a diff --git a/contrib/gdb/gdb/config/powerpc/nm-nbsd.h b/contrib/gdb/gdb/config/powerpc/nm-nbsd.h index 0ff53094e0b..5de6c9a0d21 100644 --- a/contrib/gdb/gdb/config/powerpc/nm-nbsd.h +++ b/contrib/gdb/gdb/config/powerpc/nm-nbsd.h @@ -1,5 +1,5 @@ /* Native-dependent definitions for PowerPC running NetBSD ELF, for GDB. - Copyright 2000 Free Software Foundation, Inc. + Copyright 2000, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -21,9 +21,7 @@ #ifndef NM_NBSD_H #define NM_NBSD_H -#define SVR4_SHARED_LIBS - /* Get generic NetBSD native definitions. */ -#include "nm-nbsd.h" +#include "config/nm-nbsd.h" #endif diff --git a/contrib/gdb/gdb/config/powerpc/ppc-eabi.mt b/contrib/gdb/gdb/config/powerpc/ppc-eabi.mt index 2d4a77fcdef..5ef8cd9befb 100644 --- a/contrib/gdb/gdb/config/powerpc/ppc-eabi.mt +++ b/contrib/gdb/gdb/config/powerpc/ppc-eabi.mt @@ -1,3 +1,3 @@ # Target: PowerPC running eabi -TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o solib.o solib-svr4.o +TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-sysv-tdep.o solib.o solib-svr4.o TM_FILE= tm-ppc-eabi.h diff --git a/contrib/gdb/gdb/config/powerpc/ppc-sim.mt b/contrib/gdb/gdb/config/powerpc/ppc-sim.mt index f2ad1f0b2c4..187bf39e8d5 100644 --- a/contrib/gdb/gdb/config/powerpc/ppc-sim.mt +++ b/contrib/gdb/gdb/config/powerpc/ppc-sim.mt @@ -1,5 +1,5 @@ # Target: PowerPC running eabi and including the simulator -TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o solib.o solib-svr4.o +TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-sysv-tdep.o solib.o solib-svr4.o TM_FILE= tm-ppc-eabi.h SIM_OBS = remote-sim.o diff --git a/contrib/gdb/gdb/config/powerpc/tm-nbsd.h b/contrib/gdb/gdb/config/powerpc/tm-nbsd.h index ae3418f4fdb..d167830523c 100644 --- a/contrib/gdb/gdb/config/powerpc/tm-nbsd.h +++ b/contrib/gdb/gdb/config/powerpc/tm-nbsd.h @@ -1,5 +1,5 @@ /* Macro definitions for PowerPC running under NetBSD. - Copyright 2000 Free Software Foundation, Inc. + Copyright 2000, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -22,6 +22,5 @@ #define TM_NBSD_H #include "powerpc/tm-ppc-eabi.h" -#include "tm-nbsd.h" #endif /* TM_NBSD_H */ diff --git a/contrib/gdb/gdb/config/powerpc/tm-ppc-eabi.h b/contrib/gdb/gdb/config/powerpc/tm-ppc-eabi.h index 92e41271fc1..d29b05ddcd0 100644 --- a/contrib/gdb/gdb/config/powerpc/tm-ppc-eabi.h +++ b/contrib/gdb/gdb/config/powerpc/tm-ppc-eabi.h @@ -24,21 +24,12 @@ /* Use generic RS6000 definitions. */ #include "rs6000/tm-rs6000.h" -/* except we want to allow single stepping */ -#undef SOFTWARE_SINGLE_STEP_P -#define SOFTWARE_SINGLE_STEP_P() 0 - -#undef DEFAULT_LR_SAVE -#define DEFAULT_LR_SAVE 4 /* eabi saves LR at 4 off of SP */ #undef PROCESS_LINENUMBER_HOOK #undef TEXT_SEGMENT_BASE #define TEXT_SEGMENT_BASE 1 -/* Say that we're using ELF, not XCOFF. */ -#define ELF_OBJECT_FORMAT 1 - /* The value of symbols of type N_SO and N_FUN maybe null when it shouldn't be. */ #define SOFUN_ADDRESS_MAYBE_MISSING diff --git a/contrib/gdb/gdb/config/powerpc/tm-vxworks.h b/contrib/gdb/gdb/config/powerpc/tm-vxworks.h index a31846a802f..69e2ddec3b0 100644 --- a/contrib/gdb/gdb/config/powerpc/tm-vxworks.h +++ b/contrib/gdb/gdb/config/powerpc/tm-vxworks.h @@ -23,6 +23,6 @@ #define TM_VXWORKS_H #include "powerpc/tm-ppc-eabi.h" -#include "tm-vxworks.h" +#include "config/tm-vxworks.h" #endif /* ifndef TM_VXWORKS_H */ diff --git a/contrib/gdb/gdb/config/powerpc/vxworks.mt b/contrib/gdb/gdb/config/powerpc/vxworks.mt index ba6e17bcb1c..eca028f80aa 100644 --- a/contrib/gdb/gdb/config/powerpc/vxworks.mt +++ b/contrib/gdb/gdb/config/powerpc/vxworks.mt @@ -1,3 +1,3 @@ # Target: Powerpc running VxWorks -TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o solib.o solib-svr4.o +TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o solib.o solib-svr4.o TM_FILE= tm-vxworks.h diff --git a/contrib/gdb/gdb/config/s390/s390.mh b/contrib/gdb/gdb/config/s390/s390.mh new file mode 100644 index 00000000000..3db7bd91f99 --- /dev/null +++ b/contrib/gdb/gdb/config/s390/s390.mh @@ -0,0 +1,5 @@ +# Host: S390, running Linux +NAT_FILE= nm-linux.h +NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o s390-nat.o \ + linux-proc.o gcore.o thread-db.o lin-lwp.o proc-service.o linux-nat.o +LOADLIBES = -ldl -rdynamic diff --git a/contrib/gdb/gdb/config/s390/s390.mt b/contrib/gdb/gdb/config/s390/s390.mt new file mode 100644 index 00000000000..86b6a3371cc --- /dev/null +++ b/contrib/gdb/gdb/config/s390/s390.mt @@ -0,0 +1,5 @@ +# Target: S390 running Linux +TM_FILE= tm-linux.h +TDEPFILES=s390-tdep.o solib.o +# Post 5.0 tdep-files +TDEPFILES+=solib-svr4.o solib-legacy.o diff --git a/contrib/gdb/gdb/config/sparc/fbsd.mh b/contrib/gdb/gdb/config/sparc/fbsd.mh index 33c6dc7d7a1..fb491a55c47 100644 --- a/contrib/gdb/gdb/config/sparc/fbsd.mh +++ b/contrib/gdb/gdb/config/sparc/fbsd.mh @@ -1,25 +1,5 @@ -# Host-dependent settings for FreeBSD/sparc64. -# Copyright 2002 Free Software Foundation, Inc. -# Contributed by David E. O'Brien . -# -# This file is part of GDB. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - # Host: FreeBSD/sparc64 -NATDEPFILES= sparc-nat.o \ - corelow.o fork-child.o infptrace.o inftarg.o \ +NATDEPFILES= sparc64fbsd-nat.o sparc64-nat.o sparc-nat.o \ + fork-child.o infptrace.o inftarg.o \ solib.o solib-svr4.o solib-legacy.o NAT_FILE= nm-fbsd.h diff --git a/contrib/gdb/gdb/config/sparc/fbsd.mt b/contrib/gdb/gdb/config/sparc/fbsd.mt index 317c290f9c4..8e4dead7add 100644 --- a/contrib/gdb/gdb/config/sparc/fbsd.mt +++ b/contrib/gdb/gdb/config/sparc/fbsd.mt @@ -1,23 +1,3 @@ -# Target-dependent settings for FreeBSD/sparc64. -# Copyright 2002 Free Software Foundation, Inc. -# Contributed by David E. O'Brien . -# -# This file is part of GDB. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - # Target: FreeBSD/sparc64 -TDEPFILES= sparc-tdep.o solib.o solib-svr4.o solib-legacy.o +TDEPFILES= sparc-tdep.o sparc64-tdep.o sparc64fbsd-tdep.o corelow.o TM_FILE= tm-fbsd.h diff --git a/contrib/gdb/gdb/config/sparc/nbsd.mt b/contrib/gdb/gdb/config/sparc/nbsd.mt index 5c89318bfe9..25dbefff703 100644 --- a/contrib/gdb/gdb/config/sparc/nbsd.mt +++ b/contrib/gdb/gdb/config/sparc/nbsd.mt @@ -1,3 +1,4 @@ -# Target: Sun 4 or Sparcstation, running NetBSD -TDEPFILES= sparc-tdep.o +# Target: NetBSD/sparc +TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o \ + corelow.o solib.o solib-svr4.o TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/sparc/nbsd64.mh b/contrib/gdb/gdb/config/sparc/nbsd64.mh new file mode 100644 index 00000000000..e8ac58bda2b --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/nbsd64.mh @@ -0,0 +1,4 @@ +# Host: NetBSD/sparc64 +NATDEPFILES= sparc64nbsd-nat.o sparc-nat.o \ + fork-child.o infptrace.o inftarg.o +NAT_FILE= nm-nbsd.h diff --git a/contrib/gdb/gdb/config/sparc/nbsd64.mt b/contrib/gdb/gdb/config/sparc/nbsd64.mt new file mode 100644 index 00000000000..4a1b13b9bb6 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/nbsd64.mt @@ -0,0 +1,5 @@ +# Target: NetBSD/sparc64 +TDEPFILES= sparc64-tdep.o sparc64nbsd-tdep.o \ + sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o \ + corelow.o solib.o solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/sparc/nbsdaout.mh b/contrib/gdb/gdb/config/sparc/nbsdaout.mh new file mode 100644 index 00000000000..8944e60e483 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/nbsdaout.mh @@ -0,0 +1,4 @@ +# Host: NetBSD/sparc a.out +NATDEPFILES= sparc-nat.o sparcnbsd-nat.o \ + fork-child.o infptrace.o inftarg.o solib-sunos.o +NAT_FILE= nm-nbsdaout.h diff --git a/contrib/gdb/gdb/config/sparc/nbsdelf.mh b/contrib/gdb/gdb/config/sparc/nbsdelf.mh index 7c5a123ba1e..45309ecaec0 100644 --- a/contrib/gdb/gdb/config/sparc/nbsdelf.mh +++ b/contrib/gdb/gdb/config/sparc/nbsdelf.mh @@ -1,5 +1,4 @@ -# Host: Sun 4 or Sparcstation, running NetBSD -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o solib.o solib-svr4.o solib-legacy.o -XM_FILE= xm-nbsd.h -NAT_FILE= nm-nbsdelf.h -HOST_IPC=-DBSD_IPC +# Host: NetBSD/sparc ELF +NATDEPFILES= sparc-nat.o sparcnbsd-nat.o \ + fork-child.o infptrace.o inftarg.o +NAT_FILE= nm-nbsd.h diff --git a/contrib/gdb/gdb/config/sparc/nm-fbsd.h b/contrib/gdb/gdb/config/sparc/nm-fbsd.h index 87b9622348c..917cc49bf07 100644 --- a/contrib/gdb/gdb/config/sparc/nm-fbsd.h +++ b/contrib/gdb/gdb/config/sparc/nm-fbsd.h @@ -1,6 +1,6 @@ /* Native-dependent definitions for FreeBSD/sparc64. - Copyright 2002 - Free Software Foundation, Inc. + + Copyright 2002, 2003 Free Software Foundation, Inc. Contributed by David E. O'Brien . This file is part of GDB. @@ -34,34 +34,6 @@ /* Shared library support. */ -#define SVR4_SHARED_LIBS +#include "solib.h" -#include "solib.h" /* Support for shared libraries. */ -#include "elf/common.h" /* Additional ELF shared library info. */ - -/* Make things match up with what is expected in sparc-nat.c. */ - -#define PTRACE_GETREGS PT_GETREGS -#define PTRACE_SETREGS PT_SETREGS -#define PTRACE_GETFPREGS PT_GETFPREGS -#define PTRACE_SETFPREGS PT_SETFPREGS - -#define GDB_GREGSET_T struct reg -#define GDB_FPREGSET_T struct fpreg - -#define regs trapframe -#define r_g1 tf_global[1] -#define r_ps tf_tstate -#define r_pc tf_tpc -#define r_npc tf_tnpc -#define r_y tf_y - -#define FPU_FSR_TYPE unsigned long -#define fp_status fpreg /* our reg.h */ -#define fpu fpreg /* our reg.h */ -#define fpu_regs fr_regs /* one field of fpu_fr on Solaris */ -#define fpu_fr fr_regs /* a union w/in struct fpu on Solaris */ -#define fpu_fsr fr_fsr -#define Fpu_fsr fr_fsr - -#endif /* NM_FBSD_H */ +#endif /* nm-fbsd.h */ diff --git a/contrib/gdb/gdb/config/sparc/nm-nbsd.h b/contrib/gdb/gdb/config/sparc/nm-nbsd.h index 653be852d85..c64f505c63d 100644 --- a/contrib/gdb/gdb/config/sparc/nm-nbsd.h +++ b/contrib/gdb/gdb/config/sparc/nm-nbsd.h @@ -1,6 +1,7 @@ -/* Native-dependent definitions for Sparc running NetBSD, for GDB. - Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1999, 2000 - Free Software Foundation, Inc. +/* Native-dependent definitions for NetBSD/sparc. + + Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1999, 2000, 2002, + 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -22,40 +23,20 @@ #ifndef NM_NBSD_H #define NM_NBSD_H -#include "regcache.h" - -/* Get generic NetBSD native definitions. */ - +/* Get generic NetBSD native definitions. */ #include "config/nm-nbsd.h" + -/* Before storing, we need to read all the registers. */ +/* Support for StackGhost cookies. */ -#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES) +#include "target.h" +struct target_ops; /* Fool ARI. */ -/* Make things match up with what is expected in sparc-nat.c. */ +#define NATIVE_XFER_WCOOKIE sparc_xfer_wcookie +extern LONGEST sparc_xfer_wcookie (struct target_ops *ops, + enum target_object object, + const char *annex, + void *readbuf, const void *writebuf, + ULONGEST offset, LONGEST len); -#define regs trapframe -#define fp_status fpstate - -#define r_g1 tf_global[1] -#define r_ps tf_psr -#define r_pc tf_pc -#define r_npc tf_npc -#define r_y tf_y - -#define fpu fpstate -#define fpu_regs fs_regs -#define fpu_fsr fs_fsr -#define fpu_fr fs_regs -#define Fpu_fsr fs_fsr -#define FPU_FSR_TYPE int - -#define PTRACE_GETREGS PT_GETREGS -#define PTRACE_GETFPREGS PT_GETFPREGS -#define PTRACE_SETREGS PT_SETREGS -#define PTRACE_SETFPREGS PT_SETFPREGS - -#define GDB_GREGSET_T struct reg -#define GDB_FPREGSET_T struct fpreg - -#endif /* NM_NBSD_H */ +#endif /* nm-nbsd.h */ diff --git a/contrib/gdb/gdb/config/sparc/nm-nbsdaout.h b/contrib/gdb/gdb/config/sparc/nm-nbsdaout.h new file mode 100644 index 00000000000..9e463f9b503 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/nm-nbsdaout.h @@ -0,0 +1,30 @@ +/* Native-dependent definitions for NetBSD/sparc a.out. + + Copyright 1999, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NM_NBSDAOUT_H +#define NM_NBSDAOUT_H + +#include "sparc/nm-nbsd.h" + +/* Get generic NetBSD a.out native definitions. */ +#include "config/nm-nbsdaout.h" + +#endif /* nm-nbsdaout.h */ diff --git a/contrib/gdb/gdb/config/sparc/nm-sol2.h b/contrib/gdb/gdb/config/sparc/nm-sol2.h new file mode 100644 index 00000000000..bc9de3fdf80 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/nm-sol2.h @@ -0,0 +1,65 @@ +/* Native-dependent definitions for Solaris SPARC. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef NM_SOL2_H +#define NM_SOL2_H + +#define GDB_GREGSET_T prgregset_t +#define GDB_FPREGSET_T prfpregset_t + +/* Shared library support. */ + +#include "solib.h" + +/* Hardware wactchpoints. */ + +/* Solaris 2.6 and above can do HW watchpoints. */ +#ifdef NEW_PROC_API + +#define TARGET_HAS_HARDWARE_WATCHPOINTS + +/* The man page for proc(4) on Solaris 2.6 and up says that the system + can support "thousands" of hardware watchpoints, but gives no + method for finding out how many; It doesn't say anything about the + allowed size for the watched area either. So we just tell GDB + 'yes'. */ +#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(SIZE) 1 + +/* When a hardware watchpoint fires off the PC will be left at the + instruction following the one which caused the watchpoint. It will + *NOT* be necessary for GDB to step over the watchpoint. */ +#define HAVE_CONTINUABLE_WATCHPOINT 1 + +extern int procfs_stopped_by_watchpoint (ptid_t); +#define STOPPED_BY_WATCHPOINT(W) \ + procfs_stopped_by_watchpoint(inferior_ptid) + +/* Use these macros for watchpoint insertion/deletion. TYPE can be 0 + (write watch), 1 (read watch), 2 (access watch (read/write). */ + +extern int procfs_set_watchpoint (ptid_t, CORE_ADDR, int, int, int); +#define target_insert_watchpoint(ADDR, LEN, TYPE) \ + procfs_set_watchpoint (inferior_ptid, ADDR, LEN, TYPE, 1) +#define target_remove_watchpoint(ADDR, LEN, TYPE) \ + procfs_set_watchpoint (inferior_ptid, ADDR, 0, 0, 0) + +#endif /* NEW_PROC_API */ + +#endif /* nm-sol2.h */ diff --git a/contrib/gdb/gdb/config/sparc/obsd.mt b/contrib/gdb/gdb/config/sparc/obsd.mt new file mode 100644 index 00000000000..800cb048eac --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/obsd.mt @@ -0,0 +1,4 @@ +# Target: OpenBSD/sparc +TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o sparcobsd-tdep.o nbsd-tdep.o \ + corelow.o solib.o solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/sparc/obsd64.mt b/contrib/gdb/gdb/config/sparc/obsd64.mt new file mode 100644 index 00000000000..a69281754c4 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/obsd64.mt @@ -0,0 +1,5 @@ +# Target: OpenBSD/sparc64 +TDEPFILES= sparc64-tdep.o sparc64nbsd-tdep.o sparc64obsd-tdep.o \ + sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o \ + corelow.o solib.o solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/contrib/gdb/gdb/config/sparc/sol2-64.mt b/contrib/gdb/gdb/config/sparc/sol2-64.mt new file mode 100644 index 00000000000..92f848929fe --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/sol2-64.mt @@ -0,0 +1,3 @@ +# Target: Solaris UltraSPARC +TDEPFILES= sparc64-tdep.o sparc64-sol2-tdep.o sparc-tdep.o sparc-sol2-tdep.o +TM_FILE= tm-sol2.h diff --git a/contrib/gdb/gdb/config/sparc/sol2.mh b/contrib/gdb/gdb/config/sparc/sol2.mh new file mode 100644 index 00000000000..735b9ee8096 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/sol2.mh @@ -0,0 +1,6 @@ +# Host: Solaris SPARC & UltraSPARC +NAT_FILE= nm-sol2.h +NATDEPFILES= sparc-sol2-nat.o \ + corelow.o core-regset.o fork-child.o gcore.o \ + procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o \ + solib.o solib-svr4.o solib-legacy.o diff --git a/contrib/gdb/gdb/config/sparc/sol2.mt b/contrib/gdb/gdb/config/sparc/sol2.mt new file mode 100644 index 00000000000..4037956317c --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/sol2.mt @@ -0,0 +1,3 @@ +# Target: Solaris SPARC +TDEPFILES= sparc-tdep.o sparc-sol2-tdep.o +TM_FILE= tm-sol2.h diff --git a/contrib/gdb/gdb/config/sparc/sparc.mt b/contrib/gdb/gdb/config/sparc/sparc.mt new file mode 100644 index 00000000000..ea78c97af55 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/sparc.mt @@ -0,0 +1,2 @@ +# Target: SPARC +TDEPFILES= sparc-tdep.o diff --git a/contrib/gdb/gdb/config/sparc/sparc64.mt b/contrib/gdb/gdb/config/sparc/sparc64.mt new file mode 100644 index 00000000000..b1082be4956 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/sparc64.mt @@ -0,0 +1,2 @@ +# Target: UltraSPARC +TDEPFILES= sparc-tdep.o sparc64-tdep.o diff --git a/contrib/gdb/gdb/config/sparc/tm-fbsd.h b/contrib/gdb/gdb/config/sparc/tm-fbsd.h index c84dfc4075b..f441937668a 100644 --- a/contrib/gdb/gdb/config/sparc/tm-fbsd.h +++ b/contrib/gdb/gdb/config/sparc/tm-fbsd.h @@ -1,5 +1,6 @@ /* Target-dependent definitions for FreeBSD/sparc64. - Copyright 2002 Free Software Foundation, Inc. + + Copyright 2002, 2003 Free Software Foundation, Inc. Contributed by David E. O'Brien . This file is part of GDB. @@ -21,14 +22,6 @@ #ifndef TM_FBSD_H #define TM_FBSD_H -#define SVR4_SHARED_LIBS -#include "solib.h" /* Support for shared libraries. */ -#include "sparc/tm-sp64.h" +#define GDB_MULTI_ARCH GDB_MULTI_ARCH_TM -/* Number of traps that happen between exec'ing the shell to run an - inferior, and when we finally get to the inferior code. The - default is right for FreeBSD. */ - -#undef START_INFERIOR_TRAPS_EXPECTED - -#endif /* TM_FBSD_H */ +#endif /* tm-fbsd.h */ diff --git a/contrib/gdb/gdb/config/sparc/tm-nbsd.h b/contrib/gdb/gdb/config/sparc/tm-nbsd.h index b434efe8dbd..301136bbead 100644 --- a/contrib/gdb/gdb/config/sparc/tm-nbsd.h +++ b/contrib/gdb/gdb/config/sparc/tm-nbsd.h @@ -1,5 +1,6 @@ -/* Macro definitions for Sparc running under NetBSD. - Copyright 1994 Free Software Foundation, Inc. +/* Target-dependent definitions for NetBSD/sparc. + + Copyright 1994, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -21,8 +22,9 @@ #ifndef TM_NBSD_H #define TM_NBSD_H -#include "sparc/tm-sparc.h" +#define GDB_MULTI_ARCH GDB_MULTI_ARCH_TM -#include "tm-nbsd.h" +/* Shared library support. */ +#include "solib.h" -#endif /* TM_NBSD_H */ +#endif /* tm-nbsd.h */ diff --git a/contrib/gdb/gdb/config/sparc/tm-nbsd64.h b/contrib/gdb/gdb/config/sparc/tm-nbsd64.h new file mode 100644 index 00000000000..cc1d6b32297 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/tm-nbsd64.h @@ -0,0 +1,27 @@ +/* Macro definitions for UltraSPARC running under NetBSD. + Copyright 1994, 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_NBSD64_H +#define TM_NBSD64_H + +#include "sparc/tm-sp64.h" /* sets GDB_MULTI_ARCH */ +#include "solib.h" + +#endif /* TM_NBSD64_H */ diff --git a/contrib/gdb/gdb/config/sparc/tm-sol2.h b/contrib/gdb/gdb/config/sparc/tm-sol2.h new file mode 100644 index 00000000000..d111c1a7768 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/tm-sol2.h @@ -0,0 +1,40 @@ +/* Target-dependent definitions for Solaris SPARC. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef TM_SOL2_H +#define TM_SOL2_H + +#define GDB_MULTI_ARCH GDB_MULTI_ARCH_TM + +/* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop, + SunPRO) compiler puts out 0 instead of the address in N_SO stabs. + Starting with SunPRO 3.0, the compiler does this for N_FUN stabs + too. */ +#define SOFUN_ADDRESS_MAYBE_MISSING + +/* The Sun compilers also do "globalization"; see the comment in + sparc-tdep.c for more information. */ +extern char *sparc_stabs_unglobalize_name (char *name); +#define STATIC_TRANSFORM_NAME(name) \ + sparc_stabs_unglobalize_name (name) +#define IS_STATIC_TRANSFORM_NAME(name) \ + ((name) != sparc_stabs_unglobalize_name (name)) + +#endif /* tm-sol2.h */ diff --git a/contrib/gdb/gdb/config/sparc/tm-vxworks.h b/contrib/gdb/gdb/config/sparc/tm-vxworks.h new file mode 100644 index 00000000000..7b0474847c6 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/tm-vxworks.h @@ -0,0 +1,31 @@ +/* Target-dependent defenitions for VxWorks SPARC. + + Copyright 1993, 1999, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_VXWORKS_H +#define TM_VXWORKS_H + +#define GDB_MULTI_ARCH GDB_MULTI_ARCH_TM + +/* Get generic VxWorks definitions. */ +#include "config/tm-vxworks.h" + +#endif /* tm-vxworks.h */ diff --git a/contrib/gdb/gdb/config/sparc/vxworks.mt b/contrib/gdb/gdb/config/sparc/vxworks.mt new file mode 100644 index 00000000000..175f92ed981 --- /dev/null +++ b/contrib/gdb/gdb/config/sparc/vxworks.mt @@ -0,0 +1,4 @@ +# Target: VxWorks SPARC +TDEPFILES= sparc-tdep.o \ + remote-vx.o remote-vxsparc.o xdr_ld.o xdr_ptrace.o xdr_rdb.o +TM_FILE= tm-vxworks.h diff --git a/contrib/gdb/gdb/config/tm-lynx.h b/contrib/gdb/gdb/config/tm-lynx.h new file mode 100644 index 00000000000..7fbc06f01b3 --- /dev/null +++ b/contrib/gdb/gdb/config/tm-lynx.h @@ -0,0 +1,32 @@ +/* Macro definitions for LynxOS targets. + Copyright 1993, 1995 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TM_LYNX_H +#define TM_LYNX_H + +#include "coff-solib.h" /* COFF shared library support */ + +/* Lynx's signal.h doesn't seem to have any macros for what signal numbers + the real-time events are. */ +#define REALTIME_LO 33 +/* One more than the last one. */ +#define REALTIME_HI 64 + +#endif /* TM_LYNX_H */ diff --git a/contrib/gdb/gdb/config/tm-nto.h b/contrib/gdb/gdb/config/tm-nto.h new file mode 100755 index 00000000000..359ff068b7a --- /dev/null +++ b/contrib/gdb/gdb/config/tm-nto.h @@ -0,0 +1,61 @@ +/* Target machine sub-description for QNX Neutrino version 6. + This is included by other tm-*.h files to specify nto specific + stuff. + + Copyright 2003 Free Software Foundation, Inc. + + This code was donated by QNX Software Systems Ltd. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _TM_QNXNTO_H +#define _TM_QNXNTO_H + +#include "tm-sysv4.h" + +/* Setup the valid realtime signal range. */ +#define REALTIME_LO 41 +#define REALTIME_HI 56 + +/* Set up the undefined useable signals. */ +#define RAW_SIGNAL_LO 32 +#define RAW_SIGNAL_HI (REALTIME_LO - 1) + +#define TARGET_SIGNAL_RAW_VALUES \ +TARGET_SIGNAL_RAW0, \ +TARGET_SIGNAL_RAW1, \ +TARGET_SIGNAL_RAW2, \ +TARGET_SIGNAL_RAW3, \ +TARGET_SIGNAL_RAW4, \ +TARGET_SIGNAL_RAW5, \ +TARGET_SIGNAL_RAW6, \ +TARGET_SIGNAL_RAW7, \ +TARGET_SIGNAL_RAW8 + +#define TARGET_SIGNAL_RAW_TABLE \ +{"SIGNAL32", "Signal 32"}, \ +{"SIGNAL33", "Signal 33"}, \ +{"SIGNAL34", "Signal 34"}, \ +{"SIGNAL35", "Signal 35"}, \ +{"SIGNAL36", "Signal 36"}, \ +{"SIGNAL37", "Signal 37"}, \ +{"SIGNAL38", "Signal 38"}, \ +{"SIGNAL39", "Signal 39"}, \ +{"SIGNAL40", "Signal 40"} + +#endif /* _TM_QNXNTO_H */ diff --git a/contrib/gdb/gdb/config/tm-sunos.h b/contrib/gdb/gdb/config/tm-sunos.h new file mode 100644 index 00000000000..c8db07e865e --- /dev/null +++ b/contrib/gdb/gdb/config/tm-sunos.h @@ -0,0 +1,32 @@ +/* Target machine sub-description for SunOS version 4. + This is included by other tm-*.h files to specify SunOS-specific stuff. + Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "solib.h" /* Support for shared libraries. */ + +/* Return non-zero if we are in a shared library trampoline code stub. */ + +#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \ + lookup_solib_trampoline_symbol_by_pc (pc) + +/* If PC is in a shared library trampoline code, return the PC + where the function itself actually starts. If not, return 0. */ + +#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc) diff --git a/contrib/gdb/gdb/config/tm-sysv4.h b/contrib/gdb/gdb/config/tm-sysv4.h new file mode 100644 index 00000000000..9a39af20d83 --- /dev/null +++ b/contrib/gdb/gdb/config/tm-sysv4.h @@ -0,0 +1,37 @@ +/* Macro definitions for GDB on all SVR4 target systems. + Copyright 1991, 1992, 1993, 1994, 1996, 1997, 2000 + Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support (fnf@cygnus.com). + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* For SVR4 shared libraries, each call to a library routine goes through + a small piece of trampoline code in the ".plt" section. + The horribly ugly wait_for_inferior() routine uses this macro to detect + when we have stepped into one of these fragments. + We do not use lookup_solib_trampoline_symbol_by_pc, because + we cannot always find the shared library trampoline symbols + (e.g. on Irix5). */ + +#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) in_plt_section((pc), (name)) +extern int in_plt_section (CORE_ADDR, char *); + +/* If PC is in a shared library trampoline code, return the PC + where the function itself actually starts. If not, return 0. */ + +#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc) diff --git a/contrib/gdb/gdb/config/xm-nbsd.h b/contrib/gdb/gdb/config/xm-nbsd.h new file mode 100644 index 00000000000..c8d00f6dd63 --- /dev/null +++ b/contrib/gdb/gdb/config/xm-nbsd.h @@ -0,0 +1,26 @@ +/* Host-dependent definitions for any CPU running NetBSD. + Copyright 1993, 1994, 1995, 1996, 1999 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Include this to get things like NGROUPS which doesn't + define on some systems. */ +#include + +/* NetBSD has termios facilities. */ +#define HAVE_TERMIOS diff --git a/contrib/gdb/gdb/config/xm-sysv4.h b/contrib/gdb/gdb/config/xm-sysv4.h new file mode 100644 index 00000000000..614d4032772 --- /dev/null +++ b/contrib/gdb/gdb/config/xm-sysv4.h @@ -0,0 +1,29 @@ +/* Definitions for running gdb on a host machine running any flavor of SVR4. + Copyright 1991, 1992, 1993, 1995, 1998 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support (fnf@cygnus.com). + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* SVR4 has termios facilities. */ + +#undef HAVE_TERMIO +#define HAVE_TERMIOS + +/* SVR4 is a derivative of System V Release 3 (USG) */ + +#define USG diff --git a/contrib/gdb/gdb/core-regset.c b/contrib/gdb/gdb/core-regset.c index 16cfde5be66..0600837e1a0 100644 --- a/contrib/gdb/gdb/core-regset.c +++ b/contrib/gdb/gdb/core-regset.c @@ -1,5 +1,6 @@ /* Machine independent GDB support for core files on systems using "regsets". - Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000 + + Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -19,66 +20,43 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* N O T E S - - This file is used by most systems that implement /proc. For these systems, - the general registers are laid out the same way in both the core file and - the gregset_p structure. The current exception to this is Irix-4.*, where - the gregset_p structure is split up into two pieces in the core file. - - The general register and floating point register sets are manipulated by - separate ioctl's. This file makes the assumption that if FP0_REGNUM is - defined, then support for the floating point register set is desired, - regardless of whether or not the actual target has floating point hardware. - - */ +/* This file is used by most systems that use ELF for their core + dumps. This includes most systems that have SVR4-ish variant of + /proc. For these systems, the registers are laid out the same way + in core files as in the gregset_t and fpregset_t structures that + are used in the interaction with /proc (Irix 4 is an exception and + therefore doesn't use this file). Quite a few systems without a + SVR4-ish /proc define these structures too, and can make use of + this code too. */ #include "defs.h" +#include "command.h" +#include "gdbcore.h" +#include "inferior.h" +#include "target.h" +#include +#include +#include "gdb_string.h" #include #ifdef HAVE_SYS_PROCFS_H #include #endif -#include -#include -#include "gdb_string.h" -#include "inferior.h" -#include "target.h" -#include "command.h" -#include "gdbcore.h" - -/* Prototypes for supply_gregset etc. */ +/* Prototypes for supply_gregset etc. */ #include "gregset.h" -static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); +/* Provide registers to GDB from a core file. -void _initialize_core_regset (void); + CORE_REG_SECT points to an array of bytes, which are the contents + of a `note' from a core file which BFD thinks might contain + register contents. CORE_REG_SIZE is its size. -/* + WHICH says which register set corelow suspects this is: + 0 --- the general-purpose register set, in gregset_t format + 2 --- the floating-point register set, in fpregset_t format - GLOBAL FUNCTION - - fetch_core_registers -- fetch current registers from core file - - SYNOPSIS - - void fetch_core_registers (char *core_reg_sect, - unsigned core_reg_size, - int which, CORE_ADDR reg_addr) - - DESCRIPTION - - Read the values of either the general register set (WHICH equals 0) - or the floating point register set (WHICH equals 2) from the core - file data (pointed to by CORE_REG_SECT), and update gdb's idea of - their current values. The CORE_REG_SIZE parameter is compared to - the size of the gregset or fpgregset structures (as appropriate) to - validate the size of the structure from the core file. The - REG_ADDR parameter is ignored. - - */ + REG_ADDR is ignored. */ static void fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, @@ -87,36 +65,40 @@ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, gdb_gregset_t gregset; gdb_fpregset_t fpregset; - if (which == 0) + switch (which) { + case 0: if (core_reg_size != sizeof (gregset)) - { - warning ("wrong size gregset struct in core file"); - } + warning ("Wrong size gregset in core file."); else { - memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset)); + memcpy (&gregset, core_reg_sect, sizeof (gregset)); supply_gregset (&gregset); } - } - else if (which == 2) - { + break; + + case 2: if (core_reg_size != sizeof (fpregset)) - { - warning ("wrong size fpregset struct in core file"); - } + warning ("Wrong size fpregset in core file."); else { - memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset)); + memcpy (&fpregset, core_reg_sect, sizeof (fpregset)); if (FP0_REGNUM >= 0) supply_fpregset (&fpregset); } + break; + + default: + /* We've covered all the kinds of registers we know about here, + so this must be something we wouldn't know what to do with + anyway. Just ignore it. */ + break; } } -/* Register that we are able to handle ELF file formats using standard - procfs "regset" structures. */ +/* Register that we are able to handle ELF core file formats using + standard procfs "regset" structures. */ static struct core_fns regset_core_fns = { @@ -127,6 +109,9 @@ static struct core_fns regset_core_fns = NULL /* next */ }; +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern void _initialize_core_regset (void); + void _initialize_core_regset (void) { diff --git a/contrib/gdb/gdb/corefile.c b/contrib/gdb/gdb/corefile.c index 7acbd6eb567..572b4486cd4 100644 --- a/contrib/gdb/gdb/corefile.c +++ b/contrib/gdb/gdb/corefile.c @@ -1,7 +1,7 @@ /* Core dump and executable file functions above target vector, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1996, 1997, 1998, - 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1996, 1997, + 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -238,29 +238,10 @@ read_memory (CORE_ADDR memaddr, char *myaddr, int len) memory_error (status, memaddr); } -/* Like target_read_memory, but slightly different parameters. */ -int -dis_asm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int len, - disassemble_info *info) -{ - return target_read_memory (memaddr, (char *) myaddr, len); -} - -/* Like memory_error with slightly different parameters. */ -void -dis_asm_memory_error (int status, bfd_vma memaddr, disassemble_info *info) -{ - memory_error (status, memaddr); -} - -/* Like print_address with slightly different parameters. */ -void -dis_asm_print_address (bfd_vma addr, struct disassemble_info *info) -{ - print_address (addr, info->stream); -} - -/* Read an integer from debugged memory, given address and number of bytes. */ +/* Argument / return result struct for use with + do_captured_read_memory_integer(). MEMADDR and LEN are filled in + by gdb_read_memory_integer(). RESULT is the contents that were + successfully read from MEMADDR of length LEN. */ struct captured_read_memory_integer_arguments { @@ -269,6 +250,13 @@ struct captured_read_memory_integer_arguments LONGEST result; }; +/* Helper function for gdb_read_memory_integer(). DATA must be a + pointer to a captured_read_memory_integer_arguments struct. + Return 1 if successful. Note that the catch_errors() interface + will return 0 if an error occurred while reading memory. This + choice of return code is so that we can distinguish between + success and failure. */ + static int do_captured_read_memory_integer (void *data) { @@ -278,9 +266,13 @@ do_captured_read_memory_integer (void *data) args->result = read_memory_integer (memaddr, len); - return 0; + return 1; } +/* Read memory at MEMADDR of length LEN and put the contents in + RETURN_VALUE. Return 0 if MEMADDR couldn't be read and non-zero + if successful. */ + int safe_read_memory_integer (CORE_ADDR memaddr, int len, LONGEST *return_value) { @@ -291,7 +283,7 @@ safe_read_memory_integer (CORE_ADDR memaddr, int len, LONGEST *return_value) status = catch_errors (do_captured_read_memory_integer, &args, "", RETURN_MASK_ALL); - if (!status) + if (status) *return_value = args.result; return status; @@ -318,8 +310,8 @@ read_memory_unsigned_integer (CORE_ADDR memaddr, int len) void read_memory_string (CORE_ADDR memaddr, char *buffer, int max_len) { - register char *cp; - register int i; + char *cp; + int i; int cnt; cp = buffer; @@ -342,6 +334,14 @@ read_memory_string (CORE_ADDR memaddr, char *buffer, int max_len) } } +CORE_ADDR +read_memory_typed_address (CORE_ADDR addr, struct type *type) +{ + char *buf = alloca (TYPE_LENGTH (type)); + read_memory (addr, buf, TYPE_LENGTH (type)); + return extract_typed_address (buf, type); +} + /* Same as target_write_memory, but report an error if can't write. */ void write_memory (CORE_ADDR memaddr, char *myaddr, int len) @@ -417,7 +417,7 @@ static void set_gnutarget_command (char *, int, struct cmd_list_element *); static void set_gnutarget_command (char *ignore, int from_tty, struct cmd_list_element *c) { - if (STREQ (gnutarget_string, "auto")) + if (strcmp (gnutarget_string, "auto") == 0) gnutarget = NULL; else gnutarget = gnutarget_string; @@ -441,7 +441,7 @@ _initialize_core (void) "Use FILE as core dump for examining memory and registers.\n\ No arg means have no core file. This command has been superseded by the\n\ `target core' and `detach' commands.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); c = add_set_cmd ("gnutarget", class_files, var_string_noescape, (char *) &gnutarget_string, diff --git a/contrib/gdb/gdb/corelow.c b/contrib/gdb/gdb/corelow.c index 68219c512c6..403cfa31338 100644 --- a/contrib/gdb/gdb/corelow.c +++ b/contrib/gdb/gdb/corelow.c @@ -1,7 +1,8 @@ /* Core dump and executable file functions below target vector, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, + Inc. This file is part of GDB. @@ -21,6 +22,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "arch-utils.h" #include "gdb_string.h" #include #include @@ -37,7 +39,12 @@ #include "gdbcore.h" #include "gdbthread.h" #include "regcache.h" +#include "regset.h" #include "symfile.h" +#include "exec.h" +#include "readline/readline.h" + +#include "gdb_assert.h" #ifndef O_BINARY #define O_BINARY 0 @@ -54,15 +61,20 @@ static struct core_fns *core_file_fns = NULL; static struct core_fns *core_vec = NULL; +/* FIXME: kettenis/20031023: Eventually this variable should + disappear. */ + +struct gdbarch *core_gdbarch = NULL; + static void core_files_info (struct target_ops *); #ifdef SOLIB_ADD -static int solib_add_stub (PTR); +static int solib_add_stub (void *); #endif static struct core_fns *sniff_core_bfd (bfd *); -static boolean gdb_check_format (bfd *); +static int gdb_check_format (bfd *); static void core_open (char *, int); @@ -74,7 +86,7 @@ static void core_close_cleanup (void *ignore); static void get_core_registers (int); -static void add_to_thread_list (bfd *, asection *, PTR); +static void add_to_thread_list (bfd *, asection *, void *); static int ignore (CORE_ADDR, char *); @@ -123,6 +135,10 @@ sniff_core_bfd (bfd *abfd) struct core_fns *yummy = NULL; int matches = 0;; + /* Don't sniff if we have support for register sets in CORE_GDBARCH. */ + if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) + return NULL; + for (cf = core_file_fns; cf != NULL; cf = cf->next) { if (cf->core_sniffer (cf, abfd)) @@ -160,7 +176,7 @@ default_check_format (bfd *abfd) /* Attempt to recognize core file formats that BFD rejects. */ -static boolean +static int gdb_check_format (bfd *abfd) { struct core_fns *cf; @@ -178,7 +194,6 @@ gdb_check_format (bfd *abfd) /* Discard all vestiges of any previous core file and mark data and stack spaces as empty. */ -/* ARGSUSED */ static void core_close (int quitting) { @@ -208,6 +223,7 @@ core_close (int quitting) } } core_vec = NULL; + core_gdbarch = NULL; } static void @@ -221,7 +237,7 @@ core_close_cleanup (void *ignore) is really an int * which points to from_tty. */ static int -solib_add_stub (PTR from_ttyp) +solib_add_stub (void *from_ttyp) { SOLIB_ADD (NULL, *(int *) from_ttyp, ¤t_target, auto_solib_add); re_enable_breakpoints_in_shlibs (); @@ -233,7 +249,7 @@ solib_add_stub (PTR from_ttyp) list of threads in a core file. */ static void -add_to_thread_list (bfd *abfd, asection *asect, PTR reg_sect_arg) +add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg) { int thread_id; asection *reg_sect = (asection *) reg_sect_arg; @@ -310,6 +326,14 @@ core_open (char *filename, int from_tty) core_bfd = temp_bfd; old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); + /* FIXME: kettenis/20031023: This is very dangerous. The + CORE_GDBARCH that results from this call may very well be + different from CURRENT_GDBARCH. However, its methods may only + work if it is selected as the current architecture, because they + rely on swapped data (see gdbarch.c). We should get rid of that + swapped data. */ + core_gdbarch = gdbarch_from_bfd (core_bfd); + /* Find a suitable core file handler to munch on core_bfd */ core_vec = sniff_core_bfd (core_bfd); @@ -321,7 +345,12 @@ core_open (char *filename, int from_tty) error ("\"%s\": Can't find sections: %s", bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); - set_gdbarch_from_file (core_bfd); + /* If we have no exec file, try to set the architecture from the + core file. We don't do this unconditionally since an exec file + typically contains more information that helps us determine the + architecture than a core file. */ + if (!exec_bfd) + set_gdbarch_from_file (core_bfd); ontop = !push_target (&core_ops); discard_cleanups (old_chain); @@ -358,8 +387,9 @@ core_open (char *filename, int from_tty) /* Now, set up the frame cache, and print the top of stack. */ flush_cached_frames (); - select_frame (get_current_frame (), 0); - print_stack_frame (selected_frame, selected_frame_level, 1); + select_frame (get_current_frame ()); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); } else { @@ -403,7 +433,7 @@ get_core_register_section (char *name, int required) { char section_name[100]; - sec_ptr section; + struct bfd_section *section; bfd_size_type size; char *contents; @@ -430,7 +460,25 @@ get_core_register_section (char *name, return; } - core_vec->core_read_registers (contents, size, which, + if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) + { + const struct regset *regset; + + regset = gdbarch_regset_from_core_section (core_gdbarch, name, size); + if (regset == NULL) + { + if (required) + warning ("Couldn't recognize %s registers in core file.\n", + human_name); + return; + } + + regset->supply_regset (regset, current_regcache, -1, contents, size); + return; + } + + gdb_assert (core_vec); + core_vec->core_read_registers (contents, size, which, ((CORE_ADDR) bfd_section_vma (core_bfd, section))); } @@ -442,14 +490,13 @@ get_core_register_section (char *name, /* We just get all the registers, so we don't use regno. */ -/* ARGSUSED */ static void get_core_registers (int regno) { int status; - if (core_vec == NULL - || core_vec->core_read_registers == NULL) + if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) + && (core_vec == NULL || core_vec->core_read_registers == NULL)) { fprintf_filtered (gdb_stderr, "Can't fetch registers from this type of core file\n"); @@ -460,7 +507,7 @@ get_core_registers (int regno) get_core_register_section (".reg2", 2, "floating-point", 0); get_core_register_section (".reg-xfp", 3, "extended floating-point", 0); - registers_fetched (); + deprecated_registers_fetched (); } static void @@ -468,6 +515,63 @@ core_files_info (struct target_ops *t) { print_section_info (t, core_bfd); } + +static LONGEST +core_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + switch (object) + { + case TARGET_OBJECT_MEMORY: + if (readbuf) + return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*write*/, + NULL, ops); + if (writebuf) + return (*ops->to_xfer_memory) (offset, readbuf, len, 1/*write*/, + NULL, ops); + return -1; + + case TARGET_OBJECT_AUXV: + if (readbuf) + { + /* When the aux vector is stored in core file, BFD + represents this with a fake section called ".auxv". */ + + struct bfd_section *section; + bfd_size_type size; + char *contents; + + section = bfd_get_section_by_name (core_bfd, ".auxv"); + if (section == NULL) + return -1; + + size = bfd_section_size (core_bfd, section); + if (offset >= size) + return 0; + size -= offset; + if (size > len) + size = len; + if (size > 0 && + ! bfd_get_section_contents (core_bfd, section, readbuf, + (file_ptr) offset, size)) + { + warning ("Couldn't read NT_AUXV note in core file."); + return -1; + } + + return size; + } + return -1; + + default: + if (ops->beneath != NULL) + return ops->beneath->to_xfer_partial (ops->beneath, object, annex, + readbuf, writebuf, offset, len); + return -1; + } +} + /* If mourn is being called in all the right places, this could be say `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ @@ -503,16 +607,14 @@ init_core_ops (void) core_ops.to_open = core_open; core_ops.to_close = core_close; core_ops.to_attach = find_default_attach; - core_ops.to_require_attach = find_default_require_attach; core_ops.to_detach = core_detach; - core_ops.to_require_detach = find_default_require_detach; core_ops.to_fetch_registers = get_core_registers; + core_ops.to_xfer_partial = core_xfer_partial; core_ops.to_xfer_memory = xfer_memory; core_ops.to_files_info = core_files_info; core_ops.to_insert_breakpoint = ignore; core_ops.to_remove_breakpoint = ignore; core_ops.to_create_inferior = find_default_create_inferior; - core_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior; core_ops.to_thread_alive = core_file_thread_alive; core_ops.to_stratum = core_stratum; core_ops.to_has_memory = 1; diff --git a/contrib/gdb/gdb/cp-abi.c b/contrib/gdb/gdb/cp-abi.c index d4eb0a00d08..a8530209c9b 100644 --- a/contrib/gdb/gdb/cp-abi.c +++ b/contrib/gdb/gdb/cp-abi.c @@ -1,5 +1,5 @@ /* Generic code for supporting multiple C++ ABI's - Copyright 2001 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -21,12 +21,20 @@ #include "defs.h" #include "value.h" #include "cp-abi.h" +#include "command.h" +#include "gdbcmd.h" +#include "ui-out.h" -struct cp_abi_ops current_cp_abi; +#include "gdb_string.h" -struct cp_abi_ops *cp_abis; +static struct cp_abi_ops *find_cp_abi (const char *short_name); -int num_cp_abis = 0; +static struct cp_abi_ops current_cp_abi = { "", NULL }; +static struct cp_abi_ops auto_cp_abi = { "auto", NULL }; + +#define CP_ABI_MAX 8 +static struct cp_abi_ops *cp_abis[CP_ABI_MAX]; +static int num_cp_abis = 0; enum ctor_kinds is_constructor_name (const char *name) @@ -70,8 +78,8 @@ baseclass_offset (struct type *type, int index, char *valaddr, } struct value * -value_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j, - struct type * type, int offset) +value_virtual_fn_field (struct value **arg1p, struct fn_field *f, int j, + struct type *type, int offset) { if ((current_cp_abi.virtual_fn_field) == NULL) return NULL; @@ -86,24 +94,159 @@ value_rtti_type (struct value *v, int *full, int *top, int *using_enc) return (*current_cp_abi.rtti_type) (v, full, top, using_enc); } -int -register_cp_abi (struct cp_abi_ops abi) +/* Set the current C++ ABI to SHORT_NAME. */ + +static int +switch_to_cp_abi (const char *short_name) { - cp_abis = - xrealloc (cp_abis, (num_cp_abis + 1) * sizeof (struct cp_abi_ops)); + struct cp_abi_ops *abi; + + abi = find_cp_abi (short_name); + if (abi == NULL) + return 0; + + current_cp_abi = *abi; + return 1; +} + +/* Add ABI to the list of supported C++ ABI's. */ + +int +register_cp_abi (struct cp_abi_ops *abi) +{ + if (num_cp_abis == CP_ABI_MAX) + internal_error (__FILE__, __LINE__, + "Too many C++ ABIs, please increase CP_ABI_MAX in cp-abi.c"); + cp_abis[num_cp_abis++] = abi; return 1; - } -int -switch_to_cp_abi (const char *short_name) +/* Set the ABI to use in "auto" mode to SHORT_NAME. */ + +void +set_cp_abi_as_auto_default (const char *short_name) +{ + char *new_longname, *new_doc; + struct cp_abi_ops *abi = find_cp_abi (short_name); + + if (abi == NULL) + internal_error (__FILE__, __LINE__, + "Cannot find C++ ABI \"%s\" to set it as auto default.", + short_name); + + if (auto_cp_abi.longname != NULL) + xfree ((char *) auto_cp_abi.longname); + if (auto_cp_abi.doc != NULL) + xfree ((char *) auto_cp_abi.doc); + + auto_cp_abi = *abi; + + auto_cp_abi.shortname = "auto"; + new_longname = xmalloc (strlen ("currently ") + 1 + strlen (abi->shortname) + + 1 + 1); + sprintf (new_longname, "currently \"%s\"", abi->shortname); + auto_cp_abi.longname = new_longname; + + new_doc = xmalloc (strlen ("Automatically selected; currently ") + + 1 + strlen (abi->shortname) + 1 + 1); + sprintf (new_doc, "Automatically selected; currently \"%s\"", abi->shortname); + auto_cp_abi.doc = new_doc; + + /* Since we copy the current ABI into current_cp_abi instead of + using a pointer, if auto is currently the default, we need to + reset it. */ + if (strcmp (current_cp_abi.shortname, "auto") == 0) + switch_to_cp_abi ("auto"); +} + +/* Return the ABI operations associated with SHORT_NAME. */ + +static struct cp_abi_ops * +find_cp_abi (const char *short_name) { int i; + for (i = 0; i < num_cp_abis; i++) - if (strcmp (cp_abis[i].shortname, short_name) == 0) - current_cp_abi = cp_abis[i]; - return 1; + if (strcmp (cp_abis[i]->shortname, short_name) == 0) + return cp_abis[i]; + + return NULL; } +/* Display the list of registered C++ ABIs. */ + +static void +list_cp_abis (int from_tty) +{ + struct cleanup *cleanup_chain; + int i; + ui_out_text (uiout, "The available C++ ABIs are:\n"); + + cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "cp-abi-list"); + for (i = 0; i < num_cp_abis; i++) + { + char pad[14]; + int padcount; + + ui_out_text (uiout, " "); + ui_out_field_string (uiout, "cp-abi", cp_abis[i]->shortname); + + padcount = 16 - 2 - strlen (cp_abis[i]->shortname); + pad[padcount] = 0; + while (padcount > 0) + pad[--padcount] = ' '; + ui_out_text (uiout, pad); + + ui_out_field_string (uiout, "doc", cp_abis[i]->doc); + ui_out_text (uiout, "\n"); + } + do_cleanups (cleanup_chain); +} + +/* Set the current C++ ABI, or display the list of options if no + argument is given. */ + +static void +set_cp_abi_cmd (char *args, int from_tty) +{ + if (args == NULL) + { + list_cp_abis (from_tty); + return; + } + + if (!switch_to_cp_abi (args)) + error ("Could not find \"%s\" in ABI list", args); +} + +/* Show the currently selected C++ ABI. */ + +static void +show_cp_abi_cmd (char *args, int from_tty) +{ + ui_out_text (uiout, "The currently selected C++ ABI is \""); + + ui_out_field_string (uiout, "cp-abi", current_cp_abi.shortname); + ui_out_text (uiout, "\" ("); + ui_out_field_string (uiout, "longname", current_cp_abi.longname); + ui_out_text (uiout, ").\n"); +} + +extern initialize_file_ftype _initialize_cp_abi; /* -Wmissing-prototypes */ + +void +_initialize_cp_abi (void) +{ + register_cp_abi (&auto_cp_abi); + switch_to_cp_abi ("auto"); + + add_cmd ("cp-abi", class_obscure, set_cp_abi_cmd, + "Set the ABI used for inspecting C++ objects.\n" + "\"set cp-abi\" with no arguments will list the available ABIs.", + &setlist); + + add_cmd ("cp-abi", class_obscure, show_cp_abi_cmd, + "Show the ABI used for inspecting C++ objects.", &showlist); +} diff --git a/contrib/gdb/gdb/cp-abi.h b/contrib/gdb/gdb/cp-abi.h index 7c1e9521e03..0413abafc4e 100644 --- a/contrib/gdb/gdb/cp-abi.h +++ b/contrib/gdb/gdb/cp-abi.h @@ -25,6 +25,8 @@ #ifndef CP_ABI_H_ #define CP_ABI_H_ 1 +struct fn_field; +struct type; struct value; /* The functions here that attempt to determine what sort of thing a @@ -163,11 +165,8 @@ struct cp_abi_ops }; -extern struct cp_abi_ops *cp_abis; -extern int num_cp_abis; -extern struct cp_abi_ops current_cp_abi; -extern int register_cp_abi (struct cp_abi_ops abi); -extern int switch_to_cp_abi (const char *short_name); +extern int register_cp_abi (struct cp_abi_ops *abi); +extern void set_cp_abi_as_auto_default (const char *short_name); #endif diff --git a/contrib/gdb/gdb/cp-namespace.c b/contrib/gdb/gdb/cp-namespace.c new file mode 100644 index 00000000000..910289ff3ce --- /dev/null +++ b/contrib/gdb/gdb/cp-namespace.c @@ -0,0 +1,871 @@ +/* Helper routines for C++ support in GDB. + Copyright 2003, 2004 Free Software Foundation, Inc. + + Contributed by David Carlton and by Kealia, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "cp-support.h" +#include "gdb_obstack.h" +#include "symtab.h" +#include "symfile.h" +#include "gdb_assert.h" +#include "block.h" +#include "objfiles.h" +#include "gdbtypes.h" +#include "dictionary.h" +#include "command.h" +#include "frame.h" + +/* When set, the file that we're processing is known to have debugging + info for C++ namespaces. */ + +/* NOTE: carlton/2004-01-13: No currently released version of GCC (the + latest of which is 3.3.x at the time of this writing) produces this + debug info. GCC 3.4 should, however. */ + +unsigned char processing_has_namespace_info; + +/* This contains our best guess as to the name of the current + enclosing namespace(s)/class(es), if any. For example, if we're + within the method foo() in the following code: + + namespace N { + class C { + void foo () { + } + }; + } + + then processing_current_prefix should be set to "N::C". If + processing_has_namespace_info is false, then this variable might + not be reliable. */ + +const char *processing_current_prefix; + +/* List of using directives that are active in the current file. */ + +static struct using_direct *using_list; + +static struct using_direct *cp_add_using (const char *name, + unsigned int inner_len, + unsigned int outer_len, + struct using_direct *next); + +static struct using_direct *cp_copy_usings (struct using_direct *using, + struct obstack *obstack); + +static struct symbol *lookup_namespace_scope (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab, + const char *scope, + int scope_len); + +static struct symbol *lookup_symbol_file (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab, + int anonymous_namespace); + +static struct type *cp_lookup_transparent_type_loop (const char *name, + const char *scope, + int scope_len); + +static void initialize_namespace_symtab (struct objfile *objfile); + +static struct block *get_possible_namespace_block (struct objfile *objfile); + +static void free_namespace_block (struct symtab *symtab); + +static int check_possible_namespace_symbols_loop (const char *name, + int len, + struct objfile *objfile); + +static int check_one_possible_namespace_symbol (const char *name, + int len, + struct objfile *objfile); + +static +struct symbol *lookup_possible_namespace_symbol (const char *name, + struct symtab **symtab); + +static void maintenance_cplus_namespace (char *args, int from_tty); + +/* Set up support for dealing with C++ namespace info in the current + symtab. */ + +void cp_initialize_namespace () +{ + processing_has_namespace_info = 0; + using_list = NULL; +} + +/* Add all the using directives we've gathered to the current symtab. + STATIC_BLOCK should be the symtab's static block; OBSTACK is used + for allocation. */ + +void +cp_finalize_namespace (struct block *static_block, + struct obstack *obstack) +{ + if (using_list != NULL) + { + block_set_using (static_block, + cp_copy_usings (using_list, obstack), + obstack); + using_list = NULL; + } +} + +/* Check to see if SYMBOL refers to an object contained within an + anonymous namespace; if so, add an appropriate using directive. */ + +/* Optimize away strlen ("(anonymous namespace)"). */ + +#define ANONYMOUS_NAMESPACE_LEN 21 + +void +cp_scan_for_anonymous_namespaces (const struct symbol *symbol) +{ + if (!processing_has_namespace_info + && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL) + { + const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol); + unsigned int previous_component; + unsigned int next_component; + const char *len; + + /* Start with a quick-and-dirty check for mention of "(anonymous + namespace)". */ + + if (!cp_is_anonymous (name)) + return; + + previous_component = 0; + next_component = cp_find_first_component (name + previous_component); + + while (name[next_component] == ':') + { + if ((next_component - previous_component) == ANONYMOUS_NAMESPACE_LEN + && strncmp (name + previous_component, + "(anonymous namespace)", + ANONYMOUS_NAMESPACE_LEN) == 0) + { + /* We've found a component of the name that's an + anonymous namespace. So add symbols in it to the + namespace given by the previous component if there is + one, or to the global namespace if there isn't. */ + cp_add_using_directive (name, + previous_component == 0 + ? 0 : previous_component - 2, + next_component); + } + /* The "+ 2" is for the "::". */ + previous_component = next_component + 2; + next_component = (previous_component + + cp_find_first_component (name + + previous_component)); + } + } +} + +/* Add a using directive to using_list. NAME is the start of a string + that should contain the namespaces we want to add as initial + substrings, OUTER_LENGTH is the end of the outer namespace, and + INNER_LENGTH is the end of the inner namespace. If the using + directive in question has already been added, don't add it + twice. */ + +void +cp_add_using_directive (const char *name, unsigned int outer_length, + unsigned int inner_length) +{ + struct using_direct *current; + struct using_direct *new; + + /* Has it already been added? */ + + for (current = using_list; current != NULL; current = current->next) + { + if ((strncmp (current->inner, name, inner_length) == 0) + && (strlen (current->inner) == inner_length) + && (strlen (current->outer) == outer_length)) + return; + } + + using_list = cp_add_using (name, inner_length, outer_length, + using_list); +} + +/* Record the namespace that the function defined by SYMBOL was + defined in, if necessary. BLOCK is the associated block; use + OBSTACK for allocation. */ + +void +cp_set_block_scope (const struct symbol *symbol, + struct block *block, + struct obstack *obstack) +{ + /* Make sure that the name was originally mangled: if not, there + certainly isn't any namespace information to worry about! */ + + if (SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL) + { + if (processing_has_namespace_info) + { + block_set_scope + (block, obsavestring (processing_current_prefix, + strlen (processing_current_prefix), + obstack), + obstack); + } + else + { + /* Try to figure out the appropriate namespace from the + demangled name. */ + + /* FIXME: carlton/2003-04-15: If the function in question is + a method of a class, the name will actually include the + name of the class as well. This should be harmless, but + is a little unfortunate. */ + + const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol); + unsigned int prefix_len = cp_entire_prefix_len (name); + + block_set_scope (block, + obsavestring (name, prefix_len, obstack), + obstack); + } + } +} + +/* Test whether or not NAMESPACE looks like it mentions an anonymous + namespace; return nonzero if so. */ + +int +cp_is_anonymous (const char *namespace) +{ + return (strstr (namespace, "(anonymous namespace)") + != NULL); +} + +/* Create a new struct using direct whose inner namespace is the + initial substring of NAME of leng INNER_LEN and whose outer + namespace is the initial substring of NAME of length OUTER_LENGTH. + Set its next member in the linked list to NEXT; allocate all memory + using xmalloc. It copies the strings, so NAME can be a temporary + string. */ + +static struct using_direct * +cp_add_using (const char *name, + unsigned int inner_len, + unsigned int outer_len, + struct using_direct *next) +{ + struct using_direct *retval; + + gdb_assert (outer_len < inner_len); + + retval = xmalloc (sizeof (struct using_direct)); + retval->inner = savestring (name, inner_len); + retval->outer = savestring (name, outer_len); + retval->next = next; + + return retval; +} + +/* Make a copy of the using directives in the list pointed to by + USING, using OBSTACK to allocate memory. Free all memory pointed + to by USING via xfree. */ + +static struct using_direct * +cp_copy_usings (struct using_direct *using, + struct obstack *obstack) +{ + if (using == NULL) + { + return NULL; + } + else + { + struct using_direct *retval + = obstack_alloc (obstack, sizeof (struct using_direct)); + retval->inner = obsavestring (using->inner, strlen (using->inner), + obstack); + retval->outer = obsavestring (using->outer, strlen (using->outer), + obstack); + retval->next = cp_copy_usings (using->next, obstack); + + xfree (using->inner); + xfree (using->outer); + xfree (using); + + return retval; + } +} + +/* The C++-specific version of name lookup for static and global + names. This makes sure that names get looked for in all namespaces + that are in scope. NAME is the natural name of the symbol that + we're looking for, LINKAGE_NAME (which is optional) is its linkage + name, BLOCK is the block that we're searching within, DOMAIN says + what kind of symbols we're looking for, and if SYMTAB is non-NULL, + we should store the symtab where we found the symbol in it. */ + +struct symbol * +cp_lookup_symbol_nonlocal (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab) +{ + return lookup_namespace_scope (name, linkage_name, block, domain, + symtab, block_scope (block), 0); +} + +/* Lookup NAME at namespace scope (or, in C terms, in static and + global variables). SCOPE is the namespace that the current + function is defined within; only consider namespaces whose length + is at least SCOPE_LEN. Other arguments are as in + cp_lookup_symbol_nonlocal. + + For example, if we're within a function A::B::f and looking for a + symbol x, this will get called with NAME = "x", SCOPE = "A::B", and + SCOPE_LEN = 0. It then calls itself with NAME and SCOPE the same, + but with SCOPE_LEN = 1. And then it calls itself with NAME and + SCOPE the same, but with SCOPE_LEN = 4. This third call looks for + "A::B::x"; if it doesn't find it, then the second call looks for + "A::x", and if that call fails, then the first call looks for + "x". */ + +static struct symbol * +lookup_namespace_scope (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab, + const char *scope, + int scope_len) +{ + char *namespace; + + if (scope[scope_len] != '\0') + { + /* Recursively search for names in child namespaces first. */ + + struct symbol *sym; + int new_scope_len = scope_len; + + /* If the current scope is followed by "::", skip past that. */ + if (new_scope_len != 0) + { + gdb_assert (scope[new_scope_len] == ':'); + new_scope_len += 2; + } + new_scope_len += cp_find_first_component (scope + new_scope_len); + sym = lookup_namespace_scope (name, linkage_name, block, + domain, symtab, + scope, new_scope_len); + if (sym != NULL) + return sym; + } + + /* Okay, we didn't find a match in our children, so look for the + name in the current namespace. */ + + namespace = alloca (scope_len + 1); + strncpy (namespace, scope, scope_len); + namespace[scope_len] = '\0'; + return cp_lookup_symbol_namespace (namespace, name, linkage_name, + block, domain, symtab); +} + +/* Look up NAME in the C++ namespace NAMESPACE, applying the using + directives that are active in BLOCK. Other arguments are as in + cp_lookup_symbol_nonlocal. */ + +struct symbol * +cp_lookup_symbol_namespace (const char *namespace, + const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab) +{ + const struct using_direct *current; + struct symbol *sym; + + /* First, go through the using directives. If any of them add new + names to the namespace we're searching in, see if we can find a + match by applying them. */ + + for (current = block_using (block); + current != NULL; + current = current->next) + { + if (strcmp (namespace, current->outer) == 0) + { + sym = cp_lookup_symbol_namespace (current->inner, + name, + linkage_name, + block, + domain, + symtab); + if (sym != NULL) + return sym; + } + } + + /* We didn't find anything by applying any of the using directives + that are still applicable; so let's see if we've got a match + using the current namespace. */ + + if (namespace[0] == '\0') + { + return lookup_symbol_file (name, linkage_name, block, + domain, symtab, 0); + } + else + { + char *concatenated_name + = alloca (strlen (namespace) + 2 + strlen (name) + 1); + strcpy (concatenated_name, namespace); + strcat (concatenated_name, "::"); + strcat (concatenated_name, name); + sym = lookup_symbol_file (concatenated_name, linkage_name, + block, domain, symtab, + cp_is_anonymous (namespace)); + return sym; + } +} + +/* Look up NAME in BLOCK's static block and in global blocks. If + ANONYMOUS_NAMESPACE is nonzero, the symbol in question is located + within an anonymous namespace. Other arguments are as in + cp_lookup_symbol_nonlocal. */ + +static struct symbol * +lookup_symbol_file (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab, + int anonymous_namespace) +{ + struct symbol *sym = NULL; + + sym = lookup_symbol_static (name, linkage_name, block, domain, symtab); + if (sym != NULL) + return sym; + + if (anonymous_namespace) + { + /* Symbols defined in anonymous namespaces have external linkage + but should be treated as local to a single file nonetheless. + So we only search the current file's global block. */ + + const struct block *global_block = block_global_block (block); + + if (global_block != NULL) + sym = lookup_symbol_aux_block (name, linkage_name, global_block, + domain, symtab); + } + else + { + sym = lookup_symbol_global (name, linkage_name, domain, symtab); + } + + if (sym != NULL) + return sym; + + /* Now call "lookup_possible_namespace_symbol". Symbols in here + claim to be associated to namespaces, but this claim might be + incorrect: the names in question might actually correspond to + classes instead of namespaces. But if they correspond to + classes, then we should have found a match for them above. So if + we find them now, they should be genuine. */ + + /* FIXME: carlton/2003-06-12: This is a hack and should eventually + be deleted: see comments below. */ + + if (domain == VAR_DOMAIN) + { + sym = lookup_possible_namespace_symbol (name, symtab); + if (sym != NULL) + return sym; + } + + return NULL; +} + +/* Look up a type named NESTED_NAME that is nested inside the C++ + class or namespace given by PARENT_TYPE, from within the context + given by BLOCK. Return NULL if there is no such nested type. */ + +struct type * +cp_lookup_nested_type (struct type *parent_type, + const char *nested_name, + const struct block *block) +{ + switch (TYPE_CODE (parent_type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_NAMESPACE: + { + /* NOTE: carlton/2003-11-10: We don't treat C++ class members + of classes like, say, data or function members. Instead, + they're just represented by symbols whose names are + qualified by the name of the surrounding class. This is + just like members of namespaces; in particular, + lookup_symbol_namespace works when looking them up. */ + + const char *parent_name = TYPE_TAG_NAME (parent_type); + struct symbol *sym = cp_lookup_symbol_namespace (parent_name, + nested_name, + NULL, + block, + VAR_DOMAIN, + NULL); + if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF) + return NULL; + else + return SYMBOL_TYPE (sym); + } + default: + internal_error (__FILE__, __LINE__, + "cp_lookup_nested_type called on a non-aggregate type."); + } +} + +/* The C++-version of lookup_transparent_type. */ + +/* FIXME: carlton/2004-01-16: The problem that this is trying to + address is that, unfortunately, sometimes NAME is wrong: it may not + include the name of namespaces enclosing the type in question. + lookup_transparent_type gets called when the the type in question + is a declaration, and we're trying to find its definition; but, for + declarations, our type name deduction mechanism doesn't work. + There's nothing we can do to fix this in general, I think, in the + absence of debug information about namespaces (I've filed PR + gdb/1511 about this); until such debug information becomes more + prevalent, one heuristic which sometimes looks is to search for the + definition in namespaces containing the current namespace. + + We should delete this functions once the appropriate debug + information becomes more widespread. (GCC 3.4 will be the first + released version of GCC with such information.) */ + +struct type * +cp_lookup_transparent_type (const char *name) +{ + /* First, try the honest way of looking up the definition. */ + struct type *t = basic_lookup_transparent_type (name); + const char *scope; + + if (t != NULL) + return t; + + /* If that doesn't work and we're within a namespace, look there + instead. */ + scope = block_scope (get_selected_block (0)); + + if (scope[0] == '\0') + return NULL; + + return cp_lookup_transparent_type_loop (name, scope, 0); +} + +/* Lookup the the type definition associated to NAME in + namespaces/classes containing SCOPE whose name is strictly longer + than LENGTH. LENGTH must be the index of the start of a + component of SCOPE. */ + +static struct type * +cp_lookup_transparent_type_loop (const char *name, const char *scope, + int length) +{ + int scope_length = length + cp_find_first_component (scope + length); + char *full_name; + + /* If the current scope is followed by "::", look in the next + component. */ + if (scope[scope_length] == ':') + { + struct type *retval + = cp_lookup_transparent_type_loop (name, scope, scope_length + 2); + if (retval != NULL) + return retval; + } + + full_name = alloca (scope_length + 2 + strlen (name) + 1); + strncpy (full_name, scope, scope_length); + strncpy (full_name + scope_length, "::", 2); + strcpy (full_name + scope_length + 2, name); + + return basic_lookup_transparent_type (full_name); +} + +/* Now come functions for dealing with symbols associated to + namespaces. (They're used to store the namespaces themselves, not + objects that live in the namespaces.) These symbols come in two + varieties: if we run into a DW_TAG_namespace DIE, then we know that + we have a namespace, so dwarf2read.c creates a symbol for it just + like normal. But, unfortunately, versions of GCC through at least + 3.3 don't generate those DIE's. Our solution is to try to guess + their existence by looking at demangled names. This might cause us + to misidentify classes as namespaces, however. So we put those + symbols in a special block (one per objfile), and we only search + that block as a last resort. */ + +/* FIXME: carlton/2003-06-12: Once versions of GCC that generate + DW_TAG_namespace have been out for a year or two, we should get rid + of all of this "possible namespace" nonsense. */ + +/* Allocate everything necessary for the possible namespace block + associated to OBJFILE. */ + +static void +initialize_namespace_symtab (struct objfile *objfile) +{ + struct symtab *namespace_symtab; + struct blockvector *bv; + struct block *bl; + + namespace_symtab = allocate_symtab ("<>", objfile); + namespace_symtab->language = language_cplus; + namespace_symtab->free_code = free_nothing; + namespace_symtab->dirname = NULL; + + bv = obstack_alloc (&objfile->objfile_obstack, + sizeof (struct blockvector) + + FIRST_LOCAL_BLOCK * sizeof (struct block *)); + BLOCKVECTOR_NBLOCKS (bv) = FIRST_LOCAL_BLOCK + 1; + BLOCKVECTOR (namespace_symtab) = bv; + + /* Allocate empty GLOBAL_BLOCK and STATIC_BLOCK. */ + + bl = allocate_block (&objfile->objfile_obstack); + BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack, + NULL); + BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl; + bl = allocate_block (&objfile->objfile_obstack); + BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack, + NULL); + BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl; + + /* Allocate the possible namespace block; we put it where the first + local block will live, though I don't think there's any need to + pretend that it's actually a local block (e.g. by setting + BLOCK_SUPERBLOCK appropriately). We don't use the global or + static block because we don't want it searched during the normal + search of all global/static blocks in lookup_symbol: we only want + it used as a last resort. */ + + /* NOTE: carlton/2003-09-11: I considered not associating the fake + symbols to a block/symtab at all. But that would cause problems + with lookup_symbol's SYMTAB argument and with block_found, so + having a symtab/block for this purpose seems like the best + solution for now. */ + + bl = allocate_block (&objfile->objfile_obstack); + BLOCK_DICT (bl) = dict_create_hashed_expandable (); + BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK) = bl; + + namespace_symtab->free_func = free_namespace_block; + + objfile->cp_namespace_symtab = namespace_symtab; +} + +/* Locate the possible namespace block associated to OBJFILE, + allocating it if necessary. */ + +static struct block * +get_possible_namespace_block (struct objfile *objfile) +{ + if (objfile->cp_namespace_symtab == NULL) + initialize_namespace_symtab (objfile); + + return BLOCKVECTOR_BLOCK (BLOCKVECTOR (objfile->cp_namespace_symtab), + FIRST_LOCAL_BLOCK); +} + +/* Free the dictionary associated to the possible namespace block. */ + +static void +free_namespace_block (struct symtab *symtab) +{ + struct block *possible_namespace_block; + + possible_namespace_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), + FIRST_LOCAL_BLOCK); + gdb_assert (possible_namespace_block != NULL); + dict_free (BLOCK_DICT (possible_namespace_block)); +} + +/* Ensure that there are symbols in the possible namespace block + associated to OBJFILE for all initial substrings of NAME that look + like namespaces or classes. NAME should end in a member variable: + it shouldn't consist solely of namespaces. */ + +void +cp_check_possible_namespace_symbols (const char *name, struct objfile *objfile) +{ + check_possible_namespace_symbols_loop (name, + cp_find_first_component (name), + objfile); +} + +/* This is a helper loop for cp_check_possible_namespace_symbols; it + ensures that there are symbols in the possible namespace block + associated to OBJFILE for all namespaces that are initial + substrings of NAME of length at least LEN. It returns 1 if a + previous loop had already created the shortest such symbol and 0 + otherwise. + + This function assumes that if there is already a symbol associated + to a substring of NAME of a given length, then there are already + symbols associated to all substrings of NAME whose length is less + than that length. So if cp_check_possible_namespace_symbols has + been called once with argument "A::B::C::member", then that will + create symbols "A", "A::B", and "A::B::C". If it is then later + called with argument "A::B::D::member", then the new call will + generate a new symbol for "A::B::D", but once it sees that "A::B" + has already been created, it doesn't bother checking to see if "A" + has also been created. */ + +static int +check_possible_namespace_symbols_loop (const char *name, int len, + struct objfile *objfile) +{ + if (name[len] == ':') + { + int done; + int next_len = len + 2; + + next_len += cp_find_first_component (name + next_len); + done = check_possible_namespace_symbols_loop (name, next_len, + objfile); + + if (!done) + done = check_one_possible_namespace_symbol (name, len, objfile); + + return done; + } + else + return 0; +} + +/* Check to see if there's already a possible namespace symbol in + OBJFILE whose name is the initial substring of NAME of length LEN. + If not, create one and return 0; otherwise, return 1. */ + +static int +check_one_possible_namespace_symbol (const char *name, int len, + struct objfile *objfile) +{ + struct block *block = get_possible_namespace_block (objfile); + char *name_copy = alloca (len + 1); + struct symbol *sym; + + memcpy (name_copy, name, len); + name_copy[len] = '\0'; + sym = lookup_block_symbol (block, name_copy, NULL, VAR_DOMAIN); + + if (sym == NULL) + { + struct type *type; + name_copy = obsavestring (name, len, &objfile->objfile_obstack); + + type = init_type (TYPE_CODE_NAMESPACE, 0, 0, name_copy, objfile); + + TYPE_TAG_NAME (type) = TYPE_NAME (type); + + sym = obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); + memset (sym, 0, sizeof (struct symbol)); + SYMBOL_LANGUAGE (sym) = language_cplus; + SYMBOL_SET_NAMES (sym, name_copy, len, objfile); + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_TYPE (sym) = type; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + + dict_add_symbol (BLOCK_DICT (block), sym); + + return 0; + } + else + return 1; +} + +/* Look for a symbol named NAME in all the possible namespace blocks. + If one is found, return it; if SYMTAB is non-NULL, set *SYMTAB to + equal the symtab where it was found. */ + +static struct symbol * +lookup_possible_namespace_symbol (const char *name, struct symtab **symtab) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + struct symbol *sym; + + sym = lookup_block_symbol (get_possible_namespace_block (objfile), + name, NULL, VAR_DOMAIN); + + if (sym != NULL) + { + if (symtab != NULL) + *symtab = objfile->cp_namespace_symtab; + + return sym; + } + } + + return NULL; +} + +/* Print out all the possible namespace symbols. */ + +static void +maintenance_cplus_namespace (char *args, int from_tty) +{ + struct objfile *objfile; + printf_unfiltered ("Possible namespaces:\n"); + ALL_OBJFILES (objfile) + { + struct dict_iterator iter; + struct symbol *sym; + + ALL_BLOCK_SYMBOLS (get_possible_namespace_block (objfile), iter, sym) + { + printf_unfiltered ("%s\n", SYMBOL_PRINT_NAME (sym)); + } + } +} + +void +_initialize_cp_namespace (void) +{ + add_cmd ("namespace", class_maintenance, maintenance_cplus_namespace, + "Print the list of possible C++ namespaces.", + &maint_cplus_cmd_list); +} diff --git a/contrib/gdb/gdb/cp-support.c b/contrib/gdb/gdb/cp-support.c new file mode 100644 index 00000000000..4344545c3e9 --- /dev/null +++ b/contrib/gdb/gdb/cp-support.c @@ -0,0 +1,757 @@ +/* Helper routines for C++ support in GDB. + Copyright 2002, 2003 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include +#include "cp-support.h" +#include "gdb_string.h" +#include "demangle.h" +#include "gdb_assert.h" +#include "gdbcmd.h" +#include "dictionary.h" +#include "objfiles.h" +#include "frame.h" +#include "symtab.h" +#include "block.h" +#include "complaints.h" +#include "gdbtypes.h" + +/* Functions related to demangled name parsing. */ + +static const char *find_last_component (const char *name); + +static unsigned int cp_find_first_component_aux (const char *name, + int permissive); + +static void demangled_name_complaint (const char *name); + +/* Functions/variables related to overload resolution. */ + +static int sym_return_val_size; +static int sym_return_val_index; +static struct symbol **sym_return_val; + +static char *remove_params (const char *demangled_name); + +static void overload_list_add_symbol (struct symbol *sym, + const char *oload_name); + +static void make_symbol_overload_list_using (const char *func_name, + const char *namespace); + +static void make_symbol_overload_list_qualified (const char *func_name); + +static void read_in_psymtabs (const char *oload_name); + +/* The list of "maint cplus" commands. */ + +struct cmd_list_element *maint_cplus_cmd_list = NULL; + +/* The actual commands. */ + +static void maint_cplus_command (char *arg, int from_tty); +static void first_component_command (char *arg, int from_tty); + +/* Here are some random pieces of trivia to keep in mind while trying + to take apart demangled names: + + - Names can contain function arguments or templates, so the process + has to be, to some extent recursive: maybe keep track of your + depth based on encountering <> and (). + + - Parentheses don't just have to happen at the end of a name: they + can occur even if the name in question isn't a function, because + a template argument might be a type that's a function. + + - Conversely, even if you're trying to deal with a function, its + demangled name might not end with ')': it could be a const or + volatile class method, in which case it ends with "const" or + "volatile". + + - Parentheses are also used in anonymous namespaces: a variable + 'foo' in an anonymous namespace gets demangled as "(anonymous + namespace)::foo". + + - And operator names can contain parentheses or angle brackets. */ + +/* FIXME: carlton/2003-03-13: We have several functions here with + overlapping functionality; can we combine them? Also, do they + handle all the above considerations correctly? */ + +/* Find the last component of the demangled C++ name NAME. NAME + must be a method name including arguments, in order to correctly + locate the last component. + + This function return a pointer to the first colon before the + last component, or NULL if the name had only one component. */ + +static const char * +find_last_component (const char *name) +{ + const char *p; + int depth; + + /* Functions can have local classes, so we need to find the + beginning of the last argument list, not the end of the first + one. */ + p = name + strlen (name) - 1; + while (p > name && *p != ')') + p--; + + if (p == name) + return NULL; + + /* P now points at the `)' at the end of the argument list. Walk + back to the beginning. */ + p--; + depth = 1; + while (p > name && depth > 0) + { + if (*p == '<' || *p == '(') + depth--; + else if (*p == '>' || *p == ')') + depth++; + p--; + } + + if (p == name) + return NULL; + + while (p > name && *p != ':') + p--; + + if (p == name || p == name + 1 || p[-1] != ':') + return NULL; + + return p - 1; +} + +/* Return the name of the class containing method PHYSNAME. */ + +char * +class_name_from_physname (const char *physname) +{ + char *ret = NULL; + const char *end; + int depth = 0; + char *demangled_name = cplus_demangle (physname, DMGL_ANSI | DMGL_PARAMS); + + if (demangled_name == NULL) + return NULL; + + end = find_last_component (demangled_name); + if (end != NULL) + { + ret = xmalloc (end - demangled_name + 1); + memcpy (ret, demangled_name, end - demangled_name); + ret[end - demangled_name] = '\0'; + } + + xfree (demangled_name); + return ret; +} + +/* Return the name of the method whose linkage name is PHYSNAME. */ + +char * +method_name_from_physname (const char *physname) +{ + char *ret = NULL; + const char *end; + int depth = 0; + char *demangled_name = cplus_demangle (physname, DMGL_ANSI | DMGL_PARAMS); + + if (demangled_name == NULL) + return NULL; + + end = find_last_component (demangled_name); + if (end != NULL) + { + char *args; + int len; + + /* Skip "::". */ + end = end + 2; + + /* Find the argument list, if any. */ + args = strchr (end, '('); + if (args == NULL) + len = strlen (end + 2); + else + { + args --; + while (*args == ' ') + args --; + len = args - end + 1; + } + ret = xmalloc (len + 1); + memcpy (ret, end, len); + ret[len] = 0; + } + + xfree (demangled_name); + return ret; +} + +/* This returns the length of first component of NAME, which should be + the demangled name of a C++ variable/function/method/etc. + Specifically, it returns the index of the first colon forming the + boundary of the first component: so, given 'A::foo' or 'A::B::foo' + it returns the 1, and given 'foo', it returns 0. */ + +/* The character in NAME indexed by the return value is guaranteed to + always be either ':' or '\0'. */ + +/* NOTE: carlton/2003-03-13: This function is currently only intended + for internal use: it's probably not entirely safe when called on + user-generated input, because some of the 'index += 2' lines in + cp_find_first_component_aux might go past the end of malformed + input. */ + +unsigned int +cp_find_first_component (const char *name) +{ + return cp_find_first_component_aux (name, 0); +} + +/* Helper function for cp_find_first_component. Like that function, + it returns the length of the first component of NAME, but to make + the recursion easier, it also stops if it reaches an unexpected ')' + or '>' if the value of PERMISSIVE is nonzero. */ + +/* Let's optimize away calls to strlen("operator"). */ + +#define LENGTH_OF_OPERATOR 8 + +static unsigned int +cp_find_first_component_aux (const char *name, int permissive) +{ + unsigned int index = 0; + /* Operator names can show up in unexpected places. Since these can + contain parentheses or angle brackets, they can screw up the + recursion. But not every string 'operator' is part of an + operater name: e.g. you could have a variable 'cooperator'. So + this variable tells us whether or not we should treat the string + 'operator' as starting an operator. */ + int operator_possible = 1; + + for (;; ++index) + { + switch (name[index]) + { + case '<': + /* Template; eat it up. The calls to cp_first_component + should only return (I hope!) when they reach the '>' + terminating the component or a '::' between two + components. (Hence the '+ 2'.) */ + index += 1; + for (index += cp_find_first_component_aux (name + index, 1); + name[index] != '>'; + index += cp_find_first_component_aux (name + index, 1)) + { + if (name[index] != ':') + { + demangled_name_complaint (name); + return strlen (name); + } + index += 2; + } + operator_possible = 1; + break; + case '(': + /* Similar comment as to '<'. */ + index += 1; + for (index += cp_find_first_component_aux (name + index, 1); + name[index] != ')'; + index += cp_find_first_component_aux (name + index, 1)) + { + if (name[index] != ':') + { + demangled_name_complaint (name); + return strlen (name); + } + index += 2; + } + operator_possible = 1; + break; + case '>': + case ')': + if (permissive) + return index; + else + { + demangled_name_complaint (name); + return strlen (name); + } + case '\0': + case ':': + return index; + case 'o': + /* Operator names can screw up the recursion. */ + if (operator_possible + && strncmp (name + index, "operator", LENGTH_OF_OPERATOR) == 0) + { + index += LENGTH_OF_OPERATOR; + while (isspace(name[index])) + ++index; + switch (name[index]) + { + /* Skip over one less than the appropriate number of + characters: the for loop will skip over the last + one. */ + case '<': + if (name[index + 1] == '<') + index += 1; + else + index += 0; + break; + case '>': + case '-': + if (name[index + 1] == '>') + index += 1; + else + index += 0; + break; + case '(': + index += 1; + break; + default: + index += 0; + break; + } + } + operator_possible = 0; + break; + case ' ': + case ',': + case '.': + case '&': + case '*': + /* NOTE: carlton/2003-04-18: I'm not sure what the precise + set of relevant characters are here: it's necessary to + include any character that can show up before 'operator' + in a demangled name, and it's safe to include any + character that can't be part of an identifier's name. */ + operator_possible = 1; + break; + default: + operator_possible = 0; + break; + } + } +} + +/* Complain about a demangled name that we don't know how to parse. + NAME is the demangled name in question. */ + +static void +demangled_name_complaint (const char *name) +{ + complaint (&symfile_complaints, + "unexpected demangled name '%s'", name); +} + +/* If NAME is the fully-qualified name of a C++ + function/variable/method/etc., this returns the length of its + entire prefix: all of the namespaces and classes that make up its + name. Given 'A::foo', it returns 1, given 'A::B::foo', it returns + 4, given 'foo', it returns 0. */ + +unsigned int +cp_entire_prefix_len (const char *name) +{ + unsigned int current_len = cp_find_first_component (name); + unsigned int previous_len = 0; + + while (name[current_len] != '\0') + { + gdb_assert (name[current_len] == ':'); + previous_len = current_len; + /* Skip the '::'. */ + current_len += 2; + current_len += cp_find_first_component (name + current_len); + } + + return previous_len; +} + +/* If FULL_NAME is the demangled name of a C++ function (including an + arg list, possibly including namespace/class qualifications), + return a new string containing only the function name (without the + arg list/class qualifications). Otherwise, return NULL. The + caller is responsible for freeing the memory in question. */ + +char * +cp_func_name (const char *full_name) +{ + const char *previous_component = full_name; + const char *next_component; + + if (!full_name) + return NULL; + + for (next_component = (previous_component + + cp_find_first_component (previous_component)); + *next_component == ':'; + next_component = (previous_component + + cp_find_first_component (previous_component))) + { + /* Skip '::'. */ + previous_component = next_component + 2; + } + + return remove_params (previous_component); +} + +/* Overload resolution functions. */ + +static char * +remove_params (const char *demangled_name) +{ + const char *argp; + char *new_name; + int depth; + + if (demangled_name == NULL) + return NULL; + + /* First find the end of the arg list. */ + argp = strrchr (demangled_name, ')'); + if (argp == NULL) + return NULL; + + /* Back up to the beginning. */ + depth = 1; + + while (argp-- > demangled_name) + { + if (*argp == ')') + depth ++; + else if (*argp == '(') + { + depth --; + + if (depth == 0) + break; + } + } + if (depth != 0) + internal_error (__FILE__, __LINE__, + "bad demangled name %s\n", demangled_name); + while (argp[-1] == ' ' && argp > demangled_name) + argp --; + + new_name = xmalloc (argp - demangled_name + 1); + memcpy (new_name, demangled_name, argp - demangled_name); + new_name[argp - demangled_name] = '\0'; + return new_name; +} + +/* Test to see if SYM is a symbol that we haven't seen corresponding + to a function named OLOAD_NAME. If so, add it to the current + completion list. */ + +static void +overload_list_add_symbol (struct symbol *sym, const char *oload_name) +{ + int newsize; + int i; + char *sym_name; + + /* If there is no type information, we can't do anything, so skip */ + if (SYMBOL_TYPE (sym) == NULL) + return; + + /* skip any symbols that we've already considered. */ + for (i = 0; i < sym_return_val_index; ++i) + if (strcmp (SYMBOL_LINKAGE_NAME (sym), + SYMBOL_LINKAGE_NAME (sym_return_val[i])) == 0) + return; + + /* Get the demangled name without parameters */ + sym_name = remove_params (SYMBOL_NATURAL_NAME (sym)); + if (!sym_name) + return; + + /* skip symbols that cannot match */ + if (strcmp (sym_name, oload_name) != 0) + { + xfree (sym_name); + return; + } + + xfree (sym_name); + + /* We have a match for an overload instance, so add SYM to the current list + * of overload instances */ + if (sym_return_val_index + 3 > sym_return_val_size) + { + newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *); + sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize); + } + sym_return_val[sym_return_val_index++] = sym; + sym_return_val[sym_return_val_index] = NULL; +} + +/* Return a null-terminated list of pointers to function symbols that + are named FUNC_NAME and are visible within NAMESPACE. */ + +struct symbol ** +make_symbol_overload_list (const char *func_name, + const char *namespace) +{ + struct cleanup *old_cleanups; + + sym_return_val_size = 100; + sym_return_val_index = 0; + sym_return_val = xmalloc ((sym_return_val_size + 1) * + sizeof (struct symbol *)); + sym_return_val[0] = NULL; + + old_cleanups = make_cleanup (xfree, sym_return_val); + + make_symbol_overload_list_using (func_name, namespace); + + discard_cleanups (old_cleanups); + + return sym_return_val; +} + +/* This applies the using directives to add namespaces to search in, + and then searches for overloads in all of those namespaces. It + adds the symbols found to sym_return_val. Arguments are as in + make_symbol_overload_list. */ + +static void +make_symbol_overload_list_using (const char *func_name, + const char *namespace) +{ + const struct using_direct *current; + + /* First, go through the using directives. If any of them apply, + look in the appropriate namespaces for new functions to match + on. */ + + for (current = block_using (get_selected_block (0)); + current != NULL; + current = current->next) + { + if (strcmp (namespace, current->outer) == 0) + { + make_symbol_overload_list_using (func_name, + current->inner); + } + } + + /* Now, add names for this namespace. */ + + if (namespace[0] == '\0') + { + make_symbol_overload_list_qualified (func_name); + } + else + { + char *concatenated_name + = alloca (strlen (namespace) + 2 + strlen (func_name) + 1); + strcpy (concatenated_name, namespace); + strcat (concatenated_name, "::"); + strcat (concatenated_name, func_name); + make_symbol_overload_list_qualified (concatenated_name); + } +} + +/* This does the bulk of the work of finding overloaded symbols. + FUNC_NAME is the name of the overloaded function we're looking for + (possibly including namespace info). */ + +static void +make_symbol_overload_list_qualified (const char *func_name) +{ + struct symbol *sym; + struct symtab *s; + struct objfile *objfile; + const struct block *b, *surrounding_static_block = 0; + struct dict_iterator iter; + const struct dictionary *dict; + + /* Look through the partial symtabs for all symbols which begin + by matching FUNC_NAME. Make sure we read that symbol table in. */ + + read_in_psymtabs (func_name); + + /* Search upwards from currently selected frame (so that we can + complete on local vars. */ + + for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) + { + dict = BLOCK_DICT (b); + + for (sym = dict_iter_name_first (dict, func_name, &iter); + sym; + sym = dict_iter_name_next (func_name, &iter)) + { + overload_list_add_symbol (sym, func_name); + } + } + + surrounding_static_block = block_static_block (get_selected_block (0)); + + /* Go through the symtabs and check the externs and statics for + symbols which match. */ + + ALL_SYMTABS (objfile, s) + { + QUIT; + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); + dict = BLOCK_DICT (b); + + for (sym = dict_iter_name_first (dict, func_name, &iter); + sym; + sym = dict_iter_name_next (func_name, &iter)) + { + overload_list_add_symbol (sym, func_name); + } + } + + ALL_SYMTABS (objfile, s) + { + QUIT; + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); + /* Don't do this block twice. */ + if (b == surrounding_static_block) + continue; + dict = BLOCK_DICT (b); + + for (sym = dict_iter_name_first (dict, func_name, &iter); + sym; + sym = dict_iter_name_next (func_name, &iter)) + { + overload_list_add_symbol (sym, func_name); + } + } +} + +/* Look through the partial symtabs for all symbols which begin + by matching FUNC_NAME. Make sure we read that symbol table in. */ + +static void +read_in_psymtabs (const char *func_name) +{ + struct partial_symtab *ps; + struct objfile *objfile; + + ALL_PSYMTABS (objfile, ps) + { + if (ps->readin) + continue; + + if ((lookup_partial_symbol (ps, func_name, NULL, 1, VAR_DOMAIN) + != NULL) + || (lookup_partial_symbol (ps, func_name, NULL, 0, VAR_DOMAIN) + != NULL)) + psymtab_to_symtab (ps); + } +} + +/* Lookup the rtti type for a class name. */ + +struct type * +cp_lookup_rtti_type (const char *name, struct block *block) +{ + struct symbol * rtti_sym; + struct type * rtti_type; + + rtti_sym = lookup_symbol (name, block, STRUCT_DOMAIN, NULL, NULL); + + if (rtti_sym == NULL) + { + warning ("RTTI symbol not found for class '%s'", name); + return NULL; + } + + if (SYMBOL_CLASS (rtti_sym) != LOC_TYPEDEF) + { + warning ("RTTI symbol for class '%s' is not a type", name); + return NULL; + } + + rtti_type = SYMBOL_TYPE (rtti_sym); + + switch (TYPE_CODE (rtti_type)) + { + case TYPE_CODE_CLASS: + break; + case TYPE_CODE_NAMESPACE: + /* chastain/2003-11-26: the symbol tables often contain fake + symbols for namespaces with the same name as the struct. + This warning is an indication of a bug in the lookup order + or a bug in the way that the symbol tables are populated. */ + warning ("RTTI symbol for class '%s' is a namespace", name); + return NULL; + default: + warning ("RTTI symbol for class '%s' has bad type", name); + return NULL; + } + + return rtti_type; +} + +/* Don't allow just "maintenance cplus". */ + +static void +maint_cplus_command (char *arg, int from_tty) +{ + printf_unfiltered ("\"maintenance cplus\" must be followed by the name of a command.\n"); + help_list (maint_cplus_cmd_list, "maintenance cplus ", -1, gdb_stdout); +} + +/* This is a front end for cp_find_first_component, for unit testing. + Be careful when using it: see the NOTE above + cp_find_first_component. */ + +static void +first_component_command (char *arg, int from_tty) +{ + int len = cp_find_first_component (arg); + char *prefix = alloca (len + 1); + + memcpy (prefix, arg, len); + prefix[len] = '\0'; + + printf_unfiltered ("%s\n", prefix); +} + +extern initialize_file_ftype _initialize_cp_support; /* -Wmissing-prototypes */ + +void +_initialize_cp_support (void) +{ + add_prefix_cmd ("cplus", class_maintenance, maint_cplus_command, + "C++ maintenance commands.", &maint_cplus_cmd_list, + "maintenance cplus ", 0, &maintenancelist); + add_alias_cmd ("cp", "cplus", class_maintenance, 1, &maintenancelist); + + add_cmd ("first_component", class_maintenance, first_component_command, + "Print the first class/namespace component of NAME.", + &maint_cplus_cmd_list); + +} diff --git a/contrib/gdb/gdb/cp-support.h b/contrib/gdb/gdb/cp-support.h new file mode 100644 index 00000000000..bbf911a387f --- /dev/null +++ b/contrib/gdb/gdb/cp-support.h @@ -0,0 +1,120 @@ +/* Helper routines for C++ support in GDB. + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + Namespace support contributed by David Carlton. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef CP_SUPPORT_H +#define CP_SUPPORT_H + +/* We need this for 'domain_enum', alas... */ + +#include "symtab.h" + +/* Opaque declarations. */ + +struct symbol; +struct obstack; +struct block; +struct objfile; +struct type; + +/* This struct is designed to store data from using directives. It + says that names from namespace INNER should be visible within + namespace OUTER. OUTER should always be a strict initial substring + of INNER. These form a linked list; NEXT is the next element of + the list. */ + +struct using_direct +{ + char *inner; + char *outer; + struct using_direct *next; +}; + + +/* Functions from cp-support.c. */ + +extern char *class_name_from_physname (const char *physname); + +extern char *method_name_from_physname (const char *physname); + +extern unsigned int cp_find_first_component (const char *name); + +extern unsigned int cp_entire_prefix_len (const char *name); + +extern char *cp_func_name (const char *full_name); + +extern struct symbol **make_symbol_overload_list (const char *, + const char *); + +extern struct type *cp_lookup_rtti_type (const char *name, + struct block *block); + +/* Functions/variables from cp-namespace.c. */ + +extern unsigned char processing_has_namespace_info; + +extern const char *processing_current_prefix; + +extern int cp_is_anonymous (const char *namespace); + +extern void cp_add_using_directive (const char *name, + unsigned int outer_length, + unsigned int inner_length); + +extern void cp_initialize_namespace (void); + +extern void cp_finalize_namespace (struct block *static_block, + struct obstack *obstack); + +extern void cp_set_block_scope (const struct symbol *symbol, + struct block *block, + struct obstack *obstack); + +extern void cp_scan_for_anonymous_namespaces (const struct symbol *symbol); + +extern struct symbol *cp_lookup_symbol_nonlocal (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab); + +extern struct symbol *cp_lookup_symbol_namespace (const char *namespace, + const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab); + +extern struct type *cp_lookup_nested_type (struct type *parent_type, + const char *nested_name, + const struct block *block); + +extern void cp_check_possible_namespace_symbols (const char *name, + struct objfile *objfile); + +struct type *cp_lookup_transparent_type (const char *name); + +/* The list of "maint cplus" commands. */ + +extern struct cmd_list_element *maint_cplus_cmd_list; + +#endif /* CP_SUPPORT_H */ diff --git a/contrib/gdb/gdb/cp-valprint.c b/contrib/gdb/gdb/cp-valprint.c index 669203121c8..42a48f55676 100644 --- a/contrib/gdb/gdb/cp-valprint.c +++ b/contrib/gdb/gdb/cp-valprint.c @@ -1,6 +1,6 @@ /* Support for printing C++ values for GDB, the GNU debugger. Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 2000, 2001 + 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -21,7 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" @@ -34,6 +34,7 @@ #include "c-lang.h" #include "target.h" #include "cp-abi.h" +#include "valprint.h" /* Indication of presence of HP-compiled object files */ extern int hp_som_som_object_present; /* defined in symtab.c */ @@ -87,7 +88,7 @@ cp_print_class_method (char *valaddr, fprintf_filtered (stream, ""); return; } - addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr); + addr = unpack_pointer (type, valaddr); if (METHOD_PTR_IS_VIRTUAL (addr)) { offset = METHOD_PTR_TO_VOFFSET (addr); @@ -97,13 +98,11 @@ cp_print_class_method (char *valaddr, f = TYPE_FN_FIELDLIST1 (domain, i); len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + check_stub_method_group (domain, i); for (j = 0; j < len2; j++) { - QUIT; if (TYPE_FN_FIELD_VOFFSET (f, j) == offset) { - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (domain, i, j); kind = "virtual "; goto common; } @@ -129,15 +128,12 @@ cp_print_class_method (char *valaddr, f = TYPE_FN_FIELDLIST1 (domain, i); len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + check_stub_method_group (domain, i); for (j = 0; j < len2; j++) { - QUIT; - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (domain, i, j); - if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) - { - goto common; - } + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)) + == 0) + goto common; } } } @@ -147,7 +143,7 @@ cp_print_class_method (char *valaddr, char *demangled_name; fprintf_filtered (stream, "&"); - fprintf_filtered (stream, kind); + fputs_filtered (kind, stream); demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j), DMGL_ANSI | DMGL_PARAMS); if (demangled_name == NULL) @@ -167,21 +163,13 @@ cp_print_class_method (char *valaddr, } } -/* 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. */ +/* GCC versions after 2.4.5 use this. */ const char vtbl_ptr_name[] = "__vtbl_ptr_type"; -/* HP aCC uses different names */ +/* HP aCC uses different names. */ const char hpacc_vtbl_ptr_name[] = "__vfp"; const char hpacc_vtbl_ptr_type_name[] = "__vftyp"; - /* Return truth value for assertion that TYPE is of the type "pointer to virtual function". */ @@ -190,9 +178,7 @@ cp_is_vtbl_ptr_type (struct type *type) { char *typename = type_name_no_tag (type); - return (typename != NULL - && (STREQ (typename, vtbl_ptr_name) - || STREQ (typename, vtbl_ptr_name_old))); + return (typename != NULL && !strcmp (typename, vtbl_ptr_name)); } /* Return truth value for the assertion that TYPE is of the type @@ -201,6 +187,8 @@ cp_is_vtbl_ptr_type (struct type *type) int cp_is_vtbl_member (struct type *type) { + /* With older versions of g++, the vtbl field pointed to an array + of structures. Nowadays it points directly to the structure. */ if (TYPE_CODE (type) == TYPE_CODE_PTR) { type = TYPE_TARGET_TYPE (type); @@ -215,6 +203,17 @@ cp_is_vtbl_member (struct type *type) return cp_is_vtbl_ptr_type (type); } } + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) /* if not using thunks */ + { + return cp_is_vtbl_ptr_type (type); + } + else if (TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */ + { + /* The type name of the thunk pointer is NULL when using dwarf2. + We could test for a pointer to a function, but there is + no type info for the virtual table either, so it wont help. */ + return cp_is_vtbl_ptr_type (type); + } } return 0; } @@ -262,14 +261,12 @@ cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr, if ((len == n_baseclasses) || ((len - n_baseclasses == 1) && TYPE_HAS_VTABLE (type) - && STREQN (TYPE_FIELD_NAME (type, n_baseclasses), - hpacc_vtbl_ptr_name, 5)) + && strncmp (TYPE_FIELD_NAME (type, n_baseclasses), + hpacc_vtbl_ptr_name, 5) == 0) || !len) fprintf_filtered (stream, ""); else { - extern int inspect_it; - if (dont_print_statmem == 0) { /* If we're at top level, carve out a completely fresh @@ -287,7 +284,8 @@ cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr, /* If a vtable pointer appears, we'll print it out later */ if (TYPE_HAS_VTABLE (type) - && STREQN (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 5)) + && strncmp (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, + 5) == 0) continue; if (fields_seen) @@ -410,9 +408,8 @@ cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr, } /* if there are data fields */ /* Now print out the virtual table pointer if there is one */ if (TYPE_HAS_VTABLE (type) - && STREQN (TYPE_FIELD_NAME (type, n_baseclasses), - hpacc_vtbl_ptr_name, - 5)) + && strncmp (TYPE_FIELD_NAME (type, n_baseclasses), + hpacc_vtbl_ptr_name, 5) == 0) { struct value *v; /* First get the virtual table pointer and print it out */ @@ -557,7 +554,7 @@ cp_print_value (struct type *type, struct type *real_type, char *valaddr, { boffset = baseclass_offset (type, i, valaddr + offset, - address + offset); + address); skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1; if (BASETYPE_VIA_VIRTUAL (type, i)) @@ -572,9 +569,10 @@ cp_print_value (struct type *type, struct type *real_type, char *valaddr, { /* FIXME (alloca): unsafe if baseclass is really really large. */ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass)); - if (target_read_memory (address + offset + boffset, base_valaddr, + if (target_read_memory (address + boffset, base_valaddr, TYPE_LENGTH (baseclass)) != 0) skip = 1; + address = address + boffset; thisoffset = 0; boffset = 0; thistype = baseclass; @@ -603,7 +601,8 @@ cp_print_value (struct type *type, struct type *real_type, char *valaddr, fprintf_filtered (stream, ""); else cp_print_value_fields (baseclass, thistype, base_valaddr, - thisoffset + boffset, address, stream, format, + thisoffset + boffset, address + boffset, + stream, format, recurse, pretty, ((struct type **) obstack_base (&dont_print_vb_obstack)), @@ -687,7 +686,7 @@ cp_print_class_member (char *valaddr, struct type *domain, print it. */ int extra = 0; int bits = 0; - register unsigned int i; + unsigned int i; unsigned len = TYPE_NFIELDS (domain); /* @@ Make VAL into bit offset */ @@ -721,7 +720,7 @@ cp_print_class_member (char *valaddr, struct type *domain, if (i < len) { char *name; - fprintf_filtered (stream, prefix); + fputs_filtered (prefix, stream); name = type_name_no_tag (domain); if (name) fputs_filtered (name, stream); diff --git a/contrib/gdb/gdb/cpu32bug-rom.c b/contrib/gdb/gdb/cpu32bug-rom.c new file mode 100644 index 00000000000..03b31321577 --- /dev/null +++ b/contrib/gdb/gdb/cpu32bug-rom.c @@ -0,0 +1,180 @@ +/* Remote debugging interface for CPU32Bug Rom monitor for GDB, the GNU debugger. + Copyright 1995, 1996, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + + Written by Stu Grossman of Cygnus Support + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "monitor.h" +#include "serial.h" +#include "regcache.h" + +#include "m68k-tdep.h" + +static void cpu32bug_open (char *args, int from_tty); + +static void +cpu32bug_supply_register (char *regname, int regnamelen, char *val, int vallen) +{ + int regno; + + if (regnamelen != 2) + return; + + switch (regname[0]) + { + case 'S': + if (regname[1] != 'R') + return; + regno = PS_REGNUM; + break; + case 'P': + if (regname[1] != 'C') + return; + regno = PC_REGNUM; + break; + case 'D': + if (regname[1] < '0' || regname[1] > '7') + return; + regno = regname[1] - '0' + M68K_D0_REGNUM; + break; + case 'A': + if (regname[1] < '0' || regname[1] > '7') + return; + regno = regname[1] - '0' + M68K_A0_REGNUM; + break; + default: + return; + } + + monitor_supply_register (regno, val); +} + +/* + * This array of registers needs to match the indexes used by GDB. The + * whole reason this exists is because the various ROM monitors use + * different names than GDB does, and don't support all the + * registers either. So, typing "info reg sp" becomes an "A7". + */ + +static const char * +cpu32bug_regname (int index) +{ + static char *regnames[] = + { + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", + "SR", "PC" + }; + + if ((index >= (sizeof (regnames) / sizeof (regnames[0]))) + || (index < 0) || (index >= NUM_REGS)) + return NULL; + else + return regnames[index]; +} + +/* + * Define the monitor command strings. Since these are passed directly + * through to a printf style function, we need can include formatting + * strings. We also need a CR or LF on the end. + */ + +static struct target_ops cpu32bug_ops; + +static char *cpu32bug_inits[] = +{"\r", NULL}; + +static struct monitor_ops cpu32bug_cmds; + +static void +init_cpu32bug_cmds (void) +{ + cpu32bug_cmds.flags = MO_CLR_BREAK_USES_ADDR; + cpu32bug_cmds.init = cpu32bug_inits; /* Init strings */ + cpu32bug_cmds.cont = "g\r"; /* continue command */ + cpu32bug_cmds.step = "t\r"; /* single step */ + cpu32bug_cmds.stop = NULL; /* interrupt command */ + cpu32bug_cmds.set_break = "br %x\r"; /* set a breakpoint */ + cpu32bug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */ + cpu32bug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */ + cpu32bug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */ + cpu32bug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */ + cpu32bug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */ + cpu32bug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */ + cpu32bug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ + cpu32bug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ + cpu32bug_cmds.setmem.term = NULL; /* setreg.term */ + cpu32bug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ + cpu32bug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */ + cpu32bug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */ + cpu32bug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */ + cpu32bug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ + cpu32bug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */ + cpu32bug_cmds.getmem.term = NULL; /* getmem.term */ + cpu32bug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ + cpu32bug_cmds.setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */ + cpu32bug_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ + cpu32bug_cmds.setreg.term = NULL; /* setreg.term */ + cpu32bug_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ + cpu32bug_cmds.getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */ + cpu32bug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */ + cpu32bug_cmds.getreg.term = NULL; /* getreg.term */ + cpu32bug_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ + cpu32bug_cmds.dump_registers = "rd\r"; /* dump_registers */ + cpu32bug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ + cpu32bug_cmds.supply_register = cpu32bug_supply_register; /* supply_register */ + cpu32bug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ + cpu32bug_cmds.load = "lo\r"; /* download command */ + cpu32bug_cmds.loadresp = "\n"; /* load response */ + cpu32bug_cmds.prompt = "CPU32Bug>"; /* monitor command prompt */ + cpu32bug_cmds.line_term = "\r"; /* end-of-line terminator */ + cpu32bug_cmds.cmd_end = NULL; /* optional command terminator */ + cpu32bug_cmds.target = &cpu32bug_ops; /* target operations */ + cpu32bug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ + cpu32bug_cmds.regnames = NULL; /* registers names */ + cpu32bug_cmds.regname = cpu32bug_regname; + cpu32bug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ +}; /* init_cpu32bug_cmds */ + +static void +cpu32bug_open (char *args, int from_tty) +{ + monitor_open (args, &cpu32bug_cmds, from_tty); +} + +extern initialize_file_ftype _initialize_cpu32bug_rom; /* -Wmissing-prototypes */ + +void +_initialize_cpu32bug_rom (void) +{ + init_cpu32bug_cmds (); + init_monitor_ops (&cpu32bug_ops); + + cpu32bug_ops.to_shortname = "cpu32bug"; + cpu32bug_ops.to_longname = "CPU32Bug monitor"; + cpu32bug_ops.to_doc = "Debug via the CPU32Bug monitor.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + cpu32bug_ops.to_open = cpu32bug_open; + + add_target (&cpu32bug_ops); +} diff --git a/contrib/gdb/gdb/dbug-rom.c b/contrib/gdb/gdb/dbug-rom.c index f31555738eb..a592334ea05 100644 --- a/contrib/gdb/gdb/dbug-rom.c +++ b/contrib/gdb/gdb/dbug-rom.c @@ -32,6 +32,8 @@ #include "serial.h" #include "regcache.h" +#include "m68k-tdep.h" + static void dbug_open (char *args, int from_tty); static void @@ -57,12 +59,12 @@ dbug_supply_register (char *regname, int regnamelen, char *val, int vallen) case 'D': if (regname[1] < '0' || regname[1] > '7') return; - regno = regname[1] - '0' + D0_REGNUM; + regno = regname[1] - '0' + M68K_D0_REGNUM; break; case 'A': if (regname[1] < '0' || regname[1] > '7') return; - regno = regname[1] - '0' + A0_REGNUM; + regno = regname[1] - '0' + M68K_A0_REGNUM; break; default: return; @@ -76,13 +78,25 @@ dbug_supply_register (char *regname, int regnamelen, char *val, int vallen) different names than GDB does, and don't support all the registers either. So, typing "info reg sp" becomes an "A7". */ -static char *dbug_regnames[NUM_REGS] = +static const char * +dbug_regname (int index) { - "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", - "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", - "SR", "PC" - /* no float registers */ -}; + static char *regnames[] = + { + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", + "SR", "PC" + /* no float registers */ + }; + + if ((index >= (sizeof (regnames) / sizeof (regnames[0]))) + || (index < 0) || (index >= NUM_REGS)) + return NULL; + else + return regnames[index]; + +} + static struct target_ops dbug_ops; static struct monitor_ops dbug_cmds; @@ -135,7 +149,8 @@ init_dbug_cmds (void) dbug_cmds.cmd_end = NULL; /* optional command terminator */ dbug_cmds.target = &dbug_ops; /* target operations */ dbug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - dbug_cmds.regnames = dbug_regnames; /* registers names */ + dbug_cmds.regnames = NULL; /* registers names */ + dbug_cmds.regname = dbug_regname; dbug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ } /* init_debug_ops */ @@ -145,6 +160,8 @@ dbug_open (char *args, int from_tty) monitor_open (args, &dbug_cmds, from_tty); } +extern initialize_file_ftype _initialize_dbug_rom; /* -Wmissing-prototypes */ + void _initialize_dbug_rom (void) { diff --git a/contrib/gdb/gdb/dbxread.c b/contrib/gdb/gdb/dbxread.c index 16d00434e28..efbbf2ac695 100644 --- a/contrib/gdb/gdb/dbxread.c +++ b/contrib/gdb/gdb/dbxread.c @@ -1,6 +1,6 @@ /* Read dbx symbol tables and convert to internal format, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004. Free Software Foundation, Inc. This file is part of GDB. @@ -42,14 +42,13 @@ #include #endif -#include "obstack.h" +#include "gdb_obstack.h" #include "gdb_stat.h" #include "symtab.h" #include "breakpoint.h" #include "target.h" #include "gdbcore.h" /* for bfd stuff */ #include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */ -#include "symfile.h" #include "objfiles.h" #include "buildsym.h" #include "stabsread.h" @@ -58,32 +57,17 @@ #include "language.h" /* Needed for local_hex_string */ #include "complaints.h" #include "cp-abi.h" +#include "gdb_assert.h" #include "aout/aout64.h" #include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */ -/* This macro returns the size field of a minimal symbol, which is normally - stored in the "info" field. The macro can be overridden for specific - targets (e.g. MIPS16) that use the info field for other purposes. */ -#ifndef MSYMBOL_SIZE -#define MSYMBOL_SIZE(msym) ((long) MSYMBOL_INFO (msym)) -#endif - - /* We put a pointer to this structure in the read_symtab_private field of the psymtab. */ struct symloc { - /* The start (inclusive) and end (exclusive) addresses for this - partial symtab's text. STABS doesn't reliably give us nice - start and end addresses for each function. Instead, we are - told the addresses of various boundary points, and we have to - gather those together to build ranges. These are our running - best guess as to the range of text addresses for this psymtab. */ - CORE_ADDR textlow, texthigh; - /* Offset within the file symbol table of first local symbol for this file. */ @@ -112,8 +96,6 @@ struct symloc #define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff) #define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen) #define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private)) -#define TEXTLOW(p) (SYMLOC(p)->textlow) -#define TEXTHIGH(p) (SYMLOC(p)->texthigh) #define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size) #define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset) #define STRING_OFFSET(p) (SYMLOC(p)->string_offset) @@ -177,33 +159,27 @@ static int has_line_numbers; /* Complaints about the symbols we have encountered. */ -struct complaint lbrac_complaint = -{"bad block start address patched", 0, 0}; +static void +unknown_symtype_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "unknown symbol type %s", arg1); +} -struct complaint string_table_offset_complaint = -{"bad string table offset in symbol %d", 0, 0}; +static void +lbrac_mismatch_complaint (int arg1) +{ + complaint (&symfile_complaints, + "N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", arg1); +} -struct complaint unknown_symtype_complaint = -{"unknown symbol type %s", 0, 0}; +static void +repeated_header_complaint (const char *arg1, int arg2) +{ + complaint (&symfile_complaints, + "\"repeated\" header file %s not previously seen, at symtab pos %d", + arg1, arg2); +} -struct complaint unknown_symchar_complaint = -{"unknown symbol descriptor `%c'", 0, 0}; - -struct complaint lbrac_rbrac_complaint = -{"block start larger than block end", 0, 0}; - -struct complaint lbrac_unmatched_complaint = -{"unmatched N_LBRAC before symtab pos %d", 0, 0}; - -struct complaint lbrac_mismatch_complaint = -{"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", 0, 0}; - -struct complaint repeated_header_complaint = -{"\"repeated\" header file %s not previously seen, at symtab pos %d", 0, 0}; - -struct complaint unclaimed_bincl_complaint = -{"N_BINCL %s not in entries for any file, at symtab pos %d", 0, 0}; - /* find_text_range --- find start and end of loadable code sections The find_text_range function finds the shortest address range that @@ -273,8 +249,6 @@ static int bincls_allocated; extern void _initialize_dbxread (void); -static void process_now (struct objfile *); - static void read_ofile_symtab (struct partial_symtab *); static void dbx_psymtab_to_symtab (struct partial_symtab *); @@ -365,16 +339,16 @@ add_this_object_header_file (int i) static void add_old_header_file (char *name, int instance) { - register struct header_file *p = HEADER_FILES (current_objfile); - register int i; + struct header_file *p = HEADER_FILES (current_objfile); + int i; for (i = 0; i < N_HEADER_FILES (current_objfile); i++) - if (STREQ (p[i].name, name) && instance == p[i].instance) + if (strcmp (p[i].name, name) == 0 && instance == p[i].instance) { add_this_object_header_file (i); return; } - complain (&repeated_header_complaint, name, symnum); + repeated_header_complaint (name, symnum); } /* Add to this file a "new" header file: definitions for its types follow. @@ -391,8 +365,8 @@ add_old_header_file (char *name, int instance) static void add_new_header_file (char *name, int instance) { - register int i; - register struct header_file *hfile; + int i; + struct header_file *hfile; /* Make sure there is room for one more header file. */ @@ -434,7 +408,7 @@ add_new_header_file (char *name, int instance) static struct type ** explicit_lookup_type (int real_filenum, int index) { - register struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum]; + struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum]; if (index >= f->length) { @@ -508,7 +482,7 @@ record_minimal_symbol (char *name, CORE_ADDR address, int type, Record it as global even if it's local, not global, so lookup_minimal_symbol can find it. We don't check symbol_leading_char because for SunOS4 it always is '_'. */ - if (name[8] == 'C' && STREQ ("__DYNAMIC", name)) + if (name[8] == 'C' && DEPRECATED_STREQ ("__DYNAMIC", name)) ms_type = mst_data; /* Same with virtual function tables, both global and static. */ @@ -604,19 +578,6 @@ dbx_symfile_read (struct objfile *objfile, int mainline) read_dbx_dynamic_symtab (objfile); - /* Take the text ranges the STABS partial symbol scanner computed - for each of the psymtabs and convert it into the canonical form - for psymtabs. */ - { - struct partial_symtab *p; - - ALL_OBJFILE_PSYMTABS (objfile, p) - { - p->textlow = TEXTLOW (p); - p->texthigh = TEXTHIGH (p); - } - } - /* Install any minimal symbols that have been collected as the current minimal symbols for this objfile. */ @@ -665,7 +626,7 @@ dbx_symfile_init (struct objfile *objfile) /* Allocate struct to keep track of the symfile */ objfile->sym_stab_info = (struct dbx_symfile_info *) xmmalloc (objfile->md, sizeof (struct dbx_symfile_info)); - memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info)); + memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info)); DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".text"); DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".data"); @@ -689,14 +650,13 @@ dbx_symfile_init (struct objfile *objfile) DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd); DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET; - /* Read the string table and stash it away in the psymbol_obstack. It is - only needed as long as we need to expand psymbols into full symbols, - so when we blow away the psymbol the string table goes away as well. + /* Read the string table and stash it away in the objfile_obstack. + When we blow away the objfile the string table goes away as well. Note that gdb used to use the results of attempting to malloc the string table, based on the size it read, as a form of sanity check for botched byte swapping, on the theory that a byte swapped string table size would be so totally bogus that the malloc would fail. Now - that we put in on the psymbol_obstack, we can't do this since gdb gets + that we put in on the objfile_obstack, we can't do this since gdb gets a fatal error (out of virtual memory) if the size is bogus. We can however at least check to see if the size is less than the size of the size field itself, or larger than the size of the entire file. @@ -717,8 +677,8 @@ dbx_symfile_init (struct objfile *objfile) if (val < 0) perror_with_name (name); - memset ((PTR) size_temp, 0, sizeof (size_temp)); - val = bfd_bread ((PTR) size_temp, sizeof (size_temp), sym_bfd); + memset (size_temp, 0, sizeof (size_temp)); + val = bfd_bread (size_temp, sizeof (size_temp), sym_bfd); if (val < 0) { perror_with_name (name); @@ -748,7 +708,7 @@ dbx_symfile_init (struct objfile *objfile) DBX_STRINGTAB_SIZE (objfile)); DBX_STRINGTAB (objfile) = - (char *) obstack_alloc (&objfile->psymbol_obstack, + (char *) obstack_alloc (&objfile->objfile_obstack, DBX_STRINGTAB_SIZE (objfile)); OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile)); @@ -778,8 +738,8 @@ dbx_symfile_finish (struct objfile *objfile) { if (HEADER_FILES (objfile) != NULL) { - register int i = N_HEADER_FILES (objfile); - register struct header_file *hfiles = HEADER_FILES (objfile); + int i = N_HEADER_FILES (objfile); + struct header_file *hfiles = HEADER_FILES (objfile); while (--i >= 0) { @@ -799,106 +759,6 @@ static struct external_nlist symbuf[4096]; static int symbuf_idx; static int symbuf_end; -/* cont_elem is used for continuing information in cfront. - It saves information about which types need to be fixed up and - completed after all the stabs are read. */ -struct cont_elem - { - /* sym and stabstring for continuing information in cfront */ - struct symbol *sym; - char *stabs; - /* state dependencies (statics that must be preserved) */ - int sym_idx; - int sym_end; - int symnum; - int (*func) (struct objfile *, struct symbol *, char *); - /* other state dependencies include: - (assumption is that these will not change since process_now FIXME!!) - stringtab_global - n_stabs - objfile - symfile_bfd */ - }; - -static struct cont_elem *cont_list = 0; -static int cont_limit = 0; -static int cont_count = 0; - -/* Arrange for function F to be called with arguments SYM and P later - in the stabs reading process. */ -void -process_later (struct symbol *sym, char *p, - int (*f) (struct objfile *, struct symbol *, char *)) -{ - - /* Allocate more space for the deferred list. */ - if (cont_count >= cont_limit - 1) - { - cont_limit += 32; /* chunk size */ - - cont_list - = (struct cont_elem *) xrealloc (cont_list, - (cont_limit - * sizeof (struct cont_elem))); - if (!cont_list) - error ("Virtual memory exhausted\n"); - } - - /* Save state variables so we can process these stabs later. */ - cont_list[cont_count].sym_idx = symbuf_idx; - cont_list[cont_count].sym_end = symbuf_end; - cont_list[cont_count].symnum = symnum; - cont_list[cont_count].sym = sym; - cont_list[cont_count].stabs = p; - cont_list[cont_count].func = f; - cont_count++; -} - -/* Call deferred funtions in CONT_LIST. */ - -static void -process_now (struct objfile *objfile) -{ - int i; - int save_symbuf_idx; - int save_symbuf_end; - int save_symnum; - struct symbol *sym; - char *stabs; - int err; - int (*func) (struct objfile *, struct symbol *, char *); - - /* Save the state of our caller, we'll want to restore it before - returning. */ - save_symbuf_idx = symbuf_idx; - save_symbuf_end = symbuf_end; - save_symnum = symnum; - - /* Iterate over all the deferred stabs. */ - for (i = 0; i < cont_count; i++) - { - /* Restore the state for this deferred stab. */ - symbuf_idx = cont_list[i].sym_idx; - symbuf_end = cont_list[i].sym_end; - symnum = cont_list[i].symnum; - sym = cont_list[i].sym; - stabs = cont_list[i].stabs; - func = cont_list[i].func; - - /* Call the function to handle this deferrd stab. */ - err = (*func) (objfile, sym, stabs); - if (err) - error ("Internal error: unable to resolve stab.\n"); - } - - /* Restore our caller's state. */ - symbuf_idx = save_symbuf_idx; - symbuf_end = save_symbuf_end; - symnum = save_symnum; - cont_count = 0; -} - - /* Name of last function encountered. Used in Solaris to approximate object file boundaries. */ static char *last_function_name; @@ -919,6 +779,10 @@ static struct stab_section_list *symbuf_sections; static unsigned int symbuf_left; static unsigned int symbuf_read; +/* This variable stores a global stabs buffer, if we read stabs into + memory in one chunk in order to process relocations. */ +static bfd_byte *stabs_data; + /* Refill the symbol table input buffer and set the variables that control fetching entries from it. Reports an error if no data available. @@ -931,8 +795,18 @@ fill_symbuf (bfd *sym_bfd) unsigned int count; int nbytes; - if (symbuf_sections == NULL) - count = sizeof (symbuf); + if (stabs_data) + { + nbytes = sizeof (symbuf); + if (nbytes > symbuf_left) + nbytes = symbuf_left; + memcpy (symbuf, stabs_data + symbuf_read, nbytes); + } + else if (symbuf_sections == NULL) + { + count = sizeof (symbuf); + nbytes = bfd_bread (symbuf, count, sym_bfd); + } else { if (symbuf_left <= 0) @@ -948,9 +822,9 @@ fill_symbuf (bfd *sym_bfd) count = symbuf_left; if (count > sizeof (symbuf)) count = sizeof (symbuf); + nbytes = bfd_bread (symbuf, count, sym_bfd); } - nbytes = bfd_bread ((PTR) symbuf, count, sym_bfd); if (nbytes < 0) perror_with_name (bfd_get_filename (sym_bfd)); else if (nbytes == 0) @@ -961,6 +835,18 @@ fill_symbuf (bfd *sym_bfd) symbuf_read += nbytes; } +static void +stabs_seek (int sym_offset) +{ + if (stabs_data) + { + symbuf_read += sym_offset; + symbuf_left -= sym_offset; + } + else + bfd_seek (symfile_bfd, sym_offset, SEEK_CUR); +} + #define INTERNALIZE_SYMBOL(intern, extern, abfd) \ { \ (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \ @@ -1039,10 +925,10 @@ find_corresponding_bincl_psymtab (char *name, int instance) for (bincl = bincl_list; bincl < next_bincl; bincl++) if (bincl->instance == instance - && STREQ (name, bincl->name)) + && strcmp (name, bincl->name) == 0) return bincl->pst; - complain (&repeated_header_complaint, name, symnum); + repeated_header_complaint (name, symnum); return (struct partial_symtab *) 0; } @@ -1051,7 +937,7 @@ find_corresponding_bincl_psymtab (char *name, int instance) static void free_bincl_list (struct objfile *objfile) { - xmfree (objfile->md, (PTR) bincl_list); + xmfree (objfile->md, bincl_list); bincls_allocated = 0; } @@ -1079,7 +965,8 @@ set_namestring (struct objfile *objfile, struct internal_nlist nlist) if (((unsigned) nlist.n_strx + file_string_table_offset) >= DBX_STRINGTAB_SIZE (objfile)) { - complain (&string_table_offset_complaint, symnum); + complaint (&symfile_complaints, "bad string table offset in symbol %d", + symnum); namestring = ""; } else @@ -1230,18 +1117,72 @@ read_dbx_dynamic_symtab (struct objfile *objfile) do_cleanups (back_to); } +#ifdef SOFUN_ADDRESS_MAYBE_MISSING +static CORE_ADDR +find_stab_function_addr (char *namestring, char *filename, + struct objfile *objfile) +{ + struct minimal_symbol *msym; + char *p; + int n; + + p = strchr (namestring, ':'); + if (p == NULL) + p = namestring; + n = p - namestring; + p = alloca (n + 2); + strncpy (p, namestring, n); + p[n] = 0; + + msym = lookup_minimal_symbol (p, filename, objfile); + if (msym == NULL) + { + /* Sun Fortran appends an underscore to the minimal symbol name, + try again with an appended underscore if the minimal symbol + was not found. */ + p[n] = '_'; + p[n + 1] = 0; + msym = lookup_minimal_symbol (p, filename, objfile); + } + + if (msym == NULL && filename != NULL) + { + /* Try again without the filename. */ + p[n] = 0; + msym = lookup_minimal_symbol (p, NULL, objfile); + } + if (msym == NULL && filename != NULL) + { + /* And try again for Sun Fortran, but without the filename. */ + p[n] = '_'; + p[n + 1] = 0; + msym = lookup_minimal_symbol (p, NULL, objfile); + } + + return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym); +} +#endif /* SOFUN_ADDRESS_MAYBE_MISSING */ + +static void +function_outside_compilation_unit_complaint (const char *arg1) +{ + complaint (&symfile_complaints, + "function `%s' appears to be defined outside of all compilation units", + arg1); +} + /* Setup partial_symtab's describing each source file for which debugging information is available. */ static void read_dbx_symtab (struct objfile *objfile) { - register struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */ + struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */ struct internal_nlist nlist; CORE_ADDR text_addr; int text_size; - register char *namestring; + char *namestring; int nsl; int past_first_source_file = 0; CORE_ADDR last_o_file_start = 0; @@ -1249,6 +1190,7 @@ read_dbx_symtab (struct objfile *objfile) struct cleanup *back_to; bfd *abfd; int textlow_not_set; + int data_sect_index; /* Current partial symtab */ struct partial_symtab *pst; @@ -1300,6 +1242,38 @@ read_dbx_symtab (struct objfile *objfile) textlow_not_set = 1; has_line_numbers = 0; + /* FIXME: jimb/2003-09-12: We don't apply the right section's offset + to global and static variables. The stab for a global or static + variable doesn't give us any indication of which section it's in, + so we can't tell immediately which offset in + objfile->section_offsets we should apply to the variable's + address. + + We could certainly find out which section contains the variable + by looking up the variable's unrelocated address with + find_pc_section, but that would be expensive; this is the + function that constructs the partial symbol tables by examining + every symbol in the entire executable, and it's + performance-critical. So that expense would not be welcome. I'm + not sure what to do about this at the moment. + + What we have done for years is to simply assume that the .data + section's offset is appropriate for all global and static + variables. Recently, this was expanded to fall back to the .bss + section's offset if there is no .data section, and then to the + .rodata section's offset. */ + data_sect_index = objfile->sect_index_data; + if (data_sect_index == -1) + data_sect_index = SECT_OFF_BSS (objfile); + if (data_sect_index == -1) + data_sect_index = SECT_OFF_RODATA (objfile); + + /* If data_sect_index is still -1, that's okay. It's perfectly fine + for the file to have no .data, no .bss, and no .text at all, if + it also has no global or static variables. If it does, we will + get an internal error from an ANOFFSET macro below when we try to + use data_sect_index. */ + for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++) { /* Get the symbol for this run and pull out some info */ @@ -1334,9 +1308,6 @@ read_dbx_symtab (struct objfile *objfile) switch (nlist.n_type) { - static struct complaint function_outside_compilation_unit = { - "function `%s' appears to be defined outside of all compilation units", 0, 0 - }; char *p; /* * Standard, external, non-debugger, symbols @@ -1390,18 +1361,18 @@ read_dbx_symtab (struct objfile *objfile) if (objfile->ei.entry_point < nlist.n_value && objfile->ei.entry_point >= last_o_file_start) { - objfile->ei.entry_file_lowpc = last_o_file_start; - objfile->ei.entry_file_highpc = nlist.n_value; + objfile->ei.deprecated_entry_file_lowpc = last_o_file_start; + objfile->ei.deprecated_entry_file_highpc = nlist.n_value; } if (past_first_source_file && pst /* The gould NP1 uses low values for .o and -l symbols which are not the address. */ - && nlist.n_value >= TEXTLOW (pst)) + && nlist.n_value >= pst->textlow) { end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, - nlist.n_value > TEXTHIGH (pst) - ? nlist.n_value : TEXTHIGH (pst), + nlist.n_value > pst->texthigh + ? nlist.n_value : pst->texthigh, dependency_list, dependencies_used, textlow_not_set); pst = (struct partial_symtab *) 0; includes_used = 0; @@ -1523,7 +1494,7 @@ read_dbx_symtab (struct objfile *objfile) { end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, - valu > TEXTHIGH (pst) ? valu : TEXTHIGH (pst), + valu > pst->texthigh ? valu : pst->texthigh, dependency_list, dependencies_used, prev_textlow_not_set); pst = (struct partial_symtab *) 0; @@ -1587,7 +1558,9 @@ read_dbx_symtab (struct objfile *objfile) { /* FIXME: we should not get here without a PST to work on. Attempt to recover. */ - complain (&unclaimed_bincl_complaint, namestring, symnum); + complaint (&symfile_complaints, + "N_BINCL %s not in entries for any file, at symtab pos %d", + namestring, symnum); continue; } add_bincl_to_list (pst, namestring, nlist.n_value); @@ -1624,12 +1597,12 @@ read_dbx_symtab (struct objfile *objfile) things like "break c-exp.y:435" need to work (I suppose the psymtab_include_list could be hashed or put in a binary tree, if profiling shows this is a major hog). */ - if (pst && STREQ (namestring, pst->filename)) + if (pst && strcmp (namestring, pst->filename) == 0) continue; { - register int i; + int i; for (i = 0; i < includes_used; i++) - if (STREQ (namestring, psymtab_include_list[i])) + if (strcmp (namestring, psymtab_include_list[i]) == 0) { i = -1; break; @@ -1648,7 +1621,7 @@ read_dbx_symtab (struct objfile *objfile) psymtab_include_list = (char **) alloca ((includes_allocated *= 2) * sizeof (char *)); - memcpy ((PTR) psymtab_include_list, (PTR) orig, + memcpy (psymtab_include_list, orig, includes_used * sizeof (char *)); } continue; @@ -1682,8 +1655,8 @@ read_dbx_symtab (struct objfile *objfile) function relative stabs, or the address of the function's end for old style stabs. */ valu = nlist.n_value + last_function_start; - if (TEXTHIGH (pst) == 0 || valu > TEXTHIGH (pst)) - TEXTHIGH (pst) = valu; + if (pst->texthigh == 0 || valu > pst->texthigh) + pst->texthigh = valu; break; } @@ -1703,22 +1676,22 @@ read_dbx_symtab (struct objfile *objfile) switch (p[1]) { case 'S': - nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)); + nlist.n_value += ANOFFSET (objfile->section_offsets, data_sect_index); #ifdef STATIC_TRANSFORM_NAME namestring = STATIC_TRANSFORM_NAME (namestring); #endif add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, + VAR_DOMAIN, LOC_STATIC, &objfile->static_psymbols, 0, nlist.n_value, psymtab_language, objfile); continue; case 'G': - nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)); + nlist.n_value += ANOFFSET (objfile->section_offsets, data_sect_index); /* The addresses in these entries are reported to be wrong. See the code that reads 'G's for symtabs. */ add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, + VAR_DOMAIN, LOC_STATIC, &objfile->global_psymbols, 0, nlist.n_value, psymtab_language, objfile); @@ -1736,7 +1709,7 @@ read_dbx_symtab (struct objfile *objfile) && namestring[0] != ' ')) { add_psymbol_to_list (namestring, p - namestring, - STRUCT_NAMESPACE, LOC_TYPEDEF, + STRUCT_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, nlist.n_value, 0, psymtab_language, objfile); @@ -1744,33 +1717,19 @@ read_dbx_symtab (struct objfile *objfile) { /* Also a typedef with the same name. */ add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, nlist.n_value, 0, psymtab_language, objfile); p += 1; } - /* The semantics of C++ state that "struct foo { ... }" - also defines a typedef for "foo". Unfortuantely, cfront - never makes the typedef when translating from C++ to C. - We make the typedef here so that "ptype foo" works as - expected for cfront translated code. */ - else if (psymtab_language == language_cplus) - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - nlist.n_value, 0, - psymtab_language, objfile); - } } goto check_enum; case 't': if (p != namestring) /* a name is there, not just :T... */ { add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, nlist.n_value, 0, psymtab_language, objfile); @@ -1832,7 +1791,7 @@ read_dbx_symtab (struct objfile *objfile) /* Note that the value doesn't matter for enum constants in psymtabs, just in symtabs. */ add_psymbol_to_list (p, q - p, - VAR_NAMESPACE, LOC_CONST, + VAR_DOMAIN, LOC_CONST, &objfile->static_psymbols, 0, 0, psymtab_language, objfile); /* Point past the name. */ @@ -1849,7 +1808,7 @@ read_dbx_symtab (struct objfile *objfile) case 'c': /* Constant, e.g. from "const" in Pascal. */ add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, + VAR_DOMAIN, LOC_CONST, &objfile->static_psymbols, nlist.n_value, 0, psymtab_language, objfile); continue; @@ -1861,7 +1820,7 @@ read_dbx_symtab (struct objfile *objfile) char *name = xmalloc (name_len + 1); memcpy (name, namestring, name_len); name[name_len] = '\0'; - complain (&function_outside_compilation_unit, name); + function_outside_compilation_unit_complaint (name); xfree (name); } nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -1885,7 +1844,7 @@ read_dbx_symtab (struct objfile *objfile) } if (pst && textlow_not_set) { - TEXTLOW (pst) = nlist.n_value; + pst->textlow = nlist.n_value; textlow_not_set = 0; } #endif @@ -1901,16 +1860,16 @@ read_dbx_symtab (struct objfile *objfile) the partial symbol table. */ if (pst && (textlow_not_set - || (nlist.n_value < TEXTLOW (pst) + || (nlist.n_value < pst->textlow && (nlist.n_value != ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))))) { - TEXTLOW (pst) = nlist.n_value; + pst->textlow = nlist.n_value; textlow_not_set = 0; } add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->static_psymbols, 0, nlist.n_value, psymtab_language, objfile); @@ -1926,7 +1885,7 @@ read_dbx_symtab (struct objfile *objfile) char *name = xmalloc (name_len + 1); memcpy (name, namestring, name_len); name[name_len] = '\0'; - complain (&function_outside_compilation_unit, name); + function_outside_compilation_unit_complaint (name); xfree (name); } nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -1950,7 +1909,7 @@ read_dbx_symtab (struct objfile *objfile) } if (pst && textlow_not_set) { - TEXTLOW (pst) = nlist.n_value; + pst->textlow = nlist.n_value; textlow_not_set = 0; } #endif @@ -1966,16 +1925,16 @@ read_dbx_symtab (struct objfile *objfile) the partial symbol table. */ if (pst && (textlow_not_set - || (nlist.n_value < TEXTLOW (pst) + || (nlist.n_value < pst->textlow && (nlist.n_value != ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))))) { - TEXTLOW (pst) = nlist.n_value; + pst->textlow = nlist.n_value; textlow_not_set = 0; } add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->global_psymbols, 0, nlist.n_value, psymtab_language, objfile); @@ -1998,9 +1957,6 @@ read_dbx_symtab (struct objfile *objfile) case '9': case '-': case '#': /* for symbol identification (used in live ranges) */ - /* added to support cfront stabs strings */ - case 'Z': /* for definition continuations */ - case 'P': /* for prototypes */ continue; case ':': @@ -2021,7 +1977,8 @@ read_dbx_symtab (struct objfile *objfile) time searching to the end of every string looking for a backslash. */ - complain (&unknown_symchar_complaint, p[1]); + complaint (&symfile_complaints, "unknown symbol descriptor `%c'", + p[1]); /* Ignore it; perhaps it is an extension that we don't know about. */ @@ -2067,7 +2024,7 @@ read_dbx_symtab (struct objfile *objfile) (struct partial_symtab **) alloca ((dependencies_allocated *= 2) * sizeof (struct partial_symtab *)); - memcpy ((PTR) dependency_list, (PTR) orig, + memcpy (dependency_list, orig, (dependencies_used * sizeof (struct partial_symtab *))); #ifdef DEBUG_INFO @@ -2083,7 +2040,7 @@ read_dbx_symtab (struct objfile *objfile) case N_ENDM: #ifdef SOFUN_ADDRESS_MAYBE_MISSING /* Solaris 2 end of module, finish current partial symbol table. - end_psymtab will set TEXTHIGH (pst) to the proper value, which + end_psymtab will set pst->texthigh to the proper value, which is necessary if a module compiled without debugging info follows this module. */ if (pst) @@ -2128,6 +2085,7 @@ read_dbx_symtab (struct objfile *objfile) case N_OBJ: /* useless types from Solaris */ case N_OPT: + case N_PATCH: /* These symbols aren't interesting; don't worry about them */ continue; @@ -2135,8 +2093,7 @@ read_dbx_symtab (struct objfile *objfile) default: /* If we haven't found it yet, ignore it. It's probably some new type we don't know about yet. */ - complain (&unknown_symtype_complaint, - local_hex_string (nlist.n_type)); + unknown_symtype_complaint (local_hex_string (nlist.n_type)); continue; } } @@ -2148,8 +2105,8 @@ read_dbx_symtab (struct objfile *objfile) && objfile->ei.entry_point < nlist.n_value && objfile->ei.entry_point >= last_o_file_start) { - objfile->ei.entry_file_lowpc = last_o_file_start; - objfile->ei.entry_file_highpc = nlist.n_value; + objfile->ei.deprecated_entry_file_lowpc = last_o_file_start; + objfile->ei.deprecated_entry_file_highpc = nlist.n_value; } if (pst) @@ -2163,7 +2120,7 @@ read_dbx_symtab (struct objfile *objfile) end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, - text_end > TEXTHIGH (pst) ? text_end : TEXTHIGH (pst), + text_end > pst->texthigh ? text_end : pst->texthigh, dependency_list, dependencies_used, textlow_not_set); } @@ -2188,9 +2145,7 @@ start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow, filename, textlow, global_syms, static_syms); result->read_symtab_private = (char *) - obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc)); - TEXTLOW (result) = result->textlow; - TEXTHIGH (result) = result->texthigh; + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc)); LDSYMOFF (result) = ldsymoff; result->read_symtab = dbx_psymtab_to_symtab; SYMBOL_SIZE (result) = symbol_size; @@ -2226,7 +2181,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes, if (capping_symbol_offset != -1) LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst); - TEXTHIGH (pst) = capping_text; + pst->texthigh = capping_text; #ifdef SOFUN_ADDRESS_MAYBE_MISSING /* Under Solaris, the N_SO symbols always have a value of 0, @@ -2244,7 +2199,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes, a reliable texthigh by taking the address plus size of the last function in the file. */ - if (TEXTHIGH (pst) == 0 && last_function_name) + if (pst->texthigh == 0 && last_function_name) { char *p; int n; @@ -2270,14 +2225,14 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes, } if (minsym) - TEXTHIGH (pst) = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym); + pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym); last_function_name = NULL; } /* this test will be true if the last .o file is only data */ if (textlow_not_set) - TEXTLOW (pst) = TEXTHIGH (pst); + pst->textlow = pst->texthigh; else { struct partial_symtab *p1; @@ -2290,12 +2245,12 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes, ALL_OBJFILE_PSYMTABS (objfile, p1) { - if (TEXTHIGH (p1) == 0 && TEXTLOW (p1) != 0 && p1 != pst) + if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst) { - TEXTHIGH (p1) = TEXTLOW (pst); + p1->texthigh = pst->textlow; /* if this file has only data, then make textlow match texthigh */ - if (TEXTLOW (p1) == 0) - TEXTLOW (p1) = TEXTHIGH (p1); + if (p1->textlow == 0) + p1->textlow = p1->texthigh; } } } @@ -2312,7 +2267,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes, if (number_dependencies) { pst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, number_dependencies * sizeof (struct partial_symtab *)); memcpy (pst->dependencies, dependency_list, number_dependencies * sizeof (struct partial_symtab *)); @@ -2328,17 +2283,17 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes, /* Copy the sesction_offsets array from the main psymtab. */ subpst->section_offsets = pst->section_offsets; subpst->read_symtab_private = - (char *) obstack_alloc (&objfile->psymbol_obstack, + (char *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc)); LDSYMOFF (subpst) = LDSYMLEN (subpst) = - TEXTLOW (subpst) = - TEXTHIGH (subpst) = 0; + subpst->textlow = + subpst->texthigh = 0; /* We could save slight bits of space by only making one of these, shared by the entire set of include files. FIXME-someday. */ subpst->dependencies = (struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct partial_symtab *)); subpst->dependencies[0] = pst; subpst->number_of_dependencies = 1; @@ -2428,7 +2383,6 @@ dbx_psymtab_to_symtab_1 (struct partial_symtab *pst) /* Read in this file's symbols */ bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET); read_ofile_symtab (pst); - sort_symtab_syms (pst->symtab); do_cleanups (old_chain); } @@ -2443,6 +2397,7 @@ static void dbx_psymtab_to_symtab (struct partial_symtab *pst) { bfd *sym_bfd; + struct cleanup *back_to = NULL; if (!pst) return; @@ -2468,8 +2423,21 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst) next_symbol_text_func = dbx_next_symbol_text; + if (DBX_STAB_SECTION (pst->objfile)) + { + stabs_data + = symfile_relocate_debug_section (pst->objfile->obfd, + DBX_STAB_SECTION (pst->objfile), + NULL); + if (stabs_data) + back_to = make_cleanup (free_current_contents, (void *) &stabs_data); + } + dbx_psymtab_to_symtab_1 (pst); + if (back_to) + do_cleanups (back_to); + /* Match with global symbols. This only needs to be done once, after all of the symtabs and dependencies have been read in. */ scan_file_globals (pst->objfile); @@ -2485,12 +2453,12 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst) static void read_ofile_symtab (struct partial_symtab *pst) { - register char *namestring; - register struct external_nlist *bufp; + char *namestring; + struct external_nlist *bufp; struct internal_nlist nlist; unsigned char type; unsigned max_symnum; - register bfd *abfd; + bfd *abfd; struct objfile *objfile; int sym_offset; /* Offset to start of symbols to read */ int sym_size; /* Size of symbols to read */ @@ -2501,8 +2469,8 @@ read_ofile_symtab (struct partial_symtab *pst) objfile = pst->objfile; sym_offset = LDSYMOFF (pst); sym_size = LDSYMLEN (pst); - text_offset = TEXTLOW (pst); - text_size = TEXTHIGH (pst) - TEXTLOW (pst); + text_offset = pst->textlow; + text_size = pst->texthigh - pst->textlow; /* This cannot be simply objfile->section_offsets because of elfstab_offset_sections() which initializes the psymtab section offsets information in a special way, and that is different from @@ -2518,6 +2486,8 @@ read_ofile_symtab (struct partial_symtab *pst) abfd = objfile->obfd; symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */ symbuf_end = symbuf_idx = 0; + symbuf_read = 0; + symbuf_left = sym_offset + sym_size; /* It is necessary to actually read one symbol *before* the start of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL @@ -2527,7 +2497,7 @@ read_ofile_symtab (struct partial_symtab *pst) would slow down initial readin, so we look for it here instead. */ if (!processing_acc_compilation && sym_offset >= (int) symbol_size) { - bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR); + stabs_seek (sym_offset - symbol_size); fill_symbuf (abfd); bufp = &symbuf[symbuf_idx++]; INTERNALIZE_SYMBOL (nlist, bufp, abfd); @@ -2540,13 +2510,13 @@ read_ofile_symtab (struct partial_symtab *pst) { const char *tempstring = namestring; - if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) + if (DEPRECATED_STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) processing_gcc_compilation = 1; - else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL)) + else if (DEPRECATED_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)) + if (DEPRECATED_STREQN (tempstring, "__gnu_compiled", 14)) processing_gcc_compilation = 2; } @@ -2570,7 +2540,7 @@ read_ofile_symtab (struct partial_symtab *pst) /* The N_SO starting this symtab is the first symbol, so we better not check the symbol before it. I'm not this can happen, but it doesn't hurt to check for it. */ - bfd_seek (symfile_bfd, sym_offset, SEEK_CUR); + stabs_seek (sym_offset); processing_gcc_compilation = 0; } @@ -2612,9 +2582,9 @@ read_ofile_symtab (struct partial_symtab *pst) However, there is no reason not to accept the GCC_COMPILED_FLAG_SYMBOL anywhere. */ - if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) + if (DEPRECATED_STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) processing_gcc_compilation = 1; - else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL)) + else if (DEPRECATED_STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL)) processing_gcc_compilation = 2; #if 0 @@ -2647,22 +2617,18 @@ read_ofile_symtab (struct partial_symtab *pst) /* In a Solaris elf file, this variable, which comes from the value of the N_SO symbol, will still be 0. Luckily, text_offset, - which comes from TEXTLOW (pst) is correct. */ + which comes from pst->textlow is correct. */ if (last_source_start_addr == 0) last_source_start_addr = text_offset; /* In reordered executables last_source_start_addr may not be the lower bound for this symtab, instead use text_offset which comes - from TEXTLOW (pst) which is correct. */ + from pst->textlow which is correct. */ if (last_source_start_addr > text_offset) last_source_start_addr = text_offset; pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile)); - /* Process items which we had to "process_later" due to dependencies - on other stabs. */ - process_now (objfile); - end_stabs (); } @@ -2699,7 +2665,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, static CORE_ADDR last_pc_address; #endif - register struct context_stack *new; + struct context_stack *new; /* This remembers the address of the start of a function. It is used because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are relative to the current function's start address. On systems @@ -2711,9 +2677,10 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, peculiarities of function_start_offset. */ static CORE_ADDR last_function_start; - /* If this is nonzero, we've seen an N_SLINE since the start of the current - function. Initialized to nonzero to assure that last_function_start - is never used uninitialized. */ + /* If this is nonzero, we've seen an N_SLINE since the start of the + current function. We use this to tell us to move the first sline + to the beginning of the function regardless of what its given + value is. */ static int sline_found_in_function = 1; /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source @@ -2750,7 +2717,20 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, { /* This N_FUN marks the end of a function. This closes off the current block. */ - record_line (current_subfile, 0, function_start_offset + valu); + + if (context_stack_depth <= 0) + { + lbrac_mismatch_complaint (symnum); + break; + } + + /* The following check is added before recording line 0 at + end of function so as to handle hand-generated stabs + which may have an N_FUN stabs at the end of the function, but + no N_SLINE stabs. */ + if (sline_found_in_function) + record_line (current_subfile, 0, last_function_start + valu); + within_function = 0; new = pop_context (); @@ -2796,7 +2776,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address) { /* Patch current LBRAC pc value to match last handy pc value */ - complain (&lbrac_complaint); + complaint (&symfile_complaints, "bad block start address patched"); valu = last_pc_address; } #endif @@ -2819,9 +2799,15 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, N_SO, the linker did not relocate them (sigh). */ valu += last_source_start_addr; + if (context_stack_depth <= 0) + { + lbrac_mismatch_complaint (symnum); + break; + } + new = pop_context (); if (desc != new->depth) - complain (&lbrac_mismatch_complaint, symnum); + lbrac_mismatch_complaint (symnum); /* Some compilers put the variable decls inside of an LBRAC/RBRAC block. This macro should be nonzero if this @@ -2835,7 +2821,22 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, /* Can only use new->locals as local symbols here if we're in gcc or on a machine that puts them before the lbrack. */ if (!VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation)) - local_symbols = new->locals; + { + if (local_symbols != NULL) + { + /* GCC development snapshots from March to December of + 2000 would output N_LSYM entries after N_LBRAC + entries. As a consequence, these symbols are simply + discarded. Complain if this is the case. Note that + there are some compilers which legitimately put local + symbols within an LBRAC/RBRAC block; this complaint + might also help sort out problems in which + VARIABLES_INSIDE_BLOCK is incorrectly defined. */ + complaint (&symfile_complaints, + "misplaced N_LBRAC entry; discarding local symbols which have no enclosing block"); + } + local_symbols = new->locals; + } if (context_stack_depth > !VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation)) @@ -2852,7 +2853,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, compilers? Is this ever harmful?). */ if (new->start_addr > valu) { - complain (&lbrac_rbrac_complaint); + complaint (&symfile_complaints, + "block start larger than block end"); new->start_addr = valu; } /* Make a block for the local symbols within. */ @@ -3076,7 +3078,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, case N_NBBSS: case N_NBSTS: case N_NBLCS: - complain (&unknown_symtype_complaint, local_hex_string (type)); + unknown_symtype_complaint (local_hex_string (type)); /* FALLTHROUGH */ /* The following symbol types don't need the address field relocated, @@ -3158,13 +3160,13 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, int l = colon_pos - name; m = lookup_minimal_symbol_by_pc (last_pc_address); - if (m && STREQN (SYMBOL_NAME (m), name, l) - && SYMBOL_NAME (m)[l] == '\0') + if (m && strncmp (DEPRECATED_SYMBOL_NAME (m), name, l) == 0 + && DEPRECATED_SYMBOL_NAME (m)[l] == '\0') /* last_pc_address was in this function */ valu = SYMBOL_VALUE (m); - else if (m && SYMBOL_NAME (m + 1) - && STREQN (SYMBOL_NAME (m + 1), name, l) - && SYMBOL_NAME (m + 1)[l] == '\0') + else if (m && DEPRECATED_SYMBOL_NAME (m + 1) + && strncmp (DEPRECATED_SYMBOL_NAME (m + 1), name, l) == 0 + && DEPRECATED_SYMBOL_NAME (m + 1)[l] == '\0') /* last_pc_address was in last function */ valu = SYMBOL_VALUE (m + 1); else @@ -3188,7 +3190,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, if (context_stack_depth > 1) { - complain (&lbrac_unmatched_complaint, symnum); + complaint (&symfile_complaints, + "unmatched N_LBRAC before symtab pos %d", symnum); break; } @@ -3217,7 +3220,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, case N_OPT: /* Solaris 2: Compiler options */ if (name) { - if (STREQ (name, GCC2_COMPILED_FLAG_SYMBOL)) + if (strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0) { processing_gcc_compilation = 2; #if 0 /* Works, but is experimental. -fnf */ @@ -3249,6 +3252,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, /* The following symbol types can be ignored. */ case N_OBJ: /* Solaris 2: Object file dir and name */ + case N_PATCH: /* Solaris2: Patch Run Time Checker. */ /* N_UNDF: Solaris 2: file separator mark */ /* N_UNDF: -- we will never encounter it, since we only process one file's symbols at once. */ @@ -3338,7 +3342,7 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline, if (stabstrsize > bfd_get_size (sym_bfd)) error ("ridiculous string table size: %d bytes", stabstrsize); DBX_STRINGTAB (objfile) = (char *) - obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1); + obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1); OBJSTAT (objfile, sz_strtab += stabstrsize + 1); /* Now read in the string table in one big gulp. */ @@ -3399,8 +3403,7 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline, 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). - STABOFFSET and STABSIZE define the location in OBJFILE where the .stab - section exists. + STABSECT is the BFD section information for the .stab section. STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the .stabstr section exists. @@ -3409,13 +3412,14 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline, void elfstab_build_psymtabs (struct objfile *objfile, int mainline, - file_ptr staboffset, unsigned int stabsize, + asection *stabsect, file_ptr stabstroffset, unsigned int stabstrsize) { int val; bfd *sym_bfd = objfile->obfd; char *name = bfd_get_filename (sym_bfd); struct dbx_symfile_info *info; + struct cleanup *back_to = NULL; /* There is already a dbx_symfile_info allocated by our caller. It might even contain some info from the ELF symtab to help us. */ @@ -3427,14 +3431,16 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline, #define ELF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */ DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE; - DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile); + DBX_SYMCOUNT (objfile) + = bfd_section_size (objfile->obfd, stabsect) / DBX_SYMBOL_SIZE (objfile); DBX_STRINGTAB_SIZE (objfile) = stabstrsize; - DBX_SYMTAB_OFFSET (objfile) = staboffset; + DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos; + DBX_STAB_SECTION (objfile) = stabsect; if (stabstrsize > bfd_get_size (sym_bfd)) error ("ridiculous string table size: %d bytes", stabstrsize); DBX_STRINGTAB (objfile) = (char *) - obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1); + obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1); OBJSTAT (objfile, sz_strtab += stabstrsize + 1); /* Now read in the string table in one big gulp. */ @@ -3450,14 +3456,25 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline, buildsym_new_init (); free_header_files (); init_header_files (); - install_minimal_symbols (objfile); processing_acc_compilation = 1; + symbuf_read = 0; + symbuf_left = bfd_section_size (objfile->obfd, stabsect); + stabs_data = symfile_relocate_debug_section (objfile->obfd, stabsect, NULL); + if (stabs_data) + back_to = make_cleanup (free_current_contents, (void *) &stabs_data); + /* In an elf file, we've already installed the minimal symbols that came from the elf (non-stab) symbol table, so always act like an - incremental load here. */ + incremental load here. dbx_symfile_read should not generate any new + minimal symbols, since we will have already read the ELF dynamic symbol + table and normal symbol entries won't be in the ".stab" section; but in + case it does, it will install them itself. */ dbx_symfile_read (objfile, 0); + + if (back_to) + do_cleanups (back_to); } /* Scan and build partial symbols for a file with special sections for stabs @@ -3517,7 +3534,7 @@ stabsect_build_psymtabs (struct objfile *objfile, int mainline, char *stab_name, 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); + obstack_alloc (&objfile->objfile_obstack, DBX_STRINGTAB_SIZE (objfile) + 1); OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile) + 1); /* Now read in the string table in one big gulp. */ @@ -3535,7 +3552,6 @@ stabsect_build_psymtabs (struct objfile *objfile, int mainline, char *stab_name, buildsym_new_init (); free_header_files (); init_header_files (); - install_minimal_symbols (objfile); /* Now, do an incremental load */ diff --git a/contrib/gdb/gdb/dcache.c b/contrib/gdb/gdb/dcache.c index 6e742746363..ee690948fdc 100644 --- a/contrib/gdb/gdb/dcache.c +++ b/contrib/gdb/gdb/dcache.c @@ -1,6 +1,7 @@ -/* Caching code. - Copyright 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. +/* Caching code for GDB, the GNU debugger. + + Copyright 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003 Free + Software Foundation, Inc. This file is part of GDB. @@ -217,7 +218,7 @@ dcache_invalidate (DCACHE *dcache) static struct dcache_block * dcache_hit (DCACHE *dcache, CORE_ADDR addr) { - register struct dcache_block *db; + struct dcache_block *db; /* Search all cache blocks for one that is at this address. */ db = dcache->valid_head; @@ -239,7 +240,7 @@ dcache_hit (DCACHE *dcache, CORE_ADDR addr) be written is. */ static int -dcache_write_line (DCACHE *dcache, register struct dcache_block *db) +dcache_write_line (DCACHE *dcache, struct dcache_block *db) { CORE_ADDR memaddr; char *myaddr; @@ -383,7 +384,7 @@ dcache_read_line (DCACHE *dcache, struct dcache_block *db) static struct dcache_block * dcache_alloc (DCACHE *dcache, CORE_ADDR addr) { - register struct dcache_block *db; + struct dcache_block *db; /* Take something from the free list */ db = dcache->free_head; @@ -444,7 +445,7 @@ dcache_writeback (DCACHE *dcache) static int dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr) { - register struct dcache_block *db = dcache_hit (dcache, addr); + struct dcache_block *db = dcache_hit (dcache, addr); if (!db) { @@ -471,7 +472,7 @@ dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr) static int dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr) { - register struct dcache_block *db = dcache_hit (dcache, addr); + struct dcache_block *db = dcache_hit (dcache, addr); if (!db) { diff --git a/contrib/gdb/gdb/defs.h b/contrib/gdb/gdb/defs.h index b6e79536566..e49f9e0e5ba 100644 --- a/contrib/gdb/gdb/defs.h +++ b/contrib/gdb/gdb/defs.h @@ -1,7 +1,7 @@ /* *INDENT-OFF* */ /* ATTR_FORMAT confuses indent, avoid running it for now */ /* Basic, host-specific, and target-specific definitions for GDB. Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002 + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -24,22 +24,33 @@ #ifndef DEFS_H #define DEFS_H -#include "config.h" /* Generated by configure */ +#include "config.h" /* Generated by configure. */ + #include -#include /* System call error return status */ +#include /* System call error return status. */ #include #ifdef HAVE_STDDEF_H #include #else -#include /* for size_t */ +#include /* For size_t. */ #endif #ifdef HAVE_UNISTD_H #include #endif -/* Just in case they're not defined in stdio.h. */ +/* First include ansidecl.h so we can use the various macro definitions + here and in all subsequent file inclusions. */ + +#include "ansidecl.h" + +#include "gdb_locale.h" + +/* For ``enum target_signal''. */ +#include "gdb/signals.h" + +/* Just in case they're not defined in stdio.h. */ #ifndef SEEK_SET #define SEEK_SET 0 @@ -48,17 +59,10 @@ #define SEEK_CUR 1 #endif -/* First include ansidecl.h so we can use the various macro definitions - here and in all subsequent file inclusions. */ - -#include "ansidecl.h" - -#include /* for va_list */ +#include /* For va_list. */ #include "libiberty.h" -#include "progress.h" - /* For BFD64 and bfd_vma. */ #include "bfd.h" @@ -148,25 +152,32 @@ typedef bfd_vma CORE_ADDR; issue is found that we spend the effort on algorithmic optimizations than micro-optimizing.'' J.T. */ -#define STREQ(a,b) (*(a) == *(b) ? !strcmp ((a), (b)) : 0) -#define STREQN(a,b,c) (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0) +/* NOTE: cagney/2003-11-23: All instances of STREQ[N] covered by + testing GDB on a stabs system have been replaced by equivalent + str[n]cmp calls. To avoid the possability of introducing bugs when + making untested changes, the remaining references were deprecated + rather than replaced. */ -/* The character GNU C++ uses to build identifiers that must be unique from - the program's identifiers (such as $this and $$vptr). */ -#define CPLUS_MARKER '$' /* May be overridden to '.' for SysV */ +/* DISCLAIMER: cagney/2003-11-23: Simplified definition of these + macros so that they just map directly onto strcmp equivalent. I'm + not responsible for any breakage due to code that relied on the old + underlying implementation. */ + +#define DEPRECATED_STREQ(a,b) (strcmp ((a), (b)) == 0) +#define DEPRECATED_STREQN(a,b,c) (strncmp ((a), (b), (c)) == 0) /* Check if a character is one of the commonly used C++ marker characters. */ extern int is_cplus_marker (int); -/* use tui interface if non-zero */ -extern int tui_version; - /* enable xdb commands if set */ extern int xdb_commands; /* enable dbx commands if set */ extern int dbx_commands; +/* System root path, used to find libraries etc. */ +extern char *gdb_sysroot; + extern int quit_flag; extern int immediate_quit; extern int sevenbit_strings; @@ -188,7 +199,6 @@ extern void quit (void); #define QUIT { \ if (quit_flag) quit (); \ if (interactive_hook) interactive_hook (); \ - PROGRESS (1); \ } #endif @@ -203,13 +213,14 @@ enum language language_auto, /* Placeholder for automatic setting */ language_c, /* C */ language_cplus, /* C++ */ + language_objc, /* Objective-C */ language_java, /* Java */ - language_chill, /* Chill */ language_fortran, /* Fortran */ language_m2, /* Modula-2 */ language_asm, /* Assembly language */ language_scm, /* Scheme / Guile */ - language_pascal /* Pascal */ + language_pascal, /* Pascal */ + language_minimal /* All other languages, minimal support only */ }; enum precision_type @@ -219,212 +230,28 @@ enum precision_type unspecified_precision }; -/* The numbering of these signals is chosen to match traditional unix - signals (insofar as various unices use the same numbers, anyway). - It is also the numbering of the GDB remote protocol. Other remote - protocols, if they use a different numbering, should make sure to - translate appropriately. +/* A generic, not quite boolean, enumeration. */ +enum auto_boolean +{ + AUTO_BOOLEAN_TRUE, + AUTO_BOOLEAN_FALSE, + AUTO_BOOLEAN_AUTO +}; - Since these numbers have actually made it out into other software - (stubs, etc.), you mustn't disturb the assigned numbering. If you - need to add new signals here, add them to the end of the explicitly - numbered signals. - - This is based strongly on Unix/POSIX signals for several reasons: - (1) This set of signals represents a widely-accepted attempt to - represent events of this sort in a portable fashion, (2) we want a - signal to make it from wait to child_wait to the user intact, (3) many - remote protocols use a similar encoding. However, it is - recognized that this set of signals has limitations (such as not - distinguishing between various kinds of SIGSEGV, or not - distinguishing hitting a breakpoint from finishing a single step). - So in the future we may get around this either by adding additional - signals for breakpoint, single-step, etc., or by adding signal - codes; the latter seems more in the spirit of what BSD, System V, - etc. are doing to address these issues. */ - -/* For an explanation of what each signal means, see - target_signal_to_string. */ - -enum target_signal - { - /* Used some places (e.g. stop_signal) to record the concept that - there is no signal. */ - TARGET_SIGNAL_0 = 0, - TARGET_SIGNAL_FIRST = 0, - TARGET_SIGNAL_HUP = 1, - TARGET_SIGNAL_INT = 2, - TARGET_SIGNAL_QUIT = 3, - TARGET_SIGNAL_ILL = 4, - TARGET_SIGNAL_TRAP = 5, - TARGET_SIGNAL_ABRT = 6, - TARGET_SIGNAL_EMT = 7, - TARGET_SIGNAL_FPE = 8, - TARGET_SIGNAL_KILL = 9, - TARGET_SIGNAL_BUS = 10, - TARGET_SIGNAL_SEGV = 11, - TARGET_SIGNAL_SYS = 12, - TARGET_SIGNAL_PIPE = 13, - TARGET_SIGNAL_ALRM = 14, - TARGET_SIGNAL_TERM = 15, - TARGET_SIGNAL_URG = 16, - TARGET_SIGNAL_STOP = 17, - TARGET_SIGNAL_TSTP = 18, - TARGET_SIGNAL_CONT = 19, - TARGET_SIGNAL_CHLD = 20, - TARGET_SIGNAL_TTIN = 21, - TARGET_SIGNAL_TTOU = 22, - TARGET_SIGNAL_IO = 23, - TARGET_SIGNAL_XCPU = 24, - TARGET_SIGNAL_XFSZ = 25, - TARGET_SIGNAL_VTALRM = 26, - TARGET_SIGNAL_PROF = 27, - TARGET_SIGNAL_WINCH = 28, - TARGET_SIGNAL_LOST = 29, - TARGET_SIGNAL_USR1 = 30, - TARGET_SIGNAL_USR2 = 31, - TARGET_SIGNAL_PWR = 32, - /* Similar to SIGIO. Perhaps they should have the same number. */ - TARGET_SIGNAL_POLL = 33, - TARGET_SIGNAL_WIND = 34, - TARGET_SIGNAL_PHONE = 35, - TARGET_SIGNAL_WAITING = 36, - TARGET_SIGNAL_LWP = 37, - TARGET_SIGNAL_DANGER = 38, - TARGET_SIGNAL_GRANT = 39, - TARGET_SIGNAL_RETRACT = 40, - TARGET_SIGNAL_MSG = 41, - TARGET_SIGNAL_SOUND = 42, - TARGET_SIGNAL_SAK = 43, - TARGET_SIGNAL_PRIO = 44, - TARGET_SIGNAL_REALTIME_33 = 45, - TARGET_SIGNAL_REALTIME_34 = 46, - TARGET_SIGNAL_REALTIME_35 = 47, - TARGET_SIGNAL_REALTIME_36 = 48, - TARGET_SIGNAL_REALTIME_37 = 49, - TARGET_SIGNAL_REALTIME_38 = 50, - TARGET_SIGNAL_REALTIME_39 = 51, - TARGET_SIGNAL_REALTIME_40 = 52, - TARGET_SIGNAL_REALTIME_41 = 53, - TARGET_SIGNAL_REALTIME_42 = 54, - TARGET_SIGNAL_REALTIME_43 = 55, - TARGET_SIGNAL_REALTIME_44 = 56, - TARGET_SIGNAL_REALTIME_45 = 57, - TARGET_SIGNAL_REALTIME_46 = 58, - TARGET_SIGNAL_REALTIME_47 = 59, - TARGET_SIGNAL_REALTIME_48 = 60, - TARGET_SIGNAL_REALTIME_49 = 61, - TARGET_SIGNAL_REALTIME_50 = 62, - TARGET_SIGNAL_REALTIME_51 = 63, - TARGET_SIGNAL_REALTIME_52 = 64, - TARGET_SIGNAL_REALTIME_53 = 65, - TARGET_SIGNAL_REALTIME_54 = 66, - TARGET_SIGNAL_REALTIME_55 = 67, - TARGET_SIGNAL_REALTIME_56 = 68, - TARGET_SIGNAL_REALTIME_57 = 69, - TARGET_SIGNAL_REALTIME_58 = 70, - TARGET_SIGNAL_REALTIME_59 = 71, - TARGET_SIGNAL_REALTIME_60 = 72, - TARGET_SIGNAL_REALTIME_61 = 73, - TARGET_SIGNAL_REALTIME_62 = 74, - TARGET_SIGNAL_REALTIME_63 = 75, - - /* Used internally by Solaris threads. See signal(5) on Solaris. */ - TARGET_SIGNAL_CANCEL = 76, - - /* Yes, this pains me, too. But LynxOS didn't have SIG32, and now - GNU/Linux does, and we can't disturb the numbering, since it's - part of the remote protocol. Note that in some GDB's - TARGET_SIGNAL_REALTIME_32 is number 76. */ - TARGET_SIGNAL_REALTIME_32, - /* Yet another pain, IRIX 6 has SIG64. */ - TARGET_SIGNAL_REALTIME_64, - /* Yet another pain, GNU/Linux MIPS might go up to 128. */ - TARGET_SIGNAL_REALTIME_65, - TARGET_SIGNAL_REALTIME_66, - TARGET_SIGNAL_REALTIME_67, - TARGET_SIGNAL_REALTIME_68, - TARGET_SIGNAL_REALTIME_69, - TARGET_SIGNAL_REALTIME_70, - TARGET_SIGNAL_REALTIME_71, - TARGET_SIGNAL_REALTIME_72, - TARGET_SIGNAL_REALTIME_73, - TARGET_SIGNAL_REALTIME_74, - TARGET_SIGNAL_REALTIME_75, - TARGET_SIGNAL_REALTIME_76, - TARGET_SIGNAL_REALTIME_77, - TARGET_SIGNAL_REALTIME_78, - TARGET_SIGNAL_REALTIME_79, - TARGET_SIGNAL_REALTIME_80, - TARGET_SIGNAL_REALTIME_81, - TARGET_SIGNAL_REALTIME_82, - TARGET_SIGNAL_REALTIME_83, - TARGET_SIGNAL_REALTIME_84, - TARGET_SIGNAL_REALTIME_85, - TARGET_SIGNAL_REALTIME_86, - TARGET_SIGNAL_REALTIME_87, - TARGET_SIGNAL_REALTIME_88, - TARGET_SIGNAL_REALTIME_89, - TARGET_SIGNAL_REALTIME_90, - TARGET_SIGNAL_REALTIME_91, - TARGET_SIGNAL_REALTIME_92, - TARGET_SIGNAL_REALTIME_93, - TARGET_SIGNAL_REALTIME_94, - TARGET_SIGNAL_REALTIME_95, - TARGET_SIGNAL_REALTIME_96, - TARGET_SIGNAL_REALTIME_97, - TARGET_SIGNAL_REALTIME_98, - TARGET_SIGNAL_REALTIME_99, - TARGET_SIGNAL_REALTIME_100, - TARGET_SIGNAL_REALTIME_101, - TARGET_SIGNAL_REALTIME_102, - TARGET_SIGNAL_REALTIME_103, - TARGET_SIGNAL_REALTIME_104, - TARGET_SIGNAL_REALTIME_105, - TARGET_SIGNAL_REALTIME_106, - TARGET_SIGNAL_REALTIME_107, - TARGET_SIGNAL_REALTIME_108, - TARGET_SIGNAL_REALTIME_109, - TARGET_SIGNAL_REALTIME_110, - TARGET_SIGNAL_REALTIME_111, - TARGET_SIGNAL_REALTIME_112, - TARGET_SIGNAL_REALTIME_113, - TARGET_SIGNAL_REALTIME_114, - TARGET_SIGNAL_REALTIME_115, - TARGET_SIGNAL_REALTIME_116, - TARGET_SIGNAL_REALTIME_117, - TARGET_SIGNAL_REALTIME_118, - TARGET_SIGNAL_REALTIME_119, - TARGET_SIGNAL_REALTIME_120, - TARGET_SIGNAL_REALTIME_121, - TARGET_SIGNAL_REALTIME_122, - TARGET_SIGNAL_REALTIME_123, - TARGET_SIGNAL_REALTIME_124, - TARGET_SIGNAL_REALTIME_125, - TARGET_SIGNAL_REALTIME_126, - TARGET_SIGNAL_REALTIME_127, - -#if defined(MACH) || defined(__MACH__) - /* Mach exceptions */ - TARGET_EXC_BAD_ACCESS, - TARGET_EXC_BAD_INSTRUCTION, - TARGET_EXC_ARITHMETIC, - TARGET_EXC_EMULATION, - TARGET_EXC_SOFTWARE, - TARGET_EXC_BREAKPOINT, -#endif - TARGET_SIGNAL_INFO, - - /* Some signal we don't know about. */ - TARGET_SIGNAL_UNKNOWN, - - /* Use whatever signal we use when one is not specifically specified - (for passing to proceed and so on). */ - TARGET_SIGNAL_DEFAULT, - - /* Last and unused enum value, for sizing arrays, etc. */ - TARGET_SIGNAL_LAST - }; +/* Potential ways that a function can return a value of a given type. */ +enum return_value_convention +{ + /* Where the return value has been squeezed into one or more + registers. */ + RETURN_VALUE_REGISTER_CONVENTION, + /* Commonly known as the "struct return convention". The caller + passes an additional hidden first parameter to the caller. That + parameter contains the address at which the value being returned + should be stored. While typically, and historically, used for + large structs, this is convention is applied to values of many + different types. */ + RETURN_VALUE_STRUCT_CONVENTION +}; /* the cleanup list records things that have to be undone if an error happens (descriptors to be closed, memory to be freed, etc.) @@ -439,8 +266,8 @@ enum target_signal struct cleanup { struct cleanup *next; - void (*function) (PTR); - PTR arg; + void (*function) (void *); + void *arg; }; @@ -481,23 +308,29 @@ struct cleanup #endif #endif +/* Be conservative and use enum bitfields only with GCC. + This is copied from gcc 3.3.1, system.h. */ + +#if defined(__GNUC__) && (__GNUC__ >= 2) +#define ENUM_BITFIELD(TYPE) enum TYPE +#else +#define ENUM_BITFIELD(TYPE) unsigned int +#endif + /* Needed for various prototypes */ struct symtab; struct breakpoint; +struct frame_info; /* From blockframe.c */ -extern int inside_entry_func (CORE_ADDR); +extern int inside_entry_func (struct frame_info *this_frame); -extern int inside_entry_file (CORE_ADDR addr); +extern int deprecated_inside_entry_file (CORE_ADDR addr); extern int inside_main_func (CORE_ADDR pc); -/* From ch-lang.c, for the moment. (FIXME) */ - -extern char *chill_demangle (const char *); - /* From utils.c */ extern void initialize_utils (void); @@ -506,6 +339,10 @@ extern void notice_quit (void); extern int strcmp_iw (const char *, const char *); +extern int strcmp_iw_ordered (const char *, const char *); + +extern int streq (const char *, const char *); + extern int subset_compare (char *, char *); extern char *safe_strerror (int); @@ -516,7 +353,6 @@ extern void request_quit (int); extern void do_cleanups (struct cleanup *); extern void do_final_cleanups (struct cleanup *); -extern void do_my_cleanups (struct cleanup **, struct cleanup *); extern void do_run_cleanups (struct cleanup *); extern void do_exec_cleanups (struct cleanup *); extern void do_exec_error_cleanups (struct cleanup *); @@ -569,13 +405,16 @@ extern void null_cleanup (void *); extern int myread (int, char *, int); extern int query (const char *, ...) ATTR_FORMAT (printf, 1, 2); +extern int nquery (const char *, ...) ATTR_FORMAT (printf, 1, 2); +extern int yquery (const char *, ...) ATTR_FORMAT (printf, 1, 2); extern void init_page_info (void); -extern CORE_ADDR host_pointer_to_address (void *ptr); -extern void *address_to_host_pointer (CORE_ADDR addr); - extern char *gdb_realpath (const char *); +extern char *xfullpath (const char *); + +extern unsigned long gnu_debuglink_crc32 (unsigned long crc, + unsigned char *buf, size_t len); /* From demangle.c */ @@ -587,7 +426,6 @@ struct type; typedef int (use_struct_convention_fn) (int gcc_p, struct type * value_type); extern use_struct_convention_fn generic_use_struct_convention; -typedef unsigned char *(breakpoint_from_pc_fn) (CORE_ADDR * pcptr, int *lenptr); /* Annotation stuff. */ @@ -601,22 +439,22 @@ extern void reinitialize_more_filter (void); /* Normal results */ extern struct ui_file *gdb_stdout; +/* Input stream */ +extern struct ui_file *gdb_stdin; /* Serious error notifications */ extern struct ui_file *gdb_stderr; /* Log/debug/trace messages that should bypass normal stdout/stderr - filtering. For momement, always call this stream using + filtering. For moment, always call this stream using *_unfiltered. In the very near future that restriction shall be removed - either call shall be unfiltered. (cagney 1999-06-13). */ extern struct ui_file *gdb_stdlog; /* Target output that should bypass normal stdout/stderr filtering. - For momement, always call this stream using *_unfiltered. In the + For moment, always call this stream using *_unfiltered. In the very near future that restriction shall be removed - either call shall be unfiltered. (cagney 1999-07-02). */ extern struct ui_file *gdb_stdtarg; - -#if defined(TUI) -#include "tui.h" -#endif +extern struct ui_file *gdb_stdtargerr; +extern struct ui_file *gdb_stdtargin; #include "ui-file.h" @@ -639,6 +477,8 @@ extern void puts_filtered (const char *); extern void puts_unfiltered (const char *); +extern void puts_filtered_tabular (char *string, int width, int right); + extern void puts_debug (char *prefix, char *string, char *suffix); extern void vprintf_filtered (const char *, va_list) ATTR_FORMAT (printf, 1, 0); @@ -674,7 +514,7 @@ extern void fputstr_unfiltered (const char *str, int quotr, struct ui_file * str extern void fputstrn_unfiltered (const char *str, int n, int quotr, struct ui_file * stream); /* Display the host ADDR on STREAM formatted as ``0x%x''. */ -extern void gdb_print_host_address (void *addr, struct ui_file *stream); +extern void gdb_print_host_address (const void *addr, struct ui_file *stream); /* Convert a CORE_ADDR into a HEX string. paddr() is like %08lx. paddr_nz() is like %lx. paddr_u() is like %lu. paddr_width() is @@ -729,6 +569,8 @@ extern char *skip_quoted (char *); extern char *gdb_readline (char *); +extern char *gdb_readline_wrapper (char *); + extern char *command_line_input (char *, int, char *); extern void print_prompt (void); @@ -764,10 +606,16 @@ extern int source_full_path_of (char *, char **); extern void mod_path (char *, char **); +extern void add_path (char *, char **, int); + extern void directory_command (char *, int); +extern char *source_path; + extern void init_source_path (void); +extern void init_last_source_visited (void); + extern char *symtab_to_filename (struct symtab *); /* From exec.c */ @@ -783,10 +631,6 @@ extern void exec_set_find_memory_regions (int (*) (int (*) (CORE_ADDR, void *), void *)); -/* From findvar.c */ - -extern int read_relative_register_raw_bytes (int, char *); - /* Possible lvalue types. Like enum language, this should be in value.h, but needs to be here for the same reason. */ @@ -808,12 +652,6 @@ enum lval_type lval_reg_frame_relative }; -struct frame_info; - -/* From readline (but not in any readline .h files). */ - -extern char *tilde_expand (char *); - /* Control types for commands */ enum misc_command_type @@ -970,16 +808,6 @@ typedef struct ptid ptid_t; #include "tm.h" #endif -/* GDB_MULTI_ARCH is normally set by configure.in using information - from configure.tgt or the config/%/%.mt Makefile fragment. Since - some targets have defined it in their "tm.h" file, delay providing - a default definition until after "tm.h" has been included.. */ - -#ifndef GDB_MULTI_ARCH -#define GDB_MULTI_ARCH 0 -#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 */ @@ -1044,11 +872,21 @@ extern void xmfree (void *md, void *ptr); "libiberty.h". */ extern void xfree (void *); +/* Utility macros to allocate typed memory. Avoids errors like: + struct foo *foo = xmalloc (sizeof struct bar); and memset (foo, + sizeof (struct foo), 0). */ +#define XZALLOC(TYPE) ((TYPE*) memset (xmalloc (sizeof (TYPE)), 0, sizeof (TYPE))) +#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) +#define XCALLOC(NMEMB, TYPE) ((TYPE*) xcalloc ((NMEMB), sizeof (TYPE))) + /* Like asprintf/vasprintf but get an internal_error if the call fails. */ extern void xasprintf (char **ret, const char *format, ...) ATTR_FORMAT (printf, 2, 3); extern void xvasprintf (char **ret, const char *format, va_list ap); +/* Like asprintf, but return the string, throw an error if no memory. */ +extern char *xstrprintf (const char *format, ...) ATTR_FORMAT (printf, 1, 2); + extern int parse_escape (char **); /* Message to be printed before the error message, when an error occurs. */ @@ -1065,20 +903,34 @@ extern char *warning_pre_print; extern NORETURN void verror (const char *fmt, va_list ap) ATTR_NORETURN; -extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN; +extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2); + +extern NORETURN void error_silent (const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2); extern NORETURN void error_stream (struct ui_file *) ATTR_NORETURN; +/* Initialize the error buffer. */ +extern void error_init (void); + /* Returns a freshly allocate buffer containing the last error message. */ extern char *error_last_message (void); +/* Output arbitrary error message. */ +extern void error_output_message (char *pre_print, char *msg); + extern NORETURN void internal_verror (const char *file, int line, const char *, va_list ap) ATTR_NORETURN; extern NORETURN void internal_error (const char *file, int line, const char *, ...) ATTR_NORETURN ATTR_FORMAT (printf, 3, 4); +extern void internal_vwarning (const char *file, int line, + const char *, va_list ap); + +extern void internal_warning (const char *file, int line, + const char *, ...) ATTR_FORMAT (printf, 3, 4); + extern NORETURN void nomem (long) ATTR_NORETURN; /* Reasons for calling throw_exception(). NOTE: all reason values @@ -1129,6 +981,11 @@ extern NORETURN void throw_exception (enum return_reason) ATTR_NORETURN; new cleanup_chain is established. The old values are restored before catch_exceptions() returns. + The variant catch_exceptions_with_msg() is the same as + catch_exceptions() but adds the ability to return an allocated + copy of the gdb error message. This is used when a silent error is + issued and the caller wants to manually issue the error message. + FIXME; cagney/2001-08-13: The need to override the global UIOUT builder variable should just go away. @@ -1141,6 +998,11 @@ typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args); extern int catch_exceptions (struct ui_out *uiout, catch_exceptions_ftype *func, void *func_args, char *errstring, return_mask mask); +extern int catch_exceptions_with_msg (struct ui_out *uiout, + catch_exceptions_ftype *func, + void *func_args, + char *errstring, char **gdberrmsg, + return_mask mask); /* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero otherwize the result from CATCH_ERRORS_FTYPE is returned. It is @@ -1151,7 +1013,7 @@ extern int catch_exceptions (struct ui_out *uiout, This function is superseeded by catch_exceptions(). */ -typedef int (catch_errors_ftype) (PTR); +typedef int (catch_errors_ftype) (void *); extern int catch_errors (catch_errors_ftype *, void *, char *, return_mask); /* Template to catch_errors() that wraps calls to command @@ -1164,6 +1026,43 @@ extern void warning (const char *, ...) ATTR_FORMAT (printf, 1, 2); extern void vwarning (const char *, va_list args); +/* List of known OS ABIs. If you change this, make sure to update the + table in osabi.c. */ +enum gdb_osabi +{ + GDB_OSABI_UNINITIALIZED = -1, /* For struct gdbarch_info. */ + + GDB_OSABI_UNKNOWN = 0, /* keep this zero */ + + GDB_OSABI_SVR4, + GDB_OSABI_HURD, + GDB_OSABI_SOLARIS, + GDB_OSABI_OSF1, + GDB_OSABI_LINUX, + GDB_OSABI_FREEBSD_AOUT, + GDB_OSABI_FREEBSD_ELF, + GDB_OSABI_NETBSD_AOUT, + GDB_OSABI_NETBSD_ELF, + GDB_OSABI_OPENBSD_ELF, + GDB_OSABI_WINCE, + GDB_OSABI_GO32, + GDB_OSABI_NETWARE, + GDB_OSABI_IRIX, + GDB_OSABI_LYNXOS, + GDB_OSABI_INTERIX, + GDB_OSABI_HPUX_ELF, + GDB_OSABI_HPUX_SOM, + + GDB_OSABI_ARM_EABI_V1, + GDB_OSABI_ARM_EABI_V2, + GDB_OSABI_ARM_APCS, + GDB_OSABI_QNXNTO, + + GDB_OSABI_CYGWIN, + + GDB_OSABI_INVALID /* keep this last */ +}; + /* Global functions from other, non-gdb GNU thingies. Libiberty thingies are no longer declared here. We include libiberty.h above, instead. */ @@ -1223,14 +1122,22 @@ extern void *alloca (); #endif /* Not GNU C */ #endif /* alloca not defined */ +/* Is GDB multi-arch? If there's a "tm.h" file, it is not. */ +#ifndef GDB_MULTI_ARCH +#ifdef GDB_TM_FILE +#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL +#else +#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PURE +#endif +#endif + /* Dynamic target-system-dependent parameters for GDB. */ #include "gdbarch.h" -#if (GDB_MULTI_ARCH == 0) -/* Multi-arch targets _should_ be including "arch-utils.h" directly - into their *-tdep.c file. This is a prop to help old non- - multi-arch targets to continue to compile. */ -#include "arch-utils.h" -#endif + +/* Maximum size of a register. Something small, but large enough for + all known ISAs. If it turns out to be too small, make it bigger. */ + +enum { MAX_REGISTER_SIZE = 16 }; /* Static target-system-dependent parameters for GDB. */ @@ -1261,22 +1168,18 @@ extern void *alloca (); /* In findvar.c. */ -extern LONGEST extract_signed_integer (void *, int); +extern LONGEST extract_signed_integer (const void *, int); -extern ULONGEST extract_unsigned_integer (void *, int); +extern ULONGEST extract_unsigned_integer (const void *, int); -extern int extract_long_unsigned_integer (void *, int, LONGEST *); +extern int extract_long_unsigned_integer (const void *, int, LONGEST *); -extern CORE_ADDR extract_address (void *, int); - -extern CORE_ADDR extract_typed_address (void *buf, struct type *type); +extern CORE_ADDR extract_typed_address (const void *buf, struct type *type); extern void store_signed_integer (void *, int, LONGEST); extern void store_unsigned_integer (void *, int, ULONGEST); -extern void store_address (void *, int, LONGEST); - extern void store_typed_address (void *buf, struct type *type, CORE_ADDR addr); @@ -1397,4 +1300,36 @@ extern int use_windows; #define ISATTY(FP) (isatty (fileno (FP))) #endif +/* Ensure that V is aligned to an N byte boundary (B's assumed to be a + power of 2). Round up/down when necessary. Examples of correct + use include: + + addr = align_up (addr, 8); -- VALUE needs 8 byte alignment + write_memory (addr, value, len); + addr += len; + + and: + + sp = align_down (sp - len, 16); -- Keep SP 16 byte aligned + write_memory (sp, value, len); + + Note that uses such as: + + write_memory (addr, value, len); + addr += align_up (len, 8); + + and: + + sp -= align_up (len, 8); + write_memory (sp, value, len); + + are typically not correct as they don't ensure that the address (SP + or ADDR) is correctly aligned (relying on previous alignment to + keep things right). This is also why the methods are called + "align_..." instead of "round_..." as the latter reads better with + this incorrect coding style. */ + +extern ULONGEST align_up (ULONGEST v, int n); +extern ULONGEST align_down (ULONGEST v, int n); + #endif /* #ifndef DEFS_H */ diff --git a/contrib/gdb/gdb/delta68-nat.c b/contrib/gdb/gdb/delta68-nat.c new file mode 100644 index 00000000000..e74a51bf048 --- /dev/null +++ b/contrib/gdb/gdb/delta68-nat.c @@ -0,0 +1,90 @@ +/* Functions specific to running gdb native on a Motorola Delta Series sysV68. + Copyright 1993, 1996, 1998, 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include /* for MAXSIG in sys/user.h */ +#include /* for ushort in sys/dir.h */ +#include /* for struct direct in sys/user.h */ +#include + +#include + +#if !defined (offsetof) +#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) +#endif + +/* Return the address in the core dump or inferior of register REGNO. + BLOCKEND is the address of the end of the user structure. */ + +CORE_ADDR +register_addr (int regno, CORE_ADDR blockend) +{ + static int sysv68reg[] = + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, 15, 16}; + + if (regno >= 0 && regno < sizeof (sysv68reg) / sizeof (sysv68reg[0])) + return blockend + sysv68reg[regno] * 4; + else if (regno < FPC_REGNUM) + return offsetof (struct user, u_fpu.regs.reg[regno - FP0_REGNUM][0]); + else if (regno == FPC_REGNUM) + return offsetof (struct user, u_fpu.regs.control); + else if (regno == FPS_REGNUM) + return offsetof (struct user, u_fpu.regs.status); + else if (regno == FPI_REGNUM) + return offsetof (struct user, u_fpu.regs.iaddr); + else + { + fprintf_unfiltered (gdb_stderr, "\ +Internal error: invalid register number %d in REGISTER_U_ADDR\n", + regno); + return blockend; + } +} + +CORE_ADDR kernel_u_addr; + +/* Read the value of the u area from the kernel. */ +void +_initialize_delta68_nat (void) +{ + struct nlist nl[2]; + + nl[0].n_name = "u"; + nl[1].n_name = NULL; + if (nlist ("/sysV68", nl) == 0 && nl[0].n_scnum != 0) + kernel_u_addr = nl[0].n_value; + else + { + perror ("Cannot get kernel u area address"); + exit (1); + } +} + +clear_insn_cache (void) +{ +#ifdef MCT_TEXT /* in sys/signal.h on sysV68 R3V7.1 */ + memctl (0, 4096, MCT_TEXT); +#endif +} + +kernel_u_size (void) +{ + return sizeof (struct user); +} diff --git a/contrib/gdb/gdb/demangle.c b/contrib/gdb/gdb/demangle.c index 1fd69be4c58..bcf9b77de51 100644 --- a/contrib/gdb/gdb/demangle.c +++ b/contrib/gdb/gdb/demangle.c @@ -1,6 +1,8 @@ /* Basic C++ demangling support for GDB. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, + 2001, 2003 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support. This file is part of GDB. @@ -87,8 +89,8 @@ set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c) dem->demangling_style != unknown_demangling; dem++) { - if (STREQ (current_demangling_style_string, - dem->demangling_style_name)) + if (strcmp (current_demangling_style_string, + dem->demangling_style_name) == 0) { current_demangling_style = dem->demangling_style; break; @@ -150,24 +152,18 @@ set_demangling_style (char *style) set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL); } -/* In order to allow a single demangler executable to demangle strings - using various common values of CPLUS_MARKER, as well as any specific - one set at compile time, we maintain a string containing all the - commonly used ones, and check to see if the marker we are looking for - is in that string. CPLUS_MARKER is usually '$' on systems where the - assembler can deal with that. Where the assembler can't, it's usually - '.' (but on many systems '.' is used for other things). We put the - current defined CPLUS_MARKER first (which defaults to '$'), followed - by the next most common value, followed by an explicit '$' in case - the value of CPLUS_MARKER is not '$'. +/* G++ uses a special character to indicate certain internal names. Which + character it is depends on the platform: + - Usually '$' on systems where the assembler will accept that + - Usually '.' otherwise (this includes most sysv4-like systems and most + ELF targets) + - Occasionally '_' if neither of the above is usable - We could avoid this if we could just get g++ to tell us what the actual - cplus marker character is as part of the debug information, perhaps by - ensuring that it is the character that terminates the gcc_compiled - marker symbol (FIXME). */ + We check '$' first because it is the safest, and '.' often has another + meaning. We don't currently try to handle '_' because the precise forms + of the names are different on those targets. */ -static char cplus_markers[] = -{CPLUS_MARKER, '.', '$', '\0'}; +static char cplus_markers[] = {'$', '.', '\0'}; int is_cplus_marker (int c) @@ -204,5 +200,4 @@ Use `set demangle-style' without arguments for a list of demangling styles.", /* Set the default demangling style chosen at compilation time. */ set_demangling_style (DEFAULT_DEMANGLING_STYLE); - set_cplus_marker_for_demangling (CPLUS_MARKER); } diff --git a/contrib/gdb/gdb/dictionary.c b/contrib/gdb/gdb/dictionary.c new file mode 100644 index 00000000000..5c085feaa0e --- /dev/null +++ b/contrib/gdb/gdb/dictionary.c @@ -0,0 +1,836 @@ +/* Routines for name->symbol lookups in GDB. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by David Carlton and by Kealia, + Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_obstack.h" +#include "symtab.h" +#include "buildsym.h" +#include "gdb_assert.h" +#include "dictionary.h" + +/* This file implements dictionaries, which are tables that associate + symbols to names. They are represented by an opaque type 'struct + dictionary'. That type has various internal implementations, which + you can choose between depending on what properties you need + (e.g. fast lookup, order-preserving, expandable). + + Each dictionary starts with a 'virtual function table' that + contains the functions that actually implement the various + operations that dictionaries provide. (Note, however, that, for + the sake of client code, we also provide some functions that can be + implemented generically in terms of the functions in the vtable.) + + To add a new dictionary implementation , what you should do + is: + + * Add a new element DICT_ to dict_type. + + * Create a new structure dictionary_. If your new + implementation is a variant of an existing one, make sure that + their structs have the same initial data members. Define accessor + macros for your new data members. + + * Implement all the functions in dict_vector as static functions, + whose name is the same as the corresponding member of dict_vector + plus _. You don't have to do this for those members where + you can reuse existing generic functions + (e.g. add_symbol_nonexpandable, free_obstack) or in the case where + your new implementation is a variant of an existing implementation + and where the variant doesn't affect the member function in + question. + + * Define a static const struct dict_vector dict__vector. + + * Define a function dict_create_ to create these + gizmos. Add its declaration to dictionary.h. + + To add a new operation on all existing implementations, what + you should do is: + + * Add a new member to struct dict_vector. + + * If there is useful generic behavior , define a static + function _something_informative that implements that behavior. + (E.g. add_symbol_nonexpandable, free_obstack.) + + * For every implementation that should have its own specific + behavior for , define a static function _ + implementing it. + + * Modify all existing dict_vector_'s to include the appropriate + member. + + * Define a function dict_ that looks up in the dict_vector + and calls the appropriate function. Add a declaration for + dict_ to dictionary.h. + +*/ + +/* An enum representing the various implementations of dictionaries. + Used only for debugging. */ + +enum dict_type + { + /* Symbols are stored in a fixed-size hash table. */ + DICT_HASHED, + /* Symbols are stored in an expandable hash table. */ + DICT_HASHED_EXPANDABLE, + /* Symbols are stored in a fixed-size array. */ + DICT_LINEAR, + /* Symbols are stored in an expandable array. */ + DICT_LINEAR_EXPANDABLE + }; + +/* The virtual function table. */ + +struct dict_vector +{ + /* The type of the dictionary. This is only here to make debugging + a bit easier; it's not actually used. */ + enum dict_type type; + /* The function to free a dictionary. */ + void (*free) (struct dictionary *dict); + /* Add a symbol to a dictionary, if possible. */ + void (*add_symbol) (struct dictionary *dict, struct symbol *sym); + /* Iterator functions. */ + struct symbol *(*iterator_first) (const struct dictionary *dict, + struct dict_iterator *iterator); + struct symbol *(*iterator_next) (struct dict_iterator *iterator); + /* Functions to iterate over symbols with a given name. */ + struct symbol *(*iter_name_first) (const struct dictionary *dict, + const char *name, + struct dict_iterator *iterator); + struct symbol *(*iter_name_next) (const char *name, + struct dict_iterator *iterator); + /* A size function, for maint print symtabs. */ + int (*size) (const struct dictionary *dict); +}; + +/* Now comes the structs used to store the data for different + implementations. If two implementations have data in common, put + the common data at the top of their structs, ordered in the same + way. */ + +struct dictionary_hashed +{ + int nbuckets; + struct symbol **buckets; +}; + +struct dictionary_hashed_expandable +{ + /* How many buckets we currently have. */ + int nbuckets; + struct symbol **buckets; + /* How many syms we currently have; we need this so we will know + when to add more buckets. */ + int nsyms; +}; + +struct dictionary_linear +{ + int nsyms; + struct symbol **syms; +}; + +struct dictionary_linear_expandable +{ + /* How many symbols we currently have. */ + int nsyms; + struct symbol **syms; + /* How many symbols we can store before needing to reallocate. */ + int capacity; +}; + +/* And now, the star of our show. */ + +struct dictionary +{ + const struct dict_vector *vector; + union + { + struct dictionary_hashed hashed; + struct dictionary_hashed_expandable hashed_expandable; + struct dictionary_linear linear; + struct dictionary_linear_expandable linear_expandable; + } + data; +}; + +/* Accessor macros. */ + +#define DICT_VECTOR(d) (d)->vector + +/* These can be used for DICT_HASHED_EXPANDABLE, too. */ + +#define DICT_HASHED_NBUCKETS(d) (d)->data.hashed.nbuckets +#define DICT_HASHED_BUCKETS(d) (d)->data.hashed.buckets +#define DICT_HASHED_BUCKET(d,i) DICT_HASHED_BUCKETS (d) [i] + +#define DICT_HASHED_EXPANDABLE_NSYMS(d) (d)->data.hashed_expandable.nsyms + +/* These can be used for DICT_LINEAR_EXPANDABLEs, too. */ + +#define DICT_LINEAR_NSYMS(d) (d)->data.linear.nsyms +#define DICT_LINEAR_SYMS(d) (d)->data.linear.syms +#define DICT_LINEAR_SYM(d,i) DICT_LINEAR_SYMS (d) [i] + +#define DICT_LINEAR_EXPANDABLE_CAPACITY(d) \ + (d)->data.linear_expandable.capacity + +/* The initial size of a DICT_*_EXPANDABLE dictionary. */ + +#define DICT_EXPANDABLE_INITIAL_CAPACITY 10 + +/* This calculates the number of buckets we'll use in a hashtable, + given the number of symbols that it will contain. */ + +#define DICT_HASHTABLE_SIZE(n) ((n)/5 + 1) + +/* Accessor macros for dict_iterators; they're here rather than + dictionary.h because code elsewhere should treat dict_iterators as + opaque. */ + +/* The dictionary that the iterator is associated to. */ +#define DICT_ITERATOR_DICT(iter) (iter)->dict +/* For linear dictionaries, the index of the last symbol returned; for + hashed dictionaries, the bucket of the last symbol returned. */ +#define DICT_ITERATOR_INDEX(iter) (iter)->index +/* For hashed dictionaries, this points to the last symbol returned; + otherwise, this is unused. */ +#define DICT_ITERATOR_CURRENT(iter) (iter)->current + +/* Declarations of functions for vectors. */ + +/* Functions that might work across a range of dictionary types. */ + +static void add_symbol_nonexpandable (struct dictionary *dict, + struct symbol *sym); + +static void free_obstack (struct dictionary *dict); + +/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE + dictionaries. */ + +static struct symbol *iterator_first_hashed (const struct dictionary *dict, + struct dict_iterator *iterator); + +static struct symbol *iterator_next_hashed (struct dict_iterator *iterator); + +static struct symbol *iter_name_first_hashed (const struct dictionary *dict, + const char *name, + struct dict_iterator *iterator); + +static struct symbol *iter_name_next_hashed (const char *name, + struct dict_iterator *iterator); + +/* Functions only for DICT_HASHED. */ + +static int size_hashed (const struct dictionary *dict); + +/* Functions only for DICT_HASHED_EXPANDABLE. */ + +static void free_hashed_expandable (struct dictionary *dict); + +static void add_symbol_hashed_expandable (struct dictionary *dict, + struct symbol *sym); + +static int size_hashed_expandable (const struct dictionary *dict); + +/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE + dictionaries. */ + +static struct symbol *iterator_first_linear (const struct dictionary *dict, + struct dict_iterator *iterator); + +static struct symbol *iterator_next_linear (struct dict_iterator *iterator); + +static struct symbol *iter_name_first_linear (const struct dictionary *dict, + const char *name, + struct dict_iterator *iterator); + +static struct symbol *iter_name_next_linear (const char *name, + struct dict_iterator *iterator); + +static int size_linear (const struct dictionary *dict); + +/* Functions only for DICT_LINEAR_EXPANDABLE. */ + +static void free_linear_expandable (struct dictionary *dict); + +static void add_symbol_linear_expandable (struct dictionary *dict, + struct symbol *sym); + +/* Various vectors that we'll actually use. */ + +static const struct dict_vector dict_hashed_vector = + { + DICT_HASHED, /* type */ + free_obstack, /* free */ + add_symbol_nonexpandable, /* add_symbol */ + iterator_first_hashed, /* iteractor_first */ + iterator_next_hashed, /* iterator_next */ + iter_name_first_hashed, /* iter_name_first */ + iter_name_next_hashed, /* iter_name_next */ + size_hashed, /* size */ + }; + +static const struct dict_vector dict_hashed_expandable_vector = + { + DICT_HASHED_EXPANDABLE, /* type */ + free_hashed_expandable, /* free */ + add_symbol_hashed_expandable, /* add_symbol */ + iterator_first_hashed, /* iteractor_first */ + iterator_next_hashed, /* iterator_next */ + iter_name_first_hashed, /* iter_name_first */ + iter_name_next_hashed, /* iter_name_next */ + size_hashed_expandable, /* size */ + }; + +static const struct dict_vector dict_linear_vector = + { + DICT_LINEAR, /* type */ + free_obstack, /* free */ + add_symbol_nonexpandable, /* add_symbol */ + iterator_first_linear, /* iteractor_first */ + iterator_next_linear, /* iterator_next */ + iter_name_first_linear, /* iter_name_first */ + iter_name_next_linear, /* iter_name_next */ + size_linear, /* size */ + }; + +static const struct dict_vector dict_linear_expandable_vector = + { + DICT_LINEAR_EXPANDABLE, /* type */ + free_linear_expandable, /* free */ + add_symbol_linear_expandable, /* add_symbol */ + iterator_first_linear, /* iteractor_first */ + iterator_next_linear, /* iterator_next */ + iter_name_first_linear, /* iter_name_first */ + iter_name_next_linear, /* iter_name_next */ + size_linear, /* size */ + }; + +/* Declarations of helper functions (i.e. ones that don't go into + vectors). */ + +static struct symbol *iterator_hashed_advance (struct dict_iterator *iter); + +static void insert_symbol_hashed (struct dictionary *dict, + struct symbol *sym); + +static void expand_hashtable (struct dictionary *dict); + +/* The creation functions. */ + +/* Create a dictionary implemented via a fixed-size hashtable. All + memory it uses is allocated on OBSTACK; the environment is + initialized from SYMBOL_LIST. */ + +struct dictionary * +dict_create_hashed (struct obstack *obstack, + const struct pending *symbol_list) +{ + struct dictionary *retval; + int nsyms = 0, nbuckets, i; + struct symbol **buckets; + const struct pending *list_counter; + + retval = obstack_alloc (obstack, sizeof (struct dictionary)); + DICT_VECTOR (retval) = &dict_hashed_vector; + + /* Calculate the number of symbols, and allocate space for them. */ + for (list_counter = symbol_list; + list_counter != NULL; + list_counter = list_counter->next) + { + nsyms += list_counter->nsyms; + } + nbuckets = DICT_HASHTABLE_SIZE (nsyms); + DICT_HASHED_NBUCKETS (retval) = nbuckets; + buckets = obstack_alloc (obstack, nbuckets * sizeof (struct symbol *)); + memset (buckets, 0, nbuckets * sizeof (struct symbol *)); + DICT_HASHED_BUCKETS (retval) = buckets; + + /* Now fill the buckets. */ + for (list_counter = symbol_list; + list_counter != NULL; + list_counter = list_counter->next) + { + for (i = list_counter->nsyms - 1; i >= 0; --i) + { + insert_symbol_hashed (retval, list_counter->symbol[i]); + } + } + + return retval; +} + +/* Create a dictionary implemented via a hashtable that grows as + necessary. The dictionary is initially empty; to add symbols to + it, call dict_add_symbol(). Call dict_free() when you're done with + it. */ + +extern struct dictionary * +dict_create_hashed_expandable (void) +{ + struct dictionary *retval; + + retval = xmalloc (sizeof (struct dictionary)); + DICT_VECTOR (retval) = &dict_hashed_expandable_vector; + DICT_HASHED_NBUCKETS (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY; + DICT_HASHED_BUCKETS (retval) = xcalloc (DICT_EXPANDABLE_INITIAL_CAPACITY, + sizeof (struct symbol *)); + DICT_HASHED_EXPANDABLE_NSYMS (retval) = 0; + + return retval; +} + +/* Create a dictionary implemented via a fixed-size array. All memory + it uses is allocated on OBSTACK; the environment is initialized + from the SYMBOL_LIST. The symbols are ordered in the same order + that they're found in SYMBOL_LIST. */ + +struct dictionary * +dict_create_linear (struct obstack *obstack, + const struct pending *symbol_list) +{ + struct dictionary *retval; + int nsyms = 0, i, j; + struct symbol **syms; + const struct pending *list_counter; + + retval = obstack_alloc (obstack, sizeof (struct dictionary)); + DICT_VECTOR (retval) = &dict_linear_vector; + + /* Calculate the number of symbols, and allocate space for them. */ + for (list_counter = symbol_list; + list_counter != NULL; + list_counter = list_counter->next) + { + nsyms += list_counter->nsyms; + } + DICT_LINEAR_NSYMS (retval) = nsyms; + syms = obstack_alloc (obstack, nsyms * sizeof (struct symbol *)); + DICT_LINEAR_SYMS (retval) = syms; + + /* Now fill in the symbols. Start filling in from the back, so as + to preserve the original order of the symbols. */ + for (list_counter = symbol_list, j = nsyms - 1; + list_counter != NULL; + list_counter = list_counter->next) + { + for (i = list_counter->nsyms - 1; + i >= 0; + --i, --j) + { + syms[j] = list_counter->symbol[i]; + } + } + + return retval; +} + +/* Create a dictionary implemented via an array that grows as + necessary. The dictionary is initially empty; to add symbols to + it, call dict_add_symbol(). Call dict_free() when you're done with + it. */ + +struct dictionary * +dict_create_linear_expandable (void) +{ + struct dictionary *retval; + + retval = xmalloc (sizeof (struct dictionary)); + DICT_VECTOR (retval) = &dict_linear_expandable_vector; + DICT_LINEAR_NSYMS (retval) = 0; + DICT_LINEAR_EXPANDABLE_CAPACITY (retval) + = DICT_EXPANDABLE_INITIAL_CAPACITY; + DICT_LINEAR_SYMS (retval) + = xmalloc (DICT_LINEAR_EXPANDABLE_CAPACITY (retval) + * sizeof (struct symbol *)); + + return retval; +} + +/* The functions providing the dictionary interface. */ + +/* Free the memory used by a dictionary that's not on an obstack. (If + any.) */ + +void +dict_free (struct dictionary *dict) +{ + (DICT_VECTOR (dict))->free (dict); +} + +/* Add SYM to DICT. DICT had better be expandable. */ + +void +dict_add_symbol (struct dictionary *dict, struct symbol *sym) +{ + (DICT_VECTOR (dict))->add_symbol (dict, sym); +} + +/* Initialize ITERATOR to point at the first symbol in DICT, and + return that first symbol, or NULL if DICT is empty. */ + +struct symbol * +dict_iterator_first (const struct dictionary *dict, + struct dict_iterator *iterator) +{ + return (DICT_VECTOR (dict))->iterator_first (dict, iterator); +} + +/* Advance ITERATOR, and return the next symbol, or NULL if there are + no more symbols. */ + +struct symbol * +dict_iterator_next (struct dict_iterator *iterator) +{ + return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) + ->iterator_next (iterator); +} + +struct symbol * +dict_iter_name_first (const struct dictionary *dict, + const char *name, + struct dict_iterator *iterator) +{ + return (DICT_VECTOR (dict))->iter_name_first (dict, name, iterator); +} + +struct symbol * +dict_iter_name_next (const char *name, struct dict_iterator *iterator) +{ + return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) + ->iter_name_next (name, iterator); +} + +int +dict_size (const struct dictionary *dict) +{ + return (DICT_VECTOR (dict))->size (dict); +} + +/* Now come functions (well, one function, currently) that are + implemented generically by means of the vtable. Typically, they're + rarely used. */ + +/* Test to see if DICT is empty. */ + +int +dict_empty (struct dictionary *dict) +{ + struct dict_iterator iter; + + return (dict_iterator_first (dict, &iter) == NULL); +} + + +/* The functions implementing the dictionary interface. */ + +/* Generic functions, where appropriate. */ + +static void +free_obstack (struct dictionary *dict) +{ + /* Do nothing! */ +} + +static void +add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym) +{ + internal_error (__FILE__, __LINE__, + "dict_add_symbol: non-expandable dictionary"); +} + +/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE. */ + +static struct symbol * +iterator_first_hashed (const struct dictionary *dict, + struct dict_iterator *iterator) +{ + DICT_ITERATOR_DICT (iterator) = dict; + DICT_ITERATOR_INDEX (iterator) = -1; + return iterator_hashed_advance (iterator); +} + +static struct symbol * +iterator_next_hashed (struct dict_iterator *iterator) +{ + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); + struct symbol *next; + + next = DICT_ITERATOR_CURRENT (iterator)->hash_next; + + if (next == NULL) + return iterator_hashed_advance (iterator); + else + { + DICT_ITERATOR_CURRENT (iterator) = next; + return next; + } +} + +static struct symbol * +iterator_hashed_advance (struct dict_iterator *iterator) +{ + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); + int nbuckets = DICT_HASHED_NBUCKETS (dict); + int i; + + for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nbuckets; ++i) + { + struct symbol *sym = DICT_HASHED_BUCKET (dict, i); + + if (sym != NULL) + { + DICT_ITERATOR_INDEX (iterator) = i; + DICT_ITERATOR_CURRENT (iterator) = sym; + return sym; + } + } + + return NULL; +} + +static struct symbol * +iter_name_first_hashed (const struct dictionary *dict, + const char *name, + struct dict_iterator *iterator) +{ + unsigned int hash_index + = msymbol_hash_iw (name) % DICT_HASHED_NBUCKETS (dict); + struct symbol *sym; + + DICT_ITERATOR_DICT (iterator) = dict; + + /* Loop through the symbols in the given bucket, breaking when SYM + first matches. If SYM never matches, it will be set to NULL; + either way, we have the right return value. */ + + for (sym = DICT_HASHED_BUCKET (dict, hash_index); + sym != NULL; + sym = sym->hash_next) + { + /* Warning: the order of arguments to strcmp_iw matters! */ + if (strcmp_iw (SYMBOL_NATURAL_NAME (sym), name) == 0) + { + break; + } + + } + + DICT_ITERATOR_CURRENT (iterator) = sym; + return sym; +} + +static struct symbol * +iter_name_next_hashed (const char *name, struct dict_iterator *iterator) +{ + struct symbol *next; + + for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next; + next != NULL; + next = next->hash_next) + { + if (strcmp_iw (SYMBOL_NATURAL_NAME (next), name) == 0) + break; + } + + DICT_ITERATOR_CURRENT (iterator) = next; + + return next; +} + +/* Insert SYM into DICT. */ + +static void +insert_symbol_hashed (struct dictionary *dict, + struct symbol *sym) +{ + unsigned int hash_index; + struct symbol **buckets = DICT_HASHED_BUCKETS (dict); + + hash_index = (msymbol_hash_iw (SYMBOL_NATURAL_NAME (sym)) + % DICT_HASHED_NBUCKETS (dict)); + sym->hash_next = buckets[hash_index]; + buckets[hash_index] = sym; +} + +static int +size_hashed (const struct dictionary *dict) +{ + return DICT_HASHED_NBUCKETS (dict); +} + +/* Functions only for DICT_HASHED_EXPANDABLE. */ + +static void +free_hashed_expandable (struct dictionary *dict) +{ + xfree (DICT_HASHED_BUCKETS (dict)); + xfree (dict); +} + +static void +add_symbol_hashed_expandable (struct dictionary *dict, + struct symbol *sym) +{ + int nsyms = ++DICT_HASHED_EXPANDABLE_NSYMS (dict); + + if (DICT_HASHTABLE_SIZE (nsyms) > DICT_HASHED_NBUCKETS (dict)) + expand_hashtable (dict); + + insert_symbol_hashed (dict, sym); + DICT_HASHED_EXPANDABLE_NSYMS (dict) = nsyms; +} + +static int +size_hashed_expandable (const struct dictionary *dict) +{ + return DICT_HASHED_EXPANDABLE_NSYMS (dict); +} + +static void +expand_hashtable (struct dictionary *dict) +{ + int old_nbuckets = DICT_HASHED_NBUCKETS (dict); + struct symbol **old_buckets = DICT_HASHED_BUCKETS (dict); + int new_nbuckets = 2*old_nbuckets + 1; + struct symbol **new_buckets = xcalloc (new_nbuckets, + sizeof (struct symbol *)); + int i; + + DICT_HASHED_NBUCKETS (dict) = new_nbuckets; + DICT_HASHED_BUCKETS (dict) = new_buckets; + + for (i = 0; i < old_nbuckets; ++i) { + struct symbol *sym, *next_sym; + + sym = old_buckets[i]; + if (sym != NULL) { + for (next_sym = sym->hash_next; + next_sym != NULL; + next_sym = sym->hash_next) { + insert_symbol_hashed (dict, sym); + sym = next_sym; + } + + insert_symbol_hashed (dict, sym); + } + } + + xfree (old_buckets); +} + +/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE. */ + +static struct symbol * +iterator_first_linear (const struct dictionary *dict, + struct dict_iterator *iterator) +{ + DICT_ITERATOR_DICT (iterator) = dict; + DICT_ITERATOR_INDEX (iterator) = 0; + return DICT_LINEAR_NSYMS (dict) ? DICT_LINEAR_SYM (dict, 0) : NULL; +} + +static struct symbol * +iterator_next_linear (struct dict_iterator *iterator) +{ + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); + + if (++DICT_ITERATOR_INDEX (iterator) >= DICT_LINEAR_NSYMS (dict)) + return NULL; + else + return DICT_LINEAR_SYM (dict, DICT_ITERATOR_INDEX (iterator)); +} + +static struct symbol * +iter_name_first_linear (const struct dictionary *dict, + const char *name, + struct dict_iterator *iterator) +{ + DICT_ITERATOR_DICT (iterator) = dict; + DICT_ITERATOR_INDEX (iterator) = -1; + + return iter_name_next_linear (name, iterator); +} + +static struct symbol * +iter_name_next_linear (const char *name, struct dict_iterator *iterator) +{ + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); + int i, nsyms = DICT_LINEAR_NSYMS (dict); + struct symbol *sym, *retval = NULL; + + for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i) + { + sym = DICT_LINEAR_SYM (dict, i); + if (strcmp_iw (SYMBOL_NATURAL_NAME (sym), name) == 0) + { + retval = sym; + break; + } + } + + DICT_ITERATOR_INDEX (iterator) = i; + + return retval; +} + +static int +size_linear (const struct dictionary *dict) +{ + return DICT_LINEAR_NSYMS (dict); +} + +/* Functions only for DICT_LINEAR_EXPANDABLE. */ + +static void +free_linear_expandable (struct dictionary *dict) +{ + xfree (DICT_LINEAR_SYMS (dict)); + xfree (dict); +} + + +static void +add_symbol_linear_expandable (struct dictionary *dict, + struct symbol *sym) +{ + int nsyms = ++DICT_LINEAR_NSYMS (dict); + + /* Do we have enough room? If not, grow it. */ + if (nsyms > DICT_LINEAR_EXPANDABLE_CAPACITY (dict)) { + DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2; + DICT_LINEAR_SYMS (dict) + = xrealloc (DICT_LINEAR_SYMS (dict), + DICT_LINEAR_EXPANDABLE_CAPACITY (dict) + * sizeof (struct symbol *)); + } + + DICT_LINEAR_SYM (dict, nsyms - 1) = sym; +} diff --git a/contrib/gdb/gdb/dictionary.h b/contrib/gdb/gdb/dictionary.h new file mode 100644 index 00000000000..75edd7fb67a --- /dev/null +++ b/contrib/gdb/gdb/dictionary.h @@ -0,0 +1,156 @@ +/* Routines for name->symbol lookups in GDB. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by David Carlton and by Kealia, + Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef DICTIONARY_H +#define DICTIONARY_H + +/* An opaque type for dictionaries; only dictionary.c should know + about its innards. */ + +struct dictionary; + +/* Other types needed for declarations. */ + +struct symbol; +struct obstack; +struct pending; + + +/* The creation functions for various implementations of + dictionaries. */ + +/* Create a dictionary implemented via a fixed-size hashtable. All + memory it uses is allocated on OBSTACK; the environment is + initialized from SYMBOL_LIST. */ + +extern struct dictionary *dict_create_hashed (struct obstack *obstack, + const struct pending + *symbol_list); + +/* Create a dictionary implemented via a hashtable that grows as + necessary. The dictionary is initially empty; to add symbols to + it, call dict_add_symbol(). Call dict_free() when you're done with + it. */ + +extern struct dictionary *dict_create_hashed_expandable (void); + +/* Create a dictionary implemented via a fixed-size array. All memory + it uses is allocated on OBSTACK; the environment is initialized + from the SYMBOL_LIST. The symbols are ordered in the same order + that they're found in SYMBOL_LIST. */ + +extern struct dictionary *dict_create_linear (struct obstack *obstack, + const struct pending + *symbol_list); + +/* Create a dictionary implemented via an array that grows as + necessary. The dictionary is initially empty; to add symbols to + it, call dict_add_symbol(). Call dict_free() when you're done with + it. */ + +extern struct dictionary *dict_create_linear_expandable (void); + + +/* The functions providing the interface to dictionaries. Note that + the most common parts of the interface, namely symbol lookup, are + only provided via iterator functions. */ + +/* Free the memory used by a dictionary that's not on an obstack. (If + any.) */ + +extern void dict_free (struct dictionary *dict); + +/* Add a symbol to an expandable dictionary. */ + +extern void dict_add_symbol (struct dictionary *dict, struct symbol *sym); + +/* Is the dictionary empty? */ + +extern int dict_empty (struct dictionary *dict); + +/* A type containing data that is used when iterating over all symbols + in a dictionary. Don't ever look at its innards; this type would + be opaque if we didn't need to be able to allocate it on the + stack. */ + +struct dict_iterator +{ + /* The dictionary that this iterator is associated to. */ + const struct dictionary *dict; + /* The next two members are data that is used in a way that depends + on DICT's implementation type. */ + int index; + struct symbol *current; +}; + +/* Initialize ITERATOR to point at the first symbol in DICT, and + return that first symbol, or NULL if DICT is empty. */ + +extern struct symbol *dict_iterator_first (const struct dictionary *dict, + struct dict_iterator *iterator); + +/* Advance ITERATOR, and return the next symbol, or NULL if there are + no more symbols. Don't call this if you've previously received + NULL from dict_iterator_first or dict_iterator_next on this + iteration. */ + +extern struct symbol *dict_iterator_next (struct dict_iterator *iterator); + +/* Initialize ITERATOR to point at the first symbol in DICT whose + SYMBOL_BEST_NAME is NAME (as tested using strcmp_iw), and return + that first symbol, or NULL if there are no such symbols. */ + +extern struct symbol *dict_iter_name_first (const struct dictionary *dict, + const char *name, + struct dict_iterator *iterator); + +/* Advance ITERATOR to point at the next symbol in DICT whose + SYMBOL_BEST_NAME is NAME (as tested using strcmp_iw), or NULL if + there are no more such symbols. Don't call this if you've + previously received NULL from dict_iterator_first or + dict_iterator_next on this iteration. And don't call it unless + ITERATOR was created by a previous call to dict_iter_name_first + with the same NAME. */ + +extern struct symbol *dict_iter_name_next (const char *name, + struct dict_iterator *iterator); + +/* Return some notion of the size of the dictionary: the number of + symbols if we have that, the number of hash buckets otherwise. */ + +extern int dict_size (const struct dictionary *dict); + +/* Macro to loop through all symbols in a dictionary DICT, in no + particular order. ITER is a struct dict_iterator (NOTE: __not__ a + struct dict_iterator *), and SYM points to the current symbol. + + It's implemented as a single loop, so you can terminate the loop + early by a break if you desire. */ + +#define ALL_DICT_SYMBOLS(dict, iter, sym) \ + for ((sym) = dict_iterator_first ((dict), &(iter)); \ + (sym); \ + (sym) = dict_iterator_next (&(iter))) + +#endif /* DICTIONARY_H */ diff --git a/contrib/gdb/gdb/dink32-rom.c b/contrib/gdb/gdb/dink32-rom.c index f62e7129c36..4a6814093a0 100644 --- a/contrib/gdb/gdb/dink32-rom.c +++ b/contrib/gdb/gdb/dink32-rom.c @@ -96,19 +96,6 @@ dink32_supply_register (char *regname, int regnamelen, char *val, int vallen) monitor_supply_register (regno, val); } -static void -dink32_load (struct monitor_ops *monops, char *filename, int from_tty) -{ - generic_load (filename, from_tty); - - /* Finally, make the PC point at the start address */ - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - inferior_ptid = null_ptid; /* No process now */ -} - - /* This array of registers needs to match the indexes used by GDB. The whole reason this exists is because the various ROM monitors use different names than GDB does, and don't support all the registers @@ -142,6 +129,8 @@ dink32_open (char *args, int from_tty) monitor_open (args, &dink32_cmds, from_tty); } +extern initialize_file_ftype _initialize_dink32_rom; /* -Wmissing-prototypes */ + void _initialize_dink32_rom (void) { @@ -170,9 +159,6 @@ _initialize_dink32_rom (void) /* S-record download, via "keyboard port". */ dink32_cmds.load = "dl -k\r"; dink32_cmds.loadresp = "Set Input Port : set to Keyboard Port\r"; -#if 0 /* slow load routine not needed if S-records work... */ - dink32_cmds.load_routine = dink32_load; -#endif dink32_cmds.prompt = "DINK32_603 >>"; dink32_cmds.line_term = "\r"; dink32_cmds.target = &dink32_ops; diff --git a/contrib/gdb/gdb/disasm.c b/contrib/gdb/gdb/disasm.c new file mode 100644 index 00000000000..3cde2ea9040 --- /dev/null +++ b/contrib/gdb/gdb/disasm.c @@ -0,0 +1,395 @@ +/* Disassemble support for GDB. + + Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "target.h" +#include "value.h" +#include "ui-out.h" +#include "gdb_string.h" +#include "disasm.h" +#include "gdbcore.h" +#include "dis-asm.h" + +/* Disassemble functions. + FIXME: We should get rid of all the duplicate code in gdb that does + the same thing: disassemble_command() and the gdbtk variation. */ + +/* This Structure is used to store line number information. + We need a different sort of line table from the normal one cuz we can't + depend upon implicit line-end pc's for lines to do the + reordering in this function. */ + +struct dis_line_entry +{ + int line; + CORE_ADDR start_pc; + CORE_ADDR end_pc; +}; + +/* Like target_read_memory, but slightly different parameters. */ +static int +dis_asm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int len, + struct disassemble_info *info) +{ + return target_read_memory (memaddr, (char *) myaddr, len); +} + +/* Like memory_error with slightly different parameters. */ +static void +dis_asm_memory_error (int status, bfd_vma memaddr, + struct disassemble_info *info) +{ + memory_error (status, memaddr); +} + +/* Like print_address with slightly different parameters. */ +static void +dis_asm_print_address (bfd_vma addr, struct disassemble_info *info) +{ + print_address (addr, info->stream); +} + +static int +compare_lines (const void *mle1p, const void *mle2p) +{ + struct dis_line_entry *mle1, *mle2; + int val; + + mle1 = (struct dis_line_entry *) mle1p; + mle2 = (struct dis_line_entry *) mle2p; + + val = mle1->line - mle2->line; + + if (val != 0) + return val; + + return mle1->start_pc - mle2->start_pc; +} + +static int +dump_insns (struct ui_out *uiout, struct disassemble_info * di, + CORE_ADDR low, CORE_ADDR high, + int how_many, struct ui_stream *stb) +{ + int num_displayed = 0; + CORE_ADDR pc; + + /* parts of the symbolic representation of the address */ + int unmapped; + int offset; + int line; + struct cleanup *ui_out_chain; + + for (pc = low; pc < high;) + { + char *filename = NULL; + char *name = NULL; + + QUIT; + if (how_many >= 0) + { + if (num_displayed >= how_many) + break; + else + num_displayed++; + } + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + ui_out_field_core_addr (uiout, "address", pc); + + if (!build_address_symbolic (pc, 0, &name, &offset, &filename, + &line, &unmapped)) + { + /* We don't care now about line, filename and + unmapped. But we might in the future. */ + ui_out_text (uiout, " <"); + ui_out_field_string (uiout, "func-name", name); + ui_out_text (uiout, "+"); + ui_out_field_int (uiout, "offset", offset); + ui_out_text (uiout, ">:\t"); + } + else + ui_out_text (uiout, ":\t"); + + if (filename != NULL) + xfree (filename); + if (name != NULL) + xfree (name); + + ui_file_rewind (stb->stream); + pc += TARGET_PRINT_INSN (pc, di); + ui_out_field_stream (uiout, "inst", stb); + ui_file_rewind (stb->stream); + do_cleanups (ui_out_chain); + ui_out_text (uiout, "\n"); + } + return num_displayed; +} + +/* The idea here is to present a source-O-centric view of a + function to the user. This means that things are presented + in source order, with (possibly) out of order assembly + immediately following. */ +static void +do_mixed_source_and_assembly (struct ui_out *uiout, + struct disassemble_info *di, int nlines, + struct linetable_entry *le, + CORE_ADDR low, CORE_ADDR high, + struct symtab *symtab, + int how_many, struct ui_stream *stb) +{ + int newlines = 0; + struct dis_line_entry *mle; + struct symtab_and_line sal; + int i; + int out_of_order = 0; + int next_line = 0; + CORE_ADDR pc; + int num_displayed = 0; + struct cleanup *ui_out_chain; + struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0); + struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0); + + mle = (struct dis_line_entry *) alloca (nlines + * sizeof (struct dis_line_entry)); + + /* Copy linetable entries for this function into our data + structure, creating end_pc's and setting out_of_order as + appropriate. */ + + /* First, skip all the preceding functions. */ + + for (i = 0; i < nlines - 1 && le[i].pc < low; i++); + + /* Now, copy all entries before the end of this function. */ + + for (; i < nlines - 1 && le[i].pc < high; i++) + { + if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc) + continue; /* Ignore duplicates */ + + /* Skip any end-of-function markers. */ + if (le[i].line == 0) + continue; + + mle[newlines].line = le[i].line; + if (le[i].line > le[i + 1].line) + out_of_order = 1; + mle[newlines].start_pc = le[i].pc; + mle[newlines].end_pc = le[i + 1].pc; + newlines++; + } + + /* If we're on the last line, and it's part of the function, + then we need to get the end pc in a special way. */ + + if (i == nlines - 1 && le[i].pc < high) + { + mle[newlines].line = le[i].line; + mle[newlines].start_pc = le[i].pc; + sal = find_pc_line (le[i].pc, 0); + mle[newlines].end_pc = sal.end; + newlines++; + } + + /* Now, sort mle by line #s (and, then by addresses within + lines). */ + + if (out_of_order) + qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines); + + /* Now, for each line entry, emit the specified lines (unless + they have been emitted before), followed by the assembly code + for that line. */ + + ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); + + for (i = 0; i < newlines; i++) + { + /* Print out everything from next_line to the current line. */ + if (mle[i].line >= next_line) + { + if (next_line != 0) + { + /* Just one line to print. */ + if (next_line == mle[i].line) + { + ui_out_tuple_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, + "src_and_asm_line"); + print_source_lines (symtab, next_line, mle[i].line + 1, 0); + } + else + { + /* Several source lines w/o asm instructions associated. */ + for (; next_line < mle[i].line; next_line++) + { + struct cleanup *ui_out_list_chain_line; + struct cleanup *ui_out_tuple_chain_line; + + ui_out_tuple_chain_line + = make_cleanup_ui_out_tuple_begin_end (uiout, + "src_and_asm_line"); + print_source_lines (symtab, next_line, next_line + 1, + 0); + ui_out_list_chain_line + = make_cleanup_ui_out_list_begin_end (uiout, + "line_asm_insn"); + do_cleanups (ui_out_list_chain_line); + do_cleanups (ui_out_tuple_chain_line); + } + /* Print the last line and leave list open for + asm instructions to be added. */ + ui_out_tuple_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, + "src_and_asm_line"); + print_source_lines (symtab, next_line, mle[i].line + 1, 0); + } + } + else + { + ui_out_tuple_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line"); + print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0); + } + + next_line = mle[i].line + 1; + ui_out_list_chain + = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn"); + } + + num_displayed += dump_insns (uiout, di, mle[i].start_pc, mle[i].end_pc, + how_many, stb); + + /* When we've reached the end of the mle array, or we've seen the last + assembly range for this source line, close out the list/tuple. */ + if (i == (newlines - 1) || mle[i + 1].line > mle[i].line) + { + do_cleanups (ui_out_list_chain); + do_cleanups (ui_out_tuple_chain); + ui_out_tuple_chain = make_cleanup (null_cleanup, 0); + ui_out_list_chain = make_cleanup (null_cleanup, 0); + ui_out_text (uiout, "\n"); + } + if (how_many >= 0 && num_displayed >= how_many) + break; + } + do_cleanups (ui_out_chain); +} + + +static void +do_assembly_only (struct ui_out *uiout, struct disassemble_info * di, + CORE_ADDR low, CORE_ADDR high, + int how_many, struct ui_stream *stb) +{ + int num_displayed = 0; + struct cleanup *ui_out_chain; + + ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); + + num_displayed = dump_insns (uiout, di, low, high, how_many, stb); + + do_cleanups (ui_out_chain); +} + +/* Initialize the disassemble info struct ready for the specified + stream. */ + +static int +fprintf_disasm (void *stream, const char *format, ...) +{ + va_list args; + va_start (args, format); + vfprintf_filtered (stream, format, args); + va_end (args); + /* Something non -ve. */ + return 0; +} + +static struct disassemble_info +gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file) +{ + struct disassemble_info di; + init_disassemble_info (&di, file, fprintf_disasm); + di.flavour = bfd_target_unknown_flavour; + di.memory_error_func = dis_asm_memory_error; + di.print_address_func = dis_asm_print_address; + /* NOTE: cagney/2003-04-28: The original code, from the old Insight + disassembler had a local optomization here. By default it would + access the executable file, instead of the target memory (there + was a growing list of exceptions though). Unfortunately, the + heuristic was flawed. Commands like "disassemble &variable" + didn't work as they relied on the access going to the target. + Further, it has been supperseeded by trust-read-only-sections + (although that should be superseeded by target_trust..._p()). */ + di.read_memory_func = dis_asm_read_memory; + di.arch = gdbarch_bfd_arch_info (gdbarch)->arch; + di.mach = gdbarch_bfd_arch_info (gdbarch)->mach; + di.endian = gdbarch_byte_order (gdbarch); + return di; +} + +void +gdb_disassembly (struct ui_out *uiout, + char *file_string, + int line_num, + int mixed_source_and_assembly, + int how_many, CORE_ADDR low, CORE_ADDR high) +{ + struct ui_stream *stb = ui_out_stream_new (uiout); + struct cleanup *cleanups = make_cleanup_ui_out_stream_delete (stb); + struct disassemble_info di = gdb_disassemble_info (current_gdbarch, stb->stream); + /* To collect the instruction outputted from opcodes. */ + struct symtab *symtab = NULL; + struct linetable_entry *le = NULL; + int nlines = -1; + + /* Assume symtab is valid for whole PC range */ + symtab = find_pc_symtab (low); + + if (symtab != NULL && symtab->linetable != NULL) + { + /* Convert the linetable to a bunch of my_line_entry's. */ + le = symtab->linetable->item; + nlines = symtab->linetable->nitems; + } + + if (!mixed_source_and_assembly || nlines <= 0 + || symtab == NULL || symtab->linetable == NULL) + do_assembly_only (uiout, &di, low, high, how_many, stb); + + else if (mixed_source_and_assembly) + do_mixed_source_and_assembly (uiout, &di, nlines, le, low, + high, symtab, how_many, stb); + + do_cleanups (cleanups); + gdb_flush (gdb_stdout); +} + +/* Print the instruction at address MEMADDR in debugged memory, + on STREAM. Returns length of the instruction, in bytes. */ + +int +gdb_print_insn (CORE_ADDR memaddr, struct ui_file *stream) +{ + struct disassemble_info di = gdb_disassemble_info (current_gdbarch, stream); + return TARGET_PRINT_INSN (memaddr, &di); +} diff --git a/contrib/gdb/gdb/disasm.h b/contrib/gdb/gdb/disasm.h new file mode 100644 index 00000000000..b5dbb840d24 --- /dev/null +++ b/contrib/gdb/gdb/disasm.h @@ -0,0 +1,38 @@ +/* Disassemble support for GDB. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef DISASM_H +#define DISASM_H + +struct ui_out; +struct ui_file; + +extern void gdb_disassembly (struct ui_out *uiout, + char *file_string, + int line_num, + int mixed_source_and_assembly, + int how_many, CORE_ADDR low, CORE_ADDR high); + +/* Print the instruction at address MEMADDR in debugged memory, on + STREAM. Returns length of the instruction, in bytes. */ + +extern int gdb_print_insn (CORE_ADDR memaddr, struct ui_file *stream); + +#endif diff --git a/contrib/gdb/gdb/doc/GDBvn.texi b/contrib/gdb/gdb/doc/GDBvn.texi index 4cd0e3b9f01..38987b5cff0 100644 --- a/contrib/gdb/gdb/doc/GDBvn.texi +++ b/contrib/gdb/gdb/doc/GDBvn.texi @@ -1 +1 @@ -@set GDBVN 5.2.1 +@set GDBVN 6.1.1 diff --git a/contrib/gdb/gdb/doc/agentexpr.texi b/contrib/gdb/gdb/doc/agentexpr.texi index e49232c9afd..491ae2e0ec3 100644 --- a/contrib/gdb/gdb/doc/agentexpr.texi +++ b/contrib/gdb/gdb/doc/agentexpr.texi @@ -1,14 +1,14 @@ -\input texinfo +@c \input texinfo @c %**start of header -@setfilename agentexpr.info -@settitle GDB Agent Expressions -@setchapternewpage off +@c @setfilename agentexpr.info +@c @settitle GDB Agent Expressions +@c @setchapternewpage off @c %**end of header -Revision: $Id: agentexpr.texi,v 1.2 1998/12/09 21:23:46 jimb Exp $ +@c Revision: $Id: agentexpr.texi,v 1.2 1998/12/09 21:23:46 jimb Exp $ -@node The GDB Agent Expression Mechanism -@chapter The GDB Agent Expression Mechanism +@node Agent Expressions +@appendix The GDB Agent Expression Mechanism In some applications, it is not feasable for the debugger to interrupt the program's execution long enough for the developer to learn anything @@ -299,7 +299,7 @@ Pop two integers from the stack; let @var{a} be the next-to-top value, and @var{b} be the top value. Shift @var{a} left by @var{b} bits, and push the result. -@item @code{rsh_signed} (0x0a): @var{a} @var{b} @result{} @var{@code{(signed)}a>>b} +@item @code{rsh_signed} (0x0a): @var{a} @var{b} @result{} @code{(signed)}@var{a>>b} Pop two integers from the stack; let @var{a} be the next-to-top value, and @var{b} be the top value. Shift @var{a} right by @var{b} bits, inserting copies of the top bit at the high end, and push the result. @@ -397,7 +397,7 @@ Thus, an offset of zero denotes the beginning of the expression. The @var{offset} is stored as a sixteen-bit unsigned value, stored immediately following the @code{if_goto} bytecode. It is always stored -most signficant byte first, regardless of the target's normal +most significant byte first, regardless of the target's normal endianness. The offset is not guaranteed to fall at any particular alignment within the bytecode stream; thus, on machines where fetching a 16-bit on an unaligned address raises an exception, you should fetch the @@ -431,7 +431,7 @@ registers are numbered following GDB's conventions. The register number @var{n} is encoded as a 16-bit unsigned integer immediately following the @code{reg} bytecode. It is always stored most -signficant byte first, regardless of the target's normal endianness. +significant byte first, regardless of the target's normal endianness. The register number is not guaranteed to fall at any particular alignment within the bytecode stream; thus, on machines where fetching a 16-bit on an unaligned address raises an exception, you should fetch the @@ -835,5 +835,3 @@ opcode 0x30 reserved, to remain compatible with the customer who added it. @end table - -@bye diff --git a/contrib/gdb/gdb/doc/all-cfg.texi b/contrib/gdb/gdb/doc/all-cfg.texi index 6dee4e4ef67..b680ea2b492 100644 --- a/contrib/gdb/gdb/doc/all-cfg.texi +++ b/contrib/gdb/gdb/doc/all-cfg.texi @@ -1,5 +1,6 @@ @c GDB MANUAL configuration file. -@c Copyright 1993, 1995, 1999 Free Software Foundation, Inc. +@c +@c Copyright 1993, 1995, 1999, 2002 Free Software Foundation, Inc. @c @c NOTE: While the GDB manual is configurable (by changing these @c switches), its configuration is ***NOT*** automatically tied in to @@ -31,15 +32,14 @@ @set GDBP gdb @c @c Name of GDB product. Used in running text. -@set GDBN GDB +@set GDBN @sc{gdb} @c @c Name of host. Should not be used in generic configs, but generic @c value may catch some flubs. @set HOST machine specific @c @c Name of GCC product -@set NGCC GCC +@set NGCC @sc{gcc} @c @c Name of GCC program @set GCC gcc - diff --git a/contrib/gdb/gdb/doc/annotate.texinfo b/contrib/gdb/gdb/doc/annotate.texinfo new file mode 100644 index 00000000000..2fb79d39d0e --- /dev/null +++ b/contrib/gdb/gdb/doc/annotate.texinfo @@ -0,0 +1,834 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename annotate.info + +@c This is a dir.info fragment to support semi-automated addition of +@c manuals to an info tree. +@dircategory Software development +@direntry +* Annotate: (annotate). The obsolete annotation interface. +@end direntry + +@c +@include gdb-cfg.texi +@c +@settitle @value{GDBN}'s Obsolete Annotations +@setchapternewpage off +@c %**end of header + +@set EDITION 1.0 +@set DATE July 2003 + +@c NOTE: cagney/2003-07-28: +@c Don't make this migration doccument an appendix of GDB's user guide. +@c By keeping this separate, the size of the user guide is contained. If +@c the user guide to get much bigger it would need to switch to a larger, +@c more expensive, form factor and would drive up the manuals publication +@c cost. Having a smaller cheaper manual helps the GNU Press with its sales. + +@ifinfo +This file documents @value{GDBN}'s obsolete annotations. + +Copyright 1994, 1995, 2000, 2001, 2003 Free Software Foundation, Inc. + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled ``GNU +Free Documentation License''. + +@end ifinfo + +@titlepage +@title @value{GDBN}'s Obsolete Annotations +@subtitle Edition @value{EDITION} +@subtitle @value{DATE} +@author Free Software Foundation +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1994, 1995, 2000, 2001, 2003 Free Software +Foundation, Inc. + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled ``GNU +Free Documentation License''. +@end titlepage + +@ifinfo +@node Top +@top GDB Annotations + +This document describes the obsolete level two annotation interface +implemented in older @value{GDBN} versions. + +@ignore +This is Edition @value{EDITION}, @value{DATE}. +@end ignore +@end ifinfo + +@menu +* Annotations Overview:: What annotations are; the general syntax. +* Limitations:: Limitations of the annotation interface. +* Migrating to GDB/MI:: Migrating to GDB/MI +* Server Prefix:: Issuing a command without affecting user state. +* Value Annotations:: Values are marked as such. +* Frame Annotations:: Stack frames are annotated. +* Displays:: @value{GDBN} can be told to display something periodically. +* Prompting:: Annotations marking @value{GDBN}'s need for input. +* Errors:: Annotations for error messages. +* Breakpoint Info:: Information on breakpoints. +* Invalidation:: Some annotations describe things now invalid. +* Annotations for Running:: + Whether the program is running, how it stopped, etc. +* Source Annotations:: Annotations describing source code. + +* GNU Free Documentation License:: +@end menu + +@contents + +@node Annotations Overview +@chapter What is an Annotation? +@cindex annotations + +To produce obsolete level two annotations, start @value{GDBN} with the +@code{--annotate=2} option. + +Annotations start with a newline character, two @samp{control-z} +characters, and the name of the annotation. If there is no additional +information associated with this annotation, the name of the annotation +is followed immediately by a newline. If there is additional +information, the name of the annotation is followed by a space, the +additional information, and a newline. The additional information +cannot contain newline characters. + +Any output not beginning with a newline and two @samp{control-z} +characters denotes literal output from @value{GDBN}. Currently there is +no need for @value{GDBN} to output a newline followed by two +@samp{control-z} characters, but if there was such a need, the +annotations could be extended with an @samp{escape} annotation which +means those three characters as output. + +A simple example of starting up @value{GDBN} with annotations is: + +@smallexample +$ gdb --annotate=2 +GNU GDB 5.0 +Copyright 2000 Free Software Foundation, Inc. +GDB is free software, covered by the GNU General Public License, +and you are welcome to change it and/or distribute copies of it +under certain conditions. +Type "show copying" to see the conditions. +There is absolutely no warranty for GDB. Type "show warranty" +for details. +This GDB was configured as "sparc-sun-sunos4.1.3" + +^Z^Zpre-prompt +(gdb) +^Z^Zprompt +quit + +^Z^Zpost-prompt +$ +@end smallexample + +Here @samp{quit} is input to @value{GDBN}; the rest is output from +@value{GDBN}. The three lines beginning @samp{^Z^Z} (where @samp{^Z} +denotes a @samp{control-z} character) are annotations; the rest is +output from @value{GDBN}. + +@node Limitations +@chapter Limitations of the Annotation Interface + +The level two annotations mechanism is known to have a number of +technical and architectural limitations. As a consequence, in 2001, +with the release of @value{GDBN} 5.1 and the addition of @sc{gdb/mi}, +the annotation interface was marked as deprecated. + +This chapter discusses the known problems. + +@section Dependant on @sc{cli} output + +The annotation interface works by interspersing markups with +@value{GDBN} normal command-line interpreter output. Unfortunately, this +makes the annotation client dependant on not just the annotations, but +also the @sc{cli} output. This is because the client is forced to +assume that specific @value{GDBN} commands provide specific information. +Any change to @value{GDBN}'s @sc{cli} output modifies or removes that +information and, consequently, likely breaks the client. + +Since the @sc{gdb/mi} output is independant of the @sc{cli}, it does not +have this problem. + +@section Scalability + +The annotation interface relies on value annotations (@pxref{Value +Annotations}) and the display mechanism as a way of obtaining up-to-date +value information. These mechanisms are not scalable. + +In a graphical environment, where many values can be displayed +simultaneously, a serious performance problem occurs when the client +tries to first extract from @value{GDBN}, and then re-display, all those +values. The client should instead only request and update the values +that changed. + +The @sc{gdb/mi} Variable Objects provide just that mechanism. + +@section Correctness + +The annotation interface assumes that a variable's value can only be +changed when the target is running. This assumption is not correct. A +single assignment to a single variable can result in the entire target, +and all displayed values, needing an update. + +The @sc{gdb/mi} Variable Objects include a mechanism for efficiently +reporting such changes. + +@section Reliability + +The @sc{gdb/mi} interface includes a dedicated test directory +(@file{gdb/gdb.mi}), and any addition or fix to @sc{gdb/mi} must include +testsuite changes. + +@section Maintainability + +The annotation mechanism was implemented by interspersing @sc{cli} print +statements with various annotations. As a consequence, any @sc{cli} +output change can alter the annotation output. + +Since the @sc{gdb/mi} output is independant of the @sc{cli}, and the +@sc{gdb/mi} is increasingly implemented independant of the @sc{cli} +code, its long term maintenance is much easier. + +@node Migrating to GDB/MI +@chapter Migrating to @sc{gdb/mi} + +By using the @samp{interp mi} command, it is possible for annotation +clients to invoke @sc{gdb/mi} commands, and hence access the +@sc{gdb/mi}. By doing this, existing annotation clients have a +migration path from this obsolete interface to @sc{gdb/mi}. + +@node Server Prefix +@chapter The Server Prefix +@cindex server prefix for annotations + +To issue a command to @value{GDBN} without affecting certain aspects of +the state which is seen by users, prefix it with @samp{server }. This +means that this command will not affect the command history, nor will it +affect @value{GDBN}'s notion of which command to repeat if @key{RET} is +pressed on a line by itself. + +The server prefix does not affect the recording of values into the value +history; to print a value without recording it into the value history, +use the @code{output} command instead of the @code{print} command. + +@node Value Annotations +@chapter Values + +@emph{Value Annotations have been removed. @sc{gdb/mi} instead provides +Variable Objects.} + +@cindex annotations for values +When a value is printed in various contexts, @value{GDBN} uses +annotations to delimit the value from the surrounding text. + +@findex value-history-begin +@findex value-history-value +@findex value-history-end +If a value is printed using @code{print} and added to the value history, +the annotation looks like + +@smallexample +^Z^Zvalue-history-begin @var{history-number} @var{value-flags} +@var{history-string} +^Z^Zvalue-history-value +@var{the-value} +^Z^Zvalue-history-end +@end smallexample + +@noindent +where @var{history-number} is the number it is getting in the value +history, @var{history-string} is a string, such as @samp{$5 = }, which +introduces the value to the user, @var{the-value} is the output +corresponding to the value itself, and @var{value-flags} is @samp{*} for +a value which can be dereferenced and @samp{-} for a value which cannot. + +@findex value-begin +@findex value-end +If the value is not added to the value history (it is an invalid float +or it is printed with the @code{output} command), the annotation is similar: + +@smallexample +^Z^Zvalue-begin @var{value-flags} +@var{the-value} +^Z^Zvalue-end +@end smallexample + +@findex arg-begin +@findex arg-name-end +@findex arg-value +@findex arg-end +When @value{GDBN} prints an argument to a function (for example, in the output +from the @code{backtrace} command), it annotates it as follows: + +@smallexample +^Z^Zarg-begin +@var{argument-name} +^Z^Zarg-name-end +@var{separator-string} +^Z^Zarg-value @var{value-flags} +@var{the-value} +^Z^Zarg-end +@end smallexample + +@noindent +where @var{argument-name} is the name of the argument, +@var{separator-string} is text which separates the name from the value +for the user's benefit (such as @samp{=}), and @var{value-flags} and +@var{the-value} have the same meanings as in a +@code{value-history-begin} annotation. + +@findex field-begin +@findex field-name-end +@findex field-value +@findex field-end +When printing a structure, @value{GDBN} annotates it as follows: + +@smallexample +^Z^Zfield-begin @var{value-flags} +@var{field-name} +^Z^Zfield-name-end +@var{separator-string} +^Z^Zfield-value +@var{the-value} +^Z^Zfield-end +@end smallexample + +@noindent +where @var{field-name} is the name of the field, @var{separator-string} +is text which separates the name from the value for the user's benefit +(such as @samp{=}), and @var{value-flags} and @var{the-value} have the +same meanings as in a @code{value-history-begin} annotation. + +When printing an array, @value{GDBN} annotates it as follows: + +@smallexample +^Z^Zarray-section-begin @var{array-index} @var{value-flags} +@end smallexample + +@noindent +where @var{array-index} is the index of the first element being +annotated and @var{value-flags} has the same meaning as in a +@code{value-history-begin} annotation. This is followed by any number +of elements, where is element can be either a single element: + +@findex elt +@smallexample +@samp{,} @var{whitespace} ; @r{omitted for the first element} +@var{the-value} +^Z^Zelt +@end smallexample + +or a repeated element + +@findex elt-rep +@findex elt-rep-end +@smallexample +@samp{,} @var{whitespace} ; @r{omitted for the first element} +@var{the-value} +^Z^Zelt-rep @var{number-of-repetitions} +@var{repetition-string} +^Z^Zelt-rep-end +@end smallexample + +In both cases, @var{the-value} is the output for the value of the +element and @var{whitespace} can contain spaces, tabs, and newlines. In +the repeated case, @var{number-of-repetitions} is the number of +consecutive array elements which contain that value, and +@var{repetition-string} is a string which is designed to convey to the +user that repetition is being depicted. + +@findex array-section-end +Once all the array elements have been output, the array annotation is +ended with + +@smallexample +^Z^Zarray-section-end +@end smallexample + +@node Frame Annotations +@chapter Frames + +@emph{Value Annotations have been removed. @sc{gdb/mi} instead provides +a number of frame commands.} + +@emph{Frame annotations are no longer available. The @sc{gdb/mi} +provides @samp{-stack-list-arguments}, @samp{-stack-list-locals}, and +@samp{-stack-list-frames} commands.} + +@cindex annotations for frames +Whenever @value{GDBN} prints a frame, it annotates it. For example, this applies +to frames printed when @value{GDBN} stops, output from commands such as +@code{backtrace} or @code{up}, etc. + +@findex frame-begin +The frame annotation begins with + +@smallexample +^Z^Zframe-begin @var{level} @var{address} +@var{level-string} +@end smallexample + +@noindent +where @var{level} is the number of the frame (0 is the innermost frame, +and other frames have positive numbers), @var{address} is the address of +the code executing in that frame, and @var{level-string} is a string +designed to convey the level to the user. @var{address} is in the form +@samp{0x} followed by one or more lowercase hex digits (note that this +does not depend on the language). The frame ends with + +@findex frame-end +@smallexample +^Z^Zframe-end +@end smallexample + +Between these annotations is the main body of the frame, which can +consist of + +@itemize @bullet +@item +@findex function-call +@smallexample +^Z^Zfunction-call +@var{function-call-string} +@end smallexample + +where @var{function-call-string} is text designed to convey to the user +that this frame is associated with a function call made by @value{GDBN} to a +function in the program being debugged. + +@item +@findex signal-handler-caller +@smallexample +^Z^Zsignal-handler-caller +@var{signal-handler-caller-string} +@end smallexample + +where @var{signal-handler-caller-string} is text designed to convey to +the user that this frame is associated with whatever mechanism is used +by this operating system to call a signal handler (it is the frame which +calls the signal handler, not the frame for the signal handler itself). + +@item +A normal frame. + +@findex frame-address +@findex frame-address-end +This can optionally (depending on whether this is thought of as +interesting information for the user to see) begin with + +@smallexample +^Z^Zframe-address +@var{address} +^Z^Zframe-address-end +@var{separator-string} +@end smallexample + +where @var{address} is the address executing in the frame (the same +address as in the @code{frame-begin} annotation, but printed in a form +which is intended for user consumption---in particular, the syntax varies +depending on the language), and @var{separator-string} is a string +intended to separate this address from what follows for the user's +benefit. + +@findex frame-function-name +@findex frame-args +Then comes + +@smallexample +^Z^Zframe-function-name +@var{function-name} +^Z^Zframe-args +@var{arguments} +@end smallexample + +where @var{function-name} is the name of the function executing in the +frame, or @samp{??} if not known, and @var{arguments} are the arguments +to the frame, with parentheses around them (each argument is annotated +individually as well, @pxref{Value Annotations}). + +@findex frame-source-begin +@findex frame-source-file +@findex frame-source-file-end +@findex frame-source-line +@findex frame-source-end +If source information is available, a reference to it is then printed: + +@smallexample +^Z^Zframe-source-begin +@var{source-intro-string} +^Z^Zframe-source-file +@var{filename} +^Z^Zframe-source-file-end +: +^Z^Zframe-source-line +@var{line-number} +^Z^Zframe-source-end +@end smallexample + +where @var{source-intro-string} separates for the user's benefit the +reference from the text which precedes it, @var{filename} is the name of +the source file, and @var{line-number} is the line number within that +file (the first line is line 1). + +@findex frame-where +If @value{GDBN} prints some information about where the frame is from (which +library, which load segment, etc.; currently only done on the RS/6000), +it is annotated with + +@smallexample +^Z^Zframe-where +@var{information} +@end smallexample + +Then, if source is to actually be displayed for this frame (for example, +this is not true for output from the @code{backtrace} command), then a +@code{source} annotation (@pxref{Source Annotations}) is displayed. Unlike +most annotations, this is output instead of the normal text which would be +output, not in addition. +@end itemize + +@node Displays +@chapter Displays + +@emph{Display Annotations have been removed. @sc{gdb/mi} instead +provides Variable Objects.} + +@findex display-begin +@findex display-number-end +@findex display-format +@findex display-expression +@findex display-expression-end +@findex display-value +@findex display-end +@cindex annotations for display +When @value{GDBN} is told to display something using the @code{display} command, +the results of the display are annotated: + +@smallexample +^Z^Zdisplay-begin +@var{number} +^Z^Zdisplay-number-end +@var{number-separator} +^Z^Zdisplay-format +@var{format} +^Z^Zdisplay-expression +@var{expression} +^Z^Zdisplay-expression-end +@var{expression-separator} +^Z^Zdisplay-value +@var{value} +^Z^Zdisplay-end +@end smallexample + +@noindent +where @var{number} is the number of the display, @var{number-separator} +is intended to separate the number from what follows for the user, +@var{format} includes information such as the size, format, or other +information about how the value is being displayed, @var{expression} is +the expression being displayed, @var{expression-separator} is intended +to separate the expression from the text that follows for the user, +and @var{value} is the actual value being displayed. + +@node Prompting +@chapter Annotation for @value{GDBN} Input + +@cindex annotations for prompts +When @value{GDBN} prompts for input, it annotates this fact so it is possible +to know when to send output, when the output from a given command is +over, etc. + +Different kinds of input each have a different @dfn{input type}. Each +input type has three annotations: a @code{pre-} annotation, which +denotes the beginning of any prompt which is being output, a plain +annotation, which denotes the end of the prompt, and then a @code{post-} +annotation which denotes the end of any echo which may (or may not) be +associated with the input. For example, the @code{prompt} input type +features the following annotations: + +@smallexample +^Z^Zpre-prompt +^Z^Zprompt +^Z^Zpost-prompt +@end smallexample + +The input types are + +@table @code +@findex pre-prompt +@findex prompt +@findex post-prompt +@item prompt +When @value{GDBN} is prompting for a command (the main @value{GDBN} prompt). + +@findex pre-commands +@findex commands +@findex post-commands +@item commands +When @value{GDBN} prompts for a set of commands, like in the @code{commands} +command. The annotations are repeated for each command which is input. + +@findex pre-overload-choice +@findex overload-choice +@findex post-overload-choice +@item overload-choice +When @value{GDBN} wants the user to select between various overloaded functions. + +@findex pre-query +@findex query +@findex post-query +@item query +When @value{GDBN} wants the user to confirm a potentially dangerous operation. + +@findex pre-prompt-for-continue +@findex prompt-for-continue +@findex post-prompt-for-continue +@item prompt-for-continue +When @value{GDBN} is asking the user to press return to continue. Note: Don't +expect this to work well; instead use @code{set height 0} to disable +prompting. This is because the counting of lines is buggy in the +presence of annotations. +@end table + +@node Errors +@chapter Errors +@cindex annotations for errors, warnings and interrupts + +@findex quit +@smallexample +^Z^Zquit +@end smallexample + +This annotation occurs right before @value{GDBN} responds to an interrupt. + +@findex error +@smallexample +^Z^Zerror +@end smallexample + +This annotation occurs right before @value{GDBN} responds to an error. + +Quit and error annotations indicate that any annotations which @value{GDBN} was +in the middle of may end abruptly. For example, if a +@code{value-history-begin} annotation is followed by a @code{error}, one +cannot expect to receive the matching @code{value-history-end}. One +cannot expect not to receive it either, however; an error annotation +does not necessarily mean that @value{GDBN} is immediately returning all the way +to the top level. + +@findex error-begin +A quit or error annotation may be preceded by + +@smallexample +^Z^Zerror-begin +@end smallexample + +Any output between that and the quit or error annotation is the error +message. + +Warning messages are not yet annotated. +@c If we want to change that, need to fix warning(), type_error(), +@c range_error(), and possibly other places. + +@node Breakpoint Info +@chapter Information on Breakpoints + +@emph{Breakpoint Annotations have been removed. @sc{gdb/mi} instead +provides breakpoint commands.} + +@cindex annotations for breakpoints +The output from the @code{info breakpoints} command is annotated as follows: + +@findex breakpoints-headers +@findex breakpoints-table +@smallexample +^Z^Zbreakpoints-headers +@var{header-entry} +^Z^Zbreakpoints-table +@end smallexample + +@noindent +where @var{header-entry} has the same syntax as an entry (see below) but +instead of containing data, it contains strings which are intended to +convey the meaning of each field to the user. This is followed by any +number of entries. If a field does not apply for this entry, it is +omitted. Fields may contain trailing whitespace. Each entry consists +of: + +@findex record +@findex field +@smallexample +^Z^Zrecord +^Z^Zfield 0 +@var{number} +^Z^Zfield 1 +@var{type} +^Z^Zfield 2 +@var{disposition} +^Z^Zfield 3 +@var{enable} +^Z^Zfield 4 +@var{address} +^Z^Zfield 5 +@var{what} +^Z^Zfield 6 +@var{frame} +^Z^Zfield 7 +@var{condition} +^Z^Zfield 8 +@var{ignore-count} +^Z^Zfield 9 +@var{commands} +@end smallexample + +Note that @var{address} is intended for user consumption---the syntax +varies depending on the language. + +The output ends with + +@findex breakpoints-table-end +@smallexample +^Z^Zbreakpoints-table-end +@end smallexample + +@node Invalidation +@chapter Invalidation Notices + +@cindex annotations for invalidation messages +The following annotations say that certain pieces of state may have +changed. + +@table @code +@findex frames-invalid +@item ^Z^Zframes-invalid + +The frames (for example, output from the @code{backtrace} command) may +have changed. + +@findex breakpoints-invalid +@item ^Z^Zbreakpoints-invalid + +The breakpoints may have changed. For example, the user just added or +deleted a breakpoint. +@end table + +@node Annotations for Running +@chapter Running the Program +@cindex annotations for running programs + +@findex starting +@findex stopping +When the program starts executing due to a @value{GDBN} command such as +@code{step} or @code{continue}, + +@smallexample +^Z^Zstarting +@end smallexample + +is output. When the program stops, + +@smallexample +^Z^Zstopped +@end smallexample + +is output. Before the @code{stopped} annotation, a variety of +annotations describe how the program stopped. + +@table @code +@findex exited +@item ^Z^Zexited @var{exit-status} +The program exited, and @var{exit-status} is the exit status (zero for +successful exit, otherwise nonzero). + +@findex signalled +@findex signal-name +@findex signal-name-end +@findex signal-string +@findex signal-string-end +@item ^Z^Zsignalled +The program exited with a signal. After the @code{^Z^Zsignalled}, the +annotation continues: + +@smallexample +@var{intro-text} +^Z^Zsignal-name +@var{name} +^Z^Zsignal-name-end +@var{middle-text} +^Z^Zsignal-string +@var{string} +^Z^Zsignal-string-end +@var{end-text} +@end smallexample + +@noindent +where @var{name} is the name of the signal, such as @code{SIGILL} or +@code{SIGSEGV}, and @var{string} is the explanation of the signal, such +as @code{Illegal Instruction} or @code{Segmentation fault}. +@var{intro-text}, @var{middle-text}, and @var{end-text} are for the +user's benefit and have no particular format. + +@findex signal +@item ^Z^Zsignal +The syntax of this annotation is just like @code{signalled}, but @value{GDBN} is +just saying that the program received the signal, not that it was +terminated with it. + +@findex breakpoint +@item ^Z^Zbreakpoint @var{number} +The program hit breakpoint number @var{number}. + +@findex watchpoint +@item ^Z^Zwatchpoint @var{number} +The program hit watchpoint number @var{number}. +@end table + +@node Source Annotations +@chapter Displaying Source +@cindex annotations for source display + +@findex source +The following annotation is used instead of displaying source code: + +@smallexample +^Z^Zsource @var{filename}:@var{line}:@var{character}:@var{middle}:@var{addr} +@end smallexample + +where @var{filename} is an absolute file name indicating which source +file, @var{line} is the line number within that file (where 1 is the +first line in the file), @var{character} is the character position +within the file (where 0 is the first character in the file) (for most +debug formats this will necessarily point to the beginning of a line), +@var{middle} is @samp{middle} if @var{addr} is in the middle of the +line, or @samp{beg} if @var{addr} is at the beginning of the line, and +@var{addr} is the address in the target program associated with the +source which is being displayed. @var{addr} is in the form @samp{0x} +followed by one or more lowercase hex digits (note that this does not +depend on the language). + +@raisesections +@include fdl.texi +@lowersections + +@ignore +@node Index +@unnumbered Index + +@printindex fn +@end ignore + +@bye diff --git a/contrib/gdb/gdb/doc/fdl.texi b/contrib/gdb/gdb/doc/fdl.texi index f4726b9b149..11737cc89bd 100644 --- a/contrib/gdb/gdb/doc/fdl.texi +++ b/contrib/gdb/gdb/doc/fdl.texi @@ -1,28 +1,29 @@ -@c -*-texinfo-*- -@node GNU Free Documentation License -@appendix GNU Free Documentation License -@center Version 1.1, March 2000 +@node GNU Free Documentation License +@appendixsec GNU Free Documentation License + +@cindex FDL, GNU Free Documentation License +@center Version 1.2, November 2002 @display -Copyright (C) 2000 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display -@sp 1 + @enumerate 0 @item PREAMBLE The purpose of this License is to make a manual, textbook, or other -written document ``free'' in the sense of freedom: to assure everyone -the effective freedom to copy and redistribute it, with or without -modifying it, either commercially or noncommercially. Secondarily, -this License preserves for the author and publisher a way to get -credit for their work, while not being considered responsible for -modifications made by others. +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. This License is a kind of ``copyleft'', which means that derivative works of the document must themselves be free in the same sense. It @@ -37,60 +38,72 @@ it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. -@sp 1 @item APPLICABILITY AND DEFINITIONS -This License applies to any manual or other work that contains a -notice placed by the copyright holder saying it can be distributed -under the terms of this License. The ``Document'', below, refers to any -such manual or work. Any member of the public is a licensee, and is -addressed as ``you.'' +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. A ``Modified Version'' of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. -A ``Secondary Section'' is a named appendix or a front-matter section of -the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall subject -(or to related matters) and contains nothing that could fall directly -within that overall subject. (For example, if the Document is in part a -textbook of mathematics, a Secondary Section may not explain any -mathematics.) The relationship could be a matter of historical +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The ``Invariant Sections'' are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. The ``Cover Texts'' are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. A ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the -general public, whose contents can be viewed and edited directly and +general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file -format whose markup has been designed to thwart or discourage -subsequent modification by readers is not Transparent. A copy that is -not ``Transparent'' is called ``Opaque.'' +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, LaTeX input format, SGML -or XML using a publicly available DTD, and standard-conforming simple -HTML designed for human modification. Opaque formats include -PostScript, PDF, proprietary formats that can be read and edited only -by proprietary word processors, SGML or XML for which the DTD and/or -processing tools are not generally available, and the -machine-generated HTML produced by some word processors for output -purposes only. +@sc{ascii} without markup, Texinfo input format, La@TeX{} input +format, @acronym{SGML} or @acronym{XML} using a publicly available +@acronym{DTD}, and standard-conforming simple @acronym{HTML}, +PostScript or @acronym{PDF} designed for human modification. Examples +of transparent image formats include @acronym{PNG}, @acronym{XCF} and +@acronym{JPG}. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, @acronym{SGML} or +@acronym{XML} for which the @acronym{DTD} and/or processing tools are +not generally available, and the machine-generated @acronym{HTML}, +PostScript or @acronym{PDF} produced by some word processors for +output purposes only. The ``Title Page'' means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material @@ -98,7 +111,22 @@ this License requires to appear in the title page. For works in formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. -@sp 1 + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + @item VERBATIM COPYING @@ -114,13 +142,14 @@ number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. -@sp 1 + @item COPYING IN QUANTITY -If you publish printed copies of the Document numbering more than 100, -and the Document's license notice requires Cover Texts, you must enclose -the copies in covers that carry, clearly and legibly, all these Cover +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present @@ -138,21 +167,20 @@ pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy -a publicly-accessible computer-network location containing a complete -Transparent copy of the Document, free of added material, which the -general network-using public has access to download anonymously at no -charge using public-standard network protocols. If you use the latter -option, you must take reasonably prudent steps, when you begin -distribution of Opaque copies in quantity, to ensure that this -Transparent copy will remain thus accessible at the stated location -until at least one year after the last time you distribute an Opaque -copy (directly or through your agents or retailers) of that edition to -the public. +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. -@sp 1 + @item MODIFICATIONS @@ -163,52 +191,85 @@ Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: -A. Use in the Title Page (and on the covers, if any) a title distinct - from that of the Document, and from those of previous versions - (which should, if there were any, be listed in the History section - of the Document). You may use the same title as a previous version - if the original publisher of that version gives permission.@* -B. List on the Title Page, as authors, one or more persons or entities - responsible for authorship of the modifications in the Modified - Version, together with at least five of the principal authors of the - Document (all of its principal authors, if it has less than five).@* -C. State on the Title page the name of the publisher of the - Modified Version, as the publisher.@* -D. Preserve all the copyright notices of the Document.@* -E. Add an appropriate copyright notice for your modifications - adjacent to the other copyright notices.@* -F. Include, immediately after the copyright notices, a license notice - giving the public permission to use the Modified Version under the - terms of this License, in the form shown in the Addendum below.@* -G. Preserve in that license notice the full lists of Invariant Sections - and required Cover Texts given in the Document's license notice.@* -H. Include an unaltered copy of this License.@* -I. Preserve the section entitled ``History'', and its title, and add to - it an item stating at least the title, year, new authors, and - publisher of the Modified Version as given on the Title Page. If - there is no section entitled ``History'' in the Document, create one - stating the title, year, authors, and publisher of the Document as - given on its Title Page, then add an item describing the Modified - Version as stated in the previous sentence.@* -J. Preserve the network location, if any, given in the Document for - public access to a Transparent copy of the Document, and likewise - the network locations given in the Document for previous versions - it was based on. These may be placed in the ``History'' section. - You may omit a network location for a work that was published at - least four years before the Document itself, or if the original - publisher of the version it refers to gives permission.@* -K. In any section entitled ``Acknowledgements'' or ``Dedications'', - preserve the section's title, and preserve in the section all the - substance and tone of each of the contributor acknowledgements - and/or dedications given therein.@* -L. Preserve all the Invariant Sections of the Document, - unaltered in their text and in their titles. Section numbers - or the equivalent are not considered part of the section titles.@* -M. Delete any section entitled ``Endorsements.'' Such a section - may not be included in the Modified Version.@* -N. Do not retitle any existing section as ``Endorsements'' - or to conflict in title with any Invariant Section.@* -@sp 1 +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all @@ -216,9 +277,9 @@ of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. -You may add a section entitled ``Endorsements'', provided it contains +You may add a section Entitled ``Endorsements'', provided it contains nothing but endorsements of your Modified Version by various -parties--for example, statements of peer review or that the text has +parties---for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. @@ -235,7 +296,7 @@ permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. -@sp 1 + @item COMBINING DOCUMENTS @@ -244,7 +305,7 @@ License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its -license notice. +license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single @@ -255,12 +316,12 @@ author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. -In the combination, you must combine any sections entitled ``History'' -in the various original documents, forming one section entitled -``History''; likewise combine any sections entitled ``Acknowledgements'', -and any sections entitled ``Dedications.'' You must delete all sections -entitled ``Endorsements.'' -@sp 1 +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + @item COLLECTIONS OF DOCUMENTS @@ -274,25 +335,27 @@ You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. -@sp 1 + @item AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or -distribution medium, does not as a whole count as a Modified Version -of the Document, provided no compilation copyright is claimed for the -compilation. Such a compilation is called an ``aggregate'', and this -License does not apply to the other self-contained works thus compiled -with the Document, on account of their being thus compiled, if they -are not themselves derivative works of the Document. +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one quarter -of the entire aggregate, the Document's Cover Texts may be placed on -covers that surround only the Document within the aggregate. -Otherwise they must appear on covers around the whole aggregate. -@sp 1 +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + @item TRANSLATION @@ -302,11 +365,18 @@ Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a -translation of this License provided that you also include the -original English version of this License. In case of a disagreement -between the translation and the original English version of this -License, the original English version will prevail. -@sp 1 +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + @item TERMINATION @@ -317,7 +387,7 @@ automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. -@sp 1 + @item FUTURE REVISIONS OF THIS LICENSE @@ -325,7 +395,7 @@ The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See -http://www.gnu.org/copyleft/. +@uref{http://www.gnu.org/copyleft/}. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this @@ -335,10 +405,10 @@ of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. - @end enumerate -@unnumberedsec ADDENDUM: How to use this License for your documents +@page +@appendixsubsec ADDENDUM: How to use this License for your documents To use this License in a document you have written, include a copy of the License in the document and put the following copyright and @@ -346,23 +416,37 @@ license notices just after the title page: @smallexample @group -Copyright (C) @var{year} @var{your name}. -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.1 -or any later version published by the Free Software Foundation; -with the Invariant Sections being @var{list their titles}, with the -Front-Cover Texts being @var{list}, and with the Back-Cover Texts being @var{list}. -A copy of the license is included in the section entitled "GNU -Free Documentation License." + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. @end group @end smallexample -If you have no Invariant Sections, write ``with no Invariant Sections'' -instead of saying which ones are invariant. If you have no -Front-Cover Texts, write ``no Front-Cover Texts'' instead of -``Front-Cover Texts being @var{list}''; likewise for Back-Cover Texts. +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with...Texts.'' line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: + diff --git a/contrib/gdb/gdb/doc/gdb.info-1 b/contrib/gdb/gdb/doc/gdb.info-1 new file mode 100644 index 00000000000..decf4543461 --- /dev/null +++ b/contrib/gdb/gdb/doc/gdb.info-1 @@ -0,0 +1,7636 @@ +This is gdb.info, produced by makeinfo version 4.6 from ./gdb.texinfo. + +INFO-DIR-SECTION Software development +START-INFO-DIR-ENTRY +* Gdb: (gdb). The GNU debugger. +END-INFO-DIR-ENTRY + + This file documents the GNU debugger GDB. + + This is the Ninth Edition, of `Debugging with GDB: the GNU +Source-Level Debugger' for GDB Version 6.1.1. + + Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, +1998, +1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with the +Invariant Sections being "Free Software" and "Free Software Needs Free +Documentation", with the Front-Cover Texts being "A GNU Manual," and +with the Back-Cover Texts as in (a) below. + + (a) The Free Software Foundation's Back-Cover Text is: "You have +freedom to copy and modify this GNU Manual, like GNU software. Copies +published by the Free Software Foundation raise funds for GNU +development." + + +File: gdb.info, Node: Top, Next: Summary, Prev: (dir), Up: (dir) + +Debugging with GDB +****************** + +This file describes GDB, the GNU symbolic debugger. + + This is the Ninth Edition, for GDB Version 6.1.1. + + Copyright (C) 1988-2004 Free Software Foundation, Inc. + +* Menu: + +* Summary:: Summary of GDB +* Sample Session:: A sample GDB session + +* Invocation:: Getting in and out of GDB +* Commands:: GDB commands +* Running:: Running programs under GDB +* Stopping:: Stopping and continuing +* Stack:: Examining the stack +* Source:: Examining source files +* Data:: Examining data +* Macros:: Preprocessor Macros +* Tracepoints:: Debugging remote targets non-intrusively +* Overlays:: Debugging programs that use overlays + +* Languages:: Using GDB with different languages + +* Symbols:: Examining the symbol table +* Altering:: Altering execution +* GDB Files:: GDB files +* Targets:: Specifying a debugging target +* Remote Debugging:: Debugging remote programs +* Configurations:: Configuration-specific information +* Controlling GDB:: Controlling GDB +* Sequences:: Canned sequences of commands +* TUI:: GDB Text User Interface +* Interpreters:: Command Interpreters +* Emacs:: Using GDB under GNU Emacs +* Annotations:: GDB's annotation interface. +* GDB/MI:: GDB's Machine Interface. + +* GDB Bugs:: Reporting bugs in GDB +* Formatting Documentation:: How to format and print GDB documentation + +* Command Line Editing:: Command Line Editing +* Using History Interactively:: Using History Interactively +* Installing GDB:: Installing GDB +* Maintenance Commands:: Maintenance Commands +* Remote Protocol:: GDB Remote Serial Protocol +* Agent Expressions:: The GDB Agent Expression Mechanism +* Copying:: GNU General Public License says + how you can copy and share GDB +* GNU Free Documentation License:: The license for this documentation +* Index:: Index + + +File: gdb.info, Node: Summary, Next: Sample Session, Prev: Top, Up: Top + +Summary of GDB +************** + +The purpose of a debugger such as GDB is to allow you to see what is +going on "inside" another program while it executes--or what another +program was doing at the moment it crashed. + + GDB can do four main kinds of things (plus other things in support of +these) to help you catch bugs in the act: + + * Start your program, specifying anything that might affect its + behavior. + + * Make your program stop on specified conditions. + + * Examine what has happened, when your program has stopped. + + * Change things in your program, so you can experiment with + correcting the effects of one bug and go on to learn about another. + + You can use GDB to debug programs written in C and C++. For more +information, see *Note Supported languages: Support. For more +information, see *Note C and C++: C. + + Support for Modula-2 is partial. For information on Modula-2, see +*Note Modula-2: Modula-2. + + Debugging Pascal programs which use sets, subranges, file variables, +or nested functions does not currently work. GDB does not support +entering expressions, printing values, or similar features using Pascal +syntax. + + GDB can be used to debug programs written in Fortran, although it +may be necessary to refer to some variables with a trailing underscore. + + GDB can be used to debug programs written in Objective-C, using +either the Apple/NeXT or the GNU Objective-C runtime. + +* Menu: + +* Free Software:: Freely redistributable software +* Contributors:: Contributors to GDB + + +File: gdb.info, Node: Free Software, Next: Contributors, Up: Summary + +Free software +============= + +GDB is "free software", protected by the GNU General Public License +(GPL). The GPL gives you the freedom to copy or adapt a licensed +program--but every person getting a copy also gets with it the freedom +to modify that copy (which means that they must get access to the +source code), and the freedom to distribute further copies. Typical +software companies use copyrights to limit your freedoms; the Free +Software Foundation uses the GPL to preserve these freedoms. + + Fundamentally, the General Public License is a license which says +that you have these freedoms and that you cannot take these freedoms +away from anyone else. + +Free Software Needs Free Documentation +====================================== + +The biggest deficiency in the free software community today is not in +the software--it is the lack of good free documentation that we can +include with the free software. Many of our most important programs do +not come with free reference manuals and free introductory texts. +Documentation is an essential part of any software package; when an +important free software package does not come with a free manual and a +free tutorial, that is a major gap. We have many such gaps today. + + Consider Perl, for instance. The tutorial manuals that people +normally use are non-free. How did this come about? Because the +authors of those manuals published them with restrictive terms--no +copying, no modification, source files not available--which exclude +them from the free software world. + + That wasn't the first time this sort of thing happened, and it was +far from the last. Many times we have heard a GNU user eagerly +describe a manual that he is writing, his intended contribution to the +community, only to learn that he had ruined everything by signing a +publication contract to make it non-free. + + Free documentation, like free software, is a matter of freedom, not +price. The problem with the non-free manual is not that publishers +charge a price for printed copies--that in itself is fine. (The Free +Software Foundation sells printed copies of manuals, too.) The problem +is the restrictions on the use of the manual. Free manuals are +available in source code form, and give you permission to copy and +modify. Non-free manuals do not allow this. + + The criteria of freedom for a free manual are roughly the same as for +free software. Redistribution (including the normal kinds of +commercial redistribution) must be permitted, so that the manual can +accompany every copy of the program, both on-line and on paper. + + Permission for modification of the technical content is crucial too. +When people modify the software, adding or changing features, if they +are conscientious they will change the manual too--so they can provide +accurate and clear documentation for the modified program. A manual +that leaves you no choice but to write a new manual to document a +changed version of the program is not really available to our community. + + Some kinds of limits on the way modification is handled are +acceptable. For example, requirements to preserve the original +author's copyright notice, the distribution terms, or the list of +authors, are ok. It is also no problem to require modified versions to +include notice that they were modified. Even entire sections that may +not be deleted or changed are acceptable, as long as they deal with +nontechnical topics (like this one). These kinds of restrictions are +acceptable because they don't obstruct the community's normal use of +the manual. + + However, it must be possible to modify all the _technical_ content +of the manual, and then distribute the result in all the usual media, +through all the usual channels. Otherwise, the restrictions obstruct +the use of the manual, it is not free, and we need another manual to +replace it. + + Please spread the word about this issue. Our community continues to +lose manuals to proprietary publishing. If we spread the word that +free software needs free reference manuals and free tutorials, perhaps +the next person who wants to contribute by writing documentation will +realize, before it is too late, that only free manuals contribute to +the free software community. + + If you are writing documentation, please insist on publishing it +under the GNU Free Documentation License or another free documentation +license. Remember that this decision requires your approval--you don't +have to let the publisher decide. Some commercial publishers will use +a free license if you insist, but they will not propose the option; it +is up to you to raise the issue and say firmly that this is what you +want. If the publisher you are dealing with refuses, please try other +publishers. If you're not sure whether a proposed license is free, +write to . + + You can encourage commercial publishers to sell more free, copylefted +manuals and tutorials by buying them, and particularly by buying copies +from the publishers that paid for their writing or for major +improvements. Meanwhile, try to avoid buying non-free documentation at +all. Check the distribution terms of a manual before you buy it, and +insist that whoever seeks your business must respect your freedom. +Check the history of the book, and try to reward the publishers that +have paid or pay the authors to work on it. + + The Free Software Foundation maintains a list of free documentation +published by other publishers, at +. + + +File: gdb.info, Node: Contributors, Prev: Free Software, Up: Summary + +Contributors to GDB +=================== + +Richard Stallman was the original author of GDB, and of many other GNU +programs. Many others have contributed to its development. This +section attempts to credit major contributors. One of the virtues of +free software is that everyone is free to contribute to it; with +regret, we cannot actually acknowledge everyone here. The file +`ChangeLog' in the GDB distribution approximates a blow-by-blow account. + + Changes much prior to version 2.0 are lost in the mists of time. + + _Plea:_ Additions to this section are particularly welcome. If you + or your friends (or enemies, to be evenhanded) have been unfairly + omitted from this list, we would like to add your names! + + So that they may not regard their many labors as thankless, we +particularly thank those who shepherded GDB through major releases: +Andrew Cagney (releases 6.1, 6.0, 5.3, 5.2, 5.1 and 5.0); Jim Blandy +(release 4.18); Jason Molenda (release 4.17); Stan Shebs (release 4.14); +Fred Fish (releases 4.16, 4.15, 4.13, 4.12, 4.11, 4.10, and 4.9); Stu +Grossman and John Gilmore (releases 4.8, 4.7, 4.6, 4.5, and 4.4); John +Gilmore (releases 4.3, 4.2, 4.1, 4.0, and 3.9); Jim Kingdon (releases +3.5, 3.4, and 3.3); and Randy Smith (releases 3.2, 3.1, and 3.0). + + Richard Stallman, assisted at various times by Peter TerMaat, Chris +Hanson, and Richard Mlynarik, handled releases through 2.8. + + Michael Tiemann is the author of most of the GNU C++ support in GDB, +with significant additional contributions from Per Bothner and Daniel +Berlin. James Clark wrote the GNU C++ demangler. Early work on C++ +was by Peter TerMaat (who also did much general update work leading to +release 3.0). + + GDB uses the BFD subroutine library to examine multiple object-file +formats; BFD was a joint project of David V. Henkel-Wallace, Rich +Pixley, Steve Chamberlain, and John Gilmore. + + David Johnson wrote the original COFF support; Pace Willison did the +original support for encapsulated COFF. + + Brent Benson of Harris Computer Systems contributed DWARF 2 support. + + Adam de Boor and Bradley Davis contributed the ISI Optimum V support. +Per Bothner, Noboyuki Hikichi, and Alessandro Forin contributed MIPS +support. Jean-Daniel Fekete contributed Sun 386i support. Chris +Hanson improved the HP9000 support. Noboyuki Hikichi and Tomoyuki +Hasei contributed Sony/News OS 3 support. David Johnson contributed +Encore Umax support. Jyrki Kuoppala contributed Altos 3068 support. +Jeff Law contributed HP PA and SOM support. Keith Packard contributed +NS32K support. Doug Rabson contributed Acorn Risc Machine support. +Bob Rusk contributed Harris Nighthawk CX-UX support. Chris Smith +contributed Convex support (and Fortran debugging). Jonathan Stone +contributed Pyramid support. Michael Tiemann contributed SPARC support. +Tim Tucker contributed support for the Gould NP1 and Gould Powernode. +Pace Willison contributed Intel 386 support. Jay Vosburgh contributed +Symmetry support. Marko Mlinar contributed OpenRISC 1000 support. + + Andreas Schwab contributed M68K GNU/Linux support. + + Rich Schaefer and Peter Schauer helped with support of SunOS shared +libraries. + + Jay Fenlason and Roland McGrath ensured that GDB and GAS agree about +several machine instruction sets. + + Patrick Duval, Ted Goldstein, Vikram Koka and Glenn Engel helped +develop remote debugging. Intel Corporation, Wind River Systems, AMD, +and ARM contributed remote debugging modules for the i960, VxWorks, +A29K UDI, and RDI targets, respectively. + + Brian Fox is the author of the readline libraries providing +command-line editing and command history. + + Andrew Beers of SUNY Buffalo wrote the language-switching code, the +Modula-2 support, and contributed the Languages chapter of this manual. + + Fred Fish wrote most of the support for Unix System Vr4. He also +enhanced the command-completion support to cover C++ overloaded symbols. + + Hitachi America (now Renesas America), Ltd. sponsored the support for +H8/300, H8/500, and Super-H processors. + + NEC sponsored the support for the v850, Vr4xxx, and Vr5xxx +processors. + + Mitsubishi (now Renesas) sponsored the support for D10V, D30V, and +M32R/D processors. + + Toshiba sponsored the support for the TX39 Mips processor. + + Matsushita sponsored the support for the MN10200 and MN10300 +processors. + + Fujitsu sponsored the support for SPARClite and FR30 processors. + + Kung Hsu, Jeff Law, and Rick Sladkey added support for hardware +watchpoints. + + Michael Snyder added support for tracepoints. + + Stu Grossman wrote gdbserver. + + Jim Kingdon, Peter Schauer, Ian Taylor, and Stu Grossman made nearly +innumerable bug fixes and cleanups throughout GDB. + + The following people at the Hewlett-Packard Company contributed +support for the PA-RISC 2.0 architecture, HP-UX 10.20, 10.30, and 11.0 +(narrow mode), HP's implementation of kernel threads, HP's aC++ +compiler, and the Text User Interface (nee Terminal User Interface): +Ben Krepp, Richard Title, John Bishop, Susan Macchia, Kathy Mann, +Satish Pai, India Paul, Steve Rehrauer, and Elena Zannoni. Kim Haase +provided HP-specific information in this manual. + + DJ Delorie ported GDB to MS-DOS, for the DJGPP project. Robert +Hoehne made significant contributions to the DJGPP port. + + Cygnus Solutions has sponsored GDB maintenance and much of its +development since 1991. Cygnus engineers who have worked on GDB +fulltime include Mark Alexander, Jim Blandy, Per Bothner, Kevin +Buettner, Edith Epstein, Chris Faylor, Fred Fish, Martin Hunt, Jim +Ingham, John Gilmore, Stu Grossman, Kung Hsu, Jim Kingdon, John Metzler, +Fernando Nasser, Geoffrey Noer, Dawn Perchik, Rich Pixley, Zdenek +Radouch, Keith Seitz, Stan Shebs, David Taylor, and Elena Zannoni. In +addition, Dave Brolley, Ian Carmichael, Steve Chamberlain, Nick Clifton, +JT Conklin, Stan Cox, DJ Delorie, Ulrich Drepper, Frank Eigler, Doug +Evans, Sean Fagan, David Henkel-Wallace, Richard Henderson, Jeff +Holcomb, Jeff Law, Jim Lemke, Tom Lord, Bob Manson, Michael Meissner, +Jason Merrill, Catherine Moore, Drew Moseley, Ken Raeburn, Gavin +Romig-Koch, Rob Savoye, Jamie Smith, Mike Stump, Ian Taylor, Angela +Thomas, Michael Tiemann, Tom Tromey, Ron Unrau, Jim Wilson, and David +Zuhn have made contributions both large and small. + + Jim Blandy added support for preprocessor macros, while working for +Red Hat. + + +File: gdb.info, Node: Sample Session, Next: Invocation, Prev: Summary, Up: Top + +A Sample GDB Session +******************** + +You can use this manual at your leisure to read all about GDB. +However, a handful of commands are enough to get started using the +debugger. This chapter illustrates those commands. + + One of the preliminary versions of GNU `m4' (a generic macro +processor) exhibits the following bug: sometimes, when we change its +quote strings from the default, the commands used to capture one macro +definition within another stop working. In the following short `m4' +session, we define a macro `foo' which expands to `0000'; we then use +the `m4' built-in `defn' to define `bar' as the same thing. However, +when we change the open quote string to `' and the close quote +string to `', the same procedure fails to define a new synonym +`baz': + + $ cd gnu/m4 + $ ./m4 + define(foo,0000) + + foo + 0000 + define(bar,defn(`foo')) + + bar + 0000 + changequote(,) + + define(baz,defn(foo)) + baz + C-d + m4: End of input: 0: fatal error: EOF in string + +Let us use GDB to try to see what is going on. + + $ gdb m4 + GDB is free software and you are welcome to distribute copies + of it under certain conditions; type "show copying" to see + the conditions. + There is absolutely no warranty for GDB; type "show warranty" + for details. + + GDB 6.1.1, Copyright 1999 Free Software Foundation, Inc... + (gdb) + +GDB reads only enough symbol data to know where to find the rest when +needed; as a result, the first prompt comes up very quickly. We now +tell GDB to use a narrower display width than usual, so that examples +fit in this manual. + + (gdb) set width 70 + +We need to see how the `m4' built-in `changequote' works. Having +looked at the source, we know the relevant subroutine is +`m4_changequote', so we set a breakpoint there with the GDB `break' +command. + + (gdb) break m4_changequote + Breakpoint 1 at 0x62f4: file builtin.c, line 879. + +Using the `run' command, we start `m4' running under GDB control; as +long as control does not reach the `m4_changequote' subroutine, the +program runs as usual: + + (gdb) run + Starting program: /work/Editorial/gdb/gnu/m4/m4 + define(foo,0000) + + foo + 0000 + +To trigger the breakpoint, we call `changequote'. GDB suspends +execution of `m4', displaying information about the context where it +stops. + + changequote(,) + + Breakpoint 1, m4_changequote (argc=3, argv=0x33c70) + at builtin.c:879 + 879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3)) + +Now we use the command `n' (`next') to advance execution to the next +line of the current function. + + (gdb) n + 882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\ + : nil, + +`set_quotes' looks like a promising subroutine. We can go into it by +using the command `s' (`step') instead of `next'. `step' goes to the +next line to be executed in _any_ subroutine, so it steps into +`set_quotes'. + + (gdb) s + set_quotes (lq=0x34c78 "", rq=0x34c88 "") + at input.c:530 + 530 if (lquote != def_lquote) + +The display that shows the subroutine where `m4' is now suspended (and +its arguments) is called a stack frame display. It shows a summary of +the stack. We can use the `backtrace' command (which can also be +spelled `bt'), to see where we are in the stack as a whole: the +`backtrace' command displays a stack frame for each active subroutine. + + (gdb) bt + #0 set_quotes (lq=0x34c78 "", rq=0x34c88 "") + at input.c:530 + #1 0x6344 in m4_changequote (argc=3, argv=0x33c70) + at builtin.c:882 + #2 0x8174 in expand_macro (sym=0x33320) at macro.c:242 + #3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30) + at macro.c:71 + #4 0x79dc in expand_input () at macro.c:40 + #5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195 + +We step through a few more lines to see what happens. The first two +times, we can use `s'; the next two times we use `n' to avoid falling +into the `xstrdup' subroutine. + + (gdb) s + 0x3b5c 532 if (rquote != def_rquote) + (gdb) s + 0x3b80 535 lquote = (lq == nil || *lq == '\0') ? \ + def_lquote : xstrdup(lq); + (gdb) n + 536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ + : xstrdup(rq); + (gdb) n + 538 len_lquote = strlen(rquote); + +The last line displayed looks a little odd; we can examine the variables +`lquote' and `rquote' to see if they are in fact the new left and right +quotes we specified. We use the command `p' (`print') to see their +values. + + (gdb) p lquote + $1 = 0x35d40 "" + (gdb) p rquote + $2 = 0x35d50 "" + +`lquote' and `rquote' are indeed the new left and right quotes. To +look at some context, we can display ten lines of source surrounding +the current line with the `l' (`list') command. + + (gdb) l + 533 xfree(rquote); + 534 + 535 lquote = (lq == nil || *lq == '\0') ? def_lquote\ + : xstrdup (lq); + 536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ + : xstrdup (rq); + 537 + 538 len_lquote = strlen(rquote); + 539 len_rquote = strlen(lquote); + 540 } + 541 + 542 void + +Let us step past the two lines that set `len_lquote' and `len_rquote', +and then examine the values of those variables. + + (gdb) n + 539 len_rquote = strlen(lquote); + (gdb) n + 540 } + (gdb) p len_lquote + $3 = 9 + (gdb) p len_rquote + $4 = 7 + +That certainly looks wrong, assuming `len_lquote' and `len_rquote' are +meant to be the lengths of `lquote' and `rquote' respectively. We can +set them to better values using the `p' command, since it can print the +value of any expression--and that expression can include subroutine +calls and assignments. + + (gdb) p len_lquote=strlen(lquote) + $5 = 7 + (gdb) p len_rquote=strlen(rquote) + $6 = 9 + +Is that enough to fix the problem of using the new quotes with the `m4' +built-in `defn'? We can allow `m4' to continue executing with the `c' +(`continue') command, and then try the example that caused trouble +initially: + + (gdb) c + Continuing. + + define(baz,defn(foo)) + + baz + 0000 + +Success! The new quotes now work just as well as the default ones. The +problem seems to have been just the two typos defining the wrong +lengths. We allow `m4' exit by giving it an EOF as input: + + C-d + Program exited normally. + +The message `Program exited normally.' is from GDB; it indicates `m4' +has finished executing. We can end our GDB session with the GDB `quit' +command. + + (gdb) quit + + +File: gdb.info, Node: Invocation, Next: Commands, Prev: Sample Session, Up: Top + +Getting In and Out of GDB +************************* + +This chapter discusses how to start GDB, and how to get out of it. The +essentials are: + * type `gdb' to start GDB. + + * type `quit' or `C-d' to exit. + +* Menu: + +* Invoking GDB:: How to start GDB +* Quitting GDB:: How to quit GDB +* Shell Commands:: How to use shell commands inside GDB +* Logging output:: How to log GDB's output to a file + + +File: gdb.info, Node: Invoking GDB, Next: Quitting GDB, Up: Invocation + +Invoking GDB +============ + +Invoke GDB by running the program `gdb'. Once started, GDB reads +commands from the terminal until you tell it to exit. + + You can also run `gdb' with a variety of arguments and options, to +specify more of your debugging environment at the outset. + + The command-line options described here are designed to cover a +variety of situations; in some environments, some of these options may +effectively be unavailable. + + The most usual way to start GDB is with one argument, specifying an +executable program: + + gdb PROGRAM + +You can also start with both an executable program and a core file +specified: + + gdb PROGRAM CORE + + You can, instead, specify a process ID as a second argument, if you +want to debug a running process: + + gdb PROGRAM 1234 + +would attach GDB to process `1234' (unless you also have a file named +`1234'; GDB does check for a core file first). + + Taking advantage of the second command-line argument requires a +fairly complete operating system; when you use GDB as a remote debugger +attached to a bare board, there may not be any notion of "process", and +there is often no way to get a core dump. GDB will warn you if it is +unable to attach or to read core dumps. + + You can optionally have `gdb' pass any arguments after the +executable file to the inferior using `--args'. This option stops +option processing. + gdb --args gcc -O2 -c foo.c + This will cause `gdb' to debug `gcc', and to set `gcc''s +command-line arguments (*note Arguments::) to `-O2 -c foo.c'. + + You can run `gdb' without printing the front material, which +describes GDB's non-warranty, by specifying `-silent': + + gdb -silent + +You can further control how GDB starts up by using command-line +options. GDB itself can remind you of the options available. + +Type + + gdb -help + +to display all available options and briefly describe their use (`gdb +-h' is a shorter equivalent). + + All options and command line arguments you give are processed in +sequential order. The order makes a difference when the `-x' option is +used. + +* Menu: + +* File Options:: Choosing files +* Mode Options:: Choosing modes + + +File: gdb.info, Node: File Options, Next: Mode Options, Up: Invoking GDB + +Choosing files +-------------- + +When GDB starts, it reads any arguments other than options as +specifying an executable file and core file (or process ID). This is +the same as if the arguments were specified by the `-se' and `-c' (or +`-p' options respectively. (GDB reads the first argument that does not +have an associated option flag as equivalent to the `-se' option +followed by that argument; and the second argument that does not have +an associated option flag, if any, as equivalent to the `-c'/`-p' +option followed by that argument.) If the second argument begins with +a decimal digit, GDB will first attempt to attach to it as a process, +and if that fails, attempt to open it as a corefile. If you have a +corefile whose name begins with a digit, you can prevent GDB from +treating it as a pid by prefixing it with `./', eg. `./12345'. + + If GDB has not been configured to included core file support, such +as for most embedded targets, then it will complain about a second +argument and ignore it. + + Many options have both long and short forms; both are shown in the +following list. GDB also recognizes the long forms if you truncate +them, so long as enough of the option is present to be unambiguous. +(If you prefer, you can flag option arguments with `--' rather than +`-', though we illustrate the more usual convention.) + +`-symbols FILE' +`-s FILE' + Read symbol table from file FILE. + +`-exec FILE' +`-e FILE' + Use file FILE as the executable file to execute when appropriate, + and for examining pure data in conjunction with a core dump. + +`-se FILE' + Read symbol table from file FILE and use it as the executable file. + +`-core FILE' +`-c FILE' + Use file FILE as a core dump to examine. + +`-c NUMBER' + +`-pid NUMBER' +`-p NUMBER' + Connect to process ID NUMBER, as with the `attach' command. If + there is no such process, GDB will attempt to open a core file + named NUMBER. + +`-command FILE' +`-x FILE' + Execute GDB commands from file FILE. *Note Command files: Command + Files. + +`-directory DIRECTORY' +`-d DIRECTORY' + Add DIRECTORY to the path to search for source files. + +`-m' +`-mapped' + _Warning: this option depends on operating system facilities that + are not supported on all systems._ + If memory-mapped files are available on your system through the + `mmap' system call, you can use this option to have GDB write the + symbols from your program into a reusable file in the current + directory. If the program you are debugging is called + `/tmp/fred', the mapped symbol file is `/tmp/fred.syms'. Future + GDB debugging sessions notice the presence of this file, and can + quickly map in symbol information from it, rather than reading the + symbol table from the executable program. + + The `.syms' file is specific to the host machine where GDB is run. + It holds an exact image of the internal GDB symbol table. It + cannot be shared across multiple host platforms. + +`-r' +`-readnow' + Read each symbol file's entire symbol table immediately, rather + than the default, which is to read it incrementally as it is + needed. This makes startup slower, but makes future operations + faster. + + + You typically combine the `-mapped' and `-readnow' options in order +to build a `.syms' file that contains complete symbol information. +(*Note Commands to specify files: Files, for information on `.syms' +files.) A simple GDB invocation to do nothing but build a `.syms' file +for future use is: + + gdb -batch -nx -mapped -readnow programname + + +File: gdb.info, Node: Mode Options, Prev: File Options, Up: Invoking GDB + +Choosing modes +-------------- + +You can run GDB in various alternative modes--for example, in batch +mode or quiet mode. + +`-nx' +`-n' + Do not execute commands found in any initialization files. + Normally, GDB executes the commands in these files after all the + command options and arguments have been processed. *Note Command + files: Command Files. + +`-quiet' +`-silent' +`-q' + "Quiet". Do not print the introductory and copyright messages. + These messages are also suppressed in batch mode. + +`-batch' + Run in batch mode. Exit with status `0' after processing all the + command files specified with `-x' (and all commands from + initialization files, if not inhibited with `-n'). Exit with + nonzero status if an error occurs in executing the GDB commands in + the command files. + + Batch mode may be useful for running GDB as a filter, for example + to download and run a program on another computer; in order to + make this more useful, the message + + Program exited normally. + + (which is ordinarily issued whenever a program running under GDB + control terminates) is not issued when running in batch mode. + +`-nowindows' +`-nw' + "No windows". If GDB comes with a graphical user interface (GUI) + built in, then this option tells GDB to only use the command-line + interface. If no GUI is available, this option has no effect. + +`-windows' +`-w' + If GDB includes a GUI, then this option requires it to be used if + possible. + +`-cd DIRECTORY' + Run GDB using DIRECTORY as its working directory, instead of the + current directory. + +`-fullname' +`-f' + GNU Emacs sets this option when it runs GDB as a subprocess. It + tells GDB to output the full file name and line number in a + standard, recognizable fashion each time a stack frame is + displayed (which includes each time your program stops). This + recognizable format looks like two `\032' characters, followed by + the file name, line number and character position separated by + colons, and a newline. The Emacs-to-GDB interface program uses + the two `\032' characters as a signal to display the source code + for the frame. + +`-epoch' + The Epoch Emacs-GDB interface sets this option when it runs GDB as + a subprocess. It tells GDB to modify its print routines so as to + allow Epoch to display values of expressions in a separate window. + +`-annotate LEVEL' + This option sets the "annotation level" inside GDB. Its effect is + identical to using `set annotate LEVEL' (*note Annotations::). + The annotation LEVEL controls how much information GDB prints + together with its prompt, values of expressions, source lines, and + other types of output. Level 0 is the normal, level 1 is for use + when GDB is run as a subprocess of GNU Emacs, level 3 is the + maximum annotation suitable for programs that control GDB, and + level 2 has been deprecated. + + The annotation mechanism has largely been superseeded by GDB/MI + (*note GDB/MI::). + +`-async' + Use the asynchronous event loop for the command-line interface. + GDB processes all events, such as user keyboard input, via a + special event loop. This allows GDB to accept and process user + commands in parallel with the debugged process being run(1), so + you don't need to wait for control to return to GDB before you + type the next command. (_Note:_ as of version 5.1, the target + side of the asynchronous operation is not yet in place, so + `-async' does not work fully yet.) + + When the standard input is connected to a terminal device, GDB + uses the asynchronous event loop by default, unless disabled by the + `-noasync' option. + +`-noasync' + Disable the asynchronous event loop for the command-line interface. + +`--args' + Change interpretation of command line so that arguments following + the executable file are passed as command line arguments to the + inferior. This option stops option processing. + +`-baud BPS' +`-b BPS' + Set the line speed (baud rate or bits per second) of any serial + interface used by GDB for remote debugging. + +`-tty DEVICE' +`-t DEVICE' + Run using DEVICE for your program's standard input and output. + +`-tui' + Activate the "Text User Interface" when starting. The Text User + Interface manages several text windows on the terminal, showing + source, assembly, registers and GDB command outputs (*note GDB + Text User Interface: TUI.). Alternatively, the Text User + Interface can be enabled by invoking the program `gdbtui'. Do not + use this option if you run GDB from Emacs (*note Using GDB under + GNU Emacs: Emacs.). + +`-interpreter INTERP' + Use the interpreter INTERP for interface with the controlling + program or device. This option is meant to be set by programs + which communicate with GDB using it as a back end. *Note Command + Interpreters: Interpreters. + + `--interpreter=mi' (or `--interpreter=mi2') causes GDB to use the + "GDB/MI interface" (*note The GDB/MI Interface: GDB/MI.) included + since GDBN version 6.0. The previous GDB/MI interface, included + in GDB version 5.3 and selected with `--interpreter=mi1', is + deprecated. Earlier GDB/MI interfaces are no longer supported. + +`-write' + Open the executable and core files for both reading and writing. + This is equivalent to the `set write on' command inside GDB (*note + Patching::). + +`-statistics' + This option causes GDB to print statistics about time and memory + usage after it completes each command and returns to the prompt. + +`-version' + This option causes GDB to print its version number and no-warranty + blurb, and exit. + + + ---------- Footnotes ---------- + + (1) GDB built with DJGPP tools for MS-DOS/MS-Windows supports this +mode of operation, but the event loop is suspended when the debuggee +runs. + + +File: gdb.info, Node: Quitting GDB, Next: Shell Commands, Prev: Invoking GDB, Up: Invocation + +Quitting GDB +============ + +`quit [EXPRESSION]' +`q' + To exit GDB, use the `quit' command (abbreviated `q'), or type an + end-of-file character (usually `C-d'). If you do not supply + EXPRESSION, GDB will terminate normally; otherwise it will + terminate using the result of EXPRESSION as the error code. + + An interrupt (often `C-c') does not exit from GDB, but rather +terminates the action of any GDB command that is in progress and +returns to GDB command level. It is safe to type the interrupt +character at any time because GDB does not allow it to take effect +until a time when it is safe. + + If you have been using GDB to control an attached process or device, +you can release it with the `detach' command (*note Debugging an +already-running process: Attach.). + + +File: gdb.info, Node: Shell Commands, Next: Logging output, Prev: Quitting GDB, Up: Invocation + +Shell commands +============== + +If you need to execute occasional shell commands during your debugging +session, there is no need to leave or suspend GDB; you can just use the +`shell' command. + +`shell COMMAND STRING' + Invoke a standard shell to execute COMMAND STRING. If it exists, + the environment variable `SHELL' determines which shell to run. + Otherwise GDB uses the default shell (`/bin/sh' on Unix systems, + `COMMAND.COM' on MS-DOS, etc.). + + The utility `make' is often needed in development environments. You +do not have to use the `shell' command for this purpose in GDB: + +`make MAKE-ARGS' + Execute the `make' program with the specified arguments. This is + equivalent to `shell make MAKE-ARGS'. + + +File: gdb.info, Node: Logging output, Prev: Shell Commands, Up: Invocation + +Logging output +============== + +You may want to save the output of GDB commands to a file. There are +several commands to control GDB's logging. + +`set logging on' + Enable logging. + +`set logging off' + Disable logging. + +`set logging file FILE' + Change the name of the current logfile. The default logfile is + `gdb.txt'. + +`set logging overwrite [on|off]' + By default, GDB will append to the logfile. Set `overwrite' if + you want `set logging on' to overwrite the logfile instead. + +`set logging redirect [on|off]' + By default, GDB output will go to both the terminal and the + logfile. Set `redirect' if you want output to go only to the log + file. + +`show logging' + Show the current values of the logging settings. + + +File: gdb.info, Node: Commands, Next: Running, Prev: Invocation, Up: Top + +GDB Commands +************ + +You can abbreviate a GDB command to the first few letters of the command +name, if that abbreviation is unambiguous; and you can repeat certain +GDB commands by typing just . You can also use the key to +get GDB to fill out the rest of a word in a command (or to show you the +alternatives available, if there is more than one possibility). + +* Menu: + +* Command Syntax:: How to give commands to GDB +* Completion:: Command completion +* Help:: How to ask GDB for help + + +File: gdb.info, Node: Command Syntax, Next: Completion, Up: Commands + +Command syntax +============== + +A GDB command is a single line of input. There is no limit on how long +it can be. It starts with a command name, which is followed by +arguments whose meaning depends on the command name. For example, the +command `step' accepts an argument which is the number of times to +step, as in `step 5'. You can also use the `step' command with no +arguments. Some commands do not allow any arguments. + + GDB command names may always be truncated if that abbreviation is +unambiguous. Other possible command abbreviations are listed in the +documentation for individual commands. In some cases, even ambiguous +abbreviations are allowed; for example, `s' is specially defined as +equivalent to `step' even though there are other commands whose names +start with `s'. You can test abbreviations by using them as arguments +to the `help' command. + + A blank line as input to GDB (typing just ) means to repeat the +previous command. Certain commands (for example, `run') will not +repeat this way; these are commands whose unintentional repetition +might cause trouble and which you are unlikely to want to repeat. + + The `list' and `x' commands, when you repeat them with , +construct new arguments rather than repeating exactly as typed. This +permits easy scanning of source or memory. + + GDB can also use in another way: to partition lengthy output, +in a way similar to the common utility `more' (*note Screen size: +Screen Size.). Since it is easy to press one too many in this +situation, GDB disables command repetition after any command that +generates this sort of display. + + Any text from a `#' to the end of the line is a comment; it does +nothing. This is useful mainly in command files (*note Command files: +Command Files.). + + The `C-o' binding is useful for repeating a complex sequence of +commands. This command accepts the current line, like `RET', and then +fetches the next line relative to the current line from the history for +editing. + + +File: gdb.info, Node: Completion, Next: Help, Prev: Command Syntax, Up: Commands + +Command completion +================== + +GDB can fill in the rest of a word in a command for you, if there is +only one possibility; it can also show you what the valid possibilities +are for the next word in a command, at any time. This works for GDB +commands, GDB subcommands, and the names of symbols in your program. + + Press the key whenever you want GDB to fill out the rest of a +word. If there is only one possibility, GDB fills in the word, and +waits for you to finish the command (or press to enter it). For +example, if you type + + (gdb) info bre + +GDB fills in the rest of the word `breakpoints', since that is the only +`info' subcommand beginning with `bre': + + (gdb) info breakpoints + +You can either press at this point, to run the `info breakpoints' +command, or backspace and enter something else, if `breakpoints' does +not look like the command you expected. (If you were sure you wanted +`info breakpoints' in the first place, you might as well just type + immediately after `info bre', to exploit command abbreviations +rather than command completion). + + If there is more than one possibility for the next word when you +press , GDB sounds a bell. You can either supply more characters +and try again, or just press a second time; GDB displays all the +possible completions for that word. For example, you might want to set +a breakpoint on a subroutine whose name begins with `make_', but when +you type `b make_' GDB just sounds the bell. Typing again +displays all the function names in your program that begin with those +characters, for example: + + (gdb) b make_ +GDB sounds bell; press again, to see: + make_a_section_from_file make_environ + make_abs_section make_function_type + make_blockvector make_pointer_type + make_cleanup make_reference_type + make_command make_symbol_completion_list + (gdb) b make_ + +After displaying the available possibilities, GDB copies your partial +input (`b make_' in the example) so you can finish the command. + + If you just want to see the list of alternatives in the first place, +you can press `M-?' rather than pressing twice. `M-?' means +` ?'. You can type this either by holding down a key designated +as the shift on your keyboard (if there is one) while typing +`?', or as followed by `?'. + + Sometimes the string you need, while logically a "word", may contain +parentheses or other characters that GDB normally excludes from its +notion of a word. To permit word completion to work in this situation, +you may enclose words in `'' (single quote marks) in GDB commands. + + The most likely situation where you might need this is in typing the +name of a C++ function. This is because C++ allows function +overloading (multiple definitions of the same function, distinguished +by argument type). For example, when you want to set a breakpoint you +may need to distinguish whether you mean the version of `name' that +takes an `int' parameter, `name(int)', or the version that takes a +`float' parameter, `name(float)'. To use the word-completion +facilities in this situation, type a single quote `'' at the beginning +of the function name. This alerts GDB that it may need to consider +more information than usual when you press or `M-?' to request +word completion: + + (gdb) b 'bubble( M-? + bubble(double,double) bubble(int,int) + (gdb) b 'bubble( + + In some cases, GDB can tell that completing a name requires using +quotes. When this happens, GDB inserts the quote for you (while +completing as much as it can) if you do not type the quote in the first +place: + + (gdb) b bub +GDB alters your input line to the following, and rings a bell: + (gdb) b 'bubble( + +In general, GDB can tell that a quote is needed (and inserts it) if you +have not yet started typing the argument list when you ask for +completion on an overloaded symbol. + + For more information about overloaded functions, see *Note C++ +expressions: C plus plus expressions. You can use the command `set +overload-resolution off' to disable overload resolution; see *Note GDB +features for C++: Debugging C plus plus. + + +File: gdb.info, Node: Help, Prev: Completion, Up: Commands + +Getting help +============ + +You can always ask GDB itself for information on its commands, using +the command `help'. + +`help' +`h' + You can use `help' (abbreviated `h') with no arguments to display + a short list of named classes of commands: + + (gdb) help + List of classes of commands: + + aliases -- Aliases of other commands + breakpoints -- Making program stop at certain points + data -- Examining data + files -- Specifying and examining files + internals -- Maintenance commands + obscure -- Obscure features + running -- Running the program + stack -- Examining the stack + status -- Status inquiries + support -- Support facilities + tracepoints -- Tracing of program execution without + + stopping the program + user-defined -- User-defined commands + + Type "help" followed by a class name for a list of + commands in that class. + Type "help" followed by command name for full + documentation. + Command name abbreviations are allowed if unambiguous. + (gdb) + +`help CLASS' + Using one of the general help classes as an argument, you can get a + list of the individual commands in that class. For example, here + is the help display for the class `status': + + (gdb) help status + Status inquiries. + + List of commands: + + info -- Generic command for showing things + about the program being debugged + show -- Generic command for showing things + about the debugger + + Type "help" followed by command name for full + documentation. + Command name abbreviations are allowed if unambiguous. + (gdb) + +`help COMMAND' + With a command name as `help' argument, GDB displays a short + paragraph on how to use that command. + +`apropos ARGS' + The `apropos ARGS' command searches through all of the GDB + commands, and their documentation, for the regular expression + specified in ARGS. It prints out all matches found. For example: + + apropos reload + + results in: + + set symbol-reloading -- Set dynamic symbol table reloading + multiple times in one run + show symbol-reloading -- Show dynamic symbol table reloading + multiple times in one run + +`complete ARGS' + The `complete ARGS' command lists all the possible completions for + the beginning of a command. Use ARGS to specify the beginning of + the command you want completed. For example: + + complete i + + results in: + + if + ignore + info + inspect + + This is intended for use by GNU Emacs. + + In addition to `help', you can use the GDB commands `info' and +`show' to inquire about the state of your program, or the state of GDB +itself. Each command supports many topics of inquiry; this manual +introduces each of them in the appropriate context. The listings under +`info' and under `show' in the Index point to all the sub-commands. +*Note Index::. + +`info' + This command (abbreviated `i') is for describing the state of your + program. For example, you can list the arguments given to your + program with `info args', list the registers currently in use with + `info registers', or list the breakpoints you have set with `info + breakpoints'. You can get a complete list of the `info' + sub-commands with `help info'. + +`set' + You can assign the result of an expression to an environment + variable with `set'. For example, you can set the GDB prompt to a + $-sign with `set prompt $'. + +`show' + In contrast to `info', `show' is for describing the state of GDB + itself. You can change most of the things you can `show', by + using the related command `set'; for example, you can control what + number system is used for displays with `set radix', or simply + inquire which is currently in use with `show radix'. + + To display all the settable parameters and their current values, + you can use `show' with no arguments; you may also use `info set'. + Both commands produce the same display. + + Here are three miscellaneous `show' subcommands, all of which are +exceptional in lacking corresponding `set' commands: + +`show version' + Show what version of GDB is running. You should include this + information in GDB bug-reports. If multiple versions of GDB are + in use at your site, you may need to determine which version of + GDB you are running; as GDB evolves, new commands are introduced, + and old ones may wither away. Also, many system vendors ship + variant versions of GDB, and there are variant versions of GDB in + GNU/Linux distributions as well. The version number is the same + as the one announced when you start GDB. + +`show copying' + Display information about permission for copying GDB. + +`show warranty' + Display the GNU "NO WARRANTY" statement, or a warranty, if your + version of GDB comes with one. + + + +File: gdb.info, Node: Running, Next: Stopping, Prev: Commands, Up: Top + +Running Programs Under GDB +************************** + +When you run a program under GDB, you must first generate debugging +information when you compile it. + + You may start GDB with its arguments, if any, in an environment of +your choice. If you are doing native debugging, you may redirect your +program's input and output, debug an already running process, or kill a +child process. + +* Menu: + +* Compilation:: Compiling for debugging +* Starting:: Starting your program +* Arguments:: Your program's arguments +* Environment:: Your program's environment + +* Working Directory:: Your program's working directory +* Input/Output:: Your program's input and output +* Attach:: Debugging an already-running process +* Kill Process:: Killing the child process + +* Threads:: Debugging programs with multiple threads +* Processes:: Debugging programs with multiple processes + + +File: gdb.info, Node: Compilation, Next: Starting, Up: Running + +Compiling for debugging +======================= + +In order to debug a program effectively, you need to generate debugging +information when you compile it. This debugging information is stored +in the object file; it describes the data type of each variable or +function and the correspondence between source line numbers and +addresses in the executable code. + + To request debugging information, specify the `-g' option when you +run the compiler. + + Most compilers do not include information about preprocessor macros +in the debugging information if you specify the `-g' flag alone, +because this information is rather large. Version 3.1 of GCC, the GNU +C compiler, provides macro information if you specify the options +`-gdwarf-2' and `-g3'; the former option requests debugging information +in the Dwarf 2 format, and the latter requests "extra information". In +the future, we hope to find more compact ways to represent macro +information, so that it can be included with `-g' alone. + + Many C compilers are unable to handle the `-g' and `-O' options +together. Using those compilers, you cannot generate optimized +executables containing debugging information. + + GCC, the GNU C compiler, supports `-g' with or without `-O', making +it possible to debug optimized code. We recommend that you _always_ +use `-g' whenever you compile a program. You may think your program is +correct, but there is no sense in pushing your luck. + + When you debug a program compiled with `-g -O', remember that the +optimizer is rearranging your code; the debugger shows you what is +really there. Do not be too surprised when the execution path does not +exactly match your source file! An extreme example: if you define a +variable, but never use it, GDB never sees that variable--because the +compiler optimizes it out of existence. + + Some things do not work as well with `-g -O' as with just `-g', +particularly on machines with instruction scheduling. If in doubt, +recompile with `-g' alone, and if this fixes the problem, please report +it to us as a bug (including a test case!). + + Older versions of the GNU C compiler permitted a variant option +`-gg' for debugging information. GDB no longer supports this format; +if your GNU C compiler has this option, do not use it. + + +File: gdb.info, Node: Starting, Next: Arguments, Prev: Compilation, Up: Running + +Starting your program +===================== + +`run' +`r' + Use the `run' command to start your program under GDB. You must + first specify the program name (except on VxWorks) with an + argument to GDB (*note Getting In and Out of GDB: Invocation.), or + by using the `file' or `exec-file' command (*note Commands to + specify files: Files.). + + + If you are running your program in an execution environment that +supports processes, `run' creates an inferior process and makes that +process run your program. (In environments without processes, `run' +jumps to the start of your program.) + + The execution of a program is affected by certain information it +receives from its superior. GDB provides ways to specify this +information, which you must do _before_ starting your program. (You +can change it after starting your program, but such changes only affect +your program the next time you start it.) This information may be +divided into four categories: + +The _arguments._ + Specify the arguments to give your program as the arguments of the + `run' command. If a shell is available on your target, the shell + is used to pass the arguments, so that you may use normal + conventions (such as wildcard expansion or variable substitution) + in describing the arguments. In Unix systems, you can control + which shell is used with the `SHELL' environment variable. *Note + Your program's arguments: Arguments. + +The _environment._ + Your program normally inherits its environment from GDB, but you + can use the GDB commands `set environment' and `unset environment' + to change parts of the environment that affect your program. + *Note Your program's environment: Environment. + +The _working directory._ + Your program inherits its working directory from GDB. You can set + the GDB working directory with the `cd' command in GDB. *Note + Your program's working directory: Working Directory. + +The _standard input and output._ + Your program normally uses the same device for standard input and + standard output as GDB is using. You can redirect input and output + in the `run' command line, or you can use the `tty' command to set + a different device for your program. *Note Your program's input + and output: Input/Output. + + _Warning:_ While input and output redirection work, you cannot use + pipes to pass the output of the program you are debugging to + another program; if you attempt this, GDB is likely to wind up + debugging the wrong program. + + When you issue the `run' command, your program begins to execute +immediately. *Note Stopping and continuing: Stopping, for discussion +of how to arrange for your program to stop. Once your program has +stopped, you may call functions in your program, using the `print' or +`call' commands. *Note Examining Data: Data. + + If the modification time of your symbol file has changed since the +last time GDB read its symbols, GDB discards its symbol table, and +reads it again. When it does this, GDB tries to retain your current +breakpoints. + + +File: gdb.info, Node: Arguments, Next: Environment, Prev: Starting, Up: Running + +Your program's arguments +======================== + +The arguments to your program can be specified by the arguments of the +`run' command. They are passed to a shell, which expands wildcard +characters and performs redirection of I/O, and thence to your program. +Your `SHELL' environment variable (if it exists) specifies what shell +GDB uses. If you do not define `SHELL', GDB uses the default shell +(`/bin/sh' on Unix). + + On non-Unix systems, the program is usually invoked directly by GDB, +which emulates I/O redirection via the appropriate system calls, and +the wildcard characters are expanded by the startup code of the +program, not by the shell. + + `run' with no arguments uses the same arguments used by the previous +`run', or those set by the `set args' command. + +`set args' + Specify the arguments to be used the next time your program is + run. If `set args' has no arguments, `run' executes your program + with no arguments. Once you have run your program with arguments, + using `set args' before the next `run' is the only way to run it + again without arguments. + +`show args' + Show the arguments to give your program when it is started. + + +File: gdb.info, Node: Environment, Next: Working Directory, Prev: Arguments, Up: Running + +Your program's environment +========================== + +The "environment" consists of a set of environment variables and their +values. Environment variables conventionally record such things as +your user name, your home directory, your terminal type, and your search +path for programs to run. Usually you set up environment variables with +the shell and they are inherited by all the other programs you run. +When debugging, it can be useful to try running your program with a +modified environment without having to start GDB over again. + +`path DIRECTORY' + Add DIRECTORY to the front of the `PATH' environment variable (the + search path for executables) that will be passed to your program. + The value of `PATH' used by GDB does not change. You may specify + several directory names, separated by whitespace or by a + system-dependent separator character (`:' on Unix, `;' on MS-DOS + and MS-Windows). If DIRECTORY is already in the path, it is moved + to the front, so it is searched sooner. + + You can use the string `$cwd' to refer to whatever is the current + working directory at the time GDB searches the path. If you use + `.' instead, it refers to the directory where you executed the + `path' command. GDB replaces `.' in the DIRECTORY argument (with + the current path) before adding DIRECTORY to the search path. + +`show paths' + Display the list of search paths for executables (the `PATH' + environment variable). + +`show environment [VARNAME]' + Print the value of environment variable VARNAME to be given to + your program when it starts. If you do not supply VARNAME, print + the names and values of all environment variables to be given to + your program. You can abbreviate `environment' as `env'. + +`set environment VARNAME [=VALUE]' + Set environment variable VARNAME to VALUE. The value changes for + your program only, not for GDB itself. VALUE may be any string; + the values of environment variables are just strings, and any + interpretation is supplied by your program itself. The VALUE + parameter is optional; if it is eliminated, the variable is set to + a null value. + + For example, this command: + + set env USER = foo + + tells the debugged program, when subsequently run, that its user + is named `foo'. (The spaces around `=' are used for clarity here; + they are not actually required.) + +`unset environment VARNAME' + Remove variable VARNAME from the environment to be passed to your + program. This is different from `set env VARNAME ='; `unset + environment' removes the variable from the environment, rather + than assigning it an empty value. + + _Warning:_ On Unix systems, GDB runs your program using the shell +indicated by your `SHELL' environment variable if it exists (or +`/bin/sh' if not). If your `SHELL' variable names a shell that runs an +initialization file--such as `.cshrc' for C-shell, or `.bashrc' for +BASH--any variables you set in that file affect your program. You may +wish to move setting of environment variables to files that are only +run when you sign on, such as `.login' or `.profile'. + + +File: gdb.info, Node: Working Directory, Next: Input/Output, Prev: Environment, Up: Running + +Your program's working directory +================================ + +Each time you start your program with `run', it inherits its working +directory from the current working directory of GDB. The GDB working +directory is initially whatever it inherited from its parent process +(typically the shell), but you can specify a new working directory in +GDB with the `cd' command. + + The GDB working directory also serves as a default for the commands +that specify files for GDB to operate on. *Note Commands to specify +files: Files. + +`cd DIRECTORY' + Set the GDB working directory to DIRECTORY. + +`pwd' + Print the GDB working directory. + + +File: gdb.info, Node: Input/Output, Next: Attach, Prev: Working Directory, Up: Running + +Your program's input and output +=============================== + +By default, the program you run under GDB does input and output to the +same terminal that GDB uses. GDB switches the terminal to its own +terminal modes to interact with you, but it records the terminal modes +your program was using and switches back to them when you continue +running your program. + +`info terminal' + Displays information recorded by GDB about the terminal modes your + program is using. + + You can redirect your program's input and/or output using shell +redirection with the `run' command. For example, + + run > outfile + +starts your program, diverting its output to the file `outfile'. + + Another way to specify where your program should do input and output +is with the `tty' command. This command accepts a file name as +argument, and causes this file to be the default for future `run' +commands. It also resets the controlling terminal for the child +process, for future `run' commands. For example, + + tty /dev/ttyb + +directs that processes started with subsequent `run' commands default +to do input and output on the terminal `/dev/ttyb' and have that as +their controlling terminal. + + An explicit redirection in `run' overrides the `tty' command's +effect on the input/output device, but not its effect on the controlling +terminal. + + When you use the `tty' command or redirect input in the `run' +command, only the input _for your program_ is affected. The input for +GDB still comes from your terminal. + + +File: gdb.info, Node: Attach, Next: Kill Process, Prev: Input/Output, Up: Running + +Debugging an already-running process +==================================== + +`attach PROCESS-ID' + This command attaches to a running process--one that was started + outside GDB. (`info files' shows your active targets.) The + command takes as argument a process ID. The usual way to find out + the process-id of a Unix process is with the `ps' utility, or with + the `jobs -l' shell command. + + `attach' does not repeat if you press a second time after + executing the command. + + To use `attach', your program must be running in an environment +which supports processes; for example, `attach' does not work for +programs on bare-board targets that lack an operating system. You must +also have permission to send the process a signal. + + When you use `attach', the debugger finds the program running in the +process first by looking in the current working directory, then (if the +program is not found) by using the source file search path (*note +Specifying source directories: Source Path.). You can also use the +`file' command to load the program. *Note Commands to Specify Files: +Files. + + The first thing GDB does after arranging to debug the specified +process is to stop it. You can examine and modify an attached process +with all the GDB commands that are ordinarily available when you start +processes with `run'. You can insert breakpoints; you can step and +continue; you can modify storage. If you would rather the process +continue running, you may use the `continue' command after attaching +GDB to the process. + +`detach' + When you have finished debugging the attached process, you can use + the `detach' command to release it from GDB control. Detaching + the process continues its execution. After the `detach' command, + that process and GDB become completely independent once more, and + you are ready to `attach' another process or start one with `run'. + `detach' does not repeat if you press again after executing + the command. + + If you exit GDB or use the `run' command while you have an attached +process, you kill that process. By default, GDB asks for confirmation +if you try to do either of these things; you can control whether or not +you need to confirm by using the `set confirm' command (*note Optional +warnings and messages: Messages/Warnings.). + + +File: gdb.info, Node: Kill Process, Next: Threads, Prev: Attach, Up: Running + +Killing the child process +========================= + +`kill' + Kill the child process in which your program is running under GDB. + + This command is useful if you wish to debug a core dump instead of a +running process. GDB ignores any core dump file while your program is +running. + + On some operating systems, a program cannot be executed outside GDB +while you have breakpoints set on it inside GDB. You can use the +`kill' command in this situation to permit running your program outside +the debugger. + + The `kill' command is also useful if you wish to recompile and +relink your program, since on many systems it is impossible to modify an +executable file while it is running in a process. In this case, when +you next type `run', GDB notices that the file has changed, and reads +the symbol table again (while trying to preserve your current +breakpoint settings). + + +File: gdb.info, Node: Threads, Next: Processes, Prev: Kill Process, Up: Running + +Debugging programs with multiple threads +======================================== + +In some operating systems, such as HP-UX and Solaris, a single program +may have more than one "thread" of execution. The precise semantics of +threads differ from one operating system to another, but in general the +threads of a single program are akin to multiple processes--except that +they share one address space (that is, they can all examine and modify +the same variables). On the other hand, each thread has its own +registers and execution stack, and perhaps private memory. + + GDB provides these facilities for debugging multi-thread programs: + + * automatic notification of new threads + + * `thread THREADNO', a command to switch among threads + + * `info threads', a command to inquire about existing threads + + * `thread apply [THREADNO] [ALL] ARGS', a command to apply a command + to a list of threads + + * thread-specific breakpoints + + _Warning:_ These facilities are not yet available on every GDB + configuration where the operating system supports threads. If + your GDB does not support threads, these commands have no effect. + For example, a system without thread support shows no output from + `info threads', and always rejects the `thread' command, like this: + + (gdb) info threads + (gdb) thread 1 + Thread ID 1 not known. Use the "info threads" command to + see the IDs of currently known threads. + + The GDB thread debugging facility allows you to observe all threads +while your program runs--but whenever GDB takes control, one thread in +particular is always the focus of debugging. This thread is called the +"current thread". Debugging commands show program information from the +perspective of the current thread. + + Whenever GDB detects a new thread in your program, it displays the +target system's identification for the thread with a message in the +form `[New SYSTAG]'. SYSTAG is a thread identifier whose form varies +depending on the particular system. For example, on LynxOS, you might +see + + [New process 35 thread 27] + +when GDB notices a new thread. In contrast, on an SGI system, the +SYSTAG is simply something like `process 368', with no further +qualifier. + + For debugging purposes, GDB associates its own thread number--always +a single integer--with each thread in your program. + +`info threads' + Display a summary of all threads currently in your program. GDB + displays for each thread (in this order): + + 1. the thread number assigned by GDB + + 2. the target system's thread identifier (SYSTAG) + + 3. the current stack frame summary for that thread + + An asterisk `*' to the left of the GDB thread number indicates the + current thread. + + For example, + + (gdb) info threads + 3 process 35 thread 27 0x34e5 in sigpause () + 2 process 35 thread 23 0x34e5 in sigpause () + * 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) + at threadtest.c:68 + + On HP-UX systems: + + For debugging purposes, GDB associates its own thread number--a +small integer assigned in thread-creation order--with each thread in +your program. + + Whenever GDB detects a new thread in your program, it displays both +GDB's thread number and the target system's identification for the +thread with a message in the form `[New SYSTAG]'. SYSTAG is a thread +identifier whose form varies depending on the particular system. For +example, on HP-UX, you see + + [New thread 2 (system thread 26594)] + +when GDB notices a new thread. + +`info threads' + Display a summary of all threads currently in your program. GDB + displays for each thread (in this order): + + 1. the thread number assigned by GDB + + 2. the target system's thread identifier (SYSTAG) + + 3. the current stack frame summary for that thread + + An asterisk `*' to the left of the GDB thread number indicates the + current thread. + + For example, + + (gdb) info threads + * 3 system thread 26607 worker (wptr=0x7b09c318 "@") \ + + at quicksort.c:137 + 2 system thread 26606 0x7b0030d8 in __ksleep () \ + + from /usr/lib/libc.2 + 1 system thread 27905 0x7b003498 in _brk () \ + + from /usr/lib/libc.2 + +`thread THREADNO' + Make thread number THREADNO the current thread. The command + argument THREADNO is the internal GDB thread number, as shown in + the first field of the `info threads' display. GDB responds by + displaying the system identifier of the thread you selected, and + its current stack frame summary: + + (gdb) thread 2 + [Switching to process 35 thread 23] + 0x34e5 in sigpause () + + As with the `[New ...]' message, the form of the text after + `Switching to' depends on your system's conventions for identifying + threads. + +`thread apply [THREADNO] [ALL] ARGS' + The `thread apply' command allows you to apply a command to one or + more threads. Specify the numbers of the threads that you want + affected with the command argument THREADNO. THREADNO is the + internal GDB thread number, as shown in the first field of the + `info threads' display. To apply a command to all threads, use + `thread apply all' ARGS. + + Whenever GDB stops your program, due to a breakpoint or a signal, it +automatically selects the thread where that breakpoint or signal +happened. GDB alerts you to the context switch with a message of the +form `[Switching to SYSTAG]' to identify the thread. + + *Note Stopping and starting multi-thread programs: Thread Stops, for +more information about how GDB behaves when you stop and start programs +with multiple threads. + + *Note Setting watchpoints: Set Watchpoints, for information about +watchpoints in programs with multiple threads. + + +File: gdb.info, Node: Processes, Prev: Threads, Up: Running + +Debugging programs with multiple processes +========================================== + +On most systems, GDB has no special support for debugging programs +which create additional processes using the `fork' function. When a +program forks, GDB will continue to debug the parent process and the +child process will run unimpeded. If you have set a breakpoint in any +code which the child then executes, the child will get a `SIGTRAP' +signal which (unless it catches the signal) will cause it to terminate. + + However, if you want to debug the child process there is a workaround +which isn't too painful. Put a call to `sleep' in the code which the +child process executes after the fork. It may be useful to sleep only +if a certain environment variable is set, or a certain file exists, so +that the delay need not occur when you don't want to run GDB on the +child. While the child is sleeping, use the `ps' program to get its +process ID. Then tell GDB (a new invocation of GDB if you are also +debugging the parent process) to attach to the child process (*note +Attach::). From that point on you can debug the child process just +like any other process which you attached to. + + On some systems, GDB provides support for debugging programs that +create additional processes using the `fork' or `vfork' functions. +Currently, the only platforms with this feature are HP-UX (11.x and +later only?) and GNU/Linux (kernel version 2.5.60 and later). + + By default, when a program forks, GDB will continue to debug the +parent process and the child process will run unimpeded. + + If you want to follow the child process instead of the parent +process, use the command `set follow-fork-mode'. + +`set follow-fork-mode MODE' + Set the debugger response to a program call of `fork' or `vfork'. + A call to `fork' or `vfork' creates a new process. The MODE can + be: + + `parent' + The original process is debugged after a fork. The child + process runs unimpeded. This is the default. + + `child' + The new process is debugged after a fork. The parent process + runs unimpeded. + + +`show follow-fork-mode' + Display the current debugger response to a `fork' or `vfork' call. + + If you ask to debug a child process and a `vfork' is followed by an +`exec', GDB executes the new target up to the first breakpoint in the +new target. If you have a breakpoint set on `main' in your original +program, the breakpoint will also be set on the child process's `main'. + + When a child process is spawned by `vfork', you cannot debug the +child or parent until an `exec' call completes. + + If you issue a `run' command to GDB after an `exec' call executes, +the new target restarts. To restart the parent process, use the `file' +command with the parent executable name as its argument. + + You can use the `catch' command to make GDB stop whenever a `fork', +`vfork', or `exec' call is made. *Note Setting catchpoints: Set +Catchpoints. + + +File: gdb.info, Node: Stopping, Next: Stack, Prev: Running, Up: Top + +Stopping and Continuing +*********************** + +The principal purposes of using a debugger are so that you can stop your +program before it terminates; or so that, if your program runs into +trouble, you can investigate and find out why. + + Inside GDB, your program may stop for any of several reasons, such +as a signal, a breakpoint, or reaching a new line after a GDB command +such as `step'. You may then examine and change variables, set new +breakpoints or remove old ones, and then continue execution. Usually, +the messages shown by GDB provide ample explanation of the status of +your program--but you can also explicitly request this information at +any time. + +`info program' + Display information about the status of your program: whether it is + running or not, what process it is, and why it stopped. + +* Menu: + +* Breakpoints:: Breakpoints, watchpoints, and catchpoints +* Continuing and Stepping:: Resuming execution +* Signals:: Signals +* Thread Stops:: Stopping and starting multi-thread programs + + +File: gdb.info, Node: Breakpoints, Next: Continuing and Stepping, Up: Stopping + +Breakpoints, watchpoints, and catchpoints +========================================= + +A "breakpoint" makes your program stop whenever a certain point in the +program is reached. For each breakpoint, you can add conditions to +control in finer detail whether your program stops. You can set +breakpoints with the `break' command and its variants (*note Setting +breakpoints: Set Breaks.), to specify the place where your program +should stop by line number, function name or exact address in the +program. + + In HP-UX, SunOS 4.x, SVR4, and Alpha OSF/1 configurations, you can +set breakpoints in shared libraries before the executable is run. +There is a minor limitation on HP-UX systems: you must wait until the +executable is run in order to set breakpoints in shared library +routines that are not called directly by the program (for example, +routines that are arguments in a `pthread_create' call). + + A "watchpoint" is a special breakpoint that stops your program when +the value of an expression changes. You must use a different command +to set watchpoints (*note Setting watchpoints: Set Watchpoints.), but +aside from that, you can manage a watchpoint like any other breakpoint: +you enable, disable, and delete both breakpoints and watchpoints using +the same commands. + + You can arrange to have values from your program displayed +automatically whenever GDB stops at a breakpoint. *Note Automatic +display: Auto Display. + + A "catchpoint" is another special breakpoint that stops your program +when a certain kind of event occurs, such as the throwing of a C++ +exception or the loading of a library. As with watchpoints, you use a +different command to set a catchpoint (*note Setting catchpoints: Set +Catchpoints.), but aside from that, you can manage a catchpoint like any +other breakpoint. (To stop when your program receives a signal, use the +`handle' command; see *Note Signals: Signals.) + + GDB assigns a number to each breakpoint, watchpoint, or catchpoint +when you create it; these numbers are successive integers starting with +one. In many of the commands for controlling various features of +breakpoints you use the breakpoint number to say which breakpoint you +want to change. Each breakpoint may be "enabled" or "disabled"; if +disabled, it has no effect on your program until you enable it again. + + Some GDB commands accept a range of breakpoints on which to operate. +A breakpoint range is either a single breakpoint number, like `5', or +two such numbers, in increasing order, separated by a hyphen, like +`5-7'. When a breakpoint range is given to a command, all breakpoint +in that range are operated on. + +* Menu: + +* Set Breaks:: Setting breakpoints +* Set Watchpoints:: Setting watchpoints +* Set Catchpoints:: Setting catchpoints +* Delete Breaks:: Deleting breakpoints +* Disabling:: Disabling breakpoints +* Conditions:: Break conditions +* Break Commands:: Breakpoint command lists +* Breakpoint Menus:: Breakpoint menus +* Error in Breakpoints:: ``Cannot insert breakpoints'' +* Breakpoint related warnings:: ``Breakpoint address adjusted...'' + + +File: gdb.info, Node: Set Breaks, Next: Set Watchpoints, Up: Breakpoints + +Setting breakpoints +------------------- + +Breakpoints are set with the `break' command (abbreviated `b'). The +debugger convenience variable `$bpnum' records the number of the +breakpoint you've set most recently; see *Note Convenience variables: +Convenience Vars, for a discussion of what you can do with convenience +variables. + + You have several ways to say where the breakpoint should go. + +`break FUNCTION' + Set a breakpoint at entry to function FUNCTION. When using source + languages that permit overloading of symbols, such as C++, + FUNCTION may refer to more than one possible place to break. + *Note Breakpoint menus: Breakpoint Menus, for a discussion of that + situation. + +`break +OFFSET' +`break -OFFSET' + Set a breakpoint some number of lines forward or back from the + position at which execution stopped in the currently selected + "stack frame". (*Note Frames: Frames, for a description of stack + frames.) + +`break LINENUM' + Set a breakpoint at line LINENUM in the current source file. The + current source file is the last file whose source text was printed. + The breakpoint will stop your program just before it executes any + of the code on that line. + +`break FILENAME:LINENUM' + Set a breakpoint at line LINENUM in source file FILENAME. + +`break FILENAME:FUNCTION' + Set a breakpoint at entry to function FUNCTION found in file + FILENAME. Specifying a file name as well as a function name is + superfluous except when multiple files contain similarly named + functions. + +`break *ADDRESS' + Set a breakpoint at address ADDRESS. You can use this to set + breakpoints in parts of your program which do not have debugging + information or source files. + +`break' + When called without any arguments, `break' sets a breakpoint at + the next instruction to be executed in the selected stack frame + (*note Examining the Stack: Stack.). In any selected frame but the + innermost, this makes your program stop as soon as control returns + to that frame. This is similar to the effect of a `finish' + command in the frame inside the selected frame--except that + `finish' does not leave an active breakpoint. If you use `break' + without an argument in the innermost frame, GDB stops the next + time it reaches the current location; this may be useful inside + loops. + + GDB normally ignores breakpoints when it resumes execution, until + at least one instruction has been executed. If it did not do + this, you would be unable to proceed past a breakpoint without + first disabling the breakpoint. This rule applies whether or not + the breakpoint already existed when your program stopped. + +`break ... if COND' + Set a breakpoint with condition COND; evaluate the expression COND + each time the breakpoint is reached, and stop only if the value is + nonzero--that is, if COND evaluates as true. `...' stands for one + of the possible arguments described above (or no argument) + specifying where to break. *Note Break conditions: Conditions, + for more information on breakpoint conditions. + +`tbreak ARGS' + Set a breakpoint enabled only for one stop. ARGS are the same as + for the `break' command, and the breakpoint is set in the same + way, but the breakpoint is automatically deleted after the first + time your program stops there. *Note Disabling breakpoints: + Disabling. + +`hbreak ARGS' + Set a hardware-assisted breakpoint. ARGS are the same as for the + `break' command and the breakpoint is set in the same way, but the + breakpoint requires hardware support and some target hardware may + not have this support. The main purpose of this is EPROM/ROM code + debugging, so you can set a breakpoint at an instruction without + changing the instruction. This can be used with the new + trap-generation provided by SPARClite DSU and some x86-based + targets. These targets will generate traps when a program + accesses some data or instruction address that is assigned to the + debug registers. However the hardware breakpoint registers can + take a limited number of breakpoints. For example, on the DSU, + only two data breakpoints can be set at a time, and GDB will + reject this command if more than two are used. Delete or disable + unused hardware breakpoints before setting new ones (*note + Disabling: Disabling.). *Note Break conditions: Conditions. + *Note set remote hardware-breakpoint-limit::. + +`thbreak ARGS' + Set a hardware-assisted breakpoint enabled only for one stop. ARGS + are the same as for the `hbreak' command and the breakpoint is set + in the same way. However, like the `tbreak' command, the + breakpoint is automatically deleted after the first time your + program stops there. Also, like the `hbreak' command, the + breakpoint requires hardware support and some target hardware may + not have this support. *Note Disabling breakpoints: Disabling. + See also *Note Break conditions: Conditions. + +`rbreak REGEX' + Set breakpoints on all functions matching the regular expression + REGEX. This command sets an unconditional breakpoint on all + matches, printing a list of all breakpoints it set. Once these + breakpoints are set, they are treated just like the breakpoints + set with the `break' command. You can delete them, disable them, + or make them conditional the same way as any other breakpoint. + + The syntax of the regular expression is the standard one used with + tools like `grep'. Note that this is different from the syntax + used by shells, so for instance `foo*' matches all functions that + include an `fo' followed by zero or more `o's. There is an + implicit `.*' leading and trailing the regular expression you + supply, so to match only functions that begin with `foo', use + `^foo'. + + When debugging C++ programs, `rbreak' is useful for setting + breakpoints on overloaded functions that are not members of any + special classes. + +`info breakpoints [N]' +`info break [N]' +`info watchpoints [N]' + Print a table of all breakpoints, watchpoints, and catchpoints set + and not deleted, with the following columns for each breakpoint: + + _Breakpoint Numbers_ + + _Type_ + Breakpoint, watchpoint, or catchpoint. + + _Disposition_ + Whether the breakpoint is marked to be disabled or deleted + when hit. + + _Enabled or Disabled_ + Enabled breakpoints are marked with `y'. `n' marks + breakpoints that are not enabled. + + _Address_ + Where the breakpoint is in your program, as a memory address. + If the breakpoint is pending (see below for details) on a + future load of a shared library, the address will be listed + as `'. + + _What_ + Where the breakpoint is in the source for your program, as a + file and line number. For a pending breakpoint, the original + string passed to the breakpoint command will be listed as it + cannot be resolved until the appropriate shared library is + loaded in the future. + + If a breakpoint is conditional, `info break' shows the condition on + the line following the affected breakpoint; breakpoint commands, + if any, are listed after that. A pending breakpoint is allowed to + have a condition specified for it. The condition is not parsed + for validity until a shared library is loaded that allows the + pending breakpoint to resolve to a valid location. + + `info break' with a breakpoint number N as argument lists only + that breakpoint. The convenience variable `$_' and the default + examining-address for the `x' command are set to the address of + the last breakpoint listed (*note Examining memory: Memory.). + + `info break' displays a count of the number of times the breakpoint + has been hit. This is especially useful in conjunction with the + `ignore' command. You can ignore a large number of breakpoint + hits, look at the breakpoint info to see how many times the + breakpoint was hit, and then run again, ignoring one less than + that number. This will get you quickly to the last hit of that + breakpoint. + + GDB allows you to set any number of breakpoints at the same place in +your program. There is nothing silly or meaningless about this. When +the breakpoints are conditional, this is even useful (*note Break +conditions: Conditions.). + + If a specified breakpoint location cannot be found, it may be due to +the fact that the location is in a shared library that is yet to be +loaded. In such a case, you may want GDB to create a special +breakpoint (known as a "pending breakpoint") that attempts to resolve +itself in the future when an appropriate shared library gets loaded. + + Pending breakpoints are useful to set at the start of your GDB +session for locations that you know will be dynamically loaded later by +the program being debugged. When shared libraries are loaded, a check +is made to see if the load resolves any pending breakpoint locations. +If a pending breakpoint location gets resolved, a regular breakpoint is +created and the original pending breakpoint is removed. + + GDB provides some additional commands for controlling pending +breakpoint support: + +`set breakpoint pending auto' + This is the default behavior. When GDB cannot find the breakpoint + location, it queries you whether a pending breakpoint should be + created. + +`set breakpoint pending on' + This indicates that an unrecognized breakpoint location should + automatically result in a pending breakpoint being created. + +`set breakpoint pending off' + This indicates that pending breakpoints are not to be created. Any + unrecognized breakpoint location results in an error. This + setting does not affect any pending breakpoints previously created. + +`show breakpoint pending' + Show the current behavior setting for creating pending breakpoints. + + Normal breakpoint operations apply to pending breakpoints as well. +You may specify a condition for a pending breakpoint and/or commands to +run when the breakpoint is reached. You can also enable or disable the +pending breakpoint. When you specify a condition for a pending +breakpoint, the parsing of the condition will be deferred until the +point where the pending breakpoint location is resolved. Disabling a +pending breakpoint tells GDB to not attempt to resolve the breakpoint +on any subsequent shared library load. When a pending breakpoint is +re-enabled, GDB checks to see if the location is already resolved. +This is done because any number of shared library loads could have +occurred since the time the breakpoint was disabled and one or more of +these loads could resolve the location. + + GDB itself sometimes sets breakpoints in your program for special +purposes, such as proper handling of `longjmp' (in C programs). These +internal breakpoints are assigned negative numbers, starting with `-1'; +`info breakpoints' does not display them. You can see these +breakpoints with the GDB maintenance command `maint info breakpoints' +(*note maint info breakpoints::). + + +File: gdb.info, Node: Set Watchpoints, Next: Set Catchpoints, Prev: Set Breaks, Up: Breakpoints + +Setting watchpoints +------------------- + +You can use a watchpoint to stop execution whenever the value of an +expression changes, without having to predict a particular place where +this may happen. + + Depending on your system, watchpoints may be implemented in software +or hardware. GDB does software watchpointing by single-stepping your +program and testing the variable's value each time, which is hundreds of +times slower than normal execution. (But this may still be worth it, to +catch errors where you have no clue what part of your program is the +culprit.) + + On some systems, such as HP-UX, GNU/Linux and some other x86-based +targets, GDB includes support for hardware watchpoints, which do not +slow down the running of your program. + +`watch EXPR' + Set a watchpoint for an expression. GDB will break when EXPR is + written into by the program and its value changes. + +`rwatch EXPR' + Set a watchpoint that will break when watch EXPR is read by the + program. + +`awatch EXPR' + Set a watchpoint that will break when EXPR is either read or + written into by the program. + +`info watchpoints' + This command prints a list of watchpoints, breakpoints, and + catchpoints; it is the same as `info break'. + + GDB sets a "hardware watchpoint" if possible. Hardware watchpoints +execute very quickly, and the debugger reports a change in value at the +exact instruction where the change occurs. If GDB cannot set a +hardware watchpoint, it sets a software watchpoint, which executes more +slowly and reports the change in value at the next statement, not the +instruction, after the change occurs. + + When you issue the `watch' command, GDB reports + + Hardware watchpoint NUM: EXPR + +if it was able to set a hardware watchpoint. + + Currently, the `awatch' and `rwatch' commands can only set hardware +watchpoints, because accesses to data that don't change the value of +the watched expression cannot be detected without examining every +instruction as it is being executed, and GDB does not do that +currently. If GDB finds that it is unable to set a hardware breakpoint +with the `awatch' or `rwatch' command, it will print a message like +this: + + Expression cannot be implemented with read/access watchpoint. + + Sometimes, GDB cannot set a hardware watchpoint because the data +type of the watched expression is wider than what a hardware watchpoint +on the target machine can handle. For example, some systems can only +watch regions that are up to 4 bytes wide; on such systems you cannot +set hardware watchpoints for an expression that yields a +double-precision floating-point number (which is typically 8 bytes +wide). As a work-around, it might be possible to break the large region +into a series of smaller ones and watch them with separate watchpoints. + + If you set too many hardware watchpoints, GDB might be unable to +insert all of them when you resume the execution of your program. +Since the precise number of active watchpoints is unknown until such +time as the program is about to be resumed, GDB might not be able to +warn you about this when you set the watchpoints, and the warning will +be printed only when the program is resumed: + + Hardware watchpoint NUM: Could not insert watchpoint + +If this happens, delete or disable some of the watchpoints. + + The SPARClite DSU will generate traps when a program accesses some +data or instruction address that is assigned to the debug registers. +For the data addresses, DSU facilitates the `watch' command. However +the hardware breakpoint registers can only take two data watchpoints, +and both watchpoints must be the same kind. For example, you can set +two watchpoints with `watch' commands, two with `rwatch' commands, *or* +two with `awatch' commands, but you cannot set one watchpoint with one +command and the other with a different command. GDB will reject the +command if you try to mix watchpoints. Delete or disable unused +watchpoint commands before setting new ones. + + If you call a function interactively using `print' or `call', any +watchpoints you have set will be inactive until GDB reaches another +kind of breakpoint or the call completes. + + GDB automatically deletes watchpoints that watch local (automatic) +variables, or expressions that involve such variables, when they go out +of scope, that is, when the execution leaves the block in which these +variables were defined. In particular, when the program being debugged +terminates, _all_ local variables go out of scope, and so only +watchpoints that watch global variables remain set. If you rerun the +program, you will need to set all such watchpoints again. One way of +doing that would be to set a code breakpoint at the entry to the `main' +function and when it breaks, set all the watchpoints. + + _Warning:_ In multi-thread programs, watchpoints have only limited + usefulness. With the current watchpoint implementation, GDB can + only watch the value of an expression _in a single thread_. If + you are confident that the expression can only change due to the + current thread's activity (and if you are also confident that no + other thread can become current), then you can use watchpoints as + usual. However, GDB may not notice when a non-current thread's + activity changes the expression. + + _HP-UX Warning:_ In multi-thread programs, software watchpoints + have only limited usefulness. If GDB creates a software + watchpoint, it can only watch the value of an expression _in a + single thread_. If you are confident that the expression can only + change due to the current thread's activity (and if you are also + confident that no other thread can become current), then you can + use software watchpoints as usual. However, GDB may not notice + when a non-current thread's activity changes the expression. + (Hardware watchpoints, in contrast, watch an expression in all + threads.) + + *Note set remote hardware-watchpoint-limit::. + + +File: gdb.info, Node: Set Catchpoints, Next: Delete Breaks, Prev: Set Watchpoints, Up: Breakpoints + +Setting catchpoints +------------------- + +You can use "catchpoints" to cause the debugger to stop for certain +kinds of program events, such as C++ exceptions or the loading of a +shared library. Use the `catch' command to set a catchpoint. + +`catch EVENT' + Stop when EVENT occurs. EVENT can be any of the following: + `throw' + The throwing of a C++ exception. + + `catch' + The catching of a C++ exception. + + `exec' + A call to `exec'. This is currently only available for HP-UX. + + `fork' + A call to `fork'. This is currently only available for HP-UX. + + `vfork' + A call to `vfork'. This is currently only available for + HP-UX. + + `load' + `load LIBNAME' + The dynamic loading of any shared library, or the loading of + the library LIBNAME. This is currently only available for + HP-UX. + + `unload' + `unload LIBNAME' + The unloading of any dynamically loaded shared library, or + the unloading of the library LIBNAME. This is currently only + available for HP-UX. + +`tcatch EVENT' + Set a catchpoint that is enabled only for one stop. The + catchpoint is automatically deleted after the first time the event + is caught. + + + Use the `info break' command to list the current catchpoints. + + There are currently some limitations to C++ exception handling +(`catch throw' and `catch catch') in GDB: + + * If you call a function interactively, GDB normally returns control + to you when the function has finished executing. If the call + raises an exception, however, the call may bypass the mechanism + that returns control to you and cause your program either to abort + or to simply continue running until it hits a breakpoint, catches + a signal that GDB is listening for, or exits. This is the case + even if you set a catchpoint for the exception; catchpoints on + exceptions are disabled within interactive calls. + + * You cannot raise an exception interactively. + + * You cannot install an exception handler interactively. + + Sometimes `catch' is not the best way to debug exception handling: +if you need to know exactly where an exception is raised, it is better +to stop _before_ the exception handler is called, since that way you +can see the stack before any unwinding takes place. If you set a +breakpoint in an exception handler instead, it may not be easy to find +out where the exception was raised. + + To stop just before an exception handler is called, you need some +knowledge of the implementation. In the case of GNU C++, exceptions are +raised by calling a library function named `__raise_exception' which +has the following ANSI C interface: + + /* ADDR is where the exception identifier is stored. + ID is the exception identifier. */ + void __raise_exception (void **addr, void *id); + +To make the debugger catch all exceptions before any stack unwinding +takes place, set a breakpoint on `__raise_exception' (*note +Breakpoints; watchpoints; and exceptions: Breakpoints.). + + With a conditional breakpoint (*note Break conditions: Conditions.) +that depends on the value of ID, you can stop your program when a +specific exception is raised. You can use multiple conditional +breakpoints to stop your program when any of a number of exceptions are +raised. + + +File: gdb.info, Node: Delete Breaks, Next: Disabling, Prev: Set Catchpoints, Up: Breakpoints + +Deleting breakpoints +-------------------- + +It is often necessary to eliminate a breakpoint, watchpoint, or +catchpoint once it has done its job and you no longer want your program +to stop there. This is called "deleting" the breakpoint. A breakpoint +that has been deleted no longer exists; it is forgotten. + + With the `clear' command you can delete breakpoints according to +where they are in your program. With the `delete' command you can +delete individual breakpoints, watchpoints, or catchpoints by specifying +their breakpoint numbers. + + It is not necessary to delete a breakpoint to proceed past it. GDB +automatically ignores breakpoints on the first instruction to be +executed when you continue execution without changing the execution +address. + +`clear' + Delete any breakpoints at the next instruction to be executed in + the selected stack frame (*note Selecting a frame: Selection.). + When the innermost frame is selected, this is a good way to delete + a breakpoint where your program just stopped. + +`clear FUNCTION' +`clear FILENAME:FUNCTION' + Delete any breakpoints set at entry to the function FUNCTION. + +`clear LINENUM' +`clear FILENAME:LINENUM' + Delete any breakpoints set at or within the code of the specified + line. + +`delete [breakpoints] [RANGE...]' + Delete the breakpoints, watchpoints, or catchpoints of the + breakpoint ranges specified as arguments. If no argument is + specified, delete all breakpoints (GDB asks confirmation, unless + you have `set confirm off'). You can abbreviate this command as + `d'. + + +File: gdb.info, Node: Disabling, Next: Conditions, Prev: Delete Breaks, Up: Breakpoints + +Disabling breakpoints +--------------------- + +Rather than deleting a breakpoint, watchpoint, or catchpoint, you might +prefer to "disable" it. This makes the breakpoint inoperative as if it +had been deleted, but remembers the information on the breakpoint so +that you can "enable" it again later. + + You disable and enable breakpoints, watchpoints, and catchpoints with +the `enable' and `disable' commands, optionally specifying one or more +breakpoint numbers as arguments. Use `info break' or `info watch' to +print a list of breakpoints, watchpoints, and catchpoints if you do not +know which numbers to use. + + A breakpoint, watchpoint, or catchpoint can have any of four +different states of enablement: + + * Enabled. The breakpoint stops your program. A breakpoint set + with the `break' command starts out in this state. + + * Disabled. The breakpoint has no effect on your program. + + * Enabled once. The breakpoint stops your program, but then becomes + disabled. + + * Enabled for deletion. The breakpoint stops your program, but + immediately after it does so it is deleted permanently. A + breakpoint set with the `tbreak' command starts out in this state. + + You can use the following commands to enable or disable breakpoints, +watchpoints, and catchpoints: + +`disable [breakpoints] [RANGE...]' + Disable the specified breakpoints--or all breakpoints, if none are + listed. A disabled breakpoint has no effect but is not forgotten. + All options such as ignore-counts, conditions and commands are + remembered in case the breakpoint is enabled again later. You may + abbreviate `disable' as `dis'. + +`enable [breakpoints] [RANGE...]' + Enable the specified breakpoints (or all defined breakpoints). + They become effective once again in stopping your program. + +`enable [breakpoints] once RANGE...' + Enable the specified breakpoints temporarily. GDB disables any of + these breakpoints immediately after stopping your program. + +`enable [breakpoints] delete RANGE...' + Enable the specified breakpoints to work once, then die. GDB + deletes any of these breakpoints as soon as your program stops + there. + + Except for a breakpoint set with `tbreak' (*note Setting +breakpoints: Set Breaks.), breakpoints that you set are initially +enabled; subsequently, they become disabled or enabled only when you +use one of the commands above. (The command `until' can set and delete +a breakpoint of its own, but it does not change the state of your other +breakpoints; see *Note Continuing and stepping: Continuing and +Stepping.) + + +File: gdb.info, Node: Conditions, Next: Break Commands, Prev: Disabling, Up: Breakpoints + +Break conditions +---------------- + +The simplest sort of breakpoint breaks every time your program reaches a +specified place. You can also specify a "condition" for a breakpoint. +A condition is just a Boolean expression in your programming language +(*note Expressions: Expressions.). A breakpoint with a condition +evaluates the expression each time your program reaches it, and your +program stops only if the condition is _true_. + + This is the converse of using assertions for program validation; in +that situation, you want to stop when the assertion is violated--that +is, when the condition is false. In C, if you want to test an +assertion expressed by the condition ASSERT, you should set the +condition `! ASSERT' on the appropriate breakpoint. + + Conditions are also accepted for watchpoints; you may not need them, +since a watchpoint is inspecting the value of an expression anyhow--but +it might be simpler, say, to just set a watchpoint on a variable name, +and specify a condition that tests whether the new value is an +interesting one. + + Break conditions can have side effects, and may even call functions +in your program. This can be useful, for example, to activate functions +that log program progress, or to use your own print functions to format +special data structures. The effects are completely predictable unless +there is another enabled breakpoint at the same address. (In that +case, GDB might see the other breakpoint first and stop your program +without checking the condition of this one.) Note that breakpoint +commands are usually more convenient and flexible than break conditions +for the purpose of performing side effects when a breakpoint is reached +(*note Breakpoint command lists: Break Commands.). + + Break conditions can be specified when a breakpoint is set, by using +`if' in the arguments to the `break' command. *Note Setting +breakpoints: Set Breaks. They can also be changed at any time with the +`condition' command. + + You can also use the `if' keyword with the `watch' command. The +`catch' command does not recognize the `if' keyword; `condition' is the +only way to impose a further condition on a catchpoint. + +`condition BNUM EXPRESSION' + Specify EXPRESSION as the break condition for breakpoint, + watchpoint, or catchpoint number BNUM. After you set a condition, + breakpoint BNUM stops your program only if the value of EXPRESSION + is true (nonzero, in C). When you use `condition', GDB checks + EXPRESSION immediately for syntactic correctness, and to determine + whether symbols in it have referents in the context of your + breakpoint. If EXPRESSION uses symbols not referenced in the + context of the breakpoint, GDB prints an error message: + + No symbol "foo" in current context. + + GDB does not actually evaluate EXPRESSION at the time the + `condition' command (or a command that sets a breakpoint with a + condition, like `break if ...') is given, however. *Note + Expressions: Expressions. + +`condition BNUM' + Remove the condition from breakpoint number BNUM. It becomes an + ordinary unconditional breakpoint. + + A special case of a breakpoint condition is to stop only when the +breakpoint has been reached a certain number of times. This is so +useful that there is a special way to do it, using the "ignore count" +of the breakpoint. Every breakpoint has an ignore count, which is an +integer. Most of the time, the ignore count is zero, and therefore has +no effect. But if your program reaches a breakpoint whose ignore count +is positive, then instead of stopping, it just decrements the ignore +count by one and continues. As a result, if the ignore count value is +N, the breakpoint does not stop the next N times your program reaches +it. + +`ignore BNUM COUNT' + Set the ignore count of breakpoint number BNUM to COUNT. The next + COUNT times the breakpoint is reached, your program's execution + does not stop; other than to decrement the ignore count, GDB takes + no action. + + To make the breakpoint stop the next time it is reached, specify a + count of zero. + + When you use `continue' to resume execution of your program from a + breakpoint, you can specify an ignore count directly as an + argument to `continue', rather than using `ignore'. *Note + Continuing and stepping: Continuing and Stepping. + + If a breakpoint has a positive ignore count and a condition, the + condition is not checked. Once the ignore count reaches zero, GDB + resumes checking the condition. + + You could achieve the effect of the ignore count with a condition + such as `$foo-- <= 0' using a debugger convenience variable that + is decremented each time. *Note Convenience variables: + Convenience Vars. + + Ignore counts apply to breakpoints, watchpoints, and catchpoints. + + +File: gdb.info, Node: Break Commands, Next: Breakpoint Menus, Prev: Conditions, Up: Breakpoints + +Breakpoint command lists +------------------------ + +You can give any breakpoint (or watchpoint or catchpoint) a series of +commands to execute when your program stops due to that breakpoint. For +example, you might want to print the values of certain expressions, or +enable other breakpoints. + +`commands [BNUM]' +`... COMMAND-LIST ...' +`end' + Specify a list of commands for breakpoint number BNUM. The + commands themselves appear on the following lines. Type a line + containing just `end' to terminate the commands. + + To remove all commands from a breakpoint, type `commands' and + follow it immediately with `end'; that is, give no commands. + + With no BNUM argument, `commands' refers to the last breakpoint, + watchpoint, or catchpoint set (not to the breakpoint most recently + encountered). + + Pressing as a means of repeating the last GDB command is +disabled within a COMMAND-LIST. + + You can use breakpoint commands to start your program up again. +Simply use the `continue' command, or `step', or any other command that +resumes execution. + + Any other commands in the command list, after a command that resumes +execution, are ignored. This is because any time you resume execution +(even with a simple `next' or `step'), you may encounter another +breakpoint--which could have its own command list, leading to +ambiguities about which list to execute. + + If the first command you specify in a command list is `silent', the +usual message about stopping at a breakpoint is not printed. This may +be desirable for breakpoints that are to print a specific message and +then continue. If none of the remaining commands print anything, you +see no sign that the breakpoint was reached. `silent' is meaningful +only at the beginning of a breakpoint command list. + + The commands `echo', `output', and `printf' allow you to print +precisely controlled output, and are often useful in silent +breakpoints. *Note Commands for controlled output: Output. + + For example, here is how you could use breakpoint commands to print +the value of `x' at entry to `foo' whenever `x' is positive. + + break foo if x>0 + commands + silent + printf "x is %d\n",x + cont + end + + One application for breakpoint commands is to compensate for one bug +so you can test for another. Put a breakpoint just after the erroneous +line of code, give it a condition to detect the case in which something +erroneous has been done, and give it commands to assign correct values +to any variables that need them. End with the `continue' command so +that your program does not stop, and start with the `silent' command so +that no output is produced. Here is an example: + + break 403 + commands + silent + set x = y + 4 + cont + end + + +File: gdb.info, Node: Breakpoint Menus, Next: Error in Breakpoints, Prev: Break Commands, Up: Breakpoints + +Breakpoint menus +---------------- + +Some programming languages (notably C++ and Objective-C) permit a +single function name to be defined several times, for application in +different contexts. This is called "overloading". When a function +name is overloaded, `break FUNCTION' is not enough to tell GDB where +you want a breakpoint. If you realize this is a problem, you can use +something like `break FUNCTION(TYPES)' to specify which particular +version of the function you want. Otherwise, GDB offers you a menu of +numbered choices for different possible breakpoints, and waits for your +selection with the prompt `>'. The first two options are always `[0] +cancel' and `[1] all'. Typing `1' sets a breakpoint at each definition +of FUNCTION, and typing `0' aborts the `break' command without setting +any new breakpoints. + + For example, the following session excerpt shows an attempt to set a +breakpoint at the overloaded symbol `String::after'. We choose three +particular definitions of that function name: + + (gdb) b String::after + [0] cancel + [1] all + [2] file:String.cc; line number:867 + [3] file:String.cc; line number:860 + [4] file:String.cc; line number:875 + [5] file:String.cc; line number:853 + [6] file:String.cc; line number:846 + [7] file:String.cc; line number:735 + > 2 4 6 + Breakpoint 1 at 0xb26c: file String.cc, line 867. + Breakpoint 2 at 0xb344: file String.cc, line 875. + Breakpoint 3 at 0xafcc: file String.cc, line 846. + Multiple breakpoints were set. + Use the "delete" command to delete unwanted + breakpoints. + (gdb) + + +File: gdb.info, Node: Error in Breakpoints, Next: Breakpoint related warnings, Prev: Breakpoint Menus, Up: Breakpoints + +"Cannot insert breakpoints" +--------------------------- + +Under some operating systems, breakpoints cannot be used in a program if +any other process is running that program. In this situation, +attempting to run or continue a program with a breakpoint causes GDB to +print an error message: + + Cannot insert breakpoints. + The same program may be running in another process. + + When this happens, you have three ways to proceed: + + 1. Remove or disable the breakpoints, then continue. + + 2. Suspend GDB, and copy the file containing your program to a new + name. Resume GDB and use the `exec-file' command to specify that + GDB should run your program under that name. Then start your + program again. + + 3. Relink your program so that the text segment is nonsharable, using + the linker option `-N'. The operating system limitation may not + apply to nonsharable executables. + + A similar message can be printed if you request too many active +hardware-assisted breakpoints and watchpoints: + + Stopped; cannot insert breakpoints. + You may have requested too many hardware breakpoints and watchpoints. + +This message is printed when you attempt to resume the program, since +only then GDB knows exactly how many hardware breakpoints and +watchpoints it needs to insert. + + When this message is printed, you need to disable or remove some of +the hardware-assisted breakpoints and watchpoints, and then continue. + + +File: gdb.info, Node: Breakpoint related warnings, Prev: Error in Breakpoints, Up: Breakpoints + +"Breakpoint address adjusted..." +-------------------------------- + +Some processor architectures place constraints on the addresses at +which breakpoints may be placed. For architectures thus constrained, +GDB will attempt to adjust the breakpoint's address to comply with the +constraints dictated by the architecture. + + One example of such an architecture is the Fujitsu FR-V. The FR-V is +a VLIW architecture in which a number of RISC-like instructions may be +bundled together for parallel execution. The FR-V architecture +constrains the location of a breakpoint instruction within such a +bundle to the instruction with the lowest address. GDB honors this +constraint by adjusting a breakpoint's address to the first in the +bundle. + + It is not uncommon for optimized code to have bundles which contain +instructions from different source statements, thus it may happen that +a breakpoint's address will be adjusted from one source statement to +another. Since this adjustment may significantly alter GDB's +breakpoint related behavior from what the user expects, a warning is +printed when the breakpoint is first set and also when the breakpoint +is hit. + + A warning like the one below is printed when setting a breakpoint +that's been subject to address adjustment: + + warning: Breakpoint address adjusted from 0x00010414 to 0x00010410. + + Such warnings are printed both for user settable and GDB's internal +breakpoints. If you see one of these warnings, you should verify that +a breakpoint set at the adjusted address will have the desired affect. +If not, the breakpoint in question may be removed and other breakpoints +may be set which will have the desired behavior. E.g., it may be +sufficient to place the breakpoint at a later instruction. A +conditional breakpoint may also be useful in some cases to prevent the +breakpoint from triggering too often. + + GDB will also issue a warning when stopping at one of these adjusted +breakpoints: + + warning: Breakpoint 1 address previously adjusted from 0x00010414 + to 0x00010410. + + When this warning is encountered, it may be too late to take remedial +action except in cases where the breakpoint is hit earlier or more +frequently than expected. + + +File: gdb.info, Node: Continuing and Stepping, Next: Signals, Prev: Breakpoints, Up: Stopping + +Continuing and stepping +======================= + +"Continuing" means resuming program execution until your program +completes normally. In contrast, "stepping" means executing just one +more "step" of your program, where "step" may mean either one line of +source code, or one machine instruction (depending on what particular +command you use). Either when continuing or when stepping, your +program may stop even sooner, due to a breakpoint or a signal. (If it +stops due to a signal, you may want to use `handle', or use `signal 0' +to resume execution. *Note Signals: Signals.) + +`continue [IGNORE-COUNT]' +`c [IGNORE-COUNT]' +`fg [IGNORE-COUNT]' + Resume program execution, at the address where your program last + stopped; any breakpoints set at that address are bypassed. The + optional argument IGNORE-COUNT allows you to specify a further + number of times to ignore a breakpoint at this location; its + effect is like that of `ignore' (*note Break conditions: + Conditions.). + + The argument IGNORE-COUNT is meaningful only when your program + stopped due to a breakpoint. At other times, the argument to + `continue' is ignored. + + The synonyms `c' and `fg' (for "foreground", as the debugged + program is deemed to be the foreground program) are provided + purely for convenience, and have exactly the same behavior as + `continue'. + + To resume execution at a different place, you can use `return' +(*note Returning from a function: Returning.) to go back to the calling +function; or `jump' (*note Continuing at a different address: Jumping.) +to go to an arbitrary location in your program. + + A typical technique for using stepping is to set a breakpoint (*note +Breakpoints; watchpoints; and catchpoints: Breakpoints.) at the +beginning of the function or the section of your program where a problem +is believed to lie, run your program until it stops at that breakpoint, +and then step through the suspect area, examining the variables that are +interesting, until you see the problem happen. + +`step' + Continue running your program until control reaches a different + source line, then stop it and return control to GDB. This command + is abbreviated `s'. + + _Warning:_ If you use the `step' command while control is + within a function that was compiled without debugging + information, execution proceeds until control reaches a + function that does have debugging information. Likewise, it + will not step into a function which is compiled without + debugging information. To step through functions without + debugging information, use the `stepi' command, described + below. + + The `step' command only stops at the first instruction of a source + line. This prevents the multiple stops that could otherwise occur + in `switch' statements, `for' loops, etc. `step' continues to + stop if a function that has debugging information is called within + the line. In other words, `step' _steps inside_ any functions + called within the line. + + Also, the `step' command only enters a function if there is line + number information for the function. Otherwise it acts like the + `next' command. This avoids problems when using `cc -gl' on MIPS + machines. Previously, `step' entered subroutines if there was any + debugging information about the routine. + +`step COUNT' + Continue running as in `step', but do so COUNT times. If a + breakpoint is reached, or a signal not related to stepping occurs + before COUNT steps, stepping stops right away. + +`next [COUNT]' + Continue to the next source line in the current (innermost) stack + frame. This is similar to `step', but function calls that appear + within the line of code are executed without stopping. Execution + stops when control reaches a different line of code at the + original stack level that was executing when you gave the `next' + command. This command is abbreviated `n'. + + An argument COUNT is a repeat count, as for `step'. + + The `next' command only stops at the first instruction of a source + line. This prevents multiple stops that could otherwise occur in + `switch' statements, `for' loops, etc. + +`set step-mode' +`set step-mode on' + The `set step-mode on' command causes the `step' command to stop + at the first instruction of a function which contains no debug line + information rather than stepping over it. + + This is useful in cases where you may be interested in inspecting + the machine instructions of a function which has no symbolic info + and do not want GDB to automatically skip over this function. + +`set step-mode off' + Causes the `step' command to step over any functions which + contains no debug information. This is the default. + +`finish' + Continue running until just after function in the selected stack + frame returns. Print the returned value (if any). + + Contrast this with the `return' command (*note Returning from a + function: Returning.). + +`until' +`u' + Continue running until a source line past the current line, in the + current stack frame, is reached. This command is used to avoid + single stepping through a loop more than once. It is like the + `next' command, except that when `until' encounters a jump, it + automatically continues execution until the program counter is + greater than the address of the jump. + + This means that when you reach the end of a loop after single + stepping though it, `until' makes your program continue execution + until it exits the loop. In contrast, a `next' command at the end + of a loop simply steps back to the beginning of the loop, which + forces you to step through the next iteration. + + `until' always stops your program if it attempts to exit the + current stack frame. + + `until' may produce somewhat counterintuitive results if the order + of machine code does not match the order of the source lines. For + example, in the following excerpt from a debugging session, the `f' + (`frame') command shows that execution is stopped at line `206'; + yet when we use `until', we get to line `195': + + (gdb) f + #0 main (argc=4, argv=0xf7fffae8) at m4.c:206 + 206 expand_input(); + (gdb) until + 195 for ( ; argc > 0; NEXTARG) { + + This happened because, for execution efficiency, the compiler had + generated code for the loop closure test at the end, rather than + the start, of the loop--even though the test in a C `for'-loop is + written before the body of the loop. The `until' command appeared + to step back to the beginning of the loop when it advanced to this + expression; however, it has not really gone to an earlier + statement--not in terms of the actual machine code. + + `until' with no argument works by means of single instruction + stepping, and hence is slower than `until' with an argument. + +`until LOCATION' +`u LOCATION' + Continue running your program until either the specified location + is reached, or the current stack frame returns. LOCATION is any of + the forms of argument acceptable to `break' (*note Setting + breakpoints: Set Breaks.). This form of the command uses + breakpoints, and hence is quicker than `until' without an + argument. The specified location is actually reached only if it + is in the current frame. This implies that `until' can be used to + skip over recursive function invocations. For instance in the + code below, if the current location is line `96', issuing `until + 99' will execute the program up to line `99' in the same + invocation of factorial, i.e. after the inner invocations have + returned. + + 94 int factorial (int value) + 95 { + 96 if (value > 1) { + 97 value *= factorial (value - 1); + 98 } + 99 return (value); + 100 } + +`advance LOCATION' + Continue running the program up to the given location. An + argument is required, anything of the same form as arguments for + the `break' command. Execution will also stop upon exit from the + current stack frame. This command is similar to `until', but + `advance' will not skip over recursive function calls, and the + target location doesn't have to be in the same frame as the + current one. + +`stepi' +`stepi ARG' +`si' + Execute one machine instruction, then stop and return to the + debugger. + + It is often useful to do `display/i $pc' when stepping by machine + instructions. This makes GDB automatically display the next + instruction to be executed, each time your program stops. *Note + Automatic display: Auto Display. + + An argument is a repeat count, as in `step'. + +`nexti' +`nexti ARG' +`ni' + Execute one machine instruction, but if it is a function call, + proceed until the function returns. + + An argument is a repeat count, as in `next'. + + +File: gdb.info, Node: Signals, Next: Thread Stops, Prev: Continuing and Stepping, Up: Stopping + +Signals +======= + +A signal is an asynchronous event that can happen in a program. The +operating system defines the possible kinds of signals, and gives each +kind a name and a number. For example, in Unix `SIGINT' is the signal +a program gets when you type an interrupt character (often `C-c'); +`SIGSEGV' is the signal a program gets from referencing a place in +memory far away from all the areas in use; `SIGALRM' occurs when the +alarm clock timer goes off (which happens only if your program has +requested an alarm). + + Some signals, including `SIGALRM', are a normal part of the +functioning of your program. Others, such as `SIGSEGV', indicate +errors; these signals are "fatal" (they kill your program immediately) +if the program has not specified in advance some other way to handle +the signal. `SIGINT' does not indicate an error in your program, but +it is normally fatal so it can carry out the purpose of the interrupt: +to kill the program. + + GDB has the ability to detect any occurrence of a signal in your +program. You can tell GDB in advance what to do for each kind of +signal. + + Normally, GDB is set up to let the non-erroneous signals like +`SIGALRM' be silently passed to your program (so as not to interfere +with their role in the program's functioning) but to stop your program +immediately whenever an error signal happens. You can change these +settings with the `handle' command. + +`info signals' +`info handle' + Print a table of all the kinds of signals and how GDB has been + told to handle each one. You can use this to see the signal + numbers of all the defined types of signals. + + `info handle' is an alias for `info signals'. + +`handle SIGNAL KEYWORDS...' + Change the way GDB handles signal SIGNAL. SIGNAL can be the + number of a signal or its name (with or without the `SIG' at the + beginning); a list of signal numbers of the form `LOW-HIGH'; or + the word `all', meaning all the known signals. The KEYWORDS say + what change to make. + + The keywords allowed by the `handle' command can be abbreviated. +Their full names are: + +`nostop' + GDB should not stop your program when this signal happens. It may + still print a message telling you that the signal has come in. + +`stop' + GDB should stop your program when this signal happens. This + implies the `print' keyword as well. + +`print' + GDB should print a message when this signal happens. + +`noprint' + GDB should not mention the occurrence of the signal at all. This + implies the `nostop' keyword as well. + +`pass' +`noignore' + GDB should allow your program to see this signal; your program can + handle the signal, or else it may terminate if the signal is fatal + and not handled. `pass' and `noignore' are synonyms. + +`nopass' +`ignore' + GDB should not allow your program to see this signal. `nopass' + and `ignore' are synonyms. + + When a signal stops your program, the signal is not visible to the +program until you continue. Your program sees the signal then, if +`pass' is in effect for the signal in question _at that time_. In +other words, after GDB reports a signal, you can use the `handle' +command with `pass' or `nopass' to control whether your program sees +that signal when you continue. + + The default is set to `nostop', `noprint', `pass' for non-erroneous +signals such as `SIGALRM', `SIGWINCH' and `SIGCHLD', and to `stop', +`print', `pass' for the erroneous signals. + + You can also use the `signal' command to prevent your program from +seeing a signal, or cause it to see a signal it normally would not see, +or to give it any signal at any time. For example, if your program +stopped due to some sort of memory reference error, you might store +correct values into the erroneous variables and continue, hoping to see +more execution; but your program would probably terminate immediately as +a result of the fatal signal once it saw the signal. To prevent this, +you can continue with `signal 0'. *Note Giving your program a signal: +Signaling. + + +File: gdb.info, Node: Thread Stops, Prev: Signals, Up: Stopping + +Stopping and starting multi-thread programs +=========================================== + +When your program has multiple threads (*note Debugging programs with +multiple threads: Threads.), you can choose whether to set breakpoints +on all threads, or on a particular thread. + +`break LINESPEC thread THREADNO' +`break LINESPEC thread THREADNO if ...' + LINESPEC specifies source lines; there are several ways of writing + them, but the effect is always to specify some source line. + + Use the qualifier `thread THREADNO' with a breakpoint command to + specify that you only want GDB to stop the program when a + particular thread reaches this breakpoint. THREADNO is one of the + numeric thread identifiers assigned by GDB, shown in the first + column of the `info threads' display. + + If you do not specify `thread THREADNO' when you set a breakpoint, + the breakpoint applies to _all_ threads of your program. + + You can use the `thread' qualifier on conditional breakpoints as + well; in this case, place `thread THREADNO' before the breakpoint + condition, like this: + + (gdb) break frik.c:13 thread 28 if bartab > lim + + + Whenever your program stops under GDB for any reason, _all_ threads +of execution stop, not just the current thread. This allows you to +examine the overall state of the program, including switching between +threads, without worrying that things may change underfoot. + + There is an unfortunate side effect. If one thread stops for a +breakpoint, or for some other reason, and another thread is blocked in a +system call, then the system call may return prematurely. This is a +consequence of the interaction between multiple threads and the signals +that GDB uses to implement breakpoints and other events that stop +execution. + + To handle this problem, your program should check the return value of +each system call and react appropriately. This is good programming +style anyways. + + For example, do not write code like this: + + sleep (10); + + The call to `sleep' will return early if a different thread stops at +a breakpoint or for some other reason. + + Instead, write this: + + int unslept = 10; + while (unslept > 0) + unslept = sleep (unslept); + + A system call is allowed to return early, so the system is still +conforming to its specification. But GDB does cause your +multi-threaded program to behave differently than it would without GDB. + + Also, GDB uses internal breakpoints in the thread library to monitor +certain events such as thread creation and thread destruction. When +such an event happens, a system call in another thread may return +prematurely, even though your program does not appear to stop. + + Conversely, whenever you restart the program, _all_ threads start +executing. _This is true even when single-stepping_ with commands like +`step' or `next'. + + In particular, GDB cannot single-step all threads in lockstep. +Since thread scheduling is up to your debugging target's operating +system (not controlled by GDB), other threads may execute more than one +statement while the current thread completes a single step. Moreover, +in general other threads stop in the middle of a statement, rather than +at a clean statement boundary, when the program stops. + + You might even find your program stopped in another thread after +continuing or even single-stepping. This happens whenever some other +thread runs into a breakpoint, a signal, or an exception before the +first thread completes whatever you requested. + + On some OSes, you can lock the OS scheduler and thus allow only a +single thread to run. + +`set scheduler-locking MODE' + Set the scheduler locking mode. If it is `off', then there is no + locking and any thread may run at any time. If `on', then only the + current thread may run when the inferior is resumed. The `step' + mode optimizes for single-stepping. It stops other threads from + "seizing the prompt" by preempting the current thread while you are + stepping. Other threads will only rarely (or never) get a chance + to run when you step. They are more likely to run when you `next' + over a function call, and they are completely free to run when you + use commands like `continue', `until', or `finish'. However, + unless another thread hits a breakpoint during its timeslice, they + will never steal the GDB prompt away from the thread that you are + debugging. + +`show scheduler-locking' + Display the current scheduler locking mode. + + +File: gdb.info, Node: Stack, Next: Source, Prev: Stopping, Up: Top + +Examining the Stack +******************* + +When your program has stopped, the first thing you need to know is +where it stopped and how it got there. + + Each time your program performs a function call, information about +the call is generated. That information includes the location of the +call in your program, the arguments of the call, and the local +variables of the function being called. The information is saved in a +block of data called a "stack frame". The stack frames are allocated +in a region of memory called the "call stack". + + When your program stops, the GDB commands for examining the stack +allow you to see all of this information. + + One of the stack frames is "selected" by GDB and many GDB commands +refer implicitly to the selected frame. In particular, whenever you +ask GDB for the value of a variable in your program, the value is found +in the selected frame. There are special GDB commands to select +whichever frame you are interested in. *Note Selecting a frame: +Selection. + + When your program stops, GDB automatically selects the currently +executing frame and describes it briefly, similar to the `frame' +command (*note Information about a frame: Frame Info.). + +* Menu: + +* Frames:: Stack frames +* Backtrace:: Backtraces +* Selection:: Selecting a frame +* Frame Info:: Information on a frame + + +File: gdb.info, Node: Frames, Next: Backtrace, Up: Stack + +Stack frames +============ + +The call stack is divided up into contiguous pieces called "stack +frames", or "frames" for short; each frame is the data associated with +one call to one function. The frame contains the arguments given to +the function, the function's local variables, and the address at which +the function is executing. + + When your program is started, the stack has only one frame, that of +the function `main'. This is called the "initial" frame or the +"outermost" frame. Each time a function is called, a new frame is +made. Each time a function returns, the frame for that function +invocation is eliminated. If a function is recursive, there can be +many frames for the same function. The frame for the function in which +execution is actually occurring is called the "innermost" frame. This +is the most recently created of all the stack frames that still exist. + + Inside your program, stack frames are identified by their addresses. +A stack frame consists of many bytes, each of which has its own +address; each kind of computer has a convention for choosing one byte +whose address serves as the address of the frame. Usually this address +is kept in a register called the "frame pointer register" while +execution is going on in that frame. + + GDB assigns numbers to all existing stack frames, starting with zero +for the innermost frame, one for the frame that called it, and so on +upward. These numbers do not really exist in your program; they are +assigned by GDB to give you a way of designating stack frames in GDB +commands. + + Some compilers provide a way to compile functions so that they +operate without stack frames. (For example, the gcc option + `-fomit-frame-pointer' + generates functions without a frame.) This is occasionally done +with heavily used library functions to save the frame setup time. GDB +has limited facilities for dealing with these function invocations. If +the innermost function invocation has no stack frame, GDB nevertheless +regards it as though it had a separate frame, which is numbered zero as +usual, allowing correct tracing of the function call chain. However, +GDB has no provision for frameless functions elsewhere in the stack. + +`frame ARGS' + The `frame' command allows you to move from one stack frame to + another, and to print the stack frame you select. ARGS may be + either the address of the frame or the stack frame number. + Without an argument, `frame' prints the current stack frame. + +`select-frame' + The `select-frame' command allows you to move from one stack frame + to another without printing the frame. This is the silent version + of `frame'. + + +File: gdb.info, Node: Backtrace, Next: Selection, Prev: Frames, Up: Stack + +Backtraces +========== + +A backtrace is a summary of how your program got where it is. It shows +one line per frame, for many frames, starting with the currently +executing frame (frame zero), followed by its caller (frame one), and +on up the stack. + +`backtrace' +`bt' + Print a backtrace of the entire stack: one line per frame for all + frames in the stack. + + You can stop the backtrace at any time by typing the system + interrupt character, normally `C-c'. + +`backtrace N' +`bt N' + Similar, but print only the innermost N frames. + +`backtrace -N' +`bt -N' + Similar, but print only the outermost N frames. + + The names `where' and `info stack' (abbreviated `info s') are +additional aliases for `backtrace'. + + Each line in the backtrace shows the frame number and the function +name. The program counter value is also shown--unless you use `set +print address off'. The backtrace also shows the source file name and +line number, as well as the arguments to the function. The program +counter value is omitted if it is at the beginning of the code for that +line number. + + Here is an example of a backtrace. It was made with the command `bt +3', so it shows the innermost three frames. + + #0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8) + at builtin.c:993 + #1 0x6e38 in expand_macro (sym=0x2b600) at macro.c:242 + #2 0x6840 in expand_token (obs=0x0, t=177664, td=0xf7fffb08) + at macro.c:71 + (More stack frames follow...) + +The display for frame zero does not begin with a program counter value, +indicating that your program has stopped at the beginning of the code +for line `993' of `builtin.c'. + + Most programs have a standard user entry point--a place where system +libraries and startup code transition into user code. For C this is +`main'. When GDB finds the entry function in a backtrace it will +terminate the backtrace, to avoid tracing into highly system-specific +(and generally uninteresting) code. + + If you need to examine the startup code, or limit the number of +levels in a backtrace, you can change this behavior: + +`set backtrace past-main' +`set backtrace past-main on' + Backtraces will continue past the user entry point. + +`set backtrace past-main off' + Backtraces will stop when they encounter the user entry point. + This is the default. + +`show backtrace past-main' + Display the current user entry point backtrace policy. + +`set backtrace limit N' +`set backtrace limit 0' + Limit the backtrace to N levels. A value of zero means unlimited. + +`show backtrace limit' + Display the current limit on backtrace levels. + + +File: gdb.info, Node: Selection, Next: Frame Info, Prev: Backtrace, Up: Stack + +Selecting a frame +================= + +Most commands for examining the stack and other data in your program +work on whichever stack frame is selected at the moment. Here are the +commands for selecting a stack frame; all of them finish by printing a +brief description of the stack frame just selected. + +`frame N' +`f N' + Select frame number N. Recall that frame zero is the innermost + (currently executing) frame, frame one is the frame that called the + innermost one, and so on. The highest-numbered frame is the one + for `main'. + +`frame ADDR' +`f ADDR' + Select the frame at address ADDR. This is useful mainly if the + chaining of stack frames has been damaged by a bug, making it + impossible for GDB to assign numbers properly to all frames. In + addition, this can be useful when your program has multiple stacks + and switches between them. + + On the SPARC architecture, `frame' needs two addresses to select + an arbitrary frame: a frame pointer and a stack pointer. + + On the MIPS and Alpha architecture, it needs two addresses: a stack + pointer and a program counter. + + On the 29k architecture, it needs three addresses: a register stack + pointer, a program counter, and a memory stack pointer. + +`up N' + Move N frames up the stack. For positive numbers N, this advances + toward the outermost frame, to higher frame numbers, to frames + that have existed longer. N defaults to one. + +`down N' + Move N frames down the stack. For positive numbers N, this + advances toward the innermost frame, to lower frame numbers, to + frames that were created more recently. N defaults to one. You + may abbreviate `down' as `do'. + + All of these commands end by printing two lines of output describing +the frame. The first line shows the frame number, the function name, +the arguments, and the source file and line number of execution in that +frame. The second line shows the text of that source line. + + For example: + + (gdb) up + #1 0x22f0 in main (argc=1, argv=0xf7fffbf4, env=0xf7fffbfc) + at env.c:10 + 10 read_input_file (argv[i]); + + After such a printout, the `list' command with no arguments prints +ten lines centered on the point of execution in the frame. You can +also edit the program at the point of execution with your favorite +editing program by typing `edit'. *Note Printing source lines: List, +for details. + +`up-silently N' +`down-silently N' + These two commands are variants of `up' and `down', respectively; + they differ in that they do their work silently, without causing + display of the new frame. They are intended primarily for use in + GDB command scripts, where the output might be unnecessary and + distracting. + + +File: gdb.info, Node: Frame Info, Prev: Selection, Up: Stack + +Information about a frame +========================= + +There are several other commands to print information about the selected +stack frame. + +`frame' +`f' + When used without any argument, this command does not change which + frame is selected, but prints a brief description of the currently + selected stack frame. It can be abbreviated `f'. With an + argument, this command is used to select a stack frame. *Note + Selecting a frame: Selection. + +`info frame' +`info f' + This command prints a verbose description of the selected stack + frame, including: + + * the address of the frame + + * the address of the next frame down (called by this frame) + + * the address of the next frame up (caller of this frame) + + * the language in which the source code corresponding to this + frame is written + + * the address of the frame's arguments + + * the address of the frame's local variables + + * the program counter saved in it (the address of execution in + the caller frame) + + * which registers were saved in the frame + + The verbose description is useful when something has gone wrong + that has made the stack format fail to fit the usual conventions. + +`info frame ADDR' +`info f ADDR' + Print a verbose description of the frame at address ADDR, without + selecting that frame. The selected frame remains unchanged by this + command. This requires the same kind of address (more than one + for some architectures) that you specify in the `frame' command. + *Note Selecting a frame: Selection. + +`info args' + Print the arguments of the selected frame, each on a separate line. + +`info locals' + Print the local variables of the selected frame, each on a separate + line. These are all variables (declared either static or + automatic) accessible at the point of execution of the selected + frame. + +`info catch' + Print a list of all the exception handlers that are active in the + current stack frame at the current point of execution. To see + other exception handlers, visit the associated frame (using the + `up', `down', or `frame' commands); then type `info catch'. *Note + Setting catchpoints: Set Catchpoints. + + + +File: gdb.info, Node: Source, Next: Data, Prev: Stack, Up: Top + +Examining Source Files +********************** + +GDB can print parts of your program's source, since the debugging +information recorded in the program tells GDB what source files were +used to build it. When your program stops, GDB spontaneously prints +the line where it stopped. Likewise, when you select a stack frame +(*note Selecting a frame: Selection.), GDB prints the line where +execution in that frame has stopped. You can print other portions of +source files by explicit command. + + If you use GDB through its GNU Emacs interface, you may prefer to +use Emacs facilities to view source; see *Note Using GDB under GNU +Emacs: Emacs. + +* Menu: + +* List:: Printing source lines +* Edit:: Editing source files +* Search:: Searching source files +* Source Path:: Specifying source directories +* Machine Code:: Source and machine code + + +File: gdb.info, Node: List, Next: Edit, Up: Source + +Printing source lines +===================== + +To print lines from a source file, use the `list' command (abbreviated +`l'). By default, ten lines are printed. There are several ways to +specify what part of the file you want to print. + + Here are the forms of the `list' command most commonly used: + +`list LINENUM' + Print lines centered around line number LINENUM in the current + source file. + +`list FUNCTION' + Print lines centered around the beginning of function FUNCTION. + +`list' + Print more lines. If the last lines printed were printed with a + `list' command, this prints lines following the last lines + printed; however, if the last line printed was a solitary line + printed as part of displaying a stack frame (*note Examining the + Stack: Stack.), this prints lines centered around that line. + +`list -' + Print lines just before the lines last printed. + + By default, GDB prints ten source lines with any of these forms of +the `list' command. You can change this using `set listsize': + +`set listsize COUNT' + Make the `list' command display COUNT source lines (unless the + `list' argument explicitly specifies some other number). + +`show listsize' + Display the number of lines that `list' prints. + + Repeating a `list' command with discards the argument, so it +is equivalent to typing just `list'. This is more useful than listing +the same lines again. An exception is made for an argument of `-'; +that argument is preserved in repetition so that each repetition moves +up in the source file. + + In general, the `list' command expects you to supply zero, one or two +"linespecs". Linespecs specify source lines; there are several ways of +writing them, but the effect is always to specify some source line. +Here is a complete description of the possible arguments for `list': + +`list LINESPEC' + Print lines centered around the line specified by LINESPEC. + +`list FIRST,LAST' + Print lines from FIRST to LAST. Both arguments are linespecs. + +`list ,LAST' + Print lines ending with LAST. + +`list FIRST,' + Print lines starting with FIRST. + +`list +' + Print lines just after the lines last printed. + +`list -' + Print lines just before the lines last printed. + +`list' + As described in the preceding table. + + Here are the ways of specifying a single source line--all the kinds +of linespec. + +`NUMBER' + Specifies line NUMBER of the current source file. When a `list' + command has two linespecs, this refers to the same source file as + the first linespec. + +`+OFFSET' + Specifies the line OFFSET lines after the last line printed. When + used as the second linespec in a `list' command that has two, this + specifies the line OFFSET lines down from the first linespec. + +`-OFFSET' + Specifies the line OFFSET lines before the last line printed. + +`FILENAME:NUMBER' + Specifies line NUMBER in the source file FILENAME. + +`FUNCTION' + Specifies the line that begins the body of the function FUNCTION. + For example: in C, this is the line with the open brace. + +`FILENAME:FUNCTION' + Specifies the line of the open-brace that begins the body of the + function FUNCTION in the file FILENAME. You only need the file + name with a function name to avoid ambiguity when there are + identically named functions in different source files. + +`*ADDRESS' + Specifies the line containing the program address ADDRESS. + ADDRESS may be any expression. + + +File: gdb.info, Node: Edit, Next: Search, Prev: List, Up: Source + +Editing source files +==================== + +To edit the lines in a source file, use the `edit' command. The +editing program of your choice is invoked with the current line set to +the active line in the program. Alternatively, there are several ways +to specify what part of the file you want to print if you want to see +other parts of the program. + + Here are the forms of the `edit' command most commonly used: + +`edit' + Edit the current source file at the active line number in the + program. + +`edit NUMBER' + Edit the current source file with NUMBER as the active line number. + +`edit FUNCTION' + Edit the file containing FUNCTION at the beginning of its + definition. + +`edit FILENAME:NUMBER' + Specifies line NUMBER in the source file FILENAME. + +`edit FILENAME:FUNCTION' + Specifies the line that begins the body of the function FUNCTION + in the file FILENAME. You only need the file name with a function + name to avoid ambiguity when there are identically named functions + in different source files. + +`edit *ADDRESS' + Specifies the line containing the program address ADDRESS. + ADDRESS may be any expression. + +Choosing your editor +-------------------- + +You can customize GDB to use any editor you want (1). By default, it +is /bin/ex, but you can change this by setting the environment variable +`EDITOR' before using GDB. For example, to configure GDB to use the +`vi' editor, you could use these commands with the `sh' shell: + EDITOR=/usr/bin/vi + export EDITOR + gdb ... + or in the `csh' shell, + setenv EDITOR /usr/bin/vi + gdb ... + + ---------- Footnotes ---------- + + (1) The only restriction is that your editor (say `ex'), recognizes +the following command-line syntax: + ex +NUMBER file + The optional numeric value +NUMBER designates the active line in the +file. + + +File: gdb.info, Node: Search, Next: Source Path, Prev: Edit, Up: Source + +Searching source files +====================== + +There are two commands for searching through the current source file +for a regular expression. + +`forward-search REGEXP' +`search REGEXP' + The command `forward-search REGEXP' checks each line, starting + with the one following the last line listed, for a match for + REGEXP. It lists the line that is found. You can use the synonym + `search REGEXP' or abbreviate the command name as `fo'. + +`reverse-search REGEXP' + The command `reverse-search REGEXP' checks each line, starting + with the one before the last line listed and going backward, for a + match for REGEXP. It lists the line that is found. You can + abbreviate this command as `rev'. + + +File: gdb.info, Node: Source Path, Next: Machine Code, Prev: Search, Up: Source + +Specifying source directories +============================= + +Executable programs sometimes do not record the directories of the +source files from which they were compiled, just the names. Even when +they do, the directories could be moved between the compilation and +your debugging session. GDB has a list of directories to search for +source files; this is called the "source path". Each time GDB wants a +source file, it tries all the directories in the list, in the order +they are present in the list, until it finds a file with the desired +name. Note that the executable search path is _not_ used for this +purpose. Neither is the current working directory, unless it happens +to be in the source path. + + If GDB cannot find a source file in the source path, and the object +program records a directory, GDB tries that directory too. If the +source path is empty, and there is no record of the compilation +directory, GDB looks in the current directory as a last resort. + + Whenever you reset or rearrange the source path, GDB clears out any +information it has cached about where source files are found and where +each line is in the file. + + When you start GDB, its source path includes only `cdir' and `cwd', +in that order. To add other directories, use the `directory' command. + +`directory DIRNAME ...' + +`dir DIRNAME ...' + Add directory DIRNAME to the front of the source path. Several + directory names may be given to this command, separated by `:' + (`;' on MS-DOS and MS-Windows, where `:' usually appears as part + of absolute file names) or whitespace. You may specify a + directory that is already in the source path; this moves it + forward, so GDB searches it sooner. + + You can use the string `$cdir' to refer to the compilation + directory (if one is recorded), and `$cwd' to refer to the current + working directory. `$cwd' is not the same as `.'--the former + tracks the current working directory as it changes during your GDB + session, while the latter is immediately expanded to the current + directory at the time you add an entry to the source path. + +`directory' + Reset the source path to empty again. This requires confirmation. + +`show directories' + Print the source path: show which directories it contains. + + If your source path is cluttered with directories that are no longer +of interest, GDB may sometimes cause confusion by finding the wrong +versions of source. You can correct the situation as follows: + + 1. Use `directory' with no argument to reset the source path to empty. + + 2. Use `directory' with suitable arguments to reinstall the + directories you want in the source path. You can add all the + directories in one command. + + +File: gdb.info, Node: Machine Code, Prev: Source Path, Up: Source + +Source and machine code +======================= + +You can use the command `info line' to map source lines to program +addresses (and vice versa), and the command `disassemble' to display a +range of addresses as machine instructions. When run under GNU Emacs +mode, the `info line' command causes the arrow to point to the line +specified. Also, `info line' prints addresses in symbolic form as well +as hex. + +`info line LINESPEC' + Print the starting and ending addresses of the compiled code for + source line LINESPEC. You can specify source lines in any of the + ways understood by the `list' command (*note Printing source + lines: List.). + + For example, we can use `info line' to discover the location of the +object code for the first line of function `m4_changequote': + + (gdb) info line m4_changequote + Line 895 of "builtin.c" starts at pc 0x634c and ends at 0x6350. + +We can also inquire (using `*ADDR' as the form for LINESPEC) what +source line covers a particular address: + (gdb) info line *0x63ff + Line 926 of "builtin.c" starts at pc 0x63e4 and ends at 0x6404. + + After `info line', the default address for the `x' command is +changed to the starting address of the line, so that `x/i' is +sufficient to begin examining the machine code (*note Examining memory: +Memory.). Also, this address is saved as the value of the convenience +variable `$_' (*note Convenience variables: Convenience Vars.). + +`disassemble' + This specialized command dumps a range of memory as machine + instructions. The default memory range is the function + surrounding the program counter of the selected frame. A single + argument to this command is a program counter value; GDB dumps the + function surrounding this value. Two arguments specify a range of + addresses (first inclusive, second exclusive) to dump. + + The following example shows the disassembly of a range of addresses +of HP PA-RISC 2.0 code: + + (gdb) disas 0x32c4 0x32e4 + Dump of assembler code from 0x32c4 to 0x32e4: + 0x32c4 : addil 0,dp + 0x32c8 : ldw 0x22c(sr0,r1),r26 + 0x32cc : ldil 0x3000,r31 + 0x32d0 : ble 0x3f8(sr4,r31) + 0x32d4 : ldo 0(r31),rp + 0x32d8 : addil -0x800,dp + 0x32dc : ldo 0x588(r1),r26 + 0x32e0 : ldil 0x3000,r31 + End of assembler dump. + + Some architectures have more than one commonly-used set of +instruction mnemonics or other syntax. + +`set disassembly-flavor INSTRUCTION-SET' + Select the instruction set to use when disassembling the program + via the `disassemble' or `x/i' commands. + + Currently this command is only defined for the Intel x86 family. + You can set INSTRUCTION-SET to either `intel' or `att'. The + default is `att', the AT&T flavor used by default by Unix + assemblers for x86-based targets. + + +File: gdb.info, Node: Data, Next: Macros, Prev: Source, Up: Top + +Examining Data +************** + +The usual way to examine data in your program is with the `print' +command (abbreviated `p'), or its synonym `inspect'. It evaluates and +prints the value of an expression of the language your program is +written in (*note Using GDB with Different Languages: Languages.). + +`print EXPR' +`print /F EXPR' + EXPR is an expression (in the source language). By default the + value of EXPR is printed in a format appropriate to its data type; + you can choose a different format by specifying `/F', where F is a + letter specifying the format; see *Note Output formats: Output + Formats. + +`print' +`print /F' + If you omit EXPR, GDB displays the last value again (from the + "value history"; *note Value history: Value History.). This + allows you to conveniently inspect the same value in an + alternative format. + + A more low-level way of examining data is with the `x' command. It +examines data in memory at a specified address and prints it in a +specified format. *Note Examining memory: Memory. + + If you are interested in information about types, or about how the +fields of a struct or a class are declared, use the `ptype EXP' command +rather than `print'. *Note Examining the Symbol Table: Symbols. + +* Menu: + +* Expressions:: Expressions +* Variables:: Program variables +* Arrays:: Artificial arrays +* Output Formats:: Output formats +* Memory:: Examining memory +* Auto Display:: Automatic display +* Print Settings:: Print settings +* Value History:: Value history +* Convenience Vars:: Convenience variables +* Registers:: Registers +* Floating Point Hardware:: Floating point hardware +* Vector Unit:: Vector Unit +* Auxiliary Vector:: Auxiliary data provided by operating system +* Memory Region Attributes:: Memory region attributes +* Dump/Restore Files:: Copy between memory and a file +* Character Sets:: Debugging programs that use a different + character set than GDB does + + +File: gdb.info, Node: Expressions, Next: Variables, Up: Data + +Expressions +=========== + +`print' and many other GDB commands accept an expression and compute +its value. Any kind of constant, variable or operator defined by the +programming language you are using is valid in an expression in GDB. +This includes conditional expressions, function calls, casts, and +string constants. It also includes preprocessor macros, if you +compiled your program to include this information; see *Note +Compilation::. + + GDB supports array constants in expressions input by the user. The +syntax is {ELEMENT, ELEMENT...}. For example, you can use the command +`print {1, 2, 3}' to build up an array in memory that is `malloc'ed in +the target program. + + Because C is so widespread, most of the expressions shown in +examples in this manual are in C. *Note Using GDB with Different +Languages: Languages, for information on how to use expressions in other +languages. + + In this section, we discuss operators that you can use in GDB +expressions regardless of your programming language. + + Casts are supported in all languages, not just in C, because it is so +useful to cast a number into a pointer in order to examine a structure +at that address in memory. + + GDB supports these operators, in addition to those common to +programming languages: + +`@' + `@' is a binary operator for treating parts of memory as arrays. + *Note Artificial arrays: Arrays, for more information. + +`::' + `::' allows you to specify a variable in terms of the file or + function where it is defined. *Note Program variables: Variables. + +`{TYPE} ADDR' + Refers to an object of type TYPE stored at address ADDR in memory. + ADDR may be any expression whose value is an integer or pointer + (but parentheses are required around binary operators, just as in + a cast). This construct is allowed regardless of what kind of + data is normally supposed to reside at ADDR. + + +File: gdb.info, Node: Variables, Next: Arrays, Prev: Expressions, Up: Data + +Program variables +================= + +The most common kind of expression to use is the name of a variable in +your program. + + Variables in expressions are understood in the selected stack frame +(*note Selecting a frame: Selection.); they must be either: + + * global (or file-static) + +or + + * visible according to the scope rules of the programming language + from the point of execution in that frame + +This means that in the function + + foo (a) + int a; + { + bar (a); + { + int b = test (); + bar (b); + } + } + +you can examine and use the variable `a' whenever your program is +executing within the function `foo', but you can only use or examine +the variable `b' while your program is executing inside the block where +`b' is declared. + + There is an exception: you can refer to a variable or function whose +scope is a single source file even if the current execution point is not +in this file. But it is possible to have more than one such variable or +function with the same name (in different source files). If that +happens, referring to that name has unpredictable effects. If you wish, +you can specify a static variable in a particular function or file, +using the colon-colon notation: + + FILE::VARIABLE + FUNCTION::VARIABLE + +Here FILE or FUNCTION is the name of the context for the static +VARIABLE. In the case of file names, you can use quotes to make sure +GDB parses the file name as a single word--for example, to print a +global value of `x' defined in `f2.c': + + (gdb) p 'f2.c'::x + + This use of `::' is very rarely in conflict with the very similar +use of the same notation in C++. GDB also supports use of the C++ +scope resolution operator in GDB expressions. + + _Warning:_ Occasionally, a local variable may appear to have the + wrong value at certain points in a function--just after entry to a + new scope, and just before exit. + You may see this problem when you are stepping by machine +instructions. This is because, on most machines, it takes more than +one instruction to set up a stack frame (including local variable +definitions); if you are stepping by machine instructions, variables +may appear to have the wrong values until the stack frame is completely +built. On exit, it usually also takes more than one machine +instruction to destroy a stack frame; after you begin stepping through +that group of instructions, local variable definitions may be gone. + + This may also happen when the compiler does significant +optimizations. To be sure of always seeing accurate values, turn off +all optimization when compiling. + + Another possible effect of compiler optimizations is to optimize +unused variables out of existence, or assign variables to registers (as +opposed to memory addresses). Depending on the support for such cases +offered by the debug info format used by the compiler, GDB might not be +able to display values for such local variables. If that happens, GDB +will print a message like this: + + No symbol "foo" in current context. + + To solve such problems, either recompile without optimizations, or +use a different debug info format, if the compiler supports several such +formats. For example, GCC, the GNU C/C++ compiler usually supports the +`-gstabs+' option. `-gstabs+' produces debug info in a format that is +superior to formats such as COFF. You may be able to use DWARF 2 +(`-gdwarf-2'), which is also an effective form for debug info. *Note +Options for Debugging Your Program or GNU CC: (gcc.info)Debugging +Options. + + +File: gdb.info, Node: Arrays, Next: Output Formats, Prev: Variables, Up: Data + +Artificial arrays +================= + +It is often useful to print out several successive objects of the same +type in memory; a section of an array, or an array of dynamically +determined size for which only a pointer exists in the program. + + You can do this by referring to a contiguous span of memory as an +"artificial array", using the binary operator `@'. The left operand of +`@' should be the first element of the desired array and be an +individual object. The right operand should be the desired length of +the array. The result is an array value whose elements are all of the +type of the left argument. The first element is actually the left +argument; the second element comes from bytes of memory immediately +following those that hold the first element, and so on. Here is an +example. If a program says + + int *array = (int *) malloc (len * sizeof (int)); + +you can print the contents of `array' with + + p *array@len + + The left operand of `@' must reside in memory. Array values made +with `@' in this way behave just like other arrays in terms of +subscripting, and are coerced to pointers when used in expressions. +Artificial arrays most often appear in expressions via the value history +(*note Value history: Value History.), after printing one out. + + Another way to create an artificial array is to use a cast. This +re-interprets a value as if it were an array. The value need not be in +memory: + (gdb) p/x (short[2])0x12345678 + $1 = {0x1234, 0x5678} + + As a convenience, if you leave the array length out (as in +`(TYPE[])VALUE') GDB calculates the size to fill the value (as +`sizeof(VALUE)/sizeof(TYPE)': + (gdb) p/x (short[])0x12345678 + $2 = {0x1234, 0x5678} + + Sometimes the artificial array mechanism is not quite enough; in +moderately complex data structures, the elements of interest may not +actually be adjacent--for example, if you are interested in the values +of pointers in an array. One useful work-around in this situation is +to use a convenience variable (*note Convenience variables: Convenience +Vars.) as a counter in an expression that prints the first interesting +value, and then repeat that expression via . For instance, +suppose you have an array `dtab' of pointers to structures, and you are +interested in the values of a field `fv' in each structure. Here is an +example of what you might type: + + set $i = 0 + p dtab[$i++]->fv + + + ... + + +File: gdb.info, Node: Output Formats, Next: Memory, Prev: Arrays, Up: Data + +Output formats +============== + +By default, GDB prints a value according to its data type. Sometimes +this is not what you want. For example, you might want to print a +number in hex, or a pointer in decimal. Or you might want to view data +in memory at a certain address as a character string or as an +instruction. To do these things, specify an "output format" when you +print a value. + + The simplest use of output formats is to say how to print a value +already computed. This is done by starting the arguments of the +`print' command with a slash and a format letter. The format letters +supported are: + +`x' + Regard the bits of the value as an integer, and print the integer + in hexadecimal. + +`d' + Print as integer in signed decimal. + +`u' + Print as integer in unsigned decimal. + +`o' + Print as integer in octal. + +`t' + Print as integer in binary. The letter `t' stands for "two". (1) + +`a' + Print as an address, both absolute in hexadecimal and as an offset + from the nearest preceding symbol. You can use this format used + to discover where (in what function) an unknown address is located: + + (gdb) p/a 0x54320 + $3 = 0x54320 <_initialize_vx+396> + + The command `info symbol 0x54320' yields similar results. *Note + info symbol: Symbols. + +`c' + Regard as an integer and print it as a character constant. + +`f' + Regard the bits of the value as a floating point number and print + using typical floating point syntax. + + For example, to print the program counter in hex (*note +Registers::), type + + p/x $pc + +Note that no space is required before the slash; this is because command +names in GDB cannot contain a slash. + + To reprint the last value in the value history with a different +format, you can use the `print' command with just a format and no +expression. For example, `p/x' reprints the last value in hex. + + ---------- Footnotes ---------- + + (1) `b' cannot be used because these format letters are also used +with the `x' command, where `b' stands for "byte"; see *Note Examining +memory: Memory. + + +File: gdb.info, Node: Memory, Next: Auto Display, Prev: Output Formats, Up: Data + +Examining memory +================ + +You can use the command `x' (for "examine") to examine memory in any of +several formats, independently of your program's data types. + +`x/NFU ADDR' +`x ADDR' +`x' + Use the `x' command to examine memory. + + N, F, and U are all optional parameters that specify how much memory +to display and how to format it; ADDR is an expression giving the +address where you want to start displaying memory. If you use defaults +for NFU, you need not type the slash `/'. Several commands set +convenient defaults for ADDR. + +N, the repeat count + The repeat count is a decimal integer; the default is 1. It + specifies how much memory (counting by units U) to display. + +F, the display format + The display format is one of the formats used by `print', `s' + (null-terminated string), or `i' (machine instruction). The + default is `x' (hexadecimal) initially. The default changes each + time you use either `x' or `print'. + +U, the unit size + The unit size is any of + + `b' + Bytes. + + `h' + Halfwords (two bytes). + + `w' + Words (four bytes). This is the initial default. + + `g' + Giant words (eight bytes). + + Each time you specify a unit size with `x', that size becomes the + default unit the next time you use `x'. (For the `s' and `i' + formats, the unit size is ignored and is normally not written.) + +ADDR, starting display address + ADDR is the address where you want GDB to begin displaying memory. + The expression need not have a pointer value (though it may); it + is always interpreted as an integer address of a byte of memory. + *Note Expressions: Expressions, for more information on + expressions. The default for ADDR is usually just after the last + address examined--but several other commands also set the default + address: `info breakpoints' (to the address of the last breakpoint + listed), `info line' (to the starting address of a line), and + `print' (if you use it to display a value from memory). + + For example, `x/3uh 0x54320' is a request to display three halfwords +(`h') of memory, formatted as unsigned decimal integers (`u'), starting +at address `0x54320'. `x/4xw $sp' prints the four words (`w') of +memory above the stack pointer (here, `$sp'; *note Registers: +Registers.) in hexadecimal (`x'). + + Since the letters indicating unit sizes are all distinct from the +letters specifying output formats, you do not have to remember whether +unit size or format comes first; either order works. The output +specifications `4xw' and `4wx' mean exactly the same thing. (However, +the count N must come first; `wx4' does not work.) + + Even though the unit size U is ignored for the formats `s' and `i', +you might still want to use a count N; for example, `3i' specifies that +you want to see three machine instructions, including any operands. +The command `disassemble' gives an alternative way of inspecting +machine instructions; see *Note Source and machine code: Machine Code. + + All the defaults for the arguments to `x' are designed to make it +easy to continue scanning memory with minimal specifications each time +you use `x'. For example, after you have inspected three machine +instructions with `x/3i ADDR', you can inspect the next seven with just +`x/7'. If you use to repeat the `x' command, the repeat count N +is used again; the other arguments default as for successive uses of +`x'. + + The addresses and contents printed by the `x' command are not saved +in the value history because there is often too much of them and they +would get in the way. Instead, GDB makes these values available for +subsequent use in expressions as values of the convenience variables +`$_' and `$__'. After an `x' command, the last address examined is +available for use in expressions in the convenience variable `$_'. The +contents of that address, as examined, are available in the convenience +variable `$__'. + + If the `x' command has a repeat count, the address and contents saved +are from the last memory unit printed; this is not the same as the last +address printed if several units were printed on the last line of +output. + + +File: gdb.info, Node: Auto Display, Next: Print Settings, Prev: Memory, Up: Data + +Automatic display +================= + +If you find that you want to print the value of an expression frequently +(to see how it changes), you might want to add it to the "automatic +display list" so that GDB prints its value each time your program stops. +Each expression added to the list is given a number to identify it; to +remove an expression from the list, you specify that number. The +automatic display looks like this: + + 2: foo = 38 + 3: bar[5] = (struct hack *) 0x3804 + +This display shows item numbers, expressions and their current values. +As with displays you request manually using `x' or `print', you can +specify the output format you prefer; in fact, `display' decides +whether to use `print' or `x' depending on how elaborate your format +specification is--it uses `x' if you specify a unit size, or one of the +two formats (`i' and `s') that are only supported by `x'; otherwise it +uses `print'. + +`display EXPR' + Add the expression EXPR to the list of expressions to display each + time your program stops. *Note Expressions: Expressions. + + `display' does not repeat if you press again after using it. + +`display/FMT EXPR' + For FMT specifying only a display format and not a size or count, + add the expression EXPR to the auto-display list but arrange to + display it each time in the specified format FMT. *Note Output + formats: Output Formats. + +`display/FMT ADDR' + For FMT `i' or `s', or including a unit-size or a number of units, + add the expression ADDR as a memory address to be examined each + time your program stops. Examining means in effect doing `x/FMT + ADDR'. *Note Examining memory: Memory. + + For example, `display/i $pc' can be helpful, to see the machine +instruction about to be executed each time execution stops (`$pc' is a +common name for the program counter; *note Registers: Registers.). + +`undisplay DNUMS...' +`delete display DNUMS...' + Remove item numbers DNUMS from the list of expressions to display. + + `undisplay' does not repeat if you press after using it. + (Otherwise you would just get the error `No display number ...'.) + +`disable display DNUMS...' + Disable the display of item numbers DNUMS. A disabled display + item is not printed automatically, but is not forgotten. It may be + enabled again later. + +`enable display DNUMS...' + Enable display of item numbers DNUMS. It becomes effective once + again in auto display of its expression, until you specify + otherwise. + +`display' + Display the current values of the expressions on the list, just as + is done when your program stops. + +`info display' + Print the list of expressions previously set up to display + automatically, each one with its item number, but without showing + the values. This includes disabled expressions, which are marked + as such. It also includes expressions which would not be + displayed right now because they refer to automatic variables not + currently available. + + If a display expression refers to local variables, then it does not +make sense outside the lexical context for which it was set up. Such an +expression is disabled when execution enters a context where one of its +variables is not defined. For example, if you give the command +`display last_char' while inside a function with an argument +`last_char', GDB displays this argument while your program continues to +stop inside that function. When it stops elsewhere--where there is no +variable `last_char'--the display is disabled automatically. The next +time your program stops where `last_char' is meaningful, you can enable +the display expression once again. + + +File: gdb.info, Node: Print Settings, Next: Value History, Prev: Auto Display, Up: Data + +Print settings +============== + +GDB provides the following ways to control how arrays, structures, and +symbols are printed. + +These settings are useful for debugging programs in any language: + +`set print address' +`set print address on' + GDB prints memory addresses showing the location of stack traces, + structure values, pointer values, breakpoints, and so forth, even + when it also displays the contents of those addresses. The default + is `on'. For example, this is what a stack frame display looks + like with `set print address on': + + (gdb) f + #0 set_quotes (lq=0x34c78 "<<", rq=0x34c88 ">>") + at input.c:530 + 530 if (lquote != def_lquote) + +`set print address off' + Do not print addresses when displaying their contents. For + example, this is the same stack frame displayed with `set print + address off': + + (gdb) set print addr off + (gdb) f + #0 set_quotes (lq="<<", rq=">>") at input.c:530 + 530 if (lquote != def_lquote) + + You can use `set print address off' to eliminate all machine + dependent displays from the GDB interface. For example, with + `print address off', you should get the same text for backtraces on + all machines--whether or not they involve pointer arguments. + +`show print address' + Show whether or not addresses are to be printed. + + When GDB prints a symbolic address, it normally prints the closest +earlier symbol plus an offset. If that symbol does not uniquely +identify the address (for example, it is a name whose scope is a single +source file), you may need to clarify. One way to do this is with +`info line', for example `info line *0x4537'. Alternately, you can set +GDB to print the source file and line number when it prints a symbolic +address: + +`set print symbol-filename on' + Tell GDB to print the source file name and line number of a symbol + in the symbolic form of an address. + +`set print symbol-filename off' + Do not print source file name and line number of a symbol. This + is the default. + +`show print symbol-filename' + Show whether or not GDB will print the source file name and line + number of a symbol in the symbolic form of an address. + + Another situation where it is helpful to show symbol filenames and +line numbers is when disassembling code; GDB shows you the line number +and source file that corresponds to each instruction. + + Also, you may wish to see the symbolic form only if the address being +printed is reasonably close to the closest earlier symbol: + +`set print max-symbolic-offset MAX-OFFSET' + Tell GDB to only display the symbolic form of an address if the + offset between the closest earlier symbol and the address is less + than MAX-OFFSET. The default is 0, which tells GDB to always + print the symbolic form of an address if any symbol precedes it. + +`show print max-symbolic-offset' + Ask how large the maximum offset is that GDB prints in a symbolic + address. + + If you have a pointer and you are not sure where it points, try `set +print symbol-filename on'. Then you can determine the name and source +file location of the variable where it points, using `p/a POINTER'. +This interprets the address in symbolic form. For example, here GDB +shows that a variable `ptt' points at another variable `t', defined in +`hi2.c': + + (gdb) set print symbol-filename on + (gdb) p/a ptt + $4 = 0xe008 + + _Warning:_ For pointers that point to a local variable, `p/a' does + not show the symbol name and filename of the referent, even with + the appropriate `set print' options turned on. + + Other settings control how different kinds of objects are printed: + +`set print array' +`set print array on' + Pretty print arrays. This format is more convenient to read, but + uses more space. The default is off. + +`set print array off' + Return to compressed format for arrays. + +`show print array' + Show whether compressed or pretty format is selected for displaying + arrays. + +`set print elements NUMBER-OF-ELEMENTS' + Set a limit on how many elements of an array GDB will print. If + GDB is printing a large array, it stops printing after it has + printed the number of elements set by the `set print elements' + command. This limit also applies to the display of strings. When + GDB starts, this limit is set to 200. Setting NUMBER-OF-ELEMENTS + to zero means that the printing is unlimited. + +`show print elements' + Display the number of elements of a large array that GDB will + print. If the number is 0, then the printing is unlimited. + +`set print null-stop' + Cause GDB to stop printing the characters of an array when the + first NULL is encountered. This is useful when large arrays + actually contain only short strings. The default is off. + +`set print pretty on' + Cause GDB to print structures in an indented format with one member + per line, like this: + + $1 = { + next = 0x0, + flags = { + sweet = 1, + sour = 1 + }, + meat = 0x54 "Pork" + } + +`set print pretty off' + Cause GDB to print structures in a compact format, like this: + + $1 = {next = 0x0, flags = {sweet = 1, sour = 1}, \ + meat = 0x54 "Pork"} + + This is the default format. + +`show print pretty' + Show which format GDB is using to print structures. + +`set print sevenbit-strings on' + Print using only seven-bit characters; if this option is set, GDB + displays any eight-bit characters (in strings or character values) + using the notation `\'NNN. This setting is best if you are + working in English (ASCII) and you use the high-order bit of + characters as a marker or "meta" bit. + +`set print sevenbit-strings off' + Print full eight-bit characters. This allows the use of more + international character sets, and is the default. + +`show print sevenbit-strings' + Show whether or not GDB is printing only seven-bit characters. + +`set print union on' + Tell GDB to print unions which are contained in structures. This + is the default setting. + +`set print union off' + Tell GDB not to print unions which are contained in structures. + +`show print union' + Ask GDB whether or not it will print unions which are contained in + structures. + + For example, given the declarations + + typedef enum {Tree, Bug} Species; + typedef enum {Big_tree, Acorn, Seedling} Tree_forms; + typedef enum {Caterpillar, Cocoon, Butterfly} + Bug_forms; + + struct thing { + Species it; + union { + Tree_forms tree; + Bug_forms bug; + } form; + }; + + struct thing foo = {Tree, {Acorn}}; + + with `set print union on' in effect `p foo' would print + + $1 = {it = Tree, form = {tree = Acorn, bug = Cocoon}} + + and with `set print union off' in effect it would print + + $1 = {it = Tree, form = {...}} + +These settings are of interest when debugging C++ programs: + +`set print demangle' +`set print demangle on' + Print C++ names in their source form rather than in the encoded + ("mangled") form passed to the assembler and linker for type-safe + linkage. The default is on. + +`show print demangle' + Show whether C++ names are printed in mangled or demangled form. + +`set print asm-demangle' +`set print asm-demangle on' + Print C++ names in their source form rather than their mangled + form, even in assembler code printouts such as instruction + disassemblies. The default is off. + +`show print asm-demangle' + Show whether C++ names in assembly listings are printed in mangled + or demangled form. + +`set demangle-style STYLE' + Choose among several encoding schemes used by different compilers + to represent C++ names. The choices for STYLE are currently: + + `auto' + Allow GDB to choose a decoding style by inspecting your + program. + + `gnu' + Decode based on the GNU C++ compiler (`g++') encoding + algorithm. This is the default. + + `hp' + Decode based on the HP ANSI C++ (`aCC') encoding algorithm. + + `lucid' + Decode based on the Lucid C++ compiler (`lcc') encoding + algorithm. + + `arm' + Decode using the algorithm in the `C++ Annotated Reference + Manual'. *Warning:* this setting alone is not sufficient to + allow debugging `cfront'-generated executables. GDB would + require further enhancement to permit that. + + If you omit STYLE, you will see a list of possible formats. + +`show demangle-style' + Display the encoding style currently in use for decoding C++ + symbols. + +`set print object' +`set print object on' + When displaying a pointer to an object, identify the _actual_ + (derived) type of the object rather than the _declared_ type, using + the virtual function table. + +`set print object off' + Display only the declared type of objects, without reference to the + virtual function table. This is the default setting. + +`show print object' + Show whether actual, or declared, object types are displayed. + +`set print static-members' +`set print static-members on' + Print static members when displaying a C++ object. The default is + on. + +`set print static-members off' + Do not print static members when displaying a C++ object. + +`show print static-members' + Show whether C++ static members are printed, or not. + +`set print vtbl' +`set print vtbl on' + Pretty print C++ virtual function tables. The default is off. + (The `vtbl' commands do not work on programs compiled with the HP + ANSI C++ compiler (`aCC').) + +`set print vtbl off' + Do not pretty print C++ virtual function tables. + +`show print vtbl' + Show whether C++ virtual function tables are pretty printed, or + not. + + +File: gdb.info, Node: Value History, Next: Convenience Vars, Prev: Print Settings, Up: Data + +Value history +============= + +Values printed by the `print' command are saved in the GDB "value +history". This allows you to refer to them in other expressions. +Values are kept until the symbol table is re-read or discarded (for +example with the `file' or `symbol-file' commands). When the symbol +table changes, the value history is discarded, since the values may +contain pointers back to the types defined in the symbol table. + + The values printed are given "history numbers" by which you can +refer to them. These are successive integers starting with one. +`print' shows you the history number assigned to a value by printing +`$NUM = ' before the value; here NUM is the history number. + + To refer to any previous value, use `$' followed by the value's +history number. The way `print' labels its output is designed to +remind you of this. Just `$' refers to the most recent value in the +history, and `$$' refers to the value before that. `$$N' refers to the +Nth value from the end; `$$2' is the value just prior to `$$', `$$1' is +equivalent to `$$', and `$$0' is equivalent to `$'. + + For example, suppose you have just printed a pointer to a structure +and want to see the contents of the structure. It suffices to type + + p *$ + + If you have a chain of structures where the component `next' points +to the next one, you can print the contents of the next one with this: + + p *$.next + +You can print successive links in the chain by repeating this +command--which you can do by just typing . + + Note that the history records values, not expressions. If the value +of `x' is 4 and you type these commands: + + print x + set x=5 + +then the value recorded in the value history by the `print' command +remains 4 even though the value of `x' has changed. + +`show values' + Print the last ten values in the value history, with their item + numbers. This is like `p $$9' repeated ten times, except that + `show values' does not change the history. + +`show values N' + Print ten history values centered on history item number N. + +`show values +' + Print ten history values just after the values last printed. If + no more values are available, `show values +' produces no display. + + Pressing to repeat `show values N' has exactly the same effect +as `show values +'. + + +File: gdb.info, Node: Convenience Vars, Next: Registers, Prev: Value History, Up: Data + +Convenience variables +===================== + +GDB provides "convenience variables" that you can use within GDB to +hold on to a value and refer to it later. These variables exist +entirely within GDB; they are not part of your program, and setting a +convenience variable has no direct effect on further execution of your +program. That is why you can use them freely. + + Convenience variables are prefixed with `$'. Any name preceded by +`$' can be used for a convenience variable, unless it is one of the +predefined machine-specific register names (*note Registers: +Registers.). (Value history references, in contrast, are _numbers_ +preceded by `$'. *Note Value history: Value History.) + + You can save a value in a convenience variable with an assignment +expression, just as you would set a variable in your program. For +example: + + set $foo = *object_ptr + +would save in `$foo' the value contained in the object pointed to by +`object_ptr'. + + Using a convenience variable for the first time creates it, but its +value is `void' until you assign a new value. You can alter the value +with another assignment at any time. + + Convenience variables have no fixed types. You can assign a +convenience variable any type of value, including structures and +arrays, even if that variable already has a value of a different type. +The convenience variable, when used as an expression, has the type of +its current value. + +`show convenience' + Print a list of convenience variables used so far, and their + values. Abbreviated `show conv'. + + One of the ways to use a convenience variable is as a counter to be +incremented or a pointer to be advanced. For example, to print a field +from successive elements of an array of structures: + + set $i = 0 + print bar[$i++]->contents + +Repeat that command by typing . + + Some convenience variables are created automatically by GDB and given +values likely to be useful. + +`$_' + The variable `$_' is automatically set by the `x' command to the + last address examined (*note Examining memory: Memory.). Other + commands which provide a default address for `x' to examine also + set `$_' to that address; these commands include `info line' and + `info breakpoint'. The type of `$_' is `void *' except when set + by the `x' command, in which case it is a pointer to the type of + `$__'. + +`$__' + The variable `$__' is automatically set by the `x' command to the + value found in the last address examined. Its type is chosen to + match the format in which the data was printed. + +`$_exitcode' + The variable `$_exitcode' is automatically set to the exit code + when the program being debugged terminates. + + On HP-UX systems, if you refer to a function or variable name that +begins with a dollar sign, GDB searches for a user or system name +first, before it searches for a convenience variable. + + +File: gdb.info, Node: Registers, Next: Floating Point Hardware, Prev: Convenience Vars, Up: Data + +Registers +========= + +You can refer to machine register contents, in expressions, as variables +with names starting with `$'. The names of registers are different for +each machine; use `info registers' to see the names used on your +machine. + +`info registers' + Print the names and values of all registers except floating-point + and vector registers (in the selected stack frame). + +`info all-registers' + Print the names and values of all registers, including + floating-point and vector registers (in the selected stack frame). + +`info registers REGNAME ...' + Print the "relativized" value of each specified register REGNAME. + As discussed in detail below, register values are normally + relative to the selected stack frame. REGNAME may be any register + name valid on the machine you are using, with or without the + initial `$'. + + GDB has four "standard" register names that are available (in +expressions) on most machines--whenever they do not conflict with an +architecture's canonical mnemonics for registers. The register names +`$pc' and `$sp' are used for the program counter register and the stack +pointer. `$fp' is used for a register that contains a pointer to the +current stack frame, and `$ps' is used for a register that contains the +processor status. For example, you could print the program counter in +hex with + + p/x $pc + +or print the instruction to be executed next with + + x/i $pc + +or add four to the stack pointer(1) with + + set $sp += 4 + + Whenever possible, these four standard register names are available +on your machine even though the machine has different canonical +mnemonics, so long as there is no conflict. The `info registers' +command shows the canonical names. For example, on the SPARC, `info +registers' displays the processor status register as `$psr' but you can +also refer to it as `$ps'; and on x86-based machines `$ps' is an alias +for the EFLAGS register. + + GDB always considers the contents of an ordinary register as an +integer when the register is examined in this way. Some machines have +special registers which can hold nothing but floating point; these +registers are considered to have floating point values. There is no way +to refer to the contents of an ordinary register as floating point value +(although you can _print_ it as a floating point value with `print/f +$REGNAME'). + + Some registers have distinct "raw" and "virtual" data formats. This +means that the data format in which the register contents are saved by +the operating system is not the same one that your program normally +sees. For example, the registers of the 68881 floating point +coprocessor are always saved in "extended" (raw) format, but all C +programs expect to work with "double" (virtual) format. In such cases, +GDB normally works with the virtual format only (the format that makes +sense for your program), but the `info registers' command prints the +data in both formats. + + Normally, register values are relative to the selected stack frame +(*note Selecting a frame: Selection.). This means that you get the +value that the register would contain if all stack frames farther in +were exited and their saved registers restored. In order to see the +true contents of hardware registers, you must select the innermost +frame (with `frame 0'). + + However, GDB must deduce where registers are saved, from the machine +code generated by your compiler. If some registers are not saved, or if +GDB is unable to locate the saved registers, the selected stack frame +makes no difference. + + ---------- Footnotes ---------- + + (1) This is a way of removing one word from the stack, on machines +where stacks grow downward in memory (most machines, nowadays). This +assumes that the innermost stack frame is selected; setting `$sp' is +not allowed when other stack frames are selected. To pop entire frames +off the stack, regardless of machine architecture, use `return'; see +*Note Returning from a function: Returning. + + +File: gdb.info, Node: Floating Point Hardware, Next: Vector Unit, Prev: Registers, Up: Data + +Floating point hardware +======================= + +Depending on the configuration, GDB may be able to give you more +information about the status of the floating point hardware. + +`info float' + Display hardware-dependent information about the floating point + unit. The exact contents and layout vary depending on the + floating point chip. Currently, `info float' is supported on the + ARM and x86 machines. + + +File: gdb.info, Node: Vector Unit, Next: Auxiliary Vector, Prev: Floating Point Hardware, Up: Data + +Vector Unit +=========== + +Depending on the configuration, GDB may be able to give you more +information about the status of the vector unit. + +`info vector' + Display information about the vector unit. The exact contents and + layout vary depending on the hardware. + + +File: gdb.info, Node: Auxiliary Vector, Next: Memory Region Attributes, Prev: Vector Unit, Up: Data + +Operating system auxiliary vector +================================= + +Some operating systems supply an "auxiliary vector" to programs at +startup. This is akin to the arguments and environment that you +specify for a program, but contains a system-dependent variety of +binary values that tell system libraries important details about the +hardware, operating system, and process. Each value's purpose is +identified by an integer tag; the meanings are well-known but +system-specific. Depending on the configuration and operating system +facilities, GDB may be able to show you this information. + +`info auxv' + Display the auxiliary vector of the inferior, which can be either a + live process or a core dump file. GDB prints each tag value + numerically, and also shows names and text descriptions for + recognized tags. Some values in the vector are numbers, some bit + masks, and some pointers to strings or other data. GDB displays + each value in the most appropriate form for a recognized tag, and + in hexadecimal for an unrecognized tag. + + +File: gdb.info, Node: Memory Region Attributes, Next: Dump/Restore Files, Prev: Auxiliary Vector, Up: Data + +Memory region attributes +======================== + +"Memory region attributes" allow you to describe special handling +required by regions of your target's memory. GDB uses attributes to +determine whether to allow certain types of memory accesses; whether to +use specific width accesses; and whether to cache target memory. + + Defined memory regions can be individually enabled and disabled. +When a memory region is disabled, GDB uses the default attributes when +accessing memory in that region. Similarly, if no memory regions have +been defined, GDB uses the default attributes when accessing all memory. + + When a memory region is defined, it is given a number to identify it; +to enable, disable, or remove a memory region, you specify that number. + +`mem LOWER UPPER ATTRIBUTES...' + Define memory region bounded by LOWER and UPPER with attributes + ATTRIBUTES.... Note that UPPER == 0 is a special case: it is + treated as the the target's maximum memory address. (0xffff on 16 + bit targets, 0xffffffff on 32 bit targets, etc.) + +`delete mem NUMS...' + Remove memory regions NUMS.... + +`disable mem NUMS...' + Disable memory regions NUMS.... A disabled memory region is not + forgotten. It may be enabled again later. + +`enable mem NUMS...' + Enable memory regions NUMS.... + +`info mem' + Print a table of all defined memory regions, with the following + columns for each region. + + _Memory Region Number_ + + _Enabled or Disabled._ + Enabled memory regions are marked with `y'. Disabled memory + regions are marked with `n'. + + _Lo Address_ + The address defining the inclusive lower bound of the memory + region. + + _Hi Address_ + The address defining the exclusive upper bound of the memory + region. + + _Attributes_ + The list of attributes set for this memory region. + +Attributes +---------- + +Memory Access Mode +.................. + +The access mode attributes set whether GDB may make read or write +accesses to a memory region. + + While these attributes prevent GDB from performing invalid memory +accesses, they do nothing to prevent the target system, I/O DMA, etc. +from accessing memory. + +`ro' + Memory is read only. + +`wo' + Memory is write only. + +`rw' + Memory is read/write. This is the default. + +Memory Access Size +.................. + +The acccess size attributes tells GDB to use specific sized accesses in +the memory region. Often memory mapped device registers require +specific sized accesses. If no access size attribute is specified, GDB +may use accesses of any size. + +`8' + Use 8 bit memory accesses. + +`16' + Use 16 bit memory accesses. + +`32' + Use 32 bit memory accesses. + +`64' + Use 64 bit memory accesses. + +Data Cache +.......... + +The data cache attributes set whether GDB will cache target memory. +While this generally improves performance by reducing debug protocol +overhead, it can lead to incorrect results because GDB does not know +about volatile variables or memory mapped device registers. + +`cache' + Enable GDB to cache target memory. + +`nocache' + Disable GDB from caching target memory. This is the default. + + +File: gdb.info, Node: Dump/Restore Files, Next: Character Sets, Prev: Memory Region Attributes, Up: Data + +Copy between memory and a file +============================== + +You can use the commands `dump', `append', and `restore' to copy data +between target memory and a file. The `dump' and `append' commands +write data to a file, and the `restore' command reads data from a file +back into the inferior's memory. Files may be in binary, Motorola +S-record, Intel hex, or Tektronix Hex format; however, GDB can only +append to binary files. + +`dump [FORMAT] memory FILENAME START_ADDR END_ADDR' +`dump [FORMAT] value FILENAME EXPR' + Dump the contents of memory from START_ADDR to END_ADDR, or the + value of EXPR, to FILENAME in the given format. + + The FORMAT parameter may be any one of: + `binary' + Raw binary form. + + `ihex' + Intel hex format. + + `srec' + Motorola S-record format. + + `tekhex' + Tektronix Hex format. + + GDB uses the same definitions of these formats as the GNU binary + utilities, like `objdump' and `objcopy'. If FORMAT is omitted, + GDB dumps the data in raw binary form. + +`append [binary] memory FILENAME START_ADDR END_ADDR' +`append [binary] value FILENAME EXPR' + Append the contents of memory from START_ADDR to END_ADDR, or the + value of EXPR, to FILENAME, in raw binary form. (GDB can only + append data to files in raw binary form.) + +`restore FILENAME [binary] BIAS START END' + Restore the contents of file FILENAME into memory. The `restore' + command can automatically recognize any known BFD file format, + except for raw binary. To restore a raw binary file you must + specify the optional keyword `binary' after the filename. + + If BIAS is non-zero, its value will be added to the addresses + contained in the file. Binary files always start at address zero, + so they will be restored at address BIAS. Other bfd files have a + built-in location; they will be restored at offset BIAS from that + location. + + If START and/or END are non-zero, then only data between file + offset START and file offset END will be restored. These offsets + are relative to the addresses in the file, before the BIAS + argument is applied. + + + +File: gdb.info, Node: Character Sets, Prev: Dump/Restore Files, Up: Data + +Character Sets +============== + +If the program you are debugging uses a different character set to +represent characters and strings than the one GDB uses itself, GDB can +automatically translate between the character sets for you. The +character set GDB uses we call the "host character set"; the one the +inferior program uses we call the "target character set". + + For example, if you are running GDB on a GNU/Linux system, which +uses the ISO Latin 1 character set, but you are using GDB's remote +protocol (*note Remote Debugging: Remote.) to debug a program running +on an IBM mainframe, which uses the EBCDIC character set, then the host +character set is Latin-1, and the target character set is EBCDIC. If +you give GDB the command `set target-charset EBCDIC-US', then GDB +translates between EBCDIC and Latin 1 as you print character or string +values, or use character and string literals in expressions. + + GDB has no way to automatically recognize which character set the +inferior program uses; you must tell it, using the `set target-charset' +command, described below. + + Here are the commands for controlling GDB's character set support: + +`set target-charset CHARSET' + Set the current target character set to CHARSET. We list the + character set names GDB recognizes below, but if you type `set + target-charset' followed by , GDB will list the target + character sets it supports. + +`set host-charset CHARSET' + Set the current host character set to CHARSET. + + By default, GDB uses a host character set appropriate to the + system it is running on; you can override that default using the + `set host-charset' command. + + GDB can only use certain character sets as its host character set. + We list the character set names GDB recognizes below, and + indicate which can be host character sets, but if you type `set + target-charset' followed by , GDB will list the host + character sets it supports. + +`set charset CHARSET' + Set the current host and target character sets to CHARSET. As + above, if you type `set charset' followed by , GDB will + list the name of the character sets that can be used for both host + and target. + +`show charset' + Show the names of the current host and target charsets. + +`show host-charset' + Show the name of the current host charset. + +`show target-charset' + Show the name of the current target charset. + + + GDB currently includes support for the following character sets: + +`ASCII' + Seven-bit U.S. ASCII. GDB can use this as its host character set. + +`ISO-8859-1' + The ISO Latin 1 character set. This extends ASCII with accented + characters needed for French, German, and Spanish. GDB can use + this as its host character set. + +`EBCDIC-US' +`IBM1047' + Variants of the EBCDIC character set, used on some of IBM's + mainframe operating systems. (GNU/Linux on the S/390 uses U.S. + ASCII.) GDB cannot use these as its host character set. + + + Note that these are all single-byte character sets. More work inside +GDB is needed to support multi-byte or variable-width character +encodings, like the UTF-8 and UCS-2 encodings of Unicode. + + Here is an example of GDB's character set support in action. Assume +that the following source code has been placed in the file +`charset-test.c': + + #include + + char ascii_hello[] + = {72, 101, 108, 108, 111, 44, 32, 119, + 111, 114, 108, 100, 33, 10, 0}; + char ibm1047_hello[] + = {200, 133, 147, 147, 150, 107, 64, 166, + 150, 153, 147, 132, 90, 37, 0}; + + main () + { + printf ("Hello, world!\n"); + } + + In this program, `ascii_hello' and `ibm1047_hello' are arrays +containing the string `Hello, world!' followed by a newline, encoded in +the ASCII and IBM1047 character sets. + + We compile the program, and invoke the debugger on it: + + $ gcc -g charset-test.c -o charset-test + $ gdb -nw charset-test + GNU gdb 2001-12-19-cvs + Copyright 2001 Free Software Foundation, Inc. + ... + (gdb) + + We can use the `show charset' command to see what character sets GDB +is currently using to interpret and display characters and strings: + + (gdb) show charset + The current host and target character set is `ISO-8859-1'. + (gdb) + + For the sake of printing this manual, let's use ASCII as our initial +character set: + (gdb) set charset ASCII + (gdb) show charset + The current host and target character set is `ASCII'. + (gdb) + + Let's assume that ASCII is indeed the correct character set for our +host system -- in other words, let's assume that if GDB prints +characters using the ASCII character set, our terminal will display +them properly. Since our current target character set is also ASCII, +the contents of `ascii_hello' print legibly: + + (gdb) print ascii_hello + $1 = 0x401698 "Hello, world!\n" + (gdb) print ascii_hello[0] + $2 = 72 'H' + (gdb) + + GDB uses the target character set for character and string literals +you use in expressions: + + (gdb) print '+' + $3 = 43 '+' + (gdb) + + The ASCII character set uses the number 43 to encode the `+' +character. + + GDB relies on the user to tell it which character set the target +program uses. If we print `ibm1047_hello' while our target character +set is still ASCII, we get jibberish: + + (gdb) print ibm1047_hello + $4 = 0x4016a8 "\310\205\223\223\226k@\246\226\231\223\204Z%" + (gdb) print ibm1047_hello[0] + $5 = 200 '\310' + (gdb) + + If we invoke the `set target-charset' followed by , GDB +tells us the character sets it supports: + + (gdb) set target-charset + ASCII EBCDIC-US IBM1047 ISO-8859-1 + (gdb) set target-charset + + We can select IBM1047 as our target character set, and examine the +program's strings again. Now the ASCII string is wrong, but GDB +translates the contents of `ibm1047_hello' from the target character +set, IBM1047, to the host character set, ASCII, and they display +correctly: + + (gdb) set target-charset IBM1047 + (gdb) show charset + The current host character set is `ASCII'. + The current target character set is `IBM1047'. + (gdb) print ascii_hello + $6 = 0x401698 "\110\145%%?\054\040\167?\162%\144\041\012" + (gdb) print ascii_hello[0] + $7 = 72 '\110' + (gdb) print ibm1047_hello + $8 = 0x4016a8 "Hello, world!\n" + (gdb) print ibm1047_hello[0] + $9 = 200 'H' + (gdb) + + As above, GDB uses the target character set for character and string +literals you use in expressions: + + (gdb) print '+' + $10 = 78 '+' + (gdb) + + The IBM1047 character set uses the number 78 to encode the `+' +character. + + +File: gdb.info, Node: Macros, Next: Tracepoints, Prev: Data, Up: Top + +C Preprocessor Macros +********************* + +Some languages, such as C and C++, provide a way to define and invoke +"preprocessor macros" which expand into strings of tokens. GDB can +evaluate expressions containing macro invocations, show the result of +macro expansion, and show a macro's definition, including where it was +defined. + + You may need to compile your program specially to provide GDB with +information about preprocessor macros. Most compilers do not include +macros in their debugging information, even when you compile with the +`-g' flag. *Note Compilation::. + + A program may define a macro at one point, remove that definition +later, and then provide a different definition after that. Thus, at +different points in the program, a macro may have different +definitions, or have no definition at all. If there is a current stack +frame, GDB uses the macros in scope at that frame's source code line. +Otherwise, GDB uses the macros in scope at the current listing location; +see *Note List::. + + At the moment, GDB does not support the `##' token-splicing +operator, the `#' stringification operator, or variable-arity macros. + + Whenever GDB evaluates an expression, it always expands any macro +invocations present in the expression. GDB also provides the following +commands for working with macros explicitly. + +`macro expand EXPRESSION' +`macro exp EXPRESSION' + Show the results of expanding all preprocessor macro invocations in + EXPRESSION. Since GDB simply expands macros, but does not parse + the result, EXPRESSION need not be a valid expression; it can be + any string of tokens. + +`macro expand-once EXPRESSION' +`macro exp1 EXPRESSION' + (This command is not yet implemented.) Show the results of + expanding those preprocessor macro invocations that appear + explicitly in EXPRESSION. Macro invocations appearing in that + expansion are left unchanged. This command allows you to see the + effect of a particular macro more clearly, without being confused + by further expansions. Since GDB simply expands macros, but does + not parse the result, EXPRESSION need not be a valid expression; it + can be any string of tokens. + +`info macro MACRO' + Show the definition of the macro named MACRO, and describe the + source location where that definition was established. + +`macro define MACRO REPLACEMENT-LIST' +`macro define MACRO(ARGLIST) REPLACEMENT-LIST' + (This command is not yet implemented.) Introduce a definition for + a preprocessor macro named MACRO, invocations of which are replaced + by the tokens given in REPLACEMENT-LIST. The first form of this + command defines an "object-like" macro, which takes no arguments; + the second form defines a "function-like" macro, which takes the + arguments given in ARGLIST. + + A definition introduced by this command is in scope in every + expression evaluated in GDB, until it is removed with the `macro + undef' command, described below. The definition overrides all + definitions for MACRO present in the program being debugged, as + well as any previous user-supplied definition. + +`macro undef MACRO' + (This command is not yet implemented.) Remove any user-supplied + definition for the macro named MACRO. This command only affects + definitions provided with the `macro define' command, described + above; it cannot remove definitions present in the program being + debugged. + + + Here is a transcript showing the above commands in action. First, we +show our source files: + + $ cat sample.c + #include + #include "sample.h" + + #define M 42 + #define ADD(x) (M + x) + + main () + { + #define N 28 + printf ("Hello, world!\n"); + #undef N + printf ("We're so creative.\n"); + #define N 1729 + printf ("Goodbye, world!\n"); + } + $ cat sample.h + #define Q < + $ + + Now, we compile the program using the GNU C compiler, GCC. We pass +the `-gdwarf-2' and `-g3' flags to ensure the compiler includes +information about preprocessor macros in the debugging information. + + $ gcc -gdwarf-2 -g3 sample.c -o sample + $ + + Now, we start GDB on our sample program: + + $ gdb -nw sample + GNU gdb 2002-05-06-cvs + Copyright 2002 Free Software Foundation, Inc. + GDB is free software, ... + (gdb) + + We can expand macros and examine their definitions, even when the +program is not running. GDB uses the current listing position to +decide which macro definitions are in scope: + + (gdb) list main + 3 + 4 #define M 42 + 5 #define ADD(x) (M + x) + 6 + 7 main () + 8 { + 9 #define N 28 + 10 printf ("Hello, world!\n"); + 11 #undef N + 12 printf ("We're so creative.\n"); + (gdb) info macro ADD + Defined at /home/jimb/gdb/macros/play/sample.c:5 + #define ADD(x) (M + x) + (gdb) info macro Q + Defined at /home/jimb/gdb/macros/play/sample.h:1 + included at /home/jimb/gdb/macros/play/sample.c:2 + #define Q < + (gdb) macro expand ADD(1) + expands to: (42 + 1) + (gdb) macro expand-once ADD(1) + expands to: once (M + 1) + (gdb) + + In the example above, note that `macro expand-once' expands only the +macro invocation explicit in the original text -- the invocation of +`ADD' -- but does not expand the invocation of the macro `M', which was +introduced by `ADD'. + + Once the program is running, GDB uses the macro definitions in force +at the source line of the current stack frame: + + (gdb) break main + Breakpoint 1 at 0x8048370: file sample.c, line 10. + (gdb) run + Starting program: /home/jimb/gdb/macros/play/sample + + Breakpoint 1, main () at sample.c:10 + 10 printf ("Hello, world!\n"); + (gdb) + + At line 10, the definition of the macro `N' at line 9 is in force: + + (gdb) info macro N + Defined at /home/jimb/gdb/macros/play/sample.c:9 + #define N 28 + (gdb) macro expand N Q M + expands to: 28 < 42 + (gdb) print N Q M + $1 = 1 + (gdb) + + As we step over directives that remove `N''s definition, and then +give it a new definition, GDB finds the definition (or lack thereof) in +force at each point: + + (gdb) next + Hello, world! + 12 printf ("We're so creative.\n"); + (gdb) info macro N + The symbol `N' has no definition as a C/C++ preprocessor macro + at /home/jimb/gdb/macros/play/sample.c:12 + (gdb) next + We're so creative. + 14 printf ("Goodbye, world!\n"); + (gdb) info macro N + Defined at /home/jimb/gdb/macros/play/sample.c:13 + #define N 1729 + (gdb) macro expand N Q M + expands to: 1729 < 42 + (gdb) print N Q M + $2 = 0 + (gdb) + + +File: gdb.info, Node: Tracepoints, Next: Overlays, Prev: Macros, Up: Top + +Tracepoints +*********** + +In some applications, it is not feasible for the debugger to interrupt +the program's execution long enough for the developer to learn anything +helpful about its behavior. If the program's correctness depends on +its real-time behavior, delays introduced by a debugger might cause the +program to change its behavior drastically, or perhaps fail, even when +the code itself is correct. It is useful to be able to observe the +program's behavior without interrupting it. + + Using GDB's `trace' and `collect' commands, you can specify +locations in the program, called "tracepoints", and arbitrary +expressions to evaluate when those tracepoints are reached. Later, +using the `tfind' command, you can examine the values those expressions +had when the program hit the tracepoints. The expressions may also +denote objects in memory--structures or arrays, for example--whose +values GDB should record; while visiting a particular tracepoint, you +may inspect those objects as if they were in memory at that moment. +However, because GDB records these values without interacting with you, +it can do so quickly and unobtrusively, hopefully not disturbing the +program's behavior. + + The tracepoint facility is currently available only for remote +targets. *Note Targets::. In addition, your remote target must know +how to collect trace data. This functionality is implemented in the +remote stub; however, none of the stubs distributed with GDB support +tracepoints as of this writing. + + This chapter describes the tracepoint commands and features. + +* Menu: + +* Set Tracepoints:: +* Analyze Collected Data:: +* Tracepoint Variables:: + + +File: gdb.info, Node: Set Tracepoints, Next: Analyze Collected Data, Up: Tracepoints + +Commands to Set Tracepoints +=========================== + +Before running such a "trace experiment", an arbitrary number of +tracepoints can be set. Like a breakpoint (*note Set Breaks::), a +tracepoint has a number assigned to it by GDB. Like with breakpoints, +tracepoint numbers are successive integers starting from one. Many of +the commands associated with tracepoints take the tracepoint number as +their argument, to identify which tracepoint to work on. + + For each tracepoint, you can specify, in advance, some arbitrary set +of data that you want the target to collect in the trace buffer when it +hits that tracepoint. The collected data can include registers, local +variables, or global data. Later, you can use GDB commands to examine +the values these data had at the time the tracepoint was hit. + + This section describes commands to set tracepoints and associated +conditions and actions. + +* Menu: + +* Create and Delete Tracepoints:: +* Enable and Disable Tracepoints:: +* Tracepoint Passcounts:: +* Tracepoint Actions:: +* Listing Tracepoints:: +* Starting and Stopping Trace Experiment:: + + +File: gdb.info, Node: Create and Delete Tracepoints, Next: Enable and Disable Tracepoints, Up: Set Tracepoints + +Create and Delete Tracepoints +----------------------------- + +`trace' + The `trace' command is very similar to the `break' command. Its + argument can be a source line, a function name, or an address in + the target program. *Note Set Breaks::. The `trace' command + defines a tracepoint, which is a point in the target program where + the debugger will briefly stop, collect some data, and then allow + the program to continue. Setting a tracepoint or changing its + commands doesn't take effect until the next `tstart' command; + thus, you cannot change the tracepoint attributes once a trace + experiment is running. + + Here are some examples of using the `trace' command: + + (gdb) trace foo.c:121 // a source file and line number + + (gdb) trace +2 // 2 lines forward + + (gdb) trace my_function // first source line of function + + (gdb) trace *my_function // EXACT start address of function + + (gdb) trace *0x2117c4 // an address + + You can abbreviate `trace' as `tr'. + + The convenience variable `$tpnum' records the tracepoint number of + the most recently set tracepoint. + +`delete tracepoint [NUM]' + Permanently delete one or more tracepoints. With no argument, the + default is to delete all tracepoints. + + Examples: + + (gdb) delete trace 1 2 3 // remove three tracepoints + + (gdb) delete trace // remove all tracepoints + + You can abbreviate this command as `del tr'. + + +File: gdb.info, Node: Enable and Disable Tracepoints, Next: Tracepoint Passcounts, Prev: Create and Delete Tracepoints, Up: Set Tracepoints + +Enable and Disable Tracepoints +------------------------------ + +`disable tracepoint [NUM]' + Disable tracepoint NUM, or all tracepoints if no argument NUM is + given. A disabled tracepoint will have no effect during the next + trace experiment, but it is not forgotten. You can re-enable a + disabled tracepoint using the `enable tracepoint' command. + +`enable tracepoint [NUM]' + Enable tracepoint NUM, or all tracepoints. The enabled + tracepoints will become effective the next time a trace experiment + is run. + + +File: gdb.info, Node: Tracepoint Passcounts, Next: Tracepoint Actions, Prev: Enable and Disable Tracepoints, Up: Set Tracepoints + +Tracepoint Passcounts +--------------------- + +`passcount [N [NUM]]' + Set the "passcount" of a tracepoint. The passcount is a way to + automatically stop a trace experiment. If a tracepoint's + passcount is N, then the trace experiment will be automatically + stopped on the N'th time that tracepoint is hit. If the + tracepoint number NUM is not specified, the `passcount' command + sets the passcount of the most recently defined tracepoint. If no + passcount is given, the trace experiment will run until stopped + explicitly by the user. + + Examples: + + (gdb) passcount 5 2 // Stop on the 5th execution of + `// tracepoint 2' + + (gdb) passcount 12 // Stop on the 12th execution of the + `// most recently defined tracepoint.' + (gdb) trace foo + (gdb) pass 3 + (gdb) trace bar + (gdb) pass 2 + (gdb) trace baz + (gdb) pass 1 // Stop tracing when foo has been + `// executed 3 times OR when bar has' + `// been executed 2 times' + `// OR when baz has been executed 1 time.' + + + +File: gdb.info, Node: Tracepoint Actions, Next: Listing Tracepoints, Prev: Tracepoint Passcounts, Up: Set Tracepoints + +Tracepoint Action Lists +----------------------- + +`actions [NUM]' + This command will prompt for a list of actions to be taken when the + tracepoint is hit. If the tracepoint number NUM is not specified, + this command sets the actions for the one that was most recently + defined (so that you can define a tracepoint and then say + `actions' without bothering about its number). You specify the + actions themselves on the following lines, one action at a time, + and terminate the actions list with a line containing just `end'. + So far, the only defined actions are `collect' and + `while-stepping'. + + To remove all actions from a tracepoint, type `actions NUM' and + follow it immediately with `end'. + + (gdb) collect DATA // collect some data + + (gdb) while-stepping 5 // single-step 5 times, collect data + + (gdb) end // signals the end of actions. + + In the following example, the action list begins with `collect' + commands indicating the things to be collected when the tracepoint + is hit. Then, in order to single-step and collect additional data + following the tracepoint, a `while-stepping' command is used, + followed by the list of things to be collected while stepping. The + `while-stepping' command is terminated by its own separate `end' + command. Lastly, the action list is terminated by an `end' + command. + + (gdb) trace foo + (gdb) actions + Enter actions for tracepoint 1, one per line: + > collect bar,baz + > collect $regs + > while-stepping 12 + > collect $fp, $sp + > end + end + +`collect EXPR1, EXPR2, ...' + Collect values of the given expressions when the tracepoint is hit. + This command accepts a comma-separated list of any valid + expressions. In addition to global, static, or local variables, + the following special arguments are supported: + + `$regs' + collect all registers + + `$args' + collect all function arguments + + `$locals' + collect all local variables. + + You can give several consecutive `collect' commands, each one with + a single argument, or one `collect' command with several arguments + separated by commas: the effect is the same. + + The command `info scope' (*note info scope: Symbols.) is + particularly useful for figuring out what data to collect. + +`while-stepping N' + Perform N single-step traces after the tracepoint, collecting new + data at each step. The `while-stepping' command is followed by + the list of what to collect while stepping (followed by its own + `end' command): + + > while-stepping 12 + > collect $regs, myglobal + > end + > + + You may abbreviate `while-stepping' as `ws' or `stepping'. + + +File: gdb.info, Node: Listing Tracepoints, Next: Starting and Stopping Trace Experiment, Prev: Tracepoint Actions, Up: Set Tracepoints + +Listing Tracepoints +------------------- + +`info tracepoints [NUM]' + Display information about the tracepoint NUM. If you don't specify + a tracepoint number, displays information about all the tracepoints + defined so far. For each tracepoint, the following information is + shown: + + * its number + + * whether it is enabled or disabled + + * its address + + * its passcount as given by the `passcount N' command + + * its step count as given by the `while-stepping N' command + + * where in the source files is the tracepoint set + + * its action list as given by the `actions' command + + (gdb) info trace + Num Enb Address PassC StepC What + 1 y 0x002117c4 0 0 + 2 y 0x0020dc64 0 0 in g_test at g_test.c:1375 + 3 y 0x0020b1f4 0 0 in get_data at ../foo.c:41 + (gdb) + + This command can be abbreviated `info tp'. + + +File: gdb.info, Node: Starting and Stopping Trace Experiment, Prev: Listing Tracepoints, Up: Set Tracepoints + +Starting and Stopping Trace Experiment +-------------------------------------- + +`tstart' + This command takes no arguments. It starts the trace experiment, + and begins collecting data. This has the side effect of + discarding all the data collected in the trace buffer during the + previous trace experiment. + +`tstop' + This command takes no arguments. It ends the trace experiment, and + stops collecting data. + + *Note:* a trace experiment and data collection may stop + automatically if any tracepoint's passcount is reached (*note + Tracepoint Passcounts::), or if the trace buffer becomes full. + +`tstatus' + This command displays the status of the current trace data + collection. + + Here is an example of the commands we described so far: + + (gdb) trace gdb_c_test + (gdb) actions + Enter actions for tracepoint #1, one per line. + > collect $regs,$locals,$args + > while-stepping 11 + > collect $regs + > end + > end + (gdb) tstart + [time passes ...] + (gdb) tstop + + +File: gdb.info, Node: Analyze Collected Data, Next: Tracepoint Variables, Prev: Set Tracepoints, Up: Tracepoints + +Using the collected data +======================== + +After the tracepoint experiment ends, you use GDB commands for +examining the trace data. The basic idea is that each tracepoint +collects a trace "snapshot" every time it is hit and another snapshot +every time it single-steps. All these snapshots are consecutively +numbered from zero and go into a buffer, and you can examine them +later. The way you examine them is to "focus" on a specific trace +snapshot. When the remote stub is focused on a trace snapshot, it will +respond to all GDB requests for memory and registers by reading from +the buffer which belongs to that snapshot, rather than from _real_ +memory or registers of the program being debugged. This means that +*all* GDB commands (`print', `info registers', `backtrace', etc.) will +behave as if we were currently debugging the program state as it was +when the tracepoint occurred. Any requests for data that are not in +the buffer will fail. + +* Menu: + +* tfind:: How to select a trace snapshot +* tdump:: How to display all data for a snapshot +* save-tracepoints:: How to save tracepoints for a future run + + +File: gdb.info, Node: tfind, Next: tdump, Up: Analyze Collected Data + +`tfind N' +--------- + +The basic command for selecting a trace snapshot from the buffer is +`tfind N', which finds trace snapshot number N, counting from zero. If +no argument N is given, the next snapshot is selected. + + Here are the various forms of using the `tfind' command. + +`tfind start' + Find the first snapshot in the buffer. This is a synonym for + `tfind 0' (since 0 is the number of the first snapshot). + +`tfind none' + Stop debugging trace snapshots, resume _live_ debugging. + +`tfind end' + Same as `tfind none'. + +`tfind' + No argument means find the next trace snapshot. + +`tfind -' + Find the previous trace snapshot before the current one. This + permits retracing earlier steps. + +`tfind tracepoint NUM' + Find the next snapshot associated with tracepoint NUM. Search + proceeds forward from the last examined trace snapshot. If no + argument NUM is given, it means find the next snapshot collected + for the same tracepoint as the current snapshot. + +`tfind pc ADDR' + Find the next snapshot associated with the value ADDR of the + program counter. Search proceeds forward from the last examined + trace snapshot. If no argument ADDR is given, it means find the + next snapshot with the same value of PC as the current snapshot. + +`tfind outside ADDR1, ADDR2' + Find the next snapshot whose PC is outside the given range of + addresses. + +`tfind range ADDR1, ADDR2' + Find the next snapshot whose PC is between ADDR1 and ADDR2. + +`tfind line [FILE:]N' + Find the next snapshot associated with the source line N. If the + optional argument FILE is given, refer to line N in that source + file. Search proceeds forward from the last examined trace + snapshot. If no argument N is given, it means find the next line + other than the one currently being examined; thus saying `tfind + line' repeatedly can appear to have the same effect as stepping + from line to line in a _live_ debugging session. + + The default arguments for the `tfind' commands are specifically +designed to make it easy to scan through the trace buffer. For +instance, `tfind' with no argument selects the next trace snapshot, and +`tfind -' with no argument selects the previous trace snapshot. So, by +giving one `tfind' command, and then simply hitting repeatedly +you can examine all the trace snapshots in order. Or, by saying `tfind +-' and then hitting repeatedly you can examine the snapshots in +reverse order. The `tfind line' command with no argument selects the +snapshot for the next source line executed. The `tfind pc' command with +no argument selects the next snapshot with the same program counter +(PC) as the current frame. The `tfind tracepoint' command with no +argument selects the next trace snapshot collected by the same +tracepoint as the current one. + + In addition to letting you scan through the trace buffer manually, +these commands make it easy to construct GDB scripts that scan through +the trace buffer and print out whatever collected data you are +interested in. Thus, if we want to examine the PC, FP, and SP +registers from each trace frame in the buffer, we can say this: + + (gdb) tfind start + (gdb) while ($trace_frame != -1) + > printf "Frame %d, PC = %08X, SP = %08X, FP = %08X\n", \ + $trace_frame, $pc, $sp, $fp + > tfind + > end + + Frame 0, PC = 0020DC64, SP = 0030BF3C, FP = 0030BF44 + Frame 1, PC = 0020DC6C, SP = 0030BF38, FP = 0030BF44 + Frame 2, PC = 0020DC70, SP = 0030BF34, FP = 0030BF44 + Frame 3, PC = 0020DC74, SP = 0030BF30, FP = 0030BF44 + Frame 4, PC = 0020DC78, SP = 0030BF2C, FP = 0030BF44 + Frame 5, PC = 0020DC7C, SP = 0030BF28, FP = 0030BF44 + Frame 6, PC = 0020DC80, SP = 0030BF24, FP = 0030BF44 + Frame 7, PC = 0020DC84, SP = 0030BF20, FP = 0030BF44 + Frame 8, PC = 0020DC88, SP = 0030BF1C, FP = 0030BF44 + Frame 9, PC = 0020DC8E, SP = 0030BF18, FP = 0030BF44 + Frame 10, PC = 00203F6C, SP = 0030BE3C, FP = 0030BF14 + + Or, if we want to examine the variable `X' at each source line in +the buffer: + + (gdb) tfind start + (gdb) while ($trace_frame != -1) + > printf "Frame %d, X == %d\n", $trace_frame, X + > tfind line + > end + + Frame 0, X = 1 + Frame 7, X = 2 + Frame 13, X = 255 + + +File: gdb.info, Node: tdump, Next: save-tracepoints, Prev: tfind, Up: Analyze Collected Data + +`tdump' +------- + +This command takes no arguments. It prints all the data collected at +the current trace snapshot. + + (gdb) trace 444 + (gdb) actions + Enter actions for tracepoint #2, one per line: + > collect $regs, $locals, $args, gdb_long_test + > end + + (gdb) tstart + + (gdb) tfind line 444 + #0 gdb_test (p1=0x11, p2=0x22, p3=0x33, p4=0x44, p5=0x55, p6=0x66) + at gdb_test.c:444 + 444 printp( "%s: arguments = 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", ) + + (gdb) tdump + Data collected at tracepoint 2, trace frame 1: + d0 0xc4aa0085 -995491707 + d1 0x18 24 + d2 0x80 128 + d3 0x33 51 + d4 0x71aea3d 119204413 + d5 0x22 34 + d6 0xe0 224 + d7 0x380035 3670069 + a0 0x19e24a 1696330 + a1 0x3000668 50333288 + a2 0x100 256 + a3 0x322000 3284992 + a4 0x3000698 50333336 + a5 0x1ad3cc 1758156 + fp 0x30bf3c 0x30bf3c + sp 0x30bf34 0x30bf34 + ps 0x0 0 + pc 0x20b2c8 0x20b2c8 + fpcontrol 0x0 0 + fpstatus 0x0 0 + fpiaddr 0x0 0 + p = 0x20e5b4 "gdb-test" + p1 = (void *) 0x11 + p2 = (void *) 0x22 + p3 = (void *) 0x33 + p4 = (void *) 0x44 + p5 = (void *) 0x55 + p6 = (void *) 0x66 + gdb_long_test = 17 '\021' + + (gdb) + + +File: gdb.info, Node: save-tracepoints, Prev: tdump, Up: Analyze Collected Data + +`save-tracepoints FILENAME' +--------------------------- + +This command saves all current tracepoint definitions together with +their actions and passcounts, into a file `FILENAME' suitable for use +in a later debugging session. To read the saved tracepoint +definitions, use the `source' command (*note Command Files::). + + +File: gdb.info, Node: Tracepoint Variables, Prev: Analyze Collected Data, Up: Tracepoints + +Convenience Variables for Tracepoints +===================================== + +`(int) $trace_frame' + The current trace snapshot (a.k.a. "frame") number, or -1 if no + snapshot is selected. + +`(int) $tracepoint' + The tracepoint for the current trace snapshot. + +`(int) $trace_line' + The line number for the current trace snapshot. + +`(char []) $trace_file' + The source file for the current trace snapshot. + +`(char []) $trace_func' + The name of the function containing `$tracepoint'. + + Note: `$trace_file' is not suitable for use in `printf', use +`output' instead. + + Here's a simple example of using these convenience variables for +stepping through all the trace snapshots and printing some of their +data. + + (gdb) tfind start + + (gdb) while $trace_frame != -1 + > output $trace_file + > printf ", line %d (tracepoint #%d)\n", $trace_line, $tracepoint + > tfind + > end + + +File: gdb.info, Node: Overlays, Next: Languages, Prev: Tracepoints, Up: Top + +Debugging Programs That Use Overlays +************************************ + +If your program is too large to fit completely in your target system's +memory, you can sometimes use "overlays" to work around this problem. +GDB provides some support for debugging programs that use overlays. + +* Menu: + +* How Overlays Work:: A general explanation of overlays. +* Overlay Commands:: Managing overlays in GDB. +* Automatic Overlay Debugging:: GDB can find out which overlays are + mapped by asking the inferior. +* Overlay Sample Program:: A sample program using overlays. + + +File: gdb.info, Node: How Overlays Work, Next: Overlay Commands, Up: Overlays + +How Overlays Work +================= + +Suppose you have a computer whose instruction address space is only 64 +kilobytes long, but which has much more memory which can be accessed by +other means: special instructions, segment registers, or memory +management hardware, for example. Suppose further that you want to +adapt a program which is larger than 64 kilobytes to run on this system. + + One solution is to identify modules of your program which are +relatively independent, and need not call each other directly; call +these modules "overlays". Separate the overlays from the main program, +and place their machine code in the larger memory. Place your main +program in instruction memory, but leave at least enough space there to +hold the largest overlay as well. + + Now, to call a function located in an overlay, you must first copy +that overlay's machine code from the large memory into the space set +aside for it in the instruction memory, and then jump to its entry point +there. + + Data Instruction Larger + Address Space Address Space Address Space + +-----------+ +-----------+ +-----------+ + | | | | | | + +-----------+ +-----------+ +-----------+<-- overlay 1 + | program | | main | .----| overlay 1 | load address + | variables | | program | | +-----------+ + | and heap | | | | | | + +-----------+ | | | +-----------+<-- overlay 2 + | | +-----------+ | | | load address + +-----------+ | | | .-| overlay 2 | + | | | | | | + mapped --->+-----------+ | | +-----------+ + address | | | | | | + | overlay | <-' | | | + | area | <---' +-----------+<-- overlay 3 + | | <---. | | load address + +-----------+ `--| overlay 3 | + | | | | + +-----------+ | | + +-----------+ + | | + +-----------+ + + A code overlay + + The diagram (*note A code overlay::) shows a system with separate +data and instruction address spaces. To map an overlay, the program +copies its code from the larger address space to the instruction +address space. Since the overlays shown here all use the same mapped +address, only one may be mapped at a time. For a system with a single +address space for data and instructions, the diagram would be similar, +except that the program variables and heap would share an address space +with the main program and the overlay area. + + An overlay loaded into instruction memory and ready for use is +called a "mapped" overlay; its "mapped address" is its address in the +instruction memory. An overlay not present (or only partially present) +in instruction memory is called "unmapped"; its "load address" is its +address in the larger memory. The mapped address is also called the +"virtual memory address", or "VMA"; the load address is also called the +"load memory address", or "LMA". + + Unfortunately, overlays are not a completely transparent way to +adapt a program to limited instruction memory. They introduce a new +set of global constraints you must keep in mind as you design your +program: + + * Before calling or returning to a function in an overlay, your + program must make sure that overlay is actually mapped. + Otherwise, the call or return will transfer control to the right + address, but in the wrong overlay, and your program will probably + crash. + + * If the process of mapping an overlay is expensive on your system, + you will need to choose your overlays carefully to minimize their + effect on your program's performance. + + * The executable file you load onto your system must contain each + overlay's instructions, appearing at the overlay's load address, + not its mapped address. However, each overlay's instructions must + be relocated and its symbols defined as if the overlay were at its + mapped address. You can use GNU linker scripts to specify + different load and relocation addresses for pieces of your + program; see *Note Overlay Description: (ld.info)Overlay + Description. + + * The procedure for loading executable files onto your system must + be able to load their contents into the larger address space as + well as the instruction and data spaces. + + + The overlay system described above is rather simple, and could be +improved in many ways: + + * If your system has suitable bank switch registers or memory + management hardware, you could use those facilities to make an + overlay's load area contents simply appear at their mapped address + in instruction space. This would probably be faster than copying + the overlay to its mapped area in the usual way. + + * If your overlays are small enough, you could set aside more than + one overlay area, and have more than one overlay mapped at a time. + + * You can use overlays to manage data, as well as instructions. In + general, data overlays are even less transparent to your design + than code overlays: whereas code overlays only require care when + you call or return to functions, data overlays require care every + time you access the data. Also, if you change the contents of a + data overlay, you must copy its contents back out to its load + address before you can copy a different data overlay into the same + mapped area. + + + +File: gdb.info, Node: Overlay Commands, Next: Automatic Overlay Debugging, Prev: How Overlays Work, Up: Overlays + +Overlay Commands +================ + +To use GDB's overlay support, each overlay in your program must +correspond to a separate section of the executable file. The section's +virtual memory address and load memory address must be the overlay's +mapped and load addresses. Identifying overlays with sections allows +GDB to determine the appropriate address of a function or variable, +depending on whether the overlay is mapped or not. + + GDB's overlay commands all start with the word `overlay'; you can +abbreviate this as `ov' or `ovly'. The commands are: + +`overlay off' + Disable GDB's overlay support. When overlay support is disabled, + GDB assumes that all functions and variables are always present at + their mapped addresses. By default, GDB's overlay support is + disabled. + +`overlay manual' + Enable "manual" overlay debugging. In this mode, GDB relies on + you to tell it which overlays are mapped, and which are not, using + the `overlay map-overlay' and `overlay unmap-overlay' commands + described below. + +`overlay map-overlay OVERLAY' +`overlay map OVERLAY' + Tell GDB that OVERLAY is now mapped; OVERLAY must be the name of + the object file section containing the overlay. When an overlay + is mapped, GDB assumes it can find the overlay's functions and + variables at their mapped addresses. GDB assumes that any other + overlays whose mapped ranges overlap that of OVERLAY are now + unmapped. + +`overlay unmap-overlay OVERLAY' +`overlay unmap OVERLAY' + Tell GDB that OVERLAY is no longer mapped; OVERLAY must be the + name of the object file section containing the overlay. When an + overlay is unmapped, GDB assumes it can find the overlay's + functions and variables at their load addresses. + +`overlay auto' + Enable "automatic" overlay debugging. In this mode, GDB consults + a data structure the overlay manager maintains in the inferior to + see which overlays are mapped. For details, see *Note Automatic + Overlay Debugging::. + +`overlay load-target' +`overlay load' + Re-read the overlay table from the inferior. Normally, GDB + re-reads the table GDB automatically each time the inferior stops, + so this command should only be necessary if you have changed the + overlay mapping yourself using GDB. This command is only useful + when using automatic overlay debugging. + +`overlay list-overlays' +`overlay list' + Display a list of the overlays currently mapped, along with their + mapped addresses, load addresses, and sizes. + + + Normally, when GDB prints a code address, it includes the name of +the function the address falls in: + + (gdb) print main + $3 = {int ()} 0x11a0
+ +When overlay debugging is enabled, GDB recognizes code in unmapped +overlays, and prints the names of unmapped functions with asterisks +around them. For example, if `foo' is a function in an unmapped +overlay, GDB prints it this way: + + (gdb) overlay list + No sections are mapped. + (gdb) print foo + $5 = {int (int)} 0x100000 <*foo*> + +When `foo''s overlay is mapped, GDB prints the function's name normally: + + (gdb) overlay list + Section .ov.foo.text, loaded at 0x100000 - 0x100034, + mapped at 0x1016 - 0x104a + (gdb) print foo + $6 = {int (int)} 0x1016 + + When overlay debugging is enabled, GDB can find the correct address +for functions and variables in an overlay, whether or not the overlay +is mapped. This allows most GDB commands, like `break' and +`disassemble', to work normally, even on unmapped code. However, GDB's +breakpoint support has some limitations: + + * You can set breakpoints in functions in unmapped overlays, as long + as GDB can write to the overlay at its load address. + + * GDB can not set hardware or simulator-based breakpoints in + unmapped overlays. However, if you set a breakpoint at the end of + your overlay manager (and tell GDB which overlays are now mapped, + if you are using manual overlay management), GDB will re-set its + breakpoints properly. + + +File: gdb.info, Node: Automatic Overlay Debugging, Next: Overlay Sample Program, Prev: Overlay Commands, Up: Overlays + +Automatic Overlay Debugging +=========================== + +GDB can automatically track which overlays are mapped and which are +not, given some simple co-operation from the overlay manager in the +inferior. If you enable automatic overlay debugging with the `overlay +auto' command (*note Overlay Commands::), GDB looks in the inferior's +memory for certain variables describing the current state of the +overlays. + + Here are the variables your overlay manager must define to support +GDB's automatic overlay debugging: + +`_ovly_table': + This variable must be an array of the following structures: + + struct + { + /* The overlay's mapped address. */ + unsigned long vma; + + /* The size of the overlay, in bytes. */ + unsigned long size; + + /* The overlay's load address. */ + unsigned long lma; + + /* Non-zero if the overlay is currently mapped; + zero otherwise. */ + unsigned long mapped; + } + +`_novlys': + This variable must be a four-byte signed integer, holding the total + number of elements in `_ovly_table'. + + + To decide whether a particular overlay is mapped or not, GDB looks +for an entry in `_ovly_table' whose `vma' and `lma' members equal the +VMA and LMA of the overlay's section in the executable file. When GDB +finds a matching entry, it consults the entry's `mapped' member to +determine whether the overlay is currently mapped. + + In addition, your overlay manager may define a function called +`_ovly_debug_event'. If this function is defined, GDB will silently +set a breakpoint there. If the overlay manager then calls this +function whenever it has changed the overlay table, this will enable +GDB to accurately keep track of which overlays are in program memory, +and update any breakpoints that may be set in overlays. This will +allow breakpoints to work even if the overlays are kept in ROM or other +non-writable memory while they are not being executed. + + +File: gdb.info, Node: Overlay Sample Program, Prev: Automatic Overlay Debugging, Up: Overlays + +Overlay Sample Program +====================== + +When linking a program which uses overlays, you must place the overlays +at their load addresses, while relocating them to run at their mapped +addresses. To do this, you must write a linker script (*note Overlay +Description: (ld.info)Overlay Description.). Unfortunately, since +linker scripts are specific to a particular host system, target +architecture, and target memory layout, this manual cannot provide +portable sample code demonstrating GDB's overlay support. + + However, the GDB source distribution does contain an overlaid +program, with linker scripts for a few systems, as part of its test +suite. The program consists of the following files from +`gdb/testsuite/gdb.base': + +`overlays.c' + The main program file. + +`ovlymgr.c' + A simple overlay manager, used by `overlays.c'. + +`foo.c' +`bar.c' +`baz.c' +`grbx.c' + Overlay modules, loaded and used by `overlays.c'. + +`d10v.ld' +`m32r.ld' + Linker scripts for linking the test program on the `d10v-elf' and + `m32r-elf' targets. + + You can build the test program using the `d10v-elf' GCC +cross-compiler like this: + + $ d10v-elf-gcc -g -c overlays.c + $ d10v-elf-gcc -g -c ovlymgr.c + $ d10v-elf-gcc -g -c foo.c + $ d10v-elf-gcc -g -c bar.c + $ d10v-elf-gcc -g -c baz.c + $ d10v-elf-gcc -g -c grbx.c + $ d10v-elf-gcc -g overlays.o ovlymgr.o foo.o bar.o \ + baz.o grbx.o -Wl,-Td10v.ld -o overlays + + The build process is identical for any other architecture, except +that you must substitute the appropriate compiler and linker script for +the target system for `d10v-elf-gcc' and `d10v.ld'. + + +File: gdb.info, Node: Languages, Next: Symbols, Prev: Overlays, Up: Top + +Using GDB with Different Languages +********************************** + +Although programming languages generally have common aspects, they are +rarely expressed in the same manner. For instance, in ANSI C, +dereferencing a pointer `p' is accomplished by `*p', but in Modula-2, +it is accomplished by `p^'. Values can also be represented (and +displayed) differently. Hex numbers in C appear as `0x1ae', while in +Modula-2 they appear as `1AEH'. + + Language-specific information is built into GDB for some languages, +allowing you to express operations like the above in your program's +native language, and allowing GDB to output values in a manner +consistent with the syntax of your program's native language. The +language you use to build expressions is called the "working language". + +* Menu: + +* Setting:: Switching between source languages +* Show:: Displaying the language +* Checks:: Type and range checks +* Support:: Supported languages +* Unsupported languages:: Unsupported languages + + +File: gdb.info, Node: Setting, Next: Show, Up: Languages + +Switching between source languages +================================== + +There are two ways to control the working language--either have GDB set +it automatically, or select it manually yourself. You can use the `set +language' command for either purpose. On startup, GDB defaults to +setting the language automatically. The working language is used to +determine how expressions you type are interpreted, how values are +printed, etc. + + In addition to the working language, every source file that GDB +knows about has its own working language. For some object file +formats, the compiler might indicate which language a particular source +file is in. However, most of the time GDB infers the language from the +name of the file. The language of a source file controls whether C++ +names are demangled--this way `backtrace' can show each frame +appropriately for its own language. There is no way to set the +language of a source file from within GDB, but you can set the language +associated with a filename extension. *Note Displaying the language: +Show. + + This is most commonly a problem when you use a program, such as +`cfront' or `f2c', that generates C but is written in another language. +In that case, make the program use `#line' directives in its C output; +that way GDB will know the correct language of the source code of the +original program, and will display that source code, not the generated +C code. + +* Menu: + +* Filenames:: Filename extensions and languages. +* Manually:: Setting the working language manually +* Automatically:: Having GDB infer the source language + + +File: gdb.info, Node: Filenames, Next: Manually, Up: Setting + +List of filename extensions and languages +----------------------------------------- + +If a source file name ends in one of the following extensions, then GDB +infers that its language is the one indicated. + +`.c' + C source file + +`.C' +`.cc' +`.cp' +`.cpp' +`.cxx' +`.c++' + C++ source file + +`.m' + Objective-C source file + +`.f' +`.F' + Fortran source file + +`.mod' + Modula-2 source file + +`.s' +`.S' + Assembler source file. This actually behaves almost like C, but + GDB does not skip over function prologues when stepping. + + In addition, you may set the language associated with a filename +extension. *Note Displaying the language: Show. + + +File: gdb.info, Node: Manually, Next: Automatically, Prev: Filenames, Up: Setting + +Setting the working language +---------------------------- + +If you allow GDB to set the language automatically, expressions are +interpreted the same way in your debugging session and your program. + + If you wish, you may set the language manually. To do this, issue +the command `set language LANG', where LANG is the name of a language, +such as `c' or `modula-2'. For a list of the supported languages, type +`set language'. + + Setting the language manually prevents GDB from updating the working +language automatically. This can lead to confusion if you try to debug +a program when the working language is not the same as the source +language, when an expression is acceptable to both languages--but means +different things. For instance, if the current source file were +written in C, and GDB was parsing Modula-2, a command such as: + + print a = b + c + +might not have the effect you intended. In C, this means to add `b' +and `c' and place the result in `a'. The result printed would be the +value of `a'. In Modula-2, this means to compare `a' to the result of +`b+c', yielding a `BOOLEAN' value. + + +File: gdb.info, Node: Automatically, Prev: Manually, Up: Setting + +Having GDB infer the source language +------------------------------------ + +To have GDB set the working language automatically, use `set language +local' or `set language auto'. GDB then infers the working language. +That is, when your program stops in a frame (usually by encountering a +breakpoint), GDB sets the working language to the language recorded for +the function in that frame. If the language for a frame is unknown +(that is, if the function or block corresponding to the frame was +defined in a source file that does not have a recognized extension), +the current working language is not changed, and GDB issues a warning. + + This may not seem necessary for most programs, which are written +entirely in one source language. However, program modules and libraries +written in one source language can be used by a main program written in +a different source language. Using `set language auto' in this case +frees you from having to set the working language manually. + + +File: gdb.info, Node: Show, Next: Checks, Prev: Setting, Up: Languages + +Displaying the language +======================= + +The following commands help you find out which language is the working +language, and also what language source files were written in. + +`show language' + Display the current working language. This is the language you + can use with commands such as `print' to build and compute + expressions that may involve variables in your program. + +`info frame' + Display the source language for this frame. This language becomes + the working language if you use an identifier from this frame. + *Note Information about a frame: Frame Info, to identify the other + information listed here. + +`info source' + Display the source language of this source file. *Note Examining + the Symbol Table: Symbols, to identify the other information + listed here. + + In unusual circumstances, you may have source files with extensions +not in the standard list. You can then set the extension associated +with a language explicitly: + +`set extension-language .EXT LANGUAGE' + Set source files with extension .EXT to be assumed to be in the + source language LANGUAGE. + +`info extensions' + List all the filename extensions and the associated languages. + + +File: gdb.info, Node: Checks, Next: Support, Prev: Show, Up: Languages + +Type and range checking +======================= + + _Warning:_ In this release, the GDB commands for type and range + checking are included, but they do not yet have any effect. This + section documents the intended facilities. + + Some languages are designed to guard you against making seemingly +common errors through a series of compile- and run-time checks. These +include checking the type of arguments to functions and operators, and +making sure mathematical overflows are caught at run time. Checks such +as these help to ensure a program's correctness once it has been +compiled by eliminating type mismatches, and providing active checks +for range errors when your program is running. + + GDB can check for conditions like the above if you wish. Although +GDB does not check the statements in your program, it can check +expressions entered directly into GDB for evaluation via the `print' +command, for example. As with the working language, GDB can also +decide whether or not to check automatically based on your program's +source language. *Note Supported languages: Support, for the default +settings of supported languages. + +* Menu: + +* Type Checking:: An overview of type checking +* Range Checking:: An overview of range checking + + +File: gdb.info, Node: Type Checking, Next: Range Checking, Up: Checks + +An overview of type checking +---------------------------- + +Some languages, such as Modula-2, are strongly typed, meaning that the +arguments to operators and functions have to be of the correct type, +otherwise an error occurs. These checks prevent type mismatch errors +from ever causing any run-time problems. For example, + + 1 + 2 => 3 +but + error--> 1 + 2.3 + + The second example fails because the `CARDINAL' 1 is not +type-compatible with the `REAL' 2.3. + + For the expressions you use in GDB commands, you can tell the GDB +type checker to skip checking; to treat any mismatches as errors and +abandon the expression; or to only issue warnings when type mismatches +occur, but evaluate the expression anyway. When you choose the last of +these, GDB evaluates expressions like the second example above, but +also issues a warning. + + Even if you turn type checking off, there may be other reasons +related to type that prevent GDB from evaluating an expression. For +instance, GDB does not know how to add an `int' and a `struct foo'. +These particular type errors have nothing to do with the language in +use, and usually arise from expressions, such as the one described +above, which make little sense to evaluate anyway. + + Each language defines to what degree it is strict about type. For +instance, both Modula-2 and C require the arguments to arithmetical +operators to be numbers. In C, enumerated types and pointers can be +represented as numbers, so that they are valid arguments to mathematical +operators. *Note Supported languages: Support, for further details on +specific languages. + + GDB provides some additional commands for controlling the type +checker: + +`set check type auto' + Set type checking on or off based on the current working language. + *Note Supported languages: Support, for the default settings for + each language. + +`set check type on' +`set check type off' + Set type checking on or off, overriding the default setting for the + current working language. Issue a warning if the setting does not + match the language default. If any type mismatches occur in + evaluating an expression while type checking is on, GDB prints a + message and aborts evaluation of the expression. + +`set check type warn' + Cause the type checker to issue warnings, but to always attempt to + evaluate the expression. Evaluating the expression may still be + impossible for other reasons. For example, GDB cannot add numbers + and structures. + +`show type' + Show the current setting of the type checker, and whether or not + GDB is setting it automatically. + + +File: gdb.info, Node: Range Checking, Prev: Type Checking, Up: Checks + +An overview of range checking +----------------------------- + +In some languages (such as Modula-2), it is an error to exceed the +bounds of a type; this is enforced with run-time checks. Such range +checking is meant to ensure program correctness by making sure +computations do not overflow, or indices on an array element access do +not exceed the bounds of the array. + + For expressions you use in GDB commands, you can tell GDB to treat +range errors in one of three ways: ignore them, always treat them as +errors and abandon the expression, or issue warnings but evaluate the +expression anyway. + + A range error can result from numerical overflow, from exceeding an +array index bound, or when you type a constant that is not a member of +any type. Some languages, however, do not treat overflows as an error. +In many implementations of C, mathematical overflow causes the result +to "wrap around" to lower values--for example, if M is the largest +integer value, and S is the smallest, then + + M + 1 => S + + This, too, is specific to individual languages, and in some cases +specific to individual compilers or machines. *Note Supported +languages: Support, for further details on specific languages. + + GDB provides some additional commands for controlling the range +checker: + +`set check range auto' + Set range checking on or off based on the current working language. + *Note Supported languages: Support, for the default settings for + each language. + +`set check range on' +`set check range off' + Set range checking on or off, overriding the default setting for + the current working language. A warning is issued if the setting + does not match the language default. If a range error occurs and + range checking is on, then a message is printed and evaluation of + the expression is aborted. + +`set check range warn' + Output messages when the GDB range checker detects a range error, + but attempt to evaluate the expression anyway. Evaluating the + expression may still be impossible for other reasons, such as + accessing memory that the process does not own (a typical example + from many Unix systems). + +`show range' + Show the current setting of the range checker, and whether or not + it is being set automatically by GDB. + + +File: gdb.info, Node: Support, Next: Unsupported languages, Prev: Checks, Up: Languages + +Supported languages +=================== + +GDB supports C, C++, Objective-C, Fortran, Java, assembly, and Modula-2. +Some GDB features may be used in expressions regardless of the language +you use: the GDB `@' and `::' operators, and the `{type}addr' construct +(*note Expressions: Expressions.) can be used with the constructs of +any supported language. + + The following sections detail to what degree each source language is +supported by GDB. These sections are not meant to be language +tutorials or references, but serve only as a reference guide to what the +GDB expression parser accepts, and what input and output formats should +look like for different languages. There are many good books written +on each of these languages; please look to these for a language +reference or tutorial. + +* Menu: + +* C:: C and C++ +* Objective-C:: Objective-C +* Modula-2:: Modula-2 + + +File: gdb.info, Node: C, Next: Objective-C, Up: Support + +C and C++ +--------- + +Since C and C++ are so closely related, many features of GDB apply to +both languages. Whenever this is the case, we discuss those languages +together. + + The C++ debugging facilities are jointly implemented by the C++ +compiler and GDB. Therefore, to debug your C++ code effectively, you +must compile your C++ programs with a supported C++ compiler, such as +GNU `g++', or the HP ANSI C++ compiler (`aCC'). + + For best results when using GNU C++, use the DWARF 2 debugging +format; if it doesn't work on your system, try the stabs+ debugging +format. You can select those formats explicitly with the `g++' +command-line options `-gdwarf-2' and `-gstabs+'. *Note Options for +Debugging Your Program or GNU CC: (gcc.info)Debugging Options. + +* Menu: + +* C Operators:: C and C++ operators +* C Constants:: C and C++ constants +* C plus plus expressions:: C++ expressions +* C Defaults:: Default settings for C and C++ +* C Checks:: C and C++ type and range checks +* Debugging C:: GDB and C +* Debugging C plus plus:: GDB features for C++ + + +File: gdb.info, Node: C Operators, Next: C Constants, Up: C + +C and C++ operators +................... + +Operators must be defined on values of specific types. For instance, +`+' is defined on numbers, but not on structures. Operators are often +defined on groups of types. + + For the purposes of C and C++, the following definitions hold: + + * _Integral types_ include `int' with any of its storage-class + specifiers; `char'; `enum'; and, for C++, `bool'. + + * _Floating-point types_ include `float', `double', and `long + double' (if supported by the target platform). + + * _Pointer types_ include all types defined as `(TYPE *)'. + + * _Scalar types_ include all of the above. + + +The following operators are supported. They are listed here in order +of increasing precedence: + +`,' + The comma or sequencing operator. Expressions in a + comma-separated list are evaluated from left to right, with the + result of the entire expression being the last expression + evaluated. + +`=' + Assignment. The value of an assignment expression is the value + assigned. Defined on scalar types. + +`OP=' + Used in an expression of the form `A OP= B', and translated to + `A = A OP B'. `OP=' and `=' have the same precedence. OP is any + one of the operators `|', `^', `&', `<<', `>>', `+', `-', `*', + `/', `%'. + +`?:' + The ternary operator. `A ? B : C' can be thought of as: if A + then B else C. A should be of an integral type. + +`||' + Logical OR. Defined on integral types. + +`&&' + Logical AND. Defined on integral types. + +`|' + Bitwise OR. Defined on integral types. + +`^' + Bitwise exclusive-OR. Defined on integral types. + +`&' + Bitwise AND. Defined on integral types. + +`==, !=' + Equality and inequality. Defined on scalar types. The value of + these expressions is 0 for false and non-zero for true. + +`<, >, <=, >=' + Less than, greater than, less than or equal, greater than or equal. + Defined on scalar types. The value of these expressions is 0 for + false and non-zero for true. + +`<<, >>' + left shift, and right shift. Defined on integral types. + +`@' + The GDB "artificial array" operator (*note Expressions: + Expressions.). + +`+, -' + Addition and subtraction. Defined on integral types, + floating-point types and pointer types. + +`*, /, %' + Multiplication, division, and modulus. Multiplication and + division are defined on integral and floating-point types. + Modulus is defined on integral types. + +`++, --' + Increment and decrement. When appearing before a variable, the + operation is performed before the variable is used in an + expression; when appearing after it, the variable's value is used + before the operation takes place. + +`*' + Pointer dereferencing. Defined on pointer types. Same precedence + as `++'. + +`&' + Address operator. Defined on variables. Same precedence as `++'. + + For debugging C++, GDB implements a use of `&' beyond what is + allowed in the C++ language itself: you can use `&(&REF)' (or, if + you prefer, simply `&&REF') to examine the address where a C++ + reference variable (declared with `&REF') is stored. + +`-' + Negative. Defined on integral and floating-point types. Same + precedence as `++'. + +`!' + Logical negation. Defined on integral types. Same precedence as + `++'. + +`~' + Bitwise complement operator. Defined on integral types. Same + precedence as `++'. + +`., ->' + Structure member, and pointer-to-structure member. For + convenience, GDB regards the two as equivalent, choosing whether + to dereference a pointer based on the stored type information. + Defined on `struct' and `union' data. + +`.*, ->*' + Dereferences of pointers to members. + +`[]' + Array indexing. `A[I]' is defined as `*(A+I)'. Same precedence + as `->'. + +`()' + Function parameter list. Same precedence as `->'. + +`::' + C++ scope resolution operator. Defined on `struct', `union', and + `class' types. + +`::' + Doubled colons also represent the GDB scope operator (*note + Expressions: Expressions.). Same precedence as `::', above. + + If an operator is redefined in the user code, GDB usually attempts +to invoke the redefined version instead of using the operator's +predefined meaning. + +* Menu: + +* C Constants:: + + +File: gdb.info, Node: C Constants, Next: C plus plus expressions, Prev: C Operators, Up: C + +C and C++ constants +................... + +GDB allows you to express the constants of C and C++ in the following +ways: + + * Integer constants are a sequence of digits. Octal constants are + specified by a leading `0' (i.e. zero), and hexadecimal constants + by a leading `0x' or `0X'. Constants may also end with a letter + `l', specifying that the constant should be treated as a `long' + value. + + * Floating point constants are a sequence of digits, followed by a + decimal point, followed by a sequence of digits, and optionally + followed by an exponent. An exponent is of the form: + `e[[+]|-]NNN', where NNN is another sequence of digits. The `+' + is optional for positive exponents. A floating-point constant may + also end with a letter `f' or `F', specifying that the constant + should be treated as being of the `float' (as opposed to the + default `double') type; or with a letter `l' or `L', which + specifies a `long double' constant. + + * Enumerated constants consist of enumerated identifiers, or their + integral equivalents. + + * Character constants are a single character surrounded by single + quotes (`''), or a number--the ordinal value of the corresponding + character (usually its ASCII value). Within quotes, the single + character may be represented by a letter or by "escape sequences", + which are of the form `\NNN', where NNN is the octal representation + of the character's ordinal value; or of the form `\X', where `X' + is a predefined special character--for example, `\n' for newline. + + * String constants are a sequence of character constants surrounded + by double quotes (`"'). Any valid character constant (as described + above) may appear. Double quotes within the string must be + preceded by a backslash, so for instance `"a\"b'c"' is a string of + five characters. + + * Pointer constants are an integral value. You can also write + pointers to constants using the C operator `&'. + + * Array constants are comma-separated lists surrounded by braces `{' + and `}'; for example, `{1,2,3}' is a three-element array of + integers, `{{1,2}, {3,4}, {5,6}}' is a three-by-two array, and + `{&"hi", &"there", &"fred"}' is a three-element array of pointers. + +* Menu: + +* C plus plus expressions:: +* C Defaults:: +* C Checks:: + +* Debugging C:: + + +File: gdb.info, Node: C plus plus expressions, Next: C Defaults, Prev: C Constants, Up: C + +C++ expressions +............... + +GDB expression handling can interpret most C++ expressions. + + _Warning:_ GDB can only debug C++ code if you use the proper + compiler and the proper debug format. Currently, GDB works best + when debugging C++ code that is compiled with GCC 2.95.3 or with + GCC 3.1 or newer, using the options `-gdwarf-2' or `-gstabs+'. + DWARF 2 is preferred over stabs+. Most configurations of GCC emit + either DWARF 2 or stabs+ as their default debug format, so you + usually don't need to specify a debug format explicitly. Other + compilers and/or debug formats are likely to work badly or not at + all when using GDB to debug C++ code. + + 1. Member function calls are allowed; you can use expressions like + + count = aml->GetOriginal(x, y) + + 2. While a member function is active (in the selected stack frame), + your expressions have the same namespace available as the member + function; that is, GDB allows implicit references to the class + instance pointer `this' following the same rules as C++. + + 3. You can call overloaded functions; GDB resolves the function call + to the right definition, with some restrictions. GDB does not + perform overload resolution involving user-defined type + conversions, calls to constructors, or instantiations of templates + that do not exist in the program. It also cannot handle ellipsis + argument lists or default arguments. + + It does perform integral conversions and promotions, floating-point + promotions, arithmetic conversions, pointer conversions, + conversions of class objects to base classes, and standard + conversions such as those of functions or arrays to pointers; it + requires an exact match on the number of function arguments. + + Overload resolution is always performed, unless you have specified + `set overload-resolution off'. *Note GDB features for C++: + Debugging C plus plus. + + You must specify `set overload-resolution off' in order to use an + explicit function signature to call an overloaded function, as in + p 'foo(char,int)'('x', 13) + + The GDB command-completion facility can simplify this; see *Note + Command completion: Completion. + + 4. GDB understands variables declared as C++ references; you can use + them in expressions just as you do in C++ source--they are + automatically dereferenced. + + In the parameter list shown when GDB displays a frame, the values + of reference variables are not displayed (unlike other variables); + this avoids clutter, since references are often used for large + structures. The _address_ of a reference variable is always + shown, unless you have specified `set print address off'. + + 5. GDB supports the C++ name resolution operator `::'--your + expressions can use it just as expressions in your program do. + Since one scope may be defined in another, you can use `::' + repeatedly if necessary, for example in an expression like + `SCOPE1::SCOPE2::NAME'. GDB also allows resolving name scope by + reference to source files, in both C and C++ debugging (*note + Program variables: Variables.). + + In addition, when used with HP's C++ compiler, GDB supports calling +virtual functions correctly, printing out virtual bases of objects, +calling functions in a base subobject, casting objects, and invoking +user-defined operators. + + +File: gdb.info, Node: C Defaults, Next: C Checks, Prev: C plus plus expressions, Up: C + +C and C++ defaults +.................. + +If you allow GDB to set type and range checking automatically, they +both default to `off' whenever the working language changes to C or +C++. This happens regardless of whether you or GDB selects the working +language. + + If you allow GDB to set the language automatically, it recognizes +source files whose names end with `.c', `.C', or `.cc', etc, and when +GDB enters code compiled from one of these files, it sets the working +language to C or C++. *Note Having GDB infer the source language: +Automatically, for further details. + + +File: gdb.info, Node: C Checks, Next: Debugging C, Prev: C Defaults, Up: C + +C and C++ type and range checks +............................... + +By default, when GDB parses C or C++ expressions, type checking is not +used. However, if you turn type checking on, GDB considers two +variables type equivalent if: + + * The two variables are structured and have the same structure, + union, or enumerated tag. + + * The two variables have the same type name, or types that have been + declared equivalent through `typedef'. + + + Range checking, if turned on, is done on mathematical operations. +Array indices are not checked, since they are often used to index a +pointer that is not itself an array. + + +File: gdb.info, Node: Debugging C, Next: Debugging C plus plus, Prev: C Checks, Up: C + +GDB and C +......... + +The `set print union' and `show print union' commands apply to the +`union' type. When set to `on', any `union' that is inside a `struct' +or `class' is also printed. Otherwise, it appears as `{...}'. + + The `@' operator aids in the debugging of dynamic arrays, formed +with pointers and a memory allocation function. *Note Expressions: +Expressions. + +* Menu: + +* Debugging C plus plus:: + + +File: gdb.info, Node: Debugging C plus plus, Prev: Debugging C, Up: C + +GDB features for C++ +.................... + +Some GDB commands are particularly useful with C++, and some are +designed specifically for use with C++. Here is a summary: + +`breakpoint menus' + When you want a breakpoint in a function whose name is overloaded, + GDB breakpoint menus help you specify which function definition + you want. *Note Breakpoint menus: Breakpoint Menus. + +`rbreak REGEX' + Setting breakpoints using regular expressions is helpful for + setting breakpoints on overloaded functions that are not members + of any special classes. *Note Setting breakpoints: Set Breaks. + +`catch throw' +`catch catch' + Debug C++ exception handling using these commands. *Note Setting + catchpoints: Set Catchpoints. + +`ptype TYPENAME' + Print inheritance relationships as well as other information for + type TYPENAME. *Note Examining the Symbol Table: Symbols. + +`set print demangle' +`show print demangle' +`set print asm-demangle' +`show print asm-demangle' + Control whether C++ symbols display in their source form, both when + displaying code as C++ source and when displaying disassemblies. + *Note Print settings: Print Settings. + +`set print object' +`show print object' + Choose whether to print derived (actual) or declared types of + objects. *Note Print settings: Print Settings. + +`set print vtbl' +`show print vtbl' + Control the format for printing virtual function tables. *Note + Print settings: Print Settings. (The `vtbl' commands do not work + on programs compiled with the HP ANSI C++ compiler (`aCC').) + +`set overload-resolution on' + Enable overload resolution for C++ expression evaluation. The + default is on. For overloaded functions, GDB evaluates the + arguments and searches for a function whose signature matches the + argument types, using the standard C++ conversion rules (see *Note + C++ expressions: C plus plus expressions, for details). If it + cannot find a match, it emits a message. + +`set overload-resolution off' + Disable overload resolution for C++ expression evaluation. For + overloaded functions that are not class member functions, GDB + chooses the first function of the specified name that it finds in + the symbol table, whether or not its arguments are of the correct + type. For overloaded functions that are class member functions, + GDB searches for a function whose signature _exactly_ matches the + argument types. + +`Overloaded symbol names' + You can specify a particular definition of an overloaded symbol, + using the same notation that is used to declare such symbols in + C++: type `SYMBOL(TYPES)' rather than just SYMBOL. You can also + use the GDB command-line word completion facilities to list the + available choices, or to finish the type list for you. *Note + Command completion: Completion, for details on how to do this. + + +File: gdb.info, Node: Objective-C, Next: Modula-2, Prev: C, Up: Support + +Objective-C +----------- + +This section provides information about some commands and command +options that are useful for debugging Objective-C code. + +* Menu: + +* Method Names in Commands:: +* The Print Command with Objective-C:: + + +File: gdb.info, Node: Method Names in Commands, Next: The Print Command with Objective-C, Prev: Objective-C, Up: Objective-C + +Method Names in Commands +........................ + +The following commands have been extended to accept Objective-C method +names as line specifications: + + * `clear' + + * `break' + + * `info line' + + * `jump' + + * `list' + + A fully qualified Objective-C method name is specified as + + -[CLASS METHODNAME] + + where the minus sign is used to indicate an instance method and a +plus sign (not shown) is used to indicate a class method. The class +name CLASS and method name METHODNAME are enclosed in brackets, similar +to the way messages are specified in Objective-C source code. For +example, to set a breakpoint at the `create' instance method of class +`Fruit' in the program currently being debugged, enter: + + break -[Fruit create] + + To list ten program lines around the `initialize' class method, +enter: + + list +[NSText initialize] + + In the current version of GDB, the plus or minus sign is required. +In future versions of GDB, the plus or minus sign will be optional, but +you can use it to narrow the search. It is also possible to specify +just a method name: + + break create + + You must specify the complete method name, including any colons. If +your program's source files contain more than one `create' method, +you'll be presented with a numbered list of classes that implement that +method. Indicate your choice by number, or type `0' to exit if none +apply. + + As another example, to clear a breakpoint established at the +`makeKeyAndOrderFront:' method of the `NSWindow' class, enter: + + clear -[NSWindow makeKeyAndOrderFront:] + + +File: gdb.info, Node: The Print Command with Objective-C, Prev: Method Names in Commands, Up: Objective-C + +The Print Command With Objective-C +.................................. + +The print command has also been extended to accept methods. For +example: + + print -[OBJECT hash] + +will tell GDB to send the `hash' message to OBJECT and print the +result. Also, an additional command has been added, `print-object' or +`po' for short, which is meant to print the description of an object. +However, this command may only work with certain Objective-C libraries +that have a particular hook function, `_NSPrintForDebugger', defined. + + +File: gdb.info, Node: Modula-2, Prev: Objective-C, Up: Support + +Modula-2 +-------- + +The extensions made to GDB to support Modula-2 only support output from +the GNU Modula-2 compiler (which is currently being developed). Other +Modula-2 compilers are not currently supported, and attempting to debug +executables produced by them is most likely to give an error as GDB +reads in the executable's symbol table. + +* Menu: + +* M2 Operators:: Built-in operators +* Built-In Func/Proc:: Built-in functions and procedures +* M2 Constants:: Modula-2 constants +* M2 Defaults:: Default settings for Modula-2 +* Deviations:: Deviations from standard Modula-2 +* M2 Checks:: Modula-2 type and range checks +* M2 Scope:: The scope operators `::' and `.' +* GDB/M2:: GDB and Modula-2 + + +File: gdb.info, Node: M2 Operators, Next: Built-In Func/Proc, Up: Modula-2 + +Operators +......... + +Operators must be defined on values of specific types. For instance, +`+' is defined on numbers, but not on structures. Operators are often +defined on groups of types. For the purposes of Modula-2, the +following definitions hold: + + * _Integral types_ consist of `INTEGER', `CARDINAL', and their + subranges. + + * _Character types_ consist of `CHAR' and its subranges. + + * _Floating-point types_ consist of `REAL'. + + * _Pointer types_ consist of anything declared as `POINTER TO TYPE'. + + * _Scalar types_ consist of all of the above. + + * _Set types_ consist of `SET' and `BITSET' types. + + * _Boolean types_ consist of `BOOLEAN'. + +The following operators are supported, and appear in order of +increasing precedence: + +`,' + Function argument or array index separator. + +`:=' + Assignment. The value of VAR `:=' VALUE is VALUE. + +`<, >' + Less than, greater than on integral, floating-point, or enumerated + types. + +`<=, >=' + Less than or equal to, greater than or equal to on integral, + floating-point and enumerated types, or set inclusion on set + types. Same precedence as `<'. + +`=, <>, #' + Equality and two ways of expressing inequality, valid on scalar + types. Same precedence as `<'. In GDB scripts, only `<>' is + available for inequality, since `#' conflicts with the script + comment character. + +`IN' + Set membership. Defined on set types and the types of their + members. Same precedence as `<'. + +`OR' + Boolean disjunction. Defined on boolean types. + +`AND, &' + Boolean conjunction. Defined on boolean types. + +`@' + The GDB "artificial array" operator (*note Expressions: + Expressions.). + +`+, -' + Addition and subtraction on integral and floating-point types, or + union and difference on set types. + +`*' + Multiplication on integral and floating-point types, or set + intersection on set types. + +`/' + Division on floating-point types, or symmetric set difference on + set types. Same precedence as `*'. + +`DIV, MOD' + Integer division and remainder. Defined on integral types. Same + precedence as `*'. + +`-' + Negative. Defined on `INTEGER' and `REAL' data. + +`^' + Pointer dereferencing. Defined on pointer types. + +`NOT' + Boolean negation. Defined on boolean types. Same precedence as + `^'. + +`.' + `RECORD' field selector. Defined on `RECORD' data. Same + precedence as `^'. + +`[]' + Array indexing. Defined on `ARRAY' data. Same precedence as `^'. + +`()' + Procedure argument list. Defined on `PROCEDURE' objects. Same + precedence as `^'. + +`::, .' + GDB and Modula-2 scope operators. + + _Warning:_ Sets and their operations are not yet supported, so GDB + treats the use of the operator `IN', or the use of operators `+', + `-', `*', `/', `=', , `<>', `#', `<=', and `>=' on sets as an + error. + + +File: gdb.info, Node: Built-In Func/Proc, Next: M2 Constants, Prev: M2 Operators, Up: Modula-2 + +Built-in functions and procedures +................................. + +Modula-2 also makes available several built-in procedures and functions. +In describing these, the following metavariables are used: + +A + represents an `ARRAY' variable. + +C + represents a `CHAR' constant or variable. + +I + represents a variable or constant of integral type. + +M + represents an identifier that belongs to a set. Generally used in + the same function with the metavariable S. The type of S should + be `SET OF MTYPE' (where MTYPE is the type of M). + +N + represents a variable or constant of integral or floating-point + type. + +R + represents a variable or constant of floating-point type. + +T + represents a type. + +V + represents a variable. + +X + represents a variable or constant of one of many types. See the + explanation of the function for details. + + All Modula-2 built-in procedures also return a result, described +below. + +`ABS(N)' + Returns the absolute value of N. + +`CAP(C)' + If C is a lower case letter, it returns its upper case equivalent, + otherwise it returns its argument. + +`CHR(I)' + Returns the character whose ordinal value is I. + +`DEC(V)' + Decrements the value in the variable V by one. Returns the new + value. + +`DEC(V,I)' + Decrements the value in the variable V by I. Returns the new + value. + +`EXCL(M,S)' + Removes the element M from the set S. Returns the new set. + +`FLOAT(I)' + Returns the floating point equivalent of the integer I. + +`HIGH(A)' + Returns the index of the last member of A. + +`INC(V)' + Increments the value in the variable V by one. Returns the new + value. + +`INC(V,I)' + Increments the value in the variable V by I. Returns the new + value. + +`INCL(M,S)' + Adds the element M to the set S if it is not already there. + Returns the new set. + +`MAX(T)' + Returns the maximum value of the type T. + +`MIN(T)' + Returns the minimum value of the type T. + +`ODD(I)' + Returns boolean TRUE if I is an odd number. + +`ORD(X)' + Returns the ordinal value of its argument. For example, the + ordinal value of a character is its ASCII value (on machines + supporting the ASCII character set). X must be of an ordered + type, which include integral, character and enumerated types. + +`SIZE(X)' + Returns the size of its argument. X can be a variable or a type. + +`TRUNC(R)' + Returns the integral part of R. + +`VAL(T,I)' + Returns the member of the type T whose ordinal value is I. + + _Warning:_ Sets and their operations are not yet supported, so + GDB treats the use of procedures `INCL' and `EXCL' as an error. + diff --git a/contrib/gdb/gdb/doc/gdb.info-2 b/contrib/gdb/gdb/doc/gdb.info-2 new file mode 100644 index 00000000000..4dcf4353b5b --- /dev/null +++ b/contrib/gdb/gdb/doc/gdb.info-2 @@ -0,0 +1,9133 @@ +This is gdb.info, produced by makeinfo version 4.6 from ./gdb.texinfo. + +INFO-DIR-SECTION Software development +START-INFO-DIR-ENTRY +* Gdb: (gdb). The GNU debugger. +END-INFO-DIR-ENTRY + + This file documents the GNU debugger GDB. + + This is the Ninth Edition, of `Debugging with GDB: the GNU +Source-Level Debugger' for GDB Version 6.1.1. + + Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, +1998, +1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with the +Invariant Sections being "Free Software" and "Free Software Needs Free +Documentation", with the Front-Cover Texts being "A GNU Manual," and +with the Back-Cover Texts as in (a) below. + + (a) The Free Software Foundation's Back-Cover Text is: "You have +freedom to copy and modify this GNU Manual, like GNU software. Copies +published by the Free Software Foundation raise funds for GNU +development." + + +File: gdb.info, Node: M2 Constants, Next: M2 Defaults, Prev: Built-In Func/Proc, Up: Modula-2 + +Constants +......... + +GDB allows you to express the constants of Modula-2 in the following +ways: + + * Integer constants are simply a sequence of digits. When used in an + expression, a constant is interpreted to be type-compatible with + the rest of the expression. Hexadecimal integers are specified by + a trailing `H', and octal integers by a trailing `B'. + + * Floating point constants appear as a sequence of digits, followed + by a decimal point and another sequence of digits. An optional + exponent can then be specified, in the form `E[+|-]NNN', where + `[+|-]NNN' is the desired exponent. All of the digits of the + floating point constant must be valid decimal (base 10) digits. + + * Character constants consist of a single character enclosed by a + pair of like quotes, either single (`'') or double (`"'). They may + also be expressed by their ordinal value (their ASCII value, + usually) followed by a `C'. + + * String constants consist of a sequence of characters enclosed by a + pair of like quotes, either single (`'') or double (`"'). Escape + sequences in the style of C are also allowed. *Note C and C++ + constants: C Constants, for a brief explanation of escape + sequences. + + * Enumerated constants consist of an enumerated identifier. + + * Boolean constants consist of the identifiers `TRUE' and `FALSE'. + + * Pointer constants consist of integral values only. + + * Set constants are not yet supported. + + +File: gdb.info, Node: M2 Defaults, Next: Deviations, Prev: M2 Constants, Up: Modula-2 + +Modula-2 defaults +................. + +If type and range checking are set automatically by GDB, they both +default to `on' whenever the working language changes to Modula-2. +This happens regardless of whether you or GDB selected the working +language. + + If you allow GDB to set the language automatically, then entering +code compiled from a file whose name ends with `.mod' sets the working +language to Modula-2. *Note Having GDB set the language automatically: +Automatically, for further details. + + +File: gdb.info, Node: Deviations, Next: M2 Checks, Prev: M2 Defaults, Up: Modula-2 + +Deviations from standard Modula-2 +................................. + +A few changes have been made to make Modula-2 programs easier to debug. +This is done primarily via loosening its type strictness: + + * Unlike in standard Modula-2, pointer constants can be formed by + integers. This allows you to modify pointer variables during + debugging. (In standard Modula-2, the actual address contained in + a pointer variable is hidden from you; it can only be modified + through direct assignment to another pointer variable or + expression that returned a pointer.) + + * C escape sequences can be used in strings and characters to + represent non-printable characters. GDB prints out strings with + these escape sequences embedded. Single non-printable characters + are printed using the `CHR(NNN)' format. + + * The assignment operator (`:=') returns the value of its right-hand + argument. + + * All built-in procedures both modify _and_ return their argument. + + +File: gdb.info, Node: M2 Checks, Next: M2 Scope, Prev: Deviations, Up: Modula-2 + +Modula-2 type and range checks +.............................. + + _Warning:_ in this release, GDB does not yet perform type or range + checking. + + GDB considers two Modula-2 variables type equivalent if: + + * They are of types that have been declared equivalent via a `TYPE + T1 = T2' statement + + * They have been declared on the same line. (Note: This is true of + the GNU Modula-2 compiler, but it may not be true of other + compilers.) + + As long as type checking is enabled, any attempt to combine variables +whose types are not equivalent is an error. + + Range checking is done on all mathematical operations, assignment, +array index bounds, and all built-in functions and procedures. + + +File: gdb.info, Node: M2 Scope, Next: GDB/M2, Prev: M2 Checks, Up: Modula-2 + +The scope operators `::' and `.' +................................ + +There are a few subtle differences between the Modula-2 scope operator +(`.') and the GDB scope operator (`::'). The two have similar syntax: + + + MODULE . ID + SCOPE :: ID + +where SCOPE is the name of a module or a procedure, MODULE the name of +a module, and ID is any declared identifier within your program, except +another module. + + Using the `::' operator makes GDB search the scope specified by +SCOPE for the identifier ID. If it is not found in the specified +scope, then GDB searches all scopes enclosing the one specified by +SCOPE. + + Using the `.' operator makes GDB search the current scope for the +identifier specified by ID that was imported from the definition module +specified by MODULE. With this operator, it is an error if the +identifier ID was not imported from definition module MODULE, or if ID +is not an identifier in MODULE. + + +File: gdb.info, Node: GDB/M2, Prev: M2 Scope, Up: Modula-2 + +GDB and Modula-2 +................ + +Some GDB commands have little use when debugging Modula-2 programs. +Five subcommands of `set print' and `show print' apply specifically to +C and C++: `vtbl', `demangle', `asm-demangle', `object', and `union'. +The first four apply to C++, and the last to the C `union' type, which +has no direct analogue in Modula-2. + + The `@' operator (*note Expressions: Expressions.), while available +with any language, is not useful with Modula-2. Its intent is to aid +the debugging of "dynamic arrays", which cannot be created in Modula-2 +as they can in C or C++. However, because an address can be specified +by an integral constant, the construct `{TYPE}ADREXP' is still useful. + + In GDB scripts, the Modula-2 inequality operator `#' is interpreted +as the beginning of a comment. Use `<>' instead. + + +File: gdb.info, Node: Unsupported languages, Prev: Support, Up: Languages + +Unsupported languages +===================== + +In addition to the other fully-supported programming languages, GDB +also provides a pseudo-language, called `minimal'. It does not +represent a real programming language, but provides a set of +capabilities close to what the C or assembly languages provide. This +should allow most simple operations to be performed while debugging an +application that uses a language currently not supported by GDB. + + If the language is set to `auto', GDB will automatically select this +language if the current frame corresponds to an unsupported language. + + +File: gdb.info, Node: Symbols, Next: Altering, Prev: Languages, Up: Top + +Examining the Symbol Table +************************** + +The commands described in this chapter allow you to inquire about the +symbols (names of variables, functions and types) defined in your +program. This information is inherent in the text of your program and +does not change as your program executes. GDB finds it in your +program's symbol table, in the file indicated when you started GDB +(*note Choosing files: File Options.), or by one of the file-management +commands (*note Commands to specify files: Files.). + + Occasionally, you may need to refer to symbols that contain unusual +characters, which GDB ordinarily treats as word delimiters. The most +frequent case is in referring to static variables in other source files +(*note Program variables: Variables.). File names are recorded in +object files as debugging symbols, but GDB would ordinarily parse a +typical file name, like `foo.c', as the three words `foo' `.' `c'. To +allow GDB to recognize `foo.c' as a single symbol, enclose it in single +quotes; for example, + + p 'foo.c'::x + +looks up the value of `x' in the scope of the file `foo.c'. + +`info address SYMBOL' + Describe where the data for SYMBOL is stored. For a register + variable, this says which register it is kept in. For a + non-register local variable, this prints the stack-frame offset at + which the variable is always stored. + + Note the contrast with `print &SYMBOL', which does not work at all + for a register variable, and for a stack local variable prints the + exact address of the current instantiation of the variable. + +`info symbol ADDR' + Print the name of a symbol which is stored at the address ADDR. + If no symbol is stored exactly at ADDR, GDB prints the nearest + symbol and an offset from it: + + (gdb) info symbol 0x54320 + _initialize_vx + 396 in section .text + + This is the opposite of the `info address' command. You can use + it to find out the name of a variable or a function given its + address. + +`whatis EXPR' + Print the data type of expression EXPR. EXPR is not actually + evaluated, and any side-effecting operations (such as assignments + or function calls) inside it do not take place. *Note + Expressions: Expressions. + +`whatis' + Print the data type of `$', the last value in the value history. + +`ptype TYPENAME' + Print a description of data type TYPENAME. TYPENAME may be the + name of a type, or for C code it may have the form `class + CLASS-NAME', `struct STRUCT-TAG', `union UNION-TAG' or `enum + ENUM-TAG'. + +`ptype EXPR' +`ptype' + Print a description of the type of expression EXPR. `ptype' + differs from `whatis' by printing a detailed description, instead + of just the name of the type. + + For example, for this variable declaration: + + struct complex {double real; double imag;} v; + + the two commands give this output: + + (gdb) whatis v + type = struct complex + (gdb) ptype v + type = struct complex { + double real; + double imag; + } + + As with `whatis', using `ptype' without an argument refers to the + type of `$', the last value in the value history. + +`info types REGEXP' +`info types' + Print a brief description of all types whose names match REGEXP + (or all types in your program, if you supply no argument). Each + complete typename is matched as though it were a complete line; + thus, `i type value' gives information on all types in your + program whose names include the string `value', but `i type + ^value$' gives information only on types whose complete name is + `value'. + + This command differs from `ptype' in two ways: first, like + `whatis', it does not print a detailed description; second, it + lists all source files where a type is defined. + +`info scope ADDR' + List all the variables local to a particular scope. This command + accepts a location--a function name, a source line, or an address + preceded by a `*', and prints all the variables local to the scope + defined by that location. For example: + + (gdb) info scope command_line_handler + Scope for command_line_handler: + Symbol rl is an argument at stack/frame offset 8, length 4. + Symbol linebuffer is in static storage at address 0x150a18, length 4. + Symbol linelength is in static storage at address 0x150a1c, length 4. + Symbol p is a local variable in register $esi, length 4. + Symbol p1 is a local variable in register $ebx, length 4. + Symbol nline is a local variable in register $edx, length 4. + Symbol repeat is a local variable at frame offset -8, length 4. + + This command is especially useful for determining what data to + collect during a "trace experiment", see *Note collect: Tracepoint + Actions. + +`info source' + Show information about the current source file--that is, the + source file for the function containing the current point of + execution: + * the name of the source file, and the directory containing it, + + * the directory it was compiled in, + + * its length, in lines, + + * which programming language it is written in, + + * whether the executable includes debugging information for + that file, and if so, what format the information is in + (e.g., STABS, Dwarf 2, etc.), and + + * whether the debugging information includes information about + preprocessor macros. + +`info sources' + Print the names of all source files in your program for which + there is debugging information, organized into two lists: files + whose symbols have already been read, and files whose symbols will + be read when needed. + +`info functions' + Print the names and data types of all defined functions. + +`info functions REGEXP' + Print the names and data types of all defined functions whose + names contain a match for regular expression REGEXP. Thus, `info + fun step' finds all functions whose names include `step'; `info + fun ^step' finds those whose names start with `step'. If a + function name contains characters that conflict with the regular + expression language (eg. `operator*()'), they may be quoted with + a backslash. + +`info variables' + Print the names and data types of all variables that are declared + outside of functions (i.e. excluding local variables). + +`info variables REGEXP' + Print the names and data types of all variables (except for local + variables) whose names contain a match for regular expression + REGEXP. + +`info classes' +`info classes REGEXP' + Display all Objective-C classes in your program, or (with the + REGEXP argument) all those matching a particular regular + expression. + +`info selectors' +`info selectors REGEXP' + Display all Objective-C selectors in your program, or (with the + REGEXP argument) all those matching a particular regular + expression. + + Some systems allow individual object files that make up your + program to be replaced without stopping and restarting your + program. For example, in VxWorks you can simply recompile a + defective object file and keep on running. If you are running on + one of these systems, you can allow GDB to reload the symbols for + automatically relinked modules: + + `set symbol-reloading on' + Replace symbol definitions for the corresponding source file + when an object file with a particular name is seen again. + + `set symbol-reloading off' + Do not replace symbol definitions when encountering object + files of the same name more than once. This is the default + state; if you are not running on a system that permits + automatic relinking of modules, you should leave + `symbol-reloading' off, since otherwise GDB may discard + symbols when linking large programs, that may contain several + modules (from different directories or libraries) with the + same name. + + `show symbol-reloading' + Show the current `on' or `off' setting. + +`set opaque-type-resolution on' + Tell GDB to resolve opaque types. An opaque type is a type + declared as a pointer to a `struct', `class', or `union'--for + example, `struct MyType *'--that is used in one source file + although the full declaration of `struct MyType' is in another + source file. The default is on. + + A change in the setting of this subcommand will not take effect + until the next time symbols for a file are loaded. + +`set opaque-type-resolution off' + Tell GDB not to resolve opaque types. In this case, the type is + printed as follows: + {} + +`show opaque-type-resolution' + Show whether opaque types are resolved or not. + +`maint print symbols FILENAME' +`maint print psymbols FILENAME' +`maint print msymbols FILENAME' + Write a dump of debugging symbol data into the file FILENAME. + These commands are used to debug the GDB symbol-reading code. Only + symbols with debugging data are included. If you use `maint print + symbols', GDB includes all the symbols for which it has already + collected full details: that is, FILENAME reflects symbols for + only those files whose symbols GDB has read. You can use the + command `info sources' to find out which files these are. If you + use `maint print psymbols' instead, the dump shows information + about symbols that GDB only knows partially--that is, symbols + defined in files that GDB has skimmed, but not yet read + completely. Finally, `maint print msymbols' dumps just the + minimal symbol information required for each object file from + which GDB has read some symbols. *Note Commands to specify files: + Files, for a discussion of how GDB reads symbols (in the + description of `symbol-file'). + +`maint info symtabs [ REGEXP ]' +`maint info psymtabs [ REGEXP ]' + List the `struct symtab' or `struct partial_symtab' structures + whose names match REGEXP. If REGEXP is not given, list them all. + The output includes expressions which you can copy into a GDB + debugging this one to examine a particular structure in more + detail. For example: + + (gdb) maint info psymtabs dwarf2read + { objfile /home/gnu/build/gdb/gdb + ((struct objfile *) 0x82e69d0) + { psymtab /home/gnu/src/gdb/dwarf2read.c + ((struct partial_symtab *) 0x8474b10) + readin no + fullname (null) + text addresses 0x814d3c8 -- 0x8158074 + globals (* (struct partial_symbol **) 0x8507a08 @ 9) + statics (* (struct partial_symbol **) 0x40e95b78 @ 2882) + dependencies (none) + } + } + (gdb) maint info symtabs + (gdb) + + We see that there is one partial symbol table whose filename + contains the string `dwarf2read', belonging to the `gdb' + executable; and we see that GDB has not read in any symtabs yet at + all. If we set a breakpoint on a function, that will cause GDB to + read the symtab for the compilation unit containing that function: + + (gdb) break dwarf2_psymtab_to_symtab + Breakpoint 1 at 0x814e5da: file /home/gnu/src/gdb/dwarf2read.c, + line 1574. + (gdb) maint info symtabs + { objfile /home/gnu/build/gdb/gdb + ((struct objfile *) 0x82e69d0) + { symtab /home/gnu/src/gdb/dwarf2read.c + ((struct symtab *) 0x86c1f38) + dirname (null) + fullname (null) + blockvector ((struct blockvector *) 0x86c1bd0) (primary) + debugformat DWARF 2 + } + } + (gdb) + + +File: gdb.info, Node: Altering, Next: GDB Files, Prev: Symbols, Up: Top + +Altering Execution +****************** + +Once you think you have found an error in your program, you might want +to find out for certain whether correcting the apparent error would +lead to correct results in the rest of the run. You can find the +answer by experiment, using the GDB features for altering execution of +the program. + + For example, you can store new values into variables or memory +locations, give your program a signal, restart it at a different +address, or even return prematurely from a function. + +* Menu: + +* Assignment:: Assignment to variables +* Jumping:: Continuing at a different address +* Signaling:: Giving your program a signal +* Returning:: Returning from a function +* Calling:: Calling your program's functions +* Patching:: Patching your program + + +File: gdb.info, Node: Assignment, Next: Jumping, Up: Altering + +Assignment to variables +======================= + +To alter the value of a variable, evaluate an assignment expression. +*Note Expressions: Expressions. For example, + + print x=4 + +stores the value 4 into the variable `x', and then prints the value of +the assignment expression (which is 4). *Note Using GDB with Different +Languages: Languages, for more information on operators in supported +languages. + + If you are not interested in seeing the value of the assignment, use +the `set' command instead of the `print' command. `set' is really the +same as `print' except that the expression's value is not printed and +is not put in the value history (*note Value history: Value History.). +The expression is evaluated only for its effects. + + If the beginning of the argument string of the `set' command appears +identical to a `set' subcommand, use the `set variable' command instead +of just `set'. This command is identical to `set' except for its lack +of subcommands. For example, if your program has a variable `width', +you get an error if you try to set a new value with just `set +width=13', because GDB has the command `set width': + + (gdb) whatis width + type = double + (gdb) p width + $4 = 13 + (gdb) set width=47 + Invalid syntax in expression. + +The invalid expression, of course, is `=47'. In order to actually set +the program's variable `width', use + + (gdb) set var width=47 + + Because the `set' command has many subcommands that can conflict +with the names of program variables, it is a good idea to use the `set +variable' command instead of just `set'. For example, if your program +has a variable `g', you run into problems if you try to set a new value +with just `set g=4', because GDB has the command `set gnutarget', +abbreviated `set g': + + (gdb) whatis g + type = double + (gdb) p g + $1 = 1 + (gdb) set g=4 + (gdb) p g + $2 = 1 + (gdb) r + The program being debugged has been started already. + Start it from the beginning? (y or n) y + Starting program: /home/smith/cc_progs/a.out + "/home/smith/cc_progs/a.out": can't open to read symbols: + Invalid bfd target. + (gdb) show g + The current BFD target is "=4". + +The program variable `g' did not change, and you silently set the +`gnutarget' to an invalid value. In order to set the variable `g', use + + (gdb) set var g=4 + + GDB allows more implicit conversions in assignments than C; you can +freely store an integer value into a pointer variable or vice versa, +and you can convert any structure to any other structure that is the +same length or shorter. + + To store values into arbitrary places in memory, use the `{...}' +construct to generate a value of specified type at a specified address +(*note Expressions: Expressions.). For example, `{int}0x83040' refers +to memory location `0x83040' as an integer (which implies a certain size +and representation in memory), and + + set {int}0x83040 = 4 + +stores the value 4 into that memory location. + + +File: gdb.info, Node: Jumping, Next: Signaling, Prev: Assignment, Up: Altering + +Continuing at a different address +================================= + +Ordinarily, when you continue your program, you do so at the place where +it stopped, with the `continue' command. You can instead continue at +an address of your own choosing, with the following commands: + +`jump LINESPEC' + Resume execution at line LINESPEC. Execution stops again + immediately if there is a breakpoint there. *Note Printing source + lines: List, for a description of the different forms of LINESPEC. + It is common practice to use the `tbreak' command in conjunction + with `jump'. *Note Setting breakpoints: Set Breaks. + + The `jump' command does not change the current stack frame, or the + stack pointer, or the contents of any memory location or any + register other than the program counter. If line LINESPEC is in a + different function from the one currently executing, the results + may be bizarre if the two functions expect different patterns of + arguments or of local variables. For this reason, the `jump' + command requests confirmation if the specified line is not in the + function currently executing. However, even bizarre results are + predictable if you are well acquainted with the machine-language + code of your program. + +`jump *ADDRESS' + Resume execution at the instruction at address ADDRESS. + + On many systems, you can get much the same effect as the `jump' +command by storing a new value into the register `$pc'. The difference +is that this does not start your program running; it only changes the +address of where it _will_ run when you continue. For example, + + set $pc = 0x485 + +makes the next `continue' command or stepping command execute at +address `0x485', rather than at the address where your program stopped. +*Note Continuing and stepping: Continuing and Stepping. + + The most common occasion to use the `jump' command is to back +up--perhaps with more breakpoints set--over a portion of a program that +has already executed, in order to examine its execution in more detail. + + +File: gdb.info, Node: Signaling, Next: Returning, Prev: Jumping, Up: Altering + +Giving your program a signal +============================ + +`signal SIGNAL' + Resume execution where your program stopped, but immediately give + it the signal SIGNAL. SIGNAL can be the name or the number of a + signal. For example, on many systems `signal 2' and `signal + SIGINT' are both ways of sending an interrupt signal. + + Alternatively, if SIGNAL is zero, continue execution without + giving a signal. This is useful when your program stopped on + account of a signal and would ordinary see the signal when resumed + with the `continue' command; `signal 0' causes it to resume + without a signal. + + `signal' does not repeat when you press a second time after + executing the command. + + Invoking the `signal' command is not the same as invoking the `kill' +utility from the shell. Sending a signal with `kill' causes GDB to +decide what to do with the signal depending on the signal handling +tables (*note Signals::). The `signal' command passes the signal +directly to your program. + + +File: gdb.info, Node: Returning, Next: Calling, Prev: Signaling, Up: Altering + +Returning from a function +========================= + +`return' +`return EXPRESSION' + You can cancel execution of a function call with the `return' + command. If you give an EXPRESSION argument, its value is used as + the function's return value. + + When you use `return', GDB discards the selected stack frame (and +all frames within it). You can think of this as making the discarded +frame return prematurely. If you wish to specify a value to be +returned, give that value as the argument to `return'. + + This pops the selected stack frame (*note Selecting a frame: +Selection.), and any other frames inside of it, leaving its caller as +the innermost remaining frame. That frame becomes selected. The +specified value is stored in the registers used for returning values of +functions. + + The `return' command does not resume execution; it leaves the +program stopped in the state that would exist if the function had just +returned. In contrast, the `finish' command (*note Continuing and +stepping: Continuing and Stepping.) resumes execution until the +selected stack frame returns naturally. + + +File: gdb.info, Node: Calling, Next: Patching, Prev: Returning, Up: Altering + +Calling program functions +========================= + +`call EXPR' + Evaluate the expression EXPR without displaying `void' returned + values. + + You can use this variant of the `print' command if you want to +execute a function from your program, but without cluttering the output +with `void' returned values. If the result is not void, it is printed +and saved in the value history. + + +File: gdb.info, Node: Patching, Prev: Calling, Up: Altering + +Patching programs +================= + +By default, GDB opens the file containing your program's executable +code (or the corefile) read-only. This prevents accidental alterations +to machine code; but it also prevents you from intentionally patching +your program's binary. + + If you'd like to be able to patch the binary, you can specify that +explicitly with the `set write' command. For example, you might want +to turn on internal debugging flags, or even to make emergency repairs. + +`set write on' +`set write off' + If you specify `set write on', GDB opens executable and core files + for both reading and writing; if you specify `set write off' (the + default), GDB opens them read-only. + + If you have already loaded a file, you must load it again (using + the `exec-file' or `core-file' command) after changing `set + write', for your new setting to take effect. + +`show write' + Display whether executable files and core files are opened for + writing as well as reading. + + +File: gdb.info, Node: GDB Files, Next: Targets, Prev: Altering, Up: Top + +GDB Files +********* + +GDB needs to know the file name of the program to be debugged, both in +order to read its symbol table and in order to start your program. To +debug a core dump of a previous run, you must also tell GDB the name of +the core dump file. + +* Menu: + +* Files:: Commands to specify files +* Separate Debug Files:: Debugging information in separate files +* Symbol Errors:: Errors reading symbol files + + +File: gdb.info, Node: Files, Next: Separate Debug Files, Up: GDB Files + +Commands to specify files +========================= + +You may want to specify executable and core dump file names. The usual +way to do this is at start-up time, using the arguments to GDB's +start-up commands (*note Getting In and Out of GDB: Invocation.). + + Occasionally it is necessary to change to a different file during a +GDB session. Or you may run GDB and forget to specify a file you want +to use. In these situations the GDB commands to specify new files are +useful. + +`file FILENAME' + Use FILENAME as the program to be debugged. It is read for its + symbols and for the contents of pure memory. It is also the + program executed when you use the `run' command. If you do not + specify a directory and the file is not found in the GDB working + directory, GDB uses the environment variable `PATH' as a list of + directories to search, just as the shell does when looking for a + program to run. You can change the value of this variable, for + both GDB and your program, using the `path' command. + + On systems with memory-mapped files, an auxiliary file named + `FILENAME.syms' may hold symbol table information for FILENAME. + If so, GDB maps in the symbol table from `FILENAME.syms', starting + up more quickly. See the descriptions of the file options + `-mapped' and `-readnow' (available on the command line, and with + the commands `file', `symbol-file', or `add-symbol-file', + described below), for more information. + +`file' + `file' with no argument makes GDB discard any information it has + on both executable file and the symbol table. + +`exec-file [ FILENAME ]' + Specify that the program to be run (but not the symbol table) is + found in FILENAME. GDB searches the environment variable `PATH' + if necessary to locate your program. Omitting FILENAME means to + discard information on the executable file. + +`symbol-file [ FILENAME ]' + Read symbol table information from file FILENAME. `PATH' is + searched when necessary. Use the `file' command to get both symbol + table and program to run from the same file. + + `symbol-file' with no argument clears out GDB information on your + program's symbol table. + + The `symbol-file' command causes GDB to forget the contents of its + convenience variables, the value history, and all breakpoints and + auto-display expressions. This is because they may contain + pointers to the internal data recording symbols and data types, + which are part of the old symbol table data being discarded inside + GDB. + + `symbol-file' does not repeat if you press again after + executing it once. + + When GDB is configured for a particular environment, it + understands debugging information in whatever format is the + standard generated for that environment; you may use either a GNU + compiler, or other compilers that adhere to the local conventions. + Best results are usually obtained from GNU compilers; for example, + using `gcc' you can generate debugging information for optimized + code. + + For most kinds of object files, with the exception of old SVR3 + systems using COFF, the `symbol-file' command does not normally + read the symbol table in full right away. Instead, it scans the + symbol table quickly to find which source files and which symbols + are present. The details are read later, one source file at a + time, as they are needed. + + The purpose of this two-stage reading strategy is to make GDB + start up faster. For the most part, it is invisible except for + occasional pauses while the symbol table details for a particular + source file are being read. (The `set verbose' command can turn + these pauses into messages if desired. *Note Optional warnings + and messages: Messages/Warnings.) + + We have not implemented the two-stage strategy for COFF yet. When + the symbol table is stored in COFF format, `symbol-file' reads the + symbol table data in full right away. Note that "stabs-in-COFF" + still does the two-stage strategy, since the debug info is actually + in stabs format. + +`symbol-file FILENAME [ -readnow ] [ -mapped ]' +`file FILENAME [ -readnow ] [ -mapped ]' + You can override the GDB two-stage strategy for reading symbol + tables by using the `-readnow' option with any of the commands that + load symbol table information, if you want to be sure GDB has the + entire symbol table available. + + If memory-mapped files are available on your system through the + `mmap' system call, you can use another option, `-mapped', to + cause GDB to write the symbols for your program into a reusable + file. Future GDB debugging sessions map in symbol information + from this auxiliary symbol file (if the program has not changed), + rather than spending time reading the symbol table from the + executable program. Using the `-mapped' option has the same + effect as starting GDB with the `-mapped' command-line option. + + You can use both options together, to make sure the auxiliary + symbol file has all the symbol information for your program. + + The auxiliary symbol file for a program called MYPROG is called + `MYPROG.syms'. Once this file exists (so long as it is newer than + the corresponding executable), GDB always attempts to use it when + you debug MYPROG; no special options or commands are needed. + + The `.syms' file is specific to the host machine where you run + GDB. It holds an exact image of the internal GDB symbol table. + It cannot be shared across multiple host platforms. + +`core-file [ FILENAME ]' + Specify the whereabouts of a core dump file to be used as the + "contents of memory". Traditionally, core files contain only some + parts of the address space of the process that generated them; GDB + can access the executable file itself for other parts. + + `core-file' with no argument specifies that no core file is to be + used. + + Note that the core file is ignored when your program is actually + running under GDB. So, if you have been running your program and + you wish to debug a core file instead, you must kill the + subprocess in which the program is running. To do this, use the + `kill' command (*note Killing the child process: Kill Process.). + +`add-symbol-file FILENAME ADDRESS' +`add-symbol-file FILENAME ADDRESS [ -readnow ] [ -mapped ]' +`add-symbol-file FILENAME -sSECTION ADDRESS ...' + The `add-symbol-file' command reads additional symbol table + information from the file FILENAME. You would use this command + when FILENAME has been dynamically loaded (by some other means) + into the program that is running. ADDRESS should be the memory + address at which the file has been loaded; GDB cannot figure this + out for itself. You can additionally specify an arbitrary number + of `-sSECTION ADDRESS' pairs, to give an explicit section name and + base address for that section. You can specify any ADDRESS as an + expression. + + The symbol table of the file FILENAME is added to the symbol table + originally read with the `symbol-file' command. You can use the + `add-symbol-file' command any number of times; the new symbol data + thus read keeps adding to the old. To discard all old symbol data + instead, use the `symbol-file' command without any arguments. + + Although FILENAME is typically a shared library file, an + executable file, or some other object file which has been fully + relocated for loading into a process, you can also load symbolic + information from relocatable `.o' files, as long as: + + * the file's symbolic information refers only to linker symbols + defined in that file, not to symbols defined by other object + files, + + * every section the file's symbolic information refers to has + actually been loaded into the inferior, as it appears in the + file, and + + * you can determine the address at which every section was + loaded, and provide these to the `add-symbol-file' command. + + Some embedded operating systems, like Sun Chorus and VxWorks, can + load relocatable files into an already running program; such + systems typically make the requirements above easy to meet. + However, it's important to recognize that many native systems use + complex link procedures (`.linkonce' section factoring and C++ + constructor table assembly, for example) that make the + requirements difficult to meet. In general, one cannot assume + that using `add-symbol-file' to read a relocatable object file's + symbolic information will have the same effect as linking the + relocatable object file into the program in the normal way. + + `add-symbol-file' does not repeat if you press after using + it. + + You can use the `-mapped' and `-readnow' options just as with the + `symbol-file' command, to change how GDB manages the symbol table + information for FILENAME. + +`add-shared-symbol-file' + The `add-shared-symbol-file' command can be used only under + Harris' CXUX operating system for the Motorola 88k. GDB + automatically looks for shared libraries, however if GDB does not + find yours, you can run `add-shared-symbol-file'. It takes no + arguments. + +`section' + The `section' command changes the base address of section SECTION + of the exec file to ADDR. This can be used if the exec file does + not contain section addresses, (such as in the a.out format), or + when the addresses specified in the file itself are wrong. Each + section must be changed separately. The `info files' command, + described below, lists all the sections and their addresses. + +`info files' +`info target' + `info files' and `info target' are synonymous; both print the + current target (*note Specifying a Debugging Target: Targets.), + including the names of the executable and core dump files + currently in use by GDB, and the files from which symbols were + loaded. The command `help target' lists all possible targets + rather than current ones. + +`maint info sections' + Another command that can give you extra information about program + sections is `maint info sections'. In addition to the section + information displayed by `info files', this command displays the + flags and file offset of each section in the executable and core + dump files. In addition, `maint info sections' provides the + following command options (which may be arbitrarily combined): + + `ALLOBJ' + Display sections for all loaded object files, including + shared libraries. + + `SECTIONS' + Display info only for named SECTIONS. + + `SECTION-FLAGS' + Display info only for sections for which SECTION-FLAGS are + true. The section flags that GDB currently knows about are: + `ALLOC' + Section will have space allocated in the process when + loaded. Set for all sections except those containing + debug information. + + `LOAD' + Section will be loaded from the file into the child + process memory. Set for pre-initialized code and data, + clear for `.bss' sections. + + `RELOC' + Section needs to be relocated before loading. + + `READONLY' + Section cannot be modified by the child process. + + `CODE' + Section contains executable code only. + + `DATA' + Section contains data only (no executable code). + + `ROM' + Section will reside in ROM. + + `CONSTRUCTOR' + Section contains data for constructor/destructor lists. + + `HAS_CONTENTS' + Section is not empty. + + `NEVER_LOAD' + An instruction to the linker to not output the section. + + `COFF_SHARED_LIBRARY' + A notification to the linker that the section contains + COFF shared library information. + + `IS_COMMON' + Section contains common symbols. + +`set trust-readonly-sections on' + Tell GDB that readonly sections in your object file really are + read-only (i.e. that their contents will not change). In that + case, GDB can fetch values from these sections out of the object + file, rather than from the target program. For some targets + (notably embedded ones), this can be a significant enhancement to + debugging performance. + + The default is off. + +`set trust-readonly-sections off' + Tell GDB not to trust readonly sections. This means that the + contents of the section might change while the program is running, + and must therefore be fetched from the target when needed. + + All file-specifying commands allow both absolute and relative file +names as arguments. GDB always converts the file name to an absolute +file name and remembers it that way. + + GDB supports HP-UX, SunOS, SVr4, Irix 5, and IBM RS/6000 shared +libraries. + + GDB automatically loads symbol definitions from shared libraries +when you use the `run' command, or when you examine a core file. +(Before you issue the `run' command, GDB does not understand references +to a function in a shared library, however--unless you are debugging a +core file). + + On HP-UX, if the program loads a library explicitly, GDB +automatically loads the symbols at the time of the `shl_load' call. + + There are times, however, when you may wish to not automatically load +symbol definitions from shared libraries, such as when they are +particularly large or there are many of them. + + To control the automatic loading of shared library symbols, use the +commands: + +`set auto-solib-add MODE' + If MODE is `on', symbols from all shared object libraries will be + loaded automatically when the inferior begins execution, you + attach to an independently started inferior, or when the dynamic + linker informs GDB that a new library has been loaded. If MODE is + `off', symbols must be loaded manually, using the `sharedlibrary' + command. The default value is `on'. + +`show auto-solib-add' + Display the current autoloading mode. + + To explicitly load shared library symbols, use the `sharedlibrary' +command: + +`info share' +`info sharedlibrary' + Print the names of the shared libraries which are currently loaded. + +`sharedlibrary REGEX' +`share REGEX' + Load shared object library symbols for files matching a Unix + regular expression. As with files loaded automatically, it only + loads shared libraries required by your program for a core file or + after typing `run'. If REGEX is omitted all shared libraries + required by your program are loaded. + + On some systems, such as HP-UX systems, GDB supports autoloading +shared library symbols until a limiting threshold size is reached. +This provides the benefit of allowing autoloading to remain on by +default, but avoids autoloading excessively large shared libraries, up +to a threshold that is initially set, but which you can modify if you +wish. + + Beyond that threshold, symbols from shared libraries must be +explicitly loaded. To load these symbols, use the command +`sharedlibrary FILENAME'. The base address of the shared library is +determined automatically by GDB and need not be specified. + + To display or set the threshold, use the commands: + +`set auto-solib-limit THRESHOLD' + Set the autoloading size threshold, in an integral number of + megabytes. If THRESHOLD is nonzero and shared library autoloading + is enabled, symbols from all shared object libraries will be + loaded until the total size of the loaded shared library symbols + exceeds this threshold. Otherwise, symbols must be loaded + manually, using the `sharedlibrary' command. The default + threshold is 100 (i.e. 100 Mb). + +`show auto-solib-limit' + Display the current autoloading size threshold, in megabytes. + + Shared libraries are also supported in many cross or remote debugging +configurations. A copy of the target's libraries need to be present on +the host system; they need to be the same as the target libraries, +although the copies on the target can be stripped as long as the copies +on the host are not. + + You need to tell GDB where the target libraries are, so that it can +load the correct copies--otherwise, it may try to load the host's +libraries. GDB has two variables to specify the search directories for +target libraries. + +`set solib-absolute-prefix PATH' + If this variable is set, PATH will be used as a prefix for any + absolute shared library paths; many runtime loaders store the + absolute paths to the shared library in the target program's + memory. If you use `solib-absolute-prefix' to find shared + libraries, they need to be laid out in the same way that they are + on the target, with e.g. a `/usr/lib' hierarchy under PATH. + + You can set the default value of `solib-absolute-prefix' by using + the configure-time `--with-sysroot' option. + +`show solib-absolute-prefix' + Display the current shared library prefix. + +`set solib-search-path PATH' + If this variable is set, PATH is a colon-separated list of + directories to search for shared libraries. `solib-search-path' + is used after `solib-absolute-prefix' fails to locate the library, + or if the path to the library is relative instead of absolute. If + you want to use `solib-search-path' instead of + `solib-absolute-prefix', be sure to set `solib-absolute-prefix' to + a nonexistant directory to prevent GDB from finding your host's + libraries. + +`show solib-search-path' + Display the current shared library search path. + + +File: gdb.info, Node: Separate Debug Files, Next: Symbol Errors, Prev: Files, Up: GDB Files + +Debugging Information in Separate Files +======================================= + +GDB allows you to put a program's debugging information in a file +separate from the executable itself, in a way that allows GDB to find +and load the debugging information automatically. Since debugging +information can be very large -- sometimes larger than the executable +code itself -- some systems distribute debugging information for their +executables in separate files, which users can install only when they +need to debug a problem. + + If an executable's debugging information has been extracted to a +separate file, the executable should contain a "debug link" giving the +name of the debugging information file (with no directory components), +and a checksum of its contents. (The exact form of a debug link is +described below.) If the full name of the directory containing the +executable is EXECDIR, and the executable has a debug link that +specifies the name DEBUGFILE, then GDB will automatically search for +the debugging information file in three places: + + * the directory containing the executable file (that is, it will look + for a file named `EXECDIR/DEBUGFILE', + + * a subdirectory of that directory named `.debug' (that is, the file + `EXECDIR/.debug/DEBUGFILE', and + + * a subdirectory of the global debug file directory that includes the + executable's full path, and the name from the link (that is, the + file `GLOBALDEBUGDIR/EXECDIR/DEBUGFILE', where GLOBALDEBUGDIR is + the global debug file directory, and EXECDIR has been turned into + a relative path). + +GDB checks under each of these names for a debugging information file +whose checksum matches that given in the link, and reads the debugging +information from the first one it finds. + + So, for example, if you ask GDB to debug `/usr/bin/ls', which has a +link containing the name `ls.debug', and the global debug directory is +`/usr/lib/debug', then GDB will look for debug information in +`/usr/bin/ls.debug', `/usr/bin/.debug/ls.debug', and +`/usr/lib/debug/usr/bin/ls.debug'. + + You can set the global debugging info directory's name, and view the +name GDB is currently using. + +`set debug-file-directory DIRECTORY' + Set the directory which GDB searches for separate debugging + information files to DIRECTORY. + +`show debug-file-directory' + Show the directory GDB searches for separate debugging information + files. + + + A debug link is a special section of the executable file named +`.gnu_debuglink'. The section must contain: + + * A filename, with any leading directory components removed, + followed by a zero byte, + + * zero to three bytes of padding, as needed to reach the next + four-byte boundary within the section, and + + * a four-byte CRC checksum, stored in the same endianness used for + the executable file itself. The checksum is computed on the + debugging information file's full contents by the function given + below, passing zero as the CRC argument. + + Any executable file format can carry a debug link, as long as it can +contain a section named `.gnu_debuglink' with the contents described +above. + + The debugging information file itself should be an ordinary +executable, containing a full set of linker symbols, sections, and +debugging information. The sections of the debugging information file +should have the same names, addresses and sizes as the original file, +but they need not contain any data -- much like a `.bss' section in an +ordinary executable. + + As of December 2002, there is no standard GNU utility to produce +separated executable / debugging information file pairs. Ulrich +Drepper's `elfutils' package, starting with version 0.53, contains a +version of the `strip' command such that the command `strip foo -f +foo.debug' removes the debugging information from the executable file +`foo', places it in the file `foo.debug', and leaves behind a debug +link in `foo'. + + Since there are many different ways to compute CRC's (different +polynomials, reversals, byte ordering, etc.), the simplest way to +describe the CRC used in `.gnu_debuglink' sections is to give the +complete code for a function that computes it: + + unsigned long + gnu_debuglink_crc32 (unsigned long crc, + unsigned char *buf, size_t len) + { + static const unsigned long crc32_table[256] = + { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d + }; + unsigned char *end; + + crc = ~crc & 0xffffffff; + for (end = buf + len; buf < end; ++buf) + crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); + return ~crc & 0xffffffff; + } + + +File: gdb.info, Node: Symbol Errors, Prev: Separate Debug Files, Up: GDB Files + +Errors reading symbol files +=========================== + +While reading a symbol file, GDB occasionally encounters problems, such +as symbol types it does not recognize, or known bugs in compiler +output. By default, GDB does not notify you of such problems, since +they are relatively common and primarily of interest to people +debugging compilers. If you are interested in seeing information about +ill-constructed symbol tables, you can either ask GDB to print only one +message about each such type of problem, no matter how many times the +problem occurs; or you can ask GDB to print more messages, to see how +many times the problems occur, with the `set complaints' command (*note +Optional warnings and messages: Messages/Warnings.). + + The messages currently printed, and their meanings, include: + +`inner block not inside outer block in SYMBOL' + The symbol information shows where symbol scopes begin and end + (such as at the start of a function or a block of statements). + This error indicates that an inner scope block is not fully + contained in its outer scope blocks. + + GDB circumvents the problem by treating the inner block as if it + had the same scope as the outer block. In the error message, + SYMBOL may be shown as "`(don't know)'" if the outer block is not a + function. + +`block at ADDRESS out of order' + The symbol information for symbol scope blocks should occur in + order of increasing addresses. This error indicates that it does + not do so. + + GDB does not circumvent this problem, and has trouble locating + symbols in the source file whose symbols it is reading. (You can + often determine what source file is affected by specifying `set + verbose on'. *Note Optional warnings and messages: + Messages/Warnings.) + +`bad block start address patched' + The symbol information for a symbol scope block has a start address + smaller than the address of the preceding source line. This is + known to occur in the SunOS 4.1.1 (and earlier) C compiler. + + GDB circumvents the problem by treating the symbol scope block as + starting on the previous source line. + +`bad string table offset in symbol N' + Symbol number N contains a pointer into the string table which is + larger than the size of the string table. + + GDB circumvents the problem by considering the symbol to have the + name `foo', which may cause other problems if many symbols end up + with this name. + +`unknown symbol type `0xNN'' + The symbol information contains new data types that GDB does not + yet know how to read. `0xNN' is the symbol type of the + uncomprehended information, in hexadecimal. + + GDB circumvents the error by ignoring this symbol information. + This usually allows you to debug your program, though certain + symbols are not accessible. If you encounter such a problem and + feel like debugging it, you can debug `gdb' with itself, breakpoint + on `complain', then go up to the function `read_dbx_symtab' and + examine `*bufp' to see the symbol. + +`stub type has NULL name' + GDB could not find the full definition for a struct or class. + +`const/volatile indicator missing (ok if using g++ v1.x), got...' + The symbol information for a C++ member function is missing some + information that recent versions of the compiler should have + output for it. + +`info mismatch between compiler and debugger' + GDB could not parse a type specification output by the compiler. + + + +File: gdb.info, Node: Targets, Next: Remote Debugging, Prev: GDB Files, Up: Top + +Specifying a Debugging Target +***************************** + +A "target" is the execution environment occupied by your program. + + Often, GDB runs in the same host environment as your program; in +that case, the debugging target is specified as a side effect when you +use the `file' or `core' commands. When you need more flexibility--for +example, running GDB on a physically separate host, or controlling a +standalone system over a serial port or a realtime system over a TCP/IP +connection--you can use the `target' command to specify one of the +target types configured for GDB (*note Commands for managing targets: +Target Commands.). + +* Menu: + +* Active Targets:: Active targets +* Target Commands:: Commands for managing targets +* Byte Order:: Choosing target byte order +* Remote:: Remote debugging +* KOD:: Kernel Object Display + + +File: gdb.info, Node: Active Targets, Next: Target Commands, Up: Targets + +Active targets +============== + +There are three classes of targets: processes, core files, and +executable files. GDB can work concurrently on up to three active +targets, one in each class. This allows you to (for example) start a +process and inspect its activity without abandoning your work on a core +file. + + For example, if you execute `gdb a.out', then the executable file +`a.out' is the only active target. If you designate a core file as +well--presumably from a prior run that crashed and coredumped--then GDB +has two active targets and uses them in tandem, looking first in the +corefile target, then in the executable file, to satisfy requests for +memory addresses. (Typically, these two classes of target are +complementary, since core files contain only a program's read-write +memory--variables and so on--plus machine status, while executable +files contain only the program text and initialized data.) + + When you type `run', your executable file becomes an active process +target as well. When a process target is active, all GDB commands +requesting memory addresses refer to that target; addresses in an +active core file or executable file target are obscured while the +process target is active. + + Use the `core-file' and `exec-file' commands to select a new core +file or executable target (*note Commands to specify files: Files.). +To specify as a target a process that is already running, use the +`attach' command (*note Debugging an already-running process: Attach.). + + +File: gdb.info, Node: Target Commands, Next: Byte Order, Prev: Active Targets, Up: Targets + +Commands for managing targets +============================= + +`target TYPE PARAMETERS' + Connects the GDB host environment to a target machine or process. + A target is typically a protocol for talking to debugging + facilities. You use the argument TYPE to specify the type or + protocol of the target machine. + + Further PARAMETERS are interpreted by the target protocol, but + typically include things like device names or host names to connect + with, process numbers, and baud rates. + + The `target' command does not repeat if you press again + after executing the command. + +`help target' + Displays the names of all targets available. To display targets + currently selected, use either `info target' or `info files' + (*note Commands to specify files: Files.). + +`help target NAME' + Describe a particular target, including any parameters necessary to + select it. + +`set gnutarget ARGS' + GDB uses its own library BFD to read your files. GDB knows + whether it is reading an "executable", a "core", or a ".o" file; + however, you can specify the file format with the `set gnutarget' + command. Unlike most `target' commands, with `gnutarget' the + `target' refers to a program, not a machine. + + _Warning:_ To specify a file format with `set gnutarget', you + must know the actual BFD name. + + *Note Commands to specify files: Files. + +`show gnutarget' + Use the `show gnutarget' command to display what file format + `gnutarget' is set to read. If you have not set `gnutarget', GDB + will determine the file format for each file automatically, and + `show gnutarget' displays `The current BDF target is "auto"'. + + Here are some common targets (available, or not, depending on the GDB +configuration): + +`target exec PROGRAM' + An executable file. `target exec PROGRAM' is the same as + `exec-file PROGRAM'. + +`target core FILENAME' + A core dump file. `target core FILENAME' is the same as + `core-file FILENAME'. + +`target remote DEV' + Remote serial target in GDB-specific protocol. The argument DEV + specifies what serial device to use for the connection (e.g. + `/dev/ttya'). *Note Remote debugging: Remote. `target remote' + supports the `load' command. This is only useful if you have some + other way of getting the stub to the target system, and you can put + it somewhere in memory where it won't get clobbered by the + download. + +`target sim' + Builtin CPU simulator. GDB includes simulators for most + architectures. In general, + target sim + load + run + + works; however, you cannot assume that a specific memory map, + device drivers, or even basic I/O is available, although some + simulators do provide these. For info about any + processor-specific simulator details, see the appropriate section + in *Note Embedded Processors: Embedded Processors. + + + Some configurations may include these targets as well: + +`target nrom DEV' + NetROM ROM emulator. This target only supports downloading. + + + Different targets are available on different configurations of GDB; +your configuration may have more or fewer targets. + + Many remote targets require you to download the executable's code +once you've successfully established a connection. + +`load FILENAME' + Depending on what remote debugging facilities are configured into + GDB, the `load' command may be available. Where it exists, it is + meant to make FILENAME (an executable) available for debugging on + the remote system--by downloading, or dynamic linking, for example. + `load' also records the FILENAME symbol table in GDB, like the + `add-symbol-file' command. + + If your GDB does not have a `load' command, attempting to execute + it gets the error message "`You can't do that when your target is + ...'" + + The file is loaded at whatever address is specified in the + executable. For some object file formats, you can specify the + load address when you link the program; for other formats, like + a.out, the object file format specifies a fixed address. + + `load' does not repeat if you press again after using it. + + +File: gdb.info, Node: Byte Order, Next: Remote, Prev: Target Commands, Up: Targets + +Choosing target byte order +========================== + +Some types of processors, such as the MIPS, PowerPC, and Renesas SH, +offer the ability to run either big-endian or little-endian byte +orders. Usually the executable or symbol will include a bit to +designate the endian-ness, and you will not need to worry about which +to use. However, you may still find it useful to adjust GDB's idea of +processor endian-ness manually. + +`set endian big' + Instruct GDB to assume the target is big-endian. + +`set endian little' + Instruct GDB to assume the target is little-endian. + +`set endian auto' + Instruct GDB to use the byte order associated with the executable. + +`show endian' + Display GDB's current idea of the target byte order. + + + Note that these commands merely adjust interpretation of symbolic +data on the host, and that they have absolutely no effect on the target +system. + + +File: gdb.info, Node: Remote, Next: KOD, Prev: Byte Order, Up: Targets + +Remote debugging +================ + +If you are trying to debug a program running on a machine that cannot +run GDB in the usual way, it is often useful to use remote debugging. +For example, you might use remote debugging on an operating system +kernel, or on a small system which does not have a general purpose +operating system powerful enough to run a full-featured debugger. + + Some configurations of GDB have special serial or TCP/IP interfaces +to make this work with particular debugging targets. In addition, GDB +comes with a generic serial protocol (specific to GDB, but not specific +to any particular target system) which you can use if you write the +remote stubs--the code that runs on the remote system to communicate +with GDB. + + Other remote targets may be available in your configuration of GDB; +use `help target' to list them. + + +File: gdb.info, Node: KOD, Prev: Remote, Up: Targets + +Kernel Object Display +===================== + +Some targets support kernel object display. Using this facility, GDB +communicates specially with the underlying operating system and can +display information about operating system-level objects such as +mutexes and other synchronization objects. Exactly which objects can be +displayed is determined on a per-OS basis. + + Use the `set os' command to set the operating system. This tells +GDB which kernel object display module to initialize: + + (gdb) set os cisco + + The associated command `show os' displays the operating system set +with the `set os' command; if no operating system has been set, `show +os' will display an empty string `""'. + + If `set os' succeeds, GDB will display some information about the +operating system, and will create a new `info' command which can be +used to query the target. The `info' command is named after the +operating system: + + (gdb) info cisco + List of Cisco Kernel Objects + Object Description + any Any and all objects + + Further subcommands can be used to query about particular objects +known by the kernel. + + There is currently no way to determine whether a given operating +system is supported other than to try setting it with `set os NAME', +where NAME is the name of the operating system you want to try. + + +File: gdb.info, Node: Remote Debugging, Next: Configurations, Prev: Targets, Up: Top + +Debugging remote programs +************************* + +* Menu: + +* Connecting:: Connecting to a remote target +* Server:: Using the gdbserver program +* NetWare:: Using the gdbserve.nlm program +* Remote configuration:: Remote configuration +* remote stub:: Implementing a remote stub + + +File: gdb.info, Node: Connecting, Next: Server, Up: Remote Debugging + +Connecting to a remote target +============================= + +On the GDB host machine, you will need an unstripped copy of your +program, since GDB needs symobl and debugging information. Start up +GDB as usual, using the name of the local copy of your program as the +first argument. + + If you're using a serial line, you may want to give GDB the `--baud' +option, or use the `set remotebaud' command before the `target' command. + + After that, use `target remote' to establish communications with the +target machine. Its argument specifies how to communicate--either via +a devicename attached to a direct serial line, or a TCP or UDP port +(possibly to a terminal server which in turn has a serial line to the +target). For example, to use a serial line connected to the device +named `/dev/ttyb': + + target remote /dev/ttyb + + To use a TCP connection, use an argument of the form `HOST:PORT' or +`tcp:HOST:PORT'. For example, to connect to port 2828 on a terminal +server named `manyfarms': + + target remote manyfarms:2828 + + If your remote target is actually running on the same machine as +your debugger session (e.g. a simulator of your target running on the +same host), you can omit the hostname. For example, to connect to port +1234 on your local machine: + + target remote :1234 + +Note that the colon is still required here. + + To use a UDP connection, use an argument of the form +`udp:HOST:PORT'. For example, to connect to UDP port 2828 on a +terminal server named `manyfarms': + + target remote udp:manyfarms:2828 + + When using a UDP connection for remote debugging, you should keep in +mind that the `U' stands for "Unreliable". UDP can silently drop +packets on busy or unreliable networks, which will cause havoc with +your debugging session. + + Now you can use all the usual commands to examine and change data +and to step and continue the remote program. + + Whenever GDB is waiting for the remote program, if you type the +interrupt character (often ), GDB attempts to stop the program. +This may or may not succeed, depending in part on the hardware and the +serial drivers the remote system uses. If you type the interrupt +character once again, GDB displays this prompt: + + Interrupted while waiting for the program. + Give up (and stop debugging it)? (y or n) + + If you type `y', GDB abandons the remote debugging session. (If you +decide you want to try again later, you can use `target remote' again +to connect once more.) If you type `n', GDB goes back to waiting. + +`detach' + When you have finished debugging the remote program, you can use + the `detach' command to release it from GDB control. Detaching + from the target normally resumes its execution, but the results + will depend on your particular remote stub. After the `detach' + command, GDB is free to connect to another target. + +`disconnect' + The `disconnect' command behaves like `detach', except that the + target is generally not resumed. It will wait for GDB (this + instance or another one) to connect and continue debugging. After + the `disconnect' command, GDB is again free to connect to another + target. + + +File: gdb.info, Node: Server, Next: NetWare, Prev: Connecting, Up: Remote Debugging + +Using the `gdbserver' program +============================= + +`gdbserver' is a control program for Unix-like systems, which allows +you to connect your program with a remote GDB via `target remote'--but +without linking in the usual debugging stub. + + `gdbserver' is not a complete replacement for the debugging stubs, +because it requires essentially the same operating-system facilities +that GDB itself does. In fact, a system that can run `gdbserver' to +connect to a remote GDB could also run GDB locally! `gdbserver' is +sometimes useful nevertheless, because it is a much smaller program +than GDB itself. It is also easier to port than all of GDB, so you may +be able to get started more quickly on a new system by using +`gdbserver'. Finally, if you develop code for real-time systems, you +may find that the tradeoffs involved in real-time operation make it +more convenient to do as much development work as possible on another +system, for example by cross-compiling. You can use `gdbserver' to +make a similar choice for debugging. + + GDB and `gdbserver' communicate via either a serial line or a TCP +connection, using the standard GDB remote serial protocol. + +_On the target machine,_ + you need to have a copy of the program you want to debug. + `gdbserver' does not need your program's symbol table, so you can + strip the program if necessary to save space. GDB on the host + system does all the symbol handling. + + To use the server, you must tell it how to communicate with GDB; + the name of your program; and the arguments for your program. The + usual syntax is: + + target> gdbserver COMM PROGRAM [ ARGS ... ] + + COMM is either a device name (to use a serial line) or a TCP + hostname and portnumber. For example, to debug Emacs with the + argument `foo.txt' and communicate with GDB over the serial port + `/dev/com1': + + target> gdbserver /dev/com1 emacs foo.txt + + `gdbserver' waits passively for the host GDB to communicate with + it. + + To use a TCP connection instead of a serial line: + + target> gdbserver host:2345 emacs foo.txt + + The only difference from the previous example is the first + argument, specifying that you are communicating with the host GDB + via TCP. The `host:2345' argument means that `gdbserver' is to + expect a TCP connection from machine `host' to local TCP port 2345. + (Currently, the `host' part is ignored.) You can choose any number + you want for the port number as long as it does not conflict with + any TCP ports already in use on the target system (for example, + `23' is reserved for `telnet').(1) You must use the same port + number with the host GDB `target remote' command. + + On some targets, `gdbserver' can also attach to running programs. + This is accomplished via the `--attach' argument. The syntax is: + + target> gdbserver COMM --attach PID + + PID is the process ID of a currently running process. It isn't + necessary to point `gdbserver' at a binary for the running process. + + You can debug processes by name instead of process ID if your + target has the `pidof' utility: + + target> gdbserver COMM --attach `pidof PROGRAM` + + In case more than one copy of PROGRAM is running, or PROGRAM has + multiple threads, most versions of `pidof' support the `-s' option + to only return the first process ID. + +_On the host machine,_ + connect to your target (*note Connecting to a remote target: + Connecting.). For TCP connections, you must start up `gdbserver' + prior to using the `target remote' command. Otherwise you may get + an error whose text depends on the host system, but which usually + looks something like `Connection refused'. You don't need to use + the `load' command in GDB when using gdbserver, since the program + is already on the target. + + + ---------- Footnotes ---------- + + (1) If you choose a port number that conflicts with another service, +`gdbserver' prints an error message and exits. + + +File: gdb.info, Node: NetWare, Next: Remote configuration, Prev: Server, Up: Remote Debugging + +Using the `gdbserve.nlm' program +================================ + +`gdbserve.nlm' is a control program for NetWare systems, which allows +you to connect your program with a remote GDB via `target remote'. + + GDB and `gdbserve.nlm' communicate via a serial line, using the +standard GDB remote serial protocol. + +_On the target machine,_ + you need to have a copy of the program you want to debug. + `gdbserve.nlm' does not need your program's symbol table, so you + can strip the program if necessary to save space. GDB on the host + system does all the symbol handling. + + To use the server, you must tell it how to communicate with GDB; + the name of your program; and the arguments for your program. The + syntax is: + + load gdbserve [ BOARD=BOARD ] [ PORT=PORT ] + [ BAUD=BAUD ] PROGRAM [ ARGS ... ] + + BOARD and PORT specify the serial line; BAUD specifies the baud + rate used by the connection. PORT and NODE default to 0, BAUD + defaults to 9600bps. + + For example, to debug Emacs with the argument `foo.txt'and + communicate with GDB over serial port number 2 or board 1 using a + 19200bps connection: + + load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt + +__ + On the GDB host machine, connect to your target (*note Connecting + to a remote target: Connecting.). + + + +File: gdb.info, Node: Remote configuration, Next: remote stub, Prev: NetWare, Up: Remote Debugging + +Remote configuration +==================== + +The following configuration options are available when debugging remote +programs: + +`set remote hardware-watchpoint-limit LIMIT' +`set remote hardware-breakpoint-limit LIMIT' + Restrict GDB to using LIMIT remote hardware breakpoint or + watchpoints. A limit of -1, the default, is treated as unlimited. + + +File: gdb.info, Node: remote stub, Prev: Remote configuration, Up: Remote Debugging + +Implementing a remote stub +========================== + +The stub files provided with GDB implement the target side of the +communication protocol, and the GDB side is implemented in the GDB +source file `remote.c'. Normally, you can simply allow these +subroutines to communicate, and ignore the details. (If you're +implementing your own stub file, you can still ignore the details: start +with one of the existing stub files. `sparc-stub.c' is the best +organized, and therefore the easiest to read.) + + To debug a program running on another machine (the debugging +"target" machine), you must first arrange for all the usual +prerequisites for the program to run by itself. For example, for a C +program, you need: + + 1. A startup routine to set up the C runtime environment; these + usually have a name like `crt0'. The startup routine may be + supplied by your hardware supplier, or you may have to write your + own. + + 2. A C subroutine library to support your program's subroutine calls, + notably managing input and output. + + 3. A way of getting your program to the other machine--for example, a + download program. These are often supplied by the hardware + manufacturer, but you may have to write your own from hardware + documentation. + + The next step is to arrange for your program to use a serial port to +communicate with the machine where GDB is running (the "host" machine). +In general terms, the scheme looks like this: + +_On the host,_ + GDB already understands how to use this protocol; when everything + else is set up, you can simply use the `target remote' command + (*note Specifying a Debugging Target: Targets.). + +_On the target,_ + you must link with your program a few special-purpose subroutines + that implement the GDB remote serial protocol. The file + containing these subroutines is called a "debugging stub". + + On certain remote targets, you can use an auxiliary program + `gdbserver' instead of linking a stub into your program. *Note + Using the `gdbserver' program: Server, for details. + + The debugging stub is specific to the architecture of the remote +machine; for example, use `sparc-stub.c' to debug programs on SPARC +boards. + + These working remote stubs are distributed with GDB: + +`i386-stub.c' + For Intel 386 and compatible architectures. + +`m68k-stub.c' + For Motorola 680x0 architectures. + +`sh-stub.c' + For Renesas SH architectures. + +`sparc-stub.c' + For SPARC architectures. + +`sparcl-stub.c' + For Fujitsu SPARCLITE architectures. + + + The `README' file in the GDB distribution may list other recently +added stubs. + +* Menu: + +* Stub Contents:: What the stub can do for you +* Bootstrapping:: What you must do for the stub +* Debug Session:: Putting it all together + + +File: gdb.info, Node: Stub Contents, Next: Bootstrapping, Up: remote stub + +What the stub can do for you +---------------------------- + +The debugging stub for your architecture supplies these three +subroutines: + +`set_debug_traps' + This routine arranges for `handle_exception' to run when your + program stops. You must call this subroutine explicitly near the + beginning of your program. + +`handle_exception' + This is the central workhorse, but your program never calls it + explicitly--the setup code arranges for `handle_exception' to run + when a trap is triggered. + + `handle_exception' takes control when your program stops during + execution (for example, on a breakpoint), and mediates + communications with GDB on the host machine. This is where the + communications protocol is implemented; `handle_exception' acts as + the GDB representative on the target machine. It begins by + sending summary information on the state of your program, then + continues to execute, retrieving and transmitting any information + GDB needs, until you execute a GDB command that makes your program + resume; at that point, `handle_exception' returns control to your + own code on the target machine. + +`breakpoint' + Use this auxiliary subroutine to make your program contain a + breakpoint. Depending on the particular situation, this may be + the only way for GDB to get control. For instance, if your target + machine has some sort of interrupt button, you won't need to call + this; pressing the interrupt button transfers control to + `handle_exception'--in effect, to GDB. On some machines, simply + receiving characters on the serial port may also trigger a trap; + again, in that situation, you don't need to call `breakpoint' from + your own program--simply running `target remote' from the host GDB + session gets control. + + Call `breakpoint' if none of these is true, or if you simply want + to make certain your program stops at a predetermined point for the + start of your debugging session. + + +File: gdb.info, Node: Bootstrapping, Next: Debug Session, Prev: Stub Contents, Up: remote stub + +What you must do for the stub +----------------------------- + +The debugging stubs that come with GDB are set up for a particular chip +architecture, but they have no information about the rest of your +debugging target machine. + + First of all you need to tell the stub how to communicate with the +serial port. + +`int getDebugChar()' + Write this subroutine to read a single character from the serial + port. It may be identical to `getchar' for your target system; a + different name is used to allow you to distinguish the two if you + wish. + +`void putDebugChar(int)' + Write this subroutine to write a single character to the serial + port. It may be identical to `putchar' for your target system; a + different name is used to allow you to distinguish the two if you + wish. + + If you want GDB to be able to stop your program while it is running, +you need to use an interrupt-driven serial driver, and arrange for it +to stop when it receives a `^C' (`\003', the control-C character). +That is the character which GDB uses to tell the remote system to stop. + + Getting the debugging target to return the proper status to GDB +probably requires changes to the standard stub; one quick and dirty way +is to just execute a breakpoint instruction (the "dirty" part is that +GDB reports a `SIGTRAP' instead of a `SIGINT'). + + Other routines you need to supply are: + +`void exceptionHandler (int EXCEPTION_NUMBER, void *EXCEPTION_ADDRESS)' + Write this function to install EXCEPTION_ADDRESS in the exception + handling tables. You need to do this because the stub does not + have any way of knowing what the exception handling tables on your + target system are like (for example, the processor's table might + be in ROM, containing entries which point to a table in RAM). + EXCEPTION_NUMBER is the exception number which should be changed; + its meaning is architecture-dependent (for example, different + numbers might represent divide by zero, misaligned access, etc). + When this exception occurs, control should be transferred directly + to EXCEPTION_ADDRESS, and the processor state (stack, registers, + and so on) should be just as it is when a processor exception + occurs. So if you want to use a jump instruction to reach + EXCEPTION_ADDRESS, it should be a simple jump, not a jump to + subroutine. + + For the 386, EXCEPTION_ADDRESS should be installed as an interrupt + gate so that interrupts are masked while the handler runs. The + gate should be at privilege level 0 (the most privileged level). + The SPARC and 68k stubs are able to mask interrupts themselves + without help from `exceptionHandler'. + +`void flush_i_cache()' + On SPARC and SPARCLITE only, write this subroutine to flush the + instruction cache, if any, on your target machine. If there is no + instruction cache, this subroutine may be a no-op. + + On target machines that have instruction caches, GDB requires this + function to make certain that the state of your program is stable. + +You must also make sure this library routine is available: + +`void *memset(void *, int, int)' + This is the standard library function `memset' that sets an area of + memory to a known value. If you have one of the free versions of + `libc.a', `memset' can be found there; otherwise, you must either + obtain it from your hardware manufacturer, or write your own. + + If you do not use the GNU C compiler, you may need other standard +library subroutines as well; this varies from one stub to another, but +in general the stubs are likely to use any of the common library +subroutines which `gcc' generates as inline code. + + +File: gdb.info, Node: Debug Session, Prev: Bootstrapping, Up: remote stub + +Putting it all together +----------------------- + +In summary, when your program is ready to debug, you must follow these +steps. + + 1. Make sure you have defined the supporting low-level routines + (*note What you must do for the stub: Bootstrapping.): + `getDebugChar', `putDebugChar', + `flush_i_cache', `memset', `exceptionHandler'. + + 2. Insert these lines near the top of your program: + + set_debug_traps(); + breakpoint(); + + 3. For the 680x0 stub only, you need to provide a variable called + `exceptionHook'. Normally you just use: + + void (*exceptionHook)() = 0; + + but if before calling `set_debug_traps', you set it to point to a + function in your program, that function is called when `GDB' + continues after stopping on a trap (for example, bus error). The + function indicated by `exceptionHook' is called with one + parameter: an `int' which is the exception number. + + 4. Compile and link together: your program, the GDB debugging stub for + your target architecture, and the supporting subroutines. + + 5. Make sure you have a serial connection between your target machine + and the GDB host, and identify the serial port on the host. + + 6. Download your program to your target machine (or get it there by + whatever means the manufacturer provides), and start it. + + 7. Start GDB on the host, and connect to the target (*note Connecting + to a remote target: Connecting.). + + + +File: gdb.info, Node: Configurations, Next: Controlling GDB, Prev: Remote Debugging, Up: Top + +Configuration-Specific Information +********************************** + +While nearly all GDB commands are available for all native and cross +versions of the debugger, there are some exceptions. This chapter +describes things that are only available in certain configurations. + + There are three major categories of configurations: native +configurations, where the host and target are the same, embedded +operating system configurations, which are usually the same for several +different processor architectures, and bare embedded processors, which +are quite different from each other. + +* Menu: + +* Native:: +* Embedded OS:: +* Embedded Processors:: +* Architectures:: + + +File: gdb.info, Node: Native, Next: Embedded OS, Up: Configurations + +Native +====== + +This section describes details specific to particular native +configurations. + +* Menu: + +* HP-UX:: HP-UX +* SVR4 Process Information:: SVR4 process information +* DJGPP Native:: Features specific to the DJGPP port +* Cygwin Native:: Features specific to the Cygwin port + + +File: gdb.info, Node: HP-UX, Next: SVR4 Process Information, Up: Native + +HP-UX +----- + +On HP-UX systems, if you refer to a function or variable name that +begins with a dollar sign, GDB searches for a user or system name +first, before it searches for a convenience variable. + + +File: gdb.info, Node: SVR4 Process Information, Next: DJGPP Native, Prev: HP-UX, Up: Native + +SVR4 process information +------------------------ + +Many versions of SVR4 provide a facility called `/proc' that can be +used to examine the image of a running process using file-system +subroutines. If GDB is configured for an operating system with this +facility, the command `info proc' is available to report on several +kinds of information about the process running your program. `info +proc' works only on SVR4 systems that include the `procfs' code. This +includes OSF/1 (Digital Unix), Solaris, Irix, and Unixware, but not +HP-UX or GNU/Linux, for example. + +`info proc' + Summarize available information about the process. + +`info proc mappings' + Report on the address ranges accessible in the program, with + information on whether your program may read, write, or execute + each range. + + +File: gdb.info, Node: DJGPP Native, Next: Cygwin Native, Prev: SVR4 Process Information, Up: Native + +Features for Debugging DJGPP Programs +------------------------------------- + +DJGPP is the port of GNU development tools to MS-DOS and MS-Windows. +DJGPP programs are 32-bit protected-mode programs that use the "DPMI" +(DOS Protected-Mode Interface) API to run on top of real-mode DOS +systems and their emulations. + + GDB supports native debugging of DJGPP programs, and defines a few +commands specific to the DJGPP port. This subsection describes those +commands. + +`info dos' + This is a prefix of DJGPP-specific commands which print + information about the target system and important OS structures. + +`info dos sysinfo' + This command displays assorted information about the underlying + platform: the CPU type and features, the OS version and flavor, the + DPMI version, and the available conventional and DPMI memory. + +`info dos gdt' +`info dos ldt' +`info dos idt' + These 3 commands display entries from, respectively, Global, Local, + and Interrupt Descriptor Tables (GDT, LDT, and IDT). The + descriptor tables are data structures which store a descriptor for + each segment that is currently in use. The segment's selector is + an index into a descriptor table; the table entry for that index + holds the descriptor's base address and limit, and its attributes + and access rights. + + A typical DJGPP program uses 3 segments: a code segment, a data + segment (used for both data and the stack), and a DOS segment + (which allows access to DOS/BIOS data structures and absolute + addresses in conventional memory). However, the DPMI host will + usually define additional segments in order to support the DPMI + environment. + + These commands allow to display entries from the descriptor tables. + Without an argument, all entries from the specified table are + displayed. An argument, which should be an integer expression, + means display a single entry whose index is given by the argument. + For example, here's a convenient way to display information about + the debugged program's data segment: + + `(gdb) info dos ldt $ds' + `0x13f: base=0x11970000 limit=0x0009ffff 32-Bit Data (Read/Write, Exp-up)' + + + This comes in handy when you want to see whether a pointer is + outside the data segment's limit (i.e. "garbled"). + +`info dos pde' +`info dos pte' + These two commands display entries from, respectively, the Page + Directory and the Page Tables. Page Directories and Page Tables + are data structures which control how virtual memory addresses are + mapped into physical addresses. A Page Table includes an entry + for every page of memory that is mapped into the program's address + space; there may be several Page Tables, each one holding up to + 4096 entries. A Page Directory has up to 4096 entries, one each + for every Page Table that is currently in use. + + Without an argument, `info dos pde' displays the entire Page + Directory, and `info dos pte' displays all the entries in all of + the Page Tables. An argument, an integer expression, given to the + `info dos pde' command means display only that entry from the Page + Directory table. An argument given to the `info dos pte' command + means display entries from a single Page Table, the one pointed to + by the specified entry in the Page Directory. + + These commands are useful when your program uses "DMA" (Direct + Memory Access), which needs physical addresses to program the DMA + controller. + + These commands are supported only with some DPMI servers. + +`info dos address-pte ADDR' + This command displays the Page Table entry for a specified linear + address. The argument linear address ADDR should already have the + appropriate segment's base address added to it, because this + command accepts addresses which may belong to _any_ segment. For + example, here's how to display the Page Table entry for the page + where the variable `i' is stored: + + `(gdb) info dos address-pte __djgpp_base_address + (char *)&i' + `Page Table entry for address 0x11a00d30:' + `Base=0x02698000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0xd30' + + + This says that `i' is stored at offset `0xd30' from the page whose + physical base address is `0x02698000', and prints all the + attributes of that page. + + Note that you must cast the addresses of variables to a `char *', + since otherwise the value of `__djgpp_base_address', the base + address of all variables and functions in a DJGPP program, will be + added using the rules of C pointer arithmetics: if `i' is declared + an `int', GDB will add 4 times the value of `__djgpp_base_address' + to the address of `i'. + + Here's another example, it displays the Page Table entry for the + transfer buffer: + + `(gdb) info dos address-pte *((unsigned *)&_go32_info_block + 3)' + `Page Table entry for address 0x29110:' + `Base=0x00029000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0x110' + + + (The `+ 3' offset is because the transfer buffer's address is the + 3rd member of the `_go32_info_block' structure.) The output of + this command clearly shows that addresses in conventional memory + are mapped 1:1, i.e. the physical and linear addresses are + identical. + + This command is supported only with some DPMI servers. + + +File: gdb.info, Node: Cygwin Native, Prev: DJGPP Native, Up: Native + +Features for Debugging MS Windows PE executables +------------------------------------------------ + +GDB supports native debugging of MS Windows programs, including DLLs +with and without symbolic debugging information. There are various +additional Cygwin-specific commands, described in this subsection. The +subsubsection *note Non-debug DLL symbols:: describes working with DLLs +that have no debugging symbols. + +`info w32' + This is a prefix of MS Windows specific commands which print + information about the target system and important OS structures. + +`info w32 selector' + This command displays information returned by the Win32 API + `GetThreadSelectorEntry' function. It takes an optional argument + that is evaluated to a long value to give the information about + this given selector. Without argument, this command displays + information about the the six segment registers. + +`info dll' + This is a Cygwin specific alias of info shared. + +`dll-symbols' + This command loads symbols from a dll similarly to add-sym command + but without the need to specify a base address. + +`set new-console MODE' + If MODE is `on' the debuggee will be started in a new console on + next start. If MODE is `off'i, the debuggee will be started in + the same console as the debugger. + +`show new-console' + Displays whether a new console is used when the debuggee is + started. + +`set new-group MODE' + This boolean value controls whether the debuggee should start a + new group or stay in the same group as the debugger. This affects + the way the Windows OS handles Ctrl-C. + +`show new-group' + Displays current value of new-group boolean. + +`set debugevents' + This boolean value adds debug output concerning events seen by the + debugger. + +`set debugexec' + This boolean value adds debug output concerning execute events + seen by the debugger. + +`set debugexceptions' + This boolean value adds debug ouptut concerning exception events + seen by the debugger. + +`set debugmemory' + This boolean value adds debug ouptut concerning memory events seen + by the debugger. + +`set shell' + This boolean values specifies whether the debuggee is called via a + shell or directly (default value is on). + +`show shell' + Displays if the debuggee will be started with a shell. + + +* Menu: + +* Non-debug DLL symbols:: Support for DLLs without debugging symbols + + +File: gdb.info, Node: Non-debug DLL symbols, Up: Cygwin Native + +Support for DLLs without debugging symbols +.......................................... + +Very often on windows, some of the DLLs that your program relies on do +not include symbolic debugging information (for example, +`kernel32.dll'). When GDB doesn't recognize any debugging symbols in a +DLL, it relies on the minimal amount of symbolic information contained +in the DLL's export table. This subsubsection describes working with +such symbols, known internally to GDB as "minimal symbols". + + Note that before the debugged program has started execution, no DLLs +will have been loaded. The easiest way around this problem is simply to +start the program -- either by setting a breakpoint or letting the +program run once to completion. It is also possible to force GDB to +load a particular DLL before starting the executable -- see the shared +library information in *note Files:: or the `dll-symbols' command in +*note Cygwin Native::. Currently, explicitly loading symbols from a DLL +with no debugging information will cause the symbol names to be +duplicated in GDB's lookup table, which may adversely affect symbol +lookup performance. + +DLL name prefixes +................. + +In keeping with the naming conventions used by the Microsoft debugging +tools, DLL export symbols are made available with a prefix based on the +DLL name, for instance `KERNEL32!CreateFileA'. The plain name is also +entered into the symbol table, so `CreateFileA' is often sufficient. In +some cases there will be name clashes within a program (particularly if +the executable itself includes full debugging symbols) necessitating +the use of the fully qualified name when referring to the contents of +the DLL. Use single-quotes around the name to avoid the exclamation +mark ("!") being interpreted as a language operator. + + Note that the internal name of the DLL may be all upper-case, even +though the file name of the DLL is lower-case, or vice-versa. Since +symbols within GDB are _case-sensitive_ this may cause some confusion. +If in doubt, try the `info functions' and `info variables' commands or +even `maint print msymbols' (see *note Symbols::). Here's an example: + + (gdb) info function CreateFileA + All functions matching regular expression "CreateFileA": + + Non-debugging symbols: + 0x77e885f4 CreateFileA + 0x77e885f4 KERNEL32!CreateFileA + + (gdb) info function ! + All functions matching regular expression "!": + + Non-debugging symbols: + 0x6100114c cygwin1!__assert + 0x61004034 cygwin1!_dll_crt0@0 + 0x61004240 cygwin1!dll_crt0(per_process *) + [etc...] + +Working with minimal symbols +............................ + +Symbols extracted from a DLL's export table do not contain very much +type information. All that GDB can do is guess whether a symbol refers +to a function or variable depending on the linker section that contains +the symbol. Also note that the actual contents of the memory contained +in a DLL are not available unless the program is running. This means +that you cannot examine the contents of a variable or disassemble a +function within a DLL without a running program. + + Variables are generally treated as pointers and dereferenced +automatically. For this reason, it is often necessary to prefix a +variable name with the address-of operator ("&") and provide explicit +type information in the command. Here's an example of the type of +problem: + + (gdb) print 'cygwin1!__argv' + $1 = 268572168 + + (gdb) x 'cygwin1!__argv' + 0x10021610: "\230y\"" + + And two possible solutions: + + (gdb) print ((char **)'cygwin1!__argv')[0] + $2 = 0x22fd98 "/cygdrive/c/mydirectory/myprogram" + + (gdb) x/2x &'cygwin1!__argv' + 0x610c0aa8 : 0x10021608 0x00000000 + (gdb) x/x 0x10021608 + 0x10021608: 0x0022fd98 + (gdb) x/s 0x0022fd98 + 0x22fd98: "/cygdrive/c/mydirectory/myprogram" + + Setting a break point within a DLL is possible even before the +program starts execution. However, under these circumstances, GDB can't +examine the initial instructions of the function in order to skip the +function's frame set-up code. You can work around this by using "*&" to +set the breakpoint at a raw memory address: + + (gdb) break *&'python22!PyOS_Readline' + Breakpoint 1 at 0x1e04eff0 + + The author of these extensions is not entirely convinced that +setting a break point within a shared DLL like `kernel32.dll' is +completely safe. + + +File: gdb.info, Node: Embedded OS, Next: Embedded Processors, Prev: Native, Up: Configurations + +Embedded Operating Systems +========================== + +This section describes configurations involving the debugging of +embedded operating systems that are available for several different +architectures. + +* Menu: + +* VxWorks:: Using GDB with VxWorks + + GDB includes the ability to debug programs running on various +real-time operating systems. + + +File: gdb.info, Node: VxWorks, Up: Embedded OS + +Using GDB with VxWorks +---------------------- + +`target vxworks MACHINENAME' + A VxWorks system, attached via TCP/IP. The argument MACHINENAME + is the target system's machine name or IP address. + + + On VxWorks, `load' links FILENAME dynamically on the current target +system as well as adding its symbols in GDB. + + GDB enables developers to spawn and debug tasks running on networked +VxWorks targets from a Unix host. Already-running tasks spawned from +the VxWorks shell can also be debugged. GDB uses code that runs on +both the Unix host and on the VxWorks target. The program `gdb' is +installed and executed on the Unix host. (It may be installed with the +name `vxgdb', to distinguish it from a GDB for debugging programs on +the host itself.) + +`VxWorks-timeout ARGS' + All VxWorks-based targets now support the option `vxworks-timeout'. + This option is set by the user, and ARGS represents the number of + seconds GDB waits for responses to rpc's. You might use this if + your VxWorks target is a slow software simulator or is on the far + side of a thin network line. + + The following information on connecting to VxWorks was current when +this manual was produced; newer releases of VxWorks may use revised +procedures. + + To use GDB with VxWorks, you must rebuild your VxWorks kernel to +include the remote debugging interface routines in the VxWorks library +`rdb.a'. To do this, define `INCLUDE_RDB' in the VxWorks configuration +file `configAll.h' and rebuild your VxWorks kernel. The resulting +kernel contains `rdb.a', and spawns the source debugging task +`tRdbTask' when VxWorks is booted. For more information on configuring +and remaking VxWorks, see the manufacturer's manual. + + Once you have included `rdb.a' in your VxWorks system image and set +your Unix execution search path to find GDB, you are ready to run GDB. +From your Unix host, run `gdb' (or `vxgdb', depending on your +installation). + + GDB comes up showing the prompt: + + (vxgdb) + +* Menu: + +* VxWorks Connection:: Connecting to VxWorks +* VxWorks Download:: VxWorks download +* VxWorks Attach:: Running tasks + + +File: gdb.info, Node: VxWorks Connection, Next: VxWorks Download, Up: VxWorks + +Connecting to VxWorks +..................... + +The GDB command `target' lets you connect to a VxWorks target on the +network. To connect to a target whose host name is "`tt'", type: + + (vxgdb) target vxworks tt + + GDB displays messages like these: + + Attaching remote machine across net... + Connected to tt. + + GDB then attempts to read the symbol tables of any object modules +loaded into the VxWorks target since it was last booted. GDB locates +these files by searching the directories listed in the command search +path (*note Your program's environment: Environment.); if it fails to +find an object file, it displays a message such as: + + prog.o: No such file or directory. + + When this happens, add the appropriate directory to the search path +with the GDB command `path', and execute the `target' command again. + + +File: gdb.info, Node: VxWorks Download, Next: VxWorks Attach, Prev: VxWorks Connection, Up: VxWorks + +VxWorks download +................ + +If you have connected to the VxWorks target and you want to debug an +object that has not yet been loaded, you can use the GDB `load' command +to download a file from Unix to VxWorks incrementally. The object file +given as an argument to the `load' command is actually opened twice: +first by the VxWorks target in order to download the code, then by GDB +in order to read the symbol table. This can lead to problems if the +current working directories on the two systems differ. If both systems +have NFS mounted the same filesystems, you can avoid these problems by +using absolute paths. Otherwise, it is simplest to set the working +directory on both systems to the directory in which the object file +resides, and then to reference the file by its name, without any path. +For instance, a program `prog.o' may reside in `VXPATH/vw/demo/rdb' in +VxWorks and in `HOSTPATH/vw/demo/rdb' on the host. To load this +program, type this on VxWorks: + + -> cd "VXPATH/vw/demo/rdb" + +Then, in GDB, type: + + (vxgdb) cd HOSTPATH/vw/demo/rdb + (vxgdb) load prog.o + + GDB displays a response similar to this: + + Reading symbol data from wherever/vw/demo/rdb/prog.o... done. + + You can also use the `load' command to reload an object module after +editing and recompiling the corresponding source file. Note that this +makes GDB delete all currently-defined breakpoints, auto-displays, and +convenience variables, and to clear the value history. (This is +necessary in order to preserve the integrity of debugger's data +structures that reference the target system's symbol table.) + + +File: gdb.info, Node: VxWorks Attach, Prev: VxWorks Download, Up: VxWorks + +Running tasks +............. + +You can also attach to an existing task using the `attach' command as +follows: + + (vxgdb) attach TASK + +where TASK is the VxWorks hexadecimal task ID. The task can be running +or suspended when you attach to it. Running tasks are suspended at the +time of attachment. + + +File: gdb.info, Node: Embedded Processors, Next: Architectures, Prev: Embedded OS, Up: Configurations + +Embedded Processors +=================== + +This section goes into details specific to particular embedded +configurations. + +* Menu: + +* ARM:: ARM +* H8/300:: Renesas H8/300 +* H8/500:: Renesas H8/500 +* M32R/D:: Renesas M32R/D +* M68K:: Motorola M68K +* MIPS Embedded:: MIPS Embedded +* OpenRISC 1000:: OpenRisc 1000 +* PA:: HP PA Embedded +* PowerPC: PowerPC +* SH:: Renesas SH +* Sparclet:: Tsqware Sparclet +* Sparclite:: Fujitsu Sparclite +* ST2000:: Tandem ST2000 +* Z8000:: Zilog Z8000 + + +File: gdb.info, Node: ARM, Next: H8/300, Up: Embedded Processors + +ARM +--- + +`target rdi DEV' + ARM Angel monitor, via RDI library interface to ADP protocol. You + may use this target to communicate with both boards running the + Angel monitor, or with the EmbeddedICE JTAG debug device. + +`target rdp DEV' + ARM Demon monitor. + + + +File: gdb.info, Node: H8/300, Next: H8/500, Prev: ARM, Up: Embedded Processors + +Renesas H8/300 +-------------- + +`target hms DEV' + A Renesas SH, H8/300, or H8/500 board, attached via serial line to + your host. Use special commands `device' and `speed' to control + the serial line and the communications speed used. + +`target e7000 DEV' + E7000 emulator for Renesas H8 and SH. + +`target sh3 DEV' +`target sh3e DEV' + Renesas SH-3 and SH-3E target systems. + + + When you select remote debugging to a Renesas SH, H8/300, or H8/500 +board, the `load' command downloads your program to the Renesas board +and also opens it as the current executable target for GDB on your host +(like the `file' command). + + GDB needs to know these things to talk to your Renesas SH, H8/300, +or H8/500: + + 1. that you want to use `target hms', the remote debugging interface + for Renesas microprocessors, or `target e7000', the in-circuit + emulator for the Renesas SH and the Renesas 300H. (`target hms' is + the default when GDB is configured specifically for the Renesas SH, + H8/300, or H8/500.) + + 2. what serial device connects your host to your Renesas board (the + first serial device available on your host is the default). + + 3. what speed to use over the serial device. + +* Menu: + +* Renesas Boards:: Connecting to Renesas boards. +* Renesas ICE:: Using the E7000 In-Circuit Emulator. +* Renesas Special:: Special GDB commands for Renesas micros. + + +File: gdb.info, Node: Renesas Boards, Next: Renesas ICE, Up: H8/300 + +Connecting to Renesas boards +............................ + +Use the special `GDB' command `device PORT' if you need to explicitly +set the serial device. The default PORT is the first available port on +your host. This is only necessary on Unix hosts, where it is typically +something like `/dev/ttya'. + + `GDB' has another special command to set the communications speed: +`speed BPS'. This command also is only used from Unix hosts; on DOS +hosts, set the line speed as usual from outside GDB with the DOS `mode' +command (for instance, `mode com2:9600,n,8,1,p' for a 9600bps +connection). + + The `device' and `speed' commands are available only when you use a +Unix host to debug your Renesas microprocessor programs. If you use a +DOS host, GDB depends on an auxiliary terminate-and-stay-resident +program called `asynctsr' to communicate with the development board +through a PC serial port. You must also use the DOS `mode' command to +set up the serial port on the DOS side. + + The following sample session illustrates the steps needed to start a +program under GDB control on an H8/300. The example uses a sample +H8/300 program called `t.x'. The procedure is the same for the Renesas +SH and the H8/500. + + First hook up your development board. In this example, we use a +board attached to serial port `COM2'; if you use a different serial +port, substitute its name in the argument of the `mode' command. When +you call `asynctsr', the auxiliary comms program used by the debugger, +you give it just the numeric part of the serial port's name; for +example, `asyncstr 2' below runs `asyncstr' on `COM2'. + + C:\H8300\TEST> asynctsr 2 + C:\H8300\TEST> mode com2:9600,n,8,1,p + + Resident portion of MODE loaded + + COM2: 9600, n, 8, 1, p + + _Warning:_ We have noticed a bug in PC-NFS that conflicts with + `asynctsr'. If you also run PC-NFS on your DOS host, you may need + to disable it, or even boot without it, to use `asynctsr' to + control your development board. + + Now that serial communications are set up, and the development board +is connected, you can start up GDB. Call `gdb' with the name of your +program as the argument. `GDB' prompts you, as usual, with the prompt +`(gdb)'. Use two special commands to begin your debugging session: +`target hms' to specify cross-debugging to the Renesas board, and the +`load' command to download your program to the board. `load' displays +the names of the program's sections, and a `*' for each 2K of data +downloaded. (If you want to refresh GDB data on symbols or on the +executable file without downloading, use the GDB commands `file' or +`symbol-file'. These commands, and `load' itself, are described in +*Note Commands to specify files: Files.) + + (eg-C:\H8300\TEST) gdb t.x + GDB is free software and you are welcome to distribute copies + of it under certain conditions; type "show copying" to see + the conditions. + There is absolutely no warranty for GDB; type "show warranty" + for details. + GDB 6.1.1, Copyright 1992 Free Software Foundation, Inc... + (gdb) target hms + Connected to remote H8/300 HMS system. + (gdb) load t.x + .text : 0x8000 .. 0xabde *********** + .data : 0xabde .. 0xad30 * + .stack : 0xf000 .. 0xf014 * + + At this point, you're ready to run or debug your program. From here +on, you can use all the usual GDB commands. The `break' command sets +breakpoints; the `run' command starts your program; `print' or `x' +display data; the `continue' command resumes execution after stopping +at a breakpoint. You can use the `help' command at any time to find +out more about GDB commands. + + Remember, however, that _operating system_ facilities aren't +available on your development board; for example, if your program hangs, +you can't send an interrupt--but you can press the RESET switch! + + Use the RESET button on the development board + * to interrupt your program (don't use `ctl-C' on the DOS host--it + has no way to pass an interrupt signal to the development board); + and + + * to return to the GDB command prompt after your program finishes + normally. The communications protocol provides no other way for + GDB to detect program completion. + + In either case, GDB sees the effect of a RESET on the development +board as a "normal exit" of your program. + + +File: gdb.info, Node: Renesas ICE, Next: Renesas Special, Prev: Renesas Boards, Up: H8/300 + +Using the E7000 in-circuit emulator +................................... + +You can use the E7000 in-circuit emulator to develop code for either the +Renesas SH or the H8/300H. Use one of these forms of the `target +e7000' command to connect GDB to your E7000: + +`target e7000 PORT SPEED' + Use this form if your E7000 is connected to a serial port. The + PORT argument identifies what serial port to use (for example, + `com2'). The third argument is the line speed in bits per second + (for example, `9600'). + +`target e7000 HOSTNAME' + If your E7000 is installed as a host on a TCP/IP network, you can + just specify its hostname; GDB uses `telnet' to connect. + + +File: gdb.info, Node: Renesas Special, Prev: Renesas ICE, Up: H8/300 + +Special GDB commands for Renesas micros +....................................... + +Some GDB commands are available only for the H8/300: + +`set machine h8300' +`set machine h8300h' + Condition GDB for one of the two variants of the H8/300 + architecture with `set machine'. You can use `show machine' to + check which variant is currently in effect. + + + +File: gdb.info, Node: H8/500, Next: M32R/D, Prev: H8/300, Up: Embedded Processors + +H8/500 +------ + +`set memory MOD' +`show memory' + Specify which H8/500 memory model (MOD) you are using with `set + memory'; check which memory model is in effect with `show memory'. + The accepted values for MOD are `small', `big', `medium', and + `compact'. + + + +File: gdb.info, Node: M32R/D, Next: M68K, Prev: H8/500, Up: Embedded Processors + +Renesas M32R/D +-------------- + +`target m32r DEV' + Renesas M32R/D ROM monitor. + +`target m32rsdi DEV' + Renesas M32R SDI server, connected via parallel port to the board. + + + +File: gdb.info, Node: M68K, Next: MIPS Embedded, Prev: M32R/D, Up: Embedded Processors + +M68k +---- + +The Motorola m68k configuration includes ColdFire support, and target +command for the following ROM monitors. + +`target abug DEV' + ABug ROM monitor for M68K. + +`target cpu32bug DEV' + CPU32BUG monitor, running on a CPU32 (M68K) board. + +`target dbug DEV' + dBUG ROM monitor for Motorola ColdFire. + +`target est DEV' + EST-300 ICE monitor, running on a CPU32 (M68K) board. + +`target rom68k DEV' + ROM 68K monitor, running on an M68K IDP board. + + +`target rombug DEV' + ROMBUG ROM monitor for OS/9000. + + + +File: gdb.info, Node: MIPS Embedded, Next: OpenRISC 1000, Prev: M68K, Up: Embedded Processors + +MIPS Embedded +------------- + +GDB can use the MIPS remote debugging protocol to talk to a MIPS board +attached to a serial line. This is available when you configure GDB +with `--target=mips-idt-ecoff'. + + Use these GDB commands to specify the connection to your target +board: + +`target mips PORT' + To run a program on the board, start up `gdb' with the name of + your program as the argument. To connect to the board, use the + command `target mips PORT', where PORT is the name of the serial + port connected to the board. If the program has not already been + downloaded to the board, you may use the `load' command to + download it. You can then use all the usual GDB commands. + + For example, this sequence connects to the target board through a + serial port, and loads and runs a program called PROG through the + debugger: + + host$ gdb PROG + GDB is free software and ... + (gdb) target mips /dev/ttyb + (gdb) load PROG + (gdb) run + +`target mips HOSTNAME:PORTNUMBER' + On some GDB host configurations, you can specify a TCP connection + (for instance, to a serial line managed by a terminal + concentrator) instead of a serial port, using the syntax + `HOSTNAME:PORTNUMBER'. + +`target pmon PORT' + PMON ROM monitor. + +`target ddb PORT' + NEC's DDB variant of PMON for Vr4300. + +`target lsi PORT' + LSI variant of PMON. + +`target r3900 DEV' + Densan DVE-R3900 ROM monitor for Toshiba R3900 Mips. + +`target array DEV' + Array Tech LSI33K RAID controller board. + + +GDB also supports these special commands for MIPS targets: + +`set processor ARGS' +`show processor' + Use the `set processor' command to set the type of MIPS processor + when you want to access processor-type-specific registers. For + example, `set processor R3041' tells GDB to use the CPU registers + appropriate for the 3041 chip. Use the `show processor' command + to see what MIPS processor GDB is using. Use the `info reg' + command to see what registers GDB is using. + +`set mipsfpu double' +`set mipsfpu single' +`set mipsfpu none' +`show mipsfpu' + If your target board does not support the MIPS floating point + coprocessor, you should use the command `set mipsfpu none' (if you + need this, you may wish to put the command in your GDB init file). + This tells GDB how to find the return value of functions which + return floating point values. It also allows GDB to avoid saving + the floating point registers when calling functions on the board. + If you are using a floating point coprocessor with only single + precision floating point support, as on the R4650 processor, use + the command `set mipsfpu single'. The default double precision + floating point coprocessor may be selected using `set mipsfpu + double'. + + In previous versions the only choices were double precision or no + floating point, so `set mipsfpu on' will select double precision + and `set mipsfpu off' will select no floating point. + + As usual, you can inquire about the `mipsfpu' variable with `show + mipsfpu'. + +`set remotedebug N' +`show remotedebug' + You can see some debugging information about communications with + the board by setting the `remotedebug' variable. If you set it to + `1' using `set remotedebug 1', every packet is displayed. If you + set it to `2', every character is displayed. You can check the + current value at any time with the command `show remotedebug'. + +`set timeout SECONDS' +`set retransmit-timeout SECONDS' +`show timeout' +`show retransmit-timeout' + You can control the timeout used while waiting for a packet, in + the MIPS remote protocol, with the `set timeout SECONDS' command. + The default is 5 seconds. Similarly, you can control the timeout + used while waiting for an acknowledgement of a packet with the `set + retransmit-timeout SECONDS' command. The default is 3 seconds. + You can inspect both values with `show timeout' and `show + retransmit-timeout'. (These commands are _only_ available when + GDB is configured for `--target=mips-idt-ecoff'.) + + The timeout set by `set timeout' does not apply when GDB is + waiting for your program to stop. In that case, GDB waits forever + because it has no way of knowing how long the program is going to + run before stopping. + + +File: gdb.info, Node: OpenRISC 1000, Next: PA, Prev: MIPS Embedded, Up: Embedded Processors + +OpenRISC 1000 +------------- + +See OR1k Architecture document (`www.opencores.org') for more +information about platform and commands. + +`target jtag jtag://HOST:PORT' + Connects to remote JTAG server. JTAG remote server can be either + an or1ksim or JTAG server, connected via parallel port to the + board. + + Example: `target jtag jtag://localhost:9999' + +`or1ksim COMMAND' + If connected to `or1ksim' OpenRISC 1000 Architectural Simulator, + proprietary commands can be executed. + +`info or1k spr' + Displays spr groups. + +`info or1k spr GROUP' +`info or1k spr GROUPNO' + Displays register names in selected group. + +`info or1k spr GROUP REGISTER' +`info or1k spr REGISTER' +`info or1k spr GROUPNO REGISTERNO' +`info or1k spr REGISTERNO' + Shows information about specified spr register. + +`spr GROUP REGISTER VALUE' +`spr REGISTER VALUE' +`spr GROUPNO REGISTERNO VALUE' +`spr REGISTERNO VALUE' + Writes VALUE to specified spr register. + + Some implementations of OpenRISC 1000 Architecture also have +hardware trace. It is very similar to GDB trace, except it does not +interfere with normal program execution and is thus much faster. +Hardware breakpoints/watchpoint triggers can be set using: +`$LEA/$LDATA' + Load effective address/data + +`$SEA/$SDATA' + Store effective address/data + +`$AEA/$ADATA' + Access effective address ($SEA or $LEA) or data ($SDATA/$LDATA) + +`$FETCH' + Fetch data + + When triggered, it can capture low level data, like: `PC', `LSEA', +`LDATA', `SDATA', `READSPR', `WRITESPR', `INSTR'. + + `htrace' commands: +`hwatch CONDITIONAL' + Set hardware watchpoint on combination of Load/Store Effecive + Address(es) or Data. For example: + + `hwatch ($LEA == my_var) && ($LDATA < 50) || ($SEA == my_var) && + ($SDATA >= 50)' + + `hwatch ($LEA == my_var) && ($LDATA < 50) || ($SEA == my_var) && + ($SDATA >= 50)' + +`htrace info' + Display information about current HW trace configuration. + +`htrace trigger CONDITIONAL' + Set starting criteria for HW trace. + +`htrace qualifier CONDITIONAL' + Set acquisition qualifier for HW trace. + +`htrace stop CONDITIONAL' + Set HW trace stopping criteria. + +`htrace record [DATA]*' + Selects the data to be recorded, when qualifier is met and HW + trace was triggered. + +`htrace enable' +`htrace disable' + Enables/disables the HW trace. + +`htrace rewind [FILENAME]' + Clears currently recorded trace data. + + If filename is specified, new trace file is made and any newly + collected data will be written there. + +`htrace print [START [LEN]]' + Prints trace buffer, using current record configuration. + +`htrace mode continuous' + Set continuous trace mode. + +`htrace mode suspend' + Set suspend trace mode. + + + +File: gdb.info, Node: PowerPC, Next: SH, Prev: PA, Up: Embedded Processors + +PowerPC +------- + +`target dink32 DEV' + DINK32 ROM monitor. + +`target ppcbug DEV' + +`target ppcbug1 DEV' + PPCBUG ROM monitor for PowerPC. + +`target sds DEV' + SDS monitor, running on a PowerPC board (such as Motorola's ADS). + + + +File: gdb.info, Node: PA, Next: PowerPC, Prev: OpenRISC 1000, Up: Embedded Processors + +HP PA Embedded +-------------- + +`target op50n DEV' + OP50N monitor, running on an OKI HPPA board. + +`target w89k DEV' + W89K monitor, running on a Winbond HPPA board. + + + +File: gdb.info, Node: SH, Next: Sparclet, Prev: PowerPC, Up: Embedded Processors + +Renesas SH +---------- + +`target hms DEV' + A Renesas SH board attached via serial line to your host. Use + special commands `device' and `speed' to control the serial line + and the communications speed used. + +`target e7000 DEV' + E7000 emulator for Renesas SH. + +`target sh3 DEV' + +`target sh3e DEV' + Renesas SH-3 and SH-3E target systems. + + + +File: gdb.info, Node: Sparclet, Next: Sparclite, Prev: SH, Up: Embedded Processors + +Tsqware Sparclet +---------------- + +GDB enables developers to debug tasks running on Sparclet targets from +a Unix host. GDB uses code that runs on both the Unix host and on the +Sparclet target. The program `gdb' is installed and executed on the +Unix host. + +`remotetimeout ARGS' + GDB supports the option `remotetimeout'. This option is set by + the user, and ARGS represents the number of seconds GDB waits for + responses. + + When compiling for debugging, include the options `-g' to get debug +information and `-Ttext' to relocate the program to where you wish to +load it on the target. You may also want to add the options `-n' or +`-N' in order to reduce the size of the sections. Example: + + sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N + + You can use `objdump' to verify that the addresses are what you +intended: + + sparclet-aout-objdump --headers --syms prog + + Once you have set your Unix execution search path to find GDB, you +are ready to run GDB. From your Unix host, run `gdb' (or +`sparclet-aout-gdb', depending on your installation). + + GDB comes up showing the prompt: + + (gdbslet) + +* Menu: + +* Sparclet File:: Setting the file to debug +* Sparclet Connection:: Connecting to Sparclet +* Sparclet Download:: Sparclet download +* Sparclet Execution:: Running and debugging + + +File: gdb.info, Node: Sparclet File, Next: Sparclet Connection, Up: Sparclet + +Setting file to debug +..................... + +The GDB command `file' lets you choose with program to debug. + + (gdbslet) file prog + + GDB then attempts to read the symbol table of `prog'. GDB locates +the file by searching the directories listed in the command search path. +If the file was compiled with debug information (option "-g"), source +files will be searched as well. GDB locates the source files by +searching the directories listed in the directory search path (*note +Your program's environment: Environment.). If it fails to find a file, +it displays a message such as: + + prog: No such file or directory. + + When this happens, add the appropriate directories to the search +paths with the GDB commands `path' and `dir', and execute the `target' +command again. + + +File: gdb.info, Node: Sparclet Connection, Next: Sparclet Download, Prev: Sparclet File, Up: Sparclet + +Connecting to Sparclet +...................... + +The GDB command `target' lets you connect to a Sparclet target. To +connect to a target on serial port "`ttya'", type: + + (gdbslet) target sparclet /dev/ttya + Remote target sparclet connected to /dev/ttya + main () at ../prog.c:3 + + GDB displays messages like these: + + Connected to ttya. + + +File: gdb.info, Node: Sparclet Download, Next: Sparclet Execution, Prev: Sparclet Connection, Up: Sparclet + +Sparclet download +................. + +Once connected to the Sparclet target, you can use the GDB `load' +command to download the file from the host to the target. The file +name and load offset should be given as arguments to the `load' command. +Since the file format is aout, the program must be loaded to the +starting address. You can use `objdump' to find out what this value +is. The load offset is an offset which is added to the VMA (virtual +memory address) of each of the file's sections. For instance, if the +program `prog' was linked to text address 0x1201000, with data at +0x12010160 and bss at 0x12010170, in GDB, type: + + (gdbslet) load prog 0x12010000 + Loading section .text, size 0xdb0 vma 0x12010000 + + If the code is loaded at a different address then what the program +was linked to, you may need to use the `section' and `add-symbol-file' +commands to tell GDB where to map the symbol table. + + +File: gdb.info, Node: Sparclet Execution, Prev: Sparclet Download, Up: Sparclet + +Running and debugging +..................... + +You can now begin debugging the task using GDB's execution control +commands, `b', `step', `run', etc. See the GDB manual for the list of +commands. + + (gdbslet) b main + Breakpoint 1 at 0x12010000: file prog.c, line 3. + (gdbslet) run + Starting program: prog + Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3 + 3 char *symarg = 0; + (gdbslet) step + 4 char *execarg = "hello!"; + (gdbslet) + + +File: gdb.info, Node: Sparclite, Next: ST2000, Prev: Sparclet, Up: Embedded Processors + +Fujitsu Sparclite +----------------- + +`target sparclite DEV' + Fujitsu sparclite boards, used only for the purpose of loading. + You must use an additional command to debug the program. For + example: target remote DEV using GDB standard remote protocol. + + + +File: gdb.info, Node: ST2000, Next: Z8000, Prev: Sparclite, Up: Embedded Processors + +Tandem ST2000 +------------- + +GDB may be used with a Tandem ST2000 phone switch, running Tandem's +STDBUG protocol. + + To connect your ST2000 to the host system, see the manufacturer's +manual. Once the ST2000 is physically attached, you can run: + + target st2000 DEV SPEED + +to establish it as your debugging environment. DEV is normally the +name of a serial device, such as `/dev/ttya', connected to the ST2000 +via a serial line. You can instead specify DEV as a TCP connection +(for example, to a serial line attached via a terminal concentrator) +using the syntax `HOSTNAME:PORTNUMBER'. + + The `load' and `attach' commands are _not_ defined for this target; +you must load your program into the ST2000 as you normally would for +standalone operation. GDB reads debugging information (such as +symbols) from a separate, debugging version of the program available on +your host computer. + + These auxiliary GDB commands are available to help you with the +ST2000 environment: + +`st2000 COMMAND' + Send a COMMAND to the STDBUG monitor. See the manufacturer's + manual for available commands. + +`connect' + Connect the controlling terminal to the STDBUG command monitor. + When you are done interacting with STDBUG, typing either of two + character sequences gets you back to the GDB command prompt: + `~.' (Return, followed by tilde and period) or `~' + (Return, followed by tilde and control-D). + + +File: gdb.info, Node: Z8000, Prev: ST2000, Up: Embedded Processors + +Zilog Z8000 +----------- + +When configured for debugging Zilog Z8000 targets, GDB includes a Z8000 +simulator. + + For the Z8000 family, `target sim' simulates either the Z8002 (the +unsegmented variant of the Z8000 architecture) or the Z8001 (the +segmented variant). The simulator recognizes which architecture is +appropriate by inspecting the object code. + +`target sim ARGS' + Debug programs on a simulated CPU. If the simulator supports setup + options, specify them via ARGS. + +After specifying this target, you can debug programs for the simulated +CPU in the same style as programs for your host computer; use the +`file' command to load a new program image, the `run' command to run +your program, and so on. + + As well as making available all the usual machine registers (*note +Registers: Registers.), the Z8000 simulator provides three additional +items of information as specially named registers: + +`cycles' + Counts clock-ticks in the simulator. + +`insts' + Counts instructions run in the simulator. + +`time' + Execution time in 60ths of a second. + + + You can refer to these values in GDB expressions with the usual +conventions; for example, `b fputc if $cycles>5000' sets a conditional +breakpoint that suspends only after at least 5000 simulated clock ticks. + + +File: gdb.info, Node: Architectures, Prev: Embedded Processors, Up: Configurations + +Architectures +============= + +This section describes characteristics of architectures that affect all +uses of GDB with the architecture, both native and cross. + +* Menu: + +* A29K:: +* Alpha:: +* MIPS:: + + +File: gdb.info, Node: A29K, Next: Alpha, Up: Architectures + +A29K +---- + +`set rstack_high_address ADDRESS' + On AMD 29000 family processors, registers are saved in a separate + "register stack". There is no way for GDB to determine the extent + of this stack. Normally, GDB just assumes that the stack is + "large enough". This may result in GDB referencing memory + locations that do not exist. If necessary, you can get around + this problem by specifying the ending address of the register + stack with the `set rstack_high_address' command. The argument + should be an address, which you probably want to precede with `0x' + to specify in hexadecimal. + +`show rstack_high_address' + Display the current limit of the register stack, on AMD 29000 + family processors. + + + +File: gdb.info, Node: Alpha, Next: MIPS, Prev: A29K, Up: Architectures + +Alpha +----- + +See the following section. + + +File: gdb.info, Node: MIPS, Prev: Alpha, Up: Architectures + +MIPS +---- + +Alpha- and MIPS-based computers use an unusual stack frame, which +sometimes requires GDB to search backward in the object code to find +the beginning of a function. + + To improve response time (especially for embedded applications, where +GDB may be restricted to a slow serial line for this search) you may +want to limit the size of this search, using one of these commands: + +`set heuristic-fence-post LIMIT' + Restrict GDB to examining at most LIMIT bytes in its search for + the beginning of a function. A value of 0 (the default) means + there is no limit. However, except for 0, the larger the limit + the more bytes `heuristic-fence-post' must search and therefore + the longer it takes to run. + +`show heuristic-fence-post' + Display the current limit. + +These commands are available _only_ when GDB is configured for +debugging programs on Alpha or MIPS processors. + + +File: gdb.info, Node: Controlling GDB, Next: Sequences, Prev: Configurations, Up: Top + +Controlling GDB +*************** + +You can alter the way GDB interacts with you by using the `set' +command. For commands controlling how GDB displays data, see *Note +Print settings: Print Settings. Other settings are described here. + +* Menu: + +* Prompt:: Prompt +* Editing:: Command editing +* History:: Command history +* Screen Size:: Screen size +* Numbers:: Numbers +* ABI:: Configuring the current ABI +* Messages/Warnings:: Optional warnings and messages +* Debugging Output:: Optional messages about internal happenings + + +File: gdb.info, Node: Prompt, Next: Editing, Up: Controlling GDB + +Prompt +====== + +GDB indicates its readiness to read a command by printing a string +called the "prompt". This string is normally `(gdb)'. You can change +the prompt string with the `set prompt' command. For instance, when +debugging GDB with GDB, it is useful to change the prompt in one of the +GDB sessions so that you can always tell which one you are talking to. + + _Note:_ `set prompt' does not add a space for you after the prompt +you set. This allows you to set a prompt which ends in a space or a +prompt that does not. + +`set prompt NEWPROMPT' + Directs GDB to use NEWPROMPT as its prompt string henceforth. + +`show prompt' + Prints a line of the form: `Gdb's prompt is: YOUR-PROMPT' + + +File: gdb.info, Node: Editing, Next: History, Prev: Prompt, Up: Controlling GDB + +Command editing +=============== + +GDB reads its input commands via the "readline" interface. This GNU +library provides consistent behavior for programs which provide a +command line interface to the user. Advantages are GNU Emacs-style or +"vi"-style inline editing of commands, `csh'-like history substitution, +and a storage and recall of command history across debugging sessions. + + You may control the behavior of command line editing in GDB with the +command `set'. + +`set editing' +`set editing on' + Enable command line editing (enabled by default). + +`set editing off' + Disable command line editing. + +`show editing' + Show whether command line editing is enabled. + + +File: gdb.info, Node: History, Next: Screen Size, Prev: Editing, Up: Controlling GDB + +Command history +=============== + +GDB can keep track of the commands you type during your debugging +sessions, so that you can be certain of precisely what happened. Use +these commands to manage the GDB command history facility. + +`set history filename FNAME' + Set the name of the GDB command history file to FNAME. This is + the file where GDB reads an initial command history list, and + where it writes the command history from this session when it + exits. You can access this list through history expansion or + through the history command editing characters listed below. This + file defaults to the value of the environment variable + `GDBHISTFILE', or to `./.gdb_history' (`./_gdb_history' on MS-DOS) + if this variable is not set. + +`set history save' +`set history save on' + Record command history in a file, whose name may be specified with + the `set history filename' command. By default, this option is + disabled. + +`set history save off' + Stop recording command history in a file. + +`set history size SIZE' + Set the number of commands which GDB keeps in its history list. + This defaults to the value of the environment variable `HISTSIZE', + or to 256 if this variable is not set. + + History expansion assigns special meaning to the character `!'. + + Since `!' is also the logical not operator in C, history expansion +is off by default. If you decide to enable history expansion with the +`set history expansion on' command, you may sometimes need to follow +`!' (when it is used as logical not, in an expression) with a space or +a tab to prevent it from being expanded. The readline history +facilities do not attempt substitution on the strings `!=' and `!(', +even when history expansion is enabled. + + The commands to control history expansion are: + +`set history expansion on' +`set history expansion' + Enable history expansion. History expansion is off by default. + +`set history expansion off' + Disable history expansion. + + The readline code comes with more complete documentation of + editing and history expansion features. Users unfamiliar with GNU + Emacs or `vi' may wish to read it. + +`show history' +`show history filename' +`show history save' +`show history size' +`show history expansion' + These commands display the state of the GDB history parameters. + `show history' by itself displays all four states. + +`show commands' + Display the last ten commands in the command history. + +`show commands N' + Print ten commands centered on command number N. + +`show commands +' + Print ten commands just after the commands last printed. + + +File: gdb.info, Node: Screen Size, Next: Numbers, Prev: History, Up: Controlling GDB + +Screen size +=========== + +Certain commands to GDB may produce large amounts of information output +to the screen. To help you read all of it, GDB pauses and asks you for +input at the end of each page of output. Type when you want to +continue the output, or `q' to discard the remaining output. Also, the +screen width setting determines when to wrap lines of output. +Depending on what is being printed, GDB tries to break the line at a +readable place, rather than simply letting it overflow onto the +following line. + + Normally GDB knows the size of the screen from the terminal driver +software. For example, on Unix GDB uses the termcap data base together +with the value of the `TERM' environment variable and the `stty rows' +and `stty cols' settings. If this is not correct, you can override it +with the `set height' and `set width' commands: + +`set height LPP' +`show height' +`set width CPL' +`show width' + These `set' commands specify a screen height of LPP lines and a + screen width of CPL characters. The associated `show' commands + display the current settings. + + If you specify a height of zero lines, GDB does not pause during + output no matter how long the output is. This is useful if output + is to a file or to an editor buffer. + + Likewise, you can specify `set width 0' to prevent GDB from + wrapping its output. + + +File: gdb.info, Node: Numbers, Next: ABI, Prev: Screen Size, Up: Controlling GDB + +Numbers +======= + +You can always enter numbers in octal, decimal, or hexadecimal in GDB +by the usual conventions: octal numbers begin with `0', decimal numbers +end with `.', and hexadecimal numbers begin with `0x'. Numbers that +begin with none of these are, by default, entered in base 10; likewise, +the default display for numbers--when no particular format is +specified--is base 10. You can change the default base for both input +and output with the `set radix' command. + +`set input-radix BASE' + Set the default base for numeric input. Supported choices for + BASE are decimal 8, 10, or 16. BASE must itself be specified + either unambiguously or using the current default radix; for + example, any of + + set radix 012 + set radix 10. + set radix 0xa + + sets the base to decimal. On the other hand, `set radix 10' + leaves the radix unchanged no matter what it was. + +`set output-radix BASE' + Set the default base for numeric display. Supported choices for + BASE are decimal 8, 10, or 16. BASE must itself be specified + either unambiguously or using the current default radix. + +`show input-radix' + Display the current default base for numeric input. + +`show output-radix' + Display the current default base for numeric display. + + +File: gdb.info, Node: ABI, Next: Messages/Warnings, Prev: Numbers, Up: Controlling GDB + +Configuring the current ABI +=========================== + +GDB can determine the "ABI" (Application Binary Interface) of your +application automatically. However, sometimes you need to override its +conclusions. Use these commands to manage GDB's view of the current +ABI. + + One GDB configuration can debug binaries for multiple operating +system targets, either via remote debugging or native emulation. GDB +will autodetect the "OS ABI" (Operating System ABI) in use, but you can +override its conclusion using the `set osabi' command. One example +where this is useful is in debugging of binaries which use an alternate +C library (e.g. UCLIBC for GNU/Linux) which does not have the same +identifying marks that the standard C library for your platform +provides. + +`show osabi' + Show the OS ABI currently in use. + +`set osabi' + With no argument, show the list of registered available OS ABI's. + +`set osabi ABI' + Set the current OS ABI to ABI. + + Generally, the way that an argument of type `float' is passed to a +function depends on whether the function is prototyped. For a +prototyped (i.e. ANSI/ISO style) function, `float' arguments are passed +unchanged, according to the architecture's convention for `float'. For +unprototyped (i.e. K&R style) functions, `float' arguments are first +promoted to type `double' and then passed. + + Unfortunately, some forms of debug information do not reliably +indicate whether a function is prototyped. If GDB calls a function +that is not marked as prototyped, it consults `set +coerce-float-to-double'. + +`set coerce-float-to-double' +`set coerce-float-to-double on' + Arguments of type `float' will be promoted to `double' when passed + to an unprototyped function. This is the default setting. + +`set coerce-float-to-double off' + Arguments of type `float' will be passed directly to unprototyped + functions. + + GDB needs to know the ABI used for your program's C++ objects. The +correct C++ ABI depends on which C++ compiler was used to build your +application. GDB only fully supports programs with a single C++ ABI; +if your program contains code using multiple C++ ABI's or if GDB can +not identify your program's ABI correctly, you can tell GDB which ABI +to use. Currently supported ABI's include "gnu-v2", for `g++' versions +before 3.0, "gnu-v3", for `g++' versions 3.0 and later, and "hpaCC" for +the HP ANSI C++ compiler. Other C++ compilers may use the "gnu-v2" or +"gnu-v3" ABI's as well. The default setting is "auto". + +`show cp-abi' + Show the C++ ABI currently in use. + +`set cp-abi' + With no argument, show the list of supported C++ ABI's. + +`set cp-abi ABI' +`set cp-abi auto' + Set the current C++ ABI to ABI, or return to automatic detection. + + +File: gdb.info, Node: Messages/Warnings, Next: Debugging Output, Prev: ABI, Up: Controlling GDB + +Optional warnings and messages +============================== + +By default, GDB is silent about its inner workings. If you are running +on a slow machine, you may want to use the `set verbose' command. This +makes GDB tell you when it does a lengthy internal operation, so you +will not think it has crashed. + + Currently, the messages controlled by `set verbose' are those which +announce that the symbol table for a source file is being read; see +`symbol-file' in *Note Commands to specify files: Files. + +`set verbose on' + Enables GDB output of certain informational messages. + +`set verbose off' + Disables GDB output of certain informational messages. + +`show verbose' + Displays whether `set verbose' is on or off. + + By default, if GDB encounters bugs in the symbol table of an object +file, it is silent; but if you are debugging a compiler, you may find +this information useful (*note Errors reading symbol files: Symbol +Errors.). + +`set complaints LIMIT' + Permits GDB to output LIMIT complaints about each type of unusual + symbols before becoming silent about the problem. Set LIMIT to + zero to suppress all complaints; set it to a large number to + prevent complaints from being suppressed. + +`show complaints' + Displays how many symbol complaints GDB is permitted to produce. + + + By default, GDB is cautious, and asks what sometimes seems to be a +lot of stupid questions to confirm certain commands. For example, if +you try to run a program which is already running: + + (gdb) run + The program being debugged has been started already. + Start it from the beginning? (y or n) + + If you are willing to unflinchingly face the consequences of your own +commands, you can disable this "feature": + +`set confirm off' + Disables confirmation requests. + +`set confirm on' + Enables confirmation requests (the default). + +`show confirm' + Displays state of confirmation requests. + + + +File: gdb.info, Node: Debugging Output, Prev: Messages/Warnings, Up: Controlling GDB + +Optional messages about internal happenings +=========================================== + +`set debug arch' + Turns on or off display of gdbarch debugging info. The default is + off + +`show debug arch' + Displays the current state of displaying gdbarch debugging info. + +`set debug event' + Turns on or off display of GDB event debugging info. The default + is off. + +`show debug event' + Displays the current state of displaying GDB event debugging info. + +`set debug expression' + Turns on or off display of GDB expression debugging info. The + default is off. + +`show debug expression' + Displays the current state of displaying GDB expression debugging + info. + +`set debug frame' + Turns on or off display of GDB frame debugging info. The default + is off. + +`show debug frame' + Displays the current state of displaying GDB frame debugging info. + +`set debug overload' + Turns on or off display of GDB C++ overload debugging info. This + includes info such as ranking of functions, etc. The default is + off. + +`show debug overload' + Displays the current state of displaying GDB C++ overload + debugging info. + +`set debug remote' + Turns on or off display of reports on all packets sent back and + forth across the serial line to the remote machine. The info is + printed on the GDB standard output stream. The default is off. + +`show debug remote' + Displays the state of display of remote packets. + +`set debug serial' + Turns on or off display of GDB serial debugging info. The default + is off. + +`show debug serial' + Displays the current state of displaying GDB serial debugging info. + +`set debug target' + Turns on or off display of GDB target debugging info. This info + includes what is going on at the target level of GDB, as it + happens. The default is off. + +`show debug target' + Displays the current state of displaying GDB target debugging info. + +`set debug varobj' + Turns on or off display of GDB variable object debugging info. The + default is off. + +`show debug varobj' + Displays the current state of displaying GDB variable object + debugging info. + + +File: gdb.info, Node: Sequences, Next: TUI, Prev: Controlling GDB, Up: Top + +Canned Sequences of Commands +**************************** + +Aside from breakpoint commands (*note Breakpoint command lists: Break +Commands.), GDB provides two ways to store sequences of commands for +execution as a unit: user-defined commands and command files. + +* Menu: + +* Define:: User-defined commands +* Hooks:: User-defined command hooks +* Command Files:: Command files +* Output:: Commands for controlled output + + +File: gdb.info, Node: Define, Next: Hooks, Up: Sequences + +User-defined commands +===================== + +A "user-defined command" is a sequence of GDB commands to which you +assign a new name as a command. This is done with the `define' +command. User commands may accept up to 10 arguments separated by +whitespace. Arguments are accessed within the user command via +$ARG0...$ARG9. A trivial example: + + define adder + print $arg0 + $arg1 + $arg2 + +To execute the command use: + + adder 1 2 3 + +This defines the command `adder', which prints the sum of its three +arguments. Note the arguments are text substitutions, so they may +reference variables, use complex expressions, or even perform inferior +functions calls. + +`define COMMANDNAME' + Define a command named COMMANDNAME. If there is already a command + by that name, you are asked to confirm that you want to redefine + it. + + The definition of the command is made up of other GDB command + lines, which are given following the `define' command. The end of + these commands is marked by a line containing `end'. + +`if' + Takes a single argument, which is an expression to evaluate. It + is followed by a series of commands that are executed only if the + expression is true (nonzero). There can then optionally be a line + `else', followed by a series of commands that are only executed if + the expression was false. The end of the list is marked by a line + containing `end'. + +`while' + The syntax is similar to `if': the command takes a single argument, + which is an expression to evaluate, and must be followed by the + commands to execute, one per line, terminated by an `end'. The + commands are executed repeatedly as long as the expression + evaluates to true. + +`document COMMANDNAME' + Document the user-defined command COMMANDNAME, so that it can be + accessed by `help'. The command COMMANDNAME must already be + defined. This command reads lines of documentation just as + `define' reads the lines of the command definition, ending with + `end'. After the `document' command is finished, `help' on command + COMMANDNAME displays the documentation you have written. + + You may use the `document' command again to change the + documentation of a command. Redefining the command with `define' + does not change the documentation. + +`help user-defined' + List all user-defined commands, with the first line of the + documentation (if any) for each. + +`show user' +`show user COMMANDNAME' + Display the GDB commands used to define COMMANDNAME (but not its + documentation). If no COMMANDNAME is given, display the + definitions for all user-defined commands. + +`show max-user-call-depth' +`set max-user-call-depth' + The value of `max-user-call-depth' controls how many recursion + levels are allowed in user-defined commands before GDB suspects an + infinite recursion and aborts the command. + + + When user-defined commands are executed, the commands of the +definition are not printed. An error in any command stops execution of +the user-defined command. + + If used interactively, commands that would ask for confirmation +proceed without asking when used inside a user-defined command. Many +GDB commands that normally print messages to say what they are doing +omit the messages when used in a user-defined command. + + +File: gdb.info, Node: Hooks, Next: Command Files, Prev: Define, Up: Sequences + +User-defined command hooks +========================== + +You may define "hooks", which are a special kind of user-defined +command. Whenever you run the command `foo', if the user-defined +command `hook-foo' exists, it is executed (with no arguments) before +that command. + + A hook may also be defined which is run after the command you +executed. Whenever you run the command `foo', if the user-defined +command `hookpost-foo' exists, it is executed (with no arguments) after +that command. Post-execution hooks may exist simultaneously with +pre-execution hooks, for the same command. + + It is valid for a hook to call the command which it hooks. If this +occurs, the hook is not re-executed, thereby avoiding infinte recursion. + + In addition, a pseudo-command, `stop' exists. Defining +(`hook-stop') makes the associated commands execute every time +execution stops in your program: before breakpoint commands are run, +displays are printed, or the stack frame is printed. + + For example, to ignore `SIGALRM' signals while single-stepping, but +treat them normally during normal execution, you could define: + + define hook-stop + handle SIGALRM nopass + end + + define hook-run + handle SIGALRM pass + end + + define hook-continue + handle SIGLARM pass + end + + As a further example, to hook at the begining and end of the `echo' +command, and to add extra text to the beginning and end of the message, +you could define: + + define hook-echo + echo <<<--- + end + + define hookpost-echo + echo --->>>\n + end + + (gdb) echo Hello World + <<<---Hello World--->>> + (gdb) + + You can define a hook for any single-word command in GDB, but not +for command aliases; you should define a hook for the basic command +name, e.g. `backtrace' rather than `bt'. If an error occurs during +the execution of your hook, execution of GDB commands stops and GDB +issues a prompt (before the command that you actually typed had a +chance to run). + + If you try to define a hook which does not match any known command, +you get a warning from the `define' command. + + +File: gdb.info, Node: Command Files, Next: Output, Prev: Hooks, Up: Sequences + +Command files +============= + +A command file for GDB is a file of lines that are GDB commands. +Comments (lines starting with `#') may also be included. An empty line +in a command file does nothing; it does not mean to repeat the last +command, as it would from the terminal. + + When you start GDB, it automatically executes commands from its +"init files", normally called `.gdbinit'(1). During startup, GDB does +the following: + + 1. Reads the init file (if any) in your home directory(2). + + 2. Processes command line options and operands. + + 3. Reads the init file (if any) in the current working directory. + + 4. Reads command files specified by the `-x' option. + + The init file in your home directory can set options (such as `set +complaints') that affect subsequent processing of command line options +and operands. Init files are not executed if you use the `-nx' option +(*note Choosing modes: Mode Options.). + + On some configurations of GDB, the init file is known by a different +name (these are typically environments where a specialized form of GDB +may need to coexist with other forms, hence a different name for the +specialized version's init file). These are the environments with +special init file names: + + * VxWorks (Wind River Systems real-time OS): `.vxgdbinit' + + * OS68K (Enea Data Systems real-time OS): `.os68gdbinit' + + * ES-1800 (Ericsson Telecom AB M68000 emulator): `.esgdbinit' + + You can also request the execution of a command file with the +`source' command: + +`source FILENAME' + Execute the command file FILENAME. + + The lines in a command file are executed sequentially. They are not +printed as they are executed. An error in any command terminates +execution of the command file and control is returned to the console. + + Commands that would ask for confirmation if used interactively +proceed without asking when used in a command file. Many GDB commands +that normally print messages to say what they are doing omit the +messages when called from command files. + + GDB also accepts command input from standard input. In this mode, +normal output goes to standard output and error output goes to standard +error. Errors in a command file supplied on standard input do not +terminate execution of the command file -- execution continues with the +next command. + + gdb < cmds > log 2>&1 + + (The syntax above will vary depending on the shell used.) This +example will execute commands from the file `cmds'. All output and +errors would be directed to `log'. + + ---------- Footnotes ---------- + + (1) The DJGPP port of GDB uses the name `gdb.ini' instead, due to the +limitations of file names imposed by DOS filesystems. + + (2) On DOS/Windows systems, the home directory is the one pointed to +by the `HOME' environment variable. + + +File: gdb.info, Node: Output, Prev: Command Files, Up: Sequences + +Commands for controlled output +============================== + +During the execution of a command file or a user-defined command, normal +GDB output is suppressed; the only output that appears is what is +explicitly printed by the commands in the definition. This section +describes three commands useful for generating exactly the output you +want. + +`echo TEXT' + Print TEXT. Nonprinting characters can be included in TEXT using + C escape sequences, such as `\n' to print a newline. *No newline + is printed unless you specify one.* In addition to the standard C + escape sequences, a backslash followed by a space stands for a + space. This is useful for displaying a string with spaces at the + beginning or the end, since leading and trailing spaces are + otherwise trimmed from all arguments. To print ` and foo = ', use + the command `echo \ and foo = \ '. + + A backslash at the end of TEXT can be used, as in C, to continue + the command onto subsequent lines. For example, + + echo This is some text\n\ + which is continued\n\ + onto several lines.\n + + produces the same output as + + echo This is some text\n + echo which is continued\n + echo onto several lines.\n + +`output EXPRESSION' + Print the value of EXPRESSION and nothing but that value: no + newlines, no `$NN = '. The value is not entered in the value + history either. *Note Expressions: Expressions, for more + information on expressions. + +`output/FMT EXPRESSION' + Print the value of EXPRESSION in format FMT. You can use the same + formats as for `print'. *Note Output formats: Output Formats, for + more information. + +`printf STRING, EXPRESSIONS...' + Print the values of the EXPRESSIONS under the control of STRING. + The EXPRESSIONS are separated by commas and may be either numbers + or pointers. Their values are printed as specified by STRING, + exactly as if your program were to execute the C subroutine + + printf (STRING, EXPRESSIONS...); + + For example, you can print two values in hex like this: + + printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-foo + + The only backslash-escape sequences that you can use in the format + string are the simple ones that consist of backslash followed by a + letter. + + +File: gdb.info, Node: Interpreters, Next: Emacs, Prev: TUI, Up: Top + +Command Interpreters +******************** + +GDB supports multiple command interpreters, and some command +infrastructure to allow users or user interface writers to switch +between interpreters or run commands in other interpreters. + + GDB currently supports two command interpreters, the console +interpreter (sometimes called the command-line interpreter or CLI) and +the machine interface interpreter (or GDB/MI). This manual describes +both of these interfaces in great detail. + + By default, GDB will start with the console interpreter. However, +the user may choose to start GDB with another interpreter by specifying +the `-i' or `--interpreter' startup options. Defined interpreters +include: + +`console' + The traditional console or command-line interpreter. This is the + most often used interpreter with GDB. With no interpreter + specified at runtime, GDB will use this interpreter. + +`mi' + The newest GDB/MI interface (currently `mi2'). Used primarily by + programs wishing to use GDB as a backend for a debugger GUI or an + IDE. For more information, see *Note The GDB/MI Interface: GDB/MI. + +`mi2' + The current GDB/MI interface. + +`mi1' + The GDB/MI interface included in GDB 5.1, 5.2, and 5.3. + + + The interpreter being used by GDB may not be dynamically switched at +runtime. Although possible, this could lead to a very precarious +situation. Consider an IDE using GDB/MI. If a user enters the command +"interpreter-set console" in a console view, GDB would switch to using +the console interpreter, rendering the IDE inoperable! + + Although you may only choose a single interpreter at startup, you +may execute commands in any interpreter from the current interpreter +using the appropriate command. If you are running the console +interpreter, simply use the `interpreter-exec' command: + + interpreter-exec mi "-data-list-register-names" + + GDB/MI has a similar command, although it is only available in +versions of GDB which support GDB/MI version 2 (or greater). + + +File: gdb.info, Node: TUI, Next: Interpreters, Prev: Sequences, Up: Top + +GDB Text User Interface +*********************** + +* Menu: + +* TUI Overview:: TUI overview +* TUI Keys:: TUI key bindings +* TUI Single Key Mode:: TUI single key mode +* TUI Commands:: TUI specific commands +* TUI Configuration:: TUI configuration variables + + The GDB Text User Interface, TUI in short, is a terminal interface +which uses the `curses' library to show the source file, the assembly +output, the program registers and GDB commands in separate text windows. + + The TUI is enabled by invoking GDB using either `gdbtui' or `gdb +-tui'. + + +File: gdb.info, Node: TUI Overview, Next: TUI Keys, Up: TUI + +TUI overview +============ + +The TUI has two display modes that can be switched while GDB runs: + + * A curses (or TUI) mode in which it displays several text windows + on the terminal. + + * A standard mode which corresponds to the GDB configured without + the TUI. + + In the TUI mode, GDB can display several text window on the terminal: + +_command_ + This window is the GDB command window with the GDB prompt and the + GDB outputs. The GDB input is still managed using readline but + through the TUI. The _command_ window is always visible. + +_source_ + The source window shows the source file of the program. The + current line as well as active breakpoints are displayed in this + window. + +_assembly_ + The assembly window shows the disassembly output of the program. + +_register_ + This window shows the processor registers. It detects when a + register is changed and when this is the case, registers that have + changed are highlighted. + + + The source and assembly windows show the current program position by +highlighting the current line and marking them with the `>' marker. +Breakpoints are also indicated with two markers. A first one indicates +the breakpoint type: + +`B' + Breakpoint which was hit at least once. + +`b' + Breakpoint which was never hit. + +`H' + Hardware breakpoint which was hit at least once. + +`h' + Hardware breakpoint which was never hit. + + + The second marker indicates whether the breakpoint is enabled or not: + +`+' + Breakpoint is enabled. + +`-' + Breakpoint is disabled. + + + The source, assembly and register windows are attached to the thread +and the frame position. They are updated when the current thread +changes, when the frame changes or when the program counter changes. +These three windows are arranged by the TUI according to several +layouts. The layout defines which of these three windows are visible. +The following layouts are available: + + * source + + * assembly + + * source and assembly + + * source and registers + + * assembly and registers + + + On top of the command window a status line gives various information +concerning the current process begin debugged. The status line is +updated when the information it shows changes. The following fields +are displayed: + +_target_ + Indicates the current gdb target (*note Specifying a Debugging + Target: Targets.). + +_process_ + Gives information about the current process or thread number. + When no process is being debugged, this field is set to `No + process'. + +_function_ + Gives the current function name for the selected frame. The name + is demangled if demangling is turned on (*note Print Settings::). + When there is no symbol corresponding to the current program + counter the string `??' is displayed. + +_line_ + Indicates the current line number for the selected frame. When + the current line number is not known the string `??' is displayed. + +_pc_ + Indicates the current program counter address. + + + +File: gdb.info, Node: TUI Keys, Next: TUI Single Key Mode, Prev: TUI Overview, Up: TUI + +TUI Key Bindings +================ + +The TUI installs several key bindings in the readline keymaps (*note +Command Line Editing::). They allow to leave or enter in the TUI mode +or they operate directly on the TUI layout and windows. The TUI also +provides a _SingleKey_ keymap which binds several keys directly to GDB +commands. The following key bindings are installed for both TUI mode +and the GDB standard mode. + +`C-x C-a' +`C-x a' +`C-x A' + Enter or leave the TUI mode. When the TUI mode is left, the + curses window management is left and GDB operates using its + standard mode writing on the terminal directly. When the TUI mode + is entered, the control is given back to the curses windows. The + screen is then refreshed. + +`C-x 1' + Use a TUI layout with only one window. The layout will either be + `source' or `assembly'. When the TUI mode is not active, it will + switch to the TUI mode. + + Think of this key binding as the Emacs `C-x 1' binding. + +`C-x 2' + Use a TUI layout with at least two windows. When the current + layout shows already two windows, a next layout with two windows + is used. When a new layout is chosen, one window will always be + common to the previous layout and the new one. + + Think of it as the Emacs `C-x 2' binding. + +`C-x o' + Change the active window. The TUI associates several key bindings + (like scrolling and arrow keys) to the active window. This command + gives the focus to the next TUI window. + + Think of it as the Emacs `C-x o' binding. + +`C-x s' + Use the TUI _SingleKey_ keymap that binds single key to gdb + commands (*note TUI Single Key Mode::). + + + The following key bindings are handled only by the TUI mode: + + + Scroll the active window one page up. + + + Scroll the active window one page down. + + + Scroll the active window one line up. + + + Scroll the active window one line down. + + + Scroll the active window one column left. + + + Scroll the active window one column right. + + + Refresh the screen. + + + In the TUI mode, the arrow keys are used by the active window for +scrolling. This means they are available for readline when the active +window is the command window. When the command window does not have +the focus, it is necessary to use other readline key bindings such as +, , and . + + +File: gdb.info, Node: TUI Single Key Mode, Next: TUI Commands, Prev: TUI Keys, Up: TUI + +TUI Single Key Mode +=================== + +The TUI provides a _SingleKey_ mode in which it installs a particular +key binding in the readline keymaps to connect single keys to some gdb +commands. + +`c' + continue + +`d' + down + +`f' + finish + +`n' + next + +`q' + exit the _SingleKey_ mode. + +`r' + run + +`s' + step + +`u' + up + +`v' + info locals + +`w' + where + + + Other keys temporarily switch to the GDB command prompt. The key +that was pressed is inserted in the editing buffer so that it is +possible to type most GDB commands without interaction with the TUI +_SingleKey_ mode. Once the command is entered the TUI _SingleKey_ mode +is restored. The only way to permanently leave this mode is by hitting + or ` '. + + +File: gdb.info, Node: TUI Commands, Next: TUI Configuration, Prev: TUI Single Key Mode, Up: TUI + +TUI specific commands +===================== + +The TUI has specific commands to control the text windows. These +commands are always available, that is they do not depend on the +current terminal mode in which GDB runs. When GDB is in the standard +mode, using these commands will automatically switch in the TUI mode. + +`info win' + List and give the size of all displayed windows. + +`layout next' + Display the next layout. + +`layout prev' + Display the previous layout. + +`layout src' + Display the source window only. + +`layout asm' + Display the assembly window only. + +`layout split' + Display the source and assembly window. + +`layout regs' + Display the register window together with the source or assembly + window. + +`focus next | prev | src | asm | regs | split' + Set the focus to the named window. This command allows to change + the active window so that scrolling keys can be affected to + another window. + +`refresh' + Refresh the screen. This is similar to using key. + +`tui reg float' + Show the floating point registers in the register window. + +`tui reg general' + Show the general registers in the register window. + +`tui reg next' + Show the next register group. The list of register groups as well + as their order is target specific. The predefined register groups + are the following: `general', `float', `system', `vector', `all', + `save', `restore'. + +`tui reg system' + Show the system registers in the register window. + +`update' + Update the source window and the current execution point. + +`winheight NAME +COUNT' +`winheight NAME -COUNT' + Change the height of the window NAME by COUNT lines. Positive + counts increase the height, while negative counts decrease it. + + + +File: gdb.info, Node: TUI Configuration, Prev: TUI Commands, Up: TUI + +TUI configuration variables +=========================== + +The TUI has several configuration variables that control the appearance +of windows on the terminal. + +`set tui border-kind KIND' + Select the border appearance for the source, assembly and register + windows. The possible values are the following: + `space' + Use a space character to draw the border. + + `ascii' + Use ascii characters + - and | to draw the border. + + `acs' + Use the Alternate Character Set to draw the border. The + border is drawn using character line graphics if the terminal + supports them. + + +`set tui active-border-mode MODE' + Select the attributes to display the border of the active window. + The possible values are `normal', `standout', `reverse', `half', + `half-standout', `bold' and `bold-standout'. + +`set tui border-mode MODE' + Select the attributes to display the border of other windows. The + MODE can be one of the following: + `normal' + Use normal attributes to display the border. + + `standout' + Use standout mode. + + `reverse' + Use reverse video mode. + + `half' + Use half bright mode. + + `half-standout' + Use half bright and standout mode. + + `bold' + Use extra bright or bold mode. + + `bold-standout' + Use extra bright or bold and standout mode. + + + + +File: gdb.info, Node: Emacs, Next: Annotations, Prev: Interpreters, Up: Top + +Using GDB under GNU Emacs +************************* + +A special interface allows you to use GNU Emacs to view (and edit) the +source files for the program you are debugging with GDB. + + To use this interface, use the command `M-x gdb' in Emacs. Give the +executable file you want to debug as an argument. This command starts +GDB as a subprocess of Emacs, with input and output through a newly +created Emacs buffer. + + Using GDB under Emacs is just like using GDB normally except for two +things: + + * All "terminal" input and output goes through the Emacs buffer. + + This applies both to GDB commands and their output, and to the input +and output done by the program you are debugging. + + This is useful because it means that you can copy the text of +previous commands and input them again; you can even use parts of the +output in this way. + + All the facilities of Emacs' Shell mode are available for interacting +with your program. In particular, you can send signals the usual +way--for example, `C-c C-c' for an interrupt, `C-c C-z' for a stop. + + * GDB displays source code through Emacs. + + Each time GDB displays a stack frame, Emacs automatically finds the +source file for that frame and puts an arrow (`=>') at the left margin +of the current line. Emacs uses a separate buffer for source display, +and splits the screen to show both your GDB session and the source. + + Explicit GDB `list' or search commands still produce output as +usual, but you probably have no reason to use them from Emacs. + + If you specify an absolute file name when prompted for the `M-x gdb' +argument, then Emacs sets your current working directory to where your +program resides. If you only specify the file name, then Emacs sets +your current working directory to to the directory associated with the +previous buffer. In this case, GDB may find your program by searching +your environment's `PATH' variable, but on some operating systems it +might not find the source. So, although the GDB input and output +session proceeds normally, the auxiliary buffer does not display the +current source and line of execution. + + The initial working directory of GDB is printed on the top line of +the GDB I/O buffer and this serves as a default for the commands that +specify files for GDB to operate on. *Note Commands to specify files: +Files. + + By default, `M-x gdb' calls the program called `gdb'. If you need +to call GDB by a different name (for example, if you keep several +configurations around, with different names) you can customize the +Emacs variable `gud-gdb-command-name' to run the one you want. + + In the GDB I/O buffer, you can use these special Emacs commands in +addition to the standard Shell mode commands: + +`C-h m' + Describe the features of Emacs' GDB Mode. + +`C-c C-s' + Execute to another source line, like the GDB `step' command; also + update the display window to show the current file and location. + +`C-c C-n' + Execute to next source line in this function, skipping all function + calls, like the GDB `next' command. Then update the display window + to show the current file and location. + +`C-c C-i' + Execute one instruction, like the GDB `stepi' command; update + display window accordingly. + +`C-c C-f' + Execute until exit from the selected stack frame, like the GDB + `finish' command. + +`C-c C-r' + Continue execution of your program, like the GDB `continue' + command. + +`C-c <' + Go up the number of frames indicated by the numeric argument + (*note Numeric Arguments: (Emacs)Arguments.), like the GDB `up' + command. + +`C-c >' + Go down the number of frames indicated by the numeric argument, + like the GDB `down' command. + + In any source file, the Emacs command `C-x SPC' (`gud-break') tells +GDB to set a breakpoint on the source line point is on. + + If you type `M-x speedbar', then Emacs displays a separate frame +which shows a backtrace when the GDB I/O buffer is current. Move point +to any frame in the stack and type to make it become the current +frame and display the associated source in the source buffer. +Alternatively, click `Mouse-2' to make the selected frame become the +current one. + + If you accidentally delete the source-display buffer, an easy way to +get it back is to type the command `f' in the GDB buffer, to request a +frame display; when you run under Emacs, this recreates the source +buffer if necessary to show you the context of the current frame. + + The source files displayed in Emacs are in ordinary Emacs buffers +which are visiting the source files in the usual way. You can edit the +files with these buffers if you wish; but keep in mind that GDB +communicates with Emacs in terms of line numbers. If you add or delete +lines from the text, the line numbers that GDB knows cease to +correspond properly with the code. + + The description given here is for GNU Emacs version 21.3 and a more +detailed description of its interaction with GDB is given in the Emacs +manual (*note Debuggers: (Emacs)Debuggers.). + + +File: gdb.info, Node: GDB/MI, Next: GDB Bugs, Prev: Annotations, Up: Top + +The GDB/MI Interface +******************** + +Function and Purpose +==================== + +GDB/MI is a line based machine oriented text interface to GDB. It is +specifically intended to support the development of systems which use +the debugger as just one small component of a larger system. + + This chapter is a specification of the GDB/MI interface. It is +written in the form of a reference manual. + + Note that GDB/MI is still under construction, so some of the +features described below are incomplete and subject to change. + +Notation and Terminology +======================== + +This chapter uses the following notation: + + * `|' separates two alternatives. + + * `[ SOMETHING ]' indicates that SOMETHING is optional: it may or + may not be given. + + * `( GROUP )*' means that GROUP inside the parentheses may repeat + zero or more times. + + * `( GROUP )+' means that GROUP inside the parentheses may repeat + one or more times. + + * `"STRING"' means a literal STRING. + +Acknowledgments +=============== + +In alphabetic order: Andrew Cagney, Fernando Nasser, Stan Shebs and +Elena Zannoni. + +* Menu: + +* GDB/MI Command Syntax:: +* GDB/MI Compatibility with CLI:: +* GDB/MI Output Records:: +* GDB/MI Command Description Format:: +* GDB/MI Breakpoint Table Commands:: +* GDB/MI Data Manipulation:: +* GDB/MI Program Control:: +* GDB/MI Miscellaneous Commands:: +* GDB/MI Stack Manipulation:: +* GDB/MI Symbol Query:: +* GDB/MI Target Manipulation:: +* GDB/MI Thread Commands:: +* GDB/MI Tracepoint Commands:: +* GDB/MI Variable Objects:: + + +File: gdb.info, Node: GDB/MI Command Syntax, Next: GDB/MI Compatibility with CLI, Up: GDB/MI + +GDB/MI Command Syntax +===================== + +* Menu: + +* GDB/MI Input Syntax:: +* GDB/MI Output Syntax:: +* GDB/MI Simple Examples:: + + +File: gdb.info, Node: GDB/MI Input Syntax, Next: GDB/MI Output Syntax, Up: GDB/MI Command Syntax + +GDB/MI Input Syntax +------------------- + +`COMMAND ==>' + `CLI-COMMAND | MI-COMMAND' + +`CLI-COMMAND ==>' + `[ TOKEN ] CLI-COMMAND NL', where CLI-COMMAND is any existing GDB + CLI command. + +`MI-COMMAND ==>' + `[ TOKEN ] "-" OPERATION ( " " OPTION )* `[' " --" `]' ( " " + PARAMETER )* NL' + +`TOKEN ==>' + "any sequence of digits" + +`OPTION ==>' + `"-" PARAMETER [ " " PARAMETER ]' + +`PARAMETER ==>' + `NON-BLANK-SEQUENCE | C-STRING' + +`OPERATION ==>' + _any of the operations described in this chapter_ + +`NON-BLANK-SEQUENCE ==>' + _anything, provided it doesn't contain special characters such as + "-", NL, """ and of course " "_ + +`C-STRING ==>' + `""" SEVEN-BIT-ISO-C-STRING-CONTENT """' + +`NL ==>' + `CR | CR-LF' + +Notes: + + * The CLI commands are still handled by the MI interpreter; their + output is described below. + + * The `TOKEN', when present, is passed back when the command + finishes. + + * Some MI commands accept optional arguments as part of the parameter + list. Each option is identified by a leading `-' (dash) and may be + followed by an optional argument parameter. Options occur first + in the parameter list and can be delimited from normal parameters + using `--' (this is useful when some parameters begin with a dash). + + Pragmatics: + + * We want easy access to the existing CLI syntax (for debugging). + + * We want it to be easy to spot a MI operation. + + +File: gdb.info, Node: GDB/MI Output Syntax, Next: GDB/MI Simple Examples, Prev: GDB/MI Input Syntax, Up: GDB/MI Command Syntax + +GDB/MI Output Syntax +-------------------- + +The output from GDB/MI consists of zero or more out-of-band records +followed, optionally, by a single result record. This result record is +for the most recent command. The sequence of output records is +terminated by `(gdb)'. + + If an input command was prefixed with a `TOKEN' then the +corresponding output for that command will also be prefixed by that same +TOKEN. + +`OUTPUT ==>' + `( OUT-OF-BAND-RECORD )* [ RESULT-RECORD ] "(gdb)" NL' + +`RESULT-RECORD ==>' + ` [ TOKEN ] "^" RESULT-CLASS ( "," RESULT )* NL' + +`OUT-OF-BAND-RECORD ==>' + `ASYNC-RECORD | STREAM-RECORD' + +`ASYNC-RECORD ==>' + `EXEC-ASYNC-OUTPUT | STATUS-ASYNC-OUTPUT | NOTIFY-ASYNC-OUTPUT' + +`EXEC-ASYNC-OUTPUT ==>' + `[ TOKEN ] "*" ASYNC-OUTPUT' + +`STATUS-ASYNC-OUTPUT ==>' + `[ TOKEN ] "+" ASYNC-OUTPUT' + +`NOTIFY-ASYNC-OUTPUT ==>' + `[ TOKEN ] "=" ASYNC-OUTPUT' + +`ASYNC-OUTPUT ==>' + `ASYNC-CLASS ( "," RESULT )* NL' + +`RESULT-CLASS ==>' + `"done" | "running" | "connected" | "error" | "exit"' + +`ASYNC-CLASS ==>' + `"stopped" | OTHERS' (where OTHERS will be added depending on the + needs--this is still in development). + +`RESULT ==>' + ` VARIABLE "=" VALUE' + +`VARIABLE ==>' + ` STRING ' + +`VALUE ==>' + ` CONST | TUPLE | LIST ' + +`CONST ==>' + `C-STRING' + +`TUPLE ==>' + ` "{}" | "{" RESULT ( "," RESULT )* "}" ' + +`LIST ==>' + ` "[]" | "[" VALUE ( "," VALUE )* "]" | "[" RESULT ( "," RESULT )* + "]" ' + +`STREAM-RECORD ==>' + `CONSOLE-STREAM-OUTPUT | TARGET-STREAM-OUTPUT | LOG-STREAM-OUTPUT' + +`CONSOLE-STREAM-OUTPUT ==>' + `"~" C-STRING' + +`TARGET-STREAM-OUTPUT ==>' + `"@" C-STRING' + +`LOG-STREAM-OUTPUT ==>' + `"&" C-STRING' + +`NL ==>' + `CR | CR-LF' + +`TOKEN ==>' + _any sequence of digits_. + +Notes: + + * All output sequences end in a single line containing a period. + + * The `TOKEN' is from the corresponding request. If an execution + command is interrupted by the `-exec-interrupt' command, the TOKEN + associated with the `*stopped' message is the one of the original + execution command, not the one of the interrupt command. + + * STATUS-ASYNC-OUTPUT contains on-going status information about the + progress of a slow operation. It can be discarded. All status + output is prefixed by `+'. + + * EXEC-ASYNC-OUTPUT contains asynchronous state change on the target + (stopped, started, disappeared). All async output is prefixed by + `*'. + + * NOTIFY-ASYNC-OUTPUT contains supplementary information that the + client should handle (e.g., a new breakpoint information). All + notify output is prefixed by `='. + + * CONSOLE-STREAM-OUTPUT is output that should be displayed as is in + the console. It is the textual response to a CLI command. All + the console output is prefixed by `~'. + + * TARGET-STREAM-OUTPUT is the output produced by the target program. + All the target output is prefixed by `@'. + + * LOG-STREAM-OUTPUT is output text coming from GDB's internals, for + instance messages that should be displayed as part of an error + log. All the log output is prefixed by `&'. + + * New GDB/MI commands should only output LISTS containing VALUES. + + + *Note GDB/MI Stream Records: GDB/MI Stream Records, for more details +about the various output records. + + +File: gdb.info, Node: GDB/MI Simple Examples, Prev: GDB/MI Output Syntax, Up: GDB/MI Command Syntax + +Simple Examples of GDB/MI Interaction +------------------------------------- + +This subsection presents several simple examples of interaction using +the GDB/MI interface. In these examples, `->' means that the following +line is passed to GDB/MI as input, while `<-' means the output received +from GDB/MI. + +Target Stop +........... + +Here's an example of stopping the inferior process: + + -> -stop + <- (gdb) + +and later: + + <- *stop,reason="stop",address="0x123",source="a.c:123" + <- (gdb) + +Simple CLI Command +.................. + +Here's an example of a simple CLI command being passed through GDB/MI +and on to the CLI. + + -> print 1+2 + <- &"print 1+2\n" + <- ~"$1 = 3\n" + <- ^done + <- (gdb) + +Command With Side Effects +......................... + + -> -symbol-file xyz.exe + <- *breakpoint,nr="3",address="0x123",source="a.c:123" + <- (gdb) + +A Bad Command +............. + +Here's what happens if you pass a non-existent command: + + -> -rubbish + <- ^error,msg="Undefined MI command: rubbish" + <- (gdb) + + +File: gdb.info, Node: GDB/MI Compatibility with CLI, Next: GDB/MI Output Records, Prev: GDB/MI Command Syntax, Up: GDB/MI + +GDB/MI Compatibility with CLI +============================= + +To help users familiar with GDB's existing CLI interface, GDB/MI +accepts existing CLI commands. As specified by the syntax, such +commands can be directly entered into the GDB/MI interface and GDB will +respond. + + This mechanism is provided as an aid to developers of GDB/MI clients +and not as a reliable interface into the CLI. Since the command is +being interpreteted in an environment that assumes GDB/MI behaviour, +the exact output of such commands is likely to end up being an +un-supported hybrid of GDB/MI and CLI output. + + +File: gdb.info, Node: GDB/MI Output Records, Next: GDB/MI Command Description Format, Prev: GDB/MI Compatibility with CLI, Up: GDB/MI + +GDB/MI Output Records +===================== + +* Menu: + +* GDB/MI Result Records:: +* GDB/MI Stream Records:: +* GDB/MI Out-of-band Records:: + + +File: gdb.info, Node: GDB/MI Result Records, Next: GDB/MI Stream Records, Up: GDB/MI Output Records + +GDB/MI Result Records +--------------------- + +In addition to a number of out-of-band notifications, the response to a +GDB/MI command includes one of the following result indications: + +`"^done" [ "," RESULTS ]' + The synchronous operation was successful, `RESULTS' are the return + values. + +`"^running"' + The asynchronous operation was successfully started. The target is + running. + +`"^error" "," C-STRING' + The operation failed. The `C-STRING' contains the corresponding + error message. + + +File: gdb.info, Node: GDB/MI Stream Records, Next: GDB/MI Out-of-band Records, Prev: GDB/MI Result Records, Up: GDB/MI Output Records + +GDB/MI Stream Records +--------------------- + +GDB internally maintains a number of output streams: the console, the +target, and the log. The output intended for each of these streams is +funneled through the GDB/MI interface using "stream records". + + Each stream record begins with a unique "prefix character" which +identifies its stream (*note GDB/MI Output Syntax: GDB/MI Output +Syntax.). In addition to the prefix, each stream record contains a +`STRING-OUTPUT'. This is either raw text (with an implicit new line) +or a quoted C string (which does not contain an implicit newline). + +`"~" STRING-OUTPUT' + The console output stream contains text that should be displayed + in the CLI console window. It contains the textual responses to + CLI commands. + +`"@" STRING-OUTPUT' + The target output stream contains any textual output from the + running target. + +`"&" STRING-OUTPUT' + The log stream contains debugging messages being produced by GDB's + internals. + + +File: gdb.info, Node: GDB/MI Out-of-band Records, Prev: GDB/MI Stream Records, Up: GDB/MI Output Records + +GDB/MI Out-of-band Records +-------------------------- + +"Out-of-band" records are used to notify the GDB/MI client of +additional changes that have occurred. Those changes can either be a +consequence of GDB/MI (e.g., a breakpoint modified) or a result of +target activity (e.g., target stopped). + + The following is a preliminary list of possible out-of-band records. + +`"*" "stop"' + + +File: gdb.info, Node: GDB/MI Command Description Format, Next: GDB/MI Breakpoint Table Commands, Prev: GDB/MI Output Records, Up: GDB/MI + +GDB/MI Command Description Format +================================= + +The remaining sections describe blocks of commands. Each block of +commands is laid out in a fashion similar to this section. + + Note the the line breaks shown in the examples are here only for +readability. They don't appear in the real output. Also note that the +commands with a non-available example (N.A.) are not yet implemented. + +Motivation +---------- + +The motivation for this collection of commands. + +Introduction +------------ + +A brief introduction to this collection of commands as a whole. + +Commands +-------- + +For each command in the block, the following is described: + +Synopsis +........ + + -command ARGS... + +GDB Command +........... + +The corresponding GDB CLI command. + +Result +...... + +Out-of-band +........... + +Notes +..... + +Example +....... + + +File: gdb.info, Node: GDB/MI Breakpoint Table Commands, Next: GDB/MI Data Manipulation, Prev: GDB/MI Command Description Format, Up: GDB/MI + +GDB/MI Breakpoint table commands +================================ + +This section documents GDB/MI commands for manipulating breakpoints. + +The `-break-after' Command +-------------------------- + +Synopsis +........ + + -break-after NUMBER COUNT + + The breakpoint number NUMBER is not in effect until it has been hit +COUNT times. To see how this is reflected in the output of the +`-break-list' command, see the description of the `-break-list' command +below. + +GDB Command +........... + +The corresponding GDB command is `ignore'. + +Example +....... + + (gdb) + -break-insert main + ^done,bkpt={number="1",addr="0x000100d0",file="hello.c",line="5"} + (gdb) + -break-after 1 3 + ~ + ^done + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="1",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", + addr="0x000100d0",func="main",file="hello.c",line="5",times="0", + ignore="3"}]} + (gdb) + +The `-break-condition' Command +------------------------------ + +Synopsis +........ + + -break-condition NUMBER EXPR + + Breakpoint NUMBER will stop the program only if the condition in +EXPR is true. The condition becomes part of the `-break-list' output +(see the description of the `-break-list' command below). + +GDB Command +........... + +The corresponding GDB command is `condition'. + +Example +....... + + (gdb) + -break-condition 1 1 + ^done + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="1",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", + addr="0x000100d0",func="main",file="hello.c",line="5",cond="1", + times="0",ignore="3"}]} + (gdb) + +The `-break-delete' Command +--------------------------- + +Synopsis +........ + + -break-delete ( BREAKPOINT )+ + + Delete the breakpoint(s) whose number(s) are specified in the +argument list. This is obviously reflected in the breakpoint list. + +GDB command +........... + +The corresponding GDB command is `delete'. + +Example +....... + + (gdb) + -break-delete 1 + ^done + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="0",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[]} + (gdb) + +The `-break-disable' Command +---------------------------- + +Synopsis +........ + + -break-disable ( BREAKPOINT )+ + + Disable the named BREAKPOINT(s). The field `enabled' in the break +list is now set to `n' for the named BREAKPOINT(s). + +GDB Command +........... + +The corresponding GDB command is `disable'. + +Example +....... + + (gdb) + -break-disable 2 + ^done + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="1",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="2",type="breakpoint",disp="keep",enabled="n", + addr="0x000100d0",func="main",file="hello.c",line="5",times="0"}]} + (gdb) + +The `-break-enable' Command +--------------------------- + +Synopsis +........ + + -break-enable ( BREAKPOINT )+ + + Enable (previously disabled) BREAKPOINT(s). + +GDB Command +........... + +The corresponding GDB command is `enable'. + +Example +....... + + (gdb) + -break-enable 2 + ^done + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="1",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="2",type="breakpoint",disp="keep",enabled="y", + addr="0x000100d0",func="main",file="hello.c",line="5",times="0"}]} + (gdb) + +The `-break-info' Command +------------------------- + +Synopsis +........ + + -break-info BREAKPOINT + + Get information about a single breakpoint. + +GDB command +........... + +The corresponding GDB command is `info break BREAKPOINT'. + +Example +....... + +N.A. + +The `-break-insert' Command +--------------------------- + +Synopsis +........ + + -break-insert [ -t ] [ -h ] [ -r ] + [ -c CONDITION ] [ -i IGNORE-COUNT ] + [ -p THREAD ] [ LINE | ADDR ] + +If specified, LINE, can be one of: + + * function + + * filename:linenum + + * filename:function + + * *address + + The possible optional parameters of this command are: + +`-t' + Insert a tempoary breakpoint. + +`-h' + Insert a hardware breakpoint. + +`-c CONDITION' + Make the breakpoint conditional on CONDITION. + +`-i IGNORE-COUNT' + Initialize the IGNORE-COUNT. + +`-r' + Insert a regular breakpoint in all the functions whose names match + the given regular expression. Other flags are not applicable to + regular expresson. + +Result +...... + +The result is in the form: + + ^done,bkptno="NUMBER",func="FUNCNAME", + file="FILENAME",line="LINENO" + +where NUMBER is the GDB number for this breakpoint, FUNCNAME is the +name of the function where the breakpoint was inserted, FILENAME is the +name of the source file which contains this function, and LINENO is the +source line number within that file. + + Note: this format is open to change. + +GDB Command +........... + +The corresponding GDB commands are `break', `tbreak', `hbreak', +`thbreak', and `rbreak'. + +Example +....... + + (gdb) + -break-insert main + ^done,bkpt={number="1",addr="0x0001072c",file="recursive2.c",line="4"} + (gdb) + -break-insert -t foo + ^done,bkpt={number="2",addr="0x00010774",file="recursive2.c",line="11"} + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="2",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", + addr="0x0001072c", func="main",file="recursive2.c",line="4",times="0"}, + bkpt={number="2",type="breakpoint",disp="del",enabled="y", + addr="0x00010774",func="foo",file="recursive2.c",line="11",times="0"}]} + (gdb) + -break-insert -r foo.* + ~int foo(int, int); + ^done,bkpt={number="3",addr="0x00010774",file="recursive2.c",line="11"} + (gdb) + +The `-break-list' Command +------------------------- + +Synopsis +........ + + -break-list + + Displays the list of inserted breakpoints, showing the following +fields: + +`Number' + number of the breakpoint + +`Type' + type of the breakpoint: `breakpoint' or `watchpoint' + +`Disposition' + should the breakpoint be deleted or disabled when it is hit: `keep' + or `nokeep' + +`Enabled' + is the breakpoint enabled or no: `y' or `n' + +`Address' + memory location at which the breakpoint is set + +`What' + logical location of the breakpoint, expressed by function name, + file name, line number + +`Times' + number of times the breakpoint has been hit + + If there are no breakpoints or watchpoints, the `BreakpointTable' +`body' field is an empty list. + +GDB Command +........... + +The corresponding GDB command is `info break'. + +Example +....... + + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="2",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", + addr="0x000100d0",func="main",file="hello.c",line="5",times="0"}, + bkpt={number="2",type="breakpoint",disp="keep",enabled="y", + addr="0x00010114",func="foo",file="hello.c",line="13",times="0"}]} + (gdb) + + Here's an example of the result when there are no breakpoints: + + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="0",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[]} + (gdb) + +The `-break-watch' Command +-------------------------- + +Synopsis +........ + + -break-watch [ -a | -r ] + + Create a watchpoint. With the `-a' option it will create an +"access" watchpoint, i.e. a watchpoint that triggers either on a read +from or on a write to the memory location. With the `-r' option, the +watchpoint created is a "read" watchpoint, i.e. it will trigger only +when the memory location is accessed for reading. Without either of +the options, the watchpoint created is a regular watchpoint, i.e. it +will trigger when the memory location is accessed for writing. *Note +Setting watchpoints: Set Watchpoints. + + Note that `-break-list' will report a single list of watchpoints and +breakpoints inserted. + +GDB Command +........... + +The corresponding GDB commands are `watch', `awatch', and `rwatch'. + +Example +....... + +Setting a watchpoint on a variable in the `main' function: + + (gdb) + -break-watch x + ^done,wpt={number="2",exp="x"} + (gdb) + -exec-continue + ^running + ^done,reason="watchpoint-trigger",wpt={number="2",exp="x"}, + value={old="-268439212",new="55"}, + frame={func="main",args=[],file="recursive2.c",line="5"} + (gdb) + + Setting a watchpoint on a variable local to a function. GDB will +stop the program execution twice: first for the variable changing +value, then for the watchpoint going out of scope. + + (gdb) + -break-watch C + ^done,wpt={number="5",exp="C"} + (gdb) + -exec-continue + ^running + ^done,reason="watchpoint-trigger", + wpt={number="5",exp="C"},value={old="-276895068",new="3"}, + frame={func="callee4",args=[], + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"} + (gdb) + -exec-continue + ^running + ^done,reason="watchpoint-scope",wpnum="5", + frame={func="callee3",args=[{name="strarg", + value="0x11940 \"A string argument.\""}], + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"} + (gdb) + + Listing breakpoints and watchpoints, at different points in the +program execution. Note that once the watchpoint goes out of scope, it +is deleted. + + (gdb) + -break-watch C + ^done,wpt={number="2",exp="C"} + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="2",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", + addr="0x00010734",func="callee4", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"}, + bkpt={number="2",type="watchpoint",disp="keep", + enabled="y",addr="",what="C",times="0"}]} + (gdb) + -exec-continue + ^running + ^done,reason="watchpoint-trigger",wpt={number="2",exp="C"}, + value={old="-276895068",new="3"}, + frame={func="callee4",args=[], + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"} + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="2",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", + addr="0x00010734",func="callee4", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"}, + bkpt={number="2",type="watchpoint",disp="keep", + enabled="y",addr="",what="C",times="-5"}]} + (gdb) + -exec-continue + ^running + ^done,reason="watchpoint-scope",wpnum="2", + frame={func="callee3",args=[{name="strarg", + value="0x11940 \"A string argument.\""}], + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"} + (gdb) + -break-list + ^done,BreakpointTable={nr_rows="1",nr_cols="6", + hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"}, + {width="14",alignment="-1",col_name="type",colhdr="Type"}, + {width="4",alignment="-1",col_name="disp",colhdr="Disp"}, + {width="3",alignment="-1",col_name="enabled",colhdr="Enb"}, + {width="10",alignment="-1",col_name="addr",colhdr="Address"}, + {width="40",alignment="2",col_name="what",colhdr="What"}], + body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", + addr="0x00010734",func="callee4", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"}]} + (gdb) + + +File: gdb.info, Node: GDB/MI Data Manipulation, Next: GDB/MI Program Control, Prev: GDB/MI Breakpoint Table Commands, Up: GDB/MI + +GDB/MI Data Manipulation +======================== + +This section describes the GDB/MI commands that manipulate data: +examine memory and registers, evaluate expressions, etc. + +The `-data-disassemble' Command +------------------------------- + +Synopsis +........ + + -data-disassemble + [ -s START-ADDR -e END-ADDR ] + | [ -f FILENAME -l LINENUM [ -n LINES ] ] + -- MODE + +Where: + +`START-ADDR' + is the beginning address (or `$pc') + +`END-ADDR' + is the end address + +`FILENAME' + is the name of the file to disassemble + +`LINENUM' + is the line number to disassemble around + +`LINES' + is the the number of disassembly lines to be produced. If it is + -1, the whole function will be disassembled, in case no END-ADDR is + specified. If END-ADDR is specified as a non-zero value, and + LINES is lower than the number of disassembly lines between + START-ADDR and END-ADDR, only LINES lines are displayed; if LINES + is higher than the number of lines between START-ADDR and + END-ADDR, only the lines up to END-ADDR are displayed. + +`MODE' + is either 0 (meaning only disassembly) or 1 (meaning mixed source + and disassembly). + +Result +...... + +The output for each instruction is composed of four fields: + + * Address + + * Func-name + + * Offset + + * Instruction + + Note that whatever included in the instruction field, is not +manipulated directely by GDB/MI, i.e. it is not possible to adjust its +format. + +GDB Command +........... + +There's no direct mapping from this command to the CLI. + +Example +....... + +Disassemble from the current value of `$pc' to `$pc + 20': + + (gdb) + -data-disassemble -s $pc -e "$pc + 20" -- 0 + ^done, + asm_insns=[ + {address="0x000107c0",func-name="main",offset="4", + inst="mov 2, %o0"}, + {address="0x000107c4",func-name="main",offset="8", + inst="sethi %hi(0x11800), %o2"}, + {address="0x000107c8",func-name="main",offset="12", + inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"}, + {address="0x000107cc",func-name="main",offset="16", + inst="sethi %hi(0x11800), %o2"}, + {address="0x000107d0",func-name="main",offset="20", + inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"}] + (gdb) + + Disassemble the whole `main' function. Line 32 is part of `main'. + + -data-disassemble -f basics.c -l 32 -- 0 + ^done,asm_insns=[ + {address="0x000107bc",func-name="main",offset="0", + inst="save %sp, -112, %sp"}, + {address="0x000107c0",func-name="main",offset="4", + inst="mov 2, %o0"}, + {address="0x000107c4",func-name="main",offset="8", + inst="sethi %hi(0x11800), %o2"}, + [...] + {address="0x0001081c",func-name="main",offset="96",inst="ret "}, + {address="0x00010820",func-name="main",offset="100",inst="restore "}] + (gdb) + + Disassemble 3 instructions from the start of `main': + + (gdb) + -data-disassemble -f basics.c -l 32 -n 3 -- 0 + ^done,asm_insns=[ + {address="0x000107bc",func-name="main",offset="0", + inst="save %sp, -112, %sp"}, + {address="0x000107c0",func-name="main",offset="4", + inst="mov 2, %o0"}, + {address="0x000107c4",func-name="main",offset="8", + inst="sethi %hi(0x11800), %o2"}] + (gdb) + + Disassemble 3 instructions from the start of `main' in mixed mode: + + (gdb) + -data-disassemble -f basics.c -l 32 -n 3 -- 1 + ^done,asm_insns=[ + src_and_asm_line={line="31", + file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ + testsuite/gdb.mi/basics.c",line_asm_insn=[ + {address="0x000107bc",func-name="main",offset="0", + inst="save %sp, -112, %sp"}]}, + src_and_asm_line={line="32", + file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ + testsuite/gdb.mi/basics.c",line_asm_insn=[ + {address="0x000107c0",func-name="main",offset="4", + inst="mov 2, %o0"}, + {address="0x000107c4",func-name="main",offset="8", + inst="sethi %hi(0x11800), %o2"}]}] + (gdb) + +The `-data-evaluate-expression' Command +--------------------------------------- + +Synopsis +........ + + -data-evaluate-expression EXPR + + Evaluate EXPR as an expression. The expression could contain an +inferior function call. The function call will execute synchronously. +If the expression contains spaces, it must be enclosed in double quotes. + +GDB Command +........... + +The corresponding GDB commands are `print', `output', and `call'. In +`gdbtk' only, there's a corresponding `gdb_eval' command. + +Example +....... + +In the following example, the numbers that precede the commands are the +"tokens" described in *Note GDB/MI Command Syntax: GDB/MI Command +Syntax. Notice how GDB/MI returns the same tokens in its output. + + 211-data-evaluate-expression A + 211^done,value="1" + (gdb) + 311-data-evaluate-expression &A + 311^done,value="0xefffeb7c" + (gdb) + 411-data-evaluate-expression A+3 + 411^done,value="4" + (gdb) + 511-data-evaluate-expression "A + 3" + 511^done,value="4" + (gdb) + +The `-data-list-changed-registers' Command +------------------------------------------ + +Synopsis +........ + + -data-list-changed-registers + + Display a list of the registers that have changed. + +GDB Command +........... + +GDB doesn't have a direct analog for this command; `gdbtk' has the +corresponding command `gdb_changed_register_list'. + +Example +....... + +On a PPC MBX board: + + (gdb) + -exec-continue + ^running + + (gdb) + *stopped,reason="breakpoint-hit",bkptno="1",frame={func="main", + args=[],file="try.c",line="5"} + (gdb) + -data-list-changed-registers + ^done,changed-registers=["0","1","2","4","5","6","7","8","9", + "10","11","13","14","15","16","17","18","19","20","21","22","23", + "24","25","26","27","28","30","31","64","65","66","67","69"] + (gdb) + +The `-data-list-register-names' Command +--------------------------------------- + +Synopsis +........ + + -data-list-register-names [ ( REGNO )+ ] + + Show a list of register names for the current target. If no +arguments are given, it shows a list of the names of all the registers. +If integer numbers are given as arguments, it will print a list of the +names of the registers corresponding to the arguments. To ensure +consistency between a register name and its number, the output list may +include empty register names. + +GDB Command +........... + +GDB does not have a command which corresponds to +`-data-list-register-names'. In `gdbtk' there is a corresponding +command `gdb_regnames'. + +Example +....... + +For the PPC MBX board: + (gdb) + -data-list-register-names + ^done,register-names=["r0","r1","r2","r3","r4","r5","r6","r7", + "r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18", + "r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", + "r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", + "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20", + "f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31", + "", "pc","ps","cr","lr","ctr","xer"] + (gdb) + -data-list-register-names 1 2 3 + ^done,register-names=["r1","r2","r3"] + (gdb) + +The `-data-list-register-values' Command +---------------------------------------- + +Synopsis +........ + + -data-list-register-values FMT [ ( REGNO )*] + + Display the registers' contents. FMT is the format according to +which the registers' contents are to be returned, followed by an +optional list of numbers specifying the registers to display. A +missing list of numbers indicates that the contents of all the +registers must be returned. + + Allowed formats for FMT are: + +`x' + Hexadecimal + +`o' + Octal + +`t' + Binary + +`d' + Decimal + +`r' + Raw + +`N' + Natural + +GDB Command +........... + +The corresponding GDB commands are `info reg', `info all-reg', and (in +`gdbtk') `gdb_fetch_registers'. + +Example +....... + +For a PPC MBX board (note: line breaks are for readability only, they +don't appear in the actual output): + + (gdb) + -data-list-register-values r 64 65 + ^done,register-values=[{number="64",value="0xfe00a300"}, + {number="65",value="0x00029002"}] + (gdb) + -data-list-register-values x + ^done,register-values=[{number="0",value="0xfe0043c8"}, + {number="1",value="0x3fff88"},{number="2",value="0xfffffffe"}, + {number="3",value="0x0"},{number="4",value="0xa"}, + {number="5",value="0x3fff68"},{number="6",value="0x3fff58"}, + {number="7",value="0xfe011e98"},{number="8",value="0x2"}, + {number="9",value="0xfa202820"},{number="10",value="0xfa202808"}, + {number="11",value="0x1"},{number="12",value="0x0"}, + {number="13",value="0x4544"},{number="14",value="0xffdfffff"}, + {number="15",value="0xffffffff"},{number="16",value="0xfffffeff"}, + {number="17",value="0xefffffed"},{number="18",value="0xfffffffe"}, + {number="19",value="0xffffffff"},{number="20",value="0xffffffff"}, + {number="21",value="0xffffffff"},{number="22",value="0xfffffff7"}, + {number="23",value="0xffffffff"},{number="24",value="0xffffffff"}, + {number="25",value="0xffffffff"},{number="26",value="0xfffffffb"}, + {number="27",value="0xffffffff"},{number="28",value="0xf7bfffff"}, + {number="29",value="0x0"},{number="30",value="0xfe010000"}, + {number="31",value="0x0"},{number="32",value="0x0"}, + {number="33",value="0x0"},{number="34",value="0x0"}, + {number="35",value="0x0"},{number="36",value="0x0"}, + {number="37",value="0x0"},{number="38",value="0x0"}, + {number="39",value="0x0"},{number="40",value="0x0"}, + {number="41",value="0x0"},{number="42",value="0x0"}, + {number="43",value="0x0"},{number="44",value="0x0"}, + {number="45",value="0x0"},{number="46",value="0x0"}, + {number="47",value="0x0"},{number="48",value="0x0"}, + {number="49",value="0x0"},{number="50",value="0x0"}, + {number="51",value="0x0"},{number="52",value="0x0"}, + {number="53",value="0x0"},{number="54",value="0x0"}, + {number="55",value="0x0"},{number="56",value="0x0"}, + {number="57",value="0x0"},{number="58",value="0x0"}, + {number="59",value="0x0"},{number="60",value="0x0"}, + {number="61",value="0x0"},{number="62",value="0x0"}, + {number="63",value="0x0"},{number="64",value="0xfe00a300"}, + {number="65",value="0x29002"},{number="66",value="0x202f04b5"}, + {number="67",value="0xfe0043b0"},{number="68",value="0xfe00b3e4"}, + {number="69",value="0x20002b03"}] + (gdb) + +The `-data-read-memory' Command +------------------------------- + +Synopsis +........ + + -data-read-memory [ -o BYTE-OFFSET ] + ADDRESS WORD-FORMAT WORD-SIZE + NR-ROWS NR-COLS [ ASCHAR ] + +where: + +`ADDRESS' + An expression specifying the address of the first memory word to be + read. Complex expressions containing embedded white space should + be quoted using the C convention. + +`WORD-FORMAT' + The format to be used to print the memory words. The notation is + the same as for GDB's `print' command (*note Output formats: + Output Formats.). + +`WORD-SIZE' + The size of each memory word in bytes. + +`NR-ROWS' + The number of rows in the output table. + +`NR-COLS' + The number of columns in the output table. + +`ASCHAR' + If present, indicates that each row should include an ASCII dump. + The value of ASCHAR is used as a padding character when a byte is + not a member of the printable ASCII character set (printable ASCII + characters are those whose code is between 32 and 126, + inclusively). + +`BYTE-OFFSET' + An offset to add to the ADDRESS before fetching memory. + + This command displays memory contents as a table of NR-ROWS by +NR-COLS words, each word being WORD-SIZE bytes. In total, `NR-ROWS * +NR-COLS * WORD-SIZE' bytes are read (returned as `total-bytes'). +Should less than the requested number of bytes be returned by the +target, the missing words are identified using `N/A'. The number of +bytes read from the target is returned in `nr-bytes' and the starting +address used to read memory in `addr'. + + The address of the next/previous row or page is available in +`next-row' and `prev-row', `next-page' and `prev-page'. + +GDB Command +........... + +The corresponding GDB command is `x'. `gdbtk' has `gdb_get_mem' memory +read command. + +Example +....... + +Read six bytes of memory starting at `bytes+6' but then offset by `-6' +bytes. Format as three rows of two columns. One byte per word. +Display each word in hex. + + (gdb) + 9-data-read-memory -o -6 -- bytes+6 x 1 3 2 + 9^done,addr="0x00001390",nr-bytes="6",total-bytes="6", + next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396", + prev-page="0x0000138a",memory=[ + {addr="0x00001390",data=["0x00","0x01"]}, + {addr="0x00001392",data=["0x02","0x03"]}, + {addr="0x00001394",data=["0x04","0x05"]}] + (gdb) + + Read two bytes of memory starting at address `shorts + 64' and +display as a single word formatted in decimal. + + (gdb) + 5-data-read-memory shorts+64 d 2 1 1 + 5^done,addr="0x00001510",nr-bytes="2",total-bytes="2", + next-row="0x00001512",prev-row="0x0000150e", + next-page="0x00001512",prev-page="0x0000150e",memory=[ + {addr="0x00001510",data=["128"]}] + (gdb) + + Read thirty two bytes of memory starting at `bytes+16' and format as +eight rows of four columns. Include a string encoding with `x' used as +the non-printable character. + + (gdb) + 4-data-read-memory bytes+16 x 1 8 4 x + 4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32", + next-row="0x000013c0",prev-row="0x0000139c", + next-page="0x000013c0",prev-page="0x00001380",memory=[ + {addr="0x000013a0",data=["0x10","0x11","0x12","0x13"],ascii="xxxx"}, + {addr="0x000013a4",data=["0x14","0x15","0x16","0x17"],ascii="xxxx"}, + {addr="0x000013a8",data=["0x18","0x19","0x1a","0x1b"],ascii="xxxx"}, + {addr="0x000013ac",data=["0x1c","0x1d","0x1e","0x1f"],ascii="xxxx"}, + {addr="0x000013b0",data=["0x20","0x21","0x22","0x23"],ascii=" !\"#"}, + {addr="0x000013b4",data=["0x24","0x25","0x26","0x27"],ascii="$%&'"}, + {addr="0x000013b8",data=["0x28","0x29","0x2a","0x2b"],ascii="()*+"}, + {addr="0x000013bc",data=["0x2c","0x2d","0x2e","0x2f"],ascii=",-./"}] + (gdb) + +The `-display-delete' Command +----------------------------- + +Synopsis +........ + + -display-delete NUMBER + + Delete the display NUMBER. + +GDB Command +........... + +The corresponding GDB command is `delete display'. + +Example +....... + +N.A. + +The `-display-disable' Command +------------------------------ + +Synopsis +........ + + -display-disable NUMBER + + Disable display NUMBER. + +GDB Command +........... + +The corresponding GDB command is `disable display'. + +Example +....... + +N.A. + +The `-display-enable' Command +----------------------------- + +Synopsis +........ + + -display-enable NUMBER + + Enable display NUMBER. + +GDB Command +........... + +The corresponding GDB command is `enable display'. + +Example +....... + +N.A. + +The `-display-insert' Command +----------------------------- + +Synopsis +........ + + -display-insert EXPRESSION + + Display EXPRESSION every time the program stops. + +GDB Command +........... + +The corresponding GDB command is `display'. + +Example +....... + +N.A. + +The `-display-list' Command +--------------------------- + +Synopsis +........ + + -display-list + + List the displays. Do not show the current values. + +GDB Command +........... + +The corresponding GDB command is `info display'. + +Example +....... + +N.A. + +The `-environment-cd' Command +----------------------------- + +Synopsis +........ + + -environment-cd PATHDIR + + Set GDB's working directory. + +GDB Command +........... + +The corresponding GDB command is `cd'. + +Example +....... + + (gdb) + -environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb + ^done + (gdb) + +The `-environment-directory' Command +------------------------------------ + +Synopsis +........ + + -environment-directory [ -r ] [ PATHDIR ]+ + + Add directories PATHDIR to beginning of search path for source files. +If the `-r' option is used, the search path is reset to the default +search path. If directories PATHDIR are supplied in addition to the +`-r' option, the search path is first reset and then addition occurs as +normal. Multiple directories may be specified, separated by blanks. +Specifying multiple directories in a single command results in the +directories added to the beginning of the search path in the same order +they were presented in the command. If blanks are needed as part of a +directory name, double-quotes should be used around the name. In the +command output, the path will show up separated by the system +directory-separator character. The directory-seperator character must +not be used in any directory name. If no directories are specified, +the current search path is displayed. + +GDB Command +........... + +The corresponding GDB command is `dir'. + +Example +....... + + (gdb) + -environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb + ^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd" + (gdb) + -environment-directory "" + ^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd" + (gdb) + -environment-directory -r /home/jjohnstn/src/gdb /usr/src + ^done,source-path="/home/jjohnstn/src/gdb:/usr/src:$cdir:$cwd" + (gdb) + -environment-directory -r + ^done,source-path="$cdir:$cwd" + (gdb) + +The `-environment-path' Command +------------------------------- + +Synopsis +........ + + -environment-path [ -r ] [ PATHDIR ]+ + + Add directories PATHDIR to beginning of search path for object files. +If the `-r' option is used, the search path is reset to the original +search path that existed at gdb start-up. If directories PATHDIR are +supplied in addition to the `-r' option, the search path is first reset +and then addition occurs as normal. Multiple directories may be +specified, separated by blanks. Specifying multiple directories in a +single command results in the directories added to the beginning of the +search path in the same order they were presented in the command. If +blanks are needed as part of a directory name, double-quotes should be +used around the name. In the command output, the path will show up +separated by the system directory-separator character. The +directory-seperator character must not be used in any directory name. +If no directories are specified, the current path is displayed. + +GDB Command +........... + +The corresponding GDB command is `path'. + +Example +....... + + (gdb) + -environment-path + ^done,path="/usr/bin" + (gdb) + -environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb /bin + ^done,path="/kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb:/bin:/usr/bin" + (gdb) + -environment-path -r /usr/local/bin + ^done,path="/usr/local/bin:/usr/bin" + (gdb) + +The `-environment-pwd' Command +------------------------------ + +Synopsis +........ + + -environment-pwd + + Show the current working directory. + +GDB command +........... + +The corresponding GDB command is `pwd'. + +Example +....... + + (gdb) + -environment-pwd + ^done,cwd="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb" + (gdb) + + +File: gdb.info, Node: GDB/MI Program Control, Next: GDB/MI Miscellaneous Commands, Prev: GDB/MI Data Manipulation, Up: GDB/MI + +GDB/MI Program control +====================== + +Program termination +................... + +As a result of execution, the inferior program can run to completion, if +it doesn't encounter any breakpoints. In this case the output will +include an exit code, if the program has exited exceptionally. + +Examples +........ + +Program exited normally: + + (gdb) + -exec-run + ^running + (gdb) + x = 55 + *stopped,reason="exited-normally" + (gdb) + +Program exited exceptionally: + + (gdb) + -exec-run + ^running + (gdb) + x = 55 + *stopped,reason="exited",exit-code="01" + (gdb) + + Another way the program can terminate is if it receives a signal +such as `SIGINT'. In this case, GDB/MI displays this: + + (gdb) + *stopped,reason="exited-signalled",signal-name="SIGINT", + signal-meaning="Interrupt" + +The `-exec-abort' Command +------------------------- + +Synopsis +........ + + -exec-abort + + Kill the inferior running program. + +GDB Command +........... + +The corresponding GDB command is `kill'. + +Example +....... + +N.A. + +The `-exec-arguments' Command +----------------------------- + +Synopsis +........ + + -exec-arguments ARGS + + Set the inferior program arguments, to be used in the next +`-exec-run'. + +GDB Command +........... + +The corresponding GDB command is `set args'. + +Example +....... + +Don't have one around. + +The `-exec-continue' Command +---------------------------- + +Synopsis +........ + + -exec-continue + + Asynchronous command. Resumes the execution of the inferior program +until a breakpoint is encountered, or until the inferior exits. + +GDB Command +........... + +The corresponding GDB corresponding is `continue'. + +Example +....... + + -exec-continue + ^running + (gdb) + @Hello world + *stopped,reason="breakpoint-hit",bkptno="2",frame={func="foo",args=[], + file="hello.c",line="13"} + (gdb) + +The `-exec-finish' Command +-------------------------- + +Synopsis +........ + + -exec-finish + + Asynchronous command. Resumes the execution of the inferior program +until the current function is exited. Displays the results returned by +the function. + +GDB Command +........... + +The corresponding GDB command is `finish'. + +Example +....... + +Function returning `void'. + + -exec-finish + ^running + (gdb) + @hello from foo + *stopped,reason="function-finished",frame={func="main",args=[], + file="hello.c",line="7"} + (gdb) + + Function returning other than `void'. The name of the internal GDB +variable storing the result is printed, together with the value itself. + + -exec-finish + ^running + (gdb) + *stopped,reason="function-finished",frame={addr="0x000107b0",func="foo", + args=[{name="a",value="1"],{name="b",value="9"}}, + file="recursive2.c",line="14"}, + gdb-result-var="$1",return-value="0" + (gdb) + +The `-exec-interrupt' Command +----------------------------- + +Synopsis +........ + + -exec-interrupt + + Asynchronous command. Interrupts the background execution of the +target. Note how the token associated with the stop message is the one +for the execution command that has been interrupted. The token for the +interrupt itself only appears in the `^done' output. If the user is +trying to interrupt a non-running program, an error message will be +printed. + +GDB Command +........... + +The corresponding GDB command is `interrupt'. + +Example +....... + + (gdb) + 111-exec-continue + 111^running + + (gdb) + 222-exec-interrupt + 222^done + (gdb) + 111*stopped,signal-name="SIGINT",signal-meaning="Interrupt", + frame={addr="0x00010140",func="foo",args=[],file="try.c",line="13"} + (gdb) + + (gdb) + -exec-interrupt + ^error,msg="mi_cmd_exec_interrupt: Inferior not executing." + (gdb) + +The `-exec-next' Command +------------------------ + +Synopsis +........ + + -exec-next + + Asynchronous command. Resumes execution of the inferior program, +stopping when the beginning of the next source line is reached. + +GDB Command +........... + +The corresponding GDB command is `next'. + +Example +....... + + -exec-next + ^running + (gdb) + *stopped,reason="end-stepping-range",line="8",file="hello.c" + (gdb) + +The `-exec-next-instruction' Command +------------------------------------ + +Synopsis +........ + + -exec-next-instruction + + Asynchronous command. Executes one machine instruction. If the +instruction is a function call continues until the function returns. If +the program stops at an instruction in the middle of a source line, the +address will be printed as well. + +GDB Command +........... + +The corresponding GDB command is `nexti'. + +Example +....... + + (gdb) + -exec-next-instruction + ^running + + (gdb) + *stopped,reason="end-stepping-range", + addr="0x000100d4",line="5",file="hello.c" + (gdb) + +The `-exec-return' Command +-------------------------- + +Synopsis +........ + + -exec-return + + Makes current function return immediately. Doesn't execute the +inferior. Displays the new current frame. + +GDB Command +........... + +The corresponding GDB command is `return'. + +Example +....... + + (gdb) + 200-break-insert callee4 + 200^done,bkpt={number="1",addr="0x00010734", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"} + (gdb) + 000-exec-run + 000^running + (gdb) + 000*stopped,reason="breakpoint-hit",bkptno="1", + frame={func="callee4",args=[], + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"} + (gdb) + 205-break-delete + 205^done + (gdb) + 111-exec-return + 111^done,frame={level="0",func="callee3", + args=[{name="strarg", + value="0x11940 \"A string argument.\""}], + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"} + (gdb) + +The `-exec-run' Command +----------------------- + +Synopsis +........ + + -exec-run + + Asynchronous command. Starts execution of the inferior from the +beginning. The inferior executes until either a breakpoint is +encountered or the program exits. + +GDB Command +........... + +The corresponding GDB command is `run'. + +Example +....... + + (gdb) + -break-insert main + ^done,bkpt={number="1",addr="0x0001072c",file="recursive2.c",line="4"} + (gdb) + -exec-run + ^running + (gdb) + *stopped,reason="breakpoint-hit",bkptno="1", + frame={func="main",args=[],file="recursive2.c",line="4"} + (gdb) + +The `-exec-show-arguments' Command +---------------------------------- + +Synopsis +........ + + -exec-show-arguments + + Print the arguments of the program. + +GDB Command +........... + +The corresponding GDB command is `show args'. + +Example +....... + +N.A. + +The `-exec-step' Command +------------------------ + +Synopsis +........ + + -exec-step + + Asynchronous command. Resumes execution of the inferior program, +stopping when the beginning of the next source line is reached, if the +next source line is not a function call. If it is, stop at the first +instruction of the called function. + +GDB Command +........... + +The corresponding GDB command is `step'. + +Example +....... + +Stepping into a function: + + -exec-step + ^running + (gdb) + *stopped,reason="end-stepping-range", + frame={func="foo",args=[{name="a",value="10"}, + {name="b",value="0"}],file="recursive2.c",line="11"} + (gdb) + + Regular stepping: + + -exec-step + ^running + (gdb) + *stopped,reason="end-stepping-range",line="14",file="recursive2.c" + (gdb) + +The `-exec-step-instruction' Command +------------------------------------ + +Synopsis +........ + + -exec-step-instruction + + Asynchronous command. Resumes the inferior which executes one +machine instruction. The output, once GDB has stopped, will vary +depending on whether we have stopped in the middle of a source line or +not. In the former case, the address at which the program stopped will +be printed as well. + +GDB Command +........... + +The corresponding GDB command is `stepi'. + +Example +....... + + (gdb) + -exec-step-instruction + ^running + + (gdb) + *stopped,reason="end-stepping-range", + frame={func="foo",args=[],file="try.c",line="10"} + (gdb) + -exec-step-instruction + ^running + + (gdb) + *stopped,reason="end-stepping-range", + frame={addr="0x000100f4",func="foo",args=[],file="try.c",line="10"} + (gdb) + +The `-exec-until' Command +------------------------- + +Synopsis +........ + + -exec-until [ LOCATION ] + + Asynchronous command. Executes the inferior until the LOCATION +specified in the argument is reached. If there is no argument, the +inferior executes until a source line greater than the current one is +reached. The reason for stopping in this case will be +`location-reached'. + +GDB Command +........... + +The corresponding GDB command is `until'. + +Example +....... + + (gdb) + -exec-until recursive2.c:6 + ^running + (gdb) + x = 55 + *stopped,reason="location-reached",frame={func="main",args=[], + file="recursive2.c",line="6"} + (gdb) + +The `-file-exec-and-symbols' Command +------------------------------------ + +Synopsis +........ + + -file-exec-and-symbols FILE + + Specify the executable file to be debugged. This file is the one +from which the symbol table is also read. If no file is specified, the +command clears the executable and symbol information. If breakpoints +are set when using this command with no arguments, GDB will produce +error messages. Otherwise, no output is produced, except a completion +notification. + +GDB Command +........... + +The corresponding GDB command is `file'. + +Example +....... + + (gdb) + -file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx + ^done + (gdb) + +The `-file-exec-file' Command +----------------------------- + +Synopsis +........ + + -file-exec-file FILE + + Specify the executable file to be debugged. Unlike +`-file-exec-and-symbols', the symbol table is _not_ read from this +file. If used without argument, GDB clears the information about the +executable file. No output is produced, except a completion +notification. + +GDB Command +........... + +The corresponding GDB command is `exec-file'. + +Example +....... + + (gdb) + -file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx + ^done + (gdb) + +The `-file-list-exec-sections' Command +-------------------------------------- + +Synopsis +........ + + -file-list-exec-sections + + List the sections of the current executable file. + +GDB Command +........... + +The GDB command `info file' shows, among the rest, the same information +as this command. `gdbtk' has a corresponding command `gdb_load_info'. + +Example +....... + +N.A. + +The `-file-list-exec-source-file' Command +----------------------------------------- + +Synopsis +........ + + -file-list-exec-source-file + + List the line number, the current source file, and the absolute path +to the current source file for the current executable. + +GDB Command +........... + +There's no GDB command which directly corresponds to this one. + +Example +....... + + (gdb) + 123-file-list-exec-source-file + 123^done,line="1",file="foo.c",fullname="/home/bar/foo.c" + (gdb) + +The `-file-list-exec-source-files' Command +------------------------------------------ + +Synopsis +........ + + -file-list-exec-source-files + + List the source files for the current executable. + +GDB Command +........... + +There's no GDB command which directly corresponds to this one. `gdbtk' +has an analogous command `gdb_listfiles'. + +Example +....... + +N.A. + +The `-file-list-shared-libraries' Command +----------------------------------------- + +Synopsis +........ + + -file-list-shared-libraries + + List the shared libraries in the program. + +GDB Command +........... + +The corresponding GDB command is `info shared'. + +Example +....... + +N.A. + +The `-file-list-symbol-files' Command +------------------------------------- + +Synopsis +........ + + -file-list-symbol-files + + List symbol files. + +GDB Command +........... + +The corresponding GDB command is `info file' (part of it). + +Example +....... + +N.A. + +The `-file-symbol-file' Command +------------------------------- + +Synopsis +........ + + -file-symbol-file FILE + + Read symbol table info from the specified FILE argument. When used +without arguments, clears GDB's symbol table info. No output is +produced, except for a completion notification. + +GDB Command +........... + +The corresponding GDB command is `symbol-file'. + +Example +....... + + (gdb) + -file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx + ^done + (gdb) + + +File: gdb.info, Node: GDB/MI Miscellaneous Commands, Next: GDB/MI Stack Manipulation, Prev: GDB/MI Program Control, Up: GDB/MI + +Miscellaneous GDB commands in GDB/MI +==================================== + +The `-gdb-exit' Command +----------------------- + +Synopsis +........ + + -gdb-exit + + Exit GDB immediately. + +GDB Command +........... + +Approximately corresponds to `quit'. + +Example +....... + + (gdb) + -gdb-exit + +The `-gdb-set' Command +---------------------- + +Synopsis +........ + + -gdb-set + + Set an internal GDB variable. + +GDB Command +........... + +The corresponding GDB command is `set'. + +Example +....... + + (gdb) + -gdb-set $foo=3 + ^done + (gdb) + +The `-gdb-show' Command +----------------------- + +Synopsis +........ + + -gdb-show + + Show the current value of a GDB variable. + +GDB command +........... + +The corresponding GDB command is `show'. + +Example +....... + + (gdb) + -gdb-show annotate + ^done,value="0" + (gdb) + +The `-gdb-version' Command +-------------------------- + +Synopsis +........ + + -gdb-version + + Show version information for GDB. Used mostly in testing. + +GDB Command +........... + +There's no equivalent GDB command. GDB by default shows this +information when you start an interactive session. + +Example +....... + + (gdb) + -gdb-version + ~GNU gdb 5.2.1 + ~Copyright 2000 Free Software Foundation, Inc. + ~GDB is free software, covered by the GNU General Public License, and + ~you are welcome to change it and/or distribute copies of it under + ~ certain conditions. + ~Type "show copying" to see the conditions. + ~There is absolutely no warranty for GDB. Type "show warranty" for + ~ details. + ~This GDB was configured as + "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi". + ^done + (gdb) + +The `-interpreter-exec' Command +------------------------------- + +Synopsis +-------- + + -interpreter-exec INTERPRETER COMMAND + + Execute the specified COMMAND in the given INTERPRETER. + +GDB Command +----------- + +The corresponding GDB command is `interpreter-exec'. + +Example +------- + + (gdb) + -interpreter-exec console "break main" + &"During symbol reading, couldn't parse type; debugger out of date?.\n" + &"During symbol reading, bad structure-type format.\n" + ~"Breakpoint 1 at 0x8074fc6: file ../../src/gdb/main.c, line 743.\n" + ^done + (gdb) + + +File: gdb.info, Node: GDB/MI Stack Manipulation, Next: GDB/MI Symbol Query, Prev: GDB/MI Miscellaneous Commands, Up: GDB/MI + +GDB/MI Stack Manipulation Commands +================================== + +The `-stack-info-frame' Command +------------------------------- + +Synopsis +........ + + -stack-info-frame + + Get info on the current frame. + +GDB Command +........... + +The corresponding GDB command is `info frame' or `frame' (without +arguments). + +Example +....... + +N.A. + +The `-stack-info-depth' Command +------------------------------- + +Synopsis +........ + + -stack-info-depth [ MAX-DEPTH ] + + Return the depth of the stack. If the integer argument MAX-DEPTH is +specified, do not count beyond MAX-DEPTH frames. + +GDB Command +........... + +There's no equivalent GDB command. + +Example +....... + +For a stack with frame levels 0 through 11: + + (gdb) + -stack-info-depth + ^done,depth="12" + (gdb) + -stack-info-depth 4 + ^done,depth="4" + (gdb) + -stack-info-depth 12 + ^done,depth="12" + (gdb) + -stack-info-depth 11 + ^done,depth="11" + (gdb) + -stack-info-depth 13 + ^done,depth="12" + (gdb) + +The `-stack-list-arguments' Command +----------------------------------- + +Synopsis +........ + + -stack-list-arguments SHOW-VALUES + [ LOW-FRAME HIGH-FRAME ] + + Display a list of the arguments for the frames between LOW-FRAME and +HIGH-FRAME (inclusive). If LOW-FRAME and HIGH-FRAME are not provided, +list the arguments for the whole call stack. + + The SHOW-VALUES argument must have a value of 0 or 1. A value of 0 +means that only the names of the arguments are listed, a value of 1 +means that both names and values of the arguments are printed. + +GDB Command +........... + +GDB does not have an equivalent command. `gdbtk' has a `gdb_get_args' +command which partially overlaps with the functionality of +`-stack-list-arguments'. + +Example +....... + + (gdb) + -stack-list-frames + ^done, + stack=[ + frame={level="0",addr="0x00010734",func="callee4", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"}, + frame={level="1",addr="0x0001076c",func="callee3", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"}, + frame={level="2",addr="0x0001078c",func="callee2", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"}, + frame={level="3",addr="0x000107b4",func="callee1", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"}, + frame={level="4",addr="0x000107e0",func="main", + file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"}] + (gdb) + -stack-list-arguments 0 + ^done, + stack-args=[ + frame={level="0",args=[]}, + frame={level="1",args=[name="strarg"]}, + frame={level="2",args=[name="intarg",name="strarg"]}, + frame={level="3",args=[name="intarg",name="strarg",name="fltarg"]}, + frame={level="4",args=[]}] + (gdb) + -stack-list-arguments 1 + ^done, + stack-args=[ + frame={level="0",args=[]}, + frame={level="1", + args=[{name="strarg",value="0x11940 \"A string argument.\""}]}, + frame={level="2",args=[ + {name="intarg",value="2"}, + {name="strarg",value="0x11940 \"A string argument.\""}]}, + {frame={level="3",args=[ + {name="intarg",value="2"}, + {name="strarg",value="0x11940 \"A string argument.\""}, + {name="fltarg",value="3.5"}]}, + frame={level="4",args=[]}] + (gdb) + -stack-list-arguments 0 2 2 + ^done,stack-args=[frame={level="2",args=[name="intarg",name="strarg"]}] + (gdb) + -stack-list-arguments 1 2 2 + ^done,stack-args=[frame={level="2", + args=[{name="intarg",value="2"}, + {name="strarg",value="0x11940 \"A string argument.\""}]}] + (gdb) + +The `-stack-list-frames' Command +-------------------------------- + +Synopsis +........ + + -stack-list-frames [ LOW-FRAME HIGH-FRAME ] + + List the frames currently on the stack. For each frame it displays +the following info: + +`LEVEL' + The frame number, 0 being the topmost frame, i.e. the innermost + function. + +`ADDR' + The `$pc' value for that frame. + +`FUNC' + Function name. + +`FILE' + File name of the source file where the function lives. + +`LINE' + Line number corresponding to the `$pc'. + + If invoked without arguments, this command prints a backtrace for the +whole stack. If given two integer arguments, it shows the frames whose +levels are between the two arguments (inclusive). If the two arguments +are equal, it shows the single frame at the corresponding level. + +GDB Command +........... + +The corresponding GDB commands are `backtrace' and `where'. + +Example +....... + +Full stack backtrace: + + (gdb) + -stack-list-frames + ^done,stack= + [frame={level="0",addr="0x0001076c",func="foo", + file="recursive2.c",line="11"}, + frame={level="1",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="2",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="3",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="4",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="5",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="6",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="7",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="8",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="9",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="10",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="11",addr="0x00010738",func="main", + file="recursive2.c",line="4"}] + (gdb) + + Show frames between LOW_FRAME and HIGH_FRAME: + + (gdb) + -stack-list-frames 3 5 + ^done,stack= + [frame={level="3",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="4",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}, + frame={level="5",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}] + (gdb) + + Show a single frame: + + (gdb) + -stack-list-frames 3 3 + ^done,stack= + [frame={level="3",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"}] + (gdb) + +The `-stack-list-locals' Command +-------------------------------- + +Synopsis +........ + + -stack-list-locals PRINT-VALUES + + Display the local variable names for the current frame. With an +argument of 0 or `--no-values', prints only the names of the variables. +With argument of 1 or `--all-values', prints also their values. With +argument of 2 or `--simple-values', prints the name, type and value for +simple data types and the name and type for arrays, structures and +unions. In this last case, the idea is that the user can see the value +of simple data types immediately and he can create variable objects for +other data types if he wishes to explore their values in more detail. + +GDB Command +........... + +`info locals' in GDB, `gdb_get_locals' in `gdbtk'. + +Example +....... + + (gdb) + -stack-list-locals 0 + ^done,locals=[name="A",name="B",name="C"] + (gdb) + -stack-list-locals --all-values + ^done,locals=[{name="A",value="1"},{name="B",value="2"}, + {name="C",value="{1, 2, 3}"}] + -stack-list-locals --simple-values + ^done,locals=[{name="A",type="int",value="1"}, + {name="B",type="int",value="2"},{name="C",type="int [3]"}] + (gdb) + +The `-stack-select-frame' Command +--------------------------------- + +Synopsis +........ + + -stack-select-frame FRAMENUM + + Change the current frame. Select a different frame FRAMENUM on the +stack. + +GDB Command +........... + +The corresponding GDB commands are `frame', `up', `down', +`select-frame', `up-silent', and `down-silent'. + +Example +....... + + (gdb) + -stack-select-frame 2 + ^done + (gdb) + + +File: gdb.info, Node: GDB/MI Symbol Query, Next: GDB/MI Target Manipulation, Prev: GDB/MI Stack Manipulation, Up: GDB/MI + +GDB/MI Symbol Query Commands +============================ + +The `-symbol-info-address' Command +---------------------------------- + +Synopsis +........ + + -symbol-info-address SYMBOL + + Describe where SYMBOL is stored. + +GDB Command +........... + +The corresponding GDB command is `info address'. + +Example +....... + +N.A. + +The `-symbol-info-file' Command +------------------------------- + +Synopsis +........ + + -symbol-info-file + + Show the file for the symbol. + +GDB Command +........... + +There's no equivalent GDB command. `gdbtk' has `gdb_find_file'. + +Example +....... + +N.A. + +The `-symbol-info-function' Command +----------------------------------- + +Synopsis +........ + + -symbol-info-function + + Show which function the symbol lives in. + +GDB Command +........... + +`gdb_get_function' in `gdbtk'. + +Example +....... + +N.A. + +The `-symbol-info-line' Command +------------------------------- + +Synopsis +........ + + -symbol-info-line + + Show the core addresses of the code for a source line. + +GDB Command +........... + +The corresponding GDB command is `info line'. `gdbtk' has the +`gdb_get_line' and `gdb_get_file' commands. + +Example +....... + +N.A. + +The `-symbol-info-symbol' Command +--------------------------------- + +Synopsis +........ + + -symbol-info-symbol ADDR + + Describe what symbol is at location ADDR. + +GDB Command +........... + +The corresponding GDB command is `info symbol'. + +Example +....... + +N.A. + +The `-symbol-list-functions' Command +------------------------------------ + +Synopsis +........ + + -symbol-list-functions + + List the functions in the executable. + +GDB Command +........... + +`info functions' in GDB, `gdb_listfunc' and `gdb_search' in `gdbtk'. + +Example +....... + +N.A. + +The `-symbol-list-lines' Command +-------------------------------- + +Synopsis +........ + + -symbol-list-lines FILENAME + + Print the list of lines that contain code and their associated +program addresses for the given source filename. The entries are +sorted in ascending PC order. + +GDB Command +........... + +There is no corresponding GDB command. + +Example +....... + + (gdb) + -symbol-list-lines basics.c + ^done,lines=[{pc="0x08048554",line="7"},{pc="0x0804855a",line="8"}] + (gdb) + +The `-symbol-list-types' Command +-------------------------------- + +Synopsis +........ + + -symbol-list-types + + List all the type names. + +GDB Command +........... + +The corresponding commands are `info types' in GDB, `gdb_search' in +`gdbtk'. + +Example +....... + +N.A. + +The `-symbol-list-variables' Command +------------------------------------ + +Synopsis +........ + + -symbol-list-variables + + List all the global and static variable names. + +GDB Command +........... + +`info variables' in GDB, `gdb_search' in `gdbtk'. + +Example +....... + +N.A. + +The `-symbol-locate' Command +---------------------------- + +Synopsis +........ + + -symbol-locate + +GDB Command +........... + +`gdb_loc' in `gdbtk'. + +Example +....... + +N.A. + +The `-symbol-type' Command +-------------------------- + +Synopsis +........ + + -symbol-type VARIABLE + + Show type of VARIABLE. + +GDB Command +........... + +The corresponding GDB command is `ptype', `gdbtk' has +`gdb_obj_variable'. + +Example +....... + +N.A. + + +File: gdb.info, Node: GDB/MI Target Manipulation, Next: GDB/MI Thread Commands, Prev: GDB/MI Symbol Query, Up: GDB/MI + +GDB/MI Target Manipulation Commands +=================================== + +The `-target-attach' Command +---------------------------- + +Synopsis +........ + + -target-attach PID | FILE + + Attach to a process PID or a file FILE outside of GDB. + +GDB command +........... + +The corresponding GDB command is `attach'. + +Example +....... + +N.A. + +The `-target-compare-sections' Command +-------------------------------------- + +Synopsis +........ + + -target-compare-sections [ SECTION ] + + Compare data of section SECTION on target to the exec file. Without +the argument, all sections are compared. + +GDB Command +........... + +The GDB equivalent is `compare-sections'. + +Example +....... + +N.A. + +The `-target-detach' Command +---------------------------- + +Synopsis +........ + + -target-detach + + Disconnect from the remote target. There's no output. + +GDB command +........... + +The corresponding GDB command is `detach'. + +Example +....... + + (gdb) + -target-detach + ^done + (gdb) + +The `-target-disconnect' Command +-------------------------------- + +Synopsis +........ + + -target-disconnect + + Disconnect from the remote target. There's no output. + +GDB command +........... + +The corresponding GDB command is `disconnect'. + +Example +....... + + (gdb) + -target-disconnect + ^done + (gdb) + +The `-target-download' Command +------------------------------ + +Synopsis +........ + + -target-download + + Loads the executable onto the remote target. It prints out an +update message every half second, which includes the fields: + +`section' + The name of the section. + +`section-sent' + The size of what has been sent so far for that section. + +`section-size' + The size of the section. + +`total-sent' + The total size of what was sent so far (the current and the + previous sections). + +`total-size' + The size of the overall executable to download. + +Each message is sent as status record (*note GDB/MI Output Syntax: +GDB/MI Output Syntax.). + + In addition, it prints the name and size of the sections, as they are +downloaded. These messages include the following fields: + +`section' + The name of the section. + +`section-size' + The size of the section. + +`total-size' + The size of the overall executable to download. + +At the end, a summary is printed. + +GDB Command +........... + +The corresponding GDB command is `load'. + +Example +....... + +Note: each status message appears on a single line. Here the messages +have been broken down so that they can fit onto a page. + + (gdb) + -target-download + +download,{section=".text",section-size="6668",total-size="9880"} + +download,{section=".text",section-sent="512",section-size="6668", + total-sent="512",total-size="9880"} + +download,{section=".text",section-sent="1024",section-size="6668", + total-sent="1024",total-size="9880"} + +download,{section=".text",section-sent="1536",section-size="6668", + total-sent="1536",total-size="9880"} + +download,{section=".text",section-sent="2048",section-size="6668", + total-sent="2048",total-size="9880"} + +download,{section=".text",section-sent="2560",section-size="6668", + total-sent="2560",total-size="9880"} + +download,{section=".text",section-sent="3072",section-size="6668", + total-sent="3072",total-size="9880"} + +download,{section=".text",section-sent="3584",section-size="6668", + total-sent="3584",total-size="9880"} + +download,{section=".text",section-sent="4096",section-size="6668", + total-sent="4096",total-size="9880"} + +download,{section=".text",section-sent="4608",section-size="6668", + total-sent="4608",total-size="9880"} + +download,{section=".text",section-sent="5120",section-size="6668", + total-sent="5120",total-size="9880"} + +download,{section=".text",section-sent="5632",section-size="6668", + total-sent="5632",total-size="9880"} + +download,{section=".text",section-sent="6144",section-size="6668", + total-sent="6144",total-size="9880"} + +download,{section=".text",section-sent="6656",section-size="6668", + total-sent="6656",total-size="9880"} + +download,{section=".init",section-size="28",total-size="9880"} + +download,{section=".fini",section-size="28",total-size="9880"} + +download,{section=".data",section-size="3156",total-size="9880"} + +download,{section=".data",section-sent="512",section-size="3156", + total-sent="7236",total-size="9880"} + +download,{section=".data",section-sent="1024",section-size="3156", + total-sent="7748",total-size="9880"} + +download,{section=".data",section-sent="1536",section-size="3156", + total-sent="8260",total-size="9880"} + +download,{section=".data",section-sent="2048",section-size="3156", + total-sent="8772",total-size="9880"} + +download,{section=".data",section-sent="2560",section-size="3156", + total-sent="9284",total-size="9880"} + +download,{section=".data",section-sent="3072",section-size="3156", + total-sent="9796",total-size="9880"} + ^done,address="0x10004",load-size="9880",transfer-rate="6586", + write-rate="429" + (gdb) + +The `-target-exec-status' Command +--------------------------------- + +Synopsis +........ + + -target-exec-status + + Provide information on the state of the target (whether it is +running or not, for instance). + +GDB Command +........... + +There's no equivalent GDB command. + +Example +....... + +N.A. + +The `-target-list-available-targets' Command +-------------------------------------------- + +Synopsis +........ + + -target-list-available-targets + + List the possible targets to connect to. + +GDB Command +........... + +The corresponding GDB command is `help target'. + +Example +....... + +N.A. + +The `-target-list-current-targets' Command +------------------------------------------ + +Synopsis +........ + + -target-list-current-targets + + Describe the current target. + +GDB Command +........... + +The corresponding information is printed by `info file' (among other +things). + +Example +....... + +N.A. + +The `-target-list-parameters' Command +------------------------------------- + +Synopsis +........ + + -target-list-parameters + +GDB Command +........... + +No equivalent. + +Example +....... + +N.A. + +The `-target-select' Command +---------------------------- + +Synopsis +........ + + -target-select TYPE PARAMETERS ... + + Connect GDB to the remote target. This command takes two args: + +`TYPE' + The type of target, for instance `async', `remote', etc. + +`PARAMETERS' + Device names, host names and the like. *Note Commands for + managing targets: Target Commands, for more details. + + The output is a connection notification, followed by the address at +which the target program is, in the following form: + + ^connected,addr="ADDRESS",func="FUNCTION NAME", + args=[ARG LIST] + +GDB Command +........... + +The corresponding GDB command is `target'. + +Example +....... + + (gdb) + -target-select async /dev/ttya + ^connected,addr="0xfe00a300",func="??",args=[] + (gdb) + + +File: gdb.info, Node: GDB/MI Thread Commands, Next: GDB/MI Tracepoint Commands, Prev: GDB/MI Target Manipulation, Up: GDB/MI + +GDB/MI Thread Commands +====================== + +The `-thread-info' Command +-------------------------- + +Synopsis +........ + + -thread-info + +GDB command +........... + +No equivalent. + +Example +....... + +N.A. + +The `-thread-list-all-threads' Command +-------------------------------------- + +Synopsis +........ + + -thread-list-all-threads + +GDB Command +........... + +The equivalent GDB command is `info threads'. + +Example +....... + +N.A. + +The `-thread-list-ids' Command +------------------------------ + +Synopsis +........ + + -thread-list-ids + + Produces a list of the currently known GDB thread ids. At the end +of the list it also prints the total number of such threads. + +GDB Command +........... + +Part of `info threads' supplies the same information. + +Example +....... + +No threads present, besides the main process: + + (gdb) + -thread-list-ids + ^done,thread-ids={},number-of-threads="0" + (gdb) + + Several threads: + + (gdb) + -thread-list-ids + ^done,thread-ids={thread-id="3",thread-id="2",thread-id="1"}, + number-of-threads="3" + (gdb) + +The `-thread-select' Command +---------------------------- + +Synopsis +........ + + -thread-select THREADNUM + + Make THREADNUM the current thread. It prints the number of the new +current thread, and the topmost frame for that thread. + +GDB Command +........... + +The corresponding GDB command is `thread'. + +Example +....... + + (gdb) + -exec-next + ^running + (gdb) + *stopped,reason="end-stepping-range",thread-id="2",line="187", + file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c" + (gdb) + -thread-list-ids + ^done, + thread-ids={thread-id="3",thread-id="2",thread-id="1"}, + number-of-threads="3" + (gdb) + -thread-select 3 + ^done,new-thread-id="3", + frame={level="0",func="vprintf", + args=[{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""}, + {name="arg",value="0x2"}],file="vprintf.c",line="31"} + (gdb) + + +File: gdb.info, Node: GDB/MI Tracepoint Commands, Next: GDB/MI Variable Objects, Prev: GDB/MI Thread Commands, Up: GDB/MI + +GDB/MI Tracepoint Commands +========================== + +The tracepoint commands are not yet implemented. + + +File: gdb.info, Node: GDB/MI Variable Objects, Prev: GDB/MI Tracepoint Commands, Up: GDB/MI + +GDB/MI Variable Objects +======================= + +Motivation for Variable Objects in GDB/MI +----------------------------------------- + +For the implementation of a variable debugger window (locals, watched +expressions, etc.), we are proposing the adaptation of the existing code +used by `Insight'. + + The two main reasons for that are: + + 1. It has been proven in practice (it is already on its second + generation). + + 2. It will shorten development time (needless to say how important it + is now). + + The original interface was designed to be used by Tcl code, so it was +slightly changed so it could be used through GDB/MI. This section +describes the GDB/MI operations that will be available and gives some +hints about their use. + + _Note_: In addition to the set of operations described here, we +expect the GUI implementation of a variable window to require, at +least, the following operations: + + * `-gdb-show' `output-radix' + + * `-stack-list-arguments' + + * `-stack-list-locals' + + * `-stack-select-frame' + +Introduction to Variable Objects in GDB/MI +------------------------------------------ + +The basic idea behind variable objects is the creation of a named object +to represent a variable, an expression, a memory location or even a CPU +register. For each object created, a set of operations is available for +examining or changing its properties. + + Furthermore, complex data types, such as C structures, are +represented in a tree format. For instance, the `struct' type variable +is the root and the children will represent the struct members. If a +child is itself of a complex type, it will also have children of its +own. Appropriate language differences are handled for C, C++ and Java. + + When returning the actual values of the objects, this facility allows +for the individual selection of the display format used in the result +creation. It can be chosen among: binary, decimal, hexadecimal, octal +and natural. Natural refers to a default format automatically chosen +based on the variable type (like decimal for an `int', hex for +pointers, etc.). + + The following is the complete set of GDB/MI operations defined to +access this functionality: + +*Operation* *Description* +`-var-create' create a variable object +`-var-delete' delete the variable object and its children +`-var-set-format' set the display format of this variable +`-var-show-format' show the display format of this variable +`-var-info-num-children' tells how many children this object has +`-var-list-children' return a list of the object's children +`-var-info-type' show the type of this variable object +`-var-info-expression' print what this variable object represents +`-var-show-attributes' is this variable editable? does it exist + here? +`-var-evaluate-expression' get the value of this variable +`-var-assign' set the value of this variable +`-var-update' update the variable and its children + + In the next subsection we describe each operation in detail and +suggest how it can be used. + +Description And Use of Operations on Variable Objects +----------------------------------------------------- + +The `-var-create' Command +------------------------- + +Synopsis +........ + + -var-create {NAME | "-"} + {FRAME-ADDR | "*"} EXPRESSION + + This operation creates a variable object, which allows the +monitoring of a variable, the result of an expression, a memory cell or +a CPU register. + + The NAME parameter is the string by which the object can be +referenced. It must be unique. If `-' is specified, the varobj system +will generate a string "varNNNNNN" automatically. It will be unique +provided that one does not specify NAME on that format. The command +fails if a duplicate name is found. + + The frame under which the expression should be evaluated can be +specified by FRAME-ADDR. A `*' indicates that the current frame should +be used. + + EXPRESSION is any expression valid on the current language set (must +not begin with a `*'), or one of the following: + + * `*ADDR', where ADDR is the address of a memory cell + + * `*ADDR-ADDR' -- a memory address range (TBD) + + * `$REGNAME' -- a CPU register name + +Result +...... + +This operation returns the name, number of children and the type of the +object created. Type is returned as a string as the ones generated by +the GDB CLI: + + name="NAME",numchild="N",type="TYPE" + +The `-var-delete' Command +------------------------- + +Synopsis +........ + + -var-delete NAME + + Deletes a previously created variable object and all of its children. + + Returns an error if the object NAME is not found. + +The `-var-set-format' Command +----------------------------- + +Synopsis +........ + + -var-set-format NAME FORMAT-SPEC + + Sets the output format for the value of the object NAME to be +FORMAT-SPEC. + + The syntax for the FORMAT-SPEC is as follows: + + FORMAT-SPEC ==> + {binary | decimal | hexadecimal | octal | natural} + +The `-var-show-format' Command +------------------------------ + +Synopsis +........ + + -var-show-format NAME + + Returns the format used to display the value of the object NAME. + + FORMAT ==> + FORMAT-SPEC + +The `-var-info-num-children' Command +------------------------------------ + +Synopsis +........ + + -var-info-num-children NAME + + Returns the number of children of a variable object NAME: + + numchild=N + +The `-var-list-children' Command +-------------------------------- + +Synopsis +........ + + -var-list-children [PRINT-VALUES] NAME + + Returns a list of the children of the specified variable object. +With just the variable object name as an argument or with an optional +preceding argument of 0 or `--no-values', prints only the names of the +variables. With an optional preceding argument of 1 or `--all-values', +also prints their values. + +Example +....... + + (gdb) + -var-list-children n + numchild=N,children=[{name=NAME, + numchild=N,type=TYPE},(repeats N times)] + (gdb) + -var-list-children --all-values n + numchild=N,children=[{name=NAME, + numchild=N,value=VALUE,type=TYPE},(repeats N times)] + +The `-var-info-type' Command +---------------------------- + +Synopsis +........ + + -var-info-type NAME + + Returns the type of the specified variable NAME. The type is +returned as a string in the same format as it is output by the GDB CLI: + + type=TYPENAME + +The `-var-info-expression' Command +---------------------------------- + +Synopsis +........ + + -var-info-expression NAME + + Returns what is represented by the variable object NAME: + + lang=LANG-SPEC,exp=EXPRESSION + +where LANG-SPEC is `{"C" | "C++" | "Java"}'. + +The `-var-show-attributes' Command +---------------------------------- + +Synopsis +........ + + -var-show-attributes NAME + + List attributes of the specified variable object NAME: + + status=ATTR [ ( ,ATTR )* ] + +where ATTR is `{ { editable | noneditable } | TBD }'. + +The `-var-evaluate-expression' Command +-------------------------------------- + +Synopsis +........ + + -var-evaluate-expression NAME + + Evaluates the expression that is represented by the specified +variable object and returns its value as a string in the current format +specified for the object: + + value=VALUE + + Note that one must invoke `-var-list-children' for a variable before +the value of a child variable can be evaluated. + +The `-var-assign' Command +------------------------- + +Synopsis +........ + + -var-assign NAME EXPRESSION + + Assigns the value of EXPRESSION to the variable object specified by +NAME. The object must be `editable'. If the variable's value is +altered by the assign, the variable will show up in any subsequent +`-var-update' list. + +Example +....... + + (gdb) + -var-assign var1 3 + ^done,value="3" + (gdb) + -var-update * + ^done,changelist=[{name="var1",in_scope="true",type_changed="false"}] + (gdb) + +The `-var-update' Command +------------------------- + +Synopsis +........ + + -var-update {NAME | "*"} + + Update the value of the variable object NAME by evaluating its +expression after fetching all the new values from memory or registers. +A `*' causes all existing variable objects to be updated. + + +File: gdb.info, Node: Annotations, Next: GDB/MI, Prev: Emacs, Up: Top + +GDB Annotations +*************** + +This chapter describes annotations in GDB. Annotations were designed +to interface GDB to graphical user interfaces or other similar programs +which want to interact with GDB at a relatively high level. + + The annotation mechanism has largely been superseeded by GDB/MI +(*note GDB/MI::). + +* Menu: + +* Annotations Overview:: What annotations are; the general syntax. +* Server Prefix:: Issuing a command without affecting user state. +* Prompting:: Annotations marking GDB's need for input. +* Errors:: Annotations for error messages. +* Invalidation:: Some annotations describe things now invalid. +* Annotations for Running:: + Whether the program is running, how it stopped, etc. +* Source Annotations:: Annotations describing source code. + + +File: gdb.info, Node: Annotations Overview, Next: Server Prefix, Up: Annotations + +What is an Annotation? +====================== + +Annotations start with a newline character, two `control-z' characters, +and the name of the annotation. If there is no additional information +associated with this annotation, the name of the annotation is followed +immediately by a newline. If there is additional information, the name +of the annotation is followed by a space, the additional information, +and a newline. The additional information cannot contain newline +characters. + + Any output not beginning with a newline and two `control-z' +characters denotes literal output from GDB. Currently there is no need +for GDB to output a newline followed by two `control-z' characters, but +if there was such a need, the annotations could be extended with an +`escape' annotation which means those three characters as output. + + The annotation LEVEL, which is specified using the `--annotate' +command line option (*note Mode Options::), controls how much +information GDB prints together with its prompt, values of expressions, +source lines, and other types of output. Level 0 is for no anntations, +level 1 is for use when GDB is run as a subprocess of GNU Emacs, level +3 is the maximum annotation suitable for programs that control GDB, and +level 2 annotations have been made obsolete (*note Limitations of the +Annotation Interface: (annotate)Limitations.). This chapter describes +level 3 annotations. + + A simple example of starting up GDB with annotations is: + + $ gdb --annotate=3 + GNU gdb 6.0 + Copyright 2003 Free Software Foundation, Inc. + GDB is free software, covered by the GNU General Public License, + and you are welcome to change it and/or distribute copies of it + under certain conditions. + Type "show copying" to see the conditions. + There is absolutely no warranty for GDB. Type "show warranty" + for details. + This GDB was configured as "i386-pc-linux-gnu" + + ^Z^Zpre-prompt + (gdb) + ^Z^Zprompt + quit + + ^Z^Zpost-prompt + $ + + Here `quit' is input to GDB; the rest is output from GDB. The three +lines beginning `^Z^Z' (where `^Z' denotes a `control-z' character) are +annotations; the rest is output from GDB. + + +File: gdb.info, Node: Server Prefix, Next: Prompting, Prev: Annotations Overview, Up: Annotations + +The Server Prefix +================= + +To issue a command to GDB without affecting certain aspects of the +state which is seen by users, prefix it with `server '. This means +that this command will not affect the command history, nor will it +affect GDB's notion of which command to repeat if is pressed on a +line by itself. + + The server prefix does not affect the recording of values into the +value history; to print a value without recording it into the value +history, use the `output' command instead of the `print' command. + + +File: gdb.info, Node: Prompting, Next: Errors, Prev: Server Prefix, Up: Annotations + +Annotation for GDB Input +======================== + +When GDB prompts for input, it annotates this fact so it is possible to +know when to send output, when the output from a given command is over, +etc. + + Different kinds of input each have a different "input type". Each +input type has three annotations: a `pre-' annotation, which denotes +the beginning of any prompt which is being output, a plain annotation, +which denotes the end of the prompt, and then a `post-' annotation +which denotes the end of any echo which may (or may not) be associated +with the input. For example, the `prompt' input type features the +following annotations: + + ^Z^Zpre-prompt + ^Z^Zprompt + ^Z^Zpost-prompt + + The input types are + +`prompt' + When GDB is prompting for a command (the main GDB prompt). + +`commands' + When GDB prompts for a set of commands, like in the `commands' + command. The annotations are repeated for each command which is + input. + +`overload-choice' + When GDB wants the user to select between various overloaded + functions. + +`query' + When GDB wants the user to confirm a potentially dangerous + operation. + +`prompt-for-continue' + When GDB is asking the user to press return to continue. Note: + Don't expect this to work well; instead use `set height 0' to + disable prompting. This is because the counting of lines is buggy + in the presence of annotations. + + +File: gdb.info, Node: Errors, Next: Invalidation, Prev: Prompting, Up: Annotations + +Errors +====== + + ^Z^Zquit + + This annotation occurs right before GDB responds to an interrupt. + + ^Z^Zerror + + This annotation occurs right before GDB responds to an error. + + Quit and error annotations indicate that any annotations which GDB +was in the middle of may end abruptly. For example, if a +`value-history-begin' annotation is followed by a `error', one cannot +expect to receive the matching `value-history-end'. One cannot expect +not to receive it either, however; an error annotation does not +necessarily mean that GDB is immediately returning all the way to the +top level. + + A quit or error annotation may be preceded by + + ^Z^Zerror-begin + + Any output between that and the quit or error annotation is the error +message. + + Warning messages are not yet annotated. + + +File: gdb.info, Node: Invalidation, Next: Annotations for Running, Prev: Errors, Up: Annotations + +Invalidation Notices +==================== + +The following annotations say that certain pieces of state may have +changed. + +`^Z^Zframes-invalid' + The frames (for example, output from the `backtrace' command) may + have changed. + +`^Z^Zbreakpoints-invalid' + The breakpoints may have changed. For example, the user just + added or deleted a breakpoint. + + +File: gdb.info, Node: Annotations for Running, Next: Source Annotations, Prev: Invalidation, Up: Annotations + +Running the Program +=================== + +When the program starts executing due to a GDB command such as `step' +or `continue', + + ^Z^Zstarting + + is output. When the program stops, + + ^Z^Zstopped + + is output. Before the `stopped' annotation, a variety of +annotations describe how the program stopped. + +`^Z^Zexited EXIT-STATUS' + The program exited, and EXIT-STATUS is the exit status (zero for + successful exit, otherwise nonzero). + +`^Z^Zsignalled' + The program exited with a signal. After the `^Z^Zsignalled', the + annotation continues: + + INTRO-TEXT + ^Z^Zsignal-name + NAME + ^Z^Zsignal-name-end + MIDDLE-TEXT + ^Z^Zsignal-string + STRING + ^Z^Zsignal-string-end + END-TEXT + + where NAME is the name of the signal, such as `SIGILL' or + `SIGSEGV', and STRING is the explanation of the signal, such as + `Illegal Instruction' or `Segmentation fault'. INTRO-TEXT, + MIDDLE-TEXT, and END-TEXT are for the user's benefit and have no + particular format. + +`^Z^Zsignal' + The syntax of this annotation is just like `signalled', but GDB is + just saying that the program received the signal, not that it was + terminated with it. + +`^Z^Zbreakpoint NUMBER' + The program hit breakpoint number NUMBER. + +`^Z^Zwatchpoint NUMBER' + The program hit watchpoint number NUMBER. + + +File: gdb.info, Node: Source Annotations, Prev: Annotations for Running, Up: Annotations + +Displaying Source +================= + +The following annotation is used instead of displaying source code: + + ^Z^Zsource FILENAME:LINE:CHARACTER:MIDDLE:ADDR + + where FILENAME is an absolute file name indicating which source +file, LINE is the line number within that file (where 1 is the first +line in the file), CHARACTER is the character position within the file +(where 0 is the first character in the file) (for most debug formats +this will necessarily point to the beginning of a line), MIDDLE is +`middle' if ADDR is in the middle of the line, or `beg' if ADDR is at +the beginning of the line, and ADDR is the address in the target +program associated with the source which is being displayed. ADDR is +in the form `0x' followed by one or more lowercase hex digits (note +that this does not depend on the language). + + +File: gdb.info, Node: GDB Bugs, Next: Formatting Documentation, Prev: GDB/MI, Up: Top + +Reporting Bugs in GDB +********************* + +Your bug reports play an essential role in making GDB reliable. + + Reporting a bug may help you by bringing a solution to your problem, +or it may not. But in any case the principal function of a bug report +is to help the entire community by making the next version of GDB work +better. Bug reports are your contribution to the maintenance of GDB. + + In order for a bug report to serve its purpose, you must include the +information that enables us to fix the bug. + +* Menu: + +* Bug Criteria:: Have you found a bug? +* Bug Reporting:: How to report bugs + + +File: gdb.info, Node: Bug Criteria, Next: Bug Reporting, Up: GDB Bugs + +Have you found a bug? +===================== + +If you are not sure whether you have found a bug, here are some +guidelines: + + * If the debugger gets a fatal signal, for any input whatever, that + is a GDB bug. Reliable debuggers never crash. + + * If GDB produces an error message for valid input, that is a bug. + (Note that if you're cross debugging, the problem may also be + somewhere in the connection to the target.) + + * If GDB does not produce an error message for invalid input, that + is a bug. However, you should note that your idea of "invalid + input" might be our idea of "an extension" or "support for + traditional practice". + + * If you are an experienced user of debugging tools, your suggestions + for improvement of GDB are welcome in any case. + + +File: gdb.info, Node: Bug Reporting, Prev: Bug Criteria, Up: GDB Bugs + +How to report bugs +================== + +A number of companies and individuals offer support for GNU products. +If you obtained GDB from a support organization, we recommend you +contact that organization first. + + You can find contact information for many support companies and +individuals in the file `etc/SERVICE' in the GNU Emacs distribution. + + In any event, we also recommend that you submit bug reports for GDB. +The prefered method is to submit them directly using GDB's Bugs web +page (http://www.gnu.org/software/gdb/bugs/). Alternatively, the +e-mail gateway can be used. + + *Do not send bug reports to `info-gdb', or to `help-gdb', or to any +newsgroups.* Most users of GDB do not want to receive bug reports. +Those that do have arranged to receive `bug-gdb'. + + The mailing list `bug-gdb' has a newsgroup `gnu.gdb.bug' which +serves as a repeater. The mailing list and the newsgroup carry exactly +the same messages. Often people think of posting bug reports to the +newsgroup instead of mailing them. This appears to work, but it has one +problem which can be crucial: a newsgroup posting often lacks a mail +path back to the sender. Thus, if we need to ask for more information, +we may be unable to reach you. For this reason, it is better to send +bug reports to the mailing list. + + The fundamental principle of reporting bugs usefully is this: +*report all the facts*. If you are not sure whether to state a fact or +leave it out, state it! + + Often people omit facts because they think they know what causes the +problem and assume that some details do not matter. Thus, you might +assume that the name of the variable you use in an example does not +matter. Well, probably it does not, but one cannot be sure. Perhaps +the bug is a stray memory reference which happens to fetch from the +location where that name is stored in memory; perhaps, if the name were +different, the contents of that location would fool the debugger into +doing the right thing despite the bug. Play it safe and give a +specific, complete example. That is the easiest thing for you to do, +and the most helpful. + + Keep in mind that the purpose of a bug report is to enable us to fix +the bug. It may be that the bug has been reported previously, but +neither you nor we can know that unless your bug report is complete and +self-contained. + + Sometimes people give a few sketchy facts and ask, "Does this ring a +bell?" Those bug reports are useless, and we urge everyone to _refuse +to respond to them_ except to chide the sender to report bugs properly. + + To enable us to fix the bug, you should include all these things: + + * The version of GDB. GDB announces it if you start with no + arguments; you can also print it at any time using `show version'. + + Without this, we will not know whether there is any point in + looking for the bug in the current version of GDB. + + * The type of machine you are using, and the operating system name + and version number. + + * What compiler (and its version) was used to compile GDB--e.g. + "gcc-2.8.1". + + * What compiler (and its version) was used to compile the program + you are debugging--e.g. "gcc-2.8.1", or "HP92453-01 A.10.32.03 HP + C Compiler". For GCC, you can say `gcc --version' to get this + information; for other compilers, see the documentation for those + compilers. + + * The command arguments you gave the compiler to compile your + example and observe the bug. For example, did you use `-O'? To + guarantee you will not omit something important, list them all. A + copy of the Makefile (or the output from make) is sufficient. + + If we were to try to guess the arguments, we would probably guess + wrong and then we might not encounter the bug. + + * A complete input script, and all necessary source files, that will + reproduce the bug. + + * A description of what behavior you observe that you believe is + incorrect. For example, "It gets a fatal signal." + + Of course, if the bug is that GDB gets a fatal signal, then we + will certainly notice it. But if the bug is incorrect output, we + might not notice unless it is glaringly wrong. You might as well + not give us a chance to make a mistake. + + Even if the problem you experience is a fatal signal, you should + still say so explicitly. Suppose something strange is going on, + such as, your copy of GDB is out of synch, or you have encountered + a bug in the C library on your system. (This has happened!) Your + copy might crash and ours would not. If you told us to expect a + crash, then when ours fails to crash, we would know that the bug + was not happening for us. If you had not told us to expect a + crash, then we would not be able to draw any conclusion from our + observations. + + * If you wish to suggest changes to the GDB source, send us context + diffs. If you even discuss something in the GDB source, refer to + it by context, not by line number. + + The line numbers in our development sources will not match those + in your sources. Your line numbers would convey no useful + information to us. + + + Here are some things that are not necessary: + + * A description of the envelope of the bug. + + Often people who encounter a bug spend a lot of time investigating + which changes to the input file will make the bug go away and which + changes will not affect it. + + This is often time consuming and not very useful, because the way + we will find the bug is by running a single example under the + debugger with breakpoints, not by pure deduction from a series of + examples. We recommend that you save your time for something else. + + Of course, if you can find a simpler example to report _instead_ + of the original one, that is a convenience for us. Errors in the + output will be easier to spot, running under the debugger will take + less time, and so on. + + However, simplification is not vital; if you do not want to do + this, report the bug anyway and send us the entire test case you + used. + + * A patch for the bug. + + A patch for the bug does help us if it is a good one. But do not + omit the necessary information, such as the test case, on the + assumption that a patch is all we need. We might see problems + with your patch and decide to fix the problem another way, or we + might not understand it at all. + + Sometimes with a program as complicated as GDB it is very hard to + construct an example that will make the program follow a certain + path through the code. If you do not send us the example, we will + not be able to construct one, so we will not be able to verify + that the bug is fixed. + + And if we cannot understand what bug you are trying to fix, or why + your patch should be an improvement, we will not install it. A + test case will help us to understand. + + * A guess about what the bug is or what it depends on. + + Such guesses are usually wrong. Even we cannot guess right about + such things without first using the debugger to find the facts. + + +File: gdb.info, Node: Command Line Editing, Next: Using History Interactively, Prev: Formatting Documentation, Up: Top + +Command Line Editing +******************** + +This chapter describes the basic features of the GNU command line +editing interface. + +* Menu: + +* Introduction and Notation:: Notation used in this text. +* Readline Interaction:: The minimum set of commands for editing a line. +* Readline Init File:: Customizing Readline from a user's view. +* Bindable Readline Commands:: A description of most of the Readline commands + available for binding +* Readline vi Mode:: A short description of how to make Readline + behave like the vi editor. + + +File: gdb.info, Node: Introduction and Notation, Next: Readline Interaction, Up: Command Line Editing + +Introduction to Line Editing +============================ + +The following paragraphs describe the notation used to represent +keystrokes. + + The text `C-k' is read as `Control-K' and describes the character +produced when the key is pressed while the Control key is depressed. + + The text `M-k' is read as `Meta-K' and describes the character +produced when the Meta key (if you have one) is depressed, and the +key is pressed. The Meta key is labeled on many keyboards. On +keyboards with two keys labeled (usually to either side of the +space bar), the on the left side is generally set to work as a +Meta key. The key on the right may also be configured to work as +a Meta key or may be configured as some other modifier, such as a +Compose key for typing accented characters. + + If you do not have a Meta or key, or another key working as a +Meta key, the identical keystroke can be generated by typing +_first_, and then typing . Either process is known as "metafying" +the key. + + The text `M-C-k' is read as `Meta-Control-k' and describes the +character produced by "metafying" `C-k'. + + In addition, several keys have their own names. Specifically, +, , , , , and all stand for themselves +when seen in this text, or in an init file (*note Readline Init File::). +If your keyboard lacks a key, typing will produce the +desired character. The key may be labeled or on +some keyboards. + + +File: gdb.info, Node: Readline Interaction, Next: Readline Init File, Prev: Introduction and Notation, Up: Command Line Editing + +Readline Interaction +==================== + +Often during an interactive session you type in a long line of text, +only to notice that the first word on the line is misspelled. The +Readline library gives you a set of commands for manipulating the text +as you type it in, allowing you to just fix your typo, and not forcing +you to retype the majority of the line. Using these editing commands, +you move the cursor to the place that needs correction, and delete or +insert the text of the corrections. Then, when you are satisfied with +the line, you simply press . You do not have to be at the end of +the line to press ; the entire line is accepted regardless of the +location of the cursor within the line. + +* Menu: + +* Readline Bare Essentials:: The least you need to know about Readline. +* Readline Movement Commands:: Moving about the input line. +* Readline Killing Commands:: How to delete text, and how to get it back! +* Readline Arguments:: Giving numeric arguments to commands. +* Searching:: Searching through previous lines. + + +File: gdb.info, Node: Readline Bare Essentials, Next: Readline Movement Commands, Up: Readline Interaction + +Readline Bare Essentials +------------------------ + +In order to enter characters into the line, simply type them. The typed +character appears where the cursor was, and then the cursor moves one +space to the right. If you mistype a character, you can use your erase +character to back up and delete the mistyped character. + + Sometimes you may mistype a character, and not notice the error +until you have typed several other characters. In that case, you can +type `C-b' to move the cursor to the left, and then correct your +mistake. Afterwards, you can move the cursor to the right with `C-f'. + + When you add text in the middle of a line, you will notice that +characters to the right of the cursor are `pushed over' to make room +for the text that you have inserted. Likewise, when you delete text +behind the cursor, characters to the right of the cursor are `pulled +back' to fill in the blank space created by the removal of the text. A +list of the bare essentials for editing the text of an input line +follows. + +`C-b' + Move back one character. + +`C-f' + Move forward one character. + + or + Delete the character to the left of the cursor. + +`C-d' + Delete the character underneath the cursor. + +Printing characters + Insert the character into the line at the cursor. + +`C-_' or `C-x C-u' + Undo the last editing command. You can undo all the way back to an + empty line. + +(Depending on your configuration, the key be set to delete +the character to the left of the cursor and the key set to delete +the character underneath the cursor, like `C-d', rather than the +character to the left of the cursor.) + + +File: gdb.info, Node: Readline Movement Commands, Next: Readline Killing Commands, Prev: Readline Bare Essentials, Up: Readline Interaction + +Readline Movement Commands +-------------------------- + +The above table describes the most basic keystrokes that you need in +order to do editing of the input line. For your convenience, many +other commands have been added in addition to `C-b', `C-f', `C-d', and +. Here are some commands for moving more rapidly about the line. + +`C-a' + Move to the start of the line. + +`C-e' + Move to the end of the line. + +`M-f' + Move forward a word, where a word is composed of letters and + digits. + +`M-b' + Move backward a word. + +`C-l' + Clear the screen, reprinting the current line at the top. + + Notice how `C-f' moves forward a character, while `M-f' moves +forward a word. It is a loose convention that control keystrokes +operate on characters while meta keystrokes operate on words. + + +File: gdb.info, Node: Readline Killing Commands, Next: Readline Arguments, Prev: Readline Movement Commands, Up: Readline Interaction + +Readline Killing Commands +------------------------- + +"Killing" text means to delete the text from the line, but to save it +away for later use, usually by "yanking" (re-inserting) it back into +the line. (`Cut' and `paste' are more recent jargon for `kill' and +`yank'.) + + If the description for a command says that it `kills' text, then you +can be sure that you can get the text back in a different (or the same) +place later. + + When you use a kill command, the text is saved in a "kill-ring". +Any number of consecutive kills save all of the killed text together, so +that when you yank it back, you get it all. The kill ring is not line +specific; the text that you killed on a previously typed line is +available to be yanked back later, when you are typing another line. + + Here is the list of commands for killing text. + +`C-k' + Kill the text from the current cursor position to the end of the + line. + +`M-d' + Kill from the cursor to the end of the current word, or, if between + words, to the end of the next word. Word boundaries are the same + as those used by `M-f'. + +`M-' + Kill from the cursor the start of the current word, or, if between + words, to the start of the previous word. Word boundaries are the + same as those used by `M-b'. + +`C-w' + Kill from the cursor to the previous whitespace. This is + different than `M-' because the word boundaries differ. + + + Here is how to "yank" the text back into the line. Yanking means to +copy the most-recently-killed text from the kill buffer. + +`C-y' + Yank the most recently killed text back into the buffer at the + cursor. + +`M-y' + Rotate the kill-ring, and yank the new top. You can only do this + if the prior command is `C-y' or `M-y'. + + +File: gdb.info, Node: Readline Arguments, Next: Searching, Prev: Readline Killing Commands, Up: Readline Interaction + +Readline Arguments +------------------ + +You can pass numeric arguments to Readline commands. Sometimes the +argument acts as a repeat count, other times it is the sign of the +argument that is significant. If you pass a negative argument to a +command which normally acts in a forward direction, that command will +act in a backward direction. For example, to kill text back to the +start of the line, you might type `M-- C-k'. + + The general way to pass numeric arguments to a command is to type +meta digits before the command. If the first `digit' typed is a minus +sign (`-'), then the sign of the argument will be negative. Once you +have typed one meta digit to get the argument started, you can type the +remainder of the digits, and then the command. For example, to give +the `C-d' command an argument of 10, you could type `M-1 0 C-d', which +will delete the next ten characters on the input line. + diff --git a/contrib/gdb/gdb/doc/gdb.info-3 b/contrib/gdb/gdb/doc/gdb.info-3 new file mode 100644 index 00000000000..ada53b48bb5 --- /dev/null +++ b/contrib/gdb/gdb/doc/gdb.info-3 @@ -0,0 +1,6665 @@ +This is gdb.info, produced by makeinfo version 4.6 from ./gdb.texinfo. + +INFO-DIR-SECTION Software development +START-INFO-DIR-ENTRY +* Gdb: (gdb). The GNU debugger. +END-INFO-DIR-ENTRY + + This file documents the GNU debugger GDB. + + This is the Ninth Edition, of `Debugging with GDB: the GNU +Source-Level Debugger' for GDB Version 6.1.1. + + Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, +1998, +1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with the +Invariant Sections being "Free Software" and "Free Software Needs Free +Documentation", with the Front-Cover Texts being "A GNU Manual," and +with the Back-Cover Texts as in (a) below. + + (a) The Free Software Foundation's Back-Cover Text is: "You have +freedom to copy and modify this GNU Manual, like GNU software. Copies +published by the Free Software Foundation raise funds for GNU +development." + + +File: gdb.info, Node: Searching, Prev: Readline Arguments, Up: Readline Interaction + +Searching for Commands in the History +------------------------------------- + +Readline provides commands for searching through the command history +for lines containing a specified string. There are two search modes: +"incremental" and "non-incremental". + + Incremental searches begin before the user has finished typing the +search string. As each character of the search string is typed, +Readline displays the next entry from the history matching the string +typed so far. An incremental search requires only as many characters +as needed to find the desired history entry. To search backward in the +history for a particular string, type `C-r'. Typing `C-s' searches +forward through the history. The characters present in the value of +the `isearch-terminators' variable are used to terminate an incremental +search. If that variable has not been assigned a value, the and +`C-J' characters will terminate an incremental search. `C-g' will +abort an incremental search and restore the original line. When the +search is terminated, the history entry containing the search string +becomes the current line. + + To find other matching entries in the history list, type `C-r' or +`C-s' as appropriate. This will search backward or forward in the +history for the next entry matching the search string typed so far. +Any other key sequence bound to a Readline command will terminate the +search and execute that command. For instance, a will terminate +the search and accept the line, thereby executing the command from the +history list. A movement command will terminate the search, make the +last line found the current line, and begin editing. + + Readline remembers the last incremental search string. If two +`C-r's are typed without any intervening characters defining a new +search string, any remembered search string is used. + + Non-incremental searches read the entire search string before +starting to search for matching history lines. The search string may be +typed by the user or be part of the contents of the current line. + + +File: gdb.info, Node: Readline Init File, Next: Bindable Readline Commands, Prev: Readline Interaction, Up: Command Line Editing + +Readline Init File +================== + +Although the Readline library comes with a set of Emacs-like +keybindings installed by default, it is possible to use a different set +of keybindings. Any user can customize programs that use Readline by +putting commands in an "inputrc" file, conventionally in his home +directory. The name of this file is taken from the value of the +environment variable `INPUTRC'. If that variable is unset, the default +is `~/.inputrc'. + + When a program which uses the Readline library starts up, the init +file is read, and the key bindings are set. + + In addition, the `C-x C-r' command re-reads this init file, thus +incorporating any changes that you might have made to it. + +* Menu: + +* Readline Init File Syntax:: Syntax for the commands in the inputrc file. + +* Conditional Init Constructs:: Conditional key bindings in the inputrc file. + +* Sample Init File:: An example inputrc file. + + +File: gdb.info, Node: Readline Init File Syntax, Next: Conditional Init Constructs, Up: Readline Init File + +Readline Init File Syntax +------------------------- + +There are only a few basic constructs allowed in the Readline init +file. Blank lines are ignored. Lines beginning with a `#' are +comments. Lines beginning with a `$' indicate conditional constructs +(*note Conditional Init Constructs::). Other lines denote variable +settings and key bindings. + +Variable Settings + You can modify the run-time behavior of Readline by altering the + values of variables in Readline using the `set' command within the + init file. The syntax is simple: + + set VARIABLE VALUE + + Here, for example, is how to change from the default Emacs-like + key binding to use `vi' line editing commands: + + set editing-mode vi + + Variable names and values, where appropriate, are recognized + without regard to case. + + A great deal of run-time behavior is changeable with the following + variables. + + `bell-style' + Controls what happens when Readline wants to ring the + terminal bell. If set to `none', Readline never rings the + bell. If set to `visible', Readline uses a visible bell if + one is available. If set to `audible' (the default), + Readline attempts to ring the terminal's bell. + + `comment-begin' + The string to insert at the beginning of the line when the + `insert-comment' command is executed. The default value is + `"#"'. + + `completion-ignore-case' + If set to `on', Readline performs filename matching and + completion in a case-insensitive fashion. The default value + is `off'. + + `completion-query-items' + The number of possible completions that determines when the + user is asked whether he wants to see the list of + possibilities. If the number of possible completions is + greater than this value, Readline will ask the user whether + or not he wishes to view them; otherwise, they are simply + listed. This variable must be set to an integer value + greater than or equal to 0. The default limit is `100'. + + `convert-meta' + If set to `on', Readline will convert characters with the + eighth bit set to an ASCII key sequence by stripping the + eighth bit and prefixing an character, converting them + to a meta-prefixed key sequence. The default value is `on'. + + `disable-completion' + If set to `On', Readline will inhibit word completion. + Completion characters will be inserted into the line as if + they had been mapped to `self-insert'. The default is `off'. + + `editing-mode' + The `editing-mode' variable controls which default set of key + bindings is used. By default, Readline starts up in Emacs + editing mode, where the keystrokes are most similar to Emacs. + This variable can be set to either `emacs' or `vi'. + + `enable-keypad' + When set to `on', Readline will try to enable the application + keypad when it is called. Some systems need this to enable + the arrow keys. The default is `off'. + + `expand-tilde' + If set to `on', tilde expansion is performed when Readline + attempts word completion. The default is `off'. + + If set to `on', the history code attempts to place point at + the same location on each history line retrived with + `previous-history' or `next-history'. + + `horizontal-scroll-mode' + This variable can be set to either `on' or `off'. Setting it + to `on' means that the text of the lines being edited will + scroll horizontally on a single screen line when they are + longer than the width of the screen, instead of wrapping onto + a new screen line. By default, this variable is set to `off'. + + `input-meta' + If set to `on', Readline will enable eight-bit input (it will + not clear the eighth bit in the characters it reads), + regardless of what the terminal claims it can support. The + default value is `off'. The name `meta-flag' is a synonym + for this variable. + + `isearch-terminators' + The string of characters that should terminate an incremental + search without subsequently executing the character as a + command (*note Searching::). If this variable has not been + given a value, the characters and `C-J' will terminate + an incremental search. + + `keymap' + Sets Readline's idea of the current keymap for key binding + commands. Acceptable `keymap' names are `emacs', + `emacs-standard', `emacs-meta', `emacs-ctlx', `vi', `vi-move', + `vi-command', and `vi-insert'. `vi' is equivalent to + `vi-command'; `emacs' is equivalent to `emacs-standard'. The + default value is `emacs'. The value of the `editing-mode' + variable also affects the default keymap. + + `mark-directories' + If set to `on', completed directory names have a slash + appended. The default is `on'. + + `mark-modified-lines' + This variable, when set to `on', causes Readline to display an + asterisk (`*') at the start of history lines which have been + modified. This variable is `off' by default. + + `mark-symlinked-directories' + If set to `on', completed names which are symbolic links to + directories have a slash appended (subject to the value of + `mark-directories'). The default is `off'. + + `match-hidden-files' + This variable, when set to `on', causes Readline to match + files whose names begin with a `.' (hidden files) when + performing filename completion, unless the leading `.' is + supplied by the user in the filename to be completed. This + variable is `on' by default. + + `output-meta' + If set to `on', Readline will display characters with the + eighth bit set directly rather than as a meta-prefixed escape + sequence. The default is `off'. + + `page-completions' + If set to `on', Readline uses an internal `more'-like pager + to display a screenful of possible completions at a time. + This variable is `on' by default. + + `print-completions-horizontally' + If set to `on', Readline will display completions with matches + sorted horizontally in alphabetical order, rather than down + the screen. The default is `off'. + + `show-all-if-ambiguous' + This alters the default behavior of the completion functions. + If set to `on', words which have more than one possible + completion cause the matches to be listed immediately instead + of ringing the bell. The default value is `off'. + + `visible-stats' + If set to `on', a character denoting a file's type is + appended to the filename when listing possible completions. + The default is `off'. + + +Key Bindings + The syntax for controlling key bindings in the init file is + simple. First you need to find the name of the command that you + want to change. The following sections contain tables of the + command name, the default keybinding, if any, and a short + description of what the command does. + + Once you know the name of the command, simply place on a line in + the init file the name of the key you wish to bind the command to, + a colon, and then the name of the command. The name of the key + can be expressed in different ways, depending on what you find most + comfortable. + + In addition to command names, readline allows keys to be bound to + a string that is inserted when the key is pressed (a MACRO). + + KEYNAME: FUNCTION-NAME or MACRO + KEYNAME is the name of a key spelled out in English. For + example: + Control-u: universal-argument + Meta-Rubout: backward-kill-word + Control-o: "> output" + + In the above example, `C-u' is bound to the function + `universal-argument', `M-DEL' is bound to the function + `backward-kill-word', and `C-o' is bound to run the macro + expressed on the right hand side (that is, to insert the text + `> output' into the line). + + A number of symbolic character names are recognized while + processing this key binding syntax: DEL, ESC, ESCAPE, LFD, + NEWLINE, RET, RETURN, RUBOUT, SPACE, SPC, and TAB. + + "KEYSEQ": FUNCTION-NAME or MACRO + KEYSEQ differs from KEYNAME above in that strings denoting an + entire key sequence can be specified, by placing the key + sequence in double quotes. Some GNU Emacs style key escapes + can be used, as in the following example, but the special + character names are not recognized. + + "\C-u": universal-argument + "\C-x\C-r": re-read-init-file + "\e[11~": "Function Key 1" + + In the above example, `C-u' is again bound to the function + `universal-argument' (just as it was in the first example), + `C-x C-r' is bound to the function `re-read-init-file', and + ` <[> <1> <1> <~>' is bound to insert the text `Function + Key 1'. + + + The following GNU Emacs style escape sequences are available when + specifying key sequences: + + `\C-' + control prefix + + `\M-' + meta prefix + + `\e' + an escape character + + `\\' + backslash + + `\"' + <">, a double quotation mark + + `\'' + <'>, a single quote or apostrophe + + In addition to the GNU Emacs style escape sequences, a second set + of backslash escapes is available: + + `\a' + alert (bell) + + `\b' + backspace + + `\d' + delete + + `\f' + form feed + + `\n' + newline + + `\r' + carriage return + + `\t' + horizontal tab + + `\v' + vertical tab + + `\NNN' + the eight-bit character whose value is the octal value NNN + (one to three digits) + + `\xHH' + the eight-bit character whose value is the hexadecimal value + HH (one or two hex digits) + + When entering the text of a macro, single or double quotes must be + used to indicate a macro definition. Unquoted text is assumed to + be a function name. In the macro body, the backslash escapes + described above are expanded. Backslash will quote any other + character in the macro text, including `"' and `''. For example, + the following binding will make `C-x \' insert a single `\' into + the line: + "\C-x\\": "\\" + + + +File: gdb.info, Node: Conditional Init Constructs, Next: Sample Init File, Prev: Readline Init File Syntax, Up: Readline Init File + +Conditional Init Constructs +--------------------------- + +Readline implements a facility similar in spirit to the conditional +compilation features of the C preprocessor which allows key bindings +and variable settings to be performed as the result of tests. There +are four parser directives used. + +`$if' + The `$if' construct allows bindings to be made based on the + editing mode, the terminal being used, or the application using + Readline. The text of the test extends to the end of the line; no + characters are required to isolate it. + + `mode' + The `mode=' form of the `$if' directive is used to test + whether Readline is in `emacs' or `vi' mode. This may be + used in conjunction with the `set keymap' command, for + instance, to set bindings in the `emacs-standard' and + `emacs-ctlx' keymaps only if Readline is starting out in + `emacs' mode. + + `term' + The `term=' form may be used to include terminal-specific key + bindings, perhaps to bind the key sequences output by the + terminal's function keys. The word on the right side of the + `=' is tested against both the full name of the terminal and + the portion of the terminal name before the first `-'. This + allows `sun' to match both `sun' and `sun-cmd', for instance. + + `application' + The APPLICATION construct is used to include + application-specific settings. Each program using the + Readline library sets the APPLICATION NAME, and you can test + for a particular value. This could be used to bind key + sequences to functions useful for a specific program. For + instance, the following command adds a key sequence that + quotes the current or previous word in Bash: + $if Bash + # Quote the current or previous word + "\C-xq": "\eb\"\ef\"" + $endif + +`$endif' + This command, as seen in the previous example, terminates an `$if' + command. + +`$else' + Commands in this branch of the `$if' directive are executed if the + test fails. + +`$include' + This directive takes a single filename as an argument and reads + commands and bindings from that file. For example, the following + directive reads from `/etc/inputrc': + $include /etc/inputrc + + +File: gdb.info, Node: Sample Init File, Prev: Conditional Init Constructs, Up: Readline Init File + +Sample Init File +---------------- + +Here is an example of an INPUTRC file. This illustrates key binding, +variable assignment, and conditional syntax. + + + # This file controls the behaviour of line input editing for + # programs that use the GNU Readline library. Existing + # programs include FTP, Bash, and GDB. + # + # You can re-read the inputrc file with C-x C-r. + # Lines beginning with '#' are comments. + # + # First, include any systemwide bindings and variable + # assignments from /etc/Inputrc + $include /etc/Inputrc + + # + # Set various bindings for emacs mode. + + set editing-mode emacs + + $if mode=emacs + + Meta-Control-h: backward-kill-word Text after the function name is ignored + + # + # Arrow keys in keypad mode + # + #"\M-OD": backward-char + #"\M-OC": forward-char + #"\M-OA": previous-history + #"\M-OB": next-history + # + # Arrow keys in ANSI mode + # + "\M-[D": backward-char + "\M-[C": forward-char + "\M-[A": previous-history + "\M-[B": next-history + # + # Arrow keys in 8 bit keypad mode + # + #"\M-\C-OD": backward-char + #"\M-\C-OC": forward-char + #"\M-\C-OA": previous-history + #"\M-\C-OB": next-history + # + # Arrow keys in 8 bit ANSI mode + # + #"\M-\C-[D": backward-char + #"\M-\C-[C": forward-char + #"\M-\C-[A": previous-history + #"\M-\C-[B": next-history + + C-q: quoted-insert + + $endif + + # An old-style binding. This happens to be the default. + TAB: complete + + # Macros that are convenient for shell interaction + $if Bash + # edit the path + "\C-xp": "PATH=${PATH}\e\C-e\C-a\ef\C-f" + # prepare to type a quoted word -- + # insert open and close double quotes + # and move to just after the open quote + "\C-x\"": "\"\"\C-b" + # insert a backslash (testing backslash escapes + # in sequences and macros) + "\C-x\\": "\\" + # Quote the current or previous word + "\C-xq": "\eb\"\ef\"" + # Add a binding to refresh the line, which is unbound + "\C-xr": redraw-current-line + # Edit variable on current line. + "\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" + $endif + + # use a visible bell if one is available + set bell-style visible + + # don't strip characters to 7 bits when reading + set input-meta on + + # allow iso-latin1 characters to be inserted rather + # than converted to prefix-meta sequences + set convert-meta off + + # display characters with the eighth bit set directly + # rather than as meta-prefixed characters + set output-meta on + + # if there are more than 150 possible completions for + # a word, ask the user if he wants to see all of them + set completion-query-items 150 + + # For FTP + $if Ftp + "\C-xg": "get \M-?" + "\C-xt": "put \M-?" + "\M-.": yank-last-arg + $endif + + +File: gdb.info, Node: Bindable Readline Commands, Next: Readline vi Mode, Prev: Readline Init File, Up: Command Line Editing + +Bindable Readline Commands +========================== + +* Menu: + +* Commands For Moving:: Moving about the line. +* Commands For History:: Getting at previous lines. +* Commands For Text:: Commands for changing text. +* Commands For Killing:: Commands for killing and yanking. +* Numeric Arguments:: Specifying numeric arguments, repeat counts. +* Commands For Completion:: Getting Readline to do the typing for you. +* Keyboard Macros:: Saving and re-executing typed characters +* Miscellaneous Commands:: Other miscellaneous commands. + + This section describes Readline commands that may be bound to key +sequences. Command names without an accompanying key sequence are +unbound by default. + + In the following descriptions, "point" refers to the current cursor +position, and "mark" refers to a cursor position saved by the +`set-mark' command. The text between the point and mark is referred to +as the "region". + + +File: gdb.info, Node: Commands For Moving, Next: Commands For History, Up: Bindable Readline Commands + +Commands For Moving +------------------- + +`beginning-of-line (C-a)' + Move to the start of the current line. + +`end-of-line (C-e)' + Move to the end of the line. + +`forward-char (C-f)' + Move forward a character. + +`backward-char (C-b)' + Move back a character. + +`forward-word (M-f)' + Move forward to the end of the next word. Words are composed of + letters and digits. + +`backward-word (M-b)' + Move back to the start of the current or previous word. Words are + composed of letters and digits. + +`clear-screen (C-l)' + Clear the screen and redraw the current line, leaving the current + line at the top of the screen. + +`redraw-current-line ()' + Refresh the current line. By default, this is unbound. + + + +File: gdb.info, Node: Commands For History, Next: Commands For Text, Prev: Commands For Moving, Up: Bindable Readline Commands + +Commands For Manipulating The History +------------------------------------- + +`accept-line (Newline or Return)' + Accept the line regardless of where the cursor is. If this line is + non-empty, it may be added to the history list for future recall + with `add_history()'. If this line is a modified history line, + the history line is restored to its original state. + +`previous-history (C-p)' + Move `back' through the history list, fetching the previous + command. + +`next-history (C-n)' + Move `forward' through the history list, fetching the next command. + +`beginning-of-history (M-<)' + Move to the first line in the history. + +`end-of-history (M->)' + Move to the end of the input history, i.e., the line currently + being entered. + +`reverse-search-history (C-r)' + Search backward starting at the current line and moving `up' + through the history as necessary. This is an incremental search. + +`forward-search-history (C-s)' + Search forward starting at the current line and moving `down' + through the the history as necessary. This is an incremental + search. + +`non-incremental-reverse-search-history (M-p)' + Search backward starting at the current line and moving `up' + through the history as necessary using a non-incremental search + for a string supplied by the user. + +`non-incremental-forward-search-history (M-n)' + Search forward starting at the current line and moving `down' + through the the history as necessary using a non-incremental search + for a string supplied by the user. + +`history-search-forward ()' + Search forward through the history for the string of characters + between the start of the current line and the point. This is a + non-incremental search. By default, this command is unbound. + +`history-search-backward ()' + Search backward through the history for the string of characters + between the start of the current line and the point. This is a + non-incremental search. By default, this command is unbound. + +`yank-nth-arg (M-C-y)' + Insert the first argument to the previous command (usually the + second word on the previous line) at point. With an argument N, + insert the Nth word from the previous command (the words in the + previous command begin with word 0). A negative argument inserts + the Nth word from the end of the previous command. + +`yank-last-arg (M-. or M-_)' + Insert last argument to the previous command (the last word of the + previous history entry). With an argument, behave exactly like + `yank-nth-arg'. Successive calls to `yank-last-arg' move back + through the history list, inserting the last argument of each line + in turn. + + + +File: gdb.info, Node: Commands For Text, Next: Commands For Killing, Prev: Commands For History, Up: Bindable Readline Commands + +Commands For Changing Text +-------------------------- + +`delete-char (C-d)' + Delete the character at point. If point is at the beginning of + the line, there are no characters in the line, and the last + character typed was not bound to `delete-char', then return EOF. + +`backward-delete-char (Rubout)' + Delete the character behind the cursor. A numeric argument means + to kill the characters instead of deleting them. + +`forward-backward-delete-char ()' + Delete the character under the cursor, unless the cursor is at the + end of the line, in which case the character behind the cursor is + deleted. By default, this is not bound to a key. + +`quoted-insert (C-q or C-v)' + Add the next character typed to the line verbatim. This is how to + insert key sequences like `C-q', for example. + +`tab-insert (M-)' + Insert a tab character. + +`self-insert (a, b, A, 1, !, ...)' + Insert yourself. + +`transpose-chars (C-t)' + Drag the character before the cursor forward over the character at + the cursor, moving the cursor forward as well. If the insertion + point is at the end of the line, then this transposes the last two + characters of the line. Negative arguments have no effect. + +`transpose-words (M-t)' + Drag the word before point past the word after point, moving point + past that word as well. If the insertion point is at the end of + the line, this transposes the last two words on the line. + +`upcase-word (M-u)' + Uppercase the current (or following) word. With a negative + argument, uppercase the previous word, but do not move the cursor. + +`downcase-word (M-l)' + Lowercase the current (or following) word. With a negative + argument, lowercase the previous word, but do not move the cursor. + +`capitalize-word (M-c)' + Capitalize the current (or following) word. With a negative + argument, capitalize the previous word, but do not move the cursor. + +`overwrite-mode ()' + Toggle overwrite mode. With an explicit positive numeric argument, + switches to overwrite mode. With an explicit non-positive numeric + argument, switches to insert mode. This command affects only + `emacs' mode; `vi' mode does overwrite differently. Each call to + `readline()' starts in insert mode. + + In overwrite mode, characters bound to `self-insert' replace the + text at point rather than pushing the text to the right. + Characters bound to `backward-delete-char' replace the character + before point with a space. + + By default, this command is unbound. + + + +File: gdb.info, Node: Commands For Killing, Next: Numeric Arguments, Prev: Commands For Text, Up: Bindable Readline Commands + +Killing And Yanking +------------------- + +`kill-line (C-k)' + Kill the text from point to the end of the line. + +`backward-kill-line (C-x Rubout)' + Kill backward to the beginning of the line. + +`unix-line-discard (C-u)' + Kill backward from the cursor to the beginning of the current line. + +`kill-whole-line ()' + Kill all characters on the current line, no matter where point is. + By default, this is unbound. + +`kill-word (M-d)' + Kill from point to the end of the current word, or if between + words, to the end of the next word. Word boundaries are the same + as `forward-word'. + +`backward-kill-word (M-)' + Kill the word behind point. Word boundaries are the same as + `backward-word'. + +`unix-word-rubout (C-w)' + Kill the word behind point, using white space as a word boundary. + The killed text is saved on the kill-ring. + +`delete-horizontal-space ()' + Delete all spaces and tabs around point. By default, this is + unbound. + +`kill-region ()' + Kill the text in the current region. By default, this command is + unbound. + +`copy-region-as-kill ()' + Copy the text in the region to the kill buffer, so it can be yanked + right away. By default, this command is unbound. + +`copy-backward-word ()' + Copy the word before point to the kill buffer. The word + boundaries are the same as `backward-word'. By default, this + command is unbound. + +`copy-forward-word ()' + Copy the word following point to the kill buffer. The word + boundaries are the same as `forward-word'. By default, this + command is unbound. + +`yank (C-y)' + Yank the top of the kill ring into the buffer at point. + +`yank-pop (M-y)' + Rotate the kill-ring, and yank the new top. You can only do this + if the prior command is `yank' or `yank-pop'. + + +File: gdb.info, Node: Numeric Arguments, Next: Commands For Completion, Prev: Commands For Killing, Up: Bindable Readline Commands + +Specifying Numeric Arguments +---------------------------- + +`digit-argument (M-0, M-1, ... M--)' + Add this digit to the argument already accumulating, or start a new + argument. `M--' starts a negative argument. + +`universal-argument ()' + This is another way to specify an argument. If this command is + followed by one or more digits, optionally with a leading minus + sign, those digits define the argument. If the command is + followed by digits, executing `universal-argument' again ends the + numeric argument, but is otherwise ignored. As a special case, if + this command is immediately followed by a character that is + neither a digit or minus sign, the argument count for the next + command is multiplied by four. The argument count is initially + one, so executing this function the first time makes the argument + count four, a second time makes the argument count sixteen, and so + on. By default, this is not bound to a key. + + +File: gdb.info, Node: Commands For Completion, Next: Keyboard Macros, Prev: Numeric Arguments, Up: Bindable Readline Commands + +Letting Readline Type For You +----------------------------- + +`complete ()' + Attempt to perform completion on the text before point. The + actual completion performed is application-specific. The default + is filename completion. + +`possible-completions (M-?)' + List the possible completions of the text before point. + +`insert-completions (M-*)' + Insert all completions of the text before point that would have + been generated by `possible-completions'. + +`menu-complete ()' + Similar to `complete', but replaces the word to be completed with + a single match from the list of possible completions. Repeated + execution of `menu-complete' steps through the list of possible + completions, inserting each match in turn. At the end of the list + of completions, the bell is rung (subject to the setting of + `bell-style') and the original text is restored. An argument of N + moves N positions forward in the list of matches; a negative + argument may be used to move backward through the list. This + command is intended to be bound to , but is unbound by + default. + +`delete-char-or-list ()' + Deletes the character under the cursor if not at the beginning or + end of the line (like `delete-char'). If at the end of the line, + behaves identically to `possible-completions'. This command is + unbound by default. + + + +File: gdb.info, Node: Keyboard Macros, Next: Miscellaneous Commands, Prev: Commands For Completion, Up: Bindable Readline Commands + +Keyboard Macros +--------------- + +`start-kbd-macro (C-x ()' + Begin saving the characters typed into the current keyboard macro. + +`end-kbd-macro (C-x ))' + Stop saving the characters typed into the current keyboard macro + and save the definition. + +`call-last-kbd-macro (C-x e)' + Re-execute the last keyboard macro defined, by making the + characters in the macro appear as if typed at the keyboard. + + + +File: gdb.info, Node: Miscellaneous Commands, Prev: Keyboard Macros, Up: Bindable Readline Commands + +Some Miscellaneous Commands +--------------------------- + +`re-read-init-file (C-x C-r)' + Read in the contents of the INPUTRC file, and incorporate any + bindings or variable assignments found there. + +`abort (C-g)' + Abort the current editing command and ring the terminal's bell + (subject to the setting of `bell-style'). + +`do-uppercase-version (M-a, M-b, M-X, ...)' + If the metafied character X is lowercase, run the command that is + bound to the corresponding uppercase character. + +`prefix-meta ()' + Metafy the next character typed. This is for keyboards without a + meta key. Typing ` f' is equivalent to typing `M-f'. + +`undo (C-_ or C-x C-u)' + Incremental undo, separately remembered for each line. + +`revert-line (M-r)' + Undo all changes made to this line. This is like executing the + `undo' command enough times to get back to the beginning. + +`tilde-expand (M-~)' + Perform tilde expansion on the current word. + +`set-mark (C-@)' + Set the mark to the point. If a numeric argument is supplied, the + mark is set to that position. + +`exchange-point-and-mark (C-x C-x)' + Swap the point with the mark. The current cursor position is set + to the saved position, and the old cursor position is saved as the + mark. + +`character-search (C-])' + A character is read and point is moved to the next occurrence of + that character. A negative count searches for previous + occurrences. + +`character-search-backward (M-C-])' + A character is read and point is moved to the previous occurrence + of that character. A negative count searches for subsequent + occurrences. + +`insert-comment (M-#)' + Without a numeric argument, the value of the `comment-begin' + variable is inserted at the beginning of the current line. If a + numeric argument is supplied, this command acts as a toggle: if + the characters at the beginning of the line do not match the value + of `comment-begin', the value is inserted, otherwise the + characters in `comment-begin' are deleted from the beginning of + the line. In either case, the line is accepted as if a newline + had been typed. + +`dump-functions ()' + Print all of the functions and their key bindings to the Readline + output stream. If a numeric argument is supplied, the output is + formatted in such a way that it can be made part of an INPUTRC + file. This command is unbound by default. + +`dump-variables ()' + Print all of the settable variables and their values to the + Readline output stream. If a numeric argument is supplied, the + output is formatted in such a way that it can be made part of an + INPUTRC file. This command is unbound by default. + +`dump-macros ()' + Print all of the Readline key sequences bound to macros and the + strings they output. If a numeric argument is supplied, the + output is formatted in such a way that it can be made part of an + INPUTRC file. This command is unbound by default. + +`emacs-editing-mode (C-e)' + When in `vi' command mode, this causes a switch to `emacs' editing + mode. + +`vi-editing-mode (M-C-j)' + When in `emacs' editing mode, this causes a switch to `vi' editing + mode. + + + +File: gdb.info, Node: Readline vi Mode, Prev: Bindable Readline Commands, Up: Command Line Editing + +Readline vi Mode +================ + +While the Readline library does not have a full set of `vi' editing +functions, it does contain enough to allow simple editing of the line. +The Readline `vi' mode behaves as specified in the POSIX 1003.2 +standard. + + In order to switch interactively between `emacs' and `vi' editing +modes, use the command `M-C-j' (bound to emacs-editing-mode when in +`vi' mode and to vi-editing-mode in `emacs' mode). The Readline +default is `emacs' mode. + + When you enter a line in `vi' mode, you are already placed in +`insertion' mode, as if you had typed an `i'. Pressing switches +you into `command' mode, where you can edit the text of the line with +the standard `vi' movement keys, move to previous history lines with +`k' and subsequent lines with `j', and so forth. + + +File: gdb.info, Node: Using History Interactively, Next: Installing GDB, Prev: Command Line Editing, Up: Top + +Using History Interactively +*************************** + +This chapter describes how to use the GNU History Library interactively, +from a user's standpoint. It should be considered a user's guide. + +* Menu: + +* History Interaction:: What it feels like using History as a user. + + +File: gdb.info, Node: History Interaction, Up: Using History Interactively + +History Expansion +================= + +The History library provides a history expansion feature that is similar +to the history expansion provided by `csh'. This section describes the +syntax used to manipulate the history information. + + History expansions introduce words from the history list into the +input stream, making it easy to repeat commands, insert the arguments +to a previous command into the current input line, or fix errors in +previous commands quickly. + + History expansion takes place in two parts. The first is to +determine which line from the history list should be used during +substitution. The second is to select portions of that line for +inclusion into the current one. The line selected from the history is +called the "event", and the portions of that line that are acted upon +are called "words". Various "modifiers" are available to manipulate +the selected words. The line is broken into words in the same fashion +that Bash does, so that several words surrounded by quotes are +considered one word. History expansions are introduced by the +appearance of the history expansion character, which is `!' by default. + +* Menu: + +* Event Designators:: How to specify which history line to use. +* Word Designators:: Specifying which words are of interest. +* Modifiers:: Modifying the results of substitution. + + +File: gdb.info, Node: Event Designators, Next: Word Designators, Up: History Interaction + +Event Designators +----------------- + +An event designator is a reference to a command line entry in the +history list. + +`!' + Start a history substitution, except when followed by a space, tab, + the end of the line, `=' or `('. + +`!N' + Refer to command line N. + +`!-N' + Refer to the command N lines back. + +`!!' + Refer to the previous command. This is a synonym for `!-1'. + +`!STRING' + Refer to the most recent command starting with STRING. + +`!?STRING[?]' + Refer to the most recent command containing STRING. The trailing + `?' may be omitted if the STRING is followed immediately by a + newline. + +`^STRING1^STRING2^' + Quick Substitution. Repeat the last command, replacing STRING1 + with STRING2. Equivalent to `!!:s/STRING1/STRING2/'. + +`!#' + The entire command line typed so far. + + + +File: gdb.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction + +Word Designators +---------------- + +Word designators are used to select desired words from the event. A +`:' separates the event specification from the word designator. It may +be omitted if the word designator begins with a `^', `$', `*', `-', or +`%'. Words are numbered from the beginning of the line, with the first +word being denoted by 0 (zero). Words are inserted into the current +line separated by single spaces. + + For example, + +`!!' + designates the preceding command. When you type this, the + preceding command is repeated in toto. + +`!!:$' + designates the last argument of the preceding command. This may be + shortened to `!$'. + +`!fi:2' + designates the second argument of the most recent command starting + with the letters `fi'. + + Here are the word designators: + +`0 (zero)' + The `0'th word. For many applications, this is the command word. + +`N' + The Nth word. + +`^' + The first argument; that is, word 1. + +`$' + The last argument. + +`%' + The word matched by the most recent `?STRING?' search. + +`X-Y' + A range of words; `-Y' abbreviates `0-Y'. + +`*' + All of the words, except the `0'th. This is a synonym for `1-$'. + It is not an error to use `*' if there is just one word in the + event; the empty string is returned in that case. + +`X*' + Abbreviates `X-$' + +`X-' + Abbreviates `X-$' like `X*', but omits the last word. + + + If a word designator is supplied without an event specification, the +previous command is used as the event. + + +File: gdb.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction + +Modifiers +--------- + +After the optional word designator, you can add a sequence of one or +more of the following modifiers, each preceded by a `:'. + +`h' + Remove a trailing pathname component, leaving only the head. + +`t' + Remove all leading pathname components, leaving the tail. + +`r' + Remove a trailing suffix of the form `.SUFFIX', leaving the + basename. + +`e' + Remove all but the trailing suffix. + +`p' + Print the new command but do not execute it. + +`s/OLD/NEW/' + Substitute NEW for the first occurrence of OLD in the event line. + Any delimiter may be used in place of `/'. The delimiter may be + quoted in OLD and NEW with a single backslash. If `&' appears in + NEW, it is replaced by OLD. A single backslash will quote the + `&'. The final delimiter is optional if it is the last character + on the input line. + +`&' + Repeat the previous substitution. + +`g' + Cause changes to be applied over the entire event line. Used in + conjunction with `s', as in `gs/OLD/NEW/', or with `&'. + + + +File: gdb.info, Node: Formatting Documentation, Next: Command Line Editing, Prev: GDB Bugs, Up: Top + +Formatting Documentation +************************ + +The GDB 4 release includes an already-formatted reference card, ready +for printing with PostScript or Ghostscript, in the `gdb' subdirectory +of the main source directory(1). If you can use PostScript or +Ghostscript with your printer, you can print the reference card +immediately with `refcard.ps'. + + The release also includes the source for the reference card. You +can format it, using TeX, by typing: + + make refcard.dvi + + The GDB reference card is designed to print in "landscape" mode on +US "letter" size paper; that is, on a sheet 11 inches wide by 8.5 inches +high. You will need to specify this form of printing as an option to +your DVI output program. + + All the documentation for GDB comes as part of the machine-readable +distribution. The documentation is written in Texinfo format, which is +a documentation system that uses a single source file to produce both +on-line information and a printed manual. You can use one of the Info +formatting commands to create the on-line version of the documentation +and TeX (or `texi2roff') to typeset the printed version. + + GDB includes an already formatted copy of the on-line Info version +of this manual in the `gdb' subdirectory. The main Info file is +`gdb-6.1.1/gdb/gdb.info', and it refers to subordinate files matching +`gdb.info*' in the same directory. If necessary, you can print out +these files, or read them with any editor; but they are easier to read +using the `info' subsystem in GNU Emacs or the standalone `info' +program, available as part of the GNU Texinfo distribution. + + If you want to format these Info files yourself, you need one of the +Info formatting programs, such as `texinfo-format-buffer' or `makeinfo'. + + If you have `makeinfo' installed, and are in the top level GDB +source directory (`gdb-6.1.1', in the case of version 6.1.1), you can +make the Info file by typing: + + cd gdb + make gdb.info + + If you want to typeset and print copies of this manual, you need TeX, +a program to print its DVI output files, and `texinfo.tex', the Texinfo +definitions file. + + TeX is a typesetting program; it does not print files directly, but +produces output files called DVI files. To print a typeset document, +you need a program to print DVI files. If your system has TeX +installed, chances are it has such a program. The precise command to +use depends on your system; `lpr -d' is common; another (for PostScript +devices) is `dvips'. The DVI print command may require a file name +without any extension or a `.dvi' extension. + + TeX also requires a macro definitions file called `texinfo.tex'. +This file tells TeX how to typeset a document written in Texinfo +format. On its own, TeX cannot either read or typeset a Texinfo file. +`texinfo.tex' is distributed with GDB and is located in the +`gdb-VERSION-NUMBER/texinfo' directory. + + If you have TeX and a DVI printer program installed, you can typeset +and print this manual. First switch to the the `gdb' subdirectory of +the main source directory (for example, to `gdb-6.1.1/gdb') and type: + + make gdb.dvi + + Then give `gdb.dvi' to your DVI printing program. + + ---------- Footnotes ---------- + + (1) In `gdb-6.1.1/gdb/refcard.ps' of the version 6.1.1 release. + + +File: gdb.info, Node: Installing GDB, Next: Maintenance Commands, Prev: Using History Interactively, Up: Top + +Installing GDB +************** + +GDB comes with a `configure' script that automates the process of +preparing GDB for installation; you can then use `make' to build the +`gdb' program. + + The GDB distribution includes all the source code you need for GDB +in a single directory, whose name is usually composed by appending the +version number to `gdb'. + + For example, the GDB version 6.1.1 distribution is in the +`gdb-6.1.1' directory. That directory contains: + +`gdb-6.1.1/configure (and supporting files)' + script for configuring GDB and all its supporting libraries + +`gdb-6.1.1/gdb' + the source specific to GDB itself + +`gdb-6.1.1/bfd' + source for the Binary File Descriptor library + +`gdb-6.1.1/include' + GNU include files + +`gdb-6.1.1/libiberty' + source for the `-liberty' free software library + +`gdb-6.1.1/opcodes' + source for the library of opcode tables and disassemblers + +`gdb-6.1.1/readline' + source for the GNU command-line interface + +`gdb-6.1.1/glob' + source for the GNU filename pattern-matching subroutine + +`gdb-6.1.1/mmalloc' + source for the GNU memory-mapped malloc package + + The simplest way to configure and build GDB is to run `configure' +from the `gdb-VERSION-NUMBER' source directory, which in this example +is the `gdb-6.1.1' directory. + + First switch to the `gdb-VERSION-NUMBER' source directory if you are +not already in it; then run `configure'. Pass the identifier for the +platform on which GDB will run as an argument. + + For example: + + cd gdb-6.1.1 + ./configure HOST + make + +where HOST is an identifier such as `sun4' or `decstation', that +identifies the platform where GDB will run. (You can often leave off +HOST; `configure' tries to guess the correct value by examining your +system.) + + Running `configure HOST' and then running `make' builds the `bfd', +`readline', `mmalloc', and `libiberty' libraries, then `gdb' itself. +The configured source files, and the binaries, are left in the +corresponding source directories. + + `configure' is a Bourne-shell (`/bin/sh') script; if your system +does not recognize this automatically when you run a different shell, +you may need to run `sh' on it explicitly: + + sh configure HOST + + If you run `configure' from a directory that contains source +directories for multiple libraries or programs, such as the `gdb-6.1.1' +source directory for version 6.1.1, `configure' creates configuration +files for every directory level underneath (unless you tell it not to, +with the `--norecursion' option). + + You should run the `configure' script from the top directory in the +source tree, the `gdb-VERSION-NUMBER' directory. If you run +`configure' from one of the subdirectories, you will configure only +that subdirectory. That is usually not what you want. In particular, +if you run the first `configure' from the `gdb' subdirectory of the +`gdb-VERSION-NUMBER' directory, you will omit the configuration of +`bfd', `readline', and other sibling directories of the `gdb' +subdirectory. This leads to build errors about missing include files +such as `bfd/bfd.h'. + + You can install `gdb' anywhere; it has no hardwired paths. However, +you should make sure that the shell on your path (named by the `SHELL' +environment variable) is publicly readable. Remember that GDB uses the +shell to start your program--some systems refuse to let GDB debug child +processes whose programs are not readable. + +* Menu: + +* Separate Objdir:: Compiling GDB in another directory +* Config Names:: Specifying names for hosts and targets +* Configure Options:: Summary of options for configure + + +File: gdb.info, Node: Separate Objdir, Next: Config Names, Up: Installing GDB + +Compiling GDB in another directory +================================== + +If you want to run GDB versions for several host or target machines, +you need a different `gdb' compiled for each combination of host and +target. `configure' is designed to make this easy by allowing you to +generate each configuration in a separate subdirectory, rather than in +the source directory. If your `make' program handles the `VPATH' +feature (GNU `make' does), running `make' in each of these directories +builds the `gdb' program specified there. + + To build `gdb' in a separate directory, run `configure' with the +`--srcdir' option to specify where to find the source. (You also need +to specify a path to find `configure' itself from your working +directory. If the path to `configure' would be the same as the +argument to `--srcdir', you can leave out the `--srcdir' option; it is +assumed.) + + For example, with version 6.1.1, you can build GDB in a separate +directory for a Sun 4 like this: + + cd gdb-6.1.1 + mkdir ../gdb-sun4 + cd ../gdb-sun4 + ../gdb-6.1.1/configure sun4 + make + + When `configure' builds a configuration using a remote source +directory, it creates a tree for the binaries with the same structure +(and using the same names) as the tree under the source directory. In +the example, you'd find the Sun 4 library `libiberty.a' in the +directory `gdb-sun4/libiberty', and GDB itself in `gdb-sun4/gdb'. + + Make sure that your path to the `configure' script has just one +instance of `gdb' in it. If your path to `configure' looks like +`../gdb-6.1.1/gdb/configure', you are configuring only one subdirectory +of GDB, not the whole package. This leads to build errors about +missing include files such as `bfd/bfd.h'. + + One popular reason to build several GDB configurations in separate +directories is to configure GDB for cross-compiling (where GDB runs on +one machine--the "host"--while debugging programs that run on another +machine--the "target"). You specify a cross-debugging target by giving +the `--target=TARGET' option to `configure'. + + When you run `make' to build a program or library, you must run it +in a configured directory--whatever directory you were in when you +called `configure' (or one of its subdirectories). + + The `Makefile' that `configure' generates in each source directory +also runs recursively. If you type `make' in a source directory such +as `gdb-6.1.1' (or in a separate configured directory configured with +`--srcdir=DIRNAME/gdb-6.1.1'), you will build all the required +libraries, and then build GDB. + + When you have multiple hosts or targets configured in separate +directories, you can run `make' on them in parallel (for example, if +they are NFS-mounted on each of the hosts); they will not interfere +with each other. + + +File: gdb.info, Node: Config Names, Next: Configure Options, Prev: Separate Objdir, Up: Installing GDB + +Specifying names for hosts and targets +====================================== + +The specifications used for hosts and targets in the `configure' script +are based on a three-part naming scheme, but some short predefined +aliases are also supported. The full naming scheme encodes three pieces +of information in the following pattern: + + ARCHITECTURE-VENDOR-OS + + For example, you can use the alias `sun4' as a HOST argument, or as +the value for TARGET in a `--target=TARGET' option. The equivalent +full name is `sparc-sun-sunos4'. + + The `configure' script accompanying GDB does not provide any query +facility to list all supported host and target names or aliases. +`configure' calls the Bourne shell script `config.sub' to map +abbreviations to full names; you can read the script, if you wish, or +you can use it to test your guesses on abbreviations--for example: + + % sh config.sub i386-linux + i386-pc-linux-gnu + % sh config.sub alpha-linux + alpha-unknown-linux-gnu + % sh config.sub hp9k700 + hppa1.1-hp-hpux + % sh config.sub sun4 + sparc-sun-sunos4.1.1 + % sh config.sub sun3 + m68k-sun-sunos4.1.1 + % sh config.sub i986v + Invalid configuration `i986v': machine `i986v' not recognized + +`config.sub' is also distributed in the GDB source directory +(`gdb-6.1.1', for version 6.1.1). + + +File: gdb.info, Node: Configure Options, Prev: Config Names, Up: Installing GDB + +`configure' options +=================== + +Here is a summary of the `configure' options and arguments that are +most often useful for building GDB. `configure' also has several other +options not listed here. *note (configure.info)What Configure Does::, +for a full explanation of `configure'. + + configure [--help] + [--prefix=DIR] + [--exec-prefix=DIR] + [--srcdir=DIRNAME] + [--norecursion] [--rm] + [--target=TARGET] + HOST + +You may introduce options with a single `-' rather than `--' if you +prefer; but you may abbreviate option names if you use `--'. + +`--help' + Display a quick summary of how to invoke `configure'. + +`--prefix=DIR' + Configure the source to install programs and files under directory + `DIR'. + +`--exec-prefix=DIR' + Configure the source to install programs under directory `DIR'. + +`--srcdir=DIRNAME' + *Warning: using this option requires GNU `make', or another `make' + that implements the `VPATH' feature.* + Use this option to make configurations in directories separate + from the GDB source directories. Among other things, you can use + this to build (or maintain) several configurations simultaneously, + in separate directories. `configure' writes configuration + specific files in the current directory, but arranges for them to + use the source in the directory DIRNAME. `configure' creates + directories under the working directory in parallel to the source + directories below DIRNAME. + +`--norecursion' + Configure only the directory level where `configure' is executed; + do not propagate configuration to subdirectories. + +`--target=TARGET' + Configure GDB for cross-debugging programs running on the specified + TARGET. Without this option, GDB is configured to debug programs + that run on the same machine (HOST) as GDB itself. + + There is no convenient way to generate a list of all available + targets. + +`HOST ...' + Configure GDB to run on the specified HOST. + + There is no convenient way to generate a list of all available + hosts. + + There are many other options available as well, but they are +generally needed for special purposes only. + + +File: gdb.info, Node: Maintenance Commands, Next: Remote Protocol, Prev: Installing GDB, Up: Top + +Maintenance Commands +******************** + +In addition to commands intended for GDB users, GDB includes a number +of commands intended for GDB developers. These commands are provided +here for reference. + +`maint info breakpoints' + Using the same format as `info breakpoints', display both the + breakpoints you've set explicitly, and those GDB is using for + internal purposes. Internal breakpoints are shown with negative + breakpoint numbers. The type column identifies what kind of + breakpoint is shown: + + `breakpoint' + Normal, explicitly set breakpoint. + + `watchpoint' + Normal, explicitly set watchpoint. + + `longjmp' + Internal breakpoint, used to handle correctly stepping through + `longjmp' calls. + + `longjmp resume' + Internal breakpoint at the target of a `longjmp'. + + `until' + Temporary internal breakpoint used by the GDB `until' command. + + `finish' + Temporary internal breakpoint used by the GDB `finish' + command. + + `shlib events' + Shared library events. + + +`maint internal-error' +`maint internal-warning' + Cause GDB to call the internal function `internal_error' or + `internal_warning' and hence behave as though an internal error or + internal warning has been detected. In addition to reporting the + internal problem, these functions give the user the opportunity to + either quit GDB or create a core file of the current GDB session. + + (gdb) maint internal-error testing, 1, 2 + .../maint.c:121: internal-error: testing, 1, 2 + A problem internal to GDB has been detected. Further + debugging may prove unreliable. + Quit this debugging session? (y or n) n + Create a core file? (y or n) n + (gdb) + + Takes an optional parameter that is used as the text of the error + or warning message. + +`maint print dummy-frames' + Prints the contents of GDB's internal dummy-frame stack. + + (gdb) b add + ... + (gdb) print add(2,3) + Breakpoint 2, add (a=2, b=3) at ... + 58 return (a + b); + The program being debugged stopped while in a function called from GDB. + ... + (gdb) maint print dummy-frames + 0x1a57c80: pc=0x01014068 fp=0x0200bddc sp=0x0200bdd6 + top=0x0200bdd4 id={stack=0x200bddc,code=0x101405c} + call_lo=0x01014000 call_hi=0x01014001 + (gdb) + + Takes an optional file parameter. + +`maint print registers' +`maint print raw-registers' +`maint print cooked-registers' +`maint print register-groups' + Print GDB's internal register data structures. + + The command `maint print raw-registers' includes the contents of + the raw register cache; the command `maint print cooked-registers' + includes the (cooked) value of all registers; and the command + `maint print register-groups' includes the groups that each + register is a member of. *Note Registers: (gdbint)Registers. + + Takes an optional file parameter. + +`maint print reggroups' + Print GDB's internal register group data structures. + + Takes an optional file parameter. + + (gdb) maint print reggroups + Group Type + general user + float user + all user + vector user + system user + save internal + restore internal + +`maint set profile' +`maint show profile' + Control profiling of GDB. + + Profiling will be disabled until you use the `maint set profile' + command to enable it. When you enable profiling, the system will + begin collecting timing and execution count data; when you disable + profiling or exit GDB, the results will be written to a log file. + Remember that if you use profiling, GDB will overwrite the + profiling log file (often called `gmon.out'). If you have a + record of important profiling data in a `gmon.out' file, be sure + to move it to a safe location. + + Configuring with `--enable-profiling' arranges for GDB to be + compiled with the `-pg' compiler option. + + + +File: gdb.info, Node: Remote Protocol, Next: Agent Expressions, Prev: Maintenance Commands, Up: Top + +GDB Remote Serial Protocol +************************** + +* Menu: + +* Overview:: +* Packets:: +* Stop Reply Packets:: +* General Query Packets:: +* Register Packet Format:: +* Examples:: +* File-I/O remote protocol extension:: + + +File: gdb.info, Node: Overview, Next: Packets, Up: Remote Protocol + +Overview +======== + +There may be occasions when you need to know something about the +protocol--for example, if there is only one serial port to your target +machine, you might want your program to do something special if it +recognizes a packet meant for GDB. + + In the examples below, `->' and `<-' are used to indicate +transmitted and received data respectfully. + + All GDB commands and responses (other than acknowledgments) are sent +as a PACKET. A PACKET is introduced with the character `$', the actual +PACKET-DATA, and the terminating character `#' followed by a two-digit +CHECKSUM: + + `$'PACKET-DATA`#'CHECKSUM + +The two-digit CHECKSUM is computed as the modulo 256 sum of all +characters between the leading `$' and the trailing `#' (an eight bit +unsigned checksum). + + Implementors should note that prior to GDB 5.0 the protocol +specification also included an optional two-digit SEQUENCE-ID: + + `$'SEQUENCE-ID`:'PACKET-DATA`#'CHECKSUM + +That SEQUENCE-ID was appended to the acknowledgment. GDB has never +output SEQUENCE-IDs. Stubs that handle packets added since GDB 5.0 +must not accept SEQUENCE-ID. + + When either the host or the target machine receives a packet, the +first response expected is an acknowledgment: either `+' (to indicate +the package was received correctly) or `-' (to request retransmission): + + -> `$'PACKET-DATA`#'CHECKSUM + <- `+' + +The host (GDB) sends COMMANDs, and the target (the debugging stub +incorporated in your program) sends a RESPONSE. In the case of step +and continue COMMANDs, the response is only sent when the operation has +completed (the target has again stopped). + + PACKET-DATA consists of a sequence of characters with the exception +of `#' and `$' (see `X' packet for additional exceptions). + + Fields within the packet should be separated using `,' `;' or `:'. +Except where otherwise noted all numbers are represented in HEX with +leading zeros suppressed. + + Implementors should note that prior to GDB 5.0, the character `:' +could not appear as the third character in a packet (as it would +potentially conflict with the SEQUENCE-ID). + + Response DATA can be run-length encoded to save space. A `*' means +that the next character is an ASCII encoding giving a repeat count +which stands for that many repetitions of the character preceding the +`*'. The encoding is `n+29', yielding a printable character where `n +>=3' (which is where rle starts to win). The printable characters `$', +`#', `+' and `-' or with a numeric value greater than 126 should not be +used. + + So: + "`0* '" + +means the same as "0000". + + The error response returned for some packets includes a two character +error number. That number is not well defined. + + For any COMMAND not supported by the stub, an empty response +(`$#00') should be returned. That way it is possible to extend the +protocol. A newer GDB can tell if a packet is supported based on that +response. + + A stub is required to support the `g', `G', `m', `M', `c', and `s' +COMMANDs. All other COMMANDs are optional. + + +File: gdb.info, Node: Packets, Next: Stop Reply Packets, Prev: Overview, Up: Remote Protocol + +Packets +======= + +The following table provides a complete list of all currently defined +COMMANDs and their corresponding response DATA. + +`!' -- extended mode + Enable extended mode. In extended mode, the remote server is made + persistent. The `R' packet is used to restart the program being + debugged. + + Reply: + `OK' + The remote target both supports and has enabled extended mode. + +`?' -- last signal + Indicate the reason the target halted. The reply is the same as + for step and continue. + + Reply: *Note Stop Reply Packets::, for the reply specifications. + +`a' -- reserved + Reserved for future use. + +`A'ARGLEN`,'ARGNUM`,'ARG`,...' -- set program arguments *(reserved)* + Initialized `argv[]' array passed into program. ARGLEN specifies + the number of bytes in the hex encoded byte stream ARG. See + `gdbserver' for more details. + + Reply: + `OK' + + `ENN' + +`b'BAUD -- set baud *(deprecated)* + Change the serial line speed to BAUD. + + JTC: _When does the transport layer state change? When it's + received, or after the ACK is transmitted. In either case, there + are problems if the command or the acknowledgment packet is + dropped._ + + Stan: _If people really wanted to add something like this, and get + it working for the first time, they ought to modify ser-unix.c to + send some kind of out-of-band message to a specially-setup stub + and have the switch happen "in between" packets, so that from + remote protocol's point of view, nothing actually happened._ + +`B'ADDR,MODE -- set breakpoint *(deprecated)* + Set (MODE is `S') or clear (MODE is `C') a breakpoint at ADDR. + + This packet has been replaced by the `Z' and `z' packets (*note + insert breakpoint or watchpoint packet::). + +`c'ADDR -- continue + ADDR is address to resume. If ADDR is omitted, resume at current + address. + + Reply: *Note Stop Reply Packets::, for the reply specifications. + +`C'SIG`;'ADDR -- continue with signal + Continue with signal SIG (hex signal number). If `;'ADDR is + omitted, resume at same address. + + Reply: *Note Stop Reply Packets::, for the reply specifications. + +`d' -- toggle debug *(deprecated)* + Toggle debug flag. + +`D' -- detach + Detach GDB from the remote system. Sent to the remote target + before GDB disconnects via the `detach' command. + + Reply: + `_no response_' + GDB does not check for any response after sending this packet. + +`e' -- reserved + Reserved for future use. + +`E' -- reserved + Reserved for future use. + +`f' -- reserved + Reserved for future use. + +`F'RC`,'EE`,'CF`;'XX -- Reply to target's F packet. + This packet is send by GDB as reply to a `F' request packet sent + by the target. This is part of the File-I/O protocol extension. + *Note File-I/O remote protocol extension::, for the specification. + +`g' -- read registers + Read general registers. + + Reply: + `XX...' + Each byte of register data is described by two hex digits. + The bytes with the register are transmitted in target byte + order. The size of each register and their position within + the `g' PACKET are determined by the GDB internal macros + DEPRECATED_REGISTER_RAW_SIZE and REGISTER_NAME macros. The + specification of several standard `g' packets is specified + below. + + `ENN' + for an error. + +`G'XX... -- write regs + *Note read registers packet::, for a description of the XX... + data. + + Reply: + `OK' + for success + + `ENN' + for an error + +`h' -- reserved + Reserved for future use. + +`H'CT... -- set thread + Set thread for subsequent operations (`m', `M', `g', `G', et.al.). + C depends on the operation to be performed: it should be `c' for + step and continue operations, `g' for other operations. The + thread designator T... may be -1, meaning all the threads, a + thread number, or zero which means pick any thread. + + Reply: + `OK' + for success + + `ENN' + for an error + +`i'ADDR`,'NNN -- cycle step *(draft)* + Step the remote target by a single clock cycle. If `,'NNN is + present, cycle step NNN cycles. If ADDR is present, cycle step + starting at that address. + +`I' -- signal then cycle step *(reserved)* + *Note step with signal packet::. *Note cycle step packet::. + +`j' -- reserved + Reserved for future use. + +`J' -- reserved + Reserved for future use. + +`k' -- kill request + FIXME: _There is no description of how to operate when a specific + thread context has been selected (i.e. does 'k' kill only that + thread?)_. + +`K' -- reserved + Reserved for future use. + +`l' -- reserved + Reserved for future use. + +`L' -- reserved + Reserved for future use. + +`m'ADDR`,'LENGTH -- read memory + Read LENGTH bytes of memory starting at address ADDR. Neither GDB + nor the stub assume that sized memory transfers are assumed using + word aligned accesses. FIXME: _A word aligned memory transfer + mechanism is needed._ + + Reply: + `XX...' + XX... is mem contents. Can be fewer bytes than requested if + able to read only part of the data. Neither GDB nor the stub + assume that sized memory transfers are assumed using word + aligned accesses. FIXME: _A word aligned memory transfer + mechanism is needed._ + + `ENN' + NN is errno + +`M'ADDR,LENGTH`:'XX... -- write mem + Write LENGTH bytes of memory starting at address ADDR. XX... is + the data. + + Reply: + `OK' + for success + + `ENN' + for an error (this includes the case where only part of the + data was written). + +`n' -- reserved + Reserved for future use. + +`N' -- reserved + Reserved for future use. + +`o' -- reserved + Reserved for future use. + +`O' -- reserved + Reserved for future use. + +`p'N... -- read reg *(reserved)* + *Note write register packet::. + + Reply: + `R....' + The hex encoded value of the register in target byte order. + +`P'N...`='R... -- write register + Write register N... with value R..., which contains two hex digits + for each byte in the register (target byte order). + + Reply: + `OK' + for success + + `ENN' + for an error + +`q'QUERY -- general query + Request info about QUERY. In general GDB queries have a leading + upper case letter. Custom vendor queries should use a company + prefix (in lower case) ex: `qfsf.var'. QUERY may optionally be + followed by a `,' or `;' separated list. Stubs must ensure that + they match the full QUERY name. + + Reply: + `XX...' + Hex encoded data from query. The reply can not be empty. + + `ENN' + error reply + + `' + Indicating an unrecognized QUERY. + +`Q'VAR`='VAL -- general set + Set value of VAR to VAL. + + *Note general query packet::, for a discussion of naming + conventions. + +`r' -- reset *(deprecated)* + Reset the entire system. + +`R'XX -- remote restart + Restart the program being debugged. XX, while needed, is ignored. + This packet is only available in extended mode. + + Reply: + `_no reply_' + The `R' packet has no reply. + +`s'ADDR -- step + ADDR is address to resume. If ADDR is omitted, resume at same + address. + + Reply: *Note Stop Reply Packets::, for the reply specifications. + +`S'SIG`;'ADDR -- step with signal + Like `C' but step not continue. + + Reply: *Note Stop Reply Packets::, for the reply specifications. + +`t'ADDR`:'PP`,'MM -- search + Search backwards starting at address ADDR for a match with pattern + PP and mask MM. PP and MM are 4 bytes. ADDR must be at least 3 + digits. + +`T'XX -- thread alive + Find out if the thread XX is alive. + + Reply: + `OK' + thread is still alive + + `ENN' + thread is dead + +`u' -- reserved + Reserved for future use. + +`U' -- reserved + Reserved for future use. + +`v' -- verbose packet prefix + Packets starting with `v' are identified by a multi-letter name, + up to the first `;' or `?' (or the end of the packet). + +`vCont'[;ACTION[`:'TID]]... -- extended resume + Resume the inferior. Different actions may be specified for each + thread. If an action is specified with no TID, then it is applied + to any threads that don't have a specific action specified; if no + default action is specified then other threads should remain + stopped. Specifying multiple default actions is an error; + specifying no actions is also an error. Thread IDs are specified + in hexadecimal. Currently supported actions are: + + `c' + Continue. + + `CSIG' + Continue with signal SIG. SIG should be two hex digits. + + `s' + Step. + + `SSIG' + Step with signal SIG. SIG should be two hex digits. + + The optional ADDR argument normally associated with these packets + is not supported in `vCont'. + + Reply: *Note Stop Reply Packets::, for the reply specifications. + +`vCont?' -- extended resume query + Query support for the `vCont' packet. + + Reply: + ``vCont'[;ACTION]...' + The `vCont' packet is supported. Each ACTION is a supported + command in the `vCont' packet. + + `' + The `vCont' packet is not supported. + +`V' -- reserved + Reserved for future use. + +`w' -- reserved + Reserved for future use. + +`W' -- reserved + Reserved for future use. + +`x' -- reserved + Reserved for future use. + +`X'ADDR`,'LENGTH:XX... -- write mem (binary) + ADDR is address, LENGTH is number of bytes, XX... is binary data. + The characters `$', `#', and `0x7d' are escaped using `0x7d'. + + Reply: + `OK' + for success + + `ENN' + for an error + +`y' -- reserved + Reserved for future use. + +`Y' reserved + Reserved for future use. + +`z'TYPE`,'ADDR`,'LENGTH -- remove breakpoint or watchpoint *(draft)* +`Z'TYPE`,'ADDR`,'LENGTH -- insert breakpoint or watchpoint *(draft)* + Insert (`Z') or remove (`z') a TYPE breakpoint or watchpoint + starting at address ADDRESS and covering the next LENGTH bytes. + + Each breakpoint and watchpoint packet TYPE is documented + separately. + + _Implementation notes: A remote target shall return an empty string + for an unrecognized breakpoint or watchpoint packet TYPE. A + remote target shall support either both or neither of a given + `Z'TYPE... and `z'TYPE... packet pair. To avoid potential + problems with duplicate packets, the operations should be + implemented in an idempotent way._ + +`z'`0'`,'ADDR`,'LENGTH -- remove memory breakpoint *(draft)* + +`Z'`0'`,'ADDR`,'LENGTH -- insert memory breakpoint *(draft)* + Insert (`Z0') or remove (`z0') a memory breakpoint at address + `addr' of size `length'. + + A memory breakpoint is implemented by replacing the instruction at + ADDR with a software breakpoint or trap instruction. The `length' + is used by targets that indicates the size of the breakpoint (in + bytes) that should be inserted (e.g., the ARM and MIPS can insert + either a 2 or 4 byte breakpoint). + + _Implementation note: It is possible for a target to copy or move + code that contains memory breakpoints (e.g., when implementing + overlays). The behavior of this packet, in the presence of such a + target, is not defined._ + + Reply: + `OK' + success + + `' + not supported + + `ENN' + for an error + +`z'`1'`,'ADDR`,'LENGTH -- remove hardware breakpoint *(draft)* + +`Z'`1'`,'ADDR`,'LENGTH -- insert hardware breakpoint *(draft)* + Insert (`Z1') or remove (`z1') a hardware breakpoint at address + `addr' of size `length'. + + A hardware breakpoint is implemented using a mechanism that is not + dependant on being able to modify the target's memory. + + _Implementation note: A hardware breakpoint is not affected by code + movement._ + + Reply: + `OK' + success + + `' + not supported + + `ENN' + for an error + +`z'`2'`,'ADDR`,'LENGTH -- remove write watchpoint *(draft)* + +`Z'`2'`,'ADDR`,'LENGTH -- insert write watchpoint *(draft)* + Insert (`Z2') or remove (`z2') a write watchpoint. + + Reply: + `OK' + success + + `' + not supported + + `ENN' + for an error + +`z'`3'`,'ADDR`,'LENGTH -- remove read watchpoint *(draft)* + +`Z'`3'`,'ADDR`,'LENGTH -- insert read watchpoint *(draft)* + Insert (`Z3') or remove (`z3') a read watchpoint. + + Reply: + `OK' + success + + `' + not supported + + `ENN' + for an error + +`z'`4'`,'ADDR`,'LENGTH -- remove access watchpoint *(draft)* + +`Z'`4'`,'ADDR`,'LENGTH -- insert access watchpoint *(draft)* + Insert (`Z4') or remove (`z4') an access watchpoint. + + Reply: + `OK' + success + + `' + not supported + + `ENN' + for an error + + + +File: gdb.info, Node: Stop Reply Packets, Next: General Query Packets, Prev: Packets, Up: Remote Protocol + +Stop Reply Packets +================== + +The `C', `c', `S', `s' and `?' packets can receive any of the below as +a reply. In the case of the `C', `c', `S' and `s' packets, that reply +is only returned when the target halts. In the below the exact meaning +of `signal number' is poorly defined. In general one of the UNIX +signal numbering conventions is used. + +`SAA' + AA is the signal number + +``T'AAN...`:'R...`;'N...`:'R...`;'N...`:'R...`;'' + AA = two hex digit signal number; N... = register number (hex), + R... = target byte ordered register contents, size defined by + `DEPRECATED_REGISTER_RAW_SIZE'; N... = `thread', R... = thread + process ID, this is a hex integer; N... = (`watch' | `rwatch' | + `awatch', R... = data address, this is a hex integer; N... = other + string not starting with valid hex digit. GDB should ignore this + N..., R... pair and go on to the next. This way we can extend the + protocol. + +`WAA' + The process exited, and AA is the exit status. This is only + applicable to certain targets. + +`XAA' + The process terminated with signal AA. + +`OXX...' + XX... is hex encoding of ASCII data. This can happen at any time + while the program is running and the debugger should continue to + wait for `W', `T', etc. + +`FCALL-ID`,'PARAMETER...' + CALL-ID is the identifier which says which host system call should + be called. This is just the name of the function. Translation + into the correct system call is only applicable as it's defined in + GDB. *Note File-I/O remote protocol extension::, for a list of + implemented system calls. + + PARAMETER... is a list of parameters as defined for this very + system call. + + The target replies with this packet when it expects GDB to call a + host system call on behalf of the target. GDB replies with an + appropriate `F' packet and keeps up waiting for the next reply + packet from the target. The latest `C', `c', `S' or `s' action is + expected to be continued. *Note File-I/O remote protocol + extension::, for more details. + + + +File: gdb.info, Node: General Query Packets, Next: Register Packet Format, Prev: Stop Reply Packets, Up: Remote Protocol + +General Query Packets +===================== + +The following set and query packets have already been defined. + +`q'`C' -- current thread + Return the current thread id. + + Reply: + ``QC'PID' + Where PID is a HEX encoded 16 bit process id. + + `*' + Any other reply implies the old pid. + +`q'`fThreadInfo' - all thread ids + `q'`sThreadInfo' + + Obtain a list of active thread ids from the target (OS). Since + there may be too many active threads to fit into one reply packet, + this query works iteratively: it may require more than one + query/reply sequence to obtain the entire list of threads. The + first query of the sequence will be the `qf'`ThreadInfo' query; + subsequent queries in the sequence will be the `qs'`ThreadInfo' + query. + + NOTE: replaces the `qL' query (see below). + + Reply: + ``m'ID' + A single thread id + + ``m'ID,ID...' + a comma-separated list of thread ids + + ``l'' + (lower case 'el') denotes end of list. + + In response to each query, the target will reply with a list of + one or more thread ids, in big-endian hex, separated by commas. + GDB will respond to each reply with a request for more thread ids + (using the `qs' form of the query), until the target responds with + `l' (lower-case el, for `'last''). + +`q'`ThreadExtraInfo'`,'ID -- extra thread info + Where ID is a thread-id in big-endian hex. Obtain a printable + string description of a thread's attributes from the target OS. + This string may contain anything that the target OS thinks is + interesting for GDB to tell the user about the thread. The string + is displayed in GDB's `info threads' display. Some examples of + possible thread extra info strings are "Runnable", or "Blocked on + Mutex". + + Reply: + `XX...' + Where XX... is a hex encoding of ASCII data, comprising the + printable string containing the extra information about the + thread's attributes. + +`q'`L'STARTFLAGTHREADCOUNTNEXTTHREAD -- query LIST or THREADLIST *(deprecated)* + Obtain thread information from RTOS. Where: STARTFLAG (one hex + digit) is one to indicate the first query and zero to indicate a + subsequent query; THREADCOUNT (two hex digits) is the maximum + number of threads the response packet can contain; and NEXTTHREAD + (eight hex digits), for subsequent queries (STARTFLAG is zero), is + returned in the response as ARGTHREAD. + + NOTE: this query is replaced by the `q'`fThreadInfo' query (see + above). + + Reply: + ``q'`M'COUNTDONEARGTHREADTHREAD...' + Where: COUNT (two hex digits) is the number of threads being + returned; DONE (one hex digit) is zero to indicate more + threads and one indicates no further threads; ARGTHREADID + (eight hex digits) is NEXTTHREAD from the request packet; + THREAD... is a sequence of thread IDs from the target. + THREADID (eight hex digits). See + `remote.c:parse_threadlist_response()'. + +`q'`CRC:'ADDR`,'LENGTH -- compute CRC of memory block + Reply: + ``E'NN' + An error (such as memory fault) + + ``C'CRC32' + A 32 bit cyclic redundancy check of the specified memory + region. + +`q'`Offsets' -- query sect offs + Get section offsets that the target used when re-locating the + downloaded image. _Note: while a `Bss' offset is included in the + response, GDB ignores this and instead applies the `Data' offset + to the `Bss' section._ + + Reply: + ``Text='XXX`;Data='YYY`;Bss='ZZZ' + +`q'`P'MODETHREADID -- thread info request + Returns information on THREADID. Where: MODE is a hex encoded 32 + bit mode; THREADID is a hex encoded 64 bit thread ID. + + Reply: + `*' + + See `remote.c:remote_unpack_thread_info_response()'. + +`q'`Rcmd,'COMMAND -- remote command + COMMAND (hex encoded) is passed to the local interpreter for + execution. Invalid commands should be reported using the output + string. Before the final result packet, the target may also + respond with a number of intermediate `O'OUTPUT console output + packets. _Implementors should note that providing access to a + stubs's interpreter may have security implications_. + + Reply: + `OK' + A command response with no output. + + `OUTPUT' + A command response with the hex encoded output string OUTPUT. + + ``E'NN' + Indicate a badly formed request. + + ``'' + When `q'`Rcmd' is not recognized. + +`qSymbol::' -- symbol lookup + Notify the target that GDB is prepared to serve symbol lookup + requests. Accept requests from the target for the values of + symbols. + + Reply: + ``OK'' + The target does not need to look up any (more) symbols. + + ``qSymbol:'SYM_NAME' + The target requests the value of symbol SYM_NAME (hex + encoded). GDB may provide the value by using the + `qSymbol:'SYM_VALUE:SYM_NAME message, described below. + +`qSymbol:'SYM_VALUE:SYM_NAME -- symbol value + Set the value of SYM_NAME to SYM_VALUE. + + SYM_NAME (hex encoded) is the name of a symbol whose value the + target has previously requested. + + SYM_VALUE (hex) is the value for symbol SYM_NAME. If GDB cannot + supply a value for SYM_NAME, then this field will be empty. + + Reply: + ``OK'' + The target does not need to look up any (more) symbols. + + ``qSymbol:'SYM_NAME' + The target requests the value of a new symbol SYM_NAME (hex + encoded). GDB will continue to supply the values of symbols + (if available), until the target ceases to request them. + +`qPart':OBJECT:`read':ANNEX:OFFSET,LENGTH -- read special data + Read uninterpreted bytes from the target's special data area + identified by the keyword `object'. Request LENGTH bytes starting + at OFFSET bytes into the data. The content and encoding of ANNEX + is specific to the object; it can supply additional details about + what data to access. + + Here are the specific requests of this form defined so far. All + ``qPart':OBJECT:`read':...' requests use the same reply formats, + listed below. + + `qPart':`auxv':`read'::OFFSET,LENGTH + Access the target's "auxiliary vector". *Note Auxiliary + Vector::. Note ANNEX must be empty. + + Reply: + `OK' + The OFFSET in the request is at the end of the data. There + is no more data to be read. + + XX... + Hex encoded data bytes read. This may be fewer bytes than + the LENGTH in the request. + + `E00' + The request was malformed, or ANNEX was invalid. + + `E'NN + The offset was invalid, or there was an error encountered + reading the data. NN is a hex-encoded `errno' value. + + `""' (empty) + An empty reply indicates the OBJECT or ANNEX string was not + recognized by the stub. + +`qPart':OBJECT:`write':ANNEX:OFFSET:DATA... + Write uninterpreted bytes into the target's special data area + identified by the keyword `object', starting at OFFSET bytes into + the data. DATA... is the hex-encoded data to be written. The + content and encoding of ANNEX is specific to the object; it can + supply additional details about what data to access. + + No requests of this form are presently in use. This specification + serves as a placeholder to document the common format that new + specific request specifications ought to use. + + Reply: + NN + NN (hex encoded) is the number of bytes written. This may be + fewer bytes than supplied in the request. + + `E00' + The request was malformed, or ANNEX was invalid. + + `E'NN + The offset was invalid, or there was an error encountered + writing the data. NN is a hex-encoded `errno' value. + + `""' (empty) + An empty reply indicates the OBJECT or ANNEX string was not + recognized by the stub, or that the object does not support + writing. + +`qPart':OBJECT:OPERATION:... + Requests of this form may be added in the future. When a stub does + not recognize the OBJECT keyword, or its support for OBJECT does + not recognize the OPERATION keyword, the stub must respond with an + empty packet. + + +File: gdb.info, Node: Register Packet Format, Next: Examples, Prev: General Query Packets, Up: Remote Protocol + +Register Packet Format +====================== + +The following `g'/`G' packets have previously been defined. In the +below, some thirty-two bit registers are transferred as sixty-four +bits. Those registers should be zero/sign extended (which?) to fill +the space allocated. Register bytes are transfered in target byte +order. The two nibbles within a register byte are transfered +most-significant - least-significant. + +MIPS32 + All registers are transfered as thirty-two bit quantities in the + order: 32 general-purpose; sr; lo; hi; bad; cause; pc; 32 + floating-point registers; fsr; fir; fp. + +MIPS64 + All registers are transfered as sixty-four bit quantities + (including thirty-two bit registers such as `sr'). The ordering + is the same as `MIPS32'. + + + +File: gdb.info, Node: Examples, Next: File-I/O remote protocol extension, Prev: Register Packet Format, Up: Remote Protocol + +Examples +======== + +Example sequence of a target being re-started. Notice how the restart +does not get any direct output: + + -> `R00' + <- `+' + _target restarts_ + -> `?' + <- `+' + <- `T001:1234123412341234' + -> `+' + + Example sequence of a target being stepped by a single instruction: + + -> `G1445...' + <- `+' + -> `s' + <- `+' + _time passes_ + <- `T001:1234123412341234' + -> `+' + -> `g' + <- `+' + <- `1455...' + -> `+' + + +File: gdb.info, Node: File-I/O remote protocol extension, Prev: Examples, Up: Remote Protocol + +File-I/O remote protocol extension +================================== + +* Menu: + +* File-I/O Overview:: +* Protocol basics:: +* The F request packet:: +* The F reply packet:: +* Memory transfer:: +* The Ctrl-C message:: +* Console I/O:: +* The isatty call:: +* The system call:: +* List of supported calls:: +* Protocol specific representation of datatypes:: +* Constants:: +* File-I/O Examples:: + + +File: gdb.info, Node: File-I/O Overview, Next: Protocol basics, Up: File-I/O remote protocol extension + +File-I/O Overview +----------------- + +The File I/O remote protocol extension (short: File-I/O) allows the +target to use the hosts file system and console I/O when calling various +system calls. System calls on the target system are translated into a +remote protocol packet to the host system which then performs the needed +actions and returns with an adequate response packet to the target +system. This simulates file system operations even on targets that +lack file systems. + + The protocol is defined host- and target-system independent. It uses +it's own independent representation of datatypes and values. Both, GDB +and the target's GDB stub are responsible for translating the system +dependent values into the unified protocol values when data is +transmitted. + + The communication is synchronous. A system call is possible only +when GDB is waiting for the `C', `c', `S' or `s' packets. While GDB +handles the request for a system call, the target is stopped to allow +deterministic access to the target's memory. Therefore File-I/O is not +interuptible by target signals. It is possible to interrupt File-I/O +by a user interrupt (Ctrl-C), though. + + The target's request to perform a host system call does not finish +the latest `C', `c', `S' or `s' action. That means, after finishing +the system call, the target returns to continuing the previous activity +(continue, step). No additional continue or step request from GDB is +required. + + (gdb) continue + <- target requests 'system call X' + target is stopped, GDB executes system call + -> GDB returns result + ... target continues, GDB returns to wait for the target + <- target hits breakpoint and sends a Txx packet + + The protocol is only used for files on the host file system and for +I/O on the console. Character or block special devices, pipes, named +pipes or sockets or any other communication method on the host system +are not supported by this protocol. + + +File: gdb.info, Node: Protocol basics, Next: The F request packet, Prev: File-I/O Overview, Up: File-I/O remote protocol extension + +Protocol basics +--------------- + +The File-I/O protocol uses the `F' packet, as request as well as as +reply packet. Since a File-I/O system call can only occur when GDB is +waiting for the continuing or stepping target, the File-I/O request is +a reply that GDB has to expect as a result of a former `C', `c', `S' or +`s' packet. This `F' packet contains all information needed to allow +GDB to call the appropriate host system call: + + * A unique identifier for the requested system call. + + * All parameters to the system call. Pointers are given as addresses + in the target memory address space. Pointers to strings are given + as pointer/length pair. Numerical values are given as they are. + Numerical control values are given in a protocol specific + representation. + + + At that point GDB has to perform the following actions. + + * If parameter pointer values are given, which point to data needed + as input to a system call, GDB requests this data from the target + with a standard `m' packet request. This additional communication + has to be expected by the target implementation and is handled as + any other `m' packet. + + * GDB translates all value from protocol representation to host + representation as needed. Datatypes are coerced into the host + types. + + * GDB calls the system call + + * It then coerces datatypes back to protocol representation. + + * If pointer parameters in the request packet point to buffer space + in which a system call is expected to copy data to, the data is + transmitted to the target using a `M' or `X' packet. This packet + has to be expected by the target implementation and is handled as + any other `M' or `X' packet. + + + Eventually GDB replies with another `F' packet which contains all +necessary information for the target to continue. This at least +contains + + * Return value. + + * `errno', if has been changed by the system call. + + * "Ctrl-C" flag. + + + After having done the needed type and value coercion, the target +continues the latest continue or step action. + + +File: gdb.info, Node: The F request packet, Next: The F reply packet, Prev: Protocol basics, Up: File-I/O remote protocol extension + +The `F' request packet +---------------------- + +The `F' request packet has the following format: + + `F'CALL-ID`,'PARAMETER... + + CALL-ID is the identifier to indicate the host system call to be + called. This is just the name of the function. + + PARAMETER... are the parameters to the system call. + + + Parameters are hexadecimal integer values, either the real values in +case of scalar datatypes, as pointers to target buffer space in case of +compound datatypes and unspecified memory areas or as pointer/length +pairs in case of string parameters. These are appended to the call-id, +each separated from its predecessor by a comma. All values are +transmitted in ASCII string representation, pointer/length pairs +separated by a slash. + + +File: gdb.info, Node: The F reply packet, Next: Memory transfer, Prev: The F request packet, Up: File-I/O remote protocol extension + +The `F' reply packet +-------------------- + +The `F' reply packet has the following format: + + `F'RETCODE`,'ERRNO`,'CTRL-C FLAG`;'CALL SPECIFIC ATTACHMENT + + RETCODE is the return code of the system call as hexadecimal value. + + ERRNO is the errno set by the call, in protocol specific + representation. This parameter can be omitted if the call was + successful. + + CTRL-C FLAG is only send if the user requested a break. In this + case, ERRNO must be send as well, even if the call was successful. + The CTRL-C FLAG itself consists of the character 'C': + + F0,0,C + + or, if the call was interupted before the host call has been + performed: + + F-1,4,C + + assuming 4 is the protocol specific representation of `EINTR'. + + + +File: gdb.info, Node: Memory transfer, Next: The Ctrl-C message, Prev: The F reply packet, Up: File-I/O remote protocol extension + +Memory transfer +--------------- + +Structured data which is transferred using a memory read or write as +e.g. a `struct stat' is expected to be in a protocol specific format +with all scalar multibyte datatypes being big endian. This should be +done by the target before the `F' packet is sent resp. by GDB before it +transfers memory to the target. Transferred pointers to structured +data should point to the already coerced data at any time. + + +File: gdb.info, Node: The Ctrl-C message, Next: Console I/O, Prev: Memory transfer, Up: File-I/O remote protocol extension + +The Ctrl-C message +------------------ + +A special case is, if the CTRL-C FLAG is set in the GDB reply packet. +In this case the target should behave, as if it had gotten a break +message. The meaning for the target is "system call interupted by +`SIGINT'". Consequentially, the target should actually stop (as with a +break message) and return to GDB with a `T02' packet. In this case, +it's important for the target to know, in which state the system call +was interrupted. Since this action is by design not an atomic +operation, we have to differ between two cases: + + * The system call hasn't been performed on the host yet. + + * The system call on the host has been finished. + + + These two states can be distinguished by the target by the value of +the returned `errno'. If it's the protocol representation of `EINTR', +the system call hasn't been performed. This is equivalent to the +`EINTR' handling on POSIX systems. In any other case, the target may +presume that the system call has been finished -- successful or not -- +and should behave as if the break message arrived right after the +system call. + + GDB must behave reliable. If the system call has not been called +yet, GDB may send the `F' reply immediately, setting `EINTR' as `errno' +in the packet. If the system call on the host has been finished before +the user requests a break, the full action must be finshed by GDB. +This requires sending `M' or `X' packets as they fit. The `F' packet +may only be send when either nothing has happened or the full action +has been completed. + + +File: gdb.info, Node: Console I/O, Next: The isatty call, Prev: The Ctrl-C message, Up: File-I/O remote protocol extension + +Console I/O +----------- + +By default and if not explicitely closed by the target system, the file +descriptors 0, 1 and 2 are connected to the GDB console. Output on the +GDB console is handled as any other file output operation (`write(1, +...)' or `write(2, ...)'). Console input is handled by GDB so that +after the target read request from file descriptor 0 all following +typing is buffered until either one of the following conditions is met: + + * The user presses `Ctrl-C'. The behaviour is as explained above, + the `read' system call is treated as finished. + + * The user presses `Enter'. This is treated as end of input with a + trailing line feed. + + * The user presses `Ctrl-D'. This is treated as end of input. No + trailing character, especially no Ctrl-D is appended to the input. + + + If the user has typed more characters as fit in the buffer given to +the read call, the trailing characters are buffered in GDB until either +another `read(0, ...)' is requested by the target or debugging is +stopped on users request. + + +File: gdb.info, Node: The isatty call, Next: The system call, Prev: Console I/O, Up: File-I/O remote protocol extension + +The isatty(3) call +------------------ + +A special case in this protocol is the library call `isatty' which is +implemented as it's own call inside of this protocol. It returns 1 to +the target if the file descriptor given as parameter is attached to the +GDB console, 0 otherwise. Implementing through system calls would +require implementing `ioctl' and would be more complex than needed. + + +File: gdb.info, Node: The system call, Next: List of supported calls, Prev: The isatty call, Up: File-I/O remote protocol extension + +The system(3) call +------------------ + +The other special case in this protocol is the `system' call which is +implemented as it's own call, too. GDB is taking over the full task of +calling the necessary host calls to perform the `system' call. The +return value of `system' is simplified before it's returned to the +target. Basically, the only signal transmitted back is `EINTR' in case +the user pressed `Ctrl-C'. Otherwise the return value consists +entirely of the exit status of the called command. + + Due to security concerns, the `system' call is refused to be called +by GDB by default. The user has to allow this call explicitly by +entering + +``set remote system-call-allowed 1'' + + Disabling the `system' call is done by + +``set remote system-call-allowed 0'' + + The current setting is shown by typing + +``show remote system-call-allowed'' + + +File: gdb.info, Node: List of supported calls, Next: Protocol specific representation of datatypes, Prev: The system call, Up: File-I/O remote protocol extension + +List of supported calls +----------------------- + +* Menu: + +* open:: +* close:: +* read:: +* write:: +* lseek:: +* rename:: +* unlink:: +* stat/fstat:: +* gettimeofday:: +* isatty:: +* system:: + + +File: gdb.info, Node: open, Next: close, Up: List of supported calls + +open +.... + +Synopsis: + int open(const char *pathname, int flags); + int open(const char *pathname, int flags, mode_t mode); + +Request: + Fopen,pathptr/len,flags,mode + +`flags' is the bitwise or of the following values: + +`O_CREAT' + If the file does not exist it will be created. The host rules + apply as far as file ownership and time stamps are concerned. + +`O_EXCL' + When used with O_CREAT, if the file already exists it is an error + and open() fails. + +`O_TRUNC' + If the file already exists and the open mode allows writing + (O_RDWR or O_WRONLY is given) it will be truncated to length 0. + +`O_APPEND' + The file is opened in append mode. + +`O_RDONLY' + The file is opened for reading only. + +`O_WRONLY' + The file is opened for writing only. + +`O_RDWR' + The file is opened for reading and writing. + + Each other bit is silently ignored. + + +`mode' is the bitwise or of the following values: + +`S_IRUSR' + User has read permission. + +`S_IWUSR' + User has write permission. + +`S_IRGRP' + Group has read permission. + +`S_IWGRP' + Group has write permission. + +`S_IROTH' + Others have read permission. + +`S_IWOTH' + Others have write permission. + + Each other bit is silently ignored. + + +Return value: + open returns the new file descriptor or -1 if an error + occured. + +Errors: + + +`EEXIST' + pathname already exists and O_CREAT and O_EXCL were used. + +`EISDIR' + pathname refers to a directory. + +`EACCES' + The requested access is not allowed. + +`ENAMETOOLONG' + pathname was too long. + +`ENOENT' + A directory component in pathname does not exist. + +`ENODEV' + pathname refers to a device, pipe, named pipe or socket. + +`EROFS' + pathname refers to a file on a read-only filesystem and write + access was requested. + +`EFAULT' + pathname is an invalid pointer value. + +`ENOSPC' + No space on device to create the file. + +`EMFILE' + The process already has the maximum number of files open. + +`ENFILE' + The limit on the total number of files open on the system has been + reached. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: close, Next: read, Prev: open, Up: List of supported calls + +close +..... + +Synopsis: + int close(int fd); + +Request: + Fclose,fd + +Return value: + close returns zero on success, or -1 if an error occurred. + +Errors: + + +`EBADF' + fd isn't a valid open file descriptor. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: read, Next: write, Prev: close, Up: List of supported calls + +read +.... + +Synopsis: + int read(int fd, void *buf, unsigned int count); + +Request: + Fread,fd,bufptr,count + +Return value: + On success, the number of bytes read is returned. + Zero indicates end of file. If count is zero, read + returns zero as well. On error, -1 is returned. + +Errors: + + +`EBADF' + fd is not a valid file descriptor or is not open for reading. + +`EFAULT' + buf is an invalid pointer value. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: write, Next: lseek, Prev: read, Up: List of supported calls + +write +..... + +Synopsis: + int write(int fd, const void *buf, unsigned int count); + +Request: + Fwrite,fd,bufptr,count + +Return value: + On success, the number of bytes written are returned. + Zero indicates nothing was written. On error, -1 + is returned. + +Errors: + + +`EBADF' + fd is not a valid file descriptor or is not open for writing. + +`EFAULT' + buf is an invalid pointer value. + +`EFBIG' + An attempt was made to write a file that exceeds the host specific + maximum file size allowed. + +`ENOSPC' + No space on device to write the data. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: lseek, Next: rename, Prev: write, Up: List of supported calls + +lseek +..... + +Synopsis: + long lseek (int fd, long offset, int flag); + +Request: + Flseek,fd,offset,flag + + `flag' is one of: + +`SEEK_SET' + The offset is set to offset bytes. + +`SEEK_CUR' + The offset is set to its current location plus offset bytes. + +`SEEK_END' + The offset is set to the size of the file plus offset bytes. + +Return value: + On success, the resulting unsigned offset in bytes from + the beginning of the file is returned. Otherwise, a + value of -1 is returned. + +Errors: + + +`EBADF' + fd is not a valid open file descriptor. + +`ESPIPE' + fd is associated with the GDB console. + +`EINVAL' + flag is not a proper value. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: rename, Next: unlink, Prev: lseek, Up: List of supported calls + +rename +...... + +Synopsis: + int rename(const char *oldpath, const char *newpath); + +Request: + Frename,oldpathptr/len,newpathptr/len + +Return value: + On success, zero is returned. On error, -1 is returned. + +Errors: + + +`EISDIR' + newpath is an existing directory, but oldpath is not a directory. + +`EEXIST' + newpath is a non-empty directory. + +`EBUSY' + oldpath or newpath is a directory that is in use by some process. + +`EINVAL' + An attempt was made to make a directory a subdirectory of itself. + +`ENOTDIR' + A component used as a directory in oldpath or new path is not a + directory. Or oldpath is a directory and newpath exists but is + not a directory. + +`EFAULT' + oldpathptr or newpathptr are invalid pointer values. + +`EACCES' + No access to the file or the path of the file. + +`ENAMETOOLONG' + oldpath or newpath was too long. + +`ENOENT' + A directory component in oldpath or newpath does not exist. + +`EROFS' + The file is on a read-only filesystem. + +`ENOSPC' + The device containing the file has no room for the new directory + entry. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: unlink, Next: stat/fstat, Prev: rename, Up: List of supported calls + +unlink +...... + +Synopsis: + int unlink(const char *pathname); + +Request: + Funlink,pathnameptr/len + +Return value: + On success, zero is returned. On error, -1 is returned. + +Errors: + + +`EACCES' + No access to the file or the path of the file. + +`EPERM' + The system does not allow unlinking of directories. + +`EBUSY' + The file pathname cannot be unlinked because it's being used by + another process. + +`EFAULT' + pathnameptr is an invalid pointer value. + +`ENAMETOOLONG' + pathname was too long. + +`ENOENT' + A directory component in pathname does not exist. + +`ENOTDIR' + A component of the path is not a directory. + +`EROFS' + The file is on a read-only filesystem. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: stat/fstat, Next: gettimeofday, Prev: unlink, Up: List of supported calls + +stat/fstat +.......... + +Synopsis: + int stat(const char *pathname, struct stat *buf); + int fstat(int fd, struct stat *buf); + +Request: + Fstat,pathnameptr/len,bufptr + Ffstat,fd,bufptr + +Return value: + On success, zero is returned. On error, -1 is returned. + +Errors: + + +`EBADF' + fd is not a valid open file. + +`ENOENT' + A directory component in pathname does not exist or the path is an + empty string. + +`ENOTDIR' + A component of the path is not a directory. + +`EFAULT' + pathnameptr is an invalid pointer value. + +`EACCES' + No access to the file or the path of the file. + +`ENAMETOOLONG' + pathname was too long. + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: gettimeofday, Next: isatty, Prev: stat/fstat, Up: List of supported calls + +gettimeofday +............ + +Synopsis: + int gettimeofday(struct timeval *tv, void *tz); + +Request: + Fgettimeofday,tvptr,tzptr + +Return value: + On success, 0 is returned, -1 otherwise. + +Errors: + + +`EINVAL' + tz is a non-NULL pointer. + +`EFAULT' + tvptr and/or tzptr is an invalid pointer value. + + +File: gdb.info, Node: isatty, Next: system, Prev: gettimeofday, Up: List of supported calls + +isatty +...... + +Synopsis: + int isatty(int fd); + +Request: + Fisatty,fd + +Return value: + Returns 1 if fd refers to the GDB console, 0 otherwise. + +Errors: + + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: system, Prev: isatty, Up: List of supported calls + +system +...... + +Synopsis: + int system(const char *command); + +Request: + Fsystem,commandptr/len + +Return value: + The value returned is -1 on error and the return status + of the command otherwise. Only the exit status of the + command is returned, which is extracted from the hosts + system return value by calling WEXITSTATUS(retval). + In case /bin/sh could not be executed, 127 is returned. + +Errors: + + +`EINTR' + The call was interrupted by the user. + + +File: gdb.info, Node: Protocol specific representation of datatypes, Next: Constants, Prev: List of supported calls, Up: File-I/O remote protocol extension + +Protocol specific representation of datatypes +--------------------------------------------- + +* Menu: + +* Integral datatypes:: +* Pointer values:: +* struct stat:: +* struct timeval:: + + +File: gdb.info, Node: Integral datatypes, Next: Pointer values, Up: Protocol specific representation of datatypes + +Integral datatypes +.................. + +The integral datatypes used in the system calls are + + int, unsigned int, long, unsigned long, mode_t and time_t + + `Int', `unsigned int', `mode_t' and `time_t' are implemented as 32 +bit values in this protocol. + + `Long' and `unsigned long' are implemented as 64 bit types. + + *Note Limits::, for corresponding MIN and MAX values (similar to +those in `limits.h') to allow range checking on host and target. + + `time_t' datatypes are defined as seconds since the Epoch. + + All integral datatypes transferred as part of a memory read or write +of a structured datatype e.g. a `struct stat' have to be given in big +endian byte order. + + +File: gdb.info, Node: Pointer values, Next: struct stat, Prev: Integral datatypes, Up: Protocol specific representation of datatypes + +Pointer values +.............. + +Pointers to target data are transmitted as they are. An exception is +made for pointers to buffers for which the length isn't transmitted as +part of the function call, namely strings. Strings are transmitted as +a pointer/length pair, both as hex values, e.g. + + `1aaf/12' + +which is a pointer to data of length 18 bytes at position 0x1aaf. The +length is defined as the full string length in bytes, including the +trailing null byte. Example: + + ``hello, world'' at address 0x123456 + +is transmitted as + + `123456/d' + + +File: gdb.info, Node: struct stat, Next: struct timeval, Prev: Pointer values, Up: Protocol specific representation of datatypes + +struct stat +........... + +The buffer of type struct stat used by the target and GDB is defined as +follows: + + struct stat { + unsigned int st_dev; /* device */ + unsigned int st_ino; /* inode */ + mode_t st_mode; /* protection */ + unsigned int st_nlink; /* number of hard links */ + unsigned int st_uid; /* user ID of owner */ + unsigned int st_gid; /* group ID of owner */ + unsigned int st_rdev; /* device type (if inode device) */ + unsigned long st_size; /* total size, in bytes */ + unsigned long st_blksize; /* blocksize for filesystem I/O */ + unsigned long st_blocks; /* number of blocks allocated */ + time_t st_atime; /* time of last access */ + time_t st_mtime; /* time of last modification */ + time_t st_ctime; /* time of last change */ + }; + + The integral datatypes are conforming to the definitions given in the +approriate section (see *Note Integral datatypes::, for details) so this +structure is of size 64 bytes. + + The values of several fields have a restricted meaning and/or range +of values. + + st_dev: 0 file + 1 console + + st_ino: No valid meaning for the target. Transmitted unchanged. + + st_mode: Valid mode bits are described in Appendix C. Any other + bits have currently no meaning for the target. + + st_uid: No valid meaning for the target. Transmitted unchanged. + + st_gid: No valid meaning for the target. Transmitted unchanged. + + st_rdev: No valid meaning for the target. Transmitted unchanged. + + st_atime, st_mtime, st_ctime: + These values have a host and file system dependent + accuracy. Especially on Windows hosts the file systems + don't support exact timing values. + + The target gets a struct stat of the above representation and is +responsible to coerce it to the target representation before continuing. + + Note that due to size differences between the host and target +representation of stat members, these members could eventually get +truncated on the target. + + +File: gdb.info, Node: struct timeval, Prev: struct stat, Up: Protocol specific representation of datatypes + +struct timeval +.............. + +The buffer of type struct timeval used by the target and GDB is defined +as follows: + + struct timeval { + time_t tv_sec; /* second */ + long tv_usec; /* microsecond */ + }; + + The integral datatypes are conforming to the definitions given in the +approriate section (see *Note Integral datatypes::, for details) so this +structure is of size 8 bytes. + + +File: gdb.info, Node: Constants, Next: File-I/O Examples, Prev: Protocol specific representation of datatypes, Up: File-I/O remote protocol extension + +Constants +--------- + +The following values are used for the constants inside of the protocol. +GDB and target are resposible to translate these values before and +after the call as needed. + +* Menu: + +* Open flags:: +* mode_t values:: +* Errno values:: +* Lseek flags:: +* Limits:: + + +File: gdb.info, Node: Open flags, Next: mode_t values, Up: Constants + +Open flags +.......... + +All values are given in hexadecimal representation. + + O_RDONLY 0x0 + O_WRONLY 0x1 + O_RDWR 0x2 + O_APPEND 0x8 + O_CREAT 0x200 + O_TRUNC 0x400 + O_EXCL 0x800 + + +File: gdb.info, Node: mode_t values, Next: Errno values, Prev: Open flags, Up: Constants + +mode_t values +............. + +All values are given in octal representation. + + S_IFREG 0100000 + S_IFDIR 040000 + S_IRUSR 0400 + S_IWUSR 0200 + S_IXUSR 0100 + S_IRGRP 040 + S_IWGRP 020 + S_IXGRP 010 + S_IROTH 04 + S_IWOTH 02 + S_IXOTH 01 + + +File: gdb.info, Node: Errno values, Next: Lseek flags, Prev: mode_t values, Up: Constants + +Errno values +............ + +All values are given in decimal representation. + + EPERM 1 + ENOENT 2 + EINTR 4 + EBADF 9 + EACCES 13 + EFAULT 14 + EBUSY 16 + EEXIST 17 + ENODEV 19 + ENOTDIR 20 + EISDIR 21 + EINVAL 22 + ENFILE 23 + EMFILE 24 + EFBIG 27 + ENOSPC 28 + ESPIPE 29 + EROFS 30 + ENAMETOOLONG 91 + EUNKNOWN 9999 + + EUNKNOWN is used as a fallback error value if a host system returns +any error value not in the list of supported error numbers. + + +File: gdb.info, Node: Lseek flags, Next: Limits, Prev: Errno values, Up: Constants + +Lseek flags +........... + + SEEK_SET 0 + SEEK_CUR 1 + SEEK_END 2 + + +File: gdb.info, Node: Limits, Prev: Lseek flags, Up: Constants + +Limits +...... + +All values are given in decimal representation. + + INT_MIN -2147483648 + INT_MAX 2147483647 + UINT_MAX 4294967295 + LONG_MIN -9223372036854775808 + LONG_MAX 9223372036854775807 + ULONG_MAX 18446744073709551615 + + +File: gdb.info, Node: File-I/O Examples, Prev: Constants, Up: File-I/O remote protocol extension + +File-I/O Examples +----------------- + +Example sequence of a write call, file descriptor 3, buffer is at target +address 0x1234, 6 bytes should be written: + + <- `Fwrite,3,1234,6' + _request memory read from target_ + -> `m1234,6' + <- XXXXXX + _return "6 bytes written"_ + -> `F6' + + Example sequence of a read call, file descriptor 3, buffer is at +target address 0x1234, 6 bytes should be read: + + <- `Fread,3,1234,6' + _request memory write to target_ + -> `X1234,6:XXXXXX' + _return "6 bytes read"_ + -> `F6' + + Example sequence of a read call, call fails on the host due to +invalid file descriptor (EBADF): + + <- `Fread,3,1234,6' + -> `F-1,9' + + Example sequence of a read call, user presses Ctrl-C before syscall +on host is called: + + <- `Fread,3,1234,6' + -> `F-1,4,C' + <- `T02' + + Example sequence of a read call, user presses Ctrl-C after syscall on +host is called: + + <- `Fread,3,1234,6' + -> `X1234,6:XXXXXX' + <- `T02' + + +File: gdb.info, Node: Agent Expressions, Next: Copying, Prev: Remote Protocol, Up: Top + +The GDB Agent Expression Mechanism +********************************** + +In some applications, it is not feasable for the debugger to interrupt +the program's execution long enough for the developer to learn anything +helpful about its behavior. If the program's correctness depends on its +real-time behavior, delays introduced by a debugger might cause the +program to fail, even when the code itself is correct. It is useful to +be able to observe the program's behavior without interrupting it. + + Using GDB's `trace' and `collect' commands, the user can specify +locations in the program, and arbitrary expressions to evaluate when +those locations are reached. Later, using the `tfind' command, she can +examine the values those expressions had when the program hit the trace +points. The expressions may also denote objects in memory -- +structures or arrays, for example -- whose values GDB should record; +while visiting a particular tracepoint, the user may inspect those +objects as if they were in memory at that moment. However, because GDB +records these values without interacting with the user, it can do so +quickly and unobtrusively, hopefully not disturbing the program's +behavior. + + When GDB is debugging a remote target, the GDB "agent" code running +on the target computes the values of the expressions itself. To avoid +having a full symbolic expression evaluator on the agent, GDB translates +expressions in the source language into a simpler bytecode language, and +then sends the bytecode to the agent; the agent then executes the +bytecode, and records the values for GDB to retrieve later. + + The bytecode language is simple; there are forty-odd opcodes, the +bulk of which are the usual vocabulary of C operands (addition, +subtraction, shifts, and so on) and various sizes of literals and +memory reference operations. The bytecode interpreter operates +strictly on machine-level values -- various sizes of integers and +floating point numbers -- and requires no information about types or +symbols; thus, the interpreter's internal data structures are simple, +and each bytecode requires only a few native machine instructions to +implement it. The interpreter is small, and strict limits on the +memory and time required to evaluate an expression are easy to +determine, making it suitable for use by the debugging agent in +real-time applications. + +* Menu: + +* General Bytecode Design:: Overview of the interpreter. +* Bytecode Descriptions:: What each one does. +* Using Agent Expressions:: How agent expressions fit into the big picture. +* Varying Target Capabilities:: How to discover what the target can do. +* Tracing on Symmetrix:: Special info for implementation on EMC's + boxes. +* Rationale:: Why we did it this way. + + +File: gdb.info, Node: General Bytecode Design, Next: Bytecode Descriptions, Up: Agent Expressions + +General Bytecode Design +======================= + +The agent represents bytecode expressions as an array of bytes. Each +instruction is one byte long (thus the term "bytecode"). Some +instructions are followed by operand bytes; for example, the `goto' +instruction is followed by a destination for the jump. + + The bytecode interpreter is a stack-based machine; most instructions +pop their operands off the stack, perform some operation, and push the +result back on the stack for the next instruction to consume. Each +element of the stack may contain either a integer or a floating point +value; these values are as many bits wide as the largest integer that +can be directly manipulated in the source language. Stack elements +carry no record of their type; bytecode could push a value as an +integer, then pop it as a floating point value. However, GDB will not +generate code which does this. In C, one might define the type of a +stack element as follows: + union agent_val { + LONGEST l; + DOUBLEST d; + }; + +where `LONGEST' and `DOUBLEST' are `typedef' names for the largest +integer and floating point types on the machine. + + By the time the bytecode interpreter reaches the end of the +expression, the value of the expression should be the only value left +on the stack. For tracing applications, `trace' bytecodes in the +expression will have recorded the necessary data, and the value on the +stack may be discarded. For other applications, like conditional +breakpoints, the value may be useful. + + Separate from the stack, the interpreter has two registers: +`pc' + The address of the next bytecode to execute. + +`start' + The address of the start of the bytecode expression, necessary for + interpreting the `goto' and `if_goto' instructions. + + +Neither of these registers is directly visible to the bytecode language +itself, but they are useful for defining the meanings of the bytecode +operations. + + There are no instructions to perform side effects on the running +program, or call the program's functions; we assume that these +expressions are only used for unobtrusive debugging, not for patching +the running code. + + Most bytecode instructions do not distinguish between the various +sizes of values, and operate on full-width values; the upper bits of the +values are simply ignored, since they do not usually make a difference +to the value computed. The exceptions to this rule are: +memory reference instructions (`ref'N) + There are distinct instructions to fetch different word sizes from + memory. Once on the stack, however, the values are treated as + full-size integers. They may need to be sign-extended; the `ext' + instruction exists for this purpose. + +the sign-extension instruction (`ext' N) + These clearly need to know which portion of their operand is to be + extended to occupy the full length of the word. + + + If the interpreter is unable to evaluate an expression completely for +some reason (a memory location is inaccessible, or a divisor is zero, +for example), we say that interpretation "terminates with an error". +This means that the problem is reported back to the interpreter's caller +in some helpful way. In general, code using agent expressions should +assume that they may attempt to divide by zero, fetch arbitrary memory +locations, and misbehave in other ways. + + Even complicated C expressions compile to a few bytecode +instructions; for example, the expression `x + y * z' would typically +produce code like the following, assuming that `x' and `y' live in +registers, and `z' is a global variable holding a 32-bit `int': + reg 1 + reg 2 + const32 address of z + ref32 + ext 32 + mul + add + end + + In detail, these mean: +`reg 1' + Push the value of register 1 (presumably holding `x') onto the + stack. + +`reg 2' + Push the value of register 2 (holding `y'). + +`const32 address of z' + Push the address of `z' onto the stack. + +`ref32' + Fetch a 32-bit word from the address at the top of the stack; + replace the address on the stack with the value. Thus, we replace + the address of `z' with `z''s value. + +`ext 32' + Sign-extend the value on the top of the stack from 32 bits to full + length. This is necessary because `z' is a signed integer. + +`mul' + Pop the top two numbers on the stack, multiply them, and push their + product. Now the top of the stack contains the value of the + expression `y * z'. + +`add' + Pop the top two numbers, add them, and push the sum. Now the top + of the stack contains the value of `x + y * z'. + +`end' + Stop executing; the value left on the stack top is the value to be + recorded. + + + +File: gdb.info, Node: Bytecode Descriptions, Next: Using Agent Expressions, Prev: General Bytecode Design, Up: Agent Expressions + +Bytecode Descriptions +===================== + +Each bytecode description has the following form: + +`add' (0x02): A B => A+B + Pop the top two stack items, A and B, as integers; push their sum, + as an integer. + + + In this example, `add' is the name of the bytecode, and `(0x02)' is +the one-byte value used to encode the bytecode, in hexidecimal. The +phrase "A B => A+B" shows the stack before and after the bytecode +executes. Beforehand, the stack must contain at least two values, A +and B; since the top of the stack is to the right, B is on the top of +the stack, and A is underneath it. After execution, the bytecode will +have popped A and B from the stack, and replaced them with a single +value, A+B. There may be other values on the stack below those shown, +but the bytecode affects only those shown. + + Here is another example: + +`const8' (0x22) N: => N + Push the 8-bit integer constant N on the stack, without sign + extension. + + + In this example, the bytecode `const8' takes an operand N directly +from the bytecode stream; the operand follows the `const8' bytecode +itself. We write any such operands immediately after the name of the +bytecode, before the colon, and describe the exact encoding of the +operand in the bytecode stream in the body of the bytecode description. + + For the `const8' bytecode, there are no stack items given before the +=>; this simply means that the bytecode consumes no values from the +stack. If a bytecode consumes no values, or produces no values, the +list on either side of the => may be empty. + + If a value is written as A, B, or N, then the bytecode treats it as +an integer. If a value is written is ADDR, then the bytecode treats it +as an address. + + We do not fully describe the floating point operations here; although +this design can be extended in a clean way to handle floating point +values, they are not of immediate interest to the customer, so we avoid +describing them, to save time. + +`float' (0x01): => + Prefix for floating-point bytecodes. Not implemented yet. + +`add' (0x02): A B => A+B + Pop two integers from the stack, and push their sum, as an integer. + +`sub' (0x03): A B => A-B + Pop two integers from the stack, subtract the top value from the + next-to-top value, and push the difference. + +`mul' (0x04): A B => A*B + Pop two integers from the stack, multiply them, and push the + product on the stack. Note that, when one multiplies two N-bit + numbers yielding another N-bit number, it is irrelevant whether the + numbers are signed or not; the results are the same. + +`div_signed' (0x05): A B => A/B + Pop two signed integers from the stack; divide the next-to-top + value by the top value, and push the quotient. If the divisor is + zero, terminate with an error. + +`div_unsigned' (0x06): A B => A/B + Pop two unsigned integers from the stack; divide the next-to-top + value by the top value, and push the quotient. If the divisor is + zero, terminate with an error. + +`rem_signed' (0x07): A B => A MODULO B + Pop two signed integers from the stack; divide the next-to-top + value by the top value, and push the remainder. If the divisor is + zero, terminate with an error. + +`rem_unsigned' (0x08): A B => A MODULO B + Pop two unsigned integers from the stack; divide the next-to-top + value by the top value, and push the remainder. If the divisor is + zero, terminate with an error. + +`lsh' (0x09): A B => A< `(signed)'A>>B + Pop two integers from the stack; let A be the next-to-top value, + and B be the top value. Shift A right by B bits, inserting copies + of the top bit at the high end, and push the result. + +`rsh_unsigned' (0x0b): A B => A>>B + Pop two integers from the stack; let A be the next-to-top value, + and B be the top value. Shift A right by B bits, inserting zero + bits at the high end, and push the result. + +`log_not' (0x0e): A => !A + Pop an integer from the stack; if it is zero, push the value one; + otherwise, push the value zero. + +`bit_and' (0x0f): A B => A&B + Pop two integers from the stack, and push their bitwise `and'. + +`bit_or' (0x10): A B => A|B + Pop two integers from the stack, and push their bitwise `or'. + +`bit_xor' (0x11): A B => A^B + Pop two integers from the stack, and push their bitwise + exclusive-`or'. + +`bit_not' (0x12): A => ~A + Pop an integer from the stack, and push its bitwise complement. + +`equal' (0x13): A B => A=B + Pop two integers from the stack; if they are equal, push the value + one; otherwise, push the value zero. + +`less_signed' (0x14): A B => A A A, sign-extended from N bits + Pop an unsigned value from the stack; treating it as an N-bit + twos-complement value, extend it to full length. This means that + all bits to the left of bit N-1 (where the least significant bit + is bit 0) are set to the value of bit N-1. Note that N may be + larger than or equal to the width of the stack elements of the + bytecode engine; in this case, the bytecode should have no effect. + + The number of source bits to preserve, N, is encoded as a single + byte unsigned integer following the `ext' bytecode. + +`zero_ext' (0x2a) N: A => A, zero-extended from N bits + Pop an unsigned value from the stack; zero all but the bottom N + bits. This means that all bits to the left of bit N-1 (where the + least significant bit is bit 0) are set to the value of bit N-1. + + The number of source bits to preserve, N, is encoded as a single + byte unsigned integer following the `zero_ext' bytecode. + +`ref8' (0x17): ADDR => A +`ref16' (0x18): ADDR => A +`ref32' (0x19): ADDR => A +`ref64' (0x1a): ADDR => A + Pop an address ADDR from the stack. For bytecode `ref'N, fetch an + N-bit value from ADDR, using the natural target endianness. Push + the fetched value as an unsigned integer. + + Note that ADDR may not be aligned in any particular way; the + `refN' bytecodes should operate correctly for any address. + + If attempting to access memory at ADDR would cause a processor + exception of some sort, terminate with an error. + +`ref_float' (0x1b): ADDR => D +`ref_double' (0x1c): ADDR => D +`ref_long_double' (0x1d): ADDR => D +`l_to_d' (0x1e): A => D +`d_to_l' (0x1f): D => A + Not implemented yet. + +`dup' (0x28): A => A A + Push another copy of the stack's top element. + +`swap' (0x2b): A B => B A + Exchange the top two items on the stack. + +`pop' (0x29): A => + Discard the top value on the stack. + +`if_goto' (0x20) OFFSET: A => + Pop an integer off the stack; if it is non-zero, branch to the + given offset in the bytecode string. Otherwise, continue to the + next instruction in the bytecode stream. In other words, if A is + non-zero, set the `pc' register to `start' + OFFSET. Thus, an + offset of zero denotes the beginning of the expression. + + The OFFSET is stored as a sixteen-bit unsigned value, stored + immediately following the `if_goto' bytecode. It is always stored + most significant byte first, regardless of the target's normal + endianness. The offset is not guaranteed to fall at any particular + alignment within the bytecode stream; thus, on machines where + fetching a 16-bit on an unaligned address raises an exception, you + should fetch the offset one byte at a time. + +`goto' (0x21) OFFSET: => + Branch unconditionally to OFFSET; in other words, set the `pc' + register to `start' + OFFSET. + + The offset is stored in the same way as for the `if_goto' bytecode. + +`const8' (0x22) N: => N +`const16' (0x23) N: => N +`const32' (0x24) N: => N +`const64' (0x25) N: => N + Push the integer constant N on the stack, without sign extension. + To produce a small negative value, push a small twos-complement + value, and then sign-extend it using the `ext' bytecode. + + The constant N is stored in the appropriate number of bytes + following the `const'B bytecode. The constant N is always stored + most significant byte first, regardless of the target's normal + endianness. The constant is not guaranteed to fall at any + particular alignment within the bytecode stream; thus, on machines + where fetching a 16-bit on an unaligned address raises an + exception, you should fetch N one byte at a time. + +`reg' (0x26) N: => A + Push the value of register number N, without sign extension. The + registers are numbered following GDB's conventions. + + The register number N is encoded as a 16-bit unsigned integer + immediately following the `reg' bytecode. It is always stored most + significant byte first, regardless of the target's normal + endianness. The register number is not guaranteed to fall at any + particular alignment within the bytecode stream; thus, on machines + where fetching a 16-bit on an unaligned address raises an + exception, you should fetch the register number one byte at a time. + +`trace' (0x0c): ADDR SIZE => + Record the contents of the SIZE bytes at ADDR in a trace buffer, + for later retrieval by GDB. + +`trace_quick' (0x0d) SIZE: ADDR => ADDR + Record the contents of the SIZE bytes at ADDR in a trace buffer, + for later retrieval by GDB. SIZE is a single byte unsigned + integer following the `trace' opcode. + + This bytecode is equivalent to the sequence `dup const8 SIZE + trace', but we provide it anyway to save space in bytecode strings. + +`trace16' (0x30) SIZE: ADDR => ADDR + Identical to trace_quick, except that SIZE is a 16-bit big-endian + unsigned integer, not a single byte. This should probably have + been named `trace_quick16', for consistency. + +`end' (0x27): => + Stop executing bytecode; the result should be the top element of + the stack. If the purpose of the expression was to compute an + lvalue or a range of memory, then the next-to-top of the stack is + the lvalue's address, and the top of the stack is the lvalue's + size, in bytes. + + + +File: gdb.info, Node: Using Agent Expressions, Next: Varying Target Capabilities, Prev: Bytecode Descriptions, Up: Agent Expressions + +Using Agent Expressions +======================= + +Here is a sketch of a full non-stop debugging cycle, showing how agent +expressions fit into the process. + + * The user selects trace points in the program's code at which GDB + should collect data. + + * The user specifies expressions to evaluate at each trace point. + These expressions may denote objects in memory, in which case + those objects' contents are recorded as the program runs, or + computed values, in which case the values themselves are recorded. + + * GDB transmits the tracepoints and their associated expressions to + the GDB agent, running on the debugging target. + + * The agent arranges to be notified when a trace point is hit. Note + that, on some systems, the target operating system is completely + responsible for collecting the data; see *Note Tracing on + Symmetrix::. + + * When execution on the target reaches a trace point, the agent + evaluates the expressions associated with that trace point, and + records the resulting values and memory ranges. + + * Later, when the user selects a given trace event and inspects the + objects and expression values recorded, GDB talks to the agent to + retrieve recorded data as necessary to meet the user's requests. + If the user asks to see an object whose contents have not been + recorded, GDB reports an error. + + + +File: gdb.info, Node: Varying Target Capabilities, Next: Tracing on Symmetrix, Prev: Using Agent Expressions, Up: Agent Expressions + +Varying Target Capabilities +=========================== + +Some targets don't support floating-point, and some would rather not +have to deal with `long long' operations. Also, different targets will +have different stack sizes, and different bytecode buffer lengths. + + Thus, GDB needs a way to ask the target about itself. We haven't +worked out the details yet, but in general, GDB should be able to send +the target a packet asking it to describe itself. The reply should be a +packet whose length is explicit, so we can add new information to the +packet in future revisions of the agent, without confusing old versions +of GDB, and it should contain a version number. It should contain at +least the following information: + + * whether floating point is supported + + * whether `long long' is supported + + * maximum acceptable size of bytecode stack + + * maximum acceptable length of bytecode expressions + + * which registers are actually available for collection + + * whether the target supports disabled tracepoints + + + +File: gdb.info, Node: Tracing on Symmetrix, Next: Rationale, Prev: Varying Target Capabilities, Up: Agent Expressions + +Tracing on Symmetrix +==================== + +This section documents the API used by the GDB agent to collect data on +Symmetrix systems. + + Cygnus originally implemented these tracing features to help EMC +Corporation debug their Symmetrix high-availability disk drives. The +Symmetrix application code already includes substantial tracing +facilities; the GDB agent for the Symmetrix system uses those facilities +for its own data collection, via the API described here. + + - Function: DTC_RESPONSE adbg_find_memory_in_frame (FRAME_DEF *FRAME, + char *ADDRESS, char **BUFFER, unsigned int *SIZE) + Search the trace frame FRAME for memory saved from ADDRESS. If + the memory is available, provide the address of the buffer holding + it; otherwise, provide the address of the next saved area. + + * If the memory at ADDRESS was saved in FRAME, set `*BUFFER' to + point to the buffer in which that memory was saved, set + `*SIZE' to the number of bytes from ADDRESS that are saved at + `*BUFFER', and return `OK_TARGET_RESPONSE'. (Clearly, in + this case, the function will always set `*SIZE' to a value + greater than zero.) + + * If FRAME does not record any memory at ADDRESS, set `*SIZE' + to the distance from ADDRESS to the start of the saved region + with the lowest address higher than ADDRESS. If there is no + memory saved from any higher address, set `*SIZE' to zero. + Return `NOT_FOUND_TARGET_RESPONSE'. + + These two possibilities allow the caller to either retrieve the + data, or walk the address space to the next saved area. + + This function allows the GDB agent to map the regions of memory +saved in a particular frame, and retrieve their contents efficiently. + + This function also provides a clean interface between the GDB agent +and the Symmetrix tracing structures, making it easier to adapt the GDB +agent to future versions of the Symmetrix system, and vice versa. This +function searches all data saved in FRAME, whether the data is there at +the request of a bytecode expression, or because it falls in one of the +format's memory ranges, or because it was saved from the top of the +stack. EMC can arbitrarily change and enhance the tracing mechanism, +but as long as this function works properly, all collected memory is +visible to GDB. + + The function itself is straightforward to implement. A single pass +over the trace frame's stack area, memory ranges, and expression blocks +can yield the address of the buffer (if the requested address was +saved), and also note the address of the next higher range of memory, +to be returned when the search fails. + + As an example, suppose the trace frame `f' has saved sixteen bytes +from address `0x8000' in a buffer at `0x1000', and thirty-two bytes +from address `0xc000' in a buffer at `0x1010'. Here are some sample +calls, and the effect each would have: + +`adbg_find_memory_in_frame (f, (char*) 0x8000, &buffer, &size)' + This would set `buffer' to `0x1000', set `size' to sixteen, and + return `OK_TARGET_RESPONSE', since `f' saves sixteen bytes from + `0x8000' at `0x1000'. + +`adbg_find_memory_in_frame (f, (char *) 0x8004, &buffer, &size)' + This would set `buffer' to `0x1004', set `size' to twelve, and + return `OK_TARGET_RESPONSE', since `f' saves the twelve bytes from + `0x8004' starting four bytes into the buffer at `0x1000'. This + shows that request addresses may fall in the middle of saved + areas; the function should return the address and size of the + remainder of the buffer. + +`adbg_find_memory_in_frame (f, (char *) 0x8100, &buffer, &size)' + This would set `size' to `0x3f00' and return + `NOT_FOUND_TARGET_RESPONSE', since there is no memory saved in `f' + from the address `0x8100', and the next memory available is at + `0x8100 + 0x3f00', or `0xc000'. This shows that request addresses + may fall outside of all saved memory ranges; the function should + indicate the next saved area, if any. + +`adbg_find_memory_in_frame (f, (char *) 0x7000, &buffer, &size)' + This would set `size' to `0x1000' and return + `NOT_FOUND_TARGET_RESPONSE', since the next saved memory is at + `0x7000 + 0x1000', or `0x8000'. + +`adbg_find_memory_in_frame (f, (char *) 0xf000, &buffer, &size)' + This would set `size' to zero, and return + `NOT_FOUND_TARGET_RESPONSE'. This shows how the function tells the + caller that no further memory ranges have been saved. + + + As another example, here is a function which will print out the +addresses of all memory saved in the trace frame `frame' on the +Symmetrix INLINES console: + void + print_frame_addresses (FRAME_DEF *frame) + { + char *addr; + char *buffer; + unsigned long size; + + addr = 0; + for (;;) + { + /* Either find out how much memory we have here, or discover + where the next saved region is. */ + if (adbg_find_memory_in_frame (frame, addr, &buffer, &size) + == OK_TARGET_RESPONSE) + printp ("saved %x to %x\n", addr, addr + size); + if (size == 0) + break; + addr += size; + } + } + + Note that there is not necessarily any connection between the order +in which the data is saved in the trace frame, and the order in which +`adbg_find_memory_in_frame' will return those memory ranges. The code +above will always print the saved memory regions in order of increasing +address, while the underlying frame structure might store the data in a +random order. + + [[This section should cover the rest of the Symmetrix functions the +stub relies upon, too.]] + + +File: gdb.info, Node: Rationale, Prev: Tracing on Symmetrix, Up: Agent Expressions + +Rationale +========= + +Some of the design decisions apparent above are arguable. + +What about stack overflow/underflow? + GDB should be able to query the target to discover its stack size. + Given that information, GDB can determine at translation time + whether a given expression will overflow the stack. But this spec + isn't about what kinds of error-checking GDB ought to do. + +Why are you doing everything in LONGEST? + Speed isn't important, but agent code size is; using LONGEST + brings in a bunch of support code to do things like division, etc. + So this is a serious concern. + + First, note that you don't need different bytecodes for different + operand sizes. You can generate code without _knowing_ how big the + stack elements actually are on the target. If the target only + supports 32-bit ints, and you don't send any 64-bit bytecodes, + everything just works. The observation here is that the MIPS and + the Alpha have only fixed-size registers, and you can still get + C's semantics even though most instructions only operate on + full-sized words. You just need to make sure everything is + properly sign-extended at the right times. So there is no need + for 32- and 64-bit variants of the bytecodes. Just implement + everything using the largest size you support. + + GDB should certainly check to see what sizes the target supports, + so the user can get an error earlier, rather than later. But this + information is not necessary for correctness. + +Why don't you have `>' or `<=' operators? + I want to keep the interpreter small, and we don't need them. We + can combine the `less_' opcodes with `log_not', and swap the order + of the operands, yielding all four asymmetrical comparison + operators. For example, `(x <= y)' is `! (x > y)', which is `! (y + < x)'. + +Why do you have `log_not'? +Why do you have `ext'? +Why do you have `zero_ext'? + These are all easily synthesized from other instructions, but I + expect them to be used frequently, and they're simple, so I + include them to keep bytecode strings short. + + `log_not' is equivalent to `const8 0 equal'; it's used in half the + relational operators. + + `ext N' is equivalent to `const8 S-N lsh const8 S-N rsh_signed', + where S is the size of the stack elements; it follows `refM' and + REG bytecodes when the value should be signed. See the next + bulleted item. + + `zero_ext N' is equivalent to `constM MASK log_and'; it's used + whenever we push the value of a register, because we can't assume + the upper bits of the register aren't garbage. + +Why not have sign-extending variants of the `ref' operators? + Because that would double the number of `ref' operators, and we + need the `ext' bytecode anyway for accessing bitfields. + +Why not have constant-address variants of the `ref' operators? + Because that would double the number of `ref' operators again, and + `const32 ADDRESS ref32' is only one byte longer. + +Why do the `refN' operators have to support unaligned fetches? + GDB will generate bytecode that fetches multi-byte values at + unaligned addresses whenever the executable's debugging + information tells it to. Furthermore, GDB does not know the value + the pointer will have when GDB generates the bytecode, so it + cannot determine whether a particular fetch will be aligned or not. + + In particular, structure bitfields may be several bytes long, but + follow no alignment rules; members of packed structures are not + necessarily aligned either. + + In general, there are many cases where unaligned references occur + in correct C code, either at the programmer's explicit request, or + at the compiler's discretion. Thus, it is simpler to make the GDB + agent bytecodes work correctly in all circumstances than to make + GDB guess in each case whether the compiler did the usual thing. + +Why are there no side-effecting operators? + Because our current client doesn't want them? That's a cheap + answer. I think the real answer is that I'm afraid of + implementing function calls. We should re-visit this issue after + the present contract is delivered. + +Why aren't the `goto' ops PC-relative? + The interpreter has the base address around anyway for PC bounds + checking, and it seemed simpler. + +Why is there only one offset size for the `goto' ops? + Offsets are currently sixteen bits. I'm not happy with this + situation either: + + Suppose we have multiple branch ops with different offset sizes. + As I generate code left-to-right, all my jumps are forward jumps + (there are no loops in expressions), so I never know the target + when I emit the jump opcode. Thus, I have to either always assume + the largest offset size, or do jump relaxation on the code after I + generate it, which seems like a big waste of time. + + I can imagine a reasonable expression being longer than 256 bytes. + I can't imagine one being longer than 64k. Thus, we need 16-bit + offsets. This kind of reasoning is so bogus, but relaxation is + pathetic. + + The other approach would be to generate code right-to-left. Then + I'd always know my offset size. That might be fun. + +Where is the function call bytecode? + When we add side-effects, we should add this. + +Why does the `reg' bytecode take a 16-bit register number? + Intel's IA-64 architecture has 128 general-purpose registers, and + 128 floating-point registers, and I'm sure it has some random + control registers. + +Why do we need `trace' and `trace_quick'? + Because GDB needs to record all the memory contents and registers + an expression touches. If the user wants to evaluate an expression + `x->y->z', the agent must record the values of `x' and `x->y' as + well as the value of `x->y->z'. + +Don't the `trace' bytecodes make the interpreter less general? + They do mean that the interpreter contains special-purpose code, + but that doesn't mean the interpreter can only be used for that + purpose. If an expression doesn't use the `trace' bytecodes, they + don't get in its way. + +Why doesn't `trace_quick' consume its arguments the way everything else does? + In general, you do want your operators to consume their arguments; + it's consistent, and generally reduces the amount of stack + rearrangement necessary. However, `trace_quick' is a kludge to + save space; it only exists so we needn't write `dup const8 SIZE + trace' before every memory reference. Therefore, it's okay for it + not to consume its arguments; it's meant for a specific context in + which we know exactly what it should do with the stack. If we're + going to have a kludge, it should be an effective kludge. + +Why does `trace16' exist? + That opcode was added by the customer that contracted Cygnus for + the data tracing work. I personally think it is unnecessary; + objects that large will be quite rare, so it is okay to use `dup + const16 SIZE trace' in those cases. + + Whatever we decide to do with `trace16', we should at least leave + opcode 0x30 reserved, to remain compatible with the customer who + added it. + + + +File: gdb.info, Node: Copying, Next: GNU Free Documentation License, Prev: Agent Expressions, Up: Top + +GNU GENERAL PUBLIC LICENSE +************************** + + Version 2, June 1991 + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Preamble +======== + +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + 0. This License applies to any program or other work which contains a + notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", + below, refers to any such program or work, and a "work based on + the Program" means either the Program or any derivative work under + copyright law: that is to say, a work containing the Program or a + portion of it, either verbatim or with modifications and/or + translated into another language. (Hereinafter, translation is + included without limitation in the term "modification".) Each + licensee is addressed as "you". + + Activities other than copying, distribution and modification are + not covered by this License; they are outside its scope. The act + of running the Program is not restricted, and the output from the + Program is covered only if its contents constitute a work based on + the Program (independent of having been made by running the + Program). Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's + source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate + copyright notice and disclaimer of warranty; keep intact all the + notices that refer to this License and to the absence of any + warranty; and give any other recipients of the Program a copy of + this License along with the Program. + + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange + for a fee. + + 2. You may modify your copy or copies of the Program or any portion + of it, thus forming a work based on the Program, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a. You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b. You must cause any work that you distribute or publish, that + in whole or in part contains or is derived from the Program + or any part thereof, to be licensed as a whole at no charge + to all third parties under the terms of this License. + + c. If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display + an announcement including an appropriate copyright notice and + a notice that there is no warranty (or else, saying that you + provide a warranty) and that users may redistribute the + program under these conditions, and telling the user how to + view a copy of this License. (Exception: if the Program + itself is interactive but does not normally print such an + announcement, your work based on the Program is not required + to print an announcement.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the + Program, and can be reasonably considered independent and separate + works in themselves, then this License, and its terms, do not + apply to those sections when you distribute them as separate + works. But when you distribute the same sections as part of a + whole which is a work based on the Program, the distribution of + the whole must be on the terms of this License, whose permissions + for other licensees extend to the entire whole, and thus to each + and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or + contest your rights to work written entirely by you; rather, the + intent is to exercise the right to control the distribution of + derivative or collective works based on the Program. + + In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on + a volume of a storage or distribution medium does not bring the + other work under the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms + of Sections 1 and 2 above provided that you also do one of the + following: + + a. Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Sections 1 and 2 above on a medium customarily used for + software interchange; or, + + b. Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or, + + c. Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with + such an offer, in accord with Subsection b above.) + + The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete + source code means all the source code for all modules it contains, + plus any associated interface definition files, plus the scripts + used to control compilation and installation of the executable. + However, as a special exception, the source code distributed need + not include anything that is normally distributed (in either + source or binary form) with the major components (compiler, + kernel, and so on) of the operating system on which the executable + runs, unless that component itself accompanies the executable. + + If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent + access to copy the source code from the same place counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense or distribute the Program is + void, and will automatically terminate your rights under this + License. However, parties who have received copies, or rights, + from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + + 5. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify + or distribute the Program or its derivative works. These actions + are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Program (or any work + based on the Program), you indicate your acceptance of this + License to do so, and all its terms and conditions for copying, + distributing or modifying the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program + subject to these terms and conditions. You may not impose any + further restrictions on the recipients' exercise of the rights + granted herein. You are not responsible for enforcing compliance + by third parties to this License. + + 7. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent + issues), conditions are imposed on you (whether by court order, + agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this + License. If you cannot distribute so as to satisfy simultaneously + your obligations under this License and any other pertinent + obligations, then as a consequence you may not distribute the + Program at all. For example, if a patent license would not permit + royalty-free redistribution of the Program by all those who + receive copies directly or indirectly through you, then the only + way you could satisfy both it and this License would be to refrain + entirely from distribution of the Program. + + If any portion of this section is held invalid or unenforceable + under any particular circumstance, the balance of the section is + intended to apply and the section as a whole is intended to apply + in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of + any such claims; this section has the sole purpose of protecting + the integrity of the free software distribution system, which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is + willing to distribute software through any other system and a + licensee cannot impose that choice. + + This section is intended to make thoroughly clear what is believed + to be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, + the original copyright holder who places the Program under this + License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only + in or among countries not thus excluded. In such case, this + License incorporates the limitation as if written in the body of + this License. + + 9. The Free Software Foundation may publish revised and/or new + versions of the General Public License from time to time. Such + new versions will be similar in spirit to the present version, but + may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the + Program specifies a version number of this License which applies + to it and "any later version", you have the option of following + the terms and conditions either of that version or of any later + version published by the Free Software Foundation. If the Program + does not specify a version number of this License, you may choose + any version ever published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted + by the Free Software Foundation, write to the Free Software + Foundation; we sometimes make exceptions for this. Our decision + will be guided by the two goals of preserving the free status of + all derivatives of our free software and of promoting the sharing + and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY + MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, + INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR + INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU + OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY + OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs +============================================= + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. + Copyright (C) YEAR NAME OF AUTHOR + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Also add information on how to contact you by electronic and paper +mail. + + If the program is interactive, make it output a short notice like +this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) YEAR NAME OF AUTHOR + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details + type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + + The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + + You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the program, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + SIGNATURE OF TY COON, 1 April 1989 + Ty Coon, President of Vice + + This General Public License does not permit incorporating your +program into proprietary programs. If your program is a subroutine +library, you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +GNU Library General Public License instead of this License. + + +File: gdb.info, Node: GNU Free Documentation License, Next: Index, Prev: Copying, Up: Top + +GNU Free Documentation License +****************************** + + Version 1.2, November 2002 + Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + 0. PREAMBLE + + The purpose of this License is to make a manual, textbook, or other + functional and useful document "free" in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or + noncommercially. Secondarily, this License preserves for the + author and publisher a way to get credit for their work, while not + being considered responsible for modifications made by others. + + This License is a kind of "copyleft", which means that derivative + works of the document must themselves be free in the same sense. + It complements the GNU General Public License, which is a copyleft + license designed for free software. + + We have designed this License in order to use it for manuals for + free software, because free software needs free documentation: a + free program should come with manuals providing the same freedoms + that the software does. But this License is not limited to + software manuals; it can be used for any textual work, regardless + of subject matter or whether it is published as a printed book. + We recommend this License principally for works whose purpose is + instruction or reference. + + 1. APPLICABILITY AND DEFINITIONS + + This License applies to any manual or other work, in any medium, + that contains a notice placed by the copyright holder saying it + can be distributed under the terms of this License. Such a notice + grants a world-wide, royalty-free license, unlimited in duration, + to use that work under the conditions stated herein. The + "Document", below, refers to any such manual or work. Any member + of the public is a licensee, and is addressed as "you". You + accept the license if you copy, modify or distribute the work in a + way requiring permission under copyright law. + + A "Modified Version" of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + + A "Secondary Section" is a named appendix or a front-matter section + of the Document that deals exclusively with the relationship of the + publishers or authors of the Document to the Document's overall + subject (or to related matters) and contains nothing that could + fall directly within that overall subject. (Thus, if the Document + is in part a textbook of mathematics, a Secondary Section may not + explain any mathematics.) The relationship could be a matter of + historical connection with the subject or with related matters, or + of legal, commercial, philosophical, ethical or political position + regarding them. + + The "Invariant Sections" are certain Secondary Sections whose + titles are designated, as being those of Invariant Sections, in + the notice that says that the Document is released under this + License. If a section does not fit the above definition of + Secondary then it is not allowed to be designated as Invariant. + The Document may contain zero Invariant Sections. If the Document + does not identify any Invariant Sections then there are none. + + The "Cover Texts" are certain short passages of text that are + listed, as Front-Cover Texts or Back-Cover Texts, in the notice + that says that the Document is released under this License. A + Front-Cover Text may be at most 5 words, and a Back-Cover Text may + be at most 25 words. + + A "Transparent" copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images + composed of pixels) generic paint programs or (for drawings) some + widely available drawing editor, and that is suitable for input to + text formatters or for automatic translation to a variety of + formats suitable for input to text formatters. A copy made in an + otherwise Transparent file format whose markup, or absence of + markup, has been arranged to thwart or discourage subsequent + modification by readers is not Transparent. An image format is + not Transparent if used for any substantial amount of text. A + copy that is not "Transparent" is called "Opaque". + + Examples of suitable formats for Transparent copies include plain + ASCII without markup, Texinfo input format, LaTeX input format, + SGML or XML using a publicly available DTD, and + standard-conforming simple HTML, PostScript or PDF designed for + human modification. Examples of transparent image formats include + PNG, XCF and JPG. Opaque formats include proprietary formats that + can be read and edited only by proprietary word processors, SGML or + XML for which the DTD and/or processing tools are not generally + available, and the machine-generated HTML, PostScript or PDF + produced by some word processors for output purposes only. + + The "Title Page" means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the + material this License requires to appear in the title page. For + works in formats which do not have any title page as such, "Title + Page" means the text near the most prominent appearance of the + work's title, preceding the beginning of the body of the text. + + A section "Entitled XYZ" means a named subunit of the Document + whose title either is precisely XYZ or contains XYZ in parentheses + following text that translates XYZ in another language. (Here XYZ + stands for a specific section name mentioned below, such as + "Acknowledgements", "Dedications", "Endorsements", or "History".) + To "Preserve the Title" of such a section when you modify the + Document means that it remains a section "Entitled XYZ" according + to this definition. + + The Document may include Warranty Disclaimers next to the notice + which states that this License applies to the Document. These + Warranty Disclaimers are considered to be included by reference in + this License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and + has no effect on the meaning of this License. + + 2. VERBATIM COPYING + + You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License + applies to the Document are reproduced in all copies, and that you + add no other conditions whatsoever to those of this License. You + may not use technical measures to obstruct or control the reading + or further copying of the copies you make or distribute. However, + you may accept compensation in exchange for copies. If you + distribute a large enough number of copies you must also follow + the conditions in section 3. + + You may also lend copies, under the same conditions stated above, + and you may publicly display copies. + + 3. COPYING IN QUANTITY + + If you publish printed copies (or copies in media that commonly + have printed covers) of the Document, numbering more than 100, and + the Document's license notice requires Cover Texts, you must + enclose the copies in covers that carry, clearly and legibly, all + these Cover Texts: Front-Cover Texts on the front cover, and + Back-Cover Texts on the back cover. Both covers must also clearly + and legibly identify you as the publisher of these copies. The + front cover must present the full title with all words of the + title equally prominent and visible. You may add other material + on the covers in addition. Copying with changes limited to the + covers, as long as they preserve the title of the Document and + satisfy these conditions, can be treated as verbatim copying in + other respects. + + If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto + adjacent pages. + + If you publish or distribute Opaque copies of the Document + numbering more than 100, you must either include a + machine-readable Transparent copy along with each Opaque copy, or + state in or with each Opaque copy a computer-network location from + which the general network-using public has access to download + using public-standard network protocols a complete Transparent + copy of the Document, free of added material. If you use the + latter option, you must take reasonably prudent steps, when you + begin distribution of Opaque copies in quantity, to ensure that + this Transparent copy will remain thus accessible at the stated + location until at least one year after the last time you + distribute an Opaque copy (directly or through your agents or + retailers) of that edition to the public. + + It is requested, but not required, that you contact the authors of + the Document well before redistributing any large number of + copies, to give them a chance to provide you with an updated + version of the Document. + + 4. MODIFICATIONS + + You may copy and distribute a Modified Version of the Document + under the conditions of sections 2 and 3 above, provided that you + release the Modified Version under precisely this License, with + the Modified Version filling the role of the Document, thus + licensing distribution and modification of the Modified Version to + whoever possesses a copy of it. In addition, you must do these + things in the Modified Version: + + A. Use in the Title Page (and on the covers, if any) a title + distinct from that of the Document, and from those of + previous versions (which should, if there were any, be listed + in the History section of the Document). You may use the + same title as a previous version if the original publisher of + that version gives permission. + + B. List on the Title Page, as authors, one or more persons or + entities responsible for authorship of the modifications in + the Modified Version, together with at least five of the + principal authors of the Document (all of its principal + authors, if it has fewer than five), unless they release you + from this requirement. + + C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + + D. Preserve all the copyright notices of the Document. + + E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + + F. Include, immediately after the copyright notices, a license + notice giving the public permission to use the Modified + Version under the terms of this License, in the form shown in + the Addendum below. + + G. Preserve in that license notice the full lists of Invariant + Sections and required Cover Texts given in the Document's + license notice. + + H. Include an unaltered copy of this License. + + I. Preserve the section Entitled "History", Preserve its Title, + and add to it an item stating at least the title, year, new + authors, and publisher of the Modified Version as given on + the Title Page. If there is no section Entitled "History" in + the Document, create one stating the title, year, authors, + and publisher of the Document as given on its Title Page, + then add an item describing the Modified Version as stated in + the previous sentence. + + J. Preserve the network location, if any, given in the Document + for public access to a Transparent copy of the Document, and + likewise the network locations given in the Document for + previous versions it was based on. These may be placed in + the "History" section. You may omit a network location for a + work that was published at least four years before the + Document itself, or if the original publisher of the version + it refers to gives permission. + + K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the + section all the substance and tone of each of the contributor + acknowledgements and/or dedications given therein. + + L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section + titles. + + M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. + + N. Do not retitle any existing section to be Entitled + "Endorsements" or to conflict in title with any Invariant + Section. + + O. Preserve any Warranty Disclaimers. + + If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no + material copied from the Document, you may at your option + designate some or all of these sections as invariant. To do this, + add their titles to the list of Invariant Sections in the Modified + Version's license notice. These titles must be distinct from any + other section titles. + + You may add a section Entitled "Endorsements", provided it contains + nothing but endorsements of your Modified Version by various + parties--for example, statements of peer review or that the text + has been approved by an organization as the authoritative + definition of a standard. + + You may add a passage of up to five words as a Front-Cover Text, + and a passage of up to 25 words as a Back-Cover Text, to the end + of the list of Cover Texts in the Modified Version. Only one + passage of Front-Cover Text and one of Back-Cover Text may be + added by (or through arrangements made by) any one entity. If the + Document already includes a cover text for the same cover, + previously added by you or by arrangement made by the same entity + you are acting on behalf of, you may not add another; but you may + replace the old one, on explicit permission from the previous + publisher that added the old one. + + The author(s) and publisher(s) of the Document do not by this + License give permission to use their names for publicity for or to + assert or imply endorsement of any Modified Version. + + 5. COMBINING DOCUMENTS + + You may combine the Document with other documents released under + this License, under the terms defined in section 4 above for + modified versions, provided that you include in the combination + all of the Invariant Sections of all of the original documents, + unmodified, and list them all as Invariant Sections of your + combined work in its license notice, and that you preserve all + their Warranty Disclaimers. + + The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name + but different contents, make the title of each such section unique + by adding at the end of it, in parentheses, the name of the + original author or publisher of that section if known, or else a + unique number. Make the same adjustment to the section titles in + the list of Invariant Sections in the license notice of the + combined work. + + In the combination, you must combine any sections Entitled + "History" in the various original documents, forming one section + Entitled "History"; likewise combine any sections Entitled + "Acknowledgements", and any sections Entitled "Dedications". You + must delete all sections Entitled "Endorsements." + + 6. COLLECTIONS OF DOCUMENTS + + You may make a collection consisting of the Document and other + documents released under this License, and replace the individual + copies of this License in the various documents with a single copy + that is included in the collection, provided that you follow the + rules of this License for verbatim copying of each of the + documents in all other respects. + + You may extract a single document from such a collection, and + distribute it individually under this License, provided you insert + a copy of this License into the extracted document, and follow + this License in all other respects regarding verbatim copying of + that document. + + 7. AGGREGATION WITH INDEPENDENT WORKS + + A compilation of the Document or its derivatives with other + separate and independent documents or works, in or on a volume of + a storage or distribution medium, is called an "aggregate" if the + copyright resulting from the compilation is not used to limit the + legal rights of the compilation's users beyond what the individual + works permit. When the Document is included in an aggregate, this + License does not apply to the other works in the aggregate which + are not themselves derivative works of the Document. + + If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half + of the entire aggregate, the Document's Cover Texts may be placed + on covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic + form. Otherwise they must appear on printed covers that bracket + the whole aggregate. + + 8. TRANSLATION + + Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section + 4. Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also + include the original English version of this License and the + original versions of those notices and disclaimers. In case of a + disagreement between the translation and the original version of + this License or a notice or disclaimer, the original version will + prevail. + + If a section in the Document is Entitled "Acknowledgements", + "Dedications", or "History", the requirement (section 4) to + Preserve its Title (section 1) will typically require changing the + actual title. + + 9. TERMINATION + + You may not copy, modify, sublicense, or distribute the Document + except as expressly provided for under this License. Any other + attempt to copy, modify, sublicense or distribute the Document is + void, and will automatically terminate your rights under this + License. However, parties who have received copies, or rights, + from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + + 10. FUTURE REVISIONS OF THIS LICENSE + + The Free Software Foundation may publish new, revised versions of + the GNU Free Documentation License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. See + `http://www.gnu.org/copyleft/'. + + Each version of the License is given a distinguishing version + number. If the Document specifies that a particular numbered + version of this License "or any later version" applies to it, you + have the option of following the terms and conditions either of + that specified version or of any later version that has been + published (not as a draft) by the Free Software Foundation. If + the Document does not specify a version number of this License, + you may choose any version ever published (not as a draft) by the + Free Software Foundation. + +ADDENDUM: How to use this License for your documents +==================================================== + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + + Copyright (C) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + + If you have Invariant Sections, Front-Cover Texts and Back-Cover +Texts, replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with + the Front-Cover Texts being LIST, and with the Back-Cover Texts + being LIST. + + If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + + If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, to +permit their use in free software. + + +File: gdb.info, Node: Index, Prev: GNU Free Documentation License, Up: Top + +Index +***** + +* Menu: + +* ! packet: Packets. +* "No symbol "foo" in current context": Variables. +* # (a comment): Command Syntax. +* # in Modula-2: GDB/M2. +* $: Value History. +* $$: Value History. +* $_ and info breakpoints: Set Breaks. +* $_ and info line: Machine Code. +* $_, $__, and value history: Memory. +* $_, convenience variable: Convenience Vars. +* $__, convenience variable: Convenience Vars. +* $_exitcode, convenience variable: Convenience Vars. +* $bpnum, convenience variable: Set Breaks. +* $cdir, convenience variable: Source Path. +* $cwdr, convenience variable: Source Path. +* $tpnum: Create and Delete Tracepoints. +* $trace_file: Tracepoint Variables. +* $trace_frame: Tracepoint Variables. +* $trace_func: Tracepoint Variables. +* $trace_line: Tracepoint Variables. +* $tracepoint: Tracepoint Variables. +* --annotate: Mode Options. +* --args: Mode Options. +* --async: Mode Options. +* --batch: Mode Options. +* --baud: Mode Options. +* --cd: Mode Options. +* --command: File Options. +* --core: File Options. +* --directory: File Options. +* --epoch: Mode Options. +* --exec: File Options. +* --fullname: Mode Options. +* --interpreter: Mode Options. +* --mapped: File Options. +* --noasync: Mode Options. +* --nowindows: Mode Options. +* --nx: Mode Options. +* --pid: File Options. +* --quiet: Mode Options. +* --readnow: File Options. +* --se: File Options. +* --silent: Mode Options. +* --statistics: Mode Options. +* --symbols: File Options. +* --tty: Mode Options. +* --tui: Mode Options. +* --version: Mode Options. +* --windows: Mode Options. +* --write: Mode Options. +* -b: Mode Options. +* -break-after: GDB/MI Breakpoint Table Commands. +* -break-condition: GDB/MI Breakpoint Table Commands. +* -break-delete: GDB/MI Breakpoint Table Commands. +* -break-disable: GDB/MI Breakpoint Table Commands. +* -break-enable: GDB/MI Breakpoint Table Commands. +* -break-info: GDB/MI Breakpoint Table Commands. +* -break-insert: GDB/MI Breakpoint Table Commands. +* -break-list: GDB/MI Breakpoint Table Commands. +* -break-watch: GDB/MI Breakpoint Table Commands. +* -c: File Options. +* -d: File Options. +* -data-disassemble: GDB/MI Data Manipulation. +* -data-evaluate-expression: GDB/MI Data Manipulation. +* -data-list-changed-registers: GDB/MI Data Manipulation. +* -data-list-register-names: GDB/MI Data Manipulation. +* -data-list-register-values: GDB/MI Data Manipulation. +* -data-read-memory: GDB/MI Data Manipulation. +* -display-delete: GDB/MI Data Manipulation. +* -display-disable: GDB/MI Data Manipulation. +* -display-enable: GDB/MI Data Manipulation. +* -display-insert: GDB/MI Data Manipulation. +* -display-list: GDB/MI Data Manipulation. +* -e: File Options. +* -environment-cd: GDB/MI Data Manipulation. +* -environment-directory: GDB/MI Data Manipulation. +* -environment-path: GDB/MI Data Manipulation. +* -environment-pwd: GDB/MI Data Manipulation. +* -exec-abort: GDB/MI Program Control. +* -exec-arguments: GDB/MI Program Control. +* -exec-continue: GDB/MI Program Control. +* -exec-finish: GDB/MI Program Control. +* -exec-interrupt: GDB/MI Program Control. +* -exec-next: GDB/MI Program Control. +* -exec-next-instruction: GDB/MI Program Control. +* -exec-return: GDB/MI Program Control. +* -exec-run: GDB/MI Program Control. +* -exec-show-arguments: GDB/MI Program Control. +* -exec-step: GDB/MI Program Control. +* -exec-step-instruction: GDB/MI Program Control. +* -exec-until: GDB/MI Program Control. +* -f: Mode Options. +* -file-exec-and-symbols: GDB/MI Program Control. +* -file-exec-file: GDB/MI Program Control. +* -file-list-exec-sections: GDB/MI Program Control. +* -file-list-exec-source-file: GDB/MI Program Control. +* -file-list-exec-source-files: GDB/MI Program Control. +* -file-list-shared-libraries: GDB/MI Program Control. +* -file-list-symbol-files: GDB/MI Program Control. +* -file-symbol-file: GDB/MI Program Control. +* -gdb-exit: GDB/MI Miscellaneous Commands. +* -gdb-set: GDB/MI Miscellaneous Commands. +* -gdb-show: GDB/MI Miscellaneous Commands. +* -gdb-version: GDB/MI Miscellaneous Commands. +* -interpreter-exec: GDB/MI Miscellaneous Commands. +* -m: File Options. +* -n: Mode Options. +* -nw: Mode Options. +* -p: File Options. +* -q: Mode Options. +* -r: File Options. +* -s: File Options. +* -stack-info-depth: GDB/MI Stack Manipulation. +* -stack-info-frame: GDB/MI Stack Manipulation. +* -stack-list-arguments: GDB/MI Stack Manipulation. +* -stack-list-frames: GDB/MI Stack Manipulation. +* -stack-list-locals: GDB/MI Stack Manipulation. +* -stack-select-frame: GDB/MI Stack Manipulation. +* -symbol-info-address: GDB/MI Symbol Query. +* -symbol-info-file: GDB/MI Symbol Query. +* -symbol-info-function: GDB/MI Symbol Query. +* -symbol-info-line: GDB/MI Symbol Query. +* -symbol-info-symbol: GDB/MI Symbol Query. +* -symbol-list-functions: GDB/MI Symbol Query. +* -symbol-list-lines: GDB/MI Symbol Query. +* -symbol-list-types: GDB/MI Symbol Query. +* -symbol-list-variables: GDB/MI Symbol Query. +* -symbol-locate: GDB/MI Symbol Query. +* -symbol-type: GDB/MI Symbol Query. +* -t: Mode Options. +* -target-attach: GDB/MI Target Manipulation. +* -target-compare-sections: GDB/MI Target Manipulation. +* -target-detach: GDB/MI Target Manipulation. +* -target-disconnect: GDB/MI Target Manipulation. +* -target-download: GDB/MI Target Manipulation. +* -target-exec-status: GDB/MI Target Manipulation. +* -target-list-available-targets: GDB/MI Target Manipulation. +* -target-list-current-targets: GDB/MI Target Manipulation. +* -target-list-parameters: GDB/MI Target Manipulation. +* -target-select: GDB/MI Target Manipulation. +* -thread-info: GDB/MI Thread Commands. +* -thread-list-all-threads: GDB/MI Thread Commands. +* -thread-list-ids: GDB/MI Thread Commands. +* -thread-select: GDB/MI Thread Commands. +* -var-assign: GDB/MI Variable Objects. +* -var-create: GDB/MI Variable Objects. +* -var-delete: GDB/MI Variable Objects. +* -var-evaluate-expression: GDB/MI Variable Objects. +* -var-info-expression: GDB/MI Variable Objects. +* -var-info-num-children: GDB/MI Variable Objects. +* -var-info-type: GDB/MI Variable Objects. +* -var-list-children: GDB/MI Variable Objects. +* -var-set-format: GDB/MI Variable Objects. +* -var-show-attributes: GDB/MI Variable Objects. +* -var-show-format: GDB/MI Variable Objects. +* -var-update: GDB/MI Variable Objects. +* -w: Mode Options. +* -x: File Options. +* ., Modula-2 scope operator: M2 Scope. +* .debug subdirectories: Separate Debug Files. +* .esgdbinit: Command Files. +* .gdbinit: Command Files. +* .gnu_debuglink sections: Separate Debug Files. +* .o files, reading symbols from: Files. +* .os68gdbinit: Command Files. +* .vxgdbinit: Command Files. +* /proc: SVR4 Process Information. +* ? packet: Packets. +* @, referencing memory as an array: Arrays. +* ^done: GDB/MI Result Records. +* ^error: GDB/MI Result Records. +* ^running: GDB/MI Result Records. +* _NSPrintForDebugger, and printing Objective-C objects: The Print Command with Objective-C. +* A packet: Packets. +* abbreviation: Command Syntax. +* abort (C-g): Miscellaneous Commands. +* accept-line (Newline or Return): Commands For History. +* acknowledgment, for GDB remote: Overview. +* actions: Tracepoint Actions. +* active targets: Active Targets. +* adbg_find_memory_in_frame: Tracing on Symmetrix. +* add-shared-symbol-file: Files. +* add-symbol-file: Files. +* address of a symbol: Symbols. +* advance LOCATION: Continuing and Stepping. +* Alpha stack: MIPS. +* AMD 29K register stack: A29K. +* annotations: Annotations Overview. +* annotations for errors, warnings and interrupts: Errors. +* annotations for invalidation messages: Invalidation. +* annotations for prompts: Prompting. +* annotations for running programs: Annotations for Running. +* annotations for source display: Source Annotations. +* append: Dump/Restore Files. +* append data to a file: Dump/Restore Files. +* apropos: Help. +* arguments (to your program): Arguments. +* artificial array: Arrays. +* ASCII character set: Character Sets. +* assembly instructions: Machine Code. +* assignment: Assignment. +* async output in GDB/MI: GDB/MI Output Syntax. +* AT&T disassembly flavor: Machine Code. +* attach: Attach. +* attach to a program by name: Server. +* automatic display: Auto Display. +* automatic overlay debugging: Automatic Overlay Debugging. +* automatic thread selection: Threads. +* auxiliary vector: Auxiliary Vector. +* awatch: Set Watchpoints. +* b (break): Set Breaks. +* B packet: Packets. +* b packet: Packets. +* backtrace: Backtrace. +* backtrace limit: Backtrace. +* backtraces: Backtrace. +* backward-char (C-b): Commands For Moving. +* backward-delete-char (Rubout): Commands For Text. +* backward-kill-line (C-x Rubout): Commands For Killing. +* backward-kill-word (M-): Commands For Killing. +* backward-word (M-b): Commands For Moving. +* beginning-of-history (M-<): Commands For History. +* beginning-of-line (C-a): Commands For Moving. +* bell-style: Readline Init File Syntax. +* break: Set Breaks. +* break ... thread THREADNO: Thread Stops. +* break in overloaded functions: Debugging C plus plus. +* break, and Objective-C: Method Names in Commands. +* breakpoint: Annotations for Running. +* breakpoint address adjusted: Breakpoint related warnings. +* breakpoint commands: Break Commands. +* breakpoint commands for GDB/MI: GDB/MI Breakpoint Table Commands. +* breakpoint conditions: Conditions. +* breakpoint numbers: Breakpoints. +* breakpoint on events: Breakpoints. +* breakpoint on memory address: Breakpoints. +* breakpoint on variable modification: Breakpoints. +* breakpoint ranges: Breakpoints. +* breakpoint subroutine, remote: Stub Contents. +* breakpoints: Breakpoints. +* breakpoints and threads: Thread Stops. +* breakpoints in overlays: Overlay Commands. +* breakpoints-invalid: Invalidation. +* bt (backtrace): Backtrace. +* bug criteria: Bug Criteria. +* bug reports: Bug Reporting. +* bugs in GDB: GDB Bugs. +* c (continue): Continuing and Stepping. +* c (SingleKey TUI key): TUI Single Key Mode. +* C and C++: C. +* C and C++ checks: C Checks. +* C and C++ constants: C Constants. +* C and C++ defaults: C Defaults. +* C and C++ operators: C Operators. +* C packet: Packets. +* c packet: Packets. +* C++: C. +* C++ compilers: C plus plus expressions. +* C++ exception handling: Debugging C plus plus. +* C++ scope resolution: Variables. +* C++ symbol decoding style: Print Settings. +* C++ symbol display: Debugging C plus plus. +* C-L: TUI Keys. +* C-o (operate-and-get-next): Command Syntax. +* C-x 1: TUI Keys. +* C-x 2: TUI Keys. +* C-x A: TUI Keys. +* C-x a: TUI Keys. +* C-x C-a: TUI Keys. +* C-x o: TUI Keys. +* C-x s: TUI Keys. +* call: Calling. +* call overloaded functions: C plus plus expressions. +* call stack: Stack. +* call-last-kbd-macro (C-x e): Keyboard Macros. +* calling functions: Calling. +* calling make: Shell Commands. +* capitalize-word (M-c): Commands For Text. +* casts, to view memory: Expressions. +* catch: Set Catchpoints. +* catch catch: Set Catchpoints. +* catch exceptions, list active handlers: Frame Info. +* catch exec: Set Catchpoints. +* catch fork: Set Catchpoints. +* catch load: Set Catchpoints. +* catch throw: Set Catchpoints. +* catch unload: Set Catchpoints. +* catch vfork: Set Catchpoints. +* catchpoints: Breakpoints. +* catchpoints, setting: Set Catchpoints. +* cd: Working Directory. +* cdir: Source Path. +* character sets: Character Sets. +* character-search (C-]): Miscellaneous Commands. +* character-search-backward (M-C-]): Miscellaneous Commands. +* charset: Character Sets. +* checks, range: Type Checking. +* checks, type: Checks. +* checksum, for GDB remote: Overview. +* choosing target byte order: Byte Order. +* clear: Delete Breaks. +* clear, and Objective-C: Method Names in Commands. +* clear-screen (C-l): Commands For Moving. +* clearing breakpoints, watchpoints, catchpoints: Delete Breaks. +* close, file-i/o system call: close. +* collect (tracepoints): Tracepoint Actions. +* collected data discarded: Starting and Stopping Trace Experiment. +* colon, doubled as scope operator: M2 Scope. +* colon-colon, context for variables/functions: Variables. +* colon-colon, in Modula-2: M2 Scope. +* command editing: Readline Bare Essentials. +* command files: Command Files. +* command hooks: Hooks. +* command interpreters: Interpreters. +* command line editing: Editing. +* commands <1>: Prompting. +* commands: Break Commands. +* commands for C++: Debugging C plus plus. +* commands to STDBUG (ST2000): ST2000. +* comment: Command Syntax. +* comment-begin: Readline Init File Syntax. +* compatibility, GDB/MI and CLI: GDB/MI Compatibility with CLI. +* compilation directory: Source Path. +* compiling, on Sparclet: Sparclet. +* complete: Help. +* complete (): Commands For Completion. +* completion: Completion. +* completion of quoted strings: Completion. +* completion-query-items: Readline Init File Syntax. +* condition: Conditions. +* conditional breakpoints: Conditions. +* configuring GDB: Installing GDB. +* configuring GDB, and source tree subdirectories: Installing GDB. +* confirmation: Messages/Warnings. +* connect (to STDBUG): ST2000. +* console i/o as part of file-i/o: Console I/O. +* console interpreter: Interpreters. +* console output in GDB/MI: GDB/MI Output Syntax. +* constants, in file-i/o protocol: Constants. +* continue: Continuing and Stepping. +* continuing: Continuing and Stepping. +* continuing threads: Thread Stops. +* control C, and remote debugging: Bootstrapping. +* controlling terminal: Input/Output. +* convenience variables: Convenience Vars. +* convenience variables for tracepoints: Tracepoint Variables. +* convert-meta: Readline Init File Syntax. +* copy-backward-word (): Commands For Killing. +* copy-forward-word (): Commands For Killing. +* copy-region-as-kill (): Commands For Killing. +* core: Files. +* core dump file: Files. +* core-file: Files. +* crash of debugger: Bug Criteria. +* ctrl-c message, in file-i/o protocol: The Ctrl-C message. +* current directory: Source Path. +* current stack frame: Frames. +* current thread: Threads. +* cwd: Source Path. +* Cygwin-specific commands: Cygwin Native. +* d (delete): Delete Breaks. +* d (SingleKey TUI key): TUI Single Key Mode. +* D packet: Packets. +* d packet: Packets. +* data manipulation, in GDB/MI: GDB/MI Data Manipulation. +* debug formats and C++: C plus plus expressions. +* debug links: Separate Debug Files. +* debugger crash: Bug Criteria. +* debugging C++ programs: C plus plus expressions. +* debugging information directory, global: Separate Debug Files. +* debugging information in separate files: Separate Debug Files. +* debugging optimized code: Compilation. +* debugging stub, example: remote stub. +* debugging target: Targets. +* define: Define. +* defining macros interactively: Macros. +* definition, showing a macro's: Macros. +* delete: Delete Breaks. +* delete breakpoints: Delete Breaks. +* delete display: Auto Display. +* delete mem: Memory Region Attributes. +* delete tracepoint: Create and Delete Tracepoints. +* delete-char (C-d): Commands For Text. +* delete-char-or-list (): Commands For Completion. +* delete-horizontal-space (): Commands For Killing. +* deleting breakpoints, watchpoints, catchpoints: Delete Breaks. +* demangling: Print Settings. +* descriptor tables display: DJGPP Native. +* detach: Attach. +* detach (remote): Connecting. +* device: Renesas Boards. +* digit-argument (M-0, M-1, ... M--): Numeric Arguments. +* dir: Source Path. +* direct memory access (DMA) on MS-DOS: DJGPP Native. +* directories for source files: Source Path. +* directory: Source Path. +* directory, compilation: Source Path. +* directory, current: Source Path. +* dis (disable): Disabling. +* disable: Disabling. +* disable breakpoints: Disabling. +* disable display: Auto Display. +* disable mem: Memory Region Attributes. +* disable tracepoint: Enable and Disable Tracepoints. +* disable-completion: Readline Init File Syntax. +* disassemble: Machine Code. +* disconnect: Connecting. +* display: Auto Display. +* display of expressions: Auto Display. +* DJGPP debugging: DJGPP Native. +* dll-symbols: Cygwin Native. +* DLLs with no debugging symbols: Non-debug DLL symbols. +* do (down): Selection. +* do-uppercase-version (M-a, M-b, M-X, ...): Miscellaneous Commands. +* document: Define. +* documentation: Formatting Documentation. +* Down: TUI Keys. +* down: Selection. +* down-silently: Selection. +* downcase-word (M-l): Commands For Text. +* download to H8/300 or H8/500: H8/300. +* download to Renesas SH: H8/300. +* download to Sparclet: Sparclet Download. +* download to VxWorks: VxWorks Download. +* dump: Dump/Restore Files. +* dump all data collected at tracepoint: tdump. +* dump data to a file: Dump/Restore Files. +* dump-functions (): Miscellaneous Commands. +* dump-macros (): Miscellaneous Commands. +* dump-variables (): Miscellaneous Commands. +* dump/restore files: Dump/Restore Files. +* dynamic linking: Files. +* e (edit): Edit. +* EBCDIC character set: Character Sets. +* echo: Output. +* edit: Edit. +* editing: Editing. +* editing command lines: Readline Bare Essentials. +* editing source files: Edit. +* editing-mode: Readline Init File Syntax. +* else: Define. +* Emacs: Emacs. +* enable: Disabling. +* enable breakpoints: Disabling. +* enable display: Auto Display. +* enable mem: Memory Region Attributes. +* enable tracepoint: Enable and Disable Tracepoints. +* enable-keypad: Readline Init File Syntax. +* end: Break Commands. +* end-kbd-macro (C-x )): Keyboard Macros. +* end-of-history (M->): Commands For History. +* end-of-line (C-e): Commands For Moving. +* entering numbers: Numbers. +* environment (of your program): Environment. +* errno values, in file-i/o protocol: Errno values. +* error: Errors. +* error on valid input: Bug Criteria. +* error-begin: Errors. +* event designators: Event Designators. +* event handling: Set Catchpoints. +* examining data: Data. +* examining memory: Memory. +* exception handlers: Set Catchpoints. +* exception handlers, how to list: Frame Info. +* exceptionHandler: Bootstrapping. +* exchange-point-and-mark (C-x C-x): Miscellaneous Commands. +* exec-file: Files. +* executable file: Files. +* exited: Annotations for Running. +* exiting GDB: Quitting GDB. +* expand-tilde: Readline Init File Syntax. +* expanding preprocessor macros: Macros. +* expressions: Expressions. +* expressions in C or C++: C. +* expressions in C++: C plus plus expressions. +* expressions in Modula-2: Modula-2. +* f (frame): Selection. +* f (SingleKey TUI key): TUI Single Key Mode. +* F packet: Packets. +* F reply packet: The F reply packet. +* F request packet: The F request packet. +* fatal signal: Bug Criteria. +* fatal signals: Signals. +* FDL, GNU Free Documentation License: GNU Free Documentation License. +* fg (resume foreground execution): Continuing and Stepping. +* file: Files. +* file-i/o examples: File-I/O Examples. +* file-i/o overview: File-I/O Overview. +* File-I/O remote protocol extension: File-I/O remote protocol extension. +* file-i/o reply packet: The F reply packet. +* file-i/o request packet: The F request packet. +* find trace snapshot: tfind. +* finish: Continuing and Stepping. +* flinching: Messages/Warnings. +* float promotion: ABI. +* floating point: Floating Point Hardware. +* floating point registers: Registers. +* floating point, MIPS remote: MIPS Embedded. +* flush_i_cache: Bootstrapping. +* focus: TUI Commands. +* focus of debugging: Threads. +* foo: Symbol Errors. +* fork, debugging programs which call: Processes. +* format options: Print Settings. +* formatted output: Output Formats. +* Fortran: Summary. +* forward-backward-delete-char (): Commands For Text. +* forward-char (C-f): Commands For Moving. +* forward-search: Search. +* forward-search-history (C-s): Commands For History. +* forward-word (M-f): Commands For Moving. +* frame number: Frames. +* frame pointer: Frames. +* frame, command: Frames. +* frame, definition: Frames. +* frame, selecting: Selection. +* frameless execution: Frames. +* frames-invalid: Invalidation. +* free memory information (MS-DOS): DJGPP Native. +* fstat, file-i/o system call: stat/fstat. +* Fujitsu: remote stub. +* full symbol tables, listing GDB's internal: Symbols. +* functions without line info, and stepping: Continuing and Stepping. +* G packet: Packets. +* g packet: Packets. +* g++, GNU C++ compiler: C. +* garbled pointers: DJGPP Native. +* GCC and C++: C plus plus expressions. +* GDB bugs, reporting: Bug Reporting. +* GDB reference card: Formatting Documentation. +* gdb.ini: Command Files. +* GDB/MI, breakpoint commands: GDB/MI Breakpoint Table Commands. +* GDB/MI, compatibility with CLI: GDB/MI Compatibility with CLI. +* GDB/MI, data manipulation: GDB/MI Data Manipulation. +* GDB/MI, input syntax: GDB/MI Input Syntax. +* GDB/MI, its purpose: GDB/MI. +* GDB/MI, out-of-band records: GDB/MI Out-of-band Records. +* GDB/MI, output syntax: GDB/MI Output Syntax. +* GDB/MI, result records: GDB/MI Result Records. +* GDB/MI, simple examples: GDB/MI Simple Examples. +* GDB/MI, stream records: GDB/MI Stream Records. +* GDBHISTFILE: History. +* gdbserve.nlm: NetWare. +* gdbserver: Server. +* GDT: DJGPP Native. +* getDebugChar: Bootstrapping. +* gettimeofday, file-i/o system call: gettimeofday. +* global debugging information directory: Separate Debug Files. +* GNU C++: C. +* GNU Emacs: Emacs. +* gnu_debuglink_crc32: Separate Debug Files. +* h (help): Help. +* H packet: Packets. +* H8/300 or H8/500 download: H8/300. +* handle: Signals. +* handle_exception: Stub Contents. +* handling signals: Signals. +* hardware watchpoints: Set Watchpoints. +* hbreak: Set Breaks. +* help: Help. +* help target: Target Commands. +* help user-defined: Define. +* heuristic-fence-post (Alpha, MIPS): MIPS. +* history events: Event Designators. +* history expansion <1>: History Interaction. +* history expansion: History. +* history file: History. +* history number: Value History. +* history save: History. +* history size: History. +* history substitution: History. +* history-preserve-point: Readline Init File Syntax. +* history-search-backward (): Commands For History. +* history-search-forward (): Commands For History. +* hook: Hooks. +* hook-: Hooks. +* hookpost: Hooks. +* hookpost-: Hooks. +* hooks, for commands: Hooks. +* hooks, post-command: Hooks. +* hooks, pre-command: Hooks. +* horizontal-scroll-mode: Readline Init File Syntax. +* host character set: Character Sets. +* htrace disable: OpenRISC 1000. +* htrace enable: OpenRISC 1000. +* htrace info: OpenRISC 1000. +* htrace mode continuous: OpenRISC 1000. +* htrace mode suspend: OpenRISC 1000. +* htrace print: OpenRISC 1000. +* htrace qualifier: OpenRISC 1000. +* htrace record: OpenRISC 1000. +* htrace rewind: OpenRISC 1000. +* htrace stop: OpenRISC 1000. +* htrace trigger: OpenRISC 1000. +* hwatch: OpenRISC 1000. +* i (info): Help. +* I packet: Packets. +* i packet: Packets. +* i/o: Input/Output. +* i386: remote stub. +* i386-stub.c: remote stub. +* IBM1047 character set: Character Sets. +* IDT: DJGPP Native. +* if: Define. +* ignore: Conditions. +* ignore count (of breakpoint): Conditions. +* INCLUDE_RDB: VxWorks. +* info: Help. +* info address: Symbols. +* info all-registers: Registers. +* info args: Frame Info. +* info auxv: Auxiliary Vector. +* info breakpoints: Set Breaks. +* info catch: Frame Info. +* info cisco: KOD. +* info classes: Symbols. +* info display: Auto Display. +* info dll: Cygwin Native. +* info dos: DJGPP Native. +* info extensions: Show. +* info f (info frame): Frame Info. +* info files: Files. +* info float: Floating Point Hardware. +* info frame: Frame Info. +* info frame, show the source language: Show. +* info functions: Symbols. +* info line: Machine Code. +* info line, and Objective-C: Method Names in Commands. +* info locals: Frame Info. +* info macro: Macros. +* info mem: Memory Region Attributes. +* info or1k spr: OpenRISC 1000. +* info proc: SVR4 Process Information. +* info proc mappings: SVR4 Process Information. +* info program: Stopping. +* info registers: Registers. +* info s (info stack): Backtrace. +* info scope: Symbols. +* info selectors: Symbols. +* info set: Help. +* info share: Files. +* info sharedlibrary: Files. +* info signals: Signals. +* info source: Symbols. +* info source, show the source language: Show. +* info sources: Symbols. +* info stack: Backtrace. +* info symbol: Symbols. +* info target: Files. +* info terminal: Input/Output. +* info threads: Threads. +* info tracepoints: Listing Tracepoints. +* info types: Symbols. +* info variables: Symbols. +* info vector: Vector Unit. +* info w32: Cygwin Native. +* info watchpoints: Set Watchpoints. +* info win: TUI Commands. +* information about tracepoints: Listing Tracepoints. +* inheritance: Debugging C plus plus. +* init file: Command Files. +* init file name: Command Files. +* initial frame: Frames. +* initialization file, readline: Readline Init File. +* innermost frame: Frames. +* input syntax for GDB/MI: GDB/MI Input Syntax. +* input-meta: Readline Init File Syntax. +* insert-comment (M-#): Miscellaneous Commands. +* insert-completions (M-*): Commands For Completion. +* inspect: Data. +* installation: Installing GDB. +* instructions, assembly: Machine Code. +* integral datatypes, in file-i/o protocol: Integral datatypes. +* Intel: remote stub. +* Intel disassembly flavor: Machine Code. +* interaction, readline: Readline Interaction. +* internal commands: Maintenance Commands. +* internal GDB breakpoints: Set Breaks. +* interpreter-exec: Interpreters. +* interrupt: Quitting GDB. +* interrupting remote programs: Connecting. +* interrupting remote targets: Bootstrapping. +* invalid input: Bug Criteria. +* invoke another interpreter: Interpreters. +* isatty call, file-i/o protocol: The isatty call. +* isatty, file-i/o system call: isatty. +* isearch-terminators: Readline Init File Syntax. +* ISO 8859-1 character set: Character Sets. +* ISO Latin 1 character set: Character Sets. +* jump: Jumping. +* jump, and Objective-C: Method Names in Commands. +* k packet: Packets. +* kernel object display: KOD. +* keymap: Readline Init File Syntax. +* kill: Kill Process. +* kill ring: Readline Killing Commands. +* kill-line (C-k): Commands For Killing. +* kill-region (): Commands For Killing. +* kill-whole-line (): Commands For Killing. +* kill-word (M-d): Commands For Killing. +* killing text: Readline Killing Commands. +* KOD: KOD. +* l (list): List. +* languages: Languages. +* last tracepoint number: Create and Delete Tracepoints. +* latest breakpoint: Set Breaks. +* layout asm: TUI Commands. +* layout next: TUI Commands. +* layout prev: TUI Commands. +* layout regs: TUI Commands. +* layout split: TUI Commands. +* layout src: TUI Commands. +* LDT: DJGPP Native. +* leaving GDB: Quitting GDB. +* Left: TUI Keys. +* limits, in file-i/o protocol: Limits. +* linespec: List. +* list: List. +* list of supported file-i/o calls: List of supported calls. +* list output in GDB/MI: GDB/MI Output Syntax. +* list, and Objective-C: Method Names in Commands. +* listing GDB's internal symbol tables: Symbols. +* listing machine instructions: Machine Code. +* listing mapped overlays: Overlay Commands. +* load address, overlay's: How Overlays Work. +* load FILENAME: Target Commands. +* local variables: Symbols. +* locate address: Output Formats. +* log output in GDB/MI: GDB/MI Output Syntax. +* logging GDB output: Logging output. +* lseek flags, in file-i/o protocol: Lseek flags. +* lseek, file-i/o system call: lseek. +* M packet: Packets. +* m packet: Packets. +* m680x0: remote stub. +* m68k-stub.c: remote stub. +* machine instructions: Machine Code. +* macro define: Macros. +* macro definition, showing: Macros. +* macro expand: Macros. +* macro expand-once: Macros. +* macro expansion, showing the results of preprocessor: Macros. +* macro undef: Macros. +* macros, example of debugging with: Macros. +* macros, user-defined: Macros. +* maint info breakpoints: Maintenance Commands. +* maint info psymtabs: Symbols. +* maint info sections: Files. +* maint info symtabs: Symbols. +* maint internal-error: Maintenance Commands. +* maint internal-warning: Maintenance Commands. +* maint print cooked-registers: Maintenance Commands. +* maint print dummy-frames: Maintenance Commands. +* maint print psymbols: Symbols. +* maint print raw-registers: Maintenance Commands. +* maint print reggroups: Maintenance Commands. +* maint print register-groups: Maintenance Commands. +* maint print registers: Maintenance Commands. +* maint print symbols: Symbols. +* maint set profile: Maintenance Commands. +* maint show profile: Maintenance Commands. +* maintenance commands: Maintenance Commands. +* make: Shell Commands. +* manual overlay debugging: Overlay Commands. +* map an overlay: Overlay Commands. +* mapped: Files. +* mapped address: How Overlays Work. +* mapped overlays: How Overlays Work. +* mark-modified-lines: Readline Init File Syntax. +* mark-symlinked-directories: Readline Init File Syntax. +* match-hidden-files: Readline Init File Syntax. +* mem: Memory Region Attributes. +* member functions: C plus plus expressions. +* memory models, H8/500: H8/500. +* memory region attributes: Memory Region Attributes. +* memory tracing: Breakpoints. +* memory transfer, in file-i/o protocol: Memory transfer. +* memory, viewing as typed object: Expressions. +* memory-mapped symbol file: Files. +* memset: Bootstrapping. +* menu-complete (): Commands For Completion. +* meta-flag: Readline Init File Syntax. +* mi interpreter: Interpreters. +* mi1 interpreter: Interpreters. +* mi2 interpreter: Interpreters. +* minimal language: Unsupported languages. +* Minimal symbols and DLLs: Non-debug DLL symbols. +* MIPS boards: MIPS Embedded. +* MIPS remote floating point: MIPS Embedded. +* MIPS remotedebug protocol: MIPS Embedded. +* MIPS stack: MIPS. +* mode_t values, in file-i/o protocol: mode_t values. +* Modula-2: Summary. +* Modula-2 built-ins: Built-In Func/Proc. +* Modula-2 checks: M2 Checks. +* Modula-2 constants: Built-In Func/Proc. +* Modula-2 defaults: M2 Defaults. +* Modula-2 operators: M2 Operators. +* Modula-2, deviations from: Deviations. +* Modula-2, GDB support: Modula-2. +* Motorola 680x0: remote stub. +* MS Windows debugging: Cygwin Native. +* MS-DOS system info: DJGPP Native. +* MS-DOS-specific commands: DJGPP Native. +* multiple processes: Processes. +* multiple targets: Active Targets. +* multiple threads: Threads. +* n (next): Continuing and Stepping. +* n (SingleKey TUI key): TUI Single Key Mode. +* names of symbols: Symbols. +* namespace in C++: C plus plus expressions. +* native Cygwin debugging: Cygwin Native. +* native DJGPP debugging: DJGPP Native. +* negative breakpoint numbers: Set Breaks. +* New SYSTAG message: Threads. +* New SYSTAG message, on HP-UX: Threads. +* next: Continuing and Stepping. +* next-history (C-n): Commands For History. +* nexti: Continuing and Stepping. +* ni (nexti): Continuing and Stepping. +* non-incremental-forward-search-history (M-n): Commands For History. +* non-incremental-reverse-search-history (M-p): Commands For History. +* notation, readline: Readline Bare Essentials. +* notational conventions, for GDB/MI: GDB/MI. +* notify output in GDB/MI: GDB/MI Output Syntax. +* number representation: Numbers. +* numbers for breakpoints: Breakpoints. +* object files, relocatable, reading symbols from: Files. +* Objective-C: Objective-C. +* online documentation: Help. +* open flags, in file-i/o protocol: Open flags. +* open, file-i/o system call: open. +* OpenRISC 1000: OpenRISC 1000. +* OpenRISC 1000 htrace: OpenRISC 1000. +* operations allowed on pending breakpoints: Set Breaks. +* optimized code, debugging: Compilation. +* or1k boards: OpenRISC 1000. +* or1ksim: OpenRISC 1000. +* OS ABI: ABI. +* out-of-band records in GDB/MI: GDB/MI Out-of-band Records. +* outermost frame: Frames. +* output: Output. +* output formats: Output Formats. +* output syntax of GDB/MI: GDB/MI Output Syntax. +* output-meta: Readline Init File Syntax. +* overlay area: How Overlays Work. +* overlay auto: Overlay Commands. +* overlay example program: Overlay Sample Program. +* overlay load-target: Overlay Commands. +* overlay manual: Overlay Commands. +* overlay map-overlay: Overlay Commands. +* overlay off: Overlay Commands. +* overlay unmap-overlay: Overlay Commands. +* overlays: Overlays. +* overlays, setting breakpoints in: Overlay Commands. +* overload-choice: Prompting. +* overloaded functions, calling: C plus plus expressions. +* overloaded functions, overload resolution: Debugging C plus plus. +* overloading: Breakpoint Menus. +* overloading in C++: Debugging C plus plus. +* overwrite-mode (): Commands For Text. +* P packet: Packets. +* p packet: Packets. +* packets, reporting on stdout: Debugging Output. +* page tables display (MS-DOS): DJGPP Native. +* page-completions: Readline Init File Syntax. +* partial symbol dump: Symbols. +* partial symbol tables, listing GDB's internal: Symbols. +* Pascal: Summary. +* passcount: Tracepoint Passcounts. +* patching binaries: Patching. +* path: Environment. +* pauses in output: Screen Size. +* pending breakpoints: Set Breaks. +* PgDn: TUI Keys. +* PgUp: TUI Keys. +* physical address from linear address: DJGPP Native. +* pipes: Starting. +* po (print-object): The Print Command with Objective-C. +* pointer values, in file-i/o protocol: Pointer values. +* pointer, finding referent: Print Settings. +* possible-completions (M-?): Commands For Completion. +* post-commands: Prompting. +* post-overload-choice: Prompting. +* post-prompt: Prompting. +* post-prompt-for-continue: Prompting. +* post-query: Prompting. +* pre-commands: Prompting. +* pre-overload-choice: Prompting. +* pre-prompt: Prompting. +* pre-prompt-for-continue: Prompting. +* pre-query: Prompting. +* prefix-meta (): Miscellaneous Commands. +* premature return from system calls: Thread Stops. +* preprocessor macro expansion, showing the results of: Macros. +* previous-history (C-p): Commands For History. +* print: Data. +* print an Objective-C object description: The Print Command with Objective-C. +* print settings: Print Settings. +* print-object: The Print Command with Objective-C. +* printf: Output. +* printing data: Data. +* process image: SVR4 Process Information. +* processes, multiple: Processes. +* profiling GDB: Maintenance Commands. +* prompt <1>: Prompting. +* prompt: Prompt. +* prompt-for-continue: Prompting. +* protocol basics, file-i/o: Protocol basics. +* protocol specific representation of datatypes, in file-i/o protocol: Protocol specific representation of datatypes. +* protocol, GDB remote serial: Overview. +* ptype: Symbols. +* putDebugChar: Bootstrapping. +* pwd: Working Directory. +* q (quit): Quitting GDB. +* q (SingleKey TUI key): TUI Single Key Mode. +* Q packet: Packets. +* q packet: Packets. +* query: Prompting. +* quit: Errors. +* quit [EXPRESSION]: Quitting GDB. +* quoted-insert (C-q or C-v): Commands For Text. +* quotes in commands: Completion. +* quoting names: Symbols. +* r (run): Starting. +* r (SingleKey TUI key): TUI Single Key Mode. +* R packet: Packets. +* r packet: Packets. +* raise exceptions: Set Catchpoints. +* range checking: Type Checking. +* ranges of breakpoints: Breakpoints. +* rbreak: Set Breaks. +* re-read-init-file (C-x C-r): Miscellaneous Commands. +* read, file-i/o system call: read. +* reading symbols from relocatable object files: Files. +* reading symbols immediately: Files. +* readline: Editing. +* readnow: Files. +* recent tracepoint number: Create and Delete Tracepoints. +* redirection: Input/Output. +* redraw-current-line (): Commands For Moving. +* reference card: Formatting Documentation. +* reference declarations: C plus plus expressions. +* refresh: TUI Commands. +* register stack, AMD29K: A29K. +* registers: Registers. +* regular expression: Set Breaks. +* reloading symbols: Symbols. +* reloading the overlay table: Overlay Commands. +* relocatable object files, reading symbols from: Files. +* remote connection without stubs: Server. +* remote debugging: Remote. +* remote programs, interrupting: Connecting. +* remote protocol, field separator: Overview. +* remote serial debugging summary: Debug Session. +* remote serial debugging, overview: remote stub. +* remote serial protocol: Overview. +* remote serial stub: Stub Contents. +* remote serial stub list: remote stub. +* remote serial stub, initialization: Stub Contents. +* remote serial stub, main routine: Stub Contents. +* remote stub, example: remote stub. +* remote stub, support routines: Bootstrapping. +* remotedebug, MIPS protocol: MIPS Embedded. +* remotetimeout: Sparclet. +* remove actions from a tracepoint: Tracepoint Actions. +* rename, file-i/o system call: rename. +* Renesas: remote stub. +* Renesas SH download: H8/300. +* repeating command sequences: Command Syntax. +* repeating commands: Command Syntax. +* reporting bugs in GDB: GDB Bugs. +* response time, MIPS debugging: MIPS. +* restore: Dump/Restore Files. +* restore data from a file: Dump/Restore Files. +* result records in GDB/MI: GDB/MI Result Records. +* resuming execution: Continuing and Stepping. +* RET (repeat last command): Command Syntax. +* retransmit-timeout, MIPS protocol: MIPS Embedded. +* return: Returning. +* returning from a function: Returning. +* reverse-search: Search. +* reverse-search-history (C-r): Commands For History. +* revert-line (M-r): Miscellaneous Commands. +* Right: TUI Keys. +* run: Starting. +* running: Starting. +* running and debugging Sparclet programs: Sparclet Execution. +* running VxWorks tasks: VxWorks Attach. +* running, on Sparclet: Sparclet. +* rwatch: Set Watchpoints. +* s (SingleKey TUI key): TUI Single Key Mode. +* s (step): Continuing and Stepping. +* S packet: Packets. +* s packet: Packets. +* save tracepoints for future sessions: save-tracepoints. +* save-tracepoints: save-tracepoints. +* saving symbol table: Files. +* scope: M2 Scope. +* search: Search. +* searching: Search. +* section: Files. +* segment descriptor tables: DJGPP Native. +* select trace snapshot: tfind. +* select-frame: Frames. +* selected frame: Stack. +* selecting frame silently: Frames. +* self-insert (a, b, A, 1, !, ...): Commands For Text. +* separate debugging information files: Separate Debug Files. +* sequence-id, for GDB remote: Overview. +* serial connections, debugging: Debugging Output. +* serial device, Renesas micros: Renesas Boards. +* serial line speed, Renesas micros: Renesas Boards. +* serial line, target remote: Connecting. +* serial protocol, GDB remote: Overview. +* server prefix for annotations: Server Prefix. +* set: Help. +* set args: Arguments. +* set auto-solib-add: Files. +* set auto-solib-limit: Files. +* set backtrace limit: Backtrace. +* set backtrace past-main: Backtrace. +* set breakpoint pending: Set Breaks. +* set charset: Character Sets. +* set check range: Range Checking. +* set check type: Type Checking. +* set check, range: Range Checking. +* set check, type: Type Checking. +* set coerce-float-to-double: ABI. +* set complaints: Messages/Warnings. +* set confirm: Messages/Warnings. +* set cp-abi: ABI. +* set debug arch: Debugging Output. +* set debug event: Debugging Output. +* set debug expression: Debugging Output. +* set debug frame: Debugging Output. +* set debug overload: Debugging Output. +* set debug remote: Debugging Output. +* set debug serial: Debugging Output. +* set debug target: Debugging Output. +* set debug varobj: Debugging Output. +* set debug-file-directory: Separate Debug Files. +* set debugevents: Cygwin Native. +* set debugexceptions: Cygwin Native. +* set debugexec: Cygwin Native. +* set debugmemory: Cygwin Native. +* set demangle-style: Print Settings. +* set disassembly-flavor: Machine Code. +* set editing: Editing. +* set endian auto: Byte Order. +* set endian big: Byte Order. +* set endian little: Byte Order. +* set environment: Environment. +* set extension-language: Show. +* set follow-fork-mode: Processes. +* set gnutarget: Target Commands. +* set height: Screen Size. +* set history expansion: History. +* set history filename: History. +* set history save: History. +* set history size: History. +* set host-charset: Character Sets. +* set input-radix: Numbers. +* set language: Manually. +* set listsize: List. +* set logging: Logging output. +* set machine: Renesas Special. +* set max-user-call-depth: Define. +* set memory MOD: H8/500. +* set mipsfpu: MIPS Embedded. +* set new-console: Cygwin Native. +* set new-group: Cygwin Native. +* set opaque-type-resolution: Symbols. +* set os: KOD. +* set osabi: ABI. +* set output-radix: Numbers. +* set overload-resolution: Debugging C plus plus. +* set print address: Print Settings. +* set print array: Print Settings. +* set print asm-demangle: Print Settings. +* set print demangle: Print Settings. +* set print elements: Print Settings. +* set print max-symbolic-offset: Print Settings. +* set print null-stop: Print Settings. +* set print object: Print Settings. +* set print pretty: Print Settings. +* set print sevenbit-strings: Print Settings. +* set print static-members: Print Settings. +* set print symbol-filename: Print Settings. +* set print union: Print Settings. +* set print vtbl: Print Settings. +* set processor ARGS: MIPS Embedded. +* set prompt: Prompt. +* set remote hardware-breakpoint-limit: Remote configuration. +* set remote hardware-watchpoint-limit: Remote configuration. +* set remote system-call-allowed 0: The system call. +* set remote system-call-allowed 1: The system call. +* set remotedebug, MIPS protocol: MIPS Embedded. +* set retransmit-timeout: MIPS Embedded. +* set rstack_high_address: A29K. +* set shell: Cygwin Native. +* set solib-absolute-prefix: Files. +* set solib-search-path: Files. +* set step-mode: Continuing and Stepping. +* set symbol-reloading: Symbols. +* set target-charset: Character Sets. +* set timeout: MIPS Embedded. +* set tracepoint: Create and Delete Tracepoints. +* set trust-readonly-sections: Files. +* set tui active-border-mode: TUI Configuration. +* set tui border-kind: TUI Configuration. +* set tui border-mode: TUI Configuration. +* set variable: Assignment. +* set verbose: Messages/Warnings. +* set width: Screen Size. +* set write: Patching. +* set-mark (C-@): Miscellaneous Commands. +* set_debug_traps: Stub Contents. +* setting variables: Assignment. +* setting watchpoints: Set Watchpoints. +* SH: remote stub. +* sh-stub.c: remote stub. +* share: Files. +* shared libraries: Files. +* sharedlibrary: Files. +* shell: Shell Commands. +* shell escape: Shell Commands. +* show: Help. +* show args: Arguments. +* show auto-solib-add: Files. +* show auto-solib-limit: Files. +* show backtrace limit: Backtrace. +* show backtrace past-main: Backtrace. +* show breakpoint pending: Set Breaks. +* show charset: Character Sets. +* show check range: Range Checking. +* show check type: Type Checking. +* show complaints: Messages/Warnings. +* show confirm: Messages/Warnings. +* show convenience: Convenience Vars. +* show copying: Help. +* show cp-abi: ABI. +* show debug arch: Debugging Output. +* show debug event: Debugging Output. +* show debug expression: Debugging Output. +* show debug frame: Debugging Output. +* show debug overload: Debugging Output. +* show debug remote: Debugging Output. +* show debug serial: Debugging Output. +* show debug target: Debugging Output. +* show debug varobj: Debugging Output. +* show debug-file-directory: Separate Debug Files. +* show demangle-style: Print Settings. +* show directories: Source Path. +* show editing: Editing. +* show environment: Environment. +* show gnutarget: Target Commands. +* show height: Screen Size. +* show history: History. +* show host-charset: Character Sets. +* show input-radix: Numbers. +* show language: Show. +* show listsize: List. +* show logging: Logging output. +* show machine: Renesas Special. +* show max-user-call-depth: Define. +* show mipsfpu: MIPS Embedded. +* show new-console: Cygwin Native. +* show new-group: Cygwin Native. +* show opaque-type-resolution: Symbols. +* show os: KOD. +* show osabi: ABI. +* show output-radix: Numbers. +* show paths: Environment. +* show print address: Print Settings. +* show print array: Print Settings. +* show print asm-demangle: Print Settings. +* show print demangle: Print Settings. +* show print elements: Print Settings. +* show print max-symbolic-offset: Print Settings. +* show print object: Print Settings. +* show print pretty: Print Settings. +* show print sevenbit-strings: Print Settings. +* show print static-members: Print Settings. +* show print symbol-filename: Print Settings. +* show print union: Print Settings. +* show print vtbl: Print Settings. +* show processor: MIPS Embedded. +* show prompt: Prompt. +* show remote system-call-allowed: The system call. +* show remotedebug, MIPS protocol: MIPS Embedded. +* show retransmit-timeout: MIPS Embedded. +* show rstack_high_address: A29K. +* show shell: Cygwin Native. +* show solib-absolute-prefix: Files. +* show solib-search-path: Files. +* show symbol-reloading: Symbols. +* show target-charset: Character Sets. +* show timeout: MIPS Embedded. +* show user: Define. +* show values: Value History. +* show verbose: Messages/Warnings. +* show version: Help. +* show warranty: Help. +* show width: Screen Size. +* show write: Patching. +* show-all-if-ambiguous: Readline Init File Syntax. +* shows: History. +* si (stepi): Continuing and Stepping. +* signal <1>: Annotations for Running. +* signal: Signaling. +* signal-name: Annotations for Running. +* signal-name-end: Annotations for Running. +* signal-string: Annotations for Running. +* signal-string-end: Annotations for Running. +* signalled: Annotations for Running. +* signals: Signals. +* silent: Break Commands. +* sim: Z8000. +* simulator, Z8000: Z8000. +* size of screen: Screen Size. +* software watchpoints: Set Watchpoints. +* source <1>: Source Annotations. +* source: Command Files. +* source path: Source Path. +* Sparc: remote stub. +* sparc-stub.c: remote stub. +* sparcl-stub.c: remote stub. +* Sparclet: Sparclet. +* SparcLite: remote stub. +* speed: Renesas Boards. +* spr: OpenRISC 1000. +* ST2000 auxiliary commands: ST2000. +* st2000 CMD: ST2000. +* stack frame: Frames. +* stack on Alpha: MIPS. +* stack on MIPS: MIPS. +* stack traces: Backtrace. +* stacking targets: Active Targets. +* start a new trace experiment: Starting and Stopping Trace Experiment. +* start-kbd-macro (C-x (): Keyboard Macros. +* starting <1>: Annotations for Running. +* starting: Starting. +* stat, file-i/o system call: stat/fstat. +* status of trace data collection: Starting and Stopping Trace Experiment. +* status output in GDB/MI: GDB/MI Output Syntax. +* STDBUG commands (ST2000): ST2000. +* step: Continuing and Stepping. +* stepi: Continuing and Stepping. +* stepping: Continuing and Stepping. +* stepping into functions with no line info: Continuing and Stepping. +* stop a running trace experiment: Starting and Stopping Trace Experiment. +* stop reply packets: Stop Reply Packets. +* stop, a pseudo-command: Hooks. +* stopped threads: Thread Stops. +* stopping: Annotations for Running. +* stream records in GDB/MI: GDB/MI Stream Records. +* struct stat, in file-i/o protocol: struct stat. +* struct timeval, in file-i/o protocol: struct timeval. +* stub example, remote debugging: remote stub. +* stupid questions: Messages/Warnings. +* switching threads: Threads. +* switching threads automatically: Threads. +* symbol decoding style, C++: Print Settings. +* symbol dump: Symbols. +* symbol from address: Symbols. +* symbol names: Symbols. +* symbol overloading: Breakpoint Menus. +* symbol table: Files. +* symbol tables, listing GDB's internal: Symbols. +* symbol-file: Files. +* symbols, reading from relocatable object files: Files. +* symbols, reading immediately: Files. +* sysinfo: DJGPP Native. +* system call, file-i/o protocol: The system call. +* system calls and thread breakpoints: Thread Stops. +* system, file-i/o system call: system. +* T packet: Packets. +* t packet: Packets. +* T packet reply: Stop Reply Packets. +* target: Targets. +* target abug: M68K. +* target array: MIPS Embedded. +* target byte order: Byte Order. +* target character set: Character Sets. +* target core: Target Commands. +* target cpu32bug: M68K. +* target dbug: M68K. +* target ddb PORT: MIPS Embedded. +* target dink32: PowerPC. +* target e7000, with H8/300: H8/300. +* target e7000, with Renesas ICE: Renesas ICE. +* target e7000, with Renesas SH: SH. +* target est: M68K. +* target exec: Target Commands. +* target hms, and serial protocol: Renesas Boards. +* target hms, with H8/300: H8/300. +* target hms, with Renesas SH: SH. +* target jtag: OpenRISC 1000. +* target lsi PORT: MIPS Embedded. +* target m32r: M32R/D. +* target m32rsdi: M32R/D. +* target mips PORT: MIPS Embedded. +* target nrom: Target Commands. +* target op50n: PA. +* target output in GDB/MI: GDB/MI Output Syntax. +* target pmon PORT: MIPS Embedded. +* target ppcbug: PowerPC. +* target ppcbug1: PowerPC. +* target r3900: MIPS Embedded. +* target rdi: ARM. +* target rdp: ARM. +* target remote: Target Commands. +* target rom68k: M68K. +* target rombug: M68K. +* target sds: PowerPC. +* target sh3, with H8/300: H8/300. +* target sh3, with SH: SH. +* target sh3e, with H8/300: H8/300. +* target sh3e, with SH: SH. +* target sim: Target Commands. +* target sim, with Z8000: Z8000. +* target sparclite: Sparclite. +* target vxworks: VxWorks. +* target w89k: PA. +* tbreak: Set Breaks. +* TCP port, target remote: Connecting. +* tdump: tdump. +* terminal: Input/Output. +* Text User Interface: TUI. +* tfind: tfind. +* thbreak: Set Breaks. +* this, inside C++ member functions: C plus plus expressions. +* thread apply: Threads. +* thread breakpoints: Thread Stops. +* thread breakpoints and system calls: Thread Stops. +* thread identifier (GDB): Threads. +* thread identifier (system): Threads. +* thread identifier (system), on HP-UX: Threads. +* thread number: Threads. +* thread THREADNO: Threads. +* threads and watchpoints: Set Watchpoints. +* threads of execution: Threads. +* threads, automatic switching: Threads. +* threads, continuing: Thread Stops. +* threads, stopped: Thread Stops. +* timeout, MIPS protocol: MIPS Embedded. +* trace: Create and Delete Tracepoints. +* trace experiment, status of: Starting and Stopping Trace Experiment. +* tracebacks: Backtrace. +* tracepoint actions: Tracepoint Actions. +* tracepoint data, display: tdump. +* tracepoint deletion: Create and Delete Tracepoints. +* tracepoint number: Create and Delete Tracepoints. +* tracepoint pass count: Tracepoint Passcounts. +* tracepoint variables: Tracepoint Variables. +* tracepoints: Tracepoints. +* translating between character sets: Character Sets. +* transpose-chars (C-t): Commands For Text. +* transpose-words (M-t): Commands For Text. +* tstart: Starting and Stopping Trace Experiment. +* tstatus: Starting and Stopping Trace Experiment. +* tstop: Starting and Stopping Trace Experiment. +* tty: Input/Output. +* TUI: TUI. +* TUI commands: TUI Commands. +* TUI configuration variables: TUI Configuration. +* TUI key bindings: TUI Keys. +* tui reg: TUI Commands. +* TUI single key mode: TUI Single Key Mode. +* type casting memory: Expressions. +* type checking: Checks. +* type conversions in C++: C plus plus expressions. +* u (SingleKey TUI key): TUI Single Key Mode. +* u (until): Continuing and Stepping. +* UDP port, target remote: Connecting. +* undisplay: Auto Display. +* undo (C-_ or C-x C-u): Miscellaneous Commands. +* universal-argument (): Numeric Arguments. +* unix-line-discard (C-u): Commands For Killing. +* unix-word-rubout (C-w): Commands For Killing. +* unknown address, locating: Output Formats. +* unlink, file-i/o system call: unlink. +* unmap an overlay: Overlay Commands. +* unmapped overlays: How Overlays Work. +* unset environment: Environment. +* unsupported languages: Unsupported languages. +* until: Continuing and Stepping. +* Up: TUI Keys. +* up: Selection. +* up-silently: Selection. +* upcase-word (M-u): Commands For Text. +* update: TUI Commands. +* user-defined command: Define. +* user-defined macros: Macros. +* v (SingleKey TUI key): TUI Single Key Mode. +* value history: Value History. +* variable name conflict: Variables. +* variable objects in GDB/MI: GDB/MI Variable Objects. +* variable values, wrong: Variables. +* variables, readline: Readline Init File Syntax. +* variables, setting: Assignment. +* vCont packet: Packets. +* vCont? packet: Packets. +* vector unit: Vector Unit. +* vector, auxiliary: Auxiliary Vector. +* version number: Help. +* visible-stats: Readline Init File Syntax. +* VxWorks: VxWorks. +* vxworks-timeout: VxWorks. +* w (SingleKey TUI key): TUI Single Key Mode. +* watch: Set Watchpoints. +* watchpoint: Annotations for Running. +* watchpoints: Breakpoints. +* watchpoints and threads: Set Watchpoints. +* whatis: Symbols. +* where: Backtrace. +* while: Define. +* while-stepping (tracepoints): Tracepoint Actions. +* wild pointer, interpreting: Print Settings. +* winheight: TUI Commands. +* word completion: Completion. +* working directory: Source Path. +* working directory (of your program): Working Directory. +* working language: Languages. +* write, file-i/o system call: write. +* writing into corefiles: Patching. +* writing into executables: Patching. +* wrong values: Variables. +* x (examine memory): Memory. +* X packet: Packets. +* x(examine), and info line: Machine Code. +* yank (C-y): Commands For Killing. +* yank-last-arg (M-. or M-_): Commands For History. +* yank-nth-arg (M-C-y): Commands For History. +* yank-pop (M-y): Commands For Killing. +* yanking text: Readline Killing Commands. +* z packet: Packets. +* Z packets: Packets. +* Z0 packet: Packets. +* z0 packet: Packets. +* Z1 packet: Packets. +* z1 packet: Packets. +* Z2 packet: Packets. +* z2 packet: Packets. +* Z3 packet: Packets. +* z3 packet: Packets. +* Z4 packet: Packets. +* z4 packet: Packets. +* Z8000: Z8000. +* Zilog Z8000 simulator: Z8000. +* {TYPE}: Expressions. + + diff --git a/contrib/gdb/gdb/doc/gdb.texinfo b/contrib/gdb/gdb/doc/gdb.texinfo index 04a0624dbdc..772d1ebf128 100644 --- a/contrib/gdb/gdb/doc/gdb.texinfo +++ b/contrib/gdb/gdb/doc/gdb.texinfo @@ -1,6 +1,6 @@ \input texinfo @c -*-texinfo-*- @c Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, -@c 1999, 2000, 2001, 2002 +@c 1999, 2000, 2001, 2002, 2003, 2004 @c Free Software Foundation, Inc. @c @c %**start of header @@ -28,30 +28,31 @@ @syncodeindex fn cp @c !!set GDB manual's edition---not the same as GDB version! +@c This is updated by GNU Press. @set EDITION Ninth -@c !!set GDB manual's revision date -@set DATE December 2001 +@c !!set GDB edit command default editor +@set EDITOR /bin/ex @c THIS MANUAL REQUIRES TEXINFO 4.0 OR LATER. @c This is a dir.info fragment to support semi-automated addition of @c manuals to an info tree. -@dircategory Programming & development tools. +@dircategory Software development @direntry -* Gdb: (gdb). The @sc{gnu} debugger. +* Gdb: (gdb). The GNU debugger. @end direntry @ifinfo This file documents the @sc{gnu} debugger @value{GDBN}. -This is the @value{EDITION} Edition, @value{DATE}, -of @cite{Debugging with @value{GDBN}: the @sc{gnu} Source-Level Debugger} -for @value{GDBN} Version @value{GDBVN}. +This is the @value{EDITION} Edition, of @cite{Debugging with +@value{GDBN}: the @sc{gnu} Source-Level Debugger} for @value{GDBN} +Version @value{GDBVN}. Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,@* - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or @@ -71,7 +72,6 @@ development.'' @subtitle The @sc{gnu} Source-Level Debugger @sp 1 @subtitle @value{EDITION} Edition, for @value{GDBN} version @value{GDBVN} -@subtitle @value{DATE} @author Richard Stallman, Roland Pesch, Stan Shebs, et al. @page @tex @@ -84,7 +84,7 @@ development.'' @vskip 0pt plus 1filll Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, -1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. @sp 2 Published by the Free Software Foundation @* 59 Temple Place - Suite 330, @* @@ -112,10 +112,10 @@ development.'' This file describes @value{GDBN}, the @sc{gnu} symbolic debugger. -This is the @value{EDITION} Edition, @value{DATE}, for @value{GDBN} Version +This is the @value{EDITION} Edition, for @value{GDBN} Version @value{GDBVN}. -Copyright (C) 1988-2002 Free Software Foundation, Inc. +Copyright (C) 1988-2004 Free Software Foundation, Inc. @menu * Summary:: Summary of @value{GDBN} @@ -128,6 +128,7 @@ Copyright (C) 1988-2002 Free Software Foundation, Inc. * Stack:: Examining the stack * Source:: Examining source files * Data:: Examining data +* Macros:: Preprocessor Macros * Tracepoints:: Debugging remote targets non-intrusively * Overlays:: Debugging programs that use overlays @@ -142,6 +143,7 @@ Copyright (C) 1988-2002 Free Software Foundation, Inc. * Controlling GDB:: Controlling @value{GDBN} * Sequences:: Canned sequences of commands * TUI:: @value{GDBN} Text User Interface +* Interpreters:: Command Interpreters * Emacs:: Using @value{GDBN} under @sc{gnu} Emacs * Annotations:: @value{GDBN}'s annotation interface. * GDB/MI:: @value{GDBN}'s Machine Interface. @@ -154,6 +156,7 @@ Copyright (C) 1988-2002 Free Software Foundation, Inc. * Installing GDB:: Installing GDB * Maintenance Commands:: Maintenance Commands * Remote Protocol:: GDB Remote Serial Protocol +* Agent Expressions:: The GDB Agent Expression Mechanism * Copying:: GNU General Public License says how you can copy and share GDB * GNU Free Documentation License:: The license for this documentation @@ -189,14 +192,13 @@ Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another. @end itemize -You can use @value{GDBN} to debug programs written in C and C++. +You can use @value{GDBN} to debug programs written in C and C@t{++}. For more information, see @ref{Support,,Supported languages}. For more information, see @ref{C,,C and C++}. -@cindex Chill @cindex Modula-2 -Support for Modula-2 and Chill is partial. For information on Modula-2, -see @ref{Modula-2,,Modula-2}. For information on Chill, see @ref{Chill}. +Support for Modula-2 is partial. For information on Modula-2, see +@ref{Modula-2,,Modula-2}. @cindex Pascal Debugging Pascal programs which use sets, subranges, file variables, or @@ -209,6 +211,9 @@ syntax. it may be necessary to refer to some variables with a trailing underscore. +@value{GDBN} can be used to debug programs written in Objective-C, +using either the Apple/NeXT or the GNU Objective-C runtime. + @menu * Free Software:: Freely redistributable software * Contributors:: Contributors to GDB @@ -342,7 +347,7 @@ omitted from this list, we would like to add your names! So that they may not regard their many labors as thankless, we particularly thank those who shepherded @value{GDBN} through major releases: -Andrew Cagney (releases 5.0 and 5.1); +Andrew Cagney (releases 6.1, 6.0, 5.3, 5.2, 5.1 and 5.0); Jim Blandy (release 4.18); Jason Molenda (release 4.17); Stan Shebs (release 4.14); @@ -368,7 +373,7 @@ Henkel-Wallace, Rich Pixley, Steve Chamberlain, and John Gilmore. David Johnson wrote the original COFF support; Pace Willison did the original support for encapsulated COFF. -Brent Benson of Harris Computer Systems contributed DWARF2 support. +Brent Benson of Harris Computer Systems contributed DWARF 2 support. Adam de Boor and Bradley Davis contributed the ISI Optimum V support. Per Bothner, Noboyuki Hikichi, and Alessandro Forin contributed MIPS @@ -388,8 +393,9 @@ Michael Tiemann contributed SPARC support. Tim Tucker contributed support for the Gould NP1 and Gould Powernode. Pace Willison contributed Intel 386 support. Jay Vosburgh contributed Symmetry support. +Marko Mlinar contributed OpenRISC 1000 support. -Andreas Schwab contributed M68K Linux support. +Andreas Schwab contributed M68K @sc{gnu}/Linux support. Rich Schaefer and Peter Schauer helped with support of SunOS shared libraries. @@ -412,12 +418,13 @@ Fred Fish wrote most of the support for Unix System Vr4. He also enhanced the command-completion support to cover C@t{++} overloaded symbols. -Hitachi America, Ltd. sponsored the support for H8/300, H8/500, and -Super-H processors. +Hitachi America (now Renesas America), Ltd. sponsored the support for +H8/300, H8/500, and Super-H processors. NEC sponsored the support for the v850, Vr4xxx, and Vr5xxx processors. -Mitsubishi sponsored the support for D10V, D30V, and M32R/D processors. +Mitsubishi (now Renesas) sponsored the support for D10V, D30V, and M32R/D +processors. Toshiba sponsored the support for the TX39 Mips processor. @@ -438,10 +445,10 @@ nearly innumerable bug fixes and cleanups throughout @value{GDBN}. The following people at the Hewlett-Packard Company contributed support for the PA-RISC 2.0 architecture, HP-UX 10.20, 10.30, and 11.0 (narrow mode), HP's implementation of kernel threads, HP's aC@t{++} -compiler, and the terminal user interface: Ben Krepp, Richard Title, -John Bishop, Susan Macchia, Kathy Mann, Satish Pai, India Paul, Steve -Rehrauer, and Elena Zannoni. Kim Haase provided HP-specific -information in this manual. +compiler, and the Text User Interface (nee Terminal User Interface): +Ben Krepp, Richard Title, John Bishop, Susan Macchia, Kathy Mann, +Satish Pai, India Paul, Steve Rehrauer, and Elena Zannoni. Kim Haase +provided HP-specific information in this manual. DJ Delorie ported @value{GDBN} to MS-DOS, for the DJGPP project. Robert Hoehne made significant contributions to the DJGPP port. @@ -462,6 +469,8 @@ Romig-Koch, Rob Savoye, Jamie Smith, Mike Stump, Ian Taylor, Angela Thomas, Michael Tiemann, Tom Tromey, Ron Unrau, Jim Wilson, and David Zuhn have made contributions both large and small. +Jim Blandy added support for preprocessor macros, while working for Red +Hat. @node Sample Session @chapter A Sample @value{GDBN} Session @@ -749,6 +758,7 @@ type @kbd{quit} or @kbd{C-d} to exit. * Invoking GDB:: How to start @value{GDBN} * Quitting GDB:: How to quit @value{GDBN} * Shell Commands:: How to use shell commands inside @value{GDBN} +* Logging output:: How to log @value{GDBN}'s output to a file @end menu @node Invoking GDB @@ -767,24 +777,24 @@ options may effectively be unavailable. The most usual way to start @value{GDBN} is with one argument, specifying an executable program: -@example +@smallexample @value{GDBP} @var{program} -@end example +@end smallexample @noindent You can also start with both an executable program and a core file specified: -@example +@smallexample @value{GDBP} @var{program} @var{core} -@end example +@end smallexample You can, instead, specify a process ID as a second argument, if you want to debug a running process: -@example +@smallexample @value{GDBP} @var{program} 1234 -@end example +@end smallexample @noindent would attach @value{GDBN} to process @code{1234} (unless you also have a file @@ -799,9 +809,9 @@ will warn you if it is unable to attach or to read core dumps. You can optionally have @code{@value{GDBP}} pass any arguments after the executable file to the inferior using @code{--args}. This option stops option processing. -@example +@smallexample gdb --args gcc -O2 -c foo.c -@end example +@end smallexample This will cause @code{@value{GDBP}} to debug @code{gcc}, and to set @code{gcc}'s command-line arguments (@pxref{Arguments}) to @samp{-O2 -c foo.c}. @@ -819,9 +829,9 @@ options. @value{GDBN} itself can remind you of the options available. @noindent Type -@example +@smallexample @value{GDBP} -help -@end example +@end smallexample @noindent to display all available options and briefly describe their use @@ -851,7 +861,7 @@ equivalent to the @samp{-c}/@samp{-p} option followed by that argument.) If the second argument begins with a decimal digit, @value{GDBN} will first attempt to attach to it as a process, and if that fails, attempt to open it as a corefile. If you have a corefile whose name begins with -a digit, you can prevent @value{GDBN} from treating it as a pid by +a digit, you can prevent @value{GDBN} from treating it as a pid by prefixing it with @file{./}, eg. @file{./12345}. If @value{GDBN} has not been configured to included core file support, @@ -891,7 +901,7 @@ file. @itemx -c @var{file} @cindex @code{--core} @cindex @code{-c} -Use file @var{file} as a core dump to examine. +Use file @var{file} as a core dump to examine. @item -c @var{number} @item -pid @var{number} @@ -950,9 +960,9 @@ information. (@xref{Files,,Commands to specify files}, for information on @file{.syms} files.) A simple @value{GDBN} invocation to do nothing but build a @file{.syms} file for future use is: -@example +@smallexample gdb -batch -nx -mapped -readnow programname -@end example +@end smallexample @node Mode Options @subsection Choosing modes @@ -991,9 +1001,9 @@ Batch mode may be useful for running @value{GDBN} as a filter, for example to download and run a program on another computer; in order to make this more useful, the message -@example +@smallexample Program exited normally. -@end example +@end smallexample @noindent (which is ordinarily issued whenever a program running under @@ -1045,12 +1055,15 @@ separate window. @cindex @code{--annotate} This option sets the @dfn{annotation level} inside @value{GDBN}. Its effect is identical to using @samp{set annotate @var{level}} -(@pxref{Annotations}). -Annotation level controls how much information does @value{GDBN} print -together with its prompt, values of expressions, source lines, and other -types of output. Level 0 is the normal, level 1 is for use when -@value{GDBN} is run as a subprocess of @sc{gnu} Emacs, level 2 is the -maximum annotation suitable for programs that control @value{GDBN}. +(@pxref{Annotations}). The annotation @var{level} controls how much +information @value{GDBN} prints together with its prompt, values of +expressions, source lines, and other types of output. Level 0 is the +normal, level 1 is for use when @value{GDBN} is run as a subprocess of +@sc{gnu} Emacs, level 3 is the maximum annotation suitable for programs +that control @value{GDBN}, and level 2 has been deprecated. + +The annotation mechanism has largely been superseeded by @sc{gdb/mi} +(@pxref{GDB/MI}). @item -async @cindex @code{--async} @@ -1099,12 +1112,13 @@ Run using @var{device} for your program's standard input and output. @c resolve the situation of these eventually @item -tui @cindex @code{--tui} -Activate the Terminal User Interface when starting. -The Terminal User Interface manages several text windows on the terminal, -showing source, assembly, registers and @value{GDBN} command outputs -(@pxref{TUI, ,@value{GDBN} Text User Interface}). -Do not use this option if you run @value{GDBN} from Emacs -(@pxref{Emacs, ,Using @value{GDBN} under @sc{gnu} Emacs}). +Activate the @dfn{Text User Interface} when starting. The Text User +Interface manages several text windows on the terminal, showing +source, assembly, registers and @value{GDBN} command outputs +(@pxref{TUI, ,@value{GDBN} Text User Interface}). Alternatively, the +Text User Interface can be enabled by invoking the program +@samp{gdbtui}. Do not use this option if you run @value{GDBN} from +Emacs (@pxref{Emacs, ,Using @value{GDBN} under @sc{gnu} Emacs}). @c @item -xdb @c @cindex @code{--xdb} @@ -1118,11 +1132,14 @@ Do not use this option if you run @value{GDBN} from Emacs Use the interpreter @var{interp} for interface with the controlling program or device. This option is meant to be set by programs which communicate with @value{GDBN} using it as a back end. +@xref{Interpreters, , Command Interpreters}. -@samp{--interpreter=mi} (or @samp{--interpreter=mi1}) causes -@value{GDBN} to use the @dfn{gdb/mi interface} (@pxref{GDB/MI, , The -@sc{gdb/mi} Interface}). The older @sc{gdb/mi} interface, included in -@value{GDBN} version 5.0 can be selected with @samp{--interpreter=mi0}. +@samp{--interpreter=mi} (or @samp{--interpreter=mi2}) causes +@value{GDBN} to use the @dfn{@sc{gdb/mi} interface} (@pxref{GDB/MI, , +The @sc{gdb/mi} Interface}) included since @var{GDBN} version 6.0. The +previous @sc{gdb/mi} interface, included in @value{GDBN} version 5.3 and +selected with @samp{--interpreter=mi1}, is deprecated. Earlier +@sc{gdb/mi} interfaces are no longer supported. @item -write @cindex @code{--write} @@ -1199,6 +1216,32 @@ Execute the @code{make} program with the specified arguments. This is equivalent to @samp{shell make @var{make-args}}. @end table +@node Logging output +@section Logging output +@cindex logging @value{GDBN} output + +You may want to save the output of @value{GDBN} commands to a file. +There are several commands to control @value{GDBN}'s logging. + +@table @code +@kindex set logging +@item set logging on +Enable logging. +@item set logging off +Disable logging. +@item set logging file @var{file} +Change the name of the current logfile. The default logfile is @file{gdb.txt}. +@item set logging overwrite [on|off] +By default, @value{GDBN} will append to the logfile. Set @code{overwrite} if +you want @code{set logging on} to overwrite the logfile instead. +@item set logging redirect [on|off] +By default, @value{GDBN} output will go to both the terminal and the logfile. +Set @code{redirect} if you want output to go only to the log file. +@kindex show logging +@item show logging +Show the current values of the logging settings. +@end table + @node Commands @chapter @value{GDBN} Commands @@ -1283,17 +1326,17 @@ enter it). For example, if you type @c complete accuracy in these examples; space introduced for clarity. @c If texinfo enhancements make it unnecessary, it would be nice to @c replace " @key" by "@key" in the following... -@example +@smallexample (@value{GDBP}) info bre @key{TAB} -@end example +@end smallexample @noindent @value{GDBN} fills in the rest of the word @samp{breakpoints}, since that is the only @code{info} subcommand beginning with @samp{bre}: -@example +@smallexample (@value{GDBP}) info breakpoints -@end example +@end smallexample @noindent You can either press @key{RET} at this point, to run the @code{info @@ -1313,7 +1356,7 @@ just sounds the bell. Typing @key{TAB} again displays all the function names in your program that begin with those characters, for example: -@example +@smallexample (@value{GDBP}) b make_ @key{TAB} @exdent @value{GDBN} sounds bell; press @key{TAB} again, to see: make_a_section_from_file make_environ @@ -1322,7 +1365,7 @@ make_blockvector make_pointer_type make_cleanup make_reference_type make_command make_symbol_completion_list (@value{GDBP}) b make_ -@end example +@end smallexample @noindent After displaying the available possibilities, @value{GDBN} copies your @@ -1355,22 +1398,22 @@ word-completion facilities in this situation, type a single quote @value{GDBN} that it may need to consider more information than usual when you press @key{TAB} or @kbd{M-?} to request word completion: -@example +@smallexample (@value{GDBP}) b 'bubble( @kbd{M-?} bubble(double,double) bubble(int,int) (@value{GDBP}) b 'bubble( -@end example +@end smallexample In some cases, @value{GDBN} can tell that completing a name requires using quotes. When this happens, @value{GDBN} inserts the quote for you (while completing as much as it can) if you do not type the quote in the first place: -@example +@smallexample (@value{GDBP}) b bub @key{TAB} @exdent @value{GDBN} alters your input line to the following, and rings a bell: (@value{GDBP}) b 'bubble( -@end example +@end smallexample @noindent In general, @value{GDBN} can tell that a quote is needed (and inserts it) if @@ -1609,6 +1652,16 @@ and addresses in the executable code. To request debugging information, specify the @samp{-g} option when you run the compiler. +Most compilers do not include information about preprocessor macros in +the debugging information if you specify the @option{-g} flag alone, +because this information is rather large. Version 3.1 of @value{NGCC}, +the @sc{gnu} C compiler, provides macro information if you specify the +options @option{-gdwarf-2} and @option{-g3}; the former option requests +debugging information in the Dwarf 2 format, and the latter requests +``extra information''. In the future, we hope to find more compact ways +to represent macro information, so that it can be included with +@option{-g} alone. + Many C compilers are unable to handle the @samp{-g} and @samp{-O} options together. Using those compilers, you cannot generate optimized executables containing debugging information. @@ -1806,9 +1859,9 @@ null value. For example, this command: -@example +@smallexample set env USER = foo -@end example +@end smallexample @noindent tells the debugged program, when subsequently run, that its user is named @@ -1879,9 +1932,9 @@ program is using. You can redirect your program's input and/or output using shell redirection with the @code{run} command. For example, -@example +@smallexample run > outfile -@end example +@end smallexample @noindent starts your program, diverting its output to the file @file{outfile}. @@ -1894,9 +1947,9 @@ argument, and causes this file to be the default for future @code{run} commands. It also resets the controlling terminal for the child process, for future @code{run} commands. For example, -@example +@smallexample tty /dev/ttyb -@end example +@end smallexample @noindent directs that processes started with subsequent @code{run} commands @@ -2055,9 +2108,9 @@ form @samp{[New @var{systag}]}. @var{systag} is a thread identifier whose form varies depending on the particular system. For example, on LynxOS, you might see -@example +@smallexample [New process 35 thread 27] -@end example +@end smallexample @noindent when @value{GDBN} notices a new thread. In contrast, on an SGI system, @@ -2126,9 +2179,9 @@ form @samp{[New @var{systag}]}. @var{systag} is a thread identifier whose form varies depending on the particular system. For example, on HP-UX, you see -@example +@smallexample [New thread 2 (system thread 26594)] -@end example +@end smallexample @noindent when @value{GDBN} notices a new thread. @@ -2155,7 +2208,7 @@ For example, @end table @c end table here to get a little more width for example -@example +@smallexample (@value{GDBP}) info threads * 3 system thread 26607 worker (wptr=0x7b09c318 "@@") \@* at quicksort.c:137 @@ -2163,7 +2216,7 @@ For example, from /usr/lib/libc.2 1 system thread 27905 0x7b003498 in _brk () \@* from /usr/lib/libc.2 -@end example +@end smallexample @table @code @kindex thread @var{threadno} @@ -2237,9 +2290,10 @@ get its process ID. Then tell @value{GDBN} (a new invocation of the child process (@pxref{Attach}). From that point on you can debug the child process just like any other process which you attached to. -On HP-UX (11.x and later only?), @value{GDBN} provides support for -debugging programs that create additional processes using the -@code{fork} or @code{vfork} function. +On some systems, @value{GDBN} provides support for debugging programs that +create additional processes using the @code{fork} or @code{vfork} functions. +Currently, the only platforms with this feature are HP-UX (11.x and later +only?) and GNU/Linux (kernel version 2.5.60 and later). By default, when a program forks, @value{GDBN} will continue to debug the parent process and the child process will run unimpeded. @@ -2263,8 +2317,6 @@ unimpeded. This is the default. The new process is debugged after a fork. The parent process runs unimpeded. -@item ask -The debugger will ask for one of the above choices. @end table @item show follow-fork-mode @@ -2390,6 +2442,7 @@ all breakpoint in that range are operated on. * Break Commands:: Breakpoint command lists * Breakpoint Menus:: Breakpoint menus * Error in Breakpoints:: ``Cannot insert breakpoints'' +* Breakpoint related warnings:: ``Breakpoint address adjusted...'' @end menu @node Set Breaks @@ -2494,6 +2547,8 @@ example, on the DSU, only two data breakpoints can be set at a time, and @value{GDBN} will reject this command if more than two are used. Delete or disable unused hardware breakpoints before setting new ones (@pxref{Disabling, ,Disabling}). @xref{Conditions, ,Break conditions}. +@xref{set remote hardware-breakpoint-limit}. + @kindex thbreak @item thbreak @var{args} @@ -2545,16 +2600,23 @@ Whether the breakpoint is marked to be disabled or deleted when hit. Enabled breakpoints are marked with @samp{y}. @samp{n} marks breakpoints that are not enabled. @item Address -Where the breakpoint is in your program, as a memory address. +Where the breakpoint is in your program, as a memory address. If the +breakpoint is pending (see below for details) on a future load of a shared library, the address +will be listed as @samp{}. @item What Where the breakpoint is in the source for your program, as a file and -line number. +line number. For a pending breakpoint, the original string passed to +the breakpoint command will be listed as it cannot be resolved until +the appropriate shared library is loaded in the future. @end table @noindent If a breakpoint is conditional, @code{info break} shows the condition on the line following the affected breakpoint; breakpoint commands, if any, -are listed after that. +are listed after that. A pending breakpoint is allowed to have a condition +specified for it. The condition is not parsed for validity until a shared +library is loaded that allows the pending breakpoint to resolve to a +valid location. @noindent @code{info break} with a breakpoint @@ -2577,6 +2639,58 @@ your program. There is nothing silly or meaningless about this. When the breakpoints are conditional, this is even useful (@pxref{Conditions, ,Break conditions}). +@cindex pending breakpoints +If a specified breakpoint location cannot be found, it may be due to the fact +that the location is in a shared library that is yet to be loaded. In such +a case, you may want @value{GDBN} to create a special breakpoint (known as +a @dfn{pending breakpoint}) that +attempts to resolve itself in the future when an appropriate shared library +gets loaded. + +Pending breakpoints are useful to set at the start of your +@value{GDBN} session for locations that you know will be dynamically loaded +later by the program being debugged. When shared libraries are loaded, +a check is made to see if the load resolves any pending breakpoint locations. +If a pending breakpoint location gets resolved, +a regular breakpoint is created and the original pending breakpoint is removed. + +@value{GDBN} provides some additional commands for controlling pending +breakpoint support: + +@kindex set breakpoint pending +@kindex show breakpoint pending +@table @code +@item set breakpoint pending auto +This is the default behavior. When @value{GDBN} cannot find the breakpoint +location, it queries you whether a pending breakpoint should be created. + +@item set breakpoint pending on +This indicates that an unrecognized breakpoint location should automatically +result in a pending breakpoint being created. + +@item set breakpoint pending off +This indicates that pending breakpoints are not to be created. Any +unrecognized breakpoint location results in an error. This setting does +not affect any pending breakpoints previously created. + +@item show breakpoint pending +Show the current behavior setting for creating pending breakpoints. +@end table + +@cindex operations allowed on pending breakpoints +Normal breakpoint operations apply to pending breakpoints as well. You may +specify a condition for a pending breakpoint and/or commands to run when the +breakpoint is reached. You can also enable or disable +the pending breakpoint. When you specify a condition for a pending breakpoint, +the parsing of the condition will be deferred until the point where the +pending breakpoint location is resolved. Disabling a pending breakpoint +tells @value{GDBN} to not attempt to resolve the breakpoint on any subsequent +shared library load. When a pending breakpoint is re-enabled, +@value{GDBN} checks to see if the location is already resolved. +This is done because any number of shared library loads could have +occurred since the time the breakpoint was disabled and one or more +of these loads could resolve the location. + @cindex negative breakpoint numbers @cindex internal @value{GDBN} breakpoints @value{GDBN} itself sometimes sets breakpoints in your program for @@ -2604,7 +2718,7 @@ times slower than normal execution. (But this may still be worth it, to catch errors where you have no clue what part of your program is the culprit.) -On some systems, such as HP-UX, Linux and some other x86-based targets, +On some systems, such as HP-UX, @sc{gnu}/Linux and some other x86-based targets, @value{GDBN} includes support for hardware watchpoints, which do not slow down the running of your program. @@ -2639,9 +2753,9 @@ statement, not the instruction, after the change occurs. When you issue the @code{watch} command, @value{GDBN} reports -@example +@smallexample Hardware watchpoint @var{num}: @var{expr} -@end example +@end smallexample @noindent if it was able to set a hardware watchpoint. @@ -2730,6 +2844,8 @@ when a non-current thread's activity changes the expression. (Hardware watchpoints, in contrast, watch an expression in all threads.) @end quotation +@xref{set remote hardware-watchpoint-limit}. + @node Set Catchpoints @subsection Setting catchpoints @cindex catchpoints, setting @@ -2820,11 +2936,11 @@ knowledge of the implementation. In the case of @sc{gnu} C@t{++}, exceptions ar raised by calling a library function named @code{__raise_exception} which has the following ANSI C interface: -@example +@smallexample /* @var{addr} is where the exception identifier is stored. @var{id} is the exception identifier. */ void __raise_exception (void **addr, void *id); -@end example +@end smallexample @noindent To make the debugger catch all exceptions before any stack @@ -3017,9 +3133,9 @@ referents in the context of your breakpoint. If @var{expression} uses symbols not referenced in the context of the breakpoint, @value{GDBN} prints an error message: -@example +@smallexample No symbol "foo" in current context. -@end example +@end smallexample @noindent @value{GDBN} does @@ -3128,14 +3244,14 @@ breakpoints. @xref{Output, ,Commands for controlled output}. For example, here is how you could use breakpoint commands to print the value of @code{x} at entry to @code{foo} whenever @code{x} is positive. -@example +@smallexample break foo if x>0 commands silent printf "x is %d\n",x cont end -@end example +@end smallexample One application for breakpoint commands is to compensate for one bug so you can test for another. Put a breakpoint just after the erroneous line @@ -3145,21 +3261,22 @@ to any variables that need them. End with the @code{continue} command so that your program does not stop, and start with the @code{silent} command so that no output is produced. Here is an example: -@example +@smallexample break 403 commands silent set x = y + 4 cont end -@end example +@end smallexample @node Breakpoint Menus @subsection Breakpoint menus @cindex overloading @cindex symbol overloading -Some programming languages (notably C@t{++}) permit a single function name +Some programming languages (notably C@t{++} and Objective-C) permit a +single function name to be defined several times, for application in different contexts. This is called @dfn{overloading}. When a function name is overloaded, @samp{break @var{function}} is not enough to tell @value{GDBN} where you want @@ -3211,10 +3328,10 @@ any other process is running that program. In this situation, attempting to run or continue a program with a breakpoint causes @value{GDBN} to print an error message: -@example +@smallexample Cannot insert breakpoints. The same program may be running in another process. -@end example +@end smallexample When this happens, you have three ways to proceed: @@ -3253,6 +3370,58 @@ watchpoints it needs to insert. When this message is printed, you need to disable or remove some of the hardware-assisted breakpoints and watchpoints, and then continue. +@node Breakpoint related warnings +@subsection ``Breakpoint address adjusted...'' +@cindex breakpoint address adjusted + +Some processor architectures place constraints on the addresses at +which breakpoints may be placed. For architectures thus constrained, +@value{GDBN} will attempt to adjust the breakpoint's address to comply +with the constraints dictated by the architecture. + +One example of such an architecture is the Fujitsu FR-V. The FR-V is +a VLIW architecture in which a number of RISC-like instructions may be +bundled together for parallel execution. The FR-V architecture +constrains the location of a breakpoint instruction within such a +bundle to the instruction with the lowest address. @value{GDBN} +honors this constraint by adjusting a breakpoint's address to the +first in the bundle. + +It is not uncommon for optimized code to have bundles which contain +instructions from different source statements, thus it may happen that +a breakpoint's address will be adjusted from one source statement to +another. Since this adjustment may significantly alter @value{GDBN}'s +breakpoint related behavior from what the user expects, a warning is +printed when the breakpoint is first set and also when the breakpoint +is hit. + +A warning like the one below is printed when setting a breakpoint +that's been subject to address adjustment: + +@smallexample +warning: Breakpoint address adjusted from 0x00010414 to 0x00010410. +@end smallexample + +Such warnings are printed both for user settable and @value{GDBN}'s +internal breakpoints. If you see one of these warnings, you should +verify that a breakpoint set at the adjusted address will have the +desired affect. If not, the breakpoint in question may be removed and +other breakpoints may be set which will have the desired behavior. +E.g., it may be sufficient to place the breakpoint at a later +instruction. A conditional breakpoint may also be useful in some +cases to prevent the breakpoint from triggering too often. + +@value{GDBN} will also issue a warning when stopping at one of these +adjusted breakpoints: + +@smallexample +warning: Breakpoint 1 address previously adjusted from 0x00010414 +to 0x00010410. +@end smallexample + +When this warning is encountered, it may be too late to take remedial +action except in cases where the breakpoint is hit earlier or more +frequently than expected. @node Continuing and Stepping @section Continuing and stepping @@ -3419,13 +3588,13 @@ example, in the following excerpt from a debugging session, the @code{f} (@code{frame}) command shows that execution is stopped at line @code{206}; yet when we use @code{until}, we get to line @code{195}: -@example +@smallexample (@value{GDBP}) f #0 main (argc=4, argv=0xf7fffae8) at m4.c:206 206 expand_input(); (@value{GDBP}) until 195 for ( ; argc > 0; NEXTARG) @{ -@end example +@end smallexample This happened because, for execution efficiency, the compiler had generated code for the loop closure test at the end, rather than the @@ -3444,8 +3613,35 @@ argument. Continue running your program until either the specified location is reached, or the current stack frame returns. @var{location} is any of the forms of argument acceptable to @code{break} (@pxref{Set Breaks, -,Setting breakpoints}). This form of the command uses breakpoints, -and hence is quicker than @code{until} without an argument. +,Setting breakpoints}). This form of the command uses breakpoints, and +hence is quicker than @code{until} without an argument. The specified +location is actually reached only if it is in the current frame. This +implies that @code{until} can be used to skip over recursive function +invocations. For instance in the code below, if the current location is +line @code{96}, issuing @code{until 99} will execute the program up to +line @code{99} in the same invocation of factorial, i.e. after the inner +invocations have returned. + +@smallexample +94 int factorial (int value) +95 @{ +96 if (value > 1) @{ +97 value *= factorial (value - 1); +98 @} +99 return (value); +100 @} +@end smallexample + + +@kindex advance @var{location} +@itemx advance @var{location} +Continue running the program up to the given location. An argument is +required, anything of the same form as arguments for the @code{break} +command. Execution will also stop upon exit from the current stack +frame. This command is similar to @code{until}, but @code{advance} will +not skip over recursive function calls, and the target location doesn't +have to be in the same frame as the current one. + @kindex stepi @kindex si @r{(@code{stepi})} @@ -3624,6 +3820,47 @@ allows you to examine the overall state of the program, including switching between threads, without worrying that things may change underfoot. +@cindex thread breakpoints and system calls +@cindex system calls and thread breakpoints +@cindex premature return from system calls +There is an unfortunate side effect. If one thread stops for a +breakpoint, or for some other reason, and another thread is blocked in a +system call, then the system call may return prematurely. This is a +consequence of the interaction between multiple threads and the signals +that @value{GDBN} uses to implement breakpoints and other events that +stop execution. + +To handle this problem, your program should check the return value of +each system call and react appropriately. This is good programming +style anyways. + +For example, do not write code like this: + +@smallexample + sleep (10); +@end smallexample + +The call to @code{sleep} will return early if a different thread stops +at a breakpoint or for some other reason. + +Instead, write this: + +@smallexample + int unslept = 10; + while (unslept > 0) + unslept = sleep (unslept); +@end smallexample + +A system call is allowed to return early, so the system is still +conforming to its specification. But @value{GDBN} does cause your +multi-threaded program to behave differently than it would without +@value{GDBN}. + +Also, @value{GDBN} uses internal breakpoints in the thread library to +monitor certain events such as thread creation and thread destruction. +When such an event happens, a system call in another thread may return +prematurely, even though your program does not appear to stop. + @cindex continuing threads @cindex threads, continuing Conversely, whenever you restart the program, @emph{all} threads start @@ -3747,9 +3984,9 @@ frames in @value{GDBN} commands. @cindex frameless execution Some compilers provide a way to compile functions so that they operate without stack frames. (For example, the @value{GCC} option -@example +@smallexample @samp{-fomit-frame-pointer} -@end example +@end smallexample generates functions without a frame.) This is occasionally done with heavily used library functions to save the frame setup time. @value{GDBN} has limited facilities for dealing @@ -3839,6 +4076,42 @@ The display for frame zero does not begin with a program counter value, indicating that your program has stopped at the beginning of the code for line @code{993} of @code{builtin.c}. +@kindex set backtrace past-main +@kindex show backtrace past-main +@kindex set backtrace limit +@kindex show backtrace limit + +Most programs have a standard user entry point---a place where system +libraries and startup code transition into user code. For C this is +@code{main}. When @value{GDBN} finds the entry function in a backtrace +it will terminate the backtrace, to avoid tracing into highly +system-specific (and generally uninteresting) code. + +If you need to examine the startup code, or limit the number of levels +in a backtrace, you can change this behavior: + +@table @code +@item set backtrace past-main +@itemx set backtrace past-main on +Backtraces will continue past the user entry point. + +@item set backtrace past-main off +Backtraces will stop when they encounter the user entry point. This is the +default. + +@item show backtrace past-main +Display the current user entry point backtrace policy. + +@item set backtrace limit @var{n} +@itemx set backtrace limit 0 +@cindex backtrace limit +Limit the backtrace to @var{n} levels. A value of zero means +unlimited. + +@item show backtrace limit +Display the current limit on backtrace levels. +@end table + @node Selection @section Selecting a frame @@ -3911,7 +4184,10 @@ For example: After such a printout, the @code{list} command with no arguments prints ten lines centered on the point of execution in the frame. -@xref{List, ,Printing source lines}. +You can also edit the program at the point of execution with your favorite +editing program by typing @code{edit}. +@xref{List, ,Printing source lines}, +for details. @table @code @kindex down-silently @@ -4018,6 +4294,7 @@ prefer to use Emacs facilities to view source; see @ref{Emacs, ,Using @menu * List:: Printing source lines +* Edit:: Editing source files * Search:: Searching source files * Source Path:: Specifying source directories * Machine Code:: Source and machine code @@ -4140,6 +4417,69 @@ Specifies the line containing the program address @var{address}. @var{address} may be any expression. @end table +@node Edit +@section Editing source files +@cindex editing source files + +@kindex edit +@kindex e @r{(@code{edit})} +To edit the lines in a source file, use the @code{edit} command. +The editing program of your choice +is invoked with the current line set to +the active line in the program. +Alternatively, there are several ways to specify what part of the file you +want to print if you want to see other parts of the program. + +Here are the forms of the @code{edit} command most commonly used: + +@table @code +@item edit +Edit the current source file at the active line number in the program. + +@item edit @var{number} +Edit the current source file with @var{number} as the active line number. + +@item edit @var{function} +Edit the file containing @var{function} at the beginning of its definition. + +@item edit @var{filename}:@var{number} +Specifies line @var{number} in the source file @var{filename}. + +@item edit @var{filename}:@var{function} +Specifies the line that begins the body of the +function @var{function} in the file @var{filename}. You only need the +file name with a function name to avoid ambiguity when there are +identically named functions in different source files. + +@item edit *@var{address} +Specifies the line containing the program address @var{address}. +@var{address} may be any expression. +@end table + +@subsection Choosing your editor +You can customize @value{GDBN} to use any editor you want +@footnote{ +The only restriction is that your editor (say @code{ex}), recognizes the +following command-line syntax: +@smallexample +ex +@var{number} file +@end smallexample +The optional numeric value +@var{number} designates the active line in +the file.}. By default, it is @value{EDITOR}, but you can change this +by setting the environment variable @code{EDITOR} before using +@value{GDBN}. For example, to configure @value{GDBN} to use the +@code{vi} editor, you could use these commands with the @code{sh} shell: +@smallexample +EDITOR=/usr/bin/vi +export EDITOR +gdb ... +@end smallexample +or in the @code{csh} shell, +@smallexample +setenv EDITOR /usr/bin/vi +gdb ... +@end smallexample + @node Search @section Searching source files @cindex searching @@ -4403,7 +4743,12 @@ Table}. * Convenience Vars:: Convenience variables * Registers:: Registers * Floating Point Hardware:: Floating point hardware +* Vector Unit:: Vector Unit +* Auxiliary Vector:: Auxiliary data provided by operating system * Memory Region Attributes:: Memory region attributes +* Dump/Restore Files:: Copy between memory and a file +* Character Sets:: Debugging programs that use a different + character set than GDB does @end menu @node Expressions @@ -4413,9 +4758,10 @@ Table}. @code{print} and many other @value{GDBN} commands accept an expression and compute its value. Any kind of constant, variable or operator defined by the programming language you are using is valid in an expression in -@value{GDBN}. This includes conditional expressions, function calls, casts -and string constants. It unfortunately does not include symbols defined -by preprocessor @code{#define} commands. +@value{GDBN}. This includes conditional expressions, function calls, +casts, and string constants. It also includes preprocessor macros, if +you compiled your program to include this information; see +@ref{Compilation}. @value{GDBN} supports array constants in expressions input by the user. The syntax is @{@var{element}, @var{element}@dots{}@}. For example, @@ -4483,7 +4829,7 @@ programming language from the point of execution in that frame @noindent This means that in the function -@example +@smallexample foo (a) int a; @{ @@ -4493,7 +4839,7 @@ foo (a) bar (b); @} @} -@end example +@end smallexample @noindent you can examine and use the variable @code{a} whenever your program is @@ -4515,10 +4861,10 @@ using the colon-colon notation: @c info cannot cope with a :: index entry, but why deprive hard copy readers? @cindex @code{::}, context for variables/functions @end iftex -@example +@smallexample @var{file}::@var{variable} @var{function}::@var{variable} -@end example +@end smallexample @noindent Here @var{file} or @var{function} is the name of the context for the @@ -4526,9 +4872,9 @@ static @var{variable}. In the case of file names, you can use quotes to make sure @value{GDBN} parses the file name as a single word---for example, to print a global value of @code{x} defined in @file{f2.c}: -@example +@smallexample (@value{GDBP}) p 'f2.c'::x -@end example +@end smallexample @cindex C@t{++} scope resolution This use of @samp{::} is very rarely in conflict with the very similar @@ -4565,19 +4911,18 @@ offered by the debug info format used by the compiler, @value{GDBN} might not be able to display values for such local variables. If that happens, @value{GDBN} will print a message like this: -@example +@smallexample No symbol "foo" in current context. -@end example +@end smallexample To solve such problems, either recompile without optimizations, or use a different debug info format, if the compiler supports several such -formats. For example, @value{NGCC}, the @sc{gnu} C/C@t{++} compiler usually -supports the @samp{-gstabs} option. @samp{-gstabs} produces debug info -in a format that is superior to formats such as COFF. You may be able -to use DWARF2 (@samp{-gdwarf-2}), which is also an effective form for -debug info. See @ref{Debugging Options,,Options for Debugging Your -Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}, for more -information. +formats. For example, @value{NGCC}, the @sc{gnu} C/C@t{++} compiler +usually supports the @option{-gstabs+} option. @option{-gstabs+} +produces debug info in a format that is superior to formats such as +COFF. You may be able to use DWARF 2 (@option{-gdwarf-2}), which is also +an effective form for debug info. @xref{Debugging Options,,Options +for Debugging Your Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}. @node Arrays @@ -4600,16 +4945,16 @@ argument; the second element comes from bytes of memory immediately following those that hold the first element, and so on. Here is an example. If a program says -@example +@smallexample int *array = (int *) malloc (len * sizeof (int)); -@end example +@end smallexample @noindent you can print the contents of @code{array} with -@example +@smallexample p *array@@len -@end example +@end smallexample The left operand of @samp{@@} must reside in memory. Array values made with @samp{@@} in this way behave just like other arrays in terms of @@ -4620,18 +4965,18 @@ Artificial arrays most often appear in expressions via the value history Another way to create an artificial array is to use a cast. This re-interprets a value as if it were an array. The value need not be in memory: -@example +@smallexample (@value{GDBP}) p/x (short[2])0x12345678 $1 = @{0x1234, 0x5678@} -@end example +@end smallexample As a convenience, if you leave the array length out (as in @samp{(@var{type}[])@var{value}}) @value{GDBN} calculates the size to fill the value (as @samp{sizeof(@var{value})/sizeof(@var{type})}: -@example +@smallexample (@value{GDBP}) p/x (short[])0x12345678 $2 = @{0x1234, 0x5678@} -@end example +@end smallexample Sometimes the artificial array mechanism is not quite enough; in moderately complex data structures, the elements of interest may not @@ -4644,13 +4989,13 @@ instance, suppose you have an array @code{dtab} of pointers to structures, and you are interested in the values of a field @code{fv} in each structure. Here is an example of what you might type: -@example +@smallexample set $i = 0 p dtab[$i++]->fv @key{RET} @key{RET} @dots{} -@end example +@end smallexample @node Output Formats @section Output formats @@ -4695,10 +5040,10 @@ Print as an address, both absolute in hexadecimal and as an offset from the nearest preceding symbol. You can use this format used to discover where (in what function) an unknown address is located: -@example +@smallexample (@value{GDBP}) p/a 0x54320 $3 = 0x54320 <_initialize_vx+396> -@end example +@end smallexample @noindent The command @code{info symbol 0x54320} yields similar results. @@ -4714,9 +5059,9 @@ using typical floating point syntax. For example, to print the program counter in hex (@pxref{Registers}), type -@example +@smallexample p/x $pc -@end example +@end smallexample @noindent Note that no space is required before the slash; this is because command @@ -4843,10 +5188,10 @@ Each expression added to the list is given a number to identify it; to remove an expression from the list, you specify that number. The automatic display looks like this: -@example +@smallexample 2: foo = 38 3: bar[5] = (struct hack *) 0x3804 -@end example +@end smallexample @noindent This display shows item numbers, expressions and their current values. As with @@ -5034,11 +5379,11 @@ and source file location of the variable where it points, using For example, here @value{GDBN} shows that a variable @code{ptt} points at another variable @code{t}, defined in @file{hi2.c}: -@example +@smallexample (@value{GDBP}) set print symbol-filename on (@value{GDBP}) p/a ptt $4 = 0xe008 -@end example +@end smallexample @quotation @emph{Warning:} For pointers that point to a local variable, @samp{p/a} @@ -5320,16 +5665,16 @@ is the value just prior to @code{$$}, @code{$$1} is equivalent to For example, suppose you have just printed a pointer to a structure and want to see the contents of the structure. It suffices to type -@example +@smallexample p *$ -@end example +@end smallexample If you have a chain of structures where the component @code{next} points to the next one, you can print the contents of the next one with this: -@example +@smallexample p *$.next -@end example +@end smallexample @noindent You can print successive links in the chain by repeating this @@ -5338,10 +5683,10 @@ command---which you can do by just typing @key{RET}. Note that the history records values, not expressions. If the value of @code{x} is 4 and you type these commands: -@example +@smallexample print x set x=5 -@end example +@end smallexample @noindent then the value recorded in the value history by the @code{print} command @@ -5385,9 +5730,9 @@ You can save a value in a convenience variable with an assignment expression, just as you would set a variable in your program. For example: -@example +@smallexample set $foo = *object_ptr -@end example +@end smallexample @noindent would save in @code{$foo} the value contained in the object pointed to by @@ -5413,10 +5758,10 @@ One of the ways to use a convenience variable is as a counter to be incremented or a pointer to be advanced. For example, to print a field from successive elements of an array of structures: -@example +@smallexample set $i = 0 print bar[$i++]->contents -@end example +@end smallexample @noindent Repeat that command by typing @key{RET}. @@ -5464,13 +5809,13 @@ your machine. @kindex info registers @item info registers Print the names and values of all registers except floating-point -registers (in the selected stack frame). +and vector registers (in the selected stack frame). @kindex info all-registers @cindex floating point registers @item info all-registers Print the names and values of all registers, including floating-point -registers. +and vector registers (in the selected stack frame). @item info registers @var{regname} @dots{} Print the @dfn{relativized} value of each specified register @var{regname}. @@ -5488,16 +5833,16 @@ pointer to the current stack frame, and @code{$ps} is used for a register that contains the processor status. For example, you could print the program counter in hex with -@example +@smallexample p/x $pc -@end example +@end smallexample @noindent or print the instruction to be executed next with -@example +@smallexample x/i $pc -@end example +@end smallexample @noindent or add four to the stack pointer@footnote{This is a way of removing @@ -5508,9 +5853,9 @@ stack frames are selected. To pop entire frames off the stack, regardless of machine architecture, use @code{return}; see @ref{Returning, ,Returning from a function}.} with -@example +@smallexample set $sp += 4 -@end example +@end smallexample Whenever possible, these four standard register names are available on your machine even though the machine has different canonical mnemonics, @@ -5566,12 +5911,52 @@ floating point chip. Currently, @samp{info float} is supported on the ARM and x86 machines. @end table +@node Vector Unit +@section Vector Unit +@cindex vector unit + +Depending on the configuration, @value{GDBN} may be able to give you +more information about the status of the vector unit. + +@table @code +@kindex info vector +@item info vector +Display information about the vector unit. The exact contents and +layout vary depending on the hardware. +@end table + +@node Auxiliary Vector +@section Operating system auxiliary vector +@cindex auxiliary vector +@cindex vector, auxiliary + +Some operating systems supply an @dfn{auxiliary vector} to programs at +startup. This is akin to the arguments and environment that you +specify for a program, but contains a system-dependent variety of +binary values that tell system libraries important details about the +hardware, operating system, and process. Each value's purpose is +identified by an integer tag; the meanings are well-known but system-specific. +Depending on the configuration and operating system facilities, +@value{GDBN} may be able to show you this information. + +@table @code +@kindex info auxv +@item info auxv +Display the auxiliary vector of the inferior, which can be either a +live process or a core dump file. @value{GDBN} prints each tag value +numerically, and also shows names and text descriptions for recognized +tags. Some values in the vector are numbers, some bit masks, and some +pointers to strings or other data. @value{GDBN} displays each value in the +most appropriate form for a recognized tag, and in hexadecimal for +an unrecognized tag. +@end table + @node Memory Region Attributes -@section Memory Region Attributes +@section Memory region attributes @cindex memory region attributes -@dfn{Memory region attributes} allow you to describe special handling -required by regions of your target's memory. @value{GDBN} uses attributes +@dfn{Memory region attributes} allow you to describe special handling +required by regions of your target's memory. @value{GDBN} uses attributes to determine whether to allow certain types of memory accesses; whether to use specific width accesses; and whether to cache target memory. @@ -5581,14 +5966,16 @@ accessing memory in that region. Similarly, if no memory regions have been defined, @value{GDBN} uses the default attributes when accessing all memory. -When a memory region is defined, it is given a number to identify it; +When a memory region is defined, it is given a number to identify it; to enable, disable, or remove a memory region, you specify that number. @table @code @kindex mem -@item mem @var{address1} @var{address2} @var{attributes}@dots{} -Define memory region bounded by @var{address1} and @var{address2} -with attributes @var{attributes}@dots{}. +@item mem @var{lower} @var{upper} @var{attributes}@dots{} +Define memory region bounded by @var{lower} and @var{upper} with +attributes @var{attributes}@dots{}. Note that @var{upper} == 0 is a +special case: it is treated as the the target's maximum memory address. +(0xffff on 16 bit targets, 0xffffffff on 32 bit targets, etc.) @kindex delete mem @item delete mem @var{nums}@dots{} @@ -5597,7 +5984,7 @@ Remove memory regions @var{nums}@dots{}. @kindex disable mem @item disable mem @var{nums}@dots{} Disable memory regions @var{nums}@dots{}. -A disabled memory region is not forgotten. +A disabled memory region is not forgotten. It may be enabled again later. @kindex enable mem @@ -5612,7 +5999,7 @@ for each region. @table @emph @item Memory Region Number @item Enabled or Disabled. -Enabled memory regions are marked with @samp{y}. +Enabled memory regions are marked with @samp{y}. Disabled memory regions are marked with @samp{n}. @item Lo Address @@ -5629,7 +6016,7 @@ The list of attributes set for this memory region. @subsection Attributes -@subsubsection Memory Access Mode +@subsubsection Memory Access Mode The access mode attributes set whether @value{GDBN} may make read or write accesses to a memory region. @@ -5670,7 +6057,7 @@ Use 64 bit memory accesses. @c @c @table @code @c @item hwbreak -@c Always use hardware breakpoints +@c Always use hardware breakpoints @c @item swbreak (default) @c @end table @@ -5683,13 +6070,13 @@ registers. @table @code @item cache -Enable @value{GDBN} to cache target memory. +Enable @value{GDBN} to cache target memory. @item nocache Disable @value{GDBN} from caching target memory. This is the default. @end table @c @subsubsection Memory Write Verification -@c The memory write verification attributes set whether @value{GDBN} +@c The memory write verification attributes set whether @value{GDBN} @c will re-reads data after each write to verify the write was successful. @c @c @table @code @@ -5697,6 +6084,542 @@ Disable @value{GDBN} from caching target memory. This is the default. @c @item noverify (default) @c @end table +@node Dump/Restore Files +@section Copy between memory and a file +@cindex dump/restore files +@cindex append data to a file +@cindex dump data to a file +@cindex restore data from a file + +You can use the commands @code{dump}, @code{append}, and +@code{restore} to copy data between target memory and a file. The +@code{dump} and @code{append} commands write data to a file, and the +@code{restore} command reads data from a file back into the inferior's +memory. Files may be in binary, Motorola S-record, Intel hex, or +Tektronix Hex format; however, @value{GDBN} can only append to binary +files. + +@table @code + +@kindex dump +@item dump @r{[}@var{format}@r{]} memory @var{filename} @var{start_addr} @var{end_addr} +@itemx dump @r{[}@var{format}@r{]} value @var{filename} @var{expr} +Dump the contents of memory from @var{start_addr} to @var{end_addr}, +or the value of @var{expr}, to @var{filename} in the given format. + +The @var{format} parameter may be any one of: +@table @code +@item binary +Raw binary form. +@item ihex +Intel hex format. +@item srec +Motorola S-record format. +@item tekhex +Tektronix Hex format. +@end table + +@value{GDBN} uses the same definitions of these formats as the +@sc{gnu} binary utilities, like @samp{objdump} and @samp{objcopy}. If +@var{format} is omitted, @value{GDBN} dumps the data in raw binary +form. + +@kindex append +@item append @r{[}binary@r{]} memory @var{filename} @var{start_addr} @var{end_addr} +@itemx append @r{[}binary@r{]} value @var{filename} @var{expr} +Append the contents of memory from @var{start_addr} to @var{end_addr}, +or the value of @var{expr}, to @var{filename}, in raw binary form. +(@value{GDBN} can only append data to files in raw binary form.) + +@kindex restore +@item restore @var{filename} @r{[}binary@r{]} @var{bias} @var{start} @var{end} +Restore the contents of file @var{filename} into memory. The +@code{restore} command can automatically recognize any known @sc{bfd} +file format, except for raw binary. To restore a raw binary file you +must specify the optional keyword @code{binary} after the filename. + +If @var{bias} is non-zero, its value will be added to the addresses +contained in the file. Binary files always start at address zero, so +they will be restored at address @var{bias}. Other bfd files have +a built-in location; they will be restored at offset @var{bias} +from that location. + +If @var{start} and/or @var{end} are non-zero, then only data between +file offset @var{start} and file offset @var{end} will be restored. +These offsets are relative to the addresses in the file, before +the @var{bias} argument is applied. + +@end table + +@node Character Sets +@section Character Sets +@cindex character sets +@cindex charset +@cindex translating between character sets +@cindex host character set +@cindex target character set + +If the program you are debugging uses a different character set to +represent characters and strings than the one @value{GDBN} uses itself, +@value{GDBN} can automatically translate between the character sets for +you. The character set @value{GDBN} uses we call the @dfn{host +character set}; the one the inferior program uses we call the +@dfn{target character set}. + +For example, if you are running @value{GDBN} on a @sc{gnu}/Linux system, which +uses the ISO Latin 1 character set, but you are using @value{GDBN}'s +remote protocol (@pxref{Remote,Remote Debugging}) to debug a program +running on an IBM mainframe, which uses the @sc{ebcdic} character set, +then the host character set is Latin-1, and the target character set is +@sc{ebcdic}. If you give @value{GDBN} the command @code{set +target-charset EBCDIC-US}, then @value{GDBN} translates between +@sc{ebcdic} and Latin 1 as you print character or string values, or use +character and string literals in expressions. + +@value{GDBN} has no way to automatically recognize which character set +the inferior program uses; you must tell it, using the @code{set +target-charset} command, described below. + +Here are the commands for controlling @value{GDBN}'s character set +support: + +@table @code +@item set target-charset @var{charset} +@kindex set target-charset +Set the current target character set to @var{charset}. We list the +character set names @value{GDBN} recognizes below, but if you type +@code{set target-charset} followed by @key{TAB}@key{TAB}, @value{GDBN} will +list the target character sets it supports. +@end table + +@table @code +@item set host-charset @var{charset} +@kindex set host-charset +Set the current host character set to @var{charset}. + +By default, @value{GDBN} uses a host character set appropriate to the +system it is running on; you can override that default using the +@code{set host-charset} command. + +@value{GDBN} can only use certain character sets as its host character +set. We list the character set names @value{GDBN} recognizes below, and +indicate which can be host character sets, but if you type +@code{set target-charset} followed by @key{TAB}@key{TAB}, @value{GDBN} will +list the host character sets it supports. + +@item set charset @var{charset} +@kindex set charset +Set the current host and target character sets to @var{charset}. As +above, if you type @code{set charset} followed by @key{TAB}@key{TAB}, +@value{GDBN} will list the name of the character sets that can be used +for both host and target. + + +@item show charset +@kindex show charset +Show the names of the current host and target charsets. + +@itemx show host-charset +@kindex show host-charset +Show the name of the current host charset. + +@itemx show target-charset +@kindex show target-charset +Show the name of the current target charset. + +@end table + +@value{GDBN} currently includes support for the following character +sets: + +@table @code + +@item ASCII +@cindex ASCII character set +Seven-bit U.S. @sc{ascii}. @value{GDBN} can use this as its host +character set. + +@item ISO-8859-1 +@cindex ISO 8859-1 character set +@cindex ISO Latin 1 character set +The ISO Latin 1 character set. This extends @sc{ascii} with accented +characters needed for French, German, and Spanish. @value{GDBN} can use +this as its host character set. + +@item EBCDIC-US +@itemx IBM1047 +@cindex EBCDIC character set +@cindex IBM1047 character set +Variants of the @sc{ebcdic} character set, used on some of IBM's +mainframe operating systems. (@sc{gnu}/Linux on the S/390 uses U.S. @sc{ascii}.) +@value{GDBN} cannot use these as its host character set. + +@end table + +Note that these are all single-byte character sets. More work inside +GDB is needed to support multi-byte or variable-width character +encodings, like the UTF-8 and UCS-2 encodings of Unicode. + +Here is an example of @value{GDBN}'s character set support in action. +Assume that the following source code has been placed in the file +@file{charset-test.c}: + +@smallexample +#include + +char ascii_hello[] + = @{72, 101, 108, 108, 111, 44, 32, 119, + 111, 114, 108, 100, 33, 10, 0@}; +char ibm1047_hello[] + = @{200, 133, 147, 147, 150, 107, 64, 166, + 150, 153, 147, 132, 90, 37, 0@}; + +main () +@{ + printf ("Hello, world!\n"); +@} +@end smallexample + +In this program, @code{ascii_hello} and @code{ibm1047_hello} are arrays +containing the string @samp{Hello, world!} followed by a newline, +encoded in the @sc{ascii} and @sc{ibm1047} character sets. + +We compile the program, and invoke the debugger on it: + +@smallexample +$ gcc -g charset-test.c -o charset-test +$ gdb -nw charset-test +GNU gdb 2001-12-19-cvs +Copyright 2001 Free Software Foundation, Inc. +@dots{} +(gdb) +@end smallexample + +We can use the @code{show charset} command to see what character sets +@value{GDBN} is currently using to interpret and display characters and +strings: + +@smallexample +(gdb) show charset +The current host and target character set is `ISO-8859-1'. +(gdb) +@end smallexample + +For the sake of printing this manual, let's use @sc{ascii} as our +initial character set: +@smallexample +(gdb) set charset ASCII +(gdb) show charset +The current host and target character set is `ASCII'. +(gdb) +@end smallexample + +Let's assume that @sc{ascii} is indeed the correct character set for our +host system --- in other words, let's assume that if @value{GDBN} prints +characters using the @sc{ascii} character set, our terminal will display +them properly. Since our current target character set is also +@sc{ascii}, the contents of @code{ascii_hello} print legibly: + +@smallexample +(gdb) print ascii_hello +$1 = 0x401698 "Hello, world!\n" +(gdb) print ascii_hello[0] +$2 = 72 'H' +(gdb) +@end smallexample + +@value{GDBN} uses the target character set for character and string +literals you use in expressions: + +@smallexample +(gdb) print '+' +$3 = 43 '+' +(gdb) +@end smallexample + +The @sc{ascii} character set uses the number 43 to encode the @samp{+} +character. + +@value{GDBN} relies on the user to tell it which character set the +target program uses. If we print @code{ibm1047_hello} while our target +character set is still @sc{ascii}, we get jibberish: + +@smallexample +(gdb) print ibm1047_hello +$4 = 0x4016a8 "\310\205\223\223\226k@@\246\226\231\223\204Z%" +(gdb) print ibm1047_hello[0] +$5 = 200 '\310' +(gdb) +@end smallexample + +If we invoke the @code{set target-charset} followed by @key{TAB}@key{TAB}, +@value{GDBN} tells us the character sets it supports: + +@smallexample +(gdb) set target-charset +ASCII EBCDIC-US IBM1047 ISO-8859-1 +(gdb) set target-charset +@end smallexample + +We can select @sc{ibm1047} as our target character set, and examine the +program's strings again. Now the @sc{ascii} string is wrong, but +@value{GDBN} translates the contents of @code{ibm1047_hello} from the +target character set, @sc{ibm1047}, to the host character set, +@sc{ascii}, and they display correctly: + +@smallexample +(gdb) set target-charset IBM1047 +(gdb) show charset +The current host character set is `ASCII'. +The current target character set is `IBM1047'. +(gdb) print ascii_hello +$6 = 0x401698 "\110\145%%?\054\040\167?\162%\144\041\012" +(gdb) print ascii_hello[0] +$7 = 72 '\110' +(gdb) print ibm1047_hello +$8 = 0x4016a8 "Hello, world!\n" +(gdb) print ibm1047_hello[0] +$9 = 200 'H' +(gdb) +@end smallexample + +As above, @value{GDBN} uses the target character set for character and +string literals you use in expressions: + +@smallexample +(gdb) print '+' +$10 = 78 '+' +(gdb) +@end smallexample + +The @sc{ibm1047} character set uses the number 78 to encode the @samp{+} +character. + + +@node Macros +@chapter C Preprocessor Macros + +Some languages, such as C and C@t{++}, provide a way to define and invoke +``preprocessor macros'' which expand into strings of tokens. +@value{GDBN} can evaluate expressions containing macro invocations, show +the result of macro expansion, and show a macro's definition, including +where it was defined. + +You may need to compile your program specially to provide @value{GDBN} +with information about preprocessor macros. Most compilers do not +include macros in their debugging information, even when you compile +with the @option{-g} flag. @xref{Compilation}. + +A program may define a macro at one point, remove that definition later, +and then provide a different definition after that. Thus, at different +points in the program, a macro may have different definitions, or have +no definition at all. If there is a current stack frame, @value{GDBN} +uses the macros in scope at that frame's source code line. Otherwise, +@value{GDBN} uses the macros in scope at the current listing location; +see @ref{List}. + +At the moment, @value{GDBN} does not support the @code{##} +token-splicing operator, the @code{#} stringification operator, or +variable-arity macros. + +Whenever @value{GDBN} evaluates an expression, it always expands any +macro invocations present in the expression. @value{GDBN} also provides +the following commands for working with macros explicitly. + +@table @code + +@kindex macro expand +@cindex macro expansion, showing the results of preprocessor +@cindex preprocessor macro expansion, showing the results of +@cindex expanding preprocessor macros +@item macro expand @var{expression} +@itemx macro exp @var{expression} +Show the results of expanding all preprocessor macro invocations in +@var{expression}. Since @value{GDBN} simply expands macros, but does +not parse the result, @var{expression} need not be a valid expression; +it can be any string of tokens. + +@kindex macro expand-once +@item macro expand-once @var{expression} +@itemx macro exp1 @var{expression} +@i{(This command is not yet implemented.)} Show the results of +expanding those preprocessor macro invocations that appear explicitly in +@var{expression}. Macro invocations appearing in that expansion are +left unchanged. This command allows you to see the effect of a +particular macro more clearly, without being confused by further +expansions. Since @value{GDBN} simply expands macros, but does not +parse the result, @var{expression} need not be a valid expression; it +can be any string of tokens. + +@kindex info macro +@cindex macro definition, showing +@cindex definition, showing a macro's +@item info macro @var{macro} +Show the definition of the macro named @var{macro}, and describe the +source location where that definition was established. + +@kindex macro define +@cindex user-defined macros +@cindex defining macros interactively +@cindex macros, user-defined +@item macro define @var{macro} @var{replacement-list} +@itemx macro define @var{macro}(@var{arglist}) @var{replacement-list} +@i{(This command is not yet implemented.)} Introduce a definition for a +preprocessor macro named @var{macro}, invocations of which are replaced +by the tokens given in @var{replacement-list}. The first form of this +command defines an ``object-like'' macro, which takes no arguments; the +second form defines a ``function-like'' macro, which takes the arguments +given in @var{arglist}. + +A definition introduced by this command is in scope in every expression +evaluated in @value{GDBN}, until it is removed with the @command{macro +undef} command, described below. The definition overrides all +definitions for @var{macro} present in the program being debugged, as +well as any previous user-supplied definition. + +@kindex macro undef +@item macro undef @var{macro} +@i{(This command is not yet implemented.)} Remove any user-supplied +definition for the macro named @var{macro}. This command only affects +definitions provided with the @command{macro define} command, described +above; it cannot remove definitions present in the program being +debugged. + +@end table + +@cindex macros, example of debugging with +Here is a transcript showing the above commands in action. First, we +show our source files: + +@smallexample +$ cat sample.c +#include +#include "sample.h" + +#define M 42 +#define ADD(x) (M + x) + +main () +@{ +#define N 28 + printf ("Hello, world!\n"); +#undef N + printf ("We're so creative.\n"); +#define N 1729 + printf ("Goodbye, world!\n"); +@} +$ cat sample.h +#define Q < +$ +@end smallexample + +Now, we compile the program using the @sc{gnu} C compiler, @value{NGCC}. +We pass the @option{-gdwarf-2} and @option{-g3} flags to ensure the +compiler includes information about preprocessor macros in the debugging +information. + +@smallexample +$ gcc -gdwarf-2 -g3 sample.c -o sample +$ +@end smallexample + +Now, we start @value{GDBN} on our sample program: + +@smallexample +$ gdb -nw sample +GNU gdb 2002-05-06-cvs +Copyright 2002 Free Software Foundation, Inc. +GDB is free software, @dots{} +(gdb) +@end smallexample + +We can expand macros and examine their definitions, even when the +program is not running. @value{GDBN} uses the current listing position +to decide which macro definitions are in scope: + +@smallexample +(gdb) list main +3 +4 #define M 42 +5 #define ADD(x) (M + x) +6 +7 main () +8 @{ +9 #define N 28 +10 printf ("Hello, world!\n"); +11 #undef N +12 printf ("We're so creative.\n"); +(gdb) info macro ADD +Defined at /home/jimb/gdb/macros/play/sample.c:5 +#define ADD(x) (M + x) +(gdb) info macro Q +Defined at /home/jimb/gdb/macros/play/sample.h:1 + included at /home/jimb/gdb/macros/play/sample.c:2 +#define Q < +(gdb) macro expand ADD(1) +expands to: (42 + 1) +(gdb) macro expand-once ADD(1) +expands to: once (M + 1) +(gdb) +@end smallexample + +In the example above, note that @command{macro expand-once} expands only +the macro invocation explicit in the original text --- the invocation of +@code{ADD} --- but does not expand the invocation of the macro @code{M}, +which was introduced by @code{ADD}. + +Once the program is running, GDB uses the macro definitions in force at +the source line of the current stack frame: + +@smallexample +(gdb) break main +Breakpoint 1 at 0x8048370: file sample.c, line 10. +(gdb) run +Starting program: /home/jimb/gdb/macros/play/sample + +Breakpoint 1, main () at sample.c:10 +10 printf ("Hello, world!\n"); +(gdb) +@end smallexample + +At line 10, the definition of the macro @code{N} at line 9 is in force: + +@smallexample +(gdb) info macro N +Defined at /home/jimb/gdb/macros/play/sample.c:9 +#define N 28 +(gdb) macro expand N Q M +expands to: 28 < 42 +(gdb) print N Q M +$1 = 1 +(gdb) +@end smallexample + +As we step over directives that remove @code{N}'s definition, and then +give it a new definition, @value{GDBN} finds the definition (or lack +thereof) in force at each point: + +@smallexample +(gdb) next +Hello, world! +12 printf ("We're so creative.\n"); +(gdb) info macro N +The symbol `N' has no definition as a C/C++ preprocessor macro +at /home/jimb/gdb/macros/play/sample.c:12 +(gdb) next +We're so creative. +14 printf ("Goodbye, world!\n"); +(gdb) info macro N +Defined at /home/jimb/gdb/macros/play/sample.c:13 +#define N 1729 +(gdb) macro expand N Q M +expands to: 1729 < 42 +(gdb) print N Q M +$2 = 0 +(gdb) +@end smallexample + + @node Tracepoints @chapter Tracepoints @c This chapter is based on the documentation written by Michael @@ -5732,9 +6655,9 @@ tracepoints as of this writing. This chapter describes the tracepoint commands and features. @menu -* Set Tracepoints:: -* Analyze Collected Data:: -* Tracepoint Variables:: +* Set Tracepoints:: +* Analyze Collected Data:: +* Tracepoint Variables:: @end menu @node Set Tracepoints @@ -5759,12 +6682,12 @@ This section describes commands to set tracepoints and associated conditions and actions. @menu -* Create and Delete Tracepoints:: -* Enable and Disable Tracepoints:: -* Tracepoint Passcounts:: -* Tracepoint Actions:: -* Listing Tracepoints:: -* Starting and Stopping Trace Experiment:: +* Create and Delete Tracepoints:: +* Enable and Disable Tracepoints:: +* Tracepoint Passcounts:: +* Tracepoint Actions:: +* Listing Tracepoints:: +* Starting and Stopping Trace Experiment:: @end menu @node Create and Delete Tracepoints @@ -5863,7 +6786,7 @@ user. Examples: @smallexample -(@value{GDBP}) @b{passcount 5 2} // Stop on the 5th execution of +(@value{GDBP}) @b{passcount 5 2} // Stop on the 5th execution of @exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// tracepoint 2} (@value{GDBP}) @b{passcount 12} // Stop on the 12th execution of the @@ -6368,7 +7291,7 @@ there. @c size of all overlays. This is intentional to remind the developer @c that overlays don't necessarily need to be the same size. -@example +@smallexample @group Data Instruction Larger Address Space Address Space Address Space @@ -6396,7 +7319,7 @@ Address Space Address Space Address Space @anchor{A code overlay}A code overlay @end group -@end example +@end smallexample The diagram (@pxref{A code overlay}) shows a system with separate data and instruction address spaces. To map an overlay, the program copies @@ -6553,33 +7476,33 @@ addresses, load addresses, and sizes. Normally, when @value{GDBN} prints a code address, it includes the name of the function the address falls in: -@example +@smallexample (gdb) print main $3 = @{int ()@} 0x11a0
-@end example +@end smallexample @noindent When overlay debugging is enabled, @value{GDBN} recognizes code in unmapped overlays, and prints the names of unmapped functions with asterisks around them. For example, if @code{foo} is a function in an unmapped overlay, @value{GDBN} prints it this way: -@example +@smallexample (gdb) overlay list No sections are mapped. (gdb) print foo $5 = @{int (int)@} 0x100000 <*foo*> -@end example +@end smallexample @noindent When @code{foo}'s overlay is mapped, @value{GDBN} prints the function's name normally: -@example +@smallexample (gdb) overlay list -Section .ov.foo.text, loaded at 0x100000 - 0x100034, +Section .ov.foo.text, loaded at 0x100000 - 0x100034, mapped at 0x1016 - 0x104a (gdb) print foo $6 = @{int (int)@} 0x1016 -@end example +@end smallexample When overlay debugging is enabled, @value{GDBN} can find the correct address for functions and variables in an overlay, whether or not the @@ -6621,7 +7544,7 @@ Here are the variables your overlay manager must define to support @item @code{_ovly_table}: This variable must be an array of the following structures: -@example +@smallexample struct @{ /* The overlay's mapped address. */ @@ -6637,7 +7560,7 @@ struct zero otherwise. */ unsigned long mapped; @} -@end example +@end smallexample @item @code{_novlys}: This variable must be a four-byte signed integer, holding the total @@ -6658,7 +7581,7 @@ will silently set a breakpoint there. If the overlay manager then calls this function whenever it has changed the overlay table, this will enable @value{GDBN} to accurately keep track of which overlays are in program memory, and update any breakpoints that may be set -in overlays. This will allow breakpoints to work even if the +in overlays. This will allow breakpoints to work even if the overlays are kept in ROM or other non-writable memory while they are not being executed. @@ -6698,7 +7621,7 @@ and @code{m32r-elf} targets. You can build the test program using the @code{d10v-elf} GCC cross-compiler like this: -@example +@smallexample $ d10v-elf-gcc -g -c overlays.c $ d10v-elf-gcc -g -c ovlymgr.c $ d10v-elf-gcc -g -c foo.c @@ -6707,7 +7630,7 @@ $ d10v-elf-gcc -g -c baz.c $ d10v-elf-gcc -g -c grbx.c $ d10v-elf-gcc -g overlays.o ovlymgr.o foo.o bar.o \ baz.o grbx.o -Wl,-Td10v.ld -o overlays -@end example +@end smallexample The build process is identical for any other architecture, except that you must substitute the appropriate compiler and linker script for the @@ -6738,6 +7661,7 @@ language}. * Show:: Displaying the language * Checks:: Type and range checks * Support:: Supported languages +* Unsupported languages:: Unsupported languages @end menu @node Setting @@ -6793,15 +7717,13 @@ C source file @itemx .c++ C@t{++} source file +@item .m +Objective-C source file + @item .f @itemx .F Fortran source file -@item .ch -@itemx .c186 -@itemx .c286 -CHILL source file - @item .mod Modula-2 source file @@ -6836,9 +7758,9 @@ languages---but means different things. For instance, if the current source file were written in C, and @value{GDBN} was parsing Modula-2, a command such as: -@example +@smallexample print a = b + c -@end example +@end smallexample @noindent might not have the effect you intended. In C, this means to add @@ -7032,9 +7954,9 @@ error. In many implementations of C, mathematical overflow causes the result to ``wrap around'' to lower values---for example, if @var{m} is the largest integer value, and @var{s} is the smallest, then -@example +@smallexample @var{m} + 1 @result{} @var{s} -@end example +@end smallexample This, too, is specific to individual languages, and in some cases specific to individual compilers or machines. @xref{Support, , @@ -7073,7 +7995,7 @@ being set automatically by @value{GDBN}. @node Support @section Supported languages -@value{GDBN} supports C, C@t{++}, Fortran, Java, Chill, assembly, and Modula-2. +@value{GDBN} supports C, C@t{++}, Objective-C, Fortran, Java, assembly, and Modula-2. @c This is false ... Some @value{GDBN} features may be used in expressions regardless of the language you use: the @value{GDBN} @code{@@} and @code{::} operators, @@ -7090,9 +8012,9 @@ books written on each of these languages; please look to these for a language reference or tutorial. @menu -* C:: C and C@t{++} -* Modula-2:: Modula-2 -* Chill:: Chill +* C:: C and C@t{++} +* Objective-C:: Objective-C +* Modula-2:: Modula-2 @end menu @node C @@ -7114,11 +8036,12 @@ effectively, you must compile your C@t{++} programs with a supported C@t{++} compiler, such as @sc{gnu} @code{g++}, or the HP ANSI C@t{++} compiler (@code{aCC}). -For best results when using @sc{gnu} C@t{++}, use the stabs debugging -format. You can select that format explicitly with the @code{g++} -command-line options @samp{-gstabs} or @samp{-gstabs+}. See -@ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu} -CC, gcc.info, Using @sc{gnu} CC}, for more information. +For best results when using @sc{gnu} C@t{++}, use the DWARF 2 debugging +format; if it doesn't work on your system, try the stabs+ debugging +format. You can select those formats explicitly with the @code{g++} +command-line options @option{-gdwarf-2} and @option{-gstabs+}. +@xref{Debugging Options,,Options for Debugging Your Program or @sc{gnu} +CC, gcc.info, Using @sc{gnu} CC}. @menu * C Operators:: C and C@t{++} operators @@ -7364,28 +8287,21 @@ and @samp{@{&"hi", &"there", &"fred"@}} is a three-element array of pointers. @cindex expressions in C@t{++} @value{GDBN} expression handling can interpret most C@t{++} expressions. -@cindex C@t{++} support, not in @sc{coff} -@cindex @sc{coff} versus C@t{++} -@cindex C@t{++} and object formats -@cindex object formats and C@t{++} -@cindex a.out and C@t{++} -@cindex @sc{ecoff} and C@t{++} -@cindex @sc{xcoff} and C@t{++} -@cindex @sc{elf}/stabs and C@t{++} -@cindex @sc{elf}/@sc{dwarf} and C@t{++} -@c FIXME!! GDB may eventually be able to debug C++ using DWARF; check -@c periodically whether this has happened... +@cindex debugging C@t{++} programs +@cindex C@t{++} compilers +@cindex debug formats and C@t{++} +@cindex @value{NGCC} and C@t{++} @quotation @emph{Warning:} @value{GDBN} can only debug C@t{++} code if you use the -proper compiler. Typically, C@t{++} debugging depends on the use of -additional debugging information in the symbol table, and thus requires -special support. In particular, if your compiler generates a.out, MIPS -@sc{ecoff}, RS/6000 @sc{xcoff}, or @sc{elf} with stabs extensions to the -symbol table, these facilities are all available. (With @sc{gnu} CC, -you can use the @samp{-gstabs} option to request stabs debugging -extensions explicitly.) Where the object code format is standard -@sc{coff} or @sc{dwarf} in @sc{elf}, on the other hand, most of the C@t{++} -support in @value{GDBN} does @emph{not} work. +proper compiler and the proper debug format. Currently, @value{GDBN} +works best when debugging C@t{++} code that is compiled with +@value{NGCC} 2.95.3 or with @value{NGCC} 3.1 or newer, using the options +@option{-gdwarf-2} or @option{-gstabs+}. DWARF 2 is preferred over +stabs+. Most configurations of @value{NGCC} emit either DWARF 2 or +stabs+ as their default debug format, so you usually don't need to +specify a debug format explicitly. Other compilers and/or debug formats +are likely to work badly or not at all when using @value{GDBN} to debug +C@t{++} code. @end quotation @enumerate @@ -7394,9 +8310,9 @@ support in @value{GDBN} does @emph{not} work. @item Member function calls are allowed; you can use expressions like -@example +@smallexample count = aml->GetOriginal(x, y) -@end example +@end smallexample @vindex this@r{, inside C@t{++} member functions} @cindex namespace in C@t{++} @@ -7615,7 +8531,106 @@ available choices, or to finish the type list for you. @xref{Completion,, Command completion}, for details on how to do this. @end table -@node Modula-2 +@node Objective-C +@subsection Objective-C + +@cindex Objective-C +This section provides information about some commands and command +options that are useful for debugging Objective-C code. + +@menu +* Method Names in Commands:: +* The Print Command with Objective-C:: +@end menu + +@node Method Names in Commands, The Print Command with Objective-C, Objective-C, Objective-C +@subsubsection Method Names in Commands + +The following commands have been extended to accept Objective-C method +names as line specifications: + +@kindex clear@r{, and Objective-C} +@kindex break@r{, and Objective-C} +@kindex info line@r{, and Objective-C} +@kindex jump@r{, and Objective-C} +@kindex list@r{, and Objective-C} +@itemize +@item @code{clear} +@item @code{break} +@item @code{info line} +@item @code{jump} +@item @code{list} +@end itemize + +A fully qualified Objective-C method name is specified as + +@smallexample +-[@var{Class} @var{methodName}] +@end smallexample + +where the minus sign is used to indicate an instance method and a +plus sign (not shown) is used to indicate a class method. The class +name @var{Class} and method name @var{methodName} are enclosed in +brackets, similar to the way messages are specified in Objective-C +source code. For example, to set a breakpoint at the @code{create} +instance method of class @code{Fruit} in the program currently being +debugged, enter: + +@smallexample +break -[Fruit create] +@end smallexample + +To list ten program lines around the @code{initialize} class method, +enter: + +@smallexample +list +[NSText initialize] +@end smallexample + +In the current version of @value{GDBN}, the plus or minus sign is +required. In future versions of @value{GDBN}, the plus or minus +sign will be optional, but you can use it to narrow the search. It +is also possible to specify just a method name: + +@smallexample +break create +@end smallexample + +You must specify the complete method name, including any colons. If +your program's source files contain more than one @code{create} method, +you'll be presented with a numbered list of classes that implement that +method. Indicate your choice by number, or type @samp{0} to exit if +none apply. + +As another example, to clear a breakpoint established at the +@code{makeKeyAndOrderFront:} method of the @code{NSWindow} class, enter: + +@smallexample +clear -[NSWindow makeKeyAndOrderFront:] +@end smallexample + +@node The Print Command with Objective-C +@subsubsection The Print Command With Objective-C +@kindex print-object +@kindex po @r{(@code{print-object})} + +The print command has also been extended to accept methods. For example: + +@smallexample +print -[@var{object} hash] +@end smallexample + +@cindex print an Objective-C object description +@cindex @code{_NSPrintForDebugger}, and printing Objective-C objects +@noindent +will tell @value{GDBN} to send the @code{hash} message to @var{object} +and print the result. Also, an additional command has been added, +@code{print-object} or @code{po} for short, which is meant to print +the description of an object. However, this command may only work +with certain Objective-C libraries that have a particular hook +function, @code{_NSPrintForDebugger}, defined. + +@node Modula-2, , Objective-C, Support @subsection Modula-2 @cindex Modula-2, @value{GDBN} support @@ -8014,11 +9029,11 @@ There are a few subtle differences between the Modula-2 scope operator (@code{.}) and the @value{GDBN} scope operator (@code{::}). The two have similar syntax: -@example +@smallexample @var{module} . @var{id} @var{scope} :: @var{id} -@end example +@end smallexample @noindent where @var{scope} is the name of a module or a procedure, @@ -8058,504 +9073,21 @@ address can be specified by an integral constant, the construct In @value{GDBN} scripts, the Modula-2 inequality operator @code{#} is interpreted as the beginning of a comment. Use @code{<>} instead. -@node Chill -@subsection Chill - -The extensions made to @value{GDBN} to support Chill only support output -from the @sc{gnu} Chill compiler. Other Chill compilers are not currently -supported, and attempting to debug executables produced by them is most -likely to give an error as @value{GDBN} reads in the executable's symbol -table. - -@c This used to say "... following Chill related topics ...", but since -@c menus are not shown in the printed manual, it would look awkward. -This section covers the Chill related topics and the features -of @value{GDBN} which support these topics. - -@menu -* How modes are displayed:: How modes are displayed -* Locations:: Locations and their accesses -* Values and their Operations:: Values and their Operations -* Chill type and range checks:: -* Chill defaults:: -@end menu - -@node How modes are displayed -@subsubsection How modes are displayed - -The Chill Datatype- (Mode) support of @value{GDBN} is directly related -with the functionality of the @sc{gnu} Chill compiler, and therefore deviates -slightly from the standard specification of the Chill language. The -provided modes are: - -@c FIXME: this @table's contents effectively disable @code by using @r -@c on every @item. So why does it need @code? -@table @code -@item @r{@emph{Discrete modes:}} -@itemize @bullet -@item -@emph{Integer Modes} which are predefined by @code{BYTE, UBYTE, INT, -UINT, LONG, ULONG}, -@item -@emph{Boolean Mode} which is predefined by @code{BOOL}, -@item -@emph{Character Mode} which is predefined by @code{CHAR}, -@item -@emph{Set Mode} which is displayed by the keyword @code{SET}. -@smallexample -(@value{GDBP}) ptype x -type = SET (karli = 10, susi = 20, fritzi = 100) -@end smallexample -If the type is an unnumbered set the set element values are omitted. -@item -@emph{Range Mode} which is displayed by -@smallexample -@code{type = ( : )} -@end smallexample -where @code{, } can be of any discrete literal -expression (e.g. set element names). -@end itemize - -@item @r{@emph{Powerset Mode:}} -A Powerset Mode is displayed by the keyword @code{POWERSET} followed by -the member mode of the powerset. The member mode can be any discrete mode. -@smallexample -(@value{GDBP}) ptype x -type = POWERSET SET (egon, hugo, otto) -@end smallexample - -@item @r{@emph{Reference Modes:}} -@itemize @bullet -@item -@emph{Bound Reference Mode} which is displayed by the keyword @code{REF} -followed by the mode name to which the reference is bound. -@item -@emph{Free Reference Mode} which is displayed by the keyword @code{PTR}. -@end itemize - -@item @r{@emph{Procedure mode}} -The procedure mode is displayed by @code{type = PROC() - EXCEPTIONS ()}. The @code{} is a list of the parameter modes. @code{} indicates -the mode of the result of the procedure if any. The exceptionlist lists -all possible exceptions which can be raised by the procedure. - -@ignore -@item @r{@emph{Instance mode}} -The instance mode is represented by a structure, which has a static -type, and is therefore not really of interest. -@end ignore - -@item @r{@emph{Synchronization Modes:}} -@itemize @bullet -@item -@emph{Event Mode} which is displayed by -@smallexample -@code{EVENT ()} -@end smallexample -where @code{()} is optional. -@item -@emph{Buffer Mode} which is displayed by -@smallexample -@code{BUFFER ()} -@end smallexample -where @code{()} is optional. -@end itemize - -@item @r{@emph{Timing Modes:}} -@itemize @bullet -@item -@emph{Duration Mode} which is predefined by @code{DURATION} -@item -@emph{Absolute Time Mode} which is predefined by @code{TIME} -@end itemize - -@item @r{@emph{Real Modes:}} -Real Modes are predefined with @code{REAL} and @code{LONG_REAL}. - -@item @r{@emph{String Modes:}} -@itemize @bullet -@item -@emph{Character String Mode} which is displayed by -@smallexample -@code{CHARS()} -@end smallexample -followed by the keyword @code{VARYING} if the String Mode is a varying -mode -@item -@emph{Bit String Mode} which is displayed by -@smallexample -@code{BOOLS()} -@end smallexample -@end itemize - -@item @r{@emph{Array Mode:}} -The Array Mode is displayed by the keyword @code{ARRAY()} -followed by the element mode (which may in turn be an array mode). -@smallexample -(@value{GDBP}) ptype x -type = ARRAY (1:42) - ARRAY (1:20) - SET (karli = 10, susi = 20, fritzi = 100) -@end smallexample - -@item @r{@emph{Structure Mode}} -The Structure mode is displayed by the keyword @code{STRUCT()}. The @code{} consists of names and modes of fields -of the structure. Variant structures have the keyword @code{CASE -OF ESAC} in their field list. Since the current version -of the GNU Chill compiler doesn't implement tag processing (no runtime -checks of variant fields, and therefore no debugging info), the output -always displays all variant fields. -@smallexample -(@value{GDBP}) ptype str -type = STRUCT ( - as x, - bs x, - CASE bs OF - (karli): - cs a - (ott): - ds x - ESAC -) -@end smallexample -@end table - -@node Locations -@subsubsection Locations and their accesses - -A location in Chill is an object which can contain values. - -A value of a location is generally accessed by the (declared) name of -the location. The output conforms to the specification of values in -Chill programs. How values are specified -is the topic of the next section, @ref{Values and their Operations}. - -The pseudo-location @code{RESULT} (or @code{result}) can be used to -display or change the result of a currently-active procedure: - -@smallexample -set result := EXPR -@end smallexample - -@noindent -This does the same as the Chill action @code{RESULT EXPR} (which -is not available in @value{GDBN}). - -Values of reference mode locations are printed by @code{PTR()} in case of a free reference mode, and by @code{(REF ) ()} in case of a bound reference. @code{} -represents the address where the reference points to. To access the -value of the location referenced by the pointer, use the dereference -operator @samp{->}. - -Values of procedure mode locations are displayed by -@smallexample -@code{@{ PROC -( ) @}
} -@end smallexample -@code{} is a list of modes according to the parameter -specification of the procedure and @code{
} shows the address of -the entry point. - -@ignore -Locations of instance modes are displayed just like a structure with two -fields specifying the @emph{process type} and the @emph{copy number} of -the investigated instance location@footnote{This comes from the current -implementation of instances. They are implemented as a structure (no -na). The output should be something like @code{[; -]}.}. The field names are @code{__proc_type} and -@code{__proc_copy}. - -Locations of synchronization modes are displayed like a structure with -the field name @code{__event_data} in case of a event mode location, and -like a structure with the field @code{__buffer_data} in case of a buffer -mode location (refer to previous paragraph). - -Structure Mode locations are printed by @code{[.: , -...]}. The @code{} corresponds to the structure mode -definition and the layout of @code{} varies depending of the mode -of the field. If the investigated structure mode location is of variant -structure mode, the variant parts of the structure are enclosed in curled -braces (@samp{@{@}}). Fields enclosed by @samp{@{,@}} are residing -on the same memory location and represent the current values of the -memory location in their specific modes. Since no tag processing is done -all variants are displayed. A variant field is printed by -@code{() = .: }. (who implements the -stuff ???) -@smallexample -(@value{GDBP}) print str1 $4 = [.as: 0, .bs: karli, .: { (karli) = -[.cs: []], (susi) = [.ds: susi]}] -@end smallexample -@end ignore - -Substructures of string mode-, array mode- or structure mode-values -(e.g. array slices, fields of structure locations) are accessed using -certain operations which are described in the next section, @ref{Values -and their Operations}. - -A location value may be interpreted as having a different mode using the -location conversion. This mode conversion is written as @code{()}. The user has to consider that the sizes of the modes -have to be equal otherwise an error occurs. Furthermore, no range -checking of the location against the destination mode is performed, and -therefore the result can be quite confusing. - -@smallexample -(@value{GDBP}) print int (s(3 up 4)) XXX TO be filled in !! XXX -@end smallexample - -@node Values and their Operations -@subsubsection Values and their Operations - -Values are used to alter locations, to investigate complex structures in -more detail or to filter relevant information out of a large amount of -data. There are several (mode dependent) operations defined which enable -such investigations. These operations are not only applicable to -constant values but also to locations, which can become quite useful -when debugging complex structures. During parsing the command line -(e.g. evaluating an expression) @value{GDBN} treats location names as -the values behind these locations. - -This section describes how values have to be specified and which -operations are legal to be used with such values. - -@table @code -@item Literal Values -Literal values are specified in the same manner as in @sc{gnu} Chill programs. -For detailed specification refer to the @sc{gnu} Chill implementation Manual -chapter 1.5. -@c FIXME: if the Chill Manual is a Texinfo documents, the above should -@c be converted to a @ref. - -@ignore -@itemize @bullet -@item -@emph{Integer Literals} are specified in the same manner as in Chill -programs (refer to the Chill Standard z200/88 chpt 5.2.4.2) -@item -@emph{Boolean Literals} are defined by @code{TRUE} and @code{FALSE}. -@item -@emph{Character Literals} are defined by @code{''}. (e.g. -@code{'M'}) -@item -@emph{Set Literals} are defined by a name which was specified in a set -mode. The value delivered by a Set Literal is the set value. This is -comparable to an enumeration in C/C@t{++} language. -@item -@emph{Emptiness Literal} is predefined by @code{NULL}. The value of the -emptiness literal delivers either the empty reference value, the empty -procedure value or the empty instance value. - -@item -@emph{Character String Literals} are defined by a sequence of characters -enclosed in single- or double quotes. If a single- or double quote has -to be part of the string literal it has to be stuffed (specified twice). -@item -@emph{Bitstring Literals} are specified in the same manner as in Chill -programs (refer z200/88 chpt 5.2.4.8). -@item -@emph{Floating point literals} are specified in the same manner as in -(gnu-)Chill programs (refer @sc{gnu} Chill implementation Manual chapter 1.5). -@end itemize -@end ignore - -@item Tuple Values -A tuple is specified by @code{[]}, where @code{} can be omitted if the mode of the tuple is unambiguous. This -unambiguity is derived from the context of a evaluated expression. -@code{} can be one of the following: - -@itemize @bullet -@item @emph{Powerset Tuple} -@item @emph{Array Tuple} -@item @emph{Structure Tuple} -Powerset tuples, array tuples and structure tuples are specified in the -same manner as in Chill programs refer to z200/88 chpt 5.2.5. -@end itemize - -@item String Element Value -A string element value is specified by -@smallexample -@code{()} -@end smallexample -where @code{} is a integer expression. It delivers a character -value which is equivalent to the character indexed by @code{} in -the string. - -@item String Slice Value -A string slice value is specified by @code{()}, where @code{} can be either a range of integer -expressions or specified by @code{ up }. -@code{} denotes the number of elements which the slice contains. -The delivered value is a string value, which is part of the specified -string. - -@item Array Element Values -An array element value is specified by @code{()} and -delivers a array element value of the mode of the specified array. - -@item Array Slice Values -An array slice is specified by @code{()}, where -@code{} can be either a range specified by expressions or by -@code{ up }. @code{} denotes the number of -arrayelements the slice contains. The delivered value is an array value -which is part of the specified array. - -@item Structure Field Values -A structure field value is derived by @code{.}, where @code{} indicates the name of a field specified -in the mode definition of the structure. The mode of the delivered value -corresponds to this mode definition in the structure definition. - -@item Procedure Call Value -The procedure call value is derived from the return value of the -procedure@footnote{If a procedure call is used for instance in an -expression, then this procedure is called with all its side -effects. This can lead to confusing results if used carelessly.}. - -Values of duration mode locations are represented by @code{ULONG} literals. - -Values of time mode locations appear as -@smallexample -@code{TIME(:)} -@end smallexample - - -@ignore -This is not implemented yet: -@item Built-in Value -@noindent -The following built in functions are provided: - -@table @code -@item @code{ADDR()} -@item @code{NUM()} -@item @code{PRED()} -@item @code{SUCC()} -@item @code{ABS()} -@item @code{CARD()} -@item @code{MAX()} -@item @code{MIN()} -@item @code{SIZE()} -@item @code{UPPER()} -@item @code{LOWER()} -@item @code{LENGTH()} -@item @code{SIN()} -@item @code{COS()} -@item @code{TAN()} -@item @code{ARCSIN()} -@item @code{ARCCOS()} -@item @code{ARCTAN()} -@item @code{EXP()} -@item @code{LN()} -@item @code{LOG()} -@item @code{SQRT()} -@end table - -For a detailed description refer to the GNU Chill implementation manual -chapter 1.6. -@end ignore - -@item Zero-adic Operator Value -The zero-adic operator value is derived from the instance value for the -current active process. - -@item Expression Values -The value delivered by an expression is the result of the evaluation of -the specified expression. If there are error conditions (mode -incompatibility, etc.) the evaluation of expressions is aborted with a -corresponding error message. Expressions may be parenthesised which -causes the evaluation of this expression before any other expression -which uses the result of the parenthesised expression. The following -operators are supported by @value{GDBN}: - -@table @code -@item @code{OR, ORIF, XOR} -@itemx @code{AND, ANDIF} -@itemx @code{NOT} -Logical operators defined over operands of boolean mode. - -@item @code{=, /=} -Equality and inequality operators defined over all modes. - -@item @code{>, >=} -@itemx @code{<, <=} -Relational operators defined over predefined modes. - -@item @code{+, -} -@itemx @code{*, /, MOD, REM} -Arithmetic operators defined over predefined modes. - -@item @code{-} -Change sign operator. - -@item @code{//} -String concatenation operator. - -@item @code{()} -String repetition operator. - -@item @code{->} -Referenced location operator which can be used either to take the -address of a location (@code{->loc}), or to dereference a reference -location (@code{loc->}). - -@item @code{OR, XOR} -@itemx @code{AND} -@itemx @code{NOT} -Powerset and bitstring operators. - -@item @code{>, >=} -@itemx @code{<, <=} -Powerset inclusion operators. - -@item @code{IN} -Membership operator. -@end table -@end table - -@node Chill type and range checks -@subsubsection Chill type and range checks - -@value{GDBN} considers two Chill variables mode equivalent if the sizes -of the two modes are equal. This rule applies recursively to more -complex datatypes which means that complex modes are treated -equivalent if all element modes (which also can be complex modes like -structures, arrays, etc.) have the same size. - -Range checking is done on all mathematical operations, assignment, array -index bounds and all built in procedures. - -Strong type checks are forced using the @value{GDBN} command @code{set -check strong}. This enforces strong type and range checks on all -operations where Chill constructs are used (expressions, built in -functions, etc.) in respect to the semantics as defined in the z.200 -language specification. - -All checks can be disabled by the @value{GDBN} command @code{set check -off}. - -@ignore -@c Deviations from the Chill Standard Z200/88 -see last paragraph ? -@end ignore - -@node Chill defaults -@subsubsection Chill defaults - -If type and range checking are set automatically by @value{GDBN}, they -both default to @code{on} whenever the working language changes to -Chill. This happens regardless of whether you or @value{GDBN} -selected the working language. - -If you allow @value{GDBN} to set the language automatically, then entering -code compiled from a file whose name ends with @file{.ch} sets the -working language to Chill. @xref{Automatically, ,Having @value{GDBN} set -the language automatically}, for further details. +@node Unsupported languages +@section Unsupported languages + +@cindex unsupported languages +@cindex minimal language +In addition to the other fully-supported programming languages, +@value{GDBN} also provides a pseudo-language, called @code{minimal}. +It does not represent a real programming language, but provides a set +of capabilities close to what the C or assembly languages provide. +This should allow most simple operations to be performed while debugging +an application that uses a language currently not supported by @value{GDBN}. + +If the language is set to @code{auto}, @value{GDBN} will automatically +select this language if the current frame corresponds to an unsupported +language. @node Symbols @chapter Examining the Symbol Table @@ -8580,9 +9112,9 @@ ordinarily parse a typical file name, like @file{foo.c}, as the three words @samp{foo} @samp{.} @samp{c}. To allow @value{GDBN} to recognize @samp{foo.c} as a single symbol, enclose it in single quotes; for example, -@example +@smallexample p 'foo.c'::x -@end example +@end smallexample @noindent looks up the value of @code{x} in the scope of the file @file{foo.c}. @@ -8607,10 +9139,10 @@ Print the name of a symbol which is stored at the address @var{addr}. If no symbol is stored exactly at @var{addr}, @value{GDBN} prints the nearest symbol and an offset from it: -@example +@smallexample (@value{GDBP}) info symbol 0x54320 _initialize_vx + 396 in section .text -@end example +@end smallexample @noindent This is the opposite of the @code{info address} command. You can use @@ -8641,14 +9173,14 @@ of just the name of the type. For example, for this variable declaration: -@example +@smallexample struct complex @{double real; double imag;@} v; -@end example +@end smallexample @noindent the two commands give this output: -@example +@smallexample @group (@value{GDBP}) whatis v type = struct complex @@ -8658,7 +9190,7 @@ type = struct complex @{ double imag; @} @end group -@end example +@end smallexample @noindent As with @code{whatis}, using @code{ptype} without an argument refers to @@ -8705,9 +9237,25 @@ collect}. @kindex info source @item info source -Show the name of the current source file---that is, the source file for -the function containing the current point of execution---and the language -it was written in. +Show information about the current source file---that is, the source file for +the function containing the current point of execution: +@itemize @bullet +@item +the name of the source file, and the directory containing it, +@item +the directory it was compiled in, +@item +its length, in lines, +@item +which programming language it is written in, +@item +whether the executable includes debugging information for that file, and +if so, what format the information is in (e.g., STABS, Dwarf 2, etc.), and +@item +whether the debugging information includes information about +preprocessor macros. +@end itemize + @kindex info sources @item info sources @@ -8724,8 +9272,8 @@ Print the names and data types of all defined functions whose names contain a match for regular expression @var{regexp}. Thus, @samp{info fun step} finds all functions whose names include @code{step}; @samp{info fun ^step} finds those whose names -start with @code{step}. If a function name contains characters -that conflict with the regular expression language (eg. +start with @code{step}. If a function name contains characters +that conflict with the regular expression language (eg. @samp{operator*()}), they may be quoted with a backslash. @kindex info variables @@ -8738,6 +9286,20 @@ Print the names and data types of all variables (except for local variables) whose names contain a match for regular expression @var{regexp}. +@kindex info classes +@item info classes +@itemx info classes @var{regexp} +Display all Objective-C classes in your program, or +(with the @var{regexp} argument) all those matching a particular regular +expression. + +@kindex info selectors +@item info selectors +@itemx info selectors @var{regexp} +Display all Objective-C selectors in your program, or +(with the @var{regexp} argument) all those matching a particular regular +expression. + @ignore This was never implemented. @kindex info methods @@ -8822,8 +9384,66 @@ files that @value{GDBN} has skimmed, but not yet read completely. Finally, required for each object file from which @value{GDBN} has read some symbols. @xref{Files, ,Commands to specify files}, for a discussion of how @value{GDBN} reads symbols (in the description of @code{symbol-file}). + +@kindex maint info symtabs +@kindex maint info psymtabs +@cindex listing @value{GDBN}'s internal symbol tables +@cindex symbol tables, listing @value{GDBN}'s internal +@cindex full symbol tables, listing @value{GDBN}'s internal +@cindex partial symbol tables, listing @value{GDBN}'s internal +@item maint info symtabs @r{[} @var{regexp} @r{]} +@itemx maint info psymtabs @r{[} @var{regexp} @r{]} + +List the @code{struct symtab} or @code{struct partial_symtab} +structures whose names match @var{regexp}. If @var{regexp} is not +given, list them all. The output includes expressions which you can +copy into a @value{GDBN} debugging this one to examine a particular +structure in more detail. For example: + +@smallexample +(@value{GDBP}) maint info psymtabs dwarf2read +@{ objfile /home/gnu/build/gdb/gdb + ((struct objfile *) 0x82e69d0) + @{ psymtab /home/gnu/src/gdb/dwarf2read.c + ((struct partial_symtab *) 0x8474b10) + readin no + fullname (null) + text addresses 0x814d3c8 -- 0x8158074 + globals (* (struct partial_symbol **) 0x8507a08 @@ 9) + statics (* (struct partial_symbol **) 0x40e95b78 @@ 2882) + dependencies (none) + @} +@} +(@value{GDBP}) maint info symtabs +(@value{GDBP}) +@end smallexample +@noindent +We see that there is one partial symbol table whose filename contains +the string @samp{dwarf2read}, belonging to the @samp{gdb} executable; +and we see that @value{GDBN} has not read in any symtabs yet at all. +If we set a breakpoint on a function, that will cause @value{GDBN} to +read the symtab for the compilation unit containing that function: + +@smallexample +(@value{GDBP}) break dwarf2_psymtab_to_symtab +Breakpoint 1 at 0x814e5da: file /home/gnu/src/gdb/dwarf2read.c, +line 1574. +(@value{GDBP}) maint info symtabs +@{ objfile /home/gnu/build/gdb/gdb + ((struct objfile *) 0x82e69d0) + @{ symtab /home/gnu/src/gdb/dwarf2read.c + ((struct symtab *) 0x86c1f38) + dirname (null) + fullname (null) + blockvector ((struct blockvector *) 0x86c1bd0) (primary) + debugformat DWARF 2 + @} +@} +(@value{GDBP}) +@end smallexample @end table + @node Altering @chapter Altering Execution @@ -8854,9 +9474,9 @@ address, or even return prematurely from a function. To alter the value of a variable, evaluate an assignment expression. @xref{Expressions, ,Expressions}. For example, -@example +@smallexample print x=4 -@end example +@end smallexample @noindent stores the value 4 into the variable @code{x}, and then prints the @@ -8880,22 +9500,22 @@ program has a variable @code{width}, you get an error if you try to set a new value with just @samp{set width=13}, because @value{GDBN} has the command @code{set width}: -@example +@smallexample (@value{GDBP}) whatis width type = double (@value{GDBP}) p width $4 = 13 (@value{GDBP}) set width=47 Invalid syntax in expression. -@end example +@end smallexample @noindent The invalid expression, of course, is @samp{=47}. In order to actually set the program's variable @code{width}, use -@example +@smallexample (@value{GDBP}) set var width=47 -@end example +@end smallexample Because the @code{set} command has many subcommands that can conflict with the names of program variables, it is a good idea to use the @@ -8904,7 +9524,7 @@ your program has a variable @code{g}, you run into problems if you try to set a new value with just @samp{set g=4}, because @value{GDBN} has the command @code{set gnutarget}, abbreviated @code{set g}: -@example +@smallexample @group (@value{GDBP}) whatis g type = double @@ -8922,16 +9542,16 @@ Starting program: /home/smith/cc_progs/a.out (@value{GDBP}) show g The current BFD target is "=4". @end group -@end example +@end smallexample @noindent The program variable @code{g} did not change, and you silently set the @code{gnutarget} to an invalid value. In order to set the variable @code{g}, use -@example +@smallexample (@value{GDBP}) set var g=4 -@end example +@end smallexample @value{GDBN} allows more implicit conversions in assignments than C; you can freely store an integer value into a pointer variable or vice versa, @@ -8946,9 +9566,9 @@ construct to generate a value of specified type at a specified address to memory location @code{0x83040} as an integer (which implies a certain size and representation in memory), and -@example +@smallexample set @{int@}0x83040 = 4 -@end example +@end smallexample @noindent stores the value 4 into that memory location. @@ -8991,9 +9611,9 @@ difference is that this does not start your program running; it only changes the address of where it @emph{will} run when you continue. For example, -@example +@smallexample set $pc = 0x485 -@end example +@end smallexample @noindent makes the next @code{continue} command or stepping command execute at @@ -9082,12 +9702,6 @@ execute a function from your program, but without cluttering the output with @code{void} returned values. If the result is not void, it is printed and saved in the value history. -@c OBSOLETE For the A29K, a user-controlled variable @code{call_scratch_address}, -@c OBSOLETE specifies the location of a scratch area to be used when @value{GDBN} -@c OBSOLETE calls a function in the target. This is necessary because the usual -@c OBSOLETE method of putting the scratch area on the stack does not work in systems -@c OBSOLETE that have separate instruction and data spaces. - @node Patching @section Patching programs @@ -9133,6 +9747,7 @@ program. To debug a core dump of a previous run, you must also tell @menu * Files:: Commands to specify files +* Separate Debug Files:: Debugging information in separate files * Symbol Errors:: Errors reading symbol files @end menu @@ -9338,7 +9953,7 @@ Some embedded operating systems, like Sun Chorus and VxWorks, can load relocatable files into an already running program; such systems typically make the requirements above easy to meet. However, it's important to recognize that many native systems use complex link -procedures (@code{.linkonce} section factoring and C++ constructor table +procedures (@code{.linkonce} section factoring and C@t{++} constructor table assembly, for example) that make the requirements difficult to meet. In general, one cannot assume that using @code{add-symbol-file} to read a relocatable object file's symbolic information will have the same effect @@ -9537,6 +10152,233 @@ Mb). Display the current autoloading size threshold, in megabytes. @end table +Shared libraries are also supported in many cross or remote debugging +configurations. A copy of the target's libraries need to be present on the +host system; they need to be the same as the target libraries, although the +copies on the target can be stripped as long as the copies on the host are +not. + +You need to tell @value{GDBN} where the target libraries are, so that it can +load the correct copies---otherwise, it may try to load the host's libraries. +@value{GDBN} has two variables to specify the search directories for target +libraries. + +@table @code +@kindex set solib-absolute-prefix +@item set solib-absolute-prefix @var{path} +If this variable is set, @var{path} will be used as a prefix for any +absolute shared library paths; many runtime loaders store the absolute +paths to the shared library in the target program's memory. If you use +@samp{solib-absolute-prefix} to find shared libraries, they need to be laid +out in the same way that they are on the target, with e.g.@: a +@file{/usr/lib} hierarchy under @var{path}. + +You can set the default value of @samp{solib-absolute-prefix} by using the +configure-time @samp{--with-sysroot} option. + +@kindex show solib-absolute-prefix +@item show solib-absolute-prefix +Display the current shared library prefix. + +@kindex set solib-search-path +@item set solib-search-path @var{path} +If this variable is set, @var{path} is a colon-separated list of directories +to search for shared libraries. @samp{solib-search-path} is used after +@samp{solib-absolute-prefix} fails to locate the library, or if the path to +the library is relative instead of absolute. If you want to use +@samp{solib-search-path} instead of @samp{solib-absolute-prefix}, be sure to +set @samp{solib-absolute-prefix} to a nonexistant directory to prevent +@value{GDBN} from finding your host's libraries. + +@kindex show solib-search-path +@item show solib-search-path +Display the current shared library search path. +@end table + + +@node Separate Debug Files +@section Debugging Information in Separate Files +@cindex separate debugging information files +@cindex debugging information in separate files +@cindex @file{.debug} subdirectories +@cindex debugging information directory, global +@cindex global debugging information directory + +@value{GDBN} allows you to put a program's debugging information in a +file separate from the executable itself, in a way that allows +@value{GDBN} to find and load the debugging information automatically. +Since debugging information can be very large --- sometimes larger +than the executable code itself --- some systems distribute debugging +information for their executables in separate files, which users can +install only when they need to debug a problem. + +If an executable's debugging information has been extracted to a +separate file, the executable should contain a @dfn{debug link} giving +the name of the debugging information file (with no directory +components), and a checksum of its contents. (The exact form of a +debug link is described below.) If the full name of the directory +containing the executable is @var{execdir}, and the executable has a +debug link that specifies the name @var{debugfile}, then @value{GDBN} +will automatically search for the debugging information file in three +places: + +@itemize @bullet +@item +the directory containing the executable file (that is, it will look +for a file named @file{@var{execdir}/@var{debugfile}}, +@item +a subdirectory of that directory named @file{.debug} (that is, the +file @file{@var{execdir}/.debug/@var{debugfile}}, and +@item +a subdirectory of the global debug file directory that includes the +executable's full path, and the name from the link (that is, the file +@file{@var{globaldebugdir}/@var{execdir}/@var{debugfile}}, where +@var{globaldebugdir} is the global debug file directory, and +@var{execdir} has been turned into a relative path). +@end itemize +@noindent +@value{GDBN} checks under each of these names for a debugging +information file whose checksum matches that given in the link, and +reads the debugging information from the first one it finds. + +So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls}, +which has a link containing the name @file{ls.debug}, and the global +debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look +for debug information in @file{/usr/bin/ls.debug}, +@file{/usr/bin/.debug/ls.debug}, and +@file{/usr/lib/debug/usr/bin/ls.debug}. + +You can set the global debugging info directory's name, and view the +name @value{GDBN} is currently using. + +@table @code + +@kindex set debug-file-directory +@item set debug-file-directory @var{directory} +Set the directory which @value{GDBN} searches for separate debugging +information files to @var{directory}. + +@kindex show debug-file-directory +@item show debug-file-directory +Show the directory @value{GDBN} searches for separate debugging +information files. + +@end table + +@cindex @code{.gnu_debuglink} sections +@cindex debug links +A debug link is a special section of the executable file named +@code{.gnu_debuglink}. The section must contain: + +@itemize +@item +A filename, with any leading directory components removed, followed by +a zero byte, +@item +zero to three bytes of padding, as needed to reach the next four-byte +boundary within the section, and +@item +a four-byte CRC checksum, stored in the same endianness used for the +executable file itself. The checksum is computed on the debugging +information file's full contents by the function given below, passing +zero as the @var{crc} argument. +@end itemize + +Any executable file format can carry a debug link, as long as it can +contain a section named @code{.gnu_debuglink} with the contents +described above. + +The debugging information file itself should be an ordinary +executable, containing a full set of linker symbols, sections, and +debugging information. The sections of the debugging information file +should have the same names, addresses and sizes as the original file, +but they need not contain any data --- much like a @code{.bss} section +in an ordinary executable. + +As of December 2002, there is no standard GNU utility to produce +separated executable / debugging information file pairs. Ulrich +Drepper's @file{elfutils} package, starting with version 0.53, +contains a version of the @code{strip} command such that the command +@kbd{strip foo -f foo.debug} removes the debugging information from +the executable file @file{foo}, places it in the file +@file{foo.debug}, and leaves behind a debug link in @file{foo}. + +Since there are many different ways to compute CRC's (different +polynomials, reversals, byte ordering, etc.), the simplest way to +describe the CRC used in @code{.gnu_debuglink} sections is to give the +complete code for a function that computes it: + +@kindex @code{gnu_debuglink_crc32} +@smallexample +unsigned long +gnu_debuglink_crc32 (unsigned long crc, + unsigned char *buf, size_t len) +@{ + static const unsigned long crc32_table[256] = + @{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d + @}; + unsigned char *end; + + crc = ~crc & 0xffffffff; + for (end = buf + len; buf < end; ++buf) + crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); + return ~crc & 0xffffffff; +@} +@end smallexample + + @node Symbol Errors @section Errors reading symbol files @@ -9765,11 +10607,11 @@ it somewhere in memory where it won't get clobbered by the download. @item target sim Builtin CPU simulator. @value{GDBN} includes simulators for most architectures. In general, -@example +@smallexample target sim load run -@end example +@end smallexample @noindent works; however, you cannot assume that a specific memory map, device drivers, or even basic I/O is available, although some simulators do @@ -9825,7 +10667,7 @@ specifies a fixed address. @cindex choosing target byte order @cindex target byte order -Some types of processors, such as the MIPS, PowerPC, and Hitachi SH, +Some types of processors, such as the MIPS, PowerPC, and Renesas SH, offer the ability to run either big-endian or little-endian byte orders. Usually the executable or symbol will include a bit to designate the endian-ness, and you will not need to worry about @@ -9877,9 +10719,7 @@ configuration of @value{GDBN}; use @code{help target} to list them. @node KOD @section Kernel Object Display - @cindex kernel object display -@cindex kernel object @cindex KOD Some targets support kernel object display. Using this facility, @@ -9888,41 +10728,151 @@ and can display information about operating system-level objects such as mutexes and other synchronization objects. Exactly which objects can be displayed is determined on a per-OS basis. +@kindex set os Use the @code{set os} command to set the operating system. This tells @value{GDBN} which kernel object display module to initialize: -@example +@smallexample (@value{GDBP}) set os cisco -@end example +@end smallexample + +@kindex show os +The associated command @code{show os} displays the operating system +set with the @code{set os} command; if no operating system has been +set, @code{show os} will display an empty string @samp{""}. If @code{set os} succeeds, @value{GDBN} will display some information about the operating system, and will create a new @code{info} command which can be used to query the target. The @code{info} command is named after the operating system: -@example +@kindex info cisco +@smallexample (@value{GDBP}) info cisco List of Cisco Kernel Objects Object Description any Any and all objects -@end example +@end smallexample Further subcommands can be used to query about particular objects known by the kernel. -There is currently no way to determine whether a given operating system -is supported other than to try it. +There is currently no way to determine whether a given operating +system is supported other than to try setting it with @kbd{set os +@var{name}}, where @var{name} is the name of the operating system you +want to try. @node Remote Debugging @chapter Debugging remote programs @menu +* Connecting:: Connecting to a remote target * Server:: Using the gdbserver program * NetWare:: Using the gdbserve.nlm program +* Remote configuration:: Remote configuration * remote stub:: Implementing a remote stub @end menu +@node Connecting +@section Connecting to a remote target + +On the @value{GDBN} host machine, you will need an unstripped copy of +your program, since @value{GDBN} needs symobl and debugging information. +Start up @value{GDBN} as usual, using the name of the local copy of your +program as the first argument. + +@cindex serial line, @code{target remote} +If you're using a serial line, you may want to give @value{GDBN} the +@w{@samp{--baud}} option, or use the @code{set remotebaud} command +before the @code{target} command. + +After that, use @code{target remote} to establish communications with +the target machine. Its argument specifies how to communicate---either +via a devicename attached to a direct serial line, or a TCP or UDP port +(possibly to a terminal server which in turn has a serial line to the +target). For example, to use a serial line connected to the device +named @file{/dev/ttyb}: + +@smallexample +target remote /dev/ttyb +@end smallexample + +@cindex TCP port, @code{target remote} +To use a TCP connection, use an argument of the form +@code{@var{host}:@var{port}} or @code{tcp:@var{host}:@var{port}}. +For example, to connect to port 2828 on a +terminal server named @code{manyfarms}: + +@smallexample +target remote manyfarms:2828 +@end smallexample + +If your remote target is actually running on the same machine as +your debugger session (e.g.@: a simulator of your target running on +the same host), you can omit the hostname. For example, to connect +to port 1234 on your local machine: + +@smallexample +target remote :1234 +@end smallexample +@noindent + +Note that the colon is still required here. + +@cindex UDP port, @code{target remote} +To use a UDP connection, use an argument of the form +@code{udp:@var{host}:@var{port}}. For example, to connect to UDP port 2828 +on a terminal server named @code{manyfarms}: + +@smallexample +target remote udp:manyfarms:2828 +@end smallexample + +When using a UDP connection for remote debugging, you should keep in mind +that the `U' stands for ``Unreliable''. UDP can silently drop packets on +busy or unreliable networks, which will cause havoc with your debugging +session. + +Now you can use all the usual commands to examine and change data and to +step and continue the remote program. + +@cindex interrupting remote programs +@cindex remote programs, interrupting +Whenever @value{GDBN} is waiting for the remote program, if you type the +interrupt character (often @key{C-C}), @value{GDBN} attempts to stop the +program. This may or may not succeed, depending in part on the hardware +and the serial drivers the remote system uses. If you type the +interrupt character once again, @value{GDBN} displays this prompt: + +@smallexample +Interrupted while waiting for the program. +Give up (and stop debugging it)? (y or n) +@end smallexample + +If you type @kbd{y}, @value{GDBN} abandons the remote debugging session. +(If you decide you want to try again later, you can use @samp{target +remote} again to connect once more.) If you type @kbd{n}, @value{GDBN} +goes back to waiting. + +@table @code +@kindex detach (remote) +@item detach +When you have finished debugging the remote program, you can use the +@code{detach} command to release it from @value{GDBN} control. +Detaching from the target normally resumes its execution, but the results +will depend on your particular remote stub. After the @code{detach} +command, @value{GDBN} is free to connect to another target. + +@kindex disconnect +@item disconnect +The @code{disconnect} command behaves like @code{detach}, except that +the target is generally not resumed. It will wait for @value{GDBN} +(this instance or another one) to connect and continue debugging. After +the @code{disconnect} command, @value{GDBN} is again free to connect to +another target. +@end table + @node Server @section Using the @code{gdbserver} program @@ -10005,34 +10955,28 @@ target> gdbserver @var{comm} --attach @var{pid} @var{pid} is the process ID of a currently running process. It isn't necessary to point @code{gdbserver} at a binary for the running process. -@item On the @value{GDBN} host machine, -you need an unstripped copy of your program, since @value{GDBN} needs -symbols and debugging information. Start up @value{GDBN} as usual, -using the name of the local copy of your program as the first argument. -(You may also need the @w{@samp{--baud}} option if the serial line is -running at anything other than 9600@dmn{bps}.) After that, use @code{target -remote} to establish communications with @code{gdbserver}. Its argument -is either a device name (usually a serial device, like -@file{/dev/ttyb}), or a TCP port descriptor in the form -@code{@var{host}:@var{PORT}}. For example: +@pindex pidof +@cindex attach to a program by name +You can debug processes by name instead of process ID if your target has the +@code{pidof} utility: @smallexample -(@value{GDBP}) target remote /dev/ttyb +target> gdbserver @var{comm} --attach `pidof @var{PROGRAM}` @end smallexample -@noindent -communicates with the server via serial line @file{/dev/ttyb}, and +In case more than one copy of @var{PROGRAM} is running, or @var{PROGRAM} +has multiple threads, most versions of @code{pidof} support the +@code{-s} option to only return the first process ID. -@smallexample -(@value{GDBP}) target remote the-target:2345 -@end smallexample - -@noindent -communicates via a TCP connection to port 2345 on host @w{@file{the-target}}. +@item On the host machine, +connect to your target (@pxref{Connecting,,Connecting to a remote target}). For TCP connections, you must start up @code{gdbserver} prior to using the @code{target remote} command. Otherwise you may get an error whose text depends on the host system, but which usually looks something like -@samp{Connection refused}. +@samp{Connection refused}. You don't need to use the @code{load} +command in @value{GDBN} when using gdbserver, since the program is +already on the target. + @end table @node NetWare @@ -10074,22 +11018,27 @@ using a 19200@dmn{bps} connection: load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt @end smallexample -@item On the @value{GDBN} host machine, -you need an unstripped copy of your program, since @value{GDBN} needs -symbols and debugging information. Start up @value{GDBN} as usual, -using the name of the local copy of your program as the first argument. -(You may also need the @w{@samp{--baud}} option if the serial line is -running at anything other than 9600@dmn{bps}. After that, use @code{target -remote} to establish communications with @code{gdbserve.nlm}. Its -argument is a device name (usually a serial device, like -@file{/dev/ttyb}). For example: +@item +On the @value{GDBN} host machine, connect to your target (@pxref{Connecting,, +Connecting to a remote target}). -@smallexample -(@value{GDBP}) target remote /dev/ttyb -@end smallexample +@end table -@noindent -communications with the server via serial line @file{/dev/ttyb}. +@node Remote configuration +@section Remote configuration + +The following configuration options are available when debugging remote +programs: + +@table @code +@kindex set remote hardware-watchpoint-limit +@kindex set remote hardware-breakpoint-limit +@anchor{set remote hardware-watchpoint-limit} +@anchor{set remote hardware-breakpoint-limit} +@item set remote hardware-watchpoint-limit @var{limit} +@itemx set remote hardware-breakpoint-limit @var{limit} +Restrict @value{GDBN} to using @var{limit} remote hardware breakpoint or +watchpoints. A limit of -1, the default, is treated as unlimited. @end table @node remote stub @@ -10172,9 +11121,9 @@ For Motorola 680x0 architectures. @item sh-stub.c @cindex @file{sh-stub.c} -@cindex Hitachi +@cindex Renesas @cindex SH -For Hitachi SH architectures. +For Renesas SH architectures. @item sparc-stub.c @cindex @file{sparc-stub.c} @@ -10359,18 +11308,18 @@ Make sure you have defined the supporting low-level routines @item Insert these lines near the top of your program: -@example +@smallexample set_debug_traps(); breakpoint(); -@end example +@end smallexample @item For the 680x0 stub only, you need to provide a variable called @code{exceptionHook}. Normally you just use: -@example +@smallexample void (*exceptionHook)() = 0; -@end example +@end smallexample @noindent but if before calling @code{set_debug_traps}, you set it to point to a @@ -10394,71 +11343,11 @@ Download your program to your target machine (or get it there by whatever means the manufacturer provides), and start it. @item -To start remote debugging, run @value{GDBN} on the host machine, and specify -as an executable file the program that is running in the remote machine. -This tells @value{GDBN} how to find your program's symbols and the contents -of its pure text. +Start @value{GDBN} on the host, and connect to the target +(@pxref{Connecting,,Connecting to a remote target}). -@item -@cindex serial line, @code{target remote} -Establish communication using the @code{target remote} command. -Its argument specifies how to communicate with the target -machine---either via a devicename attached to a direct serial line, or a -TCP port (usually to a terminal server which in turn has a serial line -to the target). For example, to use a serial line connected to the -device named @file{/dev/ttyb}: - -@example -target remote /dev/ttyb -@end example - -@cindex TCP port, @code{target remote} -To use a TCP connection, use an argument of the form -@code{@var{host}:port}. For example, to connect to port 2828 on a -terminal server named @code{manyfarms}: - -@example -target remote manyfarms:2828 -@end example - -If your remote target is actually running on the same machine as -your debugger session (e.g.@: a simulator of your target running on -the same host), you can omit the hostname. For example, to connect -to port 1234 on your local machine: - -@example -target remote :1234 -@end example -@noindent - -Note that the colon is still required here. @end enumerate -Now you can use all the usual commands to examine and change data and to -step and continue the remote program. - -To resume the remote program and stop debugging it, use the @code{detach} -command. - -@cindex interrupting remote programs -@cindex remote programs, interrupting -Whenever @value{GDBN} is waiting for the remote program, if you type the -interrupt character (often @key{C-C}), @value{GDBN} attempts to stop the -program. This may or may not succeed, depending in part on the hardware -and the serial drivers the remote system uses. If you type the -interrupt character once again, @value{GDBN} displays this prompt: - -@example -Interrupted while waiting for the program. -Give up (and stop debugging it)? (y or n) -@end example - -If you type @kbd{y}, @value{GDBN} abandons the remote debugging session. -(If you decide you want to try again later, you can use @samp{target -remote} again to connect once more.) If you type @kbd{n}, @value{GDBN} -goes back to waiting. - - @node Configurations @chapter Configuration-Specific Information @@ -10512,7 +11401,7 @@ this facility, the command @code{info proc} is available to report on several kinds of information about the process running your program. @code{info proc} works only on SVR4 systems that include the @code{procfs} code. This includes OSF/1 (Digital Unix), Solaris, Irix, -and Unixware, but not HP-UX or Linux, for example. +and Unixware, but not HP-UX or @sc{gnu}/Linux, for example. @table @code @kindex info proc @@ -10652,10 +11541,10 @@ accepts addresses which may belong to @emph{any} segment. For example, here's how to display the Page Table entry for the page where the variable @code{i} is stored: -@smallexample +@smallexample @exdent @code{(@value{GDBP}) info dos address-pte __djgpp_base_address + (char *)&i} @exdent @code{Page Table entry for address 0x11a00d30:} -@exdent @code{Base=0x02698000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0xd30} +@exdent @code{Base=0x02698000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0xd30} @end smallexample @noindent @@ -10694,9 +11583,12 @@ This command is supported only with some DPMI servers. @cindex native Cygwin debugging @cindex Cygwin-specific commands -@value{GDBN} supports native debugging of MS Windows programs, and -defines a few commands specific to the Cygwin port. This -subsection describes those commands. +@value{GDBN} supports native debugging of MS Windows programs, including +DLLs with and without symbolic debugging information. There are various +additional Cygwin-specific commands, described in this subsection. The +subsubsection @pxref{Non-debug DLL symbols} describes working with DLLs +that have no debugging symbols. + @table @code @kindex info w32 @@ -10721,9 +11613,9 @@ This is a Cygwin specific alias of info shared. This command loads symbols from a dll similarly to add-sym command but without the need to specify a base address. -@kindex set new-console +@kindex set new-console @item set new-console @var{mode} -If @var{mode} is @code{on} the debuggee will +If @var{mode} is @code{on} the debuggee will be started in a new console on next start. If @var{mode} is @code{off}i, the debuggee will be started in the same console as the debugger. @@ -10750,17 +11642,17 @@ This boolean value adds debug output concerning events seen by the debugger. @kindex set debugexec @item set debugexec -This boolean value adds debug output concerning execute events +This boolean value adds debug output concerning execute events seen by the debugger. @kindex set debugexceptions @item set debugexceptions -This boolean value adds debug ouptut concerning exception events +This boolean value adds debug ouptut concerning exception events seen by the debugger. @kindex set debugmemory @item set debugmemory -This boolean value adds debug ouptut concerning memory events +This boolean value adds debug ouptut concerning memory events seen by the debugger. @kindex set shell @@ -10774,6 +11666,130 @@ Displays if the debuggee will be started with a shell. @end table +@menu +* Non-debug DLL symbols:: Support for DLLs without debugging symbols +@end menu + +@node Non-debug DLL symbols +@subsubsection Support for DLLs without debugging symbols +@cindex DLLs with no debugging symbols +@cindex Minimal symbols and DLLs + +Very often on windows, some of the DLLs that your program relies on do +not include symbolic debugging information (for example, +@file{kernel32.dll}). When @value{GDBN} doesn't recognize any debugging +symbols in a DLL, it relies on the minimal amount of symbolic +information contained in the DLL's export table. This subsubsection +describes working with such symbols, known internally to @value{GDBN} as +``minimal symbols''. + +Note that before the debugged program has started execution, no DLLs +will have been loaded. The easiest way around this problem is simply to +start the program --- either by setting a breakpoint or letting the +program run once to completion. It is also possible to force +@value{GDBN} to load a particular DLL before starting the executable --- +see the shared library information in @pxref{Files} or the +@code{dll-symbols} command in @pxref{Cygwin Native}. Currently, +explicitly loading symbols from a DLL with no debugging information will +cause the symbol names to be duplicated in @value{GDBN}'s lookup table, +which may adversely affect symbol lookup performance. + +@subsubsection DLL name prefixes + +In keeping with the naming conventions used by the Microsoft debugging +tools, DLL export symbols are made available with a prefix based on the +DLL name, for instance @code{KERNEL32!CreateFileA}. The plain name is +also entered into the symbol table, so @code{CreateFileA} is often +sufficient. In some cases there will be name clashes within a program +(particularly if the executable itself includes full debugging symbols) +necessitating the use of the fully qualified name when referring to the +contents of the DLL. Use single-quotes around the name to avoid the +exclamation mark (``!'') being interpreted as a language operator. + +Note that the internal name of the DLL may be all upper-case, even +though the file name of the DLL is lower-case, or vice-versa. Since +symbols within @value{GDBN} are @emph{case-sensitive} this may cause +some confusion. If in doubt, try the @code{info functions} and +@code{info variables} commands or even @code{maint print msymbols} (see +@pxref{Symbols}). Here's an example: + +@smallexample +(gdb) info function CreateFileA +All functions matching regular expression "CreateFileA": + +Non-debugging symbols: +0x77e885f4 CreateFileA +0x77e885f4 KERNEL32!CreateFileA +@end smallexample + +@smallexample +(gdb) info function ! +All functions matching regular expression "!": + +Non-debugging symbols: +0x6100114c cygwin1!__assert +0x61004034 cygwin1!_dll_crt0@@0 +0x61004240 cygwin1!dll_crt0(per_process *) +[etc...] +@end smallexample + +@subsubsection Working with minimal symbols + +Symbols extracted from a DLL's export table do not contain very much +type information. All that @value{GDBN} can do is guess whether a symbol +refers to a function or variable depending on the linker section that +contains the symbol. Also note that the actual contents of the memory +contained in a DLL are not available unless the program is running. This +means that you cannot examine the contents of a variable or disassemble +a function within a DLL without a running program. + +Variables are generally treated as pointers and dereferenced +automatically. For this reason, it is often necessary to prefix a +variable name with the address-of operator (``&'') and provide explicit +type information in the command. Here's an example of the type of +problem: + +@smallexample +(gdb) print 'cygwin1!__argv' +$1 = 268572168 +@end smallexample + +@smallexample +(gdb) x 'cygwin1!__argv' +0x10021610: "\230y\"" +@end smallexample + +And two possible solutions: + +@smallexample +(gdb) print ((char **)'cygwin1!__argv')[0] +$2 = 0x22fd98 "/cygdrive/c/mydirectory/myprogram" +@end smallexample + +@smallexample +(gdb) x/2x &'cygwin1!__argv' +0x610c0aa8 : 0x10021608 0x00000000 +(gdb) x/x 0x10021608 +0x10021608: 0x0022fd98 +(gdb) x/s 0x0022fd98 +0x22fd98: "/cygdrive/c/mydirectory/myprogram" +@end smallexample + +Setting a break point within a DLL is possible even before the program +starts execution. However, under these circumstances, @value{GDBN} can't +examine the initial instructions of the function in order to skip the +function's frame set-up code. You can work around this by using ``*&'' +to set the breakpoint at a raw memory address: + +@smallexample +(gdb) break *&'python22!PyOS_Readline' +Breakpoint 1 at 0x1e04eff0 +@end smallexample + +The author of these extensions is not entirely convinced that setting a +break point within a shared DLL like @file{kernel32.dll} is completely +safe. + @node Embedded OS @section Embedded Operating Systems @@ -10845,9 +11861,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}} (or @value{GDBN} comes up showing the prompt: -@example +@smallexample (vxgdb) -@end example +@end smallexample @menu * VxWorks Connection:: Connecting to VxWorks @@ -10861,9 +11877,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}} (or The @value{GDBN} command @code{target} lets you connect to a VxWorks target on the network. To connect to a target whose host name is ``@code{tt}'', type: -@example +@smallexample (vxgdb) target vxworks tt -@end example +@end smallexample @need 750 @value{GDBN} displays messages like these: @@ -10880,9 +11896,9 @@ these files by searching the directories listed in the command search path (@pxref{Environment, ,Your program's environment}); if it fails to find an object file, it displays a message such as: -@example +@smallexample prog.o: No such file or directory. -@end example +@end smallexample When this happens, add the appropriate directory to the search path with the @value{GDBN} command @code{path}, and execute the @code{target} @@ -10908,17 +11924,17 @@ the file by its name, without any path. For instance, a program and in @file{@var{hostpath}/vw/demo/rdb} on the host. To load this program, type this on VxWorks: -@example +@smallexample -> cd "@var{vxpath}/vw/demo/rdb" -@end example +@end smallexample @noindent Then, in @value{GDBN}, type: -@example +@smallexample (vxgdb) cd @var{hostpath}/vw/demo/rdb (vxgdb) load prog.o -@end example +@end smallexample @value{GDBN} displays a response similar to this: @@ -10941,9 +11957,9 @@ table.) You can also attach to an existing task using the @code{attach} command as follows: -@example +@smallexample (vxgdb) attach @var{task} -@end example +@end smallexample @noindent where @var{task} is the VxWorks hexadecimal task ID. The task can be running @@ -10957,270 +11973,23 @@ This section goes into details specific to particular embedded configurations. -@c OBSOLETE * A29K Embedded:: AMD A29K Embedded @menu * ARM:: ARM -* H8/300:: Hitachi H8/300 -* H8/500:: Hitachi H8/500 -* i960:: Intel i960 -* M32R/D:: Mitsubishi M32R/D +* H8/300:: Renesas H8/300 +* H8/500:: Renesas H8/500 +* M32R/D:: Renesas M32R/D * M68K:: Motorola M68K -* M88K:: Motorola M88K * MIPS Embedded:: MIPS Embedded +* OpenRISC 1000:: OpenRisc 1000 * PA:: HP PA Embedded * PowerPC: PowerPC -* SH:: Hitachi SH +* SH:: Renesas SH * Sparclet:: Tsqware Sparclet * Sparclite:: Fujitsu Sparclite * ST2000:: Tandem ST2000 * Z8000:: Zilog Z8000 @end menu -@c OBSOLETE @node A29K Embedded -@c OBSOLETE @subsection AMD A29K Embedded -@c OBSOLETE -@c OBSOLETE @menu -@c OBSOLETE * A29K UDI:: -@c OBSOLETE * A29K EB29K:: -@c OBSOLETE * Comms (EB29K):: Communications setup -@c OBSOLETE * gdb-EB29K:: EB29K cross-debugging -@c OBSOLETE * Remote Log:: Remote log -@c OBSOLETE @end menu -@c OBSOLETE -@c OBSOLETE @table @code -@c OBSOLETE -@c OBSOLETE @kindex target adapt -@c OBSOLETE @item target adapt @var{dev} -@c OBSOLETE Adapt monitor for A29K. -@c OBSOLETE -@c OBSOLETE @kindex target amd-eb -@c OBSOLETE @item target amd-eb @var{dev} @var{speed} @var{PROG} -@c OBSOLETE @cindex AMD EB29K -@c OBSOLETE Remote PC-resident AMD EB29K board, attached over serial lines. -@c OBSOLETE @var{dev} is the serial device, as for @code{target remote}; -@c OBSOLETE @var{speed} allows you to specify the linespeed; and @var{PROG} is the -@c OBSOLETE name of the program to be debugged, as it appears to DOS on the PC. -@c OBSOLETE @xref{A29K EB29K, ,EBMON protocol for AMD29K}. -@c OBSOLETE -@c OBSOLETE @end table -@c OBSOLETE -@c OBSOLETE @node A29K UDI -@c OBSOLETE @subsubsection A29K UDI -@c OBSOLETE -@c OBSOLETE @cindex UDI -@c OBSOLETE @cindex AMD29K via UDI -@c OBSOLETE -@c OBSOLETE @value{GDBN} supports AMD's UDI (``Universal Debugger Interface'') -@c OBSOLETE protocol for debugging the a29k processor family. To use this -@c OBSOLETE configuration with AMD targets running the MiniMON monitor, you need the -@c OBSOLETE program @code{MONTIP}, available from AMD at no charge. You can also -@c OBSOLETE use @value{GDBN} with the UDI-conformant a29k simulator program -@c OBSOLETE @code{ISSTIP}, also available from AMD. -@c OBSOLETE -@c OBSOLETE @table @code -@c OBSOLETE @item target udi @var{keyword} -@c OBSOLETE @kindex udi -@c OBSOLETE Select the UDI interface to a remote a29k board or simulator, where -@c OBSOLETE @var{keyword} is an entry in the AMD configuration file @file{udi_soc}. -@c OBSOLETE This file contains keyword entries which specify parameters used to -@c OBSOLETE connect to a29k targets. If the @file{udi_soc} file is not in your -@c OBSOLETE working directory, you must set the environment variable @samp{UDICONF} -@c OBSOLETE to its pathname. -@c OBSOLETE @end table -@c OBSOLETE -@c OBSOLETE @node A29K EB29K -@c OBSOLETE @subsubsection EBMON protocol for AMD29K -@c OBSOLETE -@c OBSOLETE @cindex EB29K board -@c OBSOLETE @cindex running 29K programs -@c OBSOLETE -@c OBSOLETE AMD distributes a 29K development board meant to fit in a PC, together -@c OBSOLETE with a DOS-hosted monitor program called @code{EBMON}. As a shorthand -@c OBSOLETE term, this development system is called the ``EB29K''. To use -@c OBSOLETE @value{GDBN} from a Unix system to run programs on the EB29K board, you -@c OBSOLETE must first connect a serial cable between the PC (which hosts the EB29K -@c OBSOLETE board) and a serial port on the Unix system. In the following, we -@c OBSOLETE assume you've hooked the cable between the PC's @file{COM1} port and -@c OBSOLETE @file{/dev/ttya} on the Unix system. -@c OBSOLETE -@c OBSOLETE @node Comms (EB29K) -@c OBSOLETE @subsubsection Communications setup -@c OBSOLETE -@c OBSOLETE The next step is to set up the PC's port, by doing something like this -@c OBSOLETE in DOS on the PC: -@c OBSOLETE -@c OBSOLETE @example -@c OBSOLETE C:\> MODE com1:9600,n,8,1,none -@c OBSOLETE @end example -@c OBSOLETE -@c OBSOLETE @noindent -@c OBSOLETE This example---run on an MS DOS 4.0 system---sets the PC port to 9600 -@c OBSOLETE bps, no parity, eight data bits, one stop bit, and no ``retry'' action; -@c OBSOLETE you must match the communications parameters when establishing the Unix -@c OBSOLETE end of the connection as well. -@c OBSOLETE @c FIXME: Who knows what this "no retry action" crud from the DOS manual may -@c OBSOLETE @c mean? It's optional; leave it out? ---doc@cygnus.com, 25feb91 -@c OBSOLETE @c -@c OBSOLETE @c It's optional, but it's unwise to omit it: who knows what is the -@c OBSOLETE @c default value set when the DOS machines boots? "No retry" means that -@c OBSOLETE @c the DOS serial device driver won't retry the operation if it fails; -@c OBSOLETE @c I understand that this is needed because the GDB serial protocol -@c OBSOLETE @c handles any errors and retransmissions itself. ---Eli Zaretskii, 3sep99 -@c OBSOLETE -@c OBSOLETE To give control of the PC to the Unix side of the serial line, type -@c OBSOLETE the following at the DOS console: -@c OBSOLETE -@c OBSOLETE @example -@c OBSOLETE C:\> CTTY com1 -@c OBSOLETE @end example -@c OBSOLETE -@c OBSOLETE @noindent -@c OBSOLETE (Later, if you wish to return control to the DOS console, you can use -@c OBSOLETE the command @code{CTTY con}---but you must send it over the device that -@c OBSOLETE had control, in our example over the @file{COM1} serial line.) -@c OBSOLETE -@c OBSOLETE From the Unix host, use a communications program such as @code{tip} or -@c OBSOLETE @code{cu} to communicate with the PC; for example, -@c OBSOLETE -@c OBSOLETE @example -@c OBSOLETE cu -s 9600 -l /dev/ttya -@c OBSOLETE @end example -@c OBSOLETE -@c OBSOLETE @noindent -@c OBSOLETE The @code{cu} options shown specify, respectively, the linespeed and the -@c OBSOLETE serial port to use. If you use @code{tip} instead, your command line -@c OBSOLETE may look something like the following: -@c OBSOLETE -@c OBSOLETE @example -@c OBSOLETE tip -9600 /dev/ttya -@c OBSOLETE @end example -@c OBSOLETE -@c OBSOLETE @noindent -@c OBSOLETE Your system may require a different name where we show -@c OBSOLETE @file{/dev/ttya} as the argument to @code{tip}. The communications -@c OBSOLETE parameters, including which port to use, are associated with the -@c OBSOLETE @code{tip} argument in the ``remote'' descriptions file---normally the -@c OBSOLETE system table @file{/etc/remote}. -@c OBSOLETE @c FIXME: What if anything needs doing to match the "n,8,1,none" part of -@c OBSOLETE @c the DOS side's comms setup? cu can support -o (odd -@c OBSOLETE @c parity), -e (even parity)---apparently no settings for no parity or -@c OBSOLETE @c for character size. Taken from stty maybe...? John points out tip -@c OBSOLETE @c can set these as internal variables, eg ~s parity=none; man stty -@c OBSOLETE @c suggests that it *might* work to stty these options with stdin or -@c OBSOLETE @c stdout redirected... ---doc@cygnus.com, 25feb91 -@c OBSOLETE @c -@c OBSOLETE @c There's nothing to be done for the "none" part of the DOS MODE -@c OBSOLETE @c command. The rest of the parameters should be matched by the -@c OBSOLETE @c baudrate, bits, and parity used by the Unix side. ---Eli Zaretskii, 3Sep99 -@c OBSOLETE -@c OBSOLETE @kindex EBMON -@c OBSOLETE Using the @code{tip} or @code{cu} connection, change the DOS working -@c OBSOLETE directory to the directory containing a copy of your 29K program, then -@c OBSOLETE start the PC program @code{EBMON} (an EB29K control program supplied -@c OBSOLETE with your board by AMD). You should see an initial display from -@c OBSOLETE @code{EBMON} similar to the one that follows, ending with the -@c OBSOLETE @code{EBMON} prompt @samp{#}--- -@c OBSOLETE -@c OBSOLETE @example -@c OBSOLETE C:\> G: -@c OBSOLETE -@c OBSOLETE G:\> CD \usr\joe\work29k -@c OBSOLETE -@c OBSOLETE G:\USR\JOE\WORK29K> EBMON -@c OBSOLETE Am29000 PC Coprocessor Board Monitor, version 3.0-18 -@c OBSOLETE Copyright 1990 Advanced Micro Devices, Inc. -@c OBSOLETE Written by Gibbons and Associates, Inc. -@c OBSOLETE -@c OBSOLETE Enter '?' or 'H' for help -@c OBSOLETE -@c OBSOLETE PC Coprocessor Type = EB29K -@c OBSOLETE I/O Base = 0x208 -@c OBSOLETE Memory Base = 0xd0000 -@c OBSOLETE -@c OBSOLETE Data Memory Size = 2048KB -@c OBSOLETE Available I-RAM Range = 0x8000 to 0x1fffff -@c OBSOLETE Available D-RAM Range = 0x80002000 to 0x801fffff -@c OBSOLETE -@c OBSOLETE PageSize = 0x400 -@c OBSOLETE Register Stack Size = 0x800 -@c OBSOLETE Memory Stack Size = 0x1800 -@c OBSOLETE -@c OBSOLETE CPU PRL = 0x3 -@c OBSOLETE Am29027 Available = No -@c OBSOLETE Byte Write Available = Yes -@c OBSOLETE -@c OBSOLETE # ~. -@c OBSOLETE @end example -@c OBSOLETE -@c OBSOLETE Then exit the @code{cu} or @code{tip} program (done in the example by -@c OBSOLETE typing @code{~.} at the @code{EBMON} prompt). @code{EBMON} keeps -@c OBSOLETE running, ready for @value{GDBN} to take over. -@c OBSOLETE -@c OBSOLETE For this example, we've assumed what is probably the most convenient -@c OBSOLETE way to make sure the same 29K program is on both the PC and the Unix -@c OBSOLETE system: a PC/NFS connection that establishes ``drive @file{G:}'' on the -@c OBSOLETE PC as a file system on the Unix host. If you do not have PC/NFS or -@c OBSOLETE something similar connecting the two systems, you must arrange some -@c OBSOLETE other way---perhaps floppy-disk transfer---of getting the 29K program -@c OBSOLETE from the Unix system to the PC; @value{GDBN} does @emph{not} download it over the -@c OBSOLETE serial line. -@c OBSOLETE -@c OBSOLETE @node gdb-EB29K -@c OBSOLETE @subsubsection EB29K cross-debugging -@c OBSOLETE -@c OBSOLETE Finally, @code{cd} to the directory containing an image of your 29K -@c OBSOLETE program on the Unix system, and start @value{GDBN}---specifying as argument the -@c OBSOLETE name of your 29K program: -@c OBSOLETE -@c OBSOLETE @example -@c OBSOLETE cd /usr/joe/work29k -@c OBSOLETE @value{GDBP} myfoo -@c OBSOLETE @end example -@c OBSOLETE -@c OBSOLETE @need 500 -@c OBSOLETE Now you can use the @code{target} command: -@c OBSOLETE -@c OBSOLETE @example -@c OBSOLETE target amd-eb /dev/ttya 9600 MYFOO -@c OBSOLETE @c FIXME: test above 'target amd-eb' as spelled, with caps! caps are meant to -@c OBSOLETE @c emphasize that this is the name as seen by DOS (since I think DOS is -@c OBSOLETE @c single-minded about case of letters). ---doc@cygnus.com, 25feb91 -@c OBSOLETE @end example -@c OBSOLETE -@c OBSOLETE @noindent -@c OBSOLETE In this example, we've assumed your program is in a file called -@c OBSOLETE @file{myfoo}. Note that the filename given as the last argument to -@c OBSOLETE @code{target amd-eb} should be the name of the program as it appears to DOS. -@c OBSOLETE In our example this is simply @code{MYFOO}, but in general it can include -@c OBSOLETE a DOS path, and depending on your transfer mechanism may not resemble -@c OBSOLETE the name on the Unix side. -@c OBSOLETE -@c OBSOLETE At this point, you can set any breakpoints you wish; when you are ready -@c OBSOLETE to see your program run on the 29K board, use the @value{GDBN} command -@c OBSOLETE @code{run}. -@c OBSOLETE -@c OBSOLETE To stop debugging the remote program, use the @value{GDBN} @code{detach} -@c OBSOLETE command. -@c OBSOLETE -@c OBSOLETE To return control of the PC to its console, use @code{tip} or @code{cu} -@c OBSOLETE once again, after your @value{GDBN} session has concluded, to attach to -@c OBSOLETE @code{EBMON}. You can then type the command @code{q} to shut down -@c OBSOLETE @code{EBMON}, returning control to the DOS command-line interpreter. -@c OBSOLETE Type @kbd{CTTY con} to return command input to the main DOS console, -@c OBSOLETE and type @kbd{~.} to leave @code{tip} or @code{cu}. -@c OBSOLETE -@c OBSOLETE @node Remote Log -@c OBSOLETE @subsubsection Remote log -@c OBSOLETE @cindex @file{eb.log}, a log file for EB29K -@c OBSOLETE @cindex log file for EB29K -@c OBSOLETE -@c OBSOLETE The @code{target amd-eb} command creates a file @file{eb.log} in the -@c OBSOLETE current working directory, to help debug problems with the connection. -@c OBSOLETE @file{eb.log} records all the output from @code{EBMON}, including echoes -@c OBSOLETE of the commands sent to it. Running @samp{tail -f} on this file in -@c OBSOLETE another window often helps to understand trouble with @code{EBMON}, or -@c OBSOLETE unexpected events on the PC side of the connection. - @node ARM @subsection ARM @@ -11239,50 +12008,50 @@ ARM Demon monitor. @end table @node H8/300 -@subsection Hitachi H8/300 +@subsection Renesas H8/300 @table @code @kindex target hms@r{, with H8/300} @item target hms @var{dev} -A Hitachi SH, H8/300, or H8/500 board, attached via serial line to your host. +A Renesas SH, H8/300, or H8/500 board, attached via serial line to your host. Use special commands @code{device} and @code{speed} to control the serial line and the communications speed used. @kindex target e7000@r{, with H8/300} @item target e7000 @var{dev} -E7000 emulator for Hitachi H8 and SH. +E7000 emulator for Renesas H8 and SH. @kindex target sh3@r{, with H8/300} @kindex target sh3e@r{, with H8/300} @item target sh3 @var{dev} @itemx target sh3e @var{dev} -Hitachi SH-3 and SH-3E target systems. +Renesas SH-3 and SH-3E target systems. @end table @cindex download to H8/300 or H8/500 @cindex H8/300 or H8/500 download -@cindex download to Hitachi SH -@cindex Hitachi SH download -When you select remote debugging to a Hitachi SH, H8/300, or H8/500 -board, the @code{load} command downloads your program to the Hitachi +@cindex download to Renesas SH +@cindex Renesas SH download +When you select remote debugging to a Renesas SH, H8/300, or H8/500 +board, the @code{load} command downloads your program to the Renesas board and also opens it as the current executable target for @value{GDBN} on your host (like the @code{file} command). @value{GDBN} needs to know these things to talk to your -Hitachi SH, H8/300, or H8/500: +Renesas SH, H8/300, or H8/500: @enumerate @item that you want to use @samp{target hms}, the remote debugging interface -for Hitachi microprocessors, or @samp{target e7000}, the in-circuit -emulator for the Hitachi SH and the Hitachi 300H. (@samp{target hms} is -the default when @value{GDBN} is configured specifically for the Hitachi SH, +for Renesas microprocessors, or @samp{target e7000}, the in-circuit +emulator for the Renesas SH and the Renesas 300H. (@samp{target hms} is +the default when @value{GDBN} is configured specifically for the Renesas SH, H8/300, or H8/500.) @item -what serial device connects your host to your Hitachi board (the first +what serial device connects your host to your Renesas board (the first serial device available on your host is the default). @item @@ -11290,24 +12059,24 @@ what speed to use over the serial device. @end enumerate @menu -* Hitachi Boards:: Connecting to Hitachi boards. -* Hitachi ICE:: Using the E7000 In-Circuit Emulator. -* Hitachi Special:: Special @value{GDBN} commands for Hitachi micros. +* Renesas Boards:: Connecting to Renesas boards. +* Renesas ICE:: Using the E7000 In-Circuit Emulator. +* Renesas Special:: Special @value{GDBN} commands for Renesas micros. @end menu -@node Hitachi Boards -@subsubsection Connecting to Hitachi boards +@node Renesas Boards +@subsubsection Connecting to Renesas boards @c only for Unix hosts @kindex device -@cindex serial device, Hitachi micros +@cindex serial device, Renesas micros Use the special @code{@value{GDBN}} command @samp{device @var{port}} if you need to explicitly set the serial device. The default @var{port} is the first available port on your host. This is only necessary on Unix hosts, where it is typically something like @file{/dev/ttya}. @kindex speed -@cindex serial line speed, Hitachi micros +@cindex serial line speed, Renesas micros @code{@value{GDBN}} has another special command to set the communications speed: @samp{speed @var{bps}}. This command also is only used from Unix hosts; on DOS hosts, set the line speed as usual from outside @value{GDBN} with @@ -11315,7 +12084,7 @@ the DOS @code{mode} command (for instance, @w{@kbd{mode com2:9600,n,8,1,p}} for a 9600@dmn{bps} connection). The @samp{device} and @samp{speed} commands are available only when you -use a Unix host to debug your Hitachi microprocessor programs. If you +use a Unix host to debug your Renesas microprocessor programs. If you use a DOS host, @value{GDBN} depends on an auxiliary terminate-and-stay-resident program called @code{asynctsr} to communicate with the development board @@ -11325,7 +12094,7 @@ to set up the serial port on the DOS side. The following sample session illustrates the steps needed to start a program under @value{GDBN} control on an H8/300. The example uses a sample H8/300 program called @file{t.x}. The procedure is the same for -the Hitachi SH and the H8/500. +the Renesas SH and the H8/500. First hook up your development board. In this example, we use a board attached to serial port @code{COM2}; if you use a different serial @@ -11335,7 +12104,7 @@ debugger, you give it just the numeric part of the serial port's name; for example, @samp{asyncstr 2} below runs @code{asyncstr} on @code{COM2}. -@example +@smallexample C:\H8300\TEST> asynctsr 2 C:\H8300\TEST> mode com2:9600,n,8,1,p @@ -11343,7 +12112,7 @@ Resident portion of MODE loaded COM2: 9600, n, 8, 1, p -@end example +@end smallexample @quotation @emph{Warning:} We have noticed a bug in PC-NFS that conflicts with @@ -11358,7 +12127,7 @@ connected, you can start up @value{GDBN}. Call @code{@value{GDBP}} with the name of your program as the argument. @code{@value{GDBN}} prompts you, as usual, with the prompt @samp{(@value{GDBP})}. Use two special commands to begin your debugging session: @samp{target hms} to specify -cross-debugging to the Hitachi board, and the @code{load} command to +cross-debugging to the Renesas board, and the @code{load} command to download your program to the board. @code{load} displays the names of the program's sections, and a @samp{*} for each 2K of data downloaded. (If you want to refresh @value{GDBN} data on symbols or on the @@ -11408,12 +12177,12 @@ to detect program completion. In either case, @value{GDBN} sees the effect of a @sc{reset} on the development board as a ``normal exit'' of your program. -@node Hitachi ICE +@node Renesas ICE @subsubsection Using the E7000 in-circuit emulator -@kindex target e7000@r{, with Hitachi ICE} +@kindex target e7000@r{, with Renesas ICE} You can use the E7000 in-circuit emulator to develop code for either the -Hitachi SH or the H8/300H. Use one of these forms of the @samp{target +Renesas SH or the H8/300H. Use one of these forms of the @samp{target e7000} command to connect @value{GDBN} to your E7000: @table @code @@ -11428,8 +12197,8 @@ If your E7000 is installed as a host on a TCP/IP network, you can just specify its hostname; @value{GDBN} uses @code{telnet} to connect. @end table -@node Hitachi Special -@subsubsection Special @value{GDBN} commands for Hitachi micros +@node Renesas Special +@subsubsection Special @value{GDBN} commands for Renesas micros Some @value{GDBN} commands are available only for the H8/300: @@ -11461,136 +12230,18 @@ memory}. The accepted values for @var{mod} are @code{small}, @end table -@node i960 -@subsection Intel i960 - -@table @code - -@kindex target mon960 -@item target mon960 @var{dev} -MON960 monitor for Intel i960. - -@kindex target nindy -@item target nindy @var{devicename} -An Intel 960 board controlled by a Nindy Monitor. @var{devicename} is -the name of the serial device to use for the connection, e.g. -@file{/dev/ttya}. - -@end table - -@cindex Nindy -@cindex i960 -@dfn{Nindy} is a ROM Monitor program for Intel 960 target systems. When -@value{GDBN} is configured to control a remote Intel 960 using Nindy, you can -tell @value{GDBN} how to connect to the 960 in several ways: - -@itemize @bullet -@item -Through command line options specifying serial port, version of the -Nindy protocol, and communications speed; - -@item -By responding to a prompt on startup; - -@item -By using the @code{target} command at any point during your @value{GDBN} -session. @xref{Target Commands, ,Commands for managing targets}. - -@end itemize - -@cindex download to Nindy-960 -With the Nindy interface to an Intel 960 board, @code{load} -downloads @var{filename} to the 960 as well as adding its symbols in -@value{GDBN}. - -@menu -* Nindy Startup:: Startup with Nindy -* Nindy Options:: Options for Nindy -* Nindy Reset:: Nindy reset command -@end menu - -@node Nindy Startup -@subsubsection Startup with Nindy - -If you simply start @code{@value{GDBP}} without using any command-line -options, you are prompted for what serial port to use, @emph{before} you -reach the ordinary @value{GDBN} prompt: - -@example -Attach /dev/ttyNN -- specify NN, or "quit" to quit: -@end example - -@noindent -Respond to the prompt with whatever suffix (after @samp{/dev/tty}) -identifies the serial port you want to use. You can, if you choose, -simply start up with no Nindy connection by responding to the prompt -with an empty line. If you do this and later wish to attach to Nindy, -use @code{target} (@pxref{Target Commands, ,Commands for managing targets}). - -@node Nindy Options -@subsubsection Options for Nindy - -These are the startup options for beginning your @value{GDBN} session with a -Nindy-960 board attached: - -@table @code -@item -r @var{port} -Specify the serial port name of a serial interface to be used to connect -to the target system. This option is only available when @value{GDBN} is -configured for the Intel 960 target architecture. You may specify -@var{port} as any of: a full pathname (e.g. @samp{-r /dev/ttya}), a -device name in @file{/dev} (e.g. @samp{-r ttya}), or simply the unique -suffix for a specific @code{tty} (e.g. @samp{-r a}). - -@item -O -(An uppercase letter ``O'', not a zero.) Specify that @value{GDBN} should use -the ``old'' Nindy monitor protocol to connect to the target system. -This option is only available when @value{GDBN} is configured for the Intel 960 -target architecture. - -@quotation -@emph{Warning:} if you specify @samp{-O}, but are actually trying to -connect to a target system that expects the newer protocol, the connection -fails, appearing to be a speed mismatch. @value{GDBN} repeatedly -attempts to reconnect at several different line speeds. You can abort -this process with an interrupt. -@end quotation - -@item -brk -Specify that @value{GDBN} should first send a @code{BREAK} signal to the target -system, in an attempt to reset it, before connecting to a Nindy target. - -@quotation -@emph{Warning:} Many target systems do not have the hardware that this -requires; it only works with a few boards. -@end quotation -@end table - -The standard @samp{-b} option controls the line speed used on the serial -port. - -@c @group -@node Nindy Reset -@subsubsection Nindy reset command - -@table @code -@item reset -@kindex reset -For a Nindy target, this command sends a ``break'' to the remote target -system; this is only useful if the target has been equipped with a -circuit to perform a hard reset (or some other interesting action) when -a break is detected. -@end table -@c @end group - @node M32R/D -@subsection Mitsubishi M32R/D +@subsection Renesas M32R/D @table @code @kindex target m32r @item target m32r @var{dev} -Mitsubishi M32R/D ROM monitor. +Renesas M32R/D ROM monitor. + +@kindex target m32rsdi +@item target m32rsdi @var{dev} +Renesas M32R SDI server, connected via parallel port to the board. @end table @@ -11624,19 +12275,6 @@ ROM 68K monitor, running on an M68K IDP board. @end table -If @value{GDBN} is configured with @code{m68*-ericsson-*}, it will -instead have only a single special target command: - -@table @code - -@kindex target es1800 -@item target es1800 @var{dev} -ES-1800 emulator for M68K. - -@end table - -[context?] - @table @code @kindex target rombug @@ -11645,17 +12283,6 @@ ROMBUG ROM monitor for OS/9000. @end table -@node M88K -@subsection M88K - -@table @code - -@kindex target bug -@item target bug @var{dev} -BUG monitor, running on a MVME187 (m88k) board. - -@end table - @node MIPS Embedded @subsection MIPS Embedded @@ -11681,13 +12308,13 @@ For example, this sequence connects to the target board through a serial port, and loads and runs a program called @var{prog} through the debugger: -@example +@smallexample host$ @value{GDBP} @var{prog} @value{GDBN} is free software and @dots{} (@value{GDBP}) target mips /dev/ttyb (@value{GDBP}) load @var{prog} (@value{GDBP}) run -@end example +@end smallexample @item target mips @var{hostname}:@var{portnumber} On some @value{GDBN} host configurations, you can specify a TCP @@ -11800,6 +12427,130 @@ forever because it has no way of knowing how long the program is going to run before stopping. @end table +@node OpenRISC 1000 +@subsection OpenRISC 1000 +@cindex OpenRISC 1000 + +@cindex or1k boards +See OR1k Architecture document (@uref{www.opencores.org}) for more information +about platform and commands. + +@table @code + +@kindex target jtag +@item target jtag jtag://@var{host}:@var{port} + +Connects to remote JTAG server. +JTAG remote server can be either an or1ksim or JTAG server, +connected via parallel port to the board. + +Example: @code{target jtag jtag://localhost:9999} + +@kindex or1ksim +@item or1ksim @var{command} +If connected to @code{or1ksim} OpenRISC 1000 Architectural +Simulator, proprietary commands can be executed. + +@kindex info or1k spr +@item info or1k spr +Displays spr groups. + +@item info or1k spr @var{group} +@itemx info or1k spr @var{groupno} +Displays register names in selected group. + +@item info or1k spr @var{group} @var{register} +@itemx info or1k spr @var{register} +@itemx info or1k spr @var{groupno} @var{registerno} +@itemx info or1k spr @var{registerno} +Shows information about specified spr register. + +@kindex spr +@item spr @var{group} @var{register} @var{value} +@itemx spr @var{register @var{value}} +@itemx spr @var{groupno} @var{registerno @var{value}} +@itemx spr @var{registerno @var{value}} +Writes @var{value} to specified spr register. +@end table + +Some implementations of OpenRISC 1000 Architecture also have hardware trace. +It is very similar to @value{GDBN} trace, except it does not interfere with normal +program execution and is thus much faster. Hardware breakpoints/watchpoint +triggers can be set using: +@table @code +@item $LEA/$LDATA +Load effective address/data +@item $SEA/$SDATA +Store effective address/data +@item $AEA/$ADATA +Access effective address ($SEA or $LEA) or data ($SDATA/$LDATA) +@item $FETCH +Fetch data +@end table + +When triggered, it can capture low level data, like: @code{PC}, @code{LSEA}, +@code{LDATA}, @code{SDATA}, @code{READSPR}, @code{WRITESPR}, @code{INSTR}. + +@code{htrace} commands: +@cindex OpenRISC 1000 htrace +@table @code +@kindex hwatch +@item hwatch @var{conditional} +Set hardware watchpoint on combination of Load/Store Effecive Address(es) +or Data. For example: + +@code{hwatch ($LEA == my_var) && ($LDATA < 50) || ($SEA == my_var) && ($SDATA >= 50)} + +@code{hwatch ($LEA == my_var) && ($LDATA < 50) || ($SEA == my_var) && ($SDATA >= 50)} + +@kindex htrace info +@item htrace info +Display information about current HW trace configuration. + +@kindex htrace trigger +@item htrace trigger @var{conditional} +Set starting criteria for HW trace. + +@kindex htrace qualifier +@item htrace qualifier @var{conditional} +Set acquisition qualifier for HW trace. + +@kindex htrace stop +@item htrace stop @var{conditional} +Set HW trace stopping criteria. + +@kindex htrace record +@item htrace record [@var{data}]* +Selects the data to be recorded, when qualifier is met and HW trace was +triggered. + +@kindex htrace enable +@item htrace enable +@kindex htrace disable +@itemx htrace disable +Enables/disables the HW trace. + +@kindex htrace rewind +@item htrace rewind [@var{filename}] +Clears currently recorded trace data. + +If filename is specified, new trace file is made and any newly collected data +will be written there. + +@kindex htrace print +@item htrace print [@var{start} [@var{len}]] +Prints trace buffer, using current record configuration. + +@kindex htrace mode continuous +@item htrace mode continuous +Set continuous trace mode. + +@kindex htrace mode suspend +@item htrace mode suspend +Set suspend trace mode. + +@end table + @node PowerPC @subsection PowerPC @@ -11837,25 +12588,25 @@ W89K monitor, running on a Winbond HPPA board. @end table @node SH -@subsection Hitachi SH +@subsection Renesas SH @table @code -@kindex target hms@r{, with Hitachi SH} +@kindex target hms@r{, with Renesas SH} @item target hms @var{dev} -A Hitachi SH board attached via serial line to your host. Use special +A Renesas SH board attached via serial line to your host. Use special commands @code{device} and @code{speed} to control the serial line and the communications speed used. -@kindex target e7000@r{, with Hitachi SH} +@kindex target e7000@r{, with Renesas SH} @item target e7000 @var{dev} -E7000 emulator for Hitachi SH. +E7000 emulator for Renesas SH. @kindex target sh3@r{, with SH} @kindex target sh3e@r{, with SH} @item target sh3 @var{dev} @item target sh3e @var{dev} -Hitachi SH-3 and SH-3E target systems. +Renesas SH-3 and SH-3E target systems. @end table @@ -11884,15 +12635,15 @@ information and @samp{-Ttext} to relocate the program to where you wish to load it on the target. You may also want to add the options @samp{-n} or @samp{-N} in order to reduce the size of the sections. Example: -@example +@smallexample sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N -@end example +@end smallexample You can use @code{objdump} to verify that the addresses are what you intended: -@example +@smallexample sparclet-aout-objdump --headers --syms prog -@end example +@end smallexample @cindex running, on Sparclet Once you have set @@ -11902,9 +12653,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}} @value{GDBN} comes up showing the prompt: -@example +@smallexample (gdbslet) -@end example +@end smallexample @menu * Sparclet File:: Setting the file to debug @@ -11918,9 +12669,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}} The @value{GDBN} command @code{file} lets you choose with program to debug. -@example +@smallexample (gdbslet) file prog -@end example +@end smallexample @need 1000 @value{GDBN} then attempts to read the symbol table of @file{prog}. @@ -11935,9 +12686,9 @@ path (@pxref{Environment, ,Your program's environment}). If it fails to find a file, it displays a message such as: -@example +@smallexample prog: No such file or directory. -@end example +@end smallexample When this happens, add the appropriate directories to the search paths with the @value{GDBN} commands @code{path} and @code{dir}, and execute the @@ -11949,18 +12700,18 @@ the @value{GDBN} commands @code{path} and @code{dir}, and execute the The @value{GDBN} command @code{target} lets you connect to a Sparclet target. To connect to a target on serial port ``@code{ttya}'', type: -@example +@smallexample (gdbslet) target sparclet /dev/ttya Remote target sparclet connected to /dev/ttya main () at ../prog.c:3 -@end example +@end smallexample @need 750 @value{GDBN} displays messages like these: -@example +@smallexample Connected to ttya. -@end example +@end smallexample @node Sparclet Download @subsubsection Sparclet download @@ -11979,10 +12730,10 @@ For instance, if the program @file{prog} was linked to text address 0x1201000, with data at 0x12010160 and bss at 0x12010170, in @value{GDBN}, type: -@example +@smallexample (gdbslet) load prog 0x12010000 Loading section .text, size 0xdb0 vma 0x12010000 -@end example +@end smallexample If the code is loaded at a different address then what the program was linked to, you may need to use the @code{section} and @code{add-symbol-file} commands @@ -11996,7 +12747,7 @@ You can now begin debugging the task using @value{GDBN}'s execution control commands, @code{b}, @code{step}, @code{run}, etc. See the @value{GDBN} manual for the list of commands. -@example +@smallexample (gdbslet) b main Breakpoint 1 at 0x12010000: file prog.c, line 3. (gdbslet) run @@ -12006,7 +12757,7 @@ Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3 (gdbslet) step 4 char *execarg = "hello!"; (gdbslet) -@end example +@end smallexample @node Sparclite @subsection Fujitsu Sparclite @@ -12031,9 +12782,9 @@ STDBUG protocol. To connect your ST2000 to the host system, see the manufacturer's manual. Once the ST2000 is physically attached, you can run: -@example +@smallexample target st2000 @var{dev} @var{speed} -@end example +@end smallexample @noindent to establish it as your debugging environment. @var{dev} is normally @@ -12214,6 +12965,7 @@ described here. * History:: Command history * Screen Size:: Screen size * Numbers:: Numbers +* ABI:: Configuring the current ABI * Messages/Warnings:: Optional warnings and messages * Debugging Output:: Optional messages about internal happenings @end menu @@ -12460,6 +13212,89 @@ Display the current default base for numeric input. Display the current default base for numeric display. @end table +@node ABI +@section Configuring the current ABI + +@value{GDBN} can determine the @dfn{ABI} (Application Binary Interface) of your +application automatically. However, sometimes you need to override its +conclusions. Use these commands to manage @value{GDBN}'s view of the +current ABI. + +@cindex OS ABI +@kindex set osabi +@kindex show osabi + +One @value{GDBN} configuration can debug binaries for multiple operating +system targets, either via remote debugging or native emulation. +@value{GDBN} will autodetect the @dfn{OS ABI} (Operating System ABI) in use, +but you can override its conclusion using the @code{set osabi} command. +One example where this is useful is in debugging of binaries which use +an alternate C library (e.g.@: @sc{uClibc} for @sc{gnu}/Linux) which does +not have the same identifying marks that the standard C library for your +platform provides. + +@table @code +@item show osabi +Show the OS ABI currently in use. + +@item set osabi +With no argument, show the list of registered available OS ABI's. + +@item set osabi @var{abi} +Set the current OS ABI to @var{abi}. +@end table + +@cindex float promotion +@kindex set coerce-float-to-double + +Generally, the way that an argument of type @code{float} is passed to a +function depends on whether the function is prototyped. For a prototyped +(i.e.@: ANSI/ISO style) function, @code{float} arguments are passed unchanged, +according to the architecture's convention for @code{float}. For unprototyped +(i.e.@: K&R style) functions, @code{float} arguments are first promoted to type +@code{double} and then passed. + +Unfortunately, some forms of debug information do not reliably indicate whether +a function is prototyped. If @value{GDBN} calls a function that is not marked +as prototyped, it consults @kbd{set coerce-float-to-double}. + +@table @code +@item set coerce-float-to-double +@itemx set coerce-float-to-double on +Arguments of type @code{float} will be promoted to @code{double} when passed +to an unprototyped function. This is the default setting. + +@item set coerce-float-to-double off +Arguments of type @code{float} will be passed directly to unprototyped +functions. +@end table + +@kindex set cp-abi +@kindex show cp-abi +@value{GDBN} needs to know the ABI used for your program's C@t{++} +objects. The correct C@t{++} ABI depends on which C@t{++} compiler was +used to build your application. @value{GDBN} only fully supports +programs with a single C@t{++} ABI; if your program contains code using +multiple C@t{++} ABI's or if @value{GDBN} can not identify your +program's ABI correctly, you can tell @value{GDBN} which ABI to use. +Currently supported ABI's include ``gnu-v2'', for @code{g++} versions +before 3.0, ``gnu-v3'', for @code{g++} versions 3.0 and later, and +``hpaCC'' for the HP ANSI C@t{++} compiler. Other C@t{++} compilers may +use the ``gnu-v2'' or ``gnu-v3'' ABI's as well. The default setting is +``auto''. + +@table @code +@item show cp-abi +Show the C@t{++} ABI currently in use. + +@item set cp-abi +With no argument, show the list of supported C@t{++} ABI's. + +@item set cp-abi @var{abi} +@itemx set cp-abi auto +Set the current C@t{++} ABI to @var{abi}, or return to automatic detection. +@end table + @node Messages/Warnings @section Optional warnings and messages @@ -12509,11 +13344,11 @@ By default, @value{GDBN} is cautious, and asks what sometimes seems to be a lot of stupid questions to confirm certain commands. For example, if you try to run a program which is already running: -@example +@smallexample (@value{GDBP}) run The program being debugged has been started already. Start it from the beginning? (y or n) -@end example +@end smallexample If you are willing to unflinchingly face the consequences of your own commands, you can disable this ``feature'': @@ -12561,6 +13396,14 @@ default is off. @item show debug expression Displays the current state of displaying @value{GDBN} expression debugging info. +@kindex set debug frame +@item set debug frame +Turns on or off display of @value{GDBN} frame debugging info. The +default is off. +@kindex show debug frame +@item show debug frame +Displays the current state of displaying @value{GDBN} frame debugging +info. @kindex set debug overload @item set debug overload Turns on or off display of @value{GDBN} C@t{++} overload debugging @@ -12704,6 +13547,14 @@ Display the @value{GDBN} commands used to define @var{commandname} (but not its documentation). If no @var{commandname} is given, display the definitions for all user-defined commands. +@kindex show max-user-call-depth +@kindex set max-user-call-depth +@item show max-user-call-depth +@itemx set max-user-call-depth +The value of @code{max-user-call-depth} controls how many recursion +levels are allowed in user-defined commands before GDB suspects an +infinite recursion and aborts the command. + @end table When user-defined commands are executed, the @@ -12753,7 +13604,7 @@ For example, to ignore @code{SIGALRM} signals while single-stepping, but treat them normally during normal execution, you could define: -@example +@smallexample define hook-stop handle SIGALRM nopass end @@ -12765,13 +13616,13 @@ end define hook-continue handle SIGLARM pass end -@end example +@end smallexample As a further example, to hook at the begining and end of the @code{echo} -command, and to add extra text to the beginning and end of the message, +command, and to add extra text to the beginning and end of the message, you could define: -@example +@smallexample define hook-echo echo <<<--- end @@ -12784,7 +13635,7 @@ end <<<---Hello World--->>> (@value{GDBP}) -@end example +@end smallexample You can define a hook for any single-word command in @value{GDBN}, but not for command aliases; you should define a hook for the basic command @@ -12868,8 +13719,8 @@ Execute the command file @var{filename}. @end table The lines in a command file are executed sequentially. They are not -printed as they are executed. An error in any command terminates execution -of the command file. +printed as they are executed. An error in any command terminates +execution of the command file and control is returned to the console. Commands that would ask for confirmation if used interactively proceed without asking when used in a command file. Many @value{GDBN} commands that @@ -12882,9 +13733,9 @@ standard error. Errors in a command file supplied on standard input do not terminate execution of the command file --- execution continues with the next command. -@example +@smallexample gdb < cmds > log 2>&1 -@end example +@end smallexample (The syntax above will vary depending on the shell used.) This example will execute commands from the file @file{cmds}. All output and errors @@ -12917,19 +13768,19 @@ To print @samp{@w{ }and foo =@w{ }}, use the command A backslash at the end of @var{text} can be used, as in C, to continue the command onto subsequent lines. For example, -@example +@smallexample echo This is some text\n\ which is continued\n\ onto several lines.\n -@end example +@end smallexample produces the same output as -@example +@smallexample echo This is some text\n echo which is continued\n echo onto several lines.\n -@end example +@end smallexample @kindex output @item output @var{expression} @@ -12955,9 +13806,9 @@ subroutine @c Either this is a bug, or the manual should document what formats are @c supported. -@example +@smallexample printf (@var{string}, @var{expressions}@dots{}); -@end example +@end smallexample For example, you can print two values in hex like this: @@ -12970,23 +13821,90 @@ string are the simple ones that consist of backslash followed by a letter. @end table +@node Interpreters +@chapter Command Interpreters +@cindex command interpreters + +@value{GDBN} supports multiple command interpreters, and some command +infrastructure to allow users or user interface writers to switch +between interpreters or run commands in other interpreters. + +@value{GDBN} currently supports two command interpreters, the console +interpreter (sometimes called the command-line interpreter or @sc{cli}) +and the machine interface interpreter (or @sc{gdb/mi}). This manual +describes both of these interfaces in great detail. + +By default, @value{GDBN} will start with the console interpreter. +However, the user may choose to start @value{GDBN} with another +interpreter by specifying the @option{-i} or @option{--interpreter} +startup options. Defined interpreters include: + +@table @code +@item console +@cindex console interpreter +The traditional console or command-line interpreter. This is the most often +used interpreter with @value{GDBN}. With no interpreter specified at runtime, +@value{GDBN} will use this interpreter. + +@item mi +@cindex mi interpreter +The newest @sc{gdb/mi} interface (currently @code{mi2}). Used primarily +by programs wishing to use @value{GDBN} as a backend for a debugger GUI +or an IDE. For more information, see @ref{GDB/MI, ,The @sc{gdb/mi} +Interface}. + +@item mi2 +@cindex mi2 interpreter +The current @sc{gdb/mi} interface. + +@item mi1 +@cindex mi1 interpreter +The @sc{gdb/mi} interface included in @value{GDBN} 5.1, 5.2, and 5.3. + +@end table + +@cindex invoke another interpreter +The interpreter being used by @value{GDBN} may not be dynamically +switched at runtime. Although possible, this could lead to a very +precarious situation. Consider an IDE using @sc{gdb/mi}. If a user +enters the command "interpreter-set console" in a console view, +@value{GDBN} would switch to using the console interpreter, rendering +the IDE inoperable! + +@kindex interpreter-exec +Although you may only choose a single interpreter at startup, you may execute +commands in any interpreter from the current interpreter using the appropriate +command. If you are running the console interpreter, simply use the +@code{interpreter-exec} command: + +@smallexample +interpreter-exec mi "-data-list-register-names" +@end smallexample + +@sc{gdb/mi} has a similar command, although it is only available in versions of +@value{GDBN} which support @sc{gdb/mi} version 2 (or greater). + @node TUI @chapter @value{GDBN} Text User Interface @cindex TUI +@cindex Text User Interface @menu * TUI Overview:: TUI overview * TUI Keys:: TUI key bindings +* TUI Single Key Mode:: TUI single key mode * TUI Commands:: TUI specific commands * TUI Configuration:: TUI configuration variables @end menu -The @value{GDBN} Text User Interface, TUI in short, -is a terminal interface which uses the @code{curses} library -to show the source file, the assembly output, the program registers -and @value{GDBN} commands in separate text windows. -The TUI is available only when @value{GDBN} is configured -with the @code{--enable-tui} configure option (@pxref{Configure Options}). +The @value{GDBN} Text User Interface, TUI in short, is a terminal +interface which uses the @code{curses} library to show the source +file, the assembly output, the program registers and @value{GDBN} +commands in separate text windows. + +The TUI is enabled by invoking @value{GDBN} using either +@pindex gdbtui +@samp{gdbtui} or @samp{gdb -tui}. @node TUI Overview @section TUI overview @@ -13017,8 +13935,6 @@ window is always visible. @item source The source window shows the source file of the program. The current line as well as active breakpoints are displayed in this window. -The current program position is shown with the @samp{>} marker and -active breakpoints are shown with @samp{*} markers. @item assembly The assembly window shows the disassembly output of the program. @@ -13026,7 +13942,38 @@ The assembly window shows the disassembly output of the program. @item register This window shows the processor registers. It detects when a register is changed and when this is the case, registers that have -changed are highlighted. +changed are highlighted. + +@end table + +The source and assembly windows show the current program position +by highlighting the current line and marking them with the @samp{>} marker. +Breakpoints are also indicated with two markers. A first one +indicates the breakpoint type: + +@table @code +@item B +Breakpoint which was hit at least once. + +@item b +Breakpoint which was never hit. + +@item H +Hardware breakpoint which was hit at least once. + +@item h +Hardware breakpoint which was never hit. + +@end table + +The second marker indicates whether the breakpoint is enabled or not: + +@table @code +@item + +Breakpoint is enabled. + +@item - +Breakpoint is disabled. @end table @@ -13055,6 +14002,35 @@ assembly and registers @end itemize +On top of the command window a status line gives various information +concerning the current process begin debugged. The status line is +updated when the information it shows changes. The following fields +are displayed: + +@table @emph +@item target +Indicates the current gdb target +(@pxref{Targets, ,Specifying a Debugging Target}). + +@item process +Gives information about the current process or thread number. +When no process is being debugged, this field is set to @code{No process}. + +@item function +Gives the current function name for the selected frame. +The name is demangled if demangling is turned on (@pxref{Print Settings}). +When there is no symbol corresponding to the current program counter +the string @code{??} is displayed. + +@item line +Indicates the current line number for the selected frame. +When the current line number is not known the string @code{??} is displayed. + +@item pc +Indicates the current program counter address. + +@end table + @node TUI Keys @section TUI Key Bindings @cindex TUI key bindings @@ -13062,7 +14038,9 @@ assembly and registers The TUI installs several key bindings in the readline keymaps (@pxref{Command Line Editing}). They allow to leave or enter in the TUI mode or they operate -directly on the TUI layout and windows. The following key bindings +directly on the TUI layout and windows. The TUI also provides +a @emph{SingleKey} keymap which binds several keys directly to +@value{GDBN} commands. The following key bindings are installed for both TUI mode and the @value{GDBN} standard mode. @table @kbd @@ -13095,6 +14073,19 @@ previous layout and the new one. Think of it as the Emacs @kbd{C-x 2} binding. +@kindex C-x o +@item C-x o +Change the active window. The TUI associates several key bindings +(like scrolling and arrow keys) to the active window. This command +gives the focus to the next TUI window. + +Think of it as the Emacs @kbd{C-x o} binding. + +@kindex C-x s +@item C-x s +Use the TUI @emph{SingleKey} keymap that binds single key to gdb commands +(@pxref{TUI Single Key Mode}). + @end table The following key bindings are handled only by the TUI mode: @@ -13131,9 +14122,69 @@ Refresh the screen. @end table In the TUI mode, the arrow keys are used by the active window -for scrolling. This means they are not available for readline. It is -necessary to use other readline key bindings such as @key{C-p}, @key{C-n}, -@key{C-b} and @key{C-f}. +for scrolling. This means they are available for readline when the +active window is the command window. When the command window +does not have the focus, it is necessary to use other readline +key bindings such as @key{C-p}, @key{C-n}, @key{C-b} and @key{C-f}. + +@node TUI Single Key Mode +@section TUI Single Key Mode +@cindex TUI single key mode + +The TUI provides a @emph{SingleKey} mode in which it installs a particular +key binding in the readline keymaps to connect single keys to +some gdb commands. + +@table @kbd +@kindex c @r{(SingleKey TUI key)} +@item c +continue + +@kindex d @r{(SingleKey TUI key)} +@item d +down + +@kindex f @r{(SingleKey TUI key)} +@item f +finish + +@kindex n @r{(SingleKey TUI key)} +@item n +next + +@kindex q @r{(SingleKey TUI key)} +@item q +exit the @emph{SingleKey} mode. + +@kindex r @r{(SingleKey TUI key)} +@item r +run + +@kindex s @r{(SingleKey TUI key)} +@item s +step + +@kindex u @r{(SingleKey TUI key)} +@item u +up + +@kindex v @r{(SingleKey TUI key)} +@item v +info locals + +@kindex w @r{(SingleKey TUI key)} +@item w +where + +@end table + +Other keys temporarily switch to the @value{GDBN} command prompt. +The key that was pressed is inserted in the editing buffer so that +it is possible to type most @value{GDBN} commands without interaction +with the TUI @emph{SingleKey} mode. Once the command is entered the TUI +@emph{SingleKey} mode is restored. The only way to permanently leave +this mode is by hitting @key{q} or @samp{@key{C-x} @key{s}}. + @node TUI Commands @section TUI specific commands @@ -13146,6 +14197,10 @@ is in the standard mode, using these commands will automatically switch in the TUI mode. @table @code +@item info win +@kindex info win +List and give the size of all displayed windows. + @item layout next @kindex layout next Display the next layout. @@ -13180,6 +14235,22 @@ can be affected to another window. @kindex refresh Refresh the screen. This is similar to using @key{C-L} key. +@item tui reg float +@kindex tui reg +Show the floating point registers in the register window. + +@item tui reg general +Show the general registers in the register window. + +@item tui reg next +Show the next register group. The list of register groups as well as +their order is target specific. The predefined register groups are the +following: @code{general}, @code{float}, @code{system}, @code{vector}, +@code{all}, @code{save}, @code{restore}. + +@item tui reg system +Show the system registers in the register window. + @item update @kindex update Update the source window and the current execution point. @@ -13303,36 +14374,26 @@ and the source. Explicit @value{GDBN} @code{list} or search commands still produce output as usual, but you probably have no reason to use them from Emacs. -@quotation -@emph{Warning:} If the directory where your program resides is not your -current directory, it can be easy to confuse Emacs about the location of -the source files, in which case the auxiliary display buffer does not -appear to show your source. @value{GDBN} can find programs by searching your -environment's @code{PATH} variable, so the @value{GDBN} input and output -session proceeds normally; but Emacs does not get enough information -back from @value{GDBN} to locate the source files in this situation. To -avoid this problem, either start @value{GDBN} mode from the directory where -your program resides, or specify an absolute file name when prompted for the -@kbd{M-x gdb} argument. +If you specify an absolute file name when prompted for the @kbd{M-x +gdb} argument, then Emacs sets your current working directory to where +your program resides. If you only specify the file name, then Emacs +sets your current working directory to to the directory associated +with the previous buffer. In this case, @value{GDBN} may find your +program by searching your environment's @code{PATH} variable, but on +some operating systems it might not find the source. So, although the +@value{GDBN} input and output session proceeds normally, the auxiliary +buffer does not display the current source and line of execution. -A similar confusion can result if you use the @value{GDBN} @code{file} command to -switch to debugging a program in some other location, from an existing -@value{GDBN} buffer in Emacs. -@end quotation +The initial working directory of @value{GDBN} is printed on the top +line of the @value{GDBN} I/O buffer and this serves as a default for +the commands that specify files for @value{GDBN} to operate +on. @xref{Files, ,Commands to specify files}. -By default, @kbd{M-x gdb} calls the program called @file{gdb}. If -you need to call @value{GDBN} by a different name (for example, if you keep -several configurations around, with different names) you can set the -Emacs variable @code{gdb-command-name}; for example, - -@example -(setq gdb-command-name "mygdb") -@end example - -@noindent -(preceded by @kbd{M-:} or @kbd{ESC :}, or typed in the @code{*scratch*} buffer, or -in your @file{.emacs} file) makes Emacs call the program named -``@code{mygdb}'' instead. +By default, @kbd{M-x gdb} calls the program called @file{gdb}. If you +need to call @value{GDBN} by a different name (for example, if you +keep several configurations around, with different names) you can +customize the Emacs variable @code{gud-gdb-command-name} to run the +one you want. In the @value{GDBN} I/O buffer, you can use these special Emacs commands in addition to the standard Shell mode commands: @@ -13341,66 +14402,47 @@ addition to the standard Shell mode commands: @item C-h m Describe the features of Emacs' @value{GDBN} Mode. -@item M-s +@item C-c C-s Execute to another source line, like the @value{GDBN} @code{step} command; also update the display window to show the current file and location. -@item M-n +@item C-c C-n Execute to next source line in this function, skipping all function calls, like the @value{GDBN} @code{next} command. Then update the display window to show the current file and location. -@item M-i +@item C-c C-i Execute one instruction, like the @value{GDBN} @code{stepi} command; update display window accordingly. -@item M-x gdb-nexti -Execute to next instruction, using the @value{GDBN} @code{nexti} command; update -display window accordingly. - @item C-c C-f Execute until exit from the selected stack frame, like the @value{GDBN} @code{finish} command. -@item M-c +@item C-c C-r Continue execution of your program, like the @value{GDBN} @code{continue} command. -@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-p}. - -@item M-u +@item C-c < Go up the number of frames indicated by the numeric argument (@pxref{Arguments, , Numeric Arguments, Emacs, The @sc{gnu} Emacs Manual}), like the @value{GDBN} @code{up} command. -@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-u}. - -@item M-d +@item C-c > Go down the number of frames indicated by the numeric argument, like the @value{GDBN} @code{down} command. - -@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-d}. - -@item C-x & -Read the number where the cursor is positioned, and insert it at the end -of the @value{GDBN} I/O buffer. For example, if you wish to disassemble code -around an address that was displayed earlier, type @kbd{disassemble}; -then move the cursor to the address display, and pick up the -argument for @code{disassemble} by typing @kbd{C-x &}. - -You can customize this further by defining elements of the list -@code{gdb-print-command}; once it is defined, you can format or -otherwise process numbers picked up by @kbd{C-x &} before they are -inserted. A numeric argument to @kbd{C-x &} indicates that you -wish special formatting, and also acts as an index to pick an element of the -list. If the list element is a string, the number to be inserted is -formatted using the Emacs function @code{format}; otherwise the number -is passed as an argument to the corresponding list element. @end table -In any source file, the Emacs command @kbd{C-x SPC} (@code{gdb-break}) +In any source file, the Emacs command @kbd{C-x SPC} (@code{gud-break}) tells @value{GDBN} to set a breakpoint on the source line point is on. +If you type @kbd{M-x speedbar}, then Emacs displays a separate frame which +shows a backtrace when the @value{GDBN} I/O buffer is current. Move +point to any frame in the stack and type @key{RET} to make it become the +current frame and display the associated source in the source buffer. +Alternatively, click @kbd{Mouse-2} to make the selected frame become the +current one. + If you accidentally delete the source-display buffer, an easy way to get it back is to type the command @code{f} in the @value{GDBN} buffer, to request a frame display; when you run under Emacs, this recreates @@ -13414,6 +14456,10 @@ communicates with Emacs in terms of line numbers. If you add or delete lines from the text, the line numbers that @value{GDBN} knows cease to correspond properly with the code. +The description given here is for GNU Emacs version 21.3 and a more +detailed description of its interaction with @value{GDBN} is given in +the Emacs manual (@pxref{Debuggers,,, Emacs, The @sc{gnu} Emacs Manual}). + @c The following dropped because Epoch is nonstandard. Reactivate @c if/when v19 does something similar. ---doc@cygnus.com 19dec1990 @ignore @@ -13428,8 +14474,4269 @@ environment. Users of this environment can use a new command, each value is printed in its own window. @end ignore -@include annotate.texi -@include gdbmi.texinfo + +@node GDB/MI +@chapter The @sc{gdb/mi} Interface + +@unnumberedsec Function and Purpose + +@cindex @sc{gdb/mi}, its purpose +@sc{gdb/mi} is a line based machine oriented text interface to @value{GDBN}. It is +specifically intended to support the development of systems which use +the debugger as just one small component of a larger system. + +This chapter is a specification of the @sc{gdb/mi} interface. It is written +in the form of a reference manual. + +Note that @sc{gdb/mi} is still under construction, so some of the +features described below are incomplete and subject to change. + +@unnumberedsec Notation and Terminology + +@cindex notational conventions, for @sc{gdb/mi} +This chapter uses the following notation: + +@itemize @bullet +@item +@code{|} separates two alternatives. + +@item +@code{[ @var{something} ]} indicates that @var{something} is optional: +it may or may not be given. + +@item +@code{( @var{group} )*} means that @var{group} inside the parentheses +may repeat zero or more times. + +@item +@code{( @var{group} )+} means that @var{group} inside the parentheses +may repeat one or more times. + +@item +@code{"@var{string}"} means a literal @var{string}. +@end itemize + +@ignore +@heading Dependencies +@end ignore + +@heading Acknowledgments + +In alphabetic order: Andrew Cagney, Fernando Nasser, Stan Shebs and +Elena Zannoni. + +@menu +* GDB/MI Command Syntax:: +* GDB/MI Compatibility with CLI:: +* GDB/MI Output Records:: +* GDB/MI Command Description Format:: +* GDB/MI Breakpoint Table Commands:: +* GDB/MI Data Manipulation:: +* GDB/MI Program Control:: +* GDB/MI Miscellaneous Commands:: +@ignore +* GDB/MI Kod Commands:: +* GDB/MI Memory Overlay Commands:: +* GDB/MI Signal Handling Commands:: +@end ignore +* GDB/MI Stack Manipulation:: +* GDB/MI Symbol Query:: +* GDB/MI Target Manipulation:: +* GDB/MI Thread Commands:: +* GDB/MI Tracepoint Commands:: +* GDB/MI Variable Objects:: +@end menu + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Command Syntax +@section @sc{gdb/mi} Command Syntax + +@menu +* GDB/MI Input Syntax:: +* GDB/MI Output Syntax:: +* GDB/MI Simple Examples:: +@end menu + +@node GDB/MI Input Syntax +@subsection @sc{gdb/mi} Input Syntax + +@cindex input syntax for @sc{gdb/mi} +@cindex @sc{gdb/mi}, input syntax +@table @code +@item @var{command} @expansion{} +@code{@var{cli-command} | @var{mi-command}} + +@item @var{cli-command} @expansion{} +@code{[ @var{token} ] @var{cli-command} @var{nl}}, where +@var{cli-command} is any existing @value{GDBN} CLI command. + +@item @var{mi-command} @expansion{} +@code{[ @var{token} ] "-" @var{operation} ( " " @var{option} )* +@code{[} " --" @code{]} ( " " @var{parameter} )* @var{nl}} + +@item @var{token} @expansion{} +"any sequence of digits" + +@item @var{option} @expansion{} +@code{"-" @var{parameter} [ " " @var{parameter} ]} + +@item @var{parameter} @expansion{} +@code{@var{non-blank-sequence} | @var{c-string}} + +@item @var{operation} @expansion{} +@emph{any of the operations described in this chapter} + +@item @var{non-blank-sequence} @expansion{} +@emph{anything, provided it doesn't contain special characters such as +"-", @var{nl}, """ and of course " "} + +@item @var{c-string} @expansion{} +@code{""" @var{seven-bit-iso-c-string-content} """} + +@item @var{nl} @expansion{} +@code{CR | CR-LF} +@end table + +@noindent +Notes: + +@itemize @bullet +@item +The CLI commands are still handled by the @sc{mi} interpreter; their +output is described below. + +@item +The @code{@var{token}}, when present, is passed back when the command +finishes. + +@item +Some @sc{mi} commands accept optional arguments as part of the parameter +list. Each option is identified by a leading @samp{-} (dash) and may be +followed by an optional argument parameter. Options occur first in the +parameter list and can be delimited from normal parameters using +@samp{--} (this is useful when some parameters begin with a dash). +@end itemize + +Pragmatics: + +@itemize @bullet +@item +We want easy access to the existing CLI syntax (for debugging). + +@item +We want it to be easy to spot a @sc{mi} operation. +@end itemize + +@node GDB/MI Output Syntax +@subsection @sc{gdb/mi} Output Syntax + +@cindex output syntax of @sc{gdb/mi} +@cindex @sc{gdb/mi}, output syntax +The output from @sc{gdb/mi} consists of zero or more out-of-band records +followed, optionally, by a single result record. This result record +is for the most recent command. The sequence of output records is +terminated by @samp{(@value{GDBP})}. + +If an input command was prefixed with a @code{@var{token}} then the +corresponding output for that command will also be prefixed by that same +@var{token}. + +@table @code +@item @var{output} @expansion{} +@code{( @var{out-of-band-record} )* [ @var{result-record} ] "(gdb)" @var{nl}} + +@item @var{result-record} @expansion{} +@code{ [ @var{token} ] "^" @var{result-class} ( "," @var{result} )* @var{nl}} + +@item @var{out-of-band-record} @expansion{} +@code{@var{async-record} | @var{stream-record}} + +@item @var{async-record} @expansion{} +@code{@var{exec-async-output} | @var{status-async-output} | @var{notify-async-output}} + +@item @var{exec-async-output} @expansion{} +@code{[ @var{token} ] "*" @var{async-output}} + +@item @var{status-async-output} @expansion{} +@code{[ @var{token} ] "+" @var{async-output}} + +@item @var{notify-async-output} @expansion{} +@code{[ @var{token} ] "=" @var{async-output}} + +@item @var{async-output} @expansion{} +@code{@var{async-class} ( "," @var{result} )* @var{nl}} + +@item @var{result-class} @expansion{} +@code{"done" | "running" | "connected" | "error" | "exit"} + +@item @var{async-class} @expansion{} +@code{"stopped" | @var{others}} (where @var{others} will be added +depending on the needs---this is still in development). + +@item @var{result} @expansion{} +@code{ @var{variable} "=" @var{value}} + +@item @var{variable} @expansion{} +@code{ @var{string} } + +@item @var{value} @expansion{} +@code{ @var{const} | @var{tuple} | @var{list} } + +@item @var{const} @expansion{} +@code{@var{c-string}} + +@item @var{tuple} @expansion{} +@code{ "@{@}" | "@{" @var{result} ( "," @var{result} )* "@}" } + +@item @var{list} @expansion{} +@code{ "[]" | "[" @var{value} ( "," @var{value} )* "]" | "[" +@var{result} ( "," @var{result} )* "]" } + +@item @var{stream-record} @expansion{} +@code{@var{console-stream-output} | @var{target-stream-output} | @var{log-stream-output}} + +@item @var{console-stream-output} @expansion{} +@code{"~" @var{c-string}} + +@item @var{target-stream-output} @expansion{} +@code{"@@" @var{c-string}} + +@item @var{log-stream-output} @expansion{} +@code{"&" @var{c-string}} + +@item @var{nl} @expansion{} +@code{CR | CR-LF} + +@item @var{token} @expansion{} +@emph{any sequence of digits}. +@end table + +@noindent +Notes: + +@itemize @bullet +@item +All output sequences end in a single line containing a period. + +@item +The @code{@var{token}} is from the corresponding request. If an execution +command is interrupted by the @samp{-exec-interrupt} command, the +@var{token} associated with the @samp{*stopped} message is the one of the +original execution command, not the one of the interrupt command. + +@item +@cindex status output in @sc{gdb/mi} +@var{status-async-output} contains on-going status information about the +progress of a slow operation. It can be discarded. All status output is +prefixed by @samp{+}. + +@item +@cindex async output in @sc{gdb/mi} +@var{exec-async-output} contains asynchronous state change on the target +(stopped, started, disappeared). All async output is prefixed by +@samp{*}. + +@item +@cindex notify output in @sc{gdb/mi} +@var{notify-async-output} contains supplementary information that the +client should handle (e.g., a new breakpoint information). All notify +output is prefixed by @samp{=}. + +@item +@cindex console output in @sc{gdb/mi} +@var{console-stream-output} is output that should be displayed as is in the +console. It is the textual response to a CLI command. All the console +output is prefixed by @samp{~}. + +@item +@cindex target output in @sc{gdb/mi} +@var{target-stream-output} is the output produced by the target program. +All the target output is prefixed by @samp{@@}. + +@item +@cindex log output in @sc{gdb/mi} +@var{log-stream-output} is output text coming from @value{GDBN}'s internals, for +instance messages that should be displayed as part of an error log. All +the log output is prefixed by @samp{&}. + +@item +@cindex list output in @sc{gdb/mi} +New @sc{gdb/mi} commands should only output @var{lists} containing +@var{values}. + + +@end itemize + +@xref{GDB/MI Stream Records, , @sc{gdb/mi} Stream Records}, for more +details about the various output records. + +@node GDB/MI Simple Examples +@subsection Simple Examples of @sc{gdb/mi} Interaction +@cindex @sc{gdb/mi}, simple examples + +This subsection presents several simple examples of interaction using +the @sc{gdb/mi} interface. In these examples, @samp{->} means that the +following line is passed to @sc{gdb/mi} as input, while @samp{<-} means +the output received from @sc{gdb/mi}. + +@subsubheading Target Stop +@c Ummm... There is no "-stop" command. This assumes async, no? +Here's an example of stopping the inferior process: + +@smallexample +-> -stop +<- (@value{GDBP}) +@end smallexample + +@noindent +and later: + +@smallexample +<- *stop,reason="stop",address="0x123",source="a.c:123" +<- (@value{GDBP}) +@end smallexample + +@subsubheading Simple CLI Command + +Here's an example of a simple CLI command being passed through +@sc{gdb/mi} and on to the CLI. + +@smallexample +-> print 1+2 +<- &"print 1+2\n" +<- ~"$1 = 3\n" +<- ^done +<- (@value{GDBP}) +@end smallexample + +@subsubheading Command With Side Effects + +@smallexample +-> -symbol-file xyz.exe +<- *breakpoint,nr="3",address="0x123",source="a.c:123" +<- (@value{GDBP}) +@end smallexample + +@subsubheading A Bad Command + +Here's what happens if you pass a non-existent command: + +@smallexample +-> -rubbish +<- ^error,msg="Undefined MI command: rubbish" +<- (@value{GDBP}) +@end smallexample + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Compatibility with CLI +@section @sc{gdb/mi} Compatibility with CLI + +@cindex compatibility, @sc{gdb/mi} and CLI +@cindex @sc{gdb/mi}, compatibility with CLI +To help users familiar with @value{GDBN}'s existing CLI interface, @sc{gdb/mi} +accepts existing CLI commands. As specified by the syntax, such +commands can be directly entered into the @sc{gdb/mi} interface and @value{GDBN} will +respond. + +This mechanism is provided as an aid to developers of @sc{gdb/mi} +clients and not as a reliable interface into the CLI. Since the command +is being interpreteted in an environment that assumes @sc{gdb/mi} +behaviour, the exact output of such commands is likely to end up being +an un-supported hybrid of @sc{gdb/mi} and CLI output. + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Output Records +@section @sc{gdb/mi} Output Records + +@menu +* GDB/MI Result Records:: +* GDB/MI Stream Records:: +* GDB/MI Out-of-band Records:: +@end menu + +@node GDB/MI Result Records +@subsection @sc{gdb/mi} Result Records + +@cindex result records in @sc{gdb/mi} +@cindex @sc{gdb/mi}, result records +In addition to a number of out-of-band notifications, the response to a +@sc{gdb/mi} command includes one of the following result indications: + +@table @code +@findex ^done +@item "^done" [ "," @var{results} ] +The synchronous operation was successful, @code{@var{results}} are the return +values. + +@item "^running" +@findex ^running +@c Is this one correct? Should it be an out-of-band notification? +The asynchronous operation was successfully started. The target is +running. + +@item "^error" "," @var{c-string} +@findex ^error +The operation failed. The @code{@var{c-string}} contains the corresponding +error message. +@end table + +@node GDB/MI Stream Records +@subsection @sc{gdb/mi} Stream Records + +@cindex @sc{gdb/mi}, stream records +@cindex stream records in @sc{gdb/mi} +@value{GDBN} internally maintains a number of output streams: the console, the +target, and the log. The output intended for each of these streams is +funneled through the @sc{gdb/mi} interface using @dfn{stream records}. + +Each stream record begins with a unique @dfn{prefix character} which +identifies its stream (@pxref{GDB/MI Output Syntax, , @sc{gdb/mi} Output +Syntax}). In addition to the prefix, each stream record contains a +@code{@var{string-output}}. This is either raw text (with an implicit new +line) or a quoted C string (which does not contain an implicit newline). + +@table @code +@item "~" @var{string-output} +The console output stream contains text that should be displayed in the +CLI console window. It contains the textual responses to CLI commands. + +@item "@@" @var{string-output} +The target output stream contains any textual output from the running +target. + +@item "&" @var{string-output} +The log stream contains debugging messages being produced by @value{GDBN}'s +internals. +@end table + +@node GDB/MI Out-of-band Records +@subsection @sc{gdb/mi} Out-of-band Records + +@cindex out-of-band records in @sc{gdb/mi} +@cindex @sc{gdb/mi}, out-of-band records +@dfn{Out-of-band} records are used to notify the @sc{gdb/mi} client of +additional changes that have occurred. Those changes can either be a +consequence of @sc{gdb/mi} (e.g., a breakpoint modified) or a result of +target activity (e.g., target stopped). + +The following is a preliminary list of possible out-of-band records. + +@table @code +@item "*" "stop" +@end table + + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Command Description Format +@section @sc{gdb/mi} Command Description Format + +The remaining sections describe blocks of commands. Each block of +commands is laid out in a fashion similar to this section. + +Note the the line breaks shown in the examples are here only for +readability. They don't appear in the real output. +Also note that the commands with a non-available example (N.A.@:) are +not yet implemented. + +@subheading Motivation + +The motivation for this collection of commands. + +@subheading Introduction + +A brief introduction to this collection of commands as a whole. + +@subheading Commands + +For each command in the block, the following is described: + +@subsubheading Synopsis + +@smallexample + -command @var{args}@dots{} +@end smallexample + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} CLI command. + +@subsubheading Result + +@subsubheading Out-of-band + +@subsubheading Notes + +@subsubheading Example + + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Breakpoint Table Commands +@section @sc{gdb/mi} Breakpoint table commands + +@cindex breakpoint commands for @sc{gdb/mi} +@cindex @sc{gdb/mi}, breakpoint commands +This section documents @sc{gdb/mi} commands for manipulating +breakpoints. + +@subheading The @code{-break-after} Command +@findex -break-after + +@subsubheading Synopsis + +@smallexample + -break-after @var{number} @var{count} +@end smallexample + +The breakpoint number @var{number} is not in effect until it has been +hit @var{count} times. To see how this is reflected in the output of +the @samp{-break-list} command, see the description of the +@samp{-break-list} command below. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{ignore}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-insert main +^done,bkpt=@{number="1",addr="0x000100d0",file="hello.c",line="5"@} +(@value{GDBP}) +-break-after 1 3 +~ +^done +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="1",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", +addr="0x000100d0",func="main",file="hello.c",line="5",times="0", +ignore="3"@}]@} +(@value{GDBP}) +@end smallexample + +@ignore +@subheading The @code{-break-catch} Command +@findex -break-catch + +@subheading The @code{-break-commands} Command +@findex -break-commands +@end ignore + + +@subheading The @code{-break-condition} Command +@findex -break-condition + +@subsubheading Synopsis + +@smallexample + -break-condition @var{number} @var{expr} +@end smallexample + +Breakpoint @var{number} will stop the program only if the condition in +@var{expr} is true. The condition becomes part of the +@samp{-break-list} output (see the description of the @samp{-break-list} +command below). + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{condition}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-condition 1 1 +^done +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="1",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", +addr="0x000100d0",func="main",file="hello.c",line="5",cond="1", +times="0",ignore="3"@}]@} +(@value{GDBP}) +@end smallexample + +@subheading The @code{-break-delete} Command +@findex -break-delete + +@subsubheading Synopsis + +@smallexample + -break-delete ( @var{breakpoint} )+ +@end smallexample + +Delete the breakpoint(s) whose number(s) are specified in the argument +list. This is obviously reflected in the breakpoint list. + +@subsubheading @value{GDBN} command + +The corresponding @value{GDBN} command is @samp{delete}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-delete 1 +^done +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="0",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[]@} +(@value{GDBP}) +@end smallexample + +@subheading The @code{-break-disable} Command +@findex -break-disable + +@subsubheading Synopsis + +@smallexample + -break-disable ( @var{breakpoint} )+ +@end smallexample + +Disable the named @var{breakpoint}(s). The field @samp{enabled} in the +break list is now set to @samp{n} for the named @var{breakpoint}(s). + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{disable}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-disable 2 +^done +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="1",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="n", +addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}]@} +(@value{GDBP}) +@end smallexample + +@subheading The @code{-break-enable} Command +@findex -break-enable + +@subsubheading Synopsis + +@smallexample + -break-enable ( @var{breakpoint} )+ +@end smallexample + +Enable (previously disabled) @var{breakpoint}(s). + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{enable}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-enable 2 +^done +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="1",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y", +addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}]@} +(@value{GDBP}) +@end smallexample + +@subheading The @code{-break-info} Command +@findex -break-info + +@subsubheading Synopsis + +@smallexample + -break-info @var{breakpoint} +@end smallexample + +@c REDUNDANT??? +Get information about a single breakpoint. + +@subsubheading @value{GDBN} command + +The corresponding @value{GDBN} command is @samp{info break @var{breakpoint}}. + +@subsubheading Example +N.A. + +@subheading The @code{-break-insert} Command +@findex -break-insert + +@subsubheading Synopsis + +@smallexample + -break-insert [ -t ] [ -h ] [ -r ] + [ -c @var{condition} ] [ -i @var{ignore-count} ] + [ -p @var{thread} ] [ @var{line} | @var{addr} ] +@end smallexample + +@noindent +If specified, @var{line}, can be one of: + +@itemize @bullet +@item function +@c @item +offset +@c @item -offset +@c @item linenum +@item filename:linenum +@item filename:function +@item *address +@end itemize + +The possible optional parameters of this command are: + +@table @samp +@item -t +Insert a tempoary breakpoint. +@item -h +Insert a hardware breakpoint. +@item -c @var{condition} +Make the breakpoint conditional on @var{condition}. +@item -i @var{ignore-count} +Initialize the @var{ignore-count}. +@item -r +Insert a regular breakpoint in all the functions whose names match the +given regular expression. Other flags are not applicable to regular +expresson. +@end table + +@subsubheading Result + +The result is in the form: + +@smallexample + ^done,bkptno="@var{number}",func="@var{funcname}", + file="@var{filename}",line="@var{lineno}" +@end smallexample + +@noindent +where @var{number} is the @value{GDBN} number for this breakpoint, @var{funcname} +is the name of the function where the breakpoint was inserted, +@var{filename} is the name of the source file which contains this +function, and @var{lineno} is the source line number within that file. + +Note: this format is open to change. +@c An out-of-band breakpoint instead of part of the result? + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} commands are @samp{break}, @samp{tbreak}, +@samp{hbreak}, @samp{thbreak}, and @samp{rbreak}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-insert main +^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@} +(@value{GDBP}) +-break-insert -t foo +^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c",line="11"@} +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="2",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", +addr="0x0001072c", func="main",file="recursive2.c",line="4",times="0"@}, +bkpt=@{number="2",type="breakpoint",disp="del",enabled="y", +addr="0x00010774",func="foo",file="recursive2.c",line="11",times="0"@}]@} +(@value{GDBP}) +-break-insert -r foo.* +~int foo(int, int); +^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c",line="11"@} +(@value{GDBP}) +@end smallexample + +@subheading The @code{-break-list} Command +@findex -break-list + +@subsubheading Synopsis + +@smallexample + -break-list +@end smallexample + +Displays the list of inserted breakpoints, showing the following fields: + +@table @samp +@item Number +number of the breakpoint +@item Type +type of the breakpoint: @samp{breakpoint} or @samp{watchpoint} +@item Disposition +should the breakpoint be deleted or disabled when it is hit: @samp{keep} +or @samp{nokeep} +@item Enabled +is the breakpoint enabled or no: @samp{y} or @samp{n} +@item Address +memory location at which the breakpoint is set +@item What +logical location of the breakpoint, expressed by function name, file +name, line number +@item Times +number of times the breakpoint has been hit +@end table + +If there are no breakpoints or watchpoints, the @code{BreakpointTable} +@code{body} field is an empty list. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info break}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="2",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", +addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}, +bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y", +addr="0x00010114",func="foo",file="hello.c",line="13",times="0"@}]@} +(@value{GDBP}) +@end smallexample + +Here's an example of the result when there are no breakpoints: + +@smallexample +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="0",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[]@} +(@value{GDBP}) +@end smallexample + +@subheading The @code{-break-watch} Command +@findex -break-watch + +@subsubheading Synopsis + +@smallexample + -break-watch [ -a | -r ] +@end smallexample + +Create a watchpoint. With the @samp{-a} option it will create an +@dfn{access} watchpoint, i.e. a watchpoint that triggers either on a +read from or on a write to the memory location. With the @samp{-r} +option, the watchpoint created is a @dfn{read} watchpoint, i.e. it will +trigger only when the memory location is accessed for reading. Without +either of the options, the watchpoint created is a regular watchpoint, +i.e. it will trigger when the memory location is accessed for writing. +@xref{Set Watchpoints, , Setting watchpoints}. + +Note that @samp{-break-list} will report a single list of watchpoints and +breakpoints inserted. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} commands are @samp{watch}, @samp{awatch}, and +@samp{rwatch}. + +@subsubheading Example + +Setting a watchpoint on a variable in the @code{main} function: + +@smallexample +(@value{GDBP}) +-break-watch x +^done,wpt=@{number="2",exp="x"@} +(@value{GDBP}) +-exec-continue +^running +^done,reason="watchpoint-trigger",wpt=@{number="2",exp="x"@}, +value=@{old="-268439212",new="55"@}, +frame=@{func="main",args=[],file="recursive2.c",line="5"@} +(@value{GDBP}) +@end smallexample + +Setting a watchpoint on a variable local to a function. @value{GDBN} will stop +the program execution twice: first for the variable changing value, then +for the watchpoint going out of scope. + +@smallexample +(@value{GDBP}) +-break-watch C +^done,wpt=@{number="5",exp="C"@} +(@value{GDBP}) +-exec-continue +^running +^done,reason="watchpoint-trigger", +wpt=@{number="5",exp="C"@},value=@{old="-276895068",new="3"@}, +frame=@{func="callee4",args=[], +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@} +(@value{GDBP}) +-exec-continue +^running +^done,reason="watchpoint-scope",wpnum="5", +frame=@{func="callee3",args=[@{name="strarg", +value="0x11940 \"A string argument.\""@}], +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@} +(@value{GDBP}) +@end smallexample + +Listing breakpoints and watchpoints, at different points in the program +execution. Note that once the watchpoint goes out of scope, it is +deleted. + +@smallexample +(@value{GDBP}) +-break-watch C +^done,wpt=@{number="2",exp="C"@} +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="2",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", +addr="0x00010734",func="callee4", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}, +bkpt=@{number="2",type="watchpoint",disp="keep", +enabled="y",addr="",what="C",times="0"@}]@} +(@value{GDBP}) +-exec-continue +^running +^done,reason="watchpoint-trigger",wpt=@{number="2",exp="C"@}, +value=@{old="-276895068",new="3"@}, +frame=@{func="callee4",args=[], +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@} +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="2",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", +addr="0x00010734",func="callee4", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}, +bkpt=@{number="2",type="watchpoint",disp="keep", +enabled="y",addr="",what="C",times="-5"@}]@} +(@value{GDBP}) +-exec-continue +^running +^done,reason="watchpoint-scope",wpnum="2", +frame=@{func="callee3",args=[@{name="strarg", +value="0x11940 \"A string argument.\""@}], +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@} +(@value{GDBP}) +-break-list +^done,BreakpointTable=@{nr_rows="1",nr_cols="6", +hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@}, +@{width="14",alignment="-1",col_name="type",colhdr="Type"@}, +@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@}, +@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@}, +@{width="10",alignment="-1",col_name="addr",colhdr="Address"@}, +@{width="40",alignment="2",col_name="what",colhdr="What"@}], +body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", +addr="0x00010734",func="callee4", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}]@} +(@value{GDBP}) +@end smallexample + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Data Manipulation +@section @sc{gdb/mi} Data Manipulation + +@cindex data manipulation, in @sc{gdb/mi} +@cindex @sc{gdb/mi}, data manipulation +This section describes the @sc{gdb/mi} commands that manipulate data: +examine memory and registers, evaluate expressions, etc. + +@c REMOVED FROM THE INTERFACE. +@c @subheading -data-assign +@c Change the value of a program variable. Plenty of side effects. +@c @subsubheading GDB command +@c set variable +@c @subsubheading Example +@c N.A. + +@subheading The @code{-data-disassemble} Command +@findex -data-disassemble + +@subsubheading Synopsis + +@smallexample + -data-disassemble + [ -s @var{start-addr} -e @var{end-addr} ] + | [ -f @var{filename} -l @var{linenum} [ -n @var{lines} ] ] + -- @var{mode} +@end smallexample + +@noindent +Where: + +@table @samp +@item @var{start-addr} +is the beginning address (or @code{$pc}) +@item @var{end-addr} +is the end address +@item @var{filename} +is the name of the file to disassemble +@item @var{linenum} +is the line number to disassemble around +@item @var{lines} +is the the number of disassembly lines to be produced. If it is -1, +the whole function will be disassembled, in case no @var{end-addr} is +specified. If @var{end-addr} is specified as a non-zero value, and +@var{lines} is lower than the number of disassembly lines between +@var{start-addr} and @var{end-addr}, only @var{lines} lines are +displayed; if @var{lines} is higher than the number of lines between +@var{start-addr} and @var{end-addr}, only the lines up to @var{end-addr} +are displayed. +@item @var{mode} +is either 0 (meaning only disassembly) or 1 (meaning mixed source and +disassembly). +@end table + +@subsubheading Result + +The output for each instruction is composed of four fields: + +@itemize @bullet +@item Address +@item Func-name +@item Offset +@item Instruction +@end itemize + +Note that whatever included in the instruction field, is not manipulated +directely by @sc{gdb/mi}, i.e. it is not possible to adjust its format. + +@subsubheading @value{GDBN} Command + +There's no direct mapping from this command to the CLI. + +@subsubheading Example + +Disassemble from the current value of @code{$pc} to @code{$pc + 20}: + +@smallexample +(@value{GDBP}) +-data-disassemble -s $pc -e "$pc + 20" -- 0 +^done, +asm_insns=[ +@{address="0x000107c0",func-name="main",offset="4", +inst="mov 2, %o0"@}, +@{address="0x000107c4",func-name="main",offset="8", +inst="sethi %hi(0x11800), %o2"@}, +@{address="0x000107c8",func-name="main",offset="12", +inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"@}, +@{address="0x000107cc",func-name="main",offset="16", +inst="sethi %hi(0x11800), %o2"@}, +@{address="0x000107d0",func-name="main",offset="20", +inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"@}] +(@value{GDBP}) +@end smallexample + +Disassemble the whole @code{main} function. Line 32 is part of +@code{main}. + +@smallexample +-data-disassemble -f basics.c -l 32 -- 0 +^done,asm_insns=[ +@{address="0x000107bc",func-name="main",offset="0", +inst="save %sp, -112, %sp"@}, +@{address="0x000107c0",func-name="main",offset="4", +inst="mov 2, %o0"@}, +@{address="0x000107c4",func-name="main",offset="8", +inst="sethi %hi(0x11800), %o2"@}, +[@dots{}] +@{address="0x0001081c",func-name="main",offset="96",inst="ret "@}, +@{address="0x00010820",func-name="main",offset="100",inst="restore "@}] +(@value{GDBP}) +@end smallexample + +Disassemble 3 instructions from the start of @code{main}: + +@smallexample +(@value{GDBP}) +-data-disassemble -f basics.c -l 32 -n 3 -- 0 +^done,asm_insns=[ +@{address="0x000107bc",func-name="main",offset="0", +inst="save %sp, -112, %sp"@}, +@{address="0x000107c0",func-name="main",offset="4", +inst="mov 2, %o0"@}, +@{address="0x000107c4",func-name="main",offset="8", +inst="sethi %hi(0x11800), %o2"@}] +(@value{GDBP}) +@end smallexample + +Disassemble 3 instructions from the start of @code{main} in mixed mode: + +@smallexample +(@value{GDBP}) +-data-disassemble -f basics.c -l 32 -n 3 -- 1 +^done,asm_insns=[ +src_and_asm_line=@{line="31", +file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ + testsuite/gdb.mi/basics.c",line_asm_insn=[ +@{address="0x000107bc",func-name="main",offset="0", +inst="save %sp, -112, %sp"@}]@}, +src_and_asm_line=@{line="32", +file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ + testsuite/gdb.mi/basics.c",line_asm_insn=[ +@{address="0x000107c0",func-name="main",offset="4", +inst="mov 2, %o0"@}, +@{address="0x000107c4",func-name="main",offset="8", +inst="sethi %hi(0x11800), %o2"@}]@}] +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-data-evaluate-expression} Command +@findex -data-evaluate-expression + +@subsubheading Synopsis + +@smallexample + -data-evaluate-expression @var{expr} +@end smallexample + +Evaluate @var{expr} as an expression. The expression could contain an +inferior function call. The function call will execute synchronously. +If the expression contains spaces, it must be enclosed in double quotes. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} commands are @samp{print}, @samp{output}, and +@samp{call}. In @code{gdbtk} only, there's a corresponding +@samp{gdb_eval} command. + +@subsubheading Example + +In the following example, the numbers that precede the commands are the +@dfn{tokens} described in @ref{GDB/MI Command Syntax, ,@sc{gdb/mi} +Command Syntax}. Notice how @sc{gdb/mi} returns the same tokens in its +output. + +@smallexample +211-data-evaluate-expression A +211^done,value="1" +(@value{GDBP}) +311-data-evaluate-expression &A +311^done,value="0xefffeb7c" +(@value{GDBP}) +411-data-evaluate-expression A+3 +411^done,value="4" +(@value{GDBP}) +511-data-evaluate-expression "A + 3" +511^done,value="4" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-data-list-changed-registers} Command +@findex -data-list-changed-registers + +@subsubheading Synopsis + +@smallexample + -data-list-changed-registers +@end smallexample + +Display a list of the registers that have changed. + +@subsubheading @value{GDBN} Command + +@value{GDBN} doesn't have a direct analog for this command; @code{gdbtk} +has the corresponding command @samp{gdb_changed_register_list}. + +@subsubheading Example + +On a PPC MBX board: + +@smallexample +(@value{GDBP}) +-exec-continue +^running + +(@value{GDBP}) +*stopped,reason="breakpoint-hit",bkptno="1",frame=@{func="main", +args=[],file="try.c",line="5"@} +(@value{GDBP}) +-data-list-changed-registers +^done,changed-registers=["0","1","2","4","5","6","7","8","9", +"10","11","13","14","15","16","17","18","19","20","21","22","23", +"24","25","26","27","28","30","31","64","65","66","67","69"] +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-data-list-register-names} Command +@findex -data-list-register-names + +@subsubheading Synopsis + +@smallexample + -data-list-register-names [ ( @var{regno} )+ ] +@end smallexample + +Show a list of register names for the current target. If no arguments +are given, it shows a list of the names of all the registers. If +integer numbers are given as arguments, it will print a list of the +names of the registers corresponding to the arguments. To ensure +consistency between a register name and its number, the output list may +include empty register names. + +@subsubheading @value{GDBN} Command + +@value{GDBN} does not have a command which corresponds to +@samp{-data-list-register-names}. In @code{gdbtk} there is a +corresponding command @samp{gdb_regnames}. + +@subsubheading Example + +For the PPC MBX board: +@smallexample +(@value{GDBP}) +-data-list-register-names +^done,register-names=["r0","r1","r2","r3","r4","r5","r6","r7", +"r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18", +"r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", +"r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", +"f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20", +"f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31", +"", "pc","ps","cr","lr","ctr","xer"] +(@value{GDBP}) +-data-list-register-names 1 2 3 +^done,register-names=["r1","r2","r3"] +(@value{GDBP}) +@end smallexample + +@subheading The @code{-data-list-register-values} Command +@findex -data-list-register-values + +@subsubheading Synopsis + +@smallexample + -data-list-register-values @var{fmt} [ ( @var{regno} )*] +@end smallexample + +Display the registers' contents. @var{fmt} is the format according to +which the registers' contents are to be returned, followed by an optional +list of numbers specifying the registers to display. A missing list of +numbers indicates that the contents of all the registers must be returned. + +Allowed formats for @var{fmt} are: + +@table @code +@item x +Hexadecimal +@item o +Octal +@item t +Binary +@item d +Decimal +@item r +Raw +@item N +Natural +@end table + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} commands are @samp{info reg}, @samp{info +all-reg}, and (in @code{gdbtk}) @samp{gdb_fetch_registers}. + +@subsubheading Example + +For a PPC MBX board (note: line breaks are for readability only, they +don't appear in the actual output): + +@smallexample +(@value{GDBP}) +-data-list-register-values r 64 65 +^done,register-values=[@{number="64",value="0xfe00a300"@}, +@{number="65",value="0x00029002"@}] +(@value{GDBP}) +-data-list-register-values x +^done,register-values=[@{number="0",value="0xfe0043c8"@}, +@{number="1",value="0x3fff88"@},@{number="2",value="0xfffffffe"@}, +@{number="3",value="0x0"@},@{number="4",value="0xa"@}, +@{number="5",value="0x3fff68"@},@{number="6",value="0x3fff58"@}, +@{number="7",value="0xfe011e98"@},@{number="8",value="0x2"@}, +@{number="9",value="0xfa202820"@},@{number="10",value="0xfa202808"@}, +@{number="11",value="0x1"@},@{number="12",value="0x0"@}, +@{number="13",value="0x4544"@},@{number="14",value="0xffdfffff"@}, +@{number="15",value="0xffffffff"@},@{number="16",value="0xfffffeff"@}, +@{number="17",value="0xefffffed"@},@{number="18",value="0xfffffffe"@}, +@{number="19",value="0xffffffff"@},@{number="20",value="0xffffffff"@}, +@{number="21",value="0xffffffff"@},@{number="22",value="0xfffffff7"@}, +@{number="23",value="0xffffffff"@},@{number="24",value="0xffffffff"@}, +@{number="25",value="0xffffffff"@},@{number="26",value="0xfffffffb"@}, +@{number="27",value="0xffffffff"@},@{number="28",value="0xf7bfffff"@}, +@{number="29",value="0x0"@},@{number="30",value="0xfe010000"@}, +@{number="31",value="0x0"@},@{number="32",value="0x0"@}, +@{number="33",value="0x0"@},@{number="34",value="0x0"@}, +@{number="35",value="0x0"@},@{number="36",value="0x0"@}, +@{number="37",value="0x0"@},@{number="38",value="0x0"@}, +@{number="39",value="0x0"@},@{number="40",value="0x0"@}, +@{number="41",value="0x0"@},@{number="42",value="0x0"@}, +@{number="43",value="0x0"@},@{number="44",value="0x0"@}, +@{number="45",value="0x0"@},@{number="46",value="0x0"@}, +@{number="47",value="0x0"@},@{number="48",value="0x0"@}, +@{number="49",value="0x0"@},@{number="50",value="0x0"@}, +@{number="51",value="0x0"@},@{number="52",value="0x0"@}, +@{number="53",value="0x0"@},@{number="54",value="0x0"@}, +@{number="55",value="0x0"@},@{number="56",value="0x0"@}, +@{number="57",value="0x0"@},@{number="58",value="0x0"@}, +@{number="59",value="0x0"@},@{number="60",value="0x0"@}, +@{number="61",value="0x0"@},@{number="62",value="0x0"@}, +@{number="63",value="0x0"@},@{number="64",value="0xfe00a300"@}, +@{number="65",value="0x29002"@},@{number="66",value="0x202f04b5"@}, +@{number="67",value="0xfe0043b0"@},@{number="68",value="0xfe00b3e4"@}, +@{number="69",value="0x20002b03"@}] +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-data-read-memory} Command +@findex -data-read-memory + +@subsubheading Synopsis + +@smallexample + -data-read-memory [ -o @var{byte-offset} ] + @var{address} @var{word-format} @var{word-size} + @var{nr-rows} @var{nr-cols} [ @var{aschar} ] +@end smallexample + +@noindent +where: + +@table @samp +@item @var{address} +An expression specifying the address of the first memory word to be +read. Complex expressions containing embedded white space should be +quoted using the C convention. + +@item @var{word-format} +The format to be used to print the memory words. The notation is the +same as for @value{GDBN}'s @code{print} command (@pxref{Output Formats, +,Output formats}). + +@item @var{word-size} +The size of each memory word in bytes. + +@item @var{nr-rows} +The number of rows in the output table. + +@item @var{nr-cols} +The number of columns in the output table. + +@item @var{aschar} +If present, indicates that each row should include an @sc{ascii} dump. The +value of @var{aschar} is used as a padding character when a byte is not a +member of the printable @sc{ascii} character set (printable @sc{ascii} +characters are those whose code is between 32 and 126, inclusively). + +@item @var{byte-offset} +An offset to add to the @var{address} before fetching memory. +@end table + +This command displays memory contents as a table of @var{nr-rows} by +@var{nr-cols} words, each word being @var{word-size} bytes. In total, +@code{@var{nr-rows} * @var{nr-cols} * @var{word-size}} bytes are read +(returned as @samp{total-bytes}). Should less than the requested number +of bytes be returned by the target, the missing words are identified +using @samp{N/A}. The number of bytes read from the target is returned +in @samp{nr-bytes} and the starting address used to read memory in +@samp{addr}. + +The address of the next/previous row or page is available in +@samp{next-row} and @samp{prev-row}, @samp{next-page} and +@samp{prev-page}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{x}. @code{gdbtk} has +@samp{gdb_get_mem} memory read command. + +@subsubheading Example + +Read six bytes of memory starting at @code{bytes+6} but then offset by +@code{-6} bytes. Format as three rows of two columns. One byte per +word. Display each word in hex. + +@smallexample +(@value{GDBP}) +9-data-read-memory -o -6 -- bytes+6 x 1 3 2 +9^done,addr="0x00001390",nr-bytes="6",total-bytes="6", +next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396", +prev-page="0x0000138a",memory=[ +@{addr="0x00001390",data=["0x00","0x01"]@}, +@{addr="0x00001392",data=["0x02","0x03"]@}, +@{addr="0x00001394",data=["0x04","0x05"]@}] +(@value{GDBP}) +@end smallexample + +Read two bytes of memory starting at address @code{shorts + 64} and +display as a single word formatted in decimal. + +@smallexample +(@value{GDBP}) +5-data-read-memory shorts+64 d 2 1 1 +5^done,addr="0x00001510",nr-bytes="2",total-bytes="2", +next-row="0x00001512",prev-row="0x0000150e", +next-page="0x00001512",prev-page="0x0000150e",memory=[ +@{addr="0x00001510",data=["128"]@}] +(@value{GDBP}) +@end smallexample + +Read thirty two bytes of memory starting at @code{bytes+16} and format +as eight rows of four columns. Include a string encoding with @samp{x} +used as the non-printable character. + +@smallexample +(@value{GDBP}) +4-data-read-memory bytes+16 x 1 8 4 x +4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32", +next-row="0x000013c0",prev-row="0x0000139c", +next-page="0x000013c0",prev-page="0x00001380",memory=[ +@{addr="0x000013a0",data=["0x10","0x11","0x12","0x13"],ascii="xxxx"@}, +@{addr="0x000013a4",data=["0x14","0x15","0x16","0x17"],ascii="xxxx"@}, +@{addr="0x000013a8",data=["0x18","0x19","0x1a","0x1b"],ascii="xxxx"@}, +@{addr="0x000013ac",data=["0x1c","0x1d","0x1e","0x1f"],ascii="xxxx"@}, +@{addr="0x000013b0",data=["0x20","0x21","0x22","0x23"],ascii=" !\"#"@}, +@{addr="0x000013b4",data=["0x24","0x25","0x26","0x27"],ascii="$%&'"@}, +@{addr="0x000013b8",data=["0x28","0x29","0x2a","0x2b"],ascii="()*+"@}, +@{addr="0x000013bc",data=["0x2c","0x2d","0x2e","0x2f"],ascii=",-./"@}] +(@value{GDBP}) +@end smallexample + +@subheading The @code{-display-delete} Command +@findex -display-delete + +@subsubheading Synopsis + +@smallexample + -display-delete @var{number} +@end smallexample + +Delete the display @var{number}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{delete display}. + +@subsubheading Example +N.A. + + +@subheading The @code{-display-disable} Command +@findex -display-disable + +@subsubheading Synopsis + +@smallexample + -display-disable @var{number} +@end smallexample + +Disable display @var{number}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{disable display}. + +@subsubheading Example +N.A. + + +@subheading The @code{-display-enable} Command +@findex -display-enable + +@subsubheading Synopsis + +@smallexample + -display-enable @var{number} +@end smallexample + +Enable display @var{number}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{enable display}. + +@subsubheading Example +N.A. + + +@subheading The @code{-display-insert} Command +@findex -display-insert + +@subsubheading Synopsis + +@smallexample + -display-insert @var{expression} +@end smallexample + +Display @var{expression} every time the program stops. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{display}. + +@subsubheading Example +N.A. + + +@subheading The @code{-display-list} Command +@findex -display-list + +@subsubheading Synopsis + +@smallexample + -display-list +@end smallexample + +List the displays. Do not show the current values. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info display}. + +@subsubheading Example +N.A. + + +@subheading The @code{-environment-cd} Command +@findex -environment-cd + +@subsubheading Synopsis + +@smallexample + -environment-cd @var{pathdir} +@end smallexample + +Set @value{GDBN}'s working directory. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{cd}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb +^done +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-environment-directory} Command +@findex -environment-directory + +@subsubheading Synopsis + +@smallexample + -environment-directory [ -r ] [ @var{pathdir} ]+ +@end smallexample + +Add directories @var{pathdir} to beginning of search path for source files. +If the @samp{-r} option is used, the search path is reset to the default +search path. If directories @var{pathdir} are supplied in addition to the +@samp{-r} option, the search path is first reset and then addition +occurs as normal. +Multiple directories may be specified, separated by blanks. Specifying +multiple directories in a single command +results in the directories added to the beginning of the +search path in the same order they were presented in the command. +If blanks are needed as +part of a directory name, double-quotes should be used around +the name. In the command output, the path will show up separated +by the system directory-separator character. The directory-seperator +character must not be used +in any directory name. +If no directories are specified, the current search path is displayed. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{dir}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb +^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd" +(@value{GDBP}) +-environment-directory "" +^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd" +(@value{GDBP}) +-environment-directory -r /home/jjohnstn/src/gdb /usr/src +^done,source-path="/home/jjohnstn/src/gdb:/usr/src:$cdir:$cwd" +(@value{GDBP}) +-environment-directory -r +^done,source-path="$cdir:$cwd" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-environment-path} Command +@findex -environment-path + +@subsubheading Synopsis + +@smallexample + -environment-path [ -r ] [ @var{pathdir} ]+ +@end smallexample + +Add directories @var{pathdir} to beginning of search path for object files. +If the @samp{-r} option is used, the search path is reset to the original +search path that existed at gdb start-up. If directories @var{pathdir} are +supplied in addition to the +@samp{-r} option, the search path is first reset and then addition +occurs as normal. +Multiple directories may be specified, separated by blanks. Specifying +multiple directories in a single command +results in the directories added to the beginning of the +search path in the same order they were presented in the command. +If blanks are needed as +part of a directory name, double-quotes should be used around +the name. In the command output, the path will show up separated +by the system directory-separator character. The directory-seperator +character must not be used +in any directory name. +If no directories are specified, the current path is displayed. + + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{path}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-environment-path +^done,path="/usr/bin" +(@value{GDBP}) +-environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb /bin +^done,path="/kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb:/bin:/usr/bin" +(@value{GDBP}) +-environment-path -r /usr/local/bin +^done,path="/usr/local/bin:/usr/bin" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-environment-pwd} Command +@findex -environment-pwd + +@subsubheading Synopsis + +@smallexample + -environment-pwd +@end smallexample + +Show the current working directory. + +@subsubheading @value{GDBN} command + +The corresponding @value{GDBN} command is @samp{pwd}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-environment-pwd +^done,cwd="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb" +(@value{GDBP}) +@end smallexample + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Program Control +@section @sc{gdb/mi} Program control + +@subsubheading Program termination + +As a result of execution, the inferior program can run to completion, if +it doesn't encounter any breakpoints. In this case the output will +include an exit code, if the program has exited exceptionally. + +@subsubheading Examples + +@noindent +Program exited normally: + +@smallexample +(@value{GDBP}) +-exec-run +^running +(@value{GDBP}) +x = 55 +*stopped,reason="exited-normally" +(@value{GDBP}) +@end smallexample + +@noindent +Program exited exceptionally: + +@smallexample +(@value{GDBP}) +-exec-run +^running +(@value{GDBP}) +x = 55 +*stopped,reason="exited",exit-code="01" +(@value{GDBP}) +@end smallexample + +Another way the program can terminate is if it receives a signal such as +@code{SIGINT}. In this case, @sc{gdb/mi} displays this: + +@smallexample +(@value{GDBP}) +*stopped,reason="exited-signalled",signal-name="SIGINT", +signal-meaning="Interrupt" +@end smallexample + + +@subheading The @code{-exec-abort} Command +@findex -exec-abort + +@subsubheading Synopsis + +@smallexample + -exec-abort +@end smallexample + +Kill the inferior running program. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{kill}. + +@subsubheading Example +N.A. + + +@subheading The @code{-exec-arguments} Command +@findex -exec-arguments + +@subsubheading Synopsis + +@smallexample + -exec-arguments @var{args} +@end smallexample + +Set the inferior program arguments, to be used in the next +@samp{-exec-run}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{set args}. + +@subsubheading Example + +@c FIXME! +Don't have one around. + + +@subheading The @code{-exec-continue} Command +@findex -exec-continue + +@subsubheading Synopsis + +@smallexample + -exec-continue +@end smallexample + +Asynchronous command. Resumes the execution of the inferior program +until a breakpoint is encountered, or until the inferior exits. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} corresponding is @samp{continue}. + +@subsubheading Example + +@smallexample +-exec-continue +^running +(@value{GDBP}) +@@Hello world +*stopped,reason="breakpoint-hit",bkptno="2",frame=@{func="foo",args=[], +file="hello.c",line="13"@} +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-finish} Command +@findex -exec-finish + +@subsubheading Synopsis + +@smallexample + -exec-finish +@end smallexample + +Asynchronous command. Resumes the execution of the inferior program +until the current function is exited. Displays the results returned by +the function. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{finish}. + +@subsubheading Example + +Function returning @code{void}. + +@smallexample +-exec-finish +^running +(@value{GDBP}) +@@hello from foo +*stopped,reason="function-finished",frame=@{func="main",args=[], +file="hello.c",line="7"@} +(@value{GDBP}) +@end smallexample + +Function returning other than @code{void}. The name of the internal +@value{GDBN} variable storing the result is printed, together with the +value itself. + +@smallexample +-exec-finish +^running +(@value{GDBP}) +*stopped,reason="function-finished",frame=@{addr="0x000107b0",func="foo", +args=[@{name="a",value="1"],@{name="b",value="9"@}@}, +file="recursive2.c",line="14"@}, +gdb-result-var="$1",return-value="0" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-interrupt} Command +@findex -exec-interrupt + +@subsubheading Synopsis + +@smallexample + -exec-interrupt +@end smallexample + +Asynchronous command. Interrupts the background execution of the target. +Note how the token associated with the stop message is the one for the +execution command that has been interrupted. The token for the interrupt +itself only appears in the @samp{^done} output. If the user is trying to +interrupt a non-running program, an error message will be printed. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{interrupt}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +111-exec-continue +111^running + +(@value{GDBP}) +222-exec-interrupt +222^done +(@value{GDBP}) +111*stopped,signal-name="SIGINT",signal-meaning="Interrupt", +frame=@{addr="0x00010140",func="foo",args=[],file="try.c",line="13"@} +(@value{GDBP}) + +(@value{GDBP}) +-exec-interrupt +^error,msg="mi_cmd_exec_interrupt: Inferior not executing." +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-next} Command +@findex -exec-next + +@subsubheading Synopsis + +@smallexample + -exec-next +@end smallexample + +Asynchronous command. Resumes execution of the inferior program, stopping +when the beginning of the next source line is reached. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{next}. + +@subsubheading Example + +@smallexample +-exec-next +^running +(@value{GDBP}) +*stopped,reason="end-stepping-range",line="8",file="hello.c" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-next-instruction} Command +@findex -exec-next-instruction + +@subsubheading Synopsis + +@smallexample + -exec-next-instruction +@end smallexample + +Asynchronous command. Executes one machine instruction. If the +instruction is a function call continues until the function returns. If +the program stops at an instruction in the middle of a source line, the +address will be printed as well. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{nexti}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-exec-next-instruction +^running + +(@value{GDBP}) +*stopped,reason="end-stepping-range", +addr="0x000100d4",line="5",file="hello.c" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-return} Command +@findex -exec-return + +@subsubheading Synopsis + +@smallexample + -exec-return +@end smallexample + +Makes current function return immediately. Doesn't execute the inferior. +Displays the new current frame. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{return}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +200-break-insert callee4 +200^done,bkpt=@{number="1",addr="0x00010734", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@} +(@value{GDBP}) +000-exec-run +000^running +(@value{GDBP}) +000*stopped,reason="breakpoint-hit",bkptno="1", +frame=@{func="callee4",args=[], +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@} +(@value{GDBP}) +205-break-delete +205^done +(@value{GDBP}) +111-exec-return +111^done,frame=@{level="0",func="callee3", +args=[@{name="strarg", +value="0x11940 \"A string argument.\""@}], +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@} +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-run} Command +@findex -exec-run + +@subsubheading Synopsis + +@smallexample + -exec-run +@end smallexample + +Asynchronous command. Starts execution of the inferior from the +beginning. The inferior executes until either a breakpoint is +encountered or the program exits. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{run}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-break-insert main +^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@} +(@value{GDBP}) +-exec-run +^running +(@value{GDBP}) +*stopped,reason="breakpoint-hit",bkptno="1", +frame=@{func="main",args=[],file="recursive2.c",line="4"@} +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-show-arguments} Command +@findex -exec-show-arguments + +@subsubheading Synopsis + +@smallexample + -exec-show-arguments +@end smallexample + +Print the arguments of the program. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{show args}. + +@subsubheading Example +N.A. + +@c @subheading -exec-signal + +@subheading The @code{-exec-step} Command +@findex -exec-step + +@subsubheading Synopsis + +@smallexample + -exec-step +@end smallexample + +Asynchronous command. Resumes execution of the inferior program, stopping +when the beginning of the next source line is reached, if the next +source line is not a function call. If it is, stop at the first +instruction of the called function. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{step}. + +@subsubheading Example + +Stepping into a function: + +@smallexample +-exec-step +^running +(@value{GDBP}) +*stopped,reason="end-stepping-range", +frame=@{func="foo",args=[@{name="a",value="10"@}, +@{name="b",value="0"@}],file="recursive2.c",line="11"@} +(@value{GDBP}) +@end smallexample + +Regular stepping: + +@smallexample +-exec-step +^running +(@value{GDBP}) +*stopped,reason="end-stepping-range",line="14",file="recursive2.c" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-step-instruction} Command +@findex -exec-step-instruction + +@subsubheading Synopsis + +@smallexample + -exec-step-instruction +@end smallexample + +Asynchronous command. Resumes the inferior which executes one machine +instruction. The output, once @value{GDBN} has stopped, will vary depending on +whether we have stopped in the middle of a source line or not. In the +former case, the address at which the program stopped will be printed as +well. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{stepi}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-exec-step-instruction +^running + +(@value{GDBP}) +*stopped,reason="end-stepping-range", +frame=@{func="foo",args=[],file="try.c",line="10"@} +(@value{GDBP}) +-exec-step-instruction +^running + +(@value{GDBP}) +*stopped,reason="end-stepping-range", +frame=@{addr="0x000100f4",func="foo",args=[],file="try.c",line="10"@} +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-exec-until} Command +@findex -exec-until + +@subsubheading Synopsis + +@smallexample + -exec-until [ @var{location} ] +@end smallexample + +Asynchronous command. Executes the inferior until the @var{location} +specified in the argument is reached. If there is no argument, the inferior +executes until a source line greater than the current one is reached. +The reason for stopping in this case will be @samp{location-reached}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{until}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-exec-until recursive2.c:6 +^running +(@value{GDBP}) +x = 55 +*stopped,reason="location-reached",frame=@{func="main",args=[], +file="recursive2.c",line="6"@} +(@value{GDBP}) +@end smallexample + +@ignore +@subheading -file-clear +Is this going away???? +@end ignore + + +@subheading The @code{-file-exec-and-symbols} Command +@findex -file-exec-and-symbols + +@subsubheading Synopsis + +@smallexample + -file-exec-and-symbols @var{file} +@end smallexample + +Specify the executable file to be debugged. This file is the one from +which the symbol table is also read. If no file is specified, the +command clears the executable and symbol information. If breakpoints +are set when using this command with no arguments, @value{GDBN} will produce +error messages. Otherwise, no output is produced, except a completion +notification. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{file}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx +^done +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-file-exec-file} Command +@findex -file-exec-file + +@subsubheading Synopsis + +@smallexample + -file-exec-file @var{file} +@end smallexample + +Specify the executable file to be debugged. Unlike +@samp{-file-exec-and-symbols}, the symbol table is @emph{not} read +from this file. If used without argument, @value{GDBN} clears the information +about the executable file. No output is produced, except a completion +notification. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{exec-file}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx +^done +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-file-list-exec-sections} Command +@findex -file-list-exec-sections + +@subsubheading Synopsis + +@smallexample + -file-list-exec-sections +@end smallexample + +List the sections of the current executable file. + +@subsubheading @value{GDBN} Command + +The @value{GDBN} command @samp{info file} shows, among the rest, the same +information as this command. @code{gdbtk} has a corresponding command +@samp{gdb_load_info}. + +@subsubheading Example +N.A. + + +@subheading The @code{-file-list-exec-source-file} Command +@findex -file-list-exec-source-file + +@subsubheading Synopsis + +@smallexample + -file-list-exec-source-file +@end smallexample + +List the line number, the current source file, and the absolute path +to the current source file for the current executable. + +@subsubheading @value{GDBN} Command + +There's no @value{GDBN} command which directly corresponds to this one. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +123-file-list-exec-source-file +123^done,line="1",file="foo.c",fullname="/home/bar/foo.c" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-file-list-exec-source-files} Command +@findex -file-list-exec-source-files + +@subsubheading Synopsis + +@smallexample + -file-list-exec-source-files +@end smallexample + +List the source files for the current executable. + +@subsubheading @value{GDBN} Command + +There's no @value{GDBN} command which directly corresponds to this one. +@code{gdbtk} has an analogous command @samp{gdb_listfiles}. + +@subsubheading Example +N.A. + + +@subheading The @code{-file-list-shared-libraries} Command +@findex -file-list-shared-libraries + +@subsubheading Synopsis + +@smallexample + -file-list-shared-libraries +@end smallexample + +List the shared libraries in the program. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info shared}. + +@subsubheading Example +N.A. + + +@subheading The @code{-file-list-symbol-files} Command +@findex -file-list-symbol-files + +@subsubheading Synopsis + +@smallexample + -file-list-symbol-files +@end smallexample + +List symbol files. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info file} (part of it). + +@subsubheading Example +N.A. + + +@subheading The @code{-file-symbol-file} Command +@findex -file-symbol-file + +@subsubheading Synopsis + +@smallexample + -file-symbol-file @var{file} +@end smallexample + +Read symbol table info from the specified @var{file} argument. When +used without arguments, clears @value{GDBN}'s symbol table info. No output is +produced, except for a completion notification. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{symbol-file}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx +^done +(@value{GDBP}) +@end smallexample + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Miscellaneous Commands +@section Miscellaneous @value{GDBN} commands in @sc{gdb/mi} + +@c @subheading -gdb-complete + +@subheading The @code{-gdb-exit} Command +@findex -gdb-exit + +@subsubheading Synopsis + +@smallexample + -gdb-exit +@end smallexample + +Exit @value{GDBN} immediately. + +@subsubheading @value{GDBN} Command + +Approximately corresponds to @samp{quit}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-gdb-exit +@end smallexample + +@subheading The @code{-gdb-set} Command +@findex -gdb-set + +@subsubheading Synopsis + +@smallexample + -gdb-set +@end smallexample + +Set an internal @value{GDBN} variable. +@c IS THIS A DOLLAR VARIABLE? OR SOMETHING LIKE ANNOTATE ????? + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{set}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-gdb-set $foo=3 +^done +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-gdb-show} Command +@findex -gdb-show + +@subsubheading Synopsis + +@smallexample + -gdb-show +@end smallexample + +Show the current value of a @value{GDBN} variable. + +@subsubheading @value{GDBN} command + +The corresponding @value{GDBN} command is @samp{show}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-gdb-show annotate +^done,value="0" +(@value{GDBP}) +@end smallexample + +@c @subheading -gdb-source + + +@subheading The @code{-gdb-version} Command +@findex -gdb-version + +@subsubheading Synopsis + +@smallexample + -gdb-version +@end smallexample + +Show version information for @value{GDBN}. Used mostly in testing. + +@subsubheading @value{GDBN} Command + +There's no equivalent @value{GDBN} command. @value{GDBN} by default shows this +information when you start an interactive session. + +@subsubheading Example + +@c This example modifies the actual output from GDB to avoid overfull +@c box in TeX. +@smallexample +(@value{GDBP}) +-gdb-version +~GNU gdb 5.2.1 +~Copyright 2000 Free Software Foundation, Inc. +~GDB is free software, covered by the GNU General Public License, and +~you are welcome to change it and/or distribute copies of it under +~ certain conditions. +~Type "show copying" to see the conditions. +~There is absolutely no warranty for GDB. Type "show warranty" for +~ details. +~This GDB was configured as + "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi". +^done +(@value{GDBP}) +@end smallexample + +@subheading The @code{-interpreter-exec} Command +@findex -interpreter-exec + +@subheading Synopsis + +@smallexample +-interpreter-exec @var{interpreter} @var{command} +@end smallexample + +Execute the specified @var{command} in the given @var{interpreter}. + +@subheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{interpreter-exec}. + +@subheading Example + +@smallexample +(@value{GDBP}) +-interpreter-exec console "break main" +&"During symbol reading, couldn't parse type; debugger out of date?.\n" +&"During symbol reading, bad structure-type format.\n" +~"Breakpoint 1 at 0x8074fc6: file ../../src/gdb/main.c, line 743.\n" +^done +(@value{GDBP}) +@end smallexample + +@ignore +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Kod Commands +@section @sc{gdb/mi} Kod Commands + +The Kod commands are not implemented. + +@c @subheading -kod-info + +@c @subheading -kod-list + +@c @subheading -kod-list-object-types + +@c @subheading -kod-show + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Memory Overlay Commands +@section @sc{gdb/mi} Memory Overlay Commands + +The memory overlay commands are not implemented. + +@c @subheading -overlay-auto + +@c @subheading -overlay-list-mapping-state + +@c @subheading -overlay-list-overlays + +@c @subheading -overlay-map + +@c @subheading -overlay-off + +@c @subheading -overlay-on + +@c @subheading -overlay-unmap + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Signal Handling Commands +@section @sc{gdb/mi} Signal Handling Commands + +Signal handling commands are not implemented. + +@c @subheading -signal-handle + +@c @subheading -signal-list-handle-actions + +@c @subheading -signal-list-signal-types +@end ignore + + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Stack Manipulation +@section @sc{gdb/mi} Stack Manipulation Commands + + +@subheading The @code{-stack-info-frame} Command +@findex -stack-info-frame + +@subsubheading Synopsis + +@smallexample + -stack-info-frame +@end smallexample + +Get info on the current frame. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info frame} or @samp{frame} +(without arguments). + +@subsubheading Example +N.A. + +@subheading The @code{-stack-info-depth} Command +@findex -stack-info-depth + +@subsubheading Synopsis + +@smallexample + -stack-info-depth [ @var{max-depth} ] +@end smallexample + +Return the depth of the stack. If the integer argument @var{max-depth} +is specified, do not count beyond @var{max-depth} frames. + +@subsubheading @value{GDBN} Command + +There's no equivalent @value{GDBN} command. + +@subsubheading Example + +For a stack with frame levels 0 through 11: + +@smallexample +(@value{GDBP}) +-stack-info-depth +^done,depth="12" +(@value{GDBP}) +-stack-info-depth 4 +^done,depth="4" +(@value{GDBP}) +-stack-info-depth 12 +^done,depth="12" +(@value{GDBP}) +-stack-info-depth 11 +^done,depth="11" +(@value{GDBP}) +-stack-info-depth 13 +^done,depth="12" +(@value{GDBP}) +@end smallexample + +@subheading The @code{-stack-list-arguments} Command +@findex -stack-list-arguments + +@subsubheading Synopsis + +@smallexample + -stack-list-arguments @var{show-values} + [ @var{low-frame} @var{high-frame} ] +@end smallexample + +Display a list of the arguments for the frames between @var{low-frame} +and @var{high-frame} (inclusive). If @var{low-frame} and +@var{high-frame} are not provided, list the arguments for the whole call +stack. + +The @var{show-values} argument must have a value of 0 or 1. A value of +0 means that only the names of the arguments are listed, a value of 1 +means that both names and values of the arguments are printed. + +@subsubheading @value{GDBN} Command + +@value{GDBN} does not have an equivalent command. @code{gdbtk} has a +@samp{gdb_get_args} command which partially overlaps with the +functionality of @samp{-stack-list-arguments}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-stack-list-frames +^done, +stack=[ +frame=@{level="0",addr="0x00010734",func="callee4", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}, +frame=@{level="1",addr="0x0001076c",func="callee3", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"@}, +frame=@{level="2",addr="0x0001078c",func="callee2", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"@}, +frame=@{level="3",addr="0x000107b4",func="callee1", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"@}, +frame=@{level="4",addr="0x000107e0",func="main", +file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"@}] +(@value{GDBP}) +-stack-list-arguments 0 +^done, +stack-args=[ +frame=@{level="0",args=[]@}, +frame=@{level="1",args=[name="strarg"]@}, +frame=@{level="2",args=[name="intarg",name="strarg"]@}, +frame=@{level="3",args=[name="intarg",name="strarg",name="fltarg"]@}, +frame=@{level="4",args=[]@}] +(@value{GDBP}) +-stack-list-arguments 1 +^done, +stack-args=[ +frame=@{level="0",args=[]@}, +frame=@{level="1", + args=[@{name="strarg",value="0x11940 \"A string argument.\""@}]@}, +frame=@{level="2",args=[ +@{name="intarg",value="2"@}, +@{name="strarg",value="0x11940 \"A string argument.\""@}]@}, +@{frame=@{level="3",args=[ +@{name="intarg",value="2"@}, +@{name="strarg",value="0x11940 \"A string argument.\""@}, +@{name="fltarg",value="3.5"@}]@}, +frame=@{level="4",args=[]@}] +(@value{GDBP}) +-stack-list-arguments 0 2 2 +^done,stack-args=[frame=@{level="2",args=[name="intarg",name="strarg"]@}] +(@value{GDBP}) +-stack-list-arguments 1 2 2 +^done,stack-args=[frame=@{level="2", +args=[@{name="intarg",value="2"@}, +@{name="strarg",value="0x11940 \"A string argument.\""@}]@}] +(@value{GDBP}) +@end smallexample + +@c @subheading -stack-list-exception-handlers + + +@subheading The @code{-stack-list-frames} Command +@findex -stack-list-frames + +@subsubheading Synopsis + +@smallexample + -stack-list-frames [ @var{low-frame} @var{high-frame} ] +@end smallexample + +List the frames currently on the stack. For each frame it displays the +following info: + +@table @samp +@item @var{level} +The frame number, 0 being the topmost frame, i.e. the innermost function. +@item @var{addr} +The @code{$pc} value for that frame. +@item @var{func} +Function name. +@item @var{file} +File name of the source file where the function lives. +@item @var{line} +Line number corresponding to the @code{$pc}. +@end table + +If invoked without arguments, this command prints a backtrace for the +whole stack. If given two integer arguments, it shows the frames whose +levels are between the two arguments (inclusive). If the two arguments +are equal, it shows the single frame at the corresponding level. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} commands are @samp{backtrace} and @samp{where}. + +@subsubheading Example + +Full stack backtrace: + +@smallexample +(@value{GDBP}) +-stack-list-frames +^done,stack= +[frame=@{level="0",addr="0x0001076c",func="foo", + file="recursive2.c",line="11"@}, +frame=@{level="1",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="2",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="3",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="4",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="5",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="6",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="7",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="8",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="9",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="10",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="11",addr="0x00010738",func="main", + file="recursive2.c",line="4"@}] +(@value{GDBP}) +@end smallexample + +Show frames between @var{low_frame} and @var{high_frame}: + +@smallexample +(@value{GDBP}) +-stack-list-frames 3 5 +^done,stack= +[frame=@{level="3",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="4",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}, +frame=@{level="5",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}] +(@value{GDBP}) +@end smallexample + +Show a single frame: + +@smallexample +(@value{GDBP}) +-stack-list-frames 3 3 +^done,stack= +[frame=@{level="3",addr="0x000107a4",func="foo", + file="recursive2.c",line="14"@}] +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-stack-list-locals} Command +@findex -stack-list-locals + +@subsubheading Synopsis + +@smallexample + -stack-list-locals @var{print-values} +@end smallexample + +Display the local variable names for the current frame. With an +argument of 0 or @code{--no-values}, prints only the names of the variables. +With argument of 1 or @code{--all-values}, prints also their values. With +argument of 2 or @code{--simple-values}, prints the name, type and value for +simple data types and the name and type for arrays, structures and +unions. In this last case, the idea is that the user can see the +value of simple data types immediately and he can create variable +objects for other data types if he wishes to explore their values in +more detail. + +@subsubheading @value{GDBN} Command + +@samp{info locals} in @value{GDBN}, @samp{gdb_get_locals} in @code{gdbtk}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-stack-list-locals 0 +^done,locals=[name="A",name="B",name="C"] +(@value{GDBP}) +-stack-list-locals --all-values +^done,locals=[@{name="A",value="1"@},@{name="B",value="2"@}, + @{name="C",value="@{1, 2, 3@}"@}] +-stack-list-locals --simple-values +^done,locals=[@{name="A",type="int",value="1"@}, + @{name="B",type="int",value="2"@},@{name="C",type="int [3]"@}] +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-stack-select-frame} Command +@findex -stack-select-frame + +@subsubheading Synopsis + +@smallexample + -stack-select-frame @var{framenum} +@end smallexample + +Change the current frame. Select a different frame @var{framenum} on +the stack. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} commands are @samp{frame}, @samp{up}, +@samp{down}, @samp{select-frame}, @samp{up-silent}, and @samp{down-silent}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-stack-select-frame 2 +^done +(@value{GDBP}) +@end smallexample + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Symbol Query +@section @sc{gdb/mi} Symbol Query Commands + + +@subheading The @code{-symbol-info-address} Command +@findex -symbol-info-address + +@subsubheading Synopsis + +@smallexample + -symbol-info-address @var{symbol} +@end smallexample + +Describe where @var{symbol} is stored. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info address}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-info-file} Command +@findex -symbol-info-file + +@subsubheading Synopsis + +@smallexample + -symbol-info-file +@end smallexample + +Show the file for the symbol. + +@subsubheading @value{GDBN} Command + +There's no equivalent @value{GDBN} command. @code{gdbtk} has +@samp{gdb_find_file}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-info-function} Command +@findex -symbol-info-function + +@subsubheading Synopsis + +@smallexample + -symbol-info-function +@end smallexample + +Show which function the symbol lives in. + +@subsubheading @value{GDBN} Command + +@samp{gdb_get_function} in @code{gdbtk}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-info-line} Command +@findex -symbol-info-line + +@subsubheading Synopsis + +@smallexample + -symbol-info-line +@end smallexample + +Show the core addresses of the code for a source line. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info line}. +@code{gdbtk} has the @samp{gdb_get_line} and @samp{gdb_get_file} commands. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-info-symbol} Command +@findex -symbol-info-symbol + +@subsubheading Synopsis + +@smallexample + -symbol-info-symbol @var{addr} +@end smallexample + +Describe what symbol is at location @var{addr}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info symbol}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-list-functions} Command +@findex -symbol-list-functions + +@subsubheading Synopsis + +@smallexample + -symbol-list-functions +@end smallexample + +List the functions in the executable. + +@subsubheading @value{GDBN} Command + +@samp{info functions} in @value{GDBN}, @samp{gdb_listfunc} and +@samp{gdb_search} in @code{gdbtk}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-list-lines} Command +@findex -symbol-list-lines + +@subsubheading Synopsis + +@smallexample + -symbol-list-lines @var{filename} +@end smallexample + +Print the list of lines that contain code and their associated program +addresses for the given source filename. The entries are sorted in +ascending PC order. + +@subsubheading @value{GDBN} Command + +There is no corresponding @value{GDBN} command. + +@subsubheading Example +@smallexample +(@value{GDBP}) +-symbol-list-lines basics.c +^done,lines=[@{pc="0x08048554",line="7"@},@{pc="0x0804855a",line="8"@}] +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-symbol-list-types} Command +@findex -symbol-list-types + +@subsubheading Synopsis + +@smallexample + -symbol-list-types +@end smallexample + +List all the type names. + +@subsubheading @value{GDBN} Command + +The corresponding commands are @samp{info types} in @value{GDBN}, +@samp{gdb_search} in @code{gdbtk}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-list-variables} Command +@findex -symbol-list-variables + +@subsubheading Synopsis + +@smallexample + -symbol-list-variables +@end smallexample + +List all the global and static variable names. + +@subsubheading @value{GDBN} Command + +@samp{info variables} in @value{GDBN}, @samp{gdb_search} in @code{gdbtk}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-locate} Command +@findex -symbol-locate + +@subsubheading Synopsis + +@smallexample + -symbol-locate +@end smallexample + +@subsubheading @value{GDBN} Command + +@samp{gdb_loc} in @code{gdbtk}. + +@subsubheading Example +N.A. + + +@subheading The @code{-symbol-type} Command +@findex -symbol-type + +@subsubheading Synopsis + +@smallexample + -symbol-type @var{variable} +@end smallexample + +Show type of @var{variable}. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{ptype}, @code{gdbtk} has +@samp{gdb_obj_variable}. + +@subsubheading Example +N.A. + + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Target Manipulation +@section @sc{gdb/mi} Target Manipulation Commands + + +@subheading The @code{-target-attach} Command +@findex -target-attach + +@subsubheading Synopsis + +@smallexample + -target-attach @var{pid} | @var{file} +@end smallexample + +Attach to a process @var{pid} or a file @var{file} outside of @value{GDBN}. + +@subsubheading @value{GDBN} command + +The corresponding @value{GDBN} command is @samp{attach}. + +@subsubheading Example +N.A. + + +@subheading The @code{-target-compare-sections} Command +@findex -target-compare-sections + +@subsubheading Synopsis + +@smallexample + -target-compare-sections [ @var{section} ] +@end smallexample + +Compare data of section @var{section} on target to the exec file. +Without the argument, all sections are compared. + +@subsubheading @value{GDBN} Command + +The @value{GDBN} equivalent is @samp{compare-sections}. + +@subsubheading Example +N.A. + + +@subheading The @code{-target-detach} Command +@findex -target-detach + +@subsubheading Synopsis + +@smallexample + -target-detach +@end smallexample + +Disconnect from the remote target. There's no output. + +@subsubheading @value{GDBN} command + +The corresponding @value{GDBN} command is @samp{detach}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-target-detach +^done +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-target-disconnect} Command +@findex -target-disconnect + +@subsubheading Synopsis + +@example + -target-disconnect +@end example + +Disconnect from the remote target. There's no output. + +@subsubheading @value{GDBN} command + +The corresponding @value{GDBN} command is @samp{disconnect}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-target-disconnect +^done +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-target-download} Command +@findex -target-download + +@subsubheading Synopsis + +@smallexample + -target-download +@end smallexample + +Loads the executable onto the remote target. +It prints out an update message every half second, which includes the fields: + +@table @samp +@item section +The name of the section. +@item section-sent +The size of what has been sent so far for that section. +@item section-size +The size of the section. +@item total-sent +The total size of what was sent so far (the current and the previous sections). +@item total-size +The size of the overall executable to download. +@end table + +@noindent +Each message is sent as status record (@pxref{GDB/MI Output Syntax, , +@sc{gdb/mi} Output Syntax}). + +In addition, it prints the name and size of the sections, as they are +downloaded. These messages include the following fields: + +@table @samp +@item section +The name of the section. +@item section-size +The size of the section. +@item total-size +The size of the overall executable to download. +@end table + +@noindent +At the end, a summary is printed. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{load}. + +@subsubheading Example + +Note: each status message appears on a single line. Here the messages +have been broken down so that they can fit onto a page. + +@smallexample +(@value{GDBP}) +-target-download ++download,@{section=".text",section-size="6668",total-size="9880"@} ++download,@{section=".text",section-sent="512",section-size="6668", +total-sent="512",total-size="9880"@} ++download,@{section=".text",section-sent="1024",section-size="6668", +total-sent="1024",total-size="9880"@} ++download,@{section=".text",section-sent="1536",section-size="6668", +total-sent="1536",total-size="9880"@} ++download,@{section=".text",section-sent="2048",section-size="6668", +total-sent="2048",total-size="9880"@} ++download,@{section=".text",section-sent="2560",section-size="6668", +total-sent="2560",total-size="9880"@} ++download,@{section=".text",section-sent="3072",section-size="6668", +total-sent="3072",total-size="9880"@} ++download,@{section=".text",section-sent="3584",section-size="6668", +total-sent="3584",total-size="9880"@} ++download,@{section=".text",section-sent="4096",section-size="6668", +total-sent="4096",total-size="9880"@} ++download,@{section=".text",section-sent="4608",section-size="6668", +total-sent="4608",total-size="9880"@} ++download,@{section=".text",section-sent="5120",section-size="6668", +total-sent="5120",total-size="9880"@} ++download,@{section=".text",section-sent="5632",section-size="6668", +total-sent="5632",total-size="9880"@} ++download,@{section=".text",section-sent="6144",section-size="6668", +total-sent="6144",total-size="9880"@} ++download,@{section=".text",section-sent="6656",section-size="6668", +total-sent="6656",total-size="9880"@} ++download,@{section=".init",section-size="28",total-size="9880"@} ++download,@{section=".fini",section-size="28",total-size="9880"@} ++download,@{section=".data",section-size="3156",total-size="9880"@} ++download,@{section=".data",section-sent="512",section-size="3156", +total-sent="7236",total-size="9880"@} ++download,@{section=".data",section-sent="1024",section-size="3156", +total-sent="7748",total-size="9880"@} ++download,@{section=".data",section-sent="1536",section-size="3156", +total-sent="8260",total-size="9880"@} ++download,@{section=".data",section-sent="2048",section-size="3156", +total-sent="8772",total-size="9880"@} ++download,@{section=".data",section-sent="2560",section-size="3156", +total-sent="9284",total-size="9880"@} ++download,@{section=".data",section-sent="3072",section-size="3156", +total-sent="9796",total-size="9880"@} +^done,address="0x10004",load-size="9880",transfer-rate="6586", +write-rate="429" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-target-exec-status} Command +@findex -target-exec-status + +@subsubheading Synopsis + +@smallexample + -target-exec-status +@end smallexample + +Provide information on the state of the target (whether it is running or +not, for instance). + +@subsubheading @value{GDBN} Command + +There's no equivalent @value{GDBN} command. + +@subsubheading Example +N.A. + + +@subheading The @code{-target-list-available-targets} Command +@findex -target-list-available-targets + +@subsubheading Synopsis + +@smallexample + -target-list-available-targets +@end smallexample + +List the possible targets to connect to. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{help target}. + +@subsubheading Example +N.A. + + +@subheading The @code{-target-list-current-targets} Command +@findex -target-list-current-targets + +@subsubheading Synopsis + +@smallexample + -target-list-current-targets +@end smallexample + +Describe the current target. + +@subsubheading @value{GDBN} Command + +The corresponding information is printed by @samp{info file} (among +other things). + +@subsubheading Example +N.A. + + +@subheading The @code{-target-list-parameters} Command +@findex -target-list-parameters + +@subsubheading Synopsis + +@smallexample + -target-list-parameters +@end smallexample + +@c ???? + +@subsubheading @value{GDBN} Command + +No equivalent. + +@subsubheading Example +N.A. + + +@subheading The @code{-target-select} Command +@findex -target-select + +@subsubheading Synopsis + +@smallexample + -target-select @var{type} @var{parameters @dots{}} +@end smallexample + +Connect @value{GDBN} to the remote target. This command takes two args: + +@table @samp +@item @var{type} +The type of target, for instance @samp{async}, @samp{remote}, etc. +@item @var{parameters} +Device names, host names and the like. @xref{Target Commands, , +Commands for managing targets}, for more details. +@end table + +The output is a connection notification, followed by the address at +which the target program is, in the following form: + +@smallexample +^connected,addr="@var{address}",func="@var{function name}", + args=[@var{arg list}] +@end smallexample + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{target}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-target-select async /dev/ttya +^connected,addr="0xfe00a300",func="??",args=[] +(@value{GDBP}) +@end smallexample + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Thread Commands +@section @sc{gdb/mi} Thread Commands + + +@subheading The @code{-thread-info} Command +@findex -thread-info + +@subsubheading Synopsis + +@smallexample + -thread-info +@end smallexample + +@subsubheading @value{GDBN} command + +No equivalent. + +@subsubheading Example +N.A. + + +@subheading The @code{-thread-list-all-threads} Command +@findex -thread-list-all-threads + +@subsubheading Synopsis + +@smallexample + -thread-list-all-threads +@end smallexample + +@subsubheading @value{GDBN} Command + +The equivalent @value{GDBN} command is @samp{info threads}. + +@subsubheading Example +N.A. + + +@subheading The @code{-thread-list-ids} Command +@findex -thread-list-ids + +@subsubheading Synopsis + +@smallexample + -thread-list-ids +@end smallexample + +Produces a list of the currently known @value{GDBN} thread ids. At the +end of the list it also prints the total number of such threads. + +@subsubheading @value{GDBN} Command + +Part of @samp{info threads} supplies the same information. + +@subsubheading Example + +No threads present, besides the main process: + +@smallexample +(@value{GDBP}) +-thread-list-ids +^done,thread-ids=@{@},number-of-threads="0" +(@value{GDBP}) +@end smallexample + + +Several threads: + +@smallexample +(@value{GDBP}) +-thread-list-ids +^done,thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@}, +number-of-threads="3" +(@value{GDBP}) +@end smallexample + + +@subheading The @code{-thread-select} Command +@findex -thread-select + +@subsubheading Synopsis + +@smallexample + -thread-select @var{threadnum} +@end smallexample + +Make @var{threadnum} the current thread. It prints the number of the new +current thread, and the topmost frame for that thread. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{thread}. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-exec-next +^running +(@value{GDBP}) +*stopped,reason="end-stepping-range",thread-id="2",line="187", +file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c" +(@value{GDBP}) +-thread-list-ids +^done, +thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@}, +number-of-threads="3" +(@value{GDBP}) +-thread-select 3 +^done,new-thread-id="3", +frame=@{level="0",func="vprintf", +args=[@{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""@}, +@{name="arg",value="0x2"@}],file="vprintf.c",line="31"@} +(@value{GDBP}) +@end smallexample + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Tracepoint Commands +@section @sc{gdb/mi} Tracepoint Commands + +The tracepoint commands are not yet implemented. + +@c @subheading -trace-actions + +@c @subheading -trace-delete + +@c @subheading -trace-disable + +@c @subheading -trace-dump + +@c @subheading -trace-enable + +@c @subheading -trace-exists + +@c @subheading -trace-find + +@c @subheading -trace-frame-number + +@c @subheading -trace-info + +@c @subheading -trace-insert + +@c @subheading -trace-list + +@c @subheading -trace-pass-count + +@c @subheading -trace-save + +@c @subheading -trace-start + +@c @subheading -trace-stop + + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Variable Objects +@section @sc{gdb/mi} Variable Objects + + +@subheading Motivation for Variable Objects in @sc{gdb/mi} + +For the implementation of a variable debugger window (locals, watched +expressions, etc.), we are proposing the adaptation of the existing code +used by @code{Insight}. + +The two main reasons for that are: + +@enumerate 1 +@item +It has been proven in practice (it is already on its second generation). + +@item +It will shorten development time (needless to say how important it is +now). +@end enumerate + +The original interface was designed to be used by Tcl code, so it was +slightly changed so it could be used through @sc{gdb/mi}. This section +describes the @sc{gdb/mi} operations that will be available and gives some +hints about their use. + +@emph{Note}: In addition to the set of operations described here, we +expect the @sc{gui} implementation of a variable window to require, at +least, the following operations: + +@itemize @bullet +@item @code{-gdb-show} @code{output-radix} +@item @code{-stack-list-arguments} +@item @code{-stack-list-locals} +@item @code{-stack-select-frame} +@end itemize + +@subheading Introduction to Variable Objects in @sc{gdb/mi} + +@cindex variable objects in @sc{gdb/mi} +The basic idea behind variable objects is the creation of a named object +to represent a variable, an expression, a memory location or even a CPU +register. For each object created, a set of operations is available for +examining or changing its properties. + +Furthermore, complex data types, such as C structures, are represented +in a tree format. For instance, the @code{struct} type variable is the +root and the children will represent the struct members. If a child +is itself of a complex type, it will also have children of its own. +Appropriate language differences are handled for C, C@t{++} and Java. + +When returning the actual values of the objects, this facility allows +for the individual selection of the display format used in the result +creation. It can be chosen among: binary, decimal, hexadecimal, octal +and natural. Natural refers to a default format automatically +chosen based on the variable type (like decimal for an @code{int}, hex +for pointers, etc.). + +The following is the complete set of @sc{gdb/mi} operations defined to +access this functionality: + +@multitable @columnfractions .4 .6 +@item @strong{Operation} +@tab @strong{Description} + +@item @code{-var-create} +@tab create a variable object +@item @code{-var-delete} +@tab delete the variable object and its children +@item @code{-var-set-format} +@tab set the display format of this variable +@item @code{-var-show-format} +@tab show the display format of this variable +@item @code{-var-info-num-children} +@tab tells how many children this object has +@item @code{-var-list-children} +@tab return a list of the object's children +@item @code{-var-info-type} +@tab show the type of this variable object +@item @code{-var-info-expression} +@tab print what this variable object represents +@item @code{-var-show-attributes} +@tab is this variable editable? does it exist here? +@item @code{-var-evaluate-expression} +@tab get the value of this variable +@item @code{-var-assign} +@tab set the value of this variable +@item @code{-var-update} +@tab update the variable and its children +@end multitable + +In the next subsection we describe each operation in detail and suggest +how it can be used. + +@subheading Description And Use of Operations on Variable Objects + +@subheading The @code{-var-create} Command +@findex -var-create + +@subsubheading Synopsis + +@smallexample + -var-create @{@var{name} | "-"@} + @{@var{frame-addr} | "*"@} @var{expression} +@end smallexample + +This operation creates a variable object, which allows the monitoring of +a variable, the result of an expression, a memory cell or a CPU +register. + +The @var{name} parameter is the string by which the object can be +referenced. It must be unique. If @samp{-} is specified, the varobj +system will generate a string ``varNNNNNN'' automatically. It will be +unique provided that one does not specify @var{name} on that format. +The command fails if a duplicate name is found. + +The frame under which the expression should be evaluated can be +specified by @var{frame-addr}. A @samp{*} indicates that the current +frame should be used. + +@var{expression} is any expression valid on the current language set (must not +begin with a @samp{*}), or one of the following: + +@itemize @bullet +@item +@samp{*@var{addr}}, where @var{addr} is the address of a memory cell + +@item +@samp{*@var{addr}-@var{addr}} --- a memory address range (TBD) + +@item +@samp{$@var{regname}} --- a CPU register name +@end itemize + +@subsubheading Result + +This operation returns the name, number of children and the type of the +object created. Type is returned as a string as the ones generated by +the @value{GDBN} CLI: + +@smallexample + name="@var{name}",numchild="N",type="@var{type}" +@end smallexample + + +@subheading The @code{-var-delete} Command +@findex -var-delete + +@subsubheading Synopsis + +@smallexample + -var-delete @var{name} +@end smallexample + +Deletes a previously created variable object and all of its children. + +Returns an error if the object @var{name} is not found. + + +@subheading The @code{-var-set-format} Command +@findex -var-set-format + +@subsubheading Synopsis + +@smallexample + -var-set-format @var{name} @var{format-spec} +@end smallexample + +Sets the output format for the value of the object @var{name} to be +@var{format-spec}. + +The syntax for the @var{format-spec} is as follows: + +@smallexample + @var{format-spec} @expansion{} + @{binary | decimal | hexadecimal | octal | natural@} +@end smallexample + + +@subheading The @code{-var-show-format} Command +@findex -var-show-format + +@subsubheading Synopsis + +@smallexample + -var-show-format @var{name} +@end smallexample + +Returns the format used to display the value of the object @var{name}. + +@smallexample + @var{format} @expansion{} + @var{format-spec} +@end smallexample + + +@subheading The @code{-var-info-num-children} Command +@findex -var-info-num-children + +@subsubheading Synopsis + +@smallexample + -var-info-num-children @var{name} +@end smallexample + +Returns the number of children of a variable object @var{name}: + +@smallexample + numchild=@var{n} +@end smallexample + + +@subheading The @code{-var-list-children} Command +@findex -var-list-children + +@subsubheading Synopsis + +@smallexample + -var-list-children [@var{print-values}] @var{name} +@end smallexample + +Returns a list of the children of the specified variable object. With +just the variable object name as an argument or with an optional +preceding argument of 0 or @code{--no-values}, prints only the names of the +variables. With an optional preceding argument of 1 or @code{--all-values}, +also prints their values. + +@subsubheading Example + +@smallexample +(@value{GDBP}) + -var-list-children n + numchild=@var{n},children=[@{name=@var{name}, + numchild=@var{n},type=@var{type}@},@r{(repeats N times)}] +(@value{GDBP}) + -var-list-children --all-values n + numchild=@var{n},children=[@{name=@var{name}, + numchild=@var{n},value=@var{value},type=@var{type}@},@r{(repeats N times)}] +@end smallexample + + +@subheading The @code{-var-info-type} Command +@findex -var-info-type + +@subsubheading Synopsis + +@smallexample + -var-info-type @var{name} +@end smallexample + +Returns the type of the specified variable @var{name}. The type is +returned as a string in the same format as it is output by the +@value{GDBN} CLI: + +@smallexample + type=@var{typename} +@end smallexample + + +@subheading The @code{-var-info-expression} Command +@findex -var-info-expression + +@subsubheading Synopsis + +@smallexample + -var-info-expression @var{name} +@end smallexample + +Returns what is represented by the variable object @var{name}: + +@smallexample + lang=@var{lang-spec},exp=@var{expression} +@end smallexample + +@noindent +where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}. + +@subheading The @code{-var-show-attributes} Command +@findex -var-show-attributes + +@subsubheading Synopsis + +@smallexample + -var-show-attributes @var{name} +@end smallexample + +List attributes of the specified variable object @var{name}: + +@smallexample + status=@var{attr} [ ( ,@var{attr} )* ] +@end smallexample + +@noindent +where @var{attr} is @code{@{ @{ editable | noneditable @} | TBD @}}. + +@subheading The @code{-var-evaluate-expression} Command +@findex -var-evaluate-expression + +@subsubheading Synopsis + +@smallexample + -var-evaluate-expression @var{name} +@end smallexample + +Evaluates the expression that is represented by the specified variable +object and returns its value as a string in the current format specified +for the object: + +@smallexample + value=@var{value} +@end smallexample + +Note that one must invoke @code{-var-list-children} for a variable +before the value of a child variable can be evaluated. + +@subheading The @code{-var-assign} Command +@findex -var-assign + +@subsubheading Synopsis + +@smallexample + -var-assign @var{name} @var{expression} +@end smallexample + +Assigns the value of @var{expression} to the variable object specified +by @var{name}. The object must be @samp{editable}. If the variable's +value is altered by the assign, the variable will show up in any +subsequent @code{-var-update} list. + +@subsubheading Example + +@smallexample +(@value{GDBP}) +-var-assign var1 3 +^done,value="3" +(@value{GDBP}) +-var-update * +^done,changelist=[@{name="var1",in_scope="true",type_changed="false"@}] +(@value{GDBP}) +@end smallexample + +@subheading The @code{-var-update} Command +@findex -var-update + +@subsubheading Synopsis + +@smallexample + -var-update @{@var{name} | "*"@} +@end smallexample + +Update the value of the variable object @var{name} by evaluating its +expression after fetching all the new values from memory or registers. +A @samp{*} causes all existing variable objects to be updated. + + +@node Annotations +@chapter @value{GDBN} Annotations + +This chapter describes annotations in @value{GDBN}. Annotations were +designed to interface @value{GDBN} to graphical user interfaces or other +similar programs which want to interact with @value{GDBN} at a +relatively high level. + +The annotation mechanism has largely been superseeded by @sc{gdb/mi} +(@pxref{GDB/MI}). + +@ignore +This is Edition @value{EDITION}, @value{DATE}. +@end ignore + +@menu +* Annotations Overview:: What annotations are; the general syntax. +* Server Prefix:: Issuing a command without affecting user state. +* Prompting:: Annotations marking @value{GDBN}'s need for input. +* Errors:: Annotations for error messages. +* Invalidation:: Some annotations describe things now invalid. +* Annotations for Running:: + Whether the program is running, how it stopped, etc. +* Source Annotations:: Annotations describing source code. +@end menu + +@node Annotations Overview +@section What is an Annotation? +@cindex annotations + +Annotations start with a newline character, two @samp{control-z} +characters, and the name of the annotation. If there is no additional +information associated with this annotation, the name of the annotation +is followed immediately by a newline. If there is additional +information, the name of the annotation is followed by a space, the +additional information, and a newline. The additional information +cannot contain newline characters. + +Any output not beginning with a newline and two @samp{control-z} +characters denotes literal output from @value{GDBN}. Currently there is +no need for @value{GDBN} to output a newline followed by two +@samp{control-z} characters, but if there was such a need, the +annotations could be extended with an @samp{escape} annotation which +means those three characters as output. + +The annotation @var{level}, which is specified using the +@option{--annotate} command line option (@pxref{Mode Options}), controls +how much information @value{GDBN} prints together with its prompt, +values of expressions, source lines, and other types of output. Level 0 +is for no anntations, level 1 is for use when @value{GDBN} is run as a +subprocess of @sc{gnu} Emacs, level 3 is the maximum annotation suitable +for programs that control @value{GDBN}, and level 2 annotations have +been made obsolete (@pxref{Limitations, , Limitations of the Annotation +Interface, annotate, GDB's Obsolete Annotations}). This chapter +describes level 3 annotations. + +A simple example of starting up @value{GDBN} with annotations is: + +@smallexample +$ @kbd{gdb --annotate=3} +GNU gdb 6.0 +Copyright 2003 Free Software Foundation, Inc. +GDB is free software, covered by the GNU General Public License, +and you are welcome to change it and/or distribute copies of it +under certain conditions. +Type "show copying" to see the conditions. +There is absolutely no warranty for GDB. Type "show warranty" +for details. +This GDB was configured as "i386-pc-linux-gnu" + +^Z^Zpre-prompt +(gdb) +^Z^Zprompt +@kbd{quit} + +^Z^Zpost-prompt +$ +@end smallexample + +Here @samp{quit} is input to @value{GDBN}; the rest is output from +@value{GDBN}. The three lines beginning @samp{^Z^Z} (where @samp{^Z} +denotes a @samp{control-z} character) are annotations; the rest is +output from @value{GDBN}. + +@node Server Prefix +@section The Server Prefix +@cindex server prefix for annotations + +To issue a command to @value{GDBN} without affecting certain aspects of +the state which is seen by users, prefix it with @samp{server }. This +means that this command will not affect the command history, nor will it +affect @value{GDBN}'s notion of which command to repeat if @key{RET} is +pressed on a line by itself. + +The server prefix does not affect the recording of values into the value +history; to print a value without recording it into the value history, +use the @code{output} command instead of the @code{print} command. + +@node Prompting +@section Annotation for @value{GDBN} Input + +@cindex annotations for prompts +When @value{GDBN} prompts for input, it annotates this fact so it is possible +to know when to send output, when the output from a given command is +over, etc. + +Different kinds of input each have a different @dfn{input type}. Each +input type has three annotations: a @code{pre-} annotation, which +denotes the beginning of any prompt which is being output, a plain +annotation, which denotes the end of the prompt, and then a @code{post-} +annotation which denotes the end of any echo which may (or may not) be +associated with the input. For example, the @code{prompt} input type +features the following annotations: + +@smallexample +^Z^Zpre-prompt +^Z^Zprompt +^Z^Zpost-prompt +@end smallexample + +The input types are + +@table @code +@findex pre-prompt +@findex prompt +@findex post-prompt +@item prompt +When @value{GDBN} is prompting for a command (the main @value{GDBN} prompt). + +@findex pre-commands +@findex commands +@findex post-commands +@item commands +When @value{GDBN} prompts for a set of commands, like in the @code{commands} +command. The annotations are repeated for each command which is input. + +@findex pre-overload-choice +@findex overload-choice +@findex post-overload-choice +@item overload-choice +When @value{GDBN} wants the user to select between various overloaded functions. + +@findex pre-query +@findex query +@findex post-query +@item query +When @value{GDBN} wants the user to confirm a potentially dangerous operation. + +@findex pre-prompt-for-continue +@findex prompt-for-continue +@findex post-prompt-for-continue +@item prompt-for-continue +When @value{GDBN} is asking the user to press return to continue. Note: Don't +expect this to work well; instead use @code{set height 0} to disable +prompting. This is because the counting of lines is buggy in the +presence of annotations. +@end table + +@node Errors +@section Errors +@cindex annotations for errors, warnings and interrupts + +@findex quit +@smallexample +^Z^Zquit +@end smallexample + +This annotation occurs right before @value{GDBN} responds to an interrupt. + +@findex error +@smallexample +^Z^Zerror +@end smallexample + +This annotation occurs right before @value{GDBN} responds to an error. + +Quit and error annotations indicate that any annotations which @value{GDBN} was +in the middle of may end abruptly. For example, if a +@code{value-history-begin} annotation is followed by a @code{error}, one +cannot expect to receive the matching @code{value-history-end}. One +cannot expect not to receive it either, however; an error annotation +does not necessarily mean that @value{GDBN} is immediately returning all the way +to the top level. + +@findex error-begin +A quit or error annotation may be preceded by + +@smallexample +^Z^Zerror-begin +@end smallexample + +Any output between that and the quit or error annotation is the error +message. + +Warning messages are not yet annotated. +@c If we want to change that, need to fix warning(), type_error(), +@c range_error(), and possibly other places. + +@node Invalidation +@section Invalidation Notices + +@cindex annotations for invalidation messages +The following annotations say that certain pieces of state may have +changed. + +@table @code +@findex frames-invalid +@item ^Z^Zframes-invalid + +The frames (for example, output from the @code{backtrace} command) may +have changed. + +@findex breakpoints-invalid +@item ^Z^Zbreakpoints-invalid + +The breakpoints may have changed. For example, the user just added or +deleted a breakpoint. +@end table + +@node Annotations for Running +@section Running the Program +@cindex annotations for running programs + +@findex starting +@findex stopping +When the program starts executing due to a @value{GDBN} command such as +@code{step} or @code{continue}, + +@smallexample +^Z^Zstarting +@end smallexample + +is output. When the program stops, + +@smallexample +^Z^Zstopped +@end smallexample + +is output. Before the @code{stopped} annotation, a variety of +annotations describe how the program stopped. + +@table @code +@findex exited +@item ^Z^Zexited @var{exit-status} +The program exited, and @var{exit-status} is the exit status (zero for +successful exit, otherwise nonzero). + +@findex signalled +@findex signal-name +@findex signal-name-end +@findex signal-string +@findex signal-string-end +@item ^Z^Zsignalled +The program exited with a signal. After the @code{^Z^Zsignalled}, the +annotation continues: + +@smallexample +@var{intro-text} +^Z^Zsignal-name +@var{name} +^Z^Zsignal-name-end +@var{middle-text} +^Z^Zsignal-string +@var{string} +^Z^Zsignal-string-end +@var{end-text} +@end smallexample + +@noindent +where @var{name} is the name of the signal, such as @code{SIGILL} or +@code{SIGSEGV}, and @var{string} is the explanation of the signal, such +as @code{Illegal Instruction} or @code{Segmentation fault}. +@var{intro-text}, @var{middle-text}, and @var{end-text} are for the +user's benefit and have no particular format. + +@findex signal +@item ^Z^Zsignal +The syntax of this annotation is just like @code{signalled}, but @value{GDBN} is +just saying that the program received the signal, not that it was +terminated with it. + +@findex breakpoint +@item ^Z^Zbreakpoint @var{number} +The program hit breakpoint number @var{number}. + +@findex watchpoint +@item ^Z^Zwatchpoint @var{number} +The program hit watchpoint number @var{number}. +@end table + +@node Source Annotations +@section Displaying Source +@cindex annotations for source display + +@findex source +The following annotation is used instead of displaying source code: + +@smallexample +^Z^Zsource @var{filename}:@var{line}:@var{character}:@var{middle}:@var{addr} +@end smallexample + +where @var{filename} is an absolute file name indicating which source +file, @var{line} is the line number within that file (where 1 is the +first line in the file), @var{character} is the character position +within the file (where 0 is the first character in the file) (for most +debug formats this will necessarily point to the beginning of a line), +@var{middle} is @samp{middle} if @var{addr} is in the middle of the +line, or @samp{beg} if @var{addr} is at the beginning of the line, and +@var{addr} is the address in the target program associated with the +source which is being displayed. @var{addr} is in the form @samp{0x} +followed by one or more lowercase hex digits (note that this does not +depend on the language). @node GDB Bugs @chapter Reporting Bugs in @value{GDBN} @@ -13680,9 +18987,9 @@ you can print the reference card immediately with @file{refcard.ps}. The release also includes the source for the reference card. You can format it, using @TeX{}, by typing: -@example +@smallexample make refcard.dvi -@end example +@end smallexample The @value{GDBN} reference card is designed to print in @dfn{landscape} mode on US ``letter'' size paper; @@ -13716,10 +19023,10 @@ If you have @code{makeinfo} installed, and are in the top level @value{GDBN} source directory (@file{gdb-@value{GDBVN}}, in the case of version @value{GDBVN}), you can make the Info file by typing: -@example +@smallexample cd gdb make gdb.info -@end example +@end smallexample If you want to typeset and print copies of this manual, you need @TeX{}, a program to print its @sc{dvi} output files, and @file{texinfo.tex}, the @@ -13745,9 +19052,9 @@ typeset and print this manual. First switch to the the @file{gdb} subdirectory of the main source directory (for example, to @file{gdb-@value{GDBVN}/gdb}) and type: -@example +@smallexample make gdb.dvi -@end example +@end smallexample Then give @file{gdb.dvi} to your @sc{dvi} printing program. @@ -13755,6 +19062,7 @@ Then give @file{gdb.dvi} to your @sc{dvi} printing program. @appendix Installing @value{GDBN} @cindex configuring @value{GDBN} @cindex installation +@cindex configuring @value{GDBN}, and source tree subdirectories @value{GDBN} comes with a @code{configure} script that automates the process of preparing @value{GDBN} for installation; you can then use @code{make} to @@ -13813,11 +19121,11 @@ argument. For example: -@example +@smallexample cd gdb-@value{GDBVN} ./configure @var{host} make -@end example +@end smallexample @noindent where @var{host} is an identifier such as @samp{sun4} or @@ -13835,9 +19143,9 @@ binaries, are left in the corresponding source directories. system does not recognize this automatically when you run a different shell, you may need to run @code{sh} on it explicitly: -@example +@smallexample sh configure @var{host} -@end example +@end smallexample If you run @code{configure} from a directory that contains source directories for multiple libraries or programs, such as the @@ -13845,19 +19153,15 @@ directories for multiple libraries or programs, such as the creates configuration files for every directory level underneath (unless you tell it not to, with the @samp{--norecursion} option). -You can run the @code{configure} script from any of the -subordinate directories in the @value{GDBN} distribution if you only want to -configure that subdirectory, but be sure to specify a path to it. - -For example, with version @value{GDBVN}, type the following to configure only -the @code{bfd} subdirectory: - -@example -@group -cd gdb-@value{GDBVN}/bfd -../configure @var{host} -@end group -@end example +You should run the @code{configure} script from the top directory in the +source tree, the @file{gdb-@var{version-number}} directory. If you run +@code{configure} from one of the subdirectories, you will configure only +that subdirectory. That is usually not what you want. In particular, +if you run the first @code{configure} from the @file{gdb} subdirectory +of the @file{gdb-@var{version-number}} directory, you will omit the +configuration of @file{bfd}, @file{readline}, and other sibling +directories of the @file{gdb} subdirectory. This leads to build errors +about missing include files such as @file{bfd/bfd.h}. You can install @code{@value{GDBP}} anywhere; it has no hardwired paths. However, you should make sure that the shell on your path (named by @@ -13893,7 +19197,7 @@ the @samp{--srcdir} option; it is assumed.) For example, with version @value{GDBVN}, you can build @value{GDBN} in a separate directory for a Sun 4 like this: -@example +@smallexample @group cd gdb-@value{GDBVN} mkdir ../gdb-sun4 @@ -13901,7 +19205,7 @@ cd ../gdb-sun4 ../gdb-@value{GDBVN}/configure sun4 make @end group -@end example +@end smallexample When @code{configure} builds a configuration using a remote source directory, it creates a tree for the binaries with the same structure @@ -13910,6 +19214,12 @@ the example, you'd find the Sun 4 library @file{libiberty.a} in the directory @file{gdb-sun4/libiberty}, and @value{GDBN} itself in @file{gdb-sun4/gdb}. +Make sure that your path to the @file{configure} script has just one +instance of @file{gdb} in it. If your path to @file{configure} looks +like @file{../gdb-@value{GDBVN}/gdb/configure}, you are configuring only +one subdirectory of @value{GDBN}, not the whole package. This leads to +build errors about missing include files such as @file{bfd/bfd.h}. + One popular reason to build several @value{GDBN} configurations in separate directories is to configure @value{GDBN} for cross-compiling (where @value{GDBN} runs on one machine---the @dfn{host}---while debugging @@ -13940,9 +19250,9 @@ script are based on a three-part naming scheme, but some short predefined aliases are also supported. The full naming scheme encodes three pieces of information in the following pattern: -@example +@smallexample @var{architecture}-@var{vendor}-@var{os} -@end example +@end smallexample For example, you can use the alias @code{sun4} as a @var{host} argument, or as the value for @var{target} in a @code{--target=@var{target}} @@ -13982,7 +19292,7 @@ are most often useful for building @value{GDBN}. @code{configure} also has several other options not listed here. @inforef{What Configure Does,,configure.info}, for a full explanation of @code{configure}. -@example +@smallexample configure @r{[}--help@r{]} @r{[}--prefix=@var{dir}@r{]} @r{[}--exec-prefix=@var{dir}@r{]} @@ -13990,7 +19300,7 @@ configure @r{[}--help@r{]} @r{[}--norecursion@r{]} @r{[}--rm@r{]} @r{[}--target=@var{target}@r{]} @var{host} -@end example +@end smallexample @noindent You may introduce options with a single @samp{-} rather than @@ -14086,18 +19396,132 @@ Shared library events. @end table +@kindex maint internal-error +@kindex maint internal-warning +@item maint internal-error +@itemx maint internal-warning +Cause @value{GDBN} to call the internal function @code{internal_error} +or @code{internal_warning} and hence behave as though an internal error +or internal warning has been detected. In addition to reporting the +internal problem, these functions give the user the opportunity to +either quit @value{GDBN} or create a core file of the current +@value{GDBN} session. + +@smallexample +(gdb) @kbd{maint internal-error testing, 1, 2} +@dots{}/maint.c:121: internal-error: testing, 1, 2 +A problem internal to GDB has been detected. Further +debugging may prove unreliable. +Quit this debugging session? (y or n) @kbd{n} +Create a core file? (y or n) @kbd{n} +(gdb) +@end smallexample + +Takes an optional parameter that is used as the text of the error or +warning message. + +@kindex maint print dummy-frames +@item maint print dummy-frames + +Prints the contents of @value{GDBN}'s internal dummy-frame stack. + +@smallexample +(gdb) @kbd{b add} +@dots{} +(gdb) @kbd{print add(2,3)} +Breakpoint 2, add (a=2, b=3) at @dots{} +58 return (a + b); +The program being debugged stopped while in a function called from GDB. +@dots{} +(gdb) @kbd{maint print dummy-frames} +0x1a57c80: pc=0x01014068 fp=0x0200bddc sp=0x0200bdd6 + top=0x0200bdd4 id=@{stack=0x200bddc,code=0x101405c@} + call_lo=0x01014000 call_hi=0x01014001 +(gdb) +@end smallexample + +Takes an optional file parameter. + +@kindex maint print registers +@kindex maint print raw-registers +@kindex maint print cooked-registers +@kindex maint print register-groups +@item maint print registers +@itemx maint print raw-registers +@itemx maint print cooked-registers +@itemx maint print register-groups +Print @value{GDBN}'s internal register data structures. + +The command @code{maint print raw-registers} includes the contents of +the raw register cache; the command @code{maint print cooked-registers} +includes the (cooked) value of all registers; and the command +@code{maint print register-groups} includes the groups that each +register is a member of. @xref{Registers,, Registers, gdbint, +@value{GDBN} Internals}. + +Takes an optional file parameter. + +@kindex maint print reggroups +@item maint print reggroups +Print @value{GDBN}'s internal register group data structures. + +Takes an optional file parameter. + +@smallexample +(gdb) @kbd{maint print reggroups} + Group Type + general user + float user + all user + vector user + system user + save internal + restore internal +@end smallexample + +@kindex maint set profile +@kindex maint show profile +@cindex profiling GDB +@item maint set profile +@itemx maint show profile +Control profiling of @value{GDBN}. + +Profiling will be disabled until you use the @samp{maint set profile} +command to enable it. When you enable profiling, the system will begin +collecting timing and execution count data; when you disable profiling or +exit @value{GDBN}, the results will be written to a log file. Remember that +if you use profiling, @value{GDBN} will overwrite the profiling log file +(often called @file{gmon.out}). If you have a record of important profiling +data in a @file{gmon.out} file, be sure to move it to a safe location. + +Configuring with @samp{--enable-profiling} arranges for @value{GDBN} to be +compiled with the @samp{-pg} compiler option. + @end table @node Remote Protocol @appendix @value{GDBN} Remote Serial Protocol +@menu +* Overview:: +* Packets:: +* Stop Reply Packets:: +* General Query Packets:: +* Register Packet Format:: +* Examples:: +* File-I/O remote protocol extension:: +@end menu + +@node Overview +@section Overview + There may be occasions when you need to know something about the protocol---for example, if there is only one serial port to your target machine, you might want your program to do something special if it recognizes a packet meant for @value{GDBN}. -In the examples below, @samp{<-} and @samp{->} are used to indicate +In the examples below, @samp{->} and @samp{<-} are used to indicate transmitted and received data respectfully. @cindex protocol, @value{GDBN} remote serial @@ -14108,9 +19532,9 @@ sent as a @var{packet}. A @var{packet} is introduced with the character @samp{$}, the actual @var{packet-data}, and the terminating character @samp{#} followed by a two-digit @var{checksum}: -@example +@smallexample @code{$}@var{packet-data}@code{#}@var{checksum} -@end example +@end smallexample @noindent @cindex checksum, for @value{GDBN} remote @@ -14122,9 +19546,9 @@ eight bit unsigned checksum). Implementors should note that prior to @value{GDBN} 5.0 the protocol specification also included an optional two-digit @var{sequence-id}: -@example +@smallexample @code{$}@var{sequence-id}@code{:}@var{packet-data}@code{#}@var{checksum} -@end example +@end smallexample @cindex sequence-id, for @value{GDBN} remote @noindent @@ -14138,10 +19562,10 @@ response expected is an acknowledgment: either @samp{+} (to indicate the package was received correctly) or @samp{-} (to request retransmission): -@example -<- @code{$}@var{packet-data}@code{#}@var{checksum} --> @code{+} -@end example +@smallexample +-> @code{$}@var{packet-data}@code{#}@var{checksum} +<- @code{+} +@end smallexample @noindent The host (@value{GDBN}) sends @var{command}s, and the target (the @@ -14154,8 +19578,9 @@ exception of @samp{#} and @samp{$} (see @samp{X} packet for additional exceptions). Fields within the packet should be separated using @samp{,} @samp{;} or +@cindex remote protocol, field separator @samp{:}. Except where otherwise noted all numbers are represented in -HEX with leading zeros suppressed. +@sc{hex} with leading zeros suppressed. Implementors should note that prior to @value{GDBN} 5.0, the character @samp{:} could not appear as the third character in a packet (as it @@ -14169,14 +19594,10 @@ where @code{n >=3} (which is where rle starts to win). The printable characters @samp{$}, @samp{#}, @samp{+} and @samp{-} or with a numeric value greater than 126 should not be used. -Some remote systems have used a different run-length encoding mechanism -loosely refered to as the cisco encoding. Following the @samp{*} -character are two hex digits that indicate the size of the packet. - So: -@example +@smallexample "@code{0* }" -@end example +@end smallexample @noindent means the same as "0000". @@ -14188,170 +19609,188 @@ For any @var{command} not supported by the stub, an empty response protocol. A newer @value{GDBN} can tell if a packet is supported based on that response. -A stub is required to support the @samp{g}, @samp{G}, @samp{m}, @samp{M}, -@samp{c}, and @samp{s} @var{command}s. All other @var{command}s are +A stub is required to support the @samp{g}, @samp{G}, @samp{m}, @samp{M}, +@samp{c}, and @samp{s} @var{command}s. All other @var{command}s are optional. -Below is a complete list of all currently defined @var{command}s and -their corresponding response @var{data}: -@page -@multitable @columnfractions .30 .30 .40 -@item Packet -@tab Request -@tab Description +@node Packets +@section Packets + +The following table provides a complete list of all currently defined +@var{command}s and their corresponding response @var{data}. + +@table @r + +@item @code{!} --- extended mode +@cindex @code{!} packet -@item extended mode -@tab @code{!} -@tab Enable extended mode. In extended mode, the remote server is made persistent. The @samp{R} packet is used to restart the program being debugged. -@item -@tab reply @samp{OK} -@tab + +Reply: +@table @samp +@item OK The remote target both supports and has enabled extended mode. +@end table -@item last signal -@tab @code{?} -@tab -Indicate the reason the target halted. The reply is the same as for step -and continue. -@item -@tab reply -@tab see below +@item @code{?} --- last signal +@cindex @code{?} packet +Indicate the reason the target halted. The reply is the same as for +step and continue. -@item reserved -@tab @code{a} -@tab Reserved for future use +Reply: +@xref{Stop Reply Packets}, for the reply specifications. + +@item @code{a} --- reserved + +Reserved for future use. + +@item @code{A}@var{arglen}@code{,}@var{argnum}@code{,}@var{arg}@code{,@dots{}} --- set program arguments @strong{(reserved)} +@cindex @code{A} packet -@item set program arguments @strong{(reserved)} -@tab @code{A}@var{arglen}@code{,}@var{argnum}@code{,}@var{arg}@code{,...} -@tab -@item -@tab -@tab Initialized @samp{argv[]} array passed into program. @var{arglen} specifies the number of bytes in the hex encoded byte stream @var{arg}. -See @file{gdbserver} for more details. -@item -@tab reply @code{OK} -@item -@tab reply @code{E}@var{NN} +See @code{gdbserver} for more details. -@item set baud @strong{(deprecated)} -@tab @code{b}@var{baud} -@tab -Change the serial line speed to @var{baud}. JTC: @emph{When does the -transport layer state change? When it's received, or after the ACK is -transmitted. In either case, there are problems if the command or the -acknowledgment packet is dropped.} Stan: @emph{If people really wanted -to add something like this, and get it working for the first time, they -ought to modify ser-unix.c to send some kind of out-of-band message to a -specially-setup stub and have the switch happen "in between" packets, so -that from remote protocol's point of view, nothing actually -happened.} +Reply: +@table @samp +@item OK +@item E@var{NN} +@end table + +@item @code{b}@var{baud} --- set baud @strong{(deprecated)} +@cindex @code{b} packet + +Change the serial line speed to @var{baud}. + +JTC: @emph{When does the transport layer state change? When it's +received, or after the ACK is transmitted. In either case, there are +problems if the command or the acknowledgment packet is dropped.} + +Stan: @emph{If people really wanted to add something like this, and get +it working for the first time, they ought to modify ser-unix.c to send +some kind of out-of-band message to a specially-setup stub and have the +switch happen "in between" packets, so that from remote protocol's point +of view, nothing actually happened.} + +@item @code{B}@var{addr},@var{mode} --- set breakpoint @strong{(deprecated)} +@cindex @code{B} packet -@item set breakpoint @strong{(deprecated)} -@tab @code{B}@var{addr},@var{mode} -@tab Set (@var{mode} is @samp{S}) or clear (@var{mode} is @samp{C}) a -breakpoint at @var{addr}. @emph{This has been replaced by the @samp{Z} and -@samp{z} packets.} +breakpoint at @var{addr}. -@item continue -@tab @code{c}@var{addr} -@tab -@var{addr} is address to resume. If @var{addr} is omitted, resume at +This packet has been replaced by the @samp{Z} and @samp{z} packets +(@pxref{insert breakpoint or watchpoint packet}). + +@item @code{c}@var{addr} --- continue +@cindex @code{c} packet + +@var{addr} is address to resume. If @var{addr} is omitted, resume at current address. -@item -@tab reply -@tab see below -@item continue with signal -@tab @code{C}@var{sig}@code{;}@var{addr} -@tab +Reply: +@xref{Stop Reply Packets}, for the reply specifications. + +@item @code{C}@var{sig}@code{;}@var{addr} --- continue with signal +@cindex @code{C} packet + Continue with signal @var{sig} (hex signal number). If @code{;}@var{addr} is omitted, resume at same address. -@item -@tab reply -@tab see below -@item toggle debug @strong{(deprecated)} -@tab @code{d} -@tab -toggle debug flag. +Reply: +@xref{Stop Reply Packets}, for the reply specifications. -@item detach -@tab @code{D} -@tab -Detach @value{GDBN} from the remote system. Sent to the remote target before -@value{GDBN} disconnects. -@item -@tab reply @emph{no response} -@tab +@item @code{d} --- toggle debug @strong{(deprecated)} +@cindex @code{d} packet + +Toggle debug flag. + +@item @code{D} --- detach +@cindex @code{D} packet + +Detach @value{GDBN} from the remote system. Sent to the remote target +before @value{GDBN} disconnects via the @code{detach} command. + +Reply: +@table @samp +@item @emph{no response} @value{GDBN} does not check for any response after sending this packet. +@end table -@item reserved -@tab @code{e} -@tab Reserved for future use +@item @code{e} --- reserved -@item reserved -@tab @code{E} -@tab Reserved for future use +Reserved for future use. -@item reserved -@tab @code{f} -@tab Reserved for future use +@item @code{E} --- reserved -@item reserved -@tab @code{F} -@tab Reserved for future use +Reserved for future use. -@item read registers -@tab @code{g} -@tab Read general registers. -@item -@tab reply @var{XX...} -@tab +@item @code{f} --- reserved + +Reserved for future use. + +@item @code{F}@var{RC}@code{,}@var{EE}@code{,}@var{CF}@code{;}@var{XX} --- Reply to target's F packet. +@cindex @code{F} packet + +This packet is send by @value{GDBN} as reply to a @code{F} request packet +sent by the target. This is part of the File-I/O protocol extension. +@xref{File-I/O remote protocol extension}, for the specification. + +@item @code{g} --- read registers +@anchor{read registers packet} +@cindex @code{g} packet + +Read general registers. + +Reply: +@table @samp +@item @var{XX@dots{}} Each byte of register data is described by two hex digits. The bytes with the register are transmitted in target byte order. The size of each register and their position within the @samp{g} @var{packet} are -determined by the @value{GDBN} internal macros @var{REGISTER_RAW_SIZE} and -@var{REGISTER_NAME} macros. The specification of several standard -@code{g} packets is specified below. -@item -@tab @code{E}@var{NN} -@tab for an error. +determined by the @value{GDBN} internal macros +@var{DEPRECATED_REGISTER_RAW_SIZE} and @var{REGISTER_NAME} macros. The +specification of several standard @code{g} packets is specified below. +@item E@var{NN} +for an error. +@end table -@item write regs -@tab @code{G}@var{XX...} -@tab -See @samp{g} for a description of the @var{XX...} data. -@item -@tab reply @code{OK} -@tab for success -@item -@tab reply @code{E}@var{NN} -@tab for an error +@item @code{G}@var{XX@dots{}} --- write regs +@cindex @code{G} packet -@item reserved -@tab @code{h} -@tab Reserved for future use +@xref{read registers packet}, for a description of the @var{XX@dots{}} +data. + +Reply: +@table @samp +@item OK +for success +@item E@var{NN} +for an error +@end table + +@item @code{h} --- reserved + +Reserved for future use. + +@item @code{H}@var{c}@var{t@dots{}} --- set thread +@cindex @code{H} packet -@item set thread -@tab @code{H}@var{c}@var{t...} -@tab Set thread for subsequent operations (@samp{m}, @samp{M}, @samp{g}, -@samp{G}, et.al.). @var{c} = @samp{c} for thread used in step and -continue; @var{t...} can be -1 for all threads. @var{c} = @samp{g} for -thread used in other operations. If zero, pick a thread, any thread. -@item -@tab reply @code{OK} -@tab for success -@item -@tab reply @code{E}@var{NN} -@tab for an error +@samp{G}, et.al.). @var{c} depends on the operation to be performed: it +should be @samp{c} for step and continue operations, @samp{g} for other +operations. The thread designator @var{t@dots{}} may be -1, meaning all +the threads, a thread number, or zero which means pick any thread. + +Reply: +@table @samp +@item OK +for success +@item E@var{NN} +for an error +@end table @c FIXME: JTC: @c 'H': How restrictive (or permissive) is the thread model. If a @@ -14368,262 +19807,427 @@ thread used in other operations. If zero, pick a thread, any thread. @c selected, sets the registers of the register block of @c that thread; otherwise sets current registers. -@item cycle step @strong{(draft)} -@tab @code{i}@var{addr}@code{,}@var{nnn} -@tab +@item @code{i}@var{addr}@code{,}@var{nnn} --- cycle step @strong{(draft)} +@anchor{cycle step packet} +@cindex @code{i} packet + Step the remote target by a single clock cycle. If @code{,}@var{nnn} is present, cycle step @var{nnn} cycles. If @var{addr} is present, cycle step starting at that address. -@item signal then cycle step @strong{(reserved)} -@tab @code{I} -@tab -See @samp{i} and @samp{S} for likely syntax and semantics. +@item @code{I} --- signal then cycle step @strong{(reserved)} +@cindex @code{I} packet -@item reserved -@tab @code{j} -@tab Reserved for future use +@xref{step with signal packet}. @xref{cycle step packet}. -@item reserved -@tab @code{J} -@tab Reserved for future use +@item @code{j} --- reserved + +Reserved for future use. + +@item @code{J} --- reserved + +Reserved for future use. + +@item @code{k} --- kill request +@cindex @code{k} packet -@item kill request -@tab @code{k} -@tab FIXME: @emph{There is no description of how to operate when a specific -thread context has been selected (i.e.@: does 'k' kill only that thread?)}. +thread context has been selected (i.e.@: does 'k' kill only that +thread?)}. -@item reserved -@tab @code{l} -@tab Reserved for future use +@item @code{K} --- reserved -@item reserved -@tab @code{L} -@tab Reserved for future use +Reserved for future use. + +@item @code{l} --- reserved + +Reserved for future use. + +@item @code{L} --- reserved + +Reserved for future use. + +@item @code{m}@var{addr}@code{,}@var{length} --- read memory +@cindex @code{m} packet -@item read memory -@tab @code{m}@var{addr}@code{,}@var{length} -@tab Read @var{length} bytes of memory starting at address @var{addr}. -Neither @value{GDBN} nor the stub assume that sized memory transfers are assumed -using word alligned accesses. FIXME: @emph{A word aligned memory +Neither @value{GDBN} nor the stub assume that sized memory transfers are +assumed using word aligned accesses. FIXME: @emph{A word aligned memory transfer mechanism is needed.} -@item -@tab reply @var{XX...} -@tab -@var{XX...} is mem contents. Can be fewer bytes than requested if able -to read only part of the data. Neither @value{GDBN} nor the stub assume that -sized memory transfers are assumed using word alligned accesses. FIXME: -@emph{A word aligned memory transfer mechanism is needed.} -@item -@tab reply @code{E}@var{NN} -@tab @var{NN} is errno -@item write mem -@tab @code{M}@var{addr},@var{length}@code{:}@var{XX...} -@tab +Reply: +@table @samp +@item @var{XX@dots{}} +@var{XX@dots{}} is mem contents. Can be fewer bytes than requested if able +to read only part of the data. Neither @value{GDBN} nor the stub assume +that sized memory transfers are assumed using word aligned +accesses. FIXME: @emph{A word aligned memory transfer mechanism is +needed.} +@item E@var{NN} +@var{NN} is errno +@end table + +@item @code{M}@var{addr},@var{length}@code{:}@var{XX@dots{}} --- write mem +@cindex @code{M} packet + Write @var{length} bytes of memory starting at address @var{addr}. -@var{XX...} is the data. -@item -@tab reply @code{OK} -@tab for success -@item -@tab reply @code{E}@var{NN} -@tab +@var{XX@dots{}} is the data. + +Reply: +@table @samp +@item OK +for success +@item E@var{NN} for an error (this includes the case where only part of the data was written). +@end table -@item reserved -@tab @code{n} -@tab Reserved for future use +@item @code{n} --- reserved -@item reserved -@tab @code{N} -@tab Reserved for future use +Reserved for future use. -@item reserved -@tab @code{o} -@tab Reserved for future use +@item @code{N} --- reserved -@item reserved -@tab @code{O} -@tab Reserved for future use +Reserved for future use. -@item read reg @strong{(reserved)} -@tab @code{p}@var{n...} -@tab -See write register. -@item -@tab return @var{r....} -@tab The hex encoded value of the register in target byte order. +@item @code{o} --- reserved -@item write reg -@tab @code{P}@var{n...}@code{=}@var{r...} -@tab -Write register @var{n...} with value @var{r...}, which contains two hex +Reserved for future use. + +@item @code{O} --- reserved + +Reserved for future use. + +@item @code{p}@var{n@dots{}} --- read reg @strong{(reserved)} +@cindex @code{p} packet + +@xref{write register packet}. + +Reply: +@table @samp +@item @var{r@dots{}.} +The hex encoded value of the register in target byte order. +@end table + +@item @code{P}@var{n@dots{}}@code{=}@var{r@dots{}} --- write register +@anchor{write register packet} +@cindex @code{P} packet + +Write register @var{n@dots{}} with value @var{r@dots{}}, which contains two hex digits for each byte in the register (target byte order). -@item -@tab reply @code{OK} -@tab for success -@item -@tab reply @code{E}@var{NN} -@tab for an error -@item general query -@tab @code{q}@var{query} -@tab -Request info about @var{query}. In general @value{GDBN} queries -have a leading upper case letter. Custom vendor queries should use a -company prefix (in lower case) ex: @samp{qfsf.var}. @var{query} may -optionally be followed by a @samp{,} or @samp{;} separated list. Stubs -must ensure that they match the full @var{query} name. -@item -@tab reply @code{XX...} -@tab Hex encoded data from query. The reply can not be empty. -@item -@tab reply @code{E}@var{NN} -@tab error reply -@item -@tab reply @samp{} -@tab Indicating an unrecognized @var{query}. +Reply: +@table @samp +@item OK +for success +@item E@var{NN} +for an error +@end table -@item general set -@tab @code{Q}@var{var}@code{=}@var{val} -@tab -Set value of @var{var} to @var{val}. See @samp{q} for a discussing of -naming conventions. +@item @code{q}@var{query} --- general query +@anchor{general query packet} +@cindex @code{q} packet + +Request info about @var{query}. In general @value{GDBN} queries have a +leading upper case letter. Custom vendor queries should use a company +prefix (in lower case) ex: @samp{qfsf.var}. @var{query} may optionally +be followed by a @samp{,} or @samp{;} separated list. Stubs must ensure +that they match the full @var{query} name. + +Reply: +@table @samp +@item @var{XX@dots{}} +Hex encoded data from query. The reply can not be empty. +@item E@var{NN} +error reply +@item +Indicating an unrecognized @var{query}. +@end table + +@item @code{Q}@var{var}@code{=}@var{val} --- general set +@cindex @code{Q} packet + +Set value of @var{var} to @var{val}. + +@xref{general query packet}, for a discussion of naming conventions. + +@item @code{r} --- reset @strong{(deprecated)} +@cindex @code{r} packet -@item reset @strong{(deprecated)} -@tab @code{r} -@tab Reset the entire system. -@item remote restart -@tab @code{R}@var{XX} -@tab +@item @code{R}@var{XX} --- remote restart +@cindex @code{R} packet + Restart the program being debugged. @var{XX}, while needed, is ignored. This packet is only available in extended mode. -@item -@tab -no reply -@tab -The @samp{R} packet has no reply. -@item step -@tab @code{s}@var{addr} -@tab +Reply: +@table @samp +@item @emph{no reply} +The @samp{R} packet has no reply. +@end table + +@item @code{s}@var{addr} --- step +@cindex @code{s} packet + @var{addr} is address to resume. If @var{addr} is omitted, resume at same address. -@item -@tab reply -@tab see below -@item step with signal -@tab @code{S}@var{sig}@code{;}@var{addr} -@tab +Reply: +@xref{Stop Reply Packets}, for the reply specifications. + +@item @code{S}@var{sig}@code{;}@var{addr} --- step with signal +@anchor{step with signal packet} +@cindex @code{S} packet + Like @samp{C} but step not continue. -@item -@tab reply -@tab see below -@item search -@tab @code{t}@var{addr}@code{:}@var{PP}@code{,}@var{MM} -@tab +Reply: +@xref{Stop Reply Packets}, for the reply specifications. + +@item @code{t}@var{addr}@code{:}@var{PP}@code{,}@var{MM} --- search +@cindex @code{t} packet + Search backwards starting at address @var{addr} for a match with pattern -@var{PP} and mask @var{MM}. @var{PP} and @var{MM} are 4 -bytes. @var{addr} must be at least 3 digits. +@var{PP} and mask @var{MM}. @var{PP} and @var{MM} are 4 bytes. +@var{addr} must be at least 3 digits. -@item thread alive -@tab @code{T}@var{XX} -@tab Find out if the thread XX is alive. +@item @code{T}@var{XX} --- thread alive +@cindex @code{T} packet + +Find out if the thread XX is alive. + +Reply: +@table @samp +@item OK +thread is still alive +@item E@var{NN} +thread is dead +@end table + +@item @code{u} --- reserved + +Reserved for future use. + +@item @code{U} --- reserved + +Reserved for future use. + +@item @code{v} --- verbose packet prefix + +Packets starting with @code{v} are identified by a multi-letter name, +up to the first @code{;} or @code{?} (or the end of the packet). + +@item @code{vCont}[;@var{action}[@code{:}@var{tid}]]... --- extended resume +@cindex @code{vCont} packet + +Resume the inferior. Different actions may be specified for each thread. +If an action is specified with no @var{tid}, then it is applied to any +threads that don't have a specific action specified; if no default action is +specified then other threads should remain stopped. Specifying multiple +default actions is an error; specifying no actions is also an error. +Thread IDs are specified in hexadecimal. Currently supported actions are: + +@table @code +@item c +Continue. +@item C@var{sig} +Continue with signal @var{sig}. @var{sig} should be two hex digits. +@item s +Step. +@item S@var{sig} +Step with signal @var{sig}. @var{sig} should be two hex digits. +@end table + +The optional @var{addr} argument normally associated with these packets is +not supported in @code{vCont}. + +Reply: +@xref{Stop Reply Packets}, for the reply specifications. + +@item @code{vCont?} --- extended resume query +@cindex @code{vCont?} packet + +Query support for the @code{vCont} packet. + +Reply: +@table @samp +@item @code{vCont}[;@var{action}]... +The @code{vCont} packet is supported. Each @var{action} is a supported +command in the @code{vCont} packet. @item -@tab reply @code{OK} -@tab thread is still alive -@item -@tab reply @code{E}@var{NN} -@tab thread is dead +The @code{vCont} packet is not supported. +@end table -@item reserved -@tab @code{u} -@tab Reserved for future use +@item @code{V} --- reserved -@item reserved -@tab @code{U} -@tab Reserved for future use +Reserved for future use. -@item reserved -@tab @code{v} -@tab Reserved for future use +@item @code{w} --- reserved -@item reserved -@tab @code{V} -@tab Reserved for future use +Reserved for future use. -@item reserved -@tab @code{w} -@tab Reserved for future use +@item @code{W} --- reserved -@item reserved -@tab @code{W} -@tab Reserved for future use +Reserved for future use. -@item reserved -@tab @code{x} -@tab Reserved for future use +@item @code{x} --- reserved -@item write mem (binary) -@tab @code{X}@var{addr}@code{,}@var{length}@var{:}@var{XX...} -@tab -@var{addr} is address, @var{length} is number of bytes, @var{XX...} is -binary data. The characters @code{$}, @code{#}, and @code{0x7d} are +Reserved for future use. + +@item @code{X}@var{addr}@code{,}@var{length}@var{:}@var{XX@dots{}} --- write mem (binary) +@cindex @code{X} packet + +@var{addr} is address, @var{length} is number of bytes, @var{XX@dots{}} +is binary data. The characters @code{$}, @code{#}, and @code{0x7d} are escaped using @code{0x7d}. + +Reply: +@table @samp +@item OK +for success +@item E@var{NN} +for an error +@end table + +@item @code{y} --- reserved + +Reserved for future use. + +@item @code{Y} reserved + +Reserved for future use. + +@item @code{z}@var{type}@code{,}@var{addr}@code{,}@var{length} --- remove breakpoint or watchpoint @strong{(draft)} +@itemx @code{Z}@var{type}@code{,}@var{addr}@code{,}@var{length} --- insert breakpoint or watchpoint @strong{(draft)} +@anchor{insert breakpoint or watchpoint packet} +@cindex @code{z} packet +@cindex @code{Z} packets + +Insert (@code{Z}) or remove (@code{z}) a @var{type} breakpoint or +watchpoint starting at address @var{address} and covering the next +@var{length} bytes. + +Each breakpoint and watchpoint packet @var{type} is documented +separately. + +@emph{Implementation notes: A remote target shall return an empty string +for an unrecognized breakpoint or watchpoint packet @var{type}. A +remote target shall support either both or neither of a given +@code{Z}@var{type}@dots{} and @code{z}@var{type}@dots{} packet pair. To +avoid potential problems with duplicate packets, the operations should +be implemented in an idempotent way.} + +@item @code{z}@code{0}@code{,}@var{addr}@code{,}@var{length} --- remove memory breakpoint @strong{(draft)} +@item @code{Z}@code{0}@code{,}@var{addr}@code{,}@var{length} --- insert memory breakpoint @strong{(draft)} +@cindex @code{z0} packet +@cindex @code{Z0} packet + +Insert (@code{Z0}) or remove (@code{z0}) a memory breakpoint at address +@code{addr} of size @code{length}. + +A memory breakpoint is implemented by replacing the instruction at +@var{addr} with a software breakpoint or trap instruction. The +@code{length} is used by targets that indicates the size of the +breakpoint (in bytes) that should be inserted (e.g., the @sc{arm} and +@sc{mips} can insert either a 2 or 4 byte breakpoint). + +@emph{Implementation note: It is possible for a target to copy or move +code that contains memory breakpoints (e.g., when implementing +overlays). The behavior of this packet, in the presence of such a +target, is not defined.} + +Reply: +@table @samp +@item OK +success @item -@tab reply @code{OK} -@tab for success +not supported +@item E@var{NN} +for an error +@end table + +@item @code{z}@code{1}@code{,}@var{addr}@code{,}@var{length} --- remove hardware breakpoint @strong{(draft)} +@item @code{Z}@code{1}@code{,}@var{addr}@code{,}@var{length} --- insert hardware breakpoint @strong{(draft)} +@cindex @code{z1} packet +@cindex @code{Z1} packet + +Insert (@code{Z1}) or remove (@code{z1}) a hardware breakpoint at +address @code{addr} of size @code{length}. + +A hardware breakpoint is implemented using a mechanism that is not +dependant on being able to modify the target's memory. + +@emph{Implementation note: A hardware breakpoint is not affected by code +movement.} + +Reply: +@table @samp +@item OK +success @item -@tab reply @code{E}@var{NN} -@tab for an error +not supported +@item E@var{NN} +for an error +@end table -@item reserved -@tab @code{y} -@tab Reserved for future use +@item @code{z}@code{2}@code{,}@var{addr}@code{,}@var{length} --- remove write watchpoint @strong{(draft)} +@item @code{Z}@code{2}@code{,}@var{addr}@code{,}@var{length} --- insert write watchpoint @strong{(draft)} +@cindex @code{z2} packet +@cindex @code{Z2} packet -@item reserved -@tab @code{Y} -@tab Reserved for future use +Insert (@code{Z2}) or remove (@code{z2}) a write watchpoint. -@item remove break or watchpoint @strong{(draft)} -@tab @code{z}@var{t}@code{,}@var{addr}@code{,}@var{length} -@tab -See @samp{Z}. - -@item insert break or watchpoint @strong{(draft)} -@tab @code{Z}@var{t}@code{,}@var{addr}@code{,}@var{length} -@tab -@var{t} is type: @samp{0} - software breakpoint, @samp{1} - hardware -breakpoint, @samp{2} - write watchpoint, @samp{3} - read watchpoint, -@samp{4} - access watchpoint; @var{addr} is address; @var{length} is in -bytes. For a software breakpoint, @var{length} specifies the size of -the instruction to be patched. For hardware breakpoints and watchpoints -@var{length} specifies the memory region to be monitored. To avoid -potential problems with duplicate packets, the operations should be -implemented in an idempotent way. +Reply: +@table @samp +@item OK +success @item -@tab reply @code{E}@var{NN} -@tab for an error -@item -@tab reply @code{OK} -@tab for success -@item -@tab @samp{} -@tab If not supported. +not supported +@item E@var{NN} +for an error +@end table -@item reserved -@tab -@tab Reserved for future use +@item @code{z}@code{3}@code{,}@var{addr}@code{,}@var{length} --- remove read watchpoint @strong{(draft)} +@item @code{Z}@code{3}@code{,}@var{addr}@code{,}@var{length} --- insert read watchpoint @strong{(draft)} +@cindex @code{z3} packet +@cindex @code{Z3} packet -@end multitable +Insert (@code{Z3}) or remove (@code{z3}) a read watchpoint. + +Reply: +@table @samp +@item OK +success +@item +not supported +@item E@var{NN} +for an error +@end table + +@item @code{z}@code{4}@code{,}@var{addr}@code{,}@var{length} --- remove access watchpoint @strong{(draft)} +@item @code{Z}@code{4}@code{,}@var{addr}@code{,}@var{length} --- insert access watchpoint @strong{(draft)} +@cindex @code{z4} packet +@cindex @code{Z4} packet + +Insert (@code{Z4}) or remove (@code{z4}) an access watchpoint. + +Reply: +@table @samp +@item OK +success +@item +not supported +@item E@var{NN} +for an error +@end table + +@end table + +@node Stop Reply Packets +@section Stop Reply Packets +@cindex stop reply packets The @samp{C}, @samp{c}, @samp{S}, @samp{s} and @samp{?} packets can receive any of the below as a reply. In the case of the @samp{C}, @@ -14632,315 +20236,1525 @@ when the target halts. In the below the exact meaning of @samp{signal number} is poorly defined. In general one of the UNIX signal numbering conventions is used. -@multitable @columnfractions .4 .6 +@table @samp -@item @code{S}@var{AA} -@tab @var{AA} is the signal number +@item S@var{AA} +@var{AA} is the signal number @item @code{T}@var{AA}@var{n...}@code{:}@var{r...}@code{;}@var{n...}@code{:}@var{r...}@code{;}@var{n...}@code{:}@var{r...}@code{;} -@tab +@cindex @code{T} packet reply + @var{AA} = two hex digit signal number; @var{n...} = register number (hex), @var{r...} = target byte ordered register contents, size defined -by @code{REGISTER_RAW_SIZE}; @var{n...} = @samp{thread}, @var{r...} = -thread process ID, this is a hex integer; @var{n...} = other string not -starting with valid hex digit. @value{GDBN} should ignore this -@var{n...}, @var{r...} pair and go on to the next. This way we can -extend the protocol. +by @code{DEPRECATED_REGISTER_RAW_SIZE}; @var{n...} = @samp{thread}, +@var{r...} = thread process ID, this is a hex integer; @var{n...} = +(@samp{watch} | @samp{rwatch} | @samp{awatch}, @var{r...} = data +address, this is a hex integer; @var{n...} = other string not starting +with valid hex digit. @value{GDBN} should ignore this @var{n...}, +@var{r...} pair and go on to the next. This way we can extend the +protocol. + +@item W@var{AA} -@item @code{W}@var{AA} -@tab The process exited, and @var{AA} is the exit status. This is only -applicable for certains sorts of targets. +applicable to certain targets. + +@item X@var{AA} -@item @code{X}@var{AA} -@tab The process terminated with signal @var{AA}. -@item @code{N}@var{AA}@code{;}@var{t...}@code{;}@var{d...}@code{;}@var{b...} @strong{(obsolete)} -@tab -@var{AA} = signal number; @var{t...} = address of symbol "_start"; -@var{d...} = base of data section; @var{b...} = base of bss section. -@emph{Note: only used by Cisco Systems targets. The difference between -this reply and the "qOffsets" query is that the 'N' packet may arrive -spontaneously whereas the 'qOffsets' is a query initiated by the host -debugger.} +@item O@var{XX@dots{}} -@item @code{O}@var{XX...} -@tab -@var{XX...} is hex encoding of @sc{ascii} data. This can happen at any time -while the program is running and the debugger should continue to wait -for 'W', 'T', etc. +@var{XX@dots{}} is hex encoding of @sc{ascii} data. This can happen at +any time while the program is running and the debugger should continue +to wait for @samp{W}, @samp{T}, etc. -@end multitable +@item F@var{call-id}@code{,}@var{parameter@dots{}} + +@var{call-id} is the identifier which says which host system call should +be called. This is just the name of the function. Translation into the +correct system call is only applicable as it's defined in @value{GDBN}. +@xref{File-I/O remote protocol extension}, for a list of implemented +system calls. + +@var{parameter@dots{}} is a list of parameters as defined for this very +system call. + +The target replies with this packet when it expects @value{GDBN} to call +a host system call on behalf of the target. @value{GDBN} replies with +an appropriate @code{F} packet and keeps up waiting for the next reply +packet from the target. The latest @samp{C}, @samp{c}, @samp{S} or +@samp{s} action is expected to be continued. +@xref{File-I/O remote protocol extension}, for more details. + +@end table + +@node General Query Packets +@section General Query Packets The following set and query packets have already been defined. -@multitable @columnfractions .2 .2 .6 +@table @r -@item current thread -@tab @code{q}@code{C} -@tab Return the current thread id. -@item -@tab reply @code{QC}@var{pid} -@tab +@item @code{q}@code{C} --- current thread + +Return the current thread id. + +Reply: +@table @samp +@item @code{QC}@var{pid} Where @var{pid} is a HEX encoded 16 bit process id. -@item -@tab reply * -@tab Any other reply implies the old pid. +@item * +Any other reply implies the old pid. +@end table + +@item @code{q}@code{fThreadInfo} -- all thread ids + +@code{q}@code{sThreadInfo} -@item all thread ids -@tab @code{q}@code{fThreadInfo} -@item -@tab @code{q}@code{sThreadInfo} -@tab Obtain a list of active thread ids from the target (OS). Since there may be too many active threads to fit into one reply packet, this query works iteratively: it may require more than one query/reply sequence to obtain the entire list of threads. The first query of the sequence will be the @code{qf}@code{ThreadInfo} query; subsequent queries in the sequence will be the @code{qs}@code{ThreadInfo} query. -@item -@tab -@tab NOTE: replaces the @code{qL} query (see below). -@item -@tab reply @code{m}@var{} -@tab A single thread id -@item -@tab reply @code{m}@var{},@var{...} -@tab a comma-separated list of thread ids -@item -@tab reply @code{l} -@tab (lower case 'el') denotes end of list. -@item -@tab -@tab -In response to each query, the target will reply with a list of one -or more thread ids, in big-endian hex, separated by commas. GDB will -respond to each reply with a request for more thread ids (using the + +NOTE: replaces the @code{qL} query (see below). + +Reply: +@table @samp +@item @code{m}@var{id} +A single thread id +@item @code{m}@var{id},@var{id}@dots{} +a comma-separated list of thread ids +@item @code{l} +(lower case 'el') denotes end of list. +@end table + +In response to each query, the target will reply with a list of one or +more thread ids, in big-endian hex, separated by commas. @value{GDBN} +will respond to each reply with a request for more thread ids (using the @code{qs} form of the query), until the target responds with @code{l} (lower-case el, for @code{'last'}). -@item extra thread info -@tab @code{q}@code{ThreadExtraInfo}@code{,}@var{id} -@tab -@item -@tab -@tab -Where @var{} is a thread-id in big-endian hex. -Obtain a printable string description of a thread's attributes from -the target OS. This string may contain anything that the target OS -thinks is interesting for @value{GDBN} to tell the user about the thread. -The string is displayed in @value{GDBN}'s @samp{info threads} display. -Some examples of possible thread extra info strings are "Runnable", or -"Blocked on Mutex". -@item -@tab reply @var{XX...} -@tab -Where @var{XX...} is a hex encoding of @sc{ascii} data, comprising the -printable string containing the extra information about the thread's -attributes. +@item @code{q}@code{ThreadExtraInfo}@code{,}@var{id} --- extra thread info + +Where @var{id} is a thread-id in big-endian hex. Obtain a printable +string description of a thread's attributes from the target OS. This +string may contain anything that the target OS thinks is interesting for +@value{GDBN} to tell the user about the thread. The string is displayed +in @value{GDBN}'s @samp{info threads} display. Some examples of +possible thread extra info strings are ``Runnable'', or ``Blocked on +Mutex''. + +Reply: +@table @samp +@item @var{XX@dots{}} +Where @var{XX@dots{}} is a hex encoding of @sc{ascii} data, comprising +the printable string containing the extra information about the thread's +attributes. +@end table + +@item @code{q}@code{L}@var{startflag}@var{threadcount}@var{nextthread} --- query @var{LIST} or @var{threadLIST} @strong{(deprecated)} -@item query @var{LIST} or @var{threadLIST} @strong{(deprecated)} -@tab @code{q}@code{L}@var{startflag}@var{threadcount}@var{nextthread} -@tab -@item -@tab -@tab Obtain thread information from RTOS. Where: @var{startflag} (one hex digit) is one to indicate the first query and zero to indicate a subsequent query; @var{threadcount} (two hex digits) is the maximum number of threads the response packet can contain; and @var{nextthread} (eight hex digits), for subsequent queries (@var{startflag} is zero), is returned in the response as @var{argthread}. -@item -@tab -@tab NOTE: this query is replaced by the @code{q}@code{fThreadInfo} -query (see above). -@item -@tab reply @code{q}@code{M}@var{count}@var{done}@var{argthread}@var{thread...} -@tab -@item -@tab -@tab + +NOTE: this query is replaced by the @code{q}@code{fThreadInfo} query +(see above). + +Reply: +@table @samp +@item @code{q}@code{M}@var{count}@var{done}@var{argthread}@var{thread@dots{}} Where: @var{count} (two hex digits) is the number of threads being returned; @var{done} (one hex digit) is zero to indicate more threads and one indicates no further threads; @var{argthreadid} (eight hex -digits) is @var{nextthread} from the request packet; @var{thread...} is -a sequence of thread IDs from the target. @var{threadid} (eight hex +digits) is @var{nextthread} from the request packet; @var{thread@dots{}} +is a sequence of thread IDs from the target. @var{threadid} (eight hex digits). See @code{remote.c:parse_threadlist_response()}. +@end table -@item compute CRC of memory block -@tab @code{q}@code{CRC:}@var{addr}@code{,}@var{length} -@tab -@item -@tab reply @code{E}@var{NN} -@tab An error (such as memory fault) -@item -@tab reply @code{C}@var{CRC32} -@tab A 32 bit cyclic redundancy check of the specified memory region. +@item @code{q}@code{CRC:}@var{addr}@code{,}@var{length} --- compute CRC of memory block + +Reply: +@table @samp +@item @code{E}@var{NN} +An error (such as memory fault) +@item @code{C}@var{CRC32} +A 32 bit cyclic redundancy check of the specified memory region. +@end table + +@item @code{q}@code{Offsets} --- query sect offs -@item query sect offs -@tab @code{q}@code{Offsets} -@tab Get section offsets that the target used when re-locating the downloaded image. @emph{Note: while a @code{Bss} offset is included in the response, @value{GDBN} ignores this and instead applies the @code{Data} offset to the @code{Bss} section.} -@item -@tab reply @code{Text=}@var{xxx}@code{;Data=}@var{yyy}@code{;Bss=}@var{zzz} -@item thread info request -@tab @code{q}@code{P}@var{mode}@var{threadid} -@tab -@item -@tab -@tab +Reply: +@table @samp +@item @code{Text=}@var{xxx}@code{;Data=}@var{yyy}@code{;Bss=}@var{zzz} +@end table + +@item @code{q}@code{P}@var{mode}@var{threadid} --- thread info request + Returns information on @var{threadid}. Where: @var{mode} is a hex encoded 32 bit mode; @var{threadid} is a hex encoded 64 bit thread ID. -@item -@tab reply * -@tab + +Reply: +@table @samp +@item * +@end table + See @code{remote.c:remote_unpack_thread_info_response()}. -@item remote command -@tab @code{q}@code{Rcmd,}@var{COMMAND} -@tab -@item -@tab -@tab -@var{COMMAND} (hex encoded) is passed to the local interpreter for +@item @code{q}@code{Rcmd,}@var{command} --- remote command + +@var{command} (hex encoded) is passed to the local interpreter for execution. Invalid commands should be reported using the output string. Before the final result packet, the target may also respond with a -number of intermediate @code{O}@var{OUTPUT} console output -packets. @emph{Implementors should note that providing access to a -stubs's interpreter may have security implications}. -@item -@tab reply @code{OK} -@tab +number of intermediate @code{O}@var{output} console output packets. +@emph{Implementors should note that providing access to a stubs's +interpreter may have security implications}. + +Reply: +@table @samp +@item OK A command response with no output. -@item -@tab reply @var{OUTPUT} -@tab +@item @var{OUTPUT} A command response with the hex encoded output string @var{OUTPUT}. -@item -@tab reply @code{E}@var{NN} -@tab +@item @code{E}@var{NN} Indicate a badly formed request. - -@item -@tab reply @samp{} -@tab +@item @samp{} When @samp{q}@samp{Rcmd} is not recognized. +@end table + +@item @code{qSymbol::} --- symbol lookup -@item symbol lookup -@tab @code{qSymbol::} -@tab Notify the target that @value{GDBN} is prepared to serve symbol lookup requests. Accept requests from the target for the values of symbols. -@item -@tab -@tab -@item -@tab reply @code{OK} -@tab -The target does not need to look up any (more) symbols. -@item -@tab reply @code{qSymbol:}@var{sym_name} -@tab -@sp 2 -@noindent -The target requests the value of symbol @var{sym_name} (hex encoded). -@value{GDBN} may provide the value by using the -@code{qSymbol:}@var{sym_value}:@var{sym_name} -message, described below. -@item symbol value -@tab @code{qSymbol:}@var{sym_value}:@var{sym_name} -@tab -@sp 1 -@noindent -Set the value of SYM_NAME to SYM_VALUE. -@item -@tab -@tab -@var{sym_name} (hex encoded) is the name of a symbol whose value -the target has previously requested. -@item -@tab -@tab -@var{sym_value} (hex) is the value for symbol @var{sym_name}. -If @value{GDBN} cannot supply a value for @var{sym_name}, then this -field will be empty. -@item -@tab reply @code{OK} -@tab +Reply: +@table @samp +@item @code{OK} The target does not need to look up any (more) symbols. -@item -@tab reply @code{qSymbol:}@var{sym_name} -@tab -@sp 2 -@noindent -The target requests the value of a new symbol @var{sym_name} (hex encoded). -@value{GDBN} will continue to supply the values of symbols (if available), -until the target ceases to request them. +@item @code{qSymbol:}@var{sym_name} +The target requests the value of symbol @var{sym_name} (hex encoded). +@value{GDBN} may provide the value by using the +@code{qSymbol:}@var{sym_value}:@var{sym_name} message, described below. +@end table -@end multitable +@item @code{qSymbol:}@var{sym_value}:@var{sym_name} --- symbol value + +Set the value of @var{sym_name} to @var{sym_value}. + +@var{sym_name} (hex encoded) is the name of a symbol whose value the +target has previously requested. + +@var{sym_value} (hex) is the value for symbol @var{sym_name}. If +@value{GDBN} cannot supply a value for @var{sym_name}, then this field +will be empty. + +Reply: +@table @samp +@item @code{OK} +The target does not need to look up any (more) symbols. +@item @code{qSymbol:}@var{sym_name} +The target requests the value of a new symbol @var{sym_name} (hex +encoded). @value{GDBN} will continue to supply the values of symbols +(if available), until the target ceases to request them. +@end table + +@item @code{qPart}:@var{object}:@code{read}:@var{annex}:@var{offset},@var{length} --- read special data + +Read uninterpreted bytes from the target's special data area +identified by the keyword @code{object}. +Request @var{length} bytes starting at @var{offset} bytes into the data. +The content and encoding of @var{annex} is specific to the object; +it can supply additional details about what data to access. + +Here are the specific requests of this form defined so far. +All @samp{@code{qPart}:@var{object}:@code{read}:@dots{}} +requests use the same reply formats, listed below. + +@table @asis +@item @code{qPart}:@code{auxv}:@code{read}::@var{offset},@var{length} +Access the target's @dfn{auxiliary vector}. @xref{Auxiliary Vector}. +Note @var{annex} must be empty. +@end table + +Reply: +@table @asis +@item @code{OK} +The @var{offset} in the request is at the end of the data. +There is no more data to be read. + +@item @var{XX@dots{}} +Hex encoded data bytes read. +This may be fewer bytes than the @var{length} in the request. + +@item @code{E00} +The request was malformed, or @var{annex} was invalid. + +@item @code{E}@var{nn} +The offset was invalid, or there was an error encountered reading the data. +@var{nn} is a hex-encoded @code{errno} value. + +@item @code{""} (empty) +An empty reply indicates the @var{object} or @var{annex} string was not +recognized by the stub. +@end table + +@item @code{qPart}:@var{object}:@code{write}:@var{annex}:@var{offset}:@var{data@dots{}} + +Write uninterpreted bytes into the target's special data area +identified by the keyword @code{object}, +starting at @var{offset} bytes into the data. +@var{data@dots{}} is the hex-encoded data to be written. +The content and encoding of @var{annex} is specific to the object; +it can supply additional details about what data to access. + +No requests of this form are presently in use. This specification +serves as a placeholder to document the common format that new +specific request specifications ought to use. + +Reply: +@table @asis +@item @var{nn} +@var{nn} (hex encoded) is the number of bytes written. +This may be fewer bytes than supplied in the request. + +@item @code{E00} +The request was malformed, or @var{annex} was invalid. + +@item @code{E}@var{nn} +The offset was invalid, or there was an error encountered writing the data. +@var{nn} is a hex-encoded @code{errno} value. + +@item @code{""} (empty) +An empty reply indicates the @var{object} or @var{annex} string was not +recognized by the stub, or that the object does not support writing. +@end table + +@item @code{qPart}:@var{object}:@var{operation}:@dots{} +Requests of this form may be added in the future. When a stub does +not recognize the @var{object} keyword, or its support for +@var{object} does not recognize the @var{operation} keyword, +the stub must respond with an empty packet. +@end table + +@node Register Packet Format +@section Register Packet Format The following @samp{g}/@samp{G} packets have previously been defined. -In the below, some thirty-two bit registers are transferred as sixty-four -bits. Those registers should be zero/sign extended (which?) to fill the -space allocated. Register bytes are transfered in target byte order. -The two nibbles within a register byte are transfered most-significant - -least-significant. +In the below, some thirty-two bit registers are transferred as +sixty-four bits. Those registers should be zero/sign extended (which?) +to fill the space allocated. Register bytes are transfered in target +byte order. The two nibbles within a register byte are transfered +most-significant - least-significant. -@multitable @columnfractions .5 .5 +@table @r @item MIPS32 -@tab + All registers are transfered as thirty-two bit quantities in the order: 32 general-purpose; sr; lo; hi; bad; cause; pc; 32 floating-point registers; fsr; fir; fp. @item MIPS64 -@tab + All registers are transfered as sixty-four bit quantities (including thirty-two bit registers such as @code{sr}). The ordering is the same as @code{MIPS32}. -@end multitable +@end table + +@node Examples +@section Examples Example sequence of a target being re-started. Notice how the restart does not get any direct output: -@example -<- @code{R00} --> @code{+} -@emph{target restarts} -<- @code{?} --> @code{+} --> @code{T001:1234123412341234} +@smallexample +-> @code{R00} <- @code{+} -@end example +@emph{target restarts} +-> @code{?} +<- @code{+} +<- @code{T001:1234123412341234} +-> @code{+} +@end smallexample Example sequence of a target being stepped by a single instruction: -@example -<- @code{G1445...} --> @code{+} -<- @code{s} --> @code{+} +@smallexample +-> @code{G1445@dots{}} +<- @code{+} +-> @code{s} +<- @code{+} @emph{time passes} --> @code{T001:1234123412341234} -<- @code{+} -<- @code{g} +<- @code{T001:1234123412341234} -> @code{+} --> @code{1455...} +-> @code{g} <- @code{+} -@end example +<- @code{1455@dots{}} +-> @code{+} +@end smallexample + +@node File-I/O remote protocol extension +@section File-I/O remote protocol extension +@cindex File-I/O remote protocol extension + +@menu +* File-I/O Overview:: +* Protocol basics:: +* The F request packet:: +* The F reply packet:: +* Memory transfer:: +* The Ctrl-C message:: +* Console I/O:: +* The isatty call:: +* The system call:: +* List of supported calls:: +* Protocol specific representation of datatypes:: +* Constants:: +* File-I/O Examples:: +@end menu + +@node File-I/O Overview +@subsection File-I/O Overview +@cindex file-i/o overview + +The File I/O remote protocol extension (short: File-I/O) allows the +target to use the hosts file system and console I/O when calling various +system calls. System calls on the target system are translated into a +remote protocol packet to the host system which then performs the needed +actions and returns with an adequate response packet to the target system. +This simulates file system operations even on targets that lack file systems. + +The protocol is defined host- and target-system independent. It uses +it's own independent representation of datatypes and values. Both, +@value{GDBN} and the target's @value{GDBN} stub are responsible for +translating the system dependent values into the unified protocol values +when data is transmitted. + +The communication is synchronous. A system call is possible only +when GDB is waiting for the @samp{C}, @samp{c}, @samp{S} or @samp{s} +packets. While @value{GDBN} handles the request for a system call, +the target is stopped to allow deterministic access to the target's +memory. Therefore File-I/O is not interuptible by target signals. It +is possible to interrupt File-I/O by a user interrupt (Ctrl-C), though. + +The target's request to perform a host system call does not finish +the latest @samp{C}, @samp{c}, @samp{S} or @samp{s} action. That means, +after finishing the system call, the target returns to continuing the +previous activity (continue, step). No additional continue or step +request from @value{GDBN} is required. + +@smallexample +(gdb) continue + <- target requests 'system call X' + target is stopped, @value{GDBN} executes system call + -> GDB returns result + ... target continues, GDB returns to wait for the target + <- target hits breakpoint and sends a Txx packet +@end smallexample + +The protocol is only used for files on the host file system and +for I/O on the console. Character or block special devices, pipes, +named pipes or sockets or any other communication method on the host +system are not supported by this protocol. + +@node Protocol basics +@subsection Protocol basics +@cindex protocol basics, file-i/o + +The File-I/O protocol uses the @code{F} packet, as request as well +as as reply packet. Since a File-I/O system call can only occur when +@value{GDBN} is waiting for the continuing or stepping target, the +File-I/O request is a reply that @value{GDBN} has to expect as a result +of a former @samp{C}, @samp{c}, @samp{S} or @samp{s} packet. +This @code{F} packet contains all information needed to allow @value{GDBN} +to call the appropriate host system call: + +@itemize @bullet +@item +A unique identifier for the requested system call. + +@item +All parameters to the system call. Pointers are given as addresses +in the target memory address space. Pointers to strings are given as +pointer/length pair. Numerical values are given as they are. +Numerical control values are given in a protocol specific representation. + +@end itemize + +At that point @value{GDBN} has to perform the following actions. + +@itemize @bullet +@item +If parameter pointer values are given, which point to data needed as input +to a system call, @value{GDBN} requests this data from the target with a +standard @code{m} packet request. This additional communication has to be +expected by the target implementation and is handled as any other @code{m} +packet. + +@item +@value{GDBN} translates all value from protocol representation to host +representation as needed. Datatypes are coerced into the host types. + +@item +@value{GDBN} calls the system call + +@item +It then coerces datatypes back to protocol representation. + +@item +If pointer parameters in the request packet point to buffer space in which +a system call is expected to copy data to, the data is transmitted to the +target using a @code{M} or @code{X} packet. This packet has to be expected +by the target implementation and is handled as any other @code{M} or @code{X} +packet. + +@end itemize + +Eventually @value{GDBN} replies with another @code{F} packet which contains all +necessary information for the target to continue. This at least contains + +@itemize @bullet +@item +Return value. + +@item +@code{errno}, if has been changed by the system call. + +@item +``Ctrl-C'' flag. + +@end itemize + +After having done the needed type and value coercion, the target continues +the latest continue or step action. + +@node The F request packet +@subsection The @code{F} request packet +@cindex file-i/o request packet +@cindex @code{F} request packet + +The @code{F} request packet has the following format: + +@table @samp + +@smallexample +@code{F}@var{call-id}@code{,}@var{parameter@dots{}} +@end smallexample + +@var{call-id} is the identifier to indicate the host system call to be called. +This is just the name of the function. + +@var{parameter@dots{}} are the parameters to the system call. + +@end table + +Parameters are hexadecimal integer values, either the real values in case +of scalar datatypes, as pointers to target buffer space in case of compound +datatypes and unspecified memory areas or as pointer/length pairs in case +of string parameters. These are appended to the call-id, each separated +from its predecessor by a comma. All values are transmitted in ASCII +string representation, pointer/length pairs separated by a slash. + +@node The F reply packet +@subsection The @code{F} reply packet +@cindex file-i/o reply packet +@cindex @code{F} reply packet + +The @code{F} reply packet has the following format: + +@table @samp + +@smallexample +@code{F}@var{retcode}@code{,}@var{errno}@code{,}@var{Ctrl-C flag}@code{;}@var{call specific attachment} +@end smallexample + +@var{retcode} is the return code of the system call as hexadecimal value. + +@var{errno} is the errno set by the call, in protocol specific representation. +This parameter can be omitted if the call was successful. + +@var{Ctrl-C flag} is only send if the user requested a break. In this +case, @var{errno} must be send as well, even if the call was successful. +The @var{Ctrl-C flag} itself consists of the character 'C': + +@smallexample +F0,0,C +@end smallexample + +@noindent +or, if the call was interupted before the host call has been performed: + +@smallexample +F-1,4,C +@end smallexample + +@noindent +assuming 4 is the protocol specific representation of @code{EINTR}. + +@end table + +@node Memory transfer +@subsection Memory transfer +@cindex memory transfer, in file-i/o protocol + +Structured data which is transferred using a memory read or write as e.g.@: +a @code{struct stat} is expected to be in a protocol specific format with +all scalar multibyte datatypes being big endian. This should be done by +the target before the @code{F} packet is sent resp.@: by @value{GDBN} before +it transfers memory to the target. Transferred pointers to structured +data should point to the already coerced data at any time. + +@node The Ctrl-C message +@subsection The Ctrl-C message +@cindex ctrl-c message, in file-i/o protocol + +A special case is, if the @var{Ctrl-C flag} is set in the @value{GDBN} +reply packet. In this case the target should behave, as if it had +gotten a break message. The meaning for the target is ``system call +interupted by @code{SIGINT}''. Consequentially, the target should actually stop +(as with a break message) and return to @value{GDBN} with a @code{T02} +packet. In this case, it's important for the target to know, in which +state the system call was interrupted. Since this action is by design +not an atomic operation, we have to differ between two cases: + +@itemize @bullet +@item +The system call hasn't been performed on the host yet. + +@item +The system call on the host has been finished. + +@end itemize + +These two states can be distinguished by the target by the value of the +returned @code{errno}. If it's the protocol representation of @code{EINTR}, the system +call hasn't been performed. This is equivalent to the @code{EINTR} handling +on POSIX systems. In any other case, the target may presume that the +system call has been finished --- successful or not --- and should behave +as if the break message arrived right after the system call. + +@value{GDBN} must behave reliable. If the system call has not been called +yet, @value{GDBN} may send the @code{F} reply immediately, setting @code{EINTR} as +@code{errno} in the packet. If the system call on the host has been finished +before the user requests a break, the full action must be finshed by +@value{GDBN}. This requires sending @code{M} or @code{X} packets as they fit. +The @code{F} packet may only be send when either nothing has happened +or the full action has been completed. + +@node Console I/O +@subsection Console I/O +@cindex console i/o as part of file-i/o + +By default and if not explicitely closed by the target system, the file +descriptors 0, 1 and 2 are connected to the @value{GDBN} console. Output +on the @value{GDBN} console is handled as any other file output operation +(@code{write(1, @dots{})} or @code{write(2, @dots{})}). Console input is handled +by @value{GDBN} so that after the target read request from file descriptor +0 all following typing is buffered until either one of the following +conditions is met: + +@itemize @bullet +@item +The user presses @kbd{Ctrl-C}. The behaviour is as explained above, the +@code{read} +system call is treated as finished. + +@item +The user presses @kbd{Enter}. This is treated as end of input with a trailing +line feed. + +@item +The user presses @kbd{Ctrl-D}. This is treated as end of input. No trailing +character, especially no Ctrl-D is appended to the input. + +@end itemize + +If the user has typed more characters as fit in the buffer given to +the read call, the trailing characters are buffered in @value{GDBN} until +either another @code{read(0, @dots{})} is requested by the target or debugging +is stopped on users request. + +@node The isatty call +@subsection The isatty(3) call +@cindex isatty call, file-i/o protocol + +A special case in this protocol is the library call @code{isatty} which +is implemented as it's own call inside of this protocol. It returns +1 to the target if the file descriptor given as parameter is attached +to the @value{GDBN} console, 0 otherwise. Implementing through system calls +would require implementing @code{ioctl} and would be more complex than +needed. + +@node The system call +@subsection The system(3) call +@cindex system call, file-i/o protocol + +The other special case in this protocol is the @code{system} call which +is implemented as it's own call, too. @value{GDBN} is taking over the full +task of calling the necessary host calls to perform the @code{system} +call. The return value of @code{system} is simplified before it's returned +to the target. Basically, the only signal transmitted back is @code{EINTR} +in case the user pressed @kbd{Ctrl-C}. Otherwise the return value consists +entirely of the exit status of the called command. + +Due to security concerns, the @code{system} call is refused to be called +by @value{GDBN} by default. The user has to allow this call explicitly by +entering + +@table @samp +@kindex set remote system-call-allowed 1 +@item @code{set remote system-call-allowed 1} +@end table + +Disabling the @code{system} call is done by + +@table @samp +@kindex set remote system-call-allowed 0 +@item @code{set remote system-call-allowed 0} +@end table + +The current setting is shown by typing + +@table @samp +@kindex show remote system-call-allowed +@item @code{show remote system-call-allowed} +@end table + +@node List of supported calls +@subsection List of supported calls +@cindex list of supported file-i/o calls + +@menu +* open:: +* close:: +* read:: +* write:: +* lseek:: +* rename:: +* unlink:: +* stat/fstat:: +* gettimeofday:: +* isatty:: +* system:: +@end menu + +@node open +@unnumberedsubsubsec open +@cindex open, file-i/o system call + +@smallexample +@exdent Synopsis: +int open(const char *pathname, int flags); +int open(const char *pathname, int flags, mode_t mode); + +@exdent Request: +Fopen,pathptr/len,flags,mode +@end smallexample + +@noindent +@code{flags} is the bitwise or of the following values: + +@table @code +@item O_CREAT +If the file does not exist it will be created. The host +rules apply as far as file ownership and time stamps +are concerned. + +@item O_EXCL +When used with O_CREAT, if the file already exists it is +an error and open() fails. + +@item O_TRUNC +If the file already exists and the open mode allows +writing (O_RDWR or O_WRONLY is given) it will be +truncated to length 0. + +@item O_APPEND +The file is opened in append mode. + +@item O_RDONLY +The file is opened for reading only. + +@item O_WRONLY +The file is opened for writing only. + +@item O_RDWR +The file is opened for reading and writing. + +@noindent +Each other bit is silently ignored. + +@end table + +@noindent +@code{mode} is the bitwise or of the following values: + +@table @code +@item S_IRUSR +User has read permission. + +@item S_IWUSR +User has write permission. + +@item S_IRGRP +Group has read permission. + +@item S_IWGRP +Group has write permission. + +@item S_IROTH +Others have read permission. + +@item S_IWOTH +Others have write permission. + +@noindent +Each other bit is silently ignored. + +@end table + +@smallexample +@exdent Return value: +open returns the new file descriptor or -1 if an error +occured. + +@exdent Errors: +@end smallexample + +@table @code +@item EEXIST +pathname already exists and O_CREAT and O_EXCL were used. + +@item EISDIR +pathname refers to a directory. + +@item EACCES +The requested access is not allowed. + +@item ENAMETOOLONG +pathname was too long. + +@item ENOENT +A directory component in pathname does not exist. + +@item ENODEV +pathname refers to a device, pipe, named pipe or socket. + +@item EROFS +pathname refers to a file on a read-only filesystem and +write access was requested. + +@item EFAULT +pathname is an invalid pointer value. + +@item ENOSPC +No space on device to create the file. + +@item EMFILE +The process already has the maximum number of files open. + +@item ENFILE +The limit on the total number of files open on the system +has been reached. + +@item EINTR +The call was interrupted by the user. +@end table + +@node close +@unnumberedsubsubsec close +@cindex close, file-i/o system call + +@smallexample +@exdent Synopsis: +int close(int fd); + +@exdent Request: +Fclose,fd + +@exdent Return value: +close returns zero on success, or -1 if an error occurred. + +@exdent Errors: +@end smallexample + +@table @code +@item EBADF +fd isn't a valid open file descriptor. + +@item EINTR +The call was interrupted by the user. +@end table + +@node read +@unnumberedsubsubsec read +@cindex read, file-i/o system call + +@smallexample +@exdent Synopsis: +int read(int fd, void *buf, unsigned int count); + +@exdent Request: +Fread,fd,bufptr,count + +@exdent Return value: +On success, the number of bytes read is returned. +Zero indicates end of file. If count is zero, read +returns zero as well. On error, -1 is returned. + +@exdent Errors: +@end smallexample + +@table @code +@item EBADF +fd is not a valid file descriptor or is not open for +reading. + +@item EFAULT +buf is an invalid pointer value. + +@item EINTR +The call was interrupted by the user. +@end table + +@node write +@unnumberedsubsubsec write +@cindex write, file-i/o system call + +@smallexample +@exdent Synopsis: +int write(int fd, const void *buf, unsigned int count); + +@exdent Request: +Fwrite,fd,bufptr,count + +@exdent Return value: +On success, the number of bytes written are returned. +Zero indicates nothing was written. On error, -1 +is returned. + +@exdent Errors: +@end smallexample + +@table @code +@item EBADF +fd is not a valid file descriptor or is not open for +writing. + +@item EFAULT +buf is an invalid pointer value. + +@item EFBIG +An attempt was made to write a file that exceeds the +host specific maximum file size allowed. + +@item ENOSPC +No space on device to write the data. + +@item EINTR +The call was interrupted by the user. +@end table + +@node lseek +@unnumberedsubsubsec lseek +@cindex lseek, file-i/o system call + +@smallexample +@exdent Synopsis: +long lseek (int fd, long offset, int flag); + +@exdent Request: +Flseek,fd,offset,flag +@end smallexample + +@code{flag} is one of: + +@table @code +@item SEEK_SET +The offset is set to offset bytes. + +@item SEEK_CUR +The offset is set to its current location plus offset +bytes. + +@item SEEK_END +The offset is set to the size of the file plus offset +bytes. +@end table + +@smallexample +@exdent Return value: +On success, the resulting unsigned offset in bytes from +the beginning of the file is returned. Otherwise, a +value of -1 is returned. + +@exdent Errors: +@end smallexample + +@table @code +@item EBADF +fd is not a valid open file descriptor. + +@item ESPIPE +fd is associated with the @value{GDBN} console. + +@item EINVAL +flag is not a proper value. + +@item EINTR +The call was interrupted by the user. +@end table + +@node rename +@unnumberedsubsubsec rename +@cindex rename, file-i/o system call + +@smallexample +@exdent Synopsis: +int rename(const char *oldpath, const char *newpath); + +@exdent Request: +Frename,oldpathptr/len,newpathptr/len + +@exdent Return value: +On success, zero is returned. On error, -1 is returned. + +@exdent Errors: +@end smallexample + +@table @code +@item EISDIR +newpath is an existing directory, but oldpath is not a +directory. + +@item EEXIST +newpath is a non-empty directory. + +@item EBUSY +oldpath or newpath is a directory that is in use by some +process. + +@item EINVAL +An attempt was made to make a directory a subdirectory +of itself. + +@item ENOTDIR +A component used as a directory in oldpath or new +path is not a directory. Or oldpath is a directory +and newpath exists but is not a directory. + +@item EFAULT +oldpathptr or newpathptr are invalid pointer values. + +@item EACCES +No access to the file or the path of the file. + +@item ENAMETOOLONG + +oldpath or newpath was too long. + +@item ENOENT +A directory component in oldpath or newpath does not exist. + +@item EROFS +The file is on a read-only filesystem. + +@item ENOSPC +The device containing the file has no room for the new +directory entry. + +@item EINTR +The call was interrupted by the user. +@end table + +@node unlink +@unnumberedsubsubsec unlink +@cindex unlink, file-i/o system call + +@smallexample +@exdent Synopsis: +int unlink(const char *pathname); + +@exdent Request: +Funlink,pathnameptr/len + +@exdent Return value: +On success, zero is returned. On error, -1 is returned. + +@exdent Errors: +@end smallexample + +@table @code +@item EACCES +No access to the file or the path of the file. + +@item EPERM +The system does not allow unlinking of directories. + +@item EBUSY +The file pathname cannot be unlinked because it's +being used by another process. + +@item EFAULT +pathnameptr is an invalid pointer value. + +@item ENAMETOOLONG +pathname was too long. + +@item ENOENT +A directory component in pathname does not exist. + +@item ENOTDIR +A component of the path is not a directory. + +@item EROFS +The file is on a read-only filesystem. + +@item EINTR +The call was interrupted by the user. +@end table + +@node stat/fstat +@unnumberedsubsubsec stat/fstat +@cindex fstat, file-i/o system call +@cindex stat, file-i/o system call + +@smallexample +@exdent Synopsis: +int stat(const char *pathname, struct stat *buf); +int fstat(int fd, struct stat *buf); + +@exdent Request: +Fstat,pathnameptr/len,bufptr +Ffstat,fd,bufptr + +@exdent Return value: +On success, zero is returned. On error, -1 is returned. + +@exdent Errors: +@end smallexample + +@table @code +@item EBADF +fd is not a valid open file. + +@item ENOENT +A directory component in pathname does not exist or the +path is an empty string. + +@item ENOTDIR +A component of the path is not a directory. + +@item EFAULT +pathnameptr is an invalid pointer value. + +@item EACCES +No access to the file or the path of the file. + +@item ENAMETOOLONG +pathname was too long. + +@item EINTR +The call was interrupted by the user. +@end table + +@node gettimeofday +@unnumberedsubsubsec gettimeofday +@cindex gettimeofday, file-i/o system call + +@smallexample +@exdent Synopsis: +int gettimeofday(struct timeval *tv, void *tz); + +@exdent Request: +Fgettimeofday,tvptr,tzptr + +@exdent Return value: +On success, 0 is returned, -1 otherwise. + +@exdent Errors: +@end smallexample + +@table @code +@item EINVAL +tz is a non-NULL pointer. + +@item EFAULT +tvptr and/or tzptr is an invalid pointer value. +@end table + +@node isatty +@unnumberedsubsubsec isatty +@cindex isatty, file-i/o system call + +@smallexample +@exdent Synopsis: +int isatty(int fd); + +@exdent Request: +Fisatty,fd + +@exdent Return value: +Returns 1 if fd refers to the @value{GDBN} console, 0 otherwise. + +@exdent Errors: +@end smallexample + +@table @code +@item EINTR +The call was interrupted by the user. +@end table + +@node system +@unnumberedsubsubsec system +@cindex system, file-i/o system call + +@smallexample +@exdent Synopsis: +int system(const char *command); + +@exdent Request: +Fsystem,commandptr/len + +@exdent Return value: +The value returned is -1 on error and the return status +of the command otherwise. Only the exit status of the +command is returned, which is extracted from the hosts +system return value by calling WEXITSTATUS(retval). +In case /bin/sh could not be executed, 127 is returned. + +@exdent Errors: +@end smallexample + +@table @code +@item EINTR +The call was interrupted by the user. +@end table + +@node Protocol specific representation of datatypes +@subsection Protocol specific representation of datatypes +@cindex protocol specific representation of datatypes, in file-i/o protocol + +@menu +* Integral datatypes:: +* Pointer values:: +* struct stat:: +* struct timeval:: +@end menu + +@node Integral datatypes +@unnumberedsubsubsec Integral datatypes +@cindex integral datatypes, in file-i/o protocol + +The integral datatypes used in the system calls are + +@smallexample +int@r{,} unsigned int@r{,} long@r{,} unsigned long@r{,} mode_t @r{and} time_t +@end smallexample + +@code{Int}, @code{unsigned int}, @code{mode_t} and @code{time_t} are +implemented as 32 bit values in this protocol. + +@code{Long} and @code{unsigned long} are implemented as 64 bit types. + +@xref{Limits}, for corresponding MIN and MAX values (similar to those +in @file{limits.h}) to allow range checking on host and target. + +@code{time_t} datatypes are defined as seconds since the Epoch. + +All integral datatypes transferred as part of a memory read or write of a +structured datatype e.g.@: a @code{struct stat} have to be given in big endian +byte order. + +@node Pointer values +@unnumberedsubsubsec Pointer values +@cindex pointer values, in file-i/o protocol + +Pointers to target data are transmitted as they are. An exception +is made for pointers to buffers for which the length isn't +transmitted as part of the function call, namely strings. Strings +are transmitted as a pointer/length pair, both as hex values, e.g.@: + +@smallexample +@code{1aaf/12} +@end smallexample + +@noindent +which is a pointer to data of length 18 bytes at position 0x1aaf. +The length is defined as the full string length in bytes, including +the trailing null byte. Example: + +@smallexample +``hello, world'' at address 0x123456 +@end smallexample + +@noindent +is transmitted as + +@smallexample +@code{123456/d} +@end smallexample + +@node struct stat +@unnumberedsubsubsec struct stat +@cindex struct stat, in file-i/o protocol + +The buffer of type struct stat used by the target and @value{GDBN} is defined +as follows: + +@smallexample +struct stat @{ + unsigned int st_dev; /* device */ + unsigned int st_ino; /* inode */ + mode_t st_mode; /* protection */ + unsigned int st_nlink; /* number of hard links */ + unsigned int st_uid; /* user ID of owner */ + unsigned int st_gid; /* group ID of owner */ + unsigned int st_rdev; /* device type (if inode device) */ + unsigned long st_size; /* total size, in bytes */ + unsigned long st_blksize; /* blocksize for filesystem I/O */ + unsigned long st_blocks; /* number of blocks allocated */ + time_t st_atime; /* time of last access */ + time_t st_mtime; /* time of last modification */ + time_t st_ctime; /* time of last change */ +@}; +@end smallexample + +The integral datatypes are conforming to the definitions given in the +approriate section (see @ref{Integral datatypes}, for details) so this +structure is of size 64 bytes. + +The values of several fields have a restricted meaning and/or +range of values. + +@smallexample +st_dev: 0 file + 1 console + +st_ino: No valid meaning for the target. Transmitted unchanged. + +st_mode: Valid mode bits are described in Appendix C. Any other + bits have currently no meaning for the target. + +st_uid: No valid meaning for the target. Transmitted unchanged. + +st_gid: No valid meaning for the target. Transmitted unchanged. + +st_rdev: No valid meaning for the target. Transmitted unchanged. + +st_atime, st_mtime, st_ctime: + These values have a host and file system dependent + accuracy. Especially on Windows hosts the file systems + don't support exact timing values. +@end smallexample + +The target gets a struct stat of the above representation and is +responsible to coerce it to the target representation before +continuing. + +Note that due to size differences between the host and target +representation of stat members, these members could eventually +get truncated on the target. + +@node struct timeval +@unnumberedsubsubsec struct timeval +@cindex struct timeval, in file-i/o protocol + +The buffer of type struct timeval used by the target and @value{GDBN} +is defined as follows: + +@smallexample +struct timeval @{ + time_t tv_sec; /* second */ + long tv_usec; /* microsecond */ +@}; +@end smallexample + +The integral datatypes are conforming to the definitions given in the +approriate section (see @ref{Integral datatypes}, for details) so this +structure is of size 8 bytes. + +@node Constants +@subsection Constants +@cindex constants, in file-i/o protocol + +The following values are used for the constants inside of the +protocol. @value{GDBN} and target are resposible to translate these +values before and after the call as needed. + +@menu +* Open flags:: +* mode_t values:: +* Errno values:: +* Lseek flags:: +* Limits:: +@end menu + +@node Open flags +@unnumberedsubsubsec Open flags +@cindex open flags, in file-i/o protocol + +All values are given in hexadecimal representation. + +@smallexample + O_RDONLY 0x0 + O_WRONLY 0x1 + O_RDWR 0x2 + O_APPEND 0x8 + O_CREAT 0x200 + O_TRUNC 0x400 + O_EXCL 0x800 +@end smallexample + +@node mode_t values +@unnumberedsubsubsec mode_t values +@cindex mode_t values, in file-i/o protocol + +All values are given in octal representation. + +@smallexample + S_IFREG 0100000 + S_IFDIR 040000 + S_IRUSR 0400 + S_IWUSR 0200 + S_IXUSR 0100 + S_IRGRP 040 + S_IWGRP 020 + S_IXGRP 010 + S_IROTH 04 + S_IWOTH 02 + S_IXOTH 01 +@end smallexample + +@node Errno values +@unnumberedsubsubsec Errno values +@cindex errno values, in file-i/o protocol + +All values are given in decimal representation. + +@smallexample + EPERM 1 + ENOENT 2 + EINTR 4 + EBADF 9 + EACCES 13 + EFAULT 14 + EBUSY 16 + EEXIST 17 + ENODEV 19 + ENOTDIR 20 + EISDIR 21 + EINVAL 22 + ENFILE 23 + EMFILE 24 + EFBIG 27 + ENOSPC 28 + ESPIPE 29 + EROFS 30 + ENAMETOOLONG 91 + EUNKNOWN 9999 +@end smallexample + + EUNKNOWN is used as a fallback error value if a host system returns + any error value not in the list of supported error numbers. + +@node Lseek flags +@unnumberedsubsubsec Lseek flags +@cindex lseek flags, in file-i/o protocol + +@smallexample + SEEK_SET 0 + SEEK_CUR 1 + SEEK_END 2 +@end smallexample + +@node Limits +@unnumberedsubsubsec Limits +@cindex limits, in file-i/o protocol + +All values are given in decimal representation. + +@smallexample + INT_MIN -2147483648 + INT_MAX 2147483647 + UINT_MAX 4294967295 + LONG_MIN -9223372036854775808 + LONG_MAX 9223372036854775807 + ULONG_MAX 18446744073709551615 +@end smallexample + +@node File-I/O Examples +@subsection File-I/O Examples +@cindex file-i/o examples + +Example sequence of a write call, file descriptor 3, buffer is at target +address 0x1234, 6 bytes should be written: + +@smallexample +<- @code{Fwrite,3,1234,6} +@emph{request memory read from target} +-> @code{m1234,6} +<- XXXXXX +@emph{return "6 bytes written"} +-> @code{F6} +@end smallexample + +Example sequence of a read call, file descriptor 3, buffer is at target +address 0x1234, 6 bytes should be read: + +@smallexample +<- @code{Fread,3,1234,6} +@emph{request memory write to target} +-> @code{X1234,6:XXXXXX} +@emph{return "6 bytes read"} +-> @code{F6} +@end smallexample + +Example sequence of a read call, call fails on the host due to invalid +file descriptor (EBADF): + +@smallexample +<- @code{Fread,3,1234,6} +-> @code{F-1,9} +@end smallexample + +Example sequence of a read call, user presses Ctrl-C before syscall on +host is called: + +@smallexample +<- @code{Fread,3,1234,6} +-> @code{F-1,4,C} +<- @code{T02} +@end smallexample + +Example sequence of a read call, user presses Ctrl-C after syscall on +host is called: + +@smallexample +<- @code{Fread,3,1234,6} +-> @code{X1234,6:XXXXXX} +<- @code{T02} +@end smallexample + +@include agentexpr.texi @include gpl.texi +@raisesections @include fdl.texi +@lowersections @node Index @unnumbered Index diff --git a/contrib/gdb/gdb/doc/gdbint.texinfo b/contrib/gdb/gdb/doc/gdbint.texinfo index 67f22f004fb..2fe4b29fa1a 100644 --- a/contrib/gdb/gdb/doc/gdbint.texinfo +++ b/contrib/gdb/gdb/doc/gdbint.texinfo @@ -1,14 +1,14 @@ \input texinfo @c -*- texinfo -*- @setfilename gdbint.info @include gdb-cfg.texi -@dircategory Programming & development tools. +@dircategory Software development @direntry * Gdb-Internals: (gdbint). The GNU debugger's internals. @end direntry @ifinfo This file documents the internals of the GNU debugger @value{GDBN}. -Copyright 1990,1991,1992,1993,1994,1996,1998,1999,2000,2001,2002 +Copyright 1990,1991,1992,1993,1994,1996,1998,1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. Contributed by Cygnus Solutions. Written by John Gilmore. Second Edition by Stan Shebs. @@ -16,12 +16,9 @@ Second Edition by Stan Shebs. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' -and with the Back-Cover Texts as in (a) below. - -(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify -this GNU Manual, like GNU software. Copies published by the Free -Software Foundation raise funds for GNU development.'' +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled ``GNU +Free Documentation License''. @end ifinfo @setchapternewpage off @@ -50,18 +47,15 @@ Software Foundation raise funds for GNU development.'' @end tex @vskip 0pt plus 1filll -Copyright @copyright{} 1990,1991,1992,1993,1994,1996,1998,1999,2000,2001 - Free Software Foundation, Inc. +Copyright @copyright{} 1990,1991,1992,1993,1994,1996,1998,1999,2000,2001, + 2002, 2003, 2004 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' -and with the Back-Cover Texts as in (a) below. - -(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify -this GNU Manual, like GNU software. Copies published by the Free -Software Foundation raise funds for GNU development.'' +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled ``GNU +Free Documentation License''. @end titlepage @contents @@ -94,6 +88,7 @@ as the mechanisms that adapt @value{GDBN} to specific hosts and targets. * Testsuite:: * Hints:: +* GDB Observers:: @value{GDBN} Currently available observers * GNU Free Documentation License:: The license for this documentation * Index:: @end menu @@ -239,23 +234,25 @@ and called functions. machine-independent part of @value{GDBN}, except that it is used when setting up a new frame from scratch, as follows: -@example - create_new_frame (read_register (FP_REGNUM), read_pc ())); -@end example +@smallexample +create_new_frame (read_register (DEPRECATED_FP_REGNUM), read_pc ())); +@end smallexample @cindex frame pointer register -Other than that, all the meaning imparted to @code{FP_REGNUM} is -imparted by the machine-dependent code. So, @code{FP_REGNUM} can have -any value that is convenient for the code that creates new frames. -(@code{create_new_frame} calls @code{INIT_EXTRA_FRAME_INFO} if it is -defined; that is where you should use the @code{FP_REGNUM} value, if -your frames are nonstandard.) +Other than that, all the meaning imparted to @code{DEPRECATED_FP_REGNUM} +is imparted by the machine-dependent code. So, +@code{DEPRECATED_FP_REGNUM} can have any value that is convenient for +the code that creates new frames. (@code{create_new_frame} calls +@code{DEPRECATED_INIT_EXTRA_FRAME_INFO} if it is defined; that is where +you should use the @code{DEPRECATED_FP_REGNUM} value, if your frames are +nonstandard.) @cindex frame chain -Given a @value{GDBN} frame, define @code{FRAME_CHAIN} to determine the -address of the calling function's frame. This will be used to create -a new @value{GDBN} frame struct, and then @code{INIT_EXTRA_FRAME_INFO} -and @code{INIT_FRAME_PC} will be called for the new frame. +Given a @value{GDBN} frame, define @code{DEPRECATED_FRAME_CHAIN} to +determine the address of the calling function's frame. This will be +used to create a new @value{GDBN} frame struct, and then +@code{DEPRECATED_INIT_EXTRA_FRAME_INFO} and +@code{DEPRECATED_INIT_FRAME_PC} will be called for the new frame. @section Breakpoint Handling @@ -285,13 +282,13 @@ A third possibility is that the target already has the ability to do breakpoints somehow; for instance, a ROM monitor may do its own software breakpoints. So although these are not literally ``hardware breakpoints'', from @value{GDBN}'s point of view they work the same; -@value{GDBN} need not do nothing more than set the breakpoint and wait +@value{GDBN} need not do anything more than set the breakpoint and wait for something to happen. Since they depend on hardware resources, hardware breakpoints may be limited in number; when the user asks for more, @value{GDBN} will start trying to set software breakpoints. (On some architectures, -notably the 32-bit x86 platforms, @value{GDBN} cannot alsways know +notably the 32-bit x86 platforms, @value{GDBN} cannot always know whether there's enough hardware resources to insert all the hardware breakpoints and watchpoints. On those platforms, @value{GDBN} prints an error message only when the program being debugged is continued.) @@ -453,7 +450,7 @@ Insert or remove a hardware watchpoint starting at @var{addr}, for possible values of the enumerated data type @code{target_hw_bp_type}, defined by @file{breakpoint.h} as follows: -@example +@smallexample enum target_hw_bp_type @{ hw_write = 0, /* Common (write) HW watchpoint */ @@ -461,7 +458,7 @@ defined by @file{breakpoint.h} as follows: hw_access = 2, /* Access (read or write) HW watchpoint */ hw_execute = 3 /* Execute HW breakpoint */ @}; -@end example +@end smallexample @noindent These two macros should return 0 for success, non-zero for failure. @@ -483,13 +480,6 @@ two macros can use them for their internal purposes. If the inferior has some watchpoint that triggered, return the address associated with that watchpoint. Otherwise, return zero. -@findex DECR_PC_AFTER_HW_BREAK -@item DECR_PC_AFTER_HW_BREAK -If defined, @value{GDBN} decrements the program counter by the value -of @code{DECR_PC_AFTER_HW_BREAK} after a hardware break-point. This -overrides the value of @code{DECR_PC_AFTER_BREAK} when a breakpoint -that breaks is a hardware-assisted breakpoint. - @findex HAVE_STEPPABLE_WATCHPOINT @item HAVE_STEPPABLE_WATCHPOINT If defined to a non-zero value, it is not necessary to disable a @@ -628,8 +618,8 @@ looks for a debug register which is already set to watch the same region for the same access types; if found, it just increments the reference count of that debug register, thus implementing debug register sharing between watchpoints. If no such register is found, -the function looks for a vacant debug register, sets its mirrorred -value to @var{addr}, sets the mirrorred value of DR7 Debug Control +the function looks for a vacant debug register, sets its mirrored +value to @var{addr}, sets the mirrored value of DR7 Debug Control register as appropriate for the @var{len} and @var{type} parameters, and then passes the new values of the debug register and DR7 to the inferior by calling @code{I386_DR_LOW_SET_ADDR} and @@ -638,8 +628,8 @@ required to cover the given region, the above process is repeated for each debug register. @code{i386_remove_watchpoint} does the opposite: it resets the address -in the mirrorred value of the debug register and its read/write and -length bits in the mirrorred value of DR7, then passes these new +in the mirrored value of the debug register and its read/write and +length bits in the mirrored value of DR7, then passes these new values to the inferior via @code{I386_DR_LOW_RESET_ADDR} and @code{I386_DR_LOW_SET_CONTROL}. If a register is shared by several watchpoints, each time a @code{i386_remove_watchpoint} is called, it @@ -695,6 +685,29 @@ watchpoints might interfere with the underlying OS and are probably unavailable in many platforms. @end enumerate +@section Observing changes in @value{GDBN} internals +@cindex observer pattern interface +@cindex notifications about changes in internals + +In order to function properly, several modules need to be notified when +some changes occur in the @value{GDBN} internals. Traditionally, these +modules have relied on several paradigms, the most common ones being +hooks and gdb-events. Unfortunately, none of these paradigms was +versatile enough to become the standard notification mechanism in +@value{GDBN}. The fact that they only supported one ``client'' was also +a strong limitation. + +A new paradigm, based on the Observer pattern of the @cite{Design +Patterns} book, has therefore been implemented. The goal was to provide +a new interface overcoming the issues with the notification mechanisms +previously available. This new interface needed to be strongly typed, +easy to extend, and versatile enough to be used as the standard +interface when adding new notifications. + +See @ref{GDB Observers} for a brief description of the observers +currently implemented in GDB. The rationale for the current +implementation is also briefly discussed. + @node User Interface @chapter User Interface @@ -722,6 +735,14 @@ the main command list, and should be used for those commands. The usual place to add commands is in the @code{_initialize_@var{xyz}} routines at the ends of most source files. +@findex add_setshow_cmd +@findex add_setshow_cmd_full +To add paired @samp{set} and @samp{show} commands, use +@code{add_setshow_cmd} or @code{add_setshow_cmd_full}. The former is +a slightly simpler interface which is useful when you don't need to +further modify the new command structures, while the latter returns +the new command structures for manipulation. + @cindex deprecating commands @findex deprecate_cmd Before removing commands from the command set it is a good idea to @@ -863,7 +884,7 @@ maximum of five levels. The overall structure of the table output code is something like this: -@example +@smallexample ui_out_table_begin ui_out_table_header @dots{} @@ -874,7 +895,7 @@ The overall structure of the table output code is something like this: ui_out_tuple_end @dots{} ui_out_table_end -@end example +@end smallexample Here is the description of table-, tuple- and list-related @code{ui_out} functions: @@ -946,7 +967,7 @@ be signaled. This function first opens the tuple and then establishes a cleanup (@pxref{Coding, Cleanups}) to close the tuple. It provides a convenient and correct implementation of the non-portable@footnote{The function -cast is not portable ISO-C.} code sequence: +cast is not portable ISO C.} code sequence: @smallexample struct cleanup *old_cleanup; ui_out_tuple_begin (uiout, "..."); @@ -1003,6 +1024,13 @@ This function outputs a value of an @code{int} variable. It uses the the name of the field. @end deftypefun +@deftypefun void ui_out_field_fmt_int (struct ui_out *@var{uiout}, int @var{width}, enum ui_align @var{alignment}, const char *@var{fldname}, int @var{value}) +This function outputs a value of an @code{int} variable. It differs from +@code{ui_out_field_int} in that the caller specifies the desired @var{width} and @var{alignment} of the output. +@var{fldname} specifies +the name of the field. +@end deftypefun + @deftypefun void ui_out_field_core_addr (struct ui_out *@var{uiout}, const char *@var{fldname}, CORE_ADDR @var{address}) This function outputs an address. @end deftypefun @@ -1139,7 +1167,7 @@ produce a table. The original code was: -@example +@smallexample if (!found_a_breakpoint++) @{ annotate_breakpoints_headers (); @@ -1162,11 +1190,11 @@ The original code was: annotate_breakpoints_table (); @} -@end example +@end smallexample Here's the new version: -@example +@smallexample nr_printable_breakpoints = @dots{}; if (addressprint) @@ -1203,13 +1231,13 @@ Here's the new version: ui_out_table_body (uiout); if (nr_printable_breakpoints > 0) annotate_breakpoints_table (); -@end example +@end smallexample This example, from the @code{print_one_breakpoint} function, shows how to produce the actual data for the table whose structure was defined in the above example. The original code was: -@example +@smallexample annotate_record (); annotate_field (0); printf_filtered ("%-3d ", b->number); @@ -1224,11 +1252,11 @@ in the above example. The original code was: annotate_field (3); printf_filtered ("%-3c ", bpenables[(int)b->enable]); @dots{} -@end example +@end smallexample This is the new version: -@example +@smallexample annotate_record (); ui_out_tuple_begin (uiout, "bkpt"); annotate_field (0); @@ -1244,44 +1272,44 @@ This is the new version: annotate_field (3); ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int)b->enable]); @dots{} -@end example +@end smallexample This example, also from @code{print_one_breakpoint}, shows how to produce a complicated output field using the @code{print_expression} functions which requires a stream to be passed. It also shows how to automate stream destruction with cleanups. The original code was: -@example +@smallexample annotate_field (5); print_expression (b->exp, gdb_stdout); -@end example +@end smallexample The new version is: -@example +@smallexample struct ui_stream *stb = ui_out_stream_new (uiout); struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb); ... annotate_field (5); print_expression (b->exp, stb->stream); ui_out_field_stream (uiout, "what", local_stream); -@end example +@end smallexample This example, also from @code{print_one_breakpoint}, shows how to use @code{ui_out_text} and @code{ui_out_field_string}. The original code was: -@example +@smallexample annotate_field (5); if (b->dll_pathname == NULL) printf_filtered (" "); else printf_filtered ("library \"%s\" ", b->dll_pathname); -@end example +@end smallexample It became: -@example +@smallexample annotate_field (5); if (b->dll_pathname == NULL) @{ @@ -1294,21 +1322,21 @@ It became: ui_out_field_string (uiout, "what", b->dll_pathname); ui_out_text (uiout, "\" "); @} -@end example +@end smallexample The following example from @code{print_one_breakpoint} shows how to use @code{ui_out_field_int} and @code{ui_out_spaces}. The original code was: -@example +@smallexample annotate_field (5); if (b->forked_inferior_pid != 0) printf_filtered ("process %d ", b->forked_inferior_pid); -@end example +@end smallexample It became: -@example +@smallexample annotate_field (5); if (b->forked_inferior_pid != 0) @{ @@ -1316,20 +1344,20 @@ It became: ui_out_field_int (uiout, "what", b->forked_inferior_pid); ui_out_spaces (uiout, 1); @} -@end example +@end smallexample Here's an example of using @code{ui_out_field_string}. The original code was: -@example +@smallexample annotate_field (5); if (b->exec_pathname != NULL) printf_filtered ("program \"%s\" ", b->exec_pathname); -@end example +@end smallexample It became: -@example +@smallexample annotate_field (5); if (b->exec_pathname != NULL) @{ @@ -1337,22 +1365,22 @@ It became: ui_out_field_string (uiout, "what", b->exec_pathname); ui_out_text (uiout, "\" "); @} -@end example +@end smallexample Finally, here's an example of printing an address. The original code: -@example +@smallexample annotate_field (4); printf_filtered ("%s ", local_hex_string_custom ((unsigned long) b->address, "08l")); -@end example +@end smallexample It became: -@example +@smallexample annotate_field (4); ui_out_field_core_addr (uiout, "Address", b->address); -@end example +@end smallexample @section Console Printing @@ -1464,7 +1492,7 @@ loop. A client would need to either plug its self into this loop or, implement a new event-loop that GDB would use. The event-loop will eventually be made re-entrant. This is so that -@value{GDB} can better handle the problem of some commands blocking +@value{GDBN} can better handle the problem of some commands blocking instead of returning. @subheading Library - @file{gdb.h} @@ -1826,7 +1854,6 @@ The file @file{mdebugread.c} implements reading for this format. DWARF 1 is a debugging format that was originally designed to be used with ELF in SVR4 systems. -@c CHILL_PRODUCER @c GCC_PRODUCER @c GPLUS_PRODUCER @c LCC_PRODUCER @@ -1904,7 +1931,7 @@ parsers that define a bunch of global names, the following lines @strong{must} be included at the top of the YACC parser, to prevent the various parsers from defining the same global names: -@example +@smallexample #define yyparse @var{lang}_parse #define yylex @var{lang}_lex #define yyerror @var{lang}_error @@ -1921,7 +1948,7 @@ various parsers from defining the same global names: #define yyexca @var{lang}_exca #define yyerrflag @var{lang}_errflag #define yynerrs @var{lang}_nerrs -@end example +@end smallexample At the bottom of your parser, define a @code{struct language_defn} and initialize it with the right values for your language. Define an @@ -2211,12 +2238,6 @@ This macro is used as the argument to @code{lseek} (or, most commonly, @code{bfd_seek}). FIXME, should be replaced by SEEK_SET instead, which is the POSIX equivalent. -@item MMAP_BASE_ADDRESS -When using HAVE_MMAP, the first mapping should go at this address. - -@item MMAP_INCREMENT -when using HAVE_MMAP, this is the increment between mappings. - @item NORETURN If defined, this should be one or more tokens, such as @code{volatile}, that can be used in both the declaration and definition of functions to @@ -2230,42 +2251,6 @@ of functions to indicate that they never return. The default is already set correctly if compiling with GCC. This will almost never need to be defined. -@item USE_GENERIC_DUMMY_FRAMES -@cindex generic dummy frames -Define this to 1 if the target is using the generic inferior function -call code. See @code{blockframe.c} for more information. - -@item USE_MMALLOC -@findex mmalloc -@value{GDBN} will use the @code{mmalloc} library for memory allocation -for symbol reading if this symbol is defined. Be careful defining it -since there are systems on which @code{mmalloc} does not work for some -reason. One example is the DECstation, where its RPC library can't -cope with our redefinition of @code{malloc} to call @code{mmalloc}. -When defining @code{USE_MMALLOC}, you will also have to set -@code{MMALLOC} in the Makefile, to point to the @code{mmalloc} library. This -define is set when you configure with @samp{--with-mmalloc}. - -@item NO_MMCHECK -@findex mmcheck -Define this if you are using @code{mmalloc}, but don't want the overhead -of checking the heap with @code{mmcheck}. Note that on some systems, -the C runtime makes calls to @code{malloc} prior to calling @code{main}, and if -@code{free} is ever called with these pointers after calling -@code{mmcheck} to enable checking, a memory corruption abort is certain -to occur. These systems can still use @code{mmalloc}, but must define -@code{NO_MMCHECK}. - -@item MMCHECK_FORCE -Define this to 1 if the C runtime allocates memory prior to -@code{mmcheck} being called, but that memory is never freed so we don't -have to worry about it triggering a memory corruption abort. The -default is 0, which means that @code{mmcheck} will only install the heap -checking functions if there has not yet been any memory allocation -calls, and if it fails to install the functions, @value{GDBN} will issue a -warning. This is currently defined if you configure using -@samp{--with-mmalloc}. - @item NO_SIGINTERRUPT @findex siginterrupt Define this to indicate that @code{siginterrupt} is not available. @@ -2286,9 +2271,8 @@ always linked in.) @item USG Means that System V (prior to SVR4) include files are in use. (FIXME: -This symbol is abused in @file{infrun.c}, @file{regex.c}, -@file{remote-nindy.c}, and @file{utils.c} for other things, at the -moment.) +This symbol is abused in @file{infrun.c}, @file{regex.c}, and +@file{utils.c} for other things, at the moment.) @item lint Define this to help placate @code{lint} in some situations. @@ -2312,6 +2296,138 @@ The target architecture object is implemented as the C structure @code{struct gdbarch *}. The structure, and its methods, are generated using the Bourne shell script @file{gdbarch.sh}. +@section Operating System ABI Variant Handling +@cindex OS ABI variants + +@value{GDBN} provides a mechanism for handling variations in OS +ABIs. An OS ABI variant may have influence over any number of +variables in the target architecture definition. There are two major +components in the OS ABI mechanism: sniffers and handlers. + +A @dfn{sniffer} examines a file matching a BFD architecture/flavour pair +(the architecture may be wildcarded) in an attempt to determine the +OS ABI of that file. Sniffers with a wildcarded architecture are considered +to be @dfn{generic}, while sniffers for a specific architecture are +considered to be @dfn{specific}. A match from a specific sniffer +overrides a match from a generic sniffer. Multiple sniffers for an +architecture/flavour may exist, in order to differentiate between two +different operating systems which use the same basic file format. The +OS ABI framework provides a generic sniffer for ELF-format files which +examines the @code{EI_OSABI} field of the ELF header, as well as note +sections known to be used by several operating systems. + +@cindex fine-tuning @code{gdbarch} structure +A @dfn{handler} is used to fine-tune the @code{gdbarch} structure for the +selected OS ABI. There may be only one handler for a given OS ABI +for each BFD architecture. + +The following OS ABI variants are defined in @file{osabi.h}: + +@table @code + +@findex GDB_OSABI_UNKNOWN +@item GDB_OSABI_UNKNOWN +The ABI of the inferior is unknown. The default @code{gdbarch} +settings for the architecture will be used. + +@findex GDB_OSABI_SVR4 +@item GDB_OSABI_SVR4 +UNIX System V Release 4 + +@findex GDB_OSABI_HURD +@item GDB_OSABI_HURD +GNU using the Hurd kernel + +@findex GDB_OSABI_SOLARIS +@item GDB_OSABI_SOLARIS +Sun Solaris + +@findex GDB_OSABI_OSF1 +@item GDB_OSABI_OSF1 +OSF/1, including Digital UNIX and Compaq Tru64 UNIX + +@findex GDB_OSABI_LINUX +@item GDB_OSABI_LINUX +GNU using the Linux kernel + +@findex GDB_OSABI_FREEBSD_AOUT +@item GDB_OSABI_FREEBSD_AOUT +FreeBSD using the a.out executable format + +@findex GDB_OSABI_FREEBSD_ELF +@item GDB_OSABI_FREEBSD_ELF +FreeBSD using the ELF executable format + +@findex GDB_OSABI_NETBSD_AOUT +@item GDB_OSABI_NETBSD_AOUT +NetBSD using the a.out executable format + +@findex GDB_OSABI_NETBSD_ELF +@item GDB_OSABI_NETBSD_ELF +NetBSD using the ELF executable format + +@findex GDB_OSABI_WINCE +@item GDB_OSABI_WINCE +Windows CE + +@findex GDB_OSABI_GO32 +@item GDB_OSABI_GO32 +DJGPP + +@findex GDB_OSABI_NETWARE +@item GDB_OSABI_NETWARE +Novell NetWare + +@findex GDB_OSABI_ARM_EABI_V1 +@item GDB_OSABI_ARM_EABI_V1 +ARM Embedded ABI version 1 + +@findex GDB_OSABI_ARM_EABI_V2 +@item GDB_OSABI_ARM_EABI_V2 +ARM Embedded ABI version 2 + +@findex GDB_OSABI_ARM_APCS +@item GDB_OSABI_ARM_APCS +Generic ARM Procedure Call Standard + +@end table + +Here are the functions that make up the OS ABI framework: + +@deftypefun const char *gdbarch_osabi_name (enum gdb_osabi @var{osabi}) +Return the name of the OS ABI corresponding to @var{osabi}. +@end deftypefun + +@deftypefun void gdbarch_register_osabi (enum bfd_architecture @var{arch}, unsigned long @var{machine}, enum gdb_osabi @var{osabi}, void (*@var{init_osabi})(struct gdbarch_info @var{info}, struct gdbarch *@var{gdbarch})) +Register the OS ABI handler specified by @var{init_osabi} for the +architecture, machine type and OS ABI specified by @var{arch}, +@var{machine} and @var{osabi}. In most cases, a value of zero for the +machine type, which implies the architecture's default machine type, +will suffice. +@end deftypefun + +@deftypefun void gdbarch_register_osabi_sniffer (enum bfd_architecture @var{arch}, enum bfd_flavour @var{flavour}, enum gdb_osabi (*@var{sniffer})(bfd *@var{abfd})) +Register the OS ABI file sniffer specified by @var{sniffer} for the +BFD architecture/flavour pair specified by @var{arch} and @var{flavour}. +If @var{arch} is @code{bfd_arch_unknown}, the sniffer is considered to +be generic, and is allowed to examine @var{flavour}-flavoured files for +any architecture. +@end deftypefun + +@deftypefun enum gdb_osabi gdbarch_lookup_osabi (bfd *@var{abfd}) +Examine the file described by @var{abfd} to determine its OS ABI. +The value @code{GDB_OSABI_UNKNOWN} is returned if the OS ABI cannot +be determined. +@end deftypefun + +@deftypefun void gdbarch_init_osabi (struct gdbarch info @var{info}, struct gdbarch *@var{gdbarch}, enum gdb_osabi @var{osabi}) +Invoke the OS ABI handler corresponding to @var{osabi} to fine-tune the +@code{gdbarch} structure specified by @var{gdbarch}. If a handler +corresponding to @var{osabi} has not been registered for @var{gdbarch}'s +architecture, a warning will be issued and the debugging session will continue +with the defaults already established for @var{gdbarch}. +@end deftypefun + @section Registers and Memory @value{GDBN}'s model of the target machine is rather simple. @@ -2345,7 +2461,7 @@ However, architectures with smaller word sizes are often cramped for address space, so they may choose a pointer representation that breaks this identity, and allows a larger code address space. -For example, the Mitsubishi D10V is a 16-bit VLIW processor whose +For example, the Renesas D10V is a 16-bit VLIW processor whose instructions are 32 bits long@footnote{Some D10V instructions are actually pairs of 16-bit sub-instructions. However, since you can't jump into the middle of such a pair, code addresses can only refer to @@ -2435,35 +2551,6 @@ This function performs architecture-specific conversions as described above for @code{store_typed_address}. @end deftypefun - -@value{GDBN} also provides functions that do the same tasks, but assume -that pointers are simply byte addresses; they aren't sensitive to the -current architecture, beyond knowing the appropriate endianness. - -@deftypefun CORE_ADDR extract_address (void *@var{addr}, int len) -Extract a @var{len}-byte number from @var{addr} in the appropriate -endianness for the current architecture, and return it. Note that -@var{addr} refers to @value{GDBN}'s memory, not the inferior's. - -This function should only be used in architecture-specific code; it -doesn't have enough information to turn bits into a true address in the -appropriate way for the current architecture. If you can, use -@code{extract_typed_address} instead. -@end deftypefun - -@deftypefun void store_address (void *@var{addr}, int @var{len}, LONGEST @var{val}) -Store @var{val} at @var{addr} as a @var{len}-byte integer, in the -appropriate endianness for the current architecture. Note that -@var{addr} refers to a buffer in @value{GDBN}'s memory, not the -inferior's. - -This function should only be used in architecture-specific code; it -doesn't have enough information to turn a true address into bits in the -appropriate way for the current architecture. If you can, use -@code{store_typed_address} instead. -@end deftypefun - - Here are some macros which architectures can define to indicate the relationship between pointers and addresses. These have default definitions, appropriate for architectures on which all pointers are @@ -2486,18 +2573,105 @@ This function may safely assume that @var{type} is either a pointer or a C@t{++} reference type. @end deftypefn +@section Address Classes +@cindex address classes +@cindex DW_AT_byte_size +@cindex DW_AT_address_class -@section Using Different Register and Memory Data Representations -@cindex raw representation -@cindex virtual representation -@cindex representations, raw and virtual -@cindex register data formats, converting -@cindex @code{struct value}, converting register contents to +Sometimes information about different kinds of addresses is available +via the debug information. For example, some programming environments +define addresses of several different sizes. If the debug information +distinguishes these kinds of address classes through either the size +info (e.g, @code{DW_AT_byte_size} in @w{DWARF 2}) or through an explicit +address class attribute (e.g, @code{DW_AT_address_class} in @w{DWARF 2}), the +following macros should be defined in order to disambiguate these +types within @value{GDBN} as well as provide the added information to +a @value{GDBN} user when printing type expressions. -@emph{Maintainer's note: The way GDB manipulates registers is undergoing -significant change. Many of the macros and functions refered to in the -sections below are likely to be made obsolete. See the file @file{TODO} -for more up-to-date information.} +@deftypefn {Target Macro} int ADDRESS_CLASS_TYPE_FLAGS (int @var{byte_size}, int @var{dwarf2_addr_class}) +Returns the type flags needed to construct a pointer type whose size +is @var{byte_size} and whose address class is @var{dwarf2_addr_class}. +This function is normally called from within a symbol reader. See +@file{dwarf2read.c}. +@end deftypefn + +@deftypefn {Target Macro} char *ADDRESS_CLASS_TYPE_FLAGS_TO_NAME (int @var{type_flags}) +Given the type flags representing an address class qualifier, return +its name. +@end deftypefn +@deftypefn {Target Macro} int ADDRESS_CLASS_NAME_to_TYPE_FLAGS (int @var{name}, int *var{type_flags_ptr}) +Given an address qualifier name, set the @code{int} refererenced by @var{type_flags_ptr} to the type flags +for that address class qualifier. +@end deftypefn + +Since the need for address classes is rather rare, none of +the address class macros defined by default. Predicate +macros are provided to detect when they are defined. + +Consider a hypothetical architecture in which addresses are normally +32-bits wide, but 16-bit addresses are also supported. Furthermore, +suppose that the @w{DWARF 2} information for this architecture simply +uses a @code{DW_AT_byte_size} value of 2 to indicate the use of one +of these "short" pointers. The following functions could be defined +to implement the address class macros: + +@smallexample +somearch_address_class_type_flags (int byte_size, + int dwarf2_addr_class) +@{ + if (byte_size == 2) + return TYPE_FLAG_ADDRESS_CLASS_1; + else + return 0; +@} + +static char * +somearch_address_class_type_flags_to_name (int type_flags) +@{ + if (type_flags & TYPE_FLAG_ADDRESS_CLASS_1) + return "short"; + else + return NULL; +@} + +int +somearch_address_class_name_to_type_flags (char *name, + int *type_flags_ptr) +@{ + if (strcmp (name, "short") == 0) + @{ + *type_flags_ptr = TYPE_FLAG_ADDRESS_CLASS_1; + return 1; + @} + else + return 0; +@} +@end smallexample + +The qualifier @code{@@short} is used in @value{GDBN}'s type expressions +to indicate the presence of one of these "short" pointers. E.g, if +the debug information indicates that @code{short_ptr_var} is one of these +short pointers, @value{GDBN} might show the following behavior: + +@smallexample +(gdb) ptype short_ptr_var +type = int * @@short +@end smallexample + + +@section Raw and Virtual Register Representations +@cindex raw register representation +@cindex virtual register representation +@cindex representations, raw and virtual registers + +@emph{Maintainer note: This section is pretty much obsolete. The +functionality described here has largely been replaced by +pseudo-registers and the mechanisms described in @ref{Target +Architecture Definition, , Using Different Register and Memory Data +Representations}. See also @uref{http://www.gnu.org/software/gdb/bugs/, +Bug Tracking Database} and +@uref{http://sources.redhat.com/gdb/current/ari/, ARI Index} for more +up-to-date information.} Some architectures use one representation for a value when it lives in a register, but use a different representation when it lives in memory. @@ -2505,6 +2679,10 @@ In @value{GDBN}'s terminology, the @dfn{raw} representation is the one used in the target registers, and the @dfn{virtual} representation is the one used in memory, and within @value{GDBN} @code{struct value} objects. +@emph{Maintainer note: Notice that the same mechanism is being used to +both convert a register to a @code{struct value} and alternative +register forms.} + For almost all data types on almost all architectures, the virtual and raw representations are identical, and no special handling is needed. However, they do occasionally differ. For example: @@ -2544,19 +2722,19 @@ You should not use @code{REGISTER_CONVERT_TO_VIRTUAL} for a register unless this macro returns a non-zero value for that register. @end deftypefn -@deftypefn {Target Macro} int REGISTER_RAW_SIZE (int @var{reg}) +@deftypefn {Target Macro} int DEPRECATED_REGISTER_RAW_SIZE (int @var{reg}) The size of register number @var{reg}'s raw value. This is the number of bytes the register will occupy in @code{registers}, or in a @value{GDBN} remote protocol packet. @end deftypefn -@deftypefn {Target Macro} int REGISTER_VIRTUAL_SIZE (int @var{reg}) +@deftypefn {Target Macro} int DEPRECATED_REGISTER_VIRTUAL_SIZE (int @var{reg}) The size of register number @var{reg}'s value, in its virtual format. This is the size a @code{struct value}'s buffer will have, holding that register's value. @end deftypefn -@deftypefn {Target Macro} struct type *REGISTER_VIRTUAL_TYPE (int @var{reg}) +@deftypefn {Target Macro} struct type *DEPRECATED_REGISTER_VIRTUAL_TYPE (int @var{reg}) This is the type of the virtual representation of register number @var{reg}. Note that there is no need for a macro giving a type for the register's raw form; once the register's value has been obtained, @value{GDBN} @@ -2565,7 +2743,7 @@ always uses the virtual form. @deftypefn {Target Macro} void REGISTER_CONVERT_TO_VIRTUAL (int @var{reg}, struct type *@var{type}, char *@var{from}, char *@var{to}) Convert the value of register number @var{reg} to @var{type}, which -should always be @code{REGISTER_VIRTUAL_TYPE (@var{reg})}. The buffer +should always be @code{DEPRECATED_REGISTER_VIRTUAL_TYPE (@var{reg})}. The buffer at @var{from} holds the register's value in raw format; the macro should convert the value to virtual format, and place it at @var{to}. @@ -2580,7 +2758,7 @@ value. @deftypefn {Target Macro} void REGISTER_CONVERT_TO_RAW (struct type *@var{type}, int @var{reg}, char *@var{from}, char *@var{to}) Convert the value of register number @var{reg} to @var{type}, which -should always be @code{REGISTER_VIRTUAL_TYPE (@var{reg})}. The buffer +should always be @code{DEPRECATED_REGISTER_VIRTUAL_TYPE (@var{reg})}. The buffer at @var{from} holds the register's value in raw format; the macro should convert the value to virtual format, and place it at @var{to}. @@ -2589,6 +2767,85 @@ their @var{reg} and @var{type} arguments in different orders. @end deftypefn +@section Using Different Register and Memory Data Representations +@cindex register representation +@cindex memory representation +@cindex representations, register and memory +@cindex register data formats, converting +@cindex @code{struct value}, converting register contents to + +@emph{Maintainer's note: The way GDB manipulates registers is undergoing +significant change. Many of the macros and functions refered to in this +section are likely to be subject to further revision. See +@uref{http://sources.redhat.com/gdb/current/ari/, A.R. Index} and +@uref{http://www.gnu.org/software/gdb/bugs, Bug Tracking Database} for +further information. cagney/2002-05-06.} + +Some architectures can represent a data object in a register using a +form that is different to the objects more normal memory representation. +For example: + +@itemize @bullet + +@item +The Alpha architecture can represent 32 bit integer values in +floating-point registers. + +@item +The x86 architecture supports 80-bit floating-point registers. The +@code{long double} data type occupies 96 bits in memory but only 80 bits +when stored in a register. + +@end itemize + +In general, the register representation of a data type is determined by +the architecture, or @value{GDBN}'s interface to the architecture, while +the memory representation is determined by the Application Binary +Interface. + +For almost all data types on almost all architectures, the two +representations are identical, and no special handling is needed. +However, they do occasionally differ. Your architecture may define the +following macros to request conversions between the register and memory +representations of a data type: + +@deftypefn {Target Macro} int CONVERT_REGISTER_P (int @var{reg}) +Return non-zero if the representation of a data value stored in this +register may be different to the representation of that same data value +when stored in memory. + +When non-zero, the macros @code{REGISTER_TO_VALUE} and +@code{VALUE_TO_REGISTER} are used to perform any necessary conversion. +@end deftypefn + +@deftypefn {Target Macro} void REGISTER_TO_VALUE (int @var{reg}, struct type *@var{type}, char *@var{from}, char *@var{to}) +Convert the value of register number @var{reg} to a data object of type +@var{type}. The buffer at @var{from} holds the register's value in raw +format; the converted value should be placed in the buffer at @var{to}. + +Note that @code{REGISTER_TO_VALUE} and @code{VALUE_TO_REGISTER} take +their @var{reg} and @var{type} arguments in different orders. + +You should only use @code{REGISTER_TO_VALUE} with registers for which +the @code{CONVERT_REGISTER_P} macro returns a non-zero value. +@end deftypefn + +@deftypefn {Target Macro} void VALUE_TO_REGISTER (struct type *@var{type}, int @var{reg}, char *@var{from}, char *@var{to}) +Convert a data value of type @var{type} to register number @var{reg}' +raw format. + +Note that @code{REGISTER_TO_VALUE} and @code{VALUE_TO_REGISTER} take +their @var{reg} and @var{type} arguments in different orders. + +You should only use @code{VALUE_TO_REGISTER} with registers for which +the @code{CONVERT_REGISTER_P} macro returns a non-zero value. +@end deftypefn + +@deftypefn {Target Macro} void REGISTER_CONVERT_TO_TYPE (int @var{regnum}, struct type *@var{type}, char *@var{buf}) +See @file{mips-tdep.c}. It does not do what you want. +@end deftypefn + + @section Frame Interpretation @section Inferior Call Setup @@ -2602,18 +2859,6 @@ machine. @table @code -@item ADDITIONAL_OPTIONS -@itemx ADDITIONAL_OPTION_CASES -@itemx ADDITIONAL_OPTION_HANDLER -@itemx ADDITIONAL_OPTION_HELP -@findex ADDITIONAL_OPTION_HELP -@findex ADDITIONAL_OPTION_HANDLER -@findex ADDITIONAL_OPTION_CASES -@findex ADDITIONAL_OPTIONS -These are a set of macros that allow the addition of additional command -line options to @value{GDBN}. They are currently used only for the unsupported -i960 Nindy target, and should not be used in any other configuration. - @item ADDR_BITS_REMOVE (addr) @findex ADDR_BITS_REMOVE If a raw machine instruction address includes any bits that are not @@ -2628,6 +2873,49 @@ boundaries, the processor masks out these bits to generate the actual address of the instruction. ADDR_BITS_REMOVE should filter out these bits with an expression such as @code{((addr) & ~3)}. +@item ADDRESS_CLASS_NAME_TO_TYPE_FLAGS (@var{name}, @var{type_flags_ptr}) +@findex ADDRESS_CLASS_NAME_TO_TYPE_FLAGS +If @var{name} is a valid address class qualifier name, set the @code{int} +referenced by @var{type_flags_ptr} to the mask representing the qualifier +and return 1. If @var{name} is not a valid address class qualifier name, +return 0. + +The value for @var{type_flags_ptr} should be one of +@code{TYPE_FLAG_ADDRESS_CLASS_1}, @code{TYPE_FLAG_ADDRESS_CLASS_2}, or +possibly some combination of these values or'd together. +@xref{Target Architecture Definition, , Address Classes}. + +@item ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P () +@findex ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P +Predicate which indicates whether @code{ADDRESS_CLASS_NAME_TO_TYPE_FLAGS} +has been defined. + +@item ADDRESS_CLASS_TYPE_FLAGS (@var{byte_size}, @var{dwarf2_addr_class}) +@findex ADDRESS_CLASS_TYPE_FLAGS (@var{byte_size}, @var{dwarf2_addr_class}) +Given a pointers byte size (as described by the debug information) and +the possible @code{DW_AT_address_class} value, return the type flags +used by @value{GDBN} to represent this address class. The value +returned should be one of @code{TYPE_FLAG_ADDRESS_CLASS_1}, +@code{TYPE_FLAG_ADDRESS_CLASS_2}, or possibly some combination of these +values or'd together. +@xref{Target Architecture Definition, , Address Classes}. + +@item ADDRESS_CLASS_TYPE_FLAGS_P () +@findex ADDRESS_CLASS_TYPE_FLAGS_P +Predicate which indicates whether @code{ADDRESS_CLASS_TYPE_FLAGS} has +been defined. + +@item ADDRESS_CLASS_TYPE_FLAGS_TO_NAME (@var{type_flags}) +@findex ADDRESS_CLASS_TYPE_FLAGS_TO_NAME +Return the name of the address class qualifier associated with the type +flags given by @var{type_flags}. + +@item ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P () +@findex ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P +Predicate which indicates whether @code{ADDRESS_CLASS_TYPE_FLAGS_TO_NAME} has +been defined. +@xref{Target Architecture Definition, , Address Classes}. + @item ADDRESS_TO_POINTER (@var{type}, @var{buf}, @var{addr}) @findex ADDRESS_TO_POINTER Store in @var{buf} a pointer of type @var{type} representing the address @@ -2636,16 +2924,6 @@ This macro may safely assume that @var{type} is either a pointer or a C@t{++} reference type. @xref{Target Architecture Definition, , Pointers Are Not Always Addresses}. -@item BEFORE_MAIN_LOOP_HOOK -@findex BEFORE_MAIN_LOOP_HOOK -Define this to expand into any code that you want to execute before the -main loop starts. Although this is not, strictly speaking, a target -conditional, that is how it is currently being used. Note that if a -configuration were to define it one way for a host and a different way -for the target, @value{GDBN} will probably not compile, let alone run -correctly. This macro is currently used only for the unsupported i960 Nindy -target, and should not be used in any other configuration. - @item BELIEVE_PCC_PROMOTION @findex BELIEVE_PCC_PROMOTION Define if the compiler promotes a @code{short} or @code{char} @@ -2684,24 +2962,26 @@ Similar to BREAKPOINT, but used for bi-endian targets. @code{BIG_BREAKPOINT} and @code{LITTLE_BREAKPOINT} have been deprecated in favor of @code{BREAKPOINT_FROM_PC}. -@item REMOTE_BREAKPOINT -@itemx LITTLE_REMOTE_BREAKPOINT -@itemx BIG_REMOTE_BREAKPOINT -@findex BIG_REMOTE_BREAKPOINT -@findex LITTLE_REMOTE_BREAKPOINT -@findex REMOTE_BREAKPOINT -Similar to BREAKPOINT, but used for remote targets. - -@code{BIG_REMOTE_BREAKPOINT} and @code{LITTLE_REMOTE_BREAKPOINT} have been -deprecated in favor of @code{BREAKPOINT_FROM_PC}. +@item DEPRECATED_REMOTE_BREAKPOINT +@itemx DEPRECATED_LITTLE_REMOTE_BREAKPOINT +@itemx DEPRECATED_BIG_REMOTE_BREAKPOINT +@findex DEPRECATED_BIG_REMOTE_BREAKPOINT +@findex DEPRECATED_LITTLE_REMOTE_BREAKPOINT +@findex DEPRECATED_REMOTE_BREAKPOINT +Specify the breakpoint instruction sequence for a remote target. +@code{DEPRECATED_REMOTE_BREAKPOINT}, +@code{DEPRECATED_BIG_REMOTE_BREAKPOINT} and +@code{DEPRECATED_LITTLE_REMOTE_BREAKPOINT} have been deprecated in +favor of @code{BREAKPOINT_FROM_PC} (@pxref{BREAKPOINT_FROM_PC}). @item BREAKPOINT_FROM_PC (@var{pcptr}, @var{lenptr}) @findex BREAKPOINT_FROM_PC -Use the program counter to determine the contents and size of a -breakpoint instruction. It returns a pointer to a string of bytes -that encode a breakpoint instruction, stores the length of the string -to *@var{lenptr}, and adjusts pc (if necessary) to point to the actual -memory location where the breakpoint should be inserted. +@anchor{BREAKPOINT_FROM_PC} Use the program counter to determine the +contents and size of a breakpoint instruction. It returns a pointer to +a string of bytes that encode a breakpoint instruction, stores the +length of the string to @code{*@var{lenptr}}, and adjusts the program +counter (if necessary) to point to the actual memory location where the +breakpoint should be inserted. Although it is common to use a trap instruction for a breakpoint, it's not required; for instance, the bit pattern could be an invalid @@ -2728,45 +3008,74 @@ custom breakpoint insertion and removal routines if @code{BREAKPOINT_FROM_PC} needs to read the target's memory for some reason. -@item CALL_DUMMY_P -@findex CALL_DUMMY_P -A C expresson that is non-zero when the target suports inferior function -calls. +@item ADJUST_BREAKPOINT_ADDRESS (@var{address}) +@findex ADJUST_BREAKPOINT_ADDRESS +@cindex breakpoint address adjusted +Given an address at which a breakpoint is desired, return a breakpoint +address adjusted to account for architectural constraints on +breakpoint placement. This method is not needed by most targets. -@item CALL_DUMMY_WORDS -@findex CALL_DUMMY_WORDS +The FR-V target (see @file{frv-tdep.c}) requires this method. +The FR-V is a VLIW architecture in which a number of RISC-like +instructions are grouped (packed) together into an aggregate +instruction or instruction bundle. When the processor executes +one of these bundles, the component instructions are executed +in parallel. + +In the course of optimization, the compiler may group instructions +from distinct source statements into the same bundle. The line number +information associated with one of the latter statements will likely +refer to some instruction other than the first one in the bundle. So, +if the user attempts to place a breakpoint on one of these latter +statements, @value{GDBN} must be careful to @emph{not} place the break +instruction on any instruction other than the first one in the bundle. +(Remember though that the instructions within a bundle execute +in parallel, so the @emph{first} instruction is the instruction +at the lowest address and has nothing to do with execution order.) + +The FR-V's @code{ADJUST_BREAKPOINT_ADDRESS} method will adjust a +breakpoint's address by scanning backwards for the beginning of +the bundle, returning the address of the bundle. + +Since the adjustment of a breakpoint may significantly alter a user's +expectation, @value{GDBN} prints a warning when an adjusted breakpoint +is initially set and each time that that breakpoint is hit. + +@item DEPRECATED_CALL_DUMMY_WORDS +@findex DEPRECATED_CALL_DUMMY_WORDS Pointer to an array of @code{LONGEST} words of data containing -host-byte-ordered @code{REGISTER_BYTES} sized values that partially -specify the sequence of instructions needed for an inferior function -call. +host-byte-ordered @code{DEPRECATED_REGISTER_SIZE} sized values that +partially specify the sequence of instructions needed for an inferior +function call. Should be deprecated in favor of a macro that uses target-byte-ordered data. -@item SIZEOF_CALL_DUMMY_WORDS -@findex SIZEOF_CALL_DUMMY_WORDS -The size of @code{CALL_DUMMY_WORDS}. When @code{CALL_DUMMY_P} this must -return a positive value. See also @code{CALL_DUMMY_LENGTH}. +This method has been replaced by @code{push_dummy_code} +(@pxref{push_dummy_code}). + +@item DEPRECATED_SIZEOF_CALL_DUMMY_WORDS +@findex DEPRECATED_SIZEOF_CALL_DUMMY_WORDS +The size of @code{DEPRECATED_CALL_DUMMY_WORDS}. This must return a +positive value. See also @code{DEPRECATED_CALL_DUMMY_LENGTH}. + +This method has been replaced by @code{push_dummy_code} +(@pxref{push_dummy_code}). @item CALL_DUMMY @findex CALL_DUMMY -A static initializer for @code{CALL_DUMMY_WORDS}. Deprecated. +A static initializer for @code{DEPRECATED_CALL_DUMMY_WORDS}. +Deprecated. + +This method has been replaced by @code{push_dummy_code} +(@pxref{push_dummy_code}). @item CALL_DUMMY_LOCATION @findex CALL_DUMMY_LOCATION See the file @file{inferior.h}. -@item CALL_DUMMY_STACK_ADJUST -@findex CALL_DUMMY_STACK_ADJUST -Stack adjustment needed when performing an inferior function call. - -Should be deprecated in favor of something like @code{STACK_ALIGN}. - -@item CALL_DUMMY_STACK_ADJUST_P -@findex CALL_DUMMY_STACK_ADJUST_P -Predicate for use of @code{CALL_DUMMY_STACK_ADJUST}. - -Should be deprecated in favor of something like @code{STACK_ALIGN}. +This method has been replaced by @code{push_dummy_code} +(@pxref{push_dummy_code}). @item CANNOT_FETCH_REGISTER (@var{regno}) @findex CANNOT_FETCH_REGISTER @@ -2790,62 +3099,11 @@ and to cancel any deferred stores. Currently only implemented correctly for native Sparc configurations? -@item COERCE_FLOAT_TO_DOUBLE (@var{formal}, @var{actual}) -@findex COERCE_FLOAT_TO_DOUBLE -@cindex promotion to @code{double} -@cindex @code{float} arguments -@cindex prototyped functions, passing arguments to -@cindex passing arguments to prototyped functions -Return non-zero if GDB should promote @code{float} values to -@code{double} when calling a non-prototyped function. The argument -@var{actual} is the type of the value we want to pass to the function. -The argument @var{formal} is the type of this argument, as it appears in -the function's definition. Note that @var{formal} may be zero if we -have no debugging information for the function, or if we're passing more -arguments than are officially declared (for example, varargs). This -macro is never invoked if the function definitely has a prototype. - -How you should pass arguments to a function depends on whether it was -defined in K&R style or prototype style. If you define a function using -the K&R syntax that takes a @code{float} argument, then callers must -pass that argument as a @code{double}. If you define the function using -the prototype syntax, then you must pass the argument as a @code{float}, -with no promotion. - -Unfortunately, on certain older platforms, the debug info doesn't -indicate reliably how each function was defined. A function type's -@code{TYPE_FLAG_PROTOTYPED} flag may be unset, even if the function was -defined in prototype style. When calling a function whose -@code{TYPE_FLAG_PROTOTYPED} flag is unset, GDB consults the -@code{COERCE_FLOAT_TO_DOUBLE} macro to decide what to do. - -@findex standard_coerce_float_to_double -For modern targets, it is proper to assume that, if the prototype flag -is unset, that can be trusted: @code{float} arguments should be promoted -to @code{double}. You should use the function -@code{standard_coerce_float_to_double} to get this behavior. - -@findex default_coerce_float_to_double -For some older targets, if the prototype flag is unset, that doesn't -tell us anything. So we guess that, if we don't have a type for the -formal parameter (@i{i.e.}, the first argument to -@code{COERCE_FLOAT_TO_DOUBLE} is null), then we should promote it; -otherwise, we should leave it alone. The function -@code{default_coerce_float_to_double} provides this behavior; it is the -default value, for compatibility with older configurations. - -@item CPLUS_MARKER -@findex CPLUS_MARKERz -Define this to expand into the character that G@t{++} uses to distinguish -compiler-generated identifiers from programmer-specified identifiers. -By default, this expands into @code{'$'}. Most System V targets should -define this to @code{'.'}. - -@item DBX_PARM_SYMBOL_CLASS -@findex DBX_PARM_SYMBOL_CLASS -Hook for the @code{SYMBOL_CLASS} of a parameter when decoding DBX symbol -information. In the i960, parameters can be stored as locals or as -args, depending on the type of the debug record. +@item int CONVERT_REGISTER_P(@var{regnum}) +@findex CONVERT_REGISTER_P +Return non-zero if register @var{regnum} can represent data values in a +non-standard form. +@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. @item DECR_PC_AFTER_BREAK @findex DECR_PC_AFTER_BREAK @@ -2853,24 +3111,34 @@ Define this to be the amount by which to decrement the PC after the program encounters a breakpoint. This is often the number of bytes in @code{BREAKPOINT}, though not always. For most targets this value will be 0. -@item DECR_PC_AFTER_HW_BREAK -@findex DECR_PC_AFTER_HW_BREAK -Similarly, for hardware breakpoints. - @item DISABLE_UNSETTABLE_BREAK (@var{addr}) @findex DISABLE_UNSETTABLE_BREAK If defined, this should evaluate to 1 if @var{addr} is in a shared library in which breakpoints cannot be set and so should be disabled. -@item DO_REGISTERS_INFO -@findex DO_REGISTERS_INFO -If defined, use this to print the value of a register or all registers. - @item PRINT_FLOAT_INFO() -#findex PRINT_FLOAT_INFO +@findex PRINT_FLOAT_INFO If defined, then the @samp{info float} command will print information about the processor's floating point unit. +@item print_registers_info (@var{gdbarch}, @var{frame}, @var{regnum}, @var{all}) +@findex print_registers_info +If defined, pretty print the value of the register @var{regnum} for the +specified @var{frame}. If the value of @var{regnum} is -1, pretty print +either all registers (@var{all} is non zero) or a select subset of +registers (@var{all} is zero). + +The default method prints one register per line, and if @var{all} is +zero omits floating-point registers. + +@item PRINT_VECTOR_INFO() +@findex PRINT_VECTOR_INFO +If defined, then the @samp{info vector} command will call this function +to print information about the processor's vector unit. + +By default, the @samp{info vector} command will print all vector +registers (the register's type having the vector attribute). + @item DWARF_REG_TO_REGNUM @findex DWARF_REG_TO_REGNUM Convert DWARF register number into @value{GDBN} regnum. If not defined, @@ -2897,82 +3165,93 @@ Define this to extract a function's return value of type @var{type} from the raw register state @var{regbuf} and copy that, in virtual format, into @var{valbuf}. -@item EXTRACT_STRUCT_VALUE_ADDRESS(@var{regbuf}) -@findex EXTRACT_STRUCT_VALUE_ADDRESS +This method has been deprecated in favour of @code{gdbarch_return_value} +(@pxref{gdbarch_return_value}). + +@item DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(@var{regbuf}) +@findex DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS +@anchor{DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS} When defined, extract from the array @var{regbuf} (containing the raw register state) the @code{CORE_ADDR} at which a function should return its structure value. -If not defined, @code{EXTRACT_RETURN_VALUE} is used. +@xref{gdbarch_return_value}. -@item EXTRACT_STRUCT_VALUE_ADDRESS_P() -@findex EXTRACT_STRUCT_VALUE_ADDRESS_P -Predicate for @code{EXTRACT_STRUCT_VALUE_ADDRESS}. +@item DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P() +@findex DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P +Predicate for @code{DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS}. -@item FLOAT_INFO -@findex FLOAT_INFO -Deprecated in favor of @code{PRINT_FLOAT_INFO}. - -@item FP_REGNUM -@findex FP_REGNUM +@item DEPRECATED_FP_REGNUM +@findex DEPRECATED_FP_REGNUM If the virtual frame pointer is kept in a register, then define this macro to be the number (greater than or equal to zero) of that register. -This should only need to be defined if @code{TARGET_READ_FP} and -@code{TARGET_WRITE_FP} are not defined. +This should only need to be defined if @code{DEPRECATED_TARGET_READ_FP} +is not defined. -@item FRAMELESS_FUNCTION_INVOCATION(@var{fi}) -@findex FRAMELESS_FUNCTION_INVOCATION +@item DEPRECATED_FRAMELESS_FUNCTION_INVOCATION(@var{fi}) +@findex DEPRECATED_FRAMELESS_FUNCTION_INVOCATION Define this to an expression that returns 1 if the function invocation represented by @var{fi} does not have a stack frame associated with it. Otherwise return 0. -@item FRAME_ARGS_ADDRESS_CORRECT -@findex FRAME_ARGS_ADDRESS_CORRECT -See @file{stack.c}. +@item frame_align (@var{address}) +@anchor{frame_align} +@findex frame_align +Define this to adjust @var{address} so that it meets the alignment +requirements for the start of a new stack frame. A stack frame's +alignment requirements are typically stronger than a target processors +stack alignment requirements (@pxref{DEPRECATED_STACK_ALIGN}). -@item FRAME_CHAIN(@var{frame}) -@findex FRAME_CHAIN +This function is used to ensure that, when creating a dummy frame, both +the initial stack pointer and (if needed) the address of the return +value are correctly aligned. + +Unlike @code{DEPRECATED_STACK_ALIGN}, this function always adjusts the +address in the direction of stack growth. + +By default, no frame based stack alignment is performed. + +@item int frame_red_zone_size + +The number of bytes, beyond the innermost-stack-address, reserved by the +@sc{abi}. A function is permitted to use this scratch area (instead of +allocating extra stack space). + +When performing an inferior function call, to ensure that it does not +modify this area, @value{GDBN} adjusts the innermost-stack-address by +@var{frame_red_zone_size} bytes before pushing parameters onto the +stack. + +By default, zero bytes are allocated. The value must be aligned +(@pxref{frame_align}). + +The @sc{amd64} (nee x86-64) @sc{abi} documentation refers to the +@emph{red zone} when describing this scratch area. +@cindex red zone + +@item DEPRECATED_FRAME_CHAIN(@var{frame}) +@findex DEPRECATED_FRAME_CHAIN Given @var{frame}, return a pointer to the calling frame. -@item FRAME_CHAIN_COMBINE(@var{chain}, @var{frame}) -@findex FRAME_CHAIN_COMBINE -Define this to take the frame chain pointer and the frame's nominal -address and produce the nominal address of the caller's frame. -Presently only defined for HP PA. +@item DEPRECATED_FRAME_CHAIN_VALID(@var{chain}, @var{thisframe}) +@findex DEPRECATED_FRAME_CHAIN_VALID +Define this to be an expression that returns zero if the given frame is an +outermost frame, with no caller, and nonzero otherwise. Most normal +situations can be handled without defining this macro, including @code{NULL} +chain pointers, dummy frames, and frames whose PC values are inside the +startup file (e.g.@: @file{crt0.o}), inside @code{main}, or inside +@code{_start}. -@item FRAME_CHAIN_VALID(@var{chain}, @var{thisframe}) -@findex FRAME_CHAIN_VALID -Define this to be an expression that returns zero if the given frame is -an outermost frame, with no caller, and nonzero otherwise. Several -common definitions are available: - -@itemize @bullet -@item -@code{file_frame_chain_valid} is nonzero if the chain pointer is nonzero -and given frame's PC is not inside the startup file (such as -@file{crt0.o}). - -@item -@code{func_frame_chain_valid} is nonzero if the chain -pointer is nonzero and the given frame's PC is not in @code{main} or a -known entry point function (such as @code{_start}). - -@item -@code{generic_file_frame_chain_valid} and -@code{generic_func_frame_chain_valid} are equivalent implementations for -targets using generic dummy frames. -@end itemize - -@item FRAME_INIT_SAVED_REGS(@var{frame}) -@findex FRAME_INIT_SAVED_REGS +@item DEPRECATED_FRAME_INIT_SAVED_REGS(@var{frame}) +@findex DEPRECATED_FRAME_INIT_SAVED_REGS See @file{frame.h}. Determines the address of all registers in the current stack frame storing each in @code{frame->saved_regs}. Space for @code{frame->saved_regs} shall be allocated by -@code{FRAME_INIT_SAVED_REGS} using either -@code{frame_saved_regs_zalloc} or @code{frame_obstack_alloc}. +@code{DEPRECATED_FRAME_INIT_SAVED_REGS} using +@code{frame_saved_regs_zalloc}. -@code{FRAME_FIND_SAVED_REGS} and @code{EXTRA_FRAME_INFO} are deprecated. +@code{FRAME_FIND_SAVED_REGS} is deprecated. @item FRAME_NUM_ARGS (@var{fi}) @findex FRAME_NUM_ARGS @@ -2980,10 +3259,47 @@ For the frame described by @var{fi} return the number of arguments that are being passed. If the number of arguments is not known, return @code{-1}. -@item FRAME_SAVED_PC(@var{frame}) -@findex FRAME_SAVED_PC -Given @var{frame}, return the pc saved there. This is the return -address. +@item DEPRECATED_FRAME_SAVED_PC(@var{frame}) +@findex DEPRECATED_FRAME_SAVED_PC +@anchor{DEPRECATED_FRAME_SAVED_PC} Given @var{frame}, return the pc +saved there. This is the return address. + +This method is deprecated. @xref{unwind_pc}. + +@item CORE_ADDR unwind_pc (struct frame_info *@var{this_frame}) +@findex unwind_pc +@anchor{unwind_pc} Return the instruction address, in @var{this_frame}'s +caller, at which execution will resume after @var{this_frame} returns. +This is commonly refered to as the return address. + +The implementation, which must be frame agnostic (work with any frame), +is typically no more than: + +@smallexample +ULONGEST pc; +frame_unwind_unsigned_register (this_frame, D10V_PC_REGNUM, &pc); +return d10v_make_iaddr (pc); +@end smallexample + +@noindent +@xref{DEPRECATED_FRAME_SAVED_PC}, which this method replaces. + +@item CORE_ADDR unwind_sp (struct frame_info *@var{this_frame}) +@findex unwind_sp +@anchor{unwind_sp} Return the frame's inner most stack address. This is +commonly refered to as the frame's @dfn{stack pointer}. + +The implementation, which must be frame agnostic (work with any frame), +is typically no more than: + +@smallexample +ULONGEST sp; +frame_unwind_unsigned_register (this_frame, D10V_SP_REGNUM, &sp); +return d10v_make_daddr (sp); +@end smallexample + +@noindent +@xref{TARGET_READ_SP}, which this method replaces. @item FUNCTION_EPILOGUE_SIZE @findex FUNCTION_EPILOGUE_SIZE @@ -3018,12 +3334,12 @@ respectively. (Currently only defined for the Delta 68.) @item @value{GDBN}_MULTI_ARCH @findex @value{GDBN}_MULTI_ARCH -If defined and non-zero, enables suport for multiple architectures +If defined and non-zero, enables support for multiple architectures within @value{GDBN}. This support can be enabled at two levels. At level one, only definitions for previously undefined macros are provided; at level two, -a multi-arch definition of all architecture dependant macros will be +a multi-arch definition of all architecture dependent macros will be defined. @item @value{GDBN}_TARGET_IS_HPPA @@ -3037,31 +3353,21 @@ used instead. @findex GET_LONGJMP_TARGET For most machines, this is a target-dependent parameter. On the DECstation and the Iris, this is a native-dependent parameter, since -trhe header file @file{setjmp.h} is needed to define it. +the header file @file{setjmp.h} is needed to define it. This macro determines the target PC address that @code{longjmp} will jump to, assuming that we have just stopped at a @code{longjmp} breakpoint. It takes a @code{CORE_ADDR *} as argument, and stores the target PC value through this pointer. It examines the current state of the machine as needed. -@item GET_SAVED_REGISTER -@findex GET_SAVED_REGISTER -@findex get_saved_register +@item DEPRECATED_GET_SAVED_REGISTER +@findex DEPRECATED_GET_SAVED_REGISTER Define this if you need to supply your own definition for the function -@code{get_saved_register}. +@code{DEPRECATED_GET_SAVED_REGISTER}. -@item HAVE_REGISTER_WINDOWS -@findex HAVE_REGISTER_WINDOWS -Define this if the target has register windows. - -@item REGISTER_IN_WINDOW_P (@var{regnum}) -@findex REGISTER_IN_WINDOW_P -Define this to be an expression that is 1 if the given register is in -the window. - -@item IBM6000_TARGET -@findex IBM6000_TARGET -Shows that we are configured for an IBM RS/6000 target. This +@item DEPRECATED_IBM6000_TARGET +@findex DEPRECATED_IBM6000_TARGET +Shows that we are configured for an IBM RS/6000 system. This conditional should be eliminated (FIXME) and replaced by feature-specific macros. It was introduced in a haste and we are repenting at leisure. @@ -3080,14 +3386,14 @@ On HP-UX, certain system routines (millicode) have names beginning with @samp{$} or @samp{$$}. For example, @code{$$dyncall} is a millicode routine that handles inter-space procedure calls on PA-RISC. -@item INIT_EXTRA_FRAME_INFO (@var{fromleaf}, @var{frame}) -@findex INIT_EXTRA_FRAME_INFO +@item DEPRECATED_INIT_EXTRA_FRAME_INFO (@var{fromleaf}, @var{frame}) +@findex DEPRECATED_INIT_EXTRA_FRAME_INFO If additional information about the frame is required this should be stored in @code{frame->extra_info}. Space for @code{frame->extra_info} -is allocated using @code{frame_obstack_alloc}. +is allocated using @code{frame_extra_info_zalloc}. -@item INIT_FRAME_PC (@var{fromleaf}, @var{prev}) -@findex INIT_FRAME_PC +@item DEPRECATED_INIT_FRAME_PC (@var{fromleaf}, @var{prev}) +@findex DEPRECATED_INIT_FRAME_PC This is a C statement that sets the pc of the frame pointed to by @var{prev}. [By default...] @@ -3105,11 +3411,6 @@ The epilogue of a function is defined as the part of a function where the stack frame of the function already has been destroyed up to the final `return from function call' instruction. -@item IN_SIGTRAMP (@var{pc}, @var{name}) -@findex IN_SIGTRAMP -Define this to return non-zero if the given @var{pc} and/or @var{name} -indicates that the current function is a @code{sigtramp}. - @item SIGTRAMP_START (@var{pc}) @findex SIGTRAMP_START @itemx SIGTRAMP_END (@var{pc}) @@ -3165,18 +3466,6 @@ method like @code{INTEGER_TO_ADDRESS} certainly makes it possible for @xref{Target Architecture Definition, , Pointers Are Not Always Addresses}. -@item IS_TRAPPED_INTERNALVAR (@var{name}) -@findex IS_TRAPPED_INTERNALVAR -This is an ugly hook to allow the specification of special actions that -should occur as a side-effect of setting the value of a variable -internal to @value{GDBN}. Currently only used by the h8500. Note that this -could be either a host or target conditional. - -@item NEED_TEXT_START_END -@findex NEED_TEXT_START_END -Define this if @value{GDBN} should determine the start and end addresses of the -text section. (Seems dubious.) - @item NO_HIF_SUPPORT @findex NO_HIF_SUPPORT (Specific to the a29k.) @@ -3191,34 +3480,77 @@ address the pointer refers to. @item REGISTER_CONVERTIBLE (@var{reg}) @findex REGISTER_CONVERTIBLE Return non-zero if @var{reg} uses different raw and virtual formats. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. + +@item REGISTER_TO_VALUE(@var{regnum}, @var{type}, @var{from}, @var{to}) +@findex REGISTER_TO_VALUE +Convert the raw contents of register @var{regnum} into a value of type +@var{type}. @xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. -@item REGISTER_RAW_SIZE (@var{reg}) -@findex REGISTER_RAW_SIZE -Return the raw size of @var{reg}. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@item DEPRECATED_REGISTER_RAW_SIZE (@var{reg}) +@findex DEPRECATED_REGISTER_RAW_SIZE +Return the raw size of @var{reg}; defaults to the size of the register's +virtual type. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. -@item REGISTER_VIRTUAL_SIZE (@var{reg}) -@findex REGISTER_VIRTUAL_SIZE +@item register_reggroup_p (@var{gdbarch}, @var{regnum}, @var{reggroup}) +@findex register_reggroup_p +@cindex register groups +Return non-zero if register @var{regnum} is a member of the register +group @var{reggroup}. + +By default, registers are grouped as follows: + +@table @code +@item float_reggroup +Any register with a valid name and a floating-point type. +@item vector_reggroup +Any register with a valid name and a vector type. +@item general_reggroup +Any register with a valid name and a type other than vector or +floating-point. @samp{float_reggroup}. +@item save_reggroup +@itemx restore_reggroup +@itemx all_reggroup +Any register with a valid name. +@end table + +@item DEPRECATED_REGISTER_VIRTUAL_SIZE (@var{reg}) +@findex DEPRECATED_REGISTER_VIRTUAL_SIZE +Return the virtual size of @var{reg}; defaults to the size of the +register's virtual type. Return the virtual size of @var{reg}. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. -@item REGISTER_VIRTUAL_TYPE (@var{reg}) +@item DEPRECATED_REGISTER_VIRTUAL_TYPE (@var{reg}) @findex REGISTER_VIRTUAL_TYPE Return the virtual type of @var{reg}. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. + +@item struct type *register_type (@var{gdbarch}, @var{reg}) +@findex register_type +If defined, return the type of register @var{reg}. This function +superseeds @code{DEPRECATED_REGISTER_VIRTUAL_TYPE}. @xref{Target Architecture +Definition, , Raw and Virtual Register Representations}. @item REGISTER_CONVERT_TO_VIRTUAL(@var{reg}, @var{type}, @var{from}, @var{to}) @findex REGISTER_CONVERT_TO_VIRTUAL Convert the value of register @var{reg} from its raw form to its virtual form. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. @item REGISTER_CONVERT_TO_RAW(@var{type}, @var{reg}, @var{from}, @var{to}) @findex REGISTER_CONVERT_TO_RAW Convert the value of register @var{reg} from its virtual form to its raw form. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. + +@item const struct regset *regset_from_core_section (struct gdbarch * @var{gdbarch}, const char * @var{sect_name}, size_t @var{sect_size}) +@findex regset_from_core_section +Return the appropriate register set for a core file section with name +@var{sect_name} and size @var{sect_size}. + @item RETURN_VALUE_ON_STACK(@var{type}) @findex RETURN_VALUE_ON_STACK @@ -3304,9 +3636,17 @@ them. @findex PCC_SOL_BROKEN (Used only in the Convex target.) -@item PC_IN_CALL_DUMMY -@findex PC_IN_CALL_DUMMY -See @file{inferior.h}. +@item PC_IN_SIGTRAMP (@var{pc}, @var{name}) +@findex PC_IN_SIGTRAMP +@cindex sigtramp +The @dfn{sigtramp} is a routine that the kernel calls (which then calls +the signal handler). On most machines it is a library routine that is +linked into the executable. + +This function, given a program counter value in @var{pc} and the +(possibly NULL) name of the function in which that @var{pc} resides, +returns nonzero if the @var{pc} and/or @var{name} show that we are in +sigtramp. @item PC_LOAD_SEGMENT @findex PC_LOAD_SEGMENT @@ -3321,29 +3661,20 @@ be the number (greater than or equal to zero) of that register. This should only need to be defined if @code{TARGET_READ_PC} and @code{TARGET_WRITE_PC} are not defined. -@item NPC_REGNUM -@findex NPC_REGNUM -The number of the ``next program counter'' register, if defined. - -@item NNPC_REGNUM -@findex NNPC_REGNUM -The number of the ``next next program counter'' register, if defined. -Currently, this is only defined for the Motorola 88K. - @item PARM_BOUNDARY @findex PARM_BOUNDARY If non-zero, round arguments to a boundary of this many bits before pushing them on the stack. -@item PRINT_REGISTER_HOOK (@var{regno}) -@findex PRINT_REGISTER_HOOK -If defined, this must be a function that prints the contents of the -given register to standard output. +@item stabs_argument_has_addr (@var{gdbarch}, @var{type}) +@findex stabs_argument_has_addr +@findex DEPRECATED_REG_STRUCT_HAS_ADDR +@anchor{stabs_argument_has_addr} Define this to return nonzero if a +function argument of type @var{type} is passed by reference instead of +value. -@item PRINT_TYPELESS_INTEGER -@findex PRINT_TYPELESS_INTEGER -This is an obscure substitute for @code{print_longest} that seems to -have been defined for the Convex target. +This method replaces @code{DEPRECATED_REG_STRUCT_HAS_ADDR} +(@pxref{DEPRECATED_REG_STRUCT_HAS_ADDR}). @item PROCESS_LINENUMBER_HOOK @findex PROCESS_LINENUMBER_HOOK @@ -3358,56 +3689,125 @@ A hook defined for XCOFF reading. If defined, this is the number of the processor status register. (This definition is only used in generic code when parsing "$ps".) -@item POP_FRAME -@findex POP_FRAME -@findex call_function_by_hand -@findex return_command -Used in @samp{call_function_by_hand} to remove an artificial stack -frame and in @samp{return_command} to remove a real stack frame. +@item DEPRECATED_POP_FRAME +@findex DEPRECATED_POP_FRAME +@findex frame_pop +If defined, used by @code{frame_pop} to remove a stack frame. This +method has been superseeded by generic code. -@item PUSH_ARGUMENTS (@var{nargs}, @var{args}, @var{sp}, @var{struct_return}, @var{struct_addr}) -@findex PUSH_ARGUMENTS -Define this to push arguments onto the stack for inferior function -call. Returns the updated stack pointer value. +@item push_dummy_call (@var{gdbarch}, @var{func_addr}, @var{regcache}, @var{pc_addr}, @var{nargs}, @var{args}, @var{sp}, @var{struct_return}, @var{struct_addr}) +@findex push_dummy_call +@findex DEPRECATED_PUSH_ARGUMENTS. +@anchor{push_dummy_call} Define this to push the dummy frame's call to +the inferior function onto the stack. In addition to pushing +@var{nargs}, the code should push @var{struct_addr} (when +@var{struct_return}), and the return address (@var{bp_addr}). -@item PUSH_DUMMY_FRAME -@findex PUSH_DUMMY_FRAME +Returns the updated top-of-stack pointer. + +This method replaces @code{DEPRECATED_PUSH_ARGUMENTS}. + +@item CORE_ADDR push_dummy_code (@var{gdbarch}, @var{sp}, @var{funaddr}, @var{using_gcc}, @var{args}, @var{nargs}, @var{value_type}, @var{real_pc}, @var{bp_addr}) +@findex push_dummy_code +@findex DEPRECATED_FIX_CALL_DUMMY +@anchor{push_dummy_code} Given a stack based call dummy, push the +instruction sequence (including space for a breakpoint) to which the +called function should return. + +Set @var{bp_addr} to the address at which the breakpoint instruction +should be inserted, @var{real_pc} to the resume address when starting +the call sequence, and return the updated inner-most stack address. + +By default, the stack is grown sufficient to hold a frame-aligned +(@pxref{frame_align}) breakpoint, @var{bp_addr} is set to the address +reserved for that breakpoint, and @var{real_pc} set to @var{funaddr}. + +This method replaces @code{DEPRECATED_CALL_DUMMY_WORDS}, +@code{DEPRECATED_SIZEOF_CALL_DUMMY_WORDS}, @code{CALL_DUMMY}, +@code{CALL_DUMMY_LOCATION}, @code{DEPRECATED_REGISTER_SIZE}, +@code{GDB_TARGET_IS_HPPA}, +@code{DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET}, and +@code{DEPRECATED_FIX_CALL_DUMMY}. + +@item DEPRECATED_PUSH_DUMMY_FRAME +@findex DEPRECATED_PUSH_DUMMY_FRAME Used in @samp{call_function_by_hand} to create an artificial stack frame. -@item REGISTER_BYTES -@findex REGISTER_BYTES -The total amount of space needed to store @value{GDBN}'s copy of the machine's -register state. +@item DEPRECATED_REGISTER_BYTES +@findex DEPRECATED_REGISTER_BYTES +The total amount of space needed to store @value{GDBN}'s copy of the +machine's register state. + +This is no longer needed. @value{GDBN} instead computes the size of the +register buffer at run-time. @item REGISTER_NAME(@var{i}) @findex REGISTER_NAME Return the name of register @var{i} as a string. May return @code{NULL} or @code{NUL} to indicate that register @var{i} is not valid. -@item REGISTER_NAMES -@findex REGISTER_NAMES -Deprecated in favor of @code{REGISTER_NAME}. +@item DEPRECATED_REG_STRUCT_HAS_ADDR (@var{gcc_p}, @var{type}) +@findex DEPRECATED_REG_STRUCT_HAS_ADDR +@anchor{DEPRECATED_REG_STRUCT_HAS_ADDR}Define this to return 1 if the +given type will be passed by pointer rather than directly. -@item REG_STRUCT_HAS_ADDR (@var{gcc_p}, @var{type}) -@findex REG_STRUCT_HAS_ADDR -Define this to return 1 if the given type will be passed by pointer -rather than directly. +This method has been replaced by @code{stabs_argument_has_addr} +(@pxref{stabs_argument_has_addr}). @item SAVE_DUMMY_FRAME_TOS (@var{sp}) @findex SAVE_DUMMY_FRAME_TOS -Used in @samp{call_function_by_hand} to notify the target dependent code -of the top-of-stack value that will be passed to the the inferior code. -This is the value of the @code{SP} after both the dummy frame and space -for parameters/results have been allocated on the stack. +@anchor{SAVE_DUMMY_FRAME_TOS} Used in @samp{call_function_by_hand} to +notify the target dependent code of the top-of-stack value that will be +passed to the the inferior code. This is the value of the @code{SP} +after both the dummy frame and space for parameters/results have been +allocated on the stack. @xref{unwind_dummy_id}. @item SDB_REG_TO_REGNUM @findex SDB_REG_TO_REGNUM Define this to convert sdb register numbers into @value{GDBN} regnums. If not defined, no conversion will be done. -@item SHIFT_INST_REGS -@findex SHIFT_INST_REGS -(Only used for m88k targets.) +@item enum return_value_convention gdbarch_return_value (struct gdbarch *@var{gdbarch}, struct type *@var{valtype}, struct regcache *@var{regcache}, void *@var{readbuf}, const void *@var{writebuf}) +@findex gdbarch_return_value +@anchor{gdbarch_return_value} Given a function with a return-value of +type @var{rettype}, return which return-value convention that function +would use. + +@value{GDBN} currently recognizes two function return-value conventions: +@code{RETURN_VALUE_REGISTER_CONVENTION} where the return value is found +in registers; and @code{RETURN_VALUE_STRUCT_CONVENTION} where the return +value is found in memory and the address of that memory location is +passed in as the function's first parameter. + +If the register convention is being used, and @var{writebuf} is +non-@code{NULL}, also copy the return-value in @var{writebuf} into +@var{regcache}. + +If the register convention is being used, and @var{readbuf} is +non-@code{NULL}, also copy the return value from @var{regcache} into +@var{readbuf} (@var{regcache} contains a copy of the registers from the +just returned function). + +@xref{DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS}, for a description of how +return-values that use the struct convention are handled. + +@emph{Maintainer note: This method replaces separate predicate, extract, +store methods. By having only one method, the logic needed to determine +the return-value convention need only be implemented in one place. If +@value{GDBN} were written in an @sc{oo} language, this method would +instead return an object that knew how to perform the register +return-value extract and store.} + +@emph{Maintainer note: This method does not take a @var{gcc_p} +parameter, and such a parameter should not be added. If an architecture +that requires per-compiler or per-function information be identified, +then the replacement of @var{rettype} with @code{struct value} +@var{function} should be persued.} + +@emph{Maintainer note: The @var{regcache} parameter limits this methods +to the inner most frame. While replacing @var{regcache} with a +@code{struct frame_info} @var{frame} parameter would remove that +limitation there has yet to be a demonstrated need for such a change.} @item SKIP_PERMANENT_BREAKPOINT @findex SKIP_PERMANENT_BREAKPOINT @@ -3425,12 +3825,6 @@ of a branch or jump. A C expression that returns the address of the ``real'' code beyond the function entry prologue found at @var{pc}. -@item SKIP_PROLOGUE_FRAMELESS_P -@findex SKIP_PROLOGUE_FRAMELESS_P -A C expression that should behave similarly, but that can stop as soon -as the function is known to have a frame. If not defined, -@code{SKIP_PROLOGUE} will be used instead. - @item SKIP_TRAMPOLINE_CODE (@var{pc}) @findex SKIP_TRAMPOLINE_CODE If the target machine has trampoline code that sits between callers and @@ -3440,10 +3834,8 @@ that is at the start of the real function. @item SP_REGNUM @findex SP_REGNUM If the stack-pointer is kept in a register, then define this macro to be -the number (greater than or equal to zero) of that register. - -This should only need to be defined if @code{TARGET_WRITE_SP} and -@code{TARGET_WRITE_SP} are not defined. +the number (greater than or equal to zero) of that register, or -1 if +there is no such register. @item STAB_REG_TO_REGNUM @findex STAB_REG_TO_REGNUM @@ -3451,10 +3843,16 @@ Define this to convert stab register numbers (as gotten from `r' declarations) into @value{GDBN} regnums. If not defined, no conversion will be done. -@item STACK_ALIGN (@var{addr}) -@findex STACK_ALIGN -Define this to adjust the address to the alignment required for the -processor's stack. +@item DEPRECATED_STACK_ALIGN (@var{addr}) +@anchor{DEPRECATED_STACK_ALIGN} +@findex DEPRECATED_STACK_ALIGN +Define this to increase @var{addr} so that it meets the alignment +requirements for the processor's stack. + +Unlike @ref{frame_align}, this function always adjusts @var{addr} +upwards. + +By default, no stack alignment is performed. @item STEP_SKIPS_DELAY (@var{addr}) @findex STEP_SKIPS_DELAY @@ -3463,10 +3861,14 @@ delay slot. If a breakpoint has been placed in the instruction's delay slot, @value{GDBN} will single-step over that instruction before resuming normally. Currently only defined for the Mips. -@item STORE_RETURN_VALUE (@var{type}, @var{valbuf}) +@item STORE_RETURN_VALUE (@var{type}, @var{regcache}, @var{valbuf}) @findex STORE_RETURN_VALUE -A C expression that stores a function return value of type @var{type}, -where @var{valbuf} is the address of the value to be stored. +A C expression that writes the function return value, found in +@var{valbuf}, into the @var{regcache}. @var{type} is the type of the +value that is to be returned. + +This method has been deprecated in favour of @code{gdbarch_return_value} +(@pxref{gdbarch_return_value}). @item SUN_FIXED_LBRAC_BUG @findex SUN_FIXED_LBRAC_BUG @@ -3541,35 +3943,32 @@ Number of bits in a short integer; defaults to @code{2 * TARGET_CHAR_BIT}. @findex TARGET_READ_PC @itemx TARGET_WRITE_PC (@var{val}, @var{pid}) @findex TARGET_WRITE_PC +@anchor{TARGET_WRITE_PC} @itemx TARGET_READ_SP @findex TARGET_READ_SP -@itemx TARGET_WRITE_SP -@findex TARGET_WRITE_SP @itemx TARGET_READ_FP @findex TARGET_READ_FP -@itemx TARGET_WRITE_FP -@findex TARGET_WRITE_FP @findex read_pc @findex write_pc @findex read_sp -@findex write_sp @findex read_fp -@findex write_fp -These change the behavior of @code{read_pc}, @code{write_pc}, -@code{read_sp}, @code{write_sp}, @code{read_fp} and @code{write_fp}. -For most targets, these may be left undefined. @value{GDBN} will call the read +@anchor{TARGET_READ_SP} These change the behavior of @code{read_pc}, +@code{write_pc}, @code{read_sp} and @code{deprecated_read_fp}. For most +targets, these may be left undefined. @value{GDBN} will call the read and write register functions with the relevant @code{_REGNUM} argument. These macros are useful when a target keeps one of these registers in a hard to get at place; for example, part in a segment register and part in an ordinary register. +@xref{unwind_sp}, which replaces @code{TARGET_READ_SP}. + @item TARGET_VIRTUAL_FRAME_POINTER(@var{pc}, @var{regp}, @var{offsetp}) @findex TARGET_VIRTUAL_FRAME_POINTER -Returns a @code{(register, offset)} pair representing the virtual -frame pointer in use at the code address @var{pc}. If virtual -frame pointers are not used, a default definition simply returns -@code{FP_REGNUM}, with an offset of zero. +Returns a @code{(register, offset)} pair representing the virtual frame +pointer in use at the code address @var{pc}. If virtual frame pointers +are not used, a default definition simply returns +@code{DEPRECATED_FP_REGNUM}, with an offset of zero. @item TARGET_HAS_HARDWARE_WATCHPOINTS If non-zero, the target has support for hardware-assisted @@ -3582,11 +3981,20 @@ This is the function used by @value{GDBN} to print an assembly instruction. It prints the instruction at address @var{addr} in debugged memory and returns the length of the instruction, in bytes. If a target doesn't define its own printing routine, it defaults to an -accessor function for the global pointer @code{tm_print_insn}. This -usually points to a function in the @code{opcodes} library (@pxref{Support -Libraries, ,Opcodes}). @var{info} is a structure (of type -@code{disassemble_info}) defined in @file{include/dis-asm.h} used to -pass information to the instruction decoding routine. +accessor function for the global pointer +@code{deprecated_tm_print_insn}. This usually points to a function in +the @code{opcodes} library (@pxref{Support Libraries, ,Opcodes}). +@var{info} is a structure (of type @code{disassemble_info}) defined in +@file{include/dis-asm.h} used to pass information to the instruction +decoding routine. + +@item struct frame_id unwind_dummy_id (struct frame_info *@var{frame}) +@findex unwind_dummy_id +@anchor{unwind_dummy_id} Given @var{frame} return a @code{struct +frame_id} that uniquely identifies an inferior function call's dummy +frame. The value returned must match the dummy frame stack value +previously saved using @code{SAVE_DUMMY_FRAME_TOS}. +@xref{SAVE_DUMMY_FRAME_TOS}. @item USE_STRUCT_CONVENTION (@var{gcc_p}, @var{type}) @findex USE_STRUCT_CONVENTION @@ -3597,6 +4005,15 @@ being considered is known to have been compiled by GCC; this is helpful for systems where GCC is known to use different calling convention than other compilers. +This method has been deprecated in favour of @code{gdbarch_return_value} +(@pxref{gdbarch_return_value}). + +@item VALUE_TO_REGISTER(@var{type}, @var{regnum}, @var{from}, @var{to}) +@findex VALUE_TO_REGISTER +Convert a value of type @var{type} into the raw contents of register +@var{regnum}'s. +@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. + @item VARIABLES_INSIDE_BLOCK (@var{desc}, @var{gcc_p}) @findex VARIABLES_INSIDE_BLOCK For dbx-style debugging information, if the compiler puts variable @@ -3620,6 +4037,12 @@ not defined, it will default to @code{0xf}. @item REMOTE_BPT_VECTOR Defaults to @code{1}. + +@item NAME_OF_MALLOC +@findex NAME_OF_MALLOC +A string containing the name of the function to call in order to +allocate some memory in the inferior. The default value is "malloc". + @end ftable @section Adding a New Target @@ -3680,6 +4103,166 @@ that just @code{#include}s @file{tm-@var{arch}.h} and @file{config/tm-@var{os}.h}. +@section Converting an existing Target Architecture to Multi-arch +@cindex converting targets to multi-arch + +This section describes the current accepted best practice for converting +an existing target architecture to the multi-arch framework. + +The process consists of generating, testing, posting and committing a +sequence of patches. Each patch must contain a single change, for +instance: + +@itemize @bullet + +@item +Directly convert a group of functions into macros (the conversion does +not change the behavior of any of the functions). + +@item +Replace a non-multi-arch with a multi-arch mechanism (e.g., +@code{FRAME_INFO}). + +@item +Enable multi-arch level one. + +@item +Delete one or more files. + +@end itemize + +@noindent +There isn't a size limit on a patch, however, a developer is strongly +encouraged to keep the patch size down. + +Since each patch is well defined, and since each change has been tested +and shows no regressions, the patches are considered @emph{fairly} +obvious. Such patches, when submitted by developers listed in the +@file{MAINTAINERS} file, do not need approval. Occasional steps in the +process may be more complicated and less clear. The developer is +expected to use their judgment and is encouraged to seek advice as +needed. + +@subsection Preparation + +The first step is to establish control. Build (with @option{-Werror} +enabled) and test the target so that there is a baseline against which +the debugger can be compared. + +At no stage can the test results regress or @value{GDBN} stop compiling +with @option{-Werror}. + +@subsection Add the multi-arch initialization code + +The objective of this step is to establish the basic multi-arch +framework. It involves + +@itemize @bullet + +@item +The addition of a @code{@var{arch}_gdbarch_init} function@footnote{The +above is from the original example and uses K&R C. @value{GDBN} +has since converted to ISO C but lets ignore that.} that creates +the architecture: +@smallexample +static struct gdbarch * +d10v_gdbarch_init (info, arches) + struct gdbarch_info info; + struct gdbarch_list *arches; +@{ + struct gdbarch *gdbarch; + /* there is only one d10v architecture */ + if (arches != NULL) + return arches->gdbarch; + gdbarch = gdbarch_alloc (&info, NULL); + return gdbarch; +@} +@end smallexample +@noindent +@emph{} + +@item +A per-architecture dump function to print any architecture specific +information: +@smallexample +static void +mips_dump_tdep (struct gdbarch *current_gdbarch, + struct ui_file *file) +@{ + @dots{} code to print architecture specific info @dots{} +@} +@end smallexample + +@item +A change to @code{_initialize_@var{arch}_tdep} to register this new +architecture: +@smallexample +void +_initialize_mips_tdep (void) +@{ + gdbarch_register (bfd_arch_mips, mips_gdbarch_init, + mips_dump_tdep); +@end smallexample + +@item +Add the macro @code{GDB_MULTI_ARCH}, defined as 0 (zero), to the file@* +@file{config/@var{arch}/tm-@var{arch}.h}. + +@end itemize + +@subsection Update multi-arch incompatible mechanisms + +Some mechanisms do not work with multi-arch. They include: + +@table @code +@item FRAME_FIND_SAVED_REGS +Replaced with @code{DEPRECATED_FRAME_INIT_SAVED_REGS} +@end table + +@noindent +At this stage you could also consider converting the macros into +functions. + +@subsection Prepare for multi-arch level to one + +Temporally set @code{GDB_MULTI_ARCH} to @code{GDB_MULTI_ARCH_PARTIAL} +and then build and start @value{GDBN} (the change should not be +committed). @value{GDBN} may not build, and once built, it may die with +an internal error listing the architecture methods that must be +provided. + +Fix any build problems (patch(es)). + +Convert all the architecture methods listed, which are only macros, into +functions (patch(es)). + +Update @code{@var{arch}_gdbarch_init} to set all the missing +architecture methods and wrap the corresponding macros in @code{#if +!GDB_MULTI_ARCH} (patch(es)). + +@subsection Set multi-arch level one + +Change the value of @code{GDB_MULTI_ARCH} to GDB_MULTI_ARCH_PARTIAL (a +single patch). + +Any problems with throwing ``the switch'' should have been fixed +already. + +@subsection Convert remaining macros + +Suggest converting macros into functions (and setting the corresponding +architecture method) in small batches. + +@subsection Set multi-arch level to two + +This should go smoothly. + +@subsection Delete the TM file + +The @file{tm-@var{arch}.h} can be deleted. @file{@var{arch}.mt} and +@file{configure.in} updated. + + @node Target Vector Definition @chapter Target Vector Definition @@ -3770,7 +4353,7 @@ define @samp{NAT_CFLAGS}, @samp{NAT_ADD_FILES}, @samp{NAT_CLIBS}, @emph{Maintainer's note: The @file{.mh} suffix is because this file originally contained @file{Makefile} fragments for hosting @value{GDBN} on machine @var{xyz}. While the file is no longer used for this -purpose, the @file{.mh} suffix remains. Perhaphs someone will +purpose, the @file{.mh} suffix remains. Perhaps someone will eventually rename these fragments so that they have a @file{.mn} suffix.} @@ -3961,23 +4544,6 @@ root directory. Define this to be able to, when a breakpoint insertion fails, warn the user that another process may be running with the same executable. -@item PREPARE_TO_PROCEED (@var{select_it}) -@findex PREPARE_TO_PROCEED -This (ugly) macro allows a native configuration to customize the way the -@code{proceed} function in @file{infrun.c} deals with switching between -threads. - -In a multi-threaded task we may select another thread and then continue -or step. But if the old thread was stopped at a breakpoint, it will -immediately cause another breakpoint stop without any execution (i.e. it -will report a breakpoint hit incorrectly). So @value{GDBN} must step over it -first. - -If defined, @code{PREPARE_TO_PROCEED} should check the current thread -against the thread that reported the most recent event. If a step-over -is required, it returns TRUE. If @var{select_it} is non-zero, it should -reselect the old thread. - @item PROC_NAME_FMT @findex PROC_NAME_FMT Defines the format for the name of a @file{/proc} device. Should be @@ -4106,6 +4672,66 @@ library because it's also used in binutils, for @file{objdump}). @section mmalloc @section libiberty +@cindex @code{libiberty} library + +The @code{libiberty} library provides a set of functions and features +that integrate and improve on functionality found in modern operating +systems. Broadly speaking, such features can be divided into three +groups: supplemental functions (functions that may be missing in some +environments and operating systems), replacement functions (providing +a uniform and easier to use interface for commonly used standard +functions), and extensions (which provide additional functionality +beyond standard functions). + +@value{GDBN} uses various features provided by the @code{libiberty} +library, for instance the C@t{++} demangler, the @acronym{IEEE} +floating format support functions, the input options parser +@samp{getopt}, the @samp{obstack} extension, and other functions. + +@subsection @code{obstacks} in @value{GDBN} +@cindex @code{obstacks} + +The obstack mechanism provides a convenient way to allocate and free +chunks of memory. Each obstack is a pool of memory that is managed +like a stack. Objects (of any nature, size and alignment) are +allocated and freed in a @acronym{LIFO} fashion on an obstack (see +@code{libiberty}'s documenatation for a more detailed explanation of +@code{obstacks}). + +The most noticeable use of the @code{obstacks} in @value{GDBN} is in +object files. There is an obstack associated with each internal +representation of an object file. Lots of things get allocated on +these @code{obstacks}: dictionary entries, blocks, blockvectors, +symbols, minimal symbols, types, vectors of fundamental types, class +fields of types, object files section lists, object files section +offets lists, line tables, symbol tables, partial symbol tables, +string tables, symbol table private data, macros tables, debug +information sections and entries, import and export lists (som), +unwind information (hppa), dwarf2 location expressions data. Plus +various strings such as directory names strings, debug format strings, +names of types. + +An essential and convenient property of all data on @code{obstacks} is +that memory for it gets allocated (with @code{obstack_alloc}) at +various times during a debugging sesssion, but it is released all at +once using the @code{obstack_free} function. The @code{obstack_free} +function takes a pointer to where in the stack it must start the +deletion from (much like the cleanup chains have a pointer to where to +start the cleanups). Because of the stack like structure of the +@code{obstacks}, this allows to free only a top portion of the +obstack. There are a few instances in @value{GDBN} where such thing +happens. Calls to @code{obstack_free} are done after some local data +is allocated to the obstack. Only the local data is deleted from the +obstack. Of course this assumes that nothing between the +@code{obstack_alloc} and the @code{obstack_free} allocates anything +else on the same obstack. For this reason it is best and safest to +use temporary @code{obstacks}. + +Releasing the whole obstack is also not safe per se. It is safe only +under the condition that we know the @code{obstacks} memory is no +longer needed. In @value{GDBN} we get rid of the @code{obstacks} only +when we get rid of the whole objfile(s), for instance upon reading a +new symbol file. @section gnu-regex @cindex regular expressions library @@ -4185,7 +4811,7 @@ Cleanups are implemented as a chain. The handle returned by later cleanups appended to the chain (but not yet discarded or performed). E.g.: -@example +@smallexample make_cleanup (a, 0); @{ struct cleanup *old = make_cleanup (b, 0); @@ -4193,7 +4819,7 @@ make_cleanup (a, 0); ... do_cleanups (old); @} -@end example +@end smallexample @noindent will call @code{c()} and @code{b()} but will not call @code{a()}. The @@ -4212,13 +4838,13 @@ code-segment avoids a memory leak problem (even when @code{error} is called and a forced stack unwind occurs) by ensuring that the @code{xfree} will always be called: -@example +@smallexample struct cleanup *old = make_cleanup (null_cleanup, 0); data = xmalloc (sizeof blah); make_cleanup (xfree, data); ... blah blah ... do_cleanups (old); -@end example +@end smallexample The second style is try/except. Before it exits, your code-block calls @code{discard_cleanups} with the old cleanup chain and thus ensures that @@ -4226,13 +4852,13 @@ any created cleanups are not performed. For instance, the following code segment, ensures that the file will be closed but only if there is an error: -@example +@smallexample FILE *file = fopen ("afile", "r"); struct cleanup *old = make_cleanup (close_file, file); ... blah blah ... discard_cleanups (old); return file; -@end example +@end smallexample Some functions, e.g. @code{fputs_filtered()} or @code{error()}, specify that they ``should not be called when cleanups are not in place''. This @@ -4241,6 +4867,139 @@ interruption must be on the cleanup chain before you call these functions, since they might never return to your code (they @samp{longjmp} instead). +@section Per-architecture module data +@cindex per-architecture module data +@cindex multi-arch data +@cindex data-pointer, per-architecture/per-module + +The multi-arch framework includes a mechanism for adding module specific +per-architecture data-pointers to the @code{struct gdbarch} architecture +object. + +A module registers one or more per-architecture data-pointers using the +function @code{register_gdbarch_data}: + +@deftypefun struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *@var{init}) + +The @var{init} function is used to obtain an initial value for a +per-architecture data-pointer. The function is called, after the +architecture has been created, when the data-pointer is still +uninitialized (@code{NULL}) and its value has been requested via a call +to @code{gdbarch_data}. A data-pointer can also be initialize +explicitly using @code{set_gdbarch_data}. + +Any memory required by the @var{init} function should be allocated +using @code{GDBARCH_OBSTACK_ZALLOC}. That memory is automatically +released when the corresponding architecture is deleted. + +The function @code{register_gdbarch_data} returns a @code{struct +gdbarch_data} that is used to identify the data-pointer that was added +to the module. + +@end deftypefun + +A typical module has an @code{init} function of the form: + +@smallexample +struct nozel @{ int total; @}; +static struct gdbarch_data *nozel_handle; +static void * +nozel_init (struct gdbarch *gdbarch) +@{ + struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel); + @dots{} + return data; +@} +@end smallexample + +Since uninitialized (@code{NULL}) data-pointers are initialized +on-demand, an @code{init} function is free to call other modules that +use data-pointers. Those modules data-pointers will be initialized as +needed. Care should be taken to ensure that the @code{init} call graph +does not contain cycles. + +The data-pointer is registered with the call: + +@smallexample +void +_initialize_nozel (void) +@{ + nozel_handle = register_gdbarch_data (nozel_init); +@dots{} +@end smallexample + +The per-architecture data-pointer is accessed using the function: + +@deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle}) +Given the architecture @var{arch} and module data handle +@var{data_handle} (returned by @code{register_gdbarch_data}, this +function returns the current value of the per-architecture data-pointer. +@end deftypefun + +The non-@code{NULL} data-pointer returned by @code{gdbarch_data} should +be saved in a local variable and then used directly: + +@smallexample +int +nozel_total (struct gdbarch *gdbarch) +@{ + int total; + struct nozel *data = gdbarch_data (gdbarch, nozel_handle); + @dots{} + return total; +@} +@end smallexample + +It is also possible to directly initialize the data-pointer using: + +@deftypefun void set_gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{handle}, void *@var{pointer}) +Set the still @code{NULL} data-pointer corresponding to @var{handle} +to the non-@code{NULL} @var{pointer} value. +@end deftypefun + +This function is used by modules that require a mechanism for explicitly +setting the per-architecture data-pointer during architecture creation: + +@smallexample +/* Always return a non-NULL nozel. */ +static struct nozel * +gdbarch_nozel (struct gdbarch *gdbarch) +@{ + struct nozel *nozel = gdbarch_data (gdbarch, nozel_handle); + if (nozel == NULL) + @{ + nozel = nozel_init (gdbarch); + set_gdbarch_data (gdbarch, nozel_handle, nozel); + @} + return nozel; +@} +@end smallexample + +@smallexample +/* Called during architecture creation. */ +extern void +set_gdbarch_nozel (struct gdbarch *gdbarch, int total) +@{ + struct nozel *data = gdbarch_nozel (gdbarch); + @dots{} + data->total = total; +@} +@end smallexample + +@smallexample +void +_initialize_nozel (void) +@{ + nozel_handle = register_gdbarch_data (nozel_init); + @dots{} +@end smallexample + +@noindent +Note that an @code{init} function still needs to be registered. It is +used to initialize the data-pointer when the architecture creation phase +fail to set an initial value. + + @section Wrapping Output Lines @cindex line wrap in output @@ -4281,11 +5040,12 @@ but does not require it, @value{GDBN} requires it. @value{GDBN}, as described in the following sections. -@subsection ISO-C +@subsection ISO C -@value{GDBN} assumes an ISO-C compliant compiler. +@value{GDBN} assumes an ISO/IEC 9899:1990 (a.k.a.@: ISO C90) compliant +compiler. -@value{GDBN} does not assume an ISO-C or POSIX compliant C library. +@value{GDBN} does not assume an ISO C or POSIX compliant C library. @subsection Memory Management @@ -4355,8 +5115,9 @@ that use register windows. @item -Wtrigraphs @item -Wformat +@itemx -Wformat-nonliteral Since @value{GDBN} uses the @code{format printf} attribute on all -@code{printf} like functions this checks not just @code{printf} calls +@code{printf} like functions these check not just @code{printf} calls but also calls to functions such as @code{fprintf_unfiltered}. @item -Wparentheses @@ -4366,6 +5127,25 @@ This warning includes uses of the assignment operator within an @item -Wpointer-arith @item -Wuninitialized + +@item -Wunused-label +This warning has the additional benefit of detecting the absence of the +@code{case} reserved word in a switch statement: +@smallexample +enum @{ FD_SCHEDULED, NOTHING_SCHEDULED @} sched; +@dots{} +switch (sched) + @{ + case FD_SCHEDULED: + @dots{}; + break; + NOTHING_SCHEDULED: + @dots{}; + break; + @} +@end smallexample + +@item -Wunused-function @end table @emph{Pragmatics: Due to the way that @value{GDBN} is implemented most @@ -4389,7 +5169,7 @@ strictly. A function declaration should not have its name in column zero. A function definition should have its name in column zero. -@example +@smallexample /* Declaration */ static void foo (void); /* Definition */ @@ -4397,7 +5177,7 @@ void foo (void) @{ @} -@end example +@end smallexample @emph{Pragmatics: This simplifies scripting. Function definitions can be found using @samp{^function-name}.} @@ -4415,17 +5195,17 @@ for @code{diff} and @code{patch} utilities. Pointers are declared using the traditional K&R C style: -@example +@smallexample void *foo; -@end example +@end smallexample @noindent and not: -@example +@smallexample void * foo; void* foo; -@end example +@end smallexample @subsection Comments @@ -4435,13 +5215,13 @@ The standard GNU requirements on comments must be followed strictly. Block comments must appear in the following form, with no @code{/*}- or @code{*/}-only lines, and no leading @code{*}: -@example +@smallexample /* Wait for control to return from inferior to debugger. If inferior gets a signal, we may decide to start it up again instead of returning. That is why there is a loop in this function. When this function actually returns it means the inferior should be left stopped and @value{GDBN} should read more commands. */ -@end example +@end smallexample (Note that this format is encouraged by Emacs; tabbing for a multi-line comment works correctly, and @kbd{M-q} fills the block consistently.) @@ -4503,8 +5283,8 @@ During its execution, @value{GDBN} can encounter two types of errors. User errors and internal errors. User errors include not only a user entering an incorrect command but also problems arising from corrupt object files and system errors when interacting with the target. -Internal errors include situtations where @value{GDBN} has detected, at -run time, a corrupt or erroneous situtation. +Internal errors include situations where @value{GDBN} has detected, at +run time, a corrupt or erroneous situation. When reporting an internal error, @value{GDBN} uses @code{internal_error} and @code{gdb_assert}. @@ -4537,33 +5317,48 @@ of @value{GDBN}) must be added to @file{gdb/config/djgpp/fnchange.lst}. When @value{GDBN} has a local version of a system header file (ex @file{string.h}) the file name based on the POSIX header prefixed with -@file{gdb_} (@file{gdb_string.h}). +@file{gdb_} (@file{gdb_string.h}). These headers should be relatively +independent: they should use only macros defined by @file{configure}, +the compiler, or the host; they should include only system headers; they +should refer only to system types. They may be shared between multiple +programs, e.g.@: @value{GDBN} and @sc{gdbserver}. For other files @samp{-} is used as the separator. @subsection Include Files -All @file{.c} files should include @file{defs.h} first. +A @file{.c} file should include @file{defs.h} first. -All @file{.c} files should explicitly include the headers for any -declarations they refer to. They should not rely on files being -included indirectly. +A @file{.c} file should directly include the @code{.h} file of every +declaration and/or definition it directly refers to. It cannot rely on +indirect inclusion. -With the exception of the global definitions supplied by @file{defs.h}, -a header file should explictily include the header declaring any -@code{typedefs} et.al.@: it refers to. +A @file{.h} file should directly include the @code{.h} file of every +declaration and/or definition it directly refers to. It cannot rely on +indirect inclusion. Exception: The file @file{defs.h} does not need to +be directly included. -@code{extern} declarations should never appear in @code{.c} files. +An external declaration should only appear in one include file. -All include files should be wrapped in: +An external declaration should never appear in a @code{.c} file. +Exception: a declaration for the @code{_initialize} function that +pacifies @option{-Wmissing-declaration}. -@example +A @code{typedef} definition should only appear in one include file. + +An opaque @code{struct} declaration can appear in multiple @file{.h} +files. Where possible, a @file{.h} file should use an opaque +@code{struct} declaration instead of an include. + +All @file{.h} files should be wrapped in: + +@smallexample #ifndef INCLUDE_FILE_NAME_H #define INCLUDE_FILE_NAME_H header body #endif -@end example +@end smallexample @subsection Clean Design and Portable Implementation @@ -4723,16 +5518,16 @@ vendors, and operating systems near the bottom of the file. Also, add @code{@var{arch}-@var{xvend}-@var{xos}}. You can test your changes by running -@example +@smallexample ./config.sub @var{xyz} -@end example +@end smallexample @noindent and -@example +@smallexample ./config.sub @code{@var{arch}-@var{xvend}-@var{xos}} -@end example +@end smallexample @noindent which should both respond with @code{@var{arch}-@var{xvend}-@var{xos}} @@ -4762,103 +5557,188 @@ target-dependent @file{.h} and @file{.c} files used for your configuration. @end itemize -@section Configuring @value{GDBN} for Release - -@cindex preparing a release -@cindex making a distribution tarball -From the top level directory (containing @file{gdb}, @file{bfd}, -@file{libiberty}, and so on): - -@example -make -f Makefile.in gdb.tar.gz -@end example - -@noindent -This will properly configure, clean, rebuild any files that are -distributed pre-built (e.g. @file{c-exp.tab.c} or @file{refcard.ps}), -and will then make a tarfile. (If the top level directory has already -been configured, you can just do @code{make gdb.tar.gz} instead.) - -This procedure requires: - -@itemize @bullet - -@item -symbolic links; - -@item -@code{makeinfo} (texinfo2 level); - -@item -@TeX{}; - -@item -@code{dvips}; - -@item -@code{yacc} or @code{bison}. -@end itemize - -@noindent -@dots{} and the usual slew of utilities (@code{sed}, @code{tar}, etc.). - -@subheading TEMPORARY RELEASE PROCEDURE FOR DOCUMENTATION - -@file{gdb.texinfo} is currently marked up using the texinfo-2 macros, -which are not yet a default for anything (but we have to start using -them sometime). - -For making paper, the only thing this implies is the right generation of -@file{texinfo.tex} needs to be included in the distribution. - -For making info files, however, rather than duplicating the texinfo2 -distribution, generate @file{gdb-all.texinfo} locally, and include the -files @file{gdb.info*} in the distribution. Note the plural; -@code{makeinfo} will split the document into one overall file and five -or so included files. - @node Releasing GDB @chapter Releasing @value{GDBN} @cindex making a new release of gdb -@section Obsolete any code +@section Versions and Branches + +@subsection Version Identifiers + +@value{GDBN}'s version is determined by the file @file{gdb/version.in}. + +@value{GDBN}'s mainline uses ISO dates to differentiate between +versions. The CVS repository uses @var{YYYY}-@var{MM}-@var{DD}-cvs +while the corresponding snapshot uses @var{YYYYMMDD}. + +@value{GDBN}'s release branch uses a slightly more complicated scheme. +When the branch is first cut, the mainline version identifier is +prefixed with the @var{major}.@var{minor} from of the previous release +series but with .90 appended. As draft releases are drawn from the +branch, the minor minor number (.90) is incremented. Once the first +release (@var{M}.@var{N}) has been made, the version prefix is updated +to @var{M}.@var{N}.0.90 (dot zero, dot ninety). Follow on releases have +an incremented minor minor version number (.0). + +Using 5.1 (previous) and 5.2 (current), the example below illustrates a +typical sequence of version identifiers: + +@table @asis +@item 5.1.1 +final release from previous branch +@item 2002-03-03-cvs +main-line the day the branch is cut +@item 5.1.90-2002-03-03-cvs +corresponding branch version +@item 5.1.91 +first draft release candidate +@item 5.1.91-2002-03-17-cvs +updated branch version +@item 5.1.92 +second draft release candidate +@item 5.1.92-2002-03-31-cvs +updated branch version +@item 5.1.93 +final release candidate (see below) +@item 5.2 +official release +@item 5.2.0.90-2002-04-07-cvs +updated CVS branch version +@item 5.2.1 +second official release +@end table + +Notes: + +@itemize @bullet +@item +Minor minor minor draft release candidates such as 5.2.0.91 have been +omitted from the example. Such release candidates are, typically, never +made. +@item +For 5.1.93 the bziped tar ball @file{gdb-5.1.93.tar.bz2} is just the +official @file{gdb-5.2.tar} renamed and compressed. +@end itemize + +To avoid version conflicts, vendors are expected to modify the file +@file{gdb/version.in} to include a vendor unique alphabetic identifier +(an official @value{GDBN} release never uses alphabetic characters in +its version identifer). + +Since @value{GDBN} does not make minor minor minor releases (e.g., +5.1.0.1) the conflict between that and a minor minor draft release +identifier (e.g., 5.1.0.90) is avoided. + + +@subsection Branches + +@value{GDBN} draws a release series (5.2, 5.2.1, @dots{}) from a single +release branch (gdb_5_2-branch). Since minor minor minor releases +(5.1.0.1) are not made, the need to branch the release branch is avoided +(it also turns out that the effort required for such a a branch and +release is significantly greater than the effort needed to create a new +release from the head of the release branch). + +Releases 5.0 and 5.1 used branch and release tags of the form: + +@smallexample +gdb_N_M-YYYY-MM-DD-branchpoint +gdb_N_M-YYYY-MM-DD-branch +gdb_M_N-YYYY-MM-DD-release +@end smallexample + +Release 5.2 is trialing the branch and release tags: + +@smallexample +gdb_N_M-YYYY-MM-DD-branchpoint +gdb_N_M-branch +gdb_M_N-YYYY-MM-DD-release +@end smallexample + +@emph{Pragmatics: The branchpoint and release tags need to identify when +a branch and release are made. The branch tag, denoting the head of the +branch, does not have this criteria.} + + +@section Branch Commit Policy + +The branch commit policy is pretty slack. @value{GDBN} releases 5.0, +5.1 and 5.2 all used the below: + +@itemize @bullet +@item +The @file{gdb/MAINTAINERS} file still holds. +@item +Don't fix something on the branch unless/until it is also fixed in the +trunk. If this isn't possible, mentioning it in the @file{gdb/PROBLEMS} +file is better than committing a hack. +@item +When considering a patch for the branch, suggested criteria include: +Does it fix a build? Does it fix the sequence @kbd{break main; run} +when debugging a static binary? +@item +The further a change is from the core of @value{GDBN}, the less likely +the change will worry anyone (e.g., target specific code). +@item +Only post a proposal to change the core of @value{GDBN} after you've +sent individual bribes to all the people listed in the +@file{MAINTAINERS} file @t{;-)} +@end itemize + +@emph{Pragmatics: Provided updates are restricted to non-core +functionality there is little chance that a broken change will be fatal. +This means that changes such as adding a new architectures or (within +reason) support for a new host are considered acceptable.} + + +@section Obsoleting code Before anything else, poke the other developers (and around the source code) to see if there is anything that can be removed from @value{GDBN} (an old target, an unused file). Obsolete code is identified by adding an @code{OBSOLETE} prefix to every -line. Doing this means that it is easy to identify obsolete code when -grepping through the sources. +line. Doing this means that it is easy to identify something that has +been obsoleted when greping through the sources. -The process has a number of steps and is intentionally slow --- this is -to mainly ensure that people have had a reasonable chance to respond. -Remember, everything on the internet takes a week. +The process is done in stages --- this is mainly to ensure that the +wider @value{GDBN} community has a reasonable opportunity to respond. +Remember, everything on the Internet takes a week. -@itemize @bullet +@enumerate @item -announce the change on @email{gdb@@sources.redhat.com, GDB mailing list} +Post the proposal on @email{gdb@@sources.redhat.com, the GDB mailing +list} Creating a bug report to track the task's state, is also highly +recommended. @item -wait a week or so +Wait a week or so. @item -announce the change on @email{gdb-announce@@sources.redhat.com, GDB -Announcement mailing list} +Post the proposal on @email{gdb-announce@@sources.redhat.com, the GDB +Announcement mailing list}. @item -wait a week or so +Wait a week or so. @item -go through and edit all relevant files and lines (e.g., in -@file{configure.tgt}) so that they are prefixed with the word -@code{OBSOLETE}. -@end itemize +Go through and edit all relevant files and lines so that they are +prefixed with the word @code{OBSOLETE}. +@item +Wait until the next GDB version, containing this obsolete code, has been +released. +@item +Remove the obsolete code. +@end enumerate -@emph{Maintainer note: Removing old code, while regrettable, is a good -thing. Firstly it helps the developers by removing code that is either -no longer relevant or simply wrong. Secondly since it removes any -history associated with the file (effectively clearing the slate) the -developer has a much freer hand when it comes to fixing broken files.} +@noindent +@emph{Maintainer note: While removing old code is regrettable it is +hopefully better for @value{GDBN}'s long term development. Firstly it +helps the developers by removing code that is either no longer relevant +or simply wrong. Secondly since it removes any history associated with +the file (effectively clearing the slate) the developer has a much freer +hand when it comes to fixing broken files.} -@section Before the branch + + +@section Before the Branch The most important objective at this stage is to find and fix simple changes that become a pain to track once the branch is created. For @@ -4866,34 +5746,17 @@ instance, configuration problems that stop @value{GDBN} from even building. If you can't get the problem fixed, document it in the @file{gdb/PROBLEMS} file. -@subheading Organize and announce the schedule. +@subheading Prompt for @file{gdb/NEWS} -The following is a possible schedule. It is based on the rule-of-thumb -that everything on the Internet takes a week. You may want to even -increase those times further since an analysis of the actual data -strongly suggests that the below is far to aggressive. +People always forget. Send a post reminding them but also if you know +something interesting happened add it yourself. The @code{schedule} +script will mention this in its e-mail. -@itemize @bullet -@item -announce it -@item -wait a week -@item -announce branch date -@item -wait a week -@item -Cut the branch -@item -wait a week -@item -start enjoying all the fun -@end itemize +@subheading Review @file{gdb/README} -As an aside, the branch tag name is probably regrettable vis: -@example -gdb_N_M-YYYY-MM-DD-@{branch,branchpoint@} -@end example +Grab one of the nightly snapshots and then walk through the +@file{gdb/README} looking for anything that can be improved. The +@code{schedule} script will mention this in its e-mail. @subheading Refresh any imported files. @@ -4903,114 +5766,250 @@ A number of files are taken from external repositories. They include: @item @file{texinfo/texinfo.tex} @item -@file{config.guess} et.@: al.@: +@file{config.guess} et.@: al.@: (see the top-level @file{MAINTAINERS} +file) +@item +@file{etc/standards.texi}, @file{etc/make-stds.texi} @end itemize -and should be refreshed. - -@subheading Prompt for @file{gdb/NEWS} - -People always forget. Send a post reminding them but also if you know -something interesting happened add it your self. - -@subheading Review @file{gdb/README} - -Grab one of the nightly snapshots and then walk through the -@file{gdb/README} looking for anything that can be improved. - @subheading Check the ARI -ARI is an @code{awk} script (Awk Regression Indicator?) that checks for a -number of errors and coding conventions. The checks include things like -using @code{malloc} instead of @code{xmalloc} and file naming problems. -There shouldn't be any regressions. +@uref{http://sources.redhat.com/gdb/ari,,A.R.I.} is an @code{awk} script +(Awk Regression Index ;-) that checks for a number of errors and coding +conventions. The checks include things like using @code{malloc} instead +of @code{xmalloc} and file naming problems. There shouldn't be any +regressions. -@section Cut the branch +@subsection Review the bug data base -@subheading The dirty work +Close anything obviously fixed. -I think something like the below was used: +@subsection Check all cross targets build -@example -$ d=`date -u +%Y-%m-%d` -$ echo $d -2002-01-24 -$ cvs -f -d /cvs/src rtag -D $d-gmt \ -gdb_5_1-$d-branchpoint insight+dejagnu -$ cvs -f -d /cvs/src rtag -b -r gdb_V_V-$d-branchpoint \ -gdb_5_1-$d-branch insight+dejagnu +The targets are listed in @file{gdb/MAINTAINERS}. + + +@section Cut the Branch + +@subheading Create the branch + +@smallexample +$ u=5.1 +$ v=5.2 +$ V=`echo $v | sed 's/\./_/g'` +$ D=`date -u +%Y-%m-%d` +$ echo $u $V $D +5.1 5_2 2002-03-03 +$ echo cvs -f -d :ext:sources.redhat.com:/cvs/src rtag \ +-D $D-gmt gdb_$V-$D-branchpoint insight+dejagnu +cvs -f -d :ext:sources.redhat.com:/cvs/src rtag +-D 2002-03-03-gmt gdb_5_2-2002-03-03-branchpoint insight+dejagnu +$ ^echo ^^ +... +$ echo cvs -f -d :ext:sources.redhat.com:/cvs/src rtag \ +-b -r gdb_$V-$D-branchpoint gdb_$V-branch insight+dejagnu +cvs -f -d :ext:sources.redhat.com:/cvs/src rtag \ +-b -r gdb_5_2-2002-03-03-branchpoint gdb_5_2-branch insight+dejagnu +$ ^echo ^^ +... $ -@end example +@end smallexample @itemize @bullet @item -the @kbd{-D YYYY-MM-DD-gmt} forces the branch to an exact date/time. +by using @kbd{-D YYYY-MM-DD-gmt} the branch is forced to an exact +date/time. @item the trunk is first taged so that the branch point can easily be found @item -Insight (which includes GDB) and dejagnu are tagged at the same time +Insight (which includes GDB) and dejagnu are all tagged at the same time +@item +@file{version.in} gets bumped to avoid version number conflicts +@item +the reading of @file{.cvsrc} is disabled using @file{-f} +@end itemize + +@subheading Update @file{version.in} + +@smallexample +$ u=5.1 +$ v=5.2 +$ V=`echo $v | sed 's/\./_/g'` +$ echo $u $v$V +5.1 5_2 +$ cd /tmp +$ echo cvs -f -d :ext:sources.redhat.com:/cvs/src co \ +-r gdb_$V-branch src/gdb/version.in +cvs -f -d :ext:sources.redhat.com:/cvs/src co + -r gdb_5_2-branch src/gdb/version.in +$ ^echo ^^ +U src/gdb/version.in +$ cd src/gdb +$ echo $u.90-0000-00-00-cvs > version.in +$ cat version.in +5.1.90-0000-00-00-cvs +$ cvs -f commit version.in +@end smallexample + +@itemize @bullet +@item +@file{0000-00-00} is used as a date to pump prime the version.in update +mechanism +@item +@file{.90} and the previous branch version are used as fairly arbitrary +initial branch version number @end itemize -@subheading Post the branch info @subheading Update the web and news pages +Something? + @subheading Tweak cron to track the new branch +The file @file{gdbadmin/cron/crontab} contains gdbadmin's cron table. +This file needs to be updated so that: + +@itemize @bullet +@item +a daily timestamp is added to the file @file{version.in} +@item +the new branch is included in the snapshot process +@end itemize + +@noindent +See the file @file{gdbadmin/cron/README} for how to install the updated +cron table. + +The file @file{gdbadmin/ss/README} should also be reviewed to reflect +any changes. That file is copied to both the branch/ and current/ +snapshot directories. + + +@subheading Update the NEWS and README files + +The @file{NEWS} file needs to be updated so that on the branch it refers +to @emph{changes in the current release} while on the trunk it also +refers to @emph{changes since the current release}. + +The @file{README} file needs to be updated so that it refers to the +current release. + +@subheading Post the branch info + +Send an announcement to the mailing lists: + +@itemize @bullet +@item +@email{gdb-announce@@sources.redhat.com, GDB Announcement mailing list} +@item +@email{gdb@@sources.redhat.com, GDB Discsussion mailing list} and +@email{gdb-testers@@sources.redhat.com, GDB Discsussion mailing list} +@end itemize + +@emph{Pragmatics: The branch creation is sent to the announce list to +ensure that people people not subscribed to the higher volume discussion +list are alerted.} + +The announcement should include: + +@itemize @bullet +@item +the branch tag +@item +how to check out the branch using CVS +@item +the date/number of weeks until the release +@item +the branch commit policy +still holds. +@end itemize + @section Stabilize the branch Something goes here. @section Create a Release -This procedure can be followed when creating beta and final final -releases. With a beta many of the steps can be skipped. +The process of creating and then making available a release is broken +down into a number of stages. The first part addresses the technical +process of creating a releasable tar ball. The later stages address the +process of releasing that tar ball. -@subheading Establish a few defaults. +When making a release candidate just the first section is needed. -@example -$ b=gdb_5_1-2001-07-29-branch -$ v=5.1.1 +@subsection Create a release candidate + +The objective at this stage is to create a set of tar balls that can be +made available as a formal release (or as a less formal release +candidate). + +@subsubheading Freeze the branch + +Send out an e-mail notifying everyone that the branch is frozen to +@email{gdb-patches@@sources.redhat.com}. + +@subsubheading Establish a few defaults. + +@smallexample +$ b=gdb_5_2-branch +$ v=5.2 $ t=/sourceware/snapshot-tmp/gdbadmin-tmp $ echo $t/$b/$v +/sourceware/snapshot-tmp/gdbadmin-tmp/gdb_5_2-branch/5.2 $ mkdir -p $t/$b/$v $ cd $t/$b/$v $ pwd -/sourceware/snapshot-tmp/gdbadmin-tmp/gdb_5_1-2001-07-29-branch/5.1.1 +/sourceware/snapshot-tmp/gdbadmin-tmp/gdb_5_2-branch/5.2 $ which autoconf /home/gdbadmin/bin/autoconf $ -@end example +@end smallexample -NB: Check the autoconf version carefully. You want to be using the -version taken from the binutils snapshot directory. It is most likely -that your system's installed version (@file{/usr/bin}?) is probably -correct. +@noindent +Notes: -@subheading Check out the relevant modules: +@itemize @bullet +@item +Check the @code{autoconf} version carefully. You want to be using the +version taken from the @file{binutils} snapshot directory, which can be +found at @uref{ftp://sources.redhat.com/pub/binutils/}. It is very +unlikely that a system installed version of @code{autoconf} (e.g., +@file{/usr/bin/autoconf}) is correct. +@end itemize -@example +@subsubheading Check out the relevant modules: + +@smallexample $ for m in gdb insight dejagnu do ( mkdir -p $m && cd $m && cvs -q -f -d /cvs/src co -P -r $b $m ) done $ -@end example +@end smallexample -NB: The reading of @file{.cvsrc} is disabled (@file{-f}) so that there -isn't any confusion between what is written here and what your local CVS -really does. +@noindent +Note: -@subheading Update relevant files. +@itemize @bullet +@item +The reading of @file{.cvsrc} is disabled (@file{-f}) so that there isn't +any confusion between what is written here and what your local +@code{cvs} really does. +@end itemize -@subsubheading @file{gdb/NEWS} +@subsubheading Update relevant files. + +@table @file + +@item gdb/NEWS Major releases get their comments added as part of the mainline. Minor releases should probably mention any significant bugs that were fixed. -Don't forget to update the ChangeLog. +Don't forget to include the @file{ChangeLog} entry. -@example +@smallexample $ emacs gdb/src/gdb/NEWS ... c-x 4 a @@ -5018,13 +6017,22 @@ c-x 4 a c-x c-s c-x c-c $ cp gdb/src/gdb/NEWS insight/src/gdb/NEWS $ cp gdb/src/gdb/ChangeLog insight/src/gdb/ChangeLog -@end example +@end smallexample -@subsubheading @file{gdb/README} +@item gdb/README -You'll need to update: the version, the update date, and who did it. +You'll need to update: -@example +@itemize @bullet +@item +the version +@item +the update date +@item +who did it +@end itemize + +@smallexample $ emacs gdb/src/gdb/README ... c-x 4 a @@ -5032,192 +6040,289 @@ c-x 4 a c-x c-s c-x c-c $ cp gdb/src/gdb/README insight/src/gdb/README $ cp gdb/src/gdb/ChangeLog insight/src/gdb/ChangeLog -@end example +@end smallexample -@emph{Maintainer note: Hopefully the README file was reviewed before the -initial branch was cut so just a simple substitute is needed to get it -updated.} +@emph{Maintainer note: Hopefully the @file{README} file was reviewed +before the initial branch was cut so just a simple substitute is needed +to get it updated.} @emph{Maintainer note: Other projects generate @file{README} and @file{INSTALL} from the core documentation. This might be worth pursuing.} -@subsubheading @file{gdb/version.in} +@item gdb/version.in -@example +@smallexample $ echo $v > gdb/src/gdb/version.in +$ cat gdb/src/gdb/version.in +5.2 $ emacs gdb/src/gdb/version.in ... c-x 4 a +... Bump to version ... +c-x c-s c-x c-c +$ cp gdb/src/gdb/version.in insight/src/gdb/version.in +$ cp gdb/src/gdb/ChangeLog insight/src/gdb/ChangeLog +@end smallexample + +@item dejagnu/src/dejagnu/configure.in + +Dejagnu is more complicated. The version number is a parameter to +@code{AM_INIT_AUTOMAKE}. Tweak it to read something like gdb-5.1.91. + +Don't forget to re-generate @file{configure}. + +Don't forget to include a @file{ChangeLog} entry. + +@smallexample +$ emacs dejagnu/src/dejagnu/configure.in +... +c-x 4 a ... c-x c-s c-x c-c -$ cp gdb/src/gdb/version.in insight/src/gdb/version.in -$ cp gdb/src/gdb/ChangeLog insight/src/gdb/ChangeLog -@end example +$ ( cd dejagnu/src/dejagnu && autoconf ) +@end smallexample -@subsubheading @file{dejagnu/src/dejagnu/configure.in} +@end table -Dejagnu is more complicated. The version number is a parameter to -@var{AM_INIT_AUTOMAKE}. Tweak it to read something like -@var{gdb-5.1.1}. +@subsubheading Do the dirty work -Re-generate configure. +This is identical to the process used to create the daily snapshot. -Add a ChangeLog. - -@subheading Do the dirty work - -This is identical to the process used when creating the daily snapshot. - -@example -$ for m in gdb insight dejagnu +@smallexample +$ for m in gdb insight do -( cd $m/src && gmake -f Makefile.in $m.tar.bz2 ) +( cd $m/src && gmake -f src-release $m.tar ) done -@end example +$ ( m=dejagnu; cd $m/src && gmake -f src-release $m.tar.bz2 ) +@end smallexample -@subheading Check the source files +If the top level source directory does not have @file{src-release} +(@value{GDBN} version 5.3.1 or earlier), try these commands instead: -You're looking for files that have mysteriously disappeared as the +@smallexample +$ for m in gdb insight +do +( cd $m/src && gmake -f Makefile.in $m.tar ) +done +$ ( m=dejagnu; cd $m/src && gmake -f Makefile.in $m.tar.bz2 ) +@end smallexample + +@subsubheading Check the source files + +You're looking for files that have mysteriously disappeared. @kbd{distclean} has the habit of deleting files it shouldn't. Watch out for the @file{version.in} update @kbd{cronjob}. -@example +@smallexample $ ( cd gdb/src && cvs -f -q -n update ) M djunpack.bat +? gdb-5.1.91.tar ? proto-toplev -? gdb-5.1.1.tar.bz2 +@dots{} lots of generated files @dots{} M gdb/ChangeLog M gdb/NEWS M gdb/README M gdb/version.in -? gdb/p-exp.tab.c -? gdb/doc/gdb.info-11 -? gdb/doc/gdb.info-12 -? gdb/doc/gdb.info-13 -? gdb/doc/gdb.info-14 -? gdb/doc/gdb.info-15 -? gdb/doc/gdbint.info-4 -? gdb/doc/gdbint.info-5 +@dots{} lots of generated files @dots{} $ -@end example +@end smallexample +@noindent @emph{Don't worry about the @file{gdb.info-??} or @file{gdb/p-exp.tab.c}. They were generated (and yes @file{gdb.info-1} was also generated only something strange with CVS means that they didn't get supressed). Fixing it would be nice though.} -@subheading Re-pack the release with @code{gzip} +@subsubheading Create compressed versions of the release -@example -$ cp */*/*.bz2 . -$ bunzip2 -k -v *.bz2 -$ gzip -9 -v *.tar -@end example +@smallexample +$ cp */src/*.tar . +$ cp */src/*.bz2 . +$ ls -F +dejagnu/ dejagnu-gdb-5.2.tar.bz2 gdb/ gdb-5.2.tar insight/ insight-5.2.tar +$ for m in gdb insight +do +bzip2 -v -9 -c $m-$v.tar > $m-$v.tar.bz2 +gzip -v -9 -c $m-$v.tar > $m-$v.tar.gz +done +$ +@end smallexample -NB: A pipe such as @kbd{bunzip2 < xxx.bz2 | gzip -9 > xxx.gz} shouldn't -be used since, in that mode, gzip doesn't know the file name information -and consequently can't include it. This is also why the release process -runs @code{tar} and @code{bzip2} as separate passes. - -@emph{Maintainer note: The release process could be changed to create -@file{.tar} rather than @file{.tar.bz2} files.} - -@section Check the release - -Grab the @file{gdb.tar.bz2}, copy it to your local machine and then try -a simple build using it. - -If this is a pre-release just copy the @file{.bz2} files to the snapshot -directory and skip the remaining steps. - -If it is a final release, also make it available under a bogus name so -that others can download and check it. - -@emph{Maintainer note: This adds an extra day to the release process but -is very much worth it. Other developers are given the oportunity to -check that things like your @file{NEWS} entries are correct or that -other changes actually work.} - -@section Release the tar ball - -This is where, unfortunatly, the notes just get vague. - -@subheading Install on sware - -@example -$ cp *.bz2 *.gz ~ftp/pub/gdb/releases -@end example - -@subheading Create and update the web pages. - -Try the following: +@noindent +Note: @itemize @bullet @item -create the directory @file{htdocs/@var{version}} (e.g., @file{htdocs/5.1.1} -@item -copy @file{index.html} and @file{ANNOUNCE} from the previous release -into the @file{htdocs/@var{version}} directory and edit for content. -Things like the MD5 sums, @kbd{ls -l} output, the version number and so -on will need updating. Add NEWS entries to the @file{ANNOUNCE}. This -ensures that the previous announcement is kept somewhere handy. -@item -copy the @file{NEWS} from the distro into the -@file{htdocs/@var{version}} directory, trim down to just the most recent -news items -@item -Add a short (identical) announcement to both @file{htdocs/index.html} -and @file{htdocs/news/index.html} -@item -edit the script @file{htdocs/index.sh} to link in the new release -number. Run it across all @file{index.html} files vis @kbd{./index.sh -index.html */index.html}. -@item -grep the @file{htdocs} tree for references to the previous release -version (@file{htdocs/download/index.html}) +A pipe such as @kbd{bunzip2 < xxx.bz2 | gzip -9 > xxx.gz} is not since, +in that mode, @code{gzip} does not know the name of the file and, hence, +can not include it in the compressed file. This is also why the release +process runs @code{tar} and @code{bzip2} as separate passes. @end itemize -@emph{Maintainer note: This step is too fragile --- it is too easy to -mis one of the entries and forget to update it.} +@subsection Sanity check the tar ball -@subheading Generate online docs +Pick a popular machine (Solaris/PPC?) and try the build on that. +@smallexample +$ bunzip2 < gdb-5.2.tar.bz2 | tar xpf - +$ cd gdb-5.2 +$ ./configure +$ make +@dots{} +$ ./gdb/gdb ./gdb/gdb +GNU gdb 5.2 +@dots{} +(gdb) b main +Breakpoint 1 at 0x80732bc: file main.c, line 734. +(gdb) run +Starting program: /tmp/gdb-5.2/gdb/gdb + +Breakpoint 1, main (argc=1, argv=0xbffff8b4) at main.c:734 +734 catch_errors (captured_main, &args, "", RETURN_MASK_ALL); +(gdb) print args +$1 = @{argc = 136426532, argv = 0x821b7f0@} +(gdb) +@end smallexample + +@subsection Make a release candidate available + +If this is a release candidate then the only remaining steps are: + +@enumerate +@item +Commit @file{version.in} and @file{ChangeLog} +@item +Tweak @file{version.in} (and @file{ChangeLog} to read +@var{L}.@var{M}.@var{N}-0000-00-00-cvs so that the version update +process can restart. +@item +Make the release candidate available in +@uref{ftp://sources.redhat.com/pub/gdb/snapshots/branch} +@item +Notify the relevant mailing lists ( @email{gdb@@sources.redhat.com} and +@email{gdb-testers@@sources.redhat.com} that the candidate is available. +@end enumerate + +@subsection Make a formal release available + +(And you thought all that was required was to post an e-mail.) + +@subsubheading Install on sware + +Copy the new files to both the release and the old release directory: + +@smallexample +$ cp *.bz2 *.gz ~ftp/pub/gdb/old-releases/ +$ cp *.bz2 *.gz ~ftp/pub/gdb/releases +@end smallexample + +@noindent +Clean up the releases directory so that only the most recent releases +are available (e.g. keep 5.2 and 5.2.1 but remove 5.1): + +@smallexample +$ cd ~ftp/pub/gdb/releases +$ rm @dots{} +@end smallexample + +@noindent +Update the file @file{README} and @file{.message} in the releases +directory: + +@smallexample +$ vi README +@dots{} +$ rm -f .message +$ ln README .message +@end smallexample + +@subsubheading Update the web pages. + +@table @file + +@item htdocs/download/ANNOUNCEMENT +This file, which is posted as the official announcement, includes: +@itemize @bullet +@item +General announcement +@item +News. If making an @var{M}.@var{N}.1 release, retain the news from +earlier @var{M}.@var{N} release. +@item +Errata +@end itemize + +@item htdocs/index.html +@itemx htdocs/news/index.html +@itemx htdocs/download/index.html +These files include: +@itemize @bullet +@item +announcement of the most recent release +@item +news entry (remember to update both the top level and the news directory). +@end itemize +These pages also need to be regenerate using @code{index.sh}. + +@item download/onlinedocs/ You need to find the magic command that is used to generate the online docs from the @file{.tar.bz2}. The best way is to look in the output -from one of the nightly cronjobs and then just edit accordingly. +from one of the nightly @code{cron} jobs and then just edit accordingly. Something like: -@example +@smallexample $ ~/ss/update-web-docs \ - ~ftp/pub/gdb/releases/gdb-5.1.1.tar.bz2 \ + ~ftp/pub/gdb/releases/gdb-5.2.tar.bz2 \ $PWD/www \ - /www/sourceware/htdocs/gdb/5.1.1/onlinedocs \ + /www/sourceware/htdocs/gdb/download/onlinedocs \ gdb -@end example +@end smallexample -@subheading Something about @file{ANNOUNCEMENT} +@item download/ari/ +Just like the online documentation. Something like: -Send the @file{ANNOUNCEMENT} file you created above to: +@smallexample +$ /bin/sh ~/ss/update-web-ari \ + ~ftp/pub/gdb/releases/gdb-5.2.tar.bz2 \ + $PWD/www \ + /www/sourceware/htdocs/gdb/download/ari \ + gdb +@end smallexample + +@end table + +@subsubheading Shadow the pages onto gnu + +Something goes here. + + +@subsubheading Install the @value{GDBN} tar ball on GNU + +At the time of writing, the GNU machine was @kbd{gnudist.gnu.org} in +@file{~ftp/gnu/gdb}. + +@subsubheading Make the @file{ANNOUNCEMENT} + +Post the @file{ANNOUNCEMENT} file you created above to: @itemize @bullet @item @email{gdb-announce@@sources.redhat.com, GDB Announcement mailing list} @item -The gnu announce list (but delay it a day or so to let things get out). +@email{info-gnu@@gnu.org, General GNU Announcement list} (but delay it a +day or so to let things get out) +@item +@email{bug-gdb@@gnu.org, GDB Bug Report mailing list} @end itemize -@subheading Install it on GNU +@subsection Cleanup -At the time of writing, the GNU machine was @kbd{gnudist.gnu.org} in -@file{~ftp/gnu/gdb} (I think, I'm still waiting for it to copy into my -home directory). +The release is out but you're still not finished. -@section Cleanup +@subsubheading Commit outstanding changes -@subheading Commit outstanding changes - -In particular you'll need to commit the changes to: +In particular you'll need to commit any changes to: @itemize @bullet @item @@ -5230,36 +6335,58 @@ In particular you'll need to commit the changes to: @file{gdb/README} @end itemize -@subheading Tag the release +@subsubheading Tag the release Something like: -@example +@smallexample $ d=`date -u +%Y-%m-%d` $ echo $d 2002-01-24 $ ( cd insight/src/gdb && cvs -f -q update ) -$ ( cd insight/src && cvs -f -q tag gdb_5_1_1-$d-release ) -@end example +$ ( cd insight/src && cvs -f -q tag gdb_5_2-$d-release ) +@end smallexample -Insight is used since that contains more of the release than GDB (yes -dejagnu doesn't get tagged but I think we can live with that.). +Insight is used since that contains more of the release than +@value{GDBN} (@code{dejagnu} doesn't get tagged but I think we can live +with that). -@subheading Restart @file{gdb/version.in} +@subsubheading Mention the release on the trunk + +Just put something in the @file{ChangeLog} so that the trunk also +indicates when the release was made. + +@subsubheading Restart @file{gdb/version.in} If @file{gdb/version.in} does not contain an ISO date such as @kbd{2002-01-24} then the daily @code{cronjob} won't update it. Having committed all the release changes it can be set to -@file{5.1.0_0000-00-00-cvs} which will restart things (yes the @kbd{_} +@file{5.2.0_0000-00-00-cvs} which will restart things (yes the @kbd{_} is important - it affects the snapshot process). Don't forget the @file{ChangeLog}. -@subheading Merge into trunk +@subsubheading Merge into trunk The files committed to the branch may also need changes merged into the trunk. +@subsubheading Revise the release schedule + +Post a revised release schedule to @email{gdb@@sources.redhat.com, GDB +Discussion List} with an updated announcement. The schedule can be +generated by running: + +@smallexample +$ ~/ss/schedule `date +%s` schedule +@end smallexample + +@noindent +The first parameter is approximate date/time in seconds (from the epoch) +of the most recent release. + +Also update the schedule @code{cronjob}. + @section Post release Remove any @code{OBSOLETE} code. @@ -5290,7 +6417,7 @@ the testsuite is running, you'll get mentions of which test file is in use, and a mention of any unexpected passes or fails. When the testsuite is finished, you'll get a summary that looks like this: -@example +@smallexample === gdb Summary === # of expected passes 6016 @@ -5299,7 +6426,7 @@ finished, you'll get a summary that looks like this: # of expected failures 183 # of unresolved testcases 3 # of untested testcases 5 -@end example +@end smallexample The ideal test run consists of expected passes only; however, reality conspires to keep us from this ideal. Unexpected failures indicate @@ -5362,12 +6489,12 @@ intelligibility. This is the base testsuite. The tests in it should apply to all configurations of @value{GDBN} (but generic native-only tests may live here). The test programs should be in the subset of C that is valid K&R, -ANSI/ISO, and C++ (@code{#ifdef}s are allowed if necessary, for instance +ANSI/ISO, and C@t{++} (@code{#ifdef}s are allowed if necessary, for instance for prototypes). @item gdb.@var{lang} Language-specific tests for any language @var{lang} besides C. Examples are -@file{gdb.c++} and @file{gdb.java}. +@file{gdb.cp} and @file{gdb.java}. @item gdb.@var{platform} Non-portable tests. The tests are specific to a specific configuration @@ -5615,19 +6742,12 @@ and deleted from all of @value{GDBN}'s config files. Any @file{@var{foo}-xdep.c} file that references STACK_END_ADDR is so old that it has never been converted to use BFD. Now that's old! -@item PYRAMID_CONTROL_FRAME_DEBUGGING -pyr-xdep.c -@item PYRAMID_CORE -pyr-xdep.c -@item PYRAMID_PTRACE -pyr-xdep.c - -@item REG_STACK_SEGMENT -exec.c - @end table +@include observer.texi +@raisesections @include fdl.texi +@lowersections @node Index @unnumbered Index diff --git a/contrib/gdb/gdb/doc/observer.texi b/contrib/gdb/gdb/doc/observer.texi new file mode 100644 index 00000000000..de48a192a36 --- /dev/null +++ b/contrib/gdb/gdb/doc/observer.texi @@ -0,0 +1,70 @@ +@c -*-texinfo-*- +@node GDB Observers +@appendix @value{GDBN} Currently available observers + +@section Implementation rationale +@cindex observers implementation rationale + +An @dfn{observer} is an entity which is interested in being notified +when GDB reaches certain states, or certain events occur in GDB. +The entity being observed is called the @dfn{subject}. To receive +notifications, the observer attaches a callback to the subject. +One subject can have several observers. + +@file{observer.c} implements an internal generic low-level event +notification mechanism. This generic event notification mechanism is +then re-used to implement the exported high-level notification +management routines for all possible notifications. + +The current implementation of the generic observer provides support +for contextual data. This contextual data is given to the subject +when attaching the callback. In return, the subject will provide +this contextual data back to the observer as a parameter of the +callback. + +Note that the current support for the contextual data is only partial, +as it lacks a mechanism that would deallocate this data when the +callback is detached. This is not a problem so far, as this contextual +data is only used internally to hold a function pointer. Later on, if +a certain observer needs to provide support for user-level contextual +data, then the generic notification mechanism will need to be +enhanced to allow the observer to provide a routine to deallocate the +data when attaching the callback. + +The observer implementation is also currently not reentrant. +In particular, it is therefore not possible to call the attach +or detach routines during a notification. + +@section @code{normal_stop} Notifications +@cindex @code{normal_stop} observer +@cindex notification about inferior execution stop + +@value{GDBN} notifies all @code{normal_stop} observers when the +inferior execution has just stopped, the associated messages and +annotations have been printed, and the control is about to be returned +to the user. + +Note that the @code{normal_stop} notification is not emitted when +the execution stops due to a breakpoint, and this breakpoint has +a condition that is not met. If the breakpoint has any associated +commands list, the commands are executed after the notification +is emitted. + +The following interface is available to manage @code{normal_stop} +observers: + +@deftypefun extern struct observer *observer_attach_normal_stop (observer_normal_stop_ftype *@var{f}) +Attach the given @code{normal_stop} callback function @var{f} and +return the associated observer. +@end deftypefun + +@deftypefun extern void observer_detach_normal_stop (struct observer *@var{observer}); +Remove @var{observer} from the list of observers to be notified when +a @code{normal_stop} event occurs. +@end deftypefun + +@deftypefun extern void observer_notify_normal_stop (void); +Send a notification to all @code{normal_stop} observers. +@end deftypefun + + diff --git a/contrib/gdb/gdb/doc/stabs.texinfo b/contrib/gdb/gdb/doc/stabs.texinfo index 2a14dcc7034..d43ef372c30 100644 --- a/contrib/gdb/gdb/doc/stabs.texinfo +++ b/contrib/gdb/gdb/doc/stabs.texinfo @@ -3,13 +3,12 @@ @c @finalout -@ifinfo -@format -START-INFO-DIR-ENTRY -* Stabs: (stabs). The "stabs" debugging information format. -END-INFO-DIR-ENTRY -@end format -@end ifinfo +@c This is a dir.info fragment to support semi-automated addition of +@c manuals to an info tree. +@dircategory Software development +@direntry +* Stabs: (stabs). The "stabs" debugging information format. +@end direntry @ifinfo This document describes the stabs debugging symbol tables. @@ -22,12 +21,9 @@ and David MacKenzie. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' -and with the Back-Cover Texts as in (a) below. - -(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify -this GNU Manual, like GNU software. Copies published by the Free -Software Foundation raise funds for GNU development.'' +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled ``GNU +Free Documentation License''. @end ifinfo @setchapternewpage odd @@ -54,13 +50,9 @@ Contributed by Cygnus Support. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' -and with the Back-Cover Texts as in (a) below. - -(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify -this GNU Manual, like GNU software. Copies published by the Free -Software Foundation raise funds for GNU development.'' - +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the section entitled ``GNU +Free Documentation License''. @end titlepage @ifinfo @@ -85,6 +77,7 @@ This document describes the stabs debugging format. * Stab Sections:: In some object file formats, stabs are in sections. * Symbol Types Index:: Index of symbolic stab symbol type names. +* GNU Free Documentation License:: The license for this documentation @end menu @end ifinfo @@ -259,10 +252,10 @@ There is an AIX extension for type attributes. Following the @samp{=} are any number of type attributes. Each one starts with @samp{@@} and ends with @samp{;}. Debuggers, including AIX's dbx and GDB 4.10, skip any type attributes they do not recognize. GDB 4.9 and other versions -of dbx may not do this. Because of a conflict with C++ +of dbx may not do this. Because of a conflict with C@t{++} (@pxref{Cplusplus}), new attributes should not be defined which begin with a digit, @samp{(}, or @samp{-}; GDB may be unable to distinguish -those from the C++ type descriptor @samp{@@}. The attributes are: +those from the C@t{++} type descriptor @samp{@@}. The attributes are: @table @code @item a@var{boundary} @@ -287,6 +280,12 @@ Indicate that this type is a string instead of an array of characters, or a bitstring instead of a set. It doesn't change the layout of the data being represented, but does enable the debugger to know which type it is. + +@item V +Indicate that this type is a vector instead of an array. The only +major difference between vectors and arrays is that vectors are +passed by value instead of by reference (vector coprocessor extension). + @end table All of this can make the string field quite long. All versions of GDB, @@ -431,7 +430,7 @@ Some compilers (for example, GCC2 and SunOS4 @file{/bin/cc}) also include the directory in which the source was compiled, in a second @code{N_SO} symbol preceding the one containing the file name. This symbol can be distinguished by the fact that it ends in a slash. Code -from the @code{cfront} C++ compiler can have additional @code{N_SO} symbols for +from the @code{cfront} C@t{++} compiler can have additional @code{N_SO} symbols for nonexistent source files after the @code{N_SO} for the real source file; these are believed to contain no useful information. @@ -1766,7 +1765,7 @@ Another way is with the @samp{x} type descriptor, which is followed by @samp{s} for a structure tag, @samp{u} for a union tag, or @samp{e} for a enumerator tag, followed by the name of the tag, followed by @samp{:}. If the name contains @samp{::} between a @samp{<} and @samp{>} pair (for -C++ templates), such a @samp{::} does not end the name---only a single +C@t{++} templates), such a @samp{::} does not end the name---only a single @samp{:} ends the name; see @ref{Nested Symbols}. For example, the following C declarations: @@ -2041,8 +2040,9 @@ definition narrows the symbol type to structure. Following the @samp{s} type descriptor is the number of bytes the structure occupies, followed by a description of each structure element. -The structure element descriptions are of the form @var{name:type, bit -offset from the start of the struct, number of bits in the element}. +The structure element descriptions are of the form +@samp{@var{name}:@var{type}, @var{bit offset from the start of the +struct}, @var{number of bits in the element}}. @c FIXME: phony line break. Can probably be fixed by using an example @c with fewer fields. @@ -2062,13 +2062,13 @@ The @code{s_next} field is a pointer to the same kind of structure that the field is an element of. So the definition of structure type 16 contains a type definition for an element which is a pointer to type 16. -If a field is a static member (this is a C++ feature in which a single +If a field is a static member (this is a C@t{++} feature in which a single variable appears to be a field of every structure of a given type) it still starts out with the field name, a colon, and the type, but then instead of a comma, bit position, comma, and bit size, there is a colon followed by the name of the variable which each such field refers to. -If the structure has methods (a C++ feature), they follow the non-method +If the structure has methods (a C@t{++} feature), they follow the non-method fields; see @ref{Cplusplus}. @node Typedefs @@ -2140,8 +2140,8 @@ the stab describes an enumeration, structure, or union tag. The type descriptor @samp{u}, following the @samp{23=} of the type definition, narrows it down to a union type definition. Following the @samp{u} is the number of bytes in the union. After that is a list of union element -descriptions. Their format is @var{name:type, bit offset into the -union, number of bytes for the element;}. +descriptions. Their format is @samp{@var{name}:@var{type}, @var{bit +offset into the union}, @var{number of bytes for the element};}. The stab for the union variable is: @@ -2389,7 +2389,7 @@ Symnum n_type n_othr n_desc n_value n_strx String @end example @node Cplusplus -@chapter GNU C++ Stabs +@chapter GNU C@t{++} Stabs @menu * Class Names:: C++ class names are both tags and typedefs. @@ -2409,9 +2409,9 @@ Symnum n_type n_othr n_desc n_value n_strx String @end menu @node Class Names -@section C++ Class Names +@section C@t{++} Class Names -In C++, a class name which is declared with @code{class}, @code{struct}, +In C@t{++}, a class name which is declared with @code{class}, @code{struct}, or @code{union}, is not only a tag, as in C, but also a type name. Thus there should be stabs with both @samp{t} and @samp{T} symbol descriptors (@pxref{Typedefs}). @@ -2420,7 +2420,7 @@ To save space, there is a special abbreviation for this case. If the @samp{T} symbol descriptor is followed by @samp{t}, then the stab defines both a type name and a tag. -For example, the C++ code +For example, the C@t{++} code @example struct foo @{int x;@}; @@ -2442,7 +2442,7 @@ or @node Nested Symbols @section Defining a Symbol Within Another Type -In C++, a symbol (such as a type name) can be defined within another type. +In C@t{++}, a symbol (such as a type name) can be defined within another type. @c FIXME: Needs example. In stabs, this is sometimes represented by making the name of a symbol @@ -2457,12 +2457,12 @@ then @code{foo::bar::baz} is the name of the symbol, @samp{t} is the symbol descriptor, and @samp{5=*6} is the type information. @node Basic Cplusplus Types -@section Basic Types For C++ +@section Basic Types For C@t{++} << the examples that follow are based on a01.C >> -C++ adds two more builtin types to the set defined for C. These are +C@t{++} adds two more builtin types to the set defined for C. These are the unknown type and the vtable record type. The unknown type, type 16, is defined in terms of itself like the void type. @@ -2473,7 +2473,7 @@ pfn, and delta2. pfn is the function pointer. << In boilerplate $vtbl_ptr_type, what are the fields delta, index, and delta2 used for? >> -This basic type is present in all C++ programs even if there are no +This basic type is present in all C@t{++} programs even if there are no virtual methods defined. @display @@ -2503,8 +2503,8 @@ virtual methods defined. @node Simple Classes @section Simple Class Definition -The stabs describing C++ language features are an extension of the -stabs describing C. Stabs representing C++ class types elaborate +The stabs describing C@t{++} language features are an extension of the +stabs describing C. Stabs representing C@t{++} class types elaborate extensively on the stab format used to describe structure types in C. Stabs representing class type variables look just like stabs representing C language variables. @@ -2526,20 +2526,20 @@ stab is not located between an @code{N_FUN} and an @code{N_LBRAC} stab this indi that the class is defined at file scope. If it were, then the @code{N_LSYM} would signify a local variable. -A stab describing a C++ class type is similar in format to a stab +A stab describing a C@t{++} class type is similar in format to a stab describing a C struct, with each class member shown as a field in the structure. The part of the struct format describing fields is -expanded to include extra information relevant to C++ class members. +expanded to include extra information relevant to C@t{++} class members. In addition, if the class has multiple base classes or virtual functions the struct format outside of the field parts is also augmented. -In this simple example the field part of the C++ class stab +In this simple example the field part of the C@t{++} class stab representing member data looks just like the field part of a C struct stab. The section on protections describes how its format is sometimes extended for member data. -The field part of a C++ class stab representing a member function +The field part of a C@t{++} class stab representing a member function differs substantially from the field part of a C struct stab. It still begins with @samp{name:} but then goes on to define a new type number for the member function, describe its return type, its argument types, @@ -2566,7 +2566,7 @@ occur in the @var{operator-name} string. The next part of the method description represents the arguments to the method, preceded by a colon and ending with a semi-colon. The types of the arguments are expressed in the same way argument types are expressed -in C++ name mangling. In this example an @code{int} and a @code{char} +in C@t{++} name mangling. In this example an @code{int} and a @code{char} map to @samp{ic}. This is followed by a number, a letter, and an asterisk or period, @@ -2600,7 +2600,7 @@ information present for virtual methods. @node Class Instance @section Class Instance -As shown above, describing even a simple C++ class definition is +As shown above, describing even a simple C@t{++} class definition is accomplished by massively extending the stab format used in C to describe structure types. However, once the class is defined, C stabs with no modifications can be used to describe class instances. The @@ -2627,7 +2627,7 @@ different from a standard C stab describing a local variable. @node Methods @section Method Definition -The class definition shown above declares Ameth. The C++ source below +The class definition shown above declares Ameth. The C@t{++} source below defines Ameth: @example @@ -2718,15 +2718,26 @@ compiler it can also be used in other contexts. @node Member Type Descriptor @section The @samp{@@} Type Descriptor -The @samp{@@} type descriptor is for a member (class and variable) type. -It is followed by type information for the offset basetype, a comma, and -type information for the type of the field being pointed to. (FIXME: -this is acknowledged to be gibberish. Can anyone say what really goes -here?). +The @samp{@@} type descriptor is used together with the @samp{*} type +descriptor for a pointer-to-non-static-member-data type. It is followed +by type information for the class (or union), a comma, and type +information for the member data. + +The following C@t{++} source: + +@smallexample +typedef int A::*int_in_a; +@end smallexample + +generates the following stab: + +@smallexample +.stabs "int_in_a:t20=*21=@@19,1",128,0,0,0 +@end smallexample Note that there is a conflict between this and type attributes (@pxref{String Field}); both use type descriptor @samp{@@}. -Fortunately, the @samp{@@} type descriptor used in this C++ sense always +Fortunately, the @samp{@@} type descriptor used in this C@t{++} sense always will be followed by a digit, @samp{(}, or @samp{-}, and type attributes never start with those things. @@ -2736,7 +2747,7 @@ never start with those things. In the simple class definition shown above all member data and functions were publicly accessible. The example that follows contrasts public, protected and privately accessible fields and shows -how these protections are encoded in C++ stabs. +how these protections are encoded in C@t{++} stabs. If the character following the @samp{@var{field-name}:} part of the string is @samp{/}, then the next character is the visibility. @samp{0} @@ -2750,7 +2761,7 @@ an optimized out field with a private or protected visibility). Visibility @samp{9} is not supported by GDB 4.11; this should be fixed in the next GDB release. -The following C++ source: +The following C@t{++} source: @example class vis @{ @@ -2780,7 +2791,7 @@ type float (@samp{12}), and offset and size @samp{,64,32;}. Protections for member functions are signified by one digit embedded in the field part of the stab describing the method. The digit is 0 if -private, 1 if protected and 2 if public. Consider the C++ class +private, 1 if protected and 2 if public. Consider the C@t{++} class definition below: @example @@ -2878,7 +2889,7 @@ struct is @samp{Adat}, an integer, starting at structure offset 0 and occupying 32 bits. The second field in the class struct is not explicitly defined by the -C++ class definition but is implied by the fact that the class +C@t{++} class definition but is implied by the fact that the class contains a virtual method. This field is the vtable pointer. The name of the vtable pointer field starts with @samp{$vf} and continues with a type reference to the class it is part of. In this example the type @@ -2890,7 +2901,7 @@ This is in turn defined as a pointer to another new type (22). Type 22 is the vtable itself, which is defined as an array, indexed by a range of integers between 0 and 1, and whose elements are of type -17. Type 17 was the vtable record type defined by the boilerplate C++ +17. Type 17 was the vtable record type defined by the boilerplate C@t{++} type definitions, as shown earlier. The bit offset of the vtable pointer field is 32. The number of bits @@ -2944,7 +2955,7 @@ class. This is preceded by @samp{~%} and followed by a final semi-colon. @node Inheritance @section Inheritance -Stabs describing C++ derived classes include additional sections that +Stabs describing C@t{++} derived classes include additional sections that describe the inheritance hierarchy of the class. A derived class stab also encodes the number of base classes. For each base class it tells if the base class is virtual or not, and if the inheritance is private @@ -3275,13 +3286,13 @@ GNU Modula2 definition module dependency; see @ref{N_DEFD}. Function start/body/end line numbers (Solaris2). @item 0x50 N_EHDECL -GNU C++ exception variable; see @ref{N_EHDECL}. +GNU C@t{++} exception variable; see @ref{N_EHDECL}. @item 0x50 N_MOD2 Modula2 info "for imc" (according to Ultrix V4.0); see @ref{N_MOD2}. @item 0x54 N_CATCH -GNU C++ @code{catch} clause; see @ref{N_CATCH}. +GNU C@t{++} @code{catch} clause; see @ref{N_CATCH}. @item 0x60 N_SSYM Structure of union element; see @ref{N_SSYM}. @@ -3375,7 +3386,7 @@ for more information about their use. Variable on the stack; see @ref{Stack Variables}. @item : -C++ nested symbol; see @xref{Nested Symbols}. +C@t{++} nested symbol; see @xref{Nested Symbols}. @item a Parameter passed by reference in register; see @ref{Reference Parameters}. @@ -3388,7 +3399,7 @@ Constant; see @ref{Constants}. @item C Conformant array bound (Pascal, maybe other languages); @ref{Conformant -Arrays}. Name of a caught exception (GNU C++). These can be +Arrays}. Name of a caught exception (GNU C@t{++}). These can be distinguished because the latter uses @code{N_CATCH} and the former uses another symbol type. @@ -3489,17 +3500,17 @@ Type reference; see @ref{String Field}. Reference to builtin type; see @ref{Negative Type Numbers}. @item # -Method (C++); see @ref{Method Type Descriptor}. +Method (C@t{++}); see @ref{Method Type Descriptor}. @item * Pointer; see @ref{Miscellaneous Types}. @item & -Reference (C++). +Reference (C@t{++}). @item @@ Type Attributes (AIX); see @ref{String Field}. Member (class and variable) -type (GNU C++); see @ref{Member Type Descriptor}. +type (GNU C@t{++}); see @ref{Member Type Descriptor}. @item a Array; see @ref{Arrays}. @@ -3604,7 +3615,7 @@ Wide character; see @ref{Builtin Type Descriptors}. Cross-reference; see @ref{Cross-References}. @item Y -Used by IBM's xlC C++ compiler (for structures, I think). +Used by IBM's xlC C@t{++} compiler (for structures, I think). @item z gstring; see @ref{Strings}. @@ -3746,7 +3757,7 @@ if it is imported with the GNU M2 keyword @code{%INITIALIZE}. Perhaps @deffn @code{.stabs} N_EHDECL @findex N_EHDECL -GNU C++ exception variable <>. +GNU C@t{++} exception variable <>. "@var{string} is variable name" @@ -3768,9 +3779,9 @@ Note: conflicts with @code{N_EHDECL} <> @deffn @code{.stabn} N_CATCH @findex N_CATCH -GNU C++ @code{catch} clause +GNU C@t{++} @code{catch} clause -GNU C++ @code{catch} clause. The value is its address. The desc field +GNU C@t{++} @code{catch} clause. The value is its address. The desc field is nonzero if this entry is immediately followed by a @code{CAUGHT} stab saying what exception was caught. Multiple @code{CAUGHT} stabs means that multiple exceptions can be caught here. If desc is 0, it means all @@ -4015,6 +4026,10 @@ is no more work than having the linker relocate ELF symbols, and it solves the problem of having to associate the ELF and stab symbols. However, no one has yet designed or implemented such a scheme. +@raisesections +@include fdl.texi +@lowersections + @node Symbol Types Index @unnumbered Symbol Types Index diff --git a/contrib/gdb/gdb/doublest.c b/contrib/gdb/gdb/doublest.c index a4b4b763f7f..3f283e13ffa 100644 --- a/contrib/gdb/gdb/doublest.c +++ b/contrib/gdb/gdb/doublest.c @@ -1,7 +1,8 @@ /* Floating point routines for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -172,8 +173,10 @@ convert_floatformat_to_doublest (const struct floatformat *fmt, special_exponent = exponent == 0 || exponent == fmt->exp_nan; -/* Don't bias NaNs. Use minimum exponent for denorms. For simplicity, - we don't check for zero as the exponent doesn't matter. */ + /* Don't bias NaNs. Use minimum exponent for denorms. For simplicity, + we don't check for zero as the exponent doesn't matter. Note the cast + to int; exp_bias is unsigned, so it's important to make sure the + operation is done in signed arithmetic. */ if (!special_exponent) exponent -= fmt->exp_bias; else if (exponent == 0) @@ -401,7 +404,15 @@ convert_doublest_to_floatformat (CONST struct floatformat *fmt, { mant_long <<= 1; mant_long &= 0xffffffffL; - mant_bits -= 1; + /* If we are processing the top 32 mantissa bits of a doublest + so as to convert to a float value with implied integer bit, + we will only be putting 31 of those 32 bits into the + final value due to the discarding of the top bit. In the + case of a small float value where the number of mantissa + bits is less than 32, discarding the top bit does not alter + the number of bits we will be adding to the result. */ + if (mant_bits == 32) + mant_bits -= 1; } if (mant_bits < 32) @@ -622,7 +633,7 @@ floatformat_from_doublest (const struct floatformat *fmt, target-dependent code, the format of floating-point types is known, but not passed on by GDB. This should be fixed. */ -const struct floatformat * +static const struct floatformat * floatformat_from_length (int len) { if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT) @@ -631,6 +642,14 @@ floatformat_from_length (int len) return TARGET_DOUBLE_FORMAT; else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT) return TARGET_LONG_DOUBLE_FORMAT; + /* On i386 the 'long double' type takes 96 bits, + while the real number of used bits is only 80, + both in processor and in memory. + The code below accepts the real bit size. */ + else if ((TARGET_LONG_DOUBLE_FORMAT != NULL) + && (len * TARGET_CHAR_BIT == + TARGET_LONG_DOUBLE_FORMAT->totalsize)) + return TARGET_LONG_DOUBLE_FORMAT; return NULL; } @@ -653,15 +672,15 @@ floatformat_from_type (const struct type *type) /* Extract a floating-point number of length LEN from a target-order byte-stream at ADDR. Returns the value as type DOUBLEST. */ -DOUBLEST -extract_floating (const void *addr, int len) +static DOUBLEST +extract_floating_by_length (const void *addr, int len) { const struct floatformat *fmt = floatformat_from_length (len); DOUBLEST val; if (fmt == NULL) { - warning ("Can't store a floating-point number of %d bytes.", len); + warning ("Can't extract a floating-point number of %d bytes.", len); return NAN; } @@ -669,11 +688,17 @@ extract_floating (const void *addr, int len) return val; } +DOUBLEST +deprecated_extract_floating (const void *addr, int len) +{ + return extract_floating_by_length (addr, len); +} + /* Store VAL as a floating-point number of length LEN to a target-order byte-stream at ADDR. */ -void -store_floating (void *addr, int len, DOUBLEST val) +static void +store_floating_by_length (void *addr, int len, DOUBLEST val) { const struct floatformat *fmt = floatformat_from_length (len); @@ -681,11 +706,18 @@ store_floating (void *addr, int len, DOUBLEST val) { warning ("Can't store a floating-point number of %d bytes.", len); memset (addr, 0, len); + return; } floatformat_from_doublest (fmt, &val, addr); } +void +deprecated_store_floating (void *addr, int len, DOUBLEST val) +{ + store_floating_by_length (addr, len, val); +} + /* Extract a floating-point number of type TYPE from a target-order byte-stream at ADDR. Returns the value as type DOUBLEST. */ @@ -697,7 +729,9 @@ extract_typed_floating (const void *addr, const struct type *type) gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); if (TYPE_FLOATFORMAT (type) == NULL) - return extract_floating (addr, TYPE_LENGTH (type)); + /* Not all code remembers to set the FLOATFORMAT (language + specific code? stabs?) so handle that here as a special case. */ + return extract_floating_by_length (addr, TYPE_LENGTH (type)); floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval); return retval; @@ -732,7 +766,9 @@ store_typed_floating (void *addr, const struct type *type, DOUBLEST val) memset (addr, 0, TYPE_LENGTH (type)); if (TYPE_FLOATFORMAT (type) == NULL) - store_floating (addr, TYPE_LENGTH (type), val); + /* Not all code remembers to set the FLOATFORMAT (language + specific code? stabs?) so handle that here as a special case. */ + store_floating_by_length (addr, TYPE_LENGTH (type), val); else floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr); } diff --git a/contrib/gdb/gdb/doublest.h b/contrib/gdb/gdb/doublest.h index 920d7026db4..668efa71cf3 100644 --- a/contrib/gdb/gdb/doublest.h +++ b/contrib/gdb/gdb/doublest.h @@ -1,7 +1,8 @@ /* Floating point definitions for GDB. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -23,6 +24,8 @@ #ifndef DOUBLEST_H #define DOUBLEST_H +struct type; + /* Setup definitions for host and target floating point formats. We need to consider the format for `float', `double', and `long double' for both target and host. We need to do this so that we know what kind of conversions need @@ -59,12 +62,16 @@ extern int floatformat_is_negative (const struct floatformat *, char *); extern int floatformat_is_nan (const struct floatformat *, char *); extern char *floatformat_mantissa (const struct floatformat *, char *); -/* These two functions are deprecated in favour of - extract_typed_floating and store_typed_floating. See comments in - 'doublest.c' for details. */ +/* These functions have been replaced by extract_typed_floating and + store_typed_floating. -extern DOUBLEST extract_floating (const void *addr, int len); -extern void store_floating (void *addr, int len, DOUBLEST val); + Most calls are passing in TYPE_LENGTH (TYPE) so can be changed to + just pass the TYPE. The remainder pass in the length of a + register, those calls should instead pass in the floating point + type that corresponds to that length. */ + +extern DOUBLEST deprecated_extract_floating (const void *addr, int len); +extern void deprecated_store_floating (void *addr, int len, DOUBLEST val); /* Given TYPE, return its floatformat. TYPE_FLOATFORMAT() may return NULL. type_floatformat() detects that and returns a floatformat diff --git a/contrib/gdb/gdb/dpx2-nat.c b/contrib/gdb/gdb/dpx2-nat.c new file mode 100644 index 00000000000..488c06a5383 --- /dev/null +++ b/contrib/gdb/gdb/dpx2-nat.c @@ -0,0 +1,83 @@ +/* DPX2 host interface. + Copyright 1988, 1989, 1991, 1993, 1995, 2000 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" + +#include "gdb_string.h" +#include +#include +#include +#include +#include +#include +#include + + +/* This table must line up with REGISTER_NAME in "m68k-tdep.c". */ +/* symbols like 'A0' come from */ +static int regmap[] = +{ + R0, R1, R2, R3, R4, R5, R6, R7, + A0, A1, A2, A3, A4, A5, A6, SP, + PS, PC, + FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7, + FP_CR, FP_SR, FP_IAR +}; + +/* blockend is the value of u.u_ar0, and points to the + * place where D0 is stored + */ + +int +dpx2_register_u_addr (int blockend, int regnum) +{ + if (regnum < FP0_REGNUM) + return (blockend + 4 * regmap[regnum]); + else + return (int) &(((struct user *) 0)->u_fpstate[regmap[regnum]]); +} + +/* This is the amount to subtract from u.u_ar0 + to get the offset in the core file of the register values. + Unfortunately this is not provided in the system header files. + To make matters worse, this value also differs between + the dpx/2200 and dpx/2300 models and nlist is not available on the dpx2. + We use utsname() to decide on which model we are running. + FIXME: This breaks cross examination of core files (it would not be hard + to check whether u.u_ar0 is between 0x7fff5000 and 0x7fffc000 and if so + use 0x7fff5000 and if not use 0x7fffc000. FIXME). */ + +#define KERNEL_U_ADDR_200 0x7fff5000 +#define KERNEL_U_ADDR_300 0x7fffc000 + +CORE_ADDR kernel_u_addr; + +void +_initialize_dpx2_nat (void) +{ + struct utsname uts; + + if (uname (&uts) == 0 && strcmp (uts.machine, "DPX/2200") == 0) + kernel_u_addr = KERNEL_U_ADDR_200; + else + kernel_u_addr = KERNEL_U_ADDR_300; +} diff --git a/contrib/gdb/gdb/dsrec.c b/contrib/gdb/gdb/dsrec.c index 5f2c2d703ce..142260002ff 100644 --- a/contrib/gdb/gdb/dsrec.c +++ b/contrib/gdb/gdb/dsrec.c @@ -23,6 +23,8 @@ #include "serial.h" #include "srec.h" #include +#include "gdb_assert.h" +#include "gdb_string.h" extern void report_transfer_performance (unsigned long, time_t, time_t); @@ -223,10 +225,6 @@ make_srec (char *srec, CORE_ADDR targ_addr, bfd *abfd, asection *sect, const static char data_code_table[] = "123"; const static char term_code_table[] = "987"; const static char header_code_table[] = "000"; - const static char *formats[] = - {"S%c%02X%04X", - "S%c%02X%06X", - "S%c%02X%08X"}; char const *code_table; int addr_size; int payload_size; @@ -271,9 +269,10 @@ make_srec (char *srec, CORE_ADDR targ_addr, bfd *abfd, asection *sect, payload_size = 0; /* Term or header packets have no payload */ /* Output the header. */ - - sprintf (srec, formats[addr_size - 2], code_table[addr_size - 2], - addr_size + payload_size + 1, (int) targ_addr); + snprintf (srec, (*maxrecsize) + 1, "S%c%02X%0*X", + code_table[addr_size - 2], + addr_size + payload_size + 1, + addr_size * 2, (int) targ_addr); /* Note that the checksum is calculated on the raw data, not the hexified data. It includes the length, address and the data @@ -287,6 +286,9 @@ make_srec (char *srec, CORE_ADDR targ_addr, bfd *abfd, asection *sect, + ((targ_addr >> 16) & 0xff) + ((targ_addr >> 24) & 0xff)); + /* NOTE: cagney/2003-08-10: The equation is old. Check that the + recent snprintf changes match that equation. */ + gdb_assert (strlen (srec) == 1 + 1 + 2 + addr_size * 2); p = srec + 1 + 1 + 2 + addr_size * 2; /* Build the Srecord. */ diff --git a/contrib/gdb/gdb/dummy-frame.c b/contrib/gdb/gdb/dummy-frame.c new file mode 100644 index 00000000000..3b10c51640b --- /dev/null +++ b/contrib/gdb/gdb/dummy-frame.c @@ -0,0 +1,466 @@ +/* Code dealing with dummy stack frames, for GDB, the GNU debugger. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software + Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#include "defs.h" +#include "dummy-frame.h" +#include "regcache.h" +#include "frame.h" +#include "inferior.h" +#include "gdb_assert.h" +#include "frame-unwind.h" +#include "command.h" +#include "gdbcmd.h" + +static void dummy_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id); + +/* Dummy frame. This saves the processor state just prior to setting + up the inferior function call. Older targets save the registers + on the target stack (but that really slows down function calls). */ + +struct dummy_frame +{ + struct dummy_frame *next; + + /* These values belong to the caller (the previous frame, the frame + that this unwinds back to). */ + CORE_ADDR pc; + CORE_ADDR fp; + CORE_ADDR sp; + CORE_ADDR top; + struct frame_id id; + struct regcache *regcache; + + /* Address range of the call dummy code. Look for PC in the range + [LO..HI) (after allowing for DECR_PC_AFTER_BREAK). */ + CORE_ADDR call_lo; + CORE_ADDR call_hi; +}; + +static struct dummy_frame *dummy_frame_stack = NULL; + +/* Function: find_dummy_frame(pc, fp, sp) + + Search the stack of dummy frames for one matching the given PC and + FP/SP. Unlike pc_in_dummy_frame(), this function doesn't need to + adjust for DECR_PC_AFTER_BREAK. This is because it is only legal + to call this function after the PC has been adjusted. */ + +static struct dummy_frame * +find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp) +{ + struct dummy_frame *dummyframe; + + for (dummyframe = dummy_frame_stack; dummyframe != NULL; + dummyframe = dummyframe->next) + { + /* Does the PC fall within the dummy frame's breakpoint + instruction. If not, discard this one. */ + if (!(pc >= dummyframe->call_lo && pc < dummyframe->call_hi)) + continue; + /* Does the FP match? */ + if (dummyframe->top != 0) + { + /* If the target architecture explicitly saved the + top-of-stack before the inferior function call, assume + that that same architecture will always pass in an FP + (frame base) value that eactly matches that saved TOS. + Don't check the saved SP and SP as they can lead to false + hits. */ + if (fp != dummyframe->top) + continue; + } + else + { + /* An older target that hasn't explicitly or implicitly + saved the dummy frame's top-of-stack. Try matching the + FP against the saved SP and FP. NOTE: If you're trying + to fix a problem with GDB not correctly finding a dummy + frame, check the comments that go with FRAME_ALIGN() and + UNWIND_DUMMY_ID(). */ + if (fp != dummyframe->fp && fp != dummyframe->sp) + continue; + } + /* The FP matches this dummy frame. */ + return dummyframe; + } + + return NULL; +} + +struct regcache * +deprecated_find_dummy_frame_regcache (CORE_ADDR pc, CORE_ADDR fp) +{ + struct dummy_frame *dummy = find_dummy_frame (pc, fp); + if (dummy != NULL) + return dummy->regcache; + else + return NULL; +} + +char * +deprecated_generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp) +{ + struct regcache *regcache = deprecated_find_dummy_frame_regcache (pc, fp); + if (regcache == NULL) + return NULL; + return deprecated_grub_regcache_for_registers (regcache); +} + +/* Function: pc_in_call_dummy (pc, sp, fp) + + Return true if the PC falls in a dummy frame created by gdb for an + inferior call. The code below which allows DECR_PC_AFTER_BREAK is + for infrun.c, which may give the function a PC without that + subtracted out. */ + +int +generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp) +{ + return pc_in_dummy_frame (pc); +} + +/* Return non-zero if the PC falls in a dummy frame. + + The code below which allows DECR_PC_AFTER_BREAK is for infrun.c, + which may give the function a PC without that subtracted out. + + FIXME: cagney/2002-11-23: This is silly. Surely "infrun.c" can + figure out what the real PC (as in the resume address) is BEFORE + calling this function (Oh, and I'm not even sure that this function + is called with an decremented PC, the call to pc_in_call_dummy() in + that file is conditional on + !DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET_P yet generic dummy + targets set DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET. True?). */ + +int +pc_in_dummy_frame (CORE_ADDR pc) +{ + struct dummy_frame *dummyframe; + for (dummyframe = dummy_frame_stack; + dummyframe != NULL; + dummyframe = dummyframe->next) + { + if ((pc >= dummyframe->call_lo) + && (pc < dummyframe->call_hi + DECR_PC_AFTER_BREAK)) + return 1; + } + return 0; +} + +/* Function: read_register_dummy + Find a saved register from before GDB calls a function in the inferior */ + +CORE_ADDR +deprecated_read_register_dummy (CORE_ADDR pc, CORE_ADDR fp, int regno) +{ + struct regcache *dummy_regs = deprecated_find_dummy_frame_regcache (pc, fp); + + if (dummy_regs) + { + /* NOTE: cagney/2002-08-12: Replaced a call to + regcache_raw_read_as_address() with a call to + regcache_cooked_read_unsigned(). The old, ...as_address + function was eventually calling extract_unsigned_integer (nee + extract_address) to unpack the registers value. The below is + doing an unsigned extract so that it is functionally + equivalent. The read needs to be cooked as, otherwise, it + will never correctly return the value of a register in the + [NUM_REGS .. NUM_REGS+NUM_PSEUDO_REGS) range. */ + ULONGEST val; + regcache_cooked_read_unsigned (dummy_regs, regno, &val); + return val; + } + else + return 0; +} + +/* Save all the registers on the dummy frame stack. Most ports save the + registers on the target stack. This results in lots of unnecessary memory + references, which are slow when debugging via a serial line. Instead, we + save all the registers internally, and never write them to the stack. The + registers get restored when the called function returns to the entry point, + where a breakpoint is laying in wait. */ + +void +generic_push_dummy_frame (void) +{ + struct dummy_frame *dummy_frame; + CORE_ADDR fp = get_frame_base (get_current_frame ()); + + /* check to see if there are stale dummy frames, + perhaps left over from when a longjump took us out of a + function that was called by the debugger */ + + dummy_frame = dummy_frame_stack; + while (dummy_frame) + if (INNER_THAN (dummy_frame->fp, fp)) /* stale -- destroy! */ + { + dummy_frame_stack = dummy_frame->next; + regcache_xfree (dummy_frame->regcache); + xfree (dummy_frame); + dummy_frame = dummy_frame_stack; + } + else + dummy_frame = dummy_frame->next; + + dummy_frame = xmalloc (sizeof (struct dummy_frame)); + dummy_frame->regcache = regcache_xmalloc (current_gdbarch); + + dummy_frame->pc = read_pc (); + dummy_frame->sp = read_sp (); + dummy_frame->top = 0; + dummy_frame->fp = fp; + dummy_frame->id = get_frame_id (get_current_frame ()); + regcache_cpy (dummy_frame->regcache, current_regcache); + dummy_frame->next = dummy_frame_stack; + dummy_frame_stack = dummy_frame; +} + +void +generic_save_dummy_frame_tos (CORE_ADDR sp) +{ + dummy_frame_stack->top = sp; +} + +/* Record the upper/lower bounds on the address of the call dummy. */ + +void +generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi) +{ + dummy_frame_stack->call_lo = lo; + dummy_frame_stack->call_hi = hi; +} + +/* Restore the machine state from either the saved dummy stack or a + real stack frame. */ + +void +generic_pop_current_frame (void (*popper) (struct frame_info * frame)) +{ + struct frame_info *frame = get_current_frame (); + if (get_frame_type (frame) == DUMMY_FRAME) + /* NOTE: cagney/2002-22-23: Does this ever occure? Surely a dummy + frame will have already been poped by the "infrun.c" code. */ + generic_pop_dummy_frame (); + else + (*popper) (frame); +} + +/* Discard the innermost dummy frame from the dummy frame stack + (passed in as a parameter). */ + +static void +discard_innermost_dummy (struct dummy_frame **stack) +{ + struct dummy_frame *tbd = (*stack); + (*stack) = (*stack)->next; + regcache_xfree (tbd->regcache); + xfree (tbd); +} + +void +generic_pop_dummy_frame (void) +{ + struct dummy_frame *dummy_frame = dummy_frame_stack; + + /* FIXME: what if the first frame isn't the right one, eg.. + because one call-by-hand function has done a longjmp into another one? */ + + if (!dummy_frame) + error ("Can't pop dummy frame!"); + regcache_cpy (current_regcache, dummy_frame->regcache); + flush_cached_frames (); + + discard_innermost_dummy (&dummy_frame_stack); +} + +/* Given a call-dummy dummy-frame, return the registers. Here the + register value is taken from the local copy of the register buffer. */ + +static void +dummy_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimized, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnum, void *bufferp) +{ + struct dummy_frame *dummy; + struct frame_id id; + + /* Call the ID method which, if at all possible, will set the + prologue cache. */ + dummy_frame_this_id (next_frame, this_prologue_cache, &id); + dummy = (*this_prologue_cache); + gdb_assert (dummy != NULL); + + /* Describe the register's location. Generic dummy frames always + have the register value in an ``expression''. */ + *optimized = 0; + *lvalp = not_lval; + *addrp = 0; + *realnum = -1; + + /* If needed, find and return the value of the register. */ + if (bufferp != NULL) + { + /* Return the actual value. */ + /* Use the regcache_cooked_read() method so that it, on the fly, + constructs either a raw or pseudo register from the raw + register cache. */ + regcache_cooked_read (dummy->regcache, regnum, bufferp); + } +} + +/* Assuming that THIS frame is a dummy (remember, the NEXT and not + THIS frame is passed in), return the ID of THIS frame. That ID is + determined by examining the NEXT frame's unwound registers using + the method unwind_dummy_id(). As a side effect, THIS dummy frame's + dummy cache is located and and saved in THIS_PROLOGUE_CACHE. */ + +static void +dummy_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct dummy_frame *dummy = (*this_prologue_cache); + if (dummy != NULL) + { + (*this_id) = dummy->id; + return; + } + /* When unwinding a normal frame, the stack structure is determined + by analyzing the frame's function's code (be it using brute force + prologue analysis, or the dwarf2 CFI). In the case of a dummy + frame, that simply isn't possible. The The PC is either the + program entry point, or some random address on the stack. Trying + to use that PC to apply standard frame ID unwind techniques is + just asking for trouble. */ + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) + { + /* Use an architecture specific method to extract the prev's + dummy ID from the next frame. Note that this method uses + frame_register_unwind to obtain the register values needed to + determine the dummy frame's ID. */ + (*this_id) = gdbarch_unwind_dummy_id (current_gdbarch, next_frame); + } + else if (frame_relative_level (next_frame) < 0) + { + /* We're unwinding a sentinel frame, the PC of which is pointing + at a stack dummy. Fake up the dummy frame's ID using the + same sequence as is found a traditional unwinder. Once all + architectures supply the unwind_dummy_id method, this code + can go away. */ + (*this_id) = frame_id_build (deprecated_read_fp (), read_pc ()); + } + else if (legacy_frame_p (current_gdbarch) + && get_prev_frame (next_frame)) + { + /* Things are looking seriously grim! Assume that the legacy + get_prev_frame code has already created THIS frame and linked + it in to the frame chain (a pretty bold assumption), extract + the ID from THIS base / pc. */ + (*this_id) = frame_id_build (get_frame_base (get_prev_frame (next_frame)), + get_frame_pc (get_prev_frame (next_frame))); + } + else + { + /* Ouch! We're not trying to find the innermost frame's ID yet + we're trying to unwind to a dummy. The architecture must + provide the unwind_dummy_id() method. Abandon the unwind + process but only after first warning the user. */ + internal_warning (__FILE__, __LINE__, + "Missing unwind_dummy_id architecture method"); + (*this_id) = null_frame_id; + return; + } + (*this_prologue_cache) = find_dummy_frame ((*this_id).code_addr, + (*this_id).stack_addr); +} + +static struct frame_unwind dummy_frame_unwind = +{ + DUMMY_FRAME, + dummy_frame_this_id, + dummy_frame_prev_register +}; + +const struct frame_unwind * +dummy_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + if (DEPRECATED_PC_IN_CALL_DUMMY_P () + ? DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0) + : pc_in_dummy_frame (pc)) + return &dummy_frame_unwind; + else + return NULL; +} + +static void +fprint_dummy_frames (struct ui_file *file) +{ + struct dummy_frame *s; + for (s = dummy_frame_stack; s != NULL; s = s->next) + { + gdb_print_host_address (s, file); + fprintf_unfiltered (file, ":"); + fprintf_unfiltered (file, " pc=0x%s", paddr (s->pc)); + fprintf_unfiltered (file, " fp=0x%s", paddr (s->fp)); + fprintf_unfiltered (file, " sp=0x%s", paddr (s->sp)); + fprintf_unfiltered (file, " top=0x%s", paddr (s->top)); + fprintf_unfiltered (file, " id="); + fprint_frame_id (file, s->id); + fprintf_unfiltered (file, " call_lo=0x%s", paddr (s->call_lo)); + fprintf_unfiltered (file, " call_hi=0x%s", paddr (s->call_hi)); + fprintf_unfiltered (file, "\n"); + } +} + +static void +maintenance_print_dummy_frames (char *args, int from_tty) +{ + if (args == NULL) + fprint_dummy_frames (gdb_stdout); + else + { + struct ui_file *file = gdb_fopen (args, "w"); + if (file == NULL) + perror_with_name ("maintenance print dummy-frames"); + fprint_dummy_frames (file); + ui_file_delete (file); + } +} + +extern void _initialize_dummy_frame (void); + +void +_initialize_dummy_frame (void) +{ + add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames, + "Print the contents of the internal dummy-frame stack.", + &maintenanceprintlist); + +} diff --git a/contrib/gdb/gdb/dummy-frame.h b/contrib/gdb/gdb/dummy-frame.h new file mode 100644 index 00000000000..cde9eb7f12f --- /dev/null +++ b/contrib/gdb/gdb/dummy-frame.h @@ -0,0 +1,86 @@ +/* Code dealing with dummy stack frames, for GDB, the GNU debugger. + + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined (DUMMY_FRAME_H) +#define DUMMY_FRAME_H 1 + +struct frame_info; +struct regcache; +struct frame_unwind; +struct frame_id; + +/* GENERIC DUMMY FRAMES + + The following code serves to maintain the dummy stack frames for + inferior function calls (ie. when gdb calls into the inferior via + call_function_by_hand). This code saves the machine state before + the call in host memory, so we must maintain an independent stack + and keep it consistant etc. I am attempting to make this code + generic enough to be used by many targets. + + The cheapest and most generic way to do CALL_DUMMY on a new target + is probably to define CALL_DUMMY to be empty, + DEPRECATED_CALL_DUMMY_LENGTH to zero, and CALL_DUMMY_LOCATION to + AT_ENTRY. Then you must remember to define PUSH_RETURN_ADDRESS, + because no call instruction will be being executed by the target. + Also DEPRECATED_FRAME_CHAIN_VALID as + generic_{file,func}_frame_chain_valid and do not set + DEPRECATED_FIX_CALL_DUMMY. */ + +/* If the PC falls in a dummy frame, return a dummy frame + unwinder. */ + +extern const struct frame_unwind *dummy_frame_sniffer (struct frame_info *next_frame); + +/* Does the PC fall in a dummy frame? + + This function is used by "frame.c" when creating a new `struct + frame_info'. + + Note that there is also very similar code in breakpoint.c (where + the bpstat stop reason is computed). It is looking for a PC + falling on a dummy_frame breakpoint. Perhaphs this, and that code + should be combined? + + Architecture dependant code, that has access to a frame, should not + use this function. Instead (get_frame_type() == DUMMY_FRAME) + should be used. + + Hmm, but what about threads? When the dummy-frame code tries to + relocate a dummy frame's saved registers it definitly needs to + differentiate between threads (otherwize it will do things like + clean-up the wrong threads frames). However, when just trying to + identify a dummy-frame that shouldn't matter. The wost that can + happen is that a thread is marked as sitting in a dummy frame when, + in reality, its corrupted its stack, to the point that a PC is + pointing into a dummy frame. */ + +extern int pc_in_dummy_frame (CORE_ADDR pc); + +/* Return the regcache that belongs to the dummy-frame identifed by PC + and FP, or NULL if no such frame exists. */ +/* FIXME: cagney/2002-11-08: The function only exists because of + deprecated_generic_get_saved_register. Eliminate that function and + this, to, can go. */ + +extern struct regcache *deprecated_find_dummy_frame_regcache (CORE_ADDR pc, + CORE_ADDR fp); +#endif /* !defined (DUMMY_FRAME_H) */ diff --git a/contrib/gdb/gdb/dve3900-rom.c b/contrib/gdb/gdb/dve3900-rom.c new file mode 100644 index 00000000000..fe2fcedce65 --- /dev/null +++ b/contrib/gdb/gdb/dve3900-rom.c @@ -0,0 +1,1069 @@ +/* Remote debugging interface for Densan DVE-R3900 ROM monitor for + GDB, the GNU debugger. + Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "monitor.h" +#include "serial.h" +#include "inferior.h" +#include "command.h" +#include "gdb_string.h" +#include +#include "regcache.h" +#include "mips-tdep.h" + +/* Type of function passed to bfd_map_over_sections. */ + +typedef void (*section_map_func) (bfd * abfd, asection * sect, void *obj); + +/* Packet escape character used by Densan monitor. */ + +#define PESC 0xdc + +/* Maximum packet size. This is actually smaller than necessary + just to be safe. */ + +#define MAXPSIZE 1024 + +/* External functions. */ + +extern void report_transfer_performance (unsigned long, time_t, time_t); + +/* Certain registers are "bitmapped", in that the monitor can only display + them or let the user modify them as a series of named bitfields. + This structure describes a field in a bitmapped register. */ + +struct bit_field + { + char *prefix; /* string appearing before the value */ + char *suffix; /* string appearing after the value */ + char *user_name; /* name used by human when entering field value */ + int length; /* number of bits in the field */ + int start; /* starting (least significant) bit number of field */ + }; + +/* Local functions for register manipulation. */ + +static void r3900_supply_register (char *regname, int regnamelen, + char *val, int vallen); +static void fetch_bad_vaddr (void); +static unsigned long fetch_fields (struct bit_field *bf); +static void fetch_bitmapped_register (int regno, struct bit_field *bf); +static void r3900_fetch_registers (int regno); +static void store_bitmapped_register (int regno, struct bit_field *bf); +static void r3900_store_registers (int regno); + +/* Local functions for fast binary loading. */ + +static void write_long (char *buf, long n); +static void write_long_le (char *buf, long n); +static int debug_readchar (int hex); +static void debug_write (unsigned char *buf, int buflen); +static void ignore_packet (void); +static void send_packet (char type, unsigned char *buf, int buflen, int seq); +static void process_read_request (unsigned char *buf, int buflen); +static void count_section (bfd * abfd, asection * s, + unsigned int *section_count); +static void load_section (bfd * abfd, asection * s, unsigned int *data_count); +static void r3900_load (char *filename, int from_tty); + +/* Miscellaneous local functions. */ + +static void r3900_open (char *args, int from_tty); + + +/* Pointers to static functions in monitor.c for fetching and storing + registers. We can't use these function in certain cases where the Densan + monitor acts perversely: for registers that it displays in bit-map + format, and those that can't be modified at all. In those cases + we have to use our own functions to fetch and store their values. */ + +static void (*orig_monitor_fetch_registers) (int regno); +static void (*orig_monitor_store_registers) (int regno); + +/* Pointer to static function in monitor. for loading programs. + We use this function for loading S-records via the serial link. */ + +static void (*orig_monitor_load) (char *file, int from_tty); + +/* This flag is set if a fast ethernet download should be used. */ + +static int ethernet = 0; + +/* This array of registers needs to match the indexes used by GDB. The + whole reason this exists is because the various ROM monitors use + different names than GDB does, and don't support all the registers + either. */ + +static char *r3900_regnames[] = +{ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + + "S", /* PS_REGNUM */ + "l", /* MIPS_EMBED_LO_REGNUM */ + "h", /* MIPS_EMBED_HI_REGNUM */ + "B", /* MIPS_EMBED_BADVADDR_REGNUM */ + "Pcause", /* MIPS_EMBED_CAUSE_REGNUM */ + "p" /* MIPS_EMBED_PC_REGNUM */ +}; + + +/* Table of register names produced by monitor's register dump command. */ + +static struct reg_entry + { + char *name; + int regno; + } +reg_table[] = +{ + { + "r0_zero", 0 + } + , + { + "r1_at", 1 + } + , + { + "r2_v0", 2 + } + , + { + "r3_v1", 3 + } + , + { + "r4_a0", 4 + } + , + { + "r5_a1", 5 + } + , + { + "r6_a2", 6 + } + , + { + "r7_a3", 7 + } + , + { + "r8_t0", 8 + } + , + { + "r9_t1", 9 + } + , + { + "r10_t2", 10 + } + , + { + "r11_t3", 11 + } + , + { + "r12_t4", 12 + } + , + { + "r13_t5", 13 + } + , + { + "r14_t6", 14 + } + , + { + "r15_t7", 15 + } + , + { + "r16_s0", 16 + } + , + { + "r17_s1", 17 + } + , + { + "r18_s2", 18 + } + , + { + "r19_s3", 19 + } + , + { + "r20_s4", 20 + } + , + { + "r21_s5", 21 + } + , + { + "r22_s6", 22 + } + , + { + "r23_s7", 23 + } + , + { + "r24_t8", 24 + } + , + { + "r25_t9", 25 + } + , + { + "r26_k0", 26 + } + , + { + "r27_k1", 27 + } + , + { + "r28_gp", 28 + } + , + { + "r29_sp", 29 + } + , + { + "r30_fp", 30 + } + , + { + "r31_ra", 31 + } + , + { + "HI", MIPS_EMBED_HI_REGNUM + } + , + { + "LO", MIPS_EMBED_LO_REGNUM + } + , + { + "PC", MIPS_EMBED_PC_REGNUM + } + , + { + "BadV", MIPS_EMBED_BADVADDR_REGNUM + } + , + { + NULL, 0 + } +}; + + +/* The monitor displays the cache register along with the status register, + as if they were a single register. So when we want to fetch the + status register, parse but otherwise ignore the fields of the + cache register that the monitor displays. Register fields that should + be ignored have a length of zero in the tables below. */ + +static struct bit_field status_fields[] = +{ + /* Status register portion */ + {"SR[]", "sw", 2, 8}, + {"[]", "iec", 1, 0}, + + /* Cache register portion (dummy for parsing only) */ + {"CR[] ", "dalc", 0, 8}, + + {NULL, NULL, 0, 0} /* end of table marker */ +}; + + +#if 0 /* FIXME: Enable when we add support for modifying cache register. */ +static struct bit_field cache_fields[] = +{ + /* Status register portion (dummy for parsing only) */ + {"SR[]", "sw", 0, 8}, + {"[]", "iec", 0, 0}, + + /* Cache register portion */ + {"CR[] ", "dalc", 1, 8}, + + {NULL, NULL, NULL, 0, 0} /* end of table marker */ +}; +#endif + + +static struct bit_field cause_fields[] = +{ + {"]", "ec", 5, 2}, + + {NULL, NULL, NULL, 0, 0} /* end of table marker */ +}; + + +/* The monitor prints register values in the form + + regname = xxxx xxxx + + We look up the register name in a table, and remove the embedded space in + the hex value before passing it to monitor_supply_register. */ + +static void +r3900_supply_register (char *regname, int regnamelen, char *val, int vallen) +{ + int regno = -1; + int i; + char valbuf[10]; + char *p; + + /* Perform some sanity checks on the register name and value. */ + if (regnamelen < 2 || regnamelen > 7 || vallen != 9) + return; + + /* Look up the register name. */ + for (i = 0; reg_table[i].name != NULL; i++) + { + int rlen = strlen (reg_table[i].name); + if (rlen == regnamelen && strncmp (regname, reg_table[i].name, rlen) == 0) + { + regno = reg_table[i].regno; + break; + } + } + if (regno == -1) + return; + + /* Copy the hex value to a buffer and eliminate the embedded space. */ + for (i = 0, p = valbuf; i < vallen; i++) + if (val[i] != ' ') + *p++ = val[i]; + *p = '\0'; + + monitor_supply_register (regno, valbuf); +} + + +/* Fetch the BadVaddr register. Unlike the other registers, this + one can't be modified, and the monitor won't even prompt to let + you modify it. */ + +static void +fetch_bad_vaddr (void) +{ + char buf[20]; + + monitor_printf ("xB\r"); + monitor_expect ("BadV=", NULL, 0); + monitor_expect_prompt (buf, sizeof (buf)); + monitor_supply_register (mips_regnum (current_gdbarch)->badvaddr, buf); +} + + +/* Read a series of bit fields from the monitor, and return their + combined binary value. */ + +static unsigned long +fetch_fields (struct bit_field *bf) +{ + char buf[20]; + unsigned long val = 0; + unsigned long bits; + + for (; bf->prefix != NULL; bf++) + { + monitor_expect (bf->prefix, NULL, 0); /* get prefix */ + monitor_expect (bf->suffix, buf, sizeof (buf)); /* hex value, suffix */ + if (bf->length != 0) + { + bits = strtoul (buf, NULL, 16); /* get field value */ + bits &= ((1 << bf->length) - 1); /* mask out useless bits */ + val |= bits << bf->start; /* insert into register */ + } + + } + + return val; +} + + +static void +fetch_bitmapped_register (int regno, struct bit_field *bf) +{ + unsigned long val; + unsigned char regbuf[MAX_REGISTER_SIZE]; + char *regname = NULL; + + if (regno >= sizeof (r3900_regnames) / sizeof (r3900_regnames[0])) + internal_error (__FILE__, __LINE__, + "fetch_bitmapped_register: regno out of bounds"); + else + regname = r3900_regnames[regno]; + + monitor_printf ("x%s\r", regname); + val = fetch_fields (bf); + monitor_printf (".\r"); + monitor_expect_prompt (NULL, 0); + + /* supply register stores in target byte order, so swap here */ + + store_unsigned_integer (regbuf, DEPRECATED_REGISTER_RAW_SIZE (regno), val); + supply_register (regno, regbuf); + +} + + +/* Fetch all registers (if regno is -1), or one register from the + monitor. For most registers, we can use the generic monitor_ + monitor_fetch_registers function. But others are displayed in + a very unusual fashion by the monitor, and must be handled specially. */ + +static void +r3900_fetch_registers (int regno) +{ + if (regno == mips_regnum (current_gdbarch)->badvaddr) + fetch_bad_vaddr (); + else if (regno == PS_REGNUM) + fetch_bitmapped_register (PS_REGNUM, status_fields); + else if (regno == mips_regnum (current_gdbarch)->cause) + fetch_bitmapped_register (mips_regnum (current_gdbarch)->cause, + cause_fields); + else + orig_monitor_fetch_registers (regno); +} + + +/* Write the new value of the bitmapped register to the monitor. */ + +static void +store_bitmapped_register (int regno, struct bit_field *bf) +{ + unsigned long oldval, newval; + char *regname = NULL; + + if (regno >= sizeof (r3900_regnames) / sizeof (r3900_regnames[0])) + internal_error (__FILE__, __LINE__, + "fetch_bitmapped_register: regno out of bounds"); + else + regname = r3900_regnames[regno]; + + /* Fetch the current value of the register. */ + monitor_printf ("x%s\r", regname); + oldval = fetch_fields (bf); + newval = read_register (regno); + + /* To save time, write just the fields that have changed. */ + for (; bf->prefix != NULL; bf++) + { + if (bf->length != 0) + { + unsigned long oldbits, newbits, mask; + + mask = (1 << bf->length) - 1; + oldbits = (oldval >> bf->start) & mask; + newbits = (newval >> bf->start) & mask; + if (oldbits != newbits) + monitor_printf ("%s %lx ", bf->user_name, newbits); + } + } + + monitor_printf (".\r"); + monitor_expect_prompt (NULL, 0); +} + + +static void +r3900_store_registers (int regno) +{ + if (regno == PS_REGNUM) + store_bitmapped_register (PS_REGNUM, status_fields); + else if (regno == mips_regnum (current_gdbarch)->cause) + store_bitmapped_register (mips_regnum (current_gdbarch)->cause, + cause_fields); + else + orig_monitor_store_registers (regno); +} + + +/* Write a 4-byte integer to the buffer in big-endian order. */ + +static void +write_long (char *buf, long n) +{ + buf[0] = (n >> 24) & 0xff; + buf[1] = (n >> 16) & 0xff; + buf[2] = (n >> 8) & 0xff; + buf[3] = n & 0xff; +} + + +/* Write a 4-byte integer to the buffer in little-endian order. */ + +static void +write_long_le (char *buf, long n) +{ + buf[0] = n & 0xff; + buf[1] = (n >> 8) & 0xff; + buf[2] = (n >> 16) & 0xff; + buf[3] = (n >> 24) & 0xff; +} + + +/* Read a character from the monitor. If remote debugging is on, + print the received character. If HEX is non-zero, print the + character in hexadecimal; otherwise, print it in ASCII. */ + +static int +debug_readchar (int hex) +{ + char buf[10]; + int c = monitor_readchar (); + + if (remote_debug > 0) + { + if (hex) + sprintf (buf, "[%02x]", c & 0xff); + else if (c == '\0') + strcpy (buf, "\\0"); + else + { + buf[0] = c; + buf[1] = '\0'; + } + puts_debug ("Read -->", buf, "<--"); + } + return c; +} + + +/* Send a buffer of characters to the monitor. If remote debugging is on, + print the sent buffer in hex. */ + +static void +debug_write (unsigned char *buf, int buflen) +{ + char s[10]; + + monitor_write (buf, buflen); + + if (remote_debug > 0) + { + while (buflen-- > 0) + { + sprintf (s, "[%02x]", *buf & 0xff); + puts_debug ("Sent -->", s, "<--"); + buf++; + } + } +} + + +/* Ignore a packet sent to us by the monitor. It send packets + when its console is in "communications interface" mode. A packet + is of this form: + + start of packet flag (one byte: 0xdc) + packet type (one byte) + length (low byte) + length (high byte) + data (length bytes) + + The last two bytes of the data field are a checksum, but we don't + bother to verify it. + */ + +static void +ignore_packet (void) +{ + int c = -1; + int len; + + /* Ignore lots of trash (messages about section addresses, for example) + until we see the start of a packet. */ + for (len = 0; len < 256; len++) + { + c = debug_readchar (0); + if (c == PESC) + break; + } + if (len == 8) + error ("Packet header byte not found; %02x seen instead.", c); + + /* Read the packet type and length. */ + c = debug_readchar (1); /* type */ + + c = debug_readchar (1); /* low byte of length */ + len = c & 0xff; + + c = debug_readchar (1); /* high byte of length */ + len += (c & 0xff) << 8; + + /* Ignore the rest of the packet. */ + while (len-- > 0) + c = debug_readchar (1); +} + + +/* Encapsulate some data into a packet and send it to the monitor. + + The 'p' packet is a special case. This is a packet we send + in response to a read ('r') packet from the monitor. This function + appends a one-byte sequence number to the data field of such a packet. + */ + +static void +send_packet (char type, unsigned char *buf, int buflen, int seq) +{ + unsigned char hdr[4]; + int len = buflen; + int sum, i; + + /* If this is a 'p' packet, add one byte for a sequence number. */ + if (type == 'p') + len++; + + /* If the buffer has a non-zero length, add two bytes for a checksum. */ + if (len > 0) + len += 2; + + /* Write the packet header. */ + hdr[0] = PESC; + hdr[1] = type; + hdr[2] = len & 0xff; + hdr[3] = (len >> 8) & 0xff; + debug_write (hdr, sizeof (hdr)); + + if (len) + { + /* Write the packet data. */ + debug_write (buf, buflen); + + /* Write the sequence number if this is a 'p' packet. */ + if (type == 'p') + { + hdr[0] = seq; + debug_write (hdr, 1); + } + + /* Write the checksum. */ + sum = 0; + for (i = 0; i < buflen; i++) + { + int tmp = (buf[i] & 0xff); + if (i & 1) + sum += tmp; + else + sum += tmp << 8; + } + if (type == 'p') + { + if (buflen & 1) + sum += (seq & 0xff); + else + sum += (seq & 0xff) << 8; + } + sum = (sum & 0xffff) + ((sum >> 16) & 0xffff); + sum += (sum >> 16) & 1; + sum = ~sum; + + hdr[0] = (sum >> 8) & 0xff; + hdr[1] = sum & 0xff; + debug_write (hdr, 2); + } +} + + +/* Respond to an expected read request from the monitor by sending + data in chunks. Handle all acknowledgements and handshaking packets. + + The monitor expects a response consisting of a one or more 'p' packets, + each followed by a portion of the data requested. The 'p' packet + contains only a four-byte integer, the value of which is the number + of bytes of data we are about to send. Following the 'p' packet, + the monitor expects the data bytes themselves in raw, unpacketized, + form, without even a checksum. + */ + +static void +process_read_request (unsigned char *buf, int buflen) +{ + unsigned char len[4]; + int i, chunk; + unsigned char seq; + + /* Discard the read request. FIXME: we have to hope it's for + the exact number of bytes we want to send; should check for this. */ + ignore_packet (); + + for (i = chunk = 0, seq = 0; i < buflen; i += chunk, seq++) + { + /* Don't send more than MAXPSIZE bytes at a time. */ + chunk = buflen - i; + if (chunk > MAXPSIZE) + chunk = MAXPSIZE; + + /* Write a packet containing the number of bytes we are sending. */ + write_long_le (len, chunk); + send_packet ('p', len, sizeof (len), seq); + + /* Write the data in raw form following the packet. */ + debug_write (&buf[i], chunk); + + /* Discard the ACK packet. */ + ignore_packet (); + } + + /* Send an "end of data" packet. */ + send_packet ('e', "", 0, 0); +} + + +/* Count loadable sections (helper function for r3900_load). */ + +static void +count_section (bfd *abfd, asection *s, unsigned int *section_count) +{ + if (s->flags & SEC_LOAD && bfd_section_size (abfd, s) != 0) + (*section_count)++; +} + + +/* Load a single BFD section (helper function for r3900_load). + + WARNING: this code is filled with assumptions about how + the Densan monitor loads programs. The monitor issues + packets containing read requests, but rather than respond + to them in an general way, we expect them to following + a certain pattern. + + For example, we know that the monitor will start loading by + issuing an 8-byte read request for the binary file header. + We know this is coming and ignore the actual contents + of the read request packet. + */ + +static void +load_section (bfd *abfd, asection *s, unsigned int *data_count) +{ + if (s->flags & SEC_LOAD) + { + bfd_size_type section_size = bfd_section_size (abfd, s); + bfd_vma section_base = bfd_section_lma (abfd, s); + unsigned char *buffer; + unsigned char header[8]; + + /* Don't output zero-length sections. */ + if (section_size == 0) + return; + if (data_count) + *data_count += section_size; + + /* Print some fluff about the section being loaded. */ + printf_filtered ("Loading section %s, size 0x%lx lma ", + bfd_section_name (abfd, s), (long) section_size); + print_address_numeric (section_base, 1, gdb_stdout); + printf_filtered ("\n"); + gdb_flush (gdb_stdout); + + /* Write the section header (location and size). */ + write_long (&header[0], (long) section_base); + write_long (&header[4], (long) section_size); + process_read_request (header, sizeof (header)); + + /* Read the section contents into a buffer, write it out, + then free the buffer. */ + buffer = (unsigned char *) xmalloc (section_size); + bfd_get_section_contents (abfd, s, buffer, 0, section_size); + process_read_request (buffer, section_size); + xfree (buffer); + } +} + + +/* When the ethernet is used as the console port on the Densan board, + we can use the "Rm" command to do a fast binary load. The format + of the download data is: + + number of sections (4 bytes) + starting address (4 bytes) + repeat for each section: + location address (4 bytes) + section size (4 bytes) + binary data + + The 4-byte fields are all in big-endian order. + + Using this command is tricky because we have to put the monitor + into a special funky "communications interface" mode, in which + it sends and receives packets of data along with the normal prompt. + */ + +static void +r3900_load (char *filename, int from_tty) +{ + bfd *abfd; + unsigned int data_count = 0; + time_t start_time, end_time; /* for timing of download */ + int section_count = 0; + unsigned char buffer[8]; + + /* If we are not using the ethernet, use the normal monitor load, + which sends S-records over the serial link. */ + if (!ethernet) + { + orig_monitor_load (filename, from_tty); + return; + } + + /* Open the file. */ + if (filename == NULL || filename[0] == 0) + filename = get_exec_file (1); + abfd = bfd_openr (filename, 0); + if (!abfd) + error ("Unable to open file %s\n", filename); + if (bfd_check_format (abfd, bfd_object) == 0) + error ("File is not an object file\n"); + + /* Output the "vconsi" command to get the monitor in the communication + state where it will accept a load command. This will cause + the monitor to emit a packet before each prompt, so ignore the packet. */ + monitor_printf ("vconsi\r"); + ignore_packet (); + monitor_expect_prompt (NULL, 0); + + /* Output the "Rm" (load) command and respond to the subsequent "open" + packet by sending an ACK packet. */ + monitor_printf ("Rm\r"); + ignore_packet (); + send_packet ('a', "", 0, 0); + + /* Output the fast load header (number of sections and starting address). */ + bfd_map_over_sections ((bfd *) abfd, (section_map_func) count_section, + §ion_count); + write_long (&buffer[0], (long) section_count); + if (exec_bfd) + write_long (&buffer[4], (long) bfd_get_start_address (exec_bfd)); + else + write_long (&buffer[4], 0); + process_read_request (buffer, sizeof (buffer)); + + /* Output the section data. */ + start_time = time (NULL); + bfd_map_over_sections (abfd, (section_map_func) load_section, &data_count); + end_time = time (NULL); + + /* Acknowledge the close packet and put the monitor back into + "normal" mode so it won't send packets any more. */ + ignore_packet (); + send_packet ('a', "", 0, 0); + monitor_expect_prompt (NULL, 0); + monitor_printf ("vconsx\r"); + monitor_expect_prompt (NULL, 0); + + /* Print start address and download performance information. */ + printf_filtered ("Start address 0x%lx\n", (long) bfd_get_start_address (abfd)); + report_transfer_performance (data_count, start_time, end_time); + + /* Finally, make the PC point at the start address */ + if (exec_bfd) + write_pc (bfd_get_start_address (exec_bfd)); + + inferior_ptid = null_ptid; /* No process now */ + + /* This is necessary because many things were based on the PC at the + time that we attached to the monitor, which is no longer valid + now that we have loaded new code (and just changed the PC). + Another way to do this might be to call normal_stop, except that + the stack may not be valid, and things would get horribly + confused... */ + clear_symtab_users (); +} + + +/* Commands to send to the monitor when first connecting: + * The bare carriage return forces a prompt from the monitor + (monitor doesn't prompt immediately after a reset). + * The "vconsx" switches the monitor back to interactive mode + in case an aborted download had left it in packet mode. + * The "Xtr" command causes subsequent "t" (trace) commands to display + the general registers only. + * The "Xxr" command does the same thing for the "x" (examine + registers) command. + * The "bx" command clears all breakpoints. + */ + +static char *r3900_inits[] = +{"\r", "vconsx\r", "Xtr\r", "Xxr\r", "bx\r", NULL}; +static char *dummy_inits[] = +{NULL}; + +static struct target_ops r3900_ops; +static struct monitor_ops r3900_cmds; + +static void +r3900_open (char *args, int from_tty) +{ + char buf[64]; + int i; + + monitor_open (args, &r3900_cmds, from_tty); + + /* We have to handle sending the init strings ourselves, because + the first two strings we send (carriage returns) may not be echoed + by the monitor, but the rest will be. */ + monitor_printf_noecho ("\r\r"); + for (i = 0; r3900_inits[i] != NULL; i++) + { + monitor_printf (r3900_inits[i]); + monitor_expect_prompt (NULL, 0); + } + + /* Attempt to determine whether the console device is ethernet or serial. + This will tell us which kind of load to use (S-records over a serial + link, or the Densan fast binary multi-section format over the net). */ + + ethernet = 0; + monitor_printf ("v\r"); + if (monitor_expect ("console device :", NULL, 0) != -1) + if (monitor_expect ("\n", buf, sizeof (buf)) != -1) + if (strstr (buf, "ethernet") != NULL) + ethernet = 1; + monitor_expect_prompt (NULL, 0); +} + +void +_initialize_r3900_rom (void) +{ + r3900_cmds.flags = MO_NO_ECHO_ON_OPEN | + MO_ADDR_BITS_REMOVE | + MO_CLR_BREAK_USES_ADDR | + MO_GETMEM_READ_SINGLE | + MO_PRINT_PROGRAM_OUTPUT; + + r3900_cmds.init = dummy_inits; + r3900_cmds.cont = "g\r"; + r3900_cmds.step = "t\r"; + r3900_cmds.set_break = "b %A\r"; /* COREADDR */ + r3900_cmds.clr_break = "b %A,0\r"; /* COREADDR */ + r3900_cmds.fill = "fx %A s %x %x\r"; /* COREADDR, len, val */ + + r3900_cmds.setmem.cmdb = "sx %A %x\r"; /* COREADDR, val */ + r3900_cmds.setmem.cmdw = "sh %A %x\r"; /* COREADDR, val */ + r3900_cmds.setmem.cmdl = "sw %A %x\r"; /* COREADDR, val */ + + r3900_cmds.getmem.cmdb = "sx %A\r"; /* COREADDR */ + r3900_cmds.getmem.cmdw = "sh %A\r"; /* COREADDR */ + r3900_cmds.getmem.cmdl = "sw %A\r"; /* COREADDR */ + r3900_cmds.getmem.resp_delim = " : "; + r3900_cmds.getmem.term = " "; + r3900_cmds.getmem.term_cmd = ".\r"; + + r3900_cmds.setreg.cmd = "x%s %x\r"; /* regname, val */ + + r3900_cmds.getreg.cmd = "x%s\r"; /* regname */ + r3900_cmds.getreg.resp_delim = "="; + r3900_cmds.getreg.term = " "; + r3900_cmds.getreg.term_cmd = ".\r"; + + r3900_cmds.dump_registers = "x\r"; + r3900_cmds.register_pattern = + "\\([a-zA-Z0-9_]+\\) *=\\([0-9a-f]+ [0-9a-f]+\\b\\)"; + r3900_cmds.supply_register = r3900_supply_register; + /* S-record download, via "keyboard port". */ + r3900_cmds.load = "r0\r"; + r3900_cmds.prompt = "#"; + r3900_cmds.line_term = "\r"; + r3900_cmds.target = &r3900_ops; + r3900_cmds.stopbits = SERIAL_1_STOPBITS; + r3900_cmds.regnames = r3900_regnames; + r3900_cmds.magic = MONITOR_OPS_MAGIC; + + init_monitor_ops (&r3900_ops); + + r3900_ops.to_shortname = "r3900"; + r3900_ops.to_longname = "R3900 monitor"; + r3900_ops.to_doc = "Debug using the DVE R3900 monitor.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + r3900_ops.to_open = r3900_open; + + /* Override the functions to fetch and store registers. But save the + addresses of the default functions, because we will use those functions + for "normal" registers. */ + + orig_monitor_fetch_registers = r3900_ops.to_fetch_registers; + orig_monitor_store_registers = r3900_ops.to_store_registers; + r3900_ops.to_fetch_registers = r3900_fetch_registers; + r3900_ops.to_store_registers = r3900_store_registers; + + /* Override the load function, but save the address of the default + function to use when loading S-records over a serial link. */ + orig_monitor_load = r3900_ops.to_load; + r3900_ops.to_load = r3900_load; + + add_target (&r3900_ops); +} diff --git a/contrib/gdb/gdb/dwarf2-frame.c b/contrib/gdb/gdb/dwarf2-frame.c new file mode 100644 index 00000000000..51a631dcac9 --- /dev/null +++ b/contrib/gdb/gdb/dwarf2-frame.c @@ -0,0 +1,1621 @@ +/* Frame unwinder for frames with DWARF Call Frame Information. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + Contributed by Mark Kettenis. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "dwarf2expr.h" +#include "elf/dwarf2.h" +#include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "gdbtypes.h" +#include "symtab.h" +#include "objfiles.h" +#include "regcache.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "complaints.h" +#include "dwarf2-frame.h" + +/* Call Frame Information (CFI). */ + +/* Common Information Entry (CIE). */ + +struct dwarf2_cie +{ + /* Offset into the .debug_frame section where this CIE was found. + Used to identify this CIE. */ + ULONGEST cie_pointer; + + /* Constant that is factored out of all advance location + instructions. */ + ULONGEST code_alignment_factor; + + /* Constants that is factored out of all offset instructions. */ + LONGEST data_alignment_factor; + + /* Return address column. */ + ULONGEST return_address_register; + + /* Instruction sequence to initialize a register set. */ + unsigned char *initial_instructions; + unsigned char *end; + + /* Encoding of addresses. */ + unsigned char encoding; + + /* True if a 'z' augmentation existed. */ + unsigned char saw_z_augmentation; + + struct dwarf2_cie *next; +}; + +/* Frame Description Entry (FDE). */ + +struct dwarf2_fde +{ + /* CIE for this FDE. */ + struct dwarf2_cie *cie; + + /* First location associated with this FDE. */ + CORE_ADDR initial_location; + + /* Number of bytes of program instructions described by this FDE. */ + CORE_ADDR address_range; + + /* Instruction sequence. */ + unsigned char *instructions; + unsigned char *end; + + struct dwarf2_fde *next; +}; + +static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc); + + +/* Structure describing a frame state. */ + +struct dwarf2_frame_state +{ + /* Each register save state can be described in terms of a CFA slot, + another register, or a location expression. */ + struct dwarf2_frame_state_reg_info + { + struct dwarf2_frame_state_reg *reg; + int num_regs; + + /* Used to implement DW_CFA_remember_state. */ + struct dwarf2_frame_state_reg_info *prev; + } regs; + + LONGEST cfa_offset; + ULONGEST cfa_reg; + unsigned char *cfa_exp; + enum { + CFA_UNSET, + CFA_REG_OFFSET, + CFA_EXP + } cfa_how; + + /* The PC described by the current frame state. */ + CORE_ADDR pc; + + /* Initial register set from the CIE. + Used to implement DW_CFA_restore. */ + struct dwarf2_frame_state_reg_info initial; + + /* The information we care about from the CIE. */ + LONGEST data_align; + ULONGEST code_align; + ULONGEST retaddr_column; +}; + +/* Store the length the expression for the CFA in the `cfa_reg' field, + which is unused in that case. */ +#define cfa_exp_len cfa_reg + +/* Assert that the register set RS is large enough to store NUM_REGS + columns. If necessary, enlarge the register set. */ + +static void +dwarf2_frame_state_alloc_regs (struct dwarf2_frame_state_reg_info *rs, + int num_regs) +{ + size_t size = sizeof (struct dwarf2_frame_state_reg); + + if (num_regs <= rs->num_regs) + return; + + rs->reg = (struct dwarf2_frame_state_reg *) + xrealloc (rs->reg, num_regs * size); + + /* Initialize newly allocated registers. */ + memset (rs->reg + rs->num_regs, 0, (num_regs - rs->num_regs) * size); + rs->num_regs = num_regs; +} + +/* Copy the register columns in register set RS into newly allocated + memory and return a pointer to this newly created copy. */ + +static struct dwarf2_frame_state_reg * +dwarf2_frame_state_copy_regs (struct dwarf2_frame_state_reg_info *rs) +{ + size_t size = rs->num_regs * sizeof (struct dwarf2_frame_state_reg_info); + struct dwarf2_frame_state_reg *reg; + + reg = (struct dwarf2_frame_state_reg *) xmalloc (size); + memcpy (reg, rs->reg, size); + + return reg; +} + +/* Release the memory allocated to register set RS. */ + +static void +dwarf2_frame_state_free_regs (struct dwarf2_frame_state_reg_info *rs) +{ + if (rs) + { + dwarf2_frame_state_free_regs (rs->prev); + + xfree (rs->reg); + xfree (rs); + } +} + +/* Release the memory allocated to the frame state FS. */ + +static void +dwarf2_frame_state_free (void *p) +{ + struct dwarf2_frame_state *fs = p; + + dwarf2_frame_state_free_regs (fs->initial.prev); + dwarf2_frame_state_free_regs (fs->regs.prev); + xfree (fs->initial.reg); + xfree (fs->regs.reg); + xfree (fs); +} + + +/* Helper functions for execute_stack_op. */ + +static CORE_ADDR +read_reg (void *baton, int reg) +{ + struct frame_info *next_frame = (struct frame_info *) baton; + struct gdbarch *gdbarch = get_frame_arch (next_frame); + int regnum; + char *buf; + + regnum = DWARF2_REG_TO_REGNUM (reg); + + buf = (char *) alloca (register_size (gdbarch, regnum)); + frame_unwind_register (next_frame, regnum, buf); + return extract_typed_address (buf, builtin_type_void_data_ptr); +} + +static void +read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) +{ + read_memory (addr, buf, len); +} + +static void +no_get_frame_base (void *baton, unsigned char **start, size_t *length) +{ + internal_error (__FILE__, __LINE__, + "Support for DW_OP_fbreg is unimplemented"); +} + +static CORE_ADDR +no_get_tls_address (void *baton, CORE_ADDR offset) +{ + internal_error (__FILE__, __LINE__, + "Support for DW_OP_GNU_push_tls_address is unimplemented"); +} + +static CORE_ADDR +execute_stack_op (unsigned char *exp, ULONGEST len, + struct frame_info *next_frame, CORE_ADDR initial) +{ + struct dwarf_expr_context *ctx; + CORE_ADDR result; + + ctx = new_dwarf_expr_context (); + ctx->baton = next_frame; + ctx->read_reg = read_reg; + ctx->read_mem = read_mem; + ctx->get_frame_base = no_get_frame_base; + ctx->get_tls_address = no_get_tls_address; + + dwarf_expr_push (ctx, initial); + dwarf_expr_eval (ctx, exp, len); + result = dwarf_expr_fetch (ctx, 0); + + if (ctx->in_reg) + result = read_reg (next_frame, result); + + free_dwarf_expr_context (ctx); + + return result; +} + + +static void +execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end, + struct frame_info *next_frame, + struct dwarf2_frame_state *fs) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + int bytes_read; + + while (insn_ptr < insn_end && fs->pc <= pc) + { + unsigned char insn = *insn_ptr++; + ULONGEST utmp, reg; + LONGEST offset; + + if ((insn & 0xc0) == DW_CFA_advance_loc) + fs->pc += (insn & 0x3f) * fs->code_align; + else if ((insn & 0xc0) == DW_CFA_offset) + { + reg = insn & 0x3f; + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + offset = utmp * fs->data_align; + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + } + else if ((insn & 0xc0) == DW_CFA_restore) + { + gdb_assert (fs->initial.reg); + reg = insn & 0x3f; + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg] = fs->initial.reg[reg]; + } + else + { + switch (insn) + { + case DW_CFA_set_loc: + fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read); + insn_ptr += bytes_read; + break; + + case DW_CFA_advance_loc1: + utmp = extract_unsigned_integer (insn_ptr, 1); + fs->pc += utmp * fs->code_align; + insn_ptr++; + break; + case DW_CFA_advance_loc2: + utmp = extract_unsigned_integer (insn_ptr, 2); + fs->pc += utmp * fs->code_align; + insn_ptr += 2; + break; + case DW_CFA_advance_loc4: + utmp = extract_unsigned_integer (insn_ptr, 4); + fs->pc += utmp * fs->code_align; + insn_ptr += 4; + break; + + case DW_CFA_offset_extended: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + offset = utmp * fs->data_align; + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + break; + + case DW_CFA_restore_extended: + gdb_assert (fs->initial.reg); + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg] = fs->initial.reg[reg]; + break; + + case DW_CFA_undefined: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNDEFINED; + break; + + case DW_CFA_same_value: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAME_VALUE; + break; + + case DW_CFA_register: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG; + fs->regs.reg[reg].loc.reg = utmp; + break; + + case DW_CFA_remember_state: + { + struct dwarf2_frame_state_reg_info *new_rs; + + new_rs = XMALLOC (struct dwarf2_frame_state_reg_info); + *new_rs = fs->regs; + fs->regs.reg = dwarf2_frame_state_copy_regs (&fs->regs); + fs->regs.prev = new_rs; + } + break; + + case DW_CFA_restore_state: + { + struct dwarf2_frame_state_reg_info *old_rs = fs->regs.prev; + + gdb_assert (old_rs); + + xfree (fs->regs.reg); + fs->regs = *old_rs; + xfree (old_rs); + } + break; + + case DW_CFA_def_cfa: + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + fs->cfa_offset = utmp; + fs->cfa_how = CFA_REG_OFFSET; + break; + + case DW_CFA_def_cfa_register: + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); + fs->cfa_how = CFA_REG_OFFSET; + break; + + case DW_CFA_def_cfa_offset: + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_offset); + /* cfa_how deliberately not set. */ + break; + + case DW_CFA_nop: + break; + + case DW_CFA_def_cfa_expression: + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_exp_len); + fs->cfa_exp = insn_ptr; + fs->cfa_how = CFA_EXP; + insn_ptr += fs->cfa_exp_len; + break; + + case DW_CFA_expression: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + fs->regs.reg[reg].loc.exp = insn_ptr; + fs->regs.reg[reg].exp_len = utmp; + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_EXP; + insn_ptr += utmp; + break; + + case DW_CFA_offset_extended_sf: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); + offset += fs->data_align; + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + break; + + case DW_CFA_def_cfa_sf: + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); + insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); + fs->cfa_offset = offset * fs->data_align; + fs->cfa_how = CFA_REG_OFFSET; + break; + + case DW_CFA_def_cfa_offset_sf: + insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); + fs->cfa_offset = offset * fs->data_align; + /* cfa_how deliberately not set. */ + break; + + case DW_CFA_GNU_args_size: + /* Ignored. */ + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + break; + + default: + internal_error (__FILE__, __LINE__, "Unknown CFI encountered."); + } + } + } + + /* Don't allow remember/restore between CIE and FDE programs. */ + dwarf2_frame_state_free_regs (fs->regs.prev); + fs->regs.prev = NULL; +} + + +/* Architecture-specific operations. */ + +/* Per-architecture data key. */ +static struct gdbarch_data *dwarf2_frame_data; + +struct dwarf2_frame_ops +{ + /* Pre-initialize the register state REG for register REGNUM. */ + void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *); +}; + +/* Default architecture-specific register state initialization + function. */ + +static void +dwarf2_frame_default_init_reg (struct gdbarch *gdbarch, int regnum, + struct dwarf2_frame_state_reg *reg) +{ + /* If we have a register that acts as a program counter, mark it as + a destination for the return address. If we have a register that + serves as the stack pointer, arrange for it to be filled with the + call frame address (CFA). The other registers are marked as + unspecified. + + We copy the return address to the program counter, since many + parts in GDB assume that it is possible to get the return address + by unwinding the program counter register. However, on ISA's + with a dedicated return address register, the CFI usually only + contains information to unwind that return address register. + + The reason we're treating the stack pointer special here is + because in many cases GCC doesn't emit CFI for the stack pointer + and implicitly assumes that it is equal to the CFA. This makes + some sense since the DWARF specification (version 3, draft 8, + p. 102) says that: + + "Typically, the CFA is defined to be the value of the stack + pointer at the call site in the previous frame (which may be + different from its value on entry to the current frame)." + + However, this isn't true for all platforms supported by GCC + (e.g. IBM S/390 and zSeries). Those architectures should provide + their own architecture-specific initialization function. */ + + if (regnum == PC_REGNUM) + reg->how = DWARF2_FRAME_REG_RA; + else if (regnum == SP_REGNUM) + reg->how = DWARF2_FRAME_REG_CFA; +} + +/* Return a default for the architecture-specific operations. */ + +static void * +dwarf2_frame_init (struct gdbarch *gdbarch) +{ + struct dwarf2_frame_ops *ops; + + ops = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf2_frame_ops); + ops->init_reg = dwarf2_frame_default_init_reg; + return ops; +} + +static struct dwarf2_frame_ops * +dwarf2_frame_ops (struct gdbarch *gdbarch) +{ + struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data); + if (ops == NULL) + { + /* ULGH, called during architecture initialization. Patch + things up. */ + ops = dwarf2_frame_init (gdbarch); + set_gdbarch_data (gdbarch, dwarf2_frame_data, ops); + } + return ops; +} + +/* Set the architecture-specific register state initialization + function for GDBARCH to INIT_REG. */ + +void +dwarf2_frame_set_init_reg (struct gdbarch *gdbarch, + void (*init_reg) (struct gdbarch *, int, + struct dwarf2_frame_state_reg *)) +{ + struct dwarf2_frame_ops *ops; + + ops = dwarf2_frame_ops (gdbarch); + ops->init_reg = init_reg; +} + +/* Pre-initialize the register state REG for register REGNUM. */ + +static void +dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, + struct dwarf2_frame_state_reg *reg) +{ + struct dwarf2_frame_ops *ops; + + ops = dwarf2_frame_ops (gdbarch); + ops->init_reg (gdbarch, regnum, reg); +} + + +struct dwarf2_frame_cache +{ + /* DWARF Call Frame Address. */ + CORE_ADDR cfa; + + /* Saved registers, indexed by GDB register number, not by DWARF + register number. */ + struct dwarf2_frame_state_reg *reg; +}; + +static struct dwarf2_frame_cache * +dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct cleanup *old_chain; + struct gdbarch *gdbarch = get_frame_arch (next_frame); + const int num_regs = NUM_REGS + NUM_PSEUDO_REGS; + struct dwarf2_frame_cache *cache; + struct dwarf2_frame_state *fs; + struct dwarf2_fde *fde; + + if (*this_cache) + return *this_cache; + + /* Allocate a new cache. */ + cache = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_cache); + cache->reg = FRAME_OBSTACK_CALLOC (num_regs, struct dwarf2_frame_state_reg); + + /* Allocate and initialize the frame state. */ + fs = XMALLOC (struct dwarf2_frame_state); + memset (fs, 0, sizeof (struct dwarf2_frame_state)); + old_chain = make_cleanup (dwarf2_frame_state_free, fs); + + /* Unwind the PC. + + Note that if NEXT_FRAME is never supposed to return (i.e. a call + to abort), the compiler might optimize away the instruction at + NEXT_FRAME's return address. As a result the return address will + point at some random instruction, and the CFI for that + instruction is probably worthless to us. GCC's unwinder solves + this problem by substracting 1 from the return address to get an + address in the middle of a presumed call instruction (or the + instruction in the associated delay slot). This should only be + done for "normal" frames and not for resume-type frames (signal + handlers, sentinel frames, dummy frames). The function + frame_unwind_address_in_block does just this. It's not clear how + reliable the method is though; there is the potential for the + register state pre-call being different to that on return. */ + fs->pc = frame_unwind_address_in_block (next_frame); + + /* Find the correct FDE. */ + fde = dwarf2_frame_find_fde (&fs->pc); + gdb_assert (fde != NULL); + + /* Extract any interesting information from the CIE. */ + fs->data_align = fde->cie->data_alignment_factor; + fs->code_align = fde->cie->code_alignment_factor; + fs->retaddr_column = fde->cie->return_address_register; + + /* First decode all the insns in the CIE. */ + execute_cfa_program (fde->cie->initial_instructions, + fde->cie->end, next_frame, fs); + + /* Save the initialized register set. */ + fs->initial = fs->regs; + fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs); + + /* Then decode the insns in the FDE up to our target PC. */ + execute_cfa_program (fde->instructions, fde->end, next_frame, fs); + + /* Caclulate the CFA. */ + switch (fs->cfa_how) + { + case CFA_REG_OFFSET: + cache->cfa = read_reg (next_frame, fs->cfa_reg); + cache->cfa += fs->cfa_offset; + break; + + case CFA_EXP: + cache->cfa = + execute_stack_op (fs->cfa_exp, fs->cfa_exp_len, next_frame, 0); + break; + + default: + internal_error (__FILE__, __LINE__, "Unknown CFA rule."); + } + + /* Initialize the register state. */ + { + int regnum; + + for (regnum = 0; regnum < num_regs; regnum++) + dwarf2_frame_init_reg (gdbarch, regnum, &cache->reg[regnum]); + } + + /* Go through the DWARF2 CFI generated table and save its register + location information in the cache. Note that we don't skip the + return address column; it's perfectly all right for it to + correspond to a real register. If it doesn't correspond to a + real register, or if we shouldn't treat it as such, + DWARF2_REG_TO_REGNUM should be defined to return a number outside + the range [0, NUM_REGS). */ + { + int column; /* CFI speak for "register number". */ + + for (column = 0; column < fs->regs.num_regs; column++) + { + /* Use the GDB register number as the destination index. */ + int regnum = DWARF2_REG_TO_REGNUM (column); + + /* If there's no corresponding GDB register, ignore it. */ + if (regnum < 0 || regnum >= num_regs) + continue; + + /* NOTE: cagney/2003-09-05: CFI should specify the disposition + of all debug info registers. If it doesn't, complain (but + not too loudly). It turns out that GCC assumes that an + unspecified register implies "same value" when CFI (draft + 7) specifies nothing at all. Such a register could equally + be interpreted as "undefined". Also note that this check + isn't sufficient; it only checks that all registers in the + range [0 .. max column] are specified, and won't detect + problems when a debug info register falls outside of the + table. We need a way of iterating through all the valid + DWARF2 register numbers. */ + if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED) + complaint (&symfile_complaints, + "Incomplete CFI data; unspecified registers at 0x%s", + paddr (fs->pc)); + else + cache->reg[regnum] = fs->regs.reg[column]; + } + } + + /* Eliminate any DWARF2_FRAME_REG_RA rules. */ + { + int regnum; + + for (regnum = 0; regnum < num_regs; regnum++) + { + if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA) + { + struct dwarf2_frame_state_reg *retaddr_reg = + &fs->regs.reg[fs->retaddr_column]; + + /* It seems rather bizarre to specify an "empty" column as + the return adress column. However, this is exactly + what GCC does on some targets. It turns out that GCC + assumes that the return address can be found in the + register corresponding to the return address column. + Incidentally, that's how should treat a return address + column specifying "same value" too. */ + if (fs->retaddr_column < fs->regs.num_regs + && retaddr_reg->how != DWARF2_FRAME_REG_UNSPECIFIED + && retaddr_reg->how != DWARF2_FRAME_REG_SAME_VALUE) + cache->reg[regnum] = *retaddr_reg; + else + { + cache->reg[regnum].loc.reg = fs->retaddr_column; + cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG; + } + } + } + } + + do_cleanups (old_chain); + + *this_cache = cache; + return cache; +} + +static void +dwarf2_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct dwarf2_frame_cache *cache = + dwarf2_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->cfa, frame_func_unwind (next_frame)); +} + +static void +dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct dwarf2_frame_cache *cache = + dwarf2_frame_cache (next_frame, this_cache); + + switch (cache->reg[regnum].how) + { + case DWARF2_FRAME_REG_UNDEFINED: + /* If CFI explicitly specified that the value isn't defined, + mark it as optimized away; the value isn't available. */ + *optimizedp = 1; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + /* In some cases, for example %eflags on the i386, we have + to provide a sane value, even though this register wasn't + saved. Assume we can get it from NEXT_FRAME. */ + frame_unwind_register (next_frame, regnum, valuep); + } + break; + + case DWARF2_FRAME_REG_SAVED_OFFSET: + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = cache->cfa + cache->reg[regnum].loc.offset; + *realnump = -1; + if (valuep) + { + /* Read the value in from memory. */ + read_memory (*addrp, valuep, register_size (gdbarch, regnum)); + } + break; + + case DWARF2_FRAME_REG_SAVED_REG: + regnum = DWARF2_REG_TO_REGNUM (cache->reg[regnum].loc.reg); + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); + break; + + case DWARF2_FRAME_REG_SAVED_EXP: + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = execute_stack_op (cache->reg[regnum].loc.exp, + cache->reg[regnum].exp_len, + next_frame, cache->cfa); + *realnump = -1; + if (valuep) + { + /* Read the value in from memory. */ + read_memory (*addrp, valuep, register_size (gdbarch, regnum)); + } + break; + + case DWARF2_FRAME_REG_UNSPECIFIED: + /* GCC, in its infinite wisdom decided to not provide unwind + information for registers that are "same value". Since + DWARF2 (3 draft 7) doesn't define such behavior, said + registers are actually undefined (which is different to CFI + "undefined"). Code above issues a complaint about this. + Here just fudge the books, assume GCC, and that the value is + more inner on the stack. */ + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); + break; + + case DWARF2_FRAME_REG_SAME_VALUE: + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); + break; + + case DWARF2_FRAME_REG_CFA: + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + /* Store the value. */ + store_typed_address (valuep, builtin_type_void_data_ptr, cache->cfa); + } + break; + + default: + internal_error (__FILE__, __LINE__, "Unknown register rule."); + } +} + +static const struct frame_unwind dwarf2_frame_unwind = +{ + NORMAL_FRAME, + dwarf2_frame_this_id, + dwarf2_frame_prev_register +}; + +const struct frame_unwind * +dwarf2_frame_sniffer (struct frame_info *next_frame) +{ + /* Grab an address that is guarenteed to reside somewhere within the + function. frame_pc_unwind(), for a no-return next function, can + end up returning something past the end of this function's body. */ + CORE_ADDR block_addr = frame_unwind_address_in_block (next_frame); + if (dwarf2_frame_find_fde (&block_addr)) + return &dwarf2_frame_unwind; + + return NULL; +} + + +/* There is no explicitly defined relationship between the CFA and the + location of frame's local variables and arguments/parameters. + Therefore, frame base methods on this page should probably only be + used as a last resort, just to avoid printing total garbage as a + response to the "info frame" command. */ + +static CORE_ADDR +dwarf2_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct dwarf2_frame_cache *cache = + dwarf2_frame_cache (next_frame, this_cache); + + return cache->cfa; +} + +static const struct frame_base dwarf2_frame_base = +{ + &dwarf2_frame_unwind, + dwarf2_frame_base_address, + dwarf2_frame_base_address, + dwarf2_frame_base_address +}; + +const struct frame_base * +dwarf2_frame_base_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + if (dwarf2_frame_find_fde (&pc)) + return &dwarf2_frame_base; + + return NULL; +} + +/* A minimal decoding of DWARF2 compilation units. We only decode + what's needed to get to the call frame information. */ + +struct comp_unit +{ + /* Keep the bfd convenient. */ + bfd *abfd; + + struct objfile *objfile; + + /* Linked list of CIEs for this object. */ + struct dwarf2_cie *cie; + + /* Address size for this unit - from unit header. */ + unsigned char addr_size; + + /* Pointer to the .debug_frame section loaded into memory. */ + char *dwarf_frame_buffer; + + /* Length of the loaded .debug_frame section. */ + unsigned long dwarf_frame_size; + + /* Pointer to the .debug_frame section. */ + asection *dwarf_frame_section; + + /* Base for DW_EH_PE_datarel encodings. */ + bfd_vma dbase; + + /* Base for DW_EH_PE_textrel encodings. */ + bfd_vma tbase; +}; + +const struct objfile_data *dwarf2_frame_objfile_data; + +static unsigned int +read_1_byte (bfd *bfd, char *buf) +{ + return bfd_get_8 (abfd, (bfd_byte *) buf); +} + +static unsigned int +read_4_bytes (bfd *abfd, char *buf) +{ + return bfd_get_32 (abfd, (bfd_byte *) buf); +} + +static ULONGEST +read_8_bytes (bfd *abfd, char *buf) +{ + return bfd_get_64 (abfd, (bfd_byte *) buf); +} + +static ULONGEST +read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) +{ + ULONGEST result; + unsigned int num_read; + int shift; + unsigned char byte; + + result = 0; + shift = 0; + num_read = 0; + + do + { + byte = bfd_get_8 (abfd, (bfd_byte *) buf); + buf++; + num_read++; + result |= ((byte & 0x7f) << shift); + shift += 7; + } + while (byte & 0x80); + + *bytes_read_ptr = num_read; + + return result; +} + +static LONGEST +read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) +{ + LONGEST result; + int shift; + unsigned int num_read; + unsigned char byte; + + result = 0; + shift = 0; + num_read = 0; + + do + { + byte = bfd_get_8 (abfd, (bfd_byte *) buf); + buf++; + num_read++; + result |= ((byte & 0x7f) << shift); + shift += 7; + } + while (byte & 0x80); + + if ((shift < 32) && (byte & 0x40)) + result |= -(1 << shift); + + *bytes_read_ptr = num_read; + + return result; +} + +static ULONGEST +read_initial_length (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) +{ + LONGEST result; + + result = bfd_get_32 (abfd, (bfd_byte *) buf); + if (result == 0xffffffff) + { + result = bfd_get_64 (abfd, (bfd_byte *) buf + 4); + *bytes_read_ptr = 12; + } + else + *bytes_read_ptr = 4; + + return result; +} + + +/* Pointer encoding helper functions. */ + +/* GCC supports exception handling based on DWARF2 CFI. However, for + technical reasons, it encodes addresses in its FDE's in a different + way. Several "pointer encodings" are supported. The encoding + that's used for a particular FDE is determined by the 'R' + augmentation in the associated CIE. The argument of this + augmentation is a single byte. + + The address can be encoded as 2 bytes, 4 bytes, 8 bytes, or as a + LEB128. This is encoded in bits 0, 1 and 2. Bit 3 encodes whether + the address is signed or unsigned. Bits 4, 5 and 6 encode how the + address should be interpreted (absolute, relative to the current + position in the FDE, ...). Bit 7, indicates that the address + should be dereferenced. */ + +static unsigned char +encoding_for_size (unsigned int size) +{ + switch (size) + { + case 2: + return DW_EH_PE_udata2; + case 4: + return DW_EH_PE_udata4; + case 8: + return DW_EH_PE_udata8; + default: + internal_error (__FILE__, __LINE__, "Unsupported address size"); + } +} + +static unsigned int +size_of_encoded_value (unsigned char encoding) +{ + if (encoding == DW_EH_PE_omit) + return 0; + + switch (encoding & 0x07) + { + case DW_EH_PE_absptr: + return TYPE_LENGTH (builtin_type_void_data_ptr); + case DW_EH_PE_udata2: + return 2; + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + default: + internal_error (__FILE__, __LINE__, "Invalid or unsupported encoding"); + } +} + +static CORE_ADDR +read_encoded_value (struct comp_unit *unit, unsigned char encoding, + char *buf, unsigned int *bytes_read_ptr) +{ + int ptr_len = size_of_encoded_value (DW_EH_PE_absptr); + ptrdiff_t offset; + CORE_ADDR base; + + /* GCC currently doesn't generate DW_EH_PE_indirect encodings for + FDE's. */ + if (encoding & DW_EH_PE_indirect) + internal_error (__FILE__, __LINE__, + "Unsupported encoding: DW_EH_PE_indirect"); + + *bytes_read_ptr = 0; + + switch (encoding & 0x70) + { + case DW_EH_PE_absptr: + base = 0; + break; + case DW_EH_PE_pcrel: + base = bfd_get_section_vma (unit->bfd, unit->dwarf_frame_section); + base += (buf - unit->dwarf_frame_buffer); + break; + case DW_EH_PE_datarel: + base = unit->dbase; + break; + case DW_EH_PE_textrel: + base = unit->tbase; + break; + case DW_EH_PE_funcrel: + /* FIXME: kettenis/20040501: For now just pretend + DW_EH_PE_funcrel is equivalent to DW_EH_PE_absptr. For + reading the initial location of an FDE it should be treated + as such, and currently that's the only place where this code + is used. */ + base = 0; + break; + case DW_EH_PE_aligned: + base = 0; + offset = buf - unit->dwarf_frame_buffer; + if ((offset % ptr_len) != 0) + { + *bytes_read_ptr = ptr_len - (offset % ptr_len); + buf += *bytes_read_ptr; + } + break; + default: + internal_error (__FILE__, __LINE__, "Invalid or unsupported encoding"); + } + + if ((encoding & 0x0f) == 0x00) + encoding |= encoding_for_size (ptr_len); + + switch (encoding & 0x0f) + { + case DW_EH_PE_udata2: + *bytes_read_ptr += 2; + return (base + bfd_get_16 (unit->abfd, (bfd_byte *) buf)); + case DW_EH_PE_udata4: + *bytes_read_ptr += 4; + return (base + bfd_get_32 (unit->abfd, (bfd_byte *) buf)); + case DW_EH_PE_udata8: + *bytes_read_ptr += 8; + return (base + bfd_get_64 (unit->abfd, (bfd_byte *) buf)); + case DW_EH_PE_sdata2: + *bytes_read_ptr += 2; + return (base + bfd_get_signed_16 (unit->abfd, (bfd_byte *) buf)); + case DW_EH_PE_sdata4: + *bytes_read_ptr += 4; + return (base + bfd_get_signed_32 (unit->abfd, (bfd_byte *) buf)); + case DW_EH_PE_sdata8: + *bytes_read_ptr += 8; + return (base + bfd_get_signed_64 (unit->abfd, (bfd_byte *) buf)); + default: + internal_error (__FILE__, __LINE__, "Invalid or unsupported encoding"); + } +} + + +/* GCC uses a single CIE for all FDEs in a .debug_frame section. + That's why we use a simple linked list here. */ + +static struct dwarf2_cie * +find_cie (struct comp_unit *unit, ULONGEST cie_pointer) +{ + struct dwarf2_cie *cie = unit->cie; + + while (cie) + { + if (cie->cie_pointer == cie_pointer) + return cie; + + cie = cie->next; + } + + return NULL; +} + +static void +add_cie (struct comp_unit *unit, struct dwarf2_cie *cie) +{ + cie->next = unit->cie; + unit->cie = cie; +} + +/* Find the FDE for *PC. Return a pointer to the FDE, and store the + inital location associated with it into *PC. */ + +static struct dwarf2_fde * +dwarf2_frame_find_fde (CORE_ADDR *pc) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + struct dwarf2_fde *fde; + CORE_ADDR offset; + + fde = objfile_data (objfile, dwarf2_frame_objfile_data); + if (fde == NULL) + continue; + + gdb_assert (objfile->section_offsets); + offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + while (fde) + { + if (*pc >= fde->initial_location + offset + && *pc < fde->initial_location + offset + fde->address_range) + { + *pc = fde->initial_location + offset; + return fde; + } + + fde = fde->next; + } + } + + return NULL; +} + +static void +add_fde (struct comp_unit *unit, struct dwarf2_fde *fde) +{ + fde->next = objfile_data (unit->objfile, dwarf2_frame_objfile_data); + set_objfile_data (unit->objfile, dwarf2_frame_objfile_data, fde); +} + +#ifdef CC_HAS_LONG_LONG +#define DW64_CIE_ID 0xffffffffffffffffULL +#else +#define DW64_CIE_ID ~0 +#endif + +static char *decode_frame_entry (struct comp_unit *unit, char *start, + int eh_frame_p); + +/* Decode the next CIE or FDE. Return NULL if invalid input, otherwise + the next byte to be processed. */ +static char * +decode_frame_entry_1 (struct comp_unit *unit, char *start, int eh_frame_p) +{ + char *buf; + LONGEST length; + unsigned int bytes_read; + int dwarf64_p; + ULONGEST cie_id; + ULONGEST cie_pointer; + char *end; + + buf = start; + length = read_initial_length (unit->abfd, buf, &bytes_read); + buf += bytes_read; + end = buf + length; + + /* Are we still within the section? */ + if (end > unit->dwarf_frame_buffer + unit->dwarf_frame_size) + return NULL; + + if (length == 0) + return end; + + /* Distinguish between 32 and 64-bit encoded frame info. */ + dwarf64_p = (bytes_read == 12); + + /* In a .eh_frame section, zero is used to distinguish CIEs from FDEs. */ + if (eh_frame_p) + cie_id = 0; + else if (dwarf64_p) + cie_id = DW64_CIE_ID; + else + cie_id = DW_CIE_ID; + + if (dwarf64_p) + { + cie_pointer = read_8_bytes (unit->abfd, buf); + buf += 8; + } + else + { + cie_pointer = read_4_bytes (unit->abfd, buf); + buf += 4; + } + + if (cie_pointer == cie_id) + { + /* This is a CIE. */ + struct dwarf2_cie *cie; + char *augmentation; + + /* Record the offset into the .debug_frame section of this CIE. */ + cie_pointer = start - unit->dwarf_frame_buffer; + + /* Check whether we've already read it. */ + if (find_cie (unit, cie_pointer)) + return end; + + cie = (struct dwarf2_cie *) + obstack_alloc (&unit->objfile->objfile_obstack, + sizeof (struct dwarf2_cie)); + cie->initial_instructions = NULL; + cie->cie_pointer = cie_pointer; + + /* The encoding for FDE's in a normal .debug_frame section + depends on the target address size as specified in the + Compilation Unit Header. */ + cie->encoding = encoding_for_size (unit->addr_size); + + /* Check version number. */ + if (read_1_byte (unit->abfd, buf) != DW_CIE_VERSION) + return NULL; + buf += 1; + + /* Interpret the interesting bits of the augmentation. */ + augmentation = buf; + buf = augmentation + strlen (augmentation) + 1; + + /* The GCC 2.x "eh" augmentation has a pointer immediately + following the augmentation string, so it must be handled + first. */ + if (augmentation[0] == 'e' && augmentation[1] == 'h') + { + /* Skip. */ + buf += TYPE_LENGTH (builtin_type_void_data_ptr); + augmentation += 2; + } + + cie->code_alignment_factor = + read_unsigned_leb128 (unit->abfd, buf, &bytes_read); + buf += bytes_read; + + cie->data_alignment_factor = + read_signed_leb128 (unit->abfd, buf, &bytes_read); + buf += bytes_read; + + cie->return_address_register = read_1_byte (unit->abfd, buf); + buf += 1; + + cie->saw_z_augmentation = (*augmentation == 'z'); + if (cie->saw_z_augmentation) + { + ULONGEST length; + + length = read_unsigned_leb128 (unit->abfd, buf, &bytes_read); + buf += bytes_read; + if (buf > end) + return NULL; + cie->initial_instructions = buf + length; + augmentation++; + } + + while (*augmentation) + { + /* "L" indicates a byte showing how the LSDA pointer is encoded. */ + if (*augmentation == 'L') + { + /* Skip. */ + buf++; + augmentation++; + } + + /* "R" indicates a byte indicating how FDE addresses are encoded. */ + else if (*augmentation == 'R') + { + cie->encoding = *buf++; + augmentation++; + } + + /* "P" indicates a personality routine in the CIE augmentation. */ + else if (*augmentation == 'P') + { + /* Skip. */ + buf += size_of_encoded_value (*buf++); + augmentation++; + } + + /* Otherwise we have an unknown augmentation. + Bail out unless we saw a 'z' prefix. */ + else + { + if (cie->initial_instructions == NULL) + return end; + + /* Skip unknown augmentations. */ + buf = cie->initial_instructions; + break; + } + } + + cie->initial_instructions = buf; + cie->end = end; + + add_cie (unit, cie); + } + else + { + /* This is a FDE. */ + struct dwarf2_fde *fde; + + /* In an .eh_frame section, the CIE pointer is the delta between the + address within the FDE where the CIE pointer is stored and the + address of the CIE. Convert it to an offset into the .eh_frame + section. */ + if (eh_frame_p) + { + cie_pointer = buf - unit->dwarf_frame_buffer - cie_pointer; + cie_pointer -= (dwarf64_p ? 8 : 4); + } + + /* In either case, validate the result is still within the section. */ + if (cie_pointer >= unit->dwarf_frame_size) + return NULL; + + fde = (struct dwarf2_fde *) + obstack_alloc (&unit->objfile->objfile_obstack, + sizeof (struct dwarf2_fde)); + fde->cie = find_cie (unit, cie_pointer); + if (fde->cie == NULL) + { + decode_frame_entry (unit, unit->dwarf_frame_buffer + cie_pointer, + eh_frame_p); + fde->cie = find_cie (unit, cie_pointer); + } + + gdb_assert (fde->cie != NULL); + + fde->initial_location = + read_encoded_value (unit, fde->cie->encoding, buf, &bytes_read); + buf += bytes_read; + + fde->address_range = + read_encoded_value (unit, fde->cie->encoding & 0x0f, buf, &bytes_read); + buf += bytes_read; + + /* A 'z' augmentation in the CIE implies the presence of an + augmentation field in the FDE as well. The only thing known + to be in here at present is the LSDA entry for EH. So we + can skip the whole thing. */ + if (fde->cie->saw_z_augmentation) + { + ULONGEST length; + + length = read_unsigned_leb128 (unit->abfd, buf, &bytes_read); + buf += bytes_read + length; + if (buf > end) + return NULL; + } + + fde->instructions = buf; + fde->end = end; + + add_fde (unit, fde); + } + + return end; +} + +/* Read a CIE or FDE in BUF and decode it. */ +static char * +decode_frame_entry (struct comp_unit *unit, char *start, int eh_frame_p) +{ + enum { NONE, ALIGN4, ALIGN8, FAIL } workaround = NONE; + char *ret; + const char *msg; + ptrdiff_t start_offset; + + while (1) + { + ret = decode_frame_entry_1 (unit, start, eh_frame_p); + if (ret != NULL) + break; + + /* We have corrupt input data of some form. */ + + /* ??? Try, weakly, to work around compiler/assembler/linker bugs + and mismatches wrt padding and alignment of debug sections. */ + /* Note that there is no requirement in the standard for any + alignment at all in the frame unwind sections. Testing for + alignment before trying to interpret data would be incorrect. + + However, GCC traditionally arranged for frame sections to be + sized such that the FDE length and CIE fields happen to be + aligned (in theory, for performance). This, unfortunately, + was done with .align directives, which had the side effect of + forcing the section to be aligned by the linker. + + This becomes a problem when you have some other producer that + creates frame sections that are not as strictly aligned. That + produces a hole in the frame info that gets filled by the + linker with zeros. + + The GCC behaviour is arguably a bug, but it's effectively now + part of the ABI, so we're now stuck with it, at least at the + object file level. A smart linker may decide, in the process + of compressing duplicate CIE information, that it can rewrite + the entire output section without this extra padding. */ + + start_offset = start - unit->dwarf_frame_buffer; + if (workaround < ALIGN4 && (start_offset & 3) != 0) + { + start += 4 - (start_offset & 3); + workaround = ALIGN4; + continue; + } + if (workaround < ALIGN8 && (start_offset & 7) != 0) + { + start += 8 - (start_offset & 7); + workaround = ALIGN8; + continue; + } + + /* Nothing left to try. Arrange to return as if we've consumed + the entire input section. Hopefully we'll get valid info from + the other of .debug_frame/.eh_frame. */ + workaround = FAIL; + ret = unit->dwarf_frame_buffer + unit->dwarf_frame_size; + break; + } + + switch (workaround) + { + case NONE: + break; + + case ALIGN4: + complaint (&symfile_complaints, + "Corrupt data in %s:%s; align 4 workaround apparently succeeded", + unit->dwarf_frame_section->owner->filename, + unit->dwarf_frame_section->name); + break; + + case ALIGN8: + complaint (&symfile_complaints, + "Corrupt data in %s:%s; align 8 workaround apparently succeeded", + unit->dwarf_frame_section->owner->filename, + unit->dwarf_frame_section->name); + break; + + default: + complaint (&symfile_complaints, + "Corrupt data in %s:%s", + unit->dwarf_frame_section->owner->filename, + unit->dwarf_frame_section->name); + break; + } + + return ret; +} + + +/* FIXME: kettenis/20030504: This still needs to be integrated with + dwarf2read.c in a better way. */ + +/* Imported from dwarf2read.c. */ +extern asection *dwarf_frame_section; +extern asection *dwarf_eh_frame_section; + +/* Imported from dwarf2read.c. */ +extern char *dwarf2_read_section (struct objfile *objfile, asection *sectp); + +void +dwarf2_build_frame_info (struct objfile *objfile) +{ + struct comp_unit unit; + char *frame_ptr; + + /* Build a minimal decoding of the DWARF2 compilation unit. */ + unit.abfd = objfile->obfd; + unit.objfile = objfile; + unit.addr_size = objfile->obfd->arch_info->bits_per_address / 8; + unit.dbase = 0; + unit.tbase = 0; + + /* First add the information from the .eh_frame section. That way, + the FDEs from that section are searched last. */ + if (dwarf_eh_frame_section) + { + asection *got, *txt; + + unit.cie = NULL; + unit.dwarf_frame_buffer = dwarf2_read_section (objfile, + dwarf_eh_frame_section); + + unit.dwarf_frame_size + = bfd_get_section_size_before_reloc (dwarf_eh_frame_section); + unit.dwarf_frame_section = dwarf_eh_frame_section; + + /* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base + that is used for the i386/amd64 target, which currently is + the only target in GCC that supports/uses the + DW_EH_PE_datarel encoding. */ + got = bfd_get_section_by_name (unit.abfd, ".got"); + if (got) + unit.dbase = got->vma; + + /* GCC emits the DW_EH_PE_textrel encoding type on sh and ia64 + so far. */ + txt = bfd_get_section_by_name (unit.abfd, ".text"); + if (txt) + unit.tbase = txt->vma; + + frame_ptr = unit.dwarf_frame_buffer; + while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size) + frame_ptr = decode_frame_entry (&unit, frame_ptr, 1); + } + + if (dwarf_frame_section) + { + unit.cie = NULL; + unit.dwarf_frame_buffer = dwarf2_read_section (objfile, + dwarf_frame_section); + unit.dwarf_frame_size + = bfd_get_section_size_before_reloc (dwarf_frame_section); + unit.dwarf_frame_section = dwarf_frame_section; + + frame_ptr = unit.dwarf_frame_buffer; + while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size) + frame_ptr = decode_frame_entry (&unit, frame_ptr, 0); + } +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_dwarf2_frame (void); + +void +_initialize_dwarf2_frame (void) +{ + dwarf2_frame_data = register_gdbarch_data (dwarf2_frame_init); + dwarf2_frame_objfile_data = register_objfile_data (); +} diff --git a/contrib/gdb/gdb/dwarf2-frame.h b/contrib/gdb/gdb/dwarf2-frame.h new file mode 100644 index 00000000000..1ae44b5064c --- /dev/null +++ b/contrib/gdb/gdb/dwarf2-frame.h @@ -0,0 +1,98 @@ +/* Frame unwinder for frames with DWARF Call Frame Information. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + Contributed by Mark Kettenis. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef DWARF2_FRAME_H +#define DWARF2_FRAME_H 1 + +struct gdbarch; +struct objfile; +struct frame_info; + +/* Register rule. */ + +enum dwarf2_frame_reg_rule +{ + /* Make certain that 0 maps onto the correct enum value; the + corresponding structure is being initialized using memset zero. + This indicates that CFI didn't provide any information at all + about a register, leaving how to obtain its value totally + unspecified. */ + DWARF2_FRAME_REG_UNSPECIFIED = 0, + + /* The term "undefined" comes from the DWARF2 CFI spec which this + code is moddeling; it indicates that the register's value is + "undefined". GCC uses the less formal term "unsaved". Its + definition is a combination of REG_UNDEFINED and REG_UNSPECIFIED. + The failure to differentiate the two helps explain a few problems + with the CFI generated by GCC. */ + DWARF2_FRAME_REG_UNDEFINED, + DWARF2_FRAME_REG_SAVED_OFFSET, + DWARF2_FRAME_REG_SAVED_REG, + DWARF2_FRAME_REG_SAVED_EXP, + DWARF2_FRAME_REG_SAME_VALUE, + + /* These aren't defined by the DWARF2 CFI specification, but are + used internally by GDB. */ + DWARF2_FRAME_REG_RA, /* Return Address. */ + DWARF2_FRAME_REG_CFA /* Call Frame Address. */ +}; + +/* Register state. */ + +struct dwarf2_frame_state_reg +{ + /* Each register save state can be described in terms of a CFA slot, + another register, or a location expression. */ + union { + LONGEST offset; + ULONGEST reg; + unsigned char *exp; + } loc; + ULONGEST exp_len; + enum dwarf2_frame_reg_rule how; +}; + +/* Set the architecture-specific register state initialization + function for GDBARCH to INIT_REG. */ + +extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch, + void (*init_reg) (struct gdbarch *, int, + struct dwarf2_frame_state_reg *)); + +/* Return the frame unwind methods for the function that contains PC, + or NULL if it can't be handled by DWARF CFI frame unwinder. */ + +extern const struct frame_unwind * + dwarf2_frame_sniffer (struct frame_info *next_frame); + +/* Return the frame base methods for the function that contains PC, or + NULL if it can't be handled by the DWARF CFI frame unwinder. */ + +extern const struct frame_base * + dwarf2_frame_base_sniffer (struct frame_info *next_frame); + +/* Register the DWARF CFI for OBJFILE. */ + +void dwarf2_frame_build_info (struct objfile *objfile); + +#endif /* dwarf2-frame.h */ diff --git a/contrib/gdb/gdb/dwarf2expr.c b/contrib/gdb/gdb/dwarf2expr.c new file mode 100644 index 00000000000..50baced5f2e --- /dev/null +++ b/contrib/gdb/gdb/dwarf2expr.c @@ -0,0 +1,670 @@ +/* Dwarf2 Expression Evaluator + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + Contributed by Daniel Berlin (dan@dberlin.org) + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "value.h" +#include "gdbcore.h" +#include "elf/dwarf2.h" +#include "dwarf2expr.h" + +/* Local prototypes. */ + +static void execute_stack_op (struct dwarf_expr_context *, + unsigned char *, unsigned char *); + +/* Create a new context for the expression evaluator. */ + +struct dwarf_expr_context * +new_dwarf_expr_context (void) +{ + struct dwarf_expr_context *retval; + retval = xcalloc (1, sizeof (struct dwarf_expr_context)); + retval->stack_len = 0; + retval->stack_allocated = 10; + retval->stack = xmalloc (retval->stack_allocated * sizeof (CORE_ADDR)); + return retval; +} + +/* Release the memory allocated to CTX. */ + +void +free_dwarf_expr_context (struct dwarf_expr_context *ctx) +{ + xfree (ctx->stack); + xfree (ctx); +} + +/* Expand the memory allocated to CTX's stack to contain at least + NEED more elements than are currently used. */ + +static void +dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need) +{ + if (ctx->stack_len + need > ctx->stack_allocated) + { + size_t newlen = ctx->stack_len + need + 10; + ctx->stack = xrealloc (ctx->stack, + newlen * sizeof (CORE_ADDR)); + ctx->stack_allocated = newlen; + } +} + +/* Push VALUE onto CTX's stack. */ + +void +dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value) +{ + dwarf_expr_grow_stack (ctx, 1); + ctx->stack[ctx->stack_len++] = value; +} + +/* Pop the top item off of CTX's stack. */ + +void +dwarf_expr_pop (struct dwarf_expr_context *ctx) +{ + if (ctx->stack_len <= 0) + error ("dwarf expression stack underflow"); + ctx->stack_len--; +} + +/* Retrieve the N'th item on CTX's stack. */ + +CORE_ADDR +dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n) +{ + if (ctx->stack_len < n) + error ("Asked for position %d of stack, stack only has %d elements on it\n", + n, ctx->stack_len); + return ctx->stack[ctx->stack_len - (1 + n)]; + +} + +/* Evaluate the expression at ADDR (LEN bytes long) using the context + CTX. */ + +void +dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr, + size_t len) +{ + execute_stack_op (ctx, addr, addr + len); +} + +/* Decode the unsigned LEB128 constant at BUF into the variable pointed to + by R, and return the new value of BUF. Verify that it doesn't extend + past BUF_END. */ + +unsigned char * +read_uleb128 (unsigned char *buf, unsigned char *buf_end, ULONGEST * r) +{ + unsigned shift = 0; + ULONGEST result = 0; + unsigned char byte; + + while (1) + { + if (buf >= buf_end) + error ("read_uleb128: Corrupted DWARF expression."); + + byte = *buf++; + result |= (byte & 0x7f) << shift; + if ((byte & 0x80) == 0) + break; + shift += 7; + } + *r = result; + return buf; +} + +/* Decode the signed LEB128 constant at BUF into the variable pointed to + by R, and return the new value of BUF. Verify that it doesn't extend + past BUF_END. */ + +unsigned char * +read_sleb128 (unsigned char *buf, unsigned char *buf_end, LONGEST * r) +{ + unsigned shift = 0; + LONGEST result = 0; + unsigned char byte; + + while (1) + { + if (buf >= buf_end) + error ("read_sleb128: Corrupted DWARF expression."); + + byte = *buf++; + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + break; + } + if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) + result |= -(1 << shift); + + *r = result; + return buf; +} + +/* Read an address from BUF, and verify that it doesn't extend past + BUF_END. The address is returned, and *BYTES_READ is set to the + number of bytes read from BUF. */ + +CORE_ADDR +dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read) +{ + CORE_ADDR result; + + if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT) + error ("dwarf2_read_address: Corrupted DWARF expression."); + + *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT; + /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2 + address is always unsigned. That may or may not be true. */ + result = extract_unsigned_integer (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT); + return result; +} + +/* Return the type of an address, for unsigned arithmetic. */ + +static struct type * +unsigned_address_type (void) +{ + switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT) + { + case 2: + return builtin_type_uint16; + case 4: + return builtin_type_uint32; + case 8: + return builtin_type_uint64; + default: + internal_error (__FILE__, __LINE__, + "Unsupported address size.\n"); + } +} + +/* Return the type of an address, for signed arithmetic. */ + +static struct type * +signed_address_type (void) +{ + switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT) + { + case 2: + return builtin_type_int16; + case 4: + return builtin_type_int32; + case 8: + return builtin_type_int64; + default: + internal_error (__FILE__, __LINE__, + "Unsupported address size.\n"); + } +} + +/* The engine for the expression evaluator. Using the context in CTX, + evaluate the expression between OP_PTR and OP_END. */ + +static void +execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr, + unsigned char *op_end) +{ + ctx->in_reg = 0; + + while (op_ptr < op_end) + { + enum dwarf_location_atom op = *op_ptr++; + CORE_ADDR result; + ULONGEST uoffset, reg; + LONGEST offset; + int bytes_read; + + switch (op) + { + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + result = op - DW_OP_lit0; + break; + + case DW_OP_addr: + result = dwarf2_read_address (op_ptr, op_end, &bytes_read); + op_ptr += bytes_read; + break; + + case DW_OP_const1u: + result = extract_unsigned_integer (op_ptr, 1); + op_ptr += 1; + break; + case DW_OP_const1s: + result = extract_signed_integer (op_ptr, 1); + op_ptr += 1; + break; + case DW_OP_const2u: + result = extract_unsigned_integer (op_ptr, 2); + op_ptr += 2; + break; + case DW_OP_const2s: + result = extract_signed_integer (op_ptr, 2); + op_ptr += 2; + break; + case DW_OP_const4u: + result = extract_unsigned_integer (op_ptr, 4); + op_ptr += 4; + break; + case DW_OP_const4s: + result = extract_signed_integer (op_ptr, 4); + op_ptr += 4; + break; + case DW_OP_const8u: + result = extract_unsigned_integer (op_ptr, 8); + op_ptr += 8; + break; + case DW_OP_const8s: + result = extract_signed_integer (op_ptr, 8); + op_ptr += 8; + break; + case DW_OP_constu: + op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + result = uoffset; + break; + case DW_OP_consts: + op_ptr = read_sleb128 (op_ptr, op_end, &offset); + result = offset; + break; + + /* The DW_OP_reg operations are required to occur alone in + location expressions. */ + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + if (op_ptr != op_end && *op_ptr != DW_OP_piece) + error ("DWARF-2 expression error: DW_OP_reg operations must be " + "used either alone or in conjuction with DW_OP_piece."); + + result = op - DW_OP_reg0; + ctx->in_reg = 1; + + break; + + case DW_OP_regx: + op_ptr = read_uleb128 (op_ptr, op_end, ®); + if (op_ptr != op_end && *op_ptr != DW_OP_piece) + error ("DWARF-2 expression error: DW_OP_reg operations must be " + "used either alone or in conjuction with DW_OP_piece."); + + result = reg; + ctx->in_reg = 1; + break; + + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + { + op_ptr = read_sleb128 (op_ptr, op_end, &offset); + result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0); + result += offset; + } + break; + case DW_OP_bregx: + { + op_ptr = read_uleb128 (op_ptr, op_end, ®); + op_ptr = read_sleb128 (op_ptr, op_end, &offset); + result = (ctx->read_reg) (ctx->baton, reg); + result += offset; + } + break; + case DW_OP_fbreg: + { + unsigned char *datastart; + size_t datalen; + unsigned int before_stack_len; + + op_ptr = read_sleb128 (op_ptr, op_end, &offset); + /* Rather than create a whole new context, we simply + record the stack length before execution, then reset it + afterwards, effectively erasing whatever the recursive + call put there. */ + before_stack_len = ctx->stack_len; + /* FIXME: cagney/2003-03-26: This code should be using + get_frame_base_address(), and then implement a dwarf2 + specific this_base method. */ + (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); + dwarf_expr_eval (ctx, datastart, datalen); + result = dwarf_expr_fetch (ctx, 0); + if (ctx->in_reg) + result = (ctx->read_reg) (ctx->baton, result); + result = result + offset; + ctx->stack_len = before_stack_len; + ctx->in_reg = 0; + } + break; + case DW_OP_dup: + result = dwarf_expr_fetch (ctx, 0); + break; + + case DW_OP_drop: + dwarf_expr_pop (ctx); + goto no_push; + + case DW_OP_pick: + offset = *op_ptr++; + result = dwarf_expr_fetch (ctx, offset); + break; + + case DW_OP_over: + result = dwarf_expr_fetch (ctx, 1); + break; + + case DW_OP_rot: + { + CORE_ADDR t1, t2, t3; + + if (ctx->stack_len < 3) + error ("Not enough elements for DW_OP_rot. Need 3, have %d\n", + ctx->stack_len); + t1 = ctx->stack[ctx->stack_len - 1]; + t2 = ctx->stack[ctx->stack_len - 2]; + t3 = ctx->stack[ctx->stack_len - 3]; + ctx->stack[ctx->stack_len - 1] = t2; + ctx->stack[ctx->stack_len - 2] = t3; + ctx->stack[ctx->stack_len - 3] = t1; + goto no_push; + } + + case DW_OP_deref: + case DW_OP_deref_size: + case DW_OP_abs: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_plus_uconst: + /* Unary operations. */ + result = dwarf_expr_fetch (ctx, 0); + dwarf_expr_pop (ctx); + + switch (op) + { + case DW_OP_deref: + { + char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); + int bytes_read; + + (ctx->read_mem) (ctx->baton, buf, result, + TARGET_ADDR_BIT / TARGET_CHAR_BIT); + result = dwarf2_read_address (buf, + buf + (TARGET_ADDR_BIT + / TARGET_CHAR_BIT), + &bytes_read); + } + break; + + case DW_OP_deref_size: + { + char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); + int bytes_read; + + (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++); + result = dwarf2_read_address (buf, + buf + (TARGET_ADDR_BIT + / TARGET_CHAR_BIT), + &bytes_read); + } + break; + + case DW_OP_abs: + if ((signed int) result < 0) + result = -result; + break; + case DW_OP_neg: + result = -result; + break; + case DW_OP_not: + result = ~result; + break; + case DW_OP_plus_uconst: + op_ptr = read_uleb128 (op_ptr, op_end, ®); + result += reg; + break; + } + break; + + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_or: + case DW_OP_plus: + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + case DW_OP_le: + case DW_OP_ge: + case DW_OP_eq: + case DW_OP_lt: + case DW_OP_gt: + case DW_OP_ne: + { + /* Binary operations. Use the value engine to do computations in + the right width. */ + CORE_ADDR first, second; + enum exp_opcode binop; + struct value *val1, *val2; + + second = dwarf_expr_fetch (ctx, 0); + dwarf_expr_pop (ctx); + + first = dwarf_expr_fetch (ctx, 0); + dwarf_expr_pop (ctx); + + val1 = value_from_longest (unsigned_address_type (), first); + val2 = value_from_longest (unsigned_address_type (), second); + + switch (op) + { + case DW_OP_and: + binop = BINOP_BITWISE_AND; + break; + case DW_OP_div: + binop = BINOP_DIV; + case DW_OP_minus: + binop = BINOP_SUB; + break; + case DW_OP_mod: + binop = BINOP_MOD; + break; + case DW_OP_mul: + binop = BINOP_MUL; + break; + case DW_OP_or: + binop = BINOP_BITWISE_IOR; + break; + case DW_OP_plus: + binop = BINOP_ADD; + break; + case DW_OP_shl: + binop = BINOP_LSH; + break; + case DW_OP_shr: + binop = BINOP_RSH; + case DW_OP_shra: + binop = BINOP_RSH; + val1 = value_from_longest (signed_address_type (), first); + break; + case DW_OP_xor: + binop = BINOP_BITWISE_XOR; + break; + case DW_OP_le: + binop = BINOP_LEQ; + break; + case DW_OP_ge: + binop = BINOP_GEQ; + break; + case DW_OP_eq: + binop = BINOP_EQUAL; + break; + case DW_OP_lt: + binop = BINOP_LESS; + break; + case DW_OP_gt: + binop = BINOP_GTR; + break; + case DW_OP_ne: + binop = BINOP_NOTEQUAL; + break; + default: + internal_error (__FILE__, __LINE__, + "Can't be reached."); + } + result = value_as_long (value_binop (val1, val2, binop)); + } + break; + + case DW_OP_GNU_push_tls_address: + /* Variable is at a constant offset in the thread-local + storage block into the objfile for the current thread and + the dynamic linker module containing this expression. Here + we return returns the offset from that base. The top of the + stack has the offset from the beginning of the thread + control block at which the variable is located. Nothing + should follow this operator, so the top of stack would be + returned. */ + result = dwarf_expr_fetch (ctx, 0); + dwarf_expr_pop (ctx); + result = (ctx->get_tls_address) (ctx->baton, result); + break; + + case DW_OP_skip: + offset = extract_signed_integer (op_ptr, 2); + op_ptr += 2; + op_ptr += offset; + goto no_push; + + case DW_OP_bra: + offset = extract_signed_integer (op_ptr, 2); + op_ptr += 2; + if (dwarf_expr_fetch (ctx, 0) != 0) + op_ptr += offset; + dwarf_expr_pop (ctx); + goto no_push; + + case DW_OP_nop: + goto no_push; + + default: + error ("Unhandled dwarf expression opcode 0x%x", op); + } + + /* Most things push a result value. */ + dwarf_expr_push (ctx, result); + no_push:; + } +} diff --git a/contrib/gdb/gdb/dwarf2expr.h b/contrib/gdb/gdb/dwarf2expr.h new file mode 100644 index 00000000000..0a60edb8237 --- /dev/null +++ b/contrib/gdb/gdb/dwarf2expr.h @@ -0,0 +1,96 @@ +/* Dwarf2 Expression Evaluator + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + Contributed by Daniel Berlin (dan@dberlin.org) + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined (DWARF2EXPR_H) +#define DWARF2EXPR_H + +/* The expression evaluator works with a dwarf_expr_context, describing + its current state and its callbacks. */ +struct dwarf_expr_context +{ + /* The stack of values, allocated with xmalloc. */ + CORE_ADDR *stack; + + /* The number of values currently pushed on the stack, and the + number of elements allocated to the stack. */ + int stack_len, stack_allocated; + + /* An opaque argument provided by the caller, which will be passed + to all of the callback functions. */ + void *baton; + + /* Return the value of register number REGNUM. */ + CORE_ADDR (*read_reg) (void *baton, int regnum); + + /* Read LENGTH bytes at ADDR into BUF. */ + void (*read_mem) (void *baton, char *buf, CORE_ADDR addr, + size_t length); + + /* Return the location expression for the frame base attribute, in + START and LENGTH. The result must be live until the current + expression evaluation is complete. */ + void (*get_frame_base) (void *baton, unsigned char **start, + size_t *length); + + /* Return the thread-local storage address for + DW_OP_GNU_push_tls_address. */ + CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset); + +#if 0 + /* Not yet implemented. */ + + /* Return the location expression for the dwarf expression + subroutine in the die at OFFSET in the current compilation unit. + The result must be live until the current expression evaluation + is complete. */ + unsigned char *(*get_subr) (void *baton, off_t offset, size_t *length); + + /* Return the `object address' for DW_OP_push_object_address. */ + CORE_ADDR (*get_object_address) (void *baton); +#endif + + /* The current depth of dwarf expression recursion, via DW_OP_call*, + DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum + depth we'll tolerate before raising an error. */ + int recursion_depth, max_recursion_depth; + + /* Non-zero if the result is in a register. The register number + will be on the expression stack. */ + int in_reg; +}; + +struct dwarf_expr_context *new_dwarf_expr_context (void); +void free_dwarf_expr_context (struct dwarf_expr_context *ctx); + +void dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value); +void dwarf_expr_pop (struct dwarf_expr_context *ctx); +void dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr, + size_t len); +CORE_ADDR dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n); + + +unsigned char *read_uleb128 (unsigned char *buf, unsigned char *buf_end, + ULONGEST * r); +unsigned char *read_sleb128 (unsigned char *buf, unsigned char *buf_end, + LONGEST * r); +CORE_ADDR dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, + int *bytes_read); + +#endif diff --git a/contrib/gdb/gdb/dwarf2loc.c b/contrib/gdb/gdb/dwarf2loc.c new file mode 100644 index 00000000000..cdbeb10acf4 --- /dev/null +++ b/contrib/gdb/gdb/dwarf2loc.c @@ -0,0 +1,548 @@ +/* DWARF 2 location expression support for GDB. + Copyright 2003 Free Software Foundation, Inc. + Contributed by Daniel Jacobowitz, MontaVista Software, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "ui-out.h" +#include "value.h" +#include "frame.h" +#include "gdbcore.h" +#include "target.h" +#include "inferior.h" +#include "ax.h" +#include "ax-gdb.h" +#include "regcache.h" +#include "objfiles.h" + +#include "elf/dwarf2.h" +#include "dwarf2expr.h" +#include "dwarf2loc.h" + +#include "gdb_string.h" + +#ifndef DWARF2_REG_TO_REGNUM +#define DWARF2_REG_TO_REGNUM(REG) (REG) +#endif + +/* A helper function for dealing with location lists. Given a + symbol baton (BATON) and a pc value (PC), find the appropriate + location expression, set *LOCEXPR_LENGTH, and return a pointer + to the beginning of the expression. Returns NULL on failure. + + For now, only return the first matching location expression; there + can be more than one in the list. */ + +static char * +find_location_expression (struct dwarf2_loclist_baton *baton, + size_t *locexpr_length, CORE_ADDR pc) +{ + CORE_ADDR low, high; + char *loc_ptr, *buf_end; + unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT, length; + CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); + /* Adjust base_address for relocatable objects. */ + CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets, + SECT_OFF_TEXT (baton->objfile)); + CORE_ADDR base_address = baton->base_address + base_offset; + + loc_ptr = baton->data; + buf_end = baton->data + baton->size; + + while (1) + { + low = dwarf2_read_address (loc_ptr, buf_end, &length); + loc_ptr += length; + high = dwarf2_read_address (loc_ptr, buf_end, &length); + loc_ptr += length; + + /* An end-of-list entry. */ + if (low == 0 && high == 0) + return NULL; + + /* A base-address-selection entry. */ + if ((low & base_mask) == base_mask) + { + base_address = high; + continue; + } + + /* Otherwise, a location expression entry. */ + low += base_address; + high += base_address; + + length = extract_unsigned_integer (loc_ptr, 2); + loc_ptr += 2; + + if (pc >= low && pc < high) + { + *locexpr_length = length; + return loc_ptr; + } + + loc_ptr += length; + } +} + +/* This is the baton used when performing dwarf2 expression + evaluation. */ +struct dwarf_expr_baton +{ + struct frame_info *frame; + struct objfile *objfile; +}; + +/* Helper functions for dwarf2_evaluate_loc_desc. */ + +/* Using the frame specified in BATON, read register REGNUM. The lval + type will be returned in LVALP, and for lval_memory the register + save address will be returned in ADDRP. */ +static CORE_ADDR +dwarf_expr_read_reg (void *baton, int dwarf_regnum) +{ + struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; + CORE_ADDR result, save_addr; + enum lval_type lval_type; + char *buf; + int optimized, regnum, realnum, regsize; + + regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum); + regsize = register_size (current_gdbarch, regnum); + buf = (char *) alloca (regsize); + + frame_register (debaton->frame, regnum, &optimized, &lval_type, &save_addr, + &realnum, buf); + /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2 + address is always unsigned. That may or may not be true. */ + result = extract_unsigned_integer (buf, regsize); + + return result; +} + +/* Read memory at ADDR (length LEN) into BUF. */ + +static void +dwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) +{ + read_memory (addr, buf, len); +} + +/* Using the frame specified in BATON, find the location expression + describing the frame base. Return a pointer to it in START and + its length in LENGTH. */ +static void +dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length) +{ + /* FIXME: cagney/2003-03-26: This code should be using + get_frame_base_address(), and then implement a dwarf2 specific + this_base method. */ + struct symbol *framefunc; + struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; + + framefunc = get_frame_function (debaton->frame); + + if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs) + { + struct dwarf2_loclist_baton *symbaton; + symbaton = SYMBOL_LOCATION_BATON (framefunc); + *start = find_location_expression (symbaton, length, + get_frame_pc (debaton->frame)); + } + else + { + struct dwarf2_locexpr_baton *symbaton; + symbaton = SYMBOL_LOCATION_BATON (framefunc); + *length = symbaton->size; + *start = symbaton->data; + } + + if (*start == NULL) + error ("Could not find the frame base for \"%s\".", + SYMBOL_NATURAL_NAME (framefunc)); +} + +/* Using the objfile specified in BATON, find the address for the + current thread's thread-local storage with offset OFFSET. */ +static CORE_ADDR +dwarf_expr_tls_address (void *baton, CORE_ADDR offset) +{ + struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; + CORE_ADDR addr; + + if (target_get_thread_local_address_p ()) + addr = target_get_thread_local_address (inferior_ptid, + debaton->objfile, + offset); + /* It wouldn't be wrong here to try a gdbarch method, too; finding + TLS is an ABI-specific thing. But we don't do that yet. */ + else + error ("Cannot find thread-local variables on this target"); + + return addr; +} + +/* Evaluate a location description, starting at DATA and with length + SIZE, to find the current location of variable VAR in the context + of FRAME. */ +static struct value * +dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, + unsigned char *data, unsigned short size, + struct objfile *objfile) +{ + CORE_ADDR result; + struct value *retval; + struct dwarf_expr_baton baton; + struct dwarf_expr_context *ctx; + + if (size == 0) + { + retval = allocate_value (SYMBOL_TYPE (var)); + VALUE_LVAL (retval) = not_lval; + VALUE_OPTIMIZED_OUT (retval) = 1; + } + + baton.frame = frame; + baton.objfile = objfile; + + ctx = new_dwarf_expr_context (); + ctx->baton = &baton; + ctx->read_reg = dwarf_expr_read_reg; + ctx->read_mem = dwarf_expr_read_mem; + ctx->get_frame_base = dwarf_expr_frame_base; + ctx->get_tls_address = dwarf_expr_tls_address; + + dwarf_expr_eval (ctx, data, size); + result = dwarf_expr_fetch (ctx, 0); + + if (ctx->in_reg) + { + int regnum = DWARF2_REG_TO_REGNUM (result); + retval = value_from_register (SYMBOL_TYPE (var), regnum, frame); + } + else + { + retval = allocate_value (SYMBOL_TYPE (var)); + VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var); + + VALUE_LVAL (retval) = lval_memory; + VALUE_LAZY (retval) = 1; + VALUE_ADDRESS (retval) = result; + } + + free_dwarf_expr_context (ctx); + + return retval; +} + + + + + +/* Helper functions and baton for dwarf2_loc_desc_needs_frame. */ + +struct needs_frame_baton +{ + int needs_frame; +}; + +/* Reads from registers do require a frame. */ +static CORE_ADDR +needs_frame_read_reg (void *baton, int regnum) +{ + struct needs_frame_baton *nf_baton = baton; + nf_baton->needs_frame = 1; + return 1; +} + +/* Reads from memory do not require a frame. */ +static void +needs_frame_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) +{ + memset (buf, 0, len); +} + +/* Frame-relative accesses do require a frame. */ +static void +needs_frame_frame_base (void *baton, unsigned char **start, size_t * length) +{ + static char lit0 = DW_OP_lit0; + struct needs_frame_baton *nf_baton = baton; + + *start = &lit0; + *length = 1; + + nf_baton->needs_frame = 1; +} + +/* Thread-local accesses do require a frame. */ +static CORE_ADDR +needs_frame_tls_address (void *baton, CORE_ADDR offset) +{ + struct needs_frame_baton *nf_baton = baton; + nf_baton->needs_frame = 1; + return 1; +} + +/* Return non-zero iff the location expression at DATA (length SIZE) + requires a frame to evaluate. */ + +static int +dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size) +{ + struct needs_frame_baton baton; + struct dwarf_expr_context *ctx; + int in_reg; + + baton.needs_frame = 0; + + ctx = new_dwarf_expr_context (); + ctx->baton = &baton; + ctx->read_reg = needs_frame_read_reg; + ctx->read_mem = needs_frame_read_mem; + ctx->get_frame_base = needs_frame_frame_base; + ctx->get_tls_address = needs_frame_tls_address; + + dwarf_expr_eval (ctx, data, size); + + in_reg = ctx->in_reg; + + free_dwarf_expr_context (ctx); + + return baton.needs_frame || in_reg; +} + +static void +dwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, + struct axs_value * value, unsigned char *data, + int size) +{ + if (size == 0) + error ("Symbol \"%s\" has been optimized out.", + SYMBOL_PRINT_NAME (symbol)); + + if (size == 1 + && data[0] >= DW_OP_reg0 + && data[0] <= DW_OP_reg31) + { + value->kind = axs_lvalue_register; + value->u.reg = data[0] - DW_OP_reg0; + } + else if (data[0] == DW_OP_regx) + { + ULONGEST reg; + read_uleb128 (data + 1, data + size, ®); + value->kind = axs_lvalue_register; + value->u.reg = reg; + } + else if (data[0] == DW_OP_fbreg) + { + /* And this is worse than just minimal; we should honor the frame base + as above. */ + int frame_reg; + LONGEST frame_offset; + unsigned char *buf_end; + + buf_end = read_sleb128 (data + 1, data + size, &frame_offset); + if (buf_end != data + size) + error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".", + SYMBOL_PRINT_NAME (symbol)); + + TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset); + ax_reg (ax, frame_reg); + ax_const_l (ax, frame_offset); + ax_simple (ax, aop_add); + + ax_const_l (ax, frame_offset); + ax_simple (ax, aop_add); + value->kind = axs_lvalue_memory; + } + else + error ("Unsupported DWARF opcode in the location of \"%s\".", + SYMBOL_PRINT_NAME (symbol)); +} + +/* Return the value of SYMBOL in FRAME using the DWARF-2 expression + evaluator to calculate the location. */ +static struct value * +locexpr_read_variable (struct symbol *symbol, struct frame_info *frame) +{ + struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + struct value *val; + val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size, + dlbaton->objfile); + + return val; +} + +/* Return non-zero iff we need a frame to evaluate SYMBOL. */ +static int +locexpr_read_needs_frame (struct symbol *symbol) +{ + struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size); +} + +/* Print a natural-language description of SYMBOL to STREAM. */ +static int +locexpr_describe_location (struct symbol *symbol, struct ui_file *stream) +{ + /* FIXME: be more extensive. */ + struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + + if (dlbaton->size == 1 + && dlbaton->data[0] >= DW_OP_reg0 + && dlbaton->data[0] <= DW_OP_reg31) + { + int regno = DWARF2_REG_TO_REGNUM (dlbaton->data[0] - DW_OP_reg0); + fprintf_filtered (stream, + "a variable in register %s", REGISTER_NAME (regno)); + return 1; + } + + /* The location expression for a TLS variable looks like this (on a + 64-bit LE machine): + + DW_AT_location : 10 byte block: 3 4 0 0 0 0 0 0 0 e0 + (DW_OP_addr: 4; DW_OP_GNU_push_tls_address) + + 0x3 is the encoding for DW_OP_addr, which has an operand as long + as the size of an address on the target machine (here is 8 + bytes). 0xe0 is the encoding for DW_OP_GNU_push_tls_address. + The operand represents the offset at which the variable is within + the thread local storage. */ + + if (dlbaton->size > 1 + && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address) + if (dlbaton->data[0] == DW_OP_addr) + { + int bytes_read; + CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1], + &dlbaton->data[dlbaton->size - 1], + &bytes_read); + fprintf_filtered (stream, + "a thread-local variable at offset %s in the " + "thread-local storage for `%s'", + paddr_nz (offset), dlbaton->objfile->name); + return 1; + } + + + fprintf_filtered (stream, + "a variable with complex or multiple locations (DWARF2)"); + return 1; +} + + +/* Describe the location of SYMBOL as an agent value in VALUE, generating + any necessary bytecode in AX. + + NOTE drow/2003-02-26: This function is extremely minimal, because + doing it correctly is extremely complicated and there is no + publicly available stub with tracepoint support for me to test + against. When there is one this function should be revisited. */ + +static void +locexpr_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, + struct axs_value * value) +{ + struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + + dwarf2_tracepoint_var_ref (symbol, ax, value, dlbaton->data, dlbaton->size); +} + +/* The set of location functions used with the DWARF-2 expression + evaluator. */ +const struct symbol_ops dwarf2_locexpr_funcs = { + locexpr_read_variable, + locexpr_read_needs_frame, + locexpr_describe_location, + locexpr_tracepoint_var_ref +}; + + +/* Wrapper functions for location lists. These generally find + the appropriate location expression and call something above. */ + +/* Return the value of SYMBOL in FRAME using the DWARF-2 expression + evaluator to calculate the location. */ +static struct value * +loclist_read_variable (struct symbol *symbol, struct frame_info *frame) +{ + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + struct value *val; + unsigned char *data; + size_t size; + + data = find_location_expression (dlbaton, &size, + frame ? get_frame_pc (frame) : 0); + if (data == NULL) + error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol)); + + val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->objfile); + + return val; +} + +/* Return non-zero iff we need a frame to evaluate SYMBOL. */ +static int +loclist_read_needs_frame (struct symbol *symbol) +{ + /* If there's a location list, then assume we need to have a frame + to choose the appropriate location expression. With tracking of + global variables this is not necessarily true, but such tracking + is disabled in GCC at the moment until we figure out how to + represent it. */ + + return 1; +} + +/* Print a natural-language description of SYMBOL to STREAM. */ +static int +loclist_describe_location (struct symbol *symbol, struct ui_file *stream) +{ + /* FIXME: Could print the entire list of locations. */ + fprintf_filtered (stream, "a variable with multiple locations"); + return 1; +} + +/* Describe the location of SYMBOL as an agent value in VALUE, generating + any necessary bytecode in AX. */ +static void +loclist_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, + struct axs_value * value) +{ + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + unsigned char *data; + size_t size; + + data = find_location_expression (dlbaton, &size, ax->scope); + if (data == NULL) + error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol)); + + dwarf2_tracepoint_var_ref (symbol, ax, value, data, size); +} + +/* The set of location functions used with the DWARF-2 expression + evaluator and location lists. */ +const struct symbol_ops dwarf2_loclist_funcs = { + loclist_read_variable, + loclist_read_needs_frame, + loclist_describe_location, + loclist_tracepoint_var_ref +}; diff --git a/contrib/gdb/gdb/dwarf2loc.h b/contrib/gdb/gdb/dwarf2loc.h new file mode 100644 index 00000000000..ce0a8ef0bed --- /dev/null +++ b/contrib/gdb/gdb/dwarf2loc.h @@ -0,0 +1,70 @@ +/* Dwarf2 location expression support for GDB. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined (DWARF2LOC_H) +#define DWARF2LOC_H + +struct symbol_ops; + +/* This header is private to the DWARF-2 reader. It is shared between + dwarf2read.c and dwarf2loc.c. */ + +/* The symbol location baton types used by the DWARF-2 reader (i.e. + SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol). "struct + dwarf2_locexpr_baton" is for a symbol with a single location + expression; "struct dwarf2_loclist_baton" is for a symbol with a + location list. */ + +struct dwarf2_locexpr_baton +{ + /* Pointer to the start of the location expression. */ + unsigned char *data; + + /* Length of the location expression. */ + unsigned short size; + + /* The objfile containing the symbol whose location we're computing. */ + struct objfile *objfile; +}; + +struct dwarf2_loclist_baton +{ + /* The initial base address for the location list, based on the compilation + unit. */ + CORE_ADDR base_address; + + /* Pointer to the start of the location list. */ + unsigned char *data; + + /* Length of the location list. */ + unsigned short size; + + /* The objfile containing the symbol whose location we're computing. */ + /* Used (only???) by thread local variables. The objfile in which + this symbol is defined. To find a thread-local variable (e.g., a + variable declared with the `__thread' storage class), we may need + to know which object file it's in. */ + struct objfile *objfile; +}; + +extern const struct symbol_ops dwarf2_locexpr_funcs; +extern const struct symbol_ops dwarf2_loclist_funcs; + +#endif diff --git a/contrib/gdb/gdb/dwarf2read.c b/contrib/gdb/gdb/dwarf2read.c index 9dbcbde9cea..cc69ede557e 100644 --- a/contrib/gdb/gdb/dwarf2read.c +++ b/contrib/gdb/gdb/dwarf2read.c @@ -1,5 +1,6 @@ /* DWARF 2 debugging format support for GDB. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, @@ -30,17 +31,20 @@ #include "bfd.h" #include "symtab.h" #include "gdbtypes.h" -#include "symfile.h" #include "objfiles.h" #include "elf/dwarf2.h" #include "buildsym.h" #include "demangle.h" #include "expression.h" #include "filenames.h" /* for DOSish file names */ - +#include "macrotab.h" #include "language.h" #include "complaints.h" #include "bcache.h" +#include "dwarf2expr.h" +#include "dwarf2loc.h" +#include "cp-support.h" + #include #include "gdb_string.h" #include "gdb_assert.h" @@ -124,17 +128,6 @@ _STATEMENT_PROLOGUE; /* offsets and sizes of debugging sections */ -static file_ptr dwarf_info_offset; -static file_ptr dwarf_abbrev_offset; -static file_ptr dwarf_line_offset; -static file_ptr dwarf_pubnames_offset; -static file_ptr dwarf_aranges_offset; -static file_ptr dwarf_loc_offset; -static file_ptr dwarf_macinfo_offset; -static file_ptr dwarf_str_offset; -file_ptr dwarf_frame_offset; -file_ptr dwarf_eh_frame_offset; - static unsigned int dwarf_info_size; static unsigned int dwarf_abbrev_size; static unsigned int dwarf_line_size; @@ -143,9 +136,22 @@ static unsigned int dwarf_aranges_size; static unsigned int dwarf_loc_size; static unsigned int dwarf_macinfo_size; static unsigned int dwarf_str_size; +static unsigned int dwarf_ranges_size; unsigned int dwarf_frame_size; unsigned int dwarf_eh_frame_size; +static asection *dwarf_info_section; +static asection *dwarf_abbrev_section; +static asection *dwarf_line_section; +static asection *dwarf_pubnames_section; +static asection *dwarf_aranges_section; +static asection *dwarf_loc_section; +static asection *dwarf_macinfo_section; +static asection *dwarf_str_section; +static asection *dwarf_ranges_section; +asection *dwarf_frame_section; +asection *dwarf_eh_frame_section; + /* names of the debugging sections */ #define INFO_SECTION ".debug_info" @@ -156,11 +162,17 @@ unsigned int dwarf_eh_frame_size; #define LOC_SECTION ".debug_loc" #define MACINFO_SECTION ".debug_macinfo" #define STR_SECTION ".debug_str" +#define RANGES_SECTION ".debug_ranges" #define FRAME_SECTION ".debug_frame" #define EH_FRAME_SECTION ".eh_frame" /* local data types */ +/* We hold several abbreviation tables in memory at the same time. */ +#ifndef ABBREV_HASH_SIZE +#define ABBREV_HASH_SIZE 121 +#endif + /* The data in a compilation unit header, after target2host translation, looks like this. */ struct comp_unit_head @@ -173,21 +185,124 @@ struct comp_unit_head unsigned int offset_size; /* size of file offsets; either 4 or 8 */ unsigned int initial_length_size; /* size of the length field; either 4 or 12 */ + + /* Offset to the first byte of this compilation unit header in the + * .debug_info section, for resolving relative reference dies. */ + + unsigned int offset; + + /* Pointer to this compilation unit header in the .debug_info + * section */ + + char *cu_head_ptr; + + /* Pointer to the first die of this compilatio unit. This will + * be the first byte following the compilation unit header. */ + + char *first_die_ptr; + + /* Pointer to the next compilation unit header in the program. */ + + struct comp_unit_head *next; + + /* DWARF abbreviation table associated with this compilation unit */ + + struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE]; + + /* Base address of this compilation unit. */ + + CORE_ADDR base_address; + + /* Non-zero if base_address has been set. */ + + int base_known; }; -/* The data in the .debug_line statement prologue looks like this. */ -struct line_head +/* Internal state when decoding a particular compilation unit. */ +struct dwarf2_cu +{ + /* The objfile containing this compilation unit. */ + struct objfile *objfile; + + /* The header of the compilation unit. + + FIXME drow/2003-11-10: Some of the things from the comp_unit_head + should be moved to the dwarf2_cu structure; for instance the abbrevs + hash table. */ + struct comp_unit_head header; + + struct function_range *first_fn, *last_fn, *cached_fn; + + /* The language we are debugging. */ + enum language language; + const struct language_defn *language_defn; + + /* The generic symbol table building routines have separate lists for + file scope symbols and all all other scopes (local scopes). So + we need to select the right one to pass to add_symbol_to_list(). + We do it by keeping a pointer to the correct list in list_in_scope. + + FIXME: The original dwarf code just treated the file scope as the + first local scope, and all other local scopes as nested local + scopes, and worked fine. Check to see if we really need to + distinguish these in buildsym.c. */ + struct pending **list_in_scope; + + /* Maintain an array of referenced fundamental types for the current + compilation unit being read. For DWARF version 1, we have to construct + the fundamental types on the fly, since no information about the + fundamental types is supplied. Each such fundamental type is created by + calling a language dependent routine to create the type, and then a + pointer to that type is then placed in the array at the index specified + by it's FT_ value. The array has a fixed size set by the + FT_NUM_MEMBERS compile time constant, which is the number of predefined + fundamental types gdb knows how to construct. */ + struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */ +}; + +/* The line number information for a compilation unit (found in the + .debug_line section) begins with a "statement program header", + which contains the following information. */ +struct line_header +{ + unsigned int total_length; + unsigned short version; + unsigned int header_length; + unsigned char minimum_instruction_length; + unsigned char default_is_stmt; + int line_base; + unsigned char line_range; + unsigned char opcode_base; + + /* standard_opcode_lengths[i] is the number of operands for the + standard opcode whose value is i. This means that + standard_opcode_lengths[0] is unused, and the last meaningful + element is standard_opcode_lengths[opcode_base - 1]. */ + unsigned char *standard_opcode_lengths; + + /* The include_directories table. NOTE! These strings are not + allocated with xmalloc; instead, they are pointers into + debug_line_buffer. If you try to free them, `free' will get + indigestion. */ + unsigned int num_include_dirs, include_dirs_size; + char **include_dirs; + + /* The file_names table. NOTE! These strings are not allocated + with xmalloc; instead, they are pointers into debug_line_buffer. + Don't try to free them directly. */ + unsigned int num_file_names, file_names_size; + struct file_entry { - unsigned int total_length; - unsigned short version; - unsigned int prologue_length; - unsigned char minimum_instruction_length; - unsigned char default_is_stmt; - int line_base; - unsigned char line_range; - unsigned char opcode_base; - unsigned char *standard_opcode_lengths; - }; + char *name; + unsigned int dir_index; + unsigned int mod_time; + unsigned int length; + } *file_names; + + /* The start and end of the statement program following this + header. These point into dwarf_line_buffer. */ + char *statement_program_start, *statement_program_end; +}; /* When we construct a partial symbol table entry we only need this much information. */ @@ -230,13 +345,21 @@ struct attr_abbrev struct die_info { enum dwarf_tag tag; /* Tag indicating type of die */ - unsigned short has_children; /* Does the die have children */ unsigned int abbrev; /* Abbrev number */ unsigned int offset; /* Offset in .debug_info section */ unsigned int num_attrs; /* Number of attributes */ struct attribute *attrs; /* An array of attributes */ struct die_info *next_ref; /* Next die in ref hash table */ - struct die_info *next; /* Next die in linked list */ + + /* The dies in a compilation unit form an n-ary tree. PARENT + points to this die's parent; CHILD points to the first child of + this node; and all the children of a given node are chained + together via their SIBLING fields, terminated by a die whose + tag is zero. */ + struct die_info *child; /* Its first child, if any. */ + struct die_info *sibling; /* Its next sibling, if any. */ + struct die_info *parent; /* Its parent, if any. */ + struct type *type; /* Cached type information */ }; @@ -256,6 +379,14 @@ struct attribute u; }; +struct function_range +{ + const char *name; + CORE_ADDR lowpc, highpc; + int seen_line; + struct function_range *next; +}; + /* Get at parts of an attribute structure */ #define DW_STRING(attr) ((attr)->u.str) @@ -271,17 +402,10 @@ struct dwarf_block char *data; }; -/* We only hold one compilation unit's abbrevs in - memory at any one time. */ -#ifndef ABBREV_HASH_SIZE -#define ABBREV_HASH_SIZE 121 -#endif #ifndef ATTR_ALLOC_CHUNK #define ATTR_ALLOC_CHUNK 4 #endif -static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE]; - /* A hash table of die offsets for following references. */ #ifndef REF_HASH_SIZE #define REF_HASH_SIZE 1021 @@ -292,79 +416,36 @@ static struct die_info *die_ref_table[REF_HASH_SIZE]; /* Obstack for allocating temporary storage used during symbol reading. */ static struct obstack dwarf2_tmp_obstack; -/* Offset to the first byte of the current compilation unit header, - for resolving relative reference dies. */ -static unsigned int cu_header_offset; - /* Allocate fields for structs, unions and enums in this size. */ #ifndef DW_FIELD_ALLOC_CHUNK #define DW_FIELD_ALLOC_CHUNK 4 #endif -/* The language we are debugging. */ -static enum language cu_language; -static const struct language_defn *cu_language_defn; - /* Actually data from the sections. */ static char *dwarf_info_buffer; static char *dwarf_abbrev_buffer; static char *dwarf_line_buffer; static char *dwarf_str_buffer; +static char *dwarf_macinfo_buffer; +static char *dwarf_ranges_buffer; +static char *dwarf_loc_buffer; /* A zeroed version of a partial die for initialization purposes. */ static struct partial_die_info zeroed_partial_die; -/* The generic symbol table building routines have separate lists for - file scope symbols and all all other scopes (local scopes). So - we need to select the right one to pass to add_symbol_to_list(). - We do it by keeping a pointer to the correct list in list_in_scope. - - FIXME: The original dwarf code just treated the file scope as the first - local scope, and all other local scopes as nested local scopes, and worked - fine. Check to see if we really need to distinguish these - in buildsym.c. */ -static struct pending **list_in_scope = &file_symbols; - /* FIXME: decode_locdesc sets these variables to describe the location to the caller. These ought to be a structure or something. If none of the flags are set, the object lives at the address returned by decode_locdesc. */ -static int optimized_out; /* No ops in location in expression, - so object was optimized out. */ static int isreg; /* Object lives in register. decode_locdesc's return value is the register number. */ -static int offreg; /* Object's address is the sum of the - register specified by basereg, plus - the offset returned. */ -static int basereg; /* See `offreg'. */ -static int isderef; /* Value described by flags above is - the address of a pointer to the object. */ -static int islocal; /* Variable is at the returned offset - from the frame start, but there's - no identified frame pointer for - this function, so we can't say - which register it's relative to; - use LOC_LOCAL. */ - -/* DW_AT_frame_base values for the current function. - frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it - contains the register number for the frame register. - frame_base_offset is the offset from the frame register to the - virtual stack frame. */ -static int frame_base_reg; -static CORE_ADDR frame_base_offset; - -/* This value is added to each symbol value. FIXME: Generalize to - the section_offsets structure used by dbxread (once this is done, - pass the appropriate section number to end_symtab). */ -static CORE_ADDR baseaddr; /* Add to each symbol value */ /* We put a pointer to this structure in the read_symtab_private field of the psymtab. The complete dwarf information for an objfile is kept in the - psymbol_obstack, so that absolute die references can be handled. + objfile_obstack, so that absolute die references can be handled. Most of the information in this structure is related to an entire object file and could be passed via the sym_private field of the objfile. It is however conceivable that dwarf2 might not be the only type @@ -392,6 +473,10 @@ struct dwarf2_pinfo char *dwarf_line_buffer; + /* Size of dwarf_line_buffer, in bytes. */ + + unsigned int dwarf_line_size; + /* Pointer to start of dwarf string buffer for the objfile. */ char *dwarf_str_buffer; @@ -399,6 +484,30 @@ struct dwarf2_pinfo /* Size of dwarf string section for the objfile. */ unsigned int dwarf_str_size; + + /* Pointer to start of dwarf macro buffer for the objfile. */ + + char *dwarf_macinfo_buffer; + + /* Size of dwarf macinfo section for the objfile. */ + + unsigned int dwarf_macinfo_size; + + /* Pointer to start of dwarf ranges buffer for the objfile. */ + + char *dwarf_ranges_buffer; + + /* Size of dwarf ranges buffer for the objfile. */ + + unsigned int dwarf_ranges_size; + + /* Pointer to start of dwarf locations buffer for the objfile. */ + + char *dwarf_loc_buffer; + + /* Size of dwarf locations buffer for the objfile. */ + + unsigned int dwarf_loc_size; }; #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private) @@ -407,19 +516,15 @@ struct dwarf2_pinfo #define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer) #define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size) #define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer) +#define DWARF_LINE_SIZE(p) (PST_PRIVATE(p)->dwarf_line_size) #define DWARF_STR_BUFFER(p) (PST_PRIVATE(p)->dwarf_str_buffer) #define DWARF_STR_SIZE(p) (PST_PRIVATE(p)->dwarf_str_size) - -/* Maintain an array of referenced fundamental types for the current - compilation unit being read. For DWARF version 1, we have to construct - the fundamental types on the fly, since no information about the - fundamental types is supplied. Each such fundamental type is created by - calling a language dependent routine to create the type, and then a - pointer to that type is then placed in the array at the index specified - by it's FT_ value. The array has a fixed size set by the - FT_NUM_MEMBERS compile time constant, which is the number of predefined - fundamental types gdb knows how to construct. */ -static struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */ +#define DWARF_MACINFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_macinfo_buffer) +#define DWARF_MACINFO_SIZE(p) (PST_PRIVATE(p)->dwarf_macinfo_size) +#define DWARF_RANGES_BUFFER(p) (PST_PRIVATE(p)->dwarf_ranges_buffer) +#define DWARF_RANGES_SIZE(p) (PST_PRIVATE(p)->dwarf_ranges_size) +#define DWARF_LOC_BUFFER(p) (PST_PRIVATE(p)->dwarf_loc_buffer) +#define DWARF_LOC_SIZE(p) (PST_PRIVATE(p)->dwarf_loc_size) /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte, but this would require a corresponding change in unpack_field_as_long @@ -476,94 +581,53 @@ struct field_info /* Various complaints about symbol reading that don't abort the process */ -static struct complaint dwarf2_const_ignored = +static void +dwarf2_statement_list_fits_in_line_number_section_complaint (void) { - "type qualifier 'const' ignored", 0, 0 -}; -static struct complaint dwarf2_volatile_ignored = + complaint (&symfile_complaints, + "statement list doesn't fit in .debug_line section"); +} + +static void +dwarf2_complex_location_expr_complaint (void) { - "type qualifier 'volatile' ignored", 0, 0 -}; -static struct complaint dwarf2_non_const_array_bound_ignored = + complaint (&symfile_complaints, "location expression too complex"); +} + +static void +dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2, + int arg3) { - "non-constant array bounds form '%s' ignored", 0, 0 -}; -static struct complaint dwarf2_missing_line_number_section = + complaint (&symfile_complaints, + "const value length mismatch for '%s', got %d, expected %d", arg1, + arg2, arg3); +} + +static void +dwarf2_macros_too_long_complaint (void) { - "missing .debug_line section", 0, 0 -}; -static struct complaint dwarf2_mangled_line_number_section = + complaint (&symfile_complaints, + "macro info runs off end of `.debug_macinfo' section"); +} + +static void +dwarf2_macro_malformed_definition_complaint (const char *arg1) { - "mangled .debug_line section", 0, 0 -}; -static struct complaint dwarf2_unsupported_die_ref_attr = + complaint (&symfile_complaints, + "macro debug info contains a malformed macro definition:\n`%s'", + arg1); +} + +static void +dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2) { - "unsupported die ref attribute form: '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_stack_op = -{ - "unsupported stack op: '%s'", 0, 0 -}; -static struct complaint dwarf2_complex_location_expr = -{ - "location expression too complex", 0, 0 -}; -static struct complaint dwarf2_unsupported_tag = -{ - "unsupported tag: '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_at_encoding = -{ - "unsupported DW_AT_encoding: '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_at_frame_base = -{ - "unsupported DW_AT_frame_base for function '%s'", 0, 0 -}; -static struct complaint dwarf2_unexpected_tag = -{ - "unexepected tag in read_type_die: '%s'", 0, 0 -}; -static struct complaint dwarf2_missing_at_frame_base = -{ - "DW_AT_frame_base missing for DW_OP_fbreg", 0, 0 -}; -static struct complaint dwarf2_bad_static_member_name = -{ - "unrecognized static data member name '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_accessibility = -{ - "unsupported accessibility %d", 0, 0 -}; -static struct complaint dwarf2_bad_member_name_complaint = -{ - "cannot extract member name from '%s'", 0, 0 -}; -static struct complaint dwarf2_missing_member_fn_type_complaint = -{ - "member function type missing for '%s'", 0, 0 -}; -static struct complaint dwarf2_vtbl_not_found_complaint = -{ - "virtual function table pointer not found when defining class '%s'", 0, 0 -}; -static struct complaint dwarf2_absolute_sibling_complaint = -{ - "ignoring absolute DW_AT_sibling", 0, 0 -}; -static struct complaint dwarf2_const_value_length_mismatch = -{ - "const value length mismatch for '%s', got %d, expected %d", 0, 0 -}; -static struct complaint dwarf2_unsupported_const_value_attr = -{ - "unsupported const value attribute form: '%s'", 0, 0 -}; + complaint (&symfile_complaints, + "invalid attribute class or form for '%s' in '%s'", arg1, arg2); +} /* local function prototypes */ -static void dwarf2_locate_sections (bfd *, asection *, PTR); +static void dwarf2_locate_sections (bfd *, asection *, void *); #if 0 static void dwarf2_build_psymtabs_easy (struct objfile *, int); @@ -571,37 +635,60 @@ static void dwarf2_build_psymtabs_easy (struct objfile *, int); static void dwarf2_build_psymtabs_hard (struct objfile *, int); -static char *scan_partial_symbols (char *, struct objfile *, - CORE_ADDR *, CORE_ADDR *, - const struct comp_unit_head *); +static char *scan_partial_symbols (char *, CORE_ADDR *, CORE_ADDR *, + struct dwarf2_cu *, + const char *namespace); -static void add_partial_symbol (struct partial_die_info *, struct objfile *, - const struct comp_unit_head *); +static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *, + const char *namespace); + +static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace); + +static char *add_partial_namespace (struct partial_die_info *pdi, + char *info_ptr, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu, + const char *namespace); + +static char *add_partial_structure (struct partial_die_info *struct_pdi, + char *info_ptr, + struct dwarf2_cu *cu, + const char *namespace); + +static char *add_partial_enumeration (struct partial_die_info *enum_pdi, + char *info_ptr, + struct dwarf2_cu *cu, + const char *namespace); + +static char *locate_pdi_sibling (struct partial_die_info *orig_pdi, + char *info_ptr, + bfd *abfd, + struct dwarf2_cu *cu); static void dwarf2_psymtab_to_symtab (struct partial_symtab *); static void psymtab_to_symtab_1 (struct partial_symtab *); -char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int); +char *dwarf2_read_section (struct objfile *, asection *); -static void dwarf2_read_abbrevs (bfd *, unsigned int); +static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu); -static void dwarf2_empty_abbrev_table (PTR); +static void dwarf2_empty_abbrev_table (void *); -static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int); +static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int, + struct dwarf2_cu *); static char *read_partial_die (struct partial_die_info *, - bfd *, char *, - const struct comp_unit_head *); + bfd *, char *, struct dwarf2_cu *); static char *read_full_die (struct die_info **, bfd *, char *, - const struct comp_unit_head *); + struct dwarf2_cu *, int *); static char *read_attribute (struct attribute *, struct attr_abbrev *, - bfd *, char *, const struct comp_unit_head *); + bfd *, char *, struct dwarf2_cu *); static char *read_attribute_value (struct attribute *, unsigned, - bfd *, char *, const struct comp_unit_head *); + bfd *, char *, struct dwarf2_cu *); static unsigned int read_1_byte (bfd *, char *); @@ -613,7 +700,7 @@ static unsigned int read_4_bytes (bfd *, char *); static unsigned long read_8_bytes (bfd *, char *); -static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *, +static CORE_ADDR read_address (bfd *, char *ptr, struct dwarf2_cu *, int *bytes_read); static LONGEST read_initial_length (bfd *, char *, @@ -633,122 +720,148 @@ static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *); static long read_signed_leb128 (bfd *, char *, unsigned int *); -static void set_cu_language (unsigned int); +static void set_cu_language (unsigned int, struct dwarf2_cu *); -static struct attribute *dwarf_attr (struct die_info *, unsigned int); +static struct attribute *dwarf2_attr (struct die_info *, unsigned int, + struct dwarf2_cu *); -static int die_is_declaration (struct die_info *); +static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu); -static void dwarf_decode_lines (unsigned int, char *, bfd *, - const struct comp_unit_head *); +static struct die_info *die_specification (struct die_info *die, + struct dwarf2_cu *); + +static void free_line_header (struct line_header *lh); + +static struct line_header *(dwarf_decode_line_header + (unsigned int offset, + bfd *abfd, struct dwarf2_cu *cu)); + +static void dwarf_decode_lines (struct line_header *, char *, bfd *, + struct dwarf2_cu *); static void dwarf2_start_subfile (char *, char *); static struct symbol *new_symbol (struct die_info *, struct type *, - struct objfile *, const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_const_value (struct attribute *, struct symbol *, - struct objfile *, const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_const_value_data (struct attribute *attr, struct symbol *sym, int bits); -static struct type *die_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *die_type (struct die_info *, struct dwarf2_cu *); -static struct type *die_containing_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *die_containing_type (struct die_info *, + struct dwarf2_cu *); #if 0 static struct type *type_at_offset (unsigned int, struct objfile *); #endif -static struct type *tag_type_to_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *); -static void read_type_die (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_type_die (struct die_info *, struct dwarf2_cu *); -static void read_typedef (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static char *determine_prefix (struct die_info *die, struct dwarf2_cu *); -static void read_base_type (struct die_info *, struct objfile *); +static char *typename_concat (const char *prefix, const char *suffix); -static void read_file_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_typedef (struct die_info *, struct dwarf2_cu *); -static void read_func_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_base_type (struct die_info *, struct dwarf2_cu *); -static void read_lexical_block_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu); + +static void read_file_scope (struct die_info *, struct dwarf2_cu *); + +static void read_func_scope (struct die_info *, struct dwarf2_cu *); + +static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *); static int dwarf2_get_pc_bounds (struct die_info *, - CORE_ADDR *, CORE_ADDR *, struct objfile *); + CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *); + +static void get_scope_pc_bounds (struct die_info *, + CORE_ADDR *, CORE_ADDR *, + struct dwarf2_cu *); static void dwarf2_add_field (struct field_info *, struct die_info *, - struct objfile *, const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_attach_fields_to_type (struct field_info *, - struct type *, struct objfile *); + struct type *, struct dwarf2_cu *); static void dwarf2_add_member_fn (struct field_info *, struct die_info *, struct type *, - struct objfile *objfile, - const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_attach_fn_fields_to_type (struct field_info *, - struct type *, struct objfile *); + struct type *, struct dwarf2_cu *); -static void read_structure_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_structure_type (struct die_info *, struct dwarf2_cu *); -static void read_common_block (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void process_structure_scope (struct die_info *, struct dwarf2_cu *); -static void read_enumeration (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static char *determine_class_name (struct die_info *die, struct dwarf2_cu *cu); -static struct type *dwarf_base_type (int, int, struct objfile *); +static void read_common_block (struct die_info *, struct dwarf2_cu *); -static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *, - const struct comp_unit_head *); +static void read_namespace (struct die_info *die, struct dwarf2_cu *); -static void read_array_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static const char *namespace_name (struct die_info *die, + int *is_anonymous, struct dwarf2_cu *); -static void read_tag_pointer_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_enumeration_type (struct die_info *, struct dwarf2_cu *); -static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *); -static void read_tag_reference_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *dwarf_base_type (int, int, struct dwarf2_cu *); -static void read_tag_const_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *); -static void read_tag_volatile_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_array_type (struct die_info *, struct dwarf2_cu *); -static void read_tag_string_type (struct die_info *, struct objfile *); +static void read_tag_pointer_type (struct die_info *, struct dwarf2_cu *); -static void read_subroutine_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_tag_ptr_to_member_type (struct die_info *, + struct dwarf2_cu *); -static struct die_info *read_comp_unit (char *, bfd *, - const struct comp_unit_head *); +static void read_tag_reference_type (struct die_info *, struct dwarf2_cu *); + +static void read_tag_const_type (struct die_info *, struct dwarf2_cu *); + +static void read_tag_volatile_type (struct die_info *, struct dwarf2_cu *); + +static void read_tag_string_type (struct die_info *, struct dwarf2_cu *); + +static void read_subroutine_type (struct die_info *, struct dwarf2_cu *); + +static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *); + +static struct die_info *read_die_and_children (char *info_ptr, bfd *abfd, + struct dwarf2_cu *, + char **new_info_ptr, + struct die_info *parent); + +static struct die_info *read_die_and_siblings (char *info_ptr, bfd *abfd, + struct dwarf2_cu *, + char **new_info_ptr, + struct die_info *parent); static void free_die_list (struct die_info *); static struct cleanup *make_cleanup_free_die_list (struct die_info *); -static void process_die (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void process_die (struct die_info *, struct dwarf2_cu *); -static char *dwarf2_linkage_name (struct die_info *); +static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *); + +static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *); + +static struct die_info *dwarf2_extension (struct die_info *die, + struct dwarf2_cu *); static char *dwarf_tag_name (unsigned int); @@ -778,15 +891,19 @@ static void store_in_ref_table (unsigned int, struct die_info *); static void dwarf2_empty_hash_tables (void); -static unsigned int dwarf2_get_ref_die_offset (struct attribute *); +static unsigned int dwarf2_get_ref_die_offset (struct attribute *, + struct dwarf2_cu *); + +static int dwarf2_get_attr_constant_value (struct attribute *, int); static struct die_info *follow_die_ref (unsigned int); -static struct type *dwarf2_fundamental_type (struct objfile *, int); +static struct type *dwarf2_fundamental_type (struct objfile *, int, + struct dwarf2_cu *); /* memory allocation interface */ -static void dwarf2_free_tmp_obstack (PTR); +static void dwarf2_free_tmp_obstack (void *); static struct dwarf_block *dwarf_alloc_block (void); @@ -794,24 +911,38 @@ static struct abbrev_info *dwarf_alloc_abbrev (void); static struct die_info *dwarf_alloc_die (void); +static void initialize_cu_func_list (struct dwarf2_cu *); + +static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR, + struct dwarf2_cu *); + +static void dwarf_decode_macros (struct line_header *, unsigned int, + char *, bfd *, struct dwarf2_cu *); + +static int attr_form_is_block (struct attribute *); + +static void +dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, + struct dwarf2_cu *cu); + /* Try to locate the sections we need for DWARF 2 debugging information and return true if we have enough to do something. */ int dwarf2_has_info (bfd *abfd) { - dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0; - dwarf_str_offset = 0; - dwarf_frame_offset = dwarf_eh_frame_offset = 0; + dwarf_info_section = 0; + dwarf_abbrev_section = 0; + dwarf_line_section = 0; + dwarf_str_section = 0; + dwarf_macinfo_section = 0; + dwarf_frame_section = 0; + dwarf_eh_frame_section = 0; + dwarf_ranges_section = 0; + dwarf_loc_section = 0; + bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL); - if (dwarf_info_offset && dwarf_abbrev_offset) - { - return 1; - } - else - { - return 0; - } + return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL); } /* This function is mapped across the sections and remembers the @@ -819,57 +950,66 @@ dwarf2_has_info (bfd *abfd) in. */ static void -dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, PTR ignore_ptr) +dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) { - if (STREQ (sectp->name, INFO_SECTION)) + if (strcmp (sectp->name, INFO_SECTION) == 0) { - dwarf_info_offset = sectp->filepos; dwarf_info_size = bfd_get_section_size_before_reloc (sectp); + dwarf_info_section = sectp; } - else if (STREQ (sectp->name, ABBREV_SECTION)) + else if (strcmp (sectp->name, ABBREV_SECTION) == 0) { - dwarf_abbrev_offset = sectp->filepos; dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp); + dwarf_abbrev_section = sectp; } - else if (STREQ (sectp->name, LINE_SECTION)) + else if (strcmp (sectp->name, LINE_SECTION) == 0) { - dwarf_line_offset = sectp->filepos; dwarf_line_size = bfd_get_section_size_before_reloc (sectp); + dwarf_line_section = sectp; } - else if (STREQ (sectp->name, PUBNAMES_SECTION)) + else if (strcmp (sectp->name, PUBNAMES_SECTION) == 0) { - dwarf_pubnames_offset = sectp->filepos; dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp); + dwarf_pubnames_section = sectp; } - else if (STREQ (sectp->name, ARANGES_SECTION)) + else if (strcmp (sectp->name, ARANGES_SECTION) == 0) { - dwarf_aranges_offset = sectp->filepos; dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp); + dwarf_aranges_section = sectp; } - else if (STREQ (sectp->name, LOC_SECTION)) + else if (strcmp (sectp->name, LOC_SECTION) == 0) { - dwarf_loc_offset = sectp->filepos; dwarf_loc_size = bfd_get_section_size_before_reloc (sectp); + dwarf_loc_section = sectp; } - else if (STREQ (sectp->name, MACINFO_SECTION)) + else if (strcmp (sectp->name, MACINFO_SECTION) == 0) { - dwarf_macinfo_offset = sectp->filepos; dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp); + dwarf_macinfo_section = sectp; } - else if (STREQ (sectp->name, STR_SECTION)) + else if (strcmp (sectp->name, STR_SECTION) == 0) { - dwarf_str_offset = sectp->filepos; dwarf_str_size = bfd_get_section_size_before_reloc (sectp); + dwarf_str_section = sectp; } - else if (STREQ (sectp->name, FRAME_SECTION)) + else if (strcmp (sectp->name, FRAME_SECTION) == 0) { - dwarf_frame_offset = sectp->filepos; dwarf_frame_size = bfd_get_section_size_before_reloc (sectp); + dwarf_frame_section = sectp; } - else if (STREQ (sectp->name, EH_FRAME_SECTION)) + else if (strcmp (sectp->name, EH_FRAME_SECTION) == 0) { - dwarf_eh_frame_offset = sectp->filepos; - dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp); + flagword aflag = bfd_get_section_flags (ignore_abfd, sectp); + if (aflag & SEC_HAS_CONTENTS) + { + dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp); + dwarf_eh_frame_section = sectp; + } + } + else if (strcmp (sectp->name, RANGES_SECTION) == 0) + { + dwarf_ranges_size = bfd_get_section_size_before_reloc (sectp); + dwarf_ranges_section = sectp; } } @@ -881,23 +1021,35 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) /* We definitely need the .debug_info and .debug_abbrev sections */ - dwarf_info_buffer = dwarf2_read_section (objfile, - dwarf_info_offset, - dwarf_info_size); - dwarf_abbrev_buffer = dwarf2_read_section (objfile, - dwarf_abbrev_offset, - dwarf_abbrev_size); - dwarf_line_buffer = dwarf2_read_section (objfile, - dwarf_line_offset, - dwarf_line_size); + dwarf_info_buffer = dwarf2_read_section (objfile, dwarf_info_section); + dwarf_abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_section); - if (dwarf_str_offset) - dwarf_str_buffer = dwarf2_read_section (objfile, - dwarf_str_offset, - dwarf_str_size); + if (dwarf_line_section) + dwarf_line_buffer = dwarf2_read_section (objfile, dwarf_line_section); + else + dwarf_line_buffer = NULL; + + if (dwarf_str_section) + dwarf_str_buffer = dwarf2_read_section (objfile, dwarf_str_section); else dwarf_str_buffer = NULL; + if (dwarf_macinfo_section) + dwarf_macinfo_buffer = dwarf2_read_section (objfile, + dwarf_macinfo_section); + else + dwarf_macinfo_buffer = NULL; + + if (dwarf_ranges_section) + dwarf_ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_section); + else + dwarf_ranges_buffer = NULL; + + if (dwarf_loc_section) + dwarf_loc_buffer = dwarf2_read_section (objfile, dwarf_loc_section); + else + dwarf_loc_buffer = NULL; + if (mainline || (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)) @@ -935,8 +1087,7 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) unsigned int entry_length, version, info_offset, info_size; pubnames_buffer = dwarf2_read_section (objfile, - dwarf_pubnames_offset, - dwarf_pubnames_size); + dwarf_pubnames_section); pubnames_ptr = pubnames_buffer; while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size) { @@ -955,8 +1106,7 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) } aranges_buffer = dwarf2_read_section (objfile, - dwarf_aranges_offset, - dwarf_aranges_size); + dwarf_aranges_section); } #endif @@ -1002,7 +1152,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) struct partial_die_info comp_unit_die; struct partial_symtab *pst; struct cleanup *back_to; - CORE_ADDR lowpc, highpc; + CORE_ADDR lowpc, highpc, baseaddr; info_ptr = dwarf_info_buffer; abbrev_ptr = dwarf_abbrev_buffer; @@ -1053,40 +1203,51 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) left at all should be sufficient. */ while (info_ptr < dwarf_info_buffer + dwarf_info_size) { - struct comp_unit_head cu_header; + struct dwarf2_cu cu; beg_of_comp_unit = info_ptr; - info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); - if (cu_header.version != 2) + cu.objfile = objfile; + info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd); + + if (cu.header.version != 2) { - error ("Dwarf Error: wrong version in compilation unit header."); + error ("Dwarf Error: wrong version in compilation unit header (is %d, should be %d) [in module %s]", cu.header.version, 2, bfd_get_filename (abfd)); return; } - if (cu_header.abbrev_offset >= dwarf_abbrev_size) + if (cu.header.abbrev_offset >= dwarf_abbrev_size) { - error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).", - (long) cu_header.abbrev_offset, - (long) (beg_of_comp_unit - dwarf_info_buffer)); + error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6) [in module %s]", + (long) cu.header.abbrev_offset, + (long) (beg_of_comp_unit - dwarf_info_buffer), + bfd_get_filename (abfd)); return; } - if (beg_of_comp_unit + cu_header.length + cu_header.initial_length_size + if (beg_of_comp_unit + cu.header.length + cu.header.initial_length_size > dwarf_info_buffer + dwarf_info_size) { - error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).", - (long) cu_header.length, - (long) (beg_of_comp_unit - dwarf_info_buffer)); + error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0) [in module %s]", + (long) cu.header.length, + (long) (beg_of_comp_unit - dwarf_info_buffer), + bfd_get_filename (abfd)); return; } + /* Complete the cu_header */ + cu.header.offset = beg_of_comp_unit - dwarf_info_buffer; + cu.header.first_die_ptr = info_ptr; + cu.header.cu_head_ptr = beg_of_comp_unit; + + cu.list_in_scope = &file_symbols; + /* Read the abbrevs for this compilation unit into a table */ - dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset); - make_cleanup (dwarf2_empty_abbrev_table, NULL); + dwarf2_read_abbrevs (abfd, &cu); + make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs); /* Read the compilation unit die */ info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr, - &cu_header); + &cu); /* Set the language we're debugging */ - set_cu_language (comp_unit_die.language); + set_cu_language (comp_unit_die.language, &cu); /* Allocate a new partial symbol table structure */ pst = start_psymtab_common (objfile, objfile->section_offsets, @@ -1096,15 +1257,21 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) objfile->static_psymbols.next); pst->read_symtab_private = (char *) - obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo)); - cu_header_offset = beg_of_comp_unit - dwarf_info_buffer; + obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo)); DWARF_INFO_BUFFER (pst) = dwarf_info_buffer; DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer; DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer; DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size; DWARF_LINE_BUFFER (pst) = dwarf_line_buffer; + DWARF_LINE_SIZE (pst) = dwarf_line_size; DWARF_STR_BUFFER (pst) = dwarf_str_buffer; DWARF_STR_SIZE (pst) = dwarf_str_size; + DWARF_MACINFO_BUFFER (pst) = dwarf_macinfo_buffer; + DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size; + DWARF_RANGES_BUFFER (pst) = dwarf_ranges_buffer; + DWARF_RANGES_SIZE (pst) = dwarf_ranges_size; + DWARF_LOC_BUFFER (pst) = dwarf_loc_buffer; + DWARF_LOC_SIZE (pst) = dwarf_loc_size; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Store the function that reads in the rest of the symbol table */ @@ -1115,9 +1282,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) If not, there's no more debug_info for this comp unit. */ if (comp_unit_die.has_children) { - info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc, - &cu_header); + lowpc = ((CORE_ADDR) -1); + highpc = ((CORE_ADDR) 0); + info_ptr = scan_partial_symbols (info_ptr, &lowpc, &highpc, + &cu, NULL); + + /* If we didn't find a lowpc, set it to highpc to avoid + complaints from `maint check'. */ + if (lowpc == ((CORE_ADDR) -1)) + lowpc = highpc; + /* If the compilation unit didn't have an explicit address range, then use the information extracted from its child dies. */ if (! comp_unit_die.has_pc_info) @@ -1140,38 +1315,46 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) also happen.) This happens in VxWorks. */ free_named_symtabs (pst->filename); - info_ptr = beg_of_comp_unit + cu_header.length - + cu_header.initial_length_size; + info_ptr = beg_of_comp_unit + cu.header.length + + cu.header.initial_length_size; } do_cleanups (back_to); } -/* Read in all interesting dies to the end of the compilation unit. */ +/* Read in all interesting dies to the end of the compilation unit or + to the end of the current namespace. NAMESPACE is NULL if we + haven't yet encountered any DW_TAG_namespace entries; otherwise, + it's the name of the current namespace. In particular, it's the + empty string if we're currently in the global namespace but have + previously encountered a DW_TAG_namespace. */ static char * -scan_partial_symbols (char *info_ptr, struct objfile *objfile, - CORE_ADDR *lowpc, CORE_ADDR *highpc, - const struct comp_unit_head *cu_header) +scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc, + CORE_ADDR *highpc, struct dwarf2_cu *cu, + const char *namespace) { + struct objfile *objfile = cu->objfile; bfd *abfd = objfile->obfd; struct partial_die_info pdi; - /* This function is called after we've read in the comp_unit_die in - order to read its children. We start the nesting level at 1 since - we have pushed 1 level down in order to read the comp unit's children. - The comp unit itself is at level 0, so we stop reading when we pop - back to that level. */ + /* Now, march along the PDI's, descending into ones which have + interesting children but skipping the children of the other ones, + until we reach the end of the compilation unit. */ - int nesting_level = 1; - - *lowpc = ((CORE_ADDR) -1); - *highpc = ((CORE_ADDR) 0); - - while (nesting_level) + while (1) { - info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + /* This flag tells whether or not info_ptr has gotten updated + inside the loop. */ + int info_ptr_updated = 0; - if (pdi.name) + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu); + + /* Anonymous namespaces have no name but have interesting + children, so we need to look at them. Ditto for anonymous + enums. */ + + if (pdi.name != NULL || pdi.tag == DW_TAG_namespace + || pdi.tag == DW_TAG_enumeration_type) { switch (pdi.tag) { @@ -1186,95 +1369,121 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, { *highpc = pdi.highpc; } - if ((pdi.is_external || nesting_level == 1) - && !pdi.is_declaration) + if (!pdi.is_declaration) { - add_partial_symbol (&pdi, objfile, cu_header); + add_partial_symbol (&pdi, cu, namespace); } } break; case DW_TAG_variable: case DW_TAG_typedef: - case DW_TAG_class_type: - case DW_TAG_structure_type: case DW_TAG_union_type: - case DW_TAG_enumeration_type: - if ((pdi.is_external || nesting_level == 1) - && !pdi.is_declaration) + if (!pdi.is_declaration) { - add_partial_symbol (&pdi, objfile, cu_header); + add_partial_symbol (&pdi, cu, namespace); } break; - case DW_TAG_enumerator: - /* File scope enumerators are added to the partial symbol - table. */ - if (nesting_level == 2) - add_partial_symbol (&pdi, objfile, cu_header); + case DW_TAG_class_type: + case DW_TAG_structure_type: + if (!pdi.is_declaration) + { + info_ptr = add_partial_structure (&pdi, info_ptr, cu, + namespace); + info_ptr_updated = 1; + } + break; + case DW_TAG_enumeration_type: + if (!pdi.is_declaration) + { + info_ptr = add_partial_enumeration (&pdi, info_ptr, cu, + namespace); + info_ptr_updated = 1; + } break; case DW_TAG_base_type: + case DW_TAG_subrange_type: /* File scope base type definitions are added to the partial symbol table. */ - if (nesting_level == 1) - add_partial_symbol (&pdi, objfile, cu_header); + add_partial_symbol (&pdi, cu, namespace); + break; + case DW_TAG_namespace: + /* We've hit a DW_TAG_namespace entry, so we know this + file has been compiled using a compiler that + generates them; update NAMESPACE to reflect that. */ + if (namespace == NULL) + namespace = ""; + info_ptr = add_partial_namespace (&pdi, info_ptr, lowpc, highpc, + cu, namespace); + info_ptr_updated = 1; break; default: break; } } - /* If the die has a sibling, skip to the sibling. - Do not skip enumeration types, we want to record their - enumerators. */ - if (pdi.sibling && pdi.tag != DW_TAG_enumeration_type) - { - info_ptr = pdi.sibling; - } - else if (pdi.has_children) - { - /* Die has children, but the optional DW_AT_sibling attribute - is missing. */ - nesting_level++; - } - if (pdi.tag == 0) - { - nesting_level--; - } + break; + + /* If the die has a sibling, skip to the sibling, unless another + function has already updated info_ptr for us. */ + + /* NOTE: carlton/2003-06-16: This is a bit hackish, but whether + or not we want to update this depends on enough stuff (not + only pdi.tag but also whether or not pdi.name is NULL) that + this seems like the easiest way to handle the issue. */ + + if (!info_ptr_updated) + info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu); } - /* If we didn't find a lowpc, set it to highpc to avoid complaints - from `maint check'. */ - if (*lowpc == ((CORE_ADDR) -1)) - *lowpc = *highpc; return info_ptr; } static void -add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, - const struct comp_unit_head *cu_header) +add_partial_symbol (struct partial_die_info *pdi, + struct dwarf2_cu *cu, const char *namespace) { + struct objfile *objfile = cu->objfile; CORE_ADDR addr = 0; + char *actual_name = pdi->name; + const struct partial_symbol *psym = NULL; + CORE_ADDR baseaddr; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + /* If we're not in the global namespace and if the namespace name + isn't encoded in a mangled actual_name, add it. */ + + if (pdi_needs_namespace (pdi->tag, namespace)) + { + actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1); + strcpy (actual_name, namespace); + strcat (actual_name, "::"); + strcat (actual_name, pdi->name); + } switch (pdi->tag) { case DW_TAG_subprogram: if (pdi->is_external) { - /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, + /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, mst_text, objfile); */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->global_psymbols, - 0, pdi->lowpc + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_BLOCK, + &objfile->global_psymbols, + 0, pdi->lowpc + baseaddr, + cu->language, objfile); } else { - /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, + /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, mst_file_text, objfile); */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->static_psymbols, - 0, pdi->lowpc + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_BLOCK, + &objfile->static_psymbols, + 0, pdi->lowpc + baseaddr, + cu->language, objfile); } break; case DW_TAG_variable: @@ -1294,33 +1503,36 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, table building. */ if (pdi->locdesc) - addr = decode_locdesc (pdi->locdesc, objfile, cu_header); + addr = decode_locdesc (pdi->locdesc, cu); if (pdi->locdesc || pdi->has_type) - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_STATIC, - &objfile->global_psymbols, - 0, addr + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_STATIC, + &objfile->global_psymbols, + 0, addr + baseaddr, + cu->language, objfile); } else { /* Static Variable. Skip symbols without location descriptors. */ if (pdi->locdesc == NULL) return; - addr = decode_locdesc (pdi->locdesc, objfile, cu_header); - /*prim_record_minimal_symbol (pdi->name, addr + baseaddr, + addr = decode_locdesc (pdi->locdesc, cu); + /*prim_record_minimal_symbol (actual_name, addr + baseaddr, mst_file_data, objfile); */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_STATIC, - &objfile->static_psymbols, - 0, addr + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_STATIC, + &objfile->static_psymbols, + 0, addr + baseaddr, + cu->language, objfile); } break; case DW_TAG_typedef: case DW_TAG_base_type: - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_TYPEDEF, + case DW_TAG_subrange_type: + add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + 0, (CORE_ADDR) 0, cu->language, objfile); break; case DW_TAG_class_type: case DW_TAG_structure_type: @@ -1328,31 +1540,248 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, case DW_TAG_enumeration_type: /* Skip aggregate types without children, these are external references. */ + /* NOTE: carlton/2003-10-07: See comment in new_symbol about + static vs. global. */ if (pdi->has_children == 0) return; - add_psymbol_to_list (pdi->name, strlen (pdi->name), - STRUCT_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + add_psymbol_to_list (actual_name, strlen (actual_name), + STRUCT_DOMAIN, LOC_TYPEDEF, + cu->language == language_cplus + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); - if (cu_language == language_cplus) + if (cu->language == language_cplus) { /* For C++, these implicitly act as typedefs as well. */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->global_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); } break; case DW_TAG_enumerator: - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_CONST, + cu->language == language_cplus + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); break; default: break; } + + /* Check to see if we should scan the name for possible namespace + info. Only do this if this is C++, if we don't have namespace + debugging info in the file, if the psym is of an appropriate type + (otherwise we'll have psym == NULL), and if we actually had a + mangled name to begin with. */ + + if (cu->language == language_cplus + && namespace == NULL + && psym != NULL + && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL) + cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym), + objfile); +} + +/* Determine whether a die of type TAG living in the C++ namespace + NAMESPACE needs to have the name of the namespace prepended to the + name listed in the die. */ + +static int +pdi_needs_namespace (enum dwarf_tag tag, const char *namespace) +{ + if (namespace == NULL || namespace[0] == '\0') + return 0; + + switch (tag) + { + case DW_TAG_typedef: + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_enumerator: + return 1; + default: + return 0; + } +} + +/* Read a partial die corresponding to a namespace; also, add a symbol + corresponding to that namespace to the symbol table. NAMESPACE is + the name of the enclosing namespace. */ + +static char * +add_partial_namespace (struct partial_die_info *pdi, char *info_ptr, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu, const char *namespace) +{ + struct objfile *objfile = cu->objfile; + const char *new_name = pdi->name; + char *full_name; + + /* Calculate the full name of the namespace that we just entered. */ + + if (new_name == NULL) + new_name = "(anonymous namespace)"; + full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1); + strcpy (full_name, namespace); + if (*namespace != '\0') + strcat (full_name, "::"); + strcat (full_name, new_name); + + /* FIXME: carlton/2003-10-07: We can't just replace this by a call + to add_partial_symbol, because we don't have a way to pass in the + full name to that function; that might be a flaw in + add_partial_symbol's interface. */ + + add_psymbol_to_list (full_name, strlen (full_name), + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->global_psymbols, + 0, 0, cu->language, objfile); + + /* Now scan partial symbols in that namespace. */ + + if (pdi->has_children) + info_ptr = scan_partial_symbols (info_ptr, lowpc, highpc, cu, full_name); + + return info_ptr; +} + +/* Read a partial die corresponding to a class or structure. */ + +static char * +add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr, + struct dwarf2_cu *cu, + const char *namespace) +{ + bfd *abfd = cu->objfile->obfd; + char *actual_class_name = NULL; + + if (cu->language == language_cplus + && (namespace == NULL || namespace[0] == '\0') + && struct_pdi->name != NULL + && struct_pdi->has_children) + { + /* See if we can figure out if the class lives in a namespace + (or is nested within another class.) We do this by looking + for a member function; its demangled name will contain + namespace info, if there is any. */ + + /* NOTE: carlton/2003-10-07: Getting the info this way changes + what template types look like, because the demangler + frequently doesn't give the same name as the debug info. We + could fix this by only using the demangled name to get the + prefix (but see comment in read_structure_type). */ + + /* FIXME: carlton/2004-01-23: If NAMESPACE equals "", we have + the appropriate debug information, so it would be nice to be + able to avoid this hack. But NAMESPACE may not be the + namespace where this class was defined: NAMESPACE reflects + where STRUCT_PDI occurs in the tree of dies, but because of + DW_AT_specification, that may not actually tell us where the + class is defined. (See the comment in read_func_scope for an + example of how this could occur.) + + Unfortunately, our current partial symtab data structures are + completely unable to deal with DW_AT_specification. So, for + now, the best thing to do is to get nesting information from + places other than the tree structure of dies if there's any + chance that a DW_AT_specification is involved. :-( */ + + char *next_child = info_ptr; + + while (1) + { + struct partial_die_info child_pdi; + + next_child = read_partial_die (&child_pdi, abfd, next_child, + cu); + if (!child_pdi.tag) + break; + if (child_pdi.tag == DW_TAG_subprogram) + { + actual_class_name = class_name_from_physname (child_pdi.name); + if (actual_class_name != NULL) + struct_pdi->name = actual_class_name; + break; + } + else + { + next_child = locate_pdi_sibling (&child_pdi, next_child, + abfd, cu); + } + } + } + + add_partial_symbol (struct_pdi, cu, namespace); + xfree (actual_class_name); + + return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu); +} + +/* Read a partial die corresponding to an enumeration type. */ + +static char * +add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr, + struct dwarf2_cu *cu, const char *namespace) +{ + struct objfile *objfile = cu->objfile; + bfd *abfd = objfile->obfd; + struct partial_die_info pdi; + + if (enum_pdi->name != NULL) + add_partial_symbol (enum_pdi, cu, namespace); + + while (1) + { + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu); + if (pdi.tag == 0) + break; + if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL) + complaint (&symfile_complaints, "malformed enumerator DIE ignored"); + else + add_partial_symbol (&pdi, cu, namespace); + } + + return info_ptr; +} + +/* Locate ORIG_PDI's sibling; INFO_PTR should point to the next DIE + after ORIG_PDI. */ + +static char * +locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr, + bfd *abfd, struct dwarf2_cu *cu) +{ + /* Do we know the sibling already? */ + + if (orig_pdi->sibling) + return orig_pdi->sibling; + + /* Are there any children to deal with? */ + + if (!orig_pdi->has_children) + return info_ptr; + + /* Okay, we don't know the sibling, but we have children that we + want to skip. So read children until we run into one without a + tag; return whatever follows it. */ + + while (1) + { + struct partial_die_info pdi; + + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu); + + if (pdi.tag == 0) + return info_ptr; + else + info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu); + } } /* Expand this partial symbol table into a full symbol table. */ @@ -1389,7 +1818,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) { struct objfile *objfile = pst->objfile; bfd *abfd = objfile->obfd; - struct comp_unit_head cu_header; + struct dwarf2_cu cu; struct die_info *dies; unsigned long offset; CORE_ADDR lowpc, highpc; @@ -1397,6 +1826,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) char *info_ptr; struct symtab *symtab; struct cleanup *back_to; + struct attribute *attr; + CORE_ADDR baseaddr; /* Set local variables from the partial symbol table info. */ offset = DWARF_INFO_OFFSET (pst); @@ -1404,11 +1835,20 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst); dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst); dwarf_line_buffer = DWARF_LINE_BUFFER (pst); + dwarf_line_size = DWARF_LINE_SIZE (pst); dwarf_str_buffer = DWARF_STR_BUFFER (pst); dwarf_str_size = DWARF_STR_SIZE (pst); - baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); - cu_header_offset = offset; + dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst); + dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst); + dwarf_ranges_buffer = DWARF_RANGES_BUFFER (pst); + dwarf_ranges_size = DWARF_RANGES_SIZE (pst); + dwarf_loc_buffer = DWARF_LOC_BUFFER (pst); + dwarf_loc_size = DWARF_LOC_SIZE (pst); info_ptr = dwarf_info_buffer + offset; + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + /* We're in the global namespace. */ + processing_current_prefix = ""; obstack_init (&dwarf2_tmp_obstack); back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL); @@ -1416,57 +1856,68 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) buildsym_init (); make_cleanup (really_free_pendings, NULL); + cu.objfile = objfile; + /* read in the comp_unit header */ - info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); + info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd); /* Read the abbrevs for this compilation unit */ - dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset); - make_cleanup (dwarf2_empty_abbrev_table, NULL); + dwarf2_read_abbrevs (abfd, &cu); + make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs); - dies = read_comp_unit (info_ptr, abfd, &cu_header); + cu.header.offset = offset; + + cu.list_in_scope = &file_symbols; + + dies = read_comp_unit (info_ptr, abfd, &cu); make_cleanup_free_die_list (dies); - /* Do line number decoding in read_file_scope () */ - process_die (dies, objfile, &cu_header); + /* Find the base address of the compilation unit for range lists and + location lists. It will normally be specified by DW_AT_low_pc. + In DWARF-3 draft 4, the base address could be overridden by + DW_AT_entry_pc. It's been removed, but GCC still uses this for + compilation units with discontinuous ranges. */ - if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile)) + cu.header.base_known = 0; + cu.header.base_address = 0; + + attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu); + if (attr) { - /* Some compilers don't define a DW_AT_high_pc attribute for - the compilation unit. If the DW_AT_high_pc is missing, - synthesize it, by scanning the DIE's below the compilation unit. */ - highpc = 0; - if (dies->has_children) + cu.header.base_address = DW_ADDR (attr); + cu.header.base_known = 1; + } + else + { + attr = dwarf2_attr (dies, DW_AT_low_pc, &cu); + if (attr) { - child_die = dies->next; - while (child_die && child_die->tag) - { - if (child_die->tag == DW_TAG_subprogram) - { - CORE_ADDR low, high; - - if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile)) - { - highpc = max (highpc, high); - } - } - child_die = sibling_die (child_die); - } + cu.header.base_address = DW_ADDR (attr); + cu.header.base_known = 1; } } + + /* Do line number decoding in read_file_scope () */ + process_die (dies, &cu); + + /* Some compilers don't define a DW_AT_high_pc attribute for the + compilation unit. If the DW_AT_high_pc is missing, synthesize + it, by scanning the DIE's below the compilation unit. */ + get_scope_pc_bounds (dies, &lowpc, &highpc, &cu); + symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); /* Set symtab language to language from DW_AT_language. If the compilation is from a C file generated by language preprocessors, do not set the language if it was already deduced by start_subfile. */ if (symtab != NULL - && !(cu_language == language_c && symtab->language != language_c)) + && !(cu.language == language_c && symtab->language != language_c)) { - symtab->language = cu_language; + symtab->language = cu.language; } pst->symtab = symtab; pst->readin = 1; - sort_symtab_syms (pst->symtab); do_cleanups (back_to); } @@ -1474,19 +1925,18 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) /* Process a die and its children. */ static void -process_die (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +process_die (struct die_info *die, struct dwarf2_cu *cu) { switch (die->tag) { case DW_TAG_padding: break; case DW_TAG_compile_unit: - read_file_scope (die, objfile, cu_header); + read_file_scope (die, cu); break; case DW_TAG_subprogram: - read_subroutine_type (die, objfile, cu_header); - read_func_scope (die, objfile, cu_header); + read_subroutine_type (die, cu); + read_func_scope (die, cu); break; case DW_TAG_inlined_subroutine: /* FIXME: These are ignored for now. @@ -1494,58 +1944,94 @@ process_die (struct die_info *die, struct objfile *objfile, of a function and make GDB `next' properly over inlined functions. */ break; case DW_TAG_lexical_block: - read_lexical_block_scope (die, objfile, cu_header); + case DW_TAG_try_block: + case DW_TAG_catch_block: + read_lexical_block_scope (die, cu); break; case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: - read_structure_scope (die, objfile, cu_header); + read_structure_type (die, cu); + process_structure_scope (die, cu); break; case DW_TAG_enumeration_type: - read_enumeration (die, objfile, cu_header); + read_enumeration_type (die, cu); + process_enumeration_scope (die, cu); break; + + /* FIXME drow/2004-03-14: These initialize die->type, but do not create + a symbol or process any children. Therefore it doesn't do anything + that won't be done on-demand by read_type_die. */ case DW_TAG_subroutine_type: - read_subroutine_type (die, objfile, cu_header); + read_subroutine_type (die, cu); break; case DW_TAG_array_type: - read_array_type (die, objfile, cu_header); + read_array_type (die, cu); break; case DW_TAG_pointer_type: - read_tag_pointer_type (die, objfile, cu_header); + read_tag_pointer_type (die, cu); break; case DW_TAG_ptr_to_member_type: - read_tag_ptr_to_member_type (die, objfile, cu_header); + read_tag_ptr_to_member_type (die, cu); break; case DW_TAG_reference_type: - read_tag_reference_type (die, objfile, cu_header); + read_tag_reference_type (die, cu); break; case DW_TAG_string_type: - read_tag_string_type (die, objfile); + read_tag_string_type (die, cu); break; + /* END FIXME */ + case DW_TAG_base_type: - read_base_type (die, objfile); - if (dwarf_attr (die, DW_AT_name)) - { - /* Add a typedef symbol for the base type definition. */ - new_symbol (die, die->type, objfile, cu_header); - } + read_base_type (die, cu); + /* Add a typedef symbol for the type definition, if it has a + DW_AT_name. */ + new_symbol (die, die->type, cu); + break; + case DW_TAG_subrange_type: + read_subrange_type (die, cu); + /* Add a typedef symbol for the type definition, if it has a + DW_AT_name. */ + new_symbol (die, die->type, cu); break; case DW_TAG_common_block: - read_common_block (die, objfile, cu_header); + read_common_block (die, cu); break; case DW_TAG_common_inclusion: break; + case DW_TAG_namespace: + processing_has_namespace_info = 1; + read_namespace (die, cu); + break; + case DW_TAG_imported_declaration: + case DW_TAG_imported_module: + /* FIXME: carlton/2002-10-16: Eventually, we should use the + information contained in these. DW_TAG_imported_declaration + dies shouldn't have children; DW_TAG_imported_module dies + shouldn't in the C++ case, but conceivably could in the + Fortran case, so we'll have to replace this gdb_assert if + Fortran compilers start generating that info. */ + processing_has_namespace_info = 1; + gdb_assert (die->child == NULL); + break; default: - new_symbol (die, NULL, objfile, cu_header); + new_symbol (die, NULL, cu); break; } } static void -read_file_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +initialize_cu_func_list (struct dwarf2_cu *cu) { - unsigned int line_offset = 0; + cu->first_fn = cu->last_fn = cu->cached_fn = NULL; +} + +static void +read_file_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; + struct cleanup *back_to = make_cleanup (null_cleanup, 0); CORE_ADDR lowpc = ((CORE_ADDR) -1); CORE_ADDR highpc = ((CORE_ADDR) 0); struct attribute *attr; @@ -1553,28 +2039,12 @@ read_file_scope (struct die_info *die, struct objfile *objfile, char *comp_dir = NULL; struct die_info *child_die; bfd *abfd = objfile->obfd; + struct line_header *line_header = 0; + CORE_ADDR baseaddr; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile)) - { - if (die->has_children) - { - child_die = die->next; - while (child_die && child_die->tag) - { - if (child_die->tag == DW_TAG_subprogram) - { - CORE_ADDR low, high; - - if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile)) - { - lowpc = min (lowpc, low); - highpc = max (highpc, high); - } - } - child_die = sibling_die (child_die); - } - } - } + get_scope_pc_bounds (die, &lowpc, &highpc, cu); /* If we didn't find a lowpc, set it to highpc to avoid complaints from finish_block. */ @@ -1583,12 +2053,12 @@ read_file_scope (struct die_info *die, struct objfile *objfile, lowpc += baseaddr; highpc += baseaddr; - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr) { name = DW_STRING (attr); } - attr = dwarf_attr (die, DW_AT_comp_dir); + attr = dwarf2_attr (die, DW_AT_comp_dir, cu); if (attr) { comp_dir = DW_STRING (attr); @@ -1606,14 +2076,14 @@ read_file_scope (struct die_info *die, struct objfile *objfile, if (objfile->ei.entry_point >= lowpc && objfile->ei.entry_point < highpc) { - objfile->ei.entry_file_lowpc = lowpc; - objfile->ei.entry_file_highpc = highpc; + objfile->ei.deprecated_entry_file_lowpc = lowpc; + objfile->ei.deprecated_entry_file_highpc = highpc; } - attr = dwarf_attr (die, DW_AT_language); + attr = dwarf2_attr (die, DW_AT_language, cu); if (attr) { - set_cu_language (DW_UNSND (attr)); + set_cu_language (DW_UNSND (attr), cu); } /* We assume that we're processing GCC output. */ @@ -1628,52 +2098,137 @@ read_file_scope (struct die_info *die, struct objfile *objfile, /* The compilation unit may be in a different language or objfile, zero out all remembered fundamental types. */ - memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *)); + memset (cu->ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *)); start_symtab (name, comp_dir, lowpc); record_debugformat ("DWARF 2"); - /* Decode line number information if present. */ - attr = dwarf_attr (die, DW_AT_stmt_list); - if (attr) - { - line_offset = DW_UNSND (attr); - dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header); - } + initialize_cu_func_list (cu); /* Process all dies in compilation unit. */ - if (die->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); child_die = sibling_die (child_die); } } + + /* Decode line number information if present. */ + attr = dwarf2_attr (die, DW_AT_stmt_list, cu); + if (attr) + { + unsigned int line_offset = DW_UNSND (attr); + line_header = dwarf_decode_line_header (line_offset, abfd, cu); + if (line_header) + { + make_cleanup ((make_cleanup_ftype *) free_line_header, + (void *) line_header); + dwarf_decode_lines (line_header, comp_dir, abfd, cu); + } + } + + /* Decode macro information, if present. Dwarf 2 macro information + refers to information in the line number info statement program + header, so we can only read it if we've read the header + successfully. */ + attr = dwarf2_attr (die, DW_AT_macro_info, cu); + if (attr && line_header) + { + unsigned int macro_offset = DW_UNSND (attr); + dwarf_decode_macros (line_header, macro_offset, + comp_dir, abfd, cu); + } + do_cleanups (back_to); } static void -read_func_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc, + struct dwarf2_cu *cu) { - register struct context_stack *new; + struct function_range *thisfn; + + thisfn = (struct function_range *) + obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range)); + thisfn->name = name; + thisfn->lowpc = lowpc; + thisfn->highpc = highpc; + thisfn->seen_line = 0; + thisfn->next = NULL; + + if (cu->last_fn == NULL) + cu->first_fn = thisfn; + else + cu->last_fn->next = thisfn; + + cu->last_fn = thisfn; +} + +static void +read_func_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct context_stack *new; CORE_ADDR lowpc; CORE_ADDR highpc; struct die_info *child_die; struct attribute *attr; char *name; + const char *previous_prefix = processing_current_prefix; + struct cleanup *back_to = NULL; + CORE_ADDR baseaddr; - name = dwarf2_linkage_name (die); + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + name = dwarf2_linkage_name (die, cu); /* Ignore functions with missing or empty names and functions with missing or invalid low and high pc attributes. */ - if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile)) + if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) return; + if (cu->language == language_cplus) + { + struct die_info *spec_die = die_specification (die, cu); + + /* NOTE: carlton/2004-01-23: We have to be careful in the + presence of DW_AT_specification. For example, with GCC 3.4, + given the code + + namespace N { + void foo() { + // Definition of N::foo. + } + } + + then we'll have a tree of DIEs like this: + + 1: DW_TAG_compile_unit + 2: DW_TAG_namespace // N + 3: DW_TAG_subprogram // declaration of N::foo + 4: DW_TAG_subprogram // definition of N::foo + DW_AT_specification // refers to die #3 + + Thus, when processing die #4, we have to pretend that we're + in the context of its DW_AT_specification, namely the contex + of die #3. */ + + if (spec_die != NULL) + { + char *specification_prefix = determine_prefix (spec_die, cu); + processing_current_prefix = specification_prefix; + back_to = make_cleanup (xfree, specification_prefix); + } + } + lowpc += baseaddr; highpc += baseaddr; + /* Record the function range for dwarf_decode_lines. */ + add_to_cu_func_list (name, lowpc, highpc, cu); + if (objfile->ei.entry_point >= lowpc && objfile->ei.entry_point < highpc) { @@ -1681,37 +2236,32 @@ read_func_scope (struct die_info *die, struct objfile *objfile, objfile->ei.entry_func_highpc = highpc; } - /* Decode DW_AT_frame_base location descriptor if present, keep result - for DW_OP_fbreg operands in decode_locdesc. */ - frame_base_reg = -1; - frame_base_offset = 0; - attr = dwarf_attr (die, DW_AT_frame_base); - if (attr) - { - CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - if (isderef) - complain (&dwarf2_unsupported_at_frame_base, name); - else if (isreg) - frame_base_reg = addr; - else if (offreg) - { - frame_base_reg = basereg; - frame_base_offset = addr; - } - else - complain (&dwarf2_unsupported_at_frame_base, name); - } - new = push_context (0, lowpc); - new->name = new_symbol (die, die->type, objfile, cu_header); - list_in_scope = &local_symbols; + new->name = new_symbol (die, die->type, cu); - if (die->has_children) + /* If there is a location expression for DW_AT_frame_base, record + it. */ + attr = dwarf2_attr (die, DW_AT_frame_base, cu); + if (attr) + /* FIXME: cagney/2004-01-26: The DW_AT_frame_base's location + expression is being recorded directly in the function's symbol + and not in a separate frame-base object. I guess this hack is + to avoid adding some sort of frame-base adjunct/annex to the + function's symbol :-(. The problem with doing this is that it + results in a function symbol with a location expression that + has nothing to do with the location of the function, ouch! The + relationship should be: a function's symbol has-a frame base; a + frame-base has-a location expression. */ + dwarf2_symbol_mark_computed (attr, new->name, cu); + + cu->list_in_scope = &local_symbols; + + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); child_die = sibling_die (child_die); } } @@ -1720,33 +2270,55 @@ read_func_scope (struct die_info *die, struct objfile *objfile, /* Make a block for the local symbols within. */ finish_block (new->name, &local_symbols, new->old_blocks, lowpc, highpc, objfile); - list_in_scope = &file_symbols; + + /* In C++, we can have functions nested inside functions (e.g., when + a function declares a class that has methods). This means that + when we finish processing a function scope, we may need to go + back to building a containing block's symbol lists. */ + local_symbols = new->locals; + param_symbols = new->params; + + /* If we've finished processing a top-level function, subsequent + symbols go in the file symbol list. */ + if (outermost_context_p ()) + cu->list_in_scope = &file_symbols; + + processing_current_prefix = previous_prefix; + if (back_to != NULL) + do_cleanups (back_to); } /* Process all the DIES contained within a lexical block scope. Start a new scope, process the dies, and then close the scope. */ static void -read_lexical_block_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) { - register struct context_stack *new; + struct objfile *objfile = cu->objfile; + struct context_stack *new; CORE_ADDR lowpc, highpc; struct die_info *child_die; + CORE_ADDR baseaddr; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Ignore blocks with missing or invalid low and high pc attributes. */ - if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile)) + /* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges + as multiple lexical blocks? Handling children in a sane way would + be nasty. Might be easier to properly extend generic blocks to + describe ranges. */ + if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) return; lowpc += baseaddr; highpc += baseaddr; push_context (0, lowpc); - if (die->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); child_die = sibling_die (child_die); } } @@ -1760,27 +2332,145 @@ read_lexical_block_scope (struct die_info *die, struct objfile *objfile, local_symbols = new->locals; } -/* Get low and high pc attributes from a die. - Return 1 if the attributes are present and valid, otherwise, return 0. */ - +/* Get low and high pc attributes from a die. Return 1 if the attributes + are present and valid, otherwise, return 0. Return -1 if the range is + discontinuous, i.e. derived from DW_AT_ranges information. */ static int -dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc, - struct objfile *objfile) +dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, + CORE_ADDR *highpc, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; struct attribute *attr; - CORE_ADDR low; - CORE_ADDR high; + bfd *obfd = objfile->obfd; + CORE_ADDR low = 0; + CORE_ADDR high = 0; + int ret = 0; - attr = dwarf_attr (die, DW_AT_low_pc); + attr = dwarf2_attr (die, DW_AT_high_pc, cu); if (attr) - low = DW_ADDR (attr); + { + high = DW_ADDR (attr); + attr = dwarf2_attr (die, DW_AT_low_pc, cu); + if (attr) + low = DW_ADDR (attr); + else + /* Found high w/o low attribute. */ + return 0; + + /* Found consecutive range of addresses. */ + ret = 1; + } else - return 0; - attr = dwarf_attr (die, DW_AT_high_pc); - if (attr) - high = DW_ADDR (attr); - else - return 0; + { + attr = dwarf2_attr (die, DW_AT_ranges, cu); + if (attr != NULL) + { + unsigned int addr_size = cu_header->addr_size; + CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); + /* Value of the DW_AT_ranges attribute is the offset in the + .debug_ranges section. */ + unsigned int offset = DW_UNSND (attr); + /* Base address selection entry. */ + CORE_ADDR base; + int found_base; + int dummy; + char *buffer; + CORE_ADDR marker; + int low_set; + + found_base = cu_header->base_known; + base = cu_header->base_address; + + if (offset >= dwarf_ranges_size) + { + complaint (&symfile_complaints, + "Offset %d out of bounds for DW_AT_ranges attribute", + offset); + return 0; + } + buffer = dwarf_ranges_buffer + offset; + + /* Read in the largest possible address. */ + marker = read_address (obfd, buffer, cu, &dummy); + if ((marker & mask) == mask) + { + /* If we found the largest possible address, then + read the base address. */ + base = read_address (obfd, buffer + addr_size, cu, &dummy); + buffer += 2 * addr_size; + offset += 2 * addr_size; + found_base = 1; + } + + low_set = 0; + + while (1) + { + CORE_ADDR range_beginning, range_end; + + range_beginning = read_address (obfd, buffer, cu, &dummy); + buffer += addr_size; + range_end = read_address (obfd, buffer, cu, &dummy); + buffer += addr_size; + offset += 2 * addr_size; + + /* An end of list marker is a pair of zero addresses. */ + if (range_beginning == 0 && range_end == 0) + /* Found the end of list entry. */ + break; + + /* Each base address selection entry is a pair of 2 values. + The first is the largest possible address, the second is + the base address. Check for a base address here. */ + if ((range_beginning & mask) == mask) + { + /* If we found the largest possible address, then + read the base address. */ + base = read_address (obfd, buffer + addr_size, cu, &dummy); + found_base = 1; + continue; + } + + if (!found_base) + { + /* We have no valid base address for the ranges + data. */ + complaint (&symfile_complaints, + "Invalid .debug_ranges data (no base address)"); + return 0; + } + + range_beginning += base; + range_end += base; + + /* FIXME: This is recording everything as a low-high + segment of consecutive addresses. We should have a + data structure for discontiguous block ranges + instead. */ + if (! low_set) + { + low = range_beginning; + high = range_end; + low_set = 1; + } + else + { + if (range_beginning < low) + low = range_beginning; + if (range_end > high) + high = range_end; + } + } + + if (! low_set) + /* If the first entry is an end-of-list marker, the range + describes an empty scope, i.e. no instructions. */ + return 0; + + ret = -1; + } + } if (high < low) return 0; @@ -1793,21 +2483,83 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc, labels are not in the output, so the relocs get a value of 0. If this is a discarded function, mark the pc bounds as invalid, so that GDB will ignore it. */ - if (low == 0 && (bfd_get_file_flags (objfile->obfd) & HAS_RELOC) == 0) + if (low == 0 && (bfd_get_file_flags (obfd) & HAS_RELOC) == 0) return 0; *lowpc = low; *highpc = high; - return 1; + return ret; +} + +/* Get the low and high pc's represented by the scope DIE, and store + them in *LOWPC and *HIGHPC. If the correct values can't be + determined, set *LOWPC to -1 and *HIGHPC to 0. */ + +static void +get_scope_pc_bounds (struct die_info *die, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu) +{ + CORE_ADDR best_low = (CORE_ADDR) -1; + CORE_ADDR best_high = (CORE_ADDR) 0; + CORE_ADDR current_low, current_high; + + if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu)) + { + best_low = current_low; + best_high = current_high; + } + else + { + struct die_info *child = die->child; + + while (child && child->tag) + { + switch (child->tag) { + case DW_TAG_subprogram: + if (dwarf2_get_pc_bounds (child, ¤t_low, ¤t_high, cu)) + { + best_low = min (best_low, current_low); + best_high = max (best_high, current_high); + } + break; + case DW_TAG_namespace: + /* FIXME: carlton/2004-01-16: Should we do this for + DW_TAG_class_type/DW_TAG_structure_type, too? I think + that current GCC's always emit the DIEs corresponding + to definitions of methods of classes as children of a + DW_TAG_compile_unit or DW_TAG_namespace (as opposed to + the DIEs giving the declarations, which could be + anywhere). But I don't see any reason why the + standards says that they have to be there. */ + get_scope_pc_bounds (child, ¤t_low, ¤t_high, cu); + + if (current_low != ((CORE_ADDR) -1)) + { + best_low = min (best_low, current_low); + best_high = max (best_high, current_high); + } + break; + default: + /* Ignore. */ + break; + } + + child = sibling_die (child); + } + } + + *lowpc = best_low; + *highpc = best_high; } /* Add an aggregate field to the field list. */ static void dwarf2_add_field (struct field_info *fip, struct die_info *die, - struct objfile *objfile, - const struct comp_unit_head *cu_header) -{ + struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; struct nextfield *new_field; struct attribute *attr; struct field *fp; @@ -1830,23 +2582,28 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, new_field->accessibility = DW_ACCESS_private; new_field->virtuality = DW_VIRTUALITY_none; - attr = dwarf_attr (die, DW_AT_accessibility); + attr = dwarf2_attr (die, DW_AT_accessibility, cu); if (attr) new_field->accessibility = DW_UNSND (attr); if (new_field->accessibility != DW_ACCESS_public) fip->non_public_fields = 1; - attr = dwarf_attr (die, DW_AT_virtuality); + attr = dwarf2_attr (die, DW_AT_virtuality, cu); if (attr) new_field->virtuality = DW_UNSND (attr); fp = &new_field->field; - if (die->tag == DW_TAG_member) + + if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu)) { + /* Data member other than a C++ static data member. */ + /* Get type of field. */ - fp->type = die_type (die, objfile, cu_header); + fp->type = die_type (die, cu); + + FIELD_STATIC_KIND (*fp) = 0; /* Get bit size of field (zero if none). */ - attr = dwarf_attr (die, DW_AT_bit_size); + attr = dwarf2_attr (die, DW_AT_bit_size, cu); if (attr) { FIELD_BITSIZE (*fp) = DW_UNSND (attr); @@ -1857,15 +2614,15 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } /* Get bit offset of field. */ - attr = dwarf_attr (die, DW_AT_data_member_location); + attr = dwarf2_attr (die, DW_AT_data_member_location, cu); if (attr) { FIELD_BITPOS (*fp) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header) * bits_per_byte; + decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte; } else FIELD_BITPOS (*fp) = 0; - attr = dwarf_attr (die, DW_AT_bit_offset); + attr = dwarf2_attr (die, DW_AT_bit_offset, cu); if (attr) { if (BITS_BIG_ENDIAN) @@ -1888,7 +2645,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, int anonymous_size; int bit_offset = DW_UNSND (attr); - attr = dwarf_attr (die, DW_AT_byte_size); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { /* The size of the anonymous object containing @@ -1910,50 +2667,57 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } /* Get name of field. */ - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) fieldname = DW_STRING (attr); fp->name = obsavestring (fieldname, strlen (fieldname), - &objfile->type_obstack); + &objfile->objfile_obstack); /* Change accessibility for artificial fields (e.g. virtual table pointer or virtual base class pointer) to private. */ - if (dwarf_attr (die, DW_AT_artificial)) + if (dwarf2_attr (die, DW_AT_artificial, cu)) { new_field->accessibility = DW_ACCESS_private; fip->non_public_fields = 1; } } - else if (die->tag == DW_TAG_variable) + else if (die->tag == DW_TAG_member || die->tag == DW_TAG_variable) { + /* C++ static member. */ + + /* NOTE: carlton/2002-11-05: It should be a DW_TAG_member that + is a declaration, but all versions of G++ as of this writing + (so through at least 3.2.1) incorrectly generate + DW_TAG_variable tags. */ + char *physname; - /* C++ static member. - Get name of field. */ - attr = dwarf_attr (die, DW_AT_name); + /* Get name of field. */ + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) fieldname = DW_STRING (attr); else return; /* Get physical name. */ - physname = dwarf2_linkage_name (die); + physname = dwarf2_linkage_name (die, cu); SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname), - &objfile->type_obstack)); - FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); + &objfile->objfile_obstack)); + FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname), - &objfile->type_obstack); + &objfile->objfile_obstack); } else if (die->tag == DW_TAG_inheritance) { /* C++ base class field. */ - attr = dwarf_attr (die, DW_AT_data_member_location); + attr = dwarf2_attr (die, DW_AT_data_member_location, cu); if (attr) - FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte); FIELD_BITSIZE (*fp) = 0; - FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); + FIELD_STATIC_KIND (*fp) = 0; + FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = type_name_no_tag (fp->type); fip->nbaseclasses++; } @@ -1963,7 +2727,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, static void dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, - struct objfile *objfile) + struct dwarf2_cu *cu) { int nfields = fip->nfields; @@ -2027,8 +2791,8 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, default: /* Unknown accessibility. Complain and treat it as public. */ { - complain (&dwarf2_unsupported_accessibility, - fip->fields->accessibility); + complaint (&symfile_complaints, "unsupported accessibility %d", + fip->fields->accessibility); } break; } @@ -2050,9 +2814,9 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, static void dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, - struct type *type, struct objfile *objfile, - const struct comp_unit_head *cu_header) + struct type *type, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct attribute *attr; struct fnfieldlist *flp; int i; @@ -2062,19 +2826,19 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, struct nextfnfield *new_fnfield; /* Get name of member function. */ - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) fieldname = DW_STRING (attr); else return; /* Get the mangled name. */ - physname = dwarf2_linkage_name (die); + physname = dwarf2_linkage_name (die, cu); /* Look up member function name in fieldlist. */ for (i = 0; i < fip->nfnfields; i++) { - if (STREQ (fip->fnfieldlists[i].name, fieldname)) + if (strcmp (fip->fnfieldlists[i].name, fieldname) == 0) break; } @@ -2111,28 +2875,19 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, /* Fill in the member function field info. */ fnp = &new_fnfield->fnfield; fnp->physname = obsavestring (physname, strlen (physname), - &objfile->type_obstack); + &objfile->objfile_obstack); fnp->type = alloc_type (objfile); if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC) { - struct type *return_type = TYPE_TARGET_TYPE (die->type); - struct type **arg_types; int nparams = TYPE_NFIELDS (die->type); - int iparams; - /* Copy argument types from the subroutine type. */ - arg_types = (struct type **) - TYPE_ALLOC (fnp->type, (nparams + 1) * sizeof (struct type *)); - for (iparams = 0; iparams < nparams; iparams++) - arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams); - - /* Set last entry in argument type vector. */ - if (TYPE_VARARGS (die->type)) - arg_types[nparams] = NULL; - else - arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID); - - smash_to_method_type (fnp->type, type, return_type, arg_types); + /* TYPE is the domain of this method, and DIE->TYPE is the type + of the method itself (TYPE_CODE_METHOD). */ + smash_to_method_type (fnp->type, type, + TYPE_TARGET_TYPE (die->type), + TYPE_FIELDS (die->type), + TYPE_NFIELDS (die->type), + TYPE_VARARGS (die->type)); /* Handle static member functions. Dwarf2 has no clean way to discern C++ static and non-static @@ -2144,17 +2899,18 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, fnp->voffset = VOFFSET_STATIC; } else - complain (&dwarf2_missing_member_fn_type_complaint, physname); + complaint (&symfile_complaints, "member function type missing for '%s'", + physname); /* Get fcontext from DW_AT_containing_type if present. */ - if (dwarf_attr (die, DW_AT_containing_type) != NULL) - fnp->fcontext = die_containing_type (die, objfile, cu_header); + if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL) + fnp->fcontext = die_containing_type (die, cu); /* dwarf2 doesn't have stubbed physical names, so the setting of is_const and is_volatile is irrelevant, as it is needed by gdb_mangle_name only. */ /* Get accessibility. */ - attr = dwarf_attr (die, DW_AT_accessibility); + attr = dwarf2_attr (die, DW_AT_accessibility, cu); if (attr) { switch (DW_UNSND (attr)) @@ -2169,21 +2925,36 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, } /* Check for artificial methods. */ - attr = dwarf_attr (die, DW_AT_artificial); + attr = dwarf2_attr (die, DW_AT_artificial, cu); if (attr && DW_UNSND (attr) != 0) fnp->is_artificial = 1; /* Get index in virtual function table if it is a virtual member function. */ - attr = dwarf_attr (die, DW_AT_vtable_elem_location); + attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu); if (attr) - fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2; + { + /* Support the .debug_loc offsets */ + if (attr_form_is_block (attr)) + { + fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2; + } + else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) + { + dwarf2_complex_location_expr_complaint (); + } + else + { + dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location", + fieldname); + } + } } /* Create the vector of member function fields, and attach it to the type. */ static void dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, - struct objfile *objfile) + struct dwarf2_cu *cu) { struct fnfieldlist *flp; int total_length = 0; @@ -2230,21 +3001,36 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, suppresses creating a symbol table entry itself). */ static void -read_structure_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_structure_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type; struct attribute *attr; + const char *previous_prefix = processing_current_prefix; + struct cleanup *back_to = NULL; + + if (die->type) + return; type = alloc_type (objfile); INIT_CPLUS_SPECIFIC (type); - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) { - TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr), - strlen (DW_STRING (attr)), - &objfile->type_obstack); + if (cu->language == language_cplus) + { + char *new_prefix = determine_class_name (die, cu); + TYPE_TAG_NAME (type) = obsavestring (new_prefix, + strlen (new_prefix), + &objfile->objfile_obstack); + back_to = make_cleanup (xfree, new_prefix); + processing_current_prefix = new_prefix; + } + else + { + TYPE_TAG_NAME (type) = DW_STRING (attr); + } } if (die->tag == DW_TAG_structure_type) @@ -2262,7 +3048,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, TYPE_CODE (type) = TYPE_CODE_CLASS; } - attr = dwarf_attr (die, DW_AT_byte_size); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { TYPE_LENGTH (type) = DW_UNSND (attr); @@ -2277,7 +3063,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, type within the structure itself. */ die->type = type; - if (die->has_children && ! die_is_declaration (die)) + if (die->child != NULL && ! die_is_declaration (die, cu)) { struct field_info fi; struct die_info *child_die; @@ -2285,51 +3071,48 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, memset (&fi, 0, sizeof (struct field_info)); - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - if (child_die->tag == DW_TAG_member) + if (child_die->tag == DW_TAG_member + || child_die->tag == DW_TAG_variable) { - dwarf2_add_field (&fi, child_die, objfile, cu_header); - } - else if (child_die->tag == DW_TAG_variable) - { - /* C++ static member. */ - dwarf2_add_field (&fi, child_die, objfile, cu_header); + /* NOTE: carlton/2002-11-05: A C++ static data member + should be a DW_TAG_member that is a declaration, but + all versions of G++ as of this writing (so through at + least 3.2.1) incorrectly generate DW_TAG_variable + tags for them instead. */ + dwarf2_add_field (&fi, child_die, cu); } else if (child_die->tag == DW_TAG_subprogram) { /* C++ member function. */ - process_die (child_die, objfile, cu_header); - dwarf2_add_member_fn (&fi, child_die, type, objfile, cu_header); + read_type_die (child_die, cu); + dwarf2_add_member_fn (&fi, child_die, type, cu); } else if (child_die->tag == DW_TAG_inheritance) { /* C++ base class field. */ - dwarf2_add_field (&fi, child_die, objfile, cu_header); - } - else - { - process_die (child_die, objfile, cu_header); + dwarf2_add_field (&fi, child_die, cu); } child_die = sibling_die (child_die); } /* Attach fields and member functions to the type. */ if (fi.nfields) - dwarf2_attach_fields_to_type (&fi, type, objfile); + dwarf2_attach_fields_to_type (&fi, type, cu); if (fi.nfnfields) { - dwarf2_attach_fn_fields_to_type (&fi, type, objfile); + dwarf2_attach_fn_fields_to_type (&fi, type, cu); /* Get the type which refers to the base class (possibly this class itself) which contains the vtable pointer for the current class from the DW_AT_containing_type attribute. */ - if (dwarf_attr (die, DW_AT_containing_type) != NULL) + if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL) { - struct type *t = die_containing_type (die, objfile, cu_header); + struct type *t = die_containing_type (die, cu); TYPE_VPTR_BASETYPE (type) = t; if (type == t) @@ -2345,7 +3128,9 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, { char *fieldname = TYPE_FIELD_NAME (t, i); - if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1) + if ((strncmp (fieldname, vptr_name, + strlen (vptr_name) - 1) + == 0) && is_cplus_marker (fieldname[strlen (vptr_name)])) { TYPE_VPTR_FIELDNO (type) = i; @@ -2355,8 +3140,10 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, /* Complain if virtual function table field not found. */ if (i < TYPE_N_BASECLASSES (t)) - complain (&dwarf2_vtbl_not_found_complaint, - TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : ""); + complaint (&symfile_complaints, + "virtual function table pointer not found when defining class '%s'", + TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : + ""); } else { @@ -2365,8 +3152,6 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, } } - new_symbol (die, type, objfile, cu_header); - do_cleanups (back_to); } else @@ -2375,42 +3160,85 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, TYPE_FLAGS (type) |= TYPE_FLAG_STUB; } - finish_cv_type (die->type); + processing_current_prefix = previous_prefix; + if (back_to != NULL) + do_cleanups (back_to); } -/* Given a pointer to a die which begins an enumeration, process all - the dies that define the members of the enumeration. +static void +process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + const char *previous_prefix = processing_current_prefix; + struct die_info *child_die = die->child; - This will be much nicer in draft 6 of the DWARF spec when our - members will be dies instead squished into the DW_AT_element_list - attribute. + if (TYPE_TAG_NAME (die->type) != NULL) + processing_current_prefix = TYPE_TAG_NAME (die->type); - NOTE: We reverse the order of the element list. */ + /* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its + snapshots) has been known to create a die giving a declaration + for a class that has, as a child, a die giving a definition for a + nested class. So we have to process our children even if the + current die is a declaration. Normally, of course, a declaration + won't have any children at all. */ + + while (child_die != NULL && child_die->tag) + { + if (child_die->tag == DW_TAG_member + || child_die->tag == DW_TAG_variable + || child_die->tag == DW_TAG_inheritance) + { + /* Do nothing. */ + } + else + process_die (child_die, cu); + + child_die = sibling_die (child_die); + } + + if (die->child != NULL && ! die_is_declaration (die, cu)) + new_symbol (die, die->type, cu); + + processing_current_prefix = previous_prefix; +} + +/* Given a DW_AT_enumeration_type die, set its type. We do not + complete the type's fields yet, or create any symbols. */ static void -read_enumeration (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) { - struct die_info *child_die; + struct objfile *objfile = cu->objfile; struct type *type; - struct field *fields; struct attribute *attr; - struct symbol *sym; - int num_fields; - int unsigned_enum = 1; + + if (die->type) + return; type = alloc_type (objfile); TYPE_CODE (type) = TYPE_CODE_ENUM; - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) { - TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr), - strlen (DW_STRING (attr)), - &objfile->type_obstack); + const char *name = DW_STRING (attr); + + if (processing_has_namespace_info) + { + TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack, + processing_current_prefix, + processing_current_prefix[0] == '\0' + ? "" : "::", + name); + } + else + { + TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), + &objfile->objfile_obstack); + } } - attr = dwarf_attr (die, DW_AT_byte_size); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { TYPE_LENGTH (type) = DW_UNSND (attr); @@ -2420,23 +3248,99 @@ read_enumeration (struct die_info *die, struct objfile *objfile, TYPE_LENGTH (type) = 0; } + die->type = type; +} + +/* Determine the name of the type represented by DIE, which should be + a named C++ compound type. Return the name in question; the caller + is responsible for xfree()'ing it. */ + +static char * +determine_class_name (struct die_info *die, struct dwarf2_cu *cu) +{ + struct cleanup *back_to = NULL; + struct die_info *spec_die = die_specification (die, cu); + char *new_prefix = NULL; + + /* If this is the definition of a class that is declared by another + die, then processing_current_prefix may not be accurate; see + read_func_scope for a similar example. */ + if (spec_die != NULL) + { + char *specification_prefix = determine_prefix (spec_die, cu); + processing_current_prefix = specification_prefix; + back_to = make_cleanup (xfree, specification_prefix); + } + + /* If we don't have namespace debug info, guess the name by trying + to demangle the names of members, just like we did in + add_partial_structure. */ + if (!processing_has_namespace_info) + { + struct die_info *child; + + for (child = die->child; + child != NULL && child->tag != 0; + child = sibling_die (child)) + { + if (child->tag == DW_TAG_subprogram) + { + new_prefix = class_name_from_physname (dwarf2_linkage_name + (child, cu)); + + if (new_prefix != NULL) + break; + } + } + } + + if (new_prefix == NULL) + { + const char *name = dwarf2_name (die, cu); + new_prefix = typename_concat (processing_current_prefix, + name ? name : "<>"); + } + + if (back_to != NULL) + do_cleanups (back_to); + + return new_prefix; +} + +/* Given a pointer to a die which begins an enumeration, process all + the dies that define the members of the enumeration, and create the + symbol for the enumeration type. + + NOTE: We reverse the order of the element list. */ + +static void +process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct die_info *child_die; + struct field *fields; + struct attribute *attr; + struct symbol *sym; + int num_fields; + int unsigned_enum = 1; + num_fields = 0; fields = NULL; - if (die->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { if (child_die->tag != DW_TAG_enumerator) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); } else { - attr = dwarf_attr (child_die, DW_AT_name); + attr = dwarf2_attr (child_die, DW_AT_name, cu); if (attr) { - sym = new_symbol (child_die, type, objfile, cu_header); + sym = new_symbol (child_die, die->type, cu); if (SYMBOL_VALUE (sym) < 0) unsigned_enum = 0; @@ -2448,10 +3352,11 @@ read_enumeration (struct die_info *die, struct objfile *objfile, * sizeof (struct field)); } - FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym); + FIELD_NAME (fields[num_fields]) = DEPRECATED_SYMBOL_NAME (sym); FIELD_TYPE (fields[num_fields]) = NULL; FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym); FIELD_BITSIZE (fields[num_fields]) = 0; + FIELD_STATIC_KIND (fields[num_fields]) = 0; num_fields++; } @@ -2462,18 +3367,18 @@ read_enumeration (struct die_info *die, struct objfile *objfile, if (num_fields) { - TYPE_NFIELDS (type) = num_fields; - TYPE_FIELDS (type) = (struct field *) - TYPE_ALLOC (type, sizeof (struct field) * num_fields); - memcpy (TYPE_FIELDS (type), fields, + TYPE_NFIELDS (die->type) = num_fields; + TYPE_FIELDS (die->type) = (struct field *) + TYPE_ALLOC (die->type, sizeof (struct field) * num_fields); + memcpy (TYPE_FIELDS (die->type), fields, sizeof (struct field) * num_fields); xfree (fields); } if (unsigned_enum) - TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; + TYPE_FLAGS (die->type) |= TYPE_FLAG_UNSIGNED; } - die->type = type; - new_symbol (die, type, objfile, cu_header); + + new_symbol (die, die->type, cu); } /* Extract all information from a DW_TAG_array_type DIE and put it in @@ -2481,9 +3386,9 @@ read_enumeration (struct die_info *die, struct objfile *objfile, arrays. */ static void -read_array_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_array_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct die_info *child_die; struct type *type = NULL; struct type *element_type, *range_type, *index_type; @@ -2498,108 +3403,40 @@ read_array_type (struct die_info *die, struct objfile *objfile, return; } - element_type = die_type (die, objfile, cu_header); + element_type = die_type (die, cu); /* Irix 6.2 native cc creates array types without children for arrays with unspecified length. */ - if (die->has_children == 0) + if (die->child == NULL) { - index_type = dwarf2_fundamental_type (objfile, FT_INTEGER); + index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu); range_type = create_range_type (NULL, index_type, 0, -1); die->type = create_array_type (NULL, element_type, range_type); return; } back_to = make_cleanup (null_cleanup, NULL); - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { if (child_die->tag == DW_TAG_subrange_type) { - unsigned int low, high; + read_subrange_type (child_die, cu); - /* Default bounds to an array with unspecified length. */ - low = 0; - high = -1; - if (cu_language == language_fortran) - { - /* FORTRAN implies a lower bound of 1, if not given. */ - low = 1; - } - - index_type = die_type (child_die, objfile, cu_header); - attr = dwarf_attr (child_die, DW_AT_lower_bound); - if (attr) - { - if (attr->form == DW_FORM_sdata) - { - low = DW_SND (attr); - } - else if (attr->form == DW_FORM_udata - || attr->form == DW_FORM_data1 - || attr->form == DW_FORM_data2 - || attr->form == DW_FORM_data4) - { - low = DW_UNSND (attr); - } - else - { - complain (&dwarf2_non_const_array_bound_ignored, - dwarf_form_name (attr->form)); -#ifdef FORTRAN_HACK - die->type = lookup_pointer_type (element_type); - return; -#else - low = 0; -#endif - } - } - attr = dwarf_attr (child_die, DW_AT_upper_bound); - if (attr) - { - if (attr->form == DW_FORM_sdata) - { - high = DW_SND (attr); - } - else if (attr->form == DW_FORM_udata - || attr->form == DW_FORM_data1 - || attr->form == DW_FORM_data2 - || attr->form == DW_FORM_data4) - { - high = DW_UNSND (attr); - } - else if (attr->form == DW_FORM_block1) - { - /* GCC encodes arrays with unspecified or dynamic length - with a DW_FORM_block1 attribute. - FIXME: GDB does not yet know how to handle dynamic - arrays properly, treat them as arrays with unspecified - length for now. */ - high = -1; - } - else - { - complain (&dwarf2_non_const_array_bound_ignored, - dwarf_form_name (attr->form)); -#ifdef FORTRAN_HACK - die->type = lookup_pointer_type (element_type); - return; -#else - high = 1; -#endif - } - } - - /* Create a range type and save it for array type creation. */ - if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0) - { - range_types = (struct type **) - xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK) - * sizeof (struct type *)); - if (ndim == 0) - make_cleanup (free_current_contents, &range_types); - } - range_types[ndim++] = create_range_type (NULL, index_type, low, high); + if (child_die->type != NULL) + { + /* The range type was succesfully read. Save it for + the array type creation. */ + if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0) + { + range_types = (struct type **) + xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK) + * sizeof (struct type *)); + if (ndim == 0) + make_cleanup (free_current_contents, &range_types); + } + range_types[ndim++] = child_die->type; + } } child_die = sibling_die (child_die); } @@ -2610,6 +3447,16 @@ read_array_type (struct die_info *die, struct objfile *objfile, while (ndim-- > 0) type = create_array_type (NULL, type, range_types[ndim]); + /* Understand Dwarf2 support for vector types (like they occur on + the PowerPC w/ AltiVec). Gcc just adds another attribute to the + array type. This is not part of the Dwarf2/3 standard yet, but a + custom vendor extension. The main difference between a regular + array and the vector variant is that vectors are passed by value + to functions. */ + attr = dwarf2_attr (die, DW_AT_GNU_vector, cu); + if (attr) + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; + do_cleanups (back_to); /* Install the type in the die. */ @@ -2619,30 +3466,42 @@ read_array_type (struct die_info *die, struct objfile *objfile, /* First cut: install each common block member as a global variable. */ static void -read_common_block (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_common_block (struct die_info *die, struct dwarf2_cu *cu) { struct die_info *child_die; struct attribute *attr; struct symbol *sym; CORE_ADDR base = (CORE_ADDR) 0; - attr = dwarf_attr (die, DW_AT_location); + attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) { - base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + /* Support the .debug_loc offsets */ + if (attr_form_is_block (attr)) + { + base = decode_locdesc (DW_BLOCK (attr), cu); + } + else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) + { + dwarf2_complex_location_expr_complaint (); + } + else + { + dwarf2_invalid_attrib_class_complaint ("DW_AT_location", + "common block member"); + } } - if (die->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - sym = new_symbol (child_die, NULL, objfile, cu_header); - attr = dwarf_attr (child_die, DW_AT_data_member_location); + sym = new_symbol (child_die, NULL, cu); + attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu); if (attr) { SYMBOL_VALUE_ADDRESS (sym) = - base + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + base + decode_locdesc (DW_BLOCK (attr), cu); add_symbol_to_list (sym, &global_symbols); } child_die = sibling_die (child_die); @@ -2650,31 +3509,160 @@ read_common_block (struct die_info *die, struct objfile *objfile, } } +/* Read a C++ namespace. */ + +static void +read_namespace (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + const char *previous_prefix = processing_current_prefix; + const char *name; + int is_anonymous; + struct die_info *current_die; + + name = namespace_name (die, &is_anonymous, cu); + + /* Now build the name of the current namespace. */ + + if (previous_prefix[0] == '\0') + { + processing_current_prefix = name; + } + else + { + /* We need temp_name around because processing_current_prefix + is a const char *. */ + char *temp_name = alloca (strlen (previous_prefix) + + 2 + strlen(name) + 1); + strcpy (temp_name, previous_prefix); + strcat (temp_name, "::"); + strcat (temp_name, name); + + processing_current_prefix = temp_name; + } + + /* Add a symbol associated to this if we haven't seen the namespace + before. Also, add a using directive if it's an anonymous + namespace. */ + + if (dwarf2_extension (die, cu) == NULL) + { + struct type *type; + + /* FIXME: carlton/2003-06-27: Once GDB is more const-correct, + this cast will hopefully become unnecessary. */ + type = init_type (TYPE_CODE_NAMESPACE, 0, 0, + (char *) processing_current_prefix, + objfile); + TYPE_TAG_NAME (type) = TYPE_NAME (type); + + new_symbol (die, type, cu); + die->type = type; + + if (is_anonymous) + cp_add_using_directive (processing_current_prefix, + strlen (previous_prefix), + strlen (processing_current_prefix)); + } + + if (die->child != NULL) + { + struct die_info *child_die = die->child; + + while (child_die && child_die->tag) + { + process_die (child_die, cu); + child_die = sibling_die (child_die); + } + } + + processing_current_prefix = previous_prefix; +} + +/* Return the name of the namespace represented by DIE. Set + *IS_ANONYMOUS to tell whether or not the namespace is an anonymous + namespace. */ + +static const char * +namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu) +{ + struct die_info *current_die; + const char *name = NULL; + + /* Loop through the extensions until we find a name. */ + + for (current_die = die; + current_die != NULL; + current_die = dwarf2_extension (die, cu)) + { + name = dwarf2_name (current_die, cu); + if (name != NULL) + break; + } + + /* Is it an anonymous namespace? */ + + *is_anonymous = (name == NULL); + if (*is_anonymous) + name = "(anonymous namespace)"; + + return name; +} + /* Extract all information from a DW_TAG_pointer_type DIE and add to the user defined type vector. */ static void -read_tag_pointer_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; struct type *type; - struct attribute *attr; + struct attribute *attr_byte_size; + struct attribute *attr_address_class; + int byte_size, addr_class; if (die->type) { return; } - type = lookup_pointer_type (die_type (die, objfile, cu_header)); - attr = dwarf_attr (die, DW_AT_byte_size); - if (attr) - { - TYPE_LENGTH (type) = DW_UNSND (attr); - } + type = lookup_pointer_type (die_type (die, cu)); + + attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu); + if (attr_byte_size) + byte_size = DW_UNSND (attr_byte_size); else + byte_size = cu_header->addr_size; + + attr_address_class = dwarf2_attr (die, DW_AT_address_class, cu); + if (attr_address_class) + addr_class = DW_UNSND (attr_address_class); + else + addr_class = DW_ADDR_none; + + /* If the pointer size or address class is different than the + default, create a type variant marked as such and set the + length accordingly. */ + if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none) { - TYPE_LENGTH (type) = cu_header->addr_size; + if (ADDRESS_CLASS_TYPE_FLAGS_P ()) + { + int type_flags; + + type_flags = ADDRESS_CLASS_TYPE_FLAGS (byte_size, addr_class); + gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0); + type = make_type_with_address_space (type, type_flags); + } + else if (TYPE_LENGTH (type) != byte_size) + { + complaint (&symfile_complaints, "invalid pointer size %d", byte_size); + } + else { + /* Should we also complain about unhandled address classes? */ + } } + + TYPE_LENGTH (type) = byte_size; die->type = type; } @@ -2682,9 +3670,9 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile, the user defined type vector. */ static void -read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type; struct type *to_type; struct type *domain; @@ -2695,8 +3683,8 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile, } type = alloc_type (objfile); - to_type = die_type (die, objfile, cu_header); - domain = die_containing_type (die, objfile, cu_header); + to_type = die_type (die, cu); + domain = die_containing_type (die, cu); smash_to_member_type (type, domain, to_type); die->type = type; @@ -2706,9 +3694,9 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile, the user defined type vector. */ static void -read_tag_reference_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; struct type *type; struct attribute *attr; @@ -2717,8 +3705,8 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile, return; } - type = lookup_reference_type (die_type (die, objfile, cu_header)); - attr = dwarf_attr (die, DW_AT_byte_size); + type = lookup_reference_type (die_type (die, cu)); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { TYPE_LENGTH (type) = DW_UNSND (attr); @@ -2731,8 +3719,7 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile, } static void -read_tag_const_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *base_type; @@ -2741,13 +3728,12 @@ read_tag_const_type (struct die_info *die, struct objfile *objfile, return; } - base_type = die_type (die, objfile, cu_header); + base_type = die_type (die, cu); die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0); } static void -read_tag_volatile_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *base_type; @@ -2756,7 +3742,7 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile, return; } - base_type = die_type (die, objfile, cu_header); + base_type = die_type (die, cu); die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0); } @@ -2766,8 +3752,9 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile, attribute to reference it. */ static void -read_tag_string_type (struct die_info *die, struct objfile *objfile) +read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type, *range_type, *index_type, *char_type; struct attribute *attr; unsigned int length; @@ -2777,7 +3764,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) return; } - attr = dwarf_attr (die, DW_AT_string_length); + attr = dwarf2_attr (die, DW_AT_string_length, cu); if (attr) { length = DW_UNSND (attr); @@ -2785,7 +3772,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) else { /* check for the DW_AT_byte_size attribute */ - attr = dwarf_attr (die, DW_AT_byte_size); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { length = DW_UNSND (attr); @@ -2795,9 +3782,9 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) length = 1; } } - index_type = dwarf2_fundamental_type (objfile, FT_INTEGER); + index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu); range_type = create_range_type (NULL, index_type, 1, length); - if (cu_language == language_fortran) + if (cu->language == language_fortran) { /* Need to create a unique string type for bounds information */ @@ -2805,7 +3792,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) } else { - char_type = dwarf2_fundamental_type (objfile, FT_CHAR); + char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu); type = create_string_type (char_type, range_type); } die->type = type; @@ -2823,8 +3810,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) */ static void -read_subroutine_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *type; /* Type that this function returns */ struct type *ftype; /* Function that returns above type */ @@ -2835,16 +3821,16 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, { return; } - type = die_type (die, objfile, cu_header); + type = die_type (die, cu); ftype = lookup_function_type (type); /* All functions in C++ have prototypes. */ - attr = dwarf_attr (die, DW_AT_prototyped); + attr = dwarf2_attr (die, DW_AT_prototyped, cu); if ((attr && (DW_UNSND (attr) != 0)) - || cu_language == language_cplus) + || cu->language == language_cplus) TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED; - if (die->has_children) + if (die->child != NULL) { struct die_info *child_die; int nparams = 0; @@ -2853,7 +3839,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, /* Count the number of parameters. FIXME: GDB currently ignores vararg functions, but knows about vararg member functions. */ - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { if (child_die->tag == DW_TAG_formal_parameter) @@ -2868,7 +3854,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, TYPE_FIELDS (ftype) = (struct field *) TYPE_ALLOC (ftype, nparams * sizeof (struct field)); - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { if (child_die->tag == DW_TAG_formal_parameter) @@ -2878,13 +3864,12 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, parameter for non-static member functions (which is the this pointer) as artificial. We pass this information to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL. */ - attr = dwarf_attr (child_die, DW_AT_artificial); + attr = dwarf2_attr (child_die, DW_AT_artificial, cu); if (attr) TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr); else TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0; - TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile, - cu_header); + TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, cu); iparams++; } child_die = sibling_die (child_die); @@ -2895,21 +3880,21 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, } static void -read_typedef (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_typedef (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct attribute *attr; char *name = NULL; if (!die->type) { - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) { name = DW_STRING (attr); } die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile); - TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header); + TYPE_TARGET_TYPE (die->type) = die_type (die, cu); } } @@ -2917,8 +3902,9 @@ read_typedef (struct die_info *die, struct objfile *objfile, it in the TYPE field of the die. */ static void -read_base_type (struct die_info *die, struct objfile *objfile) +read_base_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type; struct attribute *attr; int encoding = 0, size = 0; @@ -2929,17 +3915,17 @@ read_base_type (struct die_info *die, struct objfile *objfile) return; } - attr = dwarf_attr (die, DW_AT_encoding); + attr = dwarf2_attr (die, DW_AT_encoding, cu); if (attr) { encoding = DW_UNSND (attr); } - attr = dwarf_attr (die, DW_AT_byte_size); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { size = DW_UNSND (attr); } - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) { enum type_code code = TYPE_CODE_INT; @@ -2970,67 +3956,193 @@ read_base_type (struct die_info *die, struct objfile *objfile) type_flags |= TYPE_FLAG_UNSIGNED; break; default: - complain (&dwarf2_unsupported_at_encoding, - dwarf_type_encoding_name (encoding)); + complaint (&symfile_complaints, "unsupported DW_AT_encoding: '%s'", + dwarf_type_encoding_name (encoding)); break; } type = init_type (code, size, type_flags, DW_STRING (attr), objfile); if (encoding == DW_ATE_address) - TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID); + TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID, + cu); + else if (encoding == DW_ATE_complex_float) + { + if (size == 32) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT, cu); + else if (size == 16) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu); + else if (size == 8) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_FLOAT, cu); + } } else { - type = dwarf_base_type (encoding, size, objfile); + type = dwarf_base_type (encoding, size, cu); } die->type = type; } +/* Read the given DW_AT_subrange DIE. */ + +static void +read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) +{ + struct type *base_type; + struct type *range_type; + struct attribute *attr; + int low = 0; + int high = -1; + + /* If we have already decoded this die, then nothing more to do. */ + if (die->type) + return; + + base_type = die_type (die, cu); + if (base_type == NULL) + { + complaint (&symfile_complaints, + "DW_AT_type missing from DW_TAG_subrange_type"); + return; + } + + if (TYPE_CODE (base_type) == TYPE_CODE_VOID) + base_type = alloc_type (NULL); + + if (cu->language == language_fortran) + { + /* FORTRAN implies a lower bound of 1, if not given. */ + low = 1; + } + + attr = dwarf2_attr (die, DW_AT_lower_bound, cu); + if (attr) + low = dwarf2_get_attr_constant_value (attr, 0); + + attr = dwarf2_attr (die, DW_AT_upper_bound, cu); + if (attr) + { + if (attr->form == DW_FORM_block1) + { + /* GCC encodes arrays with unspecified or dynamic length + with a DW_FORM_block1 attribute. + FIXME: GDB does not yet know how to handle dynamic + arrays properly, treat them as arrays with unspecified + length for now. + + FIXME: jimb/2003-09-22: GDB does not really know + how to handle arrays of unspecified length + either; we just represent them as zero-length + arrays. Choose an appropriate upper bound given + the lower bound we've computed above. */ + high = low - 1; + } + else + high = dwarf2_get_attr_constant_value (attr, 1); + } + + range_type = create_range_type (NULL, base_type, low, high); + + attr = dwarf2_attr (die, DW_AT_name, cu); + if (attr && DW_STRING (attr)) + TYPE_NAME (range_type) = DW_STRING (attr); + + attr = dwarf2_attr (die, DW_AT_byte_size, cu); + if (attr) + TYPE_LENGTH (range_type) = DW_UNSND (attr); + + die->type = range_type; +} + + /* Read a whole compilation unit into a linked list of dies. */ static struct die_info * -read_comp_unit (char *info_ptr, bfd *abfd, - const struct comp_unit_head *cu_header) +read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu) { - struct die_info *first_die, *last_die, *die; - char *cur_ptr; - int nesting_level; - /* Reset die reference table; we are building new ones now. */ dwarf2_empty_hash_tables (); - cur_ptr = info_ptr; - nesting_level = 0; - first_die = last_die = NULL; - do + return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL); +} + +/* Read a single die and all its descendents. Set the die's sibling + field to NULL; set other fields in the die correctly, and set all + of the descendents' fields correctly. Set *NEW_INFO_PTR to the + location of the info_ptr after reading all of those dies. PARENT + is the parent of the die in question. */ + +static struct die_info * +read_die_and_children (char *info_ptr, bfd *abfd, + struct dwarf2_cu *cu, + char **new_info_ptr, + struct die_info *parent) +{ + struct die_info *die; + char *cur_ptr; + int has_children; + + cur_ptr = read_full_die (&die, abfd, info_ptr, cu, &has_children); + store_in_ref_table (die->offset, die); + + if (has_children) { - cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header); - if (die->has_children) - { - nesting_level++; - } - if (die->tag == 0) - { - nesting_level--; - } + die->child = read_die_and_siblings (cur_ptr, abfd, cu, + new_info_ptr, die); + } + else + { + die->child = NULL; + *new_info_ptr = cur_ptr; + } - die->next = NULL; + die->sibling = NULL; + die->parent = parent; + return die; +} - /* Enter die in reference hash table */ - store_in_ref_table (die->offset, die); +/* Read a die, all of its descendents, and all of its siblings; set + all of the fields of all of the dies correctly. Arguments are as + in read_die_and_children. */ + +static struct die_info * +read_die_and_siblings (char *info_ptr, bfd *abfd, + struct dwarf2_cu *cu, + char **new_info_ptr, + struct die_info *parent) +{ + struct die_info *first_die, *last_sibling; + char *cur_ptr; + + cur_ptr = info_ptr; + first_die = last_sibling = NULL; + + while (1) + { + struct die_info *die + = read_die_and_children (cur_ptr, abfd, cu, &cur_ptr, parent); if (!first_die) { - first_die = last_die = die; + first_die = die; } else { - last_die->next = die; - last_die = die; + last_sibling->sibling = die; + } + + if (die->tag == 0) + { + *new_info_ptr = cur_ptr; + return first_die; + } + else + { + last_sibling = die; } } - while (nesting_level > 0); - return first_die; } /* Free a linked list of dies. */ @@ -3043,7 +4155,9 @@ free_die_list (struct die_info *dies) die = dies; while (die) { - next = die->next; + if (die->child != NULL) + free_die_list (die->child); + next = die->sibling; xfree (die->attrs); xfree (die); die = next; @@ -3064,26 +4178,29 @@ make_cleanup_free_die_list (struct die_info *dies) /* Read the contents of the section at OFFSET and of size SIZE from the - object file specified by OBJFILE into the psymbol_obstack and return it. */ + object file specified by OBJFILE into the objfile_obstack and return it. */ char * -dwarf2_read_section (struct objfile *objfile, file_ptr offset, - unsigned int size) +dwarf2_read_section (struct objfile *objfile, asection *sectp) { bfd *abfd = objfile->obfd; - char *buf; + char *buf, *retbuf; + bfd_size_type size = bfd_get_section_size_before_reloc (sectp); if (size == 0) return NULL; - buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size); - if ((bfd_seek (abfd, offset, SEEK_SET) != 0) || - (bfd_bread (buf, size, abfd) != size)) - { - buf = NULL; - error ("Dwarf Error: Can't read DWARF data from '%s'", - bfd_get_filename (abfd)); - } + buf = (char *) obstack_alloc (&objfile->objfile_obstack, size); + retbuf + = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf); + if (retbuf != NULL) + return retbuf; + + if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 + || bfd_bread (buf, size, abfd) != size) + error ("Dwarf Error: Can't read DWARF data from '%s'", + bfd_get_filename (abfd)); + return buf; } @@ -3093,17 +4210,19 @@ dwarf2_read_section (struct objfile *objfile, file_ptr offset, in a hash table. */ static void -dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) +dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; char *abbrev_ptr; struct abbrev_info *cur_abbrev; unsigned int abbrev_number, bytes_read, abbrev_name; unsigned int abbrev_form, hash_number; - /* empty the table */ - dwarf2_empty_abbrev_table (NULL); + /* Initialize dwarf2 abbrevs */ + memset (cu_header->dwarf2_abbrevs, 0, + ABBREV_HASH_SIZE*sizeof (struct abbrev_info *)); - abbrev_ptr = dwarf_abbrev_buffer + offset; + abbrev_ptr = dwarf_abbrev_buffer + cu_header->abbrev_offset; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -3142,8 +4261,8 @@ dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) } hash_number = abbrev_number % ABBREV_HASH_SIZE; - cur_abbrev->next = dwarf2_abbrevs[hash_number]; - dwarf2_abbrevs[hash_number] = cur_abbrev; + cur_abbrev->next = cu_header->dwarf2_abbrevs[hash_number]; + cu_header->dwarf2_abbrevs[hash_number] = cur_abbrev; /* Get next abbreviation. Under Irix6 the abbreviations for a compilation unit are not @@ -3157,24 +4276,26 @@ dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) break; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; - if (dwarf2_lookup_abbrev (abbrev_number) != NULL) + if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL) break; } } /* Empty the abbrev table for a new compilation unit. */ -/* ARGSUSED */ static void -dwarf2_empty_abbrev_table (PTR ignore) +dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table) { int i; struct abbrev_info *abbrev, *next; + struct abbrev_info **abbrevs; + + abbrevs = (struct abbrev_info **)ptr_to_abbrevs_table; for (i = 0; i < ABBREV_HASH_SIZE; ++i) { next = NULL; - abbrev = dwarf2_abbrevs[i]; + abbrev = abbrevs[i]; while (abbrev) { next = abbrev->next; @@ -3182,20 +4303,21 @@ dwarf2_empty_abbrev_table (PTR ignore) xfree (abbrev); abbrev = next; } - dwarf2_abbrevs[i] = NULL; + abbrevs[i] = NULL; } } /* Lookup an abbrev_info structure in the abbrev hash table. */ static struct abbrev_info * -dwarf2_lookup_abbrev (unsigned int number) +dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; unsigned int hash_number; struct abbrev_info *abbrev; hash_number = number % ABBREV_HASH_SIZE; - abbrev = dwarf2_abbrevs[hash_number]; + abbrev = cu_header->dwarf2_abbrevs[hash_number]; while (abbrev) { @@ -3211,7 +4333,7 @@ dwarf2_lookup_abbrev (unsigned int number) static char * read_partial_die (struct partial_die_info *part_die, bfd *abfd, - char *info_ptr, const struct comp_unit_head *cu_header) + char *info_ptr, struct dwarf2_cu *cu) { unsigned int abbrev_number, bytes_read, i; struct abbrev_info *abbrev; @@ -3227,10 +4349,11 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, if (!abbrev_number) return info_ptr; - abbrev = dwarf2_lookup_abbrev (abbrev_number); + abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); if (!abbrev) { - error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number); + error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number, + bfd_get_filename (abfd)); } part_die->offset = info_ptr - dwarf_info_buffer; part_die->tag = abbrev->tag; @@ -3239,8 +4362,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, for (i = 0; i < abbrev->num_attrs; ++i) { - info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, - info_ptr, cu_header); + info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr, cu); /* Store the data if it is of an attribute we want to keep in a partial symbol table. */ @@ -3264,7 +4386,20 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, part_die->highpc = DW_ADDR (&attr); break; case DW_AT_location: - part_die->locdesc = DW_BLOCK (&attr); + /* Support the .debug_loc offsets */ + if (attr_form_is_block (&attr)) + { + part_die->locdesc = DW_BLOCK (&attr); + } + else if (attr.form == DW_FORM_data4 || attr.form == DW_FORM_data8) + { + dwarf2_complex_location_expr_complaint (); + } + else + { + dwarf2_invalid_attrib_class_complaint ("DW_AT_location", + "partial symbol information"); + } break; case DW_AT_language: part_die->language = DW_UNSND (&attr); @@ -3287,10 +4422,10 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, /* Ignore absolute siblings, they might point outside of the current compile unit. */ if (attr.form == DW_FORM_ref_addr) - complain (&dwarf2_absolute_sibling_complaint); + complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling"); else part_die->sibling = - dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr); + dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu); break; default: break; @@ -3304,10 +4439,10 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, { struct partial_die_info spec_die; char *spec_ptr; - int dummy; - spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr); - read_partial_die (&spec_die, abfd, spec_ptr, cu_header); + spec_ptr = dwarf_info_buffer + + dwarf2_get_ref_die_offset (&spec_attr, cu); + read_partial_die (&spec_die, abfd, spec_ptr, cu); if (spec_die.name) { part_die->name = spec_die.name; @@ -3334,12 +4469,14 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, return info_ptr; } -/* Read the die from the .debug_info section buffer. And set diep to - point to a newly allocated die with its information. */ +/* Read the die from the .debug_info section buffer. Set DIEP to + point to a newly allocated die with its information, except for its + child, sibling, and parent fields. Set HAS_CHILDREN to tell + whether the die has children or not. */ static char * read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, - const struct comp_unit_head *cu_header) + struct dwarf2_cu *cu, int *has_children) { unsigned int abbrev_number, bytes_read, i, offset; struct abbrev_info *abbrev; @@ -3355,18 +4492,20 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, die->abbrev = abbrev_number; die->type = NULL; *diep = die; + *has_children = 0; return info_ptr; } - abbrev = dwarf2_lookup_abbrev (abbrev_number); + abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); if (!abbrev) { - error ("Dwarf Error: could not find abbrev number %d.", abbrev_number); + error ("Dwarf Error: could not find abbrev number %d [in module %s]", + abbrev_number, + bfd_get_filename (abfd)); } die = dwarf_alloc_die (); die->offset = offset; die->tag = abbrev->tag; - die->has_children = abbrev->has_children; die->abbrev = abbrev_number; die->type = NULL; @@ -3377,10 +4516,11 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, for (i = 0; i < abbrev->num_attrs; ++i) { info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i], - abfd, info_ptr, cu_header); + abfd, info_ptr, cu); } *diep = die; + *has_children = abbrev->has_children; return info_ptr; } @@ -3388,9 +4528,10 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, static char * read_attribute_value (struct attribute *attr, unsigned form, - bfd *abfd, char *info_ptr, - const struct comp_unit_head *cu_header) + bfd *abfd, char *info_ptr, + struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; unsigned int bytes_read; struct dwarf_block *blk; @@ -3399,7 +4540,7 @@ read_attribute_value (struct attribute *attr, unsigned form, { case DW_FORM_addr: case DW_FORM_ref_addr: - DW_ADDR (attr) = read_address (abfd, info_ptr, cu_header, &bytes_read); + DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read); info_ptr += bytes_read; break; case DW_FORM_block2: @@ -3494,11 +4635,12 @@ read_attribute_value (struct attribute *attr, unsigned form, case DW_FORM_indirect: form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; - info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu_header); + info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu); break; default: - error ("Dwarf Error: Cannot handle %s in DWARF reader.", - dwarf_form_name (form)); + error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]", + dwarf_form_name (form), + bfd_get_filename (abfd)); } return info_ptr; } @@ -3507,11 +4649,10 @@ read_attribute_value (struct attribute *attr, unsigned form, static char * read_attribute (struct attribute *attr, struct attr_abbrev *abbrev, - bfd *abfd, char *info_ptr, - const struct comp_unit_head *cu_header) + bfd *abfd, char *info_ptr, struct dwarf2_cu *cu) { attr->name = abbrev->name; - return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu_header); + return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu); } /* read dwarf information from a buffer */ @@ -3559,9 +4700,9 @@ read_8_bytes (bfd *abfd, char *buf) } static CORE_ADDR -read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, - int *bytes_read) +read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read) { + struct comp_unit_head *cu_header = &cu->header; CORE_ADDR retval = 0; if (cu_header->signed_addr_p) @@ -3579,7 +4720,8 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, break; default: internal_error (__FILE__, __LINE__, - "read_address: bad switch, signed"); + "read_address: bad switch, signed [in module %s]", + bfd_get_filename (abfd)); } } else @@ -3597,7 +4739,8 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, break; default: internal_error (__FILE__, __LINE__, - "read_address: bad switch, unsigned"); + "read_address: bad switch, unsigned [in module %s]", + bfd_get_filename (abfd)); } } @@ -3605,12 +4748,25 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, return retval; } -/* Reads the initial length from a section. The (draft) DWARF 2.1 +/* Read the initial length from a section. The (draft) DWARF 3 specification allows the initial length to take up either 4 bytes or 12 bytes. If the first 4 bytes are 0xffffffff, then the next 8 bytes describe the length and all offsets will be 8 bytes in length instead of 4. + An older, non-standard 64-bit format is also handled by this + function. The older format in question stores the initial length + as an 8-byte quantity without an escape value. Lengths greater + than 2^32 aren't very common which means that the initial 4 bytes + is almost always zero. Since a length value of zero doesn't make + sense for the 32-bit format, this initial zero can be considered to + be an escape value which indicates the presence of the older 64-bit + format. As written, the code can't detect (old format) lengths + greater than 4GB. If it becomes necessary to handle lengths somewhat + larger than 4GB, we could allow other small values (such as the + non-sensical values of 1, 2, and 3) to also be used as escape values + indicating the presence of the old format. + The value returned via bytes_read should be used to increment the relevant pointer after calling read_initial_length(). @@ -3621,14 +4777,18 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, [ Note: read_initial_length() and read_offset() are based on the document entitled "DWARF Debugging Information Format", revision - 2.1, draft 4, dated July 20, 2000. This document was obtained + 3, draft 8, dated November 19, 2001. This document was obtained from: - http://reality.sgi.com/dehnert_engr/dwarf/dwarf2p1-draft4-000720.pdf + http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf This document is only a draft and is subject to change. (So beware.) - - Kevin, Aug 4, 2000 + Details regarding the older, non-standard 64-bit format were + determined empirically by examining 64-bit ELF files produced + by the SGI toolchain on an IRIX 6.5 machine. + + - Kevin, July 16, 2002 ] */ static LONGEST @@ -3649,6 +4809,18 @@ read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header, cu_header->offset_size = 8; } } + else if (retval == 0) + { + /* Handle (non-standard) 64-bit DWARF2 formats such as that used + by IRIX. */ + retval = bfd_get_64 (abfd, (bfd_byte *) buf); + *bytes_read = 8; + if (cu_header != NULL) + { + cu_header->initial_length_size = 8; + cu_header->offset_size = 8; + } + } else { *bytes_read = 4; @@ -3683,7 +4855,8 @@ read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, break; default: internal_error (__FILE__, __LINE__, - "read_offset: bad switch"); + "read_offset: bad switch [in module %s]", + bfd_get_filename (abfd)); } return retval; @@ -3725,12 +4898,14 @@ read_indirect_string (bfd *abfd, char *buf, if (dwarf_str_buffer == NULL) { - error ("DW_FORM_strp used without .debug_str section"); + error ("DW_FORM_strp used without .debug_str section [in module %s]", + bfd_get_filename (abfd)); return NULL; } if (str_offset >= dwarf_str_size) { - error ("DW_FORM_strp pointing outside of .debug_str section"); + error ("DW_FORM_strp pointing outside of .debug_str section [in module %s]", + bfd_get_filename (abfd)); return NULL; } gdb_assert (HOST_CHAR_BIT == 8); @@ -3800,44 +4975,45 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) } static void -set_cu_language (unsigned int lang) +set_cu_language (unsigned int lang, struct dwarf2_cu *cu) { switch (lang) { case DW_LANG_C89: case DW_LANG_C: - cu_language = language_c; + cu->language = language_c; break; case DW_LANG_C_plus_plus: - cu_language = language_cplus; + cu->language = language_cplus; break; case DW_LANG_Fortran77: case DW_LANG_Fortran90: case DW_LANG_Fortran95: - cu_language = language_fortran; + cu->language = language_fortran; break; case DW_LANG_Mips_Assembler: - cu_language = language_asm; + cu->language = language_asm; break; case DW_LANG_Java: - cu_language = language_java; + cu->language = language_java; break; case DW_LANG_Ada83: + case DW_LANG_Ada95: case DW_LANG_Cobol74: case DW_LANG_Cobol85: case DW_LANG_Pascal83: case DW_LANG_Modula2: default: - cu_language = language_unknown; + cu->language = language_minimal; break; } - cu_language_defn = language_def (cu_language); + cu->language_defn = language_def (cu->language); } /* Return the named attribute or NULL if not there. */ static struct attribute * -dwarf_attr (struct die_info *die, unsigned int name) +dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu) { unsigned int i; struct attribute *spec = NULL; @@ -3855,103 +5031,182 @@ dwarf_attr (struct die_info *die, unsigned int name) if (spec) { struct die_info *ref_die = - follow_die_ref (dwarf2_get_ref_die_offset (spec)); + follow_die_ref (dwarf2_get_ref_die_offset (spec, cu)); if (ref_die) - return dwarf_attr (ref_die, name); + return dwarf2_attr (ref_die, name, cu); } return NULL; } static int -die_is_declaration (struct die_info *die) +die_is_declaration (struct die_info *die, struct dwarf2_cu *cu) { - return (dwarf_attr (die, DW_AT_declaration) - && ! dwarf_attr (die, DW_AT_specification)); + return (dwarf2_attr (die, DW_AT_declaration, cu) + && ! dwarf2_attr (die, DW_AT_specification, cu)); } -/* Decode the line number information for the compilation unit whose - line number info is at OFFSET in the .debug_line section. - The compilation directory of the file is passed in COMP_DIR. */ +/* Return the die giving the specification for DIE, if there is + one. */ -struct filenames +static struct die_info * +die_specification (struct die_info *die, struct dwarf2_cu *cu) { - unsigned int num_files; - struct fileinfo - { - char *name; - unsigned int dir; - unsigned int time; - unsigned int size; - } - *files; -}; + struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, cu); -struct directories - { - unsigned int num_dirs; - char **dirs; - }; + if (spec_attr == NULL) + return NULL; + else + return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu)); +} +/* Free the line_header structure *LH, and any arrays and strings it + refers to. */ static void -dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, - const struct comp_unit_head *cu_header) +free_line_header (struct line_header *lh) +{ + if (lh->standard_opcode_lengths) + xfree (lh->standard_opcode_lengths); + + /* Remember that all the lh->file_names[i].name pointers are + pointers into debug_line_buffer, and don't need to be freed. */ + if (lh->file_names) + xfree (lh->file_names); + + /* Similarly for the include directory names. */ + if (lh->include_dirs) + xfree (lh->include_dirs); + + xfree (lh); +} + + +/* Add an entry to LH's include directory table. */ +static void +add_include_dir (struct line_header *lh, char *include_dir) +{ + /* Grow the array if necessary. */ + if (lh->include_dirs_size == 0) + { + lh->include_dirs_size = 1; /* for testing */ + lh->include_dirs = xmalloc (lh->include_dirs_size + * sizeof (*lh->include_dirs)); + } + else if (lh->num_include_dirs >= lh->include_dirs_size) + { + lh->include_dirs_size *= 2; + lh->include_dirs = xrealloc (lh->include_dirs, + (lh->include_dirs_size + * sizeof (*lh->include_dirs))); + } + + lh->include_dirs[lh->num_include_dirs++] = include_dir; +} + + +/* Add an entry to LH's file name table. */ +static void +add_file_name (struct line_header *lh, + char *name, + unsigned int dir_index, + unsigned int mod_time, + unsigned int length) +{ + struct file_entry *fe; + + /* Grow the array if necessary. */ + if (lh->file_names_size == 0) + { + lh->file_names_size = 1; /* for testing */ + lh->file_names = xmalloc (lh->file_names_size + * sizeof (*lh->file_names)); + } + else if (lh->num_file_names >= lh->file_names_size) + { + lh->file_names_size *= 2; + lh->file_names = xrealloc (lh->file_names, + (lh->file_names_size + * sizeof (*lh->file_names))); + } + + fe = &lh->file_names[lh->num_file_names++]; + fe->name = name; + fe->dir_index = dir_index; + fe->mod_time = mod_time; + fe->length = length; +} + + +/* Read the statement program header starting at OFFSET in + dwarf_line_buffer, according to the endianness of ABFD. Return a + pointer to a struct line_header, allocated using xmalloc. + + NOTE: the strings in the include directory and file name tables of + the returned object point into debug_line_buffer, and must not be + freed. */ +static struct line_header * +dwarf_decode_line_header (unsigned int offset, bfd *abfd, + struct dwarf2_cu *cu) { - char *line_ptr; - char *line_end; - struct line_head lh; struct cleanup *back_to; - unsigned int i, bytes_read; - char *cur_file, *cur_dir; - unsigned char op_code, extended_op, adj_opcode; - -#define FILE_ALLOC_CHUNK 5 -#define DIR_ALLOC_CHUNK 5 - - struct filenames files; - struct directories dirs; + struct line_header *lh; + char *line_ptr; + int bytes_read; + int i; + char *cur_dir, *cur_file; if (dwarf_line_buffer == NULL) { - complain (&dwarf2_missing_line_number_section); - return; + complaint (&symfile_complaints, "missing .debug_line section"); + return 0; } - files.num_files = 0; - files.files = NULL; + /* Make sure that at least there's room for the total_length field. That + could be 12 bytes long, but we're just going to fudge that. */ + if (offset + 4 >= dwarf_line_size) + { + dwarf2_statement_list_fits_in_line_number_section_complaint (); + return 0; + } - dirs.num_dirs = 0; - dirs.dirs = NULL; + lh = xmalloc (sizeof (*lh)); + memset (lh, 0, sizeof (*lh)); + back_to = make_cleanup ((make_cleanup_ftype *) free_line_header, + (void *) lh); line_ptr = dwarf_line_buffer + offset; - /* read in the prologue */ - lh.total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read); + /* read in the header */ + lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read); line_ptr += bytes_read; - line_end = line_ptr + lh.total_length; - lh.version = read_2_bytes (abfd, line_ptr); - line_ptr += 2; - lh.prologue_length = read_offset (abfd, line_ptr, cu_header, &bytes_read); - line_ptr += bytes_read; - lh.minimum_instruction_length = read_1_byte (abfd, line_ptr); - line_ptr += 1; - lh.default_is_stmt = read_1_byte (abfd, line_ptr); - line_ptr += 1; - lh.line_base = read_1_signed_byte (abfd, line_ptr); - line_ptr += 1; - lh.line_range = read_1_byte (abfd, line_ptr); - line_ptr += 1; - lh.opcode_base = read_1_byte (abfd, line_ptr); - line_ptr += 1; - lh.standard_opcode_lengths = (unsigned char *) - xmalloc (lh.opcode_base * sizeof (unsigned char)); - back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths); - - lh.standard_opcode_lengths[0] = 1; - for (i = 1; i < lh.opcode_base; ++i) + if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size) { - lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr); + dwarf2_statement_list_fits_in_line_number_section_complaint (); + return 0; + } + lh->statement_program_end = line_ptr + lh->total_length; + lh->version = read_2_bytes (abfd, line_ptr); + line_ptr += 2; + lh->header_length = read_offset (abfd, line_ptr, &cu->header, &bytes_read); + line_ptr += bytes_read; + lh->minimum_instruction_length = read_1_byte (abfd, line_ptr); + line_ptr += 1; + lh->default_is_stmt = read_1_byte (abfd, line_ptr); + line_ptr += 1; + lh->line_base = read_1_signed_byte (abfd, line_ptr); + line_ptr += 1; + lh->line_range = read_1_byte (abfd, line_ptr); + line_ptr += 1; + lh->opcode_base = read_1_byte (abfd, line_ptr); + line_ptr += 1; + lh->standard_opcode_lengths + = (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char)); + + lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */ + for (i = 1; i < lh->opcode_base; ++i) + { + lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr); line_ptr += 1; } @@ -3959,44 +5214,101 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL) { line_ptr += bytes_read; - if ((dirs.num_dirs % DIR_ALLOC_CHUNK) == 0) - { - dirs.dirs = (char **) - xrealloc (dirs.dirs, - (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *)); - if (dirs.num_dirs == 0) - make_cleanup (free_current_contents, &dirs.dirs); - } - dirs.dirs[dirs.num_dirs++] = cur_dir; + add_include_dir (lh, cur_dir); } line_ptr += bytes_read; /* Read file name table */ while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL) { + unsigned int dir_index, mod_time, length; + line_ptr += bytes_read; - if ((files.num_files % FILE_ALLOC_CHUNK) == 0) - { - files.files = (struct fileinfo *) - xrealloc (files.files, - (files.num_files + FILE_ALLOC_CHUNK) - * sizeof (struct fileinfo)); - if (files.num_files == 0) - make_cleanup (free_current_contents, &files.files); - } - files.files[files.num_files].name = cur_file; - files.files[files.num_files].dir = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - files.files[files.num_files].time = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - files.files[files.num_files].size = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - files.num_files++; + + add_file_name (lh, cur_file, dir_index, mod_time, length); } line_ptr += bytes_read; + lh->statement_program_start = line_ptr; + + if (line_ptr > dwarf_line_buffer + dwarf_line_size) + complaint (&symfile_complaints, + "line number info header doesn't fit in `.debug_line' section"); + + discard_cleanups (back_to); + return lh; +} + +/* This function exists to work around a bug in certain compilers + (particularly GCC 2.95), in which the first line number marker of a + function does not show up until after the prologue, right before + the second line number marker. This function shifts ADDRESS down + to the beginning of the function if necessary, and is called on + addresses passed to record_line. */ + +static CORE_ADDR +check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu) +{ + struct function_range *fn; + + /* Find the function_range containing address. */ + if (!cu->first_fn) + return address; + + if (!cu->cached_fn) + cu->cached_fn = cu->first_fn; + + fn = cu->cached_fn; + while (fn) + if (fn->lowpc <= address && fn->highpc > address) + goto found; + else + fn = fn->next; + + fn = cu->first_fn; + while (fn && fn != cu->cached_fn) + if (fn->lowpc <= address && fn->highpc > address) + goto found; + else + fn = fn->next; + + return address; + + found: + if (fn->seen_line) + return address; + if (address != fn->lowpc) + complaint (&symfile_complaints, + "misplaced first line number at 0x%lx for '%s'", + (unsigned long) address, fn->name); + fn->seen_line = 1; + return fn->lowpc; +} + +/* Decode the line number information for the compilation unit whose + line number info is at OFFSET in the .debug_line section. + The compilation directory of the file is passed in COMP_DIR. */ + +static void +dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, + struct dwarf2_cu *cu) +{ + char *line_ptr; + char *line_end; + unsigned int bytes_read; + unsigned char op_code, extended_op, adj_opcode; + CORE_ADDR baseaddr; + struct objfile *objfile = cu->objfile; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + line_ptr = lh->statement_program_start; + line_end = lh->statement_program_end; /* Read the statement sequences until there's nothing left. */ while (line_ptr < line_end) @@ -4006,19 +5318,23 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, unsigned int file = 1; unsigned int line = 1; unsigned int column = 0; - int is_stmt = lh.default_is_stmt; + int is_stmt = lh->default_is_stmt; int basic_block = 0; int end_sequence = 0; /* Start a subfile for the current file of the state machine. */ - if (files.num_files >= file) + if (lh->num_file_names >= file) { - /* The file and directory tables are 0 based, the references - are 1 based. */ - dwarf2_start_subfile (files.files[file - 1].name, - (files.files[file - 1].dir - ? dirs.dirs[files.files[file - 1].dir - 1] - : comp_dir)); + /* lh->include_dirs and lh->file_names are 0-based, but the + directory and file name numbers in the statement program + are 1-based. */ + struct file_entry *fe = &lh->file_names[file - 1]; + char *dir; + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + else + dir = comp_dir; + dwarf2_start_subfile (fe->name, dir); } /* Decode the table. */ @@ -4027,14 +5343,15 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, op_code = read_1_byte (abfd, line_ptr); line_ptr += 1; - if (op_code >= lh.opcode_base) + if (op_code >= lh->opcode_base) { /* Special operand. */ - adj_opcode = op_code - lh.opcode_base; - address += (adj_opcode / lh.line_range) - * lh.minimum_instruction_length; - line += lh.line_base + (adj_opcode % lh.line_range); + adj_opcode = op_code - lh->opcode_base; + address += (adj_opcode / lh->line_range) + * lh->minimum_instruction_length; + line += lh->line_base + (adj_opcode % lh->line_range); /* append row to matrix using current values */ - record_line (current_subfile, line, address); + record_line (current_subfile, line, + check_cu_functions (address, cu)); basic_block = 1; } else switch (op_code) @@ -4047,53 +5364,45 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, { case DW_LNE_end_sequence: end_sequence = 1; - /* Don't call record_line here. The end_sequence - instruction provides the address of the first byte - *after* the last line in the sequence; it's not the - address of any real source line. However, the GDB - linetable structure only records the starts of lines, - not the ends. This is a weakness of GDB. */ + record_line (current_subfile, 0, address); break; case DW_LNE_set_address: - address = read_address (abfd, line_ptr, cu_header, &bytes_read); + address = read_address (abfd, line_ptr, cu, &bytes_read); line_ptr += bytes_read; address += baseaddr; break; case DW_LNE_define_file: - cur_file = read_string (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - if ((files.num_files % FILE_ALLOC_CHUNK) == 0) - { - files.files = (struct fileinfo *) - xrealloc (files.files, - (files.num_files + FILE_ALLOC_CHUNK) - * sizeof (struct fileinfo)); - if (files.num_files == 0) - make_cleanup (free_current_contents, &files.files); - } - files.files[files.num_files].name = cur_file; - files.files[files.num_files].dir = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - files.files[files.num_files].time = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - files.files[files.num_files].size = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - files.num_files++; + { + char *cur_file; + unsigned int dir_index, mod_time, length; + + cur_file = read_string (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + dir_index = + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + mod_time = + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + length = + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + add_file_name (lh, cur_file, dir_index, mod_time, length); + } break; default: - complain (&dwarf2_mangled_line_number_section); - goto done; + complaint (&symfile_complaints, + "mangled .debug_line section"); + return; } break; case DW_LNS_copy: - record_line (current_subfile, line, address); + record_line (current_subfile, line, + check_cu_functions (address, cu)); basic_block = 0; break; case DW_LNS_advance_pc: - address += lh.minimum_instruction_length + address += lh->minimum_instruction_length * read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; break; @@ -4102,15 +5411,21 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, line_ptr += bytes_read; break; case DW_LNS_set_file: - /* The file and directory tables are 0 based, the references - are 1 based. */ - file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - dwarf2_start_subfile - (files.files[file - 1].name, - (files.files[file - 1].dir - ? dirs.dirs[files.files[file - 1].dir - 1] - : comp_dir)); + { + /* lh->include_dirs and lh->file_names are 0-based, + but the directory and file name numbers in the + statement program are 1-based. */ + struct file_entry *fe; + char *dir; + file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + fe = &lh->file_names[file - 1]; + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + else + dir = comp_dir; + dwarf2_start_subfile (fe->name, dir); + } break; case DW_LNS_set_column: column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); @@ -4128,8 +5443,8 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, length since special opcode 255 would have scaled the the increment. */ case DW_LNS_const_add_pc: - address += (lh.minimum_instruction_length - * ((255 - lh.opcode_base) / lh.line_range)); + address += (lh->minimum_instruction_length + * ((255 - lh->opcode_base) / lh->line_range)); break; case DW_LNS_fixed_advance_pc: address += read_2_bytes (abfd, line_ptr); @@ -4138,7 +5453,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, default: { /* Unknown standard opcode, ignore it. */ int i; - for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++) + for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++) { (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; @@ -4147,8 +5462,6 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, } } } -done: - do_cleanups (back_to); } /* Start a subfile for DWARF. FILENAME is the name of the file and @@ -4196,6 +5509,62 @@ dwarf2_start_subfile (char *filename, char *dirname) start_subfile (filename, dirname); } +static void +var_decode_location (struct attribute *attr, struct symbol *sym, + struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; + + /* NOTE drow/2003-01-30: There used to be a comment and some special + code here to turn a symbol with DW_AT_external and a + SYMBOL_VALUE_ADDRESS of 0 into a LOC_UNRESOLVED symbol. This was + necessary for platforms (maybe Alpha, certainly PowerPC GNU/Linux + with some versions of binutils) where shared libraries could have + relocations against symbols in their debug information - the + minimal symbol would have the right address, but the debug info + would not. It's no longer necessary, because we will explicitly + apply relocations when we read in the debug information now. */ + + /* A DW_AT_location attribute with no contents indicates that a + variable has been optimized away. */ + if (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0) + { + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; + return; + } + + /* Handle one degenerate form of location expression specially, to + preserve GDB's previous behavior when section offsets are + specified. If this is just a DW_OP_addr then mark this symbol + as LOC_STATIC. */ + + if (attr_form_is_block (attr) + && DW_BLOCK (attr)->size == 1 + cu_header->addr_size + && DW_BLOCK (attr)->data[0] == DW_OP_addr) + { + int dummy; + + SYMBOL_VALUE_ADDRESS (sym) = + read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy); + fixup_symbol_section (sym, objfile); + SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, + SYMBOL_SECTION (sym)); + SYMBOL_CLASS (sym) = LOC_STATIC; + return; + } + + /* NOTE drow/2002-01-30: It might be worthwhile to have a static + expression evaluator, and use LOC_COMPUTED only when necessary + (i.e. when the value of a register or memory location is + referenced, or a thread-local block, etc.). Then again, it might + not be worthwhile. I'm assuming that it isn't unless performance + or memory numbers show me otherwise. */ + + dwarf2_symbol_mark_computed (attr, sym, cu); + SYMBOL_CLASS (sym) = LOC_COMPUTED; +} + /* Given a pointer to a DWARF information entry, figure out if we need to make a symbol table entry for it, and if so, create a new entry and return a pointer to it. @@ -4203,51 +5572,50 @@ dwarf2_start_subfile (char *filename, char *dirname) used the passed type. */ static struct symbol * -new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, - const struct comp_unit_head *cu_header) +new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct symbol *sym = NULL; char *name; struct attribute *attr = NULL; struct attribute *attr2 = NULL; - CORE_ADDR addr; + CORE_ADDR baseaddr; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + if (die->tag != DW_TAG_namespace) + name = dwarf2_linkage_name (die, cu); + else + name = TYPE_NAME (type); - name = dwarf2_linkage_name (die); if (name) { - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); OBJSTAT (objfile, n_syms++); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - &objfile->symbol_obstack); + + /* Cache this symbol's name and the name's demangled form (if any). */ + SYMBOL_LANGUAGE (sym) = cu->language; + SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); /* Default assumptions. Use the passed type or decode it from the die. */ - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_CLASS (sym) = LOC_STATIC; if (type != NULL) SYMBOL_TYPE (sym) = type; else - SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header); - attr = dwarf_attr (die, DW_AT_decl_line); + SYMBOL_TYPE (sym) = die_type (die, cu); + attr = dwarf2_attr (die, DW_AT_decl_line, cu); if (attr) { SYMBOL_LINE (sym) = DW_UNSND (attr); } - - /* If this symbol is from a C++ compilation, then attempt to - cache the demangled form for future reference. This is a - typical time versus space tradeoff, that was decided in favor - of time because it sped up C++ symbol lookups by a factor of - about 20. */ - - SYMBOL_LANGUAGE (sym) = cu_language; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); switch (die->tag) { case DW_TAG_label: - attr = dwarf_attr (die, DW_AT_low_pc); + attr = dwarf2_attr (die, DW_AT_low_pc, cu); if (attr) { SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr; @@ -4258,14 +5626,14 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by finish_block. */ SYMBOL_CLASS (sym) = LOC_BLOCK; - attr2 = dwarf_attr (die, DW_AT_external); + attr2 = dwarf2_attr (die, DW_AT_external, cu); if (attr2 && (DW_UNSND (attr2) != 0)) { add_symbol_to_list (sym, &global_symbols); } else { - add_symbol_to_list (sym, list_in_scope); + add_symbol_to_list (sym, cu->list_in_scope); } break; case DW_TAG_variable: @@ -4277,78 +5645,26 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, TARGET_INT_BIT / HOST_CHAR_BIT, 0, "", objfile); - attr = dwarf_attr (die, DW_AT_const_value); + attr = dwarf2_attr (die, DW_AT_const_value, cu); if (attr) { - dwarf2_const_value (attr, sym, objfile, cu_header); - attr2 = dwarf_attr (die, DW_AT_external); + dwarf2_const_value (attr, sym, cu); + attr2 = dwarf2_attr (die, DW_AT_external, cu); if (attr2 && (DW_UNSND (attr2) != 0)) add_symbol_to_list (sym, &global_symbols); else - add_symbol_to_list (sym, list_in_scope); + add_symbol_to_list (sym, cu->list_in_scope); break; } - attr = dwarf_attr (die, DW_AT_location); + attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) { - attr2 = dwarf_attr (die, DW_AT_external); + var_decode_location (attr, sym, cu); + attr2 = dwarf2_attr (die, DW_AT_external, cu); if (attr2 && (DW_UNSND (attr2) != 0)) - { - SYMBOL_VALUE_ADDRESS (sym) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - add_symbol_to_list (sym, &global_symbols); - - /* In shared libraries the address of the variable - in the location descriptor might still be relocatable, - so its value could be zero. - Enter the symbol as a LOC_UNRESOLVED symbol, if its - value is zero, the address of the variable will then - be determined from the minimal symbol table whenever - the variable is referenced. */ - if (SYMBOL_VALUE_ADDRESS (sym)) - { - fixup_symbol_section (sym, objfile); - SYMBOL_VALUE_ADDRESS (sym) += - ANOFFSET (objfile->section_offsets, - SYMBOL_SECTION (sym)); - SYMBOL_CLASS (sym) = LOC_STATIC; - } - else - SYMBOL_CLASS (sym) = LOC_UNRESOLVED; - } + add_symbol_to_list (sym, &global_symbols); else - { - SYMBOL_VALUE (sym) = addr = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - add_symbol_to_list (sym, list_in_scope); - if (optimized_out) - { - SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - } - else if (isreg) - { - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_VALUE (sym) = - DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); - } - else if (offreg) - { - SYMBOL_CLASS (sym) = LOC_BASEREG; - SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); - } - else if (islocal) - { - SYMBOL_CLASS (sym) = LOC_LOCAL; - } - else - { - fixup_symbol_section (sym, objfile); - SYMBOL_VALUE_ADDRESS (sym) = - addr + ANOFFSET (objfile->section_offsets, - SYMBOL_SECTION (sym)); - SYMBOL_CLASS (sym) = LOC_STATIC; - } - } + add_symbol_to_list (sym, cu->list_in_scope); } else { @@ -4358,9 +5674,9 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, The address of the variable will then be determined from the minimal symbol table whenever the variable is referenced. */ - attr2 = dwarf_attr (die, DW_AT_external); + attr2 = dwarf2_attr (die, DW_AT_external, cu); if (attr2 && (DW_UNSND (attr2) != 0) - && dwarf_attr (die, DW_AT_type) != NULL) + && dwarf2_attr (die, DW_AT_type, cu) != NULL) { SYMBOL_CLASS (sym) = LOC_UNRESOLVED; add_symbol_to_list (sym, &global_symbols); @@ -4368,42 +5684,20 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, } break; case DW_TAG_formal_parameter: - attr = dwarf_attr (die, DW_AT_location); + attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) { - SYMBOL_VALUE (sym) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - if (isreg) - { - SYMBOL_CLASS (sym) = LOC_REGPARM; - SYMBOL_VALUE (sym) = - DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); - } - else if (offreg) - { - if (isderef) - { - if (basereg != frame_base_reg) - complain (&dwarf2_complex_location_expr); - SYMBOL_CLASS (sym) = LOC_REF_ARG; - } - else - { - SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; - SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); - } - } - else - { - SYMBOL_CLASS (sym) = LOC_ARG; - } + var_decode_location (attr, sym, cu); + /* FIXME drow/2003-07-31: Is LOC_COMPUTED_ARG necessary? */ + if (SYMBOL_CLASS (sym) == LOC_COMPUTED) + SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG; } - attr = dwarf_attr (die, DW_AT_const_value); + attr = dwarf2_attr (die, DW_AT_const_value, cu); if (attr) { - dwarf2_const_value (attr, sym, objfile, cu_header); + dwarf2_const_value (attr, sym, cu); } - add_symbol_to_list (sym, list_in_scope); + add_symbol_to_list (sym, cu->list_in_scope); break; case DW_TAG_unspecified_parameters: /* From varargs functions; gdb doesn't seem to have any @@ -4415,47 +5709,122 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, case DW_TAG_union_type: case DW_TAG_enumeration_type: SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - add_symbol_to_list (sym, list_in_scope); + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; - /* The semantics of C++ state that "struct foo { ... }" also - defines a typedef for "foo". Synthesize a typedef symbol so - that "ptype foo" works as expected. */ - if (cu_language == language_cplus) + /* Make sure that the symbol includes appropriate enclosing + classes/namespaces in its name. These are calculated in + read_structure_type, and the correct name is saved in + the type. */ + + if (cu->language == language_cplus) { - struct symbol *typedef_sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - *typedef_sym = *sym; - SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE; - if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) = - obsavestring (SYMBOL_NAME (sym), - strlen (SYMBOL_NAME (sym)), - &objfile->type_obstack); - add_symbol_to_list (typedef_sym, list_in_scope); + struct type *type = SYMBOL_TYPE (sym); + + if (TYPE_TAG_NAME (type) != NULL) + { + /* FIXME: carlton/2003-11-10: Should this use + SYMBOL_SET_NAMES instead? (The same problem also + arises a further down in the function.) */ + SYMBOL_LINKAGE_NAME (sym) + = obsavestring (TYPE_TAG_NAME (type), + strlen (TYPE_TAG_NAME (type)), + &objfile->objfile_obstack); + } } + + { + /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't + really ever be static objects: otherwise, if you try + to, say, break of a class's method and you're in a file + which doesn't mention that class, it won't work unless + the check for all static symbols in lookup_symbol_aux + saves you. See the OtherFileClass tests in + gdb.c++/namespace.exp. */ + + struct pending **list_to_add; + + list_to_add = (cu->list_in_scope == &file_symbols + && cu->language == language_cplus + ? &global_symbols : cu->list_in_scope); + + add_symbol_to_list (sym, list_to_add); + + /* The semantics of C++ state that "struct foo { ... }" also + defines a typedef for "foo". Synthesize a typedef symbol so + that "ptype foo" works as expected. */ + if (cu->language == language_cplus) + { + struct symbol *typedef_sym = (struct symbol *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symbol)); + *typedef_sym = *sym; + SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN; + if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) + TYPE_NAME (SYMBOL_TYPE (sym)) = + obsavestring (SYMBOL_NATURAL_NAME (sym), + strlen (SYMBOL_NATURAL_NAME (sym)), + &objfile->objfile_obstack); + add_symbol_to_list (typedef_sym, list_to_add); + } + } break; case DW_TAG_typedef: - case DW_TAG_base_type: + if (processing_has_namespace_info + && processing_current_prefix[0] != '\0') + { + SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack, + processing_current_prefix, + "::", + name); + } SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, list_in_scope); + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + add_symbol_to_list (sym, cu->list_in_scope); + break; + case DW_TAG_base_type: + case DW_TAG_subrange_type: + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + add_symbol_to_list (sym, cu->list_in_scope); break; case DW_TAG_enumerator: - attr = dwarf_attr (die, DW_AT_const_value); + if (processing_has_namespace_info + && processing_current_prefix[0] != '\0') + { + SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack, + processing_current_prefix, + "::", + name); + } + attr = dwarf2_attr (die, DW_AT_const_value, cu); if (attr) { - dwarf2_const_value (attr, sym, objfile, cu_header); + dwarf2_const_value (attr, sym, cu); } - add_symbol_to_list (sym, list_in_scope); + { + /* NOTE: carlton/2003-11-10: See comment above in the + DW_TAG_class_type, etc. block. */ + + struct pending **list_to_add; + + list_to_add = (cu->list_in_scope == &file_symbols + && cu->language == language_cplus + ? &global_symbols : cu->list_in_scope); + + add_symbol_to_list (sym, list_to_add); + } + break; + case DW_TAG_namespace: + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + add_symbol_to_list (sym, &global_symbols); break; default: /* Not a tag we recognize. Hopefully we aren't processing trash data, but since we must specifically ignore things we don't recognize, there is nothing else we should do at this point. */ - complain (&dwarf2_unsupported_tag, dwarf_tag_name (die->tag)); + complaint (&symfile_complaints, "unsupported tag: '%s'", + dwarf_tag_name (die->tag)); break; } } @@ -4466,21 +5835,26 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, static void dwarf2_const_value (struct attribute *attr, struct symbol *sym, - struct objfile *objfile, - const struct comp_unit_head *cu_header) + struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; struct dwarf_block *blk; switch (attr->form) { case DW_FORM_addr: if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size) - complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym), - cu_header->addr_size, TYPE_LENGTH (SYMBOL_TYPE (sym))); + dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym), + cu_header->addr_size, + TYPE_LENGTH (SYMBOL_TYPE + (sym))); SYMBOL_VALUE_BYTES (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size); - store_address (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size, - DW_ADDR (attr)); + obstack_alloc (&objfile->objfile_obstack, cu_header->addr_size); + /* NOTE: cagney/2003-05-09: In-lined store_address call with + it's body - store_unsigned_integer. */ + store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size, + DW_ADDR (attr)); SYMBOL_CLASS (sym) = LOC_CONST_BYTES; break; case DW_FORM_block1: @@ -4489,10 +5863,12 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, case DW_FORM_block: blk = DW_BLOCK (attr); if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size) - complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym), - blk->size, TYPE_LENGTH (SYMBOL_TYPE (sym))); + dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym), + blk->size, + TYPE_LENGTH (SYMBOL_TYPE + (sym))); SYMBOL_VALUE_BYTES (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, blk->size); + obstack_alloc (&objfile->objfile_obstack, blk->size); memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size); SYMBOL_CLASS (sym) = LOC_CONST_BYTES; break; @@ -4526,8 +5902,9 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, break; default: - complain (&dwarf2_unsupported_const_value_attr, - dwarf_form_name (attr->form)); + complaint (&symfile_complaints, + "unsupported const value attribute form: '%s'", + dwarf_form_name (attr->form)); SYMBOL_VALUE (sym) = 0; SYMBOL_CLASS (sym) = LOC_CONST; break; @@ -4560,35 +5937,36 @@ dwarf2_const_value_data (struct attribute *attr, /* Return the type of the die in question using its DW_AT_type attribute. */ static struct type * -die_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +die_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *type; struct attribute *type_attr; struct die_info *type_die; unsigned int ref; - type_attr = dwarf_attr (die, DW_AT_type); + type_attr = dwarf2_attr (die, DW_AT_type, cu); if (!type_attr) { /* A missing DW_AT_type represents a void type. */ - return dwarf2_fundamental_type (objfile, FT_VOID); + return dwarf2_fundamental_type (cu->objfile, FT_VOID, cu); } else { - ref = dwarf2_get_ref_die_offset (type_attr); + ref = dwarf2_get_ref_die_offset (type_attr, cu); type_die = follow_die_ref (ref); if (!type_die) { - error ("Dwarf Error: Cannot find referent at offset %d.", ref); + error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", + ref, cu->objfile->name); return NULL; } } - type = tag_type_to_type (type_die, objfile, cu_header); + type = tag_type_to_type (type_die, cu); if (!type) { dump_die (type_die); - error ("Dwarf Error: Problem turning type die at offset into gdb type."); + error ("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]", + cu->objfile->name); } return type; } @@ -4597,38 +5975,39 @@ die_type (struct die_info *die, struct objfile *objfile, DW_AT_containing_type attribute. */ static struct type * -die_containing_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +die_containing_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *type = NULL; struct attribute *type_attr; struct die_info *type_die = NULL; unsigned int ref; - type_attr = dwarf_attr (die, DW_AT_containing_type); + type_attr = dwarf2_attr (die, DW_AT_containing_type, cu); if (type_attr) { - ref = dwarf2_get_ref_die_offset (type_attr); + ref = dwarf2_get_ref_die_offset (type_attr, cu); type_die = follow_die_ref (ref); if (!type_die) { - error ("Dwarf Error: Cannot find referent at offset %d.", ref); + error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, + cu->objfile->name); return NULL; } - type = tag_type_to_type (type_die, objfile, cu_header); + type = tag_type_to_type (type_die, cu); } if (!type) { if (type_die) dump_die (type_die); - error ("Dwarf Error: Problem turning containing type into gdb type."); + error ("Dwarf Error: Problem turning containing type into gdb type [in module %s]", + cu->objfile->name); } return type; } #if 0 static struct type * -type_at_offset (unsigned int offset, struct objfile *objfile) +type_at_offset (unsigned int offset, struct dwarf2_cu *cu) { struct die_info *die; struct type *type; @@ -4639,14 +6018,13 @@ type_at_offset (unsigned int offset, struct objfile *objfile) error ("Dwarf Error: Cannot find type referent at offset %d.", offset); return NULL; } - type = tag_type_to_type (die, objfile); + type = tag_type_to_type (die, cu); return type; } #endif static struct type * -tag_type_to_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu) { if (die->type) { @@ -4654,139 +6032,245 @@ tag_type_to_type (struct die_info *die, struct objfile *objfile, } else { - read_type_die (die, objfile, cu_header); + read_type_die (die, cu); if (!die->type) { dump_die (die); - error ("Dwarf Error: Cannot find type of die."); + error ("Dwarf Error: Cannot find type of die [in module %s]", + cu->objfile->name); } return die->type; } } static void -read_type_die (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_type_die (struct die_info *die, struct dwarf2_cu *cu) { + char *prefix = determine_prefix (die, cu); + const char *old_prefix = processing_current_prefix; + struct cleanup *back_to = make_cleanup (xfree, prefix); + processing_current_prefix = prefix; + switch (die->tag) { case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: - read_structure_scope (die, objfile, cu_header); + read_structure_type (die, cu); break; case DW_TAG_enumeration_type: - read_enumeration (die, objfile, cu_header); + read_enumeration_type (die, cu); break; case DW_TAG_subprogram: case DW_TAG_subroutine_type: - read_subroutine_type (die, objfile, cu_header); + read_subroutine_type (die, cu); break; case DW_TAG_array_type: - read_array_type (die, objfile, cu_header); + read_array_type (die, cu); break; case DW_TAG_pointer_type: - read_tag_pointer_type (die, objfile, cu_header); + read_tag_pointer_type (die, cu); break; case DW_TAG_ptr_to_member_type: - read_tag_ptr_to_member_type (die, objfile, cu_header); + read_tag_ptr_to_member_type (die, cu); break; case DW_TAG_reference_type: - read_tag_reference_type (die, objfile, cu_header); + read_tag_reference_type (die, cu); break; case DW_TAG_const_type: - read_tag_const_type (die, objfile, cu_header); + read_tag_const_type (die, cu); break; case DW_TAG_volatile_type: - read_tag_volatile_type (die, objfile, cu_header); + read_tag_volatile_type (die, cu); break; case DW_TAG_string_type: - read_tag_string_type (die, objfile); + read_tag_string_type (die, cu); break; case DW_TAG_typedef: - read_typedef (die, objfile, cu_header); + read_typedef (die, cu); + break; + case DW_TAG_subrange_type: + read_subrange_type (die, cu); break; case DW_TAG_base_type: - read_base_type (die, objfile); + read_base_type (die, cu); break; default: - complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag)); + complaint (&symfile_complaints, "unexepected tag in read_type_die: '%s'", + dwarf_tag_name (die->tag)); break; } + + processing_current_prefix = old_prefix; + do_cleanups (back_to); +} + +/* Return the name of the namespace/class that DIE is defined within, + or "" if we can't tell. The caller should xfree the result. */ + +/* NOTE: carlton/2004-01-23: See read_func_scope (and the comment + therein) for an example of how to use this function to deal with + DW_AT_specification. */ + +static char * +determine_prefix (struct die_info *die, struct dwarf2_cu *cu) +{ + struct die_info *parent; + + if (cu->language != language_cplus) + return NULL; + + parent = die->parent; + + if (parent == NULL) + { + return xstrdup (""); + } + else + { + switch (parent->tag) { + case DW_TAG_namespace: + { + /* FIXME: carlton/2004-03-05: Should I follow extension dies + before doing this check? */ + if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL) + { + return xstrdup (TYPE_TAG_NAME (parent->type)); + } + else + { + int dummy; + char *parent_prefix = determine_prefix (parent, cu); + char *retval = typename_concat (parent_prefix, + namespace_name (parent, &dummy, + cu)); + xfree (parent_prefix); + return retval; + } + } + break; + case DW_TAG_class_type: + case DW_TAG_structure_type: + { + if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL) + { + return xstrdup (TYPE_TAG_NAME (parent->type)); + } + else + { + const char *old_prefix = processing_current_prefix; + char *new_prefix = determine_prefix (parent, cu); + char *retval; + + processing_current_prefix = new_prefix; + retval = determine_class_name (parent, cu); + processing_current_prefix = old_prefix; + + xfree (new_prefix); + return retval; + } + } + default: + return determine_prefix (parent, cu); + } + } +} + +/* Return a newly-allocated string formed by concatenating PREFIX, + "::", and SUFFIX, except that if PREFIX is NULL or the empty + string, just return a copy of SUFFIX. */ + +static char * +typename_concat (const char *prefix, const char *suffix) +{ + if (prefix == NULL || prefix[0] == '\0') + return xstrdup (suffix); + else + { + char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1); + + strcpy (retval, prefix); + strcat (retval, "::"); + strcat (retval, suffix); + + return retval; + } } static struct type * -dwarf_base_type (int encoding, int size, struct objfile *objfile) +dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + /* FIXME - this should not produce a new (struct type *) every time. It should cache base types. */ struct type *type; switch (encoding) { case DW_ATE_address: - type = dwarf2_fundamental_type (objfile, FT_VOID); + type = dwarf2_fundamental_type (objfile, FT_VOID, cu); return type; case DW_ATE_boolean: - type = dwarf2_fundamental_type (objfile, FT_BOOLEAN); + type = dwarf2_fundamental_type (objfile, FT_BOOLEAN, cu); return type; case DW_ATE_complex_float: if (size == 16) { - type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX); + type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX, cu); } else { - type = dwarf2_fundamental_type (objfile, FT_COMPLEX); + type = dwarf2_fundamental_type (objfile, FT_COMPLEX, cu); } return type; case DW_ATE_float: if (size == 8) { - type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT); + type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu); } else { - type = dwarf2_fundamental_type (objfile, FT_FLOAT); + type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu); } return type; case DW_ATE_signed: switch (size) { case 1: - type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR); + type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu); break; case 2: - type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT); + type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT, cu); break; default: case 4: - type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER); + type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu); break; } return type; case DW_ATE_signed_char: - type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR); + type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu); return type; case DW_ATE_unsigned: switch (size) { case 1: - type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR); + type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu); break; case 2: - type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT); + type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT, cu); break; default: case 4: - type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER); + type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER, cu); break; } return type; case DW_ATE_unsigned_char: - type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR); + type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu); return type; default: - type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER); + type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu); return type; } } @@ -4829,65 +6313,66 @@ copy_die (struct die_info *old_die) static struct die_info * sibling_die (struct die_info *die) { - int nesting_level = 0; - - if (!die->has_children) - { - if (die->next && (die->next->tag == 0)) - { - return NULL; - } - else - { - return die->next; - } - } - else - { - do - { - if (die->has_children) - { - nesting_level++; - } - if (die->tag == 0) - { - nesting_level--; - } - die = die->next; - } - while (nesting_level); - if (die && (die->tag == 0)) - { - return NULL; - } - else - { - return die; - } - } + return die->sibling; } /* Get linkage name of a die, return NULL if not found. */ static char * -dwarf2_linkage_name (struct die_info *die) +dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *attr; - attr = dwarf_attr (die, DW_AT_MIPS_linkage_name); + attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); if (attr && DW_STRING (attr)) return DW_STRING (attr); - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) return DW_STRING (attr); return NULL; } +/* Get name of a die, return NULL if not found. */ + +static char * +dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + + attr = dwarf2_attr (die, DW_AT_name, cu); + if (attr && DW_STRING (attr)) + return DW_STRING (attr); + return NULL; +} + +/* Return the die that this die in an extension of, or NULL if there + is none. */ + +static struct die_info * +dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + struct die_info *extension_die; + unsigned int ref; + + attr = dwarf2_attr (die, DW_AT_extension, cu); + if (attr == NULL) + return NULL; + + ref = dwarf2_get_ref_die_offset (attr, cu); + extension_die = follow_die_ref (ref); + if (!extension_die) + { + error ("Dwarf Error: Cannot find referent at offset %d.", ref); + } + + return extension_die; +} + /* Convert a DIE tag into its string name. */ static char * -dwarf_tag_name (register unsigned tag) +dwarf_tag_name (unsigned tag) { switch (tag) { @@ -4987,6 +6472,22 @@ dwarf_tag_name (register unsigned tag) return "DW_TAG_variable"; case DW_TAG_volatile_type: return "DW_TAG_volatile_type"; + case DW_TAG_dwarf_procedure: + return "DW_TAG_dwarf_procedure"; + case DW_TAG_restrict_type: + return "DW_TAG_restrict_type"; + case DW_TAG_interface_type: + return "DW_TAG_interface_type"; + case DW_TAG_namespace: + return "DW_TAG_namespace"; + case DW_TAG_imported_module: + return "DW_TAG_imported_module"; + case DW_TAG_unspecified_type: + return "DW_TAG_unspecified_type"; + case DW_TAG_partial_unit: + return "DW_TAG_partial_unit"; + case DW_TAG_imported_unit: + return "DW_TAG_imported_unit"; case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; case DW_TAG_format_label: @@ -5003,7 +6504,7 @@ dwarf_tag_name (register unsigned tag) /* Convert a DWARF attribute code into its string name. */ static char * -dwarf_attr_name (register unsigned attr) +dwarf_attr_name (unsigned attr) { switch (attr) { @@ -5131,7 +6632,30 @@ dwarf_attr_name (register unsigned attr) return "DW_AT_virtuality"; case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location"; - + case DW_AT_allocated: + return "DW_AT_allocated"; + case DW_AT_associated: + return "DW_AT_associated"; + case DW_AT_data_location: + return "DW_AT_data_location"; + case DW_AT_stride: + return "DW_AT_stride"; + case DW_AT_entry_pc: + return "DW_AT_entry_pc"; + case DW_AT_use_UTF8: + return "DW_AT_use_UTF8"; + case DW_AT_extension: + return "DW_AT_extension"; + case DW_AT_ranges: + return "DW_AT_ranges"; + case DW_AT_trampoline: + return "DW_AT_trampoline"; + case DW_AT_call_column: + return "DW_AT_call_column"; + case DW_AT_call_file: + return "DW_AT_call_file"; + case DW_AT_call_line: + return "DW_AT_call_line"; #ifdef MIPS case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; @@ -5145,9 +6669,9 @@ dwarf_attr_name (register unsigned attr) return "DW_AT_MIPS_loop_unroll_factor"; case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth"; +#endif case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name"; -#endif case DW_AT_sf_names: return "DW_AT_sf_names"; @@ -5161,6 +6685,8 @@ dwarf_attr_name (register unsigned attr) return "DW_AT_body_begin"; case DW_AT_body_end: return "DW_AT_body_end"; + case DW_AT_GNU_vector: + return "DW_AT_GNU_vector"; default: return "DW_AT_"; } @@ -5169,7 +6695,7 @@ dwarf_attr_name (register unsigned attr) /* Convert a DWARF value form code into its string name. */ static char * -dwarf_form_name (register unsigned form) +dwarf_form_name (unsigned form) { switch (form) { @@ -5223,7 +6749,7 @@ dwarf_form_name (register unsigned form) /* Convert a DWARF stack opcode into its string name. */ static char * -dwarf_stack_op_name (register unsigned op) +dwarf_stack_op_name (unsigned op) { switch (op) { @@ -5517,6 +7043,18 @@ dwarf_stack_op_name (register unsigned op) return "DW_OP_xderef_size"; case DW_OP_nop: return "DW_OP_nop"; + /* DWARF 3 extensions. */ + case DW_OP_push_object_address: + return "DW_OP_push_object_address"; + case DW_OP_call2: + return "DW_OP_call2"; + case DW_OP_call4: + return "DW_OP_call4"; + case DW_OP_call_ref: + return "DW_OP_call_ref"; + /* GNU extensions. */ + case DW_OP_GNU_push_tls_address: + return "DW_OP_GNU_push_tls_address"; default: return "OP_"; } @@ -5534,7 +7072,7 @@ dwarf_bool_name (unsigned mybool) /* Convert a DWARF type code into its string name. */ static char * -dwarf_type_encoding_name (register unsigned enc) +dwarf_type_encoding_name (unsigned enc) { switch (enc) { @@ -5554,6 +7092,8 @@ dwarf_type_encoding_name (register unsigned enc) return "DW_ATE_unsigned"; case DW_ATE_unsigned_char: return "DW_ATE_unsigned_char"; + case DW_ATE_imaginary_float: + return "DW_ATE_imaginary_float"; default: return "DW_ATE_"; } @@ -5563,7 +7103,7 @@ dwarf_type_encoding_name (register unsigned enc) #if 0 static char * -dwarf_cfi_name (register unsigned cfi_opc) +dwarf_cfi_name (unsigned cfi_opc) { switch (cfi_opc) { @@ -5642,7 +7182,7 @@ dump_die (struct die_info *die) fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n", dwarf_tag_name (die->tag), die->abbrev, die->offset); fprintf_unfiltered (gdb_stderr, "\thas children: %s\n", - dwarf_bool_name (die->has_children)); + dwarf_bool_name (die->child != NULL)); fprintf_unfiltered (gdb_stderr, "\tattributes:\n"); for (i = 0; i < die->num_attrs; ++i) @@ -5705,7 +7245,10 @@ dump_die_list (struct die_info *die) while (die) { dump_die (die); - die = die->next; + if (die->child != NULL) + dump_die_list (die->child); + if (die->sibling != NULL) + dump_die_list (die->sibling); } } @@ -5729,7 +7272,7 @@ dwarf2_empty_hash_tables (void) } static unsigned int -dwarf2_get_ref_die_offset (struct attribute *attr) +dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu) { unsigned int result = 0; @@ -5743,14 +7286,38 @@ dwarf2_get_ref_die_offset (struct attribute *attr) case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: - result = cu_header_offset + DW_UNSND (attr); + result = cu->header.offset + DW_UNSND (attr); break; default: - complain (&dwarf2_unsupported_die_ref_attr, dwarf_form_name (attr->form)); + complaint (&symfile_complaints, + "unsupported die ref attribute form: '%s'", + dwarf_form_name (attr->form)); } return result; } +/* Return the constant value held by the given attribute. Return -1 + if the value held by the attribute is not constant. */ + +static int +dwarf2_get_attr_constant_value (struct attribute *attr, int default_value) +{ + if (attr->form == DW_FORM_sdata) + return DW_SND (attr); + else if (attr->form == DW_FORM_udata + || attr->form == DW_FORM_data1 + || attr->form == DW_FORM_data2 + || attr->form == DW_FORM_data4 + || attr->form == DW_FORM_data8) + return DW_UNSND (attr); + else + { + complaint (&symfile_complaints, "Attribute value is not a constant (%s)", + dwarf_form_name (attr->form)); + return default_value; + } +} + static struct die_info * follow_die_ref (unsigned int offset) { @@ -5771,58 +7338,57 @@ follow_die_ref (unsigned int offset) } static struct type * -dwarf2_fundamental_type (struct objfile *objfile, int typeid) +dwarf2_fundamental_type (struct objfile *objfile, int typeid, + struct dwarf2_cu *cu) { if (typeid < 0 || typeid >= FT_NUM_MEMBERS) { - error ("Dwarf Error: internal error - invalid fundamental type id %d.", - typeid); + error ("Dwarf Error: internal error - invalid fundamental type id %d [in module %s]", + typeid, objfile->name); } /* Look for this particular type in the fundamental type vector. If one is not found, create and install one appropriate for the current language and the current target machine. */ - if (ftypes[typeid] == NULL) + if (cu->ftypes[typeid] == NULL) { - ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid); + cu->ftypes[typeid] = cu->language_defn->la_fund_type (objfile, typeid); } - return (ftypes[typeid]); + return (cu->ftypes[typeid]); } /* Decode simple location descriptions. Given a pointer to a dwarf block that defines a location, compute the location and return the value. - FIXME: This is a kludge until we figure out a better - way to handle the location descriptions. - Gdb's design does not mesh well with the DWARF2 notion of a location - computing interpreter, which is a shame because the flexibility goes unused. - FIXME: Implement more operations as necessary. + NOTE drow/2003-11-18: This function is called in two situations + now: for the address of static or global variables (partial symbols + only) and for offsets into structures which are expected to be + (more or less) constant. The partial symbol case should go away, + and only the constant case should remain. That will let this + function complain more accurately. A few special modes are allowed + without complaint for global variables (for instance, global + register values and thread-local values). A location description containing no operations indicates that the - object is optimized out. The global optimized_out flag is set for - those, the return value is meaningless. + object is optimized out. The return value is 0 for that case. + FIXME drow/2003-11-16: No callers check for this case any more; soon all + callers will only want a very basic result and this can become a + complaint. When the result is a register number, the global isreg flag is set, otherwise it is cleared. - When the result is a base register offset, the global offreg flag is set - and the register number is returned in basereg, otherwise it is cleared. - - When the DW_OP_fbreg operation is encountered without a corresponding - DW_AT_frame_base attribute, the global islocal flag is set. - Hopefully the machine dependent code knows how to set up a virtual - frame pointer for the local references. - Note that stack[0] is unused except as a default error return. Note that stack overflow is not yet handled. */ static CORE_ADDR -decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, - const struct comp_unit_head *cu_header) +decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; int i; int size = blk->size; char *data = blk->data; @@ -5835,14 +7401,9 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, stacki = 0; stack[stacki] = 0; isreg = 0; - offreg = 0; - isderef = 0; - islocal = 0; - optimized_out = 1; while (i < size) { - optimized_out = 0; op = data[i++]; switch (op) { @@ -5915,86 +7476,22 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, case DW_OP_reg31: isreg = 1; stack[++stacki] = op - DW_OP_reg0; + if (i < size) + dwarf2_complex_location_expr_complaint (); break; case DW_OP_regx: isreg = 1; unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read); i += bytes_read; -#if defined(HARRIS_TARGET) && defined(_M88K) - /* The Harris 88110 gdb ports have long kept their special reg - numbers between their gp-regs and their x-regs. This is - not how our dwarf is generated. Punt. */ - unsnd += 6; -#endif stack[++stacki] = unsnd; - break; - - case DW_OP_breg0: - case DW_OP_breg1: - case DW_OP_breg2: - case DW_OP_breg3: - case DW_OP_breg4: - case DW_OP_breg5: - case DW_OP_breg6: - case DW_OP_breg7: - case DW_OP_breg8: - case DW_OP_breg9: - case DW_OP_breg10: - case DW_OP_breg11: - case DW_OP_breg12: - case DW_OP_breg13: - case DW_OP_breg14: - case DW_OP_breg15: - case DW_OP_breg16: - case DW_OP_breg17: - case DW_OP_breg18: - case DW_OP_breg19: - case DW_OP_breg20: - case DW_OP_breg21: - case DW_OP_breg22: - case DW_OP_breg23: - case DW_OP_breg24: - case DW_OP_breg25: - case DW_OP_breg26: - case DW_OP_breg27: - case DW_OP_breg28: - case DW_OP_breg29: - case DW_OP_breg30: - case DW_OP_breg31: - offreg = 1; - basereg = op - DW_OP_breg0; - stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - break; - - case DW_OP_bregx: - offreg = 1; - basereg = read_unsigned_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - break; - - case DW_OP_fbreg: - stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - if (frame_base_reg >= 0) - { - offreg = 1; - basereg = frame_base_reg; - stack[stacki] += frame_base_offset; - } - else - { - complain (&dwarf2_missing_at_frame_base); - islocal = 1; - } + if (i < size) + dwarf2_complex_location_expr_complaint (); break; case DW_OP_addr: stack[++stacki] = read_address (objfile->obfd, &data[i], - cu_header, &bytes_read); + cu, &bytes_read); i += bytes_read; break; @@ -6060,15 +7557,28 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, break; case DW_OP_deref: - isderef = 1; /* If we're not the last op, then we definitely can't encode - this using GDB's address_class enum. */ + this using GDB's address_class enum. This is valid for partial + global symbols, although the variable's address will be bogus + in the psymtab. */ if (i < size) - complain (&dwarf2_complex_location_expr); + dwarf2_complex_location_expr_complaint (); break; + case DW_OP_GNU_push_tls_address: + /* The top of the stack has the offset from the beginning + of the thread control block at which the variable is located. */ + /* Nothing should follow this operator, so the top of stack would + be returned. */ + /* This is valid for partial global symbols, but the variable's + address will be bogus in the psymtab. */ + if (i < size) + dwarf2_complex_location_expr_complaint (); + break; + default: - complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op)); + complaint (&symfile_complaints, "unsupported stack op: '%s'", + dwarf_stack_op_name (op)); return (stack[stacki]); } } @@ -6077,9 +7587,8 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, /* memory allocation interface */ -/* ARGSUSED */ static void -dwarf2_free_tmp_obstack (PTR ignore) +dwarf2_free_tmp_obstack (void *ignore) { obstack_free (&dwarf2_tmp_obstack, NULL); } @@ -6113,3 +7622,446 @@ dwarf_alloc_die (void) memset (die, 0, sizeof (struct die_info)); return (die); } + + +/* Macro support. */ + + +/* Return the full name of file number I in *LH's file name table. + Use COMP_DIR as the name of the current directory of the + compilation. The result is allocated using xmalloc; the caller is + responsible for freeing it. */ +static char * +file_full_name (int file, struct line_header *lh, const char *comp_dir) +{ + struct file_entry *fe = &lh->file_names[file - 1]; + + if (IS_ABSOLUTE_PATH (fe->name)) + return xstrdup (fe->name); + else + { + const char *dir; + int dir_len; + char *full_name; + + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + else + dir = comp_dir; + + if (dir) + { + dir_len = strlen (dir); + full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1); + strcpy (full_name, dir); + full_name[dir_len] = '/'; + strcpy (full_name + dir_len + 1, fe->name); + return full_name; + } + else + return xstrdup (fe->name); + } +} + + +static struct macro_source_file * +macro_start_file (int file, int line, + struct macro_source_file *current_file, + const char *comp_dir, + struct line_header *lh, struct objfile *objfile) +{ + /* The full name of this source file. */ + char *full_name = file_full_name (file, lh, comp_dir); + + /* We don't create a macro table for this compilation unit + at all until we actually get a filename. */ + if (! pending_macros) + pending_macros = new_macro_table (&objfile->objfile_obstack, + objfile->macro_cache); + + if (! current_file) + /* If we have no current file, then this must be the start_file + directive for the compilation unit's main source file. */ + current_file = macro_set_main (pending_macros, full_name); + else + current_file = macro_include (current_file, line, full_name); + + xfree (full_name); + + return current_file; +} + + +/* Copy the LEN characters at BUF to a xmalloc'ed block of memory, + followed by a null byte. */ +static char * +copy_string (const char *buf, int len) +{ + char *s = xmalloc (len + 1); + memcpy (s, buf, len); + s[len] = '\0'; + + return s; +} + + +static const char * +consume_improper_spaces (const char *p, const char *body) +{ + if (*p == ' ') + { + complaint (&symfile_complaints, + "macro definition contains spaces in formal argument list:\n`%s'", + body); + + while (*p == ' ') + p++; + } + + return p; +} + + +static void +parse_macro_definition (struct macro_source_file *file, int line, + const char *body) +{ + const char *p; + + /* The body string takes one of two forms. For object-like macro + definitions, it should be: + + " " + + For function-like macro definitions, it should be: + + "() " + or + "(" ( "," ) * ") " + + Spaces may appear only where explicitly indicated, and in the + . + + The Dwarf 2 spec says that an object-like macro's name is always + followed by a space, but versions of GCC around March 2002 omit + the space when the macro's definition is the empty string. + + The Dwarf 2 spec says that there should be no spaces between the + formal arguments in a function-like macro's formal argument list, + but versions of GCC around March 2002 include spaces after the + commas. */ + + + /* Find the extent of the macro name. The macro name is terminated + by either a space or null character (for an object-like macro) or + an opening paren (for a function-like macro). */ + for (p = body; *p; p++) + if (*p == ' ' || *p == '(') + break; + + if (*p == ' ' || *p == '\0') + { + /* It's an object-like macro. */ + int name_len = p - body; + char *name = copy_string (body, name_len); + const char *replacement; + + if (*p == ' ') + replacement = body + name_len + 1; + else + { + dwarf2_macro_malformed_definition_complaint (body); + replacement = body + name_len; + } + + macro_define_object (file, line, name, replacement); + + xfree (name); + } + else if (*p == '(') + { + /* It's a function-like macro. */ + char *name = copy_string (body, p - body); + int argc = 0; + int argv_size = 1; + char **argv = xmalloc (argv_size * sizeof (*argv)); + + p++; + + p = consume_improper_spaces (p, body); + + /* Parse the formal argument list. */ + while (*p && *p != ')') + { + /* Find the extent of the current argument name. */ + const char *arg_start = p; + + while (*p && *p != ',' && *p != ')' && *p != ' ') + p++; + + if (! *p || p == arg_start) + dwarf2_macro_malformed_definition_complaint (body); + else + { + /* Make sure argv has room for the new argument. */ + if (argc >= argv_size) + { + argv_size *= 2; + argv = xrealloc (argv, argv_size * sizeof (*argv)); + } + + argv[argc++] = copy_string (arg_start, p - arg_start); + } + + p = consume_improper_spaces (p, body); + + /* Consume the comma, if present. */ + if (*p == ',') + { + p++; + + p = consume_improper_spaces (p, body); + } + } + + if (*p == ')') + { + p++; + + if (*p == ' ') + /* Perfectly formed definition, no complaints. */ + macro_define_function (file, line, name, + argc, (const char **) argv, + p + 1); + else if (*p == '\0') + { + /* Complain, but do define it. */ + dwarf2_macro_malformed_definition_complaint (body); + macro_define_function (file, line, name, + argc, (const char **) argv, + p); + } + else + /* Just complain. */ + dwarf2_macro_malformed_definition_complaint (body); + } + else + /* Just complain. */ + dwarf2_macro_malformed_definition_complaint (body); + + xfree (name); + { + int i; + + for (i = 0; i < argc; i++) + xfree (argv[i]); + } + xfree (argv); + } + else + dwarf2_macro_malformed_definition_complaint (body); +} + + +static void +dwarf_decode_macros (struct line_header *lh, unsigned int offset, + char *comp_dir, bfd *abfd, + struct dwarf2_cu *cu) +{ + char *mac_ptr, *mac_end; + struct macro_source_file *current_file = 0; + + if (dwarf_macinfo_buffer == NULL) + { + complaint (&symfile_complaints, "missing .debug_macinfo section"); + return; + } + + mac_ptr = dwarf_macinfo_buffer + offset; + mac_end = dwarf_macinfo_buffer + dwarf_macinfo_size; + + for (;;) + { + enum dwarf_macinfo_record_type macinfo_type; + + /* Do we at least have room for a macinfo type byte? */ + if (mac_ptr >= mac_end) + { + dwarf2_macros_too_long_complaint (); + return; + } + + macinfo_type = read_1_byte (abfd, mac_ptr); + mac_ptr++; + + switch (macinfo_type) + { + /* A zero macinfo type indicates the end of the macro + information. */ + case 0: + return; + + case DW_MACINFO_define: + case DW_MACINFO_undef: + { + int bytes_read; + int line; + char *body; + + line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + body = read_string (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + + if (! current_file) + complaint (&symfile_complaints, + "debug info gives macro %s outside of any file: %s", + macinfo_type == + DW_MACINFO_define ? "definition" : macinfo_type == + DW_MACINFO_undef ? "undefinition" : + "something-or-other", body); + else + { + if (macinfo_type == DW_MACINFO_define) + parse_macro_definition (current_file, line, body); + else if (macinfo_type == DW_MACINFO_undef) + macro_undef (current_file, line, body); + } + } + break; + + case DW_MACINFO_start_file: + { + int bytes_read; + int line, file; + + line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + + current_file = macro_start_file (file, line, + current_file, comp_dir, + lh, cu->objfile); + } + break; + + case DW_MACINFO_end_file: + if (! current_file) + complaint (&symfile_complaints, + "macro debug info has an unmatched `close_file' directive"); + else + { + current_file = current_file->included_by; + if (! current_file) + { + enum dwarf_macinfo_record_type next_type; + + /* GCC circa March 2002 doesn't produce the zero + type byte marking the end of the compilation + unit. Complain if it's not there, but exit no + matter what. */ + + /* Do we at least have room for a macinfo type byte? */ + if (mac_ptr >= mac_end) + { + dwarf2_macros_too_long_complaint (); + return; + } + + /* We don't increment mac_ptr here, so this is just + a look-ahead. */ + next_type = read_1_byte (abfd, mac_ptr); + if (next_type != 0) + complaint (&symfile_complaints, + "no terminating 0-type entry for macros in `.debug_macinfo' section"); + + return; + } + } + break; + + case DW_MACINFO_vendor_ext: + { + int bytes_read; + int constant; + char *string; + + constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + string = read_string (abfd, mac_ptr, &bytes_read); + mac_ptr += bytes_read; + + /* We don't recognize any vendor extensions. */ + } + break; + } + } +} + +/* Check if the attribute's form is a DW_FORM_block* + if so return true else false. */ +static int +attr_form_is_block (struct attribute *attr) +{ + return (attr == NULL ? 0 : + attr->form == DW_FORM_block1 + || attr->form == DW_FORM_block2 + || attr->form == DW_FORM_block4 + || attr->form == DW_FORM_block); +} + +static void +dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, + struct dwarf2_cu *cu) +{ + if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) + { + struct dwarf2_loclist_baton *baton; + + baton = obstack_alloc (&cu->objfile->objfile_obstack, + sizeof (struct dwarf2_loclist_baton)); + baton->objfile = cu->objfile; + + /* We don't know how long the location list is, but make sure we + don't run off the edge of the section. */ + baton->size = dwarf_loc_size - DW_UNSND (attr); + baton->data = dwarf_loc_buffer + DW_UNSND (attr); + baton->base_address = cu->header.base_address; + if (cu->header.base_known == 0) + complaint (&symfile_complaints, + "Location list used without specifying the CU base address."); + + SYMBOL_OPS (sym) = &dwarf2_loclist_funcs; + SYMBOL_LOCATION_BATON (sym) = baton; + } + else + { + struct dwarf2_locexpr_baton *baton; + + baton = obstack_alloc (&cu->objfile->objfile_obstack, + sizeof (struct dwarf2_locexpr_baton)); + baton->objfile = cu->objfile; + + if (attr_form_is_block (attr)) + { + /* Note that we're just copying the block's data pointer + here, not the actual data. We're still pointing into the + dwarf_info_buffer for SYM's objfile; right now we never + release that buffer, but when we do clean up properly + this may need to change. */ + baton->size = DW_BLOCK (attr)->size; + baton->data = DW_BLOCK (attr)->data; + } + else + { + dwarf2_invalid_attrib_class_complaint ("location description", + SYMBOL_NATURAL_NAME (sym)); + baton->size = 0; + baton->data = NULL; + } + + SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs; + SYMBOL_LOCATION_BATON (sym) = baton; + } +} diff --git a/contrib/gdb/gdb/dwarfread.c b/contrib/gdb/gdb/dwarfread.c index dc72f87661d..c245108c08e 100644 --- a/contrib/gdb/gdb/dwarfread.c +++ b/contrib/gdb/gdb/dwarfread.c @@ -1,7 +1,8 @@ /* DWARF debugging format support for GDB. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004 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. @@ -21,6 +22,64 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* + If you are looking for DWARF-2 support, you are in the wrong file. + Go look in dwarf2read.c. This file is for the original DWARF, + also known as DWARF-1. + + DWARF-1 is slowly headed for obsoletion. + + In gcc HEAD 2003-11-29 16:28:31 UTC, no targets prefer dwarf-1. + + In gcc 3.3.2, these targets prefer dwarf-1: + + i[34567]86-sequent-ptx4* + i[34567]86-sequent-sysv4* + mips-sni-sysv4 + sparc-hal-solaris2* + + In gcc 3.2.2, these targets prefer dwarf-1: + + i[34567]86-dg-dgux* + i[34567]86-sequent-ptx4* + i[34567]86-sequent-sysv4* + m88k-dg-dgux* + mips-sni-sysv4 + sparc-hal-solaris2* + + In gcc 2.95.3, these targets prefer dwarf-1: + + i[34567]86-dg-dgux* + i[34567]86-ncr-sysv4* + i[34567]86-sequent-ptx4* + i[34567]86-sequent-sysv4* + i[34567]86-*-osf1* + i[34567]86-*-sco3.2v5* + i[34567]86-*-sysv4* + i860-alliant-* + i860-*-sysv4* + m68k-atari-sysv4* + m68k-cbm-sysv4* + m68k-*-sysv4* + m88k-dg-dgux* + m88k-*-sysv4* + mips-sni-sysv4 + mips-*-gnu* + sh-*-elf* + sh-*-rtemself* + sparc-hal-solaris2* + sparc-*-sysv4* + + Some non-gcc compilers produce dwarf-1: + + PR gdb/1179 was from a user with Diab C++ 4.3. + Other users have also reported using Diab compilers with dwarf-1. + On 2003-06-09 the gdb list received a report from a user + with Absoft ProFortran f77 which is dwarf-1. + + -- chastain 2003-12-01 +*/ + /* FIXME: Do we need to generate dependencies in partial symtabs? @@ -43,7 +102,6 @@ #include "defs.h" #include "symtab.h" #include "gdbtypes.h" -#include "symfile.h" #include "objfiles.h" #include "elf/dwarf.h" #include "buildsym.h" @@ -62,115 +120,37 @@ /* Complaints that can be issued during DWARF debug info reading. */ -struct complaint no_bfd_get_N = +static void +bad_die_ref_complaint (int arg1, const char *arg2, int arg3) { - "DIE @ 0x%x \"%s\", no bfd support for %d byte data object", 0, 0 -}; + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", reference to DIE (0x%x) outside compilation unit", + arg1, arg2, arg3); +} -struct complaint malformed_die = +static void +unknown_attribute_form_complaint (int arg1, const char *arg2, int arg3) { - "DIE @ 0x%x \"%s\", malformed DIE, bad length (%d bytes)", 0, 0 -}; + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", unknown attribute form (0x%x)", arg1, arg2, + arg3); +} -struct complaint bad_die_ref = +static void +dup_user_type_definition_complaint (int arg1, const char *arg2) { - "DIE @ 0x%x \"%s\", reference to DIE (0x%x) outside compilation unit", 0, 0 -}; + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", internal error: duplicate user type definition", + arg1, arg2); +} -struct complaint unknown_attribute_form = +static void +bad_array_element_type_complaint (int arg1, const char *arg2, int arg3) { - "DIE @ 0x%x \"%s\", unknown attribute form (0x%x)", 0, 0 -}; - -struct complaint unknown_attribute_length = -{ - "DIE @ 0x%x \"%s\", unknown attribute length, skipped remaining attributes", 0, 0 -}; - -struct complaint unexpected_fund_type = -{ - "DIE @ 0x%x \"%s\", unexpected fundamental type 0x%x", 0, 0 -}; - -struct complaint unknown_type_modifier = -{ - "DIE @ 0x%x \"%s\", unknown type modifier %u", 0, 0 -}; - -struct complaint volatile_ignored = -{ - "DIE @ 0x%x \"%s\", type modifier 'volatile' ignored", 0, 0 -}; - -struct complaint const_ignored = -{ - "DIE @ 0x%x \"%s\", type modifier 'const' ignored", 0, 0 -}; - -struct complaint botched_modified_type = -{ - "DIE @ 0x%x \"%s\", botched modified type decoding (mtype 0x%x)", 0, 0 -}; - -struct complaint op_deref2 = -{ - "DIE @ 0x%x \"%s\", OP_DEREF2 address 0x%x not handled", 0, 0 -}; - -struct complaint op_deref4 = -{ - "DIE @ 0x%x \"%s\", OP_DEREF4 address 0x%x not handled", 0, 0 -}; - -struct complaint basereg_not_handled = -{ - "DIE @ 0x%x \"%s\", BASEREG %d not handled", 0, 0 -}; - -struct complaint dup_user_type_allocation = -{ - "DIE @ 0x%x \"%s\", internal error: duplicate user type allocation", 0, 0 -}; - -struct complaint dup_user_type_definition = -{ - "DIE @ 0x%x \"%s\", internal error: duplicate user type definition", 0, 0 -}; - -struct complaint missing_tag = -{ - "DIE @ 0x%x \"%s\", missing class, structure, or union tag", 0, 0 -}; - -struct complaint bad_array_element_type = -{ - "DIE @ 0x%x \"%s\", bad array element type attribute 0x%x", 0, 0 -}; - -struct complaint subscript_data_items = -{ - "DIE @ 0x%x \"%s\", can't decode subscript data items", 0, 0 -}; - -struct complaint unhandled_array_subscript_format = -{ - "DIE @ 0x%x \"%s\", array subscript format 0x%x not handled yet", 0, 0 -}; - -struct complaint unknown_array_subscript_format = -{ - "DIE @ 0x%x \"%s\", unknown array subscript format %x", 0, 0 -}; - -struct complaint not_row_major = -{ - "DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0 -}; - -struct complaint missing_at_name = -{ - "DIE @ 0x%x, AT_name tag missing", 0, 0 -}; + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", bad array element type attribute 0x%x", arg1, + arg2, arg3); +} typedef unsigned int DIE_REF; /* Reference to a DIE */ @@ -186,10 +166,6 @@ typedef unsigned int DIE_REF; /* Reference to a DIE */ #define LCC_PRODUCER "NCR C/C++" #endif -#ifndef CHILL_PRODUCER -#define CHILL_PRODUCER "GNU Chill " -#endif - /* Flags to target_to_host() that tell whether or not the data object is expected to be signed. Used, for example, when fetching a signed integer in the target environment which is used as a signed integer @@ -441,7 +417,7 @@ static const struct language_defn *cu_language_defn; /* Forward declarations of static functions so we don't have to worry about ordering within this file. */ -static void free_utypes (PTR); +static void free_utypes (void *); static int attribute_size (unsigned int); @@ -451,19 +427,19 @@ static void add_enum_psymbol (struct dieinfo *, struct objfile *); static void handle_producer (char *); -static void -read_file_scope (struct dieinfo *, char *, char *, struct objfile *); +static void read_file_scope (struct dieinfo *, char *, char *, + struct objfile *); -static void -read_func_scope (struct dieinfo *, char *, char *, struct objfile *); +static void read_func_scope (struct dieinfo *, char *, char *, + struct objfile *); -static void -read_lexical_block_scope (struct dieinfo *, char *, char *, struct objfile *); +static void read_lexical_block_scope (struct dieinfo *, char *, char *, + struct objfile *); static void scan_partial_symbols (char *, char *, struct objfile *); -static void -scan_compilation_units (char *, char *, file_ptr, file_ptr, struct objfile *); +static void scan_compilation_units (char *, char *, file_ptr, file_ptr, + struct objfile *); static void add_partial_symbol (struct dieinfo *, struct objfile *); @@ -479,8 +455,8 @@ static void read_ofile_symtab (struct partial_symtab *); static void process_dies (char *, char *, struct objfile *); -static void -read_structure_scope (struct dieinfo *, char *, char *, struct objfile *); +static void read_structure_scope (struct dieinfo *, char *, char *, + struct objfile *); static struct type *decode_array_element_type (char *); @@ -494,8 +470,8 @@ static void read_tag_string_type (struct dieinfo *dip); static void read_subroutine_type (struct dieinfo *, char *, char *); -static void -read_enumeration (struct dieinfo *, char *, char *, struct objfile *); +static void read_enumeration (struct dieinfo *, char *, char *, + struct objfile *); static struct type *struct_type (struct dieinfo *, char *, char *, struct objfile *); @@ -522,8 +498,8 @@ static struct type *alloc_utype (DIE_REF, struct type *); static struct symbol *new_symbol (struct dieinfo *, struct objfile *); -static void -synthesize_typedef (struct dieinfo *, struct objfile *, struct type *); +static void synthesize_typedef (struct dieinfo *, struct objfile *, + struct type *); static int locval (struct dieinfo *); @@ -621,9 +597,6 @@ set_cu_language (struct dieinfo *dip) case LANG_C_PLUS_PLUS: cu_language = language_cplus; break; - case LANG_CHILL: - cu_language = language_chill; - break; case LANG_MODULA2: cu_language = language_m2; break; @@ -745,7 +718,7 @@ static void read_lexical_block_scope (struct dieinfo *dip, char *thisdie, char *enddie, struct objfile *objfile) { - register struct context_stack *new; + struct context_stack *new; push_context (0, dip->at_low_pc); process_dies (thisdie + dip->die_length, enddie, objfile); @@ -786,7 +759,7 @@ lookup_utype (DIE_REF die_ref) utypeidx = (die_ref - dbroff) / 4; if ((utypeidx < 0) || (utypeidx >= numutypes)) { - complain (&bad_die_ref, DIE_ID, DIE_NAME); + bad_die_ref_complaint (DIE_ID, DIE_NAME, die_ref); } else { @@ -828,12 +801,14 @@ alloc_utype (DIE_REF die_ref, struct type *utypep) if ((utypeidx < 0) || (utypeidx >= numutypes)) { utypep = dwarf_fundamental_type (current_objfile, FT_INTEGER); - complain (&bad_die_ref, DIE_ID, DIE_NAME); + bad_die_ref_complaint (DIE_ID, DIE_NAME, die_ref); } else if (*typep != NULL) { utypep = *typep; - complain (&dup_user_type_allocation, DIE_ID, DIE_NAME); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", internal error: duplicate user type allocation", + DIE_ID, DIE_NAME); } else { @@ -854,7 +829,7 @@ alloc_utype (DIE_REF die_ref, struct type *utypep) SYNOPSIS - static void free_utypes (PTR dummy) + static void free_utypes (void *dummy) DESCRIPTION @@ -864,7 +839,7 @@ alloc_utype (DIE_REF die_ref, struct type *utypep) */ static void -free_utypes (PTR dummy) +free_utypes (void *dummy) { xfree (utypes); utypes = NULL; @@ -904,7 +879,8 @@ decode_die_type (struct dieinfo *dip) } else if (dip->at_user_def_type) { - if ((type = lookup_utype (dip->at_user_def_type)) == NULL) + type = lookup_utype (dip->at_user_def_type); + if (type == NULL) { type = alloc_utype (dip->at_user_def_type, NULL); } @@ -958,7 +934,8 @@ struct_type (struct dieinfo *dip, char *thisdie, char *enddie, char *nextdie; int anonymous_size; - if ((type = lookup_utype (dip->die_ref)) == NULL) + type = lookup_utype (dip->die_ref); + if (type == NULL) { /* No forward references created an empty type, so install one now */ type = alloc_utype (dip->die_ref, NULL); @@ -978,7 +955,9 @@ struct_type (struct dieinfo *dip, char *thisdie, char *enddie, default: /* Should never happen */ TYPE_CODE (type) = TYPE_CODE_UNDEF; - complain (&missing_tag, DIE_ID, DIE_NAME); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", missing class, structure, or union tag", + DIE_ID, DIE_NAME); break; } /* Some compilers try to be helpful by inventing "fake" names for @@ -988,7 +967,7 @@ struct_type (struct dieinfo *dip, char *thisdie, char *enddie, && *dip->at_name != '~' && *dip->at_name != '.') { - TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack, + TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack, "", "", dip->at_name); } /* Use whatever size is known. Zero is a valid size. We might however @@ -1017,6 +996,13 @@ struct_type (struct dieinfo *dip, char *thisdie, char *enddie, switch (mbr.die_tag) { case TAG_member: + /* Static fields can be either TAG_global_variable (GCC) or else + TAG_member with no location (Diab). We could treat the latter like + the former... but since we don't support the former, just avoid + crashing on the latter for now. */ + if (mbr.at_location == NULL) + break; + /* Get space to record the next field's data. */ new = (struct nextfield *) alloca (sizeof (struct nextfield)); new->next = list; @@ -1024,9 +1010,10 @@ struct_type (struct dieinfo *dip, char *thisdie, char *enddie, /* Save the data. */ list->field.name = obsavestring (mbr.at_name, strlen (mbr.at_name), - &objfile->type_obstack); + &objfile->objfile_obstack); FIELD_TYPE (list->field) = decode_die_type (&mbr); FIELD_BITPOS (list->field) = 8 * locval (&mbr); + FIELD_STATIC_KIND (list->field) = 0; /* Handle bit fields. */ FIELD_BITSIZE (list->field) = mbr.at_bit_size; if (BITS_BIG_ENDIAN) @@ -1188,9 +1175,10 @@ decode_array_element_type (char *scan) attribute = target_to_host (scan, SIZEOF_ATTRIBUTE, GET_UNSIGNED, current_objfile); scan += SIZEOF_ATTRIBUTE; - if ((nbytes = attribute_size (attribute)) == -1) + nbytes = attribute_size (attribute); + if (nbytes == -1) { - complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute); + bad_array_element_type_complaint (DIE_ID, DIE_NAME, attribute); typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); } else @@ -1208,7 +1196,8 @@ decode_array_element_type (char *scan) case AT_user_def_type: die_ref = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile); - if ((typep = lookup_utype (die_ref)) == NULL) + typep = lookup_utype (die_ref); + if (typep == NULL) { typep = alloc_utype (die_ref, NULL); } @@ -1217,7 +1206,7 @@ decode_array_element_type (char *scan) typep = decode_mod_u_d_type (scan); break; default: - complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute); + bad_array_element_type_complaint (DIE_ID, DIE_NAME, attribute); typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); break; } @@ -1305,7 +1294,9 @@ decode_subscript_data_item (char *scan, char *end) if (nexttype == NULL) { /* Munged subscript data or other problem, fake it. */ - complain (&subscript_data_items, DIE_ID, DIE_NAME); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", can't decode subscript data items", + DIE_ID, DIE_NAME); nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); } rangetype = create_range_type ((struct type *) NULL, indextype, @@ -1319,13 +1310,17 @@ decode_subscript_data_item (char *scan, char *end) case FMT_UT_C_X: case FMT_UT_X_C: case FMT_UT_X_X: - complain (&unhandled_array_subscript_format, DIE_ID, DIE_NAME, format); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", array subscript format 0x%x not handled yet", + DIE_ID, DIE_NAME, format); nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0); typep = create_array_type ((struct type *) NULL, nexttype, rangetype); break; default: - complain (&unknown_array_subscript_format, DIE_ID, DIE_NAME, format); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", unknown array subscript format %x", DIE_ID, + DIE_NAME, format); nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0); typep = create_array_type ((struct type *) NULL, nexttype, rangetype); @@ -1363,16 +1358,20 @@ dwarf_read_array_type (struct dieinfo *dip) if (dip->at_ordering != ORD_row_major) { /* FIXME: Can gdb even handle column major arrays? */ - complain (¬_row_major, DIE_ID, DIE_NAME); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", array not row major; not handled correctly", + DIE_ID, DIE_NAME); } - if ((sub = dip->at_subscr_data) != NULL) + sub = dip->at_subscr_data; + if (sub != NULL) { nbytes = attribute_size (AT_subscr_data); blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile); subend = sub + nbytes + blocksz; sub += nbytes; type = decode_subscript_data_item (sub, subend); - if ((utype = lookup_utype (dip->die_ref)) == NULL) + utype = lookup_utype (dip->die_ref); + if (utype == NULL) { /* Install user defined type that has not been referenced yet. */ alloc_utype (dip->die_ref, type); @@ -1393,7 +1392,7 @@ dwarf_read_array_type (struct dieinfo *dip) { /* Double ick! Not only is a type already in our slot, but someone has decorated it. Complain and leave it alone. */ - complain (&dup_user_type_definition, DIE_ID, DIE_NAME); + dup_user_type_definition_complaint (DIE_ID, DIE_NAME); } } } @@ -1421,7 +1420,8 @@ read_tag_pointer_type (struct dieinfo *dip) struct type *utype; type = decode_die_type (dip); - if ((utype = lookup_utype (dip->die_ref)) == NULL) + utype = lookup_utype (dip->die_ref); + if (utype == NULL) { utype = lookup_pointer_type (type); alloc_utype (dip->die_ref, utype); @@ -1491,7 +1491,7 @@ read_tag_string_type (struct dieinfo *dip) is a blank one. If not, complain and leave it alone. */ if (TYPE_CODE (utype) != TYPE_CODE_UNDEF) { - complain (&dup_user_type_definition, DIE_ID, DIE_NAME); + dup_user_type_definition_complaint (DIE_ID, DIE_NAME); return; } } @@ -1540,7 +1540,8 @@ read_subroutine_type (struct dieinfo *dip, char *thisdie, char *enddie) /* Check to see if we already have a partially constructed user defined type for this DIE, from a forward reference. */ - if ((ftype = lookup_utype (dip->die_ref)) == NULL) + ftype = lookup_utype (dip->die_ref); + if (ftype == NULL) { /* This is the first reference to one of these types. Make a new one and place it in the user defined types. */ @@ -1557,7 +1558,7 @@ read_subroutine_type (struct dieinfo *dip, char *thisdie, char *enddie) } else { - complain (&dup_user_type_definition, DIE_ID, DIE_NAME); + dup_user_type_definition_complaint (DIE_ID, DIE_NAME); } } @@ -1620,7 +1621,7 @@ read_enumeration (struct dieinfo *dip, char *thisdie, char *enddie, of the enumeration and return a type pointer for the enumeration. At the same time, for each member of the enumeration, create a - symbol for it with namespace VAR_NAMESPACE and class LOC_CONST, + symbol for it with domain VAR_DOMAIN and class LOC_CONST, and give it the type of the enumeration itself. NOTES @@ -1654,7 +1655,8 @@ enum_type (struct dieinfo *dip, struct objfile *objfile) int nbytes; int unsigned_enum = 1; - if ((type = lookup_utype (dip->die_ref)) == NULL) + type = lookup_utype (dip->die_ref); + if (type == NULL) { /* No forward references created an empty type, so install one now */ type = alloc_utype (dip->die_ref, NULL); @@ -1667,14 +1669,15 @@ enum_type (struct dieinfo *dip, struct objfile *objfile) && *dip->at_name != '~' && *dip->at_name != '.') { - TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack, + TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack, "", "", dip->at_name); } if (dip->at_byte_size != 0) { TYPE_LENGTH (type) = dip->at_byte_size; } - if ((scan = dip->at_element_list) != NULL) + scan = dip->at_element_list; + if (scan != NULL) { if (dip->short_element_list) { @@ -1694,22 +1697,23 @@ enum_type (struct dieinfo *dip, struct objfile *objfile) list = new; FIELD_TYPE (list->field) = NULL; FIELD_BITSIZE (list->field) = 0; + FIELD_STATIC_KIND (list->field) = 0; FIELD_BITPOS (list->field) = target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED, objfile); scan += TARGET_FT_LONG_SIZE (objfile); list->field.name = obsavestring (scan, strlen (scan), - &objfile->type_obstack); + &objfile->objfile_obstack); scan += strlen (scan) + 1; nfields++; /* Handcraft a new symbol for this enum member. */ - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (list->field.name, - &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = create_name (list->field.name, + &objfile->objfile_obstack); SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_TYPE (sym) = type; SYMBOL_VALUE (sym) = FIELD_BITPOS (list->field); @@ -1728,7 +1732,7 @@ enum_type (struct dieinfo *dip, struct objfile *objfile) TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct field) * nfields); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct field) * nfields); /* Copy the saved-up fields into the field vector. */ for (n = 0; (n < nfields) && (list != NULL); list = list->next) { @@ -1764,7 +1768,7 @@ static void read_func_scope (struct dieinfo *dip, char *thisdie, char *enddie, struct objfile *objfile) { - register struct context_stack *new; + struct context_stack *new; /* AT_name is absent if the function is described with an AT_abstract_origin tag. @@ -1772,7 +1776,8 @@ read_func_scope (struct dieinfo *dip, char *thisdie, char *enddie, FIXME: Add code to handle AT_abstract_origin tags properly. */ if (dip->at_name == NULL) { - complain (&missing_at_name, DIE_ID); + complaint (&symfile_complaints, "DIE @ 0x%x, AT_name tag missing", + DIE_ID); return; } @@ -1814,7 +1819,7 @@ handle_producer (char *producer) /* If this compilation unit was compiled with g++ or gcc, then set the processing_gcc_compilation flag. */ - if (STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER))) + if (DEPRECATED_STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER))) { char version = producer[strlen (GCC_PRODUCER)]; processing_gcc_compilation = (version == '2' ? 2 : 1); @@ -1822,8 +1827,7 @@ handle_producer (char *producer) else { processing_gcc_compilation = - STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)) - || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER)); + strncmp (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)) == 0; } /* Select a demangling style if we can identify the producer and if @@ -1833,7 +1837,7 @@ handle_producer (char *producer) if (AUTO_DEMANGLING) { - if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))) + if (DEPRECATED_STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))) { #if 0 /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't @@ -1841,7 +1845,7 @@ handle_producer (char *producer) set_demangling_style (GNU_DEMANGLING_STYLE_STRING); #endif } - else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER))) + else if (DEPRECATED_STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER))) { set_demangling_style (LUCID_DEMANGLING_STYLE_STRING); } @@ -1881,8 +1885,8 @@ read_file_scope (struct dieinfo *dip, char *thisdie, char *enddie, if (objfile->ei.entry_point >= dip->at_low_pc && objfile->ei.entry_point < dip->at_high_pc) { - objfile->ei.entry_file_lowpc = dip->at_low_pc; - objfile->ei.entry_file_highpc = dip->at_high_pc; + objfile->ei.deprecated_entry_file_lowpc = dip->at_low_pc; + objfile->ei.deprecated_entry_file_highpc = dip->at_high_pc; } set_cu_language (dip); if (dip->at_producer != NULL) @@ -2206,10 +2210,14 @@ locval (struct dieinfo *dip) break; case OP_DEREF2: /* pop, deref and push 2 bytes (as a long) */ - complain (&op_deref2, DIE_ID, DIE_NAME, stack[stacki]); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", OP_DEREF2 address 0x%lx not handled", + DIE_ID, DIE_NAME, stack[stacki]); break; case OP_DEREF4: /* pop, deref and push 4 bytes (as a long) */ - complain (&op_deref4, DIE_ID, DIE_NAME, stack[stacki]); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", OP_DEREF4 address 0x%lx not handled", + DIE_ID, DIE_NAME, stack[stacki]); break; case OP_ADD: /* pop top 2 items, add, push result */ stack[stacki - 1] += stack[stacki]; @@ -2278,7 +2286,7 @@ read_ofile_symtab (struct partial_symtab *pst) if (LNFOFF (pst)) { if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) || - (bfd_bread ((PTR) lnsizedata, sizeof (lnsizedata), abfd) + (bfd_bread (lnsizedata, sizeof (lnsizedata), abfd) != sizeof (lnsizedata))) { error ("can't read DWARF line number table size"); @@ -2364,7 +2372,6 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) wrap_here (""); gdb_flush (gdb_stdout); } - sort_symtab_syms (pst->symtab); do_cleanups (old_chain); } pst->readin = 1; @@ -2457,7 +2464,8 @@ add_enum_psymbol (struct dieinfo *dip, struct objfile *objfile) unsigned short blocksz; int nbytes; - if ((scan = dip->at_element_list) != NULL) + scan = dip->at_element_list; + if (scan != NULL) { if (dip->short_element_list) { @@ -2473,7 +2481,7 @@ add_enum_psymbol (struct dieinfo *dip, struct objfile *objfile) while (scan < listend) { scan += TARGET_FT_LONG_SIZE (objfile); - add_psymbol_to_list (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST, + add_psymbol_to_list (scan, strlen (scan), VAR_DOMAIN, LOC_CONST, &objfile->static_psymbols, 0, 0, cu_language, objfile); scan += strlen (scan) + 1; @@ -2505,31 +2513,31 @@ add_partial_symbol (struct dieinfo *dip, struct objfile *objfile) { case TAG_global_subroutine: add_psymbol_to_list (dip->at_name, strlen (dip->at_name), - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->global_psymbols, 0, dip->at_low_pc, cu_language, objfile); break; case TAG_global_variable: add_psymbol_to_list (dip->at_name, strlen (dip->at_name), - VAR_NAMESPACE, LOC_STATIC, + VAR_DOMAIN, LOC_STATIC, &objfile->global_psymbols, 0, 0, cu_language, objfile); break; case TAG_subroutine: add_psymbol_to_list (dip->at_name, strlen (dip->at_name), - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->static_psymbols, 0, dip->at_low_pc, cu_language, objfile); break; case TAG_local_variable: add_psymbol_to_list (dip->at_name, strlen (dip->at_name), - VAR_NAMESPACE, LOC_STATIC, + VAR_DOMAIN, LOC_STATIC, &objfile->static_psymbols, 0, 0, cu_language, objfile); break; case TAG_typedef: add_psymbol_to_list (dip->at_name, strlen (dip->at_name), - VAR_NAMESPACE, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, 0, 0, cu_language, objfile); break; @@ -2541,14 +2549,14 @@ add_partial_symbol (struct dieinfo *dip, struct objfile *objfile) if (!dip->has_at_byte_size) break; add_psymbol_to_list (dip->at_name, strlen (dip->at_name), - STRUCT_NAMESPACE, LOC_TYPEDEF, + STRUCT_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, 0, 0, cu_language, objfile); if (cu_language == language_cplus) { /* For C++, these implicitly act as typedefs as well. */ add_psymbol_to_list (dip->at_name, strlen (dip->at_name), - VAR_NAMESPACE, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, 0, 0, cu_language, objfile); } @@ -2659,8 +2667,8 @@ scan_partial_symbols (char *thisdie, char *enddie, struct objfile *objfile) temp = dbbase + di.at_sibling - dbroff; if ((temp < thisdie) || (temp >= enddie)) { - complain (&bad_die_ref, DIE_ID, DIE_NAME, - di.at_sibling); + bad_die_ref_complaint (DIE_ID, DIE_NAME, + di.at_sibling); } else { @@ -2791,7 +2799,7 @@ scan_compilation_units (char *thisdie, char *enddie, file_ptr dbfoff, pst->texthigh = di.at_high_pc; pst->read_symtab_private = (char *) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwfinfo)); DBFOFF (pst) = dbfoff; DBROFF (pst) = curoff; @@ -2842,14 +2850,12 @@ new_symbol (struct dieinfo *dip, struct objfile *objfile) if (dip->at_name != NULL) { - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); OBJSTAT (objfile, n_syms++); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (dip->at_name, - &objfile->symbol_obstack); /* default assumptions */ - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_TYPE (sym) = decode_die_type (dip); @@ -2859,7 +2865,7 @@ new_symbol (struct dieinfo *dip, struct objfile *objfile) C++ symbol lookups by a factor of about 20. */ SYMBOL_LANGUAGE (sym) = cu_language; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, dip->at_name, strlen (dip->at_name), objfile); switch (dip->die_tag) { case TAG_label: @@ -2955,12 +2961,12 @@ new_symbol (struct dieinfo *dip, struct objfile *objfile) case TAG_union_type: case TAG_enumeration_type: SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; add_symbol_to_list (sym, list_in_scope); break; case TAG_typedef: SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, list_in_scope); break; default: @@ -3004,15 +3010,15 @@ synthesize_typedef (struct dieinfo *dip, struct objfile *objfile, if (dip->at_name != NULL) { sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); OBJSTAT (objfile, n_syms++); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (dip->at_name, - &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = create_name (dip->at_name, + &objfile->objfile_obstack); SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language); SYMBOL_TYPE (sym) = type; SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, list_in_scope); } } @@ -3172,13 +3178,16 @@ decode_modified_type (char *modifiers, unsigned int modcount, int mtype) nbytes = attribute_size (AT_user_def_type); die_ref = target_to_host (modifiers, nbytes, GET_UNSIGNED, current_objfile); - if ((typep = lookup_utype (die_ref)) == NULL) + typep = lookup_utype (die_ref); + if (typep == NULL) { typep = alloc_utype (die_ref, NULL); } break; default: - complain (&botched_modified_type, DIE_ID, DIE_NAME, mtype); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", botched modified type decoding (mtype 0x%x)", + DIE_ID, DIE_NAME, mtype); typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); break; } @@ -3196,16 +3205,26 @@ decode_modified_type (char *modifiers, unsigned int modcount, int mtype) typep = lookup_reference_type (typep); break; case MOD_const: - complain (&const_ignored, DIE_ID, DIE_NAME); /* FIXME */ + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", type modifier 'const' ignored", DIE_ID, + DIE_NAME); /* FIXME */ break; case MOD_volatile: - complain (&volatile_ignored, DIE_ID, DIE_NAME); /* FIXME */ + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", type modifier 'volatile' ignored", + DIE_ID, DIE_NAME); /* FIXME */ break; default: - if (!(MOD_lo_user <= (unsigned char) modifier + if (!(MOD_lo_user <= (unsigned char) modifier)) +#if 0 +/* This part of the test would always be true, and it triggers a compiler + warning. */ && (unsigned char) modifier <= MOD_hi_user)) +#endif { - complain (&unknown_type_modifier, DIE_ID, DIE_NAME, modifier); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", unknown type modifier %u", DIE_ID, + DIE_NAME, modifier); } break; } @@ -3347,7 +3366,9 @@ decode_fund_type (unsigned int fundtype) typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); if (!(FT_lo_user <= fundtype && fundtype <= FT_hi_user)) { - complain (&unexpected_fund_type, DIE_ID, DIE_NAME, fundtype); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", unexpected fundamental type 0x%x", + DIE_ID, DIE_NAME, fundtype); } } @@ -3445,7 +3466,9 @@ basicdieinfo (struct dieinfo *dip, char *diep, struct objfile *objfile) if ((dip->die_length < SIZEOF_DIE_LENGTH) || ((diep + dip->die_length) > (dbbase + dbsize))) { - complain (&malformed_die, DIE_ID, DIE_NAME, dip->die_length); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", malformed DIE, bad length (%ld bytes)", + DIE_ID, DIE_NAME, dip->die_length); dip->die_length = 0; } else if (dip->die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG)) @@ -3509,9 +3532,12 @@ completedieinfo (struct dieinfo *dip, struct objfile *objfile) { attr = target_to_host (diep, SIZEOF_ATTRIBUTE, GET_UNSIGNED, objfile); diep += SIZEOF_ATTRIBUTE; - if ((nbytes = attribute_size (attr)) == -1) + nbytes = attribute_size (attr); + if (nbytes == -1) { - complain (&unknown_attribute_length, DIE_ID, DIE_NAME); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", unknown attribute length, skipped remaining attributes", + DIE_ID, DIE_NAME); diep = end; continue; } @@ -3668,7 +3694,7 @@ completedieinfo (struct dieinfo *dip, struct objfile *objfile) diep += strlen (diep) + 1; break; default: - complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form); + unknown_attribute_form_complaint (DIE_ID, DIE_NAME, form); diep = end; break; } @@ -3725,7 +3751,9 @@ target_to_host (char *from, int nbytes, int signextend, /* FIXME: Unused */ rtnval = bfd_get_8 (objfile->obfd, (bfd_byte *) from); break; default: - complain (&no_bfd_get_N, DIE_ID, DIE_NAME, nbytes); + complaint (&symfile_complaints, + "DIE @ 0x%x \"%s\", no bfd support for %d byte data object", + DIE_ID, DIE_NAME, nbytes); rtnval = 0; break; } @@ -3780,7 +3808,7 @@ attribute_size (unsigned int attr) nbytes = TARGET_FT_POINTER_SIZE (objfile); break; default: - complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form); + unknown_attribute_form_complaint (DIE_ID, DIE_NAME, form); nbytes = -1; break; } diff --git a/contrib/gdb/gdb/elfread.c b/contrib/gdb/gdb/elfread.c index e76cd0d4a35..83a18627526 100644 --- a/contrib/gdb/gdb/elfread.c +++ b/contrib/gdb/gdb/elfread.c @@ -1,7 +1,8 @@ /* Read ELF (Executable and Linking Format) object files for GDB. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support. This file is part of GDB. @@ -52,20 +53,6 @@ struct elfinfo asection *mdebugsect; /* Section pointer for .mdebug section */ }; -/* Various things we might complain about... */ - -struct complaint section_info_complaint = -{"elf/stab section information %s without a preceding file symbol", 0, 0}; - -struct complaint section_info_dup_complaint = -{"duplicated elf/stab section information for %s", 0, 0}; - -struct complaint stab_info_mismatch_complaint = -{"elf/stab section information missing for %s", 0, 0}; - -struct complaint stab_info_questionable_complaint = -{"elf/stab section information questionable for %s", 0, 0}; - static void free_elfinfo (void *); /* We are called once per section from elf_symfile_read. We @@ -90,72 +77,43 @@ static void free_elfinfo (void *); static void elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip) { - register struct elfinfo *ei; + struct elfinfo *ei; ei = (struct elfinfo *) eip; - if (STREQ (sectp->name, ".debug")) + if (strcmp (sectp->name, ".debug") == 0) { ei->dboffset = sectp->filepos; ei->dbsize = bfd_get_section_size_before_reloc (sectp); } - else if (STREQ (sectp->name, ".line")) + else if (strcmp (sectp->name, ".line") == 0) { ei->lnoffset = sectp->filepos; ei->lnsize = bfd_get_section_size_before_reloc (sectp); } - else if (STREQ (sectp->name, ".stab")) + else if (strcmp (sectp->name, ".stab") == 0) { ei->stabsect = sectp; } - else if (STREQ (sectp->name, ".stab.index")) + else if (strcmp (sectp->name, ".stab.index") == 0) { ei->stabindexsect = sectp; } - else if (STREQ (sectp->name, ".mdebug")) + else if (strcmp (sectp->name, ".mdebug") == 0) { ei->mdebugsect = sectp; } } -#if 0 /* Currently unused */ - -char * -elf_interpreter (bfd *abfd) -{ - sec_ptr interp_sec; - unsigned size; - char *interp = NULL; - - interp_sec = bfd_get_section_by_name (abfd, ".interp"); - if (interp_sec) - { - size = bfd_section_size (abfd, interp_sec); - interp = alloca (size); - if (bfd_get_section_contents (abfd, interp_sec, interp, (file_ptr) 0, - size)) - { - interp = savestring (interp, size - 1); - } - else - { - interp = NULL; - } - } - return (interp); -} - -#endif - static struct minimal_symbol * -record_minimal_symbol_and_info (char *name, CORE_ADDR address, - enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */ - asection *bfd_section, struct objfile *objfile) +record_minimal_symbol (char *name, CORE_ADDR address, + enum minimal_symbol_type ms_type, + asection *bfd_section, struct objfile *objfile) { if (ms_type == mst_text || ms_type == mst_file_text) address = SMASH_TEXT_ADDRESS (address); return prim_record_minimal_symbol_and_info - (name, address, ms_type, info, bfd_section->index, bfd_section, objfile); + (name, address, ms_type, NULL, bfd_section->index, bfd_section, objfile); } /* @@ -190,7 +148,6 @@ elf_symtab_read (struct objfile *objfile, int dynamic) asymbol **symbol_table; long number_of_symbols; long i; - int index; struct cleanup *back_to; CORE_ADDR symaddr; CORE_ADDR offset; @@ -202,11 +159,10 @@ elf_symtab_read (struct objfile *objfile, int dynamic) seen any section info for it yet. */ asymbol *filesym = 0; #ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* Name of filesym, as saved on the symbol_obstack. */ - char *filesymname = obsavestring ("", 0, &objfile->symbol_obstack); + /* Name of filesym, as saved on the objfile_obstack. */ + char *filesymname = obsavestring ("", 0, &objfile->objfile_obstack); #endif struct dbx_symfile_info *dbx = objfile->sym_stab_info; - unsigned long size; int stripped = (bfd_get_symcount (objfile->obfd) == 0); if (dynamic) @@ -266,9 +222,9 @@ elf_symtab_read (struct objfile *objfile, int dynamic) if (symaddr == 0) continue; symaddr += offset; - msym = record_minimal_symbol_and_info + msym = record_minimal_symbol ((char *) sym->name, symaddr, - mst_solib_trampoline, NULL, sym->section, objfile); + mst_solib_trampoline, sym->section, objfile); #ifdef SOFUN_ADDRESS_MAYBE_MISSING if (msym != NULL) msym->filename = filesymname; @@ -295,7 +251,7 @@ elf_symtab_read (struct objfile *objfile, int dynamic) #ifdef SOFUN_ADDRESS_MAYBE_MISSING filesymname = obsavestring ((char *) filesym->name, strlen (filesym->name), - &objfile->symbol_obstack); + &objfile->objfile_obstack); #endif } else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK)) @@ -357,24 +313,14 @@ elf_symtab_read (struct objfile *objfile, int dynamic) || ((sym->flags & BSF_LOCAL) && sym->name[0] == '$' && 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 - delta m88k SVR4, it loses. So to have us check too - should be harmless (but I encourage people to fix this - in the assembler instead of adding checks here). */ + /* Looks like a compiler-generated label. Skip + it. The assembler should be skipping these (to + keep executables small), but apparently with + gcc on the (deleted) delta m88k SVR4, it loses. + So to have us check too should be harmless (but + I encourage people to fix this in the assembler + instead of adding checks here). */ continue; -#ifdef HARRIS_TARGET - else if (sym->name[0] == '.' && sym->name[1] == '.') - { - /* Looks like a Harris compiler generated label for the - purpose of marking instructions that are relevant to - DWARF dies. The assembler can't get rid of these - because they are relocatable addresses that the - linker needs to resolve. */ - continue; - } -#endif else { ms_type = mst_file_text; @@ -395,38 +341,50 @@ elf_symtab_read (struct objfile *objfile, int dynamic) } else if (sym->flags & BSF_LOCAL) { - /* Named Local variable in a Data section. Check its - name for stabs-in-elf. The STREQ macro checks the - first character inline, so we only actually do a - strcmp function call on names that start with 'B' - or 'D' */ - index = SECT_OFF_MAX; - if (STREQ ("Bbss.bss", sym->name)) - { - index = SECT_OFF_BSS (objfile); - } - else if (STREQ ("Ddata.data", sym->name)) - { - index = SECT_OFF_DATA (objfile); - } - else if (STREQ ("Drodata.rodata", sym->name)) - { - index = SECT_OFF_RODATA (objfile); - } - if (index != SECT_OFF_MAX) + /* Named Local variable in a Data section. + Check its name for stabs-in-elf. */ + int special_local_sect; + if (strcmp ("Bbss.bss", sym->name) == 0) + special_local_sect = SECT_OFF_BSS (objfile); + else if (strcmp ("Ddata.data", sym->name) == 0) + special_local_sect = SECT_OFF_DATA (objfile); + else if (strcmp ("Drodata.rodata", sym->name) == 0) + special_local_sect = SECT_OFF_RODATA (objfile); + else + special_local_sect = -1; + if (special_local_sect >= 0) { /* Found a special local symbol. Allocate a sectinfo, if needed, and fill it in. */ if (sectinfo == NULL) { + int max_index; + size_t size; + + max_index + = max (SECT_OFF_BSS (objfile), + max (SECT_OFF_DATA (objfile), + SECT_OFF_RODATA (objfile))); + + /* max_index is the largest index we'll + use into this array, so we must + allocate max_index+1 elements for it. + However, 'struct stab_section_info' + already includes one element, so we + need to allocate max_index aadditional + elements. */ + size = (sizeof (struct stab_section_info) + + (sizeof (CORE_ADDR) + * max_index)); sectinfo = (struct stab_section_info *) - xmmalloc (objfile->md, sizeof (*sectinfo)); - memset (sectinfo, 0, - sizeof (*sectinfo)); + xmmalloc (objfile->md, size); + memset (sectinfo, 0, size); + sectinfo->num_sections = max_index; if (filesym == NULL) { - complain (§ion_info_complaint, - sym->name); + complaint (&symfile_complaints, + "elf/stab section information %s without a preceding file symbol", + sym->name); } else { @@ -434,35 +392,23 @@ elf_symtab_read (struct objfile *objfile, int dynamic) (char *) filesym->name; } } - if (index != -1) - { - if (sectinfo->sections[index] != 0) - { - complain (§ion_info_dup_complaint, - sectinfo->filename); - } - } - else - internal_error (__FILE__, __LINE__, - "Section index uninitialized."); - /* Bfd symbols are section relative. */ + if (sectinfo->sections[special_local_sect] != 0) + complaint (&symfile_complaints, + "duplicated elf/stab section information for %s", + sectinfo->filename); + /* BFD symbols are section relative. */ symaddr = sym->value + sym->section->vma; - /* Relocate non-absolute symbols by the section offset. */ + /* Relocate non-absolute symbols by the + section offset. */ if (sym->section != &bfd_abs_section) - { - symaddr += offset; - } - if (index != -1) - sectinfo->sections[index] = symaddr; - else - internal_error (__FILE__, __LINE__, - "Section index uninitialized."); + symaddr += offset; + sectinfo->sections[special_local_sect] = symaddr; /* The special local symbols don't go in the - minimal symbol table, so ignore this one. */ + minimal symbol table, so ignore this one. */ continue; } /* Not a special stabs-in-elf symbol, do regular - symbol processing. */ + symbol processing. */ if (sym->section->flags & SEC_LOAD) { ms_type = mst_file_data; @@ -486,11 +432,15 @@ elf_symtab_read (struct objfile *objfile, int dynamic) /* ms_type = mst_unknown; */ continue; /* Skip this symbol. */ } - /* Pass symbol size field in via BFD. FIXME!!! */ - size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size; - msym = record_minimal_symbol_and_info + msym = record_minimal_symbol ((char *) sym->name, symaddr, - ms_type, (void *) size, sym->section, objfile); + ms_type, sym->section, objfile); + if (msym) + { + /* Pass symbol size field in via BFD. FIXME!!! */ + unsigned long size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size; + MSYMBOL_SIZE(msym) = size; + } #ifdef SOFUN_ADDRESS_MAYBE_MISSING if (msym != NULL) msym->filename = filesymname; @@ -563,6 +513,15 @@ elf_symfile_read (struct objfile *objfile, int mainline) elf_symtab_read (objfile, 1); + /* Install any minimal symbols that have been collected as the current + minimal symbols for this objfile. The debug readers below this point + should not generate new minimal symbols; if they do it's their + responsibility to install them. "mdebug" appears to be the only one + which will do this. */ + + install_minimal_symbols (objfile); + do_cleanups (back_to); + /* Now process debugging information, which is contained in special ELF sections. */ @@ -612,8 +571,7 @@ elf_symfile_read (struct objfile *objfile, int mainline) if (str_sect) elfstab_build_psymtabs (objfile, mainline, - ei.stabsect->filepos, - bfd_section_size (abfd, ei.stabsect), + ei.stabsect, str_sect->filepos, bfd_section_size (abfd, str_sect)); } @@ -631,15 +589,9 @@ elf_symfile_read (struct objfile *objfile, int mainline) ei.lnoffset, ei.lnsize); } - if (DWARF2_BUILD_FRAME_INFO_P ()) - DWARF2_BUILD_FRAME_INFO(objfile); - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); + /* FIXME: kettenis/20030504: This still needs to be integrated with + dwarf2read.c in a better way. */ + dwarf2_build_frame_info (objfile); } /* This cleans up the objfile's sym_stab_info pointer, and the chain of @@ -738,7 +690,7 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) for (; maybe; maybe = maybe->next) { if (filename[0] == maybe->filename[0] - && STREQ (filename, maybe->filename)) + && strcmp (filename, maybe->filename) == 0) { /* We found a match. But there might be several source files (from different directories) with the same name. */ @@ -750,7 +702,8 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) if (maybe == 0 && questionable != 0) { - complain (&stab_info_questionable_complaint, filename); + complaint (&symfile_complaints, + "elf/stab section information questionable for %s", filename); maybe = questionable; } @@ -759,15 +712,17 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) /* Found it! Allocate a new psymtab struct, and fill it in. */ maybe->found++; pst->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS); - for (i = 0; i < SECT_OFF_MAX; i++) + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + for (i = 0; i < maybe->num_sections; i++) (pst->section_offsets)->offsets[i] = maybe->sections[i]; return; } /* We were unable to find any offsets for this file. Complain. */ if (dbx->stab_section_info) /* If there *is* any info, */ - complain (&stab_info_mismatch_complaint, filename); + complaint (&symfile_complaints, + "elf/stab section information missing for %s", filename); } /* Register that we are able to handle ELF object file formats. */ diff --git a/contrib/gdb/gdb/environ.c b/contrib/gdb/gdb/environ.c index 1f9a9d67e9f..b62938851b9 100644 --- a/contrib/gdb/gdb/environ.c +++ b/contrib/gdb/gdb/environ.c @@ -1,6 +1,7 @@ /* environ.c -- library for manipulating environments for GNU. - Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 2000 - Free Software Foundation, Inc. + + Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 2000, + 2003 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 @@ -30,7 +31,7 @@ struct environ * make_environ (void) { - register struct environ *e; + struct environ *e; e = (struct environ *) xmalloc (sizeof (struct environ)); @@ -43,9 +44,9 @@ make_environ (void) /* Free an environment and all the strings in it. */ void -free_environ (register struct environ *e) +free_environ (struct environ *e) { - register char **vector = e->vector; + char **vector = e->vector; while (*vector) xfree (*vector++); @@ -58,10 +59,10 @@ free_environ (register struct environ *e) that all strings in these environments are safe to free. */ void -init_environ (register struct environ *e) +init_environ (struct environ *e) { extern char **environ; - register int i; + int i; if (environ == NULL) return; @@ -79,8 +80,8 @@ init_environ (register struct environ *e) while (--i >= 0) { - register int len = strlen (e->vector[i]); - register char *new = (char *) xmalloc (len + 1); + int len = strlen (e->vector[i]); + char *new = (char *) xmalloc (len + 1); memcpy (new, e->vector[i], len + 1); e->vector[i] = new; } @@ -100,12 +101,12 @@ environ_vector (struct environ *e) char * get_in_environ (const struct environ *e, const char *var) { - register int len = strlen (var); - register char **vector = e->vector; - register char *s; + int len = strlen (var); + char **vector = e->vector; + char *s; for (; (s = *vector) != NULL; vector++) - if (STREQN (s, var, len) && s[len] == '=') + if (strncmp (s, var, len) == 0 && s[len] == '=') return &s[len + 1]; return 0; @@ -116,13 +117,13 @@ get_in_environ (const struct environ *e, const char *var) void set_in_environ (struct environ *e, const char *var, const char *value) { - register int i; - register int len = strlen (var); - register char **vector = e->vector; - register char *s; + int i; + int len = strlen (var); + char **vector = e->vector; + char *s; for (i = 0; (s = vector[i]) != NULL; i++) - if (STREQN (s, var, len) && s[len] == '=') + if (strncmp (s, var, len) == 0 && s[len] == '=') break; if (s == 0) @@ -163,13 +164,13 @@ set_in_environ (struct environ *e, const char *var, const char *value) void unset_in_environ (struct environ *e, char *var) { - register int len = strlen (var); - register char **vector = e->vector; - register char *s; + int len = strlen (var); + char **vector = e->vector; + char *s; for (; (s = *vector) != NULL; vector++) { - if (STREQN (s, var, len) && s[len] == '=') + if (DEPRECATED_STREQN (s, var, len) && s[len] == '=') { xfree (s); /* Walk through the vector, shuffling args down by one, including diff --git a/contrib/gdb/gdb/eval.c b/contrib/gdb/gdb/eval.c index 3f5aca3733c..452aeb7f243 100644 --- a/contrib/gdb/gdb/eval.c +++ b/contrib/gdb/gdb/eval.c @@ -1,7 +1,8 @@ /* Evaluate expressions for GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software + Foundation, Inc. This file is part of GDB. @@ -31,6 +32,10 @@ #include "language.h" /* For CAST_IS_CONVERSION */ #include "f-lang.h" /* for array bound stuff */ #include "cp-abi.h" +#include "infcall.h" +#include "objc-lang.h" +#include "block.h" +#include "parser-defs.h" /* Defined in symtab.c */ extern int hp_som_som_object_present; @@ -63,10 +68,11 @@ static LONGEST init_array_element (struct value *, struct value *, LONGEST, LONGEST); static struct value * -evaluate_subexp (struct type *expect_type, register struct expression *exp, - register int *pos, enum noside noside) +evaluate_subexp (struct type *expect_type, struct expression *exp, + int *pos, enum noside noside) { - return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside); + return (*exp->language_defn->la_exp_desc->evaluate_exp) + (expect_type, exp, pos, noside); } /* Parse the string EXP as a C expression, evaluate it, @@ -76,9 +82,9 @@ CORE_ADDR parse_and_eval_address (char *exp) { struct expression *expr = parse_expression (exp); - register CORE_ADDR addr; - register struct cleanup *old_chain = - make_cleanup (free_current_contents, &expr); + CORE_ADDR addr; + struct cleanup *old_chain = + make_cleanup (free_current_contents, &expr); addr = value_as_address (evaluate_expression (expr)); do_cleanups (old_chain); @@ -92,9 +98,9 @@ CORE_ADDR parse_and_eval_address_1 (char **expptr) { struct expression *expr = parse_exp_1 (expptr, (struct block *) 0, 0); - register CORE_ADDR addr; - register struct cleanup *old_chain = - make_cleanup (free_current_contents, &expr); + CORE_ADDR addr; + struct cleanup *old_chain = + make_cleanup (free_current_contents, &expr); addr = value_as_address (evaluate_expression (expr)); do_cleanups (old_chain); @@ -107,8 +113,8 @@ LONGEST parse_and_eval_long (char *exp) { struct expression *expr = parse_expression (exp); - register LONGEST retval; - register struct cleanup *old_chain = + LONGEST retval; + struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); retval = value_as_long (evaluate_expression (expr)); @@ -121,8 +127,8 @@ parse_and_eval (char *exp) { struct expression *expr = parse_expression (exp); struct value *val; - register struct cleanup *old_chain - = make_cleanup (free_current_contents, &expr); + struct cleanup *old_chain = + make_cleanup (free_current_contents, &expr); val = evaluate_expression (expr); do_cleanups (old_chain); @@ -138,8 +144,8 @@ parse_to_comma_and_eval (char **expp) { struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1); struct value *val; - register struct cleanup *old_chain - = make_cleanup (free_current_contents, &expr); + struct cleanup *old_chain = + make_cleanup (free_current_contents, &expr); val = evaluate_expression (expr); do_cleanups (old_chain); @@ -172,7 +178,7 @@ evaluate_type (struct expression *exp) returning the label. Otherwise, does nothing and returns NULL. */ static char * -get_label (register struct expression *exp, int *pos) +get_label (struct expression *exp, int *pos) { if (exp->elts[*pos].opcode == OP_LABELED) { @@ -186,13 +192,13 @@ get_label (register struct expression *exp, int *pos) return NULL; } -/* This function evaluates tuples (in Chill) or brace-initializers - (in C/C++) for structure types. */ +/* This function evaluates tuples (in (the deleted) Chill) or + brace-initializers (in C/C++) for structure types. */ static struct value * evaluate_struct_tuple (struct value *struct_val, - register struct expression *exp, - register int *pos, enum noside noside, int nargs) + struct expression *exp, + int *pos, enum noside noside, int nargs) { struct type *struct_type = check_typedef (VALUE_TYPE (struct_val)); struct type *substruct_type = struct_type; @@ -221,7 +227,7 @@ evaluate_struct_tuple (struct value *struct_val, fieldno++) { char *field_name = TYPE_FIELD_NAME (struct_type, fieldno); - if (field_name != NULL && STREQ (field_name, label)) + if (field_name != NULL && DEPRECATED_STREQ (field_name, label)) { variantno = -1; subfieldno = fieldno; @@ -249,7 +255,7 @@ evaluate_struct_tuple (struct value *struct_val, subfieldno < TYPE_NFIELDS (substruct_type); subfieldno++) { - if (STREQ (TYPE_FIELD_NAME (substruct_type, + if (DEPRECATED_STREQ (TYPE_FIELD_NAME (substruct_type, subfieldno), label)) { @@ -325,17 +331,16 @@ evaluate_struct_tuple (struct value *struct_val, return struct_val; } -/* Recursive helper function for setting elements of array tuples for Chill. - The target is ARRAY (which has bounds LOW_BOUND to HIGH_BOUND); - the element value is ELEMENT; - EXP, POS and NOSIDE are as usual. - Evaluates index expresions and sets the specified element(s) of - ARRAY to ELEMENT. - Returns last index value. */ +/* Recursive helper function for setting elements of array tuples for + (the deleted) Chill. The target is ARRAY (which has bounds + LOW_BOUND to HIGH_BOUND); the element value is ELEMENT; EXP, POS + and NOSIDE are as usual. Evaluates index expresions and sets the + specified element(s) of ARRAY to ELEMENT. Returns last index + value. */ static LONGEST init_array_element (struct value *array, struct value *element, - register struct expression *exp, register int *pos, + struct expression *exp, int *pos, enum noside noside, LONGEST low_bound, LONGEST high_bound) { LONGEST index; @@ -376,12 +381,12 @@ init_array_element (struct value *array, struct value *element, struct value * evaluate_subexp_standard (struct type *expect_type, - register struct expression *exp, register int *pos, + struct expression *exp, int *pos, enum noside noside) { enum exp_opcode op; int tem, tem2, tem3; - register int pc, pc2 = 0, oldpos; + int pc, pc2 = 0, oldpos; struct value *arg1 = NULL; struct value *arg2 = NULL; struct value *arg3; @@ -403,11 +408,9 @@ evaluate_subexp_standard (struct type *expect_type, case OP_SCOPE: tem = longest_to_int (exp->elts[pc + 2].longconst); (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1); - arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type, - 0, - exp->elts[pc + 1].type, - &exp->elts[pc + 3].string, - NULL_TYPE); + arg1 = value_aggregate_elt (exp->elts[pc + 1].type, + &exp->elts[pc + 3].string, + noside); if (arg1 == NULL) error ("There is no field named %s", &exp->elts[pc + 3].string); return arg1; @@ -447,11 +450,11 @@ evaluate_subexp_standard (struct type *expect_type, case OP_REGISTER: { int regno = longest_to_int (exp->elts[pc + 1].longconst); - struct value *val = value_of_register (regno); - + struct value *val = value_of_register (regno, get_selected_frame ()); (*pos) += 2; if (val == NULL) - error ("Value of register %s not available.", REGISTER_NAME (regno)); + error ("Value of register %s not available.", + frame_map_regnum_to_name (get_selected_frame (), regno)); else return val; } @@ -471,6 +474,15 @@ evaluate_subexp_standard (struct type *expect_type, goto nosideret; return value_string (&exp->elts[pc + 2].string, tem); + case OP_OBJC_NSSTRING: /* Objective C Foundation Class NSString constant. */ + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); + if (noside == EVAL_SKIP) + { + goto nosideret; + } + return (struct value *) value_nsstring (&exp->elts[pc + 2].string, tem + 1); + case OP_BITSTRING: tem = longest_to_int (exp->elts[pc + 1].longconst); (*pos) @@ -667,6 +679,285 @@ evaluate_subexp_standard (struct type *expect_type, return arg2; } + case OP_OBJC_SELECTOR: + { /* Objective C @selector operator. */ + char *sel = &exp->elts[pc + 2].string; + int len = longest_to_int (exp->elts[pc + 1].longconst); + + (*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1); + if (noside == EVAL_SKIP) + goto nosideret; + + if (sel[len] != 0) + sel[len] = 0; /* Make sure it's terminated. */ + return value_from_longest (lookup_pointer_type (builtin_type_void), + lookup_child_selector (sel)); + } + + case OP_OBJC_MSGCALL: + { /* Objective C message (method) call. */ + + static CORE_ADDR responds_selector = 0; + static CORE_ADDR method_selector = 0; + + CORE_ADDR selector = 0; + + int using_gcc = 0; + int struct_return = 0; + int sub_no_side = 0; + + static struct value *msg_send = NULL; + static struct value *msg_send_stret = NULL; + static int gnu_runtime = 0; + + struct value *target = NULL; + struct value *method = NULL; + struct value *called_method = NULL; + + struct type *selector_type = NULL; + + struct value *ret = NULL; + CORE_ADDR addr = 0; + + selector = exp->elts[pc + 1].longconst; + nargs = exp->elts[pc + 2].longconst; + argvec = (struct value **) alloca (sizeof (struct value *) + * (nargs + 5)); + + (*pos) += 3; + + selector_type = lookup_pointer_type (builtin_type_void); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + sub_no_side = EVAL_NORMAL; + else + sub_no_side = noside; + + target = evaluate_subexp (selector_type, exp, pos, sub_no_side); + + if (value_as_long (target) == 0) + return value_from_longest (builtin_type_long, 0); + + if (lookup_minimal_symbol ("objc_msg_lookup", 0, 0)) + gnu_runtime = 1; + + /* Find the method dispatch (Apple runtime) or method lookup + (GNU runtime) function for Objective-C. These will be used + to lookup the symbol information for the method. If we + can't find any symbol information, then we'll use these to + call the method, otherwise we can call the method + directly. The msg_send_stret function is used in the special + case of a method that returns a structure (Apple runtime + only). */ + if (gnu_runtime) + { + struct type *type; + type = lookup_pointer_type (builtin_type_void); + type = lookup_function_type (type); + type = lookup_pointer_type (type); + type = lookup_function_type (type); + type = lookup_pointer_type (type); + + msg_send = find_function_in_inferior ("objc_msg_lookup"); + msg_send_stret = find_function_in_inferior ("objc_msg_lookup"); + + msg_send = value_from_pointer (type, value_as_address (msg_send)); + msg_send_stret = value_from_pointer (type, + value_as_address (msg_send_stret)); + } + else + { + msg_send = find_function_in_inferior ("objc_msgSend"); + /* Special dispatcher for methods returning structs */ + msg_send_stret = find_function_in_inferior ("objc_msgSend_stret"); + } + + /* Verify the target object responds to this method. The + standard top-level 'Object' class uses a different name for + the verification method than the non-standard, but more + often used, 'NSObject' class. Make sure we check for both. */ + + responds_selector = lookup_child_selector ("respondsToSelector:"); + if (responds_selector == 0) + responds_selector = lookup_child_selector ("respondsTo:"); + + if (responds_selector == 0) + error ("no 'respondsTo:' or 'respondsToSelector:' method"); + + method_selector = lookup_child_selector ("methodForSelector:"); + if (method_selector == 0) + method_selector = lookup_child_selector ("methodFor:"); + + if (method_selector == 0) + error ("no 'methodFor:' or 'methodForSelector:' method"); + + /* Call the verification method, to make sure that the target + class implements the desired method. */ + + argvec[0] = msg_send; + argvec[1] = target; + argvec[2] = value_from_longest (builtin_type_long, responds_selector); + argvec[3] = value_from_longest (builtin_type_long, selector); + argvec[4] = 0; + + ret = call_function_by_hand (argvec[0], 3, argvec + 1); + if (gnu_runtime) + { + /* Function objc_msg_lookup returns a pointer. */ + argvec[0] = ret; + ret = call_function_by_hand (argvec[0], 3, argvec + 1); + } + if (value_as_long (ret) == 0) + error ("Target does not respond to this message selector."); + + /* Call "methodForSelector:" method, to get the address of a + function method that implements this selector for this + class. If we can find a symbol at that address, then we + know the return type, parameter types etc. (that's a good + thing). */ + + argvec[0] = msg_send; + argvec[1] = target; + argvec[2] = value_from_longest (builtin_type_long, method_selector); + argvec[3] = value_from_longest (builtin_type_long, selector); + argvec[4] = 0; + + ret = call_function_by_hand (argvec[0], 3, argvec + 1); + if (gnu_runtime) + { + argvec[0] = ret; + ret = call_function_by_hand (argvec[0], 3, argvec + 1); + } + + /* ret should now be the selector. */ + + addr = value_as_long (ret); + if (addr) + { + struct symbol *sym = NULL; + /* Is it a high_level symbol? */ + + sym = find_pc_function (addr); + if (sym != NULL) + method = value_of_variable (sym, 0); + } + + /* If we found a method with symbol information, check to see + if it returns a struct. Otherwise assume it doesn't. */ + + if (method) + { + struct block *b; + CORE_ADDR funaddr; + struct type *value_type; + + funaddr = find_function_addr (method, &value_type); + + b = block_for_pc (funaddr); + + /* If compiled without -g, assume GCC 2. */ + using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b)); + + CHECK_TYPEDEF (value_type); + + if ((value_type == NULL) + || (TYPE_CODE(value_type) == TYPE_CODE_ERROR)) + { + if (expect_type != NULL) + value_type = expect_type; + } + + struct_return = using_struct_return (value_type, using_gcc); + } + else if (expect_type != NULL) + { + struct_return = using_struct_return (check_typedef (expect_type), using_gcc); + } + + /* Found a function symbol. Now we will substitute its + value in place of the message dispatcher (obj_msgSend), + so that we call the method directly instead of thru + the dispatcher. The main reason for doing this is that + we can now evaluate the return value and parameter values + according to their known data types, in case we need to + do things like promotion, dereferencing, special handling + of structs and doubles, etc. + + We want to use the type signature of 'method', but still + jump to objc_msgSend() or objc_msgSend_stret() to better + mimic the behavior of the runtime. */ + + if (method) + { + if (TYPE_CODE (VALUE_TYPE (method)) != TYPE_CODE_FUNC) + error ("method address has symbol information with non-function type; skipping"); + if (struct_return) + VALUE_ADDRESS (method) = value_as_address (msg_send_stret); + else + VALUE_ADDRESS (method) = value_as_address (msg_send); + called_method = method; + } + else + { + if (struct_return) + called_method = msg_send_stret; + else + called_method = msg_send; + } + + if (noside == EVAL_SKIP) + goto nosideret; + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + /* If the return type doesn't look like a function type, + call an error. This can happen if somebody tries to + turn a variable into a function call. This is here + because people often want to call, eg, strcmp, which + gdb doesn't know is a function. If gdb isn't asked for + it's opinion (ie. through "whatis"), it won't offer + it. */ + + struct type *type = VALUE_TYPE (called_method); + if (type && TYPE_CODE (type) == TYPE_CODE_PTR) + type = TYPE_TARGET_TYPE (type); + type = TYPE_TARGET_TYPE (type); + + if (type) + { + if ((TYPE_CODE (type) == TYPE_CODE_ERROR) && expect_type) + return allocate_value (expect_type); + else + return allocate_value (type); + } + else + error ("Expression of type other than \"method returning ...\" used as a method"); + } + + /* Now depending on whether we found a symbol for the method, + we will either call the runtime dispatcher or the method + directly. */ + + argvec[0] = called_method; + argvec[1] = target; + argvec[2] = value_from_longest (builtin_type_long, selector); + /* User-supplied arguments. */ + for (tem = 0; tem < nargs; tem++) + argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside); + argvec[tem + 3] = 0; + + if (gnu_runtime && (method != NULL)) + { + /* Function objc_msg_lookup returns a pointer. */ + VALUE_TYPE (argvec[0]) = lookup_function_type + (lookup_pointer_type (VALUE_TYPE (argvec[0]))); + argvec[0] = call_function_by_hand (argvec[0], nargs + 2, argvec + 1); + } + + ret = call_function_by_hand (argvec[0], nargs + 2, argvec + 1); + return ret; + } + break; + case OP_FUNCALL: (*pos) += 2; op = exp->elts[*pos].opcode; @@ -821,15 +1112,10 @@ evaluate_subexp_standard (struct type *expect_type, if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) { int static_memfuncp; - struct value *temp = arg2; char tstr[256]; /* Method invocation : stuff "this" as first parameter */ - /* pai: this used to have lookup_pointer_type for some reason, - * but temp is already a pointer to the object */ - argvec[1] - = value_from_pointer (VALUE_TYPE (temp), - VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)); + argvec[1] = arg2; /* Name of method from expression */ strcpy (tstr, &exp->elts[pc2 + 2].string); @@ -855,11 +1141,17 @@ evaluate_subexp_standard (struct type *expect_type, else /* Non-C++ case -- or no overload resolution */ { - temp = arg2; + struct value *temp = arg2; argvec[0] = value_struct_elt (&temp, argvec + 1, tstr, &static_memfuncp, op == STRUCTOP_STRUCT ? "structure" : "structure pointer"); + /* value_struct_elt updates temp with the correct value + of the ``this'' pointer if necessary, so modify argvec[1] to + reflect any ``this'' changes. */ + arg2 = value_from_longest (lookup_pointer_type(VALUE_TYPE (temp)), + VALUE_ADDRESS (temp) + VALUE_OFFSET (temp) + + VALUE_EMBEDDED_OFFSET (temp)); argvec[1] = arg2; /* the ``this'' pointer */ } @@ -1748,6 +2040,10 @@ evaluate_subexp_standard (struct type *expect_type, (*pos) += 1; return value_of_this (1); + case OP_OBJC_SELF: + (*pos) += 1; + return value_of_local ("self", 1); + case OP_TYPE: error ("Attempt to use a type name as an expression"); @@ -1777,11 +2073,11 @@ nosideret: then only the type of the result need be correct. */ static struct value * -evaluate_subexp_for_address (register struct expression *exp, register int *pos, +evaluate_subexp_for_address (struct expression *exp, int *pos, enum noside noside) { enum exp_opcode op; - register int pc; + int pc; struct symbol *var; pc = (*pos); @@ -1857,11 +2153,11 @@ evaluate_subexp_for_address (register struct expression *exp, register int *pos, */ struct value * -evaluate_subexp_with_coercion (register struct expression *exp, - register int *pos, enum noside noside) +evaluate_subexp_with_coercion (struct expression *exp, + int *pos, enum noside noside) { - register enum exp_opcode op; - register int pc; + enum exp_opcode op; + int pc; struct value *val; struct symbol *var; @@ -1894,10 +2190,10 @@ evaluate_subexp_with_coercion (register struct expression *exp, Advance *POS over the subexpression. */ static struct value * -evaluate_subexp_for_sizeof (register struct expression *exp, register int *pos) +evaluate_subexp_for_sizeof (struct expression *exp, int *pos) { enum exp_opcode op; - register int pc; + int pc; struct type *type; struct value *val; diff --git a/contrib/gdb/gdb/event-loop.c b/contrib/gdb/gdb/event-loop.c index ea74419623e..c8d12f925df 100644 --- a/contrib/gdb/gdb/event-loop.c +++ b/contrib/gdb/gdb/event-loop.c @@ -1,5 +1,5 @@ /* Event loop machinery for GDB, the GNU debugger. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Elena Zannoni of Cygnus Solutions. This file is part of GDB. @@ -210,7 +210,6 @@ static void create_file_handler (int fd, int mask, handler_func * proc, gdb_clie static void invoke_async_signal_handler (void); static void handle_file_event (int event_file_desc); static int gdb_wait_for_event (void); -static int gdb_do_one_event (void *data); static int check_async_ready (void); static void async_queue_event (gdb_event * event_ptr, queue_position position); static gdb_event *create_file_event (int fd); @@ -346,7 +345,7 @@ process_event (void) can happen if there are no event sources to wait for). If an error occurs catch_errors() which calls this function returns zero. */ -static int +int gdb_do_one_event (void *data) { /* Any events already waiting in the queue? */ @@ -393,10 +392,17 @@ start_event_loop (void) longer any event sources registered. */ while (1) { - int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); - if (result < 0) + int gdb_result; + + gdb_result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); + if (gdb_result < 0) break; - if (result == 0) + + /* If we long-jumped out of do_one_event, we probably + didn't get around to resetting the prompt, which leaves + readline in a messed-up state. Reset it here. */ + + if (gdb_result == 0) { /* FIXME: this should really be a call to a hook that is interface specific, because interfaces can display the @@ -494,51 +500,52 @@ create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data clie file_ptr->ready_mask = 0; file_ptr->next_file = gdb_notifier.first_file_handler; gdb_notifier.first_file_handler = file_ptr; + + if (use_poll) + { +#ifdef HAVE_POLL + gdb_notifier.num_fds++; + if (gdb_notifier.poll_fds) + gdb_notifier.poll_fds = + (struct pollfd *) xrealloc (gdb_notifier.poll_fds, + (gdb_notifier.num_fds + * sizeof (struct pollfd))); + else + gdb_notifier.poll_fds = + (struct pollfd *) xmalloc (sizeof (struct pollfd)); + (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd; + (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask; + (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0; +#else + internal_error (__FILE__, __LINE__, + "use_poll without HAVE_POLL"); +#endif /* HAVE_POLL */ + } + else + { + if (mask & GDB_READABLE) + FD_SET (fd, &gdb_notifier.check_masks[0]); + else + FD_CLR (fd, &gdb_notifier.check_masks[0]); + + if (mask & GDB_WRITABLE) + FD_SET (fd, &gdb_notifier.check_masks[1]); + else + FD_CLR (fd, &gdb_notifier.check_masks[1]); + + if (mask & GDB_EXCEPTION) + FD_SET (fd, &gdb_notifier.check_masks[2]); + else + FD_CLR (fd, &gdb_notifier.check_masks[2]); + + if (gdb_notifier.num_fds <= fd) + gdb_notifier.num_fds = fd + 1; + } } + file_ptr->proc = proc; file_ptr->client_data = client_data; file_ptr->mask = mask; - - if (use_poll) - { -#ifdef HAVE_POLL - gdb_notifier.num_fds++; - if (gdb_notifier.poll_fds) - gdb_notifier.poll_fds = - (struct pollfd *) xrealloc (gdb_notifier.poll_fds, - (gdb_notifier.num_fds - * sizeof (struct pollfd))); - else - gdb_notifier.poll_fds = - (struct pollfd *) xmalloc (sizeof (struct pollfd)); - (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd; - (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask; - (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0; -#else - internal_error (__FILE__, __LINE__, - "use_poll without HAVE_POLL"); -#endif /* HAVE_POLL */ - } - else - { - if (mask & GDB_READABLE) - FD_SET (fd, &gdb_notifier.check_masks[0]); - else - FD_CLR (fd, &gdb_notifier.check_masks[0]); - - if (mask & GDB_WRITABLE) - FD_SET (fd, &gdb_notifier.check_masks[1]); - else - FD_CLR (fd, &gdb_notifier.check_masks[1]); - - if (mask & GDB_EXCEPTION) - FD_SET (fd, &gdb_notifier.check_masks[2]); - else - FD_CLR (fd, &gdb_notifier.check_masks[2]); - - if (gdb_notifier.num_fds <= fd) - gdb_notifier.num_fds = fd + 1; - } } /* Remove the file descriptor FD from the list of monitored fd's: diff --git a/contrib/gdb/gdb/event-loop.h b/contrib/gdb/gdb/event-loop.h index 2f2ff003f6a..748f48605d6 100644 --- a/contrib/gdb/gdb/event-loop.h +++ b/contrib/gdb/gdb/event-loop.h @@ -85,6 +85,7 @@ queue_position; /* Exported functions from event-loop.c */ extern void start_event_loop (void); +extern int gdb_do_one_event (void *data); extern void delete_file_handler (int fd); extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data); extern void mark_async_signal_handler (struct async_signal_handler *async_handler_ptr); diff --git a/contrib/gdb/gdb/event-top.c b/contrib/gdb/gdb/event-top.c index 91ffc8547a2..f4ba015e817 100644 --- a/contrib/gdb/gdb/event-top.c +++ b/contrib/gdb/gdb/event-top.c @@ -1,5 +1,5 @@ /* Top level stuff for GDB, the GNU debugger. - Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. Written by Elena Zannoni of Cygnus Solutions. This file is part of GDB. @@ -26,27 +26,25 @@ #include "terminal.h" /* for job_control */ #include "event-loop.h" #include "event-top.h" +#include "interps.h" #include /* For dont_repeat() */ #include "gdbcmd.h" /* readline include files */ -#include -#include +#include "readline/readline.h" +#include "readline/history.h" /* readline defines this. */ #undef savestring -extern void _initialize_event_loop (void); - static void rl_callback_read_char_wrapper (gdb_client_data client_data); static void command_line_handler (char *rl); static void command_line_handler_continuation (struct continuation_arg *arg); static void change_line_handler (void); static void change_annotation_level (void); static void command_handler (char *command); -void cli_command_loop (void); static void async_do_nothing (gdb_client_data arg); static void async_disconnect (gdb_client_data arg); static void async_stop_sig (gdb_client_data arg); @@ -250,9 +248,9 @@ display_gdb_prompt (char *new_prompt) int prompt_length = 0; char *gdb_prompt = get_prompt (); - /* When an alternative interpreter has been installed, do not - display the comand prompt. */ - if (interpreter_p) + /* Each interpreter has its own rules on displaying the command + prompt. */ + if (!current_interp_display_prompt_p ()) return; if (target_executing && sync_execution) @@ -494,10 +492,8 @@ command_handler (char *command) if (display_space) { #ifdef HAVE_SBRK - extern char **environ; char *lim = (char *) sbrk (0); - - space_at_cmd_start = (long) (lim - (char *) &environ); + space_at_cmd_start = lim - lim_at_start; #endif } @@ -540,9 +536,8 @@ command_handler (char *command) if (display_space) { #ifdef HAVE_SBRK - extern char **environ; char *lim = (char *) sbrk (0); - long space_now = lim - (char *) &environ; + long space_now = lim - lim_at_start; long space_diff = space_now - space_at_cmd_start; printf_unfiltered ("Space used: %ld (%c%ld for this command)\n", @@ -579,9 +574,8 @@ command_line_handler_continuation (struct continuation_arg *arg) if (display_space) { #ifdef HAVE_SBRK - extern char **environ; char *lim = (char *) sbrk (0); - long space_now = lim - (char *) &environ; + long space_now = lim - lim_at_start; long space_diff = space_now - space_at_cmd_start; printf_unfiltered ("Space used: %ld (%c%ld for this command)\n", @@ -605,7 +599,7 @@ command_line_handler (char *rl) { static char *linebuffer = 0; static unsigned linelength = 0; - register char *p; + char *p; char *p1; extern char *line; extern int linesize; @@ -618,7 +612,7 @@ command_line_handler (char *rl) if (annotation_level > 1 && instream == stdin) { printf_unfiltered ("\n\032\032post-"); - printf_unfiltered (async_annotation_suffix); + puts_unfiltered (async_annotation_suffix); printf_unfiltered ("\n"); } @@ -683,24 +677,21 @@ command_line_handler (char *rl) xfree (rl); /* Allocated in readline. */ - if (*(p - 1) == '\\') + if (p > linebuffer && *(p - 1) == '\\') { p--; /* Put on top of '\'. */ - if (*p == '\\') - { - readline_input_state.linebuffer = savestring (linebuffer, - strlen (linebuffer)); - readline_input_state.linebuffer_ptr = p; + readline_input_state.linebuffer = savestring (linebuffer, + strlen (linebuffer)); + readline_input_state.linebuffer_ptr = p; - /* We will not invoke a execute_command if there is more - input expected to complete the command. So, we need to - print an empty prompt here. */ - more_to_come = 1; - push_prompt ("", "", ""); - display_gdb_prompt (0); - return; - } + /* We will not invoke a execute_command if there is more + input expected to complete the command. So, we need to + print an empty prompt here. */ + more_to_come = 1; + push_prompt ("", "", ""); + display_gdb_prompt (0); + return; } #ifdef STOP_SIGNAL @@ -711,7 +702,7 @@ command_line_handler (char *rl) #define SERVER_COMMAND_LENGTH 7 server_command = (p - linebuffer > SERVER_COMMAND_LENGTH) - && STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH); + && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0; if (server_command) { /* Note that we don't set `line'. Between this and the check in @@ -980,11 +971,7 @@ void async_request_quit (gdb_client_data arg) { quit_flag = 1; -#ifdef REQUEST_QUIT - REQUEST_QUIT; -#else quit (); -#endif } /* Tell the event loop what to do if SIGQUIT is received. @@ -1093,7 +1080,6 @@ handle_sigwinch (int sig) /* Called by do_setshow_command. */ -/* ARGSUSED */ void set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c) { @@ -1101,7 +1087,6 @@ set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c) } /* Called by do_setshow_command. */ -/* ARGSUSED */ void set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c) { @@ -1109,7 +1094,6 @@ set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c } /* Called by do_setshow_command. */ -/* ARGSUSED */ void set_async_prompt (char *args, int from_tty, struct cmd_list_element *c) { @@ -1120,10 +1104,19 @@ set_async_prompt (char *args, int from_tty, struct cmd_list_element *c) interface, i.e. via a callback function (rl_callback_read_char), and hook up instream to the event loop. */ void -_initialize_event_loop (void) +gdb_setup_readline (void) { + /* This function is a noop for the sync case. The assumption is that + the sync setup is ALL done in gdb_init, and we would only mess it up + here. The sync stuff should really go away over time. */ + if (event_loop_p) { + gdb_stdout = stdio_fileopen (stdout); + gdb_stderr = stdio_fileopen (stderr); + gdb_stdlog = gdb_stderr; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ + /* If the input stream is connected to a terminal, turn on editing. */ if (ISATTY (instream)) @@ -1156,9 +1149,6 @@ _initialize_event_loop (void) register it with the event loop. */ input_fd = fileno (instream); - /* Tell gdb to use the cli_command_loop as the main loop. */ - command_loop_hook = cli_command_loop; - /* Now we need to create the event sources for the input file descriptor. */ /* At this point in time, this is the only event source that we @@ -1169,3 +1159,29 @@ _initialize_event_loop (void) add_file_handler (input_fd, stdin_event_handler, 0); } } + +/* Disable command input through the standard CLI channels. Used in + the suspend proc for interpreters that use the standard gdb readline + interface, like the cli & the mi. */ +void +gdb_disable_readline (void) +{ + if (event_loop_p) + { + /* FIXME - It is too heavyweight to delete and remake these + every time you run an interpreter that needs readline. + It is probably better to have the interpreters cache these, + which in turn means that this needs to be moved into interpreter + specific code. */ + +#if 0 + ui_file_delete (gdb_stdout); + ui_file_delete (gdb_stderr); + gdb_stdlog = NULL; + gdb_stdtarg = NULL; +#endif + + rl_callback_handler_remove (); + delete_file_handler (input_fd); + } +} diff --git a/contrib/gdb/gdb/event-top.h b/contrib/gdb/gdb/event-top.h index 24044a57bab..7e48a6ca190 100644 --- a/contrib/gdb/gdb/event-top.h +++ b/contrib/gdb/gdb/event-top.h @@ -1,5 +1,7 @@ -/* Definitions used by GDB event-top.c. - Copyright 1999, 2001 Free Software Foundation, Inc. +/* Definitions used by event-top.c, for GDB, the GNU debugger. + + Copyright 1999, 2001, 2003 Free Software Foundation, Inc. + Written by Elena Zannoni of Cygnus Solutions. This file is part of GDB. @@ -19,6 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef EVENT_TOP_H +#define EVENT_TOP_H + +struct cmd_list_element; + /* Stack for prompts. Each prompt is composed as a prefix, a prompt and a suffix. The prompt to be displayed at any given time is the one on top of the stack. A stack is necessary because of cases in @@ -71,6 +78,8 @@ struct prompts FIXME: these should really go into top.h. */ extern void display_gdb_prompt (char *new_prompt); +void gdb_setup_readline (void); +void gdb_disable_readline (void); extern void async_init_signals (void); extern void set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c); @@ -109,3 +118,7 @@ extern void (*call_readline) (void *); extern void (*input_handler) (char *); extern int input_fd; extern void (*after_char_processing_hook) (void); + +extern void cli_command_loop (void); + +#endif diff --git a/contrib/gdb/gdb/exec.c b/contrib/gdb/gdb/exec.c index b07175ef5c6..418b0b3aa35 100644 --- a/contrib/gdb/gdb/exec.c +++ b/contrib/gdb/gdb/exec.c @@ -1,7 +1,8 @@ /* Work with executable files, for GDB. - Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -30,12 +31,14 @@ #include "objfiles.h" #include "completer.h" #include "value.h" +#include "exec.h" #ifdef USG #include #endif #include +#include "readline/readline.h" #include "gdb_string.h" #include "gdbcore.h" @@ -54,8 +57,6 @@ void (*file_changed_hook) (char *); /* Prototypes for local functions */ -static void add_to_section_table (bfd *, sec_ptr, PTR); - static void exec_close (int); static void file_command (char *, int); @@ -64,8 +65,6 @@ static void set_section_command (char *, int); static void exec_files_info (struct target_ops *); -static void bfdsec_to_vmap (bfd *, sec_ptr, PTR); - static int ignore (CORE_ADDR, char *); static void init_exec_ops (void); @@ -84,14 +83,6 @@ bfd *exec_bfd = NULL; int write_files = 0; -/* Text start and end addresses (KLUDGE) if needed */ - -#ifndef NEED_TEXT_START_END -#define NEED_TEXT_START_END (0) -#endif -CORE_ADDR text_start = 0; -CORE_ADDR text_end = 0; - struct vmap *vmap; void @@ -101,7 +92,6 @@ exec_open (char *args, int from_tty) exec_file_attach (args, from_tty); } -/* ARGSUSED */ static void exec_close (int quitting) { @@ -242,7 +232,7 @@ exec_file_attach (char *filename, int from_tty) /* FIXME - This should only be run for RS6000, but the ifdef is a poor way to accomplish. */ -#ifdef IBM6000_TARGET +#ifdef DEPRECATED_IBM6000_TARGET /* Setup initial vmap. */ map_vmap (exec_bfd, 0); @@ -254,7 +244,7 @@ exec_file_attach (char *filename, int from_tty) error ("\"%s\": can't find the file sections: %s", scratch_pathname, bfd_errmsg (bfd_get_error ())); } -#endif /* IBM6000_TARGET */ +#endif /* DEPRECATED_IBM6000_TARGET */ if (build_section_table (exec_bfd, &exec_ops.to_sections, &exec_ops.to_sections_end)) @@ -266,30 +256,9 @@ exec_file_attach (char *filename, int from_tty) scratch_pathname, bfd_errmsg (bfd_get_error ())); } - /* text_end is sometimes used for where to put call dummies. A - few ports use these for other purposes too. */ - if (NEED_TEXT_START_END) - { - struct section_table *p; - - /* Set text_start to the lowest address of the start of any - readonly code section and set text_end to the highest - address of the end of any readonly code section. */ - /* FIXME: The comment above does not match the code. The - code checks for sections with are either code *or* - readonly. */ - 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->the_bfd_section) - & (SEC_CODE | SEC_READONLY)) - { - if (text_start > p->addr) - text_start = p->addr; - if (text_end < p->endaddr) - text_end = p->endaddr; - } - } +#ifdef DEPRECATED_HPUX_TEXT_END + DEPRECATED_HPUX_TEXT_END (&exec_ops); +#endif validate_files (); @@ -365,7 +334,8 @@ file_command (char *arg, int from_tty) we cast it back to its proper type. */ static void -add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char) +add_to_section_table (bfd *abfd, struct bfd_section *asect, + void *table_pp_char) { struct section_table **table_pp = (struct section_table **) table_pp_char; flagword aflag; @@ -386,7 +356,7 @@ add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char) Returns 0 if OK, 1 on error. */ int -build_section_table (bfd *some_bfd, struct section_table **start, +build_section_table (struct bfd *some_bfd, struct section_table **start, struct section_table **end) { unsigned count; @@ -404,7 +374,7 @@ build_section_table (bfd *some_bfd, struct section_table **start, } static void -bfdsec_to_vmap (bfd *abfd, sec_ptr sect, PTR arg3) +bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3) { struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3; struct vmap *vp; @@ -414,14 +384,14 @@ bfdsec_to_vmap (bfd *abfd, sec_ptr sect, PTR arg3) if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0) return; - if (STREQ (bfd_section_name (abfd, sect), ".text")) + if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".text")) { vp->tstart = bfd_section_vma (abfd, sect); vp->tend = vp->tstart + bfd_section_size (abfd, sect); vp->tvma = bfd_section_vma (abfd, sect); vp->toffs = sect->filepos; } - else if (STREQ (bfd_section_name (abfd, sect), ".data")) + else if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".data")) { vp->dstart = bfd_section_vma (abfd, sect); vp->dend = vp->dstart + bfd_section_size (abfd, sect); @@ -481,10 +451,9 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, struct mem_attrib *attrib, struct target_ops *target) { - boolean res; + int res; struct section_table *p; CORE_ADDR nextsectaddr, memend; - boolean (*xfer_fn) (bfd *, sec_ptr, PTR, file_ptr, bfd_size_type); asection *section = NULL; if (len <= 0) @@ -498,7 +467,6 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, } memend = memaddr + len; - xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents; nextsectaddr = memend; for (p = target->to_sections; p < target->to_sections_end; p++) @@ -507,26 +475,40 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, strcmp (section->name, p->the_bfd_section->name) != 0) continue; /* not the section we need */ if (memaddr >= p->addr) - if (memend <= p->endaddr) - { - /* Entire transfer is within this section. */ - res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, - memaddr - p->addr, len); - return (res != 0) ? len : 0; - } - else if (memaddr >= p->endaddr) - { - /* This section ends before the transfer starts. */ - continue; - } - else - { - /* This section overlaps the transfer. Just do half. */ - len = p->endaddr - memaddr; - res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, - memaddr - p->addr, len); - return (res != 0) ? len : 0; - } + { + if (memend <= p->endaddr) + { + /* Entire transfer is within this section. */ + if (write) + res = bfd_set_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + else + res = bfd_get_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + return (res != 0) ? len : 0; + } + else if (memaddr >= p->endaddr) + { + /* This section ends before the transfer starts. */ + continue; + } + else + { + /* This section overlaps the transfer. Just do half. */ + len = p->endaddr - memaddr; + if (write) + res = bfd_set_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + else + res = bfd_get_section_contents (p->bfd, p->the_bfd_section, + myaddr, memaddr - p->addr, + len); + return (res != 0) ? len : 0; + } + } else nextsectaddr = min (nextsectaddr, p->addr); } @@ -542,6 +524,8 @@ void print_section_info (struct target_ops *t, bfd *abfd) { struct section_table *p; + /* FIXME: "016l" is not wide enough when TARGET_ADDR_BIT > 64. */ + char *fmt = TARGET_ADDR_BIT <= 32 ? "08l" : "016l"; printf_filtered ("\t`%s', ", bfd_get_filename (abfd)); wrap_here (" "); @@ -554,12 +538,17 @@ print_section_info (struct target_ops *t, bfd *abfd) } 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")); + printf_filtered ("\t%s", local_hex_string_custom (p->addr, fmt)); + printf_filtered (" - %s", local_hex_string_custom (p->endaddr, fmt)); + + /* FIXME: A format of "08l" is not wide enough for file offsets + larger than 4GB. OTOH, making it "016l" isn't desirable either + since most output will then be much wider than necessary. It + may make sense to test the size of the file and choose the + format string accordingly. */ if (info_verbose) printf_filtered (" @ %s", - local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l")); + local_hex_string_custom (p->the_bfd_section->filepos, "08l")); printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section)); if (p->bfd != abfd) { @@ -712,14 +701,11 @@ Specify the filename of the executable file."; exec_ops.to_open = exec_open; exec_ops.to_close = exec_close; exec_ops.to_attach = find_default_attach; - exec_ops.to_require_attach = find_default_require_attach; - exec_ops.to_require_detach = find_default_require_detach; exec_ops.to_xfer_memory = xfer_memory; exec_ops.to_files_info = exec_files_info; exec_ops.to_insert_breakpoint = ignore; exec_ops.to_remove_breakpoint = ignore; exec_ops.to_create_inferior = find_default_create_inferior; - exec_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior; exec_ops.to_stratum = file_stratum; exec_ops.to_has_memory = 1; exec_ops.to_make_corefile_notes = exec_make_note_section; @@ -742,7 +728,7 @@ and it is the program executed when you use the `run' command.\n\ If FILE cannot be found as specified, your execution directory path\n\ ($PATH) is searched for a command of that name.\n\ No arg means to have no executable file and no symbols.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); } c = add_cmd ("exec-file", class_files, exec_file_command, @@ -750,7 +736,7 @@ No arg means to have no executable file and no symbols.", &cmdlist); If FILE cannot be found as specified, your execution directory path\n\ is searched for a command of that name.\n\ No arg means have no executable file.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_com ("section", class_files, set_section_command, "Change the base address of section SECTION of the exec file to ADDR.\n\ diff --git a/contrib/gdb/gdb/exec.h b/contrib/gdb/gdb/exec.h new file mode 100644 index 00000000000..d0862516c97 --- /dev/null +++ b/contrib/gdb/gdb/exec.h @@ -0,0 +1,39 @@ +/* Work with executable files, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef EXEC_H +#define EXEC_H + +#include "target.h" + +struct section_table; +struct target_ops; +struct bfd; + +extern struct target_ops exec_ops; + +/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR. + Returns 0 if OK, 1 on error. */ + +extern int build_section_table (struct bfd *, struct section_table **, + struct section_table **); + +#endif diff --git a/contrib/gdb/gdb/expprint.c b/contrib/gdb/gdb/expprint.c index cb617113971..5949475927e 100644 --- a/contrib/gdb/gdb/expprint.c +++ b/contrib/gdb/gdb/expprint.c @@ -1,6 +1,7 @@ /* Print in infix form a struct expression. + Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000 Free Software Foundation, Inc. + 1998, 1999, 2000, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -26,16 +27,15 @@ #include "value.h" #include "language.h" #include "parser-defs.h" +#include "user-regs.h" /* For user_reg_map_regnum_to_name. */ +#include "target.h" +#include "gdb_string.h" +#include "block.h" #ifdef HAVE_CTYPE_H #include #endif -/* Prototypes for local functions */ - -static void print_subexp (struct expression *, int *, struct ui_file *, - enum precedence); - void print_expression (struct expression *exp, struct ui_file *stream) { @@ -48,15 +48,24 @@ print_expression (struct expression *exp, struct ui_file *stream) if the precedence of the main operator of this subexpression is less, parentheses are needed here. */ -static void -print_subexp (register struct expression *exp, register int *pos, +void +print_subexp (struct expression *exp, int *pos, struct ui_file *stream, enum precedence prec) { - register unsigned tem; - register const struct op_print *op_print_tab; - register int pc; + exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec); +} + +/* Standard implementation of print_subexp for use in language_defn + vectors. */ +void +print_subexp_standard (struct expression *exp, int *pos, + struct ui_file *stream, enum precedence prec) +{ + unsigned tem; + const struct op_print *op_print_tab; + int pc; unsigned nargs; - register char *op_str; + char *op_str; int assign_modify = 0; enum exp_opcode opcode; enum precedence myprec = PREC_NULL; @@ -103,12 +112,12 @@ print_subexp (register struct expression *exp, register int *pos, b = exp->elts[pc + 1].block; if (b != NULL && BLOCK_FUNCTION (b) != NULL - && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)) != NULL) + && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)) != NULL) { - fputs_filtered (SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)), stream); + fputs_filtered (SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)), stream); fputs_filtered ("::", stream); } - fputs_filtered (SYMBOL_SOURCE_NAME (exp->elts[pc + 2].symbol), stream); + fputs_filtered (SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol), stream); } return; @@ -119,10 +128,14 @@ print_subexp (register struct expression *exp, register int *pos, return; case OP_REGISTER: - (*pos) += 2; - fprintf_filtered (stream, "$%s", - REGISTER_NAME (longest_to_int (exp->elts[pc + 1].longconst))); - return; + { + int regnum = longest_to_int (exp->elts[pc + 1].longconst); + const char *name = user_reg_map_regnum_to_name (current_gdbarch, + regnum); + (*pos) += 2; + fprintf_filtered (stream, "$%s", name); + return; + } case OP_BOOL: (*pos) += 2; @@ -174,6 +187,51 @@ print_subexp (register struct expression *exp, register int *pos, fprintf_unfiltered (stream, "B''"); return; + case OP_OBJC_NSSTRING: /* Objective-C Foundation Class NSString constant. */ + nargs = longest_to_int (exp->elts[pc + 1].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); + fputs_filtered ("@\"", stream); + LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0); + fputs_filtered ("\"", stream); + return; + + case OP_OBJC_MSGCALL: + { /* Objective C message (method) call. */ + char *selector; + (*pos) += 3; + nargs = longest_to_int (exp->elts[pc + 2].longconst); + fprintf_unfiltered (stream, "["); + print_subexp (exp, pos, stream, PREC_SUFFIX); + if (0 == target_read_string (exp->elts[pc + 1].longconst, + &selector, 1024, NULL)) + { + error ("bad selector"); + return; + } + if (nargs) + { + char *s, *nextS; + s = alloca (strlen (selector) + 1); + strcpy (s, selector); + for (tem = 0; tem < nargs; tem++) + { + nextS = strchr (s, ':'); + *nextS = '\0'; + fprintf_unfiltered (stream, " %s: ", s); + s = nextS + 1; + print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); + } + } + else + { + fprintf_unfiltered (stream, " %s", selector); + } + fprintf_unfiltered (stream, "]"); + /* "selector" was malloc'd by target_read_string. Free it. */ + xfree (selector); + return; + } + case OP_ARRAY: (*pos) += 3; nargs = longest_to_int (exp->elts[pc + 2].longconst); @@ -217,8 +275,7 @@ print_subexp (register struct expression *exp, register int *pos, } else { - int is_chill = exp->language_defn->la_language == language_chill; - fputs_filtered (is_chill ? " [" : " {", stream); + fputs_filtered (" {", stream); for (tem = 0; tem < nargs; tem++) { if (tem != 0) @@ -227,34 +284,22 @@ print_subexp (register struct expression *exp, register int *pos, } print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); } - fputs_filtered (is_chill ? "]" : "}", stream); + fputs_filtered ("}", stream); } return; case OP_LABELED: tem = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - - if (exp->language_defn->la_language == language_chill) - { - fputs_filtered (".", stream); - fputs_filtered (&exp->elts[pc + 2].string, stream); - fputs_filtered (exp->elts[*pos].opcode == OP_LABELED ? ", " - : ": ", - stream); - } - else - { - /* Gcc support both these syntaxes. Unsure which is preferred. */ + /* Gcc support both these syntaxes. Unsure which is preferred. */ #if 1 - fputs_filtered (&exp->elts[pc + 2].string, stream); - fputs_filtered (": ", stream); + fputs_filtered (&exp->elts[pc + 2].string, stream); + fputs_filtered (": ", stream); #else - fputs_filtered (".", stream); - fputs_filtered (&exp->elts[pc + 2].string, stream); - fputs_filtered ("=", stream); + fputs_filtered (".", stream); + fputs_filtered (&exp->elts[pc + 2].string, stream); + fputs_filtered ("=", stream); #endif - } print_subexp (exp, pos, stream, PREC_SUFFIX); return; @@ -334,7 +379,7 @@ print_subexp (register struct expression *exp, register int *pos, (*pos) += 2; if ((int) prec > (int) PREC_PREFIX) fputs_filtered ("(", stream); - if (exp->elts[pc + 1].type->code == TYPE_CODE_FUNC && + if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC && exp->elts[pc + 3].opcode == OP_LONG) { /* We have a minimal symbol fn, probably. It's encoded @@ -384,6 +429,13 @@ print_subexp (register struct expression *exp, register int *pos, fputs_filtered ("this", stream); return; + /* Objective-C ops */ + + case OP_OBJC_SELF: + ++(*pos); + fputs_filtered ("self", stream); /* The ObjC equivalent of "this". */ + return; + /* Modula-2 ops */ case MULTI_SUBSCRIPT: @@ -487,7 +539,7 @@ char * op_string (enum exp_opcode op) { int tem; - register const struct op_print *op_print_tab; + const struct op_print *op_print_tab; op_print_tab = current_language->la_op_print_tab; for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) @@ -499,10 +551,22 @@ op_string (enum exp_opcode op) /* Support for dumping the raw data from expressions in a human readable form. */ -static char *op_name (int opcode); +static char *op_name (struct expression *, enum exp_opcode); +static int dump_subexp_body (struct expression *exp, struct ui_file *, int); + +/* Name for OPCODE, when it appears in expression EXP. */ static char * -op_name (int opcode) +op_name (struct expression *exp, enum exp_opcode opcode) +{ + return exp->language_defn->la_exp_desc->op_name (opcode); +} + +/* Default name for the standard operator OPCODE (i.e., one defined in + the definition of enum exp_opcode). */ + +char * +op_name_standard (enum exp_opcode opcode) { switch (opcode) { @@ -677,6 +741,8 @@ op_name (int opcode) return "STRUCTOP_PTR"; case OP_THIS: return "OP_THIS"; + case OP_OBJC_SELF: + return "OP_OBJC_SELF"; case OP_SCOPE: return "OP_SCOPE"; case OP_TYPE: @@ -687,8 +753,8 @@ op_name (int opcode) } void -dump_prefix_expression (struct expression *exp, struct ui_file *stream, - char *note) +dump_raw_expression (struct expression *exp, struct ui_file *stream, + char *note) { int elt; char *opcode_name; @@ -697,11 +763,6 @@ dump_prefix_expression (struct expression *exp, struct ui_file *stream, fprintf_filtered (stream, "Dump of expression @ "); gdb_print_host_address (exp, stream); - fprintf_filtered (stream, ", %s:\nExpression: `", note); - if (exp->elts[0].opcode != OP_TYPE) - print_expression (exp, stream); - else - fprintf_filtered (stream, "Type printing not yet supported...."); fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n", exp->language_defn->la_name, exp->nelts, (long) sizeof (union exp_element)); @@ -710,7 +771,7 @@ dump_prefix_expression (struct expression *exp, struct ui_file *stream, for (elt = 0; elt < exp->nelts; elt++) { fprintf_filtered (stream, "\t%5d ", elt); - opcode_name = op_name (exp->elts[elt].opcode); + opcode_name = op_name (exp, exp->elts[elt].opcode); fprintf_filtered (stream, "%20s ", opcode_name); print_longest (stream, 'd', 0, exp->elts[elt].longconst); @@ -728,10 +789,11 @@ dump_prefix_expression (struct expression *exp, struct ui_file *stream, } } -static int dump_subexp (struct expression *exp, struct ui_file *stream, - int elt); +/* Dump the subexpression of prefix expression EXP whose operator is at + position ELT onto STREAM. Returns the position of the next + subexpression in EXP. */ -static int +int dump_subexp (struct expression *exp, struct ui_file *stream, int elt) { static int indent = 0; @@ -744,9 +806,34 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt) fprintf_filtered (stream, " "); indent += 2; - fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode)); + fprintf_filtered (stream, "%-20s ", op_name (exp, exp->elts[elt].opcode)); - switch (exp->elts[elt++].opcode) + elt = dump_subexp_body (exp, stream, elt); + + indent -= 2; + + return elt; +} + +/* Dump the operands of prefix expression EXP whose opcode is at + position ELT onto STREAM. Returns the position of the next + subexpression in EXP. */ + +static int +dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt) +{ + return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt); +} + +/* Default value for subexp_body in exp_descriptor vector. */ + +int +dump_subexp_body_standard (struct expression *exp, + struct ui_file *stream, int elt) +{ + int opcode = exp->elts[elt++].opcode; + + switch (opcode) { case TERNOP_COND: case TERNOP_SLICE: @@ -842,7 +929,7 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt) fprintf_filtered (stream, ", symbol @"); gdb_print_host_address (exp->elts[elt + 1].symbol, stream); fprintf_filtered (stream, " (%s)", - SYMBOL_NAME (exp->elts[elt + 1].symbol)); + DEPRECATED_SYMBOL_NAME (exp->elts[elt + 1].symbol)); elt += 3; break; case OP_LAST: @@ -864,7 +951,7 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt) break; case OP_FUNCALL: { - int nargs; + int i, nargs; nargs = longest_to_int (exp->elts[elt].longconst); @@ -956,20 +1043,17 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt) fprintf_filtered (stream, "Unknown format"); } - indent -= 2; - return elt; } void -dump_postfix_expression (struct expression *exp, struct ui_file *stream, - char *note) +dump_prefix_expression (struct expression *exp, struct ui_file *stream) { int elt; fprintf_filtered (stream, "Dump of expression @ "); gdb_print_host_address (exp, stream); - fprintf_filtered (stream, ", %s:\nExpression: `", note); + fputs_filtered (", after conversion to prefix form:\nExpression: `", stream); if (exp->elts[0].opcode != OP_TYPE) print_expression (exp, stream); else diff --git a/contrib/gdb/gdb/expression.h b/contrib/gdb/gdb/expression.h index 0fbab0357c5..03b45c2ef9a 100644 --- a/contrib/gdb/gdb/expression.h +++ b/contrib/gdb/gdb/expression.h @@ -1,5 +1,7 @@ /* Definitions for expressions stored in reversed prefix form, for GDB. - Copyright 1986, 1989, 1992, 1994, 2000 Free Software Foundation, Inc. + + Copyright 1986, 1989, 1992, 1994, 2000, 2003 Free Software + Foundation, Inc. This file is part of GDB. @@ -109,10 +111,11 @@ enum exp_opcode the second operand with itself that many times. */ BINOP_CONCAT, - /* For Chill and Pascal. */ + /* For (the deleted) Chill and Pascal. */ BINOP_IN, /* Returns 1 iff ARG1 IN ARG2. */ - /* This is the "colon operator" used various places in Chill. */ + /* This is the "colon operator" used various places in (the + deleted) Chill. */ BINOP_RANGE, /* This must be the highest BINOP_ value, for expprint.c. */ @@ -121,12 +124,13 @@ enum exp_opcode /* Operates on three values computed by following subexpressions. */ TERNOP_COND, /* ?: */ - /* A sub-string/sub-array. Chill syntax: OP1(OP2:OP3). - Return elements OP2 through OP3 of OP1. */ + /* A sub-string/sub-array. (the deleted) Chill syntax: + OP1(OP2:OP3). Return elements OP2 through OP3 of OP1. */ TERNOP_SLICE, - /* A sub-string/sub-array. Chill syntax: OP1(OP2 UP OP3). - Return OP3 elements of OP1, starting with element OP2. */ + /* A sub-string/sub-array. (The deleted) Chill syntax: OP1(OP2 UP + OP3). Return OP3 elements of OP1, starting with element + OP2. */ TERNOP_SLICE_COUNT, /* Multidimensional subscript operator, such as Modula-2 x[a,b,...]. @@ -179,6 +183,12 @@ enum exp_opcode making three exp_elements. */ OP_FUNCALL, + /* OP_OBJC_MSGCALL is followed by a string in the next exp_element and then an + integer. The string is the selector string. The integer is the number + of arguments to the message call. That many plus one values are used, + the first one being the object pointer. This is an Objective C message */ + OP_OBJC_MSGCALL, + /* This is EXACTLY like OP_FUNCALL but is semantically different. In F77, array subscript expressions, substring expressions and function calls are all exactly the same syntactically. They may @@ -251,7 +261,7 @@ enum exp_opcode UNOP_ODD, UNOP_TRUNC, - /* Chill builtin functions. */ + /* (The deleted) Chill builtin functions. */ UNOP_LOWER, UNOP_UPPER, UNOP_LENGTH, UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN, OP_BOOL, /* Modula-2 builtin BOOLEAN type */ @@ -271,22 +281,31 @@ enum exp_opcode STRUCTOP_STRUCT, STRUCTOP_PTR, - /* C++ */ - /* OP_THIS is just a placeholder for the class instance variable. + /* C++: OP_THIS is just a placeholder for the class instance variable. It just comes in a tight (OP_THIS, OP_THIS) pair. */ OP_THIS, + /* Objective-C: OP_OBJC_SELF is just a placeholder for the class instance + variable. It just comes in a tight (OP_OBJC_SELF, OP_OBJC_SELF) pair. */ + OP_OBJC_SELF, + + /* Objective C: "@selector" pseudo-operator */ + OP_OBJC_SELECTOR, + /* OP_SCOPE surrounds a type name and a field name. The type name is encoded as one element, but the field name stays as a string, which, of course, is variable length. */ OP_SCOPE, - /* Used to represent named structure field values in brace initializers - (or tuples as they are called in Chill). - The gcc C syntax is NAME:VALUE or .NAME=VALUE, the Chill syntax is - .NAME:VALUE. Multiple labels (as in the Chill syntax - .NAME1,.NAME2:VALUE) is represented as if it were - .NAME1:(.NAME2:VALUE) (though that is not valid Chill syntax). + /* Used to represent named structure field values in brace + initializers (or tuples as they are called in (the deleted) + Chill). + + The gcc C syntax is NAME:VALUE or .NAME=VALUE, the (the + deleted) Chill syntax is .NAME:VALUE. Multiple labels (as in + the (the deleted) Chill syntax .NAME1,.NAME2:VALUE) is + represented as if it were .NAME1:(.NAME2:VALUE) (though that is + not valid (the deleted) Chill syntax). The NAME is represented as for STRUCTOP_STRUCT; VALUE follows. */ OP_LABELED, @@ -300,7 +319,30 @@ enum exp_opcode OP_NAME, /* An unparsed expression. Used for Scheme (for now at least) */ - OP_EXPRSTRING + OP_EXPRSTRING, + + /* An Objective C Foundation Class NSString constant */ + OP_OBJC_NSSTRING, + + /* First extension operator. Individual language modules define + extra operators they need as constants with values + OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate + enumerated type definition: + enum foo_extension_operator { + BINOP_MOGRIFY = OP_EXTENDED0, + BINOP_FROB, + ... + }; */ + OP_EXTENDED0, + + /* Last possible extension operator. Defined to provide an + explicit and finite number of extended operators. */ + OP_EXTENDED_LAST = 0xff + /* NOTE: Eventually, we expect to convert to an object-oriented + formulation for expression operators that does away with the + need for these extension operators, and indeed for this + entire enumeration type. Therefore, consider the OP_EXTENDED + definitions to be a temporary measure. */ }; union exp_element @@ -371,11 +413,7 @@ extern void print_expression (struct expression *, struct ui_file *); extern char *op_string (enum exp_opcode); -extern void dump_prefix_expression (struct expression *, - struct ui_file *, - char *); -extern void dump_postfix_expression (struct expression *, - struct ui_file *, - char *); +extern void dump_raw_expression (struct expression *, struct ui_file *, char *); +extern void dump_prefix_expression (struct expression *, struct ui_file *); #endif /* !defined (EXPRESSION_H) */ diff --git a/contrib/gdb/gdb/f-exp.c b/contrib/gdb/gdb/f-exp.c new file mode 100644 index 00000000000..250de12b9d8 --- /dev/null +++ b/contrib/gdb/gdb/f-exp.c @@ -0,0 +1,2564 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + INT = 258, + FLOAT = 259, + STRING_LITERAL = 260, + BOOLEAN_LITERAL = 261, + NAME = 262, + TYPENAME = 263, + NAME_OR_INT = 264, + SIZEOF = 265, + ERROR = 266, + INT_KEYWORD = 267, + INT_S2_KEYWORD = 268, + LOGICAL_S1_KEYWORD = 269, + LOGICAL_S2_KEYWORD = 270, + LOGICAL_KEYWORD = 271, + REAL_KEYWORD = 272, + REAL_S8_KEYWORD = 273, + REAL_S16_KEYWORD = 274, + COMPLEX_S8_KEYWORD = 275, + COMPLEX_S16_KEYWORD = 276, + COMPLEX_S32_KEYWORD = 277, + BOOL_AND = 278, + BOOL_OR = 279, + BOOL_NOT = 280, + CHARACTER = 281, + VARIABLE = 282, + ASSIGN_MODIFY = 283, + ABOVE_COMMA = 284, + NOTEQUAL = 285, + EQUAL = 286, + GEQ = 287, + LEQ = 288, + GREATERTHAN = 289, + LESSTHAN = 290, + RSH = 291, + LSH = 292, + UNARY = 293 + }; +#endif +#define INT 258 +#define FLOAT 259 +#define STRING_LITERAL 260 +#define BOOLEAN_LITERAL 261 +#define NAME 262 +#define TYPENAME 263 +#define NAME_OR_INT 264 +#define SIZEOF 265 +#define ERROR 266 +#define INT_KEYWORD 267 +#define INT_S2_KEYWORD 268 +#define LOGICAL_S1_KEYWORD 269 +#define LOGICAL_S2_KEYWORD 270 +#define LOGICAL_KEYWORD 271 +#define REAL_KEYWORD 272 +#define REAL_S8_KEYWORD 273 +#define REAL_S16_KEYWORD 274 +#define COMPLEX_S8_KEYWORD 275 +#define COMPLEX_S16_KEYWORD 276 +#define COMPLEX_S32_KEYWORD 277 +#define BOOL_AND 278 +#define BOOL_OR 279 +#define BOOL_NOT 280 +#define CHARACTER 281 +#define VARIABLE 282 +#define ASSIGN_MODIFY 283 +#define ABOVE_COMMA 284 +#define NOTEQUAL 285 +#define EQUAL 286 +#define GEQ 287 +#define LEQ 288 +#define GREATERTHAN 289 +#define LESSTHAN 290 +#define RSH 291 +#define LSH 292 +#define UNARY 293 + + + + +/* Copy the first part of user declarations. */ +#line 44 "f-exp.y" + + +#include "defs.h" +#include "gdb_string.h" +#include "expression.h" +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "f-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" +#include + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in gdb. Note that these are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +#define yymaxdepth f_maxdepth +#define yyparse f_parse +#define yylex f_lex +#define yyerror f_error +#define yylval f_lval +#define yychar f_char +#define yydebug f_debug +#define yypact f_pact +#define yyr1 f_r1 +#define yyr2 f_r2 +#define yydef f_def +#define yychk f_chk +#define yypgo f_pgo +#define yyact f_act +#define yyexca f_exca +#define yyerrflag f_errflag +#define yynerrs f_nerrs +#define yyps f_ps +#define yypv f_pv +#define yys f_s +#define yy_yys f_yys +#define yystate f_state +#define yytmp f_tmp +#define yyv f_v +#define yy_yyv f_yyv +#define yyval f_val +#define yylloc f_lloc +#define yyreds f_reds /* With YYDEBUG defined */ +#define yytoks f_toks /* With YYDEBUG defined */ +#define yyname f_name /* With YYDEBUG defined */ +#define yyrule f_rule /* With YYDEBUG defined */ +#define yylhs f_yylhs +#define yylen f_yylen +#define yydefred f_yydefred +#define yydgoto f_yydgoto +#define yysindex f_yysindex +#define yyrindex f_yyrindex +#define yygindex f_yygindex +#define yytable f_yytable +#define yycheck f_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 1 /* Default to yydebug support */ +#endif + +#define YYFPRINTF parser_fprintf + +int yyparse (void); + +static int yylex (void); + +void yyerror (char *); + +static void growbuf_by_size (int); + +static int match_string_literal (void); + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 130 "f-exp.y" +typedef union YYSTYPE { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val; + DOUBLEST dval; + struct symbol *sym; + struct type *tval; + struct stoken sval; + struct ttype tsym; + struct symtoken ssym; + int voidval; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + + struct type **tvec; + int *ivec; + } YYSTYPE; +/* Line 191 of yacc.c. */ +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ +#line 151 "f-exp.y" + +/* YYSTYPE gets defined by %union */ +static int parse_number (char *, int, int, YYSTYPE *); + + +/* Line 214 of yacc.c. */ + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or xmalloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC xmalloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 46 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 460 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 55 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 17 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 80 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 125 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 293 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 49, 35, 2, + 51, 52, 47, 45, 29, 46, 2, 48, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 54, 2, + 2, 31, 2, 32, 44, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 34, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 33, 2, 53, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 30, 36, 37, 38, 39, 40, + 41, 42, 43, 50 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 13, 16, 19, 22, + 25, 28, 31, 32, 38, 39, 41, 43, 47, 51, + 55, 59, 64, 68, 72, 76, 80, 84, 88, 92, + 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, + 136, 140, 144, 148, 150, 152, 154, 156, 158, 163, + 165, 167, 169, 171, 173, 176, 178, 181, 183, 186, + 188, 192, 195, 197, 200, 204, 206, 208, 210, 212, + 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, + 236 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 56, 0, -1, 58, -1, 57, -1, 64, -1, 51, + 58, 52, -1, 47, 58, -1, 35, 58, -1, 46, + 58, -1, 25, 58, -1, 53, 58, -1, 10, 58, + -1, -1, 58, 51, 59, 60, 52, -1, -1, 58, + -1, 61, -1, 60, 29, 58, -1, 58, 54, 58, + -1, 58, 29, 58, -1, 51, 62, 52, -1, 51, + 64, 52, 58, -1, 58, 44, 58, -1, 58, 47, + 58, -1, 58, 48, 58, -1, 58, 49, 58, -1, + 58, 45, 58, -1, 58, 46, 58, -1, 58, 43, + 58, -1, 58, 42, 58, -1, 58, 37, 58, -1, + 58, 36, 58, -1, 58, 39, 58, -1, 58, 38, + 58, -1, 58, 41, 58, -1, 58, 40, 58, -1, + 58, 35, 58, -1, 58, 34, 58, -1, 58, 33, + 58, -1, 58, 23, 58, -1, 58, 24, 58, -1, + 58, 31, 58, -1, 58, 28, 58, -1, 3, -1, + 9, -1, 4, -1, 63, -1, 27, -1, 10, 51, + 64, 52, -1, 6, -1, 5, -1, 71, -1, 65, + -1, 69, -1, 69, 66, -1, 47, -1, 47, 66, + -1, 35, -1, 35, 66, -1, 67, -1, 51, 66, + 52, -1, 67, 68, -1, 68, -1, 51, 52, -1, + 51, 70, 52, -1, 8, -1, 12, -1, 13, -1, + 26, -1, 16, -1, 15, -1, 14, -1, 17, -1, + 18, -1, 19, -1, 20, -1, 21, -1, 22, -1, + 64, -1, 70, 29, 64, -1, 7, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 228, 228, 229, 232, 238, 243, 247, 251, 255, + 259, 263, 273, 272, 280, 283, 287, 291, 295, 300, + 304, 308, 316, 320, 324, 328, 332, 336, 340, 344, + 348, 352, 356, 360, 364, 368, 372, 376, 380, 384, + 389, 393, 397, 403, 410, 419, 426, 429, 432, 440, + 447, 455, 499, 502, 503, 546, 548, 550, 552, 554, + 557, 559, 561, 565, 567, 572, 574, 576, 578, 580, + 582, 584, 586, 588, 590, 592, 594, 596, 604, 609, + 624 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "INT", "FLOAT", "STRING_LITERAL", + "BOOLEAN_LITERAL", "NAME", "TYPENAME", "NAME_OR_INT", "SIZEOF", "ERROR", + "INT_KEYWORD", "INT_S2_KEYWORD", "LOGICAL_S1_KEYWORD", + "LOGICAL_S2_KEYWORD", "LOGICAL_KEYWORD", "REAL_KEYWORD", + "REAL_S8_KEYWORD", "REAL_S16_KEYWORD", "COMPLEX_S8_KEYWORD", + "COMPLEX_S16_KEYWORD", "COMPLEX_S32_KEYWORD", "BOOL_AND", "BOOL_OR", + "BOOL_NOT", "CHARACTER", "VARIABLE", "ASSIGN_MODIFY", "','", + "ABOVE_COMMA", "'='", "'?'", "'|'", "'^'", "'&'", "NOTEQUAL", "EQUAL", + "GEQ", "LEQ", "GREATERTHAN", "LESSTHAN", "RSH", "LSH", "'@'", "'+'", + "'-'", "'*'", "'/'", "'%'", "UNARY", "'('", "')'", "'~'", "':'", + "$accept", "start", "type_exp", "exp", "@1", "arglist", "substring", + "complexnum", "variable", "type", "ptype", "abs_decl", + "direct_abs_decl", "func_mod", "typebase", "nonempty_typelist", + "name_not_typename", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 44, + 284, 61, 63, 124, 94, 38, 285, 286, 287, 288, + 289, 290, 291, 292, 64, 43, 45, 42, 47, 37, + 293, 40, 41, 126, 58 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 55, 56, 56, 57, 58, 58, 58, 58, 58, + 58, 58, 59, 58, 60, 60, 60, 60, 61, 62, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 63, 64, 65, 65, 66, 66, 66, 66, 66, + 67, 67, 67, 68, 68, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, + 71 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 1, 3, 2, 2, 2, 2, + 2, 2, 0, 5, 0, 1, 1, 3, 3, 3, + 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 1, 1, 1, 1, 1, 4, 1, + 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, + 3, 2, 1, 2, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 0, 43, 45, 50, 49, 80, 65, 44, 0, 66, + 67, 71, 70, 69, 72, 73, 74, 75, 76, 77, + 0, 68, 47, 0, 0, 0, 0, 0, 0, 3, + 2, 46, 4, 52, 53, 51, 0, 11, 9, 7, + 8, 6, 0, 0, 0, 10, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 12, 57, + 55, 0, 54, 59, 62, 0, 0, 5, 20, 0, + 39, 40, 42, 41, 38, 37, 36, 31, 30, 33, + 32, 35, 34, 29, 28, 22, 26, 27, 23, 24, + 25, 14, 58, 56, 63, 78, 0, 0, 0, 61, + 48, 19, 21, 15, 0, 16, 60, 0, 64, 0, + 0, 13, 79, 18, 17 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char yydefgoto[] = +{ + -1, 28, 29, 42, 101, 114, 115, 43, 31, 105, + 33, 72, 73, 74, 34, 107, 35 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -59 +static const short yypact[] = +{ + 77, -59, -59, -59, -59, -59, -59, -59, 128, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + 137, -59, -59, 137, 137, 137, 77, 137, 2, -59, + 311, -59, -59, -59, -34, -59, 77, -45, -45, -45, + -45, -45, 281, -43, -36, -45, -59, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, -59, -34, + -34, 208, -59, -44, -59, -33, 137, -59, -59, 137, + 357, 338, 311, 311, 392, 409, 163, 223, 223, -10, + -10, -10, -10, 24, 24, 60, -37, -37, -45, -45, + -45, 137, -59, -59, -59, -59, -31, -26, 232, -59, + 188, 311, -45, 252, -24, -59, -59, 399, -59, 137, + 137, -59, -59, 311, 311 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -59, -59, -59, 0, -59, -59, -59, -59, -59, 4, + -59, -27, -59, -58, -59, -59, -59 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const unsigned char yytable[] = +{ + 30, 69, 46, 117, 32, 120, 68, 108, 37, 78, + 65, 66, 67, 70, 68, 109, 79, 71, 0, 110, + 38, 116, 0, 39, 40, 41, 118, 45, 121, 0, + 44, 0, 60, 61, 62, 63, 64, 65, 66, 67, + 75, 68, 102, 103, 106, 0, 0, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 62, 63, + 64, 65, 66, 67, 0, 68, 111, 0, 0, 112, + 1, 2, 3, 4, 5, 6, 7, 8, 0, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 0, 113, 20, 21, 22, 63, 64, 65, 66, 67, + 112, 68, 23, 0, 0, 0, 0, 0, 0, 123, + 124, 122, 0, 24, 25, 0, 0, 0, 26, 0, + 27, 1, 2, 3, 4, 5, 0, 7, 8, 0, + 1, 2, 3, 4, 5, 0, 7, 8, 0, 0, + 0, 0, 0, 20, 0, 22, 0, 0, 0, 0, + 0, 0, 20, 23, 22, 0, 0, 0, 0, 0, + 0, 0, 23, 0, 24, 25, 0, 0, 0, 36, + 0, 27, 0, 24, 25, 0, 0, 0, 26, 0, + 27, 1, 2, 3, 4, 5, 0, 7, 8, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 20, 68, 22, 6, 0, 0, 0, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 0, 0, 0, 21, 0, 0, 0, 0, 26, + 6, 27, 0, 69, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 70, 0, 0, 21, 71, + 104, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 0, 68, 47, 48, 0, 0, 0, + 49, 0, 0, 50, 104, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 0, 68, 47, 48, 119, 0, 0, 49, + 76, 0, 50, 0, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 0, 68, 77, 47, 48, 0, 0, 0, 49, + 0, 0, 50, 0, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 47, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 0, 68, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 6, 68, 0, + 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 0, 0, 0, 21, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 0, 68, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 0, + 68 +}; + +static const yysigned_char yycheck[] = +{ + 0, 35, 0, 29, 0, 29, 51, 51, 8, 52, + 47, 48, 49, 47, 51, 73, 52, 51, -1, 52, + 20, 52, -1, 23, 24, 25, 52, 27, 52, -1, + 26, -1, 42, 43, 44, 45, 46, 47, 48, 49, + 36, 51, 69, 70, 71, -1, -1, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 44, 45, + 46, 47, 48, 49, -1, 51, 76, -1, -1, 79, + 3, 4, 5, 6, 7, 8, 9, 10, -1, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + -1, 101, 25, 26, 27, 45, 46, 47, 48, 49, + 110, 51, 35, -1, -1, -1, -1, -1, -1, 119, + 120, 117, -1, 46, 47, -1, -1, -1, 51, -1, + 53, 3, 4, 5, 6, 7, -1, 9, 10, -1, + 3, 4, 5, 6, 7, -1, 9, 10, -1, -1, + -1, -1, -1, 25, -1, 27, -1, -1, -1, -1, + -1, -1, 25, 35, 27, -1, -1, -1, -1, -1, + -1, -1, 35, -1, 46, 47, -1, -1, -1, 51, + -1, 53, -1, 46, 47, -1, -1, -1, 51, -1, + 53, 3, 4, 5, 6, 7, -1, 9, 10, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 25, 51, 27, 8, -1, -1, -1, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, -1, -1, -1, 26, -1, -1, -1, -1, 51, + 8, 53, -1, 35, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 47, -1, -1, 26, 51, + 52, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, -1, 51, 23, 24, -1, -1, -1, + 28, -1, -1, 31, 52, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, -1, 51, 23, 24, 54, -1, -1, 28, + 29, -1, 31, -1, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, -1, 51, 52, 23, 24, -1, -1, -1, 28, + -1, -1, 31, -1, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 23, 51, -1, -1, -1, -1, -1, -1, -1, + -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, -1, 51, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 8, 51, -1, + -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, -1, -1, -1, 26, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, -1, 51, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, -1, + 51 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 25, 26, 27, 35, 46, 47, 51, 53, 56, 57, + 58, 63, 64, 65, 69, 71, 51, 58, 58, 58, + 58, 58, 58, 62, 64, 58, 0, 23, 24, 28, + 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 51, 35, + 47, 51, 66, 67, 68, 64, 29, 52, 52, 52, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 59, 66, 66, 52, 64, 66, 70, 51, 68, + 52, 58, 58, 58, 60, 61, 52, 29, 52, 54, + 29, 52, 64, 58, 58 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to xreallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to xreallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: +#line 233 "f-exp.y" + { write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(yyvsp[0].tval); + write_exp_elt_opcode(OP_TYPE); } + break; + + case 5: +#line 239 "f-exp.y" + { } + break; + + case 6: +#line 244 "f-exp.y" + { write_exp_elt_opcode (UNOP_IND); } + break; + + case 7: +#line 248 "f-exp.y" + { write_exp_elt_opcode (UNOP_ADDR); } + break; + + case 8: +#line 252 "f-exp.y" + { write_exp_elt_opcode (UNOP_NEG); } + break; + + case 9: +#line 256 "f-exp.y" + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + break; + + case 10: +#line 260 "f-exp.y" + { write_exp_elt_opcode (UNOP_COMPLEMENT); } + break; + + case 11: +#line 264 "f-exp.y" + { write_exp_elt_opcode (UNOP_SIZEOF); } + break; + + case 12: +#line 273 "f-exp.y" + { start_arglist (); } + break; + + case 13: +#line 275 "f-exp.y" + { write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); + write_exp_elt_longcst ((LONGEST) end_arglist ()); + write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); } + break; + + case 15: +#line 284 "f-exp.y" + { arglist_len = 1; } + break; + + case 16: +#line 288 "f-exp.y" + { arglist_len = 2;} + break; + + case 17: +#line 292 "f-exp.y" + { arglist_len++; } + break; + + case 18: +#line 296 "f-exp.y" + { } + break; + + case 19: +#line 301 "f-exp.y" + { } + break; + + case 20: +#line 305 "f-exp.y" + { write_exp_elt_opcode(OP_COMPLEX); } + break; + + case 21: +#line 309 "f-exp.y" + { write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (yyvsp[-2].tval); + write_exp_elt_opcode (UNOP_CAST); } + break; + + case 22: +#line 317 "f-exp.y" + { write_exp_elt_opcode (BINOP_REPEAT); } + break; + + case 23: +#line 321 "f-exp.y" + { write_exp_elt_opcode (BINOP_MUL); } + break; + + case 24: +#line 325 "f-exp.y" + { write_exp_elt_opcode (BINOP_DIV); } + break; + + case 25: +#line 329 "f-exp.y" + { write_exp_elt_opcode (BINOP_REM); } + break; + + case 26: +#line 333 "f-exp.y" + { write_exp_elt_opcode (BINOP_ADD); } + break; + + case 27: +#line 337 "f-exp.y" + { write_exp_elt_opcode (BINOP_SUB); } + break; + + case 28: +#line 341 "f-exp.y" + { write_exp_elt_opcode (BINOP_LSH); } + break; + + case 29: +#line 345 "f-exp.y" + { write_exp_elt_opcode (BINOP_RSH); } + break; + + case 30: +#line 349 "f-exp.y" + { write_exp_elt_opcode (BINOP_EQUAL); } + break; + + case 31: +#line 353 "f-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 32: +#line 357 "f-exp.y" + { write_exp_elt_opcode (BINOP_LEQ); } + break; + + case 33: +#line 361 "f-exp.y" + { write_exp_elt_opcode (BINOP_GEQ); } + break; + + case 34: +#line 365 "f-exp.y" + { write_exp_elt_opcode (BINOP_LESS); } + break; + + case 35: +#line 369 "f-exp.y" + { write_exp_elt_opcode (BINOP_GTR); } + break; + + case 36: +#line 373 "f-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + break; + + case 37: +#line 377 "f-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + break; + + case 38: +#line 381 "f-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + break; + + case 39: +#line 385 "f-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + break; + + case 40: +#line 390 "f-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + break; + + case 41: +#line 394 "f-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN); } + break; + + case 42: +#line 398 "f-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode (yyvsp[-1].opcode); + write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } + break; + + case 43: +#line 404 "f-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (yyvsp[0].typed_val.type); + write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val.val)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 44: +#line 411 "f-exp.y" + { YYSTYPE val; + parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (val.typed_val.type); + write_exp_elt_longcst ((LONGEST)val.typed_val.val); + write_exp_elt_opcode (OP_LONG); } + break; + + case 45: +#line 420 "f-exp.y" + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type (builtin_type_f_real_s8); + write_exp_elt_dblcst (yyvsp[0].dval); + write_exp_elt_opcode (OP_DOUBLE); } + break; + + case 48: +#line 433 "f-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_f_integer); + CHECK_TYPEDEF (yyvsp[-1].tval); + write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 49: +#line 441 "f-exp.y" + { write_exp_elt_opcode (OP_BOOL); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_BOOL); + } + break; + + case 50: +#line 448 "f-exp.y" + { + write_exp_elt_opcode (OP_STRING); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_STRING); + } + break; + + case 51: +#line 456 "f-exp.y" + { struct symbol *sym = yyvsp[0].ssym.sym; + + if (sym) + { + if (symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block_found, + innermost_block)) + innermost_block = block_found; + } + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not + another more inner frame which happens to + be in the same block. */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + break; + } + else + { + struct minimal_symbol *msymbol; + char *arg = copy_name (yyvsp[0].ssym.stoken); + + msymbol = + lookup_minimal_symbol (arg, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", + copy_name (yyvsp[0].ssym.stoken)); + } + } + break; + + case 54: +#line 504 "f-exp.y" + { + /* This is where the interesting stuff happens. */ + int done = 0; + int array_size; + struct type *follow_type = yyvsp[-1].tval; + struct type *range_type; + + while (!done) + switch (pop_type ()) + { + case tp_end: + done = 1; + break; + case tp_pointer: + follow_type = lookup_pointer_type (follow_type); + break; + case tp_reference: + follow_type = lookup_reference_type (follow_type); + break; + case tp_array: + array_size = pop_type_int (); + if (array_size != -1) + { + range_type = + create_range_type ((struct type *) NULL, + builtin_type_f_integer, 0, + array_size - 1); + follow_type = + create_array_type ((struct type *) NULL, + follow_type, range_type); + } + else + follow_type = lookup_pointer_type (follow_type); + break; + case tp_function: + follow_type = lookup_function_type (follow_type); + break; + } + yyval.tval = follow_type; + } + break; + + case 55: +#line 547 "f-exp.y" + { push_type (tp_pointer); yyval.voidval = 0; } + break; + + case 56: +#line 549 "f-exp.y" + { push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; } + break; + + case 57: +#line 551 "f-exp.y" + { push_type (tp_reference); yyval.voidval = 0; } + break; + + case 58: +#line 553 "f-exp.y" + { push_type (tp_reference); yyval.voidval = yyvsp[0].voidval; } + break; + + case 60: +#line 558 "f-exp.y" + { yyval.voidval = yyvsp[-1].voidval; } + break; + + case 61: +#line 560 "f-exp.y" + { push_type (tp_function); } + break; + + case 62: +#line 562 "f-exp.y" + { push_type (tp_function); } + break; + + case 63: +#line 566 "f-exp.y" + { yyval.voidval = 0; } + break; + + case 64: +#line 568 "f-exp.y" + { free (yyvsp[-1].tvec); yyval.voidval = 0; } + break; + + case 65: +#line 573 "f-exp.y" + { yyval.tval = yyvsp[0].tsym.type; } + break; + + case 66: +#line 575 "f-exp.y" + { yyval.tval = builtin_type_f_integer; } + break; + + case 67: +#line 577 "f-exp.y" + { yyval.tval = builtin_type_f_integer_s2; } + break; + + case 68: +#line 579 "f-exp.y" + { yyval.tval = builtin_type_f_character; } + break; + + case 69: +#line 581 "f-exp.y" + { yyval.tval = builtin_type_f_logical;} + break; + + case 70: +#line 583 "f-exp.y" + { yyval.tval = builtin_type_f_logical_s2;} + break; + + case 71: +#line 585 "f-exp.y" + { yyval.tval = builtin_type_f_logical_s1;} + break; + + case 72: +#line 587 "f-exp.y" + { yyval.tval = builtin_type_f_real;} + break; + + case 73: +#line 589 "f-exp.y" + { yyval.tval = builtin_type_f_real_s8;} + break; + + case 74: +#line 591 "f-exp.y" + { yyval.tval = builtin_type_f_real_s16;} + break; + + case 75: +#line 593 "f-exp.y" + { yyval.tval = builtin_type_f_complex_s8;} + break; + + case 76: +#line 595 "f-exp.y" + { yyval.tval = builtin_type_f_complex_s16;} + break; + + case 77: +#line 597 "f-exp.y" + { yyval.tval = builtin_type_f_complex_s32;} + break; + + case 78: +#line 605 "f-exp.y" + { yyval.tvec = (struct type **) xmalloc (sizeof (struct type *) * 2); + yyval.ivec[0] = 1; /* Number of types in vector */ + yyval.tvec[1] = yyvsp[0].tval; + } + break; + + case 79: +#line 610 "f-exp.y" + { int len = sizeof (struct type *) * (++(yyvsp[-2].ivec[0]) + 1); + yyval.tvec = (struct type **) xrealloc ((char *) yyvsp[-2].tvec, len); + yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval; + } + break; + + + } + +/* Line 991 of yacc.c. */ + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. Doesn't work in C++ */ +#ifndef __cplusplus +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 634 "f-exp.y" + + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. + LEN is the number of characters in it. */ + +/*** Needs some error checking for the float case ***/ + +static int +parse_number (p, len, parsed_float, putithere) + char *p; + int len; + int parsed_float; + YYSTYPE *putithere; +{ + LONGEST n = 0; + LONGEST prevn = 0; + int c; + int base = input_radix; + int unsigned_p = 0; + int long_p = 0; + ULONGEST high_bit; + struct type *signed_type; + struct type *unsigned_type; + + if (parsed_float) + { + /* It's a float since it contains a point or an exponent. */ + /* [dD] is not understood as an exponent by atof, change it to 'e'. */ + char *tmp, *tmp2; + + tmp = xstrdup (p); + for (tmp2 = tmp; *tmp2; ++tmp2) + if (*tmp2 == 'd' || *tmp2 == 'D') + *tmp2 = 'e'; + putithere->dval = atof (tmp); + free (tmp); + return FLOAT; + } + + /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ + if (p[0] == '0') + switch (p[1]) + { + case 'x': + case 'X': + if (len >= 3) + { + p += 2; + base = 16; + len -= 2; + } + break; + + case 't': + case 'T': + case 'd': + case 'D': + if (len >= 3) + { + p += 2; + base = 10; + len -= 2; + } + break; + + default: + base = 8; + break; + } + + while (len-- > 0) + { + c = *p++; + if (isupper (c)) + c = tolower (c); + if (len == 0 && c == 'l') + long_p = 1; + else if (len == 0 && c == 'u') + unsigned_p = 1; + else + { + int i; + if (c >= '0' && c <= '9') + i = c - '0'; + else if (c >= 'a' && c <= 'f') + i = c - 'a' + 10; + else + return ERROR; /* Char not a digit */ + if (i >= base) + return ERROR; /* Invalid digit in this base */ + n *= base; + n += i; + } + /* Portably test for overflow (only works for nonzero values, so make + a second check for zero). */ + if ((prevn >= n) && n != 0) + unsigned_p=1; /* Try something unsigned */ + /* If range checking enabled, portably test for unsigned overflow. */ + if (RANGE_CHECK && n != 0) + { + if ((unsigned_p && (unsigned)prevn >= (unsigned)n)) + range_error("Overflow on numeric constant."); + } + prevn = n; + } + + /* If the number is too big to be an int, or it's got an l suffix + then it's a long. Work out if this has to be a long by + shifting right and and seeing if anything remains, and the + target int size is different to the target long size. + + In the expression below, we could have tested + (n >> TARGET_INT_BIT) + to see if it was zero, + but too many compilers warn about that, when ints and longs + are the same size. So we shift it twice, with fewer bits + each time, for the same result. */ + + if ((TARGET_INT_BIT != TARGET_LONG_BIT + && ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */ + || long_p) + { + high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1); + unsigned_type = builtin_type_unsigned_long; + signed_type = builtin_type_long; + } + else + { + high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1); + unsigned_type = builtin_type_unsigned_int; + signed_type = builtin_type_int; + } + + putithere->typed_val.val = n; + + /* If the high bit of the worked out type is set then this number + has to be unsigned. */ + + if (unsigned_p || (n & high_bit)) + putithere->typed_val.type = unsigned_type; + else + putithere->typed_val.type = signed_type; + + return INT; +} + +struct token +{ + char *operator; + int token; + enum exp_opcode opcode; +}; + +static const struct token dot_ops[] = +{ + { ".and.", BOOL_AND, BINOP_END }, + { ".AND.", BOOL_AND, BINOP_END }, + { ".or.", BOOL_OR, BINOP_END }, + { ".OR.", BOOL_OR, BINOP_END }, + { ".not.", BOOL_NOT, BINOP_END }, + { ".NOT.", BOOL_NOT, BINOP_END }, + { ".eq.", EQUAL, BINOP_END }, + { ".EQ.", EQUAL, BINOP_END }, + { ".eqv.", EQUAL, BINOP_END }, + { ".NEQV.", NOTEQUAL, BINOP_END }, + { ".neqv.", NOTEQUAL, BINOP_END }, + { ".EQV.", EQUAL, BINOP_END }, + { ".ne.", NOTEQUAL, BINOP_END }, + { ".NE.", NOTEQUAL, BINOP_END }, + { ".le.", LEQ, BINOP_END }, + { ".LE.", LEQ, BINOP_END }, + { ".ge.", GEQ, BINOP_END }, + { ".GE.", GEQ, BINOP_END }, + { ".gt.", GREATERTHAN, BINOP_END }, + { ".GT.", GREATERTHAN, BINOP_END }, + { ".lt.", LESSTHAN, BINOP_END }, + { ".LT.", LESSTHAN, BINOP_END }, + { NULL, 0, 0 } +}; + +struct f77_boolean_val +{ + char *name; + int value; +}; + +static const struct f77_boolean_val boolean_values[] = +{ + { ".true.", 1 }, + { ".TRUE.", 1 }, + { ".false.", 0 }, + { ".FALSE.", 0 }, + { NULL, 0 } +}; + +static const struct token f77_keywords[] = +{ + { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END }, + { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END }, + { "character", CHARACTER, BINOP_END }, + { "integer_2", INT_S2_KEYWORD, BINOP_END }, + { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END }, + { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END }, + { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END }, + { "integer", INT_KEYWORD, BINOP_END }, + { "logical", LOGICAL_KEYWORD, BINOP_END }, + { "real_16", REAL_S16_KEYWORD, BINOP_END }, + { "complex", COMPLEX_S8_KEYWORD, BINOP_END }, + { "sizeof", SIZEOF, BINOP_END }, + { "real_8", REAL_S8_KEYWORD, BINOP_END }, + { "real", REAL_KEYWORD, BINOP_END }, + { NULL, 0, 0 } +}; + +/* Implementation of a dynamically expandable buffer for processing input + characters acquired through lexptr and building a value to return in + yylval. Ripped off from ch-exp.y */ + +static char *tempbuf; /* Current buffer contents */ +static int tempbufsize; /* Size of allocated buffer */ +static int tempbufindex; /* Current index into buffer */ + +#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */ + +#define CHECKBUF(size) \ + do { \ + if (tempbufindex + (size) >= tempbufsize) \ + { \ + growbuf_by_size (size); \ + } \ + } while (0); + + +/* Grow the static temp buffer if necessary, including allocating the first one + on demand. */ + +static void +growbuf_by_size (count) + int count; +{ + int growby; + + growby = max (count, GROWBY_MIN_SIZE); + tempbufsize += growby; + if (tempbuf == NULL) + tempbuf = (char *) xmalloc (tempbufsize); + else + tempbuf = (char *) xrealloc (tempbuf, tempbufsize); +} + +/* Blatantly ripped off from ch-exp.y. This routine recognizes F77 + string-literals. + + Recognize a string literal. A string literal is a nonzero sequence + of characters enclosed in matching single quotes, except that + a single character inside single quotes is a character literal, which + we reject as a string literal. To embed the terminator character inside + a string, it is simply doubled (I.E. 'this''is''one''string') */ + +static int +match_string_literal () +{ + char *tokptr = lexptr; + + for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++) + { + CHECKBUF (1); + if (*tokptr == *lexptr) + { + if (*(tokptr + 1) == *lexptr) + tokptr++; + else + break; + } + tempbuf[tempbufindex++] = *tokptr; + } + if (*tokptr == '\0' /* no terminator */ + || tempbufindex == 0) /* no string */ + return 0; + else + { + tempbuf[tempbufindex] = '\0'; + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = ++tokptr; + return STRING_LITERAL; + } +} + +/* Read one token, getting characters through lexptr. */ + +static int +yylex () +{ + int c; + int namelen; + unsigned int i,token; + char *tokstart; + + retry: + + prev_lexptr = lexptr; + + tokstart = lexptr; + + /* First of all, let us make sure we are not dealing with the + special tokens .true. and .false. which evaluate to 1 and 0. */ + + if (*lexptr == '.') + { + for (i = 0; boolean_values[i].name != NULL; i++) + { + if (strncmp (tokstart, boolean_values[i].name, + strlen (boolean_values[i].name)) == 0) + { + lexptr += strlen (boolean_values[i].name); + yylval.lval = boolean_values[i].value; + return BOOLEAN_LITERAL; + } + } + } + + /* See if it is a special .foo. operator */ + + for (i = 0; dot_ops[i].operator != NULL; i++) + if (strncmp (tokstart, dot_ops[i].operator, strlen (dot_ops[i].operator)) == 0) + { + lexptr += strlen (dot_ops[i].operator); + yylval.opcode = dot_ops[i].opcode; + return dot_ops[i].token; + } + + switch (c = *tokstart) + { + case 0: + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '\'': + token = match_string_literal (); + if (token != 0) + return (token); + break; + + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return c; + + case '.': + /* Might be a floating point number. */ + if (lexptr[1] < '0' || lexptr[1] > '9') + goto symbol; /* Nope, must be a symbol. */ + /* FALL THRU into number case. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + /* It's a number. */ + int got_dot = 0, got_e = 0, got_d = 0, toktype; + char *p = tokstart; + int hex = input_radix > 10; + + if (c == '0' && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + hex = 1; + } + else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) + { + p += 2; + hex = 0; + } + + for (;; ++p) + { + if (!hex && !got_e && (*p == 'e' || *p == 'E')) + got_dot = got_e = 1; + else if (!hex && !got_d && (*p == 'd' || *p == 'D')) + got_dot = got_d = 1; + else if (!hex && !got_dot && *p == '.') + got_dot = 1; + else if (((got_e && (p[-1] == 'e' || p[-1] == 'E')) + || (got_d && (p[-1] == 'd' || p[-1] == 'D'))) + && (*p == '-' || *p == '+')) + /* This is the sign of the exponent, not the end of the + number. */ + continue; + /* We will take any letters or digits. parse_number will + complain if past the radix, or if L or U are not final. */ + else if ((*p < '0' || *p > '9') + && ((*p < 'a' || *p > 'z') + && (*p < 'A' || *p > 'Z'))) + break; + } + toktype = parse_number (tokstart, p - tokstart, got_dot|got_e|got_d, + &yylval); + if (toktype == ERROR) + { + char *err_copy = (char *) alloca (p - tokstart + 1); + + memcpy (err_copy, tokstart, p - tokstart); + err_copy[p - tokstart] = 0; + error ("Invalid number \"%s\".", err_copy); + } + lexptr = p; + return toktype; + } + + case '+': + case '-': + case '*': + case '/': + case '%': + case '|': + case '&': + case '^': + case '~': + case '!': + case '@': + case '<': + case '>': + case '[': + case ']': + case '?': + case ':': + case '=': + case '{': + case '}': + symbol: + lexptr++; + return c; + } + + if (!(c == '_' || c == '$' + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + /* We must have come across a bad character (e.g. ';'). */ + error ("Invalid character '%c' in expression.", c); + + namelen = 0; + for (c = tokstart[namelen]; + (c == '_' || c == '$' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); + c = tokstart[++namelen]); + + /* The token "if" terminates the expression and is NOT + removed from the input stream. */ + + if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') + return 0; + + lexptr += namelen; + + /* Catch specific keywords. */ + + for (i = 0; f77_keywords[i].operator != NULL; i++) + if (strncmp (tokstart, f77_keywords[i].operator, + strlen(f77_keywords[i].operator)) == 0) + { + /* lexptr += strlen(f77_keywords[i].operator); */ + yylval.opcode = f77_keywords[i].opcode; + return f77_keywords[i].token; + } + + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + if (*tokstart == '$') + { + write_dollar_variable (yylval.sval); + return VARIABLE; + } + + /* Use token-type TYPENAME for symbols that happen to be defined + currently as names of types; NAME for other symbols. + The caller is not constrained to care about the distinction. */ + { + char *tmp = copy_name (yylval.sval); + struct symbol *sym; + int is_a_field_of_this = 0; + int hextype; + + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + current_language->la_language == language_cplus + ? &is_a_field_of_this : NULL, + NULL); + if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + { + yylval.tsym.type = SYMBOL_TYPE (sym); + return TYPENAME; + } + if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) + return TYPENAME; + + /* Input names that aren't symbols but ARE valid hex numbers, + when the input radix permits them, can be names or numbers + depending on the parse. Note we support radixes > 16 here. */ + if (!sym + && ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) + || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) + { + YYSTYPE newlval; /* Its value is ignored. */ + hextype = parse_number (tokstart, namelen, 0, &newlval); + if (hextype == INT) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME_OR_INT; + } + } + + /* Any other kind of symbol */ + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME; + } +} + +void +yyerror (msg) + char *msg; +{ + if (prev_lexptr) + lexptr = prev_lexptr; + + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); +} + + diff --git a/contrib/gdb/gdb/f-exp.y b/contrib/gdb/gdb/f-exp.y index 7cbfd5ac8f2..adff33b4dd3 100644 --- a/contrib/gdb/gdb/f-exp.y +++ b/contrib/gdb/gdb/f-exp.y @@ -53,6 +53,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" /* Required by objfiles.h. */ #include "symfile.h" /* Required by objfiles.h. */ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" #include /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), @@ -91,6 +92,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yylloc f_lloc #define yyreds f_reds /* With YYDEBUG defined */ #define yytoks f_toks /* With YYDEBUG defined */ +#define yyname f_name /* With YYDEBUG defined */ +#define yyrule f_rule /* With YYDEBUG defined */ #define yylhs f_yylhs #define yylen f_yylen #define yydefred f_yydefred @@ -102,9 +105,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yycheck f_yycheck #ifndef YYDEBUG -#define YYDEBUG 1 /* Default to no yydebug support */ +#define YYDEBUG 1 /* Default to yydebug support */ #endif +#define YYFPRINTF parser_fprintf + int yyparse (void); static int yylex (void); @@ -237,9 +242,11 @@ exp : '(' exp ')' /* Expressions, not including the comma operator. */ exp : '*' exp %prec UNARY { write_exp_elt_opcode (UNOP_IND); } + ; exp : '&' exp %prec UNARY { write_exp_elt_opcode (UNOP_ADDR); } + ; exp : '-' exp %prec UNARY { write_exp_elt_opcode (UNOP_NEG); } @@ -279,6 +286,7 @@ arglist : exp arglist : substring { arglist_len = 2;} + ; arglist : arglist ',' exp %prec ABOVE_COMMA { arglist_len++; } @@ -468,7 +476,7 @@ variable: name_not_typename else { struct minimal_symbol *msymbol; - register char *arg = copy_name ($1.stoken); + char *arg = copy_name ($1.stoken); msymbol = lookup_minimal_symbol (arg, NULL, NULL); @@ -557,7 +565,7 @@ direct_abs_decl: '(' abs_decl ')' func_mod: '(' ')' { $$ = 0; } | '(' nonempty_typelist ')' - { free ((PTR)$2); $$ = 0; } + { free ($2); $$ = 0; } ; typebase /* Implements (approximately): (type-qualifier)* type-specifier */ @@ -633,15 +641,15 @@ name_not_typename : NAME static int parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; + char *p; + int len; int parsed_float; YYSTYPE *putithere; { - register LONGEST n = 0; - register LONGEST prevn = 0; - register int c; - register int base = input_radix; + LONGEST n = 0; + LONGEST prevn = 0; + int c; + int base = input_radix; int unsigned_p = 0; int long_p = 0; ULONGEST high_bit; @@ -924,7 +932,9 @@ yylex () char *tokstart; retry: - + + prev_lexptr = lexptr; + tokstart = lexptr; /* First of all, let us make sure we are not dealing with the @@ -934,8 +944,8 @@ yylex () { for (i = 0; boolean_values[i].name != NULL; i++) { - if STREQN (tokstart, boolean_values[i].name, - strlen (boolean_values[i].name)) + if (strncmp (tokstart, boolean_values[i].name, + strlen (boolean_values[i].name)) == 0) { lexptr += strlen (boolean_values[i].name); yylval.lval = boolean_values[i].value; @@ -947,7 +957,7 @@ yylex () /* See if it is a special .foo. operator */ for (i = 0; dot_ops[i].operator != NULL; i++) - if (STREQN (tokstart, dot_ops[i].operator, strlen (dot_ops[i].operator))) + if (strncmp (tokstart, dot_ops[i].operator, strlen (dot_ops[i].operator)) == 0) { lexptr += strlen (dot_ops[i].operator); yylval.opcode = dot_ops[i].opcode; @@ -1008,7 +1018,7 @@ yylex () { /* It's a number. */ int got_dot = 0, got_e = 0, got_d = 0, toktype; - register char *p = tokstart; + char *p = tokstart; int hex = input_radix > 10; if (c == '0' && (p[1] == 'x' || p[1] == 'X')) @@ -1104,8 +1114,8 @@ yylex () /* Catch specific keywords. */ for (i = 0; f77_keywords[i].operator != NULL; i++) - if (STREQN(tokstart, f77_keywords[i].operator, - strlen(f77_keywords[i].operator))) + if (strncmp (tokstart, f77_keywords[i].operator, + strlen(f77_keywords[i].operator)) == 0) { /* lexptr += strlen(f77_keywords[i].operator); */ yylval.opcode = f77_keywords[i].opcode; @@ -1131,7 +1141,7 @@ yylex () int hextype; sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, + VAR_DOMAIN, current_language->la_language == language_cplus ? &is_a_field_of_this : NULL, NULL); @@ -1171,5 +1181,8 @@ void yyerror (msg) char *msg; { + if (prev_lexptr) + lexptr = prev_lexptr; + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); } diff --git a/contrib/gdb/gdb/f-lang.c b/contrib/gdb/gdb/f-lang.c index 1727bda8d2b..1e7cd45362c 100644 --- a/contrib/gdb/gdb/f-lang.c +++ b/contrib/gdb/gdb/f-lang.c @@ -1,5 +1,5 @@ /* Fortran language support routines for GDB, the GNU debugger. - Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Motorola. Adapted from the C parser by Farooq Butt (fmbutt@engage.sps.mot.com). @@ -30,6 +30,7 @@ #include "language.h" #include "f-lang.h" #include "valprint.h" +#include "value.h" /* The built-in types of F77. FIXME: integer*4 is missing, plain logical is missing (builtin_type_logical is logical*4). */ @@ -99,7 +100,7 @@ static void f_emit_char (int c, struct ui_file * stream, int quoter); be replaced with a true F77 version. */ static void -f_emit_char (register int c, struct ui_file *stream, int quoter) +f_emit_char (int c, struct ui_file *stream, int quoter) { c &= 0xFF; /* Avoid sign bit follies */ @@ -163,11 +164,10 @@ static void f_printstr (struct ui_file *stream, char *string, unsigned int length, int width, int force_ellipses) { - register unsigned int i; + unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; - extern int inspect_it; if (length == 0) { @@ -250,7 +250,7 @@ f_printstr (struct ui_file *stream, char *string, unsigned int length, static struct type * f_create_fundamental_type (struct objfile *objfile, int typeid) { - register struct type *type = NULL; + struct type *type = NULL; switch (typeid) { @@ -462,9 +462,9 @@ const struct language_defn f_language_defn = range_check_on, type_check_on, case_sensitive_off, + &exp_descriptor_standard, f_parse, /* parser */ f_error, /* parser error function */ - evaluate_subexp_standard, f_printchar, /* Print character constant */ f_printstr, /* function to print string constant */ f_emit_char, /* Function to print a single character */ @@ -472,6 +472,11 @@ const struct language_defn f_language_defn = f_print_type, /* Print a type using appropriate syntax */ f_val_print, /* Print a value using appropriate syntax */ c_value_print, /* FIXME */ + NULL, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%o", "0", "o", ""}, /* Octal format info */ {"%d", "", "d", ""}, /* Decimal format info */ @@ -480,11 +485,12 @@ const struct language_defn f_language_defn = 0, /* arrays are first-class (not c-style) */ 1, /* String lower bound */ &builtin_type_f_character, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; -void -_initialize_f_language (void) +static void +build_fortran_types (void) { builtin_type_f_void = init_type (TYPE_CODE_VOID, 1, @@ -556,6 +562,28 @@ _initialize_f_language (void) 0, "complex*32", (struct objfile *) NULL); TYPE_TARGET_TYPE (builtin_type_f_complex_s32) = builtin_type_f_real_s16; +} + +void +_initialize_f_language (void) +{ + build_fortran_types (); + + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_character); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_logical); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_logical_s1); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_logical_s2); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_integer); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_integer_s2); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_real); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_real_s8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_real_s16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_complex_s8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_complex_s16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_complex_s32); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_f_void); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_string); + deprecated_register_gdbarch_swap (NULL, 0, build_fortran_types); builtin_type_string = init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT, @@ -632,8 +660,8 @@ add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab) parser have fits. */ - if (STREQ (name, BLANK_COMMON_NAME_ORIGINAL) || - STREQ (name, BLANK_COMMON_NAME_MF77)) + if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 + || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) { xfree (name); @@ -736,7 +764,7 @@ find_first_common_named (char *name) while (tmp != NULL) { - if (STREQ (tmp->name, name)) + if (strcmp (tmp->name, name) == 0) return (tmp); else tmp = tmp->next; @@ -758,7 +786,8 @@ find_common_for_function (char *name, char *funcname) while (tmp != NULL) { - if (STREQ (tmp->name, name) && STREQ (tmp->owning_function, funcname)) + if (DEPRECATED_STREQ (tmp->name, name) + && DEPRECATED_STREQ (tmp->owning_function, funcname)) return (tmp); else tmp = tmp->next; @@ -807,8 +836,8 @@ patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum) /* For blank common blocks, change the canonical reprsentation of a blank name */ - if ((STREQ (name, BLANK_COMMON_NAME_ORIGINAL)) || - (STREQ (name, BLANK_COMMON_NAME_MF77))) + if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 + || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) { xfree (name); name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1); @@ -820,7 +849,7 @@ patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum) while (tmp != NULL) { if (COMMON_NEEDS_PATCHING (tmp)) - if (STREQ (tmp->name, name)) + if (strcmp (tmp->name, name) == 0) patch_common_entries (tmp, offset, secnum); tmp = tmp->next; @@ -904,7 +933,7 @@ get_bf_for_fcn (long the_function) if (current_head_bf_list->symnum_fcn == the_function) { if (global_remote_debug) - fprintf (stderr, "*"); + fprintf_unfiltered (gdb_stderr, "*"); tmp = current_head_bf_list; current_head_bf_list = current_head_bf_list->next; @@ -916,7 +945,7 @@ get_bf_for_fcn (long the_function) the ugly linear scan */ if (global_remote_debug) - fprintf (stderr, "\ndefaulting to linear scan\n"); + fprintf_unfiltered (gdb_stderr, "\ndefaulting to linear scan\n"); nprobes = 0; tmp = saved_bf_list; @@ -926,7 +955,7 @@ get_bf_for_fcn (long the_function) if (tmp->symnum_fcn == the_function) { if (global_remote_debug) - fprintf (stderr, "Found in %d probes\n", nprobes); + fprintf_unfiltered (gdb_stderr, "Found in %d probes\n", nprobes); current_head_bf_list = tmp->next; return (tmp->symnum_bf); } diff --git a/contrib/gdb/gdb/f-typeprint.c b/contrib/gdb/gdb/f-typeprint.c index 2beae0fed7f..9e148fb8306 100644 --- a/contrib/gdb/gdb/f-typeprint.c +++ b/contrib/gdb/gdb/f-typeprint.c @@ -1,7 +1,8 @@ /* Support for printing Fortran types for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1998, 2000, - 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1998, + 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Contributed by Motorola. Adapted from the C version by Farooq Butt (fmbutt@engage.sps.mot.com). @@ -23,7 +24,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "bfd.h" #include "symtab.h" #include "gdbtypes.h" @@ -58,7 +59,7 @@ void f_print_type (struct type *type, char *varstring, struct ui_file *stream, int show, int level) { - register enum type_code code; + enum type_code code; int demangled_args; f_type_print_base (type, stream, show, level); @@ -328,6 +329,11 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show, f_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level); break; + case TYPE_CODE_REF: + fprintf_filtered (stream, "REF TO -> ( "); + f_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level); + break; + case TYPE_CODE_VOID: fprintf_filtered (stream, "VOID"); break; @@ -355,7 +361,7 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show, through as TYPE_CODE_INT since dbxstclass.h is so C-oriented, we must change these to "character" from "char". */ - if (STREQ (TYPE_NAME (type), "char")) + if (strcmp (TYPE_NAME (type), "char") == 0) fprintf_filtered (stream, "character"); else goto default_case; diff --git a/contrib/gdb/gdb/f-valprint.c b/contrib/gdb/gdb/f-valprint.c index 48c511377e8..805590f0a91 100644 --- a/contrib/gdb/gdb/f-valprint.c +++ b/contrib/gdb/gdb/f-valprint.c @@ -1,5 +1,5 @@ /* Support for printing Fortran values for GDB, the GNU debugger. - Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000 + Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. Contributed by Motorola. Adapted from the C definitions by Farooq Butt (fmbutt@engage.sps.mot.com), additionally worked over by Stan Shebs. @@ -33,6 +33,7 @@ #include "frame.h" #include "gdbcore.h" #include "command.h" +#include "block.h" #if 0 static int there_is_a_visible_common_named (char *); @@ -46,7 +47,8 @@ static void f77_print_array (struct type *, char *, CORE_ADDR, enum val_prettyprint); static void f77_print_array_1 (int, int, struct type *, char *, CORE_ADDR, struct ui_file *, int, int, int, - enum val_prettyprint); + enum val_prettyprint, + int *elts); static void f77_create_arrayprint_offset_tbl (struct type *, struct ui_file *); static void f77_get_dynamic_length_of_aggregate (struct type *); @@ -74,7 +76,7 @@ f77_get_dynamic_lowerbound (struct type *type, int *lower_bound) switch (TYPE_ARRAY_LOWER_BOUND_TYPE (type)) { case BOUND_BY_VALUE_ON_STACK: - current_frame_addr = selected_frame->frame; + current_frame_addr = get_frame_base (deprecated_selected_frame); if (current_frame_addr > 0) { *lower_bound = @@ -98,13 +100,13 @@ f77_get_dynamic_lowerbound (struct type *type, int *lower_bound) break; case BOUND_BY_REF_ON_STACK: - current_frame_addr = selected_frame->frame; + current_frame_addr = get_frame_base (deprecated_selected_frame); if (current_frame_addr > 0) { ptr_to_lower_bound = - read_memory_integer (current_frame_addr + - TYPE_ARRAY_LOWER_BOUND_VALUE (type), - 4); + read_memory_typed_address (current_frame_addr + + TYPE_ARRAY_LOWER_BOUND_VALUE (type), + builtin_type_void_data_ptr); *lower_bound = read_memory_integer (ptr_to_lower_bound, 4); } else @@ -132,7 +134,7 @@ f77_get_dynamic_upperbound (struct type *type, int *upper_bound) switch (TYPE_ARRAY_UPPER_BOUND_TYPE (type)) { case BOUND_BY_VALUE_ON_STACK: - current_frame_addr = selected_frame->frame; + current_frame_addr = get_frame_base (deprecated_selected_frame); if (current_frame_addr > 0) { *upper_bound = @@ -161,13 +163,13 @@ f77_get_dynamic_upperbound (struct type *type, int *upper_bound) break; case BOUND_BY_REF_ON_STACK: - current_frame_addr = selected_frame->frame; + current_frame_addr = get_frame_base (deprecated_selected_frame); if (current_frame_addr > 0) { ptr_to_upper_bound = - read_memory_integer (current_frame_addr + - TYPE_ARRAY_UPPER_BOUND_VALUE (type), - 4); + read_memory_typed_address (current_frame_addr + + TYPE_ARRAY_UPPER_BOUND_VALUE (type), + builtin_type_void_data_ptr); *upper_bound = read_memory_integer (ptr_to_upper_bound, 4); } else @@ -270,31 +272,37 @@ f77_create_arrayprint_offset_tbl (struct type *type, struct ui_file *stream) } } + + /* Actual function which prints out F77 arrays, Valaddr == address in the superior. Address == the address in the inferior. */ static void f77_print_array_1 (int nss, int ndimensions, struct type *type, char *valaddr, CORE_ADDR address, struct ui_file *stream, int format, - int deref_ref, int recurse, enum val_prettyprint pretty) + int deref_ref, int recurse, enum val_prettyprint pretty, + int *elts) { int i; if (nss != ndimensions) { - for (i = 0; i < F77_DIM_SIZE (nss); i++) + for (i = 0; (i < F77_DIM_SIZE (nss) && (*elts) < print_max); i++) { fprintf_filtered (stream, "( "); f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type), valaddr + i * F77_DIM_OFFSET (nss), address + i * F77_DIM_OFFSET (nss), - stream, format, deref_ref, recurse, pretty); + stream, format, deref_ref, recurse, pretty, elts); fprintf_filtered (stream, ") "); } + if (*elts >= print_max && i < F77_DIM_SIZE (nss)) + fprintf_filtered (stream, "..."); } else { - for (i = 0; (i < F77_DIM_SIZE (nss) && i < print_max); i++) + for (i = 0; i < F77_DIM_SIZE (nss) && (*elts) < print_max; + i++, (*elts)++) { val_print (TYPE_TARGET_TYPE (type), valaddr + i * F77_DIM_OFFSET (ndimensions), @@ -305,7 +313,7 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, char *valaddr, if (i != (F77_DIM_SIZE (nss) - 1)) fprintf_filtered (stream, ", "); - if (i == print_max - 1) + if ((*elts == print_max - 1) && (i != (F77_DIM_SIZE (nss) - 1))) fprintf_filtered (stream, "..."); } } @@ -320,6 +328,7 @@ f77_print_array (struct type *type, char *valaddr, CORE_ADDR address, enum val_prettyprint pretty) { int ndimensions; + int elts = 0; ndimensions = calc_f77_array_dims (type); @@ -334,7 +343,7 @@ f77_print_array (struct type *type, char *valaddr, CORE_ADDR address, f77_create_arrayprint_offset_tbl (type, stream); f77_print_array_1 (1, ndimensions, type, valaddr, address, stream, format, - deref_ref, recurse, pretty); + deref_ref, recurse, pretty, &elts); } @@ -356,7 +365,7 @@ f_val_print (struct type *type, char *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { - register unsigned int i = 0; /* Number of characters printed */ + unsigned int i = 0; /* Number of characters printed */ struct type *elttype; LONGEST val; CORE_ADDR addr; @@ -375,11 +384,7 @@ f_val_print (struct type *type, char *valaddr, int embedded_offset, deref_ref, recurse, pretty); fprintf_filtered (stream, ")"); break; -#if 0 - /* Array of unspecified length: treat like pointer to first elt. */ - valaddr = (char *) &address; - /* FALL THROUGH */ -#endif + case TYPE_CODE_PTR: if (format && format != 's') { @@ -400,7 +405,7 @@ f_val_print (struct type *type, char *valaddr, int embedded_offset, } if (addressprint && format != 's') - fprintf_filtered (stream, "0x%s", paddr_nz (addr)); + print_address_numeric (addr, 1, stream); /* For a pointer to char or unsigned char, also print the string pointed to, unless pointer is null. */ @@ -410,9 +415,47 @@ f_val_print (struct type *type, char *valaddr, int embedded_offset, && addr != 0) i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream); - /* 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; + + case TYPE_CODE_REF: + elttype = check_typedef (TYPE_TARGET_TYPE (type)); + if (addressprint) + { + CORE_ADDR addr + = extract_typed_address (valaddr + embedded_offset, type); + fprintf_filtered (stream, "@"); + print_address_numeric (addr, 1, stream); + if (deref_ref) + fputs_filtered (": ", stream); + } + /* De-reference the reference. */ + if (deref_ref) + { + if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) + { + struct value *deref_val = + value_at + (TYPE_TARGET_TYPE (type), + unpack_pointer (lookup_pointer_type (builtin_type_void), + valaddr + embedded_offset), + NULL); + val_print (VALUE_TYPE (deref_val), + VALUE_CONTENTS (deref_val), + 0, + VALUE_ADDRESS (deref_val), + stream, + format, + deref_ref, + recurse, + pretty); + } + else + fputs_filtered ("???", stream); } break; @@ -562,7 +605,7 @@ list_all_visible_commons (char *funname) while (tmp != NULL) { - if (STREQ (tmp->owning_function, funname)) + if (strcmp (tmp->owning_function, funname) == 0) printf_filtered ("%s\n", tmp->name); tmp = tmp->next; @@ -579,7 +622,7 @@ info_common_command (char *comname, int from_tty) SAVED_F77_COMMON_PTR the_common; COMMON_ENTRY_PTR entry; struct frame_info *fi; - register char *funname = 0; + char *funname = 0; struct symbol *func; /* We have been told to display the contents of F77 COMMON @@ -587,7 +630,7 @@ info_common_command (char *comname, int from_tty) first make sure that it is visible and if so, let us display its contents */ - fi = selected_frame; + fi = deprecated_selected_frame; if (fi == NULL) error ("No frame selected"); @@ -595,7 +638,7 @@ info_common_command (char *comname, int from_tty) /* The following is generally ripped off from stack.c's routine print_frame_info() */ - func = find_pc_function (fi->pc); + func = find_pc_function (get_frame_pc (fi)); if (func) { /* In certain pathological cases, the symtabs give the wrong @@ -612,22 +655,22 @@ info_common_command (char *comname, int from_tty) be any minimal symbols in the middle of a function. FIXME: (Not necessarily true. What about text labels) */ - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_pc (fi)); if (msymbol != NULL && (SYMBOL_VALUE_ADDRESS (msymbol) > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) - funname = SYMBOL_NAME (msymbol); + funname = DEPRECATED_SYMBOL_NAME (msymbol); else - funname = SYMBOL_NAME (func); + funname = DEPRECATED_SYMBOL_NAME (func); } else { - register struct minimal_symbol *msymbol = - lookup_minimal_symbol_by_pc (fi->pc); + struct minimal_symbol *msymbol = + lookup_minimal_symbol_by_pc (get_frame_pc (fi)); if (msymbol != NULL) - funname = SYMBOL_NAME (msymbol); + funname = DEPRECATED_SYMBOL_NAME (msymbol); } /* If comname is NULL, we assume the user wishes to see the @@ -643,7 +686,7 @@ info_common_command (char *comname, int from_tty) if (the_common) { - if (STREQ (comname, BLANK_COMMON_NAME_LOCAL)) + if (strcmp (comname, BLANK_COMMON_NAME_LOCAL) == 0) printf_filtered ("Contents of blank COMMON block:\n"); else printf_filtered ("Contents of F77 COMMON block '%s':\n", comname); @@ -653,7 +696,7 @@ info_common_command (char *comname, int from_tty) while (entry != NULL) { - printf_filtered ("%s = ", SYMBOL_NAME (entry->symbol)); + printf_filtered ("%s = ", DEPRECATED_SYMBOL_NAME (entry->symbol)); print_variable_value (entry->symbol, fi, gdb_stdout); printf_filtered ("\n"); entry = entry->next; @@ -673,13 +716,13 @@ there_is_a_visible_common_named (char *comname) { SAVED_F77_COMMON_PTR the_common; struct frame_info *fi; - register char *funname = 0; + char *funname = 0; struct symbol *func; if (comname == NULL) error ("Cannot deal with NULL common name!"); - fi = selected_frame; + fi = deprecated_selected_frame; if (fi == NULL) error ("No frame selected"); @@ -709,17 +752,17 @@ there_is_a_visible_common_named (char *comname) if (msymbol != NULL && (SYMBOL_VALUE_ADDRESS (msymbol) > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) - funname = SYMBOL_NAME (msymbol); + funname = DEPRECATED_SYMBOL_NAME (msymbol); else - funname = SYMBOL_NAME (func); + funname = DEPRECATED_SYMBOL_NAME (func); } else { - register struct minimal_symbol *msymbol = + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); if (msymbol != NULL) - funname = SYMBOL_NAME (msymbol); + funname = DEPRECATED_SYMBOL_NAME (msymbol); } the_common = find_common_for_function (comname, funname); diff --git a/contrib/gdb/gdb/fbsd-proc.c b/contrib/gdb/gdb/fbsd-proc.c new file mode 100644 index 00000000000..16813a9a1c8 --- /dev/null +++ b/contrib/gdb/gdb/fbsd-proc.c @@ -0,0 +1,166 @@ +/* FreeBSD-specific methods for using the /proc file system. + + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "inferior.h" +#include "gdb_string.h" + +#include +#include + +#include "elf-bfd.h" + +#include "gregset.h" + +char * +child_pid_to_exec_file (int pid) +{ + char *path; + char *buf; + + xasprintf (&path, "/proc/%d/file", pid); + buf = xcalloc (MAXPATHLEN, sizeof (char)); + make_cleanup (xfree, path); + make_cleanup (xfree, buf); + + if (readlink (path, buf, MAXPATHLEN) > 0) + return buf; + + return NULL; +} + +static int +read_mapping (FILE *mapfile, unsigned long *start, unsigned long *end, + char *protection) +{ + /* FreeBSD 5.1-RELEASE uses a 256-byte buffer. */ + char buf[256]; + int resident, privateresident; + unsigned long obj; + int ret = EOF; + + /* As of FreeBSD 5.0-RELEASE, the layout is described in + /usr/src/sys/fs/procfs/procfs_map.c. Somewhere in 5.1-CURRENT a + new column was added to the procfs map. Therefore we can't use + fscanf since we need to support older releases too. */ + if (fgets (buf, sizeof buf, mapfile) != NULL) + ret = sscanf (buf, "%lx %lx %d %d %lx %s", start, end, + &resident, &privateresident, &obj, protection); + + return (ret != 0 && ret != EOF); +} + +static int +fbsd_find_memory_regions (int (*func) (CORE_ADDR, unsigned long, + int, int, int, void *), + void *obfd) +{ + pid_t pid = ptid_get_pid (inferior_ptid); + char *mapfilename; + FILE *mapfile; + unsigned long start, end, size; + char protection[4]; + int read, write, exec; + + xasprintf (&mapfilename, "/proc/%ld/map", (long) pid); + mapfile = fopen (mapfilename, "r"); + if (mapfile == NULL) + error ("Couldn't open %s\n", mapfilename); + + if (info_verbose) + fprintf_filtered (gdb_stdout, + "Reading memory regions from %s\n", mapfilename); + + /* Now iterate until end-of-file. */ + while (read_mapping (mapfile, &start, &end, &protection[0])) + { + size = end - start; + + read = (strchr (protection, 'r') != 0); + write = (strchr (protection, 'w') != 0); + exec = (strchr (protection, 'x') != 0); + + if (info_verbose) + { + fprintf_filtered (gdb_stdout, + "Save segment, %ld bytes at 0x%s (%c%c%c)\n", + size, paddr_nz (start), + read ? 'r' : '-', + write ? 'w' : '-', + exec ? 'x' : '-'); + } + + /* Invoke the callback function to create the corefile segment. */ + func (start, size, read, write, exec, obfd); + } + + fclose (mapfile); + return 0; +} + +static char * +fbsd_make_corefile_notes (bfd *obfd, int *note_size) +{ + gregset_t gregs; + fpregset_t fpregs; + char *note_data = NULL; + Elf_Internal_Ehdr *i_ehdrp; + + /* Put a "FreeBSD" label in the ELF header. */ + i_ehdrp = elf_elfheader (obfd); + i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; + + fill_gregset (&gregs, -1); + note_data = elfcore_write_prstatus (obfd, note_data, note_size, + ptid_get_pid (inferior_ptid), + stop_signal, &gregs); + + fill_fpregset (&fpregs, -1); + note_data = elfcore_write_prfpreg (obfd, note_data, note_size, + &fpregs, sizeof (fpregs)); + + if (get_exec_file (0)) + { + char *fname = strrchr (get_exec_file (0), '/') + 1; + char *psargs = xstrdup (fname); + + if (get_inferior_args ()) + psargs = reconcat (psargs, psargs, " ", get_inferior_args (), NULL); + + note_data = elfcore_write_prpsinfo (obfd, note_data, note_size, + fname, psargs); + } + + make_cleanup (xfree, note_data); + return note_data; +} + + +void +_initialize_fbsd_proc (void) +{ + extern void inftarg_set_find_memory_regions (); + extern void inftarg_set_make_corefile_notes (); + + inftarg_set_find_memory_regions (fbsd_find_memory_regions); + inftarg_set_make_corefile_notes (fbsd_make_corefile_notes); +} diff --git a/contrib/gdb/gdb/findvar.c b/contrib/gdb/gdb/findvar.c index 3a160a3597b..cb1ef655dc2 100644 --- a/contrib/gdb/gdb/findvar.c +++ b/contrib/gdb/gdb/findvar.c @@ -1,7 +1,8 @@ /* Find a variable's value in memory, for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -33,6 +34,8 @@ #include "floatformat.h" #include "symfile.h" /* for overlay functions */ #include "regcache.h" +#include "user-regs.h" +#include "block.h" /* Basic byte-swapping routines. GDB has needed these for a long time... All extract a target-format integer at ADDR which is LEN bytes long. */ @@ -46,17 +49,17 @@ you lose #endif LONGEST -extract_signed_integer (void *addr, int len) +extract_signed_integer (const void *addr, int len) { LONGEST retval; - unsigned char *p; - unsigned char *startaddr = (unsigned char *) addr; - unsigned char *endaddr = startaddr + len; + const unsigned char *p; + const unsigned char *startaddr = addr; + const unsigned char *endaddr = startaddr + len; if (len > (int) sizeof (LONGEST)) error ("\ That operation is not available on integers of more than %d bytes.", - sizeof (LONGEST)); + (int) sizeof (LONGEST)); /* Start at the most significant end of the integer, and work towards the least significant. */ @@ -80,17 +83,17 @@ That operation is not available on integers of more than %d bytes.", } ULONGEST -extract_unsigned_integer (void *addr, int len) +extract_unsigned_integer (const void *addr, int len) { ULONGEST retval; - unsigned char *p; - unsigned char *startaddr = (unsigned char *) addr; - unsigned char *endaddr = startaddr + len; + const unsigned char *p; + const unsigned char *startaddr = addr; + const unsigned char *endaddr = startaddr + len; if (len > (int) sizeof (ULONGEST)) error ("\ That operation is not available on integers of more than %d bytes.", - sizeof (ULONGEST)); + (int) sizeof (ULONGEST)); /* Start at the most significant end of the integer, and work towards the least significant. */ @@ -114,7 +117,7 @@ That operation is not available on integers of more than %d bytes.", function returns 1 and sets *PVAL. Otherwise it returns 0. */ int -extract_long_unsigned_integer (void *addr, int orig_len, LONGEST *pval) +extract_long_unsigned_integer (const void *addr, int orig_len, LONGEST *pval) { char *p, *first_addr; int len; @@ -158,32 +161,10 @@ extract_long_unsigned_integer (void *addr, int orig_len, LONGEST *pval) } -/* Treat the LEN bytes at ADDR as a target-format address, and return - that address. ADDR is a buffer in the GDB process, not in the - inferior. - - This function should only be used by target-specific code. It - assumes that a pointer has the same representation as that thing's - address represented as an integer. Some machines use word - addresses, or similarly munged things, for certain types of - pointers, so that assumption doesn't hold everywhere. - - Common code should use extract_typed_address instead, or something - else based on POINTER_TO_ADDRESS. */ - -CORE_ADDR -extract_address (void *addr, int len) -{ - /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure - whether we want this to be true eventually. */ - return (CORE_ADDR) extract_unsigned_integer (addr, len); -} - - /* Treat the bytes at BUF as a pointer of type TYPE, and return the address it represents. */ CORE_ADDR -extract_typed_address (void *buf, struct type *type) +extract_typed_address (const void *buf, struct type *type) { if (TYPE_CODE (type) != TYPE_CODE_PTR && TYPE_CODE (type) != TYPE_CODE_REF) @@ -249,24 +230,6 @@ store_unsigned_integer (void *addr, int len, ULONGEST val) } } -/* Store the address VAL as a LEN-byte value in target byte order at - ADDR. ADDR is a buffer in the GDB process, not in the inferior. - - This function should only be used by target-specific code. It - assumes that a pointer has the same representation as that thing's - address represented as an integer. Some machines use word - addresses, or similarly munged things, for certain types of - pointers, so that assumption doesn't hold everywhere. - - Common code should use store_typed_address instead, or something else - based on ADDRESS_TO_POINTER. */ -void -store_address (void *addr, int len, LONGEST val) -{ - store_unsigned_integer (addr, len, val); -} - - /* Store the address ADDR as a pointer of type TYPE at BUF, in target form. */ void @@ -283,47 +246,60 @@ store_typed_address (void *buf, struct type *type, CORE_ADDR addr) -/* Return a `value' with the contents of register REGNUM - in its virtual format, with the type specified by - REGISTER_VIRTUAL_TYPE. +/* Return a `value' with the contents of (virtual or cooked) register + REGNUM as found in the specified FRAME. The register's type is + determined by register_type(). - NOTE: returns NULL if register value is not available. - Caller will check return value or die! */ + NOTE: returns NULL if register value is not available. Caller will + check return value or die! */ struct value * -value_of_register (int regnum) +value_of_register (int regnum, struct frame_info *frame) { CORE_ADDR addr; int optim; struct value *reg_val; - char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); + int realnum; + char raw_buffer[MAX_REGISTER_SIZE]; enum lval_type lval; - get_saved_register (raw_buffer, &optim, &addr, - selected_frame, regnum, &lval); + /* User registers lie completely outside of the range of normal + registers. Catch them early so that the target never sees them. */ + if (regnum >= NUM_REGS + NUM_PSEUDO_REGS) + return value_of_user_reg (regnum, frame); + + frame_register (frame, regnum, &optim, &lval, &addr, &realnum, raw_buffer); + + /* FIXME: cagney/2002-05-15: This test is just bogus. + + It indicates that the target failed to supply a value for a + register because it was "not available" at this time. Problem + is, the target still has the register and so get saved_register() + may be returning a value saved on the stack. */ if (register_cached (regnum) < 0) return NULL; /* register value not available */ - reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); + reg_val = allocate_value (register_type (current_gdbarch, regnum)); /* Convert raw data to virtual format if necessary. */ - if (REGISTER_CONVERTIBLE (regnum)) + if (DEPRECATED_REGISTER_CONVERTIBLE_P () + && DEPRECATED_REGISTER_CONVERTIBLE (regnum)) { - REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), - raw_buffer, VALUE_CONTENTS_RAW (reg_val)); + DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, register_type (current_gdbarch, regnum), + raw_buffer, VALUE_CONTENTS_RAW (reg_val)); } - else if (REGISTER_RAW_SIZE (regnum) == REGISTER_VIRTUAL_SIZE (regnum)) + else if (DEPRECATED_REGISTER_RAW_SIZE (regnum) == DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)) memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer, - REGISTER_RAW_SIZE (regnum)); + DEPRECATED_REGISTER_RAW_SIZE (regnum)); else internal_error (__FILE__, __LINE__, "Register \"%s\" (%d) has conflicting raw (%d) and virtual (%d) size", REGISTER_NAME (regnum), regnum, - REGISTER_RAW_SIZE (regnum), - REGISTER_VIRTUAL_SIZE (regnum)); + DEPRECATED_REGISTER_RAW_SIZE (regnum), + DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); VALUE_LVAL (reg_val) = lval; VALUE_ADDRESS (reg_val) = addr; VALUE_REGNO (reg_val) = regnum; @@ -334,13 +310,13 @@ value_of_register (int regnum) /* Given a pointer of type TYPE in target form in BUF, return the address it represents. */ CORE_ADDR -unsigned_pointer_to_address (struct type *type, void *buf) +unsigned_pointer_to_address (struct type *type, const void *buf) { - return extract_address (buf, TYPE_LENGTH (type)); + return extract_unsigned_integer (buf, TYPE_LENGTH (type)); } CORE_ADDR -signed_pointer_to_address (struct type *type, void *buf) +signed_pointer_to_address (struct type *type, const void *buf) { return extract_signed_integer (buf, TYPE_LENGTH (type)); } @@ -350,7 +326,7 @@ signed_pointer_to_address (struct type *type, void *buf) void unsigned_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr) { - store_address (buf, TYPE_LENGTH (type), addr); + store_unsigned_integer (buf, TYPE_LENGTH (type), addr); } void @@ -369,6 +345,15 @@ symbol_read_needs_frame (struct symbol *sym) { /* All cases listed explicitly so that gcc -Wall will detect it if we failed to consider one. */ + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + /* FIXME: cagney/2004-01-26: It should be possible to + unconditionally call the SYMBOL_OPS method when available. + Unfortunately DWARF 2 stores the frame-base (instead of the + function) location in a function's symbol. Oops! For the + moment enable this when/where applicable. */ + return SYMBOL_OPS (sym)->read_needs_frame (sym); + case LOC_REGISTER: case LOC_ARG: case LOC_REF_ARG: @@ -378,7 +363,7 @@ symbol_read_needs_frame (struct symbol *sym) case LOC_LOCAL_ARG: case LOC_BASEREG: case LOC_BASEREG_ARG: - case LOC_THREAD_LOCAL_STATIC: + case LOC_HP_THREAD_LOCAL_STATIC: return 1; case LOC_UNDEF: @@ -405,15 +390,15 @@ symbol_read_needs_frame (struct symbol *sym) and a stack frame id, read the value of the variable and return a (pointer to a) struct value containing the value. If the variable cannot be found, return a zero pointer. - If FRAME is NULL, use the selected_frame. */ + If FRAME is NULL, use the deprecated_selected_frame. */ struct value * -read_var_value (register struct symbol *var, struct frame_info *frame) +read_var_value (struct symbol *var, struct frame_info *frame) { - register struct value *v; + struct value *v; struct type *type = SYMBOL_TYPE (var); CORE_ADDR addr; - register int len; + int len; v = allocate_value (type); VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ @@ -421,8 +406,11 @@ read_var_value (register struct symbol *var, struct frame_info *frame) len = TYPE_LENGTH (type); + + /* FIXME drow/2003-09-06: this call to the selected frame should be + pushed upwards to the callers. */ if (frame == NULL) - frame = selected_frame; + frame = deprecated_safe_get_selected_frame (); switch (SYMBOL_CLASS (var)) { @@ -485,7 +473,7 @@ addresses have not been bound by the dynamic loader. Try again when executable i case LOC_ARG: if (frame == NULL) return 0; - addr = FRAME_ARGS_ADDRESS (frame); + addr = get_frame_args_address (frame); if (!addr) return 0; addr += SYMBOL_VALUE (var); @@ -497,7 +485,7 @@ addresses have not been bound by the dynamic loader. Try again when executable i CORE_ADDR argref; if (frame == NULL) return 0; - argref = FRAME_ARGS_ADDRESS (frame); + argref = get_frame_args_address (frame); if (!argref) return 0; argref += SYMBOL_VALUE (var); @@ -510,13 +498,13 @@ addresses have not been bound by the dynamic loader. Try again when executable i case LOC_LOCAL_ARG: if (frame == NULL) return 0; - addr = FRAME_LOCALS_ADDRESS (frame); + addr = get_frame_locals_address (frame); addr += SYMBOL_VALUE (var); break; case LOC_BASEREG: case LOC_BASEREG_ARG: - case LOC_THREAD_LOCAL_STATIC: + case LOC_HP_THREAD_LOCAL_STATIC: { struct value *regval; @@ -551,7 +539,7 @@ addresses have not been bound by the dynamic loader. Try again when executable i if (frame == NULL) return 0; - b = get_frame_block (frame); + b = get_frame_block (frame, 0); if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR) { @@ -576,11 +564,22 @@ addresses have not been bound by the dynamic loader. Try again when executable i } break; + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + /* FIXME: cagney/2004-01-26: It should be possible to + unconditionally call the SYMBOL_OPS method when available. + Unfortunately DWARF 2 stores the frame-base (instead of the + function) location in a function's symbol. Oops! For the + moment enable this when/where applicable. */ + if (frame == 0 && SYMBOL_OPS (var)->read_needs_frame (var)) + return 0; + return SYMBOL_OPS (var)->read_variable (var, frame); + case LOC_UNRESOLVED: { struct minimal_symbol *msym; - msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL); + msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (var), NULL, NULL); if (msym == NULL) return 0; if (overlay_debugging) @@ -615,151 +614,105 @@ addresses have not been bound by the dynamic loader. Try again when executable i struct value * value_from_register (struct type *type, int regnum, struct frame_info *frame) { - char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); - CORE_ADDR addr; - int optim; + struct gdbarch *gdbarch = get_frame_arch (frame); struct value *v = allocate_value (type); - char *value_bytes = 0; - int value_bytes_copied = 0; - int num_storage_locs; - enum lval_type lval; - int len; - CHECK_TYPEDEF (type); - len = TYPE_LENGTH (type); - VALUE_REGNO (v) = regnum; - - num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ? - ((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 : - 1); - - if (num_storage_locs > 1 -#ifdef GDB_TARGET_IS_H8500 - || TYPE_CODE (type) == TYPE_CODE_PTR -#endif - ) + if (TYPE_LENGTH (type) == 0) { - /* Value spread across multiple storage locations. */ + /* It doesn't matter much what we return for this: since the + length is zero, it could be anything. But if allowed to see + a zero-length type, the register-finding loop below will set + neither mem_stor nor reg_stor, and then report an internal + error. + Zero-length types can legitimately arise from declarations + like 'struct {}' (a GCC extension, not valid ISO C). GDB may + also create them when it finds bogus debugging information; + for example, in GCC 2.95.4 and binutils 2.11.93.0.2, the + STABS BINCL->EXCL compression process can create bad type + numbers. GDB reads these as TYPE_CODE_UNDEF types, with zero + length. (That bug is actually the only known way to get a + zero-length value allocated to a register --- which is what + it takes to make it here.) + + We'll just attribute the value to the original register. */ + VALUE_LVAL (v) = lval_register; + VALUE_ADDRESS (v) = regnum; + VALUE_REGNO (v) = regnum; + } + else if (CONVERT_REGISTER_P (regnum, type)) + { + /* The ISA/ABI need to something weird when obtaining the + specified value from this register. It might need to + re-order non-adjacent, starting with REGNUM (see MIPS and + i386). It might need to convert the [float] register into + the corresponding [integer] type (see Alpha). The assumption + is that REGISTER_TO_VALUE populates the entire value + including the location. */ + REGISTER_TO_VALUE (frame, regnum, type, VALUE_CONTENTS_RAW (v)); + VALUE_LVAL (v) = lval_reg_frame_relative; + VALUE_FRAME_ID (v) = get_frame_id (frame); + VALUE_FRAME_REGNUM (v) = regnum; + } + else + { int local_regnum; int mem_stor = 0, reg_stor = 0; int mem_tracking = 1; CORE_ADDR last_addr = 0; CORE_ADDR first_addr = 0; - - value_bytes = (char *) alloca (len + MAX_REGISTER_RAW_SIZE); + int first_realnum = regnum; + int len = TYPE_LENGTH (type); + int value_bytes_copied; + int optimized = 0; + char *value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE); /* Copy all of the data out, whereever it may be. */ - -#ifdef GDB_TARGET_IS_H8500 -/* This piece of hideosity is required because the H8500 treats registers - differently depending upon whether they are used as pointers or not. As a - pointer, a register needs to have a page register tacked onto the front. - An alternate way to do this would be to have gcc output different register - numbers for the pointer & non-pointer form of the register. But, it - doesn't, so we're stuck with this. */ - - if (TYPE_CODE (type) == TYPE_CODE_PTR - && len > 2) + for (local_regnum = regnum, value_bytes_copied = 0; + value_bytes_copied < len; + (value_bytes_copied += DEPRECATED_REGISTER_RAW_SIZE (local_regnum), + ++local_regnum)) { - int page_regnum; - - switch (regnum) + int realnum; + int optim; + enum lval_type lval; + CORE_ADDR addr; + frame_register (frame, local_regnum, &optim, &lval, &addr, + &realnum, value_bytes + value_bytes_copied); + optimized += optim; + if (register_cached (local_regnum) == -1) + return NULL; /* register value not available */ + + if (regnum == local_regnum) { - case R0_REGNUM: - case R1_REGNUM: - case R2_REGNUM: - case R3_REGNUM: - page_regnum = SEG_D_REGNUM; - break; - case R4_REGNUM: - case R5_REGNUM: - page_regnum = SEG_E_REGNUM; - break; - case R6_REGNUM: - case R7_REGNUM: - page_regnum = SEG_T_REGNUM; - break; + first_addr = addr; + first_realnum = realnum; } - - value_bytes[0] = 0; - get_saved_register (value_bytes + 1, - &optim, - &addr, - frame, - page_regnum, - &lval); - - if (register_cached (page_regnum) == -1) - return NULL; /* register value not available */ - - if (lval == lval_register) - reg_stor++; - else - mem_stor++; - first_addr = addr; - last_addr = addr; - - get_saved_register (value_bytes + 2, - &optim, - &addr, - frame, - regnum, - &lval); - - if (register_cached (regnum) == -1) - return NULL; /* register value not available */ - if (lval == lval_register) reg_stor++; else { mem_stor++; - mem_tracking = mem_tracking && (addr == last_addr); + + mem_tracking = (mem_tracking + && (regnum == local_regnum + || addr == last_addr)); } last_addr = addr; } - else -#endif /* GDB_TARGET_IS_H8500 */ - for (local_regnum = regnum; - value_bytes_copied < len; - (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum), - ++local_regnum)) - { - get_saved_register (value_bytes + value_bytes_copied, - &optim, - &addr, - frame, - local_regnum, - &lval); - - if (register_cached (local_regnum) == -1) - return NULL; /* register value not available */ - - if (regnum == local_regnum) - first_addr = addr; - if (lval == lval_register) - reg_stor++; - else - { - mem_stor++; - - mem_tracking = - (mem_tracking - && (regnum == local_regnum - || addr == last_addr)); - } - last_addr = addr; - } - + + /* FIXME: cagney/2003-06-04: Shouldn't this always use + lval_reg_frame_relative? If it doesn't and the register's + location changes (say after a resume) then this value is + going to have wrong information. */ if ((reg_stor && mem_stor) || (mem_stor && !mem_tracking)) /* Mixed storage; all of the hassle we just went through was for some good purpose. */ { VALUE_LVAL (v) = lval_reg_frame_relative; - VALUE_FRAME (v) = FRAME_FP (frame); + VALUE_FRAME_ID (v) = get_frame_id (frame); VALUE_FRAME_REGNUM (v) = regnum; } else if (mem_stor) @@ -771,64 +724,29 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) { VALUE_LVAL (v) = lval_register; VALUE_ADDRESS (v) = first_addr; + VALUE_REGNO (v) = first_realnum; } else internal_error (__FILE__, __LINE__, "value_from_register: Value not stored anywhere!"); - - VALUE_OPTIMIZED_OUT (v) = optim; - + + VALUE_OPTIMIZED_OUT (v) = optimized; + /* Any structure stored in more than one register will always be - an integral number of registers. Otherwise, you'd need to do + an integral number of registers. Otherwise, you need to do some fiddling with the last register copied here for little endian machines. */ - - /* Copy into the contents section of the value. */ - memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len); - - /* Finally do any conversion necessary when extracting this - type from more than one register. */ -#ifdef REGISTER_CONVERT_TO_TYPE - REGISTER_CONVERT_TO_TYPE (regnum, type, VALUE_CONTENTS_RAW (v)); -#endif - return v; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && len < DEPRECATED_REGISTER_RAW_SIZE (regnum)) + /* Big-endian, and we want less than full size. */ + VALUE_OFFSET (v) = DEPRECATED_REGISTER_RAW_SIZE (regnum) - len; + else + VALUE_OFFSET (v) = 0; + memcpy (VALUE_CONTENTS_RAW (v), value_bytes + VALUE_OFFSET (v), len); } - - /* Data is completely contained within a single register. Locate the - register's contents in a real register or in core; - read the data in raw format. */ - - get_saved_register (raw_buffer, &optim, &addr, frame, regnum, &lval); - - if (register_cached (regnum) == -1) - return NULL; /* register value not available */ - - VALUE_OPTIMIZED_OUT (v) = optim; - VALUE_LVAL (v) = lval; - VALUE_ADDRESS (v) = addr; - - /* Convert raw data to virtual format if necessary. */ - - if (REGISTER_CONVERTIBLE (regnum)) - { - REGISTER_CONVERT_TO_VIRTUAL (regnum, type, - raw_buffer, VALUE_CONTENTS_RAW (v)); - } - else - { - /* Raw and virtual formats are the same for this register. */ - - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG && len < REGISTER_RAW_SIZE (regnum)) - { - /* Big-endian, and we want less than full size. */ - VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len; - } - - memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len); - } - return v; } + /* Given a struct symbol for a variable or function, and a stack frame id, @@ -836,7 +754,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) address. */ struct value * -locate_var_value (register struct symbol *var, struct frame_info *frame) +locate_var_value (struct symbol *var, struct frame_info *frame) { CORE_ADDR addr = 0; struct type *type = SYMBOL_TYPE (var); @@ -847,7 +765,7 @@ locate_var_value (register struct symbol *var, struct frame_info *frame) lazy_value = read_var_value (var, frame); if (lazy_value == 0) - error ("Address of \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var)); + error ("Address of \"%s\" is unknown.", SYMBOL_PRINT_NAME (var)); if (VALUE_LAZY (lazy_value) || TYPE_CODE (type) == TYPE_CODE_FUNC) @@ -868,7 +786,7 @@ locate_var_value (register struct symbol *var, struct frame_info *frame) && *REGISTER_NAME (VALUE_REGNO (lazy_value)) != '\0'); error("Address requested for identifier " "\"%s\" which is in register $%s", - SYMBOL_SOURCE_NAME (var), + SYMBOL_PRINT_NAME (var), REGISTER_NAME (VALUE_REGNO (lazy_value))); break; @@ -877,13 +795,13 @@ locate_var_value (register struct symbol *var, struct frame_info *frame) && *REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value)) != '\0'); error("Address requested for identifier " "\"%s\" which is in frame register $%s", - SYMBOL_SOURCE_NAME (var), + SYMBOL_PRINT_NAME (var), REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value))); break; default: error ("Can't take address of \"%s\" which isn't an lvalue.", - SYMBOL_SOURCE_NAME (var)); + SYMBOL_PRINT_NAME (var)); break; } return 0; /* For lint -- never reached */ diff --git a/contrib/gdb/gdb/fork-child.c b/contrib/gdb/gdb/fork-child.c index aacd53cac71..e1d32b06452 100644 --- a/contrib/gdb/gdb/fork-child.c +++ b/contrib/gdb/gdb/fork-child.c @@ -88,6 +88,29 @@ breakup_args (char *scratch, char **argv) } +/* When executing a command under the given shell, return non-zero + if the '!' character should be escaped when embedded in a quoted + command-line argument. */ + +static int +escape_bang_in_quoted_argument (const char *shell_file) +{ + const int shell_file_len = strlen (shell_file); + + /* Bang should be escaped only in C Shells. For now, simply check + that the shell name ends with 'csh', which covers at least csh + and tcsh. This should be good enough for now. */ + + if (shell_file_len < 3) + return 0; + + if (shell_file[shell_file_len - 3] == 'c' + && shell_file[shell_file_len - 2] == 's' + && shell_file[shell_file_len - 1] == 'h') + return 1; + + return 0; +} /* Start an inferior Unix child process and sets inferior_ptid to its pid. EXEC_FILE is the file to run. @@ -171,6 +194,7 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env, char *p; int need_to_quote; + const int escape_bang = escape_bang_in_quoted_argument (shell_file); strcat (shell_command, "exec "); @@ -215,7 +239,7 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env, { if (*p == '\'') strcat (shell_command, "'\\''"); - else if (*p == '!') + else if (*p == '!' && escape_bang) strcat (shell_command, "\\!"); else strncat (shell_command, p, 1); @@ -379,131 +403,6 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env, #endif } -/* An inferior Unix process CHILD_PID has been created by a call to - fork() (or variants like vfork). It is presently stopped, and waiting - to be resumed. clone_and_follow_inferior will fork the debugger, - and that clone will "follow" (attach to) CHILD_PID. The original copy - of the debugger will not touch CHILD_PID again. - - Also, the original debugger will set FOLLOWED_CHILD FALSE, while the - clone will set it TRUE. - */ -void -clone_and_follow_inferior (int child_pid, int *followed_child) -{ - int debugger_pid; - int status; - char pid_spelling[100]; /* Arbitrary but sufficient length. */ - - /* This semaphore is used to coordinate the two debuggers' handoff - of CHILD_PID. The original debugger will detach from CHILD_PID, - and then the clone debugger will attach to it. (It must be done - this way because on some targets, only one process at a time can - trace another. Thus, the original debugger must relinquish its - tracing rights before the clone can pick them up.) - */ -#define SEM_TALK (1) -#define SEM_LISTEN (0) - int handoff_semaphore[2]; /* Original "talks" to [1], clone "listens" to [0] */ - int talk_value = 99; - int listen_value; - - /* Set debug_fork then attach to the child while it sleeps, to debug. */ - static int debug_fork = 0; - - /* It is generally good practice to flush any possible pending stdio - output prior to doing a fork, to avoid the possibility of both the - parent and child flushing the same data after the fork. */ - - gdb_flush (gdb_stdout); - gdb_flush (gdb_stderr); - - /* Open the semaphore pipes. - */ - status = pipe (handoff_semaphore); - if (status < 0) - error ("error getting pipe for handoff semaphore"); - - /* Clone the debugger. Note that the apparent call to vfork() - below *might* actually be a call to fork() due to the fact that - autoconf will ``#define vfork fork'' on certain platforms. */ - if (debug_fork) - debugger_pid = fork (); - else - debugger_pid = vfork (); - - if (debugger_pid < 0) - perror_with_name ("fork"); - - /* Are we the original debugger? If so, we must relinquish all claims - to CHILD_PID. */ - if (debugger_pid != 0) - { - char signal_spelling[100]; /* Arbitrary but sufficient length */ - - /* Detach from CHILD_PID. Deliver a "stop" signal when we do, though, - so that it remains stopped until the clone debugger can attach - to it. - */ - detach_breakpoints (child_pid); - - sprintf (signal_spelling, "%d", target_signal_to_host (TARGET_SIGNAL_STOP)); - target_require_detach (child_pid, signal_spelling, 1); - - /* Notify the clone debugger that it should attach to CHILD_PID. */ - write (handoff_semaphore[SEM_TALK], &talk_value, sizeof (talk_value)); - - *followed_child = 0; - } - - /* We're the child. */ - else - { - if (debug_fork) - sleep (debug_fork); - - /* The child (i.e., the cloned debugger) must now attach to - CHILD_PID. inferior_ptid is presently set to the parent process - of the fork, while CHILD_PID should be the child process of the - fork. - - Wait until the original debugger relinquishes control of CHILD_PID, - though. - */ - read (handoff_semaphore[SEM_LISTEN], &listen_value, sizeof (listen_value)); - - /* Note that we DON'T want to actually detach from inferior_ptid, - because that would allow it to run free. The original - debugger wants to retain control of the process. So, we - just reset inferior_ptid to CHILD_PID, and then ensure that all - breakpoints are really set in CHILD_PID. - */ - target_mourn_inferior (); - - /* Ask the tty subsystem to switch to the one we specified earlier - (or to share the current terminal, if none was specified). */ - - new_tty (); - - dont_repeat (); - sprintf (pid_spelling, "%d", child_pid); - target_require_attach (pid_spelling, 1); - - /* Perform any necessary cleanup, after attachment. (This form - of attaching can behave differently on some targets than the - standard method, where a process formerly not under debugger - control was suddenly attached to..) - */ - target_post_follow_inferior_by_clone (); - - *followed_child = 1; - } - - /* Discard the handoff sempahore. */ - (void) close (handoff_semaphore[SEM_LISTEN]); - (void) close (handoff_semaphore[SEM_TALK]); -} - /* Accept NTRAPS traps from the inferior. */ void @@ -529,12 +428,10 @@ startup_inferior (int ntraps) inferior_ignoring_leading_exec_events = target_reported_exec_events_per_exec_call () - 1; -#ifdef STARTUP_INFERIOR - STARTUP_INFERIOR (pending_execs); -#else while (1) { - stop_soon_quietly = 1; /* Make wait_for_inferior be quiet */ + /* Make wait_for_inferior be quiet */ + stop_soon = STOP_QUIETLY; wait_for_inferior (); if (stop_signal != TARGET_SIGNAL_TRAP) { @@ -568,6 +465,5 @@ startup_inferior (int ntraps) resume (0, TARGET_SIGNAL_0); /* Just make it go on */ } } -#endif /* STARTUP_INFERIOR */ - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; } diff --git a/contrib/gdb/gdb/frame-base.c b/contrib/gdb/gdb/frame-base.c new file mode 100644 index 00000000000..66a0106aa0b --- /dev/null +++ b/contrib/gdb/gdb/frame-base.c @@ -0,0 +1,150 @@ +/* Definitions for frame address handler, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame-base.h" +#include "frame.h" + +/* A default frame base implementations. If it wasn't for the old + DEPRECATED_FRAME_LOCALS_ADDRESS and DEPRECATED_FRAME_ARGS_ADDRESS, + these could be combined into a single function. All architectures + really need to override this. */ + +static CORE_ADDR +default_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct frame_info *this_frame = get_prev_frame (next_frame); + return get_frame_base (this_frame); /* sigh! */ +} + +static CORE_ADDR +default_frame_locals_address (struct frame_info *next_frame, void **this_cache) +{ + if (DEPRECATED_FRAME_LOCALS_ADDRESS_P ()) + { + /* This is bad. The computation of per-frame locals address + should use a per-frame frame-base. */ + struct frame_info *this_frame = get_prev_frame (next_frame); + return DEPRECATED_FRAME_LOCALS_ADDRESS (this_frame); + } + return default_frame_base_address (next_frame, this_cache); +} + +static CORE_ADDR +default_frame_args_address (struct frame_info *next_frame, void **this_cache) +{ + if (DEPRECATED_FRAME_ARGS_ADDRESS_P ()) + { + struct frame_info *this_frame = get_prev_frame (next_frame); + return DEPRECATED_FRAME_ARGS_ADDRESS (this_frame); + } + return default_frame_base_address (next_frame, this_cache); +} + +const struct frame_base default_frame_base = { + NULL, /* No parent. */ + default_frame_base_address, + default_frame_locals_address, + default_frame_args_address +}; + +static struct gdbarch_data *frame_base_data; + +struct frame_base_table +{ + frame_base_sniffer_ftype **sniffer; + const struct frame_base *default_base; + int nr; +}; + +static void * +frame_base_init (struct gdbarch *gdbarch) +{ + struct frame_base_table *table = XCALLOC (1, struct frame_base_table); + table->default_base = &default_frame_base; + return table; +} + +static struct frame_base_table * +frame_base_table (struct gdbarch *gdbarch) +{ + struct frame_base_table *table = gdbarch_data (gdbarch, frame_base_data); + if (table == NULL) + { + /* ULGH, called during architecture initialization. Patch + things up. */ + table = frame_base_init (gdbarch); + set_gdbarch_data (gdbarch, frame_base_data, table); + } + return table; +} + +/* Append a predicate to the end of the table. */ +static void +append_predicate (struct frame_base_table *table, + frame_base_sniffer_ftype *sniffer) +{ + table->sniffer = xrealloc (table->sniffer, + ((table->nr + 1) + * sizeof (frame_base_sniffer_ftype *))); + table->sniffer[table->nr] = sniffer; + table->nr++; +} + +void +frame_base_append_sniffer (struct gdbarch *gdbarch, + frame_base_sniffer_ftype *sniffer) +{ + struct frame_base_table *table = frame_base_table (gdbarch); + append_predicate (table, sniffer); +} + +void +frame_base_set_default (struct gdbarch *gdbarch, + const struct frame_base *default_base) +{ + struct frame_base_table *table = frame_base_table (gdbarch); + table->default_base = default_base; +} + +const struct frame_base * +frame_base_find_by_frame (struct frame_info *next_frame) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct frame_base_table *table = frame_base_table (gdbarch); + int i; + for (i = 0; i < table->nr; i++) + { + const struct frame_base *desc = NULL; + desc = table->sniffer[i] (next_frame); + if (desc != NULL) + return desc; + } + return table->default_base; +} + +extern initialize_file_ftype _initialize_frame_base; /* -Wmissing-prototypes */ + +void +_initialize_frame_base (void) +{ + frame_base_data = register_gdbarch_data (frame_base_init); +} diff --git a/contrib/gdb/gdb/frame-base.h b/contrib/gdb/gdb/frame-base.h new file mode 100644 index 00000000000..680e9d59ffb --- /dev/null +++ b/contrib/gdb/gdb/frame-base.h @@ -0,0 +1,93 @@ +/* Definitions for a frame base, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined (FRAME_BASE_H) +#define FRAME_BASE_H 1 + +struct frame_info; +struct frame_id; +struct frame_unwind; +struct frame_base; +struct gdbarch; +struct regcache; + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + and that this is a `normal frame'; use the NEXT frame, and its + register unwind method, to determine the address of THIS frame's + `base'. + + The exact meaning of `base' is highly dependant on the type of the + debug info. It is assumed that dwarf2, stabs, ... will each + provide their own methods. + + A typical implmentation will return the same value for base, + locals-base and args-base. That value, however, will likely be + different to the frame ID's stack address. */ + +/* A generic base address. */ + +typedef CORE_ADDR (frame_this_base_ftype) (struct frame_info *next_frame, + void **this_base_cache); + +/* The base address of the frame's local variables. */ + +typedef CORE_ADDR (frame_this_locals_ftype) (struct frame_info *next_frame, + void **this_base_cache); + +/* The base address of the frame's arguments / parameters. */ + +typedef CORE_ADDR (frame_this_args_ftype) (struct frame_info *next_frame, + void **this_base_cache); + +struct frame_base +{ + /* If non-NULL, a low-level unwinder that shares its implementation + with this high-level frame-base method. */ + const struct frame_unwind *unwind; + frame_this_base_ftype *this_base; + frame_this_locals_ftype *this_locals; + frame_this_args_ftype *this_args; +}; + +/* Given the NEXT frame, return the frame base methods for THIS frame, + or NULL if it can't handle THIS frame. */ + +typedef const struct frame_base *(frame_base_sniffer_ftype) (struct frame_info *next_frame); + +/* Append a frame base sniffer to the list. The sniffers are polled + in the order that they are appended. */ + +extern void frame_base_append_sniffer (struct gdbarch *gdbarch, + frame_base_sniffer_ftype *sniffer); + +/* Set the default frame base. If all else fails, this one is + returned. If this isn't set, the default is to use legacy code + that uses things like the frame ID's base (ulgh!). */ + +extern void frame_base_set_default (struct gdbarch *gdbarch, + const struct frame_base *def); + +/* Iterate through the list of frame base handlers until one returns + an implementation. */ + +extern const struct frame_base *frame_base_find_by_frame (struct frame_info *next_frame); + +#endif diff --git a/contrib/gdb/gdb/frame-unwind.c b/contrib/gdb/gdb/frame-unwind.c new file mode 100644 index 00000000000..82eaf7c0aec --- /dev/null +++ b/contrib/gdb/gdb/frame-unwind.c @@ -0,0 +1,99 @@ +/* Definitions for frame unwinder, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "frame-unwind.h" +#include "gdb_assert.h" +#include "dummy-frame.h" + +static struct gdbarch_data *frame_unwind_data; + +struct frame_unwind_table +{ + frame_unwind_sniffer_ftype **sniffer; + int nr; +}; + +/* Append a predicate to the end of the table. */ +static void +append_predicate (struct frame_unwind_table *table, + frame_unwind_sniffer_ftype *sniffer) +{ + table->sniffer = xrealloc (table->sniffer, ((table->nr + 1) + * sizeof (frame_unwind_sniffer_ftype *))); + table->sniffer[table->nr] = sniffer; + table->nr++; +} + +static void * +frame_unwind_init (struct gdbarch *gdbarch) +{ + struct frame_unwind_table *table = XCALLOC (1, struct frame_unwind_table); + append_predicate (table, dummy_frame_sniffer); + return table; +} + +void +frame_unwind_append_sniffer (struct gdbarch *gdbarch, + frame_unwind_sniffer_ftype *sniffer) +{ + struct frame_unwind_table *table = + gdbarch_data (gdbarch, frame_unwind_data); + if (table == NULL) + { + /* ULGH, called during architecture initialization. Patch + things up. */ + table = frame_unwind_init (gdbarch); + set_gdbarch_data (gdbarch, frame_unwind_data, table); + } + append_predicate (table, sniffer); +} + +const struct frame_unwind * +frame_unwind_find_by_frame (struct frame_info *next_frame) +{ + int i; + struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); + if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES && legacy_frame_p (gdbarch)) + /* Seriously old code. Don't even try to use this new mechanism. + (Note: The variable USE_GENERIC_DUMMY_FRAMES is deprecated, not + the dummy frame mechanism. All architectures should be using + generic dummy frames). */ + return legacy_saved_regs_unwind; + for (i = 0; i < table->nr; i++) + { + const struct frame_unwind *desc; + desc = table->sniffer[i] (next_frame); + if (desc != NULL) + return desc; + } + return legacy_saved_regs_unwind; +} + +extern initialize_file_ftype _initialize_frame_unwind; /* -Wmissing-prototypes */ + +void +_initialize_frame_unwind (void) +{ + frame_unwind_data = register_gdbarch_data (frame_unwind_init); +} diff --git a/contrib/gdb/gdb/frame-unwind.h b/contrib/gdb/gdb/frame-unwind.h new file mode 100644 index 00000000000..8d17280fc9a --- /dev/null +++ b/contrib/gdb/gdb/frame-unwind.h @@ -0,0 +1,141 @@ +/* Definitions for a frame unwinder, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined (FRAME_UNWIND_H) +#define FRAME_UNWIND_H 1 + +struct frame_info; +struct frame_id; +struct frame_unwind; +struct gdbarch; +struct regcache; + +#include "frame.h" /* For enum frame_type. */ + +/* The following unwind functions assume a chain of frames forming the + sequence: (outer) prev <-> this <-> next (inner). All the + functions are called with called with the next frame's `struct + frame_info' and and this frame's prologue cache. + + THIS frame's register values can be obtained by unwinding NEXT + frame's registers (a recursive operation). + + THIS frame's prologue cache can be used to cache information such + as where this frame's prologue stores the previous frame's + registers. */ + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + use the NEXT frame, and its register unwind method, to determine + the frame ID of THIS frame. + + A frame ID provides an invariant that can be used to re-identify an + instance of a frame. It is a combination of the frame's `base' and + the frame's function's code address. + + Traditionally, THIS frame's ID was determined by examining THIS + frame's function's prologue, and identifying the register/offset + used as THIS frame's base. + + Example: An examination of THIS frame's prologue reveals that, on + entry, it saves the PC(+12), SP(+8), and R1(+4) registers + (decrementing the SP by 12). Consequently, the frame ID's base can + be determined by adding 12 to the THIS frame's stack-pointer, and + the value of THIS frame's SP can be obtained by unwinding the NEXT + frame's SP. + + THIS_PROLOGUE_CACHE can be used to share any prolog analysis data + with the other unwind methods. Memory for that cache should be + allocated using frame_obstack_zalloc(). */ + +typedef void (frame_this_id_ftype) (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id); + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + use the NEXT frame, and its register unwind method, to unwind THIS + frame's registers (returning the value of the specified register + REGNUM in the previous frame). + + Traditionally, THIS frame's registers were unwound by examining + THIS frame's function's prologue and identifying which registers + that prolog code saved on the stack. + + Example: An examination of THIS frame's prologue reveals that, on + entry, it saves the PC(+12), SP(+8), and R1(+4) registers + (decrementing the SP by 12). Consequently, the value of the PC + register in the previous frame is found in memory at SP+12, and + THIS frame's SP can be obtained by unwinding the NEXT frame's SP. + + Why not pass in THIS_FRAME? By passing in NEXT frame and THIS + cache, the supplied parameters are consistent with the sibling + function THIS_ID. + + Can the code call ``frame_register (get_prev_frame (NEXT_FRAME))''? + Won't the call frame_register (THIS_FRAME) be faster? Well, + ignoring the possability that the previous frame does not yet + exist, the ``frame_register (FRAME)'' function is expanded to + ``frame_register_unwind (get_next_frame (FRAME)'' and hence that + call will expand to ``frame_register_unwind (get_next_frame + (get_prev_frame (NEXT_FRAME)))''. Might as well call + ``frame_register_unwind (NEXT_FRAME)'' directly. + + THIS_PROLOGUE_CACHE can be used to share any prolog analysis data + with the other unwind methods. Memory for that cache should be + allocated using frame_obstack_zalloc(). */ + +typedef void (frame_prev_register_ftype) (struct frame_info *next_frame, + void **this_prologue_cache, + int prev_regnum, + int *optimized, + enum lval_type * lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep); + +struct frame_unwind +{ + /* The frame's type. Should this instead be a collection of + predicates that test the frame for various attributes? */ + enum frame_type type; + /* Should an attribute indicating the frame's address-in-block go + here? */ + frame_this_id_ftype *this_id; + frame_prev_register_ftype *prev_register; +}; + +/* Given the NEXT frame, take a wiff of THIS frame's registers (namely + the PC and attributes) and if it is the applicable unwinder return + the unwind methods, or NULL if it is not. */ + +typedef const struct frame_unwind *(frame_unwind_sniffer_ftype) (struct frame_info *next_frame); + +/* Add a frame sniffer to the list. The predicates are polled in the + order that they are appended. The initial list contains the dummy + frame sniffer. */ + +extern void frame_unwind_append_sniffer (struct gdbarch *gdbarch, + frame_unwind_sniffer_ftype *sniffer); + +/* Iterate through the next frame's sniffers until one returns with an + unwinder implementation. */ + +extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame); + +#endif diff --git a/contrib/gdb/gdb/frame.c b/contrib/gdb/gdb/frame.c index ea59eba0888..a032c47e92b 100644 --- a/contrib/gdb/gdb/frame.c +++ b/contrib/gdb/gdb/frame.c @@ -1,6 +1,7 @@ -/* Cache and manage the values of registers for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001 - Free Software Foundation, Inc. +/* Cache and manage frames for GDB, the GNU debugger. + + Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -25,201 +26,2338 @@ #include "value.h" #include "inferior.h" /* for inferior_ptid */ #include "regcache.h" +#include "gdb_assert.h" +#include "gdb_string.h" +#include "user-regs.h" +#include "gdb_obstack.h" +#include "dummy-frame.h" +#include "sentinel-frame.h" +#include "gdbcore.h" +#include "annotate.h" +#include "language.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "command.h" +#include "gdbcmd.h" -/* FIND_SAVED_REGISTER () +/* We keep a cache of stack frames, each of which is a "struct + frame_info". The innermost one gets allocated (in + wait_for_inferior) each time the inferior stops; current_frame + points to it. Additional frames get allocated (in get_prev_frame) + as needed, and are chained through the next and prev fields. Any + time that the frame cache becomes invalid (most notably when we + execute something, but also if we change how we interpret the + frames (e.g. "set heuristic-fence-post" in mips-tdep.c, or anything + which reads new symbols)), we should call reinit_frame_cache. */ - Return the address in which frame FRAME's value of register REGNUM - has been saved in memory. Or return zero if it has not been saved. - If REGNUM specifies the SP, the value we return is actually - the SP value, not an address where it was saved. */ - -CORE_ADDR -find_saved_register (struct frame_info *frame, int regnum) +struct frame_info { - register struct frame_info *frame1 = NULL; - register CORE_ADDR addr = 0; + /* Level of this frame. The inner-most (youngest) frame is at level + 0. As you move towards the outer-most (oldest) frame, the level + increases. This is a cached value. It could just as easily be + computed by counting back from the selected frame to the inner + most frame. */ + /* NOTE: cagney/2002-04-05: Perhaphs a level of ``-1'' should be + reserved to indicate a bogus frame - one that has been created + just to keep GDB happy (GDB always needs a frame). For the + moment leave this as speculation. */ + int level; - if (frame == NULL) /* No regs saved if want current frame */ - return 0; + /* The frame's type. */ + /* FIXME: cagney/2003-04-02: Should instead be returning + ->unwind->type. Unfortunately, legacy code is still explicitly + setting the type using the method deprecated_set_frame_type. + Eliminate that method and this field can be eliminated. */ + enum frame_type type; -#ifdef HAVE_REGISTER_WINDOWS - /* We assume that a register in a register window will only be saved - in one place (since the name changes and/or disappears as you go - towards inner frames), so we only call get_frame_saved_regs on - the current frame. This is directly in contradiction to the - usage below, which assumes that registers used in a frame must be - saved in a lower (more interior) frame. This change is a result - of working on a register window machine; get_frame_saved_regs - always returns the registers saved within a frame, within the - context (register namespace) of that frame. */ + /* For each register, address of where it was saved on entry to the + frame, or zero if it was not saved on entry to this frame. This + includes special registers such as pc and fp saved in special + ways in the stack frame. The SP_REGNUM is even more special, the + address here is the sp for the previous frame, not the address + where the sp was saved. */ + /* Allocated by frame_saved_regs_zalloc () which is called / + initialized by DEPRECATED_FRAME_INIT_SAVED_REGS(). */ + CORE_ADDR *saved_regs; /*NUM_REGS + NUM_PSEUDO_REGS*/ - /* However, note that we don't want this to return anything if - nothing is saved (if there's a frame inside of this one). Also, - callers to this routine asking for the stack pointer want the - stack pointer saved for *this* frame; this is returned from the - next frame. */ + /* Anything extra for this structure that may have been defined in + the machine dependent files. */ + /* Allocated by frame_extra_info_zalloc () which is called / + initialized by DEPRECATED_INIT_EXTRA_FRAME_INFO */ + struct frame_extra_info *extra_info; - if (REGISTER_IN_WINDOW_P (regnum)) - { - frame1 = get_next_frame (frame); - if (!frame1) - return 0; /* Registers of this frame are active. */ + /* The frame's low-level unwinder and corresponding cache. The + low-level unwinder is responsible for unwinding register values + for the previous frame. The low-level unwind methods are + selected based on the presence, or otherwize, of register unwind + information such as CFI. */ + void *prologue_cache; + const struct frame_unwind *unwind; - /* Get the SP from the next frame in; it will be this - current frame. */ - if (regnum != SP_REGNUM) - frame1 = frame; + /* Cached copy of the previous frame's resume address. */ + struct { + int p; + CORE_ADDR value; + } prev_pc; + + /* Cached copy of the previous frame's function address. */ + struct + { + CORE_ADDR addr; + int p; + } prev_func; + + /* This frame's ID. */ + struct + { + int p; + struct frame_id value; + } this_id; + + /* The frame's high-level base methods, and corresponding cache. + The high level base methods are selected based on the frame's + debug info. */ + const struct frame_base *base; + void *base_cache; - FRAME_INIT_SAVED_REGS (frame1); - return frame1->saved_regs[regnum]; /* ... which might be zero */ - } -#endif /* HAVE_REGISTER_WINDOWS */ + /* Pointers to the next (down, inner, younger) and previous (up, + outer, older) frame_info's in the frame cache. */ + struct frame_info *next; /* down, inner, younger */ + int prev_p; + struct frame_info *prev; /* up, outer, older */ +}; - /* Note that this next routine assumes that registers used in - frame x will be saved only in the frame that x calls and - frames interior to it. This is not true on the sparc, but the - above macro takes care of it, so we should be all right. */ - while (1) - { - QUIT; - frame1 = get_prev_frame (frame1); - if (frame1 == 0 || frame1 == frame) - break; - FRAME_INIT_SAVED_REGS (frame1); - if (frame1->saved_regs[regnum]) - addr = frame1->saved_regs[regnum]; - } +/* Flag to control debugging. */ - return addr; +static int frame_debug; + +/* Flag to indicate whether backtraces should stop at main et.al. */ + +static int backtrace_past_main; +static unsigned int backtrace_limit = UINT_MAX; + + +void +fprint_frame_id (struct ui_file *file, struct frame_id id) +{ + fprintf_unfiltered (file, "{stack=0x%s,code=0x%s,special=0x%s}", + paddr_nz (id.stack_addr), + paddr_nz (id.code_addr), + paddr_nz (id.special_addr)); } -/* DEFAULT_GET_SAVED_REGISTER () +static void +fprint_frame_type (struct ui_file *file, enum frame_type type) +{ + switch (type) + { + case UNKNOWN_FRAME: + fprintf_unfiltered (file, "UNKNOWN_FRAME"); + return; + case NORMAL_FRAME: + fprintf_unfiltered (file, "NORMAL_FRAME"); + return; + case DUMMY_FRAME: + fprintf_unfiltered (file, "DUMMY_FRAME"); + return; + case SIGTRAMP_FRAME: + fprintf_unfiltered (file, "SIGTRAMP_FRAME"); + return; + default: + fprintf_unfiltered (file, ""); + return; + }; +} +static void +fprint_frame (struct ui_file *file, struct frame_info *fi) +{ + if (fi == NULL) + { + fprintf_unfiltered (file, ""); + return; + } + fprintf_unfiltered (file, "{"); + fprintf_unfiltered (file, "level=%d", fi->level); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "type="); + fprint_frame_type (file, fi->type); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "unwind="); + if (fi->unwind != NULL) + gdb_print_host_address (fi->unwind, file); + else + fprintf_unfiltered (file, ""); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "pc="); + if (fi->next != NULL && fi->next->prev_pc.p) + fprintf_unfiltered (file, "0x%s", paddr_nz (fi->next->prev_pc.value)); + else + fprintf_unfiltered (file, ""); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "id="); + if (fi->this_id.p) + fprint_frame_id (file, fi->this_id.value); + else + fprintf_unfiltered (file, ""); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "func="); + if (fi->next != NULL && fi->next->prev_func.p) + fprintf_unfiltered (file, "0x%s", paddr_nz (fi->next->prev_func.addr)); + else + fprintf_unfiltered (file, ""); + fprintf_unfiltered (file, "}"); +} + +/* Return a frame uniq ID that can be used to, later, re-find the + frame. */ + +struct frame_id +get_frame_id (struct frame_info *fi) +{ + if (fi == NULL) + { + return null_frame_id; + } + if (!fi->this_id.p) + { + gdb_assert (!legacy_frame_p (current_gdbarch)); + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, "{ get_frame_id (fi=%d) ", + fi->level); + /* Find the unwinder. */ + if (fi->unwind == NULL) + { + fi->unwind = frame_unwind_find_by_frame (fi->next); + /* FIXME: cagney/2003-04-02: Rather than storing the frame's + type in the frame, the unwinder's type should be returned + directly. Unfortunately, legacy code, called by + legacy_get_prev_frame, explicitly set the frames type + using the method deprecated_set_frame_type(). */ + fi->type = fi->unwind->type; + } + /* Find THIS frame's ID. */ + fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->this_id.value); + fi->this_id.p = 1; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame_id (gdb_stdlog, fi->this_id.value); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } + } + return fi->this_id.value; +} + +const struct frame_id null_frame_id; /* All zeros. */ + +struct frame_id +frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, + CORE_ADDR special_addr) +{ + struct frame_id id; + id.stack_addr = stack_addr; + id.code_addr = code_addr; + id.special_addr = special_addr; + return id; +} + +struct frame_id +frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr) +{ + return frame_id_build_special (stack_addr, code_addr, 0); +} + +int +frame_id_p (struct frame_id l) +{ + int p; + /* The .code can be NULL but the .stack cannot. */ + p = (l.stack_addr != 0); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ frame_id_p (l="); + fprint_frame_id (gdb_stdlog, l); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", p); + } + return p; +} + +int +frame_id_eq (struct frame_id l, struct frame_id r) +{ + int eq; + if (l.stack_addr == 0 || r.stack_addr == 0) + /* Like a NaN, if either ID is invalid, the result is false. */ + eq = 0; + else if (l.stack_addr != r.stack_addr) + /* If .stack addresses are different, the frames are different. */ + eq = 0; + else if (l.code_addr == 0 || r.code_addr == 0) + /* A zero code addr is a wild card, always succeed. */ + eq = 1; + else if (l.code_addr != r.code_addr) + /* If .code addresses are different, the frames are different. */ + eq = 0; + else if (l.special_addr == 0 || r.special_addr == 0) + /* A zero special addr is a wild card (or unused), always succeed. */ + eq = 1; + else if (l.special_addr == r.special_addr) + /* Frames are equal. */ + eq = 1; + else + /* No luck. */ + eq = 0; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ frame_id_eq (l="); + fprint_frame_id (gdb_stdlog, l); + fprintf_unfiltered (gdb_stdlog, ",r="); + fprint_frame_id (gdb_stdlog, r); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", eq); + } + return eq; +} + +int +frame_id_inner (struct frame_id l, struct frame_id r) +{ + int inner; + if (l.stack_addr == 0 || r.stack_addr == 0) + /* Like NaN, any operation involving an invalid ID always fails. */ + inner = 0; + else + /* Only return non-zero when strictly inner than. Note that, per + comment in "frame.h", there is some fuzz here. Frameless + functions are not strictly inner than (same .stack but + different .code and/or .special address). */ + inner = INNER_THAN (l.stack_addr, r.stack_addr); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ frame_id_inner (l="); + fprint_frame_id (gdb_stdlog, l); + fprintf_unfiltered (gdb_stdlog, ",r="); + fprint_frame_id (gdb_stdlog, r); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", inner); + } + return inner; +} + +struct frame_info * +frame_find_by_id (struct frame_id id) +{ + struct frame_info *frame; + + /* ZERO denotes the null frame, let the caller decide what to do + about it. Should it instead return get_current_frame()? */ + if (!frame_id_p (id)) + return NULL; + + for (frame = get_current_frame (); + frame != NULL; + frame = get_prev_frame (frame)) + { + struct frame_id this = get_frame_id (frame); + if (frame_id_eq (id, this)) + /* An exact match. */ + return frame; + if (frame_id_inner (id, this)) + /* Gone to far. */ + return NULL; + /* Either, we're not yet gone far enough out along the frame + chain (inner(this,id), or we're comparing frameless functions + (same .base, different .func, no test available). Struggle + on until we've definitly gone to far. */ + } + return NULL; +} + +CORE_ADDR +frame_pc_unwind (struct frame_info *this_frame) +{ + if (!this_frame->prev_pc.p) + { + CORE_ADDR pc; + if (gdbarch_unwind_pc_p (current_gdbarch)) + { + /* The right way. The `pure' way. The one true way. This + method depends solely on the register-unwind code to + determine the value of registers in THIS frame, and hence + the value of this frame's PC (resume address). A typical + implementation is no more than: + + frame_unwind_register (this_frame, ISA_PC_REGNUM, buf); + return extract_unsigned_integer (buf, size of ISA_PC_REGNUM); + + Note: this method is very heavily dependent on a correct + register-unwind implementation, it pays to fix that + method first; this method is frame type agnostic, since + it only deals with register values, it works with any + frame. This is all in stark contrast to the old + FRAME_SAVED_PC which would try to directly handle all the + different ways that a PC could be unwound. */ + pc = gdbarch_unwind_pc (current_gdbarch, this_frame); + } + else if (this_frame->level < 0) + { + /* FIXME: cagney/2003-03-06: Old code and and a sentinel + frame. Do like was always done. Fetch the PC's value + direct from the global registers array (via read_pc). + This assumes that this frame belongs to the current + global register cache. The assumption is dangerous. */ + pc = read_pc (); + } + else if (DEPRECATED_FRAME_SAVED_PC_P ()) + { + /* FIXME: cagney/2003-03-06: Old code, but not a sentinel + frame. Do like was always done. Note that this method, + unlike unwind_pc(), tries to handle all the different + frame cases directly. It fails. */ + pc = DEPRECATED_FRAME_SAVED_PC (this_frame); + } + else + internal_error (__FILE__, __LINE__, "No gdbarch_unwind_pc method"); + this_frame->prev_pc.value = pc; + this_frame->prev_pc.p = 1; + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ frame_pc_unwind (this_frame=%d) -> 0x%s }\n", + this_frame->level, + paddr_nz (this_frame->prev_pc.value)); + } + return this_frame->prev_pc.value; +} + +CORE_ADDR +frame_func_unwind (struct frame_info *fi) +{ + if (!fi->prev_func.p) + { + /* Make certain that this, and not the adjacent, function is + found. */ + CORE_ADDR addr_in_block = frame_unwind_address_in_block (fi); + fi->prev_func.p = 1; + fi->prev_func.addr = get_pc_function_start (addr_in_block); + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ frame_func_unwind (fi=%d) -> 0x%s }\n", + fi->level, paddr_nz (fi->prev_func.addr)); + } + return fi->prev_func.addr; +} + +CORE_ADDR +get_frame_func (struct frame_info *fi) +{ + return frame_func_unwind (fi->next); +} + +static int +do_frame_unwind_register (void *src, int regnum, void *buf) +{ + frame_unwind_register (src, regnum, buf); + return 1; +} + +void +frame_pop (struct frame_info *this_frame) +{ + struct regcache *scratch_regcache; + struct cleanup *cleanups; + + if (DEPRECATED_POP_FRAME_P ()) + { + /* A legacy architecture that has implemented a custom pop + function. All new architectures should instead be using the + generic code below. */ + DEPRECATED_POP_FRAME; + } + else + { + /* Make a copy of all the register values unwound from this + frame. Save them in a scratch buffer so that there isn't a + race betweening trying to extract the old values from the + current_regcache while, at the same time writing new values + into that same cache. */ + struct regcache *scratch = regcache_xmalloc (current_gdbarch); + struct cleanup *cleanups = make_cleanup_regcache_xfree (scratch); + regcache_save (scratch, do_frame_unwind_register, this_frame); + /* FIXME: cagney/2003-03-16: It should be possible to tell the + target's register cache that it is about to be hit with a + burst register transfer and that the sequence of register + writes should be batched. The pair target_prepare_to_store() + and target_store_registers() kind of suggest this + functionality. Unfortunately, they don't implement it. Their + lack of a formal definition can lead to targets writing back + bogus values (arguably a bug in the target code mind). */ + /* Now copy those saved registers into the current regcache. + Here, regcache_cpy() calls regcache_restore(). */ + regcache_cpy (current_regcache, scratch); + do_cleanups (cleanups); + } + /* We've made right mess of GDB's local state, just discard + everything. */ + flush_cached_frames (); +} + +void +frame_register_unwind (struct frame_info *frame, int regnum, + int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *bufferp) +{ + struct frame_unwind_cache *cache; + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "\ +{ frame_register_unwind (frame=%d,regnum=%d(%s),...) ", + frame->level, regnum, + frame_map_regnum_to_name (frame, regnum)); + } + + /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates + that the value proper does not need to be fetched. */ + gdb_assert (optimizedp != NULL); + gdb_assert (lvalp != NULL); + gdb_assert (addrp != NULL); + gdb_assert (realnump != NULL); + /* gdb_assert (bufferp != NULL); */ + + /* NOTE: cagney/2002-11-27: A program trying to unwind a NULL frame + is broken. There is always a frame. If there, for some reason, + isn't, there is some pretty busted code as it should have + detected the problem before calling here. */ + gdb_assert (frame != NULL); + + /* Find the unwinder. */ + if (frame->unwind == NULL) + { + frame->unwind = frame_unwind_find_by_frame (frame->next); + /* FIXME: cagney/2003-04-02: Rather than storing the frame's + type in the frame, the unwinder's type should be returned + directly. Unfortunately, legacy code, called by + legacy_get_prev_frame, explicitly set the frames type using + the method deprecated_set_frame_type(). */ + frame->type = frame->unwind->type; + } + + /* Ask this frame to unwind its register. See comment in + "frame-unwind.h" for why NEXT frame and this unwind cace are + passed in. */ + frame->unwind->prev_register (frame->next, &frame->prologue_cache, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "->"); + fprintf_unfiltered (gdb_stdlog, " *optimizedp=%d", (*optimizedp)); + fprintf_unfiltered (gdb_stdlog, " *lvalp=%d", (int) (*lvalp)); + fprintf_unfiltered (gdb_stdlog, " *addrp=0x%s", paddr_nz ((*addrp))); + fprintf_unfiltered (gdb_stdlog, " *bufferp="); + if (bufferp == NULL) + fprintf_unfiltered (gdb_stdlog, ""); + else + { + int i; + const unsigned char *buf = bufferp; + fprintf_unfiltered (gdb_stdlog, "["); + for (i = 0; i < register_size (current_gdbarch, regnum); i++) + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); + fprintf_unfiltered (gdb_stdlog, "]"); + } + fprintf_unfiltered (gdb_stdlog, " }\n"); + } +} + +void +frame_register (struct frame_info *frame, int regnum, + int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *bufferp) +{ + /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates + that the value proper does not need to be fetched. */ + gdb_assert (optimizedp != NULL); + gdb_assert (lvalp != NULL); + gdb_assert (addrp != NULL); + gdb_assert (realnump != NULL); + /* gdb_assert (bufferp != NULL); */ + + /* Ulgh! Old code that, for lval_register, sets ADDRP to the offset + of the register in the register cache. It should instead return + the REGNUM corresponding to that register. Translate the . */ + if (DEPRECATED_GET_SAVED_REGISTER_P ()) + { + DEPRECATED_GET_SAVED_REGISTER (bufferp, optimizedp, addrp, frame, + regnum, lvalp); + /* Compute the REALNUM if the caller wants it. */ + if (*lvalp == lval_register) + { + int regnum; + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (*addrp == register_offset_hack (current_gdbarch, regnum)) + { + *realnump = regnum; + return; + } + } + internal_error (__FILE__, __LINE__, + "Failed to compute the register number corresponding" + " to 0x%s", paddr_d (*addrp)); + } + *realnump = -1; + return; + } + + /* Obtain the register value by unwinding the register from the next + (more inner frame). */ + gdb_assert (frame != NULL && frame->next != NULL); + frame_register_unwind (frame->next, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); +} + +void +frame_unwind_register (struct frame_info *frame, int regnum, void *buf) +{ + int optimized; + CORE_ADDR addr; + int realnum; + enum lval_type lval; + frame_register_unwind (frame, regnum, &optimized, &lval, &addr, + &realnum, buf); +} + +void +get_frame_register (struct frame_info *frame, + int regnum, void *buf) +{ + frame_unwind_register (frame->next, regnum, buf); +} + +LONGEST +frame_unwind_register_signed (struct frame_info *frame, int regnum) +{ + char buf[MAX_REGISTER_SIZE]; + frame_unwind_register (frame, regnum, buf); + return extract_signed_integer (buf, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); +} + +LONGEST +get_frame_register_signed (struct frame_info *frame, int regnum) +{ + return frame_unwind_register_signed (frame->next, regnum); +} + +ULONGEST +frame_unwind_register_unsigned (struct frame_info *frame, int regnum) +{ + char buf[MAX_REGISTER_SIZE]; + frame_unwind_register (frame, regnum, buf); + return extract_unsigned_integer (buf, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); +} + +ULONGEST +get_frame_register_unsigned (struct frame_info *frame, int regnum) +{ + return frame_unwind_register_unsigned (frame->next, regnum); +} + +void +frame_unwind_unsigned_register (struct frame_info *frame, int regnum, + ULONGEST *val) +{ + char buf[MAX_REGISTER_SIZE]; + frame_unwind_register (frame, regnum, buf); + (*val) = extract_unsigned_integer (buf, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); +} + +void +put_frame_register (struct frame_info *frame, int regnum, const void *buf) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + int realnum; + int optim; + enum lval_type lval; + CORE_ADDR addr; + frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL); + if (optim) + error ("Attempt to assign to a value that was optimized out."); + switch (lval) + { + case lval_memory: + { + /* FIXME: write_memory doesn't yet take constant buffers. + Arrrg! */ + char tmp[MAX_REGISTER_SIZE]; + memcpy (tmp, buf, register_size (gdbarch, regnum)); + write_memory (addr, tmp, register_size (gdbarch, regnum)); + break; + } + case lval_register: + regcache_cooked_write (current_regcache, realnum, buf); + break; + default: + error ("Attempt to assign to an unmodifiable value."); + } +} + +/* frame_register_read () + + Find and return the value of REGNUM for the specified stack frame. + The number of bytes copied is DEPRECATED_REGISTER_RAW_SIZE + (REGNUM). + + Returns 0 if the register value could not be found. */ + +int +frame_register_read (struct frame_info *frame, int regnum, void *myaddr) +{ + int optimized; + enum lval_type lval; + CORE_ADDR addr; + int realnum; + frame_register (frame, regnum, &optimized, &lval, &addr, &realnum, myaddr); + + /* FIXME: cagney/2002-05-15: This test, is just bogus. + + It indicates that the target failed to supply a value for a + register because it was "not available" at this time. Problem + is, the target still has the register and so get saved_register() + may be returning a value saved on the stack. */ + + if (register_cached (regnum) < 0) + return 0; /* register value not available */ + + return !optimized; +} + + +/* Map between a frame register number and its name. A frame register + space is a superset of the cooked register space --- it also + includes builtin registers. */ + +int +frame_map_name_to_regnum (struct frame_info *frame, const char *name, int len) +{ + return user_reg_map_name_to_regnum (get_frame_arch (frame), name, len); +} + +const char * +frame_map_regnum_to_name (struct frame_info *frame, int regnum) +{ + return user_reg_map_regnum_to_name (get_frame_arch (frame), regnum); +} + +/* Create a sentinel frame. */ + +static struct frame_info * +create_sentinel_frame (struct regcache *regcache) +{ + struct frame_info *frame = FRAME_OBSTACK_ZALLOC (struct frame_info); + frame->type = NORMAL_FRAME; + frame->level = -1; + /* Explicitly initialize the sentinel frame's cache. Provide it + with the underlying regcache. In the future additional + information, such as the frame's thread will be added. */ + frame->prologue_cache = sentinel_frame_cache (regcache); + /* For the moment there is only one sentinel frame implementation. */ + frame->unwind = sentinel_frame_unwind; + /* Link this frame back to itself. The frame is self referential + (the unwound PC is the same as the pc), so make it so. */ + frame->next = frame; + /* Make the sentinel frame's ID valid, but invalid. That way all + comparisons with it should fail. */ + frame->this_id.p = 1; + frame->this_id.value = null_frame_id; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ create_sentinel_frame (...) -> "); + fprint_frame (gdb_stdlog, frame); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } + return frame; +} + +/* Info about the innermost stack frame (contents of FP register) */ + +static struct frame_info *current_frame; + +/* Cache for frame addresses already read by gdb. Valid only while + inferior is stopped. Control variables for the frame cache should + be local to this module. */ + +static struct obstack frame_cache_obstack; + +void * +frame_obstack_zalloc (unsigned long size) +{ + void *data = obstack_alloc (&frame_cache_obstack, size); + memset (data, 0, size); + return data; +} + +CORE_ADDR * +frame_saved_regs_zalloc (struct frame_info *fi) +{ + fi->saved_regs = (CORE_ADDR *) + frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS); + return fi->saved_regs; +} + +CORE_ADDR * +deprecated_get_frame_saved_regs (struct frame_info *fi) +{ + return fi->saved_regs; +} + +/* Return the innermost (currently executing) stack frame. This is + split into two functions. The function unwind_to_current_frame() + is wrapped in catch exceptions so that, even when the unwind of the + sentinel frame fails, the function still returns a stack frame. */ + +static int +unwind_to_current_frame (struct ui_out *ui_out, void *args) +{ + struct frame_info *frame = get_prev_frame (args); + /* A sentinel frame can fail to unwind, eg, because it's PC value + lands in somewhere like start. */ + if (frame == NULL) + return 1; + current_frame = frame; + return 0; +} + +struct frame_info * +get_current_frame (void) +{ + /* First check, and report, the lack of registers. Having GDB + report "No stack!" or "No memory" when the target doesn't even + have registers is very confusing. Besides, "printcmd.exp" + explicitly checks that ``print $pc'' with no registers prints "No + registers". */ + if (!target_has_registers) + error ("No registers."); + if (!target_has_stack) + error ("No stack."); + if (!target_has_memory) + error ("No memory."); + if (current_frame == NULL) + { + struct frame_info *sentinel_frame = + create_sentinel_frame (current_regcache); + if (catch_exceptions (uiout, unwind_to_current_frame, sentinel_frame, + NULL, RETURN_MASK_ERROR) != 0) + { + /* Oops! Fake a current frame? Is this useful? It has a PC + of zero, for instance. */ + current_frame = sentinel_frame; + } + } + return current_frame; +} + +/* The "selected" stack frame is used by default for local and arg + access. May be zero, for no selected frame. */ + +struct frame_info *deprecated_selected_frame; + +/* Return the selected frame. Always non-null (unless there isn't an + inferior sufficient for creating a frame) in which case an error is + thrown. */ + +struct frame_info * +get_selected_frame (void) +{ + if (deprecated_selected_frame == NULL) + /* Hey! Don't trust this. It should really be re-finding the + last selected frame of the currently selected thread. This, + though, is better than nothing. */ + select_frame (get_current_frame ()); + /* There is always a frame. */ + gdb_assert (deprecated_selected_frame != NULL); + return deprecated_selected_frame; +} + +/* This is a variant of get_selected_frame which can be called when + the inferior does not have a frame; in that case it will return + NULL instead of calling error (). */ + +struct frame_info * +deprecated_safe_get_selected_frame (void) +{ + if (!target_has_registers || !target_has_stack || !target_has_memory) + return NULL; + return get_selected_frame (); +} + +/* Select frame FI (or NULL - to invalidate the current frame). */ + +void +select_frame (struct frame_info *fi) +{ + struct symtab *s; + + deprecated_selected_frame = fi; + /* NOTE: cagney/2002-05-04: FI can be NULL. This occures when the + frame is being invalidated. */ + if (selected_frame_level_changed_hook) + selected_frame_level_changed_hook (frame_relative_level (fi)); + + /* FIXME: kseitz/2002-08-28: It would be nice to call + selected_frame_level_changed_event right here, but due to limitations + in the current interfaces, we would end up flooding UIs with events + because select_frame is used extensively internally. + + Once we have frame-parameterized frame (and frame-related) commands, + the event notification can be moved here, since this function will only + be called when the users selected frame is being changed. */ + + /* Ensure that symbols for this frame are read in. Also, determine the + source language of this frame, and switch to it if desired. */ + if (fi) + { + /* We retrieve the frame's symtab by using the frame PC. However + we cannot use the frame pc as is, because it usually points to + the instruction following the "call", which is sometimes the + first instruction of another function. So we rely on + get_frame_address_in_block() which provides us with a PC which + is guaranteed to be inside the frame's code block. */ + s = find_pc_symtab (get_frame_address_in_block (fi)); + if (s + && s->language != current_language->la_language + && s->language != language_unknown + && language_mode == language_mode_auto) + { + set_language (s->language); + } + } +} + +/* Return the register saved in the simplistic ``saved_regs'' cache. + If the value isn't here AND a value is needed, try the next inner + most frame. */ + +static void +legacy_saved_regs_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) +{ + /* HACK: New code is passed the next frame and this cache. + Unfortunately, old code expects this frame. Since this is a + backward compatibility hack, cheat by walking one level along the + prologue chain to the frame the old code expects. + + Do not try this at home. Professional driver, closed course. */ + struct frame_info *frame = next_frame->prev; + gdb_assert (frame != NULL); + + if (deprecated_get_frame_saved_regs (frame) == NULL) + { + /* If nothing's initialized the saved regs, do it now. */ + gdb_assert (DEPRECATED_FRAME_INIT_SAVED_REGS_P ()); + DEPRECATED_FRAME_INIT_SAVED_REGS (frame); + gdb_assert (deprecated_get_frame_saved_regs (frame) != NULL); + } + + if (deprecated_get_frame_saved_regs (frame) != NULL + && deprecated_get_frame_saved_regs (frame)[regnum] != 0) + { + if (regnum == SP_REGNUM) + { + /* SP register treated specially. */ + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (bufferp != NULL) + /* NOTE: cagney/2003-05-09: In-lined store_address with + it's body - store_unsigned_integer. */ + store_unsigned_integer (bufferp, DEPRECATED_REGISTER_RAW_SIZE (regnum), + deprecated_get_frame_saved_regs (frame)[regnum]); + } + else + { + /* Any other register is saved in memory, fetch it but cache + a local copy of its value. */ + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = deprecated_get_frame_saved_regs (frame)[regnum]; + *realnump = -1; + if (bufferp != NULL) + { +#if 1 + /* Save each register value, as it is read in, in a + frame based cache. */ + void **regs = (*this_prologue_cache); + if (regs == NULL) + { + int sizeof_cache = ((NUM_REGS + NUM_PSEUDO_REGS) + * sizeof (void *)); + regs = frame_obstack_zalloc (sizeof_cache); + (*this_prologue_cache) = regs; + } + if (regs[regnum] == NULL) + { + regs[regnum] + = frame_obstack_zalloc (DEPRECATED_REGISTER_RAW_SIZE (regnum)); + read_memory (deprecated_get_frame_saved_regs (frame)[regnum], regs[regnum], + DEPRECATED_REGISTER_RAW_SIZE (regnum)); + } + memcpy (bufferp, regs[regnum], DEPRECATED_REGISTER_RAW_SIZE (regnum)); +#else + /* Read the value in from memory. */ + read_memory (deprecated_get_frame_saved_regs (frame)[regnum], bufferp, + DEPRECATED_REGISTER_RAW_SIZE (regnum)); +#endif + } + } + return; + } + + /* No luck. Assume this and the next frame have the same register + value. Pass the unwind request down the frame chain to the next + frame. Hopefully that frame will find the register's location. */ + frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); +} + +static void +legacy_saved_regs_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *id) +{ + /* A developer is trying to bring up a new architecture, help them + by providing a default unwinder that refuses to unwind anything + (the ID is always NULL). In the case of legacy code, + legacy_get_prev_frame() will have previously set ->this_id.p, so + this code won't be called. */ + (*id) = null_frame_id; +} + +const struct frame_unwind legacy_saved_regs_unwinder = { + /* Not really. It gets overridden by legacy_get_prev_frame. */ + UNKNOWN_FRAME, + legacy_saved_regs_this_id, + legacy_saved_regs_prev_register +}; +const struct frame_unwind *legacy_saved_regs_unwind = &legacy_saved_regs_unwinder; + + +/* Function: deprecated_generic_get_saved_register Find register number REGNUM relative to FRAME and put its (raw, - target format) contents in *RAW_BUFFER. Set *OPTIMIZED if the - variable was optimized out (and thus can't be fetched). Set *LVAL - to lval_memory, lval_register, or not_lval, depending on whether - the value was fetched from memory, from a register, or in a strange - and non-modifiable way (e.g. a frame pointer which was calculated - rather than fetched). Set *ADDRP to the address, either in memory - on as a REGISTER_BYTE offset into the registers array. + target format) contents in *RAW_BUFFER. - Note that this implementation never sets *LVAL to not_lval. But - it can be replaced by defining GET_SAVED_REGISTER and supplying - your own. + Set *OPTIMIZED if the variable was optimized out (and thus can't be + fetched). Note that this is never set to anything other than zero + in this implementation. + + Set *LVAL to lval_memory, lval_register, or not_lval, depending on + whether the value was fetched from memory, from a register, or in a + strange and non-modifiable way (e.g. a frame pointer which was + calculated rather than fetched). We will use not_lval for values + fetched from generic dummy frames. + + Set *ADDRP to the address, either in memory or as a + DEPRECATED_REGISTER_BYTE offset into the registers array. If the + value is stored in a dummy frame, set *ADDRP to zero. The argument RAW_BUFFER must point to aligned memory. */ -static void -default_get_saved_register (char *raw_buffer, - int *optimized, - CORE_ADDR *addrp, - struct frame_info *frame, - int regnum, - enum lval_type *lval) +void +deprecated_generic_get_saved_register (char *raw_buffer, int *optimized, + CORE_ADDR *addrp, + struct frame_info *frame, int regnum, + enum lval_type *lval) { - CORE_ADDR addr; - if (!target_has_registers) error ("No registers."); /* Normal systems don't optimize out things with register numbers. */ if (optimized != NULL) *optimized = 0; - addr = find_saved_register (frame, regnum); - if (addr != 0) + + if (addrp) /* default assumption: not found in memory */ + *addrp = 0; + + /* Note: since the current frame's registers could only have been + saved by frames INTERIOR TO the current frame, we skip examining + the current frame itself: otherwise, we would be getting the + previous frame's registers which were saved by the current frame. */ + + if (frame != NULL) { - if (lval != NULL) - *lval = lval_memory; - if (regnum == SP_REGNUM) + for (frame = get_next_frame (frame); + frame_relative_level (frame) >= 0; + frame = get_next_frame (frame)) { - if (raw_buffer != NULL) + if (get_frame_type (frame) == DUMMY_FRAME) { - /* Put it back in target format. */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), - (LONGEST) addr); + if (lval) /* found it in a CALL_DUMMY frame */ + *lval = not_lval; + if (raw_buffer) + /* FIXME: cagney/2002-06-26: This should be via the + gdbarch_register_read() method so that it, on the + fly, constructs either a raw or pseudo register + from the raw register cache. */ + regcache_raw_read + (deprecated_find_dummy_frame_regcache (get_frame_pc (frame), + get_frame_base (frame)), + regnum, raw_buffer); + return; + } + + DEPRECATED_FRAME_INIT_SAVED_REGS (frame); + if (deprecated_get_frame_saved_regs (frame) != NULL + && deprecated_get_frame_saved_regs (frame)[regnum] != 0) + { + if (lval) /* found it saved on the stack */ + *lval = lval_memory; + if (regnum == SP_REGNUM) + { + if (raw_buffer) /* SP register treated specially */ + /* NOTE: cagney/2003-05-09: In-line store_address + with it's body - store_unsigned_integer. */ + store_unsigned_integer (raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (regnum), + deprecated_get_frame_saved_regs (frame)[regnum]); + } + else + { + if (addrp) /* any other register */ + *addrp = deprecated_get_frame_saved_regs (frame)[regnum]; + if (raw_buffer) + read_memory (deprecated_get_frame_saved_regs (frame)[regnum], raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (regnum)); + } + return; } - if (addrp != NULL) - *addrp = 0; - return; } - if (raw_buffer != NULL) - target_read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum)); } + + /* If we get thru the loop to this point, it means the register was + not saved in any frame. Return the actual live-register value. */ + + if (lval) /* found it in a live register */ + *lval = lval_register; + if (addrp) + *addrp = DEPRECATED_REGISTER_BYTE (regnum); + if (raw_buffer) + deprecated_read_register_gen (regnum, raw_buffer); +} + +/* Determine the frame's type based on its PC. */ + +static enum frame_type +frame_type_from_pc (CORE_ADDR pc) +{ + /* FIXME: cagney/2002-11-24: Can't yet directly call + pc_in_dummy_frame() as some architectures don't set + PC_IN_CALL_DUMMY() to generic_pc_in_call_dummy() (remember the + latter is implemented by simply calling pc_in_dummy_frame). */ + if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES + && DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0)) + return DUMMY_FRAME; else { - if (lval != NULL) - *lval = lval_register; - addr = REGISTER_BYTE (regnum); - if (raw_buffer != NULL) - read_register_gen (regnum, raw_buffer); + char *name; + find_pc_partial_function (pc, &name, NULL, NULL); + if (PC_IN_SIGTRAMP (pc, name)) + return SIGTRAMP_FRAME; + else + return NORMAL_FRAME; } - if (addrp != NULL) - *addrp = addr; } -#if !defined (GET_SAVED_REGISTER) -#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \ - default_get_saved_register(raw_buffer, optimized, addrp, frame, regnum, lval) -#endif +/* Create an arbitrary (i.e. address specified by user) or innermost frame. + Always returns a non-NULL value. */ + +struct frame_info * +create_new_frame (CORE_ADDR addr, CORE_ADDR pc) +{ + struct frame_info *fi; + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, + "{ create_new_frame (addr=0x%s, pc=0x%s) ", + paddr_nz (addr), paddr_nz (pc)); + } + + fi = frame_obstack_zalloc (sizeof (struct frame_info)); + + fi->next = create_sentinel_frame (current_regcache); + + /* Select/initialize both the unwind function and the frame's type + based on the PC. */ + fi->unwind = frame_unwind_find_by_frame (fi->next); + if (fi->unwind->type != UNKNOWN_FRAME) + fi->type = fi->unwind->type; + else + fi->type = frame_type_from_pc (pc); + + fi->this_id.p = 1; + deprecated_update_frame_base_hack (fi, addr); + deprecated_update_frame_pc_hack (fi, pc); + + if (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()) + DEPRECATED_INIT_EXTRA_FRAME_INFO (0, fi); + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, fi); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } + + return fi; +} + +/* Return the frame that THIS_FRAME calls (NULL if THIS_FRAME is the + innermost frame). Be careful to not fall off the bottom of the + frame chain and onto the sentinel frame. */ + +struct frame_info * +get_next_frame (struct frame_info *this_frame) +{ + if (this_frame->level > 0) + return this_frame->next; + else + return NULL; +} + +/* Flush the entire frame cache. */ void -get_saved_register (char *raw_buffer, - int *optimized, - CORE_ADDR *addrp, - struct frame_info *frame, - int regnum, - enum lval_type *lval) +flush_cached_frames (void) { - GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval); + /* Since we can't really be sure what the first object allocated was */ + obstack_free (&frame_cache_obstack, 0); + obstack_init (&frame_cache_obstack); + + current_frame = NULL; /* Invalidate cache */ + select_frame (NULL); + annotate_frames_invalid (); + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, "{ flush_cached_frames () }\n"); } -/* READ_RELATIVE_REGISTER_RAW_BYTES_FOR_FRAME +/* Flush the frame cache, and start a new one if necessary. */ - Copy the bytes of register REGNUM, relative to the input stack frame, - into our memory at MYADDR, in target byte order. - The number of bytes copied is REGISTER_RAW_SIZE (REGNUM). - - Returns 1 if could not be read, 0 if could. */ - -/* FIXME: This function increases the confusion between FP_REGNUM - and the virtual/pseudo-frame pointer. */ - -static int -read_relative_register_raw_bytes_for_frame (int regnum, - char *myaddr, - struct frame_info *frame) +void +reinit_frame_cache (void) { - int optim; - if (regnum == FP_REGNUM && frame) - { - /* Put it back in target format. */ - store_address (myaddr, REGISTER_RAW_SIZE (FP_REGNUM), - (LONGEST) FRAME_FP (frame)); + flush_cached_frames (); - return 0; + /* FIXME: The inferior_ptid test is wrong if there is a corefile. */ + if (PIDGET (inferior_ptid) != 0) + { + select_frame (get_current_frame ()); + } +} + +/* Create the previous frame using the deprecated methods + INIT_EXTRA_INFO, INIT_FRAME_PC and INIT_FRAME_PC_FIRST. */ + +static struct frame_info * +legacy_get_prev_frame (struct frame_info *this_frame) +{ + CORE_ADDR address = 0; + struct frame_info *prev; + int fromleaf; + + /* Don't frame_debug print legacy_get_prev_frame() here, just + confuses the output. */ + + /* Allocate the new frame. + + There is no reason to worry about memory leaks, should the + remainder of the function fail. The allocated memory will be + quickly reclaimed when the frame cache is flushed, and the `we've + been here before' check, in get_prev_frame will stop repeated + memory allocation calls. */ + prev = FRAME_OBSTACK_ZALLOC (struct frame_info); + prev->level = this_frame->level + 1; + + /* Do not completely wire it in to the frame chain. Some (bad) code + in INIT_FRAME_EXTRA_INFO tries to look along frame->prev to pull + some fancy tricks (of course such code is, by definition, + recursive). + + On the other hand, methods, such as get_frame_pc() and + get_frame_base() rely on being able to walk along the frame + chain. Make certain that at least they work by providing that + link. Of course things manipulating prev can't go back. */ + prev->next = this_frame; + + /* NOTE: cagney/2002-11-18: Should have been correctly setting the + frame's type here, before anything else, and not last, at the + bottom of this function. The various + DEPRECATED_INIT_EXTRA_FRAME_INFO, DEPRECATED_INIT_FRAME_PC, + DEPRECATED_INIT_FRAME_PC_FIRST and + DEPRECATED_FRAME_INIT_SAVED_REGS methods are full of work-arounds + that handle the frame not being correctly set from the start. + Unfortunately those same work-arounds rely on the type defaulting + to NORMAL_FRAME. Ulgh! The new frame code does not have this + problem. */ + prev->type = UNKNOWN_FRAME; + + /* A legacy frame's ID is always computed here. Mark it as valid. */ + prev->this_id.p = 1; + + /* Handle sentinel frame unwind as a special case. */ + if (this_frame->level < 0) + { + /* Try to unwind the PC. If that doesn't work, assume we've reached + the oldest frame and simply return. Is there a better sentinal + value? The unwound PC value is then used to initialize the new + previous frame's type. + + Note that the pc-unwind is intentionally performed before the + frame chain. This is ok since, for old targets, both + frame_pc_unwind (nee, DEPRECATED_FRAME_SAVED_PC) and + DEPRECATED_FRAME_CHAIN()) assume THIS_FRAME's data structures + have already been initialized (using + DEPRECATED_INIT_EXTRA_FRAME_INFO) and hence the call order + doesn't matter. + + By unwinding the PC first, it becomes possible to, in the case of + a dummy frame, avoid also unwinding the frame ID. This is + because (well ignoring the PPC) a dummy frame can be located + using THIS_FRAME's frame ID. */ + + deprecated_update_frame_pc_hack (prev, frame_pc_unwind (this_frame)); + if (get_frame_pc (prev) == 0) + { + /* The allocated PREV_FRAME will be reclaimed when the frame + obstack is next purged. */ + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // unwound legacy PC zero }\n"); + } + return NULL; + } + + /* Set the unwind functions based on that identified PC. Ditto + for the "type" but strongly prefer the unwinder's frame type. */ + prev->unwind = frame_unwind_find_by_frame (prev->next); + if (prev->unwind->type == UNKNOWN_FRAME) + prev->type = frame_type_from_pc (get_frame_pc (prev)); + else + prev->type = prev->unwind->type; + + /* Find the prev's frame's ID. */ + if (prev->type == DUMMY_FRAME + && gdbarch_unwind_dummy_id_p (current_gdbarch)) + { + /* When unwinding a normal frame, the stack structure is + determined by analyzing the frame's function's code (be + it using brute force prologue analysis, or the dwarf2 + CFI). In the case of a dummy frame, that simply isn't + possible. The The PC is either the program entry point, + or some random address on the stack. Trying to use that + PC to apply standard frame ID unwind techniques is just + asking for trouble. */ + /* Use an architecture specific method to extract the prev's + dummy ID from the next frame. Note that this method uses + frame_register_unwind to obtain the register values + needed to determine the dummy frame's ID. */ + prev->this_id.value = gdbarch_unwind_dummy_id (current_gdbarch, + this_frame); + } + else + { + /* We're unwinding a sentinel frame, the PC of which is + pointing at a stack dummy. Fake up the dummy frame's ID + using the same sequence as is found a traditional + unwinder. Once all architectures supply the + unwind_dummy_id method, this code can go away. */ + prev->this_id.value = frame_id_build (deprecated_read_fp (), + read_pc ()); + } + + /* Check that the unwound ID is valid. */ + if (!frame_id_p (prev->this_id.value)) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // unwound legacy ID invalid }\n"); + } + return NULL; + } + + /* Check that the new frame isn't inner to (younger, below, + next) the old frame. If that happens the frame unwind is + going backwards. */ + /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since + that doesn't have a valid frame ID. Should instead set the + sentinel frame's frame ID to a `sentinel'. Leave it until + after the switch to storing the frame ID, instead of the + frame base, in the frame object. */ + + /* Link it in. */ + this_frame->prev = prev; + + /* FIXME: cagney/2002-01-19: This call will go away. Instead of + initializing extra info, all frames will use the frame_cache + (passed to the unwind functions) to store additional frame + info. Unfortunately legacy targets can't use + legacy_get_prev_frame() to unwind the sentinel frame and, + consequently, are forced to take this code path and rely on + the below call to DEPRECATED_INIT_EXTRA_FRAME_INFO to + initialize the inner-most frame. */ + if (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()) + { + DEPRECATED_INIT_EXTRA_FRAME_INFO (0, prev); + } + + if (prev->type == NORMAL_FRAME) + prev->this_id.value.code_addr + = get_pc_function_start (prev->this_id.value.code_addr); + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy innermost frame\n"); + } + return prev; } - get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, frame, - regnum, (enum lval_type *) NULL); + /* This code only works on normal frames. A sentinel frame, where + the level is -1, should never reach this code. */ + gdb_assert (this_frame->level >= 0); - if (register_cached (regnum) < 0) - return 1; /* register value not available */ + /* On some machines it is possible to call a function without + setting up a stack frame for it. On these machines, we + define this macro to take two args; a frameinfo pointer + identifying a frame and a variable to set or clear if it is + or isn't leafless. */ - return optim; + /* Still don't want to worry about this except on the innermost + frame. This macro will set FROMLEAF if THIS_FRAME is a frameless + function invocation. */ + if (this_frame->level == 0) + /* FIXME: 2002-11-09: Frameless functions can occure anywhere in + the frame chain, not just the inner most frame! The generic, + per-architecture, frame code should handle this and the below + should simply be removed. */ + fromleaf = (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P () + && DEPRECATED_FRAMELESS_FUNCTION_INVOCATION (this_frame)); + else + fromleaf = 0; + + if (fromleaf) + /* A frameless inner-most frame. The `FP' (which isn't an + architecture frame-pointer register!) of the caller is the same + as the callee. */ + /* FIXME: 2002-11-09: There isn't any reason to special case this + edge condition. Instead the per-architecture code should hande + it locally. */ + /* FIXME: cagney/2003-06-16: This returns the inner most stack + address for the previous frame, that, however, is wrong. It + should be the inner most stack address for the previous to + previous frame. This is because it is the previous to previous + frame's innermost stack address that is constant through out + the lifetime of the previous frame (trust me :-). */ + address = get_frame_base (this_frame); + else + { + /* Two macros defined in tm.h specify the machine-dependent + actions to be performed here. + + First, get the frame's chain-pointer. + + If that is zero, the frame is the outermost frame or a leaf + called by the outermost frame. This means that if start + calls main without a frame, we'll return 0 (which is fine + anyway). + + Nope; there's a problem. This also returns when the current + routine is a leaf of main. This is unacceptable. We move + this to after the ffi test; I'd rather have backtraces from + start go curfluy than have an abort called from main not show + main. */ + if (DEPRECATED_FRAME_CHAIN_P ()) + address = DEPRECATED_FRAME_CHAIN (this_frame); + else + { + /* Someone is part way through coverting an old architecture + to the new frame code. Implement FRAME_CHAIN the way the + new frame will. */ + /* Find PREV frame's unwinder. */ + prev->unwind = frame_unwind_find_by_frame (this_frame->next); + /* FIXME: cagney/2003-04-02: Rather than storing the frame's + type in the frame, the unwinder's type should be returned + directly. Unfortunately, legacy code, called by + legacy_get_prev_frame, explicitly set the frames type + using the method deprecated_set_frame_type(). */ + prev->type = prev->unwind->type; + /* Find PREV frame's ID. */ + prev->unwind->this_id (this_frame, + &prev->prologue_cache, + &prev->this_id.value); + prev->this_id.p = 1; + address = prev->this_id.value.stack_addr; + } + + if (!legacy_frame_chain_valid (address, this_frame)) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // legacy frame chain invalid }\n"); + } + return NULL; + } + } + if (address == 0) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // legacy frame chain NULL }\n"); + } + return NULL; + } + + /* Link in the already allocated prev frame. */ + this_frame->prev = prev; + deprecated_update_frame_base_hack (prev, address); + + /* This change should not be needed, FIXME! We should determine + whether any targets *need* DEPRECATED_INIT_FRAME_PC to happen + after DEPRECATED_INIT_EXTRA_FRAME_INFO and come up with a simple + way to express what goes on here. + + DEPRECATED_INIT_EXTRA_FRAME_INFO is called from two places: + create_new_frame (where the PC is already set up) and here (where + it isn't). DEPRECATED_INIT_FRAME_PC is only called from here, + always after DEPRECATED_INIT_EXTRA_FRAME_INFO. + + The catch is the MIPS, where DEPRECATED_INIT_EXTRA_FRAME_INFO + requires the PC value (which hasn't been set yet). Some other + machines appear to require DEPRECATED_INIT_EXTRA_FRAME_INFO + before they can do DEPRECATED_INIT_FRAME_PC. Phoo. + + We shouldn't need DEPRECATED_INIT_FRAME_PC_FIRST to add more + complication to an already overcomplicated part of GDB. + gnu@cygnus.com, 15Sep92. + + Assuming that some machines need DEPRECATED_INIT_FRAME_PC after + DEPRECATED_INIT_EXTRA_FRAME_INFO, one possible scheme: + + SETUP_INNERMOST_FRAME(): Default version is just create_new_frame + (deprecated_read_fp ()), read_pc ()). Machines with extra frame + info would do that (or the local equivalent) and then set the + extra fields. + + SETUP_ARBITRARY_FRAME(argc, argv): 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 + DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_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 DEPRECATED_FRAME_CHAIN_VALID + called BEFORE DEPRECATED_INIT_EXTRA_FRAME_INFO (there is no good + way to get information deduced in DEPRECATED_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 DEPRECATED_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, 31Jan94, 14Dec94. */ + + /* NOTE: cagney/2002-11-09: Just ignore the above! There is no + reason for things to be this complicated. + + The trick is to assume that there is always a frame. Instead of + special casing the inner-most frame, create fake frame + (containing the hardware registers) that is inner to the + user-visible inner-most frame (...) and then unwind from that. + That way architecture code can use use the standard + frame_XX_unwind() functions and not differentiate between the + inner most and any other case. + + Since there is always a frame to unwind from, there is always + somewhere (THIS_FRAME) to store all the info needed to construct + a new (previous) frame without having to first create it. This + means that the convolution below - needing to carefully order a + frame's initialization - isn't needed. + + The irony here though, is that DEPRECATED_FRAME_CHAIN(), at least + for a more up-to-date architecture, always calls + FRAME_SAVED_PC(), and FRAME_SAVED_PC() computes the PC but + without first needing the frame! Instead of the convolution + below, we could have simply called FRAME_SAVED_PC() and been done + with it! Note that FRAME_SAVED_PC() is being superseed by + frame_pc_unwind() and that function does have somewhere to cache + that PC value. */ + + if (DEPRECATED_INIT_FRAME_PC_FIRST_P ()) + deprecated_update_frame_pc_hack (prev, + DEPRECATED_INIT_FRAME_PC_FIRST (fromleaf, + prev)); + + if (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()) + DEPRECATED_INIT_EXTRA_FRAME_INFO (fromleaf, prev); + + /* This entry is in the frame queue now, which is good since + 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. */ + if (DEPRECATED_INIT_FRAME_PC_P ()) + deprecated_update_frame_pc_hack (prev, + DEPRECATED_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 DEPRECATED_FRAME_CHAIN or thereabouts, but it seems + like there is no reason this can't be an architecture-independent + check. */ + if (get_frame_base (prev) == get_frame_base (this_frame) + && get_frame_pc (prev) == get_frame_pc (this_frame)) + { + this_frame->prev = NULL; + obstack_free (&frame_cache_obstack, prev); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // legacy this.id == prev.id }\n"); + } + return NULL; + } + + /* Initialize the code used to unwind the frame PREV based on the PC + (and probably other architectural information). The PC lets you + check things like the debug info at that point (dwarf2cfi?) and + use that to decide how the frame should be unwound. + + If there isn't a FRAME_CHAIN, the code above will have already + done this. */ + if (prev->unwind == NULL) + prev->unwind = frame_unwind_find_by_frame (prev->next); + + /* If the unwinder provides a frame type, use it. Otherwize + continue on to that heuristic mess. */ + if (prev->unwind->type != UNKNOWN_FRAME) + { + prev->type = prev->unwind->type; + if (prev->type == NORMAL_FRAME) + /* FIXME: cagney/2003-06-16: would get_frame_pc() be better? */ + prev->this_id.value.code_addr + = get_pc_function_start (prev->this_id.value.code_addr); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy with unwound type\n"); + } + return prev; + } + + /* NOTE: cagney/2002-11-18: The code segments, found in + create_new_frame and get_prev_frame(), that initializes the + frames type is subtly different. The latter only updates ->type + when it encounters a SIGTRAMP_FRAME or DUMMY_FRAME. This stops + get_prev_frame() overriding the frame's type when the INIT code + has previously set it. This is really somewhat bogus. The + initialization, as seen in create_new_frame(), should occur + before the INIT function has been called. */ + if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES + && (DEPRECATED_PC_IN_CALL_DUMMY_P () + ? DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (prev), 0, 0) + : pc_in_dummy_frame (get_frame_pc (prev)))) + prev->type = DUMMY_FRAME; + else + { + /* FIXME: cagney/2002-11-10: This should be moved to before the + INIT code above so that the INIT code knows what the frame's + type is (in fact, for a [generic] dummy-frame, the type can + be set and then the entire initialization can be skipped. + Unforunatly, its the INIT code that sets the PC (Hmm, catch + 22). */ + char *name; + find_pc_partial_function (get_frame_pc (prev), &name, NULL, NULL); + if (PC_IN_SIGTRAMP (get_frame_pc (prev), name)) + prev->type = SIGTRAMP_FRAME; + /* FIXME: cagney/2002-11-11: Leave prev->type alone. Some + architectures are forcing the frame's type in INIT so we + don't want to override it here. Remember, NORMAL_FRAME == 0, + so it all works (just :-/). Once this initialization is + moved to the start of this function, all this nastness will + go away. */ + } + + if (prev->type == NORMAL_FRAME) + prev->this_id.value.code_addr + = get_pc_function_start (prev->this_id.value.code_addr); + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy with confused type\n"); + } + + return prev; } -/* READ_RELATIVE_REGISTER_RAW_BYTES +/* Return a structure containing various interesting information + about the frame that called THIS_FRAME. Returns NULL + if there is no such frame. - Copy the bytes of register REGNUM, relative to the current stack - frame, into our memory at MYADDR, in target byte order. - The number of bytes copied is REGISTER_RAW_SIZE (REGNUM). + This function tests some target-independent conditions that should + terminate the frame chain, such as unwinding past main(). It + should not contain any target-dependent tests, such as checking + whether the program-counter is zero. */ - Returns 1 if could not be read, 0 if could. */ +struct frame_info * +get_prev_frame (struct frame_info *this_frame) +{ + struct frame_info *prev_frame; + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ get_prev_frame (this_frame="); + if (this_frame != NULL) + fprintf_unfiltered (gdb_stdlog, "%d", this_frame->level); + else + fprintf_unfiltered (gdb_stdlog, ""); + fprintf_unfiltered (gdb_stdlog, ") "); + } + + /* Return the inner-most frame, when the caller passes in NULL. */ + /* NOTE: cagney/2002-11-09: Not sure how this would happen. The + caller should have previously obtained a valid frame using + get_selected_frame() and then called this code - only possibility + I can think of is code behaving badly. + + NOTE: cagney/2003-01-10: Talk about code behaving badly. Check + block_innermost_frame(). It does the sequence: frame = NULL; + while (1) { frame = get_prev_frame (frame); .... }. Ulgh! Why + it couldn't be written better, I don't know. + + NOTE: cagney/2003-01-11: I suspect what is happening is + block_innermost_frame() is, when the target has no state + (registers, memory, ...), still calling this function. The + assumption being that this function will return NULL indicating + that a frame isn't possible, rather than checking that the target + has state and then calling get_current_frame() and + get_prev_frame(). This is a guess mind. */ + if (this_frame == NULL) + { + /* NOTE: cagney/2002-11-09: There was a code segment here that + would error out when CURRENT_FRAME was NULL. The comment + that went with it made the claim ... + + ``This screws value_of_variable, which just wants a nice + clean NULL return from block_innermost_frame if there are no + frames. I don't think I've ever seen this message happen + otherwise. And returning NULL here is a perfectly legitimate + thing to do.'' + + Per the above, this code shouldn't even be called with a NULL + THIS_FRAME. */ + return current_frame; + } + + /* There is always a frame. If this assertion fails, suspect that + something should be calling get_selected_frame() or + get_current_frame(). */ + gdb_assert (this_frame != NULL); + + /* Make sure we pass an address within THIS_FRAME's code block to + inside_main_func. Otherwise, we might stop unwinding at a + function which has a call instruction as its last instruction if + that function immediately precedes main(). */ + if (this_frame->level >= 0 + && !backtrace_past_main + && inside_main_func (get_frame_address_in_block (this_frame))) + /* Don't unwind past main(), bug always unwind the sentinel frame. + Note, this is done _before_ the frame has been marked as + previously unwound. That way if the user later decides to + allow unwinds past main(), that just happens. */ + { + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, "-> NULL // inside main func }\n"); + return NULL; + } + + if (this_frame->level > backtrace_limit) + { + error ("Backtrace limit of %d exceeded", backtrace_limit); + } + + /* If we're already inside the entry function for the main objfile, + then it isn't valid. Don't apply this test to a dummy frame - + dummy frame PC's typically land in the entry func. Don't apply + this test to the sentinel frame. Sentinel frames should always + be allowed to unwind. */ + /* NOTE: cagney/2003-02-25: Don't enable until someone has found + hard evidence that this is needed. */ + /* NOTE: cagney/2003-07-07: Fixed a bug in inside_main_func - wasn't + checking for "main" in the minimal symbols. With that fixed + asm-source tests now stop in "main" instead of halting the + backtrace in wierd and wonderful ways somewhere inside the entry + file. Suspect that deprecated_inside_entry_file and + inside_entry_func tests were added to work around that (now + fixed) case. */ + /* NOTE: cagney/2003-07-15: danielj (if I'm reading it right) + suggested having the inside_entry_func test use the + inside_main_func msymbol trick (along with entry_point_address I + guess) to determine the address range of the start function. + That should provide a far better stopper than the current + heuristics. */ + /* NOTE: cagney/2003-07-15: Need to add a "set backtrace + beyond-entry-func" command so that this can be selectively + disabled. */ + if (0 +#if 0 + && backtrace_beyond_entry_func +#endif + && this_frame->type != DUMMY_FRAME && this_frame->level >= 0 + && inside_entry_func (this_frame)) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, "// inside entry func }\n"); + } + return NULL; + } + + /* Only try to do the unwind once. */ + if (this_frame->prev_p) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, this_frame->prev); + fprintf_unfiltered (gdb_stdlog, " // cached \n"); + } + return this_frame->prev; + } + this_frame->prev_p = 1; + + /* If we're inside the entry file, it isn't valid. Don't apply this + test to a dummy frame - dummy frame PC's typically land in the + entry file. Don't apply this test to the sentinel frame. + Sentinel frames should always be allowed to unwind. */ + /* NOTE: drow/2002-12-25: should there be a way to disable this + check? It assumes a single small entry file, and the way some + debug readers (e.g. dbxread) figure out which object is the + entry file is somewhat hokey. */ + /* NOTE: cagney/2003-01-10: If there is a way of disabling this test + then it should probably be moved to before the ->prev_p test, + above. */ + /* NOTE: vinschen/2003-04-01: Disabled. It turns out that the call + to deprecated_inside_entry_file destroys a meaningful backtrace + under some conditions. E. g. the backtrace tests in the + asm-source testcase are broken for some targets. In this test + the functions are all implemented as part of one file and the + testcase is not necessarily linked with a start file (depending + on the target). What happens is, that the first frame is printed + normaly and following frames are treated as being inside the + enttry file then. This way, only the #0 frame is printed in the + backtrace output. */ + if (0 + && this_frame->type != DUMMY_FRAME && this_frame->level >= 0 + && deprecated_inside_entry_file (get_frame_pc (this_frame))) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, " // inside entry file }\n"); + } + return NULL; + } + + /* If any of the old frame initialization methods are around, use + the legacy get_prev_frame method. */ + if (legacy_frame_p (current_gdbarch)) + { + prev_frame = legacy_get_prev_frame (this_frame); + return prev_frame; + } + + /* Check that this frame's ID was valid. If it wasn't, don't try to + unwind to the prev frame. Be careful to not apply this test to + the sentinel frame. */ + if (this_frame->level >= 0 && !frame_id_p (get_frame_id (this_frame))) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, " // this ID is NULL }\n"); + } + return NULL; + } + + /* Check that this frame's ID isn't inner to (younger, below, next) + the next frame. This happens when a frame unwind goes backwards. + Since the sentinel frame doesn't really exist, don't compare the + inner-most against that sentinel. */ + if (this_frame->level > 0 + && frame_id_inner (get_frame_id (this_frame), + get_frame_id (this_frame->next))) + error ("Previous frame inner to this frame (corrupt stack?)"); + + /* Check that this and the next frame are not identical. If they + are, there is most likely a stack cycle. As with the inner-than + test above, avoid comparing the inner-most and sentinel frames. */ + if (this_frame->level > 0 + && frame_id_eq (get_frame_id (this_frame), + get_frame_id (this_frame->next))) + error ("Previous frame identical to this frame (corrupt stack?)"); + + /* Allocate the new frame but do not wire it in to the frame chain. + Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along + frame->next to pull some fancy tricks (of course such code is, by + definition, recursive). Try to prevent it. + + There is no reason to worry about memory leaks, should the + remainder of the function fail. The allocated memory will be + quickly reclaimed when the frame cache is flushed, and the `we've + been here before' check above will stop repeated memory + allocation calls. */ + prev_frame = FRAME_OBSTACK_ZALLOC (struct frame_info); + prev_frame->level = this_frame->level + 1; + + /* Don't yet compute ->unwind (and hence ->type). It is computed + on-demand in get_frame_type, frame_register_unwind, and + get_frame_id. */ + + /* Don't yet compute the frame's ID. It is computed on-demand by + get_frame_id(). */ + + /* The unwound frame ID is validate at the start of this function, + as part of the logic to decide if that frame should be further + unwound, and not here while the prev frame is being created. + Doing this makes it possible for the user to examine a frame that + has an invalid frame ID. + + Some very old VAX code noted: [...] For the sake of argument, + suppose that the stack is somewhat trashed (which is one reason + that "info frame" exists). So, return 0 (indicating we don't + know the address of the arglist) if we don't know what frame this + frame calls. */ + + /* Link it in. */ + this_frame->prev = prev_frame; + prev_frame->next = this_frame; + + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev_frame); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } + + return prev_frame; +} + +CORE_ADDR +get_frame_pc (struct frame_info *frame) +{ + gdb_assert (frame->next != NULL); + return frame_pc_unwind (frame->next); +} + +/* Return an address of that falls within the frame's code block. */ + +CORE_ADDR +frame_unwind_address_in_block (struct frame_info *next_frame) +{ + /* A draft address. */ + CORE_ADDR pc = frame_pc_unwind (next_frame); + + /* If THIS frame is not inner most (i.e., NEXT isn't the sentinel), + and NEXT is `normal' (i.e., not a sigtramp, dummy, ....) THIS + frame's PC ends up pointing at the instruction fallowing the + "call". Adjust that PC value so that it falls on the call + instruction (which, hopefully, falls within THIS frame's code + block. So far it's proved to be a very good approximation. See + get_frame_type for why ->type can't be used. */ + if (next_frame->level >= 0 + && get_frame_type (next_frame) == NORMAL_FRAME) + --pc; + return pc; +} + +CORE_ADDR +get_frame_address_in_block (struct frame_info *this_frame) +{ + return frame_unwind_address_in_block (this_frame->next); +} + +static int +pc_notcurrent (struct frame_info *frame) +{ + /* If FRAME is not the innermost frame, that normally means that + FRAME->pc points at the return instruction (which is *after* the + call instruction), and we want to get the line containing the + call (because the call is where the user thinks the program is). + However, if the next frame is either a SIGTRAMP_FRAME or a + DUMMY_FRAME, then the next frame will contain a saved interrupt + PC and such a PC indicates the current (rather than next) + instruction/line, consequently, for such cases, want to get the + line containing fi->pc. */ + struct frame_info *next = get_next_frame (frame); + int notcurrent = (next != NULL && get_frame_type (next) == NORMAL_FRAME); + return notcurrent; +} + +void +find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal) +{ + (*sal) = find_pc_line (get_frame_pc (frame), pc_notcurrent (frame)); +} + +/* Per "frame.h", return the ``address'' of the frame. Code should + really be using get_frame_id(). */ +CORE_ADDR +get_frame_base (struct frame_info *fi) +{ + return get_frame_id (fi).stack_addr; +} + +/* High-level offsets into the frame. Used by the debug info. */ + +CORE_ADDR +get_frame_base_address (struct frame_info *fi) +{ + if (get_frame_type (fi) != NORMAL_FRAME) + return 0; + if (fi->base == NULL) + fi->base = frame_base_find_by_frame (fi->next); + /* Sneaky: If the low-level unwind and high-level base code share a + common unwinder, let them share the prologue cache. */ + if (fi->base->unwind == fi->unwind) + return fi->base->this_base (fi->next, &fi->prologue_cache); + return fi->base->this_base (fi->next, &fi->base_cache); +} + +CORE_ADDR +get_frame_locals_address (struct frame_info *fi) +{ + void **cache; + if (get_frame_type (fi) != NORMAL_FRAME) + return 0; + /* If there isn't a frame address method, find it. */ + if (fi->base == NULL) + fi->base = frame_base_find_by_frame (fi->next); + /* Sneaky: If the low-level unwind and high-level base code share a + common unwinder, let them share the prologue cache. */ + if (fi->base->unwind == fi->unwind) + cache = &fi->prologue_cache; + else + cache = &fi->base_cache; + return fi->base->this_locals (fi->next, cache); +} + +CORE_ADDR +get_frame_args_address (struct frame_info *fi) +{ + void **cache; + if (get_frame_type (fi) != NORMAL_FRAME) + return 0; + /* If there isn't a frame address method, find it. */ + if (fi->base == NULL) + fi->base = frame_base_find_by_frame (fi->next); + /* Sneaky: If the low-level unwind and high-level base code share a + common unwinder, let them share the prologue cache. */ + if (fi->base->unwind == fi->unwind) + cache = &fi->prologue_cache; + else + cache = &fi->base_cache; + return fi->base->this_args (fi->next, cache); +} + +/* Level of the selected frame: 0 for innermost, 1 for its caller, ... + or -1 for a NULL frame. */ int -read_relative_register_raw_bytes (int regnum, char *myaddr) +frame_relative_level (struct frame_info *fi) { - return read_relative_register_raw_bytes_for_frame (regnum, myaddr, - selected_frame); + if (fi == NULL) + return -1; + else + return fi->level; +} + +enum frame_type +get_frame_type (struct frame_info *frame) +{ + /* Some targets still don't use [generic] dummy frames. Catch them + here. */ + if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES + && deprecated_frame_in_dummy (frame)) + return DUMMY_FRAME; + + /* Some legacy code, e.g, mips_init_extra_frame_info() wants + to determine the frame's type prior to it being completely + initialized. Don't attempt to lazily initialize ->unwind for + legacy code. It will be initialized in legacy_get_prev_frame(). */ + if (frame->unwind == NULL && !legacy_frame_p (current_gdbarch)) + { + /* Initialize the frame's unwinder because it is that which + provides the frame's type. */ + frame->unwind = frame_unwind_find_by_frame (frame->next); + /* FIXME: cagney/2003-04-02: Rather than storing the frame's + type in the frame, the unwinder's type should be returned + directly. Unfortunately, legacy code, called by + legacy_get_prev_frame, explicitly set the frames type using + the method deprecated_set_frame_type(). */ + frame->type = frame->unwind->type; + } + if (frame->type == UNKNOWN_FRAME) + return NORMAL_FRAME; + else + return frame->type; +} + +void +deprecated_set_frame_type (struct frame_info *frame, enum frame_type type) +{ + /* Arrrg! See comment in "frame.h". */ + frame->type = type; +} + +struct frame_extra_info * +get_frame_extra_info (struct frame_info *fi) +{ + return fi->extra_info; +} + +struct frame_extra_info * +frame_extra_info_zalloc (struct frame_info *fi, long size) +{ + fi->extra_info = frame_obstack_zalloc (size); + return fi->extra_info; +} + +void +deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc) +{ + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ deprecated_update_frame_pc_hack (frame=%d,pc=0x%s) }\n", + frame->level, paddr_nz (pc)); + /* NOTE: cagney/2003-03-11: Some architectures (e.g., Arm) are + maintaining a locally allocated frame object. Since such frame's + are not in the frame chain, it isn't possible to assume that the + frame has a next. Sigh. */ + if (frame->next != NULL) + { + /* While we're at it, update this frame's cached PC value, found + in the next frame. Oh for the day when "struct frame_info" + is opaque and this hack on hack can just go away. */ + frame->next->prev_pc.value = pc; + frame->next->prev_pc.p = 1; + } +} + +void +deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base) +{ + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ deprecated_update_frame_base_hack (frame=%d,base=0x%s) }\n", + frame->level, paddr_nz (base)); + /* See comment in "frame.h". */ + frame->this_id.value.stack_addr = base; +} + +struct frame_info * +deprecated_frame_xmalloc_with_cleanup (long sizeof_saved_regs, + long sizeof_extra_info) +{ + struct frame_info *frame = XMALLOC (struct frame_info); + memset (frame, 0, sizeof (*frame)); + frame->this_id.p = 1; + make_cleanup (xfree, frame); + if (sizeof_saved_regs > 0) + { + frame->saved_regs = xcalloc (1, sizeof_saved_regs); + make_cleanup (xfree, frame->saved_regs); + } + if (sizeof_extra_info > 0) + { + frame->extra_info = xcalloc (1, sizeof_extra_info); + make_cleanup (xfree, frame->extra_info); + } + return frame; +} + +/* Memory access methods. */ + +void +get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr, void *buf, + int len) +{ + read_memory (addr, buf, len); +} + +LONGEST +get_frame_memory_signed (struct frame_info *this_frame, CORE_ADDR addr, + int len) +{ + return read_memory_integer (addr, len); +} + +ULONGEST +get_frame_memory_unsigned (struct frame_info *this_frame, CORE_ADDR addr, + int len) +{ + return read_memory_unsigned_integer (addr, len); +} + +/* Architecture method. */ + +struct gdbarch * +get_frame_arch (struct frame_info *this_frame) +{ + return current_gdbarch; +} + +/* Stack pointer methods. */ + +CORE_ADDR +get_frame_sp (struct frame_info *this_frame) +{ + return frame_sp_unwind (this_frame->next); +} + +CORE_ADDR +frame_sp_unwind (struct frame_info *next_frame) +{ + /* Normality, an architecture that provides a way of obtaining any + frame inner-most address. */ + if (gdbarch_unwind_sp_p (current_gdbarch)) + return gdbarch_unwind_sp (current_gdbarch, next_frame); + /* Things are looking grim. If it's the inner-most frame and there + is a TARGET_READ_SP then that can be used. */ + if (next_frame->level < 0 && TARGET_READ_SP_P ()) + return TARGET_READ_SP (); + /* Now things are really are grim. Hope that the value returned by + the SP_REGNUM register is meaningful. */ + if (SP_REGNUM >= 0) + { + ULONGEST sp; + frame_unwind_unsigned_register (next_frame, SP_REGNUM, &sp); + return sp; + } + internal_error (__FILE__, __LINE__, "Missing unwind SP method"); +} + + +int +legacy_frame_p (struct gdbarch *current_gdbarch) +{ + if (DEPRECATED_INIT_FRAME_PC_P () + || DEPRECATED_INIT_FRAME_PC_FIRST_P () + || DEPRECATED_INIT_EXTRA_FRAME_INFO_P () + || DEPRECATED_FRAME_CHAIN_P ()) + /* No question, it's a legacy frame. */ + return 1; + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) + /* No question, it's not a legacy frame (provided none of the + deprecated methods checked above are present that is). */ + return 0; + if (DEPRECATED_TARGET_READ_FP_P () + || DEPRECATED_FP_REGNUM >= 0) + /* Assume it's legacy. If you're trying to convert a legacy frame + target to the new mechanism, get rid of these. legacy + get_prev_frame requires these when unwind_frame_id isn't + available. */ + return 1; + /* Default to assuming that it's brand new code, and hence not + legacy. Force it down the non-legacy path so that the new code + uses the new frame mechanism from day one. Dummy frame's won't + work very well but we can live with that. */ + return 0; +} + +extern initialize_file_ftype _initialize_frame; /* -Wmissing-prototypes */ + +static struct cmd_list_element *set_backtrace_cmdlist; +static struct cmd_list_element *show_backtrace_cmdlist; + +static void +set_backtrace_cmd (char *args, int from_tty) +{ + help_list (set_backtrace_cmdlist, "set backtrace ", -1, gdb_stdout); +} + +static void +show_backtrace_cmd (char *args, int from_tty) +{ + cmd_show_list (show_backtrace_cmdlist, from_tty, ""); +} + +void +_initialize_frame (void) +{ + obstack_init (&frame_cache_obstack); + + add_prefix_cmd ("backtrace", class_maintenance, set_backtrace_cmd, "\ +Set backtrace specific variables.\n\ +Configure backtrace variables such as the backtrace limit", + &set_backtrace_cmdlist, "set backtrace ", + 0/*allow-unknown*/, &setlist); + add_prefix_cmd ("backtrace", class_maintenance, show_backtrace_cmd, "\ +Show backtrace specific variables\n\ +Show backtrace variables such as the backtrace limit", + &show_backtrace_cmdlist, "show backtrace ", + 0/*allow-unknown*/, &showlist); + + add_setshow_boolean_cmd ("past-main", class_obscure, + &backtrace_past_main, "\ +Set whether backtraces should continue past \"main\".\n\ +Normally the caller of \"main\" is not of interest, so GDB will terminate\n\ +the backtrace at \"main\". Set this variable if you need to see the rest\n\ +of the stack trace.", "\ +Show whether backtraces should continue past \"main\".\n\ +Normally the caller of \"main\" is not of interest, so GDB will terminate\n\ +the backtrace at \"main\". Set this variable if you need to see the rest\n\ +of the stack trace.", + NULL, NULL, &set_backtrace_cmdlist, + &show_backtrace_cmdlist); + + add_setshow_uinteger_cmd ("limit", class_obscure, + &backtrace_limit, "\ +Set an upper bound on the number of backtrace levels.\n\ +No more than the specified number of frames can be displayed or examined.\n\ +Zero is unlimited.", "\ +Show the upper bound on the number of backtrace levels.", + NULL, NULL, &set_backtrace_cmdlist, + &show_backtrace_cmdlist); + + /* Debug this files internals. */ + add_show_from_set (add_set_cmd ("frame", class_maintenance, var_zinteger, + &frame_debug, "Set frame debugging.\n\ +When non-zero, frame specific internal debugging is enabled.", &setdebuglist), + &showdebuglist); } diff --git a/contrib/gdb/gdb/frame.h b/contrib/gdb/gdb/frame.h index b5f535a26d0..0cdae6d31dc 100644 --- a/contrib/gdb/gdb/frame.h +++ b/contrib/gdb/gdb/frame.h @@ -1,6 +1,7 @@ /* Definitions for dealing with stack frames, for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, - 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -22,89 +23,447 @@ #if !defined (FRAME_H) #define FRAME_H 1 -/* Describe the saved registers of a frame. */ +/* The following is the intended naming schema for frame functions. + It isn't 100% consistent, but it is aproaching that. Frame naming + schema: -#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS) -/* XXXX - deprecated */ -struct frame_saved_regs - { - /* For each register R (except the SP), regs[R] is the address at - which it was saved on entry to the frame, or zero if it was not - saved on entry to this frame. This includes special registers - such as pc and fp saved in special ways in the stack frame. + Prefixes: - regs[SP_REGNUM] is different. It holds the actual SP, not the - address at which it was saved. */ + get_frame_WHAT...(): Get WHAT from the THIS frame (functionaly + equivalent to THIS->next->unwind->what) - CORE_ADDR regs[NUM_REGS]; - }; -#endif + frame_unwind_WHAT...(): Unwind THIS frame's WHAT from the NEXT + frame. -/* We keep a cache of stack frames, each of which is a "struct - frame_info". The innermost one gets allocated (in - wait_for_inferior) each time the inferior stops; current_frame - points to it. Additional frames get allocated (in - get_prev_frame) as needed, and are chained through the next - and prev fields. Any time that the frame cache becomes invalid - (most notably when we execute something, but also if we change how - we interpret the frames (e.g. "set heuristic-fence-post" in - mips-tdep.c, or anything which reads new symbols)), we should call - reinit_frame_cache. */ + put_frame_WHAT...(): Put a value into this frame (unsafe, need to + invalidate the frame / regcache afterwards) (better name more + strongly hinting at its unsafeness) -struct frame_info - { - /* Nominal address of the frame described. See comments at FRAME_FP - about what this means outside the *FRAME* macros; in the *FRAME* - macros, it can mean whatever makes most sense for this machine. */ - CORE_ADDR frame; + safe_....(): Safer version of various functions, doesn't throw an + error (leave this for later?). Returns non-zero if the fetch + succeeds. Return a freshly allocated error message? - /* Address at which execution is occurring in this frame. - For the innermost frame, it's the current pc. - For other frames, it is a pc saved in the next frame. */ - CORE_ADDR pc; + Suffixes: - /* Nonzero if this is a frame associated with calling a signal handler. + void /frame/_WHAT(): Read WHAT's value into the buffer parameter. - Set by machine-dependent code. On some machines, if - the machine-dependent code fails to check for this, the backtrace - will look relatively normal. For example, on the i386 - #3 0x158728 in sighold () - On other machines (e.g. rs6000), the machine-dependent code better - set this to prevent us from trying to print it like a normal frame. */ - int signal_handler_caller; + ULONGEST /frame/_WHAT_unsigned(): Return an unsigned value (the + alternative is *frame_unsigned_WHAT). - /* For each register, address of where it was saved on entry to - the frame, or zero if it was not saved on entry to this frame. - This includes special registers such as pc and fp saved in - special ways in the stack frame. The SP_REGNUM is even more - special, the address here is the sp for the previous frame, not - the address where the sp was saved. */ - /* Allocated by frame_saved_regs_zalloc () which is called / - initialized by FRAME_INIT_SAVED_REGS(). */ - CORE_ADDR *saved_regs; /*NUM_REGS + NUM_PSEUDO_REGS*/ + LONGEST /frame/_WHAT_signed(): Return WHAT signed value. -#ifdef EXTRA_FRAME_INFO - /* XXXX - deprecated */ - /* Anything extra for this structure that may have been defined - in the machine dependent files. */ - EXTRA_FRAME_INFO -#endif + What: - /* Anything extra for this structure that may have been defined - in the machine dependent files. */ - /* Allocated by frame_obstack_alloc () which is called / - initialized by INIT_EXTRA_FRAME_INFO */ - struct frame_extra_info *extra_info; + /frame/_memory* (frame, coreaddr, len [, buf]): Extract/return + *memory. - /* If dwarf2 unwind frame informations is used, this structure holds all - related unwind data. */ - struct unwind_contect *context; + /frame/_register* (frame, regnum [, buf]): extract/return register. + + CORE_ADDR /frame/_{pc,sp,...} (frame): Resume address, innner most + stack *address, ... + + */ + +struct symtab_and_line; +struct frame_unwind; +struct frame_base; +struct block; +struct gdbarch; +struct ui_file; + +/* A legacy unwinder to prop up architectures using the old style + saved regs array. */ +extern const struct frame_unwind *legacy_saved_regs_unwind; + +/* The frame object. */ + +struct frame_info; + +/* The frame object's ID. This provides a per-frame unique identifier + that can be used to relocate a `struct frame_info' after a target + resume or a frame cache destruct. It of course assumes that the + inferior hasn't unwound the stack past that frame. */ + +struct frame_id +{ + /* The frame's stack address. This shall be constant through out + the lifetime of a frame. Note that this requirement applies to + not just the function body, but also the prologue and (in theory + at least) the epilogue. Since that value needs to fall either on + the boundary, or within the frame's address range, the frame's + outer-most address (the inner-most address of the previous frame) + is used. Watch out for all the legacy targets that still use the + function pointer register or stack pointer register. They are + wrong. */ + CORE_ADDR stack_addr; + /* The frame's code address. This shall be constant through out the + lifetime of the frame. While the PC (a.k.a. resume address) + changes as the function is executed, this code address cannot. + Typically, it is set to the address of the entry point of the + frame's function (as returned by frame_func_unwind(). */ + CORE_ADDR code_addr; + /* The frame's special address. This shall be constant through out the + lifetime of the frame. This is used for architectures that may have + frames that do not change the stack but are still distinct and have + some form of distinct identifier (e.g. the ia64 which uses a 2nd + stack for registers). This field is treated as unordered - i.e. will + not be used in frame ordering comparisons such as frame_id_inner(). + A zero in this field will be treated as a wild-card when comparing + frames for equality. */ + CORE_ADDR special_addr; +}; + +/* Methods for constructing and comparing Frame IDs. + + NOTE: Given stackless functions A and B, where A calls B (and hence + B is inner-to A). The relationships: !eq(A,B); !eq(B,A); + !inner(A,B); !inner(B,A); all hold. + + This is because, while B is inner-to A, B is not strictly inner-to A. + Being stackless, they have an identical .stack_addr value, and differ + only by their unordered .code_addr and/or .special_addr values. + + Because frame_id_inner is only used as a safety net (e.g., + detect a corrupt stack) the lack of strictness is not a problem. + Code needing to determine an exact relationship between two frames + must instead use frame_id_eq and frame_id_unwind. For instance, + in the above, to determine that A stepped-into B, the equation + "A.id != B.id && A.id == id_unwind (B)" can be used. */ + +/* For convenience. All fields are zero. */ +extern const struct frame_id null_frame_id; + +/* Construct a frame ID. The first parameter is the frame's constant + stack address (typically the outer-bound), and the second the + frame's constant code address (typically the entry point) (or zero, + to indicate a wild card). The special identifier address is + defaulted to zero. */ +extern struct frame_id frame_id_build (CORE_ADDR stack_addr, + CORE_ADDR code_addr); + +/* Construct a special frame ID. The first parameter is the frame's constant + stack address (typically the outer-bound), the second is the + frame's constant code address (typically the entry point) (or zero, + to indicate a wild card), and the third parameter is the frame's + special identifier address (or zero to indicate a wild card or + unused default). */ +extern struct frame_id frame_id_build_special (CORE_ADDR stack_addr, + CORE_ADDR code_addr, + CORE_ADDR special_addr); + +/* Returns non-zero when L is a valid frame (a valid frame has a + non-zero .base). */ +extern int frame_id_p (struct frame_id l); + +/* Returns non-zero when L and R identify the same frame, or, if + either L or R have a zero .func, then the same frame base. */ +extern int frame_id_eq (struct frame_id l, struct frame_id r); + +/* Returns non-zero when L is strictly inner-than R (they have + different frame .bases). Neither L, nor R can be `null'. See note + above about frameless functions. */ +extern int frame_id_inner (struct frame_id l, struct frame_id r); + +/* Write the internal representation of a frame ID on the specified + stream. */ +extern void fprint_frame_id (struct ui_file *file, struct frame_id id); + + +/* For every stopped thread, GDB tracks two frames: current and + selected. Current frame is the inner most frame of the selected + thread. Selected frame is the one being examined by the the GDB + CLI (selected using `up', `down', ...). The frames are created + on-demand (via get_prev_frame()) and then held in a frame cache. */ +/* FIXME: cagney/2002-11-28: Er, there is a lie here. If you do the + sequence: `thread 1; up; thread 2; thread 1' you loose thread 1's + selected frame. At present GDB only tracks the selected frame of + the current thread. But be warned, that might change. */ +/* FIXME: cagney/2002-11-14: At any time, only one thread's selected + and current frame can be active. Switching threads causes gdb to + discard all that cached frame information. Ulgh! Instead, current + and selected frame should be bound to a thread. */ + +/* On demand, create the inner most frame using information found in + the inferior. If the inner most frame can't be created, throw an + error. */ +extern struct frame_info *get_current_frame (void); + +/* Invalidates the frame cache (this function should have been called + invalidate_cached_frames). + + FIXME: cagney/2002-11-28: The only difference between + flush_cached_frames() and reinit_frame_cache() is that the latter + explicitly sets the selected frame back to the current frame there + isn't any real difference (except that one delays the selection of + a new frame). Code can instead simply rely on get_selected_frame() + to reinit's the selected frame as needed. As for invalidating the + cache, there should be two methods one that reverts the thread's + selected frame back to current frame (for when the inferior + resumes) and one that does not (for when the user modifies the + target invalidating the frame cache). */ +extern void flush_cached_frames (void); +extern void reinit_frame_cache (void); + +/* On demand, create the selected frame and then return it. If the + selected frame can not be created, this function throws an error. */ +/* FIXME: cagney/2002-11-28: At present, when there is no selected + frame, this function always returns the current (inner most) frame. + It should instead, when a thread has previously had its frame + selected (but not resumed) and the frame cache invalidated, find + and then return that thread's previously selected frame. */ +extern struct frame_info *get_selected_frame (void); + +/* Select a specific frame. NULL, apparently implies re-select the + inner most frame. */ +extern void select_frame (struct frame_info *); + +/* Given a FRAME, return the next (more inner, younger) or previous + (more outer, older) frame. */ +extern struct frame_info *get_prev_frame (struct frame_info *); +extern struct frame_info *get_next_frame (struct frame_info *); + +/* Given a frame's ID, relocate the frame. Returns NULL if the frame + is not found. */ +extern struct frame_info *frame_find_by_id (struct frame_id id); + +/* Base attributes of a frame: */ + +/* The frame's `resume' address. Where the program will resume in + this frame. + + This replaced: frame->pc; */ +extern CORE_ADDR get_frame_pc (struct frame_info *); + +/* An address (not necessarily alligned to an instruction boundary) + that falls within THIS frame's code block. + + When a function call is the last statement in a block, the return + address for the call may land at the start of the next block. + Similarly, if a no-return function call is the last statement in + the function, the return address may end up pointing beyond the + function, and possibly at the start of the next function. + + These methods make an allowance for this. For call frames, this + function returns the frame's PC-1 which "should" be an address in + the frame's block. */ + +extern CORE_ADDR get_frame_address_in_block (struct frame_info *this_frame); +extern CORE_ADDR frame_unwind_address_in_block (struct frame_info *next_frame); + +/* The frame's inner-most bound. AKA the stack-pointer. Confusingly + known as top-of-stack. */ + +extern CORE_ADDR get_frame_sp (struct frame_info *); +extern CORE_ADDR frame_sp_unwind (struct frame_info *); + + +/* Following on from the `resume' address. Return the entry point + address of the function containing that resume address, or zero if + that function isn't known. */ +extern CORE_ADDR frame_func_unwind (struct frame_info *fi); +extern CORE_ADDR get_frame_func (struct frame_info *fi); + +/* Closely related to the resume address, various symbol table + attributes that are determined by the PC. Note that for a normal + frame, the PC refers to the resume address after the return, and + not the call instruction. In such a case, the address is adjusted + so that it (approximatly) identifies the call site (and not return + site). + + NOTE: cagney/2002-11-28: The frame cache could be used to cache the + computed value. Working on the assumption that the bottle-neck is + in the single step code, and that code causes the frame cache to be + constantly flushed, caching things in a frame is probably of little + benefit. As they say `show us the numbers'. + + NOTE: cagney/2002-11-28: Plenty more where this one came from: + find_frame_block(), find_frame_partial_function(), + find_frame_symtab(), find_frame_function(). Each will need to be + carefully considered to determine if the real intent was for it to + apply to the PC or the adjusted PC. */ +extern void find_frame_sal (struct frame_info *frame, + struct symtab_and_line *sal); + +/* Return the frame base (what ever that is) (DEPRECATED). + + Old code was trying to use this single method for two conflicting + purposes. Such code needs to be updated to use either of: + + get_frame_id: A low level frame unique identifier, that consists of + both a stack and a function address, that can be used to uniquely + identify a frame. This value is determined by the frame's + low-level unwinder, the stack part [typically] being the + top-of-stack of the previous frame, and the function part being the + function's start address. Since the correct identification of a + frameless function requires both the a stack and function address, + the old get_frame_base method was not sufficient. + + get_frame_base_address: get_frame_locals_address: + get_frame_args_address: A set of high-level debug-info dependant + addresses that fall within the frame. These addresses almost + certainly will not match the stack address part of a frame ID (as + returned by get_frame_base). + + This replaced: frame->frame; */ + +extern CORE_ADDR get_frame_base (struct frame_info *); + +/* Return the per-frame unique identifer. Can be used to relocate a + frame after a frame cache flush (and other similar operations). If + FI is NULL, return the null_frame_id. */ +extern struct frame_id get_frame_id (struct frame_info *fi); + +/* Assuming that a frame is `normal', return its base-address, or 0 if + the information isn't available. NOTE: This address is really only + meaningful to the frame's high-level debug info. */ +extern CORE_ADDR get_frame_base_address (struct frame_info *); + +/* Assuming that a frame is `normal', return the base-address of the + local variables, or 0 if the information isn't available. NOTE: + This address is really only meaningful to the frame's high-level + debug info. Typically, the argument and locals share a single + base-address. */ +extern CORE_ADDR get_frame_locals_address (struct frame_info *); + +/* Assuming that a frame is `normal', return the base-address of the + parameter list, or 0 if that information isn't available. NOTE: + This address is really only meaningful to the frame's high-level + debug info. Typically, the argument and locals share a single + base-address. */ +extern CORE_ADDR get_frame_args_address (struct frame_info *); + +/* The frame's level: 0 for innermost, 1 for its caller, ...; or -1 + for an invalid frame). */ +extern int frame_relative_level (struct frame_info *fi); + +/* Return the frame's type. Some are real, some are signal + trampolines, and some are completely artificial (dummy). */ + +enum frame_type +{ + /* The frame's type hasn't yet been defined. This is a catch-all + for legacy code that uses really strange technicques, such as + deprecated_set_frame_type, to set the frame's type. New code + should not use this value. */ + UNKNOWN_FRAME, + /* A true stack frame, created by the target program during normal + execution. */ + NORMAL_FRAME, + /* A fake frame, created by GDB when performing an inferior function + call. */ + DUMMY_FRAME, + /* In a signal handler, various OSs handle this in various ways. + The main thing is that the frame may be far from normal. */ + SIGTRAMP_FRAME +}; +extern enum frame_type get_frame_type (struct frame_info *); + +/* FIXME: cagney/2002-11-10: Some targets want to directly mark a + frame as being of a specific type. This shouldn't be necessary. + PC_IN_SIGTRAMP() indicates a SIGTRAMP_FRAME and + DEPRECATED_PC_IN_CALL_DUMMY() indicates a DUMMY_FRAME. I suspect + the real problem here is that get_prev_frame() only sets + initialized after DEPRECATED_INIT_EXTRA_FRAME_INFO as been called. + Consequently, some targets found that the frame's type was wrong + and tried to fix it. The correct fix is to modify get_prev_frame() + so that it initializes the frame's type before calling any other + functions. */ +extern void deprecated_set_frame_type (struct frame_info *, + enum frame_type type); + +/* Unwind the stack frame so that the value of REGNUM, in the previous + (up, older) frame is returned. If VALUEP is NULL, don't + fetch/compute the value. Instead just return the location of the + value. */ +extern void frame_register_unwind (struct frame_info *frame, int regnum, + int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, + void *valuep); + +/* Fetch a register from this, or unwind a register from the next + frame. Note that the get_frame methods are wrappers to + frame->next->unwind. They all [potentially] throw an error if the + fetch fails. */ + +extern void frame_unwind_register (struct frame_info *frame, + int regnum, void *buf); +extern void get_frame_register (struct frame_info *frame, + int regnum, void *buf); + +extern LONGEST frame_unwind_register_signed (struct frame_info *frame, + int regnum); +extern LONGEST get_frame_register_signed (struct frame_info *frame, + int regnum); +extern ULONGEST frame_unwind_register_unsigned (struct frame_info *frame, + int regnum); +extern ULONGEST get_frame_register_unsigned (struct frame_info *frame, + int regnum); + + +/* Use frame_unwind_register_signed. */ +extern void frame_unwind_unsigned_register (struct frame_info *frame, + int regnum, ULONGEST *val); + +/* Get the value of the register that belongs to this FRAME. This + function is a wrapper to the call sequence ``frame_unwind_register + (get_next_frame (FRAME))''. As per frame_register_unwind(), if + VALUEP is NULL, the registers value is not fetched/computed. */ + +extern void frame_register (struct frame_info *frame, int regnum, + int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, + void *valuep); + +/* The reverse. Store a register value relative to the specified + frame. Note: this call makes the frame's state undefined. The + register and frame caches must be flushed. */ +extern void put_frame_register (struct frame_info *frame, int regnum, + const void *buf); + +/* Map between a frame register number and its name. A frame register + space is a superset of the cooked register space --- it also + includes builtin registers. If NAMELEN is negative, use the NAME's + length when doing the comparison. */ + +extern int frame_map_name_to_regnum (struct frame_info *frame, + const char *name, int namelen); +extern const char *frame_map_regnum_to_name (struct frame_info *frame, + int regnum); + +/* Unwind the PC. Strictly speaking return the resume address of the + calling frame. For GDB, `pc' is the resume address and not a + specific register. */ + +extern CORE_ADDR frame_pc_unwind (struct frame_info *frame); + +/* Discard the specified frame. Restoring the registers to the state + of the caller. */ +extern void frame_pop (struct frame_info *frame); + +/* Return memory from the specified frame. A frame knows its thread / + LWP and hence can find its way down to a target. The assumption + here is that the current and previous frame share a common address + space. + + If the memory read fails, these methods throw an error. + + NOTE: cagney/2003-06-03: Should there be unwind versions of these + methods? That isn't clear. Can code, for instance, assume that + this and the previous frame's memory or architecture are identical? + If architecture / memory changes are always separated by special + adaptor frames this should be ok. */ + +extern void get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr, + void *buf, int len); +extern LONGEST get_frame_memory_signed (struct frame_info *this_frame, + CORE_ADDR memaddr, int len); +extern ULONGEST get_frame_memory_unsigned (struct frame_info *this_frame, + CORE_ADDR memaddr, int len); + +/* Return this frame's architecture. */ + +extern struct gdbarch *get_frame_arch (struct frame_info *this_frame); - /* Pointers to the next (down, inner) and previous (up, outer) - frame_info's in the frame cache. */ - struct frame_info *next; /* down, inner */ - struct frame_info *prev; /* up, outer */ - }; /* Values for the source flag to be used in print_frame_info_base(). */ enum print_what @@ -131,91 +490,61 @@ enum print_what #define SIZEOF_FRAME_SAVED_REGS \ (sizeof (CORE_ADDR) * (NUM_REGS+NUM_PSEUDO_REGS)) -extern void *frame_obstack_alloc (unsigned long size); -extern void frame_saved_regs_zalloc (struct frame_info *); +/* Allocate zero initialized memory from the frame cache obstack. + Appendices to the frame info (such as the unwind cache) should + allocate memory using this method. */ -/* Return the frame address from FI. Except in the machine-dependent - *FRAME* macros, a frame address has no defined meaning other than - as a magic cookie which identifies a frame over calls to the - inferior. The only known exception is inferior.h - (PC_IN_CALL_DUMMY) [ON_STACK]; see comments there. You cannot - assume that a frame address contains enough information to - reconstruct the frame; if you want more than just to identify the - frame (e.g. be able to fetch variables relative to that frame), - then save the whole struct frame_info (and the next struct - frame_info, since the latter is used for fetching variables on some - machines). */ +extern void *frame_obstack_zalloc (unsigned long size); +#define FRAME_OBSTACK_ZALLOC(TYPE) ((TYPE *) frame_obstack_zalloc (sizeof (TYPE))) +#define FRAME_OBSTACK_CALLOC(NUMBER,TYPE) ((TYPE *) frame_obstack_zalloc ((NUMBER) * sizeof (TYPE))) -#define FRAME_FP(fi) ((fi)->frame) +/* If legacy_frame_chain_valid() returns zero it means that the given + frame is the outermost one and has no caller. -/* Define a default FRAME_CHAIN_VALID, in the form that is suitable for most - targets. If FRAME_CHAIN_VALID returns zero it means that the given frame - is the outermost one and has no caller. + This method has been superseeded by the per-architecture + frame_unwind_pc() (returns 0 to indicate an invalid return address) + and per-frame this_id() (returns a NULL frame ID to indicate an + invalid frame). */ +extern int legacy_frame_chain_valid (CORE_ADDR, struct frame_info *); - XXXX - both default and alternate frame_chain_valid functions are - deprecated. New code should use dummy frames and one of the - generic functions. */ - -extern int file_frame_chain_valid (CORE_ADDR, struct frame_info *); -extern int func_frame_chain_valid (CORE_ADDR, struct frame_info *); -extern int nonnull_frame_chain_valid (CORE_ADDR, struct frame_info *); -extern int generic_file_frame_chain_valid (CORE_ADDR, struct frame_info *); -extern int generic_func_frame_chain_valid (CORE_ADDR, struct frame_info *); extern void generic_save_dummy_frame_tos (CORE_ADDR sp); -/* The stack frame that the user has specified for commands to act on. - Note that one cannot assume this is the address of valid data. */ +extern struct block *get_frame_block (struct frame_info *, + CORE_ADDR *addr_in_block); -extern struct frame_info *selected_frame; +/* Return the `struct block' that belongs to the selected thread's + selected frame. If the inferior has no state, return NULL. -/* Level of the selected frame: - 0 for innermost, 1 for its caller, ... - or -1 for frame specified by address with no defined level. */ + NOTE: cagney/2002-11-29: -extern int selected_frame_level; + No state? Does the inferior have any execution state (a core file + does, an executable does not). At present the code tests + `target_has_stack' but I'm left wondering if it should test + `target_has_registers' or, even, a merged target_has_state. -extern struct frame_info *create_new_frame (CORE_ADDR, CORE_ADDR); + Should it look at the most recently specified SAL? If the target + has no state, should this function try to extract a block from the + most recently selected SAL? That way `list foo' would give it some + sort of reference point. Then again, perhaphs that would confuse + things. -extern void flush_cached_frames (void); + Calls to this function can be broken down into two categories: Code + that uses the selected block as an additional, but optional, data + point; Code that uses the selected block as a prop, when it should + have the relevant frame/block/pc explicitly passed in. -extern void reinit_frame_cache (void); + The latter can be eliminated by correctly parameterizing the code, + the former though is more interesting. Per the "address" command, + it occures in the CLI code and makes it possible for commands to + work, even when the inferior has no state. */ - -#ifdef FRAME_FIND_SAVED_REGS -/* XXX - deprecated */ -#define FRAME_INIT_SAVED_REGS(FI) get_frame_saved_regs (FI, NULL) -extern void get_frame_saved_regs (struct frame_info *, - struct frame_saved_regs *); -#endif - -extern void set_current_frame (struct frame_info *); - -extern struct frame_info *get_prev_frame (struct frame_info *); - -extern struct frame_info *get_current_frame (void); - -extern struct frame_info *get_next_frame (struct frame_info *); - -extern struct block *get_frame_block (struct frame_info *); - -extern struct block *get_current_block (void); - -extern struct block *get_selected_block (void); +extern struct block *get_selected_block (CORE_ADDR *addr_in_block); extern struct symbol *get_frame_function (struct frame_info *); -extern CORE_ADDR get_frame_pc (struct frame_info *); - extern CORE_ADDR get_pc_function_start (CORE_ADDR); -extern struct block *block_for_pc (CORE_ADDR); - -extern struct block *block_for_pc_sect (CORE_ADDR, asection *); - -extern int frameless_look_for_prologue (struct frame_info *); - -extern void print_frame_args (struct symbol *, struct frame_info *, - int, struct ui_file *); +extern int legacy_frameless_look_for_prologue (struct frame_info *); extern struct frame_info *find_relative_frame (struct frame_info *, int *); @@ -224,49 +553,153 @@ extern void show_and_print_stack_frame (struct frame_info *fi, int level, extern void print_stack_frame (struct frame_info *, int, int); -extern void print_only_stack_frame (struct frame_info *, int, int); - extern void show_stack_frame (struct frame_info *); -extern void select_frame (struct frame_info *, int); - -extern void record_selected_frame (CORE_ADDR *, int *); - -extern void select_and_print_frame (struct frame_info *, int); - extern void print_frame_info (struct frame_info *, int, int, int); extern void show_frame_info (struct frame_info *, int, int, int); -extern CORE_ADDR find_saved_register (struct frame_info *, int); - extern struct frame_info *block_innermost_frame (struct block *); -extern struct frame_info *find_frame_addr_in_frame_chain (CORE_ADDR); - -extern CORE_ADDR sigtramp_saved_pc (struct frame_info *); - -extern CORE_ADDR generic_read_register_dummy (CORE_ADDR pc, - CORE_ADDR fp, int); +/* NOTE: cagney/2002-09-13: There is no need for this function. */ +extern CORE_ADDR deprecated_read_register_dummy (CORE_ADDR pc, + CORE_ADDR fp, int); extern void generic_push_dummy_frame (void); extern void generic_pop_current_frame (void (*)(struct frame_info *)); extern void generic_pop_dummy_frame (void); extern int generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp); -extern char *generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp); -extern void generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, - int nargs, struct value **args, - struct type *type, int gcc_p); +/* NOTE: cagney/2002-06-26: Targets should no longer use this + function. Instead, the contents of a dummy frames registers can be + obtained by applying: frame_register_unwind to the dummy frame; or + frame_register_unwind() to the next outer frame. */ -extern void generic_get_saved_register (char *, int *, CORE_ADDR *, - struct frame_info *, int, - enum lval_type *); +extern char *deprecated_generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp); -extern void get_saved_register (char *raw_buffer, int *optimized, - CORE_ADDR * addrp, - struct frame_info *frame, - int regnum, enum lval_type *lval); + +/* The DEPRECATED_GET_SAVED_REGISTER architecture interface is + entirely redundant. New architectures should implement per-frame + unwinders (ref "frame-unwind.h"). */ +extern void deprecated_generic_get_saved_register (char *, int *, CORE_ADDR *, + struct frame_info *, int, + enum lval_type *); + +extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi); + +/* FIXME: cagney/2003-02-02: Should be deprecated or replaced with a + function called get_frame_register_p(). This slightly weird (and + older) variant of get_frame_register() returns zero (indicating the + register is unavailable) if either: the register isn't cached; or + the register has been optimized out. Problem is, neither check is + exactly correct. A register can't be optimized out (it may not + have been saved as part of a function call); The fact that a + register isn't in the register cache doesn't mean that the register + isn't available (it could have been fetched from memory). */ + +extern int frame_register_read (struct frame_info *frame, int regnum, + void *buf); + +/* From stack.c. */ +extern void args_info (char *, int); + +extern void locals_info (char *, int); + +extern void (*selected_frame_level_changed_hook) (int); + +extern void return_command (char *, int); + + +/* NOTE: cagney/2002-11-27: + + You might think that the below global can simply be replaced by a + call to either get_selected_frame() or select_frame(). + + Unfortunately, it isn't that easy. + + The relevant code needs to be audited to determine if it is + possible (or pratical) to instead pass the applicable frame in as a + parameter. For instance, DEPRECATED_DO_REGISTERS_INFO() relied on + the deprecated_selected_frame global, while its replacement, + PRINT_REGISTERS_INFO(), is parameterized with the selected frame. + The only real exceptions occure at the edge (in the CLI code) where + user commands need to pick up the selected frame before proceeding. + + This is important. GDB is trying to stamp out the hack: + + saved_frame = deprecated_selected_frame; + deprecated_selected_frame = ...; + hack_using_global_selected_frame (); + deprecated_selected_frame = saved_frame; + + Take care! */ + +extern struct frame_info *deprecated_selected_frame; + +/* NOTE: drow/2003-09-06: + + This function is "a step sideways" for uses of deprecated_selected_frame. + They should be fixed as above, but meanwhile, we needed a solution for + cases where functions are called with a NULL frame meaning either "the + program is not running" or "use the selected frame". Lazy building of + deprecated_selected_frame confuses the situation, because now + deprecated_selected_frame can be NULL even when the inferior is running. + + This function calls get_selected_frame if the inferior should have a + frame, or returns NULL otherwise. */ + +extern struct frame_info *deprecated_safe_get_selected_frame (void); + +/* Create a frame using the specified BASE and PC. */ + +extern struct frame_info *create_new_frame (CORE_ADDR base, CORE_ADDR pc); + + +/* Create/access the frame's `extra info'. The extra info is used by + older code to store information such as the analyzed prologue. The + zalloc() should only be called by the INIT_EXTRA_INFO method. */ + +extern struct frame_extra_info *frame_extra_info_zalloc (struct frame_info *fi, + long size); +extern struct frame_extra_info *get_frame_extra_info (struct frame_info *fi); + +/* Create/access the frame's `saved_regs'. The saved regs are used by + older code to store the address of each register (except for + SP_REGNUM where the value of the register in the previous frame is + stored). */ +extern CORE_ADDR *frame_saved_regs_zalloc (struct frame_info *); +extern CORE_ADDR *deprecated_get_frame_saved_regs (struct frame_info *); + +/* FIXME: cagney/2002-12-06: Has the PC in the current frame changed? + "infrun.c", Thanks to DECR_PC_AFTER_BREAK, can change the PC after + the initial frame create. This puts things back in sync. + + This replaced: frame->pc = ....; */ +extern void deprecated_update_frame_pc_hack (struct frame_info *frame, + CORE_ADDR pc); + +/* FIXME: cagney/2002-12-18: Has the frame's base changed? Or to be + more exact, was that initial guess at the frame's base as returned + by deprecated_read_fp() wrong? If it was, fix it. This shouldn't + be necessary since the code should be getting the frame's base + correct from the outset. + + This replaced: frame->frame = ....; */ +extern void deprecated_update_frame_base_hack (struct frame_info *frame, + CORE_ADDR base); + +/* FIXME: cagney/2003-01-05: Allocate a frame, along with the + saved_regs and extra_info. Set up cleanups for all three. Same as + for deprecated_frame_xmalloc, targets are calling this when + creating a scratch `struct frame_info'. The frame overhaul makes + this unnecessary since all frame queries are parameterized with a + common cache parameter and a frame. */ +extern struct frame_info *deprecated_frame_xmalloc_with_cleanup (long sizeof_saved_regs, + long sizeof_extra_info); + +/* Return non-zero if the architecture is relying on legacy frame + code. */ +extern int legacy_frame_p (struct gdbarch *gdbarch); #endif /* !defined (FRAME_H) */ diff --git a/contrib/gdb/gdb/gcore.c b/contrib/gdb/gdb/gcore.c index 494efad4608..b5513728ef5 100644 --- a/contrib/gdb/gdb/gcore.c +++ b/contrib/gdb/gdb/gcore.c @@ -1,5 +1,6 @@ /* Generate a core file for the inferior process. - Copyright 2001, 2002 Free Software Foundation, Inc. + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -19,21 +20,23 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "cli/cli-decode.h" +#include "elf-bfd.h" +#include "infcall.h" #include "inferior.h" #include "gdbcore.h" -#include "elf-bfd.h" -#include -#include "symfile.h" #include "objfiles.h" +#include "symfile.h" -static char *default_gcore_target (void); -static enum bfd_architecture default_gcore_arch (void); -static unsigned long default_gcore_mach (void); -static int gcore_memory_sections (bfd *); +#include "cli/cli-decode.h" -/* Function: gcore_command - Generate a core file from the inferior process. */ +#include "gdb_assert.h" + +static char *default_gcore_target (void); +static enum bfd_architecture default_gcore_arch (void); +static unsigned long default_gcore_mach (void); +static int gcore_memory_sections (bfd *); + +/* Generate a core file from the inferior process. */ static void gcore_command (char *args, int from_tty) @@ -46,7 +49,7 @@ gcore_command (char *args, int from_tty) int note_size = 0; /* No use generating a corefile without a target process. */ - if (!(target_has_execution)) + if (!target_has_execution) noprocess (); if (args && *args) @@ -59,57 +62,53 @@ gcore_command (char *args, int from_tty) } if (info_verbose) - fprintf_filtered (gdb_stdout, + fprintf_filtered (gdb_stdout, "Opening corefile '%s' for output.\n", corefilename); - /* Open the output file. */ - if (!(obfd = bfd_openw (corefilename, default_gcore_target ()))) - { - error ("Failed to open '%s' for output.", corefilename); - } + /* Open the output file. */ + obfd = bfd_openw (corefilename, default_gcore_target ()); + if (!obfd) + error ("Failed to open '%s' for output.", corefilename); - /* Need a cleanup that will close the file (FIXME: delete it?). */ + /* Need a cleanup that will close the file (FIXME: delete it?). */ old_chain = make_cleanup_bfd_close (obfd); bfd_set_format (obfd, bfd_core); bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ()); - /* An external target method must build the notes section. */ - note_data = (char *) target_make_corefile_notes (obfd, ¬e_size); + /* An external target method must build the notes section. */ + note_data = target_make_corefile_notes (obfd, ¬e_size); - /* Create the note section. */ + /* Create the note section. */ if (note_data != NULL && note_size != 0) { - if ((note_sec = bfd_make_section_anyway (obfd, "note0")) == NULL) - error ("Failed to create 'note' section for corefile: %s", + note_sec = bfd_make_section_anyway (obfd, "note0"); + if (note_sec == NULL) + error ("Failed to create 'note' section for corefile: %s", bfd_errmsg (bfd_get_error ())); bfd_set_section_vma (obfd, note_sec, 0); - bfd_set_section_flags (obfd, note_sec, + bfd_set_section_flags (obfd, note_sec, SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC); bfd_set_section_alignment (obfd, note_sec, 0); bfd_set_section_size (obfd, note_sec, note_size); } - /* Now create the memory/load sections. */ + /* Now create the memory/load sections. */ if (gcore_memory_sections (obfd) == 0) error ("gcore: failed to get corefile memory sections from target."); - /* Write out the contents of the note section. */ + /* Write out the contents of the note section. */ if (note_data != NULL && note_size != 0) { if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size)) - { - warning ("writing note section (%s)", - bfd_errmsg (bfd_get_error ())); - } + warning ("writing note section (%s)", bfd_errmsg (bfd_get_error ())); } - /* Succeeded. */ - fprintf_filtered (gdb_stdout, - "Saved corefile %s\n", corefilename); + /* Succeeded. */ + fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename); - /* Clean-ups will close the output file and free malloc memory. */ + /* Clean-ups will close the output file and free malloc memory. */ do_cleanups (old_chain); return; } @@ -117,11 +116,11 @@ gcore_command (char *args, int from_tty) static unsigned long default_gcore_mach (void) { -#if 1 /* See if this even matters... */ +#if 1 /* See if this even matters... */ return 0; #else #ifdef TARGET_ARCHITECTURE - const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE; + const struct bfd_arch_info *bfdarch = TARGET_ARCHITECTURE; if (bfdarch != NULL) return bfdarch->mach; @@ -151,100 +150,67 @@ default_gcore_arch (void) static char * default_gcore_target (void) { - /* FIXME -- this may only work for ELF targets. */ + /* FIXME: This may only work for ELF targets. */ if (exec_bfd == NULL) return NULL; else return bfd_get_target (exec_bfd); } -/* - * Default method for stack segment (preemptable by target). - */ +/* Derive a reasonable stack segment by unwinding the target stack, + and store its limits in *BOTTOM and *TOP. Return non-zero if + successful. */ -static int (*override_derive_stack_segment) (bfd_vma *, bfd_vma *); - -extern void -preempt_derive_stack_segment (int (*override_func) (bfd_vma *, bfd_vma *)) +static int +derive_stack_segment (bfd_vma *bottom, bfd_vma *top) { - override_derive_stack_segment = override_func; -} - -/* Function: default_derive_stack_segment - Derive a reasonable stack segment by unwinding the target stack. - - Returns 0 for failure, 1 for success. */ - -static int -default_derive_stack_segment (bfd_vma *bottom, bfd_vma *top) -{ - bfd_vma tmp_vma; struct frame_info *fi, *tmp_fi; - if (bottom == NULL || top == NULL) - return 0; /* Paranoia. */ + gdb_assert (bottom); + gdb_assert (top); + /* Can't succeed without stack and registers. */ if (!target_has_stack || !target_has_registers) - return 0; /* Can't succeed without stack and registers. */ + return 0; - if ((fi = get_current_frame ()) == NULL) - return 0; /* Can't succeed without current frame. */ + /* Can't succeed without current frame. */ + fi = get_current_frame (); + if (fi == NULL) + return 0; - /* Save frame pointer of TOS frame. */ - *top = fi->frame; - /* If current stack pointer is more "inner", use that instead. */ + /* Save frame pointer of TOS frame. */ + *top = get_frame_base (fi); + /* If current stack pointer is more "inner", use that instead. */ if (INNER_THAN (read_sp (), *top)) *top = read_sp (); - /* Find prev-most frame. */ + /* Find prev-most frame. */ while ((tmp_fi = get_prev_frame (fi)) != NULL) fi = tmp_fi; - /* Save frame pointer of prev-most frame. */ - *bottom = fi->frame; + /* Save frame pointer of prev-most frame. */ + *bottom = get_frame_base (fi); - /* Now canonicalize their order, so that 'bottom' is a lower address - (as opposed to a lower stack frame). */ + /* Now canonicalize their order, so that BOTTOM is a lower address + (as opposed to a lower stack frame). */ if (*bottom > *top) { + bfd_vma tmp_vma; + tmp_vma = *top; *top = *bottom; *bottom = tmp_vma; } - return 1; /* success */ + return 1; } +/* Derive a reasonable heap segment for ABFD by looking at sbrk and + the static data sections. Store its limits in *BOTTOM and *TOP. + Return non-zero if successful. */ + static int -derive_stack_segment (bfd_vma *bottom, bfd_vma *top) -{ - if (override_derive_stack_segment) - return override_derive_stack_segment (bottom, top); - else - return default_derive_stack_segment (bottom, top); -} - -/* - * Default method for heap segment (preemptable by target). - */ - -static int (*override_derive_heap_segment) (bfd *, bfd_vma *, bfd_vma *); - -extern void -preempt_derive_heap_segment (int (*override_func) (bfd *, - bfd_vma *, bfd_vma *)) -{ - override_derive_heap_segment = override_func; -} - -/* Function: default_derive_heap_segment - Derive a reasonable heap segment by looking at sbrk and - the static data sections. - - Returns 0 for failure, 1 for success. */ - -static int -default_derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) +derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) { bfd_vma top_of_data_memory = 0; bfd_vma top_of_heap = 0; @@ -253,23 +219,29 @@ default_derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) bfd_vma sec_vaddr; asection *sec; - if (bottom == NULL || top == NULL) - return 0; /* Paranoia. */ + gdb_assert (bottom); + gdb_assert (top); + /* This function depends on being able to call a function in the + inferior. */ if (!target_has_execution) - return 0; /* This function depends on being able - to call a function in the inferior. */ + return 0; - /* Assumption: link map is arranged as follows (low to high addresses): - text sections - data sections (including bss) - heap - */ + /* The following code assumes that the link map is arranged as + follows (low to high addresses): + + --------------------------------- + | text sections | + --------------------------------- + | data sections (including bss) | + --------------------------------- + | heap | + --------------------------------- */ for (sec = abfd->sections; sec; sec = sec->next) { - if (bfd_get_section_flags (abfd, sec) & SEC_DATA || - strcmp (".bss", bfd_get_section_name (abfd, sec)) == 0) + if (bfd_get_section_flags (abfd, sec) & SEC_DATA + || strcmp (".bss", bfd_section_name (abfd, sec)) == 0) { sec_vaddr = bfd_get_section_vma (abfd, sec); sec_size = bfd_get_section_size_before_reloc (sec); @@ -277,36 +249,42 @@ default_derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) top_of_data_memory = sec_vaddr + sec_size; } } + /* Now get the top-of-heap by calling sbrk in the inferior. */ - if ((sbrk = find_function_in_inferior ("sbrk")) == NULL) + if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL) + { + sbrk = find_function_in_inferior ("sbrk"); + if (sbrk == NULL) + return 0; + } + else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL) + { + sbrk = find_function_in_inferior ("_sbrk"); + if (sbrk == NULL) + return 0; + } + else return 0; - if ((zero = value_from_longest (builtin_type_int, (LONGEST) 0)) == NULL) - return 0; - if ((sbrk = call_function_by_hand (sbrk, 1, &zero)) == NULL) + + zero = value_from_longest (builtin_type_int, 0); + gdb_assert (zero); + sbrk = call_function_by_hand (sbrk, 1, &zero); + if (sbrk == NULL) return 0; top_of_heap = value_as_long (sbrk); - /* Return results. */ + /* Return results. */ if (top_of_heap > top_of_data_memory) { *bottom = top_of_data_memory; *top = top_of_heap; - return 1; /* success */ + return 1; } - else - return 0; /* No additional heap space needs to be saved. */ + + /* No additional heap space needs to be saved. */ + return 0; } -static int -derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top) -{ - if (override_derive_heap_segment) - return override_derive_heap_segment (abfd, bottom, top); - else - return default_derive_heap_segment (abfd, bottom, top); -} - -/* ARGSUSED */ static void make_output_phdrs (bfd *obfd, asection *osec, void *ignored) { @@ -314,7 +292,7 @@ make_output_phdrs (bfd *obfd, asection *osec, void *ignored) int p_type; /* FIXME: these constants may only be applicable for ELF. */ - if (strncmp (osec->name, "load", 4) == 0) + if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0) p_type = PT_LOAD; else p_type = PT_NOTE; @@ -325,81 +303,103 @@ make_output_phdrs (bfd *obfd, asection *osec, void *ignored) if (bfd_get_section_flags (obfd, osec) & SEC_CODE) p_flags |= PF_X; /* Segment is executable. */ - bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, - 0, 0, 1, &osec); + bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec); } -static asection * -make_mem_sec (bfd *obfd, - bfd_vma addr, - bfd_size_type size, - unsigned int flags, - unsigned int alignment) +static int +gcore_create_callback (CORE_ADDR vaddr, unsigned long size, + int read, int write, int exec, void *data) { + bfd *obfd = data; asection *osec; + flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD; - if ((osec = bfd_make_section_anyway (obfd, "load")) == NULL) + /* If the memory segment has no permissions set, ignore it, otherwise + when we later try to access it for read/write, we'll get an error + or jam the kernel. */ + if (read == 0 && write == 0 && exec == 0) + { + if (info_verbose) + { + fprintf_filtered (gdb_stdout, "Ignore segment, %s bytes at 0x%s\n", + paddr_d (size), paddr_nz (vaddr)); + } + + return 0; + } + + if (write == 0) + { + /* See if this region of memory lies inside a known file on disk. + If so, we can avoid copying its contents by clearing SEC_LOAD. */ + struct objfile *objfile; + struct obj_section *objsec; + + ALL_OBJSECTIONS (objfile, objsec) + { + bfd *abfd = objfile->obfd; + asection *asec = objsec->the_bfd_section; + bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd, + asec); + bfd_vma start = objsec->addr & -align; + bfd_vma end = (objsec->endaddr + align - 1) & -align; + /* Match if either the entire memory region lies inside the + section (i.e. a mapping covering some pages of a large + segment) or the entire section lies inside the memory region + (i.e. a mapping covering multiple small sections). + + This BFD was synthesized from reading target memory, + we don't want to omit that. */ + if (((vaddr >= start && vaddr + size <= end) + || (start >= vaddr && end <= vaddr + size)) + && !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY)) + { + flags &= ~SEC_LOAD; + goto keep; /* break out of two nested for loops */ + } + } + + keep: + flags |= SEC_READONLY; + } + + if (exec) + flags |= SEC_CODE; + else + flags |= SEC_DATA; + + osec = bfd_make_section_anyway (obfd, "load"); + if (osec == NULL) { warning ("Couldn't make gcore segment: %s", bfd_errmsg (bfd_get_error ())); - return NULL; + return 1; } if (info_verbose) { - fprintf_filtered (gdb_stdout, - "Save segment, %lld bytes at 0x%s\n", - (long long) size, paddr_nz (addr)); + fprintf_filtered (gdb_stdout, "Save segment, %s bytes at 0x%s\n", + paddr_d (size), paddr_nz (vaddr)); } bfd_set_section_size (obfd, osec, size); - bfd_set_section_vma (obfd, osec, addr); - osec->lma = 0; /* FIXME: there should be a macro for this! */ - bfd_set_section_alignment (obfd, osec, alignment); - bfd_set_section_flags (obfd, osec, - flags | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS); - return osec; + bfd_set_section_vma (obfd, osec, vaddr); + bfd_section_lma (obfd, osec) = 0; /* ??? bfd_set_section_lma? */ + bfd_set_section_flags (obfd, osec, flags); + return 0; } static int -gcore_create_callback (CORE_ADDR vaddr, - unsigned long size, - int read, int write, int exec, - void *data) -{ - flagword flags = 0; - - if (write == 0) - { - flags |= SEC_READONLY; - /* Set size == zero for readonly sections. */ - size = 0; - } - if (exec) - { - flags |= SEC_CODE; - } - else - { - flags |= SEC_DATA; - } - - return ((make_mem_sec ((bfd *) data, vaddr, size, flags, 0)) == NULL); -} - -static int -objfile_find_memory_regions (int (*func) (CORE_ADDR, - unsigned long, - int, int, int, - void *), +objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long, + int, int, int, void *), void *obfd) { - /* Use objfile data to create memory sections. */ + /* Use objfile data to create memory sections. */ struct objfile *objfile; struct obj_section *objsec; bfd_vma temp_bottom, temp_top; - /* Call callback function for each objfile section. */ + /* Call callback function for each objfile section. */ ALL_OBJSECTIONS (objfile, objsec) { bfd *ibfd = objfile->obfd; @@ -412,33 +412,32 @@ objfile_find_memory_regions (int (*func) (CORE_ADDR, int size = bfd_section_size (ibfd, isec); int ret; - if ((ret = (*func) (objsec->addr, - bfd_section_size (ibfd, isec), - 1, /* All sections will be readable. */ - (flags & SEC_READONLY) == 0, /* writable */ - (flags & SEC_CODE) != 0, /* executable */ - obfd)) != 0) + ret = (*func) (objsec->addr, bfd_section_size (ibfd, isec), + 1, /* All sections will be readable. */ + (flags & SEC_READONLY) == 0, /* Writable. */ + (flags & SEC_CODE) != 0, /* Executable. */ + obfd); + if (ret != 0) return ret; } } - /* Make a stack segment. */ + /* Make a stack segment. */ if (derive_stack_segment (&temp_bottom, &temp_top)) - (*func) (temp_bottom, - temp_top - temp_bottom, - 1, /* Stack section will be readable */ - 1, /* Stack section will be writable */ - 0, /* Stack section will not be executable */ + (*func) (temp_bottom, temp_top - temp_bottom, + 1, /* Stack section will be readable. */ + 1, /* Stack section will be writable. */ + 0, /* Stack section will not be executable. */ obfd); /* Make a heap segment. */ if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top)) - (*func) (temp_bottom, - temp_top - temp_bottom, - 1, /* Heap section will be readable */ - 1, /* Heap section will be writable */ - 0, /* Heap section will not be executable */ + (*func) (temp_bottom, temp_top - temp_bottom, + 1, /* Heap section will be readable. */ + 1, /* Heap section will be writable. */ + 0, /* Heap section will not be executable. */ obfd); + return 0; } @@ -449,47 +448,52 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored) struct cleanup *old_chain = NULL; void *memhunk; - if (size == 0) - return; /* Read-only sections are marked as zero-size. - We don't have to copy their contents. */ - if (strncmp ("load", bfd_get_section_name (obfd, osec), 4) != 0) - return; /* Only interested in "load" sections. */ + /* Read-only sections are marked; we don't have to copy their contents. */ + if ((bfd_get_section_flags (obfd, osec) & SEC_LOAD) == 0) + return; - if ((memhunk = xmalloc (size)) == NULL) + /* Only interested in "load" sections. */ + if (strncmp ("load", bfd_section_name (obfd, osec), 4) != 0) + return; + + memhunk = xmalloc (size); + /* ??? This is crap since xmalloc should never return NULL. */ + if (memhunk == NULL) error ("Not enough memory to create corefile."); old_chain = make_cleanup (xfree, memhunk); - if (target_read_memory (bfd_section_vma (obfd, osec), + if (target_read_memory (bfd_section_vma (obfd, osec), memhunk, size) != 0) - warning ("Memory read failed for corefile section, %ld bytes at 0x%s\n", - (long) size, paddr (bfd_section_vma (obfd, osec))); + warning ("Memory read failed for corefile section, %s bytes at 0x%s\n", + paddr_d (size), paddr (bfd_section_vma (obfd, osec))); if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size)) - warning ("Failed to write corefile contents (%s).", + warning ("Failed to write corefile contents (%s).", bfd_errmsg (bfd_get_error ())); - do_cleanups (old_chain); /* frees the xmalloc buffer */ + do_cleanups (old_chain); /* Frees MEMHUNK. */ } static int gcore_memory_sections (bfd *obfd) { if (target_find_memory_regions (gcore_create_callback, obfd) != 0) - return 0; /* FIXME error return/msg? */ + return 0; /* FIXME: error return/msg? */ - /* Record phdrs for section-to-segment mapping. */ + /* Record phdrs for section-to-segment mapping. */ bfd_map_over_sections (obfd, make_output_phdrs, NULL); - /* Copy memory region contents. */ + /* Copy memory region contents. */ bfd_map_over_sections (obfd, gcore_copy_callback, NULL); - return 1; /* success */ + return 1; } void _initialize_gcore (void) { add_com ("generate-core-file", class_files, gcore_command, - "Save a core file with the current state of the debugged process.\n\ + "\ +Save a core file with the current state of the debugged process.\n\ Argument is optional filename. Default filename is 'core.'."); add_com_alias ("gcore", "generate-core-file", class_files, 1); diff --git a/contrib/gdb/gdb/gdb-events.c b/contrib/gdb/gdb/gdb-events.c index 0fbb3bab798..63ee3bc400b 100644 --- a/contrib/gdb/gdb/gdb-events.c +++ b/contrib/gdb/gdb/gdb-events.c @@ -1,5 +1,6 @@ /* User Interface Events. - Copyright 1999, 2001 Free Software Foundation, Inc. + + Copyright 1999, 2001, 2002 Free Software Foundation, Inc. Contributed by Cygnus Solutions. @@ -38,9 +39,6 @@ #include "gdb-events.h" #include "gdbcmd.h" -#undef XMALLOC -#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) - #if WITH_GDB_EVENTS static struct gdb_events null_event_hooks; static struct gdb_events queue_event_hooks; @@ -121,6 +119,36 @@ architecture_changed_event (void) current_event_hooks->architecture_changed (); } +void +target_changed_event (void) +{ + if (gdb_events_debug) + fprintf_unfiltered (gdb_stdlog, "target_changed_event\n"); + if (!current_event_hooks->target_changed) + return; + current_event_hooks->target_changed (); +} + +void +selected_frame_level_changed_event (int level) +{ + if (gdb_events_debug) + fprintf_unfiltered (gdb_stdlog, "selected_frame_level_changed_event\n"); + if (!current_event_hooks->selected_frame_level_changed) + return; + current_event_hooks->selected_frame_level_changed (level); +} + +void +selected_thread_changed_event (int thread_num) +{ + if (gdb_events_debug) + fprintf_unfiltered (gdb_stdlog, "selected_thread_changed_event\n"); + if (!current_event_hooks->selected_thread_changed) + return; + current_event_hooks->selected_thread_changed (thread_num); +} + #endif #if WITH_GDB_EVENTS @@ -136,6 +164,14 @@ set_gdb_event_hooks (struct gdb_events *vector) } #endif +#if WITH_GDB_EVENTS +void +clear_gdb_event_hooks (void) +{ + set_gdb_event_hooks (&null_event_hooks); +} +#endif + enum gdb_event { breakpoint_create, @@ -145,6 +181,9 @@ enum gdb_event tracepoint_delete, tracepoint_modify, architecture_changed, + target_changed, + selected_frame_level_changed, + selected_thread_changed, nr_gdb_events }; @@ -178,6 +217,16 @@ struct tracepoint_modify int number; }; +struct selected_frame_level_changed + { + int level; + }; + +struct selected_thread_changed + { + int thread_num; + }; + struct event { enum gdb_event type; @@ -190,6 +239,8 @@ struct event struct tracepoint_create tracepoint_create; struct tracepoint_delete tracepoint_delete; struct tracepoint_modify tracepoint_modify; + struct selected_frame_level_changed selected_frame_level_changed; + struct selected_thread_changed selected_thread_changed; } data; }; @@ -268,6 +319,32 @@ queue_architecture_changed (void) append (event); } +static void +queue_target_changed (void) +{ + struct event *event = XMALLOC (struct event); + event->type = target_changed; + append (event); +} + +static void +queue_selected_frame_level_changed (int level) +{ + struct event *event = XMALLOC (struct event); + event->type = selected_frame_level_changed; + event->data.selected_frame_level_changed.level = level; + append (event); +} + +static void +queue_selected_thread_changed (int thread_num) +{ + struct event *event = XMALLOC (struct event); + event->type = selected_thread_changed; + event->data.selected_thread_changed.thread_num = thread_num; + append (event); +} + void gdb_events_deliver (struct gdb_events *vector) { @@ -316,6 +393,17 @@ gdb_events_deliver (struct gdb_events *vector) case architecture_changed: vector->architecture_changed (); break; + case target_changed: + vector->target_changed (); + break; + case selected_frame_level_changed: + vector->selected_frame_level_changed + (event->data.selected_frame_level_changed.level); + break; + case selected_thread_changed: + vector->selected_thread_changed + (event->data.selected_thread_changed.thread_num); + break; } delivering_events = event->next; xfree (event); @@ -335,6 +423,9 @@ _initialize_gdb_events (void) queue_event_hooks.tracepoint_delete = queue_tracepoint_delete; queue_event_hooks.tracepoint_modify = queue_tracepoint_modify; queue_event_hooks.architecture_changed = queue_architecture_changed; + queue_event_hooks.target_changed = queue_target_changed; + queue_event_hooks.selected_frame_level_changed = queue_selected_frame_level_changed; + queue_event_hooks.selected_thread_changed = queue_selected_thread_changed; #endif c = add_set_cmd ("eventdebug", class_maintenance, var_zinteger, diff --git a/contrib/gdb/gdb/gdb-events.h b/contrib/gdb/gdb/gdb-events.h index 18a4a2018c2..2ce193f19ea 100644 --- a/contrib/gdb/gdb/gdb-events.h +++ b/contrib/gdb/gdb/gdb-events.h @@ -1,5 +1,6 @@ /* User Interface Events. - Copyright 1999, 2001 Free Software Foundation, Inc. + + Copyright 1999, 2001, 2002, 2004 Free Software Foundation, Inc. Contributed by Cygnus Solutions. @@ -58,6 +59,9 @@ typedef void (gdb_events_tracepoint_create_ftype) (int number); typedef void (gdb_events_tracepoint_delete_ftype) (int number); typedef void (gdb_events_tracepoint_modify_ftype) (int number); typedef void (gdb_events_architecture_changed_ftype) (void); +typedef void (gdb_events_target_changed_ftype) (void); +typedef void (gdb_events_selected_frame_level_changed_ftype) (int level); +typedef void (gdb_events_selected_thread_changed_ftype) (int thread_num); /* gdb-events: object. */ @@ -71,6 +75,9 @@ struct gdb_events gdb_events_tracepoint_delete_ftype *tracepoint_delete; gdb_events_tracepoint_modify_ftype *tracepoint_modify; gdb_events_architecture_changed_ftype *architecture_changed; + gdb_events_target_changed_ftype *target_changed; + gdb_events_selected_frame_level_changed_ftype *selected_frame_level_changed; + gdb_events_selected_thread_changed_ftype *selected_thread_changed; }; @@ -84,9 +91,12 @@ extern void tracepoint_create_event (int number); extern void tracepoint_delete_event (int number); extern void tracepoint_modify_event (int number); extern void architecture_changed_event (void); +extern void target_changed_event (void); +extern void selected_frame_level_changed_event (int level); +extern void selected_thread_changed_event (int thread_num); -/* When GDB_EVENTS are not being used, completly disable them. */ +/* When GDB_EVENTS are not being used, completely disable them. */ #if !WITH_GDB_EVENTS #define breakpoint_create_event(b) 0 @@ -96,6 +106,9 @@ extern void architecture_changed_event (void); #define tracepoint_delete_event(number) 0 #define tracepoint_modify_event(number) 0 #define architecture_changed_event() 0 +#define target_changed_event() 0 +#define selected_frame_level_changed_event(level) 0 +#define selected_thread_changed_event(thread_num) 0 #endif /* Install custom gdb-events hooks. */ @@ -104,6 +117,9 @@ extern struct gdb_events *set_gdb_event_hooks (struct gdb_events *vector); /* Deliver any pending events. */ extern void gdb_events_deliver (struct gdb_events *vector); +/* Clear event handlers */ +extern void clear_gdb_event_hooks (void); + #if !WITH_GDB_EVENTS #define set_gdb_events(x) 0 #define set_gdb_event_hooks(x) 0 diff --git a/contrib/gdb/gdb/gdb-events.sh b/contrib/gdb/gdb/gdb-events.sh index eb7346551a0..bd0779404cd 100755 --- a/contrib/gdb/gdb/gdb-events.sh +++ b/contrib/gdb/gdb/gdb-events.sh @@ -1,7 +1,7 @@ #!/bin/sh # User Interface Events. -# Copyright 1999, 2000, 2001 Free Software Foundation, Inc. +# Copyright 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. # # Contributed by Cygnus Solutions. # @@ -65,6 +65,9 @@ f:void:tracepoint_create:int number:number f:void:tracepoint_delete:int number:number f:void:tracepoint_modify:int number:number f:void:architecture_changed:void +f:void:target_changed:void +f:void:selected_frame_level_changed:int level:level +f:void:selected_thread_changed:int thread_num:thread_num #*:void:annotate_starting_hook:void #*:void:annotate_stopped_hook:void #*:void:annotate_signalled_hook:void @@ -87,9 +90,6 @@ f:void:architecture_changed:void #*:void:readline_begin_hook:char *format, ...:format #*:char *:readline_hook:char *prompt:prompt #*:void:readline_end_hook:void -#*:void:register_changed_hook:int regno:regno -#*:void:memory_changed_hook:CORE_ADDR addr, int len:addr, len -#*:void:context_hook:int num:num #*:int:target_wait_hook:int pid, struct target_waitstatus *status:pid, status #*:void:call_command_hook:struct cmd_list_element *c, char *cmd, int from_tty:c, cmd, from_tty #*:NORETURN void:error_hook:void:: ATTR_NORETURN @@ -113,7 +113,8 @@ copyright () { cat <sym_stab_info) @@ -83,5 +85,6 @@ struct dbx_symfile_info #define DBX_TEXT_SECTION(o) (DBX_SYMFILE_INFO(o)->text_section) #define DBX_DATA_SECTION(o) (DBX_SYMFILE_INFO(o)->data_section) #define DBX_BSS_SECTION(o) (DBX_SYMFILE_INFO(o)->bss_section) +#define DBX_STAB_SECTION(o) (DBX_SYMFILE_INFO(o)->stab_section) #endif /* GDBSTABS_H */ diff --git a/contrib/gdb/gdb/gdb.1 b/contrib/gdb/gdb/gdb.1 index 55272c689d5..dbe3178f7d1 100644 --- a/contrib/gdb/gdb/gdb.1 +++ b/contrib/gdb/gdb/gdb.1 @@ -1,7 +1,7 @@ .\" Copyright 1991, 1999 Free Software Foundation, Inc. .\" See section COPYING for conditions for redistribution .\" $Id: gdb.1,v 1.4 1999/01/05 00:50:50 jsm Exp $ -.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools" +.TH gdb 1 "22may2002" "GNU Tools" "GNU Tools" .SH NAME gdb \- The GNU Debugger .SH SYNOPSIS @@ -150,6 +150,12 @@ Execute next program line (after stopping); step \c \& any function calls in the line. .TP +.B edit \fR[\|\fIfile\fB:\fR\|]\fIfunction +look at the program line where it is presently stopped. +.TP +.B list \fR[\|\fIfile\fB:\fR\|]\fIfunction +type the text of the program in the vicinity of where it is presently stopped. +.TP .B step Execute next program line (after stopping); step \c .I into\c diff --git a/contrib/gdb/gdb/gdb.c b/contrib/gdb/gdb/gdb.c new file mode 100644 index 00000000000..b6eae2b59bd --- /dev/null +++ b/contrib/gdb/gdb/gdb.c @@ -0,0 +1,36 @@ +/* Main function for CLI gdb. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "main.h" +#include "gdb_string.h" +#include "interps.h" + +int +main (int argc, char **argv) +{ + struct captured_main_args args; + memset (&args, 0, sizeof args); + args.argc = argc; + args.argv = argv; + args.use_windows = 0; + args.interpreter_p = INTERP_CONSOLE; + return gdb_main (&args); +} diff --git a/contrib/gdb/gdb/gdb.h b/contrib/gdb/gdb/gdb.h index 737ac82edfe..6a2eaa0ca12 100644 --- a/contrib/gdb/gdb/gdb.h +++ b/contrib/gdb/gdb/gdb.h @@ -22,6 +22,8 @@ #ifndef GDB_H #define GDB_H +struct ui_out; + /* Return-code (RC) from a gdb library call. (The abreviation RC is taken from the sim/common directory.) */ diff --git a/contrib/gdb/gdb/gdb_assert.h b/contrib/gdb/gdb/gdb_assert.h index 4f0bcdc9497..9cad74c9cbc 100644 --- a/contrib/gdb/gdb/gdb_assert.h +++ b/contrib/gdb/gdb/gdb_assert.h @@ -40,16 +40,19 @@ #else #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L #define ASSERT_FUNCTION __func__ -#else -#define ASSERT_FUNCTION ((const char *) 0) #endif #endif /* This prints an "Assertion failed" message, aksing the user if they want to continue, dump core, or just exit. */ +#if defined (ASSERT_FUNCTION) #define gdb_assert_fail(assertion, file, line, function) \ - internal_error (file, line, "%s%sAssertion `%s' failed.", \ - function ? function : "", function ? ": " : "", \ + internal_error (file, line, "%s: Assertion `%s' failed.", \ + function, assertion) +#else +#define gdb_assert_fail(assertion, file, line, function) \ + internal_error (file, line, "Assertion `%s' failed.", \ assertion) +#endif #endif /* gdb_assert.h */ diff --git a/contrib/gdb/gdb/gdb_curses.h b/contrib/gdb/gdb/gdb_curses.h new file mode 100644 index 00000000000..074313e068d --- /dev/null +++ b/contrib/gdb/gdb/gdb_curses.h @@ -0,0 +1,31 @@ +/* Portable . + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef GDB_CURSES_H +#define GDB_CURSES_H 1 + +#if defined (HAVE_NCURSES_H) +#include +#elif defined (HAVE_CURSES_H) +#include +#endif + +#endif diff --git a/contrib/gdb/gdb/gdb_dirent.h b/contrib/gdb/gdb/gdb_dirent.h index 9cb40061420..ba28ca55616 100644 --- a/contrib/gdb/gdb/gdb_dirent.h +++ b/contrib/gdb/gdb/gdb_dirent.h @@ -1,5 +1,5 @@ -/* Portable - Copyright 2000 Free Software Foundation, Inc. +/* Portable . + Copyright 2000, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -18,14 +18,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined(GDB_DIRENT_H) -#define GDB_DIRENT_H - -/* From bfd/hpux-core.c. */ +#ifndef GDB_DIRENT_H +#define GDB_DIRENT_H 1 +/* See description of `AC_HEADER_DIRENT' in the Autoconf manual. */ #ifdef HAVE_DIRENT_H -# include +# include /* OK: dirent.h */ +# define NAMELEN(dirent) strlen ((dirent)->d_name) /* OK: strlen d_name */ #else +# define dirent direct +# define NAMELEN(dirent) (dirent)->d_namelen /* OK: d_namelen */ # ifdef HAVE_SYS_NDIR_H # include # endif @@ -37,4 +39,4 @@ # endif #endif -#endif /* !defined(GDB_DIRENT_H) */ +#endif /* not GDB_DIRENT_H */ diff --git a/contrib/gdb/gdb/gdb_gcore.sh b/contrib/gdb/gdb/gdb_gcore.sh new file mode 100755 index 00000000000..9b428081aed --- /dev/null +++ b/contrib/gdb/gdb/gdb_gcore.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# Copyright 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# +# gcore.sh +# Script to generate a core file of a running program. +# It starts up gdb, attaches to the given PID and invokes the gcore command. +# + +if [ "$#" -eq "0" ] +then + echo "usage: gcore [-o filename] pid" + exit 2 +fi + +# Need to check for -o option, but set default basename to "core". +name=core + +if [ "$1" = "-o" ] +then + if [ "$#" -lt "3" ] + then + # Not enough arguments. + echo "usage: gcore [-o filename] pid" + exit 2 + fi + name=$2 + + # Shift over to start of pid list + shift; shift +fi + +# Initialise return code. +rc=0 + +# Loop through pids +for pid in $* +do + # Write gdb script for pid $pid. + + # Avoid need for temporary files by using funky "here + # document" feature of sh. + + /usr/bin/gdb > /dev/null << EOF + attach $pid + gcore $name.$pid + detach + quit +EOF + + if [ -r $name.$pid ] ; then + rc=0 + else + echo gcore: failed to create $name.$pid + rc=1 + break + fi + + +done + +exit $rc + diff --git a/contrib/gdb/gdb/gdb_indent.sh b/contrib/gdb/gdb/gdb_indent.sh index e54e08eac53..b21016107ad 100755 --- a/contrib/gdb/gdb/gdb_indent.sh +++ b/contrib/gdb/gdb/gdb_indent.sh @@ -36,24 +36,48 @@ fi # Check that the indent found is both GNU and a reasonable version. # Different indent versions give different indentation. -case `${indent} --version 2>/dev/null < /dev/null` in - GNU*2.2.6 ) ;; - *GNU* ) echo "Incorrect version of GNU indent" 1>&2 ;; - * ) echo "Indent is not GNU" 1>&2 ;; -esac +m1=2 +m2=2 +m3=9 +version=`${indent} --version 2>/dev/null < /dev/null` +case "${version}" in + *GNU* ) ;; + * ) echo "error: GNU indent $m1.$m2.$m3 expected" 1>&2 ; exit 1;; +esac +v1=`echo "${version}" | sed 's/^.* \([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)$/\1/'` +v2=`echo "${version}" | sed 's/^.* \([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)$/\2/'` +v3=`echo "${version}" | sed 's/^.* \([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)$/\3/'` + +if test $m1 -ne $v1 -o $m2 -ne $v2 -o $m3 -gt $v3 +then + echo "error: Must be GNU indent version $m1.$m2.$m3 or later" 1>&2 + exit 1 +fi + +if test $m3 -ne $v3 +then + echo "warning: GNU indent version $m1.$m2.$m3 recommended" 1>&2 +fi # Check that we're in the GDB source directory case `pwd` in */gdb ) ;; + */sim/* ) ;; * ) echo "Not in GDB directory" 1>&2 ; exit 1 ;; esac # Run indent per GDB specs -types="-T FILE `cat *.h | sed -n \ +types="\ +-T FILE \ +-T bfd -T asection -T pid_t \ +-T prgregset_t -T fpregset_t -T gregset_t -T sigset_t \ +-T td_thrhandle_t -T td_event_msg_t -T td_thr_events_t \ +-T td_notify_t -T td_thr_iter_f -T td_thrinfo_t \ +`cat *.h | sed -n \ -e 's/^.*[^a-z0-9_]\([a-z0-9_]*_ftype\).*$/-T \1/p' \ -e 's/^.*[^a-z0-9_]\([a-z0-9_]*_func\).*$/-T \1/p' \ -e 's/^typedef.*[^a-zA-Z0-9_]\([a-zA-Z0-9_]*[a-zA-Z0-9_]\);$/-T \1/p' \ diff --git a/contrib/gdb/gdb/gdb_locale.h b/contrib/gdb/gdb/gdb_locale.h new file mode 100644 index 00000000000..0d8909200ec --- /dev/null +++ b/contrib/gdb/gdb/gdb_locale.h @@ -0,0 +1,46 @@ +/* GDB-friendly replacement for . + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef GDB_LOCALE_H +#define GDB_LOCALE_H + +#ifdef HAVE_LOCALE_H +# include +#endif + +#ifdef ENABLE_NLS +# include +# define _(String) gettext (String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define gettext(Msgid) (Msgid) +# define dgettext(Domainname, Msgid) (Msgid) +# define dcgettext(Domainname, Msgid, Category) (Msgid) +# define textdomain(Domainname) while (0) /* nothing */ +# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ +# define _(String) (String) +# define N_(String) (String) +#endif + +#endif /* GDB_LOCALE_H */ diff --git a/contrib/gdb/gdb/gdb_mbuild.sh b/contrib/gdb/gdb/gdb_mbuild.sh new file mode 100755 index 00000000000..fc1721904b8 --- /dev/null +++ b/contrib/gdb/gdb/gdb_mbuild.sh @@ -0,0 +1,333 @@ +#!/bin/sh + +# Multi-build script for testing compilation of all maintained +# configs of GDB. + +# Copyright 2002, 2003 Free Software Foundation, Inc. + +# Contributed by Richard Earnshaw (rearnsha@arm.com) + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +usage() +{ + cat < ... ] + Options: + -j Run in parallel. Passed to make. + On a single cpu machine, 2 is recommended. + -k Keep going. Do not stop after the first build fails. + --keep Keep builds. Do not remove each build when finished. + -e Regular expression for selecting the targets to build. + -f Force rebuild. Even rebuild previously built directories. + -v Be more (and more, and more) verbose. + Arguments: + Source code directory. + Build directory. + Environment variables examined (with default if not defined): + MAKE (make)" +EOF + exit 1; +cat < Run builds in parallel. + On a single cpu machine, 1 is recommended. +NOTYET +} + +### COMMAND LINE OPTIONS + +makejobs= +maxbuilds=1 +keepgoing= +force=false +targexp="" +verbose=0 +keep=false +while test $# -gt 0 +do + case "$1" in + -j ) + # Number of parallel make jobs. + shift + test $# -ge 1 || usage + makejobs="-j $1" + ;; + -b | -c ) + # Number of builds to fire off in parallel. + shift + test $# -ge 1 || usage + maxbuilds=$1 + ;; + -k ) + # Should we soldier on after the first build fails? + keepgoing=-k + ;; + --keep ) + keep=true + ;; + -e ) + # A regular expression for selecting targets + shift + test $# -ge 1 || usage + targexp="${targexp} -e ${1}" + ;; + -f ) + # Force a rebuild + force=true ; + ;; + -v ) + # Be more, and more, and more, verbose + verbose=`expr ${verbose} + 1` + ;; + -* ) usage ;; + *) break ;; + esac + shift +done + + +### COMMAND LINE PARAMETERS + +if test $# -ne 2 +then + usage +fi + +# Convert these to absolute directory paths. + +# Where the sources live +srcdir=`cd $1 && /bin/pwd` || exit 1 + +# Where the builds occur +builddir=`cd $2 && /bin/pwd` || exit 1 + +### ENVIRONMENT PARAMETERS + +# Version of make to use +make=${MAKE:-make} +MAKE=${make} +export MAKE + + +# Where to look for the list of targets to test +maintainers=${srcdir}/gdb/MAINTAINERS +if [ ! -r ${maintainers} ] +then + echo Maintainers file ${maintainers} not found + exit 1 +fi + +# Get the list of targets and the build options +alltarg=`cat ${maintainers} | tr -s '[\t]' '[ ]' | sed -n ' +/^[ ]*[-a-z0-9\.]*[ ]*[(]*--target=.*/ !d +s/^.*--target=// +s/).*$// +h +:loop + g + /^[^ ]*,/ !b end + s/,[^ ]*// + p + g + s/^[^,]*,// + h +b loop +:end +p +' | if test "${targexp}" = "" +then + grep -v -e broken -e OBSOLETE +else + grep ${targexp} +fi` + + +# Usage: fail . Should the build +# fail? If the test is true, and we don't want to keep going, print +# the message and shoot everything in sight and abort the build. + +fail () +{ + msg="$1" ; shift + if test "$@" + then + echo "${target}: ${msg}" + if test "${keepgoing}" != "" + then + #exit 1 + continue + else + kill $$ + exit 1 + fi + fi +} + + +# Usage: log . Write standard input to and +# stdout (if verbose >= level). + +log () +{ + if test ${verbose} -ge $1 + then + tee $2 + else + cat > $2 + fi +} + + + +# Warn the user of what is comming, print the list of targets + +echo "$alltarg" +echo "" + + +# For each target, configure, build and test it. + +echo "$alltarg" | while read target gdbopts simopts +do + + trap "exit 1" 1 2 15 + dir=${builddir}/${target} + + # Should a scratch rebuild be forced, for perhaphs the entire + # build be skipped? + + if ${force} + then + echo forcing ${target} ... + rm -rf ${dir} + elif test -f ${dir} + then + echo "${target}" + continue + else + echo ${target} ... + fi + + # Did the previous configure attempt fail? If it did + # restart from scratch. + + if test -d ${dir} -a ! -r ${dir}/Makefile + then + echo ... removing partially configured ${target} + rm -rf ${dir} + if test -d ${dir} + then + echo "${target}: unable to remove directory ${dir}" + exit 1 + fi + fi + + # From now on, we're in this target's build directory + + mkdir -p ${dir} + cd ${dir} || exit 1 + + # Configure, if not already. Should this go back to being + # separate and done in parallel? + + if test ! -r Makefile + then + # Default SIMOPTS to GDBOPTS. + test -z "${simopts}" && simopts="${gdbopts}" + # The config options + __target="--target=${target}" + __enable_gdb_build_warnings=`test -z "${gdbopts}" \ + || echo "--enable-gdb-build-warnings=${gdbopts}"` + __enable_sim_build_warnings=`test -z "${simopts}" \ + || echo "--enable-sim-build-warnings=${simopts}"` + __configure="${srcdir}/configure \ + ${__target} \ + ${__enable_gdb_build_warnings} \ + ${__enable_sim_build_warnings}" + echo ... ${__configure} + trap "echo Removing partially configured ${dir} directory ...; rm -rf ${dir}; exit 1" 1 2 15 + ${__configure} 2>&1 | log 2 Config.log + trap "exit 1" 1 2 15 + fi + fail "configure failed" ! -r Makefile + + # Build, if not built. + + if test ! -x gdb/gdb -a ! -x gdb/gdb.exe + then + # Iff the build fails remove the final build target so that + # the follow-on code knows things failed. Stops the follow-on + # code thinking that a failed rebuild succedded (executable + # left around from previous build). + echo ... ${make} ${keepgoing} ${makejobs} ${target} + ( ${make} ${keepgoing} ${makejobs} all-gdb || rm -f gdb/gdb gdb/gdb.exe + ) 2>&1 | log 1 Build.log + fi + fail "compile failed" ! -x gdb/gdb -a ! -x gdb/gdb.exe + + # Check that the built GDB can at least print it's architecture. + + echo ... run ${target} + rm -f core gdb.core ${dir}/gdb/x + cat < x +maint print architecture +quit +EOF + ./gdb/gdb -batch -nx -x x 2>&1 | log 1 Gdb.log + fail "gdb dumped core" -r core -o -r gdb.core + fail "gdb printed no output" ! -s Gdb.log + grep -e internal-error Gdb.log && fail "gdb panic" 1 + + echo ... cleanup ${target} + + # Create a sed script that cleans up the output from GDB. + rm -f mbuild.sed + touch mbuild.sed || exit 1 + # Rules to replace <0xNNNN> with the corresponding function's + # name. + sed -n -e '/<0x0*>/d' -e 's/^.*<0x\([0-9a-f]*\)>.*$/0x\1/p' Gdb.log \ + | sort -u \ + | while read addr + do + func="`addr2line -f -e ./gdb/gdb -s ${addr} | sed -n -e 1p`" + test ${verbose} -gt 0 && echo "${addr} ${func}" 1>&2 + echo "s/<${addr}>/<${func}>/g" + done >> mbuild.sed + # Rules to strip the leading paths off of file names. + echo 's/"\/.*\/gdb\//"gdb\//g' >> mbuild.sed + # Run the script + sed -f mbuild.sed Gdb.log > Mbuild.log + + # Replace the build directory with a file as semaphore that stops + # a rebuild. (should the logs be saved?) + + cd ${builddir} + + if ${keep} + then + : + else + rm -f ${target}.tmp + mv ${target}/Mbuild.log ${target}.tmp + rm -rf ${target} + mv ${target}.tmp ${target} + fi + + # Success! + echo ... ${target} built + +done + +exit 0 diff --git a/contrib/gdb/gdb/gdb_obstack.h b/contrib/gdb/gdb/gdb_obstack.h new file mode 100644 index 00000000000..0dcfc4ff780 --- /dev/null +++ b/contrib/gdb/gdb/gdb_obstack.h @@ -0,0 +1,39 @@ +/* Obstack wrapper for GDB. + + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined (GDB_OBSTACK_H) +#define GDB_OBSTACK_H 1 + +#include "obstack.h" + +/* Unless explicitly specified, GDB obstacks always use xmalloc() and + xfree(). */ +/* Note: ezannoni 2004-02-09: One could also specify the allocation + functions using a special init function for each obstack, + obstack_specify_allocation. However we just use obstack_init and + let these defines here do the job. While one could argue the + superiority of one approach over the other, we just chose one + throughout. */ + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free xfree + +#endif diff --git a/contrib/gdb/gdb/gdb_regex.h b/contrib/gdb/gdb/gdb_regex.h index 27a570a1f40..7e270f4efe6 100644 --- a/contrib/gdb/gdb/gdb_regex.h +++ b/contrib/gdb/gdb/gdb_regex.h @@ -1,5 +1,5 @@ -/* Portable - Copyright 2000, 2001 Free Software Foundation, Inc. +/* Portable . + Copyright 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -19,12 +19,14 @@ Boston, MA 02111-1307, USA. */ #ifndef GDB_REGEX_H -#define GDB_REGEX_H +#define GDB_REGEX_H 1 #ifdef USE_INCLUDED_REGEX -#include "xregex.h" +# include "xregex.h" #else -#include +/* Request 4.2 BSD regex functions. */ +# define _REGEX_RE_COMP +# include #endif -#endif /* gdb_regex.h */ +#endif /* not GDB_REGEX_H */ diff --git a/contrib/gdb/gdb/gdb_thread_db.h b/contrib/gdb/gdb/gdb_thread_db.h index 8088da0da69..81dd0a062db 100644 --- a/contrib/gdb/gdb/gdb_thread_db.h +++ b/contrib/gdb/gdb/gdb_thread_db.h @@ -63,7 +63,8 @@ typedef enum TD_NOTSD, /* No thread-specific data available. */ TD_MALLOC, /* Out of memory. */ TD_PARTIALREG, /* Not entire register set was read or written. */ - TD_NOXREGS /* X register set not available for given thread. */ + TD_NOXREGS, /* X register set not available for given thread. */ + TD_NOTALLOC /* TLS memory not yet allocated. */ } td_err_e; @@ -198,6 +199,16 @@ typedef struct td_notify } u; } td_notify_t; +/* Some people still have libc5 or old glibc with no uintptr_t. + They lose. glibc 2.1.3 was released on 2000-02-25, and it has + uintptr_t, so it's reasonable to force these people to upgrade. */ + +#ifndef HAVE_UINTPTR_T +#error No uintptr_t available; your C library is too old. +/* Inhibit further compilation errors after this error. */ +#define uintptr_t void * +#endif + /* Structure used to report event. */ typedef struct td_event_msg { diff --git a/contrib/gdb/gdb/gdbarch.c b/contrib/gdb/gdb/gdbarch.c index 5aad461ed48..1ee401f7d81 100644 --- a/contrib/gdb/gdb/gdbarch.c +++ b/contrib/gdb/gdb/gdbarch.c @@ -1,7 +1,9 @@ /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. - Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -36,50 +38,22 @@ #include "defs.h" #include "arch-utils.h" -#if GDB_MULTI_ARCH #include "gdbcmd.h" #include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */ -#else -/* Just include everything in sight so that the every old definition - of macro is visible. */ -#include "gdb_string.h" -#include -#include "symtab.h" -#include "frame.h" -#include "inferior.h" -#include "breakpoint.h" -#include "gdb_wait.h" -#include "gdbcore.h" -#include "gdbcmd.h" -#include "target.h" -#include "gdbthread.h" -#include "annotate.h" -#include "symfile.h" /* for overlay functions */ -#include "value.h" /* For old tm.h/nm.h macros. */ -#endif #include "symcat.h" #include "floatformat.h" #include "gdb_assert.h" +#include "gdb_string.h" #include "gdb-events.h" +#include "reggroups.h" +#include "osabi.h" +#include "gdb_obstack.h" /* Static function declarations */ -static void verify_gdbarch (struct gdbarch *gdbarch); static void alloc_gdbarch_data (struct gdbarch *); -static void init_gdbarch_data (struct gdbarch *); -static void free_gdbarch_data (struct gdbarch *); -static void init_gdbarch_swap (struct gdbarch *); -static void swapout_gdbarch_swap (struct gdbarch *); -static void swapin_gdbarch_swap (struct gdbarch *); - -/* Convenience macro for allocting typesafe memory. */ - -#ifndef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) -#endif - /* Non-zero if we want to trace architecture code. */ @@ -93,9 +67,16 @@ int gdbarch_debug = GDBARCH_DEBUG; struct gdbarch { + /* Has this architecture been fully initialized? */ + int initialized_p; + + /* An obstack bound to the lifetime of the architecture. */ + struct obstack *obstack; + /* basic architectural information */ const struct bfd_arch_info * bfd_arch_info; int byte_order; + enum gdb_osabi osabi; /* target specific vector. */ struct gdbarch_tdep *tdep; @@ -147,105 +128,110 @@ struct gdbarch int char_signed; gdbarch_read_pc_ftype *read_pc; gdbarch_write_pc_ftype *write_pc; - gdbarch_read_fp_ftype *read_fp; - gdbarch_write_fp_ftype *write_fp; gdbarch_read_sp_ftype *read_sp; - gdbarch_write_sp_ftype *write_sp; gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer; - gdbarch_register_read_ftype *register_read; - gdbarch_register_write_ftype *register_write; + gdbarch_pseudo_register_read_ftype *pseudo_register_read; + gdbarch_pseudo_register_write_ftype *pseudo_register_write; int num_regs; int num_pseudo_regs; int sp_regnum; - int fp_regnum; int pc_regnum; + int ps_regnum; int fp0_regnum; - int npc_regnum; - int nnpc_regnum; gdbarch_stab_reg_to_regnum_ftype *stab_reg_to_regnum; gdbarch_ecoff_reg_to_regnum_ftype *ecoff_reg_to_regnum; gdbarch_dwarf_reg_to_regnum_ftype *dwarf_reg_to_regnum; gdbarch_sdb_reg_to_regnum_ftype *sdb_reg_to_regnum; gdbarch_dwarf2_reg_to_regnum_ftype *dwarf2_reg_to_regnum; gdbarch_register_name_ftype *register_name; - int register_size; - int register_bytes; - gdbarch_register_byte_ftype *register_byte; - gdbarch_register_raw_size_ftype *register_raw_size; - int max_register_raw_size; - gdbarch_register_virtual_size_ftype *register_virtual_size; - int max_register_virtual_size; - gdbarch_register_virtual_type_ftype *register_virtual_type; - gdbarch_do_registers_info_ftype *do_registers_info; + gdbarch_register_type_ftype *register_type; + gdbarch_deprecated_register_virtual_type_ftype *deprecated_register_virtual_type; + int deprecated_register_bytes; + gdbarch_deprecated_register_byte_ftype *deprecated_register_byte; + gdbarch_deprecated_register_raw_size_ftype *deprecated_register_raw_size; + gdbarch_deprecated_register_virtual_size_ftype *deprecated_register_virtual_size; + int deprecated_max_register_raw_size; + int deprecated_max_register_virtual_size; + gdbarch_unwind_dummy_id_ftype *unwind_dummy_id; + gdbarch_deprecated_save_dummy_frame_tos_ftype *deprecated_save_dummy_frame_tos; + int deprecated_fp_regnum; + gdbarch_deprecated_target_read_fp_ftype *deprecated_target_read_fp; + gdbarch_push_dummy_call_ftype *push_dummy_call; + gdbarch_deprecated_push_arguments_ftype *deprecated_push_arguments; + int deprecated_use_generic_dummy_frames; + gdbarch_deprecated_push_return_address_ftype *deprecated_push_return_address; + gdbarch_deprecated_dummy_write_sp_ftype *deprecated_dummy_write_sp; + int deprecated_register_size; + int call_dummy_location; + CORE_ADDR deprecated_call_dummy_start_offset; + CORE_ADDR deprecated_call_dummy_breakpoint_offset; + int deprecated_call_dummy_length; + LONGEST * deprecated_call_dummy_words; + int deprecated_sizeof_call_dummy_words; + gdbarch_deprecated_fix_call_dummy_ftype *deprecated_fix_call_dummy; + gdbarch_push_dummy_code_ftype *push_dummy_code; + gdbarch_deprecated_push_dummy_frame_ftype *deprecated_push_dummy_frame; + gdbarch_deprecated_do_registers_info_ftype *deprecated_do_registers_info; + gdbarch_print_registers_info_ftype *print_registers_info; gdbarch_print_float_info_ftype *print_float_info; + gdbarch_print_vector_info_ftype *print_vector_info; gdbarch_register_sim_regno_ftype *register_sim_regno; gdbarch_register_bytes_ok_ftype *register_bytes_ok; gdbarch_cannot_fetch_register_ftype *cannot_fetch_register; gdbarch_cannot_store_register_ftype *cannot_store_register; gdbarch_get_longjmp_target_ftype *get_longjmp_target; - int use_generic_dummy_frames; - int call_dummy_location; - gdbarch_call_dummy_address_ftype *call_dummy_address; - CORE_ADDR call_dummy_start_offset; - CORE_ADDR call_dummy_breakpoint_offset; - int call_dummy_breakpoint_offset_p; - int call_dummy_length; - gdbarch_pc_in_call_dummy_ftype *pc_in_call_dummy; - int call_dummy_p; - LONGEST * call_dummy_words; - int sizeof_call_dummy_words; - int call_dummy_stack_adjust_p; - int call_dummy_stack_adjust; - gdbarch_fix_call_dummy_ftype *fix_call_dummy; - gdbarch_init_frame_pc_first_ftype *init_frame_pc_first; - gdbarch_init_frame_pc_ftype *init_frame_pc; + gdbarch_deprecated_pc_in_call_dummy_ftype *deprecated_pc_in_call_dummy; + gdbarch_deprecated_init_frame_pc_first_ftype *deprecated_init_frame_pc_first; + gdbarch_deprecated_init_frame_pc_ftype *deprecated_init_frame_pc; int believe_pcc_promotion; int believe_pcc_promotion_type; - gdbarch_coerce_float_to_double_ftype *coerce_float_to_double; - gdbarch_get_saved_register_ftype *get_saved_register; - gdbarch_register_convertible_ftype *register_convertible; - gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual; - gdbarch_register_convert_to_raw_ftype *register_convert_to_raw; - gdbarch_fetch_pseudo_register_ftype *fetch_pseudo_register; - gdbarch_store_pseudo_register_ftype *store_pseudo_register; + gdbarch_deprecated_get_saved_register_ftype *deprecated_get_saved_register; + gdbarch_deprecated_register_convertible_ftype *deprecated_register_convertible; + gdbarch_deprecated_register_convert_to_virtual_ftype *deprecated_register_convert_to_virtual; + gdbarch_deprecated_register_convert_to_raw_ftype *deprecated_register_convert_to_raw; + gdbarch_convert_register_p_ftype *convert_register_p; + gdbarch_register_to_value_ftype *register_to_value; + gdbarch_value_to_register_ftype *value_to_register; gdbarch_pointer_to_address_ftype *pointer_to_address; gdbarch_address_to_pointer_ftype *address_to_pointer; gdbarch_integer_to_address_ftype *integer_to_address; + gdbarch_deprecated_pop_frame_ftype *deprecated_pop_frame; + gdbarch_deprecated_store_struct_return_ftype *deprecated_store_struct_return; + gdbarch_return_value_ftype *return_value; gdbarch_return_value_on_stack_ftype *return_value_on_stack; gdbarch_extract_return_value_ftype *extract_return_value; - gdbarch_push_arguments_ftype *push_arguments; - gdbarch_push_dummy_frame_ftype *push_dummy_frame; - gdbarch_push_return_address_ftype *push_return_address; - gdbarch_pop_frame_ftype *pop_frame; - gdbarch_store_struct_return_ftype *store_struct_return; gdbarch_store_return_value_ftype *store_return_value; - gdbarch_extract_struct_value_address_ftype *extract_struct_value_address; + gdbarch_deprecated_extract_return_value_ftype *deprecated_extract_return_value; + gdbarch_deprecated_store_return_value_ftype *deprecated_store_return_value; gdbarch_use_struct_convention_ftype *use_struct_convention; - gdbarch_frame_init_saved_regs_ftype *frame_init_saved_regs; - gdbarch_init_extra_frame_info_ftype *init_extra_frame_info; + gdbarch_deprecated_extract_struct_value_address_ftype *deprecated_extract_struct_value_address; + gdbarch_deprecated_frame_init_saved_regs_ftype *deprecated_frame_init_saved_regs; + gdbarch_deprecated_init_extra_frame_info_ftype *deprecated_init_extra_frame_info; gdbarch_skip_prologue_ftype *skip_prologue; - gdbarch_prologue_frameless_p_ftype *prologue_frameless_p; gdbarch_inner_than_ftype *inner_than; gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc; + gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address; gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint; gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint; CORE_ADDR decr_pc_after_break; - gdbarch_prepare_to_proceed_ftype *prepare_to_proceed; CORE_ADDR function_start_offset; gdbarch_remote_translate_xfer_address_ftype *remote_translate_xfer_address; CORE_ADDR frame_args_skip; - gdbarch_frameless_function_invocation_ftype *frameless_function_invocation; - gdbarch_frame_chain_ftype *frame_chain; - gdbarch_frame_chain_valid_ftype *frame_chain_valid; - gdbarch_frame_saved_pc_ftype *frame_saved_pc; - gdbarch_frame_args_address_ftype *frame_args_address; - gdbarch_frame_locals_address_ftype *frame_locals_address; - gdbarch_saved_pc_after_call_ftype *saved_pc_after_call; + gdbarch_deprecated_frameless_function_invocation_ftype *deprecated_frameless_function_invocation; + gdbarch_deprecated_frame_chain_ftype *deprecated_frame_chain; + gdbarch_deprecated_frame_chain_valid_ftype *deprecated_frame_chain_valid; + gdbarch_deprecated_frame_saved_pc_ftype *deprecated_frame_saved_pc; + gdbarch_unwind_pc_ftype *unwind_pc; + gdbarch_unwind_sp_ftype *unwind_sp; + gdbarch_deprecated_frame_args_address_ftype *deprecated_frame_args_address; + gdbarch_deprecated_frame_locals_address_ftype *deprecated_frame_locals_address; + gdbarch_deprecated_saved_pc_after_call_ftype *deprecated_saved_pc_after_call; gdbarch_frame_num_args_ftype *frame_num_args; - gdbarch_stack_align_ftype *stack_align; - int extra_stack_alignment_needed; - gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr; - gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos; + gdbarch_deprecated_stack_align_ftype *deprecated_stack_align; + gdbarch_frame_align_ftype *frame_align; + gdbarch_deprecated_reg_struct_has_addr_ftype *deprecated_reg_struct_has_addr; + gdbarch_stabs_argument_has_addr_ftype *stabs_argument_has_addr; + int frame_red_zone_size; int parm_boundary; const struct floatformat * float_format; const struct floatformat * double_format; @@ -256,12 +242,25 @@ struct gdbarch gdbarch_software_single_step_ftype *software_single_step; gdbarch_print_insn_ftype *print_insn; gdbarch_skip_trampoline_code_ftype *skip_trampoline_code; + gdbarch_skip_solib_resolver_ftype *skip_solib_resolver; gdbarch_in_solib_call_trampoline_ftype *in_solib_call_trampoline; + gdbarch_in_solib_return_trampoline_ftype *in_solib_return_trampoline; + gdbarch_pc_in_sigtramp_ftype *pc_in_sigtramp; + gdbarch_sigtramp_start_ftype *sigtramp_start; + gdbarch_sigtramp_end_ftype *sigtramp_end; gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p; gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments; - gdbarch_dwarf2_build_frame_info_ftype *dwarf2_build_frame_info; gdbarch_elf_make_msymbol_special_ftype *elf_make_msymbol_special; gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special; + const char * name_of_malloc; + int cannot_step_breakpoint; + int have_nonsteppable_watchpoint; + gdbarch_address_class_type_flags_ftype *address_class_type_flags; + gdbarch_address_class_type_flags_to_name_ftype *address_class_type_flags_to_name; + gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags; + gdbarch_register_reggroup_p_ftype *register_reggroup_p; + gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument; + gdbarch_regset_from_core_section_ftype *regset_from_core_section; }; @@ -272,157 +271,168 @@ extern const struct bfd_arch_info bfd_default_arch_struct; struct gdbarch startup_gdbarch = { + 1, /* Always initialized. */ + NULL, /* The obstack. */ /* basic architecture information */ - &bfd_default_arch_struct, - BFD_ENDIAN_BIG, + &bfd_default_arch_struct, /* bfd_arch_info */ + BFD_ENDIAN_BIG, /* byte_order */ + GDB_OSABI_UNKNOWN, /* osabi */ /* target specific vector and its dump routine */ NULL, NULL, /*per-architecture data-pointers and swap regions */ 0, NULL, NULL, /* Multi-arch values */ - 8 * sizeof (short), - 8 * sizeof (int), - 8 * sizeof (long), - 8 * sizeof (LONGEST), - 8 * sizeof (float), - 8 * sizeof (double), - 8 * sizeof (long double), - 8 * sizeof (void*), - 8 * sizeof (void*), - 8 * sizeof (void*), - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - generic_register_raw_size, - 0, - generic_register_virtual_size, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - generic_get_saved_register, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - generic_in_function_epilogue_p, - construct_inferior_arguments, - 0, - 0, - 0, + 8 * sizeof (short), /* short_bit */ + 8 * sizeof (int), /* int_bit */ + 8 * sizeof (long), /* long_bit */ + 8 * sizeof (LONGEST), /* long_long_bit */ + 8 * sizeof (float), /* float_bit */ + 8 * sizeof (double), /* double_bit */ + 8 * sizeof (long double), /* long_double_bit */ + 8 * sizeof (void*), /* ptr_bit */ + 8 * sizeof (void*), /* addr_bit */ + 8 * sizeof (void*), /* bfd_vma_bit */ + 1, /* char_signed */ + 0, /* read_pc */ + 0, /* write_pc */ + 0, /* read_sp */ + 0, /* virtual_frame_pointer */ + 0, /* pseudo_register_read */ + 0, /* pseudo_register_write */ + 0, /* num_regs */ + 0, /* num_pseudo_regs */ + -1, /* sp_regnum */ + -1, /* pc_regnum */ + -1, /* ps_regnum */ + 0, /* fp0_regnum */ + 0, /* stab_reg_to_regnum */ + 0, /* ecoff_reg_to_regnum */ + 0, /* dwarf_reg_to_regnum */ + 0, /* sdb_reg_to_regnum */ + 0, /* dwarf2_reg_to_regnum */ + 0, /* register_name */ + 0, /* register_type */ + 0, /* deprecated_register_virtual_type */ + 0, /* deprecated_register_bytes */ + generic_register_byte, /* deprecated_register_byte */ + generic_register_size, /* deprecated_register_raw_size */ + generic_register_size, /* deprecated_register_virtual_size */ + 0, /* deprecated_max_register_raw_size */ + 0, /* deprecated_max_register_virtual_size */ + 0, /* unwind_dummy_id */ + 0, /* deprecated_save_dummy_frame_tos */ + -1, /* deprecated_fp_regnum */ + 0, /* deprecated_target_read_fp */ + 0, /* push_dummy_call */ + 0, /* deprecated_push_arguments */ + 0, /* deprecated_use_generic_dummy_frames */ + 0, /* deprecated_push_return_address */ + 0, /* deprecated_dummy_write_sp */ + 0, /* deprecated_register_size */ + 0, /* call_dummy_location */ + 0, /* deprecated_call_dummy_start_offset */ + 0, /* deprecated_call_dummy_breakpoint_offset */ + 0, /* deprecated_call_dummy_length */ + 0, /* deprecated_call_dummy_words */ + 0, /* deprecated_sizeof_call_dummy_words */ + 0, /* deprecated_fix_call_dummy */ + 0, /* push_dummy_code */ + 0, /* deprecated_push_dummy_frame */ + 0, /* deprecated_do_registers_info */ + default_print_registers_info, /* print_registers_info */ + 0, /* print_float_info */ + 0, /* print_vector_info */ + 0, /* register_sim_regno */ + 0, /* register_bytes_ok */ + 0, /* cannot_fetch_register */ + 0, /* cannot_store_register */ + 0, /* get_longjmp_target */ + generic_pc_in_call_dummy, /* deprecated_pc_in_call_dummy */ + 0, /* deprecated_init_frame_pc_first */ + 0, /* deprecated_init_frame_pc */ + 0, /* believe_pcc_promotion */ + 0, /* believe_pcc_promotion_type */ + 0, /* deprecated_get_saved_register */ + 0, /* deprecated_register_convertible */ + 0, /* deprecated_register_convert_to_virtual */ + 0, /* deprecated_register_convert_to_raw */ + 0, /* convert_register_p */ + 0, /* register_to_value */ + 0, /* value_to_register */ + 0, /* pointer_to_address */ + 0, /* address_to_pointer */ + 0, /* integer_to_address */ + 0, /* deprecated_pop_frame */ + 0, /* deprecated_store_struct_return */ + 0, /* return_value */ + 0, /* return_value_on_stack */ + 0, /* extract_return_value */ + 0, /* store_return_value */ + 0, /* deprecated_extract_return_value */ + 0, /* deprecated_store_return_value */ + 0, /* use_struct_convention */ + 0, /* deprecated_extract_struct_value_address */ + 0, /* deprecated_frame_init_saved_regs */ + 0, /* deprecated_init_extra_frame_info */ + 0, /* skip_prologue */ + 0, /* inner_than */ + 0, /* breakpoint_from_pc */ + 0, /* adjust_breakpoint_address */ + 0, /* memory_insert_breakpoint */ + 0, /* memory_remove_breakpoint */ + 0, /* decr_pc_after_break */ + 0, /* function_start_offset */ + generic_remote_translate_xfer_address, /* remote_translate_xfer_address */ + 0, /* frame_args_skip */ + 0, /* deprecated_frameless_function_invocation */ + 0, /* deprecated_frame_chain */ + 0, /* deprecated_frame_chain_valid */ + 0, /* deprecated_frame_saved_pc */ + 0, /* unwind_pc */ + 0, /* unwind_sp */ + get_frame_base, /* deprecated_frame_args_address */ + get_frame_base, /* deprecated_frame_locals_address */ + 0, /* deprecated_saved_pc_after_call */ + 0, /* frame_num_args */ + 0, /* deprecated_stack_align */ + 0, /* frame_align */ + 0, /* deprecated_reg_struct_has_addr */ + default_stabs_argument_has_addr, /* stabs_argument_has_addr */ + 0, /* frame_red_zone_size */ + 0, /* parm_boundary */ + 0, /* float_format */ + 0, /* double_format */ + 0, /* long_double_format */ + convert_from_func_ptr_addr_identity, /* convert_from_func_ptr_addr */ + 0, /* addr_bits_remove */ + 0, /* smash_text_address */ + 0, /* software_single_step */ + 0, /* print_insn */ + 0, /* skip_trampoline_code */ + generic_skip_solib_resolver, /* skip_solib_resolver */ + 0, /* in_solib_call_trampoline */ + 0, /* in_solib_return_trampoline */ + 0, /* pc_in_sigtramp */ + 0, /* sigtramp_start */ + 0, /* sigtramp_end */ + generic_in_function_epilogue_p, /* in_function_epilogue_p */ + construct_inferior_arguments, /* construct_inferior_arguments */ + 0, /* elf_make_msymbol_special */ + 0, /* coff_make_msymbol_special */ + "malloc", /* name_of_malloc */ + 0, /* cannot_step_breakpoint */ + 0, /* have_nonsteppable_watchpoint */ + 0, /* address_class_type_flags */ + 0, /* address_class_type_flags_to_name */ + 0, /* address_class_name_to_type_flags */ + default_register_reggroup_p, /* register_reggroup_p */ + 0, /* fetch_pointer_argument */ + 0, /* regset_from_core_section */ /* startup_gdbarch() */ }; struct gdbarch *current_gdbarch = &startup_gdbarch; -/* Do any initialization needed for a non-multiarch configuration - after the _initialize_MODULE functions have been run. */ -void -initialize_non_multiarch () -{ - alloc_gdbarch_data (&startup_gdbarch); - init_gdbarch_data (&startup_gdbarch); -} - - /* Create a new ``struct gdbarch'' based on information provided by ``struct gdbarch_info''. */ @@ -436,8 +446,15 @@ gdbarch_alloc (const struct gdbarch_info *info, architecture. This ensures that the new architectures initial values are not influenced by the previous architecture. Once everything is parameterised with gdbarch, this will go away. */ - struct gdbarch *current_gdbarch = XMALLOC (struct gdbarch); + struct gdbarch *current_gdbarch; + + /* Create an obstack for allocating all the per-architecture memory, + then use that to allocate the architecture vector. */ + struct obstack *obstack = XMALLOC (struct obstack); + obstack_init (obstack); + current_gdbarch = obstack_alloc (obstack, sizeof (*current_gdbarch)); memset (current_gdbarch, 0, sizeof (*current_gdbarch)); + current_gdbarch->obstack = obstack; alloc_gdbarch_data (current_gdbarch); @@ -445,6 +462,7 @@ gdbarch_alloc (const struct gdbarch_info *info, current_gdbarch->bfd_arch_info = info->bfd_arch_info; current_gdbarch->byte_order = info->byte_order; + current_gdbarch->osabi = info->osabi; /* Force the explicit initialization of these. */ current_gdbarch->short_bit = 2*TARGET_CHAR_BIT; @@ -457,81 +475,77 @@ gdbarch_alloc (const struct gdbarch_info *info, current_gdbarch->ptr_bit = TARGET_INT_BIT; current_gdbarch->bfd_vma_bit = TARGET_ARCHITECTURE->bits_per_address; current_gdbarch->char_signed = -1; - current_gdbarch->read_pc = generic_target_read_pc; current_gdbarch->write_pc = generic_target_write_pc; - current_gdbarch->read_fp = generic_target_read_fp; - current_gdbarch->write_fp = generic_target_write_fp; - current_gdbarch->read_sp = generic_target_read_sp; - current_gdbarch->write_sp = generic_target_write_sp; current_gdbarch->virtual_frame_pointer = legacy_virtual_frame_pointer; current_gdbarch->num_regs = -1; current_gdbarch->sp_regnum = -1; - current_gdbarch->fp_regnum = -1; current_gdbarch->pc_regnum = -1; + current_gdbarch->ps_regnum = -1; current_gdbarch->fp0_regnum = -1; - current_gdbarch->npc_regnum = -1; - current_gdbarch->nnpc_regnum = -1; current_gdbarch->stab_reg_to_regnum = no_op_reg_to_regnum; current_gdbarch->ecoff_reg_to_regnum = no_op_reg_to_regnum; current_gdbarch->dwarf_reg_to_regnum = no_op_reg_to_regnum; current_gdbarch->sdb_reg_to_regnum = no_op_reg_to_regnum; current_gdbarch->dwarf2_reg_to_regnum = no_op_reg_to_regnum; - current_gdbarch->register_name = legacy_register_name; - current_gdbarch->register_size = -1; - current_gdbarch->register_bytes = -1; - current_gdbarch->max_register_raw_size = -1; - current_gdbarch->max_register_virtual_size = -1; - current_gdbarch->do_registers_info = do_registers_info; - current_gdbarch->print_float_info = default_print_float_info; - current_gdbarch->register_sim_regno = default_register_sim_regno; + current_gdbarch->deprecated_register_byte = generic_register_byte; + current_gdbarch->deprecated_register_raw_size = generic_register_size; + current_gdbarch->deprecated_register_virtual_size = generic_register_size; + current_gdbarch->deprecated_fp_regnum = -1; + current_gdbarch->deprecated_use_generic_dummy_frames = 1; + current_gdbarch->call_dummy_location = AT_ENTRY_POINT; + current_gdbarch->deprecated_call_dummy_words = legacy_call_dummy_words; + current_gdbarch->deprecated_sizeof_call_dummy_words = legacy_sizeof_call_dummy_words; + current_gdbarch->print_registers_info = default_print_registers_info; + current_gdbarch->register_sim_regno = legacy_register_sim_regno; current_gdbarch->cannot_fetch_register = cannot_register_not; current_gdbarch->cannot_store_register = cannot_register_not; - current_gdbarch->use_generic_dummy_frames = -1; - current_gdbarch->call_dummy_start_offset = -1; - current_gdbarch->call_dummy_breakpoint_offset = -1; - current_gdbarch->call_dummy_breakpoint_offset_p = -1; - current_gdbarch->call_dummy_length = -1; - current_gdbarch->call_dummy_p = -1; - current_gdbarch->call_dummy_words = legacy_call_dummy_words; - current_gdbarch->sizeof_call_dummy_words = legacy_sizeof_call_dummy_words; - current_gdbarch->call_dummy_stack_adjust_p = -1; - current_gdbarch->init_frame_pc_first = init_frame_pc_noop; - current_gdbarch->init_frame_pc = init_frame_pc_default; - current_gdbarch->coerce_float_to_double = default_coerce_float_to_double; - current_gdbarch->register_convertible = generic_register_convertible_not; + current_gdbarch->deprecated_pc_in_call_dummy = generic_pc_in_call_dummy; + current_gdbarch->convert_register_p = legacy_convert_register_p; + current_gdbarch->register_to_value = legacy_register_to_value; + current_gdbarch->value_to_register = legacy_value_to_register; current_gdbarch->pointer_to_address = unsigned_pointer_to_address; current_gdbarch->address_to_pointer = unsigned_address_to_pointer; current_gdbarch->return_value_on_stack = generic_return_value_on_stack_not; - current_gdbarch->push_arguments = default_push_arguments; + current_gdbarch->extract_return_value = legacy_extract_return_value; + current_gdbarch->store_return_value = legacy_store_return_value; current_gdbarch->use_struct_convention = generic_use_struct_convention; - current_gdbarch->prologue_frameless_p = generic_prologue_frameless_p; - current_gdbarch->breakpoint_from_pc = legacy_breakpoint_from_pc; current_gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint; current_gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint; - current_gdbarch->decr_pc_after_break = -1; - current_gdbarch->prepare_to_proceed = default_prepare_to_proceed; - current_gdbarch->function_start_offset = -1; current_gdbarch->remote_translate_xfer_address = generic_remote_translate_xfer_address; - current_gdbarch->frame_args_skip = -1; - current_gdbarch->frameless_function_invocation = generic_frameless_function_invocation_not; - current_gdbarch->frame_chain_valid = func_frame_chain_valid; - current_gdbarch->extra_stack_alignment_needed = 1; - current_gdbarch->convert_from_func_ptr_addr = core_addr_identity; + current_gdbarch->deprecated_frame_args_address = get_frame_base; + current_gdbarch->deprecated_frame_locals_address = get_frame_base; + current_gdbarch->stabs_argument_has_addr = default_stabs_argument_has_addr; + current_gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity; current_gdbarch->addr_bits_remove = core_addr_identity; current_gdbarch->smash_text_address = core_addr_identity; - current_gdbarch->print_insn = legacy_print_insn; current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code; + current_gdbarch->skip_solib_resolver = generic_skip_solib_resolver; current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline; + current_gdbarch->in_solib_return_trampoline = generic_in_solib_return_trampoline; + current_gdbarch->pc_in_sigtramp = legacy_pc_in_sigtramp; current_gdbarch->in_function_epilogue_p = generic_in_function_epilogue_p; current_gdbarch->construct_inferior_arguments = construct_inferior_arguments; current_gdbarch->elf_make_msymbol_special = default_elf_make_msymbol_special; current_gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special; + current_gdbarch->name_of_malloc = "malloc"; + current_gdbarch->register_reggroup_p = default_register_reggroup_p; /* gdbarch_alloc() */ return current_gdbarch; } +/* Allocate extra space using the per-architecture obstack. */ + +void * +gdbarch_obstack_zalloc (struct gdbarch *arch, long size) +{ + void *data = obstack_alloc (arch->obstack, size); + memset (data, 0, size); + return data; +} + + /* Free a gdbarch struct. This should never happen in normal operation --- once you've created a gdbarch, you keep it around. However, if an architecture's init function encounters an error @@ -541,30 +555,36 @@ gdbarch_alloc (const struct gdbarch_info *info, void gdbarch_free (struct gdbarch *arch) { + struct obstack *obstack; gdb_assert (arch != NULL); - free_gdbarch_data (arch); - xfree (arch); + gdb_assert (!arch->initialized_p); + obstack = arch->obstack; + obstack_free (obstack, 0); /* Includes the ARCH. */ + xfree (obstack); } -/* Ensure that all values in a GDBARCH are reasonable. */ +/* Ensure that all values in a GDBARCH are reasonable. */ + +/* NOTE/WARNING: The parameter is called ``current_gdbarch'' so that it + just happens to match the global variable ``current_gdbarch''. That + way macros refering to that variable get the local and not the global + version - ulgh. Once everything is parameterised with gdbarch, this + will go away. */ static void -verify_gdbarch (struct gdbarch *gdbarch) +verify_gdbarch (struct gdbarch *current_gdbarch) { struct ui_file *log; struct cleanup *cleanups; long dummy; char *buf; - /* Only perform sanity checks on a multi-arch target. */ - if (!GDB_MULTI_ARCH) - return; log = mem_fileopen (); cleanups = make_cleanup_ui_file_delete (log); /* fundamental */ - if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN) + if (current_gdbarch->byte_order == BFD_ENDIAN_UNKNOWN) fprintf_unfiltered (log, "\n\tbyte-order"); - if (gdbarch->bfd_arch_info == NULL) + if (current_gdbarch->bfd_arch_info == NULL) fprintf_unfiltered (log, "\n\tbfd_arch_info"); /* Check those that need to be defined for the given multi-arch level. */ /* Skip verify of short_bit, invalid_p == 0 */ @@ -575,212 +595,147 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of double_bit, invalid_p == 0 */ /* Skip verify of long_double_bit, invalid_p == 0 */ /* Skip verify of ptr_bit, invalid_p == 0 */ - if (gdbarch->addr_bit == 0) - gdbarch->addr_bit = TARGET_PTR_BIT; + if (current_gdbarch->addr_bit == 0) + current_gdbarch->addr_bit = TARGET_PTR_BIT; /* Skip verify of bfd_vma_bit, invalid_p == 0 */ - if (gdbarch->char_signed == -1) - gdbarch->char_signed = 1; - /* Skip verify of read_pc, invalid_p == 0 */ + if (current_gdbarch->char_signed == -1) + current_gdbarch->char_signed = 1; + /* Skip verify of read_pc, has predicate */ /* Skip verify of write_pc, invalid_p == 0 */ - /* Skip verify of read_fp, invalid_p == 0 */ - /* Skip verify of write_fp, invalid_p == 0 */ - /* Skip verify of read_sp, invalid_p == 0 */ - /* Skip verify of write_sp, invalid_p == 0 */ + /* Skip verify of read_sp, has predicate */ /* Skip verify of virtual_frame_pointer, invalid_p == 0 */ - /* Skip verify of register_read, has predicate */ - /* Skip verify of register_write, has predicate */ + /* Skip verify of pseudo_register_read, has predicate */ + /* Skip verify of pseudo_register_write, has predicate */ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->num_regs == -1)) + && (current_gdbarch->num_regs == -1)) fprintf_unfiltered (log, "\n\tnum_regs"); /* Skip verify of num_pseudo_regs, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->sp_regnum == -1)) - fprintf_unfiltered (log, "\n\tsp_regnum"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->fp_regnum == -1)) - fprintf_unfiltered (log, "\n\tfp_regnum"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->pc_regnum == -1)) - fprintf_unfiltered (log, "\n\tpc_regnum"); + /* Skip verify of sp_regnum, invalid_p == 0 */ + /* Skip verify of pc_regnum, invalid_p == 0 */ + /* Skip verify of ps_regnum, invalid_p == 0 */ /* Skip verify of fp0_regnum, invalid_p == 0 */ - /* Skip verify of npc_regnum, invalid_p == 0 */ - /* Skip verify of nnpc_regnum, invalid_p == 0 */ /* Skip verify of stab_reg_to_regnum, invalid_p == 0 */ /* Skip verify of ecoff_reg_to_regnum, invalid_p == 0 */ /* Skip verify of dwarf_reg_to_regnum, invalid_p == 0 */ /* Skip verify of sdb_reg_to_regnum, invalid_p == 0 */ /* Skip verify of dwarf2_reg_to_regnum, invalid_p == 0 */ - /* Skip verify of register_name, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->register_size == -1)) - fprintf_unfiltered (log, "\n\tregister_size"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->register_bytes == -1)) - fprintf_unfiltered (log, "\n\tregister_bytes"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->register_byte == 0)) - fprintf_unfiltered (log, "\n\tregister_byte"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->register_raw_size == 0)) - fprintf_unfiltered (log, "\n\tregister_raw_size"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->max_register_raw_size == -1)) - fprintf_unfiltered (log, "\n\tmax_register_raw_size"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->register_virtual_size == 0)) - fprintf_unfiltered (log, "\n\tregister_virtual_size"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->max_register_virtual_size == -1)) - fprintf_unfiltered (log, "\n\tmax_register_virtual_size"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->register_virtual_type == 0)) - fprintf_unfiltered (log, "\n\tregister_virtual_type"); - /* Skip verify of do_registers_info, invalid_p == 0 */ - /* Skip verify of print_float_info, invalid_p == 0 */ + /* Skip verify of register_type, has predicate */ + /* Skip verify of deprecated_register_virtual_type, has predicate */ + /* Skip verify of deprecated_register_byte, has predicate */ + /* Skip verify of deprecated_register_raw_size, has predicate */ + /* Skip verify of deprecated_register_virtual_size, has predicate */ + /* Skip verify of deprecated_max_register_raw_size, has predicate */ + /* Skip verify of deprecated_max_register_virtual_size, has predicate */ + /* Skip verify of unwind_dummy_id, has predicate */ + /* Skip verify of deprecated_save_dummy_frame_tos, has predicate */ + /* Skip verify of deprecated_fp_regnum, invalid_p == 0 */ + /* Skip verify of deprecated_target_read_fp, has predicate */ + /* Skip verify of push_dummy_call, has predicate */ + /* Skip verify of deprecated_push_arguments, has predicate */ + /* Skip verify of deprecated_use_generic_dummy_frames, invalid_p == 0 */ + /* Skip verify of deprecated_push_return_address, has predicate */ + /* Skip verify of deprecated_dummy_write_sp, has predicate */ + /* Skip verify of call_dummy_location, invalid_p == 0 */ + /* Skip verify of deprecated_call_dummy_words, invalid_p == 0 */ + /* Skip verify of deprecated_sizeof_call_dummy_words, invalid_p == 0 */ + /* Skip verify of deprecated_fix_call_dummy, has predicate */ + /* Skip verify of push_dummy_code, has predicate */ + /* Skip verify of deprecated_push_dummy_frame, has predicate */ + /* Skip verify of deprecated_do_registers_info, has predicate */ + /* Skip verify of print_registers_info, invalid_p == 0 */ + /* Skip verify of print_float_info, has predicate */ + /* Skip verify of print_vector_info, has predicate */ /* Skip verify of register_sim_regno, invalid_p == 0 */ /* Skip verify of register_bytes_ok, has predicate */ /* Skip verify of cannot_fetch_register, invalid_p == 0 */ /* Skip verify of cannot_store_register, invalid_p == 0 */ /* Skip verify of get_longjmp_target, has predicate */ - if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->use_generic_dummy_frames == -1)) - fprintf_unfiltered (log, "\n\tuse_generic_dummy_frames"); - if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_location == 0)) - fprintf_unfiltered (log, "\n\tcall_dummy_location"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_location == AT_ENTRY_POINT && gdbarch->call_dummy_address == 0)) - fprintf_unfiltered (log, "\n\tcall_dummy_address"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_start_offset == -1)) - fprintf_unfiltered (log, "\n\tcall_dummy_start_offset"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_breakpoint_offset_p && gdbarch->call_dummy_breakpoint_offset == -1)) - fprintf_unfiltered (log, "\n\tcall_dummy_breakpoint_offset"); - if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_breakpoint_offset_p == -1)) - fprintf_unfiltered (log, "\n\tcall_dummy_breakpoint_offset_p"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_length == -1)) - fprintf_unfiltered (log, "\n\tcall_dummy_length"); - if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->pc_in_call_dummy == 0)) - fprintf_unfiltered (log, "\n\tpc_in_call_dummy"); - if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_p == -1)) - fprintf_unfiltered (log, "\n\tcall_dummy_p"); - /* Skip verify of call_dummy_words, invalid_p == 0 */ - /* Skip verify of sizeof_call_dummy_words, invalid_p == 0 */ - if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_stack_adjust_p == -1)) - fprintf_unfiltered (log, "\n\tcall_dummy_stack_adjust_p"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->call_dummy_stack_adjust_p && gdbarch->call_dummy_stack_adjust == 0)) - fprintf_unfiltered (log, "\n\tcall_dummy_stack_adjust"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->fix_call_dummy == 0)) - fprintf_unfiltered (log, "\n\tfix_call_dummy"); - /* Skip verify of init_frame_pc_first, invalid_p == 0 */ - /* Skip verify of init_frame_pc, invalid_p == 0 */ - /* Skip verify of coerce_float_to_double, invalid_p == 0 */ - if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->get_saved_register == 0)) - fprintf_unfiltered (log, "\n\tget_saved_register"); - /* Skip verify of register_convertible, invalid_p == 0 */ - /* Skip verify of register_convert_to_virtual, invalid_p == 0 */ - /* Skip verify of register_convert_to_raw, invalid_p == 0 */ - /* Skip verify of fetch_pseudo_register, has predicate */ - /* Skip verify of store_pseudo_register, has predicate */ + /* Skip verify of deprecated_pc_in_call_dummy, has predicate */ + /* Skip verify of deprecated_init_frame_pc_first, has predicate */ + /* Skip verify of deprecated_init_frame_pc, has predicate */ + /* Skip verify of deprecated_get_saved_register, has predicate */ + /* Skip verify of deprecated_register_convertible, has predicate */ + /* Skip verify of deprecated_register_convert_to_virtual, invalid_p == 0 */ + /* Skip verify of deprecated_register_convert_to_raw, invalid_p == 0 */ + /* Skip verify of convert_register_p, invalid_p == 0 */ + /* Skip verify of register_to_value, invalid_p == 0 */ + /* Skip verify of value_to_register, invalid_p == 0 */ /* Skip verify of pointer_to_address, invalid_p == 0 */ /* Skip verify of address_to_pointer, invalid_p == 0 */ /* Skip verify of integer_to_address, has predicate */ + /* Skip verify of deprecated_pop_frame, has predicate */ + /* Skip verify of deprecated_store_struct_return, has predicate */ + /* Skip verify of return_value, has predicate */ /* Skip verify of return_value_on_stack, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->extract_return_value == 0)) - fprintf_unfiltered (log, "\n\textract_return_value"); - /* Skip verify of push_arguments, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->push_dummy_frame == 0)) - fprintf_unfiltered (log, "\n\tpush_dummy_frame"); - /* Skip verify of push_return_address, has predicate */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->pop_frame == 0)) - fprintf_unfiltered (log, "\n\tpop_frame"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->store_struct_return == 0)) - fprintf_unfiltered (log, "\n\tstore_struct_return"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->store_return_value == 0)) - fprintf_unfiltered (log, "\n\tstore_return_value"); - /* Skip verify of extract_struct_value_address, has predicate */ + /* Skip verify of extract_return_value, invalid_p == 0 */ + /* Skip verify of store_return_value, invalid_p == 0 */ /* Skip verify of use_struct_convention, invalid_p == 0 */ + /* Skip verify of deprecated_extract_struct_value_address, has predicate */ + /* Skip verify of deprecated_frame_init_saved_regs, has predicate */ + /* Skip verify of deprecated_init_extra_frame_info, has predicate */ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->frame_init_saved_regs == 0)) - fprintf_unfiltered (log, "\n\tframe_init_saved_regs"); - /* Skip verify of init_extra_frame_info, has predicate */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->skip_prologue == 0)) + && (current_gdbarch->skip_prologue == 0)) fprintf_unfiltered (log, "\n\tskip_prologue"); - /* Skip verify of prologue_frameless_p, invalid_p == 0 */ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->inner_than == 0)) + && (current_gdbarch->inner_than == 0)) fprintf_unfiltered (log, "\n\tinner_than"); - /* Skip verify of breakpoint_from_pc, invalid_p == 0 */ + if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) + && (current_gdbarch->breakpoint_from_pc == 0)) + fprintf_unfiltered (log, "\n\tbreakpoint_from_pc"); + /* Skip verify of adjust_breakpoint_address, has predicate */ /* Skip verify of memory_insert_breakpoint, invalid_p == 0 */ /* Skip verify of memory_remove_breakpoint, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->decr_pc_after_break == -1)) - fprintf_unfiltered (log, "\n\tdecr_pc_after_break"); - /* Skip verify of prepare_to_proceed, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->function_start_offset == -1)) - fprintf_unfiltered (log, "\n\tfunction_start_offset"); + /* Skip verify of decr_pc_after_break, invalid_p == 0 */ + /* Skip verify of function_start_offset, invalid_p == 0 */ /* Skip verify of remote_translate_xfer_address, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->frame_args_skip == -1)) - fprintf_unfiltered (log, "\n\tframe_args_skip"); - /* Skip verify of frameless_function_invocation, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->frame_chain == 0)) - fprintf_unfiltered (log, "\n\tframe_chain"); - /* Skip verify of frame_chain_valid, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->frame_saved_pc == 0)) - fprintf_unfiltered (log, "\n\tframe_saved_pc"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->frame_args_address == 0)) - fprintf_unfiltered (log, "\n\tframe_args_address"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->frame_locals_address == 0)) - fprintf_unfiltered (log, "\n\tframe_locals_address"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->saved_pc_after_call == 0)) - fprintf_unfiltered (log, "\n\tsaved_pc_after_call"); - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->frame_num_args == 0)) - fprintf_unfiltered (log, "\n\tframe_num_args"); - /* Skip verify of stack_align, has predicate */ - /* Skip verify of extra_stack_alignment_needed, invalid_p == 0 */ - /* Skip verify of reg_struct_has_addr, has predicate */ - /* Skip verify of save_dummy_frame_tos, has predicate */ - if (gdbarch->float_format == 0) - gdbarch->float_format = default_float_format (gdbarch); - if (gdbarch->double_format == 0) - gdbarch->double_format = default_double_format (gdbarch); - if (gdbarch->long_double_format == 0) - gdbarch->long_double_format = default_double_format (gdbarch); + /* Skip verify of frame_args_skip, invalid_p == 0 */ + /* Skip verify of deprecated_frameless_function_invocation, has predicate */ + /* Skip verify of deprecated_frame_chain, has predicate */ + /* Skip verify of deprecated_frame_chain_valid, has predicate */ + /* Skip verify of deprecated_frame_saved_pc, has predicate */ + /* Skip verify of unwind_pc, has predicate */ + /* Skip verify of unwind_sp, has predicate */ + /* Skip verify of deprecated_frame_args_address, has predicate */ + /* Skip verify of deprecated_frame_locals_address, has predicate */ + /* Skip verify of deprecated_saved_pc_after_call, has predicate */ + /* Skip verify of frame_num_args, has predicate */ + /* Skip verify of deprecated_stack_align, has predicate */ + /* Skip verify of frame_align, has predicate */ + /* Skip verify of deprecated_reg_struct_has_addr, has predicate */ + /* Skip verify of stabs_argument_has_addr, invalid_p == 0 */ + if (current_gdbarch->float_format == 0) + current_gdbarch->float_format = default_float_format (current_gdbarch); + if (current_gdbarch->double_format == 0) + current_gdbarch->double_format = default_double_format (current_gdbarch); + if (current_gdbarch->long_double_format == 0) + current_gdbarch->long_double_format = default_double_format (current_gdbarch); /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */ /* Skip verify of addr_bits_remove, invalid_p == 0 */ /* Skip verify of smash_text_address, invalid_p == 0 */ /* Skip verify of software_single_step, has predicate */ - /* Skip verify of print_insn, invalid_p == 0 */ + if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) + && (current_gdbarch->print_insn == 0)) + fprintf_unfiltered (log, "\n\tprint_insn"); /* Skip verify of skip_trampoline_code, invalid_p == 0 */ + /* Skip verify of skip_solib_resolver, invalid_p == 0 */ /* Skip verify of in_solib_call_trampoline, invalid_p == 0 */ + /* Skip verify of in_solib_return_trampoline, invalid_p == 0 */ + /* Skip verify of pc_in_sigtramp, invalid_p == 0 */ + /* Skip verify of sigtramp_start, has predicate */ + /* Skip verify of sigtramp_end, has predicate */ /* Skip verify of in_function_epilogue_p, invalid_p == 0 */ /* Skip verify of construct_inferior_arguments, invalid_p == 0 */ - /* Skip verify of dwarf2_build_frame_info, has predicate */ /* Skip verify of elf_make_msymbol_special, invalid_p == 0 */ /* Skip verify of coff_make_msymbol_special, invalid_p == 0 */ + /* Skip verify of name_of_malloc, invalid_p == 0 */ + /* Skip verify of cannot_step_breakpoint, invalid_p == 0 */ + /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0 */ + /* Skip verify of address_class_type_flags, has predicate */ + /* Skip verify of address_class_type_flags_to_name, has predicate */ + /* Skip verify of address_class_name_to_type_flags, has predicate */ + /* Skip verify of register_reggroup_p, invalid_p == 0 */ + /* Skip verify of fetch_pointer_argument, has predicate */ + /* Skip verify of regset_from_core_section, has predicate */ buf = ui_file_xstrdup (log, &dummy); make_cleanup (xfree, buf); if (strlen (buf) > 0) @@ -800,48 +755,110 @@ verify_gdbarch (struct gdbarch *gdbarch) will go away. */ void -gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) +gdbarch_dump (struct gdbarch *current_gdbarch, struct ui_file *file) { fprintf_unfiltered (file, "gdbarch_dump: GDB_MULTI_ARCH = %d\n", GDB_MULTI_ARCH); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: in_function_epilogue_p = 0x%08lx\n", - (long) current_gdbarch->in_function_epilogue_p); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: register_read = 0x%08lx\n", - (long) current_gdbarch->register_read); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: register_write = 0x%08lx\n", - (long) current_gdbarch->register_write); + fprintf_unfiltered (file, + "gdbarch_dump: convert_from_func_ptr_addr = 0x%08lx\n", + (long) current_gdbarch->convert_from_func_ptr_addr); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_frame_align_p() = %d\n", + gdbarch_frame_align_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: frame_align = 0x%08lx\n", + (long) current_gdbarch->frame_align); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_regset_from_core_section_p() = %d\n", + gdbarch_regset_from_core_section_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: regset_from_core_section = 0x%08lx\n", + (long) current_gdbarch->regset_from_core_section); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_return_value_p() = %d\n", + gdbarch_return_value_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: return_value = 0x%08lx\n", + (long) current_gdbarch->return_value); + fprintf_unfiltered (file, + "gdbarch_dump: in_function_epilogue_p = 0x%08lx\n", + (long) current_gdbarch->in_function_epilogue_p); + fprintf_unfiltered (file, + "gdbarch_dump: register_reggroup_p = 0x%08lx\n", + (long) current_gdbarch->register_reggroup_p); + fprintf_unfiltered (file, + "gdbarch_dump: stabs_argument_has_addr = 0x%08lx\n", + (long) current_gdbarch->stabs_argument_has_addr); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_pseudo_register_read_p() = %d\n", + gdbarch_pseudo_register_read_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: pseudo_register_read = 0x%08lx\n", + (long) current_gdbarch->pseudo_register_read); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_pseudo_register_write_p() = %d\n", + gdbarch_pseudo_register_write_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: pseudo_register_write = 0x%08lx\n", + (long) current_gdbarch->pseudo_register_write); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_address_class_name_to_type_flags_p() = %d\n", + gdbarch_address_class_name_to_type_flags_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: address_class_name_to_type_flags = 0x%08lx\n", + (long) current_gdbarch->address_class_name_to_type_flags); +#ifdef ADDRESS_CLASS_TYPE_FLAGS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "ADDRESS_CLASS_TYPE_FLAGS_P()", + XSTRING (ADDRESS_CLASS_TYPE_FLAGS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: ADDRESS_CLASS_TYPE_FLAGS_P() = %d\n", + ADDRESS_CLASS_TYPE_FLAGS_P ()); +#endif +#ifdef ADDRESS_CLASS_TYPE_FLAGS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "ADDRESS_CLASS_TYPE_FLAGS(byte_size, dwarf2_addr_class)", + XSTRING (ADDRESS_CLASS_TYPE_FLAGS (byte_size, dwarf2_addr_class))); + fprintf_unfiltered (file, + "gdbarch_dump: ADDRESS_CLASS_TYPE_FLAGS = <0x%08lx>\n", + (long) current_gdbarch->address_class_type_flags + /*ADDRESS_CLASS_TYPE_FLAGS ()*/); +#endif + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_address_class_type_flags_to_name_p() = %d\n", + gdbarch_address_class_type_flags_to_name_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: address_class_type_flags_to_name = 0x%08lx\n", + (long) current_gdbarch->address_class_type_flags_to_name); #ifdef ADDRESS_TO_POINTER -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "ADDRESS_TO_POINTER(type, buf, addr)", XSTRING (ADDRESS_TO_POINTER (type, buf, addr))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: ADDRESS_TO_POINTER = 0x%08lx\n", - (long) current_gdbarch->address_to_pointer - /*ADDRESS_TO_POINTER ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: ADDRESS_TO_POINTER = <0x%08lx>\n", + (long) current_gdbarch->address_to_pointer + /*ADDRESS_TO_POINTER ()*/); #endif #ifdef ADDR_BITS_REMOVE fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "ADDR_BITS_REMOVE(addr)", XSTRING (ADDR_BITS_REMOVE (addr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: ADDR_BITS_REMOVE = 0x%08lx\n", - (long) current_gdbarch->addr_bits_remove - /*ADDR_BITS_REMOVE ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: ADDR_BITS_REMOVE = <0x%08lx>\n", + (long) current_gdbarch->addr_bits_remove + /*ADDR_BITS_REMOVE ()*/); #endif + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_adjust_breakpoint_address_p() = %d\n", + gdbarch_adjust_breakpoint_address_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: adjust_breakpoint_address = 0x%08lx\n", + (long) current_gdbarch->adjust_breakpoint_address); #ifdef BELIEVE_PCC_PROMOTION fprintf_unfiltered (file, "gdbarch_dump: BELIEVE_PCC_PROMOTION # %s\n", @@ -863,48 +880,10 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: %s # %s\n", "BREAKPOINT_FROM_PC(pcptr, lenptr)", XSTRING (BREAKPOINT_FROM_PC (pcptr, lenptr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: BREAKPOINT_FROM_PC = 0x%08lx\n", - (long) current_gdbarch->breakpoint_from_pc - /*BREAKPOINT_FROM_PC ()*/); -#endif -#ifdef CALL_DUMMY_ADDRESS fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "CALL_DUMMY_ADDRESS()", - XSTRING (CALL_DUMMY_ADDRESS ())); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->call_dummy_address - /*CALL_DUMMY_ADDRESS ()*/); -#endif -#ifdef CALL_DUMMY_BREAKPOINT_OFFSET - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET # %s\n", - XSTRING (CALL_DUMMY_BREAKPOINT_OFFSET)); - if (CALL_DUMMY_BREAKPOINT_OFFSET_P) - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET = 0x%08lx\n", - (long) CALL_DUMMY_BREAKPOINT_OFFSET); -#endif -#ifdef CALL_DUMMY_BREAKPOINT_OFFSET_P - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET_P # %s\n", - XSTRING (CALL_DUMMY_BREAKPOINT_OFFSET_P)); - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET_P = %d\n", - CALL_DUMMY_BREAKPOINT_OFFSET_P); -#endif -#ifdef CALL_DUMMY_LENGTH - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_LENGTH # %s\n", - XSTRING (CALL_DUMMY_LENGTH)); - if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END || CALL_DUMMY_LOCATION == AFTER_TEXT_END) - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_LENGTH = %d\n", - CALL_DUMMY_LENGTH); + "gdbarch_dump: BREAKPOINT_FROM_PC = <0x%08lx>\n", + (long) current_gdbarch->breakpoint_from_pc + /*BREAKPOINT_FROM_PC ()*/); #endif #ifdef CALL_DUMMY_LOCATION fprintf_unfiltered (file, @@ -914,108 +893,56 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: CALL_DUMMY_LOCATION = %d\n", CALL_DUMMY_LOCATION); #endif -#ifdef CALL_DUMMY_P - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_P # %s\n", - XSTRING (CALL_DUMMY_P)); - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_P = %d\n", - CALL_DUMMY_P); -#endif -#ifdef CALL_DUMMY_STACK_ADJUST - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_STACK_ADJUST # %s\n", - XSTRING (CALL_DUMMY_STACK_ADJUST)); - if (CALL_DUMMY_STACK_ADJUST_P) - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_STACK_ADJUST = 0x%08lx\n", - (long) CALL_DUMMY_STACK_ADJUST); -#endif -#ifdef CALL_DUMMY_STACK_ADJUST_P - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_STACK_ADJUST_P # %s\n", - XSTRING (CALL_DUMMY_STACK_ADJUST_P)); - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_STACK_ADJUST_P = 0x%08lx\n", - (long) CALL_DUMMY_STACK_ADJUST_P); -#endif -#ifdef CALL_DUMMY_START_OFFSET - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_START_OFFSET # %s\n", - XSTRING (CALL_DUMMY_START_OFFSET)); - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_START_OFFSET = 0x%08lx\n", - (long) CALL_DUMMY_START_OFFSET); -#endif -#ifdef CALL_DUMMY_WORDS - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_WORDS # %s\n", - XSTRING (CALL_DUMMY_WORDS)); - fprintf_unfiltered (file, - "gdbarch_dump: CALL_DUMMY_WORDS = 0x%08lx\n", - (long) CALL_DUMMY_WORDS); -#endif #ifdef CANNOT_FETCH_REGISTER fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "CANNOT_FETCH_REGISTER(regnum)", XSTRING (CANNOT_FETCH_REGISTER (regnum))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: CANNOT_FETCH_REGISTER = 0x%08lx\n", - (long) current_gdbarch->cannot_fetch_register - /*CANNOT_FETCH_REGISTER ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: CANNOT_FETCH_REGISTER = <0x%08lx>\n", + (long) current_gdbarch->cannot_fetch_register + /*CANNOT_FETCH_REGISTER ()*/); +#endif +#ifdef CANNOT_STEP_BREAKPOINT + fprintf_unfiltered (file, + "gdbarch_dump: CANNOT_STEP_BREAKPOINT # %s\n", + XSTRING (CANNOT_STEP_BREAKPOINT)); + fprintf_unfiltered (file, + "gdbarch_dump: CANNOT_STEP_BREAKPOINT = %d\n", + CANNOT_STEP_BREAKPOINT); #endif #ifdef CANNOT_STORE_REGISTER fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "CANNOT_STORE_REGISTER(regnum)", XSTRING (CANNOT_STORE_REGISTER (regnum))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: CANNOT_STORE_REGISTER = 0x%08lx\n", - (long) current_gdbarch->cannot_store_register - /*CANNOT_STORE_REGISTER ()*/); -#endif -#ifdef COERCE_FLOAT_TO_DOUBLE fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "COERCE_FLOAT_TO_DOUBLE(formal, actual)", - XSTRING (COERCE_FLOAT_TO_DOUBLE (formal, actual))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: COERCE_FLOAT_TO_DOUBLE = 0x%08lx\n", - (long) current_gdbarch->coerce_float_to_double - /*COERCE_FLOAT_TO_DOUBLE ()*/); + "gdbarch_dump: CANNOT_STORE_REGISTER = <0x%08lx>\n", + (long) current_gdbarch->cannot_store_register + /*CANNOT_STORE_REGISTER ()*/); #endif #ifdef COFF_MAKE_MSYMBOL_SPECIAL -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "COFF_MAKE_MSYMBOL_SPECIAL(val, msym)", XSTRING (COFF_MAKE_MSYMBOL_SPECIAL (val, msym))); + fprintf_unfiltered (file, + "gdbarch_dump: COFF_MAKE_MSYMBOL_SPECIAL = <0x%08lx>\n", + (long) current_gdbarch->coff_make_msymbol_special + /*COFF_MAKE_MSYMBOL_SPECIAL ()*/); #endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: COFF_MAKE_MSYMBOL_SPECIAL = 0x%08lx\n", - (long) current_gdbarch->coff_make_msymbol_special - /*COFF_MAKE_MSYMBOL_SPECIAL ()*/); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: construct_inferior_arguments = 0x%08lx\n", - (long) current_gdbarch->construct_inferior_arguments); -#ifdef CONVERT_FROM_FUNC_PTR_ADDR + fprintf_unfiltered (file, + "gdbarch_dump: construct_inferior_arguments = 0x%08lx\n", + (long) current_gdbarch->construct_inferior_arguments); +#ifdef CONVERT_REGISTER_P fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "CONVERT_FROM_FUNC_PTR_ADDR(addr)", - XSTRING (CONVERT_FROM_FUNC_PTR_ADDR (addr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: CONVERT_FROM_FUNC_PTR_ADDR = 0x%08lx\n", - (long) current_gdbarch->convert_from_func_ptr_addr - /*CONVERT_FROM_FUNC_PTR_ADDR ()*/); + "CONVERT_REGISTER_P(regnum, type)", + XSTRING (CONVERT_REGISTER_P (regnum, type))); + fprintf_unfiltered (file, + "gdbarch_dump: CONVERT_REGISTER_P = <0x%08lx>\n", + (long) current_gdbarch->convert_register_p + /*CONVERT_REGISTER_P ()*/); #endif #ifdef DECR_PC_AFTER_BREAK fprintf_unfiltered (file, @@ -1025,141 +952,809 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: DECR_PC_AFTER_BREAK = %ld\n", (long) DECR_PC_AFTER_BREAK); #endif -#ifdef DO_REGISTERS_INFO -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ +#ifdef DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET # %s\n", + XSTRING (DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET = %ld\n", + (long) DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET); +#endif +#ifdef DEPRECATED_CALL_DUMMY_LENGTH + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_LENGTH # %s\n", + XSTRING (DEPRECATED_CALL_DUMMY_LENGTH)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_LENGTH = %d\n", + DEPRECATED_CALL_DUMMY_LENGTH); +#endif +#ifdef DEPRECATED_CALL_DUMMY_START_OFFSET + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_START_OFFSET # %s\n", + XSTRING (DEPRECATED_CALL_DUMMY_START_OFFSET)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_START_OFFSET = %ld\n", + (long) DEPRECATED_CALL_DUMMY_START_OFFSET); +#endif +#ifdef DEPRECATED_CALL_DUMMY_WORDS + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_WORDS # %s\n", + XSTRING (DEPRECATED_CALL_DUMMY_WORDS)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_CALL_DUMMY_WORDS = 0x%08lx\n", + (long) DEPRECATED_CALL_DUMMY_WORDS); +#endif +#ifdef DEPRECATED_DO_REGISTERS_INFO_P fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "DO_REGISTERS_INFO(reg_nr, fpregs)", - XSTRING (DO_REGISTERS_INFO (reg_nr, fpregs))); + "DEPRECATED_DO_REGISTERS_INFO_P()", + XSTRING (DEPRECATED_DO_REGISTERS_INFO_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_DO_REGISTERS_INFO_P() = %d\n", + DEPRECATED_DO_REGISTERS_INFO_P ()); #endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: DO_REGISTERS_INFO = 0x%08lx\n", - (long) current_gdbarch->do_registers_info - /*DO_REGISTERS_INFO ()*/); -#endif -#ifdef DWARF2_BUILD_FRAME_INFO -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ +#ifdef DEPRECATED_DO_REGISTERS_INFO fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "DWARF2_BUILD_FRAME_INFO(objfile)", - XSTRING (DWARF2_BUILD_FRAME_INFO (objfile))); + "DEPRECATED_DO_REGISTERS_INFO(reg_nr, fpregs)", + XSTRING (DEPRECATED_DO_REGISTERS_INFO (reg_nr, fpregs))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_DO_REGISTERS_INFO = <0x%08lx>\n", + (long) current_gdbarch->deprecated_do_registers_info + /*DEPRECATED_DO_REGISTERS_INFO ()*/); #endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: DWARF2_BUILD_FRAME_INFO = 0x%08lx\n", - (long) current_gdbarch->dwarf2_build_frame_info - /*DWARF2_BUILD_FRAME_INFO ()*/); +#ifdef DEPRECATED_DUMMY_WRITE_SP_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_DUMMY_WRITE_SP_P()", + XSTRING (DEPRECATED_DUMMY_WRITE_SP_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_DUMMY_WRITE_SP_P() = %d\n", + DEPRECATED_DUMMY_WRITE_SP_P ()); +#endif +#ifdef DEPRECATED_DUMMY_WRITE_SP + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_DUMMY_WRITE_SP(val)", + XSTRING (DEPRECATED_DUMMY_WRITE_SP (val))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_DUMMY_WRITE_SP = <0x%08lx>\n", + (long) current_gdbarch->deprecated_dummy_write_sp + /*DEPRECATED_DUMMY_WRITE_SP ()*/); +#endif +#ifdef DEPRECATED_EXTRACT_RETURN_VALUE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_EXTRACT_RETURN_VALUE(type, regbuf, valbuf)", + XSTRING (DEPRECATED_EXTRACT_RETURN_VALUE (type, regbuf, valbuf))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_EXTRACT_RETURN_VALUE = <0x%08lx>\n", + (long) current_gdbarch->deprecated_extract_return_value + /*DEPRECATED_EXTRACT_RETURN_VALUE ()*/); +#endif +#ifdef DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P()", + XSTRING (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P() = %d\n", + DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ()); +#endif +#ifdef DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(regcache)", + XSTRING (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (regcache))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS = <0x%08lx>\n", + (long) current_gdbarch->deprecated_extract_struct_value_address + /*DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS ()*/); +#endif +#ifdef DEPRECATED_FIX_CALL_DUMMY_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FIX_CALL_DUMMY_P()", + XSTRING (DEPRECATED_FIX_CALL_DUMMY_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FIX_CALL_DUMMY_P() = %d\n", + DEPRECATED_FIX_CALL_DUMMY_P ()); +#endif +#ifdef DEPRECATED_FIX_CALL_DUMMY + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, type, gcc_p)", + XSTRING (DEPRECATED_FIX_CALL_DUMMY (dummy, pc, fun, nargs, args, type, gcc_p))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FIX_CALL_DUMMY = <0x%08lx>\n", + (long) current_gdbarch->deprecated_fix_call_dummy + /*DEPRECATED_FIX_CALL_DUMMY ()*/); +#endif +#ifdef DEPRECATED_FP_REGNUM + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FP_REGNUM # %s\n", + XSTRING (DEPRECATED_FP_REGNUM)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FP_REGNUM = %d\n", + DEPRECATED_FP_REGNUM); +#endif +#ifdef DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P()", + XSTRING (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P() = %d\n", + DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P ()); +#endif +#ifdef DEPRECATED_FRAMELESS_FUNCTION_INVOCATION + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAMELESS_FUNCTION_INVOCATION(fi)", + XSTRING (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION (fi))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAMELESS_FUNCTION_INVOCATION = <0x%08lx>\n", + (long) current_gdbarch->deprecated_frameless_function_invocation + /*DEPRECATED_FRAMELESS_FUNCTION_INVOCATION ()*/); +#endif +#ifdef DEPRECATED_FRAME_ARGS_ADDRESS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_ARGS_ADDRESS_P()", + XSTRING (DEPRECATED_FRAME_ARGS_ADDRESS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_ARGS_ADDRESS_P() = %d\n", + DEPRECATED_FRAME_ARGS_ADDRESS_P ()); +#endif +#ifdef DEPRECATED_FRAME_ARGS_ADDRESS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_ARGS_ADDRESS(fi)", + XSTRING (DEPRECATED_FRAME_ARGS_ADDRESS (fi))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_ARGS_ADDRESS = <0x%08lx>\n", + (long) current_gdbarch->deprecated_frame_args_address + /*DEPRECATED_FRAME_ARGS_ADDRESS ()*/); +#endif +#ifdef DEPRECATED_FRAME_CHAIN_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_CHAIN_P()", + XSTRING (DEPRECATED_FRAME_CHAIN_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_CHAIN_P() = %d\n", + DEPRECATED_FRAME_CHAIN_P ()); +#endif +#ifdef DEPRECATED_FRAME_CHAIN + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_CHAIN(frame)", + XSTRING (DEPRECATED_FRAME_CHAIN (frame))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_CHAIN = <0x%08lx>\n", + (long) current_gdbarch->deprecated_frame_chain + /*DEPRECATED_FRAME_CHAIN ()*/); +#endif +#ifdef DEPRECATED_FRAME_CHAIN_VALID_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_CHAIN_VALID_P()", + XSTRING (DEPRECATED_FRAME_CHAIN_VALID_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_CHAIN_VALID_P() = %d\n", + DEPRECATED_FRAME_CHAIN_VALID_P ()); +#endif +#ifdef DEPRECATED_FRAME_CHAIN_VALID + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_CHAIN_VALID(chain, thisframe)", + XSTRING (DEPRECATED_FRAME_CHAIN_VALID (chain, thisframe))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_CHAIN_VALID = <0x%08lx>\n", + (long) current_gdbarch->deprecated_frame_chain_valid + /*DEPRECATED_FRAME_CHAIN_VALID ()*/); +#endif +#ifdef DEPRECATED_FRAME_INIT_SAVED_REGS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_INIT_SAVED_REGS_P()", + XSTRING (DEPRECATED_FRAME_INIT_SAVED_REGS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_INIT_SAVED_REGS_P() = %d\n", + DEPRECATED_FRAME_INIT_SAVED_REGS_P ()); +#endif +#ifdef DEPRECATED_FRAME_INIT_SAVED_REGS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_INIT_SAVED_REGS(frame)", + XSTRING (DEPRECATED_FRAME_INIT_SAVED_REGS (frame))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_INIT_SAVED_REGS = <0x%08lx>\n", + (long) current_gdbarch->deprecated_frame_init_saved_regs + /*DEPRECATED_FRAME_INIT_SAVED_REGS ()*/); +#endif +#ifdef DEPRECATED_FRAME_LOCALS_ADDRESS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_LOCALS_ADDRESS_P()", + XSTRING (DEPRECATED_FRAME_LOCALS_ADDRESS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_LOCALS_ADDRESS_P() = %d\n", + DEPRECATED_FRAME_LOCALS_ADDRESS_P ()); +#endif +#ifdef DEPRECATED_FRAME_LOCALS_ADDRESS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_LOCALS_ADDRESS(fi)", + XSTRING (DEPRECATED_FRAME_LOCALS_ADDRESS (fi))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_LOCALS_ADDRESS = <0x%08lx>\n", + (long) current_gdbarch->deprecated_frame_locals_address + /*DEPRECATED_FRAME_LOCALS_ADDRESS ()*/); +#endif +#ifdef DEPRECATED_FRAME_SAVED_PC_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_SAVED_PC_P()", + XSTRING (DEPRECATED_FRAME_SAVED_PC_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_SAVED_PC_P() = %d\n", + DEPRECATED_FRAME_SAVED_PC_P ()); +#endif +#ifdef DEPRECATED_FRAME_SAVED_PC + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_FRAME_SAVED_PC(fi)", + XSTRING (DEPRECATED_FRAME_SAVED_PC (fi))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_FRAME_SAVED_PC = <0x%08lx>\n", + (long) current_gdbarch->deprecated_frame_saved_pc + /*DEPRECATED_FRAME_SAVED_PC ()*/); +#endif +#ifdef DEPRECATED_GET_SAVED_REGISTER_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_GET_SAVED_REGISTER_P()", + XSTRING (DEPRECATED_GET_SAVED_REGISTER_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_GET_SAVED_REGISTER_P() = %d\n", + DEPRECATED_GET_SAVED_REGISTER_P ()); +#endif +#ifdef DEPRECATED_GET_SAVED_REGISTER + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval)", + XSTRING (DEPRECATED_GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_GET_SAVED_REGISTER = <0x%08lx>\n", + (long) current_gdbarch->deprecated_get_saved_register + /*DEPRECATED_GET_SAVED_REGISTER ()*/); +#endif +#ifdef DEPRECATED_INIT_EXTRA_FRAME_INFO_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_INIT_EXTRA_FRAME_INFO_P()", + XSTRING (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_INIT_EXTRA_FRAME_INFO_P() = %d\n", + DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()); +#endif +#ifdef DEPRECATED_INIT_EXTRA_FRAME_INFO + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_INIT_EXTRA_FRAME_INFO(fromleaf, frame)", + XSTRING (DEPRECATED_INIT_EXTRA_FRAME_INFO (fromleaf, frame))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_INIT_EXTRA_FRAME_INFO = <0x%08lx>\n", + (long) current_gdbarch->deprecated_init_extra_frame_info + /*DEPRECATED_INIT_EXTRA_FRAME_INFO ()*/); +#endif +#ifdef DEPRECATED_INIT_FRAME_PC_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_INIT_FRAME_PC_P()", + XSTRING (DEPRECATED_INIT_FRAME_PC_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_INIT_FRAME_PC_P() = %d\n", + DEPRECATED_INIT_FRAME_PC_P ()); +#endif +#ifdef DEPRECATED_INIT_FRAME_PC + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_INIT_FRAME_PC(fromleaf, prev)", + XSTRING (DEPRECATED_INIT_FRAME_PC (fromleaf, prev))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_INIT_FRAME_PC = <0x%08lx>\n", + (long) current_gdbarch->deprecated_init_frame_pc + /*DEPRECATED_INIT_FRAME_PC ()*/); +#endif +#ifdef DEPRECATED_INIT_FRAME_PC_FIRST_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_INIT_FRAME_PC_FIRST_P()", + XSTRING (DEPRECATED_INIT_FRAME_PC_FIRST_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_INIT_FRAME_PC_FIRST_P() = %d\n", + DEPRECATED_INIT_FRAME_PC_FIRST_P ()); +#endif +#ifdef DEPRECATED_INIT_FRAME_PC_FIRST + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_INIT_FRAME_PC_FIRST(fromleaf, prev)", + XSTRING (DEPRECATED_INIT_FRAME_PC_FIRST (fromleaf, prev))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_INIT_FRAME_PC_FIRST = <0x%08lx>\n", + (long) current_gdbarch->deprecated_init_frame_pc_first + /*DEPRECATED_INIT_FRAME_PC_FIRST ()*/); +#endif +#ifdef DEPRECATED_MAX_REGISTER_RAW_SIZE_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_MAX_REGISTER_RAW_SIZE_P()", + XSTRING (DEPRECATED_MAX_REGISTER_RAW_SIZE_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_MAX_REGISTER_RAW_SIZE_P() = %d\n", + DEPRECATED_MAX_REGISTER_RAW_SIZE_P ()); +#endif +#ifdef DEPRECATED_MAX_REGISTER_RAW_SIZE + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_MAX_REGISTER_RAW_SIZE # %s\n", + XSTRING (DEPRECATED_MAX_REGISTER_RAW_SIZE)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_MAX_REGISTER_RAW_SIZE = %d\n", + DEPRECATED_MAX_REGISTER_RAW_SIZE); +#endif +#ifdef DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P()", + XSTRING (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P() = %d\n", + DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P ()); +#endif +#ifdef DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE # %s\n", + XSTRING (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE = %d\n", + DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE); +#endif +#ifdef DEPRECATED_PC_IN_CALL_DUMMY_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PC_IN_CALL_DUMMY_P()", + XSTRING (DEPRECATED_PC_IN_CALL_DUMMY_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PC_IN_CALL_DUMMY_P() = %d\n", + DEPRECATED_PC_IN_CALL_DUMMY_P ()); +#endif +#ifdef DEPRECATED_PC_IN_CALL_DUMMY + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PC_IN_CALL_DUMMY(pc, sp, frame_address)", + XSTRING (DEPRECATED_PC_IN_CALL_DUMMY (pc, sp, frame_address))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PC_IN_CALL_DUMMY = <0x%08lx>\n", + (long) current_gdbarch->deprecated_pc_in_call_dummy + /*DEPRECATED_PC_IN_CALL_DUMMY ()*/); +#endif +#ifdef DEPRECATED_POP_FRAME_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_POP_FRAME_P()", + XSTRING (DEPRECATED_POP_FRAME_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_POP_FRAME_P() = %d\n", + DEPRECATED_POP_FRAME_P ()); +#endif +#ifdef DEPRECATED_POP_FRAME + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_POP_FRAME(-)", + XSTRING (DEPRECATED_POP_FRAME (-))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_POP_FRAME = <0x%08lx>\n", + (long) current_gdbarch->deprecated_pop_frame + /*DEPRECATED_POP_FRAME ()*/); +#endif +#ifdef DEPRECATED_PUSH_ARGUMENTS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PUSH_ARGUMENTS_P()", + XSTRING (DEPRECATED_PUSH_ARGUMENTS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PUSH_ARGUMENTS_P() = %d\n", + DEPRECATED_PUSH_ARGUMENTS_P ()); +#endif +#ifdef DEPRECATED_PUSH_ARGUMENTS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr)", + XSTRING (DEPRECATED_PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PUSH_ARGUMENTS = <0x%08lx>\n", + (long) current_gdbarch->deprecated_push_arguments + /*DEPRECATED_PUSH_ARGUMENTS ()*/); +#endif +#ifdef DEPRECATED_PUSH_DUMMY_FRAME_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PUSH_DUMMY_FRAME_P()", + XSTRING (DEPRECATED_PUSH_DUMMY_FRAME_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PUSH_DUMMY_FRAME_P() = %d\n", + DEPRECATED_PUSH_DUMMY_FRAME_P ()); +#endif +#ifdef DEPRECATED_PUSH_DUMMY_FRAME + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PUSH_DUMMY_FRAME(-)", + XSTRING (DEPRECATED_PUSH_DUMMY_FRAME (-))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PUSH_DUMMY_FRAME = <0x%08lx>\n", + (long) current_gdbarch->deprecated_push_dummy_frame + /*DEPRECATED_PUSH_DUMMY_FRAME ()*/); +#endif +#ifdef DEPRECATED_PUSH_RETURN_ADDRESS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PUSH_RETURN_ADDRESS_P()", + XSTRING (DEPRECATED_PUSH_RETURN_ADDRESS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PUSH_RETURN_ADDRESS_P() = %d\n", + DEPRECATED_PUSH_RETURN_ADDRESS_P ()); +#endif +#ifdef DEPRECATED_PUSH_RETURN_ADDRESS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_PUSH_RETURN_ADDRESS(pc, sp)", + XSTRING (DEPRECATED_PUSH_RETURN_ADDRESS (pc, sp))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_PUSH_RETURN_ADDRESS = <0x%08lx>\n", + (long) current_gdbarch->deprecated_push_return_address + /*DEPRECATED_PUSH_RETURN_ADDRESS ()*/); +#endif +#ifdef DEPRECATED_REGISTER_BYTE_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_BYTE_P()", + XSTRING (DEPRECATED_REGISTER_BYTE_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_BYTE_P() = %d\n", + DEPRECATED_REGISTER_BYTE_P ()); +#endif +#ifdef DEPRECATED_REGISTER_BYTE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_BYTE(reg_nr)", + XSTRING (DEPRECATED_REGISTER_BYTE (reg_nr))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_BYTE = <0x%08lx>\n", + (long) current_gdbarch->deprecated_register_byte + /*DEPRECATED_REGISTER_BYTE ()*/); +#endif +#ifdef DEPRECATED_REGISTER_BYTES + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_BYTES # %s\n", + XSTRING (DEPRECATED_REGISTER_BYTES)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_BYTES = %d\n", + DEPRECATED_REGISTER_BYTES); +#endif +#ifdef DEPRECATED_REGISTER_CONVERTIBLE_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_CONVERTIBLE_P()", + XSTRING (DEPRECATED_REGISTER_CONVERTIBLE_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_CONVERTIBLE_P() = %d\n", + DEPRECATED_REGISTER_CONVERTIBLE_P ()); +#endif +#ifdef DEPRECATED_REGISTER_CONVERTIBLE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_CONVERTIBLE(nr)", + XSTRING (DEPRECATED_REGISTER_CONVERTIBLE (nr))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_CONVERTIBLE = <0x%08lx>\n", + (long) current_gdbarch->deprecated_register_convertible + /*DEPRECATED_REGISTER_CONVERTIBLE ()*/); +#endif +#ifdef DEPRECATED_REGISTER_CONVERT_TO_RAW + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_CONVERT_TO_RAW(type, regnum, from, to)", + XSTRING (DEPRECATED_REGISTER_CONVERT_TO_RAW (type, regnum, from, to))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_CONVERT_TO_RAW = <0x%08lx>\n", + (long) current_gdbarch->deprecated_register_convert_to_raw + /*DEPRECATED_REGISTER_CONVERT_TO_RAW ()*/); +#endif +#ifdef DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to)", + XSTRING (DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL = <0x%08lx>\n", + (long) current_gdbarch->deprecated_register_convert_to_virtual + /*DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL ()*/); +#endif +#ifdef DEPRECATED_REGISTER_RAW_SIZE_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_RAW_SIZE_P()", + XSTRING (DEPRECATED_REGISTER_RAW_SIZE_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_RAW_SIZE_P() = %d\n", + DEPRECATED_REGISTER_RAW_SIZE_P ()); +#endif +#ifdef DEPRECATED_REGISTER_RAW_SIZE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_RAW_SIZE(reg_nr)", + XSTRING (DEPRECATED_REGISTER_RAW_SIZE (reg_nr))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_RAW_SIZE = <0x%08lx>\n", + (long) current_gdbarch->deprecated_register_raw_size + /*DEPRECATED_REGISTER_RAW_SIZE ()*/); +#endif +#ifdef DEPRECATED_REGISTER_SIZE + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_SIZE # %s\n", + XSTRING (DEPRECATED_REGISTER_SIZE)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_SIZE = %d\n", + DEPRECATED_REGISTER_SIZE); +#endif +#ifdef DEPRECATED_REGISTER_VIRTUAL_SIZE_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_VIRTUAL_SIZE_P()", + XSTRING (DEPRECATED_REGISTER_VIRTUAL_SIZE_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_VIRTUAL_SIZE_P() = %d\n", + DEPRECATED_REGISTER_VIRTUAL_SIZE_P ()); +#endif +#ifdef DEPRECATED_REGISTER_VIRTUAL_SIZE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_VIRTUAL_SIZE(reg_nr)", + XSTRING (DEPRECATED_REGISTER_VIRTUAL_SIZE (reg_nr))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_VIRTUAL_SIZE = <0x%08lx>\n", + (long) current_gdbarch->deprecated_register_virtual_size + /*DEPRECATED_REGISTER_VIRTUAL_SIZE ()*/); +#endif +#ifdef DEPRECATED_REGISTER_VIRTUAL_TYPE_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_VIRTUAL_TYPE_P()", + XSTRING (DEPRECATED_REGISTER_VIRTUAL_TYPE_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_VIRTUAL_TYPE_P() = %d\n", + DEPRECATED_REGISTER_VIRTUAL_TYPE_P ()); +#endif +#ifdef DEPRECATED_REGISTER_VIRTUAL_TYPE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REGISTER_VIRTUAL_TYPE(reg_nr)", + XSTRING (DEPRECATED_REGISTER_VIRTUAL_TYPE (reg_nr))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REGISTER_VIRTUAL_TYPE = <0x%08lx>\n", + (long) current_gdbarch->deprecated_register_virtual_type + /*DEPRECATED_REGISTER_VIRTUAL_TYPE ()*/); +#endif +#ifdef DEPRECATED_REG_STRUCT_HAS_ADDR_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REG_STRUCT_HAS_ADDR_P()", + XSTRING (DEPRECATED_REG_STRUCT_HAS_ADDR_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REG_STRUCT_HAS_ADDR_P() = %d\n", + DEPRECATED_REG_STRUCT_HAS_ADDR_P ()); +#endif +#ifdef DEPRECATED_REG_STRUCT_HAS_ADDR + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_REG_STRUCT_HAS_ADDR(gcc_p, type)", + XSTRING (DEPRECATED_REG_STRUCT_HAS_ADDR (gcc_p, type))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_REG_STRUCT_HAS_ADDR = <0x%08lx>\n", + (long) current_gdbarch->deprecated_reg_struct_has_addr + /*DEPRECATED_REG_STRUCT_HAS_ADDR ()*/); +#endif +#ifdef DEPRECATED_SAVED_PC_AFTER_CALL_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_SAVED_PC_AFTER_CALL_P()", + XSTRING (DEPRECATED_SAVED_PC_AFTER_CALL_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_SAVED_PC_AFTER_CALL_P() = %d\n", + DEPRECATED_SAVED_PC_AFTER_CALL_P ()); +#endif +#ifdef DEPRECATED_SAVED_PC_AFTER_CALL + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_SAVED_PC_AFTER_CALL(frame)", + XSTRING (DEPRECATED_SAVED_PC_AFTER_CALL (frame))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_SAVED_PC_AFTER_CALL = <0x%08lx>\n", + (long) current_gdbarch->deprecated_saved_pc_after_call + /*DEPRECATED_SAVED_PC_AFTER_CALL ()*/); +#endif +#ifdef DEPRECATED_SAVE_DUMMY_FRAME_TOS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_SAVE_DUMMY_FRAME_TOS_P()", + XSTRING (DEPRECATED_SAVE_DUMMY_FRAME_TOS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_SAVE_DUMMY_FRAME_TOS_P() = %d\n", + DEPRECATED_SAVE_DUMMY_FRAME_TOS_P ()); +#endif +#ifdef DEPRECATED_SAVE_DUMMY_FRAME_TOS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_SAVE_DUMMY_FRAME_TOS(sp)", + XSTRING (DEPRECATED_SAVE_DUMMY_FRAME_TOS (sp))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_SAVE_DUMMY_FRAME_TOS = <0x%08lx>\n", + (long) current_gdbarch->deprecated_save_dummy_frame_tos + /*DEPRECATED_SAVE_DUMMY_FRAME_TOS ()*/); +#endif +#ifdef DEPRECATED_SIZEOF_CALL_DUMMY_WORDS + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_SIZEOF_CALL_DUMMY_WORDS # %s\n", + XSTRING (DEPRECATED_SIZEOF_CALL_DUMMY_WORDS)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_SIZEOF_CALL_DUMMY_WORDS = %d\n", + DEPRECATED_SIZEOF_CALL_DUMMY_WORDS); +#endif +#ifdef DEPRECATED_STACK_ALIGN_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_STACK_ALIGN_P()", + XSTRING (DEPRECATED_STACK_ALIGN_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_STACK_ALIGN_P() = %d\n", + DEPRECATED_STACK_ALIGN_P ()); +#endif +#ifdef DEPRECATED_STACK_ALIGN + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_STACK_ALIGN(sp)", + XSTRING (DEPRECATED_STACK_ALIGN (sp))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_STACK_ALIGN = <0x%08lx>\n", + (long) current_gdbarch->deprecated_stack_align + /*DEPRECATED_STACK_ALIGN ()*/); +#endif +#ifdef DEPRECATED_STORE_RETURN_VALUE + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_STORE_RETURN_VALUE(type, valbuf)", + XSTRING (DEPRECATED_STORE_RETURN_VALUE (type, valbuf))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_STORE_RETURN_VALUE = <0x%08lx>\n", + (long) current_gdbarch->deprecated_store_return_value + /*DEPRECATED_STORE_RETURN_VALUE ()*/); +#endif +#ifdef DEPRECATED_STORE_STRUCT_RETURN_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_STORE_STRUCT_RETURN_P()", + XSTRING (DEPRECATED_STORE_STRUCT_RETURN_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_STORE_STRUCT_RETURN_P() = %d\n", + DEPRECATED_STORE_STRUCT_RETURN_P ()); +#endif +#ifdef DEPRECATED_STORE_STRUCT_RETURN + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_STORE_STRUCT_RETURN(addr, sp)", + XSTRING (DEPRECATED_STORE_STRUCT_RETURN (addr, sp))); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_STORE_STRUCT_RETURN = <0x%08lx>\n", + (long) current_gdbarch->deprecated_store_struct_return + /*DEPRECATED_STORE_STRUCT_RETURN ()*/); +#endif +#ifdef DEPRECATED_TARGET_READ_FP_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_TARGET_READ_FP_P()", + XSTRING (DEPRECATED_TARGET_READ_FP_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_TARGET_READ_FP_P() = %d\n", + DEPRECATED_TARGET_READ_FP_P ()); +#endif +#ifdef DEPRECATED_TARGET_READ_FP + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "DEPRECATED_TARGET_READ_FP()", + XSTRING (DEPRECATED_TARGET_READ_FP ())); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_TARGET_READ_FP = <0x%08lx>\n", + (long) current_gdbarch->deprecated_target_read_fp + /*DEPRECATED_TARGET_READ_FP ()*/); +#endif +#ifdef DEPRECATED_USE_GENERIC_DUMMY_FRAMES + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_USE_GENERIC_DUMMY_FRAMES # %s\n", + XSTRING (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)); + fprintf_unfiltered (file, + "gdbarch_dump: DEPRECATED_USE_GENERIC_DUMMY_FRAMES = %d\n", + DEPRECATED_USE_GENERIC_DUMMY_FRAMES); #endif #ifdef DWARF2_REG_TO_REGNUM fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "DWARF2_REG_TO_REGNUM(dwarf2_regnr)", XSTRING (DWARF2_REG_TO_REGNUM (dwarf2_regnr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: DWARF2_REG_TO_REGNUM = 0x%08lx\n", - (long) current_gdbarch->dwarf2_reg_to_regnum - /*DWARF2_REG_TO_REGNUM ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: DWARF2_REG_TO_REGNUM = <0x%08lx>\n", + (long) current_gdbarch->dwarf2_reg_to_regnum + /*DWARF2_REG_TO_REGNUM ()*/); #endif #ifdef DWARF_REG_TO_REGNUM fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "DWARF_REG_TO_REGNUM(dwarf_regnr)", XSTRING (DWARF_REG_TO_REGNUM (dwarf_regnr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: DWARF_REG_TO_REGNUM = 0x%08lx\n", - (long) current_gdbarch->dwarf_reg_to_regnum - /*DWARF_REG_TO_REGNUM ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: DWARF_REG_TO_REGNUM = <0x%08lx>\n", + (long) current_gdbarch->dwarf_reg_to_regnum + /*DWARF_REG_TO_REGNUM ()*/); #endif #ifdef ECOFF_REG_TO_REGNUM fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "ECOFF_REG_TO_REGNUM(ecoff_regnr)", XSTRING (ECOFF_REG_TO_REGNUM (ecoff_regnr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: ECOFF_REG_TO_REGNUM = 0x%08lx\n", - (long) current_gdbarch->ecoff_reg_to_regnum - /*ECOFF_REG_TO_REGNUM ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: ECOFF_REG_TO_REGNUM = <0x%08lx>\n", + (long) current_gdbarch->ecoff_reg_to_regnum + /*ECOFF_REG_TO_REGNUM ()*/); #endif #ifdef ELF_MAKE_MSYMBOL_SPECIAL -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "ELF_MAKE_MSYMBOL_SPECIAL(sym, msym)", XSTRING (ELF_MAKE_MSYMBOL_SPECIAL (sym, msym))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: ELF_MAKE_MSYMBOL_SPECIAL = 0x%08lx\n", - (long) current_gdbarch->elf_make_msymbol_special - /*ELF_MAKE_MSYMBOL_SPECIAL ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: ELF_MAKE_MSYMBOL_SPECIAL = <0x%08lx>\n", + (long) current_gdbarch->elf_make_msymbol_special + /*ELF_MAKE_MSYMBOL_SPECIAL ()*/); #endif #ifdef EXTRACT_RETURN_VALUE -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "EXTRACT_RETURN_VALUE(type, regbuf, valbuf)", - XSTRING (EXTRACT_RETURN_VALUE (type, regbuf, valbuf))); + "EXTRACT_RETURN_VALUE(type, regcache, valbuf)", + XSTRING (EXTRACT_RETURN_VALUE (type, regcache, valbuf))); + fprintf_unfiltered (file, + "gdbarch_dump: EXTRACT_RETURN_VALUE = <0x%08lx>\n", + (long) current_gdbarch->extract_return_value + /*EXTRACT_RETURN_VALUE ()*/); #endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: EXTRACT_RETURN_VALUE = 0x%08lx\n", - (long) current_gdbarch->extract_return_value - /*EXTRACT_RETURN_VALUE ()*/); -#endif -#ifdef EXTRACT_STRUCT_VALUE_ADDRESS +#ifdef FETCH_POINTER_ARGUMENT_P fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "EXTRACT_STRUCT_VALUE_ADDRESS(regbuf)", - XSTRING (EXTRACT_STRUCT_VALUE_ADDRESS (regbuf))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: EXTRACT_STRUCT_VALUE_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->extract_struct_value_address - /*EXTRACT_STRUCT_VALUE_ADDRESS ()*/); -#endif -#ifdef EXTRA_STACK_ALIGNMENT_NEEDED + "FETCH_POINTER_ARGUMENT_P()", + XSTRING (FETCH_POINTER_ARGUMENT_P ())); fprintf_unfiltered (file, - "gdbarch_dump: EXTRA_STACK_ALIGNMENT_NEEDED # %s\n", - XSTRING (EXTRA_STACK_ALIGNMENT_NEEDED)); - fprintf_unfiltered (file, - "gdbarch_dump: EXTRA_STACK_ALIGNMENT_NEEDED = %d\n", - EXTRA_STACK_ALIGNMENT_NEEDED); + "gdbarch_dump: FETCH_POINTER_ARGUMENT_P() = %d\n", + FETCH_POINTER_ARGUMENT_P ()); #endif -#ifdef FETCH_PSEUDO_REGISTER -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ +#ifdef FETCH_POINTER_ARGUMENT fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "FETCH_PSEUDO_REGISTER(regnum)", - XSTRING (FETCH_PSEUDO_REGISTER (regnum))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FETCH_PSEUDO_REGISTER = 0x%08lx\n", - (long) current_gdbarch->fetch_pseudo_register - /*FETCH_PSEUDO_REGISTER ()*/); -#endif -#ifdef FIX_CALL_DUMMY -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ + "FETCH_POINTER_ARGUMENT(frame, argi, type)", + XSTRING (FETCH_POINTER_ARGUMENT (frame, argi, type))); fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, type, gcc_p)", - XSTRING (FIX_CALL_DUMMY (dummy, pc, fun, nargs, args, type, gcc_p))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FIX_CALL_DUMMY = 0x%08lx\n", - (long) current_gdbarch->fix_call_dummy - /*FIX_CALL_DUMMY ()*/); + "gdbarch_dump: FETCH_POINTER_ARGUMENT = <0x%08lx>\n", + (long) current_gdbarch->fetch_pointer_argument + /*FETCH_POINTER_ARGUMENT ()*/); #endif #ifdef FP0_REGNUM fprintf_unfiltered (file, @@ -1169,36 +1764,6 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: FP0_REGNUM = %d\n", FP0_REGNUM); #endif -#ifdef FP_REGNUM - fprintf_unfiltered (file, - "gdbarch_dump: FP_REGNUM # %s\n", - XSTRING (FP_REGNUM)); - fprintf_unfiltered (file, - "gdbarch_dump: FP_REGNUM = %d\n", - FP_REGNUM); -#endif -#ifdef FRAMELESS_FUNCTION_INVOCATION - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "FRAMELESS_FUNCTION_INVOCATION(fi)", - XSTRING (FRAMELESS_FUNCTION_INVOCATION (fi))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAMELESS_FUNCTION_INVOCATION = 0x%08lx\n", - (long) current_gdbarch->frameless_function_invocation - /*FRAMELESS_FUNCTION_INVOCATION ()*/); -#endif -#ifdef FRAME_ARGS_ADDRESS - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "FRAME_ARGS_ADDRESS(fi)", - XSTRING (FRAME_ARGS_ADDRESS (fi))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAME_ARGS_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->frame_args_address - /*FRAME_ARGS_ADDRESS ()*/); -#endif #ifdef FRAME_ARGS_SKIP fprintf_unfiltered (file, "gdbarch_dump: FRAME_ARGS_SKIP # %s\n", @@ -1207,74 +1772,32 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: FRAME_ARGS_SKIP = %ld\n", (long) FRAME_ARGS_SKIP); #endif -#ifdef FRAME_CHAIN +#ifdef FRAME_NUM_ARGS_P fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "FRAME_CHAIN(frame)", - XSTRING (FRAME_CHAIN (frame))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAME_CHAIN = 0x%08lx\n", - (long) current_gdbarch->frame_chain - /*FRAME_CHAIN ()*/); -#endif -#ifdef FRAME_CHAIN_VALID + "FRAME_NUM_ARGS_P()", + XSTRING (FRAME_NUM_ARGS_P ())); fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "FRAME_CHAIN_VALID(chain, thisframe)", - XSTRING (FRAME_CHAIN_VALID (chain, thisframe))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAME_CHAIN_VALID = 0x%08lx\n", - (long) current_gdbarch->frame_chain_valid - /*FRAME_CHAIN_VALID ()*/); -#endif -#ifdef FRAME_INIT_SAVED_REGS -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "FRAME_INIT_SAVED_REGS(frame)", - XSTRING (FRAME_INIT_SAVED_REGS (frame))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAME_INIT_SAVED_REGS = 0x%08lx\n", - (long) current_gdbarch->frame_init_saved_regs - /*FRAME_INIT_SAVED_REGS ()*/); -#endif -#ifdef FRAME_LOCALS_ADDRESS - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "FRAME_LOCALS_ADDRESS(fi)", - XSTRING (FRAME_LOCALS_ADDRESS (fi))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAME_LOCALS_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->frame_locals_address - /*FRAME_LOCALS_ADDRESS ()*/); + "gdbarch_dump: FRAME_NUM_ARGS_P() = %d\n", + FRAME_NUM_ARGS_P ()); #endif #ifdef FRAME_NUM_ARGS fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "FRAME_NUM_ARGS(frame)", XSTRING (FRAME_NUM_ARGS (frame))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAME_NUM_ARGS = 0x%08lx\n", - (long) current_gdbarch->frame_num_args - /*FRAME_NUM_ARGS ()*/); -#endif -#ifdef FRAME_SAVED_PC fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "FRAME_SAVED_PC(fi)", - XSTRING (FRAME_SAVED_PC (fi))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: FRAME_SAVED_PC = 0x%08lx\n", - (long) current_gdbarch->frame_saved_pc - /*FRAME_SAVED_PC ()*/); + "gdbarch_dump: FRAME_NUM_ARGS = <0x%08lx>\n", + (long) current_gdbarch->frame_num_args + /*FRAME_NUM_ARGS ()*/); +#endif +#ifdef FRAME_RED_ZONE_SIZE + fprintf_unfiltered (file, + "gdbarch_dump: FRAME_RED_ZONE_SIZE # %s\n", + XSTRING (FRAME_RED_ZONE_SIZE)); + fprintf_unfiltered (file, + "gdbarch_dump: FRAME_RED_ZONE_SIZE = %d\n", + FRAME_RED_ZONE_SIZE); #endif #ifdef FUNCTION_START_OFFSET fprintf_unfiltered (file, @@ -1284,159 +1807,109 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: FUNCTION_START_OFFSET = %ld\n", (long) FUNCTION_START_OFFSET); #endif +#ifdef GET_LONGJMP_TARGET_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "GET_LONGJMP_TARGET_P()", + XSTRING (GET_LONGJMP_TARGET_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: GET_LONGJMP_TARGET_P() = %d\n", + GET_LONGJMP_TARGET_P ()); +#endif #ifdef GET_LONGJMP_TARGET fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "GET_LONGJMP_TARGET(pc)", XSTRING (GET_LONGJMP_TARGET (pc))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: GET_LONGJMP_TARGET = 0x%08lx\n", - (long) current_gdbarch->get_longjmp_target - /*GET_LONGJMP_TARGET ()*/); -#endif -#ifdef GET_SAVED_REGISTER -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval)", - XSTRING (GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval))); + "gdbarch_dump: GET_LONGJMP_TARGET = <0x%08lx>\n", + (long) current_gdbarch->get_longjmp_target + /*GET_LONGJMP_TARGET ()*/); #endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: GET_SAVED_REGISTER = 0x%08lx\n", - (long) current_gdbarch->get_saved_register - /*GET_SAVED_REGISTER ()*/); -#endif -#ifdef INIT_EXTRA_FRAME_INFO -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ +#ifdef HAVE_NONSTEPPABLE_WATCHPOINT fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "INIT_EXTRA_FRAME_INFO(fromleaf, frame)", - XSTRING (INIT_EXTRA_FRAME_INFO (fromleaf, frame))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: INIT_EXTRA_FRAME_INFO = 0x%08lx\n", - (long) current_gdbarch->init_extra_frame_info - /*INIT_EXTRA_FRAME_INFO ()*/); -#endif -#ifdef INIT_FRAME_PC -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ + "gdbarch_dump: HAVE_NONSTEPPABLE_WATCHPOINT # %s\n", + XSTRING (HAVE_NONSTEPPABLE_WATCHPOINT)); fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "INIT_FRAME_PC(fromleaf, prev)", - XSTRING (INIT_FRAME_PC (fromleaf, prev))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: INIT_FRAME_PC = 0x%08lx\n", - (long) current_gdbarch->init_frame_pc - /*INIT_FRAME_PC ()*/); -#endif -#ifdef INIT_FRAME_PC_FIRST -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "INIT_FRAME_PC_FIRST(fromleaf, prev)", - XSTRING (INIT_FRAME_PC_FIRST (fromleaf, prev))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: INIT_FRAME_PC_FIRST = 0x%08lx\n", - (long) current_gdbarch->init_frame_pc_first - /*INIT_FRAME_PC_FIRST ()*/); + "gdbarch_dump: HAVE_NONSTEPPABLE_WATCHPOINT = %d\n", + HAVE_NONSTEPPABLE_WATCHPOINT); #endif #ifdef INNER_THAN fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "INNER_THAN(lhs, rhs)", XSTRING (INNER_THAN (lhs, rhs))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: INNER_THAN = 0x%08lx\n", - (long) current_gdbarch->inner_than - /*INNER_THAN ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: INNER_THAN = <0x%08lx>\n", + (long) current_gdbarch->inner_than + /*INNER_THAN ()*/); +#endif +#ifdef INTEGER_TO_ADDRESS_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "INTEGER_TO_ADDRESS_P()", + XSTRING (INTEGER_TO_ADDRESS_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: INTEGER_TO_ADDRESS_P() = %d\n", + INTEGER_TO_ADDRESS_P ()); #endif #ifdef INTEGER_TO_ADDRESS fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "INTEGER_TO_ADDRESS(type, buf)", XSTRING (INTEGER_TO_ADDRESS (type, buf))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: INTEGER_TO_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->integer_to_address - /*INTEGER_TO_ADDRESS ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: INTEGER_TO_ADDRESS = <0x%08lx>\n", + (long) current_gdbarch->integer_to_address + /*INTEGER_TO_ADDRESS ()*/); #endif #ifdef IN_SOLIB_CALL_TRAMPOLINE fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "IN_SOLIB_CALL_TRAMPOLINE(pc, name)", XSTRING (IN_SOLIB_CALL_TRAMPOLINE (pc, name))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: IN_SOLIB_CALL_TRAMPOLINE = 0x%08lx\n", - (long) current_gdbarch->in_solib_call_trampoline - /*IN_SOLIB_CALL_TRAMPOLINE ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: IN_SOLIB_CALL_TRAMPOLINE = <0x%08lx>\n", + (long) current_gdbarch->in_solib_call_trampoline + /*IN_SOLIB_CALL_TRAMPOLINE ()*/); #endif -#ifdef MAX_REGISTER_RAW_SIZE +#ifdef IN_SOLIB_RETURN_TRAMPOLINE fprintf_unfiltered (file, - "gdbarch_dump: MAX_REGISTER_RAW_SIZE # %s\n", - XSTRING (MAX_REGISTER_RAW_SIZE)); + "gdbarch_dump: %s # %s\n", + "IN_SOLIB_RETURN_TRAMPOLINE(pc, name)", + XSTRING (IN_SOLIB_RETURN_TRAMPOLINE (pc, name))); fprintf_unfiltered (file, - "gdbarch_dump: MAX_REGISTER_RAW_SIZE = %d\n", - MAX_REGISTER_RAW_SIZE); -#endif -#ifdef MAX_REGISTER_VIRTUAL_SIZE - fprintf_unfiltered (file, - "gdbarch_dump: MAX_REGISTER_VIRTUAL_SIZE # %s\n", - XSTRING (MAX_REGISTER_VIRTUAL_SIZE)); - fprintf_unfiltered (file, - "gdbarch_dump: MAX_REGISTER_VIRTUAL_SIZE = %d\n", - MAX_REGISTER_VIRTUAL_SIZE); + "gdbarch_dump: IN_SOLIB_RETURN_TRAMPOLINE = <0x%08lx>\n", + (long) current_gdbarch->in_solib_return_trampoline + /*IN_SOLIB_RETURN_TRAMPOLINE ()*/); #endif #ifdef MEMORY_INSERT_BREAKPOINT fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "MEMORY_INSERT_BREAKPOINT(addr, contents_cache)", XSTRING (MEMORY_INSERT_BREAKPOINT (addr, contents_cache))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: MEMORY_INSERT_BREAKPOINT = 0x%08lx\n", - (long) current_gdbarch->memory_insert_breakpoint - /*MEMORY_INSERT_BREAKPOINT ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: MEMORY_INSERT_BREAKPOINT = <0x%08lx>\n", + (long) current_gdbarch->memory_insert_breakpoint + /*MEMORY_INSERT_BREAKPOINT ()*/); #endif #ifdef MEMORY_REMOVE_BREAKPOINT fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "MEMORY_REMOVE_BREAKPOINT(addr, contents_cache)", XSTRING (MEMORY_REMOVE_BREAKPOINT (addr, contents_cache))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: MEMORY_REMOVE_BREAKPOINT = 0x%08lx\n", - (long) current_gdbarch->memory_remove_breakpoint - /*MEMORY_REMOVE_BREAKPOINT ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: MEMORY_REMOVE_BREAKPOINT = <0x%08lx>\n", + (long) current_gdbarch->memory_remove_breakpoint + /*MEMORY_REMOVE_BREAKPOINT ()*/); #endif -#ifdef NNPC_REGNUM +#ifdef NAME_OF_MALLOC fprintf_unfiltered (file, - "gdbarch_dump: NNPC_REGNUM # %s\n", - XSTRING (NNPC_REGNUM)); + "gdbarch_dump: NAME_OF_MALLOC # %s\n", + XSTRING (NAME_OF_MALLOC)); fprintf_unfiltered (file, - "gdbarch_dump: NNPC_REGNUM = %d\n", - NNPC_REGNUM); -#endif -#ifdef NPC_REGNUM - fprintf_unfiltered (file, - "gdbarch_dump: NPC_REGNUM # %s\n", - XSTRING (NPC_REGNUM)); - fprintf_unfiltered (file, - "gdbarch_dump: NPC_REGNUM = %d\n", - NPC_REGNUM); + "gdbarch_dump: NAME_OF_MALLOC = %s\n", + NAME_OF_MALLOC); #endif #ifdef NUM_PSEUDO_REGS fprintf_unfiltered (file, @@ -1462,16 +1935,15 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: PARM_BOUNDARY = %d\n", PARM_BOUNDARY); #endif -#ifdef PC_IN_CALL_DUMMY +#ifdef PC_IN_SIGTRAMP fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "PC_IN_CALL_DUMMY(pc, sp, frame_address)", - XSTRING (PC_IN_CALL_DUMMY (pc, sp, frame_address))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: PC_IN_CALL_DUMMY = 0x%08lx\n", - (long) current_gdbarch->pc_in_call_dummy - /*PC_IN_CALL_DUMMY ()*/); + "PC_IN_SIGTRAMP(pc, name)", + XSTRING (PC_IN_SIGTRAMP (pc, name))); + fprintf_unfiltered (file, + "gdbarch_dump: PC_IN_SIGTRAMP = <0x%08lx>\n", + (long) current_gdbarch->pc_in_sigtramp + /*PC_IN_SIGTRAMP ()*/); #endif #ifdef PC_REGNUM fprintf_unfiltered (file, @@ -1486,356 +1958,213 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: %s # %s\n", "POINTER_TO_ADDRESS(type, buf)", XSTRING (POINTER_TO_ADDRESS (type, buf))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: POINTER_TO_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->pointer_to_address - /*POINTER_TO_ADDRESS ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: POINTER_TO_ADDRESS = <0x%08lx>\n", + (long) current_gdbarch->pointer_to_address + /*POINTER_TO_ADDRESS ()*/); #endif -#ifdef POP_FRAME -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_print_float_info_p() = %d\n", + gdbarch_print_float_info_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: print_float_info = 0x%08lx\n", + (long) current_gdbarch->print_float_info); + fprintf_unfiltered (file, + "gdbarch_dump: print_registers_info = 0x%08lx\n", + (long) current_gdbarch->print_registers_info); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_print_vector_info_p() = %d\n", + gdbarch_print_vector_info_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: print_vector_info = 0x%08lx\n", + (long) current_gdbarch->print_vector_info); +#ifdef PS_REGNUM + fprintf_unfiltered (file, + "gdbarch_dump: PS_REGNUM # %s\n", + XSTRING (PS_REGNUM)); + fprintf_unfiltered (file, + "gdbarch_dump: PS_REGNUM = %d\n", + PS_REGNUM); +#endif + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_push_dummy_call_p() = %d\n", + gdbarch_push_dummy_call_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: push_dummy_call = 0x%08lx\n", + (long) current_gdbarch->push_dummy_call); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_push_dummy_code_p() = %d\n", + gdbarch_push_dummy_code_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: push_dummy_code = 0x%08lx\n", + (long) current_gdbarch->push_dummy_code); +#ifdef REGISTER_BYTES_OK_P fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "POP_FRAME(-)", - XSTRING (POP_FRAME (-))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: POP_FRAME = 0x%08lx\n", - (long) current_gdbarch->pop_frame - /*POP_FRAME ()*/); -#endif -#ifdef PREPARE_TO_PROCEED + "REGISTER_BYTES_OK_P()", + XSTRING (REGISTER_BYTES_OK_P ())); fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "PREPARE_TO_PROCEED(select_it)", - XSTRING (PREPARE_TO_PROCEED (select_it))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: PREPARE_TO_PROCEED = 0x%08lx\n", - (long) current_gdbarch->prepare_to_proceed - /*PREPARE_TO_PROCEED ()*/); -#endif -#ifdef PRINT_FLOAT_INFO -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "PRINT_FLOAT_INFO()", - XSTRING (PRINT_FLOAT_INFO ())); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: PRINT_FLOAT_INFO = 0x%08lx\n", - (long) current_gdbarch->print_float_info - /*PRINT_FLOAT_INFO ()*/); -#endif -#ifdef PROLOGUE_FRAMELESS_P - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "PROLOGUE_FRAMELESS_P(ip)", - XSTRING (PROLOGUE_FRAMELESS_P (ip))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: PROLOGUE_FRAMELESS_P = 0x%08lx\n", - (long) current_gdbarch->prologue_frameless_p - /*PROLOGUE_FRAMELESS_P ()*/); -#endif -#ifdef PUSH_ARGUMENTS - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr)", - XSTRING (PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: PUSH_ARGUMENTS = 0x%08lx\n", - (long) current_gdbarch->push_arguments - /*PUSH_ARGUMENTS ()*/); -#endif -#ifdef PUSH_DUMMY_FRAME -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "PUSH_DUMMY_FRAME(-)", - XSTRING (PUSH_DUMMY_FRAME (-))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: PUSH_DUMMY_FRAME = 0x%08lx\n", - (long) current_gdbarch->push_dummy_frame - /*PUSH_DUMMY_FRAME ()*/); -#endif -#ifdef PUSH_RETURN_ADDRESS - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "PUSH_RETURN_ADDRESS(pc, sp)", - XSTRING (PUSH_RETURN_ADDRESS (pc, sp))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: PUSH_RETURN_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->push_return_address - /*PUSH_RETURN_ADDRESS ()*/); -#endif -#ifdef REGISTER_BYTE - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REGISTER_BYTE(reg_nr)", - XSTRING (REGISTER_BYTE (reg_nr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_BYTE = 0x%08lx\n", - (long) current_gdbarch->register_byte - /*REGISTER_BYTE ()*/); -#endif -#ifdef REGISTER_BYTES - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_BYTES # %s\n", - XSTRING (REGISTER_BYTES)); - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_BYTES = %d\n", - REGISTER_BYTES); + "gdbarch_dump: REGISTER_BYTES_OK_P() = %d\n", + REGISTER_BYTES_OK_P ()); #endif #ifdef REGISTER_BYTES_OK fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "REGISTER_BYTES_OK(nr_bytes)", XSTRING (REGISTER_BYTES_OK (nr_bytes))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_BYTES_OK = 0x%08lx\n", - (long) current_gdbarch->register_bytes_ok - /*REGISTER_BYTES_OK ()*/); -#endif -#ifdef REGISTER_CONVERTIBLE fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REGISTER_CONVERTIBLE(nr)", - XSTRING (REGISTER_CONVERTIBLE (nr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_CONVERTIBLE = 0x%08lx\n", - (long) current_gdbarch->register_convertible - /*REGISTER_CONVERTIBLE ()*/); -#endif -#ifdef REGISTER_CONVERT_TO_RAW -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REGISTER_CONVERT_TO_RAW(type, regnum, from, to)", - XSTRING (REGISTER_CONVERT_TO_RAW (type, regnum, from, to))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_CONVERT_TO_RAW = 0x%08lx\n", - (long) current_gdbarch->register_convert_to_raw - /*REGISTER_CONVERT_TO_RAW ()*/); -#endif -#ifdef REGISTER_CONVERT_TO_VIRTUAL -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to)", - XSTRING (REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_CONVERT_TO_VIRTUAL = 0x%08lx\n", - (long) current_gdbarch->register_convert_to_virtual - /*REGISTER_CONVERT_TO_VIRTUAL ()*/); + "gdbarch_dump: REGISTER_BYTES_OK = <0x%08lx>\n", + (long) current_gdbarch->register_bytes_ok + /*REGISTER_BYTES_OK ()*/); #endif #ifdef REGISTER_NAME fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "REGISTER_NAME(regnr)", XSTRING (REGISTER_NAME (regnr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_NAME = 0x%08lx\n", - (long) current_gdbarch->register_name - /*REGISTER_NAME ()*/); -#endif -#ifdef REGISTER_RAW_SIZE fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REGISTER_RAW_SIZE(reg_nr)", - XSTRING (REGISTER_RAW_SIZE (reg_nr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_RAW_SIZE = 0x%08lx\n", - (long) current_gdbarch->register_raw_size - /*REGISTER_RAW_SIZE ()*/); + "gdbarch_dump: REGISTER_NAME = <0x%08lx>\n", + (long) current_gdbarch->register_name + /*REGISTER_NAME ()*/); #endif #ifdef REGISTER_SIM_REGNO fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "REGISTER_SIM_REGNO(reg_nr)", XSTRING (REGISTER_SIM_REGNO (reg_nr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_SIM_REGNO = 0x%08lx\n", - (long) current_gdbarch->register_sim_regno - /*REGISTER_SIM_REGNO ()*/); -#endif -#ifdef REGISTER_SIZE fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_SIZE # %s\n", - XSTRING (REGISTER_SIZE)); - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_SIZE = %d\n", - REGISTER_SIZE); + "gdbarch_dump: REGISTER_SIM_REGNO = <0x%08lx>\n", + (long) current_gdbarch->register_sim_regno + /*REGISTER_SIM_REGNO ()*/); #endif -#ifdef REGISTER_VIRTUAL_SIZE +#ifdef REGISTER_TO_VALUE fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "REGISTER_VIRTUAL_SIZE(reg_nr)", - XSTRING (REGISTER_VIRTUAL_SIZE (reg_nr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_VIRTUAL_SIZE = 0x%08lx\n", - (long) current_gdbarch->register_virtual_size - /*REGISTER_VIRTUAL_SIZE ()*/); -#endif -#ifdef REGISTER_VIRTUAL_TYPE + "REGISTER_TO_VALUE(frame, regnum, type, buf)", + XSTRING (REGISTER_TO_VALUE (frame, regnum, type, buf))); fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REGISTER_VIRTUAL_TYPE(reg_nr)", - XSTRING (REGISTER_VIRTUAL_TYPE (reg_nr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REGISTER_VIRTUAL_TYPE = 0x%08lx\n", - (long) current_gdbarch->register_virtual_type - /*REGISTER_VIRTUAL_TYPE ()*/); + "gdbarch_dump: REGISTER_TO_VALUE = <0x%08lx>\n", + (long) current_gdbarch->register_to_value + /*REGISTER_TO_VALUE ()*/); #endif -#ifdef REG_STRUCT_HAS_ADDR fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REG_STRUCT_HAS_ADDR(gcc_p, type)", - XSTRING (REG_STRUCT_HAS_ADDR (gcc_p, type))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REG_STRUCT_HAS_ADDR = 0x%08lx\n", - (long) current_gdbarch->reg_struct_has_addr - /*REG_STRUCT_HAS_ADDR ()*/); -#endif -#ifdef REMOTE_TRANSLATE_XFER_ADDRESS -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ + "gdbarch_dump: gdbarch_register_type_p() = %d\n", + gdbarch_register_type_p (current_gdbarch)); fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "REMOTE_TRANSLATE_XFER_ADDRESS(gdb_addr, gdb_len, rem_addr, rem_len)", - XSTRING (REMOTE_TRANSLATE_XFER_ADDRESS (gdb_addr, gdb_len, rem_addr, rem_len))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: REMOTE_TRANSLATE_XFER_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->remote_translate_xfer_address - /*REMOTE_TRANSLATE_XFER_ADDRESS ()*/); -#endif + "gdbarch_dump: register_type = 0x%08lx\n", + (long) current_gdbarch->register_type); + fprintf_unfiltered (file, + "gdbarch_dump: remote_translate_xfer_address = 0x%08lx\n", + (long) current_gdbarch->remote_translate_xfer_address); #ifdef RETURN_VALUE_ON_STACK fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "RETURN_VALUE_ON_STACK(type)", XSTRING (RETURN_VALUE_ON_STACK (type))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: RETURN_VALUE_ON_STACK = 0x%08lx\n", - (long) current_gdbarch->return_value_on_stack - /*RETURN_VALUE_ON_STACK ()*/); -#endif -#ifdef SAVED_PC_AFTER_CALL fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "SAVED_PC_AFTER_CALL(frame)", - XSTRING (SAVED_PC_AFTER_CALL (frame))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: SAVED_PC_AFTER_CALL = 0x%08lx\n", - (long) current_gdbarch->saved_pc_after_call - /*SAVED_PC_AFTER_CALL ()*/); -#endif -#ifdef SAVE_DUMMY_FRAME_TOS -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "SAVE_DUMMY_FRAME_TOS(sp)", - XSTRING (SAVE_DUMMY_FRAME_TOS (sp))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: SAVE_DUMMY_FRAME_TOS = 0x%08lx\n", - (long) current_gdbarch->save_dummy_frame_tos - /*SAVE_DUMMY_FRAME_TOS ()*/); + "gdbarch_dump: RETURN_VALUE_ON_STACK = <0x%08lx>\n", + (long) current_gdbarch->return_value_on_stack + /*RETURN_VALUE_ON_STACK ()*/); #endif #ifdef SDB_REG_TO_REGNUM fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "SDB_REG_TO_REGNUM(sdb_regnr)", XSTRING (SDB_REG_TO_REGNUM (sdb_regnr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: SDB_REG_TO_REGNUM = 0x%08lx\n", - (long) current_gdbarch->sdb_reg_to_regnum - /*SDB_REG_TO_REGNUM ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: SDB_REG_TO_REGNUM = <0x%08lx>\n", + (long) current_gdbarch->sdb_reg_to_regnum + /*SDB_REG_TO_REGNUM ()*/); #endif -#ifdef SIZEOF_CALL_DUMMY_WORDS +#ifdef SIGTRAMP_END_P fprintf_unfiltered (file, - "gdbarch_dump: SIZEOF_CALL_DUMMY_WORDS # %s\n", - XSTRING (SIZEOF_CALL_DUMMY_WORDS)); + "gdbarch_dump: %s # %s\n", + "SIGTRAMP_END_P()", + XSTRING (SIGTRAMP_END_P ())); fprintf_unfiltered (file, - "gdbarch_dump: SIZEOF_CALL_DUMMY_WORDS = 0x%08lx\n", - (long) SIZEOF_CALL_DUMMY_WORDS); + "gdbarch_dump: SIGTRAMP_END_P() = %d\n", + SIGTRAMP_END_P ()); +#endif +#ifdef SIGTRAMP_END + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "SIGTRAMP_END(pc)", + XSTRING (SIGTRAMP_END (pc))); + fprintf_unfiltered (file, + "gdbarch_dump: SIGTRAMP_END = <0x%08lx>\n", + (long) current_gdbarch->sigtramp_end + /*SIGTRAMP_END ()*/); +#endif +#ifdef SIGTRAMP_START_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "SIGTRAMP_START_P()", + XSTRING (SIGTRAMP_START_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: SIGTRAMP_START_P() = %d\n", + SIGTRAMP_START_P ()); +#endif +#ifdef SIGTRAMP_START + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "SIGTRAMP_START(pc)", + XSTRING (SIGTRAMP_START (pc))); + fprintf_unfiltered (file, + "gdbarch_dump: SIGTRAMP_START = <0x%08lx>\n", + (long) current_gdbarch->sigtramp_start + /*SIGTRAMP_START ()*/); #endif #ifdef SKIP_PROLOGUE fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "SKIP_PROLOGUE(ip)", XSTRING (SKIP_PROLOGUE (ip))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: SKIP_PROLOGUE = 0x%08lx\n", - (long) current_gdbarch->skip_prologue - /*SKIP_PROLOGUE ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: SKIP_PROLOGUE = <0x%08lx>\n", + (long) current_gdbarch->skip_prologue + /*SKIP_PROLOGUE ()*/); #endif + fprintf_unfiltered (file, + "gdbarch_dump: skip_solib_resolver = 0x%08lx\n", + (long) current_gdbarch->skip_solib_resolver); #ifdef SKIP_TRAMPOLINE_CODE fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "SKIP_TRAMPOLINE_CODE(pc)", XSTRING (SKIP_TRAMPOLINE_CODE (pc))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: SKIP_TRAMPOLINE_CODE = 0x%08lx\n", - (long) current_gdbarch->skip_trampoline_code - /*SKIP_TRAMPOLINE_CODE ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: SKIP_TRAMPOLINE_CODE = <0x%08lx>\n", + (long) current_gdbarch->skip_trampoline_code + /*SKIP_TRAMPOLINE_CODE ()*/); #endif #ifdef SMASH_TEXT_ADDRESS fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "SMASH_TEXT_ADDRESS(addr)", XSTRING (SMASH_TEXT_ADDRESS (addr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: SMASH_TEXT_ADDRESS = 0x%08lx\n", - (long) current_gdbarch->smash_text_address - /*SMASH_TEXT_ADDRESS ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: SMASH_TEXT_ADDRESS = <0x%08lx>\n", + (long) current_gdbarch->smash_text_address + /*SMASH_TEXT_ADDRESS ()*/); +#endif +#ifdef SOFTWARE_SINGLE_STEP_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "SOFTWARE_SINGLE_STEP_P()", + XSTRING (SOFTWARE_SINGLE_STEP_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: SOFTWARE_SINGLE_STEP_P() = %d\n", + SOFTWARE_SINGLE_STEP_P ()); #endif #ifdef SOFTWARE_SINGLE_STEP -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p)", XSTRING (SOFTWARE_SINGLE_STEP (sig, insert_breakpoints_p))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: SOFTWARE_SINGLE_STEP = 0x%08lx\n", - (long) current_gdbarch->software_single_step - /*SOFTWARE_SINGLE_STEP ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: SOFTWARE_SINGLE_STEP = <0x%08lx>\n", + (long) current_gdbarch->software_single_step + /*SOFTWARE_SINGLE_STEP ()*/); #endif #ifdef SP_REGNUM fprintf_unfiltered (file, @@ -1850,64 +2179,20 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: %s # %s\n", "STAB_REG_TO_REGNUM(stab_regnr)", XSTRING (STAB_REG_TO_REGNUM (stab_regnr))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: STAB_REG_TO_REGNUM = 0x%08lx\n", - (long) current_gdbarch->stab_reg_to_regnum - /*STAB_REG_TO_REGNUM ()*/); -#endif -#ifdef STACK_ALIGN fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "STACK_ALIGN(sp)", - XSTRING (STACK_ALIGN (sp))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: STACK_ALIGN = 0x%08lx\n", - (long) current_gdbarch->stack_align - /*STACK_ALIGN ()*/); -#endif -#ifdef STORE_PSEUDO_REGISTER -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ - fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "STORE_PSEUDO_REGISTER(regnum)", - XSTRING (STORE_PSEUDO_REGISTER (regnum))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: STORE_PSEUDO_REGISTER = 0x%08lx\n", - (long) current_gdbarch->store_pseudo_register - /*STORE_PSEUDO_REGISTER ()*/); + "gdbarch_dump: STAB_REG_TO_REGNUM = <0x%08lx>\n", + (long) current_gdbarch->stab_reg_to_regnum + /*STAB_REG_TO_REGNUM ()*/); #endif #ifdef STORE_RETURN_VALUE -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "STORE_RETURN_VALUE(type, valbuf)", - XSTRING (STORE_RETURN_VALUE (type, valbuf))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: STORE_RETURN_VALUE = 0x%08lx\n", - (long) current_gdbarch->store_return_value - /*STORE_RETURN_VALUE ()*/); -#endif -#ifdef STORE_STRUCT_RETURN -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ + "STORE_RETURN_VALUE(type, regcache, valbuf)", + XSTRING (STORE_RETURN_VALUE (type, regcache, valbuf))); fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "STORE_STRUCT_RETURN(addr, sp)", - XSTRING (STORE_STRUCT_RETURN (addr, sp))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: STORE_STRUCT_RETURN = 0x%08lx\n", - (long) current_gdbarch->store_struct_return - /*STORE_STRUCT_RETURN ()*/); + "gdbarch_dump: STORE_RETURN_VALUE = <0x%08lx>\n", + (long) current_gdbarch->store_return_value + /*STORE_RETURN_VALUE ()*/); #endif #ifdef TARGET_ADDR_BIT fprintf_unfiltered (file, @@ -1963,8 +2248,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: TARGET_DOUBLE_FORMAT # %s\n", XSTRING (TARGET_DOUBLE_FORMAT)); fprintf_unfiltered (file, - "gdbarch_dump: TARGET_DOUBLE_FORMAT = %ld\n", - (long) TARGET_DOUBLE_FORMAT); + "gdbarch_dump: TARGET_DOUBLE_FORMAT = %s\n", + (TARGET_DOUBLE_FORMAT)->name); #endif #ifdef TARGET_FLOAT_BIT fprintf_unfiltered (file, @@ -1979,8 +2264,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: TARGET_FLOAT_FORMAT # %s\n", XSTRING (TARGET_FLOAT_FORMAT)); fprintf_unfiltered (file, - "gdbarch_dump: TARGET_FLOAT_FORMAT = %ld\n", - (long) TARGET_FLOAT_FORMAT); + "gdbarch_dump: TARGET_FLOAT_FORMAT = %s\n", + (TARGET_FLOAT_FORMAT)->name); #endif #ifdef TARGET_INT_BIT fprintf_unfiltered (file, @@ -2011,8 +2296,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT # %s\n", XSTRING (TARGET_LONG_DOUBLE_FORMAT)); fprintf_unfiltered (file, - "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT = %ld\n", - (long) TARGET_LONG_DOUBLE_FORMAT); + "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT = %s\n", + (TARGET_LONG_DOUBLE_FORMAT)->name); #endif #ifdef TARGET_LONG_LONG_BIT fprintf_unfiltered (file, @@ -2022,16 +2307,23 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: TARGET_LONG_LONG_BIT = %d\n", TARGET_LONG_LONG_BIT); #endif +#ifdef TARGET_OSABI + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_OSABI # %s\n", + XSTRING (TARGET_OSABI)); + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_OSABI = %ld\n", + (long) TARGET_OSABI); +#endif #ifdef TARGET_PRINT_INSN fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "TARGET_PRINT_INSN(vma, info)", XSTRING (TARGET_PRINT_INSN (vma, info))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_PRINT_INSN = 0x%08lx\n", - (long) current_gdbarch->print_insn - /*TARGET_PRINT_INSN ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_PRINT_INSN = <0x%08lx>\n", + (long) current_gdbarch->print_insn + /*TARGET_PRINT_INSN ()*/); #endif #ifdef TARGET_PTR_BIT fprintf_unfiltered (file, @@ -2041,38 +2333,43 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: TARGET_PTR_BIT = %d\n", TARGET_PTR_BIT); #endif -#ifdef TARGET_READ_FP +#ifdef TARGET_READ_PC_P fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "TARGET_READ_FP()", - XSTRING (TARGET_READ_FP ())); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_READ_FP = 0x%08lx\n", - (long) current_gdbarch->read_fp - /*TARGET_READ_FP ()*/); + "TARGET_READ_PC_P()", + XSTRING (TARGET_READ_PC_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_READ_PC_P() = %d\n", + TARGET_READ_PC_P ()); #endif #ifdef TARGET_READ_PC fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "TARGET_READ_PC(ptid)", XSTRING (TARGET_READ_PC (ptid))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_READ_PC = 0x%08lx\n", - (long) current_gdbarch->read_pc - /*TARGET_READ_PC ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_READ_PC = <0x%08lx>\n", + (long) current_gdbarch->read_pc + /*TARGET_READ_PC ()*/); +#endif +#ifdef TARGET_READ_SP_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "TARGET_READ_SP_P()", + XSTRING (TARGET_READ_SP_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_READ_SP_P() = %d\n", + TARGET_READ_SP_P ()); #endif #ifdef TARGET_READ_SP fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "TARGET_READ_SP()", XSTRING (TARGET_READ_SP ())); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_READ_SP = 0x%08lx\n", - (long) current_gdbarch->read_sp - /*TARGET_READ_SP ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_READ_SP = <0x%08lx>\n", + (long) current_gdbarch->read_sp + /*TARGET_READ_SP ()*/); #endif #ifdef TARGET_SHORT_BIT fprintf_unfiltered (file, @@ -2083,79 +2380,62 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) TARGET_SHORT_BIT); #endif #ifdef TARGET_VIRTUAL_FRAME_POINTER -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "TARGET_VIRTUAL_FRAME_POINTER(pc, frame_regnum, frame_offset)", XSTRING (TARGET_VIRTUAL_FRAME_POINTER (pc, frame_regnum, frame_offset))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_VIRTUAL_FRAME_POINTER = 0x%08lx\n", - (long) current_gdbarch->virtual_frame_pointer - /*TARGET_VIRTUAL_FRAME_POINTER ()*/); -#endif -#ifdef TARGET_WRITE_FP -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "TARGET_WRITE_FP(val)", - XSTRING (TARGET_WRITE_FP (val))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_WRITE_FP = 0x%08lx\n", - (long) current_gdbarch->write_fp - /*TARGET_WRITE_FP ()*/); + "gdbarch_dump: TARGET_VIRTUAL_FRAME_POINTER = <0x%08lx>\n", + (long) current_gdbarch->virtual_frame_pointer + /*TARGET_VIRTUAL_FRAME_POINTER ()*/); #endif #ifdef TARGET_WRITE_PC -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "TARGET_WRITE_PC(val, ptid)", XSTRING (TARGET_WRITE_PC (val, ptid))); -#endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_WRITE_PC = 0x%08lx\n", - (long) current_gdbarch->write_pc - /*TARGET_WRITE_PC ()*/); -#endif -#ifdef TARGET_WRITE_SP -#if GDB_MULTI_ARCH - /* Macro might contain `[{}]' when not multi-arch */ fprintf_unfiltered (file, - "gdbarch_dump: %s # %s\n", - "TARGET_WRITE_SP(val)", - XSTRING (TARGET_WRITE_SP (val))); + "gdbarch_dump: TARGET_WRITE_PC = <0x%08lx>\n", + (long) current_gdbarch->write_pc + /*TARGET_WRITE_PC ()*/); #endif - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: TARGET_WRITE_SP = 0x%08lx\n", - (long) current_gdbarch->write_sp - /*TARGET_WRITE_SP ()*/); -#endif -#ifdef USE_GENERIC_DUMMY_FRAMES fprintf_unfiltered (file, - "gdbarch_dump: USE_GENERIC_DUMMY_FRAMES # %s\n", - XSTRING (USE_GENERIC_DUMMY_FRAMES)); + "gdbarch_dump: gdbarch_unwind_dummy_id_p() = %d\n", + gdbarch_unwind_dummy_id_p (current_gdbarch)); fprintf_unfiltered (file, - "gdbarch_dump: USE_GENERIC_DUMMY_FRAMES = %d\n", - USE_GENERIC_DUMMY_FRAMES); -#endif + "gdbarch_dump: unwind_dummy_id = 0x%08lx\n", + (long) current_gdbarch->unwind_dummy_id); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_unwind_pc_p() = %d\n", + gdbarch_unwind_pc_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: unwind_pc = 0x%08lx\n", + (long) current_gdbarch->unwind_pc); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_unwind_sp_p() = %d\n", + gdbarch_unwind_sp_p (current_gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: unwind_sp = 0x%08lx\n", + (long) current_gdbarch->unwind_sp); #ifdef USE_STRUCT_CONVENTION fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", "USE_STRUCT_CONVENTION(gcc_p, value_type)", XSTRING (USE_STRUCT_CONVENTION (gcc_p, value_type))); - if (GDB_MULTI_ARCH) - fprintf_unfiltered (file, - "gdbarch_dump: USE_STRUCT_CONVENTION = 0x%08lx\n", - (long) current_gdbarch->use_struct_convention - /*USE_STRUCT_CONVENTION ()*/); + fprintf_unfiltered (file, + "gdbarch_dump: USE_STRUCT_CONVENTION = <0x%08lx>\n", + (long) current_gdbarch->use_struct_convention + /*USE_STRUCT_CONVENTION ()*/); +#endif +#ifdef VALUE_TO_REGISTER + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "VALUE_TO_REGISTER(frame, regnum, type, buf)", + XSTRING (VALUE_TO_REGISTER (frame, regnum, type, buf))); + fprintf_unfiltered (file, + "gdbarch_dump: VALUE_TO_REGISTER = <0x%08lx>\n", + (long) current_gdbarch->value_to_register + /*VALUE_TO_REGISTER ()*/); #endif if (current_gdbarch->dump_tdep != NULL) current_gdbarch->dump_tdep (current_gdbarch, file); @@ -2173,6 +2453,7 @@ gdbarch_tdep (struct gdbarch *gdbarch) const struct bfd_arch_info * gdbarch_bfd_arch_info (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_bfd_arch_info called\n"); return gdbarch->bfd_arch_info; @@ -2181,14 +2462,25 @@ gdbarch_bfd_arch_info (struct gdbarch *gdbarch) int gdbarch_byte_order (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_byte_order called\n"); return gdbarch->byte_order; } +enum gdb_osabi +gdbarch_osabi (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_osabi called\n"); + return gdbarch->osabi; +} + int gdbarch_short_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of short_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_short_bit called\n"); @@ -2205,6 +2497,7 @@ set_gdbarch_short_bit (struct gdbarch *gdbarch, int gdbarch_int_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of int_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_int_bit called\n"); @@ -2221,6 +2514,7 @@ set_gdbarch_int_bit (struct gdbarch *gdbarch, int gdbarch_long_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of long_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_long_bit called\n"); @@ -2237,6 +2531,7 @@ set_gdbarch_long_bit (struct gdbarch *gdbarch, int gdbarch_long_long_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of long_long_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_long_long_bit called\n"); @@ -2253,6 +2548,7 @@ set_gdbarch_long_long_bit (struct gdbarch *gdbarch, int gdbarch_float_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of float_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_float_bit called\n"); @@ -2269,6 +2565,7 @@ set_gdbarch_float_bit (struct gdbarch *gdbarch, int gdbarch_double_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of double_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_double_bit called\n"); @@ -2285,6 +2582,7 @@ set_gdbarch_double_bit (struct gdbarch *gdbarch, int gdbarch_long_double_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of long_double_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_long_double_bit called\n"); @@ -2301,6 +2599,7 @@ set_gdbarch_long_double_bit (struct gdbarch *gdbarch, int gdbarch_ptr_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of ptr_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_ptr_bit called\n"); @@ -2317,9 +2616,9 @@ set_gdbarch_ptr_bit (struct gdbarch *gdbarch, int gdbarch_addr_bit (struct gdbarch *gdbarch) { - if (gdbarch->addr_bit == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_addr_bit invalid"); + gdb_assert (gdbarch != NULL); + /* Check variable changed from pre-default. */ + gdb_assert (gdbarch->addr_bit != 0); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_addr_bit called\n"); return gdbarch->addr_bit; @@ -2335,6 +2634,7 @@ set_gdbarch_addr_bit (struct gdbarch *gdbarch, int gdbarch_bfd_vma_bit (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of bfd_vma_bit, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_bfd_vma_bit called\n"); @@ -2351,9 +2651,9 @@ set_gdbarch_bfd_vma_bit (struct gdbarch *gdbarch, int gdbarch_char_signed (struct gdbarch *gdbarch) { - if (gdbarch->char_signed == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_char_signed invalid"); + gdb_assert (gdbarch != NULL); + /* Check variable changed from pre-default. */ + gdb_assert (gdbarch->char_signed != -1); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_char_signed called\n"); return gdbarch->char_signed; @@ -2366,12 +2666,18 @@ set_gdbarch_char_signed (struct gdbarch *gdbarch, gdbarch->char_signed = char_signed; } +int +gdbarch_read_pc_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->read_pc != NULL; +} + CORE_ADDR gdbarch_read_pc (struct gdbarch *gdbarch, ptid_t ptid) { - if (gdbarch->read_pc == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_read_pc invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->read_pc != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_read_pc called\n"); return gdbarch->read_pc (ptid); @@ -2387,9 +2693,8 @@ set_gdbarch_read_pc (struct gdbarch *gdbarch, void gdbarch_write_pc (struct gdbarch *gdbarch, CORE_ADDR val, ptid_t ptid) { - if (gdbarch->write_pc == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_write_pc invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->write_pc != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_write_pc called\n"); gdbarch->write_pc (val, ptid); @@ -2402,48 +2707,18 @@ set_gdbarch_write_pc (struct gdbarch *gdbarch, gdbarch->write_pc = write_pc; } -CORE_ADDR -gdbarch_read_fp (struct gdbarch *gdbarch) +int +gdbarch_read_sp_p (struct gdbarch *gdbarch) { - if (gdbarch->read_fp == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_read_fp invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_read_fp called\n"); - return gdbarch->read_fp (); -} - -void -set_gdbarch_read_fp (struct gdbarch *gdbarch, - gdbarch_read_fp_ftype read_fp) -{ - gdbarch->read_fp = read_fp; -} - -void -gdbarch_write_fp (struct gdbarch *gdbarch, CORE_ADDR val) -{ - if (gdbarch->write_fp == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_write_fp invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_write_fp called\n"); - gdbarch->write_fp (val); -} - -void -set_gdbarch_write_fp (struct gdbarch *gdbarch, - gdbarch_write_fp_ftype write_fp) -{ - gdbarch->write_fp = write_fp; + gdb_assert (gdbarch != NULL); + return gdbarch->read_sp != NULL; } CORE_ADDR gdbarch_read_sp (struct gdbarch *gdbarch) { - if (gdbarch->read_sp == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_read_sp invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->read_sp != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_read_sp called\n"); return gdbarch->read_sp (); @@ -2456,30 +2731,11 @@ set_gdbarch_read_sp (struct gdbarch *gdbarch, gdbarch->read_sp = read_sp; } -void -gdbarch_write_sp (struct gdbarch *gdbarch, CORE_ADDR val) -{ - if (gdbarch->write_sp == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_write_sp invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_write_sp called\n"); - gdbarch->write_sp (val); -} - -void -set_gdbarch_write_sp (struct gdbarch *gdbarch, - gdbarch_write_sp_ftype write_sp) -{ - gdbarch->write_sp = write_sp; -} - void gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset) { - if (gdbarch->virtual_frame_pointer == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_virtual_frame_pointer invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->virtual_frame_pointer != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_virtual_frame_pointer called\n"); gdbarch->virtual_frame_pointer (pc, frame_regnum, frame_offset); @@ -2493,59 +2749,59 @@ set_gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, } int -gdbarch_register_read_p (struct gdbarch *gdbarch) +gdbarch_pseudo_register_read_p (struct gdbarch *gdbarch) { - return gdbarch->register_read != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->pseudo_register_read != NULL; } void -gdbarch_register_read (struct gdbarch *gdbarch, int regnum, char *buf) +gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, void *buf) { - if (gdbarch->register_read == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_read invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->pseudo_register_read != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_read called\n"); - gdbarch->register_read (gdbarch, regnum, buf); + fprintf_unfiltered (gdb_stdlog, "gdbarch_pseudo_register_read called\n"); + gdbarch->pseudo_register_read (gdbarch, regcache, cookednum, buf); } void -set_gdbarch_register_read (struct gdbarch *gdbarch, - gdbarch_register_read_ftype register_read) +set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch, + gdbarch_pseudo_register_read_ftype pseudo_register_read) { - gdbarch->register_read = register_read; + gdbarch->pseudo_register_read = pseudo_register_read; } int -gdbarch_register_write_p (struct gdbarch *gdbarch) +gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch) { - return gdbarch->register_write != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->pseudo_register_write != NULL; } void -gdbarch_register_write (struct gdbarch *gdbarch, int regnum, char *buf) +gdbarch_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const void *buf) { - if (gdbarch->register_write == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_write invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->pseudo_register_write != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_write called\n"); - gdbarch->register_write (gdbarch, regnum, buf); + fprintf_unfiltered (gdb_stdlog, "gdbarch_pseudo_register_write called\n"); + gdbarch->pseudo_register_write (gdbarch, regcache, cookednum, buf); } void -set_gdbarch_register_write (struct gdbarch *gdbarch, - gdbarch_register_write_ftype register_write) +set_gdbarch_pseudo_register_write (struct gdbarch *gdbarch, + gdbarch_pseudo_register_write_ftype pseudo_register_write) { - gdbarch->register_write = register_write; + gdbarch->pseudo_register_write = pseudo_register_write; } int gdbarch_num_regs (struct gdbarch *gdbarch) { - if (gdbarch->num_regs == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_num_regs invalid"); + gdb_assert (gdbarch != NULL); + /* Check variable changed from pre-default. */ + gdb_assert (gdbarch->num_regs != -1); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_num_regs called\n"); return gdbarch->num_regs; @@ -2561,6 +2817,7 @@ set_gdbarch_num_regs (struct gdbarch *gdbarch, int gdbarch_num_pseudo_regs (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of num_pseudo_regs, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_num_pseudo_regs called\n"); @@ -2577,9 +2834,8 @@ set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch, int gdbarch_sp_regnum (struct gdbarch *gdbarch) { - if (gdbarch->sp_regnum == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_sp_regnum invalid"); + gdb_assert (gdbarch != NULL); + /* Skip verify of sp_regnum, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_sp_regnum called\n"); return gdbarch->sp_regnum; @@ -2592,30 +2848,11 @@ set_gdbarch_sp_regnum (struct gdbarch *gdbarch, gdbarch->sp_regnum = sp_regnum; } -int -gdbarch_fp_regnum (struct gdbarch *gdbarch) -{ - if (gdbarch->fp_regnum == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_fp_regnum invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_fp_regnum called\n"); - return gdbarch->fp_regnum; -} - -void -set_gdbarch_fp_regnum (struct gdbarch *gdbarch, - int fp_regnum) -{ - gdbarch->fp_regnum = fp_regnum; -} - int gdbarch_pc_regnum (struct gdbarch *gdbarch) { - if (gdbarch->pc_regnum == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_pc_regnum invalid"); + gdb_assert (gdbarch != NULL); + /* Skip verify of pc_regnum, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_regnum called\n"); return gdbarch->pc_regnum; @@ -2628,9 +2865,27 @@ set_gdbarch_pc_regnum (struct gdbarch *gdbarch, gdbarch->pc_regnum = pc_regnum; } +int +gdbarch_ps_regnum (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of ps_regnum, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_ps_regnum called\n"); + return gdbarch->ps_regnum; +} + +void +set_gdbarch_ps_regnum (struct gdbarch *gdbarch, + int ps_regnum) +{ + gdbarch->ps_regnum = ps_regnum; +} + int gdbarch_fp0_regnum (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); /* Skip verify of fp0_regnum, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_fp0_regnum called\n"); @@ -2644,44 +2899,11 @@ set_gdbarch_fp0_regnum (struct gdbarch *gdbarch, gdbarch->fp0_regnum = fp0_regnum; } -int -gdbarch_npc_regnum (struct gdbarch *gdbarch) -{ - /* Skip verify of npc_regnum, invalid_p == 0 */ - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_npc_regnum called\n"); - return gdbarch->npc_regnum; -} - -void -set_gdbarch_npc_regnum (struct gdbarch *gdbarch, - int npc_regnum) -{ - gdbarch->npc_regnum = npc_regnum; -} - -int -gdbarch_nnpc_regnum (struct gdbarch *gdbarch) -{ - /* Skip verify of nnpc_regnum, invalid_p == 0 */ - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_nnpc_regnum called\n"); - return gdbarch->nnpc_regnum; -} - -void -set_gdbarch_nnpc_regnum (struct gdbarch *gdbarch, - int nnpc_regnum) -{ - gdbarch->nnpc_regnum = nnpc_regnum; -} - int gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, int stab_regnr) { - if (gdbarch->stab_reg_to_regnum == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_stab_reg_to_regnum invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->stab_reg_to_regnum != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_stab_reg_to_regnum called\n"); return gdbarch->stab_reg_to_regnum (stab_regnr); @@ -2697,9 +2919,8 @@ set_gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, int gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int ecoff_regnr) { - if (gdbarch->ecoff_reg_to_regnum == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_ecoff_reg_to_regnum invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->ecoff_reg_to_regnum != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_ecoff_reg_to_regnum called\n"); return gdbarch->ecoff_reg_to_regnum (ecoff_regnr); @@ -2715,9 +2936,8 @@ set_gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_regnr) { - if (gdbarch->dwarf_reg_to_regnum == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_dwarf_reg_to_regnum invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->dwarf_reg_to_regnum != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf_reg_to_regnum called\n"); return gdbarch->dwarf_reg_to_regnum (dwarf_regnr); @@ -2733,9 +2953,8 @@ set_gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int sdb_regnr) { - if (gdbarch->sdb_reg_to_regnum == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_sdb_reg_to_regnum invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->sdb_reg_to_regnum != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_sdb_reg_to_regnum called\n"); return gdbarch->sdb_reg_to_regnum (sdb_regnr); @@ -2751,9 +2970,8 @@ set_gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2_regnr) { - if (gdbarch->dwarf2_reg_to_regnum == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_dwarf2_reg_to_regnum invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->dwarf2_reg_to_regnum != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf2_reg_to_regnum called\n"); return gdbarch->dwarf2_reg_to_regnum (dwarf2_regnr); @@ -2766,12 +2984,11 @@ set_gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, gdbarch->dwarf2_reg_to_regnum = dwarf2_reg_to_regnum; } -char * +const char * gdbarch_register_name (struct gdbarch *gdbarch, int regnr) { - if (gdbarch->register_name == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_name invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->register_name != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_register_name called\n"); return gdbarch->register_name (regnr); @@ -2785,176 +3002,635 @@ set_gdbarch_register_name (struct gdbarch *gdbarch, } int -gdbarch_register_size (struct gdbarch *gdbarch) +gdbarch_register_type_p (struct gdbarch *gdbarch) { - if (gdbarch->register_size == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_size invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_size called\n"); - return gdbarch->register_size; -} - -void -set_gdbarch_register_size (struct gdbarch *gdbarch, - int register_size) -{ - gdbarch->register_size = register_size; -} - -int -gdbarch_register_bytes (struct gdbarch *gdbarch) -{ - if (gdbarch->register_bytes == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_bytes invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_bytes called\n"); - return gdbarch->register_bytes; -} - -void -set_gdbarch_register_bytes (struct gdbarch *gdbarch, - int register_bytes) -{ - gdbarch->register_bytes = register_bytes; -} - -int -gdbarch_register_byte (struct gdbarch *gdbarch, int reg_nr) -{ - if (gdbarch->register_byte == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_byte invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_byte called\n"); - return gdbarch->register_byte (reg_nr); -} - -void -set_gdbarch_register_byte (struct gdbarch *gdbarch, - gdbarch_register_byte_ftype register_byte) -{ - gdbarch->register_byte = register_byte; -} - -int -gdbarch_register_raw_size (struct gdbarch *gdbarch, int reg_nr) -{ - if (gdbarch->register_raw_size == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_raw_size invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_raw_size called\n"); - return gdbarch->register_raw_size (reg_nr); -} - -void -set_gdbarch_register_raw_size (struct gdbarch *gdbarch, - gdbarch_register_raw_size_ftype register_raw_size) -{ - gdbarch->register_raw_size = register_raw_size; -} - -int -gdbarch_max_register_raw_size (struct gdbarch *gdbarch) -{ - if (gdbarch->max_register_raw_size == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_max_register_raw_size invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_max_register_raw_size called\n"); - return gdbarch->max_register_raw_size; -} - -void -set_gdbarch_max_register_raw_size (struct gdbarch *gdbarch, - int max_register_raw_size) -{ - gdbarch->max_register_raw_size = max_register_raw_size; -} - -int -gdbarch_register_virtual_size (struct gdbarch *gdbarch, int reg_nr) -{ - if (gdbarch->register_virtual_size == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_virtual_size invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_virtual_size called\n"); - return gdbarch->register_virtual_size (reg_nr); -} - -void -set_gdbarch_register_virtual_size (struct gdbarch *gdbarch, - gdbarch_register_virtual_size_ftype register_virtual_size) -{ - gdbarch->register_virtual_size = register_virtual_size; -} - -int -gdbarch_max_register_virtual_size (struct gdbarch *gdbarch) -{ - if (gdbarch->max_register_virtual_size == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_max_register_virtual_size invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_max_register_virtual_size called\n"); - return gdbarch->max_register_virtual_size; -} - -void -set_gdbarch_max_register_virtual_size (struct gdbarch *gdbarch, - int max_register_virtual_size) -{ - gdbarch->max_register_virtual_size = max_register_virtual_size; + gdb_assert (gdbarch != NULL); + return gdbarch->register_type != NULL; } struct type * -gdbarch_register_virtual_type (struct gdbarch *gdbarch, int reg_nr) +gdbarch_register_type (struct gdbarch *gdbarch, int reg_nr) { - if (gdbarch->register_virtual_type == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_virtual_type invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->register_type != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_virtual_type called\n"); - return gdbarch->register_virtual_type (reg_nr); + fprintf_unfiltered (gdb_stdlog, "gdbarch_register_type called\n"); + return gdbarch->register_type (gdbarch, reg_nr); } void -set_gdbarch_register_virtual_type (struct gdbarch *gdbarch, - gdbarch_register_virtual_type_ftype register_virtual_type) +set_gdbarch_register_type (struct gdbarch *gdbarch, + gdbarch_register_type_ftype register_type) { - gdbarch->register_virtual_type = register_virtual_type; + gdbarch->register_type = register_type; } -void -gdbarch_do_registers_info (struct gdbarch *gdbarch, int reg_nr, int fpregs) +int +gdbarch_deprecated_register_virtual_type_p (struct gdbarch *gdbarch) { - if (gdbarch->do_registers_info == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_do_registers_info invalid"); + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_register_virtual_type != NULL; +} + +struct type * +gdbarch_deprecated_register_virtual_type (struct gdbarch *gdbarch, int reg_nr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_register_virtual_type != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_do_registers_info called\n"); - gdbarch->do_registers_info (reg_nr, fpregs); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_virtual_type called\n"); + return gdbarch->deprecated_register_virtual_type (reg_nr); } void -set_gdbarch_do_registers_info (struct gdbarch *gdbarch, - gdbarch_do_registers_info_ftype do_registers_info) +set_gdbarch_deprecated_register_virtual_type (struct gdbarch *gdbarch, + gdbarch_deprecated_register_virtual_type_ftype deprecated_register_virtual_type) { - gdbarch->do_registers_info = do_registers_info; + gdbarch->deprecated_register_virtual_type = deprecated_register_virtual_type; +} + +int +gdbarch_deprecated_register_bytes (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_bytes called\n"); + return gdbarch->deprecated_register_bytes; } void -gdbarch_print_float_info (struct gdbarch *gdbarch) +set_gdbarch_deprecated_register_bytes (struct gdbarch *gdbarch, + int deprecated_register_bytes) { - if (gdbarch->print_float_info == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_print_float_info invalid"); + gdbarch->deprecated_register_bytes = deprecated_register_bytes; +} + +int +gdbarch_deprecated_register_byte_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_register_byte != generic_register_byte; +} + +int +gdbarch_deprecated_register_byte (struct gdbarch *gdbarch, int reg_nr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_register_byte != NULL); + /* Do not check predicate: gdbarch->deprecated_register_byte != generic_register_byte, allow call. */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_byte called\n"); + return gdbarch->deprecated_register_byte (reg_nr); +} + +void +set_gdbarch_deprecated_register_byte (struct gdbarch *gdbarch, + gdbarch_deprecated_register_byte_ftype deprecated_register_byte) +{ + gdbarch->deprecated_register_byte = deprecated_register_byte; +} + +int +gdbarch_deprecated_register_raw_size_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_register_raw_size != generic_register_size; +} + +int +gdbarch_deprecated_register_raw_size (struct gdbarch *gdbarch, int reg_nr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_register_raw_size != NULL); + /* Do not check predicate: gdbarch->deprecated_register_raw_size != generic_register_size, allow call. */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_raw_size called\n"); + return gdbarch->deprecated_register_raw_size (reg_nr); +} + +void +set_gdbarch_deprecated_register_raw_size (struct gdbarch *gdbarch, + gdbarch_deprecated_register_raw_size_ftype deprecated_register_raw_size) +{ + gdbarch->deprecated_register_raw_size = deprecated_register_raw_size; +} + +int +gdbarch_deprecated_register_virtual_size_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_register_virtual_size != generic_register_size; +} + +int +gdbarch_deprecated_register_virtual_size (struct gdbarch *gdbarch, int reg_nr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_register_virtual_size != NULL); + /* Do not check predicate: gdbarch->deprecated_register_virtual_size != generic_register_size, allow call. */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_virtual_size called\n"); + return gdbarch->deprecated_register_virtual_size (reg_nr); +} + +void +set_gdbarch_deprecated_register_virtual_size (struct gdbarch *gdbarch, + gdbarch_deprecated_register_virtual_size_ftype deprecated_register_virtual_size) +{ + gdbarch->deprecated_register_virtual_size = deprecated_register_virtual_size; +} + +int +gdbarch_deprecated_max_register_raw_size_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_max_register_raw_size != 0; +} + +int +gdbarch_deprecated_max_register_raw_size (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_max_register_raw_size called\n"); + return gdbarch->deprecated_max_register_raw_size; +} + +void +set_gdbarch_deprecated_max_register_raw_size (struct gdbarch *gdbarch, + int deprecated_max_register_raw_size) +{ + gdbarch->deprecated_max_register_raw_size = deprecated_max_register_raw_size; +} + +int +gdbarch_deprecated_max_register_virtual_size_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_max_register_virtual_size != 0; +} + +int +gdbarch_deprecated_max_register_virtual_size (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_max_register_virtual_size called\n"); + return gdbarch->deprecated_max_register_virtual_size; +} + +void +set_gdbarch_deprecated_max_register_virtual_size (struct gdbarch *gdbarch, + int deprecated_max_register_virtual_size) +{ + gdbarch->deprecated_max_register_virtual_size = deprecated_max_register_virtual_size; +} + +int +gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->unwind_dummy_id != NULL; +} + +struct frame_id +gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->unwind_dummy_id != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_dummy_id called\n"); + return gdbarch->unwind_dummy_id (gdbarch, info); +} + +void +set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, + gdbarch_unwind_dummy_id_ftype unwind_dummy_id) +{ + gdbarch->unwind_dummy_id = unwind_dummy_id; +} + +int +gdbarch_deprecated_save_dummy_frame_tos_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_save_dummy_frame_tos != NULL; +} + +void +gdbarch_deprecated_save_dummy_frame_tos (struct gdbarch *gdbarch, CORE_ADDR sp) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_save_dummy_frame_tos != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_save_dummy_frame_tos called\n"); + gdbarch->deprecated_save_dummy_frame_tos (sp); +} + +void +set_gdbarch_deprecated_save_dummy_frame_tos (struct gdbarch *gdbarch, + gdbarch_deprecated_save_dummy_frame_tos_ftype deprecated_save_dummy_frame_tos) +{ + gdbarch->deprecated_save_dummy_frame_tos = deprecated_save_dummy_frame_tos; +} + +int +gdbarch_deprecated_fp_regnum (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of deprecated_fp_regnum, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_fp_regnum called\n"); + return gdbarch->deprecated_fp_regnum; +} + +void +set_gdbarch_deprecated_fp_regnum (struct gdbarch *gdbarch, + int deprecated_fp_regnum) +{ + gdbarch->deprecated_fp_regnum = deprecated_fp_regnum; +} + +int +gdbarch_deprecated_target_read_fp_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_target_read_fp != NULL; +} + +CORE_ADDR +gdbarch_deprecated_target_read_fp (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_target_read_fp != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_target_read_fp called\n"); + return gdbarch->deprecated_target_read_fp (); +} + +void +set_gdbarch_deprecated_target_read_fp (struct gdbarch *gdbarch, + gdbarch_deprecated_target_read_fp_ftype deprecated_target_read_fp) +{ + gdbarch->deprecated_target_read_fp = deprecated_target_read_fp; +} + +int +gdbarch_push_dummy_call_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->push_dummy_call != NULL; +} + +CORE_ADDR +gdbarch_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->push_dummy_call != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_push_dummy_call called\n"); + return gdbarch->push_dummy_call (gdbarch, func_addr, regcache, bp_addr, nargs, args, sp, struct_return, struct_addr); +} + +void +set_gdbarch_push_dummy_call (struct gdbarch *gdbarch, + gdbarch_push_dummy_call_ftype push_dummy_call) +{ + gdbarch->push_dummy_call = push_dummy_call; +} + +int +gdbarch_deprecated_push_arguments_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_push_arguments != NULL; +} + +CORE_ADDR +gdbarch_deprecated_push_arguments (struct gdbarch *gdbarch, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_push_arguments != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_push_arguments called\n"); + return gdbarch->deprecated_push_arguments (nargs, args, sp, struct_return, struct_addr); +} + +void +set_gdbarch_deprecated_push_arguments (struct gdbarch *gdbarch, + gdbarch_deprecated_push_arguments_ftype deprecated_push_arguments) +{ + gdbarch->deprecated_push_arguments = deprecated_push_arguments; +} + +int +gdbarch_deprecated_use_generic_dummy_frames (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of deprecated_use_generic_dummy_frames, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_use_generic_dummy_frames called\n"); + return gdbarch->deprecated_use_generic_dummy_frames; +} + +void +set_gdbarch_deprecated_use_generic_dummy_frames (struct gdbarch *gdbarch, + int deprecated_use_generic_dummy_frames) +{ + gdbarch->deprecated_use_generic_dummy_frames = deprecated_use_generic_dummy_frames; +} + +int +gdbarch_deprecated_push_return_address_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_push_return_address != NULL; +} + +CORE_ADDR +gdbarch_deprecated_push_return_address (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_push_return_address != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_push_return_address called\n"); + return gdbarch->deprecated_push_return_address (pc, sp); +} + +void +set_gdbarch_deprecated_push_return_address (struct gdbarch *gdbarch, + gdbarch_deprecated_push_return_address_ftype deprecated_push_return_address) +{ + gdbarch->deprecated_push_return_address = deprecated_push_return_address; +} + +int +gdbarch_deprecated_dummy_write_sp_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_dummy_write_sp != NULL; +} + +void +gdbarch_deprecated_dummy_write_sp (struct gdbarch *gdbarch, CORE_ADDR val) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_dummy_write_sp != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_dummy_write_sp called\n"); + gdbarch->deprecated_dummy_write_sp (val); +} + +void +set_gdbarch_deprecated_dummy_write_sp (struct gdbarch *gdbarch, + gdbarch_deprecated_dummy_write_sp_ftype deprecated_dummy_write_sp) +{ + gdbarch->deprecated_dummy_write_sp = deprecated_dummy_write_sp; +} + +int +gdbarch_deprecated_register_size (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_size called\n"); + return gdbarch->deprecated_register_size; +} + +void +set_gdbarch_deprecated_register_size (struct gdbarch *gdbarch, + int deprecated_register_size) +{ + gdbarch->deprecated_register_size = deprecated_register_size; +} + +int +gdbarch_call_dummy_location (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of call_dummy_location, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_location called\n"); + return gdbarch->call_dummy_location; +} + +void +set_gdbarch_call_dummy_location (struct gdbarch *gdbarch, + int call_dummy_location) +{ + gdbarch->call_dummy_location = call_dummy_location; +} + +CORE_ADDR +gdbarch_deprecated_call_dummy_start_offset (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_call_dummy_start_offset called\n"); + return gdbarch->deprecated_call_dummy_start_offset; +} + +void +set_gdbarch_deprecated_call_dummy_start_offset (struct gdbarch *gdbarch, + CORE_ADDR deprecated_call_dummy_start_offset) +{ + gdbarch->deprecated_call_dummy_start_offset = deprecated_call_dummy_start_offset; +} + +CORE_ADDR +gdbarch_deprecated_call_dummy_breakpoint_offset (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_call_dummy_breakpoint_offset called\n"); + return gdbarch->deprecated_call_dummy_breakpoint_offset; +} + +void +set_gdbarch_deprecated_call_dummy_breakpoint_offset (struct gdbarch *gdbarch, + CORE_ADDR deprecated_call_dummy_breakpoint_offset) +{ + gdbarch->deprecated_call_dummy_breakpoint_offset = deprecated_call_dummy_breakpoint_offset; +} + +int +gdbarch_deprecated_call_dummy_length (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_call_dummy_length called\n"); + return gdbarch->deprecated_call_dummy_length; +} + +void +set_gdbarch_deprecated_call_dummy_length (struct gdbarch *gdbarch, + int deprecated_call_dummy_length) +{ + gdbarch->deprecated_call_dummy_length = deprecated_call_dummy_length; +} + +LONGEST * +gdbarch_deprecated_call_dummy_words (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of deprecated_call_dummy_words, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_call_dummy_words called\n"); + return gdbarch->deprecated_call_dummy_words; +} + +void +set_gdbarch_deprecated_call_dummy_words (struct gdbarch *gdbarch, + LONGEST * deprecated_call_dummy_words) +{ + gdbarch->deprecated_call_dummy_words = deprecated_call_dummy_words; +} + +int +gdbarch_deprecated_sizeof_call_dummy_words (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of deprecated_sizeof_call_dummy_words, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_sizeof_call_dummy_words called\n"); + return gdbarch->deprecated_sizeof_call_dummy_words; +} + +void +set_gdbarch_deprecated_sizeof_call_dummy_words (struct gdbarch *gdbarch, + int deprecated_sizeof_call_dummy_words) +{ + gdbarch->deprecated_sizeof_call_dummy_words = deprecated_sizeof_call_dummy_words; +} + +int +gdbarch_deprecated_fix_call_dummy_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_fix_call_dummy != NULL; +} + +void +gdbarch_deprecated_fix_call_dummy (struct gdbarch *gdbarch, char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_fix_call_dummy != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_fix_call_dummy called\n"); + gdbarch->deprecated_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p); +} + +void +set_gdbarch_deprecated_fix_call_dummy (struct gdbarch *gdbarch, + gdbarch_deprecated_fix_call_dummy_ftype deprecated_fix_call_dummy) +{ + gdbarch->deprecated_fix_call_dummy = deprecated_fix_call_dummy; +} + +int +gdbarch_push_dummy_code_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->push_dummy_code != NULL; +} + +CORE_ADDR +gdbarch_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, struct value **args, int nargs, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->push_dummy_code != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_push_dummy_code called\n"); + return gdbarch->push_dummy_code (gdbarch, sp, funaddr, using_gcc, args, nargs, value_type, real_pc, bp_addr); +} + +void +set_gdbarch_push_dummy_code (struct gdbarch *gdbarch, + gdbarch_push_dummy_code_ftype push_dummy_code) +{ + gdbarch->push_dummy_code = push_dummy_code; +} + +int +gdbarch_deprecated_push_dummy_frame_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_push_dummy_frame != NULL; +} + +void +gdbarch_deprecated_push_dummy_frame (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_push_dummy_frame != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_push_dummy_frame called\n"); + gdbarch->deprecated_push_dummy_frame (); +} + +void +set_gdbarch_deprecated_push_dummy_frame (struct gdbarch *gdbarch, + gdbarch_deprecated_push_dummy_frame_ftype deprecated_push_dummy_frame) +{ + gdbarch->deprecated_push_dummy_frame = deprecated_push_dummy_frame; +} + +int +gdbarch_deprecated_do_registers_info_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_do_registers_info != NULL; +} + +void +gdbarch_deprecated_do_registers_info (struct gdbarch *gdbarch, int reg_nr, int fpregs) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_do_registers_info != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_do_registers_info called\n"); + gdbarch->deprecated_do_registers_info (reg_nr, fpregs); +} + +void +set_gdbarch_deprecated_do_registers_info (struct gdbarch *gdbarch, + gdbarch_deprecated_do_registers_info_ftype deprecated_do_registers_info) +{ + gdbarch->deprecated_do_registers_info = deprecated_do_registers_info; +} + +void +gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->print_registers_info != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_print_registers_info called\n"); + gdbarch->print_registers_info (gdbarch, file, frame, regnum, all); +} + +void +set_gdbarch_print_registers_info (struct gdbarch *gdbarch, + gdbarch_print_registers_info_ftype print_registers_info) +{ + gdbarch->print_registers_info = print_registers_info; +} + +int +gdbarch_print_float_info_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->print_float_info != NULL; +} + +void +gdbarch_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->print_float_info != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_print_float_info called\n"); - gdbarch->print_float_info (); + gdbarch->print_float_info (gdbarch, file, frame, args); } void @@ -2964,12 +3640,35 @@ set_gdbarch_print_float_info (struct gdbarch *gdbarch, gdbarch->print_float_info = print_float_info; } +int +gdbarch_print_vector_info_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->print_vector_info != NULL; +} + +void +gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->print_vector_info != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_print_vector_info called\n"); + gdbarch->print_vector_info (gdbarch, file, frame, args); +} + +void +set_gdbarch_print_vector_info (struct gdbarch *gdbarch, + gdbarch_print_vector_info_ftype print_vector_info) +{ + gdbarch->print_vector_info = print_vector_info; +} + int gdbarch_register_sim_regno (struct gdbarch *gdbarch, int reg_nr) { - if (gdbarch->register_sim_regno == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_sim_regno invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->register_sim_regno != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_register_sim_regno called\n"); return gdbarch->register_sim_regno (reg_nr); @@ -2985,15 +3684,15 @@ set_gdbarch_register_sim_regno (struct gdbarch *gdbarch, int gdbarch_register_bytes_ok_p (struct gdbarch *gdbarch) { - return gdbarch->register_bytes_ok != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->register_bytes_ok != NULL; } int gdbarch_register_bytes_ok (struct gdbarch *gdbarch, long nr_bytes) { - if (gdbarch->register_bytes_ok == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_bytes_ok invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->register_bytes_ok != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_register_bytes_ok called\n"); return gdbarch->register_bytes_ok (nr_bytes); @@ -3009,9 +3708,8 @@ set_gdbarch_register_bytes_ok (struct gdbarch *gdbarch, int gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, int regnum) { - if (gdbarch->cannot_fetch_register == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_cannot_fetch_register invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->cannot_fetch_register != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_cannot_fetch_register called\n"); return gdbarch->cannot_fetch_register (regnum); @@ -3027,9 +3725,8 @@ set_gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, int gdbarch_cannot_store_register (struct gdbarch *gdbarch, int regnum) { - if (gdbarch->cannot_store_register == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_cannot_store_register invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->cannot_store_register != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_cannot_store_register called\n"); return gdbarch->cannot_store_register (regnum); @@ -3045,15 +3742,15 @@ set_gdbarch_cannot_store_register (struct gdbarch *gdbarch, int gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch) { - return gdbarch->get_longjmp_target != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->get_longjmp_target != NULL; } int gdbarch_get_longjmp_target (struct gdbarch *gdbarch, CORE_ADDR *pc) { - if (gdbarch->get_longjmp_target == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_get_longjmp_target invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->get_longjmp_target != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_get_longjmp_target called\n"); return gdbarch->get_longjmp_target (pc); @@ -3067,292 +3764,82 @@ set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch, } int -gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch) +gdbarch_deprecated_pc_in_call_dummy_p (struct gdbarch *gdbarch) { - if (gdbarch->use_generic_dummy_frames == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_use_generic_dummy_frames invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_use_generic_dummy_frames called\n"); - return gdbarch->use_generic_dummy_frames; -} - -void -set_gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch, - int use_generic_dummy_frames) -{ - gdbarch->use_generic_dummy_frames = use_generic_dummy_frames; + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_pc_in_call_dummy != generic_pc_in_call_dummy; } int -gdbarch_call_dummy_location (struct gdbarch *gdbarch) +gdbarch_deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address) { - if (gdbarch->call_dummy_location == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_location invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_pc_in_call_dummy != NULL); + /* Do not check predicate: gdbarch->deprecated_pc_in_call_dummy != generic_pc_in_call_dummy, allow call. */ if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_location called\n"); - return gdbarch->call_dummy_location; + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_pc_in_call_dummy called\n"); + return gdbarch->deprecated_pc_in_call_dummy (pc, sp, frame_address); } void -set_gdbarch_call_dummy_location (struct gdbarch *gdbarch, - int call_dummy_location) +set_gdbarch_deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, + gdbarch_deprecated_pc_in_call_dummy_ftype deprecated_pc_in_call_dummy) { - gdbarch->call_dummy_location = call_dummy_location; + gdbarch->deprecated_pc_in_call_dummy = deprecated_pc_in_call_dummy; +} + +int +gdbarch_deprecated_init_frame_pc_first_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_init_frame_pc_first != NULL; } CORE_ADDR -gdbarch_call_dummy_address (struct gdbarch *gdbarch) +gdbarch_deprecated_init_frame_pc_first (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev) { - if (gdbarch->call_dummy_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_init_frame_pc_first != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_address called\n"); - return gdbarch->call_dummy_address (); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_init_frame_pc_first called\n"); + return gdbarch->deprecated_init_frame_pc_first (fromleaf, prev); } void -set_gdbarch_call_dummy_address (struct gdbarch *gdbarch, - gdbarch_call_dummy_address_ftype call_dummy_address) +set_gdbarch_deprecated_init_frame_pc_first (struct gdbarch *gdbarch, + gdbarch_deprecated_init_frame_pc_first_ftype deprecated_init_frame_pc_first) { - gdbarch->call_dummy_address = call_dummy_address; + gdbarch->deprecated_init_frame_pc_first = deprecated_init_frame_pc_first; +} + +int +gdbarch_deprecated_init_frame_pc_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_init_frame_pc != NULL; } CORE_ADDR -gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch) +gdbarch_deprecated_init_frame_pc (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev) { - if (gdbarch->call_dummy_start_offset == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_start_offset invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_init_frame_pc != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_start_offset called\n"); - return gdbarch->call_dummy_start_offset; + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_init_frame_pc called\n"); + return gdbarch->deprecated_init_frame_pc (fromleaf, prev); } void -set_gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch, - CORE_ADDR call_dummy_start_offset) +set_gdbarch_deprecated_init_frame_pc (struct gdbarch *gdbarch, + gdbarch_deprecated_init_frame_pc_ftype deprecated_init_frame_pc) { - gdbarch->call_dummy_start_offset = call_dummy_start_offset; -} - -CORE_ADDR -gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch) -{ - if (gdbarch->call_dummy_breakpoint_offset_p && gdbarch->call_dummy_breakpoint_offset == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_breakpoint_offset invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_breakpoint_offset called\n"); - return gdbarch->call_dummy_breakpoint_offset; -} - -void -set_gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch, - CORE_ADDR call_dummy_breakpoint_offset) -{ - gdbarch->call_dummy_breakpoint_offset = call_dummy_breakpoint_offset; -} - -int -gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch) -{ - if (gdbarch->call_dummy_breakpoint_offset_p == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_breakpoint_offset_p invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_breakpoint_offset_p called\n"); - return gdbarch->call_dummy_breakpoint_offset_p; -} - -void -set_gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch, - int call_dummy_breakpoint_offset_p) -{ - gdbarch->call_dummy_breakpoint_offset_p = call_dummy_breakpoint_offset_p; -} - -int -gdbarch_call_dummy_length (struct gdbarch *gdbarch) -{ - if (gdbarch->call_dummy_length == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_length invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_length called\n"); - return gdbarch->call_dummy_length; -} - -void -set_gdbarch_call_dummy_length (struct gdbarch *gdbarch, - int call_dummy_length) -{ - gdbarch->call_dummy_length = call_dummy_length; -} - -int -gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address) -{ - if (gdbarch->pc_in_call_dummy == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_pc_in_call_dummy invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_in_call_dummy called\n"); - return gdbarch->pc_in_call_dummy (pc, sp, frame_address); -} - -void -set_gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch, - gdbarch_pc_in_call_dummy_ftype pc_in_call_dummy) -{ - gdbarch->pc_in_call_dummy = pc_in_call_dummy; -} - -int -gdbarch_call_dummy_p (struct gdbarch *gdbarch) -{ - if (gdbarch->call_dummy_p == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_p invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_p called\n"); - return gdbarch->call_dummy_p; -} - -void -set_gdbarch_call_dummy_p (struct gdbarch *gdbarch, - int call_dummy_p) -{ - gdbarch->call_dummy_p = call_dummy_p; -} - -LONGEST * -gdbarch_call_dummy_words (struct gdbarch *gdbarch) -{ - /* Skip verify of call_dummy_words, invalid_p == 0 */ - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_words called\n"); - return gdbarch->call_dummy_words; -} - -void -set_gdbarch_call_dummy_words (struct gdbarch *gdbarch, - LONGEST * call_dummy_words) -{ - gdbarch->call_dummy_words = call_dummy_words; -} - -int -gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch) -{ - /* Skip verify of sizeof_call_dummy_words, invalid_p == 0 */ - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_sizeof_call_dummy_words called\n"); - return gdbarch->sizeof_call_dummy_words; -} - -void -set_gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch, - int sizeof_call_dummy_words) -{ - gdbarch->sizeof_call_dummy_words = sizeof_call_dummy_words; -} - -int -gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch) -{ - if (gdbarch->call_dummy_stack_adjust_p == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_stack_adjust_p invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_stack_adjust_p called\n"); - return gdbarch->call_dummy_stack_adjust_p; -} - -void -set_gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch, - int call_dummy_stack_adjust_p) -{ - gdbarch->call_dummy_stack_adjust_p = call_dummy_stack_adjust_p; -} - -int -gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch) -{ - if (gdbarch->call_dummy_stack_adjust_p && gdbarch->call_dummy_stack_adjust == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_call_dummy_stack_adjust invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_stack_adjust called\n"); - return gdbarch->call_dummy_stack_adjust; -} - -void -set_gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch, - int call_dummy_stack_adjust) -{ - gdbarch->call_dummy_stack_adjust = call_dummy_stack_adjust; -} - -void -gdbarch_fix_call_dummy (struct gdbarch *gdbarch, char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p) -{ - if (gdbarch->fix_call_dummy == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_fix_call_dummy invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_fix_call_dummy called\n"); - gdbarch->fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p); -} - -void -set_gdbarch_fix_call_dummy (struct gdbarch *gdbarch, - gdbarch_fix_call_dummy_ftype fix_call_dummy) -{ - gdbarch->fix_call_dummy = fix_call_dummy; -} - -void -gdbarch_init_frame_pc_first (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev) -{ - if (gdbarch->init_frame_pc_first == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_init_frame_pc_first invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_init_frame_pc_first called\n"); - gdbarch->init_frame_pc_first (fromleaf, prev); -} - -void -set_gdbarch_init_frame_pc_first (struct gdbarch *gdbarch, - gdbarch_init_frame_pc_first_ftype init_frame_pc_first) -{ - gdbarch->init_frame_pc_first = init_frame_pc_first; -} - -void -gdbarch_init_frame_pc (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev) -{ - if (gdbarch->init_frame_pc == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_init_frame_pc invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_init_frame_pc called\n"); - gdbarch->init_frame_pc (fromleaf, prev); -} - -void -set_gdbarch_init_frame_pc (struct gdbarch *gdbarch, - gdbarch_init_frame_pc_ftype init_frame_pc) -{ - gdbarch->init_frame_pc = init_frame_pc; + gdbarch->deprecated_init_frame_pc = deprecated_init_frame_pc; } int gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_believe_pcc_promotion called\n"); return gdbarch->believe_pcc_promotion; @@ -3368,6 +3855,7 @@ set_gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch, int gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_believe_pcc_promotion_type called\n"); return gdbarch->believe_pcc_promotion_type; @@ -3381,149 +3869,143 @@ set_gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch, } int -gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, struct type *formal, struct type *actual) +gdbarch_deprecated_get_saved_register_p (struct gdbarch *gdbarch) { - if (gdbarch->coerce_float_to_double == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_coerce_float_to_double invalid"); + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_get_saved_register != NULL; +} + +void +gdbarch_deprecated_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_get_saved_register != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_coerce_float_to_double called\n"); - return gdbarch->coerce_float_to_double (formal, actual); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_get_saved_register called\n"); + gdbarch->deprecated_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval); } void -set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, - gdbarch_coerce_float_to_double_ftype coerce_float_to_double) +set_gdbarch_deprecated_get_saved_register (struct gdbarch *gdbarch, + gdbarch_deprecated_get_saved_register_ftype deprecated_get_saved_register) { - gdbarch->coerce_float_to_double = coerce_float_to_double; -} - -void -gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval) -{ - if (gdbarch->get_saved_register == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_get_saved_register invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_get_saved_register called\n"); - gdbarch->get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval); -} - -void -set_gdbarch_get_saved_register (struct gdbarch *gdbarch, - gdbarch_get_saved_register_ftype get_saved_register) -{ - gdbarch->get_saved_register = get_saved_register; + gdbarch->deprecated_get_saved_register = deprecated_get_saved_register; } int -gdbarch_register_convertible (struct gdbarch *gdbarch, int nr) +gdbarch_deprecated_register_convertible_p (struct gdbarch *gdbarch) { - if (gdbarch->register_convertible == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_convertible invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_convertible called\n"); - return gdbarch->register_convertible (nr); -} - -void -set_gdbarch_register_convertible (struct gdbarch *gdbarch, - gdbarch_register_convertible_ftype register_convertible) -{ - gdbarch->register_convertible = register_convertible; -} - -void -gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to) -{ - if (gdbarch->register_convert_to_virtual == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_convert_to_virtual invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_convert_to_virtual called\n"); - gdbarch->register_convert_to_virtual (regnum, type, from, to); -} - -void -set_gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch, - gdbarch_register_convert_to_virtual_ftype register_convert_to_virtual) -{ - gdbarch->register_convert_to_virtual = register_convert_to_virtual; -} - -void -gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to) -{ - if (gdbarch->register_convert_to_raw == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_register_convert_to_raw invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_register_convert_to_raw called\n"); - gdbarch->register_convert_to_raw (type, regnum, from, to); -} - -void -set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, - gdbarch_register_convert_to_raw_ftype register_convert_to_raw) -{ - gdbarch->register_convert_to_raw = register_convert_to_raw; + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_register_convertible != NULL; } int -gdbarch_fetch_pseudo_register_p (struct gdbarch *gdbarch) +gdbarch_deprecated_register_convertible (struct gdbarch *gdbarch, int nr) { - return gdbarch->fetch_pseudo_register != 0; -} - -void -gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch, int regnum) -{ - if (gdbarch->fetch_pseudo_register == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_fetch_pseudo_register invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_register_convertible != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_fetch_pseudo_register called\n"); - gdbarch->fetch_pseudo_register (regnum); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_convertible called\n"); + return gdbarch->deprecated_register_convertible (nr); } void -set_gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch, - gdbarch_fetch_pseudo_register_ftype fetch_pseudo_register) +set_gdbarch_deprecated_register_convertible (struct gdbarch *gdbarch, + gdbarch_deprecated_register_convertible_ftype deprecated_register_convertible) { - gdbarch->fetch_pseudo_register = fetch_pseudo_register; + gdbarch->deprecated_register_convertible = deprecated_register_convertible; +} + +void +gdbarch_deprecated_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_register_convert_to_virtual != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_convert_to_virtual called\n"); + gdbarch->deprecated_register_convert_to_virtual (regnum, type, from, to); +} + +void +set_gdbarch_deprecated_register_convert_to_virtual (struct gdbarch *gdbarch, + gdbarch_deprecated_register_convert_to_virtual_ftype deprecated_register_convert_to_virtual) +{ + gdbarch->deprecated_register_convert_to_virtual = deprecated_register_convert_to_virtual; +} + +void +gdbarch_deprecated_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type, int regnum, const char *from, char *to) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_register_convert_to_raw != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_register_convert_to_raw called\n"); + gdbarch->deprecated_register_convert_to_raw (type, regnum, from, to); +} + +void +set_gdbarch_deprecated_register_convert_to_raw (struct gdbarch *gdbarch, + gdbarch_deprecated_register_convert_to_raw_ftype deprecated_register_convert_to_raw) +{ + gdbarch->deprecated_register_convert_to_raw = deprecated_register_convert_to_raw; } int -gdbarch_store_pseudo_register_p (struct gdbarch *gdbarch) +gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) { - return gdbarch->store_pseudo_register != 0; -} - -void -gdbarch_store_pseudo_register (struct gdbarch *gdbarch, int regnum) -{ - if (gdbarch->store_pseudo_register == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_store_pseudo_register invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->convert_register_p != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_store_pseudo_register called\n"); - gdbarch->store_pseudo_register (regnum); + fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_register_p called\n"); + return gdbarch->convert_register_p (regnum, type); } void -set_gdbarch_store_pseudo_register (struct gdbarch *gdbarch, - gdbarch_store_pseudo_register_ftype store_pseudo_register) +set_gdbarch_convert_register_p (struct gdbarch *gdbarch, + gdbarch_convert_register_p_ftype convert_register_p) { - gdbarch->store_pseudo_register = store_pseudo_register; + gdbarch->convert_register_p = convert_register_p; +} + +void +gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->register_to_value != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_register_to_value called\n"); + gdbarch->register_to_value (frame, regnum, type, buf); +} + +void +set_gdbarch_register_to_value (struct gdbarch *gdbarch, + gdbarch_register_to_value_ftype register_to_value) +{ + gdbarch->register_to_value = register_to_value; +} + +void +gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const void *buf) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->value_to_register != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_value_to_register called\n"); + gdbarch->value_to_register (frame, regnum, type, buf); +} + +void +set_gdbarch_value_to_register (struct gdbarch *gdbarch, + gdbarch_value_to_register_ftype value_to_register) +{ + gdbarch->value_to_register = value_to_register; } CORE_ADDR -gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf) +gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const void *buf) { - if (gdbarch->pointer_to_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_pointer_to_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->pointer_to_address != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_pointer_to_address called\n"); return gdbarch->pointer_to_address (type, buf); @@ -3539,9 +4021,8 @@ set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, void gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, void *buf, CORE_ADDR addr) { - if (gdbarch->address_to_pointer == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_address_to_pointer invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->address_to_pointer != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_address_to_pointer called\n"); gdbarch->address_to_pointer (type, buf, addr); @@ -3557,15 +4038,15 @@ set_gdbarch_address_to_pointer (struct gdbarch *gdbarch, int gdbarch_integer_to_address_p (struct gdbarch *gdbarch) { - return gdbarch->integer_to_address != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->integer_to_address != NULL; } CORE_ADDR gdbarch_integer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf) { - if (gdbarch->integer_to_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_integer_to_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->integer_to_address != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_integer_to_address called\n"); return gdbarch->integer_to_address (type, buf); @@ -3578,12 +4059,83 @@ set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch->integer_to_address = integer_to_address; } +int +gdbarch_deprecated_pop_frame_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_pop_frame != NULL; +} + +void +gdbarch_deprecated_pop_frame (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_pop_frame != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_pop_frame called\n"); + gdbarch->deprecated_pop_frame (); +} + +void +set_gdbarch_deprecated_pop_frame (struct gdbarch *gdbarch, + gdbarch_deprecated_pop_frame_ftype deprecated_pop_frame) +{ + gdbarch->deprecated_pop_frame = deprecated_pop_frame; +} + +int +gdbarch_deprecated_store_struct_return_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_store_struct_return != NULL; +} + +void +gdbarch_deprecated_store_struct_return (struct gdbarch *gdbarch, CORE_ADDR addr, CORE_ADDR sp) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_store_struct_return != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_store_struct_return called\n"); + gdbarch->deprecated_store_struct_return (addr, sp); +} + +void +set_gdbarch_deprecated_store_struct_return (struct gdbarch *gdbarch, + gdbarch_deprecated_store_struct_return_ftype deprecated_store_struct_return) +{ + gdbarch->deprecated_store_struct_return = deprecated_store_struct_return; +} + +int +gdbarch_return_value_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->return_value != NULL; +} + +enum return_value_convention +gdbarch_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->return_value != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value called\n"); + return gdbarch->return_value (gdbarch, valtype, regcache, readbuf, writebuf); +} + +void +set_gdbarch_return_value (struct gdbarch *gdbarch, + gdbarch_return_value_ftype return_value) +{ + gdbarch->return_value = return_value; +} + int gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type) { - if (gdbarch->return_value_on_stack == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_return_value_on_stack invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->return_value_on_stack != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value_on_stack called\n"); return gdbarch->return_value_on_stack (type); @@ -3597,14 +4149,13 @@ set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch, } void -gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf) +gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, void *valbuf) { - if (gdbarch->extract_return_value == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_extract_return_value invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->extract_return_value != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_extract_return_value called\n"); - gdbarch->extract_return_value (type, regbuf, valbuf); + gdbarch->extract_return_value (type, regcache, valbuf); } void @@ -3614,111 +4165,14 @@ set_gdbarch_extract_return_value (struct gdbarch *gdbarch, gdbarch->extract_return_value = extract_return_value; } -CORE_ADDR -gdbarch_push_arguments (struct gdbarch *gdbarch, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) -{ - if (gdbarch->push_arguments == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_push_arguments invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_push_arguments called\n"); - return gdbarch->push_arguments (nargs, args, sp, struct_return, struct_addr); -} - void -set_gdbarch_push_arguments (struct gdbarch *gdbarch, - gdbarch_push_arguments_ftype push_arguments) +gdbarch_store_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, const void *valbuf) { - gdbarch->push_arguments = push_arguments; -} - -void -gdbarch_push_dummy_frame (struct gdbarch *gdbarch) -{ - if (gdbarch->push_dummy_frame == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_push_dummy_frame invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_push_dummy_frame called\n"); - gdbarch->push_dummy_frame (); -} - -void -set_gdbarch_push_dummy_frame (struct gdbarch *gdbarch, - gdbarch_push_dummy_frame_ftype push_dummy_frame) -{ - gdbarch->push_dummy_frame = push_dummy_frame; -} - -int -gdbarch_push_return_address_p (struct gdbarch *gdbarch) -{ - return gdbarch->push_return_address != 0; -} - -CORE_ADDR -gdbarch_push_return_address (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp) -{ - if (gdbarch->push_return_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_push_return_address invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_push_return_address called\n"); - return gdbarch->push_return_address (pc, sp); -} - -void -set_gdbarch_push_return_address (struct gdbarch *gdbarch, - gdbarch_push_return_address_ftype push_return_address) -{ - gdbarch->push_return_address = push_return_address; -} - -void -gdbarch_pop_frame (struct gdbarch *gdbarch) -{ - if (gdbarch->pop_frame == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_pop_frame invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_pop_frame called\n"); - gdbarch->pop_frame (); -} - -void -set_gdbarch_pop_frame (struct gdbarch *gdbarch, - gdbarch_pop_frame_ftype pop_frame) -{ - gdbarch->pop_frame = pop_frame; -} - -void -gdbarch_store_struct_return (struct gdbarch *gdbarch, CORE_ADDR addr, CORE_ADDR sp) -{ - if (gdbarch->store_struct_return == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_store_struct_return invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_store_struct_return called\n"); - gdbarch->store_struct_return (addr, sp); -} - -void -set_gdbarch_store_struct_return (struct gdbarch *gdbarch, - gdbarch_store_struct_return_ftype store_struct_return) -{ - gdbarch->store_struct_return = store_struct_return; -} - -void -gdbarch_store_return_value (struct gdbarch *gdbarch, struct type *type, char *valbuf) -{ - if (gdbarch->store_return_value == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_store_return_value invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->store_return_value != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_store_return_value called\n"); - gdbarch->store_return_value (type, valbuf); + gdbarch->store_return_value (type, regcache, valbuf); } void @@ -3728,36 +4182,45 @@ set_gdbarch_store_return_value (struct gdbarch *gdbarch, gdbarch->store_return_value = store_return_value; } -int -gdbarch_extract_struct_value_address_p (struct gdbarch *gdbarch) +void +gdbarch_deprecated_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf) { - return gdbarch->extract_struct_value_address != 0; -} - -CORE_ADDR -gdbarch_extract_struct_value_address (struct gdbarch *gdbarch, char *regbuf) -{ - if (gdbarch->extract_struct_value_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_extract_struct_value_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_extract_return_value != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_extract_struct_value_address called\n"); - return gdbarch->extract_struct_value_address (regbuf); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_extract_return_value called\n"); + gdbarch->deprecated_extract_return_value (type, regbuf, valbuf); } void -set_gdbarch_extract_struct_value_address (struct gdbarch *gdbarch, - gdbarch_extract_struct_value_address_ftype extract_struct_value_address) +set_gdbarch_deprecated_extract_return_value (struct gdbarch *gdbarch, + gdbarch_deprecated_extract_return_value_ftype deprecated_extract_return_value) { - gdbarch->extract_struct_value_address = extract_struct_value_address; + gdbarch->deprecated_extract_return_value = deprecated_extract_return_value; +} + +void +gdbarch_deprecated_store_return_value (struct gdbarch *gdbarch, struct type *type, char *valbuf) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_store_return_value != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_store_return_value called\n"); + gdbarch->deprecated_store_return_value (type, valbuf); +} + +void +set_gdbarch_deprecated_store_return_value (struct gdbarch *gdbarch, + gdbarch_deprecated_store_return_value_ftype deprecated_store_return_value) +{ + gdbarch->deprecated_store_return_value = deprecated_store_return_value; } int gdbarch_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type) { - if (gdbarch->use_struct_convention == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_use_struct_convention invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->use_struct_convention != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_use_struct_convention called\n"); return gdbarch->use_struct_convention (gcc_p, value_type); @@ -3770,54 +4233,83 @@ set_gdbarch_use_struct_convention (struct gdbarch *gdbarch, gdbarch->use_struct_convention = use_struct_convention; } -void -gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch, struct frame_info *frame) +int +gdbarch_deprecated_extract_struct_value_address_p (struct gdbarch *gdbarch) { - if (gdbarch->frame_init_saved_regs == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_init_saved_regs invalid"); + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_extract_struct_value_address != NULL; +} + +CORE_ADDR +gdbarch_deprecated_extract_struct_value_address (struct gdbarch *gdbarch, struct regcache *regcache) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_extract_struct_value_address != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_init_saved_regs called\n"); - gdbarch->frame_init_saved_regs (frame); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_extract_struct_value_address called\n"); + return gdbarch->deprecated_extract_struct_value_address (regcache); } void -set_gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch, - gdbarch_frame_init_saved_regs_ftype frame_init_saved_regs) +set_gdbarch_deprecated_extract_struct_value_address (struct gdbarch *gdbarch, + gdbarch_deprecated_extract_struct_value_address_ftype deprecated_extract_struct_value_address) { - gdbarch->frame_init_saved_regs = frame_init_saved_regs; + gdbarch->deprecated_extract_struct_value_address = deprecated_extract_struct_value_address; } int -gdbarch_init_extra_frame_info_p (struct gdbarch *gdbarch) +gdbarch_deprecated_frame_init_saved_regs_p (struct gdbarch *gdbarch) { - return gdbarch->init_extra_frame_info != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_frame_init_saved_regs != NULL; } void -gdbarch_init_extra_frame_info (struct gdbarch *gdbarch, int fromleaf, struct frame_info *frame) +gdbarch_deprecated_frame_init_saved_regs (struct gdbarch *gdbarch, struct frame_info *frame) { - if (gdbarch->init_extra_frame_info == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_init_extra_frame_info invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_frame_init_saved_regs != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_init_extra_frame_info called\n"); - gdbarch->init_extra_frame_info (fromleaf, frame); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_frame_init_saved_regs called\n"); + gdbarch->deprecated_frame_init_saved_regs (frame); } void -set_gdbarch_init_extra_frame_info (struct gdbarch *gdbarch, - gdbarch_init_extra_frame_info_ftype init_extra_frame_info) +set_gdbarch_deprecated_frame_init_saved_regs (struct gdbarch *gdbarch, + gdbarch_deprecated_frame_init_saved_regs_ftype deprecated_frame_init_saved_regs) { - gdbarch->init_extra_frame_info = init_extra_frame_info; + gdbarch->deprecated_frame_init_saved_regs = deprecated_frame_init_saved_regs; +} + +int +gdbarch_deprecated_init_extra_frame_info_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_init_extra_frame_info != NULL; +} + +void +gdbarch_deprecated_init_extra_frame_info (struct gdbarch *gdbarch, int fromleaf, struct frame_info *frame) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_init_extra_frame_info != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_init_extra_frame_info called\n"); + gdbarch->deprecated_init_extra_frame_info (fromleaf, frame); +} + +void +set_gdbarch_deprecated_init_extra_frame_info (struct gdbarch *gdbarch, + gdbarch_deprecated_init_extra_frame_info_ftype deprecated_init_extra_frame_info) +{ + gdbarch->deprecated_init_extra_frame_info = deprecated_init_extra_frame_info; } CORE_ADDR gdbarch_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip) { - if (gdbarch->skip_prologue == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_skip_prologue invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->skip_prologue != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_prologue called\n"); return gdbarch->skip_prologue (ip); @@ -3830,30 +4322,11 @@ set_gdbarch_skip_prologue (struct gdbarch *gdbarch, gdbarch->skip_prologue = skip_prologue; } -int -gdbarch_prologue_frameless_p (struct gdbarch *gdbarch, CORE_ADDR ip) -{ - if (gdbarch->prologue_frameless_p == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_prologue_frameless_p invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_prologue_frameless_p called\n"); - return gdbarch->prologue_frameless_p (ip); -} - -void -set_gdbarch_prologue_frameless_p (struct gdbarch *gdbarch, - gdbarch_prologue_frameless_p_ftype prologue_frameless_p) -{ - gdbarch->prologue_frameless_p = prologue_frameless_p; -} - int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs) { - if (gdbarch->inner_than == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_inner_than invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->inner_than != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_inner_than called\n"); return gdbarch->inner_than (lhs, rhs); @@ -3866,12 +4339,11 @@ set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch->inner_than = inner_than; } -unsigned char * +const unsigned char * gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) { - if (gdbarch->breakpoint_from_pc == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_breakpoint_from_pc invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->breakpoint_from_pc != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_breakpoint_from_pc called\n"); return gdbarch->breakpoint_from_pc (pcptr, lenptr); @@ -3884,12 +4356,35 @@ set_gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, gdbarch->breakpoint_from_pc = breakpoint_from_pc; } +int +gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->adjust_breakpoint_address != NULL; +} + +CORE_ADDR +gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->adjust_breakpoint_address != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_adjust_breakpoint_address called\n"); + return gdbarch->adjust_breakpoint_address (gdbarch, bpaddr); +} + +void +set_gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, + gdbarch_adjust_breakpoint_address_ftype adjust_breakpoint_address) +{ + gdbarch->adjust_breakpoint_address = adjust_breakpoint_address; +} + int gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache) { - if (gdbarch->memory_insert_breakpoint == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_memory_insert_breakpoint invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->memory_insert_breakpoint != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_insert_breakpoint called\n"); return gdbarch->memory_insert_breakpoint (addr, contents_cache); @@ -3905,9 +4400,8 @@ set_gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, int gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache) { - if (gdbarch->memory_remove_breakpoint == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_memory_remove_breakpoint invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->memory_remove_breakpoint != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_remove_breakpoint called\n"); return gdbarch->memory_remove_breakpoint (addr, contents_cache); @@ -3923,9 +4417,8 @@ set_gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, CORE_ADDR gdbarch_decr_pc_after_break (struct gdbarch *gdbarch) { - if (gdbarch->decr_pc_after_break == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_decr_pc_after_break invalid"); + gdb_assert (gdbarch != NULL); + /* Skip verify of decr_pc_after_break, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_decr_pc_after_break called\n"); return gdbarch->decr_pc_after_break; @@ -3938,30 +4431,11 @@ set_gdbarch_decr_pc_after_break (struct gdbarch *gdbarch, gdbarch->decr_pc_after_break = decr_pc_after_break; } -int -gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, int select_it) -{ - if (gdbarch->prepare_to_proceed == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_prepare_to_proceed invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_prepare_to_proceed called\n"); - return gdbarch->prepare_to_proceed (select_it); -} - -void -set_gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, - gdbarch_prepare_to_proceed_ftype prepare_to_proceed) -{ - gdbarch->prepare_to_proceed = prepare_to_proceed; -} - CORE_ADDR gdbarch_function_start_offset (struct gdbarch *gdbarch) { - if (gdbarch->function_start_offset == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_function_start_offset invalid"); + gdb_assert (gdbarch != NULL); + /* Skip verify of function_start_offset, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_function_start_offset called\n"); return gdbarch->function_start_offset; @@ -3975,14 +4449,13 @@ set_gdbarch_function_start_offset (struct gdbarch *gdbarch, } void -gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len) +gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len) { - if (gdbarch->remote_translate_xfer_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_remote_translate_xfer_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->remote_translate_xfer_address != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_remote_translate_xfer_address called\n"); - gdbarch->remote_translate_xfer_address (gdb_addr, gdb_len, rem_addr, rem_len); + gdbarch->remote_translate_xfer_address (gdbarch, regcache, gdb_addr, gdb_len, rem_addr, rem_len); } void @@ -3995,9 +4468,8 @@ set_gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch) { - if (gdbarch->frame_args_skip == -1) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_args_skip invalid"); + gdb_assert (gdbarch != NULL); + /* Skip verify of frame_args_skip, invalid_p == 0 */ if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_args_skip called\n"); return gdbarch->frame_args_skip; @@ -4011,137 +4483,235 @@ set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, } int -gdbarch_frameless_function_invocation (struct gdbarch *gdbarch, struct frame_info *fi) +gdbarch_deprecated_frameless_function_invocation_p (struct gdbarch *gdbarch) { - if (gdbarch->frameless_function_invocation == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frameless_function_invocation invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_frameless_function_invocation called\n"); - return gdbarch->frameless_function_invocation (fi); -} - -void -set_gdbarch_frameless_function_invocation (struct gdbarch *gdbarch, - gdbarch_frameless_function_invocation_ftype frameless_function_invocation) -{ - gdbarch->frameless_function_invocation = frameless_function_invocation; -} - -CORE_ADDR -gdbarch_frame_chain (struct gdbarch *gdbarch, struct frame_info *frame) -{ - if (gdbarch->frame_chain == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_chain invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_chain called\n"); - return gdbarch->frame_chain (frame); -} - -void -set_gdbarch_frame_chain (struct gdbarch *gdbarch, - gdbarch_frame_chain_ftype frame_chain) -{ - gdbarch->frame_chain = frame_chain; + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_frameless_function_invocation != NULL; } int -gdbarch_frame_chain_valid (struct gdbarch *gdbarch, CORE_ADDR chain, struct frame_info *thisframe) +gdbarch_deprecated_frameless_function_invocation (struct gdbarch *gdbarch, struct frame_info *fi) { - if (gdbarch->frame_chain_valid == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_chain_valid invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_frameless_function_invocation != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_chain_valid called\n"); - return gdbarch->frame_chain_valid (chain, thisframe); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_frameless_function_invocation called\n"); + return gdbarch->deprecated_frameless_function_invocation (fi); } void -set_gdbarch_frame_chain_valid (struct gdbarch *gdbarch, - gdbarch_frame_chain_valid_ftype frame_chain_valid) +set_gdbarch_deprecated_frameless_function_invocation (struct gdbarch *gdbarch, + gdbarch_deprecated_frameless_function_invocation_ftype deprecated_frameless_function_invocation) { - gdbarch->frame_chain_valid = frame_chain_valid; + gdbarch->deprecated_frameless_function_invocation = deprecated_frameless_function_invocation; +} + +int +gdbarch_deprecated_frame_chain_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_frame_chain != NULL; } CORE_ADDR -gdbarch_frame_saved_pc (struct gdbarch *gdbarch, struct frame_info *fi) +gdbarch_deprecated_frame_chain (struct gdbarch *gdbarch, struct frame_info *frame) { - if (gdbarch->frame_saved_pc == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_saved_pc invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_frame_chain != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_saved_pc called\n"); - return gdbarch->frame_saved_pc (fi); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_frame_chain called\n"); + return gdbarch->deprecated_frame_chain (frame); } void -set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch, - gdbarch_frame_saved_pc_ftype frame_saved_pc) +set_gdbarch_deprecated_frame_chain (struct gdbarch *gdbarch, + gdbarch_deprecated_frame_chain_ftype deprecated_frame_chain) { - gdbarch->frame_saved_pc = frame_saved_pc; + gdbarch->deprecated_frame_chain = deprecated_frame_chain; +} + +int +gdbarch_deprecated_frame_chain_valid_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_frame_chain_valid != NULL; +} + +int +gdbarch_deprecated_frame_chain_valid (struct gdbarch *gdbarch, CORE_ADDR chain, struct frame_info *thisframe) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_frame_chain_valid != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_frame_chain_valid called\n"); + return gdbarch->deprecated_frame_chain_valid (chain, thisframe); +} + +void +set_gdbarch_deprecated_frame_chain_valid (struct gdbarch *gdbarch, + gdbarch_deprecated_frame_chain_valid_ftype deprecated_frame_chain_valid) +{ + gdbarch->deprecated_frame_chain_valid = deprecated_frame_chain_valid; +} + +int +gdbarch_deprecated_frame_saved_pc_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_frame_saved_pc != NULL; } CORE_ADDR -gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi) +gdbarch_deprecated_frame_saved_pc (struct gdbarch *gdbarch, struct frame_info *fi) { - if (gdbarch->frame_args_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_args_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_frame_saved_pc != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_args_address called\n"); - return gdbarch->frame_args_address (fi); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_frame_saved_pc called\n"); + return gdbarch->deprecated_frame_saved_pc (fi); } void -set_gdbarch_frame_args_address (struct gdbarch *gdbarch, - gdbarch_frame_args_address_ftype frame_args_address) +set_gdbarch_deprecated_frame_saved_pc (struct gdbarch *gdbarch, + gdbarch_deprecated_frame_saved_pc_ftype deprecated_frame_saved_pc) { - gdbarch->frame_args_address = frame_args_address; + gdbarch->deprecated_frame_saved_pc = deprecated_frame_saved_pc; +} + +int +gdbarch_unwind_pc_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->unwind_pc != NULL; } CORE_ADDR -gdbarch_frame_locals_address (struct gdbarch *gdbarch, struct frame_info *fi) +gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - if (gdbarch->frame_locals_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_locals_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->unwind_pc != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_locals_address called\n"); - return gdbarch->frame_locals_address (fi); + fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_pc called\n"); + return gdbarch->unwind_pc (gdbarch, next_frame); } void -set_gdbarch_frame_locals_address (struct gdbarch *gdbarch, - gdbarch_frame_locals_address_ftype frame_locals_address) +set_gdbarch_unwind_pc (struct gdbarch *gdbarch, + gdbarch_unwind_pc_ftype unwind_pc) { - gdbarch->frame_locals_address = frame_locals_address; + gdbarch->unwind_pc = unwind_pc; +} + +int +gdbarch_unwind_sp_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->unwind_sp != NULL; } CORE_ADDR -gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame) +gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) { - if (gdbarch->saved_pc_after_call == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_saved_pc_after_call invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->unwind_sp != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_saved_pc_after_call called\n"); - return gdbarch->saved_pc_after_call (frame); + fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_sp called\n"); + return gdbarch->unwind_sp (gdbarch, next_frame); } void -set_gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, - gdbarch_saved_pc_after_call_ftype saved_pc_after_call) +set_gdbarch_unwind_sp (struct gdbarch *gdbarch, + gdbarch_unwind_sp_ftype unwind_sp) { - gdbarch->saved_pc_after_call = saved_pc_after_call; + gdbarch->unwind_sp = unwind_sp; +} + +int +gdbarch_deprecated_frame_args_address_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_frame_args_address != get_frame_base; +} + +CORE_ADDR +gdbarch_deprecated_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_frame_args_address != NULL); + /* Do not check predicate: gdbarch->deprecated_frame_args_address != get_frame_base, allow call. */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_frame_args_address called\n"); + return gdbarch->deprecated_frame_args_address (fi); +} + +void +set_gdbarch_deprecated_frame_args_address (struct gdbarch *gdbarch, + gdbarch_deprecated_frame_args_address_ftype deprecated_frame_args_address) +{ + gdbarch->deprecated_frame_args_address = deprecated_frame_args_address; +} + +int +gdbarch_deprecated_frame_locals_address_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_frame_locals_address != get_frame_base; +} + +CORE_ADDR +gdbarch_deprecated_frame_locals_address (struct gdbarch *gdbarch, struct frame_info *fi) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_frame_locals_address != NULL); + /* Do not check predicate: gdbarch->deprecated_frame_locals_address != get_frame_base, allow call. */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_frame_locals_address called\n"); + return gdbarch->deprecated_frame_locals_address (fi); +} + +void +set_gdbarch_deprecated_frame_locals_address (struct gdbarch *gdbarch, + gdbarch_deprecated_frame_locals_address_ftype deprecated_frame_locals_address) +{ + gdbarch->deprecated_frame_locals_address = deprecated_frame_locals_address; +} + +int +gdbarch_deprecated_saved_pc_after_call_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_saved_pc_after_call != NULL; +} + +CORE_ADDR +gdbarch_deprecated_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_saved_pc_after_call != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_saved_pc_after_call called\n"); + return gdbarch->deprecated_saved_pc_after_call (frame); +} + +void +set_gdbarch_deprecated_saved_pc_after_call (struct gdbarch *gdbarch, + gdbarch_deprecated_saved_pc_after_call_ftype deprecated_saved_pc_after_call) +{ + gdbarch->deprecated_saved_pc_after_call = deprecated_saved_pc_after_call; +} + +int +gdbarch_frame_num_args_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->frame_num_args != NULL; } int gdbarch_frame_num_args (struct gdbarch *gdbarch, struct frame_info *frame) { - if (gdbarch->frame_num_args == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_frame_num_args invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->frame_num_args != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_num_args called\n"); return gdbarch->frame_num_args (frame); @@ -4155,96 +4725,114 @@ set_gdbarch_frame_num_args (struct gdbarch *gdbarch, } int -gdbarch_stack_align_p (struct gdbarch *gdbarch) +gdbarch_deprecated_stack_align_p (struct gdbarch *gdbarch) { - return gdbarch->stack_align != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_stack_align != NULL; } CORE_ADDR -gdbarch_stack_align (struct gdbarch *gdbarch, CORE_ADDR sp) +gdbarch_deprecated_stack_align (struct gdbarch *gdbarch, CORE_ADDR sp) { - if (gdbarch->stack_align == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_stack_align invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_stack_align != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_stack_align called\n"); - return gdbarch->stack_align (sp); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_stack_align called\n"); + return gdbarch->deprecated_stack_align (sp); } void -set_gdbarch_stack_align (struct gdbarch *gdbarch, - gdbarch_stack_align_ftype stack_align) +set_gdbarch_deprecated_stack_align (struct gdbarch *gdbarch, + gdbarch_deprecated_stack_align_ftype deprecated_stack_align) { - gdbarch->stack_align = stack_align; + gdbarch->deprecated_stack_align = deprecated_stack_align; } int -gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch) +gdbarch_frame_align_p (struct gdbarch *gdbarch) { - /* Skip verify of extra_stack_alignment_needed, invalid_p == 0 */ + gdb_assert (gdbarch != NULL); + return gdbarch->frame_align != NULL; +} + +CORE_ADDR +gdbarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR address) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->frame_align != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_extra_stack_alignment_needed called\n"); - return gdbarch->extra_stack_alignment_needed; + fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_align called\n"); + return gdbarch->frame_align (gdbarch, address); } void -set_gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch, - int extra_stack_alignment_needed) +set_gdbarch_frame_align (struct gdbarch *gdbarch, + gdbarch_frame_align_ftype frame_align) { - gdbarch->extra_stack_alignment_needed = extra_stack_alignment_needed; + gdbarch->frame_align = frame_align; } int -gdbarch_reg_struct_has_addr_p (struct gdbarch *gdbarch) +gdbarch_deprecated_reg_struct_has_addr_p (struct gdbarch *gdbarch) { - return gdbarch->reg_struct_has_addr != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->deprecated_reg_struct_has_addr != NULL; } int -gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, int gcc_p, struct type *type) +gdbarch_deprecated_reg_struct_has_addr (struct gdbarch *gdbarch, int gcc_p, struct type *type) { - if (gdbarch->reg_struct_has_addr == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_reg_struct_has_addr invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->deprecated_reg_struct_has_addr != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_reg_struct_has_addr called\n"); - return gdbarch->reg_struct_has_addr (gcc_p, type); + fprintf_unfiltered (gdb_stdlog, "gdbarch_deprecated_reg_struct_has_addr called\n"); + return gdbarch->deprecated_reg_struct_has_addr (gcc_p, type); } void -set_gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, - gdbarch_reg_struct_has_addr_ftype reg_struct_has_addr) +set_gdbarch_deprecated_reg_struct_has_addr (struct gdbarch *gdbarch, + gdbarch_deprecated_reg_struct_has_addr_ftype deprecated_reg_struct_has_addr) { - gdbarch->reg_struct_has_addr = reg_struct_has_addr; + gdbarch->deprecated_reg_struct_has_addr = deprecated_reg_struct_has_addr; } int -gdbarch_save_dummy_frame_tos_p (struct gdbarch *gdbarch) +gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type) { - return gdbarch->save_dummy_frame_tos != 0; -} - -void -gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, CORE_ADDR sp) -{ - if (gdbarch->save_dummy_frame_tos == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_save_dummy_frame_tos invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->stabs_argument_has_addr != NULL); if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_save_dummy_frame_tos called\n"); - gdbarch->save_dummy_frame_tos (sp); + fprintf_unfiltered (gdb_stdlog, "gdbarch_stabs_argument_has_addr called\n"); + return gdbarch->stabs_argument_has_addr (gdbarch, type); } void -set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, - gdbarch_save_dummy_frame_tos_ftype save_dummy_frame_tos) +set_gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, + gdbarch_stabs_argument_has_addr_ftype stabs_argument_has_addr) { - gdbarch->save_dummy_frame_tos = save_dummy_frame_tos; + gdbarch->stabs_argument_has_addr = stabs_argument_has_addr; +} + +int +gdbarch_frame_red_zone_size (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_red_zone_size called\n"); + return gdbarch->frame_red_zone_size; +} + +void +set_gdbarch_frame_red_zone_size (struct gdbarch *gdbarch, + int frame_red_zone_size) +{ + gdbarch->frame_red_zone_size = frame_red_zone_size; } int gdbarch_parm_boundary (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_parm_boundary called\n"); return gdbarch->parm_boundary; @@ -4260,6 +4848,7 @@ set_gdbarch_parm_boundary (struct gdbarch *gdbarch, const struct floatformat * gdbarch_float_format (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_float_format called\n"); return gdbarch->float_format; @@ -4275,6 +4864,7 @@ set_gdbarch_float_format (struct gdbarch *gdbarch, const struct floatformat * gdbarch_double_format (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_double_format called\n"); return gdbarch->double_format; @@ -4290,6 +4880,7 @@ set_gdbarch_double_format (struct gdbarch *gdbarch, const struct floatformat * gdbarch_long_double_format (struct gdbarch *gdbarch) { + gdb_assert (gdbarch != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_long_double_format called\n"); return gdbarch->long_double_format; @@ -4303,14 +4894,13 @@ set_gdbarch_long_double_format (struct gdbarch *gdbarch, } CORE_ADDR -gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr) +gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ) { - if (gdbarch->convert_from_func_ptr_addr == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_convert_from_func_ptr_addr invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->convert_from_func_ptr_addr != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_from_func_ptr_addr called\n"); - return gdbarch->convert_from_func_ptr_addr (addr); + return gdbarch->convert_from_func_ptr_addr (gdbarch, addr, targ); } void @@ -4323,9 +4913,8 @@ set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr) { - if (gdbarch->addr_bits_remove == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_addr_bits_remove invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->addr_bits_remove != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_addr_bits_remove called\n"); return gdbarch->addr_bits_remove (addr); @@ -4341,9 +4930,8 @@ set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr) { - if (gdbarch->smash_text_address == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_smash_text_address invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->smash_text_address != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_smash_text_address called\n"); return gdbarch->smash_text_address (addr); @@ -4359,15 +4947,15 @@ set_gdbarch_smash_text_address (struct gdbarch *gdbarch, int gdbarch_software_single_step_p (struct gdbarch *gdbarch) { - return gdbarch->software_single_step != 0; + gdb_assert (gdbarch != NULL); + return gdbarch->software_single_step != NULL; } void gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p) { - if (gdbarch->software_single_step == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_software_single_step invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->software_single_step != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n"); gdbarch->software_single_step (sig, insert_breakpoints_p); @@ -4381,11 +4969,10 @@ set_gdbarch_software_single_step (struct gdbarch *gdbarch, } int -gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, disassemble_info *info) +gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, struct disassemble_info *info) { - if (gdbarch->print_insn == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_print_insn invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->print_insn != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_print_insn called\n"); return gdbarch->print_insn (vma, info); @@ -4401,9 +4988,8 @@ set_gdbarch_print_insn (struct gdbarch *gdbarch, CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, CORE_ADDR pc) { - if (gdbarch->skip_trampoline_code == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_skip_trampoline_code invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->skip_trampoline_code != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_trampoline_code called\n"); return gdbarch->skip_trampoline_code (pc); @@ -4416,12 +5002,28 @@ set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch->skip_trampoline_code = skip_trampoline_code; } +CORE_ADDR +gdbarch_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->skip_solib_resolver != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_solib_resolver called\n"); + return gdbarch->skip_solib_resolver (gdbarch, pc); +} + +void +set_gdbarch_skip_solib_resolver (struct gdbarch *gdbarch, + gdbarch_skip_solib_resolver_ftype skip_solib_resolver) +{ + gdbarch->skip_solib_resolver = skip_solib_resolver; +} + int gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc, char *name) { - if (gdbarch->in_solib_call_trampoline == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_in_solib_call_trampoline invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->in_solib_call_trampoline != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_in_solib_call_trampoline called\n"); return gdbarch->in_solib_call_trampoline (pc, name); @@ -4434,12 +5036,93 @@ set_gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, gdbarch->in_solib_call_trampoline = in_solib_call_trampoline; } +int +gdbarch_in_solib_return_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc, char *name) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->in_solib_return_trampoline != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_in_solib_return_trampoline called\n"); + return gdbarch->in_solib_return_trampoline (pc, name); +} + +void +set_gdbarch_in_solib_return_trampoline (struct gdbarch *gdbarch, + gdbarch_in_solib_return_trampoline_ftype in_solib_return_trampoline) +{ + gdbarch->in_solib_return_trampoline = in_solib_return_trampoline; +} + +int +gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc, char *name) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->pc_in_sigtramp != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_in_sigtramp called\n"); + return gdbarch->pc_in_sigtramp (pc, name); +} + +void +set_gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, + gdbarch_pc_in_sigtramp_ftype pc_in_sigtramp) +{ + gdbarch->pc_in_sigtramp = pc_in_sigtramp; +} + +int +gdbarch_sigtramp_start_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->sigtramp_start != NULL; +} + +CORE_ADDR +gdbarch_sigtramp_start (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->sigtramp_start != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_sigtramp_start called\n"); + return gdbarch->sigtramp_start (pc); +} + +void +set_gdbarch_sigtramp_start (struct gdbarch *gdbarch, + gdbarch_sigtramp_start_ftype sigtramp_start) +{ + gdbarch->sigtramp_start = sigtramp_start; +} + +int +gdbarch_sigtramp_end_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->sigtramp_end != NULL; +} + +CORE_ADDR +gdbarch_sigtramp_end (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->sigtramp_end != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_sigtramp_end called\n"); + return gdbarch->sigtramp_end (pc); +} + +void +set_gdbarch_sigtramp_end (struct gdbarch *gdbarch, + gdbarch_sigtramp_end_ftype sigtramp_end) +{ + gdbarch->sigtramp_end = sigtramp_end; +} + int gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR addr) { - if (gdbarch->in_function_epilogue_p == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_in_function_epilogue_p invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->in_function_epilogue_p != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_in_function_epilogue_p called\n"); return gdbarch->in_function_epilogue_p (gdbarch, addr); @@ -4455,9 +5138,8 @@ set_gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, char * gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv) { - if (gdbarch->construct_inferior_arguments == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_construct_inferior_arguments invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->construct_inferior_arguments != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_construct_inferior_arguments called\n"); return gdbarch->construct_inferior_arguments (gdbarch, argc, argv); @@ -4470,36 +5152,11 @@ set_gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, gdbarch->construct_inferior_arguments = construct_inferior_arguments; } -int -gdbarch_dwarf2_build_frame_info_p (struct gdbarch *gdbarch) -{ - return gdbarch->dwarf2_build_frame_info != 0; -} - -void -gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch, struct objfile *objfile) -{ - if (gdbarch->dwarf2_build_frame_info == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_dwarf2_build_frame_info invalid"); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf2_build_frame_info called\n"); - gdbarch->dwarf2_build_frame_info (objfile); -} - -void -set_gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch, - gdbarch_dwarf2_build_frame_info_ftype dwarf2_build_frame_info) -{ - gdbarch->dwarf2_build_frame_info = dwarf2_build_frame_info; -} - void gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch, asymbol *sym, struct minimal_symbol *msym) { - if (gdbarch->elf_make_msymbol_special == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_elf_make_msymbol_special invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->elf_make_msymbol_special != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_elf_make_msymbol_special called\n"); gdbarch->elf_make_msymbol_special (sym, msym); @@ -4515,9 +5172,8 @@ set_gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch, void gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, int val, struct minimal_symbol *msym) { - if (gdbarch->coff_make_msymbol_special == 0) - internal_error (__FILE__, __LINE__, - "gdbarch: gdbarch_coff_make_msymbol_special invalid"); + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->coff_make_msymbol_special != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_coff_make_msymbol_special called\n"); gdbarch->coff_make_msymbol_special (val, msym); @@ -4530,6 +5186,194 @@ set_gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, gdbarch->coff_make_msymbol_special = coff_make_msymbol_special; } +const char * +gdbarch_name_of_malloc (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of name_of_malloc, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_name_of_malloc called\n"); + return gdbarch->name_of_malloc; +} + +void +set_gdbarch_name_of_malloc (struct gdbarch *gdbarch, + const char * name_of_malloc) +{ + gdbarch->name_of_malloc = name_of_malloc; +} + +int +gdbarch_cannot_step_breakpoint (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of cannot_step_breakpoint, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_cannot_step_breakpoint called\n"); + return gdbarch->cannot_step_breakpoint; +} + +void +set_gdbarch_cannot_step_breakpoint (struct gdbarch *gdbarch, + int cannot_step_breakpoint) +{ + gdbarch->cannot_step_breakpoint = cannot_step_breakpoint; +} + +int +gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_have_nonsteppable_watchpoint called\n"); + return gdbarch->have_nonsteppable_watchpoint; +} + +void +set_gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch, + int have_nonsteppable_watchpoint) +{ + gdbarch->have_nonsteppable_watchpoint = have_nonsteppable_watchpoint; +} + +int +gdbarch_address_class_type_flags_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->address_class_type_flags != NULL; +} + +int +gdbarch_address_class_type_flags (struct gdbarch *gdbarch, int byte_size, int dwarf2_addr_class) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->address_class_type_flags != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_address_class_type_flags called\n"); + return gdbarch->address_class_type_flags (byte_size, dwarf2_addr_class); +} + +void +set_gdbarch_address_class_type_flags (struct gdbarch *gdbarch, + gdbarch_address_class_type_flags_ftype address_class_type_flags) +{ + gdbarch->address_class_type_flags = address_class_type_flags; +} + +int +gdbarch_address_class_type_flags_to_name_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->address_class_type_flags_to_name != NULL; +} + +const char * +gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->address_class_type_flags_to_name != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_address_class_type_flags_to_name called\n"); + return gdbarch->address_class_type_flags_to_name (gdbarch, type_flags); +} + +void +set_gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, + gdbarch_address_class_type_flags_to_name_ftype address_class_type_flags_to_name) +{ + gdbarch->address_class_type_flags_to_name = address_class_type_flags_to_name; +} + +int +gdbarch_address_class_name_to_type_flags_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->address_class_name_to_type_flags != NULL; +} + +int +gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, const char *name, int *type_flags_ptr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->address_class_name_to_type_flags != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_address_class_name_to_type_flags called\n"); + return gdbarch->address_class_name_to_type_flags (gdbarch, name, type_flags_ptr); +} + +void +set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, + gdbarch_address_class_name_to_type_flags_ftype address_class_name_to_type_flags) +{ + gdbarch->address_class_name_to_type_flags = address_class_name_to_type_flags; +} + +int +gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->register_reggroup_p != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_register_reggroup_p called\n"); + return gdbarch->register_reggroup_p (gdbarch, regnum, reggroup); +} + +void +set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch, + gdbarch_register_reggroup_p_ftype register_reggroup_p) +{ + gdbarch->register_reggroup_p = register_reggroup_p; +} + +int +gdbarch_fetch_pointer_argument_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->fetch_pointer_argument != NULL; +} + +CORE_ADDR +gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, struct frame_info *frame, int argi, struct type *type) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->fetch_pointer_argument != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_fetch_pointer_argument called\n"); + return gdbarch->fetch_pointer_argument (frame, argi, type); +} + +void +set_gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, + gdbarch_fetch_pointer_argument_ftype fetch_pointer_argument) +{ + gdbarch->fetch_pointer_argument = fetch_pointer_argument; +} + +int +gdbarch_regset_from_core_section_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->regset_from_core_section != NULL; +} + +const struct regset * +gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->regset_from_core_section != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_regset_from_core_section called\n"); + return gdbarch->regset_from_core_section (gdbarch, sect_name, sect_size); +} + +void +set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, + gdbarch_regset_from_core_section_ftype regset_from_core_section) +{ + gdbarch->regset_from_core_section = regset_from_core_section; +} + /* Keep a registry of per-architecture data-pointers required by GDB modules. */ @@ -4537,8 +5381,8 @@ set_gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, struct gdbarch_data { unsigned index; + int init_p; gdbarch_data_init_ftype *init; - gdbarch_data_free_ftype *free; }; struct gdbarch_data_registration @@ -4559,10 +5403,10 @@ struct gdbarch_data_registry gdbarch_data_registry = }; struct gdbarch_data * -register_gdbarch_data (gdbarch_data_init_ftype *init, - gdbarch_data_free_ftype *free) +register_gdbarch_data (gdbarch_data_init_ftype *init) { struct gdbarch_data_registration **curr; + /* Append the new registraration. */ for (curr = &gdbarch_data_registry.registrations; (*curr) != NULL; curr = &(*curr)->next); @@ -4571,31 +5415,11 @@ register_gdbarch_data (gdbarch_data_init_ftype *init, (*curr)->data = XMALLOC (struct gdbarch_data); (*curr)->data->index = gdbarch_data_registry.nr++; (*curr)->data->init = init; - (*curr)->data->free = free; + (*curr)->data->init_p = 1; return (*curr)->data; } -/* Walk through all the registered users initializing each in turn. */ - -static void -init_gdbarch_data (struct gdbarch *gdbarch) -{ - struct gdbarch_data_registration *rego; - for (rego = gdbarch_data_registry.registrations; - rego != NULL; - rego = rego->next) - { - struct gdbarch_data *data = rego->data; - gdb_assert (data->index < gdbarch->nr_data); - if (data->init != NULL) - { - void *pointer = data->init (gdbarch); - set_gdbarch_data (gdbarch, data, pointer); - } - } -} - /* Create/delete the gdbarch data vector. */ static void @@ -4603,32 +5427,10 @@ alloc_gdbarch_data (struct gdbarch *gdbarch) { gdb_assert (gdbarch->data == NULL); gdbarch->nr_data = gdbarch_data_registry.nr; - gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*)); + gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *); } -static void -free_gdbarch_data (struct gdbarch *gdbarch) -{ - struct gdbarch_data_registration *rego; - gdb_assert (gdbarch->data != NULL); - for (rego = gdbarch_data_registry.registrations; - rego != NULL; - rego = rego->next) - { - struct gdbarch_data *data = rego->data; - gdb_assert (data->index < gdbarch->nr_data); - if (data->free != NULL && gdbarch->data[data->index] != NULL) - { - data->free (gdbarch, gdbarch->data[data->index]); - gdbarch->data[data->index] = NULL; - } - } - xfree (gdbarch->data); - gdbarch->data = NULL; -} - - -/* Initialize the current value of thee specified per-architecture +/* Initialize the current value of the specified per-architecture data-pointer. */ void @@ -4637,8 +5439,7 @@ set_gdbarch_data (struct gdbarch *gdbarch, void *pointer) { gdb_assert (data->index < gdbarch->nr_data); - if (data->free != NULL && gdbarch->data[data->index] != NULL) - data->free (gdbarch, gdbarch->data[data->index]); + gdb_assert (gdbarch->data[data->index] == NULL); gdbarch->data[data->index] = pointer; } @@ -4646,10 +5447,24 @@ set_gdbarch_data (struct gdbarch *gdbarch, data-pointer. */ void * -gdbarch_data (struct gdbarch_data *data) +gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data) { - gdb_assert (data->index < current_gdbarch->nr_data); - return current_gdbarch->data[data->index]; + gdb_assert (data->index < gdbarch->nr_data); + /* The data-pointer isn't initialized, call init() to get a value but + only if the architecture initializaiton has completed. Otherwise + punt - hope that the caller knows what they are doing. */ + if (gdbarch->data[data->index] == NULL + && gdbarch->initialized_p) + { + /* Be careful to detect an initialization cycle. */ + gdb_assert (data->init_p); + data->init_p = 0; + gdb_assert (data->init != NULL); + gdbarch->data[data->index] = data->init (gdbarch); + data->init_p = 1; + gdb_assert (gdbarch->data[data->index] != NULL); + } + return gdbarch->data[data->index]; } @@ -4683,9 +5498,9 @@ struct gdbarch_swap_registry gdbarch_swap_registry = }; void -register_gdbarch_swap (void *data, - unsigned long sizeof_data, - gdbarch_swap_ftype *init) +deprecated_register_gdbarch_swap (void *data, + unsigned long sizeof_data, + gdbarch_swap_ftype *init) { struct gdbarch_swap_registration **rego; for (rego = &gdbarch_swap_registry.registrations; @@ -4698,23 +5513,23 @@ register_gdbarch_swap (void *data, (*rego)->sizeof_data = sizeof_data; } - static void -init_gdbarch_swap (struct gdbarch *gdbarch) +current_gdbarch_swap_init_hack (void) { struct gdbarch_swap_registration *rego; - struct gdbarch_swap **curr = &gdbarch->swap; + struct gdbarch_swap **curr = ¤t_gdbarch->swap; for (rego = gdbarch_swap_registry.registrations; rego != NULL; rego = rego->next) { if (rego->data != NULL) { - (*curr) = XMALLOC (struct gdbarch_swap); + (*curr) = GDBARCH_OBSTACK_ZALLOC (current_gdbarch, + struct gdbarch_swap); (*curr)->source = rego; - (*curr)->swap = xmalloc (rego->sizeof_data); + (*curr)->swap = gdbarch_obstack_zalloc (current_gdbarch, + rego->sizeof_data); (*curr)->next = NULL; - memset (rego->data, 0, rego->sizeof_data); curr = &(*curr)->next; } if (rego->init != NULL) @@ -4722,24 +5537,35 @@ init_gdbarch_swap (struct gdbarch *gdbarch) } } -static void -swapout_gdbarch_swap (struct gdbarch *gdbarch) +static struct gdbarch * +current_gdbarch_swap_out_hack (void) { + struct gdbarch *old_gdbarch = current_gdbarch; struct gdbarch_swap *curr; - for (curr = gdbarch->swap; + + gdb_assert (old_gdbarch != NULL); + for (curr = old_gdbarch->swap; curr != NULL; curr = curr->next) - memcpy (curr->swap, curr->source->data, curr->source->sizeof_data); + { + memcpy (curr->swap, curr->source->data, curr->source->sizeof_data); + memset (curr->source->data, 0, curr->source->sizeof_data); + } + current_gdbarch = NULL; + return old_gdbarch; } static void -swapin_gdbarch_swap (struct gdbarch *gdbarch) +current_gdbarch_swap_in_hack (struct gdbarch *new_gdbarch) { struct gdbarch_swap *curr; - for (curr = gdbarch->swap; + + gdb_assert (current_gdbarch == NULL); + for (curr = new_gdbarch->swap; curr != NULL; curr = curr->next) memcpy (curr->source->data, curr->swap, curr->source->sizeof_data); + current_gdbarch = new_gdbarch; } @@ -4767,37 +5593,30 @@ append_name (const char ***buf, int *nr, const char *name) const char ** gdbarch_printable_names (void) { - if (GDB_MULTI_ARCH) + /* Accumulate a list of names based on the registed list of + architectures. */ + enum bfd_architecture a; + int nr_arches = 0; + const char **arches = NULL; + struct gdbarch_registration *rego; + for (rego = gdbarch_registry; + rego != NULL; + rego = rego->next) { - /* Accumulate a list of names based on the registed list of - architectures. */ - enum bfd_architecture a; - int nr_arches = 0; - const char **arches = NULL; - struct gdbarch_registration *rego; - for (rego = gdbarch_registry; - rego != NULL; - rego = rego->next) - { - const struct bfd_arch_info *ap; - ap = bfd_lookup_arch (rego->bfd_architecture, 0); - if (ap == NULL) - internal_error (__FILE__, __LINE__, - "gdbarch_architecture_names: multi-arch unknown"); - do - { - append_name (&arches, &nr_arches, ap->printable_name); - ap = ap->next; - } - while (ap != NULL); - } - append_name (&arches, &nr_arches, NULL); - return arches; + const struct bfd_arch_info *ap; + ap = bfd_lookup_arch (rego->bfd_architecture, 0); + if (ap == NULL) + internal_error (__FILE__, __LINE__, + "gdbarch_architecture_names: multi-arch unknown"); + do + { + append_name (&arches, &nr_arches, ap->printable_name); + ap = ap->next; + } + while (ap != NULL); } - else - /* Just return all the architectures that BFD knows. Assume that - the legacy architecture framework supports them. */ - return bfd_arch_list (); + append_name (&arches, &nr_arches, NULL); + return arches; } @@ -4838,12 +5657,6 @@ gdbarch_register (enum bfd_architecture bfd_architecture, (*curr)->dump_tdep = dump_tdep; (*curr)->arches = NULL; (*curr)->next = NULL; - /* When non- multi-arch, install whatever target dump routine we've - been provided - hopefully that routine has been written correctly - and works regardless of multi-arch. */ - if (!GDB_MULTI_ARCH && dump_tdep != NULL - && startup_gdbarch.dump_tdep == NULL) - startup_gdbarch.dump_tdep = dump_tdep; } void @@ -4867,50 +5680,32 @@ gdbarch_list_lookup_by_info (struct gdbarch_list *arches, continue; if (info->byte_order != arches->gdbarch->byte_order) continue; + if (info->osabi != arches->gdbarch->osabi) + continue; return arches; } return NULL; } -/* Update the current architecture. Return ZERO if the update request - failed. */ +/* Find an architecture that matches the specified INFO. Create a new + architecture if needed. Return that new architecture. Assumes + that there is no current architecture. */ -int -gdbarch_update_p (struct gdbarch_info info) +static struct gdbarch * +find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info) { struct gdbarch *new_gdbarch; - struct gdbarch_list **list; struct gdbarch_registration *rego; + /* The existing architecture has been swapped out - all this code + works from a clean slate. */ + gdb_assert (current_gdbarch == NULL); + /* Fill in missing parts of the INFO struct using a number of - sources: ``set ...''; INFOabfd supplied; existing target. */ - - /* ``(gdb) set architecture ...'' */ - if (info.bfd_arch_info == NULL - && !TARGET_ARCHITECTURE_AUTO) - info.bfd_arch_info = TARGET_ARCHITECTURE; - if (info.bfd_arch_info == NULL - && info.abfd != NULL - && bfd_get_arch (info.abfd) != bfd_arch_unknown - && bfd_get_arch (info.abfd) != bfd_arch_obscure) - info.bfd_arch_info = bfd_get_arch_info (info.abfd); - if (info.bfd_arch_info == NULL) - info.bfd_arch_info = TARGET_ARCHITECTURE; - - /* ``(gdb) set byte-order ...'' */ - if (info.byte_order == BFD_ENDIAN_UNKNOWN - && !TARGET_BYTE_ORDER_AUTO) - info.byte_order = TARGET_BYTE_ORDER; - /* From the INFO struct. */ - if (info.byte_order == BFD_ENDIAN_UNKNOWN - && info.abfd != NULL) - info.byte_order = (bfd_big_endian (info.abfd) ? BFD_ENDIAN_BIG - : bfd_little_endian (info.abfd) ? BFD_ENDIAN_LITTLE - : BFD_ENDIAN_UNKNOWN); - /* From the current target. */ - if (info.byte_order == BFD_ENDIAN_UNKNOWN) - info.byte_order = TARGET_BYTE_ORDER; + sources: "set ..."; INFOabfd supplied; and the existing + architecture. */ + gdbarch_info_fill (old_gdbarch, &info); /* Must have found some sort of architecture. */ gdb_assert (info.bfd_arch_info != NULL); @@ -4918,25 +5713,28 @@ gdbarch_update_p (struct gdbarch_info info) if (gdbarch_debug) { fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.bfd_arch_info %s\n", + "find_arch_by_info: info.bfd_arch_info %s\n", (info.bfd_arch_info != NULL ? info.bfd_arch_info->printable_name : "(null)")); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.byte_order %d (%s)\n", + "find_arch_by_info: info.byte_order %d (%s)\n", info.byte_order, (info.byte_order == BFD_ENDIAN_BIG ? "big" : info.byte_order == BFD_ENDIAN_LITTLE ? "little" : "default")); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.abfd 0x%lx\n", + "find_arch_by_info: info.osabi %d (%s)\n", + info.osabi, gdbarch_osabi_name (info.osabi)); + fprintf_unfiltered (gdb_stdlog, + "find_arch_by_info: info.abfd 0x%lx\n", (long) info.abfd); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.tdep_info 0x%lx\n", + "find_arch_by_info: info.tdep_info 0x%lx\n", (long) info.tdep_info); } - /* Find the target that knows about this architecture. */ + /* Find the tdep code that knows about this architecture. */ for (rego = gdbarch_registry; rego != NULL; rego = rego->next) @@ -4945,97 +5743,121 @@ gdbarch_update_p (struct gdbarch_info info) if (rego == NULL) { if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: No matching architecture\n"); + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "No matching architecture\n"); return 0; } - /* Ask the target for a replacement architecture. */ + /* Ask the tdep code for an architecture that matches "info". */ new_gdbarch = rego->init (info, rego->arches); - /* Did the target like it? No. Reject the change. */ + /* Did the tdep code like it? No. Reject the change and revert to + the old architecture. */ if (new_gdbarch == NULL) { if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Target rejected architecture\n"); - return 0; + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "Target rejected architecture\n"); + return NULL; } - /* Did the architecture change? No. Do nothing. */ - if (current_gdbarch == new_gdbarch) + /* Is this a pre-existing architecture (as determined by already + being initialized)? Move it to the front of the architecture + list (keeping the list sorted Most Recently Used). */ + if (new_gdbarch->initialized_p) { + struct gdbarch_list **list; + struct gdbarch_list *this; if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\n", + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "Previous architecture 0x%08lx (%s) selected\n", (long) new_gdbarch, new_gdbarch->bfd_arch_info->printable_name); - return 1; + /* Find the existing arch in the list. */ + for (list = ®o->arches; + (*list) != NULL && (*list)->gdbarch != new_gdbarch; + list = &(*list)->next); + /* It had better be in the list of architectures. */ + gdb_assert ((*list) != NULL && (*list)->gdbarch == new_gdbarch); + /* Unlink THIS. */ + this = (*list); + (*list) = this->next; + /* Insert THIS at the front. */ + this->next = rego->arches; + rego->arches = this; + /* Return it. */ + return new_gdbarch; } - /* Swap all data belonging to the old target out */ - swapout_gdbarch_swap (current_gdbarch); - - /* Is this a pre-existing architecture? Yes. Swap it in. */ - for (list = ®o->arches; - (*list) != NULL; - list = &(*list)->next) - { - if ((*list)->gdbarch == new_gdbarch) - { - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: Previous architecture 0x%08lx (%s) selected\n", - (long) new_gdbarch, - new_gdbarch->bfd_arch_info->printable_name); - current_gdbarch = new_gdbarch; - swapin_gdbarch_swap (new_gdbarch); - architecture_changed_event (); - return 1; - } - } - - /* Append this new architecture to this targets list. */ - (*list) = XMALLOC (struct gdbarch_list); - (*list)->next = NULL; - (*list)->gdbarch = new_gdbarch; - - /* Switch to this new architecture. Dump it out. */ - current_gdbarch = new_gdbarch; + /* It's a new architecture. */ if (gdbarch_debug) - { - fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: New architecture 0x%08lx (%s) selected\n", - (long) new_gdbarch, - new_gdbarch->bfd_arch_info->printable_name); - } + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "New architecture 0x%08lx (%s) selected\n", + (long) new_gdbarch, + new_gdbarch->bfd_arch_info->printable_name); + /* Insert the new architecture into the front of the architecture + list (keep the list sorted Most Recently Used). */ + { + struct gdbarch_list *this = XMALLOC (struct gdbarch_list); + this->next = rego->arches; + this->gdbarch = new_gdbarch; + rego->arches = this; + } + /* Check that the newly installed architecture is valid. Plug in any post init values. */ new_gdbarch->dump_tdep = rego->dump_tdep; verify_gdbarch (new_gdbarch); + new_gdbarch->initialized_p = 1; - /* Initialize the per-architecture memory (swap) areas. - CURRENT_GDBARCH must be update before these modules are - called. */ - init_gdbarch_swap (new_gdbarch); - - /* Initialize the per-architecture data-pointer of all parties that - registered an interest in this architecture. CURRENT_GDBARCH - must be updated before these modules are called. */ - init_gdbarch_data (new_gdbarch); - architecture_changed_event (); + /* Initialize any per-architecture swap areas. This phase requires + a valid global CURRENT_GDBARCH. Set it momentarially, and then + swap the entire architecture out. */ + current_gdbarch = new_gdbarch; + current_gdbarch_swap_init_hack (); + current_gdbarch_swap_out_hack (); if (gdbarch_debug) - gdbarch_dump (current_gdbarch, gdb_stdlog); + gdbarch_dump (new_gdbarch, gdb_stdlog); - return 1; + return new_gdbarch; } +struct gdbarch * +gdbarch_find_by_info (struct gdbarch_info info) +{ + /* Save the previously selected architecture, setting the global to + NULL. This stops things like gdbarch->init() trying to use the + previous architecture's configuration. The previous architecture + may not even be of the same architecture family. The most recent + architecture of the same family is found at the head of the + rego->arches list. */ + struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack (); -/* Disassembler */ + /* Find the specified architecture. */ + struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info); -/* Pointer to the target-dependent disassembly function. */ -int (*tm_print_insn) (bfd_vma, disassemble_info *); -disassemble_info tm_print_insn_info; + /* Restore the existing architecture. */ + gdb_assert (current_gdbarch == NULL); + current_gdbarch_swap_in_hack (old_gdbarch); + return new_gdbarch; +} + +/* Make the specified architecture current, swapping the existing one + out. */ + +void +deprecated_current_gdbarch_select_hack (struct gdbarch *new_gdbarch) +{ + gdb_assert (new_gdbarch != NULL); + gdb_assert (current_gdbarch != NULL); + gdb_assert (new_gdbarch->initialized_p); + current_gdbarch_swap_out_hack (); + current_gdbarch_swap_in_hack (new_gdbarch); + architecture_changed_event (); +} extern void _initialize_gdbarch (void); @@ -5044,12 +5866,6 @@ _initialize_gdbarch (void) { struct cmd_list_element *c; - INIT_DISASSEMBLE_INFO_NO_ARCH (tm_print_insn_info, gdb_stdout, (fprintf_ftype)fprintf_filtered); - tm_print_insn_info.flavour = bfd_target_unknown_flavour; - tm_print_insn_info.read_memory_func = dis_asm_read_memory; - tm_print_insn_info.memory_error_func = dis_asm_memory_error; - tm_print_insn_info.print_address_func = dis_asm_print_address; - add_show_from_set (add_set_cmd ("arch", class_maintenance, var_zinteger, diff --git a/contrib/gdb/gdb/gdbarch.h b/contrib/gdb/gdb/gdbarch.h index 81f5174aa8b..3f01249ad3d 100644 --- a/contrib/gdb/gdb/gdbarch.h +++ b/contrib/gdb/gdb/gdbarch.h @@ -1,7 +1,9 @@ /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. - Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -35,15 +37,17 @@ #ifndef GDBARCH_H #define GDBARCH_H -#include "dis-asm.h" /* Get defs for disassemble_info, which unfortunately is a typedef. */ -#if !GDB_MULTI_ARCH -#include "value.h" /* For default_coerce_float_to_double which is referenced by a macro. */ -#endif - +struct floatformat; +struct ui_file; struct frame_info; struct value; struct objfile; struct minimal_symbol; +struct regcache; +struct reggroup; +struct regset; +struct disassemble_info; +struct target_ops; extern struct gdbarch *current_gdbarch; @@ -51,18 +55,6 @@ extern struct gdbarch *current_gdbarch; /* If any of the following are defined, the target wasn't correctly converted. */ -#if GDB_MULTI_ARCH -#if defined (EXTRA_FRAME_INFO) -#error "EXTRA_FRAME_INFO: replaced by struct frame_extra_info" -#endif -#endif - -#if GDB_MULTI_ARCH -#if defined (FRAME_FIND_SAVED_REGS) -#error "FRAME_FIND_SAVED_REGS: replaced by FRAME_INIT_SAVED_REGS" -#endif -#endif - #if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PURE) && defined (GDB_TM_FILE) #error "GDB_TM_FILE: Pure multi-arch targets do not have a tm.h file." #endif @@ -75,21 +67,26 @@ extern const struct bfd_arch_info * gdbarch_bfd_arch_info (struct gdbarch *gdbar #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_ARCHITECTURE) #error "Non multi-arch definition of TARGET_ARCHITECTURE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_ARCHITECTURE) +#if !defined (TARGET_ARCHITECTURE) #define TARGET_ARCHITECTURE (gdbarch_bfd_arch_info (current_gdbarch)) #endif -#endif extern int gdbarch_byte_order (struct gdbarch *gdbarch); /* set_gdbarch_byte_order() - not applicable - pre-initialized. */ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_BYTE_ORDER) #error "Non multi-arch definition of TARGET_BYTE_ORDER" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_BYTE_ORDER) +#if !defined (TARGET_BYTE_ORDER) #define TARGET_BYTE_ORDER (gdbarch_byte_order (current_gdbarch)) #endif + +extern enum gdb_osabi gdbarch_osabi (struct gdbarch *gdbarch); +/* set_gdbarch_osabi() - not applicable - pre-initialized. */ +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_OSABI) +#error "Non multi-arch definition of TARGET_OSABI" +#endif +#if !defined (TARGET_OSABI) +#define TARGET_OSABI (gdbarch_osabi (current_gdbarch)) #endif @@ -97,134 +94,85 @@ extern int gdbarch_byte_order (struct gdbarch *gdbarch); /* Number of bits in a char or unsigned char for the target machine. Just like CHAR_BIT in but describes the target machine. - v::TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0: + v:2:TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0: Number of bits in a short or unsigned short for the target machine. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_SHORT_BIT) -#define TARGET_SHORT_BIT (2*TARGET_CHAR_BIT) -#endif - extern int gdbarch_short_bit (struct gdbarch *gdbarch); extern void set_gdbarch_short_bit (struct gdbarch *gdbarch, int short_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_SHORT_BIT) #error "Non multi-arch definition of TARGET_SHORT_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_SHORT_BIT) +#if !defined (TARGET_SHORT_BIT) #define TARGET_SHORT_BIT (gdbarch_short_bit (current_gdbarch)) #endif -#endif /* Number of bits in an int or unsigned int for the target machine. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_INT_BIT) -#define TARGET_INT_BIT (4*TARGET_CHAR_BIT) -#endif - extern int gdbarch_int_bit (struct gdbarch *gdbarch); extern void set_gdbarch_int_bit (struct gdbarch *gdbarch, int int_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_INT_BIT) #error "Non multi-arch definition of TARGET_INT_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_INT_BIT) +#if !defined (TARGET_INT_BIT) #define TARGET_INT_BIT (gdbarch_int_bit (current_gdbarch)) #endif -#endif /* Number of bits in a long or unsigned long for the target machine. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_BIT) -#define TARGET_LONG_BIT (4*TARGET_CHAR_BIT) -#endif - extern int gdbarch_long_bit (struct gdbarch *gdbarch); extern void set_gdbarch_long_bit (struct gdbarch *gdbarch, int long_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_BIT) #error "Non multi-arch definition of TARGET_LONG_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_BIT) +#if !defined (TARGET_LONG_BIT) #define TARGET_LONG_BIT (gdbarch_long_bit (current_gdbarch)) #endif -#endif /* Number of bits in a long long or unsigned long long for the target machine. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_LONG_BIT) -#define TARGET_LONG_LONG_BIT (2*TARGET_LONG_BIT) -#endif - extern int gdbarch_long_long_bit (struct gdbarch *gdbarch); extern void set_gdbarch_long_long_bit (struct gdbarch *gdbarch, int long_long_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_LONG_BIT) #error "Non multi-arch definition of TARGET_LONG_LONG_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_LONG_BIT) +#if !defined (TARGET_LONG_LONG_BIT) #define TARGET_LONG_LONG_BIT (gdbarch_long_long_bit (current_gdbarch)) #endif -#endif /* Number of bits in a float for the target machine. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_FLOAT_BIT) -#define TARGET_FLOAT_BIT (4*TARGET_CHAR_BIT) -#endif - extern int gdbarch_float_bit (struct gdbarch *gdbarch); extern void set_gdbarch_float_bit (struct gdbarch *gdbarch, int float_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_FLOAT_BIT) #error "Non multi-arch definition of TARGET_FLOAT_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_FLOAT_BIT) +#if !defined (TARGET_FLOAT_BIT) #define TARGET_FLOAT_BIT (gdbarch_float_bit (current_gdbarch)) #endif -#endif /* Number of bits in a double for the target machine. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_DOUBLE_BIT) -#define TARGET_DOUBLE_BIT (8*TARGET_CHAR_BIT) -#endif - extern int gdbarch_double_bit (struct gdbarch *gdbarch); extern void set_gdbarch_double_bit (struct gdbarch *gdbarch, int double_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_DOUBLE_BIT) #error "Non multi-arch definition of TARGET_DOUBLE_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_DOUBLE_BIT) +#if !defined (TARGET_DOUBLE_BIT) #define TARGET_DOUBLE_BIT (gdbarch_double_bit (current_gdbarch)) #endif -#endif /* Number of bits in a long double for the target machine. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_DOUBLE_BIT) -#define TARGET_LONG_DOUBLE_BIT (8*TARGET_CHAR_BIT) -#endif - extern int gdbarch_long_double_bit (struct gdbarch *gdbarch); extern void set_gdbarch_long_double_bit (struct gdbarch *gdbarch, int long_double_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_DOUBLE_BIT) #error "Non multi-arch definition of TARGET_LONG_DOUBLE_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_DOUBLE_BIT) +#if !defined (TARGET_LONG_DOUBLE_BIT) #define TARGET_LONG_DOUBLE_BIT (gdbarch_long_double_bit (current_gdbarch)) #endif -#endif /* For most targets, a pointer on the target and its representation as an address in GDB have the same size and "look the same". For such a @@ -236,79 +184,61 @@ extern void set_gdbarch_long_double_bit (struct gdbarch *gdbarch, int long_doubl ptr_bit is the size of a pointer on the target */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_PTR_BIT) -#define TARGET_PTR_BIT (TARGET_INT_BIT) -#endif - extern int gdbarch_ptr_bit (struct gdbarch *gdbarch); extern void set_gdbarch_ptr_bit (struct gdbarch *gdbarch, int ptr_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_PTR_BIT) #error "Non multi-arch definition of TARGET_PTR_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_PTR_BIT) +#if !defined (TARGET_PTR_BIT) #define TARGET_PTR_BIT (gdbarch_ptr_bit (current_gdbarch)) #endif -#endif /* addr_bit is the size of a target address as represented in gdb */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_ADDR_BIT) -#define TARGET_ADDR_BIT (TARGET_PTR_BIT) -#endif - extern int gdbarch_addr_bit (struct gdbarch *gdbarch); extern void set_gdbarch_addr_bit (struct gdbarch *gdbarch, int addr_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_ADDR_BIT) #error "Non multi-arch definition of TARGET_ADDR_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_ADDR_BIT) +#if !defined (TARGET_ADDR_BIT) #define TARGET_ADDR_BIT (gdbarch_addr_bit (current_gdbarch)) #endif -#endif /* Number of bits in a BFD_VMA for the target object file format. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_BFD_VMA_BIT) -#define TARGET_BFD_VMA_BIT (TARGET_ARCHITECTURE->bits_per_address) -#endif - extern int gdbarch_bfd_vma_bit (struct gdbarch *gdbarch); extern void set_gdbarch_bfd_vma_bit (struct gdbarch *gdbarch, int bfd_vma_bit); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_BFD_VMA_BIT) #error "Non multi-arch definition of TARGET_BFD_VMA_BIT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_BFD_VMA_BIT) +#if !defined (TARGET_BFD_VMA_BIT) #define TARGET_BFD_VMA_BIT (gdbarch_bfd_vma_bit (current_gdbarch)) #endif -#endif /* One if `char' acts like `signed char', zero if `unsigned char'. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_CHAR_SIGNED) -#define TARGET_CHAR_SIGNED (1) -#endif - extern int gdbarch_char_signed (struct gdbarch *gdbarch); extern void set_gdbarch_char_signed (struct gdbarch *gdbarch, int char_signed); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_CHAR_SIGNED) #error "Non multi-arch definition of TARGET_CHAR_SIGNED" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_CHAR_SIGNED) +#if !defined (TARGET_CHAR_SIGNED) #define TARGET_CHAR_SIGNED (gdbarch_char_signed (current_gdbarch)) #endif + +#if defined (TARGET_READ_PC) +/* Legacy for systems yet to multi-arch TARGET_READ_PC */ +#if !defined (TARGET_READ_PC_P) +#define TARGET_READ_PC_P() (1) +#endif #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_READ_PC) -#define TARGET_READ_PC(ptid) (generic_target_read_pc (ptid)) +extern int gdbarch_read_pc_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_PC_P) +#error "Non multi-arch definition of TARGET_READ_PC" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_PC_P) +#define TARGET_READ_PC_P() (gdbarch_read_pc_p (current_gdbarch)) #endif typedef CORE_ADDR (gdbarch_read_pc_ftype) (ptid_t ptid); @@ -317,16 +247,9 @@ extern void set_gdbarch_read_pc (struct gdbarch *gdbarch, gdbarch_read_pc_ftype #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_PC) #error "Non multi-arch definition of TARGET_READ_PC" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_PC) +#if !defined (TARGET_READ_PC) #define TARGET_READ_PC(ptid) (gdbarch_read_pc (current_gdbarch, ptid)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_WRITE_PC) -#define TARGET_WRITE_PC(val, ptid) (generic_target_write_pc (val, ptid)) -#endif typedef void (gdbarch_write_pc_ftype) (CORE_ADDR val, ptid_t ptid); extern void gdbarch_write_pc (struct gdbarch *gdbarch, CORE_ADDR val, ptid_t ptid); @@ -334,49 +257,25 @@ extern void set_gdbarch_write_pc (struct gdbarch *gdbarch, gdbarch_write_pc_ftyp #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_WRITE_PC) #error "Non multi-arch definition of TARGET_WRITE_PC" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_WRITE_PC) +#if !defined (TARGET_WRITE_PC) #define TARGET_WRITE_PC(val, ptid) (gdbarch_write_pc (current_gdbarch, val, ptid)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_READ_FP) -#define TARGET_READ_FP() (generic_target_read_fp ()) -#endif +/* UNWIND_SP is a direct replacement for TARGET_READ_SP. */ -typedef CORE_ADDR (gdbarch_read_fp_ftype) (void); -extern CORE_ADDR gdbarch_read_fp (struct gdbarch *gdbarch); -extern void set_gdbarch_read_fp (struct gdbarch *gdbarch, gdbarch_read_fp_ftype *read_fp); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_FP) -#error "Non multi-arch definition of TARGET_READ_FP" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_FP) -#define TARGET_READ_FP() (gdbarch_read_fp (current_gdbarch)) +#if defined (TARGET_READ_SP) +/* Legacy for systems yet to multi-arch TARGET_READ_SP */ +#if !defined (TARGET_READ_SP_P) +#define TARGET_READ_SP_P() (1) #endif #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_WRITE_FP) -#define TARGET_WRITE_FP(val) (generic_target_write_fp (val)) +extern int gdbarch_read_sp_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_SP_P) +#error "Non multi-arch definition of TARGET_READ_SP" #endif - -typedef void (gdbarch_write_fp_ftype) (CORE_ADDR val); -extern void gdbarch_write_fp (struct gdbarch *gdbarch, CORE_ADDR val); -extern void set_gdbarch_write_fp (struct gdbarch *gdbarch, gdbarch_write_fp_ftype *write_fp); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_WRITE_FP) -#error "Non multi-arch definition of TARGET_WRITE_FP" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_WRITE_FP) -#define TARGET_WRITE_FP(val) (gdbarch_write_fp (current_gdbarch, val)) -#endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_READ_SP) -#define TARGET_READ_SP() (generic_target_read_sp ()) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_SP_P) +#define TARGET_READ_SP_P() (gdbarch_read_sp_p (current_gdbarch)) #endif typedef CORE_ADDR (gdbarch_read_sp_ftype) (void); @@ -385,130 +284,89 @@ extern void set_gdbarch_read_sp (struct gdbarch *gdbarch, gdbarch_read_sp_ftype #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_SP) #error "Non multi-arch definition of TARGET_READ_SP" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_SP) +#if !defined (TARGET_READ_SP) #define TARGET_READ_SP() (gdbarch_read_sp (current_gdbarch)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_WRITE_SP) -#define TARGET_WRITE_SP(val) (generic_target_write_sp (val)) -#endif - -typedef void (gdbarch_write_sp_ftype) (CORE_ADDR val); -extern void gdbarch_write_sp (struct gdbarch *gdbarch, CORE_ADDR val); -extern void set_gdbarch_write_sp (struct gdbarch *gdbarch, gdbarch_write_sp_ftype *write_sp); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_WRITE_SP) -#error "Non multi-arch definition of TARGET_WRITE_SP" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_WRITE_SP) -#define TARGET_WRITE_SP(val) (gdbarch_write_sp (current_gdbarch, val)) -#endif -#endif /* Function for getting target's idea of a frame pointer. FIXME: GDB's whole scheme for dealing with "frames" and "frame pointers" needs a serious shakedown. */ -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_VIRTUAL_FRAME_POINTER) -#define TARGET_VIRTUAL_FRAME_POINTER(pc, frame_regnum, frame_offset) (legacy_virtual_frame_pointer (pc, frame_regnum, frame_offset)) -#endif - typedef void (gdbarch_virtual_frame_pointer_ftype) (CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset); extern void gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset); extern void set_gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_VIRTUAL_FRAME_POINTER) #error "Non multi-arch definition of TARGET_VIRTUAL_FRAME_POINTER" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_VIRTUAL_FRAME_POINTER) +#if !defined (TARGET_VIRTUAL_FRAME_POINTER) #define TARGET_VIRTUAL_FRAME_POINTER(pc, frame_regnum, frame_offset) (gdbarch_virtual_frame_pointer (current_gdbarch, pc, frame_regnum, frame_offset)) #endif -#endif -extern int gdbarch_register_read_p (struct gdbarch *gdbarch); +extern int gdbarch_pseudo_register_read_p (struct gdbarch *gdbarch); -typedef void (gdbarch_register_read_ftype) (struct gdbarch *gdbarch, int regnum, char *buf); -extern void gdbarch_register_read (struct gdbarch *gdbarch, int regnum, char *buf); -extern void set_gdbarch_register_read (struct gdbarch *gdbarch, gdbarch_register_read_ftype *register_read); +typedef void (gdbarch_pseudo_register_read_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, void *buf); +extern void gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, void *buf); +extern void set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_ftype *pseudo_register_read); -extern int gdbarch_register_write_p (struct gdbarch *gdbarch); +extern int gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch); -typedef void (gdbarch_register_write_ftype) (struct gdbarch *gdbarch, int regnum, char *buf); -extern void gdbarch_register_write (struct gdbarch *gdbarch, int regnum, char *buf); -extern void set_gdbarch_register_write (struct gdbarch *gdbarch, gdbarch_register_write_ftype *register_write); +typedef void (gdbarch_pseudo_register_write_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const void *buf); +extern void gdbarch_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const void *buf); +extern void set_gdbarch_pseudo_register_write (struct gdbarch *gdbarch, gdbarch_pseudo_register_write_ftype *pseudo_register_write); extern int gdbarch_num_regs (struct gdbarch *gdbarch); extern void set_gdbarch_num_regs (struct gdbarch *gdbarch, int num_regs); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NUM_REGS) #error "Non multi-arch definition of NUM_REGS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (NUM_REGS) +#if !defined (NUM_REGS) #define NUM_REGS (gdbarch_num_regs (current_gdbarch)) #endif -#endif /* This macro gives the number of pseudo-registers that live in the register namespace but do not get fetched or stored on the target. These pseudo-registers may be aliases for other registers, combinations of other registers, or they may be computed by GDB. */ -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (NUM_PSEUDO_REGS) -#define NUM_PSEUDO_REGS (0) -#endif - extern int gdbarch_num_pseudo_regs (struct gdbarch *gdbarch); extern void set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch, int num_pseudo_regs); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NUM_PSEUDO_REGS) #error "Non multi-arch definition of NUM_PSEUDO_REGS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (NUM_PSEUDO_REGS) +#if !defined (NUM_PSEUDO_REGS) #define NUM_PSEUDO_REGS (gdbarch_num_pseudo_regs (current_gdbarch)) #endif -#endif + +/* GDB's standard (or well known) register numbers. These can map onto + a real register or a pseudo (computed) register or not be defined at + all (-1). + SP_REGNUM will hopefully be replaced by UNWIND_SP. */ extern int gdbarch_sp_regnum (struct gdbarch *gdbarch); extern void set_gdbarch_sp_regnum (struct gdbarch *gdbarch, int sp_regnum); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SP_REGNUM) #error "Non multi-arch definition of SP_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SP_REGNUM) +#if !defined (SP_REGNUM) #define SP_REGNUM (gdbarch_sp_regnum (current_gdbarch)) #endif -#endif - -extern int gdbarch_fp_regnum (struct gdbarch *gdbarch); -extern void set_gdbarch_fp_regnum (struct gdbarch *gdbarch, int fp_regnum); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FP_REGNUM) -#error "Non multi-arch definition of FP_REGNUM" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FP_REGNUM) -#define FP_REGNUM (gdbarch_fp_regnum (current_gdbarch)) -#endif -#endif extern int gdbarch_pc_regnum (struct gdbarch *gdbarch); extern void set_gdbarch_pc_regnum (struct gdbarch *gdbarch, int pc_regnum); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PC_REGNUM) #error "Non multi-arch definition of PC_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PC_REGNUM) +#if !defined (PC_REGNUM) #define PC_REGNUM (gdbarch_pc_regnum (current_gdbarch)) #endif -#endif -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (FP0_REGNUM) -#define FP0_REGNUM (-1) +extern int gdbarch_ps_regnum (struct gdbarch *gdbarch); +extern void set_gdbarch_ps_regnum (struct gdbarch *gdbarch, int ps_regnum); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PS_REGNUM) +#error "Non multi-arch definition of PS_REGNUM" +#endif +#if !defined (PS_REGNUM) +#define PS_REGNUM (gdbarch_ps_regnum (current_gdbarch)) #endif extern int gdbarch_fp0_regnum (struct gdbarch *gdbarch); @@ -516,109 +374,47 @@ extern void set_gdbarch_fp0_regnum (struct gdbarch *gdbarch, int fp0_regnum); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FP0_REGNUM) #error "Non multi-arch definition of FP0_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FP0_REGNUM) +#if !defined (FP0_REGNUM) #define FP0_REGNUM (gdbarch_fp0_regnum (current_gdbarch)) #endif -#endif - -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (NPC_REGNUM) -#define NPC_REGNUM (-1) -#endif - -extern int gdbarch_npc_regnum (struct gdbarch *gdbarch); -extern void set_gdbarch_npc_regnum (struct gdbarch *gdbarch, int npc_regnum); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NPC_REGNUM) -#error "Non multi-arch definition of NPC_REGNUM" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (NPC_REGNUM) -#define NPC_REGNUM (gdbarch_npc_regnum (current_gdbarch)) -#endif -#endif - -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (NNPC_REGNUM) -#define NNPC_REGNUM (-1) -#endif - -extern int gdbarch_nnpc_regnum (struct gdbarch *gdbarch); -extern void set_gdbarch_nnpc_regnum (struct gdbarch *gdbarch, int nnpc_regnum); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NNPC_REGNUM) -#error "Non multi-arch definition of NNPC_REGNUM" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (NNPC_REGNUM) -#define NNPC_REGNUM (gdbarch_nnpc_regnum (current_gdbarch)) -#endif -#endif /* Convert stab register number (from `r' declaration) to a gdb REGNUM. */ -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (STAB_REG_TO_REGNUM) -#define STAB_REG_TO_REGNUM(stab_regnr) (no_op_reg_to_regnum (stab_regnr)) -#endif - typedef int (gdbarch_stab_reg_to_regnum_ftype) (int stab_regnr); extern int gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, int stab_regnr); extern void set_gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_stab_reg_to_regnum_ftype *stab_reg_to_regnum); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STAB_REG_TO_REGNUM) #error "Non multi-arch definition of STAB_REG_TO_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STAB_REG_TO_REGNUM) +#if !defined (STAB_REG_TO_REGNUM) #define STAB_REG_TO_REGNUM(stab_regnr) (gdbarch_stab_reg_to_regnum (current_gdbarch, stab_regnr)) #endif -#endif /* Provide a default mapping from a ecoff register number to a gdb REGNUM. */ -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (ECOFF_REG_TO_REGNUM) -#define ECOFF_REG_TO_REGNUM(ecoff_regnr) (no_op_reg_to_regnum (ecoff_regnr)) -#endif - typedef int (gdbarch_ecoff_reg_to_regnum_ftype) (int ecoff_regnr); extern int gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int ecoff_regnr); extern void set_gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_ecoff_reg_to_regnum_ftype *ecoff_reg_to_regnum); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ECOFF_REG_TO_REGNUM) #error "Non multi-arch definition of ECOFF_REG_TO_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ECOFF_REG_TO_REGNUM) +#if !defined (ECOFF_REG_TO_REGNUM) #define ECOFF_REG_TO_REGNUM(ecoff_regnr) (gdbarch_ecoff_reg_to_regnum (current_gdbarch, ecoff_regnr)) #endif -#endif /* Provide a default mapping from a DWARF register number to a gdb REGNUM. */ -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (DWARF_REG_TO_REGNUM) -#define DWARF_REG_TO_REGNUM(dwarf_regnr) (no_op_reg_to_regnum (dwarf_regnr)) -#endif - typedef int (gdbarch_dwarf_reg_to_regnum_ftype) (int dwarf_regnr); extern int gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_regnr); extern void set_gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_dwarf_reg_to_regnum_ftype *dwarf_reg_to_regnum); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF_REG_TO_REGNUM) #error "Non multi-arch definition of DWARF_REG_TO_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF_REG_TO_REGNUM) +#if !defined (DWARF_REG_TO_REGNUM) #define DWARF_REG_TO_REGNUM(dwarf_regnr) (gdbarch_dwarf_reg_to_regnum (current_gdbarch, dwarf_regnr)) #endif -#endif -/* Convert from an sdb register number to an internal gdb register number. - This should be defined in tm.h, if REGISTER_NAMES is not set up - to map one to one onto the sdb register numbers. */ - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (SDB_REG_TO_REGNUM) -#define SDB_REG_TO_REGNUM(sdb_regnr) (no_op_reg_to_regnum (sdb_regnr)) -#endif +/* Convert from an sdb register number to an internal gdb register number. */ typedef int (gdbarch_sdb_reg_to_regnum_ftype) (int sdb_regnr); extern int gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int sdb_regnr); @@ -626,16 +422,9 @@ extern void set_gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_sdb_ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SDB_REG_TO_REGNUM) #error "Non multi-arch definition of SDB_REG_TO_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SDB_REG_TO_REGNUM) +#if !defined (SDB_REG_TO_REGNUM) #define SDB_REG_TO_REGNUM(sdb_regnr) (gdbarch_sdb_reg_to_regnum (current_gdbarch, sdb_regnr)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (DWARF2_REG_TO_REGNUM) -#define DWARF2_REG_TO_REGNUM(dwarf2_regnr) (no_op_reg_to_regnum (dwarf2_regnr)) -#endif typedef int (gdbarch_dwarf2_reg_to_regnum_ftype) (int dwarf2_regnr); extern int gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2_regnr); @@ -643,174 +432,583 @@ extern void set_gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_d #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_REG_TO_REGNUM) #error "Non multi-arch definition of DWARF2_REG_TO_REGNUM" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_REG_TO_REGNUM) +#if !defined (DWARF2_REG_TO_REGNUM) #define DWARF2_REG_TO_REGNUM(dwarf2_regnr) (gdbarch_dwarf2_reg_to_regnum (current_gdbarch, dwarf2_regnr)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REGISTER_NAME) -#define REGISTER_NAME(regnr) (legacy_register_name (regnr)) -#endif - -typedef char * (gdbarch_register_name_ftype) (int regnr); -extern char * gdbarch_register_name (struct gdbarch *gdbarch, int regnr); +typedef const char * (gdbarch_register_name_ftype) (int regnr); +extern const char * gdbarch_register_name (struct gdbarch *gdbarch, int regnr); extern void set_gdbarch_register_name (struct gdbarch *gdbarch, gdbarch_register_name_ftype *register_name); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_NAME) #error "Non multi-arch definition of REGISTER_NAME" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_NAME) +#if !defined (REGISTER_NAME) #define REGISTER_NAME(regnr) (gdbarch_register_name (current_gdbarch, regnr)) #endif -#endif -extern int gdbarch_register_size (struct gdbarch *gdbarch); -extern void set_gdbarch_register_size (struct gdbarch *gdbarch, int register_size); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_SIZE) -#error "Non multi-arch definition of REGISTER_SIZE" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_SIZE) -#define REGISTER_SIZE (gdbarch_register_size (current_gdbarch)) +/* REGISTER_TYPE is a direct replacement for DEPRECATED_REGISTER_VIRTUAL_TYPE. */ + +extern int gdbarch_register_type_p (struct gdbarch *gdbarch); + +typedef struct type * (gdbarch_register_type_ftype) (struct gdbarch *gdbarch, int reg_nr); +extern struct type * gdbarch_register_type (struct gdbarch *gdbarch, int reg_nr); +extern void set_gdbarch_register_type (struct gdbarch *gdbarch, gdbarch_register_type_ftype *register_type); + +/* REGISTER_TYPE is a direct replacement for DEPRECATED_REGISTER_VIRTUAL_TYPE. */ + +#if defined (DEPRECATED_REGISTER_VIRTUAL_TYPE) +/* Legacy for systems yet to multi-arch DEPRECATED_REGISTER_VIRTUAL_TYPE */ +#if !defined (DEPRECATED_REGISTER_VIRTUAL_TYPE_P) +#define DEPRECATED_REGISTER_VIRTUAL_TYPE_P() (1) #endif #endif -extern int gdbarch_register_bytes (struct gdbarch *gdbarch); -extern void set_gdbarch_register_bytes (struct gdbarch *gdbarch, int register_bytes); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTES) -#error "Non multi-arch definition of REGISTER_BYTES" +extern int gdbarch_deprecated_register_virtual_type_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_VIRTUAL_TYPE_P) +#error "Non multi-arch definition of DEPRECATED_REGISTER_VIRTUAL_TYPE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_BYTES) -#define REGISTER_BYTES (gdbarch_register_bytes (current_gdbarch)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_REGISTER_VIRTUAL_TYPE_P) +#define DEPRECATED_REGISTER_VIRTUAL_TYPE_P() (gdbarch_deprecated_register_virtual_type_p (current_gdbarch)) +#endif + +typedef struct type * (gdbarch_deprecated_register_virtual_type_ftype) (int reg_nr); +extern struct type * gdbarch_deprecated_register_virtual_type (struct gdbarch *gdbarch, int reg_nr); +extern void set_gdbarch_deprecated_register_virtual_type (struct gdbarch *gdbarch, gdbarch_deprecated_register_virtual_type_ftype *deprecated_register_virtual_type); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_VIRTUAL_TYPE) +#error "Non multi-arch definition of DEPRECATED_REGISTER_VIRTUAL_TYPE" +#endif +#if !defined (DEPRECATED_REGISTER_VIRTUAL_TYPE) +#define DEPRECATED_REGISTER_VIRTUAL_TYPE(reg_nr) (gdbarch_deprecated_register_virtual_type (current_gdbarch, reg_nr)) +#endif + +/* DEPRECATED_REGISTER_BYTES can be deleted. The value is computed + from REGISTER_TYPE. */ + +extern int gdbarch_deprecated_register_bytes (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_register_bytes (struct gdbarch *gdbarch, int deprecated_register_bytes); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_BYTES) +#error "Non multi-arch definition of DEPRECATED_REGISTER_BYTES" +#endif +#if !defined (DEPRECATED_REGISTER_BYTES) +#define DEPRECATED_REGISTER_BYTES (gdbarch_deprecated_register_bytes (current_gdbarch)) +#endif + +/* If the value returned by DEPRECATED_REGISTER_BYTE agrees with the + register offsets computed using just REGISTER_TYPE, this can be + deleted. See: maint print registers. NOTE: cagney/2002-05-02: This + function with predicate has a valid (callable) initial value. As a + consequence, even when the predicate is false, the corresponding + function works. This simplifies the migration process - old code, + calling DEPRECATED_REGISTER_BYTE, doesn't need to be modified. */ + +#if defined (DEPRECATED_REGISTER_BYTE) +/* Legacy for systems yet to multi-arch DEPRECATED_REGISTER_BYTE */ +#if !defined (DEPRECATED_REGISTER_BYTE_P) +#define DEPRECATED_REGISTER_BYTE_P() (1) #endif #endif -typedef int (gdbarch_register_byte_ftype) (int reg_nr); -extern int gdbarch_register_byte (struct gdbarch *gdbarch, int reg_nr); -extern void set_gdbarch_register_byte (struct gdbarch *gdbarch, gdbarch_register_byte_ftype *register_byte); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTE) -#error "Non multi-arch definition of REGISTER_BYTE" +extern int gdbarch_deprecated_register_byte_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_BYTE_P) +#error "Non multi-arch definition of DEPRECATED_REGISTER_BYTE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_BYTE) -#define REGISTER_BYTE(reg_nr) (gdbarch_register_byte (current_gdbarch, reg_nr)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_REGISTER_BYTE_P) +#define DEPRECATED_REGISTER_BYTE_P() (gdbarch_deprecated_register_byte_p (current_gdbarch)) +#endif + +typedef int (gdbarch_deprecated_register_byte_ftype) (int reg_nr); +extern int gdbarch_deprecated_register_byte (struct gdbarch *gdbarch, int reg_nr); +extern void set_gdbarch_deprecated_register_byte (struct gdbarch *gdbarch, gdbarch_deprecated_register_byte_ftype *deprecated_register_byte); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_BYTE) +#error "Non multi-arch definition of DEPRECATED_REGISTER_BYTE" +#endif +#if !defined (DEPRECATED_REGISTER_BYTE) +#define DEPRECATED_REGISTER_BYTE(reg_nr) (gdbarch_deprecated_register_byte (current_gdbarch, reg_nr)) +#endif + +/* If all registers have identical raw and virtual sizes and those + sizes agree with the value computed from REGISTER_TYPE, + DEPRECATED_REGISTER_RAW_SIZE can be deleted. See: maint print + registers. */ + +#if defined (DEPRECATED_REGISTER_RAW_SIZE) +/* Legacy for systems yet to multi-arch DEPRECATED_REGISTER_RAW_SIZE */ +#if !defined (DEPRECATED_REGISTER_RAW_SIZE_P) +#define DEPRECATED_REGISTER_RAW_SIZE_P() (1) #endif #endif -typedef int (gdbarch_register_raw_size_ftype) (int reg_nr); -extern int gdbarch_register_raw_size (struct gdbarch *gdbarch, int reg_nr); -extern void set_gdbarch_register_raw_size (struct gdbarch *gdbarch, gdbarch_register_raw_size_ftype *register_raw_size); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_RAW_SIZE) -#error "Non multi-arch definition of REGISTER_RAW_SIZE" +extern int gdbarch_deprecated_register_raw_size_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_RAW_SIZE_P) +#error "Non multi-arch definition of DEPRECATED_REGISTER_RAW_SIZE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_RAW_SIZE) -#define REGISTER_RAW_SIZE(reg_nr) (gdbarch_register_raw_size (current_gdbarch, reg_nr)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_REGISTER_RAW_SIZE_P) +#define DEPRECATED_REGISTER_RAW_SIZE_P() (gdbarch_deprecated_register_raw_size_p (current_gdbarch)) +#endif + +typedef int (gdbarch_deprecated_register_raw_size_ftype) (int reg_nr); +extern int gdbarch_deprecated_register_raw_size (struct gdbarch *gdbarch, int reg_nr); +extern void set_gdbarch_deprecated_register_raw_size (struct gdbarch *gdbarch, gdbarch_deprecated_register_raw_size_ftype *deprecated_register_raw_size); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_RAW_SIZE) +#error "Non multi-arch definition of DEPRECATED_REGISTER_RAW_SIZE" +#endif +#if !defined (DEPRECATED_REGISTER_RAW_SIZE) +#define DEPRECATED_REGISTER_RAW_SIZE(reg_nr) (gdbarch_deprecated_register_raw_size (current_gdbarch, reg_nr)) +#endif + +/* If all registers have identical raw and virtual sizes and those + sizes agree with the value computed from REGISTER_TYPE, + DEPRECATED_REGISTER_VIRTUAL_SIZE can be deleted. See: maint print + registers. */ + +#if defined (DEPRECATED_REGISTER_VIRTUAL_SIZE) +/* Legacy for systems yet to multi-arch DEPRECATED_REGISTER_VIRTUAL_SIZE */ +#if !defined (DEPRECATED_REGISTER_VIRTUAL_SIZE_P) +#define DEPRECATED_REGISTER_VIRTUAL_SIZE_P() (1) #endif #endif -extern int gdbarch_max_register_raw_size (struct gdbarch *gdbarch); -extern void set_gdbarch_max_register_raw_size (struct gdbarch *gdbarch, int max_register_raw_size); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MAX_REGISTER_RAW_SIZE) -#error "Non multi-arch definition of MAX_REGISTER_RAW_SIZE" +extern int gdbarch_deprecated_register_virtual_size_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_VIRTUAL_SIZE_P) +#error "Non multi-arch definition of DEPRECATED_REGISTER_VIRTUAL_SIZE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MAX_REGISTER_RAW_SIZE) -#define MAX_REGISTER_RAW_SIZE (gdbarch_max_register_raw_size (current_gdbarch)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_REGISTER_VIRTUAL_SIZE_P) +#define DEPRECATED_REGISTER_VIRTUAL_SIZE_P() (gdbarch_deprecated_register_virtual_size_p (current_gdbarch)) +#endif + +typedef int (gdbarch_deprecated_register_virtual_size_ftype) (int reg_nr); +extern int gdbarch_deprecated_register_virtual_size (struct gdbarch *gdbarch, int reg_nr); +extern void set_gdbarch_deprecated_register_virtual_size (struct gdbarch *gdbarch, gdbarch_deprecated_register_virtual_size_ftype *deprecated_register_virtual_size); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_VIRTUAL_SIZE) +#error "Non multi-arch definition of DEPRECATED_REGISTER_VIRTUAL_SIZE" +#endif +#if !defined (DEPRECATED_REGISTER_VIRTUAL_SIZE) +#define DEPRECATED_REGISTER_VIRTUAL_SIZE(reg_nr) (gdbarch_deprecated_register_virtual_size (current_gdbarch, reg_nr)) +#endif + +/* DEPRECATED_MAX_REGISTER_RAW_SIZE can be deleted. It has been + replaced by the constant MAX_REGISTER_SIZE. */ + +#if defined (DEPRECATED_MAX_REGISTER_RAW_SIZE) +/* Legacy for systems yet to multi-arch DEPRECATED_MAX_REGISTER_RAW_SIZE */ +#if !defined (DEPRECATED_MAX_REGISTER_RAW_SIZE_P) +#define DEPRECATED_MAX_REGISTER_RAW_SIZE_P() (1) #endif #endif -typedef int (gdbarch_register_virtual_size_ftype) (int reg_nr); -extern int gdbarch_register_virtual_size (struct gdbarch *gdbarch, int reg_nr); -extern void set_gdbarch_register_virtual_size (struct gdbarch *gdbarch, gdbarch_register_virtual_size_ftype *register_virtual_size); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_VIRTUAL_SIZE) -#error "Non multi-arch definition of REGISTER_VIRTUAL_SIZE" +extern int gdbarch_deprecated_max_register_raw_size_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_MAX_REGISTER_RAW_SIZE_P) +#error "Non multi-arch definition of DEPRECATED_MAX_REGISTER_RAW_SIZE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_VIRTUAL_SIZE) -#define REGISTER_VIRTUAL_SIZE(reg_nr) (gdbarch_register_virtual_size (current_gdbarch, reg_nr)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_MAX_REGISTER_RAW_SIZE_P) +#define DEPRECATED_MAX_REGISTER_RAW_SIZE_P() (gdbarch_deprecated_max_register_raw_size_p (current_gdbarch)) +#endif + +extern int gdbarch_deprecated_max_register_raw_size (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_max_register_raw_size (struct gdbarch *gdbarch, int deprecated_max_register_raw_size); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_MAX_REGISTER_RAW_SIZE) +#error "Non multi-arch definition of DEPRECATED_MAX_REGISTER_RAW_SIZE" +#endif +#if !defined (DEPRECATED_MAX_REGISTER_RAW_SIZE) +#define DEPRECATED_MAX_REGISTER_RAW_SIZE (gdbarch_deprecated_max_register_raw_size (current_gdbarch)) +#endif + +/* DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE can be deleted. It has been + replaced by the constant MAX_REGISTER_SIZE. */ + +#if defined (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE) +/* Legacy for systems yet to multi-arch DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE */ +#if !defined (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P) +#define DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P() (1) #endif #endif -extern int gdbarch_max_register_virtual_size (struct gdbarch *gdbarch); -extern void set_gdbarch_max_register_virtual_size (struct gdbarch *gdbarch, int max_register_virtual_size); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MAX_REGISTER_VIRTUAL_SIZE) -#error "Non multi-arch definition of MAX_REGISTER_VIRTUAL_SIZE" +extern int gdbarch_deprecated_max_register_virtual_size_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P) +#error "Non multi-arch definition of DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MAX_REGISTER_VIRTUAL_SIZE) -#define MAX_REGISTER_VIRTUAL_SIZE (gdbarch_max_register_virtual_size (current_gdbarch)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P) +#define DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE_P() (gdbarch_deprecated_max_register_virtual_size_p (current_gdbarch)) +#endif + +extern int gdbarch_deprecated_max_register_virtual_size (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_max_register_virtual_size (struct gdbarch *gdbarch, int deprecated_max_register_virtual_size); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE) +#error "Non multi-arch definition of DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE" +#endif +#if !defined (DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE) +#define DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE (gdbarch_deprecated_max_register_virtual_size (current_gdbarch)) +#endif + +/* See gdbint.texinfo, and PUSH_DUMMY_CALL. */ + +extern int gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch); + +typedef struct frame_id (gdbarch_unwind_dummy_id_ftype) (struct gdbarch *gdbarch, struct frame_info *info); +extern struct frame_id gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info); +extern void set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, gdbarch_unwind_dummy_id_ftype *unwind_dummy_id); + +/* Implement UNWIND_DUMMY_ID and PUSH_DUMMY_CALL, then delete + SAVE_DUMMY_FRAME_TOS. */ + +#if defined (DEPRECATED_SAVE_DUMMY_FRAME_TOS) +/* Legacy for systems yet to multi-arch DEPRECATED_SAVE_DUMMY_FRAME_TOS */ +#if !defined (DEPRECATED_SAVE_DUMMY_FRAME_TOS_P) +#define DEPRECATED_SAVE_DUMMY_FRAME_TOS_P() (1) #endif #endif -typedef struct type * (gdbarch_register_virtual_type_ftype) (int reg_nr); -extern struct type * gdbarch_register_virtual_type (struct gdbarch *gdbarch, int reg_nr); -extern void set_gdbarch_register_virtual_type (struct gdbarch *gdbarch, gdbarch_register_virtual_type_ftype *register_virtual_type); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_VIRTUAL_TYPE) -#error "Non multi-arch definition of REGISTER_VIRTUAL_TYPE" +extern int gdbarch_deprecated_save_dummy_frame_tos_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_SAVE_DUMMY_FRAME_TOS_P) +#error "Non multi-arch definition of DEPRECATED_SAVE_DUMMY_FRAME_TOS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_VIRTUAL_TYPE) -#define REGISTER_VIRTUAL_TYPE(reg_nr) (gdbarch_register_virtual_type (current_gdbarch, reg_nr)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_SAVE_DUMMY_FRAME_TOS_P) +#define DEPRECATED_SAVE_DUMMY_FRAME_TOS_P() (gdbarch_deprecated_save_dummy_frame_tos_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_save_dummy_frame_tos_ftype) (CORE_ADDR sp); +extern void gdbarch_deprecated_save_dummy_frame_tos (struct gdbarch *gdbarch, CORE_ADDR sp); +extern void set_gdbarch_deprecated_save_dummy_frame_tos (struct gdbarch *gdbarch, gdbarch_deprecated_save_dummy_frame_tos_ftype *deprecated_save_dummy_frame_tos); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_SAVE_DUMMY_FRAME_TOS) +#error "Non multi-arch definition of DEPRECATED_SAVE_DUMMY_FRAME_TOS" +#endif +#if !defined (DEPRECATED_SAVE_DUMMY_FRAME_TOS) +#define DEPRECATED_SAVE_DUMMY_FRAME_TOS(sp) (gdbarch_deprecated_save_dummy_frame_tos (current_gdbarch, sp)) +#endif + +/* Implement UNWIND_DUMMY_ID and PUSH_DUMMY_CALL, then delete + DEPRECATED_FP_REGNUM. */ + +extern int gdbarch_deprecated_fp_regnum (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_fp_regnum (struct gdbarch *gdbarch, int deprecated_fp_regnum); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FP_REGNUM) +#error "Non multi-arch definition of DEPRECATED_FP_REGNUM" +#endif +#if !defined (DEPRECATED_FP_REGNUM) +#define DEPRECATED_FP_REGNUM (gdbarch_deprecated_fp_regnum (current_gdbarch)) +#endif + +/* Implement UNWIND_DUMMY_ID and PUSH_DUMMY_CALL, then delete + DEPRECATED_TARGET_READ_FP. */ + +#if defined (DEPRECATED_TARGET_READ_FP) +/* Legacy for systems yet to multi-arch DEPRECATED_TARGET_READ_FP */ +#if !defined (DEPRECATED_TARGET_READ_FP_P) +#define DEPRECATED_TARGET_READ_FP_P() (1) #endif #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (DO_REGISTERS_INFO) -#define DO_REGISTERS_INFO(reg_nr, fpregs) (do_registers_info (reg_nr, fpregs)) +extern int gdbarch_deprecated_target_read_fp_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_TARGET_READ_FP_P) +#error "Non multi-arch definition of DEPRECATED_TARGET_READ_FP" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_TARGET_READ_FP_P) +#define DEPRECATED_TARGET_READ_FP_P() (gdbarch_deprecated_target_read_fp_p (current_gdbarch)) #endif -typedef void (gdbarch_do_registers_info_ftype) (int reg_nr, int fpregs); -extern void gdbarch_do_registers_info (struct gdbarch *gdbarch, int reg_nr, int fpregs); -extern void set_gdbarch_do_registers_info (struct gdbarch *gdbarch, gdbarch_do_registers_info_ftype *do_registers_info); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DO_REGISTERS_INFO) -#error "Non multi-arch definition of DO_REGISTERS_INFO" +typedef CORE_ADDR (gdbarch_deprecated_target_read_fp_ftype) (void); +extern CORE_ADDR gdbarch_deprecated_target_read_fp (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_target_read_fp (struct gdbarch *gdbarch, gdbarch_deprecated_target_read_fp_ftype *deprecated_target_read_fp); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_TARGET_READ_FP) +#error "Non multi-arch definition of DEPRECATED_TARGET_READ_FP" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DO_REGISTERS_INFO) -#define DO_REGISTERS_INFO(reg_nr, fpregs) (gdbarch_do_registers_info (current_gdbarch, reg_nr, fpregs)) +#if !defined (DEPRECATED_TARGET_READ_FP) +#define DEPRECATED_TARGET_READ_FP() (gdbarch_deprecated_target_read_fp (current_gdbarch)) +#endif + +/* See gdbint.texinfo. See infcall.c. New, all singing all dancing, + replacement for DEPRECATED_PUSH_ARGUMENTS. */ + +extern int gdbarch_push_dummy_call_p (struct gdbarch *gdbarch); + +typedef CORE_ADDR (gdbarch_push_dummy_call_ftype) (struct gdbarch *gdbarch, CORE_ADDR func_addr, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr); +extern CORE_ADDR gdbarch_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr); +extern void set_gdbarch_push_dummy_call (struct gdbarch *gdbarch, gdbarch_push_dummy_call_ftype *push_dummy_call); + +/* PUSH_DUMMY_CALL is a direct replacement for DEPRECATED_PUSH_ARGUMENTS. */ + +#if defined (DEPRECATED_PUSH_ARGUMENTS) +/* Legacy for systems yet to multi-arch DEPRECATED_PUSH_ARGUMENTS */ +#if !defined (DEPRECATED_PUSH_ARGUMENTS_P) +#define DEPRECATED_PUSH_ARGUMENTS_P() (1) #endif #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (PRINT_FLOAT_INFO) -#define PRINT_FLOAT_INFO() (default_print_float_info ()) +extern int gdbarch_deprecated_push_arguments_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PUSH_ARGUMENTS_P) +#error "Non multi-arch definition of DEPRECATED_PUSH_ARGUMENTS" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PUSH_ARGUMENTS_P) +#define DEPRECATED_PUSH_ARGUMENTS_P() (gdbarch_deprecated_push_arguments_p (current_gdbarch)) #endif -typedef void (gdbarch_print_float_info_ftype) (void); -extern void gdbarch_print_float_info (struct gdbarch *gdbarch); +typedef CORE_ADDR (gdbarch_deprecated_push_arguments_ftype) (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr); +extern CORE_ADDR gdbarch_deprecated_push_arguments (struct gdbarch *gdbarch, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr); +extern void set_gdbarch_deprecated_push_arguments (struct gdbarch *gdbarch, gdbarch_deprecated_push_arguments_ftype *deprecated_push_arguments); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PUSH_ARGUMENTS) +#error "Non multi-arch definition of DEPRECATED_PUSH_ARGUMENTS" +#endif +#if !defined (DEPRECATED_PUSH_ARGUMENTS) +#define DEPRECATED_PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) (gdbarch_deprecated_push_arguments (current_gdbarch, nargs, args, sp, struct_return, struct_addr)) +#endif + +/* DEPRECATED_USE_GENERIC_DUMMY_FRAMES can be deleted. Always true. */ + +extern int gdbarch_deprecated_use_generic_dummy_frames (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_use_generic_dummy_frames (struct gdbarch *gdbarch, int deprecated_use_generic_dummy_frames); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) +#error "Non multi-arch definition of DEPRECATED_USE_GENERIC_DUMMY_FRAMES" +#endif +#if !defined (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) +#define DEPRECATED_USE_GENERIC_DUMMY_FRAMES (gdbarch_deprecated_use_generic_dummy_frames (current_gdbarch)) +#endif + +/* Implement PUSH_RETURN_ADDRESS, and then merge in + DEPRECATED_PUSH_RETURN_ADDRESS. */ + +#if defined (DEPRECATED_PUSH_RETURN_ADDRESS) +/* Legacy for systems yet to multi-arch DEPRECATED_PUSH_RETURN_ADDRESS */ +#if !defined (DEPRECATED_PUSH_RETURN_ADDRESS_P) +#define DEPRECATED_PUSH_RETURN_ADDRESS_P() (1) +#endif +#endif + +extern int gdbarch_deprecated_push_return_address_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PUSH_RETURN_ADDRESS_P) +#error "Non multi-arch definition of DEPRECATED_PUSH_RETURN_ADDRESS" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PUSH_RETURN_ADDRESS_P) +#define DEPRECATED_PUSH_RETURN_ADDRESS_P() (gdbarch_deprecated_push_return_address_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_deprecated_push_return_address_ftype) (CORE_ADDR pc, CORE_ADDR sp); +extern CORE_ADDR gdbarch_deprecated_push_return_address (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp); +extern void set_gdbarch_deprecated_push_return_address (struct gdbarch *gdbarch, gdbarch_deprecated_push_return_address_ftype *deprecated_push_return_address); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PUSH_RETURN_ADDRESS) +#error "Non multi-arch definition of DEPRECATED_PUSH_RETURN_ADDRESS" +#endif +#if !defined (DEPRECATED_PUSH_RETURN_ADDRESS) +#define DEPRECATED_PUSH_RETURN_ADDRESS(pc, sp) (gdbarch_deprecated_push_return_address (current_gdbarch, pc, sp)) +#endif + +/* Implement PUSH_DUMMY_CALL, then merge in DEPRECATED_DUMMY_WRITE_SP. */ + +#if defined (DEPRECATED_DUMMY_WRITE_SP) +/* Legacy for systems yet to multi-arch DEPRECATED_DUMMY_WRITE_SP */ +#if !defined (DEPRECATED_DUMMY_WRITE_SP_P) +#define DEPRECATED_DUMMY_WRITE_SP_P() (1) +#endif +#endif + +extern int gdbarch_deprecated_dummy_write_sp_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_DUMMY_WRITE_SP_P) +#error "Non multi-arch definition of DEPRECATED_DUMMY_WRITE_SP" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_DUMMY_WRITE_SP_P) +#define DEPRECATED_DUMMY_WRITE_SP_P() (gdbarch_deprecated_dummy_write_sp_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_dummy_write_sp_ftype) (CORE_ADDR val); +extern void gdbarch_deprecated_dummy_write_sp (struct gdbarch *gdbarch, CORE_ADDR val); +extern void set_gdbarch_deprecated_dummy_write_sp (struct gdbarch *gdbarch, gdbarch_deprecated_dummy_write_sp_ftype *deprecated_dummy_write_sp); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_DUMMY_WRITE_SP) +#error "Non multi-arch definition of DEPRECATED_DUMMY_WRITE_SP" +#endif +#if !defined (DEPRECATED_DUMMY_WRITE_SP) +#define DEPRECATED_DUMMY_WRITE_SP(val) (gdbarch_deprecated_dummy_write_sp (current_gdbarch, val)) +#endif + +/* DEPRECATED_REGISTER_SIZE can be deleted. */ + +extern int gdbarch_deprecated_register_size (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_register_size (struct gdbarch *gdbarch, int deprecated_register_size); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_SIZE) +#error "Non multi-arch definition of DEPRECATED_REGISTER_SIZE" +#endif +#if !defined (DEPRECATED_REGISTER_SIZE) +#define DEPRECATED_REGISTER_SIZE (gdbarch_deprecated_register_size (current_gdbarch)) +#endif + +extern int gdbarch_call_dummy_location (struct gdbarch *gdbarch); +extern void set_gdbarch_call_dummy_location (struct gdbarch *gdbarch, int call_dummy_location); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_LOCATION) +#error "Non multi-arch definition of CALL_DUMMY_LOCATION" +#endif +#if !defined (CALL_DUMMY_LOCATION) +#define CALL_DUMMY_LOCATION (gdbarch_call_dummy_location (current_gdbarch)) +#endif + +/* DEPRECATED_CALL_DUMMY_START_OFFSET can be deleted. */ + +extern CORE_ADDR gdbarch_deprecated_call_dummy_start_offset (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_call_dummy_start_offset (struct gdbarch *gdbarch, CORE_ADDR deprecated_call_dummy_start_offset); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_CALL_DUMMY_START_OFFSET) +#error "Non multi-arch definition of DEPRECATED_CALL_DUMMY_START_OFFSET" +#endif +#if !defined (DEPRECATED_CALL_DUMMY_START_OFFSET) +#define DEPRECATED_CALL_DUMMY_START_OFFSET (gdbarch_deprecated_call_dummy_start_offset (current_gdbarch)) +#endif + +/* DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET can be deleted. */ + +extern CORE_ADDR gdbarch_deprecated_call_dummy_breakpoint_offset (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_call_dummy_breakpoint_offset (struct gdbarch *gdbarch, CORE_ADDR deprecated_call_dummy_breakpoint_offset); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET) +#error "Non multi-arch definition of DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET" +#endif +#if !defined (DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET) +#define DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET (gdbarch_deprecated_call_dummy_breakpoint_offset (current_gdbarch)) +#endif + +/* DEPRECATED_CALL_DUMMY_LENGTH can be deleted. */ + +extern int gdbarch_deprecated_call_dummy_length (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_call_dummy_length (struct gdbarch *gdbarch, int deprecated_call_dummy_length); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_CALL_DUMMY_LENGTH) +#error "Non multi-arch definition of DEPRECATED_CALL_DUMMY_LENGTH" +#endif +#if !defined (DEPRECATED_CALL_DUMMY_LENGTH) +#define DEPRECATED_CALL_DUMMY_LENGTH (gdbarch_deprecated_call_dummy_length (current_gdbarch)) +#endif + +/* DEPRECATED_CALL_DUMMY_WORDS can be deleted. */ + +extern LONGEST * gdbarch_deprecated_call_dummy_words (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_call_dummy_words (struct gdbarch *gdbarch, LONGEST * deprecated_call_dummy_words); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_CALL_DUMMY_WORDS) +#error "Non multi-arch definition of DEPRECATED_CALL_DUMMY_WORDS" +#endif +#if !defined (DEPRECATED_CALL_DUMMY_WORDS) +#define DEPRECATED_CALL_DUMMY_WORDS (gdbarch_deprecated_call_dummy_words (current_gdbarch)) +#endif + +/* Implement PUSH_DUMMY_CALL, then delete DEPRECATED_SIZEOF_CALL_DUMMY_WORDS. */ + +extern int gdbarch_deprecated_sizeof_call_dummy_words (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_sizeof_call_dummy_words (struct gdbarch *gdbarch, int deprecated_sizeof_call_dummy_words); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_SIZEOF_CALL_DUMMY_WORDS) +#error "Non multi-arch definition of DEPRECATED_SIZEOF_CALL_DUMMY_WORDS" +#endif +#if !defined (DEPRECATED_SIZEOF_CALL_DUMMY_WORDS) +#define DEPRECATED_SIZEOF_CALL_DUMMY_WORDS (gdbarch_deprecated_sizeof_call_dummy_words (current_gdbarch)) +#endif + +/* DEPRECATED_FIX_CALL_DUMMY can be deleted. For the SPARC, implement + PUSH_DUMMY_CODE and set CALL_DUMMY_LOCATION to ON_STACK. */ + +#if defined (DEPRECATED_FIX_CALL_DUMMY) +/* Legacy for systems yet to multi-arch DEPRECATED_FIX_CALL_DUMMY */ +#if !defined (DEPRECATED_FIX_CALL_DUMMY_P) +#define DEPRECATED_FIX_CALL_DUMMY_P() (1) +#endif +#endif + +extern int gdbarch_deprecated_fix_call_dummy_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FIX_CALL_DUMMY_P) +#error "Non multi-arch definition of DEPRECATED_FIX_CALL_DUMMY" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FIX_CALL_DUMMY_P) +#define DEPRECATED_FIX_CALL_DUMMY_P() (gdbarch_deprecated_fix_call_dummy_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_fix_call_dummy_ftype) (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p); +extern void gdbarch_deprecated_fix_call_dummy (struct gdbarch *gdbarch, char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p); +extern void set_gdbarch_deprecated_fix_call_dummy (struct gdbarch *gdbarch, gdbarch_deprecated_fix_call_dummy_ftype *deprecated_fix_call_dummy); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FIX_CALL_DUMMY) +#error "Non multi-arch definition of DEPRECATED_FIX_CALL_DUMMY" +#endif +#if !defined (DEPRECATED_FIX_CALL_DUMMY) +#define DEPRECATED_FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, type, gcc_p) (gdbarch_deprecated_fix_call_dummy (current_gdbarch, dummy, pc, fun, nargs, args, type, gcc_p)) +#endif + +/* This is a replacement for DEPRECATED_FIX_CALL_DUMMY et.al. */ + +extern int gdbarch_push_dummy_code_p (struct gdbarch *gdbarch); + +typedef CORE_ADDR (gdbarch_push_dummy_code_ftype) (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, struct value **args, int nargs, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr); +extern CORE_ADDR gdbarch_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, struct value **args, int nargs, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr); +extern void set_gdbarch_push_dummy_code (struct gdbarch *gdbarch, gdbarch_push_dummy_code_ftype *push_dummy_code); + +/* Implement PUSH_DUMMY_CALL, then delete DEPRECATED_PUSH_DUMMY_FRAME. */ + +#if defined (DEPRECATED_PUSH_DUMMY_FRAME) +/* Legacy for systems yet to multi-arch DEPRECATED_PUSH_DUMMY_FRAME */ +#if !defined (DEPRECATED_PUSH_DUMMY_FRAME_P) +#define DEPRECATED_PUSH_DUMMY_FRAME_P() (1) +#endif +#endif + +extern int gdbarch_deprecated_push_dummy_frame_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PUSH_DUMMY_FRAME_P) +#error "Non multi-arch definition of DEPRECATED_PUSH_DUMMY_FRAME" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PUSH_DUMMY_FRAME_P) +#define DEPRECATED_PUSH_DUMMY_FRAME_P() (gdbarch_deprecated_push_dummy_frame_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_push_dummy_frame_ftype) (void); +extern void gdbarch_deprecated_push_dummy_frame (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_push_dummy_frame (struct gdbarch *gdbarch, gdbarch_deprecated_push_dummy_frame_ftype *deprecated_push_dummy_frame); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PUSH_DUMMY_FRAME) +#error "Non multi-arch definition of DEPRECATED_PUSH_DUMMY_FRAME" +#endif +#if !defined (DEPRECATED_PUSH_DUMMY_FRAME) +#define DEPRECATED_PUSH_DUMMY_FRAME (gdbarch_deprecated_push_dummy_frame (current_gdbarch)) +#endif + +#if defined (DEPRECATED_DO_REGISTERS_INFO) +/* Legacy for systems yet to multi-arch DEPRECATED_DO_REGISTERS_INFO */ +#if !defined (DEPRECATED_DO_REGISTERS_INFO_P) +#define DEPRECATED_DO_REGISTERS_INFO_P() (1) +#endif +#endif + +extern int gdbarch_deprecated_do_registers_info_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_DO_REGISTERS_INFO_P) +#error "Non multi-arch definition of DEPRECATED_DO_REGISTERS_INFO" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_DO_REGISTERS_INFO_P) +#define DEPRECATED_DO_REGISTERS_INFO_P() (gdbarch_deprecated_do_registers_info_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_do_registers_info_ftype) (int reg_nr, int fpregs); +extern void gdbarch_deprecated_do_registers_info (struct gdbarch *gdbarch, int reg_nr, int fpregs); +extern void set_gdbarch_deprecated_do_registers_info (struct gdbarch *gdbarch, gdbarch_deprecated_do_registers_info_ftype *deprecated_do_registers_info); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_DO_REGISTERS_INFO) +#error "Non multi-arch definition of DEPRECATED_DO_REGISTERS_INFO" +#endif +#if !defined (DEPRECATED_DO_REGISTERS_INFO) +#define DEPRECATED_DO_REGISTERS_INFO(reg_nr, fpregs) (gdbarch_deprecated_do_registers_info (current_gdbarch, reg_nr, fpregs)) +#endif + +typedef void (gdbarch_print_registers_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all); +extern void gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all); +extern void set_gdbarch_print_registers_info (struct gdbarch *gdbarch, gdbarch_print_registers_info_ftype *print_registers_info); + +extern int gdbarch_print_float_info_p (struct gdbarch *gdbarch); + +typedef void (gdbarch_print_float_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args); +extern void gdbarch_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args); extern void set_gdbarch_print_float_info (struct gdbarch *gdbarch, gdbarch_print_float_info_ftype *print_float_info); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PRINT_FLOAT_INFO) -#error "Non multi-arch definition of PRINT_FLOAT_INFO" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PRINT_FLOAT_INFO) -#define PRINT_FLOAT_INFO() (gdbarch_print_float_info (current_gdbarch)) -#endif -#endif + +extern int gdbarch_print_vector_info_p (struct gdbarch *gdbarch); + +typedef void (gdbarch_print_vector_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args); +extern void gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args); +extern void set_gdbarch_print_vector_info (struct gdbarch *gdbarch, gdbarch_print_vector_info_ftype *print_vector_info); /* MAP a GDB RAW register number onto a simulator register number. See also include/...-sim.h. */ -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REGISTER_SIM_REGNO) -#define REGISTER_SIM_REGNO(reg_nr) (default_register_sim_regno (reg_nr)) -#endif - typedef int (gdbarch_register_sim_regno_ftype) (int reg_nr); extern int gdbarch_register_sim_regno (struct gdbarch *gdbarch, int reg_nr); extern void set_gdbarch_register_sim_regno (struct gdbarch *gdbarch, gdbarch_register_sim_regno_ftype *register_sim_regno); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_SIM_REGNO) #error "Non multi-arch definition of REGISTER_SIM_REGNO" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_SIM_REGNO) +#if !defined (REGISTER_SIM_REGNO) #define REGISTER_SIM_REGNO(reg_nr) (gdbarch_register_sim_regno (current_gdbarch, reg_nr)) #endif -#endif #if defined (REGISTER_BYTES_OK) /* Legacy for systems yet to multi-arch REGISTER_BYTES_OK */ @@ -819,11 +1017,6 @@ extern void set_gdbarch_register_sim_regno (struct gdbarch *gdbarch, gdbarch_reg #endif #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (REGISTER_BYTES_OK_P) -#define REGISTER_BYTES_OK_P() (0) -#endif - extern int gdbarch_register_bytes_ok_p (struct gdbarch *gdbarch); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTES_OK_P) #error "Non multi-arch definition of REGISTER_BYTES_OK" @@ -832,27 +1025,15 @@ extern int gdbarch_register_bytes_ok_p (struct gdbarch *gdbarch); #define REGISTER_BYTES_OK_P() (gdbarch_register_bytes_ok_p (current_gdbarch)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REGISTER_BYTES_OK) -#define REGISTER_BYTES_OK(nr_bytes) (internal_error (__FILE__, __LINE__, "REGISTER_BYTES_OK"), 0) -#endif - typedef int (gdbarch_register_bytes_ok_ftype) (long nr_bytes); extern int gdbarch_register_bytes_ok (struct gdbarch *gdbarch, long nr_bytes); extern void set_gdbarch_register_bytes_ok (struct gdbarch *gdbarch, gdbarch_register_bytes_ok_ftype *register_bytes_ok); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTES_OK) #error "Non multi-arch definition of REGISTER_BYTES_OK" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_BYTES_OK) +#if !defined (REGISTER_BYTES_OK) #define REGISTER_BYTES_OK(nr_bytes) (gdbarch_register_bytes_ok (current_gdbarch, nr_bytes)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (CANNOT_FETCH_REGISTER) -#define CANNOT_FETCH_REGISTER(regnum) (cannot_register_not (regnum)) -#endif typedef int (gdbarch_cannot_fetch_register_ftype) (int regnum); extern int gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, int regnum); @@ -860,16 +1041,9 @@ extern void set_gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, gdbarch_ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CANNOT_FETCH_REGISTER) #error "Non multi-arch definition of CANNOT_FETCH_REGISTER" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CANNOT_FETCH_REGISTER) +#if !defined (CANNOT_FETCH_REGISTER) #define CANNOT_FETCH_REGISTER(regnum) (gdbarch_cannot_fetch_register (current_gdbarch, regnum)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (CANNOT_STORE_REGISTER) -#define CANNOT_STORE_REGISTER(regnum) (cannot_register_not (regnum)) -#endif typedef int (gdbarch_cannot_store_register_ftype) (int regnum); extern int gdbarch_cannot_store_register (struct gdbarch *gdbarch, int regnum); @@ -877,11 +1051,9 @@ extern void set_gdbarch_cannot_store_register (struct gdbarch *gdbarch, gdbarch_ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CANNOT_STORE_REGISTER) #error "Non multi-arch definition of CANNOT_STORE_REGISTER" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CANNOT_STORE_REGISTER) +#if !defined (CANNOT_STORE_REGISTER) #define CANNOT_STORE_REGISTER(regnum) (gdbarch_cannot_store_register (current_gdbarch, regnum)) #endif -#endif /* setjmp/longjmp support. */ @@ -892,11 +1064,6 @@ extern void set_gdbarch_cannot_store_register (struct gdbarch *gdbarch, gdbarch_ #endif #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (GET_LONGJMP_TARGET_P) -#define GET_LONGJMP_TARGET_P() (0) -#endif - extern int gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_LONGJMP_TARGET_P) #error "Non multi-arch definition of GET_LONGJMP_TARGET" @@ -905,230 +1072,95 @@ extern int gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch); #define GET_LONGJMP_TARGET_P() (gdbarch_get_longjmp_target_p (current_gdbarch)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (GET_LONGJMP_TARGET) -#define GET_LONGJMP_TARGET(pc) (internal_error (__FILE__, __LINE__, "GET_LONGJMP_TARGET"), 0) -#endif - typedef int (gdbarch_get_longjmp_target_ftype) (CORE_ADDR *pc); extern int gdbarch_get_longjmp_target (struct gdbarch *gdbarch, CORE_ADDR *pc); extern void set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch, gdbarch_get_longjmp_target_ftype *get_longjmp_target); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_LONGJMP_TARGET) #error "Non multi-arch definition of GET_LONGJMP_TARGET" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (GET_LONGJMP_TARGET) +#if !defined (GET_LONGJMP_TARGET) #define GET_LONGJMP_TARGET(pc) (gdbarch_get_longjmp_target (current_gdbarch, pc)) #endif -#endif -/* Non multi-arch DUMMY_FRAMES are a mess (multi-arch ones are not that - much better but at least they are vaguely consistent). The headers - and body contain convoluted #if/#else sequences for determine how - things should be compiled. Instead of trying to mimic that - behaviour here (and hence entrench it further) gdbarch simply - reqires that these methods be set up from the word go. This also - avoids any potential problems with moving beyond multi-arch partial. */ +/* NOTE: cagney/2002-11-24: This function with predicate has a valid + (callable) initial value. As a consequence, even when the predicate + is false, the corresponding function works. This simplifies the + migration process - old code, calling DEPRECATED_PC_IN_CALL_DUMMY(), + doesn't need to be modified. */ -extern int gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch); -extern void set_gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch, int use_generic_dummy_frames); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (USE_GENERIC_DUMMY_FRAMES) -#error "Non multi-arch definition of USE_GENERIC_DUMMY_FRAMES" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (USE_GENERIC_DUMMY_FRAMES) -#define USE_GENERIC_DUMMY_FRAMES (gdbarch_use_generic_dummy_frames (current_gdbarch)) +#if defined (DEPRECATED_PC_IN_CALL_DUMMY) +/* Legacy for systems yet to multi-arch DEPRECATED_PC_IN_CALL_DUMMY */ +#if !defined (DEPRECATED_PC_IN_CALL_DUMMY_P) +#define DEPRECATED_PC_IN_CALL_DUMMY_P() (1) #endif #endif -extern int gdbarch_call_dummy_location (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_location (struct gdbarch *gdbarch, int call_dummy_location); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_LOCATION) -#error "Non multi-arch definition of CALL_DUMMY_LOCATION" +extern int gdbarch_deprecated_pc_in_call_dummy_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PC_IN_CALL_DUMMY_P) +#error "Non multi-arch definition of DEPRECATED_PC_IN_CALL_DUMMY" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_LOCATION) -#define CALL_DUMMY_LOCATION (gdbarch_call_dummy_location (current_gdbarch)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PC_IN_CALL_DUMMY_P) +#define DEPRECATED_PC_IN_CALL_DUMMY_P() (gdbarch_deprecated_pc_in_call_dummy_p (current_gdbarch)) +#endif + +typedef int (gdbarch_deprecated_pc_in_call_dummy_ftype) (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address); +extern int gdbarch_deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address); +extern void set_gdbarch_deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, gdbarch_deprecated_pc_in_call_dummy_ftype *deprecated_pc_in_call_dummy); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PC_IN_CALL_DUMMY) +#error "Non multi-arch definition of DEPRECATED_PC_IN_CALL_DUMMY" +#endif +#if !defined (DEPRECATED_PC_IN_CALL_DUMMY) +#define DEPRECATED_PC_IN_CALL_DUMMY(pc, sp, frame_address) (gdbarch_deprecated_pc_in_call_dummy (current_gdbarch, pc, sp, frame_address)) +#endif + +#if defined (DEPRECATED_INIT_FRAME_PC_FIRST) +/* Legacy for systems yet to multi-arch DEPRECATED_INIT_FRAME_PC_FIRST */ +#if !defined (DEPRECATED_INIT_FRAME_PC_FIRST_P) +#define DEPRECATED_INIT_FRAME_PC_FIRST_P() (1) #endif #endif -typedef CORE_ADDR (gdbarch_call_dummy_address_ftype) (void); -extern CORE_ADDR gdbarch_call_dummy_address (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_address (struct gdbarch *gdbarch, gdbarch_call_dummy_address_ftype *call_dummy_address); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_ADDRESS) -#error "Non multi-arch definition of CALL_DUMMY_ADDRESS" +extern int gdbarch_deprecated_init_frame_pc_first_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_INIT_FRAME_PC_FIRST_P) +#error "Non multi-arch definition of DEPRECATED_INIT_FRAME_PC_FIRST" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_ADDRESS) -#define CALL_DUMMY_ADDRESS() (gdbarch_call_dummy_address (current_gdbarch)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_INIT_FRAME_PC_FIRST_P) +#define DEPRECATED_INIT_FRAME_PC_FIRST_P() (gdbarch_deprecated_init_frame_pc_first_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_deprecated_init_frame_pc_first_ftype) (int fromleaf, struct frame_info *prev); +extern CORE_ADDR gdbarch_deprecated_init_frame_pc_first (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev); +extern void set_gdbarch_deprecated_init_frame_pc_first (struct gdbarch *gdbarch, gdbarch_deprecated_init_frame_pc_first_ftype *deprecated_init_frame_pc_first); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_INIT_FRAME_PC_FIRST) +#error "Non multi-arch definition of DEPRECATED_INIT_FRAME_PC_FIRST" +#endif +#if !defined (DEPRECATED_INIT_FRAME_PC_FIRST) +#define DEPRECATED_INIT_FRAME_PC_FIRST(fromleaf, prev) (gdbarch_deprecated_init_frame_pc_first (current_gdbarch, fromleaf, prev)) +#endif + +#if defined (DEPRECATED_INIT_FRAME_PC) +/* Legacy for systems yet to multi-arch DEPRECATED_INIT_FRAME_PC */ +#if !defined (DEPRECATED_INIT_FRAME_PC_P) +#define DEPRECATED_INIT_FRAME_PC_P() (1) #endif #endif -extern CORE_ADDR gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch, CORE_ADDR call_dummy_start_offset); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_START_OFFSET) -#error "Non multi-arch definition of CALL_DUMMY_START_OFFSET" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_START_OFFSET) -#define CALL_DUMMY_START_OFFSET (gdbarch_call_dummy_start_offset (current_gdbarch)) +extern int gdbarch_deprecated_init_frame_pc_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_INIT_FRAME_PC_P) +#error "Non multi-arch definition of DEPRECATED_INIT_FRAME_PC" #endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_INIT_FRAME_PC_P) +#define DEPRECATED_INIT_FRAME_PC_P() (gdbarch_deprecated_init_frame_pc_p (current_gdbarch)) #endif -extern CORE_ADDR gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch, CORE_ADDR call_dummy_breakpoint_offset); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_BREAKPOINT_OFFSET) -#error "Non multi-arch definition of CALL_DUMMY_BREAKPOINT_OFFSET" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_BREAKPOINT_OFFSET) -#define CALL_DUMMY_BREAKPOINT_OFFSET (gdbarch_call_dummy_breakpoint_offset (current_gdbarch)) -#endif -#endif - -extern int gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch, int call_dummy_breakpoint_offset_p); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_BREAKPOINT_OFFSET_P) -#error "Non multi-arch definition of CALL_DUMMY_BREAKPOINT_OFFSET_P" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_BREAKPOINT_OFFSET_P) -#define CALL_DUMMY_BREAKPOINT_OFFSET_P (gdbarch_call_dummy_breakpoint_offset_p (current_gdbarch)) -#endif -#endif - -extern int gdbarch_call_dummy_length (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_length (struct gdbarch *gdbarch, int call_dummy_length); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_LENGTH) -#error "Non multi-arch definition of CALL_DUMMY_LENGTH" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_LENGTH) -#define CALL_DUMMY_LENGTH (gdbarch_call_dummy_length (current_gdbarch)) -#endif -#endif - -typedef int (gdbarch_pc_in_call_dummy_ftype) (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address); -extern int gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address); -extern void set_gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch, gdbarch_pc_in_call_dummy_ftype *pc_in_call_dummy); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (PC_IN_CALL_DUMMY) -#error "Non multi-arch definition of PC_IN_CALL_DUMMY" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (PC_IN_CALL_DUMMY) -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) (gdbarch_pc_in_call_dummy (current_gdbarch, pc, sp, frame_address)) -#endif -#endif - -extern int gdbarch_call_dummy_p (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_p (struct gdbarch *gdbarch, int call_dummy_p); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_P) -#error "Non multi-arch definition of CALL_DUMMY_P" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_P) -#define CALL_DUMMY_P (gdbarch_call_dummy_p (current_gdbarch)) -#endif -#endif - -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (CALL_DUMMY_WORDS) -#define CALL_DUMMY_WORDS (legacy_call_dummy_words) -#endif - -extern LONGEST * gdbarch_call_dummy_words (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_words (struct gdbarch *gdbarch, LONGEST * call_dummy_words); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_WORDS) -#error "Non multi-arch definition of CALL_DUMMY_WORDS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_WORDS) -#define CALL_DUMMY_WORDS (gdbarch_call_dummy_words (current_gdbarch)) -#endif -#endif - -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (SIZEOF_CALL_DUMMY_WORDS) -#define SIZEOF_CALL_DUMMY_WORDS (legacy_sizeof_call_dummy_words) -#endif - -extern int gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch); -extern void set_gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch, int sizeof_call_dummy_words); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIZEOF_CALL_DUMMY_WORDS) -#error "Non multi-arch definition of SIZEOF_CALL_DUMMY_WORDS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SIZEOF_CALL_DUMMY_WORDS) -#define SIZEOF_CALL_DUMMY_WORDS (gdbarch_sizeof_call_dummy_words (current_gdbarch)) -#endif -#endif - -extern int gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch, int call_dummy_stack_adjust_p); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_STACK_ADJUST_P) -#error "Non multi-arch definition of CALL_DUMMY_STACK_ADJUST_P" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_STACK_ADJUST_P) -#define CALL_DUMMY_STACK_ADJUST_P (gdbarch_call_dummy_stack_adjust_p (current_gdbarch)) -#endif -#endif - -extern int gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch); -extern void set_gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch, int call_dummy_stack_adjust); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_STACK_ADJUST) -#error "Non multi-arch definition of CALL_DUMMY_STACK_ADJUST" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_STACK_ADJUST) -#define CALL_DUMMY_STACK_ADJUST (gdbarch_call_dummy_stack_adjust (current_gdbarch)) -#endif -#endif - -typedef void (gdbarch_fix_call_dummy_ftype) (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p); -extern void gdbarch_fix_call_dummy (struct gdbarch *gdbarch, char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p); -extern void set_gdbarch_fix_call_dummy (struct gdbarch *gdbarch, gdbarch_fix_call_dummy_ftype *fix_call_dummy); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FIX_CALL_DUMMY) -#error "Non multi-arch definition of FIX_CALL_DUMMY" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FIX_CALL_DUMMY) -#define FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, type, gcc_p) (gdbarch_fix_call_dummy (current_gdbarch, dummy, pc, fun, nargs, args, type, gcc_p)) -#endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (INIT_FRAME_PC_FIRST) -#define INIT_FRAME_PC_FIRST(fromleaf, prev) (init_frame_pc_noop (fromleaf, prev)) -#endif - -typedef void (gdbarch_init_frame_pc_first_ftype) (int fromleaf, struct frame_info *prev); -extern void gdbarch_init_frame_pc_first (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev); -extern void set_gdbarch_init_frame_pc_first (struct gdbarch *gdbarch, gdbarch_init_frame_pc_first_ftype *init_frame_pc_first); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_FRAME_PC_FIRST) -#error "Non multi-arch definition of INIT_FRAME_PC_FIRST" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_FRAME_PC_FIRST) -#define INIT_FRAME_PC_FIRST(fromleaf, prev) (gdbarch_init_frame_pc_first (current_gdbarch, fromleaf, prev)) -#endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (INIT_FRAME_PC) -#define INIT_FRAME_PC(fromleaf, prev) (init_frame_pc_default (fromleaf, prev)) -#endif - -typedef void (gdbarch_init_frame_pc_ftype) (int fromleaf, struct frame_info *prev); -extern void gdbarch_init_frame_pc (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev); -extern void set_gdbarch_init_frame_pc (struct gdbarch *gdbarch, gdbarch_init_frame_pc_ftype *init_frame_pc); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_FRAME_PC) -#error "Non multi-arch definition of INIT_FRAME_PC" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_FRAME_PC) -#define INIT_FRAME_PC(fromleaf, prev) (gdbarch_init_frame_pc (current_gdbarch, fromleaf, prev)) +typedef CORE_ADDR (gdbarch_deprecated_init_frame_pc_ftype) (int fromleaf, struct frame_info *prev); +extern CORE_ADDR gdbarch_deprecated_init_frame_pc (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev); +extern void set_gdbarch_deprecated_init_frame_pc (struct gdbarch *gdbarch, gdbarch_deprecated_init_frame_pc_ftype *deprecated_init_frame_pc); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_INIT_FRAME_PC) +#error "Non multi-arch definition of DEPRECATED_INIT_FRAME_PC" #endif +#if !defined (DEPRECATED_INIT_FRAME_PC) +#define DEPRECATED_INIT_FRAME_PC(fromleaf, prev) (gdbarch_deprecated_init_frame_pc (current_gdbarch, fromleaf, prev)) #endif extern int gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch); @@ -1136,210 +1168,137 @@ extern void set_gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch, int beli #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (BELIEVE_PCC_PROMOTION) #error "Non multi-arch definition of BELIEVE_PCC_PROMOTION" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (BELIEVE_PCC_PROMOTION) +#if !defined (BELIEVE_PCC_PROMOTION) #define BELIEVE_PCC_PROMOTION (gdbarch_believe_pcc_promotion (current_gdbarch)) #endif -#endif extern int gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch); extern void set_gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch, int believe_pcc_promotion_type); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (BELIEVE_PCC_PROMOTION_TYPE) #error "Non multi-arch definition of BELIEVE_PCC_PROMOTION_TYPE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (BELIEVE_PCC_PROMOTION_TYPE) +#if !defined (BELIEVE_PCC_PROMOTION_TYPE) #define BELIEVE_PCC_PROMOTION_TYPE (gdbarch_believe_pcc_promotion_type (current_gdbarch)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (COERCE_FLOAT_TO_DOUBLE) -#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (default_coerce_float_to_double (formal, actual)) -#endif - -typedef int (gdbarch_coerce_float_to_double_ftype) (struct type *formal, struct type *actual); -extern int gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, struct type *formal, struct type *actual); -extern void set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, gdbarch_coerce_float_to_double_ftype *coerce_float_to_double); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (COERCE_FLOAT_TO_DOUBLE) -#error "Non multi-arch definition of COERCE_FLOAT_TO_DOUBLE" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (COERCE_FLOAT_TO_DOUBLE) -#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (gdbarch_coerce_float_to_double (current_gdbarch, formal, actual)) +#if defined (DEPRECATED_GET_SAVED_REGISTER) +/* Legacy for systems yet to multi-arch DEPRECATED_GET_SAVED_REGISTER */ +#if !defined (DEPRECATED_GET_SAVED_REGISTER_P) +#define DEPRECATED_GET_SAVED_REGISTER_P() (1) #endif #endif -/* GET_SAVED_REGISTER is like DUMMY_FRAMES. It is at level one as the - old code has strange #ifdef interaction. So far no one has found - that default_get_saved_register() is the default they are after. */ - -typedef void (gdbarch_get_saved_register_ftype) (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval); -extern void gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval); -extern void set_gdbarch_get_saved_register (struct gdbarch *gdbarch, gdbarch_get_saved_register_ftype *get_saved_register); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (GET_SAVED_REGISTER) -#error "Non multi-arch definition of GET_SAVED_REGISTER" +extern int gdbarch_deprecated_get_saved_register_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_GET_SAVED_REGISTER_P) +#error "Non multi-arch definition of DEPRECATED_GET_SAVED_REGISTER" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (GET_SAVED_REGISTER) -#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) (gdbarch_get_saved_register (current_gdbarch, raw_buffer, optimized, addrp, frame, regnum, lval)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_GET_SAVED_REGISTER_P) +#define DEPRECATED_GET_SAVED_REGISTER_P() (gdbarch_deprecated_get_saved_register_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_get_saved_register_ftype) (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval); +extern void gdbarch_deprecated_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval); +extern void set_gdbarch_deprecated_get_saved_register (struct gdbarch *gdbarch, gdbarch_deprecated_get_saved_register_ftype *deprecated_get_saved_register); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_GET_SAVED_REGISTER) +#error "Non multi-arch definition of DEPRECATED_GET_SAVED_REGISTER" +#endif +#if !defined (DEPRECATED_GET_SAVED_REGISTER) +#define DEPRECATED_GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) (gdbarch_deprecated_get_saved_register (current_gdbarch, raw_buffer, optimized, addrp, frame, regnum, lval)) +#endif + +/* For register <-> value conversions, replaced by CONVERT_REGISTER_P et.al. + For raw <-> cooked register conversions, replaced by pseudo registers. */ + +#if defined (DEPRECATED_REGISTER_CONVERTIBLE) +/* Legacy for systems yet to multi-arch DEPRECATED_REGISTER_CONVERTIBLE */ +#if !defined (DEPRECATED_REGISTER_CONVERTIBLE_P) +#define DEPRECATED_REGISTER_CONVERTIBLE_P() (1) #endif #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REGISTER_CONVERTIBLE) -#define REGISTER_CONVERTIBLE(nr) (generic_register_convertible_not (nr)) +extern int gdbarch_deprecated_register_convertible_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_CONVERTIBLE_P) +#error "Non multi-arch definition of DEPRECATED_REGISTER_CONVERTIBLE" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_REGISTER_CONVERTIBLE_P) +#define DEPRECATED_REGISTER_CONVERTIBLE_P() (gdbarch_deprecated_register_convertible_p (current_gdbarch)) #endif -typedef int (gdbarch_register_convertible_ftype) (int nr); -extern int gdbarch_register_convertible (struct gdbarch *gdbarch, int nr); -extern void set_gdbarch_register_convertible (struct gdbarch *gdbarch, gdbarch_register_convertible_ftype *register_convertible); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_CONVERTIBLE) -#error "Non multi-arch definition of REGISTER_CONVERTIBLE" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_CONVERTIBLE) -#define REGISTER_CONVERTIBLE(nr) (gdbarch_register_convertible (current_gdbarch, nr)) +typedef int (gdbarch_deprecated_register_convertible_ftype) (int nr); +extern int gdbarch_deprecated_register_convertible (struct gdbarch *gdbarch, int nr); +extern void set_gdbarch_deprecated_register_convertible (struct gdbarch *gdbarch, gdbarch_deprecated_register_convertible_ftype *deprecated_register_convertible); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_CONVERTIBLE) +#error "Non multi-arch definition of DEPRECATED_REGISTER_CONVERTIBLE" #endif +#if !defined (DEPRECATED_REGISTER_CONVERTIBLE) +#define DEPRECATED_REGISTER_CONVERTIBLE(nr) (gdbarch_deprecated_register_convertible (current_gdbarch, nr)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REGISTER_CONVERT_TO_VIRTUAL) -#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) (internal_error (__FILE__, __LINE__, "REGISTER_CONVERT_TO_VIRTUAL"), 0) +/* For register <-> value conversions, replaced by CONVERT_REGISTER_P et.al. + For raw <-> cooked register conversions, replaced by pseudo registers. */ + +typedef void (gdbarch_deprecated_register_convert_to_virtual_ftype) (int regnum, struct type *type, char *from, char *to); +extern void gdbarch_deprecated_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to); +extern void set_gdbarch_deprecated_register_convert_to_virtual (struct gdbarch *gdbarch, gdbarch_deprecated_register_convert_to_virtual_ftype *deprecated_register_convert_to_virtual); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL) +#error "Non multi-arch definition of DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL" +#endif +#if !defined (DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL) +#define DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) (gdbarch_deprecated_register_convert_to_virtual (current_gdbarch, regnum, type, from, to)) #endif -typedef void (gdbarch_register_convert_to_virtual_ftype) (int regnum, struct type *type, char *from, char *to); -extern void gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to); -extern void set_gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch, gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_CONVERT_TO_VIRTUAL) -#error "Non multi-arch definition of REGISTER_CONVERT_TO_VIRTUAL" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_CONVERT_TO_VIRTUAL) -#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) (gdbarch_register_convert_to_virtual (current_gdbarch, regnum, type, from, to)) +/* For register <-> value conversions, replaced by CONVERT_REGISTER_P et.al. + For raw <-> cooked register conversions, replaced by pseudo registers. */ + +typedef void (gdbarch_deprecated_register_convert_to_raw_ftype) (struct type *type, int regnum, const char *from, char *to); +extern void gdbarch_deprecated_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type, int regnum, const char *from, char *to); +extern void set_gdbarch_deprecated_register_convert_to_raw (struct gdbarch *gdbarch, gdbarch_deprecated_register_convert_to_raw_ftype *deprecated_register_convert_to_raw); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REGISTER_CONVERT_TO_RAW) +#error "Non multi-arch definition of DEPRECATED_REGISTER_CONVERT_TO_RAW" #endif +#if !defined (DEPRECATED_REGISTER_CONVERT_TO_RAW) +#define DEPRECATED_REGISTER_CONVERT_TO_RAW(type, regnum, from, to) (gdbarch_deprecated_register_convert_to_raw (current_gdbarch, type, regnum, from, to)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REGISTER_CONVERT_TO_RAW) -#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) (internal_error (__FILE__, __LINE__, "REGISTER_CONVERT_TO_RAW"), 0) +typedef int (gdbarch_convert_register_p_ftype) (int regnum, struct type *type); +extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type); +extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p); +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CONVERT_REGISTER_P) +#error "Non multi-arch definition of CONVERT_REGISTER_P" +#endif +#if !defined (CONVERT_REGISTER_P) +#define CONVERT_REGISTER_P(regnum, type) (gdbarch_convert_register_p (current_gdbarch, regnum, type)) #endif -typedef void (gdbarch_register_convert_to_raw_ftype) (struct type *type, int regnum, char *from, char *to); -extern void gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to); -extern void set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, gdbarch_register_convert_to_raw_ftype *register_convert_to_raw); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_CONVERT_TO_RAW) -#error "Non multi-arch definition of REGISTER_CONVERT_TO_RAW" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_CONVERT_TO_RAW) -#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) (gdbarch_register_convert_to_raw (current_gdbarch, type, regnum, from, to)) +typedef void (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, void *buf); +extern void gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf); +extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value); +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_TO_VALUE) +#error "Non multi-arch definition of REGISTER_TO_VALUE" #endif +#if !defined (REGISTER_TO_VALUE) +#define REGISTER_TO_VALUE(frame, regnum, type, buf) (gdbarch_register_to_value (current_gdbarch, frame, regnum, type, buf)) #endif -/* This function is called when the value of a pseudo-register needs to - be updated. Typically it will be defined on a per-architecture - basis. */ - -#if defined (FETCH_PSEUDO_REGISTER) -/* Legacy for systems yet to multi-arch FETCH_PSEUDO_REGISTER */ -#if !defined (FETCH_PSEUDO_REGISTER_P) -#define FETCH_PSEUDO_REGISTER_P() (1) +typedef void (gdbarch_value_to_register_ftype) (struct frame_info *frame, int regnum, struct type *type, const void *buf); +extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const void *buf); +extern void set_gdbarch_value_to_register (struct gdbarch *gdbarch, gdbarch_value_to_register_ftype *value_to_register); +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (VALUE_TO_REGISTER) +#error "Non multi-arch definition of VALUE_TO_REGISTER" #endif +#if !defined (VALUE_TO_REGISTER) +#define VALUE_TO_REGISTER(frame, regnum, type, buf) (gdbarch_value_to_register (current_gdbarch, frame, regnum, type, buf)) #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (FETCH_PSEUDO_REGISTER_P) -#define FETCH_PSEUDO_REGISTER_P() (0) -#endif - -extern int gdbarch_fetch_pseudo_register_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FETCH_PSEUDO_REGISTER_P) -#error "Non multi-arch definition of FETCH_PSEUDO_REGISTER" -#endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FETCH_PSEUDO_REGISTER_P) -#define FETCH_PSEUDO_REGISTER_P() (gdbarch_fetch_pseudo_register_p (current_gdbarch)) -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (FETCH_PSEUDO_REGISTER) -#define FETCH_PSEUDO_REGISTER(regnum) (internal_error (__FILE__, __LINE__, "FETCH_PSEUDO_REGISTER"), 0) -#endif - -typedef void (gdbarch_fetch_pseudo_register_ftype) (int regnum); -extern void gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch, int regnum); -extern void set_gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch, gdbarch_fetch_pseudo_register_ftype *fetch_pseudo_register); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FETCH_PSEUDO_REGISTER) -#error "Non multi-arch definition of FETCH_PSEUDO_REGISTER" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FETCH_PSEUDO_REGISTER) -#define FETCH_PSEUDO_REGISTER(regnum) (gdbarch_fetch_pseudo_register (current_gdbarch, regnum)) -#endif -#endif - -/* This function is called when the value of a pseudo-register needs to - be set or stored. Typically it will be defined on a - per-architecture basis. */ - -#if defined (STORE_PSEUDO_REGISTER) -/* Legacy for systems yet to multi-arch STORE_PSEUDO_REGISTER */ -#if !defined (STORE_PSEUDO_REGISTER_P) -#define STORE_PSEUDO_REGISTER_P() (1) -#endif -#endif - -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (STORE_PSEUDO_REGISTER_P) -#define STORE_PSEUDO_REGISTER_P() (0) -#endif - -extern int gdbarch_store_pseudo_register_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_PSEUDO_REGISTER_P) -#error "Non multi-arch definition of STORE_PSEUDO_REGISTER" -#endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_PSEUDO_REGISTER_P) -#define STORE_PSEUDO_REGISTER_P() (gdbarch_store_pseudo_register_p (current_gdbarch)) -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (STORE_PSEUDO_REGISTER) -#define STORE_PSEUDO_REGISTER(regnum) (internal_error (__FILE__, __LINE__, "STORE_PSEUDO_REGISTER"), 0) -#endif - -typedef void (gdbarch_store_pseudo_register_ftype) (int regnum); -extern void gdbarch_store_pseudo_register (struct gdbarch *gdbarch, int regnum); -extern void set_gdbarch_store_pseudo_register (struct gdbarch *gdbarch, gdbarch_store_pseudo_register_ftype *store_pseudo_register); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_PSEUDO_REGISTER) -#error "Non multi-arch definition of STORE_PSEUDO_REGISTER" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_PSEUDO_REGISTER) -#define STORE_PSEUDO_REGISTER(regnum) (gdbarch_store_pseudo_register (current_gdbarch, regnum)) -#endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (POINTER_TO_ADDRESS) -#define POINTER_TO_ADDRESS(type, buf) (unsigned_pointer_to_address (type, buf)) -#endif - -typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct type *type, void *buf); -extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf); +typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct type *type, const void *buf); +extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const void *buf); extern void set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, gdbarch_pointer_to_address_ftype *pointer_to_address); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (POINTER_TO_ADDRESS) #error "Non multi-arch definition of POINTER_TO_ADDRESS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (POINTER_TO_ADDRESS) +#if !defined (POINTER_TO_ADDRESS) #define POINTER_TO_ADDRESS(type, buf) (gdbarch_pointer_to_address (current_gdbarch, type, buf)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_TO_POINTER) -#define ADDRESS_TO_POINTER(type, buf, addr) (unsigned_address_to_pointer (type, buf, addr)) -#endif typedef void (gdbarch_address_to_pointer_ftype) (struct type *type, void *buf, CORE_ADDR addr); extern void gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, void *buf, CORE_ADDR addr); @@ -1347,11 +1306,9 @@ extern void set_gdbarch_address_to_pointer (struct gdbarch *gdbarch, gdbarch_add #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_TO_POINTER) #error "Non multi-arch definition of ADDRESS_TO_POINTER" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_TO_POINTER) +#if !defined (ADDRESS_TO_POINTER) #define ADDRESS_TO_POINTER(type, buf, addr) (gdbarch_address_to_pointer (current_gdbarch, type, buf, addr)) #endif -#endif #if defined (INTEGER_TO_ADDRESS) /* Legacy for systems yet to multi-arch INTEGER_TO_ADDRESS */ @@ -1360,11 +1317,6 @@ extern void set_gdbarch_address_to_pointer (struct gdbarch *gdbarch, gdbarch_add #endif #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (INTEGER_TO_ADDRESS_P) -#define INTEGER_TO_ADDRESS_P() (0) -#endif - extern int gdbarch_integer_to_address_p (struct gdbarch *gdbarch); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INTEGER_TO_ADDRESS_P) #error "Non multi-arch definition of INTEGER_TO_ADDRESS" @@ -1373,27 +1325,81 @@ extern int gdbarch_integer_to_address_p (struct gdbarch *gdbarch); #define INTEGER_TO_ADDRESS_P() (gdbarch_integer_to_address_p (current_gdbarch)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (INTEGER_TO_ADDRESS) -#define INTEGER_TO_ADDRESS(type, buf) (internal_error (__FILE__, __LINE__, "INTEGER_TO_ADDRESS"), 0) -#endif - typedef CORE_ADDR (gdbarch_integer_to_address_ftype) (struct type *type, void *buf); extern CORE_ADDR gdbarch_integer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf); extern void set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch_integer_to_address_ftype *integer_to_address); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INTEGER_TO_ADDRESS) #error "Non multi-arch definition of INTEGER_TO_ADDRESS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INTEGER_TO_ADDRESS) +#if !defined (INTEGER_TO_ADDRESS) #define INTEGER_TO_ADDRESS(type, buf) (gdbarch_integer_to_address (current_gdbarch, type, buf)) #endif + +#if defined (DEPRECATED_POP_FRAME) +/* Legacy for systems yet to multi-arch DEPRECATED_POP_FRAME */ +#if !defined (DEPRECATED_POP_FRAME_P) +#define DEPRECATED_POP_FRAME_P() (1) +#endif #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (RETURN_VALUE_ON_STACK) -#define RETURN_VALUE_ON_STACK(type) (generic_return_value_on_stack_not (type)) +extern int gdbarch_deprecated_pop_frame_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_POP_FRAME_P) +#error "Non multi-arch definition of DEPRECATED_POP_FRAME" #endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_POP_FRAME_P) +#define DEPRECATED_POP_FRAME_P() (gdbarch_deprecated_pop_frame_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_pop_frame_ftype) (void); +extern void gdbarch_deprecated_pop_frame (struct gdbarch *gdbarch); +extern void set_gdbarch_deprecated_pop_frame (struct gdbarch *gdbarch, gdbarch_deprecated_pop_frame_ftype *deprecated_pop_frame); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_POP_FRAME) +#error "Non multi-arch definition of DEPRECATED_POP_FRAME" +#endif +#if !defined (DEPRECATED_POP_FRAME) +#define DEPRECATED_POP_FRAME (gdbarch_deprecated_pop_frame (current_gdbarch)) +#endif + +/* NOTE: cagney/2003-03-24: Replaced by PUSH_ARGUMENTS. */ + +#if defined (DEPRECATED_STORE_STRUCT_RETURN) +/* Legacy for systems yet to multi-arch DEPRECATED_STORE_STRUCT_RETURN */ +#if !defined (DEPRECATED_STORE_STRUCT_RETURN_P) +#define DEPRECATED_STORE_STRUCT_RETURN_P() (1) +#endif +#endif + +extern int gdbarch_deprecated_store_struct_return_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_STORE_STRUCT_RETURN_P) +#error "Non multi-arch definition of DEPRECATED_STORE_STRUCT_RETURN" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_STORE_STRUCT_RETURN_P) +#define DEPRECATED_STORE_STRUCT_RETURN_P() (gdbarch_deprecated_store_struct_return_p (current_gdbarch)) +#endif + +typedef void (gdbarch_deprecated_store_struct_return_ftype) (CORE_ADDR addr, CORE_ADDR sp); +extern void gdbarch_deprecated_store_struct_return (struct gdbarch *gdbarch, CORE_ADDR addr, CORE_ADDR sp); +extern void set_gdbarch_deprecated_store_struct_return (struct gdbarch *gdbarch, gdbarch_deprecated_store_struct_return_ftype *deprecated_store_struct_return); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_STORE_STRUCT_RETURN) +#error "Non multi-arch definition of DEPRECATED_STORE_STRUCT_RETURN" +#endif +#if !defined (DEPRECATED_STORE_STRUCT_RETURN) +#define DEPRECATED_STORE_STRUCT_RETURN(addr, sp) (gdbarch_deprecated_store_struct_return (current_gdbarch, addr, sp)) +#endif + +/* It has been suggested that this, well actually its predecessor, + should take the type/value of the function to be called and not the + return type. This is left as an exercise for the reader. */ + +extern int gdbarch_return_value_p (struct gdbarch *gdbarch); + +typedef enum return_value_convention (gdbarch_return_value_ftype) (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf); +extern enum return_value_convention gdbarch_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf); +extern void set_gdbarch_return_value (struct gdbarch *gdbarch, gdbarch_return_value_ftype *return_value); + +/* The deprecated methods RETURN_VALUE_ON_STACK, EXTRACT_RETURN_VALUE, + STORE_RETURN_VALUE and USE_STRUCT_CONVENTION have all been folded + into RETURN_VALUE. */ typedef int (gdbarch_return_value_on_stack_ftype) (struct type *type); extern int gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type); @@ -1401,166 +1407,48 @@ extern void set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch, gdbarch_ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (RETURN_VALUE_ON_STACK) #error "Non multi-arch definition of RETURN_VALUE_ON_STACK" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (RETURN_VALUE_ON_STACK) +#if !defined (RETURN_VALUE_ON_STACK) #define RETURN_VALUE_ON_STACK(type) (gdbarch_return_value_on_stack (current_gdbarch, type)) #endif -#endif -typedef void (gdbarch_extract_return_value_ftype) (struct type *type, char *regbuf, char *valbuf); -extern void gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf); +typedef void (gdbarch_extract_return_value_ftype) (struct type *type, struct regcache *regcache, void *valbuf); +extern void gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, void *valbuf); extern void set_gdbarch_extract_return_value (struct gdbarch *gdbarch, gdbarch_extract_return_value_ftype *extract_return_value); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRACT_RETURN_VALUE) #error "Non multi-arch definition of EXTRACT_RETURN_VALUE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRACT_RETURN_VALUE) -#define EXTRACT_RETURN_VALUE(type, regbuf, valbuf) (gdbarch_extract_return_value (current_gdbarch, type, regbuf, valbuf)) -#endif +#if !defined (EXTRACT_RETURN_VALUE) +#define EXTRACT_RETURN_VALUE(type, regcache, valbuf) (gdbarch_extract_return_value (current_gdbarch, type, regcache, valbuf)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (PUSH_ARGUMENTS) -#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) (default_push_arguments (nargs, args, sp, struct_return, struct_addr)) -#endif - -typedef CORE_ADDR (gdbarch_push_arguments_ftype) (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr); -extern CORE_ADDR gdbarch_push_arguments (struct gdbarch *gdbarch, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr); -extern void set_gdbarch_push_arguments (struct gdbarch *gdbarch, gdbarch_push_arguments_ftype *push_arguments); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_ARGUMENTS) -#error "Non multi-arch definition of PUSH_ARGUMENTS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_ARGUMENTS) -#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) (gdbarch_push_arguments (current_gdbarch, nargs, args, sp, struct_return, struct_addr)) -#endif -#endif - -typedef void (gdbarch_push_dummy_frame_ftype) (void); -extern void gdbarch_push_dummy_frame (struct gdbarch *gdbarch); -extern void set_gdbarch_push_dummy_frame (struct gdbarch *gdbarch, gdbarch_push_dummy_frame_ftype *push_dummy_frame); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_DUMMY_FRAME) -#error "Non multi-arch definition of PUSH_DUMMY_FRAME" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_DUMMY_FRAME) -#define PUSH_DUMMY_FRAME (gdbarch_push_dummy_frame (current_gdbarch)) -#endif -#endif - -#if defined (PUSH_RETURN_ADDRESS) -/* Legacy for systems yet to multi-arch PUSH_RETURN_ADDRESS */ -#if !defined (PUSH_RETURN_ADDRESS_P) -#define PUSH_RETURN_ADDRESS_P() (1) -#endif -#endif - -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (PUSH_RETURN_ADDRESS_P) -#define PUSH_RETURN_ADDRESS_P() (0) -#endif - -extern int gdbarch_push_return_address_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_RETURN_ADDRESS_P) -#error "Non multi-arch definition of PUSH_RETURN_ADDRESS" -#endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_RETURN_ADDRESS_P) -#define PUSH_RETURN_ADDRESS_P() (gdbarch_push_return_address_p (current_gdbarch)) -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (PUSH_RETURN_ADDRESS) -#define PUSH_RETURN_ADDRESS(pc, sp) (internal_error (__FILE__, __LINE__, "PUSH_RETURN_ADDRESS"), 0) -#endif - -typedef CORE_ADDR (gdbarch_push_return_address_ftype) (CORE_ADDR pc, CORE_ADDR sp); -extern CORE_ADDR gdbarch_push_return_address (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp); -extern void set_gdbarch_push_return_address (struct gdbarch *gdbarch, gdbarch_push_return_address_ftype *push_return_address); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_RETURN_ADDRESS) -#error "Non multi-arch definition of PUSH_RETURN_ADDRESS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_RETURN_ADDRESS) -#define PUSH_RETURN_ADDRESS(pc, sp) (gdbarch_push_return_address (current_gdbarch, pc, sp)) -#endif -#endif - -typedef void (gdbarch_pop_frame_ftype) (void); -extern void gdbarch_pop_frame (struct gdbarch *gdbarch); -extern void set_gdbarch_pop_frame (struct gdbarch *gdbarch, gdbarch_pop_frame_ftype *pop_frame); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (POP_FRAME) -#error "Non multi-arch definition of POP_FRAME" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (POP_FRAME) -#define POP_FRAME (gdbarch_pop_frame (current_gdbarch)) -#endif -#endif - -typedef void (gdbarch_store_struct_return_ftype) (CORE_ADDR addr, CORE_ADDR sp); -extern void gdbarch_store_struct_return (struct gdbarch *gdbarch, CORE_ADDR addr, CORE_ADDR sp); -extern void set_gdbarch_store_struct_return (struct gdbarch *gdbarch, gdbarch_store_struct_return_ftype *store_struct_return); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_STRUCT_RETURN) -#error "Non multi-arch definition of STORE_STRUCT_RETURN" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_STRUCT_RETURN) -#define STORE_STRUCT_RETURN(addr, sp) (gdbarch_store_struct_return (current_gdbarch, addr, sp)) -#endif -#endif - -typedef void (gdbarch_store_return_value_ftype) (struct type *type, char *valbuf); -extern void gdbarch_store_return_value (struct gdbarch *gdbarch, struct type *type, char *valbuf); +typedef void (gdbarch_store_return_value_ftype) (struct type *type, struct regcache *regcache, const void *valbuf); +extern void gdbarch_store_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, const void *valbuf); extern void set_gdbarch_store_return_value (struct gdbarch *gdbarch, gdbarch_store_return_value_ftype *store_return_value); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_RETURN_VALUE) #error "Non multi-arch definition of STORE_RETURN_VALUE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_RETURN_VALUE) -#define STORE_RETURN_VALUE(type, valbuf) (gdbarch_store_return_value (current_gdbarch, type, valbuf)) -#endif +#if !defined (STORE_RETURN_VALUE) +#define STORE_RETURN_VALUE(type, regcache, valbuf) (gdbarch_store_return_value (current_gdbarch, type, regcache, valbuf)) #endif -#if defined (EXTRACT_STRUCT_VALUE_ADDRESS) -/* Legacy for systems yet to multi-arch EXTRACT_STRUCT_VALUE_ADDRESS */ -#if !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P) -#define EXTRACT_STRUCT_VALUE_ADDRESS_P() (1) +typedef void (gdbarch_deprecated_extract_return_value_ftype) (struct type *type, char *regbuf, char *valbuf); +extern void gdbarch_deprecated_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf); +extern void set_gdbarch_deprecated_extract_return_value (struct gdbarch *gdbarch, gdbarch_deprecated_extract_return_value_ftype *deprecated_extract_return_value); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_EXTRACT_RETURN_VALUE) +#error "Non multi-arch definition of DEPRECATED_EXTRACT_RETURN_VALUE" #endif +#if !defined (DEPRECATED_EXTRACT_RETURN_VALUE) +#define DEPRECATED_EXTRACT_RETURN_VALUE(type, regbuf, valbuf) (gdbarch_deprecated_extract_return_value (current_gdbarch, type, regbuf, valbuf)) #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P) -#define EXTRACT_STRUCT_VALUE_ADDRESS_P() (0) +typedef void (gdbarch_deprecated_store_return_value_ftype) (struct type *type, char *valbuf); +extern void gdbarch_deprecated_store_return_value (struct gdbarch *gdbarch, struct type *type, char *valbuf); +extern void set_gdbarch_deprecated_store_return_value (struct gdbarch *gdbarch, gdbarch_deprecated_store_return_value_ftype *deprecated_store_return_value); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_STORE_RETURN_VALUE) +#error "Non multi-arch definition of DEPRECATED_STORE_RETURN_VALUE" #endif - -extern int gdbarch_extract_struct_value_address_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRACT_STRUCT_VALUE_ADDRESS_P) -#error "Non multi-arch definition of EXTRACT_STRUCT_VALUE_ADDRESS" -#endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P) -#define EXTRACT_STRUCT_VALUE_ADDRESS_P() (gdbarch_extract_struct_value_address_p (current_gdbarch)) -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (EXTRACT_STRUCT_VALUE_ADDRESS) -#define EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) (internal_error (__FILE__, __LINE__, "EXTRACT_STRUCT_VALUE_ADDRESS"), 0) -#endif - -typedef CORE_ADDR (gdbarch_extract_struct_value_address_ftype) (char *regbuf); -extern CORE_ADDR gdbarch_extract_struct_value_address (struct gdbarch *gdbarch, char *regbuf); -extern void set_gdbarch_extract_struct_value_address (struct gdbarch *gdbarch, gdbarch_extract_struct_value_address_ftype *extract_struct_value_address); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRACT_STRUCT_VALUE_ADDRESS) -#error "Non multi-arch definition of EXTRACT_STRUCT_VALUE_ADDRESS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRACT_STRUCT_VALUE_ADDRESS) -#define EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) (gdbarch_extract_struct_value_address (current_gdbarch, regbuf)) -#endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (USE_STRUCT_CONVENTION) -#define USE_STRUCT_CONVENTION(gcc_p, value_type) (generic_use_struct_convention (gcc_p, value_type)) +#if !defined (DEPRECATED_STORE_RETURN_VALUE) +#define DEPRECATED_STORE_RETURN_VALUE(type, valbuf) (gdbarch_deprecated_store_return_value (current_gdbarch, type, valbuf)) #endif typedef int (gdbarch_use_struct_convention_ftype) (int gcc_p, struct type *value_type); @@ -1569,59 +1457,101 @@ extern void set_gdbarch_use_struct_convention (struct gdbarch *gdbarch, gdbarch_ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (USE_STRUCT_CONVENTION) #error "Non multi-arch definition of USE_STRUCT_CONVENTION" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (USE_STRUCT_CONVENTION) +#if !defined (USE_STRUCT_CONVENTION) #define USE_STRUCT_CONVENTION(gcc_p, value_type) (gdbarch_use_struct_convention (current_gdbarch, gcc_p, value_type)) #endif -#endif -typedef void (gdbarch_frame_init_saved_regs_ftype) (struct frame_info *frame); -extern void gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch, struct frame_info *frame); -extern void set_gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch, gdbarch_frame_init_saved_regs_ftype *frame_init_saved_regs); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_INIT_SAVED_REGS) -#error "Non multi-arch definition of FRAME_INIT_SAVED_REGS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_INIT_SAVED_REGS) -#define FRAME_INIT_SAVED_REGS(frame) (gdbarch_frame_init_saved_regs (current_gdbarch, frame)) +/* As of 2004-01-17 only the 32-bit SPARC ABI has been identified as an + ABI suitable for the implementation of a robust extract + struct-convention return-value address method (the sparc saves the + address in the callers frame). All the other cases so far examined, + the DEPRECATED_EXTRACT_STRUCT_VALUE implementation has been + erreneous - the code was incorrectly assuming that the return-value + address, stored in a register, was preserved across the entire + function call. + For the moment retain DEPRECATED_EXTRACT_STRUCT_VALUE as a marker of + the ABIs that are still to be analyzed - perhaps this should simply + be deleted. The commented out extract_returned_value_address method + is provided as a starting point for the 32-bit SPARC. It, or + something like it, along with changes to both infcmd.c and stack.c + will be needed for that case to work. NB: It is passed the callers + frame since it is only after the callee has returned that this + function is used. + M:::CORE_ADDR:extract_returned_value_address:struct frame_info *caller_frame:caller_frame */ + +#if defined (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS) +/* Legacy for systems yet to multi-arch DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS */ +#if !defined (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P) +#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P() (1) #endif #endif -#if defined (INIT_EXTRA_FRAME_INFO) -/* Legacy for systems yet to multi-arch INIT_EXTRA_FRAME_INFO */ -#if !defined (INIT_EXTRA_FRAME_INFO_P) -#define INIT_EXTRA_FRAME_INFO_P() (1) +extern int gdbarch_deprecated_extract_struct_value_address_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P) +#error "Non multi-arch definition of DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P) +#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P() (gdbarch_deprecated_extract_struct_value_address_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_deprecated_extract_struct_value_address_ftype) (struct regcache *regcache); +extern CORE_ADDR gdbarch_deprecated_extract_struct_value_address (struct gdbarch *gdbarch, struct regcache *regcache); +extern void set_gdbarch_deprecated_extract_struct_value_address (struct gdbarch *gdbarch, gdbarch_deprecated_extract_struct_value_address_ftype *deprecated_extract_struct_value_address); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS) +#error "Non multi-arch definition of DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS" +#endif +#if !defined (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS) +#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(regcache) (gdbarch_deprecated_extract_struct_value_address (current_gdbarch, regcache)) +#endif + +#if defined (DEPRECATED_FRAME_INIT_SAVED_REGS) +/* Legacy for systems yet to multi-arch DEPRECATED_FRAME_INIT_SAVED_REGS */ +#if !defined (DEPRECATED_FRAME_INIT_SAVED_REGS_P) +#define DEPRECATED_FRAME_INIT_SAVED_REGS_P() (1) #endif #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (INIT_EXTRA_FRAME_INFO_P) -#define INIT_EXTRA_FRAME_INFO_P() (0) +extern int gdbarch_deprecated_frame_init_saved_regs_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_INIT_SAVED_REGS_P) +#error "Non multi-arch definition of DEPRECATED_FRAME_INIT_SAVED_REGS" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FRAME_INIT_SAVED_REGS_P) +#define DEPRECATED_FRAME_INIT_SAVED_REGS_P() (gdbarch_deprecated_frame_init_saved_regs_p (current_gdbarch)) #endif -extern int gdbarch_init_extra_frame_info_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_EXTRA_FRAME_INFO_P) -#error "Non multi-arch definition of INIT_EXTRA_FRAME_INFO" +typedef void (gdbarch_deprecated_frame_init_saved_regs_ftype) (struct frame_info *frame); +extern void gdbarch_deprecated_frame_init_saved_regs (struct gdbarch *gdbarch, struct frame_info *frame); +extern void set_gdbarch_deprecated_frame_init_saved_regs (struct gdbarch *gdbarch, gdbarch_deprecated_frame_init_saved_regs_ftype *deprecated_frame_init_saved_regs); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_INIT_SAVED_REGS) +#error "Non multi-arch definition of DEPRECATED_FRAME_INIT_SAVED_REGS" #endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_EXTRA_FRAME_INFO_P) -#define INIT_EXTRA_FRAME_INFO_P() (gdbarch_init_extra_frame_info_p (current_gdbarch)) +#if !defined (DEPRECATED_FRAME_INIT_SAVED_REGS) +#define DEPRECATED_FRAME_INIT_SAVED_REGS(frame) (gdbarch_deprecated_frame_init_saved_regs (current_gdbarch, frame)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (INIT_EXTRA_FRAME_INFO) -#define INIT_EXTRA_FRAME_INFO(fromleaf, frame) (internal_error (__FILE__, __LINE__, "INIT_EXTRA_FRAME_INFO"), 0) +#if defined (DEPRECATED_INIT_EXTRA_FRAME_INFO) +/* Legacy for systems yet to multi-arch DEPRECATED_INIT_EXTRA_FRAME_INFO */ +#if !defined (DEPRECATED_INIT_EXTRA_FRAME_INFO_P) +#define DEPRECATED_INIT_EXTRA_FRAME_INFO_P() (1) +#endif #endif -typedef void (gdbarch_init_extra_frame_info_ftype) (int fromleaf, struct frame_info *frame); -extern void gdbarch_init_extra_frame_info (struct gdbarch *gdbarch, int fromleaf, struct frame_info *frame); -extern void set_gdbarch_init_extra_frame_info (struct gdbarch *gdbarch, gdbarch_init_extra_frame_info_ftype *init_extra_frame_info); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_EXTRA_FRAME_INFO) -#error "Non multi-arch definition of INIT_EXTRA_FRAME_INFO" +extern int gdbarch_deprecated_init_extra_frame_info_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_INIT_EXTRA_FRAME_INFO_P) +#error "Non multi-arch definition of DEPRECATED_INIT_EXTRA_FRAME_INFO" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_EXTRA_FRAME_INFO) -#define INIT_EXTRA_FRAME_INFO(fromleaf, frame) (gdbarch_init_extra_frame_info (current_gdbarch, fromleaf, frame)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_INIT_EXTRA_FRAME_INFO_P) +#define DEPRECATED_INIT_EXTRA_FRAME_INFO_P() (gdbarch_deprecated_init_extra_frame_info_p (current_gdbarch)) #endif + +typedef void (gdbarch_deprecated_init_extra_frame_info_ftype) (int fromleaf, struct frame_info *frame); +extern void gdbarch_deprecated_init_extra_frame_info (struct gdbarch *gdbarch, int fromleaf, struct frame_info *frame); +extern void set_gdbarch_deprecated_init_extra_frame_info (struct gdbarch *gdbarch, gdbarch_deprecated_init_extra_frame_info_ftype *deprecated_init_extra_frame_info); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_INIT_EXTRA_FRAME_INFO) +#error "Non multi-arch definition of DEPRECATED_INIT_EXTRA_FRAME_INFO" +#endif +#if !defined (DEPRECATED_INIT_EXTRA_FRAME_INFO) +#define DEPRECATED_INIT_EXTRA_FRAME_INFO(fromleaf, frame) (gdbarch_deprecated_init_extra_frame_info (current_gdbarch, fromleaf, frame)) #endif typedef CORE_ADDR (gdbarch_skip_prologue_ftype) (CORE_ADDR ip); @@ -1630,28 +1560,9 @@ extern void set_gdbarch_skip_prologue (struct gdbarch *gdbarch, gdbarch_skip_pro #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SKIP_PROLOGUE) #error "Non multi-arch definition of SKIP_PROLOGUE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SKIP_PROLOGUE) +#if !defined (SKIP_PROLOGUE) #define SKIP_PROLOGUE(ip) (gdbarch_skip_prologue (current_gdbarch, ip)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (PROLOGUE_FRAMELESS_P) -#define PROLOGUE_FRAMELESS_P(ip) (generic_prologue_frameless_p (ip)) -#endif - -typedef int (gdbarch_prologue_frameless_p_ftype) (CORE_ADDR ip); -extern int gdbarch_prologue_frameless_p (struct gdbarch *gdbarch, CORE_ADDR ip); -extern void set_gdbarch_prologue_frameless_p (struct gdbarch *gdbarch, gdbarch_prologue_frameless_p_ftype *prologue_frameless_p); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PROLOGUE_FRAMELESS_P) -#error "Non multi-arch definition of PROLOGUE_FRAMELESS_P" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PROLOGUE_FRAMELESS_P) -#define PROLOGUE_FRAMELESS_P(ip) (gdbarch_prologue_frameless_p (current_gdbarch, ip)) -#endif -#endif typedef int (gdbarch_inner_than_ftype) (CORE_ADDR lhs, CORE_ADDR rhs); extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs); @@ -1659,33 +1570,25 @@ extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INNER_THAN) #error "Non multi-arch definition of INNER_THAN" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INNER_THAN) +#if !defined (INNER_THAN) #define INNER_THAN(lhs, rhs) (gdbarch_inner_than (current_gdbarch, lhs, rhs)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (BREAKPOINT_FROM_PC) -#define BREAKPOINT_FROM_PC(pcptr, lenptr) (legacy_breakpoint_from_pc (pcptr, lenptr)) -#endif - -typedef unsigned char * (gdbarch_breakpoint_from_pc_ftype) (CORE_ADDR *pcptr, int *lenptr); -extern unsigned char * gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr); +typedef const unsigned char * (gdbarch_breakpoint_from_pc_ftype) (CORE_ADDR *pcptr, int *lenptr); +extern const unsigned char * gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr); extern void set_gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (BREAKPOINT_FROM_PC) #error "Non multi-arch definition of BREAKPOINT_FROM_PC" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (BREAKPOINT_FROM_PC) +#if !defined (BREAKPOINT_FROM_PC) #define BREAKPOINT_FROM_PC(pcptr, lenptr) (gdbarch_breakpoint_from_pc (current_gdbarch, pcptr, lenptr)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (MEMORY_INSERT_BREAKPOINT) -#define MEMORY_INSERT_BREAKPOINT(addr, contents_cache) (default_memory_insert_breakpoint (addr, contents_cache)) -#endif +extern int gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch); + +typedef CORE_ADDR (gdbarch_adjust_breakpoint_address_ftype) (struct gdbarch *gdbarch, CORE_ADDR bpaddr); +extern CORE_ADDR gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr); +extern void set_gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address); typedef int (gdbarch_memory_insert_breakpoint_ftype) (CORE_ADDR addr, char *contents_cache); extern int gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache); @@ -1693,16 +1596,9 @@ extern void set_gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, gdbar #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MEMORY_INSERT_BREAKPOINT) #error "Non multi-arch definition of MEMORY_INSERT_BREAKPOINT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MEMORY_INSERT_BREAKPOINT) +#if !defined (MEMORY_INSERT_BREAKPOINT) #define MEMORY_INSERT_BREAKPOINT(addr, contents_cache) (gdbarch_memory_insert_breakpoint (current_gdbarch, addr, contents_cache)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (MEMORY_REMOVE_BREAKPOINT) -#define MEMORY_REMOVE_BREAKPOINT(addr, contents_cache) (default_memory_remove_breakpoint (addr, contents_cache)) -#endif typedef int (gdbarch_memory_remove_breakpoint_ftype) (CORE_ADDR addr, char *contents_cache); extern int gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache); @@ -1710,179 +1606,255 @@ extern void set_gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, gdbar #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MEMORY_REMOVE_BREAKPOINT) #error "Non multi-arch definition of MEMORY_REMOVE_BREAKPOINT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MEMORY_REMOVE_BREAKPOINT) +#if !defined (MEMORY_REMOVE_BREAKPOINT) #define MEMORY_REMOVE_BREAKPOINT(addr, contents_cache) (gdbarch_memory_remove_breakpoint (current_gdbarch, addr, contents_cache)) #endif -#endif extern CORE_ADDR gdbarch_decr_pc_after_break (struct gdbarch *gdbarch); extern void set_gdbarch_decr_pc_after_break (struct gdbarch *gdbarch, CORE_ADDR decr_pc_after_break); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DECR_PC_AFTER_BREAK) #error "Non multi-arch definition of DECR_PC_AFTER_BREAK" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DECR_PC_AFTER_BREAK) +#if !defined (DECR_PC_AFTER_BREAK) #define DECR_PC_AFTER_BREAK (gdbarch_decr_pc_after_break (current_gdbarch)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (PREPARE_TO_PROCEED) -#define PREPARE_TO_PROCEED(select_it) (default_prepare_to_proceed (select_it)) -#endif - -typedef int (gdbarch_prepare_to_proceed_ftype) (int select_it); -extern int gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, int select_it); -extern void set_gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, gdbarch_prepare_to_proceed_ftype *prepare_to_proceed); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PREPARE_TO_PROCEED) -#error "Non multi-arch definition of PREPARE_TO_PROCEED" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PREPARE_TO_PROCEED) -#define PREPARE_TO_PROCEED(select_it) (gdbarch_prepare_to_proceed (current_gdbarch, select_it)) -#endif -#endif extern CORE_ADDR gdbarch_function_start_offset (struct gdbarch *gdbarch); extern void set_gdbarch_function_start_offset (struct gdbarch *gdbarch, CORE_ADDR function_start_offset); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FUNCTION_START_OFFSET) #error "Non multi-arch definition of FUNCTION_START_OFFSET" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FUNCTION_START_OFFSET) +#if !defined (FUNCTION_START_OFFSET) #define FUNCTION_START_OFFSET (gdbarch_function_start_offset (current_gdbarch)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REMOTE_TRANSLATE_XFER_ADDRESS) -#define REMOTE_TRANSLATE_XFER_ADDRESS(gdb_addr, gdb_len, rem_addr, rem_len) (generic_remote_translate_xfer_address (gdb_addr, gdb_len, rem_addr, rem_len)) -#endif - -typedef void (gdbarch_remote_translate_xfer_address_ftype) (CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len); -extern void gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len); +typedef void (gdbarch_remote_translate_xfer_address_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len); +extern void gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len); extern void set_gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, gdbarch_remote_translate_xfer_address_ftype *remote_translate_xfer_address); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REMOTE_TRANSLATE_XFER_ADDRESS) -#error "Non multi-arch definition of REMOTE_TRANSLATE_XFER_ADDRESS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REMOTE_TRANSLATE_XFER_ADDRESS) -#define REMOTE_TRANSLATE_XFER_ADDRESS(gdb_addr, gdb_len, rem_addr, rem_len) (gdbarch_remote_translate_xfer_address (current_gdbarch, gdb_addr, gdb_len, rem_addr, rem_len)) -#endif -#endif extern CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch); extern void set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, CORE_ADDR frame_args_skip); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_ARGS_SKIP) #error "Non multi-arch definition of FRAME_ARGS_SKIP" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_ARGS_SKIP) +#if !defined (FRAME_ARGS_SKIP) #define FRAME_ARGS_SKIP (gdbarch_frame_args_skip (current_gdbarch)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (FRAMELESS_FUNCTION_INVOCATION) -#define FRAMELESS_FUNCTION_INVOCATION(fi) (generic_frameless_function_invocation_not (fi)) -#endif +/* DEPRECATED_FRAMELESS_FUNCTION_INVOCATION is not needed. The new + frame code works regardless of the type of frame - frameless, + stackless, or normal. */ -typedef int (gdbarch_frameless_function_invocation_ftype) (struct frame_info *fi); -extern int gdbarch_frameless_function_invocation (struct gdbarch *gdbarch, struct frame_info *fi); -extern void set_gdbarch_frameless_function_invocation (struct gdbarch *gdbarch, gdbarch_frameless_function_invocation_ftype *frameless_function_invocation); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAMELESS_FUNCTION_INVOCATION) -#error "Non multi-arch definition of FRAMELESS_FUNCTION_INVOCATION" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAMELESS_FUNCTION_INVOCATION) -#define FRAMELESS_FUNCTION_INVOCATION(fi) (gdbarch_frameless_function_invocation (current_gdbarch, fi)) +#if defined (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION) +/* Legacy for systems yet to multi-arch DEPRECATED_FRAMELESS_FUNCTION_INVOCATION */ +#if !defined (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P) +#define DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P() (1) #endif #endif -typedef CORE_ADDR (gdbarch_frame_chain_ftype) (struct frame_info *frame); -extern CORE_ADDR gdbarch_frame_chain (struct gdbarch *gdbarch, struct frame_info *frame); -extern void set_gdbarch_frame_chain (struct gdbarch *gdbarch, gdbarch_frame_chain_ftype *frame_chain); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_CHAIN) -#error "Non multi-arch definition of FRAME_CHAIN" +extern int gdbarch_deprecated_frameless_function_invocation_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P) +#error "Non multi-arch definition of DEPRECATED_FRAMELESS_FUNCTION_INVOCATION" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_CHAIN) -#define FRAME_CHAIN(frame) (gdbarch_frame_chain (current_gdbarch, frame)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P) +#define DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P() (gdbarch_deprecated_frameless_function_invocation_p (current_gdbarch)) +#endif + +typedef int (gdbarch_deprecated_frameless_function_invocation_ftype) (struct frame_info *fi); +extern int gdbarch_deprecated_frameless_function_invocation (struct gdbarch *gdbarch, struct frame_info *fi); +extern void set_gdbarch_deprecated_frameless_function_invocation (struct gdbarch *gdbarch, gdbarch_deprecated_frameless_function_invocation_ftype *deprecated_frameless_function_invocation); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION) +#error "Non multi-arch definition of DEPRECATED_FRAMELESS_FUNCTION_INVOCATION" +#endif +#if !defined (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION) +#define DEPRECATED_FRAMELESS_FUNCTION_INVOCATION(fi) (gdbarch_deprecated_frameless_function_invocation (current_gdbarch, fi)) +#endif + +#if defined (DEPRECATED_FRAME_CHAIN) +/* Legacy for systems yet to multi-arch DEPRECATED_FRAME_CHAIN */ +#if !defined (DEPRECATED_FRAME_CHAIN_P) +#define DEPRECATED_FRAME_CHAIN_P() (1) #endif #endif -/* Define a default FRAME_CHAIN_VALID, in the form that is suitable for - most targets. If FRAME_CHAIN_VALID returns zero it means that the - given frame is the outermost one and has no caller. - - XXXX - both default and alternate frame_chain_valid functions are - deprecated. New code should use dummy frames and one of the generic - functions. */ - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (FRAME_CHAIN_VALID) -#define FRAME_CHAIN_VALID(chain, thisframe) (func_frame_chain_valid (chain, thisframe)) +extern int gdbarch_deprecated_frame_chain_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_CHAIN_P) +#error "Non multi-arch definition of DEPRECATED_FRAME_CHAIN" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FRAME_CHAIN_P) +#define DEPRECATED_FRAME_CHAIN_P() (gdbarch_deprecated_frame_chain_p (current_gdbarch)) #endif -typedef int (gdbarch_frame_chain_valid_ftype) (CORE_ADDR chain, struct frame_info *thisframe); -extern int gdbarch_frame_chain_valid (struct gdbarch *gdbarch, CORE_ADDR chain, struct frame_info *thisframe); -extern void set_gdbarch_frame_chain_valid (struct gdbarch *gdbarch, gdbarch_frame_chain_valid_ftype *frame_chain_valid); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_CHAIN_VALID) -#error "Non multi-arch definition of FRAME_CHAIN_VALID" +typedef CORE_ADDR (gdbarch_deprecated_frame_chain_ftype) (struct frame_info *frame); +extern CORE_ADDR gdbarch_deprecated_frame_chain (struct gdbarch *gdbarch, struct frame_info *frame); +extern void set_gdbarch_deprecated_frame_chain (struct gdbarch *gdbarch, gdbarch_deprecated_frame_chain_ftype *deprecated_frame_chain); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_CHAIN) +#error "Non multi-arch definition of DEPRECATED_FRAME_CHAIN" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_CHAIN_VALID) -#define FRAME_CHAIN_VALID(chain, thisframe) (gdbarch_frame_chain_valid (current_gdbarch, chain, thisframe)) +#if !defined (DEPRECATED_FRAME_CHAIN) +#define DEPRECATED_FRAME_CHAIN(frame) (gdbarch_deprecated_frame_chain (current_gdbarch, frame)) +#endif + +#if defined (DEPRECATED_FRAME_CHAIN_VALID) +/* Legacy for systems yet to multi-arch DEPRECATED_FRAME_CHAIN_VALID */ +#if !defined (DEPRECATED_FRAME_CHAIN_VALID_P) +#define DEPRECATED_FRAME_CHAIN_VALID_P() (1) #endif #endif -typedef CORE_ADDR (gdbarch_frame_saved_pc_ftype) (struct frame_info *fi); -extern CORE_ADDR gdbarch_frame_saved_pc (struct gdbarch *gdbarch, struct frame_info *fi); -extern void set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch, gdbarch_frame_saved_pc_ftype *frame_saved_pc); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_SAVED_PC) -#error "Non multi-arch definition of FRAME_SAVED_PC" +extern int gdbarch_deprecated_frame_chain_valid_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_CHAIN_VALID_P) +#error "Non multi-arch definition of DEPRECATED_FRAME_CHAIN_VALID" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_SAVED_PC) -#define FRAME_SAVED_PC(fi) (gdbarch_frame_saved_pc (current_gdbarch, fi)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FRAME_CHAIN_VALID_P) +#define DEPRECATED_FRAME_CHAIN_VALID_P() (gdbarch_deprecated_frame_chain_valid_p (current_gdbarch)) +#endif + +typedef int (gdbarch_deprecated_frame_chain_valid_ftype) (CORE_ADDR chain, struct frame_info *thisframe); +extern int gdbarch_deprecated_frame_chain_valid (struct gdbarch *gdbarch, CORE_ADDR chain, struct frame_info *thisframe); +extern void set_gdbarch_deprecated_frame_chain_valid (struct gdbarch *gdbarch, gdbarch_deprecated_frame_chain_valid_ftype *deprecated_frame_chain_valid); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_CHAIN_VALID) +#error "Non multi-arch definition of DEPRECATED_FRAME_CHAIN_VALID" +#endif +#if !defined (DEPRECATED_FRAME_CHAIN_VALID) +#define DEPRECATED_FRAME_CHAIN_VALID(chain, thisframe) (gdbarch_deprecated_frame_chain_valid (current_gdbarch, chain, thisframe)) +#endif + +/* DEPRECATED_FRAME_SAVED_PC has been replaced by UNWIND_PC. Please + note, per UNWIND_PC's doco, that while the two have similar + interfaces they have very different underlying implementations. */ + +#if defined (DEPRECATED_FRAME_SAVED_PC) +/* Legacy for systems yet to multi-arch DEPRECATED_FRAME_SAVED_PC */ +#if !defined (DEPRECATED_FRAME_SAVED_PC_P) +#define DEPRECATED_FRAME_SAVED_PC_P() (1) #endif #endif -typedef CORE_ADDR (gdbarch_frame_args_address_ftype) (struct frame_info *fi); -extern CORE_ADDR gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi); -extern void set_gdbarch_frame_args_address (struct gdbarch *gdbarch, gdbarch_frame_args_address_ftype *frame_args_address); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_ARGS_ADDRESS) -#error "Non multi-arch definition of FRAME_ARGS_ADDRESS" +extern int gdbarch_deprecated_frame_saved_pc_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_SAVED_PC_P) +#error "Non multi-arch definition of DEPRECATED_FRAME_SAVED_PC" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_ARGS_ADDRESS) -#define FRAME_ARGS_ADDRESS(fi) (gdbarch_frame_args_address (current_gdbarch, fi)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FRAME_SAVED_PC_P) +#define DEPRECATED_FRAME_SAVED_PC_P() (gdbarch_deprecated_frame_saved_pc_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_deprecated_frame_saved_pc_ftype) (struct frame_info *fi); +extern CORE_ADDR gdbarch_deprecated_frame_saved_pc (struct gdbarch *gdbarch, struct frame_info *fi); +extern void set_gdbarch_deprecated_frame_saved_pc (struct gdbarch *gdbarch, gdbarch_deprecated_frame_saved_pc_ftype *deprecated_frame_saved_pc); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_SAVED_PC) +#error "Non multi-arch definition of DEPRECATED_FRAME_SAVED_PC" +#endif +#if !defined (DEPRECATED_FRAME_SAVED_PC) +#define DEPRECATED_FRAME_SAVED_PC(fi) (gdbarch_deprecated_frame_saved_pc (current_gdbarch, fi)) +#endif + +extern int gdbarch_unwind_pc_p (struct gdbarch *gdbarch); + +typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame); +extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame); +extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc); + +extern int gdbarch_unwind_sp_p (struct gdbarch *gdbarch); + +typedef CORE_ADDR (gdbarch_unwind_sp_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame); +extern CORE_ADDR gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame); +extern void set_gdbarch_unwind_sp (struct gdbarch *gdbarch, gdbarch_unwind_sp_ftype *unwind_sp); + +/* DEPRECATED_FRAME_ARGS_ADDRESS as been replaced by the per-frame + frame-base. Enable frame-base before frame-unwind. */ + +#if defined (DEPRECATED_FRAME_ARGS_ADDRESS) +/* Legacy for systems yet to multi-arch DEPRECATED_FRAME_ARGS_ADDRESS */ +#if !defined (DEPRECATED_FRAME_ARGS_ADDRESS_P) +#define DEPRECATED_FRAME_ARGS_ADDRESS_P() (1) #endif #endif -typedef CORE_ADDR (gdbarch_frame_locals_address_ftype) (struct frame_info *fi); -extern CORE_ADDR gdbarch_frame_locals_address (struct gdbarch *gdbarch, struct frame_info *fi); -extern void set_gdbarch_frame_locals_address (struct gdbarch *gdbarch, gdbarch_frame_locals_address_ftype *frame_locals_address); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_LOCALS_ADDRESS) -#error "Non multi-arch definition of FRAME_LOCALS_ADDRESS" +extern int gdbarch_deprecated_frame_args_address_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_ARGS_ADDRESS_P) +#error "Non multi-arch definition of DEPRECATED_FRAME_ARGS_ADDRESS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_LOCALS_ADDRESS) -#define FRAME_LOCALS_ADDRESS(fi) (gdbarch_frame_locals_address (current_gdbarch, fi)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FRAME_ARGS_ADDRESS_P) +#define DEPRECATED_FRAME_ARGS_ADDRESS_P() (gdbarch_deprecated_frame_args_address_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_deprecated_frame_args_address_ftype) (struct frame_info *fi); +extern CORE_ADDR gdbarch_deprecated_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi); +extern void set_gdbarch_deprecated_frame_args_address (struct gdbarch *gdbarch, gdbarch_deprecated_frame_args_address_ftype *deprecated_frame_args_address); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_ARGS_ADDRESS) +#error "Non multi-arch definition of DEPRECATED_FRAME_ARGS_ADDRESS" +#endif +#if !defined (DEPRECATED_FRAME_ARGS_ADDRESS) +#define DEPRECATED_FRAME_ARGS_ADDRESS(fi) (gdbarch_deprecated_frame_args_address (current_gdbarch, fi)) +#endif + +/* DEPRECATED_FRAME_LOCALS_ADDRESS as been replaced by the per-frame + frame-base. Enable frame-base before frame-unwind. */ + +#if defined (DEPRECATED_FRAME_LOCALS_ADDRESS) +/* Legacy for systems yet to multi-arch DEPRECATED_FRAME_LOCALS_ADDRESS */ +#if !defined (DEPRECATED_FRAME_LOCALS_ADDRESS_P) +#define DEPRECATED_FRAME_LOCALS_ADDRESS_P() (1) #endif #endif -typedef CORE_ADDR (gdbarch_saved_pc_after_call_ftype) (struct frame_info *frame); -extern CORE_ADDR gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame); -extern void set_gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, gdbarch_saved_pc_after_call_ftype *saved_pc_after_call); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVED_PC_AFTER_CALL) -#error "Non multi-arch definition of SAVED_PC_AFTER_CALL" +extern int gdbarch_deprecated_frame_locals_address_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_LOCALS_ADDRESS_P) +#error "Non multi-arch definition of DEPRECATED_FRAME_LOCALS_ADDRESS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVED_PC_AFTER_CALL) -#define SAVED_PC_AFTER_CALL(frame) (gdbarch_saved_pc_after_call (current_gdbarch, frame)) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_FRAME_LOCALS_ADDRESS_P) +#define DEPRECATED_FRAME_LOCALS_ADDRESS_P() (gdbarch_deprecated_frame_locals_address_p (current_gdbarch)) #endif + +typedef CORE_ADDR (gdbarch_deprecated_frame_locals_address_ftype) (struct frame_info *fi); +extern CORE_ADDR gdbarch_deprecated_frame_locals_address (struct gdbarch *gdbarch, struct frame_info *fi); +extern void set_gdbarch_deprecated_frame_locals_address (struct gdbarch *gdbarch, gdbarch_deprecated_frame_locals_address_ftype *deprecated_frame_locals_address); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_FRAME_LOCALS_ADDRESS) +#error "Non multi-arch definition of DEPRECATED_FRAME_LOCALS_ADDRESS" +#endif +#if !defined (DEPRECATED_FRAME_LOCALS_ADDRESS) +#define DEPRECATED_FRAME_LOCALS_ADDRESS(fi) (gdbarch_deprecated_frame_locals_address (current_gdbarch, fi)) +#endif + +#if defined (DEPRECATED_SAVED_PC_AFTER_CALL) +/* Legacy for systems yet to multi-arch DEPRECATED_SAVED_PC_AFTER_CALL */ +#if !defined (DEPRECATED_SAVED_PC_AFTER_CALL_P) +#define DEPRECATED_SAVED_PC_AFTER_CALL_P() (1) +#endif +#endif + +extern int gdbarch_deprecated_saved_pc_after_call_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_SAVED_PC_AFTER_CALL_P) +#error "Non multi-arch definition of DEPRECATED_SAVED_PC_AFTER_CALL" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_SAVED_PC_AFTER_CALL_P) +#define DEPRECATED_SAVED_PC_AFTER_CALL_P() (gdbarch_deprecated_saved_pc_after_call_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_deprecated_saved_pc_after_call_ftype) (struct frame_info *frame); +extern CORE_ADDR gdbarch_deprecated_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame); +extern void set_gdbarch_deprecated_saved_pc_after_call (struct gdbarch *gdbarch, gdbarch_deprecated_saved_pc_after_call_ftype *deprecated_saved_pc_after_call); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_SAVED_PC_AFTER_CALL) +#error "Non multi-arch definition of DEPRECATED_SAVED_PC_AFTER_CALL" +#endif +#if !defined (DEPRECATED_SAVED_PC_AFTER_CALL) +#define DEPRECATED_SAVED_PC_AFTER_CALL(frame) (gdbarch_deprecated_saved_pc_after_call (current_gdbarch, frame)) +#endif + +#if defined (FRAME_NUM_ARGS) +/* Legacy for systems yet to multi-arch FRAME_NUM_ARGS */ +#if !defined (FRAME_NUM_ARGS_P) +#define FRAME_NUM_ARGS_P() (1) +#endif +#endif + +extern int gdbarch_frame_num_args_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_NUM_ARGS_P) +#error "Non multi-arch definition of FRAME_NUM_ARGS" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_NUM_ARGS_P) +#define FRAME_NUM_ARGS_P() (gdbarch_frame_num_args_p (current_gdbarch)) #endif typedef int (gdbarch_frame_num_args_ftype) (struct frame_info *frame); @@ -1891,137 +1863,85 @@ extern void set_gdbarch_frame_num_args (struct gdbarch *gdbarch, gdbarch_frame_n #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_NUM_ARGS) #error "Non multi-arch definition of FRAME_NUM_ARGS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_NUM_ARGS) +#if !defined (FRAME_NUM_ARGS) #define FRAME_NUM_ARGS(frame) (gdbarch_frame_num_args (current_gdbarch, frame)) #endif -#endif -#if defined (STACK_ALIGN) -/* Legacy for systems yet to multi-arch STACK_ALIGN */ -#if !defined (STACK_ALIGN_P) -#define STACK_ALIGN_P() (1) +/* DEPRECATED_STACK_ALIGN has been replaced by an initial aligning call + to frame_align and the requirement that methods such as + push_dummy_call and frame_red_zone_size maintain correct stack/frame + alignment. */ + +#if defined (DEPRECATED_STACK_ALIGN) +/* Legacy for systems yet to multi-arch DEPRECATED_STACK_ALIGN */ +#if !defined (DEPRECATED_STACK_ALIGN_P) +#define DEPRECATED_STACK_ALIGN_P() (1) #endif #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (STACK_ALIGN_P) -#define STACK_ALIGN_P() (0) +extern int gdbarch_deprecated_stack_align_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_STACK_ALIGN_P) +#error "Non multi-arch definition of DEPRECATED_STACK_ALIGN" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_STACK_ALIGN_P) +#define DEPRECATED_STACK_ALIGN_P() (gdbarch_deprecated_stack_align_p (current_gdbarch)) #endif -extern int gdbarch_stack_align_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STACK_ALIGN_P) -#error "Non multi-arch definition of STACK_ALIGN" +typedef CORE_ADDR (gdbarch_deprecated_stack_align_ftype) (CORE_ADDR sp); +extern CORE_ADDR gdbarch_deprecated_stack_align (struct gdbarch *gdbarch, CORE_ADDR sp); +extern void set_gdbarch_deprecated_stack_align (struct gdbarch *gdbarch, gdbarch_deprecated_stack_align_ftype *deprecated_stack_align); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_STACK_ALIGN) +#error "Non multi-arch definition of DEPRECATED_STACK_ALIGN" #endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STACK_ALIGN_P) -#define STACK_ALIGN_P() (gdbarch_stack_align_p (current_gdbarch)) +#if !defined (DEPRECATED_STACK_ALIGN) +#define DEPRECATED_STACK_ALIGN(sp) (gdbarch_deprecated_stack_align (current_gdbarch, sp)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (STACK_ALIGN) -#define STACK_ALIGN(sp) (internal_error (__FILE__, __LINE__, "STACK_ALIGN"), 0) -#endif +extern int gdbarch_frame_align_p (struct gdbarch *gdbarch); -typedef CORE_ADDR (gdbarch_stack_align_ftype) (CORE_ADDR sp); -extern CORE_ADDR gdbarch_stack_align (struct gdbarch *gdbarch, CORE_ADDR sp); -extern void set_gdbarch_stack_align (struct gdbarch *gdbarch, gdbarch_stack_align_ftype *stack_align); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STACK_ALIGN) -#error "Non multi-arch definition of STACK_ALIGN" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STACK_ALIGN) -#define STACK_ALIGN(sp) (gdbarch_stack_align (current_gdbarch, sp)) +typedef CORE_ADDR (gdbarch_frame_align_ftype) (struct gdbarch *gdbarch, CORE_ADDR address); +extern CORE_ADDR gdbarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR address); +extern void set_gdbarch_frame_align (struct gdbarch *gdbarch, gdbarch_frame_align_ftype *frame_align); + +/* DEPRECATED_REG_STRUCT_HAS_ADDR has been replaced by + stabs_argument_has_addr. */ + +#if defined (DEPRECATED_REG_STRUCT_HAS_ADDR) +/* Legacy for systems yet to multi-arch DEPRECATED_REG_STRUCT_HAS_ADDR */ +#if !defined (DEPRECATED_REG_STRUCT_HAS_ADDR_P) +#define DEPRECATED_REG_STRUCT_HAS_ADDR_P() (1) #endif #endif -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (EXTRA_STACK_ALIGNMENT_NEEDED) -#define EXTRA_STACK_ALIGNMENT_NEEDED (1) +extern int gdbarch_deprecated_reg_struct_has_addr_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REG_STRUCT_HAS_ADDR_P) +#error "Non multi-arch definition of DEPRECATED_REG_STRUCT_HAS_ADDR" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_REG_STRUCT_HAS_ADDR_P) +#define DEPRECATED_REG_STRUCT_HAS_ADDR_P() (gdbarch_deprecated_reg_struct_has_addr_p (current_gdbarch)) #endif -extern int gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch); -extern void set_gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch, int extra_stack_alignment_needed); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRA_STACK_ALIGNMENT_NEEDED) -#error "Non multi-arch definition of EXTRA_STACK_ALIGNMENT_NEEDED" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRA_STACK_ALIGNMENT_NEEDED) -#define EXTRA_STACK_ALIGNMENT_NEEDED (gdbarch_extra_stack_alignment_needed (current_gdbarch)) +typedef int (gdbarch_deprecated_reg_struct_has_addr_ftype) (int gcc_p, struct type *type); +extern int gdbarch_deprecated_reg_struct_has_addr (struct gdbarch *gdbarch, int gcc_p, struct type *type); +extern void set_gdbarch_deprecated_reg_struct_has_addr (struct gdbarch *gdbarch, gdbarch_deprecated_reg_struct_has_addr_ftype *deprecated_reg_struct_has_addr); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_REG_STRUCT_HAS_ADDR) +#error "Non multi-arch definition of DEPRECATED_REG_STRUCT_HAS_ADDR" #endif +#if !defined (DEPRECATED_REG_STRUCT_HAS_ADDR) +#define DEPRECATED_REG_STRUCT_HAS_ADDR(gcc_p, type) (gdbarch_deprecated_reg_struct_has_addr (current_gdbarch, gcc_p, type)) #endif -#if defined (REG_STRUCT_HAS_ADDR) -/* Legacy for systems yet to multi-arch REG_STRUCT_HAS_ADDR */ -#if !defined (REG_STRUCT_HAS_ADDR_P) -#define REG_STRUCT_HAS_ADDR_P() (1) -#endif -#endif +typedef int (gdbarch_stabs_argument_has_addr_ftype) (struct gdbarch *gdbarch, struct type *type); +extern int gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type); +extern void set_gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, gdbarch_stabs_argument_has_addr_ftype *stabs_argument_has_addr); -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (REG_STRUCT_HAS_ADDR_P) -#define REG_STRUCT_HAS_ADDR_P() (0) -#endif - -extern int gdbarch_reg_struct_has_addr_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REG_STRUCT_HAS_ADDR_P) -#error "Non multi-arch definition of REG_STRUCT_HAS_ADDR" -#endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REG_STRUCT_HAS_ADDR_P) -#define REG_STRUCT_HAS_ADDR_P() (gdbarch_reg_struct_has_addr_p (current_gdbarch)) -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (REG_STRUCT_HAS_ADDR) -#define REG_STRUCT_HAS_ADDR(gcc_p, type) (internal_error (__FILE__, __LINE__, "REG_STRUCT_HAS_ADDR"), 0) -#endif - -typedef int (gdbarch_reg_struct_has_addr_ftype) (int gcc_p, struct type *type); -extern int gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, int gcc_p, struct type *type); -extern void set_gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REG_STRUCT_HAS_ADDR) -#error "Non multi-arch definition of REG_STRUCT_HAS_ADDR" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REG_STRUCT_HAS_ADDR) -#define REG_STRUCT_HAS_ADDR(gcc_p, type) (gdbarch_reg_struct_has_addr (current_gdbarch, gcc_p, type)) -#endif -#endif - -#if defined (SAVE_DUMMY_FRAME_TOS) -/* Legacy for systems yet to multi-arch SAVE_DUMMY_FRAME_TOS */ -#if !defined (SAVE_DUMMY_FRAME_TOS_P) -#define SAVE_DUMMY_FRAME_TOS_P() (1) -#endif -#endif - -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (SAVE_DUMMY_FRAME_TOS_P) -#define SAVE_DUMMY_FRAME_TOS_P() (0) -#endif - -extern int gdbarch_save_dummy_frame_tos_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVE_DUMMY_FRAME_TOS_P) -#error "Non multi-arch definition of SAVE_DUMMY_FRAME_TOS" -#endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVE_DUMMY_FRAME_TOS_P) -#define SAVE_DUMMY_FRAME_TOS_P() (gdbarch_save_dummy_frame_tos_p (current_gdbarch)) -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (SAVE_DUMMY_FRAME_TOS) -#define SAVE_DUMMY_FRAME_TOS(sp) (internal_error (__FILE__, __LINE__, "SAVE_DUMMY_FRAME_TOS"), 0) -#endif - -typedef void (gdbarch_save_dummy_frame_tos_ftype) (CORE_ADDR sp); -extern void gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, CORE_ADDR sp); -extern void set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVE_DUMMY_FRAME_TOS) -#error "Non multi-arch definition of SAVE_DUMMY_FRAME_TOS" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVE_DUMMY_FRAME_TOS) -#define SAVE_DUMMY_FRAME_TOS(sp) (gdbarch_save_dummy_frame_tos (current_gdbarch, sp)) +extern int gdbarch_frame_red_zone_size (struct gdbarch *gdbarch); +extern void set_gdbarch_frame_red_zone_size (struct gdbarch *gdbarch, int frame_red_zone_size); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_RED_ZONE_SIZE) +#error "Non multi-arch definition of FRAME_RED_ZONE_SIZE" #endif +#if !defined (FRAME_RED_ZONE_SIZE) +#define FRAME_RED_ZONE_SIZE (gdbarch_frame_red_zone_size (current_gdbarch)) #endif extern int gdbarch_parm_boundary (struct gdbarch *gdbarch); @@ -2029,76 +1949,40 @@ extern void set_gdbarch_parm_boundary (struct gdbarch *gdbarch, int parm_boundar #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PARM_BOUNDARY) #error "Non multi-arch definition of PARM_BOUNDARY" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PARM_BOUNDARY) +#if !defined (PARM_BOUNDARY) #define PARM_BOUNDARY (gdbarch_parm_boundary (current_gdbarch)) #endif -#endif - -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_FLOAT_FORMAT) -#define TARGET_FLOAT_FORMAT (default_float_format (current_gdbarch)) -#endif extern const struct floatformat * gdbarch_float_format (struct gdbarch *gdbarch); extern void set_gdbarch_float_format (struct gdbarch *gdbarch, const struct floatformat * float_format); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_FLOAT_FORMAT) #error "Non multi-arch definition of TARGET_FLOAT_FORMAT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_FLOAT_FORMAT) +#if !defined (TARGET_FLOAT_FORMAT) #define TARGET_FLOAT_FORMAT (gdbarch_float_format (current_gdbarch)) #endif -#endif - -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_DOUBLE_FORMAT) -#define TARGET_DOUBLE_FORMAT (default_double_format (current_gdbarch)) -#endif extern const struct floatformat * gdbarch_double_format (struct gdbarch *gdbarch); extern void set_gdbarch_double_format (struct gdbarch *gdbarch, const struct floatformat * double_format); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_DOUBLE_FORMAT) #error "Non multi-arch definition of TARGET_DOUBLE_FORMAT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_DOUBLE_FORMAT) +#if !defined (TARGET_DOUBLE_FORMAT) #define TARGET_DOUBLE_FORMAT (gdbarch_double_format (current_gdbarch)) #endif -#endif - -/* Default (value) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_DOUBLE_FORMAT) -#define TARGET_LONG_DOUBLE_FORMAT (default_double_format (current_gdbarch)) -#endif extern const struct floatformat * gdbarch_long_double_format (struct gdbarch *gdbarch); extern void set_gdbarch_long_double_format (struct gdbarch *gdbarch, const struct floatformat * long_double_format); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_DOUBLE_FORMAT) #error "Non multi-arch definition of TARGET_LONG_DOUBLE_FORMAT" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_DOUBLE_FORMAT) +#if !defined (TARGET_LONG_DOUBLE_FORMAT) #define TARGET_LONG_DOUBLE_FORMAT (gdbarch_long_double_format (current_gdbarch)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (CONVERT_FROM_FUNC_PTR_ADDR) -#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (core_addr_identity (addr)) -#endif - -typedef CORE_ADDR (gdbarch_convert_from_func_ptr_addr_ftype) (CORE_ADDR addr); -extern CORE_ADDR gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr); +typedef CORE_ADDR (gdbarch_convert_from_func_ptr_addr_ftype) (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ); +extern CORE_ADDR gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ); extern void set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CONVERT_FROM_FUNC_PTR_ADDR) -#error "Non multi-arch definition of CONVERT_FROM_FUNC_PTR_ADDR" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CONVERT_FROM_FUNC_PTR_ADDR) -#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (gdbarch_convert_from_func_ptr_addr (current_gdbarch, addr)) -#endif -#endif /* 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. @@ -2110,42 +1994,28 @@ extern void set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdb sort of generic thing to handle alignment or segmentation (it's possible it should be in TARGET_READ_PC instead). */ -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (ADDR_BITS_REMOVE) -#define ADDR_BITS_REMOVE(addr) (core_addr_identity (addr)) -#endif - typedef CORE_ADDR (gdbarch_addr_bits_remove_ftype) (CORE_ADDR addr); extern CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr); extern void set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch_addr_bits_remove_ftype *addr_bits_remove); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDR_BITS_REMOVE) #error "Non multi-arch definition of ADDR_BITS_REMOVE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDR_BITS_REMOVE) +#if !defined (ADDR_BITS_REMOVE) #define ADDR_BITS_REMOVE(addr) (gdbarch_addr_bits_remove (current_gdbarch, addr)) #endif -#endif /* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into ADDR_BITS_REMOVE. */ -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (SMASH_TEXT_ADDRESS) -#define SMASH_TEXT_ADDRESS(addr) (core_addr_identity (addr)) -#endif - typedef CORE_ADDR (gdbarch_smash_text_address_ftype) (CORE_ADDR addr); extern CORE_ADDR gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr); extern void set_gdbarch_smash_text_address (struct gdbarch *gdbarch, gdbarch_smash_text_address_ftype *smash_text_address); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SMASH_TEXT_ADDRESS) #error "Non multi-arch definition of SMASH_TEXT_ADDRESS" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SMASH_TEXT_ADDRESS) +#if !defined (SMASH_TEXT_ADDRESS) #define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr)) #endif -#endif /* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if the target needs software single step. An ISA method to implement it. @@ -2163,11 +2033,6 @@ extern void set_gdbarch_smash_text_address (struct gdbarch *gdbarch, gdbarch_sma #endif #endif -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (SOFTWARE_SINGLE_STEP_P) -#define SOFTWARE_SINGLE_STEP_P() (0) -#endif - extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SOFTWARE_SINGLE_STEP_P) #error "Non multi-arch definition of SOFTWARE_SINGLE_STEP" @@ -2176,44 +2041,28 @@ extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch); #define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch)) #endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (SOFTWARE_SINGLE_STEP) -#define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (internal_error (__FILE__, __LINE__, "SOFTWARE_SINGLE_STEP"), 0) -#endif - typedef void (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p); extern void gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p); extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SOFTWARE_SINGLE_STEP) #error "Non multi-arch definition of SOFTWARE_SINGLE_STEP" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SOFTWARE_SINGLE_STEP) +#if !defined (SOFTWARE_SINGLE_STEP) #define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (gdbarch_software_single_step (current_gdbarch, sig, insert_breakpoints_p)) #endif -#endif -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (TARGET_PRINT_INSN) -#define TARGET_PRINT_INSN(vma, info) (legacy_print_insn (vma, info)) -#endif +/* FIXME: cagney/2003-08-28: Need to find a better way of selecting the + disassembler. Perhaphs objdump can handle it? */ -typedef int (gdbarch_print_insn_ftype) (bfd_vma vma, disassemble_info *info); -extern int gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, disassemble_info *info); +typedef int (gdbarch_print_insn_ftype) (bfd_vma vma, struct disassemble_info *info); +extern int gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, struct disassemble_info *info); extern void set_gdbarch_print_insn (struct gdbarch *gdbarch, gdbarch_print_insn_ftype *print_insn); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_PRINT_INSN) #error "Non multi-arch definition of TARGET_PRINT_INSN" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_PRINT_INSN) +#if !defined (TARGET_PRINT_INSN) #define TARGET_PRINT_INSN(vma, info) (gdbarch_print_insn (current_gdbarch, vma, info)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (SKIP_TRAMPOLINE_CODE) -#define SKIP_TRAMPOLINE_CODE(pc) (generic_skip_trampoline_code (pc)) -#endif typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (CORE_ADDR pc); extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, CORE_ADDR pc); @@ -2221,20 +2070,21 @@ extern void set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch_s #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SKIP_TRAMPOLINE_CODE) #error "Non multi-arch definition of SKIP_TRAMPOLINE_CODE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SKIP_TRAMPOLINE_CODE) +#if !defined (SKIP_TRAMPOLINE_CODE) #define SKIP_TRAMPOLINE_CODE(pc) (gdbarch_skip_trampoline_code (current_gdbarch, pc)) #endif -#endif + +/* If IN_SOLIB_DYNSYM_RESOLVE_CODE returns true, and SKIP_SOLIB_RESOLVER + evaluates non-zero, this is the address where the debugger will place + a step-resume breakpoint to get us past the dynamic linker. */ + +typedef CORE_ADDR (gdbarch_skip_solib_resolver_ftype) (struct gdbarch *gdbarch, CORE_ADDR pc); +extern CORE_ADDR gdbarch_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc); +extern void set_gdbarch_skip_solib_resolver (struct gdbarch *gdbarch, gdbarch_skip_solib_resolver_ftype *skip_solib_resolver); /* For SVR4 shared libraries, each call goes through a small piece of trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates - to nonzero if we are current stopped in one of these. */ - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (IN_SOLIB_CALL_TRAMPOLINE) -#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) (generic_in_solib_call_trampoline (pc, name)) -#endif + to nonzero if we are currently stopped in one of these. */ typedef int (gdbarch_in_solib_call_trampoline_ftype) (CORE_ADDR pc, char *name); extern int gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc, char *name); @@ -2242,10 +2092,101 @@ extern void set_gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, gdbar #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (IN_SOLIB_CALL_TRAMPOLINE) #error "Non multi-arch definition of IN_SOLIB_CALL_TRAMPOLINE" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (IN_SOLIB_CALL_TRAMPOLINE) +#if !defined (IN_SOLIB_CALL_TRAMPOLINE) #define IN_SOLIB_CALL_TRAMPOLINE(pc, name) (gdbarch_in_solib_call_trampoline (current_gdbarch, pc, name)) #endif + +/* Some systems also have trampoline code for returning from shared libs. */ + +typedef int (gdbarch_in_solib_return_trampoline_ftype) (CORE_ADDR pc, char *name); +extern int gdbarch_in_solib_return_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc, char *name); +extern void set_gdbarch_in_solib_return_trampoline (struct gdbarch *gdbarch, gdbarch_in_solib_return_trampoline_ftype *in_solib_return_trampoline); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (IN_SOLIB_RETURN_TRAMPOLINE) +#error "Non multi-arch definition of IN_SOLIB_RETURN_TRAMPOLINE" +#endif +#if !defined (IN_SOLIB_RETURN_TRAMPOLINE) +#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) (gdbarch_in_solib_return_trampoline (current_gdbarch, pc, name)) +#endif + +/* Sigtramp is a routine that the kernel calls (which then calls the + signal handler). On most machines it is a library routine that is + linked into the executable. + + This macro, given a program counter value and the name of the + function in which that PC resides (which can be null if the name is + not known), returns nonzero if the PC and name show that we are in + sigtramp. + + On most machines just see if the name is sigtramp (and if we have + no name, assume we are not in sigtramp). + + FIXME: cagney/2002-04-21: The function find_pc_partial_function + calls find_pc_sect_partial_function() which calls PC_IN_SIGTRAMP. + This means PC_IN_SIGTRAMP function can't be implemented by doing its + own local NAME lookup. + + FIXME: cagney/2002-04-21: PC_IN_SIGTRAMP is something of a mess. + Some code also depends on SIGTRAMP_START and SIGTRAMP_END but other + does not. */ + +typedef int (gdbarch_pc_in_sigtramp_ftype) (CORE_ADDR pc, char *name); +extern int gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc, char *name); +extern void set_gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, gdbarch_pc_in_sigtramp_ftype *pc_in_sigtramp); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PC_IN_SIGTRAMP) +#error "Non multi-arch definition of PC_IN_SIGTRAMP" +#endif +#if !defined (PC_IN_SIGTRAMP) +#define PC_IN_SIGTRAMP(pc, name) (gdbarch_pc_in_sigtramp (current_gdbarch, pc, name)) +#endif + +#if defined (SIGTRAMP_START) +/* Legacy for systems yet to multi-arch SIGTRAMP_START */ +#if !defined (SIGTRAMP_START_P) +#define SIGTRAMP_START_P() (1) +#endif +#endif + +extern int gdbarch_sigtramp_start_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIGTRAMP_START_P) +#error "Non multi-arch definition of SIGTRAMP_START" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SIGTRAMP_START_P) +#define SIGTRAMP_START_P() (gdbarch_sigtramp_start_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_sigtramp_start_ftype) (CORE_ADDR pc); +extern CORE_ADDR gdbarch_sigtramp_start (struct gdbarch *gdbarch, CORE_ADDR pc); +extern void set_gdbarch_sigtramp_start (struct gdbarch *gdbarch, gdbarch_sigtramp_start_ftype *sigtramp_start); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIGTRAMP_START) +#error "Non multi-arch definition of SIGTRAMP_START" +#endif +#if !defined (SIGTRAMP_START) +#define SIGTRAMP_START(pc) (gdbarch_sigtramp_start (current_gdbarch, pc)) +#endif + +#if defined (SIGTRAMP_END) +/* Legacy for systems yet to multi-arch SIGTRAMP_END */ +#if !defined (SIGTRAMP_END_P) +#define SIGTRAMP_END_P() (1) +#endif +#endif + +extern int gdbarch_sigtramp_end_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIGTRAMP_END_P) +#error "Non multi-arch definition of SIGTRAMP_END" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SIGTRAMP_END_P) +#define SIGTRAMP_END_P() (gdbarch_sigtramp_end_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_sigtramp_end_ftype) (CORE_ADDR pc); +extern CORE_ADDR gdbarch_sigtramp_end (struct gdbarch *gdbarch, CORE_ADDR pc); +extern void set_gdbarch_sigtramp_end (struct gdbarch *gdbarch, gdbarch_sigtramp_end_ftype *sigtramp_end); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIGTRAMP_END) +#error "Non multi-arch definition of SIGTRAMP_END" +#endif +#if !defined (SIGTRAMP_END) +#define SIGTRAMP_END(pc) (gdbarch_sigtramp_end (current_gdbarch, pc)) #endif /* A target might have problems with watchpoints as soon as the stack @@ -2275,64 +2216,15 @@ typedef char * (gdbarch_construct_inferior_arguments_ftype) (struct gdbarch *gdb extern char * gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv); extern void set_gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments); -#if defined (DWARF2_BUILD_FRAME_INFO) -/* Legacy for systems yet to multi-arch DWARF2_BUILD_FRAME_INFO */ -#if !defined (DWARF2_BUILD_FRAME_INFO_P) -#define DWARF2_BUILD_FRAME_INFO_P() (1) -#endif -#endif - -/* Default predicate for non- multi-arch targets. */ -#if (!GDB_MULTI_ARCH) && !defined (DWARF2_BUILD_FRAME_INFO_P) -#define DWARF2_BUILD_FRAME_INFO_P() (0) -#endif - -extern int gdbarch_dwarf2_build_frame_info_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_BUILD_FRAME_INFO_P) -#error "Non multi-arch definition of DWARF2_BUILD_FRAME_INFO" -#endif -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_BUILD_FRAME_INFO_P) -#define DWARF2_BUILD_FRAME_INFO_P() (gdbarch_dwarf2_build_frame_info_p (current_gdbarch)) -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (DWARF2_BUILD_FRAME_INFO) -#define DWARF2_BUILD_FRAME_INFO(objfile) (internal_error (__FILE__, __LINE__, "DWARF2_BUILD_FRAME_INFO"), 0) -#endif - -typedef void (gdbarch_dwarf2_build_frame_info_ftype) (struct objfile *objfile); -extern void gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch, struct objfile *objfile); -extern void set_gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch, gdbarch_dwarf2_build_frame_info_ftype *dwarf2_build_frame_info); -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_BUILD_FRAME_INFO) -#error "Non multi-arch definition of DWARF2_BUILD_FRAME_INFO" -#endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_BUILD_FRAME_INFO) -#define DWARF2_BUILD_FRAME_INFO(objfile) (gdbarch_dwarf2_build_frame_info (current_gdbarch, objfile)) -#endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (ELF_MAKE_MSYMBOL_SPECIAL) -#define ELF_MAKE_MSYMBOL_SPECIAL(sym, msym) (default_elf_make_msymbol_special (sym, msym)) -#endif - typedef void (gdbarch_elf_make_msymbol_special_ftype) (asymbol *sym, struct minimal_symbol *msym); extern void gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch, asymbol *sym, struct minimal_symbol *msym); extern void set_gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch, gdbarch_elf_make_msymbol_special_ftype *elf_make_msymbol_special); #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ELF_MAKE_MSYMBOL_SPECIAL) #error "Non multi-arch definition of ELF_MAKE_MSYMBOL_SPECIAL" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ELF_MAKE_MSYMBOL_SPECIAL) +#if !defined (ELF_MAKE_MSYMBOL_SPECIAL) #define ELF_MAKE_MSYMBOL_SPECIAL(sym, msym) (gdbarch_elf_make_msymbol_special (current_gdbarch, sym, msym)) #endif -#endif - -/* Default (function) for non- multi-arch platforms. */ -#if (!GDB_MULTI_ARCH) && !defined (COFF_MAKE_MSYMBOL_SPECIAL) -#define COFF_MAKE_MSYMBOL_SPECIAL(val, msym) (default_coff_make_msymbol_special (val, msym)) -#endif typedef void (gdbarch_coff_make_msymbol_special_ftype) (int val, struct minimal_symbol *msym); extern void gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, int val, struct minimal_symbol *msym); @@ -2340,11 +2232,115 @@ extern void set_gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, gdba #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (COFF_MAKE_MSYMBOL_SPECIAL) #error "Non multi-arch definition of COFF_MAKE_MSYMBOL_SPECIAL" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (COFF_MAKE_MSYMBOL_SPECIAL) +#if !defined (COFF_MAKE_MSYMBOL_SPECIAL) #define COFF_MAKE_MSYMBOL_SPECIAL(val, msym) (gdbarch_coff_make_msymbol_special (current_gdbarch, val, msym)) #endif + +extern const char * gdbarch_name_of_malloc (struct gdbarch *gdbarch); +extern void set_gdbarch_name_of_malloc (struct gdbarch *gdbarch, const char * name_of_malloc); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NAME_OF_MALLOC) +#error "Non multi-arch definition of NAME_OF_MALLOC" #endif +#if !defined (NAME_OF_MALLOC) +#define NAME_OF_MALLOC (gdbarch_name_of_malloc (current_gdbarch)) +#endif + +extern int gdbarch_cannot_step_breakpoint (struct gdbarch *gdbarch); +extern void set_gdbarch_cannot_step_breakpoint (struct gdbarch *gdbarch, int cannot_step_breakpoint); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CANNOT_STEP_BREAKPOINT) +#error "Non multi-arch definition of CANNOT_STEP_BREAKPOINT" +#endif +#if !defined (CANNOT_STEP_BREAKPOINT) +#define CANNOT_STEP_BREAKPOINT (gdbarch_cannot_step_breakpoint (current_gdbarch)) +#endif + +extern int gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch); +extern void set_gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch, int have_nonsteppable_watchpoint); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (HAVE_NONSTEPPABLE_WATCHPOINT) +#error "Non multi-arch definition of HAVE_NONSTEPPABLE_WATCHPOINT" +#endif +#if !defined (HAVE_NONSTEPPABLE_WATCHPOINT) +#define HAVE_NONSTEPPABLE_WATCHPOINT (gdbarch_have_nonsteppable_watchpoint (current_gdbarch)) +#endif + +#if defined (ADDRESS_CLASS_TYPE_FLAGS) +/* Legacy for systems yet to multi-arch ADDRESS_CLASS_TYPE_FLAGS */ +#if !defined (ADDRESS_CLASS_TYPE_FLAGS_P) +#define ADDRESS_CLASS_TYPE_FLAGS_P() (1) +#endif +#endif + +extern int gdbarch_address_class_type_flags_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_TYPE_FLAGS_P) +#error "Non multi-arch definition of ADDRESS_CLASS_TYPE_FLAGS" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_CLASS_TYPE_FLAGS_P) +#define ADDRESS_CLASS_TYPE_FLAGS_P() (gdbarch_address_class_type_flags_p (current_gdbarch)) +#endif + +typedef int (gdbarch_address_class_type_flags_ftype) (int byte_size, int dwarf2_addr_class); +extern int gdbarch_address_class_type_flags (struct gdbarch *gdbarch, int byte_size, int dwarf2_addr_class); +extern void set_gdbarch_address_class_type_flags (struct gdbarch *gdbarch, gdbarch_address_class_type_flags_ftype *address_class_type_flags); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_TYPE_FLAGS) +#error "Non multi-arch definition of ADDRESS_CLASS_TYPE_FLAGS" +#endif +#if !defined (ADDRESS_CLASS_TYPE_FLAGS) +#define ADDRESS_CLASS_TYPE_FLAGS(byte_size, dwarf2_addr_class) (gdbarch_address_class_type_flags (current_gdbarch, byte_size, dwarf2_addr_class)) +#endif + +extern int gdbarch_address_class_type_flags_to_name_p (struct gdbarch *gdbarch); + +typedef const char * (gdbarch_address_class_type_flags_to_name_ftype) (struct gdbarch *gdbarch, int type_flags); +extern const char * gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags); +extern void set_gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, gdbarch_address_class_type_flags_to_name_ftype *address_class_type_flags_to_name); + +extern int gdbarch_address_class_name_to_type_flags_p (struct gdbarch *gdbarch); + +typedef int (gdbarch_address_class_name_to_type_flags_ftype) (struct gdbarch *gdbarch, const char *name, int *type_flags_ptr); +extern int gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, const char *name, int *type_flags_ptr); +extern void set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags); + +/* Is a register in a group */ + +typedef int (gdbarch_register_reggroup_p_ftype) (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup); +extern int gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup); +extern void set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch, gdbarch_register_reggroup_p_ftype *register_reggroup_p); + +/* Fetch the pointer to the ith function argument. */ + +#if defined (FETCH_POINTER_ARGUMENT) +/* Legacy for systems yet to multi-arch FETCH_POINTER_ARGUMENT */ +#if !defined (FETCH_POINTER_ARGUMENT_P) +#define FETCH_POINTER_ARGUMENT_P() (1) +#endif +#endif + +extern int gdbarch_fetch_pointer_argument_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FETCH_POINTER_ARGUMENT_P) +#error "Non multi-arch definition of FETCH_POINTER_ARGUMENT" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FETCH_POINTER_ARGUMENT_P) +#define FETCH_POINTER_ARGUMENT_P() (gdbarch_fetch_pointer_argument_p (current_gdbarch)) +#endif + +typedef CORE_ADDR (gdbarch_fetch_pointer_argument_ftype) (struct frame_info *frame, int argi, struct type *type); +extern CORE_ADDR gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, struct frame_info *frame, int argi, struct type *type); +extern void set_gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FETCH_POINTER_ARGUMENT) +#error "Non multi-arch definition of FETCH_POINTER_ARGUMENT" +#endif +#if !defined (FETCH_POINTER_ARGUMENT) +#define FETCH_POINTER_ARGUMENT(frame, argi, type) (gdbarch_fetch_pointer_argument (current_gdbarch, frame, argi, type)) +#endif + +/* Return the appropriate register set for a core file section with + name SECT_NAME and size SECT_SIZE. */ + +extern int gdbarch_regset_from_core_section_p (struct gdbarch *gdbarch); + +typedef const struct regset * (gdbarch_regset_from_core_section_ftype) (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size); +extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size); +extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section); extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); @@ -2386,9 +2382,16 @@ extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); architecture; ARCHES which is a list of the previously created ``struct gdbarch'' for this architecture. - The INIT function parameter INFO shall, as far as possible, be - pre-initialized with information obtained from INFO.ABFD or - previously selected architecture (if similar). + The INFO parameter is, as far as possible, be pre-initialized with + information obtained from INFO.ABFD or the previously selected + architecture. + + The ARCHES parameter is a linked list (sorted most recently used) + of all the previously created architures for this architecture + family. The (possibly NULL) ARCHES->gdbarch can used to access + values from the previously selected architecture for this + architecture family. The global ``current_gdbarch'' shall not be + used. The INIT function shall return any of: NULL - indicating that it doesn't recognize the selected architecture; an existing ``struct @@ -2420,6 +2423,9 @@ struct gdbarch_info /* Use default: NULL (ZERO). */ struct gdbarch_tdep_info *tdep_info; + + /* Use default: GDB_OSABI_UNINITIALIZED (-1). */ + enum gdb_osabi osabi; }; typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches); @@ -2462,6 +2468,15 @@ extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gd extern void gdbarch_free (struct gdbarch *); +/* Helper function. Allocate memory from the ``struct gdbarch'' + obstack. The memory is freed when the corresponding architecture + is also freed. */ + +extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size); +#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE))) +#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE))) + + /* Helper function. Force an update of the current architecture. The actual architecture selected is determined by INFO, ``(gdb) set @@ -2474,6 +2489,27 @@ extern void gdbarch_free (struct gdbarch *); extern int gdbarch_update_p (struct gdbarch_info info); +/* Helper function. Find an architecture matching info. + + INFO should be initialized using gdbarch_info_init, relevant fields + set, and then finished using gdbarch_info_fill. + + Returns the corresponding architecture, or NULL if no matching + architecture was found. "current_gdbarch" is not updated. */ + +extern struct gdbarch *gdbarch_find_by_info (struct gdbarch_info info); + + +/* Helper function. Set the global "current_gdbarch" to "gdbarch". + + FIXME: kettenis/20031124: Of the functions that follow, only + gdbarch_from_bfd is supposed to survive. The others will + dissappear since in the future GDB will (hopefully) be truly + multi-arch. However, for now we're still stuck with the concept of + a single active architecture. */ + +extern void deprecated_current_gdbarch_select_hack (struct gdbarch *gdbarch); + /* Register per-architecture data-pointer. @@ -2481,20 +2517,17 @@ extern int gdbarch_update_p (struct gdbarch_info info); for the reserved data-pointer is returned. That identifer should be saved in a local static variable. - The per-architecture data-pointer can be initialized in one of two - ways: The value can be set explicitly using a call to - set_gdbarch_data(); the value can be set implicitly using the value - returned by a non-NULL INIT() callback. INIT(), when non-NULL is - called after the basic architecture vector has been created. + The per-architecture data-pointer is either initialized explicitly + (set_gdbarch_data()) or implicitly (by INIT() via a call to + gdbarch_data()). + + Memory for the per-architecture data shall be allocated using + gdbarch_obstack_zalloc. That memory will be deleted when the + corresponding architecture object is deleted. When a previously created architecture is re-selected, the per-architecture data-pointer for that previous architecture is - restored. INIT() is not called. - - During initialization, multiple assignments of the data-pointer are - allowed, non-NULL values are deleted by calling FREE(). If the - architecture is deleted using gdbarch_free() all non-NULL data - pointers are also deleted using FREE(). + restored. INIT() is not re-called. Multiple registrarants for any architecture are allowed (and strongly encouraged). */ @@ -2502,15 +2535,13 @@ extern int gdbarch_update_p (struct gdbarch_info info); struct gdbarch_data; typedef void *(gdbarch_data_init_ftype) (struct gdbarch *gdbarch); -typedef void (gdbarch_data_free_ftype) (struct gdbarch *gdbarch, - void *pointer); -extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init, - gdbarch_data_free_ftype *free); +extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init); extern void set_gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data, void *pointer); -extern void *gdbarch_data (struct gdbarch_data*); +extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *); + /* Register per-architecture memory region. @@ -2526,54 +2557,8 @@ extern void *gdbarch_data (struct gdbarch_data*); New code should use register_gdbarch_data(). */ typedef void (gdbarch_swap_ftype) (void); -extern void register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init); -#define REGISTER_GDBARCH_SWAP(VAR) register_gdbarch_swap (&(VAR), sizeof ((VAR)), NULL) - - - -/* The target-system-dependent byte order is dynamic */ - -extern int target_byte_order; -#ifndef TARGET_BYTE_ORDER -#define TARGET_BYTE_ORDER (target_byte_order + 0) -#endif - -extern int target_byte_order_auto; -#ifndef TARGET_BYTE_ORDER_AUTO -#define TARGET_BYTE_ORDER_AUTO (target_byte_order_auto + 0) -#endif - - - -/* The target-system-dependent BFD architecture is dynamic */ - -extern int target_architecture_auto; -#ifndef TARGET_ARCHITECTURE_AUTO -#define TARGET_ARCHITECTURE_AUTO (target_architecture_auto + 0) -#endif - -extern const struct bfd_arch_info *target_architecture; -#ifndef TARGET_ARCHITECTURE -#define TARGET_ARCHITECTURE (target_architecture + 0) -#endif - - -/* The target-system-dependent disassembler is semi-dynamic */ - -extern int dis_asm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, - unsigned int len, disassemble_info *info); - -extern void dis_asm_memory_error (int status, bfd_vma memaddr, - disassemble_info *info); - -extern void dis_asm_print_address (bfd_vma addr, - disassemble_info *info); - -extern int (*tm_print_insn) (bfd_vma, disassemble_info*); -extern disassemble_info tm_print_insn_info; -#ifndef TARGET_PRINT_INSN_INFO -#define TARGET_PRINT_INSN_INFO (&tm_print_insn_info) -#endif +extern void deprecated_register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init); +#define DEPRECATED_REGISTER_GDBARCH_SWAP(VAR) deprecated_register_gdbarch_swap (&(VAR), sizeof ((VAR)), NULL) @@ -2588,11 +2573,6 @@ extern void set_gdbarch_from_file (bfd *); extern void initialize_current_architecture (void); -/* For non-multiarched targets, do any initialization of the default - gdbarch object necessary after the _initialize_MODULE functions - have run. */ -extern void initialize_non_multiarch (); - /* gdbarch trace variable */ extern int gdbarch_debug; diff --git a/contrib/gdb/gdb/gdbarch.sh b/contrib/gdb/gdb/gdbarch.sh index 310d3c4cd7c..df3b10265cc 100755 --- a/contrib/gdb/gdb/gdbarch.sh +++ b/contrib/gdb/gdb/gdbarch.sh @@ -1,7 +1,10 @@ #!/bin/sh -u # Architecture commands for GDB, the GNU debugger. -# Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +# +# Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software +# Foundation, Inc. +# # # This file is part of GDB. # @@ -19,6 +22,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Make certain that the script is running in an internationalized +# environment. +LANG=c ; export LANG +LC_ALL=c ; export LC_ALL + + compare_new () { file=$1 @@ -79,7 +88,7 @@ EOF case "${level}" in 1 ) gt_level=">= GDB_MULTI_ARCH_PARTIAL" ;; 2 ) gt_level="> GDB_MULTI_ARCH_PARTIAL" ;; - "" ) ;; + "" ) gt_level="> GDB_MULTI_ARCH_PARTIAL" ;; * ) error "Error: bad level for ${function}" 1>&2 ; kill $$ ; exit 1 ;; esac @@ -88,9 +97,6 @@ EOF M ) staticdefault="0" ;; * ) test "${staticdefault}" || staticdefault=0 ;; esac - # NOT YET: Breaks BELIEVE_PCC_PROMOTION and confuses non- - # multi-arch defaults. - # test "${predefault}" || predefault=0 # come up with a format, use a few guesses for variables case ":${class}:${fmt}:${print}:" in @@ -109,19 +115,28 @@ EOF test "${fmt}" || fmt="%ld" test "${print}" || print="(long) ${macro}" - case "${invalid_p}" in - 0 ) valid_p=1 ;; + case "${class}" in + F | V | M ) + case "${invalid_p}" in "" ) - if [ -n "${predefault}" ] + if test -n "${predefault}" then #invalid_p="gdbarch->${function} == ${predefault}" - valid_p="gdbarch->${function} != ${predefault}" - else - #invalid_p="gdbarch->${function} == 0" - valid_p="gdbarch->${function} != 0" + predicate="gdbarch->${function} != ${predefault}" + elif class_is_variable_p + then + predicate="gdbarch->${function} != 0" + elif class_is_function_p + then + predicate="gdbarch->${function} != NULL" fi ;; - * ) valid_p="!(${invalid_p})" + * ) + echo "Predicate function ${function} with invalid_p." 1>&2 + kill $$ + exit 1 + ;; + esac esac # PREDEFAULT is a valid fallback definition of MEMBER when @@ -311,8 +326,9 @@ do # You cannot specify both a zero INVALID_P and a POSTDEFAULT. - # Variable declarations can refer to ``gdbarch'' which will - # contain the current architecture. Care should be taken. + # Variable declarations can refer to ``current_gdbarch'' which + # will contain the current architecture. Care should be + # taken. invalid_p ) : ;; @@ -375,25 +391,27 @@ function_list () i:2:TARGET_ARCHITECTURE:const struct bfd_arch_info *:bfd_arch_info::::&bfd_default_arch_struct::::%s:TARGET_ARCHITECTURE->printable_name:TARGET_ARCHITECTURE != NULL # i:2:TARGET_BYTE_ORDER:int:byte_order::::BFD_ENDIAN_BIG +# +i:2:TARGET_OSABI:enum gdb_osabi:osabi::::GDB_OSABI_UNKNOWN # Number of bits in a char or unsigned char for the target machine. # Just like CHAR_BIT in but describes the target machine. -# v::TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0: +# v:2:TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0: # # Number of bits in a short or unsigned short for the target machine. -v::TARGET_SHORT_BIT:int:short_bit::::8 * sizeof (short):2*TARGET_CHAR_BIT::0 +v:2:TARGET_SHORT_BIT:int:short_bit::::8 * sizeof (short):2*TARGET_CHAR_BIT::0 # Number of bits in an int or unsigned int for the target machine. -v::TARGET_INT_BIT:int:int_bit::::8 * sizeof (int):4*TARGET_CHAR_BIT::0 +v:2:TARGET_INT_BIT:int:int_bit::::8 * sizeof (int):4*TARGET_CHAR_BIT::0 # Number of bits in a long or unsigned long for the target machine. -v::TARGET_LONG_BIT:int:long_bit::::8 * sizeof (long):4*TARGET_CHAR_BIT::0 +v:2:TARGET_LONG_BIT:int:long_bit::::8 * sizeof (long):4*TARGET_CHAR_BIT::0 # Number of bits in a long long or unsigned long long for the target # machine. -v::TARGET_LONG_LONG_BIT:int:long_long_bit::::8 * sizeof (LONGEST):2*TARGET_LONG_BIT::0 +v:2:TARGET_LONG_LONG_BIT:int:long_long_bit::::8 * sizeof (LONGEST):2*TARGET_LONG_BIT::0 # Number of bits in a float for the target machine. -v::TARGET_FLOAT_BIT:int:float_bit::::8 * sizeof (float):4*TARGET_CHAR_BIT::0 +v:2:TARGET_FLOAT_BIT:int:float_bit::::8 * sizeof (float):4*TARGET_CHAR_BIT::0 # Number of bits in a double for the target machine. -v::TARGET_DOUBLE_BIT:int:double_bit::::8 * sizeof (double):8*TARGET_CHAR_BIT::0 +v:2:TARGET_DOUBLE_BIT:int:double_bit::::8 * sizeof (double):8*TARGET_CHAR_BIT::0 # Number of bits in a long double for the target machine. -v::TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::8 * sizeof (long double):8*TARGET_CHAR_BIT::0 +v:2:TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::8 * sizeof (long double):8*TARGET_CHAR_BIT::0 # For most targets, a pointer on the target and its representation as an # address in GDB have the same size and "look the same". For such a # target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT @@ -403,28 +421,26 @@ v::TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::8 * sizeof (long double):8*TARG # also need to set POINTER_TO_ADDRESS and ADDRESS_TO_POINTER as well. # # ptr_bit is the size of a pointer on the target -v::TARGET_PTR_BIT:int:ptr_bit::::8 * sizeof (void*):TARGET_INT_BIT::0 +v:2:TARGET_PTR_BIT:int:ptr_bit::::8 * sizeof (void*):TARGET_INT_BIT::0 # addr_bit is the size of a target address as represented in gdb -v::TARGET_ADDR_BIT:int:addr_bit::::8 * sizeof (void*):0:TARGET_PTR_BIT: +v:2:TARGET_ADDR_BIT:int:addr_bit::::8 * sizeof (void*):0:TARGET_PTR_BIT: # Number of bits in a BFD_VMA for the target object file format. -v::TARGET_BFD_VMA_BIT:int:bfd_vma_bit::::8 * sizeof (void*):TARGET_ARCHITECTURE->bits_per_address::0 +v:2:TARGET_BFD_VMA_BIT:int:bfd_vma_bit::::8 * sizeof (void*):TARGET_ARCHITECTURE->bits_per_address::0 # # One if \`char' acts like \`signed char', zero if \`unsigned char'. -v::TARGET_CHAR_SIGNED:int:char_signed::::1:-1:1:::: +v:2:TARGET_CHAR_SIGNED:int:char_signed::::1:-1:1:::: # -f::TARGET_READ_PC:CORE_ADDR:read_pc:ptid_t ptid:ptid::0:generic_target_read_pc::0 -f::TARGET_WRITE_PC:void:write_pc:CORE_ADDR val, ptid_t ptid:val, ptid::0:generic_target_write_pc::0 -f::TARGET_READ_FP:CORE_ADDR:read_fp:void:::0:generic_target_read_fp::0 -f::TARGET_WRITE_FP:void:write_fp:CORE_ADDR val:val::0:generic_target_write_fp::0 -f::TARGET_READ_SP:CORE_ADDR:read_sp:void:::0:generic_target_read_sp::0 -f::TARGET_WRITE_SP:void:write_sp:CORE_ADDR val:val::0:generic_target_write_sp::0 +F:2:TARGET_READ_PC:CORE_ADDR:read_pc:ptid_t ptid:ptid +f:2:TARGET_WRITE_PC:void:write_pc:CORE_ADDR val, ptid_t ptid:val, ptid::0:generic_target_write_pc::0 +# UNWIND_SP is a direct replacement for TARGET_READ_SP. +F:2:TARGET_READ_SP:CORE_ADDR:read_sp:void # Function for getting target's idea of a frame pointer. FIXME: GDB's # whole scheme for dealing with "frames" and "frame pointers" needs a # serious shakedown. -f::TARGET_VIRTUAL_FRAME_POINTER:void:virtual_frame_pointer:CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset:pc, frame_regnum, frame_offset::0:legacy_virtual_frame_pointer::0 +f:2:TARGET_VIRTUAL_FRAME_POINTER:void:virtual_frame_pointer:CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset:pc, frame_regnum, frame_offset::0:legacy_virtual_frame_pointer::0 # -M:::void:register_read:int regnum, char *buf:regnum, buf: -M:::void:register_write:int regnum, char *buf:regnum, buf: +M:::void:pseudo_register_read:struct regcache *regcache, int cookednum, void *buf:regcache, cookednum, buf +M:::void:pseudo_register_write:struct regcache *regcache, int cookednum, const void *buf:regcache, cookednum, buf # v:2:NUM_REGS:int:num_regs::::0:-1 # This macro gives the number of pseudo-registers that live in the @@ -432,12 +448,15 @@ v:2:NUM_REGS:int:num_regs::::0:-1 # These pseudo-registers may be aliases for other registers, # combinations of other registers, or they may be computed by GDB. v:2:NUM_PSEUDO_REGS:int:num_pseudo_regs::::0:0::0::: -v:2:SP_REGNUM:int:sp_regnum::::0:-1 -v:2:FP_REGNUM:int:fp_regnum::::0:-1 -v:2:PC_REGNUM:int:pc_regnum::::0:-1 + +# GDB's standard (or well known) register numbers. These can map onto +# a real register or a pseudo (computed) register or not be defined at +# all (-1). +# SP_REGNUM will hopefully be replaced by UNWIND_SP. +v:2:SP_REGNUM:int:sp_regnum::::-1:-1::0 +v:2:PC_REGNUM:int:pc_regnum::::-1:-1::0 +v:2:PS_REGNUM:int:ps_regnum::::-1:-1::0 v:2:FP0_REGNUM:int:fp0_regnum::::0:-1::0 -v:2:NPC_REGNUM:int:npc_regnum::::0:-1::0 -v:2:NNPC_REGNUM:int:nnpc_regnum::::0:-1::0 # Convert stab register number (from \`r\' declaration) to a gdb REGNUM. f:2:STAB_REG_TO_REGNUM:int:stab_reg_to_regnum:int stab_regnr:stab_regnr:::no_op_reg_to_regnum::0 # Provide a default mapping from a ecoff register number to a gdb REGNUM. @@ -445,132 +464,225 @@ f:2:ECOFF_REG_TO_REGNUM:int:ecoff_reg_to_regnum:int ecoff_regnr:ecoff_regnr:::no # Provide a default mapping from a DWARF register number to a gdb REGNUM. f:2:DWARF_REG_TO_REGNUM:int:dwarf_reg_to_regnum:int dwarf_regnr:dwarf_regnr:::no_op_reg_to_regnum::0 # Convert from an sdb register number to an internal gdb register number. -# This should be defined in tm.h, if REGISTER_NAMES is not set up -# to map one to one onto the sdb register numbers. f:2:SDB_REG_TO_REGNUM:int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr:::no_op_reg_to_regnum::0 f:2:DWARF2_REG_TO_REGNUM:int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr:::no_op_reg_to_regnum::0 -f:2:REGISTER_NAME:char *:register_name:int regnr:regnr:::legacy_register_name::0 -v:2:REGISTER_SIZE:int:register_size::::0:-1 -v:2:REGISTER_BYTES:int:register_bytes::::0:-1 -f:2:REGISTER_BYTE:int:register_byte:int reg_nr:reg_nr::0:0 -f:2:REGISTER_RAW_SIZE:int:register_raw_size:int reg_nr:reg_nr::generic_register_raw_size:0 -v:2:MAX_REGISTER_RAW_SIZE:int:max_register_raw_size::::0:-1 -f:2:REGISTER_VIRTUAL_SIZE:int:register_virtual_size:int reg_nr:reg_nr::generic_register_virtual_size:0 -v:2:MAX_REGISTER_VIRTUAL_SIZE:int:max_register_virtual_size::::0:-1 -f:2:REGISTER_VIRTUAL_TYPE:struct type *:register_virtual_type:int reg_nr:reg_nr::0:0 -f:2:DO_REGISTERS_INFO:void:do_registers_info:int reg_nr, int fpregs:reg_nr, fpregs:::do_registers_info::0 -f:2:PRINT_FLOAT_INFO:void:print_float_info:void::::default_print_float_info::0 +f::REGISTER_NAME:const char *:register_name:int regnr:regnr + +# REGISTER_TYPE is a direct replacement for DEPRECATED_REGISTER_VIRTUAL_TYPE. +M:2:REGISTER_TYPE:struct type *:register_type:int reg_nr:reg_nr +# REGISTER_TYPE is a direct replacement for DEPRECATED_REGISTER_VIRTUAL_TYPE. +F:2:DEPRECATED_REGISTER_VIRTUAL_TYPE:struct type *:deprecated_register_virtual_type:int reg_nr:reg_nr +# DEPRECATED_REGISTER_BYTES can be deleted. The value is computed +# from REGISTER_TYPE. +v::DEPRECATED_REGISTER_BYTES:int:deprecated_register_bytes +# If the value returned by DEPRECATED_REGISTER_BYTE agrees with the +# register offsets computed using just REGISTER_TYPE, this can be +# deleted. See: maint print registers. NOTE: cagney/2002-05-02: This +# function with predicate has a valid (callable) initial value. As a +# consequence, even when the predicate is false, the corresponding +# function works. This simplifies the migration process - old code, +# calling DEPRECATED_REGISTER_BYTE, doesn't need to be modified. +F::DEPRECATED_REGISTER_BYTE:int:deprecated_register_byte:int reg_nr:reg_nr::generic_register_byte:generic_register_byte +# If all registers have identical raw and virtual sizes and those +# sizes agree with the value computed from REGISTER_TYPE, +# DEPRECATED_REGISTER_RAW_SIZE can be deleted. See: maint print +# registers. +F:2:DEPRECATED_REGISTER_RAW_SIZE:int:deprecated_register_raw_size:int reg_nr:reg_nr::generic_register_size:generic_register_size +# If all registers have identical raw and virtual sizes and those +# sizes agree with the value computed from REGISTER_TYPE, +# DEPRECATED_REGISTER_VIRTUAL_SIZE can be deleted. See: maint print +# registers. +F:2:DEPRECATED_REGISTER_VIRTUAL_SIZE:int:deprecated_register_virtual_size:int reg_nr:reg_nr::generic_register_size:generic_register_size +# DEPRECATED_MAX_REGISTER_RAW_SIZE can be deleted. It has been +# replaced by the constant MAX_REGISTER_SIZE. +V:2:DEPRECATED_MAX_REGISTER_RAW_SIZE:int:deprecated_max_register_raw_size +# DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE can be deleted. It has been +# replaced by the constant MAX_REGISTER_SIZE. +V:2:DEPRECATED_MAX_REGISTER_VIRTUAL_SIZE:int:deprecated_max_register_virtual_size + +# See gdbint.texinfo, and PUSH_DUMMY_CALL. +M::UNWIND_DUMMY_ID:struct frame_id:unwind_dummy_id:struct frame_info *info:info +# Implement UNWIND_DUMMY_ID and PUSH_DUMMY_CALL, then delete +# SAVE_DUMMY_FRAME_TOS. +F:2:DEPRECATED_SAVE_DUMMY_FRAME_TOS:void:deprecated_save_dummy_frame_tos:CORE_ADDR sp:sp +# Implement UNWIND_DUMMY_ID and PUSH_DUMMY_CALL, then delete +# DEPRECATED_FP_REGNUM. +v:2:DEPRECATED_FP_REGNUM:int:deprecated_fp_regnum::::-1:-1::0 +# Implement UNWIND_DUMMY_ID and PUSH_DUMMY_CALL, then delete +# DEPRECATED_TARGET_READ_FP. +F::DEPRECATED_TARGET_READ_FP:CORE_ADDR:deprecated_target_read_fp:void + +# See gdbint.texinfo. See infcall.c. New, all singing all dancing, +# replacement for DEPRECATED_PUSH_ARGUMENTS. +M::PUSH_DUMMY_CALL:CORE_ADDR:push_dummy_call:CORE_ADDR func_addr, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:func_addr, regcache, bp_addr, nargs, args, sp, struct_return, struct_addr +# PUSH_DUMMY_CALL is a direct replacement for DEPRECATED_PUSH_ARGUMENTS. +F:2:DEPRECATED_PUSH_ARGUMENTS:CORE_ADDR:deprecated_push_arguments:int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:nargs, args, sp, struct_return, struct_addr +# DEPRECATED_USE_GENERIC_DUMMY_FRAMES can be deleted. Always true. +v::DEPRECATED_USE_GENERIC_DUMMY_FRAMES:int:deprecated_use_generic_dummy_frames:::::1::0 +# Implement PUSH_RETURN_ADDRESS, and then merge in +# DEPRECATED_PUSH_RETURN_ADDRESS. +F:2:DEPRECATED_PUSH_RETURN_ADDRESS:CORE_ADDR:deprecated_push_return_address:CORE_ADDR pc, CORE_ADDR sp:pc, sp +# Implement PUSH_DUMMY_CALL, then merge in DEPRECATED_DUMMY_WRITE_SP. +F:2:DEPRECATED_DUMMY_WRITE_SP:void:deprecated_dummy_write_sp:CORE_ADDR val:val +# DEPRECATED_REGISTER_SIZE can be deleted. +v::DEPRECATED_REGISTER_SIZE:int:deprecated_register_size +v::CALL_DUMMY_LOCATION:int:call_dummy_location:::::AT_ENTRY_POINT::0 +# DEPRECATED_CALL_DUMMY_START_OFFSET can be deleted. +v::DEPRECATED_CALL_DUMMY_START_OFFSET:CORE_ADDR:deprecated_call_dummy_start_offset +# DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET can be deleted. +v::DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET:CORE_ADDR:deprecated_call_dummy_breakpoint_offset +# DEPRECATED_CALL_DUMMY_LENGTH can be deleted. +v::DEPRECATED_CALL_DUMMY_LENGTH:int:deprecated_call_dummy_length +# DEPRECATED_CALL_DUMMY_WORDS can be deleted. +v::DEPRECATED_CALL_DUMMY_WORDS:LONGEST *:deprecated_call_dummy_words::::0:legacy_call_dummy_words::0:0x%08lx +# Implement PUSH_DUMMY_CALL, then delete DEPRECATED_SIZEOF_CALL_DUMMY_WORDS. +v::DEPRECATED_SIZEOF_CALL_DUMMY_WORDS:int:deprecated_sizeof_call_dummy_words::::0:legacy_sizeof_call_dummy_words::0 +# DEPRECATED_FIX_CALL_DUMMY can be deleted. For the SPARC, implement +# PUSH_DUMMY_CODE and set CALL_DUMMY_LOCATION to ON_STACK. +F::DEPRECATED_FIX_CALL_DUMMY:void:deprecated_fix_call_dummy:char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p:dummy, pc, fun, nargs, args, type, gcc_p +# This is a replacement for DEPRECATED_FIX_CALL_DUMMY et.al. +M::PUSH_DUMMY_CODE:CORE_ADDR:push_dummy_code:CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, struct value **args, int nargs, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr:sp, funaddr, using_gcc, args, nargs, value_type, real_pc, bp_addr +# Implement PUSH_DUMMY_CALL, then delete DEPRECATED_PUSH_DUMMY_FRAME. +F:2:DEPRECATED_PUSH_DUMMY_FRAME:void:deprecated_push_dummy_frame:void:- + +F:2:DEPRECATED_DO_REGISTERS_INFO:void:deprecated_do_registers_info:int reg_nr, int fpregs:reg_nr, fpregs +m:2:PRINT_REGISTERS_INFO:void:print_registers_info:struct ui_file *file, struct frame_info *frame, int regnum, int all:file, frame, regnum, all:::default_print_registers_info::0 +M:2:PRINT_FLOAT_INFO:void:print_float_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args +M:2:PRINT_VECTOR_INFO:void:print_vector_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args # MAP a GDB RAW register number onto a simulator register number. See # also include/...-sim.h. -f:2:REGISTER_SIM_REGNO:int:register_sim_regno:int reg_nr:reg_nr:::default_register_sim_regno::0 -F:2:REGISTER_BYTES_OK:int:register_bytes_ok:long nr_bytes:nr_bytes::0:0 +f:2:REGISTER_SIM_REGNO:int:register_sim_regno:int reg_nr:reg_nr:::legacy_register_sim_regno::0 +F:2:REGISTER_BYTES_OK:int:register_bytes_ok:long nr_bytes:nr_bytes f:2:CANNOT_FETCH_REGISTER:int:cannot_fetch_register:int regnum:regnum:::cannot_register_not::0 f:2:CANNOT_STORE_REGISTER:int:cannot_store_register:int regnum:regnum:::cannot_register_not::0 # setjmp/longjmp support. -F:2:GET_LONGJMP_TARGET:int:get_longjmp_target:CORE_ADDR *pc:pc::0:0 -# -# Non multi-arch DUMMY_FRAMES are a mess (multi-arch ones are not that -# much better but at least they are vaguely consistent). The headers -# and body contain convoluted #if/#else sequences for determine how -# things should be compiled. Instead of trying to mimic that -# behaviour here (and hence entrench it further) gdbarch simply -# reqires that these methods be set up from the word go. This also -# avoids any potential problems with moving beyond multi-arch partial. -v:1:USE_GENERIC_DUMMY_FRAMES:int:use_generic_dummy_frames::::0:-1 -v:1:CALL_DUMMY_LOCATION:int:call_dummy_location::::0:0 -f:2:CALL_DUMMY_ADDRESS:CORE_ADDR:call_dummy_address:void:::0:0::gdbarch->call_dummy_location == AT_ENTRY_POINT && gdbarch->call_dummy_address == 0 -v:2:CALL_DUMMY_START_OFFSET:CORE_ADDR:call_dummy_start_offset::::0:-1:::0x%08lx -v:2:CALL_DUMMY_BREAKPOINT_OFFSET:CORE_ADDR:call_dummy_breakpoint_offset::::0:-1::gdbarch->call_dummy_breakpoint_offset_p && gdbarch->call_dummy_breakpoint_offset == -1:0x%08lx::CALL_DUMMY_BREAKPOINT_OFFSET_P -v:1:CALL_DUMMY_BREAKPOINT_OFFSET_P:int:call_dummy_breakpoint_offset_p::::0:-1 -v:2:CALL_DUMMY_LENGTH:int:call_dummy_length::::0:-1:::::CALL_DUMMY_LOCATION == BEFORE_TEXT_END || CALL_DUMMY_LOCATION == AFTER_TEXT_END -f:1:PC_IN_CALL_DUMMY:int:pc_in_call_dummy:CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address:pc, sp, frame_address::0:0 -v:1:CALL_DUMMY_P:int:call_dummy_p::::0:-1 -v:2:CALL_DUMMY_WORDS:LONGEST *:call_dummy_words::::0:legacy_call_dummy_words::0:0x%08lx -v:2:SIZEOF_CALL_DUMMY_WORDS:int:sizeof_call_dummy_words::::0:legacy_sizeof_call_dummy_words::0:0x%08lx -v:1:CALL_DUMMY_STACK_ADJUST_P:int:call_dummy_stack_adjust_p::::0:-1:::0x%08lx -v:2:CALL_DUMMY_STACK_ADJUST:int:call_dummy_stack_adjust::::0:::gdbarch->call_dummy_stack_adjust_p && gdbarch->call_dummy_stack_adjust == 0:0x%08lx::CALL_DUMMY_STACK_ADJUST_P -f:2:FIX_CALL_DUMMY:void:fix_call_dummy:char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p:dummy, pc, fun, nargs, args, type, gcc_p:::0 -f:2:INIT_FRAME_PC_FIRST:void:init_frame_pc_first:int fromleaf, struct frame_info *prev:fromleaf, prev:::init_frame_pc_noop::0 -f:2:INIT_FRAME_PC:void:init_frame_pc:int fromleaf, struct frame_info *prev:fromleaf, prev:::init_frame_pc_default::0 +F:2:GET_LONGJMP_TARGET:int:get_longjmp_target:CORE_ADDR *pc:pc +# NOTE: cagney/2002-11-24: This function with predicate has a valid +# (callable) initial value. As a consequence, even when the predicate +# is false, the corresponding function works. This simplifies the +# migration process - old code, calling DEPRECATED_PC_IN_CALL_DUMMY(), +# doesn't need to be modified. +F::DEPRECATED_PC_IN_CALL_DUMMY:int:deprecated_pc_in_call_dummy:CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address:pc, sp, frame_address::generic_pc_in_call_dummy:generic_pc_in_call_dummy +F:2:DEPRECATED_INIT_FRAME_PC_FIRST:CORE_ADDR:deprecated_init_frame_pc_first:int fromleaf, struct frame_info *prev:fromleaf, prev +F:2:DEPRECATED_INIT_FRAME_PC:CORE_ADDR:deprecated_init_frame_pc:int fromleaf, struct frame_info *prev:fromleaf, prev # v:2:BELIEVE_PCC_PROMOTION:int:believe_pcc_promotion::::::: -v:2:BELIEVE_PCC_PROMOTION_TYPE:int:believe_pcc_promotion_type::::::: -f:2:COERCE_FLOAT_TO_DOUBLE:int:coerce_float_to_double:struct type *formal, struct type *actual:formal, actual:::default_coerce_float_to_double::0 -# GET_SAVED_REGISTER is like DUMMY_FRAMES. It is at level one as the -# old code has strange #ifdef interaction. So far no one has found -# that default_get_saved_register() is the default they are after. -f:1:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval::generic_get_saved_register:0 +v::BELIEVE_PCC_PROMOTION_TYPE:int:believe_pcc_promotion_type::::::: +F:2:DEPRECATED_GET_SAVED_REGISTER:void:deprecated_get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval # -f:2:REGISTER_CONVERTIBLE:int:register_convertible:int nr:nr:::generic_register_convertible_not::0 -f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0 -f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, char *from, char *to:type, regnum, from, to:::0::0 -# This function is called when the value of a pseudo-register needs to -# be updated. Typically it will be defined on a per-architecture -# basis. -F:2:FETCH_PSEUDO_REGISTER:void:fetch_pseudo_register:int regnum:regnum: -# This function is called when the value of a pseudo-register needs to -# be set or stored. Typically it will be defined on a -# per-architecture basis. -F:2:STORE_PSEUDO_REGISTER:void:store_pseudo_register:int regnum:regnum: +# For register <-> value conversions, replaced by CONVERT_REGISTER_P et.al. +# For raw <-> cooked register conversions, replaced by pseudo registers. +F::DEPRECATED_REGISTER_CONVERTIBLE:int:deprecated_register_convertible:int nr:nr +# For register <-> value conversions, replaced by CONVERT_REGISTER_P et.al. +# For raw <-> cooked register conversions, replaced by pseudo registers. +f:2:DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL:void:deprecated_register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0 +# For register <-> value conversions, replaced by CONVERT_REGISTER_P et.al. +# For raw <-> cooked register conversions, replaced by pseudo registers. +f:2:DEPRECATED_REGISTER_CONVERT_TO_RAW:void:deprecated_register_convert_to_raw:struct type *type, int regnum, const char *from, char *to:type, regnum, from, to:::0::0 # -f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, void *buf:type, buf:::unsigned_pointer_to_address::0 +f:1:CONVERT_REGISTER_P:int:convert_register_p:int regnum, struct type *type:regnum, type::0:legacy_convert_register_p::0 +f:1:REGISTER_TO_VALUE:void:register_to_value:struct frame_info *frame, int regnum, struct type *type, void *buf:frame, regnum, type, buf::0:legacy_register_to_value::0 +f:1:VALUE_TO_REGISTER:void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const void *buf:frame, regnum, type, buf::0:legacy_value_to_register::0 +# +f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, const void *buf:type, buf:::unsigned_pointer_to_address::0 f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0 F:2:INTEGER_TO_ADDRESS:CORE_ADDR:integer_to_address:struct type *type, void *buf:type, buf # +F:2:DEPRECATED_POP_FRAME:void:deprecated_pop_frame:void:- +# NOTE: cagney/2003-03-24: Replaced by PUSH_ARGUMENTS. +F:2:DEPRECATED_STORE_STRUCT_RETURN:void:deprecated_store_struct_return:CORE_ADDR addr, CORE_ADDR sp:addr, sp + +# It has been suggested that this, well actually its predecessor, +# should take the type/value of the function to be called and not the +# return type. This is left as an exercise for the reader. + +M:::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf:valtype, regcache, readbuf, writebuf + +# The deprecated methods RETURN_VALUE_ON_STACK, EXTRACT_RETURN_VALUE, +# STORE_RETURN_VALUE and USE_STRUCT_CONVENTION have all been folded +# into RETURN_VALUE. + f:2:RETURN_VALUE_ON_STACK:int:return_value_on_stack:struct type *type:type:::generic_return_value_on_stack_not::0 -f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf::0:0 -f:2:PUSH_ARGUMENTS:CORE_ADDR:push_arguments:int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:nargs, args, sp, struct_return, struct_addr:::default_push_arguments::0 -f:2:PUSH_DUMMY_FRAME:void:push_dummy_frame:void:-:::0 -F:2:PUSH_RETURN_ADDRESS:CORE_ADDR:push_return_address:CORE_ADDR pc, CORE_ADDR sp:pc, sp:::0 -f:2:POP_FRAME:void:pop_frame:void:-:::0 -# -f:2:STORE_STRUCT_RETURN:void:store_struct_return:CORE_ADDR addr, CORE_ADDR sp:addr, sp:::0 -f:2:STORE_RETURN_VALUE:void:store_return_value:struct type *type, char *valbuf:type, valbuf:::0 -F:2:EXTRACT_STRUCT_VALUE_ADDRESS:CORE_ADDR:extract_struct_value_address:char *regbuf:regbuf:::0 +f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, struct regcache *regcache, void *valbuf:type, regcache, valbuf:::legacy_extract_return_value::0 +f:2:STORE_RETURN_VALUE:void:store_return_value:struct type *type, struct regcache *regcache, const void *valbuf:type, regcache, valbuf:::legacy_store_return_value::0 +f:2:DEPRECATED_EXTRACT_RETURN_VALUE:void:deprecated_extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf +f:2:DEPRECATED_STORE_RETURN_VALUE:void:deprecated_store_return_value:struct type *type, char *valbuf:type, valbuf f:2:USE_STRUCT_CONVENTION:int:use_struct_convention:int gcc_p, struct type *value_type:gcc_p, value_type:::generic_use_struct_convention::0 -# -f:2:FRAME_INIT_SAVED_REGS:void:frame_init_saved_regs:struct frame_info *frame:frame::0:0 -F:2:INIT_EXTRA_FRAME_INFO:void:init_extra_frame_info:int fromleaf, struct frame_info *frame:fromleaf, frame:::0 + +# As of 2004-01-17 only the 32-bit SPARC ABI has been identified as an +# ABI suitable for the implementation of a robust extract +# struct-convention return-value address method (the sparc saves the +# address in the callers frame). All the other cases so far examined, +# the DEPRECATED_EXTRACT_STRUCT_VALUE implementation has been +# erreneous - the code was incorrectly assuming that the return-value +# address, stored in a register, was preserved across the entire +# function call. + +# For the moment retain DEPRECATED_EXTRACT_STRUCT_VALUE as a marker of +# the ABIs that are still to be analyzed - perhaps this should simply +# be deleted. The commented out extract_returned_value_address method +# is provided as a starting point for the 32-bit SPARC. It, or +# something like it, along with changes to both infcmd.c and stack.c +# will be needed for that case to work. NB: It is passed the callers +# frame since it is only after the callee has returned that this +# function is used. + +#M:::CORE_ADDR:extract_returned_value_address:struct frame_info *caller_frame:caller_frame +F:2:DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS:CORE_ADDR:deprecated_extract_struct_value_address:struct regcache *regcache:regcache + +F:2:DEPRECATED_FRAME_INIT_SAVED_REGS:void:deprecated_frame_init_saved_regs:struct frame_info *frame:frame +F:2:DEPRECATED_INIT_EXTRA_FRAME_INFO:void:deprecated_init_extra_frame_info:int fromleaf, struct frame_info *frame:fromleaf, frame # f:2:SKIP_PROLOGUE:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip::0:0 -f:2:PROLOGUE_FRAMELESS_P:int:prologue_frameless_p:CORE_ADDR ip:ip::0:generic_prologue_frameless_p::0 f:2:INNER_THAN:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs::0:0 -f:2:BREAKPOINT_FROM_PC:unsigned char *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr:::legacy_breakpoint_from_pc::0 +f::BREAKPOINT_FROM_PC:const unsigned char *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr:::0: +M:2:ADJUST_BREAKPOINT_ADDRESS:CORE_ADDR:adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr f:2:MEMORY_INSERT_BREAKPOINT:int:memory_insert_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_insert_breakpoint::0 f:2:MEMORY_REMOVE_BREAKPOINT:int:memory_remove_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_remove_breakpoint::0 -v:2:DECR_PC_AFTER_BREAK:CORE_ADDR:decr_pc_after_break::::0:-1 -f::PREPARE_TO_PROCEED:int:prepare_to_proceed:int select_it:select_it::0:default_prepare_to_proceed::0 -v:2:FUNCTION_START_OFFSET:CORE_ADDR:function_start_offset::::0:-1 +v:2:DECR_PC_AFTER_BREAK:CORE_ADDR:decr_pc_after_break::::0:::0 +v:2:FUNCTION_START_OFFSET:CORE_ADDR:function_start_offset::::0:::0 # -f:2:REMOTE_TRANSLATE_XFER_ADDRESS:void:remote_translate_xfer_address:CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len:gdb_addr, gdb_len, rem_addr, rem_len:::generic_remote_translate_xfer_address::0 +m::REMOTE_TRANSLATE_XFER_ADDRESS:void:remote_translate_xfer_address:struct regcache *regcache, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len:regcache, gdb_addr, gdb_len, rem_addr, rem_len:::generic_remote_translate_xfer_address::0 # -v:2:FRAME_ARGS_SKIP:CORE_ADDR:frame_args_skip::::0:-1 -f:2:FRAMELESS_FUNCTION_INVOCATION:int:frameless_function_invocation:struct frame_info *fi:fi:::generic_frameless_function_invocation_not::0 -f:2:FRAME_CHAIN:CORE_ADDR:frame_chain:struct frame_info *frame:frame::0:0 -# Define a default FRAME_CHAIN_VALID, in the form that is suitable for -# most targets. If FRAME_CHAIN_VALID returns zero it means that the -# given frame is the outermost one and has no caller. +v::FRAME_ARGS_SKIP:CORE_ADDR:frame_args_skip::::0:::0 +# DEPRECATED_FRAMELESS_FUNCTION_INVOCATION is not needed. The new +# frame code works regardless of the type of frame - frameless, +# stackless, or normal. +F::DEPRECATED_FRAMELESS_FUNCTION_INVOCATION:int:deprecated_frameless_function_invocation:struct frame_info *fi:fi +F:2:DEPRECATED_FRAME_CHAIN:CORE_ADDR:deprecated_frame_chain:struct frame_info *frame:frame +F:2:DEPRECATED_FRAME_CHAIN_VALID:int:deprecated_frame_chain_valid:CORE_ADDR chain, struct frame_info *thisframe:chain, thisframe +# DEPRECATED_FRAME_SAVED_PC has been replaced by UNWIND_PC. Please +# note, per UNWIND_PC's doco, that while the two have similar +# interfaces they have very different underlying implementations. +F:2:DEPRECATED_FRAME_SAVED_PC:CORE_ADDR:deprecated_frame_saved_pc:struct frame_info *fi:fi +M::UNWIND_PC:CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame +M::UNWIND_SP:CORE_ADDR:unwind_sp:struct frame_info *next_frame:next_frame +# DEPRECATED_FRAME_ARGS_ADDRESS as been replaced by the per-frame +# frame-base. Enable frame-base before frame-unwind. +F::DEPRECATED_FRAME_ARGS_ADDRESS:CORE_ADDR:deprecated_frame_args_address:struct frame_info *fi:fi::get_frame_base:get_frame_base +# DEPRECATED_FRAME_LOCALS_ADDRESS as been replaced by the per-frame +# frame-base. Enable frame-base before frame-unwind. +F::DEPRECATED_FRAME_LOCALS_ADDRESS:CORE_ADDR:deprecated_frame_locals_address:struct frame_info *fi:fi::get_frame_base:get_frame_base +F::DEPRECATED_SAVED_PC_AFTER_CALL:CORE_ADDR:deprecated_saved_pc_after_call:struct frame_info *frame:frame +F:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame # -# XXXX - both default and alternate frame_chain_valid functions are -# deprecated. New code should use dummy frames and one of the generic -# functions. -f:2:FRAME_CHAIN_VALID:int:frame_chain_valid:CORE_ADDR chain, struct frame_info *thisframe:chain, thisframe:::func_frame_chain_valid::0 -f:2:FRAME_SAVED_PC:CORE_ADDR:frame_saved_pc:struct frame_info *fi:fi::0:0 -f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:0 -f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:0 -f:2:SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame::0:0 -f:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame::0:0 -# -F:2:STACK_ALIGN:CORE_ADDR:stack_align:CORE_ADDR sp:sp::0:0 -v:2:EXTRA_STACK_ALIGNMENT_NEEDED:int:extra_stack_alignment_needed::::0:1::0::: -F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type::0:0 -F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0 +# DEPRECATED_STACK_ALIGN has been replaced by an initial aligning call +# to frame_align and the requirement that methods such as +# push_dummy_call and frame_red_zone_size maintain correct stack/frame +# alignment. +F:2:DEPRECATED_STACK_ALIGN:CORE_ADDR:deprecated_stack_align:CORE_ADDR sp:sp +M:::CORE_ADDR:frame_align:CORE_ADDR address:address +# DEPRECATED_REG_STRUCT_HAS_ADDR has been replaced by +# stabs_argument_has_addr. +F:2:DEPRECATED_REG_STRUCT_HAS_ADDR:int:deprecated_reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type +m:::int:stabs_argument_has_addr:struct type *type:type:::default_stabs_argument_has_addr::0 +v::FRAME_RED_ZONE_SIZE:int:frame_red_zone_size v:2:PARM_BOUNDARY:int:parm_boundary # -v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch) -v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch) -v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::default_double_format (gdbarch) -f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::core_addr_identity::0 +v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (current_gdbarch)::%s:(TARGET_FLOAT_FORMAT)->name +v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (current_gdbarch)::%s:(TARGET_DOUBLE_FORMAT)->name +v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::default_double_format (current_gdbarch)::%s:(TARGET_LONG_DOUBLE_FORMAT)->name +m:::CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr, struct target_ops *targ:addr, targ:::convert_from_func_ptr_addr_identity::0 # 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. # for special purposes. ADDR_BITS_REMOVE takes out any such bits so @@ -581,7 +693,7 @@ f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR ad # sort of generic thing to handle alignment or segmentation (it's # possible it should be in TARGET_READ_PC instead). f:2:ADDR_BITS_REMOVE:CORE_ADDR:addr_bits_remove:CORE_ADDR addr:addr:::core_addr_identity::0 -# It is not at all clear why SMASH_TEXT_ADDRESS is not folded into +# It is not at all clear why SMASH_TEXT_ADDRESS is not folded into # ADDR_BITS_REMOVE. f:2:SMASH_TEXT_ADDRESS:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr:::core_addr_identity::0 # FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if @@ -592,13 +704,48 @@ f:2:SMASH_TEXT_ADDRESS:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr:::core_a # # FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can # single step. If not, then implement single step using breakpoints. -F:2:SOFTWARE_SINGLE_STEP:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p::0:0 -f:2:TARGET_PRINT_INSN:int:print_insn:bfd_vma vma, disassemble_info *info:vma, info:::legacy_print_insn::0 +F:2:SOFTWARE_SINGLE_STEP:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p +# FIXME: cagney/2003-08-28: Need to find a better way of selecting the +# disassembler. Perhaphs objdump can handle it? +f::TARGET_PRINT_INSN:int:print_insn:bfd_vma vma, struct disassemble_info *info:vma, info:::0: f:2:SKIP_TRAMPOLINE_CODE:CORE_ADDR:skip_trampoline_code:CORE_ADDR pc:pc:::generic_skip_trampoline_code::0 + + +# If IN_SOLIB_DYNSYM_RESOLVE_CODE returns true, and SKIP_SOLIB_RESOLVER +# evaluates non-zero, this is the address where the debugger will place +# a step-resume breakpoint to get us past the dynamic linker. +m:2:SKIP_SOLIB_RESOLVER:CORE_ADDR:skip_solib_resolver:CORE_ADDR pc:pc:::generic_skip_solib_resolver::0 # For SVR4 shared libraries, each call goes through a small piece of # trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates -# to nonzero if we are current stopped in one of these. +# to nonzero if we are currently stopped in one of these. f:2:IN_SOLIB_CALL_TRAMPOLINE:int:in_solib_call_trampoline:CORE_ADDR pc, char *name:pc, name:::generic_in_solib_call_trampoline::0 + +# Some systems also have trampoline code for returning from shared libs. +f:2:IN_SOLIB_RETURN_TRAMPOLINE:int:in_solib_return_trampoline:CORE_ADDR pc, char *name:pc, name:::generic_in_solib_return_trampoline::0 + +# Sigtramp is a routine that the kernel calls (which then calls the +# signal handler). On most machines it is a library routine that is +# linked into the executable. +# +# This macro, given a program counter value and the name of the +# function in which that PC resides (which can be null if the name is +# not known), returns nonzero if the PC and name show that we are in +# sigtramp. +# +# On most machines just see if the name is sigtramp (and if we have +# no name, assume we are not in sigtramp). +# +# FIXME: cagney/2002-04-21: The function find_pc_partial_function +# calls find_pc_sect_partial_function() which calls PC_IN_SIGTRAMP. +# This means PC_IN_SIGTRAMP function can't be implemented by doing its +# own local NAME lookup. +# +# FIXME: cagney/2002-04-21: PC_IN_SIGTRAMP is something of a mess. +# Some code also depends on SIGTRAMP_START and SIGTRAMP_END but other +# does not. +f:2:PC_IN_SIGTRAMP:int:pc_in_sigtramp:CORE_ADDR pc, char *name:pc, name:::legacy_pc_in_sigtramp::0 +F:2:SIGTRAMP_START:CORE_ADDR:sigtramp_start:CORE_ADDR pc:pc +F:2:SIGTRAMP_END:CORE_ADDR:sigtramp_end:CORE_ADDR pc:pc # A target might have problems with watchpoints as soon as the stack # frame of the current function has been destroyed. This mostly happens # as the first action in a funtion's epilogue. in_function_epilogue_p() @@ -618,9 +765,22 @@ m:::int:in_function_epilogue_p:CORE_ADDR addr:addr::0:generic_in_function_epilog # ARGC is the number of elements in the vector. # ARGV is an array of strings, one per argument. m::CONSTRUCT_INFERIOR_ARGUMENTS:char *:construct_inferior_arguments:int argc, char **argv:argc, argv:::construct_inferior_arguments::0 -F:2:DWARF2_BUILD_FRAME_INFO:void:dwarf2_build_frame_info:struct objfile *objfile:objfile:::0 f:2:ELF_MAKE_MSYMBOL_SPECIAL:void:elf_make_msymbol_special:asymbol *sym, struct minimal_symbol *msym:sym, msym:::default_elf_make_msymbol_special::0 f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_make_msymbol_special:int val, struct minimal_symbol *msym:val, msym:::default_coff_make_msymbol_special::0 +v:2:NAME_OF_MALLOC:const char *:name_of_malloc::::"malloc":"malloc"::0:%s:NAME_OF_MALLOC +v:2:CANNOT_STEP_BREAKPOINT:int:cannot_step_breakpoint::::0:0::0 +v:2:HAVE_NONSTEPPABLE_WATCHPOINT:int:have_nonsteppable_watchpoint::::0:0::0 +F:2:ADDRESS_CLASS_TYPE_FLAGS:int:address_class_type_flags:int byte_size, int dwarf2_addr_class:byte_size, dwarf2_addr_class +M:2:ADDRESS_CLASS_TYPE_FLAGS_TO_NAME:const char *:address_class_type_flags_to_name:int type_flags:type_flags +M:2:ADDRESS_CLASS_NAME_TO_TYPE_FLAGS:int:address_class_name_to_type_flags:const char *name, int *type_flags_ptr:name, type_flags_ptr +# Is a register in a group +m:::int:register_reggroup_p:int regnum, struct reggroup *reggroup:regnum, reggroup:::default_register_reggroup_p::0 +# Fetch the pointer to the ith function argument. +F::FETCH_POINTER_ARGUMENT:CORE_ADDR:fetch_pointer_argument:struct frame_info *frame, int argi, struct type *type:frame, argi, type + +# Return the appropriate register set for a core file section with +# name SECT_NAME and size SECT_SIZE. +M:::const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size EOF } @@ -638,9 +798,6 @@ EOF do eval echo \"\ \ \ \ ${r}=\${${r}}\" done -# #fallbackdefault=${fallbackdefault} -# #valid_p=${valid_p} -#EOF if class_is_predicate_p && fallback_default_p then echo "Error: predicate function ${macro} can not have a non- multi-arch default" 1>&2 @@ -676,7 +833,9 @@ cat <= GDB_MULTI_ARCH_PURE) && defined (GDB_TM_FILE) #error "GDB_TM_FILE: Pure multi-arch targets do not have a tm.h file." #endif @@ -767,11 +916,9 @@ do printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro})\n" printf "#error \"Non multi-arch definition of ${macro}\"\n" printf "#endif\n" - printf "#if GDB_MULTI_ARCH\n" - printf "#if (GDB_MULTI_ARCH ${gt_level}) || !defined (${macro})\n" + printf "#if !defined (${macro})\n" printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n" printf "#endif\n" - printf "#endif\n" fi done @@ -807,11 +954,6 @@ do printf "#endif\n" printf "#endif\n" printf "\n" - printf "/* Default predicate for non- multi-arch targets. */\n" - printf "#if (!GDB_MULTI_ARCH) && !defined (${macro}_P)\n" - printf "#define ${macro}_P() (0)\n" - printf "#endif\n" - printf "\n" printf "extern int gdbarch_${function}_p (struct gdbarch *gdbarch);\n" printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro}_P)\n" printf "#error \"Non multi-arch definition of ${macro}\"\n" @@ -823,45 +965,18 @@ do fi if class_is_variable_p then - if fallback_default_p || class_is_predicate_p - then - printf "\n" - printf "/* Default (value) for non- multi-arch platforms. */\n" - printf "#if (!GDB_MULTI_ARCH) && !defined (${macro})\n" - echo "#define ${macro} (${fallbackdefault})" \ - | sed -e 's/\([^a-z_]\)\(gdbarch[^a-z_]\)/\1current_\2/g' - printf "#endif\n" - fi printf "\n" printf "extern ${returntype} gdbarch_${function} (struct gdbarch *gdbarch);\n" printf "extern void set_gdbarch_${function} (struct gdbarch *gdbarch, ${returntype} ${function});\n" printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro})\n" printf "#error \"Non multi-arch definition of ${macro}\"\n" printf "#endif\n" - printf "#if GDB_MULTI_ARCH\n" - printf "#if (GDB_MULTI_ARCH ${gt_level}) || !defined (${macro})\n" + printf "#if !defined (${macro})\n" printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n" printf "#endif\n" - printf "#endif\n" fi if class_is_function_p then - if class_is_multiarch_p ; then : - elif fallback_default_p || class_is_predicate_p - then - printf "\n" - printf "/* Default (function) for non- multi-arch platforms. */\n" - printf "#if (!GDB_MULTI_ARCH) && !defined (${macro})\n" - if [ "x${fallbackdefault}" = "x0" ] - then - printf "#define ${macro}(${actual}) (internal_error (__FILE__, __LINE__, \"${macro}\"), 0)\n" - else - # FIXME: Should be passing current_gdbarch through! - echo "#define ${macro}(${actual}) (${fallbackdefault} (${actual}))" \ - | sed -e 's/\([^a-z_]\)\(gdbarch[^a-z_]\)/\1current_\2/g' - fi - printf "#endif\n" - fi printf "\n" if [ "x${formal}" = "xvoid" ] && class_is_multiarch_p then @@ -884,8 +999,16 @@ do printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro})\n" printf "#error \"Non multi-arch definition of ${macro}\"\n" printf "#endif\n" - printf "#if GDB_MULTI_ARCH\n" - printf "#if (GDB_MULTI_ARCH ${gt_level}) || !defined (${macro})\n" + if [ "x${actual}" = "x" ] + then + d="#define ${macro}() (gdbarch_${function} (current_gdbarch))" + elif [ "x${actual}" = "x-" ] + then + d="#define ${macro} (gdbarch_${function} (current_gdbarch))" + else + d="#define ${macro}(${actual}) (gdbarch_${function} (current_gdbarch, ${actual}))" + fi + printf "#if !defined (${macro})\n" if [ "x${actual}" = "x" ] then printf "#define ${macro}() (gdbarch_${function} (current_gdbarch))\n" @@ -896,7 +1019,6 @@ do printf "#define ${macro}(${actual}) (gdbarch_${function} (current_gdbarch, ${actual}))\n" fi printf "#endif\n" - printf "#endif\n" fi fi done @@ -944,9 +1066,16 @@ extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); architecture; ARCHES which is a list of the previously created \`\`struct gdbarch'' for this architecture. - The INIT function parameter INFO shall, as far as possible, be - pre-initialized with information obtained from INFO.ABFD or - previously selected architecture (if similar). + The INFO parameter is, as far as possible, be pre-initialized with + information obtained from INFO.ABFD or the previously selected + architecture. + + The ARCHES parameter is a linked list (sorted most recently used) + of all the previously created architures for this architecture + family. The (possibly NULL) ARCHES->gdbarch can used to access + values from the previously selected architecture for this + architecture family. The global \`\`current_gdbarch'' shall not be + used. The INIT function shall return any of: NULL - indicating that it doesn't recognize the selected architecture; an existing \`\`struct @@ -978,6 +1107,9 @@ struct gdbarch_info /* Use default: NULL (ZERO). */ struct gdbarch_tdep_info *tdep_info; + + /* Use default: GDB_OSABI_UNINITIALIZED (-1). */ + enum gdb_osabi osabi; }; typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches); @@ -1020,6 +1152,15 @@ extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gd extern void gdbarch_free (struct gdbarch *); +/* Helper function. Allocate memory from the \`\`struct gdbarch'' + obstack. The memory is freed when the corresponding architecture + is also freed. */ + +extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size); +#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE))) +#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE))) + + /* Helper function. Force an update of the current architecture. The actual architecture selected is determined by INFO, \`\`(gdb) set @@ -1032,6 +1173,27 @@ extern void gdbarch_free (struct gdbarch *); extern int gdbarch_update_p (struct gdbarch_info info); +/* Helper function. Find an architecture matching info. + + INFO should be initialized using gdbarch_info_init, relevant fields + set, and then finished using gdbarch_info_fill. + + Returns the corresponding architecture, or NULL if no matching + architecture was found. "current_gdbarch" is not updated. */ + +extern struct gdbarch *gdbarch_find_by_info (struct gdbarch_info info); + + +/* Helper function. Set the global "current_gdbarch" to "gdbarch". + + FIXME: kettenis/20031124: Of the functions that follow, only + gdbarch_from_bfd is supposed to survive. The others will + dissappear since in the future GDB will (hopefully) be truly + multi-arch. However, for now we're still stuck with the concept of + a single active architecture. */ + +extern void deprecated_current_gdbarch_select_hack (struct gdbarch *gdbarch); + /* Register per-architecture data-pointer. @@ -1039,20 +1201,17 @@ extern int gdbarch_update_p (struct gdbarch_info info); for the reserved data-pointer is returned. That identifer should be saved in a local static variable. - The per-architecture data-pointer can be initialized in one of two - ways: The value can be set explicitly using a call to - set_gdbarch_data(); the value can be set implicitly using the value - returned by a non-NULL INIT() callback. INIT(), when non-NULL is - called after the basic architecture vector has been created. + The per-architecture data-pointer is either initialized explicitly + (set_gdbarch_data()) or implicitly (by INIT() via a call to + gdbarch_data()). + + Memory for the per-architecture data shall be allocated using + gdbarch_obstack_zalloc. That memory will be deleted when the + corresponding architecture object is deleted. When a previously created architecture is re-selected, the per-architecture data-pointer for that previous architecture is - restored. INIT() is not called. - - During initialization, multiple assignments of the data-pointer are - allowed, non-NULL values are deleted by calling FREE(). If the - architecture is deleted using gdbarch_free() all non-NULL data - pointers are also deleted using FREE(). + restored. INIT() is not re-called. Multiple registrarants for any architecture are allowed (and strongly encouraged). */ @@ -1060,15 +1219,13 @@ extern int gdbarch_update_p (struct gdbarch_info info); struct gdbarch_data; typedef void *(gdbarch_data_init_ftype) (struct gdbarch *gdbarch); -typedef void (gdbarch_data_free_ftype) (struct gdbarch *gdbarch, - void *pointer); -extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init, - gdbarch_data_free_ftype *free); +extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init); extern void set_gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data, void *pointer); -extern void *gdbarch_data (struct gdbarch_data*); +extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *); + /* Register per-architecture memory region. @@ -1084,54 +1241,8 @@ extern void *gdbarch_data (struct gdbarch_data*); New code should use register_gdbarch_data(). */ typedef void (gdbarch_swap_ftype) (void); -extern void register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init); -#define REGISTER_GDBARCH_SWAP(VAR) register_gdbarch_swap (&(VAR), sizeof ((VAR)), NULL) - - - -/* The target-system-dependent byte order is dynamic */ - -extern int target_byte_order; -#ifndef TARGET_BYTE_ORDER -#define TARGET_BYTE_ORDER (target_byte_order + 0) -#endif - -extern int target_byte_order_auto; -#ifndef TARGET_BYTE_ORDER_AUTO -#define TARGET_BYTE_ORDER_AUTO (target_byte_order_auto + 0) -#endif - - - -/* The target-system-dependent BFD architecture is dynamic */ - -extern int target_architecture_auto; -#ifndef TARGET_ARCHITECTURE_AUTO -#define TARGET_ARCHITECTURE_AUTO (target_architecture_auto + 0) -#endif - -extern const struct bfd_arch_info *target_architecture; -#ifndef TARGET_ARCHITECTURE -#define TARGET_ARCHITECTURE (target_architecture + 0) -#endif - - -/* The target-system-dependent disassembler is semi-dynamic */ - -extern int dis_asm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, - unsigned int len, disassemble_info *info); - -extern void dis_asm_memory_error (int status, bfd_vma memaddr, - disassemble_info *info); - -extern void dis_asm_print_address (bfd_vma addr, - disassemble_info *info); - -extern int (*tm_print_insn) (bfd_vma, disassemble_info*); -extern disassemble_info tm_print_insn_info; -#ifndef TARGET_PRINT_INSN_INFO -#define TARGET_PRINT_INSN_INFO (&tm_print_insn_info) -#endif +extern void deprecated_register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init); +#define DEPRECATED_REGISTER_GDBARCH_SWAP(VAR) deprecated_register_gdbarch_swap (&(VAR), sizeof ((VAR)), NULL) @@ -1146,11 +1257,6 @@ extern void set_gdbarch_from_file (bfd *); extern void initialize_current_architecture (void); -/* For non-multiarched targets, do any initialization of the default - gdbarch object necessary after the _initialize_MODULE functions - have run. */ -extern void initialize_non_multiarch (); - /* gdbarch trace variable */ extern int gdbarch_debug; @@ -1174,50 +1280,22 @@ cat < -#include "symtab.h" -#include "frame.h" -#include "inferior.h" -#include "breakpoint.h" -#include "gdb_wait.h" -#include "gdbcore.h" -#include "gdbcmd.h" -#include "target.h" -#include "gdbthread.h" -#include "annotate.h" -#include "symfile.h" /* for overlay functions */ -#include "value.h" /* For old tm.h/nm.h macros. */ -#endif #include "symcat.h" #include "floatformat.h" #include "gdb_assert.h" +#include "gdb_string.h" #include "gdb-events.h" +#include "reggroups.h" +#include "osabi.h" +#include "gdb_obstack.h" /* Static function declarations */ -static void verify_gdbarch (struct gdbarch *gdbarch); static void alloc_gdbarch_data (struct gdbarch *); -static void init_gdbarch_data (struct gdbarch *); -static void free_gdbarch_data (struct gdbarch *); -static void init_gdbarch_swap (struct gdbarch *); -static void swapout_gdbarch_swap (struct gdbarch *); -static void swapin_gdbarch_swap (struct gdbarch *); - -/* Convenience macro for allocting typesafe memory. */ - -#ifndef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) -#endif - /* Non-zero if we want to trace architecture code. */ @@ -1234,6 +1312,12 @@ printf "/* Maintain the struct gdbarch object */\n" printf "\n" printf "struct gdbarch\n" printf "{\n" +printf " /* Has this architecture been fully initialized? */\n" +printf " int initialized_p;\n" +printf "\n" +printf " /* An obstack bound to the lifetime of the architecture. */\n" +printf " struct obstack *obstack;\n" +printf "\n" printf " /* basic architectural information */\n" function_list | while do_read do @@ -1306,12 +1390,14 @@ printf "extern const struct bfd_arch_info bfd_default_arch_struct;\n" printf "\n" printf "struct gdbarch startup_gdbarch =\n" printf "{\n" +printf " 1, /* Always initialized. */\n" +printf " NULL, /* The obstack. */\n" printf " /* basic architecture information */\n" function_list | while do_read do if class_is_info_p then - printf " ${staticdefault},\n" + printf " ${staticdefault}, /* ${function} */\n" fi done cat <obstack = obstack; alloc_gdbarch_data (current_gdbarch); @@ -1401,6 +1484,17 @@ EOF printf "\n" printf "\n" cat <obstack, size); + memset (data, 0, size); + return data; +} + + /* Free a gdbarch struct. This should never happen in normal operation --- once you've created a gdbarch, you keep it around. However, if an architecture's init function encounters an error @@ -1410,34 +1504,40 @@ cat <initialized_p); + obstack = arch->obstack; + obstack_free (obstack, 0); /* Includes the ARCH. */ + xfree (obstack); } EOF # verify a new architecture -printf "\n" -printf "\n" -printf "/* Ensure that all values in a GDBARCH are reasonable. */\n" -printf "\n" cat <byte_order == BFD_ENDIAN_UNKNOWN) + if (current_gdbarch->byte_order == BFD_ENDIAN_UNKNOWN) fprintf_unfiltered (log, "\n\tbyte-order"); - if (gdbarch->bfd_arch_info == NULL) + if (current_gdbarch->bfd_arch_info == NULL) fprintf_unfiltered (log, "\n\tbfd_arch_info"); /* Check those that need to be defined for the given multi-arch level. */ EOF @@ -1455,15 +1555,15 @@ do elif [ -n "${invalid_p}" -a -n "${postdefault}" ] then printf " if (${invalid_p})\n" - printf " gdbarch->${function} = ${postdefault};\n" + printf " current_gdbarch->${function} = ${postdefault};\n" elif [ -n "${predefault}" -a -n "${postdefault}" ] then - printf " if (gdbarch->${function} == ${predefault})\n" - printf " gdbarch->${function} = ${postdefault};\n" + printf " if (current_gdbarch->${function} == ${predefault})\n" + printf " current_gdbarch->${function} = ${postdefault};\n" elif [ -n "${postdefault}" ] then - printf " if (gdbarch->${function} == 0)\n" - printf " gdbarch->${function} = ${postdefault};\n" + printf " if (current_gdbarch->${function} == 0)\n" + printf " current_gdbarch->${function} = ${postdefault};\n" elif [ -n "${invalid_p}" ] then printf " if ((GDB_MULTI_ARCH ${gt_level})\n" @@ -1472,7 +1572,7 @@ do elif [ -n "${predefault}" ] then printf " if ((GDB_MULTI_ARCH ${gt_level})\n" - printf " && (gdbarch->${function} == ${predefault}))\n" + printf " && (current_gdbarch->${function} == ${predefault}))\n" printf " fprintf_unfiltered (log, \"\\\\n\\\\t${function}\");\n" fi fi @@ -1501,30 +1601,44 @@ cat <${function});\n" + printf " fprintf_unfiltered (file,\n" + printf " \"gdbarch_dump: ${function} = 0x%%08lx\\\\n\",\n" + printf " (long) current_gdbarch->${function});\n" continue fi # Print the macro definition. printf "#ifdef ${macro}\n" - if [ "x${returntype}" = "xvoid" ] - then - printf "#if GDB_MULTI_ARCH\n" - printf " /* Macro might contain \`[{}]' when not multi-arch */\n" - fi if class_is_function_p then printf " fprintf_unfiltered (file,\n" @@ -1536,11 +1650,6 @@ do printf " \"gdbarch_dump: ${macro} # %%s\\\\n\",\n" printf " XSTRING (${macro}));\n" fi - # Print the architecture vector value - if [ "x${returntype}" = "xvoid" ] - then - printf "#endif\n" - fi if [ "x${print_p}" = "x()" ] then printf " gdbarch_dump_${function} (current_gdbarch);\n" @@ -1555,11 +1664,10 @@ do printf " ${print});\n" elif class_is_function_p then - printf " if (GDB_MULTI_ARCH)\n" - printf " fprintf_unfiltered (file,\n" - printf " \"gdbarch_dump: ${macro} = 0x%%08lx\\\\n\",\n" - printf " (long) current_gdbarch->${function}\n" - printf " /*${macro} ()*/);\n" + printf " fprintf_unfiltered (file,\n" + printf " \"gdbarch_dump: ${macro} = <0x%%08lx>\\\\n\",\n" + printf " (long) current_gdbarch->${function}\n" + printf " /*${macro} ()*/);\n" else printf " fprintf_unfiltered (file,\n" printf " \"gdbarch_dump: ${macro} = %s\\\\n\",\n" "${fmt}" @@ -1594,12 +1702,8 @@ do printf "int\n" printf "gdbarch_${function}_p (struct gdbarch *gdbarch)\n" printf "{\n" - if [ -n "${valid_p}" ] - then - printf " return ${valid_p};\n" - else - printf "#error \"gdbarch_${function}_p: not defined\"\n" - fi + printf " gdb_assert (gdbarch != NULL);\n" + printf " return ${predicate};\n" printf "}\n" fi if class_is_function_p @@ -1613,9 +1717,13 @@ do printf "gdbarch_${function} (struct gdbarch *gdbarch, ${formal})\n" fi printf "{\n" - printf " if (gdbarch->${function} == 0)\n" - printf " internal_error (__FILE__, __LINE__,\n" - printf " \"gdbarch: gdbarch_${function} invalid\");\n" + printf " gdb_assert (gdbarch != NULL);\n" + printf " gdb_assert (gdbarch->${function} != NULL);\n" + if class_is_predicate_p && test -n "${predefault}" + then + # Allow a call to a function with a predicate. + printf " /* Do not check predicate: ${predicate}, allow call. */\n" + fi printf " if (gdbarch_debug >= 2)\n" printf " fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n" if [ "x${actual}" = "x-" -o "x${actual}" = "x" ] @@ -1654,19 +1762,18 @@ do printf "${returntype}\n" printf "gdbarch_${function} (struct gdbarch *gdbarch)\n" printf "{\n" + printf " gdb_assert (gdbarch != NULL);\n" if [ "x${invalid_p}" = "x0" ] then printf " /* Skip verify of ${function}, invalid_p == 0 */\n" elif [ -n "${invalid_p}" ] then - printf " if (${invalid_p})\n" - printf " internal_error (__FILE__, __LINE__,\n" - printf " \"gdbarch: gdbarch_${function} invalid\");\n" + printf " /* Check variable is valid. */\n" + printf " gdb_assert (!(${invalid_p}));\n" elif [ -n "${predefault}" ] then - printf " if (gdbarch->${function} == ${predefault})\n" - printf " internal_error (__FILE__, __LINE__,\n" - printf " \"gdbarch: gdbarch_${function} invalid\");\n" + printf " /* Check variable changed from pre-default. */\n" + printf " gdb_assert (gdbarch->${function} != ${predefault});\n" fi printf " if (gdbarch_debug >= 2)\n" printf " fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n" @@ -1685,6 +1792,7 @@ do printf "${returntype}\n" printf "gdbarch_${function} (struct gdbarch *gdbarch)\n" printf "{\n" + printf " gdb_assert (gdbarch != NULL);\n" printf " if (gdbarch_debug >= 2)\n" printf " fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n" printf " return gdbarch->${function};\n" @@ -1702,8 +1810,8 @@ cat <next); @@ -1736,31 +1844,11 @@ register_gdbarch_data (gdbarch_data_init_ftype *init, (*curr)->data = XMALLOC (struct gdbarch_data); (*curr)->data->index = gdbarch_data_registry.nr++; (*curr)->data->init = init; - (*curr)->data->free = free; + (*curr)->data->init_p = 1; return (*curr)->data; } -/* Walk through all the registered users initializing each in turn. */ - -static void -init_gdbarch_data (struct gdbarch *gdbarch) -{ - struct gdbarch_data_registration *rego; - for (rego = gdbarch_data_registry.registrations; - rego != NULL; - rego = rego->next) - { - struct gdbarch_data *data = rego->data; - gdb_assert (data->index < gdbarch->nr_data); - if (data->init != NULL) - { - void *pointer = data->init (gdbarch); - set_gdbarch_data (gdbarch, data, pointer); - } - } -} - /* Create/delete the gdbarch data vector. */ static void @@ -1768,32 +1856,10 @@ alloc_gdbarch_data (struct gdbarch *gdbarch) { gdb_assert (gdbarch->data == NULL); gdbarch->nr_data = gdbarch_data_registry.nr; - gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*)); + gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *); } -static void -free_gdbarch_data (struct gdbarch *gdbarch) -{ - struct gdbarch_data_registration *rego; - gdb_assert (gdbarch->data != NULL); - for (rego = gdbarch_data_registry.registrations; - rego != NULL; - rego = rego->next) - { - struct gdbarch_data *data = rego->data; - gdb_assert (data->index < gdbarch->nr_data); - if (data->free != NULL && gdbarch->data[data->index] != NULL) - { - data->free (gdbarch, gdbarch->data[data->index]); - gdbarch->data[data->index] = NULL; - } - } - xfree (gdbarch->data); - gdbarch->data = NULL; -} - - -/* Initialize the current value of thee specified per-architecture +/* Initialize the current value of the specified per-architecture data-pointer. */ void @@ -1802,8 +1868,7 @@ set_gdbarch_data (struct gdbarch *gdbarch, void *pointer) { gdb_assert (data->index < gdbarch->nr_data); - if (data->free != NULL && gdbarch->data[data->index] != NULL) - data->free (gdbarch, gdbarch->data[data->index]); + gdb_assert (gdbarch->data[data->index] == NULL); gdbarch->data[data->index] = pointer; } @@ -1811,10 +1876,24 @@ set_gdbarch_data (struct gdbarch *gdbarch, data-pointer. */ void * -gdbarch_data (struct gdbarch_data *data) +gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data) { - gdb_assert (data->index < current_gdbarch->nr_data); - return current_gdbarch->data[data->index]; + gdb_assert (data->index < gdbarch->nr_data); + /* The data-pointer isn't initialized, call init() to get a value but + only if the architecture initializaiton has completed. Otherwise + punt - hope that the caller knows what they are doing. */ + if (gdbarch->data[data->index] == NULL + && gdbarch->initialized_p) + { + /* Be careful to detect an initialization cycle. */ + gdb_assert (data->init_p); + data->init_p = 0; + gdb_assert (data->init != NULL); + gdbarch->data[data->index] = data->init (gdbarch); + data->init_p = 1; + gdb_assert (gdbarch->data[data->index] != NULL); + } + return gdbarch->data[data->index]; } @@ -1848,9 +1927,9 @@ struct gdbarch_swap_registry gdbarch_swap_registry = }; void -register_gdbarch_swap (void *data, - unsigned long sizeof_data, - gdbarch_swap_ftype *init) +deprecated_register_gdbarch_swap (void *data, + unsigned long sizeof_data, + gdbarch_swap_ftype *init) { struct gdbarch_swap_registration **rego; for (rego = &gdbarch_swap_registry.registrations; @@ -1863,23 +1942,23 @@ register_gdbarch_swap (void *data, (*rego)->sizeof_data = sizeof_data; } - static void -init_gdbarch_swap (struct gdbarch *gdbarch) +current_gdbarch_swap_init_hack (void) { struct gdbarch_swap_registration *rego; - struct gdbarch_swap **curr = &gdbarch->swap; + struct gdbarch_swap **curr = ¤t_gdbarch->swap; for (rego = gdbarch_swap_registry.registrations; rego != NULL; rego = rego->next) { if (rego->data != NULL) { - (*curr) = XMALLOC (struct gdbarch_swap); + (*curr) = GDBARCH_OBSTACK_ZALLOC (current_gdbarch, + struct gdbarch_swap); (*curr)->source = rego; - (*curr)->swap = xmalloc (rego->sizeof_data); + (*curr)->swap = gdbarch_obstack_zalloc (current_gdbarch, + rego->sizeof_data); (*curr)->next = NULL; - memset (rego->data, 0, rego->sizeof_data); curr = &(*curr)->next; } if (rego->init != NULL) @@ -1887,24 +1966,35 @@ init_gdbarch_swap (struct gdbarch *gdbarch) } } -static void -swapout_gdbarch_swap (struct gdbarch *gdbarch) +static struct gdbarch * +current_gdbarch_swap_out_hack (void) { + struct gdbarch *old_gdbarch = current_gdbarch; struct gdbarch_swap *curr; - for (curr = gdbarch->swap; + + gdb_assert (old_gdbarch != NULL); + for (curr = old_gdbarch->swap; curr != NULL; curr = curr->next) - memcpy (curr->swap, curr->source->data, curr->source->sizeof_data); + { + memcpy (curr->swap, curr->source->data, curr->source->sizeof_data); + memset (curr->source->data, 0, curr->source->sizeof_data); + } + current_gdbarch = NULL; + return old_gdbarch; } static void -swapin_gdbarch_swap (struct gdbarch *gdbarch) +current_gdbarch_swap_in_hack (struct gdbarch *new_gdbarch) { struct gdbarch_swap *curr; - for (curr = gdbarch->swap; + + gdb_assert (current_gdbarch == NULL); + for (curr = new_gdbarch->swap; curr != NULL; curr = curr->next) memcpy (curr->source->data, curr->swap, curr->source->sizeof_data); + current_gdbarch = new_gdbarch; } @@ -1932,37 +2022,30 @@ append_name (const char ***buf, int *nr, const char *name) const char ** gdbarch_printable_names (void) { - if (GDB_MULTI_ARCH) + /* Accumulate a list of names based on the registed list of + architectures. */ + enum bfd_architecture a; + int nr_arches = 0; + const char **arches = NULL; + struct gdbarch_registration *rego; + for (rego = gdbarch_registry; + rego != NULL; + rego = rego->next) { - /* Accumulate a list of names based on the registed list of - architectures. */ - enum bfd_architecture a; - int nr_arches = 0; - const char **arches = NULL; - struct gdbarch_registration *rego; - for (rego = gdbarch_registry; - rego != NULL; - rego = rego->next) - { - const struct bfd_arch_info *ap; - ap = bfd_lookup_arch (rego->bfd_architecture, 0); - if (ap == NULL) - internal_error (__FILE__, __LINE__, - "gdbarch_architecture_names: multi-arch unknown"); - do - { - append_name (&arches, &nr_arches, ap->printable_name); - ap = ap->next; - } - while (ap != NULL); - } - append_name (&arches, &nr_arches, NULL); - return arches; + const struct bfd_arch_info *ap; + ap = bfd_lookup_arch (rego->bfd_architecture, 0); + if (ap == NULL) + internal_error (__FILE__, __LINE__, + "gdbarch_architecture_names: multi-arch unknown"); + do + { + append_name (&arches, &nr_arches, ap->printable_name); + ap = ap->next; + } + while (ap != NULL); } - else - /* Just return all the architectures that BFD knows. Assume that - the legacy architecture framework supports them. */ - return bfd_arch_list (); + append_name (&arches, &nr_arches, NULL); + return arches; } @@ -2003,12 +2086,6 @@ gdbarch_register (enum bfd_architecture bfd_architecture, (*curr)->dump_tdep = dump_tdep; (*curr)->arches = NULL; (*curr)->next = NULL; - /* When non- multi-arch, install whatever target dump routine we've - been provided - hopefully that routine has been written correctly - and works regardless of multi-arch. */ - if (!GDB_MULTI_ARCH && dump_tdep != NULL - && startup_gdbarch.dump_tdep == NULL) - startup_gdbarch.dump_tdep = dump_tdep; } void @@ -2032,50 +2109,32 @@ gdbarch_list_lookup_by_info (struct gdbarch_list *arches, continue; if (info->byte_order != arches->gdbarch->byte_order) continue; + if (info->osabi != arches->gdbarch->osabi) + continue; return arches; } return NULL; } -/* Update the current architecture. Return ZERO if the update request - failed. */ +/* Find an architecture that matches the specified INFO. Create a new + architecture if needed. Return that new architecture. Assumes + that there is no current architecture. */ -int -gdbarch_update_p (struct gdbarch_info info) +static struct gdbarch * +find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info) { struct gdbarch *new_gdbarch; - struct gdbarch_list **list; struct gdbarch_registration *rego; + /* The existing architecture has been swapped out - all this code + works from a clean slate. */ + gdb_assert (current_gdbarch == NULL); + /* Fill in missing parts of the INFO struct using a number of - sources: \`\`set ...''; INFOabfd supplied; existing target. */ - - /* \`\`(gdb) set architecture ...'' */ - if (info.bfd_arch_info == NULL - && !TARGET_ARCHITECTURE_AUTO) - info.bfd_arch_info = TARGET_ARCHITECTURE; - if (info.bfd_arch_info == NULL - && info.abfd != NULL - && bfd_get_arch (info.abfd) != bfd_arch_unknown - && bfd_get_arch (info.abfd) != bfd_arch_obscure) - info.bfd_arch_info = bfd_get_arch_info (info.abfd); - if (info.bfd_arch_info == NULL) - info.bfd_arch_info = TARGET_ARCHITECTURE; - - /* \`\`(gdb) set byte-order ...'' */ - if (info.byte_order == BFD_ENDIAN_UNKNOWN - && !TARGET_BYTE_ORDER_AUTO) - info.byte_order = TARGET_BYTE_ORDER; - /* From the INFO struct. */ - if (info.byte_order == BFD_ENDIAN_UNKNOWN - && info.abfd != NULL) - info.byte_order = (bfd_big_endian (info.abfd) ? BFD_ENDIAN_BIG - : bfd_little_endian (info.abfd) ? BFD_ENDIAN_LITTLE - : BFD_ENDIAN_UNKNOWN); - /* From the current target. */ - if (info.byte_order == BFD_ENDIAN_UNKNOWN) - info.byte_order = TARGET_BYTE_ORDER; + sources: "set ..."; INFOabfd supplied; and the existing + architecture. */ + gdbarch_info_fill (old_gdbarch, &info); /* Must have found some sort of architecture. */ gdb_assert (info.bfd_arch_info != NULL); @@ -2083,25 +2142,28 @@ gdbarch_update_p (struct gdbarch_info info) if (gdbarch_debug) { fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.bfd_arch_info %s\n", + "find_arch_by_info: info.bfd_arch_info %s\n", (info.bfd_arch_info != NULL ? info.bfd_arch_info->printable_name : "(null)")); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.byte_order %d (%s)\n", + "find_arch_by_info: info.byte_order %d (%s)\n", info.byte_order, (info.byte_order == BFD_ENDIAN_BIG ? "big" : info.byte_order == BFD_ENDIAN_LITTLE ? "little" : "default")); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.abfd 0x%lx\n", + "find_arch_by_info: info.osabi %d (%s)\n", + info.osabi, gdbarch_osabi_name (info.osabi)); + fprintf_unfiltered (gdb_stdlog, + "find_arch_by_info: info.abfd 0x%lx\n", (long) info.abfd); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.tdep_info 0x%lx\n", + "find_arch_by_info: info.tdep_info 0x%lx\n", (long) info.tdep_info); } - /* Find the target that knows about this architecture. */ + /* Find the tdep code that knows about this architecture. */ for (rego = gdbarch_registry; rego != NULL; rego = rego->next) @@ -2110,97 +2172,121 @@ gdbarch_update_p (struct gdbarch_info info) if (rego == NULL) { if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: No matching architecture\\n"); + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "No matching architecture\n"); return 0; } - /* Ask the target for a replacement architecture. */ + /* Ask the tdep code for an architecture that matches "info". */ new_gdbarch = rego->init (info, rego->arches); - /* Did the target like it? No. Reject the change. */ + /* Did the tdep code like it? No. Reject the change and revert to + the old architecture. */ if (new_gdbarch == NULL) { if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Target rejected architecture\\n"); - return 0; + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "Target rejected architecture\n"); + return NULL; } - /* Did the architecture change? No. Do nothing. */ - if (current_gdbarch == new_gdbarch) + /* Is this a pre-existing architecture (as determined by already + being initialized)? Move it to the front of the architecture + list (keeping the list sorted Most Recently Used). */ + if (new_gdbarch->initialized_p) { + struct gdbarch_list **list; + struct gdbarch_list *this; if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\\n", + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "Previous architecture 0x%08lx (%s) selected\n", (long) new_gdbarch, new_gdbarch->bfd_arch_info->printable_name); - return 1; + /* Find the existing arch in the list. */ + for (list = ®o->arches; + (*list) != NULL && (*list)->gdbarch != new_gdbarch; + list = &(*list)->next); + /* It had better be in the list of architectures. */ + gdb_assert ((*list) != NULL && (*list)->gdbarch == new_gdbarch); + /* Unlink THIS. */ + this = (*list); + (*list) = this->next; + /* Insert THIS at the front. */ + this->next = rego->arches; + rego->arches = this; + /* Return it. */ + return new_gdbarch; } - /* Swap all data belonging to the old target out */ - swapout_gdbarch_swap (current_gdbarch); - - /* Is this a pre-existing architecture? Yes. Swap it in. */ - for (list = ®o->arches; - (*list) != NULL; - list = &(*list)->next) - { - if ((*list)->gdbarch == new_gdbarch) - { - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: Previous architecture 0x%08lx (%s) selected\\n", - (long) new_gdbarch, - new_gdbarch->bfd_arch_info->printable_name); - current_gdbarch = new_gdbarch; - swapin_gdbarch_swap (new_gdbarch); - architecture_changed_event (); - return 1; - } - } - - /* Append this new architecture to this targets list. */ - (*list) = XMALLOC (struct gdbarch_list); - (*list)->next = NULL; - (*list)->gdbarch = new_gdbarch; - - /* Switch to this new architecture. Dump it out. */ - current_gdbarch = new_gdbarch; + /* It's a new architecture. */ if (gdbarch_debug) - { - fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: New architecture 0x%08lx (%s) selected\\n", - (long) new_gdbarch, - new_gdbarch->bfd_arch_info->printable_name); - } + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "New architecture 0x%08lx (%s) selected\n", + (long) new_gdbarch, + new_gdbarch->bfd_arch_info->printable_name); + /* Insert the new architecture into the front of the architecture + list (keep the list sorted Most Recently Used). */ + { + struct gdbarch_list *this = XMALLOC (struct gdbarch_list); + this->next = rego->arches; + this->gdbarch = new_gdbarch; + rego->arches = this; + } + /* Check that the newly installed architecture is valid. Plug in any post init values. */ new_gdbarch->dump_tdep = rego->dump_tdep; verify_gdbarch (new_gdbarch); + new_gdbarch->initialized_p = 1; - /* Initialize the per-architecture memory (swap) areas. - CURRENT_GDBARCH must be update before these modules are - called. */ - init_gdbarch_swap (new_gdbarch); - - /* Initialize the per-architecture data-pointer of all parties that - registered an interest in this architecture. CURRENT_GDBARCH - must be updated before these modules are called. */ - init_gdbarch_data (new_gdbarch); - architecture_changed_event (); + /* Initialize any per-architecture swap areas. This phase requires + a valid global CURRENT_GDBARCH. Set it momentarially, and then + swap the entire architecture out. */ + current_gdbarch = new_gdbarch; + current_gdbarch_swap_init_hack (); + current_gdbarch_swap_out_hack (); if (gdbarch_debug) - gdbarch_dump (current_gdbarch, gdb_stdlog); + gdbarch_dump (new_gdbarch, gdb_stdlog); - return 1; + return new_gdbarch; } +struct gdbarch * +gdbarch_find_by_info (struct gdbarch_info info) +{ + /* Save the previously selected architecture, setting the global to + NULL. This stops things like gdbarch->init() trying to use the + previous architecture's configuration. The previous architecture + may not even be of the same architecture family. The most recent + architecture of the same family is found at the head of the + rego->arches list. */ + struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack (); -/* Disassembler */ + /* Find the specified architecture. */ + struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info); -/* Pointer to the target-dependent disassembly function. */ -int (*tm_print_insn) (bfd_vma, disassemble_info *); -disassemble_info tm_print_insn_info; + /* Restore the existing architecture. */ + gdb_assert (current_gdbarch == NULL); + current_gdbarch_swap_in_hack (old_gdbarch); + return new_gdbarch; +} + +/* Make the specified architecture current, swapping the existing one + out. */ + +void +deprecated_current_gdbarch_select_hack (struct gdbarch *new_gdbarch) +{ + gdb_assert (new_gdbarch != NULL); + gdb_assert (current_gdbarch != NULL); + gdb_assert (new_gdbarch->initialized_p); + current_gdbarch_swap_out_hack (); + current_gdbarch_swap_in_hack (new_gdbarch); + architecture_changed_event (); +} extern void _initialize_gdbarch (void); @@ -2209,12 +2295,6 @@ _initialize_gdbarch (void) { struct cmd_list_element *c; - INIT_DISASSEMBLE_INFO_NO_ARCH (tm_print_insn_info, gdb_stdout, (fprintf_ftype)fprintf_filtered); - tm_print_insn_info.flavour = bfd_target_unknown_flavour; - tm_print_insn_info.read_memory_func = dis_asm_read_memory; - tm_print_insn_info.memory_error_func = dis_asm_memory_error; - tm_print_insn_info.print_address_func = dis_asm_print_address; - add_show_from_set (add_set_cmd ("arch", class_maintenance, var_zinteger, diff --git a/contrib/gdb/gdb/gdbcore.h b/contrib/gdb/gdb/gdbcore.h index 88594554080..e03ebf47fa7 100644 --- a/contrib/gdb/gdb/gdbcore.h +++ b/contrib/gdb/gdb/gdbcore.h @@ -24,6 +24,8 @@ #if !defined (GDBCORE_H) #define GDBCORE_H 1 +struct type; + #include "bfd.h" /* Return the name of the executable file as a string. @@ -64,8 +66,14 @@ extern ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len); /* Read a null-terminated string from the debuggee's memory, given address, * a buffer into which to place the string, and the maximum available space */ + extern void read_memory_string (CORE_ADDR, char *, int); +/* Read the pointer of type TYPE at ADDR, and return the address it + represents. */ + +CORE_ADDR read_memory_typed_address (CORE_ADDR addr, struct type *type); + /* 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, diff --git a/contrib/gdb/gdb/gdbinit.in b/contrib/gdb/gdb/gdbinit.in index b6a32dba09f..1a080dca897 100644 --- a/contrib/gdb/gdb/gdbinit.in +++ b/contrib/gdb/gdb/gdbinit.in @@ -10,9 +10,8 @@ commands return end -dir @srcdir@ -dir . -dir @srcdir@/../mmalloc dir @srcdir@/../libiberty dir @srcdir@/../bfd +dir @srcdir@ +dir . set prompt (top-gdb) diff --git a/contrib/gdb/gdb/gdbserver/acinclude.m4 b/contrib/gdb/gdb/gdbserver/acinclude.m4 new file mode 100644 index 00000000000..bbfa86f16c5 --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/acinclude.m4 @@ -0,0 +1,41 @@ +dnl gdb/gdbserver/configure.in uses BFD_HAVE_SYS_PROCFS_TYPE. +sinclude(../../bfd/acinclude.m4) + +AC_DEFUN([SRV_CHECK_THREAD_DB], +[AC_CACHE_CHECK([for libthread_db],[srv_cv_thread_db], + [old_LIBS="$LIBS" + LIBS="$LIBS -lthread_db" + AC_TRY_LINK( + [void ps_pglobal_lookup() {} + void ps_pdread() {} + void ps_pdwrite() {} + void ps_lgetregs() {} + void ps_lsetregs() {} + void ps_lgetfpregs() {} + void ps_lsetfpregs() {} + void ps_getpid() {}], + [td_ta_new();], + [srv_cv_thread_db="-lthread_db"], + [srv_cv_thread_db=no + + if test "$prefix" = "/usr" || test "$prefix" = "NONE"; then + thread_db="/lib/libthread_db.so.1" + else + thread_db='$prefix/lib/libthread_db.so.1' + fi + LIBS="$old_LIBS `eval echo "$thread_db"`" + AC_TRY_LINK( + [void ps_pglobal_lookup() {} + void ps_pdread() {} + void ps_pdwrite() {} + void ps_lgetregs() {} + void ps_lsetregs() {} + void ps_lgetfpregs() {} + void ps_lsetfpregs() {} + void ps_getpid() {}], + [td_ta_new();], + [srv_cv_thread_db="$thread_db"], + [srv_cv_thread_db=no]) + LIBS="$old_LIBS" + ]]) +)]) diff --git a/contrib/gdb/gdb/gdbserver/aclocal.m4 b/contrib/gdb/gdb/gdbserver/aclocal.m4 index 24b9ced2835..2fc6cf883da 100644 --- a/contrib/gdb/gdb/gdbserver/aclocal.m4 +++ b/contrib/gdb/gdb/gdbserver/aclocal.m4 @@ -10,91 +10,45 @@ dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. +dnl gdb/gdbserver/configure.in uses BFD_HAVE_SYS_PROCFS_TYPE. +sinclude(../../bfd/acinclude.m4) -# serial 1 +AC_DEFUN([SRV_CHECK_THREAD_DB], +[AC_CACHE_CHECK([for libthread_db],[srv_cv_thread_db], + [old_LIBS="$LIBS" + LIBS="$LIBS -lthread_db" + AC_TRY_LINK( + [void ps_pglobal_lookup() {} + void ps_pdread() {} + void ps_pdwrite() {} + void ps_lgetregs() {} + void ps_lsetregs() {} + void ps_lgetfpregs() {} + void ps_lsetfpregs() {} + void ps_getpid() {}], + [td_ta_new();], + [srv_cv_thread_db="-lthread_db"], + [srv_cv_thread_db=no -# @defmac AC_PROG_CC_STDC -# @maindex PROG_CC_STDC -# @ovindex CC -# If the C compiler in not in ANSI C mode by default, try to add an option -# to output variable @code{CC} to make it so. This macro tries various -# options that select ANSI C on some system or another. It considers the -# compiler to be in ANSI C mode if it handles function prototypes correctly. -# -# If you use this macro, you should check after calling it whether the C -# compiler has been set to accept ANSI C; if not, the shell variable -# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source -# code in ANSI C, you can make an un-ANSIfied copy of it by using the -# program @code{ansi2knr}, which comes with Ghostscript. -# @end defmac - -AC_DEFUN(AM_PROG_CC_STDC, -[AC_REQUIRE([AC_PROG_CC]) -AC_BEFORE([$0], [AC_C_INLINE]) -AC_BEFORE([$0], [AC_C_CONST]) -dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require -dnl a magic option to avoid problems with ANSI preprocessor commands -dnl like #elif. -dnl FIXME: can't do this because then AC_AIX won't work due to a -dnl circular dependency. -dnl AC_BEFORE([$0], [AC_PROG_CPP]) -AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) -AC_CACHE_VAL(am_cv_prog_cc_stdc, -[am_cv_prog_cc_stdc=no -ac_save_CC="$CC" -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - AC_TRY_COMPILE( -[#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -], [ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; -], -[am_cv_prog_cc_stdc="$ac_arg"; break]) -done -CC="$ac_save_CC" -]) -if test -z "$am_cv_prog_cc_stdc"; then - AC_MSG_RESULT([none needed]) -else - AC_MSG_RESULT($am_cv_prog_cc_stdc) -fi -case "x$am_cv_prog_cc_stdc" in - x|xno) ;; - *) CC="$CC $am_cv_prog_cc_stdc" ;; -esac -]) + if test "$prefix" = "/usr" || test "$prefix" = "NONE"; then + thread_db="/lib/libthread_db.so.1" + else + thread_db='$prefix/lib/libthread_db.so.1' + fi + LIBS="$old_LIBS `eval echo "$thread_db"`" + AC_TRY_LINK( + [void ps_pglobal_lookup() {} + void ps_pdread() {} + void ps_pdwrite() {} + void ps_lgetregs() {} + void ps_lsetregs() {} + void ps_lgetfpregs() {} + void ps_lsetfpregs() {} + void ps_getpid() {}], + [td_ta_new();], + [srv_cv_thread_db="$thread_db"], + [srv_cv_thread_db=no]) + LIBS="$old_LIBS" + ]]) +)]) diff --git a/contrib/gdb/gdb/gdbserver/gdbreplay.c b/contrib/gdb/gdb/gdbserver/gdbreplay.c index 8c57906ea07..7c9064bf2d7 100644 --- a/contrib/gdb/gdb/gdbserver/gdbreplay.c +++ b/contrib/gdb/gdb/gdbserver/gdbreplay.c @@ -1,5 +1,5 @@ /* Replay a remote debug session logfile for GDB. - Copyright 1996, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright 1996, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. Written by Fred Fish (fnf@cygnus.com) from pieces of gdbserver. This file is part of GDB. @@ -54,14 +54,15 @@ static void perror_with_name (char *string) { #ifndef STDC_HEADERS - extern int sys_nerr; - extern char *sys_errlist[]; extern int errno; #endif const char *err; char *combined; - err = (errno < sys_nerr) ? sys_errlist[errno] : "unknown error"; + err = strerror (errno); + if (err == NULL) + err = "unknown error"; + combined = (char *) alloca (strlen (err) + strlen (string) + 3); strcpy (combined, string); strcat (combined, ": "); @@ -93,10 +94,6 @@ remote_close (void) static void remote_open (char *name) { -#ifndef HAVE_STRING_H - extern char *strchr (); -#endif - if (!strchr (name, ':')) { fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name); diff --git a/contrib/gdb/gdb/gdbserver/i387-fp.c b/contrib/gdb/gdb/gdbserver/i387-fp.c index 3d1d6a6fd5c..19a9929debc 100644 --- a/contrib/gdb/gdb/gdbserver/i387-fp.c +++ b/contrib/gdb/gdb/gdbserver/i387-fp.c @@ -20,6 +20,7 @@ Boston, MA 02111-1307, USA. */ #include "server.h" +#include "i387-fp.h" int num_xmm_registers = 8; @@ -108,7 +109,7 @@ i387_cache_to_fsave (void *buf) } void -i387_fsave_to_cache (void *buf) +i387_fsave_to_cache (const void *buf) { struct i387_fsave *fp = (struct i387_fsave *) buf; int i; @@ -240,7 +241,7 @@ i387_ftag (struct i387_fxsave *fp, int regno) } void -i387_fxsave_to_cache (void *buf) +i387_fxsave_to_cache (const void *buf) { struct i387_fxsave *fp = (struct i387_fxsave *) buf; int i, top; @@ -287,4 +288,3 @@ i387_fxsave_to_cache (void *buf) val = (fp->fop) & 0x7FF; supply_register_by_name ("fop", &val); } - diff --git a/contrib/gdb/gdb/gdbserver/i387-fp.h b/contrib/gdb/gdb/gdbserver/i387-fp.h index 90fe4ca6eb7..d28c4228830 100644 --- a/contrib/gdb/gdb/gdbserver/i387-fp.h +++ b/contrib/gdb/gdb/gdbserver/i387-fp.h @@ -23,10 +23,10 @@ #define I387_FP_H void i387_cache_to_fsave (void *buf); -void i387_fsave_to_cache (void *buf); +void i387_fsave_to_cache (const void *buf); void i387_cache_to_fxsave (void *buf); -void i387_fxsave_to_cache (void *buf); +void i387_fxsave_to_cache (const void *buf); extern int num_xmm_registers; diff --git a/contrib/gdb/gdb/gdbserver/inferiors.c b/contrib/gdb/gdb/gdbserver/inferiors.c new file mode 100644 index 00000000000..68c91c4efa9 --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/inferiors.c @@ -0,0 +1,199 @@ +/* Inferior process information for the remote server for GDB. + Copyright 2002 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "server.h" + +struct thread_info +{ + struct inferior_list_entry entry; + void *target_data; + void *regcache_data; +}; + +struct inferior_list all_threads; + +struct thread_info *current_inferior; + +#define get_thread(inf) ((struct thread_info *)(inf)) + +void +add_inferior_to_list (struct inferior_list *list, + struct inferior_list_entry *new_inferior) +{ + new_inferior->next = NULL; + if (list->tail != NULL) + list->tail->next = new_inferior; + else + list->head = new_inferior; + list->tail = new_inferior; +} + +void +for_each_inferior (struct inferior_list *list, + void (*action) (struct inferior_list_entry *)) +{ + struct inferior_list_entry *cur = list->head, *next; + + while (cur != NULL) + { + next = cur->next; + (*action) (cur); + cur = next; + } +} + +void +change_inferior_id (struct inferior_list *list, + int new_id) +{ + if (list->head != list->tail) + error ("tried to change thread ID after multiple threads are created"); + + list->head->id = new_id; +} + +void +remove_inferior (struct inferior_list *list, + struct inferior_list_entry *entry) +{ + struct inferior_list_entry **cur; + + if (list->head == entry) + { + list->head = entry->next; + if (list->tail == entry) + list->tail = list->head; + return; + } + + cur = &list->head; + while (*cur && (*cur)->next != entry) + cur = &(*cur)->next; + + if (*cur == NULL) + return; + + (*cur)->next = entry->next; + + if (list->tail == entry) + list->tail = *cur; +} + +void +add_thread (int thread_id, void *target_data) +{ + struct thread_info *new_thread + = (struct thread_info *) malloc (sizeof (*new_thread)); + + memset (new_thread, 0, sizeof (*new_thread)); + + new_thread->entry.id = thread_id; + + add_inferior_to_list (&all_threads, & new_thread->entry); + + if (current_inferior == NULL) + current_inferior = new_thread; + + new_thread->target_data = target_data; + set_inferior_regcache_data (new_thread, new_register_cache ()); +} + +static void +free_one_thread (struct inferior_list_entry *inf) +{ + struct thread_info *thread = get_thread (inf); + free_register_cache (inferior_regcache_data (thread)); + free (thread); +} + +void +remove_thread (struct thread_info *thread) +{ + remove_inferior (&all_threads, (struct inferior_list_entry *) thread); + free_one_thread (&thread->entry); +} + +void +clear_inferiors (void) +{ + for_each_inferior (&all_threads, free_one_thread); + + all_threads.head = all_threads.tail = NULL; +} + +struct inferior_list_entry * +find_inferior (struct inferior_list *list, + int (*func) (struct inferior_list_entry *, void *), void *arg) +{ + struct inferior_list_entry *inf = list->head; + + while (inf != NULL) + { + if ((*func) (inf, arg)) + return inf; + inf = inf->next; + } + + return NULL; +} + +struct inferior_list_entry * +find_inferior_id (struct inferior_list *list, int id) +{ + struct inferior_list_entry *inf = list->head; + + while (inf != NULL) + { + if (inf->id == id) + return inf; + inf = inf->next; + } + + return NULL; +} + +void * +inferior_target_data (struct thread_info *inferior) +{ + return inferior->target_data; +} + +void +set_inferior_target_data (struct thread_info *inferior, void *data) +{ + inferior->target_data = data; +} + +void * +inferior_regcache_data (struct thread_info *inferior) +{ + return inferior->regcache_data; +} + +void +set_inferior_regcache_data (struct thread_info *inferior, void *data) +{ + inferior->regcache_data = data; +} diff --git a/contrib/gdb/gdb/gdbserver/mem-break.c b/contrib/gdb/gdb/gdbserver/mem-break.c new file mode 100644 index 00000000000..977b0e3f3d3 --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/mem-break.c @@ -0,0 +1,278 @@ +/* Memory breakpoint operations for the remote server for GDB. + Copyright 2002 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +const char *breakpoint_data; +int breakpoint_len; + +#define MAX_BREAKPOINT_LEN 8 + +struct breakpoint +{ + struct breakpoint *next; + CORE_ADDR pc; + unsigned char old_data[MAX_BREAKPOINT_LEN]; + + /* Non-zero iff we are stepping over this breakpoint. */ + int reinserting; + + /* Non-NULL iff this breakpoint was inserted to step over + another one. Points to the other breakpoint (which is also + in the *next chain somewhere). */ + struct breakpoint *breakpoint_to_reinsert; + + /* Function to call when we hit this breakpoint. */ + void (*handler) (CORE_ADDR); +}; + +struct breakpoint *breakpoints; + +void +set_breakpoint_at (CORE_ADDR where, void (*handler) (CORE_ADDR)) +{ + struct breakpoint *bp; + + if (breakpoint_data == NULL) + error ("Target does not support breakpoints."); + + bp = malloc (sizeof (struct breakpoint)); + memset (bp, 0, sizeof (struct breakpoint)); + + (*the_target->read_memory) (where, bp->old_data, + breakpoint_len); + (*the_target->write_memory) (where, breakpoint_data, + breakpoint_len); + + bp->pc = where; + bp->handler = handler; + + bp->next = breakpoints; + breakpoints = bp; +} + +static void +delete_breakpoint (struct breakpoint *bp) +{ + struct breakpoint *cur; + + if (breakpoints == bp) + { + breakpoints = bp->next; + (*the_target->write_memory) (bp->pc, bp->old_data, + breakpoint_len); + free (bp); + return; + } + cur = breakpoints; + while (cur->next) + { + if (cur->next == bp) + { + cur->next = bp->next; + (*the_target->write_memory) (bp->pc, bp->old_data, + breakpoint_len); + free (bp); + return; + } + } + warning ("Could not find breakpoint in list."); +} + +static struct breakpoint * +find_breakpoint_at (CORE_ADDR where) +{ + struct breakpoint *bp = breakpoints; + + while (bp != NULL) + { + if (bp->pc == where) + return bp; + bp = bp->next; + } + + return NULL; +} + +static void +reinsert_breakpoint_handler (CORE_ADDR stop_pc) +{ + struct breakpoint *stop_bp, *orig_bp; + + stop_bp = find_breakpoint_at (stop_pc); + if (stop_bp == NULL) + error ("lost the stopping breakpoint."); + + orig_bp = stop_bp->breakpoint_to_reinsert; + if (orig_bp == NULL) + error ("no breakpoint to reinsert"); + + (*the_target->write_memory) (orig_bp->pc, breakpoint_data, + breakpoint_len); + orig_bp->reinserting = 0; + delete_breakpoint (stop_bp); +} + +void +reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at) +{ + struct breakpoint *bp, *orig_bp; + + set_breakpoint_at (stop_at, reinsert_breakpoint_handler); + + orig_bp = find_breakpoint_at (stop_pc); + if (orig_bp == NULL) + error ("Could not find original breakpoint in list."); + + bp = find_breakpoint_at (stop_at); + if (bp == NULL) + error ("Could not find breakpoint in list (reinserting by breakpoint)."); + bp->breakpoint_to_reinsert = orig_bp; + + (*the_target->write_memory) (orig_bp->pc, orig_bp->old_data, + breakpoint_len); + orig_bp->reinserting = 1; +} + +void +uninsert_breakpoint (CORE_ADDR stopped_at) +{ + struct breakpoint *bp; + + bp = find_breakpoint_at (stopped_at); + if (bp == NULL) + error ("Could not find breakpoint in list (uninserting)."); + + (*the_target->write_memory) (bp->pc, bp->old_data, + breakpoint_len); + bp->reinserting = 1; +} + +void +reinsert_breakpoint (CORE_ADDR stopped_at) +{ + struct breakpoint *bp; + + bp = find_breakpoint_at (stopped_at); + if (bp == NULL) + error ("Could not find breakpoint in list (uninserting)."); + if (! bp->reinserting) + error ("Breakpoint already inserted at reinsert time."); + + (*the_target->write_memory) (bp->pc, breakpoint_data, + breakpoint_len); + bp->reinserting = 0; +} + +int +check_breakpoints (CORE_ADDR stop_pc) +{ + struct breakpoint *bp; + + bp = find_breakpoint_at (stop_pc); + if (bp == NULL) + return 0; + if (bp->reinserting) + { + warning ("Hit a removed breakpoint?"); + return 0; + } + + (*bp->handler) (bp->pc); + return 1; +} + +void +set_breakpoint_data (const char *bp_data, int bp_len) +{ + breakpoint_data = bp_data; + breakpoint_len = bp_len; +} + +void +check_mem_read (CORE_ADDR mem_addr, char *buf, int mem_len) +{ + struct breakpoint *bp = breakpoints; + CORE_ADDR mem_end = mem_addr + mem_len; + + for (; bp != NULL; bp = bp->next) + { + CORE_ADDR bp_end = bp->pc + breakpoint_len; + CORE_ADDR start, end; + int copy_offset, copy_len, buf_offset; + + if (mem_addr >= bp_end) + continue; + if (bp->pc >= mem_end) + continue; + + start = bp->pc; + if (mem_addr > start) + start = mem_addr; + + end = bp_end; + if (end > mem_end) + end = mem_end; + + copy_len = end - start; + copy_offset = start - bp->pc; + buf_offset = start - mem_addr; + + memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len); + } +} + +void +check_mem_write (CORE_ADDR mem_addr, char *buf, int mem_len) +{ + struct breakpoint *bp = breakpoints; + CORE_ADDR mem_end = mem_addr + mem_len; + + for (; bp != NULL; bp = bp->next) + { + CORE_ADDR bp_end = bp->pc + breakpoint_len; + CORE_ADDR start, end; + int copy_offset, copy_len, buf_offset; + + if (mem_addr >= bp_end) + continue; + if (bp->pc >= mem_end) + continue; + + start = bp->pc; + if (mem_addr > start) + start = mem_addr; + + end = bp_end; + if (end > mem_end) + end = mem_end; + + copy_len = end - start; + copy_offset = start - bp->pc; + buf_offset = start - mem_addr; + + memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len); + if (bp->reinserting == 0) + memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len); + } +} diff --git a/contrib/gdb/gdb/gdbserver/mem-break.h b/contrib/gdb/gdb/gdbserver/mem-break.h new file mode 100644 index 00000000000..356e7630cab --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/mem-break.h @@ -0,0 +1,71 @@ +/* Memory breakpoint interfaces for the remote server for GDB. + Copyright 2002 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MEM_BREAK_H +#define MEM_BREAK_H + +/* Breakpoints are opaque. */ + +/* Create a new breakpoint at WHERE, and call HANDLER when + it is hit. */ + +void set_breakpoint_at (CORE_ADDR where, + void (*handler) (CORE_ADDR)); + +/* Create a reinsertion breakpoint at STOP_AT for the breakpoint + currently at STOP_PC (and temporarily remove the breakpoint at + STOP_PC). */ + +void reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at); + +/* Change the status of the breakpoint at WHERE to inserted. */ + +void reinsert_breakpoint (CORE_ADDR where); + +/* Change the status of the breakpoint at WHERE to uninserted. */ + +void uninsert_breakpoint (CORE_ADDR where); + +/* See if any breakpoint claims ownership of STOP_PC. Call the handler for + the breakpoint, if found. */ + +int check_breakpoints (CORE_ADDR stop_pc); + +/* See if any breakpoints shadow the target memory area from MEM_ADDR + to MEM_ADDR + MEM_LEN. Update the data already read from the target + (in BUF) if necessary. */ + +void check_mem_read (CORE_ADDR mem_addr, char *buf, int mem_len); + +/* See if any breakpoints shadow the target memory area from MEM_ADDR + to MEM_ADDR + MEM_LEN. Update the data to be written to the target + (in BUF) if necessary, as well as the original data for any breakpoints. */ + +void check_mem_write (CORE_ADDR mem_addr, char *buf, int mem_len); + +/* Set the byte pattern to insert for memory breakpoints. This function + must be called before any breakpoints are set. */ + +void set_breakpoint_data (const char *bp_data, int bp_len); + +#endif /* MEM_BREAK_H */ diff --git a/contrib/gdb/gdb/gdbserver/proc-service.c b/contrib/gdb/gdb/gdbserver/proc-service.c new file mode 100644 index 00000000000..becf565529b --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/proc-service.c @@ -0,0 +1,256 @@ +/* libthread_db helper functions for the remote server for GDB. + Copyright 2002 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +/* This file is currently tied to GNU/Linux. It should scale well to + another libthread_db implementation, with the approriate gdbserver + hooks, but for now this means we can use GNU/Linux's target data. */ + +#include "linux-low.h" + +/* Correct for all GNU/Linux targets (for quite some time). */ +#define GDB_GREGSET_T elf_gregset_t +#define GDB_FPREGSET_T elf_fpregset_t + +#ifndef HAVE_ELF_FPREGSET_T +/* Make sure we have said types. Not all platforms bring in + via . */ +#ifdef HAVE_LINUX_ELF_H +#include +#endif +#endif + +#include "../gdb_proc_service.h" + +typedef struct ps_prochandle *gdb_ps_prochandle_t; +typedef void *gdb_ps_read_buf_t; +typedef const void *gdb_ps_write_buf_t; +typedef size_t gdb_ps_size_t; + +/* FIXME redo this right */ +#if 0 +#ifndef HAVE_LINUX_REGSETS +#error HAVE_LINUX_REGSETS required! +#else +static struct regset_info * +gregset_info(void) +{ + int i = 0; + + while (target_regsets[i].size != -1) + { + if (target_regsets[i].type == GENERAL_REGS) + break; + i++; + } + + return &target_regsets[i]; +} + +static struct regset_info * +fpregset_info(void) +{ + int i = 0; + + while (target_regsets[i].size != -1) + { + if (target_regsets[i].type == FP_REGS) + break; + i++; + } + + return &target_regsets[i]; +} +#endif +#endif + +/* Search for the symbol named NAME within the object named OBJ within + the target process PH. If the symbol is found the address of the + symbol is stored in SYM_ADDR. */ + +ps_err_e +ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj, + const char *name, paddr_t *sym_addr) +{ + CORE_ADDR addr; + + if (look_up_one_symbol (name, &addr) == 0) + return PS_NOSYM; + + *sym_addr = (paddr_t) (unsigned long) addr; + return PS_OK; +} + +/* Read SIZE bytes from the target process PH at address ADDR and copy + them into BUF. */ + +ps_err_e +ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr, + gdb_ps_read_buf_t buf, gdb_ps_size_t size) +{ + read_inferior_memory (addr, buf, size); + return PS_OK; +} + +/* Write SIZE bytes from BUF into the target process PH at address ADDR. */ + +ps_err_e +ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr, + gdb_ps_write_buf_t buf, gdb_ps_size_t size) +{ + return write_inferior_memory (addr, buf, size); +} + +/* Get the general registers of LWP LWPID within the target process PH + and store them in GREGSET. */ + +ps_err_e +ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) +{ +#if 0 + struct thread_info *reg_inferior, *save_inferior; + void *regcache; + + reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, + lwpid); + if (reg_inferior == NULL) + return PS_ERR; + + save_inferior = current_inferior; + current_inferior = reg_inferior; + + regcache = new_register_cache (); + the_target->fetch_registers (0, regcache); + gregset_info()->fill_function (gregset, regcache); + free_register_cache (regcache); + + current_inferior = save_inferior; + return PS_OK; +#endif + /* FIXME */ + return PS_ERR; +} + +/* Set the general registers of LWP LWPID within the target process PH + from GREGSET. */ + +ps_err_e +ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset) +{ +#if 0 + struct thread_info *reg_inferior, *save_inferior; + void *regcache; + + reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid); + if (reg_inferior == NULL) + return PS_ERR; + + save_inferior = current_inferior; + current_inferior = reg_inferior; + + regcache = new_register_cache (); + gregset_info()->store_function (gregset, regcache); + the_target->store_registers (0, regcache); + free_register_cache (regcache); + + current_inferior = save_inferior; + + return PS_OK; +#endif + /* FIXME */ + return PS_ERR; +} + +/* Get the floating-point registers of LWP LWPID within the target + process PH and store them in FPREGSET. */ + +ps_err_e +ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, + gdb_prfpregset_t *fpregset) +{ +#if 0 + struct thread_info *reg_inferior, *save_inferior; + void *regcache; + + reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid); + if (reg_inferior == NULL) + return PS_ERR; + + save_inferior = current_inferior; + current_inferior = reg_inferior; + + regcache = new_register_cache (); + the_target->fetch_registers (0, regcache); + fpregset_info()->fill_function (fpregset, regcache); + free_register_cache (regcache); + + current_inferior = save_inferior; + + return PS_OK; +#endif + /* FIXME */ + return PS_ERR; +} + +/* Set the floating-point registers of LWP LWPID within the target + process PH from FPREGSET. */ + +ps_err_e +ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, + const gdb_prfpregset_t *fpregset) +{ +#if 0 + struct thread_info *reg_inferior, *save_inferior; + void *regcache; + + reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid); + if (reg_inferior == NULL) + return PS_ERR; + + save_inferior = current_inferior; + current_inferior = reg_inferior; + + regcache = new_register_cache (); + fpregset_info()->store_function (fpregset, regcache); + the_target->store_registers (0, regcache); + free_register_cache (regcache); + + current_inferior = save_inferior; + + return PS_OK; +#endif + /* FIXME */ + return PS_ERR; +} + +/* Return overall process id of the target PH. Special for GNU/Linux + -- not used on Solaris. */ + +pid_t +ps_getpid (gdb_ps_prochandle_t ph) +{ + return ph->pid; +} + + diff --git a/contrib/gdb/gdb/gdbserver/regcache.c b/contrib/gdb/gdb/gdbserver/regcache.c index bec20bb6fd8..bc64ebcbb97 100644 --- a/contrib/gdb/gdb/gdbserver/regcache.c +++ b/contrib/gdb/gdb/gdbserver/regcache.c @@ -1,5 +1,5 @@ /* Register support routines for the remote server for GDB. - Copyright 2001, 2002 + Copyright 2001, 2002, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -25,7 +25,16 @@ #include #include -static char *registers; +/* The private data for the register cache. Note that we have one + per inferior; this is primarily for simplicity, as the performance + benefit is minimal. */ + +struct inferior_regcache_data +{ + int registers_valid; + char *registers; +}; + static int register_bytes; static struct reg *reg_defs; @@ -33,12 +42,87 @@ static int num_registers; const char **gdbserver_expedite_regs; +static struct inferior_regcache_data * +get_regcache (struct thread_info *inf, int fetch) +{ + struct inferior_regcache_data *regcache; + + regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf); + + if (regcache == NULL) + fatal ("no register cache"); + + /* FIXME - fetch registers for INF */ + if (fetch && regcache->registers_valid == 0) + { + fetch_inferior_registers (0); + regcache->registers_valid = 1; + } + + return regcache; +} + +void +regcache_invalidate_one (struct inferior_list_entry *entry) +{ + struct thread_info *thread = (struct thread_info *) entry; + struct inferior_regcache_data *regcache; + + regcache = (struct inferior_regcache_data *) inferior_regcache_data (thread); + + if (regcache->registers_valid) + { + struct thread_info *saved_inferior = current_inferior; + + current_inferior = thread; + store_inferior_registers (-1); + current_inferior = saved_inferior; + } + + regcache->registers_valid = 0; +} + +void +regcache_invalidate () +{ + for_each_inferior (&all_threads, regcache_invalidate_one); +} + int registers_length (void) { return 2 * register_bytes; } +void * +new_register_cache (void) +{ + struct inferior_regcache_data *regcache; + + regcache = malloc (sizeof (*regcache)); + + /* Make sure to zero-initialize the register cache when it is created, + in case there are registers the target never fetches. This way they'll + read as zero instead of garbage. */ + regcache->registers = calloc (1, register_bytes); + if (regcache->registers == NULL) + fatal ("Could not allocate register cache."); + + regcache->registers_valid = 0; + + return regcache; +} + +void +free_register_cache (void *regcache_p) +{ + struct inferior_regcache_data *regcache + = (struct inferior_regcache_data *) regcache_p; + + free (regcache->registers); + free (regcache); +} + void set_register_cache (struct reg *regs, int n) { @@ -55,14 +139,13 @@ set_register_cache (struct reg *regs, int n) } register_bytes = offset / 8; - registers = malloc (offset / 8); - if (!registers) - fatal ("Could not allocate register cache."); } void registers_to_string (char *buf) { + char *registers = get_regcache (current_inferior, 1)->registers; + convert_int_to_ascii (registers, buf, register_bytes); } @@ -70,6 +153,7 @@ void registers_from_string (char *buf) { int len = strlen (buf); + char *registers = get_regcache (current_inferior, 1)->registers; if (len != register_bytes * 2) { @@ -116,32 +200,40 @@ register_size (int n) return reg_defs[n].size / 8; } -char * -register_data (int n) +static char * +register_data (int n, int fetch) { + char *registers = get_regcache (current_inferior, fetch)->registers; + return registers + (reg_defs[n].offset / 8); } void -supply_register (int n, const char *buf) +supply_register (int n, const void *buf) { - memcpy (register_data (n), buf, register_size (n)); + memcpy (register_data (n, 0), buf, register_size (n)); } void -supply_register_by_name (const char *name, const char *buf) +supply_register_by_name (const char *name, const void *buf) { supply_register (find_regno (name), buf); } void -collect_register (int n, char *buf) +collect_register (int n, void *buf) { - memcpy (buf, register_data (n), register_size (n)); + memcpy (buf, register_data (n, 1), register_size (n)); } void -collect_register_by_name (const char *name, char *buf) +collect_register_as_string (int n, char *buf) +{ + convert_int_to_ascii (register_data (n, 1), buf, register_size (n)); +} + +void +collect_register_by_name (const char *name, void *buf) { collect_register (find_regno (name), buf); } diff --git a/contrib/gdb/gdb/gdbserver/regcache.h b/contrib/gdb/gdb/gdbserver/regcache.h index 07195b3f44e..930bd9cbfe6 100644 --- a/contrib/gdb/gdb/gdbserver/regcache.h +++ b/contrib/gdb/gdb/gdbserver/regcache.h @@ -21,6 +21,21 @@ #ifndef REGCACHE_H #define REGCACHE_H +struct inferior_list_entry; + +/* Create a new register cache for INFERIOR. */ + +void *new_register_cache (void); + +/* Release all memory associated with the register cache for INFERIOR. */ + +void free_register_cache (void *regcache); + +/* Invalidate cached registers for one or all threads. */ + +void regcache_invalidate_one (struct inferior_list_entry *); +void regcache_invalidate (void); + /* Convert all registers to a string in the currently specified remote format. */ @@ -38,12 +53,20 @@ int registers_length (void); struct reg *find_register_by_number (int n); -char *register_data (int n); - int register_size (int n); int find_regno (const char *name); extern const char **gdbserver_expedite_regs; +void supply_register (int n, const void *buf); + +void supply_register_by_name (const char *name, const void *buf); + +void collect_register (int n, void *buf); + +void collect_register_as_string (int n, char *buf); + +void collect_register_by_name (const char *name, void *buf); + #endif /* REGCACHE_H */ diff --git a/contrib/gdb/gdb/gdbserver/remote-utils.c b/contrib/gdb/gdb/gdbserver/remote-utils.c index adf52996094..26b267a3aaf 100644 --- a/contrib/gdb/gdb/gdbserver/remote-utils.c +++ b/contrib/gdb/gdb/gdbserver/remote-utils.c @@ -1,6 +1,6 @@ /* Remote utility routines for the remote server for GDB. Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002 + 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -35,12 +35,17 @@ #include #include #include +#include int remote_debug = 0; struct ui_file *gdb_stdlog; static int remote_desc; +/* FIXME headerize? */ +extern int using_threads; +extern int debug_threads; + /* Open a connection to a remote debugger. NAME is the filename used for communication. */ @@ -130,6 +135,8 @@ remote_open (char *name) || listen (tmp_desc, 1)) perror_with_name ("Can't bind address"); + fprintf (stderr, "Listening on port %d\n", port); + tmp = sizeof (sockaddr); remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp); if (remote_desc == -1) @@ -185,6 +192,42 @@ fromhex (int a) return 0; } +int +unhexify (char *bin, const char *hex, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + if (hex[0] == 0 || hex[1] == 0) + { + /* Hex string is short, or of uneven length. + Return the count that has been converted so far. */ + return i; + } + *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]); + hex += 2; + } + return i; +} + +static void +decode_address (CORE_ADDR *addrp, const char *start, int len) +{ + CORE_ADDR addr; + char ch; + int i; + + addr = 0; + for (i = 0; i < len; i++) + { + ch = start[i]; + addr = addr << 4; + addr = addr | (fromhex (ch) & 0x0f); + } + *addrp = addr; +} + /* Convert number NIB to a hex digit. */ static int @@ -196,6 +239,24 @@ tohex (int nib) return 'a' + nib - 10; } +int +hexify (char *hex, const char *bin, int count) +{ + int i; + + /* May use a length, or a nul-terminated string as input. */ + if (count == 0) + count = strlen (bin); + + for (i = 0; i < count; i++) + { + *hex++ = tohex ((*bin >> 4) & 0xf); + *hex++ = tohex (*bin++ & 0xf); + } + *hex = 0; + return i; +} + /* Send a packet to the remote machine, with error checking. The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */ @@ -241,10 +302,17 @@ putpkt (char *buf) } if (remote_debug) - printf ("putpkt (\"%s\"); [looking for ack]\n", buf2); + { + fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2); + fflush (stderr); + } cc = read (remote_desc, buf3, 1); if (remote_debug) - printf ("[received '%c' (0x%x)]\n", buf3[0], buf3[0]); + { + fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]); + fflush (stderr); + } + if (cc <= 0) { if (cc == 0) @@ -255,6 +323,10 @@ putpkt (char *buf) free (buf2); return -1; } + + /* Check for an input interrupt while we're here. */ + if (buf3[0] == '\003') + (*the_target->send_signal) (SIGINT); } while (buf3[0] != '+'); @@ -291,10 +363,28 @@ input_interrupt (int unused) return; } - kill (inferior_pid, SIGINT); + (*the_target->send_signal) (SIGINT); } } +void +block_async_io (void) +{ + sigset_t sigio_set; + sigemptyset (&sigio_set); + sigaddset (&sigio_set, SIGIO); + sigprocmask (SIG_BLOCK, &sigio_set, NULL); +} + +void +unblock_async_io (void) +{ + sigset_t sigio_set; + sigemptyset (&sigio_set); + sigaddset (&sigio_set, SIGIO); + sigprocmask (SIG_UNBLOCK, &sigio_set, NULL); +} + void enable_async_io (void) { @@ -356,7 +446,11 @@ getpkt (char *buf) if (c == '$') break; if (remote_debug) - printf ("[getpkt: discarding char '%c']\n", c); + { + fprintf (stderr, "[getpkt: discarding char '%c']\n", c); + fflush (stderr); + } + if (c < 0) return -1; } @@ -386,12 +480,19 @@ getpkt (char *buf) } if (remote_debug) - printf ("getpkt (\"%s\"); [sending ack] \n", buf); + { + fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf); + fflush (stderr); + } write (remote_desc, "+", 1); if (remote_debug) - printf ("[sent ack]\n"); + { + fprintf (stderr, "[sent ack]\n"); + fflush (stderr); + } + return bp - buf; } @@ -406,9 +507,10 @@ write_ok (char *buf) void write_enn (char *buf) { + /* Some day, we should define the meanings of the error codes... */ buf[0] = 'E'; - buf[1] = 'N'; - buf[2] = 'N'; + buf[1] = '0'; + buf[2] = '1'; buf[3] = '\0'; } @@ -444,8 +546,6 @@ convert_ascii_to_int (char *from, char *to, int n) static char * outreg (int regno, char *buf) { - int regsize = register_size (regno); - if ((regno >> 12) != 0) *buf++ = tohex ((regno >> 12) & 0xf); if ((regno >> 8) != 0) @@ -453,13 +553,46 @@ outreg (int regno, char *buf) *buf++ = tohex ((regno >> 4) & 0xf); *buf++ = tohex (regno & 0xf); *buf++ = ':'; - convert_int_to_ascii (register_data (regno), buf, regsize); - buf += 2 * regsize; + collect_register_as_string (regno, buf); + buf += 2 * register_size (regno); *buf++ = ';'; return buf; } +void +new_thread_notify (int id) +{ + char own_buf[256]; + + /* The `n' response is not yet part of the remote protocol. Do nothing. */ + if (1) + return; + + if (server_waiting == 0) + return; + + sprintf (own_buf, "n%x", id); + disable_async_io (); + putpkt (own_buf); + enable_async_io (); +} + +void +dead_thread_notify (int id) +{ + char own_buf[256]; + + /* The `x' response is not yet part of the remote protocol. Do nothing. */ + if (1) + return; + + sprintf (own_buf, "x%x", id); + disable_async_io (); + putpkt (own_buf); + enable_async_io (); +} + void prepare_resume_reply (char *buf, char status, unsigned char signo) { @@ -483,12 +616,27 @@ prepare_resume_reply (char *buf, char status, unsigned char signo) regp ++; } - /* If the debugger hasn't used any thread features, don't burden it with - threads. If we didn't check this, GDB 4.13 and older would choke. */ - if (cont_thread != 0) + /* Formerly, if the debugger had not used any thread features we would not + burden it with a thread status response. This was for the benefit of + GDB 4.13 and older. However, in recent GDB versions the check + (``if (cont_thread != 0)'') does not have the desired effect because of + sillyness in the way that the remote protocol handles specifying a thread. + Since thread support relies on qSymbol support anyway, assume GDB can handle + threads. */ + + if (using_threads) { - if (old_thread_from_wait != thread_from_wait) + /* FIXME right place to set this? */ + thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id; + if (debug_threads) + fprintf (stderr, "Writing resume reply for %d\n\n", thread_from_wait); + /* This if (1) ought to be unnecessary. But remote_wait in GDB + will claim this event belongs to inferior_ptid if we do not + specify a thread, and there's no way for gdbserver to know + what inferior_ptid is. */ + if (1 || old_thread_from_wait != thread_from_wait) { + general_thread = thread_from_wait; sprintf (buf, "thread:%x;", thread_from_wait); buf += strlen (buf); old_thread_from_wait = thread_from_wait; @@ -543,3 +691,46 @@ decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr, convert_ascii_to_int (&from[i++], to, *len_ptr); } + +int +look_up_one_symbol (const char *name, CORE_ADDR *addrp) +{ + char own_buf[266], *p, *q; + int len; + + /* Send the request. */ + strcpy (own_buf, "qSymbol:"); + hexify (own_buf + strlen ("qSymbol:"), name, strlen (name)); + if (putpkt (own_buf) < 0) + return -1; + + /* FIXME: Eventually add buffer overflow checking (to getpkt?) */ + len = getpkt (own_buf); + if (len < 0) + return -1; + + if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0) + { + /* Malformed response. */ + if (remote_debug) + { + fprintf (stderr, "Malformed response to qSymbol, ignoring.\n"); + fflush (stderr); + } + + return -1; + } + + p = own_buf + strlen ("qSymbol:"); + q = p; + while (*q && *q != ':') + q++; + + /* Make sure we found a value for the symbol. */ + if (p == q || *q == '\0') + return 0; + + decode_address (addrp, p, q - p); + return 1; +} + diff --git a/contrib/gdb/gdb/gdbserver/server.c b/contrib/gdb/gdb/gdbserver/server.c index adaabacdf2f..93e3ea431bb 100644 --- a/contrib/gdb/gdb/gdbserver/server.c +++ b/contrib/gdb/gdb/gdbserver/server.c @@ -1,5 +1,5 @@ /* Main code for remote server for GDB. - Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002 + Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -21,22 +21,44 @@ #include "server.h" +#include +#include +#include + int cont_thread; int general_thread; +int step_thread; int thread_from_wait; int old_thread_from_wait; int extended_protocol; +int server_waiting; + jmp_buf toplevel; -int inferior_pid; + +/* The PID of the originally created or attached inferior. Used to + send signals to the process when GDB sends us an asynchronous interrupt + (user hitting Control-C in the client), and to wait for the child to exit + when no longer debugging it. */ + +int signal_pid; static unsigned char start_inferior (char *argv[], char *statusptr) { - inferior_pid = create_inferior (argv[0], argv); - fprintf (stderr, "Process %s created; pid = %d\n", argv[0], inferior_pid); + signal (SIGTTOU, SIG_DFL); + signal (SIGTTIN, SIG_DFL); + + signal_pid = create_inferior (argv[0], argv); + + fprintf (stderr, "Process %s created; pid = %d\n", argv[0], + signal_pid); + + signal (SIGTTOU, SIG_IGN); + signal (SIGTTIN, SIG_IGN); + tcsetpgrp (fileno (stderr), signal_pid); /* Wait till we are at 1st instruction in program, return signal number. */ - return mywait (statusptr); + return mywait (statusptr, 0); } static int @@ -44,18 +66,249 @@ attach_inferior (int pid, char *statusptr, unsigned char *sigptr) { /* myattach should return -1 if attaching is unsupported, 0 if it succeeded, and call error() otherwise. */ + if (myattach (pid) != 0) return -1; - inferior_pid = pid; + fprintf (stderr, "Attached; pid = %d\n", pid); - *sigptr = mywait (statusptr); + /* FIXME - It may be that we should get the SIGNAL_PID from the + attach function, so that it can be the main thread instead of + whichever we were told to attach to. */ + signal_pid = pid; + + *sigptr = mywait (statusptr, 0); return 0; } extern int remote_debug; +/* Handle all of the extended 'q' packets. */ +void +handle_query (char *own_buf) +{ + static struct inferior_list_entry *thread_ptr; + + if (strcmp ("qSymbol::", own_buf) == 0) + { + if (the_target->look_up_symbols != NULL) + (*the_target->look_up_symbols) (); + + strcpy (own_buf, "OK"); + return; + } + + if (strcmp ("qfThreadInfo", own_buf) == 0) + { + thread_ptr = all_threads.head; + sprintf (own_buf, "m%x", thread_ptr->id); + thread_ptr = thread_ptr->next; + return; + } + + if (strcmp ("qsThreadInfo", own_buf) == 0) + { + if (thread_ptr != NULL) + { + sprintf (own_buf, "m%x", thread_ptr->id); + thread_ptr = thread_ptr->next; + return; + } + else + { + sprintf (own_buf, "l"); + return; + } + } + + if (the_target->read_auxv != NULL + && strncmp ("qPart:auxv:read::", own_buf, 17) == 0) + { + char data[(PBUFSIZ - 1) / 2]; + CORE_ADDR ofs; + unsigned int len; + int n; + decode_m_packet (&own_buf[17], &ofs, &len); /* "OFS,LEN" */ + if (len > sizeof data) + len = sizeof data; + n = (*the_target->read_auxv) (ofs, data, len); + if (n == 0) + write_ok (own_buf); + else if (n < 0) + write_enn (own_buf); + else + convert_int_to_ascii (data, own_buf, n); + return; + } + + /* Otherwise we didn't know what packet it was. Say we didn't + understand it. */ + own_buf[0] = 0; +} + +/* Parse vCont packets. */ +void +handle_v_cont (char *own_buf, char *status, unsigned char *signal) +{ + char *p, *q; + int n = 0, i = 0; + struct thread_resume *resume_info, default_action; + + /* Count the number of semicolons in the packet. There should be one + for every action. */ + p = &own_buf[5]; + while (p) + { + n++; + p++; + p = strchr (p, ';'); + } + /* Allocate room for one extra action, for the default remain-stopped + behavior; if no default action is in the list, we'll need the extra + slot. */ + resume_info = malloc ((n + 1) * sizeof (resume_info[0])); + + default_action.thread = -1; + default_action.leave_stopped = 1; + default_action.step = 0; + default_action.sig = 0; + + p = &own_buf[5]; + i = 0; + while (*p) + { + p++; + + resume_info[i].leave_stopped = 0; + + if (p[0] == 's' || p[0] == 'S') + resume_info[i].step = 1; + else if (p[0] == 'c' || p[0] == 'C') + resume_info[i].step = 0; + else + goto err; + + if (p[0] == 'S' || p[0] == 'C') + { + int sig; + sig = strtol (p + 1, &q, 16); + if (p == q) + goto err; + p = q; + + if (!target_signal_to_host_p (sig)) + goto err; + resume_info[i].sig = target_signal_to_host (sig); + } + else + { + resume_info[i].sig = 0; + p = p + 1; + } + + if (p[0] == 0) + { + resume_info[i].thread = -1; + default_action = resume_info[i]; + + /* Note: we don't increment i here, we'll overwrite this entry + the next time through. */ + } + else if (p[0] == ':') + { + resume_info[i].thread = strtol (p + 1, &q, 16); + if (p == q) + goto err; + p = q; + if (p[0] != ';' && p[0] != 0) + goto err; + + i++; + } + } + + resume_info[i] = default_action; + + /* Still used in occasional places in the backend. */ + if (n == 1 && resume_info[0].thread != -1) + cont_thread = resume_info[0].thread; + else + cont_thread = -1; + set_desired_inferior (0); + + (*the_target->resume) (resume_info); + + free (resume_info); + + *signal = mywait (status, 1); + prepare_resume_reply (own_buf, *status, *signal); + return; + +err: + /* No other way to report an error... */ + strcpy (own_buf, ""); + free (resume_info); + return; +} + +/* Handle all of the extended 'v' packets. */ +void +handle_v_requests (char *own_buf, char *status, unsigned char *signal) +{ + if (strncmp (own_buf, "vCont;", 6) == 0) + { + handle_v_cont (own_buf, status, signal); + return; + } + + if (strncmp (own_buf, "vCont?", 6) == 0) + { + strcpy (own_buf, "vCont;c;C;s;S"); + return; + } + + /* Otherwise we didn't know what packet it was. Say we didn't + understand it. */ + own_buf[0] = 0; + return; +} + +void +myresume (int step, int sig) +{ + struct thread_resume resume_info[2]; + int n = 0; + + if (step || sig || cont_thread > 0) + { + resume_info[0].thread + = ((struct inferior_list_entry *) current_inferior)->id; + resume_info[0].step = step; + resume_info[0].sig = sig; + resume_info[0].leave_stopped = 0; + n++; + } + resume_info[n].thread = -1; + resume_info[n].step = 0; + resume_info[n].sig = 0; + resume_info[n].leave_stopped = (cont_thread > 0); + + (*the_target->resume) (resume_info); +} + +static int attached; + +static void +gdbserver_usage (void) +{ + error ("Usage:\tgdbserver COMM PROG [ARGS ...]\n" + "\tgdbserver COMM --attach PID\n" + "\n" + "COMM may either be a tty device (for serial debugging), or \n" + "HOST:PORT to listen for a TCP connection.\n"); +} + int main (int argc, char *argv[]) { @@ -64,9 +317,8 @@ main (int argc, char *argv[]) unsigned char signal; unsigned int len; CORE_ADDR mem_addr; - int bad_attach = 0; - int pid = 0; - int attached = 0; + int bad_attach; + int pid; char *arg_end; if (setjmp (toplevel)) @@ -75,6 +327,9 @@ main (int argc, char *argv[]) exit (1); } + bad_attach = 0; + pid = 0; + attached = 0; if (argc >= 3 && strcmp (argv[2], "--attach") == 0) { if (argc == 4 @@ -89,8 +344,7 @@ main (int argc, char *argv[]) } if (argc < 3 || bad_attach) - error ("Usage:\tgdbserver tty prog [args ...]\n" - "\tgdbserver tty --attach pid"); + gdbserver_usage(); initialize_low (); @@ -129,9 +383,34 @@ main (int argc, char *argv[]) ch = own_buf[i++]; switch (ch) { + case 'q': + handle_query (own_buf); + break; case 'd': remote_debug = !remote_debug; break; + case 'D': + fprintf (stderr, "Detaching from inferior\n"); + detach_inferior (); + write_ok (own_buf); + putpkt (own_buf); + remote_close (); + + /* If we are attached, then we can exit. Otherwise, we need to + hang around doing nothing, until the child is gone. */ + if (!attached) + { + int status, ret; + + do { + ret = waitpid (signal_pid, &status, 0); + if (WIFEXITED (status) || WIFSIGNALED (status)) + break; + } while (ret != -1 || errno != ECHILD); + } + + exit (0); + case '!': if (attached == 0) { @@ -155,12 +434,16 @@ main (int argc, char *argv[]) case 'g': general_thread = strtol (&own_buf[2], NULL, 16); write_ok (own_buf); - fetch_inferior_registers (0); + set_desired_inferior (1); break; case 'c': cont_thread = strtol (&own_buf[2], NULL, 16); write_ok (own_buf); break; + case 's': + step_thread = strtol (&own_buf[2], NULL, 16); + write_ok (own_buf); + break; default: /* Silently ignore it so that gdb can extend the protocol without compatibility headaches. */ @@ -169,17 +452,20 @@ main (int argc, char *argv[]) } break; case 'g': + set_desired_inferior (1); registers_to_string (own_buf); break; case 'G': + set_desired_inferior (1); registers_from_string (&own_buf[1]); - store_inferior_registers (-1); write_ok (own_buf); break; case 'm': decode_m_packet (&own_buf[1], &mem_addr, &len); - read_inferior_memory (mem_addr, mem_buf, len); - convert_int_to_ascii (mem_buf, own_buf, len); + if (read_inferior_memory (mem_addr, mem_buf, len) == 0) + convert_int_to_ascii (mem_buf, own_buf, len); + else + write_enn (own_buf); break; case 'M': decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf); @@ -194,8 +480,9 @@ main (int argc, char *argv[]) signal = target_signal_to_host (sig); else signal = 0; + set_desired_inferior (0); myresume (0, signal); - signal = mywait (&status); + signal = mywait (&status, 1); prepare_resume_reply (own_buf, status, signal); break; case 'S': @@ -204,18 +491,21 @@ main (int argc, char *argv[]) signal = target_signal_to_host (sig); else signal = 0; + set_desired_inferior (0); myresume (1, signal); - signal = mywait (&status); + signal = mywait (&status, 1); prepare_resume_reply (own_buf, status, signal); break; case 'c': + set_desired_inferior (0); myresume (0, 0); - signal = mywait (&status); + signal = mywait (&status, 1); prepare_resume_reply (own_buf, status, signal); break; case 's': + set_desired_inferior (0); myresume (1, 0); - signal = mywait (&status); + signal = mywait (&status, 1); prepare_resume_reply (own_buf, status, signal); break; case 'k': @@ -267,6 +557,10 @@ main (int argc, char *argv[]) own_buf[0] = '\0'; break; } + case 'v': + /* Extended (long) request. */ + handle_v_requests (own_buf, &status, &signal); + break; default: /* It is a request we don't understand. Respond with an empty packet so that gdb knows that we don't support this @@ -279,9 +573,10 @@ main (int argc, char *argv[]) if (status == 'W') fprintf (stderr, - "\nChild exited with status %d\n", sig); + "\nChild exited with status %d\n", signal); if (status == 'X') - fprintf (stderr, "\nChild terminated with signal = 0x%x\n", sig); + fprintf (stderr, "\nChild terminated with signal = 0x%x\n", + signal); if (status == 'W' || status == 'X') { if (extended_protocol) diff --git a/contrib/gdb/gdb/gdbserver/server.h b/contrib/gdb/gdb/gdbserver/server.h index 7f22041b23d..59dbcf97e1c 100644 --- a/contrib/gdb/gdb/gdbserver/server.h +++ b/contrib/gdb/gdb/gdbserver/server.h @@ -1,5 +1,5 @@ /* Common definitions for remote server for GDB. - Copyright 1993, 1995, 1997, 1998, 1999, 2000, 2002 + Copyright 1993, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -23,48 +23,106 @@ #define SERVER_H #include "config.h" + #include #include #include #include +#include +#ifdef HAVE_STRING_H +#include +#endif -/* FIXME: Both of these should be autoconf'd for. */ -#define NORETURN +#ifdef NEED_DECLARATION_STRERROR +#ifndef strerror +extern char *strerror (int); /* X3.159-1989 4.11.6.2 */ +#endif +#endif + +#ifndef ATTR_NORETURN +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) +#define ATTR_NORETURN __attribute__ ((noreturn)) +#else +#define ATTR_NORETURN /* nothing */ +#endif +#endif + +#ifndef ATTR_FORMAT +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 4)) +#define ATTR_FORMAT(type, x, y) __attribute__ ((format(type, x, y))) +#else +#define ATTR_FORMAT(type, x, y) /* nothing */ +#endif +#endif + +/* FIXME: This should probably be autoconf'd for. It's an integer type at + least the size of a (void *). */ typedef long long CORE_ADDR; +/* Generic information for tracking a list of ``inferiors'' - threads, + processes, etc. */ +struct inferior_list +{ + struct inferior_list_entry *head; + struct inferior_list_entry *tail; +}; +struct inferior_list_entry +{ + int id; + struct inferior_list_entry *next; +}; + +/* Opaque type for user-visible threads. */ +struct thread_info; + #include "regcache.h" #include "gdb/signals.h" -#include +#include "target.h" +#include "mem-break.h" /* Target-specific functions */ -int create_inferior (char *program, char **allargs); -void kill_inferior (void); -void fetch_inferior_registers (int regno); -void store_inferior_registers (int regno); -int mythread_alive (int pid); -void myresume (int step, int signo); -unsigned char mywait (char *status); -void read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len); -int write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len); -int create_inferior (); void initialize_low (); -/* Target-specific variables */ +/* From inferiors.c. */ -extern char *registers; +extern struct inferior_list all_threads; +void add_inferior_to_list (struct inferior_list *list, + struct inferior_list_entry *new_inferior); +void for_each_inferior (struct inferior_list *list, + void (*action) (struct inferior_list_entry *)); +extern struct thread_info *current_inferior; +void remove_inferior (struct inferior_list *list, + struct inferior_list_entry *entry); +void remove_thread (struct thread_info *thread); +void add_thread (int thread_id, void *target_data); +void clear_inferiors (void); +struct inferior_list_entry *find_inferior + (struct inferior_list *, + int (*func) (struct inferior_list_entry *, + void *), + void *arg); +struct inferior_list_entry *find_inferior_id (struct inferior_list *list, + int id); +void *inferior_target_data (struct thread_info *); +void set_inferior_target_data (struct thread_info *, void *); +void *inferior_regcache_data (struct thread_info *); +void set_inferior_regcache_data (struct thread_info *, void *); +void change_inferior_id (struct inferior_list *list, + int new_id); /* Public variables in server.c */ extern int cont_thread; extern int general_thread; +extern int step_thread; extern int thread_from_wait; extern int old_thread_from_wait; +extern int server_waiting; extern jmp_buf toplevel; -extern int inferior_pid; /* Functions from remote-utils.c */ @@ -76,8 +134,12 @@ void write_ok (char *buf); void write_enn (char *buf); void enable_async_io (void); void disable_async_io (void); +void unblock_async_io (void); +void block_async_io (void); void convert_ascii_to_int (char *from, char *to, int n); void convert_int_to_ascii (char *from, char *to, int n); +void new_thread_notify (int id); +void dead_thread_notify (int id); void prepare_resume_reply (char *buf, char status, unsigned char sig); void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr, @@ -85,6 +147,11 @@ void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr, void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr, unsigned int *len_ptr, char *to); +int unhexify (char *bin, const char *hex, int count); +int hexify (char *hex, const char *bin, int count); + +int look_up_one_symbol (const char *name, CORE_ADDR *addrp); + /* Functions from ``signals.c''. */ enum target_signal target_signal_from_host (int hostsig); int target_signal_to_host_p (enum target_signal oursig); @@ -93,11 +160,13 @@ int target_signal_to_host (enum target_signal oursig); /* Functions from utils.c */ void perror_with_name (char *string); -void error (const char *string,...); -void fatal (const char *string,...); +void error (const char *string,...) ATTR_NORETURN; +void fatal (const char *string,...) ATTR_NORETURN; void warning (const char *string,...); +/* Functions from the register cache definition. */ +void init_registers (void); /* Maximum number of bytes to read/write at once. The value here is chosen to fill up a packet (the headers account for the 32). */ diff --git a/contrib/gdb/gdb/gdbserver/target.c b/contrib/gdb/gdb/gdbserver/target.c new file mode 100644 index 00000000000..2c60e1777da --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/target.c @@ -0,0 +1,112 @@ +/* Target operations for the remote server for GDB. + Copyright 2002, 2004 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +struct target_ops *the_target; + +void +set_desired_inferior (int use_general) +{ + struct thread_info *found; + + if (use_general == 1) + { + found = (struct thread_info *) find_inferior_id (&all_threads, + general_thread); + } + else + { + found = NULL; + + /* If we are continuing any (all) thread(s), use step_thread + to decide which thread to step and/or send the specified + signal to. */ + if (step_thread > 0 && (cont_thread == 0 || cont_thread == -1)) + found = (struct thread_info *) find_inferior_id (&all_threads, + step_thread); + + if (found == NULL) + found = (struct thread_info *) find_inferior_id (&all_threads, + cont_thread); + } + + if (found == NULL) + current_inferior = (struct thread_info *) all_threads.head; + else + current_inferior = found; +} + +int +read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + int res; + res = (*the_target->read_memory) (memaddr, myaddr, len); + check_mem_read (memaddr, myaddr, len); + return res; +} + +int +write_inferior_memory (CORE_ADDR memaddr, const char *myaddr, int len) +{ + /* Lacking cleanups, there is some potential for a memory leak if the + write fails and we go through error(). Make sure that no more than + one buffer is ever pending by making BUFFER static. */ + static char *buffer = 0; + int res; + + if (buffer != NULL) + free (buffer); + + buffer = malloc (len); + memcpy (buffer, myaddr, len); + check_mem_write (memaddr, buffer, len); + res = (*the_target->write_memory) (memaddr, buffer, len); + free (buffer); + buffer = NULL; + + return res; +} + +unsigned char +mywait (char *statusp, int connected_wait) +{ + unsigned char ret; + + if (connected_wait) + server_waiting = 1; + + ret = (*the_target->wait) (statusp); + + if (connected_wait) + server_waiting = 0; + + return ret; +} + +void +set_target_ops (struct target_ops *target) +{ + the_target = (struct target_ops *) malloc (sizeof (*the_target)); + memcpy (the_target, target, sizeof (*the_target)); +} diff --git a/contrib/gdb/gdb/gdbserver/target.h b/contrib/gdb/gdb/gdbserver/target.h new file mode 100644 index 00000000000..770ffcbbb05 --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/target.h @@ -0,0 +1,171 @@ +/* Target operations for the remote server for GDB. + Copyright 2002, 2003, 2004 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TARGET_H +#define TARGET_H + +/* This structure describes how to resume a particular thread (or + all threads) based on the client's request. If thread is -1, then + this entry applies to all threads. These are generally passed around + as an array, and terminated by a thread == -1 entry. */ + +struct thread_resume +{ + int thread; + + /* If non-zero, leave this thread stopped. */ + int leave_stopped; + + /* If non-zero, we want to single-step. */ + int step; + + /* If non-zero, send this signal when we resume. */ + int sig; +}; + +struct target_ops +{ + /* Start a new process. + + PROGRAM is a path to the program to execute. + ARGS is a standard NULL-terminated array of arguments, + to be passed to the inferior as ``argv''. + + Returns the new PID on success, -1 on failure. Registers the new + process with the process list. */ + + int (*create_inferior) (char *program, char **args); + + /* Attach to a running process. + + PID is the process ID to attach to, specified by the user + or a higher layer. */ + + int (*attach) (int pid); + + /* Kill all inferiors. */ + + void (*kill) (void); + + /* Detach from all inferiors. */ + + void (*detach) (void); + + /* Return 1 iff the thread with process ID PID is alive. */ + + int (*thread_alive) (int pid); + + /* Resume the inferior process. */ + + void (*resume) (struct thread_resume *resume_info); + + /* Wait for the inferior process to change state. + + STATUSP will be filled in with a response code to send to GDB. + + Returns the signal which caused the process to stop. */ + + unsigned char (*wait) (char *status); + + /* Fetch registers from the inferior process. + + If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */ + + void (*fetch_registers) (int regno); + + /* Store registers to the inferior process. + + If REGNO is -1, store all registers; otherwise, store at least REGNO. */ + + void (*store_registers) (int regno); + + /* Read memory from the inferior process. This should generally be + called through read_inferior_memory, which handles breakpoint shadowing. + + Read LEN bytes at MEMADDR into a buffer at MYADDR. + + Returns 0 on success and errno on failure. */ + + int (*read_memory) (CORE_ADDR memaddr, char *myaddr, int len); + + /* Write memory to the inferior process. This should generally be + called through write_inferior_memory, which handles breakpoint shadowing. + + Write LEN bytes from the buffer at MYADDR to MEMADDR. + + Returns 0 on success and errno on failure. */ + + int (*write_memory) (CORE_ADDR memaddr, const char *myaddr, int len); + + /* Query GDB for the values of any symbols we're interested in. + This function is called whenever we receive a "qSymbols::" + query, which corresponds to every time more symbols (might) + become available. NULL if we aren't interested in any + symbols. */ + + void (*look_up_symbols) (void); + + /* Send a signal to the inferior process, however is appropriate. */ + void (*send_signal) (int); + + /* Read auxiliary vector data from the inferior process. + + Read LEN bytes at OFFSET into a buffer at MYADDR. */ + + int (*read_auxv) (CORE_ADDR offset, char *myaddr, unsigned int len); +}; + +extern struct target_ops *the_target; + +void set_target_ops (struct target_ops *); + +#define create_inferior(program, args) \ + (*the_target->create_inferior) (program, args) + +#define myattach(pid) \ + (*the_target->attach) (pid) + +#define kill_inferior() \ + (*the_target->kill) () + +#define detach_inferior() \ + (*the_target->detach) () + +#define mythread_alive(pid) \ + (*the_target->thread_alive) (pid) + +#define fetch_inferior_registers(regno) \ + (*the_target->fetch_registers) (regno) + +#define store_inferior_registers(regno) \ + (*the_target->store_registers) (regno) + +unsigned char mywait (char *statusp, int connected_wait); + +int read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len); + +int write_inferior_memory (CORE_ADDR memaddr, const char *myaddr, int len); + +void set_desired_inferior (int id); + +#endif /* TARGET_H */ diff --git a/contrib/gdb/gdb/gdbserver/thread-db.c b/contrib/gdb/gdb/gdbserver/thread-db.c new file mode 100644 index 00000000000..f3d57a54d62 --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/thread-db.c @@ -0,0 +1,342 @@ +/* Thread management interface, for the remote server for GDB. + Copyright 2002 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#include "linux-low.h" + +extern int debug_threads; + +#ifdef HAVE_THREAD_DB_H +#include +#endif + +/* Correct for all GNU/Linux targets (for quite some time). */ +#define GDB_GREGSET_T elf_gregset_t +#define GDB_FPREGSET_T elf_fpregset_t + +#ifndef HAVE_ELF_FPREGSET_T +/* Make sure we have said types. Not all platforms bring in + via . */ +#ifdef HAVE_LINUX_ELF_H +#include +#endif +#endif + +#include "../gdb_proc_service.h" + +/* Structure that identifies the child process for the + interface. */ +static struct ps_prochandle proc_handle; + +/* Connection to the libthread_db library. */ +static td_thragent_t *thread_agent; + +static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data); + +static char * +thread_db_err_str (td_err_e err) +{ + static char buf[64]; + + switch (err) + { + case TD_OK: + return "generic 'call succeeded'"; + case TD_ERR: + return "generic error"; + case TD_NOTHR: + return "no thread to satisfy query"; + case TD_NOSV: + return "no sync handle to satisfy query"; + case TD_NOLWP: + return "no LWP to satisfy query"; + case TD_BADPH: + return "invalid process handle"; + case TD_BADTH: + return "invalid thread handle"; + case TD_BADSH: + return "invalid synchronization handle"; + case TD_BADTA: + return "invalid thread agent"; + case TD_BADKEY: + return "invalid key"; + case TD_NOMSG: + return "no event message for getmsg"; + case TD_NOFPREGS: + return "FPU register set not available"; + case TD_NOLIBTHREAD: + return "application not linked with libthread"; + case TD_NOEVENT: + return "requested event is not supported"; + case TD_NOCAPAB: + return "capability not available"; + case TD_DBERR: + return "debugger service failed"; + case TD_NOAPLIC: + return "operation not applicable to"; + case TD_NOTSD: + return "no thread-specific data for this thread"; + case TD_MALLOC: + return "malloc failed"; + case TD_PARTIALREG: + return "only part of register set was written/read"; + case TD_NOXREGS: + return "X register set not available for this thread"; + default: + snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err); + return buf; + } +} + +#if 0 +static char * +thread_db_state_str (td_thr_state_e state) +{ + static char buf[64]; + + switch (state) + { + case TD_THR_STOPPED: + return "stopped by debugger"; + case TD_THR_RUN: + return "runnable"; + case TD_THR_ACTIVE: + return "active"; + case TD_THR_ZOMBIE: + return "zombie"; + case TD_THR_SLEEP: + return "sleeping"; + case TD_THR_STOPPED_ASLEEP: + return "stopped by debugger AND blocked"; + default: + snprintf (buf, sizeof (buf), "unknown thread_db state %d", state); + return buf; + } +} +#endif + +static void +thread_db_create_event (CORE_ADDR where) +{ + td_event_msg_t msg; + td_err_e err; + struct inferior_linux_data *tdata; + + if (debug_threads) + fprintf (stderr, "Thread creation event.\n"); + + tdata = inferior_target_data (current_inferior); + + /* FIXME: This assumes we don't get another event. + In the LinuxThreads implementation, this is safe, + because all events come from the manager thread + (except for its own creation, of course). */ + err = td_ta_event_getmsg (thread_agent, &msg); + if (err != TD_OK) + fprintf (stderr, "thread getmsg err: %s\n", + thread_db_err_str (err)); + + /* msg.event == TD_EVENT_CREATE */ + + find_new_threads_callback (msg.th_p, NULL); +} + +#if 0 +static void +thread_db_death_event (CORE_ADDR where) +{ + if (debug_threads) + fprintf (stderr, "Thread death event.\n"); +} +#endif + +static int +thread_db_enable_reporting () +{ + td_thr_events_t events; + td_notify_t notify; + td_err_e err; + + /* Set the process wide mask saying which events we're interested in. */ + td_event_emptyset (&events); + td_event_addset (&events, TD_CREATE); + +#if 0 + /* This is reported to be broken in glibc 2.1.3. A different approach + will be necessary to support that. */ + td_event_addset (&events, TD_DEATH); +#endif + + err = td_ta_set_event (thread_agent, &events); + if (err != TD_OK) + { + warning ("Unable to set global thread event mask: %s", + thread_db_err_str (err)); + return 0; + } + + /* Get address for thread creation breakpoint. */ + err = td_ta_event_addr (thread_agent, TD_CREATE, ¬ify); + if (err != TD_OK) + { + warning ("Unable to get location for thread creation breakpoint: %s", + thread_db_err_str (err)); + return 0; + } + set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr, + thread_db_create_event); + +#if 0 + /* Don't concern ourselves with reported thread deaths, only + with actual thread deaths (via wait). */ + + /* Get address for thread death breakpoint. */ + err = td_ta_event_addr (thread_agent, TD_DEATH, ¬ify); + if (err != TD_OK) + { + warning ("Unable to get location for thread death breakpoint: %s", + thread_db_err_str (err)); + return; + } + set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr, + thread_db_death_event); +#endif + + return 1; +} + +static void +maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p) +{ + td_err_e err; + struct thread_info *inferior; + struct process_info *process; + + /* If we are attaching to our first thread, things are a little + different. */ + if (all_threads.head == all_threads.tail) + { + inferior = (struct thread_info *) all_threads.head; + process = get_thread_process (inferior); + if (process->thread_known == 0) + { + /* Switch to indexing the threads list by TID. */ + change_inferior_id (&all_threads, ti_p->ti_tid); + goto found; + } + } + + inferior = (struct thread_info *) find_inferior_id (&all_threads, + ti_p->ti_tid); + if (inferior != NULL) + return; + + if (debug_threads) + fprintf (stderr, "Attaching to thread %ld (LWP %d)\n", + ti_p->ti_tid, ti_p->ti_lid); + linux_attach_lwp (ti_p->ti_lid, ti_p->ti_tid); + inferior = (struct thread_info *) find_inferior_id (&all_threads, + ti_p->ti_tid); + if (inferior == NULL) + { + warning ("Could not attach to thread %ld (LWP %d)\n", + ti_p->ti_tid, ti_p->ti_lid); + return; + } + + process = inferior_target_data (inferior); + +found: + new_thread_notify (ti_p->ti_tid); + + process->tid = ti_p->ti_tid; + process->lwpid = ti_p->ti_lid; + + process->thread_known = 1; + err = td_thr_event_enable (th_p, 1); + if (err != TD_OK) + error ("Cannot enable thread event reporting for %d: %s", + ti_p->ti_lid, thread_db_err_str (err)); +} + +static int +find_new_threads_callback (const td_thrhandle_t *th_p, void *data) +{ + td_thrinfo_t ti; + td_err_e err; + + err = td_thr_get_info (th_p, &ti); + if (err != TD_OK) + error ("Cannot get thread info: %s", thread_db_err_str (err)); + + /* Check for zombies. */ + if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) + return 0; + + maybe_attach_thread (th_p, &ti); + + return 0; +} + +static void +thread_db_find_new_threads (void) +{ + td_err_e err; + + /* Iterate over all user-space threads to discover new threads. */ + err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL, + TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, + TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); + if (err != TD_OK) + error ("Cannot find new threads: %s", thread_db_err_str (err)); +} + +int +thread_db_init () +{ + int err; + + proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id; + + err = td_ta_new (&proc_handle, &thread_agent); + switch (err) + { + case TD_NOLIBTHREAD: + /* No thread library was detected. */ + return 0; + + case TD_OK: + /* The thread library was detected. */ + + if (thread_db_enable_reporting () == 0) + return 0; + thread_db_find_new_threads (); + return 1; + + default: + warning ("error initializing thread_db library."); + } + + return 0; +} diff --git a/contrib/gdb/gdb/gdbserver/utils.c b/contrib/gdb/gdb/gdbserver/utils.c index a8ea9a15f8b..44bdccfb160 100644 --- a/contrib/gdb/gdb/gdbserver/utils.c +++ b/contrib/gdb/gdb/gdbserver/utils.c @@ -1,5 +1,5 @@ /* General utility routines for the remote server for GDB. - Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002 + Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -33,16 +33,13 @@ void perror_with_name (char *string) { #ifndef STDC_HEADERS - extern int sys_nerr; - extern char *sys_errlist[]; extern int errno; #endif const char *err; char *combined; - if (errno < sys_nerr) - err = sys_errlist[errno]; - else + err = strerror (errno); + if (err == NULL) err = "unknown error"; combined = (char *) alloca (strlen (err) + strlen (string) + 3); @@ -57,7 +54,7 @@ perror_with_name (char *string) STRING is the error message, used as a fprintf string, and ARG is passed as an argument to it. */ -NORETURN void +void error (const char *string,...) { extern jmp_buf toplevel; @@ -74,7 +71,7 @@ error (const char *string,...) STRING and ARG are passed to fprintf. */ /* VARARGS */ -NORETURN void +void fatal (const char *string,...) { va_list args; diff --git a/contrib/gdb/gdb/gdbthread.h b/contrib/gdb/gdb/gdbthread.h index da89b36eee1..09dea26ca8c 100644 --- a/contrib/gdb/gdb/gdbthread.h +++ b/contrib/gdb/gdb/gdbthread.h @@ -25,9 +25,16 @@ #ifndef GDBTHREAD_H #define GDBTHREAD_H +struct breakpoint; +struct frame_id; +struct symtab; + /* For bpstat */ #include "breakpoint.h" +/* For struct frame_id. */ +#include "frame.h" + struct thread_info { struct thread_info *next; @@ -37,13 +44,11 @@ struct thread_info int num; /* Convenient handle (GDB thread id) */ /* State from wait_for_inferior */ CORE_ADDR prev_pc; - CORE_ADDR prev_func_start; - char *prev_func_name; struct breakpoint *step_resume_breakpoint; struct breakpoint *through_sigtramp_breakpoint; CORE_ADDR step_range_start; CORE_ADDR step_range_end; - CORE_ADDR step_frame_address; + struct frame_id step_frame_id; CORE_ADDR step_sp; int current_line; struct symtab *current_symtab; @@ -111,14 +116,12 @@ extern struct thread_info *iterate_over_threads (thread_callback_func, void *); /* infrun context switch: save the debugger state for the given thread. */ extern void save_infrun_state (ptid_t ptid, CORE_ADDR prev_pc, - CORE_ADDR prev_func_start, - char *prev_func_name, int trap_expected, struct breakpoint *step_resume_breakpoint, struct breakpoint *through_sigtramp_breakpoint, CORE_ADDR step_range_start, CORE_ADDR step_range_end, - CORE_ADDR step_frame_address, + const struct frame_id *step_frame_id, int handling_longjmp, int another_trap, int stepping_through_solib_after_catch, @@ -132,14 +135,12 @@ extern void save_infrun_state (ptid_t ptid, for the given thread. */ extern void load_infrun_state (ptid_t ptid, CORE_ADDR *prev_pc, - CORE_ADDR *prev_func_start, - char **prev_func_name, int *trap_expected, struct breakpoint **step_resume_breakpoint, struct breakpoint **through_sigtramp_breakpoint, CORE_ADDR *step_range_start, CORE_ADDR *step_range_end, - CORE_ADDR *step_frame_address, + struct frame_id *step_frame_id, int *handling_longjmp, int *another_trap, int *stepping_through_solib_affter_catch, diff --git a/contrib/gdb/gdb/gdbtypes.c b/contrib/gdb/gdb/gdbtypes.c index a13847e6b6f..1349ffbbe19 100644 --- a/contrib/gdb/gdb/gdbtypes.c +++ b/contrib/gdb/gdb/gdbtypes.c @@ -1,6 +1,6 @@ /* Support routines for manipulating internal types for GDB. - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, + 2004 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. This file is part of GDB. @@ -60,6 +60,7 @@ struct type *builtin_type_long_double; struct type *builtin_type_complex; struct type *builtin_type_double_complex; struct type *builtin_type_string; +struct type *builtin_type_int0; struct type *builtin_type_int8; struct type *builtin_type_uint8; struct type *builtin_type_int16; @@ -71,6 +72,20 @@ struct type *builtin_type_uint64; struct type *builtin_type_int128; struct type *builtin_type_uint128; struct type *builtin_type_bool; + +/* 128 bit long vector types */ +struct type *builtin_type_v2_double; +struct type *builtin_type_v4_float; +struct type *builtin_type_v2_int64; +struct type *builtin_type_v4_int32; +struct type *builtin_type_v8_int16; +struct type *builtin_type_v16_int8; +/* 64 bit long vector types */ +struct type *builtin_type_v2_float; +struct type *builtin_type_v2_int32; +struct type *builtin_type_v4_int16; +struct type *builtin_type_v8_int8; + struct type *builtin_type_v4sf; struct type *builtin_type_v4si; struct type *builtin_type_v16qi; @@ -78,7 +93,10 @@ struct type *builtin_type_v8qi; struct type *builtin_type_v8hi; struct type *builtin_type_v4hi; struct type *builtin_type_v2si; +struct type *builtin_type_vec64; +struct type *builtin_type_vec64i; struct type *builtin_type_vec128; +struct type *builtin_type_vec128i; struct type *builtin_type_ieee_single_big; struct type *builtin_type_ieee_single_little; struct type *builtin_type_ieee_double_big; @@ -109,13 +127,8 @@ struct extra int len; }; /* maximum extension is 128! FIXME */ -static void add_name (struct extra *, char *); -static void add_mangled_type (struct extra *, struct type *); -#if 0 -static void cfront_mangle_name (struct type *, int, int); -#endif static void print_bit_vector (B_TYPE *, int); -static void print_arg_types (struct type **, int); +static void print_arg_types (struct field *, int, int); static void dump_fn_fieldlists (struct type *, int); static void print_cplus_stuff (struct type *, int); static void virtual_base_list_aux (struct type *dclass); @@ -123,38 +136,85 @@ static void virtual_base_list_aux (struct type *dclass); /* Alloc a new type structure and fill it with some defaults. If OBJFILE is non-NULL, then allocate the space for the type structure - in that objfile's type_obstack. */ + in that objfile's objfile_obstack. Otherwise allocate the new type structure + by xmalloc () (for permanent types). */ struct type * alloc_type (struct objfile *objfile) { - register struct type *type; + struct type *type; /* Alloc the structure and start off with all fields zeroed. */ if (objfile == NULL) { - type = (struct type *) xmalloc (sizeof (struct type)); + type = xmalloc (sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + TYPE_MAIN_TYPE (type) = xmalloc (sizeof (struct main_type)); } else { - type = (struct type *) obstack_alloc (&objfile->type_obstack, - sizeof (struct type)); + type = obstack_alloc (&objfile->objfile_obstack, + sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + TYPE_MAIN_TYPE (type) = obstack_alloc (&objfile->objfile_obstack, + sizeof (struct main_type)); OBJSTAT (objfile, n_types++); } - memset ((char *) type, 0, sizeof (struct type)); + memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type)); /* Initialize the fields that might not be zero. */ TYPE_CODE (type) = TYPE_CODE_UNDEF; TYPE_OBJFILE (type) = objfile; TYPE_VPTR_FIELDNO (type) = -1; - TYPE_CV_TYPE (type) = type; /* chain back to itself */ - TYPE_AS_TYPE (type) = type; /* ditto */ + TYPE_CHAIN (type) = type; /* Chain back to itself. */ return (type); } +/* Alloc a new type instance structure, fill it with some defaults, + and point it at OLDTYPE. Allocate the new type instance from the + same place as OLDTYPE. */ + +static struct type * +alloc_type_instance (struct type *oldtype) +{ + struct type *type; + + /* Allocate the structure. */ + + if (TYPE_OBJFILE (oldtype) == NULL) + { + type = xmalloc (sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + } + else + { + type = obstack_alloc (&TYPE_OBJFILE (oldtype)->objfile_obstack, + sizeof (struct type)); + memset (type, 0, sizeof (struct type)); + } + TYPE_MAIN_TYPE (type) = TYPE_MAIN_TYPE (oldtype); + + TYPE_CHAIN (type) = type; /* Chain back to itself for now. */ + + return (type); +} + +/* Clear all remnants of the previous type at TYPE, in preparation for + replacing it with something else. */ +static void +smash_type (struct type *type) +{ + memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type)); + + /* For now, delete the rings. */ + TYPE_CHAIN (type) = type; + + /* For now, leave the pointer/reference types alone. */ +} + /* Lookup a pointer to a type TYPE. TYPEPTR, if nonzero, points to a pointer to memory where the pointer type should be stored. If *TYPEPTR is zero, update it to point to the pointer type we return. @@ -163,7 +223,7 @@ alloc_type (struct objfile *objfile) struct type * make_pointer_type (struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ + struct type *ntype; /* New type */ struct objfile *objfile; ntype = TYPE_POINTER_TYPE (type); @@ -190,7 +250,7 @@ make_pointer_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -230,7 +290,7 @@ lookup_pointer_type (struct type *type) struct type * make_reference_type (struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ + struct type *ntype; /* New type */ struct objfile *objfile; ntype = TYPE_REFERENCE_TYPE (type); @@ -257,7 +317,7 @@ make_reference_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -292,7 +352,7 @@ lookup_reference_type (struct type *type) struct type * make_function_type (struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ + struct type *ntype; /* New type */ struct objfile *objfile; if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ @@ -306,7 +366,7 @@ make_function_type (struct type *type, struct type **typeptr) { ntype = *typeptr; objfile = TYPE_OBJFILE (ntype); - memset ((char *) ntype, 0, sizeof (struct type)); + smash_type (ntype); TYPE_OBJFILE (ntype) = objfile; } @@ -333,11 +393,18 @@ lookup_function_type (struct type *type) extern int address_space_name_to_int (char *space_identifier) { + struct gdbarch *gdbarch = current_gdbarch; + int type_flags; /* Check for known address space delimiters. */ if (!strcmp (space_identifier, "code")) return TYPE_FLAG_CODE_SPACE; else if (!strcmp (space_identifier, "data")) return TYPE_FLAG_DATA_SPACE; + else if (gdbarch_address_class_name_to_type_flags_p (gdbarch) + && gdbarch_address_class_name_to_type_flags (gdbarch, + space_identifier, + &type_flags)) + return type_flags; else error ("Unknown address space specifier: \"%s\"", space_identifier); } @@ -345,57 +412,85 @@ address_space_name_to_int (char *space_identifier) /* Identify address space identifier by integer flag as defined in gdbtypes.h -- return the string version of the adress space name. */ -extern char * +const char * address_space_int_to_name (int space_flag) { + struct gdbarch *gdbarch = current_gdbarch; if (space_flag & TYPE_FLAG_CODE_SPACE) return "code"; else if (space_flag & TYPE_FLAG_DATA_SPACE) return "data"; + else if ((space_flag & TYPE_FLAG_ADDRESS_CLASS_ALL) + && gdbarch_address_class_type_flags_to_name_p (gdbarch)) + return gdbarch_address_class_type_flags_to_name (gdbarch, space_flag); else return NULL; } +/* Create a new type with instance flags NEW_FLAGS, based on TYPE. + If STORAGE is non-NULL, create the new type instance there. */ + +static struct type * +make_qualified_type (struct type *type, int new_flags, + struct type *storage) +{ + struct type *ntype; + + ntype = type; + do { + if (TYPE_INSTANCE_FLAGS (ntype) == new_flags) + return ntype; + ntype = TYPE_CHAIN (ntype); + } while (ntype != type); + + /* Create a new type instance. */ + if (storage == NULL) + ntype = alloc_type_instance (type); + else + { + ntype = storage; + TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type); + TYPE_CHAIN (ntype) = ntype; + } + + /* Pointers or references to the original type are not relevant to + the new type. */ + TYPE_POINTER_TYPE (ntype) = (struct type *) 0; + TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; + + /* Chain the new qualified type to the old type. */ + TYPE_CHAIN (ntype) = TYPE_CHAIN (type); + TYPE_CHAIN (type) = ntype; + + /* Now set the instance flags and return the new type. */ + TYPE_INSTANCE_FLAGS (ntype) = new_flags; + + /* Set length of new type to that of the original type. */ + TYPE_LENGTH (ntype) = TYPE_LENGTH (type); + + return ntype; +} + /* Make an address-space-delimited variant of a type -- a type that is identical to the one supplied except that it has an address space attribute attached to it (such as "code" or "data"). - This is for Harvard architectures. */ + The space attributes "code" and "data" are for Harvard architectures. + The address space attributes are for architectures which have + alternately sized pointers or pointers with alternate representations. */ struct type * make_type_with_address_space (struct type *type, int space_flag) { struct type *ntype; + int new_flags = ((TYPE_INSTANCE_FLAGS (type) + & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE + | TYPE_FLAG_ADDRESS_CLASS_ALL)) + | space_flag); - ntype = type; - do { - if ((ntype->flags & space_flag) != 0) - return ntype; - ntype = TYPE_AS_TYPE (ntype); - } while (ntype != type); - - /* Create a new, duplicate type. */ - ntype = alloc_type (TYPE_OBJFILE (type)); - /* Copy original type. */ - memcpy ((char *) ntype, (char *) type, sizeof (struct type)); - - /* Pointers or references to the original type are not relevant to - the new type; but if the original type is a pointer, the new type - points to the same thing (so TYPE_TARGET_TYPE remains unchanged). */ - TYPE_POINTER_TYPE (ntype) = (struct type *) 0; - TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; - TYPE_CV_TYPE (ntype) = ntype; - - /* Chain the new address-space-specific type to the old type. */ - ntype->as_type = type->as_type; - type->as_type = ntype; - - /* Now set the address-space flag, and return the new type. */ - ntype->flags |= space_flag; - return ntype; + return make_qualified_type (type, new_flags, NULL); } - /* Make a "c-v" variant of a type -- a type that is identical to the one supplied except that it may have const or volatile attributes CNST is a flag for setting the const attribute @@ -409,140 +504,80 @@ make_type_with_address_space (struct type *type, int space_flag) struct type * make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr) { - register struct type *ntype; /* New type */ - register struct type *tmp_type = type; /* tmp type */ + struct type *ntype; /* New type */ + struct type *tmp_type = type; /* tmp type */ struct objfile *objfile; - ntype = TYPE_CV_TYPE (type); + int new_flags = (TYPE_INSTANCE_FLAGS (type) + & ~(TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE)); - while (ntype != type) - { - if ((TYPE_CONST (ntype) == cnst) && - (TYPE_VOLATILE (ntype) == voltl)) - { - if (typeptr == 0) - return ntype; - else if (*typeptr == 0) - { - *typeptr = ntype; /* Tracking alloc, and we have new type. */ - return ntype; - } - } - tmp_type = ntype; - ntype = TYPE_CV_TYPE (ntype); - } - - if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ - { - ntype = alloc_type (TYPE_OBJFILE (type)); - if (typeptr) - *typeptr = ntype; - } - else - /* We have storage, but need to reset it. */ - { - ntype = *typeptr; - objfile = TYPE_OBJFILE (ntype); - /* memset ((char *) ntype, 0, sizeof (struct type)); */ - TYPE_OBJFILE (ntype) = objfile; - } - - /* Copy original type */ - memcpy ((char *) ntype, (char *) type, sizeof (struct type)); - /* But zero out fields that shouldn't be copied */ - TYPE_POINTER_TYPE (ntype) = (struct type *) 0; /* Need new pointer kind */ - TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; /* Need new referene kind */ - TYPE_AS_TYPE (ntype) = ntype; /* Need new address-space kind. */ - /* Note: TYPE_TARGET_TYPE can be left as is */ - - /* Set flags appropriately */ if (cnst) - TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST; - else - TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST; + new_flags |= TYPE_FLAG_CONST; if (voltl) - TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE; - else - TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE; + new_flags |= TYPE_FLAG_VOLATILE; - /* Fix the chain of cv variants */ - TYPE_CV_TYPE (ntype) = type; - TYPE_CV_TYPE (tmp_type) = ntype; + if (typeptr && *typeptr != NULL) + { + /* Objfile is per-core-type. This const-qualified type had best + belong to the same objfile as the type it is qualifying, unless + we are overwriting a stub type, in which case the safest thing + to do is to copy the core type into the new objfile. */ + + gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type) + || TYPE_STUB (*typeptr)); + if (TYPE_OBJFILE (*typeptr) != TYPE_OBJFILE (type)) + { + TYPE_MAIN_TYPE (*typeptr) + = TYPE_ALLOC (*typeptr, sizeof (struct main_type)); + *TYPE_MAIN_TYPE (*typeptr) + = *TYPE_MAIN_TYPE (type); + } + } + + ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL); + + if (typeptr != NULL) + *typeptr = ntype; return ntype; } -/* When reading in a class type, we may have created references to - cv-qualified versions of the type (in method arguments, for - instance). Update everything on the cv ring from the primary - type TYPE. +/* Replace the contents of ntype with the type *type. This changes the + contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus + the changes are propogated to all types in the TYPE_CHAIN. - The only reason we do not need to do the same thing for address - spaces is that type readers do not create address space qualified - types. */ -void -finish_cv_type (struct type *type) -{ - struct type *ntype, *cv_type, *ptr_type, *ref_type; - int cv_flags; - - gdb_assert (!TYPE_CONST (type) && !TYPE_VOLATILE (type)); - - ntype = type; - while ((ntype = TYPE_CV_TYPE (ntype)) != type) - { - /* Save cv_flags. */ - cv_flags = TYPE_FLAGS (ntype) & (TYPE_FLAG_VOLATILE | TYPE_FLAG_CONST); - - /* If any reference or pointer types were created, save them too. */ - ptr_type = TYPE_POINTER_TYPE (ntype); - ref_type = TYPE_REFERENCE_TYPE (ntype); - - /* Don't disturb the CV chain. */ - cv_type = TYPE_CV_TYPE (ntype); - - /* Verify that we haven't added any address-space qualified types, - for the future. */ - gdb_assert (ntype == TYPE_AS_TYPE (ntype)); - - /* Copy original type */ - memcpy ((char *) ntype, (char *) type, sizeof (struct type)); - - /* Restore everything. */ - TYPE_POINTER_TYPE (ntype) = ptr_type; - TYPE_REFERENCE_TYPE (ntype) = ref_type; - TYPE_CV_TYPE (ntype) = cv_type; - TYPE_FLAGS (ntype) = TYPE_FLAGS (ntype) | cv_flags; - - TYPE_AS_TYPE (ntype) = ntype; - } -} - -/* Replace the contents of ntype with the type *type. - - This function should not be necessary, but is due to quirks in the stabs - reader. This should go away. It does not handle the replacement type - being cv-qualified; it could be easily fixed to, but it should go away, - remember? */ + In order to build recursive types, it's inevitable that we'll need + to update types in place --- but this sort of indiscriminate + smashing is ugly, and needs to be replaced with something more + controlled. TYPE_MAIN_TYPE is a step in this direction; it's not + clear if more steps are needed. */ void replace_type (struct type *ntype, struct type *type) { - struct type *cv_chain, *as_chain, *ptr, *ref; + struct type *chain; - cv_chain = TYPE_CV_TYPE (ntype); - as_chain = TYPE_AS_TYPE (ntype); - ptr = TYPE_POINTER_TYPE (ntype); - ref = TYPE_REFERENCE_TYPE (ntype); + *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type); - *ntype = *type; + /* The type length is not a part of the main type. Update it for each + type on the variant chain. */ + chain = ntype; + do { + /* Assert that this element of the chain has no address-class bits + set in its flags. Such type variants might have type lengths + which are supposed to be different from the non-address-class + variants. This assertion shouldn't ever be triggered because + symbol readers which do construct address-class variants don't + call replace_type(). */ + gdb_assert (TYPE_ADDRESS_CLASS_ALL (chain) == 0); - TYPE_POINTER_TYPE (ntype) = ptr; - TYPE_REFERENCE_TYPE (ntype) = ref; - TYPE_CV_TYPE (ntype) = cv_chain; - TYPE_AS_TYPE (ntype) = as_chain; + TYPE_LENGTH (ntype) = TYPE_LENGTH (type); + chain = TYPE_CHAIN (chain); + } while (ntype != chain); - finish_cv_type (ntype); + /* Assert that the two types have equivalent instance qualifiers. + This should be true for at least all of our debug readers. */ + gdb_assert (TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type)); } /* Implement direct support for MEMBER_TYPE in GNU C++. @@ -553,7 +588,7 @@ replace_type (struct type *ntype, struct type *type) struct type * lookup_member_type (struct type *type, struct type *domain) { - register struct type *mtype; + struct type *mtype; mtype = alloc_type (TYPE_OBJFILE (type)); smash_to_member_type (mtype, domain, type); @@ -575,7 +610,6 @@ allocate_stub_method (struct type *type) TYPE_OBJFILE (type)); TYPE_TARGET_TYPE (mtype) = type; /* _DOMAIN_TYPE (mtype) = unknown yet */ - /* _ARG_TYPES (mtype) = unknown yet */ return (mtype); } @@ -777,7 +811,6 @@ create_set_type (struct type *result_type, struct type *domain_type) return (result_type); } - /* Construct and return a type of the form: struct NAME { ELT_TYPE ELT_NAME[N]; } We use these types for SIMD registers. For example, the type of @@ -793,24 +826,84 @@ init_simd_type (char *name, char *elt_name, int n) { + struct type *simd_type; + struct type *array_type; + + simd_type = init_composite_type (name, TYPE_CODE_STRUCT); + array_type = create_array_type (0, elt_type, + create_range_type (0, builtin_type_int, + 0, n-1)); + append_composite_type_field (simd_type, elt_name, array_type); + return simd_type; +} + +static struct type * +init_vector_type (struct type *elt_type, int n) +{ + struct type *array_type; + + array_type = create_array_type (0, elt_type, + create_range_type (0, builtin_type_int, + 0, n-1)); + TYPE_FLAGS (array_type) |= TYPE_FLAG_VECTOR; + return array_type; +} + +static struct type * +build_builtin_type_vec64 (void) +{ + /* Construct a type for the 64 bit registers. The type we're + building is this: */ +#if 0 + union __gdb_builtin_type_vec64 + { + int64_t uint64; + float v2_float[2]; + int32_t v2_int32[2]; + int16_t v4_int16[4]; + int8_t v8_int8[8]; + }; +#endif + struct type *t; - struct field *f; - /* Build the field structure. */ - f = xmalloc (sizeof (*f)); - memset (f, 0, sizeof (*f)); - f->loc.bitpos = 0; - f->type = create_array_type (0, elt_type, - create_range_type (0, builtin_type_int, - 0, n-1)); - f->name = elt_name; + t = init_composite_type ("__gdb_builtin_type_vec64", TYPE_CODE_UNION); + append_composite_type_field (t, "uint64", builtin_type_int64); + append_composite_type_field (t, "v2_float", builtin_type_v2_float); + append_composite_type_field (t, "v2_int32", builtin_type_v2_int32); + append_composite_type_field (t, "v4_int16", builtin_type_v4_int16); + append_composite_type_field (t, "v8_int8", builtin_type_v8_int8); - /* Build a struct type with that field. */ - t = init_type (TYPE_CODE_STRUCT, n * TYPE_LENGTH (elt_type), 0, 0, 0); - t->nfields = 1; - t->fields = f; - TYPE_TAG_NAME (t) = name; + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR; + TYPE_NAME (t) = "builtin_type_vec64"; + return t; +} +static struct type * +build_builtin_type_vec64i (void) +{ + /* Construct a type for the 64 bit registers. The type we're + building is this: */ +#if 0 + union __gdb_builtin_type_vec64i + { + int64_t uint64; + int32_t v2_int32[2]; + int16_t v4_int16[4]; + int8_t v8_int8[8]; + }; +#endif + + struct type *t; + + t = init_composite_type ("__gdb_builtin_type_vec64i", TYPE_CODE_UNION); + append_composite_type_field (t, "uint64", builtin_type_int64); + append_composite_type_field (t, "v2_int32", builtin_type_v2_int32); + append_composite_type_field (t, "v4_int16", builtin_type_v4_int16); + append_composite_type_field (t, "v8_int8", builtin_type_v8_int8); + + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR; + TYPE_NAME (t) = "builtin_type_vec64i"; return t; } @@ -820,42 +913,47 @@ build_builtin_type_vec128 (void) /* Construct a type for the 128 bit registers. The type we're building is this: */ #if 0 - union __gdb_builtin_type_vec128 + union __gdb_builtin_type_vec128 { - struct __builtin_v16qi v16qi; - struct __builtin_v8hi v8hi; - struct __builtin_v4si v4si; - struct __builtin_v4sf v4sf; - uint128_t uint128; + int128_t uint128; + float v4_float[4]; + int32_t v4_int32[4]; + int16_t v8_int16[8]; + int8_t v16_int8[16]; }; #endif struct type *t; - struct field *f; - f = (struct field *) xcalloc (5, sizeof (*f)); + t = init_composite_type ("__gdb_builtin_type_vec128", TYPE_CODE_UNION); + append_composite_type_field (t, "uint128", builtin_type_int128); + append_composite_type_field (t, "v4_float", builtin_type_v4_float); + append_composite_type_field (t, "v4_int32", builtin_type_v4_int32); + append_composite_type_field (t, "v8_int16", builtin_type_v8_int16); + append_composite_type_field (t, "v16_int8", builtin_type_v16_int8); - FIELD_TYPE (f[0]) = builtin_type_int128; - FIELD_NAME (f[0]) = "uint128"; + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR; + TYPE_NAME (t) = "builtin_type_vec128"; + return t; +} - FIELD_TYPE (f[1]) = builtin_type_v4sf; - FIELD_NAME (f[1]) = "v4sf"; +static struct type * +build_builtin_type_vec128i (void) +{ + /* 128-bit Intel SIMD registers */ + struct type *t; - FIELD_TYPE (f[2]) = builtin_type_v4si; - FIELD_NAME (f[2]) = "v4si"; - - FIELD_TYPE (f[3]) = builtin_type_v8hi; - FIELD_NAME (f[3]) = "v8hi"; - - FIELD_TYPE (f[4]) = builtin_type_v16qi; - FIELD_NAME (f[4]) = "v16qi"; - - /* Build a union type with those fields. */ - t = init_type (TYPE_CODE_UNION, 16, 0, 0, 0); - TYPE_NFIELDS (t) = 5; - TYPE_FIELDS (t) = f; - TYPE_TAG_NAME (t) = "__gdb_builtin_type_vec128"; + t = init_composite_type ("__gdb_builtin_type_vec128i", TYPE_CODE_UNION); + append_composite_type_field (t, "v4_float", builtin_type_v4_float); + append_composite_type_field (t, "v2_double", builtin_type_v2_double); + append_composite_type_field (t, "v16_int8", builtin_type_v16_int8); + append_composite_type_field (t, "v8_int16", builtin_type_v8_int16); + append_composite_type_field (t, "v4_int32", builtin_type_v4_int32); + append_composite_type_field (t, "v2_int64", builtin_type_v2_int64); + append_composite_type_field (t, "uint128", builtin_type_int128); + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR; + TYPE_NAME (t) = "builtin_type_vec128i"; return t; } @@ -877,7 +975,7 @@ smash_to_member_type (struct type *type, struct type *domain, objfile = TYPE_OBJFILE (type); - memset ((char *) type, 0, sizeof (struct type)); + smash_type (type); TYPE_OBJFILE (type) = objfile; TYPE_TARGET_TYPE (type) = to_type; TYPE_DOMAIN_TYPE (type) = domain; @@ -894,17 +992,21 @@ smash_to_member_type (struct type *type, struct type *domain, void smash_to_method_type (struct type *type, struct type *domain, - struct type *to_type, struct type **args) + struct type *to_type, struct field *args, + int nargs, int varargs) { struct objfile *objfile; objfile = TYPE_OBJFILE (type); - memset ((char *) type, 0, sizeof (struct type)); + smash_type (type); TYPE_OBJFILE (type) = objfile; TYPE_TARGET_TYPE (type) = to_type; TYPE_DOMAIN_TYPE (type) = domain; - TYPE_ARG_TYPES (type) = args; + TYPE_FIELDS (type) = args; + TYPE_NFIELDS (type) = nargs; + if (varargs) + TYPE_FLAGS (type) |= TYPE_FLAG_VARARGS; TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */ TYPE_CODE (type) = TYPE_CODE_METHOD; } @@ -913,7 +1015,7 @@ smash_to_method_type (struct type *type, struct type *domain, "union ", or "enum ". If the type has a NULL name, return NULL. */ char * -type_name_no_tag (register const struct type *type) +type_name_no_tag (const struct type *type) { if (TYPE_TAG_NAME (type) != NULL) return TYPE_TAG_NAME (type); @@ -934,7 +1036,7 @@ lookup_primitive_typename (char *name) for (p = current_language->la_builtin_type_vector; *p != NULL; p++) { - if (STREQ ((**p)->name, name)) + if (strcmp (TYPE_NAME (**p), name) == 0) { return (**p); } @@ -949,10 +1051,10 @@ lookup_primitive_typename (char *name) struct type * lookup_typename (char *name, struct block *block, int noerr) { - register struct symbol *sym; - register struct type *tmp; + struct symbol *sym; + struct type *tmp; - sym = lookup_symbol (name, block, VAR_NAMESPACE, 0, (struct symtab **) NULL); + sym = lookup_symbol (name, block, VAR_DOMAIN, 0, (struct symtab **) NULL); if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF) { tmp = lookup_primitive_typename (name); @@ -1003,9 +1105,9 @@ lookup_signed_typename (char *name) struct type * lookup_struct (char *name, struct block *block) { - register struct symbol *sym; + struct symbol *sym; - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, + sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0, (struct symtab **) NULL); if (sym == NULL) @@ -1025,10 +1127,10 @@ lookup_struct (char *name, struct block *block) struct type * lookup_union (char *name, struct block *block) { - register struct symbol *sym; + struct symbol *sym; struct type *t; - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, + sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0, (struct symtab **) NULL); if (sym == NULL) @@ -1057,9 +1159,9 @@ lookup_union (char *name, struct block *block) struct type * lookup_enum (char *name, struct block *block) { - register struct symbol *sym; + struct symbol *sym; - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, + sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0, (struct symtab **) NULL); if (sym == NULL) { @@ -1079,13 +1181,13 @@ struct type * lookup_template_type (char *name, struct type *type, struct block *block) { struct symbol *sym; - char *nam = (char *) alloca (strlen (name) + strlen (type->name) + 4); + char *nam = (char *) alloca (strlen (name) + strlen (TYPE_NAME (type)) + 4); strcpy (nam, name); strcat (nam, "<"); - strcat (nam, type->name); + strcat (nam, TYPE_NAME (type)); strcat (nam, " >"); /* FIXME, extra space still introduced in gcc? */ - sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **) NULL); + sym = lookup_symbol (nam, block, VAR_DOMAIN, 0, (struct symtab **) NULL); if (sym == NULL) { @@ -1141,7 +1243,7 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) char *typename; typename = type_name_no_tag (type); - if (typename != NULL && STREQ (typename, name)) + if (typename != NULL && strcmp (typename, name) == 0) return type; } #endif @@ -1203,13 +1305,12 @@ fill_in_vptr_fieldno (struct type *type) virtual (and hence we cannot share the table pointer). */ for (i = 0; i < TYPE_N_BASECLASSES (type); i++) { - fill_in_vptr_fieldno (TYPE_BASECLASS (type, i)); - if (TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)) >= 0) + struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); + fill_in_vptr_fieldno (baseclass); + if (TYPE_VPTR_FIELDNO (baseclass) >= 0) { - TYPE_VPTR_FIELDNO (type) - = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)); - TYPE_VPTR_BASETYPE (type) - = TYPE_VPTR_BASETYPE (TYPE_BASECLASS (type, i)); + TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (baseclass); + TYPE_VPTR_BASETYPE (type) = TYPE_VPTR_BASETYPE (baseclass); break; } } @@ -1242,6 +1343,12 @@ get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp) return 0; } +static void +stub_noname_complaint (void) +{ + complaint (&symfile_complaints, "stub type has NULL name"); +} + /* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989. If this is a stubbed struct (i.e. declared as struct foo *), see if @@ -1255,8 +1362,10 @@ get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp) This used to be coded as a macro, but I don't think it is called often enough to merit such treatment. */ -struct complaint stub_noname_complaint = -{"stub type has NULL name", 0, 0}; +/* Find the real type of TYPE. This function returns the real type, after + removing all layers of typedefs and completing opaque or stub types. + Completion changes the TYPE argument, but stripping of typedefs does + not. */ struct type * check_typedef (struct type *type) @@ -1278,15 +1387,15 @@ check_typedef (struct type *type) name = type_name_no_tag (type); /* FIXME: shouldn't we separately check the TYPE_NAME and the - TYPE_TAG_NAME, and look in STRUCT_NAMESPACE and/or VAR_NAMESPACE + TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or VAR_DOMAIN as appropriate? (this code was written before TYPE_NAME and TYPE_TAG_NAME were separate). */ if (name == NULL) { - complain (&stub_noname_complaint); + stub_noname_complaint (); return type; } - sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, + sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL); if (sym) TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym); @@ -1310,7 +1419,7 @@ check_typedef (struct type *type) struct type *newtype; if (name == NULL) { - complain (&stub_noname_complaint); + stub_noname_complaint (); return type; } newtype = lookup_transparent_type (name); @@ -1322,16 +1431,16 @@ check_typedef (struct type *type) { char *name = type_name_no_tag (type); /* FIXME: shouldn't we separately check the TYPE_NAME and the - TYPE_TAG_NAME, and look in STRUCT_NAMESPACE and/or VAR_NAMESPACE + TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or VAR_DOMAIN as appropriate? (this code was written before TYPE_NAME and TYPE_TAG_NAME were separate). */ struct symbol *sym; if (name == NULL) { - complain (&stub_noname_complaint); + stub_noname_complaint (); return type; } - sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, (struct symtab **) NULL); + sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL); if (sym) make_cv_type (is_const, is_volatile, SYMBOL_TYPE (sym), &type); } @@ -1369,206 +1478,10 @@ check_typedef (struct type *type) return type; } -/* New code added to support parsing of Cfront stabs strings */ -#define INIT_EXTRA { pextras->len=0; pextras->str[0]='\0'; } -#define ADD_EXTRA(c) { pextras->str[pextras->len++]=c; } - -static void -add_name (struct extra *pextras, char *n) -{ - int nlen; - - if ((nlen = (n ? strlen (n) : 0)) == 0) - return; - sprintf (pextras->str + pextras->len, "%d%s", nlen, n); - pextras->len = strlen (pextras->str); -} - -static void -add_mangled_type (struct extra *pextras, struct type *t) -{ - enum type_code tcode; - int tlen, tflags; - char *tname; - - tcode = TYPE_CODE (t); - tlen = TYPE_LENGTH (t); - tflags = TYPE_FLAGS (t); - tname = TYPE_NAME (t); - /* args of "..." seem to get mangled as "e" */ - - switch (tcode) - { - case TYPE_CODE_INT: - if (tflags == 1) - ADD_EXTRA ('U'); - switch (tlen) - { - case 1: - ADD_EXTRA ('c'); - break; - case 2: - ADD_EXTRA ('s'); - break; - case 4: - { - char *pname; - if ((pname = strrchr (tname, 'l'), pname) && !strcmp (pname, "long")) - { - ADD_EXTRA ('l'); - } - else - { - ADD_EXTRA ('i'); - } - } - break; - default: - { - - static struct complaint msg = - {"Bad int type code length x%x\n", 0, 0}; - - complain (&msg, tlen); - - } - } - break; - case TYPE_CODE_FLT: - switch (tlen) - { - case 4: - ADD_EXTRA ('f'); - break; - case 8: - ADD_EXTRA ('d'); - break; - case 16: - ADD_EXTRA ('r'); - break; - default: - { - static struct complaint msg = - {"Bad float type code length x%x\n", 0, 0}; - complain (&msg, tlen); - } - } - break; - case TYPE_CODE_REF: - ADD_EXTRA ('R'); - /* followed by what it's a ref to */ - break; - case TYPE_CODE_PTR: - ADD_EXTRA ('P'); - /* followed by what it's a ptr to */ - break; - case TYPE_CODE_TYPEDEF: - { - static struct complaint msg = - {"Typedefs in overloaded functions not yet supported\n", 0, 0}; - complain (&msg); - } - /* followed by type bytes & name */ - break; - case TYPE_CODE_FUNC: - ADD_EXTRA ('F'); - /* followed by func's arg '_' & ret types */ - break; - case TYPE_CODE_VOID: - ADD_EXTRA ('v'); - break; - case TYPE_CODE_METHOD: - ADD_EXTRA ('M'); - /* followed by name of class and func's arg '_' & ret types */ - add_name (pextras, tname); - ADD_EXTRA ('F'); /* then mangle function */ - break; - case TYPE_CODE_STRUCT: /* C struct */ - case TYPE_CODE_UNION: /* C union */ - case TYPE_CODE_ENUM: /* Enumeration type */ - /* followed by name of type */ - add_name (pextras, tname); - break; - - /* errors possible types/not supported */ - case TYPE_CODE_CHAR: - case TYPE_CODE_ARRAY: /* Array type */ - case TYPE_CODE_MEMBER: /* Member type */ - case TYPE_CODE_BOOL: - case TYPE_CODE_COMPLEX: /* Complex float */ - case TYPE_CODE_UNDEF: - case TYPE_CODE_SET: /* Pascal sets */ - case TYPE_CODE_RANGE: - case TYPE_CODE_STRING: - case TYPE_CODE_BITSTRING: - case TYPE_CODE_ERROR: - default: - { - static struct complaint msg = - {"Unknown type code x%x\n", 0, 0}; - complain (&msg, tcode); - } - } - if (t->target_type) - add_mangled_type (pextras, t->target_type); -} - -#if 0 -void -cfront_mangle_name (struct type *type, int i, int j) -{ - struct fn_field *f; - char *mangled_name = gdb_mangle_name (type, i, j); - - f = TYPE_FN_FIELDLIST1 (type, i); /* moved from below */ - - /* kludge to support cfront methods - gdb expects to find "F" for - ARM_mangled names, so when we mangle, we have to add it here */ - if (ARM_DEMANGLING) - { - int k; - char *arm_mangled_name; - struct fn_field *method = &f[j]; - char *field_name = TYPE_FN_FIELDLIST_NAME (type, i); - char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); - char *newname = type_name_no_tag (type); - - struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); - int nargs = TYPE_NFIELDS (ftype); /* number of args */ - struct extra extras, *pextras = &extras; - INIT_EXTRA - - if (TYPE_FN_FIELD_STATIC_P (f, j)) /* j for sublist within this list */ - ADD_EXTRA ('S') - ADD_EXTRA ('F') - /* add args here! */ - if (nargs <= 1) /* no args besides this */ - ADD_EXTRA ('v') - else - { - for (k = 1; k < nargs; k++) - { - struct type *t; - t = TYPE_FIELD_TYPE (ftype, k); - add_mangled_type (pextras, t); - } - } - ADD_EXTRA ('\0') - printf ("add_mangled_type: %s\n", extras.str); /* FIXME */ - xasprintf (&arm_mangled_name, "%s%s", mangled_name, extras.str); - xfree (mangled_name); - mangled_name = arm_mangled_name; - } -} -#endif /* 0 */ - -#undef ADD_EXTRA -/* End of new code added to support parsing of Cfront stabs strings */ - /* Parse a type expression in the string [P..P+LENGTH). If an error occurs, silently return builtin_type_void. */ -struct type * +static struct type * safe_parse_type (char *p, int length) { struct ui_file *saved_gdb_stderr; @@ -1599,7 +1512,7 @@ safe_parse_type (char *p, int length) which info used to be in the stab's but was removed to hack back the space required for them. */ -void +static void check_stub_method (struct type *type, int method_id, int signature_id) { struct fn_field *f; @@ -1608,7 +1521,7 @@ check_stub_method (struct type *type, int method_id, int signature_id) DMGL_PARAMS | DMGL_ANSI); char *argtypetext, *p; int depth = 0, argcount = 1; - struct type **argtypes; + struct field *argtypes; struct type *mtype; /* Make sure we got back a function string that we can use. */ @@ -1641,15 +1554,25 @@ check_stub_method (struct type *type, int method_id, int signature_id) p += 1; } - /* We need two more slots: one for the THIS pointer, and one for the - NULL [...] or void [end of arglist]. */ + /* If we read one argument and it was ``void'', don't count it. */ + if (strncmp (argtypetext, "(void)", 6) == 0) + argcount -= 1; - argtypes = (struct type **) - TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *)); + /* We need one extra slot, for the THIS pointer. */ + + argtypes = (struct field *) + TYPE_ALLOC (type, (argcount + 1) * sizeof (struct field)); p = argtypetext; - /* FIXME: This is wrong for static member functions. */ - argtypes[0] = lookup_pointer_type (type); - argcount = 1; + + /* Add THIS pointer for non-static methods. */ + f = TYPE_FN_FIELDLIST1 (type, method_id); + if (TYPE_FN_FIELD_STATIC_P (f, signature_id)) + argcount = 0; + else + { + argtypes[0].type = lookup_pointer_type (type); + argcount = 1; + } if (*p != ')') /* () means no args, skip while */ { @@ -1658,10 +1581,12 @@ check_stub_method (struct type *type, int method_id, int signature_id) { if (depth <= 0 && (*p == ',' || *p == ')')) { - /* Avoid parsing of ellipsis, they will be handled below. */ - if (strncmp (argtypetext, "...", p - argtypetext) != 0) + /* Avoid parsing of ellipsis, they will be handled below. + Also avoid ``void'' as above. */ + if (strncmp (argtypetext, "...", p - argtypetext) != 0 + && strncmp (argtypetext, "void", p - argtypetext) != 0) { - argtypes[argcount] = + argtypes[argcount].type = safe_parse_type (argtypetext, p - argtypetext); argcount += 1; } @@ -1681,27 +1606,62 @@ check_stub_method (struct type *type, int method_id, int signature_id) } } - if (p[-2] != '.') /* Not '...' */ - { - argtypes[argcount] = builtin_type_void; /* List terminator */ - } - else - { - argtypes[argcount] = NULL; /* Ellist terminator */ - } - - xfree (demangled_name); - - f = TYPE_FN_FIELDLIST1 (type, method_id); - TYPE_FN_FIELD_PHYSNAME (f, signature_id) = mangled_name; /* Now update the old "stub" type into a real type. */ mtype = TYPE_FN_FIELD_TYPE (f, signature_id); TYPE_DOMAIN_TYPE (mtype) = type; - TYPE_ARG_TYPES (mtype) = argtypes; + TYPE_FIELDS (mtype) = argtypes; + TYPE_NFIELDS (mtype) = argcount; TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB; TYPE_FN_FIELD_STUB (f, signature_id) = 0; + if (p[-2] == '.') + TYPE_FLAGS (mtype) |= TYPE_FLAG_VARARGS; + + xfree (demangled_name); +} + +/* This is the external interface to check_stub_method, above. This function + unstubs all of the signatures for TYPE's METHOD_ID method name. After + calling this function TYPE_FN_FIELD_STUB will be cleared for each signature + and TYPE_FN_FIELDLIST_NAME will be correct. + + This function unfortunately can not die until stabs do. */ + +void +check_stub_method_group (struct type *type, int method_id) +{ + int len = TYPE_FN_FIELDLIST_LENGTH (type, method_id); + struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id); + int j, found_stub = 0; + + for (j = 0; j < len; j++) + if (TYPE_FN_FIELD_STUB (f, j)) + { + found_stub = 1; + check_stub_method (type, method_id, j); + } + + /* GNU v3 methods with incorrect names were corrected when we read in + type information, because it was cheaper to do it then. The only GNU v2 + methods with incorrect method names are operators and destructors; + destructors were also corrected when we read in type information. + + Therefore the only thing we need to handle here are v2 operator + names. */ + if (found_stub && strncmp (TYPE_FN_FIELD_PHYSNAME (f, 0), "_Z", 2) != 0) + { + int ret; + char dem_opname[256]; + + ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, method_id), + dem_opname, DMGL_ANSI); + if (!ret) + ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, method_id), + dem_opname, 0); + if (ret) + TYPE_FN_FIELDLIST_NAME (type, method_id) = xstrdup (dem_opname); + } } const struct cplus_struct_type cplus_struct_default; @@ -1720,7 +1680,7 @@ allocate_cplus_struct_type (struct type *type) /* Helper function to initialize the standard scalar types. If NAME is non-NULL and OBJFILE is non-NULL, then we make a copy - of the string pointed to by name in the type_obstack for that objfile, + of the string pointed to by name in the objfile_obstack for that objfile, and initialize the type name to that copy. There are places (mipsread.c in particular, where init_type is called with a NULL value for NAME). */ @@ -1728,7 +1688,7 @@ struct type * init_type (enum type_code code, int length, int flags, char *name, struct objfile *objfile) { - register struct type *type; + struct type *type; type = alloc_type (objfile); TYPE_CODE (type) = code; @@ -1737,7 +1697,7 @@ init_type (enum type_code code, int length, int flags, char *name, if ((name != NULL) && (objfile != NULL)) { TYPE_NAME (type) = - obsavestring (name, strlen (name), &objfile->type_obstack); + obsavestring (name, strlen (name), &objfile->objfile_obstack); } else { @@ -1746,13 +1706,59 @@ init_type (enum type_code code, int length, int flags, char *name, /* C++ fancies. */ - if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) + if (name && strcmp (name, "char") == 0) + TYPE_FLAGS (type) |= TYPE_FLAG_NOSIGN; + + if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION + || code == TYPE_CODE_NAMESPACE) { INIT_CPLUS_SPECIFIC (type); } return (type); } +/* Helper function. Create an empty composite type. */ + +struct type * +init_composite_type (char *name, enum type_code code) +{ + struct type *t; + gdb_assert (code == TYPE_CODE_STRUCT + || code == TYPE_CODE_UNION); + t = init_type (code, 0, 0, NULL, NULL); + TYPE_TAG_NAME (t) = name; + return t; +} + +/* Helper function. Append a field to a composite type. */ + +void +append_composite_type_field (struct type *t, char *name, struct type *field) +{ + struct field *f; + TYPE_NFIELDS (t) = TYPE_NFIELDS (t) + 1; + TYPE_FIELDS (t) = xrealloc (TYPE_FIELDS (t), + sizeof (struct field) * TYPE_NFIELDS (t)); + f = &(TYPE_FIELDS (t)[TYPE_NFIELDS (t) - 1]); + memset (f, 0, sizeof f[0]); + FIELD_TYPE (f[0]) = field; + FIELD_NAME (f[0]) = name; + if (TYPE_CODE (t) == TYPE_CODE_UNION) + { + if (TYPE_LENGTH (t) < TYPE_LENGTH (field)) + TYPE_LENGTH (t) = TYPE_LENGTH (field); + } + else if (TYPE_CODE (t) == TYPE_CODE_STRUCT) + { + TYPE_LENGTH (t) = TYPE_LENGTH (t) + TYPE_LENGTH (field); + if (TYPE_NFIELDS (t) > 1) + { + FIELD_BITPOS (f[0]) = (FIELD_BITPOS (f[-1]) + + TYPE_LENGTH (field) * TARGET_CHAR_BIT); + } + } +} + /* Look up a fundamental type for the specified objfile. May need to construct such a type if this is the first use. @@ -1777,8 +1783,8 @@ init_type (enum type_code code, int length, int flags, char *name, struct type * lookup_fundamental_type (struct objfile *objfile, int typeid) { - register struct type **typep; - register int nbytes; + struct type **typep; + int nbytes; if (typeid < 0 || typeid >= FT_NUM_MEMBERS) { @@ -1792,7 +1798,7 @@ lookup_fundamental_type (struct objfile *objfile, int typeid) { nbytes = FT_NUM_MEMBERS * sizeof (struct type *); objfile->fundamental_types = (struct type **) - obstack_alloc (&objfile->type_obstack, nbytes); + obstack_alloc (&objfile->objfile_obstack, nbytes); memset ((char *) objfile->fundamental_types, 0, nbytes); OBJSTAT (objfile, n_types += FT_NUM_MEMBERS); } @@ -1833,22 +1839,6 @@ is_integral_type (struct type *t) || (TYPE_CODE (t) == TYPE_CODE_BOOL))); } -/* Chill varying string and arrays are represented as follows: - - struct { int __var_length; ELEMENT_TYPE[MAX_SIZE] __var_data}; - - Return true if TYPE is such a Chill varying type. */ - -int -chill_varying_type (struct type *type) -{ - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - || TYPE_NFIELDS (type) != 2 - || strcmp (TYPE_FIELD_NAME (type, 0), "__var_length") != 0) - return 0; - return 1; -} - /* Check whether BASE is an ancestor or base class or DCLASS Return 1 if so, and 0 if not. Note: callers may want to check for identity of the types before @@ -1888,7 +1878,7 @@ has_vtable (struct type *dclass) /* In the HP ANSI C++ runtime model, a class has a vtable only if it has virtual functions or virtual bases. */ - register int i; + int i; if (TYPE_CODE (dclass) != TYPE_CODE_CLASS) return 0; @@ -1931,7 +1921,7 @@ primary_base_class (struct type *dclass) is the first directly inherited, non-virtual base class that requires a virtual table */ - register int i; + int i; if (TYPE_CODE (dclass) != TYPE_CODE_CLASS) return NULL; @@ -1960,7 +1950,7 @@ static void virtual_base_list_aux (struct type *dclass) { struct vbase *tmp_vbase; - register int i; + int i; if (TYPE_CODE (dclass) != TYPE_CODE_CLASS) return; @@ -2017,9 +2007,9 @@ virtual_base_list_aux (struct type *dclass) struct type ** virtual_base_list (struct type *dclass) { - register struct vbase *tmp_vbase; - register struct vbase *tmp_vbase_2; - register int i; + struct vbase *tmp_vbase; + struct vbase *tmp_vbase_2; + int i; int count; struct type **vbase_array; @@ -2054,8 +2044,8 @@ virtual_base_list (struct type *dclass) int virtual_base_list_length (struct type *dclass) { - register int i; - register struct vbase *tmp_vbase; + int i; + struct vbase *tmp_vbase; current_vbase_list = NULL; virtual_base_list_aux (dclass); @@ -2072,8 +2062,8 @@ virtual_base_list_length (struct type *dclass) int virtual_base_list_length_skip_primaries (struct type *dclass) { - register int i; - register struct vbase *tmp_vbase; + int i; + struct vbase *tmp_vbase; struct type *primary; primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL; @@ -2101,8 +2091,8 @@ virtual_base_list_length_skip_primaries (struct type *dclass) int virtual_base_index (struct type *base, struct type *dclass) { - register struct type *vbase; - register int i; + struct type *vbase; + int i; if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) || (TYPE_CODE (base) != TYPE_CODE_CLASS)) @@ -2131,8 +2121,8 @@ virtual_base_index (struct type *base, struct type *dclass) int virtual_base_index_skip_primaries (struct type *base, struct type *dclass) { - register struct type *vbase; - register int i, j; + struct type *vbase; + int i, j; struct type *primary; if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) || @@ -2287,6 +2277,43 @@ rank_function (struct type **parms, int nparms, struct type **args, int nargs) return bv; } +/* Compare the names of two integer types, assuming that any sign + qualifiers have been checked already. We do it this way because + there may be an "int" in the name of one of the types. */ + +static int +integer_types_same_name_p (const char *first, const char *second) +{ + int first_p, second_p; + + /* If both are shorts, return 1; if neither is a short, keep checking. */ + first_p = (strstr (first, "short") != NULL); + second_p = (strstr (second, "short") != NULL); + if (first_p && second_p) + return 1; + if (first_p || second_p) + return 0; + + /* Likewise for long. */ + first_p = (strstr (first, "long") != NULL); + second_p = (strstr (second, "long") != NULL); + if (first_p && second_p) + return 1; + if (first_p || second_p) + return 0; + + /* Likewise for char. */ + first_p = (strstr (first, "char") != NULL); + second_p = (strstr (second, "char") != NULL); + if (first_p && second_p) + return 1; + if (first_p || second_p) + return 0; + + /* They must both be ints. */ + return 1; +} + /* Compare one type (PARM) for compatibility with another (ARG). * PARM is intended to be the parameter type of a function; and * ARG is the supplied argument's type. This function tests if @@ -2397,43 +2424,47 @@ rank_one_type (struct type *parm, struct type *arg) if (TYPE_NOSIGN (arg)) /* plain char -> plain char */ return 0; else - return INTEGER_COERCION_BADNESS; /* signed/unsigned char -> plain char */ + return INTEGER_CONVERSION_BADNESS; /* signed/unsigned char -> plain char */ } else if (TYPE_UNSIGNED (parm)) { if (TYPE_UNSIGNED (arg)) { - if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg))) - return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */ - else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) + /* unsigned int -> unsigned int, or unsigned long -> unsigned long */ + if (integer_types_same_name_p (TYPE_NAME (parm), TYPE_NAME (arg))) + return 0; + else if (integer_types_same_name_p (TYPE_NAME (arg), "int") + && integer_types_same_name_p (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */ else - return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */ + return INTEGER_CONVERSION_BADNESS; /* unsigned long -> unsigned int */ } else { - if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int")) - return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */ + if (integer_types_same_name_p (TYPE_NAME (arg), "long") + && integer_types_same_name_p (TYPE_NAME (parm), "int")) + return INTEGER_CONVERSION_BADNESS; /* signed long -> unsigned int */ else return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */ } } else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) { - if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg))) + if (integer_types_same_name_p (TYPE_NAME (parm), TYPE_NAME (arg))) return 0; - else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) + else if (integer_types_same_name_p (TYPE_NAME (arg), "int") + && integer_types_same_name_p (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) return INTEGER_PROMOTION_BADNESS; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_ENUM: case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: @@ -2455,7 +2486,7 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; default: @@ -2468,12 +2499,12 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; case TYPE_CODE_INT: if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm)) - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) return INTEGER_PROMOTION_BADNESS; /* >>> !! else fall through !! <<< */ @@ -2485,7 +2516,7 @@ rank_one_type (struct type *parm, struct type *arg) if (TYPE_NOSIGN (arg)) return 0; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else if (TYPE_UNSIGNED (parm)) { @@ -2497,7 +2528,7 @@ rank_one_type (struct type *parm, struct type *arg) else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) return 0; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; default: return INCOMPATIBLE_TYPE_BADNESS; } @@ -2510,7 +2541,7 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; default: @@ -2650,25 +2681,18 @@ print_bit_vector (B_TYPE *bits, int nbits) } } -/* The args list is a strange beast. It is either terminated by a NULL - pointer for varargs functions, or by a pointer to a TYPE_CODE_VOID - type for normal fixed argcount functions. (FIXME someday) - Also note the first arg should be the "this" pointer, we may not want to - include it since we may get into a infinitely recursive situation. */ +/* Note the first arg should be the "this" pointer, we may not want to + include it since we may get into a infinitely recursive situation. */ static void -print_arg_types (struct type **args, int spaces) +print_arg_types (struct field *args, int nargs, int spaces) { if (args != NULL) { - while (*args != NULL) - { - recursive_dump_type (*args, spaces + 2); - if ((*args++)->code == TYPE_CODE_VOID) - { - break; - } - } + int i; + + for (i = 0; i < nargs; i++) + recursive_dump_type (args[i].type, spaces + 2); } } @@ -2713,7 +2737,9 @@ dump_fn_fieldlists (struct type *type, int spaces) gdb_print_host_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout); printf_filtered ("\n"); - print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), spaces); + print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), + TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f, overload_idx)), + spaces); printfi_filtered (spaces + 8, "fcontext "); gdb_print_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx), gdb_stdout); @@ -2932,6 +2958,9 @@ recursive_dump_type (struct type *type, int spaces) case TYPE_CODE_TEMPLATE_ARG: printf_filtered ("(TYPE_CODE_TEMPLATE_ARG)"); break; + case TYPE_CODE_NAMESPACE: + printf_filtered ("(TYPE_CODE_NAMESPACE)"); + break; default: printf_filtered ("(UNKNOWN TYPE CODE)"); break; @@ -2962,12 +2991,35 @@ recursive_dump_type (struct type *type, int spaces) printfi_filtered (spaces, "reference_type "); gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout); printf_filtered ("\n"); - printfi_filtered (spaces, "cv_type "); - gdb_print_host_address (TYPE_CV_TYPE (type), gdb_stdout); - printf_filtered ("\n"); - printfi_filtered (spaces, "as_type "); - gdb_print_host_address (TYPE_AS_TYPE (type), gdb_stdout); + printfi_filtered (spaces, "type_chain "); + gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout); printf_filtered ("\n"); + printfi_filtered (spaces, "instance_flags 0x%x", TYPE_INSTANCE_FLAGS (type)); + if (TYPE_CONST (type)) + { + puts_filtered (" TYPE_FLAG_CONST"); + } + if (TYPE_VOLATILE (type)) + { + puts_filtered (" TYPE_FLAG_VOLATILE"); + } + if (TYPE_CODE_SPACE (type)) + { + puts_filtered (" TYPE_FLAG_CODE_SPACE"); + } + if (TYPE_DATA_SPACE (type)) + { + puts_filtered (" TYPE_FLAG_DATA_SPACE"); + } + if (TYPE_ADDRESS_CLASS_1 (type)) + { + puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_1"); + } + if (TYPE_ADDRESS_CLASS_2 (type)) + { + puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_2"); + } + puts_filtered ("\n"); printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type)); if (TYPE_UNSIGNED (type)) { @@ -2989,14 +3041,6 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_FLAG_STATIC"); } - if (TYPE_CONST (type)) - { - puts_filtered (" TYPE_FLAG_CONST"); - } - if (TYPE_VOLATILE (type)) - { - puts_filtered (" TYPE_FLAG_VOLATILE"); - } if (TYPE_PROTOTYPED (type)) { puts_filtered (" TYPE_FLAG_PROTOTYPED"); @@ -3005,18 +3049,17 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_FLAG_INCOMPLETE"); } - if (TYPE_CODE_SPACE (type)) - { - puts_filtered (" TYPE_FLAG_CODE_SPACE"); - } - if (TYPE_DATA_SPACE (type)) - { - puts_filtered (" TYPE_FLAG_DATA_SPACE"); - } if (TYPE_VARARGS (type)) { puts_filtered (" TYPE_FLAG_VARARGS"); } + /* This is used for things like AltiVec registers on ppc. Gcc emits + an attribute for the array type, which tells whether or not we + have a vector, instead of a regular array. */ + if (TYPE_VECTOR (type)) + { + puts_filtered (" TYPE_FLAG_VECTOR"); + } puts_filtered ("\n"); printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type)); gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout); @@ -3049,14 +3092,6 @@ recursive_dump_type (struct type *type, int spaces) printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type)); switch (TYPE_CODE (type)) { - case TYPE_CODE_METHOD: - case TYPE_CODE_FUNC: - printfi_filtered (spaces, "arg_types "); - gdb_print_host_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 "); gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout); @@ -3192,6 +3227,10 @@ build_gdbtypes (void) init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT, 0, "string", (struct objfile *) NULL); + builtin_type_int0 = + init_type (TYPE_CODE_INT, 0 / 8, + 0, + "int0_t", (struct objfile *) NULL); builtin_type_int8 = init_type (TYPE_CODE_INT, 8 / 8, 0, @@ -3261,9 +3300,24 @@ build_gdbtypes (void) builtin_type_v2si = init_simd_type ("__builtin_v2si", builtin_type_int32, "f", 2); - /* Vector types. */ - builtin_type_vec128 - = build_builtin_type_vec128 (); + /* 128 bit vectors. */ + builtin_type_v2_double = init_vector_type (builtin_type_double, 2); + builtin_type_v4_float = init_vector_type (builtin_type_float, 4); + builtin_type_v2_int64 = init_vector_type (builtin_type_int64, 2); + builtin_type_v4_int32 = init_vector_type (builtin_type_int32, 4); + builtin_type_v8_int16 = init_vector_type (builtin_type_int16, 8); + builtin_type_v16_int8 = init_vector_type (builtin_type_int8, 16); + /* 64 bit vectors. */ + builtin_type_v2_float = init_vector_type (builtin_type_float, 2); + builtin_type_v2_int32 = init_vector_type (builtin_type_int32, 2); + builtin_type_v4_int16 = init_vector_type (builtin_type_int16, 4); + builtin_type_v8_int8 = init_vector_type (builtin_type_int8, 8); + + /* Vector types. */ + builtin_type_vec64 = build_builtin_type_vec64 (); + builtin_type_vec64i = build_builtin_type_vec64i (); + builtin_type_vec128 = build_builtin_type_vec128 (); + builtin_type_vec128i = build_builtin_type_vec128i (); /* Pointer/Address types. */ @@ -3306,7 +3360,6 @@ build_gdbtypes (void) "__bfd_vma", (struct objfile *) NULL); } - extern void _initialize_gdbtypes (void); void _initialize_gdbtypes (void) @@ -3317,47 +3370,58 @@ _initialize_gdbtypes (void) /* FIXME - For the moment, handle types by swapping them in and out. Should be using the per-architecture data-pointer and a large struct. */ - register_gdbarch_swap (&builtin_type_void, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_char, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_short, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_long_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_signed_char, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_char, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_short, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_int, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_unsigned_long_long, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_float, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_double, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_long_double, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_complex, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_double_complex, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_string, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int8, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint8, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int16, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint16, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int32, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint32, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int64, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint64, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_int128, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_uint128, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v4sf, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v4si, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v16qi, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v8hi, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v4hi, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_v2si, sizeof (struct type *), NULL); - register_gdbarch_swap (&builtin_type_vec128, sizeof (struct type *), NULL); - REGISTER_GDBARCH_SWAP (builtin_type_void_data_ptr); - REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr); - REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR); - REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma); - register_gdbarch_swap (NULL, 0, build_gdbtypes); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_char); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_short); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_int); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_long_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_signed_char); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_char); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_short); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_int); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_unsigned_long_long); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_float); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_double); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_long_double); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_complex); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_double_complex); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_string); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_int8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_uint8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_int16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_uint16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_int32); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_uint32); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_int64); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_uint64); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_int128); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_uint128); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4sf); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4si); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v16qi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8qi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8hi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4hi); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2si); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_double); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4_float); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_int64); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4_int32); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8_int16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v16_int8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_float); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v2_int32); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v8_int8); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_v4_int16); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_vec128); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_vec128i); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void_data_ptr); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR); + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma); + deprecated_register_gdbarch_swap (NULL, 0, build_gdbtypes); /* Note: These types do not need to be swapped - they are target neutral. */ diff --git a/contrib/gdb/gdb/gdbtypes.h b/contrib/gdb/gdb/gdbtypes.h index 74b521abb67..c0696ad969e 100644 --- a/contrib/gdb/gdb/gdbtypes.h +++ b/contrib/gdb/gdb/gdbtypes.h @@ -1,6 +1,8 @@ /* Internal type definitions for GDB. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Support, using pieces from other GDB modules. This file is part of GDB. @@ -24,6 +26,7 @@ #define GDBTYPES_H 1 /* Forward declarations for prototypes. */ +struct field; struct block; /* Codes for `fundamental types'. This is a monstrosity based on the @@ -101,13 +104,14 @@ enum type_code TYPE_CODE_RANGE, /* Range (integers within spec'd bounds) */ /* 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. */ + differently (at least for (the deleted) 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). */ + /* String of bits; like TYPE_CODE_SET but prints differently (at + least for (the deleted) CHILL). */ TYPE_CODE_BITSTRING, /* Unknown type. The length field is valid if we were able to @@ -130,8 +134,9 @@ enum type_code TYPE_CODE_TYPEDEF, TYPE_CODE_TEMPLATE, /* C++ template */ - TYPE_CODE_TEMPLATE_ARG /* C++ template arg */ + TYPE_CODE_TEMPLATE_ARG, /* C++ template arg */ + TYPE_CODE_NAMESPACE /* C++ namespace. */ }; /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an @@ -148,21 +153,21 @@ enum type_code type is signed (unless TYPE_FLAG_NOSIGN (below) is set). */ #define TYPE_FLAG_UNSIGNED (1 << 0) -#define TYPE_UNSIGNED(t) ((t)->flags & TYPE_FLAG_UNSIGNED) +#define TYPE_UNSIGNED(t) (TYPE_FLAGS (t) & TYPE_FLAG_UNSIGNED) /* No sign for this type. In C++, "char", "signed char", and "unsigned char" are distinct types; so we need an extra flag to indicate the absence of a sign! */ #define TYPE_FLAG_NOSIGN (1 << 1) -#define TYPE_NOSIGN(t) ((t)->flags & TYPE_FLAG_NOSIGN) +#define TYPE_NOSIGN(t) (TYPE_FLAGS (t) & TYPE_FLAG_NOSIGN) /* 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) -#define TYPE_STUB(t) ((t)->flags & TYPE_FLAG_STUB) +#define TYPE_STUB(t) (TYPE_FLAGS (t) & TYPE_FLAG_STUB) /* The target type of this type is a stub type, and this type needs to be updated if it gets un-stubbed in check_typedef. @@ -171,7 +176,7 @@ enum type_code Also, set for TYPE_CODE_TYPEDEF. */ #define TYPE_FLAG_TARGET_STUB (1 << 3) -#define TYPE_TARGET_STUB(t) ((t)->flags & TYPE_FLAG_TARGET_STUB) +#define TYPE_TARGET_STUB(t) (TYPE_FLAGS (t) & TYPE_FLAG_TARGET_STUB) /* Static type. If this is set, the corresponding type had * a static modifier. @@ -180,21 +185,21 @@ enum type_code */ #define TYPE_FLAG_STATIC (1 << 4) -#define TYPE_STATIC(t) ((t)->flags & TYPE_FLAG_STATIC) +#define TYPE_STATIC(t) (TYPE_FLAGS (t) & TYPE_FLAG_STATIC) /* Constant type. If this is set, the corresponding type has a * const modifier. */ #define TYPE_FLAG_CONST (1 << 5) -#define TYPE_CONST(t) ((t)->flags & TYPE_FLAG_CONST) +#define TYPE_CONST(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CONST) /* Volatile type. If this is set, the corresponding type has a * volatile modifier. */ #define TYPE_FLAG_VOLATILE (1 << 6) -#define TYPE_VOLATILE(t) ((t)->flags & TYPE_FLAG_VOLATILE) +#define TYPE_VOLATILE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_VOLATILE) /* This is a function type which appears to have a prototype. We need this @@ -202,7 +207,7 @@ enum type_code or to just do the standard conversions. This is used with a short field. */ #define TYPE_FLAG_PROTOTYPED (1 << 7) -#define TYPE_PROTOTYPED(t) ((t)->flags & TYPE_FLAG_PROTOTYPED) +#define TYPE_PROTOTYPED(t) (TYPE_FLAGS (t) & TYPE_FLAG_PROTOTYPED) /* This flag is used to indicate that processing for this type is incomplete. @@ -213,7 +218,7 @@ enum type_code the method can be assigned correct types.) */ #define TYPE_FLAG_INCOMPLETE (1 << 8) -#define TYPE_INCOMPLETE(t) ((t)->flags & TYPE_FLAG_INCOMPLETE) +#define TYPE_INCOMPLETE(t) (TYPE_FLAGS (t) & TYPE_FLAG_INCOMPLETE) /* Instruction-space delimited type. This is for Harvard architectures which have separate instruction and data address spaces (and perhaps @@ -235,250 +240,279 @@ enum type_code is instruction space, and for data objects is data memory. */ #define TYPE_FLAG_CODE_SPACE (1 << 9) -#define TYPE_CODE_SPACE(t) ((t)->flags & TYPE_FLAG_CODE_SPACE) +#define TYPE_CODE_SPACE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CODE_SPACE) #define TYPE_FLAG_DATA_SPACE (1 << 10) -#define TYPE_DATA_SPACE(t) ((t)->flags & TYPE_FLAG_DATA_SPACE) +#define TYPE_DATA_SPACE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_DATA_SPACE) -/* FIXME: Kludge to mark a varargs function type for C++ member - function argument processing. Currently only used in dwarf2read.c, - but put it here so we won't accidentally overload the bit with - another flag. */ +/* FIXME drow/2002-06-03: Only used for methods, but applies as well + to functions. */ #define TYPE_FLAG_VARARGS (1 << 11) -#define TYPE_VARARGS(t) ((t)->flags & TYPE_FLAG_VARARGS) +#define TYPE_VARARGS(t) (TYPE_FLAGS (t) & TYPE_FLAG_VARARGS) -struct type +/* Identify a vector type. Gcc is handling this by adding an extra + attribute to the array type. We slurp that in as a new flag of a + type. This is used only in dwarf2read.c. */ +#define TYPE_FLAG_VECTOR (1 << 12) +#define TYPE_VECTOR(t) (TYPE_FLAGS (t) & TYPE_FLAG_VECTOR) + +/* Address class flags. Some environments provide for pointers whose + size is different from that of a normal pointer or address types + where the bits are interpreted differently than normal addresses. The + TYPE_FLAG_ADDRESS_CLASS_n flags may be used in target specific + ways to represent these different types of address classes. */ +#define TYPE_FLAG_ADDRESS_CLASS_1 (1 << 13) +#define TYPE_ADDRESS_CLASS_1(t) (TYPE_INSTANCE_FLAGS(t) \ + & TYPE_FLAG_ADDRESS_CLASS_1) +#define TYPE_FLAG_ADDRESS_CLASS_2 (1 << 14) +#define TYPE_ADDRESS_CLASS_2(t) (TYPE_INSTANCE_FLAGS(t) \ + & TYPE_FLAG_ADDRESS_CLASS_2) +#define TYPE_FLAG_ADDRESS_CLASS_ALL (TYPE_FLAG_ADDRESS_CLASS_1 \ + | TYPE_FLAG_ADDRESS_CLASS_2) +#define TYPE_ADDRESS_CLASS_ALL(t) (TYPE_INSTANCE_FLAGS(t) \ + & TYPE_FLAG_ADDRESS_CLASS_ALL) + +/* Array bound type. */ +enum array_bound_type +{ + BOUND_SIMPLE = 0, + BOUND_BY_VALUE_IN_REG, + BOUND_BY_REF_IN_REG, + BOUND_BY_VALUE_ON_STACK, + BOUND_BY_REF_ON_STACK, + BOUND_CANNOT_BE_DETERMINED +}; + +/* This structure is space-critical. + Its layout has been tweaked to reduce the space used. */ + +struct main_type +{ + /* Code for kind of type */ + + ENUM_BITFIELD(type_code) code : 8; + + /* Array bounds. These fields appear at this location because + they pack nicely here. */ + + ENUM_BITFIELD(array_bound_type) upper_bound_type : 4; + ENUM_BITFIELD(array_bound_type) lower_bound_type : 4; + + /* Name of this type, or NULL if none. + + This is used for printing only, except by poorly designed C++ code. + For looking up a name, look for a symbol in the VAR_DOMAIN. */ + + char *name; + + /* Tag name for this type, or NULL if none. This means that the + name of the type consists of a keyword followed by the tag name. + Which keyword is determined by the type code ("struct" for + TYPE_CODE_STRUCT, etc.). As far as I know C/C++ are the only languages + with this feature. + + This is used for printing only, except by poorly designed C++ code. + For looking up a name, look for a symbol in the STRUCT_DOMAIN. + One more legitimate use is that if TYPE_FLAG_STUB is set, this is + the name to use to look for definitions in other files. */ + + char *tag_name; + + /* Every type is now associated with a particular objfile, and the + type is allocated on the objfile_obstack for that objfile. One problem + however, is that there are times when gdb allocates new types while + it is not in the process of reading symbols from a particular objfile. + Fortunately, these happen when the type being created is a derived + type of an existing type, such as in lookup_pointer_type(). So + we can just allocate the new type using the same objfile as the + existing type, but to do this we need a backpointer to the objfile + from the existing type. Yes this is somewhat ugly, but without + major overhaul of the internal type system, it can't be avoided + for now. */ + + struct objfile *objfile; + + /* For a pointer type, describes the type of object pointed to. + For an array type, describes the type of the elements. + For a function or method type, describes the type of the return value. + For a range type, describes the type of the full range. + For a complex type, describes the type of each coordinate. + Unused otherwise. */ + + struct type *target_type; + + /* Flags about this type. */ + + int flags; + + /* Number of fields described for this type */ + + short nfields; + + /* Field number of the virtual function table pointer in + VPTR_BASETYPE. If -1, we were unable to find the virtual + function table pointer in initial symbol reading, and + fill_in_vptr_fieldno should be called to find it if possible. + + Unused if this type does not have virtual functions. */ + + short vptr_fieldno; + + /* For structure and union types, a description of each field. + For set and pascal array types, there is one "field", + whose type is the domain type of the set or array. + For range types, there are two "fields", + the minimum and maximum values (both inclusive). + For enum types, each possible value is described by one "field". + For a function or method type, a "field" for each parameter. + For C++ classes, there is one field for each base class (if it is + a derived class) plus one field for each class data member. Member + functions are recorded elsewhere. + + Using a pointer to a separate array of fields + allows all types to have the same size, which is useful + because we can allocate the space for a type before + we know what to put in it. */ + + struct field { + union field_location + { + /* Position of this field, counting in bits from start of + containing structure. + For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB. + For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB. + For a range bound or enum value, this is the value itself. */ - /* Code for kind of type */ + int bitpos; - enum type_code code; + /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr + is the location (in the target) of the static field. + Otherwise, physname is the mangled label of the static field. */ - /* Name of this type, or NULL if none. + CORE_ADDR physaddr; + char *physname; + } + loc; - This is used for printing only, except by poorly designed C++ code. - For looking up a name, look for a symbol in the VAR_NAMESPACE. */ + /* For a function or member type, this is 1 if the argument is marked + artificial. Artificial arguments should not be shown to the + user. */ + unsigned int artificial : 1; + + /* This flag is zero for non-static fields, 1 for fields whose location + is specified by the label loc.physname, and 2 for fields whose location + is specified by loc.physaddr. */ + + unsigned int static_kind : 2; + + /* Size of this field, in bits, or zero if not packed. + For an unpacked field, the field's type's length + says how many bytes the field occupies. */ + + unsigned int bitsize : 29; + + /* In a struct or union type, type of this field. + In a function or member type, type of this argument. + In an array type, the domain-type of the array. */ + + struct type *type; + + /* Name of field, value or argument. + NULL for range bounds, array domains, and member function + arguments. */ char *name; - /* Tag name for this type, or NULL if none. This means that the - name of the type consists of a keyword followed by the tag name. - Which keyword is determined by the type code ("struct" for - TYPE_CODE_STRUCT, etc.). As far as I know C/C++ are the only languages - with this feature. + } *fields; - This is used for printing only, except by poorly designed C++ code. - For looking up a name, look for a symbol in the STRUCT_NAMESPACE. - One more legitimate use is that if TYPE_FLAG_STUB is set, this is - the name to use to look for definitions in other files. */ + /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE + is the base class which defined the virtual function table pointer. - char *tag_name; + For types that are pointer to member types (TYPE_CODE_MEMBER), + VPTR_BASETYPE is the type that this pointer is a member of. - /* Length of storage for a value of this type. This is what - sizeof(type) would return; use it for address arithmetic, - memory reads and writes, etc. This size includes padding. For - example, an i386 extended-precision floating point value really - only occupies ten bytes, but most ABI's declare its size to be - 12 bytes, to preserve alignment. A `struct type' representing - such a floating-point type would have a `length' value of 12, - even though the last two bytes are unused. + For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate + type that contains the method. - There's a bit of a host/target mess here, if you're concerned - about machines whose bytes aren't eight bits long, or who don't - have byte-addressed memory. Various places pass this to memcpy - and such, meaning it must be in units of host bytes. Various - other places expect they can calculate addresses by adding it - and such, meaning it must be in units of target bytes. For - some DSP targets, in which HOST_CHAR_BIT will (presumably) be 8 - and TARGET_CHAR_BIT will be (say) 32, this is a problem. + Unused otherwise. */ - One fix would be to make this field in bits (requiring that it - always be a multiple of HOST_CHAR_BIT and TARGET_CHAR_BIT) --- - the other choice would be to make it consistently in units of - HOST_CHAR_BIT. However, this would still fail to address - machines based on a ternary or decimal representation. */ - unsigned length; + struct type *vptr_basetype; - /* FIXME, these should probably be restricted to a Fortran-specific - field in some fashion. */ -#define BOUND_CANNOT_BE_DETERMINED 5 -#define BOUND_BY_REF_ON_STACK 4 -#define BOUND_BY_VALUE_ON_STACK 3 -#define BOUND_BY_REF_IN_REG 2 -#define BOUND_BY_VALUE_IN_REG 1 -#define BOUND_SIMPLE 0 - int upper_bound_type; - int lower_bound_type; + /* Slot to point to additional language-specific fields of this type. */ - /* Every type is now associated with a particular objfile, and the - type is allocated on the type_obstack for that objfile. One problem - however, is that there are times when gdb allocates new types while - it is not in the process of reading symbols from a particular objfile. - Fortunately, these happen when the type being created is a derived - type of an existing type, such as in lookup_pointer_type(). So - we can just allocate the new type using the same objfile as the - existing type, but to do this we need a backpointer to the objfile - from the existing type. Yes this is somewhat ugly, but without - major overhaul of the internal type system, it can't be avoided - for now. */ + union type_specific + { + /* CPLUS_STUFF is for TYPE_CODE_STRUCT. It is initialized to point to + cplus_struct_default, a default static instance of a struct + cplus_struct_type. */ - struct objfile *objfile; + struct cplus_struct_type *cplus_stuff; - /* For a pointer type, describes the type of object pointed to. - For an array type, describes the type of the elements. - For a function or method type, describes the type of the return value. - For a range type, describes the type of the full range. - For a complex type, describes the type of each coordinate. - Unused otherwise. */ + /* FLOATFORMAT is for TYPE_CODE_FLT. It is a pointer to the + floatformat object that describes the floating-point value + that resides within the type. */ - struct type *target_type; + const struct floatformat *floatformat; + } type_specific; +}; - /* Type that is a pointer to this type. - NULL if no such pointer-to type is known yet. - The debugger may add the address of such a type - if it has to construct one later. */ +/* A ``struct type'' describes a particular instance of a type, with + some particular qualification. */ +struct type +{ + /* Type that is a pointer to this type. + NULL if no such pointer-to type is known yet. + The debugger may add the address of such a type + if it has to construct one later. */ - struct type *pointer_type; + struct type *pointer_type; - /* C++: also need a reference type. */ + /* C++: also need a reference type. */ - struct type *reference_type; + struct type *reference_type; - /* C-v variant chain. This points to a type that - differs from this one only in a const or volatile - attribute (or both). The various c-v variants - are chained together in a ring. */ - struct type *cv_type; + /* Variant chain. This points to a type that differs from this one only + in qualifiers and length. Currently, the possible qualifiers are + const, volatile, code-space, data-space, and address class. The + length may differ only when one of the address class flags are set. + The variants are linked in a circular ring and share MAIN_TYPE. */ + struct type *chain; - /* Address-space delimited variant chain. This points to a type - that differs from this one only in an address-space qualifier - attribute. The otherwise-identical address-space delimited - types are chained together in a ring. */ - struct type *as_type; + /* Flags specific to this instance of the type, indicating where + on the ring we are. */ + int instance_flags; - /* Flags about this type. */ + /* Length of storage for a value of this type. This is what + sizeof(type) would return; use it for address arithmetic, + memory reads and writes, etc. This size includes padding. For + example, an i386 extended-precision floating point value really + only occupies ten bytes, but most ABI's declare its size to be + 12 bytes, to preserve alignment. A `struct type' representing + such a floating-point type would have a `length' value of 12, + even though the last two bytes are unused. - int flags; + There's a bit of a host/target mess here, if you're concerned + about machines whose bytes aren't eight bits long, or who don't + have byte-addressed memory. Various places pass this to memcpy + and such, meaning it must be in units of host bytes. Various + other places expect they can calculate addresses by adding it + and such, meaning it must be in units of target bytes. For + some DSP targets, in which HOST_CHAR_BIT will (presumably) be 8 + and TARGET_CHAR_BIT will be (say) 32, this is a problem. - /* Number of fields described for this type */ + One fix would be to make this field in bits (requiring that it + always be a multiple of HOST_CHAR_BIT and TARGET_CHAR_BIT) --- + the other choice would be to make it consistently in units of + HOST_CHAR_BIT. However, this would still fail to address + machines based on a ternary or decimal representation. */ + + unsigned length; - short nfields; - - /* For structure and union types, a description of each field. - For set and pascal array types, there is one "field", - whose type is the domain type of the set or array. - For range types, there are two "fields", - the minimum and maximum values (both inclusive). - For enum types, each possible value is described by one "field". - For a function type, a "field" for each parameter type. - For C++ classes, there is one field for each base class (if it is - a derived class) plus one field for each class data member. Member - functions are recorded elsewhere. - - Using a pointer to a separate array of fields - allows all types to have the same size, which is useful - because we can allocate the space for a type before - we know what to put in it. */ - - struct field - { - union field_location - { - /* Position of this field, counting in bits from start of - containing structure. - For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB. - For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB. - For a range bound or enum value, this is the value itself. */ - - int bitpos; - - /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr - is the location (in the target) of the static field. - Otherwise, physname is the mangled label of the static field. */ - - CORE_ADDR physaddr; - char *physname; - - /* For a function type, this is 1 if the argument is marked - artificial. Artificial arguments should not be shown to the - user. */ - int artificial; - } - loc; - - /* Size of this field, in bits, or zero if not packed. - For an unpacked field, the field's type's length - says how many bytes the field occupies. - A value of -1 or -2 indicates a static field; -1 means the location - is specified by the label loc.physname; -2 means that loc.physaddr - specifies the actual address. */ - - int bitsize; - - /* In a struct or union type, type of this field. - In a function type, type of this argument. - In an array type, the domain-type of the array. */ - - struct type *type; - - /* Name of field, value or argument. - NULL for range bounds and array domains. */ - - char *name; - - } - *fields; - - /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE - is the base class which defined the virtual function table pointer. - - For types that are pointer to member types (TYPE_CODE_MEMBER), - VPTR_BASETYPE is the type that this pointer is a member of. - - For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate - type that contains the method. - - Unused otherwise. */ - - struct type *vptr_basetype; - - /* Field number of the virtual function table pointer in - VPTR_BASETYPE. If -1, we were unable to find the virtual - function table pointer in initial symbol reading, and - fill_in_vptr_fieldno should be called to find it if possible. - - Unused if this type does not have virtual functions. */ - - int vptr_fieldno; - - /* Slot to point to additional language-specific fields of this type. */ - - union type_specific - { - - /* ARG_TYPES is for TYPE_CODE_METHOD. - Contains the type of each argument, ending with a void type - after the last argument for normal member functions or a NULL - pointer after the last argument for functions with variable - arguments. */ - - struct type **arg_types; - - /* CPLUS_STUFF is for TYPE_CODE_STRUCT. It is initialized to point to - cplus_struct_default, a default static instance of a struct - cplus_struct_type. */ - - struct cplus_struct_type *cplus_stuff; - - /* FLOATFORMAT is for TYPE_CODE_FLT. It is a pointer to the - floatformat object that describes the floating-point value - that resides within the type. */ - - const struct floatformat *floatformat; - } - type_specific; - }; + /* Core type, shared by a group of qualified types. */ + struct main_type *main_type; +}; #define NULL_TYPE ((struct type *) 0) @@ -595,13 +629,6 @@ struct cplus_struct_type struct type *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. Should not contain - a `this' pointer for static member functions. */ - - struct type **args; - /* For virtual functions. First baseclass that defines this virtual function. */ @@ -731,25 +758,26 @@ extern void allocate_cplus_struct_type (struct type *); #define HAVE_CPLUS_STRUCT(type) \ (TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default) -#define TYPE_NAME(thistype) (thistype)->name -#define TYPE_TAG_NAME(type) ((type)->tag_name) -#define TYPE_TARGET_TYPE(thistype) (thistype)->target_type +#define TYPE_INSTANCE_FLAGS(thistype) (thistype)->instance_flags +#define TYPE_MAIN_TYPE(thistype) (thistype)->main_type +#define TYPE_NAME(thistype) TYPE_MAIN_TYPE(thistype)->name +#define TYPE_TAG_NAME(type) TYPE_MAIN_TYPE(type)->tag_name +#define TYPE_TARGET_TYPE(thistype) TYPE_MAIN_TYPE(thistype)->target_type #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type -#define TYPE_CV_TYPE(thistype) (thistype)->cv_type -#define TYPE_AS_TYPE(thistype) (thistype)->as_type +#define TYPE_CHAIN(thistype) (thistype)->chain /* Note that if thistype is a TYPEDEF type, you have to call check_typedef. But check_typedef does set the TYPE_LENGTH of the TYPEDEF type, so you only have to call check_typedef once. Since allocate_value calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */ #define TYPE_LENGTH(thistype) (thistype)->length -#define TYPE_OBJFILE(thistype) (thistype)->objfile -#define TYPE_FLAGS(thistype) (thistype)->flags +#define TYPE_OBJFILE(thistype) TYPE_MAIN_TYPE(thistype)->objfile +#define TYPE_FLAGS(thistype) TYPE_MAIN_TYPE(thistype)->flags /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real type, you need to do TYPE_CODE (check_type (this_type)). */ -#define TYPE_CODE(thistype) (thistype)->code -#define TYPE_NFIELDS(thistype) (thistype)->nfields -#define TYPE_FIELDS(thistype) (thistype)->fields +#define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code +#define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields +#define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->fields #define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args #define TYPE_INSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->instantiations @@ -759,8 +787,10 @@ extern void allocate_cplus_struct_type (struct type *); /* Moto-specific stuff for FORTRAN arrays */ -#define TYPE_ARRAY_UPPER_BOUND_TYPE(thistype) (thistype)->upper_bound_type -#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) (thistype)->lower_bound_type +#define TYPE_ARRAY_UPPER_BOUND_TYPE(thistype) \ + TYPE_MAIN_TYPE(thistype)->upper_bound_type +#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) \ + TYPE_MAIN_TYPE(thistype)->lower_bound_type #define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \ (TYPE_FIELD_BITPOS((TYPE_FIELD_TYPE((arraytype),0)),1)) @@ -770,22 +800,21 @@ extern void allocate_cplus_struct_type (struct type *); /* C++ */ -#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype -#define TYPE_DOMAIN_TYPE(thistype) (thistype)->vptr_basetype -#define TYPE_VPTR_FIELDNO(thistype) (thistype)->vptr_fieldno +#define TYPE_VPTR_BASETYPE(thistype) TYPE_MAIN_TYPE(thistype)->vptr_basetype +#define TYPE_DOMAIN_TYPE(thistype) TYPE_MAIN_TYPE(thistype)->vptr_basetype +#define TYPE_VPTR_FIELDNO(thistype) TYPE_MAIN_TYPE(thistype)->vptr_fieldno #define TYPE_FN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fields #define TYPE_NFN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields #define TYPE_NFN_FIELDS_TOTAL(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields_total #define TYPE_NTEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ntemplate_args #define TYPE_NINSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ninstantiations #define TYPE_DECLARED_TYPE(thistype) TYPE_CPLUS_SPECIFIC(thistype)->declared_type -#define TYPE_TYPE_SPECIFIC(thistype) (thistype)->type_specific -#define TYPE_ARG_TYPES(thistype) (thistype)->type_specific.arg_types -#define TYPE_CPLUS_SPECIFIC(thistype) (thistype)->type_specific.cplus_stuff -#define TYPE_FLOATFORMAT(thistype) (thistype)->type_specific.floatformat -#define TYPE_BASECLASS(thistype,index) (thistype)->fields[index].type +#define TYPE_TYPE_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific +#define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff +#define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat +#define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses -#define TYPE_BASECLASS_NAME(thistype,index) (thistype)->fields[index].name +#define TYPE_BASECLASS_NAME(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].name #define TYPE_BASECLASS_BITPOS(thistype,index) TYPE_FIELD_BITPOS(thistype,index) #define BASETYPE_VIA_PUBLIC(thistype, index) \ ((!TYPE_FIELD_PRIVATE(thistype, index)) && (!TYPE_FIELD_PROTECTED(thistype, index))) @@ -797,15 +826,16 @@ extern void allocate_cplus_struct_type (struct type *); #define FIELD_TYPE(thisfld) ((thisfld).type) #define FIELD_NAME(thisfld) ((thisfld).name) #define FIELD_BITPOS(thisfld) ((thisfld).loc.bitpos) -#define FIELD_ARTIFICIAL(thisfld) ((thisfld).loc.artificial) +#define FIELD_ARTIFICIAL(thisfld) ((thisfld).artificial) #define FIELD_BITSIZE(thisfld) ((thisfld).bitsize) +#define FIELD_STATIC_KIND(thisfld) ((thisfld).static_kind) #define FIELD_PHYSNAME(thisfld) ((thisfld).loc.physname) #define FIELD_PHYSADDR(thisfld) ((thisfld).loc.physaddr) #define SET_FIELD_PHYSNAME(thisfld, name) \ - ((thisfld).bitsize = -1, FIELD_PHYSNAME(thisfld) = (name)) + ((thisfld).static_kind = 1, FIELD_PHYSNAME(thisfld) = (name)) #define SET_FIELD_PHYSADDR(thisfld, name) \ - ((thisfld).bitsize = -2, FIELD_PHYSADDR(thisfld) = (name)) -#define TYPE_FIELD(thistype, n) (thistype)->fields[n] + ((thisfld).static_kind = 2, FIELD_PHYSADDR(thisfld) = (name)) +#define TYPE_FIELD(thistype, n) TYPE_MAIN_TYPE(thistype)->fields[n] #define TYPE_FIELD_TYPE(thistype, n) FIELD_TYPE(TYPE_FIELD(thistype, n)) #define TYPE_FIELD_NAME(thistype, n) FIELD_NAME(TYPE_FIELD(thistype, n)) #define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS(TYPE_FIELD(thistype,n)) @@ -844,8 +874,9 @@ extern void allocate_cplus_struct_type (struct type *); (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))) -#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitsize < 0) -#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) ((thistype)->fields[n].bitsize == -2) +#define TYPE_FIELD_STATIC(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].static_kind != 0) +#define TYPE_FIELD_STATIC_KIND(thistype, n) TYPE_MAIN_TYPE (thistype)->fields[n].static_kind +#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].static_kind == 2) #define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_PHYSNAME(TYPE_FIELD(thistype, n)) #define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_PHYSADDR(TYPE_FIELD(thistype, n)) @@ -858,7 +889,7 @@ extern void allocate_cplus_struct_type (struct type *); #define TYPE_FN_FIELD(thisfn, n) (thisfn)[n] #define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname #define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type -#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_ARG_TYPES ((thisfn)[n].type) +#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_FIELDS ((thisfn)[n].type) #define TYPE_FN_FIELD_CONST(thisfn, n) ((thisfn)[n].is_const) #define TYPE_FN_FIELD_VOLATILE(thisfn, n) ((thisfn)[n].is_volatile) #define TYPE_FN_FIELD_PRIVATE(thisfn, n) ((thisfn)[n].is_private) @@ -935,7 +966,10 @@ extern struct type *builtin_type_CORE_ADDR; (cf MIPS). */ extern struct type *builtin_type_bfd_vma; -/* Explicit sizes - see C9X for naming scheme */ +/* Explicit sizes - see C9X for naming scheme. The "int0" + is for when an architecture needs to describe a register that has + no size. */ +extern struct type *builtin_type_int0; extern struct type *builtin_type_int8; extern struct type *builtin_type_uint8; extern struct type *builtin_type_int16; @@ -956,8 +990,13 @@ extern struct type *builtin_type_v8hi; extern struct type *builtin_type_v4hi; extern struct type *builtin_type_v2si; +/* Type for 64 bit vectors. */ +extern struct type *builtin_type_vec64; +extern struct type *builtin_type_vec64i; + /* Type for 128 bit vectors. */ extern struct type *builtin_type_vec128; +extern struct type *builtin_type_vec128i; /* Explicit floating-point formats. See "floatformat.h". */ extern struct type *builtin_type_ieee_single_big; @@ -998,14 +1037,6 @@ extern struct type *builtin_type_m2_card; extern struct type *builtin_type_m2_real; extern struct type *builtin_type_m2_bool; -/* Chill types */ - -extern struct type *builtin_type_chill_bool; -extern struct type *builtin_type_chill_char; -extern struct type *builtin_type_chill_long; -extern struct type *builtin_type_chill_ulong; -extern struct type *builtin_type_chill_real; - /* Fortran (F77) types */ extern struct type *builtin_type_f_character; @@ -1038,15 +1069,15 @@ extern struct type *builtin_type_f_void; /* Allocate space for storing data associated with a particular type. We ensure that the space is allocated using the same mechanism that was used to allocate the space for the type structure itself. I.E. - if the type is on an objfile's type_obstack, then the space for data - associated with that type will also be allocated on the type_obstack. + if the type is on an objfile's objfile_obstack, then the space for data + associated with that type will also be allocated on the objfile_obstack. If the type is not associated with any particular objfile (such as builtin types), then the data space will be allocated with xmalloc, the same as for the type structure. */ #define TYPE_ALLOC(t,size) \ (TYPE_OBJFILE (t) != NULL \ - ? obstack_alloc (&TYPE_OBJFILE (t) -> type_obstack, size) \ + ? obstack_alloc (&TYPE_OBJFILE (t) -> objfile_obstack, size) \ : xmalloc (size)) extern struct type *alloc_type (struct objfile *); @@ -1054,19 +1085,27 @@ extern struct type *alloc_type (struct objfile *); extern struct type *init_type (enum type_code, int, int, char *, struct objfile *); +/* Helper functions to construct a struct or record type. An + initially empty type is created using init_composite_type(). + Fields are then added using append_struct_type_field(). A union + type has its size set to the largest field. A struct type has each + field packed against the previous. */ + +extern struct type *init_composite_type (char *name, enum type_code code); +extern void append_composite_type_field (struct type *t, char *name, + struct type *field); + extern struct type *lookup_reference_type (struct type *); extern struct type *make_reference_type (struct type *, struct type **); extern struct type *make_cv_type (int, int, struct type *, struct type **); -extern void finish_cv_type (struct type *); - extern void replace_type (struct type *, struct type *); extern int address_space_name_to_int (char *); -extern char *address_space_int_to_name (int); +extern const char *address_space_int_to_name (int); extern struct type *make_type_with_address_space (struct type *type, int space_identifier); @@ -1074,11 +1113,11 @@ extern struct type *make_type_with_address_space (struct type *type, extern struct type *lookup_member_type (struct type *, struct type *); extern void -smash_to_method_type (struct type *, struct type *, struct type *, - struct type **); +smash_to_method_type (struct type *type, struct type *domain, + struct type *to_type, struct field *args, + int nargs, int varargs); -extern void -smash_to_member_type (struct type *, struct type *, struct type *); +extern void smash_to_member_type (struct type *, struct type *, struct type *); extern struct type *allocate_stub_method (struct type *); @@ -1104,8 +1143,6 @@ extern struct type *create_string_type (struct type *, struct type *); extern struct type *create_set_type (struct type *, struct type *); -extern int chill_varying_type (struct type *); - extern struct type *lookup_unsigned_typename (char *); extern struct type *lookup_signed_typename (char *); @@ -1114,7 +1151,7 @@ extern struct type *check_typedef (struct type *); #define CHECK_TYPEDEF(TYPE) (TYPE) = check_typedef (TYPE) -extern void check_stub_method (struct type *, int, int); +extern void check_stub_method_group (struct type *, int); extern struct type *lookup_primitive_typename (char *); @@ -1189,10 +1226,6 @@ extern int count_virtual_fns (struct type *); #define TOO_FEW_PARAMS_BADNESS 100 /* Badness if no conversion among types */ #define INCOMPATIBLE_TYPE_BADNESS 100 -/* Badness of coercing large integer to smaller size */ -#define INTEGER_COERCION_BADNESS 100 -/* Badness of coercing large floating type to smaller size */ -#define FLOAT_COERCION_BADNESS 100 /* Badness of integral promotion */ #define INTEGER_PROMOTION_BADNESS 1 @@ -1231,7 +1264,7 @@ extern void recursive_dump_type (struct type *, int); /* printcmd.c */ -extern void print_scalar_formatted (char *, struct type *, int, int, +extern void print_scalar_formatted (void *, struct type *, int, int, struct ui_file *); extern int can_dereference (struct type *); diff --git a/contrib/gdb/gdb/glibc-tdep.c b/contrib/gdb/gdb/glibc-tdep.c new file mode 100644 index 00000000000..04bb6834ad1 --- /dev/null +++ b/contrib/gdb/gdb/glibc-tdep.c @@ -0,0 +1,101 @@ +/* Target-dependent code for the GNU C Library (glibc). + + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" + +#include "glibc-tdep.h" + +/* Calling functions in shared libraries. */ + +/* Find the minimal symbol named NAME, and return both the minsym + struct and its objfile. This probably ought to be in minsym.c, but + everything there is trying to deal with things like C++ and + SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may + be considered too special-purpose for general consumption. */ + +static struct minimal_symbol * +find_minsym_and_objfile (char *name, struct objfile **objfile_p) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + struct minimal_symbol *msym; + + ALL_OBJFILE_MSYMBOLS (objfile, msym) + { + if (SYMBOL_LINKAGE_NAME (msym) + && strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0) + { + *objfile_p = objfile; + return msym; + } + } + } + + return 0; +} + +/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c. + This function: + 1) decides whether a PLT has sent us into the linker to resolve + a function reference, and + 2) if so, tells us where to set a temporary breakpoint that will + trigger when the dynamic linker is done. */ + +CORE_ADDR +glibc_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + /* The GNU dynamic linker is part of the GNU C library, and is used + by all GNU systems (GNU/Hurd, GNU/Linux). An unresolved PLT + entry points to "_dl_runtime_resolve", which calls "fixup" to + patch the PLT, and then passes control to the function. + + We look for the symbol `_dl_runtime_resolve', and find `fixup' in + the same objfile. If we are at the entry point of `fixup', then + we set a breakpoint at the return address (at the top of the + stack), and continue. + + It's kind of gross to do all these checks every time we're + called, since they don't change once the executable has gotten + started. But this is only a temporary hack --- upcoming versions + of GNU/Linux will provide a portable, efficient interface for + debugging programs that use shared libraries. */ + + struct objfile *objfile; + struct minimal_symbol *resolver + = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile); + + if (resolver) + { + struct minimal_symbol *fixup + = lookup_minimal_symbol ("fixup", NULL, objfile); + + if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) + return frame_pc_unwind (get_current_frame ()); + } + + return 0; +} diff --git a/contrib/gdb/gdb/glibc-tdep.h b/contrib/gdb/gdb/glibc-tdep.h new file mode 100644 index 00000000000..75598d5e08b --- /dev/null +++ b/contrib/gdb/gdb/glibc-tdep.h @@ -0,0 +1,30 @@ +/* Target-dependent code for the GNU C Library (glibc). + + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef GLIBC_TDEP_H +#define GLIBC_TDEP_H + +struct gdbarch; + +extern CORE_ADDR glibc_skip_solib_resolver (struct gdbarch *gdbarch, + CORE_ADDR); + +#endif /* glibc-tdep.h */ diff --git a/contrib/gdb/gdb/gnu-nat.c b/contrib/gdb/gdb/gnu-nat.c new file mode 100644 index 00000000000..a61d577f839 --- /dev/null +++ b/contrib/gdb/gdb/gnu-nat.c @@ -0,0 +1,3409 @@ +/* Interface GDB to the GNU Hurd. + Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + + This file is part of GDB. + + Written by Miles Bader + + Some code and ideas from m3-nat.c by Jukka Virtanen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include "gdb_string.h" +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "defs.h" +#include "inferior.h" +#include "symtab.h" +#include "value.h" +#include "language.h" +#include "target.h" +#include "gdb_wait.h" +#include "gdbcmd.h" +#include "gdbcore.h" +#include "gdbthread.h" +#include "gdb_assert.h" +#include "gdb_obstack.h" + +#include "gnu-nat.h" + +#include "exc_request_S.h" +#include "notify_S.h" +#include "process_reply_S.h" +#include "msg_reply_S.h" +#include "exc_request_U.h" +#include "msg_U.h" + +static process_t proc_server = MACH_PORT_NULL; + +/* If we've sent a proc_wait_request to the proc server, the pid of the + process we asked about. We can only ever have one outstanding. */ +int proc_wait_pid = 0; + +/* The number of wait requests we've sent, and expect replies from. */ +int proc_waits_pending = 0; + +int gnu_debug_flag = 0; + +/* Forward decls */ + +extern struct target_ops gnu_ops; + +struct inf *make_inf (); +void inf_clear_wait (struct inf *inf); +void inf_cleanup (struct inf *inf); +void inf_startup (struct inf *inf, int pid); +int inf_update_suspends (struct inf *inf); +void inf_set_pid (struct inf *inf, pid_t pid); +void inf_validate_procs (struct inf *inf); +void inf_steal_exc_ports (struct inf *inf); +void inf_restore_exc_ports (struct inf *inf); +struct proc *inf_tid_to_proc (struct inf *inf, int tid); +void inf_set_threads_resume_sc (struct inf *inf, + struct proc *run_thread, + int run_others); +int inf_set_threads_resume_sc_for_signal_thread (struct inf *inf); +void inf_suspend (struct inf *inf); +void inf_resume (struct inf *inf); +void inf_set_step_thread (struct inf *inf, struct proc *proc); +void inf_detach (struct inf *inf); +void inf_attach (struct inf *inf, int pid); +void inf_signal (struct inf *inf, enum target_signal sig); +void inf_continue (struct inf *inf); + +#define inf_debug(_inf, msg, args...) \ + do { struct inf *__inf = (_inf); \ + debug ("{inf %d %p}: " msg, __inf->pid, __inf , ##args); } while (0) + +void proc_abort (struct proc *proc, int force); +struct proc *make_proc (struct inf *inf, mach_port_t port, int tid); +struct proc *_proc_free (struct proc *proc); +int proc_update_sc (struct proc *proc); +error_t proc_get_exception_port (struct proc *proc, mach_port_t * port); +error_t proc_set_exception_port (struct proc *proc, mach_port_t port); +static mach_port_t _proc_get_exc_port (struct proc *proc); +void proc_steal_exc_port (struct proc *proc, mach_port_t exc_port); +void proc_restore_exc_port (struct proc *proc); +int proc_trace (struct proc *proc, int set); + +/* Evaluate RPC_EXPR in a scope with the variables MSGPORT and REFPORT bound + to INF's msg port and task port respectively. If it has no msg port, + EIEIO is returned. INF must refer to a running process! */ +#define INF_MSGPORT_RPC(inf, rpc_expr) \ + HURD_MSGPORT_RPC (proc_getmsgport (proc_server, inf->pid, &msgport), \ + (refport = inf->task->port, 0), 0, \ + msgport ? (rpc_expr) : EIEIO) + +/* Like INF_MSGPORT_RPC, but will also resume the signal thread to ensure + there's someone around to deal with the RPC (and resuspend things + afterwards). This effects INF's threads' resume_sc count. */ +#define INF_RESUME_MSGPORT_RPC(inf, rpc_expr) \ + (inf_set_threads_resume_sc_for_signal_thread (inf) \ + ? ({ error_t __e; \ + inf_resume (inf); \ + __e = INF_MSGPORT_RPC (inf, rpc_expr); \ + inf_suspend (inf); \ + __e; }) \ + : EIEIO) + + +/* The state passed by an exception message. */ +struct exc_state + { + int exception; /* The exception code */ + int code, subcode; + mach_port_t handler; /* The real exception port to handle this. */ + mach_port_t reply; /* The reply port from the exception call. */ + }; + +/* The results of the last wait an inf did. */ +struct inf_wait + { + struct target_waitstatus status; /* The status returned to gdb. */ + struct exc_state exc; /* The exception that caused us to return. */ + struct proc *thread; /* The thread in question. */ + int suppress; /* Something trivial happened. */ + }; + +/* The state of an inferior. */ +struct inf + { + /* Fields describing the current inferior. */ + + struct proc *task; /* The mach task. */ + struct proc *threads; /* A linked list of all threads in TASK. */ + + /* True if THREADS needn't be validated by querying the task. We assume that + we and the task in question are the only ones frobbing the thread list, + so as long as we don't let any code run, we don't have to worry about + THREADS changing. */ + int threads_up_to_date; + + pid_t pid; /* The real system PID. */ + + struct inf_wait wait; /* What to return from target_wait. */ + + /* One thread proc in INF may be in `single-stepping mode'. This is it. */ + struct proc *step_thread; + + /* The thread we think is the signal thread. */ + struct proc *signal_thread; + + mach_port_t event_port; /* Where we receive various msgs. */ + + /* True if we think at least one thread in the inferior could currently be + running. */ + unsigned int running:1; + + /* True if the process has stopped (in the proc server sense). Note that + since a proc server `stop' leaves the signal thread running, the inf can + be RUNNING && STOPPED... */ + unsigned int stopped:1; + + /* True if the inferior has no message port. */ + unsigned int nomsg:1; + + /* True if the inferior is traced. */ + unsigned int traced:1; + + /* True if we shouldn't try waiting for the inferior, usually because we + can't for some reason. */ + unsigned int no_wait:1; + + /* When starting a new inferior, we don't try to validate threads until all + the proper execs have been done. This is a count of how many execs we + expect to happen. */ + unsigned pending_execs; + + /* Fields describing global state */ + + /* The task suspend count used when gdb has control. This is normally 1 to + make things easier for us, but sometimes (like when attaching to vital + system servers) it may be desirable to let the task continue to run + (pausing individual threads as necessary). */ + int pause_sc; + + /* The task suspend count left when detaching from a task. */ + int detach_sc; + + /* The initial values used for the run_sc and pause_sc of newly discovered + threads -- see the definition of those fields in struct proc. */ + int default_thread_run_sc; + int default_thread_pause_sc; + int default_thread_detach_sc; + + /* True if the process should be traced when started/attached. Newly + started processes *must* be traced at first to exec them properly, but + if this is false, tracing is turned off as soon it has done so. */ + int want_signals; + + /* True if exceptions from the inferior process should be trapped. This + must be on to use breakpoints. */ + int want_exceptions; + }; + + +int +__proc_pid (struct proc *proc) +{ + return proc->inf->pid; +} + + +/* Update PROC's real suspend count to match it's desired one. Returns true + if we think PROC is now in a runnable state. */ +int +proc_update_sc (struct proc *proc) +{ + int running; + int err = 0; + int delta = proc->sc - proc->cur_sc; + + if (delta) + proc_debug (proc, "sc: %d --> %d", proc->cur_sc, proc->sc); + + if (proc->sc == 0 && proc->state_changed) + /* Since PROC may start running, we must write back any state changes. */ + { + gdb_assert (proc_is_thread (proc)); + proc_debug (proc, "storing back changed thread state"); + err = thread_set_state (proc->port, THREAD_STATE_FLAVOR, + (thread_state_t) &proc->state, THREAD_STATE_SIZE); + if (!err) + proc->state_changed = 0; + } + + if (delta > 0) + { + while (delta-- > 0 && !err) + { + if (proc_is_task (proc)) + err = task_suspend (proc->port); + else + err = thread_suspend (proc->port); + } + } + else + { + while (delta++ < 0 && !err) + { + if (proc_is_task (proc)) + err = task_resume (proc->port); + else + err = thread_resume (proc->port); + } + } + if (!err) + proc->cur_sc = proc->sc; + + /* If we got an error, then the task/thread has disappeared. */ + running = !err && proc->sc == 0; + + proc_debug (proc, "is %s", err ? "dead" : running ? "running" : "suspended"); + if (err) + proc_debug (proc, "err = %s", safe_strerror (err)); + + if (running) + { + proc->aborted = 0; + proc->state_valid = proc->state_changed = 0; + proc->fetched_regs = 0; + } + + return running; +} + + +/* Thread_abort is called on PROC if needed. PROC must be a thread proc. + If PROC is deemed `precious', then nothing is done unless FORCE is true. + In particular, a thread is precious if it's running (in which case forcing + it includes suspending it first), or if it has an exception pending. */ +void +proc_abort (struct proc *proc, int force) +{ + gdb_assert (proc_is_thread (proc)); + + if (!proc->aborted) + { + struct inf *inf = proc->inf; + int running = (proc->cur_sc == 0 && inf->task->cur_sc == 0); + + if (running && force) + { + proc->sc = 1; + inf_update_suspends (proc->inf); + running = 0; + warning ("Stopped %s.", proc_string (proc)); + } + else if (proc == inf->wait.thread && inf->wait.exc.reply && !force) + /* An exception is pending on PROC, which don't mess with. */ + running = 1; + + if (!running) + /* We only abort the thread if it's not actually running. */ + { + thread_abort (proc->port); + proc_debug (proc, "aborted"); + proc->aborted = 1; + } + else + proc_debug (proc, "not aborting"); + } +} + +/* Make sure that the state field in PROC is up to date, and return a pointer + to it, or 0 if something is wrong. If WILL_MODIFY is true, makes sure + that the thread is stopped and aborted first, and sets the state_changed + field in PROC to true. */ +thread_state_t +proc_get_state (struct proc *proc, int will_modify) +{ + int was_aborted = proc->aborted; + + proc_debug (proc, "updating state info%s", + will_modify ? " (with intention to modify)" : ""); + + proc_abort (proc, will_modify); + + if (!was_aborted && proc->aborted) + /* PROC's state may have changed since we last fetched it. */ + proc->state_valid = 0; + + if (!proc->state_valid) + { + mach_msg_type_number_t state_size = THREAD_STATE_SIZE; + error_t err = + thread_get_state (proc->port, THREAD_STATE_FLAVOR, + (thread_state_t) &proc->state, &state_size); + proc_debug (proc, "getting thread state"); + proc->state_valid = !err; + } + + if (proc->state_valid) + { + if (will_modify) + proc->state_changed = 1; + return (thread_state_t) &proc->state; + } + else + return 0; +} + + +/* Set PORT to PROC's exception port. */ +error_t +proc_get_exception_port (struct proc * proc, mach_port_t * port) +{ + if (proc_is_task (proc)) + return task_get_exception_port (proc->port, port); + else + return thread_get_exception_port (proc->port, port); +} + +/* Set PROC's exception port to PORT. */ +error_t +proc_set_exception_port (struct proc * proc, mach_port_t port) +{ + proc_debug (proc, "setting exception port: %d", port); + if (proc_is_task (proc)) + return task_set_exception_port (proc->port, port); + else + return thread_set_exception_port (proc->port, port); +} + +/* Get PROC's exception port, cleaning up a bit if proc has died. */ +static mach_port_t +_proc_get_exc_port (struct proc *proc) +{ + mach_port_t exc_port; + error_t err = proc_get_exception_port (proc, &exc_port); + + if (err) + /* PROC must be dead. */ + { + if (proc->exc_port) + mach_port_deallocate (mach_task_self (), proc->exc_port); + proc->exc_port = MACH_PORT_NULL; + if (proc->saved_exc_port) + mach_port_deallocate (mach_task_self (), proc->saved_exc_port); + proc->saved_exc_port = MACH_PORT_NULL; + } + + return exc_port; +} + +/* Replace PROC's exception port with EXC_PORT, unless it's already been + done. Stash away any existing exception port so we can restore it later. */ +void +proc_steal_exc_port (struct proc *proc, mach_port_t exc_port) +{ + mach_port_t cur_exc_port = _proc_get_exc_port (proc); + + if (cur_exc_port) + { + error_t err = 0; + + proc_debug (proc, "inserting exception port: %d", exc_port); + + if (cur_exc_port != exc_port) + /* Put in our exception port. */ + err = proc_set_exception_port (proc, exc_port); + + if (err || cur_exc_port == proc->exc_port) + /* We previously set the exception port, and it's still set. So we + just keep the old saved port which is what the proc set. */ + { + if (cur_exc_port) + mach_port_deallocate (mach_task_self (), cur_exc_port); + } + else + /* Keep a copy of PROC's old exception port so it can be restored. */ + { + if (proc->saved_exc_port) + mach_port_deallocate (mach_task_self (), proc->saved_exc_port); + proc->saved_exc_port = cur_exc_port; + } + + proc_debug (proc, "saved exception port: %d", proc->saved_exc_port); + + if (!err) + proc->exc_port = exc_port; + else + warning ("Error setting exception port for %s: %s", + proc_string (proc), safe_strerror (err)); + } +} + +/* If we previously replaced PROC's exception port, put back what we + found there at the time, unless *our* exception port has since been + overwritten, in which case who knows what's going on. */ +void +proc_restore_exc_port (struct proc *proc) +{ + mach_port_t cur_exc_port = _proc_get_exc_port (proc); + + if (cur_exc_port) + { + error_t err = 0; + + proc_debug (proc, "restoring real exception port"); + + if (proc->exc_port == cur_exc_port) + /* Our's is still there. */ + err = proc_set_exception_port (proc, proc->saved_exc_port); + + if (proc->saved_exc_port) + mach_port_deallocate (mach_task_self (), proc->saved_exc_port); + proc->saved_exc_port = MACH_PORT_NULL; + + if (!err) + proc->exc_port = MACH_PORT_NULL; + else + warning ("Error setting exception port for %s: %s", + proc_string (proc), safe_strerror (err)); + } +} + + +/* Turns hardware tracing in PROC on or off when SET is true or false, + respectively. Returns true on success. */ +int +proc_trace (struct proc *proc, int set) +{ + thread_state_t state = proc_get_state (proc, 1); + + if (!state) + return 0; /* the thread must be dead. */ + + proc_debug (proc, "tracing %s", set ? "on" : "off"); + + if (set) + { + /* XXX We don't get the exception unless the thread has its own + exception port???? */ + if (proc->exc_port == MACH_PORT_NULL) + proc_steal_exc_port (proc, proc->inf->event_port); + THREAD_STATE_SET_TRACED (state); + } + else + THREAD_STATE_CLEAR_TRACED (state); + + return 1; +} + + +/* A variable from which to assign new TIDs. */ +static int next_thread_id = 1; + +/* Returns a new proc structure with the given fields. Also adds a + notification for PORT becoming dead to be sent to INF's notify port. */ +struct proc * +make_proc (struct inf *inf, mach_port_t port, int tid) +{ + error_t err; + mach_port_t prev_port = MACH_PORT_NULL; + struct proc *proc = xmalloc (sizeof (struct proc)); + + proc->port = port; + proc->tid = tid; + proc->inf = inf; + proc->next = 0; + proc->saved_exc_port = MACH_PORT_NULL; + proc->exc_port = MACH_PORT_NULL; + + proc->sc = 0; + proc->cur_sc = 0; + + /* Note that these are all the values for threads; the task simply uses the + corresponding field in INF directly. */ + proc->run_sc = inf->default_thread_run_sc; + proc->pause_sc = inf->default_thread_pause_sc; + proc->detach_sc = inf->default_thread_detach_sc; + proc->resume_sc = proc->run_sc; + + proc->aborted = 0; + proc->dead = 0; + proc->state_valid = 0; + proc->state_changed = 0; + + proc_debug (proc, "is new"); + + /* Get notified when things die. */ + err = + mach_port_request_notification (mach_task_self (), port, + MACH_NOTIFY_DEAD_NAME, 1, + inf->event_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + &prev_port); + if (err) + warning ("Couldn't request notification for port %d: %s", + port, safe_strerror (err)); + else + { + proc_debug (proc, "notifications to: %d", inf->event_port); + if (prev_port != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), prev_port); + } + + if (inf->want_exceptions) + { + if (proc_is_task (proc)) + /* Make the task exception port point to us. */ + proc_steal_exc_port (proc, inf->event_port); + else + /* Just clear thread exception ports -- they default to the + task one. */ + proc_steal_exc_port (proc, MACH_PORT_NULL); + } + + return proc; +} + +/* Frees PROC and any resources it uses, and returns the value of PROC's + next field. */ +struct proc * +_proc_free (struct proc *proc) +{ + struct inf *inf = proc->inf; + struct proc *next = proc->next; + + proc_debug (proc, "freeing..."); + + if (proc == inf->step_thread) + /* Turn off single stepping. */ + inf_set_step_thread (inf, 0); + if (proc == inf->wait.thread) + inf_clear_wait (inf); + if (proc == inf->signal_thread) + inf->signal_thread = 0; + + if (proc->port != MACH_PORT_NULL) + { + if (proc->exc_port != MACH_PORT_NULL) + /* Restore the original exception port. */ + proc_restore_exc_port (proc); + if (proc->cur_sc != 0) + /* Resume the thread/task. */ + { + proc->sc = 0; + proc_update_sc (proc); + } + mach_port_deallocate (mach_task_self (), proc->port); + } + + xfree (proc); + return next; +} + + +struct inf * +make_inf (void) +{ + struct inf *inf = xmalloc (sizeof (struct inf)); + + inf->task = 0; + inf->threads = 0; + inf->threads_up_to_date = 0; + inf->pid = 0; + inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS; + inf->wait.thread = 0; + inf->wait.exc.handler = MACH_PORT_NULL; + inf->wait.exc.reply = MACH_PORT_NULL; + inf->step_thread = 0; + inf->signal_thread = 0; + inf->event_port = MACH_PORT_NULL; + inf->running = 0; + inf->stopped = 0; + inf->nomsg = 1; + inf->traced = 0; + inf->no_wait = 0; + inf->pending_execs = 0; + inf->pause_sc = 1; + inf->detach_sc = 0; + inf->default_thread_run_sc = 0; + inf->default_thread_pause_sc = 0; + inf->default_thread_detach_sc = 0; + inf->want_signals = 1; /* By default */ + inf->want_exceptions = 1; /* By default */ + + return inf; +} + +/* Clear INF's target wait status. */ +void +inf_clear_wait (struct inf *inf) +{ + inf_debug (inf, "clearing wait"); + inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS; + inf->wait.thread = 0; + inf->wait.suppress = 0; + if (inf->wait.exc.handler != MACH_PORT_NULL) + { + mach_port_deallocate (mach_task_self (), inf->wait.exc.handler); + inf->wait.exc.handler = MACH_PORT_NULL; + } + if (inf->wait.exc.reply != MACH_PORT_NULL) + { + mach_port_deallocate (mach_task_self (), inf->wait.exc.reply); + inf->wait.exc.reply = MACH_PORT_NULL; + } +} + + +void +inf_cleanup (struct inf *inf) +{ + inf_debug (inf, "cleanup"); + + inf_clear_wait (inf); + + inf_set_pid (inf, -1); + inf->pid = 0; + inf->running = 0; + inf->stopped = 0; + inf->nomsg = 1; + inf->traced = 0; + inf->no_wait = 0; + inf->pending_execs = 0; + + if (inf->event_port) + { + mach_port_destroy (mach_task_self (), inf->event_port); + inf->event_port = MACH_PORT_NULL; + } +} + +void +inf_startup (struct inf *inf, int pid) +{ + error_t err; + + inf_debug (inf, "startup: pid = %d", pid); + + inf_cleanup (inf); + + /* Make the port on which we receive all events. */ + err = mach_port_allocate (mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, &inf->event_port); + if (err) + error ("Error allocating event port: %s", safe_strerror (err)); + + /* Make a send right for it, so we can easily copy it for other people. */ + mach_port_insert_right (mach_task_self (), inf->event_port, + inf->event_port, MACH_MSG_TYPE_MAKE_SEND); + inf_set_pid (inf, pid); +} + + +/* Close current process, if any, and attach INF to process PORT. */ +void +inf_set_pid (struct inf *inf, pid_t pid) +{ + task_t task_port; + struct proc *task = inf->task; + + inf_debug (inf, "setting pid: %d", pid); + + if (pid < 0) + task_port = MACH_PORT_NULL; + else + { + error_t err = proc_pid2task (proc_server, pid, &task_port); + if (err) + error ("Error getting task for pid %d: %s", pid, safe_strerror (err)); + } + + inf_debug (inf, "setting task: %d", task_port); + + if (inf->pause_sc) + task_suspend (task_port); + + if (task && task->port != task_port) + { + inf->task = 0; + inf_validate_procs (inf); /* Trash all the threads. */ + _proc_free (task); /* And the task. */ + } + + if (task_port != MACH_PORT_NULL) + { + inf->task = make_proc (inf, task_port, PROC_TID_TASK); + inf->threads_up_to_date = 0; + } + + if (inf->task) + { + inf->pid = pid; + if (inf->pause_sc) + /* Reflect task_suspend above. */ + inf->task->sc = inf->task->cur_sc = 1; + } + else + inf->pid = -1; +} + + +/* Validates INF's stopped, nomsg and traced field from the actual + proc server state. Note that the traced field is only updated from + the proc server state if we do not have a message port. If we do + have a message port we'd better look at the tracemask itself. */ +static void +inf_validate_procinfo (struct inf *inf) +{ + char *noise; + mach_msg_type_number_t noise_len = 0; + struct procinfo *pi; + mach_msg_type_number_t pi_len = 0; + int info_flags = 0; + error_t err = + proc_getprocinfo (proc_server, inf->pid, &info_flags, + (procinfo_t *) &pi, &pi_len, &noise, &noise_len); + + if (!err) + { + inf->stopped = !!(pi->state & PI_STOPPED); + inf->nomsg = !!(pi->state & PI_NOMSG); + if (inf->nomsg) + inf->traced = !!(pi->state & PI_TRACED); + vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); + if (noise_len > 0) + vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len); + } +} + +/* Validates INF's task suspend count. If it's higher than we expect, + verify with the user before `stealing' the extra count. */ +static void +inf_validate_task_sc (struct inf *inf) +{ + char *noise; + mach_msg_type_number_t noise_len = 0; + struct procinfo *pi; + mach_msg_type_number_t pi_len = 0; + int info_flags = PI_FETCH_TASKINFO; + int suspend_count = -1; + error_t err; + + retry: + err = proc_getprocinfo (proc_server, inf->pid, &info_flags, + (procinfo_t *) &pi, &pi_len, &noise, &noise_len); + if (err) + { + inf->task->dead = 1; /* oh well */ + return; + } + + if (inf->task->cur_sc < pi->taskinfo.suspend_count && suspend_count == -1) + { + /* The proc server might have suspended the task while stopping + it. This happens when the task is handling a traced signal. + Refetch the suspend count. The proc server should be + finished stopping the task by now. */ + suspend_count = pi->taskinfo.suspend_count; + goto retry; + } + + suspend_count = pi->taskinfo.suspend_count; + + vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); + if (noise_len > 0) + vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); + + if (inf->task->cur_sc < suspend_count) + { + int abort; + + target_terminal_ours (); /* Allow I/O. */ + abort = !query ("Pid %d has an additional task suspend count of %d;" + " clear it? ", inf->pid, + suspend_count - inf->task->cur_sc); + target_terminal_inferior (); /* Give it back to the child. */ + + if (abort) + error ("Additional task suspend count left untouched."); + + inf->task->cur_sc = suspend_count; + } +} + +/* Turns tracing for INF on or off, depending on ON, unless it already + is. If INF is running, the resume_sc count of INF's threads will + be modified, and the signal thread will briefly be run to change + the trace state. */ +void +inf_set_traced (struct inf *inf, int on) +{ + if (on == inf->traced) + return; + + if (inf->task && !inf->task->dead) + /* Make it take effect immediately. */ + { + sigset_t mask = on ? ~(sigset_t) 0 : 0; + error_t err = + INF_RESUME_MSGPORT_RPC (inf, msg_set_init_int (msgport, refport, + INIT_TRACEMASK, mask)); + if (err == EIEIO) + { + if (on) + warning ("Can't modify tracing state for pid %d: %s", + inf->pid, "No signal thread"); + inf->traced = on; + } + else if (err) + warning ("Can't modify tracing state for pid %d: %s", + inf->pid, safe_strerror (err)); + else + inf->traced = on; + } + else + inf->traced = on; +} + + +/* Makes all the real suspend count deltas of all the procs in INF + match the desired values. Careful to always do thread/task suspend + counts in the safe order. Returns true if at least one thread is + thought to be running. */ +int +inf_update_suspends (struct inf *inf) +{ + struct proc *task = inf->task; + /* We don't have to update INF->threads even though we're iterating over it + because we'll change a thread only if it already has an existing proc + entry. */ + + inf_debug (inf, "updating suspend counts"); + + if (task) + { + struct proc *thread; + int task_running = (task->sc == 0), thread_running = 0; + + if (task->sc > task->cur_sc) + /* The task is becoming _more_ suspended; do before any threads. */ + task_running = proc_update_sc (task); + + if (inf->pending_execs) + /* When we're waiting for an exec, things may be happening behind our + back, so be conservative. */ + thread_running = 1; + + /* Do all the thread suspend counts. */ + for (thread = inf->threads; thread; thread = thread->next) + thread_running |= proc_update_sc (thread); + + if (task->sc != task->cur_sc) + /* We didn't do the task first, because we wanted to wait for the + threads; do it now. */ + task_running = proc_update_sc (task); + + inf_debug (inf, "%srunning...", + (thread_running && task_running) ? "" : "not "); + + inf->running = thread_running && task_running; + + /* Once any thread has executed some code, we can't depend on the + threads list any more. */ + if (inf->running) + inf->threads_up_to_date = 0; + + return inf->running; + } + + return 0; +} + + +/* Converts a GDB pid to a struct proc. */ +struct proc * +inf_tid_to_thread (struct inf *inf, int tid) +{ + struct proc *thread = inf->threads; + + while (thread) + if (thread->tid == tid) + return thread; + else + thread = thread->next; + return 0; +} + +/* Converts a thread port to a struct proc. */ +struct proc * +inf_port_to_thread (struct inf *inf, mach_port_t port) +{ + struct proc *thread = inf->threads; + while (thread) + if (thread->port == port) + return thread; + else + thread = thread->next; + return 0; +} + + +/* Make INF's list of threads be consistent with reality of TASK. */ +void +inf_validate_procs (struct inf *inf) +{ + thread_array_t threads; + mach_msg_type_number_t num_threads, i; + struct proc *task = inf->task; + + /* If no threads are currently running, this function will guarantee that + things are up to date. The exception is if there are zero threads -- + then it is almost certainly in an odd state, and probably some outside + agent will create threads. */ + inf->threads_up_to_date = inf->threads ? !inf->running : 0; + + if (task) + { + error_t err = task_threads (task->port, &threads, &num_threads); + inf_debug (inf, "fetching threads"); + if (err) + /* TASK must be dead. */ + { + task->dead = 1; + task = 0; + } + } + + if (!task) + { + num_threads = 0; + inf_debug (inf, "no task"); + } + + { + /* Make things normally linear. */ + mach_msg_type_number_t search_start = 0; + /* Which thread in PROCS corresponds to each task thread, & the task. */ + struct proc *matched[num_threads + 1]; + /* The last thread in INF->threads, so we can add to the end. */ + struct proc *last = 0; + /* The current thread we're considering. */ + struct proc *thread = inf->threads; + + memset (matched, 0, sizeof (matched)); + + while (thread) + { + mach_msg_type_number_t left; + + for (i = search_start, left = num_threads; left; i++, left--) + { + if (i >= num_threads) + i -= num_threads; /* I wrapped around. */ + if (thread->port == threads[i]) + /* We already know about this thread. */ + { + matched[i] = thread; + last = thread; + thread = thread->next; + search_start++; + break; + } + } + + if (!left) + { + proc_debug (thread, "died!"); + thread->port = MACH_PORT_NULL; + thread = _proc_free (thread); /* THREAD is dead. */ + (last ? last->next : inf->threads) = thread; + } + } + + for (i = 0; i < num_threads; i++) + { + if (matched[i]) + /* Throw away the duplicate send right. */ + mach_port_deallocate (mach_task_self (), threads[i]); + else + /* THREADS[I] is a thread we don't know about yet! */ + { + thread = make_proc (inf, threads[i], next_thread_id++); + (last ? last->next : inf->threads) = thread; + last = thread; + proc_debug (thread, "new thread: %d", threads[i]); + add_thread (pid_to_ptid (thread->tid)); /* Tell GDB's generic thread code. */ + } + } + + vm_deallocate (mach_task_self (), + (vm_address_t) threads, (num_threads * sizeof (thread_t))); + } +} + + +/* Makes sure that INF's thread list is synced with the actual process. */ +int +inf_update_procs (struct inf *inf) +{ + if (!inf->task) + return 0; + if (!inf->threads_up_to_date) + inf_validate_procs (inf); + return !!inf->task; +} + +/* Sets the resume_sc of each thread in inf. That of RUN_THREAD is set to 0, + and others are set to their run_sc if RUN_OTHERS is true, and otherwise + their pause_sc. */ +void +inf_set_threads_resume_sc (struct inf *inf, + struct proc *run_thread, int run_others) +{ + struct proc *thread; + inf_update_procs (inf); + for (thread = inf->threads; thread; thread = thread->next) + if (thread == run_thread) + thread->resume_sc = 0; + else if (run_others) + thread->resume_sc = thread->run_sc; + else + thread->resume_sc = thread->pause_sc; +} + + +/* Cause INF to continue execution immediately; individual threads may still + be suspended (but their suspend counts will be updated). */ +void +inf_resume (struct inf *inf) +{ + struct proc *thread; + + inf_update_procs (inf); + + for (thread = inf->threads; thread; thread = thread->next) + thread->sc = thread->resume_sc; + + if (inf->task) + { + if (!inf->pending_execs) + /* Try to make sure our task count is correct -- in the case where + we're waiting for an exec though, things are too volatile, so just + assume things will be reasonable (which they usually will be). */ + inf_validate_task_sc (inf); + inf->task->sc = 0; + } + + inf_update_suspends (inf); +} + +/* Cause INF to stop execution immediately; individual threads may still + be running. */ +void +inf_suspend (struct inf *inf) +{ + struct proc *thread; + + inf_update_procs (inf); + + for (thread = inf->threads; thread; thread = thread->next) + thread->sc = thread->pause_sc; + + if (inf->task) + inf->task->sc = inf->pause_sc; + + inf_update_suspends (inf); +} + + +/* INF has one thread PROC that is in single-stepping mode. This + function changes it to be PROC, changing any old step_thread to be + a normal one. A PROC of 0 clears any existing value. */ +void +inf_set_step_thread (struct inf *inf, struct proc *thread) +{ + gdb_assert (!thread || proc_is_thread (thread)); + + if (thread) + inf_debug (inf, "setting step thread: %d/%d", inf->pid, thread->tid); + else + inf_debug (inf, "clearing step thread"); + + if (inf->step_thread != thread) + { + if (inf->step_thread && inf->step_thread->port != MACH_PORT_NULL) + if (!proc_trace (inf->step_thread, 0)) + return; + if (thread && proc_trace (thread, 1)) + inf->step_thread = thread; + else + inf->step_thread = 0; + } +} + + +/* Set up the thread resume_sc's so that only the signal thread is running + (plus whatever other thread are set to always run). Returns true if we + did so, or false if we can't find a signal thread. */ +int +inf_set_threads_resume_sc_for_signal_thread (struct inf *inf) +{ + if (inf->signal_thread) + { + inf_set_threads_resume_sc (inf, inf->signal_thread, 0); + return 1; + } + else + return 0; +} + +static void +inf_update_signal_thread (struct inf *inf) +{ + /* XXX for now we assume that if there's a msgport, the 2nd thread is + the signal thread. */ + inf->signal_thread = inf->threads ? inf->threads->next : 0; +} + + +/* Detachs from INF's inferior task, letting it run once again... */ +void +inf_detach (struct inf *inf) +{ + struct proc *task = inf->task; + + inf_debug (inf, "detaching..."); + + inf_clear_wait (inf); + inf_set_step_thread (inf, 0); + + if (task) + { + struct proc *thread; + + inf_validate_procinfo (inf); + + inf_set_traced (inf, 0); + if (inf->stopped) + { + if (inf->nomsg) + inf_continue (inf); + else + inf_signal (inf, TARGET_SIGNAL_0); + } + + proc_restore_exc_port (task); + task->sc = inf->detach_sc; + + for (thread = inf->threads; thread; thread = thread->next) + { + proc_restore_exc_port (thread); + thread->sc = thread->detach_sc; + } + + inf_update_suspends (inf); + } + + inf_cleanup (inf); +} + +/* Attaches INF to the process with process id PID, returning it in a + suspended state suitable for debugging. */ +void +inf_attach (struct inf *inf, int pid) +{ + inf_debug (inf, "attaching: %d", pid); + + if (inf->pid) + inf_detach (inf); + + inf_startup (inf, pid); +} + + +/* Makes sure that we've got our exception ports entrenched in the process. */ +void +inf_steal_exc_ports (struct inf *inf) +{ + struct proc *thread; + + inf_debug (inf, "stealing exception ports"); + + inf_set_step_thread (inf, 0); /* The step thread is special. */ + + proc_steal_exc_port (inf->task, inf->event_port); + for (thread = inf->threads; thread; thread = thread->next) + proc_steal_exc_port (thread, MACH_PORT_NULL); +} + +/* Makes sure the process has its own exception ports. */ +void +inf_restore_exc_ports (struct inf *inf) +{ + struct proc *thread; + + inf_debug (inf, "restoring exception ports"); + + inf_set_step_thread (inf, 0); /* The step thread is special. */ + + proc_restore_exc_port (inf->task); + for (thread = inf->threads; thread; thread = thread->next) + proc_restore_exc_port (thread); +} + + +/* Deliver signal SIG to INF. If INF is stopped, delivering a signal, even + signal 0, will continue it. INF is assumed to be in a paused state, and + the resume_sc's of INF's threads may be affected. */ +void +inf_signal (struct inf *inf, enum target_signal sig) +{ + error_t err = 0; + int host_sig = target_signal_to_host (sig); + +#define NAME target_signal_to_name (sig) + + if (host_sig >= _NSIG) + /* A mach exception. Exceptions are encoded in the signal space by + putting them after _NSIG; this assumes they're positive (and not + extremely large)! */ + { + struct inf_wait *w = &inf->wait; + if (w->status.kind == TARGET_WAITKIND_STOPPED + && w->status.value.sig == sig + && w->thread && !w->thread->aborted) + /* We're passing through the last exception we received. This is + kind of bogus, because exceptions are per-thread whereas gdb + treats signals as per-process. We just forward the exception to + the correct handler, even it's not for the same thread as TID -- + i.e., we pretend it's global. */ + { + struct exc_state *e = &w->exc; + inf_debug (inf, "passing through exception:" + " task = %d, thread = %d, exc = %d" + ", code = %d, subcode = %d", + w->thread->port, inf->task->port, + e->exception, e->code, e->subcode); + err = + exception_raise_request (e->handler, + e->reply, MACH_MSG_TYPE_MOVE_SEND_ONCE, + w->thread->port, inf->task->port, + e->exception, e->code, e->subcode); + } + else + error ("Can't forward spontaneous exception (%s).", NAME); + } + else + /* A Unix signal. */ + if (inf->stopped) + /* The process is stopped and expecting a signal. Just send off a + request and let it get handled when we resume everything. */ + { + inf_debug (inf, "sending %s to stopped process", NAME); + err = + INF_MSGPORT_RPC (inf, + msg_sig_post_untraced_request (msgport, + inf->event_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + host_sig, 0, + refport)); + if (!err) + /* Posting an untraced signal automatically continues it. + We clear this here rather than when we get the reply + because we'd rather assume it's not stopped when it + actually is, than the reverse. */ + inf->stopped = 0; + } + else + /* It's not expecting it. We have to let just the signal thread + run, and wait for it to get into a reasonable state before we + can continue the rest of the process. When we finally resume the + process the signal we request will be the very first thing that + happens. */ + { + inf_debug (inf, "sending %s to unstopped process" + " (so resuming signal thread)", NAME); + err = + INF_RESUME_MSGPORT_RPC (inf, + msg_sig_post_untraced (msgport, host_sig, + 0, refport)); + } + + if (err == EIEIO) + /* Can't do too much... */ + warning ("Can't deliver signal %s: No signal thread.", NAME); + else if (err) + warning ("Delivering signal %s: %s", NAME, safe_strerror (err)); + +#undef NAME +} + + +/* Continue INF without delivering a signal. This is meant to be used + when INF does not have a message port. */ +void +inf_continue (struct inf *inf) +{ + process_t proc; + error_t err = proc_pid2proc (proc_server, inf->pid, &proc); + + if (!err) + { + inf_debug (inf, "continuing process"); + + err = proc_mark_cont (proc); + if (!err) + { + struct proc *thread; + + for (thread = inf->threads; thread; thread = thread->next) + thread_resume (thread->port); + + inf->stopped = 0; + } + } + + if (err) + warning ("Can't continue process: %s", safe_strerror (err)); +} + + +/* The inferior used for all gdb target ops. */ +struct inf *current_inferior = 0; + +/* The inferior being waited for by gnu_wait. Since GDB is decidely not + multi-threaded, we don't bother to lock this. */ +struct inf *waiting_inf; + +/* Wait for something to happen in the inferior, returning what in STATUS. */ +static ptid_t +gnu_wait (ptid_t tid, struct target_waitstatus *status) +{ + struct msg + { + mach_msg_header_t hdr; + mach_msg_type_t type; + int data[8000]; + } msg; + error_t err; + struct proc *thread; + struct inf *inf = current_inferior; + + extern int exc_server (mach_msg_header_t *, mach_msg_header_t *); + extern int msg_reply_server (mach_msg_header_t *, mach_msg_header_t *); + extern int notify_server (mach_msg_header_t *, mach_msg_header_t *); + extern int process_reply_server (mach_msg_header_t *, mach_msg_header_t *); + + gdb_assert (inf->task); + + if (!inf->threads && !inf->pending_execs) + /* No threads! Assume that maybe some outside agency is frobbing our + task, and really look for new threads. If we can't find any, just tell + the user to try again later. */ + { + inf_validate_procs (inf); + if (!inf->threads && !inf->task->dead) + error ("There are no threads; try again later."); + } + + waiting_inf = inf; + + inf_debug (inf, "waiting for: %d", PIDGET (tid)); + +rewait: + if (proc_wait_pid != inf->pid && !inf->no_wait) + /* Always get information on events from the proc server. */ + { + inf_debug (inf, "requesting wait on pid %d", inf->pid); + + if (proc_wait_pid) + /* The proc server is single-threaded, and only allows a single + outstanding wait request, so we have to cancel the previous one. */ + { + inf_debug (inf, "cancelling previous wait on pid %d", proc_wait_pid); + interrupt_operation (proc_server, 0); + } + + err = + proc_wait_request (proc_server, inf->event_port, inf->pid, WUNTRACED); + if (err) + warning ("wait request failed: %s", safe_strerror (err)); + else + { + inf_debug (inf, "waits pending: %d", proc_waits_pending); + proc_wait_pid = inf->pid; + /* Even if proc_waits_pending was > 0 before, we still won't + get any other replies, because it was either from a + different INF, or a different process attached to INF -- + and the event port, which is the wait reply port, changes + when you switch processes. */ + proc_waits_pending = 1; + } + } + + inf_clear_wait (inf); + + /* What can happen? (1) Dead name notification; (2) Exceptions arrive; + (3) wait reply from the proc server. */ + + inf_debug (inf, "waiting for an event..."); + err = mach_msg (&msg.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, + 0, sizeof (struct msg), inf->event_port, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + + /* Re-suspend the task. */ + inf_suspend (inf); + + if (!inf->task && inf->pending_execs) + /* When doing an exec, it's possible that the old task wasn't reused + (e.g., setuid execs). So if the task seems to have disappeared, + attempt to refetch it, as the pid should still be the same. */ + inf_set_pid (inf, inf->pid); + + if (err == EMACH_RCV_INTERRUPTED) + inf_debug (inf, "interrupted"); + else if (err) + error ("Couldn't wait for an event: %s", safe_strerror (err)); + else + { + struct + { + mach_msg_header_t hdr; + mach_msg_type_t err_type; + kern_return_t err; + char noise[200]; + } + reply; + + inf_debug (inf, "event: msgid = %d", msg.hdr.msgh_id); + + /* Handle what we got. */ + if (!notify_server (&msg.hdr, &reply.hdr) + && !exc_server (&msg.hdr, &reply.hdr) + && !process_reply_server (&msg.hdr, &reply.hdr) + && !msg_reply_server (&msg.hdr, &reply.hdr)) + /* Whatever it is, it's something strange. */ + error ("Got a strange event, msg id = %d.", msg.hdr.msgh_id); + + if (reply.err) + error ("Handling event, msgid = %d: %s", + msg.hdr.msgh_id, safe_strerror (reply.err)); + } + + if (inf->pending_execs) + /* We're waiting for the inferior to finish execing. */ + { + struct inf_wait *w = &inf->wait; + enum target_waitkind kind = w->status.kind; + + if (kind == TARGET_WAITKIND_SPURIOUS) + /* Since gdb is actually counting the number of times the inferior + stops, expecting one stop per exec, we only return major events + while execing. */ + { + w->suppress = 1; + inf_debug (inf, "pending_execs = %d, ignoring minor event", + inf->pending_execs); + } + else if (kind == TARGET_WAITKIND_STOPPED + && w->status.value.sig == TARGET_SIGNAL_TRAP) + /* Ah hah! A SIGTRAP from the inferior while starting up probably + means we've succesfully completed an exec! */ + { + if (--inf->pending_execs == 0) + /* We're done! */ + { +#if 0 /* do we need this? */ + prune_threads (1); /* Get rid of the old shell threads */ + renumber_threads (0); /* Give our threads reasonable names. */ +#endif + } + inf_debug (inf, "pending exec completed, pending_execs => %d", + inf->pending_execs); + } + else if (kind == TARGET_WAITKIND_STOPPED) + /* It's possible that this signal is because of a crashed process + being handled by the hurd crash server; in this case, the process + will have an extra task suspend, which we need to know about. + Since the code in inf_resume that normally checks for this is + disabled while INF->pending_execs, we do the check here instead. */ + inf_validate_task_sc (inf); + } + + if (inf->wait.suppress) + /* Some totally spurious event happened that we don't consider + worth returning to gdb. Just keep waiting. */ + { + inf_debug (inf, "suppressing return, rewaiting..."); + inf_resume (inf); + goto rewait; + } + + /* Pass back out our results. */ + bcopy (&inf->wait.status, status, sizeof (*status)); + + thread = inf->wait.thread; + if (thread) + tid = pid_to_ptid (thread->tid); + else + thread = inf_tid_to_thread (inf, PIDGET (tid)); + + if (!thread || thread->port == MACH_PORT_NULL) + { + /* TID is dead; try and find a new thread. */ + if (inf_update_procs (inf) && inf->threads) + tid = pid_to_ptid (inf->threads->tid); /* The first available thread. */ + else + tid = inferior_ptid; /* let wait_for_inferior handle exit case */ + } + + if (thread && PIDGET (tid) >= 0 && status->kind != TARGET_WAITKIND_SPURIOUS + && inf->pause_sc == 0 && thread->pause_sc == 0) + /* If something actually happened to THREAD, make sure we + suspend it. */ + { + thread->sc = 1; + inf_update_suspends (inf); + } + + inf_debug (inf, "returning tid = %d, status = %s (%d)", PIDGET (tid), + status->kind == TARGET_WAITKIND_EXITED ? "EXITED" + : status->kind == TARGET_WAITKIND_STOPPED ? "STOPPED" + : status->kind == TARGET_WAITKIND_SIGNALLED ? "SIGNALLED" + : status->kind == TARGET_WAITKIND_LOADED ? "LOADED" + : status->kind == TARGET_WAITKIND_SPURIOUS ? "SPURIOUS" + : "?", + status->value.integer); + + return tid; +} + + +/* The rpc handler called by exc_server. */ +error_t +S_exception_raise_request (mach_port_t port, mach_port_t reply_port, + thread_t thread_port, task_t task_port, + int exception, int code, int subcode) +{ + struct inf *inf = waiting_inf; + struct proc *thread = inf_port_to_thread (inf, thread_port); + + inf_debug (waiting_inf, + "thread = %d, task = %d, exc = %d, code = %d, subcode = %d", + thread_port, task_port, exception, code, subcode); + + if (!thread) + /* We don't know about thread? */ + { + inf_update_procs (inf); + thread = inf_port_to_thread (inf, thread_port); + if (!thread) + /* Give up, the generating thread is gone. */ + return 0; + } + + mach_port_deallocate (mach_task_self (), thread_port); + mach_port_deallocate (mach_task_self (), task_port); + + if (!thread->aborted) + /* THREAD hasn't been aborted since this exception happened (abortion + clears any exception state), so it must be real. */ + { + /* Store away the details; this will destroy any previous info. */ + inf->wait.thread = thread; + + inf->wait.status.kind = TARGET_WAITKIND_STOPPED; + + if (exception == EXC_BREAKPOINT) + /* GDB likes to get SIGTRAP for breakpoints. */ + { + inf->wait.status.value.sig = TARGET_SIGNAL_TRAP; + mach_port_deallocate (mach_task_self (), reply_port); + } + else + /* Record the exception so that we can forward it later. */ + { + if (thread->exc_port == port) + { + inf_debug (waiting_inf, "Handler is thread exception port <%d>", + thread->saved_exc_port); + inf->wait.exc.handler = thread->saved_exc_port; + } + else + { + inf_debug (waiting_inf, "Handler is task exception port <%d>", + inf->task->saved_exc_port); + inf->wait.exc.handler = inf->task->saved_exc_port; + gdb_assert (inf->task->exc_port == port); + } + if (inf->wait.exc.handler != MACH_PORT_NULL) + /* Add a reference to the exception handler. */ + mach_port_mod_refs (mach_task_self (), + inf->wait.exc.handler, MACH_PORT_RIGHT_SEND, + 1); + + inf->wait.exc.exception = exception; + inf->wait.exc.code = code; + inf->wait.exc.subcode = subcode; + inf->wait.exc.reply = reply_port; + + /* Exceptions are encoded in the signal space by putting them after + _NSIG; this assumes they're positive (and not extremely large)! */ + inf->wait.status.value.sig = + target_signal_from_host (_NSIG + exception); + } + } + else + /* A supppressed exception, which ignore. */ + { + inf->wait.suppress = 1; + mach_port_deallocate (mach_task_self (), reply_port); + } + + return 0; +} + + +/* Fill in INF's wait field after a task has died without giving us more + detailed information. */ +void +inf_task_died_status (struct inf *inf) +{ + warning ("Pid %d died with unknown exit status, using SIGKILL.", inf->pid); + inf->wait.status.kind = TARGET_WAITKIND_SIGNALLED; + inf->wait.status.value.sig = TARGET_SIGNAL_KILL; +} + +/* Notify server routines. The only real one is dead name notification. */ +error_t +do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port) +{ + struct inf *inf = waiting_inf; + + inf_debug (waiting_inf, "port = %d", dead_port); + + if (inf->task && inf->task->port == dead_port) + { + proc_debug (inf->task, "is dead"); + inf->task->port = MACH_PORT_NULL; + if (proc_wait_pid == inf->pid) + /* We have a wait outstanding on the process, which will return more + detailed information, so delay until we get that. */ + inf->wait.suppress = 1; + else + /* We never waited for the process (maybe it wasn't a child), so just + pretend it got a SIGKILL. */ + inf_task_died_status (inf); + } + else + { + struct proc *thread = inf_port_to_thread (inf, dead_port); + if (thread) + { + proc_debug (thread, "is dead"); + thread->port = MACH_PORT_NULL; + } + + if (inf->task->dead) + /* Since the task is dead, its threads are dying with it. */ + inf->wait.suppress = 1; + } + + mach_port_deallocate (mach_task_self (), dead_port); + inf->threads_up_to_date = 0; /* Just in case */ + + return 0; +} + + +static error_t +ill_rpc (char *fun) +{ + warning ("illegal rpc: %s", fun); + return 0; +} + +error_t +do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t count) +{ + return ill_rpc ("do_mach_notify_no_senders"); +} + +error_t +do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name) +{ + return ill_rpc ("do_mach_notify_port_deleted"); +} + +error_t +do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name) +{ + return ill_rpc ("do_mach_notify_msg_accepted"); +} + +error_t +do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t name) +{ + return ill_rpc ("do_mach_notify_port_destroyed"); +} + +error_t +do_mach_notify_send_once (mach_port_t notify) +{ + return ill_rpc ("do_mach_notify_send_once"); +} + + +/* Process_reply server routines. We only use process_wait_reply. */ + +error_t +S_proc_wait_reply (mach_port_t reply, error_t err, + int status, int sigcode, rusage_t rusage, pid_t pid) +{ + struct inf *inf = waiting_inf; + + inf_debug (inf, "err = %s, pid = %d, status = 0x%x, sigcode = %d", + err ? safe_strerror (err) : "0", pid, status, sigcode); + + if (err && proc_wait_pid && (!inf->task || !inf->task->port)) + /* Ack. The task has died, but the task-died notification code didn't + tell anyone because it thought a more detailed reply from the + procserver was forthcoming. However, we now learn that won't + happen... So we have to act like the task just died, and this time, + tell the world. */ + inf_task_died_status (inf); + + if (--proc_waits_pending == 0) + /* PROC_WAIT_PID represents the most recent wait. We will always get + replies in order because the proc server is single threaded. */ + proc_wait_pid = 0; + + inf_debug (inf, "waits pending now: %d", proc_waits_pending); + + if (err) + { + if (err != EINTR) + { + warning ("Can't wait for pid %d: %s", inf->pid, safe_strerror (err)); + inf->no_wait = 1; + + /* Since we can't see the inferior's signals, don't trap them. */ + inf_set_traced (inf, 0); + } + } + else if (pid == inf->pid) + { + store_waitstatus (&inf->wait.status, status); + if (inf->wait.status.kind == TARGET_WAITKIND_STOPPED) + /* The process has sent us a signal, and stopped itself in a sane + state pending our actions. */ + { + inf_debug (inf, "process has stopped itself"); + inf->stopped = 1; + } + } + else + inf->wait.suppress = 1; /* Something odd happened. Ignore. */ + + return 0; +} + +error_t +S_proc_setmsgport_reply (mach_port_t reply, error_t err, + mach_port_t old_msg_port) +{ + return ill_rpc ("S_proc_setmsgport_reply"); +} + +error_t +S_proc_getmsgport_reply (mach_port_t reply, error_t err, mach_port_t msg_port) +{ + return ill_rpc ("S_proc_getmsgport_reply"); +} + + +/* Msg_reply server routines. We only use msg_sig_post_untraced_reply. */ + +error_t +S_msg_sig_post_untraced_reply (mach_port_t reply, error_t err) +{ + struct inf *inf = waiting_inf; + + if (err == EBUSY) + /* EBUSY is what we get when the crash server has grabbed control of the + process and doesn't like what signal we tried to send it. Just act + like the process stopped (using a signal of 0 should mean that the + *next* time the user continues, it will pass signal 0, which the crash + server should like). */ + { + inf->wait.status.kind = TARGET_WAITKIND_STOPPED; + inf->wait.status.value.sig = TARGET_SIGNAL_0; + } + else if (err) + warning ("Signal delivery failed: %s", safe_strerror (err)); + + if (err) + /* We only get this reply when we've posted a signal to a process which we + thought was stopped, and which we expected to continue after the signal. + Given that the signal has failed for some reason, it's reasonable to + assume it's still stopped. */ + inf->stopped = 1; + else + inf->wait.suppress = 1; + + return 0; +} + +error_t +S_msg_sig_post_reply (mach_port_t reply, error_t err) +{ + return ill_rpc ("S_msg_sig_post_reply"); +} + + +/* Returns the number of messages queued for the receive right PORT. */ +static mach_port_msgcount_t +port_msgs_queued (mach_port_t port) +{ + struct mach_port_status status; + error_t err = + mach_port_get_receive_status (mach_task_self (), port, &status); + + if (err) + return 0; + else + return status.mps_msgcount; +} + + +/* Resume execution of the inferior process. + + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. + + TID STEP: + -1 true Single step the current thread allowing other threads to run. + -1 false Continue the current thread allowing other threads to run. + X true Single step the given thread, don't allow any others to run. + X false Continue the given thread, do not allow any others to run. + (Where X, of course, is anything except -1) + + Note that a resume may not `take' if there are pending exceptions/&c + still unprocessed from the last resume we did (any given resume may result + in multiple events returned by wait). + */ +static void +gnu_resume (ptid_t tid, int step, enum target_signal sig) +{ + struct proc *step_thread = 0; + struct inf *inf = current_inferior; + + inf_debug (inf, "tid = %d, step = %d, sig = %d", PIDGET (tid), step, sig); + + inf_validate_procinfo (inf); + + if (sig != TARGET_SIGNAL_0 || inf->stopped) + { + if (sig == TARGET_SIGNAL_0 && inf->nomsg) + inf_continue (inf); + else + inf_signal (inf, sig); + } + else if (inf->wait.exc.reply != MACH_PORT_NULL) + /* We received an exception to which we have chosen not to forward, so + abort the faulting thread, which will perhaps retake it. */ + { + proc_abort (inf->wait.thread, 1); + warning ("Aborting %s with unforwarded exception %s.", + proc_string (inf->wait.thread), + target_signal_to_name (inf->wait.status.value.sig)); + } + + if (port_msgs_queued (inf->event_port)) + /* If there are still messages in our event queue, don't bother resuming + the process, as we're just going to stop it right away anyway. */ + return; + + inf_update_procs (inf); + + if (PIDGET (tid) < 0) + /* Allow all threads to run, except perhaps single-stepping one. */ + { + inf_debug (inf, "running all threads; tid = %d", PIDGET (inferior_ptid)); + tid = inferior_ptid; /* What to step. */ + inf_set_threads_resume_sc (inf, 0, 1); + } + else + /* Just allow a single thread to run. */ + { + struct proc *thread = inf_tid_to_thread (inf, PIDGET (tid)); + if (!thread) + error ("Can't run single thread id %d: no such thread!"); + inf_debug (inf, "running one thread: %d/%d", inf->pid, thread->tid); + inf_set_threads_resume_sc (inf, thread, 0); + } + + if (step) + { + step_thread = inf_tid_to_thread (inf, PIDGET (tid)); + if (!step_thread) + warning ("Can't step thread id %d: no such thread.", PIDGET (tid)); + else + inf_debug (inf, "stepping thread: %d/%d", inf->pid, step_thread->tid); + } + if (step_thread != inf->step_thread) + inf_set_step_thread (inf, step_thread); + + inf_debug (inf, "here we go..."); + inf_resume (inf); +} + + +static void +gnu_kill_inferior (void) +{ + struct proc *task = current_inferior->task; + if (task) + { + proc_debug (task, "terminating..."); + task_terminate (task->port); + inf_set_pid (current_inferior, -1); + } + target_mourn_inferior (); +} + +/* Clean up after the inferior dies. */ +static void +gnu_mourn_inferior (void) +{ + inf_debug (current_inferior, "rip"); + inf_detach (current_inferior); + unpush_target (&gnu_ops); + generic_mourn_inferior (); +} + + +/* Fork an inferior process, and start debugging it. */ + +/* Set INFERIOR_PID to the first thread available in the child, if any. */ +static int +inf_pick_first_thread (void) +{ + if (current_inferior->task && current_inferior->threads) + /* The first thread. */ + return current_inferior->threads->tid; + else + /* What may be the next thread. */ + return next_thread_id; +} + +static struct inf * +cur_inf (void) +{ + if (!current_inferior) + current_inferior = make_inf (); + return current_inferior; +} + +static void +gnu_create_inferior (char *exec_file, char *allargs, char **env) +{ + struct inf *inf = cur_inf (); + + void trace_me () + { + /* We're in the child; make this process stop as soon as it execs. */ + inf_debug (inf, "tracing self"); + if (ptrace (PTRACE_TRACEME) != 0) + error ("ptrace (PTRACE_TRACEME) failed!"); + } + void attach_to_child (int pid) + { + /* Attach to the now stopped child, which is actually a shell... */ + inf_debug (inf, "attaching to child: %d", pid); + + inf_attach (inf, pid); + + attach_flag = 0; + push_target (&gnu_ops); + + inf->pending_execs = 2; + inf->nomsg = 1; + inf->traced = 1; + + /* Now let the child run again, knowing that it will stop immediately + because of the ptrace. */ + inf_resume (inf); + inferior_ptid = pid_to_ptid (inf_pick_first_thread ()); + + startup_inferior (inf->pending_execs); + } + + inf_debug (inf, "creating inferior"); + + fork_inferior (exec_file, allargs, env, trace_me, attach_to_child, + NULL, NULL); + + inf_validate_procinfo (inf); + inf_update_signal_thread (inf); + inf_set_traced (inf, inf->want_signals); + + /* Execing the process will have trashed our exception ports; steal them + back (or make sure they're restored if the user wants that). */ + if (inf->want_exceptions) + inf_steal_exc_ports (inf); + else + inf_restore_exc_ports (inf); + + /* Here we go! */ + proceed ((CORE_ADDR) -1, 0, 0); +} + +/* Mark our target-struct as eligible for stray "run" and "attach" + commands. */ +static int +gnu_can_run (void) +{ + return 1; +} + + +#ifdef ATTACH_DETACH + +/* Attach to process PID, then initialize for debugging it + and wait for the trace-trap that results from attaching. */ +static void +gnu_attach (char *args, int from_tty) +{ + int pid; + char *exec_file; + struct inf *inf = cur_inf (); + + if (!args) + error_no_arg ("process-id to attach"); + + pid = atoi (args); + + if (pid == getpid ()) /* Trying to masturbate? */ + error ("I refuse to debug myself!"); + + if (from_tty) + { + exec_file = (char *) get_exec_file (0); + + if (exec_file) + printf_unfiltered ("Attaching to program `%s', pid %d\n", + exec_file, pid); + else + printf_unfiltered ("Attaching to pid %d\n", pid); + + gdb_flush (gdb_stdout); + } + + inf_debug (inf, "attaching to pid: %d", pid); + + inf_attach (inf, pid); + inf_update_procs (inf); + + inferior_ptid = pid_to_ptid (inf_pick_first_thread ()); + + attach_flag = 1; + push_target (&gnu_ops); + + /* We have to initialize the terminal settings now, since the code + below might try to restore them. */ + target_terminal_init (); + + /* If the process was stopped before we attached, make it continue the next + time the user does a continue. */ + inf_validate_procinfo (inf); + + inf_update_signal_thread (inf); + inf_set_traced (inf, inf->want_signals); + +#if 0 /* Do we need this? */ + renumber_threads (0); /* Give our threads reasonable names. */ +#endif +} + + +/* Take a program previously attached to and detaches it. + The program resumes execution and will no longer stop + on signals, etc. We'd better not have left any breakpoints + in the program or it'll die when it hits one. For this + to work, it may be necessary for the process to have been + previously attached. It *might* work if the program was + started via fork. */ +static void +gnu_detach (char *args, int from_tty) +{ + if (from_tty) + { + char *exec_file = get_exec_file (0); + if (exec_file) + printf_unfiltered ("Detaching from program `%s' pid %d\n", + exec_file, current_inferior->pid); + else + printf_unfiltered ("Detaching from pid %d\n", current_inferior->pid); + gdb_flush (gdb_stdout); + } + + inf_detach (current_inferior); + + inferior_ptid = null_ptid; + + unpush_target (&gnu_ops); /* Pop out of handling an inferior */ +} +#endif /* ATTACH_DETACH */ + + +static void +gnu_terminal_init_inferior (void) +{ + gdb_assert (current_inferior); + terminal_init_inferior_with_pgrp (current_inferior->pid); +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ +static void +gnu_prepare_to_store (void) +{ +#ifdef CHILD_PREPARE_TO_STORE + CHILD_PREPARE_TO_STORE (); +#endif +} + +static void +gnu_open (char *arg, int from_tty) +{ + error ("Use the \"run\" command to start a Unix child process."); +} + +static void +gnu_stop (void) +{ + error ("to_stop target function not implemented"); +} + +static char * +gnu_pid_to_exec_file (int pid) +{ + error ("to_pid_to_exec_file target function not implemented"); + return NULL; +} + + +static int +gnu_thread_alive (ptid_t tid) +{ + inf_update_procs (current_inferior); + return !!inf_tid_to_thread (current_inferior, PIDGET (tid)); +} + + +/* Read inferior task's LEN bytes from ADDR and copy it to MYADDR in + gdb's address space. Return 0 on failure; number of bytes read + otherwise. */ +int +gnu_read_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length) +{ + error_t err; + vm_address_t low_address = (vm_address_t) trunc_page (addr); + vm_size_t aligned_length = + (vm_size_t) round_page (addr + length) - low_address; + pointer_t copied; + int copy_count; + + /* Get memory from inferior with page aligned addresses */ + err = vm_read (task, low_address, aligned_length, &copied, ©_count); + if (err) + return 0; + + err = hurd_safe_copyin (myaddr, (void *) addr - low_address + copied, length); + if (err) + { + warning ("Read from inferior faulted: %s", safe_strerror (err)); + length = 0; + } + + err = vm_deallocate (mach_task_self (), copied, copy_count); + if (err) + warning ("gnu_read_inferior vm_deallocate failed: %s", safe_strerror (err)); + + return length; +} + +#define CHK_GOTO_OUT(str,ret) \ + do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0) + +struct vm_region_list +{ + struct vm_region_list *next; + vm_prot_t protection; + vm_address_t start; + vm_size_t length; +}; + +struct obstack region_obstack; + +/* Write gdb's LEN bytes from MYADDR and copy it to ADDR in inferior + task's address space. */ +int +gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length) +{ + error_t err = 0; + vm_address_t low_address = (vm_address_t) trunc_page (addr); + vm_size_t aligned_length = + (vm_size_t) round_page (addr + length) - low_address; + pointer_t copied; + int copy_count; + int deallocate = 0; + + char *errstr = "Bug in gnu_write_inferior"; + + struct vm_region_list *region_element; + struct vm_region_list *region_head = (struct vm_region_list *) NULL; + + /* Get memory from inferior with page aligned addresses */ + err = vm_read (task, + low_address, + aligned_length, + &copied, + ©_count); + CHK_GOTO_OUT ("gnu_write_inferior vm_read failed", err); + + deallocate++; + + err = hurd_safe_copyout ((void *) addr - low_address + copied, + myaddr, length); + CHK_GOTO_OUT ("Write to inferior faulted", err); + + obstack_init (®ion_obstack); + + /* Do writes atomically. + First check for holes and unwritable memory. */ + { + vm_size_t remaining_length = aligned_length; + vm_address_t region_address = low_address; + + struct vm_region_list *scan; + + while (region_address < low_address + aligned_length) + { + vm_prot_t protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + boolean_t shared; + mach_port_t object_name; + vm_offset_t offset; + vm_size_t region_length = remaining_length; + vm_address_t old_address = region_address; + + err = vm_region (task, + ®ion_address, + ®ion_length, + &protection, + &max_protection, + &inheritance, + &shared, + &object_name, + &offset); + CHK_GOTO_OUT ("vm_region failed", err); + + /* Check for holes in memory */ + if (old_address != region_address) + { + warning ("No memory at 0x%x. Nothing written", + old_address); + err = KERN_SUCCESS; + length = 0; + goto out; + } + + if (!(max_protection & VM_PROT_WRITE)) + { + warning ("Memory at address 0x%x is unwritable. Nothing written", + old_address); + err = KERN_SUCCESS; + length = 0; + goto out; + } + + /* Chain the regions for later use */ + region_element = + (struct vm_region_list *) + obstack_alloc (®ion_obstack, sizeof (struct vm_region_list)); + + region_element->protection = protection; + region_element->start = region_address; + region_element->length = region_length; + + /* Chain the regions along with protections */ + region_element->next = region_head; + region_head = region_element; + + region_address += region_length; + remaining_length = remaining_length - region_length; + } + + /* If things fail after this, we give up. + Somebody is messing up inferior_task's mappings. */ + + /* Enable writes to the chained vm regions */ + for (scan = region_head; scan; scan = scan->next) + { + if (!(scan->protection & VM_PROT_WRITE)) + { + err = vm_protect (task, + scan->start, + scan->length, + FALSE, + scan->protection | VM_PROT_WRITE); + CHK_GOTO_OUT ("vm_protect: enable write failed", err); + } + } + + err = vm_write (task, + low_address, + copied, + aligned_length); + CHK_GOTO_OUT ("vm_write failed", err); + + /* Set up the original region protections, if they were changed */ + for (scan = region_head; scan; scan = scan->next) + { + if (!(scan->protection & VM_PROT_WRITE)) + { + err = vm_protect (task, + scan->start, + scan->length, + FALSE, + scan->protection); + CHK_GOTO_OUT ("vm_protect: enable write failed", err); + } + } + } + +out: + if (deallocate) + { + obstack_free (®ion_obstack, 0); + + (void) vm_deallocate (mach_task_self (), + copied, + copy_count); + } + + if (err != KERN_SUCCESS) + { + warning ("%s: %s", errstr, mach_error_string (err)); + return 0; + } + + return length; +} + + +/* Return 0 on failure, number of bytes handled otherwise. TARGET + is ignored. */ +static int +gnu_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, + struct target_ops *target) +{ + task_t task = (current_inferior + ? (current_inferior->task + ? current_inferior->task->port : 0) + : 0); + + if (task == MACH_PORT_NULL) + return 0; + else + { + inf_debug (current_inferior, "%s %p[%d] %s %p", + write ? "writing" : "reading", (void *) memaddr, len, + write ? "<--" : "-->", myaddr); + if (write) + return gnu_write_inferior (task, memaddr, myaddr, len); + else + return gnu_read_inferior (task, memaddr, myaddr, len); + } +} + +/* Call FUNC on each memory region in the task. */ +static int +gnu_find_memory_regions (int (*func) (CORE_ADDR, + unsigned long, + int, int, int, + void *), + void *data) +{ + error_t err; + task_t task; + vm_address_t region_address, last_region_address, last_region_end; + vm_prot_t last_protection; + + if (current_inferior == 0 || current_inferior->task == 0) + return 0; + task = current_inferior->task->port; + if (task == MACH_PORT_NULL) + return 0; + + region_address = last_region_address = last_region_end = VM_MIN_ADDRESS; + last_protection = VM_PROT_NONE; + while (region_address < VM_MAX_ADDRESS) + { + vm_prot_t protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + boolean_t shared; + mach_port_t object_name; + vm_offset_t offset; + vm_size_t region_length = VM_MAX_ADDRESS - region_address; + vm_address_t old_address = region_address; + + err = vm_region (task, + ®ion_address, + ®ion_length, + &protection, + &max_protection, + &inheritance, + &shared, + &object_name, + &offset); + if (err == KERN_NO_SPACE) + break; + if (err != KERN_SUCCESS) + { + warning ("vm_region failed: %s", mach_error_string (err)); + return -1; + } + + if (protection == last_protection && region_address == last_region_end) + /* This region is contiguous with and indistinguishable from + the previous one, so we just extend that one. */ + last_region_end = region_address += region_length; + else + { + /* This region is distinct from the last one we saw, so report + that previous one. */ + if (last_protection != VM_PROT_NONE) + (*func) (last_region_address, + last_region_end - last_region_address, + last_protection & VM_PROT_READ, + last_protection & VM_PROT_WRITE, + last_protection & VM_PROT_EXECUTE, + data); + last_region_address = region_address; + last_region_end = region_address += region_length; + last_protection = protection; + } + } + + /* Report the final region. */ + if (last_region_end > last_region_address && last_protection != VM_PROT_NONE) + (*func) (last_region_address, last_region_end - last_region_address, + last_protection & VM_PROT_READ, + last_protection & VM_PROT_WRITE, + last_protection & VM_PROT_EXECUTE, + data); + + return 0; +} + + +/* Return printable description of proc. */ +char * +proc_string (struct proc *proc) +{ + static char tid_str[80]; + if (proc_is_task (proc)) + sprintf (tid_str, "process %d", proc->inf->pid); + else + sprintf (tid_str, "thread %d.%d", + proc->inf->pid, pid_to_thread_id (MERGEPID (proc->tid, 0))); + return tid_str; +} + +static char * +gnu_pid_to_str (ptid_t ptid) +{ + struct inf *inf = current_inferior; + int tid = PIDGET (ptid); + struct proc *thread = inf_tid_to_thread (inf, tid); + + if (thread) + return proc_string (thread); + else + { + static char tid_str[80]; + sprintf (tid_str, "bogus thread id %d", tid); + return tid_str; + } +} + + +extern void gnu_store_registers (int regno); +extern void gnu_fetch_registers (int regno); + +struct target_ops gnu_ops; + +static void +init_gnu_ops (void) +{ + gnu_ops.to_shortname = "GNU"; /* to_shortname */ + gnu_ops.to_longname = "GNU Hurd process"; /* to_longname */ + gnu_ops.to_doc = "GNU Hurd process"; /* to_doc */ + gnu_ops.to_open = gnu_open; /* to_open */ + gnu_ops.to_attach = gnu_attach; /* to_attach */ + gnu_ops.to_detach = gnu_detach; /* to_detach */ + gnu_ops.to_resume = gnu_resume; /* to_resume */ + gnu_ops.to_wait = gnu_wait; /* to_wait */ + gnu_ops.to_fetch_registers = gnu_fetch_registers; /* to_fetch_registers */ + gnu_ops.to_store_registers = gnu_store_registers; /* to_store_registers */ + gnu_ops.to_prepare_to_store = gnu_prepare_to_store; /* to_prepare_to_store */ + gnu_ops.to_xfer_memory = gnu_xfer_memory; /* to_xfer_memory */ + gnu_ops.to_find_memory_regions = gnu_find_memory_regions; + gnu_ops.to_insert_breakpoint = memory_insert_breakpoint; + gnu_ops.to_remove_breakpoint = memory_remove_breakpoint; + gnu_ops.to_terminal_init = gnu_terminal_init_inferior; + gnu_ops.to_terminal_inferior = terminal_inferior; + gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output; + gnu_ops.to_terminal_save_ours = terminal_save_ours; + gnu_ops.to_terminal_ours = terminal_ours; + gnu_ops.to_terminal_info = child_terminal_info; + gnu_ops.to_kill = gnu_kill_inferior; /* to_kill */ + gnu_ops.to_create_inferior = gnu_create_inferior; /* to_create_inferior */ + gnu_ops.to_mourn_inferior = gnu_mourn_inferior; /* to_mourn_inferior */ + gnu_ops.to_can_run = gnu_can_run; /* to_can_run */ + gnu_ops.to_thread_alive = gnu_thread_alive; /* to_thread_alive */ + gnu_ops.to_pid_to_str = gnu_pid_to_str; /* to_pid_to_str */ + gnu_ops.to_stop = gnu_stop; /* to_stop */ + gnu_ops.to_pid_to_exec_file = gnu_pid_to_exec_file; /* to_pid_to_exec_file */ + gnu_ops.to_stratum = process_stratum; /* to_stratum */ + gnu_ops.to_has_all_memory = 1; /* to_has_all_memory */ + gnu_ops.to_has_memory = 1; /* to_has_memory */ + gnu_ops.to_has_stack = 1; /* to_has_stack */ + gnu_ops.to_has_registers = 1; /* to_has_registers */ + gnu_ops.to_has_execution = 1; /* to_has_execution */ + gnu_ops.to_magic = OPS_MAGIC; /* to_magic */ +} /* init_gnu_ops */ + + +/* User task commands. */ + +struct cmd_list_element *set_task_cmd_list = 0; +struct cmd_list_element *show_task_cmd_list = 0; +/* User thread commands. */ + +/* Commands with a prefix of `set/show thread'. */ +extern struct cmd_list_element *thread_cmd_list; +struct cmd_list_element *set_thread_cmd_list = NULL; +struct cmd_list_element *show_thread_cmd_list = NULL; + +/* Commands with a prefix of `set/show thread default'. */ +struct cmd_list_element *set_thread_default_cmd_list = NULL; +struct cmd_list_element *show_thread_default_cmd_list = NULL; + +static void +set_thread_cmd (char *args, int from_tty) +{ + printf_unfiltered ("\"set thread\" must be followed by the name of a thread property, or \"default\".\n"); +} + +static void +show_thread_cmd (char *args, int from_tty) +{ + printf_unfiltered ("\"show thread\" must be followed by the name of a thread property, or \"default\".\n"); +} + +static void +set_thread_default_cmd (char *args, int from_tty) +{ + printf_unfiltered ("\"set thread default\" must be followed by the name of a thread property.\n"); +} + +static void +show_thread_default_cmd (char *args, int from_tty) +{ + printf_unfiltered ("\"show thread default\" must be followed by the name of a thread property.\n"); +} + +static int +parse_int_arg (char *args, char *cmd_prefix) +{ + if (args) + { + char *arg_end; + int val = strtoul (args, &arg_end, 10); + if (*args && *arg_end == '\0') + return val; + } + error ("Illegal argument for \"%s\" command, should be an integer.", cmd_prefix); +} + +static int +_parse_bool_arg (char *args, char *t_val, char *f_val, char *cmd_prefix) +{ + if (!args || strcmp (args, t_val) == 0) + return 1; + else if (strcmp (args, f_val) == 0) + return 0; + else + error ("Illegal argument for \"%s\" command, should be \"%s\" or \"%s\".", + cmd_prefix, t_val, f_val); +} + +#define parse_bool_arg(args, cmd_prefix) \ + _parse_bool_arg (args, "on", "off", cmd_prefix) + +static void +check_empty (char *args, char *cmd_prefix) +{ + if (args) + error ("Garbage after \"%s\" command: `%s'", cmd_prefix, args); +} + +/* Returns the alive thread named by INFERIOR_PID, or signals an error. */ +static struct proc * +cur_thread (void) +{ + struct inf *inf = cur_inf (); + struct proc *thread = inf_tid_to_thread (inf, PIDGET (inferior_ptid)); + if (!thread) + error ("No current thread."); + return thread; +} + +/* Returns the current inferior, but signals an error if it has no task. */ +static struct inf * +active_inf (void) +{ + struct inf *inf = cur_inf (); + if (!inf->task) + error ("No current process."); + return inf; +} + + +static void +set_task_pause_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + int old_sc = inf->pause_sc; + + inf->pause_sc = parse_bool_arg (args, "set task pause"); + + if (old_sc == 0 && inf->pause_sc != 0) + /* If the task is currently unsuspended, immediately suspend it, + otherwise wait until the next time it gets control. */ + inf_suspend (inf); +} + +static void +show_task_pause_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + check_empty (args, "show task pause"); + printf_unfiltered ("The inferior task %s suspended while gdb has control.\n", + inf->task + ? (inf->pause_sc == 0 ? "isn't" : "is") + : (inf->pause_sc == 0 ? "won't be" : "will be")); +} + +static void +set_task_detach_sc_cmd (char *args, int from_tty) +{ + cur_inf ()->detach_sc = parse_int_arg (args, "set task detach-suspend-count"); +} + +static void +show_task_detach_sc_cmd (char *args, int from_tty) +{ + check_empty (args, "show task detach-suspend-count"); + printf_unfiltered ("The inferior task will be left with a suspend count of %d when detaching.\n", + cur_inf ()->detach_sc); +} + + +static void +set_thread_default_pause_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + inf->default_thread_pause_sc = + parse_bool_arg (args, "set thread default pause") ? 0 : 1; +} + +static void +show_thread_default_pause_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + int sc = inf->default_thread_pause_sc; + check_empty (args, "show thread default pause"); + printf_unfiltered ("New threads %s suspended while gdb has control%s.\n", + sc ? "are" : "aren't", + !sc && inf->pause_sc ? " (but the task is)" : ""); +} + +static void +set_thread_default_run_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + inf->default_thread_run_sc = + parse_bool_arg (args, "set thread default run") ? 0 : 1; +} + +static void +show_thread_default_run_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + check_empty (args, "show thread default run"); + printf_unfiltered ("New threads %s allowed to run.\n", + inf->default_thread_run_sc == 0 ? "are" : "aren't"); +} + +static void +set_thread_default_detach_sc_cmd (char *args, int from_tty) +{ + cur_inf ()->default_thread_detach_sc = + parse_int_arg (args, "set thread default detach-suspend-count"); +} + +static void +show_thread_default_detach_sc_cmd (char *args, int from_tty) +{ + check_empty (args, "show thread default detach-suspend-count"); + printf_unfiltered ("New threads will get a detach-suspend-count of %d.\n", + cur_inf ()->default_thread_detach_sc); +} + + +/* Steal a send right called NAME in the inferior task, and make it PROC's + saved exception port. */ +static void +steal_exc_port (struct proc *proc, mach_port_t name) +{ + error_t err; + mach_port_t port; + mach_msg_type_name_t port_type; + + if (!proc || !proc->inf->task) + error ("No inferior task."); + + err = mach_port_extract_right (proc->inf->task->port, + name, MACH_MSG_TYPE_COPY_SEND, + &port, &port_type); + if (err) + error ("Couldn't extract send right %d from inferior: %s", + name, safe_strerror (err)); + + if (proc->saved_exc_port) + /* Get rid of our reference to the old one. */ + mach_port_deallocate (mach_task_self (), proc->saved_exc_port); + + proc->saved_exc_port = port; + + if (!proc->exc_port) + /* If PROC is a thread, we may not have set its exception port before. + We can't use proc_steal_exc_port because it also sets saved_exc_port. */ + { + proc->exc_port = proc->inf->event_port; + err = proc_set_exception_port (proc, proc->exc_port); + error ("Can't set exception port for %s: %s", + proc_string (proc), safe_strerror (err)); + } +} + +static void +set_task_exc_port_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + if (!args) + error ("No argument to \"set task exception-port\" command."); + steal_exc_port (inf->task, parse_and_eval_address (args)); +} + +static void +set_stopped_cmd (char *args, int from_tty) +{ + cur_inf ()->stopped = _parse_bool_arg (args, "yes", "no", "set stopped"); +} + +static void +show_stopped_cmd (char *args, int from_tty) +{ + struct inf *inf = active_inf (); + check_empty (args, "show stopped"); + printf_unfiltered ("The inferior process %s stopped.\n", + inf->stopped ? "is" : "isn't"); +} + +static void +set_sig_thread_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + + if (!args || (!isdigit (*args) && strcmp (args, "none") != 0)) + error ("Illegal argument to \"set signal-thread\" command.\n" + "Should be an integer thread ID, or `none'."); + + if (strcmp (args, "none") == 0) + inf->signal_thread = 0; + else + { + int tid = PIDGET (thread_id_to_pid (atoi (args))); + if (tid < 0) + error ("Thread ID %s not known. Use the \"info threads\" command to\n" + "see the IDs of currently known threads.", args); + inf->signal_thread = inf_tid_to_thread (inf, tid); + } +} + +static void +show_sig_thread_cmd (char *args, int from_tty) +{ + struct inf *inf = active_inf (); + check_empty (args, "show signal-thread"); + if (inf->signal_thread) + printf_unfiltered ("The signal thread is %s.\n", + proc_string (inf->signal_thread)); + else + printf_unfiltered ("There is no signal thread.\n"); +} + + +static void +set_signals_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + + inf->want_signals = parse_bool_arg (args, "set signals"); + + if (inf->task && inf->want_signals != inf->traced) + /* Make this take effect immediately in a running process. */ + inf_set_traced (inf, inf->want_signals); +} + +static void +show_signals_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + check_empty (args, "show signals"); + printf_unfiltered ("The inferior process's signals %s intercepted.\n", + inf->task + ? (inf->traced ? "are" : "aren't") + : (inf->want_signals ? "will be" : "won't be")); +} + +static void +set_exceptions_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + int val = parse_bool_arg (args, "set exceptions"); + + if (inf->task && inf->want_exceptions != val) + /* Make this take effect immediately in a running process. */ + /* XXX */ ; + + inf->want_exceptions = val; +} + +static void +show_exceptions_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + check_empty (args, "show exceptions"); + printf_unfiltered ("Exceptions in the inferior %s trapped.\n", + inf->task + ? (inf->want_exceptions ? "are" : "aren't") + : (inf->want_exceptions ? "will be" : "won't be")); +} + + +static void +set_task_cmd (char *args, int from_tty) +{ + printf_unfiltered ("\"set task\" must be followed by the name" + " of a task property.\n"); +} + +static void +show_task_cmd (char *args, int from_tty) +{ + struct inf *inf = cur_inf (); + + check_empty (args, "show task"); + + show_signals_cmd (0, from_tty); + show_exceptions_cmd (0, from_tty); + show_task_pause_cmd (0, from_tty); + + if (inf->pause_sc == 0) + show_thread_default_pause_cmd (0, from_tty); + show_thread_default_run_cmd (0, from_tty); + + if (inf->task) + { + show_stopped_cmd (0, from_tty); + show_sig_thread_cmd (0, from_tty); + } + + if (inf->detach_sc != 0) + show_task_detach_sc_cmd (0, from_tty); + if (inf->default_thread_detach_sc != 0) + show_thread_default_detach_sc_cmd (0, from_tty); +} + + +static void +set_noninvasive_cmd (char *args, int from_tty) +{ + /* Invert the sense of the arg for each component. */ + char *inv_args = parse_bool_arg (args, "set noninvasive") ? "off" : "on"; + + set_task_pause_cmd (inv_args, from_tty); + set_signals_cmd (inv_args, from_tty); + set_exceptions_cmd (inv_args, from_tty); +} + + +static void +info_port_rights (char *args, mach_port_type_t only) +{ + struct inf *inf = active_inf (); + struct value *vmark = value_mark (); + + if (args) + /* Explicit list of port rights. */ + { + while (*args) + { + struct value *val = parse_to_comma_and_eval (&args); + long right = value_as_long (val); + error_t err = + print_port_info (right, 0, inf->task->port, PORTINFO_DETAILS, + stdout); + if (err) + error ("%ld: %s.", right, safe_strerror (err)); + } + } + else + /* Print all of them. */ + { + error_t err = + print_task_ports_info (inf->task->port, only, PORTINFO_DETAILS, + stdout); + if (err) + error ("%s.", safe_strerror (err)); + } + + value_free_to_mark (vmark); +} + +static void +info_send_rights_cmd (char *args, int from_tty) +{ + info_port_rights (args, MACH_PORT_TYPE_SEND); +} + +static void +info_recv_rights_cmd (char *args, int from_tty) +{ + info_port_rights (args, MACH_PORT_TYPE_RECEIVE); +} + +static void +info_port_sets_cmd (char *args, int from_tty) +{ + info_port_rights (args, MACH_PORT_TYPE_PORT_SET); +} + +static void +info_dead_names_cmd (char *args, int from_tty) +{ + info_port_rights (args, MACH_PORT_TYPE_DEAD_NAME); +} + +static void +info_port_rights_cmd (char *args, int from_tty) +{ + info_port_rights (args, ~0); +} + + +static void +add_task_commands (void) +{ + add_cmd ("pause", class_run, set_thread_default_pause_cmd, + "Set whether the new threads are suspended while gdb has control.\n\ +This property normally has no effect because the whole task is\n\ +suspended, however, that may be disabled with \"set task pause off\".\n\ +The default value is \"off\".", + &set_thread_default_cmd_list); + add_cmd ("pause", no_class, show_thread_default_pause_cmd, + "Show whether new threads are suspended while gdb has control.", + &show_thread_default_cmd_list); + + add_cmd ("run", class_run, set_thread_default_run_cmd, + "Set whether new threads are allowed to run \ +(once gdb has noticed them).", + &set_thread_default_cmd_list); + add_cmd ("run", no_class, show_thread_default_run_cmd, + "Show whether new threads are allowed to run \ +(once gdb has noticed them).", + &show_thread_default_cmd_list); + + add_cmd ("detach-suspend-count", class_run, set_thread_default_detach_sc_cmd, + "Set the default detach-suspend-count value for new threads.", + &set_thread_default_cmd_list); + add_cmd ("detach-suspend-count", no_class, show_thread_default_detach_sc_cmd, + "Show the default detach-suspend-count value for new threads.", + &show_thread_default_cmd_list); + + add_cmd ("signals", class_run, set_signals_cmd, + "Set whether the inferior process's signals will be intercepted.\n\ +Mach exceptions (such as breakpoint traps) are not affected.", + &setlist); + add_alias_cmd ("sigs", "signals", class_run, 1, &setlist); + add_cmd ("signals", no_class, show_signals_cmd, + "Show whether the inferior process's signals will be intercepted.", + &showlist); + add_alias_cmd ("sigs", "signals", no_class, 1, &showlist); + + add_cmd ("signal-thread", class_run, set_sig_thread_cmd, + "Set the thread that gdb thinks is the libc signal thread.\n\ +This thread is run when delivering a signal to a non-stopped process.", + &setlist); + add_alias_cmd ("sigthread", "signal-thread", class_run, 1, &setlist); + add_cmd ("signal-thread", no_class, show_sig_thread_cmd, + "Set the thread that gdb thinks is the libc signal thread.", + &showlist); + add_alias_cmd ("sigthread", "signal-thread", no_class, 1, &showlist); + + add_cmd ("stopped", class_run, set_stopped_cmd, + "Set whether gdb thinks the inferior process is stopped \ +as with SIGSTOP.\n\ +Stopped process will be continued by sending them a signal.", + &setlist); + add_cmd ("stopped", no_class, show_signals_cmd, + "Show whether gdb thinks the inferior process is stopped \ +as with SIGSTOP.", + &showlist); + + add_cmd ("exceptions", class_run, set_exceptions_cmd, + "Set whether exceptions in the inferior process will be trapped.\n\ +When exceptions are turned off, neither breakpoints nor single-stepping\n\ +will work.", + &setlist); + /* Allow `set exc' despite conflict with `set exception-port'. */ + add_alias_cmd ("exc", "exceptions", class_run, 1, &setlist); + add_cmd ("exceptions", no_class, show_exceptions_cmd, + "Show whether exceptions in the inferior process will be trapped.", + &showlist); + + add_prefix_cmd ("task", no_class, set_task_cmd, + "Command prefix for setting task attributes.", + &set_task_cmd_list, "set task ", 0, &setlist); + add_prefix_cmd ("task", no_class, show_task_cmd, + "Command prefix for showing task attributes.", + &show_task_cmd_list, "show task ", 0, &showlist); + + add_cmd ("pause", class_run, set_task_pause_cmd, + "Set whether the task is suspended while gdb has control.\n\ +A value of \"on\" takes effect immediately, otherwise nothing happens\n\ +until the next time the program is continued.\n\ +When setting this to \"off\", \"set thread default pause on\" can be\n\ +used to pause individual threads by default instead.", + &set_task_cmd_list); + add_cmd ("pause", no_class, show_task_pause_cmd, + "Show whether the task is suspended while gdb has control.", + &show_task_cmd_list); + + add_cmd ("detach-suspend-count", class_run, set_task_detach_sc_cmd, + "Set the suspend count will leave on the thread when detaching.", + &set_task_cmd_list); + add_cmd ("detach-suspend-count", no_class, show_task_detach_sc_cmd, + "Show the suspend count will leave on the thread when detaching.", + &show_task_cmd_list); + + add_cmd ("exception-port", no_class, set_task_exc_port_cmd, + "Set the task exception port to which we forward exceptions.\n\ +The argument should be the value of the send right in the task.", + &set_task_cmd_list); + add_alias_cmd ("excp", "exception-port", no_class, 1, &set_task_cmd_list); + add_alias_cmd ("exc-port", "exception-port", no_class, 1, + &set_task_cmd_list); + + /* A convenient way of turning on all options require to noninvasively + debug running tasks. */ + add_cmd ("noninvasive", no_class, set_noninvasive_cmd, + "Set task options so that we interfere as little as possible.\n\ +This is the same as setting `task pause', `exceptions', and\n\ +`signals' to the opposite value.", + &setlist); + + /* Commands to show information about the task's ports. */ + add_cmd ("send-rights", class_info, info_send_rights_cmd, + "Show information about the task's send rights", + &infolist); + add_cmd ("receive-rights", class_info, info_recv_rights_cmd, + "Show information about the task's receive rights", + &infolist); + add_cmd ("port-rights", class_info, info_port_rights_cmd, + "Show information about the task's port rights", + &infolist); + add_cmd ("port-sets", class_info, info_port_sets_cmd, + "Show information about the task's port sets", + &infolist); + add_cmd ("dead-names", class_info, info_dead_names_cmd, + "Show information about the task's dead names", + &infolist); + add_info_alias ("ports", "port-rights", 1); + add_info_alias ("port", "port-rights", 1); + add_info_alias ("psets", "port-sets", 1); +} + + +static void +set_thread_pause_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + int old_sc = thread->pause_sc; + thread->pause_sc = parse_bool_arg (args, "set thread pause"); + if (old_sc == 0 && thread->pause_sc != 0 && thread->inf->pause_sc == 0) + /* If the task is currently unsuspended, immediately suspend it, + otherwise wait until the next time it gets control. */ + inf_suspend (thread->inf); +} + +static void +show_thread_pause_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + int sc = thread->pause_sc; + check_empty (args, "show task pause"); + printf_unfiltered ("Thread %s %s suspended while gdb has control%s.\n", + proc_string (thread), + sc ? "is" : "isn't", + !sc && thread->inf->pause_sc ? " (but the task is)" : ""); +} + +static void +set_thread_run_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + thread->run_sc = parse_bool_arg (args, "set thread run") ? 0 : 1; +} + +static void +show_thread_run_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + check_empty (args, "show thread run"); + printf_unfiltered ("Thread %s %s allowed to run.", + proc_string (thread), + thread->run_sc == 0 ? "is" : "isn't"); +} + +static void +set_thread_detach_sc_cmd (char *args, int from_tty) +{ + cur_thread ()->detach_sc = parse_int_arg (args, + "set thread detach-suspend-count"); +} + +static void +show_thread_detach_sc_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + check_empty (args, "show thread detach-suspend-count"); + printf_unfiltered ("Thread %s will be left with a suspend count" + " of %d when detaching.\n", + proc_string (thread), + thread->detach_sc); +} + +static void +set_thread_exc_port_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + if (!args) + error ("No argument to \"set thread exception-port\" command."); + steal_exc_port (thread, parse_and_eval_address (args)); +} + +#if 0 +static void +show_thread_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + check_empty (args, "show thread"); + show_thread_run_cmd (0, from_tty); + show_thread_pause_cmd (0, from_tty); + if (thread->detach_sc != 0) + show_thread_detach_sc_cmd (0, from_tty); +} +#endif + +static void +thread_takeover_sc_cmd (char *args, int from_tty) +{ + struct proc *thread = cur_thread (); + thread_basic_info_data_t _info; + thread_basic_info_t info = &_info; + mach_msg_type_number_t info_len = THREAD_BASIC_INFO_COUNT; + error_t err = + thread_info (thread->port, THREAD_BASIC_INFO, (int *) &info, &info_len); + if (err) + error ("%s.", safe_strerror (err)); + thread->sc = info->suspend_count; + if (from_tty) + printf_unfiltered ("Suspend count was %d.\n", thread->sc); + if (info != &_info) + vm_deallocate (mach_task_self (), (vm_address_t) info, + info_len * sizeof (int)); +} + + +static void +add_thread_commands (void) +{ + add_prefix_cmd ("thread", no_class, set_thread_cmd, + "Command prefix for setting thread properties.", + &set_thread_cmd_list, "set thread ", 0, &setlist); + add_prefix_cmd ("default", no_class, show_thread_cmd, + "Command prefix for setting default thread properties.", + &set_thread_default_cmd_list, "set thread default ", 0, + &set_thread_cmd_list); + add_prefix_cmd ("thread", no_class, set_thread_default_cmd, + "Command prefix for showing thread properties.", + &show_thread_cmd_list, "show thread ", 0, &showlist); + add_prefix_cmd ("default", no_class, show_thread_default_cmd, + "Command prefix for showing default thread properties.", + &show_thread_default_cmd_list, "show thread default ", 0, + &show_thread_cmd_list); + + add_cmd ("pause", class_run, set_thread_pause_cmd, + "Set whether the current thread is suspended \ +while gdb has control.\n\ +A value of \"on\" takes effect immediately, otherwise nothing happens\n\ +until the next time the program is continued. This property normally\n\ +has no effect because the whole task is suspended, however, that may\n\ +be disabled with \"set task pause off\".\n\ +The default value is \"off\".", + &set_thread_cmd_list); + add_cmd ("pause", no_class, show_thread_pause_cmd, + "Show whether the current thread is suspended \ +while gdb has control.", + &show_thread_cmd_list); + + add_cmd ("run", class_run, set_thread_run_cmd, + "Set whether the current thread is allowed to run.", + &set_thread_cmd_list); + add_cmd ("run", no_class, show_thread_run_cmd, + "Show whether the current thread is allowed to run.", + &show_thread_cmd_list); + + add_cmd ("detach-suspend-count", class_run, set_thread_detach_sc_cmd, + "Set the suspend count will leave on the thread when detaching.\n\ +Note that this is relative to suspend count when gdb noticed the thread;\n\ +use the `thread takeover-suspend-count' to force it to an absolute value.", + &set_thread_cmd_list); + add_cmd ("detach-suspend-count", no_class, show_thread_detach_sc_cmd, + "Show the suspend count will leave on the thread when detaching.\n\ +Note that this is relative to suspend count when gdb noticed the thread;\n\ +use the `thread takeover-suspend-count' to force it to an absolute value.", + &show_thread_cmd_list); + + add_cmd ("exception-port", no_class, set_thread_exc_port_cmd, + "Set the thread exception port to which we forward exceptions.\n\ +This overrides the task exception port.\n\ +The argument should be the value of the send right in the task.", + &set_thread_cmd_list); + add_alias_cmd ("excp", "exception-port", no_class, 1, &set_thread_cmd_list); + add_alias_cmd ("exc-port", "exception-port", no_class, 1, + &set_thread_cmd_list); + + add_cmd ("takeover-suspend-count", no_class, thread_takeover_sc_cmd, + "Force the threads absolute suspend-count to be gdb's.\n\ +Prior to giving this command, gdb's thread suspend-counts are relative\n\ +to the thread's initial suspend-count when gdb notices the threads.", + &thread_cmd_list); +} + + +void +_initialize_gnu_nat (void) +{ + proc_server = getproc (); + + init_gnu_ops (); + add_target (&gnu_ops); + + add_task_commands (); + add_thread_commands (); + add_set_cmd ("gnu-debug", class_maintenance, + var_boolean, (char *) &gnu_debug_flag, + "Set debugging output for the gnu backend.", &maintenancelist); +} + +#ifdef FLUSH_INFERIOR_CACHE + +/* When over-writing code on some machines the I-Cache must be flushed + explicitly, because it is not kept coherent by the lazy hardware. + This definitely includes breakpoints, for instance, or else we + end up looping in mysterious Bpt traps */ + +void +flush_inferior_icache (CORE_ADDR pc, int amount) +{ + vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH; + error_t ret; + + ret = vm_machine_attribute (current_inferior->task->port, + pc, + amount, + MATTR_CACHE, + &flush); + if (ret != KERN_SUCCESS) + warning ("Error flushing inferior's cache : %s", safe_strerror (ret)); +} +#endif /* FLUSH_INFERIOR_CACHE */ diff --git a/contrib/gdb/gdb/gnu-nat.h b/contrib/gdb/gdb/gnu-nat.h new file mode 100644 index 00000000000..bcdfe6e7779 --- /dev/null +++ b/contrib/gdb/gdb/gnu-nat.h @@ -0,0 +1,101 @@ +/* Common things used by the various *gnu-nat.c files + Copyright 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. + + Written by Miles Bader + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef __GNU_NAT_H__ +#define __GNU_NAT_H__ + +#include +#include + +struct inf; + +extern struct inf *current_inferior; + +/* Converts a GDB pid to a struct proc. */ +struct proc *inf_tid_to_thread (struct inf *inf, int tid); + +/* Makes sure that INF's thread list is synced with the actual process. */ +int inf_update_procs (struct inf *inf); + +/* A proc is either a thread, or the task (there can only be one task proc + because it always has the same TID, PROC_TID_TASK). */ +struct proc + { + thread_t port; /* The task or thread port. */ + int tid; /* The GDB pid (actually a thread id). */ + int num; /* An id number for threads, to print. */ + + mach_port_t saved_exc_port; /* The task/thread's real exception port. */ + mach_port_t exc_port; /* Our replacement, which for. */ + + int sc; /* Desired suspend count. */ + int cur_sc; /* Implemented suspend count. */ + int run_sc; /* Default sc when the program is running. */ + int pause_sc; /* Default sc when gdb has control. */ + int resume_sc; /* Sc resulting from the last resume. */ + int detach_sc; /* SC to leave around when detaching + from program. */ + + thread_state_data_t state; /* Registers, &c. */ + int state_valid:1; /* True if STATE is up to date. */ + int state_changed:1; + + int aborted:1; /* True if thread_abort has been called. */ + int dead:1; /* We happen to know it's actually dead. */ + + /* Bit mask of registers fetched by gdb. This is used when we re-fetch + STATE after aborting the thread, to detect that gdb may have out-of-date + information. */ + unsigned long fetched_regs; + + struct inf *inf; /* Where we come from. */ + + struct proc *next; + }; + +/* The task has a thread entry with this TID. */ +#define PROC_TID_TASK (-1) + +#define proc_is_task(proc) ((proc)->tid == PROC_TID_TASK) +#define proc_is_thread(proc) ((proc)->tid != PROC_TID_TASK) + +extern int __proc_pid (struct proc *proc); + +/* Make sure that the state field in PROC is up to date, and return a + pointer to it, or 0 if something is wrong. If WILL_MODIFY is true, + makes sure that the thread is stopped and aborted first, and sets + the state_changed field in PROC to true. */ +extern thread_state_t proc_get_state (struct proc *proc, int will_modify); + +/* Return printable description of proc. */ +extern char *proc_string (struct proc *proc); + +#define proc_debug(_proc, msg, args...) \ + do { struct proc *__proc = (_proc); \ + debug ("{proc %d/%d %p}: " msg, \ + __proc_pid (__proc), __proc->tid, __proc , ##args); } while (0) + +extern int gnu_debug_flag; + +#define debug(msg, args...) \ + do { if (gnu_debug_flag) \ + fprintf_unfiltered (gdb_stdlog, "%s:%d: " msg "\r\n", __FILE__ , __LINE__ , ##args); } while (0) + +#endif /* __GNU_NAT_H__ */ diff --git a/contrib/gdb/gdb/gnu-v2-abi.c b/contrib/gdb/gdb/gnu-v2-abi.c index 2b086c57f5e..8cb2a7e4494 100644 --- a/contrib/gdb/gdb/gnu-v2-abi.c +++ b/contrib/gdb/gdb/gnu-v2-abi.c @@ -1,6 +1,8 @@ /* Abstraction of GNU v2 abi. + + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + Contributed by Daniel Berlin - Copyright 2001 Free Software Foundation, Inc. This file is part of GDB. @@ -28,6 +30,7 @@ #include "value.h" #include "demangle.h" #include "cp-abi.h" +#include "cp-support.h" #include @@ -182,14 +185,13 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j, } -struct type * +static struct type * gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) { struct type *known_type; struct type *rtti_type; CORE_ADDR coreptr; struct value *vp; - int using_enclosing = 0; long top_offset = 0; char rtti_type_name[256]; CORE_ADDR vtbl; @@ -244,30 +246,12 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0) return NULL; - /* - If we are enclosed by something that isn't us, adjust the - address properly and set using_enclosing. - */ - if (VALUE_ENCLOSING_TYPE(v) != VALUE_TYPE(v)) - { - struct value *tempval; - int bitpos = TYPE_BASECLASS_BITPOS (known_type, - TYPE_VPTR_FIELDNO (known_type)); - tempval=value_field (v, TYPE_VPTR_FIELDNO(known_type)); - VALUE_ADDRESS(tempval) += bitpos / 8; - vtbl=value_as_address (tempval); - using_enclosing=1; - } - else - { - vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type))); - using_enclosing=0; - } + vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type))); /* Try to find a symbol that is the vtable */ minsym=lookup_minimal_symbol_by_pc(vtbl); if (minsym==NULL - || (demangled_name=SYMBOL_NAME(minsym))==NULL + || (demangled_name=DEPRECATED_SYMBOL_NAME (minsym))==NULL || !is_vtable_name (demangled_name)) return NULL; @@ -276,9 +260,9 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) *(strchr(demangled_name,' '))=0; /* Lookup the type for the name */ - rtti_type=lookup_typename(demangled_name, (struct block *)0,1); - - if (rtti_type==NULL) + /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ + rtti_type = cp_lookup_rtti_type (demangled_name, NULL); + if (rtti_type == NULL) return NULL; if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1) @@ -304,8 +288,6 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) if (full) *full=1; } - if (using_enc) - *using_enc=using_enclosing; return rtti_type; } @@ -350,8 +332,8 @@ vb_match (struct type *type, int index, struct type *basetype) if (TYPE_NAME (basetype) != NULL && TYPE_NAME (TYPE_TARGET_TYPE (fieldtype)) != NULL - && STREQ (TYPE_NAME (basetype), - TYPE_NAME (TYPE_TARGET_TYPE (fieldtype)))) + && strcmp (TYPE_NAME (basetype), + TYPE_NAME (TYPE_TARGET_TYPE (fieldtype))) == 0) return 1; return 0; } @@ -373,8 +355,8 @@ gnuv2_baseclass_offset (struct type *type, int index, char *valaddr, if (BASETYPE_VIA_VIRTUAL (type, index)) { /* Must hunt for the pointer to this virtual baseclass. */ - register int i, len = TYPE_NFIELDS (type); - register int n_baseclasses = TYPE_N_BASECLASSES (type); + int i, len = TYPE_NFIELDS (type); + int n_baseclasses = TYPE_N_BASECLASSES (type); /* First look for the virtual baseclass pointer in the fields. */ @@ -420,10 +402,12 @@ init_gnuv2_ops (void) gnu_v2_abi_ops.baseclass_offset = gnuv2_baseclass_offset; } +extern initialize_file_ftype _initialize_gnu_v2_abi; /* -Wmissing-prototypes */ + void _initialize_gnu_v2_abi (void) { init_gnuv2_ops (); - register_cp_abi (gnu_v2_abi_ops); - switch_to_cp_abi ("gnu-v2"); + register_cp_abi (&gnu_v2_abi_ops); + set_cp_abi_as_auto_default (gnu_v2_abi_ops.shortname); } diff --git a/contrib/gdb/gdb/gnu-v3-abi.c b/contrib/gdb/gdb/gnu-v3-abi.c index ae2104d59c4..0fbdd6eefbf 100644 --- a/contrib/gdb/gdb/gnu-v3-abi.c +++ b/contrib/gdb/gdb/gnu-v3-abi.c @@ -1,6 +1,7 @@ /* Abstraction of GNU v3 abi. Contributed by Jim Blandy - Copyright 2001 Free Software Foundation, Inc. + + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -22,8 +23,10 @@ #include "defs.h" #include "value.h" #include "cp-abi.h" +#include "cp-support.h" #include "demangle.h" #include "gdb_assert.h" +#include "gdb_string.h" static struct cp_abi_ops gnu_v3_abi_ops; @@ -172,9 +175,10 @@ build_gdb_vtable_type (struct gdbarch *arch) gdb_gnu_v3_abi_vtable' object to the vtable's "address point" (i.e., where objects' virtual table pointers point). */ static int -vtable_address_point_offset () +vtable_address_point_offset (void) { - struct type *vtable_type = gdbarch_data (vtable_type_gdbarch_data); + struct type *vtable_type = gdbarch_data (current_gdbarch, + vtable_type_gdbarch_data); return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions) / TARGET_CHAR_BIT); @@ -185,14 +189,14 @@ static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { - struct type *vtable_type = gdbarch_data (vtable_type_gdbarch_data); + struct type *vtable_type = gdbarch_data (current_gdbarch, + vtable_type_gdbarch_data); struct type *value_type = check_typedef (VALUE_TYPE (value)); CORE_ADDR vtable_address; struct value *vtable; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; - struct symbol *class_symbol; struct type *run_time_type; struct type *base_type; LONGEST offset_to_top; @@ -241,25 +245,20 @@ gnuv3_rtti_type (struct value *value, vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol); if (vtable_symbol_name == NULL || strncmp (vtable_symbol_name, "vtable for ", 11)) - error ("can't find linker symbol for virtual table for `%s' value", - TYPE_NAME (value_type)); + { + warning ("can't find linker symbol for virtual table for `%s' value", + TYPE_NAME (value_type)); + if (vtable_symbol_name) + warning (" found `%s' instead", vtable_symbol_name); + return NULL; + } class_name = vtable_symbol_name + 11; /* Try to look up the class name as a type name. */ - class_symbol = lookup_symbol (class_name, 0, STRUCT_NAMESPACE, 0, 0); - if (! class_symbol) - error ("can't find class named `%s', as given by C++ RTTI", class_name); - - /* Make sure the type symbol is sane. (An earlier version of this - code would find constructor functions, who have the same name as - the class.) */ - if (SYMBOL_CLASS (class_symbol) != LOC_TYPEDEF - || TYPE_CODE (SYMBOL_TYPE (class_symbol)) != TYPE_CODE_CLASS) - error ("C++ RTTI gives a class name of `%s', but that isn't a type name", - class_name); - - /* This is the object's run-time type! */ - run_time_type = SYMBOL_TYPE (class_symbol); + /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ + run_time_type = cp_lookup_rtti_type (class_name, NULL); + if (run_time_type == NULL) + return NULL; /* Get the offset from VALUE to the top of the complete object. NOTE: this is the reverse of the meaning of *TOP_P. */ @@ -282,7 +281,8 @@ gnuv3_virtual_fn_field (struct value **value_p, struct fn_field *f, int j, struct type *type, int offset) { - struct type *vtable_type = gdbarch_data (vtable_type_gdbarch_data); + struct type *vtable_type = gdbarch_data (current_gdbarch, + vtable_type_gdbarch_data); struct value *value = *value_p; struct type *value_type = check_typedef (VALUE_TYPE (value)); struct type *vfn_base; @@ -308,6 +308,9 @@ gnuv3_virtual_fn_field (struct value **value_p, type now. */ if (TYPE_VPTR_FIELDNO (vfn_base) < 0) fill_in_vptr_fieldno (vfn_base); + if (TYPE_VPTR_FIELDNO (vfn_base) < 0) + error ("Could not find virtual table pointer for class \"%s\".", + TYPE_TAG_NAME (vfn_base) ? TYPE_TAG_NAME (vfn_base) : ""); /* Now that we know which base class is defining our virtual function, cast our value to that baseclass. This takes care of @@ -353,20 +356,17 @@ gnuv3_virtual_fn_field (struct value **value_p, to (the address of)(ARG) + OFFSET. -1 is returned on error. */ -int +static int gnuv3_baseclass_offset (struct type *type, int index, char *valaddr, CORE_ADDR address) { - struct type *vtable_type = gdbarch_data (vtable_type_gdbarch_data); - struct type *basetype = TYPE_BASECLASS (type, index); - struct value *full_object, *vbase_object, *orig_object; - struct value *vtable, *orig_typeinfo, *orig_base_info; - struct type *orig_type, *vbasetype; + struct type *vtable_type = gdbarch_data (current_gdbarch, + vtable_type_gdbarch_data); + struct value *vtable; + struct type *vbasetype; struct value *offset_val, *vbase_array; CORE_ADDR vtable_address; long int cur_base_offset, base_offset; - int to_top; - int baseclasses, i; /* If it isn't a virtual base, this is easy. The offset is in the type definition. */ @@ -389,15 +389,27 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr, / ((int) TYPE_LENGTH (builtin_type_void_data_ptr)); /* We're now looking for the cur_base_offset'th entry (negative index) - in the vcall_and_vbase_offsets array. */ + in the vcall_and_vbase_offsets array. We used to cast the object to + its TYPE_VPTR_BASETYPE, and reference the vtable as TYPE_VPTR_FIELDNO; + however, that cast can not be done without calling baseclass_offset again + if the TYPE_VPTR_BASETYPE is a virtual base class, as described in the + v3 C++ ABI Section 2.4.I.2.b. Fortunately the ABI guarantees that the + vtable pointer will be located at the beginning of the object, so we can + bypass the casting. Verify that the TYPE_VPTR_FIELDNO is in fact at the + start of whichever baseclass it resides in, as a sanity measure - iff + we have debugging information for that baseclass. */ - orig_object = value_at_lazy (type, address, NULL); - vbasetype = TYPE_VPTR_BASETYPE (VALUE_TYPE (orig_object)); - vbase_object = value_cast (vbasetype, orig_object); + vbasetype = TYPE_VPTR_BASETYPE (type); + if (TYPE_VPTR_FIELDNO (vbasetype) < 0) + fill_in_vptr_fieldno (vbasetype); - vtable_address - = value_as_address (value_field (vbase_object, - TYPE_VPTR_FIELDNO (vbasetype))); + if (TYPE_VPTR_FIELDNO (vbasetype) >= 0 + && TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0) + error ("Illegal vptr offset in class %s", + TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : ""); + + vtable_address = value_as_address (value_at_lazy (builtin_type_void_data_ptr, + address, NULL)); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset (), NULL); @@ -410,7 +422,7 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr, static void init_gnuv3_ops (void) { - vtable_type_gdbarch_data = register_gdbarch_data (build_gdb_vtable_type, 0); + vtable_type_gdbarch_data = register_gdbarch_data (build_gdb_vtable_type); gnu_v3_abi_ops.shortname = "gnu-v3"; gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI"; @@ -424,11 +436,12 @@ init_gnuv3_ops (void) gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset; } +extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */ void _initialize_gnu_v3_abi (void) { init_gnuv3_ops (); - register_cp_abi (gnu_v3_abi_ops); + register_cp_abi (&gnu_v3_abi_ops); } diff --git a/contrib/gdb/gdb/go32-nat.c b/contrib/gdb/gdb/go32-nat.c new file mode 100644 index 00000000000..0932ddb541c --- /dev/null +++ b/contrib/gdb/gdb/go32-nat.c @@ -0,0 +1,1963 @@ +/* Native debugging support for Intel x86 running DJGPP. + Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + Written by Robert Hoehne. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "defs.h" +#include "inferior.h" +#include "gdb_wait.h" +#include "gdbcore.h" +#include "command.h" +#include "gdbcmd.h" +#include "floatformat.h" +#include "buildsym.h" +#include "i387-tdep.h" +#include "i386-tdep.h" +#include "value.h" +#include "regcache.h" +#include "gdb_string.h" + +#include /* might be required for __DJGPP_MINOR__ */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if __DJGPP_MINOR__ > 2 +#include +#endif + +#if __DJGPP_MINOR__ < 3 +/* This code will be provided from DJGPP 2.03 on. Until then I code it + here */ +typedef struct + { + unsigned short sig0; + unsigned short sig1; + unsigned short sig2; + unsigned short sig3; + unsigned short exponent:15; + unsigned short sign:1; + } +NPXREG; + +typedef struct + { + unsigned int control; + unsigned int status; + unsigned int tag; + unsigned int eip; + unsigned int cs; + unsigned int dataptr; + unsigned int datasel; + NPXREG reg[8]; + } +NPX; + +static NPX npx; + +static void save_npx (void); /* Save the FPU of the debugged program */ +static void load_npx (void); /* Restore the FPU of the debugged program */ + +/* ------------------------------------------------------------------------- */ +/* Store the contents of the NPX in the global variable `npx'. */ +/* *INDENT-OFF* */ + +static void +save_npx (void) +{ + asm ("inb $0xa0, %%al \n\ + testb $0x20, %%al \n\ + jz 1f \n\ + xorb %%al, %%al \n\ + outb %%al, $0xf0 \n\ + movb $0x20, %%al \n\ + outb %%al, $0xa0 \n\ + outb %%al, $0x20 \n\ +1: \n\ + fnsave %0 \n\ + fwait " +: "=m" (npx) +: /* No input */ +: "%eax"); +} + +/* *INDENT-ON* */ + + +/* ------------------------------------------------------------------------- */ +/* Reload the contents of the NPX from the global variable `npx'. */ + +static void +load_npx (void) +{ + asm ("frstor %0":"=m" (npx)); +} +/* ------------------------------------------------------------------------- */ +/* Stubs for the missing redirection functions. */ +typedef struct { + char *command; + int redirected; +} cmdline_t; + +void +redir_cmdline_delete (cmdline_t *ptr) +{ + ptr->redirected = 0; +} + +int +redir_cmdline_parse (const char *args, cmdline_t *ptr) +{ + return -1; +} + +int +redir_to_child (cmdline_t *ptr) +{ + return 1; +} + +int +redir_to_debugger (cmdline_t *ptr) +{ + return 1; +} + +int +redir_debug_init (cmdline_t *ptr) +{ + return 0; +} +#endif /* __DJGPP_MINOR < 3 */ + +typedef enum { wp_insert, wp_remove, wp_count } wp_op; + +/* This holds the current reference counts for each debug register. */ +static int dr_ref_count[4]; + +#define SOME_PID 42 + +static int prog_has_started = 0; +static void go32_open (char *name, int from_tty); +static void go32_close (int quitting); +static void go32_attach (char *args, int from_tty); +static void go32_detach (char *args, int from_tty); +static void go32_resume (ptid_t ptid, int step, + enum target_signal siggnal); +static ptid_t go32_wait (ptid_t ptid, + struct target_waitstatus *status); +static void go32_fetch_registers (int regno); +static void store_register (int regno); +static void go32_store_registers (int regno); +static void go32_prepare_to_store (void); +static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, + struct mem_attrib *attrib, + struct target_ops *target); +static void go32_files_info (struct target_ops *target); +static void go32_stop (void); +static void go32_kill_inferior (void); +static void go32_create_inferior (char *exec_file, char *args, char **env); +static void go32_mourn_inferior (void); +static int go32_can_run (void); + +static struct target_ops go32_ops; +static void go32_terminal_init (void); +static void go32_terminal_inferior (void); +static void go32_terminal_ours (void); + +#define r_ofs(x) (offsetof(TSS,x)) + +static struct +{ + size_t tss_ofs; + size_t size; +} +regno_mapping[] = +{ + {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */ + {r_ofs (tss_ecx), 4}, + {r_ofs (tss_edx), 4}, + {r_ofs (tss_ebx), 4}, + {r_ofs (tss_esp), 4}, + {r_ofs (tss_ebp), 4}, + {r_ofs (tss_esi), 4}, + {r_ofs (tss_edi), 4}, + {r_ofs (tss_eip), 4}, + {r_ofs (tss_eflags), 4}, + {r_ofs (tss_cs), 2}, + {r_ofs (tss_ss), 2}, + {r_ofs (tss_ds), 2}, + {r_ofs (tss_es), 2}, + {r_ofs (tss_fs), 2}, + {r_ofs (tss_gs), 2}, + {0, 10}, /* 8 FP registers, from npx.reg[] */ + {1, 10}, + {2, 10}, + {3, 10}, + {4, 10}, + {5, 10}, + {6, 10}, + {7, 10}, + /* The order of the next 7 registers must be consistent + with their numbering in config/i386/tm-i386.h, which see. */ + {0, 2}, /* control word, from npx */ + {4, 2}, /* status word, from npx */ + {8, 2}, /* tag word, from npx */ + {16, 2}, /* last FP exception CS from npx */ + {12, 4}, /* last FP exception EIP from npx */ + {24, 2}, /* last FP exception operand selector from npx */ + {20, 4}, /* last FP exception operand offset from npx */ + {18, 2} /* last FP opcode from npx */ +}; + +static struct + { + int go32_sig; + enum target_signal gdb_sig; + } +sig_map[] = +{ + {0, TARGET_SIGNAL_FPE}, + {1, TARGET_SIGNAL_TRAP}, + /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL, + but I think SIGBUS is better, since the NMI is usually activated + as a result of a memory parity check failure. */ + {2, TARGET_SIGNAL_BUS}, + {3, TARGET_SIGNAL_TRAP}, + {4, TARGET_SIGNAL_FPE}, + {5, TARGET_SIGNAL_SEGV}, + {6, TARGET_SIGNAL_ILL}, + {7, TARGET_SIGNAL_EMT}, /* no-coprocessor exception */ + {8, TARGET_SIGNAL_SEGV}, + {9, TARGET_SIGNAL_SEGV}, + {10, TARGET_SIGNAL_BUS}, + {11, TARGET_SIGNAL_SEGV}, + {12, TARGET_SIGNAL_SEGV}, + {13, TARGET_SIGNAL_SEGV}, + {14, TARGET_SIGNAL_SEGV}, + {16, TARGET_SIGNAL_FPE}, + {17, TARGET_SIGNAL_BUS}, + {31, TARGET_SIGNAL_ILL}, + {0x1b, TARGET_SIGNAL_INT}, + {0x75, TARGET_SIGNAL_FPE}, + {0x78, TARGET_SIGNAL_ALRM}, + {0x79, TARGET_SIGNAL_INT}, + {0x7a, TARGET_SIGNAL_QUIT}, + {-1, TARGET_SIGNAL_LAST} +}; + +static struct { + enum target_signal gdb_sig; + int djgpp_excepno; +} excepn_map[] = { + {TARGET_SIGNAL_0, -1}, + {TARGET_SIGNAL_ILL, 6}, /* Invalid Opcode */ + {TARGET_SIGNAL_EMT, 7}, /* triggers SIGNOFP */ + {TARGET_SIGNAL_SEGV, 13}, /* GPF */ + {TARGET_SIGNAL_BUS, 17}, /* Alignment Check */ + /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for + details. */ + {TARGET_SIGNAL_TERM, 0x1b}, /* triggers Ctrl-Break type of SIGINT */ + {TARGET_SIGNAL_FPE, 0x75}, + {TARGET_SIGNAL_INT, 0x79}, + {TARGET_SIGNAL_QUIT, 0x7a}, + {TARGET_SIGNAL_ALRM, 0x78}, /* triggers SIGTIMR */ + {TARGET_SIGNAL_PROF, 0x78}, + {TARGET_SIGNAL_LAST, -1} +}; + +static void +go32_open (char *name, int from_tty) +{ + printf_unfiltered ("Done. Use the \"run\" command to run the program.\n"); +} + +static void +go32_close (int quitting) +{ +} + +static void +go32_attach (char *args, int from_tty) +{ + error ("\ +You cannot attach to a running program on this platform.\n\ +Use the `run' command to run DJGPP programs."); +} + +static void +go32_detach (char *args, int from_tty) +{ +} + +static int resume_is_step; +static int resume_signal = -1; + +static void +go32_resume (ptid_t ptid, int step, enum target_signal siggnal) +{ + int i; + + resume_is_step = step; + + if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP) + { + for (i = 0, resume_signal = -1; + excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++) + if (excepn_map[i].gdb_sig == siggnal) + { + resume_signal = excepn_map[i].djgpp_excepno; + break; + } + if (resume_signal == -1) + printf_unfiltered ("Cannot deliver signal %s on this platform.\n", + target_signal_to_name (siggnal)); + } +} + +static char child_cwd[FILENAME_MAX]; + +static ptid_t +go32_wait (ptid_t ptid, struct target_waitstatus *status) +{ + int i; + unsigned char saved_opcode; + unsigned long INT3_addr = 0; + int stepping_over_INT = 0; + + a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */ + if (resume_is_step) + { + /* If the next instruction is INT xx or INTO, we need to handle + them specially. Intel manuals say that these instructions + reset the single-step flag (a.k.a. TF). However, it seems + that, at least in the DPMI environment, and at least when + stepping over the DPMI interrupt 31h, the problem is having + TF set at all when INT 31h is executed: the debuggee either + crashes (and takes the system with it) or is killed by a + SIGTRAP. + + So we need to emulate single-step mode: we put an INT3 opcode + right after the INT xx instruction, let the debuggee run + until it hits INT3 and stops, then restore the original + instruction which we overwrote with the INT3 opcode, and back + up the debuggee's EIP to that instruction. */ + read_child (a_tss.tss_eip, &saved_opcode, 1); + if (saved_opcode == 0xCD || saved_opcode == 0xCE) + { + unsigned char INT3_opcode = 0xCC; + + INT3_addr + = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1; + stepping_over_INT = 1; + read_child (INT3_addr, &saved_opcode, 1); + write_child (INT3_addr, &INT3_opcode, 1); + } + else + a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */ + } + + /* The special value FFFFh in tss_trap indicates to run_child that + tss_irqn holds a signal to be delivered to the debuggee. */ + if (resume_signal <= -1) + { + a_tss.tss_trap = 0; + a_tss.tss_irqn = 0xff; + } + else + { + a_tss.tss_trap = 0xffff; /* run_child looks for this */ + a_tss.tss_irqn = resume_signal; + } + + /* The child might change working directory behind our back. The + GDB users won't like the side effects of that when they work with + relative file names, and GDB might be confused by its current + directory not being in sync with the truth. So we always make a + point of changing back to where GDB thinks is its cwd, when we + return control to the debugger, but restore child's cwd before we + run it. */ + /* Initialize child_cwd, before the first call to run_child and not + in the initialization, so the child get also the changed directory + set with the gdb-command "cd ..." */ + if (!*child_cwd) + /* Initialize child's cwd with the current one. */ + getcwd (child_cwd, sizeof (child_cwd)); + + chdir (child_cwd); + +#if __DJGPP_MINOR__ < 3 + load_npx (); +#endif + run_child (); +#if __DJGPP_MINOR__ < 3 + save_npx (); +#endif + + /* Did we step over an INT xx instruction? */ + if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1) + { + /* Restore the original opcode. */ + a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */ + write_child (a_tss.tss_eip, &saved_opcode, 1); + /* Simulate a TRAP exception. */ + a_tss.tss_irqn = 1; + a_tss.tss_eflags |= 0x0100; + } + + getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */ + chdir (current_directory); + + if (a_tss.tss_irqn == 0x21) + { + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = a_tss.tss_eax & 0xff; + } + else + { + status->value.sig = TARGET_SIGNAL_UNKNOWN; + status->kind = TARGET_WAITKIND_STOPPED; + for (i = 0; sig_map[i].go32_sig != -1; i++) + { + if (a_tss.tss_irqn == sig_map[i].go32_sig) + { +#if __DJGPP_MINOR__ < 3 + if ((status->value.sig = sig_map[i].gdb_sig) != + TARGET_SIGNAL_TRAP) + status->kind = TARGET_WAITKIND_SIGNALLED; +#else + status->value.sig = sig_map[i].gdb_sig; +#endif + break; + } + } + } + return pid_to_ptid (SOME_PID); +} + +static void +fetch_register (int regno) +{ + if (regno < FP0_REGNUM) + supply_register (regno, (char *) &a_tss + regno_mapping[regno].tss_ofs); + else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno)) + i387_supply_fsave (current_regcache, regno, &npx); + else + internal_error (__FILE__, __LINE__, + "Invalid register no. %d in fetch_register.", regno); +} + +static void +go32_fetch_registers (int regno) +{ + if (regno >= 0) + fetch_register (regno); + else + { + for (regno = 0; regno < FP0_REGNUM; regno++) + fetch_register (regno); + i387_supply_fsave (current_regcache, -1, &npx); + } +} + +static void +store_register (int regno) +{ + if (regno < FP0_REGNUM) + regcache_collect (regno, (char *) &a_tss + regno_mapping[regno].tss_ofs); + else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno)) + i387_fill_fsave ((char *) &npx, regno); + else + internal_error (__FILE__, __LINE__, + "Invalid register no. %d in store_register.", regno); +} + +static void +go32_store_registers (int regno) +{ + unsigned r; + + if (regno >= 0) + store_register (regno); + else + { + for (r = 0; r < FP0_REGNUM; r++) + store_register (r); + i387_fill_fsave ((char *) &npx, -1); + } +} + +static void +go32_prepare_to_store (void) +{ +} + +static int +go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, struct target_ops *target) +{ + if (write) + { + if (write_child (memaddr, myaddr, len)) + { + return 0; + } + else + { + return len; + } + } + else + { + if (read_child (memaddr, myaddr, len)) + { + return 0; + } + else + { + return len; + } + } +} + +static cmdline_t child_cmd; /* parsed child's command line kept here */ + +static void +go32_files_info (struct target_ops *target) +{ + printf_unfiltered ("You are running a DJGPP V2 program.\n"); +} + +static void +go32_stop (void) +{ + normal_stop (); + cleanup_client (); + inferior_ptid = null_ptid; + prog_has_started = 0; +} + +static void +go32_kill_inferior (void) +{ + redir_cmdline_delete (&child_cmd); + resume_signal = -1; + resume_is_step = 0; + unpush_target (&go32_ops); +} + +static void +go32_create_inferior (char *exec_file, char *args, char **env) +{ + extern char **environ; + jmp_buf start_state; + char *cmdline; + char **env_save = environ; + size_t cmdlen; + + /* If no exec file handed to us, get it from the exec-file command -- with + a good, common error message if none is specified. */ + if (exec_file == 0) + exec_file = get_exec_file (1); + + if (prog_has_started) + { + go32_stop (); + go32_kill_inferior (); + } + resume_signal = -1; + resume_is_step = 0; + + /* Initialize child's cwd as empty to be initialized when starting + the child. */ + *child_cwd = 0; + + /* Init command line storage. */ + if (redir_debug_init (&child_cmd) == -1) + internal_error (__FILE__, __LINE__, + "Cannot allocate redirection storage: not enough memory.\n"); + + /* Parse the command line and create redirections. */ + if (strpbrk (args, "<>")) + { + if (redir_cmdline_parse (args, &child_cmd) == 0) + args = child_cmd.command; + else + error ("Syntax error in command line."); + } + else + child_cmd.command = xstrdup (args); + + cmdlen = strlen (args); + /* v2loadimage passes command lines via DOS memory, so it cannot + possibly handle commands longer than 1MB. */ + if (cmdlen > 1024*1024) + error ("Command line too long."); + + cmdline = xmalloc (cmdlen + 4); + strcpy (cmdline + 1, args); + /* If the command-line length fits into DOS 126-char limits, use the + DOS command tail format; otherwise, tell v2loadimage to pass it + through a buffer in conventional memory. */ + if (cmdlen < 127) + { + cmdline[0] = strlen (args); + cmdline[cmdlen + 1] = 13; + } + else + cmdline[0] = 0xff; /* signal v2loadimage it's a long command */ + + environ = env; + + if (v2loadimage (exec_file, cmdline, start_state)) + { + environ = env_save; + printf_unfiltered ("Load failed for image %s\n", exec_file); + exit (1); + } + environ = env_save; + xfree (cmdline); + + edi_init (start_state); +#if __DJGPP_MINOR__ < 3 + save_npx (); +#endif + + inferior_ptid = pid_to_ptid (SOME_PID); + push_target (&go32_ops); + clear_proceed_status (); + insert_breakpoints (); + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0); + prog_has_started = 1; +} + +static void +go32_mourn_inferior (void) +{ + /* We need to make sure all the breakpoint enable bits in the DR7 + register are reset when the inferior exits. Otherwise, if they + rerun the inferior, the uncleared bits may cause random SIGTRAPs, + failure to set more watchpoints, and other calamities. It would + be nice if GDB itself would take care to remove all breakpoints + at all times, but it doesn't, probably under an assumption that + the OS cleans up when the debuggee exits. */ + i386_cleanup_dregs (); + go32_kill_inferior (); + generic_mourn_inferior (); +} + +static int +go32_can_run (void) +{ + return 1; +} + +/* Hardware watchpoint support. */ + +#define D_REGS edi.dr +#define CONTROL D_REGS[7] +#define STATUS D_REGS[6] + +/* Pass the address ADDR to the inferior in the I'th debug register. + Here we just store the address in D_REGS, the watchpoint will be + actually set up when go32_wait runs the debuggee. */ +void +go32_set_dr (int i, CORE_ADDR addr) +{ + if (i < 0 || i > 3) + internal_error (__FILE__, __LINE__, + "Invalid register %d in go32_set_dr.\n", i); + D_REGS[i] = addr; +} + +/* Pass the value VAL to the inferior in the DR7 debug control + register. Here we just store the address in D_REGS, the watchpoint + will be actually set up when go32_wait runs the debuggee. */ +void +go32_set_dr7 (unsigned val) +{ + CONTROL = val; +} + +/* Get the value of the DR6 debug status register from the inferior. + Here we just return the value stored in D_REGS, as we've got it + from the last go32_wait call. */ +unsigned +go32_get_dr6 (void) +{ + return STATUS; +} + +/* Put the device open on handle FD into either raw or cooked + mode, return 1 if it was in raw mode, zero otherwise. */ + +static int +device_mode (int fd, int raw_p) +{ + int oldmode, newmode; + __dpmi_regs regs; + + regs.x.ax = 0x4400; + regs.x.bx = fd; + __dpmi_int (0x21, ®s); + if (regs.x.flags & 1) + return -1; + newmode = oldmode = regs.x.dx; + + if (raw_p) + newmode |= 0x20; + else + newmode &= ~0x20; + + if (oldmode & 0x80) /* Only for character dev */ + { + regs.x.ax = 0x4401; + regs.x.bx = fd; + regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */ + __dpmi_int (0x21, ®s); + if (regs.x.flags & 1) + return -1; + } + return (oldmode & 0x20) == 0x20; +} + + +static int inf_mode_valid = 0; +static int inf_terminal_mode; + +/* This semaphore is needed because, amazingly enough, GDB calls + target.to_terminal_ours more than once after the inferior stops. + But we need the information from the first call only, since the + second call will always see GDB's own cooked terminal. */ +static int terminal_is_ours = 1; + +static void +go32_terminal_init (void) +{ + inf_mode_valid = 0; /* reinitialize, in case they are restarting child */ + terminal_is_ours = 1; +} + +static void +go32_terminal_info (char *args, int from_tty) +{ + printf_unfiltered ("Inferior's terminal is in %s mode.\n", + !inf_mode_valid + ? "default" : inf_terminal_mode ? "raw" : "cooked"); + +#if __DJGPP_MINOR__ > 2 + if (child_cmd.redirection) + { + int i; + + for (i = 0; i < DBG_HANDLES; i++) + { + if (child_cmd.redirection[i]->file_name) + printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n", + i, child_cmd.redirection[i]->file_name); + else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1) + printf_unfiltered + ("\tFile handle %d appears to be closed by inferior.\n", i); + /* Mask off the raw/cooked bit when comparing device info words. */ + else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf) + != (_get_dev_info (i) & 0xdf)) + printf_unfiltered + ("\tFile handle %d appears to be redirected by inferior.\n", i); + } + } +#endif +} + +static void +go32_terminal_inferior (void) +{ + /* Redirect standard handles as child wants them. */ + errno = 0; + if (redir_to_child (&child_cmd) == -1) + { + redir_to_debugger (&child_cmd); + error ("Cannot redirect standard handles for program: %s.", + safe_strerror (errno)); + } + /* set the console device of the inferior to whatever mode + (raw or cooked) we found it last time */ + if (terminal_is_ours) + { + if (inf_mode_valid) + device_mode (0, inf_terminal_mode); + terminal_is_ours = 0; + } +} + +static void +go32_terminal_ours (void) +{ + /* Switch to cooked mode on the gdb terminal and save the inferior + terminal mode to be restored when it is resumed */ + if (!terminal_is_ours) + { + inf_terminal_mode = device_mode (0, 0); + if (inf_terminal_mode != -1) + inf_mode_valid = 1; + else + /* If device_mode returned -1, we don't know what happens with + handle 0 anymore, so make the info invalid. */ + inf_mode_valid = 0; + terminal_is_ours = 1; + + /* Restore debugger's standard handles. */ + errno = 0; + if (redir_to_debugger (&child_cmd) == -1) + { + redir_to_child (&child_cmd); + error ("Cannot redirect standard handles for debugger: %s.", + safe_strerror (errno)); + } + } +} + +static void +init_go32_ops (void) +{ + go32_ops.to_shortname = "djgpp"; + go32_ops.to_longname = "djgpp target process"; + go32_ops.to_doc = + "Program loaded by djgpp, when gdb is used as an external debugger"; + go32_ops.to_open = go32_open; + go32_ops.to_close = go32_close; + go32_ops.to_attach = go32_attach; + go32_ops.to_detach = go32_detach; + go32_ops.to_resume = go32_resume; + go32_ops.to_wait = go32_wait; + go32_ops.to_fetch_registers = go32_fetch_registers; + go32_ops.to_store_registers = go32_store_registers; + go32_ops.to_prepare_to_store = go32_prepare_to_store; + go32_ops.to_xfer_memory = go32_xfer_memory; + go32_ops.to_files_info = go32_files_info; + go32_ops.to_insert_breakpoint = memory_insert_breakpoint; + go32_ops.to_remove_breakpoint = memory_remove_breakpoint; + go32_ops.to_terminal_init = go32_terminal_init; + go32_ops.to_terminal_inferior = go32_terminal_inferior; + go32_ops.to_terminal_ours_for_output = go32_terminal_ours; + go32_ops.to_terminal_ours = go32_terminal_ours; + go32_ops.to_terminal_info = go32_terminal_info; + go32_ops.to_kill = go32_kill_inferior; + go32_ops.to_create_inferior = go32_create_inferior; + go32_ops.to_mourn_inferior = go32_mourn_inferior; + go32_ops.to_can_run = go32_can_run; + go32_ops.to_stop = go32_stop; + go32_ops.to_stratum = process_stratum; + go32_ops.to_has_all_memory = 1; + go32_ops.to_has_memory = 1; + go32_ops.to_has_stack = 1; + go32_ops.to_has_registers = 1; + go32_ops.to_has_execution = 1; + go32_ops.to_magic = OPS_MAGIC; + + /* Initialize child's cwd as empty to be initialized when starting + the child. */ + *child_cwd = 0; + + /* Initialize child's command line storage. */ + if (redir_debug_init (&child_cmd) == -1) + internal_error (__FILE__, __LINE__, + "Cannot allocate redirection storage: not enough memory.\n"); + + /* We are always processing GCC-compiled programs. */ + processing_gcc_compilation = 2; +} + +unsigned short windows_major, windows_minor; + +/* Compute the version Windows reports via Int 2Fh/AX=1600h. */ +static void +go32_get_windows_version(void) +{ + __dpmi_regs r; + + r.x.ax = 0x1600; + __dpmi_int(0x2f, &r); + if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff + && (r.h.al > 3 || r.h.ah > 0)) + { + windows_major = r.h.al; + windows_minor = r.h.ah; + } + else + windows_major = 0xff; /* meaning no Windows */ +} + +/* A subroutine of go32_sysinfo to display memory info. */ +static void +print_mem (unsigned long datum, const char *header, int in_pages_p) +{ + if (datum != 0xffffffffUL) + { + if (in_pages_p) + datum <<= 12; + puts_filtered (header); + if (datum > 1024) + { + printf_filtered ("%lu KB", datum >> 10); + if (datum > 1024 * 1024) + printf_filtered (" (%lu MB)", datum >> 20); + } + else + printf_filtered ("%lu Bytes", datum); + puts_filtered ("\n"); + } +} + +/* Display assorted information about the underlying OS. */ +static void +go32_sysinfo (char *arg, int from_tty) +{ + struct utsname u; + char cpuid_vendor[13]; + unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx; + unsigned true_dos_version = _get_dos_version (1); + unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor; + int dpmi_flags; + char dpmi_vendor_info[129]; + int dpmi_vendor_available = + __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info); + __dpmi_version_ret dpmi_version_data; + long eflags; + __dpmi_free_mem_info mem_info; + __dpmi_regs regs; + + cpuid_vendor[0] = '\0'; + if (uname (&u)) + strcpy (u.machine, "Unknown x86"); + else if (u.machine[0] == 'i' && u.machine[1] > 4) + { + /* CPUID with EAX = 0 returns the Vendor ID. */ + __asm__ __volatile__ ("xorl %%ebx, %%ebx;" + "xorl %%ecx, %%ecx;" + "xorl %%edx, %%edx;" + "movl $0, %%eax;" + "cpuid;" + "movl %%ebx, %0;" + "movl %%edx, %1;" + "movl %%ecx, %2;" + "movl %%eax, %3;" + : "=m" (cpuid_vendor[0]), + "=m" (cpuid_vendor[4]), + "=m" (cpuid_vendor[8]), + "=m" (cpuid_max) + : + : "%eax", "%ebx", "%ecx", "%edx"); + cpuid_vendor[12] = '\0'; + } + + printf_filtered ("CPU Type.......................%s", u.machine); + if (cpuid_vendor[0]) + printf_filtered (" (%s)", cpuid_vendor); + puts_filtered ("\n"); + + /* CPUID with EAX = 1 returns processor signature and features. */ + if (cpuid_max >= 1) + { + static char *brand_name[] = { + "", + " Celeron", + " III", + " III Xeon", + "", "", "", "", + " 4" + }; + char cpu_string[80]; + char cpu_brand[20]; + unsigned brand_idx; + int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0; + int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0; + unsigned cpu_family, cpu_model; + + __asm__ __volatile__ ("movl $1, %%eax;" + "cpuid;" + : "=a" (cpuid_eax), + "=b" (cpuid_ebx), + "=d" (cpuid_edx) + : + : "%ecx"); + brand_idx = cpuid_ebx & 0xff; + cpu_family = (cpuid_eax >> 8) & 0xf; + cpu_model = (cpuid_eax >> 4) & 0xf; + cpu_brand[0] = '\0'; + if (intel_p) + { + if (brand_idx > 0 + && brand_idx < sizeof(brand_name)/sizeof(brand_name[0]) + && *brand_name[brand_idx]) + strcpy (cpu_brand, brand_name[brand_idx]); + else if (cpu_family == 5) + { + if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4) + strcpy (cpu_brand, " MMX"); + else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1) + strcpy (cpu_brand, " OverDrive"); + else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2) + strcpy (cpu_brand, " Dual"); + } + else if (cpu_family == 6 && cpu_model < 8) + { + switch (cpu_model) + { + case 1: + strcpy (cpu_brand, " Pro"); + break; + case 3: + strcpy (cpu_brand, " II"); + break; + case 5: + strcpy (cpu_brand, " II Xeon"); + break; + case 6: + strcpy (cpu_brand, " Celeron"); + break; + case 7: + strcpy (cpu_brand, " III"); + break; + } + } + } + else if (amd_p) + { + switch (cpu_family) + { + case 4: + strcpy (cpu_brand, "486/5x86"); + break; + case 5: + switch (cpu_model) + { + case 0: + case 1: + case 2: + case 3: + strcpy (cpu_brand, "-K5"); + break; + case 6: + case 7: + strcpy (cpu_brand, "-K6"); + break; + case 8: + strcpy (cpu_brand, "-K6-2"); + break; + case 9: + strcpy (cpu_brand, "-K6-III"); + break; + } + break; + case 6: + switch (cpu_model) + { + case 1: + case 2: + case 4: + strcpy (cpu_brand, " Athlon"); + break; + case 3: + strcpy (cpu_brand, " Duron"); + break; + } + break; + } + } + sprintf (cpu_string, "%s%s Model %d Stepping %d", + intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"), + cpu_brand, cpu_model, cpuid_eax & 0xf); + printfi_filtered (31, "%s\n", cpu_string); + if (((cpuid_edx & (6 | (0x0d << 23))) != 0) + || ((cpuid_edx & 1) == 0) + || (amd_p && (cpuid_edx & (3 << 30)) != 0)) + { + puts_filtered ("CPU Features..................."); + /* We only list features which might be useful in the DPMI + environment. */ + if ((cpuid_edx & 1) == 0) + puts_filtered ("No FPU "); /* it's unusual to not have an FPU */ + if ((cpuid_edx & (1 << 1)) != 0) + puts_filtered ("VME "); + if ((cpuid_edx & (1 << 2)) != 0) + puts_filtered ("DE "); + if ((cpuid_edx & (1 << 4)) != 0) + puts_filtered ("TSC "); + if ((cpuid_edx & (1 << 23)) != 0) + puts_filtered ("MMX "); + if ((cpuid_edx & (1 << 25)) != 0) + puts_filtered ("SSE "); + if ((cpuid_edx & (1 << 26)) != 0) + puts_filtered ("SSE2 "); + if (amd_p) + { + if ((cpuid_edx & (1 << 31)) != 0) + puts_filtered ("3DNow! "); + if ((cpuid_edx & (1 << 30)) != 0) + puts_filtered ("3DNow!Ext"); + } + puts_filtered ("\n"); + } + } + puts_filtered ("\n"); + printf_filtered ("DOS Version....................%s %s.%s", + _os_flavor, u.release, u.version); + if (true_dos_version != advertized_dos_version) + printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor); + puts_filtered ("\n"); + if (!windows_major) + go32_get_windows_version (); + if (windows_major != 0xff) + { + const char *windows_flavor; + + printf_filtered ("Windows Version................%d.%02d (Windows ", + windows_major, windows_minor); + switch (windows_major) + { + case 3: + windows_flavor = "3.X"; + break; + case 4: + switch (windows_minor) + { + case 0: + windows_flavor = "95, 95A, or 95B"; + break; + case 3: + windows_flavor = "95B OSR2.1 or 95C OSR2.5"; + break; + case 10: + windows_flavor = "98 or 98 SE"; + break; + case 90: + windows_flavor = "ME"; + break; + default: + windows_flavor = "9X"; + break; + } + break; + default: + windows_flavor = "??"; + break; + } + printf_filtered ("%s)\n", windows_flavor); + } + else if (true_dos_version == 0x532 && advertized_dos_version == 0x500) + printf_filtered ("Windows Version................Windows NT or Windows 2000\n"); + puts_filtered ("\n"); + if (dpmi_vendor_available == 0) + { + /* The DPMI spec says the vendor string should be ASCIIZ, but + I don't trust the vendors to follow that... */ + if (!memchr (&dpmi_vendor_info[2], 0, 126)) + dpmi_vendor_info[128] = '\0'; + printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n", + &dpmi_vendor_info[2], + (unsigned)dpmi_vendor_info[0], + (unsigned)dpmi_vendor_info[1], + ((unsigned)dpmi_flags & 0x7f)); + } + __dpmi_get_version (&dpmi_version_data); + printf_filtered ("DPMI Version...................%d.%02d\n", + dpmi_version_data.major, dpmi_version_data.minor); + printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n", + (dpmi_version_data.flags & 1) ? "32" : "16", + (dpmi_version_data.flags & 4) ? "" : "out"); + printfi_filtered (31, "Interrupts reflected to %s mode\n", + (dpmi_version_data.flags & 2) ? "V86" : "Real"); + printfi_filtered (31, "Processor type: i%d86\n", + dpmi_version_data.cpu); + printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n", + dpmi_version_data.master_pic, dpmi_version_data.slave_pic); + + /* a_tss is only initialized when the debuggee is first run. */ + if (prog_has_started) + { + __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags)); + printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n", + a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT", + (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out"); + } + puts_filtered ("\n"); + __dpmi_get_free_memory_information (&mem_info); + print_mem (mem_info.total_number_of_physical_pages, + "DPMI Total Physical Memory.....", 1); + print_mem (mem_info.total_number_of_free_pages, + "DPMI Free Physical Memory......", 1); + print_mem (mem_info.size_of_paging_file_partition_in_pages, + "DPMI Swap Space................", 1); + print_mem (mem_info.linear_address_space_size_in_pages, + "DPMI Total Linear Address Size.", 1); + print_mem (mem_info.free_linear_address_space_in_pages, + "DPMI Free Linear Address Size..", 1); + print_mem (mem_info.largest_available_free_block_in_bytes, + "DPMI Largest Free Memory Block.", 0); + + regs.h.ah = 0x48; + regs.x.bx = 0xffff; + __dpmi_int (0x21, ®s); + print_mem (regs.x.bx << 4, "Free DOS Memory................", 0); + regs.x.ax = 0x5800; + __dpmi_int (0x21, ®s); + if ((regs.x.flags & 1) == 0) + { + static const char *dos_hilo[] = { + "Low", "", "", "", "High", "", "", "", "High, then Low" + }; + static const char *dos_fit[] = { + "First", "Best", "Last" + }; + int hilo_idx = (regs.x.ax >> 4) & 0x0f; + int fit_idx = regs.x.ax & 0x0f; + + if (hilo_idx > 8) + hilo_idx = 0; + if (fit_idx > 2) + fit_idx = 0; + printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n", + dos_hilo[hilo_idx], dos_fit[fit_idx]); + regs.x.ax = 0x5802; + __dpmi_int (0x21, ®s); + if ((regs.x.flags & 1) != 0) + regs.h.al = 0; + printfi_filtered (31, "UMBs %sin DOS memory chain\n", + regs.h.al == 0 ? "not " : ""); + } +} + +struct seg_descr { + unsigned short limit0 __attribute__((packed)); + unsigned short base0 __attribute__((packed)); + unsigned char base1 __attribute__((packed)); + unsigned stype:5 __attribute__((packed)); + unsigned dpl:2 __attribute__((packed)); + unsigned present:1 __attribute__((packed)); + unsigned limit1:4 __attribute__((packed)); + unsigned available:1 __attribute__((packed)); + unsigned dummy:1 __attribute__((packed)); + unsigned bit32:1 __attribute__((packed)); + unsigned page_granular:1 __attribute__((packed)); + unsigned char base2 __attribute__((packed)); +}; + +struct gate_descr { + unsigned short offset0 __attribute__((packed)); + unsigned short selector __attribute__((packed)); + unsigned param_count:5 __attribute__((packed)); + unsigned dummy:3 __attribute__((packed)); + unsigned stype:5 __attribute__((packed)); + unsigned dpl:2 __attribute__((packed)); + unsigned present:1 __attribute__((packed)); + unsigned short offset1 __attribute__((packed)); +}; + +/* Read LEN bytes starting at logical address ADDR, and put the result + into DEST. Return 1 if success, zero if not. */ +static int +read_memory_region (unsigned long addr, void *dest, size_t len) +{ + unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds); + int retval = 1; + + /* For the low memory, we can simply use _dos_ds. */ + if (addr <= dos_ds_limit - len) + dosmemget (addr, len, dest); + else + { + /* For memory above 1MB we need to set up a special segment to + be able to access that memory. */ + int sel = __dpmi_allocate_ldt_descriptors (1); + + if (sel <= 0) + retval = 0; + else + { + int access_rights = __dpmi_get_descriptor_access_rights (sel); + size_t segment_limit = len - 1; + + /* Make sure the crucial bits in the descriptor access + rights are set correctly. Some DPMI providers might barf + if we set the segment limit to something that is not an + integral multiple of 4KB pages if the granularity bit is + not set to byte-granular, even though the DPMI spec says + it's the host's responsibility to set that bit correctly. */ + if (len > 1024 * 1024) + { + access_rights |= 0x8000; + /* Page-granular segments should have the low 12 bits of + the limit set. */ + segment_limit |= 0xfff; + } + else + access_rights &= ~0x8000; + + if (__dpmi_set_segment_base_address (sel, addr) != -1 + && __dpmi_set_descriptor_access_rights (sel, access_rights) != -1 + && __dpmi_set_segment_limit (sel, segment_limit) != -1 + /* W2K silently fails to set the segment limit, leaving + it at zero; this test avoids the resulting crash. */ + && __dpmi_get_segment_limit (sel) >= segment_limit) + movedata (sel, 0, _my_ds (), (unsigned)dest, len); + else + retval = 0; + + __dpmi_free_ldt_descriptor (sel); + } + } + return retval; +} + +/* Get a segment descriptor stored at index IDX in the descriptor + table whose base address is TABLE_BASE. Return the descriptor + type, or -1 if failure. */ +static int +get_descriptor (unsigned long table_base, int idx, void *descr) +{ + unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */ + + if (read_memory_region (addr, descr, 8)) + return (int)((struct seg_descr *)descr)->stype; + return -1; +} + +struct dtr_reg { + unsigned short limit __attribute__((packed)); + unsigned long base __attribute__((packed)); +}; + +/* Display a segment descriptor stored at index IDX in a descriptor + table whose type is TYPE and whose base address is BASE_ADDR. If + FORCE is non-zero, display even invalid descriptors. */ +static void +display_descriptor (unsigned type, unsigned long base_addr, int idx, int force) +{ + struct seg_descr descr; + struct gate_descr gate; + + /* Get the descriptor from the table. */ + if (idx == 0 && type == 0) + puts_filtered ("0x000: null descriptor\n"); + else if (get_descriptor (base_addr, idx, &descr) != -1) + { + /* For each type of descriptor table, this has a bit set if the + corresponding type of selectors is valid in that table. */ + static unsigned allowed_descriptors[] = { + 0xffffdafeL, /* GDT */ + 0x0000c0e0L, /* IDT */ + 0xffffdafaL /* LDT */ + }; + + /* If the program hasn't started yet, assume the debuggee will + have the same CPL as the debugger. */ + int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3; + unsigned long limit = (descr.limit1 << 16) | descr.limit0; + + if (descr.present + && (allowed_descriptors[type] & (1 << descr.stype)) != 0) + { + printf_filtered ("0x%03x: ", + type == 1 + ? idx : (idx * 8) | (type ? (cpl | 4) : 0)); + if (descr.page_granular) + limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */ + if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3 + || descr.stype == 9 || descr.stype == 11 + || (descr.stype >= 16 && descr.stype < 32)) + printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx", + descr.base2, descr.base1, descr.base0, limit); + + switch (descr.stype) + { + case 1: + case 3: + printf_filtered (" 16-bit TSS (task %sactive)", + descr.stype == 3 ? "" : "in"); + break; + case 2: + puts_filtered (" LDT"); + break; + case 4: + memcpy (&gate, &descr, sizeof gate); + printf_filtered ("selector=0x%04x offs=0x%04x%04x", + gate.selector, gate.offset1, gate.offset0); + printf_filtered (" 16-bit Call Gate (params=%d)", + gate.param_count); + break; + case 5: + printf_filtered ("TSS selector=0x%04x", descr.base0); + printfi_filtered (16, "Task Gate"); + break; + case 6: + case 7: + memcpy (&gate, &descr, sizeof gate); + printf_filtered ("selector=0x%04x offs=0x%04x%04x", + gate.selector, gate.offset1, gate.offset0); + printf_filtered (" 16-bit %s Gate", + descr.stype == 6 ? "Interrupt" : "Trap"); + break; + case 9: + case 11: + printf_filtered (" 32-bit TSS (task %sactive)", + descr.stype == 3 ? "" : "in"); + break; + case 12: + memcpy (&gate, &descr, sizeof gate); + printf_filtered ("selector=0x%04x offs=0x%04x%04x", + gate.selector, gate.offset1, gate.offset0); + printf_filtered (" 32-bit Call Gate (params=%d)", + gate.param_count); + break; + case 14: + case 15: + memcpy (&gate, &descr, sizeof gate); + printf_filtered ("selector=0x%04x offs=0x%04x%04x", + gate.selector, gate.offset1, gate.offset0); + printf_filtered (" 32-bit %s Gate", + descr.stype == 14 ? "Interrupt" : "Trap"); + break; + case 16: /* data segments */ + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + printf_filtered (" %s-bit Data (%s Exp-%s%s)", + descr.bit32 ? "32" : "16", + descr.stype & 2 ? "Read/Write," : "Read-Only, ", + descr.stype & 4 ? "down" : "up", + descr.stype & 1 ? "" : ", N.Acc"); + break; + case 24: /* code segments */ + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + printf_filtered (" %s-bit Code (%s, %sConf%s)", + descr.bit32 ? "32" : "16", + descr.stype & 2 ? "Exec/Read" : "Exec-Only", + descr.stype & 4 ? "" : "N.", + descr.stype & 1 ? "" : ", N.Acc"); + break; + default: + printf_filtered ("Unknown type 0x%02x", descr.stype); + break; + } + puts_filtered ("\n"); + } + else if (force) + { + printf_filtered ("0x%03x: ", + type == 1 + ? idx : (idx * 8) | (type ? (cpl | 4) : 0)); + if (!descr.present) + puts_filtered ("Segment not present\n"); + else + printf_filtered ("Segment type 0x%02x is invalid in this table\n", + descr.stype); + } + } + else if (force) + printf_filtered ("0x%03x: Cannot read this descriptor\n", idx); +} + +static void +go32_sldt (char *arg, int from_tty) +{ + struct dtr_reg gdtr; + unsigned short ldtr = 0; + int ldt_idx; + struct seg_descr ldt_descr; + long ldt_entry = -1L; + int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3; + + if (arg && *arg) + { + while (*arg && isspace(*arg)) + arg++; + + if (*arg) + { + ldt_entry = parse_and_eval_long (arg); + if (ldt_entry < 0 + || (ldt_entry & 4) == 0 + || (ldt_entry & 3) != (cpl & 3)) + error ("Invalid LDT entry 0x%03lx.", (unsigned long)ldt_entry); + } + } + + __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ ); + __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ ); + ldt_idx = ldtr / 8; + if (ldt_idx == 0) + puts_filtered ("There is no LDT.\n"); + /* LDT's entry in the GDT must have the type LDT, which is 2. */ + else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2) + printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n", + ldt_descr.base0 + | (ldt_descr.base1 << 16) + | (ldt_descr.base2 << 24)); + else + { + unsigned base = + ldt_descr.base0 + | (ldt_descr.base1 << 16) + | (ldt_descr.base2 << 24); + unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16); + int max_entry; + + if (ldt_descr.page_granular) + /* Page-granular segments must have the low 12 bits of their + limit set. */ + limit = (limit << 12) | 0xfff; + /* LDT cannot have more than 8K 8-byte entries, i.e. more than + 64KB. */ + if (limit > 0xffff) + limit = 0xffff; + + max_entry = (limit + 1) / 8; + + if (ldt_entry >= 0) + { + if (ldt_entry > limit) + error ("Invalid LDT entry %#lx: outside valid limits [0..%#x]", + (unsigned long)ldt_entry, limit); + + display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1); + } + else + { + int i; + + for (i = 0; i < max_entry; i++) + display_descriptor (ldt_descr.stype, base, i, 0); + } + } +} + +static void +go32_sgdt (char *arg, int from_tty) +{ + struct dtr_reg gdtr; + long gdt_entry = -1L; + int max_entry; + + if (arg && *arg) + { + while (*arg && isspace(*arg)) + arg++; + + if (*arg) + { + gdt_entry = parse_and_eval_long (arg); + if (gdt_entry < 0 || (gdt_entry & 7) != 0) + error ("Invalid GDT entry 0x%03lx: not an integral multiple of 8.", + (unsigned long)gdt_entry); + } + } + + __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ ); + max_entry = (gdtr.limit + 1) / 8; + + if (gdt_entry >= 0) + { + if (gdt_entry > gdtr.limit) + error ("Invalid GDT entry %#lx: outside valid limits [0..%#x]", + (unsigned long)gdt_entry, gdtr.limit); + + display_descriptor (0, gdtr.base, gdt_entry / 8, 1); + } + else + { + int i; + + for (i = 0; i < max_entry; i++) + display_descriptor (0, gdtr.base, i, 0); + } +} + +static void +go32_sidt (char *arg, int from_tty) +{ + struct dtr_reg idtr; + long idt_entry = -1L; + int max_entry; + + if (arg && *arg) + { + while (*arg && isspace(*arg)) + arg++; + + if (*arg) + { + idt_entry = parse_and_eval_long (arg); + if (idt_entry < 0) + error ("Invalid (negative) IDT entry %ld.", idt_entry); + } + } + + __asm__ __volatile__ ("sidt %0" : "=m" (idtr) : /* no inputs */ ); + max_entry = (idtr.limit + 1) / 8; + if (max_entry > 0x100) /* no more than 256 entries */ + max_entry = 0x100; + + if (idt_entry >= 0) + { + if (idt_entry > idtr.limit) + error ("Invalid IDT entry %#lx: outside valid limits [0..%#x]", + (unsigned long)idt_entry, idtr.limit); + + display_descriptor (1, idtr.base, idt_entry, 1); + } + else + { + int i; + + for (i = 0; i < max_entry; i++) + display_descriptor (1, idtr.base, i, 0); + } +} + +/* Cached linear address of the base of the page directory. For + now, available only under CWSDPMI. Code based on ideas and + suggestions from Charles Sandmann . */ +static unsigned long pdbr; + +static unsigned long +get_cr3 (void) +{ + unsigned offset; + unsigned taskreg; + unsigned long taskbase, cr3; + struct dtr_reg gdtr; + + if (pdbr > 0 && pdbr <= 0xfffff) + return pdbr; + + /* Get the linear address of GDT and the Task Register. */ + __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ ); + __asm__ __volatile__ ("str %0" : "=m" (taskreg) : /* no inputs */ ); + + /* Task Register is a segment selector for the TSS of the current + task. Therefore, it can be used as an index into the GDT to get + at the segment descriptor for the TSS. To get the index, reset + the low 3 bits of the selector (which give the CPL). Add 2 to the + offset to point to the 3 low bytes of the base address. */ + offset = gdtr.base + (taskreg & 0xfff8) + 2; + + + /* CWSDPMI's task base is always under the 1MB mark. */ + if (offset > 0xfffff) + return 0; + + _farsetsel (_dos_ds); + taskbase = _farnspeekl (offset) & 0xffffffU; + taskbase += _farnspeekl (offset + 2) & 0xff000000U; + if (taskbase > 0xfffff) + return 0; + + /* CR3 (a.k.a. PDBR, the Page Directory Base Register) is stored at + offset 1Ch in the TSS. */ + cr3 = _farnspeekl (taskbase + 0x1c) & ~0xfff; + if (cr3 > 0xfffff) + { +#if 0 /* not fullly supported yet */ + /* The Page Directory is in UMBs. In that case, CWSDPMI puts + the first Page Table right below the Page Directory. Thus, + the first Page Table's entry for its own address and the Page + Directory entry for that Page Table will hold the same + physical address. The loop below searches the entire UMB + range of addresses for such an occurence. */ + unsigned long addr, pte_idx; + + for (addr = 0xb0000, pte_idx = 0xb0; + pte_idx < 0xff; + addr += 0x1000, pte_idx++) + { + if (((_farnspeekl (addr + 4 * pte_idx) & 0xfffff027) == + (_farnspeekl (addr + 0x1000) & 0xfffff027)) + && ((_farnspeekl (addr + 4 * pte_idx + 4) & 0xfffff000) == cr3)) + { + cr3 = addr + 0x1000; + break; + } + } +#endif + + if (cr3 > 0xfffff) + cr3 = 0; + } + + return cr3; +} + +/* Return the N'th Page Directory entry. */ +static unsigned long +get_pde (int n) +{ + unsigned long pde = 0; + + if (pdbr && n >= 0 && n < 1024) + { + pde = _farpeekl (_dos_ds, pdbr + 4*n); + } + return pde; +} + +/* Return the N'th entry of the Page Table whose Page Directory entry + is PDE. */ +static unsigned long +get_pte (unsigned long pde, int n) +{ + unsigned long pte = 0; + + /* pde & 0x80 tests the 4MB page bit. We don't support 4MB + page tables, for now. */ + if ((pde & 1) && !(pde & 0x80) && n >= 0 && n < 1024) + { + pde &= ~0xfff; /* clear non-address bits */ + pte = _farpeekl (_dos_ds, pde + 4*n); + } + return pte; +} + +/* Display a Page Directory or Page Table entry. IS_DIR, if non-zero, + says this is a Page Directory entry. If FORCE is non-zero, display + the entry even if its Present flag is off. OFF is the offset of the + address from the page's base address. */ +static void +display_ptable_entry (unsigned long entry, int is_dir, int force, unsigned off) +{ + if ((entry & 1) != 0) + { + printf_filtered ("Base=0x%05lx000", entry >> 12); + if ((entry & 0x100) && !is_dir) + puts_filtered (" Global"); + if ((entry & 0x40) && !is_dir) + puts_filtered (" Dirty"); + printf_filtered (" %sAcc.", (entry & 0x20) ? "" : "Not-"); + printf_filtered (" %sCached", (entry & 0x10) ? "" : "Not-"); + printf_filtered (" Write-%s", (entry & 8) ? "Thru" : "Back"); + printf_filtered (" %s", (entry & 4) ? "Usr" : "Sup"); + printf_filtered (" Read-%s", (entry & 2) ? "Write" : "Only"); + if (off) + printf_filtered (" +0x%x", off); + puts_filtered ("\n"); + } + else if (force) + printf_filtered ("Page%s not present or not supported; value=0x%lx.\n", + is_dir ? " Table" : "", entry >> 1); +} + +static void +go32_pde (char *arg, int from_tty) +{ + long pde_idx = -1, i; + + if (arg && *arg) + { + while (*arg && isspace(*arg)) + arg++; + + if (*arg) + { + pde_idx = parse_and_eval_long (arg); + if (pde_idx < 0 || pde_idx >= 1024) + error ("Entry %ld is outside valid limits [0..1023].", pde_idx); + } + } + + pdbr = get_cr3 (); + if (!pdbr) + puts_filtered ("Access to Page Directories is not supported on this system.\n"); + else if (pde_idx >= 0) + display_ptable_entry (get_pde (pde_idx), 1, 1, 0); + else + for (i = 0; i < 1024; i++) + display_ptable_entry (get_pde (i), 1, 0, 0); +} + +/* A helper function to display entries in a Page Table pointed to by + the N'th entry in the Page Directory. If FORCE is non-zero, say + something even if the Page Table is not accessible. */ +static void +display_page_table (long n, int force) +{ + unsigned long pde = get_pde (n); + + if ((pde & 1) != 0) + { + int i; + + printf_filtered ("Page Table pointed to by Page Directory entry 0x%lx:\n", n); + for (i = 0; i < 1024; i++) + display_ptable_entry (get_pte (pde, i), 0, 0, 0); + puts_filtered ("\n"); + } + else if (force) + printf_filtered ("Page Table not present; value=0x%lx.\n", pde >> 1); +} + +static void +go32_pte (char *arg, int from_tty) +{ + long pde_idx = -1L, i; + + if (arg && *arg) + { + while (*arg && isspace(*arg)) + arg++; + + if (*arg) + { + pde_idx = parse_and_eval_long (arg); + if (pde_idx < 0 || pde_idx >= 1024) + error ("Entry %ld is outside valid limits [0..1023].", pde_idx); + } + } + + pdbr = get_cr3 (); + if (!pdbr) + puts_filtered ("Access to Page Tables is not supported on this system.\n"); + else if (pde_idx >= 0) + display_page_table (pde_idx, 1); + else + for (i = 0; i < 1024; i++) + display_page_table (i, 0); +} + +static void +go32_pte_for_address (char *arg, int from_tty) +{ + CORE_ADDR addr = 0, i; + + if (arg && *arg) + { + while (*arg && isspace(*arg)) + arg++; + + if (*arg) + addr = parse_and_eval_address (arg); + } + if (!addr) + error_no_arg ("linear address"); + + pdbr = get_cr3 (); + if (!pdbr) + puts_filtered ("Access to Page Tables is not supported on this system.\n"); + else + { + int pde_idx = (addr >> 22) & 0x3ff; + int pte_idx = (addr >> 12) & 0x3ff; + unsigned offs = addr & 0xfff; + + printf_filtered ("Page Table entry for address 0x%llx:\n", + (unsigned long long)addr); + display_ptable_entry (get_pte (get_pde (pde_idx), pte_idx), 0, 1, offs); + } +} + +static struct cmd_list_element *info_dos_cmdlist = NULL; + +static void +go32_info_dos_command (char *args, int from_tty) +{ + help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout); +} + +void +_initialize_go32_nat (void) +{ + init_go32_ops (); + add_target (&go32_ops); + + add_prefix_cmd ("dos", class_info, go32_info_dos_command, + "Print information specific to DJGPP (aka MS-DOS) debugging.", + &info_dos_cmdlist, "info dos ", 0, &infolist); + + add_cmd ("sysinfo", class_info, go32_sysinfo, + "Display information about the target system, including CPU, OS, DPMI, etc.", + &info_dos_cmdlist); + add_cmd ("ldt", class_info, go32_sldt, + "Display entries in the LDT (Local Descriptor Table).\n" + "Entry number (an expression) as an argument means display only that entry.", + &info_dos_cmdlist); + add_cmd ("gdt", class_info, go32_sgdt, + "Display entries in the GDT (Global Descriptor Table).\n" + "Entry number (an expression) as an argument means display only that entry.", + &info_dos_cmdlist); + add_cmd ("idt", class_info, go32_sidt, + "Display entries in the IDT (Interrupt Descriptor Table).\n" + "Entry number (an expression) as an argument means display only that entry.", + &info_dos_cmdlist); + add_cmd ("pde", class_info, go32_pde, + "Display entries in the Page Directory.\n" + "Entry number (an expression) as an argument means display only that entry.", + &info_dos_cmdlist); + add_cmd ("pte", class_info, go32_pte, + "Display entries in Page Tables.\n" + "Entry number (an expression) as an argument means display only entries\n" + "from the Page Table pointed to by the specified Page Directory entry.", + &info_dos_cmdlist); + add_cmd ("address-pte", class_info, go32_pte_for_address, + "Display a Page Table entry for a linear address.\n" + "The address argument must be a linear address, after adding to\n" + "it the base address of the appropriate segment.\n" + "The base address of variables and functions in the debuggee's data\n" + "or code segment is stored in the variable __djgpp_base_address,\n" + "so use `__djgpp_base_address + (char *)&var' as the argument.\n" + "For other segments, look up their base address in the output of\n" + "the `info dos ldt' command.", + &info_dos_cmdlist); +} + +pid_t +tcgetpgrp (int fd) +{ + if (isatty (fd)) + return SOME_PID; + errno = ENOTTY; + return -1; +} + +int +tcsetpgrp (int fd, pid_t pgid) +{ + if (isatty (fd) && pgid == SOME_PID) + return 0; + errno = pgid == SOME_PID ? ENOTTY : ENOSYS; + return -1; +} diff --git a/contrib/gdb/gdb/gregset.h b/contrib/gdb/gdb/gregset.h index a3a13257906..0ec80a118d0 100644 --- a/contrib/gdb/gdb/gregset.h +++ b/contrib/gdb/gdb/gregset.h @@ -52,5 +52,18 @@ extern void supply_fpregset (gdb_fpregset_t *fpregs); extern void fill_gregset (gdb_gregset_t *gregs, int regno); extern void fill_fpregset (gdb_fpregset_t *fpregs, int regno); +#ifdef FILL_FPXREGSET +/* GNU/Linux i386: Copy register values between GDB's internal register cache + and the i386 extended floating point registers. */ + +#ifndef GDB_FPXREGSET_T +#define GDB_FPXREGSET_T elf_fpxregset_t +#endif + +typedef GDB_FPXREGSET_T gdb_fpxregset_t; + +extern void supply_fpxregset (gdb_fpxregset_t *fpxregs); +extern void fill_fpxregset (gdb_fpxregset_t *fpxregs, int regno); +#endif #endif diff --git a/contrib/gdb/gdb/hpacc-abi.c b/contrib/gdb/gdb/hpacc-abi.c index 6753cd7d865..0fb3adccb12 100644 --- a/contrib/gdb/gdb/hpacc-abi.c +++ b/contrib/gdb/gdb/hpacc-abi.c @@ -309,6 +309,7 @@ init_hpacc_ops (void) hpacc_abi_ops.baseclass_offset = gnuv2_baseclass_offset; } +extern initialize_file_ftype _initialize_hpacc_abi; /* -Wmissing-prototypes */ void _initialize_hpacc_abi (void) @@ -324,5 +325,5 @@ _initialize_hpacc_abi (void) regcomp (&operator_pattern, "^This will never match anything, please fill it in$", REG_NOSUB); - register_cp_abi (hpacc_abi_ops); + register_cp_abi (&hpacc_abi_ops); } diff --git a/contrib/gdb/gdb/hpread.c b/contrib/gdb/gdb/hpread.c new file mode 100644 index 00000000000..d345a04b974 --- /dev/null +++ b/contrib/gdb/gdb/hpread.c @@ -0,0 +1,6327 @@ +/* Read hp debug symbols and convert to internal format, for GDB. + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Written by the Center for Software Science at the University of Utah + and by Cygnus Support. */ + +#include "defs.h" +#include "bfd.h" +#include "gdb_string.h" +#include "hp-symtab.h" +#include "syms.h" +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" +#include "buildsym.h" +#include "complaints.h" +#include "gdb-stabs.h" +#include "gdbtypes.h" +#include "demangle.h" +#include "somsolib.h" +#include "gdb_assert.h" + +/* Private information attached to an objfile which we use to find + and internalize the HP C debug symbols within that objfile. */ + +struct hpread_symfile_info + { + /* The contents of each of the debug sections (there are 4 of them). */ + char *gntt; + char *lntt; + char *slt; + char *vt; + + /* We keep the size of the $VT$ section for range checking. */ + unsigned int vt_size; + + /* Some routines still need to know the number of symbols in the + main debug sections ($LNTT$ and $GNTT$). */ + unsigned int lntt_symcount; + unsigned int gntt_symcount; + + /* To keep track of all the types we've processed. */ + struct type **dntt_type_vector; + int dntt_type_vector_length; + + /* Keeps track of the beginning of a range of source lines. */ + sltpointer sl_index; + + /* Some state variables we'll need. */ + int within_function; + + /* Keep track of the current function's address. We may need to look + up something based on this address. */ + unsigned int current_function_value; + }; + +/* Accessor macros to get at the fields. */ +#define HPUX_SYMFILE_INFO(o) \ + ((struct hpread_symfile_info *)((o)->sym_private)) +#define GNTT(o) (HPUX_SYMFILE_INFO(o)->gntt) +#define LNTT(o) (HPUX_SYMFILE_INFO(o)->lntt) +#define SLT(o) (HPUX_SYMFILE_INFO(o)->slt) +#define VT(o) (HPUX_SYMFILE_INFO(o)->vt) +#define VT_SIZE(o) (HPUX_SYMFILE_INFO(o)->vt_size) +#define LNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->lntt_symcount) +#define GNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->gntt_symcount) +#define DNTT_TYPE_VECTOR(o) (HPUX_SYMFILE_INFO(o)->dntt_type_vector) +#define DNTT_TYPE_VECTOR_LENGTH(o) \ + (HPUX_SYMFILE_INFO(o)->dntt_type_vector_length) +#define SL_INDEX(o) (HPUX_SYMFILE_INFO(o)->sl_index) +#define WITHIN_FUNCTION(o) (HPUX_SYMFILE_INFO(o)->within_function) +#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value) + + +/* We put a pointer to this structure in the read_symtab_private field + of the psymtab. */ + +struct symloc + { + /* The offset within the file symbol table of first local symbol for + this file. */ + + int ldsymoff; + + /* Length (in bytes) of the section of the symbol table devoted to + this file's symbols (actually, the section bracketed may contain + more than just this file's symbols). If ldsymlen is 0, the only + reason for this thing's existence is the dependency list. + Nothing else will happen when it is read in. */ + + int ldsymlen; + }; + +#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff) +#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen) +#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private)) + +/* Complaints about the symbols we have encountered. */ +static void +lbrac_unmatched_complaint (int arg1) +{ + complaint (&symfile_complaints, "unmatched N_LBRAC before symtab pos %d", + arg1); +} + +static void +lbrac_mismatch_complaint (int arg1) +{ + complaint (&symfile_complaints, + "N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", arg1); +} + +/* To generate dumping code, uncomment this define. The dumping + itself is controlled by routine-local statics called "dumping". */ +/* #define DUMPING 1 */ + +/* To use the quick look-up tables, uncomment this define. */ +#define QUICK_LOOK_UP 1 + +/* To call PXDB to process un-processed files, uncomment this define. */ +#define USE_PXDB 1 + +/* Forward procedure declarations */ + +/* Used in somread.c. */ +void hpread_symfile_init (struct objfile *); + +void do_pxdb (bfd *); + +void hpread_build_psymtabs (struct objfile *, int); + +void hpread_symfile_finish (struct objfile *); + +static void set_namestring (union dnttentry *sym, char **namep, + struct objfile *objfile); + +static union dnttentry *hpread_get_gntt (int, struct objfile *); + +static union dnttentry *hpread_get_lntt (int index, struct objfile *objfile); + + +static unsigned long hpread_get_textlow (int, int, struct objfile *, int); + +static struct partial_symtab *hpread_start_psymtab + (struct objfile *, char *, CORE_ADDR, int, + struct partial_symbol **, struct partial_symbol **); + +static struct partial_symtab *hpread_end_psymtab + (struct partial_symtab *, char **, int, int, CORE_ADDR, + struct partial_symtab **, int); + +static unsigned long hpread_get_scope_start (sltpointer, struct objfile *); + +static unsigned long hpread_get_line (sltpointer, struct objfile *); + +static CORE_ADDR hpread_get_location (sltpointer, struct objfile *); + +static int hpread_has_name (enum dntt_entry_type kind); + +static void hpread_psymtab_to_symtab_1 (struct partial_symtab *); + +static void hpread_psymtab_to_symtab (struct partial_symtab *); + +static struct symtab *hpread_expand_symtab + (struct objfile *, int, int, CORE_ADDR, int, + struct section_offsets *, char *); + +static int hpread_type_translate (dnttpointer); + +static struct type **hpread_lookup_type (dnttpointer, struct objfile *); + +static struct type *hpread_alloc_type (dnttpointer, struct objfile *); + +static struct type *hpread_read_enum_type + (dnttpointer, union dnttentry *, struct objfile *); + +static struct type *hpread_read_function_type + (dnttpointer, union dnttentry *, struct objfile *, int); + +static struct type *hpread_read_doc_function_type + (dnttpointer, union dnttentry *, struct objfile *, int); + +static struct type *hpread_read_struct_type + (dnttpointer, union dnttentry *, struct objfile *); + +static struct type *hpread_get_nth_template_arg (struct objfile *, int); + +static struct type *hpread_read_templ_arg_type + (dnttpointer, union dnttentry *, struct objfile *, char *); + +static struct type *hpread_read_set_type + (dnttpointer, union dnttentry *, struct objfile *); + +static struct type *hpread_read_array_type + (dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile); + +static struct type *hpread_read_subrange_type + (dnttpointer, union dnttentry *, struct objfile *); + +static struct type *hpread_type_lookup (dnttpointer, struct objfile *); + +static sltpointer hpread_record_lines + (struct subfile *, sltpointer, sltpointer, struct objfile *, CORE_ADDR); + +static void hpread_process_one_debug_symbol + (union dnttentry *, char *, struct section_offsets *, + struct objfile *, CORE_ADDR, int, char *, int, int *); + +static int hpread_get_scope_depth (union dnttentry *, struct objfile *, int); + +static void fix_static_member_physnames + (struct type *, char *, struct objfile *); + +static void fixup_class_method_type + (struct type *, struct type *, struct objfile *); + +static void hpread_adjust_bitoffsets (struct type *, int); + +static dnttpointer hpread_get_next_skip_over_anon_unions + (int, dnttpointer, union dnttentry **, struct objfile *); + + +/* Global to indicate presence of HP-compiled objects, + in particular, SOM executable file with SOM debug info + Defined in symtab.c, used in hppa-tdep.c. */ +extern int hp_som_som_object_present; + +/* Static used to indicate a class type that requires a + fix-up of one of its method types */ +static struct type *fixup_class = NULL; + +/* Static used to indicate the method type that is to be + used to fix-up the type for fixup_class */ +static struct type *fixup_method = NULL; + +#ifdef USE_PXDB + +/* NOTE use of system files! May not be portable. */ + +#define PXDB_SVR4 "/opt/langtools/bin/pxdb" +#define PXDB_BSD "/usr/bin/pxdb" + +#include +#include "gdb_string.h" + +/* check for the existence of a file, given its full pathname */ +static int +file_exists (char *filename) +{ + if (filename) + return (access (filename, F_OK) == 0); + return 0; +} + + +/* Translate from the "hp_language" enumeration in hp-symtab.h + used in the debug info to gdb's generic enumeration in defs.h. */ +static enum language +trans_lang (enum hp_language in_lang) +{ + if (in_lang == HP_LANGUAGE_C) + return language_c; + + else if (in_lang == HP_LANGUAGE_CPLUSPLUS) + return language_cplus; + + else if (in_lang == HP_LANGUAGE_FORTRAN) + return language_fortran; + + else + return language_unknown; +} + +static char main_string[] = "main"; + + +/* Given the native debug symbol SYM, set NAMEP to the name associated + with the debug symbol. Note we may be called with a debug symbol which + has no associated name, in that case we return an empty string. */ + +static void +set_namestring (union dnttentry *sym, char **namep, struct objfile *objfile) +{ + /* Note that we "know" that the name for any symbol is always in the same + place. Hence we don't have to conditionalize on the symbol type. */ + if (! hpread_has_name (sym->dblock.kind)) + *namep = ""; + else if ((unsigned) sym->dsfile.name >= VT_SIZE (objfile)) + { + complaint (&symfile_complaints, "bad string table offset in symbol %d", + symnum); + *namep = ""; + } + else + *namep = sym->dsfile.name + VT (objfile); +} + +/* Call PXDB to process our file. + + Approach copied from DDE's "dbgk_run_pxdb". Note: we + don't check for BSD location of pxdb, nor for existence + of pxdb itself, etc. + + NOTE: uses system function and string functions directly. + + Return value: 1 if ok, 0 if not */ +static int +hpread_call_pxdb (const char *file_name) +{ + char *p; + int status; + int retval; + + if (file_exists (PXDB_SVR4)) + { + p = xmalloc (strlen (PXDB_SVR4) + strlen (file_name) + 2); + strcpy (p, PXDB_SVR4); + strcat (p, " "); + strcat (p, file_name); + + warning ("File not processed by pxdb--about to process now.\n"); + status = system (p); + + retval = (status == 0); + } + else + { + warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name); + + retval = 0; + } + return retval; +} /* hpread_call_pxdb */ + + +/* Return 1 if the file turns out to need pre-processing + by PXDB, and we have thus called PXDB to do this processing + and the file therefore needs to be re-loaded. Otherwise + return 0. */ +static int +hpread_pxdb_needed (bfd *sym_bfd) +{ + asection *pinfo_section, *debug_section, *header_section; + unsigned int do_pxdb; + char *buf; + bfd_size_type header_section_size; + + unsigned long tmp; + unsigned int pxdbed; + + header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$"); + if (!header_section) + { + return 0; /* No header at all, can't recover... */ + } + + debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$"); + pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$"); + + if (pinfo_section && !debug_section) + { + /* Debug info with DOC, has different header format. + this only happens if the file was pxdbed and compiled optimized + otherwise the PINFO section is not there. */ + header_section_size = bfd_section_size (objfile->obfd, header_section); + + if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header)) + { + buf = alloca (sizeof (DOC_info_PXDB_header)); + memset (buf, 0, sizeof (DOC_info_PXDB_header)); + + if (!bfd_get_section_contents (sym_bfd, + header_section, + buf, 0, + header_section_size)) + error ("bfd_get_section_contents\n"); + + tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4)); + pxdbed = (tmp >> 31) & 0x1; + + if (!pxdbed) + error ("file debug header info invalid\n"); + do_pxdb = 0; + } + + else + error ("invalid $HEADER$ size in executable \n"); + } + + else + { + + /* this can be three different cases: + 1. pxdbed and not doc + - DEBUG and HEADER sections are there + - header is PXDB_header type + - pxdbed flag is set to 1 + + 2. not pxdbed and doc + - DEBUG and HEADER sections are there + - header is DOC_info_header type + - pxdbed flag is set to 0 + + 3. not pxdbed and not doc + - DEBUG and HEADER sections are there + - header is XDB_header type + - pxdbed flag is set to 0 + + NOTE: the pxdbed flag is meaningful also in the not + already pxdb processed version of the header, + because in case on non-already processed by pxdb files + that same bit in the header would be always zero. + Why? Because the bit is the leftmost bit of a word + which contains a 'length' which is always a positive value + so that bit is never set to 1 (otherwise it would be negative) + + Given the above, we have two choices : either we ignore the + size of the header itself and just look at the pxdbed field, + or we check the size and then we (for safety and paranoia related + issues) check the bit. + The first solution is used by DDE, the second by PXDB itself. + I am using the second one here, because I already wrote it, + and it is the end of a long day. + Also, using the first approach would still involve size issues + because we need to read in the contents of the header section, and + give the correct amount of stuff we want to read to the + get_bfd_section_contents function. */ + + /* decide which case depending on the size of the header section. + The size is as defined in hp-symtab.h */ + + header_section_size = bfd_section_size (objfile->obfd, header_section); + + if (header_section_size == (bfd_size_type) sizeof (PXDB_header)) /* pxdb and not doc */ + { + + buf = alloca (sizeof (PXDB_header)); + memset (buf, 0, sizeof (PXDB_header)); + if (!bfd_get_section_contents (sym_bfd, + header_section, + buf, 0, + header_section_size)) + error ("bfd_get_section_contents\n"); + + tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3)); + pxdbed = (tmp >> 31) & 0x1; + + if (pxdbed) + do_pxdb = 0; + else + error ("file debug header invalid\n"); + } + else /*not pxdbed and doc OR not pxdbed and non doc */ + do_pxdb = 1; + } + + if (do_pxdb) + { + return 1; + } + else + { + return 0; + } +} /* hpread_pxdb_needed */ + +#endif + +/* Check whether the file needs to be preprocessed by pxdb. + If so, call pxdb. */ + +void +do_pxdb (bfd *sym_bfd) +{ + /* The following code is HP-specific. The "right" way of + doing this is unknown, but we bet would involve a target- + specific pre-file-load check using a generic mechanism. */ + + /* This code will not be executed if the file is not in SOM + format (i.e. if compiled with gcc) */ + if (hpread_pxdb_needed (sym_bfd)) + { + /*This file has not been pre-processed. Preprocess now */ + + if (hpread_call_pxdb (sym_bfd->filename)) + { + /* The call above has changed the on-disk file, + we can close the file anyway, because the + symbols will be reread in when the target is run */ + bfd_close (sym_bfd); + } + } +} + + + +#ifdef QUICK_LOOK_UP + +/* Code to handle quick lookup-tables follows. */ + + +/* Some useful macros */ +#define VALID_FILE(i) ((i) < pxdb_header_p->fd_entries) +#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries) +#define VALID_PROC(i) ((i) < pxdb_header_p->pd_entries) +#define VALID_CLASS(i) ((i) < pxdb_header_p->cd_entries) + +#define FILE_START(i) (qFD[i].adrStart) +#define MODULE_START(i) (qMD[i].adrStart) +#define PROC_START(i) (qPD[i].adrStart) + +#define FILE_END(i) (qFD[i].adrEnd) +#define MODULE_END(i) (qMD[i].adrEnd) +#define PROC_END(i) (qPD[i].adrEnd) + +#define FILE_ISYM(i) (qFD[i].isym) +#define MODULE_ISYM(i) (qMD[i].isym) +#define PROC_ISYM(i) (qPD[i].isym) + +#define VALID_CURR_FILE (curr_fd < pxdb_header_p->fd_entries) +#define VALID_CURR_MODULE (curr_md < pxdb_header_p->md_entries) +#define VALID_CURR_PROC (curr_pd < pxdb_header_p->pd_entries) +#define VALID_CURR_CLASS (curr_cd < pxdb_header_p->cd_entries) + +#define CURR_FILE_START (qFD[curr_fd].adrStart) +#define CURR_MODULE_START (qMD[curr_md].adrStart) +#define CURR_PROC_START (qPD[curr_pd].adrStart) + +#define CURR_FILE_END (qFD[curr_fd].adrEnd) +#define CURR_MODULE_END (qMD[curr_md].adrEnd) +#define CURR_PROC_END (qPD[curr_pd].adrEnd) + +#define CURR_FILE_ISYM (qFD[curr_fd].isym) +#define CURR_MODULE_ISYM (qMD[curr_md].isym) +#define CURR_PROC_ISYM (qPD[curr_pd].isym) + +#define TELL_OBJFILE \ + do { \ + if( !told_objfile ) { \ + told_objfile = 1; \ + warning ("\nIn object file \"%s\":\n", \ + objfile->name); \ + } \ + } while (0) + + + +/* Keeping track of the start/end symbol table (LNTT) indices of + psymtabs created so far */ + +typedef struct +{ + int start; + int end; +} +pst_syms_struct; + +static pst_syms_struct *pst_syms_array = 0; + +static int pst_syms_count = 0; +static int pst_syms_size = 0; + +/* used by the TELL_OBJFILE macro */ +static int told_objfile = 0; + +/* Set up psymtab symbol index stuff */ +static void +init_pst_syms (void) +{ + pst_syms_count = 0; + pst_syms_size = 20; + pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct)); +} + +/* Clean up psymtab symbol index stuff */ +static void +clear_pst_syms (void) +{ + pst_syms_count = 0; + pst_syms_size = 0; + xfree (pst_syms_array); + pst_syms_array = 0; +} + +/* Add information about latest psymtab to symbol index table */ +static void +record_pst_syms (int start_sym, int end_sym) +{ + if (++pst_syms_count > pst_syms_size) + { + pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array, + 2 * pst_syms_size * sizeof (pst_syms_struct)); + pst_syms_size *= 2; + } + pst_syms_array[pst_syms_count - 1].start = start_sym; + pst_syms_array[pst_syms_count - 1].end = end_sym; +} + +/* Find a suitable symbol table index which can serve as the upper + bound of a psymtab that starts at INDEX + + This scans backwards in the psymtab symbol index table to find a + "hole" in which the given index can fit. This is a heuristic!! + We don't search the entire table to check for multiple holes, + we don't care about overlaps, etc. + + Return 0 => not found */ +static int +find_next_pst_start (int index) +{ + int i; + + for (i = pst_syms_count - 1; i >= 0; i--) + if (pst_syms_array[i].end <= index) + return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1; + + if (pst_syms_array[0].start > index) + return pst_syms_array[0].start - 1; + + return 0; +} + + + +/* Utility functions to find the ending symbol index for a psymtab */ + +/* Find the next file entry that begins beyond INDEX, and return + its starting symbol index - 1. + QFD is the file table, CURR_FD is the file entry from where to start, + PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work). + + Return 0 => not found */ +static int +find_next_file_isym (int index, quick_file_entry *qFD, int curr_fd, + PXDB_header_ptr pxdb_header_p) +{ + while (VALID_CURR_FILE) + { + if (CURR_FILE_ISYM >= index) + return CURR_FILE_ISYM - 1; + curr_fd++; + } + return 0; +} + +/* Find the next procedure entry that begins beyond INDEX, and return + its starting symbol index - 1. + QPD is the procedure table, CURR_PD is the proc entry from where to start, + PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work). + + Return 0 => not found */ +static int +find_next_proc_isym (int index, quick_procedure_entry *qPD, int curr_pd, + PXDB_header_ptr pxdb_header_p) +{ + while (VALID_CURR_PROC) + { + if (CURR_PROC_ISYM >= index) + return CURR_PROC_ISYM - 1; + curr_pd++; + } + return 0; +} + +/* Find the next module entry that begins beyond INDEX, and return + its starting symbol index - 1. + QMD is the module table, CURR_MD is the modue entry from where to start, + PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work). + + Return 0 => not found */ +static int +find_next_module_isym (int index, quick_module_entry *qMD, int curr_md, + PXDB_header_ptr pxdb_header_p) +{ + while (VALID_CURR_MODULE) + { + if (CURR_MODULE_ISYM >= index) + return CURR_MODULE_ISYM - 1; + curr_md++; + } + return 0; +} + +/* Scan and record partial symbols for all functions starting from index + pointed to by CURR_PD_P, and between code addresses START_ADR and END_ADR. + Other parameters are explained in comments below. */ + +/* This used to be inline in hpread_quick_traverse, but now that we do + essentially the same thing for two different cases (modules and + module-less files), it's better organized in a separate routine, + although it does take lots of arguments. pai/1997-10-08 + + CURR_PD_P is the pointer to the current proc index. QPD is the + procedure quick lookup table. MAX_PROCS is the number of entries + in the proc. table. START_ADR is the beginning of the code range + for the current psymtab. end_adr is the end of the code range for + the current psymtab. PST is the current psymtab. VT_bits is + a pointer to the strings table of SOM debug space. OBJFILE is + the current object file. */ + +static int +scan_procs (int *curr_pd_p, quick_procedure_entry *qPD, int max_procs, + CORE_ADDR start_adr, CORE_ADDR end_adr, struct partial_symtab *pst, + char *vt_bits, struct objfile *objfile) +{ + union dnttentry *dn_bufp; + int symbol_count = 0; /* Total number of symbols in this psymtab */ + int curr_pd = *curr_pd_p; /* Convenience variable -- avoid dereferencing pointer all the time */ + +#ifdef DUMPING + /* Turn this on for lots of debugging information in this routine */ + static int dumping = 0; +#endif + +#ifdef DUMPING + if (dumping) + { + printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd); + } +#endif + + while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs)) + { + + char *rtn_name; /* mangled name */ + char *rtn_dem_name; /* qualified demangled name */ + char *class_name; + int class; + + if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) && + vt_bits[(long) qPD[curr_pd].sbAlias]) /* not a null string */ + { + /* Get mangled name for the procedure, and demangle it */ + rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias]; + rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS); + } + else + { + rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc]; + rtn_dem_name = NULL; + } + + /* Hack to get around HP C/C++ compilers' insistence on providing + "_MAIN_" as an alternate name for "main" */ + if ((strcmp (rtn_name, "_MAIN_") == 0) && + (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0)) + rtn_dem_name = rtn_name = main_string; + +#ifdef DUMPING + if (dumping) + { + printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd); + } +#endif + + /* Check for module-spanning routines. */ + if (CURR_PROC_END > end_adr) + { + TELL_OBJFILE; + warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd); + } + + /* Add this routine symbol to the list in the objfile. + Unfortunately we have to go to the LNTT to determine the + correct list to put it on. An alternative (which the + code used to do) would be to not check and always throw + it on the "static" list. But if we go that route, then + symbol_lookup() needs to be tweaked a bit to account + for the fact that the function might not be found on + the correct list in the psymtab. - RT */ + dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile); + if (dn_bufp->dfunc.global) + add_psymbol_with_dem_name_to_list (rtn_name, + strlen (rtn_name), + rtn_dem_name, + strlen (rtn_dem_name), + VAR_DOMAIN, + LOC_BLOCK, /* "I am a routine" */ + &objfile->global_psymbols, + (qPD[curr_pd].adrStart + /* Starting address of rtn */ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))), + 0, /* core addr?? */ + trans_lang ((enum hp_language) qPD[curr_pd].language), + objfile); + else + add_psymbol_with_dem_name_to_list (rtn_name, + strlen (rtn_name), + rtn_dem_name, + strlen (rtn_dem_name), + VAR_DOMAIN, + LOC_BLOCK, /* "I am a routine" */ + &objfile->static_psymbols, + (qPD[curr_pd].adrStart + /* Starting address of rtn */ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))), + 0, /* core addr?? */ + trans_lang ((enum hp_language) qPD[curr_pd].language), + objfile); + + symbol_count++; + *curr_pd_p = ++curr_pd; /* bump up count & reflect in caller */ + } /* loop over procedures */ + +#ifdef DUMPING + if (dumping) + { + if (symbol_count == 0) + printf ("Scan_procs: no symbols found!\n"); + } +#endif + + return symbol_count; +} + + +/* Traverse the quick look-up tables, building a set of psymtabs. + + This constructs a psymtab for modules and files in the quick lookup + tables. + + Mostly, modules correspond to compilation units, so we try to + create psymtabs that correspond to modules; however, in some cases + a file can result in a compiled object which does not have a module + entry for it, so in such cases we create a psymtab for the file. */ + +static int +hpread_quick_traverse (struct objfile *objfile, char *gntt_bits, + char *vt_bits, PXDB_header_ptr pxdb_header_p) +{ + struct partial_symtab *pst; + + char *addr; + + quick_procedure_entry *qPD; + quick_file_entry *qFD; + quick_module_entry *qMD; + quick_class_entry *qCD; + + int idx; + int i; + CORE_ADDR start_adr; /* current psymtab's starting code addr */ + CORE_ADDR end_adr; /* current psymtab's ending code addr */ + CORE_ADDR next_mod_adr; /* next module's starting code addr */ + int curr_pd; /* current procedure */ + int curr_fd; /* current file */ + int curr_md; /* current module */ + int start_sym; /* current psymtab's starting symbol index */ + int end_sym; /* current psymtab's ending symbol index */ + int max_LNTT_sym_index; + int syms_in_pst; + B_TYPE *class_entered; + + struct partial_symbol **global_syms; /* We'll be filling in the "global" */ + struct partial_symbol **static_syms; /* and "static" tables in the objfile + as we go, so we need a pair of + current pointers. */ + +#ifdef DUMPING + /* Turn this on for lots of debugging information in this routine. + You get a blow-by-blow account of quick lookup table reading */ + static int dumping = 0; +#endif + + pst = (struct partial_symtab *) 0; + + /* Clear out some globals */ + init_pst_syms (); + told_objfile = 0; + + /* Demangling style -- if EDG style already set, don't change it, + as HP style causes some problems with the KAI EDG compiler */ + if (current_demangling_style != edg_demangling) + { + /* Otherwise, ensure that we are using HP style demangling */ + set_demangling_style (HP_DEMANGLING_STYLE_STRING); + } + + /* First we need to find the starting points of the quick + look-up tables in the GNTT. */ + + addr = gntt_bits; + + qPD = (quick_procedure_entry_ptr) addr; + addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry); + +#ifdef DUMPING + if (dumping) + { + printf ("\n Printing routines as we see them\n"); + for (i = 0; VALID_PROC (i); i++) + { + idx = (long) qPD[i].sbProc; + printf ("%s %x..%x\n", &vt_bits[idx], + (int) PROC_START (i), + (int) PROC_END (i)); + } + } +#endif + + qFD = (quick_file_entry_ptr) addr; + addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry); + +#ifdef DUMPING + if (dumping) + { + printf ("\n Printing files as we see them\n"); + for (i = 0; VALID_FILE (i); i++) + { + idx = (long) qFD[i].sbFile; + printf ("%s %x..%x\n", &vt_bits[idx], + (int) FILE_START (i), + (int) FILE_END (i)); + } + } +#endif + + qMD = (quick_module_entry_ptr) addr; + addr += pxdb_header_p->md_entries * sizeof (quick_module_entry); + +#ifdef DUMPING + if (dumping) + { + printf ("\n Printing modules as we see them\n"); + for (i = 0; i < pxdb_header_p->md_entries; i++) + { + idx = (long) qMD[i].sbMod; + printf ("%s\n", &vt_bits[idx]); + } + } +#endif + + qCD = (quick_class_entry_ptr) addr; + addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry); + +#ifdef DUMPING + if (dumping) + { + printf ("\n Printing classes as we see them\n"); + for (i = 0; VALID_CLASS (i); i++) + { + idx = (long) qCD[i].sbClass; + printf ("%s\n", &vt_bits[idx]); + } + + printf ("\n Done with dump, on to build!\n"); + } +#endif + + /* We need this index only while hp-symtab-read.c expects + a byte offset to the end of the LNTT entries for a given + psymtab. Thus the need for it should go away someday. + + When it goes away, then we won't have any need to load the + LNTT from the objfile at psymtab-time, and start-up will be + faster. To make that work, we'll need some way to create + a null pst for the "globals" pseudo-module. */ + max_LNTT_sym_index = LNTT_SYMCOUNT (objfile); + + /* Scan the module descriptors and make a psymtab for each. + + We know the MDs, FDs and the PDs are in order by starting + address. We use that fact to traverse all three arrays in + parallel, knowing when the next PD is in a new file + and we need to create a new psymtab. */ + curr_pd = 0; /* Current procedure entry */ + curr_fd = 0; /* Current file entry */ + curr_md = 0; /* Current module entry */ + + start_adr = 0; /* Current psymtab code range */ + end_adr = 0; + + start_sym = 0; /* Current psymtab symbol range */ + end_sym = 0; + + syms_in_pst = 0; /* Symbol count for psymtab */ + + /* Psts actually just have pointers into the objfile's + symbol table, not their own symbol tables. */ + global_syms = objfile->global_psymbols.list; + static_syms = objfile->static_psymbols.list; + + + /* First skip over pseudo-entries with address 0. These represent inlined + routines and abstract (uninstantiated) template routines. + FIXME: These should be read in and available -- even if we can't set + breakpoints, etc., there's some information that can be presented + to the user. pai/1997-10-08 */ + + while (VALID_CURR_PROC && (CURR_PROC_START == 0)) + curr_pd++; + + /* Loop over files, modules, and procedures in code address order. Each + time we enter an iteration of this loop, curr_pd points to the first + unprocessed procedure, curr_fd points to the first unprocessed file, and + curr_md to the first unprocessed module. Each iteration of this loop + updates these as required -- any or all of them may be bumpd up + each time around. When we exit this loop, we are done with all files + and modules in the tables -- there may still be some procedures, however. + + Note: This code used to loop only over module entries, under the assumption + that files can occur via inclusions and are thus unreliable, while a + compiled object always corresponds to a module. With CTTI in the HP aCC + compiler, it turns out that compiled objects may have only files and no + modules; so we have to loop over files and modules, creating psymtabs for + either as appropriate. Unfortunately there are some problems (notably: + 1. the lack of "SRC_FILE_END" entries in the LNTT, 2. the lack of pointers + to the ending symbol indices of a module or a file) which make it quite hard + to do this correctly. Currently it uses a bunch of heuristics to start and + end psymtabs; they seem to work well with most objects generated by aCC, but + who knows when that will change... */ + + while (VALID_CURR_FILE || VALID_CURR_MODULE) + { + + char *mod_name_string = NULL; + char *full_name_string; + + /* First check for modules like "version.c", which have no code + in them but still have qMD entries. They also have no qFD or + qPD entries. Their start address is -1 and their end address + is 0. */ + if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0)) + { + + mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod]; + +#ifdef DUMPING + if (dumping) + printf ("Module with data only %s\n", mod_name_string); +#endif + + /* We'll skip the rest (it makes error-checking easier), and + just make an empty pst. Right now empty psts are not put + in the pst chain, so all this is for naught, but later it + might help. */ + + pst = hpread_start_psymtab (objfile, + mod_name_string, + CURR_MODULE_START, /* Low text address: bogus! */ + (CURR_MODULE_ISYM * sizeof (struct dntt_type_block)), + /* ldsymoff */ + global_syms, + static_syms); + + pst = hpread_end_psymtab (pst, + NULL, /* psymtab_include_list */ + 0, /* includes_used */ + end_sym * sizeof (struct dntt_type_block), + /* byte index in LNTT of end + = capping symbol offset + = LDSYMOFF of nextfile */ + 0, /* text high */ + NULL, /* dependency_list */ + 0); /* dependencies_used */ + + global_syms = objfile->global_psymbols.next; + static_syms = objfile->static_psymbols.next; + + curr_md++; + } + else if (VALID_CURR_MODULE && + ((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) || + (CURR_MODULE_END == 0) || (CURR_MODULE_END == -1))) + { + TELL_OBJFILE; + warning ("Module \"%s\" [0x%s] has non-standard addresses. It starts at 0x%s, ends at 0x%s, and will be skipped.", + mod_name_string, paddr_nz (curr_md), paddr_nz (start_adr), paddr_nz (end_adr)); + /* On to next module */ + curr_md++; + } + else + { + /* First check if we are looking at a file with code in it + that does not overlap the current module's code range */ + + if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0) + { + + /* Looking at file not corresponding to any module, + create a psymtab for it */ + full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile]; + start_adr = CURR_FILE_START; + end_adr = CURR_FILE_END; + start_sym = CURR_FILE_ISYM; + + /* Check if there are any procedures not handled until now, that + begin before the start address of this file, and if so, adjust + this module's start address to include them. This handles routines that + are in between file or module ranges for some reason (probably + indicates a compiler bug */ + + if (CURR_PROC_START < start_adr) + { + TELL_OBJFILE; + warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.", + &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd); + start_adr = CURR_PROC_START; + if (CURR_PROC_ISYM < start_sym) + start_sym = CURR_PROC_ISYM; + } + + /* Sometimes (compiler bug -- COBOL) the module end address is higher + than the start address of the next module, so check for that and + adjust accordingly */ + + if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr)) + { + TELL_OBJFILE; + warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.", + full_name_string, curr_fd); + end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */ + } + if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr)) + { + TELL_OBJFILE; + warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.", + full_name_string, curr_fd); + end_adr = CURR_MODULE_START - 1; /* Is -4 (or -8 for 64-bit) better? */ + } + + +#ifdef DUMPING + if (dumping) + { + printf ("Make new psymtab for file %s (%x to %x).\n", + full_name_string, start_adr, end_adr); + } +#endif + /* Create the basic psymtab, connecting it in the list + for this objfile and pointing its symbol entries + to the current end of the symbol areas in the objfile. + + The "ldsymoff" parameter is the byte offset in the LNTT + of the first symbol in this file. Some day we should + turn this into an index (fix in hp-symtab-read.c as well). + And it's not even the right byte offset, as we're using + the size of a union! FIXME! */ + pst = hpread_start_psymtab (objfile, + full_name_string, + start_adr, /* Low text address */ + (start_sym * sizeof (struct dntt_type_block)), + /* ldsymoff */ + global_syms, + static_syms); + + /* Set up to only enter each class referenced in this module once. */ + class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries)); + B_CLRALL (class_entered, pxdb_header_p->cd_entries); + + /* Scan the procedure descriptors for procedures in the current + file, based on the starting addresses. */ + + syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries, + start_adr, end_adr, pst, vt_bits, objfile); + + /* Get ending symbol offset */ + + end_sym = 0; + /* First check for starting index before previous psymtab */ + if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end) + { + end_sym = find_next_pst_start (start_sym); + } + /* Look for next start index of a file or module, or procedure */ + if (!end_sym) + { + int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p); + int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p); + int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p); + + if (next_file_isym && next_module_isym) + { + /* pick lower of next file or module start index */ + end_sym = min (next_file_isym, next_module_isym); + } + else + { + /* one of them is zero, pick the other */ + end_sym = max (next_file_isym, next_module_isym); + } + + /* As a precaution, check next procedure index too */ + if (!end_sym) + end_sym = next_proc_isym; + else + end_sym = min (end_sym, next_proc_isym); + } + + /* Couldn't find procedure, file, or module, use globals as default */ + if (!end_sym) + end_sym = pxdb_header_p->globals; + +#ifdef DUMPING + if (dumping) + { + printf ("File psymtab indices: %x to %x\n", start_sym, end_sym); + } +#endif + + pst = hpread_end_psymtab (pst, + NULL, /* psymtab_include_list */ + 0, /* includes_used */ + end_sym * sizeof (struct dntt_type_block), + /* byte index in LNTT of end + = capping symbol offset + = LDSYMOFF of nextfile */ + end_adr, /* text high */ + NULL, /* dependency_list */ + 0); /* dependencies_used */ + + record_pst_syms (start_sym, end_sym); + + if (NULL == pst) + warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd); + +#ifdef DUMPING + if (dumping) + { + printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n", + full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym); + } +#endif + /* Prepare for the next psymtab. */ + global_syms = objfile->global_psymbols.next; + static_syms = objfile->static_psymbols.next; + xfree (class_entered); + + curr_fd++; + } /* Psymtab for file */ + else + { + /* We have a module for which we create a psymtab */ + + mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod]; + + /* We will include the code ranges of any files that happen to + overlap with this module */ + + /* So, first pick the lower of the file's and module's start addresses */ + start_adr = CURR_MODULE_START; + if (VALID_CURR_FILE) + { + if (CURR_FILE_START < CURR_MODULE_START) + { + TELL_OBJFILE; + warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".", + &vt_bits[(long) qFD[curr_fd].sbFile], + curr_fd, mod_name_string); + + start_adr = CURR_FILE_START; + } + } + + /* Also pick the lower of the file's and the module's start symbol indices */ + start_sym = CURR_MODULE_ISYM; + if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM)) + start_sym = CURR_FILE_ISYM; + + /* For the end address, we scan through the files till we find one + that overlaps the current module but ends beyond it; if no such file exists we + simply use the module's start address. + (Note, if file entries themselves overlap + we take the longest overlapping extension beyond the end of the module...) + We assume that modules never overlap. */ + + end_adr = CURR_MODULE_END; + + if (VALID_CURR_FILE) + { + while (VALID_CURR_FILE && (CURR_FILE_START < end_adr)) + { + +#ifdef DUMPING + if (dumping) + printf ("Maybe skipping file %s which overlaps with module %s\n", + &vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string); +#endif + if (CURR_FILE_END > end_adr) + { + TELL_OBJFILE; + warning ("File \"%s\" [0x%x] crosses end of module \"%s\".", + &vt_bits[(long) qFD[curr_fd].sbFile], + curr_fd, mod_name_string); + end_adr = CURR_FILE_END; + } + curr_fd++; + } + curr_fd--; /* back up after going too far */ + } + + /* Sometimes (compiler bug -- COBOL) the module end address is higher + than the start address of the next module, so check for that and + adjust accordingly */ + + if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr)) + { + TELL_OBJFILE; + warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.", + mod_name_string, curr_md); + end_adr = MODULE_START (curr_md + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */ + } + if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr)) + { + TELL_OBJFILE; + warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.", + mod_name_string, curr_md); + end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */ + } + + /* Use one file to get the full name for the module. This + situation can arise if there is executable code in a #include + file. Each file with code in it gets a qFD. Files which don't + contribute code don't get a qFD, even if they include files + which do, e.g.: + + body.c: rtn.h: + int x; int main() { + #include "rtn.h" return x; + } + + There will a qFD for "rtn.h",and a qMD for "body.c", + but no qMD for "rtn.h" or qFD for "body.c"! + + We pick the name of the last file to overlap with this + module. C convention is to put include files first. In a + perfect world, we could check names and use the file whose full + path name ends with the module name. */ + + if (VALID_CURR_FILE) + full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile]; + else + full_name_string = mod_name_string; + + /* Check if there are any procedures not handled until now, that + begin before the start address we have now, and if so, adjust + this psymtab's start address to include them. This handles routines that + are in between file or module ranges for some reason (probably + indicates a compiler bug */ + + if (CURR_PROC_START < start_adr) + { + TELL_OBJFILE; + warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.", + &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd); + start_adr = CURR_PROC_START; + if (CURR_PROC_ISYM < start_sym) + start_sym = CURR_PROC_ISYM; + } + +#ifdef DUMPING + if (dumping) + { + printf ("Make new psymtab for module %s (%x to %x), using file %s\n", + mod_name_string, start_adr, end_adr, full_name_string); + } +#endif + /* Create the basic psymtab, connecting it in the list + for this objfile and pointing its symbol entries + to the current end of the symbol areas in the objfile. + + The "ldsymoff" parameter is the byte offset in the LNTT + of the first symbol in this file. Some day we should + turn this into an index (fix in hp-symtab-read.c as well). + And it's not even the right byte offset, as we're using + the size of a union! FIXME! */ + pst = hpread_start_psymtab (objfile, + full_name_string, + start_adr, /* Low text address */ + (start_sym * sizeof (struct dntt_type_block)), + /* ldsymoff */ + global_syms, + static_syms); + + /* Set up to only enter each class referenced in this module once. */ + class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries)); + B_CLRALL (class_entered, pxdb_header_p->cd_entries); + + /* Scan the procedure descriptors for procedures in the current + module, based on the starting addresses. */ + + syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries, + start_adr, end_adr, pst, vt_bits, objfile); + + /* Get ending symbol offset */ + + end_sym = 0; + /* First check for starting index before previous psymtab */ + if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end) + { + end_sym = find_next_pst_start (start_sym); + } + /* Look for next start index of a file or module, or procedure */ + if (!end_sym) + { + int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p); + int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p); + int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p); + + if (next_file_isym && next_module_isym) + { + /* pick lower of next file or module start index */ + end_sym = min (next_file_isym, next_module_isym); + } + else + { + /* one of them is zero, pick the other */ + end_sym = max (next_file_isym, next_module_isym); + } + + /* As a precaution, check next procedure index too */ + if (!end_sym) + end_sym = next_proc_isym; + else + end_sym = min (end_sym, next_proc_isym); + } + + /* Couldn't find procedure, file, or module, use globals as default */ + if (!end_sym) + end_sym = pxdb_header_p->globals; + +#ifdef DUMPING + if (dumping) + { + printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym); + } +#endif + + pst = hpread_end_psymtab (pst, + NULL, /* psymtab_include_list */ + 0, /* includes_used */ + end_sym * sizeof (struct dntt_type_block), + /* byte index in LNTT of end + = capping symbol offset + = LDSYMOFF of nextfile */ + end_adr, /* text high */ + NULL, /* dependency_list */ + 0); /* dependencies_used */ + + record_pst_syms (start_sym, end_sym); + + if (NULL == pst) + warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md); + +#ifdef DUMPING + if (dumping) + { + printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n", + mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym); + } +#endif + + /* Prepare for the next psymtab. */ + global_syms = objfile->global_psymbols.next; + static_syms = objfile->static_psymbols.next; + xfree (class_entered); + + curr_md++; + curr_fd++; + } /* psymtab for module */ + } /* psymtab for non-bogus file or module */ + } /* End of while loop over all files & modules */ + + /* There may be some routines after all files and modules -- these will get + inserted in a separate new module of their own */ + if (VALID_CURR_PROC) + { + start_adr = CURR_PROC_START; + end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd; + TELL_OBJFILE; + warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd); +#ifdef DUMPING + if (dumping) + { + printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n", + curr_pd, start_adr, end_adr); + } +#endif + pst = hpread_start_psymtab (objfile, + "orphans", + start_adr, /* Low text address */ + (CURR_PROC_ISYM * sizeof (struct dntt_type_block)), + /* ldsymoff */ + global_syms, + static_syms); + + scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries, + start_adr, end_adr, pst, vt_bits, objfile); + + pst = hpread_end_psymtab (pst, + NULL, /* psymtab_include_list */ + 0, /* includes_used */ + pxdb_header_p->globals * sizeof (struct dntt_type_block), + /* byte index in LNTT of end + = capping symbol offset + = LDSYMOFF of nextfile */ + end_adr, /* text high */ + NULL, /* dependency_list */ + 0); /* dependencies_used */ + } + + +#ifdef NEVER_NEVER + /* Now build psts for non-module things (in the tail of + the LNTT, after the last END MODULE entry). + + If null psts were kept on the chain, this would be + a solution. FIXME */ + pst = hpread_start_psymtab (objfile, + "globals", + 0, + (pxdb_header_p->globals + * sizeof (struct dntt_type_block)), + objfile->global_psymbols.next, + objfile->static_psymbols.next); + hpread_end_psymtab (pst, + NULL, 0, + (max_LNTT_sym_index * sizeof (struct dntt_type_block)), + 0, + NULL, 0); +#endif + + clear_pst_syms (); + + return 1; + +} /* End of hpread_quick_traverse. */ + + +/* Get appropriate header, based on pxdb type. + Return value: 1 if ok, 0 if not */ +static int +hpread_get_header (struct objfile *objfile, PXDB_header_ptr pxdb_header_p) +{ + asection *pinfo_section, *debug_section, *header_section; + +#ifdef DUMPING + /* Turn on for debugging information */ + static int dumping = 0; +#endif + + header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$"); + if (!header_section) + { + /* We don't have either PINFO or DEBUG sections. But + stuff like "libc.sl" has no debug info. There's no + need to warn the user of this, as it may be ok. The + caller will figure it out and issue any needed + messages. */ +#ifdef DUMPING + if (dumping) + printf ("==No debug info at all for %s.\n", objfile->name); +#endif + + return 0; + } + + /* We would like either a $DEBUG$ or $PINFO$ section. + Once we know which, we can understand the header + data (which we have defined to suit the more common + $DEBUG$ case). */ + debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$"); + pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$"); + if (debug_section) + { + /* The expected case: normal pxdb header. */ + bfd_get_section_contents (objfile->obfd, header_section, + pxdb_header_p, 0, sizeof (PXDB_header)); + + if (!pxdb_header_p->pxdbed) + { + /* This shouldn't happen if we check in "symfile.c". */ + return 0; + } /* DEBUG section */ + } + + else if (pinfo_section) + { + /* The DOC case; we need to translate this into a + regular header. */ + DOC_info_PXDB_header doc_header; + +#ifdef DUMPING + if (dumping) + { + printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name); + } +#endif + + bfd_get_section_contents (objfile->obfd, + header_section, + &doc_header, 0, + sizeof (DOC_info_PXDB_header)); + + if (!doc_header.pxdbed) + { + /* This shouldn't happen if we check in "symfile.c". */ + warning ("File \"%s\" not processed by pxdb!", objfile->name); + return 0; + } + + /* Copy relevent fields to standard header passed in. */ + pxdb_header_p->pd_entries = doc_header.pd_entries; + pxdb_header_p->fd_entries = doc_header.fd_entries; + pxdb_header_p->md_entries = doc_header.md_entries; + pxdb_header_p->pxdbed = doc_header.pxdbed; + pxdb_header_p->bighdr = doc_header.bighdr; + pxdb_header_p->sa_header = doc_header.sa_header; + pxdb_header_p->inlined = doc_header.inlined; + pxdb_header_p->globals = doc_header.globals; + pxdb_header_p->time = doc_header.time; + pxdb_header_p->pg_entries = doc_header.pg_entries; + pxdb_header_p->functions = doc_header.functions; + pxdb_header_p->files = doc_header.files; + pxdb_header_p->cd_entries = doc_header.cd_entries; + pxdb_header_p->aa_entries = doc_header.aa_entries; + pxdb_header_p->oi_entries = doc_header.oi_entries; + pxdb_header_p->version = doc_header.version; + } /* PINFO section */ + + else + { +#ifdef DUMPING + if (dumping) + printf ("==No debug info at all for %s.\n", objfile->name); +#endif + + return 0; + + } + + return 1; +} /* End of hpread_get_header */ +#endif /* QUICK_LOOK_UP */ + + +/* Initialization for reading native HP C debug symbols from OBJFILE. + + Its only purpose in life is to set up the symbol reader's private + per-objfile data structures, and read in the raw contents of the debug + sections (attaching pointers to the debug info into the private data + structures). + + Since BFD doesn't know how to read debug symbols in a format-independent + way (and may never do so...), we have to do it ourselves. Note we may + be called on a file without native HP C debugging symbols. + + FIXME, there should be a cleaner peephole into the BFD environment + here. */ +void +hpread_symfile_init (struct objfile *objfile) +{ + asection *vt_section, *slt_section, *lntt_section, *gntt_section; + + /* Allocate struct to keep track of the symfile */ + objfile->sym_private = + xmmalloc (objfile->md, sizeof (struct hpread_symfile_info)); + memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info)); + + /* We haven't read in any types yet. */ + DNTT_TYPE_VECTOR (objfile) = 0; + + /* Read in data from the $GNTT$ subspace. */ + gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$"); + if (!gntt_section) + return; + + GNTT (objfile) + = obstack_alloc (&objfile->objfile_obstack, + bfd_section_size (objfile->obfd, gntt_section)); + + bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile), + 0, bfd_section_size (objfile->obfd, gntt_section)); + + GNTT_SYMCOUNT (objfile) + = bfd_section_size (objfile->obfd, gntt_section) + / sizeof (struct dntt_type_block); + + /* Read in data from the $LNTT$ subspace. Also keep track of the number + of LNTT symbols. + + FIXME: this could be moved into the psymtab-to-symtab expansion + code, and save startup time. At the moment this data is + still used, though. We'd need a way to tell hp-symtab-read.c + whether or not to load the LNTT. */ + lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$"); + if (!lntt_section) + return; + + LNTT (objfile) + = obstack_alloc (&objfile->objfile_obstack, + bfd_section_size (objfile->obfd, lntt_section)); + + bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile), + 0, bfd_section_size (objfile->obfd, lntt_section)); + + LNTT_SYMCOUNT (objfile) + = bfd_section_size (objfile->obfd, lntt_section) + / sizeof (struct dntt_type_block); + + /* Read in data from the $SLT$ subspace. $SLT$ contains information + on source line numbers. */ + slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$"); + if (!slt_section) + return; + + SLT (objfile) = + obstack_alloc (&objfile->objfile_obstack, + bfd_section_size (objfile->obfd, slt_section)); + + bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile), + 0, bfd_section_size (objfile->obfd, slt_section)); + + /* Read in data from the $VT$ subspace. $VT$ contains things like + names and constants. Keep track of the number of symbols in the VT. */ + vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$"); + if (!vt_section) + return; + + VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section); + + VT (objfile) = + (char *) obstack_alloc (&objfile->objfile_obstack, + VT_SIZE (objfile)); + + bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile), + 0, VT_SIZE (objfile)); +} + +/* Scan and build partial symbols for a symbol file. + + The minimal symbol table (either SOM or HP a.out) has already been + read in; all we need to do is setup partial symbols based on the + native debugging information. + + Note that the minimal table is produced by the linker, and has + only global routines in it; the psymtab is based on compiler- + generated debug information and has non-global + routines in it as well as files and class information. + + We assume hpread_symfile_init has been called to initialize the + symbol reader's private data structures. + + MAINLINE is true if we are reading the main symbol table (as + opposed to a shared lib or dynamically loaded file). */ + +void +hpread_build_psymtabs (struct objfile *objfile, int mainline) +{ + +#ifdef DUMPING + /* Turn this on to get debugging output. */ + static int dumping = 0; +#endif + + char *namestring; + int past_first_source_file = 0; + struct cleanup *old_chain; + + int hp_symnum, symcount, i; + int scan_start = 0; + + union dnttentry *dn_bufp; + unsigned long valu; + char *p; + int texthigh = 0; + int have_name = 0; + + /* Current partial symtab */ + struct partial_symtab *pst; + + /* List of current psymtab's include files */ + char **psymtab_include_list; + int includes_allocated; + int includes_used; + + /* Index within current psymtab dependency list */ + struct partial_symtab **dependency_list; + int dependencies_used, dependencies_allocated; + + /* Just in case the stabs reader left turds lying around. */ + free_pending_blocks (); + make_cleanup (really_free_pendings, 0); + + pst = (struct partial_symtab *) 0; + + /* We shouldn't use alloca, instead use malloc/free. Doing so avoids + a number of problems with cross compilation and creating useless holes + in the stack when we have to allocate new entries. FIXME. */ + + includes_allocated = 30; + includes_used = 0; + psymtab_include_list = (char **) alloca (includes_allocated * + sizeof (char *)); + + dependencies_allocated = 30; + dependencies_used = 0; + dependency_list = + (struct partial_symtab **) alloca (dependencies_allocated * + sizeof (struct partial_symtab *)); + + old_chain = make_cleanup_free_objfile (objfile); + + last_source_file = 0; + +#ifdef QUICK_LOOK_UP + { + /* Begin code for new-style loading of quick look-up tables. */ + + /* elz: this checks whether the file has beeen processed by pxdb. + If not we would like to try to read the psymbols in + anyway, but it turns out to be not so easy. So this could + actually be commented out, but I leave it in, just in case + we decide to add support for non-pxdb-ed stuff in the future. */ + PXDB_header pxdb_header; + int found_modules_in_program; + + if (hpread_get_header (objfile, &pxdb_header)) + { + /* Build a minimal table. No types, no global variables, + no include files.... */ +#ifdef DUMPING + if (dumping) + printf ("\nNew method for %s\n", objfile->name); +#endif + + /* elz: quick_traverse returns true if it found + some modules in the main source file, other + than those in end.c + In C and C++, all the files have MODULES entries + in the LNTT, and the quick table traverse is all + based on finding these MODULES entries. Without + those it cannot work. + It happens that F77 programs don't have MODULES + so the quick traverse gets confused. F90 programs + have modules, and the quick method still works. + So, if modules (other than those in end.c) are + not found we give up on the quick table stuff, + and fall back on the slower method */ + found_modules_in_program = hpread_quick_traverse (objfile, + GNTT (objfile), + VT (objfile), + &pxdb_header); + + discard_cleanups (old_chain); + + /* Set up to scan the global section of the LNTT. + + This field is not always correct: if there are + no globals, it will point to the last record in + the regular LNTT, which is usually an END MODULE. + + Since it might happen that there could be a file + with just one global record, there's no way to + tell other than by looking at the record, so that's + done below. */ + if (found_modules_in_program) + scan_start = pxdb_header.globals; + } +#ifdef DUMPING + else + { + if (dumping) + printf ("\nGoing on to old method for %s\n", objfile->name); + } +#endif + } +#endif /* QUICK_LOOK_UP */ + + /* Make two passes, one over the GNTT symbols, the other for the + LNTT symbols. + + JB comment: above isn't true--they only make one pass, over + the LNTT. */ + for (i = 0; i < 1; i++) + { + int within_function = 0; + + if (i) + symcount = GNTT_SYMCOUNT (objfile); + else + symcount = LNTT_SYMCOUNT (objfile); + + + for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++) + { + QUIT; + if (i) + dn_bufp = hpread_get_gntt (hp_symnum, objfile); + else + dn_bufp = hpread_get_lntt (hp_symnum, objfile); + + if (dn_bufp->dblock.extension) + continue; + + /* Only handle things which are necessary for minimal symbols. + everything else is ignored. */ + switch (dn_bufp->dblock.kind) + { + case DNTT_TYPE_SRCFILE: + { +#ifdef QUICK_LOOK_UP + if (scan_start == hp_symnum + && symcount == hp_symnum + 1) + { + /* If there are NO globals in an executable, + PXDB's index to the globals will point to + the last record in the file, which + could be this record. (this happened for F77 libraries) + ignore it and be done! */ + continue; + } +#endif /* QUICK_LOOK_UP */ + + /* A source file of some kind. Note this may simply + be an included file. */ + set_namestring (dn_bufp, &namestring, objfile); + + /* Check if this is the source file we are already working + with. */ + if (pst && !strcmp (namestring, pst->filename)) + continue; + + /* Check if this is an include file, if so check if we have + already seen it. Add it to the include list */ + p = strrchr (namestring, '.'); + if (!strcmp (p, ".h")) + { + int j, found; + + found = 0; + for (j = 0; j < includes_used; j++) + if (!strcmp (namestring, psymtab_include_list[j])) + { + found = 1; + break; + } + if (found) + continue; + + /* Add it to the list of includes seen so far and + allocate more include space if necessary. */ + psymtab_include_list[includes_used++] = namestring; + if (includes_used >= includes_allocated) + { + char **orig = psymtab_include_list; + + psymtab_include_list = (char **) + alloca ((includes_allocated *= 2) * + sizeof (char *)); + memcpy (psymtab_include_list, orig, + includes_used * sizeof (char *)); + } + continue; + } + + if (pst) + { + if (!have_name) + { + pst->filename = (char *) + obstack_alloc (&pst->objfile->objfile_obstack, + strlen (namestring) + 1); + strcpy (pst->filename, namestring); + have_name = 1; + continue; + } + continue; + } + + /* This is a bonafide new source file. + End the current partial symtab and start a new one. */ + + if (pst && past_first_source_file) + { + hpread_end_psymtab (pst, psymtab_include_list, + includes_used, + (hp_symnum + * sizeof (struct dntt_type_block)), + texthigh, + dependency_list, dependencies_used); + pst = (struct partial_symtab *) 0; + includes_used = 0; + dependencies_used = 0; + } + else + past_first_source_file = 1; + + valu = hpread_get_textlow (i, hp_symnum, objfile, symcount); + valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + pst = hpread_start_psymtab (objfile, + namestring, valu, + (hp_symnum + * sizeof (struct dntt_type_block)), + objfile->global_psymbols.next, + objfile->static_psymbols.next); + texthigh = valu; + have_name = 1; + continue; + } + + case DNTT_TYPE_MODULE: + /* A source file. It's still unclear to me what the + real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE + is supposed to be. */ + + /* First end the previous psymtab */ + if (pst) + { + hpread_end_psymtab (pst, psymtab_include_list, includes_used, + ((hp_symnum - 1) + * sizeof (struct dntt_type_block)), + texthigh, + dependency_list, dependencies_used); + pst = (struct partial_symtab *) 0; + includes_used = 0; + dependencies_used = 0; + have_name = 0; + } + + /* Now begin a new module and a new psymtab for it */ + set_namestring (dn_bufp, &namestring, objfile); + valu = hpread_get_textlow (i, hp_symnum, objfile, symcount); + valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + if (!pst) + { + pst = hpread_start_psymtab (objfile, + namestring, valu, + (hp_symnum + * sizeof (struct dntt_type_block)), + objfile->global_psymbols.next, + objfile->static_psymbols.next); + texthigh = valu; + have_name = 0; + } + continue; + + case DNTT_TYPE_FUNCTION: + case DNTT_TYPE_ENTRY: + /* The beginning of a function. DNTT_TYPE_ENTRY may also denote + a secondary entry point. */ + valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)); + if (valu > texthigh) + texthigh = valu; + valu = dn_bufp->dfunc.lowaddr + + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + set_namestring (dn_bufp, &namestring, objfile); + if (dn_bufp->dfunc.global) + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, LOC_BLOCK, + &objfile->global_psymbols, valu, + 0, language_unknown, objfile); + else + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, LOC_BLOCK, + &objfile->static_psymbols, valu, + 0, language_unknown, objfile); + within_function = 1; + continue; + + case DNTT_TYPE_DOC_FUNCTION: + valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)); + if (valu > texthigh) + texthigh = valu; + valu = dn_bufp->ddocfunc.lowaddr + + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + set_namestring (dn_bufp, &namestring, objfile); + if (dn_bufp->ddocfunc.global) + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, LOC_BLOCK, + &objfile->global_psymbols, valu, + 0, language_unknown, objfile); + else + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, LOC_BLOCK, + &objfile->static_psymbols, valu, + 0, language_unknown, objfile); + within_function = 1; + continue; + + case DNTT_TYPE_BEGIN: + case DNTT_TYPE_END: + /* We don't check MODULE end here, because there can be + symbols beyond the module end which properly belong to the + current psymtab -- so we wait till the next MODULE start */ + + +#ifdef QUICK_LOOK_UP + if (scan_start == hp_symnum + && symcount == hp_symnum + 1) + { + /* If there are NO globals in an executable, + PXDB's index to the globals will point to + the last record in the file, which is + probably an END MODULE, i.e. this record. + ignore it and be done! */ + continue; + } +#endif /* QUICK_LOOK_UP */ + + /* Scope block begin/end. We only care about function + and file blocks right now. */ + + if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) || + (dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION)) + within_function = 0; + continue; + + case DNTT_TYPE_SVAR: + case DNTT_TYPE_DVAR: + case DNTT_TYPE_TYPEDEF: + case DNTT_TYPE_TAGDEF: + { + /* Variables, typedefs an the like. */ + enum address_class storage; + domain_enum domain; + + /* Don't add locals to the partial symbol table. */ + if (within_function + && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR + || dn_bufp->dblock.kind == DNTT_TYPE_DVAR)) + continue; + + /* TAGDEFs go into the structure domain. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF) + domain = STRUCT_DOMAIN; + else + domain = VAR_DOMAIN; + + /* What kind of "storage" does this use? */ + if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR) + storage = LOC_STATIC; + else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR + && dn_bufp->ddvar.regvar) + storage = LOC_REGISTER; + else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR) + storage = LOC_LOCAL; + else + storage = LOC_UNDEF; + + set_namestring (dn_bufp, &namestring, objfile); + if (!pst) + { + pst = hpread_start_psymtab (objfile, + "globals", 0, + (hp_symnum + * sizeof (struct dntt_type_block)), + objfile->global_psymbols.next, + objfile->static_psymbols.next); + } + + /* Compute address of the data symbol */ + valu = dn_bufp->dsvar.location; + /* Relocate in case it's in a shared library */ + if (storage == LOC_STATIC) + valu += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)); + + /* Luckily, dvar, svar, typedef, and tagdef all + have their "global" bit in the same place, so it works + (though it's bad programming practice) to reference + "dsvar.global" even though we may be looking at + any of the above four types. */ + if (dn_bufp->dsvar.global) + { + add_psymbol_to_list (namestring, strlen (namestring), + domain, storage, + &objfile->global_psymbols, + valu, + 0, language_unknown, objfile); + } + else + { + add_psymbol_to_list (namestring, strlen (namestring), + domain, storage, + &objfile->static_psymbols, + valu, + 0, language_unknown, objfile); + } + + /* For TAGDEF's, the above code added the tagname to the + struct domain. This will cause tag "t" to be found + on a reference of the form "(struct t) x". But for + C++ classes, "t" will also be a typename, which we + want to find on a reference of the form "ptype t". + Therefore, we also add "t" to the var domain. + Do the same for enum's due to the way aCC generates + debug info for these (see more extended comment + in hp-symtab-read.c). + We do the same for templates, so that "ptype t" + where "t" is a template also works. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF && + dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile)) + { + int global = dn_bufp->dtag.global; + /* Look ahead to see if it's a C++ class */ + dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile); + if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS || + dn_bufp->dblock.kind == DNTT_TYPE_ENUM || + dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) + { + if (global) + { + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, storage, + &objfile->global_psymbols, + dn_bufp->dsvar.location, + 0, language_unknown, objfile); + } + else + { + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, storage, + &objfile->static_psymbols, + dn_bufp->dsvar.location, + 0, language_unknown, objfile); + } + } + } + } + continue; + + case DNTT_TYPE_MEMENUM: + case DNTT_TYPE_CONST: + /* Constants and members of enumerated types. */ + set_namestring (dn_bufp, &namestring, objfile); + if (!pst) + { + pst = hpread_start_psymtab (objfile, + "globals", 0, + (hp_symnum + * sizeof (struct dntt_type_block)), + objfile->global_psymbols.next, + objfile->static_psymbols.next); + } + if (dn_bufp->dconst.global) + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, LOC_CONST, + &objfile->global_psymbols, 0, + 0, language_unknown, objfile); + else + add_psymbol_to_list (namestring, strlen (namestring), + VAR_DOMAIN, LOC_CONST, + &objfile->static_psymbols, 0, + 0, language_unknown, objfile); + continue; + default: + continue; + } + } + } + + /* End any pending partial symbol table. */ + if (pst) + { + hpread_end_psymtab (pst, psymtab_include_list, includes_used, + hp_symnum * sizeof (struct dntt_type_block), + 0, dependency_list, dependencies_used); + } + + discard_cleanups (old_chain); +} + +/* Perform any local cleanups required when we are done with a particular + objfile. I.E, we are in the process of discarding all symbol information + for an objfile, freeing up all memory held for it, and unlinking the + objfile struct from the global list of known objfiles. */ + +void +hpread_symfile_finish (struct objfile *objfile) +{ + if (objfile->sym_private != NULL) + { + xmfree (objfile->md, objfile->sym_private); + } +} + + +/* The remaining functions are all for internal use only. */ + +/* Various small functions to get entries in the debug symbol sections. */ + +static union dnttentry * +hpread_get_lntt (int index, struct objfile *objfile) +{ + return (union dnttentry *) + &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]); +} + +static union dnttentry * +hpread_get_gntt (int index, struct objfile *objfile) +{ + return (union dnttentry *) + &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]); +} + +static union sltentry * +hpread_get_slt (int index, struct objfile *objfile) +{ + return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]); +} + +/* Get the low address associated with some symbol (typically the start + of a particular source file or module). Since that information is not + stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we + must infer it from the existence of DNTT_TYPE_FUNCTION symbols. */ + +static unsigned long +hpread_get_textlow (int global, int index, struct objfile *objfile, + int symcount) +{ + union dnttentry *dn_bufp = NULL; + struct minimal_symbol *msymbol; + + /* Look for a DNTT_TYPE_FUNCTION symbol. */ + if (index < symcount) /* symcount is the number of symbols in */ + { /* the dbinfo, LNTT table */ + do + { + if (global) + dn_bufp = hpread_get_gntt (index++, objfile); + else + dn_bufp = hpread_get_lntt (index++, objfile); + } + while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION + && dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION + && dn_bufp->dblock.kind != DNTT_TYPE_END + && index < symcount); + } + + /* NOTE: cagney/2003-03-29: If !(index < symcount), dn_bufp is left + undefined and that means that the test below is using a garbage + pointer from the stack. */ + gdb_assert (dn_bufp != NULL); + + /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION. This + might happen when a sourcefile has no functions. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_END) + return 0; + + /* Avoid going past the end of the LNTT file */ + if (index == symcount) + return 0; + + /* The minimal symbols are typically more accurate for some reason. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION) + msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL, + objfile); + else /* must be a DNTT_TYPE_DOC_FUNCTION */ + msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL, + objfile); + + if (msymbol) + return SYMBOL_VALUE_ADDRESS (msymbol); + else + return dn_bufp->dfunc.lowaddr; +} + +/* Allocate and partially fill a partial symtab. It will be + completely filled at the end of the symbol list. + + SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR + is the address relative to which its symbols are (incremental) or 0 + (normal). */ + +static struct partial_symtab * +hpread_start_psymtab (struct objfile *objfile, char *filename, + CORE_ADDR textlow, int ldsymoff, + struct partial_symbol **global_syms, + struct partial_symbol **static_syms) +{ + int offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + extern void hpread_psymtab_to_symtab (); + struct partial_symtab *result = + start_psymtab_common (objfile, objfile->section_offsets, + filename, textlow, global_syms, static_syms); + + result->textlow += offset; + result->read_symtab_private = (char *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc)); + LDSYMOFF (result) = ldsymoff; + result->read_symtab = hpread_psymtab_to_symtab; + + return result; +} + + +/* Close off the current usage of PST. + Returns PST or NULL if the partial symtab was empty and thrown away. + + capping_symbol_offset --Byte index in LNTT or GNTT of the + last symbol processed during the build + of the previous pst. + + FIXME: List variables and peculiarities of same. */ + +static struct partial_symtab * +hpread_end_psymtab (struct partial_symtab *pst, char **include_list, + int num_includes, int capping_symbol_offset, + CORE_ADDR capping_text, + struct partial_symtab **dependency_list, + int number_dependencies) +{ + int i; + struct objfile *objfile = pst->objfile; + int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); + +#ifdef DUMPING + /* Turn on to see what kind of a psymtab we've built. */ + static int dumping = 0; +#endif + + if (capping_symbol_offset != -1) + LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst); + else + LDSYMLEN (pst) = 0; + pst->texthigh = capping_text + offset; + + pst->n_global_syms = + objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset); + pst->n_static_syms = + objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset); + +#ifdef DUMPING + if (dumping) + { + printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n", + pst->filename, + LDSYMOFF (pst), + LDSYMOFF (pst) / sizeof (struct dntt_type_block), + LDSYMLEN (pst), + LDSYMLEN (pst) / sizeof (struct dntt_type_block), + pst->n_global_syms, pst->n_static_syms); + } +#endif + + pst->number_of_dependencies = number_dependencies; + if (number_dependencies) + { + pst->dependencies = (struct partial_symtab **) + obstack_alloc (&objfile->objfile_obstack, + number_dependencies * sizeof (struct partial_symtab *)); + memcpy (pst->dependencies, dependency_list, + number_dependencies * sizeof (struct partial_symtab *)); + } + else + pst->dependencies = 0; + + for (i = 0; i < num_includes; i++) + { + struct partial_symtab *subpst = + allocate_psymtab (include_list[i], objfile); + + subpst->section_offsets = pst->section_offsets; + subpst->read_symtab_private = + (char *) obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symloc)); + LDSYMOFF (subpst) = + LDSYMLEN (subpst) = + subpst->textlow = + subpst->texthigh = 0; + + /* We could save slight bits of space by only making one of these, + shared by the entire set of include files. FIXME-someday. */ + subpst->dependencies = (struct partial_symtab **) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct partial_symtab *)); + subpst->dependencies[0] = pst; + subpst->number_of_dependencies = 1; + + subpst->globals_offset = + subpst->n_global_syms = + subpst->statics_offset = + subpst->n_static_syms = 0; + + subpst->readin = 0; + subpst->symtab = 0; + subpst->read_symtab = pst->read_symtab; + } + + sort_pst_symbols (pst); + + /* If there is already a psymtab or symtab for a file of this name, remove it. + (If there is a symtab, more drastic things also happen.) + This happens in VxWorks. */ + 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. + 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. + It's also wrong if we're using the quick look-up tables, as + we can get empty psymtabs from modules with no routines in + them. */ + + discard_psymtab (pst); + + /* Indicate that psymtab was thrown away. */ + pst = (struct partial_symtab *) NULL; + + } + return pst; +} + + +/* Get the nesting depth for the source line identified by INDEX. */ + +static unsigned long +hpread_get_scope_start (sltpointer index, struct objfile *objfile) +{ + union sltentry *sl_bufp; + + sl_bufp = hpread_get_slt (index, objfile); + return sl_bufp->sspec.backptr.dnttp.index; +} + +/* Get the source line number the the line identified by INDEX. */ + +static unsigned long +hpread_get_line (sltpointer index, struct objfile *objfile) +{ + union sltentry *sl_bufp; + + sl_bufp = hpread_get_slt (index, objfile); + return sl_bufp->snorm.line; +} + +/* Find the code address associated with a given sltpointer */ + +static CORE_ADDR +hpread_get_location (sltpointer index, struct objfile *objfile) +{ + union sltentry *sl_bufp; + int i; + + /* code location of special sltentrys is determined from context */ + sl_bufp = hpread_get_slt (index, objfile); + + if (sl_bufp->snorm.sltdesc == SLT_END) + { + /* find previous normal sltentry and get address */ + for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) && + (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) && + (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++) + sl_bufp = hpread_get_slt (index - i, objfile); + if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET) + return sl_bufp->snormoff.address; + else + return sl_bufp->snorm.address; + } + + /* find next normal sltentry and get address */ + for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) && + (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) && + (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++) + sl_bufp = hpread_get_slt (index + i, objfile); + if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET) + return sl_bufp->snormoff.address; + else + return sl_bufp->snorm.address; +} + + +/* Return 1 if an HP debug symbol of type KIND has a name associated with + * it, else return 0. (This function is not currently used, but I'll + * leave it here in case it proves useful later on. - RT). + */ + +static int +hpread_has_name (enum dntt_entry_type kind) +{ + switch (kind) + { + case DNTT_TYPE_SRCFILE: + case DNTT_TYPE_MODULE: + case DNTT_TYPE_FUNCTION: + case DNTT_TYPE_DOC_FUNCTION: + case DNTT_TYPE_ENTRY: + case DNTT_TYPE_IMPORT: + case DNTT_TYPE_LABEL: + case DNTT_TYPE_FPARAM: + case DNTT_TYPE_SVAR: + case DNTT_TYPE_DVAR: + case DNTT_TYPE_CONST: + case DNTT_TYPE_TYPEDEF: + case DNTT_TYPE_TAGDEF: + case DNTT_TYPE_MEMENUM: + case DNTT_TYPE_FIELD: + case DNTT_TYPE_SA: + case DNTT_TYPE_BLOCKDATA: + case DNTT_TYPE_MEMFUNC: + case DNTT_TYPE_DOC_MEMFUNC: + return 1; + + case DNTT_TYPE_BEGIN: + case DNTT_TYPE_END: + case DNTT_TYPE_POINTER: + case DNTT_TYPE_ENUM: + case DNTT_TYPE_SET: + case DNTT_TYPE_ARRAY: + case DNTT_TYPE_STRUCT: + case DNTT_TYPE_UNION: + case DNTT_TYPE_VARIANT: + case DNTT_TYPE_FILE: + case DNTT_TYPE_FUNCTYPE: + case DNTT_TYPE_SUBRANGE: + case DNTT_TYPE_WITH: + case DNTT_TYPE_COMMON: + case DNTT_TYPE_COBSTRUCT: + case DNTT_TYPE_XREF: + case DNTT_TYPE_MACRO: + case DNTT_TYPE_CLASS_SCOPE: + case DNTT_TYPE_REFERENCE: + case DNTT_TYPE_PTRMEM: + case DNTT_TYPE_PTRMEMFUNC: + case DNTT_TYPE_CLASS: + case DNTT_TYPE_GENFIELD: + case DNTT_TYPE_VFUNC: + case DNTT_TYPE_MEMACCESS: + case DNTT_TYPE_INHERITANCE: + case DNTT_TYPE_FRIEND_CLASS: + case DNTT_TYPE_FRIEND_FUNC: + case DNTT_TYPE_MODIFIER: + case DNTT_TYPE_OBJECT_ID: + case DNTT_TYPE_TEMPLATE: + case DNTT_TYPE_TEMPLATE_ARG: + case DNTT_TYPE_FUNC_TEMPLATE: + case DNTT_TYPE_LINK: + /* DNTT_TYPE_DYN_ARRAY_DESC ? */ + /* DNTT_TYPE_DESC_SUBRANGE ? */ + /* DNTT_TYPE_BEGIN_EXT ? */ + /* DNTT_TYPE_INLN ? */ + /* DNTT_TYPE_INLN_LIST ? */ + /* DNTT_TYPE_ALIAS ? */ + default: + return 0; + } +} + +/* Do the dirty work of reading in the full symbol from a partial symbol + table. */ + +static void +hpread_psymtab_to_symtab_1 (struct partial_symtab *pst) +{ + struct cleanup *old_chain; + int i; + + /* Get out quick if passed junk. */ + if (!pst) + return; + + /* Complain if we've already read in this symbol table. */ + if (pst->readin) + { + fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in." + " Shouldn't happen.\n", + pst->filename); + return; + } + + /* Read in all partial symtabs on which this one is dependent */ + for (i = 0; i < pst->number_of_dependencies; i++) + if (!pst->dependencies[i]->readin) + { + /* Inform about additional files that need to be read in. */ + if (info_verbose) + { + fputs_filtered (" ", gdb_stdout); + wrap_here (""); + fputs_filtered ("and ", gdb_stdout); + wrap_here (""); + printf_filtered ("%s...", pst->dependencies[i]->filename); + wrap_here (""); /* Flush output */ + gdb_flush (gdb_stdout); + } + hpread_psymtab_to_symtab_1 (pst->dependencies[i]); + } + + /* If it's real... */ + if (LDSYMLEN (pst)) + { + /* Init stuff necessary for reading in symbols */ + buildsym_init (); + old_chain = make_cleanup (really_free_pendings, 0); + + pst->symtab = + hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst), + pst->textlow, pst->texthigh - pst->textlow, + pst->section_offsets, pst->filename); + + do_cleanups (old_chain); + } + + pst->readin = 1; +} + +/* Read in all of the symbols for a given psymtab for real. + Be verbose about it if the user wants that. */ + +static void +hpread_psymtab_to_symtab (struct partial_symtab *pst) +{ + /* Get out quick if given junk. */ + if (!pst) + return; + + /* Sanity check. */ + if (pst->readin) + { + fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in." + " Shouldn't happen.\n", + pst->filename); + return; + } + + /* elz: setting the flag to indicate that the code of the target + was compiled using an HP compiler (aCC, cc) + the processing_acc_compilation variable is declared in the + file buildsym.h, the HP_COMPILED_TARGET is defined to be equal + to 3 in the file tm_hppa.h */ + + processing_gcc_compilation = 0; + + if (LDSYMLEN (pst) || pst->number_of_dependencies) + { + /* Print the message now, before reading the string table, + to avoid disconcerting pauses. */ + if (info_verbose) + { + printf_filtered ("Reading in symbols for %s...", pst->filename); + gdb_flush (gdb_stdout); + } + + hpread_psymtab_to_symtab_1 (pst); + + /* Match with global symbols. This only needs to be done once, + after all of the symtabs and dependencies have been read in. */ + scan_file_globals (pst->objfile); + + /* Finish up the debug error message. */ + if (info_verbose) + printf_filtered ("done.\n"); + } +} + +/* Read in a defined section of a specific object file's symbols. + + DESC is the file descriptor for the file, positioned at the + beginning of the symtab + SYM_OFFSET is the offset within the file of + the beginning of the symbols we want to read + SYM_SIZE is the size of the symbol info to read in. + TEXT_OFFSET is the beginning of the text segment we are reading symbols for + TEXT_SIZE is the size of the text segment read in. + SECTION_OFFSETS are the relocation offsets which get added to each symbol. */ + +static struct symtab * +hpread_expand_symtab (struct objfile *objfile, int sym_offset, int sym_size, + CORE_ADDR text_offset, int text_size, + struct section_offsets *section_offsets, char *filename) +{ + char *namestring; + union dnttentry *dn_bufp; + unsigned max_symnum; + int at_module_boundary = 0; + /* 1 => at end, -1 => at beginning */ + + int sym_index = sym_offset / sizeof (struct dntt_type_block); + + current_objfile = objfile; + subfile_stack = 0; + + last_source_file = 0; + + /* Demangling style -- if EDG style already set, don't change it, + as HP style causes some problems with the KAI EDG compiler */ + if (current_demangling_style != edg_demangling) + { + /* Otherwise, ensure that we are using HP style demangling */ + set_demangling_style (HP_DEMANGLING_STYLE_STRING); + } + + dn_bufp = hpread_get_lntt (sym_index, objfile); + if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) || + (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE))) + { + start_symtab ("globals", NULL, 0); + record_debugformat ("HP"); + } + + /* The psymtab builder (hp-psymtab-read.c) is the one that + * determined the "sym_size" argument (i.e. how many DNTT symbols + * are in this symtab), which we use to compute "max_symnum" + * (point in DNTT to which we read). + * + * Perhaps this should be changed so that + * process_one_debug_symbol() "knows" when + * to stop reading (based on reading from the MODULE to the matching + * END), and take out this reliance on a #-syms being passed in... + * (I'm worried about the reliability of this number). But I'll + * leave it as-is, for now. - RT + * + * The change above has been made. I've left the "for" loop control + * in to prepare for backing this out again. -JB + */ + max_symnum = sym_size / sizeof (struct dntt_type_block); + /* No reason to multiply on pst side and divide on sym side... FIXME */ + + /* Read in and process each debug symbol within the specified range. + */ + for (symnum = 0; + symnum < max_symnum; + symnum++) + { + QUIT; /* Allow this to be interruptable */ + dn_bufp = hpread_get_lntt (sym_index + symnum, objfile); + + if (dn_bufp->dblock.extension) + continue; + + /* Yow! We call set_namestring on things without names! */ + set_namestring (dn_bufp, &namestring, objfile); + + hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets, + objfile, text_offset, text_size, + filename, symnum + sym_index, + &at_module_boundary + ); + + /* OLD COMMENTS: This routine is only called for psts. All psts + * correspond to MODULES. If we ever do lazy-reading of globals + * from the LNTT, then there will be a pst which ends when the + * LNTT ends, and not at an END MODULE entry. Then we'll have + * to re-visit this break. + + if( at_end_of_module ) + break; + + */ + + /* We no longer break out of the loop when we reach the end of a + module. The reason is that with CTTI, the compiler can generate + function symbols (for template function instantiations) which are not + in any module; typically they show up beyond a module's end, and + before the next module's start. We include them in the current + module. However, we still don't trust the MAX_SYMNUM value from + the psymtab, so we break out if we enter a new module. */ + + if (at_module_boundary == -1) + break; + } + + current_objfile = NULL; + hp_som_som_object_present = 1; /* Indicate we've processed an HP SOM SOM file */ + + return end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile)); +} + + + + +/* Convert basic types from HP debug format into GDB internal format. */ + +static int +hpread_type_translate (dnttpointer typep) +{ + if (!typep.dntti.immediate) + { + error ("error in hpread_type_translate\n."); + return FT_VOID; + } + + switch (typep.dntti.type) + { + case HP_TYPE_BOOLEAN: + case HP_TYPE_BOOLEAN_S300_COMPAT: + case HP_TYPE_BOOLEAN_VAX_COMPAT: + return FT_BOOLEAN; + case HP_TYPE_CHAR: /* C signed char, C++ plain char */ + + case HP_TYPE_WIDE_CHAR: + return FT_CHAR; + case HP_TYPE_INT: + if (typep.dntti.bitlength <= 8) + return FT_SIGNED_CHAR; /* C++ signed char */ + if (typep.dntti.bitlength <= 16) + return FT_SHORT; + if (typep.dntti.bitlength <= 32) + return FT_INTEGER; + return FT_LONG_LONG; + case HP_TYPE_LONG: + if (typep.dntti.bitlength <= 8) + return FT_SIGNED_CHAR; /* C++ signed char. */ + return FT_LONG; + case HP_TYPE_UNSIGNED_LONG: + if (typep.dntti.bitlength <= 8) + return FT_UNSIGNED_CHAR; /* C/C++ unsigned char */ + if (typep.dntti.bitlength <= 16) + return FT_UNSIGNED_SHORT; + if (typep.dntti.bitlength <= 32) + return FT_UNSIGNED_LONG; + return FT_UNSIGNED_LONG_LONG; + case HP_TYPE_UNSIGNED_INT: + if (typep.dntti.bitlength <= 8) + return FT_UNSIGNED_CHAR; + if (typep.dntti.bitlength <= 16) + return FT_UNSIGNED_SHORT; + if (typep.dntti.bitlength <= 32) + return FT_UNSIGNED_INTEGER; + return FT_UNSIGNED_LONG_LONG; + case HP_TYPE_REAL: + case HP_TYPE_REAL_3000: + case HP_TYPE_DOUBLE: + if (typep.dntti.bitlength == 64) + return FT_DBL_PREC_FLOAT; + if (typep.dntti.bitlength == 128) + return FT_EXT_PREC_FLOAT; + return FT_FLOAT; + case HP_TYPE_COMPLEX: + case HP_TYPE_COMPLEXS3000: + if (typep.dntti.bitlength == 128) + return FT_DBL_PREC_COMPLEX; + if (typep.dntti.bitlength == 192) + return FT_EXT_PREC_COMPLEX; + return FT_COMPLEX; + case HP_TYPE_VOID: + return FT_VOID; + case HP_TYPE_STRING200: + case HP_TYPE_LONGSTRING200: + case HP_TYPE_FTN_STRING_SPEC: + case HP_TYPE_MOD_STRING_SPEC: + case HP_TYPE_MOD_STRING_3000: + case HP_TYPE_FTN_STRING_S300_COMPAT: + case HP_TYPE_FTN_STRING_VAX_COMPAT: + return FT_STRING; + case HP_TYPE_TEMPLATE_ARG: + return FT_TEMPLATE_ARG; + case HP_TYPE_TEXT: + case HP_TYPE_FLABEL: + case HP_TYPE_PACKED_DECIMAL: + case HP_TYPE_ANYPOINTER: + case HP_TYPE_GLOBAL_ANYPOINTER: + case HP_TYPE_LOCAL_ANYPOINTER: + default: + warning ("hpread_type_translate: unhandled type code.\n"); + return FT_VOID; + } +} + +/* Given a position in the DNTT, return a pointer to the + * already-built "struct type" (if any), for the type defined + * at that position. + */ + +static struct type ** +hpread_lookup_type (dnttpointer hp_type, struct objfile *objfile) +{ + unsigned old_len; + int index = hp_type.dnttp.index; + int size_changed = 0; + + /* The immediate flag indicates this doesn't actually point to + * a type DNTT. + */ + if (hp_type.dntti.immediate) + return NULL; + + /* For each objfile, we maintain a "type vector". + * This an array of "struct type *"'s with one pointer per DNTT index. + * Given a DNTT index, we look in this array to see if we have + * already processed this DNTT and if it is a type definition. + * If so, then we can locate a pointer to the already-built + * "struct type", and not build it again. + * + * The need for this arises because our DNTT-walking code wanders + * around. In particular, it will encounter the same type multiple + * times (once for each object of that type). We don't want to + * built multiple "struct type"'s for the same thing. + * + * Having said this, I should point out that this type-vector is + * an expensive way to keep track of this. If most DNTT entries are + * 3 words, the type-vector will be 1/3 the size of the DNTT itself. + * Alternative solutions: + * - Keep a compressed or hashed table. Less memory, but more expensive + * to search and update. + * - (Suggested by JB): Overwrite the DNTT entry itself + * with the info. Create a new type code "ALREADY_BUILT", and modify + * the DNTT to have that type code and point to the already-built entry. + * -RT + */ + + if (index < LNTT_SYMCOUNT (objfile)) + { + if (index >= DNTT_TYPE_VECTOR_LENGTH (objfile)) + { + old_len = DNTT_TYPE_VECTOR_LENGTH (objfile); + + /* See if we need to allocate a type-vector. */ + if (old_len == 0) + { + DNTT_TYPE_VECTOR_LENGTH (objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile); + DNTT_TYPE_VECTOR (objfile) = (struct type **) + xmmalloc (objfile->md, DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)); + memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0, + (DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) * + sizeof (struct type *)); + } + + /* See if we need to resize type-vector. With my change to + * initially allocate a correct-size type-vector, this code + * should no longer trigger. + */ + while (index >= DNTT_TYPE_VECTOR_LENGTH (objfile)) + { + DNTT_TYPE_VECTOR_LENGTH (objfile) *= 2; + size_changed = 1; + } + if (size_changed) + { + DNTT_TYPE_VECTOR (objfile) = (struct type **) + xmrealloc (objfile->md, + (char *) DNTT_TYPE_VECTOR (objfile), + (DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *))); + + memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0, + (DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) * + sizeof (struct type *)); + } + + } + return &DNTT_TYPE_VECTOR (objfile)[index]; + } + else + return NULL; +} + +/* Possibly allocate a GDB internal type so we can internalize HP_TYPE. + Note we'll just return the address of a GDB internal type if we already + have it lying around. */ + +static struct type * +hpread_alloc_type (dnttpointer hp_type, struct objfile *objfile) +{ + struct type **type_addr; + + type_addr = hpread_lookup_type (hp_type, objfile); + if (*type_addr == 0) + { + *type_addr = alloc_type (objfile); + + /* A hack - if we really are a C++ class symbol, then this default + * will get overriden later on. + */ + TYPE_CPLUS_SPECIFIC (*type_addr) + = (struct cplus_struct_type *) &cplus_struct_default; + } + + return *type_addr; +} + +/* Read a native enumerated type and return it in GDB internal form. */ + +static struct type * +hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile) +{ + struct type *type; + struct pending **symlist, *osyms, *syms; + struct pending *local_list = NULL; + int o_nsyms, nsyms = 0; + dnttpointer mem; + union dnttentry *memp; + char *name; + long n; + struct symbol *sym; + + /* Allocate a GDB type. If we've already read in this enum type, + * it'll return the already built GDB type, so stop here. + * (Note: I added this check, to conform with what's done for + * struct, union, class. + * I assume this is OK. - RT) + */ + type = hpread_alloc_type (hp_type, objfile); + if (TYPE_CODE (type) == TYPE_CODE_ENUM) + return type; + + /* HP C supports "sized enums", where a specifier such as "short" or + "char" can be used to get enums of different sizes. So don't assume + an enum is always 4 bytes long. pai/1997-08-21 */ + TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8; + + symlist = &file_symbols; + osyms = *symlist; + o_nsyms = osyms ? osyms->nsyms : 0; + + /* Get a name for each member and add it to our list of members. + * The list of "mem" SOM records we are walking should all be + * SOM type DNTT_TYPE_MEMENUM (not checked). + */ + mem = dn_bufp->denum.firstmem; + while (mem.word && mem.word != DNTTNIL) + { + memp = hpread_get_lntt (mem.dnttp.index, objfile); + + name = VT (objfile) + memp->dmember.name; + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symbol)); + memset (sym, 0, sizeof (struct symbol)); + DEPRECATED_SYMBOL_NAME (sym) = obsavestring (name, strlen (name), + &objfile->objfile_obstack); + SYMBOL_CLASS (sym) = LOC_CONST; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + SYMBOL_VALUE (sym) = memp->dmember.value; + add_symbol_to_list (sym, symlist); + nsyms++; + mem = memp->dmember.nextmem; + } + + /* Now that we know more about the enum, fill in more info. */ + TYPE_CODE (type) = TYPE_CODE_ENUM; + TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; + TYPE_NFIELDS (type) = nsyms; + TYPE_FIELDS (type) = (struct field *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct field) * nsyms); + + /* Find the symbols for the members and put them into the type. + The symbols can be found in the symlist that we put them on + to cause them to be defined. osyms contains the old value + of that symlist; everything up to there was defined by us. + + Note that we preserve the order of the enum constants, so + that in something like "enum {FOO, LAST_THING=FOO}" we print + FOO, not LAST_THING. */ + for (syms = *symlist, n = 0; syms; syms = syms->next) + { + int j = 0; + if (syms == osyms) + j = o_nsyms; + for (; j < syms->nsyms; j++, n++) + { + struct symbol *xsym = syms->symbol[j]; + SYMBOL_TYPE (xsym) = type; + TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym); + TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); + TYPE_FIELD_BITSIZE (type, n) = 0; + TYPE_FIELD_STATIC_KIND (type, n) = 0; + } + if (syms == osyms) + break; + } + + return type; +} + +/* Read and internalize a native function debug symbol. */ + +static struct type * +hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile, int newblock) +{ + struct type *type, *type1; + struct pending *syms; + struct pending *local_list = NULL; + int nsyms = 0; + dnttpointer param; + union dnttentry *paramp; + char *name; + long n; + struct symbol *sym; + int record_args = 1; + + /* See if we've already read in this type. */ + type = hpread_alloc_type (hp_type, objfile); + if (TYPE_CODE (type) == TYPE_CODE_FUNC) + { + record_args = 0; /* already read in, don't modify type */ + } + else + { + /* Nope, so read it in and store it away. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION || + dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC) + type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval, + objfile)); + else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE) + type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval, + objfile)); + else /* expect DNTT_TYPE_FUNC_TEMPLATE */ + type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval, + objfile)); + replace_type (type, type1); + + /* Mark it -- in the middle of processing */ + TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE; + } + + /* Now examine each parameter noting its type, location, and a + wealth of other information. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION || + dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC) + param = dn_bufp->dfunc.firstparam; + else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE) + param = dn_bufp->dfunctype.firstparam; + else /* expect DNTT_TYPE_FUNC_TEMPLATE */ + param = dn_bufp->dfunc_template.firstparam; + while (param.word && param.word != DNTTNIL) + { + paramp = hpread_get_lntt (param.dnttp.index, objfile); + nsyms++; + param = paramp->dfparam.nextparam; + + /* Get the name. */ + name = VT (objfile) + paramp->dfparam.name; + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symbol)); + (void) memset (sym, 0, sizeof (struct symbol)); + DEPRECATED_SYMBOL_NAME (sym) = obsavestring (name, strlen (name), + &objfile->objfile_obstack); + + /* Figure out where it lives. */ + if (paramp->dfparam.regparam) + SYMBOL_CLASS (sym) = LOC_REGPARM; + else if (paramp->dfparam.indirect) + SYMBOL_CLASS (sym) = LOC_REF_ARG; + else + SYMBOL_CLASS (sym) = LOC_ARG; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + if (paramp->dfparam.copyparam) + { + SYMBOL_VALUE (sym) = paramp->dfparam.location; +#ifdef HPREAD_ADJUST_STACK_ADDRESS + SYMBOL_VALUE (sym) + += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); +#endif + /* This is likely a pass-by-invisible reference parameter, + Hack on the symbol class to make GDB happy. */ + /* ??rehrauer: This appears to be broken w/r/t to passing + C values of type float and struct. Perhaps this ought + to be highighted as a special case, but for now, just + allowing these to be LOC_ARGs seems to work fine. + */ +#if 0 + SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; +#endif + } + else + SYMBOL_VALUE (sym) = paramp->dfparam.location; + + /* Get its type. */ + SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile); + /* Add it to the symbol list. */ + /* Note 1 (RT) At the moment, add_symbol_to_list() is also being + * called on FPARAM symbols from the process_one_debug_symbol() + * level... so parameters are getting added twice! (this shows + * up in the symbol dump you get from "maint print symbols ..."). + * Note 2 (RT) I took out the processing of FPARAM from the + * process_one_debug_symbol() level, so at the moment parameters are only + * being processed here. This seems to have no ill effect. + */ + /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put + each fparam on the local_symbols list from here. Now we use the + local_list to which fparams are added below, and set the param_symbols + global to point to that at the end of this routine. */ + /* elz: I added this new list of symbols which is local to the function. + this list is the one which is actually used to build the type for the + function rather than the gloabal list pointed to by symlist. + Using a global list to keep track of the parameters is wrong, because + this function is called recursively if one parameter happend to be + a function itself with more parameters in it. Adding parameters to the + same global symbol list would not work! + Actually it did work in case of cc compiled programs where you do + not check the parameter lists of the arguments. */ + add_symbol_to_list (sym, &local_list); + + } + + /* If type was read in earlier, don't bother with modifying + the type struct */ + if (!record_args) + goto finish; + + /* Note how many parameters we found. */ + TYPE_NFIELDS (type) = nsyms; + TYPE_FIELDS (type) = (struct field *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct field) * nsyms); + + /* Find the symbols for the parameters and + use them to fill parameter-type information into the function-type. + The parameter symbols can be found in the local_list that we just put them on. */ + /* Note that we preserve the order of the parameters, so + that in something like "enum {FOO, LAST_THING=FOO}" we print + FOO, not LAST_THING. */ + + /* get the parameters types from the local list not the global list + so that the type can be correctly constructed for functions which + have function as parameters */ + for (syms = local_list, n = 0; syms; syms = syms->next) + { + int j = 0; + for (j = 0; j < syms->nsyms; j++, n++) + { + struct symbol *xsym = syms->symbol[j]; + TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym); + TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym); + TYPE_FIELD_ARTIFICIAL (type, n) = 0; + TYPE_FIELD_BITSIZE (type, n) = 0; + TYPE_FIELD_STATIC_KIND (type, n) = 0; + } + } + /* Mark it as having been processed */ + TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE); + + /* Check whether we need to fix-up a class type with this function's type */ + if (fixup_class && (fixup_method == type)) + { + fixup_class_method_type (fixup_class, fixup_method, objfile); + fixup_class = NULL; + fixup_method = NULL; + } + + /* Set the param list of this level of the context stack + to our local list. Do this only if this function was + called for creating a new block, and not if it was called + simply to get the function type. This prevents recursive + invocations from trashing param_symbols. */ +finish: + if (newblock) + param_symbols = local_list; + + return type; +} + + +/* Read and internalize a native DOC function debug symbol. */ +/* This is almost identical to hpread_read_function_type(), except + * for references to dn_bufp->ddocfunc instead of db_bufp->dfunc. + * Since debug information for DOC functions is more likely to be + * volatile, please leave it this way. + */ +static struct type * +hpread_read_doc_function_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile, int newblock) +{ + struct pending *syms; + struct pending *local_list = NULL; + int nsyms = 0; + struct type *type; + dnttpointer param; + union dnttentry *paramp; + char *name; + long n; + struct symbol *sym; + int record_args = 1; + + /* See if we've already read in this type. */ + type = hpread_alloc_type (hp_type, objfile); + if (TYPE_CODE (type) == TYPE_CODE_FUNC) + { + record_args = 0; /* already read in, don't modify type */ + } + else + { + struct type *type1 = NULL; + /* Nope, so read it in and store it away. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION || + dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) + type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval, + objfile)); + /* NOTE: cagney/2003-03-29: Oh, no not again. TYPE1 is + potentially left undefined here. Assert it isn't and hope + the assert never fails ... */ + gdb_assert (type1 != NULL); + + replace_type (type, type1); + + /* Mark it -- in the middle of processing */ + TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE; + } + + /* Now examine each parameter noting its type, location, and a + wealth of other information. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION || + dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) + param = dn_bufp->ddocfunc.firstparam; + while (param.word && param.word != DNTTNIL) + { + paramp = hpread_get_lntt (param.dnttp.index, objfile); + nsyms++; + param = paramp->dfparam.nextparam; + + /* Get the name. */ + name = VT (objfile) + paramp->dfparam.name; + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symbol)); + (void) memset (sym, 0, sizeof (struct symbol)); + DEPRECATED_SYMBOL_NAME (sym) = name; + + /* Figure out where it lives. */ + if (paramp->dfparam.regparam) + SYMBOL_CLASS (sym) = LOC_REGPARM; + else if (paramp->dfparam.indirect) + SYMBOL_CLASS (sym) = LOC_REF_ARG; + else + SYMBOL_CLASS (sym) = LOC_ARG; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + if (paramp->dfparam.copyparam) + { + SYMBOL_VALUE (sym) = paramp->dfparam.location; +#ifdef HPREAD_ADJUST_STACK_ADDRESS + SYMBOL_VALUE (sym) + += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); +#endif + /* This is likely a pass-by-invisible reference parameter, + Hack on the symbol class to make GDB happy. */ + /* ??rehrauer: This appears to be broken w/r/t to passing + C values of type float and struct. Perhaps this ought + to be highighted as a special case, but for now, just + allowing these to be LOC_ARGs seems to work fine. + */ +#if 0 + SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; +#endif + } + else + SYMBOL_VALUE (sym) = paramp->dfparam.location; + + /* Get its type. */ + SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile); + /* Add it to the symbol list. */ + /* Note 1 (RT) At the moment, add_symbol_to_list() is also being + * called on FPARAM symbols from the process_one_debug_symbol() + * level... so parameters are getting added twice! (this shows + * up in the symbol dump you get from "maint print symbols ..."). + * Note 2 (RT) I took out the processing of FPARAM from the + * process_one_debug_symbol() level, so at the moment parameters are only + * being processed here. This seems to have no ill effect. + */ + /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put + each fparam on the local_symbols list from here. Now we use the + local_list to which fparams are added below, and set the param_symbols + global to point to that at the end of this routine. */ + + /* elz: I added this new list of symbols which is local to the function. + this list is the one which is actually used to build the type for the + function rather than the gloabal list pointed to by symlist. + Using a global list to keep track of the parameters is wrong, because + this function is called recursively if one parameter happend to be + a function itself with more parameters in it. Adding parameters to the + same global symbol list would not work! + Actually it did work in case of cc compiled programs where you do not check the + parameter lists of the arguments. */ + add_symbol_to_list (sym, &local_list); + } + + /* If type was read in earlier, don't bother with modifying + the type struct */ + if (!record_args) + goto finish; + + /* Note how many parameters we found. */ + TYPE_NFIELDS (type) = nsyms; + TYPE_FIELDS (type) = (struct field *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct field) * nsyms); + + /* Find the symbols for the parameters and + use them to fill parameter-type information into the function-type. + The parameter symbols can be found in the local_list that we just put them on. */ + /* Note that we preserve the order of the parameters, so + that in something like "enum {FOO, LAST_THING=FOO}" we print + FOO, not LAST_THING. */ + + /* get the parameters types from the local list not the global list + so that the type can be correctly constructed for functions which + have function as parameters + */ + for (syms = local_list, n = 0; syms; syms = syms->next) + { + int j = 0; + for (j = 0; j < syms->nsyms; j++, n++) + { + struct symbol *xsym = syms->symbol[j]; + TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym); + TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym); + TYPE_FIELD_ARTIFICIAL (type, n) = 0; + TYPE_FIELD_BITSIZE (type, n) = 0; + TYPE_FIELD_STATIC_KIND (type, n) = 0; + } + } + + /* Mark it as having been processed */ + TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE); + + /* Check whether we need to fix-up a class type with this function's type */ + if (fixup_class && (fixup_method == type)) + { + fixup_class_method_type (fixup_class, fixup_method, objfile); + fixup_class = NULL; + fixup_method = NULL; + } + + /* Set the param list of this level of the context stack + to our local list. Do this only if this function was + called for creating a new block, and not if it was called + simply to get the function type. This prevents recursive + invocations from trashing param_symbols. */ +finish: + if (newblock) + param_symbols = local_list; + + return type; +} + + + +/* A file-level variable which keeps track of the current-template + * being processed. Set in hpread_read_struct_type() while processing + * a template type. Referred to in hpread_get_nth_templ_arg(). + * Yes, this is a kludge, but it arises from the kludge that already + * exists in symtab.h, namely the fact that they encode + * "template argument n" with fundamental type FT_TEMPLATE_ARG and + * bitlength n. This means that deep in processing fundamental types + * I need to ask the question "what template am I in the middle of?". + * The alternative to stuffing a global would be to pass an argument + * down the chain of calls just for this purpose. + * + * There may be problems handling nested templates... tough. + */ +static struct type *current_template = NULL; + +/* Read in and internalize a structure definition. + * This same routine is called for struct, union, and class types. + * Also called for templates, since they build a very similar + * type entry as for class types. + */ + +static struct type * +hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile) +{ + /* The data members get linked together into a list of struct nextfield's */ + struct nextfield + { + struct nextfield *next; + struct field field; + unsigned char attributes; /* store visibility and virtuality info */ +#define ATTR_VIRTUAL 1 +#define ATTR_PRIVATE 2 +#define ATTR_PROTECT 3 + }; + + + /* The methods get linked together into a list of struct next_fn_field's */ + struct next_fn_field + { + struct next_fn_field *next; + struct fn_fieldlist field; + struct fn_field fn_field; + int num_fn_fields; + }; + + /* The template args get linked together into a list of struct next_template's */ + struct next_template + { + struct next_template *next; + struct template_arg arg; + }; + + /* The template instantiations get linked together into a list of these... */ + struct next_instantiation + { + struct next_instantiation *next; + struct type *t; + }; + + struct type *type; + struct type *baseclass; + struct type *memtype; + struct nextfield *list = 0, *tmp_list = 0; + struct next_fn_field *fn_list = 0; + struct next_fn_field *fn_p; + struct next_template *t_new, *t_list = 0; + struct nextfield *new; + struct next_fn_field *fn_new; + struct next_instantiation *i_new, *i_list = 0; + int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0; + int n_base_classes = 0, n_templ_args = 0; + int ninstantiations = 0; + dnttpointer field, fn_field, parent; + union dnttentry *fieldp, *fn_fieldp, *parentp; + int i; + int static_member = 0; + int const_member = 0; + int volatile_member = 0; + unsigned long vtbl_offset; + int need_bitvectors = 0; + char *method_name = NULL; + char *method_alias = NULL; + + + /* Is it something we've already dealt with? */ + type = hpread_alloc_type (hp_type, objfile); + if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) || + (TYPE_CODE (type) == TYPE_CODE_UNION) || + (TYPE_CODE (type) == TYPE_CODE_CLASS) || + (TYPE_CODE (type) == TYPE_CODE_TEMPLATE)) + return type; + + /* Get the basic type correct. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT) + { + TYPE_CODE (type) = TYPE_CODE_STRUCT; + TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8; + } + else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION) + { + TYPE_CODE (type) = TYPE_CODE_UNION; + TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8; + } + else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) + { + TYPE_CODE (type) = TYPE_CODE_CLASS; + TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8; + + /* Overrides the TYPE_CPLUS_SPECIFIC(type) with allocated memory + * rather than &cplus_struct_default. + */ + allocate_cplus_struct_type (type); + + /* Fill in declared-type. + * (The C++ compiler will emit TYPE_CODE_CLASS + * for all 3 of "class", "struct" + * "union", and we have to look at the "class_decl" field if we + * want to know how it was really declared) + */ + /* (0==class, 1==union, 2==struct) */ + TYPE_DECLARED_TYPE (type) = dn_bufp->dclass.class_decl; + } + else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) + { + /* Get the basic type correct. */ + TYPE_CODE (type) = TYPE_CODE_TEMPLATE; + allocate_cplus_struct_type (type); + TYPE_DECLARED_TYPE (type) = DECLARED_TYPE_TEMPLATE; + } + else + return type; + + + TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; + + /* For classes, read the parent list. + * Question (RT): Do we need to do this for templates also? + */ + if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) + { + + /* First read the parent-list (classes from which we derive fields) */ + parent = dn_bufp->dclass.parentlist; + while (parent.word && parent.word != DNTTNIL) + { + parentp = hpread_get_lntt (parent.dnttp.index, objfile); + + /* "parentp" should point to a DNTT_TYPE_INHERITANCE record */ + + /* Get space to record the next field/data-member. */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + memset (new, 0, sizeof (struct nextfield)); + new->next = list; + list = new; + + FIELD_BITSIZE (list->field) = 0; + FIELD_STATIC_KIND (list->field) = 0; + + /* The "classname" field is actually a DNTT pointer to the base class */ + baseclass = hpread_type_lookup (parentp->dinheritance.classname, + objfile); + FIELD_TYPE (list->field) = baseclass; + + list->field.name = type_name_no_tag (FIELD_TYPE (list->field)); + + list->attributes = 0; + + /* Check for virtuality of base, and set the + * offset of the base subobject within the object. + * (Offset set to -1 for virtual bases (for now).) + */ + if (parentp->dinheritance.Virtual) + { + B_SET (&(list->attributes), ATTR_VIRTUAL); + parentp->dinheritance.offset = -1; + } + else + FIELD_BITPOS (list->field) = parentp->dinheritance.offset; + + /* Check visibility */ + switch (parentp->dinheritance.visibility) + { + case 1: + B_SET (&(list->attributes), ATTR_PROTECT); + break; + case 2: + B_SET (&(list->attributes), ATTR_PRIVATE); + break; + } + + n_base_classes++; + nfields++; + + parent = parentp->dinheritance.next; + } + } + + /* For templates, read the template argument list. + * This must be done before processing the member list, because + * the member list may refer back to this. E.g.: + * template class q2 { + * public: + * T1 a; + * T2 b; + * }; + * We need to read the argument list "T1", "T2" first. + */ + if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) + { + /* Kludge alert: This stuffs a global "current_template" which + * is referred to by hpread_get_nth_templ_arg(). The global + * is cleared at the end of this routine. + */ + current_template = type; + + /* Read in the argument list */ + field = dn_bufp->dtemplate.arglist; + while (field.word && field.word != DNTTNIL) + { + /* Get this template argument */ + fieldp = hpread_get_lntt (field.dnttp.index, objfile); + if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG) + { + warning ("Invalid debug info: Template argument entry is of wrong kind"); + break; + } + /* Bump the count */ + n_templ_args++; + /* Allocate and fill in a struct next_template */ + t_new = (struct next_template *) alloca (sizeof (struct next_template)); + memset (t_new, 0, sizeof (struct next_template)); + t_new->next = t_list; + t_list = t_new; + t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name; + t_list->arg.type = hpread_read_templ_arg_type (field, fieldp, + objfile, t_list->arg.name); + /* Walk to the next template argument */ + field = fieldp->dtempl_arg.nextarg; + } + } + + TYPE_NTEMPLATE_ARGS (type) = n_templ_args; + + if (n_templ_args > 0) + TYPE_TEMPLATE_ARGS (type) = (struct template_arg *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct template_arg) * n_templ_args); + for (n = n_templ_args; t_list; t_list = t_list->next) + { + n -= 1; + TYPE_TEMPLATE_ARG (type, n) = t_list->arg; + } + + /* Next read in and internalize all the fields/members. */ + if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT) + field = dn_bufp->dstruct.firstfield; + else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION) + field = dn_bufp->dunion.firstfield; + else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) + field = dn_bufp->dclass.memberlist; + else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) + field = dn_bufp->dtemplate.memberlist; + else + field.word = DNTTNIL; + + while (field.word && field.word != DNTTNIL) + { + fieldp = hpread_get_lntt (field.dnttp.index, objfile); + + /* At this point "fieldp" may point to either a DNTT_TYPE_FIELD + * or a DNTT_TYPE_GENFIELD record. + */ + vtbl_offset = 0; + static_member = 0; + const_member = 0; + volatile_member = 0; + + if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD) + { + + /* The type will be GENFIELD if the field is a method or + * a static member (or some other cases -- see below) + */ + + /* Follow a link to get to the record for the field. */ + fn_field = fieldp->dgenfield.field; + fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile); + + /* Virtual funcs are indicated by a VFUNC which points to the + * real entry + */ + if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC) + { + vtbl_offset = fn_fieldp->dvfunc.vtbl_offset; + fn_field = fn_fieldp->dvfunc.funcptr; + fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile); + } + + /* A function's entry may be preceded by a modifier which + * labels it static/constant/volatile. + */ + if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER) + { + static_member = fn_fieldp->dmodifier.m_static; + const_member = fn_fieldp->dmodifier.m_const; + volatile_member = fn_fieldp->dmodifier.m_volatile; + fn_field = fn_fieldp->dmodifier.type; + fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile); + } + + /* Check whether we have a method */ + if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) || + (fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) || + (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) || + (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION)) + { + /* Method found */ + + short ix = 0; + + /* Look up function type of method */ + memtype = hpread_type_lookup (fn_field, objfile); + + /* Methods can be seen before classes in the SOM records. + If we are processing this class because it's a parameter of a + method, at this point the method's type is actually incomplete; + we'll have to fix it up later; mark the class for this. */ + + if (TYPE_INCOMPLETE (memtype)) + { + TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE; + if (fixup_class) + warning ("Two classes to fix up for method?? Type information may be incorrect for some classes."); + if (fixup_method) + warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes."); + fixup_class = type; /* remember this class has to be fixed up */ + fixup_method = memtype; /* remember the method type to be used in fixup */ + } + + /* HP aCC generates operator names without the "operator" keyword, and + generates null strings as names for operators that are + user-defined type conversions to basic types (e.g. operator int ()). + So try to reconstruct name as best as possible. */ + + method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name); + method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias); + + if (!method_name || /* no name */ + !*method_name || /* or null name */ + cplus_mangle_opname (method_name, DMGL_ANSI)) /* or name is an operator like "<" */ + { + char *tmp_name = cplus_demangle (method_alias, DMGL_ANSI); + char *op_string = strstr (tmp_name, "operator"); + method_name = xmalloc (strlen (op_string) + 1); /* don't overwrite VT! */ + strcpy (method_name, op_string); + } + + /* First check if a method of the same name has already been seen. */ + fn_p = fn_list; + while (fn_p) + { + if (DEPRECATED_STREQ (fn_p->field.name, method_name)) + break; + fn_p = fn_p->next; + } + + /* If no such method was found, allocate a new entry in the list */ + if (!fn_p) + { + /* Get space to record this member function */ + /* Note: alloca used; this will disappear on routine exit */ + fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field)); + memset (fn_new, 0, sizeof (struct next_fn_field)); + fn_new->next = fn_list; + fn_list = fn_new; + + /* Fill in the fields of the struct nextfield */ + + /* Record the (unmangled) method name */ + fn_list->field.name = method_name; + /* Initial space for overloaded methods */ + /* Note: xmalloc is used; this will persist after this routine exits */ + fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field))); + fn_list->field.length = 1; /* Init # of overloaded instances */ + fn_list->num_fn_fields = 5; /* # of entries for which space allocated */ + fn_p = fn_list; + ix = 0; /* array index for fn_field */ + /* Bump the total count of the distinctly named methods */ + n_fn_fields++; + } + else + /* Another overloaded instance of an already seen method name */ + { + if (++(fn_p->field.length) > fn_p->num_fn_fields) + { + /* Increase space allocated for overloaded instances */ + fn_p->field.fn_fields + = (struct fn_field *) xrealloc (fn_p->field.fn_fields, + (fn_p->num_fn_fields + 5) * sizeof (struct fn_field)); + fn_p->num_fn_fields += 5; + } + ix = fn_p->field.length - 1; /* array index for fn_field */ + } + + /* "physname" is intended to be the name of this overloaded instance. */ + if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) && + method_alias && + *method_alias) /* not a null string */ + fn_p->field.fn_fields[ix].physname = method_alias; + else + fn_p->field.fn_fields[ix].physname = method_name; + /* What's expected here is the function type */ + /* But mark it as NULL if the method was incompletely processed + We'll fix this up later when the method is fully processed */ + if (TYPE_INCOMPLETE (memtype)) + fn_p->field.fn_fields[ix].type = NULL; + else + fn_p->field.fn_fields[ix].type = memtype; + + /* For virtual functions, fill in the voffset field with the + * virtual table offset. (This is just copied over from the + * SOM record; not sure if it is what GDB expects here...). + * But if the function is a static method, set it to 1. + * + * Note that we have to add 1 because 1 indicates a static + * method, and 0 indicates a non-static, non-virtual method */ + + if (static_member) + fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC; + else + fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0; + + /* Also fill in the fcontext field with the current + * class. (The latter isn't quite right: should be the baseclass + * that defines the virtual function... Note we do have + * a variable "baseclass" that we could stuff into the fcontext + * field, but "baseclass" isn't necessarily right either, + * since the virtual function could have been defined more + * than one level up). + */ + + if (vtbl_offset != 0) + fn_p->field.fn_fields[ix].fcontext = type; + else + fn_p->field.fn_fields[ix].fcontext = NULL; + + /* Other random fields pertaining to this method */ + fn_p->field.fn_fields[ix].is_const = const_member; + fn_p->field.fn_fields[ix].is_volatile = volatile_member; /* ?? */ + switch (fieldp->dgenfield.visibility) + { + case 1: + fn_p->field.fn_fields[ix].is_protected = 1; + fn_p->field.fn_fields[ix].is_private = 0; + break; + case 2: + fn_p->field.fn_fields[ix].is_protected = 0; + fn_p->field.fn_fields[ix].is_private = 1; + break; + default: /* public */ + fn_p->field.fn_fields[ix].is_protected = 0; + fn_p->field.fn_fields[ix].is_private = 0; + } + fn_p->field.fn_fields[ix].is_stub = 0; + + /* HP aCC emits both MEMFUNC and FUNCTION entries for a method; + if the class points to the FUNCTION, there is usually separate + code for the method; but if we have a MEMFUNC, the method has + been inlined (and there is usually no FUNCTION entry) + FIXME Not sure if this test is accurate. pai/1997-08-22 */ + if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) || + (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)) + fn_p->field.fn_fields[ix].is_inlined = 1; + else + fn_p->field.fn_fields[ix].is_inlined = 0; + + fn_p->field.fn_fields[ix].dummy = 0; + + /* Bump the total count of the member functions */ + n_fn_fields_total++; + + } + else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR) + { + /* This case is for static data members of classes */ + + /* pai:: FIXME -- check that "staticmem" bit is set */ + + /* Get space to record this static member */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + memset (new, 0, sizeof (struct nextfield)); + new->next = list; + list = new; + + list->field.name = VT (objfile) + fn_fieldp->dsvar.name; + SET_FIELD_PHYSNAME (list->field, 0); /* initialize to empty */ + memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile); + + FIELD_TYPE (list->field) = memtype; + list->attributes = 0; + switch (fieldp->dgenfield.visibility) + { + case 1: + B_SET (&(list->attributes), ATTR_PROTECT); + break; + case 2: + B_SET (&(list->attributes), ATTR_PRIVATE); + break; + } + nfields++; + } + + else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD) + { + /* FIELDs follow GENFIELDs for fields of anonymous unions. + Code below is replicated from the case for FIELDs further + below, except that fieldp is replaced by fn_fieldp */ + if (!fn_fieldp->dfield.a_union) + warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set"); + /* Get space to record the next field/data-member. */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + memset (new, 0, sizeof (struct nextfield)); + new->next = list; + list = new; + + list->field.name = VT (objfile) + fn_fieldp->dfield.name; + FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset; + if (fn_fieldp->dfield.bitlength % 8) + list->field.bitsize = fn_fieldp->dfield.bitlength; + else + list->field.bitsize = 0; + + memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile); + list->field.type = memtype; + list->attributes = 0; + switch (fn_fieldp->dfield.visibility) + { + case 1: + B_SET (&(list->attributes), ATTR_PROTECT); + break; + case 2: + B_SET (&(list->attributes), ATTR_PRIVATE); + break; + } + nfields++; + } + else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR) + { + /* Field of anonymous union; union is not inside a class */ + if (!fn_fieldp->dsvar.a_union) + warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set"); + /* Get space to record the next field/data-member. */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + memset (new, 0, sizeof (struct nextfield)); + new->next = list; + list = new; + + list->field.name = VT (objfile) + fn_fieldp->dsvar.name; + FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */ + FIELD_BITSIZE (list->field) = 0; /* use length from type */ + FIELD_STATIC_KIND (list->field) = 0; + memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile); + list->field.type = memtype; + list->attributes = 0; + /* No info to set visibility -- always public */ + nfields++; + } + else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR) + { + /* Field of anonymous union; union is not inside a class */ + if (!fn_fieldp->ddvar.a_union) + warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set"); + /* Get space to record the next field/data-member. */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + memset (new, 0, sizeof (struct nextfield)); + new->next = list; + list = new; + + list->field.name = VT (objfile) + fn_fieldp->ddvar.name; + FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */ + FIELD_BITSIZE (list->field) = 0; /* use length from type */ + FIELD_STATIC_KIND (list->field) = 0; + memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile); + list->field.type = memtype; + list->attributes = 0; + /* No info to set visibility -- always public */ + nfields++; + } + else + { /* Not a method, nor a static data member, nor an anon union field */ + + /* This case is for miscellaneous type entries (local enums, + local function templates, etc.) that can be present + inside a class. */ + + /* Enums -- will be handled by other code that takes care + of DNTT_TYPE_ENUM; here we see only DNTT_TYPE_MEMENUM so + it's not clear we could have handled them here at all. */ + /* FUNC_TEMPLATE: is handled by other code (?). */ + /* MEMACCESS: modified access for inherited member. Not + sure what to do with this, ignoriing it at present. */ + + /* What other entries can appear following a GENFIELD which + we do not handle above? (MODIFIER, VFUNC handled above.) */ + + if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) && + (fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) && + (fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE)) + warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD", + fn_fieldp->dblock.kind); + } + /* walk to the next FIELD or GENFIELD */ + field = fieldp->dgenfield.nextfield; + + } + else if (fieldp->dblock.kind == DNTT_TYPE_FIELD) + { + + /* Ordinary structure/union/class field */ + struct type *anon_union_type; + + /* Get space to record the next field/data-member. */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + memset (new, 0, sizeof (struct nextfield)); + new->next = list; + list = new; + + list->field.name = VT (objfile) + fieldp->dfield.name; + + + /* A FIELD by itself (without a GENFIELD) can also be a static + member. Mark it as static with a physname of NULL. + fix_static_member_physnames will assign the physname later. */ + if (fieldp->dfield.staticmem) + { + SET_FIELD_PHYSNAME (list->field, NULL); + FIELD_BITPOS (list->field) = 0; + FIELD_BITSIZE (list->field) = 0; + } + else + /* Non-static data member */ + { + FIELD_STATIC_KIND (list->field) = 0; + FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset; + if (fieldp->dfield.bitlength % 8) + FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength; + else + FIELD_BITSIZE (list->field) = 0; + } + + memtype = hpread_type_lookup (fieldp->dfield.type, objfile); + FIELD_TYPE (list->field) = memtype; + list->attributes = 0; + switch (fieldp->dfield.visibility) + { + case 1: + B_SET (&(list->attributes), ATTR_PROTECT); + break; + case 2: + B_SET (&(list->attributes), ATTR_PRIVATE); + break; + } + nfields++; + + + /* Note 1: First, we have to check if the current field is an anonymous + union. If it is, then *its* fields are threaded along in the + nextfield chain. :-( This was supposed to help debuggers, but is + really just a nuisance since we deal with anonymous unions anyway by + checking that the name is null. So anyway, we skip over the fields + of the anonymous union. pai/1997-08-22 */ + /* Note 2: In addition, the bitoffsets for the fields of the anon union + are relative to the enclosing struct, *NOT* relative to the anon + union! This is an even bigger nuisance -- we have to go in and munge + the anon union's type information appropriately. pai/1997-08-22 */ + + /* Both tasks noted above are done by a separate function. This takes us + to the next FIELD or GENFIELD, skipping anon unions, and recursively + processing intermediate types. */ + field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile); + + } + else + { + /* neither field nor genfield ?? is this possible?? */ + /* pai:: FIXME walk to the next -- how? */ + warning ("Internal error: unexpected DNTT kind %d encountered as field of struct", + fieldp->dblock.kind); + warning ("Skipping remaining fields of struct"); + break; /* get out of loop of fields */ + } + } + + /* If it's a template, read in the instantiation list */ + if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) + { + ninstantiations = 0; + field = dn_bufp->dtemplate.expansions; + while (field.word && field.word != DNTTNIL) + { + fieldp = hpread_get_lntt (field.dnttp.index, objfile); + + /* The expansions or nextexp should point to a tagdef */ + if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF) + break; + + i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation)); + memset (i_new, 0, sizeof (struct next_instantiation)); + i_new->next = i_list; + i_list = i_new; + i_list->t = hpread_type_lookup (field, objfile); + ninstantiations++; + + /* And the "type" field of that should point to a class */ + field = fieldp->dtag.type; + fieldp = hpread_get_lntt (field.dnttp.index, objfile); + if (fieldp->dblock.kind != DNTT_TYPE_CLASS) + break; + + /* Get the next expansion */ + field = fieldp->dclass.nextexp; + } + } + TYPE_NINSTANTIATIONS (type) = ninstantiations; + if (ninstantiations > 0) + TYPE_INSTANTIATIONS (type) = (struct type **) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct type *) * ninstantiations); + for (n = ninstantiations; i_list; i_list = i_list->next) + { + n -= 1; + TYPE_INSTANTIATION (type, n) = i_list->t; + } + + + /* Copy the field-list to GDB's symbol table */ + TYPE_NFIELDS (type) = nfields; + TYPE_N_BASECLASSES (type) = n_base_classes; + TYPE_FIELDS (type) = (struct field *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct field) * nfields); + /* Copy the saved-up fields into the field vector. */ + for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next) + { + n -= 1; + TYPE_FIELD (type, n) = tmp_list->field; + } + + /* Copy the "function-field-list" (i.e., the list of member + * functions in the class) to GDB's symbol table + */ + TYPE_NFN_FIELDS (type) = n_fn_fields; + TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total; + TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct fn_fieldlist) * n_fn_fields); + for (n = n_fn_fields; fn_list; fn_list = fn_list->next) + { + n -= 1; + TYPE_FN_FIELDLIST (type, n) = fn_list->field; + } + + /* pai:: FIXME -- perhaps each bitvector should be created individually */ + for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next) + { + n -= 1; + if (tmp_list->attributes) + { + need_bitvectors = 1; + break; + } + } + + if (need_bitvectors) + { + /* pai:: this step probably redundant */ + ALLOCATE_CPLUS_STRUCT_TYPE (type); + + TYPE_FIELD_VIRTUAL_BITS (type) = + (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); + B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields); + + TYPE_FIELD_PRIVATE_BITS (type) = + (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); + B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields); + + TYPE_FIELD_PROTECTED_BITS (type) = + (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); + B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields); + + /* this field vector isn't actually used with HP aCC */ + TYPE_FIELD_IGNORE_BITS (type) = + (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); + B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields); + + while (nfields-- > 0) + { + if (B_TST (&(list->attributes), ATTR_VIRTUAL)) + SET_TYPE_FIELD_VIRTUAL (type, nfields); + if (B_TST (&(list->attributes), ATTR_PRIVATE)) + SET_TYPE_FIELD_PRIVATE (type, nfields); + if (B_TST (&(list->attributes), ATTR_PROTECT)) + SET_TYPE_FIELD_PROTECTED (type, nfields); + + list = list->next; + } + } + else + { + TYPE_FIELD_VIRTUAL_BITS (type) = NULL; + TYPE_FIELD_PROTECTED_BITS (type) = NULL; + TYPE_FIELD_PRIVATE_BITS (type) = NULL; + } + + if (has_vtable (type)) + { + /* Allocate space for class runtime information */ + TYPE_RUNTIME_PTR (type) = (struct runtime_info *) xmalloc (sizeof (struct runtime_info)); + /* Set flag for vtable */ + TYPE_VTABLE (type) = 1; + /* The first non-virtual base class with a vtable. */ + TYPE_PRIMARY_BASE (type) = primary_base_class (type); + /* The virtual base list. */ + TYPE_VIRTUAL_BASE_LIST (type) = virtual_base_list (type); + } + else + TYPE_RUNTIME_PTR (type) = NULL; + + /* If this is a local type (C++ - declared inside a function), record file name & line # */ + if (hpread_get_scope_depth (dn_bufp, objfile, 1 /* no need for real depth */ )) + { + TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info)); + TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1); + strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name); + if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0)) + TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line; + else + TYPE_LOCALTYPE_LINE (type) = 0; + } + else + TYPE_LOCALTYPE_PTR (type) = NULL; + + /* Clear the global saying what template we are in the middle of processing */ + current_template = NULL; + + return type; +} + +/* Adjust the physnames for each static member of a struct + or class type to be something like "A::x"; then various + other pieces of code that do a lookup_symbol on the phyname + work correctly. + TYPE is a pointer to the struct/class type + NAME is a char * (string) which is the class/struct name + Void return */ + +static void +fix_static_member_physnames (struct type *type, char *class_name, + struct objfile *objfile) +{ + int i; + + /* We fix the member names only for classes or structs */ + if (TYPE_CODE (type) != TYPE_CODE_STRUCT) + return; + + for (i = 0; i < TYPE_NFIELDS (type); i++) + if (TYPE_FIELD_STATIC (type, i)) + { + if (TYPE_FIELD_STATIC_PHYSNAME (type, i)) + return; /* physnames are already set */ + + SET_FIELD_PHYSNAME (TYPE_FIELDS (type)[i], + obstack_alloc (&objfile->objfile_obstack, + strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3)); + strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name); + strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::"); + strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i)); + } +} + +/* Fix-up the type structure for a CLASS so that the type entry + * for a method (previously marked with a null type in hpread_read_struct_type() + * is set correctly to METHOD. + * OBJFILE is as for other such functions. + * Void return. */ + +static void +fixup_class_method_type (struct type *class, struct type *method, + struct objfile *objfile) +{ + int i, j, k; + + if (!class || !method || !objfile) + return; + + /* Only for types that have methods */ + if ((TYPE_CODE (class) != TYPE_CODE_CLASS) && + (TYPE_CODE (class) != TYPE_CODE_UNION)) + return; + + /* Loop over all methods and find the one marked with a NULL type */ + for (i = 0; i < TYPE_NFN_FIELDS (class); i++) + for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++) + if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL) + { + /* Set the method type */ + TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method; + + /* Break out of both loops -- only one method to fix up in a class */ + goto finish; + } + +finish: + TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE; +} + + +/* If we're in the middle of processing a template, get a pointer + * to the Nth template argument. + * An example may make this clearer: + * template class q2 { + * public: + * T1 a; + * T2 b; + * }; + * The type for "a" will be "first template arg" and + * the type for "b" will be "second template arg". + * We need to look these up in order to fill in "a" and "b"'s type. + * This is called from hpread_type_lookup(). + */ +static struct type * +hpread_get_nth_template_arg (struct objfile *objfile, int n) +{ + if (current_template != NULL) + return TYPE_TEMPLATE_ARG (current_template, n).type; + else + return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG); +} + +/* Read in and internalize a TEMPL_ARG (template arg) symbol. */ + +static struct type * +hpread_read_templ_arg_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile, char *name) +{ + struct type *type; + + /* See if it's something we've already deal with. */ + type = hpread_alloc_type (hp_type, objfile); + if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG) + return type; + + /* Nope. Fill in the appropriate fields. */ + TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG; + TYPE_LENGTH (type) = 0; + TYPE_NFIELDS (type) = 0; + TYPE_NAME (type) = name; + return type; +} + +/* Read in and internalize a set debug symbol. */ + +static struct type * +hpread_read_set_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile) +{ + struct type *type; + + /* See if it's something we've already deal with. */ + type = hpread_alloc_type (hp_type, objfile); + if (TYPE_CODE (type) == TYPE_CODE_SET) + return type; + + /* Nope. Fill in the appropriate fields. */ + TYPE_CODE (type) = TYPE_CODE_SET; + TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8; + TYPE_NFIELDS (type) = 0; + TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype, + objfile); + return type; +} + +/* Read in and internalize an array debug symbol. */ + +static struct type * +hpread_read_array_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile) +{ + struct type *type; + + /* Allocate an array type symbol. + * Why no check for already-read here, like in the other + * hpread_read_xxx_type routines? Because it kept us + * from properly determining the size of the array! + */ + type = hpread_alloc_type (hp_type, objfile); + + TYPE_CODE (type) = TYPE_CODE_ARRAY; + + /* Although the hp-symtab.h does not *require* this to be the case, + * GDB is assuming that "arrayisbytes" and "elemisbytes" be consistent. + * I.e., express both array-length and element-length in bits, + * or express both array-length and element-length in bytes. + */ + if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) || + (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes))) + { + warning ("error in hpread_array_type.\n"); + return NULL; + } + else if (dn_bufp->darray.arraylength == 0x7fffffff) + { + /* The HP debug format represents char foo[]; as an array with + * length 0x7fffffff. Internally GDB wants to represent this + * as an array of length zero. + */ + TYPE_LENGTH (type) = 0; + } + else if (dn_bufp->darray.arrayisbytes) + TYPE_LENGTH (type) = dn_bufp->darray.arraylength; + else /* arraylength is in bits */ + TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8; + + TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype, + objfile); + + /* The one "field" is used to store the subscript type */ + /* Since C and C++ multi-dimensional arrays are simply represented + * as: array of array of ..., we only need one subscript-type + * per array. This subscript type is typically a subrange of integer. + * If this gets extended to support languages like Pascal, then + * we need to fix this to represent multi-dimensional arrays properly. + */ + TYPE_NFIELDS (type) = 1; + TYPE_FIELDS (type) = (struct field *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct field)); + TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype, + objfile); + return type; +} + +/* Read in and internalize a subrange debug symbol. */ +static struct type * +hpread_read_subrange_type (dnttpointer hp_type, union dnttentry *dn_bufp, + struct objfile *objfile) +{ + struct type *type; + + /* Is it something we've already dealt with. */ + type = hpread_alloc_type (hp_type, objfile); + if (TYPE_CODE (type) == TYPE_CODE_RANGE) + return type; + + /* Nope, internalize it. */ + TYPE_CODE (type) = TYPE_CODE_RANGE; + TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8; + TYPE_NFIELDS (type) = 2; + TYPE_FIELDS (type) + = (struct field *) obstack_alloc (&objfile->objfile_obstack, + 2 * sizeof (struct field)); + + if (dn_bufp->dsubr.dyn_low) + TYPE_FIELD_BITPOS (type, 0) = 0; + else + TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound; + + if (dn_bufp->dsubr.dyn_high) + TYPE_FIELD_BITPOS (type, 1) = -1; + else + TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound; + TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype, + objfile); + return type; +} + +/* struct type * hpread_type_lookup(hp_type, objfile) + * Arguments: + * hp_type: A pointer into the DNTT specifying what type we + * are about to "look up"., or else [for fundamental types + * like int, float, ...] an "immediate" structure describing + * the type. + * objfile: ? + * Return value: A pointer to a "struct type" (representation of a + * type in GDB's internal symbol table - see gdbtypes.h) + * Routine description: + * There are a variety of places when scanning the DNTT when we + * need to interpret a "type" field. The simplest and most basic + * example is when we're processing the symbol table record + * for a data symbol (a SVAR or DVAR record). That has + * a "type" field specifying the type of the data symbol. That + * "type" field is either an "immediate" type specification (for the + * fundamental types) or a DNTT pointer (for more complicated types). + * For the more complicated types, we may or may not have already + * processed the pointed-to type. (Multiple data symbols can of course + * share the same type). + * The job of hpread_type_lookup() is to process this "type" field. + * Most of the real work is done in subroutines. Here we interpret + * the immediate flag. If not immediate, chase the DNTT pointer to + * find our way to the SOM record describing the type, switch on + * the SOM kind, and then call an appropriate subroutine depending + * on what kind of type we are constructing. (e.g., an array type, + * a struct/class type, etc). + */ +static struct type * +hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile) +{ + union dnttentry *dn_bufp; + struct type *tmp_type; + + /* First see if it's a simple builtin type. */ + if (hp_type.dntti.immediate) + { + /* If this is a template argument, the argument number is + * encoded in the bitlength. All other cases, just return + * GDB's representation of this fundamental type. + */ + if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG) + return hpread_get_nth_template_arg (objfile, hp_type.dntti.bitlength); + else + return lookup_fundamental_type (objfile, + hpread_type_translate (hp_type)); + } + + /* Not a builtin type. We'll have to read it in. */ + if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile)) + dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile); + else + /* This is a fancy way of returning NULL */ + return lookup_fundamental_type (objfile, FT_VOID); + + switch (dn_bufp->dblock.kind) + { + case DNTT_TYPE_SRCFILE: + case DNTT_TYPE_MODULE: + case DNTT_TYPE_ENTRY: + case DNTT_TYPE_BEGIN: + case DNTT_TYPE_END: + case DNTT_TYPE_IMPORT: + case DNTT_TYPE_LABEL: + case DNTT_TYPE_FPARAM: + case DNTT_TYPE_SVAR: + case DNTT_TYPE_DVAR: + case DNTT_TYPE_CONST: + case DNTT_TYPE_MEMENUM: + case DNTT_TYPE_VARIANT: + case DNTT_TYPE_FILE: + case DNTT_TYPE_WITH: + case DNTT_TYPE_COMMON: + case DNTT_TYPE_COBSTRUCT: + case DNTT_TYPE_XREF: + case DNTT_TYPE_SA: + case DNTT_TYPE_MACRO: + case DNTT_TYPE_BLOCKDATA: + case DNTT_TYPE_CLASS_SCOPE: + case DNTT_TYPE_MEMACCESS: + case DNTT_TYPE_INHERITANCE: + case DNTT_TYPE_OBJECT_ID: + case DNTT_TYPE_FRIEND_CLASS: + case DNTT_TYPE_FRIEND_FUNC: + /* These are not types - something went wrong. */ + /* This is a fancy way of returning NULL */ + return lookup_fundamental_type (objfile, FT_VOID); + + case DNTT_TYPE_FUNCTION: + /* We wind up here when dealing with class member functions + * (called from hpread_read_struct_type(), i.e. when processing + * the class definition itself). + */ + return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); + + case DNTT_TYPE_DOC_FUNCTION: + return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0); + + case DNTT_TYPE_TYPEDEF: + { + /* A typedef - chase it down by making a recursive call */ + struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type, + objfile); + + /* The following came from the base hpread.c that we inherited. + * It is WRONG so I have commented it out. - RT + *... + + char *suffix; + suffix = VT (objfile) + dn_bufp->dtype.name; + TYPE_NAME (structtype) = suffix; + + * ... further explanation .... + * + * What we have here is a typedef pointing to a typedef. + * E.g., + * typedef int foo; + * typedef foo fum; + * + * What we desire to build is (these are pictures + * of "struct type"'s): + * + * +---------+ +----------+ +------------+ + * | typedef | | typedef | | fund. type | + * | type| -> | type| -> | | + * | "fum" | | "foo" | | "int" | + * +---------+ +----------+ +------------+ + * + * What this commented-out code is doing is smashing the + * name of pointed-to-type to be the same as the pointed-from + * type. So we wind up with something like: + * + * +---------+ +----------+ +------------+ + * | typedef | | typedef | | fund. type | + * | type| -> | type| -> | | + * | "fum" | | "fum" | | "fum" | + * +---------+ +----------+ +------------+ + * + */ + + return structtype; + } + + case DNTT_TYPE_TAGDEF: + { + /* Just a little different from above. We have to tack on + * an identifier of some kind (struct, union, enum, class, etc). + */ + struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type, + objfile); + char *prefix, *suffix; + suffix = VT (objfile) + dn_bufp->dtype.name; + + /* Lookup the next type in the list. It should be a structure, + * union, class, enum, or template type. + * We will need to attach that to our name. + */ + if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile)) + dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile); + else + { + complaint (&symfile_complaints, "error in hpread_type_lookup()."); + return NULL; + } + + if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT) + { + prefix = "struct "; + } + else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION) + { + prefix = "union "; + } + else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) + { + /* Further field for CLASS saying how it was really declared */ + /* 0==class, 1==union, 2==struct */ + if (dn_bufp->dclass.class_decl == 0) + prefix = "class "; + else if (dn_bufp->dclass.class_decl == 1) + prefix = "union "; + else if (dn_bufp->dclass.class_decl == 2) + prefix = "struct "; + else + prefix = ""; + } + else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM) + { + prefix = "enum "; + } + else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) + { + prefix = "template "; + } + else + { + prefix = ""; + } + + /* Build the correct name. */ + TYPE_NAME (structtype) + = (char *) obstack_alloc (&objfile->objfile_obstack, + strlen (prefix) + strlen (suffix) + 1); + TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix); + TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix); + TYPE_TAG_NAME (structtype) = suffix; + + /* For classes/structs, we have to set the static member "physnames" + to point to strings like "Class::Member" */ + if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT) + fix_static_member_physnames (structtype, suffix, objfile); + + return structtype; + } + + case DNTT_TYPE_POINTER: + /* Pointer type - call a routine in gdbtypes.c that constructs + * the appropriate GDB type. + */ + return make_pointer_type ( + hpread_type_lookup (dn_bufp->dptr.pointsto, + objfile), + NULL); + + case DNTT_TYPE_REFERENCE: + /* C++ reference type - call a routine in gdbtypes.c that constructs + * the appropriate GDB type. + */ + return make_reference_type ( + hpread_type_lookup (dn_bufp->dreference.pointsto, + objfile), + NULL); + + case DNTT_TYPE_ENUM: + return hpread_read_enum_type (hp_type, dn_bufp, objfile); + case DNTT_TYPE_SET: + return hpread_read_set_type (hp_type, dn_bufp, objfile); + case DNTT_TYPE_SUBRANGE: + return hpread_read_subrange_type (hp_type, dn_bufp, objfile); + case DNTT_TYPE_ARRAY: + return hpread_read_array_type (hp_type, dn_bufp, objfile); + case DNTT_TYPE_STRUCT: + case DNTT_TYPE_UNION: + return hpread_read_struct_type (hp_type, dn_bufp, objfile); + case DNTT_TYPE_FIELD: + return hpread_type_lookup (dn_bufp->dfield.type, objfile); + + case DNTT_TYPE_FUNCTYPE: + /* Here we want to read the function SOMs and return a + * type for it. We get here, for instance, when processing + * pointer-to-function type. + */ + return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); + + case DNTT_TYPE_PTRMEM: + /* Declares a C++ pointer-to-data-member type. + * The "pointsto" field defines the class, + * while the "memtype" field defines the pointed-to-type. + */ + { + struct type *ptrmemtype; + struct type *class_type; + struct type *memtype; + memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype, + objfile), + class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto, + objfile), + ptrmemtype = alloc_type (objfile); + smash_to_member_type (ptrmemtype, class_type, memtype); + return make_pointer_type (ptrmemtype, NULL); + } + break; + + case DNTT_TYPE_PTRMEMFUNC: + /* Defines a C++ pointer-to-function-member type. + * The "pointsto" field defines the class, + * while the "memtype" field defines the pointed-to-type. + */ + { + struct type *ptrmemtype; + struct type *class_type; + struct type *functype; + struct type *retvaltype; + int nargs; + int i; + class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto, + objfile); + functype = hpread_type_lookup (dn_bufp->dptrmem.memtype, + objfile); + retvaltype = TYPE_TARGET_TYPE (functype); + nargs = TYPE_NFIELDS (functype); + ptrmemtype = alloc_type (objfile); + + smash_to_method_type (ptrmemtype, class_type, retvaltype, + TYPE_FIELDS (functype), + TYPE_NFIELDS (functype), + 0); + return make_pointer_type (ptrmemtype, NULL); + } + break; + + case DNTT_TYPE_CLASS: + return hpread_read_struct_type (hp_type, dn_bufp, objfile); + + case DNTT_TYPE_GENFIELD: + /* Chase pointer from GENFIELD to FIELD, and make recursive + * call on that. + */ + return hpread_type_lookup (dn_bufp->dgenfield.field, objfile); + + case DNTT_TYPE_VFUNC: + /* C++ virtual function. + * We get here in the course of processing a class type which + * contains virtual functions. Just go through another level + * of indirection to get to the pointed-to function SOM. + */ + return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile); + + case DNTT_TYPE_MODIFIER: + /* Check the modifiers and then just make a recursive call on + * the "type" pointed to by the modifier DNTT. + * + * pai:: FIXME -- do we ever want to handle "m_duplicate" and + * "m_void" modifiers? Is static_flag really needed here? + * (m_static used for methods of classes, elsewhere). + */ + tmp_type = make_cv_type (dn_bufp->dmodifier.m_const, + dn_bufp->dmodifier.m_volatile, + hpread_type_lookup (dn_bufp->dmodifier.type, objfile), + 0); + return tmp_type; + + + case DNTT_TYPE_MEMFUNC: + /* Member function. Treat like a function. + * I think we get here in the course of processing a + * pointer-to-member-function type... + */ + return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); + + case DNTT_TYPE_DOC_MEMFUNC: + return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0); + + case DNTT_TYPE_TEMPLATE: + /* Template - sort of the header for a template definition, + * which like a class, points to a member list and also points + * to a TEMPLATE_ARG list of type-arguments. + */ + return hpread_read_struct_type (hp_type, dn_bufp, objfile); + + case DNTT_TYPE_TEMPLATE_ARG: + { + char *name; + /* The TEMPLATE record points to an argument list of + * TEMPLATE_ARG records, each of which describes one + * of the type-arguments. + */ + name = VT (objfile) + dn_bufp->dtempl_arg.name; + return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name); + } + + case DNTT_TYPE_FUNC_TEMPLATE: + /* We wind up here when processing a TEMPLATE type, + * if the template has member function(s). + * Treat it like a FUNCTION. + */ + return hpread_read_function_type (hp_type, dn_bufp, objfile, 0); + + case DNTT_TYPE_LINK: + /* The LINK record is used to link up templates with instantiations. + * There is no type associated with the LINK record per se. + */ + return lookup_fundamental_type (objfile, FT_VOID); + + /* Also not yet handled... */ + /* case DNTT_TYPE_DYN_ARRAY_DESC: */ + /* case DNTT_TYPE_DESC_SUBRANGE: */ + /* case DNTT_TYPE_BEGIN_EXT: */ + /* case DNTT_TYPE_INLN: */ + /* case DNTT_TYPE_INLN_LIST: */ + /* case DNTT_TYPE_ALIAS: */ + default: + /* A fancy way of returning NULL */ + return lookup_fundamental_type (objfile, FT_VOID); + } +} + +static sltpointer +hpread_record_lines (struct subfile *subfile, sltpointer s_idx, + sltpointer e_idx, struct objfile *objfile, + CORE_ADDR offset) +{ + union sltentry *sl_bufp; + + while (s_idx <= e_idx) + { + sl_bufp = hpread_get_slt (s_idx, objfile); + /* Only record "normal" entries in the SLT. */ + if (sl_bufp->snorm.sltdesc == SLT_NORMAL + || sl_bufp->snorm.sltdesc == SLT_EXIT) + record_line (subfile, sl_bufp->snorm.line, + sl_bufp->snorm.address + offset); + else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET) + record_line (subfile, sl_bufp->snormoff.line, + sl_bufp->snormoff.address + offset); + s_idx++; + } + return e_idx; +} + +/* Given a function "f" which is a member of a class, find + * the classname that it is a member of. Used to construct + * the name (e.g., "c::f") which GDB will put in the + * "demangled name" field of the function's symbol. + * Called from hpread_process_one_debug_symbol() + * If "f" is not a member function, return NULL. + */ +static char * +class_of (struct type *functype) +{ + struct type *first_param_type; + char *first_param_name; + struct type *pointed_to_type; + char *class_name; + + /* Check that the function has a first argument "this", + * and that "this" is a pointer to a class. If not, + * functype is not a member function, so return NULL. + */ + if (TYPE_NFIELDS (functype) == 0) + return NULL; + first_param_name = TYPE_FIELD_NAME (functype, 0); + if (first_param_name == NULL) + return NULL; /* paranoia */ + if (strcmp (first_param_name, "this")) + return NULL; + first_param_type = TYPE_FIELD_TYPE (functype, 0); + if (first_param_type == NULL) + return NULL; /* paranoia */ + if (TYPE_CODE (first_param_type) != TYPE_CODE_PTR) + return NULL; + + /* Get the thing that "this" points to, check that + * it's a class, and get its class name. + */ + pointed_to_type = TYPE_TARGET_TYPE (first_param_type); + if (pointed_to_type == NULL) + return NULL; /* paranoia */ + if (TYPE_CODE (pointed_to_type) != TYPE_CODE_CLASS) + return NULL; + class_name = TYPE_NAME (pointed_to_type); + if (class_name == NULL) + return NULL; /* paranoia */ + + /* The class name may be of the form "class c", in which case + * we want to strip off the leading "class ". + */ + if (strncmp (class_name, "class ", 6) == 0) + class_name += 6; + + return class_name; +} + +/* Internalize one native debug symbol. + * Called in a loop from hpread_expand_symtab(). + * Arguments: + * dn_bufp: + * name: + * section_offsets: + * objfile: + * text_offset: + * text_size: + * filename: + * index: Index of this symbol + * at_module_boundary_p Pointer to boolean flag to control caller's loop. + */ + +static void +hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name, + struct section_offsets *section_offsets, + struct objfile *objfile, CORE_ADDR text_offset, + int text_size, char *filename, int index, + int *at_module_boundary_p) +{ + unsigned long desc; + int type; + CORE_ADDR valu; + int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); + int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA (objfile)); + union dnttentry *dn_temp; + dnttpointer hp_type; + struct symbol *sym; + struct context_stack *new; + char *class_scope_name; + + /* Allocate one GDB debug symbol and fill in some default values. */ + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symbol)); + memset (sym, 0, sizeof (struct symbol)); + DEPRECATED_SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->objfile_obstack); + SYMBOL_LANGUAGE (sym) = language_auto; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + SYMBOL_LINE (sym) = 0; + SYMBOL_VALUE (sym) = 0; + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + + /* Just a trick in case the SOM debug symbol is a type definition. + * There are routines that are set up to build a GDB type symbol, given + * a SOM dnttpointer. So we set up a dummy SOM dnttpointer "hp_type". + * This allows us to call those same routines. + */ + hp_type.dnttp.extension = 1; + hp_type.dnttp.immediate = 0; + hp_type.dnttp.global = 0; + hp_type.dnttp.index = index; + + /* This "type" is the type of SOM record. + * Switch on SOM type. + */ + type = dn_bufp->dblock.kind; + switch (type) + { + case DNTT_TYPE_SRCFILE: + /* This type of symbol indicates from which source file or + * include file any following data comes. It may indicate: + * + * o The start of an entirely new source file (and thus + * a new module) + * + * o The start of a different source file due to #include + * + * o The end of an include file and the return to the original + * file. Thus if "foo.c" includes "bar.h", we see first + * a SRCFILE for foo.c, then one for bar.h, and then one for + * foo.c again. + * + * If it indicates the start of a new module then we must + * finish the symbol table of the previous module + * (if any) and start accumulating a new symbol table. + */ + + valu = text_offset; + if (!last_source_file) + { + /* + * A note on "last_source_file": this is a char* pointing + * to the actual file name. "start_symtab" sets it, + * "end_symtab" clears it. + * + * So if "last_source_file" is NULL, then either this is + * the first record we are looking at, or a previous call + * to "end_symtab()" was made to close out the previous + * module. Since we're now quitting the scan loop when we + * see a MODULE END record, we should never get here, except + * in the case that we're not using the quick look-up tables + * and have to use the old system as a fall-back. + */ + start_symtab (name, NULL, valu); + record_debugformat ("HP"); + SL_INDEX (objfile) = dn_bufp->dsfile.address; + } + + else + { + /* Either a new include file, or a SRCFILE record + * saying we are back in the main source (or out of + * a nested include file) again. + */ + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->dsfile.address, + objfile, offset); + } + + /* A note on "start_subfile". This routine will check + * the name we pass it and look for an existing subfile + * of that name. There's thus only one sub-file for the + * actual source (e.g. for "foo.c" in foo.c), despite the + * fact that we'll see lots of SRCFILE entries for foo.c + * inside foo.c. + */ + start_subfile (name, NULL); + break; + + case DNTT_TYPE_MODULE: + /* + * We no longer ignore DNTT_TYPE_MODULE symbols. The module + * represents the meaningful semantic structure of a compilation + * unit. We expect to start the psymtab-to-symtab expansion + * looking at a MODULE entry, and to end it at the corresponding + * END MODULE entry. + * + *--Begin outdated comments + * + * This record signifies the start of a new source module + * In C/C++ there is no explicit "module" construct in the language, + * but each compilation unit is implicitly a module and they + * do emit the DNTT_TYPE_MODULE records. + * The end of the module is marked by a matching DNTT_TYPE_END record. + * + * The reason GDB gets away with ignoring the DNTT_TYPE_MODULE record + * is it notices the DNTT_TYPE_END record for the previous + * module (see comments under DNTT_TYPE_END case), and then treats + * the next DNTT_TYPE_SRCFILE record as if it were the module-start record. + * (i.e., it makes a start_symtab() call). + * This scheme seems a little convoluted, but I'll leave it + * alone on the principle "if it ain't broke don't fix + * it". (RT). + * + *-- End outdated comments + */ + + valu = text_offset; + if (!last_source_file) + { + /* Start of a new module. We know this because "last_source_file" + * is NULL, which can only happen the first time or if we just + * made a call to end_symtab() to close out the previous module. + */ + start_symtab (name, NULL, valu); + SL_INDEX (objfile) = dn_bufp->dmodule.address; + } + else + { + /* This really shouldn't happen if we're using the quick + * look-up tables, as it would mean we'd scanned past an + * END MODULE entry. But if we're not using the tables, + * we started the module on the SRCFILE entry, so it's ok. + * For now, accept this. + */ + /* warning( "Error expanding psymtab, missed module end, found entry for %s", + * name ); + */ + *at_module_boundary_p = -1; + } + + start_subfile (name, NULL); + break; + + case DNTT_TYPE_FUNCTION: + case DNTT_TYPE_ENTRY: + /* A function or secondary entry point. */ + valu = dn_bufp->dfunc.lowaddr + offset; + + /* Record lines up to this point. */ + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->dfunc.address, + objfile, offset); + + WITHIN_FUNCTION (objfile) = 1; + CURRENT_FUNCTION_VALUE (objfile) = valu; + + /* Stack must be empty now. */ + if (context_stack_depth != 0) + lbrac_unmatched_complaint (symnum); + new = push_context (0, valu); + + /* Built a type for the function. This includes processing + * the symbol records for the function parameters. + */ + SYMBOL_CLASS (sym) = LOC_BLOCK; + SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1); + + /* All functions in C++ have prototypes. For C we don't have enough + information in the debug info. */ + if (SYMBOL_LANGUAGE (sym) == language_cplus) + TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED; + + /* The "DEPRECATED_SYMBOL_NAME" field is expected to be the mangled name + * (if any), which we get from the "alias" field of the SOM record + * if that exists. + */ + if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) && + dn_bufp->dfunc.alias && /* has an alias */ + *(char *) (VT (objfile) + dn_bufp->dfunc.alias)) /* not a null string */ + DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias; + else + DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name; + + /* Special hack to get around HP compilers' insistence on + * reporting "main" as "_MAIN_" for C/C++ */ + if ((strcmp (DEPRECATED_SYMBOL_NAME (sym), "_MAIN_") == 0) && + (strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0)) + DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name; + + /* The SYMBOL_CPLUS_DEMANGLED_NAME field is expected to + * be the demangled name. + */ + if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) + { + /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up + * calling the demangler in libiberty (cplus_demangle()) to + * do the job. This generally does the job, even though + * it's intended for the GNU compiler and not the aCC compiler + * Note that SYMBOL_INIT_DEMANGLED_NAME calls the + * demangler with arguments DMGL_PARAMS | DMGL_ANSI. + * Generally, we don't want params when we display + * a demangled name, but when I took out the DMGL_PARAMS, + * some things broke, so I'm leaving it in here, and + * working around the issue in stack.c. - RT + */ + SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->objfile_obstack); + if ((DEPRECATED_SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) && + (!SYMBOL_CPLUS_DEMANGLED_NAME (sym))) + { + + /* Well, the symbol name is mangled, but the + * demangler in libiberty failed so the demangled + * field is still NULL. Try to + * do the job ourselves based on the "name" field + * in the SOM record. A complication here is that + * the name field contains only the function name + * (like "f"), whereas we want the class qualification + * (as in "c::f"). Try to reconstruct that. + */ + char *basename; + char *classname; + char *dem_name; + basename = VT (objfile) + dn_bufp->dfunc.name; + classname = class_of (SYMBOL_TYPE (sym)); + if (classname) + { + dem_name = xmalloc (strlen (basename) + strlen (classname) + 3); + strcpy (dem_name, classname); + strcat (dem_name, "::"); + strcat (dem_name, basename); + SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name; + SYMBOL_LANGUAGE (sym) = language_cplus; + } + } + } + + /* Add the function symbol to the list of symbols in this blockvector */ + if (dn_bufp->dfunc.global) + add_symbol_to_list (sym, &global_symbols); + else + add_symbol_to_list (sym, &file_symbols); + new->name = sym; + + /* Search forward to the next BEGIN and also read + * in the line info up to that point. + * Not sure why this is needed. + * In HP FORTRAN this code is harmful since there + * may not be a BEGIN after the FUNCTION. + * So I made it C/C++ specific. - RT + */ + if (dn_bufp->dfunc.language == HP_LANGUAGE_C || + dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) + { + while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN) + { + dn_bufp = hpread_get_lntt (++index, objfile); + if (dn_bufp->dblock.extension) + continue; + } + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->dbegin.address, + objfile, offset); + SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile); + } + record_line (current_subfile, SYMBOL_LINE (sym), valu); + break; + + case DNTT_TYPE_DOC_FUNCTION: + valu = dn_bufp->ddocfunc.lowaddr + offset; + + /* Record lines up to this point. */ + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->ddocfunc.address, + objfile, offset); + + WITHIN_FUNCTION (objfile) = 1; + CURRENT_FUNCTION_VALUE (objfile) = valu; + /* Stack must be empty now. */ + if (context_stack_depth != 0) + lbrac_unmatched_complaint (symnum); + new = push_context (0, valu); + + /* Built a type for the function. This includes processing + * the symbol records for the function parameters. + */ + SYMBOL_CLASS (sym) = LOC_BLOCK; + SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1); + + /* The "DEPRECATED_SYMBOL_NAME" field is expected to be the mangled name + * (if any), which we get from the "alias" field of the SOM record + * if that exists. + */ + if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) && + dn_bufp->ddocfunc.alias && /* has an alias */ + *(char *) (VT (objfile) + dn_bufp->ddocfunc.alias)) /* not a null string */ + DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias; + else + DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name; + + /* Special hack to get around HP compilers' insistence on + * reporting "main" as "_MAIN_" for C/C++ */ + if ((strcmp (DEPRECATED_SYMBOL_NAME (sym), "_MAIN_") == 0) && + (strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0)) + DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name; + + if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) + { + + /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up + * calling the demangler in libiberty (cplus_demangle()) to + * do the job. This generally does the job, even though + * it's intended for the GNU compiler and not the aCC compiler + * Note that SYMBOL_INIT_DEMANGLED_NAME calls the + * demangler with arguments DMGL_PARAMS | DMGL_ANSI. + * Generally, we don't want params when we display + * a demangled name, but when I took out the DMGL_PARAMS, + * some things broke, so I'm leaving it in here, and + * working around the issue in stack.c. - RT + */ + SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->objfile_obstack); + + if ((DEPRECATED_SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) && + (!SYMBOL_CPLUS_DEMANGLED_NAME (sym))) + { + + /* Well, the symbol name is mangled, but the + * demangler in libiberty failed so the demangled + * field is still NULL. Try to + * do the job ourselves based on the "name" field + * in the SOM record. A complication here is that + * the name field contains only the function name + * (like "f"), whereas we want the class qualification + * (as in "c::f"). Try to reconstruct that. + */ + char *basename; + char *classname; + char *dem_name; + basename = VT (objfile) + dn_bufp->ddocfunc.name; + classname = class_of (SYMBOL_TYPE (sym)); + if (classname) + { + dem_name = xmalloc (strlen (basename) + strlen (classname) + 3); + strcpy (dem_name, classname); + strcat (dem_name, "::"); + strcat (dem_name, basename); + SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name; + SYMBOL_LANGUAGE (sym) = language_cplus; + } + } + } + + /* Add the function symbol to the list of symbols in this blockvector */ + if (dn_bufp->ddocfunc.global) + add_symbol_to_list (sym, &global_symbols); + else + add_symbol_to_list (sym, &file_symbols); + new->name = sym; + + /* Search forward to the next BEGIN and also read + * in the line info up to that point. + * Not sure why this is needed. + * In HP FORTRAN this code is harmful since there + * may not be a BEGIN after the FUNCTION. + * So I made it C/C++ specific. - RT + */ + if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C || + dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) + { + while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN) + { + dn_bufp = hpread_get_lntt (++index, objfile); + if (dn_bufp->dblock.extension) + continue; + } + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->dbegin.address, + objfile, offset); + SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile); + } + record_line (current_subfile, SYMBOL_LINE (sym), valu); + break; + + case DNTT_TYPE_BEGIN: + /* Begin a new scope. */ + if (context_stack_depth == 1 /* this means we're at function level */ && + context_stack[0].name != NULL /* this means it's a function */ && + context_stack[0].depth == 0 /* this means it's the first BEGIN + we've seen after the FUNCTION */ + ) + { + /* This is the first BEGIN after a FUNCTION. + * We ignore this one, since HP compilers always insert + * at least one BEGIN, i.e. it's: + * + * FUNCTION + * argument symbols + * BEGIN + * local symbols + * (possibly nested BEGIN ... END's if there are inner { } blocks) + * END + * END + * + * By ignoring this first BEGIN, the local symbols get treated + * as belonging to the function scope, and "print func::local_sym" + * works (which is what we want). + */ + + /* All we do here is increase the depth count associated with + * the FUNCTION entry in the context stack. This ensures that + * the next BEGIN we see (if any), representing a real nested { } + * block, will get processed. + */ + + context_stack[0].depth++; + + } + else + { + + /* Record lines up to this SLT pointer. */ + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->dbegin.address, + objfile, offset); + /* Calculate start address of new scope */ + valu = hpread_get_location (dn_bufp->dbegin.address, objfile); + valu += offset; /* Relocate for dynamic loading */ + /* We use the scope start DNTT index as nesting depth identifier! */ + desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile); + new = push_context (desc, valu); + } + break; + + case DNTT_TYPE_END: + /* End a scope. */ + + /* Valid end kinds are: + * MODULE + * FUNCTION + * WITH + * COMMON + * BEGIN + * CLASS_SCOPE + */ + + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->dend.address, + objfile, offset); + switch (dn_bufp->dend.endkind) + { + case DNTT_TYPE_MODULE: + /* Ending a module ends the symbol table for that module. + * Calling end_symtab() has the side effect of clearing the + * last_source_file pointer, which in turn signals + * process_one_debug_symbol() to treat the next DNTT_TYPE_SRCFILE + * record as a module-begin. + */ + valu = text_offset + text_size + offset; + + /* Tell our caller that we're done with expanding the + * debug information for a module. + */ + *at_module_boundary_p = 1; + + /* Don't do this, as our caller will do it! + + * (void) end_symtab (valu, objfile, 0); + */ + break; + + case DNTT_TYPE_FUNCTION: + /* Ending a function, well, ends the function's scope. */ + dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index, + objfile); + valu = dn_temp->dfunc.hiaddr + offset; + /* Insert func params into local list */ + merge_symbol_lists (¶m_symbols, &local_symbols); + new = pop_context (); + /* Make a block for the local symbols within. */ + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, valu, objfile); + WITHIN_FUNCTION (objfile) = 0; /* This may have to change for Pascal */ + local_symbols = new->locals; + param_symbols = new->params; + break; + + case DNTT_TYPE_BEGIN: + if (context_stack_depth == 1 && + context_stack[0].name != NULL && + context_stack[0].depth == 1) + { + /* This is the END corresponding to the + * BEGIN which we ignored - see DNTT_TYPE_BEGIN case above. + */ + context_stack[0].depth--; + } + else + { + /* Ending a local scope. */ + valu = hpread_get_location (dn_bufp->dend.address, objfile); + /* Why in the hell is this needed? */ + valu += offset + 9; /* Relocate for dynamic loading */ + new = pop_context (); + desc = dn_bufp->dend.beginscope.dnttp.index; + if (desc != new->depth) + lbrac_mismatch_complaint (symnum); + + /* Make a block for the local symbols within. */ + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, valu, objfile); + local_symbols = new->locals; + param_symbols = new->params; + } + break; + + case DNTT_TYPE_WITH: + /* Since we ignore the DNTT_TYPE_WITH that starts the scope, + * we can ignore the DNTT_TYPE_END that ends it. + */ + break; + + case DNTT_TYPE_COMMON: + /* End a FORTRAN common block. We don't currently handle these */ + complaint (&symfile_complaints, + "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n"); + break; + + case DNTT_TYPE_CLASS_SCOPE: + + /* pai: FIXME Not handling nested classes for now -- must + * maintain a stack */ + class_scope_name = NULL; + +#if 0 + /* End a class scope */ + valu = hpread_get_location (dn_bufp->dend.address, objfile); + /* Why in the hell is this needed? */ + valu += offset + 9; /* Relocate for dynamic loading */ + new = pop_context (); + desc = dn_bufp->dend.beginscope.dnttp.index; + if (desc != new->depth) + lbrac_mismatch_complaint ((char *) symnum); + /* Make a block for the local symbols within. */ + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, valu, objfile); + local_symbols = new->locals; + param_symbols = new->params; +#endif + break; + + default: + complaint (&symfile_complaints, + "internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind."); + break; + } + break; + + /* DNTT_TYPE_IMPORT is not handled */ + + case DNTT_TYPE_LABEL: + SYMBOL_DOMAIN (sym) = LABEL_DOMAIN; + break; + + case DNTT_TYPE_FPARAM: + /* Function parameters. */ + /* Note 1: This code was present in the 4.16 sources, and then + removed, because fparams are handled in + hpread_read_function_type(). However, while fparam symbols + are indeed handled twice, this code here cannot be removed + because then they don't get added to the local symbol list of + the function's code block, which leads to a failure to look + up locals, "this"-relative member names, etc. So I've put + this code back in. pai/1997-07-21 */ + /* Note 2: To fix a defect, we stopped adding FPARAMS to local_symbols + in hpread_read_function_type(), so FPARAMS had to be handled + here. I changed the location to be the appropriate argument + kinds rather than LOC_LOCAL. pai/1997-08-08 */ + /* Note 3: Well, the fix in Note 2 above broke argument printing + in traceback frames, and further it makes assumptions about the + order of the FPARAM entries from HP compilers (cc and aCC in particular + generate them in reverse orders -- fixing one breaks for the other). + So I've added code in hpread_read_function_type() to add fparams + to a param_symbols list for the current context level. These are + then merged into local_symbols when a function end is reached. + pai/1997-08-11 */ + + break; /* do nothing; handled in hpread_read_function_type() */ + +#if 0 /* Old code */ + if (dn_bufp->dfparam.regparam) + SYMBOL_CLASS (sym) = LOC_REGISTER; + else if (dn_bufp->dfparam.indirect) + SYMBOL_CLASS (sym) = LOC_REF_ARG; + else + SYMBOL_CLASS (sym) = LOC_ARG; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + if (dn_bufp->dfparam.copyparam) + { + SYMBOL_VALUE (sym) = dn_bufp->dfparam.location; +#ifdef HPREAD_ADJUST_STACK_ADDRESS + SYMBOL_VALUE (sym) + += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); +#endif + } + else + SYMBOL_VALUE (sym) = dn_bufp->dfparam.location; + SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile); + add_symbol_to_list (sym, &fparam_symbols); + break; +#endif + + case DNTT_TYPE_SVAR: + /* Static variables. */ + SYMBOL_CLASS (sym) = LOC_STATIC; + + /* Note: There is a case that arises with globals in shared + * libraries where we need to set the address to LOC_INDIRECT. + * This case is if you have a global "g" in one library, and + * it is referenced "extern g;" in another library. + * If we're processing the symbols for the referencing library, + * we'll see a global "g", but in this case the address given + * in the symbol table contains a pointer to the real "g". + * We use the storage class LOC_INDIRECT to indicate this. RT + */ + if (is_in_import_list (DEPRECATED_SYMBOL_NAME (sym), objfile)) + SYMBOL_CLASS (sym) = LOC_INDIRECT; + + SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset; + SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile); + + if (dn_bufp->dsvar.global) + add_symbol_to_list (sym, &global_symbols); + + else if (WITHIN_FUNCTION (objfile)) + add_symbol_to_list (sym, &local_symbols); + + else + add_symbol_to_list (sym, &file_symbols); + + if (dn_bufp->dsvar.thread_specific) + { + /* Thread-local variable. + */ + SYMBOL_CLASS (sym) = LOC_HP_THREAD_LOCAL_STATIC; + SYMBOL_BASEREG (sym) = CR27_REGNUM; + + if (objfile->flags & OBJF_SHARED) + { + /* + * This variable is not only thread local but + * in a shared library. + * + * Alas, the shared lib structures are private + * to "somsolib.c". But C lets us point to one. + */ + struct so_list *so; + + if (objfile->obj_private == NULL) + error ("Internal error in reading shared library information."); + + so = ((obj_private_data_t *) (objfile->obj_private))->so_info; + if (so == NULL) + error ("Internal error in reading shared library information."); + + /* Thread-locals in shared libraries do NOT have the + * standard offset ("data_offset"), so we re-calculate + * where to look for this variable, using a call-back + * to interpret the private shared-library data. + */ + SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + + so_lib_thread_start_addr (so); + } + } + break; + + case DNTT_TYPE_DVAR: + /* Dynamic variables. */ + if (dn_bufp->ddvar.regvar) + SYMBOL_CLASS (sym) = LOC_REGISTER; + else + SYMBOL_CLASS (sym) = LOC_LOCAL; + + SYMBOL_VALUE (sym) = dn_bufp->ddvar.location; +#ifdef HPREAD_ADJUST_STACK_ADDRESS + SYMBOL_VALUE (sym) + += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile)); +#endif + SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile); + if (dn_bufp->ddvar.global) + add_symbol_to_list (sym, &global_symbols); + else if (WITHIN_FUNCTION (objfile)) + add_symbol_to_list (sym, &local_symbols); + else + add_symbol_to_list (sym, &file_symbols); + break; + + case DNTT_TYPE_CONST: + /* A constant (pascal?). */ + SYMBOL_CLASS (sym) = LOC_CONST; + SYMBOL_VALUE (sym) = dn_bufp->dconst.location; + SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile); + if (dn_bufp->dconst.global) + add_symbol_to_list (sym, &global_symbols); + else if (WITHIN_FUNCTION (objfile)) + add_symbol_to_list (sym, &local_symbols); + else + add_symbol_to_list (sym, &file_symbols); + break; + + case DNTT_TYPE_TYPEDEF: + /* A typedef. We do want to process these, since a name is + * added to the domain for the typedef'ed name. + */ + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile); + if (dn_bufp->dtype.global) + add_symbol_to_list (sym, &global_symbols); + else if (WITHIN_FUNCTION (objfile)) + add_symbol_to_list (sym, &local_symbols); + else + add_symbol_to_list (sym, &file_symbols); + break; + + case DNTT_TYPE_TAGDEF: + { + int global = dn_bufp->dtag.global; + /* Structure, union, enum, template, or class tag definition */ + /* We do want to process these, since a name is + * added to the domain for the tag name (and if C++ class, + * for the typename also). + */ + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; + + /* The tag contains in its "type" field a pointer to the + * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, DNTT_TYPE_ENUM, + * DNTT_TYPE_CLASS or DNTT_TYPE_TEMPLATE + * record that actually defines the type. + */ + SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile); + TYPE_NAME (sym->type) = DEPRECATED_SYMBOL_NAME (sym); + TYPE_TAG_NAME (sym->type) = DEPRECATED_SYMBOL_NAME (sym); + if (dn_bufp->dtag.global) + add_symbol_to_list (sym, &global_symbols); + else if (WITHIN_FUNCTION (objfile)) + add_symbol_to_list (sym, &local_symbols); + else + add_symbol_to_list (sym, &file_symbols); + + /* If this is a C++ class, then we additionally + * need to define a typedef for the + * class type. E.g., so that the name "c" becomes visible as + * a type name when the user says "class c { ... }". + * In order to figure this out, we need to chase down the "type" + * field to get to the DNTT_TYPE_CLASS record. + * + * We also add the typename for ENUM. Though this isn't + * strictly correct, it is necessary because of the debug info + * generated by the aCC compiler, in which we cannot + * distinguish between: + * enum e { ... }; + * and + * typedef enum { ... } e; + * I.e., the compiler emits the same debug info for the above + * two cases, in both cases "e" appearing as a tagdef. + * Therefore go ahead and generate the typename so that + * "ptype e" will work in the above cases. + * + * We also add the typename for TEMPLATE, so as to allow "ptype t" + * when "t" is a template name. + */ + if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile)) + dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile); + else + { + complaint (&symfile_complaints, "error processing class tagdef"); + return; + } + if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS || + dn_bufp->dblock.kind == DNTT_TYPE_ENUM || + dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) + { + struct symbol *newsym; + + newsym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symbol)); + memset (newsym, 0, sizeof (struct symbol)); + DEPRECATED_SYMBOL_NAME (newsym) = name; + SYMBOL_LANGUAGE (newsym) = language_auto; + SYMBOL_DOMAIN (newsym) = VAR_DOMAIN; + SYMBOL_LINE (newsym) = 0; + SYMBOL_VALUE (newsym) = 0; + SYMBOL_CLASS (newsym) = LOC_TYPEDEF; + SYMBOL_TYPE (newsym) = sym->type; + if (global) + add_symbol_to_list (newsym, &global_symbols); + else if (WITHIN_FUNCTION (objfile)) + add_symbol_to_list (newsym, &local_symbols); + else + add_symbol_to_list (newsym, &file_symbols); + } + } + break; + + case DNTT_TYPE_POINTER: + /* Declares a pointer type. Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_ENUM: + /* Declares an enum type. Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_MEMENUM: + /* Member of enum */ + /* Ignored at this level, but hpread_read_enum_type() will take + * care of walking the list of enumeration members. + */ + break; + + case DNTT_TYPE_SET: + /* Declares a set type. Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_SUBRANGE: + /* Declares a subrange type. Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_ARRAY: + /* Declares an array type. Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_STRUCT: + case DNTT_TYPE_UNION: + /* Declares an struct/union type. + * Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_FIELD: + /* Structure/union/class field */ + /* Ignored at this level, but hpread_read_struct_type() will take + * care of walking the list of structure/union/class members. + */ + break; + + /* DNTT_TYPE_VARIANT is not handled by GDB */ + + /* DNTT_TYPE_FILE is not handled by GDB */ + + case DNTT_TYPE_FUNCTYPE: + /* Function type */ + /* Ignored at this level, handled within hpread_type_lookup() */ + break; + + case DNTT_TYPE_WITH: + /* This is emitted within methods to indicate "with " + * scoping rules (i.e., indicate that the class data members + * are directly visible). + * However, since GDB already infers this by looking at the + * "this" argument, interpreting the DNTT_TYPE_WITH + * symbol record is unnecessary. + */ + break; + + case DNTT_TYPE_COMMON: + /* FORTRAN common. Not yet handled. */ + complaint (&symfile_complaints, + "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON."); + break; + + /* DNTT_TYPE_COBSTRUCT is not handled by GDB. */ + /* DNTT_TYPE_XREF is not handled by GDB. */ + /* DNTT_TYPE_SA is not handled by GDB. */ + /* DNTT_TYPE_MACRO is not handled by GDB */ + + case DNTT_TYPE_BLOCKDATA: + /* Not sure what this is - part of FORTRAN support maybe? + * Anyway, not yet handled. + */ + complaint (&symfile_complaints, + "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA."); + break; + + case DNTT_TYPE_CLASS_SCOPE: + + + + /* The compiler brackets member functions with a CLASS_SCOPE/END + * pair of records, presumably to put them in a different scope + * from the module scope where they are normally defined. + * E.g., in the situation: + * void f() { ... } + * void c::f() { ...} + * The member function "c::f" will be bracketed by a CLASS_SCOPE/END. + * This causes "break f" at the module level to pick the + * the file-level function f(), not the member function + * (which needs to be referenced via "break c::f"). + * + * Here we record the class name to generate the demangled names of + * member functions later. + * + * FIXME Not being used now for anything -- cplus_demangle seems + * enough for getting the class-qualified names of functions. We + * may need this for handling nested classes and types. */ + + /* pai: FIXME Not handling nested classes for now -- need to + * maintain a stack */ + + dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile); + if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF) + class_scope_name = VT (objfile) + dn_temp->dtag.name; + else + class_scope_name = NULL; + +#if 0 + + /* Begin a new scope. */ + SL_INDEX (objfile) = hpread_record_lines (current_subfile, + SL_INDEX (objfile), + dn_bufp->dclass_scope.address, + objfile, offset); + valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile); + valu += offset; /* Relocate for dynamic loading */ + desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile); + /* We use the scope start DNTT index as the nesting depth identifier! */ + new = push_context (desc, valu); +#endif + break; + + case DNTT_TYPE_REFERENCE: + /* Declares a C++ reference type. Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_PTRMEM: + /* Declares a C++ pointer-to-data-member type. This does not + * need to be handled at this level; being a type description it + * is instead handled at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_PTRMEMFUNC: + /* Declares a C++ pointer-to-function-member type. This does not + * need to be handled at this level; being a type description it + * is instead handled at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_CLASS: + /* Declares a class type. + * Should not be necessary to do anything + * with the type at this level; these are processed + * at the hpread_type_lookup() level. + */ + break; + + case DNTT_TYPE_GENFIELD: + /* I believe this is used for class member functions */ + /* Ignored at this level, but hpread_read_struct_type() will take + * care of walking the list of class members. + */ + break; + + case DNTT_TYPE_VFUNC: + /* Virtual function */ + /* This does not have to be handled at this level; handled in + * the course of processing class symbols. + */ + break; + + case DNTT_TYPE_MEMACCESS: + /* DDE ignores this symbol table record. + * It has something to do with "modified access" to class members. + * I'll assume we can safely ignore it too. + */ + break; + + case DNTT_TYPE_INHERITANCE: + /* These don't have to be handled here, since they are handled + * within hpread_read_struct_type() in the process of constructing + * a class type. + */ + break; + + case DNTT_TYPE_FRIEND_CLASS: + case DNTT_TYPE_FRIEND_FUNC: + /* These can safely be ignored, as GDB doesn't need this + * info. DDE only uses it in "describe". We may later want + * to extend GDB's "ptype" to give this info, but for now + * it seems safe enough to ignore it. + */ + break; + + case DNTT_TYPE_MODIFIER: + /* Intended to supply "modified access" to a type */ + /* From the way DDE handles this, it looks like it always + * modifies a type. Therefore it is safe to ignore it at this + * level, and handle it in hpread_type_lookup(). + */ + break; + + case DNTT_TYPE_OBJECT_ID: + /* Just ignore this - that's all DDE does */ + break; + + case DNTT_TYPE_MEMFUNC: + /* Member function */ + /* This does not have to be handled at this level; handled in + * the course of processing class symbols. + */ + break; + + case DNTT_TYPE_DOC_MEMFUNC: + /* Member function */ + /* This does not have to be handled at this level; handled in + * the course of processing class symbols. + */ + break; + + case DNTT_TYPE_TEMPLATE: + /* Template - sort of the header for a template definition, + * which like a class, points to a member list and also points + * to a TEMPLATE_ARG list of type-arguments. + * We do not need to process TEMPLATE records at this level though. + */ + break; + + case DNTT_TYPE_TEMPLATE_ARG: + /* The TEMPLATE record points to an argument list of + * TEMPLATE_ARG records, each of which describes one + * of the type-arguments. + * We do not need to process TEMPLATE_ARG records at this level though. + */ + break; + + case DNTT_TYPE_FUNC_TEMPLATE: + /* This will get emitted for member functions of templates. + * But we don't need to process this record at this level though, + * we will process it in the course of processing a TEMPLATE + * record. + */ + break; + + case DNTT_TYPE_LINK: + /* The LINK record is used to link up templates with instantiations. */ + /* It is not clear why this is needed, and furthermore aCC does + * not appear to generate this, so I think we can safely ignore it. - RT + */ + break; + + /* DNTT_TYPE_DYN_ARRAY_DESC is not handled by GDB */ + /* DNTT_TYPE_DESC_SUBRANGE is not handled by GDB */ + /* DNTT_TYPE_BEGIN_EXT is not handled by GDB */ + /* DNTT_TYPE_INLN is not handled by GDB */ + /* DNTT_TYPE_INLN_LIST is not handled by GDB */ + /* DNTT_TYPE_ALIAS is not handled by GDB */ + + default: + break; + } +} + +/* Get nesting depth for a DNTT entry. + * DN_BUFP points to a DNTT entry. + * OBJFILE is the object file. + * REPORT_NESTED is a flag; if 0, real nesting depth is + * reported, if it is 1, the function simply returns a + * non-zero value if the nesting depth is anything > 0. + * + * Return value is an integer. 0 => not a local type / name + * positive return => type or name is local to some + * block or function. + */ + + +/* elz: ATTENTION: FIXME: NOTE: WARNING!!!! + this function now returns 0 right away. It was taking too much time + at start up. Now, though, the local types are not handled correctly. + */ + + +static int +hpread_get_scope_depth (union dnttentry *dn_bufp, struct objfile *objfile, + int report_nested) +{ + int index; + union dnttentry *dn_tmp; + short depth = 0; +/****************************/ + return 0; +/****************************/ + + index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block)); + + while (--index >= 0) + { + dn_tmp = hpread_get_lntt (index, objfile); + switch (dn_tmp->dblock.kind) + { + case DNTT_TYPE_MODULE: + return depth; + case DNTT_TYPE_END: + /* index is signed int; dnttp.index is 29-bit unsigned int! */ + index = (int) dn_tmp->dend.beginscope.dnttp.index; + break; + case DNTT_TYPE_BEGIN: + case DNTT_TYPE_FUNCTION: + case DNTT_TYPE_DOC_FUNCTION: + case DNTT_TYPE_WITH: + case DNTT_TYPE_COMMON: + case DNTT_TYPE_CLASS_SCOPE: + depth++; + if (report_nested) + return 1; + break; + default: + break; + } + } + return depth; +} + +/* Adjust the bitoffsets for all fields of an anonymous union of + type TYPE by negative BITS. This handles HP aCC's hideous habit + of giving members of anonymous unions bit offsets relative to the + enclosing structure instead of relative to the union itself. */ + +static void +hpread_adjust_bitoffsets (struct type *type, int bits) +{ + int i; + + /* This is done only for unions; caller had better check that + it is an anonymous one. */ + if (TYPE_CODE (type) != TYPE_CODE_UNION) + return; + + /* Adjust each field; since this is a union, there are no base + classes. Also no static membes. Also, no need for recursion as + the members of this union if themeselves structs or unions, have + the correct bitoffsets; if an anonymous union is a member of this + anonymous union, the code in hpread_read_struct_type() will + adjust for that. */ + + for (i = 0; i < TYPE_NFIELDS (type); i++) + TYPE_FIELD_BITPOS (type, i) -= bits; +} + +/* Because of quirks in HP compilers' treatment of anonymous unions inside + classes, we have to chase through a chain of threaded FIELD entries. + If we encounter an anonymous union in the chain, we must recursively skip over + that too. + + This function does a "next" in the chain of FIELD entries, but transparently + skips over anonymous unions' fields (recursively). + + Inputs are the number of times to do "next" at the top level, the dnttpointer + (FIELD) and entry pointer (FIELDP) for the dntt record corresponding to it, + and the ubiquitous objfile parameter. (Note: FIELDP is a **.) Return value + is a dnttpointer for the new field after all the skipped ones */ + +static dnttpointer +hpread_get_next_skip_over_anon_unions (int skip_fields, dnttpointer field, + union dnttentry **fieldp, + struct objfile *objfile) +{ + struct type *anon_type; + int i; + int bitoffset; + char *name; + + for (i = 0; i < skip_fields; i++) + { + /* Get type of item we're looking at now; recursively processes the types + of these intermediate items we skip over, so they aren't lost. */ + anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile); + anon_type = CHECK_TYPEDEF (anon_type); + bitoffset = (*fieldp)->dfield.bitoffset; + name = VT (objfile) + (*fieldp)->dfield.name; + /* First skip over one item to avoid stack death on recursion */ + field = (*fieldp)->dfield.nextfield; + *fieldp = hpread_get_lntt (field.dnttp.index, objfile); + /* Do we have another anonymous union? If so, adjust the bitoffsets + of its members and skip over its members. */ + if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) && + (!name || DEPRECATED_STREQ (name, ""))) + { + hpread_adjust_bitoffsets (anon_type, bitoffset); + field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile); + } + } + return field; +} diff --git a/contrib/gdb/gdb/i386-nat.c b/contrib/gdb/gdb/i386-nat.c index 53a81a463eb..a20e9b06635 100644 --- a/contrib/gdb/gdb/i386-nat.c +++ b/contrib/gdb/gdb/i386-nat.c @@ -1,5 +1,6 @@ -/* Intel x86 (a.k.a. ia32) native-dependent code. - Copyright (C) 2001 Free Software Foundation, Inc. +/* Native-dependent code for the i386. + + Copyright 2001, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -23,24 +24,24 @@ #include "command.h" #include "gdbcmd.h" -/* Support for hardware watchpoints and breakpoints using the x86 +/* Support for hardware watchpoints and breakpoints using the i386 debug registers. This provides several functions for inserting and removing - hardware-assisted breakpoints and watchpoints, testing if - one or more of the watchpoints triggered and at what address, - checking whether a given region can be watched, etc. + hardware-assisted breakpoints and watchpoints, testing if one or + more of the watchpoints triggered and at what address, checking + whether a given region can be watched, etc. - A target which wants to use these functions should define - several macros, such as `target_insert_watchpoint' and - `target_stopped_data_address', listed in target.h, to call - the appropriate functions below. It should also define + A target which wants to use these functions should define several + macros, such as `target_insert_watchpoint' and + `target_stopped_data_address', listed in target.h, to call the + appropriate functions below. It should also define I386_USE_GENERIC_WATCHPOINTS in its tm.h file. - In addition, each target should provide several low-level - macros that will be called to insert watchpoints and hardware - breakpoints into the inferior, remove them, and check their - status. These macros are: + In addition, each target should provide several low-level macros + that will be called to insert watchpoints and hardware breakpoints + into the inferior, remove them, and check their status. These + macros are: I386_DR_LOW_SET_CONTROL -- set the debug control (DR7) register to a given value @@ -54,21 +55,20 @@ I386_DR_LOW_GET_STATUS -- return the value of the debug status (DR6) register. - The functions below implement debug registers sharing by - reference counts, and allow to watch regions up to 16 bytes - long. */ + The functions below implement debug registers sharing by reference + counts, and allow to watch regions up to 16 bytes long. */ #ifdef I386_USE_GENERIC_WATCHPOINTS /* Support for 8-byte wide hw watchpoints. */ #ifndef TARGET_HAS_DR_LEN_8 -#define TARGET_HAS_DR_LEN_8 0 +#define TARGET_HAS_DR_LEN_8 0 #endif /* Debug registers' indices. */ -#define DR_NADDR 4 /* the number of debug address registers */ -#define DR_STATUS 6 /* index of debug status register (DR6) */ -#define DR_CONTROL 7 /* index of debug control register (DR7) */ +#define DR_NADDR 4 /* The number of debug address registers. */ +#define DR_STATUS 6 /* Index of debug status register (DR6). */ +#define DR_CONTROL 7 /* Index of debug control register (DR7). */ /* DR7 Debug Control register fields. */ @@ -78,46 +78,46 @@ #define DR_CONTROL_SIZE 4 /* Watchpoint/breakpoint read/write fields in DR7. */ -#define DR_RW_EXECUTE (0x0) /* break on instruction execution */ -#define DR_RW_WRITE (0x1) /* break on data writes */ -#define DR_RW_READ (0x3) /* break on data reads or writes */ +#define DR_RW_EXECUTE (0x0) /* Break on instruction execution. */ +#define DR_RW_WRITE (0x1) /* Break on data writes. */ +#define DR_RW_READ (0x3) /* Break on data reads or writes. */ /* This is here for completeness. No platform supports this - functionality yet (as of Mar-2001). Note that the DE flag in the + functionality yet (as of March 2001). Note that the DE flag in the CR4 register needs to be set to support this. */ #ifndef DR_RW_IORW -#define DR_RW_IORW (0x2) /* break on I/O reads or writes */ +#define DR_RW_IORW (0x2) /* Break on I/O reads or writes. */ #endif /* Watchpoint/breakpoint length fields in DR7. The 2-bit left shift is so we could OR this with the read/write field defined above. */ -#define DR_LEN_1 (0x0 << 2) /* 1-byte region watch or breakpt */ -#define DR_LEN_2 (0x1 << 2) /* 2-byte region watch */ -#define DR_LEN_4 (0x3 << 2) /* 4-byte region watch */ -#define DR_LEN_8 (0x2 << 2) /* 8-byte region watch (x86-64) */ +#define DR_LEN_1 (0x0 << 2) /* 1-byte region watch or breakpoint. */ +#define DR_LEN_2 (0x1 << 2) /* 2-byte region watch. */ +#define DR_LEN_4 (0x3 << 2) /* 4-byte region watch. */ +#define DR_LEN_8 (0x2 << 2) /* 8-byte region watch (AMD64). */ /* Local and Global Enable flags in DR7. When the Local Enable flag is set, the breakpoint/watchpoint is enabled only for the current task; the processor automatically - clears this flag on every task switch. When the Global Enable - flag is set, the breakpoint/watchpoint is enabled for all tasks; - the processor never clears this flag. + clears this flag on every task switch. When the Global Enable flag + is set, the breakpoint/watchpoint is enabled for all tasks; the + processor never clears this flag. Currently, all watchpoint are locally enabled. If you need to enable them globally, read the comment which pertains to this in i386_insert_aligned_watchpoint below. */ -#define DR_LOCAL_ENABLE_SHIFT 0 /* extra shift to the local enable bit */ -#define DR_GLOBAL_ENABLE_SHIFT 1 /* extra shift to the global enable bit */ -#define DR_ENABLE_SIZE 2 /* 2 enable bits per debug register */ +#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit. */ +#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit. */ +#define DR_ENABLE_SIZE 2 /* Two enable bits per debug register. */ /* Local and global exact breakpoint enable flags (a.k.a. slowdown flags). These are only required on i386, to allow detection of the exact instruction which caused a watchpoint to break; i486 and later processors do that automatically. We set these flags for - back compatibility. */ + backwards compatibility. */ #define DR_LOCAL_SLOWDOWN (0x100) -#define DR_GLOBAL_SLOWDOWN (0x200) +#define DR_GLOBAL_SLOWDOWN (0x200) /* Fields reserved by Intel. This includes the GD (General Detect Enable) flag, which causes a debug exception to be generated when a @@ -129,7 +129,7 @@ /* Auxiliary helper macros. */ /* A value that masks all fields in DR7 that are reserved by Intel. */ -#define I386_DR_CONTROL_MASK (~DR_CONTROL_RESERVED) +#define I386_DR_CONTROL_MASK (~DR_CONTROL_RESERVED) /* The I'th debug register is vacant if its Local and Global Enable bits are reset in the Debug Control register. */ @@ -168,13 +168,13 @@ /* Mirror the inferior's DRi registers. We keep the status and control registers separated because they don't hold addresses. */ static CORE_ADDR dr_mirror[DR_NADDR]; -static unsigned dr_status_mirror, dr_control_mirror; +static unsigned dr_status_mirror, dr_control_mirror; /* Reference counts for each debug register. */ -static int dr_ref_count[DR_NADDR]; +static int dr_ref_count[DR_NADDR]; /* Whether or not to print the mirrored debug registers. */ -static int maint_show_dr; +static int maint_show_dr; /* Types of operations supported by i386_handle_nonaligned_watchpoint. */ typedef enum { WP_INSERT, WP_REMOVE, WP_COUNT } i386_wp_op_t; @@ -182,8 +182,8 @@ typedef enum { WP_INSERT, WP_REMOVE, WP_COUNT } i386_wp_op_t; /* Internal functions. */ /* Return the value of a 4-bit field for DR7 suitable for watching a - region of LEN bytes for accesses of type TYPE. LEN is assumed - to have the value of 1, 2, or 4. */ + region of LEN bytes for accesses of type TYPE. LEN is assumed to + have the value of 1, 2, or 4. */ static unsigned i386_length_and_rw_bits (int len, enum target_hw_bp_type type); /* Insert a watchpoint at address ADDR, which is assumed to be aligned @@ -206,16 +206,17 @@ static int i386_remove_aligned_watchpoint (CORE_ADDR addr, number of debug registers required to watch a region at address ADDR whose length is LEN for accesses of type TYPE. Return 0 on successful insertion or removal, a positive number when queried - about the number of registers, or -1 on failure. If WHAT is not - a valid value, bombs through internal_error. */ + about the number of registers, or -1 on failure. If WHAT is not a + valid value, bombs through internal_error. */ static int i386_handle_nonaligned_watchpoint (i386_wp_op_t what, CORE_ADDR addr, int len, enum target_hw_bp_type type); /* Implementation. */ -/* Clear the reference counts and forget everything we knew about - the debug registers. */ +/* Clear the reference counts and forget everything we knew about the + debug registers. */ + void i386_cleanup_dregs (void) { @@ -230,17 +231,23 @@ i386_cleanup_dregs (void) dr_status_mirror = 0; } -/* Reset all debug registers at each new startup - to avoid missing watchpoints after restart. */ +#ifndef LINUX_CHILD_POST_STARTUP_INFERIOR + +/* Reset all debug registers at each new startup to avoid missing + watchpoints after restart. */ + void child_post_startup_inferior (ptid_t ptid) { i386_cleanup_dregs (); } -/* Print the values of the mirrored debug registers. - This is called when maint_show_dr is non-zero. To set that - up, type "maint show-debug-regs" at GDB's prompt. */ +#endif /* LINUX_CHILD_POST_STARTUP_INFERIOR */ + +/* Print the values of the mirrored debug registers. This is called + when maint_show_dr is non-zero. To set that up, type "maint + show-debug-regs" at GDB's prompt. */ + static void i386_show_dr (const char *func, CORE_ADDR addr, int len, enum target_hw_bp_type type) @@ -266,7 +273,8 @@ i386_show_dr (const char *func, CORE_ADDR addr, dr_control_mirror, dr_status_mirror); ALL_DEBUG_REGISTERS(i) { - printf_unfiltered ("\tDR%d: addr=0x%s, ref.count=%d DR%d: addr=0x%s, ref.count=%d\n", + printf_unfiltered ("\ +\tDR%d: addr=0x%s, ref.count=%d DR%d: addr=0x%s, ref.count=%d\n", i, paddr(dr_mirror[i]), dr_ref_count[i], i+1, paddr(dr_mirror[i+1]), dr_ref_count[i+1]); i++; @@ -274,8 +282,9 @@ i386_show_dr (const char *func, CORE_ADDR addr, } /* Return the value of a 4-bit field for DR7 suitable for watching a - region of LEN bytes for accesses of type TYPE. LEN is assumed - to have the value of 1, 2, or 4. */ + region of LEN bytes for accesses of type TYPE. LEN is assumed to + have the value of 1, 2, or 4. */ + static unsigned i386_length_and_rw_bits (int len, enum target_hw_bp_type type) { @@ -289,18 +298,21 @@ i386_length_and_rw_bits (int len, enum target_hw_bp_type type) case hw_write: rw = DR_RW_WRITE; break; - case hw_read: /* x86 doesn't support data-read watchpoints */ + case hw_read: + /* The i386 doesn't support data-read watchpoints. */ case hw_access: rw = DR_RW_READ; break; #if 0 - case hw_io_access: /* not yet supported */ + /* Not yet supported. */ + case hw_io_access: rw = DR_RW_IORW; break; #endif default: internal_error (__FILE__, __LINE__, "\ -Invalid hw breakpoint type %d in i386_length_and_rw_bits.\n", (int)type); +Invalid hardware breakpoint type %d in i386_length_and_rw_bits.\n", + (int) type); } switch (len) @@ -316,7 +328,7 @@ Invalid hw breakpoint type %d in i386_length_and_rw_bits.\n", (int)type); return (DR_LEN_8 | rw); default: internal_error (__FILE__, __LINE__, "\ -Invalid hw breakpoint length %d in i386_length_and_rw_bits.\n", len); +Invalid hardware breakpoint length %d in i386_length_and_rw_bits.\n", len); } } @@ -325,6 +337,7 @@ Invalid hw breakpoint length %d in i386_length_and_rw_bits.\n", len); value of the bits from DR7 which describes the length and access type of the region to be watched by this watchpoint. Return 0 on success, -1 on failure. */ + static int i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits) { @@ -362,7 +375,7 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits) dr_ref_count[i] = 1; I386_DR_SET_RW_LEN (i, len_rw_bits); /* Note: we only enable the watchpoint locally, i.e. in the current - task. Currently, no x86 target allows or supports global + task. Currently, no i386 target allows or supports global watchpoints; however, if any target would want that in the future, GDB should probably provide a command to control whether to enable watchpoints globally or locally, and the code below @@ -384,6 +397,7 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits) value of the bits from DR7 which describes the length and access type of the region watched by this watchpoint. Return 0 on success, -1 on failure. */ + static int i386_remove_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits) { @@ -415,42 +429,46 @@ i386_remove_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits) number of debug registers required to watch a region at address ADDR whose length is LEN for accesses of type TYPE. Return 0 on successful insertion or removal, a positive number when queried - about the number of registers, or -1 on failure. If WHAT is not - a valid value, bombs through internal_error. */ + about the number of registers, or -1 on failure. If WHAT is not a + valid value, bombs through internal_error. */ + static int i386_handle_nonaligned_watchpoint (i386_wp_op_t what, CORE_ADDR addr, int len, enum target_hw_bp_type type) { - int align; - int size; - int rv = 0, status = 0; + int retval = 0, status = 0; int max_wp_len = TARGET_HAS_DR_LEN_8 ? 8 : 4; static int size_try_array[8][8] = { - {1, 1, 1, 1, 1, 1, 1, 1}, /* trying size one */ - {2, 1, 2, 1, 2, 1, 2, 1}, /* trying size two */ - {2, 1, 2, 1, 2, 1, 2, 1}, /* trying size three */ - {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size four */ - {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size five */ - {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size six */ - {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size seven */ - {8, 1, 2, 1, 4, 1, 2, 1}, /* trying size eight */ + {1, 1, 1, 1, 1, 1, 1, 1}, /* Trying size one. */ + {2, 1, 2, 1, 2, 1, 2, 1}, /* Trying size two. */ + {2, 1, 2, 1, 2, 1, 2, 1}, /* Trying size three. */ + {4, 1, 2, 1, 4, 1, 2, 1}, /* Trying size four. */ + {4, 1, 2, 1, 4, 1, 2, 1}, /* Trying size five. */ + {4, 1, 2, 1, 4, 1, 2, 1}, /* Trying size six. */ + {4, 1, 2, 1, 4, 1, 2, 1}, /* Trying size seven. */ + {8, 1, 2, 1, 4, 1, 2, 1}, /* Trying size eight. */ }; while (len > 0) { - align = addr % max_wp_len; - /* Four(eigth on x86_64) is the maximum length an x86 debug register + int align = addr % max_wp_len; + /* Four (eigth on AMD64) is the maximum length a debug register can watch. */ - size = size_try_array[len > max_wp_len ? (max_wp_len - 1) : len - 1][align]; + int try = (len > max_wp_len ? (max_wp_len - 1) : len - 1); + int size = size_try_array[try][align]; + if (what == WP_COUNT) - /* size_try_array[] is defined so that each iteration through - the loop is guaranteed to produce an address and a size - that can be watched with a single debug register. Thus, - for counting the registers required to watch a region, we - simply need to increment the count on each iteration. */ - rv++; + { + /* size_try_array[] is defined such that each iteration + through the loop is guaranteed to produce an address and a + size that can be watched with a single debug register. + Thus, for counting the registers required to watch a + region, we simply need to increment the count on each + iteration. */ + retval++; + } else { unsigned len_rw = i386_length_and_rw_bits (size, type); @@ -473,17 +491,20 @@ Invalid value %d of operation in i386_handle_nonaligned_watchpoint.\n", to our failure to insert this watchpoint and tries to remove it. */ if (status) - rv = status; + retval = status; } + addr += size; len -= size; } - return rv; + + return retval; } /* Insert a watchpoint to watch a memory region which starts at address ADDR and whose length is LEN bytes. Watch memory accesses of the type TYPE. Return 0 on success, -1 on failure. */ + int i386_insert_watchpoint (CORE_ADDR addr, int len, int type) { @@ -531,25 +552,26 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type) /* Return non-zero if we can watch a memory region that starts at address ADDR and whose length is LEN bytes. */ + int i386_region_ok_for_watchpoint (CORE_ADDR addr, int len) { + int nregs; + /* Compute how many aligned watchpoints we would need to cover this region. */ - int nregs = i386_handle_nonaligned_watchpoint (WP_COUNT, addr, len, - hw_write); - + nregs = i386_handle_nonaligned_watchpoint (WP_COUNT, addr, len, hw_write); return nregs <= DR_NADDR ? 1 : 0; } /* If the inferior has some watchpoint that triggered, return the - address associated with that watchpoint. Otherwise, return - zero. */ + address associated with that watchpoint. Otherwise, return zero. */ + CORE_ADDR i386_stopped_data_address (void) { + CORE_ADDR addr = 0; int i; - CORE_ADDR ret = 0; dr_status_mirror = I386_DR_LOW_GET_STATUS (); @@ -560,22 +582,23 @@ i386_stopped_data_address (void) watchpoint, not a hardware breakpoint. The reason is that GDB doesn't call the target_stopped_data_address method except for data watchpoints. In other words, I'm - being paranoiac. */ + being paranoid. */ && I386_DR_GET_RW_LEN (i) != 0) { - ret = dr_mirror[i]; + addr = dr_mirror[i]; if (maint_show_dr) - i386_show_dr ("watchpoint_hit", ret, -1, hw_write); + i386_show_dr ("watchpoint_hit", addr, -1, hw_write); } } - if (maint_show_dr && ret == 0) + if (maint_show_dr && addr == 0) i386_show_dr ("stopped_data_addr", 0, 0, hw_write); - return ret; + return addr; } /* Return non-zero if the inferior has some break/watchpoint that triggered. */ + int i386_stopped_by_hwbp (void) { @@ -610,6 +633,7 @@ i386_insert_hw_breakpoint (CORE_ADDR addr, void *shadow) /* Remove a hardware-assisted breakpoint at address ADDR. SHADOW is unused. Return 0 on success, -1 on failure. */ + int i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow) { @@ -623,8 +647,11 @@ i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow) } #endif /* I386_USE_GENERIC_WATCHPOINTS */ - + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386_nat (void); + void _initialize_i386_nat (void) { diff --git a/contrib/gdb/gdb/i386-nto-tdep.c b/contrib/gdb/gdb/i386-nto-tdep.c new file mode 100755 index 00000000000..6d2f4923b3e --- /dev/null +++ b/contrib/gdb/gdb/i386-nto-tdep.c @@ -0,0 +1,306 @@ +/* i386-nto-tdep.c - i386 specific functionality for QNX Neutrino. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by QNX Software Systems Ltd. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "gdb_string.h" +#include "gdb_assert.h" +#include "defs.h" +#include "frame.h" +#include "target.h" +#include "regcache.h" +#include "solib-svr4.h" +#include "i386-tdep.h" +#include "nto-tdep.h" +#include "osabi.h" +#include "i387-tdep.h" + +#ifndef X86_CPU_FXSR +#define X86_CPU_FXSR (1L << 12) +#endif + +/* Why 13? Look in our /usr/include/x86/context.h header at the + x86_cpu_registers structure and you'll see an 'exx' junk register + that is just filler. Don't ask me, ask the kernel guys. */ +#define NUM_GPREGS 13 + +/* Map a GDB register number to an offset in the reg structure. */ +static int regmap[] = { + (7 * 4), /* eax */ + (6 * 4), /* ecx */ + (5 * 4), /* edx */ + (4 * 4), /* ebx */ + (11 * 4), /* esp */ + (2 * 4), /* epb */ + (1 * 4), /* esi */ + (0 * 4), /* edi */ + (8 * 4), /* eip */ + (10 * 4), /* eflags */ + (9 * 4), /* cs */ + (12 * 4), /* ss */ + (-1 * 4) /* filler */ +}; + +/* Given a gdb regno, return the offset into Neutrino's register structure + or -1 if register is unknown. */ +static int +nto_reg_offset (int regno) +{ + return (regno >= 0 && regno < NUM_GPREGS) ? regmap[regno] : -1; +} + +static void +i386nto_supply_gregset (char *gpregs) +{ + unsigned regno; + int empty = 0; + + for (regno = 0; regno < FP0_REGNUM; regno++) + { + int offset = nto_reg_offset (regno); + if (offset == -1) + supply_register (regno, (char *) &empty); + else + supply_register (regno, gpregs + offset); + } +} + +static void +i386nto_supply_fpregset (char *fpregs) +{ + if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) + i387_supply_fxsave (current_regcache, -1, fpregs); + else + i387_supply_fsave (current_regcache, -1, fpregs); +} + +static void +i386nto_supply_regset (int regset, char *data) +{ + switch (regset) + { + case NTO_REG_GENERAL: /* QNX has different ordering of GP regs than GDB. */ + i386nto_supply_gregset (data); + break; + case NTO_REG_FLOAT: + i386nto_supply_fpregset (data); + break; + } +} + +static int +i386nto_regset_id (int regno) +{ + if (regno == -1) + return NTO_REG_END; + else if (regno < FP0_REGNUM) + return NTO_REG_GENERAL; + else if (regno < FPC_REGNUM) + return NTO_REG_FLOAT; + + return -1; /* Error. */ +} + +static int +i386nto_register_area (int regno, int regset, unsigned *off) +{ + int len; + + *off = 0; + if (regset == NTO_REG_GENERAL) + { + if (regno == -1) + return NUM_GPREGS * 4; + + *off = nto_reg_offset (regno); + if (*off == -1) + return 0; + return 4; + } + else if (regset == NTO_REG_FLOAT) + { + unsigned off_adjust, regsize, regset_size; + + if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) + { + off_adjust = 32; + regsize = 16; + regset_size = 512; + } + else + { + off_adjust = 28; + regsize = 10; + regset_size = 128; + } + + if (regno == -1) + return regset_size; + + *off = (regno - FP0_REGNUM) * regsize + off_adjust; + return 10; + /* Why 10 instead of regsize? GDB only stores 10 bytes per FP + register so if we're sending a register back to the target, + we only want pdebug to write 10 bytes so as not to clobber + the reserved 6 bytes in the fxsave structure. */ + } + return -1; +} + +static int +i386nto_regset_fill (int regset, char *data) +{ + if (regset == NTO_REG_GENERAL) + { + int regno; + + for (regno = 0; regno < NUM_GPREGS; regno++) + { + int offset = nto_reg_offset (regno); + if (offset != -1) + regcache_collect (regno, data + offset); + } + } + else if (regset == NTO_REG_FLOAT) + { + if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) + i387_fill_fxsave (data, -1); + else + i387_fill_fsave (data, -1); + } + else + return -1; + + return 0; +} + +static struct link_map_offsets * +i386nto_svr4_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + lmo.r_debug_size = 8; /* The actual size is 20 bytes, but + only 8 bytes are used. */ + lmo.r_map_offset = 4; + lmo.r_map_size = 4; + + lmo.link_map_size = 20; /* The actual size is 552 bytes, but + only 20 bytes are used. */ + lmo.l_addr_offset = 0; + lmo.l_addr_size = 4; + + lmo.l_name_offset = 4; + lmo.l_name_size = 4; + + lmo.l_next_offset = 12; + lmo.l_next_size = 4; + + lmo.l_prev_offset = 16; + lmo.l_prev_size = 4; + } + + return lmp; +} + +static int +i386nto_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + return name && strcmp ("__signalstub", name) == 0; +} + +#define I386_NTO_SIGCONTEXT_OFFSET 136 + +/* Assuming NEXT_FRAME is a frame following a QNX Neutrino sigtramp + routine, return the address of the associated sigcontext structure. */ + +static CORE_ADDR +i386nto_sigcontext_addr (struct frame_info *next_frame) +{ + char buf[4]; + CORE_ADDR sp; + + frame_unwind_register (next_frame, SP_REGNUM, buf); + sp = extract_unsigned_integer (buf, 4); + + return sp + I386_NTO_SIGCONTEXT_OFFSET; +} + +static void +init_i386nto_ops (void) +{ + current_nto_target.nto_regset_id = i386nto_regset_id; + current_nto_target.nto_supply_gregset = i386nto_supply_gregset; + current_nto_target.nto_supply_fpregset = i386nto_supply_fpregset; + current_nto_target.nto_supply_altregset = nto_dummy_supply_regset; + current_nto_target.nto_supply_regset = i386nto_supply_regset; + current_nto_target.nto_register_area = i386nto_register_area; + current_nto_target.nto_regset_fill = i386nto_regset_fill; + current_nto_target.nto_fetch_link_map_offsets = + i386nto_svr4_fetch_link_map_offsets; +} + +static void +i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* NTO uses ELF. */ + i386_elf_init_abi (info, gdbarch); + + /* Neutrino rewinds to look more normal. Need to override the i386 + default which is [unfortunately] to decrement the PC. */ + set_gdbarch_decr_pc_after_break (gdbarch, 0); + + /* NTO has shared libraries. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + + set_gdbarch_pc_in_sigtramp (gdbarch, i386nto_pc_in_sigtramp); + tdep->sigcontext_addr = i386nto_sigcontext_addr; + tdep->sc_pc_offset = 56; + tdep->sc_sp_offset = 68; + + /* Setjmp()'s return PC saved in EDX (5). */ + tdep->jb_pc_offset = 20; /* 5x32 bit ints in. */ + + set_solib_svr4_fetch_link_map_offsets (gdbarch, + i386nto_svr4_fetch_link_map_offsets); + + /* Our loader handles solib relocations slightly differently than svr4. */ + TARGET_SO_RELOCATE_SECTION_ADDRESSES = nto_relocate_section_addresses; + + /* Supply a nice function to find our solibs. */ + TARGET_SO_FIND_AND_OPEN_SOLIB = nto_find_and_open_solib; + + init_i386nto_ops (); +} + +void +_initialize_i386nto_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO, + i386nto_init_abi); +} diff --git a/contrib/gdb/gdb/i386-sol2-tdep.c b/contrib/gdb/gdb/i386-sol2-tdep.c new file mode 100644 index 00000000000..0da32d5c0e2 --- /dev/null +++ b/contrib/gdb/gdb/i386-sol2-tdep.c @@ -0,0 +1,120 @@ +/* Target-dependent code for Solaris x86. + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "value.h" +#include "osabi.h" + +#include "i386-tdep.h" + +/* From . */ +static int i386_sol2_gregset_reg_offset[] = +{ + 11 * 4, /* %eax */ + 10 * 4, /* %ecx */ + 9 * 4, /* %edx */ + 8 * 4, /* %ebx */ + 17 * 4, /* %esp */ + 6 * 4, /* %ebp */ + 5 * 4, /* %esi */ + 4 * 4, /* %edi */ + 14 * 4, /* %eip */ + 16 * 4, /* %eflags */ + 15 * 4, /* %cs */ + 18 * 4, /* %ss */ + 3 * 4, /* %ds */ + 2 * 4, /* %es */ + 1 * 4, /* %fs */ + 0 * 4 /* %gs */ +}; + +static int +i386_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + /* Signal handler frames under Solaris 2 are recognized by a return + address of 0xffffffff. */ + return (pc == 0xffffffff); +} + +/* Solaris doesn't have a `struct sigcontext', but it does have a + `mcontext_t' that contains the saved set of machine registers. */ + +static CORE_ADDR +i386_sol2_mcontext_addr (struct frame_info *next_frame) +{ + CORE_ADDR sp, ucontext_addr; + + sp = frame_unwind_register_unsigned (next_frame, I386_ESP_REGNUM); + ucontext_addr = get_frame_memory_unsigned (next_frame, sp + 8, 4); + + return ucontext_addr + 36; +} + +/* Solaris 2. */ + +static void +i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Solaris is SVR4-based. */ + i386_svr4_init_abi (info, gdbarch); + + /* Solaris reserves space for its FPU emulator in `fpregset_t'. + There is also some space reserved for the registers of a Weitek + math coprocessor. */ + tdep->gregset_reg_offset = i386_sol2_gregset_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386_sol2_gregset_reg_offset); + tdep->sizeof_gregset = 19 * 4; + tdep->sizeof_fpregset = 380; + + tdep->sigcontext_addr = i386_sol2_mcontext_addr; + tdep->sc_reg_offset = tdep->gregset_reg_offset; + tdep->sc_num_regs = tdep->gregset_num_regs; + + /* Signal trampolines are slightly different from SVR4. */ + set_gdbarch_pc_in_sigtramp (gdbarch, i386_sol2_pc_in_sigtramp); +} + + +static enum gdb_osabi +i386_sol2_osabi_sniffer (bfd *abfd) +{ + /* If we have a section named .SUNW_version, then it is almost + certainly Solaris 2. */ + if (bfd_get_section_by_name (abfd, ".SUNW_version")) + return GDB_OSABI_SOLARIS; + + return GDB_OSABI_UNKNOWN; +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386_sol2_tdep (void); + +void +_initialize_i386_sol2_tdep (void) +{ + /* Register an ELF OS ABI sniffer for Solaris 2 binaries. */ + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, + i386_sol2_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SOLARIS, + i386_sol2_init_abi); +} diff --git a/contrib/gdb/gdb/i386-stub.c b/contrib/gdb/gdb/i386-stub.c new file mode 100644 index 00000000000..1251567e912 --- /dev/null +++ b/contrib/gdb/gdb/i386-stub.c @@ -0,0 +1,952 @@ +/**************************************************************************** + + THIS SOFTWARE IS NOT COPYRIGHTED + + HP offers the following for use in the public domain. HP makes no + warranty with regard to the software or it's performance and the + user accepts the software "AS IS" with all faults. + + HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD + TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +****************************************************************************/ + +/**************************************************************************** + * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ + * + * Module name: remcom.c $ + * Revision: 1.34 $ + * Date: 91/03/09 12:29:49 $ + * Contributor: Lake Stevens Instrument Division$ + * + * Description: low level support for gdb debugger. $ + * + * Considerations: only works on target hardware $ + * + * Written by: Glenn Engel $ + * ModuleState: Experimental $ + * + * NOTES: See Below $ + * + * Modified for 386 by Jim Kingdon, Cygnus Support. + * + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a trap #1. + * + * The external function exceptionHandler() is + * used to attach a specific handler to a specific 386 vector number. + * It should use the same privilege level it runs at. It should + * install it as an interrupt gate so that interrupts are masked + * while the handler runs. + * + * Because gdb will sometimes write to the stack area to execute function + * calls, this program cannot rely on using the supervisor stack so it + * uses it's own stack area reserved in the int array remcomStack. + * + ************* + * + * The following gdb commands are supported: + * + * command function Return value + * + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * + * k kill + * + * ? What was the last sigval ? SNN (signal NN) + * + * All commands and responses are sent with a packet which includes a + * checksum. A packet consists of + * + * $#. + * + * where + * :: + * :: < two hex digits computed as modulo 256 sum of > + * + * When a packet is received, it is first acknowledged with either '+' or '-'. + * '+' indicates a successful transfer. '-' indicates a failed transfer. + * + * Example: + * + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 + * + ****************************************************************************/ + +#include +#include + +/************************************************************************ + * + * external low-level support routines + */ + +extern void putDebugChar(); /* write a single character */ +extern int getDebugChar(); /* read and return a single char */ +extern void exceptionHandler(); /* assign an exception handler */ + +/************************************************************************/ +/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ +/* at least NUMREGBYTES*2 are needed for register packets */ +#define BUFMAX 400 + +static char initialized; /* boolean flag. != 0 means we've been initialized */ + +int remote_debug; +/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ + +static const char hexchars[]="0123456789abcdef"; + +/* Number of registers. */ +#define NUMREGS 16 + +/* Number of bytes of registers. */ +#define NUMREGBYTES (NUMREGS * 4) + +enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, + PC /* also known as eip */, + PS /* also known as eflags */, + CS, SS, DS, ES, FS, GS}; + +/* + * these should not be static cuz they can be used outside this module + */ +int registers[NUMREGS]; + +#define STACKSIZE 10000 +int remcomStack[STACKSIZE/sizeof(int)]; +static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; + +/*************************** ASSEMBLY CODE MACROS *************************/ +/* */ + +extern void +return_to_prog (); + +/* Restore the program's registers (including the stack pointer, which + means we get the right stack and don't have to worry about popping our + return address and any stack frames and so on) and return. */ +asm(".text"); +asm(".globl _return_to_prog"); +asm("_return_to_prog:"); +asm(" movw _registers+44, %ss"); +asm(" movl _registers+16, %esp"); +asm(" movl _registers+4, %ecx"); +asm(" movl _registers+8, %edx"); +asm(" movl _registers+12, %ebx"); +asm(" movl _registers+20, %ebp"); +asm(" movl _registers+24, %esi"); +asm(" movl _registers+28, %edi"); +asm(" movw _registers+48, %ds"); +asm(" movw _registers+52, %es"); +asm(" movw _registers+56, %fs"); +asm(" movw _registers+60, %gs"); +asm(" movl _registers+36, %eax"); +asm(" pushl %eax"); /* saved eflags */ +asm(" movl _registers+40, %eax"); +asm(" pushl %eax"); /* saved cs */ +asm(" movl _registers+32, %eax"); +asm(" pushl %eax"); /* saved eip */ +asm(" movl _registers, %eax"); +/* use iret to restore pc and flags together so + that trace flag works right. */ +asm(" iret"); + +#define BREAKPOINT() asm(" int $3"); + +/* Put the error code here just in case the user cares. */ +int gdb_i386errcode; +/* Likewise, the vector number here (since GDB only gets the signal + number through the usual means, and that's not very specific). */ +int gdb_i386vector = -1; + +/* GDB stores segment registers in 32-bit words (that's just the way + m-i386v.h is written). So zero the appropriate areas in registers. */ +#define SAVE_REGISTERS1() \ + asm ("movl %eax, _registers"); \ + asm ("movl %ecx, _registers+4"); \ + asm ("movl %edx, _registers+8"); \ + asm ("movl %ebx, _registers+12"); \ + asm ("movl %ebp, _registers+20"); \ + asm ("movl %esi, _registers+24"); \ + asm ("movl %edi, _registers+28"); \ + asm ("movw $0, %ax"); \ + asm ("movw %ds, _registers+48"); \ + asm ("movw %ax, _registers+50"); \ + asm ("movw %es, _registers+52"); \ + asm ("movw %ax, _registers+54"); \ + asm ("movw %fs, _registers+56"); \ + asm ("movw %ax, _registers+58"); \ + asm ("movw %gs, _registers+60"); \ + asm ("movw %ax, _registers+62"); +#define SAVE_ERRCODE() \ + asm ("popl %ebx"); \ + asm ("movl %ebx, _gdb_i386errcode"); +#define SAVE_REGISTERS2() \ + asm ("popl %ebx"); /* old eip */ \ + asm ("movl %ebx, _registers+32"); \ + asm ("popl %ebx"); /* old cs */ \ + asm ("movl %ebx, _registers+40"); \ + asm ("movw %ax, _registers+42"); \ + asm ("popl %ebx"); /* old eflags */ \ + asm ("movl %ebx, _registers+36"); \ + /* Now that we've done the pops, we can save the stack pointer."); */ \ + asm ("movw %ss, _registers+44"); \ + asm ("movw %ax, _registers+46"); \ + asm ("movl %esp, _registers+16"); + +/* See if mem_fault_routine is set, if so just IRET to that address. */ +#define CHECK_FAULT() \ + asm ("cmpl $0, _mem_fault_routine"); \ + asm ("jne mem_fault"); + +asm (".text"); +asm ("mem_fault:"); +/* OK to clobber temp registers; we're just going to end up in set_mem_err. */ +/* Pop error code from the stack and save it. */ +asm (" popl %eax"); +asm (" movl %eax, _gdb_i386errcode"); + +asm (" popl %eax"); /* eip */ +/* We don't want to return there, we want to return to the function + pointed to by mem_fault_routine instead. */ +asm (" movl _mem_fault_routine, %eax"); +asm (" popl %ecx"); /* cs (low 16 bits; junk in hi 16 bits). */ +asm (" popl %edx"); /* eflags */ + +/* Remove this stack frame; when we do the iret, we will be going to + the start of a function, so we want the stack to look just like it + would after a "call" instruction. */ +asm (" leave"); + +/* Push the stuff that iret wants. */ +asm (" pushl %edx"); /* eflags */ +asm (" pushl %ecx"); /* cs */ +asm (" pushl %eax"); /* eip */ + +/* Zero mem_fault_routine. */ +asm (" movl $0, %eax"); +asm (" movl %eax, _mem_fault_routine"); + +asm ("iret"); + +#define CALL_HOOK() asm("call _remcomHandler"); + +/* This function is called when a i386 exception occurs. It saves + * all the cpu regs in the _registers array, munges the stack a bit, + * and invokes an exception handler (remcom_handler). + * + * stack on entry: stack on exit: + * old eflags vector number + * old cs (zero-filled to 32 bits) + * old eip + * + */ +extern void _catchException3(); +asm(".text"); +asm(".globl __catchException3"); +asm("__catchException3:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $3"); +CALL_HOOK(); + +/* Same thing for exception 1. */ +extern void _catchException1(); +asm(".text"); +asm(".globl __catchException1"); +asm("__catchException1:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $1"); +CALL_HOOK(); + +/* Same thing for exception 0. */ +extern void _catchException0(); +asm(".text"); +asm(".globl __catchException0"); +asm("__catchException0:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $0"); +CALL_HOOK(); + +/* Same thing for exception 4. */ +extern void _catchException4(); +asm(".text"); +asm(".globl __catchException4"); +asm("__catchException4:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $4"); +CALL_HOOK(); + +/* Same thing for exception 5. */ +extern void _catchException5(); +asm(".text"); +asm(".globl __catchException5"); +asm("__catchException5:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $5"); +CALL_HOOK(); + +/* Same thing for exception 6. */ +extern void _catchException6(); +asm(".text"); +asm(".globl __catchException6"); +asm("__catchException6:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $6"); +CALL_HOOK(); + +/* Same thing for exception 7. */ +extern void _catchException7(); +asm(".text"); +asm(".globl __catchException7"); +asm("__catchException7:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $7"); +CALL_HOOK(); + +/* Same thing for exception 8. */ +extern void _catchException8(); +asm(".text"); +asm(".globl __catchException8"); +asm("__catchException8:"); +SAVE_REGISTERS1(); +SAVE_ERRCODE(); +SAVE_REGISTERS2(); +asm ("pushl $8"); +CALL_HOOK(); + +/* Same thing for exception 9. */ +extern void _catchException9(); +asm(".text"); +asm(".globl __catchException9"); +asm("__catchException9:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $9"); +CALL_HOOK(); + +/* Same thing for exception 10. */ +extern void _catchException10(); +asm(".text"); +asm(".globl __catchException10"); +asm("__catchException10:"); +SAVE_REGISTERS1(); +SAVE_ERRCODE(); +SAVE_REGISTERS2(); +asm ("pushl $10"); +CALL_HOOK(); + +/* Same thing for exception 12. */ +extern void _catchException12(); +asm(".text"); +asm(".globl __catchException12"); +asm("__catchException12:"); +SAVE_REGISTERS1(); +SAVE_ERRCODE(); +SAVE_REGISTERS2(); +asm ("pushl $12"); +CALL_HOOK(); + +/* Same thing for exception 16. */ +extern void _catchException16(); +asm(".text"); +asm(".globl __catchException16"); +asm("__catchException16:"); +SAVE_REGISTERS1(); +SAVE_REGISTERS2(); +asm ("pushl $16"); +CALL_HOOK(); + +/* For 13, 11, and 14 we have to deal with the CHECK_FAULT stuff. */ + +/* Same thing for exception 13. */ +extern void _catchException13 (); +asm (".text"); +asm (".globl __catchException13"); +asm ("__catchException13:"); +CHECK_FAULT(); +SAVE_REGISTERS1(); +SAVE_ERRCODE(); +SAVE_REGISTERS2(); +asm ("pushl $13"); +CALL_HOOK(); + +/* Same thing for exception 11. */ +extern void _catchException11 (); +asm (".text"); +asm (".globl __catchException11"); +asm ("__catchException11:"); +CHECK_FAULT(); +SAVE_REGISTERS1(); +SAVE_ERRCODE(); +SAVE_REGISTERS2(); +asm ("pushl $11"); +CALL_HOOK(); + +/* Same thing for exception 14. */ +extern void _catchException14 (); +asm (".text"); +asm (".globl __catchException14"); +asm ("__catchException14:"); +CHECK_FAULT(); +SAVE_REGISTERS1(); +SAVE_ERRCODE(); +SAVE_REGISTERS2(); +asm ("pushl $14"); +CALL_HOOK(); + +/* + * remcomHandler is a front end for handle_exception. It moves the + * stack pointer into an area reserved for debugger use. + */ +asm("_remcomHandler:"); +asm(" popl %eax"); /* pop off return address */ +asm(" popl %eax"); /* get the exception number */ +asm(" movl _stackPtr, %esp"); /* move to remcom stack area */ +asm(" pushl %eax"); /* push exception onto stack */ +asm(" call _handle_exception"); /* this never returns */ + +void +_returnFromException () +{ + return_to_prog (); +} + +int +hex (ch) + char ch; +{ + if ((ch >= 'a') && (ch <= 'f')) + return (ch - 'a' + 10); + if ((ch >= '0') && (ch <= '9')) + return (ch - '0'); + if ((ch >= 'A') && (ch <= 'F')) + return (ch - 'A' + 10); + return (-1); +} + +static char remcomInBuffer[BUFMAX]; +static char remcomOutBuffer[BUFMAX]; + +/* scan for the sequence $# */ + +unsigned char * +getpacket (void) +{ + unsigned char *buffer = &remcomInBuffer[0]; + unsigned char checksum; + unsigned char xmitcsum; + int count; + char ch; + + while (1) + { + /* wait around for the start character, ignore all other characters */ + while ((ch = getDebugChar ()) != '$') + ; + + retry: + checksum = 0; + xmitcsum = -1; + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX) + { + ch = getDebugChar (); + if (ch == '$') + goto retry; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') + { + ch = getDebugChar (); + xmitcsum = hex (ch) << 4; + ch = getDebugChar (); + xmitcsum += hex (ch); + + if (checksum != xmitcsum) + { + if (remote_debug) + { + fprintf (stderr, + "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", + checksum, xmitcsum, buffer); + } + putDebugChar ('-'); /* failed checksum */ + } + else + { + putDebugChar ('+'); /* successful transfer */ + + /* if a sequence char is present, reply the sequence ID */ + if (buffer[2] == ':') + { + putDebugChar (buffer[0]); + putDebugChar (buffer[1]); + + return &buffer[3]; + } + + return &buffer[0]; + } + } + } +} + +/* send the packet in buffer. */ + +void +putpacket (unsigned char *buffer) +{ + unsigned char checksum; + int count; + char ch; + + /* $#. */ + do + { + putDebugChar ('$'); + checksum = 0; + count = 0; + + while (ch = buffer[count]) + { + putDebugChar (ch); + checksum += ch; + count += 1; + } + + putDebugChar ('#'); + putDebugChar (hexchars[checksum >> 4]); + putDebugChar (hexchars[checksum % 16]); + + } + while (getDebugChar () != '+'); +} + +void +debug_error (format, parm) + char *format; + char *parm; +{ + if (remote_debug) + fprintf (stderr, format, parm); +} + +/* Address of a routine to RTE to if we get a memory fault. */ +static void (*volatile mem_fault_routine) () = NULL; + +/* Indicate to caller of mem2hex or hex2mem that there has been an + error. */ +static volatile int mem_err = 0; + +void +set_mem_err (void) +{ + mem_err = 1; +} + +/* These are separate functions so that they are so short and sweet + that the compiler won't save any registers (if there is a fault + to mem_fault, they won't get restored, so there better not be any + saved). */ +int +get_char (char *addr) +{ + return *addr; +} + +void +set_char (char *addr, int val) +{ + *addr = val; +} + +/* convert the memory pointed to by mem into hex, placing result in buf */ +/* return a pointer to the last char put in buf (null) */ +/* If MAY_FAULT is non-zero, then we should set mem_err in response to + a fault; if zero treat a fault like any other fault in the stub. */ +char * +mem2hex (mem, buf, count, may_fault) + char *mem; + char *buf; + int count; + int may_fault; +{ + int i; + unsigned char ch; + + if (may_fault) + mem_fault_routine = set_mem_err; + for (i = 0; i < count; i++) + { + ch = get_char (mem++); + if (may_fault && mem_err) + return (buf); + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch % 16]; + } + *buf = 0; + if (may_fault) + mem_fault_routine = NULL; + return (buf); +} + +/* convert the hex array pointed to by buf into binary to be placed in mem */ +/* return a pointer to the character AFTER the last byte written */ +char * +hex2mem (buf, mem, count, may_fault) + char *buf; + char *mem; + int count; + int may_fault; +{ + int i; + unsigned char ch; + + if (may_fault) + mem_fault_routine = set_mem_err; + for (i = 0; i < count; i++) + { + ch = hex (*buf++) << 4; + ch = ch + hex (*buf++); + set_char (mem++, ch); + if (may_fault && mem_err) + return (mem); + } + if (may_fault) + mem_fault_routine = NULL; + return (mem); +} + +/* this function takes the 386 exception vector and attempts to + translate this number into a unix compatible signal value */ +int +computeSignal (int exceptionVector) +{ + int sigval; + switch (exceptionVector) + { + case 0: + sigval = 8; + break; /* divide by zero */ + case 1: + sigval = 5; + break; /* debug exception */ + case 3: + sigval = 5; + break; /* breakpoint */ + case 4: + sigval = 16; + break; /* into instruction (overflow) */ + case 5: + sigval = 16; + break; /* bound instruction */ + case 6: + sigval = 4; + break; /* Invalid opcode */ + case 7: + sigval = 8; + break; /* coprocessor not available */ + case 8: + sigval = 7; + break; /* double fault */ + case 9: + sigval = 11; + break; /* coprocessor segment overrun */ + case 10: + sigval = 11; + break; /* Invalid TSS */ + case 11: + sigval = 11; + break; /* Segment not present */ + case 12: + sigval = 11; + break; /* stack exception */ + case 13: + sigval = 11; + break; /* general protection */ + case 14: + sigval = 11; + break; /* page fault */ + case 16: + sigval = 7; + break; /* coprocessor error */ + default: + sigval = 7; /* "software generated" */ + } + return (sigval); +} + +/**********************************************/ +/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ +/* RETURN NUMBER OF CHARS PROCESSED */ +/**********************************************/ +int +hexToInt (char **ptr, int *intValue) +{ + int numChars = 0; + int hexValue; + + *intValue = 0; + + while (**ptr) + { + hexValue = hex (**ptr); + if (hexValue >= 0) + { + *intValue = (*intValue << 4) | hexValue; + numChars++; + } + else + break; + + (*ptr)++; + } + + return (numChars); +} + +/* + * This function does all command procesing for interfacing to gdb. + */ +void +handle_exception (int exceptionVector) +{ + int sigval, stepping; + int addr, length; + char *ptr; + int newPC; + + gdb_i386vector = exceptionVector; + + if (remote_debug) + { + printf ("vector=%d, sr=0x%x, pc=0x%x\n", + exceptionVector, registers[PS], registers[PC]); + } + + /* reply to host that an exception has occurred */ + sigval = computeSignal (exceptionVector); + + ptr = remcomOutBuffer; + + *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; + + *ptr++ = hexchars[ESP]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[ESP], ptr, 4, 0); /* SP */ + *ptr++ = ';'; + + *ptr++ = hexchars[EBP]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[EBP], ptr, 4, 0); /* FP */ + *ptr++ = ';'; + + *ptr++ = hexchars[PC]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); /* PC */ + *ptr++ = ';'; + + *ptr = '\0' + + putpacket (remcomOutBuffer); + + stepping = 0; + + while (1 == 1) + { + remcomOutBuffer[0] = 0; + ptr = getpacket (); + + switch (*ptr++) + { + case '?': + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + break; + case 'd': + remote_debug = !(remote_debug); /* toggle debug flag */ + break; + case 'g': /* return the value of the CPU registers */ + mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0); + break; + case 'G': /* set the value of the CPU registers - return OK */ + hex2mem (ptr, (char *) registers, NUMREGBYTES, 0); + strcpy (remcomOutBuffer, "OK"); + break; + case 'P': /* set the value of a single CPU register - return OK */ + { + int regno; + + if (hexToInt (&ptr, ®no) && *ptr++ == '=') + if (regno >= 0 && regno < NUMREGS) + { + hex2mem (ptr, (char *) ®isters[regno], 4, 0); + strcpy (remcomOutBuffer, "OK"); + break; + } + + strcpy (remcomOutBuffer, "E01"); + break; + } + + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + case 'm': + /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ + if (hexToInt (&ptr, &addr)) + if (*(ptr++) == ',') + if (hexToInt (&ptr, &length)) + { + ptr = 0; + mem_err = 0; + mem2hex ((char *) addr, remcomOutBuffer, length, 1); + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); + } + } + + if (ptr) + { + strcpy (remcomOutBuffer, "E01"); + } + break; + + /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + case 'M': + /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ + if (hexToInt (&ptr, &addr)) + if (*(ptr++) == ',') + if (hexToInt (&ptr, &length)) + if (*(ptr++) == ':') + { + mem_err = 0; + hex2mem (ptr, (char *) addr, length, 1); + + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); + } + else + { + strcpy (remcomOutBuffer, "OK"); + } + + ptr = 0; + } + if (ptr) + { + strcpy (remcomOutBuffer, "E02"); + } + break; + + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + case 's': + stepping = 1; + case 'c': + /* try to read optional parameter, pc unchanged if no parm */ + if (hexToInt (&ptr, &addr)) + registers[PC] = addr; + + newPC = registers[PC]; + + /* clear the trace bit */ + registers[PS] &= 0xfffffeff; + + /* set the trace bit if we're stepping */ + if (stepping) + registers[PS] |= 0x100; + + _returnFromException (); /* this is a jump */ + break; + + /* kill the program */ + case 'k': /* do nothing */ +#if 0 + /* Huh? This doesn't look like "nothing". + m68k-stub.c and sparc-stub.c don't have it. */ + BREAKPOINT (); +#endif + break; + } /* switch */ + + /* reply to the request */ + putpacket (remcomOutBuffer); + } +} + +/* this function is used to set up exception handlers for tracing and + breakpoints */ +void +set_debug_traps (void) +{ + stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1]; + + exceptionHandler (0, _catchException0); + exceptionHandler (1, _catchException1); + exceptionHandler (3, _catchException3); + exceptionHandler (4, _catchException4); + exceptionHandler (5, _catchException5); + exceptionHandler (6, _catchException6); + exceptionHandler (7, _catchException7); + exceptionHandler (8, _catchException8); + exceptionHandler (9, _catchException9); + exceptionHandler (10, _catchException10); + exceptionHandler (11, _catchException11); + exceptionHandler (12, _catchException12); + exceptionHandler (13, _catchException13); + exceptionHandler (14, _catchException14); + exceptionHandler (16, _catchException16); + + initialized = 1; +} + +/* This function will generate a breakpoint exception. It is used at the + beginning of a program to sync up with a debugger and can be used + otherwise as a quick means to stop program execution and "break" into + the debugger. */ + +void +breakpoint (void) +{ + if (initialized) + BREAKPOINT (); +} diff --git a/contrib/gdb/gdb/i386-tdep.c b/contrib/gdb/gdb/i386-tdep.c index b2ddd280675..e1ce81fcf0c 100644 --- a/contrib/gdb/gdb/i386-tdep.c +++ b/contrib/gdb/gdb/i386-tdep.c @@ -1,7 +1,8 @@ /* Intel 386 target-dependent stuff. - Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -21,30 +22,38 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "gdb_string.h" -#include "frame.h" -#include "inferior.h" -#include "gdbcore.h" -#include "target.h" -#include "floatformat.h" -#include "symtab.h" -#include "gdbcmd.h" -#include "command.h" #include "arch-utils.h" -#include "regcache.h" +#include "command.h" +#include "dummy-frame.h" +#include "dwarf2-frame.h" #include "doublest.h" +#include "floatformat.h" +#include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" +#include "inferior.h" +#include "gdbcmd.h" +#include "gdbcore.h" +#include "objfiles.h" +#include "osabi.h" +#include "regcache.h" +#include "reggroups.h" +#include "regset.h" +#include "symfile.h" +#include "symtab.h" +#include "target.h" #include "value.h" -#include "gdb_assert.h" +#include "dis-asm.h" -#include "elf-bfd.h" +#include "gdb_assert.h" +#include "gdb_string.h" #include "i386-tdep.h" - -#undef XMALLOC -#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) +#include "i387-tdep.h" /* Names of the registers. The first 10 registers match the register numbering scheme used by GCC for stabs and DWARF. */ + static char *i386_register_names[] = { "eax", "ecx", "edx", "ebx", @@ -60,116 +69,152 @@ static char *i386_register_names[] = "mxcsr" }; -/* i386_register_offset[i] is the offset into the register file of the - start of register number i. We initialize this from - i386_register_size. */ -static int i386_register_offset[MAX_NUM_REGS]; +static const int i386_num_register_names = ARRAY_SIZE (i386_register_names); -/* i386_register_size[i] is the number of bytes of storage in GDB's - register array occupied by register i. */ -static int i386_register_size[MAX_NUM_REGS] = { - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 10, 10, 10, 10, - 10, 10, 10, 10, - 4, 4, 4, 4, - 4, 4, 4, 4, - 16, 16, 16, 16, - 16, 16, 16, 16, - 4 +/* MMX registers. */ + +static char *i386_mmx_names[] = +{ + "mm0", "mm1", "mm2", "mm3", + "mm4", "mm5", "mm6", "mm7" }; +static const int i386_num_mmx_regs = ARRAY_SIZE (i386_mmx_names); + +static int +i386_mmx_regnum_p (struct gdbarch *gdbarch, int regnum) +{ + int mm0_regnum = gdbarch_tdep (gdbarch)->mm0_regnum; + + if (mm0_regnum < 0) + return 0; + + return (regnum >= mm0_regnum && regnum < mm0_regnum + i386_num_mmx_regs); +} + +/* SSE register? */ + +static int +i386_sse_regnum_p (struct gdbarch *gdbarch, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +#define I387_ST0_REGNUM tdep->st0_regnum +#define I387_NUM_XMM_REGS tdep->num_xmm_regs + + if (I387_NUM_XMM_REGS == 0) + return 0; + + return (I387_XMM0_REGNUM <= regnum && regnum < I387_MXCSR_REGNUM); + +#undef I387_ST0_REGNUM +#undef I387_NUM_XMM_REGS +} + +static int +i386_mxcsr_regnum_p (struct gdbarch *gdbarch, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +#define I387_ST0_REGNUM tdep->st0_regnum +#define I387_NUM_XMM_REGS tdep->num_xmm_regs + + if (I387_NUM_XMM_REGS == 0) + return 0; + + return (regnum == I387_MXCSR_REGNUM); + +#undef I387_ST0_REGNUM +#undef I387_NUM_XMM_REGS +} + +#define I387_ST0_REGNUM (gdbarch_tdep (current_gdbarch)->st0_regnum) +#define I387_MM0_REGNUM (gdbarch_tdep (current_gdbarch)->mm0_regnum) +#define I387_NUM_XMM_REGS (gdbarch_tdep (current_gdbarch)->num_xmm_regs) + +/* FP register? */ + +int +i386_fp_regnum_p (int regnum) +{ + if (I387_ST0_REGNUM < 0) + return 0; + + return (I387_ST0_REGNUM <= regnum && regnum < I387_FCTRL_REGNUM); +} + +int +i386_fpc_regnum_p (int regnum) +{ + if (I387_ST0_REGNUM < 0) + return 0; + + return (I387_FCTRL_REGNUM <= regnum && regnum < I387_XMM0_REGNUM); +} + /* Return the name of register REG. */ -char * +const char * i386_register_name (int reg) { - if (reg < 0) - return NULL; - if (reg >= sizeof (i386_register_names) / sizeof (*i386_register_names)) - return NULL; + if (i386_mmx_regnum_p (current_gdbarch, reg)) + return i386_mmx_names[reg - I387_MM0_REGNUM]; - return i386_register_names[reg]; -} + if (reg >= 0 && reg < i386_num_register_names) + return i386_register_names[reg]; -/* Return the offset into the register array of the start of register - number REG. */ -int -i386_register_byte (int reg) -{ - return i386_register_offset[reg]; -} - -/* Return the number of bytes of storage in GDB's register array - occupied by register REG. */ - -int -i386_register_raw_size (int reg) -{ - return i386_register_size[reg]; -} - -/* Return the size in bytes of the virtual type of register REG. */ - -int -i386_register_virtual_size (int reg) -{ - return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (reg)); + return NULL; } /* Convert stabs register number REG to the appropriate register number used by GDB. */ -int +static int i386_stab_reg_to_regnum (int reg) { /* This implements what GCC calls the "default" register map. */ if (reg >= 0 && reg <= 7) { - /* General registers. */ + /* General-purpose registers. */ return reg; } else if (reg >= 12 && reg <= 19) { /* Floating-point registers. */ - return reg - 12 + FP0_REGNUM; + return reg - 12 + I387_ST0_REGNUM; } else if (reg >= 21 && reg <= 28) { /* SSE registers. */ - return reg - 21 + XMM0_REGNUM; + return reg - 21 + I387_XMM0_REGNUM; } else if (reg >= 29 && reg <= 36) { /* MMX registers. */ - /* FIXME: kettenis/2001-07-28: Should we have the MMX registers - as pseudo-registers? */ - return reg - 29 + FP0_REGNUM; + return reg - 29 + I387_MM0_REGNUM; } /* This will hopefully provoke a warning. */ return NUM_REGS + NUM_PSEUDO_REGS; } -/* Convert Dwarf register number REG to the appropriate register +/* Convert DWARF register number REG to the appropriate register number used by GDB. */ -int +static int i386_dwarf_reg_to_regnum (int reg) { /* The DWARF register numbering includes %eip and %eflags, and numbers the floating point registers differently. */ if (reg >= 0 && reg <= 9) { - /* General registers. */ + /* General-purpose registers. */ return reg; } else if (reg >= 11 && reg <= 18) { /* Floating-point registers. */ - return reg - 11 + FP0_REGNUM; + return reg - 11 + I387_ST0_REGNUM; } else if (reg >= 21) { @@ -180,6 +225,10 @@ i386_dwarf_reg_to_regnum (int reg) /* This will hopefully provoke a warning. */ return NUM_REGS + NUM_PSEUDO_REGS; } + +#undef I387_ST0_REGNUM +#undef I387_MM0_REGNUM +#undef I387_NUM_XMM_REGS /* This is the variable that is set with "set disassembly-flavor", and @@ -193,415 +242,402 @@ static const char *valid_flavors[] = NULL }; static const char *disassembly_flavor = att_flavor; - -/* Stdio style buffering was used to minimize calls to ptrace, but - this buffering did not take into account that the code section - being accessed may not be an even number of buffers long (even if - the buffer is only sizeof(int) long). In cases where the code - section size happened to be a non-integral number of buffers long, - attempting to read the last buffer would fail. Simply using - target_read_memory and ignoring errors, rather than read_memory, is - not the correct solution, since legitimate access errors would then - be totally ignored. To properly handle this situation and continue - to use buffering would require that this code be able to determine - the minimum code section size granularity (not the alignment of the - section itself, since the actual failing case that pointed out this - problem had a section alignment of 4 but was not a multiple of 4 - bytes long), on a target by target basis, and then adjust it's - buffer size accordingly. This is messy, but potentially feasible. - It probably needs the bfd library's help and support. For now, the - buffer size is set to 1. (FIXME -fnf) */ - -#define CODESTREAM_BUFSIZ 1 /* Was sizeof(int), see note above. */ -static CORE_ADDR codestream_next_addr; -static CORE_ADDR codestream_addr; -static unsigned char codestream_buf[CODESTREAM_BUFSIZ]; -static int codestream_off; -static int codestream_cnt; - -#define codestream_tell() (codestream_addr + codestream_off) -#define codestream_peek() \ - (codestream_cnt == 0 ? \ - codestream_fill(1) : codestream_buf[codestream_off]) -#define codestream_get() \ - (codestream_cnt-- == 0 ? \ - codestream_fill(0) : codestream_buf[codestream_off++]) - -static unsigned char -codestream_fill (int peek_flag) -{ - codestream_addr = codestream_next_addr; - codestream_next_addr += CODESTREAM_BUFSIZ; - codestream_off = 0; - codestream_cnt = CODESTREAM_BUFSIZ; - read_memory (codestream_addr, (char *) codestream_buf, CODESTREAM_BUFSIZ); - - if (peek_flag) - return (codestream_peek ()); - else - return (codestream_get ()); -} - -static void -codestream_seek (CORE_ADDR place) -{ - codestream_next_addr = place / CODESTREAM_BUFSIZ; - codestream_next_addr *= CODESTREAM_BUFSIZ; - codestream_cnt = 0; - codestream_fill (1); - while (codestream_tell () != place) - codestream_get (); -} - -static void -codestream_read (unsigned char *buf, int count) -{ - unsigned char *p; - int i; - p = buf; - for (i = 0; i < count; i++) - *p++ = codestream_get (); -} -/* If the next instruction is a jump, move to its target. */ +/* Use the program counter to determine the contents and size of a + breakpoint instruction. Return a pointer to a string of bytes that + encode a breakpoint instruction, store the length of the string in + *LEN and optionally adjust *PC to point to the correct memory + location for inserting the breakpoint. -static void -i386_follow_jump (void) + On the i386 we have a single breakpoint that fits in a single byte + and can be inserted anywhere. + + This function is 64-bit safe. */ + +static const unsigned char * +i386_breakpoint_from_pc (CORE_ADDR *pc, int *len) { - unsigned char buf[4]; - long delta; + static unsigned char break_insn[] = { 0xcc }; /* int 3 */ + + *len = sizeof (break_insn); + return break_insn; +} + +#ifdef I386_REGNO_TO_SYMMETRY +#error "The Sequent Symmetry is no longer supported." +#endif - int data16; - CORE_ADDR pos; +/* According to the System V ABI, the registers %ebp, %ebx, %edi, %esi + and %esp "belong" to the calling function. Therefore these + registers should be saved if they're going to be modified. */ - pos = codestream_tell (); +/* The maximum number of saved registers. This should include all + registers mentioned above, and %eip. */ +#define I386_NUM_SAVED_REGS I386_NUM_GREGS - data16 = 0; - if (codestream_peek () == 0x66) +struct i386_frame_cache +{ + /* Base address. */ + CORE_ADDR base; + CORE_ADDR sp_offset; + CORE_ADDR pc; + + /* Saved registers. */ + CORE_ADDR saved_regs[I386_NUM_SAVED_REGS]; + CORE_ADDR saved_sp; + int pc_in_eax; + + /* Stack space reserved for local variables. */ + long locals; +}; + +/* Allocate and initialize a frame cache. */ + +static struct i386_frame_cache * +i386_alloc_frame_cache (void) +{ + struct i386_frame_cache *cache; + int i; + + cache = FRAME_OBSTACK_ZALLOC (struct i386_frame_cache); + + /* Base address. */ + cache->base = 0; + cache->sp_offset = -4; + cache->pc = 0; + + /* Saved registers. We initialize these to -1 since zero is a valid + offset (that's where %ebp is supposed to be stored). */ + for (i = 0; i < I386_NUM_SAVED_REGS; i++) + cache->saved_regs[i] = -1; + cache->saved_sp = 0; + cache->pc_in_eax = 0; + + /* Frameless until proven otherwise. */ + cache->locals = -1; + + return cache; +} + +/* If the instruction at PC is a jump, return the address of its + target. Otherwise, return PC. */ + +static CORE_ADDR +i386_follow_jump (CORE_ADDR pc) +{ + unsigned char op; + long delta = 0; + int data16 = 0; + + op = read_memory_unsigned_integer (pc, 1); + if (op == 0x66) { - codestream_get (); data16 = 1; + op = read_memory_unsigned_integer (pc + 1, 1); } - switch (codestream_get ()) + switch (op) { case 0xe9: /* Relative jump: if data16 == 0, disp32, else disp16. */ if (data16) { - codestream_read (buf, 2); - delta = extract_signed_integer (buf, 2); + delta = read_memory_integer (pc + 2, 2); /* Include the size of the jmp instruction (including the 0x66 prefix). */ - pos += delta + 4; + delta += 4; } else { - codestream_read (buf, 4); - delta = extract_signed_integer (buf, 4); + delta = read_memory_integer (pc + 1, 4); - pos += delta + 5; + /* Include the size of the jmp instruction. */ + delta += 5; } break; case 0xeb: /* Relative jump, disp8 (ignore data16). */ - codestream_read (buf, 1); - /* Sign-extend it. */ - delta = extract_signed_integer (buf, 1); + delta = read_memory_integer (pc + data16 + 1, 1); - pos += delta + 2; + delta += data16 + 2; break; } - codestream_seek (pos); + + return pc + delta; } -/* Find & return the amount a local space allocated, and advance the - codestream to the first register push (if any). +/* Check whether PC points at a prologue for a function returning a + structure or union. If so, it updates CACHE and returns the + address of the first instruction after the code sequence that + removes the "hidden" argument from the stack or CURRENT_PC, + whichever is smaller. Otherwise, return PC. */ - If the entry sequence doesn't make sense, return -1, and leave - codestream pointer at a random spot. */ - -static long -i386_get_frame_setup (CORE_ADDR pc) +static CORE_ADDR +i386_analyze_struct_return (CORE_ADDR pc, CORE_ADDR current_pc, + struct i386_frame_cache *cache) { + /* Functions that return a structure or union start with: + + popl %eax 0x58 + xchgl %eax, (%esp) 0x87 0x04 0x24 + or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00 + + (the System V compiler puts out the second `xchg' instruction, + and the assembler doesn't try to optimize it, so the 'sib' form + gets generated). This sequence is used to get the address of the + return buffer for a function that returns a structure. */ + static unsigned char proto1[3] = { 0x87, 0x04, 0x24 }; + static unsigned char proto2[4] = { 0x87, 0x44, 0x24, 0x00 }; + unsigned char buf[4]; unsigned char op; - codestream_seek (pc); + if (current_pc <= pc) + return pc; - i386_follow_jump (); + op = read_memory_unsigned_integer (pc, 1); - op = codestream_get (); + if (op != 0x58) /* popl %eax */ + return pc; - if (op == 0x58) /* popl %eax */ + read_memory (pc + 1, buf, 4); + if (memcmp (buf, proto1, 3) != 0 && memcmp (buf, proto2, 4) != 0) + return pc; + + if (current_pc == pc) { - /* This function must start with - - popl %eax 0x58 - xchgl %eax, (%esp) 0x87 0x04 0x24 - or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00 - - (the System V compiler puts out the second `xchg' - instruction, and the assembler doesn't try to optimize it, so - the 'sib' form gets generated). This sequence is used to get - the address of the return buffer for a function that returns - a structure. */ - int pos; - unsigned char buf[4]; - static unsigned char proto1[3] = { 0x87, 0x04, 0x24 }; - static unsigned char proto2[4] = { 0x87, 0x44, 0x24, 0x00 }; - - pos = codestream_tell (); - codestream_read (buf, 4); - if (memcmp (buf, proto1, 3) == 0) - pos += 3; - else if (memcmp (buf, proto2, 4) == 0) - pos += 4; - - codestream_seek (pos); - op = codestream_get (); /* Update next opcode. */ + cache->sp_offset += 4; + return current_pc; } + if (current_pc == pc + 1) + { + cache->pc_in_eax = 1; + return current_pc; + } + + if (buf[1] == proto1[1]) + return pc + 4; + else + return pc + 5; +} + +static CORE_ADDR +i386_skip_probe (CORE_ADDR pc) +{ + /* A function may start with + + pushl constant + call _probe + addl $4, %esp + + followed by + + pushl %ebp + + etc. */ + unsigned char buf[8]; + unsigned char op; + + op = read_memory_unsigned_integer (pc, 1); + if (op == 0x68 || op == 0x6a) { - /* This function may start with + int delta; - pushl constant - call _probe - addl $4, %esp - - followed by - - pushl %ebp - - etc. */ - int pos; - unsigned char buf[8]; - - /* Skip past the `pushl' instruction; it has either a one-byte - or a four-byte operand, depending on the opcode. */ - pos = codestream_tell (); + /* Skip past the `pushl' instruction; it has either a one-byte or a + four-byte operand, depending on the opcode. */ if (op == 0x68) - pos += 4; + delta = 5; else - pos += 1; - codestream_seek (pos); + delta = 2; - /* Read the following 8 bytes, which should be "call _probe" (6 - bytes) followed by "addl $4,%esp" (2 bytes). */ - codestream_read (buf, sizeof (buf)); + /* Read the following 8 bytes, which should be `call _probe' (6 + bytes) followed by `addl $4,%esp' (2 bytes). */ + read_memory (pc + delta, buf, sizeof (buf)); if (buf[0] == 0xe8 && buf[6] == 0xc4 && buf[7] == 0x4) - pos += sizeof (buf); - codestream_seek (pos); - op = codestream_get (); /* Update next opcode. */ + pc += delta + sizeof (buf); } + return pc; +} + +/* Check whether PC points at a code that sets up a new stack frame. + If so, it updates CACHE and returns the address of the first + instruction after the sequence that sets removes the "hidden" + argument from the stack or CURRENT_PC, whichever is smaller. + Otherwise, return PC. */ + +static CORE_ADDR +i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc, + struct i386_frame_cache *cache) +{ + unsigned char op; + int skip = 0; + + if (current_pc <= pc) + return current_pc; + + op = read_memory_unsigned_integer (pc, 1); + if (op == 0x55) /* pushl %ebp */ { - /* Check for "movl %esp, %ebp" -- can be written in two ways. */ - switch (codestream_get ()) + /* Take into account that we've executed the `pushl %ebp' that + starts this instruction sequence. */ + cache->saved_regs[I386_EBP_REGNUM] = 0; + cache->sp_offset += 4; + + /* If that's all, return now. */ + if (current_pc <= pc + 1) + return current_pc; + + op = read_memory_unsigned_integer (pc + 1, 1); + + /* Check for some special instructions that might be migrated + by GCC into the prologue. We check for + + xorl %ebx, %ebx + xorl %ecx, %ecx + xorl %edx, %edx + xorl %eax, %eax + + and the equivalent + + subl %ebx, %ebx + subl %ecx, %ecx + subl %edx, %edx + subl %eax, %eax + + Because of the symmetry, there are actually two ways to + encode these instructions; with opcode bytes 0x29 and 0x2b + for `subl' and opcode bytes 0x31 and 0x33 for `xorl'. + + Make sure we only skip these instructions if we later see the + `movl %esp, %ebp' that actually sets up the frame. */ + while (op == 0x29 || op == 0x2b || op == 0x31 || op == 0x33) + { + op = read_memory_unsigned_integer (pc + skip + 2, 1); + switch (op) + { + case 0xdb: /* %ebx */ + case 0xc9: /* %ecx */ + case 0xd2: /* %edx */ + case 0xc0: /* %eax */ + skip += 2; + break; + default: + return pc + 1; + } + + op = read_memory_unsigned_integer (pc + skip + 1, 1); + } + + /* Check for `movl %esp, %ebp' -- can be written in two ways. */ + switch (op) { case 0x8b: - if (codestream_get () != 0xec) - return -1; + if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xec) + return pc + 1; break; case 0x89: - if (codestream_get () != 0xe5) - return -1; + if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xe5) + return pc + 1; break; default: - return -1; + return pc + 1; } + + /* OK, we actually have a frame. We just don't know how large + it is yet. Set its size to zero. We'll adjust it if + necessary. We also now commit to skipping the special + instructions mentioned before. */ + cache->locals = 0; + pc += skip; + + /* If that's all, return now. */ + if (current_pc <= pc + 3) + return current_pc; + /* Check for stack adjustment - subl $XXX, %esp + subl $XXX, %esp NOTE: You can't subtract a 16 bit immediate from a 32 bit reg, so we don't have to worry about a data16 prefix. */ - op = codestream_peek (); + op = read_memory_unsigned_integer (pc + 3, 1); if (op == 0x83) { /* `subl' with 8 bit immediate. */ - codestream_get (); - if (codestream_get () != 0xec) + if (read_memory_unsigned_integer (pc + 4, 1) != 0xec) /* Some instruction starting with 0x83 other than `subl'. */ - { - codestream_seek (codestream_tell () - 2); - return 0; - } - /* `subl' with signed byte immediate (though it wouldn't - make sense to be negative). */ - return (codestream_get ()); + return pc + 3; + + /* `subl' with signed byte immediate (though it wouldn't make + sense to be negative). */ + cache->locals = read_memory_integer (pc + 5, 1); + return pc + 6; } else if (op == 0x81) { - char buf[4]; /* Maybe it is `subl' with a 32 bit immedediate. */ - codestream_get (); - if (codestream_get () != 0xec) + if (read_memory_unsigned_integer (pc + 4, 1) != 0xec) /* Some instruction starting with 0x81 other than `subl'. */ - { - codestream_seek (codestream_tell () - 2); - return 0; - } + return pc + 3; + /* It is `subl' with a 32 bit immediate. */ - codestream_read ((unsigned char *) buf, 4); - return extract_signed_integer (buf, 4); + cache->locals = read_memory_integer (pc + 5, 4); + return pc + 9; } else { - return 0; + /* Some instruction other than `subl'. */ + return pc + 3; } } - else if (op == 0xc8) + else if (op == 0xc8) /* enter $XXX */ { - char buf[2]; - /* `enter' with 16 bit unsigned immediate. */ - codestream_read ((unsigned char *) buf, 2); - codestream_get (); /* Flush final byte of enter instruction. */ - return extract_unsigned_integer (buf, 2); + cache->locals = read_memory_unsigned_integer (pc + 1, 2); + return pc + 4; } - return (-1); + + return pc; } -/* Return the chain-pointer for FRAME. In the case of the i386, the - frame's nominal address is the address of a 4-byte word containing - the calling frame's address. */ +/* Check whether PC points at code that saves registers on the stack. + If so, it updates CACHE and returns the address of the first + instruction after the register saves or CURRENT_PC, whichever is + smaller. Otherwise, return PC. */ -CORE_ADDR -i386_frame_chain (struct frame_info *frame) +static CORE_ADDR +i386_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc, + struct i386_frame_cache *cache) { - if (frame->signal_handler_caller) - return frame->frame; - - if (! inside_entry_file (frame->pc)) - return read_memory_unsigned_integer (frame->frame, 4); - - return 0; -} - -/* Determine whether the function invocation represented by FRAME does - not have a from on the stack associated with it. If it does not, - return non-zero, otherwise return zero. */ - -int -i386_frameless_function_invocation (struct frame_info *frame) -{ - if (frame->signal_handler_caller) - return 0; - - return frameless_look_for_prologue (frame); -} - -/* Return the saved program counter for FRAME. */ - -CORE_ADDR -i386_frame_saved_pc (struct frame_info *frame) -{ - /* FIXME: kettenis/2001-05-09: Conditionalizing the next bit of code - on SIGCONTEXT_PC_OFFSET and I386V4_SIGTRAMP_SAVED_PC should be - considered a temporary hack. I plan to come up with something - better when we go multi-arch. */ -#if defined (SIGCONTEXT_PC_OFFSET) || defined (I386V4_SIGTRAMP_SAVED_PC) - if (frame->signal_handler_caller) - return sigtramp_saved_pc (frame); -#endif - - return read_memory_unsigned_integer (frame->frame + 4, 4); -} - -CORE_ADDR -i386go32_frame_saved_pc (struct frame_info *frame) -{ - return read_memory_integer (frame->frame + 4, 4); -} - -/* Immediately after a function call, return the saved pc. */ - -CORE_ADDR -i386_saved_pc_after_call (struct frame_info *frame) -{ - return read_memory_unsigned_integer (read_register (SP_REGNUM), 4); -} - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -int -i386_frame_num_args (struct frame_info *fi) -{ -#if 1 - return -1; -#else - /* This loses because not only might the compiler not be popping the - args right after the function call, it might be popping args from - both this call and a previous one, and we would say there are - more args than there really are. */ - - int retpc; + CORE_ADDR offset = 0; unsigned char op; - struct frame_info *pfi; + int i; - /* On the i386, the instruction following the call could be: - popl %ecx - one arg - addl $imm, %esp - imm/4 args; imm may be 8 or 32 bits - anything else - zero args. */ - - int frameless; - - frameless = FRAMELESS_FUNCTION_INVOCATION (fi); - if (frameless) - /* In the absence of a frame pointer, GDB doesn't get correct - values for nameless arguments. Return -1, so it doesn't print - any nameless arguments. */ - return -1; - - pfi = get_prev_frame (fi); - if (pfi == 0) + if (cache->locals > 0) + offset -= cache->locals; + for (i = 0; i < 8 && pc < current_pc; i++) { - /* NOTE: This can happen if we are looking at the frame for - main, because FRAME_CHAIN_VALID won't let us go into start. - If we have debugging symbols, that's not really a big deal; - it just means it will only show as many arguments to main as - are declared. */ - return -1; + op = read_memory_unsigned_integer (pc, 1); + if (op < 0x50 || op > 0x57) + break; + + offset -= 4; + cache->saved_regs[op - 0x50] = offset; + cache->sp_offset += 4; + pc++; } - else - { - retpc = pfi->pc; - op = read_memory_integer (retpc, 1); - if (op == 0x59) /* pop %ecx */ - return 1; - else if (op == 0x83) - { - op = read_memory_integer (retpc + 1, 1); - if (op == 0xc4) - /* addl $, %esp */ - return (read_memory_integer (retpc + 2, 1) & 0xff) / 4; - else - return 0; - } - else if (op == 0x81) /* `add' with 32 bit immediate. */ - { - op = read_memory_integer (retpc + 1, 1); - if (op == 0xc4) - /* addl $, %esp */ - return read_memory_integer (retpc + 2, 4) / 4; - else - return 0; - } - else - { - return 0; - } - } -#endif + + return pc; } -/* Parse the first few instructions the function to see what registers - were stored. - +/* Do a full analysis of the prologue at PC and update CACHE + accordingly. Bail out early if CURRENT_PC is reached. Return the + address where the analysis stopped. + We handle these cases: The startup sequence can be at the start of the function, or the @@ -625,97 +661,43 @@ i386_frame_num_args (struct frame_info *fi) If the setup sequence is at the end of the function, then the next instruction will be a branch back to the start. */ -void -i386_frame_init_saved_regs (struct frame_info *fip) +static CORE_ADDR +i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, + struct i386_frame_cache *cache) { - long locals = -1; - unsigned char op; - CORE_ADDR dummy_bottom; - CORE_ADDR addr; - CORE_ADDR pc; - int i; - - if (fip->saved_regs) - return; - - frame_saved_regs_zalloc (fip); - - /* If the frame is the end of a dummy, compute where the beginning - would be. */ - dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH; - - /* Check if the PC points in the stack, in a dummy frame. */ - if (dummy_bottom <= fip->pc && fip->pc <= fip->frame) - { - /* All registers were saved by push_call_dummy. */ - addr = fip->frame; - for (i = 0; i < NUM_REGS; i++) - { - addr -= REGISTER_RAW_SIZE (i); - fip->saved_regs[i] = addr; - } - return; - } - - pc = get_pc_function_start (fip->pc); - if (pc != 0) - locals = i386_get_frame_setup (pc); - - if (locals >= 0) - { - addr = fip->frame - 4 - locals; - for (i = 0; i < 8; i++) - { - op = codestream_get (); - if (op < 0x50 || op > 0x57) - break; -#ifdef I386_REGNO_TO_SYMMETRY - /* Dynix uses different internal numbering. Ick. */ - fip->saved_regs[I386_REGNO_TO_SYMMETRY (op - 0x50)] = addr; -#else - fip->saved_regs[op - 0x50] = addr; -#endif - addr -= 4; - } - } - - fip->saved_regs[PC_REGNUM] = fip->frame + 4; - fip->saved_regs[FP_REGNUM] = fip->frame; + pc = i386_follow_jump (pc); + pc = i386_analyze_struct_return (pc, current_pc, cache); + pc = i386_skip_probe (pc); + pc = i386_analyze_frame_setup (pc, current_pc, cache); + return i386_analyze_register_saves (pc, current_pc, cache); } /* Return PC of first real instruction. */ -int -i386_skip_prologue (int pc) +static CORE_ADDR +i386_skip_prologue (CORE_ADDR start_pc) { + static unsigned char pic_pat[6] = + { + 0xe8, 0, 0, 0, 0, /* call 0x0 */ + 0x5b, /* popl %ebx */ + }; + struct i386_frame_cache cache; + CORE_ADDR 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); + cache.locals = -1; + pc = i386_analyze_prologue (start_pc, 0xffffffff, &cache); + if (cache.locals < 0) + return start_pc; - /* Found valid frame setup -- codestream now points to start of push - instructions for saving registers. */ - - /* Skip over register saves. */ - for (i = 0; i < 8; i++) - { - op = codestream_peek (); - /* Break if not `pushl' instrunction. */ - if (op < 0x50 || op > 0x57) - break; - codestream_get (); - } + /* Found valid frame setup. */ /* 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 - + %ebx: + call 0x0 popl %ebx movl %ebx,x(%ebp) (optional) @@ -725,212 +707,469 @@ i386_skip_prologue (int pc) 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 (); + op = read_memory_unsigned_integer (pc + i, 1); if (pic_pat[i] != op) break; } if (i == 6) { - unsigned char buf[4]; - long delta = 6; + int delta = 6; + + op = read_memory_unsigned_integer (pc + delta, 1); - op = codestream_get (); if (op == 0x89) /* movl %ebx, x(%ebp) */ { - op = codestream_get (); + op = read_memory_unsigned_integer (pc + delta + 1, 1); + if (op == 0x5d) /* One byte offset from %ebp. */ - { - delta += 3; - codestream_read (buf, 1); - } + delta += 3; else if (op == 0x9d) /* Four byte offset from %ebp. */ - { - delta += 6; - codestream_read (buf, 4); - } + delta += 6; else /* Unexpected instruction. */ - delta = -1; - op = codestream_get (); + delta = 0; + + op = read_memory_unsigned_integer (pc + delta, 1); } + /* addl y,%ebx */ - if (delta > 0 && op == 0x81 && codestream_get () == 0xc3) + if (delta > 0 && op == 0x81 + && read_memory_unsigned_integer (pc + delta + 1, 1) == 0xc3); { - pos += delta + 6; + pc += delta + 6; } } - codestream_seek (pos); - i386_follow_jump (); - - return (codestream_tell ()); + return i386_follow_jump (pc); } -void -i386_push_dummy_frame (void) +/* This function is 64-bit safe. */ + +static CORE_ADDR +i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - CORE_ADDR sp = read_register (SP_REGNUM); - CORE_ADDR fp; - int regnum; - char regbuf[MAX_REGISTER_RAW_SIZE]; + char buf[8]; - sp = push_word (sp, read_register (PC_REGNUM)); - sp = push_word (sp, read_register (FP_REGNUM)); - fp = sp; - for (regnum = 0; regnum < NUM_REGS; regnum++) - { - read_register_gen (regnum, regbuf); - sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum)); - } - write_register (SP_REGNUM, sp); - write_register (FP_REGNUM, fp); -} - -/* Insert the (relative) function address into the call sequence - stored at DYMMY. */ - -void -i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - int from, to, delta, loc; - - loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); - from = loc + 5; - to = (int)(fun); - delta = to - from; - - *((char *)(dummy) + 1) = (delta & 0xff); - *((char *)(dummy) + 2) = ((delta >> 8) & 0xff); - *((char *)(dummy) + 3) = ((delta >> 16) & 0xff); - *((char *)(dummy) + 4) = ((delta >> 24) & 0xff); -} - -void -i386_pop_frame (void) -{ - struct frame_info *frame = get_current_frame (); - CORE_ADDR fp; - int regnum; - char regbuf[MAX_REGISTER_RAW_SIZE]; - - fp = FRAME_FP (frame); - i386_frame_init_saved_regs (frame); - - for (regnum = 0; regnum < NUM_REGS; regnum++) - { - CORE_ADDR addr; - addr = frame->saved_regs[regnum]; - if (addr) - { - read_memory (addr, regbuf, REGISTER_RAW_SIZE (regnum)); - write_register_bytes (REGISTER_BYTE (regnum), regbuf, - REGISTER_RAW_SIZE (regnum)); - } - } - write_register (FP_REGNUM, read_memory_integer (fp, 4)); - write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); - write_register (SP_REGNUM, fp + 8); - flush_cached_frames (); + frame_unwind_register (next_frame, PC_REGNUM, buf); + return extract_typed_address (buf, builtin_type_void_func_ptr); } -#ifdef GET_LONGJMP_TARGET +/* Normal frames. */ -/* FIXME: Multi-arching does not set JB_PC and JB_ELEMENT_SIZE yet. - Fill in with dummy value to enable compilation. */ -#ifndef JB_PC -#define JB_PC 0 -#endif /* JB_PC */ +static struct i386_frame_cache * +i386_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct i386_frame_cache *cache; + char buf[4]; + int i; -#ifndef JB_ELEMENT_SIZE -#define JB_ELEMENT_SIZE 4 -#endif /* JB_ELEMENT_SIZE */ + if (*this_cache) + return *this_cache; + + cache = i386_alloc_frame_cache (); + *this_cache = cache; + + /* In principle, for normal frames, %ebp holds the frame pointer, + which holds the base address for the current stack frame. + However, for functions that don't need it, the frame pointer is + optional. For these "frameless" functions the frame pointer is + actually the frame pointer of the calling frame. Signal + trampolines are just a special case of a "frameless" function. + They (usually) share their frame pointer with the frame that was + in progress when the signal occurred. */ + + frame_unwind_register (next_frame, I386_EBP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 4); + if (cache->base == 0) + return cache; + + /* For normal frames, %eip is stored at 4(%ebp). */ + cache->saved_regs[I386_EIP_REGNUM] = 4; + + cache->pc = frame_func_unwind (next_frame); + if (cache->pc != 0) + i386_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache); + + if (cache->locals < 0) + { + /* We didn't find a valid frame, which means that CACHE->base + currently holds the frame pointer for our calling frame. If + we're at the start of a function, or somewhere half-way its + prologue, the function's frame probably hasn't been fully + setup yet. Try to reconstruct the base address for the stack + frame by looking at the stack pointer. For truly "frameless" + functions this might work too. */ + + frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset; + } + + /* Now that we have the base address for the stack frame we can + calculate the value of %esp in the calling frame. */ + cache->saved_sp = cache->base + 8; + + /* Adjust all the saved registers such that they contain addresses + instead of offsets. */ + for (i = 0; i < I386_NUM_SAVED_REGS; i++) + if (cache->saved_regs[i] != -1) + cache->saved_regs[i] += cache->base; + + return cache; +} + +static void +i386_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache); + + /* This marks the outermost frame. */ + if (cache->base == 0) + return; + + /* See the end of i386_push_dummy_call. */ + (*this_id) = frame_id_build (cache->base + 8, cache->pc); +} + +static void +i386_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache); + + gdb_assert (regnum >= 0); + + /* The System V ABI says that: + + "The flags register contains the system flags, such as the + direction flag and the carry flag. The direction flag must be + set to the forward (that is, zero) direction before entry and + upon exit from a function. Other user flags have no specified + role in the standard calling sequence and are not preserved." + + To guarantee the "upon exit" part of that statement we fake a + saved flags register that has its direction flag cleared. + + Note that GCC doesn't seem to rely on the fact that the direction + flag is cleared after a function return; it always explicitly + clears the flag before operations where it matters. + + FIXME: kettenis/20030316: I'm not quite sure whether this is the + right thing to do. The way we fake the flags register here makes + it impossible to change it. */ + + if (regnum == I386_EFLAGS_REGNUM) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + ULONGEST val; + + /* Clear the direction flag. */ + val = frame_unwind_register_unsigned (next_frame, + I386_EFLAGS_REGNUM); + val &= ~(1 << 10); + store_unsigned_integer (valuep, 4, val); + } + + return; + } + + if (regnum == I386_EIP_REGNUM && cache->pc_in_eax) + { + frame_register_unwind (next_frame, I386_EAX_REGNUM, + optimizedp, lvalp, addrp, realnump, valuep); + return; + } + + if (regnum == I386_ESP_REGNUM && cache->saved_sp) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + /* Store the value. */ + store_unsigned_integer (valuep, 4, cache->saved_sp); + } + return; + } + + if (regnum < I386_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = cache->saved_regs[regnum]; + *realnump = -1; + if (valuep) + { + /* Read the value in from memory. */ + read_memory (*addrp, valuep, + register_size (current_gdbarch, regnum)); + } + return; + } + + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind i386_frame_unwind = +{ + NORMAL_FRAME, + i386_frame_this_id, + i386_frame_prev_register +}; + +static const struct frame_unwind * +i386_frame_sniffer (struct frame_info *next_frame) +{ + return &i386_frame_unwind; +} + + +/* Signal trampolines. */ + +static struct i386_frame_cache * +i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct i386_frame_cache *cache; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + CORE_ADDR addr; + char buf[4]; + + if (*this_cache) + return *this_cache; + + cache = i386_alloc_frame_cache (); + + frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 4) - 4; + + addr = tdep->sigcontext_addr (next_frame); + if (tdep->sc_reg_offset) + { + int i; + + gdb_assert (tdep->sc_num_regs <= I386_NUM_SAVED_REGS); + + for (i = 0; i < tdep->sc_num_regs; i++) + if (tdep->sc_reg_offset[i] != -1) + cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; + } + else + { + cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset; + cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset; + } + + *this_cache = cache; + return cache; +} + +static void +i386_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct i386_frame_cache *cache = + i386_sigtramp_frame_cache (next_frame, this_cache); + + /* See the end of i386_push_dummy_call. */ + (*this_id) = frame_id_build (cache->base + 8, frame_pc_unwind (next_frame)); +} + +static void +i386_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + /* Make sure we've initialized the cache. */ + i386_sigtramp_frame_cache (next_frame, this_cache); + + i386_frame_prev_register (next_frame, this_cache, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind i386_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + i386_sigtramp_frame_this_id, + i386_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +i386_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + /* We shouldn't even bother to try if the OSABI didn't register + a sigcontext_addr handler. */ + if (!gdbarch_tdep (current_gdbarch)->sigcontext_addr) + return NULL; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (PC_IN_SIGTRAMP (pc, name)) + return &i386_sigtramp_frame_unwind; + + return NULL; +} + + +static CORE_ADDR +i386_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache); + + return cache->base; +} + +static const struct frame_base i386_frame_base = +{ + &i386_frame_unwind, + i386_frame_base_address, + i386_frame_base_address, + i386_frame_base_address +}; + +static struct frame_id +i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + char buf[4]; + CORE_ADDR fp; + + frame_unwind_register (next_frame, I386_EBP_REGNUM, buf); + fp = extract_unsigned_integer (buf, 4); + + /* See the end of i386_push_dummy_call. */ + return frame_id_build (fp + 8, frame_pc_unwind (next_frame)); +} + /* Figure out where the longjmp will land. Slurp the args out of the stack. We expect the first arg to be a pointer to the jmp_buf - structure from which we extract the pc (JB_PC) that we will land - at. The pc is copied into PC. This routine returns true on - success. */ + structure from which we extract the address that we will land at. + This address is copied into PC. This routine returns non-zero on + success. -int -get_longjmp_target (CORE_ADDR *pc) + This function is 64-bit safe. */ + +static int +i386_get_longjmp_target (CORE_ADDR *pc) { - char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; + char buf[8]; CORE_ADDR sp, jb_addr; + int jb_pc_offset = gdbarch_tdep (current_gdbarch)->jb_pc_offset; + int len = TYPE_LENGTH (builtin_type_void_func_ptr); - sp = read_register (SP_REGNUM); - - if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack. */ - buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) + /* If JB_PC_OFFSET is -1, we have no way to find out where the + longjmp will land. */ + if (jb_pc_offset == -1) return 0; - jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); - - if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) + /* Don't use I386_ESP_REGNUM here, since this function is also used + for AMD64. */ + regcache_cooked_read (current_regcache, SP_REGNUM, buf); + sp = extract_typed_address (buf, builtin_type_void_data_ptr); + if (target_read_memory (sp + len, buf, len)) return 0; - *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); + jb_addr = extract_typed_address (buf, builtin_type_void_data_ptr); + if (target_read_memory (jb_addr + jb_pc_offset, buf, len)) + return 0; + *pc = extract_typed_address (buf, builtin_type_void_func_ptr); return 1; } - -#endif /* GET_LONGJMP_TARGET */ -CORE_ADDR -i386_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) +static CORE_ADDR +i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr) { - sp = default_push_arguments (nargs, args, sp, struct_return, struct_addr); - + char buf[4]; + int i; + + /* Push arguments in reverse order. */ + for (i = nargs - 1; i >= 0; i--) + { + int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i])); + + /* The System V ABI says that: + + "An argument's size is increased, if necessary, to make it a + multiple of [32-bit] words. This may require tail padding, + depending on the size of the argument." + + This makes sure the stack says word-aligned. */ + sp -= (len + 3) & ~3; + write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len); + } + + /* Push value address. */ if (struct_return) { - char buf[4]; - sp -= 4; - store_address (buf, 4, struct_addr); + store_unsigned_integer (buf, 4, struct_addr); write_memory (sp, buf, 4); } - return sp; -} + /* Store return address. */ + sp -= 4; + store_unsigned_integer (buf, 4, bp_addr); + write_memory (sp, buf, 4); -void -i386_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - /* Do nothing. Everything was already done by i386_push_arguments. */ + /* Finally, update the stack pointer... */ + store_unsigned_integer (buf, 4, sp); + regcache_cooked_write (regcache, I386_ESP_REGNUM, buf); + + /* ...and fake a frame pointer. */ + regcache_cooked_write (regcache, I386_EBP_REGNUM, buf); + + /* MarkK wrote: This "+ 8" is all over the place: + (i386_frame_this_id, i386_sigtramp_frame_this_id, + i386_unwind_dummy_id). It's there, since all frame unwinders for + a given target have to agree (within a certain margin) on the + defenition of the stack address of a frame. Otherwise + frame_id_inner() won't work correctly. Since DWARF2/GCC uses the + stack address *before* the function call as a frame's CFA. On + the i386, when %ebp is used as a frame pointer, the offset + between the contents %ebp and the CFA as defined by GCC. */ + return sp + 8; } /* These registers are used for returning integers (and on some targets also for returning `struct' and `union' values when their size and alignment match an integer type). */ -#define LOW_RETURN_REGNUM 0 /* %eax */ -#define HIGH_RETURN_REGNUM 2 /* %edx */ +#define LOW_RETURN_REGNUM I386_EAX_REGNUM /* %eax */ +#define HIGH_RETURN_REGNUM I386_EDX_REGNUM /* %edx */ -/* Extract from an array REGBUF containing the (raw) register state, a - function return value of TYPE, and copy that, in virtual format, - into VALBUF. */ +/* Read, for architecture GDBARCH, a function return value of TYPE + from REGCACHE, and copy that into VALBUF. */ -void -i386_extract_return_value (struct type *type, char *regbuf, char *valbuf) +static void +i386_extract_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, void *valbuf) { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int len = TYPE_LENGTH (type); - - if (TYPE_CODE (type) == TYPE_CODE_STRUCT - && TYPE_NFIELDS (type) == 1) - { - i386_extract_return_value (TYPE_FIELD_TYPE (type, 0), regbuf, valbuf); - return; - } + char buf[I386_MAX_REGISTER_SIZE]; if (TYPE_CODE (type) == TYPE_CODE_FLT) { - if (NUM_FREGS == 0) + if (tdep->st0_regnum < 0) { warning ("Cannot find floating-point return value."); memset (valbuf, 0, len); @@ -941,22 +1180,25 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf) its contents to the desired type. This is probably not exactly how it would happen on the target itself, but it is the best we can do. */ - convert_typed_floating (®buf[REGISTER_BYTE (FP0_REGNUM)], - builtin_type_i387_ext, valbuf, type); + regcache_raw_read (regcache, I386_ST0_REGNUM, buf); + convert_typed_floating (buf, builtin_type_i387_ext, valbuf, type); } else { - int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM); - int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM); + int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM); + int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM); if (len <= low_size) - memcpy (valbuf, ®buf[REGISTER_BYTE (LOW_RETURN_REGNUM)], len); + { + regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf); + memcpy (valbuf, buf, len); + } else if (len <= (low_size + high_size)) { - memcpy (valbuf, - ®buf[REGISTER_BYTE (LOW_RETURN_REGNUM)], low_size); - memcpy (valbuf + low_size, - ®buf[REGISTER_BYTE (HIGH_RETURN_REGNUM)], len - low_size); + regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf); + memcpy (valbuf, buf, low_size); + regcache_raw_read (regcache, HIGH_RETURN_REGNUM, buf); + memcpy ((char *) valbuf + low_size, buf, len - low_size); } else internal_error (__FILE__, __LINE__, @@ -964,27 +1206,26 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf) } } -/* Write into the appropriate registers a function return value stored - in VALBUF of type TYPE, given in virtual format. */ +/* Write, for architecture GDBARCH, a function return value of TYPE + from VALBUF into REGCACHE. */ -void -i386_store_return_value (struct type *type, char *valbuf) +static void +i386_store_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, const void *valbuf) { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int len = TYPE_LENGTH (type); - if (TYPE_CODE (type) == TYPE_CODE_STRUCT - && TYPE_NFIELDS (type) == 1) - { - i386_store_return_value (TYPE_FIELD_TYPE (type, 0), valbuf); - return; - } + /* Define I387_ST0_REGNUM such that we use the proper definitions + for the architecture. */ +#define I387_ST0_REGNUM I386_ST0_REGNUM if (TYPE_CODE (type) == TYPE_CODE_FLT) { - unsigned int fstat; - char buf[FPU_REG_RAW_SIZE]; + ULONGEST fstat; + char buf[I386_MAX_REGISTER_SIZE]; - if (NUM_FREGS == 0) + if (tdep->st0_regnum < 0) { warning ("Cannot set floating-point return value."); return; @@ -999,51 +1240,113 @@ i386_store_return_value (struct type *type, char *valbuf) not exactly how it would happen on the target itself, but it is the best we can do. */ convert_typed_floating (valbuf, type, buf, builtin_type_i387_ext); - write_register_bytes (REGISTER_BYTE (FP0_REGNUM), buf, - FPU_REG_RAW_SIZE); + regcache_raw_write (regcache, I386_ST0_REGNUM, buf); /* Set the top of the floating-point register stack to 7. The actual value doesn't really matter, but 7 is what a normal function return would end up with if the program started out with a freshly initialized FPU. */ - fstat = read_register (FSTAT_REGNUM); + regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat); fstat |= (7 << 11); - write_register (FSTAT_REGNUM, fstat); + regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat); /* Mark %st(1) through %st(7) as empty. Since we set the top of the floating-point register stack to 7, the appropriate value for the tag word is 0x3fff. */ - write_register (FTAG_REGNUM, 0x3fff); + regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff); } else { - int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM); - int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM); + int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM); + int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM); if (len <= low_size) - write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM), valbuf, len); + regcache_raw_write_part (regcache, LOW_RETURN_REGNUM, 0, len, valbuf); else if (len <= (low_size + high_size)) { - write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM), - valbuf, low_size); - write_register_bytes (REGISTER_BYTE (HIGH_RETURN_REGNUM), - valbuf + low_size, len - low_size); + regcache_raw_write (regcache, LOW_RETURN_REGNUM, valbuf); + regcache_raw_write_part (regcache, HIGH_RETURN_REGNUM, 0, + len - low_size, (char *) valbuf + low_size); } else internal_error (__FILE__, __LINE__, "Cannot store return value of %d bytes long.", len); } + +#undef I387_ST0_REGNUM +} + + +/* This is the variable that is set with "set struct-convention", and + its legitimate values. */ +static const char default_struct_convention[] = "default"; +static const char pcc_struct_convention[] = "pcc"; +static const char reg_struct_convention[] = "reg"; +static const char *valid_conventions[] = +{ + default_struct_convention, + pcc_struct_convention, + reg_struct_convention, + NULL +}; +static const char *struct_convention = default_struct_convention; + +/* Return non-zero if TYPE, which is assumed to be a structure or + union type, should be returned in registers for architecture + GDBARCH. */ + +static int +i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + enum type_code code = TYPE_CODE (type); + int len = TYPE_LENGTH (type); + + gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION); + + if (struct_convention == pcc_struct_convention + || (struct_convention == default_struct_convention + && tdep->struct_return == pcc_struct_return)) + return 0; + + return (len == 1 || len == 2 || len == 4 || len == 8); } -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR. */ +/* Determine, for architecture GDBARCH, how a return value of TYPE + should be returned. If it is supposed to be returned in registers, + and READBUF is non-zero, read the appropriate value from REGCACHE, + and copy it into READBUF. If WRITEBUF is non-zero, write the value + from WRITEBUF into REGCACHE. */ -CORE_ADDR -i386_extract_struct_value_address (char *regbuf) +static enum return_value_convention +i386_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, void *readbuf, + const void *writebuf) { - return extract_address (®buf[REGISTER_BYTE (LOW_RETURN_REGNUM)], - REGISTER_RAW_SIZE (LOW_RETURN_REGNUM)); + enum type_code code = TYPE_CODE (type); + + if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) + && !i386_reg_struct_return_p (gdbarch, type)) + return RETURN_VALUE_STRUCT_CONVENTION; + + /* This special case is for structures consisting of a single + `float' or `double' member. These structures are returned in + %st(0). For these structures, we call ourselves recursively, + changing TYPE into the type of the first member of the structure. + Since that should work for all structures that have only one + member, we don't bother to check the member's type here. */ + if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) + { + type = check_typedef (TYPE_FIELD_TYPE (type, 0)); + return i386_return_value (gdbarch, type, regcache, readbuf, writebuf); + } + + if (readbuf) + i386_extract_return_value (gdbarch, type, regcache, readbuf); + if (writebuf) + i386_store_return_value (gdbarch, type, regcache, writebuf); + + return RETURN_VALUE_REGISTER_CONVENTION; } @@ -1051,106 +1354,291 @@ i386_extract_struct_value_address (char *regbuf) register REGNUM. Perhaps %esi and %edi should go here, but potentially they could be used for things other than address. */ -struct type * -i386_register_virtual_type (int regnum) +static struct type * +i386_register_type (struct gdbarch *gdbarch, int regnum) { - if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM) + if (regnum == I386_EIP_REGNUM + || regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM) return lookup_pointer_type (builtin_type_void); - if (IS_FP_REGNUM (regnum)) + if (i386_fp_regnum_p (regnum)) return builtin_type_i387_ext; - if (IS_SSE_REGNUM (regnum)) - return builtin_type_v4sf; + if (i386_sse_regnum_p (gdbarch, regnum)) + return builtin_type_vec128i; + + if (i386_mmx_regnum_p (gdbarch, regnum)) + return builtin_type_vec64i; return builtin_type_int; } -/* Return true iff register REGNUM's virtual format is different from - its raw format. Note that this definition assumes that the host - supports IEEE 32-bit floats, since it doesn't say that SSE - registers need conversion. Even if we can't find a counterexample, - this is still sloppy. */ +/* Map a cooked register onto a raw register or memory. For the i386, + the MMX registers need to be mapped onto floating point registers. */ -int -i386_register_convertible (int regnum) +static int +i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum) { - return IS_FP_REGNUM (regnum); + struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); + int mmxreg, fpreg; + ULONGEST fstat; + int tos; + + /* Define I387_ST0_REGNUM such that we use the proper definitions + for REGCACHE's architecture. */ +#define I387_ST0_REGNUM tdep->st0_regnum + + mmxreg = regnum - tdep->mm0_regnum; + regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat); + tos = (fstat >> 11) & 0x7; + fpreg = (mmxreg + tos) % 8; + + return (I387_ST0_REGNUM + fpreg); + +#undef I387_ST0_REGNUM } -/* Convert data from raw format for register REGNUM in buffer FROM to - virtual format with type TYPE in buffer TO. */ - -void -i386_register_convert_to_virtual (int regnum, struct type *type, - char *from, char *to) +static void +i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, void *buf) { - gdb_assert (IS_FP_REGNUM (regnum)); - - /* We only support floating-point values. */ - if (TYPE_CODE (type) != TYPE_CODE_FLT) + if (i386_mmx_regnum_p (gdbarch, regnum)) { - warning ("Cannot convert floating-point register value " - "to non-floating-point type."); - memset (to, 0, TYPE_LENGTH (type)); + char mmx_buf[MAX_REGISTER_SIZE]; + int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum); + + /* Extract (always little endian). */ + regcache_raw_read (regcache, fpnum, mmx_buf); + memcpy (buf, mmx_buf, register_size (gdbarch, regnum)); + } + else + regcache_raw_read (regcache, regnum, buf); +} + +static void +i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, const void *buf) +{ + if (i386_mmx_regnum_p (gdbarch, regnum)) + { + char mmx_buf[MAX_REGISTER_SIZE]; + int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum); + + /* Read ... */ + regcache_raw_read (regcache, fpnum, mmx_buf); + /* ... Modify ... (always little endian). */ + memcpy (mmx_buf, buf, register_size (gdbarch, regnum)); + /* ... Write. */ + regcache_raw_write (regcache, fpnum, mmx_buf); + } + else + regcache_raw_write (regcache, regnum, buf); +} + + +/* Return the register number of the register allocated by GCC after + REGNUM, or -1 if there is no such register. */ + +static int +i386_next_regnum (int regnum) +{ + /* GCC allocates the registers in the order: + + %eax, %edx, %ecx, %ebx, %esi, %edi, %ebp, %esp, ... + + Since storing a variable in %esp doesn't make any sense we return + -1 for %ebp and for %esp itself. */ + static int next_regnum[] = + { + I386_EDX_REGNUM, /* Slot for %eax. */ + I386_EBX_REGNUM, /* Slot for %ecx. */ + I386_ECX_REGNUM, /* Slot for %edx. */ + I386_ESI_REGNUM, /* Slot for %ebx. */ + -1, -1, /* Slots for %esp and %ebp. */ + I386_EDI_REGNUM, /* Slot for %esi. */ + I386_EBP_REGNUM /* Slot for %edi. */ + }; + + if (regnum >= 0 && regnum < sizeof (next_regnum) / sizeof (next_regnum[0])) + return next_regnum[regnum]; + + return -1; +} + +/* Return nonzero if a value of type TYPE stored in register REGNUM + needs any special handling. */ + +static int +i386_convert_register_p (int regnum, struct type *type) +{ + int len = TYPE_LENGTH (type); + + /* Values may be spread across multiple registers. Most debugging + formats aren't expressive enough to specify the locations, so + some heuristics is involved. Right now we only handle types that + have a length that is a multiple of the word size, since GCC + doesn't seem to put any other types into registers. */ + if (len > 4 && len % 4 == 0) + { + int last_regnum = regnum; + + while (len > 4) + { + last_regnum = i386_next_regnum (last_regnum); + len -= 4; + } + + if (last_regnum != -1) + return 1; + } + + return i386_fp_regnum_p (regnum); +} + +/* Read a value of type TYPE from register REGNUM in frame FRAME, and + return its contents in TO. */ + +static void +i386_register_to_value (struct frame_info *frame, int regnum, + struct type *type, void *to) +{ + int len = TYPE_LENGTH (type); + char *buf = to; + + /* FIXME: kettenis/20030609: What should we do if REGNUM isn't + available in FRAME (i.e. if it wasn't saved)? */ + + if (i386_fp_regnum_p (regnum)) + { + i387_register_to_value (frame, regnum, type, to); return; } - /* Convert to TYPE. This should be a no-op if TYPE is equivalent to - the extended floating-point format used by the FPU. */ - convert_typed_floating (from, builtin_type_i387_ext, to, type); + /* Read a value spread accross multiple registers. */ + + gdb_assert (len > 4 && len % 4 == 0); + + while (len > 0) + { + gdb_assert (regnum != -1); + gdb_assert (register_size (current_gdbarch, regnum) == 4); + + get_frame_register (frame, regnum, buf); + regnum = i386_next_regnum (regnum); + len -= 4; + buf += 4; + } } -/* Convert data from virtual format with type TYPE in buffer FROM to - raw format for register REGNUM in buffer TO. */ +/* Write the contents FROM of a value of type TYPE into register + REGNUM in frame FRAME. */ -void -i386_register_convert_to_raw (struct type *type, int regnum, - char *from, char *to) +static void +i386_value_to_register (struct frame_info *frame, int regnum, + struct type *type, const void *from) { - gdb_assert (IS_FP_REGNUM (regnum)); + int len = TYPE_LENGTH (type); + const char *buf = from; - /* We only support floating-point values. */ - if (TYPE_CODE (type) != TYPE_CODE_FLT) + if (i386_fp_regnum_p (regnum)) { - warning ("Cannot convert non-floating-point type " - "to floating-point register value."); - memset (to, 0, TYPE_LENGTH (type)); + i387_value_to_register (frame, regnum, type, from); return; } - /* Convert from TYPE. This should be a no-op if TYPE is equivalent - to the extended floating-point format used by the FPU. */ - convert_typed_floating (from, type, to, builtin_type_i387_ext); -} - + /* Write a value spread accross multiple registers. */ -#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. */ + gdb_assert (len > 4 && len % 4 == 0); -CORE_ADDR -i386v4_sigtramp_saved_pc (struct frame_info *frame) -{ - CORE_ADDR saved_pc_offset = 4; - char *name = NULL; - - find_pc_partial_function (frame->pc, &name, NULL, NULL); - if (name) + while (len > 0) { - 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; + gdb_assert (regnum != -1); + gdb_assert (register_size (current_gdbarch, regnum) == 4); + + put_frame_register (frame, regnum, buf); + regnum = i386_next_regnum (regnum); + len -= 4; + buf += 4; + } +} + +/* Supply register REGNUM from the general-purpose register set REGSET + to register cache REGCACHE. If REGNUM is -1, do this for all + registers in REGSET. */ + +void +i386_supply_gregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + const struct gdbarch_tdep *tdep = regset->descr; + const char *regs = gregs; + int i; + + gdb_assert (len == tdep->sizeof_gregset); + + for (i = 0; i < tdep->gregset_num_regs; i++) + { + if ((regnum == i || regnum == -1) + && tdep->gregset_reg_offset[i] != -1) + regcache_raw_supply (regcache, i, regs + tdep->gregset_reg_offset[i]); + } +} + +/* Supply register REGNUM from the floating-point register set REGSET + to register cache REGCACHE. If REGNUM is -1, do this for all + registers in REGSET. */ + +static void +i386_supply_fpregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *fpregs, size_t len) +{ + const struct gdbarch_tdep *tdep = regset->descr; + + if (len == I387_SIZEOF_FXSAVE) + { + i387_supply_fxsave (regcache, regnum, fpregs); + return; } - 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); + gdb_assert (len == tdep->sizeof_fpregset); + i387_supply_fsave (regcache, regnum, fpregs); +} + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ + +const struct regset * +i386_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset) + { + if (tdep->gregset == NULL) + { + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = tdep; + tdep->gregset->supply_regset = i386_supply_gregset; + } + return tdep->gregset; + } + + if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset) + || (strcmp (sect_name, ".reg-xfp") == 0 + && sect_size == I387_SIZEOF_FXSAVE)) + { + if (tdep->fpregset == NULL) + { + tdep->fpregset = XMALLOC (struct regset); + tdep->fpregset->descr = tdep; + tdep->fpregset->supply_regset = i386_supply_fpregset; + } + return tdep->fpregset; + } + + return NULL; } -#endif /* I386V4_SIGTRAMP_SAVED_PC */ #ifdef STATIC_TRANSFORM_NAME @@ -1182,14 +1670,14 @@ sunpro_static_transform_name (char *name) /* Stuff for WIN32 PE style DLL's but is pretty generic really. */ CORE_ADDR -skip_trampoline_code (CORE_ADDR pc, char *name) +i386_pe_skip_trampoline_code (CORE_ADDR pc, char *name) { if (pc && read_memory_unsigned_integer (pc, 2) == 0x25ff) /* jmp *(dest) */ { unsigned long indirect = read_memory_unsigned_integer (pc + 2, 4); struct minimal_symbol *indsym = indirect ? lookup_minimal_symbol_by_pc (indirect) : 0; - char *symname = indsym ? SYMBOL_NAME (indsym) : 0; + char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0; if (symname) { @@ -1202,148 +1690,372 @@ skip_trampoline_code (CORE_ADDR pc, char *name) } +/* Return non-zero if PC and NAME show that we are in a signal + trampoline. */ + +static int +i386_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + return (name && strcmp ("_sigtramp", name) == 0); +} + + /* We have two flavours of disassembly. The machinery on this page deals with switching between those. */ static int -gdb_print_insn_i386 (bfd_vma memaddr, disassemble_info *info) +i386_print_insn (bfd_vma pc, struct disassemble_info *info) { - if (disassembly_flavor == att_flavor) - return print_insn_i386_att (memaddr, info); - else if (disassembly_flavor == intel_flavor) - return print_insn_i386_intel (memaddr, info); - /* Never reached -- disassembly_flavour is always either att_flavor - or intel_flavor. */ - internal_error (__FILE__, __LINE__, "failed internal consistency check"); + gdb_assert (disassembly_flavor == att_flavor + || disassembly_flavor == intel_flavor); + + /* FIXME: kettenis/20020915: Until disassembler_options is properly + constified, cast to prevent a compiler warning. */ + info->disassembler_options = (char *) disassembly_flavor; + info->mach = gdbarch_bfd_arch_info (current_gdbarch)->mach; + + return print_insn_i386 (pc, info); +} + + +/* There are a few i386 architecture variants that differ only + slightly from the generic i386 target. For now, we don't give them + their own source file, but include them here. As a consequence, + they'll always be included. */ + +/* System V Release 4 (SVR4). */ + +static int +i386_svr4_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + /* UnixWare uses _sigacthandler. The origin of the other symbols is + currently unknown. */ + return (name && (strcmp ("_sigreturn", name) == 0 + || strcmp ("_sigacthandler", name) == 0 + || strcmp ("sigvechandler", name) == 0)); +} + +/* Assuming NEXT_FRAME is for a frame following a SVR4 sigtramp + routine, return the address of the associated sigcontext (ucontext) + structure. */ + +static CORE_ADDR +i386_svr4_sigcontext_addr (struct frame_info *next_frame) +{ + char buf[4]; + CORE_ADDR sp; + + frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); + sp = extract_unsigned_integer (buf, 4); + + return read_memory_unsigned_integer (sp + 8, 4); +} + + +/* DJGPP. */ + +static int +i386_go32_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + /* DJGPP doesn't have any special frames for signal handlers. */ + return 0; +} + + +/* Generic ELF. */ + +void +i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + /* We typically use stabs-in-ELF with the DWARF register numbering. */ + set_gdbarch_stab_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum); +} + +/* System V Release 4 (SVR4). */ + +void +i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* System V Release 4 uses ELF. */ + i386_elf_init_abi (info, gdbarch); + + /* System V Release 4 has shared libraries. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + + set_gdbarch_pc_in_sigtramp (gdbarch, i386_svr4_pc_in_sigtramp); + tdep->sigcontext_addr = i386_svr4_sigcontext_addr; + tdep->sc_pc_offset = 36 + 14 * 4; + tdep->sc_sp_offset = 36 + 17 * 4; + + tdep->jb_pc_offset = 20; +} + +/* DJGPP. */ + +static void +i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + set_gdbarch_pc_in_sigtramp (gdbarch, i386_go32_pc_in_sigtramp); + + tdep->jb_pc_offset = 36; +} + +/* NetWare. */ + +static void +i386_nw_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + tdep->jb_pc_offset = 24; +} + + +/* i386 register groups. In addition to the normal groups, add "mmx" + and "sse". */ + +static struct reggroup *i386_sse_reggroup; +static struct reggroup *i386_mmx_reggroup; + +static void +i386_init_reggroups (void) +{ + i386_sse_reggroup = reggroup_new ("sse", USER_REGGROUP); + i386_mmx_reggroup = reggroup_new ("mmx", USER_REGGROUP); +} + +static void +i386_add_reggroups (struct gdbarch *gdbarch) +{ + reggroup_add (gdbarch, i386_sse_reggroup); + reggroup_add (gdbarch, i386_mmx_reggroup); + reggroup_add (gdbarch, general_reggroup); + reggroup_add (gdbarch, float_reggroup); + reggroup_add (gdbarch, all_reggroup); + reggroup_add (gdbarch, save_reggroup); + reggroup_add (gdbarch, restore_reggroup); + reggroup_add (gdbarch, vector_reggroup); + reggroup_add (gdbarch, system_reggroup); +} + +int +i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) +{ + int sse_regnum_p = (i386_sse_regnum_p (gdbarch, regnum) + || i386_mxcsr_regnum_p (gdbarch, regnum)); + int fp_regnum_p = (i386_fp_regnum_p (regnum) + || i386_fpc_regnum_p (regnum)); + int mmx_regnum_p = (i386_mmx_regnum_p (gdbarch, regnum)); + + if (group == i386_mmx_reggroup) + return mmx_regnum_p; + if (group == i386_sse_reggroup) + return sse_regnum_p; + if (group == vector_reggroup) + return (mmx_regnum_p || sse_regnum_p); + if (group == float_reggroup) + return fp_regnum_p; + if (group == general_reggroup) + return (!fp_regnum_p && !mmx_regnum_p && !sse_regnum_p); + + return default_register_reggroup_p (gdbarch, regnum, group); +} + + +/* Get the ARGIth function argument for the current function. */ + +static CORE_ADDR +i386_fetch_pointer_argument (struct frame_info *frame, int argi, + struct type *type) +{ + CORE_ADDR sp = get_frame_register_unsigned (frame, I386_ESP_REGNUM); + return read_memory_unsigned_integer (sp + (4 * (argi + 1)), 4); } -static void -process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) -{ - int *os_ident_ptr = obj; - const char *name; - unsigned int sect_size; - - name = bfd_get_section_name (abfd, sect); - sect_size = bfd_section_size (abfd, sect); - if (strcmp (name, ".note.ABI-tag") == 0 && sect_size > 0) - { - unsigned int name_length, data_length, note_type; - char *note = alloca (sect_size); - - bfd_get_section_contents (abfd, sect, note, - (file_ptr) 0, (bfd_size_type) sect_size); - - name_length = bfd_h_get_32 (abfd, note); - data_length = bfd_h_get_32 (abfd, note + 4); - note_type = bfd_h_get_32 (abfd, note + 8); - - if (name_length == 4 && data_length == 16 && note_type == 1 - && strcmp (note + 12, "GNU") == 0) - { - int os_number = bfd_h_get_32 (abfd, note + 16); - - /* The case numbers are from abi-tags in glibc. */ - switch (os_number) - { - case 0: - *os_ident_ptr = ELFOSABI_LINUX; - break; - case 1: - *os_ident_ptr = ELFOSABI_HURD; - break; - case 2: - *os_ident_ptr = ELFOSABI_SOLARIS; - break; - default: - internal_error (__FILE__, __LINE__, - "process_note_abi_sections: " - "unknown OS number %d", os_number); - break; - } - } - } -} - -struct gdbarch * +static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch_tdep *tdep; struct gdbarch *gdbarch; - int os_ident; - if (info.abfd != NULL - && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) - { - os_ident = elf_elfheader (info.abfd)->e_ident[EI_OSABI]; - - /* If os_ident is 0, it is not necessarily the case that we're - on a SYSV system. (ELFOSABI_NONE is defined to be 0.) - GNU/Linux uses a note section to record OS/ABI info, but - leaves e_ident[EI_OSABI] zero. So we have to check for note - sections too. */ - if (os_ident == ELFOSABI_NONE) - bfd_map_over_sections (info.abfd, - process_note_abi_tag_sections, - &os_ident); - - /* If that didn't help us, revert to some non-standard checks. */ - if (os_ident == ELFOSABI_NONE) - { - /* FreeBSD folks are naughty; they stored the string - "FreeBSD" in the padding of the e_ident field of the ELF - header. */ - if (strcmp (&elf_elfheader (info.abfd)->e_ident[8], "FreeBSD") == 0) - os_ident = ELFOSABI_FREEBSD; - } - } - else - os_ident = -1; - - for (arches = gdbarch_list_lookup_by_info (arches, &info); - arches != NULL; - arches = gdbarch_list_lookup_by_info (arches->next, &info)) - { - tdep = gdbarch_tdep (arches->gdbarch); - if (tdep && tdep->os_ident == os_ident) - return arches->gdbarch; - } + /* If there is already a candidate, use it. */ + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != NULL) + return arches->gdbarch; /* Allocate space for the new architecture. */ tdep = XMALLOC (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); - tdep->os_ident = os_ident; + /* General-purpose registers. */ + tdep->gregset = NULL; + tdep->gregset_reg_offset = NULL; + tdep->gregset_num_regs = I386_NUM_GREGS; + tdep->sizeof_gregset = 0; - /* FIXME: kettenis/2001-11-24: Although not all IA-32 processors - have the SSE registers, it's easier to set the default to 8. */ - tdep->num_xmm_regs = 8; + /* Floating-point registers. */ + tdep->fpregset = NULL; + tdep->sizeof_fpregset = I387_SIZEOF_FSAVE; - set_gdbarch_use_generic_dummy_frames (gdbarch, 0); + /* The default settings include the FPU registers, the MMX registers + and the SSE registers. This can be overidden for a specific ABI + by adjusting the members `st0_regnum', `mm0_regnum' and + `num_xmm_regs' of `struct gdbarch_tdep', otherwise the registers + will show up in the output of "info all-registers". Ideally we + should try to autodetect whether they are available, such that we + can prevent "info all-registers" from displaying registers that + aren't available. + + NOTE: kevinb/2003-07-13: ... if it's a choice between printing + [the SSE registers] always (even when they don't exist) or never + showing them to the user (even when they do exist), I prefer the + former over the latter. */ + + tdep->st0_regnum = I386_ST0_REGNUM; + + /* The MMX registers are implemented as pseudo-registers. Put off + caclulating the register number for %mm0 until we know the number + of raw registers. */ + tdep->mm0_regnum = 0; + + /* I386_NUM_XREGS includes %mxcsr, so substract one. */ + tdep->num_xmm_regs = I386_NUM_XREGS - 1; + + tdep->jb_pc_offset = -1; + tdep->struct_return = pcc_struct_return; + tdep->sigtramp_start = 0; + tdep->sigtramp_end = 0; + tdep->sigcontext_addr = NULL; + tdep->sc_reg_offset = NULL; + tdep->sc_pc_offset = -1; + tdep->sc_sp_offset = -1; + + /* The format used for `long double' on almost all i386 targets is + the i387 extended floating-point format. In fact, of all targets + in the GCC 2.95 tree, only OSF/1 does it different, and insists + on having a `long double' that's not `long' at all. */ + set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext); + + /* Although the i387 extended floating-point has only 80 significant + bits, a `long double' actually takes up 96, probably to enforce + alignment. */ + set_gdbarch_long_double_bit (gdbarch, 96); + + /* The default ABI includes general-purpose registers, + floating-point registers, and the SSE registers. */ + set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS); + set_gdbarch_register_name (gdbarch, i386_register_name); + set_gdbarch_register_type (gdbarch, i386_register_type); + + /* Register numbers of various important registers. */ + set_gdbarch_sp_regnum (gdbarch, I386_ESP_REGNUM); /* %esp */ + set_gdbarch_pc_regnum (gdbarch, I386_EIP_REGNUM); /* %eip */ + set_gdbarch_ps_regnum (gdbarch, I386_EFLAGS_REGNUM); /* %eflags */ + set_gdbarch_fp0_regnum (gdbarch, I386_ST0_REGNUM); /* %st(0) */ + + /* Use the "default" register numbering scheme for stabs and COFF. */ + set_gdbarch_stab_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum); + set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum); + + /* Use the DWARF register numbering scheme for DWARF and DWARF 2. */ + set_gdbarch_dwarf_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum); + + /* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to + be in use on any of the supported i386 targets. */ + + set_gdbarch_print_float_info (gdbarch, i387_print_float_info); + + set_gdbarch_get_longjmp_target (gdbarch, i386_get_longjmp_target); /* Call dummy code. */ - set_gdbarch_call_dummy_location (gdbarch, ON_STACK); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 5); - set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); - set_gdbarch_call_dummy_p (gdbarch, 1); - set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); + set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call); - set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register); - set_gdbarch_push_arguments (gdbarch, i386_push_arguments); + set_gdbarch_convert_register_p (gdbarch, i386_convert_register_p); + set_gdbarch_register_to_value (gdbarch, i386_register_to_value); + set_gdbarch_value_to_register (gdbarch, i386_value_to_register); - set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack); + set_gdbarch_return_value (gdbarch, i386_return_value); - /* NOTE: tm-i386nw.h and tm-i386v4.h override this. */ - set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); + set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue); - /* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-linux.h, - tm-ptx.h, tm-symmetry.h currently override this. Sigh. */ - set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SSE_REGS); + /* Stack grows downward. */ + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + + set_gdbarch_breakpoint_from_pc (gdbarch, i386_breakpoint_from_pc); + set_gdbarch_decr_pc_after_break (gdbarch, 1); + + set_gdbarch_frame_args_skip (gdbarch, 8); + set_gdbarch_pc_in_sigtramp (gdbarch, i386_pc_in_sigtramp); + + /* Wire in the MMX registers. */ + set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs); + set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write); + + set_gdbarch_print_insn (gdbarch, i386_print_insn); + + set_gdbarch_unwind_dummy_id (gdbarch, i386_unwind_dummy_id); + + set_gdbarch_unwind_pc (gdbarch, i386_unwind_pc); + + /* Add the i386 register groups. */ + i386_add_reggroups (gdbarch); + set_gdbarch_register_reggroup_p (gdbarch, i386_register_reggroup_p); + + /* Helper for function argument information. */ + set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument); + + /* Hook in the DWARF CFI frame unwinder. */ + frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); + + frame_base_set_default (gdbarch, &i386_frame_base); + + /* Hook in ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); + + frame_unwind_append_sniffer (gdbarch, i386_sigtramp_frame_sniffer); + frame_unwind_append_sniffer (gdbarch, i386_frame_sniffer); + + /* If we have a register mapping, enable the generic core file + support, unless it has already been enabled. */ + if (tdep->gregset_reg_offset + && !gdbarch_regset_from_core_section_p (gdbarch)) + set_gdbarch_regset_from_core_section (gdbarch, + i386_regset_from_core_section); + + /* Unless support for MMX has been disabled, make %mm0 the first + pseudo-register. */ + if (tdep->mm0_regnum == 0) + tdep->mm0_regnum = gdbarch_num_regs (gdbarch); return gdbarch; } +static enum gdb_osabi +i386_coff_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "coff-go32-exe") == 0 + || strcmp (bfd_get_target (abfd), "coff-go32") == 0) + return GDB_OSABI_GO32; + + return GDB_OSABI_UNKNOWN; +} + +static enum gdb_osabi +i386_nlm_osabi_sniffer (bfd *abfd) +{ + return GDB_OSABI_NETWARE; +} + + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_i386_tdep (void); @@ -1352,22 +2064,6 @@ _initialize_i386_tdep (void) { register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init); - /* Initialize the table saying where each register starts in the - register file. */ - { - int i, offset; - - offset = 0; - for (i = 0; i < MAX_NUM_REGS; i++) - { - i386_register_offset[i] = offset; - offset += i386_register_size[i]; - } - } - - tm_print_insn = gdb_print_insn_i386; - tm_print_insn_info.mach = bfd_lookup_arch (bfd_arch_i386, 0)->mach; - /* Add the variable that controls the disassembly flavor. */ { struct cmd_list_element *new_cmd; @@ -1381,4 +2077,33 @@ and the default value is \"att\".", &setlist); add_show_from_set (new_cmd, &showlist); } + + /* Add the variable that controls the convention for returning + structs. */ + { + struct cmd_list_element *new_cmd; + + new_cmd = add_set_enum_cmd ("struct-convention", no_class, + valid_conventions, + &struct_convention, "\ +Set the convention for returning small structs, valid values \ +are \"default\", \"pcc\" and \"reg\", and the default value is \"default\".", + &setlist); + add_show_from_set (new_cmd, &showlist); + } + + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour, + i386_coff_osabi_sniffer); + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_nlm_flavour, + i386_nlm_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4, + i386_svr4_init_abi); + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_GO32, + i386_go32_init_abi); + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETWARE, + i386_nw_init_abi); + + /* Initialize the i386 specific register groups. */ + i386_init_reggroups (); } diff --git a/contrib/gdb/gdb/i386-tdep.h b/contrib/gdb/gdb/i386-tdep.h index a990adf0d66..9cb87653e12 100644 --- a/contrib/gdb/gdb/i386-tdep.h +++ b/contrib/gdb/gdb/i386-tdep.h @@ -1,6 +1,6 @@ -/* Target-dependent code for GDB, the GNU debugger. - Copyright 2001 - Free Software Foundation, Inc. +/* Target-dependent code for the i386. + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -22,6 +22,12 @@ #ifndef I386_TDEP_H #define I386_TDEP_H +struct frame_info; +struct gdbarch; +struct reggroup; +struct regset; +struct regcache; + /* GDB's i386 target supports both the 32-bit Intel Architecture (IA-32) and the 64-bit AMD x86-64 architecture. Internally it uses a similar register layout for both. @@ -40,20 +46,64 @@ differs and is determined by the num_xmm_regs member of `struct gdbarch_tdep'. */ +/* Convention for returning structures. */ + +enum struct_return +{ + pcc_struct_return, /* Return "short" structures in memory. */ + reg_struct_return /* Return "short" structures in registers. */ +}; + /* i386 architecture specific information. */ struct gdbarch_tdep { - /* OS/ABI. */ - int os_ident; + /* General-purpose registers. */ + struct regset *gregset; + int *gregset_reg_offset; + int gregset_num_regs; + size_t sizeof_gregset; + + /* Floating-point registers. */ + struct regset *fpregset; + size_t sizeof_fpregset; + + /* Register number for %st(0). The register numbers for the other + registers follow from this one. Set this to -1 to indicate the + absence of an FPU. */ + int st0_regnum; + + /* Register number for %mm0. Set this to -1 to indicate the absence + of MMX support. */ + int mm0_regnum; /* Number of SSE registers. */ int num_xmm_regs; + + /* Offset of saved PC in jmp_buf. */ + int jb_pc_offset; + + /* Convention for returning structures. */ + enum struct_return struct_return; + + /* Address range where sigtramp lives. */ + CORE_ADDR sigtramp_start; + CORE_ADDR sigtramp_end; + + /* Get address of sigcontext for sigtramp. */ + CORE_ADDR (*sigcontext_addr) (struct frame_info *); + + /* Offset of registers in `struct sigcontext'. */ + int *sc_reg_offset; + int sc_num_regs; + + /* Offset of saved PC and SP in `struct sigcontext'. Usage of these + is deprecated, please use `sc_reg_offset' instead. */ + int sc_pc_offset; + int sc_sp_offset; }; /* Floating-point registers. */ -#define FPU_REG_RAW_SIZE 10 - /* All FPU control regusters (except for FIOFF and FOOFF) are 16-bit (at most) in the FPU, but are zero-extended to 32 bits in GDB's register cache. */ @@ -86,11 +136,10 @@ struct gdbarch_tdep /* FPU opcode, bottom eleven bits. */ #define FOP_REGNUM (FPC_REGNUM + 7) -/* Return non-zero if N corresponds to a FPU data registers. */ -#define FP_REGNUM_P(n) (FP0_REGNUM <= (n) && (n) < FPC_REGNUM) - -/* Return non-zero if N corresponds to a FPU control register. */ -#define FPC_REGNUM_P(n) (FPC_REGNUM <= (n) && (n) < XMM0_REGNUM) +/* Return non-zero if REGNUM matches the FP register and the FP + register set is active. */ +extern int i386_fp_regnum_p (int regnum); +extern int i386_fpc_regnum_p (int regnum); /* SSE registers. */ @@ -101,16 +150,84 @@ struct gdbarch_tdep #define MXCSR_REGNUM \ (XMM0_REGNUM + gdbarch_tdep (current_gdbarch)->num_xmm_regs) -/* Return non-zero if N corresponds to a SSE data register. */ -#define SSE_REGNUM_P(n) (XMM0_REGNUM <= (n) && (n) < MXCSR_REGNUM) +/* Register numbers of various important registers. */ -/* FIXME: kettenis/2001-11-24: Obsolete macro's. */ -#define FCS_REGNUM FISEG_REGNUM -#define FCOFF_REGNUM FIOFF_REGNUM -#define FDS_REGNUM FOSEG_REGNUM -#define FDOFF_REGNUM FOOFF_REGNUM -#define IS_FP_REGNUM(n) FP_REGNUM_P (n) -#define IS_FPU_CTRL_REGNUM(n) FPC_REGNUM_P (n) -#define IS_SSE_REGNUM(n) SSE_REGNUM_P (n) +enum i386_regnum +{ + I386_EAX_REGNUM, /* %eax */ + I386_ECX_REGNUM, /* %ecx */ + I386_EDX_REGNUM, /* %edx */ + I386_EBX_REGNUM, /* %ebx */ + I386_ESP_REGNUM, /* %esp */ + I386_EBP_REGNUM, /* %ebp */ + I386_ESI_REGNUM, /* %esi */ + I386_EDI_REGNUM, /* %edi */ + I386_EIP_REGNUM, /* %eip */ + I386_EFLAGS_REGNUM, /* %eflags */ + I386_CS_REGNUM, /* %cs */ + I386_SS_REGNUM, /* %ss */ + I386_DS_REGNUM, /* %ds */ + I386_ES_REGNUM, /* %es */ + I386_FS_REGNUM, /* %fs */ + I386_GS_REGNUM, /* %gs */ + I386_ST0_REGNUM /* %st(0) */ +}; + +#define I386_NUM_GREGS 16 +#define I386_NUM_FREGS 16 +#define I386_NUM_XREGS 9 + +#define I386_SSE_NUM_REGS (I386_NUM_GREGS + I386_NUM_FREGS \ + + I386_NUM_XREGS) + +/* Size of the largest register. */ +#define I386_MAX_REGISTER_SIZE 16 + +/* Functions exported from i386-tdep.c. */ +extern CORE_ADDR i386_pe_skip_trampoline_code (CORE_ADDR pc, char *name); +extern int i386_frameless_signal_p (struct frame_info *frame); + +/* Return the name of register REG. */ +extern char const *i386_register_name (int reg); + +/* Return non-zero if REGNUM is a member of the specified group. */ +extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group); + +/* Supply register REGNUM from the general-purpose register set REGSET + to register cache REGCACHE. If REGNUM is -1, do this for all + registers in REGSET. */ +extern void i386_supply_gregset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *gregs, size_t len); + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ +extern const struct regset * + i386_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size); + +/* Initialize a basic ELF architecture variant. */ +extern void i386_elf_init_abi (struct gdbarch_info, struct gdbarch *); + +/* Initialize a SVR4 architecture variant. */ +extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *); + + +/* Functions and variables exported from i386bsd-tdep.c. */ + +extern void i386bsd_init_abi (struct gdbarch_info, struct gdbarch *); +extern int i386bsd_pc_in_sigtramp (CORE_ADDR pc, char *name); +extern CORE_ADDR i386bsd_sigtramp_start (CORE_ADDR pc); +extern CORE_ADDR i386bsd_sigtramp_end (CORE_ADDR pc); +extern CORE_ADDR i386fbsd_sigtramp_start_addr; +extern CORE_ADDR i386fbsd_sigtramp_end_addr; +extern CORE_ADDR i386obsd_sigtramp_start_addr; +extern CORE_ADDR i386obsd_sigtramp_end_addr; +extern int i386fbsd4_sc_reg_offset[]; +extern int i386fbsd_sc_reg_offset[]; +extern int i386nbsd_sc_reg_offset[]; +extern int i386obsd_sc_reg_offset[]; +extern int i386bsd_sc_reg_offset[]; #endif /* i386-tdep.h */ diff --git a/contrib/gdb/gdb/i386bsd-nat.c b/contrib/gdb/gdb/i386bsd-nat.c index 5d3583041b6..9383a1d5fea 100644 --- a/contrib/gdb/gdb/i386bsd-nat.c +++ b/contrib/gdb/gdb/i386bsd-nat.c @@ -1,5 +1,5 @@ /* Native-dependent code for modern i386 BSD's. - Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -43,6 +43,7 @@ typedef struct fpreg fpregset_t; #endif #include "gregset.h" +#include "i386-tdep.h" /* In older BSD versions we cannot get at some of the segment @@ -125,7 +126,7 @@ supply_gregset (gregset_t *gregsetp) { int i; - for (i = 0; i < NUM_GREGS; i++) + for (i = 0; i < I386_NUM_GREGS; i++) { if (CANNOT_FETCH_REGISTER (i)) supply_register (i, NULL); @@ -143,12 +144,12 @@ fill_gregset (gregset_t *gregsetp, int regno) { int i; - for (i = 0; i < NUM_GREGS; i++) + for (i = 0; i < I386_NUM_GREGS; i++) if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i)) regcache_collect (i, REG_ADDR (gregsetp, i)); } -#include "i387-nat.h" +#include "i387-tdep.h" /* Fill GDB's register array with the floating-point register values in *FPREGSETP. */ @@ -156,7 +157,7 @@ fill_gregset (gregset_t *gregsetp, int regno) void supply_fpregset (fpregset_t *fpregsetp) { - i387_supply_fsave ((char *) fpregsetp); + i387_supply_fsave (current_regcache, -1, fpregsetp); } /* Fill register REGNO (if it is a floating-point register) in @@ -175,7 +176,6 @@ fill_fpregset (fpregset_t *fpregsetp, int regno) void fetch_inferior_registers (int regno) { - if (regno == -1 || GETREGS_SUPPLIES (regno)) { gregset_t gregs; @@ -195,12 +195,12 @@ fetch_inferior_registers (int regno) #ifdef HAVE_PT_GETXMMREGS char xmmregs[512]; - if (have_ptrace_xmmregs != 0 && - ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) xmmregs, 0) == 0) + if (have_ptrace_xmmregs != 0 + && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) xmmregs, 0) == 0) { have_ptrace_xmmregs = 1; - i387_supply_fxsave (xmmregs); + i387_supply_fxsave (current_regcache, -1, xmmregs); } else { @@ -208,14 +208,14 @@ fetch_inferior_registers (int regno) (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) perror_with_name ("Couldn't get floating point status"); - supply_fpregset (&fpregs); + i387_supply_fsave (current_regcache, -1, &fpregs); } #else if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) perror_with_name ("Couldn't get floating point status"); - supply_fpregset (&fpregs); + i387_supply_fsave (current_regcache, -1, &fpregs); #endif } } @@ -226,7 +226,6 @@ fetch_inferior_registers (int regno) void store_inferior_registers (int regno) { - if (regno == -1 || GETREGS_SUPPLIES (regno)) { gregset_t gregs; @@ -251,9 +250,9 @@ store_inferior_registers (int regno) #ifdef HAVE_PT_GETXMMREGS char xmmregs[512]; - if (have_ptrace_xmmregs != 0 && - ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) xmmregs, 0) == 0) + if (have_ptrace_xmmregs != 0 + && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) xmmregs, 0) == 0) { have_ptrace_xmmregs = 1; @@ -271,7 +270,7 @@ store_inferior_registers (int regno) (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) perror_with_name ("Couldn't get floating point status"); - fill_fpregset (&fpregs, regno); + i387_fill_fsave ((char *) &fpregs, regno); if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) @@ -305,7 +304,7 @@ i386bsd_dr_set (int regnum, unsigned int value) /* For some mysterious reason, some of the reserved bits in the debug control register get set. Mask these off, otherwise the ptrace call below will fail. */ - dbregs.dr7 &= ~(0x0000fc00); + DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00); DBREG_DRX ((&dbregs), regnum) = value; @@ -354,7 +353,7 @@ i386bsd_dr_get_status (void) return 0; #endif - return dbregs.dr6; + return DBREG_DRX ((&dbregs), 6); } #endif /* PT_GETDBREGS */ @@ -382,19 +381,76 @@ kernel_u_size (void) return (sizeof (struct user)); } -/* See i386bsd-tdep.c. */ -extern int i386bsd_sigcontext_pc_offset; - void _initialize_i386bsd_nat (void) { + int offset; + /* To support the recognition of signal handlers, i386bsd-tdep.c hardcodes some constants. Inclusion of this file means that we are compiling a native debugger, which means that we can use the system header files and sysctl(3) to get at the relevant information. */ +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011 +#define SC_REG_OFFSET i386fbsd4_sc_reg_offset +#elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005 +#define SC_REG_OFFSET i386fbsd_sc_reg_offset +#elif defined (NetBSD) || defined (__NetBSD_Version__) +#define SC_REG_OFFSET i386nbsd_sc_reg_offset +#elif defined (OpenBSD) +#define SC_REG_OFFSET i386obsd_sc_reg_offset +#else +#define SC_REG_OFFSET i386bsd_sc_reg_offset +#endif + + /* We only check the program counter, stack pointer and frame + pointer since these members of `struct sigcontext' are essential + for providing backtraces. More checks could be added, but would + involve adding configure checks for the appropriate structure + members, since older BSD's don't provide all of them. */ + +#define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM] +#define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM] +#define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM] + /* Override the default value for the offset of the program counter in the sigcontext structure. */ - i386bsd_sigcontext_pc_offset = offsetof (struct sigcontext, sc_pc); + offset = offsetof (struct sigcontext, sc_pc); + + if (SC_PC_OFFSET != offset) + { + warning ("\ +offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\ +Please report this to .", + offset, SC_PC_OFFSET); + } + + SC_PC_OFFSET = offset; + + /* Likewise for the stack pointer. */ + offset = offsetof (struct sigcontext, sc_sp); + + if (SC_SP_OFFSET != offset) + { + warning ("\ +offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\ +Please report this to .", + offset, SC_SP_OFFSET); + } + + SC_SP_OFFSET = offset; + + /* And the frame pointer. */ + offset = offsetof (struct sigcontext, sc_fp); + + if (SC_FP_OFFSET != offset) + { + warning ("\ +offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\ +Please report this to .", + offset, SC_FP_OFFSET); + } + + SC_FP_OFFSET = offset; } diff --git a/contrib/gdb/gdb/i386bsd-tdep.c b/contrib/gdb/gdb/i386bsd-tdep.c index a01ed6b89e6..9276c32b3f7 100644 --- a/contrib/gdb/gdb/i386bsd-tdep.c +++ b/contrib/gdb/gdb/i386bsd-tdep.c @@ -1,5 +1,6 @@ /* Target-dependent code for i386 BSD's. - Copyright 2001 Free Software Foundation, Inc. + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -19,66 +20,151 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "arch-utils.h" #include "frame.h" #include "gdbcore.h" #include "regcache.h" +#include "osabi.h" + +#include "gdb_string.h" + +#include "i386-tdep.h" /* Support for signal handlers. */ -/* Range in which to find the signaltramp routine, traditionally found - on the use stack, just below the user area. Initialized to values - that work for NetBSD and FreeBSD. */ - -CORE_ADDR i386bsd_sigtramp_start = 0xbfbfdf20; -CORE_ADDR i386bsd_sigtramp_end = 0xbfbfdff0; - /* Return whether PC is in a BSD sigtramp routine. */ int -i386bsd_in_sigtramp (CORE_ADDR pc, char *name) +i386bsd_pc_in_sigtramp (CORE_ADDR pc, char *name) { - return (pc >= i386bsd_sigtramp_start && pc < i386bsd_sigtramp_end); + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + return (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end); } -/* Offset in the sigcontext structure of the program counter. - Initialized to the value from 4.4 BSD Lite. */ -int i386bsd_sigcontext_pc_offset = 20; - -/* Assuming FRAME is for a BSD sigtramp routine, return the address of - the associated sigcontext structure. */ +/* Assuming NEXT_FRAME is for a frame following a BSD sigtramp + routine, return the address of the associated sigcontext structure. */ static CORE_ADDR -i386bsd_sigcontext_addr (struct frame_info *frame) +i386bsd_sigcontext_addr (struct frame_info *next_frame) { - if (frame->next) - /* If this isn't the top frame, the next frame must be for the - signal handler itself. A pointer to the sigcontext structure - is passed as the third argument to the signal handler. */ - return read_memory_unsigned_integer (frame->next->frame + 16, 4); + char buf[4]; + CORE_ADDR sp; - /* This is the top frame. We'll have to find the address of the - sigcontext structure by looking at the stack pointer. */ - return read_memory_unsigned_integer (read_register (SP_REGNUM) + 8, 4); + frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); + sp = extract_unsigned_integer (buf, 4); + + return read_memory_unsigned_integer (sp + 8, 4); } -/* Assuming FRAME is for a BSD sigtramp routine, return the saved - program counter. */ - -static CORE_ADDR -i386bsd_sigtramp_saved_pc (struct frame_info *frame) -{ - CORE_ADDR addr; - addr = i386bsd_sigcontext_addr (frame); - return read_memory_unsigned_integer (addr + i386bsd_sigcontext_pc_offset, 4); -} - -/* Return the saved program counter for FRAME. */ +/* Return the start address of the sigtramp routine. */ CORE_ADDR -i386bsd_frame_saved_pc (struct frame_info *frame) +i386bsd_sigtramp_start (CORE_ADDR pc) { - if (frame->signal_handler_caller) - return i386bsd_sigtramp_saved_pc (frame); - - return read_memory_unsigned_integer (frame->frame + 4, 4); + return gdbarch_tdep (current_gdbarch)->sigtramp_start; +} + +/* Return the end address of the sigtramp routine. */ + +CORE_ADDR +i386bsd_sigtramp_end (CORE_ADDR pc) +{ + return gdbarch_tdep (current_gdbarch)->sigtramp_end; +} + + +/* Support for shared libraries. */ + +/* Return non-zero if we are in a shared library trampoline code stub. */ + +int +i386bsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name) +{ + return (name && !strcmp (name, "_DYNAMIC")); +} + +/* Traditional BSD (4.3 BSD, still used for BSDI and 386BSD). */ + +/* From . */ +int i386bsd_sc_reg_offset[] = +{ + -1, /* %eax */ + -1, /* %ecx */ + -1, /* %edx */ + -1, /* %ebx */ + 8 + 0 * 4, /* %esp */ + 8 + 1 * 4, /* %ebp */ + -1, /* %esi */ + -1, /* %edi */ + 8 + 3 * 4, /* %eip */ + 8 + 4 * 4, /* %eflags */ + -1, /* %cs */ + -1, /* %ss */ + -1, /* %ds */ + -1, /* %es */ + -1, /* %fs */ + -1 /* %gs */ +}; + +void +i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + set_gdbarch_pc_in_sigtramp (gdbarch, i386bsd_pc_in_sigtramp); + + /* Allow the recognition of sigtramps as a function named . */ + set_gdbarch_sigtramp_start (gdbarch, i386bsd_sigtramp_start); + set_gdbarch_sigtramp_end (gdbarch, i386bsd_sigtramp_end); + + /* Assume SunOS-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, + i386bsd_aout_in_solib_call_trampoline); + + tdep->jb_pc_offset = 0; + + tdep->sigtramp_start = 0xfdbfdfc0; + tdep->sigtramp_end = 0xfdbfe000; + tdep->sigcontext_addr = i386bsd_sigcontext_addr; + tdep->sc_reg_offset = i386bsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386bsd_sc_reg_offset); +} + + +static enum gdb_osabi +i386bsd_aout_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "a.out-i386-netbsd") == 0) + return GDB_OSABI_NETBSD_AOUT; + + if (strcmp (bfd_get_target (abfd), "a.out-i386-freebsd") == 0) + return GDB_OSABI_FREEBSD_AOUT; + + return GDB_OSABI_UNKNOWN; +} + +static enum gdb_osabi +i386bsd_core_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) + return GDB_OSABI_NETBSD_AOUT; + + return GDB_OSABI_UNKNOWN; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386bsd_tdep (void); + +void +_initialize_i386bsd_tdep (void) +{ + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_aout_flavour, + i386bsd_aout_osabi_sniffer); + + /* BFD doesn't set the architecture for NetBSD style a.out core + files. */ + gdbarch_register_osabi_sniffer (bfd_arch_unknown, bfd_target_unknown_flavour, + i386bsd_core_osabi_sniffer); } diff --git a/contrib/gdb/gdb/i386fbsd-nat.c b/contrib/gdb/gdb/i386fbsd-nat.c index 1c19ac87eb4..efc61b6cbbb 100644 --- a/contrib/gdb/gdb/i386fbsd-nat.c +++ b/contrib/gdb/gdb/i386fbsd-nat.c @@ -1,5 +1,6 @@ /* Native-dependent code for FreeBSD/i386. - Copyright 2001 Free Software Foundation, Inc. + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -26,6 +27,8 @@ #include #include +#include "i386-tdep.h" + /* Prevent warning from -Wmissing-prototypes. */ void _initialize_i386fbsd_nat (void); @@ -47,7 +50,7 @@ child_resume (ptid_t ptid, int step, enum target_signal signal) if (!step) { - unsigned int eflags; + ULONGEST eflags; /* Workaround for a bug in FreeBSD. Make sure that the trace flag is off when doing a continue. There is a code path @@ -59,9 +62,11 @@ child_resume (ptid_t ptid, int step, enum target_signal signal) never goes through the kernel's trap() function which would normally clear it. */ - eflags = read_register (PS_REGNUM); + regcache_cooked_read_unsigned (current_regcache, I386_EFLAGS_REGNUM, + &eflags); if (eflags & 0x0100) - write_register (PS_REGNUM, eflags & ~0x0100); + regcache_cooked_write_unsigned (current_regcache, I386_EFLAGS_REGNUM, + eflags & ~0x0100); request = PT_CONTINUE; } @@ -79,7 +84,7 @@ _initialize_i386fbsd_nat (void) { /* FreeBSD provides a kern.ps_strings sysctl that we can use to locate the sigtramp. That way we can still recognize a sigtramp - if it's location is changed in a new kernel. Of course this is + if its location is changed in a new kernel. Of course this is still based on the assumption that the sigtramp is placed directly under the location where the program arguments and environment can be found. */ @@ -94,8 +99,8 @@ _initialize_i386fbsd_nat (void) len = sizeof (ps_strings); if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0) { - i386bsd_sigtramp_start = ps_strings - 128; - i386bsd_sigtramp_end = ps_strings; + i386fbsd_sigtramp_start_addr = ps_strings - 128; + i386fbsd_sigtramp_end_addr = ps_strings; } } #endif diff --git a/contrib/gdb/gdb/i386fbsd-tdep.c b/contrib/gdb/gdb/i386fbsd-tdep.c new file mode 100644 index 00000000000..db14a67a5b5 --- /dev/null +++ b/contrib/gdb/gdb/i386fbsd-tdep.c @@ -0,0 +1,175 @@ +/* Target-dependent code for FreeBSD/i386. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "osabi.h" + +#include "i386-tdep.h" +#include "i387-tdep.h" +#include "solib-svr4.h" + +/* FreeBSD 3.0-RELEASE or later. */ + +/* From . */ +static int i386fbsd_r_reg_offset[] = +{ + 9 * 4, 8 * 4, 7 * 4, 6 * 4, /* %eax, %ecx, %edx, %ebx */ + 15 * 4, 4 * 4, /* %esp, %ebp */ + 3 * 4, 2 * 4, /* %esi, %edi */ + 12 * 4, 14 * 4, /* %eip, %eflags */ + 13 * 4, 16 * 4, /* %cs, %ss */ + 1 * 4, 0 * 4, -1, -1 /* %ds, %es, %fs, %gs */ +}; + +/* Sigtramp routine location. */ +CORE_ADDR i386fbsd_sigtramp_start_addr = 0xbfbfdf20; +CORE_ADDR i386fbsd_sigtramp_end_addr = 0xbfbfdff0; + +/* From . */ +static int i386fbsd_sc_reg_offset[] = +{ + 8 + 14 * 4, /* %eax */ + 8 + 13 * 4, /* %ecx */ + 8 + 12 * 4, /* %edx */ + 8 + 11 * 4, /* %ebx */ + 8 + 0 * 4, /* %esp */ + 8 + 1 * 4, /* %ebp */ + 8 + 10 * 4, /* %esi */ + 8 + 9 * 4, /* %edi */ + 8 + 3 * 4, /* %eip */ + 8 + 4 * 4, /* %eflags */ + 8 + 7 * 4, /* %cs */ + 8 + 8 * 4, /* %ss */ + 8 + 6 * 4, /* %ds */ + 8 + 5 * 4, /* %es */ + 8 + 15 * 4, /* %fs */ + 8 + 16 * 4 /* %gs */ +}; + +static void +i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Obviously FreeBSD is BSD-based. */ + i386bsd_init_abi (info, gdbarch); + + /* FreeBSD has a different `struct reg', and reserves some space for + its FPU emulator in `struct fpreg'. */ + tdep->gregset_reg_offset = i386fbsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd_r_reg_offset); + tdep->sizeof_gregset = 18 * 4; + tdep->sizeof_fpregset = 176; + + /* FreeBSD uses -freg-struct-return by default. */ + tdep->struct_return = reg_struct_return; + + /* FreeBSD uses a different memory layout. */ + tdep->sigtramp_start = i386fbsd_sigtramp_start_addr; + tdep->sigtramp_end = i386fbsd_sigtramp_end_addr; + + /* FreeBSD has a more complete `struct sigcontext'. */ + tdep->sc_reg_offset = i386fbsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset); +} + +static void +i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + /* It's almost identical to FreeBSD a.out. */ + i386fbsdaout_init_abi (info, gdbarch); + + /* Except that it uses ELF. */ + i386_elf_init_abi (info, gdbarch); + + /* FreeBSD ELF uses SVR4-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline + (gdbarch, generic_in_solib_call_trampoline); + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_ilp32_fetch_link_map_offsets); +} + +/* FreeBSD 4.0-RELEASE or later. */ + +/* From . */ +static int i386fbsd4_r_reg_offset[] = +{ + 10 * 4, 9 * 4, 8 * 4, 7 * 4, /* %eax, %ecx, %edx, %ebx */ + 16 * 4, 5 * 4, /* %esp, %ebp */ + 4 * 4, 3 * 4, /* %esi, %edi */ + 13 * 4, 15 * 4, /* %eip, %eflags */ + 14 * 4, 17 * 4, /* %cs, %ss */ + 2 * 4, 1 * 4, 0 * 4, 18 * 4 /* %ds, %es, %fs, %gs */ +}; + +/* From . */ +int i386fbsd4_sc_reg_offset[] = +{ + 20 + 11 * 4, /* %eax */ + 20 + 10 * 4, /* %ecx */ + 20 + 9 * 4, /* %edx */ + 20 + 8 * 4, /* %ebx */ + 20 + 17 * 4, /* %esp */ + 20 + 6 * 4, /* %ebp */ + 20 + 5 * 4, /* %esi */ + 20 + 4 * 4, /* %edi */ + 20 + 14 * 4, /* %eip */ + 20 + 16 * 4, /* %eflags */ + 20 + 15 * 4, /* %cs */ + 20 + 18 * 4, /* %ss */ + 20 + 3 * 4, /* %ds */ + 20 + 2 * 4, /* %es */ + 20 + 1 * 4, /* %fs */ + 20 + 0 * 4 /* %gs */ +}; + +static void +i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Inherit stuff from older releases. We assume that FreeBSD + 4.0-RELEASE always uses ELF. */ + i386fbsd_init_abi (info, gdbarch); + + /* FreeBSD 4.0 introduced a new `struct reg'. */ + tdep->gregset_reg_offset = i386fbsd4_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd4_r_reg_offset); + tdep->sizeof_gregset = 19 * 4; + + /* FreeBSD 4.0 introduced a new `struct sigcontext'. */ + tdep->sc_reg_offset = i386fbsd4_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386fbsd4_sc_reg_offset); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386fbsd_tdep (void); + +void +_initialize_i386fbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_AOUT, + i386fbsdaout_init_abi); + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_ELF, + i386fbsd4_init_abi); +} diff --git a/contrib/gdb/gdb/i386gnu-nat.c b/contrib/gdb/gdb/i386gnu-nat.c new file mode 100644 index 00000000000..7533f0965d5 --- /dev/null +++ b/contrib/gdb/gdb/i386gnu-nat.c @@ -0,0 +1,293 @@ +/* Low level interface to i386 running the GNU Hurd. + Copyright 1992, 1995, 1996, 1998, 2000, 2001 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "floatformat.h" +#include "regcache.h" + +#include "gdb_assert.h" +#include +#include + +#include +#include +#include +#include + +#include "i386-tdep.h" + +#include "gnu-nat.h" +#include "i387-tdep.h" + +#ifdef HAVE_SYS_PROCFS_H +# include +# include "gregset.h" +#endif + +/* Offset to the thread_state_t location where REG is stored. */ +#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg) + +/* At REG_OFFSET[N] is the offset to the thread_state_t location where + the GDB register N is stored. */ +static int reg_offset[] = +{ + REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx), + REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi), + REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss), + REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs) +}; + +#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum]) + + +/* Get the whole floating-point state of THREAD and record the + values of the corresponding (pseudo) registers. */ +static void +fetch_fpregs (struct proc *thread) +{ + mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; + struct i386_float_state state; + error_t err; + + err = thread_get_state (thread->port, i386_FLOAT_STATE, + (thread_state_t) &state, &count); + if (err) + { + warning ("Couldn't fetch floating-point state from %s", + proc_string (thread)); + return; + } + + if (!state.initialized) + /* The floating-point state isn't initialized. */ + { + int i; + + for (i = FP0_REGNUM; i <= FOP_REGNUM; i++) + supply_register (i, NULL); + + return; + } + + /* Supply the floating-point registers. */ + i387_supply_fsave (current_regcache, -1, state.hw_state); +} + +#ifdef HAVE_SYS_PROCFS_H +/* These two calls are used by the core-regset.c code for + reading ELF core files. */ +void +supply_gregset (gdb_gregset_t *gregs) +{ + int i; + for (i = 0; i < I386_NUM_GREGS; i++) + supply_register (i, REG_ADDR (gregs, i)); +} + +void +supply_fpregset (gdb_fpregset_t *fpregs) +{ + i387_supply_fsave (current_regcache, -1, fpregs); +} +#endif + +/* Fetch register REGNO, or all regs if REGNO is -1. */ +void +gnu_fetch_registers (int regno) +{ + struct proc *thread; + + /* Make sure we know about new threads. */ + inf_update_procs (current_inferior); + + thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); + if (!thread) + error ("Can't fetch registers from thread %d: No such thread", + PIDGET (inferior_ptid)); + + if (regno < I386_NUM_GREGS || regno == -1) + { + thread_state_t state; + + /* This does the dirty work for us. */ + state = proc_get_state (thread, 0); + if (!state) + { + warning ("Couldn't fetch registers from %s", + proc_string (thread)); + return; + } + + if (regno == -1) + { + int i; + + proc_debug (thread, "fetching all register"); + + for (i = 0; i < I386_NUM_GREGS; i++) + supply_register (i, REG_ADDR (state, i)); + thread->fetched_regs = ~0; + } + else + { + proc_debug (thread, "fetching register %s", REGISTER_NAME (regno)); + + supply_register (regno, REG_ADDR (state, regno)); + thread->fetched_regs |= (1 << regno); + } + } + + if (regno >= I386_NUM_GREGS || regno == -1) + { + proc_debug (thread, "fetching floating-point registers"); + + fetch_fpregs (thread); + } +} + + +/* Store the whole floating-point state into THREAD using information + from the corresponding (pseudo) registers. */ +static void +store_fpregs (struct proc *thread, int regno) +{ + mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; + struct i386_float_state state; + error_t err; + + err = thread_get_state (thread->port, i386_FLOAT_STATE, + (thread_state_t) &state, &count); + if (err) + { + warning ("Couldn't fetch floating-point state from %s", + proc_string (thread)); + return; + } + + /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow + take into account DEPRECATED_REGISTER_VALID like the old code did? */ + i387_fill_fsave (state.hw_state, regno); + + err = thread_set_state (thread->port, i386_FLOAT_STATE, + (thread_state_t) &state, i386_FLOAT_STATE_COUNT); + if (err) + { + warning ("Couldn't store floating-point state into %s", + proc_string (thread)); + return; + } +} + +/* Store at least register REGNO, or all regs if REGNO == -1. */ +void +gnu_store_registers (int regno) +{ + struct proc *thread; + + /* Make sure we know about new threads. */ + inf_update_procs (current_inferior); + + thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); + if (!thread) + error ("Couldn't store registers into thread %d: No such thread", + PIDGET (inferior_ptid)); + + if (regno < I386_NUM_GREGS || regno == -1) + { + thread_state_t state; + thread_state_data_t old_state; + int was_aborted = thread->aborted; + int was_valid = thread->state_valid; + int trace; + + if (!was_aborted && was_valid) + memcpy (&old_state, &thread->state, sizeof (old_state)); + + state = proc_get_state (thread, 1); + if (!state) + { + warning ("Couldn't store registers into %s", proc_string (thread)); + return; + } + + /* Save the T bit. We might try to restore the %eflags register + below, but changing the T bit would seriously confuse GDB. */ + trace = ((struct i386_thread_state *)state)->efl & 0x100; + + if (!was_aborted && was_valid) + /* See which registers have changed after aborting the thread. */ + { + int check_regno; + + for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++) + if ((thread->fetched_regs & (1 << check_regno)) + && memcpy (REG_ADDR (&old_state, check_regno), + REG_ADDR (state, check_regno), + DEPRECATED_REGISTER_RAW_SIZE (check_regno))) + /* Register CHECK_REGNO has changed! Ack! */ + { + warning ("Register %s changed after the thread was aborted", + REGISTER_NAME (check_regno)); + if (regno >= 0 && regno != check_regno) + /* Update GDB's copy of the register. */ + supply_register (check_regno, REG_ADDR (state, check_regno)); + else + warning ("... also writing this register! Suspicious..."); + } + } + +#define fill(state, regno) \ + memcpy (REG_ADDR(state, regno), &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)], \ + DEPRECATED_REGISTER_RAW_SIZE (regno)) + + if (regno == -1) + { + int i; + + proc_debug (thread, "storing all registers"); + + for (i = 0; i < I386_NUM_GREGS; i++) + if (deprecated_register_valid[i]) + fill (state, i); + } + else + { + proc_debug (thread, "storing register %s", REGISTER_NAME (regno)); + + gdb_assert (deprecated_register_valid[regno]); + fill (state, regno); + } + + /* Restore the T bit. */ + ((struct i386_thread_state *)state)->efl &= ~0x100; + ((struct i386_thread_state *)state)->efl |= trace; + } + +#undef fill + + if (regno >= I386_NUM_GREGS || regno == -1) + { + proc_debug (thread, "storing floating-point registers"); + + store_fpregs (thread, regno); + } +} diff --git a/contrib/gdb/gdb/i386gnu-tdep.c b/contrib/gdb/gdb/i386gnu-tdep.c new file mode 100644 index 00000000000..297d566abcb --- /dev/null +++ b/contrib/gdb/gdb/i386gnu-tdep.c @@ -0,0 +1,44 @@ +/* Target-dependent code for the GNU Hurd. + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "osabi.h" + +#include "i386-tdep.h" + +static void +i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* GNU uses ELF. */ + i386_elf_init_abi (info, gdbarch); + + tdep->jb_pc_offset = 20; /* From . */ +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern void _initialize_i386gnu_tdep (void); + +void +_initialize_i386gnu_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_HURD, i386gnu_init_abi); +} diff --git a/contrib/gdb/gdb/i386ly-tdep.c b/contrib/gdb/gdb/i386ly-tdep.c new file mode 100644 index 00000000000..2374b71aa1f --- /dev/null +++ b/contrib/gdb/gdb/i386ly-tdep.c @@ -0,0 +1,81 @@ +/* Target-dependent code for Intel 386 running LynxOS. + Copyright 1993, 1996, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "inferior.h" +#include "regcache.h" +#include "target.h" +#include "osabi.h" + +#include "i386-tdep.h" + +/* Return the PC of the caller from the call frame. Assumes the subr + prologue has already been executed, and the frame pointer setup. + If this is the outermost frame, we check to see if we are in a + system call by examining the previous instruction. If so, then the + return PC is actually at SP+4 because system calls use a different + calling sequence. */ + +static CORE_ADDR +i386lynx_saved_pc_after_call (struct frame_info *frame) +{ + char opcode[7]; + static const unsigned char call_inst[] = + { 0x9a, 0, 0, 0, 0, 8, 0 }; /* lcall 0x8,0x0 */ + + read_memory_nobpt (frame->pc - 7, opcode, 7); + if (memcmp (opcode, call_inst, 7) == 0) + return read_memory_unsigned_integer (read_register (SP_REGNUM) + 4, 4); + + return read_memory_unsigned_integer (read_register (SP_REGNUM), 4); +} + + +/* LynxOS. */ +static void +i386lynx_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + set_gdbarch_deprecated_saved_pc_after_call (gdbarch, i386lynx_saved_pc_after_call); +} + + +static enum gdb_osabi +i386lynx_coff_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "coff-i386-lynx") == 0) + return GDB_OSABI_LYNXOS; + + return GDB_OSABI_UNKNOWN; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386lynx_tdep (void); + +void +_initialize_i386lynx_tdep (void) +{ + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour, + i386lynx_coff_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LYNXOS, + i386lynx_init_abi); +} diff --git a/contrib/gdb/gdb/i386nbsd-tdep.c b/contrib/gdb/gdb/i386nbsd-tdep.c index 7174d4d433e..82013b59fc0 100644 --- a/contrib/gdb/gdb/i386nbsd-tdep.c +++ b/contrib/gdb/gdb/i386nbsd-tdep.c @@ -1,5 +1,7 @@ -/* Target-dependent code for NetBSD/i386, for GDB. - Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001 +/* Target-dependent code for NetBSD/i386. + + Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002, + 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -20,13 +22,265 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "gdbtypes.h" +#include "arch-utils.h" +#include "gdbcore.h" +#include "regcache.h" +#include "regset.h" +#include "osabi.h" -int -i386nbsd_use_struct_convention (int gcc_p, struct type *type) +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "i386-tdep.h" +#include "i387-tdep.h" +#include "nbsd-tdep.h" +#include "solib-svr4.h" + +/* From . */ +static int i386nbsd_r_reg_offset[] = { - return !(TYPE_LENGTH (type) == 1 - || TYPE_LENGTH (type) == 2 - || TYPE_LENGTH (type) == 4 - || TYPE_LENGTH (type) == 8); + 0 * 4, /* %eax */ + 1 * 4, /* %ecx */ + 2 * 4, /* %edx */ + 3 * 4, /* %ebx */ + 4 * 4, /* %esp */ + 5 * 4, /* %ebp */ + 6 * 4, /* %esi */ + 7 * 4, /* %edi */ + 8 * 4, /* %eip */ + 9 * 4, /* %eflags */ + 10 * 4, /* %cs */ + 11 * 4, /* %ss */ + 12 * 4, /* %ds */ + 13 * 4, /* %es */ + 14 * 4, /* %fs */ + 15 * 4 /* %gs */ +}; + +static void +i386nbsd_aout_supply_regset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *regs, size_t len) +{ + const struct gdbarch_tdep *tdep = regset->descr; + + gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE); + + i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset); + i387_supply_fsave (regcache, regnum, (char *) regs + tdep->sizeof_gregset); +} + +static const struct regset * +i386nbsd_aout_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, + size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* NetBSD a.out core dumps don't use seperate register sets for the + general-purpose and floating-point registers. */ + + if (strcmp (sect_name, ".reg") == 0 + && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE) + { + if (tdep->gregset == NULL) + { + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = tdep; + tdep->gregset->supply_regset = i386nbsd_aout_supply_regset; + } + return tdep->gregset; + } + + return NULL; +} + +/* Under NetBSD/i386, signal handler invocations can be identified by the + designated code sequence that is used to return from a signal handler. + In particular, the return address of a signal handler points to the + following code sequence: + + leal 0x10(%esp), %eax + pushl %eax + pushl %eax + movl $0x127, %eax # __sigreturn14 + int $0x80 + + Each instruction has a unique encoding, so we simply attempt to match + the instruction the PC is pointing to with any of the above instructions. + If there is a hit, we know the offset to the start of the designated + sequence and can then check whether we really are executing in the + signal trampoline. If not, -1 is returned, otherwise the offset from the + start of the return sequence is returned. */ +#define RETCODE_INSN1 0x8d +#define RETCODE_INSN2 0x50 +#define RETCODE_INSN3 0x50 +#define RETCODE_INSN4 0xb8 +#define RETCODE_INSN5 0xcd + +#define RETCODE_INSN2_OFF 4 +#define RETCODE_INSN3_OFF 5 +#define RETCODE_INSN4_OFF 6 +#define RETCODE_INSN5_OFF 11 + +static const unsigned char sigtramp_retcode[] = +{ + RETCODE_INSN1, 0x44, 0x24, 0x10, + RETCODE_INSN2, + RETCODE_INSN3, + RETCODE_INSN4, 0x27, 0x01, 0x00, 0x00, + RETCODE_INSN5, 0x80, +}; + +static LONGEST +i386nbsd_sigtramp_offset (CORE_ADDR pc) +{ + unsigned char ret[sizeof(sigtramp_retcode)], insn; + LONGEST off; + int i; + + if (read_memory_nobpt (pc, &insn, 1) != 0) + return -1; + + switch (insn) + { + case RETCODE_INSN1: + off = 0; + break; + + case RETCODE_INSN2: + /* INSN2 and INSN3 are the same. Read at the location of PC+1 + to determine if we're actually looking at INSN2 or INSN3. */ + if (read_memory_nobpt (pc + 1, &insn, 1) != 0) + return -1; + + if (insn == RETCODE_INSN3) + off = RETCODE_INSN2_OFF; + else + off = RETCODE_INSN3_OFF; + break; + + case RETCODE_INSN4: + off = RETCODE_INSN4_OFF; + break; + + case RETCODE_INSN5: + off = RETCODE_INSN5_OFF; + break; + + default: + return -1; + } + + pc -= off; + + if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0) + return -1; + + if (memcmp (ret, sigtramp_retcode, sizeof (ret)) == 0) + return off; + + return -1; +} + +static int +i386nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + return (nbsd_pc_in_sigtramp (pc, name) + || i386nbsd_sigtramp_offset (pc) >= 0); +} + +/* From . */ +int i386nbsd_sc_reg_offset[] = +{ + 10 * 4, /* %eax */ + 9 * 4, /* %ecx */ + 8 * 4, /* %edx */ + 7 * 4, /* %ebx */ + 14 * 4, /* %esp */ + 6 * 4, /* %ebp */ + 5 * 4, /* %esi */ + 4 * 4, /* %edi */ + 11 * 4, /* %eip */ + 13 * 4, /* %eflags */ + 12 * 4, /* %cs */ + 15 * 4, /* %ss */ + 3 * 4, /* %ds */ + 2 * 4, /* %es */ + 1 * 4, /* %fs */ + 0 * 4 /* %gs */ +}; + +static void +i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Obviously NetBSD is BSD-based. */ + i386bsd_init_abi (info, gdbarch); + + /* NetBSD has a different `struct reg'. */ + tdep->gregset_reg_offset = i386nbsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset); + tdep->sizeof_gregset = 16 * 4; + + /* NetBSD has different signal trampoline conventions. */ + set_gdbarch_pc_in_sigtramp (gdbarch, i386nbsd_pc_in_sigtramp); + /* FIXME: kettenis/20020906: We should probably provide + NetBSD-specific versions of these functions if we want to + recognize signal trampolines that live on the stack. */ + set_gdbarch_sigtramp_start (gdbarch, NULL); + set_gdbarch_sigtramp_end (gdbarch, NULL); + + /* NetBSD uses -freg-struct-return by default. */ + tdep->struct_return = reg_struct_return; + + /* NetBSD has a `struct sigcontext' that's different from the + origional 4.3 BSD. */ + tdep->sc_reg_offset = i386nbsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset); +} + +/* NetBSD a.out. */ + +static void +i386nbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + i386nbsd_init_abi (info, gdbarch); + + /* NetBSD a.out has a single register set. */ + set_gdbarch_regset_from_core_section + (gdbarch, i386nbsd_aout_regset_from_core_section); +} + +/* NetBSD ELF. */ + +static void +i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* It's still NetBSD. */ + i386nbsd_init_abi (info, gdbarch); + + /* But ELF-based. */ + i386_elf_init_abi (info, gdbarch); + + /* NetBSD ELF uses SVR4-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline + (gdbarch, generic_in_solib_call_trampoline); + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_ilp32_fetch_link_map_offsets); + + /* NetBSD ELF uses -fpcc-struct-return by default. */ + tdep->struct_return = pcc_struct_return; +} + +void +_initialize_i386nbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD_AOUT, + i386nbsdaout_init_abi); + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD_ELF, + i386nbsdelf_init_abi); } diff --git a/contrib/gdb/gdb/i386obsd-nat.c b/contrib/gdb/gdb/i386obsd-nat.c new file mode 100644 index 00000000000..68cc79044ec --- /dev/null +++ b/contrib/gdb/gdb/i386obsd-nat.c @@ -0,0 +1,60 @@ +/* Native-dependent code for OpenBSD/i386. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include +#include + +#include "i386-tdep.h" + +/* Prevent warning from -Wmissing-prototypes. */ +void _initialize_i386obsd_nat (void); + +void +_initialize_i386obsd_nat (void) +{ + /* OpenBSD provides a vm.psstrings sysctl that we can use to locate + the sigtramp. That way we can still recognize a sigtramp if its + location is changed in a new kernel. This is especially + important for OpenBSD, since it uses a different memory layout + than NetBSD, yet we cannot distinguish between the two. + + Of course this is still based on the assumption that the sigtramp + is placed directly under the location where the program arguments + and environment can be found. */ +#ifdef VM_PSSTRINGS + { + struct _ps_strings _ps; + int mib[2]; + size_t len; + + mib[0] = CTL_VM; + mib[1] = VM_PSSTRINGS; + len = sizeof (_ps); + if (sysctl (mib, 2, &_ps, &len, NULL, 0) == 0) + { + i386obsd_sigtramp_start_addr = (CORE_ADDR)_ps.val - 128; + i386obsd_sigtramp_end_addr = (CORE_ADDR)_ps.val; + } + } +#endif +} diff --git a/contrib/gdb/gdb/i386obsd-tdep.c b/contrib/gdb/gdb/i386obsd-tdep.c new file mode 100644 index 00000000000..d8556ea460a --- /dev/null +++ b/contrib/gdb/gdb/i386obsd-tdep.c @@ -0,0 +1,277 @@ +/* Target-dependent code for OpenBSD/i386. + + Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002, + 2003, 2004 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "gdbcore.h" +#include "regcache.h" +#include "regset.h" +#include "osabi.h" +#include "target.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "i386-tdep.h" +#include "i387-tdep.h" +#include "solib-svr4.h" + +/* Support for signal handlers. */ + +/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page + in virtual memory. The randomness makes it somewhat tricky to + detect it, but fortunately we can rely on the fact that the start + of the sigtramp routine is page-aligned. By the way, the mapping + is read-only, so you cannot place a breakpoint in the signal + trampoline. */ + +/* Default page size. */ +static const int i386obsd_page_size = 4096; + +/* Return whether PC is in an OpenBSD sigtramp routine. */ + +static int +i386obsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1)); + const char sigreturn[] = + { + 0xb8, + 0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */ + 0xcd, 0x80 /* int $0x80 */ + }; + char *buf; + + /* Avoid reading memory from the target if possible. If we're in a + named function, we're certainly not in a sigtramp routine + provided by the kernel. Take synthetic function names into + account though. */ + if (name && name[0] != '<') + return 0; + + /* If we can't read the instructions at START_PC, return zero. */ + buf = alloca (sizeof sigreturn); + if (target_read_memory (start_pc + 0x14, buf, sizeof sigreturn)) + return 0; + + /* Check for sigreturn(2). */ + if (memcmp (buf, sigreturn, sizeof sigreturn) == 0) + return 1; + + /* Check for a traditional BSD sigtramp routine. */ + return i386bsd_pc_in_sigtramp (pc, name); +} + +/* Return the start address of the sigtramp routine. */ + +static CORE_ADDR +i386obsd_sigtramp_start (CORE_ADDR pc) +{ + CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1)); + + if (i386bsd_pc_in_sigtramp (pc, NULL)) + return i386bsd_sigtramp_start (pc); + + return start_pc; +} + +/* Return the end address of the sigtramp routine. */ + +static CORE_ADDR +i386obsd_sigtramp_end (CORE_ADDR pc) +{ + CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1)); + + if (i386bsd_pc_in_sigtramp (pc, NULL)) + return i386bsd_sigtramp_end (pc); + + return start_pc + 0x22; +} + +/* Mapping between the general-purpose registers in `struct reg' + format and GDB's register cache layout. */ + +/* From . */ +static int i386obsd_r_reg_offset[] = +{ + 0 * 4, /* %eax */ + 1 * 4, /* %ecx */ + 2 * 4, /* %edx */ + 3 * 4, /* %ebx */ + 4 * 4, /* %esp */ + 5 * 4, /* %ebp */ + 6 * 4, /* %esi */ + 7 * 4, /* %edi */ + 8 * 4, /* %eip */ + 9 * 4, /* %eflags */ + 10 * 4, /* %cs */ + 11 * 4, /* %ss */ + 12 * 4, /* %ds */ + 13 * 4, /* %es */ + 14 * 4, /* %fs */ + 15 * 4 /* %gs */ +}; + +static void +i386obsd_aout_supply_regset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *regs, size_t len) +{ + const struct gdbarch_tdep *tdep = regset->descr; + + gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE); + + i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset); + i387_supply_fsave (regcache, regnum, (char *) regs + tdep->sizeof_gregset); +} + +static const struct regset * +i386obsd_aout_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, + size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* OpenBSD a.out core dumps don't use seperate register sets for the + general-purpose and floating-point registers. */ + + if (strcmp (sect_name, ".reg") == 0 + && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE) + { + if (tdep->gregset == NULL) + { + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = tdep; + tdep->gregset->supply_regset = i386obsd_aout_supply_regset; + } + return tdep->gregset; + } + + return NULL; +} + + +/* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */ +CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20; +CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0; + +/* From . */ +int i386obsd_sc_reg_offset[I386_NUM_GREGS] = +{ + 10 * 4, /* %eax */ + 9 * 4, /* %ecx */ + 8 * 4, /* %edx */ + 7 * 4, /* %ebx */ + 14 * 4, /* %esp */ + 6 * 4, /* %ebp */ + 5 * 4, /* %esi */ + 4 * 4, /* %edi */ + 11 * 4, /* %eip */ + 13 * 4, /* %eflags */ + 12 * 4, /* %cs */ + 15 * 4, /* %ss */ + 3 * 4, /* %ds */ + 2 * 4, /* %es */ + 1 * 4, /* %fs */ + 0 * 4 /* %gs */ +}; + +static void +i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Obviously OpenBSD is BSD-based. */ + i386bsd_init_abi (info, gdbarch); + + /* OpenBSD has a different `struct reg'. */ + tdep->gregset_reg_offset = i386obsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset); + tdep->sizeof_gregset = 16 * 4; + + /* OpenBSD uses -freg-struct-return by default. */ + tdep->struct_return = reg_struct_return; + + /* OpenBSD uses a different memory layout. */ + tdep->sigtramp_start = i386obsd_sigtramp_start_addr; + tdep->sigtramp_end = i386obsd_sigtramp_end_addr; + set_gdbarch_pc_in_sigtramp (gdbarch, i386obsd_pc_in_sigtramp); + set_gdbarch_sigtramp_start (gdbarch, i386obsd_sigtramp_start); + set_gdbarch_sigtramp_end (gdbarch, i386obsd_sigtramp_end); + + /* OpenBSD has a `struct sigcontext' that's different from the + origional 4.3 BSD. */ + tdep->sc_reg_offset = i386obsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset); +} + +/* OpenBSD a.out. */ + +static void +i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + i386obsd_init_abi (info, gdbarch); + + /* OpenBSD a.out has a single register set. */ + set_gdbarch_regset_from_core_section + (gdbarch, i386obsd_aout_regset_from_core_section); +} + +/* OpenBSD ELF. */ + +static void +i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* It's still OpenBSD. */ + i386obsd_init_abi (info, gdbarch); + + /* But ELF-based. */ + i386_elf_init_abi (info, gdbarch); + + /* OpenBSD ELF uses SVR4-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline + (gdbarch, generic_in_solib_call_trampoline); + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_ilp32_fetch_link_map_offsets); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386obsd_tdep (void); + +void +_initialize_i386obsd_tdep (void) +{ + /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are + indistingushable from NetBSD/i386 a.out binaries, building a GDB + that should support both these targets will probably not work as + expected. */ +#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT + + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT, + i386obsd_aout_init_abi); + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF, + i386obsd_elf_init_abi); +} diff --git a/contrib/gdb/gdb/i386v-nat.c b/contrib/gdb/gdb/i386v-nat.c new file mode 100644 index 00000000000..678eabc346d --- /dev/null +++ b/contrib/gdb/gdb/i386v-nat.c @@ -0,0 +1,277 @@ +/* Intel 386 native support for System V systems (pre-SVR4). + + Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, + 1999, 2000, 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#ifdef HAVE_PTRACE_H +#include +#else +#ifdef HAVE_SYS_PTRACE_H +#include +#endif +#endif + +#include "frame.h" +#include "inferior.h" +#include "language.h" +#include "gdbcore.h" + +#ifdef USG +#include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS +#include +#endif + +#include +#include "gdb_stat.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#include "floatformat.h" + +#include "target.h" + +#include "i386-tdep.h" + + +/* Mapping between the general-purpose registers in `struct user' + format and GDB's register array layout. */ +static int regmap[] = +{ + EAX, ECX, EDX, EBX, + UESP, EBP, ESI, EDI, + EIP, EFL, CS, SS, + DS, ES, FS, GS, +}; + +/* Support for the user struct. */ + +/* Return the address of register REGNUM. BLOCKEND is the value of + u.u_ar0, and points to the place where GS is stored. */ + +CORE_ADDR +register_u_addr (CORE_ADDR blockend, int regnum) +{ + struct user u; + CORE_ADDR fpstate; + + if (i386_fp_regnum_p (regnum)) + { +#ifdef KSTKSZ /* SCO, and others? */ + blockend += 4 * (SS + 1) - KSTKSZ; + fpstate = blockend + ((char *) &u.u_fps.u_fpstate - (char *) &u); + return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM)); +#else + fpstate = blockend + ((char *) &u.i387.st_space - (char *) &u); + return (fpstate + 10 * (regnum - FP0_REGNUM)); +#endif + } + + return (blockend + 4 * regmap[regnum]); +} + +/* Return the size of the user struct. */ + +int +kernel_u_size (void) +{ + return (sizeof (struct user)); +} + +#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS + +#if !defined (offsetof) +#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) +#endif + +/* Record the value of the debug control register. */ +static int debug_control_mirror; + +/* Record which address associates with which register. */ +static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1]; + +static int i386_insert_aligned_watchpoint (int, CORE_ADDR, CORE_ADDR, int, + int); + +static int i386_insert_nonaligned_watchpoint (int, CORE_ADDR, CORE_ADDR, int, + int); + +/* Insert a watchpoint. */ + +int +i386_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw) +{ + return i386_insert_aligned_watchpoint (pid, addr, addr, len, rw); +} + +static int +i386_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, + int len, int rw) +{ + int i; + int read_write_bits, len_bits; + int free_debug_register; + int register_number; + + /* Look for a free debug register. */ + for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) + { + if (address_lookup[i - DR_FIRSTADDR] == 0) + break; + } + + /* No more debug registers! */ + if (i > DR_LASTADDR) + return -1; + + read_write_bits = (rw & 1) ? DR_RW_READ : DR_RW_WRITE; + + if (len == 1) + len_bits = DR_LEN_1; + else if (len == 2) + { + if (addr % 2) + return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); + len_bits = DR_LEN_2; + } + + else if (len == 4) + { + if (addr % 4) + return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); + len_bits = DR_LEN_4; + } + else + return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); + + free_debug_register = i; + register_number = free_debug_register - DR_FIRSTADDR; + debug_control_mirror |= + ((read_write_bits | len_bits) + << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * register_number)); + debug_control_mirror |= + (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * register_number)); + debug_control_mirror |= DR_LOCAL_SLOWDOWN; + debug_control_mirror &= ~DR_CONTROL_RESERVED; + + ptrace (6, pid, offsetof (struct user, u_debugreg[DR_CONTROL]), + debug_control_mirror); + ptrace (6, pid, offsetof (struct user, u_debugreg[free_debug_register]), + addr); + + /* Record where we came from. */ + address_lookup[register_number] = addr; + return 0; +} + +static int +i386_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, + int len, int rw) +{ + int align; + int size; + int rv; + + static int size_try_array[4][4] = + { + { 1, 1, 1, 1 }, /* trying size one */ + { 2, 1, 2, 1 }, /* trying size two */ + { 2, 1, 2, 1 }, /* trying size three */ + { 4, 1, 2, 1 } /* trying size four */ + }; + + rv = 0; + while (len > 0) + { + align = addr % 4; + /* Four is the maximum length for 386. */ + size = size_try_array[len > 4 ? 3 : len - 1][align]; + + rv = i386_insert_aligned_watchpoint (pid, waddr, addr, size, rw); + if (rv) + { + i386_remove_watchpoint (pid, waddr, size); + return rv; + } + addr += size; + len -= size; + } + return rv; +} + +/* Remove a watchpoint. */ + +int +i386_remove_watchpoint (int pid, CORE_ADDR addr, int len) +{ + int i; + int register_number; + + for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) + { + register_number = i - DR_FIRSTADDR; + if (address_lookup[register_number] == addr) + { + debug_control_mirror &= + ~(1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * register_number)); + address_lookup[register_number] = 0; + } + } + ptrace (6, pid, offsetof (struct user, u_debugreg[DR_CONTROL]), + debug_control_mirror); + ptrace (6, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0); + + return 0; +} + +/* Check if stopped by a watchpoint. */ + +CORE_ADDR +i386_stopped_by_watchpoint (int pid) +{ + int i; + int status; + + status = ptrace (3, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0); + ptrace (6, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0); + + for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) + { + if (status & (1 << (i - DR_FIRSTADDR))) + return address_lookup[i - DR_FIRSTADDR]; + } + + return 0; +} + +#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */ diff --git a/contrib/gdb/gdb/i386v4-nat.c b/contrib/gdb/gdb/i386v4-nat.c new file mode 100644 index 00000000000..188f01b4c12 --- /dev/null +++ b/contrib/gdb/gdb/i386v4-nat.c @@ -0,0 +1,160 @@ +/* Native-dependent code for SVR4 Unix running on i386's. + Copyright 1988, 1989, 1991, 1992, 1996, 1997, 1998, 1999, 2000, + 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "value.h" +#include "inferior.h" +#include "regcache.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#include "i386-tdep.h" +#include "i387-tdep.h" + +#ifdef HAVE_SYS_PROCFS_H + +#include + +/* Prototypes for supply_gregset etc. */ +#include "gregset.h" + +/* The `/proc' interface divides the target machine's register set up + into two different sets, the general purpose register set (gregset) + and the floating-point register set (fpregset). For each set, + there is an ioctl to get the current register set and another ioctl + to set the current values. + + The actual structure passed through the ioctl interface is, of + course, naturally machine dependent, and is different for each set + of registers. For the i386 for example, the general-purpose + register set is typically defined by: + + typedef int gregset_t[19]; (in ) + + #define GS 0 (in ) + #define FS 1 + ... + #define UESP 17 + #define SS 18 + + and the floating-point set by: + + typedef struct fpregset { + union { + struct fpchip_state // fp extension state // + { + int state[27]; // 287/387 saved state // + int status; // status word saved at // + // exception // + } fpchip_state; + struct fp_emul_space // for emulators // + { + char fp_emul[246]; + char fp_epad[2]; + } fp_emul_space; + int f_fpregs[62]; // union of the above // + } fp_reg_set; + long f_wregs[33]; // saved weitek state // + } fpregset_t; + + Incidentally fpchip_state contains the FPU state in the same format + as used by the "fsave" instruction, and that's the only thing we + support here. I don't know how the emulator stores it state. The + Weitek stuff definitely isn't supported. + + The routines defined here, provide the packing and unpacking of + gregset_t and fpregset_t formatted data. */ + +#ifdef HAVE_GREGSET_T + +/* Mapping between the general-purpose registers in `/proc' + format and GDB's register array layout. */ +static int regmap[] = +{ + EAX, ECX, EDX, EBX, + UESP, EBP, ESI, EDI, + EIP, EFL, CS, SS, + DS, ES, FS, GS, +}; + +/* Fill GDB's register array with the general-purpose register values + in *GREGSETP. */ + +void +supply_gregset (gregset_t *gregsetp) +{ + greg_t *regp = (greg_t *) gregsetp; + int i; + + for (i = 0; i < I386_NUM_GREGS; i++) + supply_register (i, (char *) (regp + regmap[i])); +} + +/* Fill register REGNO (if it is a general-purpose register) in + *GREGSETPS with the value in GDB's register array. If REGNO is -1, + do this for all registers. */ + +void +fill_gregset (gregset_t *gregsetp, int regno) +{ + greg_t *regp = (greg_t *) gregsetp; + int i; + + for (i = 0; i < I386_NUM_GREGS; i++) + if (regno == -1 || regno == i) + regcache_collect (i, regp + regmap[i]); +} + +#endif /* HAVE_GREGSET_T */ + +#ifdef HAVE_FPREGSET_T + +/* Fill GDB's register array with the floating-point register values in + *FPREGSETP. */ + +void +supply_fpregset (fpregset_t *fpregsetp) +{ + if (FP0_REGNUM == 0) + return; + + i387_supply_fsave (current_regcache, -1, fpregsetp); +} + +/* Fill register REGNO (if it is a floating-point register) in + *FPREGSETP with the value in GDB's register array. If REGNO is -1, + do this for all registers. */ + +void +fill_fpregset (fpregset_t *fpregsetp, int regno) +{ + if (FP0_REGNUM == 0) + return; + + i387_fill_fsave ((char *) fpregsetp, regno); +} + +#endif /* HAVE_FPREGSET_T */ + +#endif /* HAVE_SYS_PROCFS_H */ diff --git a/contrib/gdb/gdb/i387-tdep.c b/contrib/gdb/gdb/i387-tdep.c index 2a6f77ce42d..21386fb13f0 100644 --- a/contrib/gdb/gdb/i387-tdep.c +++ b/contrib/gdb/gdb/i387-tdep.c @@ -1,6 +1,7 @@ /* Intel 387 floating point stuff. - Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -20,147 +21,28 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "doublest.h" +#include "floatformat.h" #include "frame.h" +#include "gdbcore.h" #include "inferior.h" #include "language.h" -#include "value.h" -#include "gdbcore.h" -#include "floatformat.h" #include "regcache.h" +#include "value.h" + #include "gdb_assert.h" -#include "doublest.h" +#include "gdb_string.h" #include "i386-tdep.h" +#include "i387-tdep.h" -/* FIXME: Eliminate the next two functions when we have the time to - change all the callers. */ - -void i387_to_double (char *from, char *to); -void double_to_i387 (char *from, char *to); - -void -i387_to_double (char *from, char *to) -{ - floatformat_to_double (&floatformat_i387_ext, from, (double *) to); -} - -void -double_to_i387 (char *from, char *to) -{ - floatformat_from_double (&floatformat_i387_ext, (double *) from, to); -} - - -/* FIXME: The functions on this page are used by the old `info float' - implementations that a few of the i386 targets provide. These - functions should be removed if all of these have been converted to - use the generic implementation based on the new register file - layout. */ - -static void print_387_control_bits (unsigned int control); -static void print_387_status_bits (unsigned int status); - -static void -print_387_control_bits (unsigned int control) -{ - switch ((control >> 8) & 3) - { - case 0: - puts_unfiltered (" 24 bit; "); - break; - case 1: - puts_unfiltered (" (bad); "); - break; - case 2: - puts_unfiltered (" 53 bit; "); - break; - case 3: - puts_unfiltered (" 64 bit; "); - break; - } - switch ((control >> 10) & 3) - { - case 0: - puts_unfiltered ("NEAR; "); - break; - case 1: - puts_unfiltered ("DOWN; "); - break; - case 2: - puts_unfiltered ("UP; "); - break; - case 3: - puts_unfiltered ("CHOP; "); - break; - } - if (control & 0x3f) - { - puts_unfiltered ("mask"); - if (control & 0x0001) - puts_unfiltered (" INVAL"); - if (control & 0x0002) - puts_unfiltered (" DENOR"); - if (control & 0x0004) - puts_unfiltered (" DIVZ"); - if (control & 0x0008) - puts_unfiltered (" OVERF"); - if (control & 0x0010) - puts_unfiltered (" UNDER"); - if (control & 0x0020) - puts_unfiltered (" LOS"); - puts_unfiltered (";"); - } - - if (control & 0xe080) - warning ("\nreserved bits on: %s", - local_hex_string (control & 0xe080)); -} - -void -print_387_control_word (unsigned int control) -{ - printf_filtered ("control %s:", local_hex_string(control & 0xffff)); - print_387_control_bits (control); - puts_unfiltered ("\n"); -} - -static void -print_387_status_bits (unsigned int status) -{ - printf_unfiltered (" flags %d%d%d%d; ", - (status & 0x4000) != 0, - (status & 0x0400) != 0, - (status & 0x0200) != 0, - (status & 0x0100) != 0); - printf_unfiltered ("top %d; ", (status >> 11) & 7); - if (status & 0xff) - { - puts_unfiltered ("excep"); - if (status & 0x0001) puts_unfiltered (" INVAL"); - if (status & 0x0002) puts_unfiltered (" DENOR"); - if (status & 0x0004) puts_unfiltered (" DIVZ"); - if (status & 0x0008) puts_unfiltered (" OVERF"); - if (status & 0x0010) puts_unfiltered (" UNDER"); - if (status & 0x0020) puts_unfiltered (" LOS"); - if (status & 0x0040) puts_unfiltered (" STACK"); - } -} - -void -print_387_status_word (unsigned int status) -{ - printf_filtered ("status %s:", local_hex_string (status & 0xffff)); - print_387_status_bits (status); - puts_unfiltered ("\n"); -} - - /* Implement the `info float' layout based on the register definitions in `tm-i386.h'. */ /* Print the floating point number specified by RAW. */ + static void -print_i387_value (char *raw) +print_i387_value (char *raw, struct ui_file *file) { DOUBLEST value; @@ -175,15 +57,16 @@ print_i387_value (char *raw) to print the value, 1 position for the sign, 1 for the decimal point, 19 for the digits and 6 for the exponent adds up to 27. */ #ifdef PRINTF_HAS_LONG_DOUBLE - printf_filtered (" %-+27.19Lg", (long double) value); + fprintf_filtered (file, " %-+27.19Lg", (long double) value); #else - printf_filtered (" %-+27.19g", (double) value); + fprintf_filtered (file, " %-+27.19g", (double) value); #endif } /* Print the classification for the register contents RAW. */ + static void -print_i387_ext (unsigned char *raw) +print_i387_ext (unsigned char *raw, struct ui_file *file) { int sign; int integer; @@ -201,190 +84,691 @@ print_i387_ext (unsigned char *raw) { if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000) /* Infinity. */ - printf_filtered (" %cInf", (sign ? '-' : '+')); + fprintf_filtered (file, " %cInf", (sign ? '-' : '+')); else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000) /* Real Indefinite (QNaN). */ - puts_unfiltered (" Real Indefinite (QNaN)"); + fputs_unfiltered (" Real Indefinite (QNaN)", file); else if (fraction[1] & 0x40000000) /* QNaN. */ - puts_filtered (" QNaN"); + fputs_filtered (" QNaN", file); else /* SNaN. */ - puts_filtered (" SNaN"); + fputs_filtered (" SNaN", file); } else if (exponent < 0x7fff && exponent > 0x0000 && integer) /* Normal. */ - print_i387_value (raw); + print_i387_value (raw, file); else if (exponent == 0x0000) { /* Denormal or zero. */ - print_i387_value (raw); + print_i387_value (raw, file); if (integer) /* Pseudo-denormal. */ - puts_filtered (" Pseudo-denormal"); + fputs_filtered (" Pseudo-denormal", file); else if (fraction[0] || fraction[1]) /* Denormal. */ - puts_filtered (" Denormal"); + fputs_filtered (" Denormal", file); } else /* Unsupported. */ - puts_filtered (" Unsupported"); + fputs_filtered (" Unsupported", file); } /* Print the status word STATUS. */ + static void -print_i387_status_word (unsigned int status) +print_i387_status_word (unsigned int status, struct ui_file *file) { - printf_filtered ("Status Word: %s", + fprintf_filtered (file, "Status Word: %s", local_hex_string_custom (status, "04")); - puts_filtered (" "); - printf_filtered (" %s", (status & 0x0001) ? "IE" : " "); - printf_filtered (" %s", (status & 0x0002) ? "DE" : " "); - printf_filtered (" %s", (status & 0x0004) ? "ZE" : " "); - printf_filtered (" %s", (status & 0x0008) ? "OE" : " "); - printf_filtered (" %s", (status & 0x0010) ? "UE" : " "); - printf_filtered (" %s", (status & 0x0020) ? "PE" : " "); - puts_filtered (" "); - printf_filtered (" %s", (status & 0x0080) ? "ES" : " "); - puts_filtered (" "); - printf_filtered (" %s", (status & 0x0040) ? "SF" : " "); - puts_filtered (" "); - printf_filtered (" %s", (status & 0x0100) ? "C0" : " "); - printf_filtered (" %s", (status & 0x0200) ? "C1" : " "); - printf_filtered (" %s", (status & 0x0400) ? "C2" : " "); - printf_filtered (" %s", (status & 0x4000) ? "C3" : " "); + fputs_filtered (" ", file); + fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " "); + fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " "); + fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " "); + fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " "); + fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " "); + fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " "); + fputs_filtered (" ", file); + fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " "); + fputs_filtered (" ", file); + fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " "); + fputs_filtered (" ", file); + fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " "); + fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " "); + fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " "); + fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " "); - puts_filtered ("\n"); + fputs_filtered ("\n", file); - printf_filtered (" TOP: %d\n", ((status >> 11) & 7)); + fprintf_filtered (file, + " TOP: %d\n", ((status >> 11) & 7)); } /* Print the control word CONTROL. */ + static void -print_i387_control_word (unsigned int control) +print_i387_control_word (unsigned int control, struct ui_file *file) { - printf_filtered ("Control Word: %s", + fprintf_filtered (file, "Control Word: %s", local_hex_string_custom (control, "04")); - puts_filtered (" "); - printf_filtered (" %s", (control & 0x0001) ? "IM" : " "); - printf_filtered (" %s", (control & 0x0002) ? "DM" : " "); - printf_filtered (" %s", (control & 0x0004) ? "ZM" : " "); - printf_filtered (" %s", (control & 0x0008) ? "OM" : " "); - printf_filtered (" %s", (control & 0x0010) ? "UM" : " "); - printf_filtered (" %s", (control & 0x0020) ? "PM" : " "); + fputs_filtered (" ", file); + fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " "); + fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " "); + fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " "); + fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " "); + fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " "); + fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " "); - puts_filtered ("\n"); + fputs_filtered ("\n", file); - puts_filtered (" PC: "); + fputs_filtered (" PC: ", file); switch ((control >> 8) & 3) { case 0: - puts_filtered ("Single Precision (24-bits)\n"); + fputs_filtered ("Single Precision (24-bits)\n", file); break; case 1: - puts_filtered ("Reserved\n"); + fputs_filtered ("Reserved\n", file); break; case 2: - puts_filtered ("Double Precision (53-bits)\n"); + fputs_filtered ("Double Precision (53-bits)\n", file); break; case 3: - puts_filtered ("Extended Precision (64-bits)\n"); + fputs_filtered ("Extended Precision (64-bits)\n", file); break; } - puts_filtered (" RC: "); + fputs_filtered (" RC: ", file); switch ((control >> 10) & 3) { case 0: - puts_filtered ("Round to nearest\n"); + fputs_filtered ("Round to nearest\n", file); break; case 1: - puts_filtered ("Round down\n"); + fputs_filtered ("Round down\n", file); break; case 2: - puts_filtered ("Round up\n"); + fputs_filtered ("Round up\n", file); break; case 3: - puts_filtered ("Round toward zero\n"); + fputs_filtered ("Round toward zero\n", file); break; } } -/* Print out the i387 floating poin state. */ +/* Print out the i387 floating point state. Note that we ignore FRAME + in the code below. That's OK since floating-point registers are + never saved on the stack. */ + void -i387_float_info (void) +i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) { - unsigned int fctrl; - unsigned int fstat; - unsigned int ftag; - unsigned int fiseg; - unsigned int fioff; - unsigned int foseg; - unsigned int fooff; - unsigned int fop; + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); + char buf[4]; + ULONGEST fctrl; + ULONGEST fstat; + ULONGEST ftag; + ULONGEST fiseg; + ULONGEST fioff; + ULONGEST foseg; + ULONGEST fooff; + ULONGEST fop; int fpreg; int top; - fctrl = read_register (FCTRL_REGNUM); - fstat = read_register (FSTAT_REGNUM); - ftag = read_register (FTAG_REGNUM); - fiseg = read_register (FCS_REGNUM); - fioff = read_register (FCOFF_REGNUM); - foseg = read_register (FDS_REGNUM); - fooff = read_register (FDOFF_REGNUM); - fop = read_register (FOP_REGNUM); - + gdb_assert (gdbarch == get_frame_arch (frame)); + + /* Define I387_ST0_REGNUM such that we use the proper definitions + for FRAME's architecture. */ +#define I387_ST0_REGNUM tdep->st0_regnum + + fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM); + fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM); + ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM); + fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM); + fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM); + foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM); + fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM); + fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM); + top = ((fstat >> 11) & 7); for (fpreg = 7; fpreg >= 0; fpreg--) { - unsigned char raw[FPU_REG_RAW_SIZE]; + unsigned char raw[I386_MAX_REGISTER_SIZE]; int tag = (ftag >> (fpreg * 2)) & 3; int i; - printf_filtered ("%sR%d: ", fpreg == top ? "=>" : " ", fpreg); + fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg); switch (tag) { case 0: - puts_filtered ("Valid "); + fputs_filtered ("Valid ", file); break; case 1: - puts_filtered ("Zero "); + fputs_filtered ("Zero ", file); break; case 2: - puts_filtered ("Special "); + fputs_filtered ("Special ", file); break; case 3: - puts_filtered ("Empty "); + fputs_filtered ("Empty ", file); break; } - read_register_gen ((fpreg + 8 - top) % 8 + FP0_REGNUM, raw); + get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM, raw); - puts_filtered ("0x"); + fputs_filtered ("0x", file); for (i = 9; i >= 0; i--) - printf_filtered ("%02x", raw[i]); + fprintf_filtered (file, "%02x", raw[i]); if (tag != 3) - print_i387_ext (raw); + print_i387_ext (raw, file); - puts_filtered ("\n"); + fputs_filtered ("\n", file); } - puts_filtered ("\n"); + fputs_filtered ("\n", file); - print_i387_status_word (fstat); - print_i387_control_word (fctrl); - printf_filtered ("Tag Word: %s\n", - local_hex_string_custom (ftag, "04")); - printf_filtered ("Instruction Pointer: %s:", - local_hex_string_custom (fiseg, "02")); - printf_filtered ("%s\n", local_hex_string_custom (fioff, "08")); - printf_filtered ("Operand Pointer: %s:", - local_hex_string_custom (foseg, "02")); - printf_filtered ("%s\n", local_hex_string_custom (fooff, "08")); - printf_filtered ("Opcode: %s\n", - local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04")); + print_i387_status_word (fstat, file); + print_i387_control_word (fctrl, file); + fprintf_filtered (file, "Tag Word: %s\n", + local_hex_string_custom (ftag, "04")); + fprintf_filtered (file, "Instruction Pointer: %s:", + local_hex_string_custom (fiseg, "02")); + fprintf_filtered (file, "%s\n", local_hex_string_custom (fioff, "08")); + fprintf_filtered (file, "Operand Pointer: %s:", + local_hex_string_custom (foseg, "02")); + fprintf_filtered (file, "%s\n", local_hex_string_custom (fooff, "08")); + fprintf_filtered (file, "Opcode: %s\n", + local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04")); + +#undef I387_ST0_REGNUM +} + + +/* Read a value of type TYPE from register REGNUM in frame FRAME, and + return its contents in TO. */ + +void +i387_register_to_value (struct frame_info *frame, int regnum, + struct type *type, void *to) +{ + char from[I386_MAX_REGISTER_SIZE]; + + gdb_assert (i386_fp_regnum_p (regnum)); + + /* We only support floating-point values. */ + if (TYPE_CODE (type) != TYPE_CODE_FLT) + { + warning ("Cannot convert floating-point register value " + "to non-floating-point type."); + return; + } + + /* Convert to TYPE. This should be a no-op if TYPE is equivalent to + the extended floating-point format used by the FPU. */ + get_frame_register (frame, regnum, from); + convert_typed_floating (from, builtin_type_i387_ext, to, type); +} + +/* Write the contents FROM of a value of type TYPE into register + REGNUM in frame FRAME. */ + +void +i387_value_to_register (struct frame_info *frame, int regnum, + struct type *type, const void *from) +{ + char to[I386_MAX_REGISTER_SIZE]; + + gdb_assert (i386_fp_regnum_p (regnum)); + + /* We only support floating-point values. */ + if (TYPE_CODE (type) != TYPE_CODE_FLT) + { + warning ("Cannot convert non-floating-point type " + "to floating-point register value."); + return; + } + + /* Convert from TYPE. This should be a no-op if TYPE is equivalent + to the extended floating-point format used by the FPU. */ + convert_typed_floating (from, type, to, builtin_type_i387_ext); + put_frame_register (frame, regnum, to); +} + + + +/* Handle FSAVE and FXSAVE formats. */ + +/* FIXME: kettenis/20030927: The functions below should accept a + `regcache' argument, but I don't want to change the function + signature just yet. There's some band-aid in the functions below + in the form of the `regcache' local variables. This will ease the + transition later on. */ + +/* At fsave_offset[REGNUM] you'll find the offset to the location in + the data structure used by the "fsave" instruction where GDB + register REGNUM is stored. */ + +static int fsave_offset[] = +{ + 28 + 0 * 10, /* %st(0) ... */ + 28 + 1 * 10, + 28 + 2 * 10, + 28 + 3 * 10, + 28 + 4 * 10, + 28 + 5 * 10, + 28 + 6 * 10, + 28 + 7 * 10, /* ... %st(7). */ + 0, /* `fctrl' (16 bits). */ + 4, /* `fstat' (16 bits). */ + 8, /* `ftag' (16 bits). */ + 16, /* `fiseg' (16 bits). */ + 12, /* `fioff'. */ + 24, /* `foseg' (16 bits). */ + 20, /* `fooff'. */ + 18 /* `fop' (bottom 11 bits). */ +}; + +#define FSAVE_ADDR(fsave, regnum) \ + (fsave + fsave_offset[regnum - I387_ST0_REGNUM]) + + +/* Fill register REGNUM in REGCACHE with the appropriate value from + *FSAVE. This function masks off any of the reserved bits in + *FSAVE. */ + +void +i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); + const char *regs = fsave; + int i; + + gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); + + /* Define I387_ST0_REGNUM such that we use the proper definitions + for REGCACHE's architecture. */ +#define I387_ST0_REGNUM tdep->st0_regnum + + for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++) + if (regnum == -1 || regnum == i) + { + if (fsave == NULL) + { + regcache_raw_supply (regcache, i, NULL); + continue; + } + + /* Most of the FPU control registers occupy only 16 bits in the + fsave area. Give those a special treatment. */ + if (i >= I387_FCTRL_REGNUM + && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) + { + unsigned char val[4]; + + memcpy (val, FSAVE_ADDR (regs, i), 2); + val[2] = val[3] = 0; + if (i == I387_FOP_REGNUM) + val[1] &= ((1 << 3) - 1); + regcache_raw_supply (regcache, i, val); + } + else + regcache_raw_supply (regcache, i, FSAVE_ADDR (regs, i)); + } +#undef I387_ST0_REGNUM +} + +/* Fill register REGNUM (if it is a floating-point register) in *FSAVE + with the value in GDB's register cache. If REGNUM is -1, do this + for all registers. This function doesn't touch any of the reserved + bits in *FSAVE. */ + +void +i387_fill_fsave (void *fsave, int regnum) +{ + struct regcache *regcache = current_regcache; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + char *regs = fsave; + int i; + + gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); + + /* Define I387_ST0_REGNUM such that we use the proper definitions + for REGCACHE's architecture. */ +#define I387_ST0_REGNUM tdep->st0_regnum + + for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++) + if (regnum == -1 || regnum == i) + { + /* Most of the FPU control registers occupy only 16 bits in + the fsave area. Give those a special treatment. */ + if (i >= I387_FCTRL_REGNUM + && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) + { + unsigned char buf[4]; + + regcache_raw_collect (regcache, i, buf); + + if (i == I387_FOP_REGNUM) + { + /* The opcode occupies only 11 bits. Make sure we + don't touch the other bits. */ + buf[1] &= ((1 << 3) - 1); + buf[1] |= ((FSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1)); + } + memcpy (FSAVE_ADDR (regs, i), buf, 2); + } + else + regcache_raw_collect (regcache, i, FSAVE_ADDR (regs, i)); + } +#undef I387_ST0_REGNUM +} + + +/* At fxsave_offset[REGNUM] you'll find the offset to the location in + the data structure used by the "fxsave" instruction where GDB + register REGNUM is stored. */ + +static int fxsave_offset[] = +{ + 32, /* %st(0) through ... */ + 48, + 64, + 80, + 96, + 112, + 128, + 144, /* ... %st(7) (80 bits each). */ + 0, /* `fctrl' (16 bits). */ + 2, /* `fstat' (16 bits). */ + 4, /* `ftag' (16 bits). */ + 12, /* `fiseg' (16 bits). */ + 8, /* `fioff'. */ + 20, /* `foseg' (16 bits). */ + 16, /* `fooff'. */ + 6, /* `fop' (bottom 11 bits). */ + 160 + 0 * 16, /* %xmm0 through ... */ + 160 + 1 * 16, + 160 + 2 * 16, + 160 + 3 * 16, + 160 + 4 * 16, + 160 + 5 * 16, + 160 + 6 * 16, + 160 + 7 * 16, + 160 + 8 * 16, + 160 + 9 * 16, + 160 + 10 * 16, + 160 + 11 * 16, + 160 + 12 * 16, + 160 + 13 * 16, + 160 + 14 * 16, + 160 + 15 * 16, /* ... %xmm15 (128 bits each). */ +}; + +#define FXSAVE_ADDR(fxsave, regnum) \ + (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM]) + +/* We made an unfortunate choice in putting %mxcsr after the SSE + registers %xmm0-%xmm7 instead of before, since it makes supporting + the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we + don't include the offset for %mxcsr here above. */ + +#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24) + +static int i387_tag (const unsigned char *raw); + + +/* Fill register REGNUM in REGCACHE with the appropriate + floating-point or SSE register value from *FXSAVE. This function + masks off any of the reserved bits in *FXSAVE. */ + +void +i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); + const char *regs = fxsave; + int i; + + gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); + gdb_assert (tdep->num_xmm_regs > 0); + + /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the + proper definitions for REGCACHE's architecture. */ + +#define I387_ST0_REGNUM tdep->st0_regnum +#define I387_NUM_XMM_REGS tdep->num_xmm_regs + + for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++) + if (regnum == -1 || regnum == i) + { + if (regs == NULL) + { + regcache_raw_supply (regcache, i, NULL); + continue; + } + + /* Most of the FPU control registers occupy only 16 bits in + the fxsave area. Give those a special treatment. */ + if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM + && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) + { + unsigned char val[4]; + + memcpy (val, FXSAVE_ADDR (regs, i), 2); + val[2] = val[3] = 0; + if (i == I387_FOP_REGNUM) + val[1] &= ((1 << 3) - 1); + else if (i== I387_FTAG_REGNUM) + { + /* The fxsave area contains a simplified version of + the tag word. We have to look at the actual 80-bit + FP data to recreate the traditional i387 tag word. */ + + unsigned long ftag = 0; + int fpreg; + int top; + + top = ((FXSAVE_ADDR (regs, I387_FSTAT_REGNUM))[1] >> 3); + top &= 0x7; + + for (fpreg = 7; fpreg >= 0; fpreg--) + { + int tag; + + if (val[0] & (1 << fpreg)) + { + int regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM; + tag = i387_tag (FXSAVE_ADDR (regs, regnum)); + } + else + tag = 3; /* Empty */ + + ftag |= tag << (2 * fpreg); + } + val[0] = ftag & 0xff; + val[1] = (ftag >> 8) & 0xff; + } + regcache_raw_supply (regcache, i, val); + } + else + regcache_raw_supply (regcache, i, FXSAVE_ADDR (regs, i)); + } + + if (regnum == I387_MXCSR_REGNUM || regnum == -1) + { + if (regs == NULL) + regcache_raw_supply (regcache, I387_MXCSR_REGNUM, NULL); + else + regcache_raw_supply (regcache, I387_MXCSR_REGNUM, + FXSAVE_MXCSR_ADDR (regs)); + } + +#undef I387_ST0_REGNUM +#undef I387_NUM_XMM_REGS +} + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for + all registers. This function doesn't touch any of the reserved + bits in *FXSAVE. */ + +void +i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + char *regs = fxsave; + int i; + + gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); + gdb_assert (tdep->num_xmm_regs > 0); + + /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the + proper definitions for REGCACHE's architecture. */ + +#define I387_ST0_REGNUM tdep->st0_regnum +#define I387_NUM_XMM_REGS tdep->num_xmm_regs + + for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++) + if (regnum == -1 || regnum == i) + { + /* Most of the FPU control registers occupy only 16 bits in + the fxsave area. Give those a special treatment. */ + if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM + && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) + { + unsigned char buf[4]; + + regcache_raw_collect (regcache, i, buf); + + if (i == I387_FOP_REGNUM) + { + /* The opcode occupies only 11 bits. Make sure we + don't touch the other bits. */ + buf[1] &= ((1 << 3) - 1); + buf[1] |= ((FXSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1)); + } + else if (i == I387_FTAG_REGNUM) + { + /* Converting back is much easier. */ + + unsigned short ftag; + int fpreg; + + ftag = (buf[1] << 8) | buf[0]; + buf[0] = 0; + buf[1] = 0; + + for (fpreg = 7; fpreg >= 0; fpreg--) + { + int tag = (ftag >> (fpreg * 2)) & 3; + + if (tag != 3) + buf[0] |= (1 << fpreg); + } + } + memcpy (FXSAVE_ADDR (regs, i), buf, 2); + } + else + regcache_raw_collect (regcache, i, FXSAVE_ADDR (regs, i)); + } + + if (regnum == I387_MXCSR_REGNUM || regnum == -1) + regcache_raw_collect (regcache, I387_MXCSR_REGNUM, + FXSAVE_MXCSR_ADDR (regs)); + +#undef I387_ST0_REGNUM +#undef I387_NUM_XMM_REGS +} + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value in GDB's register cache. If REGNUM is -1, do + this for all registers. This function doesn't touch any of the + reserved bits in *FXSAVE. */ + +void +i387_fill_fxsave (void *fxsave, int regnum) +{ + i387_collect_fxsave (current_regcache, regnum, fxsave); +} + +/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in + *RAW. */ + +static int +i387_tag (const unsigned char *raw) +{ + int integer; + unsigned int exponent; + unsigned long fraction[2]; + + integer = raw[7] & 0x80; + exponent = (((raw[9] & 0x7f) << 8) | raw[8]); + fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]); + fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16) + | (raw[5] << 8) | raw[4]); + + if (exponent == 0x7fff) + { + /* Special. */ + return (2); + } + else if (exponent == 0x0000) + { + if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer) + { + /* Zero. */ + return (1); + } + else + { + /* Special. */ + return (2); + } + } + else + { + if (integer) + { + /* Valid. */ + return (0); + } + else + { + /* Special. */ + return (2); + } + } +} + +/* Prepare the FPU stack in REGCACHE for a function return. */ + +void +i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ULONGEST fstat; + + /* Define I387_ST0_REGNUM such that we use the proper + definitions for the architecture. */ +#define I387_ST0_REGNUM tdep->st0_regnum + + /* Set the top of the floating-point register stack to 7. The + actual value doesn't really matter, but 7 is what a normal + function return would end up with if the program started out with + a freshly initialized FPU. */ + regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat); + fstat |= (7 << 11); + regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat); + + /* Mark %st(1) through %st(7) as empty. Since we set the top of the + floating-point register stack to 7, the appropriate value for the + tag word is 0x3fff. */ + regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff); + +#undef I387_ST0_REGNUM } diff --git a/contrib/gdb/gdb/i387-tdep.h b/contrib/gdb/gdb/i387-tdep.h new file mode 100644 index 00000000000..978fdf9937e --- /dev/null +++ b/contrib/gdb/gdb/i387-tdep.h @@ -0,0 +1,118 @@ +/* Target-dependent code for the i387. + + Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef I387_TDEP_H +#define I387_TDEP_H + +struct gdbarch; +struct frame_info; +struct regcache; +struct type; +struct ui_file; + +/* Because the number of general-purpose registers is different for + AMD64, the floating-point registers and SSE registers get shifted. + The following definitions are intended to help writing code that + needs the register numbers of floating-point registers and SSE + registers. In order to use these, one should provide a definition + for I387_ST0_REGNUM, and possibly I387_NUM_XMM_REGS, preferably by + using a local "#define" in the body of the function that uses this. + Please "#undef" them before the end of the function. */ + +#define I387_FCTRL_REGNUM (I387_ST0_REGNUM + 8) +#define I387_FSTAT_REGNUM (I387_FCTRL_REGNUM + 1) +#define I387_FTAG_REGNUM (I387_FCTRL_REGNUM + 2) +#define I387_FISEG_REGNUM (I387_FCTRL_REGNUM + 3) +#define I387_FIOFF_REGNUM (I387_FCTRL_REGNUM + 4) +#define I387_FOSEG_REGNUM (I387_FCTRL_REGNUM + 5) +#define I387_FOOFF_REGNUM (I387_FCTRL_REGNUM + 6) +#define I387_FOP_REGNUM (I387_FCTRL_REGNUM + 7) +#define I387_XMM0_REGNUM (I387_ST0_REGNUM + 16) +#define I387_MXCSR_REGNUM (I387_XMM0_REGNUM + I387_NUM_XMM_REGS) + + +/* Print out the i387 floating point state. */ + +extern void i387_print_float_info (struct gdbarch *gdbarch, + struct ui_file *file, + struct frame_info *frame, + const char *args); + +/* Read a value of type TYPE from register REGNUM in frame FRAME, and + return its contents in TO. */ + +extern void i387_register_to_value (struct frame_info *frame, int regnum, + struct type *type, void *to); + +/* Write the contents FROM of a value of type TYPE into register + REGNUM in frame FRAME. */ + +extern void i387_value_to_register (struct frame_info *frame, int regnum, + struct type *type, const void *from); + + +/* Size of the memory area use by the 'fsave' and 'fxsave' + instructions. */ +#define I387_SIZEOF_FSAVE 108 +#define I387_SIZEOF_FXSAVE 512 + +/* Fill register REGNUM in REGCACHE with the appropriate value from + *FSAVE. This function masks off any of the reserved bits in + *FSAVE. */ + +extern void i387_supply_fsave (struct regcache *regcache, int regnum, + const void *fsave); + +/* Fill register REGNUM (if it is a floating-point register) in *FSAVE + with the value in GDB's register cache. If REGNUM is -1, do this + for all registers. This function doesn't touch any of the reserved + bits in *FSAVE. */ + +extern void i387_fill_fsave (void *fsave, int regnum); + +/* Fill register REGNUM in REGCACHE with the appropriate + floating-point or SSE register value from *FXSAVE. This function + masks off any of the reserved bits in *FXSAVE. */ + +extern void i387_supply_fxsave (struct regcache *regcache, int regnum, + const void *fxsave); + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for + all registers. This function doesn't touch any of the reserved + bits in *FXSAVE. */ + +extern void i387_collect_fxsave (const struct regcache *regcache, int regnum, + void *fxsave); + +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value in GDB's register cache. If REGNUM is -1, do + this for all registers. This function doesn't touch any of the + reserved bits in *FXSAVE. */ + +extern void i387_fill_fxsave (void *fxsave, int regnum); + +/* Prepare the FPU stack in REGCACHE for a function return. */ + +extern void i387_return_value (struct gdbarch *gdbarch, + struct regcache *regcache); + +#endif /* i387-tdep.h */ diff --git a/contrib/gdb/gdb/ia64-tdep.c b/contrib/gdb/gdb/ia64-tdep.c index 7ca7fe71a4d..278538caa8b 100644 --- a/contrib/gdb/gdb/ia64-tdep.c +++ b/contrib/gdb/gdb/ia64-tdep.c @@ -1,6 +1,7 @@ /* Target-dependent code for the IA-64 for GDB, the GNU debugger. - Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -21,17 +22,28 @@ #include "defs.h" #include "inferior.h" -#include "symfile.h" /* for entry_point_address */ #include "gdbcore.h" #include "arch-utils.h" #include "floatformat.h" #include "regcache.h" +#include "reggroups.h" +#include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" #include "doublest.h" #include "value.h" - +#include "gdb_assert.h" #include "objfiles.h" #include "elf/common.h" /* for DT_PLTGOT value */ #include "elf-bfd.h" +#include "elf.h" /* for PT_IA64_UNWIND value */ +#include "dis-asm.h" +#include "ia64-tdep.h" + +#ifdef HAVE_LIBUNWIND_IA64_H +#include "libunwind-frame.h" +#include "libunwind-ia64.h" +#endif /* Hook for determining the global pointer when calling functions in the inferior under AIX. The initialization code in ia64-aix-nat.c @@ -79,45 +91,29 @@ typedef enum instruction_type #define BUNDLE_LEN 16 -/* FIXME: These extern declarations should go in ia64-tdep.h. */ -extern CORE_ADDR ia64_linux_sigcontext_register_address (CORE_ADDR, int); -extern CORE_ADDR ia64_aix_sigcontext_register_address (CORE_ADDR, int); - static gdbarch_init_ftype ia64_gdbarch_init; static gdbarch_register_name_ftype ia64_register_name; -static gdbarch_register_raw_size_ftype ia64_register_raw_size; -static gdbarch_register_virtual_size_ftype ia64_register_virtual_size; -static gdbarch_register_virtual_type_ftype ia64_register_virtual_type; -static gdbarch_register_byte_ftype ia64_register_byte; +static gdbarch_register_type_ftype ia64_register_type; static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc; -static gdbarch_frame_chain_ftype ia64_frame_chain; -static gdbarch_frame_saved_pc_ftype ia64_frame_saved_pc; static gdbarch_skip_prologue_ftype ia64_skip_prologue; -static gdbarch_frame_init_saved_regs_ftype ia64_frame_init_saved_regs; -static gdbarch_get_saved_register_ftype ia64_get_saved_register; static gdbarch_extract_return_value_ftype ia64_extract_return_value; -static gdbarch_extract_struct_value_address_ftype ia64_extract_struct_value_address; static gdbarch_use_struct_convention_ftype ia64_use_struct_convention; -static gdbarch_frameless_function_invocation_ftype ia64_frameless_function_invocation; -static gdbarch_init_extra_frame_info_ftype ia64_init_extra_frame_info; -static gdbarch_store_return_value_ftype ia64_store_return_value; -static gdbarch_store_struct_return_ftype ia64_store_struct_return; -static gdbarch_push_arguments_ftype ia64_push_arguments; -static gdbarch_push_return_address_ftype ia64_push_return_address; -static gdbarch_pop_frame_ftype ia64_pop_frame; -static gdbarch_saved_pc_after_call_ftype ia64_saved_pc_after_call; -static void ia64_pop_frame_regular (struct frame_info *frame); static struct type *is_float_or_hfa_type (struct type *t); -static int ia64_num_regs = 590; +static struct type *builtin_type_ia64_ext; + +#define NUM_IA64_RAW_REGS 462 -static int pc_regnum = IA64_IP_REGNUM; static int sp_regnum = IA64_GR12_REGNUM; static int fp_regnum = IA64_VFP_REGNUM; static int lr_regnum = IA64_VRAP_REGNUM; -static LONGEST ia64_call_dummy_words[] = {0}; +/* NOTE: we treat the register stack registers r32-r127 as pseudo-registers because + they may not be accessible via the ptrace register get/set interfaces. */ +enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS, VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM, + V127_REGNUM = V32_REGNUM + 95, + VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16, VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM }; /* Array of register names; There should be ia64_num_regs strings in the initializer. */ @@ -127,18 +123,18 @@ static char *ia64_register_names[] = "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", - "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", - "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", - "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63", - "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71", - "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79", - "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87", - "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95", - "r96", "r97", "r98", "r99", "r100", "r101", "r102", "r103", - "r104", "r105", "r106", "r107", "r108", "r109", "r110", "r111", - "r112", "r113", "r114", "r115", "r116", "r117", "r118", "r119", - "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", @@ -157,14 +153,14 @@ static char *ia64_register_names[] = "f112", "f113", "f114", "f115", "f116", "f117", "f118", "f119", "f120", "f121", "f122", "f123", "f124", "f125", "f126", "f127", - "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", - "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", - "p16", "p17", "p18", "p19", "p20", "p21", "p22", "p23", - "p24", "p25", "p26", "p27", "p28", "p29", "p30", "p31", - "p32", "p33", "p34", "p35", "p36", "p37", "p38", "p39", - "p40", "p41", "p42", "p43", "p44", "p45", "p46", "p47", - "p48", "p49", "p50", "p51", "p52", "p53", "p54", "p55", - "p56", "p57", "p58", "p59", "p60", "p61", "p62", "p63", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", @@ -205,32 +201,63 @@ static char *ia64_register_names[] = "nat104","nat105","nat106","nat107","nat108","nat109","nat110","nat111", "nat112","nat113","nat114","nat115","nat116","nat117","nat118","nat119", "nat120","nat121","nat122","nat123","nat124","nat125","nat126","nat127", + + "bof", + + "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", + "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", + "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", + "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63", + "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71", + "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79", + "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87", + "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95", + "r96", "r97", "r98", "r99", "r100", "r101", "r102", "r103", + "r104", "r105", "r106", "r107", "r108", "r109", "r110", "r111", + "r112", "r113", "r114", "r115", "r116", "r117", "r118", "r119", + "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127", + + "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", + "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", + "p16", "p17", "p18", "p19", "p20", "p21", "p22", "p23", + "p24", "p25", "p26", "p27", "p28", "p29", "p30", "p31", + "p32", "p33", "p34", "p35", "p36", "p37", "p38", "p39", + "p40", "p41", "p42", "p43", "p44", "p45", "p46", "p47", + "p48", "p49", "p50", "p51", "p52", "p53", "p54", "p55", + "p56", "p57", "p58", "p59", "p60", "p61", "p62", "p63", }; -struct frame_extra_info - { - CORE_ADDR bsp; /* points at r32 for the current frame */ - CORE_ADDR cfm; /* cfm value for current frame */ - int sof; /* Size of frame (decoded from cfm value) */ - int sol; /* Size of locals (decoded from cfm value) */ - CORE_ADDR after_prologue; - /* Address of first instruction after the last - prologue instruction; Note that there may - be instructions from the function's body - intermingled with the prologue. */ - int mem_stack_frame_size; - /* Size of the memory stack frame (may be zero), - or -1 if it has not been determined yet. */ - int fp_reg; /* Register number (if any) used a frame pointer +struct ia64_frame_cache +{ + CORE_ADDR base; /* frame pointer base for frame */ + CORE_ADDR pc; /* function start pc for frame */ + CORE_ADDR saved_sp; /* stack pointer for frame */ + CORE_ADDR bsp; /* points at r32 for the current frame */ + CORE_ADDR cfm; /* cfm value for current frame */ + CORE_ADDR prev_cfm; /* cfm value for previous frame */ + int frameless; + int sof; /* Size of frame (decoded from cfm value) */ + int sol; /* Size of locals (decoded from cfm value) */ + int sor; /* Number of rotating registers. (decoded from cfm value) */ + CORE_ADDR after_prologue; + /* Address of first instruction after the last + prologue instruction; Note that there may + be instructions from the function's body + intermingled with the prologue. */ + int mem_stack_frame_size; + /* Size of the memory stack frame (may be zero), + or -1 if it has not been determined yet. */ + int fp_reg; /* Register number (if any) used a frame pointer for this frame. 0 if no register is being used as the frame pointer. */ - }; + + /* Saved registers. */ + CORE_ADDR saved_regs[NUM_IA64_RAW_REGS]; + +}; struct gdbarch_tdep { - int os_ident; /* From the ELF header, one of the ELFOSABI_ - constants: ELFOSABI_LINUX, ELFOSABI_AIX, - etc. */ CORE_ADDR (*sigcontext_register_address) (CORE_ADDR, int); /* OS specific function which, given a frame address and register number, returns the offset to the @@ -243,106 +270,64 @@ struct gdbarch_tdep #define FIND_GLOBAL_POINTER \ (gdbarch_tdep (current_gdbarch)->find_global_pointer) -static char * +int +ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) +{ + int vector_p; + int float_p; + int raw_p; + if (group == all_reggroup) + return 1; + vector_p = TYPE_VECTOR (register_type (gdbarch, regnum)); + float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT; + raw_p = regnum < NUM_IA64_RAW_REGS; + if (group == float_reggroup) + return float_p; + if (group == vector_reggroup) + return vector_p; + if (group == general_reggroup) + return (!vector_p && !float_p); + if (group == save_reggroup || group == restore_reggroup) + return raw_p; + return 0; +} + +static const char * ia64_register_name (int reg) { return ia64_register_names[reg]; } -int -ia64_register_raw_size (int reg) +struct type * +ia64_register_type (struct gdbarch *arch, int reg) { - return (IA64_FR0_REGNUM <= reg && reg <= IA64_FR127_REGNUM) ? 16 : 8; + if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM) + return builtin_type_ia64_ext; + else + return builtin_type_long; } -int -ia64_register_virtual_size (int reg) +static int +ia64_dwarf_reg_to_regnum (int reg) { - return (IA64_FR0_REGNUM <= reg && reg <= IA64_FR127_REGNUM) ? 16 : 8; + if (reg >= IA64_GR32_REGNUM && reg <= IA64_GR127_REGNUM) + return V32_REGNUM + (reg - IA64_GR32_REGNUM); + return reg; } -/* Return true iff register N's virtual format is different from - its raw format. */ -int -ia64_register_convertible (int nr) +static int +floatformat_valid (const struct floatformat *fmt, const char *from) { - return (IA64_FR0_REGNUM <= nr && nr <= IA64_FR127_REGNUM); + return 1; } const struct floatformat floatformat_ia64_ext = { floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64, - floatformat_intbit_yes + floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid }; -void -ia64_register_convert_to_virtual (int regnum, struct type *type, - char *from, char *to) -{ - if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR127_REGNUM) - { - DOUBLEST val; - floatformat_to_doublest (&floatformat_ia64_ext, from, &val); - store_floating(to, TYPE_LENGTH(type), val); - } - else - error("ia64_register_convert_to_virtual called with non floating point register number"); -} - -void -ia64_register_convert_to_raw (struct type *type, int regnum, - char *from, char *to) -{ - if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR127_REGNUM) - { - DOUBLEST val = extract_floating (from, TYPE_LENGTH(type)); - floatformat_from_doublest (&floatformat_ia64_ext, &val, to); - } - else - error("ia64_register_convert_to_raw called with non floating point register number"); -} - -struct type * -ia64_register_virtual_type (int reg) -{ - if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM) - return builtin_type_long_double; - else - return builtin_type_long; -} - -int -ia64_register_byte (int reg) -{ - return (8 * reg) + - (reg <= IA64_FR0_REGNUM ? 0 : 8 * ((reg > IA64_FR127_REGNUM) ? 128 : reg - IA64_FR0_REGNUM)); -} - -/* Read the given register from a sigcontext structure in the - specified frame. */ - -static CORE_ADDR -read_sigcontext_register (struct frame_info *frame, int regnum) -{ - CORE_ADDR regaddr; - - if (frame == NULL) - internal_error (__FILE__, __LINE__, - "read_sigcontext_register: NULL frame"); - if (!frame->signal_handler_caller) - internal_error (__FILE__, __LINE__, - "read_sigcontext_register: frame not a signal_handler_caller"); - if (SIGCONTEXT_REGISTER_ADDRESS == 0) - internal_error (__FILE__, __LINE__, - "read_sigcontext_register: SIGCONTEXT_REGISTER_ADDRESS is 0"); - - regaddr = SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regnum); - if (regaddr) - return read_memory_integer (regaddr, REGISTER_RAW_SIZE (regnum)); - else - internal_error (__FILE__, __LINE__, - "read_sigcontext_register: Register %d not in struct sigcontext", regnum); -} /* Extract ``len'' bits from an instruction bundle starting at bit ``from''. */ @@ -553,9 +538,9 @@ fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr) using the pattern seen below. */ #if 0 -#define BREAKPOINT 0x00002000040LL +#define IA64_BREAKPOINT 0x00002000040LL #endif -#define BREAKPOINT 0x00003333300LL +#define IA64_BREAKPOINT 0x00003333300LL static int ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache) @@ -564,6 +549,7 @@ ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache) int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER; long long instr; int val; + int template; if (slotnum > 2) error("Can't insert breakpoint for slot numbers greater than 2."); @@ -571,9 +557,18 @@ ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache) addr &= ~0x0f; val = target_read_memory (addr, bundle, BUNDLE_LEN); + + /* Check for L type instruction in 2nd slot, if present then + bump up the slot number to the 3rd slot */ + template = extract_bit_field (bundle, 0, 5); + if (slotnum == 1 && template_encoding_table[template][1] == L) + { + slotnum = 2; + } + instr = slotN_contents (bundle, slotnum); memcpy(contents_cache, &instr, sizeof(instr)); - replace_slotN_contents (bundle, BREAKPOINT, slotnum); + replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum); if (val == 0) target_write_memory (addr, bundle, BUNDLE_LEN); @@ -587,10 +582,20 @@ ia64_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache) int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER; long long instr; int val; + int template; addr &= ~0x0f; val = target_read_memory (addr, bundle, BUNDLE_LEN); + + /* Check for L type instruction in 2nd slot, if present then + bump up the slot number to the 3rd slot */ + template = extract_bit_field (bundle, 0, 5); + if (slotnum == 1 && template_encoding_table[template][1] == L) + { + slotnum = 2; + } + memcpy (&instr, contents_cache, sizeof instr); replace_slotN_contents (bundle, instr, slotnum); if (val == 0) @@ -601,7 +606,7 @@ ia64_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache) /* We don't really want to use this, but remote.c needs to call it in order to figure out if Z-packets are supported or not. Oh, well. */ -unsigned char * +const unsigned char * ia64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) { static unsigned char breakpoint[] = @@ -613,7 +618,7 @@ ia64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) return breakpoint; } -CORE_ADDR +static CORE_ADDR ia64_read_pc (ptid_t ptid) { CORE_ADDR psr_value = read_register_pid (IA64_PSR_REGNUM, ptid); @@ -659,69 +664,258 @@ rse_address_add(CORE_ADDR addr, int nslots) return new_addr; } -/* The IA-64 frame chain is a bit odd. We won't always have a frame - pointer, so we use the SP value as the FP for the purpose of - creating a frame. There is sometimes a register (not fixed) which - is used as a frame pointer. When this register exists, it is not - especially hard to determine which one is being used. It isn't - even really hard to compute the frame chain, but it can be - computationally expensive. So, instead of making life difficult - (and slow), we pick a more convenient representation of the frame - chain, knowing that we'll have to make some small adjustments - in other places. (E.g, note that read_fp() and write_fp() are - actually read_sp() and write_sp() below in ia64_gdbarch_init() - below.) - - Okay, so what is the frame chain exactly? It'll be the SP value - at the time that the function in question was entered. - - Note that this *should* actually the frame pointer for the current - function! But as I note above, if we were to attempt to find the - address of the beginning of the previous frame, we'd waste a lot - of cycles for no good reason. So instead, we simply choose to - represent the frame chain as the end of the previous frame instead - of the beginning. */ - -CORE_ADDR -ia64_frame_chain (struct frame_info *frame) +static void +ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, void *buf) { - if (frame->signal_handler_caller) - return read_sigcontext_register (frame, sp_regnum); - else if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - return frame->frame; - else + if (regnum >= V32_REGNUM && regnum <= V127_REGNUM) { - FRAME_INIT_SAVED_REGS (frame); - if (frame->saved_regs[IA64_VFP_REGNUM]) - return read_memory_integer (frame->saved_regs[IA64_VFP_REGNUM], 8); + ULONGEST bsp; + ULONGEST cfm; + CORE_ADDR reg; + regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp); + regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm); + + /* The bsp points at the end of the register frame so we + subtract the size of frame from it to get start of register frame. */ + bsp = rse_address_add (bsp, -(cfm & 0x7f)); + + if ((cfm & 0x7f) > regnum - V32_REGNUM) + { + ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM)); + reg = read_memory_integer ((CORE_ADDR)reg_addr, 8); + store_unsigned_integer (buf, register_size (current_gdbarch, regnum), reg); + } else - return frame->frame + frame->extra_info->mem_stack_frame_size; + store_unsigned_integer (buf, register_size (current_gdbarch, regnum), 0); } -} - -CORE_ADDR -ia64_frame_saved_pc (struct frame_info *frame) -{ - if (frame->signal_handler_caller) - return read_sigcontext_register (frame, pc_regnum); - else if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - return generic_read_register_dummy (frame->pc, frame->frame, pc_regnum); - else + else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM) { - FRAME_INIT_SAVED_REGS (frame); + ULONGEST unatN_val; + ULONGEST unat; + regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat); + unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0; + store_unsigned_integer (buf, register_size (current_gdbarch, regnum), unatN_val); + } + else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM) + { + ULONGEST natN_val = 0; + ULONGEST bsp; + ULONGEST cfm; + CORE_ADDR gr_addr = 0; + regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp); + regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm); - if (frame->saved_regs[IA64_VRAP_REGNUM]) - return read_memory_integer (frame->saved_regs[IA64_VRAP_REGNUM], 8); - else if (frame->next && frame->next->signal_handler_caller) - return read_sigcontext_register (frame->next, IA64_BR0_REGNUM); - else /* either frameless, or not far enough along in the prologue... */ - return ia64_saved_pc_after_call (frame); + /* The bsp points at the end of the register frame so we + subtract the size of frame from it to get start of register frame. */ + bsp = rse_address_add (bsp, -(cfm & 0x7f)); + + if ((cfm & 0x7f) > regnum - V32_REGNUM) + gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM)); + + if (gr_addr != 0) + { + /* Compute address of nat collection bits. */ + CORE_ADDR nat_addr = gr_addr | 0x1f8; + CORE_ADDR nat_collection; + int nat_bit; + /* If our nat collection address is bigger than bsp, we have to get + the nat collection from rnat. Otherwise, we fetch the nat + collection from the computed address. */ + if (nat_addr >= bsp) + regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection); + else + nat_collection = read_memory_integer (nat_addr, 8); + nat_bit = (gr_addr >> 3) & 0x3f; + natN_val = (nat_collection >> nat_bit) & 1; + } + + store_unsigned_integer (buf, register_size (current_gdbarch, regnum), natN_val); + } + else if (regnum == VBOF_REGNUM) + { + /* A virtual register frame start is provided for user convenience. + It can be calculated as the bsp - sof (sizeof frame). */ + ULONGEST bsp, vbsp; + ULONGEST cfm; + CORE_ADDR reg; + regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp); + regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm); + + /* The bsp points at the end of the register frame so we + subtract the size of frame from it to get beginning of frame. */ + vbsp = rse_address_add (bsp, -(cfm & 0x7f)); + store_unsigned_integer (buf, register_size (current_gdbarch, regnum), vbsp); + } + else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM) + { + ULONGEST pr; + ULONGEST cfm; + ULONGEST prN_val; + CORE_ADDR reg; + regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr); + regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm); + + if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM) + { + /* Fetch predicate register rename base from current frame + marker for this frame. */ + int rrb_pr = (cfm >> 32) & 0x3f; + + /* Adjust the register number to account for register rotation. */ + regnum = VP16_REGNUM + + ((regnum - VP16_REGNUM) + rrb_pr) % 48; + } + prN_val = (pr & (1LL << (regnum - VP0_REGNUM))) != 0; + store_unsigned_integer (buf, register_size (current_gdbarch, regnum), prN_val); + } + else + memset (buf, 0, register_size (current_gdbarch, regnum)); +} + +static void +ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, const void *buf) +{ + if (regnum >= V32_REGNUM && regnum <= V127_REGNUM) + { + ULONGEST bsp; + ULONGEST cfm; + CORE_ADDR reg; + regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp); + regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm); + + bsp = rse_address_add (bsp, -(cfm & 0x7f)); + + if ((cfm & 0x7f) > regnum - V32_REGNUM) + { + ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM)); + write_memory (reg_addr, (void *)buf, 8); + } + } + else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM) + { + ULONGEST unatN_val, unat, unatN_mask; + regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat); + unatN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum)); + unatN_mask = (1LL << (regnum - IA64_NAT0_REGNUM)); + if (unatN_val == 0) + unat &= ~unatN_mask; + else if (unatN_val == 1) + unat |= unatN_mask; + regcache_cooked_write_unsigned (regcache, IA64_UNAT_REGNUM, unat); + } + else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM) + { + ULONGEST natN_val; + ULONGEST bsp; + ULONGEST cfm; + CORE_ADDR gr_addr = 0; + regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp); + regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm); + + /* The bsp points at the end of the register frame so we + subtract the size of frame from it to get start of register frame. */ + bsp = rse_address_add (bsp, -(cfm & 0x7f)); + + if ((cfm & 0x7f) > regnum - V32_REGNUM) + gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM)); + + natN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum)); + + if (gr_addr != 0 && (natN_val == 0 || natN_val == 1)) + { + /* Compute address of nat collection bits. */ + CORE_ADDR nat_addr = gr_addr | 0x1f8; + CORE_ADDR nat_collection; + int natN_bit = (gr_addr >> 3) & 0x3f; + ULONGEST natN_mask = (1LL << natN_bit); + /* If our nat collection address is bigger than bsp, we have to get + the nat collection from rnat. Otherwise, we fetch the nat + collection from the computed address. */ + if (nat_addr >= bsp) + { + regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection); + if (natN_val) + nat_collection |= natN_mask; + else + nat_collection &= ~natN_mask; + regcache_cooked_write_unsigned (regcache, IA64_RNAT_REGNUM, nat_collection); + } + else + { + char nat_buf[8]; + nat_collection = read_memory_integer (nat_addr, 8); + if (natN_val) + nat_collection |= natN_mask; + else + nat_collection &= ~natN_mask; + store_unsigned_integer (nat_buf, register_size (current_gdbarch, regnum), nat_collection); + write_memory (nat_addr, nat_buf, 8); + } + } + } + else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM) + { + ULONGEST pr; + ULONGEST cfm; + ULONGEST prN_val; + ULONGEST prN_mask; + + regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr); + regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm); + + if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM) + { + /* Fetch predicate register rename base from current frame + marker for this frame. */ + int rrb_pr = (cfm >> 32) & 0x3f; + + /* Adjust the register number to account for register rotation. */ + regnum = VP16_REGNUM + + ((regnum - VP16_REGNUM) + rrb_pr) % 48; + } + prN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum)); + prN_mask = (1LL << (regnum - VP0_REGNUM)); + if (prN_val == 0) + pr &= ~prN_mask; + else if (prN_val == 1) + pr |= prN_mask; + regcache_cooked_write_unsigned (regcache, IA64_PR_REGNUM, pr); } } +/* The ia64 needs to convert between various ieee floating-point formats + and the special ia64 floating point register format. */ + +static int +ia64_convert_register_p (int regno, struct type *type) +{ + return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM); +} + +static void +ia64_register_to_value (struct frame_info *frame, int regnum, + struct type *valtype, void *out) +{ + char in[MAX_REGISTER_SIZE]; + frame_register_read (frame, regnum, in); + convert_typed_floating (in, builtin_type_ia64_ext, out, valtype); +} + +static void +ia64_value_to_register (struct frame_info *frame, int regnum, + struct type *valtype, const void *in) +{ + char out[MAX_REGISTER_SIZE]; + convert_typed_floating (in, valtype, out, builtin_type_ia64_ext); + put_frame_register (frame, regnum, out); +} + + /* Limit the number of skipped non-prologue instructions since examining of the prologue is expensive. */ -static int max_skip_non_prologue_insns = 10; +static int max_skip_non_prologue_insns = 40; /* Given PC representing the starting address of a function, and LIM_PC which is the (sloppy) limit to which to scan when looking @@ -733,6 +927,9 @@ static int max_skip_non_prologue_insns = 10; used with no further scanning in the event that the function is frameless. */ +/* FIXME: cagney/2004-02-14: This function and logic have largely been + superseded by skip_prologue_using_sal. */ + static CORE_ADDR refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit) { @@ -790,15 +987,41 @@ refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit) | (((_instr_) & 0x00008000000LL) >> 20) \ | (((_instr_) & 0x00000001fc0LL) >> 6)) +/* Allocate and initialize a frame cache. */ + +static struct ia64_frame_cache * +ia64_alloc_frame_cache (void) +{ + struct ia64_frame_cache *cache; + int i; + + cache = FRAME_OBSTACK_ZALLOC (struct ia64_frame_cache); + + /* Base address. */ + cache->base = 0; + cache->pc = 0; + cache->cfm = 0; + cache->prev_cfm = 0; + cache->sof = 0; + cache->sol = 0; + cache->sor = 0; + cache->bsp = 0; + cache->fp_reg = 0; + cache->frameless = 1; + + for (i = 0; i < NUM_IA64_RAW_REGS; i++) + cache->saved_regs[i] = 0; + + return cache; +} + static CORE_ADDR -examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) +examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame, struct ia64_frame_cache *cache) { CORE_ADDR next_pc; CORE_ADDR last_prologue_pc = pc; instruction_type it; long long instr; - int do_fsr_stuff = 0; - int cfm_reg = 0; int ret_reg = 0; int fp_reg = 0; @@ -809,48 +1032,80 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) CORE_ADDR spill_addr = 0; char instores[8]; char infpstores[8]; + char reg_contents[256]; int trust_limit; + int frameless = 1; + int i; + CORE_ADDR addr; + char buf[8]; + CORE_ADDR bof, sor, sol, sof, cfm, rrb_gr; memset (instores, 0, sizeof instores); memset (infpstores, 0, sizeof infpstores); + memset (reg_contents, 0, sizeof reg_contents); - if (frame && !frame->saved_regs) - { - frame_saved_regs_zalloc (frame); - do_fsr_stuff = 1; - } - - if (frame - && !do_fsr_stuff - && frame->extra_info->after_prologue != 0 - && frame->extra_info->after_prologue <= lim_pc) - return frame->extra_info->after_prologue; + if (cache->after_prologue != 0 + && cache->after_prologue <= lim_pc) + return cache->after_prologue; lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit); - - /* Must start with an alloc instruction */ next_pc = fetch_instruction (pc, &it, &instr); + + /* We want to check if we have a recognizable function start before we + look ahead for a prologue. */ if (pc < lim_pc && next_pc && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL)) { - /* alloc */ + /* alloc - start of a regular function. */ int sor = (int) ((instr & 0x00078000000LL) >> 27); int sol = (int) ((instr & 0x00007f00000LL) >> 20); int sof = (int) ((instr & 0x000000fe000LL) >> 13); - /* Okay, so sor, sol, and sof aren't used right now; but perhaps - we could compare against the size given to us via the cfm as - either a sanity check or possibly to see if the frame has been - changed by a later alloc instruction... */ int rN = (int) ((instr & 0x00000001fc0LL) >> 6); + + /* Verify that the current cfm matches what we think is the + function start. If we have somehow jumped within a function, + we do not want to interpret the prologue and calculate the + addresses of various registers such as the return address. + We will instead treat the frame as frameless. */ + if (!next_frame || + (sof == (cache->cfm & 0x7f) && + sol == ((cache->cfm >> 7) & 0x7f))) + frameless = 0; + cfm_reg = rN; last_prologue_pc = next_pc; pc = next_pc; } else { - pc = lim_pc; /* Frameless: We're done early. */ - if (trust_limit) - last_prologue_pc = lim_pc; + /* Look for a leaf routine. */ + if (pc < lim_pc && next_pc + && (it == I || it == M) + && ((instr & 0x1ee00000000LL) == 0x10800000000LL)) + { + /* adds rN = imm14, rM (or mov rN, rM when imm14 is 0) */ + int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13) + | ((instr & 0x001f8000000LL) >> 20) + | ((instr & 0x000000fe000LL) >> 13)); + int rM = (int) ((instr & 0x00007f00000LL) >> 20); + int rN = (int) ((instr & 0x00000001fc0LL) >> 6); + int qp = (int) (instr & 0x0000000003fLL); + if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0) + { + /* mov r2, r12 - beginning of leaf routine */ + fp_reg = rN; + last_prologue_pc = next_pc; + } + } + + /* If we don't recognize a regular function or leaf routine, we are + done. */ + if (!fp_reg) + { + pc = lim_pc; + if (trust_limit) + last_prologue_pc = lim_pc; + } } /* Loop, looking for prologue instructions, keeping track of @@ -861,11 +1116,20 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) if (next_pc == 0) break; - if ((it == B && ((instr & 0x1e1f800003f) != 0x04000000000)) - || ((instr & 0x3fLL) != 0LL)) + if (it == B && ((instr & 0x1e1f800003f) != 0x04000000000)) { - /* Exit loop upon hitting a non-nop branch instruction - or a predicated instruction. */ + /* Exit loop upon hitting a non-nop branch instruction. */ + if (trust_limit) + lim_pc = pc; + break; + } + else if (((instr & 0x3fLL) != 0LL) && + (frameless || ret_reg != 0)) + { + /* Exit loop upon hitting a predicated instruction if + we already have the return register or if we are frameless. */ + if (trust_limit) + lim_pc = pc; break; } else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL)) @@ -907,6 +1171,8 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) else if (qp == 0 && rN == 2 && ((rM == fp_reg && fp_reg != 0) || rM == 12)) { + char buf[MAX_REGISTER_SIZE]; + CORE_ADDR saved_sp = 0; /* adds r2, spilloffset, rFramePointer or adds r2, spilloffset, r12 @@ -919,12 +1185,31 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) /* Hmm... whether or not this will work will depend on where the pc is. If it's still early in the prologue this'll be wrong. FIXME */ - spill_addr = (frame ? frame->frame : 0) + if (next_frame) + { + frame_unwind_register (next_frame, sp_regnum, buf); + saved_sp = extract_unsigned_integer (buf, 8); + } + spill_addr = saved_sp + (rM == 12 ? 0 : mem_stack_frame_size) + imm; spill_reg = rN; last_prologue_pc = next_pc; } + else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] && + rN < 256 && imm == 0) + { + /* mov rN, rM where rM is an input register */ + reg_contents[rN] = rM; + last_prologue_pc = next_pc; + } + else if (frameless && qp == 0 && rN == fp_reg && imm == 0 && + rM == 2) + { + /* mov r12, r2 */ + last_prologue_pc = next_pc; + break; + } } else if (it == M && ( ((instr & 0x1efc0000000LL) == 0x0eec0000000LL) @@ -941,8 +1226,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) if (qp == 0 && rN == spill_reg && spill_addr != 0 && ((2 <= fM && fM <= 5) || (16 <= fM && fM <= 31))) { - if (do_fsr_stuff) - frame->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr; + cache->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr; if ((instr & 0x1efc0000000) == 0x0eec0000000) spill_addr += imm; @@ -990,6 +1274,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) int rN = (int) ((instr & 0x00007f00000LL) >> 20); int rM = (int) ((instr & 0x000000fe000LL) >> 13); int qp = (int) (instr & 0x0000000003fLL); + int indirect = rM < 256 ? reg_contents[rM] : 0; if (qp == 0 && rN == spill_reg && spill_addr != 0 && (rM == unat_save_reg || rM == pr_save_reg)) { @@ -1000,15 +1285,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) if (rM == unat_save_reg) { /* Track UNAT register */ - if (do_fsr_stuff) - frame->saved_regs[IA64_UNAT_REGNUM] = spill_addr; + cache->saved_regs[IA64_UNAT_REGNUM] = spill_addr; unat_save_reg = 0; } else { /* Track PR register */ - if (do_fsr_stuff) - frame->saved_regs[IA64_PR_REGNUM] = spill_addr; + cache->saved_regs[IA64_PR_REGNUM] = spill_addr; pr_save_reg = 0; } if ((instr & 0x1efc0000000LL) == 0x0acc0000000LL) @@ -1024,6 +1307,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) instores[rM-32] = 1; last_prologue_pc = next_pc; } + else if (qp == 0 && 32 <= indirect && indirect < 40 && + !instores[indirect-32]) + { + /* Allow an indirect store of an input register. */ + instores[indirect-32] = 1; + last_prologue_pc = next_pc; + } } else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL)) { @@ -1038,11 +1328,19 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) register is permitted. */ int rM = (int) ((instr & 0x000000fe000LL) >> 13); int qp = (int) (instr & 0x0000000003fLL); + int indirect = rM < 256 ? reg_contents[rM] : 0; if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32]) { instores[rM-32] = 1; last_prologue_pc = next_pc; } + else if (qp == 0 && 32 <= indirect && indirect < 40 && + !instores[indirect-32]) + { + /* Allow an indirect store of an input register. */ + instores[indirect-32] = 1; + last_prologue_pc = next_pc; + } } else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL)) { @@ -1076,8 +1374,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) /* We've found a spill of one of the preserved general purpose regs. Record the spill address and advance the spill register if appropriate. */ - if (do_fsr_stuff) - frame->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr; + cache->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr; if ((instr & 0x1efc0000000LL) == 0x0aec0000000LL) /* st8.spill [rN] = rM, imm9 */ spill_addr += imm9(instr); @@ -1090,45 +1387,90 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) pc = next_pc; } - if (do_fsr_stuff) { - int i; - CORE_ADDR addr; - int sor, rrb_gr; - - /* Extract the size of the rotating portion of the stack - frame and the register rename base from the current - frame marker. */ - sor = ((frame->extra_info->cfm >> 14) & 0xf) * 8; - rrb_gr = (frame->extra_info->cfm >> 18) & 0x7f; + /* If not frameless and we aren't called by skip_prologue, then we need to calculate + registers for the previous frame which will be needed later. */ - for (i = 0, addr = frame->extra_info->bsp; - i < frame->extra_info->sof; - i++, addr += 8) - { - if (IS_NaT_COLLECTION_ADDR (addr)) - { - addr += 8; - } - if (i < sor) - frame->saved_regs[IA64_GR32_REGNUM + ((i + (sor - rrb_gr)) % sor)] - = addr; - else - frame->saved_regs[IA64_GR32_REGNUM + i] = addr; + if (!frameless && next_frame) + { + /* Extract the size of the rotating portion of the stack + frame and the register rename base from the current + frame marker. */ + cfm = cache->cfm; + sor = cache->sor; + sof = cache->sof; + sol = cache->sol; + rrb_gr = (cfm >> 18) & 0x7f; - if (i+32 == cfm_reg) - frame->saved_regs[IA64_CFM_REGNUM] = addr; - if (i+32 == ret_reg) - frame->saved_regs[IA64_VRAP_REGNUM] = addr; - if (i+32 == fp_reg) - frame->saved_regs[IA64_VFP_REGNUM] = addr; - } - } + /* Find the bof (beginning of frame). */ + bof = rse_address_add (cache->bsp, -sof); + + for (i = 0, addr = bof; + i < sof; + i++, addr += 8) + { + if (IS_NaT_COLLECTION_ADDR (addr)) + { + addr += 8; + } + if (i+32 == cfm_reg) + cache->saved_regs[IA64_CFM_REGNUM] = addr; + if (i+32 == ret_reg) + cache->saved_regs[IA64_VRAP_REGNUM] = addr; + if (i+32 == fp_reg) + cache->saved_regs[IA64_VFP_REGNUM] = addr; + } - if (frame && frame->extra_info) { - frame->extra_info->after_prologue = last_prologue_pc; - frame->extra_info->mem_stack_frame_size = mem_stack_frame_size; - frame->extra_info->fp_reg = fp_reg; - } + /* For the previous argument registers we require the previous bof. + If we can't find the previous cfm, then we can do nothing. */ + cfm = 0; + if (cache->saved_regs[IA64_CFM_REGNUM] != 0) + { + cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM], 8); + } + else if (cfm_reg != 0) + { + frame_unwind_register (next_frame, cfm_reg, buf); + cfm = extract_unsigned_integer (buf, 8); + } + cache->prev_cfm = cfm; + + if (cfm != 0) + { + sor = ((cfm >> 14) & 0xf) * 8; + sof = (cfm & 0x7f); + sol = (cfm >> 7) & 0x7f; + rrb_gr = (cfm >> 18) & 0x7f; + + /* The previous bof only requires subtraction of the sol (size of locals) + due to the overlap between output and input of subsequent frames. */ + bof = rse_address_add (bof, -sol); + + for (i = 0, addr = bof; + i < sof; + i++, addr += 8) + { + if (IS_NaT_COLLECTION_ADDR (addr)) + { + addr += 8; + } + if (i < sor) + cache->saved_regs[IA64_GR32_REGNUM + ((i + (sor - rrb_gr)) % sor)] + = addr; + else + cache->saved_regs[IA64_GR32_REGNUM + i] = addr; + } + + } + } + + /* Try and trust the lim_pc value whenever possible. */ + if (trust_limit && lim_pc >= last_prologue_pc) + last_prologue_pc = lim_pc; + + cache->frameless = frameless; + cache->after_prologue = last_prologue_pc; + cache->mem_stack_frame_size = mem_stack_frame_size; + cache->fp_reg = fp_reg; return last_prologue_pc; } @@ -1136,235 +1478,1218 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame) CORE_ADDR ia64_skip_prologue (CORE_ADDR pc) { - return examine_prologue (pc, pc+1024, 0); + struct ia64_frame_cache cache; + cache.base = 0; + cache.after_prologue = 0; + cache.cfm = 0; + cache.bsp = 0; + + /* Call examine_prologue with - as third argument since we don't have a next frame pointer to send. */ + return examine_prologue (pc, pc+1024, 0, &cache); } -void -ia64_frame_init_saved_regs (struct frame_info *frame) + +/* Normal frames. */ + +static struct ia64_frame_cache * +ia64_frame_cache (struct frame_info *next_frame, void **this_cache) { - if (frame->saved_regs) + struct ia64_frame_cache *cache; + char buf[8]; + CORE_ADDR cfm, sof, sol, bsp, psr; + int i; + + if (*this_cache) + return *this_cache; + + cache = ia64_alloc_frame_cache (); + *this_cache = cache; + + frame_unwind_register (next_frame, sp_regnum, buf); + cache->saved_sp = extract_unsigned_integer (buf, 8); + + /* We always want the bsp to point to the end of frame. + This way, we can always get the beginning of frame (bof) + by subtracting frame size. */ + frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf); + cache->bsp = extract_unsigned_integer (buf, 8); + + frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf); + psr = extract_unsigned_integer (buf, 8); + + frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf); + cfm = extract_unsigned_integer (buf, 8); + + cache->sof = (cfm & 0x7f); + cache->sol = (cfm >> 7) & 0x7f; + cache->sor = ((cfm >> 14) & 0xf) * 8; + + cache->cfm = cfm; + + cache->pc = frame_func_unwind (next_frame); + + if (cache->pc != 0) + examine_prologue (cache->pc, frame_pc_unwind (next_frame), next_frame, cache); + + cache->base = cache->saved_sp + cache->mem_stack_frame_size; + + return cache; +} + +static void +ia64_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct ia64_frame_cache *cache = + ia64_frame_cache (next_frame, this_cache); + + /* This marks the outermost frame. */ + if (cache->base == 0) return; - if (frame->signal_handler_caller && SIGCONTEXT_REGISTER_ADDRESS) - { - int regno; - - frame_saved_regs_zalloc (frame); - - frame->saved_regs[IA64_VRAP_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_IP_REGNUM); - frame->saved_regs[IA64_CFM_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_CFM_REGNUM); - frame->saved_regs[IA64_PSR_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_PSR_REGNUM); -#if 0 - frame->saved_regs[IA64_BSP_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_BSP_REGNUM); -#endif - frame->saved_regs[IA64_RNAT_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_RNAT_REGNUM); - frame->saved_regs[IA64_CCV_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_CCV_REGNUM); - frame->saved_regs[IA64_UNAT_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_UNAT_REGNUM); - frame->saved_regs[IA64_FPSR_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_FPSR_REGNUM); - frame->saved_regs[IA64_PFS_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_PFS_REGNUM); - frame->saved_regs[IA64_LC_REGNUM] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_LC_REGNUM); - for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++) - if (regno != sp_regnum) - frame->saved_regs[regno] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regno); - for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++) - frame->saved_regs[regno] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regno); - for (regno = IA64_FR2_REGNUM; regno <= IA64_BR7_REGNUM; regno++) - frame->saved_regs[regno] = - SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regno); - } - else - { - CORE_ADDR func_start; - - func_start = get_pc_function_start (frame->pc); - examine_prologue (func_start, frame->pc, frame); - } + (*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp); + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "regular frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n", + paddr_nz (this_id->code_addr), + paddr_nz (this_id->stack_addr), + paddr_nz (cache->bsp), next_frame); } -void -ia64_get_saved_register (char *raw_buffer, - int *optimized, - CORE_ADDR *addrp, - struct frame_info *frame, - int regnum, - enum lval_type *lval) +static void +ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) { - int is_dummy_frame; + struct ia64_frame_cache *cache = + ia64_frame_cache (next_frame, this_cache); + char dummy_valp[MAX_REGISTER_SIZE]; + char buf[8]; + + gdb_assert (regnum >= 0); if (!target_has_registers) error ("No registers."); - if (optimized != NULL) - *optimized = 0; + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; - if (addrp != NULL) - *addrp = 0; - - if (lval != NULL) - *lval = not_lval; - - is_dummy_frame = PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame); - - if (regnum == SP_REGNUM && frame->next) + /* Rather than check each time if valuep is non-null, supply a dummy buffer + when valuep is not supplied. */ + if (!valuep) + valuep = dummy_valp; + + memset (valuep, 0, register_size (current_gdbarch, regnum)); + + if (regnum == SP_REGNUM) { /* Handle SP values for all frames but the topmost. */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->frame); + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), + cache->base); } else if (regnum == IA64_BSP_REGNUM) { - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), - frame->extra_info->bsp); + char cfm_valuep[MAX_REGISTER_SIZE]; + int cfm_optim; + int cfm_realnum; + enum lval_type cfm_lval; + CORE_ADDR cfm_addr; + CORE_ADDR bsp, prev_cfm, prev_bsp; + + /* We want to calculate the previous bsp as the end of the previous register stack frame. + This corresponds to what the hardware bsp register will be if we pop the frame + back which is why we might have been called. We know the beginning of the current + frame is cache->bsp - cache->sof. This value in the previous frame points to + the start of the output registers. We can calculate the end of that frame by adding + the size of output (sof (size of frame) - sol (size of locals)). */ + ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM, + &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep); + prev_cfm = extract_unsigned_integer (cfm_valuep, 8); + + bsp = rse_address_add (cache->bsp, -(cache->sof)); + prev_bsp = rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f)); + + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), + prev_bsp); + } + else if (regnum == IA64_CFM_REGNUM) + { + CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM]; + + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, valuep, register_size (current_gdbarch, regnum)); + } + else if (cache->prev_cfm) + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), cache->prev_cfm); + else if (cache->frameless) + { + CORE_ADDR cfm = 0; + frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep); + } } else if (regnum == IA64_VFP_REGNUM) { /* If the function in question uses an automatic register (r32-r127) for the frame pointer, it'll be found by ia64_find_saved_register() above. If the function lacks one of these frame pointers, we can - still provide a value since we know the size of the frame */ - CORE_ADDR vfp = frame->frame + frame->extra_info->mem_stack_frame_size; - store_address (raw_buffer, REGISTER_RAW_SIZE (IA64_VFP_REGNUM), vfp); + still provide a value since we know the size of the frame. */ + CORE_ADDR vfp = cache->base; + store_unsigned_integer (valuep, register_size (current_gdbarch, IA64_VFP_REGNUM), vfp); } - else if (IA64_PR0_REGNUM <= regnum && regnum <= IA64_PR63_REGNUM) + else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM) { - char *pr_raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + char pr_valuep[MAX_REGISTER_SIZE]; int pr_optim; + int pr_realnum; enum lval_type pr_lval; CORE_ADDR pr_addr; - int prN_val; - ia64_get_saved_register (pr_raw_buffer, &pr_optim, &pr_addr, - frame, IA64_PR_REGNUM, &pr_lval); - if (IA64_PR16_REGNUM <= regnum && regnum <= IA64_PR63_REGNUM) + ULONGEST prN_val; + ia64_frame_prev_register (next_frame, this_cache, IA64_PR_REGNUM, + &pr_optim, &pr_lval, &pr_addr, &pr_realnum, pr_valuep); + if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM) { /* Fetch predicate register rename base from current frame - marker for this frame. */ - int rrb_pr = (frame->extra_info->cfm >> 32) & 0x3f; + marker for this frame. */ + int rrb_pr = (cache->cfm >> 32) & 0x3f; - /* Adjust the register number to account for register rotation. */ - regnum = IA64_PR16_REGNUM - + ((regnum - IA64_PR16_REGNUM) + rrb_pr) % 48; + /* Adjust the register number to account for register rotation. */ + regnum = VP16_REGNUM + + ((regnum - VP16_REGNUM) + rrb_pr) % 48; } - prN_val = extract_bit_field ((unsigned char *) pr_raw_buffer, - regnum - IA64_PR0_REGNUM, 1); - store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), prN_val); + prN_val = extract_bit_field ((unsigned char *) pr_valuep, + regnum - VP0_REGNUM, 1); + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), prN_val); } else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM) { - char *unat_raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + char unat_valuep[MAX_REGISTER_SIZE]; int unat_optim; + int unat_realnum; enum lval_type unat_lval; CORE_ADDR unat_addr; - int unatN_val; - ia64_get_saved_register (unat_raw_buffer, &unat_optim, &unat_addr, - frame, IA64_UNAT_REGNUM, &unat_lval); - unatN_val = extract_bit_field ((unsigned char *) unat_raw_buffer, + ULONGEST unatN_val; + ia64_frame_prev_register (next_frame, this_cache, IA64_UNAT_REGNUM, + &unat_optim, &unat_lval, &unat_addr, &unat_realnum, unat_valuep); + unatN_val = extract_bit_field ((unsigned char *) unat_valuep, regnum - IA64_NAT0_REGNUM, 1); - store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), unatN_val); } else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM) { int natval = 0; /* Find address of general register corresponding to nat bit we're - interested in. */ - CORE_ADDR gr_addr = 0; + interested in. */ + CORE_ADDR gr_addr; - if (!is_dummy_frame) + gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM + + IA64_GR0_REGNUM]; + if (gr_addr != 0) { - FRAME_INIT_SAVED_REGS (frame); - gr_addr = frame->saved_regs[ regnum - IA64_NAT0_REGNUM - + IA64_GR0_REGNUM]; - } - if (gr_addr) - { - /* Compute address of nat collection bits */ + /* Compute address of nat collection bits. */ CORE_ADDR nat_addr = gr_addr | 0x1f8; - CORE_ADDR bsp = read_register (IA64_BSP_REGNUM); + CORE_ADDR bsp; CORE_ADDR nat_collection; int nat_bit; /* If our nat collection address is bigger than bsp, we have to get the nat collection from rnat. Otherwise, we fetch the nat - collection from the computed address. */ + collection from the computed address. */ + frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf); + bsp = extract_unsigned_integer (buf, 8); if (nat_addr >= bsp) - nat_collection = read_register (IA64_RNAT_REGNUM); + { + frame_unwind_register (next_frame, IA64_RNAT_REGNUM, buf); + nat_collection = extract_unsigned_integer (buf, 8); + } else nat_collection = read_memory_integer (nat_addr, 8); nat_bit = (gr_addr >> 3) & 0x3f; natval = (nat_collection >> nat_bit) & 1; } - store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), natval); + + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), natval); } else if (regnum == IA64_IP_REGNUM) { - CORE_ADDR pc; - if (frame->next) - { - /* FIXME: Set *addrp, *lval when possible. */ - pc = ia64_frame_saved_pc (frame->next); - } - else - { - pc = read_pc (); - } - store_address (raw_buffer, REGISTER_RAW_SIZE (IA64_IP_REGNUM), pc); - } - else if (IA64_GR32_REGNUM <= regnum && regnum <= IA64_GR127_REGNUM) - { - CORE_ADDR addr = 0; - if (!is_dummy_frame) - { - FRAME_INIT_SAVED_REGS (frame); - addr = frame->saved_regs[regnum]; - } + CORE_ADDR pc = 0; + CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM]; if (addr != 0) { - if (lval != NULL) - *lval = lval_memory; - if (addrp != NULL) - *addrp = addr; - read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum)); + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM)); + pc = extract_unsigned_integer (buf, 8); } - else + else if (cache->frameless) + { + frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf); + pc = extract_unsigned_integer (buf, 8); + } + pc &= ~0xf; + store_unsigned_integer (valuep, 8, pc); + } + else if (regnum == IA64_PSR_REGNUM) + { + /* We don't know how to get the complete previous PSR, but we need it for + the slot information when we unwind the pc (pc is formed of IP register + plus slot information from PSR). To get the previous slot information, + we mask it off the return address. */ + ULONGEST slot_num = 0; + CORE_ADDR pc= 0; + CORE_ADDR psr = 0; + CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM]; + + frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf); + psr = extract_unsigned_integer (buf, 8); + + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM)); + pc = extract_unsigned_integer (buf, 8); + } + else if (cache->frameless) + { + CORE_ADDR pc; + frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf); + pc = extract_unsigned_integer (buf, 8); + } + psr &= ~(3LL << 41); + slot_num = pc & 0x3LL; + psr |= (CORE_ADDR)slot_num << 41; + store_unsigned_integer (valuep, 8, psr); + } + else if (regnum == IA64_BR0_REGNUM) + { + CORE_ADDR br0 = 0; + CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM]; + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, buf, register_size (current_gdbarch, IA64_BR0_REGNUM)); + br0 = extract_unsigned_integer (buf, 8); + } + store_unsigned_integer (valuep, 8, br0); + } + else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) || + (regnum >= V32_REGNUM && regnum <= V127_REGNUM)) + { + CORE_ADDR addr = 0; + if (regnum >= V32_REGNUM) + regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM); + addr = cache->saved_regs[regnum]; + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, valuep, register_size (current_gdbarch, regnum)); + } + else if (cache->frameless) { - /* r32 - r127 must be fetchable via memory. If they aren't, - then the register is unavailable */ - memset (raw_buffer, 0, REGISTER_RAW_SIZE (regnum)); + char r_valuep[MAX_REGISTER_SIZE]; + int r_optim; + int r_realnum; + enum lval_type r_lval; + CORE_ADDR r_addr; + CORE_ADDR prev_cfm, prev_bsp, prev_bof; + CORE_ADDR addr = 0; + if (regnum >= V32_REGNUM) + regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM); + ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM, + &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep); + prev_cfm = extract_unsigned_integer (r_valuep, 8); + ia64_frame_prev_register (next_frame, this_cache, IA64_BSP_REGNUM, + &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep); + prev_bsp = extract_unsigned_integer (r_valuep, 8); + prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f)); + + addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM)); + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, valuep, register_size (current_gdbarch, regnum)); } } else { + CORE_ADDR addr = 0; if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM) { /* Fetch floating point register rename base from current - frame marker for this frame. */ - int rrb_fr = (frame->extra_info->cfm >> 25) & 0x7f; + frame marker for this frame. */ + int rrb_fr = (cache->cfm >> 25) & 0x7f; /* Adjust the floating point register number to account for - register rotation. */ + register rotation. */ regnum = IA64_FR32_REGNUM + ((regnum - IA64_FR32_REGNUM) + rrb_fr) % 96; } - generic_get_saved_register (raw_buffer, optimized, addrp, frame, - regnum, lval); + /* If we have stored a memory address, access the register. */ + addr = cache->saved_regs[regnum]; + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, valuep, register_size (current_gdbarch, regnum)); + } + /* Otherwise, punt and get the current value of the register. */ + else + frame_unwind_register (next_frame, regnum, valuep); + } + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "regular prev register <%d> <%s> is 0x%s\n", regnum, + (((unsigned) regnum <= IA64_NAT127_REGNUM) + ? ia64_register_names[regnum] : "r??"), + paddr_nz (extract_unsigned_integer (valuep, 8))); +} + +static const struct frame_unwind ia64_frame_unwind = +{ + NORMAL_FRAME, + &ia64_frame_this_id, + &ia64_frame_prev_register +}; + +static const struct frame_unwind * +ia64_frame_sniffer (struct frame_info *next_frame) +{ + return &ia64_frame_unwind; +} + +/* Signal trampolines. */ + +static void +ia64_sigtramp_frame_init_saved_regs (struct ia64_frame_cache *cache) +{ + if (SIGCONTEXT_REGISTER_ADDRESS) + { + int regno; + + cache->saved_regs[IA64_VRAP_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_IP_REGNUM); + cache->saved_regs[IA64_CFM_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CFM_REGNUM); + cache->saved_regs[IA64_PSR_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PSR_REGNUM); + cache->saved_regs[IA64_BSP_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSP_REGNUM); + cache->saved_regs[IA64_RNAT_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RNAT_REGNUM); + cache->saved_regs[IA64_CCV_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CCV_REGNUM); + cache->saved_regs[IA64_UNAT_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_UNAT_REGNUM); + cache->saved_regs[IA64_FPSR_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_FPSR_REGNUM); + cache->saved_regs[IA64_PFS_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PFS_REGNUM); + cache->saved_regs[IA64_LC_REGNUM] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_LC_REGNUM); + for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++) + cache->saved_regs[regno] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno); + for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++) + cache->saved_regs[regno] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno); + for (regno = IA64_FR2_REGNUM; regno <= IA64_FR31_REGNUM; regno++) + cache->saved_regs[regno] = + SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno); } } -/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of - EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc - and TYPE is the type (which is known to be struct, union or array). */ +static struct ia64_frame_cache * +ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct ia64_frame_cache *cache; + CORE_ADDR addr; + char buf[8]; + int i; + + if (*this_cache) + return *this_cache; + + cache = ia64_alloc_frame_cache (); + + frame_unwind_register (next_frame, sp_regnum, buf); + /* Note that frame size is hard-coded below. We cannot calculate it + via prologue examination. */ + cache->base = extract_unsigned_integer (buf, 8) + 16; + + frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf); + cache->bsp = extract_unsigned_integer (buf, 8); + + frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf); + cache->cfm = extract_unsigned_integer (buf, 8); + cache->sof = cache->cfm & 0x7f; + + ia64_sigtramp_frame_init_saved_regs (cache); + + *this_cache = cache; + return cache; +} + +static void +ia64_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_cache, struct frame_id *this_id) +{ + struct ia64_frame_cache *cache = + ia64_sigtramp_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp); + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n", + paddr_nz (this_id->code_addr), + paddr_nz (this_id->stack_addr), + paddr_nz (cache->bsp), next_frame); +} + +static void +ia64_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + char dummy_valp[MAX_REGISTER_SIZE]; + char buf[MAX_REGISTER_SIZE]; + + struct ia64_frame_cache *cache = + ia64_sigtramp_frame_cache (next_frame, this_cache); + + gdb_assert (regnum >= 0); + + if (!target_has_registers) + error ("No registers."); + + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; + + /* Rather than check each time if valuep is non-null, supply a dummy buffer + when valuep is not supplied. */ + if (!valuep) + valuep = dummy_valp; + + memset (valuep, 0, register_size (current_gdbarch, regnum)); + + if (regnum == IA64_IP_REGNUM) + { + CORE_ADDR pc = 0; + CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM]; + + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM)); + pc = extract_unsigned_integer (buf, 8); + } + pc &= ~0xf; + store_unsigned_integer (valuep, 8, pc); + } + else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) || + (regnum >= V32_REGNUM && regnum <= V127_REGNUM)) + { + CORE_ADDR addr = 0; + if (regnum >= V32_REGNUM) + regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM); + addr = cache->saved_regs[regnum]; + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, valuep, register_size (current_gdbarch, regnum)); + } + } + else + { + /* All other registers not listed above. */ + CORE_ADDR addr = cache->saved_regs[regnum]; + if (addr != 0) + { + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, valuep, register_size (current_gdbarch, regnum)); + } + } + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "sigtramp prev register <%s> is 0x%s\n", + (((unsigned) regnum <= IA64_NAT127_REGNUM) + ? ia64_register_names[regnum] : "r??"), + paddr_nz (extract_unsigned_integer (valuep, 8))); +} + +static const struct frame_unwind ia64_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + ia64_sigtramp_frame_this_id, + ia64_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +ia64_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + char *name; + CORE_ADDR pc = frame_pc_unwind (next_frame); + + find_pc_partial_function (pc, &name, NULL, NULL); + if (PC_IN_SIGTRAMP (pc, name)) + return &ia64_sigtramp_frame_unwind; + + return NULL; +} + + +static CORE_ADDR +ia64_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct ia64_frame_cache *cache = + ia64_frame_cache (next_frame, this_cache); + + return cache->base; +} + +static const struct frame_base ia64_frame_base = +{ + &ia64_frame_unwind, + ia64_frame_base_address, + ia64_frame_base_address, + ia64_frame_base_address +}; + +#ifdef HAVE_LIBUNWIND_IA64_H + +struct ia64_unwind_table_entry + { + unw_word_t start_offset; + unw_word_t end_offset; + unw_word_t info_offset; + }; + +static __inline__ uint64_t +ia64_rse_slot_num (uint64_t addr) +{ + return (addr >> 3) & 0x3f; +} + +/* Skip over a designated number of registers in the backing + store, remembering every 64th position is for NAT. */ +static __inline__ uint64_t +ia64_rse_skip_regs (uint64_t addr, long num_regs) +{ + long delta = ia64_rse_slot_num(addr) + num_regs; + + if (num_regs < 0) + delta -= 0x3e; + return addr + ((num_regs + delta/0x3f) << 3); +} + +/* Gdb libunwind-frame callback function to convert from an ia64 gdb register + number to a libunwind register number. */ +static int +ia64_gdb2uw_regnum (int regnum) +{ + if (regnum == sp_regnum) + return UNW_IA64_SP; + else if (regnum == IA64_BSP_REGNUM) + return UNW_IA64_BSP; + else if ((unsigned) (regnum - IA64_GR0_REGNUM) < 128) + return UNW_IA64_GR + (regnum - IA64_GR0_REGNUM); + else if ((unsigned) (regnum - V32_REGNUM) < 95) + return UNW_IA64_GR + 32 + (regnum - V32_REGNUM); + else if ((unsigned) (regnum - IA64_FR0_REGNUM) < 128) + return UNW_IA64_FR + (regnum - IA64_FR0_REGNUM); + else if ((unsigned) (regnum - IA64_PR0_REGNUM) < 64) + return -1; + else if ((unsigned) (regnum - IA64_BR0_REGNUM) < 8) + return UNW_IA64_BR + (regnum - IA64_BR0_REGNUM); + else if (regnum == IA64_PR_REGNUM) + return UNW_IA64_PR; + else if (regnum == IA64_IP_REGNUM) + return UNW_REG_IP; + else if (regnum == IA64_CFM_REGNUM) + return UNW_IA64_CFM; + else if ((unsigned) (regnum - IA64_AR0_REGNUM) < 128) + return UNW_IA64_AR + (regnum - IA64_AR0_REGNUM); + else if ((unsigned) (regnum - IA64_NAT0_REGNUM) < 128) + return UNW_IA64_NAT + (regnum - IA64_NAT0_REGNUM); + else + return -1; +} + +/* Gdb libunwind-frame callback function to convert from a libunwind register + number to a ia64 gdb register number. */ +static int +ia64_uw2gdb_regnum (int uw_regnum) +{ + if (uw_regnum == UNW_IA64_SP) + return sp_regnum; + else if (uw_regnum == UNW_IA64_BSP) + return IA64_BSP_REGNUM; + else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 32) + return IA64_GR0_REGNUM + (uw_regnum - UNW_IA64_GR); + else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 128) + return V32_REGNUM + (uw_regnum - (IA64_GR0_REGNUM + 32)); + else if ((unsigned) (uw_regnum - UNW_IA64_FR) < 128) + return IA64_FR0_REGNUM + (uw_regnum - UNW_IA64_FR); + else if ((unsigned) (uw_regnum - UNW_IA64_BR) < 8) + return IA64_BR0_REGNUM + (uw_regnum - UNW_IA64_BR); + else if (uw_regnum == UNW_IA64_PR) + return IA64_PR_REGNUM; + else if (uw_regnum == UNW_REG_IP) + return IA64_IP_REGNUM; + else if (uw_regnum == UNW_IA64_CFM) + return IA64_CFM_REGNUM; + else if ((unsigned) (uw_regnum - UNW_IA64_AR) < 128) + return IA64_AR0_REGNUM + (uw_regnum - UNW_IA64_AR); + else if ((unsigned) (uw_regnum - UNW_IA64_NAT) < 128) + return IA64_NAT0_REGNUM + (uw_regnum - UNW_IA64_NAT); + else + return -1; +} + +/* Gdb libunwind-frame callback function to reveal if register is a float + register or not. */ +static int +ia64_is_fpreg (int uw_regnum) +{ + return unw_is_fpreg (uw_regnum); +} + +/* Libunwind callback accessor function for general registers. */ +static int +ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val, + int write, void *arg) +{ + int regnum = ia64_uw2gdb_regnum (uw_regnum); + unw_word_t bsp, sof, sol, cfm, psr, ip; + struct frame_info *next_frame = arg; + long new_sof, old_sof; + char buf[MAX_REGISTER_SIZE]; + + if (write) + { + if (regnum < 0) + /* ignore writes to pseudo-registers such as UNW_IA64_PROC_STARTI. */ + return 0; + + switch (uw_regnum) + { + case UNW_REG_IP: + ia64_write_pc (*val, inferior_ptid); + break; + + case UNW_IA64_AR_BSPSTORE: + write_register (IA64_BSP_REGNUM, *val); + break; + + case UNW_IA64_AR_BSP: + case UNW_IA64_BSP: + /* Account for the fact that ptrace() expects bsp to point + after the current register frame. */ + cfm = read_register (IA64_CFM_REGNUM); + sof = (cfm & 0x7f); + bsp = ia64_rse_skip_regs (*val, sof); + write_register (IA64_BSP_REGNUM, bsp); + break; + + case UNW_IA64_CFM: + /* If we change CFM, we need to adjust ptrace's notion of + bsp accordingly, so that the real bsp remains + unchanged. */ + bsp = read_register (IA64_BSP_REGNUM); + cfm = read_register (IA64_CFM_REGNUM); + old_sof = (cfm & 0x7f); + new_sof = (*val & 0x7f); + if (old_sof != new_sof) + { + bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof); + write_register (IA64_BSP_REGNUM, bsp); + } + write_register (IA64_CFM_REGNUM, *val); + break; + + default: + write_register (regnum, *val); + break; + } + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + " access_reg: to cache: %4s=0x%s\n", + (((unsigned) regnum <= IA64_NAT127_REGNUM) + ? ia64_register_names[regnum] : "r??"), + paddr_nz (*val)); + } + else + { + switch (uw_regnum) + { + case UNW_REG_IP: + /* Libunwind expects to see the pc value which means the slot number + from the psr must be merged with the ip word address. */ + frame_unwind_register (next_frame, IA64_IP_REGNUM, buf); + ip = extract_unsigned_integer (buf, 8); + frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf); + psr = extract_unsigned_integer (buf, 8); + *val = ip | ((psr >> 41) & 0x3); + break; + + case UNW_IA64_AR_BSP: + /* Libunwind expects to see the beginning of the current register + frame so we must account for the fact that ptrace() will return a value + for bsp that points *after* the current register frame. */ + frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf); + bsp = extract_unsigned_integer (buf, 8); + frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf); + cfm = extract_unsigned_integer (buf, 8); + sof = (cfm & 0x7f); + *val = ia64_rse_skip_regs (bsp, -sof); + break; + + case UNW_IA64_AR_BSPSTORE: + /* Libunwind wants bspstore to be after the current register frame. + This is what ptrace() and gdb treats as the regular bsp value. */ + frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf); + *val = extract_unsigned_integer (buf, 8); + break; + + default: + /* For all other registers, just unwind the value directly. */ + frame_unwind_register (next_frame, regnum, buf); + *val = extract_unsigned_integer (buf, 8); + break; + } + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + " access_reg: from cache: %4s=0x%s\n", + (((unsigned) regnum <= IA64_NAT127_REGNUM) + ? ia64_register_names[regnum] : "r??"), + paddr_nz (*val)); + } + return 0; +} + +/* Libunwind callback accessor function for floating-point registers. */ +static int +ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_fpreg_t *val, + int write, void *arg) +{ + int regnum = ia64_uw2gdb_regnum (uw_regnum); + + if (write) + regcache_cooked_write (current_regcache, regnum, (char *) val); + else + regcache_cooked_read (current_regcache, regnum, (char *) val); + return 0; +} + +/* Libunwind callback accessor function for accessing memory. */ +static int +ia64_access_mem (unw_addr_space_t as, + unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + /* XXX do we need to normalize byte-order here? */ + if (write) + return target_write_memory (addr, (char *) val, sizeof (unw_word_t)); + else + return target_read_memory (addr, (char *) val, sizeof (unw_word_t)); +} + +/* Call low-level function to access the kernel unwind table. */ +static int +getunwind_table (void *buf, size_t len) +{ + LONGEST x; + x = target_read_partial (¤t_target, TARGET_OBJECT_UNWIND_TABLE, NULL, + buf, 0, len); + + return (int)x; +} + +/* Get the kernel unwind table. */ +static int +get_kernel_table (unw_word_t ip, unw_dyn_info_t *di) +{ + size_t size; + struct ia64_table_entry + { + uint64_t start_offset; + uint64_t end_offset; + uint64_t info_offset; + }; + static struct ia64_table_entry *ktab = NULL, *etab; + + if (!ktab) + { + size = getunwind_table (NULL, 0); + if ((int)size < 0) + return -UNW_ENOINFO; + ktab = xmalloc (size); + getunwind_table (ktab, size); + + /* Determine length of kernel's unwind table and relocate + it's entries. */ + for (etab = ktab; etab->start_offset; ++etab) + etab->info_offset += (uint64_t) ktab; + } + + if (ip < ktab[0].start_offset || ip >= etab[-1].end_offset) + return -UNW_ENOINFO; + + di->format = UNW_INFO_FORMAT_TABLE; + di->gp = 0; + di->start_ip = ktab[0].start_offset; + di->end_ip = etab[-1].end_offset; + di->u.ti.name_ptr = (unw_word_t) ""; + di->u.ti.segbase = 0; + di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t); + di->u.ti.table_data = (unw_word_t *) ktab; + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, "get_kernel_table: found table `%s': " + "segbase=0x%s, length=%s, gp=0x%s\n", + (char *) di->u.ti.name_ptr, + paddr_nz (di->u.ti.segbase), + paddr_u (di->u.ti.table_len), + paddr_nz (di->gp)); + return 0; +} + +/* Find the unwind table entry for a specified address. */ +static int +ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip, + unw_dyn_info_t *dip, void **buf) +{ + Elf_Internal_Phdr *phdr, *p_text = NULL, *p_unwind = NULL; + Elf_Internal_Ehdr *ehdr; + unw_word_t segbase = 0; + CORE_ADDR load_base; + bfd *bfd; + int i; + + bfd = objfile->obfd; + + ehdr = elf_tdata (bfd)->elf_header; + phdr = elf_tdata (bfd)->phdr; + + load_base = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if ((unw_word_t) (ip - load_base - phdr[i].p_vaddr) + < phdr[i].p_memsz) + p_text = phdr + i; + break; + + case PT_IA_64_UNWIND: + p_unwind = phdr + i; + break; + + default: + break; + } + } + + if (!p_text || !p_unwind + /* Verify that the segment that contains the IP also contains + the static unwind table. If not, we are dealing with + runtime-generated code, for which we have no info here. */ + || (p_unwind->p_vaddr - p_text->p_vaddr) >= p_text->p_memsz) + return -UNW_ENOINFO; + + segbase = p_text->p_vaddr + load_base; + + dip->start_ip = segbase; + dip->end_ip = dip->start_ip + p_text->p_memsz; + dip->gp = FIND_GLOBAL_POINTER (ip); + dip->format = UNW_INFO_FORMAT_REMOTE_TABLE; + dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd); + dip->u.rti.segbase = segbase; + dip->u.rti.table_len = p_unwind->p_memsz / sizeof (unw_word_t); + dip->u.rti.table_data = p_unwind->p_vaddr + load_base; + + return 0; +} + +/* Libunwind callback accessor function to acquire procedure unwind-info. */ +static int +ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + struct obj_section *sec = find_pc_section (ip); + unw_dyn_info_t di; + int ret; + void *buf = NULL; + + if (!sec) + { + /* XXX This only works if the host and the target architecture are + both ia64 and if the have (more or less) the same kernel + version. */ + if (get_kernel_table (ip, &di) < 0) + return -UNW_ENOINFO; + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> " + "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s," + "length=%s,data=0x%s)\n", + paddr_nz (ip), (char *)di.u.ti.name_ptr, + paddr_nz (di.u.ti.segbase), + paddr_nz (di.start_ip), paddr_nz (di.end_ip), + paddr_nz (di.gp), + paddr_u (di.u.ti.table_len), + paddr_nz ((CORE_ADDR)di.u.ti.table_data)); + } + else + { + ret = ia64_find_unwind_table (sec->objfile, ip, &di, &buf); + if (ret < 0) + return ret; + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> " + "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s," + "length=%s,data=0x%s)\n", + paddr_nz (ip), (char *)di.u.rti.name_ptr, + paddr_nz (di.u.rti.segbase), + paddr_nz (di.start_ip), paddr_nz (di.end_ip), + paddr_nz (di.gp), + paddr_u (di.u.rti.table_len), + paddr_nz (di.u.rti.table_data)); + } + + ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info, + arg); + + /* We no longer need the dyn info storage so free it. */ + xfree (buf); + + return ret; +} + +/* Libunwind callback accessor function for cleanup. */ +static void +ia64_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pip, void *arg) +{ + /* Nothing required for now. */ +} + +/* Libunwind callback accessor function to get head of the dynamic + unwind-info registration list. */ +static int +ia64_get_dyn_info_list (unw_addr_space_t as, + unw_word_t *dilap, void *arg) +{ + struct obj_section *text_sec; + struct objfile *objfile; + unw_word_t ip, addr; + unw_dyn_info_t di; + int ret; + + if (!libunwind_is_initialized ()) + return -UNW_ENOINFO; + + for (objfile = object_files; objfile; objfile = objfile->next) + { + void *buf = NULL; + + text_sec = objfile->sections + SECT_OFF_TEXT (objfile); + ip = text_sec->addr; + ret = ia64_find_unwind_table (objfile, ip, &di, &buf); + if (ret >= 0) + { + addr = libunwind_find_dyn_list (as, &di, arg); + /* We no longer need the dyn info storage so free it. */ + xfree (buf); + + if (addr) + { + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "dynamic unwind table in objfile %s " + "at 0x%s (gp=0x%s)\n", + bfd_get_filename (objfile->obfd), + paddr_nz (addr), paddr_nz (di.gp)); + *dilap = addr; + return 0; + } + } + } + return -UNW_ENOINFO; +} + + +/* Frame interface functions for libunwind. */ + +static void +ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + char buf[8]; + CORE_ADDR bsp; + struct frame_id id; + + libunwind_frame_this_id (next_frame, this_cache, &id); + + /* We must add the bsp as the special address for frame comparison purposes. */ + frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf); + bsp = extract_unsigned_integer (buf, 8); + + (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp); + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n", + paddr_nz (id.code_addr), paddr_nz (id.stack_addr), + paddr_nz (bsp), next_frame); +} + +static void +ia64_libunwind_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + int reg = regnum; + + if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM) + reg = IA64_PR_REGNUM; + else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM) + reg = IA64_UNAT_REGNUM; + + /* Let libunwind do most of the work. */ + libunwind_frame_prev_register (next_frame, this_cache, reg, + optimizedp, lvalp, addrp, realnump, valuep); + + if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM) + { + ULONGEST prN_val; + + if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM) + { + int rrb_pr = 0; + ULONGEST cfm; + unsigned char buf[MAX_REGISTER_SIZE]; + + /* Fetch predicate register rename base from current frame + marker for this frame. */ + frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf); + cfm = extract_unsigned_integer (buf, 8); + rrb_pr = (cfm >> 32) & 0x3f; + + /* Adjust the register number to account for register rotation. */ + regnum = VP16_REGNUM + + ((regnum - VP16_REGNUM) + rrb_pr) % 48; + } + prN_val = extract_bit_field ((unsigned char *) valuep, + regnum - VP0_REGNUM, 1); + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), prN_val); + } + else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM) + { + ULONGEST unatN_val; + + unatN_val = extract_bit_field ((unsigned char *) valuep, + regnum - IA64_NAT0_REGNUM, 1); + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), + unatN_val); + } + else if (regnum == IA64_BSP_REGNUM) + { + char cfm_valuep[MAX_REGISTER_SIZE]; + int cfm_optim; + int cfm_realnum; + enum lval_type cfm_lval; + CORE_ADDR cfm_addr; + CORE_ADDR bsp, prev_cfm, prev_bsp; + + /* We want to calculate the previous bsp as the end of the previous register stack frame. + This corresponds to what the hardware bsp register will be if we pop the frame + back which is why we might have been called. We know that libunwind will pass us back + the beginning of the current frame so we should just add sof to it. */ + prev_bsp = extract_unsigned_integer (valuep, 8); + libunwind_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM, + &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep); + prev_cfm = extract_unsigned_integer (cfm_valuep, 8); + prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f)); + + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), + prev_bsp); + } + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "libunwind prev register <%s> is 0x%s\n", + (((unsigned) regnum <= IA64_NAT127_REGNUM) + ? ia64_register_names[regnum] : "r??"), + paddr_nz (extract_unsigned_integer (valuep, 8))); +} + +static const struct frame_unwind ia64_libunwind_frame_unwind = +{ + NORMAL_FRAME, + ia64_libunwind_frame_this_id, + ia64_libunwind_frame_prev_register +}; + +static const struct frame_unwind * +ia64_libunwind_frame_sniffer (struct frame_info *next_frame) +{ + if (libunwind_is_initialized () && libunwind_frame_sniffer (next_frame)) + return &ia64_libunwind_frame_unwind; + + return NULL; +} + +/* Set of libunwind callback acccessor functions. */ +static unw_accessors_t ia64_unw_accessors = +{ + ia64_find_proc_info_x, + ia64_put_unwind_info, + ia64_get_dyn_info_list, + ia64_access_mem, + ia64_access_reg, + ia64_access_fpreg, + /* resume */ + /* get_proc_name */ +}; + +/* Set of ia64 gdb libunwind-frame callbacks and data for generic libunwind-frame code to use. */ +static struct libunwind_descr ia64_libunwind_descr = +{ + ia64_gdb2uw_regnum, + ia64_uw2gdb_regnum, + ia64_is_fpreg, + &ia64_unw_accessors, +}; + +#endif /* HAVE_LIBUNWIND_IA64_H */ + +/* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of + EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc and TYPE + is the type (which is known to be struct, union or array). */ int ia64_use_struct_convention (int gcc_p, struct type *type) { @@ -1373,154 +2698,72 @@ ia64_use_struct_convention (int gcc_p, struct type *type) /* HFAs are structures (or arrays) consisting entirely of floating point values of the same length. Up to 8 of these are returned in registers. Don't use the struct convention when this is the - case. */ + case. */ float_elt_type = is_float_or_hfa_type (type); if (float_elt_type != NULL && TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type) <= 8) return 0; /* Other structs of length 32 or less are returned in r8-r11. - Don't use the struct convention for those either. */ + Don't use the struct convention for those either. */ return TYPE_LENGTH (type) > 32; } void -ia64_extract_return_value (struct type *type, char *regbuf, char *valbuf) +ia64_extract_return_value (struct type *type, struct regcache *regcache, void *valbuf) { struct type *float_elt_type; float_elt_type = is_float_or_hfa_type (type); if (float_elt_type != NULL) { + char from[MAX_REGISTER_SIZE]; int offset = 0; int regnum = IA64_FR8_REGNUM; int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type); while (n-- > 0) { - ia64_register_convert_to_virtual (regnum, float_elt_type, - ®buf[REGISTER_BYTE (regnum)], valbuf + offset); + regcache_cooked_read (regcache, regnum, from); + convert_typed_floating (from, builtin_type_ia64_ext, + (char *)valbuf + offset, float_elt_type); offset += TYPE_LENGTH (float_elt_type); regnum++; } } else - memcpy (valbuf, ®buf[REGISTER_BYTE (IA64_GR8_REGNUM)], - TYPE_LENGTH (type)); -} + { + ULONGEST val; + int offset = 0; + int regnum = IA64_GR8_REGNUM; + int reglen = TYPE_LENGTH (ia64_register_type (NULL, IA64_GR8_REGNUM)); + int n = TYPE_LENGTH (type) / reglen; + int m = TYPE_LENGTH (type) % reglen; -/* FIXME: Turn this into a stack of some sort. Unfortunately, something - like this is necessary though since the IA-64 calling conventions specify - that r8 is not preserved. */ -static CORE_ADDR struct_return_address; + while (n-- > 0) + { + ULONGEST val; + regcache_cooked_read_unsigned (regcache, regnum, &val); + memcpy ((char *)valbuf + offset, &val, reglen); + offset += reglen; + regnum++; + } -CORE_ADDR -ia64_extract_struct_value_address (char *regbuf) -{ - /* FIXME: See above. */ - return struct_return_address; -} - -void -ia64_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - /* FIXME: See above. */ - /* Note that most of the work was done in ia64_push_arguments() */ - struct_return_address = addr; -} - -int -ia64_frameless_function_invocation (struct frame_info *frame) -{ - FRAME_INIT_SAVED_REGS (frame); - return (frame->extra_info->mem_stack_frame_size == 0); + if (m) + { + regcache_cooked_read_unsigned (regcache, regnum, &val); + memcpy ((char *)valbuf + offset, &val, m); + } + } } CORE_ADDR -ia64_saved_pc_after_call (struct frame_info *frame) +ia64_extract_struct_value_address (struct regcache *regcache) { - return read_register (IA64_BR0_REGNUM); + error ("ia64_extract_struct_value_address called and cannot get struct value address"); + return 0; } -CORE_ADDR -ia64_frame_args_address (struct frame_info *frame) -{ - /* frame->frame points at the SP for this frame; But we want the start - of the frame, not the end. Calling frame chain will get his for us. */ - return ia64_frame_chain (frame); -} - -CORE_ADDR -ia64_frame_locals_address (struct frame_info *frame) -{ - /* frame->frame points at the SP for this frame; But we want the start - of the frame, not the end. Calling frame chain will get his for us. */ - return ia64_frame_chain (frame); -} - -void -ia64_init_extra_frame_info (int fromleaf, struct frame_info *frame) -{ - CORE_ADDR bsp, cfm; - int next_frame_is_call_dummy = ((frame->next != NULL) - && PC_IN_CALL_DUMMY (frame->next->pc, frame->next->frame, - frame->next->frame)); - - frame->extra_info = (struct frame_extra_info *) - frame_obstack_alloc (sizeof (struct frame_extra_info)); - - if (frame->next == 0) - { - bsp = read_register (IA64_BSP_REGNUM); - cfm = read_register (IA64_CFM_REGNUM); - - } - else if (frame->next->signal_handler_caller) - { - bsp = read_sigcontext_register (frame->next, IA64_BSP_REGNUM); - cfm = read_sigcontext_register (frame->next, IA64_CFM_REGNUM); - } - else if (next_frame_is_call_dummy) - { - bsp = generic_read_register_dummy (frame->next->pc, frame->next->frame, - IA64_BSP_REGNUM); - cfm = generic_read_register_dummy (frame->next->pc, frame->next->frame, - IA64_CFM_REGNUM); - } - else - { - struct frame_info *frn = frame->next; - - FRAME_INIT_SAVED_REGS (frn); - - if (frn->saved_regs[IA64_CFM_REGNUM] != 0) - cfm = read_memory_integer (frn->saved_regs[IA64_CFM_REGNUM], 8); - else if (frn->next && frn->next->signal_handler_caller) - cfm = read_sigcontext_register (frn->next, IA64_PFS_REGNUM); - else if (frn->next - && PC_IN_CALL_DUMMY (frn->next->pc, frn->next->frame, - frn->next->frame)) - cfm = generic_read_register_dummy (frn->next->pc, frn->next->frame, - IA64_PFS_REGNUM); - else - cfm = read_register (IA64_PFS_REGNUM); - - bsp = frn->extra_info->bsp; - } - frame->extra_info->cfm = cfm; - frame->extra_info->sof = cfm & 0x7f; - frame->extra_info->sol = (cfm >> 7) & 0x7f; - if (frame->next == 0 - || frame->next->signal_handler_caller - || next_frame_is_call_dummy) - frame->extra_info->bsp = rse_address_add (bsp, -frame->extra_info->sof); - else - frame->extra_info->bsp = rse_address_add (bsp, -frame->extra_info->sol); - - frame->extra_info->after_prologue = 0; - frame->extra_info->mem_stack_frame_size = -1; /* Not yet determined */ - frame->extra_info->fp_reg = 0; -} static int is_float_or_hfa_type_recurse (struct type *t, struct type **etp) @@ -1560,7 +2803,7 @@ is_float_or_hfa_type_recurse (struct type *t, struct type **etp) /* Determine if the given type is one of the floating point types or and HFA (which is a struct, array, or combination thereof whose - bottom-most elements are all of the same floating point type.) */ + bottom-most elements are all of the same floating point type). */ static struct type * is_float_or_hfa_type (struct type *t) @@ -1574,7 +2817,7 @@ is_float_or_hfa_type (struct type *t) /* Return 1 if the alignment of T is such that the next even slot should be used. Return 0, if the next available slot should be used. (See section 8.5.1 of the IA-64 Software Conventions - and Runtime manual.) */ + and Runtime manual). */ static int slot_alignment_is_next_even (struct type *t) @@ -1654,7 +2897,7 @@ generic_elf_find_global_pointer (CORE_ADDR faddr) status = target_read_memory (addr + 8, buf, sizeof (buf)); if (status != 0) break; - global_pointer = extract_address (buf, sizeof (buf)); + global_pointer = extract_unsigned_integer (buf, sizeof (buf)); /* The payoff... */ return global_pointer; @@ -1672,13 +2915,13 @@ generic_elf_find_global_pointer (CORE_ADDR faddr) /* Given a function's address, attempt to find (and return) the corresponding (canonical) function descriptor. Return 0 if - not found. */ + not found. */ static CORE_ADDR find_extant_func_descr (CORE_ADDR faddr) { struct obj_section *faddr_sect; - /* Return early if faddr is already a function descriptor */ + /* Return early if faddr is already a function descriptor. */ faddr_sect = find_pc_section (faddr); if (faddr_sect && strcmp (faddr_sect->the_bfd_section->name, ".opd") == 0) return faddr; @@ -1720,7 +2963,7 @@ find_extant_func_descr (CORE_ADDR faddr) /* Attempt to find a function descriptor corresponding to the given address. If none is found, construct one on the - stack using the address at fdaptr */ + stack using the address at fdaptr. */ static CORE_ADDR find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr) @@ -1742,8 +2985,8 @@ find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr) if (global_pointer == 0) global_pointer = read_register (IA64_GR1_REGNUM); - store_address (buf, 8, faddr); - store_address (buf + 8, 8, global_pointer); + store_unsigned_integer (buf, 8, faddr); + store_unsigned_integer (buf + 8, 8, global_pointer); write_memory (fdesc, buf, 16); } @@ -1751,9 +2994,35 @@ find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr) return fdesc; } -CORE_ADDR -ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) +/* Use the following routine when printing out function pointers + so the user can see the function address rather than just the + function descriptor. */ +static CORE_ADDR +ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr, + struct target_ops *targ) +{ + struct obj_section *s; + + s = find_pc_section (addr); + + /* check if ADDR points to a function descriptor. */ + if (s && strcmp (s->the_bfd_section->name, ".opd") == 0) + return read_memory_unsigned_integer (addr, 8); + + return addr; +} + +static CORE_ADDR +ia64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) +{ + return sp & ~0xfLL; +} + +static CORE_ADDR +ia64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) { int argno; struct value *arg; @@ -1761,11 +3030,11 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int len, argoffset; int nslots, rseslots, memslots, slotnum, nfuncargs; int floatreg; - CORE_ADDR bsp, cfm, pfs, new_bsp, funcdescaddr; + CORE_ADDR bsp, cfm, pfs, new_bsp, funcdescaddr, pc, global_pointer; nslots = 0; nfuncargs = 0; - /* Count the number of slots needed for the arguments */ + /* Count the number of slots needed for the arguments. */ for (argno = 0; argno < nargs; argno++) { arg = args[argno]; @@ -1781,15 +3050,14 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, nslots += (len + 7) / 8; } - /* Divvy up the slots between the RSE and the memory stack */ + /* Divvy up the slots between the RSE and the memory stack. */ rseslots = (nslots > 8) ? 8 : nslots; memslots = nslots - rseslots; - /* Allocate a new RSE frame */ + /* Allocate a new RSE frame. */ cfm = read_register (IA64_CFM_REGNUM); bsp = read_register (IA64_BSP_REGNUM); - bsp = rse_address_add (bsp, cfm & 0x7f); new_bsp = rse_address_add (bsp, rseslots); write_register (IA64_BSP_REGNUM, new_bsp); @@ -1804,20 +3072,20 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, /* We will attempt to find function descriptors in the .opd segment, but if we can't we'll construct them ourselves. That being the - case, we'll need to reserve space on the stack for them. */ + case, we'll need to reserve space on the stack for them. */ funcdescaddr = sp - nfuncargs * 16; funcdescaddr &= ~0xfLL; /* Adjust the stack pointer to it's new value. The calling conventions require us to have 16 bytes of scratch, plus whatever space is - necessary for the memory slots and our function descriptors */ + necessary for the memory slots and our function descriptors. */ sp = sp - 16 - (memslots + nfuncargs) * 8; - sp &= ~0xfLL; /* Maintain 16 byte alignment */ + sp &= ~0xfLL; /* Maintain 16 byte alignment. */ /* Place the arguments where they belong. The arguments will be either placed in the RSE backing store or on the memory stack. In addition, floating point arguments or HFAs are placed in - floating point registers. */ + floating point registers. */ slotnum = 0; floatreg = IA64_FR8_REGNUM; for (argno = 0; argno < nargs; argno++) @@ -1828,16 +3096,16 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, type = check_typedef (VALUE_TYPE (arg)); len = TYPE_LENGTH (type); - /* Special handling for function parameters */ + /* Special handling for function parameters. */ if (len == 8 && TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC) { char val_buf[8]; - store_address (val_buf, 8, - find_func_descr (extract_address (VALUE_CONTENTS (arg), 8), - &funcdescaddr)); + store_unsigned_integer (val_buf, 8, + find_func_descr (extract_unsigned_integer (VALUE_CONTENTS (arg), 8), + &funcdescaddr)); if (slotnum < rseslots) write_memory (rse_address_add (bsp, slotnum), val_buf, 8); else @@ -1846,7 +3114,7 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, continue; } - /* Normal slots */ + /* Normal slots. */ /* Skip odd slot if necessary... */ if ((slotnum & 1) && slot_alignment_is_next_even (type)) @@ -1870,7 +3138,7 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, slotnum++; } - /* Handle floating point types (including HFAs) */ + /* Handle floating point types (including HFAs). */ float_elt_type = is_float_or_hfa_type (type); if (float_elt_type != NULL) { @@ -1878,11 +3146,10 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, len = TYPE_LENGTH (type); while (len > 0 && floatreg < IA64_FR16_REGNUM) { - ia64_register_convert_to_raw ( - float_elt_type, - floatreg, - VALUE_CONTENTS (arg) + argoffset, - ®isters[REGISTER_BYTE (floatreg)]); + char to[MAX_REGISTER_SIZE]; + convert_typed_floating (VALUE_CONTENTS (arg) + argoffset, float_elt_type, + to, builtin_type_ia64_ext); + regcache_cooked_write (regcache, floatreg, (void *)to); floatreg++; argoffset += TYPE_LENGTH (float_elt_type); len -= TYPE_LENGTH (float_elt_type); @@ -1890,174 +3157,89 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, } } - /* Store the struct return value in r8 if necessary. */ + /* Store the struct return value in r8 if necessary. */ if (struct_return) { - store_address (®isters[REGISTER_BYTE (IA64_GR8_REGNUM)], - REGISTER_RAW_SIZE (IA64_GR8_REGNUM), - struct_addr); + regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM, (ULONGEST)struct_addr); } - /* Sync gdb's idea of what the registers are with the target. */ - target_store_registers (-1); - - /* FIXME: This doesn't belong here! Instead, SAVE_DUMMY_FRAME_TOS needs - to be defined to call generic_save_dummy_frame_tos(). But at the - time of this writing, SAVE_DUMMY_FRAME_TOS wasn't gdbarch'd, so - I chose to put this call here instead of using the old mechanisms. - Once SAVE_DUMMY_FRAME_TOS is gdbarch'd, all we need to do is add the - line - - set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); - - to ia64_gdbarch_init() and remove the line below. */ - generic_save_dummy_frame_tos (sp); - - return sp; -} - -CORE_ADDR -ia64_push_return_address (CORE_ADDR pc, CORE_ADDR sp) -{ - CORE_ADDR global_pointer = FIND_GLOBAL_POINTER (pc); + global_pointer = FIND_GLOBAL_POINTER (func_addr); if (global_pointer != 0) write_register (IA64_GR1_REGNUM, global_pointer); - write_register (IA64_BR0_REGNUM, CALL_DUMMY_ADDRESS ()); + write_register (IA64_BR0_REGNUM, bp_addr); + + write_register (sp_regnum, sp); + return sp; } -void -ia64_store_return_value (struct type *type, char *valbuf) +static struct frame_id +ia64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + char buf[8]; + CORE_ADDR sp, bsp; + + frame_unwind_register (next_frame, sp_regnum, buf); + sp = extract_unsigned_integer (buf, 8); + + frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf); + bsp = extract_unsigned_integer (buf, 8); + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, + "dummy frame id: code 0x%s, stack 0x%s, special 0x%s\n", + paddr_nz (frame_pc_unwind (next_frame)), + paddr_nz (sp), paddr_nz (bsp)); + + return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp); +} + +static CORE_ADDR +ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + char buf[8]; + CORE_ADDR ip, psr, pc; + + frame_unwind_register (next_frame, IA64_IP_REGNUM, buf); + ip = extract_unsigned_integer (buf, 8); + frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf); + psr = extract_unsigned_integer (buf, 8); + + pc = (ip & ~0xf) | ((psr >> 41) & 3); + return pc; +} + +static void +ia64_store_return_value (struct type *type, struct regcache *regcache, const void *valbuf) { if (TYPE_CODE (type) == TYPE_CODE_FLT) { - ia64_register_convert_to_raw (type, IA64_FR8_REGNUM, valbuf, - ®isters[REGISTER_BYTE (IA64_FR8_REGNUM)]); + char to[MAX_REGISTER_SIZE]; + convert_typed_floating (valbuf, type, to, builtin_type_ia64_ext); + regcache_cooked_write (regcache, IA64_FR8_REGNUM, (void *)to); target_store_registers (IA64_FR8_REGNUM); } else - write_register_bytes (REGISTER_BYTE (IA64_GR8_REGNUM), - valbuf, TYPE_LENGTH (type)); -} - -void -ia64_pop_frame (void) -{ - generic_pop_current_frame (ia64_pop_frame_regular); + regcache_cooked_write (regcache, IA64_GR8_REGNUM, valbuf); } static void -ia64_pop_frame_regular (struct frame_info *frame) -{ - int regno; - CORE_ADDR bsp, cfm, pfs; - - FRAME_INIT_SAVED_REGS (frame); - - for (regno = 0; regno < ia64_num_regs; regno++) - { - if (frame->saved_regs[regno] - && (!(IA64_GR32_REGNUM <= regno && regno <= IA64_GR127_REGNUM)) - && regno != pc_regnum - && regno != sp_regnum - && regno != IA64_PFS_REGNUM - && regno != IA64_CFM_REGNUM - && regno != IA64_BSP_REGNUM - && regno != IA64_BSPSTORE_REGNUM) - { - write_register (regno, - read_memory_integer (frame->saved_regs[regno], - REGISTER_RAW_SIZE (regno))); - } - } - - write_register (sp_regnum, FRAME_CHAIN (frame)); - write_pc (FRAME_SAVED_PC (frame)); - - cfm = read_register (IA64_CFM_REGNUM); - - if (frame->saved_regs[IA64_PFS_REGNUM]) - { - pfs = read_memory_integer (frame->saved_regs[IA64_PFS_REGNUM], - REGISTER_RAW_SIZE (IA64_PFS_REGNUM)); - } - else - pfs = read_register (IA64_PFS_REGNUM); - - /* Compute the new bsp by *adding* the difference between the - size of the frame and the size of the locals (both wrt the - frame that we're going back to). This seems kind of strange, - especially since it seems like we ought to be subtracting the - size of the locals... and we should; but the Linux kernel - wants bsp to be set at the end of all used registers. It's - likely that this code will need to be revised to accomodate - other operating systems. */ - bsp = rse_address_add (frame->extra_info->bsp, - (pfs & 0x7f) - ((pfs >> 7) & 0x7f)); - write_register (IA64_BSP_REGNUM, bsp); - - /* FIXME: What becomes of the epilog count in the PFS? */ - cfm = (cfm & ~0xffffffffffffLL) | (pfs & 0xffffffffffffLL); - write_register (IA64_CFM_REGNUM, cfm); - - flush_cached_frames (); -} - -static void -ia64_remote_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes, +ia64_remote_translate_xfer_address (struct gdbarch *gdbarch, + struct regcache *regcache, + CORE_ADDR memaddr, int nr_bytes, CORE_ADDR *targ_addr, int *targ_len) { *targ_addr = memaddr; *targ_len = nr_bytes; } -static void -process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) +static int +ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info) { - int *os_ident_ptr = obj; - const char *name; - unsigned int sectsize; - - name = bfd_get_section_name (abfd, sect); - sectsize = bfd_section_size (abfd, sect); - if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0) - { - unsigned int name_length, data_length, note_type; - char *note = alloca (sectsize); - - bfd_get_section_contents (abfd, sect, note, - (file_ptr) 0, (bfd_size_type) sectsize); - - name_length = bfd_h_get_32 (abfd, note); - data_length = bfd_h_get_32 (abfd, note + 4); - note_type = bfd_h_get_32 (abfd, note + 8); - - if (name_length == 4 && data_length == 16 && note_type == 1 - && strcmp (note + 12, "GNU") == 0) - { - int os_number = bfd_h_get_32 (abfd, note + 16); - - /* The case numbers are from abi-tags in glibc */ - switch (os_number) - { - case 0 : - *os_ident_ptr = ELFOSABI_LINUX; - break; - case 1 : - *os_ident_ptr = ELFOSABI_HURD; - break; - case 2 : - *os_ident_ptr = ELFOSABI_SOLARIS; - break; - default : - internal_error (__FILE__, __LINE__, - "process_note_abi_sections: unknown OS number %d", os_number); - break; - } - } - } + info->bytes_per_line = SLOT_MULTIPLIER; + return print_insn_ia64 (memaddr, info); } static struct gdbarch * @@ -2065,48 +3247,21 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; struct gdbarch_tdep *tdep; - int os_ident; - if (info.abfd != NULL - && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) - { - os_ident = elf_elfheader (info.abfd)->e_ident[EI_OSABI]; - - /* If os_ident is 0, it is not necessarily the case that we're - on a SYSV system. (ELFOSABI_NONE is defined to be 0.) - GNU/Linux uses a note section to record OS/ABI info, but - leaves e_ident[EI_OSABI] zero. So we have to check for note - sections too. */ - if (os_ident == 0) - { - bfd_map_over_sections (info.abfd, - process_note_abi_tag_sections, - &os_ident); - } - } - else - os_ident = -1; - - for (arches = gdbarch_list_lookup_by_info (arches, &info); - arches != NULL; - arches = gdbarch_list_lookup_by_info (arches->next, &info)) - { - tdep = gdbarch_tdep (arches->gdbarch); - if (tdep &&tdep->os_ident == os_ident) - return arches->gdbarch; - } + /* If there is already a candidate, use it. */ + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != NULL) + return arches->gdbarch; tdep = xmalloc (sizeof (struct gdbarch_tdep)); gdbarch = gdbarch_alloc (&info, tdep); - tdep->os_ident = os_ident; - /* Set the method of obtaining the sigcontext addresses at which registers are saved. The method of checking to see if native_find_global_pointer is nonzero to indicate that we're on AIX is kind of hokey, but I can't think of a better way to do it. */ - if (os_ident == ELFOSABI_LINUX) + if (info.osabi == GDB_OSABI_LINUX) tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address; else if (native_find_global_pointer != 0) tdep->sigcontext_register_address = ia64_aix_sigcontext_register_address; @@ -2120,121 +3275,104 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) generic_elf_find_global_pointer. This arrangement should (in theory) allow us to cross debug GNU/Linux binaries from an AIX machine. */ - if (os_ident == ELFOSABI_LINUX) + if (info.osabi == GDB_OSABI_LINUX) tdep->find_global_pointer = generic_elf_find_global_pointer; else if (native_find_global_pointer != 0) tdep->find_global_pointer = native_find_global_pointer; else tdep->find_global_pointer = generic_elf_find_global_pointer; + /* Define the ia64 floating-point format to gdb. */ + builtin_type_ia64_ext = + init_type (TYPE_CODE_FLT, 128 / 8, + 0, "builtin_type_ia64_ext", NULL); + TYPE_FLOATFORMAT (builtin_type_ia64_ext) = &floatformat_ia64_ext; + + /* According to the ia64 specs, instructions that store long double + floats in memory use a long-double format different than that + used in the floating registers. The memory format matches the + x86 extended float format which is 80 bits. An OS may choose to + use this format (e.g. GNU/Linux) or choose to use a different + format for storing long doubles (e.g. HPUX). In the latter case, + the setting of the format may be moved/overridden in an + OS-specific tdep file. */ + set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext); + set_gdbarch_short_bit (gdbarch, 16); set_gdbarch_int_bit (gdbarch, 32); set_gdbarch_long_bit (gdbarch, 64); set_gdbarch_long_long_bit (gdbarch, 64); set_gdbarch_float_bit (gdbarch, 32); set_gdbarch_double_bit (gdbarch, 64); - set_gdbarch_long_double_bit (gdbarch, 64); + set_gdbarch_long_double_bit (gdbarch, 128); set_gdbarch_ptr_bit (gdbarch, 64); - set_gdbarch_num_regs (gdbarch, ia64_num_regs); + set_gdbarch_num_regs (gdbarch, NUM_IA64_RAW_REGS); + set_gdbarch_num_pseudo_regs (gdbarch, LAST_PSEUDO_REGNUM - FIRST_PSEUDO_REGNUM); set_gdbarch_sp_regnum (gdbarch, sp_regnum); - set_gdbarch_fp_regnum (gdbarch, fp_regnum); - set_gdbarch_pc_regnum (gdbarch, pc_regnum); set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM); set_gdbarch_register_name (gdbarch, ia64_register_name); - set_gdbarch_register_size (gdbarch, 8); - set_gdbarch_register_bytes (gdbarch, ia64_num_regs * 8 + 128*8); - set_gdbarch_register_byte (gdbarch, ia64_register_byte); - set_gdbarch_register_raw_size (gdbarch, ia64_register_raw_size); - set_gdbarch_max_register_raw_size (gdbarch, 16); - set_gdbarch_register_virtual_size (gdbarch, ia64_register_virtual_size); - set_gdbarch_max_register_virtual_size (gdbarch, 16); - set_gdbarch_register_virtual_type (gdbarch, ia64_register_virtual_type); + /* FIXME: Following interface should not be needed, however, without it recurse.exp + gets a number of extra failures. */ + set_gdbarch_deprecated_register_size (gdbarch, 8); + set_gdbarch_register_type (gdbarch, ia64_register_type); + + set_gdbarch_pseudo_register_read (gdbarch, ia64_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, ia64_pseudo_register_write); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, ia64_dwarf_reg_to_regnum); + set_gdbarch_register_reggroup_p (gdbarch, ia64_register_reggroup_p); + set_gdbarch_convert_register_p (gdbarch, ia64_convert_register_p); + set_gdbarch_register_to_value (gdbarch, ia64_register_to_value); + set_gdbarch_value_to_register (gdbarch, ia64_value_to_register); set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue); - set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); - set_gdbarch_frameless_function_invocation (gdbarch, ia64_frameless_function_invocation); - - set_gdbarch_saved_pc_after_call (gdbarch, ia64_saved_pc_after_call); - - set_gdbarch_frame_chain (gdbarch, ia64_frame_chain); - set_gdbarch_frame_chain_valid (gdbarch, generic_func_frame_chain_valid); - set_gdbarch_frame_saved_pc (gdbarch, ia64_frame_saved_pc); - - set_gdbarch_frame_init_saved_regs (gdbarch, ia64_frame_init_saved_regs); - set_gdbarch_get_saved_register (gdbarch, ia64_get_saved_register); - - set_gdbarch_register_convertible (gdbarch, ia64_register_convertible); - set_gdbarch_register_convert_to_virtual (gdbarch, ia64_register_convert_to_virtual); - set_gdbarch_register_convert_to_raw (gdbarch, ia64_register_convert_to_raw); - set_gdbarch_use_struct_convention (gdbarch, ia64_use_struct_convention); set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value); - set_gdbarch_store_struct_return (gdbarch, ia64_store_struct_return); set_gdbarch_store_return_value (gdbarch, ia64_store_return_value); - set_gdbarch_extract_struct_value_address (gdbarch, ia64_extract_struct_value_address); + set_gdbarch_deprecated_extract_struct_value_address (gdbarch, ia64_extract_struct_value_address); set_gdbarch_memory_insert_breakpoint (gdbarch, ia64_memory_insert_breakpoint); set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint); set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc); set_gdbarch_read_pc (gdbarch, ia64_read_pc); - set_gdbarch_write_pc (gdbarch, ia64_write_pc); + if (info.osabi == GDB_OSABI_LINUX) + set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc); + else + set_gdbarch_write_pc (gdbarch, ia64_write_pc); /* Settings for calling functions in the inferior. */ - set_gdbarch_use_generic_dummy_frames (gdbarch, 1); - set_gdbarch_call_dummy_length (gdbarch, 0); - set_gdbarch_push_arguments (gdbarch, ia64_push_arguments); - set_gdbarch_push_return_address (gdbarch, ia64_push_return_address); - set_gdbarch_pop_frame (gdbarch, ia64_pop_frame); + set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call); + set_gdbarch_frame_align (gdbarch, ia64_frame_align); + set_gdbarch_unwind_dummy_id (gdbarch, ia64_unwind_dummy_id); - set_gdbarch_call_dummy_p (gdbarch, 1); - set_gdbarch_call_dummy_words (gdbarch, ia64_call_dummy_words); - set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (ia64_call_dummy_words)); - set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); - set_gdbarch_init_extra_frame_info (gdbarch, ia64_init_extra_frame_info); - set_gdbarch_frame_args_address (gdbarch, ia64_frame_args_address); - set_gdbarch_frame_locals_address (gdbarch, ia64_frame_locals_address); - - /* We won't necessarily have a frame pointer and even if we do, - it winds up being extraordinarly messy when attempting to find - the frame chain. So for the purposes of creating frames (which - is all read_fp() is used for), simply use the stack pointer value - instead. */ - set_gdbarch_read_fp (gdbarch, generic_target_read_sp); - set_gdbarch_write_fp (gdbarch, generic_target_write_sp); + set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc); + frame_unwind_append_sniffer (gdbarch, ia64_sigtramp_frame_sniffer); +#ifdef HAVE_LIBUNWIND_IA64_H + frame_unwind_append_sniffer (gdbarch, ia64_libunwind_frame_sniffer); + libunwind_frame_set_descr (gdbarch, &ia64_libunwind_descr); +#endif + frame_unwind_append_sniffer (gdbarch, ia64_frame_sniffer); + frame_base_set_default (gdbarch, &ia64_frame_base); /* Settings that should be unnecessary. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_read_sp (gdbarch, generic_target_read_sp); - set_gdbarch_write_sp (gdbarch, generic_target_write_sp); - - set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT); - set_gdbarch_call_dummy_address (gdbarch, entry_point_address); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0); - set_gdbarch_call_dummy_start_offset (gdbarch, 0); - set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy); - set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); - set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame); - set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy); - - set_gdbarch_decr_pc_after_break (gdbarch, 0); - set_gdbarch_function_start_offset (gdbarch, 0); - set_gdbarch_remote_translate_xfer_address ( gdbarch, ia64_remote_translate_xfer_address); + set_gdbarch_print_insn (gdbarch, ia64_print_insn); + set_gdbarch_convert_from_func_ptr_addr (gdbarch, ia64_convert_from_func_ptr_addr); + return gdbarch; } +extern initialize_file_ftype _initialize_ia64_tdep; /* -Wmissing-prototypes */ + void _initialize_ia64_tdep (void) { register_gdbarch_init (bfd_arch_ia64, ia64_gdbarch_init); - - tm_print_insn = print_insn_ia64; - tm_print_insn_info.bytes_per_line = SLOT_MULTIPLIER; } diff --git a/contrib/gdb/gdb/ia64-tdep.h b/contrib/gdb/gdb/ia64-tdep.h new file mode 100644 index 00000000000..e153eed580c --- /dev/null +++ b/contrib/gdb/gdb/ia64-tdep.h @@ -0,0 +1,31 @@ +/* Target-dependent code for the ia64. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef IA64_TDEP_H +#define IA64_TDEP_H + +extern CORE_ADDR ia64_linux_sigcontext_register_address (CORE_ADDR, int); +extern CORE_ADDR ia64_aix_sigcontext_register_address (CORE_ADDR, int); +extern unsigned long ia64_linux_getunwind_table (void *, size_t); +extern void ia64_write_pc (CORE_ADDR, ptid_t); +extern void ia64_linux_write_pc (CORE_ADDR, ptid_t); + +#endif /* IA64_TDEP_H */ diff --git a/contrib/gdb/gdb/infcall.c b/contrib/gdb/gdb/infcall.c new file mode 100644 index 00000000000..11ce018087c --- /dev/null +++ b/contrib/gdb/gdb/infcall.c @@ -0,0 +1,1103 @@ +/* Perform an inferior function call, for GDB, the GNU debugger. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "breakpoint.h" +#include "target.h" +#include "regcache.h" +#include "inferior.h" +#include "gdb_assert.h" +#include "block.h" +#include "gdbcore.h" +#include "language.h" +#include "objfiles.h" +#include "gdbcmd.h" +#include "command.h" +#include "gdb_string.h" +#include "infcall.h" + +/* NOTE: cagney/2003-04-16: What's the future of this code? + + GDB needs an asynchronous expression evaluator, that means an + asynchronous inferior function call implementation, and that in + turn means restructuring the code so that it is event driven. */ + +/* How you should pass arguments to a function depends on whether it + was defined in K&R style or prototype style. If you define a + function using the K&R syntax that takes a `float' argument, then + callers must pass that argument as a `double'. If you define the + function using the prototype syntax, then you must pass the + argument as a `float', with no promotion. + + Unfortunately, on certain older platforms, the debug info doesn't + indicate reliably how each function was defined. A function type's + TYPE_FLAG_PROTOTYPED flag may be clear, even if the function was + defined in prototype style. When calling a function whose + TYPE_FLAG_PROTOTYPED flag is clear, GDB consults this flag to + decide what to do. + + For modern targets, it is proper to assume that, if the prototype + flag is clear, that can be trusted: `float' arguments should be + promoted to `double'. For some older targets, if the prototype + flag is clear, that doesn't tell us anything. The default is to + trust the debug information; the user can override this behavior + with "set coerce-float-to-double 0". */ + +static int coerce_float_to_double_p = 1; + +/* This boolean tells what gdb should do if a signal is received while + in a function called from gdb (call dummy). If set, gdb unwinds + the stack and restore the context to what as it was before the + call. + + The default is to stop in the frame where the signal was received. */ + +int unwind_on_signal_p = 0; + +/* Perform the standard coercions that are specified + for arguments to be passed to C functions. + + If PARAM_TYPE is non-NULL, it is the expected parameter type. + IS_PROTOTYPED is non-zero if the function declaration is prototyped. */ + +static struct value * +value_arg_coerce (struct value *arg, struct type *param_type, + int is_prototyped) +{ + struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + struct type *type + = param_type ? check_typedef (param_type) : arg_type; + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_REF: + if (TYPE_CODE (arg_type) != TYPE_CODE_REF + && TYPE_CODE (arg_type) != TYPE_CODE_PTR) + { + arg = value_addr (arg); + VALUE_TYPE (arg) = param_type; + return arg; + } + break; + case TYPE_CODE_INT: + case TYPE_CODE_CHAR: + case TYPE_CODE_BOOL: + case TYPE_CODE_ENUM: + /* If we don't have a prototype, coerce to integer type if necessary. */ + if (!is_prototyped) + { + if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) + type = builtin_type_int; + } + /* Currently all target ABIs require at least the width of an integer + type for an argument. We may have to conditionalize the following + type coercion for future targets. */ + if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) + type = builtin_type_int; + break; + case TYPE_CODE_FLT: + if (!is_prototyped && coerce_float_to_double_p) + { + if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) + type = builtin_type_double; + else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double)) + type = builtin_type_long_double; + } + break; + case TYPE_CODE_FUNC: + type = lookup_pointer_type (type); + break; + case TYPE_CODE_ARRAY: + /* Arrays are coerced to pointers to their first element, unless + they are vectors, in which case we want to leave them alone, + because they are passed by value. */ + if (current_language->c_style_arrays) + if (!TYPE_VECTOR (type)) + type = lookup_pointer_type (TYPE_TARGET_TYPE (type)); + break; + case TYPE_CODE_UNDEF: + case TYPE_CODE_PTR: + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_VOID: + case TYPE_CODE_SET: + case TYPE_CODE_RANGE: + case TYPE_CODE_STRING: + case TYPE_CODE_BITSTRING: + case TYPE_CODE_ERROR: + case TYPE_CODE_MEMBER: + case TYPE_CODE_METHOD: + case TYPE_CODE_COMPLEX: + default: + break; + } + + return value_cast (type, arg); +} + +/* Determine a function's address and its return type from its value. + Calls error() if the function is not valid for calling. */ + +CORE_ADDR +find_function_addr (struct value *function, struct type **retval_type) +{ + struct type *ftype = check_typedef (VALUE_TYPE (function)); + enum type_code code = TYPE_CODE (ftype); + struct type *value_type; + CORE_ADDR funaddr; + + /* If it's a member function, just look at the function + part of it. */ + + /* Determine address to call. */ + if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD) + { + funaddr = VALUE_ADDRESS (function); + value_type = TYPE_TARGET_TYPE (ftype); + } + else if (code == TYPE_CODE_PTR) + { + funaddr = value_as_address (function); + ftype = check_typedef (TYPE_TARGET_TYPE (ftype)); + if (TYPE_CODE (ftype) == TYPE_CODE_FUNC + || TYPE_CODE (ftype) == TYPE_CODE_METHOD) + { + funaddr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, + funaddr, + ¤t_target); + value_type = TYPE_TARGET_TYPE (ftype); + } + else + value_type = builtin_type_int; + } + else if (code == TYPE_CODE_INT) + { + /* Handle the case of functions lacking debugging info. + Their values are characters since their addresses are char */ + if (TYPE_LENGTH (ftype) == 1) + funaddr = value_as_address (value_addr (function)); + else + /* Handle integer used as address of a function. */ + funaddr = (CORE_ADDR) value_as_long (function); + + value_type = builtin_type_int; + } + else + error ("Invalid data type for function to be called."); + + *retval_type = value_type; + return funaddr; +} + +/* Call breakpoint_auto_delete on the current contents of the bpstat + pointed to by arg (which is really a bpstat *). */ + +static void +breakpoint_auto_delete_contents (void *arg) +{ + breakpoint_auto_delete (*(bpstat *) arg); +} + +static CORE_ADDR +legacy_push_dummy_code (struct gdbarch *gdbarch, + CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, + struct value **args, int nargs, + struct type *value_type, + CORE_ADDR *real_pc, CORE_ADDR *bp_addr) +{ + /* CALL_DUMMY is an array of words (DEPRECATED_REGISTER_SIZE), but + each word is in host byte order. Before calling + DEPRECATED_FIX_CALL_DUMMY, we byteswap it and remove any extra + bytes which might exist because ULONGEST is bigger than + DEPRECATED_REGISTER_SIZE. */ + /* NOTE: This is pretty wierd, as the call dummy is actually a + sequence of instructions. But CISC machines will have to pack + the instructions into DEPRECATED_REGISTER_SIZE units (and so will + RISC machines for which INSTRUCTION_SIZE is not + DEPRECATED_REGISTER_SIZE). */ + /* NOTE: This is pretty stupid. CALL_DUMMY should be in strict + target byte order. */ + CORE_ADDR start_sp; + ULONGEST *dummy = alloca (DEPRECATED_SIZEOF_CALL_DUMMY_WORDS); + int sizeof_dummy1 = (DEPRECATED_REGISTER_SIZE + * DEPRECATED_SIZEOF_CALL_DUMMY_WORDS + / sizeof (ULONGEST)); + char *dummy1 = alloca (sizeof_dummy1); + memcpy (dummy, DEPRECATED_CALL_DUMMY_WORDS, + DEPRECATED_SIZEOF_CALL_DUMMY_WORDS); + if (INNER_THAN (1, 2)) + { + /* Stack grows down */ + sp -= sizeof_dummy1; + start_sp = sp; + } + else + { + /* Stack grows up */ + start_sp = sp; + sp += sizeof_dummy1; + } + /* NOTE: cagney/2002-09-10: Don't bother re-adjusting the stack + after allocating space for the call dummy. A target can specify + a SIZEOF_DUMMY1 (via DEPRECATED_SIZEOF_CALL_DUMMY_WORDS) such + that all local alignment requirements are met. */ + /* Create a call sequence customized for this function and the + number of arguments for it. */ + { + int i; + for (i = 0; i < (int) (DEPRECATED_SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); + i++) + store_unsigned_integer (&dummy1[i * DEPRECATED_REGISTER_SIZE], + DEPRECATED_REGISTER_SIZE, + (ULONGEST) dummy[i]); + } + /* NOTE: cagney/2003-04-22: This computation of REAL_PC, BP_ADDR and + DUMMY_ADDR is pretty messed up. It comes from constant tinkering + with the values. Instead a DEPRECATED_FIX_CALL_DUMMY replacement + (PUSH_DUMMY_BREAKPOINT?) should just do everything. */ + if (!gdbarch_push_dummy_call_p (current_gdbarch)) + { +#ifdef GDB_TARGET_IS_HPPA + (*real_pc) = DEPRECATED_FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, + args, value_type, using_gcc); +#else + if (DEPRECATED_FIX_CALL_DUMMY_P ()) + { + /* gdb_assert (CALL_DUMMY_LOCATION == ON_STACK) true? */ + DEPRECATED_FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, + value_type, using_gcc); + } + (*real_pc) = start_sp; +#endif + } + /* Yes, the offset is applied to the real_pc and not the dummy addr. + Ulgh! Blame the HP/UX target. */ + (*bp_addr) = (*real_pc) + DEPRECATED_CALL_DUMMY_BREAKPOINT_OFFSET; + /* Yes, the offset is applied to the real_pc and not the + dummy_addr. Ulgh! Blame the HP/UX target. */ + (*real_pc) += DEPRECATED_CALL_DUMMY_START_OFFSET; + write_memory (start_sp, (char *) dummy1, sizeof_dummy1); + if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) + generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1); + return sp; +} + +static CORE_ADDR +generic_push_dummy_code (struct gdbarch *gdbarch, + CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, + struct value **args, int nargs, + struct type *value_type, + CORE_ADDR *real_pc, CORE_ADDR *bp_addr) +{ + /* Something here to findout the size of a breakpoint and then + allocate space for it on the stack. */ + int bplen; + /* This code assumes frame align. */ + gdb_assert (gdbarch_frame_align_p (gdbarch)); + /* Force the stack's alignment. The intent is to ensure that the SP + is aligned to at least a breakpoint instruction's boundary. */ + sp = gdbarch_frame_align (gdbarch, sp); + /* Allocate space for, and then position the breakpoint on the + stack. */ + if (gdbarch_inner_than (gdbarch, 1, 2)) + { + CORE_ADDR bppc = sp; + gdbarch_breakpoint_from_pc (gdbarch, &bppc, &bplen); + sp = gdbarch_frame_align (gdbarch, sp - bplen); + (*bp_addr) = sp; + /* Should the breakpoint size/location be re-computed here? */ + } + else + { + (*bp_addr) = sp; + gdbarch_breakpoint_from_pc (gdbarch, bp_addr, &bplen); + sp = gdbarch_frame_align (gdbarch, sp + bplen); + } + /* Inferior resumes at the function entry point. */ + (*real_pc) = funaddr; + return sp; +} + +/* Provide backward compatibility. Once DEPRECATED_FIX_CALL_DUMMY is + eliminated, this can be simplified. */ + +static CORE_ADDR +push_dummy_code (struct gdbarch *gdbarch, + CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, + struct value **args, int nargs, + struct type *value_type, + CORE_ADDR *real_pc, CORE_ADDR *bp_addr) +{ + if (gdbarch_push_dummy_code_p (gdbarch)) + return gdbarch_push_dummy_code (gdbarch, sp, funaddr, using_gcc, + args, nargs, value_type, real_pc, bp_addr); + else if (DEPRECATED_FIX_CALL_DUMMY_P () + && !gdbarch_push_dummy_call_p (gdbarch)) + return legacy_push_dummy_code (gdbarch, sp, funaddr, using_gcc, + args, nargs, value_type, real_pc, bp_addr); + else + return generic_push_dummy_code (gdbarch, sp, funaddr, using_gcc, + args, nargs, value_type, real_pc, bp_addr); +} + +/* All this stuff with a dummy frame may seem unnecessarily complicated + (why not just save registers in GDB?). The purpose of pushing a dummy + frame which looks just like a real frame is so that if you call a + function and then hit a breakpoint (get a signal, etc), "backtrace" + will look right. Whether the backtrace needs to actually show the + stack at the time the inferior function was called is debatable, but + it certainly needs to not display garbage. So if you are contemplating + making dummy frames be different from normal frames, consider that. */ + +/* Perform a function call in the inferior. + ARGS is a vector of values of arguments (NARGS of them). + FUNCTION is a value, the function to be called. + Returns a value representing what the function returned. + May fail to return, if a breakpoint or signal is hit + during the execution of the function. + + ARGS is modified to contain coerced values. */ + +struct value * +call_function_by_hand (struct value *function, int nargs, struct value **args) +{ + CORE_ADDR sp; + CORE_ADDR dummy_addr; + struct type *value_type; + unsigned char struct_return; + CORE_ADDR struct_addr = 0; + struct regcache *retbuf; + struct cleanup *retbuf_cleanup; + struct inferior_status *inf_status; + struct cleanup *inf_status_cleanup; + CORE_ADDR funaddr; + int using_gcc; /* Set to version of gcc in use, or zero if not gcc */ + CORE_ADDR real_pc; + struct type *ftype = check_typedef (SYMBOL_TYPE (function)); + CORE_ADDR bp_addr; + + if (!target_has_execution) + noprocess (); + + /* Create a cleanup chain that contains the retbuf (buffer + containing the register values). This chain is create BEFORE the + inf_status chain so that the inferior status can cleaned up + (restored or discarded) without having the retbuf freed. */ + retbuf = regcache_xmalloc (current_gdbarch); + retbuf_cleanup = make_cleanup_regcache_xfree (retbuf); + + /* A cleanup for the inferior status. Create this AFTER the retbuf + so that this can be discarded or applied without interfering with + the regbuf. */ + inf_status = save_inferior_status (1); + inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status); + + if (DEPRECATED_PUSH_DUMMY_FRAME_P ()) + { + /* DEPRECATED_PUSH_DUMMY_FRAME is responsible for saving the + inferior registers (and frame_pop() for restoring them). (At + least on most machines) they are saved on the stack in the + inferior. */ + DEPRECATED_PUSH_DUMMY_FRAME; + } + else + { + /* FIXME: cagney/2003-02-26: Step zero of this little tinker is + to extract the generic dummy frame code from the architecture + vector. Hence this direct call. + + A follow-on change is to modify this interface so that it takes + thread OR frame OR ptid as a parameter, and returns a dummy + frame handle. The handle can then be used further down as a + parameter to generic_save_dummy_frame_tos(). Hmm, thinking + about it, since everything is ment to be using generic dummy + frames, why not even use some of the dummy frame code to here - + do a regcache dup and then pass the duped regcache, along with + all the other stuff, at one single point. + + In fact, you can even save the structure's return address in the + dummy frame and fix one of those nasty lost struct return edge + conditions. */ + generic_push_dummy_frame (); + } + + /* Ensure that the initial SP is correctly aligned. */ + { + CORE_ADDR old_sp = read_sp (); + if (gdbarch_frame_align_p (current_gdbarch)) + { + sp = gdbarch_frame_align (current_gdbarch, old_sp); + /* NOTE: cagney/2003-08-13: Skip the "red zone". For some + ABIs, a function can use memory beyond the inner most stack + address. AMD64 called that region the "red zone". Skip at + least the "red zone" size before allocating any space on + the stack. */ + if (INNER_THAN (1, 2)) + sp -= gdbarch_frame_red_zone_size (current_gdbarch); + else + sp += gdbarch_frame_red_zone_size (current_gdbarch); + /* Still aligned? */ + gdb_assert (sp == gdbarch_frame_align (current_gdbarch, sp)); + /* NOTE: cagney/2002-09-18: + + On a RISC architecture, a void parameterless generic dummy + frame (i.e., no parameters, no result) typically does not + need to push anything the stack and hence can leave SP and + FP. Similarly, a frameless (possibly leaf) function does + not push anything on the stack and, hence, that too can + leave FP and SP unchanged. As a consequence, a sequence of + void parameterless generic dummy frame calls to frameless + functions will create a sequence of effectively identical + frames (SP, FP and TOS and PC the same). This, not + suprisingly, results in what appears to be a stack in an + infinite loop --- when GDB tries to find a generic dummy + frame on the internal dummy frame stack, it will always + find the first one. + + To avoid this problem, the code below always grows the + stack. That way, two dummy frames can never be identical. + It does burn a few bytes of stack but that is a small price + to pay :-). */ + if (sp == old_sp) + { + if (INNER_THAN (1, 2)) + /* Stack grows down. */ + sp = gdbarch_frame_align (current_gdbarch, old_sp - 1); + else + /* Stack grows up. */ + sp = gdbarch_frame_align (current_gdbarch, old_sp + 1); + } + gdb_assert ((INNER_THAN (1, 2) && sp <= old_sp) + || (INNER_THAN (2, 1) && sp >= old_sp)); + } + else + /* FIXME: cagney/2002-09-18: Hey, you loose! + + Who knows how badly aligned the SP is! + + If the generic dummy frame ends up empty (because nothing is + pushed) GDB won't be able to correctly perform back traces. + If a target is having trouble with backtraces, first thing to + do is add FRAME_ALIGN() to the architecture vector. If that + fails, try unwind_dummy_id(). + + If the ABI specifies a "Red Zone" (see the doco) the code + below will quietly trash it. */ + sp = old_sp; + } + + funaddr = find_function_addr (function, &value_type); + CHECK_TYPEDEF (value_type); + + { + struct block *b = block_for_pc (funaddr); + /* If compiled without -g, assume GCC 2. */ + using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b)); + } + + /* Are we returning a value using a structure return or a normal + value return? */ + + struct_return = using_struct_return (value_type, using_gcc); + + /* Determine the location of the breakpoint (and possibly other + stuff) that the called function will return to. The SPARC, for a + function returning a structure or union, needs to make space for + not just the breakpoint but also an extra word containing the + size (?) of the structure being passed. */ + + /* The actual breakpoint (at BP_ADDR) is inserted separatly so there + is no need to write that out. */ + + switch (CALL_DUMMY_LOCATION) + { + case ON_STACK: + /* "dummy_addr" is here just to keep old targets happy. New + targets return that same information via "sp" and "bp_addr". */ + if (INNER_THAN (1, 2)) + { + sp = push_dummy_code (current_gdbarch, sp, funaddr, + using_gcc, args, nargs, value_type, + &real_pc, &bp_addr); + dummy_addr = sp; + } + else + { + dummy_addr = sp; + sp = push_dummy_code (current_gdbarch, sp, funaddr, + using_gcc, args, nargs, value_type, + &real_pc, &bp_addr); + } + break; + case AT_ENTRY_POINT: + if (DEPRECATED_FIX_CALL_DUMMY_P () + && !gdbarch_push_dummy_call_p (current_gdbarch)) + { + /* Sigh. Some targets use DEPRECATED_FIX_CALL_DUMMY to + shove extra stuff onto the stack or into registers. That + code should be in PUSH_DUMMY_CALL, however, in the mean + time ... */ + /* If the target is manipulating DUMMY1, it looses big time. */ + void *dummy1 = NULL; + DEPRECATED_FIX_CALL_DUMMY (dummy1, sp, funaddr, nargs, args, + value_type, using_gcc); + } + real_pc = funaddr; + dummy_addr = entry_point_address (); + /* Make certain that the address points at real code, and not a + function descriptor. */ + dummy_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, + dummy_addr, + ¤t_target); + /* A call dummy always consists of just a single breakpoint, so + it's address is the same as the address of the dummy. */ + bp_addr = dummy_addr; + break; + case AT_SYMBOL: + /* Some executables define a symbol __CALL_DUMMY_ADDRESS whose + address is the location where the breakpoint should be + placed. Once all targets are using the overhauled frame code + this can be deleted - ON_STACK is a better option. */ + { + struct minimal_symbol *sym; + + sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL); + real_pc = funaddr; + if (sym) + dummy_addr = SYMBOL_VALUE_ADDRESS (sym); + else + dummy_addr = entry_point_address (); + /* Make certain that the address points at real code, and not + a function descriptor. */ + dummy_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, + dummy_addr, + ¤t_target); + /* A call dummy always consists of just a single breakpoint, + so it's address is the same as the address of the dummy. */ + bp_addr = dummy_addr; + break; + } + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + + if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) + /* Save where the breakpoint is going to be inserted so that the + dummy-frame code is later able to re-identify it. */ + generic_save_call_dummy_addr (bp_addr, bp_addr + 1); + + if (nargs < TYPE_NFIELDS (ftype)) + error ("too few arguments in function call"); + + { + int i; + for (i = nargs - 1; i >= 0; i--) + { + int prototyped; + struct type *param_type; + + /* FIXME drow/2002-05-31: Should just always mark methods as + prototyped. Can we respect TYPE_VARARGS? Probably not. */ + if (TYPE_CODE (ftype) == TYPE_CODE_METHOD) + prototyped = 1; + else if (i < TYPE_NFIELDS (ftype)) + prototyped = TYPE_PROTOTYPED (ftype); + else + prototyped = 0; + + if (i < TYPE_NFIELDS (ftype)) + param_type = TYPE_FIELD_TYPE (ftype, i); + else + param_type = NULL; + + args[i] = value_arg_coerce (args[i], param_type, prototyped); + + /* elz: this code is to handle the case in which the function + to be called has a pointer to function as parameter and the + corresponding actual argument is the address of a function + and not a pointer to function variable. In aCC compiled + code, the calls through pointers to functions (in the body + of the function called by hand) are made via + $$dyncall_external which requires some registers setting, + this is taken care of if we call via a function pointer + variable, but not via a function address. In cc this is + not a problem. */ + + if (using_gcc == 0) + { + if (param_type != NULL && TYPE_CODE (ftype) != TYPE_CODE_METHOD) + { + /* if this parameter is a pointer to function. */ + if (TYPE_CODE (param_type) == TYPE_CODE_PTR) + if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC) + /* elz: FIXME here should go the test about the + compiler used to compile the target. We want to + issue the error message only if the compiler + used was HP's aCC. If we used HP's cc, then + there is no problem and no need to return at + this point. */ + /* Go see if the actual parameter is a variable of + type pointer to function or just a function. */ + if (args[i]->lval == not_lval) + { + char *arg_name; + if (find_pc_partial_function ((CORE_ADDR) args[i]->aligner.contents[0], &arg_name, NULL, NULL)) + error ("\ +You cannot use function <%s> as argument. \n\ +You must use a pointer to function type variable. Command ignored.", arg_name); + } + } + } + } + } + + if (DEPRECATED_REG_STRUCT_HAS_ADDR_P ()) + { + int i; + /* This is a machine like the sparc, where we may need to pass a + pointer to the structure, not the structure itself. */ + for (i = nargs - 1; i >= 0; i--) + { + struct type *arg_type = check_typedef (VALUE_TYPE (args[i])); + if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT + || TYPE_CODE (arg_type) == TYPE_CODE_UNION + || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY + || TYPE_CODE (arg_type) == TYPE_CODE_STRING + || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING + || TYPE_CODE (arg_type) == TYPE_CODE_SET + || (TYPE_CODE (arg_type) == TYPE_CODE_FLT + && TYPE_LENGTH (arg_type) > 8) + ) + && DEPRECATED_REG_STRUCT_HAS_ADDR (using_gcc, arg_type)) + { + CORE_ADDR addr; + int len; /* = TYPE_LENGTH (arg_type); */ + int aligned_len; + arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i])); + len = TYPE_LENGTH (arg_type); + + if (DEPRECATED_STACK_ALIGN_P ()) + /* MVS 11/22/96: I think at least some of this + stack_align code is really broken. Better to let + PUSH_ARGUMENTS adjust the stack in a target-defined + manner. */ + aligned_len = DEPRECATED_STACK_ALIGN (len); + else + aligned_len = len; + if (INNER_THAN (1, 2)) + { + /* stack grows downward */ + sp -= aligned_len; + /* ... so the address of the thing we push is the + stack pointer after we push it. */ + addr = sp; + } + else + { + /* The stack grows up, so the address of the thing + we push is the stack pointer before we push it. */ + addr = sp; + sp += aligned_len; + } + /* Push the structure. */ + write_memory (addr, VALUE_CONTENTS_ALL (args[i]), len); + /* The value we're going to pass is the address of the + thing we just pushed. */ + /*args[i] = value_from_longest (lookup_pointer_type (value_type), + (LONGEST) addr); */ + args[i] = value_from_pointer (lookup_pointer_type (arg_type), + addr); + } + } + } + + + /* Reserve space for the return structure to be written on the + stack, if necessary. Make certain that the value is correctly + aligned. */ + + if (struct_return) + { + int len = TYPE_LENGTH (value_type); + if (DEPRECATED_STACK_ALIGN_P ()) + /* NOTE: cagney/2003-03-22: Should rely on frame align, rather + than stack align to force the alignment of the stack. */ + len = DEPRECATED_STACK_ALIGN (len); + if (INNER_THAN (1, 2)) + { + /* Stack grows downward. Align STRUCT_ADDR and SP after + making space for the return value. */ + sp -= len; + if (gdbarch_frame_align_p (current_gdbarch)) + sp = gdbarch_frame_align (current_gdbarch, sp); + struct_addr = sp; + } + else + { + /* Stack grows upward. Align the frame, allocate space, and + then again, re-align the frame??? */ + if (gdbarch_frame_align_p (current_gdbarch)) + sp = gdbarch_frame_align (current_gdbarch, sp); + struct_addr = sp; + sp += len; + if (gdbarch_frame_align_p (current_gdbarch)) + sp = gdbarch_frame_align (current_gdbarch, sp); + } + } + + /* Create the dummy stack frame. Pass in the call dummy address as, + presumably, the ABI code knows where, in the call dummy, the + return address should be pointed. */ + if (gdbarch_push_dummy_call_p (current_gdbarch)) + /* When there is no push_dummy_call method, should this code + simply error out. That would the implementation of this method + for all ABIs (which is probably a good thing). */ + sp = gdbarch_push_dummy_call (current_gdbarch, funaddr, current_regcache, + bp_addr, nargs, args, sp, struct_return, + struct_addr); + else if (DEPRECATED_PUSH_ARGUMENTS_P ()) + /* Keep old targets working. */ + sp = DEPRECATED_PUSH_ARGUMENTS (nargs, args, sp, struct_return, + struct_addr); + else + sp = legacy_push_arguments (nargs, args, sp, struct_return, struct_addr); + + if (DEPRECATED_PUSH_RETURN_ADDRESS_P ()) + /* for targets that use no CALL_DUMMY */ + /* There are a number of targets now which actually don't write + any CALL_DUMMY instructions into the target, but instead just + save the machine state, push the arguments, and jump directly + to the callee function. Since this doesn't actually involve + executing a JSR/BSR instruction, the return address must be set + up by hand, either by pushing onto the stack or copying into a + return-address register as appropriate. Formerly this has been + done in PUSH_ARGUMENTS, but that's overloading its + functionality a bit, so I'm making it explicit to do it here. */ + /* NOTE: cagney/2003-04-22: The first parameter ("real_pc") has + been replaced with zero, it turns out that no implementation + used that parameter. This occured because the value being + supplied - the address of the called function's entry point + instead of the address of the breakpoint that the called + function should return to - wasn't useful. */ + sp = DEPRECATED_PUSH_RETURN_ADDRESS (0, sp); + + /* NOTE: cagney/2003-03-23: Diable this code when there is a + push_dummy_call() method. Since that method will have already + handled any alignment issues, the code below is entirely + redundant. */ + if (!gdbarch_push_dummy_call_p (current_gdbarch) + && DEPRECATED_STACK_ALIGN_P () && !INNER_THAN (1, 2)) + { + /* If stack grows up, we must leave a hole at the bottom, note + that sp already has been advanced for the arguments! */ + sp = DEPRECATED_STACK_ALIGN (sp); + } + + /* Store the address at which the structure is supposed to be + written. */ + /* NOTE: 2003-03-24: Since PUSH_ARGUMENTS can (and typically does) + store the struct return address, this call is entirely redundant. */ + if (struct_return && DEPRECATED_STORE_STRUCT_RETURN_P ()) + DEPRECATED_STORE_STRUCT_RETURN (struct_addr, sp); + + /* Write the stack pointer. This is here because the statements + above might fool with it. On SPARC, this write also stores the + register window into the right place in the new stack frame, + which otherwise wouldn't happen (see store_inferior_registers in + sparc-nat.c). */ + /* NOTE: cagney/2003-03-23: Since the architecture method + push_dummy_call() should have already stored the stack pointer + (as part of creating the fake call frame), and none of the code + following that call adjusts the stack-pointer value, the below + call is entirely redundant. */ + if (DEPRECATED_DUMMY_WRITE_SP_P ()) + DEPRECATED_DUMMY_WRITE_SP (sp); + + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) + { + /* Sanity. The exact same SP value is returned by + PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by + unwind_dummy_id to form the frame ID's stack address. */ + gdb_assert (DEPRECATED_USE_GENERIC_DUMMY_FRAMES); + generic_save_dummy_frame_tos (sp); + } + else if (DEPRECATED_SAVE_DUMMY_FRAME_TOS_P ()) + DEPRECATED_SAVE_DUMMY_FRAME_TOS (sp); + + /* Now proceed, having reached the desired place. */ + clear_proceed_status (); + + /* Create a momentary breakpoint at the return address of the + inferior. That way it breaks when it returns. */ + + { + struct breakpoint *bpt; + struct symtab_and_line sal; + struct frame_id frame; + init_sal (&sal); /* initialize to zeroes */ + sal.pc = bp_addr; + sal.section = find_pc_overlay (sal.pc); + /* Set up a frame ID for the dummy frame so we can pass it to + set_momentary_breakpoint. We need to give the breakpoint a + frame ID so that the breakpoint code can correctly re-identify + the dummy breakpoint. */ + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) + { + /* Sanity. The exact same SP value is returned by + PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by + unwind_dummy_id to form the frame ID's stack address. */ + gdb_assert (DEPRECATED_USE_GENERIC_DUMMY_FRAMES); + frame = frame_id_build (sp, sal.pc); + } + else + { + /* The assumption here is that push_dummy_call() returned the + stack part of the frame ID. Unfortunately, many older + architectures were, via a convoluted mess, relying on the + poorly defined and greatly overloaded + DEPRECATED_TARGET_READ_FP or DEPRECATED_FP_REGNUM to supply + the value. */ + if (DEPRECATED_TARGET_READ_FP_P ()) + frame = frame_id_build (DEPRECATED_TARGET_READ_FP (), sal.pc); + else if (DEPRECATED_FP_REGNUM >= 0) + frame = frame_id_build (read_register (DEPRECATED_FP_REGNUM), sal.pc); + else + frame = frame_id_build (sp, sal.pc); + } + bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy); + bpt->disposition = disp_del; + } + + /* Execute a "stack dummy", a piece of code stored in the stack by + the debugger to be executed in the inferior. + + The dummy's frame is automatically popped whenever that break is + hit. If that is the first time the program stops, + call_function_by_hand returns to its caller with that frame + already gone and sets RC to 0. + + Otherwise, set RC to a non-zero value. If the called function + receives a random signal, we do not allow the user to continue + executing it as this may not work. The dummy frame is poped and + we return 1. If we hit a breakpoint, we leave the frame in place + and return 2 (the frame will eventually be popped when we do hit + the dummy end breakpoint). */ + + { + struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); + int saved_async = 0; + + /* If all error()s out of proceed ended up calling normal_stop + (and perhaps they should; it already does in the special case + of error out of resume()), then we wouldn't need this. */ + make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat); + + disable_watchpoints_before_interactive_call_start (); + proceed_to_finish = 1; /* We want stop_registers, please... */ + + if (target_can_async_p ()) + saved_async = target_async_mask (0); + + proceed (real_pc, TARGET_SIGNAL_0, 0); + + if (saved_async) + target_async_mask (saved_async); + + enable_watchpoints_after_interactive_call_stop (); + + discard_cleanups (old_cleanups); + } + + if (stopped_by_random_signal || !stop_stack_dummy) + { + /* Find the name of the function we're about to complain about. */ + const char *name = NULL; + { + struct symbol *symbol = find_pc_function (funaddr); + if (symbol) + name = SYMBOL_PRINT_NAME (symbol); + else + { + /* Try the minimal symbols. */ + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr); + if (msymbol) + name = SYMBOL_PRINT_NAME (msymbol); + } + if (name == NULL) + { + /* Can't use a cleanup here. It is discarded, instead use + an alloca. */ + char *tmp = xstrprintf ("at %s", local_hex_string (funaddr)); + char *a = alloca (strlen (tmp) + 1); + strcpy (a, tmp); + xfree (tmp); + name = a; + } + } + if (stopped_by_random_signal) + { + /* We stopped inside the FUNCTION because of a random + signal. Further execution of the FUNCTION is not + allowed. */ + + if (unwind_on_signal_p) + { + /* The user wants the context restored. */ + + /* We must get back to the frame we were before the + dummy call. */ + frame_pop (get_current_frame ()); + + /* FIXME: Insert a bunch of wrap_here; name can be very + long if it's a C++ name with arguments and stuff. */ + error ("\ +The program being debugged was signaled while in a function called from GDB.\n\ +GDB has restored the context to what it was before the call.\n\ +To change this behavior use \"set unwindonsignal off\"\n\ +Evaluation of the expression containing the function (%s) will be abandoned.", + name); + } + else + { + /* The user wants to stay in the frame where we stopped + (default).*/ + /* If we restored the inferior status (via the cleanup), + we would print a spurious error message (Unable to + restore previously selected frame), would write the + registers from the inf_status (which is wrong), and + would do other wrong things. */ + discard_cleanups (inf_status_cleanup); + discard_inferior_status (inf_status); + /* FIXME: Insert a bunch of wrap_here; name can be very + long if it's a C++ name with arguments and stuff. */ + error ("\ +The program being debugged was signaled while in a function called from GDB.\n\ +GDB remains in the frame where the signal was received.\n\ +To change this behavior use \"set unwindonsignal on\"\n\ +Evaluation of the expression containing the function (%s) will be abandoned.", + name); + } + } + + if (!stop_stack_dummy) + { + /* We hit a breakpoint inside the FUNCTION. */ + /* If we restored the inferior status (via the cleanup), we + would print a spurious error message (Unable to restore + previously selected frame), would write the registers + from the inf_status (which is wrong), and would do other + wrong things. */ + discard_cleanups (inf_status_cleanup); + discard_inferior_status (inf_status); + /* The following error message used to say "The expression + which contained the function call has been discarded." + It is a hard concept to explain in a few words. Ideally, + GDB would be able to resume evaluation of the expression + when the function finally is done executing. Perhaps + someday this will be implemented (it would not be easy). */ + /* FIXME: Insert a bunch of wrap_here; name can be very long if it's + a C++ name with arguments and stuff. */ + error ("\ +The program being debugged stopped while in a function called from GDB.\n\ +When the function (%s) is done executing, GDB will silently\n\ +stop (instead of continuing to evaluate the expression containing\n\ +the function call).", name); + } + + /* The above code errors out, so ... */ + internal_error (__FILE__, __LINE__, "... should not be here"); + } + + /* If we get here the called FUNCTION run to completion. */ + + /* On normal return, the stack dummy has been popped already. */ + regcache_cpy_no_passthrough (retbuf, stop_registers); + + /* Restore the inferior status, via its cleanup. At this stage, + leave the RETBUF alone. */ + do_cleanups (inf_status_cleanup); + + /* Figure out the value returned by the function. */ + if (struct_return) + { + /* NOTE: cagney/2003-09-27: This assumes that PUSH_DUMMY_CALL + has correctly stored STRUCT_ADDR in the target. In the past + that hasn't been the case, the old MIPS PUSH_ARGUMENTS + (PUSH_DUMMY_CALL precursor) would silently move the location + of the struct return value making STRUCT_ADDR bogus. If + you're seeing problems with values being returned using the + "struct return convention", check that PUSH_DUMMY_CALL isn't + playing tricks. */ + struct value *retval = value_at (value_type, struct_addr, NULL); + do_cleanups (retbuf_cleanup); + return retval; + } + else + { + /* The non-register case was handled above. */ + struct value *retval = register_value_being_returned (value_type, + retbuf); + do_cleanups (retbuf_cleanup); + return retval; + } +} + +void _initialize_infcall (void); + +void +_initialize_infcall (void) +{ + add_setshow_boolean_cmd ("coerce-float-to-double", class_obscure, + &coerce_float_to_double_p, "\ +Set coercion of floats to doubles when calling functions\n\ +Variables of type float should generally be converted to doubles before\n\ +calling an unprototyped function, and left alone when calling a prototyped\n\ +function. However, some older debug info formats do not provide enough\n\ +information to determine that a function is prototyped. If this flag is\n\ +set, GDB will perform the conversion for a function it considers\n\ +unprototyped.\n\ +The default is to perform the conversion.\n", "\ +Show coercion of floats to doubles when calling functions\n\ +Variables of type float should generally be converted to doubles before\n\ +calling an unprototyped function, and left alone when calling a prototyped\n\ +function. However, some older debug info formats do not provide enough\n\ +information to determine that a function is prototyped. If this flag is\n\ +set, GDB will perform the conversion for a function it considers\n\ +unprototyped.\n\ +The default is to perform the conversion.\n", + NULL, NULL, &setlist, &showlist); + + add_setshow_boolean_cmd ("unwindonsignal", no_class, + &unwind_on_signal_p, "\ +Set unwinding of stack if a signal is received while in a call dummy.\n\ +The unwindonsignal lets the user determine what gdb should do if a signal\n\ +is received while in a function called from gdb (call dummy). If set, gdb\n\ +unwinds the stack and restore the context to what as it was before the call.\n\ +The default is to stop in the frame where the signal was received.", "\ +Set unwinding of stack if a signal is received while in a call dummy.\n\ +The unwindonsignal lets the user determine what gdb should do if a signal\n\ +is received while in a function called from gdb (call dummy). If set, gdb\n\ +unwinds the stack and restore the context to what as it was before the call.\n\ +The default is to stop in the frame where the signal was received.", + NULL, NULL, &setlist, &showlist); +} diff --git a/contrib/gdb/gdb/infcall.h b/contrib/gdb/gdb/infcall.h new file mode 100644 index 00000000000..05d06e034bf --- /dev/null +++ b/contrib/gdb/gdb/infcall.h @@ -0,0 +1,43 @@ +/* Perform an inferior function call, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef INFCALL_H +#define INFCALL_H + +struct value; +struct type; + +extern CORE_ADDR find_function_addr (struct value *function, + struct type **retval_type); + +/* Perform a function call in the inferior. + + ARGS is a vector of values of arguments (NARGS of them). FUNCTION + is a value, the function to be called. Returns a value + representing what the function returned. May fail to return, if a + breakpoint or signal is hit during the execution of the function. + + ARGS is modified to contain coerced values. */ + +extern struct value *call_function_by_hand (struct value *function, int nargs, + struct value **args); + +#endif diff --git a/contrib/gdb/gdb/infcmd.c b/contrib/gdb/gdb/infcmd.c index 02384483822..6e74f4e5431 100644 --- a/contrib/gdb/gdb/infcmd.c +++ b/contrib/gdb/gdb/infcmd.c @@ -1,6 +1,6 @@ /* Memory-access and commands for "inferior" process, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -40,19 +40,30 @@ #include "ui-out.h" #include "event-top.h" #include "parser-defs.h" +#include "regcache.h" +#include "reggroups.h" +#include "block.h" +#include +#include "gdb_assert.h" -/* Functions exported for general use: */ - -void nofp_registers_info (char *, int); +/* Functions exported for general use, in inferior.h: */ void all_registers_info (char *, int); void registers_info (char *, int); -/* Local functions: */ +void nexti_command (char *, int); + +void stepi_command (char *, int); void continue_command (char *, int); +void interrupt_target_command (char *args, int from_tty); + +/* Local functions: */ + +static void nofp_registers_info (char *, int); + static void print_return_value (int struct_return, struct type *value_type); static void finish_command_continuation (struct continuation_arg *); @@ -71,7 +82,7 @@ static void float_info (char *, int); static void detach_command (char *, int); -static void interrupt_target_command (char *args, int from_tty); +static void disconnect_command (char *, int); static void unset_environment_command (char *, int); @@ -91,10 +102,6 @@ static void step_1 (int, int, char *); static void step_once (int skip_subroutines, int single_inst, int count); static void step_1_continuation (struct continuation_arg *arg); -void nexti_command (char *, int); - -void stepi_command (char *, int); - static void next_command (char *, int); static void step_command (char *, int); @@ -111,8 +118,6 @@ void _initialize_infcmd (void); #define GO_USAGE "Usage: go \n" -static void breakpoint_auto_delete_contents (PTR); - #define ERROR_NO_INFERIOR \ if (!target_has_execution) error ("The program is not being run."); @@ -179,7 +184,7 @@ CORE_ADDR step_range_end; /* Exclusive */ This is how we know when we step into a subroutine call, and how to set the frame for the breakpoint used to step out. */ -CORE_ADDR step_frame_address; +struct frame_id step_frame_id; /* Our notion of the current stack pointer. */ @@ -257,7 +262,6 @@ notice_args_read (char *args, int from_tty, struct cmd_list_element *c) /* Compute command-line string given argument vector. This does the same shell processing as fork_inferior. */ -/* ARGSUSED */ char * construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv) { @@ -275,7 +279,7 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv) /* We over-compute the size. It shouldn't matter. */ for (i = 0; i < argc; ++i) - length += 2 * strlen (argv[i]) + 1; + length += 2 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0'); result = (char *) xmalloc (length); out = result; @@ -285,11 +289,20 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv) if (i > 0) *out++ = ' '; - for (cp = argv[i]; *cp; ++cp) + /* Need to handle empty arguments specially. */ + if (argv[i][0] == '\0') { - if (strchr (special, *cp) != NULL) - *out++ = '\\'; - *out++ = *cp; + *out++ = '\''; + *out++ = '\''; + } + else + { + for (cp = argv[i]; *cp; ++cp) + { + if (strchr (special, *cp) != NULL) + *out++ = '\\'; + *out++ = *cp; + } } } *out = '\0'; @@ -357,7 +370,6 @@ strip_bg_char (char **args) return 0; } -/* ARGSUSED */ void tty_command (char *file, int from_tty) { @@ -530,7 +542,6 @@ continue_command (char *proc_count_exp, int from_tty) /* Step until outside of current statement. */ -/* ARGSUSED */ static void step_command (char *count_string, int from_tty) { @@ -539,7 +550,6 @@ step_command (char *count_string, int from_tty) /* Likewise, but skip over subroutine calls as if single instructions. */ -/* ARGSUSED */ static void next_command (char *count_string, int from_tty) { @@ -548,14 +558,12 @@ next_command (char *count_string, int from_tty) /* Likewise, but step only one instruction. */ -/* ARGSUSED */ void stepi_command (char *count_string, int from_tty) { step_1 (0, 1, count_string); } -/* ARGSUSED */ void nexti_command (char *count_string, int from_tty) { @@ -571,7 +579,7 @@ disable_longjmp_breakpoint_cleanup (void *ignore) static void step_1 (int skip_subroutines, int single_inst, char *count_string) { - register int count = 1; + int count = 1; struct frame_info *frame; struct cleanup *cleanups = 0; int async_exec = 0; @@ -615,7 +623,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) frame = get_current_frame (); if (!frame) /* Avoid coredump here. Why tho? */ error ("No current frame"); - step_frame_address = FRAME_FP (frame); + step_frame_id = get_frame_id (frame); step_sp = read_sp (); if (!single_inst) @@ -653,13 +661,6 @@ which has no line number information.\n", name); if (!stop_step) break; - - /* FIXME: On nexti, this may have already been done (when we hit the - step resume break, I think). Probably this should be moved to - wait_for_inferior (near the top). */ -#if defined (SHIFT_INST_REGS) - SHIFT_INST_REGS (); -#endif } if (!single_inst || skip_subroutines) @@ -694,15 +695,7 @@ step_1_continuation (struct continuation_arg *arg) count = arg->next->next->data.integer; if (stop_step) - { - /* FIXME: On nexti, this may have already been done (when we hit the - step resume break, I think). Probably this should be moved to - wait_for_inferior (near the top). */ -#if defined (SHIFT_INST_REGS) - SHIFT_INST_REGS (); -#endif - step_once (skip_subroutines, single_inst, count - 1); - } + step_once (skip_subroutines, single_inst, count - 1); else if (!single_inst || skip_subroutines) do_exec_cleanups (ALL_CLEANUPS); @@ -730,7 +723,7 @@ step_once (int skip_subroutines, int single_inst, int count) frame = get_current_frame (); if (!frame) /* Avoid coredump here. Why tho? */ error ("No current frame"); - step_frame_address = FRAME_FP (frame); + step_frame_id = get_frame_id (frame); step_sp = read_sp (); if (!single_inst) @@ -793,7 +786,7 @@ which has no line number information.\n", name); static void jump_command (char *arg, int from_tty) { - register CORE_ADDR addr; + CORE_ADDR addr; struct symtabs_and_lines sals; struct symtab_and_line sal; struct symbol *fn; @@ -842,7 +835,7 @@ jump_command (char *arg, int from_tty) if (fn != NULL && sfn != fn) { if (!query ("Line %d is not in `%s'. Jump anyway? ", sal.line, - SYMBOL_SOURCE_NAME (fn))) + SYMBOL_PRINT_NAME (fn))) { error ("Not confirmed."); /* NOTREACHED */ @@ -937,116 +930,6 @@ signal_command (char *signum_exp, int from_tty) proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0); } -/* Call breakpoint_auto_delete on the current contents of the bpstat - pointed to by arg (which is really a bpstat *). */ - -static void -breakpoint_auto_delete_contents (PTR arg) -{ - breakpoint_auto_delete (*(bpstat *) arg); -} - - -/* Execute a "stack dummy", a piece of code stored in the stack - by the debugger to be executed in the inferior. - - To call: first, do PUSH_DUMMY_FRAME. - Then push the contents of the dummy. It should end with a breakpoint insn. - Then call here, passing address at which to start the dummy. - - The contents of all registers are saved before the dummy frame is popped - and copied into the buffer BUFFER. - - The dummy's frame is automatically popped whenever that break is hit. - If that is the first time the program stops, run_stack_dummy - returns to its caller with that frame already gone and returns 0. - - Otherwise, run_stack-dummy returns a non-zero value. - If the called function receives a random signal, we do not allow the user - to continue executing it as this may not work. The dummy frame is poped - and we return 1. - If we hit a breakpoint, we leave the frame in place and return 2 (the frame - will eventually be popped when we do hit the dummy end breakpoint). */ - -int -run_stack_dummy (CORE_ADDR addr, char *buffer) -{ - struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); - int saved_async = 0; - - /* Now proceed, having reached the desired place. */ - clear_proceed_status (); - - if (CALL_DUMMY_BREAKPOINT_OFFSET_P) - { - struct breakpoint *bpt; - struct symtab_and_line sal; - - INIT_SAL (&sal); /* initialize to zeroes */ - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) - { - sal.pc = CALL_DUMMY_ADDRESS (); - } - else - { - sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET; - } - sal.section = find_pc_overlay (sal.pc); - - /* Set up a FRAME for the dummy frame so we can pass it to - set_momentary_breakpoint. We need to give the breakpoint a - frame in case there is only one copy of the dummy (e.g. - CALL_DUMMY_LOCATION == AFTER_TEXT_END). */ - flush_cached_frames (); - set_current_frame (create_new_frame (read_fp (), sal.pc)); - - /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to put - a breakpoint instruction. If not, the call dummy already has the - breakpoint instruction in it. - - addr is the address of the call dummy plus the CALL_DUMMY_START_OFFSET, - so we need to subtract the CALL_DUMMY_START_OFFSET. */ - bpt = set_momentary_breakpoint (sal, - get_current_frame (), - bp_call_dummy); - bpt->disposition = disp_del; - - /* If all error()s out of proceed ended up calling normal_stop (and - perhaps they should; it already does in the special case of error - out of resume()), then we wouldn't need this. */ - make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat); - } - - disable_watchpoints_before_interactive_call_start (); - proceed_to_finish = 1; /* We want stop_registers, please... */ - - if (target_can_async_p ()) - saved_async = target_async_mask (0); - - proceed (addr, TARGET_SIGNAL_0, 0); - - if (saved_async) - target_async_mask (saved_async); - - enable_watchpoints_after_interactive_call_stop (); - - discard_cleanups (old_cleanups); - - /* We can stop during an inferior call because a signal is received. */ - if (stopped_by_random_signal) - return 1; - - /* We may also stop prematurely because we hit a breakpoint in the - called routine. */ - if (!stop_stack_dummy) - return 2; - - /* On normal return, the stack dummy has been popped already. */ - - memcpy (buffer, stop_registers, REGISTER_BYTES); - return 0; -} - /* Proceed until we reach a different source line with pc greater than our current one or exit the function. We skip calls in both cases. @@ -1055,7 +938,6 @@ run_stack_dummy (CORE_ADDR addr, char *buffer) we set. This may involve changes to wait_for_inferior and the proceed status code. */ -/* ARGSUSED */ static void until_next_command (int from_tty) { @@ -1094,7 +976,7 @@ until_next_command (int from_tty) } step_over_calls = STEP_OVER_ALL; - step_frame_address = FRAME_FP (frame); + step_frame_id = get_frame_id (frame); step_sp = read_sp (); step_multi = 0; /* Only one call to proceed */ @@ -1128,79 +1010,144 @@ until_command (char *arg, int from_tty) } if (arg) - until_break_command (arg, from_tty); + until_break_command (arg, from_tty, 0); else until_next_command (from_tty); } + +static void +advance_command (char *arg, int from_tty) +{ + int async_exec = 0; + + if (!target_has_execution) + error ("The program is not running."); + + if (arg == NULL) + error_no_arg ("a location"); + + /* Find out whether we must run in the background. */ + if (arg != NULL) + async_exec = strip_bg_char (&arg); + + /* If we must run in the background, but the target can't do it, + error out. */ + if (event_loop_p && async_exec && !target_can_async_p ()) + error ("Asynchronous execution not supported on this target."); + + /* If we are not asked to run in the bg, then prepare to run in the + foreground, synchronously. */ + if (event_loop_p && !async_exec && target_can_async_p ()) + { + /* Simulate synchronous execution. */ + async_disable_stdin (); + } + + until_break_command (arg, from_tty, 1); +} -/* Print the result of a function at the end of a 'finish' command. */ -static void -print_return_value (int structure_return, struct type *value_type) -{ - struct value *value; - static struct ui_stream *stb = NULL; +/* Print the result of a function at the end of a 'finish' command. */ - if (!structure_return) +static void +print_return_value (int struct_return, struct type *value_type) +{ + struct cleanup *old_chain; + struct ui_stream *stb; + struct value *value; + + if (!struct_return) { - value = value_being_returned (value_type, stop_registers, structure_return); - stb = ui_out_stream_new (uiout); - ui_out_text (uiout, "Value returned is "); - ui_out_field_fmt (uiout, "gdb-result-var", "$%d", record_latest_value (value)); - ui_out_text (uiout, " = "); - value_print (value, stb->stream, 0, Val_no_prettyprint); - ui_out_field_stream (uiout, "return-value", stb); - ui_out_text (uiout, "\n"); + /* The return value can be found in the inferior's registers. */ + value = register_value_being_returned (value_type, stop_registers); } - else + /* FIXME: cagney/2004-01-17: When both return_value and + extract_returned_value_address are available, should use that to + find the address of and then extract the returned value. */ + /* FIXME: 2003-09-27: When returning from a nested inferior function + call, it's possible (with no help from the architecture vector) + to locate and return/print a "struct return" value. This is just + a more complicated case of what is already being done in in the + inferior function call code. In fact, when inferior function + calls are made async, this will likely be made the norm. */ + else if (gdbarch_return_value_p (current_gdbarch)) + /* We cannot determine the contents of the structure because it is + on the stack, and we don't know where, since we did not + initiate the call, as opposed to the call_function_by_hand + case. */ { - /* We cannot determine the contents of the structure because - it is on the stack, and we don't know where, since we did not - initiate the call, as opposed to the call_function_by_hand case */ -#ifdef VALUE_RETURNED_FROM_STACK - value = 0; + gdb_assert (gdbarch_return_value (current_gdbarch, value_type, + NULL, NULL, NULL) + == RETURN_VALUE_STRUCT_CONVENTION); ui_out_text (uiout, "Value returned has type: "); ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type)); ui_out_text (uiout, "."); ui_out_text (uiout, " Cannot determine contents\n"); -#else - value = value_being_returned (value_type, stop_registers, structure_return); - stb = ui_out_stream_new (uiout); - ui_out_text (uiout, "Value returned is "); - ui_out_field_fmt (uiout, "gdb-result-var", "$%d", record_latest_value (value)); - ui_out_text (uiout, " = "); - value_print (value, stb->stream, 0, Val_no_prettyprint); - ui_out_field_stream (uiout, "return-value", stb); - ui_out_text (uiout, "\n"); -#endif + return; } + else + { + if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ()) + { + CORE_ADDR addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers); + if (!addr) + error ("Function return value unknown."); + value = value_at (value_type, addr, NULL); + } + else + { + /* It is "struct return" yet the value is being extracted, + presumably from registers, using EXTRACT_RETURN_VALUE. + This doesn't make sense. Unfortunately, the legacy + interfaces allowed this behavior. Sigh! */ + value = allocate_value (value_type); + CHECK_TYPEDEF (value_type); + /* If the function returns void, don't bother fetching the + return value. */ + EXTRACT_RETURN_VALUE (value_type, stop_registers, + VALUE_CONTENTS_RAW (value)); + } + } + + /* Print it. */ + stb = ui_out_stream_new (uiout); + old_chain = make_cleanup_ui_out_stream_delete (stb); + ui_out_text (uiout, "Value returned is "); + ui_out_field_fmt (uiout, "gdb-result-var", "$%d", + record_latest_value (value)); + ui_out_text (uiout, " = "); + value_print (value, stb->stream, 0, Val_no_prettyprint); + ui_out_field_stream (uiout, "return-value", stb); + ui_out_text (uiout, "\n"); + do_cleanups (old_chain); } /* Stuff that needs to be done by the finish command after the target - has stopped. In asynchronous mode, we wait for the target to stop in - the call to poll or select in the event loop, so it is impossible to - do all the stuff as part of the finish_command function itself. The - only chance we have to complete this command is in - fetch_inferior_event, which is called by the event loop as soon as it - detects that the target has stopped. This function is called via the - cmd_continuation pointer. */ -void + has stopped. In asynchronous mode, we wait for the target to stop + in the call to poll or select in the event loop, so it is + impossible to do all the stuff as part of the finish_command + function itself. The only chance we have to complete this command + is in fetch_inferior_event, which is called by the event loop as + soon as it detects that the target has stopped. This function is + called via the cmd_continuation pointer. */ + +static void finish_command_continuation (struct continuation_arg *arg) { - register struct symbol *function; + struct symbol *function; struct breakpoint *breakpoint; struct cleanup *cleanups; breakpoint = (struct breakpoint *) arg->data.pointer; - function = (struct symbol *) arg->next->data.pointer; - cleanups = (struct cleanup *) arg->next->next->data.pointer; + function = (struct symbol *) arg->next->data.pointer; + cleanups = (struct cleanup *) arg->next->next->data.pointer; if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL - && function != 0) + && function != NULL) { struct type *value_type; - CORE_ADDR funcaddr; int struct_return; + int gcc_compiled; value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); if (!value_type) @@ -1213,47 +1160,45 @@ finish_command_continuation (struct continuation_arg *arg) return; } - funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function)); - - struct_return = using_struct_return (value_of_variable (function, NULL), - funcaddr, - check_typedef (value_type), - BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))); + CHECK_TYPEDEF (value_type); + gcc_compiled = BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)); + struct_return = using_struct_return (value_type, gcc_compiled); print_return_value (struct_return, value_type); } + do_exec_cleanups (cleanups); } -/* "finish": Set a temporary breakpoint at the place - the selected frame will return to, then continue. */ +/* "finish": Set a temporary breakpoint at the place the selected + frame will return to, then continue. */ static void finish_command (char *arg, int from_tty) { struct symtab_and_line sal; - register struct frame_info *frame; - register struct symbol *function; + struct frame_info *frame; + struct symbol *function; struct breakpoint *breakpoint; struct cleanup *old_chain; struct continuation_arg *arg1, *arg2, *arg3; int async_exec = 0; - /* Find out whether we must run in the background. */ + /* Find out whether we must run in the background. */ if (arg != NULL) async_exec = strip_bg_char (&arg); /* If we must run in the background, but the target can't do it, - error out. */ + error out. */ if (event_loop_p && async_exec && !target_can_async_p ()) error ("Asynchronous execution not supported on this target."); /* If we are not asked to run in the bg, then prepare to run in the - foreground, synchronously. */ + foreground, synchronously. */ if (event_loop_p && !async_exec && target_can_async_p ()) { - /* Simulate synchronous execution */ + /* Simulate synchronous execution. */ async_disable_stdin (); } @@ -1261,19 +1206,19 @@ finish_command (char *arg, int from_tty) error ("The \"finish\" command does not take any arguments."); if (!target_has_execution) error ("The program is not running."); - if (selected_frame == NULL) + if (deprecated_selected_frame == NULL) error ("No selected frame."); - frame = get_prev_frame (selected_frame); + frame = get_prev_frame (deprecated_selected_frame); if (frame == 0) error ("\"finish\" not meaningful in the outermost frame."); clear_proceed_status (); - sal = find_pc_line (frame->pc, 0); - sal.pc = frame->pc; + sal = find_pc_line (get_frame_pc (frame), 0); + sal.pc = get_frame_pc (frame); - breakpoint = set_momentary_breakpoint (sal, frame, bp_finish); + breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish); if (!event_loop_p || !target_can_async_p ()) old_chain = make_cleanup_delete_breakpoint (breakpoint); @@ -1282,20 +1227,21 @@ finish_command (char *arg, int from_tty) /* Find the function we will return from. */ - function = find_pc_function (selected_frame->pc); + function = find_pc_function (get_frame_pc (deprecated_selected_frame)); - /* Print info on the selected frame, including level number - but not source. */ + /* Print info on the selected frame, including level number but not + source. */ if (from_tty) { printf_filtered ("Run till exit from "); - print_stack_frame (selected_frame, selected_frame_level, 0); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 0); } /* If running asynchronously and the target support asynchronous execution, set things up for the rest of the finish command to be completed later on, when gdb has detected that the target has - stopped, in fetch_inferior_event. */ + stopped, in fetch_inferior_event. */ if (event_loop_p && target_can_async_p ()) { arg1 = @@ -1313,47 +1259,43 @@ finish_command (char *arg, int from_tty) add_continuation (finish_command_continuation, arg1); } - proceed_to_finish = 1; /* We want stop_registers, please... */ + proceed_to_finish = 1; /* We want stop_registers, please... */ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); /* Do this only if not running asynchronously or if the target - cannot do async execution. Otherwise, complete this command when - the target actually stops, in fetch_inferior_event. */ + cannot do async execution. Otherwise, complete this command when + the target actually stops, in fetch_inferior_event. */ if (!event_loop_p || !target_can_async_p ()) { - - /* Did we stop at our breakpoint? */ + /* Did we stop at our breakpoint? */ if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL - && function != 0) + && function != NULL) { struct type *value_type; - CORE_ADDR funcaddr; int struct_return; + int gcc_compiled; value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); if (!value_type) internal_error (__FILE__, __LINE__, "finish_command: function has no target type"); - /* FIXME: Shouldn't we do the cleanups before returning? */ + /* FIXME: Shouldn't we do the cleanups before returning? */ if (TYPE_CODE (value_type) == TYPE_CODE_VOID) return; - funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function)); - - struct_return = - using_struct_return (value_of_variable (function, NULL), - funcaddr, - check_typedef (value_type), - BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))); + CHECK_TYPEDEF (value_type); + gcc_compiled = BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)); + struct_return = using_struct_return (value_type, gcc_compiled); print_return_value (struct_return, value_type); } + do_cleanups (old_chain); } } -/* ARGSUSED */ + static void program_info (char *args, int from_tty) { @@ -1406,7 +1348,7 @@ environment_info (char *var, int from_tty) { if (var) { - register char *val = get_in_environ (inferior_environ, var); + char *val = get_in_environ (inferior_environ, var); if (val) { puts_filtered (var); @@ -1423,7 +1365,7 @@ environment_info (char *var, int from_tty) } else { - register char **vector = environ_vector (inferior_environ); + char **vector = environ_vector (inferior_environ); while (*vector) { puts_filtered (*vector++); @@ -1435,7 +1377,7 @@ environment_info (char *var, int from_tty) static void set_environment_command (char *arg, int from_tty) { - register char *p, *val, *var; + char *p, *val, *var; int nullset = 0; if (arg == 0) @@ -1515,7 +1457,6 @@ unset_environment_command (char *var, int from_tty) static const char path_var_name[] = "PATH"; -/* ARGSUSED */ static void path_info (char *args, int from_tty) { @@ -1545,35 +1486,50 @@ path_command (char *dirname, int from_tty) } -#ifdef REGISTER_NAMES -char *gdb_register_names[] = REGISTER_NAMES; -#endif -/* Print out the machine register regnum. If regnum is -1, - print all registers (fpregs == 1) or all non-float registers - (fpregs == 0). +/* Print out the machine register regnum. If regnum is -1, print all + registers (print_all == 1) or all non-float and non-vector + registers (print_all == 0). For most machines, having all_registers_info() print the - register(s) one per line is good enough. If a different format - is required, (eg, for MIPS or Pyramid 90x, which both have - lots of regs), or there is an existing convention for showing - all the registers, define the macro DO_REGISTERS_INFO(regnum, fp) - to provide that format. */ + register(s) one per line is good enough. If a different format is + required, (eg, for MIPS or Pyramid 90x, which both have lots of + regs), or there is an existing convention for showing all the + registers, define the architecture method PRINT_REGISTERS_INFO to + provide that format. */ void -do_registers_info (int regnum, int fpregs) +default_print_registers_info (struct gdbarch *gdbarch, + struct ui_file *file, + struct frame_info *frame, + int regnum, int print_all) { - register int i; - int numregs = NUM_REGS + NUM_PSEUDO_REGS; - char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); - char *virtual_buffer = (char*) alloca (MAX_REGISTER_VIRTUAL_SIZE); + int i; + const int numregs = NUM_REGS + NUM_PSEUDO_REGS; + char raw_buffer[MAX_REGISTER_SIZE]; + char virtual_buffer[MAX_REGISTER_SIZE]; + + if (DEPRECATED_DO_REGISTERS_INFO_P ()) + { + DEPRECATED_DO_REGISTERS_INFO (regnum, print_all); + return; + } for (i = 0; i < numregs; i++) { - /* Decide between printing all regs, nonfloat regs, or specific reg. */ + /* Decide between printing all regs, non-float / vector regs, or + specific reg. */ if (regnum == -1) { - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT && !fpregs) - continue; + if (print_all) + { + if (!gdbarch_register_reggroup_p (gdbarch, i, all_reggroup)) + continue; + } + else + { + if (!gdbarch_register_reggroup_p (gdbarch, i, general_reggroup)) + continue; + } } else { @@ -1586,62 +1542,69 @@ do_registers_info (int regnum, int fpregs) if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0') continue; - fputs_filtered (REGISTER_NAME (i), gdb_stdout); - print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout); + fputs_filtered (REGISTER_NAME (i), file); + print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), file); /* Get the data in raw format. */ - if (read_relative_register_raw_bytes (i, raw_buffer)) + if (! frame_register_read (frame, i, raw_buffer)) { - printf_filtered ("*value not available*\n"); + fprintf_filtered (file, "*value not available*\n"); continue; } + /* FIXME: cagney/2002-08-03: This code shouldn't be necessary. + The function frame_register_read() should have returned the + pre-cooked register so no conversion is necessary. */ /* Convert raw data to virtual format if necessary. */ - if (REGISTER_CONVERTIBLE (i)) + if (DEPRECATED_REGISTER_CONVERTIBLE_P () + && DEPRECATED_REGISTER_CONVERTIBLE (i)) { - REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i), + DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (i, register_type (current_gdbarch, i), raw_buffer, virtual_buffer); } else { memcpy (virtual_buffer, raw_buffer, - REGISTER_VIRTUAL_SIZE (i)); + DEPRECATED_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) + /* If virtual format is floating, print it that way, and in raw + hex. */ + if (TYPE_CODE (register_type (current_gdbarch, i)) == TYPE_CODE_FLT) { - register int j; + int j; - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); + val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0, + file, 0, 1, 0, Val_pretty_default); - printf_filtered ("\t(raw 0x"); - for (j = 0; j < REGISTER_RAW_SIZE (i); j++) + fprintf_filtered (file, "\t(raw 0x"); + for (j = 0; j < DEPRECATED_REGISTER_RAW_SIZE (i); j++) { - register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j - : REGISTER_RAW_SIZE (i) - 1 - j; - printf_filtered ("%02x", (unsigned char) raw_buffer[idx]); + int idx; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + idx = j; + else + idx = DEPRECATED_REGISTER_RAW_SIZE (i) - 1 - j; + fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]); } - printf_filtered (")"); + fprintf_filtered (file, ")"); } - /* Else print as integer in hex and in decimal. */ else { - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, - gdb_stdout, 'x', 1, 0, Val_pretty_default); - printf_filtered ("\t"); - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); + /* Print the register in hex. */ + val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0, + file, 'x', 1, 0, Val_pretty_default); + /* If not a vector register, print it also according to its + natural format. */ + if (TYPE_VECTOR (register_type (current_gdbarch, i)) == 0) + { + fprintf_filtered (file, "\t"); + val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0, + file, 0, 1, 0, Val_pretty_default); + } } - /* The SPARC wants to print even-numbered float regs as doubles - in addition to printing them as floats. */ -#ifdef PRINT_REGISTER_HOOK - PRINT_REGISTER_HOOK (i); -#endif - - printf_filtered ("\n"); + fprintf_filtered (file, "\n"); } } @@ -1649,47 +1612,104 @@ void registers_info (char *addr_exp, int fpregs) { int regnum, numregs; - register char *end; + char *end; if (!target_has_registers) error ("The program has no registers now."); - if (selected_frame == NULL) + if (deprecated_selected_frame == NULL) error ("No selected frame."); if (!addr_exp) { - DO_REGISTERS_INFO (-1, fpregs); + gdbarch_print_registers_info (current_gdbarch, gdb_stdout, + deprecated_selected_frame, -1, fpregs); return; } - do + while (*addr_exp != '\0') { + char *start; + const char *end; + + /* Keep skipping leading white space. */ + if (isspace ((*addr_exp))) + { + addr_exp++; + continue; + } + + /* Discard any leading ``$''. Check that there is something + resembling a register following it. */ if (addr_exp[0] == '$') addr_exp++; + if (isspace ((*addr_exp)) || (*addr_exp) == '\0') + error ("Missing register name"); + + /* Find the start/end of this register name/num/group. */ + start = addr_exp; + while ((*addr_exp) != '\0' && !isspace ((*addr_exp))) + addr_exp++; end = addr_exp; - while (*end != '\0' && *end != ' ' && *end != '\t') - ++end; - numregs = NUM_REGS + NUM_PSEUDO_REGS; + + /* Figure out what we've found and display it. */ - regnum = target_map_name_to_register (addr_exp, end - addr_exp); - if (regnum >= 0) - goto found; + /* A register name? */ + { + int regnum = frame_map_name_to_regnum (deprecated_selected_frame, + start, end - start); + if (regnum >= 0) + { + gdbarch_print_registers_info (current_gdbarch, gdb_stdout, + deprecated_selected_frame, regnum, fpregs); + continue; + } + } + + /* A register number? (how portable is this one?). */ + { + char *endptr; + int regnum = strtol (start, &endptr, 0); + if (endptr == end + && regnum >= 0 + && regnum < NUM_REGS + NUM_PSEUDO_REGS) + { + gdbarch_print_registers_info (current_gdbarch, gdb_stdout, + deprecated_selected_frame, regnum, fpregs); + continue; + } + } - regnum = numregs; + /* A register group? */ + { + struct reggroup *group; + for (group = reggroup_next (current_gdbarch, NULL); + group != NULL; + group = reggroup_next (current_gdbarch, group)) + { + /* Don't bother with a length check. Should the user + enter a short register group name, go with the first + group that matches. */ + if (strncmp (start, reggroup_name (group), end - start) == 0) + break; + } + if (group != NULL) + { + int regnum; + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (gdbarch_register_reggroup_p (current_gdbarch, regnum, + group)) + gdbarch_print_registers_info (current_gdbarch, + gdb_stdout, deprecated_selected_frame, + regnum, fpregs); + } + continue; + } + } - if (*addr_exp >= '0' && *addr_exp <= '9') - regnum = atoi (addr_exp); /* Take a number */ - if (regnum >= numregs) /* Bad name, or bad number */ - error ("%.*s: invalid register", end - addr_exp, addr_exp); - - found: - DO_REGISTERS_INFO (regnum, fpregs); - - addr_exp = end; - while (*addr_exp == ' ' || *addr_exp == '\t') - ++addr_exp; + /* Nothing matched. */ + error ("Invalid register `%.*s'", (int) (end - start), start); } - while (*addr_exp != '\0'); } void @@ -1698,11 +1718,46 @@ all_registers_info (char *addr_exp, int from_tty) registers_info (addr_exp, 1); } -void +static void nofp_registers_info (char *addr_exp, int from_tty) { registers_info (addr_exp, 0); } + +static void +print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) +{ + if (!target_has_registers) + error ("The program has no registers now."); + if (deprecated_selected_frame == NULL) + error ("No selected frame."); + + if (gdbarch_print_vector_info_p (gdbarch)) + gdbarch_print_vector_info (gdbarch, file, frame, args); + else + { + int regnum; + int printed_something = 0; + + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup)) + { + printed_something = 1; + gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1); + } + } + if (!printed_something) + fprintf_filtered (file, "No vector information\n"); + } +} + +static void +vector_info (char *args, int from_tty) +{ + print_vector_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args); +} /* @@ -1754,8 +1809,13 @@ attach_command (char *args, int from_tty) /* No traps are generated when attaching to inferior under Mach 3 or GNU hurd. */ #ifndef ATTACH_NO_WAIT - stop_soon_quietly = 1; + /* Careful here. See comments in inferior.h. Basically some OSes + don't ignore SIGSTOPs on continue requests anymore. We need a + way for handle_inferior_event to reset the stop_signal variable + after an attach, and this is what STOP_QUIETLY_NO_SIGSTOP is for. */ + stop_soon = STOP_QUIETLY_NO_SIGSTOP; wait_for_inferior (); + stop_soon = NO_STOP_QUIETLY; #endif /* @@ -1823,16 +1883,29 @@ detach_command (char *args, int from_tty) detach_hook (); } -/* Stop the execution of the target while running in async mode, in - the backgound. */ +/* Disconnect from the current target without resuming it (leaving it + waiting for a debugger). -void -interrupt_target_command_wrapper (char *args, int from_tty) -{ - interrupt_target_command (args, from_tty); -} + We'd better not have left any breakpoints in the program or the + next debugger will get confused. Currently only supported for some + remote targets, since the normal attach mechanisms don't work on + stopped processes on some native platforms (e.g. GNU/Linux). */ static void +disconnect_command (char *args, int from_tty) +{ + dont_repeat (); /* Not for the faint of heart */ + target_disconnect (args, from_tty); +#if defined(SOLIB_RESTART) + SOLIB_RESTART (); +#endif + if (detach_hook) + detach_hook (); +} + +/* Stop the execution of the target while running in async mode, in + the backgound. */ +void interrupt_target_command (char *args, int from_tty) { if (event_loop_p && target_can_async_p ()) @@ -1842,14 +1915,42 @@ interrupt_target_command (char *args, int from_tty) } } -/* ARGSUSED */ static void -float_info (char *addr_exp, int from_tty) +print_float_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) { - PRINT_FLOAT_INFO (); + if (!target_has_registers) + error ("The program has no registers now."); + if (deprecated_selected_frame == NULL) + error ("No selected frame."); + + if (gdbarch_print_float_info_p (gdbarch)) + gdbarch_print_float_info (gdbarch, file, frame, args); + else + { + int regnum; + int printed_something = 0; + + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup)) + { + printed_something = 1; + gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1); + } + } + if (!printed_something) + fprintf_filtered (file, "\ +No floating-point info available for this processor.\n"); + } +} + +static void +float_info (char *args, int from_tty) +{ + print_float_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args); } -/* ARGSUSED */ static void unset_command (char *args, int from_tty) { @@ -1865,14 +1966,14 @@ _initialize_infcmd (void) c = add_com ("tty", class_run, tty_command, "Set terminal for future runs of program being debugged."); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); c = add_set_cmd ("args", class_run, var_string_noescape, (char *) &inferior_args, "Set argument list to give program being debugged when it is started.\n\ Follow this command with any number of args, to be passed to the program.", &setlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); set_cmd_sfunc (c, notice_args_set); c = add_show_from_set (c, &showlist); set_cmd_sfunc (c, notice_args_read); @@ -1883,17 +1984,17 @@ Follow this command with any number of args, to be passed to the program.", With an argument VAR, prints the value of environment variable VAR to\n\ give the program being debugged. With no arguments, prints the entire\n\ environment to be given to the program.", &showlist); - c->completer = noop_completer; + set_cmd_completer (c, noop_completer); add_prefix_cmd ("unset", no_class, unset_command, - "Complement to certain \"set\" commands", + "Complement to certain \"set\" commands.", &unsetlist, "unset ", 0, &cmdlist); c = add_cmd ("environment", class_run, unset_environment_command, "Cancel environment variable VAR for the program.\n\ This does not affect the program until the next \"run\" command.", &unsetlist); - c->completer = noop_completer; + set_cmd_completer (c, noop_completer); c = add_cmd ("environment", class_run, set_environment_command, "Set environment variable value to give the program.\n\ @@ -1901,7 +2002,7 @@ Arguments are VAR VALUE where VAR is variable name and VALUE is value.\n\ VALUES of environment variables are uninterpreted strings.\n\ This does not affect the program until the next \"run\" command.", &setlist); - c->completer = noop_completer; + set_cmd_completer (c, noop_completer); c = add_com ("path", class_files, path_command, "Add directory DIR(s) to beginning of search path for object files.\n\ @@ -1909,7 +2010,7 @@ $cwd in the path means the current working directory.\n\ This path is equivalent to the $PATH shell variable. It is a list of\n\ directories, separated by colons. These directories are searched to find\n\ fully linked executable files and separately compiled object files as needed."); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); c = add_cmd ("paths", no_class, path_info, "Current search path for finding object files.\n\ @@ -1918,7 +2019,7 @@ This path is equivalent to the $PATH shell variable. It is a list of\n\ directories, separated by colons. These directories are searched to find\n\ fully linked executable files and separately compiled object files as needed.", &showlist); - c->completer = noop_completer; + set_cmd_completer (c, noop_completer); add_com ("attach", class_run, attach_command, "Attach to a process or file outside of GDB.\n\ @@ -1938,6 +2039,11 @@ to specify the program, and to load its symbol table."); If a process, it is no longer traced, and it continues its execution. If\n\ you were debugging a file, the file is closed and gdb no longer accesses it."); + add_com ("disconnect", class_run, disconnect_command, + "Disconnect from a target.\n\ +The target will wait for another debugger to connect. Not available for\n\ +all targets."); + add_com ("signal", class_run, signal_command, "Continue program giving it signal specified by the argument.\n\ An argument of \"0\" means continue program without giving it a signal."); @@ -1972,16 +2078,20 @@ Argument N means do this N times (or till program stops for another reason)."); c = add_com ("until", class_run, until_command, "Execute until the program reaches a source line greater than the current\n\ -or a specified line or address or function (same args as break command).\n\ -Execution will also stop upon exit from the current stack frame."); - c->completer = location_completer; +or a specified location (same args as break command) within the current frame."); + set_cmd_completer (c, location_completer); add_com_alias ("u", "until", class_run, 1); + c = add_com ("advance", class_run, advance_command, + "Continue the program up to the given location (same form as args for break command).\n\ +Execution will also stop upon exit from the current stack frame."); + set_cmd_completer (c, location_completer); + c = add_com ("jump", class_run, jump_command, "Continue program being debugged at specified line or address.\n\ Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\ for an address to start at."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); if (xdb_commands) { @@ -1992,7 +2102,7 @@ address.\n\ Give as argument either LINENUM or *ADDR, where ADDR is an \n\ expression for an address to start at.\n\ This command is a combination of tbreak and jump."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); } if (xdb_commands) @@ -2013,7 +2123,7 @@ Input and output redirection with \">\", \"<\", or \">>\" are also allowed.\n\n\ With no arguments, uses arguments last specified (with \"run\" or \"set args\").\n\ To cancel previous arguments and run with no arguments,\n\ use \"set args\" without arguments."); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_com_alias ("r", "run", class_run, 1); if (xdb_commands) add_com ("R", class_run, run_no_args_command, @@ -2041,6 +2151,9 @@ Register name as argument means describe only that register."); add_info ("float", float_info, "Print the status of the floating point unit\n"); + add_info ("vector", vector_info, + "Print the status of the vector unit\n"); + inferior_environ = make_environ (); init_environ (inferior_environ); } diff --git a/contrib/gdb/gdb/inferior.h b/contrib/gdb/gdb/inferior.h index 93c8d9b3b95..b36dcd45b1d 100644 --- a/contrib/gdb/gdb/inferior.h +++ b/contrib/gdb/gdb/inferior.h @@ -1,7 +1,8 @@ /* Variables that describe the inferior process running under GDB: Where it is, why it stopped, and how to step it. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -23,12 +24,22 @@ #if !defined (INFERIOR_H) #define INFERIOR_H 1 +struct target_waitstatus; +struct frame_info; +struct ui_file; +struct type; +struct gdbarch; +struct regcache; + /* For bpstat. */ #include "breakpoint.h" /* For enum target_signal. */ #include "target.h" +/* For struct frame_id. */ +#include "frame.h" + /* Structure in which to save the status of the inferior. Create/Save through "save_inferior_status", restore through "restore_inferior_status". @@ -149,16 +160,14 @@ extern void kill_inferior (void); extern void generic_mourn_inferior (void); -extern void terminal_ours (void); +extern void terminal_save_ours (void); -extern int run_stack_dummy (CORE_ADDR, char *); +extern void terminal_ours (void); extern CORE_ADDR read_pc (void); extern CORE_ADDR read_pc_pid (ptid_t); -extern CORE_ADDR generic_target_read_pc (ptid_t); - extern void write_pc (CORE_ADDR); extern void write_pc_pid (CORE_ADDR, ptid_t); @@ -167,25 +176,16 @@ extern void generic_target_write_pc (CORE_ADDR, ptid_t); extern CORE_ADDR read_sp (void); -extern CORE_ADDR generic_target_read_sp (void); +extern void deprecated_write_sp (CORE_ADDR); -extern void write_sp (CORE_ADDR); +extern CORE_ADDR deprecated_read_fp (void); -extern void generic_target_write_sp (CORE_ADDR); - -extern CORE_ADDR read_fp (void); - -extern CORE_ADDR generic_target_read_fp (void); - -extern void write_fp (CORE_ADDR); - -extern void generic_target_write_fp (CORE_ADDR); - -extern CORE_ADDR unsigned_pointer_to_address (struct type *type, void *buf); +extern CORE_ADDR unsigned_pointer_to_address (struct type *type, const void *buf); extern void unsigned_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr); -extern CORE_ADDR signed_pointer_to_address (struct type *type, void *buf); +extern CORE_ADDR signed_pointer_to_address (struct type *type, + const void *buf); extern void address_to_signed_pointer (struct type *type, void *buf, CORE_ADDR addr); @@ -206,7 +206,10 @@ extern void resume (int, enum target_signal); /* From misc files */ -extern void do_registers_info (int, int); +extern void default_print_registers_info (struct gdbarch *gdbarch, + struct ui_file *file, + struct frame_info *frame, + int regnum, int all); extern void store_inferior_registers (int); @@ -230,14 +233,6 @@ extern void terminal_init_inferior_with_pgrp (int pgrp); extern int attach (int); -#if !defined(REQUIRE_ATTACH) -#define REQUIRE_ATTACH attach -#endif - -#if !defined(REQUIRE_DETACH) -#define REQUIRE_DETACH(pid,siggnal) detach (siggnal) -#endif - extern void detach (int); /* PTRACE method of waiting for inferior process. */ @@ -266,8 +261,6 @@ extern void fork_inferior (char *, char *, char **, void (*)(int), void (*)(void), char *); -extern void clone_and_follow_inferior (int, int *); - extern void startup_inferior (int); extern char *construct_inferior_arguments (struct gdbarch *, int, char **); @@ -299,6 +292,8 @@ extern int signal_pass_update (int, int); extern void get_last_target_status(ptid_t *ptid, struct target_waitstatus *status); +extern void follow_inferior_reset_breakpoints (void); + /* From infcmd.c */ extern void tty_command (char *, int); @@ -311,6 +306,16 @@ extern char *set_inferior_args (char *); extern void set_inferior_args_vector (int, char **); +extern void registers_info (char *, int); + +extern void nexti_command (char *, int); + +extern void stepi_command (char *, int); + +extern void continue_command (char *, int); + +extern void interrupt_target_command (char *args, int from_tty); + /* Last signal that the inferior received (why it stopped). */ extern enum target_signal stop_signal; @@ -357,7 +362,7 @@ extern CORE_ADDR step_range_end; /* Exclusive */ This is how we know when we step into a subroutine call, and how to set the frame for the breakpoint used to step out. */ -extern CORE_ADDR step_frame_address; +extern struct frame_id step_frame_id; /* Our notion of the current stack pointer. */ @@ -381,12 +386,37 @@ extern enum step_over_calls_kind step_over_calls; extern int step_multi; -/* Nonzero means expecting a trap and caller will handle it themselves. - It is used after attach, due to attaching to a process; - when running in the shell before the child program has been exec'd; - and when running some kinds of remote stuff (FIXME?). */ +/* Nonzero means expecting a trap and caller will handle it + themselves. It is used when running in the shell before the child + program has been exec'd; and when running some kinds of remote + stuff (FIXME?). */ -extern int stop_soon_quietly; +/* It is also used after attach, due to attaching to a process. This + is a bit trickier. When doing an attach, the kernel stops the + debuggee with a SIGSTOP. On newer GNU/Linux kernels (>= 2.5.61) + the handling of SIGSTOP for a ptraced process has changed. Earlier + versions of the kernel would ignore these SIGSTOPs, while now + SIGSTOP is treated like any other signal, i.e. it is not muffled. + + If the gdb user does a 'continue' after the 'attach', gdb passes + the global variable stop_signal (which stores the signal from the + attach, SIGSTOP) to the ptrace(PTRACE_CONT,...) call. This is + problematic, because the kernel doesn't ignore such SIGSTOP + now. I.e. it is reported back to gdb, which in turn presents it + back to the user. + + To avoid the problem, we use STOP_QUIETLY_NO_SIGSTOP, which allows + gdb to clear the value of stop_signal after the attach, so that it + is not passed back down to the kernel. */ + +enum stop_kind + { + NO_STOP_QUIETLY = 0, + STOP_QUIETLY, + STOP_QUIETLY_NO_SIGSTOP + }; + +extern enum stop_kind stop_soon; /* Nonzero if proceed is being used for a "finish" command or a similar situation when stop_registers should be saved. */ @@ -398,98 +428,25 @@ extern int proceed_to_finish; Thus this contains the return value from the called function (assuming values are returned in a register). */ -extern char *stop_registers; +extern struct regcache *stop_registers; /* Nonzero if the child process in inferior_ptid was attached rather than forked. */ extern int attach_flag; -/* Sigtramp is a routine that the kernel calls (which then calls the - signal handler). On most machines it is a library routine that - is linked into the executable. - - This macro, given a program counter value and the name of the - function in which that PC resides (which can be null if the - name is not known), returns nonzero if the PC and name show - that we are in sigtramp. - - On most machines just see if the name is sigtramp (and if we have - no name, assume we are not in sigtramp). */ -#if !defined (IN_SIGTRAMP) -#if defined (SIGTRAMP_START) -#define IN_SIGTRAMP(pc, name) \ - ((pc) >= SIGTRAMP_START(pc) \ - && (pc) < SIGTRAMP_END(pc) \ - ) -#else -#define IN_SIGTRAMP(pc, name) \ - (name && STREQ ("_sigtramp", name)) -#endif -#endif - /* Possible values for CALL_DUMMY_LOCATION. */ #define ON_STACK 1 -#define BEFORE_TEXT_END 2 -#define AFTER_TEXT_END 3 #define AT_ENTRY_POINT 4 - -#if !defined (USE_GENERIC_DUMMY_FRAMES) -#define USE_GENERIC_DUMMY_FRAMES 0 -#endif - -#if !defined (CALL_DUMMY_LOCATION) -#define CALL_DUMMY_LOCATION ON_STACK -#endif /* No CALL_DUMMY_LOCATION. */ - -#if !defined (CALL_DUMMY_ADDRESS) -#define CALL_DUMMY_ADDRESS() (internal_error (__FILE__, __LINE__, "CALL_DUMMY_ADDRESS"), 0) -#endif -#if !defined (CALL_DUMMY_START_OFFSET) -#define CALL_DUMMY_START_OFFSET (internal_error (__FILE__, __LINE__, "CALL_DUMMY_START_OFFSET"), 0) -#endif -#if !defined (CALL_DUMMY_BREAKPOINT_OFFSET) -#define CALL_DUMMY_BREAKPOINT_OFFSET_P (0) -#define CALL_DUMMY_BREAKPOINT_OFFSET (internal_error (__FILE__, __LINE__, "CALL_DUMMY_BREAKPOINT_OFFSET"), 0) -#endif -#if !defined CALL_DUMMY_BREAKPOINT_OFFSET_P -#define CALL_DUMMY_BREAKPOINT_OFFSET_P (1) -#endif -#if !defined (CALL_DUMMY_LENGTH) -#define CALL_DUMMY_LENGTH (internal_error (__FILE__, __LINE__, "CALL_DUMMY_LENGTH"), 0) -#endif - -#if defined (CALL_DUMMY_STACK_ADJUST) -#if !defined (CALL_DUMMY_STACK_ADJUST_P) -#define CALL_DUMMY_STACK_ADJUST_P (1) -#endif -#endif -#if !defined (CALL_DUMMY_STACK_ADJUST) -#define CALL_DUMMY_STACK_ADJUST (internal_error (__FILE__, __LINE__, "CALL_DUMMY_STACK_ADJUST"), 0) -#endif -#if !defined (CALL_DUMMY_STACK_ADJUST_P) -#define CALL_DUMMY_STACK_ADJUST_P (0) -#endif +#define AT_SYMBOL 5 /* FIXME: cagney/2000-04-17: gdbarch should manage this. The default shouldn't be necessary. */ -#if !defined (CALL_DUMMY_P) -#if defined (CALL_DUMMY) -#define CALL_DUMMY_P 1 -#else -#define CALL_DUMMY_P 0 -#endif -#endif - #if !defined PUSH_DUMMY_FRAME #define PUSH_DUMMY_FRAME (internal_error (__FILE__, __LINE__, "PUSH_DUMMY_FRAME"), 0) #endif -#if !defined FIX_CALL_DUMMY -#define FIX_CALL_DUMMY(a1,a2,a3,a4,a5,a6,a7) (internal_error (__FILE__, __LINE__, "FIX_CALL_DUMMY"), 0) -#endif - #if !defined STORE_STRUCT_RETURN #define STORE_STRUCT_RETURN(a1,a2) (internal_error (__FILE__, __LINE__, "STORE_STRUCT_RETURN"), 0) #endif @@ -497,59 +454,23 @@ extern int attach_flag; /* Are we in a call dummy? */ -extern int pc_in_call_dummy_before_text_end (CORE_ADDR pc, CORE_ADDR sp, - CORE_ADDR frame_address); -#if !GDB_MULTI_ARCH -#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == BEFORE_TEXT_END -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_before_text_end (pc, sp, frame_address) -#endif /* Before text_end. */ -#endif +/* NOTE: cagney/2002-11-24: Targets need to both switch to generic + dummy frames, and use generic_pc_in_call_dummy(). The generic + version should be able to handle all cases since that code works by + saving the address of the dummy's breakpoint (where ever it is). */ -extern int pc_in_call_dummy_after_text_end (CORE_ADDR pc, CORE_ADDR sp, - CORE_ADDR frame_address); -#if !GDB_MULTI_ARCH -#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == AFTER_TEXT_END -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_after_text_end (pc, sp, frame_address) -#endif -#endif +extern int deprecated_pc_in_call_dummy_on_stack (CORE_ADDR pc, + CORE_ADDR sp, + CORE_ADDR frame_address); -extern int pc_in_call_dummy_on_stack (CORE_ADDR pc, CORE_ADDR sp, - CORE_ADDR frame_address); -#if !GDB_MULTI_ARCH -#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == ON_STACK -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_on_stack (pc, sp, frame_address) -#endif -#endif +/* NOTE: cagney/2002-11-24: Targets need to both switch to generic + dummy frames, and use generic_pc_in_call_dummy(). The generic + version should be able to handle all cases since that code works by + saving the address of the dummy's breakpoint (where ever it is). */ -extern int pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp, - CORE_ADDR frame_address); -#if !GDB_MULTI_ARCH -#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == AT_ENTRY_POINT -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_at_entry_point (pc, sp, frame_address) -#endif -#endif - -/* It's often not enough for our clients to know whether the PC is merely - somewhere within the call dummy. They may need to know whether the - call dummy has actually completed. (For example, wait_for_inferior - wants to know when it should truly stop because the call dummy has - completed. If we're single-stepping because of slow watchpoints, - then we may find ourselves stopped at the entry of the call dummy, - and want to continue stepping until we reach the end.) - - Note that this macro is intended for targets (like HP-UX) which - require more than a single breakpoint in their call dummies, and - therefore cannot use the CALL_DUMMY_BREAKPOINT_OFFSET mechanism. - - If a target does define CALL_DUMMY_BREAKPOINT_OFFSET, then this - default implementation of CALL_DUMMY_HAS_COMPLETED is sufficient. - Else, a target may wish to supply an implementation that works in - the presense of multiple breakpoints in its call dummy. - */ -#if !defined(CALL_DUMMY_HAS_COMPLETED) -#define CALL_DUMMY_HAS_COMPLETED(pc, sp, frame_address) \ - PC_IN_CALL_DUMMY((pc), (sp), (frame_address)) -#endif +extern int deprecated_pc_in_call_dummy_at_entry_point (CORE_ADDR pc, + CORE_ADDR sp, + CORE_ADDR frame_address); /* If STARTUP_WITH_SHELL is set, GDB's "run" will attempts to start up the debugee under a shell. diff --git a/contrib/gdb/gdb/inflow.c b/contrib/gdb/gdb/inflow.c index 66671f7a681..35cd79968b9 100644 --- a/contrib/gdb/gdb/inflow.c +++ b/contrib/gdb/gdb/inflow.c @@ -1,6 +1,7 @@ /* Low level interface to ptrace, for GDB when running under Unix. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GDB. @@ -35,22 +36,7 @@ #include #endif -#ifdef HAVE_TERMIOS -#define PROCESS_GROUP_TYPE pid_t -#endif - -#ifdef HAVE_TERMIO -#define PROCESS_GROUP_TYPE int -#endif - -#ifdef HAVE_SGTTY -#ifdef SHORT_PGRP -/* This is only used for the ultra. Does it have pid_t? */ -#define PROCESS_GROUP_TYPE short -#else -#define PROCESS_GROUP_TYPE int -#endif -#endif /* sgtty */ +#include "inflow.h" #ifdef HAVE_SYS_IOCTL_H #include @@ -171,7 +157,7 @@ gdb_has_a_terminal (void) #define OOPSY(what) \ if (result == -1) \ fprintf_unfiltered(gdb_stderr, "[%s failed in terminal_inferior: %s]\n", \ - what, strerror (errno)) + what, safe_strerror (errno)) static void terminal_ours_1 (int); @@ -200,6 +186,23 @@ terminal_init_inferior_with_pgrp (int pgrp) } } +/* Save the terminal settings again. This is necessary for the TUI + when it switches to TUI or non-TUI mode; curses changes the terminal + and gdb must be able to restore it correctly. */ + +void +terminal_save_ours (void) +{ + if (gdb_has_a_terminal ()) + { + /* We could just as well copy our_ttystate (if we felt like adding + a new function serial_copy_tty_state). */ + if (our_ttystate) + xfree (our_ttystate); + our_ttystate = serial_get_tty_state (stdin_serial); + } +} + void terminal_init_inferior (void) { @@ -221,6 +224,7 @@ void terminal_inferior (void) { if (gdb_has_a_terminal () && terminal_is_ours + && inferior_ttystate != NULL && inferior_thisrun_terminal == 0) { int result; @@ -374,7 +378,7 @@ terminal_ours_1 (int output_only) such situations as well. */ if (result == -1) fprintf_unfiltered (gdb_stderr, "[tcsetpgrp failed in terminal_ours: %s]\n", - strerror (errno)); + safe_strerror (errno)); #endif #endif /* termios */ @@ -410,14 +414,12 @@ terminal_ours_1 (int output_only) } } -/* ARGSUSED */ void term_info (char *arg, int from_tty) { target_terminal_info (arg, from_tty); } -/* ARGSUSED */ void child_terminal_info (char *args, int from_tty) { @@ -513,7 +515,7 @@ new_tty_prefork (char *ttyname) void new_tty (void) { - register int tty; + int tty; if (inferior_thisrun_terminal == 0) return; @@ -570,7 +572,6 @@ new_tty (void) /* Kill the inferior process. Make us have no inferior. */ -/* ARGSUSED */ static void kill_command (char *arg, int from_tty) { @@ -591,17 +592,17 @@ kill_command (char *arg, int from_tty) if (target_has_stack) { printf_filtered ("In %s,\n", target_longname); - if (selected_frame == NULL) + if (deprecated_selected_frame == NULL) fputs_filtered ("No selected stack frame.\n", gdb_stdout); else - print_stack_frame (selected_frame, selected_frame_level, 1); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); } } /* Call set_sigint_trap when you need to pass a signal on to an attached process when handling SIGINT */ -/* ARGSUSED */ static void pass_signal (int signo) { diff --git a/contrib/gdb/gdb/inflow.h b/contrib/gdb/gdb/inflow.h new file mode 100644 index 00000000000..1cbfa71b484 --- /dev/null +++ b/contrib/gdb/gdb/inflow.h @@ -0,0 +1,51 @@ +/* Low level interface to ptrace, for GDB when running under Unix. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef INFLOW_H +#define INFLOW_H + +#include "terminal.h" /* For HAVE_TERMIOS et.al. */ + +#ifdef HAVE_TERMIOS +#define PROCESS_GROUP_TYPE pid_t +#endif + +#ifdef HAVE_TERMIO +#define PROCESS_GROUP_TYPE int +#endif + +#ifdef HAVE_SGTTY +#ifdef SHORT_PGRP +/* This is only used for the ultra. Does it have pid_t? */ +#define PROCESS_GROUP_TYPE short +#else +#define PROCESS_GROUP_TYPE int +#endif +#endif /* sgtty */ + +#ifdef PROCESS_GROUP_TYPE +/* Process group for us and the inferior. Saved and restored just like + {our,inferior}_ttystate. */ +extern PROCESS_GROUP_TYPE our_process_group; +extern PROCESS_GROUP_TYPE inferior_process_group; +#endif + +#endif diff --git a/contrib/gdb/gdb/infptrace.c b/contrib/gdb/gdb/infptrace.c index 777a5b491ed..ef86f90cf2e 100644 --- a/contrib/gdb/gdb/infptrace.c +++ b/contrib/gdb/gdb/infptrace.c @@ -208,6 +208,7 @@ ptrace_wait (ptid_t ptid, int *status) return wstate; } +#ifndef KILL_INFERIOR void kill_inferior (void) { @@ -229,6 +230,7 @@ kill_inferior (void) ptrace_wait (null_ptid, &status); target_mourn_inferior (); } +#endif /* KILL_INFERIOR */ #ifndef CHILD_RESUME @@ -302,7 +304,7 @@ detach (int signal) ptrace (PT_DETACH, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) 1, signal); if (errno) - perror_with_name ("ptrace"); + print_sys_errmsg ("ptrace", errno); attach_flag = 0; } #endif /* ATTACH_DETACH */ @@ -357,14 +359,14 @@ fetch_register (int regno) /* This isn't really an address. But ptrace thinks of it as one. */ CORE_ADDR regaddr; char mess[128]; /* For messages */ - register int i; + int i; unsigned int offset; /* Offset of registers within the u area. */ - char *buf = alloca (MAX_REGISTER_RAW_SIZE); + char buf[MAX_REGISTER_SIZE]; int tid; if (CANNOT_FETCH_REGISTER (regno)) { - memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ + memset (buf, '\0', DEPRECATED_REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ supply_register (regno, buf); return; } @@ -376,7 +378,7 @@ fetch_register (int regno) offset = U_REGS_OFFSET; regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid, @@ -421,10 +423,10 @@ store_register (int regno) /* This isn't really an address. But ptrace thinks of it as one. */ CORE_ADDR regaddr; char mess[128]; /* For messages */ - register int i; + int i; unsigned int offset; /* Offset of registers within the u area. */ int tid; - char *buf = alloca (MAX_REGISTER_RAW_SIZE); + char buf[MAX_REGISTER_SIZE]; if (CANNOT_STORE_REGISTER (regno)) { @@ -443,7 +445,7 @@ store_register (int regno) regcache_collect (regno, buf); /* Store the local buffer into the inferior a chunk at the time. */ - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr, @@ -514,6 +516,37 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, PTRACE_XFER_TYPE *buffer; struct cleanup *old_chain = NULL; +#ifdef PT_IO + /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO request + that promises to be much more efficient in reading and writing + data in the traced process's address space. */ + + { + struct ptrace_io_desc piod; + + /* NOTE: We assume that there are no distinct address spaces for + instruction and data. */ + piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D; + piod.piod_offs = (void *) memaddr; + piod.piod_addr = myaddr; + piod.piod_len = len; + + if (ptrace (PT_IO, PIDGET (inferior_ptid), (caddr_t) &piod, 0) == -1) + { + /* If the PT_IO request is somehow not supported, fallback on + using PT_WRITE_D/PT_READ_D. Otherwise we will return zero + to indicate failure. */ + if (errno != EINVAL) + return 0; + } + else + { + /* Return the actual number of bytes read or written. */ + return piod.piod_len; + } + } +#endif + /* Allocate buffer of that many longwords. */ if (len < GDB_MAX_ALLOCA) { @@ -598,7 +631,7 @@ static void udot_info (char *dummy1, int dummy2) { #if defined (KERNEL_U_SIZE) - int udot_off; /* Offset into user struct */ + long udot_off; /* Offset into user struct */ int udot_val; /* Value from user struct at udot_off */ char mess[128]; /* For messages */ #endif @@ -626,12 +659,13 @@ udot_info (char *dummy1, int dummy2) { printf_filtered ("\n"); } - printf_filtered ("%04x:", udot_off); + printf_filtered ("%s:", paddr (udot_off)); } udot_val = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) udot_off, 0); if (errno != 0) { - sprintf (mess, "\nreading user struct at offset 0x%x", udot_off); + sprintf (mess, "\nreading user struct at offset 0x%s", + paddr_nz (udot_off)); perror_with_name (mess); } /* Avoid using nonportable (?) "*" in print specs */ diff --git a/contrib/gdb/gdb/infrun.c b/contrib/gdb/gdb/infrun.c index 6ae8f7c468b..6bbee5e8176 100644 --- a/contrib/gdb/gdb/infrun.c +++ b/contrib/gdb/gdb/infrun.c @@ -2,8 +2,8 @@ process. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -42,6 +42,9 @@ #include "inf-loop.h" #include "regcache.h" #include "value.h" +#include "observer.h" +#include "language.h" +#include "gdb_assert.h" /* Prototypes for local functions */ @@ -59,26 +62,14 @@ static int hook_stop_stub (void *); static void delete_breakpoint_current_contents (void *); -static void set_follow_fork_mode_command (char *arg, int from_tty, - struct cmd_list_element * c); - -static struct inferior_status *xmalloc_inferior_status (void); - -static void free_inferior_status (struct inferior_status *); - static int restore_selected_frame (void *); static void build_infrun (void); -static void follow_inferior_fork (int parent_pid, int child_pid, - int has_forked, int has_vforked); - -static void follow_fork (int parent_pid, int child_pid); - -static void follow_vfork (int parent_pid, int child_pid); +static int follow_fork (void); static void set_schedlock_func (char *args, int from_tty, - struct cmd_list_element * c); + struct cmd_list_element *c); struct execution_control_state; @@ -86,6 +77,8 @@ static int currently_stepping (struct execution_control_state *ecs); static void xdb_handle_command (char *args, int from_tty); +static int prepare_to_proceed (void); + void _initialize_infrun (void); int inferior_ignoring_startup_exec_events = 0; @@ -115,21 +108,6 @@ static ptid_t previous_inferior_ptid; static int may_follow_exec = MAY_FOLLOW_EXEC; -/* Dynamic function trampolines are similar to solib trampolines in that they - are between the caller and the callee. The difference is that when you - enter a dynamic trampoline, you can't determine the callee's address. Some - (usually complex) code needs to run in the dynamic trampoline to figure out - the callee's address. This macro is usually called twice. First, when we - enter the trampoline (looks like a normal function call at that point). It - should return the PC of a point within the trampoline where the callee's - address is known. Second, when we hit the breakpoint, this routine returns - the callee's address. At that point, things proceed as per a step resume - breakpoint. */ - -#ifndef DYNAMIC_TRAMPOLINE_NEXTPC -#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0 -#endif - /* If the program uses ELF-style shared libraries, then calls to functions in shared libraries go through stubs, which live in a table called the PLT (Procedure Linkage Table). The first time the @@ -173,17 +151,6 @@ static int may_follow_exec = MAY_FOLLOW_EXEC; #define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) 0 #endif -#ifndef SKIP_SOLIB_RESOLVER -#define SKIP_SOLIB_RESOLVER(pc) 0 -#endif - -/* In some shared library schemes, the return path from a shared library - call may need to go through a trampoline too. */ - -#ifndef IN_SOLIB_RETURN_TRAMPOLINE -#define IN_SOLIB_RETURN_TRAMPOLINE(pc,name) 0 -#endif - /* This function returns TRUE if pc is the address of an instruction that lies within the dynamic linker (such as the event hook, or the dld itself). @@ -219,7 +186,7 @@ static int may_follow_exec = MAY_FOLLOW_EXEC; instruction. This macro should expand to a pointer to a function that does that, or zero if we have no such function. If we don't have a definition for it, we have to report an error. */ -#ifndef SKIP_PERMANENT_BREAKPOINT +#ifndef SKIP_PERMANENT_BREAKPOINT #define SKIP_PERMANENT_BREAKPOINT (default_skip_permanent_breakpoint) static void default_skip_permanent_breakpoint (void) @@ -230,7 +197,7 @@ how to step past a permanent breakpoint on this architecture. Try using\n\ a command like `return' or `jump' to continue execution."); } #endif - + /* Convert the #defines into values. This is temporary until wfi control flow is completely sorted out. */ @@ -242,20 +209,6 @@ a command like `return' or `jump' to continue execution."); #define HAVE_STEPPABLE_WATCHPOINT 1 #endif -#ifndef HAVE_NONSTEPPABLE_WATCHPOINT -#define HAVE_NONSTEPPABLE_WATCHPOINT 0 -#else -#undef HAVE_NONSTEPPABLE_WATCHPOINT -#define HAVE_NONSTEPPABLE_WATCHPOINT 1 -#endif - -#ifndef HAVE_CONTINUABLE_WATCHPOINT -#define HAVE_CONTINUABLE_WATCHPOINT 0 -#else -#undef HAVE_CONTINUABLE_WATCHPOINT -#define HAVE_CONTINUABLE_WATCHPOINT 1 -#endif - #ifndef CANNOT_STEP_HW_WATCHPOINTS #define CANNOT_STEP_HW_WATCHPOINTS 0 #else @@ -329,7 +282,7 @@ int stop_after_trap; when running in the shell before the child program has been exec'd; and when running some kinds of remote stuff (FIXME?). */ -int stop_soon_quietly; +enum stop_kind stop_soon; /* Nonzero if proceed is being used for a "finish" command or a similar situation when stop_registers should be saved. */ @@ -341,7 +294,7 @@ int proceed_to_finish; Thus this contains the return value from the called function (assuming values are returned in a register). */ -char *stop_registers; +struct regcache *stop_registers; /* Nonzero if program stopped due to error trying to insert breakpoints. */ @@ -373,49 +326,22 @@ static struct target_waitstatus target_last_waitstatus; followed at the next resume of the inferior, and not immediately. */ static struct +{ + enum target_waitkind kind; + struct { - enum target_waitkind kind; - struct - { - int parent_pid; - int saw_parent_fork; - int child_pid; - int saw_child_fork; - int saw_child_exec; - } - fork_event; - char *execd_pathname; + int parent_pid; + int child_pid; } + fork_event; + char *execd_pathname; +} pending_follow; -/* Some platforms don't allow us to do anything meaningful with a - vforked child until it has exec'd. Vforked processes on such - platforms can only be followed after they've exec'd. - - When this is set to 0, a vfork can be immediately followed, - and an exec can be followed merely as an exec. When this is - set to 1, a vfork event has been seen, but cannot be followed - until the exec is seen. - - (In the latter case, inferior_ptid is still the parent of the - vfork, and pending_follow.fork_event.child_pid is the child. The - appropriate process is followed, according to the setting of - follow-fork-mode.) */ -static int follow_vfork_when_exec; - -static const char follow_fork_mode_ask[] = "ask"; -static const char follow_fork_mode_both[] = "both"; static const char follow_fork_mode_child[] = "child"; static const char follow_fork_mode_parent[] = "parent"; -static const char *follow_fork_mode_kind_names[] = -{ - follow_fork_mode_ask, - /* ??rehrauer: The "both" option is broken, by what may be a 10.20 - kernel problem. It's also not terribly useful without a GUI to - help the user drive two debuggers. So for now, I'm disabling the - "both" option. */ - /* follow_fork_mode_both, */ +static const char *follow_fork_mode_kind_names[] = { follow_fork_mode_child, follow_fork_mode_parent, NULL @@ -424,196 +350,38 @@ static const char *follow_fork_mode_kind_names[] = static const char *follow_fork_mode_string = follow_fork_mode_parent; -static void -follow_inferior_fork (int parent_pid, int child_pid, int has_forked, - int has_vforked) +static int +follow_fork (void) { - int followed_parent = 0; - int followed_child = 0; + int follow_child = (follow_fork_mode_string == follow_fork_mode_child); - /* Which process did the user want us to follow? */ - const char *follow_mode = follow_fork_mode_string; - - /* Or, did the user not know, and want us to ask? */ - if (follow_fork_mode_string == follow_fork_mode_ask) - { - internal_error (__FILE__, __LINE__, - "follow_inferior_fork: \"ask\" mode not implemented"); - /* follow_mode = follow_fork_mode_...; */ - } - - /* If we're to be following the parent, then detach from child_pid. - We're already following the parent, so need do nothing explicit - for it. */ - if (follow_mode == follow_fork_mode_parent) - { - followed_parent = 1; - - /* We're already attached to the parent, by default. */ - - /* Before detaching from the child, remove all breakpoints from - it. (This won't actually modify the breakpoint list, but will - physically remove the breakpoints from the child.) */ - if (!has_vforked || !follow_vfork_when_exec) - { - detach_breakpoints (child_pid); -#ifdef SOLIB_REMOVE_INFERIOR_HOOK - SOLIB_REMOVE_INFERIOR_HOOK (child_pid); -#endif - } - - /* Detach from the child. */ - dont_repeat (); - - target_require_detach (child_pid, "", 1); - } - - /* If we're to be following the child, then attach to it, detach - from inferior_ptid, and set inferior_ptid to child_pid. */ - else if (follow_mode == follow_fork_mode_child) - { - char child_pid_spelling[100]; /* Arbitrary length. */ - - followed_child = 1; - - /* Before detaching from the parent, detach all breakpoints from - the child. But only if we're forking, or if we follow vforks - as soon as they happen. (If we're following vforks only when - the child has exec'd, then it's very wrong to try to write - back the "shadow contents" of inserted breakpoints now -- they - belong to the child's pre-exec'd a.out.) */ - if (!has_vforked || !follow_vfork_when_exec) - { - detach_breakpoints (child_pid); - } - - /* Before detaching from the parent, remove all breakpoints from it. */ - remove_breakpoints (); - - /* Also reset the solib inferior hook from the parent. */ -#ifdef SOLIB_REMOVE_INFERIOR_HOOK - SOLIB_REMOVE_INFERIOR_HOOK (PIDGET (inferior_ptid)); -#endif - - /* Detach from the parent. */ - dont_repeat (); - target_detach (NULL, 1); - - /* Attach to the child. */ - inferior_ptid = pid_to_ptid (child_pid); - sprintf (child_pid_spelling, "%d", child_pid); - dont_repeat (); - - target_require_attach (child_pid_spelling, 1); - - /* Was there a step_resume breakpoint? (There was if the user - did a "next" at the fork() call.) If so, explicitly reset its - thread number. - - step_resumes are a form of bp that are made to be per-thread. - Since we created the step_resume bp when the parent process - was being debugged, and now are switching to the child process, - from the breakpoint package's viewpoint, that's a switch of - "threads". We must update the bp's notion of which thread - it is for, or it'll be ignored when it triggers... */ - if (step_resume_breakpoint && - (!has_vforked || !follow_vfork_when_exec)) - breakpoint_re_set_thread (step_resume_breakpoint); - - /* Reinsert all breakpoints in the child. (The user may've set - breakpoints after catching the fork, in which case those - actually didn't get set in the child, but only in the parent.) */ - if (!has_vforked || !follow_vfork_when_exec) - { - breakpoint_re_set (); - insert_breakpoints (); - } - } - - /* If we're to be following both parent and child, then fork ourselves, - and attach the debugger clone to the child. */ - else if (follow_mode == follow_fork_mode_both) - { - char pid_suffix[100]; /* Arbitrary length. */ - - /* Clone ourselves to follow the child. This is the end of our - involvement with child_pid; our clone will take it from here... */ - dont_repeat (); - target_clone_and_follow_inferior (child_pid, &followed_child); - followed_parent = !followed_child; - - /* We continue to follow the parent. To help distinguish the two - debuggers, though, both we and our clone will reset our prompts. */ - sprintf (pid_suffix, "[%d] ", PIDGET (inferior_ptid)); - set_prompt (strcat (get_prompt (), pid_suffix)); - } - - /* The parent and child of a vfork share the same address space. - Also, on some targets the order in which vfork and exec events - are received for parent in child requires some delicate handling - of the events. - - For instance, on ptrace-based HPUX we receive the child's vfork - event first, at which time the parent has been suspended by the - OS and is essentially untouchable until the child's exit or second - exec event arrives. At that time, the parent's vfork event is - delivered to us, and that's when we see and decide how to follow - the vfork. But to get to that point, we must continue the child - until it execs or exits. To do that smoothly, all breakpoints - must be removed from the child, in case there are any set between - the vfork() and exec() calls. But removing them from the child - also removes them from the parent, due to the shared-address-space - nature of a vfork'd parent and child. On HPUX, therefore, we must - take care to restore the bp's to the parent before we continue it. - Else, it's likely that we may not stop in the expected place. (The - worst scenario is when the user tries to step over a vfork() call; - the step-resume bp must be restored for the step to properly stop - in the parent after the call completes!) - - Sequence of events, as reported to gdb from HPUX: - - Parent Child Action for gdb to take - ------------------------------------------------------- - 1 VFORK Continue child - 2 EXEC - 3 EXEC or EXIT - 4 VFORK */ - if (has_vforked) - { - target_post_follow_vfork (parent_pid, - followed_parent, - child_pid, - followed_child); - } - - pending_follow.fork_event.saw_parent_fork = 0; - pending_follow.fork_event.saw_child_fork = 0; + return target_follow_fork (follow_child); } -static void -follow_fork (int parent_pid, int child_pid) +void +follow_inferior_reset_breakpoints (void) { - follow_inferior_fork (parent_pid, child_pid, 1, 0); -} + /* Was there a step_resume breakpoint? (There was if the user + did a "next" at the fork() call.) If so, explicitly reset its + thread number. + step_resumes are a form of bp that are made to be per-thread. + Since we created the step_resume bp when the parent process + was being debugged, and now are switching to the child process, + from the breakpoint package's viewpoint, that's a switch of + "threads". We must update the bp's notion of which thread + it is for, or it'll be ignored when it triggers. */ -/* Forward declaration. */ -static void follow_exec (int, char *); + if (step_resume_breakpoint) + breakpoint_re_set_thread (step_resume_breakpoint); -static void -follow_vfork (int parent_pid, int child_pid) -{ - follow_inferior_fork (parent_pid, child_pid, 0, 1); + /* Reinsert all breakpoints in the child. The user may have set + breakpoints after catching the fork, in which case those + were never set in the child, but only in the parent. This makes + sure the inserted breakpoints match the breakpoint list. */ - /* Did we follow the child? Had it exec'd before we saw the parent vfork? */ - if (pending_follow.fork_event.saw_child_exec - && (PIDGET (inferior_ptid) == child_pid)) - { - pending_follow.fork_event.saw_child_exec = 0; - pending_follow.kind = TARGET_WAITKIND_SPURIOUS; - follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname); - xfree (pending_follow.execd_pathname); - } + breakpoint_re_set (); + insert_breakpoints (); } /* EXECD_PATHNAME is assumed to be non-NULL. */ @@ -627,23 +395,6 @@ follow_exec (int pid, char *execd_pathname) if (!may_follow_exec) return; - /* Did this exec() follow a vfork()? If so, we must follow the - vfork now too. Do it before following the exec. */ - if (follow_vfork_when_exec && - (pending_follow.kind == TARGET_WAITKIND_VFORKED)) - { - pending_follow.kind = TARGET_WAITKIND_SPURIOUS; - follow_vfork (PIDGET (inferior_ptid), - pending_follow.fork_event.child_pid); - follow_vfork_when_exec = 0; - saved_pid = PIDGET (inferior_ptid); - - /* Did we follow the parent? If so, we're done. If we followed - the child then we must also follow its exec(). */ - if (PIDGET (inferior_ptid) == pending_follow.fork_event.parent_pid) - return; - } - /* This is an exec event that we actually wish to pay attention to. Refresh our symbol table to the newly exec'd program, remove any momentary bp's, etc. @@ -690,7 +441,7 @@ follow_exec (int pid, char *execd_pathname) gdb_flush (gdb_stdout); target_mourn_inferior (); inferior_ptid = pid_to_ptid (saved_pid); - /* Because mourn_inferior resets inferior_ptid. */ + /* Because mourn_inferior resets inferior_ptid. */ push_target (tgt); /* That a.out is now the one to use. */ @@ -724,10 +475,17 @@ follow_exec (int pid, char *execd_pathname) because we cannot remove the breakpoints in the inferior process until after the `wait' in `wait_for_inferior'. */ static int singlestep_breakpoints_inserted_p = 0; + +/* The thread we inserted single-step breakpoints for. */ +static ptid_t singlestep_ptid; + +/* If another thread hit the singlestep breakpoint, we save the original + thread here so that we can resume single-stepping it later. */ +static ptid_t saved_singlestep_ptid; +static int stepping_past_singlestep_breakpoint; /* Things to clean up if we QUIT out of resume (). */ -/* ARGSUSED */ static void resume_cleanups (void *ignore) { @@ -738,8 +496,7 @@ static const char schedlock_off[] = "off"; static const char schedlock_on[] = "on"; static const char schedlock_step[] = "step"; static const char *scheduler_mode = schedlock_off; -static const char *scheduler_enums[] = -{ +static const char *scheduler_enums[] = { schedlock_off, schedlock_on, schedlock_step, @@ -749,12 +506,19 @@ static const char *scheduler_enums[] = static void set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c) { - if (c->type == set_cmd) + /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones + the set command passed as a parameter. The clone operation will + include (BUG?) any ``set'' command callback, if present. + Commands like ``info set'' call all the ``show'' command + callbacks. Unfortunately, for ``show'' commands cloned from + ``set'', this includes callbacks belonging to ``set'' commands. + Making this worse, this only occures if add_show_from_set() is + called after add_cmd_sfunc() (BUG?). */ + if (cmd_type (c) == set_cmd) if (!target_can_lock_scheduler) { scheduler_mode = schedlock_off; - error ("Target '%s' cannot support this command.", - target_shortname); + error ("Target '%s' cannot support this command.", target_shortname); } } @@ -787,7 +551,7 @@ resume (int step, enum target_signal sig) step anyway. */ if (CANNOT_STEP_HW_WATCHPOINTS && step && breakpoints_inserted) remove_hw_watchpoints (); - + /* Normally, by the time we reach `resume', the breakpoints are either removed or inserted, as appropriate. The exception is if we're sitting @@ -805,6 +569,7 @@ resume (int step, enum target_signal sig) /* and do not pull these breakpoints until after a `wait' in `wait_for_inferior' */ singlestep_breakpoints_inserted_p = 1; + singlestep_ptid = inferior_ptid; } /* Handle any optimized stores to the inferior NOW... */ @@ -813,38 +578,19 @@ resume (int step, enum target_signal sig) #endif /* If there were any forks/vforks/execs that were caught and are - now to be followed, then do so. */ + now to be followed, then do so. */ switch (pending_follow.kind) { - case (TARGET_WAITKIND_FORKED): + case TARGET_WAITKIND_FORKED: + case TARGET_WAITKIND_VFORKED: pending_follow.kind = TARGET_WAITKIND_SPURIOUS; - follow_fork (PIDGET (inferior_ptid), - pending_follow.fork_event.child_pid); + if (follow_fork ()) + should_resume = 0; break; - case (TARGET_WAITKIND_VFORKED): - { - int saw_child_exec = pending_follow.fork_event.saw_child_exec; - - pending_follow.kind = TARGET_WAITKIND_SPURIOUS; - follow_vfork (PIDGET (inferior_ptid), - pending_follow.fork_event.child_pid); - - /* Did we follow the child, but not yet see the child's exec event? - If so, then it actually ought to be waiting for us; we respond to - parent vfork events. We don't actually want to resume the child - in this situation; we want to just get its exec event. */ - if (!saw_child_exec && - (PIDGET (inferior_ptid) == pending_follow.fork_event.child_pid)) - should_resume = 0; - } - break; - - case (TARGET_WAITKIND_EXECD): - /* If we saw a vfork event but couldn't follow it until we saw - an exec, then now might be the time! */ - pending_follow.kind = TARGET_WAITKIND_SPURIOUS; + case TARGET_WAITKIND_EXECD: /* follow_exec is called as soon as the exec event is seen. */ + pending_follow.kind = TARGET_WAITKIND_SPURIOUS; break; default: @@ -858,10 +604,11 @@ resume (int step, enum target_signal sig) { ptid_t resume_ptid; - resume_ptid = RESUME_ALL; /* Default */ + resume_ptid = RESUME_ALL; /* Default */ if ((step || singlestep_breakpoints_inserted_p) && - !breakpoints_inserted && breakpoint_here_p (read_pc ())) + (stepping_past_singlestep_breakpoint + || (!breakpoints_inserted && breakpoint_here_p (read_pc ())))) { /* Stepping past a breakpoint without inserting breakpoints. Make sure only the current thread gets to step, so that @@ -872,20 +619,21 @@ resume (int step, enum target_signal sig) } if ((scheduler_mode == schedlock_on) || - (scheduler_mode == schedlock_step && + (scheduler_mode == schedlock_step && (step || singlestep_breakpoints_inserted_p))) { /* User-settable 'scheduler' mode requires solo thread resume. */ - resume_ptid = inferior_ptid; + resume_ptid = inferior_ptid; } -#ifdef CANNOT_STEP_BREAKPOINT - /* Most targets can step a breakpoint instruction, thus executing it - normally. But if this one cannot, just continue and we will hit - it anyway. */ - if (step && breakpoints_inserted && breakpoint_here_p (read_pc ())) - step = 0; -#endif + if (CANNOT_STEP_BREAKPOINT) + { + /* Most targets can step a breakpoint instruction, thus + executing it normally. But if this one cannot, just + continue and we will hit it anyway. */ + if (step && breakpoints_inserted && breakpoint_here_p (read_pc ())) + step = 0; + } target_resume (resume_ptid, step, sig); } @@ -902,10 +650,10 @@ clear_proceed_status (void) trap_expected = 0; step_range_start = 0; step_range_end = 0; - step_frame_address = 0; + step_frame_id = null_frame_id; step_over_calls = STEP_OVER_UNDEBUGGABLE; stop_after_trap = 0; - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; proceed_to_finish = 0; breakpoint_proceeded = 1; /* We're about to proceed... */ @@ -913,6 +661,61 @@ clear_proceed_status (void) bpstat_clear (&stop_bpstat); } +/* This should be suitable for any targets that support threads. */ + +static int +prepare_to_proceed (void) +{ + ptid_t wait_ptid; + struct target_waitstatus wait_status; + + /* Get the last target status returned by target_wait(). */ + get_last_target_status (&wait_ptid, &wait_status); + + /* Make sure we were stopped either at a breakpoint, or because + of a Ctrl-C. */ + if (wait_status.kind != TARGET_WAITKIND_STOPPED + || (wait_status.value.sig != TARGET_SIGNAL_TRAP && + wait_status.value.sig != TARGET_SIGNAL_INT)) + { + return 0; + } + + if (!ptid_equal (wait_ptid, minus_one_ptid) + && !ptid_equal (inferior_ptid, wait_ptid)) + { + /* Switched over from WAIT_PID. */ + CORE_ADDR wait_pc = read_pc_pid (wait_ptid); + + if (wait_pc != read_pc ()) + { + /* Switch back to WAIT_PID thread. */ + inferior_ptid = wait_ptid; + + /* FIXME: This stuff came from switch_to_thread() in + thread.c (which should probably be a public function). */ + flush_cached_frames (); + registers_changed (); + stop_pc = wait_pc; + select_frame (get_current_frame ()); + } + + /* We return 1 to indicate that there is a breakpoint here, + so we need to step over it before continuing to avoid + hitting it straight away. */ + if (breakpoint_here_p (wait_pc)) + return 1; + } + + return 0; + +} + +/* Record the pc of the program the last time it stopped. This is + just used internally by wait_for_inferior, but need to be preserved + over calls to it and cleared when the inferior is started. */ +static CORE_ADDR prev_pc; + /* Basic routine for continuing the program in various fashions. ADDR is the address to resume at, or -1 for resume where stopped. @@ -962,7 +765,6 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step) write_pc (addr); } -#ifdef PREPARE_TO_PROCEED /* In a multi-threaded task we may select another thread and then continue or step. @@ -971,15 +773,11 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step) any execution (i.e. it will report a breakpoint hit incorrectly). So we must step over it first. - PREPARE_TO_PROCEED checks the current thread against the thread + prepare_to_proceed checks the current thread against the thread that reported the most recent event. If a step-over is required it returns TRUE and sets the current thread to the old thread. */ - if (PREPARE_TO_PROCEED (1) && breakpoint_here_p (read_pc ())) - { - oneproc = 1; - } - -#endif /* PREPARE_TO_PROCEED */ + if (prepare_to_proceed () && breakpoint_here_p (read_pc ())) + oneproc = 1; #ifdef HP_OS_BUG if (trap_expected_after_continue) @@ -999,16 +797,9 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step) trap_expected = 1; else { - int temp = insert_breakpoints (); - if (temp) - { - print_sys_errmsg ("insert_breakpoints", temp); - error ("Cannot insert breakpoints.\n\ -The same program may be running in another process,\n\ -or you may have requested too many hardware\n\ -breakpoints and/or watchpoints.\n"); - } - + insert_breakpoints (); + /* If we get here there was no call to error() in + insert breakpoints -- so they were inserted. */ breakpoints_inserted = 1; } @@ -1025,6 +816,30 @@ breakpoints and/or watchpoints.\n"); inferior. */ gdb_flush (gdb_stdout); + /* Refresh prev_pc value just prior to resuming. This used to be + done in stop_stepping, however, setting prev_pc there did not handle + scenarios such as inferior function calls or returning from + a function via the return command. In those cases, the prev_pc + value was not set properly for subsequent commands. The prev_pc value + is used to initialize the starting line number in the ecs. With an + invalid value, the gdb next command ends up stopping at the position + represented by the next line table entry past our start position. + On platforms that generate one line table entry per line, this + is not a problem. However, on the ia64, the compiler generates + extraneous line table entries that do not increase the line number. + When we issue the gdb next command on the ia64 after an inferior call + or a return command, we often end up a few instructions forward, still + within the original line we started. + + An attempt was made to have init_execution_control_state () refresh + the prev_pc value before calculating the line number. This approach + did not work because on platforms that use ptrace, the pc register + cannot be read unless the inferior is stopped. At that point, we + are not guaranteed the inferior is stopped and so the read_pc () + call can fail. Setting the prev_pc value here ensures the value is + updated correctly when the inferior is stopped. */ + prev_pc = read_pc (); + /* Resume inferior. */ resume (oneproc || step || bpstat_should_step (), stop_signal); @@ -1038,14 +853,6 @@ breakpoints and/or watchpoints.\n"); normal_stop (); } } - -/* Record the pc and sp of the program the last time it stopped. - These are just used internally by wait_for_inferior, but need - to be preserved over calls to it and cleared when the inferior - is started. */ -static CORE_ADDR prev_pc; -static CORE_ADDR prev_func_start; -static char *prev_func_name; /* Start remote-debugging of a machine over a serial link. */ @@ -1055,7 +862,7 @@ start_remote (void) { init_thread_list (); init_wait_for_inferior (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; trap_expected = 0; /* Always go on waiting for the target, regardless of the mode. */ @@ -1083,8 +890,6 @@ init_wait_for_inferior (void) { /* These are meaningless until the first time through wait_for_inferior. */ prev_pc = 0; - prev_func_start = 0; - prev_func_name = NULL; #ifdef HP_OS_BUG trap_expected_after_continue = 0; @@ -1097,14 +902,13 @@ init_wait_for_inferior (void) /* The first resume is not following a fork/vfork/exec. */ pending_follow.kind = TARGET_WAITKIND_SPURIOUS; /* I.e., none. */ - pending_follow.fork_event.saw_parent_fork = 0; - pending_follow.fork_event.saw_child_fork = 0; - pending_follow.fork_event.saw_child_exec = 0; /* See wait_for_inferior's handling of SYSCALL_ENTRY/RETURN events. */ number_of_threads_in_syscalls = 0; clear_proceed_status (); + + stepping_past_singlestep_breakpoint = 0; } static void @@ -1153,36 +957,37 @@ enum inferior_stop_reason locals in handle_inferior_event. */ struct execution_control_state - { - struct target_waitstatus ws; - struct target_waitstatus *wp; - int another_trap; - int random_signal; - CORE_ADDR stop_func_start; - CORE_ADDR stop_func_end; - char *stop_func_name; - struct symtab_and_line sal; - int remove_breakpoints_on_following_step; - int current_line; - struct symtab *current_symtab; - int handling_longjmp; /* FIXME */ - ptid_t ptid; - ptid_t saved_inferior_ptid; - int update_step_sp; - int stepping_through_solib_after_catch; - bpstat stepping_through_solib_catchpoints; - int enable_hw_watchpoints_after_wait; - int stepping_through_sigtramp; - int new_thread_event; - struct target_waitstatus tmpstatus; - enum infwait_states infwait_state; - ptid_t waiton_ptid; - int wait_some_more; - }; +{ + struct target_waitstatus ws; + struct target_waitstatus *wp; + int another_trap; + int random_signal; + CORE_ADDR stop_func_start; + CORE_ADDR stop_func_end; + char *stop_func_name; + struct symtab_and_line sal; + int remove_breakpoints_on_following_step; + int current_line; + struct symtab *current_symtab; + int handling_longjmp; /* FIXME */ + ptid_t ptid; + ptid_t saved_inferior_ptid; + int update_step_sp; + int stepping_through_solib_after_catch; + bpstat stepping_through_solib_catchpoints; + int enable_hw_watchpoints_after_wait; + int stepping_through_sigtramp; + int new_thread_event; + struct target_waitstatus tmpstatus; + enum infwait_states infwait_state; + ptid_t waiton_ptid; + int wait_some_more; +}; -void init_execution_control_state (struct execution_control_state * ecs); +void init_execution_control_state (struct execution_control_state *ecs); -void handle_inferior_event (struct execution_control_state * ecs); +static void handle_step_into_function (struct execution_control_state *ecs); +void handle_inferior_event (struct execution_control_state *ecs); static void check_sigtramp2 (struct execution_control_state *ecs); static void step_into_function (struct execution_control_state *ecs); @@ -1190,7 +995,8 @@ static void step_over_function (struct execution_control_state *ecs); static void stop_stepping (struct execution_control_state *ecs); static void prepare_to_wait (struct execution_control_state *ecs); static void keep_going (struct execution_control_state *ecs); -static void print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info); +static void print_stop_reason (enum inferior_stop_reason stop_reason, + int stop_info); /* Wait for control to return from inferior to debugger. If inferior gets a signal, we may decide to start it up again @@ -1267,7 +1073,7 @@ fetch_inferior_event (void *client_data) if (!async_ecs->wait_some_more) { - old_cleanups = make_exec_cleanup (delete_step_resume_breakpoint, + old_cleanups = make_exec_cleanup (delete_step_resume_breakpoint, &step_resume_breakpoint); make_exec_cleanup (delete_breakpoint_current_contents, &through_sigtramp_breakpoint); @@ -1290,7 +1096,8 @@ fetch_inferior_event (void *client_data) } if (target_wait_hook) - async_ecs->ptid = target_wait_hook (async_ecs->waiton_ptid, async_ecs->wp); + async_ecs->ptid = + target_wait_hook (async_ecs->waiton_ptid, async_ecs->wp); else async_ecs->ptid = target_wait (async_ecs->waiton_ptid, async_ecs->wp); @@ -1300,8 +1107,8 @@ fetch_inferior_event (void *client_data) if (!async_ecs->wait_some_more) { /* Do only the cleanups that have been added by this - function. Let the continuations for the commands do the rest, - if there are any. */ + function. Let the continuations for the commands do the rest, + if there are any. */ do_exec_cleanups (old_cleanups); normal_stop (); if (step_multi && stop_step) @@ -1342,7 +1149,8 @@ static void check_for_old_step_resume_breakpoint (void) { if (step_resume_breakpoint) - warning ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint"); + warning + ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint"); } /* Return the cached copy of the last pid/waitstatus returned by @@ -1351,7 +1159,7 @@ check_for_old_step_resume_breakpoint (void) target_wait()/target_wait_hook(). */ void -get_last_target_status(ptid_t *ptidp, struct target_waitstatus *status) +get_last_target_status (ptid_t *ptidp, struct target_waitstatus *status) { *ptidp = target_last_wait_ptid; *status = target_last_waitstatus; @@ -1369,36 +1177,227 @@ context_switch (struct execution_control_state *ecs) mishandling thread creation. */ if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid)) - { /* Perform infrun state context switch: */ + { /* Perform infrun state context switch: */ /* Save infrun state for the old thread. */ - save_infrun_state (inferior_ptid, prev_pc, - prev_func_start, prev_func_name, + save_infrun_state (inferior_ptid, prev_pc, trap_expected, step_resume_breakpoint, - through_sigtramp_breakpoint, step_range_start, - step_range_end, step_frame_address, + through_sigtramp_breakpoint, step_range_start, + step_range_end, &step_frame_id, ecs->handling_longjmp, ecs->another_trap, ecs->stepping_through_solib_after_catch, ecs->stepping_through_solib_catchpoints, ecs->stepping_through_sigtramp, - ecs->current_line, ecs->current_symtab, - step_sp); + ecs->current_line, ecs->current_symtab, step_sp); /* Load infrun state for the new thread. */ - load_infrun_state (ecs->ptid, &prev_pc, - &prev_func_start, &prev_func_name, + load_infrun_state (ecs->ptid, &prev_pc, &trap_expected, &step_resume_breakpoint, - &through_sigtramp_breakpoint, &step_range_start, - &step_range_end, &step_frame_address, + &through_sigtramp_breakpoint, &step_range_start, + &step_range_end, &step_frame_id, &ecs->handling_longjmp, &ecs->another_trap, &ecs->stepping_through_solib_after_catch, &ecs->stepping_through_solib_catchpoints, - &ecs->stepping_through_sigtramp, - &ecs->current_line, &ecs->current_symtab, - &step_sp); + &ecs->stepping_through_sigtramp, + &ecs->current_line, &ecs->current_symtab, &step_sp); } inferior_ptid = ecs->ptid; } +/* Wrapper for PC_IN_SIGTRAMP that takes care of the need to find the + function's name. + + In a classic example of "left hand VS right hand", "infrun.c" was + trying to improve GDB's performance by caching the result of calls + to calls to find_pc_partial_funtion, while at the same time + find_pc_partial_function was also trying to ramp up performance by + caching its most recent return value. The below makes the the + function find_pc_partial_function solely responsibile for + performance issues (the local cache that relied on a global + variable - arrrggg - deleted). + + Using the testsuite and gcov, it was found that dropping the local + "infrun.c" cache and instead relying on find_pc_partial_function + increased the number of calls to 12000 (from 10000), but the number + of times find_pc_partial_function's cache missed (this is what + matters) was only increased by only 4 (to 3569). (A quick back of + envelope caculation suggests that the extra 2000 function calls + @1000 extra instructions per call make the 1 MIP VAX testsuite run + take two extra seconds, oops :-) + + Long term, this function can be eliminated, replaced by the code: + get_frame_type(current_frame()) == SIGTRAMP_FRAME (for new + architectures this is very cheap). */ + +static int +pc_in_sigtramp (CORE_ADDR pc) +{ + char *name; + find_pc_partial_function (pc, &name, NULL, NULL); + return PC_IN_SIGTRAMP (pc, name); +} + +/* Handle the inferior event in the cases when we just stepped + into a function. */ + +static void +handle_step_into_function (struct execution_control_state *ecs) +{ + CORE_ADDR real_stop_pc; + + if ((step_over_calls == STEP_OVER_NONE) + || ((step_range_end == 1) + && in_prologue (prev_pc, ecs->stop_func_start))) + { + /* I presume that step_over_calls is only 0 when we're + supposed to be stepping at the assembly language level + ("stepi"). Just stop. */ + /* Also, maybe we just did a "nexti" inside a prolog, + so we thought it was a subroutine call but it was not. + Stop as well. FENN */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc)) + { + /* We're doing a "next". */ + + if (pc_in_sigtramp (stop_pc) + && frame_id_inner (step_frame_id, + frame_id_build (read_sp (), 0))) + /* We stepped out of a signal handler, and into its + calling trampoline. This is misdetected as a + subroutine call, but stepping over the signal + trampoline isn't such a bad idea. In order to do that, + we have to ignore the value in step_frame_id, since + that doesn't represent the frame that'll reach when we + return from the signal trampoline. Otherwise we'll + probably continue to the end of the program. */ + step_frame_id = null_frame_id; + + step_over_function (ecs); + keep_going (ecs); + return; + } + + /* If we are in a function call trampoline (a stub between + the calling routine and the real function), locate the real + function. That's what tells us (a) whether we want to step + into it at all, and (b) what prologue we want to run to + the end of, if we do step into it. */ + real_stop_pc = skip_language_trampoline (stop_pc); + if (real_stop_pc == 0) + real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc); + if (real_stop_pc != 0) + ecs->stop_func_start = real_stop_pc; + + /* If we have line number information for the function we + are thinking of stepping into, step into it. + + If there are several symtabs at that PC (e.g. with include + files), just want to know whether *any* of them have line + numbers. find_pc_line handles this. */ + { + struct symtab_and_line tmp_sal; + + tmp_sal = find_pc_line (ecs->stop_func_start, 0); + if (tmp_sal.line != 0) + { + step_into_function (ecs); + return; + } + } + + /* If we have no line number and the step-stop-if-no-debug + is set, we stop the step so that the user has a chance to + switch in assembly mode. */ + if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug) + { + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + step_over_function (ecs); + keep_going (ecs); + return; +} + +static void +adjust_pc_after_break (struct execution_control_state *ecs) +{ + CORE_ADDR stop_pc; + + /* If this target does not decrement the PC after breakpoints, then + we have nothing to do. */ + if (DECR_PC_AFTER_BREAK == 0) + return; + + /* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP. If + we aren't, just return. + + We assume that waitkinds other than TARGET_WAITKIND_STOPPED are not + affected by DECR_PC_AFTER_BREAK. Other waitkinds which are implemented + by software breakpoints should be handled through the normal breakpoint + layer. + + NOTE drow/2004-01-31: On some targets, breakpoints may generate + different signals (SIGILL or SIGEMT for instance), but it is less + clear where the PC is pointing afterwards. It may not match + DECR_PC_AFTER_BREAK. I don't know any specific target that generates + these signals at breakpoints (the code has been in GDB since at least + 1992) so I can not guess how to handle them here. + + In earlier versions of GDB, a target with HAVE_NONSTEPPABLE_WATCHPOINTS + would have the PC after hitting a watchpoint affected by + DECR_PC_AFTER_BREAK. I haven't found any target with both of these set + in GDB history, and it seems unlikely to be correct, so + HAVE_NONSTEPPABLE_WATCHPOINTS is not checked here. */ + + if (ecs->ws.kind != TARGET_WAITKIND_STOPPED) + return; + + if (ecs->ws.value.sig != TARGET_SIGNAL_TRAP) + return; + + /* Find the location where (if we've hit a breakpoint) the breakpoint would + be. */ + stop_pc = read_pc_pid (ecs->ptid) - DECR_PC_AFTER_BREAK; + + /* If we're software-single-stepping, then assume this is a breakpoint. + NOTE drow/2004-01-17: This doesn't check that the PC matches, or that + we're even in the right thread. The software-single-step code needs + some modernization. + + If we're not software-single-stepping, then we first check that there + is an enabled software breakpoint at this address. If there is, and + we weren't using hardware-single-step, then we've hit the breakpoint. + + If we were using hardware-single-step, we check prev_pc; if we just + stepped over an inserted software breakpoint, then we should decrement + the PC and eventually report hitting the breakpoint. The prev_pc check + prevents us from decrementing the PC if we just stepped over a jump + instruction and landed on the instruction after a breakpoint. + + The last bit checks that we didn't hit a breakpoint in a signal handler + without an intervening stop in sigtramp, which is detected by a new + stack pointer value below any usual function calling stack adjustments. + + NOTE drow/2004-01-17: I'm not sure that this is necessary. The check + predates checking for software single step at the same time. Also, + if we've moved into a signal handler we should have seen the + signal. */ + + if ((SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + || (software_breakpoint_inserted_here_p (stop_pc) + && !(currently_stepping (ecs) + && prev_pc != stop_pc + && !(step_range_end && INNER_THAN (read_sp (), (step_sp - 16)))))) + write_pc_pid (stop_pc, ecs->ptid); +} /* Given an execution control state that has been freshly filled in by an event from the inferior, figure out what it means and take @@ -1407,510 +1406,498 @@ context_switch (struct execution_control_state *ecs) void handle_inferior_event (struct execution_control_state *ecs) { - CORE_ADDR tmp; + /* NOTE: cagney/2003-03-28: If you're looking at this code and + thinking that the variable stepped_after_stopped_by_watchpoint + isn't used, then you're wrong! The macro STOPPED_BY_WATCHPOINT, + defined in the file "config/pa/nm-hppah.h", accesses the variable + indirectly. Mutter something rude about the HP merge. */ int stepped_after_stopped_by_watchpoint; + int sw_single_step_trap_p = 0; /* Cache the last pid/waitstatus. */ target_last_wait_ptid = ecs->ptid; target_last_waitstatus = *ecs->wp; - /* Keep this extra brace for now, minimizes diffs. */ - { - switch (ecs->infwait_state) - { - case infwait_thread_hop_state: - /* Cancel the waiton_ptid. */ - ecs->waiton_ptid = pid_to_ptid (-1); - /* Fall thru to the normal_state case. */ + adjust_pc_after_break (ecs); - case infwait_normal_state: - /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event - is serviced in this loop, below. */ - if (ecs->enable_hw_watchpoints_after_wait) - { - TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid)); - ecs->enable_hw_watchpoints_after_wait = 0; - } - stepped_after_stopped_by_watchpoint = 0; - break; + switch (ecs->infwait_state) + { + case infwait_thread_hop_state: + /* Cancel the waiton_ptid. */ + ecs->waiton_ptid = pid_to_ptid (-1); + /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event + is serviced in this loop, below. */ + if (ecs->enable_hw_watchpoints_after_wait) + { + TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid)); + ecs->enable_hw_watchpoints_after_wait = 0; + } + stepped_after_stopped_by_watchpoint = 0; + break; - case infwait_nullified_state: - break; + case infwait_normal_state: + /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event + is serviced in this loop, below. */ + if (ecs->enable_hw_watchpoints_after_wait) + { + TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid)); + ecs->enable_hw_watchpoints_after_wait = 0; + } + stepped_after_stopped_by_watchpoint = 0; + break; - case infwait_nonstep_watch_state: - insert_breakpoints (); + case infwait_nullified_state: + stepped_after_stopped_by_watchpoint = 0; + break; - /* FIXME-maybe: is this cleaner than setting a flag? Does it - handle things like signals arriving and other things happening - in combination correctly? */ - stepped_after_stopped_by_watchpoint = 1; - break; - } - ecs->infwait_state = infwait_normal_state; + case infwait_nonstep_watch_state: + insert_breakpoints (); - flush_cached_frames (); + /* FIXME-maybe: is this cleaner than setting a flag? Does it + handle things like signals arriving and other things happening + in combination correctly? */ + stepped_after_stopped_by_watchpoint = 1; + break; - /* If it's a new process, add it to the thread database */ + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + ecs->infwait_state = infwait_normal_state; - ecs->new_thread_event = (! ptid_equal (ecs->ptid, inferior_ptid) - && ! in_thread_list (ecs->ptid)); + flush_cached_frames (); - if (ecs->ws.kind != TARGET_WAITKIND_EXITED - && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED - && ecs->new_thread_event) - { - add_thread (ecs->ptid); + /* If it's a new process, add it to the thread database */ - ui_out_text (uiout, "[New "); - ui_out_text (uiout, target_pid_or_tid_to_str (ecs->ptid)); - ui_out_text (uiout, "]\n"); + ecs->new_thread_event = (!ptid_equal (ecs->ptid, inferior_ptid) + && !in_thread_list (ecs->ptid)); + + if (ecs->ws.kind != TARGET_WAITKIND_EXITED + && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event) + { + add_thread (ecs->ptid); + + ui_out_text (uiout, "[New "); + ui_out_text (uiout, target_pid_or_tid_to_str (ecs->ptid)); + ui_out_text (uiout, "]\n"); #if 0 - /* NOTE: This block is ONLY meant to be invoked in case of a - "thread creation event"! If it is invoked for any other - sort of event (such as a new thread landing on a breakpoint), - the event will be discarded, which is almost certainly - a bad thing! + /* NOTE: This block is ONLY meant to be invoked in case of a + "thread creation event"! If it is invoked for any other + sort of event (such as a new thread landing on a breakpoint), + the event will be discarded, which is almost certainly + a bad thing! - To avoid this, the low-level module (eg. target_wait) - should call in_thread_list and add_thread, so that the - new thread is known by the time we get here. */ + To avoid this, the low-level module (eg. target_wait) + should call in_thread_list and add_thread, so that the + new thread is known by the time we get here. */ - /* We may want to consider not doing a resume here in order - to give the user a chance to play with the new thread. - It might be good to make that a user-settable option. */ + /* We may want to consider not doing a resume here in order + to give the user a chance to play with the new thread. + It might be good to make that a user-settable option. */ - /* At this point, all threads are stopped (happens - automatically in either the OS or the native code). - Therefore we need to continue all threads in order to - make progress. */ + /* At this point, all threads are stopped (happens + automatically in either the OS or the native code). + Therefore we need to continue all threads in order to + make progress. */ - target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; + target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; #endif - } + } - switch (ecs->ws.kind) - { - case TARGET_WAITKIND_LOADED: - /* Ignore gracefully during startup of the inferior, as it - might be the shell which has just loaded some objects, - otherwise add the symbols for the newly loaded objects. */ + switch (ecs->ws.kind) + { + case TARGET_WAITKIND_LOADED: + /* Ignore gracefully during startup of the inferior, as it + might be the shell which has just loaded some objects, + otherwise add the symbols for the newly loaded objects. */ #ifdef SOLIB_ADD - if (!stop_soon_quietly) - { - /* Remove breakpoints, SOLIB_ADD might adjust - breakpoint addresses via breakpoint_re_set. */ - if (breakpoints_inserted) - remove_breakpoints (); + if (stop_soon == NO_STOP_QUIETLY) + { + /* Remove breakpoints, SOLIB_ADD might adjust + breakpoint addresses via breakpoint_re_set. */ + if (breakpoints_inserted) + remove_breakpoints (); - /* Check for any newly added shared libraries if we're - supposed to be adding them automatically. Switch - terminal for any messages produced by - breakpoint_re_set. */ - target_terminal_ours_for_output (); - SOLIB_ADD (NULL, 0, NULL, auto_solib_add); - target_terminal_inferior (); + /* Check for any newly added shared libraries if we're + supposed to be adding them automatically. Switch + terminal for any messages produced by + breakpoint_re_set. */ + target_terminal_ours_for_output (); + /* NOTE: cagney/2003-11-25: Make certain that the target + stack's section table is kept up-to-date. Architectures, + (e.g., PPC64), use the section table to perform + operations such as address => section name and hence + require the table to contain all sections (including + those found in shared libraries). */ + /* NOTE: cagney/2003-11-25: Pass current_target and not + exec_ops to SOLIB_ADD. This is because current GDB is + only tooled to propagate section_table changes out from + the "current_target" (see target_resize_to_sections), and + not up from the exec stratum. This, of course, isn't + right. "infrun.c" should only interact with the + exec/process stratum, instead relying on the target stack + to propagate relevant changes (stop, section table + changed, ...) up to other layers. */ + SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); + target_terminal_inferior (); - /* Reinsert breakpoints and continue. */ - if (breakpoints_inserted) - insert_breakpoints (); - } + /* Reinsert breakpoints and continue. */ + if (breakpoints_inserted) + insert_breakpoints (); + } #endif - resume (0, TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; + resume (0, TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; - case TARGET_WAITKIND_SPURIOUS: - resume (0, TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; + case TARGET_WAITKIND_SPURIOUS: + resume (0, TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; - case TARGET_WAITKIND_EXITED: - target_terminal_ours (); /* Must do this before mourn anyway */ - print_stop_reason (EXITED, ecs->ws.value.integer); + case TARGET_WAITKIND_EXITED: + target_terminal_ours (); /* Must do this before mourn anyway */ + print_stop_reason (EXITED, ecs->ws.value.integer); - /* Record the exit code in the convenience variable $_exitcode, so - that the user can inspect this again later. */ - set_internalvar (lookup_internalvar ("_exitcode"), - value_from_longest (builtin_type_int, - (LONGEST) ecs->ws.value.integer)); - gdb_flush (gdb_stdout); - target_mourn_inferior (); - singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */ - stop_print_frame = 0; - stop_stepping (ecs); - return; + /* Record the exit code in the convenience variable $_exitcode, so + that the user can inspect this again later. */ + set_internalvar (lookup_internalvar ("_exitcode"), + value_from_longest (builtin_type_int, + (LONGEST) ecs->ws.value.integer)); + gdb_flush (gdb_stdout); + target_mourn_inferior (); + singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */ + stop_print_frame = 0; + stop_stepping (ecs); + return; - case TARGET_WAITKIND_SIGNALLED: - stop_print_frame = 0; - stop_signal = ecs->ws.value.sig; - target_terminal_ours (); /* Must do this before mourn anyway */ + case TARGET_WAITKIND_SIGNALLED: + stop_print_frame = 0; + stop_signal = ecs->ws.value.sig; + target_terminal_ours (); /* Must do this before mourn anyway */ - /* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't - reach here unless the inferior is dead. However, for years - target_kill() was called here, which hints that fatal signals aren't - really fatal on some systems. If that's true, then some changes - may be needed. */ - target_mourn_inferior (); + /* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't + reach here unless the inferior is dead. However, for years + target_kill() was called here, which hints that fatal signals aren't + really fatal on some systems. If that's true, then some changes + may be needed. */ + target_mourn_inferior (); - print_stop_reason (SIGNAL_EXITED, stop_signal); - singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */ - stop_stepping (ecs); - return; + print_stop_reason (SIGNAL_EXITED, stop_signal); + singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */ + stop_stepping (ecs); + return; - /* The following are the only cases in which we keep going; - the above cases end in a continue or goto. */ - case TARGET_WAITKIND_FORKED: - stop_signal = TARGET_SIGNAL_TRAP; - pending_follow.kind = ecs->ws.kind; + /* The following are the only cases in which we keep going; + the above cases end in a continue or goto. */ + case TARGET_WAITKIND_FORKED: + case TARGET_WAITKIND_VFORKED: + stop_signal = TARGET_SIGNAL_TRAP; + pending_follow.kind = ecs->ws.kind; - /* Ignore fork events reported for the parent; we're only - interested in reacting to forks of the child. Note that - we expect the child's fork event to be available if we - waited for it now. */ - if (ptid_equal (inferior_ptid, ecs->ptid)) - { - pending_follow.fork_event.saw_parent_fork = 1; - pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid); - pending_follow.fork_event.child_pid = ecs->ws.value.related_pid; - prepare_to_wait (ecs); - return; - } - else - { - pending_follow.fork_event.saw_child_fork = 1; - pending_follow.fork_event.child_pid = PIDGET (ecs->ptid); - pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid; - } + pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid); + pending_follow.fork_event.child_pid = ecs->ws.value.related_pid; - stop_pc = read_pc_pid (ecs->ptid); - ecs->saved_inferior_ptid = inferior_ptid; - inferior_ptid = ecs->ptid; - /* The second argument of bpstat_stop_status is meant to help - distinguish between a breakpoint trap and a singlestep trap. - This is only important on targets where DECR_PC_AFTER_BREAK - is non-zero. The prev_pc test is meant to distinguish between - singlestepping a trap instruction, and singlestepping thru a - jump to the instruction following a trap instruction. */ - - stop_bpstat = bpstat_stop_status (&stop_pc, - currently_stepping (ecs) && - prev_pc != - stop_pc - DECR_PC_AFTER_BREAK); - ecs->random_signal = !bpstat_explains_signal (stop_bpstat); - inferior_ptid = ecs->saved_inferior_ptid; - goto process_event_stop_test; + stop_pc = read_pc (); - /* If this a platform which doesn't allow a debugger to touch a - vfork'd inferior until after it exec's, then we'd best keep - our fingers entirely off the inferior, other than continuing - it. This has the unfortunate side-effect that catchpoints - of vforks will be ignored. But since the platform doesn't - allow the inferior be touched at vfork time, there's really - little choice. */ - case TARGET_WAITKIND_VFORKED: - stop_signal = TARGET_SIGNAL_TRAP; - pending_follow.kind = ecs->ws.kind; + stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); - /* Is this a vfork of the parent? If so, then give any - vfork catchpoints a chance to trigger now. (It's - dangerous to do so if the child canot be touched until - it execs, and the child has not yet exec'd. We probably - should warn the user to that effect when the catchpoint - triggers...) */ - if (ptid_equal (ecs->ptid, inferior_ptid)) - { - pending_follow.fork_event.saw_parent_fork = 1; - pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid); - pending_follow.fork_event.child_pid = ecs->ws.value.related_pid; - } + ecs->random_signal = !bpstat_explains_signal (stop_bpstat); - /* If we've seen the child's vfork event but cannot really touch - the child until it execs, then we must continue the child now. - Else, give any vfork catchpoints a chance to trigger now. */ - else - { - pending_follow.fork_event.saw_child_fork = 1; - pending_follow.fork_event.child_pid = PIDGET (ecs->ptid); - pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid; - target_post_startup_inferior ( - pid_to_ptid (pending_follow.fork_event.child_pid)); - follow_vfork_when_exec = !target_can_follow_vfork_prior_to_exec (); - if (follow_vfork_when_exec) - { - target_resume (ecs->ptid, 0, TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; - } - } + /* If no catchpoint triggered for this, then keep going. */ + if (ecs->random_signal) + { + stop_signal = TARGET_SIGNAL_0; + keep_going (ecs); + return; + } + goto process_event_stop_test; - stop_pc = read_pc (); - /* The second argument of bpstat_stop_status is meant to help - distinguish between a breakpoint trap and a singlestep trap. - This is only important on targets where DECR_PC_AFTER_BREAK - is non-zero. The prev_pc test is meant to distinguish between - singlestepping a trap instruction, and singlestepping thru a - jump to the instruction following a trap instruction. */ - - stop_bpstat = bpstat_stop_status (&stop_pc, - currently_stepping (ecs) && - prev_pc != - stop_pc - DECR_PC_AFTER_BREAK); - ecs->random_signal = !bpstat_explains_signal (stop_bpstat); - goto process_event_stop_test; + case TARGET_WAITKIND_EXECD: + stop_signal = TARGET_SIGNAL_TRAP; - case TARGET_WAITKIND_EXECD: - stop_signal = TARGET_SIGNAL_TRAP; + /* NOTE drow/2002-12-05: This code should be pushed down into the + target_wait function. Until then following vfork on HP/UX 10.20 + is probably broken by this. Of course, it's broken anyway. */ + /* Is this a target which reports multiple exec events per actual + call to exec()? (HP-UX using ptrace does, for example.) If so, + ignore all but the last one. Just resume the exec'r, and wait + for the next exec event. */ + if (inferior_ignoring_leading_exec_events) + { + inferior_ignoring_leading_exec_events--; + if (pending_follow.kind == TARGET_WAITKIND_VFORKED) + ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event. + parent_pid); + target_resume (ecs->ptid, 0, TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; + } + inferior_ignoring_leading_exec_events = + target_reported_exec_events_per_exec_call () - 1; - /* Is this a target which reports multiple exec events per actual - call to exec()? (HP-UX using ptrace does, for example.) If so, - ignore all but the last one. Just resume the exec'r, and wait - for the next exec event. */ - if (inferior_ignoring_leading_exec_events) - { - inferior_ignoring_leading_exec_events--; - if (pending_follow.kind == TARGET_WAITKIND_VFORKED) - ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event.parent_pid); - target_resume (ecs->ptid, 0, TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; - } - inferior_ignoring_leading_exec_events = - target_reported_exec_events_per_exec_call () - 1; + pending_follow.execd_pathname = + savestring (ecs->ws.value.execd_pathname, + strlen (ecs->ws.value.execd_pathname)); - pending_follow.execd_pathname = - savestring (ecs->ws.value.execd_pathname, - strlen (ecs->ws.value.execd_pathname)); + /* This causes the eventpoints and symbol table to be reset. Must + do this now, before trying to determine whether to stop. */ + follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname); + xfree (pending_follow.execd_pathname); - /* Did inferior_ptid exec, or did a (possibly not-yet-followed) - child of a vfork exec? + stop_pc = read_pc_pid (ecs->ptid); + ecs->saved_inferior_ptid = inferior_ptid; + inferior_ptid = ecs->ptid; - ??rehrauer: This is unabashedly an HP-UX specific thing. On - HP-UX, events associated with a vforking inferior come in - threes: a vfork event for the child (always first), followed - a vfork event for the parent and an exec event for the child. - The latter two can come in either order. + stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); - If we get the parent vfork event first, life's good: We follow - either the parent or child, and then the child's exec event is - a "don't care". + ecs->random_signal = !bpstat_explains_signal (stop_bpstat); + inferior_ptid = ecs->saved_inferior_ptid; - But if we get the child's exec event first, then we delay - responding to it until we handle the parent's vfork. Because, - otherwise we can't satisfy a "catch vfork". */ - if (pending_follow.kind == TARGET_WAITKIND_VFORKED) - { - pending_follow.fork_event.saw_child_exec = 1; + /* If no catchpoint triggered for this, then keep going. */ + if (ecs->random_signal) + { + stop_signal = TARGET_SIGNAL_0; + keep_going (ecs); + return; + } + goto process_event_stop_test; - /* On some targets, the child must be resumed before - the parent vfork event is delivered. A single-step - suffices. */ - if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ()) - target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); - /* We expect the parent vfork event to be available now. */ - prepare_to_wait (ecs); - return; - } + /* These syscall events are returned on HP-UX, as part of its + implementation of page-protection-based "hardware" watchpoints. + HP-UX has unfortunate interactions between page-protections and + some system calls. Our solution is to disable hardware watches + when a system call is entered, and reenable them when the syscall + completes. The downside of this is that we may miss the precise + point at which a watched piece of memory is modified. "Oh well." - /* This causes the eventpoints and symbol table to be reset. Must - do this now, before trying to determine whether to stop. */ - follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname); - xfree (pending_follow.execd_pathname); + Note that we may have multiple threads running, which may each + enter syscalls at roughly the same time. Since we don't have a + good notion currently of whether a watched piece of memory is + thread-private, we'd best not have any page-protections active + when any thread is in a syscall. Thus, we only want to reenable + hardware watches when no threads are in a syscall. - stop_pc = read_pc_pid (ecs->ptid); - ecs->saved_inferior_ptid = inferior_ptid; - inferior_ptid = ecs->ptid; - /* The second argument of bpstat_stop_status is meant to help - distinguish between a breakpoint trap and a singlestep trap. - This is only important on targets where DECR_PC_AFTER_BREAK - is non-zero. The prev_pc test is meant to distinguish between - singlestepping a trap instruction, and singlestepping thru a - jump to the instruction following a trap instruction. */ - - stop_bpstat = bpstat_stop_status (&stop_pc, - currently_stepping (ecs) && - prev_pc != - stop_pc - DECR_PC_AFTER_BREAK); - ecs->random_signal = !bpstat_explains_signal (stop_bpstat); - inferior_ptid = ecs->saved_inferior_ptid; - goto process_event_stop_test; + Also, be careful not to try to gather much state about a thread + that's in a syscall. It's frequently a losing proposition. */ + case TARGET_WAITKIND_SYSCALL_ENTRY: + number_of_threads_in_syscalls++; + if (number_of_threads_in_syscalls == 1) + { + TARGET_DISABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid)); + } + resume (0, TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; - /* These syscall events are returned on HP-UX, as part of its - implementation of page-protection-based "hardware" watchpoints. - HP-UX has unfortunate interactions between page-protections and - some system calls. Our solution is to disable hardware watches - when a system call is entered, and reenable them when the syscall - completes. The downside of this is that we may miss the precise - point at which a watched piece of memory is modified. "Oh well." + /* Before examining the threads further, step this thread to + get it entirely out of the syscall. (We get notice of the + event when the thread is just on the verge of exiting a + syscall. Stepping one instruction seems to get it back + into user code.) - Note that we may have multiple threads running, which may each - enter syscalls at roughly the same time. Since we don't have a - good notion currently of whether a watched piece of memory is - thread-private, we'd best not have any page-protections active - when any thread is in a syscall. Thus, we only want to reenable - hardware watches when no threads are in a syscall. + Note that although the logical place to reenable h/w watches + is here, we cannot. We cannot reenable them before stepping + the thread (this causes the next wait on the thread to hang). - Also, be careful not to try to gather much state about a thread - that's in a syscall. It's frequently a losing proposition. */ - case TARGET_WAITKIND_SYSCALL_ENTRY: - number_of_threads_in_syscalls++; - if (number_of_threads_in_syscalls == 1) - { - TARGET_DISABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid)); - } - resume (0, TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; + Nor can we enable them after stepping until we've done a wait. + Thus, we simply set the flag ecs->enable_hw_watchpoints_after_wait + here, which will be serviced immediately after the target + is waited on. */ + case TARGET_WAITKIND_SYSCALL_RETURN: + target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); - /* Before examining the threads further, step this thread to - get it entirely out of the syscall. (We get notice of the - event when the thread is just on the verge of exiting a - syscall. Stepping one instruction seems to get it back - into user code.) + if (number_of_threads_in_syscalls > 0) + { + number_of_threads_in_syscalls--; + ecs->enable_hw_watchpoints_after_wait = + (number_of_threads_in_syscalls == 0); + } + prepare_to_wait (ecs); + return; - Note that although the logical place to reenable h/w watches - is here, we cannot. We cannot reenable them before stepping - the thread (this causes the next wait on the thread to hang). + case TARGET_WAITKIND_STOPPED: + stop_signal = ecs->ws.value.sig; + break; - Nor can we enable them after stepping until we've done a wait. - Thus, we simply set the flag ecs->enable_hw_watchpoints_after_wait - here, which will be serviced immediately after the target - is waited on. */ - case TARGET_WAITKIND_SYSCALL_RETURN: - target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); + /* We had an event in the inferior, but we are not interested + in handling it at this level. The lower layers have already + done what needs to be done, if anything. + + One of the possible circumstances for this is when the + inferior produces output for the console. The inferior has + not stopped, and we are ignoring the event. Another possible + circumstance is any event which the lower level knows will be + reported multiple times without an intervening resume. */ + case TARGET_WAITKIND_IGNORE: + prepare_to_wait (ecs); + return; + } - if (number_of_threads_in_syscalls > 0) - { - number_of_threads_in_syscalls--; - ecs->enable_hw_watchpoints_after_wait = - (number_of_threads_in_syscalls == 0); - } - prepare_to_wait (ecs); - return; + /* We may want to consider not doing a resume here in order to give + the user a chance to play with the new thread. It might be good + to make that a user-settable option. */ - case TARGET_WAITKIND_STOPPED: - stop_signal = ecs->ws.value.sig; - break; + /* At this point, all threads are stopped (happens automatically in + either the OS or the native code). Therefore we need to continue + all threads in order to make progress. */ + if (ecs->new_thread_event) + { + target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; + } - /* We had an event in the inferior, but we are not interested - in handling it at this level. The lower layers have already - done what needs to be done, if anything. This case can - occur only when the target is async or extended-async. One - of the circumstamces for this to happen is when the - inferior produces output for the console. The inferior has - not stopped, and we are ignoring the event. */ - case TARGET_WAITKIND_IGNORE: - ecs->wait_some_more = 1; - return; - } + stop_pc = read_pc_pid (ecs->ptid); - /* We may want to consider not doing a resume here in order to give - the user a chance to play with the new thread. It might be good - to make that a user-settable option. */ + if (stepping_past_singlestep_breakpoint) + { + gdb_assert (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p); + gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid)); + gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid)); - /* At this point, all threads are stopped (happens automatically in - either the OS or the native code). Therefore we need to continue - all threads in order to make progress. */ - if (ecs->new_thread_event) - { - target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; - } + stepping_past_singlestep_breakpoint = 0; - stop_pc = read_pc_pid (ecs->ptid); + /* We've either finished single-stepping past the single-step + breakpoint, or stopped for some other reason. It would be nice if + we could tell, but we can't reliably. */ + if (stop_signal == TARGET_SIGNAL_TRAP) + { + /* Pull the single step breakpoints out of the target. */ + SOFTWARE_SINGLE_STEP (0, 0); + singlestep_breakpoints_inserted_p = 0; - /* See if a thread hit a thread-specific breakpoint that was meant for - another thread. If so, then step that thread past the breakpoint, - and continue it. */ - - if (stop_signal == TARGET_SIGNAL_TRAP) - { - if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) ecs->random_signal = 0; - else if (breakpoints_inserted - && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK)) - { - ecs->random_signal = 0; - if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, - ecs->ptid)) - { - int remove_status; - /* Saw a breakpoint, but it was hit by the wrong thread. - Just continue. */ - if (DECR_PC_AFTER_BREAK) - write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->ptid); + ecs->ptid = saved_singlestep_ptid; + context_switch (ecs); + if (context_hook) + context_hook (pid_to_thread_id (ecs->ptid)); - remove_status = remove_breakpoints (); - /* Did we fail to remove breakpoints? If so, try - to set the PC past the bp. (There's at least - one situation in which we can fail to remove - the bp's: On HP-UX's that use ttrace, we can't - change the address space of a vforking child - process until the child exits (well, okay, not - then either :-) or execs. */ - if (remove_status != 0) - { - /* FIXME! This is obviously non-portable! */ - write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, - ecs->ptid); - /* We need to restart all the threads now, - * unles we're running in scheduler-locked mode. - * Use currently_stepping to determine whether to - * step or continue. - */ - /* FIXME MVS: is there any reason not to call resume()? */ - if (scheduler_mode == schedlock_on) - target_resume (ecs->ptid, - currently_stepping (ecs), - TARGET_SIGNAL_0); - else - target_resume (RESUME_ALL, - currently_stepping (ecs), - TARGET_SIGNAL_0); - prepare_to_wait (ecs); - return; - } - else - { /* Single step */ - breakpoints_inserted = 0; - if (!ptid_equal (inferior_ptid, ecs->ptid)) - context_switch (ecs); - ecs->waiton_ptid = ecs->ptid; - ecs->wp = &(ecs->ws); - ecs->another_trap = 1; + resume (1, TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; + } + } - ecs->infwait_state = infwait_thread_hop_state; - keep_going (ecs); - registers_changed (); - return; - } - } - } - } - else - ecs->random_signal = 1; + stepping_past_singlestep_breakpoint = 0; - /* See if something interesting happened to the non-current thread. If - so, then switch to that thread, and eventually give control back to - the user. + /* See if a thread hit a thread-specific breakpoint that was meant for + another thread. If so, then step that thread past the breakpoint, + and continue it. */ - Note that if there's any kind of pending follow (i.e., of a fork, - vfork or exec), we don't want to do this now. Rather, we'll let - the next resume handle it. */ - if (! ptid_equal (ecs->ptid, inferior_ptid) && - (pending_follow.kind == TARGET_WAITKIND_SPURIOUS)) - { - int printed = 0; + if (stop_signal == TARGET_SIGNAL_TRAP) + { + int thread_hop_needed = 0; - /* If it's a random signal for a non-current thread, notify user - if he's expressed an interest. */ - if (ecs->random_signal - && signal_print[stop_signal]) - { + /* Check if a regular breakpoint has been hit before checking + for a potential single step breakpoint. Otherwise, GDB will + not see this breakpoint hit when stepping onto breakpoints. */ + if (breakpoints_inserted && breakpoint_here_p (stop_pc)) + { + ecs->random_signal = 0; + if (!breakpoint_thread_match (stop_pc, ecs->ptid)) + thread_hop_needed = 1; + } + else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + ecs->random_signal = 0; + /* The call to in_thread_list is necessary because PTIDs sometimes + change when we go from single-threaded to multi-threaded. If + the singlestep_ptid is still in the list, assume that it is + really different from ecs->ptid. */ + if (!ptid_equal (singlestep_ptid, ecs->ptid) + && in_thread_list (singlestep_ptid)) + { + thread_hop_needed = 1; + stepping_past_singlestep_breakpoint = 1; + saved_singlestep_ptid = singlestep_ptid; + } + } + + if (thread_hop_needed) + { + int remove_status; + + /* Saw a breakpoint, but it was hit by the wrong thread. + Just continue. */ + + if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + /* Pull the single step breakpoints out of the target. */ + SOFTWARE_SINGLE_STEP (0, 0); + singlestep_breakpoints_inserted_p = 0; + } + + remove_status = remove_breakpoints (); + /* Did we fail to remove breakpoints? If so, try + to set the PC past the bp. (There's at least + one situation in which we can fail to remove + the bp's: On HP-UX's that use ttrace, we can't + change the address space of a vforking child + process until the child exits (well, okay, not + then either :-) or execs. */ + if (remove_status != 0) + { + /* FIXME! This is obviously non-portable! */ + write_pc_pid (stop_pc + 4, ecs->ptid); + /* We need to restart all the threads now, + * unles we're running in scheduler-locked mode. + * Use currently_stepping to determine whether to + * step or continue. + */ + /* FIXME MVS: is there any reason not to call resume()? */ + if (scheduler_mode == schedlock_on) + target_resume (ecs->ptid, + currently_stepping (ecs), TARGET_SIGNAL_0); + else + target_resume (RESUME_ALL, + currently_stepping (ecs), TARGET_SIGNAL_0); + prepare_to_wait (ecs); + return; + } + else + { /* Single step */ + breakpoints_inserted = 0; + if (!ptid_equal (inferior_ptid, ecs->ptid)) + context_switch (ecs); + ecs->waiton_ptid = ecs->ptid; + ecs->wp = &(ecs->ws); + ecs->another_trap = 1; + + ecs->infwait_state = infwait_thread_hop_state; + keep_going (ecs); + registers_changed (); + return; + } + } + else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + sw_single_step_trap_p = 1; + ecs->random_signal = 0; + } + } + else + ecs->random_signal = 1; + + /* See if something interesting happened to the non-current thread. If + so, then switch to that thread, and eventually give control back to + the user. + + Note that if there's any kind of pending follow (i.e., of a fork, + vfork or exec), we don't want to do this now. Rather, we'll let + the next resume handle it. */ + if (!ptid_equal (ecs->ptid, inferior_ptid) && + (pending_follow.kind == TARGET_WAITKIND_SPURIOUS)) + { + int printed = 0; + + /* If it's a random signal for a non-current thread, notify user + if he's expressed an interest. */ + if (ecs->random_signal && signal_print[stop_signal]) + { /* ??rehrauer: I don't understand the rationale for this code. If the inferior will stop as a result of this signal, then the act of handling the stop ought to print a message that's couches the stoppage in user @@ -1922,1018 +1909,883 @@ handle_inferior_event (struct execution_control_state *ecs) For now, remove the message altogether. */ #if 0 - printed = 1; - target_terminal_ours_for_output (); - printf_filtered ("\nProgram received signal %s, %s.\n", - target_signal_to_name (stop_signal), - target_signal_to_string (stop_signal)); - gdb_flush (gdb_stdout); -#endif - } - - /* If it's not SIGTRAP and not a signal we want to stop for, then - continue the thread. */ - - if (stop_signal != TARGET_SIGNAL_TRAP - && !signal_stop[stop_signal]) - { - if (printed) - target_terminal_inferior (); - - /* Clear the signal if it should not be passed. */ - if (signal_program[stop_signal] == 0) - stop_signal = TARGET_SIGNAL_0; - - target_resume (ecs->ptid, 0, stop_signal); - prepare_to_wait (ecs); - return; - } - - /* It's a SIGTRAP or a signal we're interested in. Switch threads, - and fall into the rest of wait_for_inferior(). */ - - context_switch (ecs); - - if (context_hook) - context_hook (pid_to_thread_id (ecs->ptid)); - - flush_cached_frames (); - } - - if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) - { - /* Pull the single step breakpoints out of the target. */ - SOFTWARE_SINGLE_STEP (0, 0); - singlestep_breakpoints_inserted_p = 0; - } - - /* If PC is pointing at a nullified instruction, then step beyond - it so that the user won't be confused when GDB appears to be ready - to execute it. */ - - /* if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */ - if (INSTRUCTION_NULLIFIED) - { - registers_changed (); - target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); - - /* We may have received a signal that we want to pass to - the inferior; therefore, we must not clobber the waitstatus - in WS. */ - - ecs->infwait_state = infwait_nullified_state; - ecs->waiton_ptid = ecs->ptid; - ecs->wp = &(ecs->tmpstatus); - prepare_to_wait (ecs); - return; - } - - /* It may not be necessary to disable the watchpoint to stop over - it. For example, the PA can (with some kernel cooperation) - single step over a watchpoint without disabling the watchpoint. */ - if (HAVE_STEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws)) - { - resume (1, 0); - prepare_to_wait (ecs); - return; - } - - /* It is far more common to need to disable a watchpoint to step - the inferior over it. FIXME. What else might a debug - register or page protection watchpoint scheme need here? */ - if (HAVE_NONSTEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws)) - { - /* At this point, we are stopped at an instruction which has - attempted to write to a piece of memory under control of - a watchpoint. The instruction hasn't actually executed - yet. If we were to evaluate the watchpoint expression - now, we would get the old value, and therefore no change - would seem to have occurred. - - In order to make watchpoints work `right', we really need - to complete the memory write, and then evaluate the - watchpoint expression. The following code does that by - removing the watchpoint (actually, all watchpoints and - breakpoints), single-stepping the target, re-inserting - watchpoints, and then falling through to let normal - single-step processing handle proceed. Since this - includes evaluating watchpoints, things will come to a - stop in the correct manner. */ - - if (DECR_PC_AFTER_BREAK) - write_pc (stop_pc - DECR_PC_AFTER_BREAK); - - remove_breakpoints (); - registers_changed (); - target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); /* Single step */ - - ecs->waiton_ptid = ecs->ptid; - ecs->wp = &(ecs->ws); - ecs->infwait_state = infwait_nonstep_watch_state; - prepare_to_wait (ecs); - return; - } - - /* It may be possible to simply continue after a watchpoint. */ - if (HAVE_CONTINUABLE_WATCHPOINT) - STOPPED_BY_WATCHPOINT (ecs->ws); - - ecs->stop_func_start = 0; - ecs->stop_func_end = 0; - ecs->stop_func_name = 0; - /* Don't care about return value; stop_func_start and stop_func_name - will both be 0 if it doesn't work. */ - find_pc_partial_function (stop_pc, &ecs->stop_func_name, - &ecs->stop_func_start, &ecs->stop_func_end); - ecs->stop_func_start += FUNCTION_START_OFFSET; - ecs->another_trap = 0; - bpstat_clear (&stop_bpstat); - stop_step = 0; - stop_stack_dummy = 0; - stop_print_frame = 1; - ecs->random_signal = 0; - stopped_by_random_signal = 0; - breakpoints_failed = 0; - - /* Look at the cause of the stop, and decide what to do. - The alternatives are: - 1) break; to really stop and return to the debugger, - 2) drop through to start up again - (set ecs->another_trap to 1 to single step once) - 3) set ecs->random_signal to 1, and the decision between 1 and 2 - will be made according to the signal handling tables. */ - - /* First, distinguish signals caused by the debugger from signals - that have to do with the program's own actions. - Note that breakpoint insns may cause SIGTRAP or SIGILL - or SIGEMT, depending on the operating system version. - Here we detect when a SIGILL or SIGEMT is really a breakpoint - and change it to SIGTRAP. */ - - if (stop_signal == TARGET_SIGNAL_TRAP - || (breakpoints_inserted && - (stop_signal == TARGET_SIGNAL_ILL - || stop_signal == TARGET_SIGNAL_EMT - )) - || stop_soon_quietly) - { - if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap) - { - stop_print_frame = 0; - stop_stepping (ecs); - return; - } - if (stop_soon_quietly) - { - stop_stepping (ecs); - return; - } - - /* Don't even think about breakpoints - if just proceeded over a breakpoint. - - However, if we are trying to proceed over a breakpoint - and end up in sigtramp, then through_sigtramp_breakpoint - will be set and we should check whether we've hit the - step breakpoint. */ - if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected - && through_sigtramp_breakpoint == NULL) - bpstat_clear (&stop_bpstat); - else - { - /* See if there is a breakpoint at the current PC. */ - - /* The second argument of bpstat_stop_status is meant to help - distinguish between a breakpoint trap and a singlestep trap. - This is only important on targets where DECR_PC_AFTER_BREAK - is non-zero. The prev_pc test is meant to distinguish between - singlestepping a trap instruction, and singlestepping thru a - jump to the instruction following a trap instruction. */ - - stop_bpstat = bpstat_stop_status - (&stop_pc, - /* Pass TRUE if our reason for stopping is something other - than hitting a breakpoint. We do this by checking that - 1) stepping is going on and 2) we didn't hit a breakpoint - in a signal handler without an intervening stop in - sigtramp, which is detected by a new stack pointer value - below any usual function calling stack adjustments. */ - (currently_stepping (ecs) - && prev_pc != stop_pc - DECR_PC_AFTER_BREAK - && !(step_range_end - && INNER_THAN (read_sp (), (step_sp - 16)))) - ); - /* Following in case break condition called a - function. */ - stop_print_frame = 1; - } - - if (stop_signal == TARGET_SIGNAL_TRAP) - ecs->random_signal - = !(bpstat_explains_signal (stop_bpstat) - || trap_expected - || (!CALL_DUMMY_BREAKPOINT_OFFSET_P - && PC_IN_CALL_DUMMY (stop_pc, read_sp (), - FRAME_FP (get_current_frame ()))) - || (step_range_end && step_resume_breakpoint == NULL)); - - else - { - ecs->random_signal - = !(bpstat_explains_signal (stop_bpstat) - /* End of a stack dummy. Some systems (e.g. Sony - news) give another signal besides SIGTRAP, so - check here as well as above. */ - || (!CALL_DUMMY_BREAKPOINT_OFFSET_P - && PC_IN_CALL_DUMMY (stop_pc, read_sp (), - FRAME_FP (get_current_frame ()))) - ); - if (!ecs->random_signal) - stop_signal = TARGET_SIGNAL_TRAP; - } - } - - /* When we reach this point, we've pretty much decided - that the reason for stopping must've been a random - (unexpected) signal. */ - - else - ecs->random_signal = 1; - /* If a fork, vfork or exec event was seen, then there are two - possible responses we can make: - - 1. If a catchpoint triggers for the event (ecs->random_signal == 0), - then we must stop now and issue a prompt. We will resume - the inferior when the user tells us to. - 2. If no catchpoint triggers for the event (ecs->random_signal == 1), - then we must resume the inferior now and keep checking. - - In either case, we must take appropriate steps to "follow" the - the fork/vfork/exec when the inferior is resumed. For example, - if follow-fork-mode is "child", then we must detach from the - parent inferior and follow the new child inferior. - - In either case, setting pending_follow causes the next resume() - to take the appropriate following action. */ - process_event_stop_test: - if (ecs->ws.kind == TARGET_WAITKIND_FORKED) - { - if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */ - { - trap_expected = 1; - stop_signal = TARGET_SIGNAL_0; - keep_going (ecs); - return; - } - } - else if (ecs->ws.kind == TARGET_WAITKIND_VFORKED) - { - if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */ - { - stop_signal = TARGET_SIGNAL_0; - keep_going (ecs); - return; - } - } - else if (ecs->ws.kind == TARGET_WAITKIND_EXECD) - { - pending_follow.kind = ecs->ws.kind; - if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */ - { - trap_expected = 1; - stop_signal = TARGET_SIGNAL_0; - keep_going (ecs); - return; - } - } - - /* For the program's own signals, act according to - the signal handling tables. */ - - if (ecs->random_signal) - { - /* Signal not for debugging purposes. */ - int printed = 0; - - stopped_by_random_signal = 1; - - if (signal_print[stop_signal]) - { - printed = 1; - target_terminal_ours_for_output (); - print_stop_reason (SIGNAL_RECEIVED, stop_signal); - } - if (signal_stop[stop_signal]) - { - stop_stepping (ecs); - return; - } - /* If not going to stop, give terminal back - if we took it away. */ - else if (printed) - target_terminal_inferior (); - - /* Clear the signal if it should not be passed. */ - if (signal_program[stop_signal] == 0) - stop_signal = TARGET_SIGNAL_0; - - /* I'm not sure whether this needs to be check_sigtramp2 or - whether it could/should be keep_going. - - This used to jump to step_over_function if we are stepping, - which is wrong. - - Suppose the user does a `next' over a function call, and while - that call is in progress, the inferior receives a signal for - which GDB does not stop (i.e., signal_stop[SIG] is false). In - that case, when we reach this point, there is already a - step-resume breakpoint established, right where it should be: - immediately after the function call the user is "next"-ing - over. If we call step_over_function now, two bad things - happen: - - - we'll create a new breakpoint, at wherever the current - frame's return address happens to be. That could be - anywhere, depending on what function call happens to be on - the top of the stack at that point. Point is, it's probably - not where we need it. - - - the existing step-resume breakpoint (which is at the correct - address) will get orphaned: step_resume_breakpoint will point - to the new breakpoint, and the old step-resume breakpoint - will never be cleaned up. - - The old behavior was meant to help HP-UX single-step out of - sigtramps. It would place the new breakpoint at prev_pc, which - was certainly wrong. I don't know the details there, so fixing - this probably breaks that. As with anything else, it's up to - the HP-UX maintainer to furnish a fix that doesn't break other - platforms. --JimB, 20 May 1999 */ - check_sigtramp2 (ecs); - keep_going (ecs); - return; - } - - /* Handle cases caused by hitting a breakpoint. */ - { - CORE_ADDR jmp_buf_pc; - struct bpstat_what what; - - what = bpstat_what (stop_bpstat); - - if (what.call_dummy) - { - stop_stack_dummy = 1; -#ifdef HP_OS_BUG - trap_expected_after_continue = 1; + printed = 1; + target_terminal_ours_for_output (); + printf_filtered ("\nProgram received signal %s, %s.\n", + target_signal_to_name (stop_signal), + target_signal_to_string (stop_signal)); + gdb_flush (gdb_stdout); #endif } - switch (what.main_action) + /* If it's not SIGTRAP and not a signal we want to stop for, then + continue the thread. */ + + if (stop_signal != TARGET_SIGNAL_TRAP && !signal_stop[stop_signal]) { - case BPSTAT_WHAT_SET_LONGJMP_RESUME: - /* If we hit the breakpoint at longjmp, disable it for the - duration of this command. Then, install a temporary - breakpoint at the target of the jmp_buf. */ - disable_longjmp_breakpoint (); - remove_breakpoints (); - breakpoints_inserted = 0; - if (!GET_LONGJMP_TARGET_P () - || !GET_LONGJMP_TARGET (&jmp_buf_pc)) - { - keep_going (ecs); - return; - } - - /* Need to blow away step-resume breakpoint, as it - interferes with us */ - if (step_resume_breakpoint != NULL) - { - delete_step_resume_breakpoint (&step_resume_breakpoint); - } - /* Not sure whether we need to blow this away too, but probably - it is like the step-resume breakpoint. */ - if (through_sigtramp_breakpoint != NULL) - { - delete_breakpoint (through_sigtramp_breakpoint); - through_sigtramp_breakpoint = NULL; - } - -#if 0 - /* FIXME - Need to implement nested temporary breakpoints */ - if (step_over_calls > 0) - set_longjmp_resume_breakpoint (jmp_buf_pc, - get_current_frame ()); - else -#endif /* 0 */ - set_longjmp_resume_breakpoint (jmp_buf_pc, NULL); - ecs->handling_longjmp = 1; /* FIXME */ - keep_going (ecs); - return; - - case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME: - case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE: - remove_breakpoints (); - breakpoints_inserted = 0; -#if 0 - /* FIXME - Need to implement nested temporary breakpoints */ - if (step_over_calls - && (INNER_THAN (FRAME_FP (get_current_frame ()), - step_frame_address))) - { - ecs->another_trap = 1; - keep_going (ecs); - return; - } -#endif /* 0 */ - disable_longjmp_breakpoint (); - ecs->handling_longjmp = 0; /* FIXME */ - if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME) - break; - /* else fallthrough */ - - case BPSTAT_WHAT_SINGLE: - if (breakpoints_inserted) - { - remove_breakpoints (); - } - breakpoints_inserted = 0; - ecs->another_trap = 1; - /* Still need to check other stuff, at least the case - where we are stepping and step out of the right range. */ - break; - - case BPSTAT_WHAT_STOP_NOISY: - stop_print_frame = 1; - - /* We are about to nuke the step_resume_breakpoint and - through_sigtramp_breakpoint via the cleanup chain, so - no need to worry about it here. */ - - stop_stepping (ecs); - return; - - case BPSTAT_WHAT_STOP_SILENT: - stop_print_frame = 0; - - /* We are about to nuke the step_resume_breakpoint and - through_sigtramp_breakpoint via the cleanup chain, so - no need to worry about it here. */ - - stop_stepping (ecs); - return; - - case BPSTAT_WHAT_STEP_RESUME: - /* This proably demands a more elegant solution, but, yeah - right... - - This function's use of the simple variable - step_resume_breakpoint doesn't seem to accomodate - simultaneously active step-resume bp's, although the - breakpoint list certainly can. - - If we reach here and step_resume_breakpoint is already - NULL, then apparently we have multiple active - step-resume bp's. We'll just delete the breakpoint we - stopped at, and carry on. - - Correction: what the code currently does is delete a - step-resume bp, but it makes no effort to ensure that - the one deleted is the one currently stopped at. MVS */ - - if (step_resume_breakpoint == NULL) - { - step_resume_breakpoint = - bpstat_find_step_resume_breakpoint (stop_bpstat); - } - delete_step_resume_breakpoint (&step_resume_breakpoint); - break; - - case BPSTAT_WHAT_THROUGH_SIGTRAMP: - if (through_sigtramp_breakpoint) - delete_breakpoint (through_sigtramp_breakpoint); - through_sigtramp_breakpoint = NULL; - - /* If were waiting for a trap, hitting the step_resume_break - doesn't count as getting it. */ - if (trap_expected) - ecs->another_trap = 1; - break; - - case BPSTAT_WHAT_CHECK_SHLIBS: - case BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK: -#ifdef SOLIB_ADD - { - /* Remove breakpoints, we eventually want to step over the - shlib event breakpoint, and SOLIB_ADD might adjust - breakpoint addresses via breakpoint_re_set. */ - if (breakpoints_inserted) - remove_breakpoints (); - breakpoints_inserted = 0; - - /* Check for any newly added shared libraries if we're - supposed to be adding them automatically. Switch - terminal for any messages produced by - breakpoint_re_set. */ - target_terminal_ours_for_output (); - SOLIB_ADD (NULL, 0, NULL, auto_solib_add); + if (printed) target_terminal_inferior (); - /* Try to reenable shared library breakpoints, additional - code segments in shared libraries might be mapped in now. */ - re_enable_breakpoints_in_shlibs (); + /* Clear the signal if it should not be passed. */ + if (signal_program[stop_signal] == 0) + stop_signal = TARGET_SIGNAL_0; - /* If requested, stop when the dynamic linker notifies - gdb of events. This allows the user to get control - and place breakpoints in initializer routines for - dynamically loaded objects (among other things). */ - if (stop_on_solib_events) - { - stop_stepping (ecs); - return; - } + target_resume (ecs->ptid, 0, stop_signal); + prepare_to_wait (ecs); + return; + } - /* If we stopped due to an explicit catchpoint, then the - (see above) call to SOLIB_ADD pulled in any symbols - from a newly-loaded library, if appropriate. + /* It's a SIGTRAP or a signal we're interested in. Switch threads, + and fall into the rest of wait_for_inferior(). */ - We do want the inferior to stop, but not where it is - now, which is in the dynamic linker callback. Rather, - we would like it stop in the user's program, just after - the call that caused this catchpoint to trigger. That - gives the user a more useful vantage from which to - examine their program's state. */ - else if (what.main_action == BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK) - { - /* ??rehrauer: If I could figure out how to get the - right return PC from here, we could just set a temp - breakpoint and resume. I'm not sure we can without - cracking open the dld's shared libraries and sniffing - their unwind tables and text/data ranges, and that's - not a terribly portable notion. + context_switch (ecs); - Until that time, we must step the inferior out of the - dld callback, and also out of the dld itself (and any - code or stubs in libdld.sl, such as "shl_load" and - friends) until we reach non-dld code. At that point, - we can stop stepping. */ - bpstat_get_triggered_catchpoints (stop_bpstat, - &ecs->stepping_through_solib_catchpoints); - ecs->stepping_through_solib_after_catch = 1; + if (context_hook) + context_hook (pid_to_thread_id (ecs->ptid)); - /* Be sure to lift all breakpoints, so the inferior does - actually step past this point... */ - ecs->another_trap = 1; - break; - } - else - { - /* We want to step over this breakpoint, then keep going. */ - ecs->another_trap = 1; - break; - } - } -#endif - break; + flush_cached_frames (); + } - case BPSTAT_WHAT_LAST: - /* Not a real code, but listed here to shut up gcc -Wall. */ + if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + /* Pull the single step breakpoints out of the target. */ + SOFTWARE_SINGLE_STEP (0, 0); + singlestep_breakpoints_inserted_p = 0; + } - case BPSTAT_WHAT_KEEP_CHECKING: - break; + /* If PC is pointing at a nullified instruction, then step beyond + it so that the user won't be confused when GDB appears to be ready + to execute it. */ + + /* if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */ + if (INSTRUCTION_NULLIFIED) + { + registers_changed (); + target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); + + /* We may have received a signal that we want to pass to + the inferior; therefore, we must not clobber the waitstatus + in WS. */ + + ecs->infwait_state = infwait_nullified_state; + ecs->waiton_ptid = ecs->ptid; + ecs->wp = &(ecs->tmpstatus); + prepare_to_wait (ecs); + return; + } + + /* It may not be necessary to disable the watchpoint to stop over + it. For example, the PA can (with some kernel cooperation) + single step over a watchpoint without disabling the watchpoint. */ + if (HAVE_STEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws)) + { + resume (1, 0); + prepare_to_wait (ecs); + return; + } + + /* It is far more common to need to disable a watchpoint to step + the inferior over it. FIXME. What else might a debug + register or page protection watchpoint scheme need here? */ + if (HAVE_NONSTEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws)) + { + /* At this point, we are stopped at an instruction which has + attempted to write to a piece of memory under control of + a watchpoint. The instruction hasn't actually executed + yet. If we were to evaluate the watchpoint expression + now, we would get the old value, and therefore no change + would seem to have occurred. + + In order to make watchpoints work `right', we really need + to complete the memory write, and then evaluate the + watchpoint expression. The following code does that by + removing the watchpoint (actually, all watchpoints and + breakpoints), single-stepping the target, re-inserting + watchpoints, and then falling through to let normal + single-step processing handle proceed. Since this + includes evaluating watchpoints, things will come to a + stop in the correct manner. */ + + remove_breakpoints (); + registers_changed (); + target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); /* Single step */ + + ecs->waiton_ptid = ecs->ptid; + ecs->wp = &(ecs->ws); + ecs->infwait_state = infwait_nonstep_watch_state; + prepare_to_wait (ecs); + return; + } + + /* It may be possible to simply continue after a watchpoint. */ + if (HAVE_CONTINUABLE_WATCHPOINT) + STOPPED_BY_WATCHPOINT (ecs->ws); + + ecs->stop_func_start = 0; + ecs->stop_func_end = 0; + ecs->stop_func_name = 0; + /* Don't care about return value; stop_func_start and stop_func_name + will both be 0 if it doesn't work. */ + find_pc_partial_function (stop_pc, &ecs->stop_func_name, + &ecs->stop_func_start, &ecs->stop_func_end); + ecs->stop_func_start += FUNCTION_START_OFFSET; + ecs->another_trap = 0; + bpstat_clear (&stop_bpstat); + stop_step = 0; + stop_stack_dummy = 0; + stop_print_frame = 1; + ecs->random_signal = 0; + stopped_by_random_signal = 0; + breakpoints_failed = 0; + + /* Look at the cause of the stop, and decide what to do. + The alternatives are: + 1) break; to really stop and return to the debugger, + 2) drop through to start up again + (set ecs->another_trap to 1 to single step once) + 3) set ecs->random_signal to 1, and the decision between 1 and 2 + will be made according to the signal handling tables. */ + + /* First, distinguish signals caused by the debugger from signals + that have to do with the program's own actions. Note that + breakpoint insns may cause SIGTRAP or SIGILL or SIGEMT, depending + on the operating system version. Here we detect when a SIGILL or + SIGEMT is really a breakpoint and change it to SIGTRAP. We do + something similar for SIGSEGV, since a SIGSEGV will be generated + when we're trying to execute a breakpoint instruction on a + non-executable stack. This happens for call dummy breakpoints + for architectures like SPARC that place call dummies on the + stack. */ + + if (stop_signal == TARGET_SIGNAL_TRAP + || (breakpoints_inserted && + (stop_signal == TARGET_SIGNAL_ILL + || stop_signal == TARGET_SIGNAL_SEGV + || stop_signal == TARGET_SIGNAL_EMT)) + || stop_soon == STOP_QUIETLY + || stop_soon == STOP_QUIETLY_NO_SIGSTOP) + { + if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap) + { + stop_print_frame = 0; + stop_stepping (ecs); + return; + } + + /* This is originated from start_remote(), start_inferior() and + shared libraries hook functions. */ + if (stop_soon == STOP_QUIETLY) + { + stop_stepping (ecs); + return; + } + + /* This originates from attach_command(). We need to overwrite + the stop_signal here, because some kernels don't ignore a + SIGSTOP in a subsequent ptrace(PTRACE_SONT,SOGSTOP) call. + See more comments in inferior.h. */ + if (stop_soon == STOP_QUIETLY_NO_SIGSTOP) + { + stop_stepping (ecs); + if (stop_signal == TARGET_SIGNAL_STOP) + stop_signal = TARGET_SIGNAL_0; + return; + } + + /* Don't even think about breakpoints + if just proceeded over a breakpoint. + + However, if we are trying to proceed over a breakpoint + and end up in sigtramp, then through_sigtramp_breakpoint + will be set and we should check whether we've hit the + step breakpoint. */ + if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected + && through_sigtramp_breakpoint == NULL) + bpstat_clear (&stop_bpstat); + else + { + /* See if there is a breakpoint at the current PC. */ + stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); + + /* Following in case break condition called a + function. */ + stop_print_frame = 1; + } + + /* NOTE: cagney/2003-03-29: These two checks for a random signal + at one stage in the past included checks for an inferior + function call's call dummy's return breakpoint. The original + comment, that went with the test, read: + + ``End of a stack dummy. Some systems (e.g. Sony news) give + another signal besides SIGTRAP, so check here as well as + above.'' + + If someone ever tries to get get call dummys on a + non-executable stack to work (where the target would stop + with something like a SIGSEGV), then those tests might need + to be re-instated. Given, however, that the tests were only + enabled when momentary breakpoints were not being used, I + suspect that it won't be the case. + + NOTE: kettenis/2004-02-05: Indeed such checks don't seem to + be necessary for call dummies on a non-executable stack on + SPARC. */ + + if (stop_signal == TARGET_SIGNAL_TRAP) + ecs->random_signal + = !(bpstat_explains_signal (stop_bpstat) + || trap_expected + || (step_range_end && step_resume_breakpoint == NULL)); + else + { + ecs->random_signal = !bpstat_explains_signal (stop_bpstat); + if (!ecs->random_signal) + stop_signal = TARGET_SIGNAL_TRAP; } } - /* We come here if we hit a breakpoint but should not - stop for it. Possibly we also were stepping - and should stop for that. So fall through and - test for stepping. But, if not stepping, - do not stop. */ + /* When we reach this point, we've pretty much decided + that the reason for stopping must've been a random + (unexpected) signal. */ - /* Are we stepping to get the inferior out of the dynamic - linker's hook (and possibly the dld itself) after catching - a shlib event? */ - if (ecs->stepping_through_solib_after_catch) + else + ecs->random_signal = 1; + +process_event_stop_test: + /* For the program's own signals, act according to + the signal handling tables. */ + + if (ecs->random_signal) + { + /* Signal not for debugging purposes. */ + int printed = 0; + + stopped_by_random_signal = 1; + + if (signal_print[stop_signal]) + { + printed = 1; + target_terminal_ours_for_output (); + print_stop_reason (SIGNAL_RECEIVED, stop_signal); + } + if (signal_stop[stop_signal]) + { + stop_stepping (ecs); + return; + } + /* If not going to stop, give terminal back + if we took it away. */ + else if (printed) + target_terminal_inferior (); + + /* Clear the signal if it should not be passed. */ + if (signal_program[stop_signal] == 0) + stop_signal = TARGET_SIGNAL_0; + + /* I'm not sure whether this needs to be check_sigtramp2 or + whether it could/should be keep_going. + + This used to jump to step_over_function if we are stepping, + which is wrong. + + Suppose the user does a `next' over a function call, and while + that call is in progress, the inferior receives a signal for + which GDB does not stop (i.e., signal_stop[SIG] is false). In + that case, when we reach this point, there is already a + step-resume breakpoint established, right where it should be: + immediately after the function call the user is "next"-ing + over. If we call step_over_function now, two bad things + happen: + + - we'll create a new breakpoint, at wherever the current + frame's return address happens to be. That could be + anywhere, depending on what function call happens to be on + the top of the stack at that point. Point is, it's probably + not where we need it. + + - the existing step-resume breakpoint (which is at the correct + address) will get orphaned: step_resume_breakpoint will point + to the new breakpoint, and the old step-resume breakpoint + will never be cleaned up. + + The old behavior was meant to help HP-UX single-step out of + sigtramps. It would place the new breakpoint at prev_pc, which + was certainly wrong. I don't know the details there, so fixing + this probably breaks that. As with anything else, it's up to + the HP-UX maintainer to furnish a fix that doesn't break other + platforms. --JimB, 20 May 1999 */ + check_sigtramp2 (ecs); + keep_going (ecs); + return; + } + + /* Handle cases caused by hitting a breakpoint. */ + { + CORE_ADDR jmp_buf_pc; + struct bpstat_what what; + + what = bpstat_what (stop_bpstat); + + if (what.call_dummy) { -#if defined(SOLIB_ADD) - /* Have we reached our destination? If not, keep going. */ - if (SOLIB_IN_DYNAMIC_LINKER (PIDGET (ecs->ptid), stop_pc)) + stop_stack_dummy = 1; +#ifdef HP_OS_BUG + trap_expected_after_continue = 1; +#endif + } + + switch (what.main_action) + { + case BPSTAT_WHAT_SET_LONGJMP_RESUME: + /* If we hit the breakpoint at longjmp, disable it for the + duration of this command. Then, install a temporary + breakpoint at the target of the jmp_buf. */ + disable_longjmp_breakpoint (); + remove_breakpoints (); + breakpoints_inserted = 0; + if (!GET_LONGJMP_TARGET_P () || !GET_LONGJMP_TARGET (&jmp_buf_pc)) + { + keep_going (ecs); + return; + } + + /* Need to blow away step-resume breakpoint, as it + interferes with us */ + if (step_resume_breakpoint != NULL) + { + delete_step_resume_breakpoint (&step_resume_breakpoint); + } + /* Not sure whether we need to blow this away too, but probably + it is like the step-resume breakpoint. */ + if (through_sigtramp_breakpoint != NULL) + { + delete_breakpoint (through_sigtramp_breakpoint); + through_sigtramp_breakpoint = NULL; + } + +#if 0 + /* FIXME - Need to implement nested temporary breakpoints */ + if (step_over_calls > 0) + set_longjmp_resume_breakpoint (jmp_buf_pc, get_current_frame ()); + else +#endif /* 0 */ + set_longjmp_resume_breakpoint (jmp_buf_pc, null_frame_id); + ecs->handling_longjmp = 1; /* FIXME */ + keep_going (ecs); + return; + + case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME: + case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE: + remove_breakpoints (); + breakpoints_inserted = 0; +#if 0 + /* FIXME - Need to implement nested temporary breakpoints */ + if (step_over_calls + && (frame_id_inner (get_frame_id (get_current_frame ()), + step_frame_id))) { ecs->another_trap = 1; keep_going (ecs); return; } -#endif - /* Else, stop and report the catchpoint(s) whose triggering - caused us to begin stepping. */ - ecs->stepping_through_solib_after_catch = 0; - bpstat_clear (&stop_bpstat); - stop_bpstat = bpstat_copy (ecs->stepping_through_solib_catchpoints); - bpstat_clear (&ecs->stepping_through_solib_catchpoints); +#endif /* 0 */ + disable_longjmp_breakpoint (); + ecs->handling_longjmp = 0; /* FIXME */ + if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME) + break; + /* else fallthrough */ + + case BPSTAT_WHAT_SINGLE: + if (breakpoints_inserted) + { + remove_breakpoints (); + } + breakpoints_inserted = 0; + ecs->another_trap = 1; + /* Still need to check other stuff, at least the case + where we are stepping and step out of the right range. */ + break; + + case BPSTAT_WHAT_STOP_NOISY: stop_print_frame = 1; + + /* We are about to nuke the step_resume_breakpoint and + through_sigtramp_breakpoint via the cleanup chain, so + no need to worry about it here. */ + stop_stepping (ecs); return; - } - if (!CALL_DUMMY_BREAKPOINT_OFFSET_P) - { - /* This is the old way of detecting the end of the stack dummy. - An architecture which defines CALL_DUMMY_BREAKPOINT_OFFSET gets - handled above. As soon as we can test it on all of them, all - architectures should define it. */ + case BPSTAT_WHAT_STOP_SILENT: + stop_print_frame = 0; - /* If this is the breakpoint at the end of a stack dummy, - just stop silently, unless the user was doing an si/ni, in which - case she'd better know what she's doing. */ + /* We are about to nuke the step_resume_breakpoint and + through_sigtramp_breakpoint via the cleanup chain, so + no need to worry about it here. */ - if (CALL_DUMMY_HAS_COMPLETED (stop_pc, read_sp (), - FRAME_FP (get_current_frame ())) - && !step_range_end) + stop_stepping (ecs); + return; + + case BPSTAT_WHAT_STEP_RESUME: + /* This proably demands a more elegant solution, but, yeah + right... + + This function's use of the simple variable + step_resume_breakpoint doesn't seem to accomodate + simultaneously active step-resume bp's, although the + breakpoint list certainly can. + + If we reach here and step_resume_breakpoint is already + NULL, then apparently we have multiple active + step-resume bp's. We'll just delete the breakpoint we + stopped at, and carry on. + + Correction: what the code currently does is delete a + step-resume bp, but it makes no effort to ensure that + the one deleted is the one currently stopped at. MVS */ + + if (step_resume_breakpoint == NULL) { - stop_print_frame = 0; - stop_stack_dummy = 1; -#ifdef HP_OS_BUG - trap_expected_after_continue = 1; -#endif - stop_stepping (ecs); - return; - } - } - - if (step_resume_breakpoint) - { - /* Having a step-resume breakpoint overrides anything - else having to do with stepping commands until - that breakpoint is reached. */ - /* I'm not sure whether this needs to be check_sigtramp2 or - whether it could/should be keep_going. */ - check_sigtramp2 (ecs); - keep_going (ecs); - return; - } - - if (step_range_end == 0) - { - /* Likewise if we aren't even stepping. */ - /* I'm not sure whether this needs to be check_sigtramp2 or - whether it could/should be keep_going. */ - check_sigtramp2 (ecs); - keep_going (ecs); - return; - } - - /* If stepping through a line, keep going if still within it. - - Note that step_range_end is the address of the first instruction - beyond the step range, and NOT the address of the last instruction - within it! */ - if (stop_pc >= step_range_start - && stop_pc < step_range_end) - { - /* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal. - So definately need to check for sigtramp here. */ - check_sigtramp2 (ecs); - keep_going (ecs); - return; - } - - /* We stepped out of the stepping range. */ - - /* If we are stepping at the source level and entered the runtime - loader dynamic symbol resolution code, we keep on single stepping - until we exit the run time loader code and reach the callee's - address. */ - if (step_over_calls == STEP_OVER_UNDEBUGGABLE && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc)) - { - CORE_ADDR pc_after_resolver = SKIP_SOLIB_RESOLVER (stop_pc); - - if (pc_after_resolver) - { - /* Set up a step-resume breakpoint at the address - indicated by SKIP_SOLIB_RESOLVER. */ - struct symtab_and_line sr_sal; - INIT_SAL (&sr_sal); - sr_sal.pc = pc_after_resolver; - - check_for_old_step_resume_breakpoint (); step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_step_resume); - if (breakpoints_inserted) - insert_breakpoints (); + bpstat_find_step_resume_breakpoint (stop_bpstat); } + delete_step_resume_breakpoint (&step_resume_breakpoint); + break; - keep_going (ecs); - return; - } - - /* We can't update step_sp every time through the loop, because - reading the stack pointer would slow down stepping too much. - But we can update it every time we leave the step range. */ - ecs->update_step_sp = 1; - - /* Did we just take a signal? */ - if (IN_SIGTRAMP (stop_pc, ecs->stop_func_name) - && !IN_SIGTRAMP (prev_pc, prev_func_name) - && INNER_THAN (read_sp (), step_sp)) - { - /* We've just taken a signal; go until we are back to - the point where we took it and one more. */ - - /* Note: The test above succeeds not only when we stepped - into a signal handler, but also when we step past the last - statement of a signal handler and end up in the return stub - of the signal handler trampoline. To distinguish between - these two cases, check that the frame is INNER_THAN the - previous one below. pai/1997-09-11 */ + case BPSTAT_WHAT_THROUGH_SIGTRAMP: + if (through_sigtramp_breakpoint) + delete_breakpoint (through_sigtramp_breakpoint); + through_sigtramp_breakpoint = NULL; + /* If were waiting for a trap, hitting the step_resume_break + doesn't count as getting it. */ + if (trap_expected) + ecs->another_trap = 1; + break; + case BPSTAT_WHAT_CHECK_SHLIBS: + case BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK: +#ifdef SOLIB_ADD { - CORE_ADDR current_frame = FRAME_FP (get_current_frame ()); + /* Remove breakpoints, we eventually want to step over the + shlib event breakpoint, and SOLIB_ADD might adjust + breakpoint addresses via breakpoint_re_set. */ + if (breakpoints_inserted) + remove_breakpoints (); + breakpoints_inserted = 0; - if (INNER_THAN (current_frame, step_frame_address)) + /* Check for any newly added shared libraries if we're + supposed to be adding them automatically. Switch + terminal for any messages produced by + breakpoint_re_set. */ + target_terminal_ours_for_output (); + /* NOTE: cagney/2003-11-25: Make certain that the target + stack's section table is kept up-to-date. Architectures, + (e.g., PPC64), use the section table to perform + operations such as address => section name and hence + require the table to contain all sections (including + those found in shared libraries). */ + /* NOTE: cagney/2003-11-25: Pass current_target and not + exec_ops to SOLIB_ADD. This is because current GDB is + only tooled to propagate section_table changes out from + the "current_target" (see target_resize_to_sections), and + not up from the exec stratum. This, of course, isn't + right. "infrun.c" should only interact with the + exec/process stratum, instead relying on the target stack + to propagate relevant changes (stop, section table + changed, ...) up to other layers. */ + SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); + target_terminal_inferior (); + + /* Try to reenable shared library breakpoints, additional + code segments in shared libraries might be mapped in now. */ + re_enable_breakpoints_in_shlibs (); + + /* If requested, stop when the dynamic linker notifies + gdb of events. This allows the user to get control + and place breakpoints in initializer routines for + dynamically loaded objects (among other things). */ + if (stop_on_solib_events || stop_stack_dummy) { - /* We have just taken a signal; go until we are back to - the point where we took it and one more. */ + stop_stepping (ecs); + return; + } - /* This code is needed at least in the following case: - The user types "next" and then a signal arrives (before - the "next" is done). */ + /* If we stopped due to an explicit catchpoint, then the + (see above) call to SOLIB_ADD pulled in any symbols + from a newly-loaded library, if appropriate. - /* Note that if we are stopped at a breakpoint, then we need - the step_resume breakpoint to override any breakpoints at - the same location, so that we will still step over the - breakpoint even though the signal happened. */ - struct symtab_and_line sr_sal; + We do want the inferior to stop, but not where it is + now, which is in the dynamic linker callback. Rather, + we would like it stop in the user's program, just after + the call that caused this catchpoint to trigger. That + gives the user a more useful vantage from which to + examine their program's state. */ + else if (what.main_action == + BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK) + { + /* ??rehrauer: If I could figure out how to get the + right return PC from here, we could just set a temp + breakpoint and resume. I'm not sure we can without + cracking open the dld's shared libraries and sniffing + their unwind tables and text/data ranges, and that's + not a terribly portable notion. - INIT_SAL (&sr_sal); - sr_sal.symtab = NULL; - sr_sal.line = 0; - sr_sal.pc = prev_pc; - /* We could probably be setting the frame to - step_frame_address; I don't think anyone thought to - try it. */ - check_for_old_step_resume_breakpoint (); - step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_step_resume); - if (breakpoints_inserted) - insert_breakpoints (); + Until that time, we must step the inferior out of the + dld callback, and also out of the dld itself (and any + code or stubs in libdld.sl, such as "shl_load" and + friends) until we reach non-dld code. At that point, + we can stop stepping. */ + bpstat_get_triggered_catchpoints (stop_bpstat, + &ecs-> + stepping_through_solib_catchpoints); + ecs->stepping_through_solib_after_catch = 1; + + /* Be sure to lift all breakpoints, so the inferior does + actually step past this point... */ + ecs->another_trap = 1; + break; } else { - /* We just stepped out of a signal handler and into - its calling trampoline. - - Normally, we'd call step_over_function from - here, but for some reason GDB can't unwind the - stack correctly to find the real PC for the point - user code where the signal trampoline will return - -- FRAME_SAVED_PC fails, at least on HP-UX 10.20. - But signal trampolines are pretty small stubs of - code, anyway, so it's OK instead to just - single-step out. Note: assuming such trampolines - don't exhibit recursion on any platform... */ - find_pc_partial_function (stop_pc, &ecs->stop_func_name, - &ecs->stop_func_start, - &ecs->stop_func_end); - /* Readjust stepping range */ - step_range_start = ecs->stop_func_start; - step_range_end = ecs->stop_func_end; - ecs->stepping_through_sigtramp = 1; + /* We want to step over this breakpoint, then keep going. */ + ecs->another_trap = 1; + break; } } +#endif + break; + case BPSTAT_WHAT_LAST: + /* Not a real code, but listed here to shut up gcc -Wall. */ - /* If this is stepi or nexti, make sure that the stepping range - gets us past that instruction. */ - if (step_range_end == 1) - /* FIXME: Does this run afoul of the code below which, if - we step into the middle of a line, resets the stepping - range? */ - step_range_end = (step_range_start = prev_pc) + 1; - - ecs->remove_breakpoints_on_following_step = 1; - keep_going (ecs); - return; + case BPSTAT_WHAT_KEEP_CHECKING: + break; } + } - if (stop_pc == ecs->stop_func_start /* Quick test */ - || (in_prologue (stop_pc, ecs->stop_func_start) && - !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) - || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, ecs->stop_func_name) - || ecs->stop_func_name == 0) - { - /* It's a subroutine call. */ + /* We come here if we hit a breakpoint but should not + stop for it. Possibly we also were stepping + and should stop for that. So fall through and + test for stepping. But, if not stepping, + do not stop. */ - if ((step_over_calls == STEP_OVER_NONE) - || ((step_range_end == 1) - && in_prologue (prev_pc, ecs->stop_func_start))) - { - /* I presume that step_over_calls is only 0 when we're - supposed to be stepping at the assembly language level - ("stepi"). Just stop. */ - /* Also, maybe we just did a "nexti" inside a prolog, - so we thought it was a subroutine call but it was not. - Stop as well. FENN */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - - if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc)) - { - /* We're doing a "next". */ - - if (IN_SIGTRAMP (stop_pc, ecs->stop_func_name) - && INNER_THAN (step_frame_address, read_sp())) - /* We stepped out of a signal handler, and into its - calling trampoline. This is misdetected as a - subroutine call, but stepping over the signal - trampoline isn't such a bad idea. In order to do - that, we have to ignore the value in - step_frame_address, since that doesn't represent the - frame that'll reach when we return from the signal - trampoline. Otherwise we'll probably continue to the - end of the program. */ - step_frame_address = 0; - - step_over_function (ecs); - keep_going (ecs); - return; - } - - /* If we are in a function call trampoline (a stub between - the calling routine and the real function), locate the real - function. That's what tells us (a) whether we want to step - into it at all, and (b) what prologue we want to run to - the end of, if we do step into it. */ - tmp = SKIP_TRAMPOLINE_CODE (stop_pc); - if (tmp != 0) - ecs->stop_func_start = tmp; - else - { - tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc); - if (tmp) - { - struct symtab_and_line xxx; - /* Why isn't this s_a_l called "sr_sal", like all of the - other s_a_l's where this code is duplicated? */ - INIT_SAL (&xxx); /* initialize to zeroes */ - xxx.pc = tmp; - xxx.section = find_pc_overlay (xxx.pc); - check_for_old_step_resume_breakpoint (); - step_resume_breakpoint = - set_momentary_breakpoint (xxx, NULL, bp_step_resume); - insert_breakpoints (); - keep_going (ecs); - return; - } - } - - /* If we have line number information for the function we - are thinking of stepping into, step into it. - - If there are several symtabs at that PC (e.g. with include - files), just want to know whether *any* of them have line - numbers. find_pc_line handles this. */ - { - struct symtab_and_line tmp_sal; - - tmp_sal = find_pc_line (ecs->stop_func_start, 0); - if (tmp_sal.line != 0) - { - step_into_function (ecs); - return; - } - } - - /* If we have no line number and the step-stop-if-no-debug - is set, we stop the step so that the user has a chance to - switch in assembly mode. */ - if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug) - { - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - - step_over_function (ecs); - keep_going (ecs); - return; - - } - - /* We've wandered out of the step range. */ - - ecs->sal = find_pc_line (stop_pc, 0); - - if (step_range_end == 1) - { - /* It is stepi or nexti. We always want to stop stepping after - one instruction. */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - - /* If we're in the return path from a shared library trampoline, - we want to proceed through the trampoline when stepping. */ - if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) - { - CORE_ADDR tmp; - - /* Determine where this trampoline returns. */ - tmp = SKIP_TRAMPOLINE_CODE (stop_pc); - - /* Only proceed through if we know where it's going. */ - if (tmp) - { - /* And put the step-breakpoint there and go until there. */ - struct symtab_and_line sr_sal; - - INIT_SAL (&sr_sal); /* initialize to zeroes */ - sr_sal.pc = tmp; - sr_sal.section = find_pc_overlay (sr_sal.pc); - /* Do not specify what the fp should be when we stop - since on some machines the prologue - is where the new fp value is established. */ - check_for_old_step_resume_breakpoint (); - step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_step_resume); - if (breakpoints_inserted) - insert_breakpoints (); - - /* Restart without fiddling with the step ranges or - other state. */ - keep_going (ecs); - return; - } - } - - if (ecs->sal.line == 0) - { - /* We have no line number information. That means to stop - stepping (does this always happen right after one instruction, - when we do "s" in a function with no line numbers, - or can this happen as a result of a return or longjmp?). */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - - if ((stop_pc == ecs->sal.pc) - && (ecs->current_line != ecs->sal.line || ecs->current_symtab != ecs->sal.symtab)) - { - /* We are at the start of a different line. So stop. Note that - we don't stop if we step into the middle of a different line. - That is said to make things like for (;;) statements work - better. */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - - /* We aren't done stepping. - - Optimize by setting the stepping range to the line. - (We might not be in the original line, but if we entered a - new line in mid-statement, we continue stepping. This makes - things like for(;;) statements work better.) */ - - if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end) - { - /* If this is the last line of the function, don't keep stepping - (it would probably step us out of the function). - This is particularly necessary for a one-line function, - in which after skipping the prologue we better stop even though - we will be in mid-line. */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - step_range_start = ecs->sal.pc; - step_range_end = ecs->sal.end; - step_frame_address = FRAME_FP (get_current_frame ()); - ecs->current_line = ecs->sal.line; - ecs->current_symtab = ecs->sal.symtab; - - /* In the case where we just stepped out of a function into the middle - of a line of the caller, continue stepping, but step_frame_address - must be modified to current frame */ + /* Are we stepping to get the inferior out of the dynamic + linker's hook (and possibly the dld itself) after catching + a shlib event? */ + if (ecs->stepping_through_solib_after_catch) { - CORE_ADDR current_frame = FRAME_FP (get_current_frame ()); - if (!(INNER_THAN (current_frame, step_frame_address))) - step_frame_address = current_frame; +#if defined(SOLIB_ADD) + /* Have we reached our destination? If not, keep going. */ + if (SOLIB_IN_DYNAMIC_LINKER (PIDGET (ecs->ptid), stop_pc)) + { + ecs->another_trap = 1; + keep_going (ecs); + return; + } +#endif + /* Else, stop and report the catchpoint(s) whose triggering + caused us to begin stepping. */ + ecs->stepping_through_solib_after_catch = 0; + bpstat_clear (&stop_bpstat); + stop_bpstat = bpstat_copy (ecs->stepping_through_solib_catchpoints); + bpstat_clear (&ecs->stepping_through_solib_catchpoints); + stop_print_frame = 1; + stop_stepping (ecs); + return; } - keep_going (ecs); + if (step_resume_breakpoint) + { + /* Having a step-resume breakpoint overrides anything + else having to do with stepping commands until + that breakpoint is reached. */ + /* I'm not sure whether this needs to be check_sigtramp2 or + whether it could/should be keep_going. */ + check_sigtramp2 (ecs); + keep_going (ecs); + return; + } - } /* extra brace, to preserve old indentation */ + if (step_range_end == 0) + { + /* Likewise if we aren't even stepping. */ + /* I'm not sure whether this needs to be check_sigtramp2 or + whether it could/should be keep_going. */ + check_sigtramp2 (ecs); + keep_going (ecs); + return; + } + + /* If stepping through a line, keep going if still within it. + + Note that step_range_end is the address of the first instruction + beyond the step range, and NOT the address of the last instruction + within it! */ + if (stop_pc >= step_range_start && stop_pc < step_range_end) + { + /* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal. + So definately need to check for sigtramp here. */ + check_sigtramp2 (ecs); + keep_going (ecs); + return; + } + + /* We stepped out of the stepping range. */ + + /* If we are stepping at the source level and entered the runtime + loader dynamic symbol resolution code, we keep on single stepping + until we exit the run time loader code and reach the callee's + address. */ + if (step_over_calls == STEP_OVER_UNDEBUGGABLE + && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc)) + { + CORE_ADDR pc_after_resolver = + gdbarch_skip_solib_resolver (current_gdbarch, stop_pc); + + if (pc_after_resolver) + { + /* Set up a step-resume breakpoint at the address + indicated by SKIP_SOLIB_RESOLVER. */ + struct symtab_and_line sr_sal; + init_sal (&sr_sal); + sr_sal.pc = pc_after_resolver; + + check_for_old_step_resume_breakpoint (); + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume); + if (breakpoints_inserted) + insert_breakpoints (); + } + + keep_going (ecs); + return; + } + + /* We can't update step_sp every time through the loop, because + reading the stack pointer would slow down stepping too much. + But we can update it every time we leave the step range. */ + ecs->update_step_sp = 1; + + /* Did we just take a signal? */ + if (pc_in_sigtramp (stop_pc) + && !pc_in_sigtramp (prev_pc) + && INNER_THAN (read_sp (), step_sp)) + { + /* We've just taken a signal; go until we are back to + the point where we took it and one more. */ + + /* Note: The test above succeeds not only when we stepped + into a signal handler, but also when we step past the last + statement of a signal handler and end up in the return stub + of the signal handler trampoline. To distinguish between + these two cases, check that the frame is INNER_THAN the + previous one below. pai/1997-09-11 */ + + + { + struct frame_id current_frame = get_frame_id (get_current_frame ()); + + if (frame_id_inner (current_frame, step_frame_id)) + { + /* We have just taken a signal; go until we are back to + the point where we took it and one more. */ + + /* This code is needed at least in the following case: + The user types "next" and then a signal arrives (before + the "next" is done). */ + + /* Note that if we are stopped at a breakpoint, then we need + the step_resume breakpoint to override any breakpoints at + the same location, so that we will still step over the + breakpoint even though the signal happened. */ + struct symtab_and_line sr_sal; + + init_sal (&sr_sal); + sr_sal.symtab = NULL; + sr_sal.line = 0; + sr_sal.pc = prev_pc; + /* We could probably be setting the frame to + step_frame_id; I don't think anyone thought to try it. */ + check_for_old_step_resume_breakpoint (); + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume); + if (breakpoints_inserted) + insert_breakpoints (); + } + else + { + /* We just stepped out of a signal handler and into + its calling trampoline. + + Normally, we'd call step_over_function from + here, but for some reason GDB can't unwind the + stack correctly to find the real PC for the point + user code where the signal trampoline will return + -- FRAME_SAVED_PC fails, at least on HP-UX 10.20. + But signal trampolines are pretty small stubs of + code, anyway, so it's OK instead to just + single-step out. Note: assuming such trampolines + don't exhibit recursion on any platform... */ + find_pc_partial_function (stop_pc, &ecs->stop_func_name, + &ecs->stop_func_start, + &ecs->stop_func_end); + /* Readjust stepping range */ + step_range_start = ecs->stop_func_start; + step_range_end = ecs->stop_func_end; + ecs->stepping_through_sigtramp = 1; + } + } + + + /* If this is stepi or nexti, make sure that the stepping range + gets us past that instruction. */ + if (step_range_end == 1) + /* FIXME: Does this run afoul of the code below which, if + we step into the middle of a line, resets the stepping + range? */ + step_range_end = (step_range_start = prev_pc) + 1; + + ecs->remove_breakpoints_on_following_step = 1; + keep_going (ecs); + return; + } + + if (((stop_pc == ecs->stop_func_start /* Quick test */ + || in_prologue (stop_pc, ecs->stop_func_start)) + && !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) + || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, ecs->stop_func_name) + || ecs->stop_func_name == 0) + { + /* It's a subroutine call. */ + handle_step_into_function (ecs); + return; + } + + /* We've wandered out of the step range. */ + + ecs->sal = find_pc_line (stop_pc, 0); + + if (step_range_end == 1) + { + /* It is stepi or nexti. We always want to stop stepping after + one instruction. */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + /* If we're in the return path from a shared library trampoline, + we want to proceed through the trampoline when stepping. */ + if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) + { + /* Determine where this trampoline returns. */ + CORE_ADDR real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc); + + /* Only proceed through if we know where it's going. */ + if (real_stop_pc) + { + /* And put the step-breakpoint there and go until there. */ + struct symtab_and_line sr_sal; + + init_sal (&sr_sal); /* initialize to zeroes */ + sr_sal.pc = real_stop_pc; + sr_sal.section = find_pc_overlay (sr_sal.pc); + /* Do not specify what the fp should be when we stop + since on some machines the prologue + is where the new fp value is established. */ + check_for_old_step_resume_breakpoint (); + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume); + if (breakpoints_inserted) + insert_breakpoints (); + + /* Restart without fiddling with the step ranges or + other state. */ + keep_going (ecs); + return; + } + } + + if (ecs->sal.line == 0) + { + /* We have no line number information. That means to stop + stepping (does this always happen right after one instruction, + when we do "s" in a function with no line numbers, + or can this happen as a result of a return or longjmp?). */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + if ((stop_pc == ecs->sal.pc) + && (ecs->current_line != ecs->sal.line + || ecs->current_symtab != ecs->sal.symtab)) + { + /* We are at the start of a different line. So stop. Note that + we don't stop if we step into the middle of a different line. + That is said to make things like for (;;) statements work + better. */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + /* We aren't done stepping. + + Optimize by setting the stepping range to the line. + (We might not be in the original line, but if we entered a + new line in mid-statement, we continue stepping. This makes + things like for(;;) statements work better.) */ + + if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end) + { + /* If this is the last line of the function, don't keep stepping + (it would probably step us out of the function). + This is particularly necessary for a one-line function, + in which after skipping the prologue we better stop even though + we will be in mid-line. */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + step_range_start = ecs->sal.pc; + step_range_end = ecs->sal.end; + step_frame_id = get_frame_id (get_current_frame ()); + ecs->current_line = ecs->sal.line; + ecs->current_symtab = ecs->sal.symtab; + + /* In the case where we just stepped out of a function into the + middle of a line of the caller, continue stepping, but + step_frame_id must be modified to current frame */ +#if 0 + /* NOTE: cagney/2003-10-16: I think this frame ID inner test is too + generous. It will trigger on things like a step into a frameless + stackless leaf function. I think the logic should instead look + at the unwound frame ID has that should give a more robust + indication of what happened. */ + if (step-ID == current-ID) + still stepping in same function; + else if (step-ID == unwind (current-ID)) + stepped into a function; + else + stepped out of a function; + /* Of course this assumes that the frame ID unwind code is robust + and we're willing to introduce frame unwind logic into this + function. Fortunately, those days are nearly upon us. */ +#endif + { + struct frame_id current_frame = get_frame_id (get_current_frame ()); + if (!(frame_id_inner (current_frame, step_frame_id))) + step_frame_id = current_frame; + } + + keep_going (ecs); } /* Are we in the middle of stepping? */ @@ -2953,30 +2805,30 @@ static void check_sigtramp2 (struct execution_control_state *ecs) { if (trap_expected - && IN_SIGTRAMP (stop_pc, ecs->stop_func_name) - && !IN_SIGTRAMP (prev_pc, prev_func_name) + && pc_in_sigtramp (stop_pc) + && !pc_in_sigtramp (prev_pc) && INNER_THAN (read_sp (), step_sp)) { /* What has happened here is that we have just stepped the - inferior with a signal (because it is a signal which - shouldn't make us stop), thus stepping into sigtramp. + inferior with a signal (because it is a signal which + shouldn't make us stop), thus stepping into sigtramp. - So we need to set a step_resume_break_address breakpoint and - continue until we hit it, and then step. FIXME: This should - be more enduring than a step_resume breakpoint; we should - know that we will later need to keep going rather than - re-hitting the breakpoint here (see the testsuite, - gdb.base/signals.exp where it says "exceedingly difficult"). */ + So we need to set a step_resume_break_address breakpoint and + continue until we hit it, and then step. FIXME: This should + be more enduring than a step_resume breakpoint; we should + know that we will later need to keep going rather than + re-hitting the breakpoint here (see the testsuite, + gdb.base/signals.exp where it says "exceedingly difficult"). */ struct symtab_and_line sr_sal; - INIT_SAL (&sr_sal); /* initialize to zeroes */ + init_sal (&sr_sal); /* initialize to zeroes */ sr_sal.pc = prev_pc; sr_sal.section = find_pc_overlay (sr_sal.pc); /* We perhaps could set the frame if we kept track of what the - frame corresponding to prev_pc was. But we don't, so don't. */ + frame corresponding to prev_pc was. But we don't, so don't. */ through_sigtramp_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp); + set_momentary_breakpoint (sr_sal, null_frame_id, bp_through_sigtramp); if (breakpoints_inserted) insert_breakpoints (); @@ -3005,36 +2857,54 @@ step_into_function (struct execution_control_state *ecs) /* If the prologue ends in the middle of a source line, continue to the end of that source line (if it is still within the function). Otherwise, just go to end of prologue. */ -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* no, don't either. It skips any code that's legitimately on the - first line. */ -#else if (ecs->sal.end && ecs->sal.pc != ecs->stop_func_start && ecs->sal.end < ecs->stop_func_end) ecs->stop_func_start = ecs->sal.end; -#endif + + /* Architectures which require breakpoint adjustment might not be able + to place a breakpoint at the computed address. If so, the test + ``ecs->stop_func_start == stop_pc'' will never succeed. Adjust + ecs->stop_func_start to an address at which a breakpoint may be + legitimately placed. + + Note: kevinb/2004-01-19: On FR-V, if this adjustment is not + made, GDB will enter an infinite loop when stepping through + optimized code consisting of VLIW instructions which contain + subinstructions corresponding to different source lines. On + FR-V, it's not permitted to place a breakpoint on any but the + first subinstruction of a VLIW instruction. When a breakpoint is + set, GDB will adjust the breakpoint address to the beginning of + the VLIW instruction. Thus, we need to make the corresponding + adjustment here when computing the stop address. */ + + if (gdbarch_adjust_breakpoint_address_p (current_gdbarch)) + { + ecs->stop_func_start + = gdbarch_adjust_breakpoint_address (current_gdbarch, + ecs->stop_func_start); + } if (ecs->stop_func_start == stop_pc) { /* We are already there: stop now. */ stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); + print_stop_reason (END_STEPPING_RANGE, 0); stop_stepping (ecs); return; } else { /* Put the step-breakpoint there and go until there. */ - INIT_SAL (&sr_sal); /* initialize to zeroes */ + init_sal (&sr_sal); /* initialize to zeroes */ sr_sal.pc = ecs->stop_func_start; sr_sal.section = find_pc_overlay (ecs->stop_func_start); /* Do not specify what the fp should be when we stop since on - some machines the prologue is where the new fp value is - established. */ + some machines the prologue is where the new fp value is + established. */ check_for_old_step_resume_breakpoint (); step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_step_resume); + set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume); if (breakpoints_inserted) insert_breakpoints (); @@ -3053,7 +2923,7 @@ step_into_function (struct execution_control_state *ecs) of the call. To do this, we set the step_resume bp's frame to our current - caller's frame (step_frame_address, which is set by the "next" or + caller's frame (step_frame_id, which is set by the "next" or "until" command, before execution begins). */ static void @@ -3061,16 +2931,55 @@ step_over_function (struct execution_control_state *ecs) { struct symtab_and_line sr_sal; - INIT_SAL (&sr_sal); /* initialize to zeros */ - sr_sal.pc = ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ())); + init_sal (&sr_sal); /* initialize to zeros */ + + /* NOTE: cagney/2003-04-06: + + At this point the equality get_frame_pc() == get_frame_func() + should hold. This may make it possible for this code to tell the + frame where it's function is, instead of the reverse. This would + avoid the need to search for the frame's function, which can get + very messy when there is no debug info available (look at the + heuristic find pc start code found in targets like the MIPS). */ + + /* NOTE: cagney/2003-04-06: + + The intent of DEPRECATED_SAVED_PC_AFTER_CALL was to: + + - provide a very light weight equivalent to frame_unwind_pc() + (nee FRAME_SAVED_PC) that avoids the prologue analyzer + + - avoid handling the case where the PC hasn't been saved in the + prologue analyzer + + Unfortunately, not five lines further down, is a call to + get_frame_id() and that is guarenteed to trigger the prologue + analyzer. + + The `correct fix' is for the prologe analyzer to handle the case + where the prologue is incomplete (PC in prologue) and, + consequently, the return pc has not yet been saved. It should be + noted that the prologue analyzer needs to handle this case + anyway: frameless leaf functions that don't save the return PC; + single stepping through a prologue. + + The d10v handles all this by bailing out of the prologue analsis + when it reaches the current instruction. */ + + if (DEPRECATED_SAVED_PC_AFTER_CALL_P ()) + sr_sal.pc = ADDR_BITS_REMOVE (DEPRECATED_SAVED_PC_AFTER_CALL (get_current_frame ())); + else + sr_sal.pc = ADDR_BITS_REMOVE (frame_pc_unwind (get_current_frame ())); sr_sal.section = find_pc_overlay (sr_sal.pc); check_for_old_step_resume_breakpoint (); step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, get_current_frame (), bp_step_resume); + set_momentary_breakpoint (sr_sal, get_frame_id (get_current_frame ()), + bp_step_resume); - if (step_frame_address && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc)) - step_resume_breakpoint->frame = step_frame_address; + if (frame_id_p (step_frame_id) + && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc)) + step_resume_breakpoint->frame_id = step_frame_id; if (breakpoints_inserted) insert_breakpoints (); @@ -3079,40 +2988,6 @@ step_over_function (struct execution_control_state *ecs) static void stop_stepping (struct execution_control_state *ecs) { - if (target_has_execution) - { - /* Are we stopping for a vfork event? We only stop when we see - the child's event. However, we may not yet have seen the - parent's event. And, inferior_ptid is still set to the - parent's pid, until we resume again and follow either the - parent or child. - - To ensure that we can really touch inferior_ptid (aka, the - parent process) -- which calls to functions like read_pc - implicitly do -- wait on the parent if necessary. */ - if ((pending_follow.kind == TARGET_WAITKIND_VFORKED) - && !pending_follow.fork_event.saw_parent_fork) - { - ptid_t parent_ptid; - - do - { - if (target_wait_hook) - parent_ptid = target_wait_hook (pid_to_ptid (-1), &(ecs->ws)); - else - parent_ptid = target_wait (pid_to_ptid (-1), &(ecs->ws)); - } - while (! ptid_equal (parent_ptid, inferior_ptid)); - } - - /* Assuming the inferior still exists, set these up for next - time, just like we did above if we didn't break out of the - loop. */ - prev_pc = read_pc (); - prev_func_start = ecs->stop_func_start; - prev_func_name = ecs->stop_func_name; - } - /* Let callers know we don't want to wait for the inferior anymore. */ ecs->wait_some_more = 0; } @@ -3124,24 +2999,8 @@ stop_stepping (struct execution_control_state *ecs) static void keep_going (struct execution_control_state *ecs) { - /* ??rehrauer: ttrace on HP-UX theoretically allows one to debug a - vforked child between its creation and subsequent exit or call to - exec(). However, I had big problems in this rather creaky exec - engine, getting that to work. The fundamental problem is that - I'm trying to debug two processes via an engine that only - understands a single process with possibly multiple threads. - - Hence, this spot is known to have problems when - target_can_follow_vfork_prior_to_exec returns 1. */ - /* Save the pc before execution, to compare with pc after stop. */ - prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */ - prev_func_start = ecs->stop_func_start; /* Ok, since if DECR_PC_AFTER - BREAK is defined, the - original pc would not have - been at the start of a - function. */ - prev_func_name = ecs->stop_func_name; + prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */ if (ecs->update_step_sp) step_sp = read_sp (); @@ -3153,25 +3012,25 @@ keep_going (struct execution_control_state *ecs) if (trap_expected && stop_signal != TARGET_SIGNAL_TRAP) { /* We took a signal (which we are supposed to pass through to - the inferior, else we'd have done a break above) and we - haven't yet gotten our trap. Simply continue. */ + the inferior, else we'd have done a break above) and we + haven't yet gotten our trap. Simply continue. */ resume (currently_stepping (ecs), stop_signal); } else { /* Either the trap was not expected, but we are continuing - anyway (the user asked that this signal be passed to the - child) - -- or -- - The signal was SIGTRAP, e.g. it was our signal, but we - decided we should resume from it. + anyway (the user asked that this signal be passed to the + child) + -- or -- + The signal was SIGTRAP, e.g. it was our signal, but we + decided we should resume from it. - We're going to run this baby now! + We're going to run this baby now! - Insert breakpoints now, unless we are trying to one-proceed - past a breakpoint. */ + Insert breakpoints now, unless we are trying to one-proceed + past a breakpoint. */ /* If we've just finished a special step resume and we don't - want to hit a breakpoint, pull em out. */ + want to hit a breakpoint, pull em out. */ if (step_resume_breakpoint == NULL && through_sigtramp_breakpoint == NULL && ecs->remove_breakpoints_on_following_step) @@ -3195,38 +3054,25 @@ keep_going (struct execution_control_state *ecs) trap_expected = ecs->another_trap; /* Do not deliver SIGNAL_TRAP (except when the user explicitly - specifies that such a signal should be delivered to the - target program). + specifies that such a signal should be delivered to the + target program). - Typically, this would occure when a user is debugging a - target monitor on a simulator: the target monitor sets a - breakpoint; the simulator encounters this break-point and - halts the simulation handing control to GDB; GDB, noteing - that the break-point isn't valid, returns control back to the - simulator; the simulator then delivers the hardware - equivalent of a SIGNAL_TRAP to the program being debugged. */ + Typically, this would occure when a user is debugging a + target monitor on a simulator: the target monitor sets a + breakpoint; the simulator encounters this break-point and + halts the simulation handing control to GDB; GDB, noteing + that the break-point isn't valid, returns control back to the + simulator; the simulator then delivers the hardware + equivalent of a SIGNAL_TRAP to the program being debugged. */ - if (stop_signal == TARGET_SIGNAL_TRAP - && !signal_program[stop_signal]) + if (stop_signal == TARGET_SIGNAL_TRAP && !signal_program[stop_signal]) stop_signal = TARGET_SIGNAL_0; -#ifdef SHIFT_INST_REGS - /* I'm not sure when this following segment applies. I do know, - now, that we shouldn't rewrite the regs when we were stopped - by a random signal from the inferior process. */ - /* FIXME: Shouldn't this be based on the valid bit of the SXIP? - (this is only used on the 88k). */ - - if (!bpstat_explains_signal (stop_bpstat) - && (stop_signal != TARGET_SIGNAL_CHLD) - && !stopped_by_random_signal) - SHIFT_INST_REGS (); -#endif /* SHIFT_INST_REGS */ resume (currently_stepping (ecs), stop_signal); } - prepare_to_wait (ecs); + prepare_to_wait (ecs); } /* This function normally comes after a resume, before @@ -3241,10 +3087,10 @@ prepare_to_wait (struct execution_control_state *ecs) overlay_cache_invalid = 1; /* We have to invalidate the registers BEFORE calling - target_wait because they can be loaded from the target while - in target_wait. This makes remote debugging a bit more - efficient for those targets that provide critical registers - as part of their normal status mechanism. */ + target_wait because they can be loaded from the target while + in target_wait. This makes remote debugging a bit more + efficient for those targets that provide critical registers + as part of their normal status mechanism. */ registers_changed (); ecs->waiton_ptid = pid_to_ptid (-1); @@ -3274,7 +3120,7 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info) /* We are done with a step/next/si/ni command. */ /* For now print nothing. */ /* Print a message only if not in the middle of doing a "step n" - operation for n > 1 */ + operation for n > 1 */ if (!step_multi || !stop_step) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "end-stepping-range"); @@ -3290,11 +3136,13 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info) ui_out_field_string (uiout, "reason", "exited-signalled"); ui_out_text (uiout, "\nProgram terminated with signal "); annotate_signal_name (); - ui_out_field_string (uiout, "signal-name", target_signal_to_name (stop_info)); + ui_out_field_string (uiout, "signal-name", + target_signal_to_name (stop_info)); annotate_signal_name_end (); ui_out_text (uiout, ", "); annotate_signal_string (); - ui_out_field_string (uiout, "signal-meaning", target_signal_to_string (stop_info)); + ui_out_field_string (uiout, "signal-meaning", + target_signal_to_string (stop_info)); annotate_signal_string_end (); ui_out_text (uiout, ".\n"); ui_out_text (uiout, "The program no longer exists.\n"); @@ -3307,7 +3155,8 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "exited"); ui_out_text (uiout, "\nProgram exited with code "); - ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) stop_info); + ui_out_field_fmt (uiout, "exit-code", "0%o", + (unsigned int) stop_info); ui_out_text (uiout, ".\n"); } else @@ -3325,11 +3174,13 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info) annotate_signal_name (); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "signal-received"); - ui_out_field_string (uiout, "signal-name", target_signal_to_name (stop_info)); + ui_out_field_string (uiout, "signal-name", + target_signal_to_name (stop_info)); annotate_signal_name_end (); ui_out_text (uiout, ", "); annotate_signal_string (); - ui_out_field_string (uiout, "signal-meaning", target_signal_to_string (stop_info)); + ui_out_field_string (uiout, "signal-meaning", + target_signal_to_string (stop_info)); annotate_signal_string_end (); ui_out_text (uiout, ".\n"); break; @@ -3352,14 +3203,22 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info) void normal_stop (void) { + struct target_waitstatus last; + ptid_t last_ptid; + + get_last_target_status (&last_ptid, &last); + /* As with the notification of thread events, we want to delay notifying the user that we've switched thread context until the inferior actually stops. - (Note that there's no point in saying anything if the inferior - has exited!) */ - if (! ptid_equal (previous_inferior_ptid, inferior_ptid) - && target_has_execution) + There's no point in saying anything if the inferior has exited. + Note that SIGNALLED here means "exited with a signal", not + "received a signal". */ + if (!ptid_equal (previous_inferior_ptid, inferior_ptid) + && target_has_execution + && last.kind != TARGET_WAITKIND_SIGNALLED + && last.kind != TARGET_WAITKIND_EXITED) { target_terminal_ours_for_output (); printf_filtered ("[Switching to %s]\n", @@ -3367,21 +3226,16 @@ normal_stop (void) previous_inferior_ptid = inferior_ptid; } + /* NOTE drow/2004-01-17: Is this still necessary? */ /* Make sure that the current_frame's pc is correct. This is a correction for setting up the frame info before doing DECR_PC_AFTER_BREAK */ - if (target_has_execution && get_current_frame ()) - (get_current_frame ())->pc = read_pc (); - - if (breakpoints_failed) - { - target_terminal_ours_for_output (); - print_sys_errmsg ("While inserting breakpoints", breakpoints_failed); - printf_filtered ("Stopped; cannot insert breakpoints.\n\ -The same program may be running in another process,\n\ -or you may have requested too many hardware breakpoints\n\ -and/or watchpoints.\n"); - } + if (target_has_execution) + /* FIXME: cagney/2002-12-06: Has the PC changed? Thanks to + DECR_PC_AFTER_BREAK, the program counter can change. Ask the + frame code to check for this and sort out any resultant mess. + DECR_PC_AFTER_BREAK needs to just go away. */ + deprecated_update_frame_pc_hack (get_current_frame (), read_pc ()); if (target_has_execution && breakpoints_inserted) { @@ -3414,13 +3268,11 @@ and/or watchpoints.\n"); target_terminal_ours (); - /* Look up the hook_stop and run it if it exists. */ - - if (stop_command && stop_command->hook_pre) - { - catch_errors (hook_stop_stub, stop_command->hook_pre, - "Error while running hook_stop:\n", RETURN_MASK_ALL); - } + /* Look up the hook_stop and run it (CLI internally handles problem + of stop_command's pre-hook not existing). */ + if (stop_command) + catch_errors (hook_stop_stub, stop_command, + "Error while running hook_stop:\n", RETURN_MASK_ALL); if (!target_has_stack) { @@ -3435,7 +3287,7 @@ and/or watchpoints.\n"); if (!stop_stack_dummy) { - select_frame (get_current_frame (), 0); + select_frame (get_current_frame ()); /* Print current location without a level number, if we have changed functions or hit a breakpoint. @@ -3443,8 +3295,7 @@ and/or watchpoints.\n"); bpstat_print() contains the logic deciding in detail what to print, based on the event(s) that just occurred. */ - if (stop_print_frame - && selected_frame) + if (stop_print_frame && deprecated_selected_frame) { int bpstat_ret; int source_flag; @@ -3454,42 +3305,45 @@ and/or watchpoints.\n"); switch (bpstat_ret) { case PRINT_UNKNOWN: + /* FIXME: cagney/2002-12-01: Given that a frame ID does + (or should) carry around the function and does (or + should) use that when doing a frame comparison. */ if (stop_step - && step_frame_address == FRAME_FP (get_current_frame ()) + && frame_id_eq (step_frame_id, + get_frame_id (get_current_frame ())) && step_start_function == find_pc_function (stop_pc)) - source_flag = SRC_LINE; /* finished step, just print source line */ + source_flag = SRC_LINE; /* finished step, just print source line */ else - source_flag = SRC_AND_LOC; /* print location and source line */ + source_flag = SRC_AND_LOC; /* print location and source line */ break; case PRINT_SRC_AND_LOC: - source_flag = SRC_AND_LOC; /* print location and source line */ + source_flag = SRC_AND_LOC; /* print location and source line */ break; case PRINT_SRC_ONLY: source_flag = SRC_LINE; break; case PRINT_NOTHING: - source_flag = SRC_LINE; /* something bogus */ + source_flag = SRC_LINE; /* something bogus */ do_frame_printing = 0; break; default: - internal_error (__FILE__, __LINE__, - "Unknown value."); + internal_error (__FILE__, __LINE__, "Unknown value."); } /* For mi, have the same behavior every time we stop: - print everything but the source line. */ + print everything but the source line. */ if (ui_out_is_mi_like_p (uiout)) source_flag = LOC_AND_ADDRESS; if (ui_out_is_mi_like_p (uiout)) ui_out_field_int (uiout, "thread-id", - pid_to_thread_id (inferior_ptid)); + pid_to_thread_id (inferior_ptid)); /* The behavior of this routine with respect to the source flag is: SRC_LINE: Print only source line LOCATION: Print only location SRC_AND_LOC: Print location and source line */ if (do_frame_printing) - show_and_print_stack_frame (selected_frame, -1, source_flag); + print_stack_frame (deprecated_selected_frame, -1, source_flag); /* Display the auto-display expressions. */ do_displays (); @@ -3499,29 +3353,32 @@ and/or watchpoints.\n"); /* Save the function value return registers, if we care. We might be about to restore their previous contents. */ if (proceed_to_finish) - read_register_bytes (0, stop_registers, REGISTER_BYTES); + /* NB: The copy goes through to the target picking up the value of + all the registers. */ + regcache_cpy (stop_registers, current_regcache); if (stop_stack_dummy) { - /* Pop the empty frame that contains the stack dummy. - POP_FRAME ends with a setting of the current frame, so we - can use that next. */ - POP_FRAME; + /* Pop the empty frame that contains the stack dummy. POP_FRAME + ends with a setting of the current frame, so we can use that + next. */ + frame_pop (get_current_frame ()); /* Set stop_pc to what it was before we called the function. Can't rely on restore_inferior_status because that only gets called if we don't stop in the called function. */ stop_pc = read_pc (); - select_frame (get_current_frame (), 0); + select_frame (get_current_frame ()); } done: annotate_stopped (); + observer_notify_normal_stop (); } static int hook_stop_stub (void *cmd) { - execute_user_command ((struct cmd_list_element *) cmd, 0); + execute_cmd_pre_hook ((struct cmd_list_element *) cmd); return (0); } @@ -3543,27 +3400,24 @@ signal_pass_state (int signo) return signal_program[signo]; } -int signal_stop_update (signo, state) - int signo; - int state; +int +signal_stop_update (int signo, int state) { int ret = signal_stop[signo]; signal_stop[signo] = state; return ret; } -int signal_print_update (signo, state) - int signo; - int state; +int +signal_print_update (int signo, int state) { int ret = signal_print[signo]; signal_print[signo] = state; return ret; } -int signal_pass_update (signo, state) - int signo; - int state; +int +signal_pass_update (int signo, int state) { int ret = signal_program[signo]; signal_program[signo] = state; @@ -3587,8 +3441,7 @@ sig_print_info (enum target_signal oursig) name_padding = 0; printf_filtered ("%s", name); - printf_filtered ("%*.*s ", name_padding, name_padding, - " "); + printf_filtered ("%*.*s ", name_padding, name_padding, " "); printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No"); printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No"); printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No"); @@ -3734,9 +3587,7 @@ handle_command (char *args, int from_tty) if (!allsigs && !sigs[signum]) { if (query ("%s is used by the debugger.\n\ -Are you sure you want to change it? ", - target_signal_to_name - ((enum target_signal) signum))) +Are you sure you want to change it? ", target_signal_to_name ((enum target_signal) signum))) { sigs[signum] = 1; } @@ -3880,8 +3731,7 @@ signals_info (char *signum_exp, int from_tty) QUIT; if (oursig != TARGET_SIGNAL_UNKNOWN - && oursig != TARGET_SIGNAL_DEFAULT - && oursig != TARGET_SIGNAL_0) + && oursig != TARGET_SIGNAL_DEFAULT && oursig != TARGET_SIGNAL_0) sig_print_info (oursig); } @@ -3899,51 +3749,34 @@ struct inferior_status int trap_expected; CORE_ADDR step_range_start; CORE_ADDR step_range_end; - CORE_ADDR step_frame_address; + struct frame_id step_frame_id; enum step_over_calls_kind step_over_calls; CORE_ADDR step_resume_break_address; int stop_after_trap; - int stop_soon_quietly; - CORE_ADDR selected_frame_address; - char *stop_registers; + int stop_soon; + struct regcache *stop_registers; /* These are here because if call_function_by_hand has written some registers and then decides to call error(), we better not have changed any registers. */ - char *registers; + struct regcache *registers; + + /* A frame unique identifier. */ + struct frame_id selected_frame_id; - int selected_level; int breakpoint_proceeded; int restore_stack_info; int proceed_to_finish; }; -static struct inferior_status * -xmalloc_inferior_status (void) -{ - struct inferior_status *inf_status; - inf_status = xmalloc (sizeof (struct inferior_status)); - inf_status->stop_registers = xmalloc (REGISTER_BYTES); - inf_status->registers = xmalloc (REGISTER_BYTES); - return inf_status; -} - -static void -free_inferior_status (struct inferior_status *inf_status) -{ - xfree (inf_status->registers); - xfree (inf_status->stop_registers); - xfree (inf_status); -} - void write_inferior_status_register (struct inferior_status *inf_status, int regno, LONGEST val) { - int size = REGISTER_RAW_SIZE (regno); + int size = DEPRECATED_REGISTER_RAW_SIZE (regno); void *buf = alloca (size); store_signed_integer (buf, size, val); - memcpy (&inf_status->registers[REGISTER_BYTE (regno)], buf, size); + regcache_raw_write (inf_status->registers, regno, buf); } /* Save all of the information associated with the inferior<==>gdb @@ -3953,7 +3786,7 @@ write_inferior_status_register (struct inferior_status *inf_status, int regno, struct inferior_status * save_inferior_status (int restore_stack_info) { - struct inferior_status *inf_status = xmalloc_inferior_status (); + struct inferior_status *inf_status = XMALLOC (struct inferior_status); inf_status->stop_signal = stop_signal; inf_status->stop_pc = stop_pc; @@ -3963,10 +3796,10 @@ save_inferior_status (int restore_stack_info) inf_status->trap_expected = trap_expected; inf_status->step_range_start = step_range_start; inf_status->step_range_end = step_range_end; - inf_status->step_frame_address = step_frame_address; + inf_status->step_frame_id = step_frame_id; inf_status->step_over_calls = step_over_calls; inf_status->stop_after_trap = stop_after_trap; - inf_status->stop_soon_quietly = stop_soon_quietly; + inf_status->stop_soon = stop_soon; /* Save original bpstat chain here; replace it with copy of chain. If caller's caller is walking the chain, they'll be happier if we hand them back the original chain when restore_inferior_status is @@ -3977,48 +3810,31 @@ save_inferior_status (int restore_stack_info) inf_status->restore_stack_info = restore_stack_info; inf_status->proceed_to_finish = proceed_to_finish; - memcpy (inf_status->stop_registers, stop_registers, REGISTER_BYTES); + inf_status->stop_registers = regcache_dup_no_passthrough (stop_registers); - read_register_bytes (0, inf_status->registers, REGISTER_BYTES); + inf_status->registers = regcache_dup (current_regcache); - record_selected_frame (&(inf_status->selected_frame_address), - &(inf_status->selected_level)); + inf_status->selected_frame_id = get_frame_id (deprecated_selected_frame); return inf_status; } -struct restore_selected_frame_args -{ - CORE_ADDR frame_address; - int level; -}; - static int restore_selected_frame (void *args) { - struct restore_selected_frame_args *fr = - (struct restore_selected_frame_args *) args; + struct frame_id *fid = (struct frame_id *) args; struct frame_info *frame; - int level = fr->level; - frame = find_relative_frame (get_current_frame (), &level); + frame = frame_find_by_id (*fid); - /* If inf_status->selected_frame_address is NULL, there was no - previously selected frame. */ - if (frame == NULL || - /* FRAME_FP (frame) != fr->frame_address || */ - /* elz: deleted this check as a quick fix to the problem that - for function called by hand gdb creates no internal frame - structure and the real stack and gdb's idea of stack are - different if nested calls by hands are made. - - mvs: this worries me. */ - level != 0) + /* If inf_status->selected_frame_id is NULL, there was no previously + selected frame. */ + if (frame == NULL) { warning ("Unable to restore previously selected frame.\n"); return 0; } - select_frame (frame, fr->level); + select_frame (frame); return (1); } @@ -4034,22 +3850,25 @@ restore_inferior_status (struct inferior_status *inf_status) trap_expected = inf_status->trap_expected; step_range_start = inf_status->step_range_start; step_range_end = inf_status->step_range_end; - step_frame_address = inf_status->step_frame_address; + step_frame_id = inf_status->step_frame_id; step_over_calls = inf_status->step_over_calls; stop_after_trap = inf_status->stop_after_trap; - stop_soon_quietly = inf_status->stop_soon_quietly; + stop_soon = inf_status->stop_soon; bpstat_clear (&stop_bpstat); stop_bpstat = inf_status->stop_bpstat; breakpoint_proceeded = inf_status->breakpoint_proceeded; proceed_to_finish = inf_status->proceed_to_finish; - /* FIXME: Is the restore of stop_registers always needed */ - memcpy (stop_registers, inf_status->stop_registers, REGISTER_BYTES); + /* FIXME: Is the restore of stop_registers always needed. */ + regcache_xfree (stop_registers); + stop_registers = inf_status->stop_registers; /* The inferior can be gone if the user types "print exit(0)" (and perhaps other times). */ if (target_has_execution) - write_register_bytes (0, inf_status->registers, REGISTER_BYTES); + /* NB: The register write goes through to the target. */ + regcache_cpy (current_regcache, inf_status->registers); + regcache_xfree (inf_status->registers); /* FIXME: If we are being called after stopping in a function which is called from gdb, we should not be trying to restore the @@ -4060,24 +3879,20 @@ restore_inferior_status (struct inferior_status *inf_status) if (target_has_stack && inf_status->restore_stack_info) { - struct restore_selected_frame_args fr; - fr.level = inf_status->selected_level; - fr.frame_address = inf_status->selected_frame_address; /* The point of catch_errors is that if the stack is clobbered, - walking the stack might encounter a garbage pointer and error() - trying to dereference it. */ - if (catch_errors (restore_selected_frame, &fr, - "Unable to restore previously selected frame:\n", - RETURN_MASK_ERROR) == 0) + walking the stack might encounter a garbage pointer and + error() trying to dereference it. */ + if (catch_errors + (restore_selected_frame, &inf_status->selected_frame_id, + "Unable to restore previously selected frame:\n", + RETURN_MASK_ERROR) == 0) /* Error in restoring the selected frame. Select the innermost frame. */ - - - select_frame (get_current_frame (), 0); + select_frame (get_current_frame ()); } - free_inferior_status (inf_status); + xfree (inf_status); } static void @@ -4097,7 +3912,63 @@ discard_inferior_status (struct inferior_status *inf_status) { /* See save_inferior_status for info on stop_bpstat. */ bpstat_clear (&inf_status->stop_bpstat); - free_inferior_status (inf_status); + regcache_xfree (inf_status->registers); + regcache_xfree (inf_status->stop_registers); + xfree (inf_status); +} + +int +inferior_has_forked (int pid, int *child_pid) +{ + struct target_waitstatus last; + ptid_t last_ptid; + + get_last_target_status (&last_ptid, &last); + + if (last.kind != TARGET_WAITKIND_FORKED) + return 0; + + if (ptid_get_pid (last_ptid) != pid) + return 0; + + *child_pid = last.value.related_pid; + return 1; +} + +int +inferior_has_vforked (int pid, int *child_pid) +{ + struct target_waitstatus last; + ptid_t last_ptid; + + get_last_target_status (&last_ptid, &last); + + if (last.kind != TARGET_WAITKIND_VFORKED) + return 0; + + if (ptid_get_pid (last_ptid) != pid) + return 0; + + *child_pid = last.value.related_pid; + return 1; +} + +int +inferior_has_execd (int pid, char **execd_pathname) +{ + struct target_waitstatus last; + ptid_t last_ptid; + + get_last_target_status (&last_ptid, &last); + + if (last.kind != TARGET_WAITKIND_EXECD) + return 0; + + if (ptid_get_pid (last_ptid) != pid) + return 0; + + *execd_pathname = xstrdup (last.value.execd_pathname); + return 1; } /* Oft used ptids */ @@ -4105,7 +3976,7 @@ ptid_t null_ptid; ptid_t minus_one_ptid; /* Create a ptid given the necessary PID, LWP, and TID components. */ - + ptid_t ptid_build (int pid, long lwp, long tid) { @@ -4155,7 +4026,7 @@ int ptid_equal (ptid_t ptid1, ptid_t ptid2) { return (ptid1.pid == ptid2.pid && ptid1.lwp == ptid2.lwp - && ptid1.tid == ptid2.tid); + && ptid1.tid == ptid2.tid); } /* restore_inferior_ptid() will be used by the cleanup machinery @@ -4183,25 +4054,23 @@ save_inferior_ptid (void) *saved_ptid_ptr = inferior_ptid; return make_cleanup (restore_inferior_ptid, saved_ptid_ptr); } - + static void build_infrun (void) { - stop_registers = xmalloc (REGISTER_BYTES); + stop_registers = regcache_xmalloc (current_gdbarch); } void _initialize_infrun (void) { - register int i; - register int numsigs; + int i; + int numsigs; struct cmd_list_element *c; - build_infrun (); - - register_gdbarch_swap (&stop_registers, sizeof (stop_registers), NULL); - register_gdbarch_swap (NULL, 0, build_infrun); + DEPRECATED_REGISTER_GDBARCH_SWAP (stop_registers); + deprecated_register_gdbarch_swap (NULL, 0, build_infrun); add_info ("signals", signals_info, "What debugger does when program gets various signals.\n\ @@ -4215,8 +4084,7 @@ Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\ from 1-15 are allowed for compatibility with old versions of GDB.\n\ Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\ The special arg \"all\" is recognized to mean all signals except those\n\ -used by the debugger, typically SIGTRAP and SIGINT.\n", - "Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\ +used by the debugger, typically SIGTRAP and SIGINT.\n", "Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\ \"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\ Stop means reenter debugger if this signal happens (implies print).\n\ Print means print a message if this signal happens.\n\ @@ -4235,8 +4103,7 @@ Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\ from 1-15 are allowed for compatibility with old versions of GDB.\n\ Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\ The special arg \"all\" is recognized to mean all signals except those\n\ -used by the debugger, typically SIGTRAP and SIGINT.\n", - "Recognized actions include \"s\" (toggles between stop and nostop), \n\ +used by the debugger, typically SIGTRAP and SIGINT.\n", "Recognized actions include \"s\" (toggles between stop and nostop), \n\ \"r\" (toggles between print and noprint), \"i\" (toggles between pass and \ nopass), \"Q\" (noprint)\n\ Stop means reenter debugger if this signal happens (implies print).\n\ @@ -4247,14 +4114,13 @@ Pass and Stop may be combined.", NULL)); } if (!dbx_commands) - stop_command = add_cmd ("stop", class_obscure, not_just_help_class_command, - "There is no `stop' command, but you can set a hook on `stop'.\n\ + stop_command = + add_cmd ("stop", class_obscure, not_just_help_class_command, "There is no `stop' command, but you can set a hook on `stop'.\n\ This allows you to set a list of commands to be run each time execution\n\ of the program stops.", &cmdlist); numsigs = (int) TARGET_SIGNAL_LAST; - signal_stop = (unsigned char *) - xmalloc (sizeof (signal_stop[0]) * numsigs); + signal_stop = (unsigned char *) xmalloc (sizeof (signal_stop[0]) * numsigs); signal_print = (unsigned char *) xmalloc (sizeof (signal_print[0]) * numsigs); signal_program = (unsigned char *) @@ -4307,65 +4173,39 @@ of the program stops.", &cmdlist); "Set stopping for shared library events.\n\ If nonzero, gdb will give control to the user when the dynamic linker\n\ notifies gdb of shared library events. The most common event of interest\n\ -to the user would be loading/unloading of a new library.\n", - &setlist), - &showlist); +to the user would be loading/unloading of a new library.\n", &setlist), &showlist); #endif c = add_set_enum_cmd ("follow-fork-mode", class_run, - follow_fork_mode_kind_names, - &follow_fork_mode_string, -/* ??rehrauer: The "both" option is broken, by what may be a 10.20 - kernel problem. It's also not terribly useful without a GUI to - help the user drive two debuggers. So for now, I'm disabling - the "both" option. */ -/* "Set debugger response to a program call of fork \ - or vfork.\n\ - A fork or vfork creates a new process. follow-fork-mode can be:\n\ - parent - the original process is debugged after a fork\n\ - child - the new process is debugged after a fork\n\ - both - both the parent and child are debugged after a fork\n\ - ask - the debugger will ask for one of the above choices\n\ - For \"both\", another copy of the debugger will be started to follow\n\ - the new child process. The original debugger will continue to follow\n\ - the original parent process. To distinguish their prompts, the\n\ - debugger copy's prompt will be changed.\n\ - For \"parent\" or \"child\", the unfollowed process will run free.\n\ - By default, the debugger will follow the parent process.", - */ + follow_fork_mode_kind_names, &follow_fork_mode_string, "Set debugger response to a program call of fork \ or vfork.\n\ A fork or vfork creates a new process. follow-fork-mode can be:\n\ parent - the original process is debugged after a fork\n\ child - the new process is debugged after a fork\n\ - ask - the debugger will ask for one of the above choices\n\ -For \"parent\" or \"child\", the unfollowed process will run free.\n\ -By default, the debugger will follow the parent process.", - &setlist); +The unfollowed process will continue to run.\n\ +By default, the debugger will follow the parent process.", &setlist); add_show_from_set (c, &showlist); - c = add_set_enum_cmd ("scheduler-locking", class_run, - scheduler_enums, /* array of string names */ + c = add_set_enum_cmd ("scheduler-locking", class_run, scheduler_enums, /* array of string names */ &scheduler_mode, /* current mode */ "Set mode for locking scheduler during execution.\n\ off == no locking (threads may preempt at any time)\n\ on == full locking (no thread except the current thread may run)\n\ step == scheduler locked during every single-step operation.\n\ In this mode, no other thread may run during a step command.\n\ - Other threads may run while stepping over a function call ('next').", - &setlist); + Other threads may run while stepping over a function call ('next').", &setlist); set_cmd_sfunc (c, set_schedlock_func); /* traps on target vector */ add_show_from_set (c, &showlist); c = add_set_cmd ("step-mode", class_run, - var_boolean, (char*) &step_stop_if_no_debug, -"Set mode of the step operation. When set, doing a step over a\n\ + var_boolean, (char *) &step_stop_if_no_debug, + "Set mode of the step operation. When set, doing a step over a\n\ function without debug line information will stop at the first\n\ instruction of that function. Otherwise, the function is skipped and\n\ -the step command stops at a different source line.", - &setlist); +the step command stops at a different source line.", &setlist); add_show_from_set (c, &showlist); /* ptid initializations */ diff --git a/contrib/gdb/gdb/inftarg.c b/contrib/gdb/gdb/inftarg.c index 9035310c494..a6f40ec12c2 100644 --- a/contrib/gdb/gdb/inftarg.c +++ b/contrib/gdb/gdb/inftarg.c @@ -1,7 +1,8 @@ /* Target-vector operations for controlling Unix child processes, for GDB. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, - 2000, 2002 - Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, + 2000, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Support. ## Contains temporary hacks.. @@ -35,6 +36,7 @@ #include #include "gdb_wait.h" +#include "inflow.h" extern struct symtab_and_line *child_enable_exception_callback (enum exception_event_kind, @@ -61,20 +63,12 @@ static void child_files_info (struct target_ops *); static void child_detach (char *, int); -static void child_detach_from_process (int, char *, int, int); - static void child_attach (char *, int); -static void child_attach_to_process (char *, int, int); - #if !defined(CHILD_POST_ATTACH) extern void child_post_attach (int); #endif -static void child_require_attach (char *, int); - -static void child_require_detach (int, char *, int); - static void ptrace_me (void); static void ptrace_him (int); @@ -104,16 +98,6 @@ int child_suppress_run = 0; /* Non-zero if inftarg should pretend not to #ifndef CHILD_WAIT -/*## */ -/* Enable HACK for ttrace work. In - * infttrace.c/require_notification_of_events, - * this is set to 0 so that the loop in child_wait - * won't loop. - */ -int not_same_real_pid = 1; -/*## */ - - /* Wait for child to do something. Return pid of child, or -1 in case of error; store status through argument pointer OURSTATUS. */ @@ -170,59 +154,7 @@ child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) ourstatus->kind = TARGET_WAITKIND_SPURIOUS; return pid_to_ptid (pid); } - - if (target_has_forked (pid, &related_pid) - && ((pid == PIDGET (inferior_ptid)) - || (related_pid == PIDGET (inferior_ptid)))) - { - ourstatus->kind = TARGET_WAITKIND_FORKED; - ourstatus->value.related_pid = related_pid; - return pid_to_ptid (pid); - } - - if (target_has_vforked (pid, &related_pid) - && ((pid == PIDGET (inferior_ptid)) - || (related_pid == PIDGET (inferior_ptid)))) - { - ourstatus->kind = TARGET_WAITKIND_VFORKED; - ourstatus->value.related_pid = related_pid; - return pid_to_ptid (pid); - } - - if (target_has_execd (pid, &execd_pathname)) - { - /* Are we ignoring initial exec events? (This is likely because - we're in the process of starting up the inferior, and another - (older) mechanism handles those.) If so, we'll report this - as a regular stop, not an exec. - */ - if (inferior_ignoring_startup_exec_events) - { - inferior_ignoring_startup_exec_events--; - } - else - { - ourstatus->kind = TARGET_WAITKIND_EXECD; - ourstatus->value.execd_pathname = execd_pathname; - return pid_to_ptid (pid); - } - } - - /* All we must do with these is communicate their occurrence - to wait_for_inferior... - */ - if (target_has_syscall_event (pid, &kind, &syscall_id)) - { - ourstatus->kind = kind; - ourstatus->value.syscall_id = syscall_id; - return pid_to_ptid (pid); - } - - /*## } while (pid != PIDGET (inferior_ptid)); ## *//* Some other child died or stopped */ -/* hack for thread testing */ - } - while ((pid != PIDGET (inferior_ptid)) && not_same_real_pid); -/*## */ + } while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ store_waitstatus (ourstatus, status); return pid_to_ptid (pid); @@ -257,8 +189,10 @@ child_thread_alive (ptid_t ptid) #endif +/* Attach to process PID, then initialize for debugging it. */ + static void -child_attach_to_process (char *args, int from_tty, int after_fork) +child_attach (char *args, int from_tty) { if (!args) error_no_arg ("process-id to attach"); @@ -284,23 +218,17 @@ child_attach_to_process (char *args, int from_tty, int after_fork) { exec_file = (char *) get_exec_file (0); - if (after_fork) - printf_unfiltered ("Attaching after fork to %s\n", - target_pid_to_str (pid_to_ptid (pid))); - else if (exec_file) + if (exec_file) printf_unfiltered ("Attaching to program: %s, %s\n", exec_file, target_pid_to_str (pid_to_ptid (pid))); else - printf_unfiltered ("Attaching to %s\n", + printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid_to_ptid (pid))); gdb_flush (gdb_stdout); } - if (!after_fork) - attach (pid); - else - REQUIRE_ATTACH (pid); + attach (pid); inferior_ptid = pid_to_ptid (pid); push_target (&child_ops); @@ -308,15 +236,6 @@ child_attach_to_process (char *args, int from_tty, int after_fork) #endif /* ATTACH_DETACH */ } - -/* Attach to process PID, then initialize for debugging it. */ - -static void -child_attach (char *args, int from_tty) -{ - child_attach_to_process (args, from_tty, 0); -} - #if !defined(CHILD_POST_ATTACH) void child_post_attach (int pid) @@ -326,45 +245,6 @@ child_post_attach (int pid) } #endif -static void -child_require_attach (char *args, int from_tty) -{ - child_attach_to_process (args, from_tty, 1); -} - -static void -child_detach_from_process (int pid, char *args, int from_tty, int after_fork) -{ -#ifdef ATTACH_DETACH - { - int siggnal = 0; - - if (from_tty) - { - char *exec_file = get_exec_file (0); - if (exec_file == 0) - exec_file = ""; - if (after_fork) - printf_unfiltered ("Detaching after fork from %s\n", - target_pid_to_str (pid_to_ptid (pid))); - else - printf_unfiltered ("Detaching from program: %s, %s\n", exec_file, - target_pid_to_str (pid_to_ptid (pid))); - gdb_flush (gdb_stdout); - } - if (args) - siggnal = atoi (args); - - if (!after_fork) - detach (siggnal); - else - REQUIRE_DETACH (pid, siggnal); - } -#else - error ("This version of Unix does not support detaching a process."); -#endif -} - /* Take a program previously attached to and detaches it. The program resumes execution and will no longer stop on signals, etc. We'd better not have left any breakpoints @@ -376,17 +256,32 @@ child_detach_from_process (int pid, char *args, int from_tty, int after_fork) static void child_detach (char *args, int from_tty) { - child_detach_from_process (PIDGET (inferior_ptid), args, from_tty, 0); - inferior_ptid = null_ptid; - unpush_target (&child_ops); -} +#ifdef ATTACH_DETACH + { + int siggnal = 0; + int pid = PIDGET (inferior_ptid); -static void -child_require_detach (int pid, char *args, int from_tty) -{ - child_detach_from_process (pid, args, from_tty, 1); -} + if (from_tty) + { + char *exec_file = get_exec_file (0); + if (exec_file == 0) + exec_file = ""; + printf_unfiltered ("Detaching from program: %s, %s\n", exec_file, + target_pid_to_str (pid_to_ptid (pid))); + gdb_flush (gdb_stdout); + } + if (args) + siggnal = atoi (args); + detach (siggnal); + + inferior_ptid = null_ptid; + unpush_target (&child_ops); + } +#else + error ("This version of Unix does not support detaching a process."); +#endif +} /* Get ready to modify the registers array. On machines which store individual registers, this doesn't need to do anything. On machines @@ -411,7 +306,6 @@ child_files_info (struct target_ops *ignore) attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); } -/* ARGSUSED */ static void child_open (char *arg, int from_tty) { @@ -495,27 +389,6 @@ child_acknowledge_created_inferior (int pid) #endif -void -child_clone_and_follow_inferior (int child_pid, int *followed_child) -{ - clone_and_follow_inferior (child_pid, followed_child); - - /* Don't resume CHILD_PID; it's stopped where it ought to be, until - the decision gets made elsewhere how to continue it. - */ -} - - -#if !defined(CHILD_POST_FOLLOW_INFERIOR_BY_CLONE) -void -child_post_follow_inferior_by_clone (void) -{ - /* This version of Unix doesn't require a meaningful "post follow inferior" - operation by a clone debugger. - */ -} -#endif - #if !defined(CHILD_INSERT_FORK_CATCHPOINT) int child_insert_fork_catchpoint (int pid) @@ -552,51 +425,15 @@ child_remove_vfork_catchpoint (int pid) } #endif -#if !defined(CHILD_HAS_FORKED) +#if !defined(CHILD_FOLLOW_FORK) int -child_has_forked (int pid, int *child_pid) +child_follow_fork (int follow_child) { - /* This version of Unix doesn't support notification of fork events. */ + /* This version of Unix doesn't support following fork or vfork events. */ return 0; } #endif - -#if !defined(CHILD_HAS_VFORKED) -int -child_has_vforked (int pid, int *child_pid) -{ - /* This version of Unix doesn't support notification of vfork events. - */ - return 0; -} -#endif - - -#if !defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC) -int -child_can_follow_vfork_prior_to_exec (void) -{ - /* This version of Unix doesn't support notification of vfork events. - However, if it did, it probably wouldn't allow vforks to be followed - before the following exec. - */ - return 0; -} -#endif - - -#if !defined(CHILD_POST_FOLLOW_VFORK) -void -child_post_follow_vfork (int parent_pid, int followed_parent, int child_pid, - int followed_child) -{ - /* This version of Unix doesn't require a meaningful "post follow vfork" - operation by a clone debugger. - */ -} -#endif - #if !defined(CHILD_INSERT_EXEC_CATCHPOINT) int child_insert_exec_catchpoint (int pid) @@ -615,17 +452,6 @@ child_remove_exec_catchpoint (int pid) } #endif -#if !defined(CHILD_HAS_EXECD) -int -child_has_execd (int pid, char **execd_pathname) -{ - /* This version of Unix doesn't support notification of exec events. - */ - return 0; -} -#endif - - #if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL) int child_reported_exec_events_per_exec_call (void) @@ -636,18 +462,6 @@ child_reported_exec_events_per_exec_call (void) } #endif - -#if !defined(CHILD_HAS_SYSCALL_EVENT) -int -child_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id) -{ - /* This version of Unix doesn't support notification of syscall events. - */ - return 0; -} -#endif - - #if !defined(CHILD_HAS_EXITED) int child_has_exited (int pid, int wait_status, int *exit_status) @@ -698,8 +512,6 @@ child_can_run (void) static void child_stop (void) { - extern pid_t inferior_process_group; - kill (-inferior_process_group, SIGINT); } @@ -739,7 +551,51 @@ child_core_file_to_sym_file (char *core) */ return NULL; } - + +/* Perform a partial transfer to/from the specified object. For + memory transfers, fall back to the old memory xfer functions. */ + +static LONGEST +child_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + switch (object) + { + case TARGET_OBJECT_MEMORY: + if (readbuf) + return child_xfer_memory (offset, readbuf, len, 0/*write*/, + NULL, ops); + if (writebuf) + return child_xfer_memory (offset, readbuf, len, 1/*write*/, + NULL, ops); + return -1; + + case TARGET_OBJECT_UNWIND_TABLE: +#ifndef NATIVE_XFER_UNWIND_TABLE +#define NATIVE_XFER_UNWIND_TABLE(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1) +#endif + return NATIVE_XFER_UNWIND_TABLE (ops, object, annex, readbuf, writebuf, + offset, len); + + case TARGET_OBJECT_AUXV: +#ifndef NATIVE_XFER_AUXV +#define NATIVE_XFER_AUXV(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1) +#endif + return NATIVE_XFER_AUXV (ops, object, annex, readbuf, writebuf, + offset, len); + + case TARGET_OBJECT_WCOOKIE: +#ifndef NATIVE_XFER_WCOOKIE +#define NATIVE_XFER_WCOOKIE(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1) +#endif + return NATIVE_XFER_WCOOKIE (ops, object, annex, readbuf, writebuf, + offset, len); + + default: + return -1; + } +} #if !defined(CHILD_PID_TO_STR) char * @@ -758,9 +614,7 @@ init_child_ops (void) child_ops.to_open = child_open; child_ops.to_attach = child_attach; child_ops.to_post_attach = child_post_attach; - child_ops.to_require_attach = child_require_attach; child_ops.to_detach = child_detach; - child_ops.to_require_detach = child_require_detach; child_ops.to_resume = child_resume; child_ops.to_wait = child_wait; child_ops.to_post_wait = child_post_wait; @@ -768,33 +622,28 @@ init_child_ops (void) child_ops.to_store_registers = store_inferior_registers; child_ops.to_prepare_to_store = child_prepare_to_store; child_ops.to_xfer_memory = child_xfer_memory; + child_ops.to_xfer_partial = child_xfer_partial; child_ops.to_files_info = child_files_info; child_ops.to_insert_breakpoint = memory_insert_breakpoint; child_ops.to_remove_breakpoint = memory_remove_breakpoint; child_ops.to_terminal_init = terminal_init_inferior; child_ops.to_terminal_inferior = terminal_inferior; child_ops.to_terminal_ours_for_output = terminal_ours_for_output; + child_ops.to_terminal_save_ours = terminal_save_ours; child_ops.to_terminal_ours = terminal_ours; child_ops.to_terminal_info = child_terminal_info; child_ops.to_kill = kill_inferior; child_ops.to_create_inferior = child_create_inferior; child_ops.to_post_startup_inferior = child_post_startup_inferior; child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior; - child_ops.to_clone_and_follow_inferior = child_clone_and_follow_inferior; - child_ops.to_post_follow_inferior_by_clone = child_post_follow_inferior_by_clone; child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint; child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint; child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint; child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint; - child_ops.to_has_forked = child_has_forked; - child_ops.to_has_vforked = child_has_vforked; - child_ops.to_can_follow_vfork_prior_to_exec = child_can_follow_vfork_prior_to_exec; - child_ops.to_post_follow_vfork = child_post_follow_vfork; + child_ops.to_follow_fork = child_follow_fork; child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint; child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint; - child_ops.to_has_execd = child_has_execd; child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call; - child_ops.to_has_syscall_event = child_has_syscall_event; child_ops.to_has_exited = child_has_exited; child_ops.to_mourn_inferior = child_mourn_inferior; child_ops.to_can_run = child_can_run; @@ -814,10 +663,10 @@ init_child_ops (void) } /* Take over the 'find_mapped_memory' vector from inftarg.c. */ -extern void -inftarg_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR, - unsigned long, - int, int, int, +extern void +inftarg_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR, + unsigned long, + int, int, int, void *), void *)) { @@ -825,7 +674,7 @@ inftarg_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR, } /* Take over the 'make_corefile_notes' vector from inftarg.c. */ -extern void +extern void inftarg_set_make_corefile_notes (char * (*func) (bfd *, int *)) { child_ops.to_make_corefile_notes = func; @@ -844,7 +693,8 @@ _initialize_inftarg (void) #define PROC_NAME_FMT "/proc/%05d" #endif sprintf (procname, PROC_NAME_FMT, getpid ()); - if ((fd = open (procname, O_RDONLY)) >= 0) + fd = open (procname, O_RDONLY); + if (fd >= 0) { close (fd); return; diff --git a/contrib/gdb/gdb/infttrace.c b/contrib/gdb/gdb/infttrace.c index 7433b7c7292..3f76edbbd1a 100644 --- a/contrib/gdb/gdb/infttrace.c +++ b/contrib/gdb/gdb/infttrace.c @@ -1,6 +1,6 @@ /* Low level Unix child interface to ttrace, for GDB when running under HP-UX. Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001 + 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -27,6 +27,7 @@ #include "gdb_string.h" #include "gdb_wait.h" #include "command.h" +#include "gdbthread.h" /* We need pstat functionality so that we can get the exec file for a process we attach to. @@ -141,12 +142,6 @@ static startup_semaphore_t startup_semaphore; static int vforking_child_pid = 0; static int vfork_in_flight = 0; -/* To support PREPARE_TO_PROCEED (hppa_prepare_to_proceed). - */ -static pid_t old_gdb_pid = 0; -static pid_t reported_pid = 0; -static int reported_bpt = 0; - /* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise. */ #define TT_OK( _status, _errno ) \ @@ -2289,7 +2284,7 @@ call_ttrace_wait (int pid, ttwopt_t option, ttstate_t *tsp, size_t tsp_size) thread descriptor. This caches the state. The implementation of queries like - target_has_execd can then use this cached state, rather than + hpux_has_execd can then use this cached state, rather than be forced to make an explicit ttrace call to get it. (Guard against the condition that this is the first time we've @@ -2911,12 +2906,6 @@ ptrace_wait (ptid_t ptid, int *status) */ return_pid = map_to_gdb_tid (real_tid); - /* Remember this for later use in "hppa_prepare_to_proceed". - */ - old_gdb_pid = PIDGET (inferior_ptid); - reported_pid = return_pid; - reported_bpt = ((tsp.tts_event & TTEVT_SIGNAL) && (5 == tsp.tts_u.tts_signal.tts_signo)); - if (real_tid == 0 || return_pid == 0) { warning ("Internal error: process-wait failed."); @@ -2947,7 +2936,7 @@ ptrace_wait (ptid_t ptid, int *status) child_acknowledge_created_inferior.) */ int -parent_attach_all (void) +parent_attach_all (int p1, PTRACE_ARG3_TYPE p2, int p3) { int tt_status; @@ -3357,8 +3346,6 @@ child_remove_vfork_catchpoint (int tid) } #endif -#if defined(CHILD_HAS_FORKED) - /* Q: Do we need to map the returned process ID to a thread ID? * A: I don't think so--here we want a _real_ pid. Any later @@ -3366,7 +3353,7 @@ child_remove_vfork_catchpoint (int tid) * start the mapping. */ int -child_has_forked (int tid, int *childpid) +hpux_has_forked (int tid, int *childpid) { int tt_status; ttstate_t ttrace_state; @@ -3403,15 +3390,11 @@ child_has_forked (int tid, int *childpid) return 0; } -#endif - -#if defined(CHILD_HAS_VFORKED) - -/* See child_has_forked for pid discussion. +/* See hpux_has_forked for pid discussion. */ int -child_has_vforked (int tid, int *childpid) +hpux_has_vforked (int tid, int *childpid) { int tt_status; ttstate_t ttrace_state; @@ -3446,22 +3429,6 @@ child_has_vforked (int tid, int *childpid) return 0; } -#endif - - -#if defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC) -int -child_can_follow_vfork_prior_to_exec (void) -{ - /* ttrace does allow this. - - ??rehrauer: However, I had major-league problems trying to - convince wait_for_inferior to handle that case. Perhaps when - it is rewritten to grok multiple processes in an explicit way... - */ - return 0; -} -#endif #if defined(CHILD_INSERT_EXEC_CATCHPOINT) @@ -3490,9 +3457,8 @@ child_remove_exec_catchpoint (int tid) #endif -#if defined(CHILD_HAS_EXECD) int -child_has_execd (int tid, char **execd_pathname) +hpux_has_execd (int tid, char **execd_pathname) { int tt_status; ttstate_t ttrace_state; @@ -3531,12 +3497,10 @@ child_has_execd (int tid, char **execd_pathname) return 0; } -#endif -#if defined(CHILD_HAS_SYSCALL_EVENT) int -child_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id) +hpux_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id) { int tt_status; ttstate_t ttrace_state; @@ -3576,7 +3540,6 @@ child_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id) *syscall_id = ttrace_state.tts_scno; return 1; } -#endif @@ -3700,7 +3663,7 @@ call_ptrace (int pt_request, int gdb_tid, PTRACE_ARG3_TYPE addr, int data) there's no need for any "break" statements. */ case PT_SETTRC: - return parent_attach_all (); + return parent_attach_all (0, 0, 0); case PT_RUREGS: tt_status = read_from_register_save_state (gdb_tid, @@ -3977,7 +3940,7 @@ threads_continue_all_but_one (lwpid_t gdb_tid, int signal) * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED */ if (debug_on) - if (state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED) + if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED) printf ("About to continue non-stopped thread %d\n", scan_tid); #endif @@ -4111,7 +4074,7 @@ threads_continue_all_with_signals (lwpid_t gdb_tid, int signal) #ifdef THREAD_DEBUG if (debug_on) - if (state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED) + if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED) warning ("About to continue non-stopped thread %d\n", scan_tid); #endif @@ -4539,98 +4502,49 @@ child_resume (ptid_t ptid, int step, enum target_signal signal) else { - /* TT_LWP_CONTINUE can pass signals to threads, - * TT_PROC_CONTINUE can't. So if there are any - * signals to pass, we have to use the (slower) - * loop over the stopped threads. - * - * Equally, if we have to not continue some threads, - * due to saved events, we have to use the loop. - */ - if ((signal != 0) || saved_signals_exist ()) + /* TT_LWP_CONTINUE can pass signals to threads, TT_PROC_CONTINUE can't. + Therefore, we really can't use TT_PROC_CONTINUE here. + + Consider a process which stopped due to signal which gdb decides + to handle and not pass on to the inferior. In that case we must + clear the pending signal by restarting the inferior using + TT_LWP_CONTINUE and pass zero as the signal number. Else the + pending signal will be passed to the inferior. interrupt.exp + in the testsuite does this precise thing and fails due to the + unwanted signal delivery to the inferior. */ + /* drow/2002-12-05: However, note that we must use TT_PROC_CONTINUE + if we are tracing a vfork. */ + if (vfork_in_flight) { - if (resume_all_threads) - { - -#ifdef THREAD_DEBUG - if (debug_on) - printf ("Doing a continue by loop of all threads\n"); -#endif - - threads_continue_all_with_signals (tid, signal); - - clear_all_handled (); - clear_all_stepping_mode (); - } - - else - { -#ifdef THREAD_DEBUG - printf ("Doing a continue w/signal of just thread %d\n", tid); -#endif - - threads_continue_one_with_signal (tid, signal); - - /* Clear the "handled" state of this thread, because - * we'll soon get a new event for it. Other events - * can stay as they were. - */ - clear_handled (tid); - clear_stepping_mode (tid); - } + call_ttrace (TT_PROC_CONTINUE, tid, TT_NIL, TT_NIL, TT_NIL); + clear_all_handled (); + clear_all_stepping_mode (); } + else if (resume_all_threads) + { +#ifdef THREAD_DEBUG + if (debug_on) + printf ("Doing a continue by loop of all threads\n"); +#endif + threads_continue_all_with_signals (tid, signal); + + clear_all_handled (); + clear_all_stepping_mode (); + } else { - /* No signals to send. - */ - if (resume_all_threads) - { #ifdef THREAD_DEBUG - if (debug_on) - printf ("Doing a continue by process of process %d\n", tid); + printf ("Doing a continue w/signal of just thread %d\n", tid); #endif - if (more_events_left > 0) - { - warning ("Losing buffered events on continue."); - more_events_left = 0; - } + threads_continue_one_with_signal (tid, signal); - call_ttrace (TT_PROC_CONTINUE, - tid, - TT_NIL, - TT_NIL, - TT_NIL); - - clear_all_handled (); - clear_all_stepping_mode (); - } - - else - { -#ifdef THREAD_DEBUG - if (debug_on) - { - printf ("Doing a continue of just thread %d\n", tid); - if (is_terminated (tid)) - printf ("Why are we continuing a dead thread? (5)\n"); - } -#endif - - call_ttrace (TT_LWP_CONTINUE, - tid, - TT_NIL, - TT_NIL, - TT_NIL); - - /* Clear the "handled" state of this thread, because - * we'll soon get a new event for it. Other events - * can stay as they were. - */ - clear_handled (tid); - clear_stepping_mode (tid); - } + /* Clear the "handled" state of this thread, because we + will soon get a new event for it. Other events can + stay as they were. */ + clear_handled (tid); + clear_stepping_mode (tid); } } @@ -4922,18 +4836,18 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, struct mem_attrib *attrib, struct target_ops *target) { - register int i; + int i; /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (TTRACE_XFER_TYPE); + CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (TTRACE_XFER_TYPE); /* Round ending address up; get number of longwords that makes. */ - register int count + int count = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1) / sizeof (TTRACE_XFER_TYPE); /* Allocate buffer of that many longwords. */ /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe because it uses alloca to allocate a buffer of arbitrary size. For very large xfers, this could crash GDB's stack. */ - register TTRACE_XFER_TYPE *buffer + TTRACE_XFER_TYPE *buffer = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE)); if (write) @@ -5125,9 +5039,7 @@ pre_fork_inferior (void) } } -/* Called via #define REQUIRE_ATTACH from inftarg.c, - * ultimately from "follow_inferior_fork" in infrun.c, - * itself called from "resume". +/* Called from child_follow_fork in hppah-nat.c. * * This seems to be intended to attach after a fork or * vfork, while "attach" is used to attach to a pid @@ -5455,8 +5367,7 @@ hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type) watchpoints. */ int -hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, - enum bptype type) +hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type) { CORE_ADDR page_start; int dictionary_is_empty; @@ -5516,7 +5427,7 @@ hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, hardware support. */ int -hppa_can_use_hw_watchpoint (enum bptype type, int cnt, enum bptype ot) +hppa_can_use_hw_watchpoint (int type, int cnt, int ot) { return (type == bp_hardware_watchpoint); } @@ -5613,64 +5524,6 @@ hppa_pid_or_tid_to_str (ptid_t ptid) } -/* If the current pid is not the pid this module reported - * from "ptrace_wait" with the most recent event, then the - * user has switched threads. - * - * If the last reported event was a breakpoint, then return - * the old thread id, else return 0. - */ -pid_t -hppa_switched_threads (pid_t gdb_pid) -{ - if (gdb_pid == old_gdb_pid) - { - /* - * Core gdb is working with the same pid that it - * was before we reported the last event. This - * is ok: e.g. we reported hitting a thread-specific - * breakpoint, but we were reporting the wrong - * thread, so the core just ignored the event. - * - * No thread switch has happened. - */ - return (pid_t) 0; - } - else if (gdb_pid == reported_pid) - { - /* - * Core gdb is working with the pid we reported, so - * any continue or step will be able to figure out - * that it needs to step over any hit breakpoints - * without our (i.e. PREPARE_TO_PROCEED's) help. - */ - return (pid_t) 0; - } - else if (!reported_bpt) - { - /* - * The core switched, but we didn't just report a - * breakpoint, so there's no just-hit breakpoint - * instruction at "reported_pid"'s PC, and thus there - * is no need to step over it. - */ - return (pid_t) 0; - } - else - { - /* There's been a real switch, and we reported - * a hit breakpoint. Let "hppa_prepare_to_proceed" - * know, so it can see whether the breakpoint is - * still active. - */ - return reported_pid; - } - - /* Keep compiler happy with an obvious return at the end. - */ - return (pid_t) 0; -} - void hppa_ensure_vforking_parent_remains_stopped (int pid) { diff --git a/contrib/gdb/gdb/infttrace.h b/contrib/gdb/gdb/infttrace.h new file mode 100644 index 00000000000..d3330e3b85a --- /dev/null +++ b/contrib/gdb/gdb/infttrace.h @@ -0,0 +1,28 @@ +/* Low level Unix child interface to ttrace, for GDB when running under HP-UX. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef INFTTRACE_H +#define INFTTRACE_H + +extern int parent_attach_all (int, PTRACE_ARG3_TYPE, int); +extern pid_t hppa_switched_threads (pid_t gdb_pid); + +#endif diff --git a/contrib/gdb/gdb/interps.c b/contrib/gdb/gdb/interps.c new file mode 100644 index 00000000000..82e9af690b1 --- /dev/null +++ b/contrib/gdb/gdb/interps.c @@ -0,0 +1,486 @@ +/* Manages interpreters for GDB, the GNU debugger. + + Copyright 2000, 2002, 2003 Free Software Foundation, Inc. + + Written by Jim Ingham of Apple Computer, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This is just a first cut at separating out the "interpreter" + functions of gdb into self-contained modules. There are a couple + of open areas that need to be sorted out: + + 1) The interpreter explicitly contains a UI_OUT, and can insert itself + into the event loop, but it doesn't explicitly contain hooks for readline. + I did this because it seems to me many interpreters won't want to use + the readline command interface, and it is probably simpler to just let + them take over the input in their resume proc. */ + +#include "defs.h" +#include "gdbcmd.h" +#include "ui-out.h" +#include "event-loop.h" +#include "event-top.h" +#include "interps.h" +#include "completer.h" +#include "gdb_string.h" +#include "gdb-events.h" +#include "gdb_assert.h" +#include "top.h" /* For command_loop. */ + +struct interp +{ + /* This is the name in "-i=" and set interpreter. */ + const char *name; + + /* Interpreters are stored in a linked list, this is the next + one... */ + struct interp *next; + + /* This is a cookie that an instance of the interpreter can use. + This is a bit confused right now as the exact initialization + sequence for it, and how it relates to the interpreter's uiout + object is a bit confused. */ + void *data; + + /* Has the init_proc been run? */ + int inited; + + /* This is the ui_out used to collect results for this interpreter. + It can be a formatter for stdout, as is the case for the console + & mi outputs, or it might be a result formatter. */ + struct ui_out *interpreter_out; + + const struct interp_procs *procs; + int quiet_p; +}; + +/* Functions local to this file. */ +static void initialize_interps (void); +static char **interpreter_completer (char *text, char *word); + +/* The magic initialization routine for this module. */ + +void _initialize_interpreter (void); + +/* Variables local to this file: */ + +static struct interp *interp_list = NULL; +static struct interp *current_interpreter = NULL; + +static int interpreter_initialized = 0; + +/* interp_new - This allocates space for a new interpreter, + fills the fields from the inputs, and returns a pointer to the + interpreter. */ +struct interp * +interp_new (const char *name, void *data, struct ui_out *uiout, + const struct interp_procs *procs) +{ + struct interp *new_interp; + + new_interp = XMALLOC (struct interp); + + new_interp->name = xstrdup (name); + new_interp->data = data; + new_interp->interpreter_out = uiout; + new_interp->quiet_p = 0; + new_interp->procs = procs; + new_interp->inited = 0; + + return new_interp; +} + +/* Add interpreter INTERP to the gdb interpreter list. The + interpreter must not have previously been added. */ +void +interp_add (struct interp *interp) +{ + if (!interpreter_initialized) + initialize_interps (); + + gdb_assert (interp_lookup (interp->name) == NULL); + + interp->next = interp_list; + interp_list = interp; +} + +/* This sets the current interpreter to be INTERP. If INTERP has not + been initialized, then this will also run the init proc. If the + init proc is successful, return 1, if it fails, set the old + interpreter back in place and return 0. If we can't restore the + old interpreter, then raise an internal error, since we are in + pretty bad shape at this point. */ +int +interp_set (struct interp *interp) +{ + struct interp *old_interp = current_interpreter; + int first_time = 0; + + + char buffer[64]; + + if (current_interpreter != NULL) + { + do_all_continuations (); + ui_out_flush (uiout); + if (current_interpreter->procs->suspend_proc + && !current_interpreter->procs->suspend_proc (current_interpreter-> + data)) + { + error ("Could not suspend interpreter \"%s\"\n", + current_interpreter->name); + } + } + else + { + first_time = 1; + } + + current_interpreter = interp; + + /* We use interpreter_p for the "set interpreter" variable, so we need + to make sure we have a malloc'ed copy for the set command to free. */ + if (interpreter_p != NULL + && strcmp (current_interpreter->name, interpreter_p) != 0) + { + xfree (interpreter_p); + + interpreter_p = xstrdup (current_interpreter->name); + } + + uiout = interp->interpreter_out; + + /* Run the init proc. If it fails, try to restore the old interp. */ + + if (!interp->inited) + { + if (interp->procs->init_proc != NULL) + { + interp->data = interp->procs->init_proc (); + } + interp->inited = 1; + } + + /* Clear out any installed interpreter hooks/event handlers. */ + clear_interpreter_hooks (); + + if (interp->procs->resume_proc != NULL + && (!interp->procs->resume_proc (interp->data))) + { + if (old_interp == NULL || !interp_set (old_interp)) + internal_error (__FILE__, __LINE__, + "Failed to initialize new interp \"%s\" %s", + interp->name, "and could not restore old interp!\n"); + return 0; + } + + /* Finally, put up the new prompt to show that we are indeed here. + Also, display_gdb_prompt for the console does some readline magic + which is needed for the console interpreter, at least... */ + + if (!first_time) + { + if (!interp_quiet_p (interp)) + { + sprintf (buffer, "Switching to interpreter \"%.24s\".\n", + interp->name); + ui_out_text (uiout, buffer); + } + display_gdb_prompt (NULL); + } + + return 1; +} + +/* interp_lookup - Looks up the interpreter for NAME. If no such + interpreter exists, return NULL, otherwise return a pointer to the + interpreter. */ +struct interp * +interp_lookup (const char *name) +{ + struct interp *interp; + + if (name == NULL || strlen (name) == 0) + return NULL; + + for (interp = interp_list; interp != NULL; interp = interp->next) + { + if (strcmp (interp->name, name) == 0) + return interp; + } + + return NULL; +} + +/* Returns the current interpreter. */ + +struct ui_out * +interp_ui_out (struct interp *interp) +{ + if (interp != NULL) + return interp->interpreter_out; + + return current_interpreter->interpreter_out; +} + +/* Returns true if the current interp is the passed in name. */ +int +current_interp_named_p (const char *interp_name) +{ + if (current_interpreter) + return (strcmp (current_interpreter->name, interp_name) == 0); + + return 0; +} + +/* This is called in display_gdb_prompt. If the proc returns a zero + value, display_gdb_prompt will return without displaying the + prompt. */ +int +current_interp_display_prompt_p (void) +{ + if (current_interpreter == NULL + || current_interpreter->procs->prompt_proc_p == NULL) + return 0; + else + return current_interpreter->procs->prompt_proc_p (current_interpreter-> + data); +} + +/* Run the current command interpreter's main loop. */ +void +current_interp_command_loop (void) +{ + /* Somewhat messy. For the moment prop up all the old ways of + selecting the command loop. `command_loop_hook' should be + deprecated. */ + if (command_loop_hook != NULL) + command_loop_hook (); + else if (current_interpreter != NULL + && current_interpreter->procs->command_loop_proc != NULL) + current_interpreter->procs->command_loop_proc (current_interpreter->data); + else if (event_loop_p) + cli_command_loop (); + else + command_loop (); +} + +int +interp_quiet_p (struct interp *interp) +{ + if (interp != NULL) + return interp->quiet_p; + else + return current_interpreter->quiet_p; +} + +static int +interp_set_quiet (struct interp *interp, int quiet) +{ + int old_val = interp->quiet_p; + interp->quiet_p = quiet; + return old_val; +} + +/* interp_exec - This executes COMMAND_STR in the current + interpreter. */ +int +interp_exec_p (struct interp *interp) +{ + return interp->procs->exec_proc != NULL; +} + +int +interp_exec (struct interp *interp, const char *command_str) +{ + if (interp->procs->exec_proc != NULL) + { + return interp->procs->exec_proc (interp->data, command_str); + } + return 0; +} + +/* A convenience routine that nulls out all the + common command hooks. Use it when removing your interpreter in its + suspend proc. */ +void +clear_interpreter_hooks (void) +{ + init_ui_hook = 0; + print_frame_info_listing_hook = 0; + /*print_frame_more_info_hook = 0; */ + query_hook = 0; + warning_hook = 0; + create_breakpoint_hook = 0; + delete_breakpoint_hook = 0; + modify_breakpoint_hook = 0; + interactive_hook = 0; + registers_changed_hook = 0; + readline_begin_hook = 0; + readline_hook = 0; + readline_end_hook = 0; + register_changed_hook = 0; + memory_changed_hook = 0; + context_hook = 0; + target_wait_hook = 0; + call_command_hook = 0; + error_hook = 0; + error_begin_hook = 0; + command_loop_hook = 0; + clear_gdb_event_hooks (); +} + +/* This is a lazy init routine, called the first time + the interpreter module is used. I put it here just in case, but I haven't + thought of a use for it yet. I will probably bag it soon, since I don't + think it will be necessary. */ +static void +initialize_interps (void) +{ + interpreter_initialized = 1; + /* Don't know if anything needs to be done here... */ +} + +static void +interpreter_exec_cmd (char *args, int from_tty) +{ + struct interp *old_interp, *interp_to_use; + char **prules = NULL; + char **trule = NULL; + unsigned int nrules; + unsigned int i; + int old_quiet, use_quiet; + + prules = buildargv (args); + if (prules == NULL) + { + error ("unable to parse arguments"); + } + + nrules = 0; + if (prules != NULL) + { + for (trule = prules; *trule != NULL; trule++) + { + nrules++; + } + } + + if (nrules < 2) + error ("usage: interpreter-exec [ ... ]"); + + old_interp = current_interpreter; + + interp_to_use = interp_lookup (prules[0]); + if (interp_to_use == NULL) + error ("Could not find interpreter \"%s\".", prules[0]); + + /* Temporarily set interpreters quiet */ + old_quiet = interp_set_quiet (old_interp, 1); + use_quiet = interp_set_quiet (interp_to_use, 1); + + if (!interp_set (interp_to_use)) + error ("Could not switch to interpreter \"%s\".", prules[0]); + + for (i = 1; i < nrules; i++) + { + if (!interp_exec (interp_to_use, prules[i])) + { + interp_set (old_interp); + interp_set_quiet (interp_to_use, old_quiet); + error ("error in command: \"%s\".", prules[i]); + break; + } + } + + interp_set (old_interp); + interp_set_quiet (interp_to_use, use_quiet); + interp_set_quiet (old_interp, old_quiet); +} + +/* List the possible interpreters which could complete the given text. */ +static char ** +interpreter_completer (char *text, char *word) +{ + int alloced = 0; + int textlen; + int num_matches; + char **matches; + struct interp *interp; + + /* We expect only a very limited number of interpreters, so just + allocate room for all of them. */ + for (interp = interp_list; interp != NULL; interp = interp->next) + ++alloced; + matches = (char **) xmalloc (alloced * sizeof (char *)); + + num_matches = 0; + textlen = strlen (text); + for (interp = interp_list; interp != NULL; interp = interp->next) + { + if (strncmp (interp->name, text, textlen) == 0) + { + matches[num_matches] = + (char *) xmalloc (strlen (word) + strlen (interp->name) + 1); + if (word == text) + strcpy (matches[num_matches], interp->name); + else if (word > text) + { + /* Return some portion of interp->name */ + strcpy (matches[num_matches], interp->name + (word - text)); + } + else + { + /* Return some of text plus interp->name */ + strncpy (matches[num_matches], word, text - word); + matches[num_matches][text - word] = '\0'; + strcat (matches[num_matches], interp->name); + } + ++num_matches; + } + } + + if (num_matches == 0) + { + xfree (matches); + matches = NULL; + } + else if (num_matches < alloced) + { + matches = (char **) xrealloc ((char *) matches, ((num_matches + 1) + * sizeof (char *))); + matches[num_matches] = NULL; + } + + return matches; +} + +/* This just adds the "interpreter-exec" command. */ +void +_initialize_interpreter (void) +{ + struct cmd_list_element *c; + + c = add_cmd ("interpreter-exec", class_support, + interpreter_exec_cmd, + "Execute a command in an interpreter. It takes two arguments:\n\ +The first argument is the name of the interpreter to use.\n\ +The second argument is the command to execute.\n", &cmdlist); + set_cmd_completer (c, interpreter_completer); +} diff --git a/contrib/gdb/gdb/interps.h b/contrib/gdb/gdb/interps.h new file mode 100644 index 00000000000..8e3257b268e --- /dev/null +++ b/contrib/gdb/gdb/interps.h @@ -0,0 +1,76 @@ +/* Manages interpreters for GDB, the GNU debugger. + + Copyright 2000, 2002, 2003 Free Software Foundation, Inc. + + Written by Jim Ingham of Apple Computer, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef INTERPS_H +#define INTERPS_H + +struct ui_out; +struct interp; + +extern int interp_resume (struct interp *interp); +extern int interp_suspend (struct interp *interp); +extern int interp_prompt_p (struct interp *interp); +extern int interp_exec_p (struct interp *interp); +extern int interp_exec (struct interp *interp, const char *command); +extern int interp_quiet_p (struct interp *interp); + +typedef void *(interp_init_ftype) (void); +typedef int (interp_resume_ftype) (void *data); +typedef int (interp_suspend_ftype) (void *data); +typedef int (interp_prompt_p_ftype) (void *data); +typedef int (interp_exec_ftype) (void *data, const char *command); +typedef void (interp_command_loop_ftype) (void *data); + +struct interp_procs +{ + interp_init_ftype *init_proc; + interp_resume_ftype *resume_proc; + interp_suspend_ftype *suspend_proc; + interp_exec_ftype *exec_proc; + interp_prompt_p_ftype *prompt_proc_p; + interp_command_loop_ftype *command_loop_proc; +}; + +extern struct interp *interp_new (const char *name, void *data, + struct ui_out *uiout, + const struct interp_procs *procs); +extern void interp_add (struct interp *interp); +extern int interp_set (struct interp *interp); +extern struct interp *interp_lookup (const char *name); +extern struct ui_out *interp_ui_out (struct interp *interp); + +extern int current_interp_named_p (const char *name); +extern int current_interp_display_prompt_p (void); +extern void current_interp_command_loop (void); + +extern void clear_interpreter_hooks (void); + +/* well-known interpreters */ +#define INTERP_CONSOLE "console" +#define INTERP_MI1 "mi1" +#define INTERP_MI2 "mi2" +#define INTERP_MI3 "mi3" +#define INTERP_MI "mi" +#define INTERP_TUI "tui" + +#endif diff --git a/contrib/gdb/gdb/jv-exp.c b/contrib/gdb/gdb/jv-exp.c new file mode 100644 index 00000000000..17b792d4338 --- /dev/null +++ b/contrib/gdb/gdb/jv-exp.c @@ -0,0 +1,2842 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + INTEGER_LITERAL = 258, + FLOATING_POINT_LITERAL = 259, + IDENTIFIER = 260, + STRING_LITERAL = 261, + BOOLEAN_LITERAL = 262, + TYPENAME = 263, + NAME_OR_INT = 264, + ERROR = 265, + LONG = 266, + SHORT = 267, + BYTE = 268, + INT = 269, + CHAR = 270, + BOOLEAN = 271, + DOUBLE = 272, + FLOAT = 273, + VARIABLE = 274, + ASSIGN_MODIFY = 275, + SUPER = 276, + NEW = 277, + OROR = 278, + ANDAND = 279, + NOTEQUAL = 280, + EQUAL = 281, + GEQ = 282, + LEQ = 283, + RSH = 284, + LSH = 285, + DECREMENT = 286, + INCREMENT = 287 + }; +#endif +#define INTEGER_LITERAL 258 +#define FLOATING_POINT_LITERAL 259 +#define IDENTIFIER 260 +#define STRING_LITERAL 261 +#define BOOLEAN_LITERAL 262 +#define TYPENAME 263 +#define NAME_OR_INT 264 +#define ERROR 265 +#define LONG 266 +#define SHORT 267 +#define BYTE 268 +#define INT 269 +#define CHAR 270 +#define BOOLEAN 271 +#define DOUBLE 272 +#define FLOAT 273 +#define VARIABLE 274 +#define ASSIGN_MODIFY 275 +#define SUPER 276 +#define NEW 277 +#define OROR 278 +#define ANDAND 279 +#define NOTEQUAL 280 +#define EQUAL 281 +#define GEQ 282 +#define LEQ 283 +#define RSH 284 +#define LSH 285 +#define DECREMENT 286 +#define INCREMENT 287 + + + + +/* Copy the first part of user declarations. */ +#line 38 "jv-exp.y" + + +#include "defs.h" +#include "gdb_string.h" +#include +#include "expression.h" +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "jv-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in gdb. Note that these are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +#define yymaxdepth java_maxdepth +#define yyparse java_parse +#define yylex java_lex +#define yyerror java_error +#define yylval java_lval +#define yychar java_char +#define yydebug java_debug +#define yypact java_pact +#define yyr1 java_r1 +#define yyr2 java_r2 +#define yydef java_def +#define yychk java_chk +#define yypgo java_pgo +#define yyact java_act +#define yyexca java_exca +#define yyerrflag java_errflag +#define yynerrs java_nerrs +#define yyps java_ps +#define yypv java_pv +#define yys java_s +#define yy_yys java_yys +#define yystate java_state +#define yytmp java_tmp +#define yyv java_v +#define yy_yyv java_yyv +#define yyval java_val +#define yylloc java_lloc +#define yyreds java_reds /* With YYDEBUG defined */ +#define yytoks java_toks /* With YYDEBUG defined */ +#define yyname java_name /* With YYDEBUG defined */ +#define yyrule java_rule /* With YYDEBUG defined */ +#define yylhs java_yylhs +#define yylen java_yylen +#define yydefred java_yydefred +#define yydgoto java_yydgoto +#define yysindex java_yysindex +#define yyrindex java_yyrindex +#define yygindex java_yygindex +#define yytable java_yytable +#define yycheck java_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 1 /* Default to yydebug support */ +#endif + +#define YYFPRINTF parser_fprintf + +int yyparse (void); + +static int yylex (void); + +void yyerror (char *); + +static struct type *java_type_from_name (struct stoken); +static void push_expression_name (struct stoken); +static void push_fieldnames (struct stoken); + +static struct expression *copy_exp (struct expression *, int); +static void insert_exp (int, struct expression *); + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 127 "jv-exp.y" +typedef union YYSTYPE { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val_int; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; + struct symbol *sym; + struct type *tval; + struct stoken sval; + struct ttype tsym; + struct symtoken ssym; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + int *ivec; + } YYSTYPE; +/* Line 191 of yacc.c. */ +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ +#line 148 "jv-exp.y" + +/* YYSTYPE gets defined by %union */ +static int parse_number (char *, int, int, YYSTYPE *); + + +/* Line 214 of yacc.c. */ + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or xmalloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC xmalloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 97 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 421 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 56 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 56 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 130 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 207 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 287 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 54, 2, 2, 2, 43, 30, 2, + 48, 49, 41, 39, 23, 40, 46, 42, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 55, 2, + 33, 24, 34, 25, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 47, 2, 52, 29, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 50, 28, 51, 53, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 26, 27, + 31, 32, 35, 36, 37, 38, 44, 45 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, + 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, + 39, 41, 43, 45, 47, 49, 51, 54, 57, 59, + 61, 63, 65, 67, 69, 73, 75, 79, 81, 83, + 85, 89, 91, 93, 95, 97, 101, 103, 105, 111, + 113, 117, 118, 120, 125, 130, 132, 135, 139, 142, + 146, 148, 149, 153, 157, 162, 169, 176, 181, 186, + 191, 193, 195, 197, 199, 201, 204, 207, 209, 211, + 214, 217, 220, 222, 225, 228, 230, 233, 236, 238, + 244, 249, 255, 257, 261, 265, 269, 271, 275, 279, + 281, 285, 289, 291, 295, 299, 303, 307, 309, 313, + 317, 319, 323, 325, 329, 331, 335, 337, 341, 343, + 347, 349, 355, 357, 359, 363, 367, 369, 371, 373, + 375 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 57, 0, -1, 73, -1, 58, -1, 59, -1, 62, + -1, 68, -1, 6, -1, 3, -1, 9, -1, 4, + -1, 7, -1, 60, -1, 63, -1, 16, -1, 64, + -1, 65, -1, 13, -1, 12, -1, 14, -1, 11, + -1, 15, -1, 18, -1, 17, -1, 69, -1, 66, + -1, 62, 84, -1, 69, 84, -1, 5, -1, 72, + -1, 71, -1, 72, -1, 5, -1, 9, -1, 69, + 46, 71, -1, 111, -1, 73, 23, 111, -1, 75, + -1, 81, -1, 61, -1, 48, 111, 49, -1, 78, + -1, 86, -1, 87, -1, 88, -1, 76, 79, 77, + -1, 50, -1, 51, -1, 22, 67, 48, 80, 49, + -1, 111, -1, 79, 23, 111, -1, -1, 79, -1, + 22, 62, 82, 85, -1, 22, 66, 82, 85, -1, + 83, -1, 82, 83, -1, 47, 111, 52, -1, 47, + 52, -1, 84, 47, 52, -1, 84, -1, -1, 74, + 46, 71, -1, 19, 46, 71, -1, 69, 48, 80, + 49, -1, 74, 46, 71, 48, 80, 49, -1, 21, + 46, 71, 48, 80, 49, -1, 69, 47, 111, 52, + -1, 19, 47, 111, 52, -1, 75, 47, 111, 52, + -1, 74, -1, 69, -1, 19, -1, 90, -1, 91, + -1, 89, 45, -1, 89, 44, -1, 93, -1, 94, + -1, 39, 92, -1, 40, 92, -1, 41, 92, -1, + 95, -1, 45, 92, -1, 44, 92, -1, 89, -1, + 53, 92, -1, 54, 92, -1, 96, -1, 48, 62, + 85, 49, 92, -1, 48, 111, 49, 95, -1, 48, + 69, 84, 49, 95, -1, 92, -1, 97, 41, 92, + -1, 97, 42, 92, -1, 97, 43, 92, -1, 97, + -1, 98, 39, 97, -1, 98, 40, 97, -1, 98, + -1, 99, 38, 98, -1, 99, 37, 98, -1, 99, + -1, 100, 33, 99, -1, 100, 34, 99, -1, 100, + 36, 99, -1, 100, 35, 99, -1, 100, -1, 101, + 32, 100, -1, 101, 31, 100, -1, 101, -1, 102, + 30, 101, -1, 102, -1, 103, 29, 102, -1, 103, + -1, 104, 28, 103, -1, 104, -1, 105, 27, 104, + -1, 105, -1, 106, 26, 105, -1, 106, -1, 106, + 25, 111, 55, 107, -1, 107, -1, 109, -1, 110, + 24, 107, -1, 110, 20, 107, -1, 70, -1, 19, + -1, 86, -1, 88, -1, 108, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 204, 204, 205, 208, 217, 218, 222, 231, 236, + 244, 249, 254, 265, 266, 271, 272, 276, 278, 280, + 282, 284, 289, 291, 303, 308, 312, 314, 319, 320, + 324, 325, 329, 330, 334, 357, 358, 363, 364, 368, + 369, 370, 371, 372, 373, 374, 382, 387, 392, 398, + 400, 406, 407, 411, 414, 420, 421, 425, 429, 431, + 436, 438, 442, 444, 450, 452, 454, 459, 476, 478, + 483, 484, 486, 488, 489, 493, 498, 503, 504, 505, + 506, 508, 510, 514, 519, 524, 525, 527, 529, 533, + 537, 558, 566, 567, 569, 571, 576, 577, 579, 584, + 585, 587, 593, 594, 596, 598, 600, 606, 607, 609, + 614, 615, 620, 621, 625, 626, 631, 632, 637, 638, + 643, 644, 649, 650, 654, 656, 663, 665, 667, 668, + 673 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "INTEGER_LITERAL", + "FLOATING_POINT_LITERAL", "IDENTIFIER", "STRING_LITERAL", + "BOOLEAN_LITERAL", "TYPENAME", "NAME_OR_INT", "ERROR", "LONG", "SHORT", + "BYTE", "INT", "CHAR", "BOOLEAN", "DOUBLE", "FLOAT", "VARIABLE", + "ASSIGN_MODIFY", "SUPER", "NEW", "','", "'='", "'?'", "OROR", "ANDAND", + "'|'", "'^'", "'&'", "NOTEQUAL", "EQUAL", "'<'", "'>'", "GEQ", "LEQ", + "RSH", "LSH", "'+'", "'-'", "'*'", "'/'", "'%'", "DECREMENT", + "INCREMENT", "'.'", "'['", "'('", "')'", "'{'", "'}'", "']'", "'~'", + "'!'", "':'", "$accept", "start", "type_exp", "PrimitiveOrArrayType", + "StringLiteral", "Literal", "PrimitiveType", "NumericType", + "IntegralType", "FloatingPointType", "ClassOrInterfaceType", + "ClassType", "ArrayType", "Name", "ForcedName", "SimpleName", + "QualifiedName", "exp1", "Primary", "PrimaryNoNewArray", "lcurly", + "rcurly", "ClassInstanceCreationExpression", "ArgumentList", + "ArgumentList_opt", "ArrayCreationExpression", "DimExprs", "DimExpr", + "Dims", "Dims_opt", "FieldAccess", "MethodInvocation", "ArrayAccess", + "PostfixExpression", "PostIncrementExpression", + "PostDecrementExpression", "UnaryExpression", "PreIncrementExpression", + "PreDecrementExpression", "UnaryExpressionNotPlusMinus", + "CastExpression", "MultiplicativeExpression", "AdditiveExpression", + "ShiftExpression", "RelationalExpression", "EqualityExpression", + "AndExpression", "ExclusiveOrExpression", "InclusiveOrExpression", + "ConditionalAndExpression", "ConditionalOrExpression", + "ConditionalExpression", "AssignmentExpression", "Assignment", + "LeftHandSide", "Expression", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 44, 61, 63, 278, 279, 124, 94, + 38, 280, 281, 60, 62, 282, 283, 284, 285, 43, + 45, 42, 47, 37, 286, 287, 46, 91, 40, 41, + 123, 125, 93, 126, 33, 58 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 56, 57, 57, 58, 59, 59, 60, 61, 61, + 61, 61, 61, 62, 62, 63, 63, 64, 64, 64, + 64, 64, 65, 65, 66, 67, 68, 68, 69, 69, + 70, 70, 71, 71, 72, 73, 73, 74, 74, 75, + 75, 75, 75, 75, 75, 75, 76, 77, 78, 79, + 79, 80, 80, 81, 81, 82, 82, 83, 84, 84, + 85, 85, 86, 86, 87, 87, 87, 88, 88, 88, + 89, 89, 89, 89, 89, 90, 91, 92, 92, 92, + 92, 92, 92, 93, 94, 95, 95, 95, 95, 96, + 96, 96, 97, 97, 97, 97, 98, 98, 98, 99, + 99, 99, 100, 100, 100, 100, 100, 101, 101, 101, + 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, + 107, 107, 108, 108, 109, 109, 110, 110, 110, 110, + 111 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, + 3, 1, 1, 1, 1, 3, 1, 1, 5, 1, + 3, 0, 1, 4, 4, 1, 2, 3, 2, 3, + 1, 0, 3, 3, 4, 6, 6, 4, 4, 4, + 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, + 2, 2, 1, 2, 2, 1, 2, 2, 1, 5, + 4, 5, 1, 3, 3, 3, 1, 3, 3, 1, + 3, 3, 1, 3, 3, 3, 3, 1, 3, 3, + 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, + 1, 5, 1, 1, 3, 3, 1, 1, 1, 1, + 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 0, 8, 10, 28, 7, 11, 9, 20, 18, 17, + 19, 21, 14, 23, 22, 72, 0, 0, 0, 0, + 0, 0, 0, 0, 46, 0, 0, 0, 3, 4, + 12, 39, 5, 13, 15, 16, 6, 71, 126, 30, + 29, 2, 70, 37, 0, 41, 38, 42, 43, 44, + 85, 73, 74, 92, 77, 78, 82, 88, 96, 99, + 102, 107, 110, 112, 114, 116, 118, 120, 122, 130, + 123, 0, 35, 0, 0, 0, 28, 0, 25, 0, + 24, 29, 9, 72, 71, 42, 44, 79, 80, 81, + 84, 83, 61, 71, 0, 86, 87, 1, 0, 26, + 0, 0, 51, 27, 0, 0, 0, 0, 49, 76, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 33, 63, 0, 0, 0, 61, 55, + 61, 51, 0, 60, 0, 0, 40, 58, 0, 34, + 0, 52, 0, 36, 62, 0, 0, 47, 45, 93, + 94, 95, 97, 98, 101, 100, 103, 104, 106, 105, + 109, 108, 111, 113, 115, 117, 0, 119, 125, 124, + 68, 51, 0, 0, 56, 53, 54, 0, 0, 0, + 90, 59, 67, 64, 51, 69, 50, 0, 0, 57, + 48, 89, 91, 0, 121, 66, 65 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 78, 79, 36, 84, 38, 39, 81, 41, 42, 43, + 44, 158, 45, 151, 152, 46, 138, 139, 143, 144, + 85, 48, 86, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 108 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -135 +static const short yypact[] = +{ + 204, -135, -135, 8, -135, -135, 14, -135, -135, -135, + -135, -135, -135, -135, -135, -4, 5, 50, 308, 308, + 308, 308, 308, 204, -135, 308, 308, 40, -135, -135, + -135, -135, -1, -135, -135, -135, -135, 37, -135, -135, + 28, 36, 45, 46, 360, -135, -135, 33, -135, 49, + -19, -135, -135, -135, -135, -135, -135, -135, 84, 31, + 95, 54, 89, 75, 74, 81, 88, 110, -135, -135, + -135, 52, -135, 73, 360, 73, -135, 64, 64, 69, + 77, -135, -135, 92, 83, -135, -135, -135, -135, -135, + -135, -135, -1, 37, 103, -135, -135, -135, 107, 114, + 73, 256, 360, 114, 360, 73, 360, -6, -135, -135, + -135, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 360, 308, + 308, 308, -135, -135, -135, 111, 116, 360, 118, -135, + 118, 360, 360, 114, 117, -16, 367, -135, 115, -135, + 120, 146, 121, -135, 125, 123, 360, -135, -135, -135, + -135, -135, 84, 84, 31, 31, 95, 95, 95, 95, + 54, 54, 89, 75, 74, 81, 122, 88, -135, -135, + -135, 360, 124, 256, -135, -135, -135, 129, 308, 367, + -135, -135, -135, -135, 360, -135, -135, 308, 130, -135, + -135, -135, -135, 131, -135, -135, -135 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short yypgoto[] = +{ + -135, -135, -135, -135, -135, -135, 4, -135, -135, -135, + -135, -135, -135, 13, -135, -51, 0, -135, -135, -135, + -135, -135, -135, 138, -134, -135, 106, -101, -18, -59, + 6, -135, 12, -135, -135, -135, -17, -135, -135, -131, + -135, 30, 34, -21, 35, 61, 63, 60, 65, 62, + -135, -120, -135, -135, -135, 18 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -130 +static const short yytable[] = +{ + 40, 87, 88, 89, 90, 91, 47, 187, 95, 96, + 178, 179, 49, 37, 99, 190, -127, 156, 72, 103, + -127, 77, 134, 40, 136, 109, 110, 92, -32, 47, + 80, 148, -32, 189, -33, 49, 93, 184, -33, 184, + 97, 94, 73, 74, 40, 157, 98, 198, -31, 149, + 47, 75, -31, -128, 154, 76, 49, -128, 202, 104, + 203, 7, 8, 9, 10, 11, 12, 13, 14, -129, + 114, 115, 130, -129, 40, 145, 131, 204, 132, 185, + 47, 186, 133, 100, 101, 102, 49, 118, 119, 120, + 121, 105, 135, 106, 159, 160, 161, 166, 167, 168, + 169, 40, 40, 125, 40, 124, 40, 47, 47, 126, + 47, 137, 47, 49, 49, 127, 49, 141, 49, 150, + 122, 123, 153, 100, 155, 111, 112, 113, 40, 100, + 142, 102, 116, 117, 47, 128, 129, 40, 73, 74, + 49, 40, 40, 47, 162, 163, 176, 47, 47, 49, + 164, 165, 146, 49, 49, 182, 40, 170, 171, 147, + 150, 148, 47, 180, 181, 183, 188, 191, 49, 156, + 193, 201, 192, 194, 196, 195, 199, 197, 200, 205, + 206, 40, 107, 40, 140, 172, 174, 47, 173, 47, + 0, 177, 175, 49, 40, 49, 0, 0, 0, 0, + 47, 182, 0, 0, 0, 0, 49, 1, 2, 3, + 4, 5, 0, 6, 0, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 16, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 18, 19, 20, 0, 0, 21, 22, + 0, 0, 23, 0, 24, 0, 0, 25, 26, 1, + 2, 3, 4, 5, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 16, 17, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 19, 20, 0, 0, + 21, 22, 0, 0, 23, 0, 24, 0, 147, 25, + 26, 1, 2, 76, 4, 5, 0, 82, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 83, 0, 16, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, + 0, 0, 21, 22, 0, 0, 23, 0, 24, 0, + 0, 25, 26, 1, 2, 3, 4, 5, 0, 6, + 1, 2, 76, 4, 5, 0, 82, 0, 0, 15, + 0, 16, 17, 0, 0, 0, 83, 0, 16, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, + 19, 20, 0, 0, 21, 22, 0, 0, 23, 0, + 24, 0, 0, 25, 26, 23, 0, 24, 0, 0, + 25, 26 +}; + +static const short yycheck[] = +{ + 0, 18, 19, 20, 21, 22, 0, 141, 25, 26, + 130, 131, 0, 0, 32, 146, 20, 23, 0, 37, + 24, 17, 73, 23, 75, 44, 45, 23, 20, 23, + 17, 47, 24, 49, 20, 23, 23, 138, 24, 140, + 0, 23, 46, 47, 44, 51, 47, 181, 20, 100, + 44, 46, 24, 20, 105, 5, 44, 24, 189, 23, + 194, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 39, 40, 20, 24, 74, 93, 24, 197, 5, 138, + 74, 140, 9, 46, 47, 48, 74, 33, 34, 35, + 36, 46, 74, 47, 111, 112, 113, 118, 119, 120, + 121, 101, 102, 29, 104, 30, 106, 101, 102, 28, + 104, 47, 106, 101, 102, 27, 104, 48, 106, 101, + 31, 32, 104, 46, 106, 41, 42, 43, 128, 46, + 47, 48, 37, 38, 128, 25, 26, 137, 46, 47, + 128, 141, 142, 137, 114, 115, 128, 141, 142, 137, + 116, 117, 49, 141, 142, 137, 156, 122, 123, 52, + 142, 47, 156, 52, 48, 47, 49, 52, 156, 23, + 49, 188, 52, 48, 156, 52, 52, 55, 49, 49, + 49, 181, 44, 183, 78, 124, 126, 181, 125, 183, + -1, 129, 127, 181, 194, 183, -1, -1, -1, -1, + 194, 183, -1, -1, -1, -1, 194, 3, 4, 5, + 6, 7, -1, 9, -1, 11, 12, 13, 14, 15, + 16, 17, 18, 19, -1, 21, 22, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 39, 40, 41, -1, -1, 44, 45, + -1, -1, 48, -1, 50, -1, -1, 53, 54, 3, + 4, 5, 6, 7, -1, 9, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, -1, 21, 22, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 39, 40, 41, -1, -1, + 44, 45, -1, -1, 48, -1, 50, -1, 52, 53, + 54, 3, 4, 5, 6, 7, -1, 9, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, -1, 21, + 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, + -1, -1, 44, 45, -1, -1, 48, -1, 50, -1, + -1, 53, 54, 3, 4, 5, 6, 7, -1, 9, + 3, 4, 5, 6, 7, -1, 9, -1, -1, 19, + -1, 21, 22, -1, -1, -1, 19, -1, 21, 22, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, + 40, 41, -1, -1, 44, 45, -1, -1, 48, -1, + 50, -1, -1, 53, 54, 48, -1, 50, -1, -1, + 53, 54 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 9, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 21, 22, 39, 40, + 41, 44, 45, 48, 50, 53, 54, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 78, 81, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 46, 47, 46, 5, 62, 66, 67, + 69, 72, 9, 19, 69, 86, 88, 92, 92, 92, + 92, 92, 62, 69, 111, 92, 92, 0, 47, 84, + 46, 47, 48, 84, 23, 46, 47, 79, 111, 44, + 45, 41, 42, 43, 39, 40, 37, 38, 33, 34, + 35, 36, 31, 32, 30, 29, 28, 27, 25, 26, + 20, 24, 5, 9, 71, 111, 71, 47, 82, 83, + 82, 48, 47, 84, 85, 84, 49, 52, 47, 71, + 111, 79, 80, 111, 71, 111, 23, 51, 77, 92, + 92, 92, 97, 97, 98, 98, 99, 99, 99, 99, + 100, 100, 101, 102, 103, 104, 111, 105, 107, 107, + 52, 48, 111, 47, 83, 85, 85, 80, 49, 49, + 95, 52, 52, 49, 48, 52, 111, 55, 80, 52, + 49, 92, 95, 80, 107, 49, 49 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to xreallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to xreallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: +#line 209 "jv-exp.y" + { + write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(yyvsp[0].tval); + write_exp_elt_opcode(OP_TYPE); + } + break; + + case 7: +#line 223 "jv-exp.y" + { + write_exp_elt_opcode (OP_STRING); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_STRING); + } + break; + + case 8: +#line 232 "jv-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (yyvsp[0].typed_val_int.type); + write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 9: +#line 237 "jv-exp.y" + { YYSTYPE val; + parse_number (yyvsp[0].sval.ptr, yyvsp[0].sval.length, 0, &val); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (val.typed_val_int.type); + write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 10: +#line 245 "jv-exp.y" + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type (yyvsp[0].typed_val_float.type); + write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval); + write_exp_elt_opcode (OP_DOUBLE); } + break; + + case 11: +#line 250 "jv-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (java_boolean_type); + write_exp_elt_longcst ((LONGEST)yyvsp[0].lval); + write_exp_elt_opcode (OP_LONG); } + break; + + case 14: +#line 267 "jv-exp.y" + { yyval.tval = java_boolean_type; } + break; + + case 17: +#line 277 "jv-exp.y" + { yyval.tval = java_byte_type; } + break; + + case 18: +#line 279 "jv-exp.y" + { yyval.tval = java_short_type; } + break; + + case 19: +#line 281 "jv-exp.y" + { yyval.tval = java_int_type; } + break; + + case 20: +#line 283 "jv-exp.y" + { yyval.tval = java_long_type; } + break; + + case 21: +#line 285 "jv-exp.y" + { yyval.tval = java_char_type; } + break; + + case 22: +#line 290 "jv-exp.y" + { yyval.tval = java_float_type; } + break; + + case 23: +#line 292 "jv-exp.y" + { yyval.tval = java_double_type; } + break; + + case 24: +#line 304 "jv-exp.y" + { yyval.tval = java_type_from_name (yyvsp[0].sval); } + break; + + case 26: +#line 313 "jv-exp.y" + { yyval.tval = java_array_type (yyvsp[-1].tval, yyvsp[0].lval); } + break; + + case 27: +#line 315 "jv-exp.y" + { yyval.tval = java_array_type (java_type_from_name (yyvsp[-1].sval), yyvsp[0].lval); } + break; + + case 34: +#line 335 "jv-exp.y" + { yyval.sval.length = yyvsp[-2].sval.length + yyvsp[0].sval.length + 1; + if (yyvsp[-2].sval.ptr + yyvsp[-2].sval.length + 1 == yyvsp[0].sval.ptr + && yyvsp[-2].sval.ptr[yyvsp[-2].sval.length] == '.') + yyval.sval.ptr = yyvsp[-2].sval.ptr; /* Optimization. */ + else + { + yyval.sval.ptr = (char *) xmalloc (yyval.sval.length + 1); + make_cleanup (free, yyval.sval.ptr); + sprintf (yyval.sval.ptr, "%.*s.%.*s", + yyvsp[-2].sval.length, yyvsp[-2].sval.ptr, yyvsp[0].sval.length, yyvsp[0].sval.ptr); + } } + break; + + case 36: +#line 359 "jv-exp.y" + { write_exp_elt_opcode (BINOP_COMMA); } + break; + + case 45: +#line 375 "jv-exp.y" + { write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_ARRAY); } + break; + + case 46: +#line 383 "jv-exp.y" + { start_arglist (); } + break; + + case 47: +#line 388 "jv-exp.y" + { yyval.lval = end_arglist () - 1; } + break; + + case 48: +#line 393 "jv-exp.y" + { internal_error (__FILE__, __LINE__, + _("FIXME - ClassInstanceCreationExpression")); } + break; + + case 49: +#line 399 "jv-exp.y" + { arglist_len = 1; } + break; + + case 50: +#line 401 "jv-exp.y" + { arglist_len++; } + break; + + case 51: +#line 406 "jv-exp.y" + { arglist_len = 0; } + break; + + case 53: +#line 412 "jv-exp.y" + { internal_error (__FILE__, __LINE__, + _("FIXME - ArrayCreationExpression")); } + break; + + case 54: +#line 415 "jv-exp.y" + { internal_error (__FILE__, __LINE__, + _("FIXME - ArrayCreationExpression")); } + break; + + case 58: +#line 430 "jv-exp.y" + { yyval.lval = 1; } + break; + + case 59: +#line 432 "jv-exp.y" + { yyval.lval = yyvsp[-2].lval + 1; } + break; + + case 61: +#line 438 "jv-exp.y" + { yyval.lval = 0; } + break; + + case 62: +#line 443 "jv-exp.y" + { push_fieldnames (yyvsp[0].sval); } + break; + + case 63: +#line 445 "jv-exp.y" + { push_fieldnames (yyvsp[0].sval); } + break; + + case 64: +#line 451 "jv-exp.y" + { error (_("Method invocation not implemented")); } + break; + + case 65: +#line 453 "jv-exp.y" + { error (_("Method invocation not implemented")); } + break; + + case 66: +#line 455 "jv-exp.y" + { error (_("Method invocation not implemented")); } + break; + + case 67: +#line 460 "jv-exp.y" + { + /* Emit code for the Name now, then exchange it in the + expout array with the Expression's code. We could + introduce a OP_SWAP code or a reversed version of + BINOP_SUBSCRIPT, but that makes the rest of GDB pay + for our parsing kludges. */ + struct expression *name_expr; + + push_expression_name (yyvsp[-3].sval); + name_expr = copy_exp (expout, expout_ptr); + expout_ptr -= name_expr->nelts; + insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr), + name_expr); + free (name_expr); + write_exp_elt_opcode (BINOP_SUBSCRIPT); + } + break; + + case 68: +#line 477 "jv-exp.y" + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + break; + + case 69: +#line 479 "jv-exp.y" + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + break; + + case 71: +#line 485 "jv-exp.y" + { push_expression_name (yyvsp[0].sval); } + break; + + case 75: +#line 494 "jv-exp.y" + { write_exp_elt_opcode (UNOP_POSTINCREMENT); } + break; + + case 76: +#line 499 "jv-exp.y" + { write_exp_elt_opcode (UNOP_POSTDECREMENT); } + break; + + case 80: +#line 507 "jv-exp.y" + { write_exp_elt_opcode (UNOP_NEG); } + break; + + case 81: +#line 509 "jv-exp.y" + { write_exp_elt_opcode (UNOP_IND); } + break; + + case 83: +#line 515 "jv-exp.y" + { write_exp_elt_opcode (UNOP_PREINCREMENT); } + break; + + case 84: +#line 520 "jv-exp.y" + { write_exp_elt_opcode (UNOP_PREDECREMENT); } + break; + + case 86: +#line 526 "jv-exp.y" + { write_exp_elt_opcode (UNOP_COMPLEMENT); } + break; + + case 87: +#line 528 "jv-exp.y" + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + break; + + case 89: +#line 534 "jv-exp.y" + { write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (java_array_type (yyvsp[-3].tval, yyvsp[-2].lval)); + write_exp_elt_opcode (UNOP_CAST); } + break; + + case 90: +#line 538 "jv-exp.y" + { + int exp_size = expout_ptr; + int last_exp_size = length_of_subexp(expout, expout_ptr); + struct type *type; + int i; + int base = expout_ptr - last_exp_size - 3; + if (base < 0 || expout->elts[base+2].opcode != OP_TYPE) + error (_("Invalid cast expression")); + type = expout->elts[base+1].type; + /* Remove the 'Expression' and slide the + UnaryExpressionNotPlusMinus down to replace it. */ + for (i = 0; i < last_exp_size; i++) + expout->elts[base + i] = expout->elts[base + i + 3]; + expout_ptr -= 3; + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + type = lookup_pointer_type (type); + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (type); + write_exp_elt_opcode (UNOP_CAST); + } + break; + + case 91: +#line 559 "jv-exp.y" + { write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (java_array_type (java_type_from_name (yyvsp[-3].sval), yyvsp[-2].lval)); + write_exp_elt_opcode (UNOP_CAST); } + break; + + case 93: +#line 568 "jv-exp.y" + { write_exp_elt_opcode (BINOP_MUL); } + break; + + case 94: +#line 570 "jv-exp.y" + { write_exp_elt_opcode (BINOP_DIV); } + break; + + case 95: +#line 572 "jv-exp.y" + { write_exp_elt_opcode (BINOP_REM); } + break; + + case 97: +#line 578 "jv-exp.y" + { write_exp_elt_opcode (BINOP_ADD); } + break; + + case 98: +#line 580 "jv-exp.y" + { write_exp_elt_opcode (BINOP_SUB); } + break; + + case 100: +#line 586 "jv-exp.y" + { write_exp_elt_opcode (BINOP_LSH); } + break; + + case 101: +#line 588 "jv-exp.y" + { write_exp_elt_opcode (BINOP_RSH); } + break; + + case 103: +#line 595 "jv-exp.y" + { write_exp_elt_opcode (BINOP_LESS); } + break; + + case 104: +#line 597 "jv-exp.y" + { write_exp_elt_opcode (BINOP_GTR); } + break; + + case 105: +#line 599 "jv-exp.y" + { write_exp_elt_opcode (BINOP_LEQ); } + break; + + case 106: +#line 601 "jv-exp.y" + { write_exp_elt_opcode (BINOP_GEQ); } + break; + + case 108: +#line 608 "jv-exp.y" + { write_exp_elt_opcode (BINOP_EQUAL); } + break; + + case 109: +#line 610 "jv-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 111: +#line 616 "jv-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + break; + + case 113: +#line 622 "jv-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + break; + + case 115: +#line 627 "jv-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + break; + + case 117: +#line 633 "jv-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + break; + + case 119: +#line 639 "jv-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + break; + + case 121: +#line 645 "jv-exp.y" + { write_exp_elt_opcode (TERNOP_COND); } + break; + + case 124: +#line 655 "jv-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN); } + break; + + case 125: +#line 657 "jv-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode (yyvsp[-1].opcode); + write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } + break; + + case 126: +#line 664 "jv-exp.y" + { push_expression_name (yyvsp[0].sval); } + break; + + + } + +/* Line 991 of yacc.c. */ + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. Doesn't work in C++ */ +#ifndef __cplusplus +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 676 "jv-exp.y" + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. + LEN is the number of characters in it. */ + +/*** Needs some error checking for the float case ***/ + +static int +parse_number (p, len, parsed_float, putithere) + char *p; + int len; + int parsed_float; + YYSTYPE *putithere; +{ + ULONGEST n = 0; + ULONGEST limit, limit_div_base; + + int c; + int base = input_radix; + + struct type *type; + + if (parsed_float) + { + /* It's a float since it contains a point or an exponent. */ + char c; + int num = 0; /* number of tokens scanned by scanf */ + char saved_char = p[len]; + + p[len] = 0; /* null-terminate the token */ + if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) + num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c); + else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) + num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c); + else + { +#ifdef SCANF_HAS_LONG_DOUBLE + num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c); +#else + /* Scan it into a double, then assign it to the long double. + This at least wins with values representable in the range + of doubles. */ + double temp; + num = sscanf (p, "%lg%c", &temp, &c); + putithere->typed_val_float.dval = temp; +#endif + } + p[len] = saved_char; /* restore the input stream */ + if (num != 1) /* check scanf found ONLY a float ... */ + return ERROR; + /* See if it has `f' or `d' suffix (float or double). */ + + c = tolower (p[len - 1]); + + if (c == 'f' || c == 'F') + putithere->typed_val_float.type = builtin_type_float; + else if (isdigit (c) || c == '.' || c == 'd' || c == 'D') + putithere->typed_val_float.type = builtin_type_double; + else + return ERROR; + + return FLOATING_POINT_LITERAL; + } + + /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ + if (p[0] == '0') + switch (p[1]) + { + case 'x': + case 'X': + if (len >= 3) + { + p += 2; + base = 16; + len -= 2; + } + break; + + case 't': + case 'T': + case 'd': + case 'D': + if (len >= 3) + { + p += 2; + base = 10; + len -= 2; + } + break; + + default: + base = 8; + break; + } + + c = p[len-1]; + /* A paranoid calculation of (1<<64)-1. */ + limit = (ULONGEST)0xffffffff; + limit = ((limit << 16) << 16) | limit; + if (c == 'l' || c == 'L') + { + type = java_long_type; + len--; + } + else + { + type = java_int_type; + } + limit_div_base = limit / (ULONGEST) base; + + while (--len >= 0) + { + c = *p++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + return ERROR; /* Char not a digit */ + if (c >= base) + return ERROR; + if (n > limit_div_base + || (n *= base) > limit - c) + error (_("Numeric constant too large")); + n += c; + } + + /* If the type is bigger than a 32-bit signed integer can be, implicitly + promote to long. Java does not do this, so mark it as builtin_type_uint64 + rather than java_long_type. 0x80000000 will become -0x80000000 instead + of 0x80000000L, because we don't know the sign at this point. + */ + if (type == java_int_type && n > (ULONGEST)0x80000000) + type = builtin_type_uint64; + + putithere->typed_val_int.val = n; + putithere->typed_val_int.type = type; + + return INTEGER_LITERAL; +} + +struct token +{ + char *operator; + int token; + enum exp_opcode opcode; +}; + +static const struct token tokentab3[] = + { + {">>=", ASSIGN_MODIFY, BINOP_RSH}, + {"<<=", ASSIGN_MODIFY, BINOP_LSH} + }; + +static const struct token tokentab2[] = + { + {"+=", ASSIGN_MODIFY, BINOP_ADD}, + {"-=", ASSIGN_MODIFY, BINOP_SUB}, + {"*=", ASSIGN_MODIFY, BINOP_MUL}, + {"/=", ASSIGN_MODIFY, BINOP_DIV}, + {"%=", ASSIGN_MODIFY, BINOP_REM}, + {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR}, + {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND}, + {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR}, + {"++", INCREMENT, BINOP_END}, + {"--", DECREMENT, BINOP_END}, + {"&&", ANDAND, BINOP_END}, + {"||", OROR, BINOP_END}, + {"<<", LSH, BINOP_END}, + {">>", RSH, BINOP_END}, + {"==", EQUAL, BINOP_END}, + {"!=", NOTEQUAL, BINOP_END}, + {"<=", LEQ, BINOP_END}, + {">=", GEQ, BINOP_END} + }; + +/* Read one token, getting characters through lexptr. */ + +static int +yylex () +{ + int c; + int namelen; + unsigned int i; + char *tokstart; + char *tokptr; + int tempbufindex; + static char *tempbuf; + static int tempbufsize; + + retry: + + prev_lexptr = lexptr; + + tokstart = lexptr; + /* See if it is a special token of length 3. */ + for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) + if (strncmp (tokstart, tokentab3[i].operator, 3) == 0) + { + lexptr += 3; + yylval.opcode = tokentab3[i].opcode; + return tokentab3[i].token; + } + + /* See if it is a special token of length 2. */ + for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) + if (strncmp (tokstart, tokentab2[i].operator, 2) == 0) + { + lexptr += 2; + yylval.opcode = tokentab2[i].opcode; + return tokentab2[i].token; + } + + switch (c = *tokstart) + { + case 0: + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '\'': + /* We either have a character constant ('0' or '\177' for example) + or we have a quoted symbol reference ('foo(int,int)' in C++ + for example). */ + lexptr++; + c = *lexptr++; + if (c == '\\') + c = parse_escape (&lexptr); + else if (c == '\'') + error (_("Empty character constant")); + + yylval.typed_val_int.val = c; + yylval.typed_val_int.type = java_char_type; + + c = *lexptr++; + if (c != '\'') + { + namelen = skip_quoted (tokstart) - tokstart; + if (namelen > 2) + { + lexptr = tokstart + namelen; + if (lexptr[-1] != '\'') + error (_("Unmatched single quote")); + namelen -= 2; + tokstart++; + goto tryname; + } + error (_("Invalid character constant")); + } + return INTEGER_LITERAL; + + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return c; + + case '.': + /* Might be a floating point number. */ + if (lexptr[1] < '0' || lexptr[1] > '9') + goto symbol; /* Nope, must be a symbol. */ + /* FALL THRU into number case. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + /* It's a number. */ + int got_dot = 0, got_e = 0, toktype; + char *p = tokstart; + int hex = input_radix > 10; + + if (c == '0' && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + hex = 1; + } + else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) + { + p += 2; + hex = 0; + } + + for (;; ++p) + { + /* This test includes !hex because 'e' is a valid hex digit + and thus does not indicate a floating point number when + the radix is hex. */ + if (!hex && !got_e && (*p == 'e' || *p == 'E')) + got_dot = got_e = 1; + /* This test does not include !hex, because a '.' always indicates + a decimal floating point number regardless of the radix. */ + else if (!got_dot && *p == '.') + got_dot = 1; + else if (got_e && (p[-1] == 'e' || p[-1] == 'E') + && (*p == '-' || *p == '+')) + /* This is the sign of the exponent, not the end of the + number. */ + continue; + /* We will take any letters or digits. parse_number will + complain if past the radix, or if L or U are not final. */ + else if ((*p < '0' || *p > '9') + && ((*p < 'a' || *p > 'z') + && (*p < 'A' || *p > 'Z'))) + break; + } + toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval); + if (toktype == ERROR) + { + char *err_copy = (char *) alloca (p - tokstart + 1); + + memcpy (err_copy, tokstart, p - tokstart); + err_copy[p - tokstart] = 0; + error (_("Invalid number \"%s\""), err_copy); + } + lexptr = p; + return toktype; + } + + case '+': + case '-': + case '*': + case '/': + case '%': + case '|': + case '&': + case '^': + case '~': + case '!': + case '<': + case '>': + case '[': + case ']': + case '?': + case ':': + case '=': + case '{': + case '}': + symbol: + lexptr++; + return c; + + case '"': + + /* Build the gdb internal form of the input string in tempbuf, + translating any standard C escape forms seen. Note that the + buffer is null byte terminated *only* for the convenience of + debugging gdb itself and printing the buffer contents when + the buffer contains no embedded nulls. Gdb does not depend + upon the buffer being null byte terminated, it uses the length + string instead. This allows gdb to handle C strings (as well + as strings in other languages) with embedded null bytes */ + + tokptr = ++tokstart; + tempbufindex = 0; + + do { + /* Grow the static temp buffer if necessary, including allocating + the first one on demand. */ + if (tempbufindex + 1 >= tempbufsize) + { + tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64); + } + switch (*tokptr) + { + case '\0': + case '"': + /* Do nothing, loop will terminate. */ + break; + case '\\': + tokptr++; + c = parse_escape (&tokptr); + if (c == -1) + { + continue; + } + tempbuf[tempbufindex++] = c; + break; + default: + tempbuf[tempbufindex++] = *tokptr++; + break; + } + } while ((*tokptr != '"') && (*tokptr != '\0')); + if (*tokptr++ != '"') + { + error (_("Unterminated string in expression")); + } + tempbuf[tempbufindex] = '\0'; /* See note above */ + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = tokptr; + return (STRING_LITERAL); + } + + if (!(c == '_' || c == '$' + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + /* We must have come across a bad character (e.g. ';'). */ + error (_("Invalid character '%c' in expression"), c); + + /* It's a name. See how long it is. */ + namelen = 0; + for (c = tokstart[namelen]; + (c == '_' + || c == '$' + || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || c == '<'); + ) + { + if (c == '<') + { + int i = namelen; + while (tokstart[++i] && tokstart[i] != '>'); + if (tokstart[i] == '>') + namelen = i; + } + c = tokstart[++namelen]; + } + + /* The token "if" terminates the expression and is NOT + removed from the input stream. */ + if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') + { + return 0; + } + + lexptr += namelen; + + tryname: + + /* Catch specific keywords. Should be done with a data structure. */ + switch (namelen) + { + case 7: + if (DEPRECATED_STREQN (tokstart, "boolean", 7)) + return BOOLEAN; + break; + case 6: + if (DEPRECATED_STREQN (tokstart, "double", 6)) + return DOUBLE; + break; + case 5: + if (DEPRECATED_STREQN (tokstart, "short", 5)) + return SHORT; + if (DEPRECATED_STREQN (tokstart, "false", 5)) + { + yylval.lval = 0; + return BOOLEAN_LITERAL; + } + if (DEPRECATED_STREQN (tokstart, "super", 5)) + return SUPER; + if (DEPRECATED_STREQN (tokstart, "float", 5)) + return FLOAT; + break; + case 4: + if (DEPRECATED_STREQN (tokstart, "long", 4)) + return LONG; + if (DEPRECATED_STREQN (tokstart, "byte", 4)) + return BYTE; + if (DEPRECATED_STREQN (tokstart, "char", 4)) + return CHAR; + if (DEPRECATED_STREQN (tokstart, "true", 4)) + { + yylval.lval = 1; + return BOOLEAN_LITERAL; + } + break; + case 3: + if (strncmp (tokstart, "int", 3) == 0) + return INT; + if (strncmp (tokstart, "new", 3) == 0) + return NEW; + break; + default: + break; + } + + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + if (*tokstart == '$') + { + write_dollar_variable (yylval.sval); + return VARIABLE; + } + + /* Input names that aren't symbols but ARE valid hex numbers, + when the input radix permits them, can be names or numbers + depending on the parse. Note we support radixes > 16 here. */ + if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || + (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) + { + YYSTYPE newlval; /* Its value is ignored. */ + int hextype = parse_number (tokstart, namelen, 0, &newlval); + if (hextype == INTEGER_LITERAL) + return NAME_OR_INT; + } + return IDENTIFIER; +} + +void +yyerror (msg) + char *msg; +{ + if (prev_lexptr) + lexptr = prev_lexptr; + + if (msg) + error (_("%s: near `%s'"), msg, lexptr); + else + error (_("error in expression, near `%s'"), lexptr); +} + +static struct type * +java_type_from_name (name) + struct stoken name; + +{ + char *tmp = copy_name (name); + struct type *typ = java_lookup_class (tmp); + if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT) + error (_("No class named `%s'"), tmp); + return typ; +} + +/* If NAME is a valid variable name in this scope, push it and return 1. + Otherwise, return 0. */ + +static int +push_variable (struct stoken name) +{ + char *tmp = copy_name (name); + int is_a_field_of_this = 0; + struct symbol *sym; + sym = lookup_symbol (tmp, expression_context_block, VAR_DOMAIN, + &is_a_field_of_this, (struct symtab **) NULL); + if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF) + { + if (symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block_found, innermost_block)) + innermost_block = block_found; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not another more inner frame + which happens to be in the same block. */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + return 1; + } + if (is_a_field_of_this) + { + /* it hangs off of `this'. Must not inadvertently convert from a + method call to data ref. */ + if (innermost_block == 0 || + contained_in (block_found, innermost_block)) + innermost_block = block_found; + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string (name); + write_exp_elt_opcode (STRUCTOP_PTR); + return 1; + } + return 0; +} + +/* Assuming a reference expression has been pushed, emit the + STRUCTOP_STRUCT ops to access the field named NAME. If NAME is a + qualified name (has '.'), generate a field access for each part. */ + +static void +push_fieldnames (name) + struct stoken name; +{ + int i; + struct stoken token; + token.ptr = name.ptr; + for (i = 0; ; i++) + { + if (i == name.length || name.ptr[i] == '.') + { + /* token.ptr is start of current field name. */ + token.length = &name.ptr[i] - token.ptr; + write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (token); + write_exp_elt_opcode (STRUCTOP_STRUCT); + token.ptr += token.length + 1; + } + if (i >= name.length) + break; + } +} + +/* Helper routine for push_expression_name. + Handle a qualified name, where DOT_INDEX is the index of the first '.' */ + +static void +push_qualified_expression_name (struct stoken name, int dot_index) +{ + struct stoken token; + char *tmp; + struct type *typ; + + token.ptr = name.ptr; + token.length = dot_index; + + if (push_variable (token)) + { + token.ptr = name.ptr + dot_index + 1; + token.length = name.length - dot_index - 1; + push_fieldnames (token); + return; + } + + token.ptr = name.ptr; + for (;;) + { + token.length = dot_index; + tmp = copy_name (token); + typ = java_lookup_class (tmp); + if (typ != NULL) + { + if (dot_index == name.length) + { + write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(typ); + write_exp_elt_opcode(OP_TYPE); + return; + } + dot_index++; /* Skip '.' */ + name.ptr += dot_index; + name.length -= dot_index; + dot_index = 0; + while (dot_index < name.length && name.ptr[dot_index] != '.') + dot_index++; + token.ptr = name.ptr; + token.length = dot_index; + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (typ); + write_exp_string (token); + write_exp_elt_opcode (OP_SCOPE); + if (dot_index < name.length) + { + dot_index++; + name.ptr += dot_index; + name.length -= dot_index; + push_fieldnames (name); + } + return; + } + else if (dot_index >= name.length) + break; + dot_index++; /* Skip '.' */ + while (dot_index < name.length && name.ptr[dot_index] != '.') + dot_index++; + } + error (_("unknown type `%.*s'"), name.length, name.ptr); +} + +/* Handle Name in an expression (or LHS). + Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */ + +static void +push_expression_name (name) + struct stoken name; +{ + char *tmp; + struct type *typ; + char *ptr; + int i; + + for (i = 0; i < name.length; i++) + { + if (name.ptr[i] == '.') + { + /* It's a Qualified Expression Name. */ + push_qualified_expression_name (name, i); + return; + } + } + + /* It's a Simple Expression Name. */ + + if (push_variable (name)) + return; + tmp = copy_name (name); + typ = java_lookup_class (tmp); + if (typ != NULL) + { + write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(typ); + write_exp_elt_opcode(OP_TYPE); + } + else + { + struct minimal_symbol *msymbol; + + msymbol = lookup_minimal_symbol (tmp, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (!have_full_symbols () && !have_partial_symbols ()) + error (_("No symbol table is loaded. Use the \"file\" command")); + else + error (_("No symbol \"%s\" in current context"), tmp); + } + +} + + +/* The following two routines, copy_exp and insert_exp, aren't specific to + Java, so they could go in parse.c, but their only purpose is to support + the parsing kludges we use in this file, so maybe it's best to isolate + them here. */ + +/* Copy the expression whose last element is at index ENDPOS - 1 in EXPR + into a freshly xmalloc'ed struct expression. Its language_defn is set + to null. */ +static struct expression * +copy_exp (expr, endpos) + struct expression *expr; + int endpos; +{ + int len = length_of_subexp (expr, endpos); + struct expression *new + = (struct expression *) xmalloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len)); + new->nelts = len; + memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len)); + new->language_defn = 0; + + return new; +} + +/* Insert the expression NEW into the current expression (expout) at POS. */ +static void +insert_exp (pos, new) + int pos; + struct expression *new; +{ + int newlen = new->nelts; + + /* Grow expout if necessary. In this function's only use at present, + this should never be necessary. */ + if (expout_ptr + newlen > expout_size) + { + expout_size = max (expout_size * 2, expout_ptr + newlen + 10); + expout = (struct expression *) + xrealloc ((char *) expout, (sizeof (struct expression) + + EXP_ELEM_TO_BYTES (expout_size))); + } + + { + int i; + + for (i = expout_ptr - 1; i >= pos; i--) + expout->elts[i + newlen] = expout->elts[i]; + } + + memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen)); + expout_ptr += newlen; +} + + diff --git a/contrib/gdb/gdb/jv-exp.y b/contrib/gdb/gdb/jv-exp.y index 1b80ab45827..41da7d0f3fd 100644 --- a/contrib/gdb/gdb/jv-exp.y +++ b/contrib/gdb/gdb/jv-exp.y @@ -48,6 +48,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" /* Required by objfiles.h. */ #include "symfile.h" /* Required by objfiles.h. */ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), as well as gratuitiously global symbol names, so we can have multiple @@ -85,6 +86,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yylloc java_lloc #define yyreds java_reds /* With YYDEBUG defined */ #define yytoks java_toks /* With YYDEBUG defined */ +#define yyname java_name /* With YYDEBUG defined */ +#define yyrule java_rule /* With YYDEBUG defined */ #define yylhs java_yylhs #define yylen java_yylen #define yydefred java_yydefred @@ -96,9 +99,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yycheck java_yycheck #ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ +#define YYDEBUG 1 /* Default to yydebug support */ #endif +#define YYFPRINTF parser_fprintf + int yyparse (void); static int yylex (void); @@ -175,7 +180,7 @@ static int parse_number (char *, int, int, YYSTYPE *); %token ASSIGN_MODIFY -%token THIS SUPER NEW +%token SUPER NEW %left ',' %right '=' ASSIGN_MODIFY @@ -361,9 +366,6 @@ Primary: PrimaryNoNewArray: Literal -| THIS - { write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); } | '(' Expression ')' | ClassInstanceCreationExpression | FieldAccess @@ -388,7 +390,8 @@ rcurly: ClassInstanceCreationExpression: NEW ClassType '(' ArgumentList_opt ')' - { error ("FIXME - ClassInstanceCreationExpression"); } + { internal_error (__FILE__, __LINE__, + _("FIXME - ClassInstanceCreationExpression")); } ; ArgumentList: @@ -406,9 +409,11 @@ ArgumentList_opt: ArrayCreationExpression: NEW PrimitiveType DimExprs Dims_opt - { error ("FIXME - ArrayCreatiionExpression"); } + { internal_error (__FILE__, __LINE__, + _("FIXME - ArrayCreationExpression")); } | NEW ClassOrInterfaceType DimExprs Dims_opt - { error ("FIXME - ArrayCreatiionExpression"); } + { internal_error (__FILE__, __LINE__, + _("FIXME - ArrayCreationExpression")); } ; DimExprs: @@ -443,11 +448,11 @@ FieldAccess: MethodInvocation: Name '(' ArgumentList_opt ')' - { error ("method invocation not implemented"); } + { error (_("Method invocation not implemented")); } | Primary '.' SimpleName '(' ArgumentList_opt ')' - { error ("method invocation not implemented"); } + { error (_("Method invocation not implemented")); } | SUPER '.' SimpleName '(' ArgumentList_opt ')' - { error ("method invocation not implemented"); } + { error (_("Method invocation not implemented")); } ; ArrayAccess: @@ -537,7 +542,7 @@ CastExpression: int i; int base = expout_ptr - last_exp_size - 3; if (base < 0 || expout->elts[base+2].opcode != OP_TYPE) - error ("invalid cast expression"); + error (_("Invalid cast expression")); type = expout->elts[base+1].type; /* Remove the 'Expression' and slide the UnaryExpressionNotPlusMinus down to replace it. */ @@ -677,16 +682,16 @@ Expression: static int parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; + char *p; + int len; int parsed_float; YYSTYPE *putithere; { - register ULONGEST n = 0; + ULONGEST n = 0; ULONGEST limit, limit_div_base; - register int c; - register int base = input_radix; + int c; + int base = input_radix; struct type *type; @@ -793,7 +798,7 @@ parse_number (p, len, parsed_float, putithere) return ERROR; if (n > limit_div_base || (n *= base) > limit - c) - error ("Numeric constant too large."); + error (_("Numeric constant too large")); n += c; } @@ -862,10 +867,12 @@ yylex () retry: + prev_lexptr = lexptr; + tokstart = lexptr; /* See if it is a special token of length 3. */ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) - if (STREQN (tokstart, tokentab3[i].operator, 3)) + if (strncmp (tokstart, tokentab3[i].operator, 3) == 0) { lexptr += 3; yylval.opcode = tokentab3[i].opcode; @@ -874,7 +881,7 @@ yylex () /* See if it is a special token of length 2. */ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) - if (STREQN (tokstart, tokentab2[i].operator, 2)) + if (strncmp (tokstart, tokentab2[i].operator, 2) == 0) { lexptr += 2; yylval.opcode = tokentab2[i].opcode; @@ -901,7 +908,7 @@ yylex () if (c == '\\') c = parse_escape (&lexptr); else if (c == '\'') - error ("Empty character constant."); + error (_("Empty character constant")); yylval.typed_val_int.val = c; yylval.typed_val_int.type = java_char_type; @@ -914,12 +921,12 @@ yylex () { lexptr = tokstart + namelen; if (lexptr[-1] != '\'') - error ("Unmatched single quote."); + error (_("Unmatched single quote")); namelen -= 2; tokstart++; goto tryname; } - error ("Invalid character constant."); + error (_("Invalid character constant")); } return INTEGER_LITERAL; @@ -960,7 +967,7 @@ yylex () { /* It's a number. */ int got_dot = 0, got_e = 0, toktype; - register char *p = tokstart; + char *p = tokstart; int hex = input_radix > 10; if (c == '0' && (p[1] == 'x' || p[1] == 'X')) @@ -1004,7 +1011,7 @@ yylex () memcpy (err_copy, tokstart, p - tokstart); err_copy[p - tokstart] = 0; - error ("Invalid number \"%s\".", err_copy); + error (_("Invalid number \"%s\""), err_copy); } lexptr = p; return toktype; @@ -1076,7 +1083,7 @@ yylex () } while ((*tokptr != '"') && (*tokptr != '\0')); if (*tokptr++ != '"') { - error ("Unterminated string in expression."); + error (_("Unterminated string in expression")); } tempbuf[tempbufindex] = '\0'; /* See note above */ yylval.sval.ptr = tempbuf; @@ -1088,7 +1095,7 @@ yylex () if (!(c == '_' || c == '$' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) /* We must have come across a bad character (e.g. ';'). */ - error ("Invalid character '%c' in expression.", c); + error (_("Invalid character '%c' in expression"), c); /* It's a name. See how long it is. */ namelen = 0; @@ -1126,54 +1133,43 @@ yylex () switch (namelen) { case 7: - if (STREQN (tokstart, "boolean", 7)) + if (DEPRECATED_STREQN (tokstart, "boolean", 7)) return BOOLEAN; break; case 6: - if (STREQN (tokstart, "double", 6)) + if (DEPRECATED_STREQN (tokstart, "double", 6)) return DOUBLE; break; case 5: - if (STREQN (tokstart, "short", 5)) + if (DEPRECATED_STREQN (tokstart, "short", 5)) return SHORT; - if (STREQN (tokstart, "false", 5)) + if (DEPRECATED_STREQN (tokstart, "false", 5)) { yylval.lval = 0; return BOOLEAN_LITERAL; } - if (STREQN (tokstart, "super", 5)) + if (DEPRECATED_STREQN (tokstart, "super", 5)) return SUPER; - if (STREQN (tokstart, "float", 5)) + if (DEPRECATED_STREQN (tokstart, "float", 5)) return FLOAT; break; case 4: - if (STREQN (tokstart, "long", 4)) + if (DEPRECATED_STREQN (tokstart, "long", 4)) return LONG; - if (STREQN (tokstart, "byte", 4)) + if (DEPRECATED_STREQN (tokstart, "byte", 4)) return BYTE; - if (STREQN (tokstart, "char", 4)) + if (DEPRECATED_STREQN (tokstart, "char", 4)) return CHAR; - if (STREQN (tokstart, "true", 4)) + if (DEPRECATED_STREQN (tokstart, "true", 4)) { yylval.lval = 1; return BOOLEAN_LITERAL; } - if (current_language->la_language == language_cplus - && STREQN (tokstart, "this", 4)) - { - static const char this_name[] = - { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' }; - - if (lookup_symbol (this_name, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL)) - return THIS; - } break; case 3: - if (STREQN (tokstart, "int", 3)) + if (strncmp (tokstart, "int", 3) == 0) return INT; - if (STREQN (tokstart, "new", 3)) + if (strncmp (tokstart, "new", 3) == 0) return NEW; break; default: @@ -1207,7 +1203,13 @@ void yyerror (msg) char *msg; { - error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); + if (prev_lexptr) + lexptr = prev_lexptr; + + if (msg) + error (_("%s: near `%s'"), msg, lexptr); + else + error (_("error in expression, near `%s'"), lexptr); } static struct type * @@ -1218,7 +1220,7 @@ java_type_from_name (name) char *tmp = copy_name (name); struct type *typ = java_lookup_class (tmp); if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT) - error ("No class named %s.", tmp); + error (_("No class named `%s'"), tmp); return typ; } @@ -1226,14 +1228,12 @@ java_type_from_name (name) Otherwise, return 0. */ static int -push_variable (name) - struct stoken name; - +push_variable (struct stoken name) { char *tmp = copy_name (name); int is_a_field_of_this = 0; struct symbol *sym; - sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE, + sym = lookup_symbol (tmp, expression_context_block, VAR_DOMAIN, &is_a_field_of_this, (struct symtab **) NULL); if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF) { @@ -1300,9 +1300,7 @@ push_fieldnames (name) Handle a qualified name, where DOT_INDEX is the index of the first '.' */ static void -push_qualified_expression_name (name, dot_index) - struct stoken name; - int dot_index; +push_qualified_expression_name (struct stoken name, int dot_index) { struct stoken token; char *tmp; @@ -1361,7 +1359,7 @@ push_qualified_expression_name (name, dot_index) while (dot_index < name.length && name.ptr[dot_index] != '.') dot_index++; } - error ("unknown type `%.*s'", name.length, name.ptr); + error (_("unknown type `%.*s'"), name.length, name.ptr); } /* Handle Name in an expression (or LHS). @@ -1410,9 +1408,9 @@ push_expression_name (name) builtin_type_int); } else if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); + error (_("No symbol table is loaded. Use the \"file\" command")); else - error ("No symbol \"%s\" in current context.", tmp); + error (_("No symbol \"%s\" in current context"), tmp); } } diff --git a/contrib/gdb/gdb/jv-lang.c b/contrib/gdb/gdb/jv-lang.c index e221105ed6f..6db6e88efa5 100644 --- a/contrib/gdb/gdb/jv-lang.c +++ b/contrib/gdb/gdb/jv-lang.c @@ -1,5 +1,5 @@ /* Java language support routines for GDB, the GNU debugger. - Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright 1997, 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -33,6 +33,9 @@ #include "c-lang.h" #include "jv-lang.h" #include "gdbcore.h" +#include "block.h" +#include "demangle.h" +#include "dictionary.h" #include struct type *java_int_type; @@ -55,7 +58,6 @@ static void java_demangled_signature_copy (char *, char *); static struct symtab *get_java_class_symtab (void); static char *get_java_utf8_name (struct obstack *obstack, struct value *name); static int java_class_is_primitive (struct value *clas); -static struct type *java_lookup_type (char *signature); static struct value *java_value_string (char *ptr, int len); static void java_emit_char (int c, struct ui_file * stream, int quoter); @@ -68,6 +70,12 @@ static struct objfile *dynamics_objfile = NULL; static struct type *java_link_class_type (struct type *, struct value *); +/* FIXME: carlton/2003-02-04: This is the main or only caller of + allocate_objfile with first argument NULL; as a result, this code + breaks every so often. Somebody should write a test case that + exercises GDB in various ways (e.g. something involving loading a + dynamic library) after this code has been called. */ + static struct objfile * get_dynamics_objfile (void) { @@ -83,9 +91,7 @@ get_dynamics_objfile (void) static struct symtab *class_symtab = NULL; -/* Maximum number of class in class_symtab before relocation is needed. */ - -static int class_symtab_space; +static void free_class_block (struct symtab *symtab); static struct symtab * get_java_class_symtab (void) @@ -98,29 +104,22 @@ get_java_class_symtab (void) class_symtab = allocate_symtab ("", objfile); class_symtab->language = language_java; bv = (struct blockvector *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector)); + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct blockvector) + sizeof (struct block *)); BLOCKVECTOR_NBLOCKS (bv) = 1; BLOCKVECTOR (class_symtab) = bv; /* Allocate dummy STATIC_BLOCK. */ - bl = (struct block *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct block)); - BLOCK_NSYMS (bl) = 0; - BLOCK_START (bl) = 0; - BLOCK_END (bl) = 0; - BLOCK_FUNCTION (bl) = NULL; - BLOCK_SUPERBLOCK (bl) = NULL; - BLOCK_GCC_COMPILED (bl) = 0; + bl = allocate_block (&objfile->objfile_obstack); + BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack, + NULL); BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl; - /* Allocate GLOBAL_BLOCK. This has to be relocatable. */ - class_symtab_space = 128; - bl = xmmalloc (objfile->md, - sizeof (struct block) - + ((class_symtab_space - 1) * sizeof (struct symbol *))); - *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + /* Allocate GLOBAL_BLOCK. */ + bl = allocate_block (&objfile->objfile_obstack); + BLOCK_DICT (bl) = dict_create_hashed_expandable (); BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl; - class_symtab->free_ptr = (char *) bl; + class_symtab->free_func = free_class_block; } return class_symtab; } @@ -130,20 +129,7 @@ add_class_symtab_symbol (struct symbol *sym) { struct symtab *symtab = get_java_class_symtab (); struct blockvector *bv = BLOCKVECTOR (symtab); - struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - if (BLOCK_NSYMS (bl) >= class_symtab_space) - { - /* Need to re-allocate. */ - class_symtab_space *= 2; - bl = xmrealloc (symtab->objfile->md, bl, - sizeof (struct block) - + ((class_symtab_space - 1) * sizeof (struct symbol *))); - class_symtab->free_ptr = (char *) bl; - BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl; - } - - BLOCK_SYM (bl, BLOCK_NSYMS (bl)) = sym; - BLOCK_NSYMS (bl) = BLOCK_NSYMS (bl) + 1; + dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)), sym); } static struct symbol *add_class_symbol (struct type *type, CORE_ADDR addr); @@ -153,24 +139,34 @@ add_class_symbol (struct type *type, CORE_ADDR addr) { struct symbol *sym; sym = (struct symbol *) - obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&dynamics_objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); SYMBOL_LANGUAGE (sym) = language_java; - SYMBOL_NAME (sym) = TYPE_TAG_NAME (type); + DEPRECATED_SYMBOL_NAME (sym) = TYPE_TAG_NAME (type); SYMBOL_CLASS (sym) = LOC_TYPEDEF; /* SYMBOL_VALUE (sym) = valu; */ SYMBOL_TYPE (sym) = type; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; SYMBOL_VALUE_ADDRESS (sym) = addr; return sym; } + +/* Free the dynamic symbols block. */ +static void +free_class_block (struct symtab *symtab) +{ + struct blockvector *bv = BLOCKVECTOR (symtab); + struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + + dict_free (BLOCK_DICT (bl)); +} #endif struct type * java_lookup_class (char *name) { struct symbol *sym; - sym = lookup_symbol (name, expression_context_block, STRUCT_NAMESPACE, + sym = lookup_symbol (name, expression_context_block, STRUCT_DOMAIN, (int *) 0, (struct symtab **) NULL); if (sym != NULL) return SYMBOL_TYPE (sym); @@ -190,7 +186,7 @@ java_lookup_class (char *name) type = alloc_type (objfile); TYPE_CODE (type) = TYPE_CODE_STRUCT; INIT_CPLUS_SPECIFIC (type); - TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), &objfile->type_obstack); + TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), &objfile->objfile_obstack); TYPE_FLAGS (type) |= TYPE_FLAG_STUB; TYPE ? = addr; return type; @@ -258,7 +254,7 @@ type_from_class (struct value *clas) char *nptr; CORE_ADDR addr; struct block *bl; - int i; + struct dict_iterator iter; int is_array = 0; type = check_typedef (VALUE_TYPE (clas)); @@ -273,9 +269,8 @@ type_from_class (struct value *clas) #if 0 get_java_class_symtab (); bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK); - for (i = BLOCK_NSYMS (bl); --i >= 0;) + ALL_BLOCK_SYMBOLS (block, iter, sym) { - struct symbol *sym = BLOCK_SYM (bl, i); if (SYMBOL_VALUE_ADDRESS (sym) == addr) return SYMBOL_TYPE (sym); } @@ -294,7 +289,7 @@ type_from_class (struct value *clas) /* if clasloader non-null, prepend loader address. FIXME */ temp = clas; utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure"); - name = get_java_utf8_name (&objfile->type_obstack, utf8_name); + name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name); for (nptr = name; *nptr != 0; nptr++) { if (*nptr == '/') @@ -314,7 +309,7 @@ type_from_class (struct value *clas) char *signature = name; int namelen = java_demangled_signature_length (signature); if (namelen > strlen (name)) - name = obstack_alloc (&objfile->type_obstack, namelen + 1); + name = obstack_alloc (&objfile->objfile_obstack, namelen + 1); java_demangled_signature_copy (name, signature); name[namelen] = '\0'; is_array = 1; @@ -447,7 +442,7 @@ java_link_class_type (struct type *type, struct value *clas) temp = field; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); TYPE_FIELD_NAME (type, i) = - get_java_utf8_name (&objfile->type_obstack, temp); + get_java_utf8_name (&objfile->objfile_obstack, temp); temp = field; accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags", NULL, "structure")); @@ -493,7 +488,7 @@ java_link_class_type (struct type *type, struct value *clas) TYPE_NFN_FIELDS_TOTAL (type) = nmethods; j = nmethods * sizeof (struct fn_field); fn_fields = (struct fn_field *) - obstack_alloc (&dynamics_objfile->symbol_obstack, j); + obstack_alloc (&dynamics_objfile->objfile_obstack, j); memset (fn_fields, 0, j); fn_fieldlists = (struct fn_fieldlist *) alloca (nmethods * sizeof (struct fn_fieldlist)); @@ -518,7 +513,7 @@ java_link_class_type (struct type *type, struct value *clas) /* Get method name. */ temp = method; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); - mname = get_java_utf8_name (&objfile->type_obstack, temp); + mname = get_java_utf8_name (&objfile->objfile_obstack, temp); if (strcmp (mname, "") == 0) mname = unqualified_name; @@ -543,7 +538,7 @@ java_link_class_type (struct type *type, struct value *clas) { /* Found an existing method with the same name. */ int l; if (mname != unqualified_name) - obstack_free (&objfile->type_obstack, mname); + obstack_free (&objfile->objfile_obstack, mname); mname = fn_fieldlists[j].name; fn_fieldlists[j].length++; k = i - k; /* Index of new slot. */ @@ -564,7 +559,7 @@ java_link_class_type (struct type *type, struct value *clas) j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist); TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) - obstack_alloc (&dynamics_objfile->symbol_obstack, j); + obstack_alloc (&dynamics_objfile->objfile_obstack, j); memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j); return type; @@ -578,7 +573,7 @@ get_java_object_type (void) if (java_object_type == NULL) { struct symbol *sym; - sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_NAMESPACE, + sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_DOMAIN, (int *) 0, (struct symtab **) NULL); if (sym == NULL) error ("cannot find java.lang.Object"); @@ -768,19 +763,6 @@ java_demangle_type_signature (char *signature) return result; } -struct type * -java_lookup_type (char *signature) -{ - switch (signature[0]) - { - case 'L': - case '[': - error ("java_lookup_type not fully implemented"); - default: - return java_primitive_type (signature[0]); - } -} - /* Return the type of TYPE followed by DIMS pairs of [ ]. If DIMS == 0, TYPE is returned. */ @@ -845,8 +827,8 @@ java_emit_char (int c, struct ui_file *stream, int quoter) } static struct value * -evaluate_subexp_java (struct type *expect_type, register struct expression *exp, - register int *pos, enum noside noside) +evaluate_subexp_java (struct type *expect_type, struct expression *exp, + int *pos, enum noside noside) { int pc = *pos; int i; @@ -988,6 +970,12 @@ java_create_fundamental_type (struct objfile *objfile, int typeid) return c_create_fundamental_type (objfile, typeid); } +static char *java_demangle (const char *mangled, int options) +{ + return cplus_demangle (mangled, options | DMGL_JAVA); +} + + /* Table mapping opcodes into strings for printing operators and precedences of the operators. */ @@ -1028,6 +1016,15 @@ const struct op_print java_op_print_tab[] = {NULL, 0, 0, 0} }; +const struct exp_descriptor exp_descriptor_java = +{ + print_subexp_standard, + operator_length_standard, + op_name_standard, + dump_subexp_body_standard, + evaluate_subexp_java +}; + const struct language_defn java_language_defn = { "java", /* Language name */ @@ -1036,9 +1033,9 @@ const struct language_defn java_language_defn = range_check_off, type_check_off, case_sensitive_on, + &exp_descriptor_java, java_parse, java_error, - evaluate_subexp_java, c_printchar, /* Print a character constant */ c_printstr, /* Function to print string constant */ java_emit_char, /* Function to print a single character */ @@ -1046,6 +1043,11 @@ const struct language_defn java_language_defn = java_print_type, /* Print a type using appropriate syntax */ java_val_print, /* Print a value using appropriate syntax */ java_value_print, /* Print a top-level value */ + NULL, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + java_demangle, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -1054,6 +1056,7 @@ const struct language_defn java_language_defn = 0, /* not c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; diff --git a/contrib/gdb/gdb/jv-typeprint.c b/contrib/gdb/gdb/jv-typeprint.c index 893082cc187..18bfc32b385 100644 --- a/contrib/gdb/gdb/jv-typeprint.c +++ b/contrib/gdb/gdb/jv-typeprint.c @@ -86,8 +86,8 @@ static void java_type_print_base (struct type *type, struct ui_file *stream, int show, int level) { - register int i; - register int len; + int i; + int len; char *mangled_name; char *demangled_name; QUIT; @@ -166,12 +166,12 @@ java_type_print_base (struct type *type, struct ui_file *stream, int show, { QUIT; /* Don't print out virtual function table. */ - if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5) + if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0 && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; /* Don't print the dummy field "class". */ - if (STREQN (TYPE_FIELD_NAME (type, i), "class", 5)) + if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0) continue; print_spaces_filtered (level + 4, stream); @@ -216,7 +216,7 @@ java_type_print_base (struct type *type, struct ui_file *stream, int show, n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i); method_name = TYPE_FN_FIELDLIST_NAME (type, i); name = type_name_no_tag (type); - is_constructor = name && STREQ (method_name, name); + is_constructor = name && strcmp (method_name, name) == 0; for (j = 0; j < n_overloads; j++) { diff --git a/contrib/gdb/gdb/jv-valprint.c b/contrib/gdb/gdb/jv-valprint.c index 73fff27199b..87152576141 100644 --- a/contrib/gdb/gdb/jv-valprint.c +++ b/contrib/gdb/gdb/jv-valprint.c @@ -1,5 +1,7 @@ /* Support for printing Java values for GDB, the GNU debugger. - Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -30,6 +32,7 @@ #include "jv-lang.h" #include "c-lang.h" #include "annotate.h" +#include "gdb_string.h" /* Local functions */ @@ -109,14 +112,22 @@ java_value_print (struct value *val, struct ui_file *stream, int format, { read_memory (address, buf, sizeof (buf)); address += TARGET_PTR_BIT / HOST_CHAR_BIT; - element = extract_address (buf, sizeof (buf)); + /* FIXME: cagney/2003-05-24: Bogus or what. It + pulls a host sized pointer out of the target and + then extracts that as an address (while assuming + that the address is unsigned)! */ + element = extract_unsigned_integer (buf, sizeof (buf)); } for (reps = 1; i + reps < length; reps++) { read_memory (address, buf, sizeof (buf)); address += TARGET_PTR_BIT / HOST_CHAR_BIT; - next_element = extract_address (buf, sizeof (buf)); + /* FIXME: cagney/2003-05-24: Bogus or what. It + pulls a host sized pointer out of the target and + then extracts that as an address (while assuming + that the address is unsigned)! */ + next_element = extract_unsigned_integer (buf, sizeof (buf)); if (next_element != element) break; } @@ -198,8 +209,9 @@ java_value_print (struct value *val, struct ui_file *stream, int format, if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_TARGET_TYPE (type) - && TYPE_NAME (TYPE_TARGET_TYPE (type)) - && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0 + && TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)) + && strcmp (TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)), + "java.lang.String") == 0 && (format == 0 || format == 's') && address != 0 && value_as_address (val) != 0) @@ -288,9 +300,6 @@ java_print_value_fields (struct type *type, char *valaddr, CORE_ADDR address, java_print_value_fields (baseclass, base_valaddr, address + boffset, stream, format, recurse + 1, pretty); fputs_filtered (", ", stream); - - flush_it: - ; } } @@ -299,7 +308,6 @@ java_print_value_fields (struct type *type, char *valaddr, CORE_ADDR address, fprintf_filtered (stream, ""); else { - extern int inspect_it; int fields_seen = 0; for (i = n_baseclasses; i < len; i++) @@ -448,7 +456,7 @@ java_val_print (struct type *type, char *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { - register unsigned int i = 0; /* Number of characters printed */ + unsigned int i = 0; /* Number of characters printed */ struct type *target_type; CORE_ADDR addr; @@ -467,7 +475,8 @@ java_val_print (struct type *type, char *valaddr, int embedded_offset, /* 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)), + /* Extract an address, assume that it is unsigned. */ + print_address_demangle (extract_unsigned_integer (valaddr, TYPE_LENGTH (type)), stream, demangle); break; } @@ -497,18 +506,17 @@ java_val_print (struct type *type, char *valaddr, int embedded_offset, return i; case TYPE_CODE_CHAR: - format = format ? format : output_format; - if (format) - print_scalar_formatted (valaddr, type, format, 0, stream); - else - LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream); - break; - case TYPE_CODE_INT: - /* Can't just call c_val_print because that print bytes as C chars. */ + /* Can't just call c_val_print because that prints bytes as C + chars. */ format = format ? format : output_format; if (format) print_scalar_formatted (valaddr, type, format, 0, stream); + else if (TYPE_CODE (type) == TYPE_CODE_CHAR + || (TYPE_CODE (type) == TYPE_CODE_INT + && TYPE_LENGTH (type) == 2 + && strcmp (TYPE_NAME (type), "char") == 0)) + LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream); else val_print_type_code_int (type, valaddr, stream); break; diff --git a/contrib/gdb/gdb/kod.c b/contrib/gdb/gdb/kod.c index 2641c38e009..6cb3622f87a 100644 --- a/contrib/gdb/gdb/kod.c +++ b/contrib/gdb/gdb/kod.c @@ -87,11 +87,13 @@ gdb_kod_display (char *arg) static void gdb_kod_query (char *arg, char *result, int *maxsiz) { - int bufsiz = 0; + LONGEST bufsiz = 0; - /* Check if current target has remote_query capabilities. - If not, it does not have kod either. */ - if (! current_target.to_query) + /* Check if current target has remote_query capabilities. If not, + it does not have kod either. */ + bufsiz = target_read_partial (¤t_target, TARGET_OBJECT_KOD, + NULL, NULL, 0, 0); + if (bufsiz < 0) { strcpy (result, "ERR: Kernel Object Display not supported by current target\n"); @@ -99,7 +101,6 @@ gdb_kod_query (char *arg, char *result, int *maxsiz) } /* Just get the maximum buffer size. */ - target_query ((int) 'K', 0, 0, &bufsiz); /* Check if *we* were called just for getting the buffer size. */ if (*maxsiz == 0) @@ -119,7 +120,8 @@ gdb_kod_query (char *arg, char *result, int *maxsiz) error ("kod: query argument too long"); /* Send actual request. */ - if (target_query ((int) 'K', arg, result, &bufsiz)) + if (target_read_partial (¤t_target, TARGET_OBJECT_KOD, + arg, result, 0, bufsiz) < 0) strcpy (result, "ERR: remote query failed"); } @@ -132,7 +134,16 @@ kod_set_os (char *arg, int from_tty, struct cmd_list_element *command) { char *p; - if (command->type != set_cmd) + /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones + the set command passed as a parameter. The clone operation will + include (BUG?) any ``set'' command callback, if present. + Commands like ``info set'' call all the ``show'' command + callbacks. Unfortunately, for ``show'' commands cloned from + ``set'', this includes callbacks belonging to ``set'' commands. + Making this worse, this only occures if add_show_from_set() is + called after add_cmd_sfunc() (BUG?). */ + + if (cmd_type (command) != set_cmd) return; /* If we had already had an open OS, close it. */ @@ -145,7 +156,6 @@ kod_set_os (char *arg, int from_tty, struct cmd_list_element *command) delete_cmd (old_operating_system, &infolist); xfree (old_operating_system); } - old_operating_system = xstrdup (operating_system); if (! operating_system || ! *operating_system) { @@ -160,6 +170,8 @@ kod_set_os (char *arg, int from_tty, struct cmd_list_element *command) { char *kodlib; + old_operating_system = xstrdup (operating_system); + load_kod_library (operating_system); kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query); diff --git a/contrib/gdb/gdb/language.c b/contrib/gdb/gdb/language.c index 4c4036b68f7..bc00b473a6c 100644 --- a/contrib/gdb/gdb/language.c +++ b/contrib/gdb/gdb/language.c @@ -1,6 +1,8 @@ /* Multiple source language support for GDB. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by the Department of Computer Science at the State University of New York at Buffalo. @@ -42,6 +44,7 @@ #include "target.h" #include "parser-defs.h" #include "jv-lang.h" +#include "demangle.h" extern void _initialize_language (void); @@ -98,6 +101,8 @@ static int unk_lang_val_print (struct type *, char *, int, CORE_ADDR, static int unk_lang_value_print (struct value *, struct ui_file *, int, enum val_prettyprint); +static CORE_ADDR unk_lang_trampoline (CORE_ADDR pc); + /* Forward declaration */ extern const struct language_defn unknown_language_defn; @@ -146,7 +151,6 @@ static char *case_sensitive; char lang_frame_mismatch_warn[] = "Warning: the current language does not match this frame."; - /* This page contains the functions corresponding to GDB commands and their helpers. */ @@ -201,7 +205,7 @@ set_language_command (char *ignore, int from_tty) /* Search the list of languages for a match. */ for (i = 0; i < languages_size; i++) { - if (STREQ (languages[i]->la_name, language)) + if (strcmp (languages[i]->la_name, language) == 0) { /* Found it! Go into manual mode, and use this language. */ if (languages[i]->la_language == language_auto) @@ -249,22 +253,22 @@ show_type_command (char *ignore, int from_tty) static void set_type_command (char *ignore, int from_tty) { - if (STREQ (type, "on")) + if (strcmp (type, "on") == 0) { type_check = type_check_on; type_mode = type_mode_manual; } - else if (STREQ (type, "warn")) + else if (strcmp (type, "warn") == 0) { type_check = type_check_warn; type_mode = type_mode_manual; } - else if (STREQ (type, "off")) + else if (strcmp (type, "off") == 0) { type_check = type_check_off; type_mode = type_mode_manual; } - else if (STREQ (type, "auto")) + else if (strcmp (type, "auto") == 0) { type_mode = type_mode_auto; set_type_range_case (); @@ -295,22 +299,22 @@ show_range_command (char *ignore, int from_tty) static void set_range_command (char *ignore, int from_tty) { - if (STREQ (range, "on")) + if (strcmp (range, "on") == 0) { range_check = range_check_on; range_mode = range_mode_manual; } - else if (STREQ (range, "warn")) + else if (strcmp (range, "warn") == 0) { range_check = range_check_warn; range_mode = range_mode_manual; } - else if (STREQ (range, "off")) + else if (strcmp (range, "off") == 0) { range_check = range_check_off; range_mode = range_mode_manual; } - else if (STREQ (range, "auto")) + else if (strcmp (range, "auto") == 0) { range_mode = range_mode_auto; set_type_range_case (); @@ -340,17 +344,17 @@ show_case_command (char *ignore, int from_tty) static void set_case_command (char *ignore, int from_tty) { - if (STREQ (case_sensitive, "on")) + if (DEPRECATED_STREQ (case_sensitive, "on")) { case_sensitivity = case_sensitive_on; case_mode = case_mode_manual; } - else if (STREQ (case_sensitive, "off")) + else if (DEPRECATED_STREQ (case_sensitive, "off")) { case_sensitivity = case_sensitive_off; case_mode = case_mode_manual; } - else if (STREQ (case_sensitive, "auto")) + else if (DEPRECATED_STREQ (case_sensitive, "auto")) { case_mode = case_mode_auto; set_type_range_case (); @@ -484,7 +488,7 @@ set_range_str (void) } static void -set_case_str() +set_case_str (void) { char *tmp = NULL, *prefix = ""; @@ -549,6 +553,7 @@ binop_result_type (struct value *v1, struct value *v2) { case language_c: case language_cplus: + case language_objc: if (TYPE_CODE (t1) == TYPE_CODE_FLT) return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ? VALUE_TYPE (v2) : VALUE_TYPE (v1); @@ -567,8 +572,6 @@ binop_result_type (struct value *v1, struct value *v2) not needed. */ return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2); break; - case language_chill: - error ("Missing Chill support in function binop_result_check."); /*FIXME */ } internal_error (__FILE__, __LINE__, "failed internal consistency check"); return (struct type *) 0; /* For lint */ @@ -595,34 +598,12 @@ local_hex_format_custom (char *pre) return form; } -/* Converts a number to hexadecimal and stores it in a static +/* Converts a LONGEST to custom hexadecimal and stores it in a static string. Returns a pointer to this string. */ char * -local_hex_string (unsigned long num) +local_hex_string (LONGEST num) { - static char res[50]; - - sprintf (res, local_hex_format (), num); - return res; -} - -/* Converts a LONGEST number to hexadecimal and stores it in a static - string. Returns a pointer to this string. */ -char * -longest_local_hex_string (LONGEST num) -{ - return longest_local_hex_string_custom (num, "l"); -} - -/* Converts a number to custom hexadecimal and stores it in a static - string. Returns a pointer to this string. */ -char * -local_hex_string_custom (unsigned long num, char *pre) -{ - static char res[50]; - - sprintf (res, local_hex_format_custom (pre), num); - return res; + return local_hex_string_custom (num, "l"); } /* Converts a LONGEST number to custom hexadecimal and stores it in a static @@ -630,12 +611,11 @@ local_hex_string_custom (unsigned long num, char *pre) should end with "l", e.g. "08l" as with calls to local_hex_string_custom */ char * -longest_local_hex_string_custom (LONGEST num, char *width) +local_hex_string_custom (LONGEST num, char *width) { #define RESULT_BUF_LEN 50 static char res2[RESULT_BUF_LEN]; char format[RESULT_BUF_LEN]; -#if !defined (PRINTF_HAS_LONG_LONG) int field_width; int num_len; int num_pad_chars; @@ -643,24 +623,7 @@ longest_local_hex_string_custom (LONGEST num, char *width) int pad_on_left; char *parse_ptr; char temp_nbr_buf[RESULT_BUF_LEN]; -#endif -#ifndef CC_HAS_LONG_LONG - /* If there is no long long, then LONGEST should be just long and we - can use local_hex_string_custom - */ - return local_hex_string_custom ((unsigned long) num, width); -#elif defined (PRINTF_HAS_LONG_LONG) - /* Just use printf. */ - strcpy (format, local_hex_format_prefix ()); /* 0x */ - strcat (format, "%"); - strcat (format, width); /* e.g. "08l" */ - strcat (format, "l"); /* need "ll" for long long */ - strcat (format, local_hex_format_specifier ()); /* "x" */ - strcat (format, local_hex_format_suffix ()); /* "" */ - sprintf (res2, format, num); - return res2; -#else /* !defined (PRINTF_HAS_LONG_LONG) */ /* Use phex_nz to print the number into a string, then build the result string from local_hex_format_prefix, padding and the hex representation as indicated by "width". */ @@ -687,7 +650,7 @@ longest_local_hex_string_custom (LONGEST num, char *width) if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars >= RESULT_BUF_LEN) /* paranoia */ internal_error (__FILE__, __LINE__, - "longest_local_hex_string_custom: insufficient space to store result"); + "local_hex_string_custom: insufficient space to store result"); strcpy (res2, local_hex_format_prefix ()); if (pad_on_left) @@ -708,9 +671,8 @@ longest_local_hex_string_custom (LONGEST num, char *width) } } return res2; -#endif -} /* longest_local_hex_string_custom */ +} /* local_hex_string_custom */ /* Returns the appropriate printf format for octal numbers. */ @@ -827,13 +789,12 @@ integral_type (struct type *type) { case language_c: case language_cplus: + case language_objc: return (TYPE_CODE (type) != TYPE_CODE_INT) && (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1; case language_m2: case language_pascal: return TYPE_CODE (type) != TYPE_CODE_INT ? 0 : 1; - case language_chill: - error ("Missing Chill support in function integral_type."); /*FIXME */ default: error ("Language not supported."); } @@ -862,13 +823,13 @@ character_type (struct type *type) CHECK_TYPEDEF (type); switch (current_language->la_language) { - case language_chill: case language_m2: case language_pascal: return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1; case language_c: case language_cplus: + case language_objc: return (TYPE_CODE (type) == TYPE_CODE_INT) && TYPE_LENGTH (type) == sizeof (char) ? 1 : 0; @@ -884,13 +845,13 @@ string_type (struct type *type) CHECK_TYPEDEF (type); switch (current_language->la_language) { - case language_chill: case language_m2: case language_pascal: return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1; case language_c: case language_cplus: + case language_objc: /* C does not have distinct string type. */ return (0); default: @@ -909,8 +870,10 @@ boolean_type (struct type *type) { case language_c: case language_cplus: - /* Might be more cleanly handled by having a TYPE_CODE_INT_NOT_BOOL - for CHILL and such languages, or a TYPE_CODE_INT_OR_BOOL for C. */ + case language_objc: + /* Might be more cleanly handled by having a + TYPE_CODE_INT_NOT_BOOL for (the deleted) CHILL and such + languages, or a TYPE_CODE_INT_OR_BOOL for C. */ if (TYPE_CODE (type) == TYPE_CODE_INT) return 1; default: @@ -944,6 +907,7 @@ structured_type (struct type *type) { case language_c: case language_cplus: + case language_objc: return (TYPE_CODE (type) == TYPE_CODE_STRUCT) || (TYPE_CODE (type) == TYPE_CODE_UNION) || (TYPE_CODE (type) == TYPE_CODE_ARRAY); @@ -956,8 +920,6 @@ structured_type (struct type *type) return (TYPE_CODE (type) == TYPE_CODE_STRUCT) || (TYPE_CODE (type) == TYPE_CODE_SET) || (TYPE_CODE (type) == TYPE_CODE_ARRAY); - case language_chill: - error ("Missing Chill support in function structured_type."); /*FIXME */ default: return (0); } @@ -971,10 +933,8 @@ lang_bool_type (void) struct type *type; switch (current_language->la_language) { - case language_chill: - return builtin_type_chill_bool; case language_fortran: - sym = lookup_symbol ("logical", NULL, VAR_NAMESPACE, NULL, NULL); + sym = lookup_symbol ("logical", NULL, VAR_DOMAIN, NULL, NULL); if (sym) { type = SYMBOL_TYPE (sym); @@ -985,9 +945,9 @@ lang_bool_type (void) case language_cplus: case language_pascal: if (current_language->la_language==language_cplus) - {sym = lookup_symbol ("bool", NULL, VAR_NAMESPACE, NULL, NULL);} + {sym = lookup_symbol ("bool", NULL, VAR_DOMAIN, NULL, NULL);} else - {sym = lookup_symbol ("boolean", NULL, VAR_NAMESPACE, NULL, NULL);} + {sym = lookup_symbol ("boolean", NULL, VAR_DOMAIN, NULL, NULL);} if (sym) { type = SYMBOL_TYPE (sym); @@ -996,7 +956,7 @@ lang_bool_type (void) } return builtin_type_bool; case language_java: - sym = lookup_symbol ("boolean", NULL, VAR_NAMESPACE, NULL, NULL); + sym = lookup_symbol ("boolean", NULL, VAR_DOMAIN, NULL, NULL); if (sym) { type = SYMBOL_TYPE (sym); @@ -1025,214 +985,10 @@ value_true (struct value *val) return !value_logical_not (val); } -/* Returns non-zero if the operator OP is defined on - the values ARG1 and ARG2. */ - -#if 0 /* Currently unused */ - -void -binop_type_check (struct value *arg1, struct value *arg2, int op) -{ - struct type *t1, *t2; - - /* If we're not checking types, always return success. */ - if (!STRICT_TYPE) - return; - - t1 = VALUE_TYPE (arg1); - if (arg2 != NULL) - t2 = VALUE_TYPE (arg2); - else - t2 = NULL; - - switch (op) - { - case BINOP_ADD: - case BINOP_SUB: - if ((numeric_type (t1) && pointer_type (t2)) || - (pointer_type (t1) && numeric_type (t2))) - { - warning ("combining pointer and integer.\n"); - break; - } - case BINOP_MUL: - case BINOP_LSH: - case BINOP_RSH: - if (!numeric_type (t1) || !numeric_type (t2)) - type_op_error ("Arguments to %s must be numbers.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_LOGICAL_AND: - case BINOP_LOGICAL_OR: - if (!boolean_type (t1) || !boolean_type (t2)) - type_op_error ("Arguments to %s must be of boolean type.", op); - break; - - case BINOP_EQUAL: - if ((pointer_type (t1) && !(pointer_type (t2) || integral_type (t2))) || - (pointer_type (t2) && !(pointer_type (t1) || integral_type (t1)))) - type_op_error ("A pointer can only be compared to an integer or pointer.", op); - else if ((pointer_type (t1) && integral_type (t2)) || - (integral_type (t1) && pointer_type (t2))) - { - warning ("combining integer and pointer.\n"); - break; - } - else if (!simple_type (t1) || !simple_type (t2)) - type_op_error ("Arguments to %s must be of simple type.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_REM: - case BINOP_MOD: - if (!integral_type (t1) || !integral_type (t2)) - type_op_error ("Arguments to %s must be of integral type.", op); - break; - - case BINOP_LESS: - case BINOP_GTR: - case BINOP_LEQ: - case BINOP_GEQ: - if (!ordered_type (t1) || !ordered_type (t2)) - type_op_error ("Arguments to %s must be of ordered type.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_ASSIGN: - if (pointer_type (t1) && !integral_type (t2)) - type_op_error ("A pointer can only be assigned an integer.", op); - else if (pointer_type (t1) && integral_type (t2)) - { - warning ("combining integer and pointer."); - break; - } - else if (!simple_type (t1) || !simple_type (t2)) - type_op_error ("Arguments to %s must be of simple type.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_CONCAT: - /* FIXME: Needs to handle bitstrings as well. */ - if (!(string_type (t1) || character_type (t1) || integral_type (t1)) - || !(string_type (t2) || character_type (t2) || integral_type (t2))) - type_op_error ("Arguments to %s must be strings or characters.", op); - break; - - /* Unary checks -- arg2 is null */ - - case UNOP_LOGICAL_NOT: - if (!boolean_type (t1)) - type_op_error ("Argument to %s must be of boolean type.", op); - break; - - case UNOP_PLUS: - case UNOP_NEG: - if (!numeric_type (t1)) - type_op_error ("Argument to %s must be of numeric type.", op); - break; - - case UNOP_IND: - if (integral_type (t1)) - { - warning ("combining pointer and integer.\n"); - break; - } - else if (!pointer_type (t1)) - type_op_error ("Argument to %s must be a pointer.", op); - break; - - case UNOP_PREINCREMENT: - case UNOP_POSTINCREMENT: - case UNOP_PREDECREMENT: - case UNOP_POSTDECREMENT: - if (!ordered_type (t1)) - type_op_error ("Argument to %s must be of an ordered type.", op); - break; - - default: - /* Ok. The following operators have different meanings in - different languages. */ - switch (current_language->la_language) - { -#ifdef _LANG_c - case language_c: - case language_cplus: - switch (op) - { - case BINOP_DIV: - if (!numeric_type (t1) || !numeric_type (t2)) - type_op_error ("Arguments to %s must be numbers.", op); - break; - } - break; -#endif - -#ifdef _LANG_m2 - case language_m2: - switch (op) - { - case BINOP_DIV: - if (!float_type (t1) || !float_type (t2)) - type_op_error ("Arguments to %s must be floating point numbers.", op); - break; - case BINOP_INTDIV: - if (!integral_type (t1) || !integral_type (t2)) - type_op_error ("Arguments to %s must be of integral type.", op); - break; - } -#endif - -#ifdef _LANG_pascal - case language_pascal: - switch(op) - { - case BINOP_DIV: - if (!float_type(t1) && !float_type(t2)) - type_op_error ("Arguments to %s must be floating point numbers.",op); - break; - case BINOP_INTDIV: - if (!integral_type(t1) || !integral_type(t2)) - type_op_error ("Arguments to %s must be of integral type.",op); - break; - } -#endif - -#ifdef _LANG_chill - case language_chill: - error ("Missing Chill support in function binop_type_check."); /*FIXME */ -#endif - - } - } -} - -#endif /* 0 */ - - /* This page contains functions for the printing out of error messages that occur during type- and range- checking. */ -/* Prints the format string FMT with the operator as a string - corresponding to the opcode OP. If FATAL is non-zero, then - this is an error and error () is called. Otherwise, it is - a warning and printf() is called. */ -void -op_error (char *fmt, enum exp_opcode op, int fatal) -{ - if (fatal) - error (fmt, op_string (op)); - else - { - warning (fmt, op_string (op)); - } -} - /* These are called when a language fails a type- or range-check. The first argument should be a printf()-style format string, and the rest of the arguments should be its arguments. If @@ -1303,7 +1059,7 @@ language_enum (char *str) int i; for (i = 0; i < languages_size; i++) - if (STREQ (languages[i]->la_name, str)) + if (DEPRECATED_STREQ (languages[i]->la_name, str)) return languages[i]->la_language; return language_unknown; @@ -1383,6 +1139,53 @@ add_language (const struct language_defn *lang) languages[languages_size++] = lang; } +/* Iterate through all registered languages looking for and calling + any non-NULL struct language_defn.skip_trampoline() functions. + Return the result from the first that returns non-zero, or 0 if all + `fail'. */ +CORE_ADDR +skip_language_trampoline (CORE_ADDR pc) +{ + int i; + + for (i = 0; i < languages_size; i++) + { + if (languages[i]->skip_trampoline) + { + CORE_ADDR real_pc = (languages[i]->skip_trampoline) (pc); + if (real_pc) + return real_pc; + } + } + + return 0; +} + +/* Return demangled language symbol, or NULL. + FIXME: Options are only useful for certain languages and ignored + by others, so it would be better to remove them here and have a + more flexible demangler for the languages that need it. + FIXME: Sometimes the demangler is invoked when we don't know the + language, so we can't use this everywhere. */ +char * +language_demangle (const struct language_defn *current_language, + const char *mangled, int options) +{ + if (current_language != NULL && current_language->la_demangle) + return current_language->la_demangle (mangled, options); + return NULL; +} + +/* Return the default string containing the list of characters + delimiting words. This is a reasonable default value that + most languages should be able to use. */ + +char * +default_word_break_characters (void) +{ + return " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-"; +} + /* Define the language that is no language. */ static int @@ -1398,13 +1201,13 @@ unk_lang_error (char *msg) } static void -unk_lang_emit_char (register int c, struct ui_file *stream, int quoter) +unk_lang_emit_char (int c, struct ui_file *stream, int quoter) { error ("internal error - unimplemented function unk_lang_emit_char called."); } static void -unk_lang_printchar (register int c, struct ui_file *stream) +unk_lang_printchar (int c, struct ui_file *stream) { error ("internal error - unimplemented function unk_lang_printchar called."); } @@ -1444,6 +1247,18 @@ unk_lang_value_print (struct value *val, struct ui_file *stream, int format, error ("internal error - unimplemented function unk_lang_value_print called."); } +static CORE_ADDR unk_lang_trampoline (CORE_ADDR pc) +{ + return 0; +} + +/* Unknown languages just use the cplus demangler. */ +static char *unk_lang_demangle (const char *mangled, int options) +{ + return cplus_demangle (mangled, options); +} + + static struct type **const (unknown_builtin_types[]) = { 0 @@ -1461,9 +1276,9 @@ const struct language_defn unknown_language_defn = range_check_off, type_check_off, case_sensitive_on, + &exp_descriptor_standard, unk_lang_parser, unk_lang_error, - evaluate_subexp_standard, unk_lang_printchar, /* Print character constant */ unk_lang_printstr, unk_lang_emit_char, @@ -1471,6 +1286,11 @@ const struct language_defn unknown_language_defn = unk_lang_print_type, /* Print a type using appropriate syntax */ unk_lang_val_print, /* Print a value using appropriate syntax */ unk_lang_value_print, /* Print a top-level value */ + unk_lang_trampoline, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + unk_lang_demangle, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -1479,6 +1299,7 @@ const struct language_defn unknown_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; @@ -1491,9 +1312,9 @@ const struct language_defn auto_language_defn = range_check_off, type_check_off, case_sensitive_on, + &exp_descriptor_standard, unk_lang_parser, unk_lang_error, - evaluate_subexp_standard, unk_lang_printchar, /* Print character constant */ unk_lang_printstr, unk_lang_emit_char, @@ -1501,6 +1322,11 @@ const struct language_defn auto_language_defn = unk_lang_print_type, /* Print a type using appropriate syntax */ unk_lang_val_print, /* Print a value using appropriate syntax */ unk_lang_value_print, /* Print a top-level value */ + unk_lang_trampoline, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + unk_lang_demangle, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -1509,6 +1335,7 @@ const struct language_defn auto_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; @@ -1520,9 +1347,9 @@ const struct language_defn local_language_defn = range_check_off, type_check_off, case_sensitive_on, + &exp_descriptor_standard, unk_lang_parser, unk_lang_error, - evaluate_subexp_standard, unk_lang_printchar, /* Print character constant */ unk_lang_printstr, unk_lang_emit_char, @@ -1530,6 +1357,11 @@ const struct language_defn local_language_defn = unk_lang_print_type, /* Print a type using appropriate syntax */ unk_lang_val_print, /* Print a value using appropriate syntax */ unk_lang_value_print, /* Print a top-level value */ + unk_lang_trampoline, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + unk_lang_demangle, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -1538,6 +1370,7 @@ const struct language_defn local_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; @@ -1559,13 +1392,13 @@ _initialize_language (void) set_cmd_cfunc (show, show_language_command); add_prefix_cmd ("check", no_class, set_check, - "Set the status of the type/range checker", + "Set the status of the type/range checker.", &setchecklist, "set check ", 0, &setlist); add_alias_cmd ("c", "check", no_class, 1, &setlist); add_alias_cmd ("ch", "check", no_class, 1, &setlist); add_prefix_cmd ("check", no_class, show_check, - "Show the status of the type/range checker", + "Show the status of the type/range checker.", &showchecklist, "show check ", 0, &showlist); add_alias_cmd ("c", "check", no_class, 1, &showlist); add_alias_cmd ("ch", "check", no_class, 1, &showlist); diff --git a/contrib/gdb/gdb/language.h b/contrib/gdb/gdb/language.h index 88375db268a..8ed9fb08417 100644 --- a/contrib/gdb/gdb/language.h +++ b/contrib/gdb/gdb/language.h @@ -1,6 +1,8 @@ /* Source-language-related definitions for GDB. - Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000 - Free Software Foundation, Inc. + + Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2003, + 2004 Free Software Foundation, Inc. + Contributed by the Department of Computer Science at the State University of New York at Buffalo. @@ -28,6 +30,8 @@ struct value; struct objfile; struct expression; +struct ui_file; + /* enum exp_opcode; ANSI's `wisdom' didn't include forward enum decls. */ /* This used to be included to configure GDB for one or more specific @@ -35,7 +39,6 @@ struct expression; /* #include "lang_def.h" */ #define _LANG_c #define _LANG_m2 -#define _LANG_chill #define _LANG_fortran #define _LANG_pascal @@ -164,6 +167,11 @@ struct language_defn /* Default case sensitivity */ enum case_sensitivity la_case_sensitivity; + /* Definitions related to expression printing, prefixifying, and + dumping */ + + const struct exp_descriptor *la_exp_desc; + /* Parser function. */ int (*la_parser) (void); @@ -172,10 +180,6 @@ struct language_defn void (*la_error) (char *); - /* Evaluate an expression. */ - struct value *(*evaluate_exp) (struct type *, struct expression *, - int *, enum noside); - void (*la_printchar) (int ch, struct ui_file * stream); void (*la_printstr) (struct ui_file * stream, char *string, @@ -202,6 +206,39 @@ struct language_defn int (*la_value_print) (struct value *, struct ui_file *, int, enum val_prettyprint); + /* PC is possibly an unknown languages trampoline. + If that PC falls in a trampoline belonging to this language, + return the address of the first pc in the real function, or 0 + if it isn't a language tramp for this language. */ + CORE_ADDR (*skip_trampoline) (CORE_ADDR pc); + + /* Now come some hooks for lookup_symbol. */ + + /* If this is non-NULL, lookup_symbol will do the 'field_of_this' + check, using this function to find the value of this. */ + + /* FIXME: carlton/2003-05-19: Audit all the language_defn structs + to make sure we're setting this appropriately: I'm sure it + could be NULL in more languages. */ + + struct value *(*la_value_of_this) (int complain); + + /* This is a function that lookup_symbol will call when it gets to + the part of symbol lookup where C looks up static and global + variables. */ + + struct symbol *(*la_lookup_symbol_nonlocal) (const char *, + const char *, + const struct block *, + const domain_enum, + struct symtab **); + + /* Find the definition of the type with the given name. */ + struct type *(*la_lookup_transparent_type) (const char *); + + /* Return demangled language symbol, or NULL. */ + char *(*la_demangle) (const char *mangled, int options); + /* Base 2 (binary) formats. */ struct language_format_info la_binary_format; @@ -233,6 +270,9 @@ struct language_defn /* Type of elements of strings. */ struct type **string_char_type; + /* The list of characters forming word boundaries. */ + char *(*la_word_break_characters) (void); + /* Add fields above this point, so the magic number is always last. */ /* Magic number for compat checking */ @@ -288,7 +328,8 @@ language_mode; /* "cast" really means conversion */ /* FIXME -- should be a setting in language_defn */ #define CAST_IS_CONVERSION (current_language->la_language == language_c || \ - current_language->la_language == language_cplus) + current_language->la_language == language_cplus || \ + current_language->la_language == language_objc) extern void language_info (int); @@ -395,13 +436,9 @@ extern char *longest_raw_hex_string (LONGEST); (language-specific) formats. Result is static and is overwritten by the next call. Takes printf options like "08l" or "l". */ -extern char *local_hex_string (unsigned long); /* language.c */ +extern char *local_hex_string (LONGEST); /* language.c */ -extern char *longest_local_hex_string (LONGEST); /* language.c */ - -extern char *local_hex_string_custom (unsigned long, char *); /* language.c */ - -extern char *longest_local_hex_string_custom (LONGEST, char *); /* language.c */ +extern char *local_hex_string_custom (LONGEST, char *); /* language.c */ /* Type predicates */ @@ -433,12 +470,8 @@ extern void binop_type_check (struct value *, struct value *, int); /* Error messages */ -extern void op_error (char *fmt, enum exp_opcode, int); - -#define type_op_error(f,o) \ - op_error((f),(o),type_check==type_check_on ? 1 : 0) -#define range_op_error(f,o) \ - op_error((f),(o),range_check==range_check_on ? 1 : 0) +extern void op_error (const char *lhs, enum exp_opcode, + const char *rhs); extern void type_error (const char *, ...) ATTR_FORMAT (printf, 1, 2); @@ -467,4 +500,15 @@ extern void add_language (const struct language_defn *); extern enum language get_frame_language (void); /* In stack.c */ +/* Check for a language-specific trampoline. */ + +extern CORE_ADDR skip_language_trampoline (CORE_ADDR pc); + +/* Return demangled language symbol, or NULL. */ +extern char *language_demangle (const struct language_defn *current_language, + const char *mangled, int options); + +/* Splitting strings into words. */ +extern char *default_word_break_characters (void); + #endif /* defined (LANGUAGE_H) */ diff --git a/contrib/gdb/gdb/libunwind-frame.c b/contrib/gdb/gdb/libunwind-frame.c new file mode 100644 index 00000000000..bf0c36d9f60 --- /dev/null +++ b/contrib/gdb/gdb/libunwind-frame.c @@ -0,0 +1,387 @@ +/* Frame unwinder for frames using the libunwind library. + + Copyright 2003 Free Software Foundation, Inc. + + Written by Jeff Johnston, contributed by Red Hat Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "inferior.h" +#include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "gdbtypes.h" +#include "symtab.h" +#include "objfiles.h" +#include "regcache.h" + +#include + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "libunwind-frame.h" + +#include "complaints.h" + +static int libunwind_initialized; +static struct gdbarch_data *libunwind_descr_handle; + +#ifndef LIBUNWIND_SO +#define LIBUNWIND_SO "libunwind.so" +#endif + +/* Required function pointers from libunwind. */ +static int (*unw_get_reg_p) (unw_cursor_t *, unw_regnum_t, unw_word_t *); +static int (*unw_get_fpreg_p) (unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); +static int (*unw_get_saveloc_p) (unw_cursor_t *, unw_regnum_t, unw_save_loc_t *); +static int (*unw_step_p) (unw_cursor_t *); +static int (*unw_init_remote_p) (unw_cursor_t *, unw_addr_space_t, void *); +static unw_addr_space_t (*unw_create_addr_space_p) (unw_accessors_t *, int); +static int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *, + unw_proc_info_t *, int, void *); +static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, unw_dyn_info_t *, + void *); + + +struct libunwind_frame_cache +{ + CORE_ADDR base; + CORE_ADDR func_addr; + unw_cursor_t cursor; +}; + +/* We need to qualify the function names with a platform-specific prefix to match + the names used by the libunwind library. The UNW_OBJ macro is provided by the + libunwind.h header file. */ +#define STRINGIFY2(name) #name +#define STRINGIFY(name) STRINGIFY2(name) + +static char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg)); +static char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg)); +static char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc)); +static char *step_name = STRINGIFY(UNW_OBJ(step)); +static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote)); +static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space)); +static char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table)); +static char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list)); + +static struct libunwind_descr * +libunwind_descr (struct gdbarch *gdbarch) +{ + return gdbarch_data (gdbarch, libunwind_descr_handle); +} + +static void * +libunwind_descr_init (struct gdbarch *gdbarch) +{ + struct libunwind_descr *descr = GDBARCH_OBSTACK_ZALLOC (gdbarch, + struct libunwind_descr); + return descr; +} + +void +libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *descr) +{ + struct libunwind_descr *arch_descr; + + gdb_assert (gdbarch != NULL); + + arch_descr = gdbarch_data (gdbarch, libunwind_descr_handle); + + if (arch_descr == NULL) + { + /* First time here. Must initialize data area. */ + arch_descr = libunwind_descr_init (gdbarch); + set_gdbarch_data (gdbarch, libunwind_descr_handle, arch_descr); + } + + /* Copy new descriptor info into arch descriptor. */ + arch_descr->gdb2uw = descr->gdb2uw; + arch_descr->uw2gdb = descr->uw2gdb; + arch_descr->is_fpreg = descr->is_fpreg; + arch_descr->accessors = descr->accessors; +} + +static struct libunwind_frame_cache * +libunwind_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + unw_accessors_t *acc; + unw_addr_space_t as; + unw_word_t fp; + unw_regnum_t uw_sp_regnum; + struct libunwind_frame_cache *cache; + struct libunwind_descr *descr; + int i, ret; + + if (*this_cache) + return *this_cache; + + /* Allocate a new cache. */ + cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache); + + cache->func_addr = frame_func_unwind (next_frame); + + /* Get a libunwind cursor to the previous frame. We do this by initializing + a cursor. Libunwind treats a new cursor as the top of stack and will get + the current register set via the libunwind register accessor. Now, we + provide the platform-specific accessors and we set up the register accessor to use + the frame register unwinding interfaces so that we properly get the registers for + the current frame rather than the top. We then use the unw_step function to + move the libunwind cursor back one frame. We can later use this cursor to find previous + registers via the unw_get_reg interface which will invoke libunwind's special logic. */ + descr = libunwind_descr (get_frame_arch (next_frame)); + acc = descr->accessors; + as = unw_create_addr_space_p (acc, + TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + ? __BIG_ENDIAN + : __LITTLE_ENDIAN); + + unw_init_remote_p (&cache->cursor, as, next_frame); + unw_step_p (&cache->cursor); + + /* To get base address, get sp from previous frame. */ + uw_sp_regnum = descr->gdb2uw (SP_REGNUM); + ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp); + if (ret < 0) + error ("Can't get libunwind sp register."); + + cache->base = (CORE_ADDR)fp; + + *this_cache = cache; + return cache; +} + +unw_word_t +libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg) +{ + return unw_find_dyn_list_p (as, di, arg); +} + +static const struct frame_unwind libunwind_frame_unwind = +{ + NORMAL_FRAME, + libunwind_frame_this_id, + libunwind_frame_prev_register +}; + +/* Verify if there is sufficient libunwind information for the frame to use + libunwind frame unwinding. */ +const struct frame_unwind * +libunwind_frame_sniffer (struct frame_info *next_frame) +{ + unw_cursor_t cursor; + unw_accessors_t *acc; + unw_addr_space_t as; + struct libunwind_descr *descr; + int i, ret; + + /* To test for libunwind unwind support, initialize a cursor to the current frame and try to back + up. We use this same method when setting up the frame cache (see libunwind_frame_cache()). + If libunwind returns success for this operation, it means that it has found sufficient + libunwind unwinding information to do so. */ + + descr = libunwind_descr (get_frame_arch (next_frame)); + acc = descr->accessors; + as = unw_create_addr_space_p (acc, + TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + ? __BIG_ENDIAN + : __LITTLE_ENDIAN); + + ret = unw_init_remote_p (&cursor, as, next_frame); + + if (ret >= 0) + ret = unw_step_p (&cursor); + + if (ret < 0) + return NULL; + + return &libunwind_frame_unwind; +} + +void +libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct libunwind_frame_cache *cache = + libunwind_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->func_addr); +} + +void +libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct libunwind_frame_cache *cache = + libunwind_frame_cache (next_frame, this_cache); + + void *ptr; + unw_cursor_t *c; + unw_save_loc_t sl; + int i, ret; + unw_word_t intval; + unw_fpreg_t fpval; + unw_regnum_t uw_regnum; + struct libunwind_descr *descr; + + /* Convert from gdb register number to libunwind register number. */ + descr = libunwind_descr (get_frame_arch (next_frame)); + uw_regnum = descr->gdb2uw (regnum); + + gdb_assert (regnum >= 0); + + if (!target_has_registers) + error ("No registers."); + + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; + + memset (valuep, 0, register_size (current_gdbarch, regnum)); + + if (uw_regnum < 0) + return; + + /* To get the previous register, we use the libunwind register APIs with + the cursor we have already pushed back to the previous frame. */ + + if (descr->is_fpreg (uw_regnum)) + { + ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval); + ptr = &fpval; + } + else + { + ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval); + ptr = &intval; + } + + if (ret < 0) + return; + + memcpy (valuep, ptr, register_size (current_gdbarch, regnum)); + + if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0) + return; + + switch (sl.type) + { + case UNW_SLT_NONE: + *optimizedp = 1; + break; + + case UNW_SLT_MEMORY: + *lvalp = lval_memory; + *addrp = sl.u.addr; + break; + + case UNW_SLT_REG: + *lvalp = lval_register; + *realnump = regnum; + break; + } +} + +CORE_ADDR +libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct libunwind_frame_cache *cache = + libunwind_frame_cache (next_frame, this_cache); + + return cache->base; +} + +/* The following is a glue routine to call the libunwind unwind table + search function to get unwind information for a specified ip address. */ +int +libunwind_search_unwind_table (void *as, long ip, void *di, + void *pi, int need_unwind_info, void *args) +{ + return unw_search_unwind_table_p (*(unw_addr_space_t *)as, (unw_word_t )ip, + di, pi, need_unwind_info, args); +} + +static int +libunwind_load (void) +{ + void *handle; + + handle = dlopen (LIBUNWIND_SO, RTLD_NOW); + if (handle == NULL) + return 0; + + /* Initialize pointers to the dynamic library functions we will use. */ + + unw_get_reg_p = dlsym (handle, get_reg_name); + if (unw_get_reg_p == NULL) + return 0; + + unw_get_fpreg_p = dlsym (handle, get_fpreg_name); + if (unw_get_fpreg_p == NULL) + return 0; + + unw_get_saveloc_p = dlsym (handle, get_saveloc_name); + if (unw_get_saveloc_p == NULL) + return 0; + + unw_step_p = dlsym (handle, step_name); + if (unw_step_p == NULL) + return 0; + + unw_init_remote_p = dlsym (handle, init_remote_name); + if (unw_init_remote_p == NULL) + return 0; + + unw_create_addr_space_p = dlsym (handle, create_addr_space_name); + if (unw_create_addr_space_p == NULL) + return 0; + + unw_search_unwind_table_p = dlsym (handle, search_unwind_table_name); + if (unw_search_unwind_table_p == NULL) + return 0; + + unw_find_dyn_list_p = dlsym (handle, find_dyn_list_name); + if (unw_find_dyn_list_p == NULL) + return 0; + + return 1; +} + +int +libunwind_is_initialized (void) +{ + return libunwind_initialized; +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_libunwind_frame (void); + +void +_initialize_libunwind_frame (void) +{ + libunwind_descr_handle = register_gdbarch_data (libunwind_descr_init); + + libunwind_initialized = libunwind_load (); +} diff --git a/contrib/gdb/gdb/libunwind-frame.h b/contrib/gdb/gdb/libunwind-frame.h new file mode 100644 index 00000000000..e47a792cc98 --- /dev/null +++ b/contrib/gdb/gdb/libunwind-frame.h @@ -0,0 +1,64 @@ +/* Frame unwinder for frames with libunwind frame information. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by Jeff Johnston. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_LIBUNWIND_H + +struct frame_info; +struct frame_id; + +#ifndef LIBUNWIND_FRAME_H +#define LIBUNWIND_FRAME_H 1 + +#include "libunwind.h" + +struct libunwind_descr +{ + int (*gdb2uw) (int); + int (*uw2gdb) (int); + int (*is_fpreg) (int); + void *accessors; +}; + +const struct frame_unwind *libunwind_frame_sniffer (struct frame_info *next_frame); + +void libunwind_frame_set_descr (struct gdbarch *arch, struct libunwind_descr *descr); + +void libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id); +void libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep); +CORE_ADDR libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache); + +int libunwind_is_initialized (void); + +int libunwind_search_unwind_table (void *as, long ip, void *di, + void *pi, int need_unwind_info, void *args); + +unw_word_t libunwind_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *, + void *); + +#endif /* libunwind-frame.h */ + +#endif /* HAVE_LIBUNWIND_H */ diff --git a/contrib/gdb/gdb/lin-lwp.c b/contrib/gdb/gdb/lin-lwp.c index e39e78732b3..df91aa76963 100644 --- a/contrib/gdb/gdb/lin-lwp.c +++ b/contrib/gdb/gdb/lin-lwp.c @@ -1,5 +1,5 @@ /* Multi-threaded debugging support for GNU/Linux (LWP layer). - Copyright 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -21,8 +21,13 @@ #include "defs.h" #include "gdb_assert.h" +#include "gdb_string.h" #include #include +#ifdef HAVE_TKILL_SYSCALL +#include +#include +#endif #include #include "gdb_wait.h" @@ -33,7 +38,9 @@ #include "gdbcmd.h" static int debug_lin_lwp; -extern const char *strsignal (int sig); +extern char *strsignal (int sig); + +#include "linux-nat.h" /* On GNU/Linux there are no real LWP's. The closest thing to LWP's are processes sharing the same VM space. A multi-threaded process @@ -68,43 +75,6 @@ extern const char *strsignal (int sig); threads will run out of processes, even if the threads exit, because the "zombies" stay around. */ -/* Structure describing a LWP. */ -struct lwp_info -{ - /* The process id of the LWP. This is a combination of the LWP id - and overall process id. */ - ptid_t ptid; - - /* Non-zero if this LWP is cloned. In this context "cloned" means - that the LWP is reporting to its parent using a signal other than - SIGCHLD. */ - int cloned; - - /* Non-zero if we sent this LWP a SIGSTOP (but the LWP didn't report - it back yet). */ - int signalled; - - /* Non-zero if this LWP is stopped. */ - int stopped; - - /* Non-zero if this LWP will be/has been resumed. Note that an LWP - can be marked both as stopped and resumed at the same time. This - happens if we try to resume an LWP that has a wait status - pending. We shouldn't let the LWP run until that wait status has - been processed, but we should not report that wait status if GDB - didn't try to let the LWP run. */ - int resumed; - - /* If non-zero, a pending wait status. */ - int status; - - /* Non-zero if we were stepping this LWP. */ - int step; - - /* Next LWP in list. */ - struct lwp_info *next; -}; - /* List of known LWPs. */ static struct lwp_info *lwp_list; @@ -155,6 +125,7 @@ static sigset_t blocked_mask; /* Prototypes for local functions. */ static int stop_wait_callback (struct lwp_info *lp, void *data); +static int lin_lwp_thread_alive (ptid_t ptid); /* Convert wait status STATUS to a string. Used for printing debug messages only. */ @@ -171,8 +142,7 @@ status_to_str (int status) snprintf (buf, sizeof (buf), "%s (terminated)", strsignal (WSTOPSIG (status))); else - snprintf (buf, sizeof (buf), "%d (exited)", - WEXITSTATUS (status)); + snprintf (buf, sizeof (buf), "%d (exited)", WEXITSTATUS (status)); return buf; } @@ -293,46 +263,6 @@ iterate_over_lwps (int (*callback) (struct lwp_info *, void *), void *data) } -/* Implementation of the PREPARE_TO_PROCEED hook for the GNU/Linux LWP - layer. - - Note that this implementation is potentially redundant now that - default_prepare_to_proceed() has been added. - - FIXME This may not support switching threads after Ctrl-C - correctly. The default implementation does support this. */ - -int -lin_lwp_prepare_to_proceed (void) -{ - if (! ptid_equal (trap_ptid, null_ptid) - && ! ptid_equal (inferior_ptid, trap_ptid)) - { - /* Switched over from TRAP_PID. */ - CORE_ADDR stop_pc = read_pc (); - CORE_ADDR trap_pc; - - /* Avoid switching where it wouldn't do any good, i.e. if both - threads are at the same breakpoint. */ - trap_pc = read_pc_pid (trap_ptid); - if (trap_pc != stop_pc && breakpoint_here_p (trap_pc)) - { - /* User hasn't deleted the breakpoint. Return non-zero, and - switch back to TRAP_PID. */ - inferior_ptid = trap_ptid; - - /* FIXME: Is this stuff really necessary? */ - flush_cached_frames (); - registers_changed (); - - return 1; - } - } - - return 0; -} - - #if 0 static void lin_lwp_open (char *args, int from_tty) @@ -354,7 +284,7 @@ lin_lwp_attach_lwp (ptid_t ptid, int verbose) /* Make sure SIGCHLD is blocked. We don't want SIGCHLD events to interrupt either the ptrace() or waitpid() calls below. */ - if (! sigismember (&blocked_mask, SIGCHLD)) + if (!sigismember (&blocked_mask, SIGCHLD)) { sigaddset (&blocked_mask, SIGCHLD); sigprocmask (SIG_BLOCK, &blocked_mask, NULL); @@ -376,7 +306,12 @@ lin_lwp_attach_lwp (ptid_t ptid, int verbose) if (ptrace (PTRACE_ATTACH, GET_LWP (ptid), 0, 0) < 0) error ("Can't attach %s: %s", target_pid_to_str (ptid), - strerror (errno)); + safe_strerror (errno)); + + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "LLAL: PTRACE_ATTACH %s, 0, 0 (OK)\n", + target_pid_to_str (ptid)); pid = waitpid (GET_LWP (ptid), &status, 0); if (pid == -1 && errno == ECHILD) @@ -389,16 +324,26 @@ lin_lwp_attach_lwp (ptid_t ptid, int verbose) gdb_assert (pid == GET_LWP (ptid) && WIFSTOPPED (status) && WSTOPSIG (status)); + child_post_attach (pid); + lp->stopped = 1; + + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "LLAL: waitpid %s received %s\n", + target_pid_to_str (ptid), + status_to_str (status)); + } } else { /* We assume that the LWP representing the original process - is already stopped. Mark it as stopped in the data structure - that the lin-lwp layer uses to keep track of threads. Note - that this won't have already been done since the main thread - will have, we assume, been stopped by an attach from a - different layer. */ + is already stopped. Mark it as stopped in the data structure + that the lin-lwp layer uses to keep track of threads. Note + that this won't have already been done since the main thread + will have, we assume, been stopped by an attach from a + different layer. */ lp->stopped = 1; } } @@ -438,6 +383,11 @@ lin_lwp_attach (char *args, int from_tty) /* Fake the SIGSTOP that core GDB expects. */ lp->status = W_STOPCODE (SIGSTOP); lp->resumed = 1; + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "LLA: waitpid %ld, faking SIGSTOP\n", (long) pid); + } } static int @@ -446,20 +396,33 @@ detach_callback (struct lwp_info *lp, void *data) gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status)); if (debug_lin_lwp && lp->status) - fprintf_unfiltered (gdb_stdlog, "Pending %s for LWP %ld on detach.\n", - strsignal (WSTOPSIG (lp->status)), GET_LWP (lp->ptid)); + fprintf_unfiltered (gdb_stdlog, "DC: Pending %s for %s on detach.\n", + strsignal (WSTOPSIG (lp->status)), + target_pid_to_str (lp->ptid)); while (lp->signalled && lp->stopped) { + errno = 0; if (ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, WSTOPSIG (lp->status)) < 0) error ("Can't continue %s: %s", target_pid_to_str (lp->ptid), - strerror (errno)); + safe_strerror (errno)); + + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "DC: PTRACE_CONTINUE (%s, 0, %s) (OK)\n", + target_pid_to_str (lp->ptid), + status_to_str (lp->status)); lp->stopped = 0; lp->signalled = 0; lp->status = 0; - stop_wait_callback (lp, NULL); + /* FIXME drow/2003-08-26: There was a call to stop_wait_callback + here. But since lp->signalled was cleared above, + stop_wait_callback didn't do anything; the process was left + running. Shouldn't we be waiting for it to stop? + I've removed the call, since stop_wait_callback now does do + something when called with lp->signalled == 0. */ gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status)); } @@ -468,10 +431,17 @@ detach_callback (struct lwp_info *lp, void *data) overall process id just yet. */ if (GET_LWP (lp->ptid) != GET_PID (lp->ptid)) { + errno = 0; if (ptrace (PTRACE_DETACH, GET_LWP (lp->ptid), 0, WSTOPSIG (lp->status)) < 0) error ("Can't detach %s: %s", target_pid_to_str (lp->ptid), - strerror (errno)); + safe_strerror (errno)); + + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "PTRACE_DETACH (%s, %s, 0) (OK)\n", + target_pid_to_str (lp->ptid), + strsignal (WSTOPSIG (lp->status))); delete_lwp (lp->ptid); } @@ -501,25 +471,6 @@ lin_lwp_detach (char *args, int from_tty) } -struct private_thread_info -{ - int lwpid; -}; - -/* Return non-zero if TP corresponds to the LWP specified by DATA - (which is assumed to be a pointer to a `struct lwp_info'. */ - -static int -find_lwp_callback (struct thread_info *tp, void *data) -{ - struct lwp_info *lp = data; - - if (tp->private->lwpid == GET_LWP (lp->ptid)) - return 1; - - return 0; -} - /* Resume LP. */ static int @@ -529,28 +480,11 @@ resume_callback (struct lwp_info *lp, void *data) { struct thread_info *tp; -#if 0 - /* FIXME: kettenis/2000-08-26: This should really be handled - properly by core GDB. */ - - tp = find_thread_pid (lp->ptid); - if (tp == NULL) - tp = iterate_over_threads (find_lwp_callback, lp); - gdb_assert (tp); - - /* If we were previously stepping the thread, and now continue - the thread we must invalidate the stepping range. However, - if there is a step_resume breakpoint for this thread, we must - preserve the stepping range to make it possible to continue - stepping once we hit it. */ - if (tp->step_range_end && tp->step_resume_breakpoint == NULL) - { - gdb_assert (lp->step); - tp->step_range_start = tp->step_range_end = 0; - } -#endif - child_resume (pid_to_ptid (GET_LWP (lp->ptid)), 0, TARGET_SIGNAL_0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "RC: PTRACE_CONT %s, 0, 0 (resume sibling)\n", + target_pid_to_str (lp->ptid)); lp->stopped = 0; lp->step = 0; } @@ -578,11 +512,8 @@ lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo) struct lwp_info *lp; int resume_all; - /* Apparently the interpretation of PID is dependent on STEP: If - STEP is non-zero, a specific PID means `step only this process - id'. But if STEP is zero, then PID means `continue *all* - processes, but give the signal only to this one'. */ - resume_all = (PIDGET (ptid) == -1) || !step; + /* A specific PTID means `step only this process id'. */ + resume_all = (PIDGET (ptid) == -1); if (resume_all) iterate_over_lwps (resume_set_callback, NULL); @@ -610,13 +541,13 @@ lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo) if (lp->status) { /* FIXME: What should we do if we are supposed to continue - this thread with a signal? */ + this thread with a signal? */ gdb_assert (signo == TARGET_SIGNAL_0); return; } /* Mark LWP as not stopped to prevent it from being continued by - resume_callback. */ + resume_callback. */ lp->stopped = 0; } @@ -624,20 +555,136 @@ lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo) iterate_over_lwps (resume_callback, NULL); child_resume (ptid, step, signo); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "LLR: %s %s, %s (resume event thread)\n", + step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT", + target_pid_to_str (ptid), + signo ? strsignal (signo) : "0"); } +/* Issue kill to specified lwp. */ + +static int tkill_failed; + +static int +kill_lwp (int lwpid, int signo) +{ + errno = 0; + +/* Use tkill, if possible, in case we are using nptl threads. If tkill + fails, then we are not using nptl threads and we should be using kill. */ + +#ifdef HAVE_TKILL_SYSCALL + if (!tkill_failed) + { + int ret = syscall (__NR_tkill, lwpid, signo); + if (errno != ENOSYS) + return ret; + errno = 0; + tkill_failed = 1; + } +#endif + + return kill (lwpid, signo); +} + +/* Wait for LP to stop. Returns the wait status, or 0 if the LWP has + exited. */ + +static int +wait_lwp (struct lwp_info *lp) +{ + pid_t pid; + int status; + int thread_dead = 0; + + gdb_assert (!lp->stopped); + gdb_assert (lp->status == 0); + + pid = waitpid (GET_LWP (lp->ptid), &status, 0); + if (pid == -1 && errno == ECHILD) + { + pid = waitpid (GET_LWP (lp->ptid), &status, __WCLONE); + if (pid == -1 && errno == ECHILD) + { + /* The thread has previously exited. We need to delete it now + because in the case of NPTL threads, there won't be an + exit event unless it is the main thread. */ + thread_dead = 1; + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, "WL: %s vanished.\n", + target_pid_to_str (lp->ptid)); + } + } + + if (!thread_dead) + { + gdb_assert (pid == GET_LWP (lp->ptid)); + + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "WL: waitpid %s received %s\n", + target_pid_to_str (lp->ptid), + status_to_str (status)); + } + } + + /* Check if the thread has exited. */ + if (WIFEXITED (status) || WIFSIGNALED (status)) + { + thread_dead = 1; + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, "WL: %s exited.\n", + target_pid_to_str (lp->ptid)); + } + + if (thread_dead) + { + if (in_thread_list (lp->ptid)) + { + /* Core GDB cannot deal with us deleting the current thread. */ + if (!ptid_equal (lp->ptid, inferior_ptid)) + delete_thread (lp->ptid); + printf_unfiltered ("[%s exited]\n", + target_pid_to_str (lp->ptid)); + } + + delete_lwp (lp->ptid); + return 0; + } + + gdb_assert (WIFSTOPPED (status)); + + return status; +} + /* Send a SIGSTOP to LP. */ static int stop_callback (struct lwp_info *lp, void *data) { - if (! lp->stopped && ! lp->signalled) + if (!lp->stopped && !lp->signalled) { int ret; - ret = kill (GET_LWP (lp->ptid), SIGSTOP); - gdb_assert (ret == 0); + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "SC: kill %s ****\n", + target_pid_to_str (lp->ptid)); + } + errno = 0; + ret = kill_lwp (GET_LWP (lp->ptid), SIGSTOP); + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "SC: lwp kill %d %s\n", + ret, + errno ? safe_strerror (errno) : "ERRNO-OK"); + } lp->signalled = 1; gdb_assert (lp->status == 0); @@ -654,48 +701,31 @@ stop_wait_callback (struct lwp_info *lp, void *data) { sigset_t *flush_mask = data; - if (! lp->stopped && lp->signalled) + if (!lp->stopped) { - pid_t pid; int status; - gdb_assert (lp->status == 0); - - pid = waitpid (GET_LWP (lp->ptid), &status, lp->cloned ? __WCLONE : 0); - if (pid == -1 && errno == ECHILD) - /* OK, the proccess has disappeared. We'll catch the actual - exit event in lin_lwp_wait. */ + status = wait_lwp (lp); + if (status == 0) return 0; - gdb_assert (pid == GET_LWP (lp->ptid)); - - if (WIFEXITED (status) || WIFSIGNALED (status)) - { - gdb_assert (num_lwps > 1); - - if (in_thread_list (lp->ptid)) - { - /* Core GDB cannot deal with us deleting the current - thread. */ - if (!ptid_equal (lp->ptid, inferior_ptid)) - delete_thread (lp->ptid); - printf_unfiltered ("[%s exited]\n", - target_pid_to_str (lp->ptid)); - } - if (debug_lin_lwp) - fprintf_unfiltered (gdb_stdlog, - "%s exited.\n", target_pid_to_str (lp->ptid)); - - delete_lwp (lp->ptid); - return 0; - } - - gdb_assert (WIFSTOPPED (status)); - /* Ignore any signals in FLUSH_MASK. */ if (flush_mask && sigismember (flush_mask, WSTOPSIG (status))) { + if (!lp->signalled) + { + lp->stopped = 1; + return 0; + } + + errno = 0; ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "PTRACE_CONT %s, 0, 0 (%s)\n", + target_pid_to_str (lp->ptid), + errno ? safe_strerror (errno) : "OK"); + return stop_wait_callback (lp, flush_mask); } @@ -704,31 +734,46 @@ stop_wait_callback (struct lwp_info *lp, void *data) if (WSTOPSIG (status) == SIGTRAP) { /* If a LWP other than the LWP that we're reporting an - event for has hit a GDB breakpoint (as opposed to - some random trap signal), then just arrange for it to - hit it again later. We don't keep the SIGTRAP status - and don't forward the SIGTRAP signal to the LWP. We - will handle the current event, eventually we will - resume all LWPs, and this one will get its breakpoint - trap again. + event for has hit a GDB breakpoint (as opposed to + some random trap signal), then just arrange for it to + hit it again later. We don't keep the SIGTRAP status + and don't forward the SIGTRAP signal to the LWP. We + will handle the current event, eventually we will + resume all LWPs, and this one will get its breakpoint + trap again. - If we do not do this, then we run the risk that the - user will delete or disable the breakpoint, but the - thread will have already tripped on it. */ + If we do not do this, then we run the risk that the + user will delete or disable the breakpoint, but the + thread will have already tripped on it. */ /* Now resume this LWP and get the SIGSTOP event. */ + errno = 0; ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); if (debug_lin_lwp) { - fprintf_unfiltered (gdb_stderr, - "SWC: Candidate SIGTRAP event in %ld\n", - GET_LWP (lp->ptid)); + fprintf_unfiltered (gdb_stdlog, + "PTRACE_CONT %s, 0, 0 (%s)\n", + target_pid_to_str (lp->ptid), + errno ? safe_strerror (errno) : "OK"); + + fprintf_unfiltered (gdb_stdlog, + "SWC: Candidate SIGTRAP event in %s\n", + target_pid_to_str (lp->ptid)); } /* Hold the SIGTRAP for handling by lin_lwp_wait. */ stop_wait_callback (lp, data); /* If there's another event, throw it back into the queue. */ if (lp->status) - kill (GET_LWP (lp->ptid), WSTOPSIG (lp->status)); + { + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "SWC: kill %s, %s\n", + target_pid_to_str (lp->ptid), + status_to_str ((int) status)); + } + kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status)); + } /* Save the sigtrap event. */ lp->status = status; return 0; @@ -736,34 +781,50 @@ stop_wait_callback (struct lwp_info *lp, void *data) else { /* The thread was stopped with a signal other than - SIGSTOP, and didn't accidentally trip a breakpoint. */ + SIGSTOP, and didn't accidentally trip a breakpoint. */ if (debug_lin_lwp) { - fprintf_unfiltered (gdb_stderr, - "SWC: Pending event %d in %ld\n", - WSTOPSIG (status), GET_LWP (lp->ptid)); + fprintf_unfiltered (gdb_stdlog, + "SWC: Pending event %s in %s\n", + status_to_str ((int) status), + target_pid_to_str (lp->ptid)); } /* Now resume this LWP and get the SIGSTOP event. */ + errno = 0; ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "SWC: PTRACE_CONT %s, 0, 0 (%s)\n", + target_pid_to_str (lp->ptid), + errno ? safe_strerror (errno) : "OK"); /* Hold this event/waitstatus while we check to see if - there are any more (we still want to get that SIGSTOP). */ + there are any more (we still want to get that SIGSTOP). */ stop_wait_callback (lp, data); /* If the lp->status field is still empty, use it to hold - this event. If not, then this event must be returned - to the event queue of the LWP. */ + this event. If not, then this event must be returned + to the event queue of the LWP. */ if (lp->status == 0) lp->status = status; else - kill (GET_LWP (lp->ptid), WSTOPSIG (status)); + { + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "SWC: kill %s, %s\n", + target_pid_to_str (lp->ptid), + status_to_str ((int) status)); + } + kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (status)); + } return 0; } } else { /* We caught the SIGSTOP that we intended to catch, so - there's no SIGSTOP pending. */ + there's no SIGSTOP pending. */ lp->stopped = 1; lp->signalled = 0; } @@ -772,6 +833,88 @@ stop_wait_callback (struct lwp_info *lp, void *data) return 0; } +/* Check whether PID has any pending signals in FLUSH_MASK. If so set + the appropriate bits in PENDING, and return 1 - otherwise return 0. */ + +static int +lin_lwp_has_pending (int pid, sigset_t *pending, sigset_t *flush_mask) +{ + sigset_t blocked, ignored; + int i; + + linux_proc_pending_signals (pid, pending, &blocked, &ignored); + + if (!flush_mask) + return 0; + + for (i = 1; i < NSIG; i++) + if (sigismember (pending, i)) + if (!sigismember (flush_mask, i) + || sigismember (&blocked, i) + || sigismember (&ignored, i)) + sigdelset (pending, i); + + if (sigisemptyset (pending)) + return 0; + + return 1; +} + +/* DATA is interpreted as a mask of signals to flush. If LP has + signals pending, and they are all in the flush mask, then arrange + to flush them. LP should be stopped, as should all other threads + it might share a signal queue with. */ + +static int +flush_callback (struct lwp_info *lp, void *data) +{ + sigset_t *flush_mask = data; + sigset_t pending, intersection, blocked, ignored; + int pid, status; + + /* Normally, when an LWP exits, it is removed from the LWP list. The + last LWP isn't removed till later, however. So if there is only + one LWP on the list, make sure it's alive. */ + if (lwp_list == lp && lp->next == NULL) + if (!lin_lwp_thread_alive (lp->ptid)) + return 0; + + /* Just because the LWP is stopped doesn't mean that new signals + can't arrive from outside, so this function must be careful of + race conditions. However, because all threads are stopped, we + can assume that the pending mask will not shrink unless we resume + the LWP, and that it will then get another signal. We can't + control which one, however. */ + + if (lp->status) + { + if (debug_lin_lwp) + printf_unfiltered ("FC: LP has pending status %06x\n", lp->status); + if (WIFSTOPPED (lp->status) && sigismember (flush_mask, WSTOPSIG (lp->status))) + lp->status = 0; + } + + while (lin_lwp_has_pending (GET_LWP (lp->ptid), &pending, flush_mask)) + { + int ret; + + errno = 0; + ret = ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stderr, + "FC: Sent PTRACE_CONT, ret %d %d\n", ret, errno); + + lp->stopped = 0; + stop_wait_callback (lp, flush_mask); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stderr, + "FC: Wait finished; saved status is %d\n", + lp->status); + } + + return 0; +} + /* Return non-zero if LP has a wait status pending. */ static int @@ -787,7 +930,7 @@ status_callback (struct lwp_info *lp, void *data) static int running_callback (struct lwp_info *lp, void *data) { - return (lp->stopped == 0); + return (lp->stopped == 0 || (lp->status != 0 && lp->resumed)); } /* Count the LWP's that have had events. */ @@ -857,14 +1000,14 @@ cancel_breakpoints_callback (struct lwp_info *lp, void *data) tripped on it. */ if (lp->status != 0 - && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP - && breakpoint_inserted_here_p (read_pc_pid (lp->ptid) - + && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP + && breakpoint_inserted_here_p (read_pc_pid (lp->ptid) - DECR_PC_AFTER_BREAK)) { if (debug_lin_lwp) fprintf_unfiltered (gdb_stdlog, - "Push back breakpoint for LWP %ld\n", - GET_LWP (lp->ptid)); + "CBC: Push back breakpoint for %s\n", + target_pid_to_str (lp->ptid)); /* Back up the PC if necessary. */ if (DECR_PC_AFTER_BREAK) @@ -895,13 +1038,13 @@ select_event_lwp (struct lwp_info **orig_lp, int *status) { if (debug_lin_lwp) fprintf_unfiltered (gdb_stdlog, - "Select single-step LWP %ld\n", - GET_LWP (event_lp->ptid)); + "SEL: Select single-step %s\n", + target_pid_to_str (event_lp->ptid)); } else { /* No single-stepping LWP. Select one at random, out of those - which have had SIGTRAP events. */ + which have had SIGTRAP events. */ /* First see how many SIGTRAP events we have. */ iterate_over_lwps (count_events_callback, &num_events); @@ -911,8 +1054,8 @@ select_event_lwp (struct lwp_info **orig_lp, int *status) ((num_events * (double) rand ()) / (RAND_MAX + 1.0)); if (debug_lin_lwp && num_events > 1) - fprintf_unfiltered (gdb_stdlog, - "Found %d SIGTRAP events, selecting #%d\n", + fprintf_unfiltered (gdb_stdlog, + "SEL: Found %d SIGTRAP events, selecting #%d\n", num_events, random_selector); event_lp = iterate_over_lwps (select_event_lwp_callback, @@ -923,7 +1066,7 @@ select_event_lwp (struct lwp_info **orig_lp, int *status) { /* Switch the event LWP. */ *orig_lp = event_lp; - *status = event_lp->status; + *status = event_lp->status; } /* Flush the wait status for the event LWP. */ @@ -964,16 +1107,51 @@ child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) if (pid == -1 && errno == ECHILD) /* Try again with __WCLONE to check cloned processes. */ pid = waitpid (GET_PID (ptid), &status, __WCLONE); + + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "CW: waitpid %ld received %s\n", + (long) pid, status_to_str (status)); + } + save_errno = errno; + /* Make sure we don't report an event for the exit of the + original program, if we've detached from it. */ + if (pid != -1 && !WIFSTOPPED (status) && pid != GET_PID (inferior_ptid)) + { + pid = -1; + save_errno = EINTR; + } + + /* Check for stop events reported by a process we didn't already + know about - in this case, anything other than inferior_ptid. + + If we're expecting to receive stopped processes after fork, + vfork, and clone events, then we'll just add the new one to + our list and go back to waiting for the event to be reported + - the stopped process might be returned from waitpid before + or after the event is. If we want to handle debugging of + CLONE_PTRACE processes we need to do more here, i.e. switch + to multi-threaded mode. */ + if (pid != -1 && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP + && pid != GET_PID (inferior_ptid)) + { + linux_record_stopped_pid (pid); + pid = -1; + save_errno = EINTR; + } + clear_sigio_trap (); clear_sigint_trap (); } - while (pid == -1 && errno == EINTR); + while (pid == -1 && save_errno == EINTR); if (pid == -1) { - warning ("Child process unexpectedly missing: %s", strerror (errno)); + warning ("Child process unexpectedly missing: %s", + safe_strerror (errno)); /* Claim it exited with unknown signal. */ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; @@ -981,12 +1159,38 @@ child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) return minus_one_ptid; } + /* Handle GNU/Linux's extended waitstatus for trace events. */ + if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) + return linux_handle_extended_wait (pid, status, ourstatus); + store_waitstatus (ourstatus, status); return pid_to_ptid (pid); } #endif +/* Stop an active thread, verify it still exists, then resume it. */ + +static int +stop_and_resume_callback (struct lwp_info *lp, void *data) +{ + struct lwp_info *ptr; + + if (!lp->stopped && !lp->signalled) + { + stop_callback (lp, NULL); + stop_wait_callback (lp, NULL); + /* Resume if the lwp still exists. */ + for (ptr = lwp_list; ptr; ptr = ptr->next) + if (lp == ptr) + { + resume_callback (lp, NULL); + resume_set_callback (lp, NULL); + } + } + return 0; +} + static ptid_t lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { @@ -999,13 +1203,13 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) sigemptyset (&flush_mask); /* Make sure SIGCHLD is blocked. */ - if (! sigismember (&blocked_mask, SIGCHLD)) + if (!sigismember (&blocked_mask, SIGCHLD)) { sigaddset (&blocked_mask, SIGCHLD); sigprocmask (SIG_BLOCK, &blocked_mask, NULL); } - retry: +retry: /* Make sure there is at least one LWP that has been resumed, at least if there are any LWPs at all. */ @@ -1023,8 +1227,9 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) if (debug_lin_lwp && status) fprintf_unfiltered (gdb_stdlog, - "Using pending wait status %s for LWP %ld.\n", - status_to_str (status), GET_LWP (lp->ptid)); + "LLW: Using pending wait status %s for %s.\n", + status_to_str (status), + target_pid_to_str (lp->ptid)); } /* But if we don't fine one, we'll have to wait, and check both @@ -1035,9 +1240,9 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) else if (is_lwp (ptid)) { if (debug_lin_lwp) - fprintf_unfiltered (gdb_stdlog, - "Waiting for specific LWP %ld.\n", - GET_LWP (ptid)); + fprintf_unfiltered (gdb_stdlog, + "LLW: Waiting for specific LWP %s.\n", + target_pid_to_str (ptid)); /* We have a specific LWP to check. */ lp = find_lwp_pid (ptid); @@ -1047,8 +1252,9 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) if (debug_lin_lwp && status) fprintf_unfiltered (gdb_stdlog, - "Using pending wait status %s for LWP %ld.\n", - status_to_str (status), GET_LWP (lp->ptid)); + "LLW: Using pending wait status %s for %s.\n", + status_to_str (status), + target_pid_to_str (lp->ptid)); /* If we have to wait, take into account whether PID is a cloned process or not. And we have to convert it to something that @@ -1060,18 +1266,24 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) if (status && lp->signalled) { /* A pending SIGSTOP may interfere with the normal stream of - events. In a typical case where interference is a problem, - we have a SIGSTOP signal pending for LWP A while - single-stepping it, encounter an event in LWP B, and take the - pending SIGSTOP while trying to stop LWP A. After processing - the event in LWP B, LWP A is continued, and we'll never see - the SIGTRAP associated with the last time we were - single-stepping LWP A. */ + events. In a typical case where interference is a problem, + we have a SIGSTOP signal pending for LWP A while + single-stepping it, encounter an event in LWP B, and take the + pending SIGSTOP while trying to stop LWP A. After processing + the event in LWP B, LWP A is continued, and we'll never see + the SIGTRAP associated with the last time we were + single-stepping LWP A. */ /* Resume the thread. It should halt immediately returning the - pending SIGSTOP. */ + pending SIGSTOP. */ + registers_changed (); child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, - TARGET_SIGNAL_0); + TARGET_SIGNAL_0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "LLW: %s %s, 0, 0 (expect SIGSTOP)\n", + lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT", + target_pid_to_str (lp->ptid)); lp->stopped = 0; gdb_assert (lp->resumed); @@ -1079,8 +1291,8 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) stop_wait_callback (lp, NULL); } - set_sigint_trap (); /* Causes SIGINT to be passed on to the - attached process. */ + set_sigint_trap (); /* Causes SIGINT to be passed on to the + attached process. */ set_sigio_trap (); while (status == 0) @@ -1092,8 +1304,49 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { gdb_assert (pid == -1 || lwpid == pid); + if (debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "LLW: waitpid %ld received %s\n", + (long) lwpid, status_to_str (status)); + } + lp = find_lwp_pid (pid_to_ptid (lwpid)); - if (! lp) + + /* Check for stop events reported by a process we didn't + already know about - anything not already in our LWP + list. + + If we're expecting to receive stopped processes after + fork, vfork, and clone events, then we'll just add the + new one to our list and go back to waiting for the event + to be reported - the stopped process might be returned + from waitpid before or after the event is. */ + if (WIFSTOPPED (status) && !lp) + { + linux_record_stopped_pid (lwpid); + status = 0; + continue; + } + + /* Make sure we don't report an event for the exit of an LWP not in + our list, i.e. not part of the current process. This can happen + if we detach from a program we original forked and then it + exits. */ + if (!WIFSTOPPED (status) && !lp) + { + status = 0; + continue; + } + + /* NOTE drow/2003-06-17: This code seems to be meant for debugging + CLONE_PTRACE processes which do not use the thread library - + otherwise we wouldn't find the new LWP this way. That doesn't + currently work, and the following code is currently unreachable + due to the two blocks above. If it's fixed some day, this code + should be broken out into a function so that we can also pick up + LWPs from the new interface. */ + if (!lp) { lp = add_lwp (BUILD_LWP (lwpid, GET_PID (inferior_ptid))); if (options & __WCLONE) @@ -1105,10 +1358,10 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) && WSTOPSIG (status) == SIGSTOP); lp->signalled = 1; - if (! in_thread_list (inferior_ptid)) + if (!in_thread_list (inferior_ptid)) { inferior_ptid = BUILD_LWP (GET_PID (inferior_ptid), - GET_PID (inferior_ptid)); + GET_PID (inferior_ptid)); add_thread (inferior_ptid); } @@ -1118,23 +1371,74 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) } } - /* Make sure we don't report a TARGET_WAITKIND_EXITED or - TARGET_WAITKIND_SIGNALLED event if there are still LWP's - left in the process. */ + /* Check if the thread has exited. */ if ((WIFEXITED (status) || WIFSIGNALED (status)) && num_lwps > 1) { if (in_thread_list (lp->ptid)) { /* Core GDB cannot deal with us deleting the current - thread. */ - if (! ptid_equal (lp->ptid, inferior_ptid)) + thread. */ + if (!ptid_equal (lp->ptid, inferior_ptid)) + delete_thread (lp->ptid); + printf_unfiltered ("[%s exited]\n", + target_pid_to_str (lp->ptid)); + } + + /* If this is the main thread, we must stop all threads and + verify if they are still alive. This is because in the nptl + thread model, there is no signal issued for exiting LWPs + other than the main thread. We only get the main thread + exit signal once all child threads have already exited. + If we stop all the threads and use the stop_wait_callback + to check if they have exited we can determine whether this + signal should be ignored or whether it means the end of the + debugged application, regardless of which threading model + is being used. */ + if (GET_PID (lp->ptid) == GET_LWP (lp->ptid)) + { + lp->stopped = 1; + iterate_over_lwps (stop_and_resume_callback, NULL); + } + + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "LLW: %s exited.\n", + target_pid_to_str (lp->ptid)); + + delete_lwp (lp->ptid); + + /* If there is at least one more LWP, then the exit signal + was not the end of the debugged application and should be + ignored. */ + if (num_lwps > 0) + { + /* Make sure there is at least one thread running. */ + gdb_assert (iterate_over_lwps (running_callback, NULL)); + + /* Discard the event. */ + status = 0; + continue; + } + } + + /* Check if the current LWP has previously exited. In the nptl + thread model, LWPs other than the main thread do not issue + signals when they exit so we must check whenever the thread + has stopped. A similar check is made in stop_wait_callback(). */ + if (num_lwps > 1 && !lin_lwp_thread_alive (lp->ptid)) + { + if (in_thread_list (lp->ptid)) + { + /* Core GDB cannot deal with us deleting the current + thread. */ + if (!ptid_equal (lp->ptid, inferior_ptid)) delete_thread (lp->ptid); printf_unfiltered ("[%s exited]\n", target_pid_to_str (lp->ptid)); } if (debug_lin_lwp) - fprintf_unfiltered (gdb_stdlog, - "%s exited.\n", + fprintf_unfiltered (gdb_stdlog, + "LLW: %s exited.\n", target_pid_to_str (lp->ptid)); delete_lwp (lp->ptid); @@ -1148,20 +1452,28 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) } /* Make sure we don't report a SIGSTOP that we sent - ourselves in an attempt to stop an LWP. */ - if (lp->signalled && WIFSTOPPED (status) - && WSTOPSIG (status) == SIGSTOP) + ourselves in an attempt to stop an LWP. */ + if (lp->signalled + && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP) { if (debug_lin_lwp) - fprintf_unfiltered (gdb_stdlog, - "Delayed SIGSTOP caught for %s.\n", + fprintf_unfiltered (gdb_stdlog, + "LLW: Delayed SIGSTOP caught for %s.\n", target_pid_to_str (lp->ptid)); /* This is a delayed SIGSTOP. */ lp->signalled = 0; + registers_changed (); child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, - TARGET_SIGNAL_0); + TARGET_SIGNAL_0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "LLW: %s %s, 0, 0 (discard SIGSTOP)\n", + lp->step ? + "PTRACE_SINGLESTEP" : "PTRACE_CONT", + target_pid_to_str (lp->ptid)); + lp->stopped = 0; gdb_assert (lp->resumed); @@ -1208,23 +1520,30 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) && signal_pass_state (signo) == 1) { /* FIMXE: kettenis/2001-06-06: Should we resume all threads - here? It is not clear we should. GDB may not expect - other threads to run. On the other hand, not resuming - newly attached threads may cause an unwanted delay in - getting them running. */ + here? It is not clear we should. GDB may not expect + other threads to run. On the other hand, not resuming + newly attached threads may cause an unwanted delay in + getting them running. */ + registers_changed (); child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, signo); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "LLW: %s %s, %s (preempt 'handle')\n", + lp->step ? + "PTRACE_SINGLESTEP" : "PTRACE_CONT", + target_pid_to_str (lp->ptid), + signo ? strsignal (signo) : "0"); lp->stopped = 0; status = 0; goto retry; } - if (signo == TARGET_SIGNAL_INT - && signal_pass_state (signo) == 0) + if (signo == TARGET_SIGNAL_INT && signal_pass_state (signo) == 0) { /* If ^C/BREAK is typed at the tty/console, SIGINT gets - forwarded to the entire process group, that is, all LWP's - will receive it. Since we only want to report it once, - we try to flush it from all LWPs except this one. */ + forwarded to the entire process group, that is, all LWP's + will receive it. Since we only want to report it once, + we try to flush it from all LWPs except this one. */ sigaddset (&flush_mask, SIGINT); } } @@ -1233,8 +1552,8 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) lp->stopped = 1; if (debug_lin_lwp) - fprintf_unfiltered (gdb_stdlog, "Candidate event %s in LWP %ld.\n", - status_to_str (status), GET_LWP (lp->ptid)); + fprintf_unfiltered (gdb_stdlog, "LLW: Candidate event %s in %s.\n", + status_to_str (status), target_pid_to_str (lp->ptid)); /* Now stop all other LWP's ... */ iterate_over_lwps (stop_callback, NULL); @@ -1242,6 +1561,7 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) /* ... and wait until all of them have reported back that they're no longer running. */ iterate_over_lwps (stop_wait_callback, &flush_mask); + iterate_over_lwps (flush_callback, &flush_mask); /* If we're not waiting for a specific LWP, choose an event LWP from among those that have had events. Giving equal priority to all @@ -1261,13 +1581,21 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { trap_ptid = (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid))); if (debug_lin_lwp) - fprintf_unfiltered (gdb_stdlog, - "LLW: trap_ptid is %ld\n", - GET_LWP (trap_ptid)); + fprintf_unfiltered (gdb_stdlog, + "LLW: trap_ptid is %s.\n", + target_pid_to_str (trap_ptid)); } else trap_ptid = null_ptid; + /* Handle GNU/Linux's extended waitstatus for trace events. */ + if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) + { + linux_handle_extended_wait (ptid_get_pid (trap_ptid), + status, ourstatus); + return trap_ptid; + } + store_waitstatus (ourstatus, status); return (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid))); } @@ -1275,7 +1603,14 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus) static int kill_callback (struct lwp_info *lp, void *data) { + errno = 0; ptrace (PTRACE_KILL, GET_LWP (lp->ptid), 0, 0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "KC: PTRACE_KILL %s, 0, 0 (%s)\n", + target_pid_to_str (lp->ptid), + errno ? safe_strerror (errno) : "OK"); + return 0; } @@ -1296,6 +1631,12 @@ kill_wait_callback (struct lwp_info *lp, void *data) do { pid = waitpid (GET_LWP (lp->ptid), NULL, __WCLONE); + if (pid != (pid_t) -1 && debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "KWC: wait %s received unknown.\n", + target_pid_to_str (lp->ptid)); + } } while (pid == GET_LWP (lp->ptid)); @@ -1305,6 +1646,12 @@ kill_wait_callback (struct lwp_info *lp, void *data) do { pid = waitpid (GET_LWP (lp->ptid), NULL, 0); + if (pid != (pid_t) -1 && debug_lin_lwp) + { + fprintf_unfiltered (gdb_stdlog, + "KWC: wait %s received unk.\n", + target_pid_to_str (lp->ptid)); + } } while (pid == GET_LWP (lp->ptid)); @@ -1330,7 +1677,7 @@ lin_lwp_create_inferior (char *exec_file, char *allargs, char **env) child_ops.to_create_inferior (exec_file, allargs, env); } -static void +static void lin_lwp_mourn_inferior (void) { trap_ptid = null_ptid; @@ -1345,36 +1692,9 @@ lin_lwp_mourn_inferior (void) child_ops.to_mourn_inferior (); } -static void -lin_lwp_fetch_registers (int regno) -{ - struct cleanup *old_chain = save_inferior_ptid (); - - if (is_lwp (inferior_ptid)) - inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid)); - - fetch_inferior_registers (regno); - - do_cleanups (old_chain); -} - -static void -lin_lwp_store_registers (int regno) -{ - struct cleanup *old_chain = save_inferior_ptid (); - - if (is_lwp (inferior_ptid)) - inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid)); - - store_inferior_registers (regno); - - do_cleanups (old_chain); -} - static int lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, - struct target_ops *target) + struct mem_attrib *attrib, struct target_ops *target) { struct cleanup *old_chain = save_inferior_ptid (); int xfer; @@ -1382,7 +1702,9 @@ lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, if (is_lwp (inferior_ptid)) inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid)); - xfer = child_xfer_memory (memaddr, myaddr, len, write, attrib, target); + xfer = linux_proc_xfer_memory (memaddr, myaddr, len, write, attrib, target); + if (xfer == 0) + xfer = child_xfer_memory (memaddr, myaddr, len, write, attrib, target); do_cleanups (old_chain); return xfer; @@ -1395,6 +1717,11 @@ lin_lwp_thread_alive (ptid_t ptid) errno = 0; ptrace (PTRACE_PEEKUSER, GET_LWP (ptid), 0, 0); + if (debug_lin_lwp) + fprintf_unfiltered (gdb_stdlog, + "LLTA: PTRACE_PEEKUSER %s, 0, 0 (%s)\n", + target_pid_to_str (ptid), + errno ? safe_strerror (errno) : "OK"); if (errno) return 0; @@ -1428,14 +1755,22 @@ init_lin_lwp_ops (void) lin_lwp_ops.to_detach = lin_lwp_detach; lin_lwp_ops.to_resume = lin_lwp_resume; lin_lwp_ops.to_wait = lin_lwp_wait; - lin_lwp_ops.to_fetch_registers = lin_lwp_fetch_registers; - lin_lwp_ops.to_store_registers = lin_lwp_store_registers; + /* fetch_inferior_registers and store_inferior_registers will + honor the LWP id, so we can use them directly. */ + lin_lwp_ops.to_fetch_registers = fetch_inferior_registers; + lin_lwp_ops.to_store_registers = store_inferior_registers; lin_lwp_ops.to_xfer_memory = lin_lwp_xfer_memory; lin_lwp_ops.to_kill = lin_lwp_kill; lin_lwp_ops.to_create_inferior = lin_lwp_create_inferior; lin_lwp_ops.to_mourn_inferior = lin_lwp_mourn_inferior; lin_lwp_ops.to_thread_alive = lin_lwp_thread_alive; lin_lwp_ops.to_pid_to_str = lin_lwp_pid_to_str; + lin_lwp_ops.to_post_startup_inferior = child_post_startup_inferior; + lin_lwp_ops.to_post_attach = child_post_attach; + lin_lwp_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint; + lin_lwp_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint; + lin_lwp_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint; + lin_lwp_ops.to_stratum = thread_stratum; lin_lwp_ops.to_has_thread_control = tc_schedlock; lin_lwp_ops.to_magic = OPS_MAGIC; @@ -1475,11 +1810,9 @@ _initialize_lin_lwp (void) sigemptyset (&blocked_mask); add_show_from_set (add_set_cmd ("lin-lwp", no_class, var_zinteger, - (char *) &debug_lin_lwp, + (char *) &debug_lin_lwp, "Set debugging of GNU/Linux lwp module.\n\ -Enables printf debugging output.\n", - &setdebuglist), - &showdebuglist); +Enables printf debugging output.\n", &setdebuglist), &showdebuglist); } diff --git a/contrib/gdb/gdb/linespec.c b/contrib/gdb/gdb/linespec.c index ca9d01ddae6..eedc671fd00 100644 --- a/contrib/gdb/gdb/linespec.c +++ b/contrib/gdb/gdb/linespec.c @@ -1,6 +1,6 @@ /* Parser for linespec for the GNU debugger, GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -26,15 +26,15 @@ #include "command.h" #include "symfile.h" #include "objfiles.h" +#include "source.h" #include "demangle.h" #include "value.h" #include "completer.h" #include "cp-abi.h" - -/* Prototype for one function in parser-defs.h, - instead of including that entire file. */ - -extern char *find_template_name_end (char *); +#include "parser-defs.h" +#include "block.h" +#include "objc-lang.h" +#include "linespec.h" /* We share this one with symtab.c, but it is not exported widely. */ @@ -42,27 +42,106 @@ extern char *operator_chars (char *, char **); /* Prototypes for local functions */ -static void cplusplus_error (const char *name, const char *fmt, ...) ATTR_FORMAT (printf, 2, 3); +static void initialize_defaults (struct symtab **default_symtab, + int *default_line); + +static void set_flags (char *arg, int *is_quoted, char **paren_pointer); + +static struct symtabs_and_lines decode_indirect (char **argptr); + +static char *locate_first_half (char **argptr, int *is_quote_enclosed); + +static struct symtabs_and_lines decode_objc (char **argptr, + int funfirstline, + struct symtab *file_symtab, + char ***canonical, + char *saved_arg); + +static struct symtabs_and_lines decode_compound (char **argptr, + int funfirstline, + char ***canonical, + char *saved_arg, + char *p); + +static struct symbol *lookup_prefix_sym (char **argptr, char *p); + +static struct symtabs_and_lines find_method (int funfirstline, + char ***canonical, + char *saved_arg, + char *copy, + struct type *t, + struct symbol *sym_class); + +static int collect_methods (char *copy, struct type *t, + struct symbol **sym_arr); + +static NORETURN void cplusplus_error (const char *name, + const char *fmt, ...) + ATTR_NORETURN ATTR_FORMAT (printf, 2, 3); static int total_number_of_methods (struct type *type); static int find_methods (struct type *, char *, struct symbol **); +static int add_matching_methods (int method_counter, struct type *t, + struct symbol **sym_arr); + +static int add_constructors (int method_counter, struct type *t, + struct symbol **sym_arr); + static void build_canonical_line_spec (struct symtab_and_line *, char *, char ***); static char *find_toplevel_char (char *s, char c); +static int is_objc_method_format (const char *s); + static struct symtabs_and_lines decode_line_2 (struct symbol *[], int, int, char ***); +static struct symtab *symtab_from_filename (char **argptr, + char *p, int is_quote_enclosed, + int *not_found_ptr); + +static struct +symtabs_and_lines decode_all_digits (char **argptr, + struct symtab *default_symtab, + int default_line, + char ***canonical, + struct symtab *file_symtab, + char *q); + +static struct symtabs_and_lines decode_dollar (char *copy, + int funfirstline, + struct symtab *default_symtab, + char ***canonical, + struct symtab *file_symtab); + +static struct symtabs_and_lines decode_variable (char *copy, + int funfirstline, + char ***canonical, + struct symtab *file_symtab, + int *not_found_ptr); + +static struct +symtabs_and_lines symbol_found (int funfirstline, + char ***canonical, + char *copy, + struct symbol *sym, + struct symtab *file_symtab, + struct symtab *sym_symtab); + +static struct +symtabs_and_lines minsym_found (int funfirstline, + struct minimal_symbol *msymbol); + /* Helper functions. */ /* Issue a helpful hint on using the command completion feature on single quoted demangled C++ symbols as part of the completion error. */ -static void +static NORETURN void cplusplus_error (const char *name, const char *fmt, ...) { struct ui_file *tmp_stream; @@ -126,10 +205,11 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr) the class, then the loop can't do any good. */ if (class_name && (lookup_symbol (class_name, (struct block *) NULL, - STRUCT_NAMESPACE, (int *) NULL, + STRUCT_DOMAIN, (int *) NULL, (struct symtab **) NULL))) { int method_counter; + int name_len = strlen (name); CHECK_TYPEDEF (t); @@ -141,7 +221,6 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr) method_counter >= 0; --method_counter) { - int field_counter; char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter); char dem_opname[64]; @@ -157,84 +236,13 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr) if (strcmp_iw (name, method_name) == 0) /* Find all the overloaded methods with that name. */ - for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; - field_counter >= 0; - --field_counter) - { - struct fn_field *f; - char *phys_name; - - f = TYPE_FN_FIELDLIST1 (t, method_counter); - - if (TYPE_FN_FIELD_STUB (f, field_counter)) - { - char *tmp_name; - - tmp_name = gdb_mangle_name (t, - method_counter, - field_counter); - phys_name = alloca (strlen (tmp_name) + 1); - strcpy (phys_name, tmp_name); - xfree (tmp_name); - } - else - phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); - - /* Destructor is handled by caller, dont add it to the list */ - if (is_destructor_name (phys_name) != 0) - continue; - - sym_arr[i1] = lookup_symbol (phys_name, - NULL, VAR_NAMESPACE, - (int *) NULL, - (struct symtab **) NULL); - if (sym_arr[i1]) - i1++; - else - { - /* This error message gets printed, but the method - still seems to be found - fputs_filtered("(Cannot find method ", gdb_stdout); - fprintf_symbol_filtered (gdb_stdout, phys_name, - language_cplus, - DMGL_PARAMS | DMGL_ANSI); - fputs_filtered(" - possibly inlined.)\n", gdb_stdout); - */ - } - } - else if (strcmp_iw (class_name, name) == 0) - { - /* For GCC 3.x and stabs, constructors and destructors have names - like __base_ctor and __complete_dtor. Check the physname for now - if we're looking for a constructor. */ - for (field_counter - = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; - field_counter >= 0; - --field_counter) - { - struct fn_field *f; - char *phys_name; - - f = TYPE_FN_FIELDLIST1 (t, method_counter); - - /* GCC 3.x will never produce stabs stub methods, so we don't need - to handle this case. */ - if (TYPE_FN_FIELD_STUB (f, field_counter)) - continue; - phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); - if (! is_constructor_name (phys_name)) - continue; - - /* If this method is actually defined, include it in the - list. */ - sym_arr[i1] = lookup_symbol (phys_name, - NULL, VAR_NAMESPACE, - (int *) NULL, - (struct symtab **) NULL); - if (sym_arr[i1]) - i1++; - } - } + i1 += add_matching_methods (method_counter, t, + sym_arr + i1); + else if (strncmp (class_name, name, name_len) == 0 + && (class_name[name_len] == '\0' + || class_name[name_len] == '<')) + i1 += add_constructors (method_counter, t, + sym_arr + i1); } } @@ -256,6 +264,113 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr) return i1; } +/* Add the symbols associated to methods of the class whose type is T + and whose name matches the method indexed by METHOD_COUNTER in the + array SYM_ARR. Return the number of methods added. */ + +static int +add_matching_methods (int method_counter, struct type *t, + struct symbol **sym_arr) +{ + int field_counter; + int i1 = 0; + + for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; + field_counter >= 0; + --field_counter) + { + struct fn_field *f; + char *phys_name; + + f = TYPE_FN_FIELDLIST1 (t, method_counter); + + if (TYPE_FN_FIELD_STUB (f, field_counter)) + { + char *tmp_name; + + tmp_name = gdb_mangle_name (t, + method_counter, + field_counter); + phys_name = alloca (strlen (tmp_name) + 1); + strcpy (phys_name, tmp_name); + xfree (tmp_name); + } + else + phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); + + /* Destructor is handled by caller, don't add it to + the list. */ + if (is_destructor_name (phys_name) != 0) + continue; + + sym_arr[i1] = lookup_symbol (phys_name, + NULL, VAR_DOMAIN, + (int *) NULL, + (struct symtab **) NULL); + if (sym_arr[i1]) + i1++; + else + { + /* This error message gets printed, but the method + still seems to be found + fputs_filtered("(Cannot find method ", gdb_stdout); + fprintf_symbol_filtered (gdb_stdout, phys_name, + language_cplus, + DMGL_PARAMS | DMGL_ANSI); + fputs_filtered(" - possibly inlined.)\n", gdb_stdout); + */ + } + } + + return i1; +} + +/* Add the symbols associated to constructors of the class whose type + is CLASS_TYPE and which are indexed by by METHOD_COUNTER to the + array SYM_ARR. Return the number of methods added. */ + +static int +add_constructors (int method_counter, struct type *t, + struct symbol **sym_arr) +{ + int field_counter; + int i1 = 0; + + /* For GCC 3.x and stabs, constructors and destructors + have names like __base_ctor and __complete_dtor. + Check the physname for now if we're looking for a + constructor. */ + for (field_counter + = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; + field_counter >= 0; + --field_counter) + { + struct fn_field *f; + char *phys_name; + + f = TYPE_FN_FIELDLIST1 (t, method_counter); + + /* GCC 3.x will never produce stabs stub methods, so + we don't need to handle this case. */ + if (TYPE_FN_FIELD_STUB (f, field_counter)) + continue; + phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); + if (! is_constructor_name (phys_name)) + continue; + + /* If this method is actually defined, include it in the + list. */ + sym_arr[i1] = lookup_symbol (phys_name, + NULL, VAR_DOMAIN, + (int *) NULL, + (struct symtab **) NULL); + if (sym_arr[i1]) + i1++; + } + + return i1; +} + /* Helper function for decode_line_1. Build a canonical line spec in CANONICAL if it is non-NULL and if the SAL has a symtab. @@ -298,14 +413,16 @@ build_canonical_line_spec (struct symtab_and_line *sal, char *symname, /* Find an instance of the character C in the string S that is outside of all parenthesis pairs, single-quoted strings, and double-quoted - strings. */ + strings. Also, ignore the char within a template name, like a ',' + within foo. */ + static char * find_toplevel_char (char *s, char c) { int quoted = 0; /* zero if we're not in quotes; '"' if we're in a double-quoted string; '\'' if we're in a single-quoted string. */ - int depth = 0; /* number of unclosed parens we've seen */ + int depth = 0; /* Number of unclosed parens we've seen. */ char *scan; for (scan = s; *scan; scan++) @@ -321,15 +438,34 @@ find_toplevel_char (char *s, char c) return scan; else if (*scan == '"' || *scan == '\'') quoted = *scan; - else if (*scan == '(') + else if (*scan == '(' || *scan == '<') depth++; - else if (*scan == ')' && depth > 0) + else if ((*scan == ')' || *scan == '>') && depth > 0) depth--; } return 0; } +/* Determines if the gives string corresponds to an Objective-C method + representation, such as -[Foo bar:] or +[Foo bar]. Objective-C symbols + are allowed to have spaces and parentheses in them. */ + +static int +is_objc_method_format (const char *s) +{ + if (s == NULL || *s == '\0') + return 0; + /* Handle arguments with the format FILENAME:SYMBOL. */ + if ((s[0] == ':') && (strchr ("+-", s[1]) != NULL) + && (s[2] == '[') && strchr(s, ']')) + return 1; + /* Handle arguments that are just SYMBOL. */ + else if ((strchr ("+-", s[0]) != NULL) && (s[1] == '[') && strchr(s, ']')) + return 1; + return 0; +} + /* Given a list of NELTS symbols in SYM_ARR, return a list of lines to operate on (ask user if necessary). If CANONICAL is non-NULL return a corresponding array of mangled names @@ -365,23 +501,31 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, printf_unfiltered ("[0] cancel\n[1] all\n"); while (i < nelts) { - INIT_SAL (&return_values.sals[i]); /* initialize to zeroes */ - INIT_SAL (&values.sals[i]); + init_sal (&return_values.sals[i]); /* Initialize to zeroes. */ + init_sal (&values.sals[i]); if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK) { values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline); - printf_unfiltered ("[%d] %s at %s:%d\n", - (i + 2), - SYMBOL_SOURCE_NAME (sym_arr[i]), - values.sals[i].symtab->filename, - values.sals[i].line); + if (values.sals[i].symtab) + printf_unfiltered ("[%d] %s at %s:%d\n", + (i + 2), + SYMBOL_PRINT_NAME (sym_arr[i]), + values.sals[i].symtab->filename, + values.sals[i].line); + else + printf_unfiltered ("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n", + (i + 2), + SYMBOL_PRINT_NAME (sym_arr[i]), + values.sals[i].line); + } else printf_unfiltered ("?HERE\n"); i++; } - if ((prompt = getenv ("PS2")) == NULL) + prompt = getenv ("PS2"); + if (prompt == NULL) { prompt = "> "; } @@ -413,7 +557,7 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, { if (canonical_arr[i] == NULL) { - symname = SYMBOL_NAME (sym_arr[i]); + symname = DEPRECATED_SYMBOL_NAME (sym_arr[i]); canonical_arr[i] = savestring (symname, strlen (symname)); } } @@ -436,7 +580,7 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, { if (canonical_arr) { - symname = SYMBOL_NAME (sym_arr[num]); + symname = DEPRECATED_SYMBOL_NAME (sym_arr[num]); make_cleanup (xfree, symname); canonical_arr[i] = savestring (symname, strlen (symname)); } @@ -495,7 +639,12 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, Note that it is possible to return zero for the symtab if no file is validly specified. Callers must check that. - Also, the line number returned may be invalid. */ + Also, the line number returned may be invalid. + + If NOT_FOUND_PTR is not null, store a boolean true/false value at the location, based + on whether or not failure occurs due to an unknown function or file. In the case + where failure does occur due to an unknown function or file, do not issue an error + message. */ /* We allow single quotes in various places. This is a hideous kludge, which exists because the completer can't yet deal with the @@ -504,460 +653,96 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, struct symtabs_and_lines decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, - int default_line, char ***canonical) + int default_line, char ***canonical, int *not_found_ptr) { - struct symtabs_and_lines values; - struct symtab_and_line val; - register char *p, *p1; - char *q, *pp, *ii, *p2; -#if 0 - char *q1; -#endif - register struct symtab *s; + char *p; + char *q; + /* If a file name is specified, this is its symtab. */ + struct symtab *file_symtab = NULL; - register struct symbol *sym; - /* The symtab that SYM was found in. */ - struct symtab *sym_symtab; - - register CORE_ADDR pc; - register struct minimal_symbol *msymbol; char *copy; - struct symbol *sym_class; - int i1; + /* This is NULL if there are no parens in *ARGPTR, or a pointer to + the closing parenthesis if there are parens. */ + char *paren_pointer; + /* This says whether or not something in *ARGPTR is quoted with + completer_quotes (i.e. with single quotes). */ int is_quoted; + /* Is part of *ARGPTR is enclosed in double quotes? */ int is_quote_enclosed; - int has_parens; - int has_if = 0; - int has_comma = 0; - struct symbol **sym_arr; - struct type *t; + int is_objc_method = 0; char *saved_arg = *argptr; - extern char *gdb_completer_quote_characters; - INIT_SAL (&val); /* initialize to zeroes */ + if (not_found_ptr) + *not_found_ptr = 0; /* Defaults have defaults. */ - if (default_symtab == 0) - { - default_symtab = current_source_symtab; - default_line = current_source_line; - } - - /* See if arg is *PC */ + initialize_defaults (&default_symtab, &default_line); + + /* See if arg is *PC. */ if (**argptr == '*') + return decode_indirect (argptr); + + /* Set various flags. 'paren_pointer' is important for overload + checking, where we allow things like: + (gdb) break c::f(int) + */ + + set_flags (*argptr, &is_quoted, &paren_pointer); + + /* Check to see if it's a multipart linespec (with colons or + periods). */ + + /* Locate the end of the first half of the linespec. + After the call, for instance, if the argptr string is "foo.c:123" + p will point at "123". If there is only one part, like "foo", p + will point to "". If this is a C++ name, like "A::B::foo", p will + point to "::B::foo". Argptr is not changed by this call. */ + + p = locate_first_half (argptr, &is_quote_enclosed); + + /* Check if this is an Objective-C method (anything that starts with + a '+' or '-' and a '['). */ + if (is_objc_method_format (p)) { - (*argptr)++; - pc = parse_and_eval_address_1 (argptr); + is_objc_method = 1; + paren_pointer = NULL; /* Just a category name. Ignore it. */ + } - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - - values.nelts = 1; - values.sals[0] = find_pc_line (pc, 0); - values.sals[0].pc = pc; - values.sals[0].section = find_pc_overlay (pc); + /* Check if the symbol could be an Objective-C selector. */ + { + struct symtabs_and_lines values; + values = decode_objc (argptr, funfirstline, NULL, + canonical, saved_arg); + if (values.sals != NULL) return values; - } + } - /* 'has_if' is for the syntax: - * (gdb) break foo if (a==b) - */ - if ((ii = strstr (*argptr, " if ")) != NULL || - (ii = strstr (*argptr, "\tif ")) != NULL || - (ii = strstr (*argptr, " if\t")) != NULL || - (ii = strstr (*argptr, "\tif\t")) != NULL || - (ii = strstr (*argptr, " if(")) != NULL || - (ii = strstr (*argptr, "\tif( ")) != NULL) - has_if = 1; - /* Temporarily zap out "if (condition)" to not - * confuse the parenthesis-checking code below. - * This is undone below. Do not change ii!! - */ - if (has_if) + /* Does it look like there actually were two parts? */ + + if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL) { - *ii = '\0'; - } - - /* Set various flags. - * 'has_parens' is important for overload checking, where - * we allow things like: - * (gdb) break c::f(int) - */ - - /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ - - is_quoted = (**argptr - && strchr (get_gdb_completer_quote_characters (), - **argptr) != NULL); - - has_parens = ((pp = strchr (*argptr, '(')) != NULL - && (pp = strrchr (pp, ')')) != NULL); - - /* Now that we're safely past the has_parens check, - * put back " if (condition)" so outer layers can see it - */ - if (has_if) - *ii = ' '; - - /* Maybe we were called with a line range FILENAME:LINENUM,FILENAME:LINENUM - and we must isolate the first half. Outer layers will call again later - for the second half. - - Don't count commas that appear in argument lists of overloaded - functions, or in quoted strings. It's stupid to go to this much - trouble when the rest of the function is such an obvious roach hotel. */ - ii = find_toplevel_char (*argptr, ','); - has_comma = (ii != 0); - - /* Temporarily zap out second half to not - * confuse the code below. - * This is undone below. Do not change ii!! - */ - if (has_comma) - { - *ii = '\0'; - } - - /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ - /* May also be CLASS::MEMBER, or NAMESPACE::NAME */ - /* Look for ':', but ignore inside of <> */ - - s = NULL; - p = *argptr; - if (p[0] == '"') - { - is_quote_enclosed = 1; - (*argptr)++; - p++; - } - else - is_quote_enclosed = 0; - for (; *p; p++) - { - if (p[0] == '<') - { - char *temp_end = find_template_name_end (p); - if (!temp_end) - error ("malformed template specification in command"); - p = temp_end; - } - /* Check for the end of the first half of the linespec. End of line, - a tab, a double colon or the last single colon, or a space. But - if enclosed in double quotes we do not break on enclosed spaces */ - if (!*p - || p[0] == '\t' - || ((p[0] == ':') - && ((p[1] == ':') || (strchr (p + 1, ':') == NULL))) - || ((p[0] == ' ') && !is_quote_enclosed)) - break; - if (p[0] == '.' && strchr (p, ':') == NULL) /* Java qualified method. */ - { - /* Find the *last* '.', since the others are package qualifiers. */ - for (p1 = p; *p1; p1++) - { - if (*p1 == '.') - p = p1; - } - break; - } - } - while (p[0] == ' ' || p[0] == '\t') - p++; - - /* if the closing double quote was left at the end, remove it */ - if (is_quote_enclosed) - { - char *closing_quote = strchr (p - 1, '"'); - if (closing_quote && closing_quote[1] == '\0') - *closing_quote = '\0'; - } - - /* Now that we've safely parsed the first half, - * put back ',' so outer layers can see it - */ - if (has_comma) - *ii = ','; - - if ((p[0] == ':' || p[0] == '.') && !has_parens) - { - /* C++ */ - /* ... or Java */ if (is_quoted) *argptr = *argptr + 1; + + /* Is it a C++ or Java compound data structure? + The check on p[1] == ':' is capturing the case of "::", + since p[0]==':' was checked above. + Note that the call to decode_compound does everything + for us, including the lookup on the symbol table, so we + can return now. */ + if (p[0] == '.' || p[1] == ':') - { - char *saved_arg2 = *argptr; - char *temp_end; - /* First check for "global" namespace specification, - of the form "::foo". If found, skip over the colons - and jump to normal symbol processing */ - if (p[0] == ':' - && ((*argptr == p) || (p[-1] == ' ') || (p[-1] == '\t'))) - saved_arg2 += 2; + return decode_compound (argptr, funfirstline, canonical, + saved_arg, p); - /* We have what looks like a class or namespace - scope specification (A::B), possibly with many - levels of namespaces or classes (A::B::C::D). + /* No, the first part is a filename; set s to be that file's + symtab. Also, move argptr past the filename. */ - Some versions of the HP ANSI C++ compiler (as also possibly - other compilers) generate class/function/member names with - embedded double-colons if they are inside namespaces. To - handle this, we loop a few times, considering larger and - larger prefixes of the string as though they were single - symbols. So, if the initially supplied string is - A::B::C::D::foo, we have to look up "A", then "A::B", - then "A::B::C", then "A::B::C::D", and finally - "A::B::C::D::foo" as single, monolithic symbols, because - A, B, C or D may be namespaces. - - Note that namespaces can nest only inside other - namespaces, and not inside classes. So we need only - consider *prefixes* of the string; there is no need to look up - "B::C" separately as a symbol in the previous example. */ - - p2 = p; /* save for restart */ - while (1) - { - /* Extract the class name. */ - p1 = p; - while (p != *argptr && p[-1] == ' ') - --p; - copy = (char *) alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = 0; - - /* Discard the class name from the arg. */ - p = p1 + (p1[0] == ':' ? 2 : 1); - while (*p == ' ' || *p == '\t') - p++; - *argptr = p; - - sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE, 0, - (struct symtab **) NULL); - - if (sym_class && - (t = check_typedef (SYMBOL_TYPE (sym_class)), - (TYPE_CODE (t) == TYPE_CODE_STRUCT - || TYPE_CODE (t) == TYPE_CODE_UNION))) - { - /* Arg token is not digits => try it as a function name - Find the next token(everything up to end or next blank). */ - if (**argptr - && strchr (get_gdb_completer_quote_characters (), - **argptr) != NULL) - { - p = skip_quoted (*argptr); - *argptr = *argptr + 1; - } - else - { - p = *argptr; - while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':') - p++; - } -/* - q = operator_chars (*argptr, &q1); - if (q1 - q) - { - char *opname; - char *tmp = alloca (q1 - q + 1); - memcpy (tmp, q, q1 - q); - tmp[q1 - q] = '\0'; - opname = cplus_mangle_opname (tmp, DMGL_ANSI); - if (opname == NULL) - { - cplusplus_error (saved_arg, "no mangling for \"%s\"\n", tmp); - } - copy = (char*) alloca (3 + strlen(opname)); - sprintf (copy, "__%s", opname); - p = q1; - } - else - */ - { - copy = (char *) alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = '\0'; - if (p != *argptr - && copy[p - *argptr - 1] - && strchr (get_gdb_completer_quote_characters (), - copy[p - *argptr - 1]) != NULL) - copy[p - *argptr - 1] = '\0'; - } - - /* no line number may be specified */ - while (*p == ' ' || *p == '\t') - p++; - *argptr = p; - - sym = 0; - i1 = 0; /* counter for the symbol array */ - sym_arr = (struct symbol **) alloca (total_number_of_methods (t) - * sizeof (struct symbol *)); - - if (destructor_name_p (copy, t)) - { - /* Destructors are a special case. */ - int m_index, f_index; - - if (get_destructor_fn_field (t, &m_index, &f_index)) - { - struct fn_field *f = TYPE_FN_FIELDLIST1 (t, m_index); - - sym_arr[i1] = - lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, f_index), - NULL, VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (sym_arr[i1]) - i1++; - } - } - else - i1 = find_methods (t, copy, sym_arr); - if (i1 == 1) - { - /* There is exactly one field with that name. */ - sym = sym_arr[0]; - - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) - { - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.nelts = 1; - values.sals[0] = find_function_start_sal (sym, - funfirstline); - } - else - { - values.nelts = 0; - } - return values; - } - if (i1 > 0) - { - /* There is more than one field with that name - (overloaded). Ask the user which one to use. */ - return decode_line_2 (sym_arr, i1, funfirstline, canonical); - } - else - { - char *tmp; - - if (is_operator_name (copy)) - { - tmp = (char *) alloca (strlen (copy + 3) + 9); - strcpy (tmp, "operator "); - strcat (tmp, copy + 3); - } - else - tmp = copy; - if (tmp[0] == '~') - cplusplus_error (saved_arg, - "the class `%s' does not have destructor defined\n", - SYMBOL_SOURCE_NAME (sym_class)); - else - cplusplus_error (saved_arg, - "the class %s does not have any method named %s\n", - SYMBOL_SOURCE_NAME (sym_class), tmp); - } - } - - /* Move pointer up to next possible class/namespace token */ - p = p2 + 1; /* restart with old value +1 */ - /* Move pointer ahead to next double-colon */ - while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')) - { - if (p[0] == '<') - { - temp_end = find_template_name_end (p); - if (!temp_end) - error ("malformed template specification in command"); - p = temp_end; - } - else if ((p[0] == ':') && (p[1] == ':')) - break; /* found double-colon */ - else - p++; - } - - if (*p != ':') - break; /* out of the while (1) */ - - p2 = p; /* save restart for next time around */ - *argptr = saved_arg2; /* restore argptr */ - } /* while (1) */ - - /* Last chance attempt -- check entire name as a symbol */ - /* Use "copy" in preparation for jumping out of this block, - to be consistent with usage following the jump target */ - copy = (char *) alloca (p - saved_arg2 + 1); - memcpy (copy, saved_arg2, p - saved_arg2); - /* Note: if is_quoted should be true, we snuff out quote here anyway */ - copy[p - saved_arg2] = '\000'; - /* Set argptr to skip over the name */ - *argptr = (*p == '\'') ? p + 1 : p; - /* Look up entire name */ - sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab); - s = (struct symtab *) 0; - /* Prepare to jump: restore the " if (condition)" so outer layers see it */ - /* Symbol was found --> jump to normal symbol processing. - Code following "symbol_found" expects "copy" to have the - symbol name, "sym" to have the symbol pointer, "s" to be - a specified file's symtab, and sym_symtab to be the symbol's - symtab. */ - /* By jumping there we avoid falling through the FILE:LINE and - FILE:FUNC processing stuff below */ - if (sym) - goto symbol_found; - - /* Couldn't find any interpretation as classes/namespaces, so give up */ - /* The quotes are important if copy is empty. */ - cplusplus_error (saved_arg, - "Can't find member of namespace, class, struct, or union named \"%s\"\n", - copy); - } - /* end of C++ */ - - - /* Extract the file name. */ - p1 = p; - while (p != *argptr && p[-1] == ' ') - --p; - if ((*p == '"') && is_quote_enclosed) - --p; - copy = (char *) alloca (p - *argptr + 1); - if ((**argptr == '"') && is_quote_enclosed) - { - memcpy (copy, *argptr + 1, p - *argptr - 1); - /* It may have the ending quote right after the file name */ - if (copy[p - *argptr - 2] == '"') - copy[p - *argptr - 2] = 0; - else - copy[p - *argptr - 1] = 0; - } - else - { - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = 0; - } - - /* Find that file's data. */ - s = lookup_symtab (copy); - if (s == 0) - { - if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); - error ("No source file named %s.", copy); - } - - /* Discard the file name from the arg. */ - p = p1 + 1; - while (*p == ' ' || *p == '\t') - p++; - *argptr = p; + file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, + not_found_ptr); } #if 0 /* No one really seems to know why this was added. It certainly @@ -982,15 +767,12 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, copy = (char *) alloca (p - *argptr + 1); memcpy (copy, *argptr, p - *argptr); copy[p - *argptr] = '\000'; - sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab); + sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab); if (sym) { - /* Yes, we have a symbol; jump to symbol processing */ - /* Code after symbol_found expects S, SYM_SYMTAB, SYM, - and COPY to be set correctly */ *argptr = (*p == '\'') ? p + 1 : p; - s = (struct symtab *) 0; - goto symbol_found; + return symbol_found (funfirstline, canonical, copy, sym, + NULL, sym_symtab); } /* Otherwise fall out from here and go to file/line spec processing, etc. */ @@ -1000,7 +782,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, /* S is specified file's symtab, or 0 if no file specified. arg no longer contains the file name. */ - /* Check whether arg is all digits (and sign) */ + /* Check whether arg is all digits (and sign). */ q = *argptr; if (*q == '-' || *q == '+') @@ -1009,91 +791,30 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, q++; if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ',')) - { - /* We found a token consisting of all digits -- at least one digit. */ - enum sign - { - none, plus, minus - } - sign = none; - - /* We might need a canonical line spec if no file was specified. */ - int need_canonical = (s == 0) ? 1 : 0; - - /* This is where we need to make sure that we have good defaults. - We must guarantee that this section of code is never executed - when we are called with just a function name, since - select_source_symtab calls us with such an argument */ - - if (s == 0 && default_symtab == 0) - { - select_source_symtab (0); - default_symtab = current_source_symtab; - default_line = current_source_line; - } - - if (**argptr == '+') - sign = plus, (*argptr)++; - else if (**argptr == '-') - sign = minus, (*argptr)++; - val.line = atoi (*argptr); - switch (sign) - { - case plus: - if (q == *argptr) - val.line = 5; - if (s == 0) - val.line = default_line + val.line; - break; - case minus: - if (q == *argptr) - val.line = 15; - if (s == 0) - val.line = default_line - val.line; - else - val.line = 1; - break; - case none: - break; /* No need to adjust val.line. */ - } - - while (*q == ' ' || *q == '\t') - q++; - *argptr = q; - if (s == 0) - s = default_symtab; - - /* It is possible that this source file has more than one symtab, - and that the new line number specification has moved us from the - default (in s) to a new one. */ - val.symtab = find_line_symtab (s, val.line, NULL, NULL); - if (val.symtab == 0) - val.symtab = s; - - val.pc = 0; - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.sals[0] = val; - values.nelts = 1; - if (need_canonical) - build_canonical_line_spec (values.sals, NULL, canonical); - return values; - } + /* We found a token consisting of all digits -- at least one digit. */ + return decode_all_digits (argptr, default_symtab, default_line, + canonical, file_symtab, q); /* Arg token is not digits => try it as a variable name Find the next token (everything up to end or next whitespace). */ - if (**argptr == '$') /* May be a convenience variable */ - p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); /* One or two $ chars possible */ + if (**argptr == '$') /* May be a convenience variable. */ + /* One or two $ chars possible. */ + p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); else if (is_quoted) { p = skip_quoted (*argptr); if (p[-1] != '\'') error ("Unmatched single quote."); } - else if (has_parens) + else if (is_objc_method) { - p = pp + 1; + /* allow word separators in method names for Obj-C */ + p = skip_quoted_chars (*argptr, NULL, ""); + } + else if (paren_pointer != NULL) + { + p = paren_pointer + 1; } else { @@ -1117,157 +838,1013 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, /* If it starts with $: may be a legitimate variable or routine name (e.g. HP-UX millicode routines such as $$dyncall), or it may - be history value, or it may be a convenience variable */ + be history value, or it may be a convenience variable. */ if (*copy == '$') - { - struct value *valx; - int index = 0; - int need_canonical = 0; - - p = (copy[1] == '$') ? copy + 2 : copy + 1; - while (*p >= '0' && *p <= '9') - p++; - if (!*p) /* reached end of token without hitting non-digit */ - { - /* We have a value history reference */ - sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index); - valx = access_value_history ((copy[1] == '$') ? -index : index); - if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT) - error ("History values used in line specs must have integer values."); - } - else - { - /* Not all digits -- may be user variable/function or a - convenience variable */ - - /* Look up entire name as a symbol first */ - sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab); - s = (struct symtab *) 0; - need_canonical = 1; - /* Symbol was found --> jump to normal symbol processing. - Code following "symbol_found" expects "copy" to have the - symbol name, "sym" to have the symbol pointer, "s" to be - a specified file's symtab, and sym_symtab to be the symbol's - symtab. */ - if (sym) - goto symbol_found; - - /* If symbol was not found, look in minimal symbol tables */ - msymbol = lookup_minimal_symbol (copy, NULL, NULL); - /* Min symbol was found --> jump to minsym processing. */ - if (msymbol) - goto minimal_symbol_found; - - /* Not a user variable or function -- must be convenience variable */ - need_canonical = (s == 0) ? 1 : 0; - valx = value_of_internalvar (lookup_internalvar (copy + 1)); - if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT) - error ("Convenience variables used in line specs must have integer values."); - } - - /* Either history value or convenience value from above, in valx */ - val.symtab = s ? s : default_symtab; - val.line = value_as_long (valx); - val.pc = 0; - - values.sals = (struct symtab_and_line *) xmalloc (sizeof val); - values.sals[0] = val; - values.nelts = 1; - - if (need_canonical) - build_canonical_line_spec (values.sals, NULL, canonical); - - return values; - } - + return decode_dollar (copy, funfirstline, default_symtab, + canonical, file_symtab); /* Look up that token as a variable. If file specified, use that file's per-file block to start with. */ - sym = lookup_symbol (copy, - (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) - : get_selected_block ()), - VAR_NAMESPACE, 0, &sym_symtab); + return decode_variable (copy, funfirstline, canonical, + file_symtab, not_found_ptr); +} -symbol_found: /* We also jump here from inside the C++ class/namespace - code on finding a symbol of the form "A::B::C" */ + - if (sym != NULL) +/* Now, more helper functions for decode_line_1. Some conventions + that these functions follow: + + Decode_line_1 typically passes along some of its arguments or local + variables to the subfunctions. It passes the variables by + reference if they are modified by the subfunction, and by value + otherwise. + + Some of the functions have side effects that don't arise from + variables that are passed by reference. In particular, if a + function is passed ARGPTR as an argument, it modifies what ARGPTR + points to; typically, it advances *ARGPTR past whatever substring + it has just looked at. (If it doesn't modify *ARGPTR, then the + function gets passed *ARGPTR instead, which is then called ARG: see + set_flags, for example.) Also, functions that return a struct + symtabs_and_lines may modify CANONICAL, as in the description of + decode_line_1. + + If a function returns a struct symtabs_and_lines, then that struct + will immediately make its way up the call chain to be returned by + decode_line_1. In particular, all of the functions decode_XXX + calculate the appropriate struct symtabs_and_lines, under the + assumption that their argument is of the form XXX. */ + +/* First, some functions to initialize stuff at the beggining of the + function. */ + +static void +initialize_defaults (struct symtab **default_symtab, int *default_line) +{ + if (*default_symtab == 0) { - if (SYMBOL_CLASS (sym) == LOC_BLOCK) + /* Use whatever we have for the default source line. We don't use + get_current_or_default_symtab_and_line as it can recurse and call + us back! */ + struct symtab_and_line cursal = + get_current_source_symtab_and_line (); + + *default_symtab = cursal.symtab; + *default_line = cursal.line; + } +} + +static void +set_flags (char *arg, int *is_quoted, char **paren_pointer) +{ + char *ii; + int has_if = 0; + + /* 'has_if' is for the syntax: + (gdb) break foo if (a==b) + */ + if ((ii = strstr (arg, " if ")) != NULL || + (ii = strstr (arg, "\tif ")) != NULL || + (ii = strstr (arg, " if\t")) != NULL || + (ii = strstr (arg, "\tif\t")) != NULL || + (ii = strstr (arg, " if(")) != NULL || + (ii = strstr (arg, "\tif( ")) != NULL) + has_if = 1; + /* Temporarily zap out "if (condition)" to not confuse the + parenthesis-checking code below. This is undone below. Do not + change ii!! */ + if (has_if) + { + *ii = '\0'; + } + + *is_quoted = (*arg + && strchr (get_gdb_completer_quote_characters (), + *arg) != NULL); + + *paren_pointer = strchr (arg, '('); + if (*paren_pointer != NULL) + *paren_pointer = strrchr (*paren_pointer, ')'); + + /* Now that we're safely past the paren_pointer check, put back " if + (condition)" so outer layers can see it. */ + if (has_if) + *ii = ' '; +} + + + +/* Decode arg of the form *PC. */ + +static struct symtabs_and_lines +decode_indirect (char **argptr) +{ + struct symtabs_and_lines values; + CORE_ADDR pc; + + (*argptr)++; + pc = parse_and_eval_address_1 (argptr); + + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + + values.nelts = 1; + values.sals[0] = find_pc_line (pc, 0); + values.sals[0].pc = pc; + values.sals[0].section = find_pc_overlay (pc); + + return values; +} + + + +/* Locate the first half of the linespec, ending in a colon, period, + or whitespace. (More or less.) Also, check to see if *ARGPTR is + enclosed in double quotes; if so, set is_quote_enclosed, advance + ARGPTR past that and zero out the trailing double quote. + If ARGPTR is just a simple name like "main", p will point to "" + at the end. */ + +static char * +locate_first_half (char **argptr, int *is_quote_enclosed) +{ + char *ii; + char *p, *p1; + int has_comma; + + /* Maybe we were called with a line range FILENAME:LINENUM,FILENAME:LINENUM + and we must isolate the first half. Outer layers will call again later + for the second half. + + Don't count commas that appear in argument lists of overloaded + functions, or in quoted strings. It's stupid to go to this much + trouble when the rest of the function is such an obvious roach hotel. */ + ii = find_toplevel_char (*argptr, ','); + has_comma = (ii != 0); + + /* Temporarily zap out second half to not confuse the code below. + This is undone below. Do not change ii!! */ + if (has_comma) + { + *ii = '\0'; + } + + /* Maybe arg is FILE : LINENUM or FILE : FUNCTION. May also be + CLASS::MEMBER, or NAMESPACE::NAME. Look for ':', but ignore + inside of <>. */ + + p = *argptr; + if (p[0] == '"') + { + *is_quote_enclosed = 1; + (*argptr)++; + p++; + } + else + *is_quote_enclosed = 0; + for (; *p; p++) + { + if (p[0] == '<') { - /* Arg is the name of a function */ - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.sals[0] = find_function_start_sal (sym, funfirstline); - values.nelts = 1; - - /* Don't use the SYMBOL_LINE; if used at all it points to - the line containing the parameters or thereabouts, not - the first line of code. */ - - /* We might need a canonical line spec if it is a static - function. */ - if (s == 0) + char *temp_end = find_template_name_end (p); + if (!temp_end) + error ("malformed template specification in command"); + p = temp_end; + } + /* Check for a colon and a plus or minus and a [ (which + indicates an Objective-C method) */ + if (is_objc_method_format (p)) + { + break; + } + /* Check for the end of the first half of the linespec. End of + line, a tab, a double colon or the last single colon, or a + space. But if enclosed in double quotes we do not break on + enclosed spaces. */ + if (!*p + || p[0] == '\t' + || ((p[0] == ':') + && ((p[1] == ':') || (strchr (p + 1, ':') == NULL))) + || ((p[0] == ' ') && !*is_quote_enclosed)) + break; + if (p[0] == '.' && strchr (p, ':') == NULL) + { + /* Java qualified method. Find the *last* '.', since the + others are package qualifiers. */ + for (p1 = p; *p1; p1++) { - struct blockvector *bv = BLOCKVECTOR (sym_symtab); - struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - if (lookup_block_symbol (b, copy, VAR_NAMESPACE) != NULL) - build_canonical_line_spec (values.sals, copy, canonical); + if (*p1 == '.') + p = p1; } - return values; + break; + } + } + while (p[0] == ' ' || p[0] == '\t') + p++; + + /* If the closing double quote was left at the end, remove it. */ + if (*is_quote_enclosed) + { + char *closing_quote = strchr (p - 1, '"'); + if (closing_quote && closing_quote[1] == '\0') + *closing_quote = '\0'; + } + + /* Now that we've safely parsed the first half, put back ',' so + outer layers can see it. */ + if (has_comma) + *ii = ','; + + return p; +} + + + +/* Here's where we recognise an Objective-C Selector. An Objective C + selector may be implemented by more than one class, therefore it + may represent more than one method/function. This gives us a + situation somewhat analogous to C++ overloading. If there's more + than one method that could represent the selector, then use some of + the existing C++ code to let the user choose one. */ + +struct symtabs_and_lines +decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab, + char ***canonical, char *saved_arg) +{ + struct symtabs_and_lines values; + struct symbol **sym_arr = NULL; + struct symbol *sym = NULL; + char *copy = NULL; + struct block *block = NULL; + int i1 = 0; + int i2 = 0; + + values.sals = NULL; + values.nelts = 0; + + if (file_symtab != NULL) + block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab), STATIC_BLOCK); + else + block = get_selected_block (0); + + copy = find_imps (file_symtab, block, *argptr, NULL, &i1, &i2); + + if (i1 > 0) + { + sym_arr = (struct symbol **) alloca ((i1 + 1) * sizeof (struct symbol *)); + sym_arr[i1] = 0; + + copy = find_imps (file_symtab, block, *argptr, sym_arr, &i1, &i2); + *argptr = copy; + } + + /* i1 now represents the TOTAL number of matches found. + i2 represents how many HIGH-LEVEL (struct symbol) matches, + which will come first in the sym_arr array. Any low-level + (minimal_symbol) matches will follow those. */ + + if (i1 == 1) + { + if (i2 > 0) + { + /* Already a struct symbol. */ + sym = sym_arr[0]; } else { - if (funfirstline) - error ("\"%s\" is not a function", copy); - else if (SYMBOL_LINE (sym) != 0) + sym = find_pc_function (SYMBOL_VALUE_ADDRESS (sym_arr[0])); + if ((sym != NULL) && strcmp (SYMBOL_LINKAGE_NAME (sym_arr[0]), SYMBOL_LINKAGE_NAME (sym)) != 0) { - /* We know its line number. */ - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.nelts = 1; - memset (&values.sals[0], 0, sizeof (values.sals[0])); - values.sals[0].symtab = sym_symtab; - values.sals[0].line = SYMBOL_LINE (sym); - return values; + warning ("debugging symbol \"%s\" does not match selector; ignoring", SYMBOL_LINKAGE_NAME (sym)); + sym = NULL; } + } + + values.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + + if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) + { + /* Canonicalize this, so it remains resolved for dylib loads. */ + values.sals[0] = find_function_start_sal (sym, funfirstline); + build_canonical_line_spec (values.sals, SYMBOL_NATURAL_NAME (sym), canonical); + } + else + { + /* The only match was a non-debuggable symbol. */ + values.sals[0].symtab = 0; + values.sals[0].line = 0; + values.sals[0].end = 0; + values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym_arr[0]); + } + return values; + } + + if (i1 > 1) + { + /* More than one match. The user must choose one or more. */ + return decode_line_2 (sym_arr, i2, funfirstline, canonical); + } + + return values; +} + +/* This handles C++ and Java compound data structures. P should point + at the first component separator, i.e. double-colon or period. As + an example, on entrance to this function we could have ARGPTR + pointing to "AAA::inA::fun" and P pointing to "::inA::fun". */ + +static struct symtabs_and_lines +decode_compound (char **argptr, int funfirstline, char ***canonical, + char *saved_arg, char *p) +{ + struct symtabs_and_lines values; + char *p2; + char *saved_arg2 = *argptr; + char *temp_end; + struct symbol *sym; + /* The symtab that SYM was found in. */ + struct symtab *sym_symtab; + char *copy; + struct symbol *sym_class; + struct symbol **sym_arr; + struct type *t; + + /* First check for "global" namespace specification, of the form + "::foo". If found, skip over the colons and jump to normal + symbol processing. I.e. the whole line specification starts with + "::" (note the condition that *argptr == p). */ + if (p[0] == ':' + && ((*argptr == p) || (p[-1] == ' ') || (p[-1] == '\t'))) + saved_arg2 += 2; + + /* Given our example "AAA::inA::fun", we have two cases to consider: + + 1) AAA::inA is the name of a class. In that case, presumably it + has a method called "fun"; we then look up that method using + find_method. + + 2) AAA::inA isn't the name of a class. In that case, either the + user made a typo or AAA::inA is the name of a namespace. + Either way, we just look up AAA::inA::fun with lookup_symbol. + + Thus, our first task is to find everything before the last set of + double-colons and figure out if it's the name of a class. So we + first loop through all of the double-colons. */ + + p2 = p; /* Save for restart. */ + + /* This is very messy. Following the example above we have now the + following pointers: + p -> "::inA::fun" + argptr -> "AAA::inA::fun + saved_arg -> "AAA::inA::fun + saved_arg2 -> "AAA::inA::fun + p2 -> "::inA::fun". */ + + /* In the loop below, with these strings, we'll make 2 passes, each + is marked in comments.*/ + + while (1) + { + /* Move pointer up to next possible class/namespace token. */ + + p = p2 + 1; /* Restart with old value +1. */ + + /* PASS1: at this point p2->"::inA::fun", so p->":inA::fun", + i.e. if there is a double-colon, p will now point to the + second colon. */ + /* PASS2: p2->"::fun", p->":fun" */ + + /* Move pointer ahead to next double-colon. */ + while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')) + { + if (p[0] == '<') + { + temp_end = find_template_name_end (p); + if (!temp_end) + error ("malformed template specification in command"); + p = temp_end; + } + /* Note that, since, at the start of this loop, p would be + pointing to the second colon in a double-colon, we only + satisfy the condition below if there is another + double-colon to the right (after). I.e. there is another + component that can be a class or a namespace. I.e, if at + the beginning of this loop (PASS1), we had + p->":inA::fun", we'll trigger this when p has been + advanced to point to "::fun". */ + /* PASS2: we will not trigger this. */ + else if ((p[0] == ':') && (p[1] == ':')) + break; /* Found double-colon. */ else - /* This can happen if it is compiled with a compiler which doesn't - put out line numbers for variables. */ - /* FIXME: Shouldn't we just set .line and .symtab to zero - and return? For example, "info line foo" could print - the address. */ - error ("Line number not known for symbol \"%s\"", copy); + /* PASS2: We'll keep getting here, until p->"", at which point + we exit this loop. */ + p++; + } + + if (*p != ':') + break; /* Out of the while (1). This would happen + for instance if we have looked up + unsuccessfully all the components of the + string, and p->""(PASS2) */ + + /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e + string ended). */ + /* Save restart for next time around. */ + p2 = p; + /* Restore argptr as it was on entry to this function. */ + *argptr = saved_arg2; + /* PASS1: at this point p->"::fun" argptr->"AAA::inA::fun", + p2->"::fun". */ + + /* All ready for next pass through the loop. */ + } /* while (1) */ + + + /* Start of lookup in the symbol tables. */ + + /* Lookup in the symbol table the substring between argptr and + p. Note, this call changes the value of argptr. */ + /* Before the call, argptr->"AAA::inA::fun", + p->"", p2->"::fun". After the call: argptr->"fun", p, p2 + unchanged. */ + sym_class = lookup_prefix_sym (argptr, p2); + + /* If sym_class has been found, and if "AAA::inA" is a class, then + we're in case 1 above. So we look up "fun" as a method of that + class. */ + if (sym_class && + (t = check_typedef (SYMBOL_TYPE (sym_class)), + (TYPE_CODE (t) == TYPE_CODE_STRUCT + || TYPE_CODE (t) == TYPE_CODE_UNION))) + { + /* Arg token is not digits => try it as a function name. + Find the next token (everything up to end or next + blank). */ + if (**argptr + && strchr (get_gdb_completer_quote_characters (), + **argptr) != NULL) + { + p = skip_quoted (*argptr); + *argptr = *argptr + 1; + } + else + { + /* At this point argptr->"fun". */ + p = *argptr; + while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':') + p++; + /* At this point p->"". String ended. */ + } + + /* Allocate our own copy of the substring between argptr and + p. */ + copy = (char *) alloca (p - *argptr + 1); + memcpy (copy, *argptr, p - *argptr); + copy[p - *argptr] = '\0'; + if (p != *argptr + && copy[p - *argptr - 1] + && strchr (get_gdb_completer_quote_characters (), + copy[p - *argptr - 1]) != NULL) + copy[p - *argptr - 1] = '\0'; + + /* At this point copy->"fun", p->"" */ + + /* No line number may be specified. */ + while (*p == ' ' || *p == '\t') + p++; + *argptr = p; + /* At this point arptr->"". */ + + /* Look for copy as a method of sym_class. */ + /* At this point copy->"fun", sym_class is "AAA:inA", + saved_arg->"AAA::inA::fun". This concludes the scanning of + the string for possible components matches. If we find it + here, we return. If not, and we are at the and of the string, + we'll lookup the whole string in the symbol tables. */ + + return find_method (funfirstline, canonical, saved_arg, + copy, t, sym_class); + + } /* End if symbol found */ + + + /* We couldn't find a class, so we're in case 2 above. We check the + entire name as a symbol instead. */ + + copy = (char *) alloca (p - saved_arg2 + 1); + memcpy (copy, saved_arg2, p - saved_arg2); + /* Note: if is_quoted should be true, we snuff out quote here + anyway. */ + copy[p - saved_arg2] = '\000'; + /* Set argptr to skip over the name. */ + *argptr = (*p == '\'') ? p + 1 : p; + + /* Look up entire name */ + sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab); + if (sym) + return symbol_found (funfirstline, canonical, copy, sym, + NULL, sym_symtab); + + /* Couldn't find any interpretation as classes/namespaces, so give + up. The quotes are important if copy is empty. */ + cplusplus_error (saved_arg, + "Can't find member of namespace, class, struct, or union named \"%s\"\n", + copy); +} + +/* Next come some helper functions for decode_compound. */ + +/* Return the symbol corresponding to the substring of *ARGPTR ending + at P, allowing whitespace. Also, advance *ARGPTR past the symbol + name in question, the compound object separator ("::" or "."), and + whitespace. Note that *ARGPTR is changed whether or not the + lookup_symbol call finds anything (i.e we return NULL). As an + example, say ARGPTR is "AAA::inA::fun" and P is "::inA::fun". */ + +static struct symbol * +lookup_prefix_sym (char **argptr, char *p) +{ + char *p1; + char *copy; + + /* Extract the class name. */ + p1 = p; + while (p != *argptr && p[-1] == ' ') + --p; + copy = (char *) alloca (p - *argptr + 1); + memcpy (copy, *argptr, p - *argptr); + copy[p - *argptr] = 0; + + /* Discard the class name from the argptr. */ + p = p1 + (p1[0] == ':' ? 2 : 1); + while (*p == ' ' || *p == '\t') + p++; + *argptr = p; + + /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA", + argptr->"inA::fun" */ + + return lookup_symbol (copy, 0, STRUCT_DOMAIN, 0, + (struct symtab **) NULL); +} + +/* This finds the method COPY in the class whose type is T and whose + symbol is SYM_CLASS. */ + +static struct symtabs_and_lines +find_method (int funfirstline, char ***canonical, char *saved_arg, + char *copy, struct type *t, struct symbol *sym_class) +{ + struct symtabs_and_lines values; + struct symbol *sym = 0; + int i1; /* Counter for the symbol array. */ + struct symbol **sym_arr = alloca (total_number_of_methods (t) + * sizeof (struct symbol *)); + + /* Find all methods with a matching name, and put them in + sym_arr. */ + + i1 = collect_methods (copy, t, sym_arr); + + if (i1 == 1) + { + /* There is exactly one field with that name. */ + sym = sym_arr[0]; + + if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) + { + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + values.sals[0] = find_function_start_sal (sym, + funfirstline); + } + else + { + values.nelts = 0; + } + return values; + } + if (i1 > 0) + { + /* There is more than one field with that name + (overloaded). Ask the user which one to use. */ + return decode_line_2 (sym_arr, i1, funfirstline, canonical); + } + else + { + char *tmp; + + if (is_operator_name (copy)) + { + tmp = (char *) alloca (strlen (copy + 3) + 9); + strcpy (tmp, "operator "); + strcat (tmp, copy + 3); + } + else + tmp = copy; + if (tmp[0] == '~') + cplusplus_error (saved_arg, + "the class `%s' does not have destructor defined\n", + SYMBOL_PRINT_NAME (sym_class)); + else + cplusplus_error (saved_arg, + "the class %s does not have any method named %s\n", + SYMBOL_PRINT_NAME (sym_class), tmp); + } +} + +/* Find all methods named COPY in the class whose type is T, and put + them in SYM_ARR. Return the number of methods found. */ + +static int +collect_methods (char *copy, struct type *t, + struct symbol **sym_arr) +{ + int i1 = 0; /* Counter for the symbol array. */ + + if (destructor_name_p (copy, t)) + { + /* Destructors are a special case. */ + int m_index, f_index; + + if (get_destructor_fn_field (t, &m_index, &f_index)) + { + struct fn_field *f = TYPE_FN_FIELDLIST1 (t, m_index); + + sym_arr[i1] = + lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, f_index), + NULL, VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym_arr[i1]) + i1++; } } + else + i1 = find_methods (t, copy, sym_arr); + + return i1; +} + + + +/* Return the symtab associated to the filename given by the substring + of *ARGPTR ending at P, and advance ARGPTR past that filename. If + NOT_FOUND_PTR is not null and the source file is not found, store + boolean true at the location pointed to and do not issue an + error message. */ + +static struct symtab * +symtab_from_filename (char **argptr, char *p, int is_quote_enclosed, + int *not_found_ptr) +{ + char *p1; + char *copy; + struct symtab *file_symtab; + + p1 = p; + while (p != *argptr && p[-1] == ' ') + --p; + if ((*p == '"') && is_quote_enclosed) + --p; + copy = (char *) alloca (p - *argptr + 1); + memcpy (copy, *argptr, p - *argptr); + /* It may have the ending quote right after the file name. */ + if (is_quote_enclosed && copy[p - *argptr - 1] == '"') + copy[p - *argptr - 1] = 0; + else + copy[p - *argptr] = 0; + + /* Find that file's data. */ + file_symtab = lookup_symtab (copy); + if (file_symtab == 0) + { + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + if (not_found_ptr) + { + *not_found_ptr = 1; + /* The caller has indicated that it wishes quiet notification of any + error where the function or file is not found. A call to + error_silent causes an error to occur, but it does not issue + the supplied message. The message can be manually output by + the caller, if desired. This is used, for example, when + attempting to set breakpoints for functions in shared libraries + that have not yet been loaded. */ + error_silent ("No source file named %s.", copy); + } + error ("No source file named %s.", copy); + } + + /* Discard the file name from the arg. */ + p = p1 + 1; + while (*p == ' ' || *p == '\t') + p++; + *argptr = p; + + return file_symtab; +} + + + +/* This decodes a line where the argument is all digits (possibly + preceded by a sign). Q should point to the end of those digits; + the other arguments are as usual. */ + +static struct symtabs_and_lines +decode_all_digits (char **argptr, struct symtab *default_symtab, + int default_line, char ***canonical, + struct symtab *file_symtab, char *q) + +{ + struct symtabs_and_lines values; + struct symtab_and_line val; + + enum sign + { + none, plus, minus + } + sign = none; + + /* We might need a canonical line spec if no file was specified. */ + int need_canonical = (file_symtab == 0) ? 1 : 0; + + init_sal (&val); + + /* This is where we need to make sure that we have good defaults. + We must guarantee that this section of code is never executed + when we are called with just a function name, since + set_default_source_symtab_and_line uses + select_source_symtab that calls us with such an argument. */ + + if (file_symtab == 0 && default_symtab == 0) + { + /* Make sure we have at least a default source file. */ + set_default_source_symtab_and_line (); + initialize_defaults (&default_symtab, &default_line); + } + + if (**argptr == '+') + sign = plus, (*argptr)++; + else if (**argptr == '-') + sign = minus, (*argptr)++; + val.line = atoi (*argptr); + switch (sign) + { + case plus: + if (q == *argptr) + val.line = 5; + if (file_symtab == 0) + val.line = default_line + val.line; + break; + case minus: + if (q == *argptr) + val.line = 15; + if (file_symtab == 0) + val.line = default_line - val.line; + else + val.line = 1; + break; + case none: + break; /* No need to adjust val.line. */ + } + + while (*q == ' ' || *q == '\t') + q++; + *argptr = q; + if (file_symtab == 0) + file_symtab = default_symtab; + + /* It is possible that this source file has more than one symtab, + and that the new line number specification has moved us from the + default (in file_symtab) to a new one. */ + val.symtab = find_line_symtab (file_symtab, val.line, NULL, NULL); + if (val.symtab == 0) + val.symtab = file_symtab; + + val.pc = 0; + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.sals[0] = val; + values.nelts = 1; + if (need_canonical) + build_canonical_line_spec (values.sals, NULL, canonical); + return values; +} + + + +/* Decode a linespec starting with a dollar sign. */ + +static struct symtabs_and_lines +decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab, + char ***canonical, struct symtab *file_symtab) +{ + struct value *valx; + int index = 0; + int need_canonical = 0; + struct symtabs_and_lines values; + struct symtab_and_line val; + char *p; + struct symbol *sym; + /* The symtab that SYM was found in. */ + struct symtab *sym_symtab; + struct minimal_symbol *msymbol; + + p = (copy[1] == '$') ? copy + 2 : copy + 1; + while (*p >= '0' && *p <= '9') + p++; + if (!*p) /* Reached end of token without hitting non-digit. */ + { + /* We have a value history reference. */ + sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index); + valx = access_value_history ((copy[1] == '$') ? -index : index); + if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT) + error ("History values used in line specs must have integer values."); + } + else + { + /* Not all digits -- may be user variable/function or a + convenience variable. */ + + /* Look up entire name as a symbol first. */ + sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab); + file_symtab = (struct symtab *) 0; + need_canonical = 1; + /* Symbol was found --> jump to normal symbol processing. */ + if (sym) + return symbol_found (funfirstline, canonical, copy, sym, + NULL, sym_symtab); + + /* If symbol was not found, look in minimal symbol tables. */ + msymbol = lookup_minimal_symbol (copy, NULL, NULL); + /* Min symbol was found --> jump to minsym processing. */ + if (msymbol) + return minsym_found (funfirstline, msymbol); + + /* Not a user variable or function -- must be convenience variable. */ + need_canonical = (file_symtab == 0) ? 1 : 0; + valx = value_of_internalvar (lookup_internalvar (copy + 1)); + if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT) + error ("Convenience variables used in line specs must have integer values."); + } + + init_sal (&val); + + /* Either history value or convenience value from above, in valx. */ + val.symtab = file_symtab ? file_symtab : default_symtab; + val.line = value_as_long (valx); + val.pc = 0; + + values.sals = (struct symtab_and_line *) xmalloc (sizeof val); + values.sals[0] = val; + values.nelts = 1; + + if (need_canonical) + build_canonical_line_spec (values.sals, NULL, canonical); + + return values; +} + + + +/* Decode a linespec that's a variable. If FILE_SYMTAB is non-NULL, + look in that symtab's static variables first. If NOT_FOUND_PTR is not NULL and + the function cannot be found, store boolean true in the location pointed to + and do not issue an error message. */ + +static struct symtabs_and_lines +decode_variable (char *copy, int funfirstline, char ***canonical, + struct symtab *file_symtab, int *not_found_ptr) +{ + struct symbol *sym; + /* The symtab that SYM was found in. */ + struct symtab *sym_symtab; + + struct minimal_symbol *msymbol; + + sym = lookup_symbol (copy, + (file_symtab + ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab), + STATIC_BLOCK) + : get_selected_block (0)), + VAR_DOMAIN, 0, &sym_symtab); + + if (sym != NULL) + return symbol_found (funfirstline, canonical, copy, sym, + file_symtab, sym_symtab); msymbol = lookup_minimal_symbol (copy, NULL, NULL); -minimal_symbol_found: /* We also jump here from the case for variables - that begin with '$' */ - if (msymbol != NULL) - { - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol), - (struct sec *) 0, 0); - values.sals[0].section = SYMBOL_BFD_SECTION (msymbol); - if (funfirstline) - { - values.sals[0].pc += FUNCTION_START_OFFSET; - values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc); - } - values.nelts = 1; - return values; - } + return minsym_found (funfirstline, msymbol); if (!have_full_symbols () && !have_partial_symbols () && !have_minimal_symbols ()) error ("No symbol table is loaded. Use the \"file\" command."); + if (not_found_ptr) + { + *not_found_ptr = 1; + /* The caller has indicated that it wishes quiet notification of any + error where the function or file is not found. A call to + error_silent causes an error to occur, but it does not issue + the supplied message. The message can be manually output by + the caller, if desired. This is used, for example, when + attempting to set breakpoints for functions in shared libraries + that have not yet been loaded. */ + error_silent ("Function \"%s\" not defined.", copy); + } + error ("Function \"%s\" not defined.", copy); - return values; /* for lint */ +} + + + + +/* Now come some functions that are called from multiple places within + decode_line_1. */ + +/* We've found a symbol SYM to associate with our linespec; build a + corresponding struct symtabs_and_lines. */ + +static struct symtabs_and_lines +symbol_found (int funfirstline, char ***canonical, char *copy, + struct symbol *sym, struct symtab *file_symtab, + struct symtab *sym_symtab) +{ + struct symtabs_and_lines values; + + if (SYMBOL_CLASS (sym) == LOC_BLOCK) + { + /* Arg is the name of a function */ + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.sals[0] = find_function_start_sal (sym, funfirstline); + values.nelts = 1; + + /* Don't use the SYMBOL_LINE; if used at all it points to + the line containing the parameters or thereabouts, not + the first line of code. */ + + /* We might need a canonical line spec if it is a static + function. */ + if (file_symtab == 0) + { + struct blockvector *bv = BLOCKVECTOR (sym_symtab); + struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL) + build_canonical_line_spec (values.sals, copy, canonical); + } + return values; + } + else + { + if (funfirstline) + error ("\"%s\" is not a function", copy); + else if (SYMBOL_LINE (sym) != 0) + { + /* We know its line number. */ + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + memset (&values.sals[0], 0, sizeof (values.sals[0])); + values.sals[0].symtab = sym_symtab; + values.sals[0].line = SYMBOL_LINE (sym); + return values; + } + else + /* This can happen if it is compiled with a compiler which doesn't + put out line numbers for variables. */ + /* FIXME: Shouldn't we just set .line and .symtab to zero + and return? For example, "info line foo" could print + the address. */ + error ("Line number not known for symbol \"%s\"", copy); + } +} + +/* We've found a minimal symbol MSYMBOL to associate with our + linespec; build a corresponding struct symtabs_and_lines. */ + +static struct symtabs_and_lines +minsym_found (int funfirstline, struct minimal_symbol *msymbol) +{ + struct symtabs_and_lines values; + + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol), + (struct bfd_section *) 0, 0); + values.sals[0].section = SYMBOL_BFD_SECTION (msymbol); + if (funfirstline) + { + values.sals[0].pc += FUNCTION_START_OFFSET; + values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc); + } + values.nelts = 1; + return values; } diff --git a/contrib/gdb/gdb/linespec.h b/contrib/gdb/gdb/linespec.h index 7c3f90ca268..38b0941dcb3 100644 --- a/contrib/gdb/gdb/linespec.h +++ b/contrib/gdb/gdb/linespec.h @@ -19,9 +19,11 @@ #if !defined (LINESPEC_H) #define LINESPEC_H 1 +struct symtab; + extern struct symtabs_and_lines decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, int default_line, - char ***canonical); + char ***canonical, int *not_found_ptr); #endif /* defined (LINESPEC_H) */ diff --git a/contrib/gdb/gdb/lynx-nat.c b/contrib/gdb/gdb/lynx-nat.c new file mode 100644 index 00000000000..7bfd40ee56e --- /dev/null +++ b/contrib/gdb/gdb/lynx-nat.c @@ -0,0 +1,624 @@ +/* Native-dependent code for LynxOS. + + Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001, 2003 Free + Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "inferior.h" +#include "target.h" +#include "gdbcore.h" +#include "regcache.h" + +#include +#Include "gdb_wait.h" +#include + +static unsigned long registers_addr (int pid); +static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); + +#define X(ENTRY)(offsetof(struct econtext, ENTRY)) + +#ifdef I386 +/* Mappings from tm-i386v.h */ + +static int regmap[] = +{ + X (eax), + X (ecx), + X (edx), + X (ebx), + X (esp), /* sp */ + X (ebp), /* fp */ + X (esi), + X (edi), + X (eip), /* pc */ + X (flags), /* ps */ + X (cs), + X (ss), + X (ds), + X (es), + X (ecode), /* Lynx doesn't give us either fs or gs, so */ + X (fault), /* we just substitute these two in the hopes + that they are useful. */ +}; +#endif /* I386 */ + +#ifdef M68K +/* Mappings from tm-m68k.h */ + +static int regmap[] = +{ + X (regs[0]), /* d0 */ + X (regs[1]), /* d1 */ + X (regs[2]), /* d2 */ + X (regs[3]), /* d3 */ + X (regs[4]), /* d4 */ + X (regs[5]), /* d5 */ + X (regs[6]), /* d6 */ + X (regs[7]), /* d7 */ + X (regs[8]), /* a0 */ + X (regs[9]), /* a1 */ + X (regs[10]), /* a2 */ + X (regs[11]), /* a3 */ + X (regs[12]), /* a4 */ + X (regs[13]), /* a5 */ + X (regs[14]), /* fp */ + offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */ + X (status), /* ps */ + X (pc), + + X (fregs[0 * 3]), /* fp0 */ + X (fregs[1 * 3]), /* fp1 */ + X (fregs[2 * 3]), /* fp2 */ + X (fregs[3 * 3]), /* fp3 */ + X (fregs[4 * 3]), /* fp4 */ + X (fregs[5 * 3]), /* fp5 */ + X (fregs[6 * 3]), /* fp6 */ + X (fregs[7 * 3]), /* fp7 */ + + X (fcregs[0]), /* fpcontrol */ + X (fcregs[1]), /* fpstatus */ + X (fcregs[2]), /* fpiaddr */ + X (ssw), /* fpcode */ + X (fault), /* fpflags */ +}; +#endif /* M68K */ + +#ifdef SPARC +/* Mappings from tm-sparc.h */ + +#define FX(ENTRY)(offsetof(struct fcontext, ENTRY)) + +static int regmap[] = +{ + -1, /* g0 */ + X (g1), + X (g2), + X (g3), + X (g4), + -1, /* g5->g7 aren't saved by Lynx */ + -1, + -1, + + X (o[0]), + X (o[1]), + X (o[2]), + X (o[3]), + X (o[4]), + X (o[5]), + X (o[6]), /* sp */ + X (o[7]), /* ra */ + + -1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */ + + -1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */ + + FX (f.fregs[0]), /* f0 */ + FX (f.fregs[1]), + FX (f.fregs[2]), + FX (f.fregs[3]), + FX (f.fregs[4]), + FX (f.fregs[5]), + FX (f.fregs[6]), + FX (f.fregs[7]), + FX (f.fregs[8]), + FX (f.fregs[9]), + FX (f.fregs[10]), + FX (f.fregs[11]), + FX (f.fregs[12]), + FX (f.fregs[13]), + FX (f.fregs[14]), + FX (f.fregs[15]), + FX (f.fregs[16]), + FX (f.fregs[17]), + FX (f.fregs[18]), + FX (f.fregs[19]), + FX (f.fregs[20]), + FX (f.fregs[21]), + FX (f.fregs[22]), + FX (f.fregs[23]), + FX (f.fregs[24]), + FX (f.fregs[25]), + FX (f.fregs[26]), + FX (f.fregs[27]), + FX (f.fregs[28]), + FX (f.fregs[29]), + FX (f.fregs[30]), + FX (f.fregs[31]), + + X (y), + X (psr), + X (wim), + X (tbr), + X (pc), + X (npc), + FX (fsr), /* fpsr */ + -1, /* cpsr */ +}; +#endif /* SPARC */ + +#ifdef rs6000 + +static int regmap[] = +{ + X (iregs[0]), /* r0 */ + X (iregs[1]), + X (iregs[2]), + X (iregs[3]), + X (iregs[4]), + X (iregs[5]), + X (iregs[6]), + X (iregs[7]), + X (iregs[8]), + X (iregs[9]), + X (iregs[10]), + X (iregs[11]), + X (iregs[12]), + X (iregs[13]), + X (iregs[14]), + X (iregs[15]), + X (iregs[16]), + X (iregs[17]), + X (iregs[18]), + X (iregs[19]), + X (iregs[20]), + X (iregs[21]), + X (iregs[22]), + X (iregs[23]), + X (iregs[24]), + X (iregs[25]), + X (iregs[26]), + X (iregs[27]), + X (iregs[28]), + X (iregs[29]), + X (iregs[30]), + X (iregs[31]), + + X (fregs[0]), /* f0 */ + X (fregs[1]), + X (fregs[2]), + X (fregs[3]), + X (fregs[4]), + X (fregs[5]), + X (fregs[6]), + X (fregs[7]), + X (fregs[8]), + X (fregs[9]), + X (fregs[10]), + X (fregs[11]), + X (fregs[12]), + X (fregs[13]), + X (fregs[14]), + X (fregs[15]), + X (fregs[16]), + X (fregs[17]), + X (fregs[18]), + X (fregs[19]), + X (fregs[20]), + X (fregs[21]), + X (fregs[22]), + X (fregs[23]), + X (fregs[24]), + X (fregs[25]), + X (fregs[26]), + X (fregs[27]), + X (fregs[28]), + X (fregs[29]), + X (fregs[30]), + X (fregs[31]), + + X (srr0), /* IAR (PC) */ + X (srr1), /* MSR (PS) */ + X (cr), /* CR */ + X (lr), /* LR */ + X (ctr), /* CTR */ + X (xer), /* XER */ + X (mq) /* MQ */ +}; + +#endif /* rs6000 */ + +#if defined (I386) || defined (M68K) || defined (rs6000) + +/* Return the offset relative to the start of the per-thread data to the + saved context block. */ + +static unsigned long +registers_addr (int pid) +{ + CORE_ADDR stblock; + int ecpoff = offsetof (st_t, ecp); + CORE_ADDR ecp; + + errno = 0; + stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, + 0); + if (errno) + perror_with_name ("ptrace(PTRACE_THREADUSER)"); + + ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff, + 0); + if (errno) + perror_with_name ("ptrace(PTRACE_PEEKTHREAD)"); + + return ecp - stblock; +} + +/* Fetch one or more registers from the inferior. REGNO == -1 to get + them all. We actually fetch more than requested, when convenient, + marking them as valid so we won't fetch them again. */ + +void +fetch_inferior_registers (int regno) +{ + int reglo, reghi; + int i; + unsigned long ecp; + + if (regno == -1) + { + reglo = 0; + reghi = NUM_REGS - 1; + } + else + reglo = reghi = regno; + + ecp = registers_addr (PIDGET (inferior_ptid)); + + { + char buf[MAX_REGISTER_SIZE]; + for (regno = reglo; regno <= reghi; regno++) + { + int ptrace_fun = PTRACE_PEEKTHREAD; + +#ifdef M68K + ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD; +#endif + + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + unsigned int reg; + + errno = 0; + reg = ptrace (ptrace_fun, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0); + if (errno) + perror_with_name ("ptrace(PTRACE_PEEKUSP)"); + + *(int *) &buf[i] = reg; + } + supply_register (regno, buf); + } + } +} + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + +void +store_inferior_registers (int regno) +{ + int reglo, reghi; + int i; + unsigned long ecp; + + if (regno == -1) + { + reglo = 0; + reghi = NUM_REGS - 1; + } + else + reglo = reghi = regno; + + ecp = registers_addr (PIDGET (inferior_ptid)); + + for (regno = reglo; regno <= reghi; regno++) + { + int ptrace_fun = PTRACE_POKEUSER; + + if (CANNOT_STORE_REGISTER (regno)) + continue; + +#ifdef M68K + ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER; +#endif + + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + unsigned int reg; + + reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i]; + + errno = 0; + ptrace (ptrace_fun, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg); + if (errno) + perror_with_name ("ptrace(PTRACE_POKEUSP)"); + } + } +} +#endif /* defined (I386) || defined (M68K) || defined (rs6000) */ + +/* Wait for child to do something. Return pid of child, or -1 in case + of error; store status through argument pointer OURSTATUS. */ + +ptid_t +child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +{ + int save_errno; + int thread; + union wait status; + int pid; + + while (1) + { + int sig; + + set_sigint_trap (); /* Causes SIGINT to be passed on to the + attached process. */ + pid = wait (&status); + + save_errno = errno; + + clear_sigint_trap (); + + if (pid == -1) + { + if (save_errno == EINTR) + continue; + fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n", + safe_strerror (save_errno)); + /* Claim it exited with unknown signal. */ + ourstatus->kind = TARGET_WAITKIND_SIGNALLED; + ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; + return -1; + } + + if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */ + continue; + + thread = status.w_tid; /* Get thread id from status */ + + /* Initial thread value can only be acquired via wait, so we have to + resort to this hack. */ + + if (TIDGET (inferior_ptid) == 0 && thread != 0) + { + inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread); + add_thread (inferior_ptid); + } + + ptid = BUILDPID (pid, thread); + + /* We've become a single threaded process again. */ + if (thread == 0) + inferior_ptid = ptid; + + /* Check for thread creation. */ + if (WIFSTOPPED (status) + && WSTOPSIG (status) == SIGTRAP + && !in_thread_list (ptid)) + { + int realsig; + + realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid), + (PTRACE_ARG3_TYPE) 0, 0); + + if (realsig == SIGNEWTHREAD) + { + /* It's a new thread notification. We don't want to much with + realsig -- the code in wait_for_inferior expects SIGTRAP. */ + ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + ourstatus->value.sig = TARGET_SIGNAL_0; + return ptid; + } + else + error ("Signal for unknown thread was not SIGNEWTHREAD"); + } + + /* Check for thread termination. */ + else if (WIFSTOPPED (status) + && WSTOPSIG (status) == SIGTRAP + && in_thread_list (ptid)) + { + int realsig; + + realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid), + (PTRACE_ARG3_TYPE) 0, 0); + + if (realsig == SIGTHREADEXIT) + { + ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0); + continue; + } + } + +#ifdef SPARC + /* SPARC Lynx uses an byte reversed wait status; we must use the + host macros to access it. These lines just a copy of + store_waitstatus. We can't use CHILD_SPECIAL_WAITSTATUS + because target.c can't include the Lynx . */ + if (WIFEXITED (status)) + { + ourstatus->kind = TARGET_WAITKIND_EXITED; + ourstatus->value.integer = WEXITSTATUS (status); + } + else if (!WIFSTOPPED (status)) + { + ourstatus->kind = TARGET_WAITKIND_SIGNALLED; + ourstatus->value.sig = + target_signal_from_host (WTERMSIG (status)); + } + else + { + ourstatus->kind = TARGET_WAITKIND_STOPPED; + ourstatus->value.sig = + target_signal_from_host (WSTOPSIG (status)); + } +#else + store_waitstatus (ourstatus, status.w_status); +#endif + + return ptid; + } +} + +/* Return nonzero if the given thread is still alive. */ +int +child_thread_alive (ptid_t ptid) +{ + int pid = PIDGET (ptid); + + /* Arggh. Apparently pthread_kill only works for threads within + the process that calls pthread_kill. + + We want to avoid the lynx signal extensions as they simply don't + map well to the generic gdb interface we want to keep. + + All we want to do is determine if a particular thread is alive; + it appears as if we can just make a harmless thread specific + ptrace call to do that. */ + return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1); +} + +/* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + +void +child_resume (ptid_t ptid, int step, enum target_signal signal) +{ + int func; + int pid = PIDGET (ptid); + + errno = 0; + + /* If pid == -1, then we want to step/continue all threads, else + we only want to step/continue a single thread. */ + if (pid == -1) + { + pid = PIDGET (inferior_ptid); + func = step ? PTRACE_SINGLESTEP : PTRACE_CONT; + } + else + func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE; + + + /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where + it was. (If GDB wanted it to start some other way, we have already + written a new PC value to the child.) + + If this system does not support PT_STEP, a higher level function will + have called single_step() to transmute the step request into a + continue request (by setting breakpoints on all possible successor + instructions), so we don't have to worry about that here. */ + + ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal)); + + if (errno) + perror_with_name ("ptrace"); +} + +/* Convert a Lynx process ID to a string. Returns the string in a static + buffer. */ + +char * +child_pid_to_str (ptid_t ptid) +{ + static char buf[40]; + + sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid)); + + return buf; +} + +/* Extract the register values out of the core file and store + them where `read_register' will find them. + + CORE_REG_SECT points to the register values themselves, read into memory. + CORE_REG_SIZE is the size of that area. + WHICH says which set of registers we are handling (0 = int, 2 = float + on machines where they are discontiguous). + REG_ADDR is the offset from u.u_ar0 to the register values relative to + core_reg_sect. This is used with old-fashioned core files to + locate the registers in a large upage-plus-stack ".reg" section. + Original upage address X is at location core_reg_sect+x+reg_addr. + */ + +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR reg_addr) +{ + struct st_entry s; + unsigned int regno; + + for (regno = 0; regno < NUM_REGS; regno++) + if (regmap[regno] != -1) + supply_register (regno, core_reg_sect + offsetof (st_t, ec) + + regmap[regno]); + +#ifdef SPARC +/* Fetching this register causes all of the I & L regs to be read from the + stack and validated. */ + + fetch_inferior_registers (I0_REGNUM); +#endif +} + + +/* Register that we are able to handle lynx core file formats. + FIXME: is this really bfd_target_unknown_flavour? */ + +static struct core_fns lynx_core_fns = +{ + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +void +_initialize_core_lynx (void) +{ + add_core_fns (&lynx_core_fns); +} diff --git a/contrib/gdb/gdb/m2-exp.c b/contrib/gdb/gdb/m2-exp.c new file mode 100644 index 00000000000..39233614dd3 --- /dev/null +++ b/contrib/gdb/gdb/m2-exp.c @@ -0,0 +1,2600 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + INT = 258, + HEX = 259, + ERROR = 260, + UINT = 261, + M2_TRUE = 262, + M2_FALSE = 263, + CHAR = 264, + FLOAT = 265, + STRING = 266, + NAME = 267, + BLOCKNAME = 268, + IDENT = 269, + VARNAME = 270, + TYPENAME = 271, + SIZE = 272, + CAP = 273, + ORD = 274, + HIGH = 275, + ABS = 276, + MIN_FUNC = 277, + MAX_FUNC = 278, + FLOAT_FUNC = 279, + VAL = 280, + CHR = 281, + ODD = 282, + TRUNC = 283, + INC = 284, + DEC = 285, + INCL = 286, + EXCL = 287, + COLONCOLON = 288, + INTERNAL_VAR = 289, + ABOVE_COMMA = 290, + ASSIGN = 291, + IN = 292, + NOTEQUAL = 293, + GEQ = 294, + LEQ = 295, + OROR = 296, + LOGICAL_AND = 297, + MOD = 298, + DIV = 299, + UNARY = 300, + DOT = 301, + NOT = 302, + QID = 303 + }; +#endif +#define INT 258 +#define HEX 259 +#define ERROR 260 +#define UINT 261 +#define M2_TRUE 262 +#define M2_FALSE 263 +#define CHAR 264 +#define FLOAT 265 +#define STRING 266 +#define NAME 267 +#define BLOCKNAME 268 +#define IDENT 269 +#define VARNAME 270 +#define TYPENAME 271 +#define SIZE 272 +#define CAP 273 +#define ORD 274 +#define HIGH 275 +#define ABS 276 +#define MIN_FUNC 277 +#define MAX_FUNC 278 +#define FLOAT_FUNC 279 +#define VAL 280 +#define CHR 281 +#define ODD 282 +#define TRUNC 283 +#define INC 284 +#define DEC 285 +#define INCL 286 +#define EXCL 287 +#define COLONCOLON 288 +#define INTERNAL_VAR 289 +#define ABOVE_COMMA 290 +#define ASSIGN 291 +#define IN 292 +#define NOTEQUAL 293 +#define GEQ 294 +#define LEQ 295 +#define OROR 296 +#define LOGICAL_AND 297 +#define MOD 298 +#define DIV 299 +#define UNARY 300 +#define DOT 301 +#define NOT 302 +#define QID 303 + + + + +/* Copy the first part of user declarations. */ +#line 41 "m2-exp.y" + + +#include "defs.h" +#include "gdb_string.h" +#include "expression.h" +#include "language.h" +#include "value.h" +#include "parser-defs.h" +#include "m2-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in gdb. Note that these are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +#define yymaxdepth m2_maxdepth +#define yyparse m2_parse +#define yylex m2_lex +#define yyerror m2_error +#define yylval m2_lval +#define yychar m2_char +#define yydebug m2_debug +#define yypact m2_pact +#define yyr1 m2_r1 +#define yyr2 m2_r2 +#define yydef m2_def +#define yychk m2_chk +#define yypgo m2_pgo +#define yyact m2_act +#define yyexca m2_exca +#define yyerrflag m2_errflag +#define yynerrs m2_nerrs +#define yyps m2_ps +#define yypv m2_pv +#define yys m2_s +#define yy_yys m2_yys +#define yystate m2_state +#define yytmp m2_tmp +#define yyv m2_v +#define yy_yyv m2_yyv +#define yyval m2_val +#define yylloc m2_lloc +#define yyreds m2_reds /* With YYDEBUG defined */ +#define yytoks m2_toks /* With YYDEBUG defined */ +#define yyname m2_name /* With YYDEBUG defined */ +#define yyrule m2_rule /* With YYDEBUG defined */ +#define yylhs m2_yylhs +#define yylen m2_yylen +#define yydefred m2_yydefred +#define yydgoto m2_yydgoto +#define yysindex m2_yysindex +#define yyrindex m2_yyrindex +#define yygindex m2_yygindex +#define yytable m2_yytable +#define yycheck m2_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 1 /* Default to yydebug support */ +#endif + +#define YYFPRINTF parser_fprintf + +int yyparse (void); + +static int yylex (void); + +void yyerror (char *); + +#if 0 +static char *make_qualname (char *, char *); +#endif + +static int parse_number (int); + +/* The sign of the number being parsed. */ +static int number_sign = 1; + +/* The block that the module specified by the qualifer on an identifer is + contained in, */ +#if 0 +static struct block *modblock=0; +#endif + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 137 "m2-exp.y" +typedef union YYSTYPE { + LONGEST lval; + ULONGEST ulval; + DOUBLEST dval; + struct symbol *sym; + struct type *tval; + struct stoken sval; + int voidval; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + + struct type **tvec; + int *ivec; + } YYSTYPE; +/* Line 191 of yacc.c. */ +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or xmalloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC xmalloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 67 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 848 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 68 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 15 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 80 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 181 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 303 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 41, 2, 2, 47, 2, + 59, 64, 52, 50, 35, 51, 2, 53, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 38, 40, 39, 2, 49, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 58, 2, 67, 57, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 65, 2, 66, 61, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 36, 37, 42, 43, 44, 45, 46, 48, 54, 55, + 56, 60, 62, 63 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 12, 13, 17, 20, + 23, 25, 27, 32, 37, 42, 47, 52, 57, 62, + 69, 74, 79, 84, 87, 92, 99, 104, 111, 115, + 117, 121, 128, 135, 139, 144, 145, 151, 152, 158, + 159, 161, 165, 167, 171, 176, 181, 185, 189, 193, + 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, + 237, 241, 245, 249, 253, 255, 257, 259, 261, 263, + 265, 267, 272, 274, 276, 278, 282, 284, 286, 290, + 292 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 69, 0, -1, 71, -1, 70, -1, 82, -1, 71, + 57, -1, -1, 51, 72, 71, -1, 50, 71, -1, + 73, 71, -1, 62, -1, 61, -1, 18, 59, 71, + 64, -1, 19, 59, 71, 64, -1, 21, 59, 71, + 64, -1, 20, 59, 71, 64, -1, 22, 59, 82, + 64, -1, 23, 59, 82, 64, -1, 24, 59, 71, + 64, -1, 25, 59, 82, 35, 71, 64, -1, 26, + 59, 71, 64, -1, 27, 59, 71, 64, -1, 28, + 59, 71, 64, -1, 17, 71, -1, 29, 59, 71, + 64, -1, 29, 59, 71, 35, 71, 64, -1, 30, + 59, 71, 64, -1, 30, 59, 71, 35, 71, 64, + -1, 71, 60, 12, -1, 74, -1, 71, 42, 74, + -1, 31, 59, 71, 35, 71, 64, -1, 32, 59, + 71, 35, 71, 64, -1, 65, 77, 66, -1, 82, + 65, 77, 66, -1, -1, 71, 58, 75, 78, 67, + -1, -1, 71, 59, 76, 77, 64, -1, -1, 71, + -1, 77, 35, 71, -1, 71, -1, 78, 35, 71, + -1, 65, 82, 66, 71, -1, 82, 59, 71, 64, + -1, 59, 71, 64, -1, 71, 49, 71, -1, 71, + 52, 71, -1, 71, 53, 71, -1, 71, 55, 71, + -1, 71, 54, 71, -1, 71, 50, 71, -1, 71, + 51, 71, -1, 71, 40, 71, -1, 71, 43, 71, + -1, 71, 41, 71, -1, 71, 45, 71, -1, 71, + 44, 71, -1, 71, 38, 71, -1, 71, 39, 71, + -1, 71, 48, 71, -1, 71, 46, 71, -1, 71, + 37, 71, -1, 7, -1, 8, -1, 3, -1, 6, + -1, 9, -1, 10, -1, 81, -1, 17, 59, 82, + 64, -1, 11, -1, 80, -1, 13, -1, 79, 33, + 13, -1, 80, -1, 34, -1, 79, 33, 12, -1, + 12, -1, 16, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 205, 205, 206, 209, 218, 223, 222, 229, 233, + 237, 238, 241, 245, 249, 253, 257, 263, 269, 273, + 279, 283, 287, 291, 296, 300, 306, 310, 316, 322, + 325, 329, 333, 337, 339, 349, 345, 359, 356, 366, + 369, 373, 378, 383, 388, 394, 400, 408, 412, 416, + 420, 424, 428, 432, 436, 440, 442, 446, 450, 454, + 458, 462, 466, 470, 477, 483, 489, 496, 505, 513, + 520, 523, 530, 537, 541, 550, 562, 570, 574, 590, + 641 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "INT", "HEX", "ERROR", "UINT", "M2_TRUE", + "M2_FALSE", "CHAR", "FLOAT", "STRING", "NAME", "BLOCKNAME", "IDENT", + "VARNAME", "TYPENAME", "SIZE", "CAP", "ORD", "HIGH", "ABS", "MIN_FUNC", + "MAX_FUNC", "FLOAT_FUNC", "VAL", "CHR", "ODD", "TRUNC", "INC", "DEC", + "INCL", "EXCL", "COLONCOLON", "INTERNAL_VAR", "','", "ABOVE_COMMA", + "ASSIGN", "'<'", "'>'", "'='", "'#'", "IN", "NOTEQUAL", "GEQ", "LEQ", + "OROR", "'&'", "LOGICAL_AND", "'@'", "'+'", "'-'", "'*'", "'/'", "MOD", + "DIV", "UNARY", "'^'", "'['", "'('", "DOT", "'~'", "NOT", "QID", "')'", + "'{'", "'}'", "']'", "$accept", "start", "type_exp", "exp", "@1", + "not_exp", "set", "@2", "@3", "arglist", "non_empty_arglist", "block", + "fblock", "variable", "type", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 44, 290, 291, 60, 62, + 61, 35, 292, 293, 294, 295, 296, 38, 297, 64, + 43, 45, 42, 47, 298, 299, 300, 94, 91, 40, + 301, 126, 302, 303, 41, 123, 125, 93 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 68, 69, 69, 70, 71, 72, 71, 71, 71, + 73, 73, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 74, 74, 75, 71, 76, 71, 77, + 77, 77, 78, 78, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 79, 80, 80, 81, 81, 81, 81, + 82 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 1, 2, 0, 3, 2, 2, + 1, 1, 4, 4, 4, 4, 4, 4, 4, 6, + 4, 4, 4, 2, 4, 6, 4, 6, 3, 1, + 3, 6, 6, 3, 4, 0, 5, 0, 5, 0, + 1, 3, 1, 3, 4, 4, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, + 1, 4, 1, 1, 1, 3, 1, 1, 3, 1, + 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 0, 66, 67, 64, 65, 68, 69, 72, 79, 74, + 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 77, 0, 6, + 0, 11, 10, 39, 0, 3, 2, 0, 29, 0, + 76, 70, 4, 0, 23, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 40, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 35, 37, 0, + 9, 0, 0, 39, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 46, 0, 33, 0, 63, 59, 60, 54, 56, + 39, 30, 0, 55, 58, 57, 62, 61, 47, 52, + 53, 48, 49, 51, 50, 0, 39, 28, 78, 75, + 0, 0, 71, 12, 13, 15, 14, 16, 17, 18, + 0, 20, 21, 22, 0, 24, 0, 26, 0, 0, + 41, 44, 42, 0, 0, 45, 34, 0, 0, 0, + 0, 0, 0, 36, 38, 19, 25, 27, 31, 32, + 43 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 34, 35, 64, 62, 37, 38, 135, 136, 65, + 163, 39, 40, 41, 45 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -92 +static const short yypact[] = +{ + 157, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, 217, -53, -27, -18, -17, -8, 2, 8, 14, + 28, 29, 30, 31, 32, 34, 35, -92, 157, -92, + 157, -92, -92, 157, 44, -92, 744, 157, -92, 62, + 64, -92, -34, 157, 6, -34, 157, 157, 157, 157, + 13, 13, 157, 13, 157, 157, 157, 157, 157, 157, + 157, 6, 157, 79, 744, -30, -39, -92, 157, 157, + 157, 157, 157, -15, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, -92, -92, -92, 86, + 6, -4, 157, 157, -25, 302, 330, 358, 386, 36, + 37, 414, 67, 442, 470, 498, 246, 274, 694, 720, + 6, -92, 157, -92, 157, 768, -36, -36, -36, -36, + 157, -92, 40, -36, -36, -36, 144, 203, 779, 788, + 788, 6, 6, 6, 6, 157, 157, -92, -92, -92, + 526, -28, -92, -92, -92, -92, -92, -92, -92, -92, + 157, -92, -92, -92, 157, -92, 157, -92, 157, 157, + 744, 6, 744, -32, -31, -92, -92, 554, 582, 610, + 638, 666, 157, -92, -92, -92, -92, -92, -92, -92, + 744 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -92, -92, -92, 0, -92, -92, 26, -92, -92, -91, + -92, -92, -92, -92, 53 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -74 +static const short yytable[] = +{ + 36, 10, 141, 172, 112, 112, 46, 112, 138, 139, + 77, 44, 78, 79, 80, 81, 82, 83, 84, 85, + 92, 86, 87, 88, 89, 92, 93, 114, 61, 10, + 63, 93, 47, 174, 92, 173, 113, 90, 166, 142, + 93, 48, 49, 63, 67, 164, 95, 96, 97, 98, + 120, 50, 101, 42, 103, 104, 105, 106, 107, 108, + 109, 51, 110, 86, 87, 88, 89, 52, 115, 116, + 117, 118, 119, 53, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 66, 54, 55, 56, + 57, 58, 140, 59, 60, 91, 94, -73, 137, 121, + 147, 148, 150, 99, 100, 93, 102, 0, 0, 0, + 0, 0, 160, 0, 161, 0, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 122, 78, 79, 80, + 81, 82, 83, 84, 85, 162, 86, 87, 88, 89, + 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, + 167, 0, 0, 0, 168, 0, 169, 0, 170, 171, + 1, 0, 0, 2, 3, 4, 5, 6, 7, 8, + 9, 0, 180, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 0, 27, 78, 79, 80, 81, 82, 83, 84, 85, + 0, 86, 87, 88, 89, 0, 0, 28, 29, 0, + 0, 0, 0, 0, 0, 0, 30, 0, 31, 32, + 1, 0, 33, 2, 3, 4, 5, 6, 7, 8, + 9, 0, 0, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 0, 27, 79, 80, 81, 82, 83, 84, 85, 0, + 86, 87, 88, 89, 0, 0, 0, 28, 29, 0, + 0, 0, 0, 0, 0, 0, 43, 0, 31, 32, + 0, 154, 33, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 0, 78, 79, 80, 81, 82, 83, + 84, 85, 0, 86, 87, 88, 89, 0, 0, 156, + 155, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 0, 78, 79, 80, 81, 82, 83, 84, 85, + 0, 86, 87, 88, 89, 0, 0, 0, 157, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 0, + 78, 79, 80, 81, 82, 83, 84, 85, 0, 86, + 87, 88, 89, 0, 0, 0, 143, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 0, 78, 79, + 80, 81, 82, 83, 84, 85, 0, 86, 87, 88, + 89, 0, 0, 0, 144, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 0, 78, 79, 80, 81, + 82, 83, 84, 85, 0, 86, 87, 88, 89, 0, + 0, 0, 145, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 0, 78, 79, 80, 81, 82, 83, + 84, 85, 0, 86, 87, 88, 89, 0, 0, 0, + 146, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 0, 78, 79, 80, 81, 82, 83, 84, 85, + 0, 86, 87, 88, 89, 0, 0, 0, 149, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 0, + 78, 79, 80, 81, 82, 83, 84, 85, 0, 86, + 87, 88, 89, 0, 0, 0, 151, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 0, 78, 79, + 80, 81, 82, 83, 84, 85, 0, 86, 87, 88, + 89, 0, 0, 0, 152, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 0, 78, 79, 80, 81, + 82, 83, 84, 85, 0, 86, 87, 88, 89, 0, + 0, 0, 153, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 0, 78, 79, 80, 81, 82, 83, + 84, 85, 0, 86, 87, 88, 89, 0, 0, 0, + 165, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 0, 78, 79, 80, 81, 82, 83, 84, 85, + 0, 86, 87, 88, 89, 0, 0, 0, 175, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 0, + 78, 79, 80, 81, 82, 83, 84, 85, 0, 86, + 87, 88, 89, 0, 0, 0, 176, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 0, 78, 79, + 80, 81, 82, 83, 84, 85, 0, 86, 87, 88, + 89, 0, 0, 0, 177, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 0, 78, 79, 80, 81, + 82, 83, 84, 85, 0, 86, 87, 88, 89, 0, + 0, 0, 178, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 0, 78, 79, 80, 81, 82, 83, + 84, 85, 0, 86, 87, 88, 89, 0, 0, 158, + 179, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 0, 78, 79, 80, 81, 82, 83, 84, 85, + 0, 86, 87, 88, 89, 159, 0, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 0, 78, 79, + 80, 81, 82, 83, 84, 85, 0, 86, 87, 88, + 89, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 0, 78, 79, 80, 81, 82, 83, 84, 85, + 0, 86, 87, 88, 89, -74, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 0, 78, 79, 80, 81, + 82, 83, 84, 85, 0, 86, 87, 88, 89, 80, + 81, 82, 83, 84, 85, 0, 86, 87, 88, 89, + 82, 83, 84, 85, 0, 86, 87, 88, 89 +}; + +static const short yycheck[] = +{ + 0, 16, 93, 35, 35, 35, 59, 35, 12, 13, + 46, 11, 48, 49, 50, 51, 52, 53, 54, 55, + 59, 57, 58, 59, 60, 59, 65, 66, 28, 16, + 30, 65, 59, 64, 59, 67, 66, 37, 66, 64, + 65, 59, 59, 43, 0, 136, 46, 47, 48, 49, + 65, 59, 52, 0, 54, 55, 56, 57, 58, 59, + 60, 59, 62, 57, 58, 59, 60, 59, 68, 69, + 70, 71, 72, 59, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 33, 59, 59, 59, + 59, 59, 92, 59, 59, 33, 43, 33, 12, 73, + 64, 64, 35, 50, 51, 65, 53, -1, -1, -1, + -1, -1, 112, -1, 114, -1, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 73, 48, 49, 50, + 51, 52, 53, 54, 55, 135, 57, 58, 59, 60, + -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, + 150, -1, -1, -1, 154, -1, 156, -1, 158, 159, + 3, -1, -1, 6, 7, 8, 9, 10, 11, 12, + 13, -1, 172, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + -1, 34, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, -1, -1, 50, 51, -1, + -1, -1, -1, -1, -1, -1, 59, -1, 61, 62, + 3, -1, 65, 6, 7, 8, 9, 10, 11, 12, + 13, -1, -1, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + -1, 34, 49, 50, 51, 52, 53, 54, 55, -1, + 57, 58, 59, 60, -1, -1, -1, 50, 51, -1, + -1, -1, -1, -1, -1, -1, 59, -1, 61, 62, + -1, 35, 65, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, -1, 48, 49, 50, 51, 52, 53, + 54, 55, -1, 57, 58, 59, 60, -1, -1, 35, + 64, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, -1, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, -1, -1, -1, 64, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, -1, + 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, + 58, 59, 60, -1, -1, -1, 64, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, -1, 48, 49, + 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, + 60, -1, -1, -1, 64, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, -1, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, -1, + -1, -1, 64, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, -1, 48, 49, 50, 51, 52, 53, + 54, 55, -1, 57, 58, 59, 60, -1, -1, -1, + 64, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, -1, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, -1, -1, -1, 64, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, -1, + 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, + 58, 59, 60, -1, -1, -1, 64, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, -1, 48, 49, + 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, + 60, -1, -1, -1, 64, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, -1, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, -1, + -1, -1, 64, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, -1, 48, 49, 50, 51, 52, 53, + 54, 55, -1, 57, 58, 59, 60, -1, -1, -1, + 64, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, -1, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, -1, -1, -1, 64, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, -1, + 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, + 58, 59, 60, -1, -1, -1, 64, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, -1, 48, 49, + 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, + 60, -1, -1, -1, 64, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, -1, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, -1, + -1, -1, 64, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, -1, 48, 49, 50, 51, 52, 53, + 54, 55, -1, 57, 58, 59, 60, -1, -1, 35, + 64, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, -1, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, 35, -1, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, -1, 48, 49, + 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, + 60, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, -1, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, -1, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, 50, + 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, + 52, 53, 54, 55, -1, 57, 58, 59, 60 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 6, 7, 8, 9, 10, 11, 12, 13, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 34, 50, 51, + 59, 61, 62, 65, 69, 70, 71, 73, 74, 79, + 80, 81, 82, 59, 71, 82, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 71, 72, 71, 71, 77, 82, 0, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 48, 49, + 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, + 71, 33, 59, 65, 82, 71, 71, 71, 71, 82, + 82, 71, 82, 71, 71, 71, 71, 71, 71, 71, + 71, 64, 35, 66, 66, 71, 71, 71, 71, 71, + 65, 74, 82, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 75, 76, 12, 12, 13, + 71, 77, 64, 64, 64, 64, 64, 64, 64, 64, + 35, 64, 64, 64, 35, 64, 35, 64, 35, 35, + 71, 71, 71, 78, 77, 64, 66, 71, 71, 71, + 71, 71, 35, 67, 64, 64, 64, 64, 64, 64, + 71 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to xreallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to xreallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: +#line 210 "m2-exp.y" + { write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(yyvsp[0].tval); + write_exp_elt_opcode(OP_TYPE); + } + break; + + case 5: +#line 219 "m2-exp.y" + { write_exp_elt_opcode (UNOP_IND); } + break; + + case 6: +#line 223 "m2-exp.y" + { number_sign = -1; } + break; + + case 7: +#line 225 "m2-exp.y" + { number_sign = 1; + write_exp_elt_opcode (UNOP_NEG); } + break; + + case 8: +#line 230 "m2-exp.y" + { write_exp_elt_opcode(UNOP_PLUS); } + break; + + case 9: +#line 234 "m2-exp.y" + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + break; + + case 12: +#line 242 "m2-exp.y" + { write_exp_elt_opcode (UNOP_CAP); } + break; + + case 13: +#line 246 "m2-exp.y" + { write_exp_elt_opcode (UNOP_ORD); } + break; + + case 14: +#line 250 "m2-exp.y" + { write_exp_elt_opcode (UNOP_ABS); } + break; + + case 15: +#line 254 "m2-exp.y" + { write_exp_elt_opcode (UNOP_HIGH); } + break; + + case 16: +#line 258 "m2-exp.y" + { write_exp_elt_opcode (UNOP_MIN); + write_exp_elt_type (yyvsp[-1].tval); + write_exp_elt_opcode (UNOP_MIN); } + break; + + case 17: +#line 264 "m2-exp.y" + { write_exp_elt_opcode (UNOP_MAX); + write_exp_elt_type (yyvsp[-1].tval); + write_exp_elt_opcode (UNOP_MIN); } + break; + + case 18: +#line 270 "m2-exp.y" + { write_exp_elt_opcode (UNOP_FLOAT); } + break; + + case 19: +#line 274 "m2-exp.y" + { write_exp_elt_opcode (BINOP_VAL); + write_exp_elt_type (yyvsp[-3].tval); + write_exp_elt_opcode (BINOP_VAL); } + break; + + case 20: +#line 280 "m2-exp.y" + { write_exp_elt_opcode (UNOP_CHR); } + break; + + case 21: +#line 284 "m2-exp.y" + { write_exp_elt_opcode (UNOP_ODD); } + break; + + case 22: +#line 288 "m2-exp.y" + { write_exp_elt_opcode (UNOP_TRUNC); } + break; + + case 23: +#line 292 "m2-exp.y" + { write_exp_elt_opcode (UNOP_SIZEOF); } + break; + + case 24: +#line 297 "m2-exp.y" + { write_exp_elt_opcode(UNOP_PREINCREMENT); } + break; + + case 25: +#line 301 "m2-exp.y" + { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode(BINOP_ADD); + write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); } + break; + + case 26: +#line 307 "m2-exp.y" + { write_exp_elt_opcode(UNOP_PREDECREMENT);} + break; + + case 27: +#line 311 "m2-exp.y" + { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode(BINOP_SUB); + write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); } + break; + + case 28: +#line 317 "m2-exp.y" + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (STRUCTOP_STRUCT); } + break; + + case 30: +#line 326 "m2-exp.y" + { error("Sets are not implemented.");} + break; + + case 31: +#line 330 "m2-exp.y" + { error("Sets are not implemented.");} + break; + + case 32: +#line 334 "m2-exp.y" + { error("Sets are not implemented.");} + break; + + case 33: +#line 338 "m2-exp.y" + { error("Sets are not implemented.");} + break; + + case 34: +#line 340 "m2-exp.y" + { error("Sets are not implemented.");} + break; + + case 35: +#line 349 "m2-exp.y" + { start_arglist(); } + break; + + case 36: +#line 351 "m2-exp.y" + { write_exp_elt_opcode (MULTI_SUBSCRIPT); + write_exp_elt_longcst ((LONGEST) end_arglist()); + write_exp_elt_opcode (MULTI_SUBSCRIPT); } + break; + + case 37: +#line 359 "m2-exp.y" + { start_arglist (); } + break; + + case 38: +#line 361 "m2-exp.y" + { write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) end_arglist ()); + write_exp_elt_opcode (OP_FUNCALL); } + break; + + case 40: +#line 370 "m2-exp.y" + { arglist_len = 1; } + break; + + case 41: +#line 374 "m2-exp.y" + { arglist_len++; } + break; + + case 42: +#line 379 "m2-exp.y" + { arglist_len = 1; } + break; + + case 43: +#line 384 "m2-exp.y" + { arglist_len++; } + break; + + case 44: +#line 389 "m2-exp.y" + { write_exp_elt_opcode (UNOP_MEMVAL); + write_exp_elt_type (yyvsp[-2].tval); + write_exp_elt_opcode (UNOP_MEMVAL); } + break; + + case 45: +#line 395 "m2-exp.y" + { write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (yyvsp[-3].tval); + write_exp_elt_opcode (UNOP_CAST); } + break; + + case 46: +#line 401 "m2-exp.y" + { } + break; + + case 47: +#line 409 "m2-exp.y" + { write_exp_elt_opcode (BINOP_REPEAT); } + break; + + case 48: +#line 413 "m2-exp.y" + { write_exp_elt_opcode (BINOP_MUL); } + break; + + case 49: +#line 417 "m2-exp.y" + { write_exp_elt_opcode (BINOP_DIV); } + break; + + case 50: +#line 421 "m2-exp.y" + { write_exp_elt_opcode (BINOP_INTDIV); } + break; + + case 51: +#line 425 "m2-exp.y" + { write_exp_elt_opcode (BINOP_REM); } + break; + + case 52: +#line 429 "m2-exp.y" + { write_exp_elt_opcode (BINOP_ADD); } + break; + + case 53: +#line 433 "m2-exp.y" + { write_exp_elt_opcode (BINOP_SUB); } + break; + + case 54: +#line 437 "m2-exp.y" + { write_exp_elt_opcode (BINOP_EQUAL); } + break; + + case 55: +#line 441 "m2-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 56: +#line 443 "m2-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 57: +#line 447 "m2-exp.y" + { write_exp_elt_opcode (BINOP_LEQ); } + break; + + case 58: +#line 451 "m2-exp.y" + { write_exp_elt_opcode (BINOP_GEQ); } + break; + + case 59: +#line 455 "m2-exp.y" + { write_exp_elt_opcode (BINOP_LESS); } + break; + + case 60: +#line 459 "m2-exp.y" + { write_exp_elt_opcode (BINOP_GTR); } + break; + + case 61: +#line 463 "m2-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + break; + + case 62: +#line 467 "m2-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + break; + + case 63: +#line 471 "m2-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN); } + break; + + case 64: +#line 478 "m2-exp.y" + { write_exp_elt_opcode (OP_BOOL); + write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); + write_exp_elt_opcode (OP_BOOL); } + break; + + case 65: +#line 484 "m2-exp.y" + { write_exp_elt_opcode (OP_BOOL); + write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); + write_exp_elt_opcode (OP_BOOL); } + break; + + case 66: +#line 490 "m2-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_m2_int); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_LONG); } + break; + + case 67: +#line 497 "m2-exp.y" + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_m2_card); + write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 68: +#line 506 "m2-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_m2_char); + write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval); + write_exp_elt_opcode (OP_LONG); } + break; + + case 69: +#line 514 "m2-exp.y" + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type (builtin_type_m2_real); + write_exp_elt_dblcst (yyvsp[0].dval); + write_exp_elt_opcode (OP_DOUBLE); } + break; + + case 71: +#line 524 "m2-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 72: +#line 531 "m2-exp.y" + { write_exp_elt_opcode (OP_M2_STRING); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_M2_STRING); } + break; + + case 73: +#line 538 "m2-exp.y" + { yyval.bval = SYMBOL_BLOCK_VALUE(yyvsp[0].sym); } + break; + + case 74: +#line 542 "m2-exp.y" + { struct symbol *sym + = lookup_symbol (copy_name (yyvsp[0].sval), expression_context_block, + VAR_DOMAIN, 0, NULL); + yyval.sym = sym;} + break; + + case 75: +#line 551 "m2-exp.y" + { struct symbol *tem + = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, 0, NULL); + if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) + error ("No function \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + yyval.sym = tem; + } + break; + + case 76: +#line 563 "m2-exp.y" + { write_exp_elt_opcode(OP_VAR_VALUE); + write_exp_elt_block (NULL); + write_exp_elt_sym (yyvsp[0].sym); + write_exp_elt_opcode (OP_VAR_VALUE); } + break; + + case 78: +#line 575 "m2-exp.y" + { struct symbol *sym; + sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, 0, NULL); + if (sym == 0) + error ("No symbol \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + + write_exp_elt_opcode (OP_VAR_VALUE); + /* block_found is set by lookup_symbol. */ + write_exp_elt_block (block_found); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); } + break; + + case 79: +#line 591 "m2-exp.y" + { struct symbol *sym; + int is_a_field_of_this; + + sym = lookup_symbol (copy_name (yyvsp[0].sval), + expression_context_block, + VAR_DOMAIN, + &is_a_field_of_this, + NULL); + if (sym) + { + if (symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block_found, + innermost_block)) + innermost_block = block_found; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not + another more inner frame which happens to + be in the same block. */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + } + else + { + struct minimal_symbol *msymbol; + char *arg = copy_name (yyvsp[0].sval); + + msymbol = + lookup_minimal_symbol (arg, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol + (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"symbol-file\" command."); + else + error ("No symbol \"%s\" in current context.", + copy_name (yyvsp[0].sval)); + } + } + break; + + case 80: +#line 642 "m2-exp.y" + { yyval.tval = lookup_typename (copy_name (yyvsp[0].sval), + expression_context_block, 0); } + break; + + + } + +/* Line 991 of yacc.c. */ + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. Doesn't work in C++ */ +#ifndef __cplusplus +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 647 "m2-exp.y" + + +#if 0 /* FIXME! */ +int +overflow(a,b) + long a,b; +{ + return (MAX_OF_TYPE(builtin_type_m2_int) - b) < a; +} + +int +uoverflow(a,b) + unsigned long a,b; +{ + return (MAX_OF_TYPE(builtin_type_m2_card) - b) < a; +} +#endif /* FIXME */ + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. + LEN is the number of characters in it. */ + +/*** Needs some error checking for the float case ***/ + +static int +parse_number (olen) + int olen; +{ + char *p = lexptr; + LONGEST n = 0; + LONGEST prevn = 0; + int c,i,ischar=0; + int base = input_radix; + int len = olen; + int unsigned_p = number_sign == 1 ? 1 : 0; + + if(p[len-1] == 'H') + { + base = 16; + len--; + } + else if(p[len-1] == 'C' || p[len-1] == 'B') + { + base = 8; + ischar = p[len-1] == 'C'; + len--; + } + + /* Scan the number */ + for (c = 0; c < len; c++) + { + if (p[c] == '.' && base == 10) + { + /* It's a float since it contains a point. */ + yylval.dval = atof (p); + lexptr += len; + return FLOAT; + } + if (p[c] == '.' && base != 10) + error("Floating point numbers must be base 10."); + if (base == 10 && (p[c] < '0' || p[c] > '9')) + error("Invalid digit \'%c\' in number.",p[c]); + } + + while (len-- > 0) + { + c = *p++; + n *= base; + if( base == 8 && (c == '8' || c == '9')) + error("Invalid digit \'%c\' in octal number.",c); + if (c >= '0' && c <= '9') + i = c - '0'; + else + { + if (base == 16 && c >= 'A' && c <= 'F') + i = c - 'A' + 10; + else + return ERROR; + } + n+=i; + if(i >= base) + return ERROR; + if(!unsigned_p && number_sign == 1 && (prevn >= n)) + unsigned_p=1; /* Try something unsigned */ + /* Don't do the range check if n==i and i==0, since that special + case will give an overflow error. */ + if(RANGE_CHECK && n!=i && i) + { + if((unsigned_p && (unsigned)prevn >= (unsigned)n) || + ((!unsigned_p && number_sign==-1) && -prevn <= -n)) + range_error("Overflow on numeric constant."); + } + prevn=n; + } + + lexptr = p; + if(*p == 'B' || *p == 'C' || *p == 'H') + lexptr++; /* Advance past B,C or H */ + + if (ischar) + { + yylval.ulval = n; + return CHAR; + } + else if ( unsigned_p && number_sign == 1) + { + yylval.ulval = n; + return UINT; + } + else if((unsigned_p && (n<0))) { + range_error("Overflow on numeric constant -- number too large."); + /* But, this can return if range_check == range_warn. */ + } + yylval.lval = n; + return INT; +} + + +/* Some tokens */ + +static struct +{ + char name[2]; + int token; +} tokentab2[] = +{ + { {'<', '>'}, NOTEQUAL }, + { {':', '='}, ASSIGN }, + { {'<', '='}, LEQ }, + { {'>', '='}, GEQ }, + { {':', ':'}, COLONCOLON }, + +}; + +/* Some specific keywords */ + +struct keyword { + char keyw[10]; + int token; +}; + +static struct keyword keytab[] = +{ + {"OR" , OROR }, + {"IN", IN },/* Note space after IN */ + {"AND", LOGICAL_AND}, + {"ABS", ABS }, + {"CHR", CHR }, + {"DEC", DEC }, + {"NOT", NOT }, + {"DIV", DIV }, + {"INC", INC }, + {"MAX", MAX_FUNC }, + {"MIN", MIN_FUNC }, + {"MOD", MOD }, + {"ODD", ODD }, + {"CAP", CAP }, + {"ORD", ORD }, + {"VAL", VAL }, + {"EXCL", EXCL }, + {"HIGH", HIGH }, + {"INCL", INCL }, + {"SIZE", SIZE }, + {"FLOAT", FLOAT_FUNC }, + {"TRUNC", TRUNC }, +}; + + +/* Read one token, getting characters through lexptr. */ + +/* This is where we will check to make sure that the language and the operators used are + compatible */ + +static int +yylex () +{ + int c; + int namelen; + int i; + char *tokstart; + char quote; + + retry: + + prev_lexptr = lexptr; + + tokstart = lexptr; + + + /* See if it is a special token of length 2 */ + for( i = 0 ; i < (int) (sizeof tokentab2 / sizeof tokentab2[0]) ; i++) + if(DEPRECATED_STREQN(tokentab2[i].name, tokstart, 2)) + { + lexptr += 2; + return tokentab2[i].token; + } + + switch (c = *tokstart) + { + case 0: + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return c; + + case '.': + /* Might be a floating point number. */ + if (lexptr[1] >= '0' && lexptr[1] <= '9') + break; /* Falls into number code. */ + else + { + lexptr++; + return DOT; + } + +/* These are character tokens that appear as-is in the YACC grammar */ + case '+': + case '-': + case '*': + case '/': + case '^': + case '<': + case '>': + case '[': + case ']': + case '=': + case '{': + case '}': + case '#': + case '@': + case '~': + case '&': + lexptr++; + return c; + + case '\'' : + case '"': + quote = c; + for (namelen = 1; (c = tokstart[namelen]) != quote && c != '\0'; namelen++) + if (c == '\\') + { + c = tokstart[++namelen]; + if (c >= '0' && c <= '9') + { + c = tokstart[++namelen]; + if (c >= '0' && c <= '9') + c = tokstart[++namelen]; + } + } + if(c != quote) + error("Unterminated string or character constant."); + yylval.sval.ptr = tokstart + 1; + yylval.sval.length = namelen - 1; + lexptr += namelen + 1; + + if(namelen == 2) /* Single character */ + { + yylval.ulval = tokstart[1]; + return CHAR; + } + else + return STRING; + } + + /* Is it a number? */ + /* Note: We have already dealt with the case of the token '.'. + See case '.' above. */ + if ((c >= '0' && c <= '9')) + { + /* It's a number. */ + int got_dot = 0, got_e = 0; + char *p = tokstart; + int toktype; + + for (++p ;; ++p) + { + if (!got_e && (*p == 'e' || *p == 'E')) + got_dot = got_e = 1; + else if (!got_dot && *p == '.') + got_dot = 1; + else if (got_e && (p[-1] == 'e' || p[-1] == 'E') + && (*p == '-' || *p == '+')) + /* This is the sign of the exponent, not the end of the + number. */ + continue; + else if ((*p < '0' || *p > '9') && + (*p < 'A' || *p > 'F') && + (*p != 'H')) /* Modula-2 hexadecimal number */ + break; + } + toktype = parse_number (p - tokstart); + if (toktype == ERROR) + { + char *err_copy = (char *) alloca (p - tokstart + 1); + + memcpy (err_copy, tokstart, p - tokstart); + err_copy[p - tokstart] = 0; + error ("Invalid number \"%s\".", err_copy); + } + lexptr = p; + return toktype; + } + + if (!(c == '_' || c == '$' + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + /* We must have come across a bad character (e.g. ';'). */ + error ("Invalid character '%c' in expression.", c); + + /* It's a name. See how long it is. */ + namelen = 0; + for (c = tokstart[namelen]; + (c == '_' || c == '$' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); + c = tokstart[++namelen]) + ; + + /* The token "if" terminates the expression and is NOT + removed from the input stream. */ + if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') + { + return 0; + } + + lexptr += namelen; + + /* Lookup special keywords */ + for(i = 0 ; i < (int) (sizeof(keytab) / sizeof(keytab[0])) ; i++) + if(namelen == strlen(keytab[i].keyw) && DEPRECATED_STREQN(tokstart,keytab[i].keyw,namelen)) + return keytab[i].token; + + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + if (*tokstart == '$') + { + write_dollar_variable (yylval.sval); + return INTERNAL_VAR; + } + + /* Use token-type BLOCKNAME for symbols that happen to be defined as + functions. If this is not so, then ... + Use token-type TYPENAME for symbols that happen to be defined + currently as names of types; NAME for other symbols. + The caller is not constrained to care about the distinction. */ + { + + + char *tmp = copy_name (yylval.sval); + struct symbol *sym; + + if (lookup_partial_symtab (tmp)) + return BLOCKNAME; + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, 0, NULL); + if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) + return BLOCKNAME; + if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1)) + return TYPENAME; + + if(sym) + { + switch(sym->aclass) + { + case LOC_STATIC: + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_LOCAL_ARG: + case LOC_BASEREG: + case LOC_BASEREG_ARG: + case LOC_CONST: + case LOC_CONST_BYTES: + case LOC_OPTIMIZED_OUT: + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + return NAME; + + case LOC_TYPEDEF: + return TYPENAME; + + case LOC_BLOCK: + return BLOCKNAME; + + case LOC_UNDEF: + error("internal: Undefined class in m2lex()"); + + case LOC_LABEL: + case LOC_UNRESOLVED: + error("internal: Unforseen case in m2lex()"); + + default: + error ("unhandled token in m2lex()"); + break; + } + } + else + { + /* Built-in BOOLEAN type. This is sort of a hack. */ + if(DEPRECATED_STREQN(tokstart,"TRUE",4)) + { + yylval.ulval = 1; + return M2_TRUE; + } + else if(DEPRECATED_STREQN(tokstart,"FALSE",5)) + { + yylval.ulval = 0; + return M2_FALSE; + } + } + + /* Must be another type of name... */ + return NAME; + } +} + +#if 0 /* Unused */ +static char * +make_qualname(mod,ident) + char *mod, *ident; +{ + char *new = xmalloc(strlen(mod)+strlen(ident)+2); + + strcpy(new,mod); + strcat(new,"."); + strcat(new,ident); + return new; +} +#endif /* 0 */ + +void +yyerror (msg) + char *msg; +{ + if (prev_lexptr) + lexptr = prev_lexptr; + + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); +} + + diff --git a/contrib/gdb/gdb/m2-exp.y b/contrib/gdb/gdb/m2-exp.y index eaaad5a3882..646672b391f 100644 --- a/contrib/gdb/gdb/m2-exp.y +++ b/contrib/gdb/gdb/m2-exp.y @@ -50,6 +50,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" /* Required by objfiles.h. */ #include "symfile.h" /* Required by objfiles.h. */ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), as well as gratuitiously global symbol names, so we can have multiple @@ -87,6 +88,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yylloc m2_lloc #define yyreds m2_reds /* With YYDEBUG defined */ #define yytoks m2_toks /* With YYDEBUG defined */ +#define yyname m2_name /* With YYDEBUG defined */ +#define yyrule m2_rule /* With YYDEBUG defined */ #define yylhs m2_yylhs #define yylen m2_yylen #define yydefred m2_yydefred @@ -98,9 +101,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yycheck m2_yycheck #ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ +#define YYDEBUG 1 /* Default to yydebug support */ #endif +#define YYFPRINTF parser_fprintf + int yyparse (void); static int yylex (void); @@ -212,6 +217,7 @@ type_exp: type exp : exp '^' %prec UNARY { write_exp_elt_opcode (UNOP_IND); } + ; exp : '-' { number_sign = -1; } @@ -326,6 +332,7 @@ exp : INCL '(' exp ',' exp ')' exp : EXCL '(' exp ',' exp ')' { error("Sets are not implemented.");} + ; set : '{' arglist '}' { error("Sets are not implemented.");} @@ -534,7 +541,7 @@ block : fblock fblock : BLOCKNAME { struct symbol *sym = lookup_symbol (copy_name ($1), expression_context_block, - VAR_NAMESPACE, 0, NULL); + VAR_DOMAIN, 0, NULL); $$ = sym;} ; @@ -543,7 +550,7 @@ fblock : BLOCKNAME fblock : block COLONCOLON BLOCKNAME { struct symbol *tem = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, 0, NULL); + VAR_DOMAIN, 0, NULL); if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) error ("No function \"%s\" in specified context.", copy_name ($3)); @@ -567,7 +574,7 @@ variable: INTERNAL_VAR variable: block COLONCOLON NAME { struct symbol *sym; sym = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, 0, NULL); + VAR_DOMAIN, 0, NULL); if (sym == 0) error ("No symbol \"%s\" in specified context.", copy_name ($3)); @@ -586,7 +593,7 @@ variable: NAME sym = lookup_symbol (copy_name ($1), expression_context_block, - VAR_NAMESPACE, + VAR_DOMAIN, &is_a_field_of_this, NULL); if (sym) @@ -610,7 +617,7 @@ variable: NAME else { struct minimal_symbol *msymbol; - register char *arg = copy_name ($1); + char *arg = copy_name ($1); msymbol = lookup_minimal_symbol (arg, NULL, NULL); @@ -665,12 +672,12 @@ static int parse_number (olen) int olen; { - register char *p = lexptr; - register LONGEST n = 0; - register LONGEST prevn = 0; - register int c,i,ischar=0; - register int base = input_radix; - register int len = olen; + char *p = lexptr; + LONGEST n = 0; + LONGEST prevn = 0; + int c,i,ischar=0; + int base = input_radix; + int len = olen; int unsigned_p = number_sign == 1 ? 1 : 0; if(p[len-1] == 'H') @@ -813,20 +820,22 @@ static struct keyword keytab[] = static int yylex () { - register int c; - register int namelen; - register int i; - register char *tokstart; - register char quote; + int c; + int namelen; + int i; + char *tokstart; + char quote; retry: + prev_lexptr = lexptr; + tokstart = lexptr; /* See if it is a special token of length 2 */ for( i = 0 ; i < (int) (sizeof tokentab2 / sizeof tokentab2[0]) ; i++) - if(STREQN(tokentab2[i].name, tokstart, 2)) + if(DEPRECATED_STREQN(tokentab2[i].name, tokstart, 2)) { lexptr += 2; return tokentab2[i].token; @@ -927,7 +936,7 @@ yylex () { /* It's a number. */ int got_dot = 0, got_e = 0; - register char *p = tokstart; + char *p = tokstart; int toktype; for (++p ;; ++p) @@ -983,7 +992,7 @@ yylex () /* Lookup special keywords */ for(i = 0 ; i < (int) (sizeof(keytab) / sizeof(keytab[0])) ; i++) - if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen)) + if(namelen == strlen(keytab[i].keyw) && DEPRECATED_STREQN(tokstart,keytab[i].keyw,namelen)) return keytab[i].token; yylval.sval.ptr = tokstart; @@ -1009,7 +1018,7 @@ yylex () if (lookup_partial_symtab (tmp)) return BLOCKNAME; sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, 0, NULL); + VAR_DOMAIN, 0, NULL); if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) return BLOCKNAME; if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1)) @@ -1032,6 +1041,8 @@ yylex () case LOC_CONST: case LOC_CONST_BYTES: case LOC_OPTIMIZED_OUT: + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: return NAME; case LOC_TYPEDEF: @@ -1055,12 +1066,12 @@ yylex () else { /* Built-in BOOLEAN type. This is sort of a hack. */ - if(STREQN(tokstart,"TRUE",4)) + if(DEPRECATED_STREQN(tokstart,"TRUE",4)) { yylval.ulval = 1; return M2_TRUE; } - else if(STREQN(tokstart,"FALSE",5)) + else if(DEPRECATED_STREQN(tokstart,"FALSE",5)) { yylval.ulval = 0; return M2_FALSE; @@ -1090,5 +1101,8 @@ void yyerror (msg) char *msg; { + if (prev_lexptr) + lexptr = prev_lexptr; + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); } diff --git a/contrib/gdb/gdb/m2-lang.c b/contrib/gdb/gdb/m2-lang.c index 116d85009fd..e5b6b500e7c 100644 --- a/contrib/gdb/gdb/m2-lang.c +++ b/contrib/gdb/gdb/m2-lang.c @@ -1,5 +1,5 @@ /* Modula 2 language support routines for GDB, the GNU debugger. - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2002 + Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -45,7 +45,7 @@ static void m2_emit_char (int, struct ui_file *, int); */ static void -m2_emit_char (register int c, struct ui_file *stream, int quoter) +m2_emit_char (int c, struct ui_file *stream, int quoter) { c &= 0xFF; /* Avoid sign bit follies */ @@ -112,11 +112,10 @@ static void m2_printstr (struct ui_file *stream, char *string, unsigned int length, int width, int force_ellipses) { - register unsigned int i; + unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; - extern int inspect_it; if (length == 0) { @@ -199,7 +198,7 @@ m2_printstr (struct ui_file *stream, char *string, unsigned int length, static struct type * m2_create_fundamental_type (struct objfile *objfile, int typeid) { - register struct type *type = NULL; + struct type *type = NULL; switch (typeid) { @@ -416,9 +415,9 @@ const struct language_defn m2_language_defn = range_check_on, type_check_on, case_sensitive_on, + &exp_descriptor_standard, m2_parse, /* parser */ m2_error, /* parser error function */ - evaluate_subexp_standard, m2_printchar, /* Print character constant */ m2_printstr, /* function to print string constant */ m2_emit_char, /* Function to print a single character */ @@ -426,6 +425,11 @@ const struct language_defn m2_language_defn = m2_print_type, /* Print a type using appropriate syntax */ m2_val_print, /* Print a value using appropriate syntax */ c_value_print, /* Print a top-level value */ + NULL, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"%loB", "", "o", "B"}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -434,6 +438,7 @@ const struct language_defn m2_language_defn = 0, /* arrays are first-class (not c-style) */ 0, /* String lower bound */ &builtin_type_m2_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; diff --git a/contrib/gdb/gdb/macrocmd.c b/contrib/gdb/gdb/macrocmd.c new file mode 100644 index 00000000000..7c2ebbea749 --- /dev/null +++ b/contrib/gdb/gdb/macrocmd.c @@ -0,0 +1,289 @@ +/* C preprocessor macro expansion commands for GDB. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#include "defs.h" +#include "macrotab.h" +#include "macroexp.h" +#include "macroscope.h" +#include "command.h" +#include "gdbcmd.h" + + +/* The `macro' prefix command. */ + +static struct cmd_list_element *macrolist; + +static void +macro_command (char *arg, int from_tty) +{ + printf_unfiltered + ("\"macro\" must be followed by the name of a macro command.\n"); + help_list (macrolist, "macro ", -1, gdb_stdout); +} + + + +/* Macro expansion commands. */ + + +static void +macro_expand_command (char *exp, int from_tty) +{ + struct macro_scope *ms = NULL; + char *expanded = NULL; + struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms); + make_cleanup (free_current_contents, &expanded); + + /* You know, when the user doesn't specify any expression, it would be + really cool if this defaulted to the last expression evaluated. + Then it would be easy to ask, "Hey, what did I just evaluate?" But + at the moment, the `print' commands don't save the last expression + evaluated, just its value. */ + if (! exp || ! *exp) + error ("You must follow the `macro expand' command with the" + " expression you\n" + "want to expand."); + + ms = default_macro_scope (); + if (ms) + { + expanded = macro_expand (exp, standard_macro_lookup, ms); + fputs_filtered ("expands to: ", gdb_stdout); + fputs_filtered (expanded, gdb_stdout); + fputs_filtered ("\n", gdb_stdout); + } + else + fputs_filtered ("GDB has no preprocessor macro information for " + "that code.\n", + gdb_stdout); + + do_cleanups (cleanup_chain); + return; +} + + +static void +macro_expand_once_command (char *exp, int from_tty) +{ + struct macro_scope *ms = NULL; + char *expanded = NULL; + struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms); + make_cleanup (free_current_contents, &expanded); + + /* You know, when the user doesn't specify any expression, it would be + really cool if this defaulted to the last expression evaluated. + And it should set the once-expanded text as the new `last + expression'. That way, you could just hit return over and over and + see the expression expanded one level at a time. */ + if (! exp || ! *exp) + error ("You must follow the `macro expand-once' command with" + " the expression\n" + "you want to expand."); + + ms = default_macro_scope (); + if (ms) + { + expanded = macro_expand_once (exp, standard_macro_lookup, ms); + fputs_filtered ("expands to: ", gdb_stdout); + fputs_filtered (expanded, gdb_stdout); + fputs_filtered ("\n", gdb_stdout); + } + else + fputs_filtered ("GDB has no preprocessor macro information for " + "that code.\n", + gdb_stdout); + + do_cleanups (cleanup_chain); + return; +} + + +static void +show_pp_source_pos (struct ui_file *stream, + struct macro_source_file *file, + int line) +{ + fprintf_filtered (stream, "%s:%d\n", file->filename, line); + + while (file->included_by) + { + fprintf_filtered (gdb_stdout, " included at %s:%d\n", + file->included_by->filename, + file->included_at_line); + file = file->included_by; + } +} + + +static void +info_macro_command (char *name, int from_tty) +{ + struct macro_scope *ms = NULL; + struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms); + struct macro_definition *d; + + if (! name || ! *name) + error ("You must follow the `info macro' command with the name" + " of the macro\n" + "whose definition you want to see."); + + ms = default_macro_scope (); + if (! ms) + error ("GDB has no preprocessor macro information for that code."); + + d = macro_lookup_definition (ms->file, ms->line, name); + if (d) + { + int line; + struct macro_source_file *file + = macro_definition_location (ms->file, ms->line, name, &line); + + fprintf_filtered (gdb_stdout, "Defined at "); + show_pp_source_pos (gdb_stdout, file, line); + fprintf_filtered (gdb_stdout, "#define %s", name); + if (d->kind == macro_function_like) + { + int i; + + fputs_filtered ("(", gdb_stdout); + for (i = 0; i < d->argc; i++) + { + fputs_filtered (d->argv[i], gdb_stdout); + if (i + 1 < d->argc) + fputs_filtered (", ", gdb_stdout); + } + fputs_filtered (")", gdb_stdout); + } + fprintf_filtered (gdb_stdout, " %s\n", d->replacement); + } + else + { + fprintf_filtered (gdb_stdout, + "The symbol `%s' has no definition as a C/C++" + " preprocessor macro\n" + "at ", name); + show_pp_source_pos (gdb_stdout, ms->file, ms->line); + } + + do_cleanups (cleanup_chain); +} + + + +/* User-defined macros. */ + +/* A table of user-defined macros. Unlike the macro tables used for + symtabs, this one uses xmalloc for all its allocation, not an + obstack, and it doesn't bcache anything; it just xmallocs things. So + it's perfectly possible to remove things from this, or redefine + things. */ +static struct macro_table *user_macros; + +static void +macro_define_command (char *exp, int from_tty) +{ + error ("Command not implemented yet."); +} + + +static void +macro_undef_command (char *exp, int from_tty) +{ + error ("Command not implemented yet."); +} + + +static void +macro_list_command (char *exp, int from_tty) +{ + error ("Command not implemented yet."); +} + + + +/* Initializing the `macrocmd' module. */ + +extern initialize_file_ftype _initialize_macrocmd; /* -Wmissing-prototypes */ + +void +_initialize_macrocmd (void) +{ + struct cmd_list_element *c; + + /* We introduce a new command prefix, `macro', under which we'll put + the various commands for working with preprocessor macros. */ + add_prefix_cmd + ("macro", class_info, macro_command, + "Prefix for commands dealing with C preprocessor macros.", + ¯olist, "macro ", 0, &cmdlist); + + add_cmd + ("expand", no_class, macro_expand_command, + "Fully expand any C/C++ preprocessor macro invocations in EXPRESSION.\n" + "Show the expanded expression.", + ¯olist); + add_alias_cmd ("exp", "expand", no_class, 1, ¯olist); + add_cmd + ("expand-once", no_class, macro_expand_once_command, + "Expand C/C++ preprocessor macro invocations appearing directly in" + " EXPRESSION.\n" + "Show the expanded expression.\n" + "\n" + "This command differs from `macro expand' in that it only expands macro\n" + "invocations that appear directly in EXPRESSION; if expanding a macro\n" + "introduces further macro invocations, those are left unexpanded.\n" + "\n" + "`macro expand-once' helps you see how a particular macro expands,\n" + "whereas `macro expand' shows you how all the macros involved in an\n" + "expression work together to yield a pre-processed expression.", + ¯olist); + add_alias_cmd ("exp1", "expand-once", no_class, 1, ¯olist); + + add_cmd + ("macro", no_class, info_macro_command, + "Show the definition of MACRO, and its source location.", + &infolist); + + add_cmd + ("define", no_class, macro_define_command, + "Define a new C/C++ preprocessor macro.\n" + "The GDB command `macro define DEFINITION' is equivalent to placing a\n" + "preprocessor directive of the form `#define DEFINITION' such that the\n" + "definition is visible in all the inferior's source files.\n" + "For example:\n" + " (gdb) macro define PI (3.1415926)\n" + " (gdb) macro define MIN(x,y) ((x) < (y) ? (x) : (y))", + ¯olist); + + add_cmd + ("undef", no_class, macro_undef_command, + "Remove the definition of the C/C++ preprocessor macro with the" + " given name.", + ¯olist); + + add_cmd + ("list", no_class, macro_list_command, + "List all the macros defined using the `macro define' command.", + ¯olist); + + user_macros = new_macro_table (0, 0); +} diff --git a/contrib/gdb/gdb/macroexp.c b/contrib/gdb/gdb/macroexp.c new file mode 100644 index 00000000000..e39f81ac0bd --- /dev/null +++ b/contrib/gdb/gdb/macroexp.c @@ -0,0 +1,1169 @@ +/* C preprocessor macro expansion for GDB. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_obstack.h" +#include "bcache.h" +#include "macrotab.h" +#include "macroexp.h" +#include "gdb_assert.h" + + + +/* A resizeable, substringable string type. */ + + +/* A string type that we can resize, quickly append to, and use to + refer to substrings of other strings. */ +struct macro_buffer +{ + /* An array of characters. The first LEN bytes are the real text, + but there are SIZE bytes allocated to the array. If SIZE is + zero, then this doesn't point to a malloc'ed block. If SHARED is + non-zero, then this buffer is actually a pointer into some larger + string, and we shouldn't append characters to it, etc. Because + of sharing, we can't assume in general that the text is + null-terminated. */ + char *text; + + /* The number of characters in the string. */ + int len; + + /* The number of characters allocated to the string. If SHARED is + non-zero, this is meaningless; in this case, we set it to zero so + that any "do we have room to append something?" tests will fail, + so we don't always have to check SHARED before using this field. */ + int size; + + /* Zero if TEXT can be safely realloc'ed (i.e., it's its own malloc + block). Non-zero if TEXT is actually pointing into the middle of + some other block, and we shouldn't reallocate it. */ + int shared; + + /* For detecting token splicing. + + This is the index in TEXT of the first character of the token + that abuts the end of TEXT. If TEXT contains no tokens, then we + set this equal to LEN. If TEXT ends in whitespace, then there is + no token abutting the end of TEXT (it's just whitespace), and + again, we set this equal to LEN. We set this to -1 if we don't + know the nature of TEXT. */ + int last_token; + + /* If this buffer is holding the result from get_token, then this + is non-zero if it is an identifier token, zero otherwise. */ + int is_identifier; +}; + + +/* Set the macro buffer *B to the empty string, guessing that its + final contents will fit in N bytes. (It'll get resized if it + doesn't, so the guess doesn't have to be right.) Allocate the + initial storage with xmalloc. */ +static void +init_buffer (struct macro_buffer *b, int n) +{ + /* Small value for initial testing. */ + n = 1; + + b->size = n; + if (n > 0) + b->text = (char *) xmalloc (n); + else + b->text = NULL; + b->len = 0; + b->shared = 0; + b->last_token = -1; +} + + +/* Set the macro buffer *BUF to refer to the LEN bytes at ADDR, as a + shared substring. */ +static void +init_shared_buffer (struct macro_buffer *buf, char *addr, int len) +{ + buf->text = addr; + buf->len = len; + buf->shared = 1; + buf->size = 0; + buf->last_token = -1; +} + + +/* Free the text of the buffer B. Raise an error if B is shared. */ +static void +free_buffer (struct macro_buffer *b) +{ + gdb_assert (! b->shared); + if (b->size) + xfree (b->text); +} + + +/* A cleanup function for macro buffers. */ +static void +cleanup_macro_buffer (void *untyped_buf) +{ + free_buffer ((struct macro_buffer *) untyped_buf); +} + + +/* Resize the buffer B to be at least N bytes long. Raise an error if + B shouldn't be resized. */ +static void +resize_buffer (struct macro_buffer *b, int n) +{ + /* We shouldn't be trying to resize shared strings. */ + gdb_assert (! b->shared); + + if (b->size == 0) + b->size = n; + else + while (b->size <= n) + b->size *= 2; + + b->text = xrealloc (b->text, b->size); +} + + +/* Append the character C to the buffer B. */ +static void +appendc (struct macro_buffer *b, int c) +{ + int new_len = b->len + 1; + + if (new_len > b->size) + resize_buffer (b, new_len); + + b->text[b->len] = c; + b->len = new_len; +} + + +/* Append the LEN bytes at ADDR to the buffer B. */ +static void +appendmem (struct macro_buffer *b, char *addr, int len) +{ + int new_len = b->len + len; + + if (new_len > b->size) + resize_buffer (b, new_len); + + memcpy (b->text + b->len, addr, len); + b->len = new_len; +} + + + +/* Recognizing preprocessor tokens. */ + + +static int +is_whitespace (int c) +{ + return (c == ' ' + || c == '\t' + || c == '\n' + || c == '\v' + || c == '\f'); +} + + +static int +is_digit (int c) +{ + return ('0' <= c && c <= '9'); +} + + +static int +is_identifier_nondigit (int c) +{ + return (c == '_' + || ('a' <= c && c <= 'z') + || ('A' <= c && c <= 'Z')); +} + + +static void +set_token (struct macro_buffer *tok, char *start, char *end) +{ + init_shared_buffer (tok, start, end - start); + tok->last_token = 0; + + /* Presumed; get_identifier may overwrite this. */ + tok->is_identifier = 0; +} + + +static int +get_comment (struct macro_buffer *tok, char *p, char *end) +{ + if (p + 2 > end) + return 0; + else if (p[0] == '/' + && p[1] == '*') + { + char *tok_start = p; + + p += 2; + + for (; p < end; p++) + if (p + 2 <= end + && p[0] == '*' + && p[1] == '/') + { + p += 2; + set_token (tok, tok_start, p); + return 1; + } + + error ("Unterminated comment in macro expansion."); + } + else if (p[0] == '/' + && p[1] == '/') + { + char *tok_start = p; + + p += 2; + for (; p < end; p++) + if (*p == '\n') + break; + + set_token (tok, tok_start, p); + return 1; + } + else + return 0; +} + + +static int +get_identifier (struct macro_buffer *tok, char *p, char *end) +{ + if (p < end + && is_identifier_nondigit (*p)) + { + char *tok_start = p; + + while (p < end + && (is_identifier_nondigit (*p) + || is_digit (*p))) + p++; + + set_token (tok, tok_start, p); + tok->is_identifier = 1; + return 1; + } + else + return 0; +} + + +static int +get_pp_number (struct macro_buffer *tok, char *p, char *end) +{ + if (p < end + && (is_digit (*p) + || *p == '.')) + { + char *tok_start = p; + + while (p < end) + { + if (is_digit (*p) + || is_identifier_nondigit (*p) + || *p == '.') + p++; + else if (p + 2 <= end + && strchr ("eEpP.", *p) + && (p[1] == '+' || p[1] == '-')) + p += 2; + else + break; + } + + set_token (tok, tok_start, p); + return 1; + } + else + return 0; +} + + + +/* If the text starting at P going up to (but not including) END + starts with a character constant, set *TOK to point to that + character constant, and return 1. Otherwise, return zero. + Signal an error if it contains a malformed or incomplete character + constant. */ +static int +get_character_constant (struct macro_buffer *tok, char *p, char *end) +{ + /* ISO/IEC 9899:1999 (E) Section 6.4.4.4 paragraph 1 + But of course, what really matters is that we handle it the same + way GDB's C/C++ lexer does. So we call parse_escape in utils.c + to handle escape sequences. */ + if ((p + 1 <= end && *p == '\'') + || (p + 2 <= end && p[0] == 'L' && p[1] == '\'')) + { + char *tok_start = p; + char *body_start; + + if (*p == '\'') + p++; + else if (*p == 'L') + p += 2; + else + gdb_assert (0); + + body_start = p; + for (;;) + { + if (p >= end) + error ("Unmatched single quote."); + else if (*p == '\'') + { + if (p == body_start) + error ("A character constant must contain at least one " + "character."); + p++; + break; + } + else if (*p == '\\') + { + p++; + parse_escape (&p); + } + else + p++; + } + + set_token (tok, tok_start, p); + return 1; + } + else + return 0; +} + + +/* If the text starting at P going up to (but not including) END + starts with a string literal, set *TOK to point to that string + literal, and return 1. Otherwise, return zero. Signal an error if + it contains a malformed or incomplete string literal. */ +static int +get_string_literal (struct macro_buffer *tok, char *p, char *end) +{ + if ((p + 1 <= end + && *p == '\"') + || (p + 2 <= end + && p[0] == 'L' + && p[1] == '\"')) + { + char *tok_start = p; + + if (*p == '\"') + p++; + else if (*p == 'L') + p += 2; + else + gdb_assert (0); + + for (;;) + { + if (p >= end) + error ("Unterminated string in expression."); + else if (*p == '\"') + { + p++; + break; + } + else if (*p == '\n') + error ("Newline characters may not appear in string " + "constants."); + else if (*p == '\\') + { + p++; + parse_escape (&p); + } + else + p++; + } + + set_token (tok, tok_start, p); + return 1; + } + else + return 0; +} + + +static int +get_punctuator (struct macro_buffer *tok, char *p, char *end) +{ + /* Here, speed is much less important than correctness and clarity. */ + + /* ISO/IEC 9899:1999 (E) Section 6.4.6 Paragraph 1 */ + static const char * const punctuators[] = { + "[", "]", "(", ")", "{", "}", ".", "->", + "++", "--", "&", "*", "+", "-", "~", "!", + "/", "%", "<<", ">>", "<", ">", "<=", ">=", "==", "!=", + "^", "|", "&&", "||", + "?", ":", ";", "...", + "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|=", + ",", "#", "##", + "<:", ":>", "<%", "%>", "%:", "%:%:", + 0 + }; + + int i; + + if (p + 1 <= end) + { + for (i = 0; punctuators[i]; i++) + { + const char *punctuator = punctuators[i]; + + if (p[0] == punctuator[0]) + { + int len = strlen (punctuator); + + if (p + len <= end + && ! memcmp (p, punctuator, len)) + { + set_token (tok, p, p + len); + return 1; + } + } + } + } + + return 0; +} + + +/* Peel the next preprocessor token off of SRC, and put it in TOK. + Mutate TOK to refer to the first token in SRC, and mutate SRC to + refer to the text after that token. SRC must be a shared buffer; + the resulting TOK will be shared, pointing into the same string SRC + does. Initialize TOK's last_token field. Return non-zero if we + succeed, or 0 if we didn't find any more tokens in SRC. */ +static int +get_token (struct macro_buffer *tok, + struct macro_buffer *src) +{ + char *p = src->text; + char *end = p + src->len; + + gdb_assert (src->shared); + + /* From the ISO C standard, ISO/IEC 9899:1999 (E), section 6.4: + + preprocessing-token: + header-name + identifier + pp-number + character-constant + string-literal + punctuator + each non-white-space character that cannot be one of the above + + We don't have to deal with header-name tokens, since those can + only occur after a #include, which we will never see. */ + + while (p < end) + if (is_whitespace (*p)) + p++; + else if (get_comment (tok, p, end)) + p += tok->len; + else if (get_pp_number (tok, p, end) + || get_character_constant (tok, p, end) + || get_string_literal (tok, p, end) + /* Note: the grammar in the standard seems to be + ambiguous: L'x' can be either a wide character + constant, or an identifier followed by a normal + character constant. By trying `get_identifier' after + we try get_character_constant and get_string_literal, + we give the wide character syntax precedence. Now, + since GDB doesn't handle wide character constants + anyway, is this the right thing to do? */ + || get_identifier (tok, p, end) + || get_punctuator (tok, p, end)) + { + /* How many characters did we consume, including whitespace? */ + int consumed = p - src->text + tok->len; + src->text += consumed; + src->len -= consumed; + return 1; + } + else + { + /* We have found a "non-whitespace character that cannot be + one of the above." Make a token out of it. */ + int consumed; + + set_token (tok, p, p + 1); + consumed = p - src->text + tok->len; + src->text += consumed; + src->len -= consumed; + return 1; + } + + return 0; +} + + + +/* Appending token strings, with and without splicing */ + + +/* Append the macro buffer SRC to the end of DEST, and ensure that + doing so doesn't splice the token at the end of SRC with the token + at the beginning of DEST. SRC and DEST must have their last_token + fields set. Upon return, DEST's last_token field is set correctly. + + For example: + + If DEST is "(" and SRC is "y", then we can return with + DEST set to "(y" --- we've simply appended the two buffers. + + However, if DEST is "x" and SRC is "y", then we must not return + with DEST set to "xy" --- that would splice the two tokens "x" and + "y" together to make a single token "xy". However, it would be + fine to return with DEST set to "x y". Similarly, "<" and "<" must + yield "< <", not "<<", etc. */ +static void +append_tokens_without_splicing (struct macro_buffer *dest, + struct macro_buffer *src) +{ + int original_dest_len = dest->len; + struct macro_buffer dest_tail, new_token; + + gdb_assert (src->last_token != -1); + gdb_assert (dest->last_token != -1); + + /* First, just try appending the two, and call get_token to see if + we got a splice. */ + appendmem (dest, src->text, src->len); + + /* If DEST originally had no token abutting its end, then we can't + have spliced anything, so we're done. */ + if (dest->last_token == original_dest_len) + { + dest->last_token = original_dest_len + src->last_token; + return; + } + + /* Set DEST_TAIL to point to the last token in DEST, followed by + all the stuff we just appended. */ + init_shared_buffer (&dest_tail, + dest->text + dest->last_token, + dest->len - dest->last_token); + + /* Re-parse DEST's last token. We know that DEST used to contain + at least one token, so if it doesn't contain any after the + append, then we must have spliced "/" and "*" or "/" and "/" to + make a comment start. (Just for the record, I got this right + the first time. This is not a bug fix.) */ + if (get_token (&new_token, &dest_tail) + && (new_token.text + new_token.len + == dest->text + original_dest_len)) + { + /* No splice, so we're done. */ + dest->last_token = original_dest_len + src->last_token; + return; + } + + /* Okay, a simple append caused a splice. Let's chop dest back to + its original length and try again, but separate the texts with a + space. */ + dest->len = original_dest_len; + appendc (dest, ' '); + appendmem (dest, src->text, src->len); + + init_shared_buffer (&dest_tail, + dest->text + dest->last_token, + dest->len - dest->last_token); + + /* Try to re-parse DEST's last token, as above. */ + if (get_token (&new_token, &dest_tail) + && (new_token.text + new_token.len + == dest->text + original_dest_len)) + { + /* No splice, so we're done. */ + dest->last_token = original_dest_len + 1 + src->last_token; + return; + } + + /* As far as I know, there's no case where inserting a space isn't + enough to prevent a splice. */ + internal_error (__FILE__, __LINE__, + "unable to avoid splicing tokens during macro expansion"); +} + + + +/* Expanding macros! */ + + +/* A singly-linked list of the names of the macros we are currently + expanding --- for detecting expansion loops. */ +struct macro_name_list { + const char *name; + struct macro_name_list *next; +}; + + +/* Return non-zero if we are currently expanding the macro named NAME, + according to LIST; otherwise, return zero. + + You know, it would be possible to get rid of all the NO_LOOP + arguments to these functions by simply generating a new lookup + function and baton which refuses to find the definition for a + particular macro, and otherwise delegates the decision to another + function/baton pair. But that makes the linked list of excluded + macros chained through untyped baton pointers, which will make it + harder to debug. :( */ +static int +currently_rescanning (struct macro_name_list *list, const char *name) +{ + for (; list; list = list->next) + if (strcmp (name, list->name) == 0) + return 1; + + return 0; +} + + +/* Gather the arguments to a macro expansion. + + NAME is the name of the macro being invoked. (It's only used for + printing error messages.) + + Assume that SRC is the text of the macro invocation immediately + following the macro name. For example, if we're processing the + text foo(bar, baz), then NAME would be foo and SRC will be (bar, + baz). + + If SRC doesn't start with an open paren ( token at all, return + zero, leave SRC unchanged, and don't set *ARGC_P to anything. + + If SRC doesn't contain a properly terminated argument list, then + raise an error. + + Otherwise, return a pointer to the first element of an array of + macro buffers referring to the argument texts, and set *ARGC_P to + the number of arguments we found --- the number of elements in the + array. The macro buffers share their text with SRC, and their + last_token fields are initialized. The array is allocated with + xmalloc, and the caller is responsible for freeing it. + + NOTE WELL: if SRC starts with a open paren ( token followed + immediately by a close paren ) token (e.g., the invocation looks + like "foo()"), we treat that as one argument, which happens to be + the empty list of tokens. The caller should keep in mind that such + a sequence of tokens is a valid way to invoke one-parameter + function-like macros, but also a valid way to invoke zero-parameter + function-like macros. Eeew. + + Consume the tokens from SRC; after this call, SRC contains the text + following the invocation. */ + +static struct macro_buffer * +gather_arguments (const char *name, struct macro_buffer *src, int *argc_p) +{ + struct macro_buffer tok; + int args_len, args_size; + struct macro_buffer *args = NULL; + struct cleanup *back_to = make_cleanup (free_current_contents, &args); + + /* Does SRC start with an opening paren token? Read from a copy of + SRC, so SRC itself is unaffected if we don't find an opening + paren. */ + { + struct macro_buffer temp; + init_shared_buffer (&temp, src->text, src->len); + + if (! get_token (&tok, &temp) + || tok.len != 1 + || tok.text[0] != '(') + { + discard_cleanups (back_to); + return 0; + } + } + + /* Consume SRC's opening paren. */ + get_token (&tok, src); + + args_len = 0; + args_size = 1; /* small for initial testing */ + args = (struct macro_buffer *) xmalloc (sizeof (*args) * args_size); + + for (;;) + { + struct macro_buffer *arg; + int depth; + + /* Make sure we have room for the next argument. */ + if (args_len >= args_size) + { + args_size *= 2; + args = xrealloc (args, sizeof (*args) * args_size); + } + + /* Initialize the next argument. */ + arg = &args[args_len++]; + set_token (arg, src->text, src->text); + + /* Gather the argument's tokens. */ + depth = 0; + for (;;) + { + char *start = src->text; + + if (! get_token (&tok, src)) + error ("Malformed argument list for macro `%s'.", name); + + /* Is tok an opening paren? */ + if (tok.len == 1 && tok.text[0] == '(') + depth++; + + /* Is tok is a closing paren? */ + else if (tok.len == 1 && tok.text[0] == ')') + { + /* If it's a closing paren at the top level, then that's + the end of the argument list. */ + if (depth == 0) + { + discard_cleanups (back_to); + *argc_p = args_len; + return args; + } + + depth--; + } + + /* If tok is a comma at top level, then that's the end of + the current argument. */ + else if (tok.len == 1 && tok.text[0] == ',' && depth == 0) + break; + + /* Extend the current argument to enclose this token. If + this is the current argument's first token, leave out any + leading whitespace, just for aesthetics. */ + if (arg->len == 0) + { + arg->text = tok.text; + arg->len = tok.len; + arg->last_token = 0; + } + else + { + arg->len = (tok.text + tok.len) - arg->text; + arg->last_token = tok.text - arg->text; + } + } + } +} + + +/* The `expand' and `substitute_args' functions both invoke `scan' + recursively, so we need a forward declaration somewhere. */ +static void scan (struct macro_buffer *dest, + struct macro_buffer *src, + struct macro_name_list *no_loop, + macro_lookup_ftype *lookup_func, + void *lookup_baton); + + +/* Given the macro definition DEF, being invoked with the actual + arguments given by ARGC and ARGV, substitute the arguments into the + replacement list, and store the result in DEST. + + If it is necessary to expand macro invocations in one of the + arguments, use LOOKUP_FUNC and LOOKUP_BATON to find the macro + definitions, and don't expand invocations of the macros listed in + NO_LOOP. */ +static void +substitute_args (struct macro_buffer *dest, + struct macro_definition *def, + int argc, struct macro_buffer *argv, + struct macro_name_list *no_loop, + macro_lookup_ftype *lookup_func, + void *lookup_baton) +{ + /* A macro buffer for the macro's replacement list. */ + struct macro_buffer replacement_list; + + init_shared_buffer (&replacement_list, (char *) def->replacement, + strlen (def->replacement)); + + gdb_assert (dest->len == 0); + dest->last_token = 0; + + for (;;) + { + struct macro_buffer tok; + char *original_rl_start = replacement_list.text; + int substituted = 0; + + /* Find the next token in the replacement list. */ + if (! get_token (&tok, &replacement_list)) + break; + + /* Just for aesthetics. If we skipped some whitespace, copy + that to DEST. */ + if (tok.text > original_rl_start) + { + appendmem (dest, original_rl_start, tok.text - original_rl_start); + dest->last_token = dest->len; + } + + /* Is this token the stringification operator? */ + if (tok.len == 1 + && tok.text[0] == '#') + error ("Stringification is not implemented yet."); + + /* Is this token the splicing operator? */ + if (tok.len == 2 + && tok.text[0] == '#' + && tok.text[1] == '#') + error ("Token splicing is not implemented yet."); + + /* Is this token an identifier? */ + if (tok.is_identifier) + { + int i; + + /* Is it the magic varargs parameter? */ + if (tok.len == 11 + && ! memcmp (tok.text, "__VA_ARGS__", 11)) + error ("Variable-arity macros not implemented yet."); + + /* Is it one of the parameters? */ + for (i = 0; i < def->argc; i++) + if (tok.len == strlen (def->argv[i]) + && ! memcmp (tok.text, def->argv[i], tok.len)) + { + struct macro_buffer arg_src; + + /* Expand any macro invocations in the argument text, + and append the result to dest. Remember that scan + mutates its source, so we need to scan a new buffer + referring to the argument's text, not the argument + itself. */ + init_shared_buffer (&arg_src, argv[i].text, argv[i].len); + scan (dest, &arg_src, no_loop, lookup_func, lookup_baton); + substituted = 1; + break; + } + } + + /* If it wasn't a parameter, then just copy it across. */ + if (! substituted) + append_tokens_without_splicing (dest, &tok); + } +} + + +/* Expand a call to a macro named ID, whose definition is DEF. Append + its expansion to DEST. SRC is the input text following the ID + token. We are currently rescanning the expansions of the macros + named in NO_LOOP; don't re-expand them. Use LOOKUP_FUNC and + LOOKUP_BATON to find definitions for any nested macro references. + + Return 1 if we decided to expand it, zero otherwise. (If it's a + function-like macro name that isn't followed by an argument list, + we don't expand it.) If we return zero, leave SRC unchanged. */ +static int +expand (const char *id, + struct macro_definition *def, + struct macro_buffer *dest, + struct macro_buffer *src, + struct macro_name_list *no_loop, + macro_lookup_ftype *lookup_func, + void *lookup_baton) +{ + struct macro_name_list new_no_loop; + + /* Create a new node to be added to the front of the no-expand list. + This list is appropriate for re-scanning replacement lists, but + it is *not* appropriate for scanning macro arguments; invocations + of the macro whose arguments we are gathering *do* get expanded + there. */ + new_no_loop.name = id; + new_no_loop.next = no_loop; + + /* What kind of macro are we expanding? */ + if (def->kind == macro_object_like) + { + struct macro_buffer replacement_list; + + init_shared_buffer (&replacement_list, (char *) def->replacement, + strlen (def->replacement)); + + scan (dest, &replacement_list, &new_no_loop, lookup_func, lookup_baton); + return 1; + } + else if (def->kind == macro_function_like) + { + struct cleanup *back_to = make_cleanup (null_cleanup, 0); + int argc; + struct macro_buffer *argv = NULL; + struct macro_buffer substituted; + struct macro_buffer substituted_src; + + if (def->argc >= 1 + && strcmp (def->argv[def->argc - 1], "...") == 0) + error ("Varargs macros not implemented yet."); + + make_cleanup (free_current_contents, &argv); + argv = gather_arguments (id, src, &argc); + + /* If we couldn't find any argument list, then we don't expand + this macro. */ + if (! argv) + { + do_cleanups (back_to); + return 0; + } + + /* Check that we're passing an acceptable number of arguments for + this macro. */ + if (argc != def->argc) + { + /* Remember that a sequence of tokens like "foo()" is a + valid invocation of a macro expecting either zero or one + arguments. */ + if (! (argc == 1 + && argv[0].len == 0 + && def->argc == 0)) + error ("Wrong number of arguments to macro `%s' " + "(expected %d, got %d).", + id, def->argc, argc); + } + + /* Note that we don't expand macro invocations in the arguments + yet --- we let subst_args take care of that. Parameters that + appear as operands of the stringifying operator "#" or the + splicing operator "##" don't get macro references expanded, + so we can't really tell whether it's appropriate to macro- + expand an argument until we see how it's being used. */ + init_buffer (&substituted, 0); + make_cleanup (cleanup_macro_buffer, &substituted); + substitute_args (&substituted, def, argc, argv, no_loop, + lookup_func, lookup_baton); + + /* Now `substituted' is the macro's replacement list, with all + argument values substituted into it properly. Re-scan it for + macro references, but don't expand invocations of this macro. + + We create a new buffer, `substituted_src', which points into + `substituted', and scan that. We can't scan `substituted' + itself, since the tokenization process moves the buffer's + text pointer around, and we still need to be able to find + `substituted's original text buffer after scanning it so we + can free it. */ + init_shared_buffer (&substituted_src, substituted.text, substituted.len); + scan (dest, &substituted_src, &new_no_loop, lookup_func, lookup_baton); + + do_cleanups (back_to); + + return 1; + } + else + internal_error (__FILE__, __LINE__, "bad macro definition kind"); +} + + +/* If the single token in SRC_FIRST followed by the tokens in SRC_REST + constitute a macro invokation not forbidden in NO_LOOP, append its + expansion to DEST and return non-zero. Otherwise, return zero, and + leave DEST unchanged. + + SRC_FIRST and SRC_REST must be shared buffers; DEST must not be one. + SRC_FIRST must be a string built by get_token. */ +static int +maybe_expand (struct macro_buffer *dest, + struct macro_buffer *src_first, + struct macro_buffer *src_rest, + struct macro_name_list *no_loop, + macro_lookup_ftype *lookup_func, + void *lookup_baton) +{ + gdb_assert (src_first->shared); + gdb_assert (src_rest->shared); + gdb_assert (! dest->shared); + + /* Is this token an identifier? */ + if (src_first->is_identifier) + { + /* Make a null-terminated copy of it, since that's what our + lookup function expects. */ + char *id = xmalloc (src_first->len + 1); + struct cleanup *back_to = make_cleanup (xfree, id); + memcpy (id, src_first->text, src_first->len); + id[src_first->len] = 0; + + /* If we're currently re-scanning the result of expanding + this macro, don't expand it again. */ + if (! currently_rescanning (no_loop, id)) + { + /* Does this identifier have a macro definition in scope? */ + struct macro_definition *def = lookup_func (id, lookup_baton); + + if (def && expand (id, def, dest, src_rest, no_loop, + lookup_func, lookup_baton)) + { + do_cleanups (back_to); + return 1; + } + } + + do_cleanups (back_to); + } + + return 0; +} + + +/* Expand macro references in SRC, appending the results to DEST. + Assume we are re-scanning the result of expanding the macros named + in NO_LOOP, and don't try to re-expand references to them. + + SRC must be a shared buffer; DEST must not be one. */ +static void +scan (struct macro_buffer *dest, + struct macro_buffer *src, + struct macro_name_list *no_loop, + macro_lookup_ftype *lookup_func, + void *lookup_baton) +{ + gdb_assert (src->shared); + gdb_assert (! dest->shared); + + for (;;) + { + struct macro_buffer tok; + char *original_src_start = src->text; + + /* Find the next token in SRC. */ + if (! get_token (&tok, src)) + break; + + /* Just for aesthetics. If we skipped some whitespace, copy + that to DEST. */ + if (tok.text > original_src_start) + { + appendmem (dest, original_src_start, tok.text - original_src_start); + dest->last_token = dest->len; + } + + if (! maybe_expand (dest, &tok, src, no_loop, lookup_func, lookup_baton)) + /* We didn't end up expanding tok as a macro reference, so + simply append it to dest. */ + append_tokens_without_splicing (dest, &tok); + } + + /* Just for aesthetics. If there was any trailing whitespace in + src, copy it to dest. */ + if (src->len) + { + appendmem (dest, src->text, src->len); + dest->last_token = dest->len; + } +} + + +char * +macro_expand (const char *source, + macro_lookup_ftype *lookup_func, + void *lookup_func_baton) +{ + struct macro_buffer src, dest; + struct cleanup *back_to; + + init_shared_buffer (&src, (char *) source, strlen (source)); + + init_buffer (&dest, 0); + dest.last_token = 0; + back_to = make_cleanup (cleanup_macro_buffer, &dest); + + scan (&dest, &src, 0, lookup_func, lookup_func_baton); + + appendc (&dest, '\0'); + + discard_cleanups (back_to); + return dest.text; +} + + +char * +macro_expand_once (const char *source, + macro_lookup_ftype *lookup_func, + void *lookup_func_baton) +{ + error ("Expand-once not implemented yet."); +} + + +char * +macro_expand_next (char **lexptr, + macro_lookup_ftype *lookup_func, + void *lookup_baton) +{ + struct macro_buffer src, dest, tok; + struct cleanup *back_to; + + /* Set up SRC to refer to the input text, pointed to by *lexptr. */ + init_shared_buffer (&src, *lexptr, strlen (*lexptr)); + + /* Set up DEST to receive the expansion, if there is one. */ + init_buffer (&dest, 0); + dest.last_token = 0; + back_to = make_cleanup (cleanup_macro_buffer, &dest); + + /* Get the text's first preprocessing token. */ + if (! get_token (&tok, &src)) + { + do_cleanups (back_to); + return 0; + } + + /* If it's a macro invocation, expand it. */ + if (maybe_expand (&dest, &tok, &src, 0, lookup_func, lookup_baton)) + { + /* It was a macro invocation! Package up the expansion as a + null-terminated string and return it. Set *lexptr to the + start of the next token in the input. */ + appendc (&dest, '\0'); + discard_cleanups (back_to); + *lexptr = src.text; + return dest.text; + } + else + { + /* It wasn't a macro invocation. */ + do_cleanups (back_to); + return 0; + } +} diff --git a/contrib/gdb/gdb/macroexp.h b/contrib/gdb/gdb/macroexp.h new file mode 100644 index 00000000000..57269fa22f8 --- /dev/null +++ b/contrib/gdb/gdb/macroexp.h @@ -0,0 +1,90 @@ +/* Interface to C preprocessor macro expansion for GDB. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#ifndef MACROEXP_H +#define MACROEXP_H + +/* A function for looking up preprocessor macro definitions. Return + the preprocessor definition of NAME in scope according to BATON, or + zero if NAME is not defined as a preprocessor macro. + + The caller must not free or modify the definition returned. It is + probably unwise for the caller to hold pointers to it for very + long; it probably lives in some objfile's obstacks. */ +typedef struct macro_definition *(macro_lookup_ftype) (const char *name, + void *baton); + + +/* Expand any preprocessor macros in SOURCE, and return the expanded + text. Use LOOKUP_FUNC and LOOKUP_FUNC_BATON to find identifiers' + preprocessor definitions. SOURCE is a null-terminated string. The + result is a null-terminated string, allocated using xmalloc; it is + the caller's responsibility to free it. */ +char *macro_expand (const char *source, + macro_lookup_ftype *lookup_func, + void *lookup_func_baton); + + +/* Expand all preprocessor macro references that appear explicitly in + SOURCE, but do not expand any new macro references introduced by + that first level of expansion. Use LOOKUP_FUNC and + LOOKUP_FUNC_BATON to find identifiers' preprocessor definitions. + SOURCE is a null-terminated string. The result is a + null-terminated string, allocated using xmalloc; it is the caller's + responsibility to free it. */ +char *macro_expand_once (const char *source, + macro_lookup_ftype *lookup_func, + void *lookup_func_baton); + + +/* If the null-terminated string pointed to by *LEXPTR begins with a + macro invocation, return the result of expanding that invocation as + a null-terminated string, and set *LEXPTR to the next character + after the invocation. The result is completely expanded; it + contains no further macro invocations. + + Otherwise, if *LEXPTR does not start with a macro invocation, + return zero, and leave *LEXPTR unchanged. + + Use LOOKUP_FUNC and LOOKUP_BATON to find macro definitions. + + If this function returns a string, the caller is responsible for + freeing it, using xfree. + + We need this expand-one-token-at-a-time interface in order to + accomodate GDB's C expression parser, which may not consume the + entire string. When the user enters a command like + + (gdb) break *func+20 if x == 5 + + the parser is expected to consume `func+20', and then stop when it + sees the "if". But of course, "if" appearing in a character string + or as part of a larger identifier doesn't count. So you pretty + much have to do tokenization to find the end of the string that + needs to be macro-expanded. Our C/C++ tokenizer isn't really + designed to be called by anything but the yacc parser engine. */ +char *macro_expand_next (char **lexptr, + macro_lookup_ftype *lookup_func, + void *lookup_baton); + + +#endif /* MACROEXP_H */ diff --git a/contrib/gdb/gdb/macroscope.c b/contrib/gdb/gdb/macroscope.c new file mode 100644 index 00000000000..19557d7dc08 --- /dev/null +++ b/contrib/gdb/gdb/macroscope.c @@ -0,0 +1,132 @@ +/* Functions for deciding which macros are currently in scope. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "macroscope.h" +#include "symtab.h" +#include "source.h" +#include "target.h" +#include "frame.h" +#include "inferior.h" +#include "complaints.h" + + +struct macro_scope * +sal_macro_scope (struct symtab_and_line sal) +{ + struct macro_source_file *main, *inclusion; + struct macro_scope *ms; + + if (! sal.symtab + || ! sal.symtab->macro_table) + return 0; + + ms = (struct macro_scope *) xmalloc (sizeof (*ms)); + + main = macro_main (sal.symtab->macro_table); + inclusion = macro_lookup_inclusion (main, sal.symtab->filename); + + if (inclusion) + { + ms->file = inclusion; + ms->line = sal.line; + } + else + { + /* There are, unfortunately, cases where a compilation unit can + have a symtab for a source file that doesn't appear in the + macro table. For example, at the moment, Dwarf doesn't have + any way in the .debug_macinfo section to describe the effect + of #line directives, so if you debug a YACC parser you'll get + a macro table which only mentions the .c files generated by + YACC, but symtabs that mention the .y files consumed by YACC. + + In the long run, we should extend the Dwarf macro info + representation to handle #line directives, and get GCC to + emit it. + + For the time being, though, we'll just treat these as + occurring at the end of the main source file. */ + ms->file = main; + ms->line = -1; + + complaint (&symfile_complaints, + "symtab found for `%s', but that file\n" + "is not covered in the compilation unit's macro information", + sal.symtab->filename); + } + + return ms; +} + + +struct macro_scope * +default_macro_scope (void) +{ + struct symtab_and_line sal; + struct macro_source_file *main; + struct macro_scope *ms; + + /* If there's a selected frame, use its PC. */ + if (deprecated_selected_frame) + sal = find_pc_line (get_frame_pc (deprecated_selected_frame), 0); + + /* If the target has any registers at all, then use its PC. Why we + would have registers but no stack, I'm not sure. */ + else if (target_has_registers) + sal = find_pc_line (read_pc (), 0); + + /* If all else fails, fall back to the current listing position. */ + else + { + /* Don't call select_source_symtab here. That can raise an + error if symbols aren't loaded, but GDB calls the expression + evaluator in all sorts of contexts. + + For example, commands like `set width' call the expression + evaluator to evaluate their numeric arguments. If the + current language is C, then that may call this function to + choose a scope for macro expansion. If you don't have any + symbol files loaded, then get_current_or_default would raise an + error. But `set width' shouldn't raise an error just because + it can't decide which scope to macro-expand its argument in. */ + struct symtab_and_line cursal = + get_current_source_symtab_and_line (); + + sal.symtab = cursal.symtab; + sal.line = cursal.line; + } + + return sal_macro_scope (sal); +} + + +/* Look up the definition of the macro named NAME in scope at the source + location given by BATON, which must be a pointer to a `struct + macro_scope' structure. */ +struct macro_definition * +standard_macro_lookup (const char *name, void *baton) +{ + struct macro_scope *ms = (struct macro_scope *) baton; + + return macro_lookup_definition (ms->file, ms->line, name); +} diff --git a/contrib/gdb/gdb/macroscope.h b/contrib/gdb/gdb/macroscope.h new file mode 100644 index 00000000000..fc10b6dcd60 --- /dev/null +++ b/contrib/gdb/gdb/macroscope.h @@ -0,0 +1,63 @@ +/* Interface to functions for deciding which macros are currently in scope. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MACROSCOPE_H +#define MACROSCOPE_H + +#include "macrotab.h" +#include "symtab.h" + + +/* All the information we need to decide which macro definitions are + in scope: a source file (either a main source file or an + #inclusion), and a line number in that file. */ +struct macro_scope { + struct macro_source_file *file; + int line; +}; + + +/* Return a `struct macro_scope' object corresponding to the symtab + and line given in SAL. If we have no macro information for that + location, or if SAL's pc is zero, return zero. */ +struct macro_scope *sal_macro_scope (struct symtab_and_line sal); + + +/* Return a `struct macro_scope' object describing the scope the `macro + expand' and `macro expand-once' commands should use for looking up + macros. If we have a selected frame, this is the source location of + its PC; otherwise, this is the last listing position. + + If we have no macro information for the current location, return zero. + + The object returned is allocated using xmalloc; the caller is + responsible for freeing it. */ +struct macro_scope *default_macro_scope (void); + + +/* Look up the definition of the macro named NAME in scope at the source + location given by BATON, which must be a pointer to a `struct + macro_scope' structure. This function is suitable for use as + a macro_lookup_ftype function. */ +struct macro_definition *standard_macro_lookup (const char *name, void *baton); + + +#endif /* MACROSCOPE_H */ diff --git a/contrib/gdb/gdb/macrotab.c b/contrib/gdb/gdb/macrotab.c new file mode 100644 index 00000000000..56ee2a4c284 --- /dev/null +++ b/contrib/gdb/gdb/macrotab.c @@ -0,0 +1,892 @@ +/* C preprocessor macro tables for GDB. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_obstack.h" +#include "splay-tree.h" +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" +#include "macrotab.h" +#include "gdb_assert.h" +#include "bcache.h" +#include "complaints.h" + + +/* The macro table structure. */ + +struct macro_table +{ + /* The obstack this table's data should be allocated in, or zero if + we should use xmalloc. */ + struct obstack *obstack; + + /* The bcache we should use to hold macro names, argument names, and + definitions, or zero if we should use xmalloc. */ + struct bcache *bcache; + + /* The main source file for this compilation unit --- the one whose + name was given to the compiler. This is the root of the + #inclusion tree; everything else is #included from here. */ + struct macro_source_file *main_source; + + /* The table of macro definitions. This is a splay tree (an ordered + binary tree that stays balanced, effectively), sorted by macro + name. Where a macro gets defined more than once (presumably with + an #undefinition in between), we sort the definitions by the + order they would appear in the preprocessor's output. That is, + if `a.c' #includes `m.h' and then #includes `n.h', and both + header files #define X (with an #undef somewhere in between), + then the definition from `m.h' appears in our splay tree before + the one from `n.h'. + + The splay tree's keys are `struct macro_key' pointers; + the values are `struct macro_definition' pointers. + + The splay tree, its nodes, and the keys and values are allocated + in obstack, if it's non-zero, or with xmalloc otherwise. The + macro names, argument names, argument name arrays, and definition + strings are all allocated in bcache, if non-zero, or with xmalloc + otherwise. */ + splay_tree definitions; +}; + + + +/* Allocation and freeing functions. */ + +/* Allocate SIZE bytes of memory appropriately for the macro table T. + This just checks whether T has an obstack, or whether its pieces + should be allocated with xmalloc. */ +static void * +macro_alloc (int size, struct macro_table *t) +{ + if (t->obstack) + return obstack_alloc (t->obstack, size); + else + return xmalloc (size); +} + + +static void +macro_free (void *object, struct macro_table *t) +{ + gdb_assert (! t->obstack); + xfree (object); +} + + +/* If the macro table T has a bcache, then cache the LEN bytes at ADDR + there, and return the cached copy. Otherwise, just xmalloc a copy + of the bytes, and return a pointer to that. */ +static const void * +macro_bcache (struct macro_table *t, const void *addr, int len) +{ + if (t->bcache) + return bcache (addr, len, t->bcache); + else + { + void *copy = xmalloc (len); + memcpy (copy, addr, len); + return copy; + } +} + + +/* If the macro table T has a bcache, cache the null-terminated string + S there, and return a pointer to the cached copy. Otherwise, + xmalloc a copy and return that. */ +static const char * +macro_bcache_str (struct macro_table *t, const char *s) +{ + return (char *) macro_bcache (t, s, strlen (s) + 1); +} + + +/* Free a possibly bcached object OBJ. That is, if the macro table T + has a bcache, it's an error; otherwise, xfree OBJ. */ +static void +macro_bcache_free (struct macro_table *t, void *obj) +{ + gdb_assert (! t->bcache); + xfree (obj); +} + + + +/* Macro tree keys, w/their comparison, allocation, and freeing functions. */ + +/* A key in the splay tree. */ +struct macro_key +{ + /* The table we're in. We only need this in order to free it, since + the splay tree library's key and value freeing functions require + that the key or value contain all the information needed to free + themselves. */ + struct macro_table *table; + + /* The name of the macro. This is in the table's bcache, if it has + one. */ + const char *name; + + /* The source file and line number where the definition's scope + begins. This is also the line of the definition itself. */ + struct macro_source_file *start_file; + int start_line; + + /* The first source file and line after the definition's scope. + (That is, the scope does not include this endpoint.) If end_file + is zero, then the definition extends to the end of the + compilation unit. */ + struct macro_source_file *end_file; + int end_line; +}; + + +/* Return the #inclusion depth of the source file FILE. This is the + number of #inclusions it took to reach this file. For the main + source file, the #inclusion depth is zero; for a file it #includes + directly, the depth would be one; and so on. */ +static int +inclusion_depth (struct macro_source_file *file) +{ + int depth; + + for (depth = 0; file->included_by; depth++) + file = file->included_by; + + return depth; +} + + +/* Compare two source locations (from the same compilation unit). + This is part of the comparison function for the tree of + definitions. + + LINE1 and LINE2 are line numbers in the source files FILE1 and + FILE2. Return a value: + - less than zero if {LINE,FILE}1 comes before {LINE,FILE}2, + - greater than zero if {LINE,FILE}1 comes after {LINE,FILE}2, or + - zero if they are equal. + + When the two locations are in different source files --- perhaps + one is in a header, while another is in the main source file --- we + order them by where they would appear in the fully pre-processed + sources, where all the #included files have been substituted into + their places. */ +static int +compare_locations (struct macro_source_file *file1, int line1, + struct macro_source_file *file2, int line2) +{ + /* We want to treat positions in an #included file as coming *after* + the line containing the #include, but *before* the line after the + include. As we walk up the #inclusion tree toward the main + source file, we update fileX and lineX as we go; includedX + indicates whether the original position was from the #included + file. */ + int included1 = 0; + int included2 = 0; + + /* If a file is zero, that means "end of compilation unit." Handle + that specially. */ + if (! file1) + { + if (! file2) + return 0; + else + return 1; + } + else if (! file2) + return -1; + + /* If the two files are not the same, find their common ancestor in + the #inclusion tree. */ + if (file1 != file2) + { + /* If one file is deeper than the other, walk up the #inclusion + chain until the two files are at least at the same *depth*. + Then, walk up both files in synchrony until they're the same + file. That file is the common ancestor. */ + int depth1 = inclusion_depth (file1); + int depth2 = inclusion_depth (file2); + + /* Only one of these while loops will ever execute in any given + case. */ + while (depth1 > depth2) + { + line1 = file1->included_at_line; + file1 = file1->included_by; + included1 = 1; + depth1--; + } + while (depth2 > depth1) + { + line2 = file2->included_at_line; + file2 = file2->included_by; + included2 = 1; + depth2--; + } + + /* Now both file1 and file2 are at the same depth. Walk toward + the root of the tree until we find where the branches meet. */ + while (file1 != file2) + { + line1 = file1->included_at_line; + file1 = file1->included_by; + /* At this point, we know that the case the includedX flags + are trying to deal with won't come up, but we'll just + maintain them anyway. */ + included1 = 1; + + line2 = file2->included_at_line; + file2 = file2->included_by; + included2 = 1; + + /* Sanity check. If file1 and file2 are really from the + same compilation unit, then they should both be part of + the same tree, and this shouldn't happen. */ + gdb_assert (file1 && file2); + } + } + + /* Now we've got two line numbers in the same file. */ + if (line1 == line2) + { + /* They can't both be from #included files. Then we shouldn't + have walked up this far. */ + gdb_assert (! included1 || ! included2); + + /* Any #included position comes after a non-#included position + with the same line number in the #including file. */ + if (included1) + return 1; + else if (included2) + return -1; + else + return 0; + } + else + return line1 - line2; +} + + +/* Compare a macro key KEY against NAME, the source file FILE, and + line number LINE. + + Sort definitions by name; for two definitions with the same name, + place the one whose definition comes earlier before the one whose + definition comes later. + + Return -1, 0, or 1 if key comes before, is identical to, or comes + after NAME, FILE, and LINE. */ +static int +key_compare (struct macro_key *key, + const char *name, struct macro_source_file *file, int line) +{ + int names = strcmp (key->name, name); + if (names) + return names; + + return compare_locations (key->start_file, key->start_line, + file, line); +} + + +/* The macro tree comparison function, typed for the splay tree + library's happiness. */ +static int +macro_tree_compare (splay_tree_key untyped_key1, + splay_tree_key untyped_key2) +{ + struct macro_key *key1 = (struct macro_key *) untyped_key1; + struct macro_key *key2 = (struct macro_key *) untyped_key2; + + return key_compare (key1, key2->name, key2->start_file, key2->start_line); +} + + +/* Construct a new macro key node for a macro in table T whose name is + NAME, and whose scope starts at LINE in FILE; register the name in + the bcache. */ +static struct macro_key * +new_macro_key (struct macro_table *t, + const char *name, + struct macro_source_file *file, + int line) +{ + struct macro_key *k = macro_alloc (sizeof (*k), t); + + memset (k, 0, sizeof (*k)); + k->table = t; + k->name = macro_bcache_str (t, name); + k->start_file = file; + k->start_line = line; + k->end_file = 0; + + return k; +} + + +static void +macro_tree_delete_key (void *untyped_key) +{ + struct macro_key *key = (struct macro_key *) untyped_key; + + macro_bcache_free (key->table, (char *) key->name); + macro_free (key, key->table); +} + + + +/* Building and querying the tree of #included files. */ + + +/* Allocate and initialize a new source file structure. */ +static struct macro_source_file * +new_source_file (struct macro_table *t, + const char *filename) +{ + /* Get space for the source file structure itself. */ + struct macro_source_file *f = macro_alloc (sizeof (*f), t); + + memset (f, 0, sizeof (*f)); + f->table = t; + f->filename = macro_bcache_str (t, filename); + f->includes = 0; + + return f; +} + + +/* Free a source file, and all the source files it #included. */ +static void +free_macro_source_file (struct macro_source_file *src) +{ + struct macro_source_file *child, *next_child; + + /* Free this file's children. */ + for (child = src->includes; child; child = next_child) + { + next_child = child->next_included; + free_macro_source_file (child); + } + + macro_bcache_free (src->table, (char *) src->filename); + macro_free (src, src->table); +} + + +struct macro_source_file * +macro_set_main (struct macro_table *t, + const char *filename) +{ + /* You can't change a table's main source file. What would that do + to the tree? */ + gdb_assert (! t->main_source); + + t->main_source = new_source_file (t, filename); + + return t->main_source; +} + + +struct macro_source_file * +macro_main (struct macro_table *t) +{ + gdb_assert (t->main_source); + + return t->main_source; +} + + +struct macro_source_file * +macro_include (struct macro_source_file *source, + int line, + const char *included) +{ + struct macro_source_file *new; + struct macro_source_file **link; + + /* Find the right position in SOURCE's `includes' list for the new + file. Skip inclusions at earlier lines, until we find one at the + same line or later --- or until the end of the list. */ + for (link = &source->includes; + *link && (*link)->included_at_line < line; + link = &(*link)->next_included) + ; + + /* Did we find another file already #included at the same line as + the new one? */ + if (*link && line == (*link)->included_at_line) + { + /* This means the compiler is emitting bogus debug info. (GCC + circa March 2002 did this.) It also means that the splay + tree ordering function, macro_tree_compare, will abort, + because it can't tell which #inclusion came first. But GDB + should tolerate bad debug info. So: + + First, squawk. */ + complaint (&symfile_complaints, + "both `%s' and `%s' allegedly #included at %s:%d", included, + (*link)->filename, source->filename, line); + + /* Now, choose a new, unoccupied line number for this + #inclusion, after the alleged #inclusion line. */ + while (*link && line == (*link)->included_at_line) + { + /* This line number is taken, so try the next line. */ + line++; + link = &(*link)->next_included; + } + } + + /* At this point, we know that LINE is an unused line number, and + *LINK points to the entry an #inclusion at that line should + precede. */ + new = new_source_file (source->table, included); + new->included_by = source; + new->included_at_line = line; + new->next_included = *link; + *link = new; + + return new; +} + + +struct macro_source_file * +macro_lookup_inclusion (struct macro_source_file *source, const char *name) +{ + /* Is SOURCE itself named NAME? */ + if (strcmp (name, source->filename) == 0) + return source; + + /* The filename in the source structure is probably a full path, but + NAME could be just the final component of the name. */ + { + int name_len = strlen (name); + int src_name_len = strlen (source->filename); + + /* We do mean < here, and not <=; if the lengths are the same, + then the strcmp above should have triggered, and we need to + check for a slash here. */ + if (name_len < src_name_len + && source->filename[src_name_len - name_len - 1] == '/' + && strcmp (name, source->filename + src_name_len - name_len) == 0) + return source; + } + + /* It's not us. Try all our children, and return the lowest. */ + { + struct macro_source_file *child; + struct macro_source_file *best = NULL; + int best_depth = 0; + + for (child = source->includes; child; child = child->next_included) + { + struct macro_source_file *result + = macro_lookup_inclusion (child, name); + + if (result) + { + int result_depth = inclusion_depth (result); + + if (! best || result_depth < best_depth) + { + best = result; + best_depth = result_depth; + } + } + } + + return best; + } +} + + + +/* Registering and looking up macro definitions. */ + + +/* Construct a definition for a macro in table T. Cache all strings, + and the macro_definition structure itself, in T's bcache. */ +static struct macro_definition * +new_macro_definition (struct macro_table *t, + enum macro_kind kind, + int argc, const char **argv, + const char *replacement) +{ + struct macro_definition *d = macro_alloc (sizeof (*d), t); + + memset (d, 0, sizeof (*d)); + d->table = t; + d->kind = kind; + d->replacement = macro_bcache_str (t, replacement); + + if (kind == macro_function_like) + { + int i; + const char **cached_argv; + int cached_argv_size = argc * sizeof (*cached_argv); + + /* Bcache all the arguments. */ + cached_argv = alloca (cached_argv_size); + for (i = 0; i < argc; i++) + cached_argv[i] = macro_bcache_str (t, argv[i]); + + /* Now bcache the array of argument pointers itself. */ + d->argv = macro_bcache (t, cached_argv, cached_argv_size); + d->argc = argc; + } + + /* We don't bcache the entire definition structure because it's got + a pointer to the macro table in it; since each compilation unit + has its own macro table, you'd only get bcache hits for identical + definitions within a compilation unit, which seems unlikely. + + "So, why do macro definitions have pointers to their macro tables + at all?" Well, when the splay tree library wants to free a + node's value, it calls the value freeing function with nothing + but the value itself. It makes the (apparently reasonable) + assumption that the value carries enough information to free + itself. But not all macro tables have bcaches, so not all macro + definitions would be bcached. There's no way to tell whether a + given definition is bcached without knowing which table the + definition belongs to. ... blah. The thing's only sixteen + bytes anyway, and we can still bcache the name, args, and + definition, so we just don't bother bcaching the definition + structure itself. */ + return d; +} + + +/* Free a macro definition. */ +static void +macro_tree_delete_value (void *untyped_definition) +{ + struct macro_definition *d = (struct macro_definition *) untyped_definition; + struct macro_table *t = d->table; + + if (d->kind == macro_function_like) + { + int i; + + for (i = 0; i < d->argc; i++) + macro_bcache_free (t, (char *) d->argv[i]); + macro_bcache_free (t, (char **) d->argv); + } + + macro_bcache_free (t, (char *) d->replacement); + macro_free (d, t); +} + + +/* Find the splay tree node for the definition of NAME at LINE in + SOURCE, or zero if there is none. */ +static splay_tree_node +find_definition (const char *name, + struct macro_source_file *file, + int line) +{ + struct macro_table *t = file->table; + splay_tree_node n; + + /* Construct a macro_key object, just for the query. */ + struct macro_key query; + + query.name = name; + query.start_file = file; + query.start_line = line; + query.end_file = NULL; + + n = splay_tree_lookup (t->definitions, (splay_tree_key) &query); + if (! n) + { + /* It's okay for us to do two queries like this: the real work + of the searching is done when we splay, and splaying the tree + a second time at the same key is a constant time operation. + If this still bugs you, you could always just extend the + splay tree library with a predecessor-or-equal operation, and + use that. */ + splay_tree_node pred = splay_tree_predecessor (t->definitions, + (splay_tree_key) &query); + + if (pred) + { + /* Make sure this predecessor actually has the right name. + We just want to search within a given name's definitions. */ + struct macro_key *found = (struct macro_key *) pred->key; + + if (strcmp (found->name, name) == 0) + n = pred; + } + } + + if (n) + { + struct macro_key *found = (struct macro_key *) n->key; + + /* Okay, so this definition has the right name, and its scope + begins before the given source location. But does its scope + end after the given source location? */ + if (compare_locations (file, line, found->end_file, found->end_line) < 0) + return n; + else + return 0; + } + else + return 0; +} + + +/* If NAME already has a definition in scope at LINE in SOURCE, return + the key. If the old definition is different from the definition + given by KIND, ARGC, ARGV, and REPLACEMENT, complain, too. + Otherwise, return zero. (ARGC and ARGV are meaningless unless KIND + is `macro_function_like'.) */ +static struct macro_key * +check_for_redefinition (struct macro_source_file *source, int line, + const char *name, enum macro_kind kind, + int argc, const char **argv, + const char *replacement) +{ + splay_tree_node n = find_definition (name, source, line); + + if (n) + { + struct macro_key *found_key = (struct macro_key *) n->key; + struct macro_definition *found_def + = (struct macro_definition *) n->value; + int same = 1; + + /* Is this definition the same as the existing one? + According to the standard, this comparison needs to be done + on lists of tokens, not byte-by-byte, as we do here. But + that's too hard for us at the moment, and comparing + byte-by-byte will only yield false negatives (i.e., extra + warning messages), not false positives (i.e., unnoticed + definition changes). */ + if (kind != found_def->kind) + same = 0; + else if (strcmp (replacement, found_def->replacement)) + same = 0; + else if (kind == macro_function_like) + { + if (argc != found_def->argc) + same = 0; + else + { + int i; + + for (i = 0; i < argc; i++) + if (strcmp (argv[i], found_def->argv[i])) + same = 0; + } + } + + if (! same) + { + complaint (&symfile_complaints, + "macro `%s' redefined at %s:%d; original definition at %s:%d", + name, source->filename, line, + found_key->start_file->filename, found_key->start_line); + } + + return found_key; + } + else + return 0; +} + + +void +macro_define_object (struct macro_source_file *source, int line, + const char *name, const char *replacement) +{ + struct macro_table *t = source->table; + struct macro_key *k; + struct macro_definition *d; + + k = check_for_redefinition (source, line, + name, macro_object_like, + 0, 0, + replacement); + + /* If we're redefining a symbol, and the existing key would be + identical to our new key, then the splay_tree_insert function + will try to delete the old definition. When the definition is + living on an obstack, this isn't a happy thing. + + Since this only happens in the presence of questionable debug + info, we just ignore all definitions after the first. The only + case I know of where this arises is in GCC's output for + predefined macros, and all the definitions are the same in that + case. */ + if (k && ! key_compare (k, name, source, line)) + return; + + k = new_macro_key (t, name, source, line); + d = new_macro_definition (t, macro_object_like, 0, 0, replacement); + splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d); +} + + +void +macro_define_function (struct macro_source_file *source, int line, + const char *name, int argc, const char **argv, + const char *replacement) +{ + struct macro_table *t = source->table; + struct macro_key *k; + struct macro_definition *d; + + k = check_for_redefinition (source, line, + name, macro_function_like, + argc, argv, + replacement); + + /* See comments about duplicate keys in macro_define_object. */ + if (k && ! key_compare (k, name, source, line)) + return; + + /* We should also check here that all the argument names in ARGV are + distinct. */ + + k = new_macro_key (t, name, source, line); + d = new_macro_definition (t, macro_function_like, argc, argv, replacement); + splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d); +} + + +void +macro_undef (struct macro_source_file *source, int line, + const char *name) +{ + splay_tree_node n = find_definition (name, source, line); + + if (n) + { + /* This function is the only place a macro's end-of-scope + location gets set to anything other than "end of the + compilation unit" (i.e., end_file is zero). So if this macro + already has its end-of-scope set, then we're probably seeing + a second #undefinition for the same #definition. */ + struct macro_key *key = (struct macro_key *) n->key; + + if (key->end_file) + { + complaint (&symfile_complaints, + "macro '%s' is #undefined twice, at %s:%d and %s:%d", name, + source->filename, line, key->end_file->filename, + key->end_line); + } + + /* Whatever the case, wipe out the old ending point, and + make this the ending point. */ + key->end_file = source; + key->end_line = line; + } + else + { + /* According to the ISO C standard, an #undef for a symbol that + has no macro definition in scope is ignored. So we should + ignore it too. */ +#if 0 + complaint (&symfile_complaints, + "no definition for macro `%s' in scope to #undef at %s:%d", + name, source->filename, line); +#endif + } +} + + +struct macro_definition * +macro_lookup_definition (struct macro_source_file *source, + int line, const char *name) +{ + splay_tree_node n = find_definition (name, source, line); + + if (n) + return (struct macro_definition *) n->value; + else + return 0; +} + + +struct macro_source_file * +macro_definition_location (struct macro_source_file *source, + int line, + const char *name, + int *definition_line) +{ + splay_tree_node n = find_definition (name, source, line); + + if (n) + { + struct macro_key *key = (struct macro_key *) n->key; + *definition_line = key->start_line; + return key->start_file; + } + else + return 0; +} + + + +/* Creating and freeing macro tables. */ + + +struct macro_table * +new_macro_table (struct obstack *obstack, + struct bcache *b) +{ + struct macro_table *t; + + /* First, get storage for the `struct macro_table' itself. */ + if (obstack) + t = obstack_alloc (obstack, sizeof (*t)); + else + t = xmalloc (sizeof (*t)); + + memset (t, 0, sizeof (*t)); + t->obstack = obstack; + t->bcache = b; + t->main_source = NULL; + t->definitions = (splay_tree_new_with_allocator + (macro_tree_compare, + ((splay_tree_delete_key_fn) macro_tree_delete_key), + ((splay_tree_delete_value_fn) macro_tree_delete_value), + ((splay_tree_allocate_fn) macro_alloc), + ((splay_tree_deallocate_fn) macro_free), + t)); + + return t; +} + + +void +free_macro_table (struct macro_table *table) +{ + /* Free the source file tree. */ + free_macro_source_file (table->main_source); + + /* Free the table of macro definitions. */ + splay_tree_delete (table->definitions); +} diff --git a/contrib/gdb/gdb/macrotab.h b/contrib/gdb/gdb/macrotab.h new file mode 100644 index 00000000000..bd44e2c3ed3 --- /dev/null +++ b/contrib/gdb/gdb/macrotab.h @@ -0,0 +1,304 @@ +/* Interface to C preprocessor macro tables for GDB. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MACROTAB_H +#define MACROTAB_H + +struct obstack; +struct bcache; + +/* How do we represent a source location? I mean, how should we + represent them within GDB; the user wants to use all sorts of + ambiguous abbreviations, like "break 32" and "break foo.c:32" + ("foo.c" may have been #included into several compilation units), + but what do we disambiguate those things to? + + - Answer 1: "Filename and line number." (Or column number, if + you're picky.) That's not quite good enough. For example, the + same source file can be #included into several different + compilation units --- which #inclusion do you mean? + + - Answer 2: "Compilation unit, filename, and line number." This is + a pretty good answer; GDB's `struct symtab_and_line' basically + embodies this representation. But it's still ambiguous; what if a + given compilation unit #includes the same file twice --- how can I + set a breakpoint on line 12 of the fifth #inclusion of "foo.c"? + + - Answer 3: "Compilation unit, chain of #inclusions, and line + number." This is analogous to the way GCC reports errors in + #include files: + + $ gcc -c base.c + In file included from header2.h:8, + from header1.h:3, + from base.c:5: + header3.h:1: parse error before ')' token + $ + + GCC tells you exactly what path of #inclusions led you to the + problem. It gives you complete information, in a way that the + following would not: + + $ gcc -c base.c + header3.h:1: parse error before ')' token + $ + + Converting all of GDB to use this is a big task, and I'm not really + suggesting it should be a priority. But this module's whole + purpose is to maintain structures describing the macro expansion + process, so I think it's appropriate for us to take a little care + to do that in a complete fashion. + + In this interface, the first line of a file is numbered 1, not 0. + This is the same convention the rest of GDB uses. */ + + +/* A table of all the macro definitions for a given compilation unit. */ +struct macro_table; + + +/* A source file that participated in a compilation unit --- either a + main file, or an #included file. If a file is #included more than + once, the presence of the `included_from' and `included_at_line' + members means that we need to make one instance of this structure + for each #inclusion. Taken as a group, these structures form a + tree mapping the #inclusions that contributed to the compilation + unit, with the main source file as its root. + + Beware --- not every source file mentioned in a compilation unit's + symtab structures will appear in the #inclusion tree! As of Oct + 2002, GCC does record the effect of #line directives in the source + line info, but not in macro info. This means that GDB's symtabs + (built from the former, among other things) may mention filenames + that the #inclusion tree (built from the latter) doesn't have any + record of. See macroscope.c:sal_macro_scope for how to accomodate + this. + + It's worth noting that libcpp has a simpler way of representing all + this, which we should consider switching to. It might even be + suitable for ordinary non-macro line number info. + + Suppose you take your main source file, and after each line + containing an #include directive you insert the text of the + #included file. The result is a big file that pretty much + corresponds to the full text the compiler's going to see. There's + a one-to-one correspondence between lines in the big file and + per-inclusion lines in the source files. (Obviously, #include + directives that are #if'd out don't count. And you'll need to + append a newline to any file that doesn't end in one, to avoid + splicing the last #included line with the next line of the + #including file.) + + Libcpp calls line numbers in this big imaginary file "logical line + numbers", and has a data structure called a "line map" that can map + logical line numbers onto actual source filenames and line numbers, + and also tell you the chain of #inclusions responsible for any + particular logical line number. Basically, this means you can pass + around a single line number and some kind of "compilation unit" + object and you get nice, unambiguous source code locations that + distinguish between multiple #inclusions of the same file, etc. + + Pretty neat, huh? */ + +struct macro_source_file +{ + + /* The macro table for the compilation unit this source location is + a part of. */ + struct macro_table *table; + + /* A source file --- possibly a header file. */ + const char *filename; + + /* The location we were #included from, or zero if we are the + compilation unit's main source file. */ + struct macro_source_file *included_by; + + /* If `included_from' is non-zero, the line number in that source + file at which we were included. */ + int included_at_line; + + /* Head of a linked list of the source files #included by this file; + our children in the #inclusion tree. This list is sorted by its + elements' `included_at_line' values, which are unique. (The + macro splay tree's ordering function needs this property.) */ + struct macro_source_file *includes; + + /* The next file #included by our `included_from' file; our sibling + in the #inclusion tree. */ + struct macro_source_file *next_included; +}; + + +/* Create a new, empty macro table. Allocate it in OBSTACK, or use + xmalloc if OBSTACK is zero. Use BCACHE to store all macro names, + arguments, definitions, and anything else that might be the same + amongst compilation units in an executable file; if BCACHE is zero, + don't cache these things. + + Note that, if either OBSTACK or BCACHE are non-zero, then you + should only ever add information the macro table --- you should + never remove things from it. You'll get an error if you try. At + the moment, since we only provide obstacks and bcaches for macro + tables for symtabs, this restriction makes a nice sanity check. + Obstacks and bcaches are pretty much grow-only structures anyway. + However, if we find that it's occasionally useful to delete things + even from the symtab's tables, and the storage leak isn't a + problem, this restriction could be lifted. */ +struct macro_table *new_macro_table (struct obstack *obstack, + struct bcache *bcache); + + +/* Free TABLE, and any macro definitions, source file structures, + etc. it owns. This will raise an internal error if TABLE was + allocated on an obstack, or if it uses a bcache. */ +void free_macro_table (struct macro_table *table); + + +/* Set FILENAME as the main source file of TABLE. Return a source + file structure describing that file; if we record the #definition + of macros, or the #inclusion of other files into FILENAME, we'll + use that source file structure to indicate the context. + + The "main source file" is the one that was given to the compiler; + all other source files that contributed to the compilation unit are + #included, directly or indirectly, from this one. + + The macro table makes its own copy of FILENAME; the caller is + responsible for freeing FILENAME when it is no longer needed. */ +struct macro_source_file *macro_set_main (struct macro_table *table, + const char *filename); + + +/* Return the main source file of the macro table TABLE. */ +struct macro_source_file *macro_main (struct macro_table *table); + + +/* Record a #inclusion. + Record in SOURCE's macro table that, at line number LINE in SOURCE, + we #included the file INCLUDED. Return a source file structure we + can use for symbols #defined or files #included into that. If we've + already created a source file structure for this #inclusion, return + the same structure we created last time. + + The first line of the source file has a line number of 1, not 0. + + The macro table makes its own copy of INCLUDED; the caller is + responsible for freeing INCLUDED when it is no longer needed. */ +struct macro_source_file *macro_include (struct macro_source_file *source, + int line, + const char *included); + + +/* Find any source file structure for a file named NAME, either + included into SOURCE, or SOURCE itself. Return zero if we have + none. NAME is only the final portion of the filename, not the full + path. e.g., `stdio.h', not `/usr/include/stdio.h'. If NAME + appears more than once in the inclusion tree, return the + least-nested inclusion --- the one closest to the main source file. */ +struct macro_source_file *(macro_lookup_inclusion + (struct macro_source_file *source, + const char *name)); + + +/* Record an object-like #definition (i.e., one with no parameter list). + Record in SOURCE's macro table that, at line number LINE in SOURCE, + we #defined a preprocessor symbol named NAME, whose replacement + string is REPLACEMENT. This function makes copies of NAME and + REPLACEMENT; the caller is responsible for freeing them. */ +void macro_define_object (struct macro_source_file *source, int line, + const char *name, const char *replacement); + + +/* Record an function-like #definition (i.e., one with a parameter list). + + Record in SOURCE's macro table that, at line number LINE in SOURCE, + we #defined a preprocessor symbol named NAME, with ARGC arguments + whose names are given in ARGV, whose replacement string is REPLACEMENT. If + the macro takes a variable number of arguments, then ARGC should be + one greater than the number of named arguments, and ARGV[ARGC-1] + should be the string "...". This function makes its own copies of + NAME, ARGV, and REPLACEMENT; the caller is responsible for freeing + them. */ +void macro_define_function (struct macro_source_file *source, int line, + const char *name, int argc, const char **argv, + const char *replacement); + + +/* Record an #undefinition. + Record in SOURCE's macro table that, at line number LINE in SOURCE, + we removed the definition for the preprocessor symbol named NAME. */ +void macro_undef (struct macro_source_file *source, int line, + const char *name); + + +/* Different kinds of macro definitions. */ +enum macro_kind +{ + macro_object_like, + macro_function_like +}; + + +/* A preprocessor symbol definition. */ +struct macro_definition +{ + /* The table this definition lives in. */ + struct macro_table *table; + + /* What kind of macro it is. */ + enum macro_kind kind; + + /* If `kind' is `macro_function_like', the number of arguments it + takes, and their names. The names, and the array of pointers to + them, are in the table's bcache, if it has one. */ + int argc; + const char * const *argv; + + /* The replacement string (body) of the macro. This is in the + table's bcache, if it has one. */ + const char *replacement; +}; + + +/* Return a pointer to the macro definition for NAME in scope at line + number LINE of SOURCE. If LINE is -1, return the definition in + effect at the end of the file. The macro table owns the structure; + the caller need not free it. Return zero if NAME is not #defined + at that point. */ +struct macro_definition *(macro_lookup_definition + (struct macro_source_file *source, + int line, const char *name)); + + +/* Return the source location of the definition for NAME in scope at + line number LINE of SOURCE. Set *DEFINITION_LINE to the line + number of the definition, and return a source file structure for + the file. Return zero if NAME has no definition in scope at that + point, and leave *DEFINITION_LINE unchanged. */ +struct macro_source_file *(macro_definition_location + (struct macro_source_file *source, + int line, + const char *name, + int *definition_line)); + + +#endif /* MACROTAB_H */ diff --git a/contrib/gdb/gdb/main.c b/contrib/gdb/gdb/main.c index 7ef8647c65a..7385cfdf20c 100644 --- a/contrib/gdb/gdb/main.c +++ b/contrib/gdb/gdb/main.c @@ -1,7 +1,8 @@ /* Top level stuff for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -37,6 +38,9 @@ #include "event-loop.h" #include "ui-out.h" +#include "interps.h" +#include "main.h" + /* If nonzero, display time usage both at startup and for each command. */ int display_time; @@ -51,26 +55,28 @@ int display_space; processes UI events asynchronously. */ int event_loop_p = 1; -/* Has an interpreter been specified and if so, which. */ +/* The selected interpreter. This will be used as a set command + variable, so it should always be malloc'ed - since + do_setshow_command will free it. */ char *interpreter_p; -/* Whether this is the command line version or not */ -int tui_version = 0; - /* Whether xdb commands will be handled */ int xdb_commands = 0; /* Whether dbx commands will be handled */ int dbx_commands = 0; +/* System root path, used to find libraries etc. */ +char *gdb_sysroot = 0; + struct ui_file *gdb_stdout; struct ui_file *gdb_stderr; struct ui_file *gdb_stdlog; +struct ui_file *gdb_stdin; +/* target IO streams */ +struct ui_file *gdb_stdtargin; struct ui_file *gdb_stdtarg; - -/* Used to initialize error() - defined in utils.c */ - -extern void error_init (void); +struct ui_file *gdb_stdtargerr; /* Whether to enable writing into executable and core files */ extern int write_files; @@ -88,10 +94,7 @@ extern char *external_editor_command; static int captured_command_loop (void *data) { - if (command_loop_hook == NULL) - command_loop (); - else - command_loop_hook (); + current_interp_command_loop (); /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton would clean things up (restoring the cleanup chain) to the state they were just prior to the call. Technically, this means that @@ -108,12 +111,6 @@ captured_command_loop (void *data) return 1; } -struct captured_main_args - { - int argc; - char **argv; - }; - static int captured_main (void *data) { @@ -153,19 +150,25 @@ captured_main (void *data) struct stat homebuf, cwdbuf; char *homedir, *homeinit; - register int i; + int i; long time_at_startup = get_run_time (); - START_PROGRESS (argv[0], 0); - -#ifdef MPW - /* Do all Mac-specific setup. */ - mac_init (); -#endif /* MPW */ +#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) + setlocale (LC_MESSAGES, ""); +#endif +#if defined (HAVE_SETLOCALE) + setlocale (LC_CTYPE, ""); +#endif + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); /* This needs to happen before the first use of malloc. */ - init_malloc ((PTR) NULL); + init_malloc (NULL); + +#ifdef HAVE_SBRK + lim_at_start = (char *) sbrk (0); +#endif #if defined (ALIGN_STACK_ON_STARTUP) i = (int) &count & 0x3; @@ -192,29 +195,73 @@ captured_main (void *data) gdb_stderr = stdio_fileopen (stderr); gdb_stdlog = gdb_stderr; /* for moment */ gdb_stdtarg = gdb_stderr; /* for moment */ + gdb_stdin = stdio_fileopen (stdin); + gdb_stdtargerr = gdb_stderr; /* for moment */ + gdb_stdtargin = gdb_stdin; /* for moment */ /* initialize error() */ error_init (); + /* Set the sysroot path. */ +#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE + gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT); + if (gdb_sysroot) + { + struct stat s; + int res = 0; + + if (stat (gdb_sysroot, &s) == 0) + if (S_ISDIR (s.st_mode)) + res = 1; + + if (res == 0) + { + xfree (gdb_sysroot); + gdb_sysroot = TARGET_SYSTEM_ROOT; + } + } + else + gdb_sysroot = TARGET_SYSTEM_ROOT; +#else +#if defined (TARGET_SYSTEM_ROOT) + gdb_sysroot = TARGET_SYSTEM_ROOT; +#else + gdb_sysroot = ""; +#endif +#endif + + /* There will always be an interpreter. Either the one passed into + this captured main, or one specified by the user at start up, or + the console. Initialize the interpreter to the one requested by + the application. */ + interpreter_p = xstrdup (context->interpreter_p); + /* Parse arguments and options. */ { int c; /* When var field is 0, use flag field to record the equivalent short option (or arbitrary numbers starting at 10 for those with no equivalent). */ + enum { + OPT_SE = 10, + OPT_CD, + OPT_ANNOTATE, + OPT_STATISTICS, + OPT_TUI, + OPT_NOWINDOWS, + OPT_WINDOWS + }; static struct option long_options[] = { {"async", no_argument, &event_loop_p, 1}, {"noasync", no_argument, &event_loop_p, 0}, #if defined(TUI) - {"tui", no_argument, &tui_version, 1}, + {"tui", no_argument, 0, OPT_TUI}, #endif {"xdb", no_argument, &xdb_commands, 1}, {"dbx", no_argument, &dbx_commands, 1}, {"readnow", no_argument, &readnow_symbol_files, 1}, {"r", no_argument, &readnow_symbol_files, 1}, - {"mapped", no_argument, &mapped_symbol_files, 1}, - {"m", no_argument, &mapped_symbol_files, 1}, {"quiet", no_argument, &quiet, 1}, {"q", no_argument, &quiet, 1}, {"silent", no_argument, &quiet, 1}, @@ -229,9 +276,9 @@ captured_main (void *data) {"fullname", no_argument, 0, 'f'}, {"f", no_argument, 0, 'f'}, - {"annotate", required_argument, 0, 12}, + {"annotate", required_argument, 0, OPT_ANNOTATE}, {"help", no_argument, &print_help, 1}, - {"se", required_argument, 0, 10}, + {"se", required_argument, 0, OPT_SE}, {"symbols", required_argument, 0, 's'}, {"s", required_argument, 0, 's'}, {"exec", required_argument, 0, 'e'}, @@ -253,21 +300,17 @@ captured_main (void *data) {"i", required_argument, 0, 'i'}, {"directory", required_argument, 0, 'd'}, {"d", required_argument, 0, 'd'}, - {"cd", required_argument, 0, 11}, + {"cd", required_argument, 0, OPT_CD}, {"tty", required_argument, 0, 't'}, {"baud", required_argument, 0, 'b'}, {"b", required_argument, 0, 'b'}, - {"nw", no_argument, &use_windows, 0}, - {"nowindows", no_argument, &use_windows, 0}, - {"w", no_argument, &use_windows, 1}, - {"windows", no_argument, &use_windows, 1}, - {"statistics", no_argument, 0, 13}, + {"nw", no_argument, NULL, OPT_NOWINDOWS}, + {"nowindows", no_argument, NULL, OPT_NOWINDOWS}, + {"w", no_argument, NULL, OPT_WINDOWS}, + {"windows", no_argument, NULL, OPT_WINDOWS}, + {"statistics", no_argument, 0, OPT_STATISTICS}, {"write", no_argument, &write_files, 1}, {"args", no_argument, &set_args, 1}, -/* Allow machine descriptions to add more options... */ -#ifdef ADDITIONAL_OPTIONS - ADDITIONAL_OPTIONS -#endif {0, no_argument, 0, 0} }; @@ -289,22 +332,38 @@ captured_main (void *data) case 0: /* Long option that just sets a flag. */ break; - case 10: + case OPT_SE: symarg = optarg; execarg = optarg; break; - case 11: + case OPT_CD: cdarg = optarg; break; - case 12: + case OPT_ANNOTATE: /* FIXME: what if the syntax is wrong (e.g. not digits)? */ annotation_level = atoi (optarg); break; - case 13: + case OPT_STATISTICS: /* Enable the display of both time and space usage. */ display_time = 1; display_space = 1; break; + case OPT_TUI: + /* --tui is equivalent to -i=tui. */ + xfree (interpreter_p); + interpreter_p = xstrdup ("tui"); + break; + case OPT_WINDOWS: + /* FIXME: cagney/2003-03-01: Not sure if this option is + actually useful, and if it is, what it should do. */ + use_windows = 1; + break; + case OPT_NOWINDOWS: + /* -nw is equivalent to -i=console. */ + xfree (interpreter_p); + interpreter_p = xstrdup (INTERP_CONSOLE); + use_windows = 0; + break; case 'f': annotation_level = 1; /* We have probably been invoked from emacs. Disable window interface. */ @@ -338,7 +397,7 @@ captured_main (void *data) extern int gdbtk_test (char *); if (!gdbtk_test (optarg)) { - fprintf_unfiltered (gdb_stderr, "%s: unable to load tclcommand file \"%s\"", + fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""), argv[0], optarg); exit (1); } @@ -354,7 +413,8 @@ extern int gdbtk_test (char *); } #endif /* GDBTK */ case 'i': - interpreter_p = optarg; + xfree (interpreter_p); + interpreter_p = xstrdup (optarg); break; case 'd': dirarg[ndir++] = optarg; @@ -384,10 +444,11 @@ extern int gdbtk_test (char *); fprintf_unfiltered (gdb_stderr, - "warning: could not set baud rate to `%s'.\n", optarg); + _("warning: could not set baud rate to `%s'.\n"), optarg); else baud_rate = i; } + break; case 'l': { int i; @@ -401,18 +462,15 @@ extern int gdbtk_test (char *); fprintf_unfiltered (gdb_stderr, - "warning: could not set timeout limit to `%s'.\n", optarg); + _("warning: could not set timeout limit to `%s'.\n"), optarg); else remote_timeout = i; } break; -#ifdef ADDITIONAL_OPTION_CASES - ADDITIONAL_OPTION_CASES -#endif case '?': fprintf_unfiltered (gdb_stderr, - "Use `%s --help' for a complete list of options.\n", + _("Use `%s --help' for a complete list of options.\n"), argv[0]); exit (1); } @@ -422,19 +480,8 @@ extern int gdbtk_test (char *); if (print_help || print_version) { use_windows = 0; -#ifdef TUI - /* Disable the TUI as well. */ - tui_version = 0; -#endif } -#ifdef TUI - /* An explicit --tui flag overrides the default UI, which is the - window system. */ - if (tui_version) - use_windows = 0; -#endif - if (set_args) { /* The remaining options are the command-line options for the @@ -443,7 +490,7 @@ extern int gdbtk_test (char *); if (optind >= argc) { fprintf_unfiltered (gdb_stderr, - "%s: `--args' specified but no program specified\n", + _("%s: `--args' specified but no program specified\n"), argv[0]); exit (1); } @@ -470,7 +517,7 @@ extern int gdbtk_test (char *); break; case 3: fprintf_unfiltered (gdb_stderr, - "Excess command line arguments ignored. (%s%s)\n", + _("Excess command line arguments ignored. (%s%s)\n"), argv[optind], (optind == argc - 1) ? "" : " ..."); break; } @@ -484,7 +531,10 @@ extern int gdbtk_test (char *); gdb_init (argv[0]); /* Do these (and anything which might call wrap_here or *_filtered) - after initialize_all_files. */ + after initialize_all_files() but before the interpreter has been + installed. Otherwize the help/version messages will be eaten by + the interpreter's output handler. */ + if (print_version) { print_gdb_version (gdb_stdout); @@ -500,7 +550,45 @@ extern int gdbtk_test (char *); exit (0); } - if (!quiet) + /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets + GDB retain the old MI1 interpreter startup behavior. Output the + copyright message before the interpreter is installed. That way + it isn't encapsulated in MI output. */ + if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0) + { + /* Print all the junk at the top, with trailing "..." if we are about + to read a symbol file (possibly slowly). */ + print_gdb_version (gdb_stdout); + if (symarg) + printf_filtered (".."); + wrap_here (""); + gdb_flush (gdb_stdout); /* Force to screen during slow operations */ + } + + + /* Install the default UI. All the interpreters should have had a + look at things by now. Initialize the default interpreter. */ + + { + /* Find it. */ + struct interp *interp = interp_lookup (interpreter_p); + if (interp == NULL) + error ("Interpreter `%s' unrecognized", interpreter_p); + /* Install it. */ + if (!interp_set (interp)) + { + fprintf_unfiltered (gdb_stderr, + "Interpreter `%s' failed to initialize.\n", + interpreter_p); + exit (1); + } + } + + /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets + GDB retain the old MI1 interpreter startup behavior. Output the + copyright message after the interpreter is installed when it is + any sane interpreter. */ + if (!quiet && !current_interp_named_p (INTERP_MI1)) { /* Print all the junk at the top, with trailing "..." if we are about to read a symbol file (possibly slowly). */ @@ -515,7 +603,7 @@ extern int gdbtk_test (char *); quit_pre_print = error_pre_print; /* We may get more than one warning, don't double space all of them... */ - warning_pre_print = "\nwarning: "; + warning_pre_print = _("\nwarning: "); /* Read and execute $HOME/.gdbinit file, if it exists. This is done *before* all the command line arguments are processed; it sets @@ -560,7 +648,7 @@ extern int gdbtk_test (char *); if (execarg != NULL && symarg != NULL - && STREQ (execarg, symarg)) + && strcmp (execarg, symarg) == 0) { /* The exec file and the symbol-file are the same. If we can't open it, better only print one error message. @@ -583,7 +671,7 @@ extern int gdbtk_test (char *); printf_filtered ("\n"); error_pre_print = "\n"; quit_pre_print = error_pre_print; - warning_pre_print = "\nwarning: "; + warning_pre_print = _("\nwarning: "); if (corearg != NULL) { @@ -606,14 +694,10 @@ extern int gdbtk_test (char *); if (ttyarg != NULL) catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); -#ifdef ADDITIONAL_OPTION_HANDLER - ADDITIONAL_OPTION_HANDLER; -#endif - /* Error messages should no longer be distinguished with extra output. */ error_pre_print = NULL; quit_pre_print = NULL; - warning_pre_print = "warning: "; + warning_pre_print = _("warning: "); /* Read the .gdbinit file in the current directory, *if* it isn't the same as the $HOME/.gdbinit file (it should exist, also). */ @@ -664,15 +748,13 @@ extern int gdbtk_test (char *); BEFORE_MAIN_LOOP_HOOK; #endif - END_PROGRESS (argv[0]); - /* Show time and/or space usage. */ if (display_time) { long init_time = get_run_time () - time_at_startup; - printf_unfiltered ("Startup time: %ld.%06ld\n", + printf_unfiltered (_("Startup time: %ld.%06ld\n"), init_time / 1000000, init_time % 1000000); } @@ -682,7 +764,7 @@ extern int gdbtk_test (char *); extern char **environ; char *lim = (char *) sbrk (0); - printf_unfiltered ("Startup size: data size %ld\n", + printf_unfiltered (_("Startup size: data size %ld\n"), (long) (lim - (char *) &environ)); #endif } @@ -726,13 +808,13 @@ extern int gdbtk_test (char *); } int -main (int argc, char **argv) +gdb_main (struct captured_main_args *args) { - struct captured_main_args args; - args.argc = argc; - args.argv = argv; - catch_errors (captured_main, &args, "", RETURN_MASK_ALL); - return 0; + use_windows = args->use_windows; + catch_errors (captured_main, args, "", RETURN_MASK_ALL); + /* The only way to end up here is by an error (normal exit is + handled by quit_force()), hence always return an error status. */ + return 1; } @@ -743,69 +825,66 @@ main (int argc, char **argv) static void print_gdb_help (struct ui_file *stream) { - fputs_unfiltered ("\ + fputs_unfiltered (_("\ This is the GNU debugger. Usage:\n\n\ gdb [options] [executable-file [core-file or process-id]]\n\ gdb [options] --args executable-file [inferior-arguments ...]\n\n\ Options:\n\n\ -", stream); - fputs_unfiltered ("\ +"), stream); + fputs_unfiltered (_("\ --args Arguments after executable-file are passed to inferior\n\ -", stream); - fputs_unfiltered ("\ +"), stream); + fputs_unfiltered (_("\ --[no]async Enable (disable) asynchronous version of CLI\n\ -", stream); - fputs_unfiltered ("\ +"), stream); + fputs_unfiltered (_("\ -b BAUDRATE Set serial port baud rate used for remote debugging.\n\ --batch Exit after processing options.\n\ --cd=DIR Change current directory to DIR.\n\ --command=FILE Execute GDB commands from FILE.\n\ --core=COREFILE Analyze the core dump COREFILE.\n\ --pid=PID Attach to running process PID.\n\ -", stream); - fputs_unfiltered ("\ +"), stream); + fputs_unfiltered (_("\ --dbx DBX compatibility mode.\n\ --directory=DIR Search for source files in DIR.\n\ --epoch Output information used by epoch emacs-GDB interface.\n\ --exec=EXECFILE Use EXECFILE as the executable.\n\ --fullname Output information used by emacs-GDB interface.\n\ --help Print this message.\n\ -", stream); - fputs_unfiltered ("\ +"), stream); + fputs_unfiltered (_("\ --interpreter=INTERP\n\ Select a specific interpreter / user interface\n\ -", stream); - fputs_unfiltered ("\ +"), stream); + fputs_unfiltered (_("\ --mapped Use mapped symbol files if supported on this system.\n\ --nw Do not use a window interface.\n\ - --nx Do not read ", stream); + --nx Do not read "), stream); fputs_unfiltered (gdbinit, stream); - fputs_unfiltered (" file.\n\ + fputs_unfiltered (_(" file.\n\ --quiet Do not print version number on startup.\n\ --readnow Fully read symbol files on first access.\n\ -", stream); - fputs_unfiltered ("\ +"), stream); + fputs_unfiltered (_("\ --se=FILE Use FILE as symbol file and executable file.\n\ --symbols=SYMFILE Read symbols from SYMFILE.\n\ --tty=TTY Use TTY for input/output by the program being debugged.\n\ -", stream); +"), stream); #if defined(TUI) - fputs_unfiltered ("\ + fputs_unfiltered (_("\ --tui Use a terminal user interface.\n\ -", stream); +"), stream); #endif - fputs_unfiltered ("\ + fputs_unfiltered (_("\ --version Print version information and then exit.\n\ -w Use a window interface.\n\ --write Set writing into executable and core files.\n\ --xdb XDB compatibility mode.\n\ -", stream); -#ifdef ADDITIONAL_OPTION_HELP - fputs_unfiltered (ADDITIONAL_OPTION_HELP, stream); -#endif - fputs_unfiltered ("\n\ +"), stream); + fputs_unfiltered (_("\n\ For more information, type \"help\" from within GDB, or consult the\n\ GDB manual (available as on-line info or a printed manual).\n\ Report bugs to \"bug-gdb@gnu.org\".\ -", stream); +"), stream); } diff --git a/contrib/gdb/gdb/main.h b/contrib/gdb/gdb/main.h new file mode 100644 index 00000000000..1c91d0770f8 --- /dev/null +++ b/contrib/gdb/gdb/main.h @@ -0,0 +1,35 @@ +/* Main interface for GDB, the GNU debugger. + + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MAIN_H +#define MAIN_H + +struct captured_main_args +{ + int argc; + char **argv; + int use_windows; + const char *interpreter_p; +}; + +extern int gdb_main (struct captured_main_args *); + +#endif diff --git a/contrib/gdb/gdb/maint.c b/contrib/gdb/gdb/maint.c index 0d2be0912f5..f105afa601d 100644 --- a/contrib/gdb/gdb/maint.c +++ b/contrib/gdb/gdb/maint.c @@ -1,6 +1,8 @@ /* Support for GDB maintenance commands. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, + 2002, 2003, 2004 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support. This file is part of GDB. @@ -36,6 +38,8 @@ #include "objfiles.h" #include "value.h" +#include "cli/cli-decode.h" + extern void _initialize_maint_cmds (void); static void maintenance_command (char *, int); @@ -52,8 +56,6 @@ static void maintenance_space_display (char *, int); static void maintenance_info_command (char *, int); -static void print_section_table (bfd *, asection *, void *); - static void maintenance_info_sections (char *, int); static void maintenance_print_command (char *, int); @@ -90,7 +92,6 @@ maintenance_command (char *args, int from_tty) } #ifndef _WIN32 -/* ARGSUSED */ static void maintenance_dump_me (char *args, int from_tty) { @@ -116,8 +117,18 @@ maintenance_dump_me (char *args, int from_tty) static void maintenance_internal_error (char *args, int from_tty) { - internal_error (__FILE__, __LINE__, - "internal maintenance"); + internal_error (__FILE__, __LINE__, "%s", (args == NULL ? "" : args)); +} + +/* Stimulate the internal error mechanism that GDB uses when an + internal problem is detected. Allows testing of the mechanism. + Also useful when the user wants to drop a core file but not exit + GDB. */ + +static void +maintenance_internal_warning (char *args, int from_tty) +{ + internal_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args)); } /* Someday we should allow demangling for things other than just @@ -139,7 +150,8 @@ maintenance_demangle (char *args, int from_tty) } else { - demangled = cplus_demangle (args, DMGL_ANSI | DMGL_PARAMS); + demangled = language_demangle (current_language, args, + DMGL_ANSI | DMGL_PARAMS); if (demangled != NULL) { printf_unfiltered ("%s\n", demangled); @@ -178,7 +190,6 @@ maintenance_space_display (char *args, int from_tty) allow_unknown 0. Therefore, its own definition is called only for "maintenance info" with no args. */ -/* ARGSUSED */ static void maintenance_info_command (char *arg, int from_tty) { @@ -289,9 +300,9 @@ print_bfd_flags (flagword flags) } static void -print_section_info (const char *name, flagword flags, - CORE_ADDR addr, CORE_ADDR endaddr, - unsigned long filepos) +maint_print_section_info (const char *name, flagword flags, + CORE_ADDR addr, CORE_ADDR endaddr, + unsigned long filepos) { /* FIXME-32x64: Need print_address_numeric with field width. */ printf_filtered (" 0x%s", paddr (addr)); @@ -319,7 +330,7 @@ print_bfd_section_info (bfd *abfd, addr = bfd_section_vma (abfd, asect); endaddr = addr + bfd_section_size (abfd, asect); - print_section_info (name, flags, addr, endaddr, asect->filepos); + maint_print_section_info (name, flags, addr, endaddr, asect->filepos); } } @@ -335,12 +346,11 @@ print_objfile_section_info (bfd *abfd, || match_substring (string, name) || match_bfd_flags (string, flags)) { - print_section_info (name, flags, asect->addr, asect->endaddr, + maint_print_section_info (name, flags, asect->addr, asect->endaddr, asect->the_bfd_section->filepos); } } -/* ARGSUSED */ static void maintenance_info_sections (char *arg, int from_tty) { @@ -386,7 +396,6 @@ maintenance_info_sections (char *arg, int from_tty) } } -/* ARGSUSED */ void maintenance_print_statistics (char *args, int from_tty) { @@ -394,7 +403,7 @@ maintenance_print_statistics (char *args, int from_tty) print_symbol_bcache_statistics (); } -void +static void maintenance_print_architecture (char *args, int from_tty) { if (args == NULL) @@ -413,7 +422,6 @@ maintenance_print_architecture (char *args, int from_tty) allow_unknown 0. Therefore, its own definition is called only for "maintenance print" with no args. */ -/* ARGSUSED */ static void maintenance_print_command (char *arg, int from_tty) { @@ -472,7 +480,7 @@ maintenance_translate_address (char *arg, int from_tty) if (sym) printf_filtered ("%s+%s\n", - SYMBOL_SOURCE_NAME (sym), + SYMBOL_PRINT_NAME (sym), paddr_u (address - SYMBOL_VALUE_ADDRESS (sym))); else if (sect) printf_filtered ("no symbol at %s:0x%s\n", sect->name, paddr (address)); @@ -617,16 +625,67 @@ maintenance_show_cmd (char *args, int from_tty) cmd_show_list (maintenance_show_cmdlist, from_tty, ""); } -#ifdef NOTYET /* Profiling support. */ static int maintenance_profile_p; +#if defined (HAVE_MONSTARTUP) && defined (HAVE__MCLEANUP) + +#ifdef HAVE__ETEXT +extern char _etext; +#define TEXTEND &_etext +#else +extern char etext; +#define TEXTEND &etext +#endif + +static int profiling_state; + +static void +mcleanup_wrapper (void) +{ + extern void _mcleanup (void); + + if (profiling_state) + _mcleanup (); +} + static void maintenance_set_profile_cmd (char *args, int from_tty, struct cmd_list_element *c) { - maintenance_profile_p = 0; - warning ("\"maintenance set profile\" command not supported.\n"); + if (maintenance_profile_p == profiling_state) + return; + + profiling_state = maintenance_profile_p; + + if (maintenance_profile_p) + { + static int profiling_initialized; + + extern void monstartup (unsigned long, unsigned long); + extern int main(); + + if (!profiling_initialized) + { + atexit (mcleanup_wrapper); + profiling_initialized = 1; + } + + /* "main" is now always the first function in the text segment, so use + its address for monstartup. */ + monstartup ((unsigned long) &main, (unsigned long) TEXTEND); + } + else + { + extern void _mcleanup (void); + _mcleanup (); + } +} +#else +static void +maintenance_set_profile_cmd (char *args, int from_tty, struct cmd_list_element *c) +{ + error ("Profiling support is not available on this system."); } #endif @@ -639,7 +698,7 @@ _initialize_maint_cmds (void) "Commands for use by GDB maintainers.\n\ Includes commands to dump specific internal GDB structures in\n\ a human readable form, to cause GDB to deliberately dump core,\n\ -to test internal functions such as the C++ demangler, etc.", +to test internal functions such as the C++/ObjC demangler, etc.", &maintenancelist, "maintenance ", 0, &cmdlist); @@ -685,7 +744,7 @@ Configure variables internal to GDB that aid in GDB's maintenance", #ifndef _WIN32 add_cmd ("dump-me", class_maintenance, maintenance_dump_me, "Get fatal error; make debugger dump its core.\n\ -GDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\n\ +GDB sets its handling of SIGQUIT back to SIG_DFL and then sends\n\ itself a SIGQUIT signal.", &maintenancelist); #endif @@ -695,8 +754,13 @@ itself a SIGQUIT signal.", Cause GDB to behave as if an internal error was detected.", &maintenancelist); + add_cmd ("internal-warning", class_maintenance, maintenance_internal_warning, + "Give GDB an internal warning.\n\ +Cause GDB to behave as if an internal warning was reported.", + &maintenancelist); + add_cmd ("demangle", class_maintenance, maintenance_demangle, - "Demangle a C++ mangled name.\n\ + "Demangle a C++/ObjC mangled name.\n\ Call internal GDB demangler routine to demangle a C++ link name\n\ and prints the result.", &maintenancelist); @@ -741,6 +805,19 @@ If a SOURCE file is specified, dump only that file's partial symbols.", "Print dump of current object file definitions.", &maintenanceprintlist); + add_cmd ("symtabs", class_maintenance, maintenance_info_symtabs, + "List the full symbol tables for all object files.\n\ +This does not include information about individual symbols, blocks, or\n\ +linetables --- just the symbol table structures themselves.\n\ +With an argument REGEXP, list the symbol tables whose names that match that.", + &maintenanceinfolist); + + add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, + "List the partial symbol tables for all object files.\n\ +This does not include information about individual partial symbols,\n\ +just the symbol table structures themselves.", + &maintenanceinfolist); + add_cmd ("statistics", class_maintenance, maintenance_print_statistics, "Print statistics about internal gdb state.", &maintenanceprintlist); @@ -780,17 +857,12 @@ passes without a response from the target, an error occurs.", &setlist), &showlist); -#ifdef NOTYET - /* FIXME: cagney/2001-09-24: A patch introducing a - add_set_boolean_cmd() is pending, the below should probably use - it. A patch implementing profiling is pending, this just sets up - the framework. */ - tmpcmd = add_set_cmd ("profile", class_maintenance, - var_boolean, &maintenance_profile_p, - "Set internal profiling.\n\ -When enabled GDB is profiled.", - &maintenance_set_cmdlist); - set_cmd_sfunc (tmpcmd, maintenance_set_profile_cmd); - add_show_from_set (tmpcmd, &maintenance_show_cmdlist); -#endif + add_setshow_boolean_cmd ("profile", class_maintenance, + &maintenance_profile_p, + "Set internal profiling.\n" + "When enabled GDB is profiled.", + "Show internal profiling.\n", + maintenance_set_profile_cmd, NULL, + &maintenance_set_cmdlist, + &maintenance_show_cmdlist); } diff --git a/contrib/gdb/gdb/mdebugread.c b/contrib/gdb/gdb/mdebugread.c index c974c9e874a..89d0282ecfd 100644 --- a/contrib/gdb/gdb/mdebugread.c +++ b/contrib/gdb/gdb/mdebugread.c @@ -1,7 +1,9 @@ /* Read a symbol table in ECOFF format (Third-Eye). - Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + Original version contributed by Alessandro Forin (af@cs.cmu.edu) at CMU. Major work by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support. @@ -45,13 +47,15 @@ #include "symtab.h" #include "gdbtypes.h" #include "gdbcore.h" -#include "symfile.h" #include "objfiles.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "buildsym.h" #include "stabsread.h" #include "complaints.h" #include "demangle.h" +#include "gdb_assert.h" +#include "block.h" +#include "dictionary.h" /* These are needed if the tm.h file does not contain the necessary mips specific definitions. */ @@ -105,11 +109,6 @@ extern void _initialize_mdebugread (void); struct symloc { - /* Our running best guess as to the range of text addresses for - this psymtab. After we've read everything in, we use this to - build pst->text_addrs. */ - CORE_ADDR textlow, texthigh; - /* Index of the FDR that this psymtab represents. */ int fdr_idx; /* The BFD that the psymtab was created from. */ @@ -125,8 +124,6 @@ struct symloc }; #define PST_PRIVATE(p) ((struct symloc *)(p)->read_symtab_private) -#define TEXTLOW(p) (PST_PRIVATE(p)->textlow) -#define TEXTHIGH(p) (PST_PRIVATE(p)->texthigh) #define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx) #define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd) #define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap) @@ -148,96 +145,43 @@ struct symloc #define SC_IS_UNDEF(sc) ((sc) == scUndefined || (sc) == scSUndefined) /* Various complaints about symbol reading that don't abort the process */ +static void +index_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "bad aux index at symbol %s", arg1); +} -static struct complaint bad_file_number_complaint = -{"bad file number %d", 0, 0}; +static void +unknown_ext_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "unknown external symbol %s", arg1); +} -static struct complaint index_complaint = -{"bad aux index at symbol %s", 0, 0}; +static void +basic_type_complaint (int arg1, const char *arg2) +{ + complaint (&symfile_complaints, "cannot map ECOFF basic type 0x%x for %s", + arg1, arg2); +} -static struct complaint aux_index_complaint = -{"bad proc end in aux found from symbol %s", 0, 0}; +static void +bad_tag_guess_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "guessed tag type of %s incorrectly", arg1); +} -static struct complaint block_index_complaint = -{"bad aux index at block symbol %s", 0, 0}; +static void +bad_rfd_entry_complaint (const char *arg1, int arg2, int arg3) +{ + complaint (&symfile_complaints, "bad rfd entry for %s: file %d, index %d", + arg1, arg2, arg3); +} -static struct complaint unknown_ext_complaint = -{"unknown external symbol %s", 0, 0}; - -static struct complaint unknown_sym_complaint = -{"unknown local symbol %s", 0, 0}; - -static struct complaint unknown_st_complaint = -{"with type %d", 0, 0}; - -static struct complaint block_overflow_complaint = -{"block containing %s overfilled", 0, 0}; - -static struct complaint basic_type_complaint = -{"cannot map ECOFF basic type 0x%x for %s", 0, 0}; - -static struct complaint unknown_type_qual_complaint = -{"unknown type qualifier 0x%x", 0, 0}; - -static struct complaint array_index_type_complaint = -{"illegal array index type for %s, assuming int", 0, 0}; - -static struct complaint bad_tag_guess_complaint = -{"guessed tag type of %s incorrectly", 0, 0}; - -static struct complaint block_member_complaint = -{"declaration block contains unhandled symbol type %d", 0, 0}; - -static struct complaint stEnd_complaint = -{"stEnd with storage class %d not handled", 0, 0}; - -static struct complaint unknown_mdebug_symtype_complaint = -{"unknown symbol type 0x%x", 0, 0}; - -static struct complaint stab_unknown_complaint = -{"unknown stabs symbol %s", 0, 0}; - -static struct complaint pdr_for_nonsymbol_complaint = -{"PDR for %s, but no symbol", 0, 0}; - -static struct complaint pdr_static_symbol_complaint = -{"can't handle PDR for static proc at 0x%lx", 0, 0}; - -static struct complaint bad_setjmp_pdr_complaint = -{"fixing bad setjmp PDR from libc", 0, 0}; - -static struct complaint bad_fbitfield_complaint = -{"can't handle TIR fBitfield for %s", 0, 0}; - -static struct complaint bad_continued_complaint = -{"illegal TIR continued for %s", 0, 0}; - -static struct complaint bad_rfd_entry_complaint = -{"bad rfd entry for %s: file %d, index %d", 0, 0}; - -static struct complaint unexpected_type_code_complaint = -{"unexpected type code for %s", 0, 0}; - -static struct complaint unable_to_cross_ref_complaint = -{"unable to cross ref btTypedef for %s", 0, 0}; - -static struct complaint bad_indirect_xref_complaint = -{"unable to cross ref btIndirect for %s", 0, 0}; - -static struct complaint illegal_forward_tq0_complaint = -{"illegal tq0 in forward typedef for %s", 0, 0}; - -static struct complaint illegal_forward_bt_complaint = -{"illegal bt %d in forward typedef for %s", 0, 0}; - -static struct complaint bad_linetable_guess_complaint = -{"guessed size of linetable for %s incorrectly", 0, 0}; - -static struct complaint bad_ext_ifd_complaint = -{"bad ifd for external symbol: %d (max %d)", 0, 0}; - -static struct complaint bad_ext_iss_complaint = -{"bad iss for external symbol: %ld (max %ld)", 0, 0}; +static void +unexpected_type_code_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "unexpected type code for %s", arg1); +} /* Macros and extra defs */ @@ -342,9 +286,11 @@ static struct symbol *new_symbol (char *); static struct type *new_type (char *); -static struct block *new_block (int); +enum block_type { FUNCTION_BLOCK, NON_FUNCTION_BLOCK }; -static struct symtab *new_symtab (char *, int, int, struct objfile *); +static struct block *new_block (enum block_type); + +static struct symtab *new_symtab (char *, int, struct objfile *); static struct linetable *new_linetable (int); @@ -353,11 +299,9 @@ static struct blockvector *new_bvect (int); static struct type *parse_type (int, union aux_ext *, unsigned int, int *, int, char *); -static struct symbol *mylookup_symbol (char *, struct block *, namespace_enum, +static struct symbol *mylookup_symbol (char *, struct block *, domain_enum, enum address_class); -static struct block *shrink_block (struct block *, struct symtab *); - static void sort_blocks (struct symtab *); static struct partial_symtab *new_psymtab (char *, struct objfile *); @@ -430,7 +374,7 @@ static FDR * get_rfd (int cf, int rf) { FDR *fdrs; - register FDR *f; + FDR *f; RFDT rfd; fdrs = debug_info->fdr; @@ -483,7 +427,7 @@ mdebug_build_psymtabs (struct objfile *objfile, char *fdr_end; FDR *fdr_ptr; - info->fdr = (FDR *) obstack_alloc (&objfile->psymbol_obstack, + info->fdr = (FDR *) obstack_alloc (&objfile->objfile_obstack, (info->symbolic_header.ifdMax * sizeof (FDR))); fdr_src = info->external_fdr; @@ -496,19 +440,6 @@ mdebug_build_psymtabs (struct objfile *objfile, parse_partial_symbols (objfile); - /* Take the text ranges the partial symbol scanner computed for each - of the psymtabs and convert it into the canonical form for - psymtabs. */ - { - struct partial_symtab *p; - - ALL_OBJFILE_PSYMTABS (objfile, p) - { - p->textlow = TEXTLOW (p); - p->texthigh = TEXTHIGH (p); - } - } - #if 0 /* Check to make sure file was compiled with -g. If not, warn the user of this limitation. */ @@ -554,7 +485,6 @@ static struct parse_stack int blocktype; - int maxsyms; /* Max symbols in this block. */ struct type *cur_type; /* Type we parse fields for. */ int cur_field; /* Field number in cur_type. */ CORE_ADDR procadr; /* Start addres of this procedure */ @@ -579,7 +509,7 @@ push_parse_stack (void) /* Initialize new frame with previous content */ if (top_stack) { - register struct parse_stack *prev = new->prev; + struct parse_stack *prev = new->prev; *new = *top_stack; top_stack->prev = new; @@ -629,7 +559,7 @@ static struct mdebug_pending * is_pending_symbol (FDR *fh, char *sh) { int f_idx = fh - debug_info->fdr; - register struct mdebug_pending *p; + struct mdebug_pending *p; /* Linear search is ok, list is typically no more than 10 deep */ for (p = pending_list[f_idx]; p; p = p->next) @@ -650,7 +580,7 @@ add_pending (FDR *fh, char *sh, struct type *t) if (!p) { p = ((struct mdebug_pending *) - obstack_alloc (¤t_objfile->psymbol_obstack, + obstack_alloc (¤t_objfile->objfile_obstack, sizeof (struct mdebug_pending))); p->s = sh; p->t = t; @@ -741,7 +671,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, /* It is a FORTRAN common block. At least for SGI Fortran the address is not in the symbol; we need to fix it later in scan_file_globals. */ - int bucket = hashname (SYMBOL_NAME (s)); + int bucket = hashname (DEPRECATED_SYMBOL_NAME (s)); SYMBOL_VALUE_CHAIN (s) = global_sym_chain[bucket]; global_sym_chain[bucket] = s; } @@ -762,7 +692,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, SYMBOL_VALUE (s) = svalue; data: /* Common code for symbols describing data */ - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; + SYMBOL_DOMAIN (s) = VAR_DOMAIN; SYMBOL_CLASS (s) = class; add_symbol (s, b); @@ -785,7 +715,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, name = "this"; /* FIXME, not alloc'd in obstack */ s = new_symbol (name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; + SYMBOL_DOMAIN (s) = VAR_DOMAIN; switch (sh->sc) { case scRegister: @@ -814,7 +744,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, case stLabel: /* label, goes into current block */ s = new_symbol (name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; /* so that it can be used */ + SYMBOL_DOMAIN (s) = VAR_DOMAIN; /* so that it can be used */ SYMBOL_CLASS (s) = LOC_LABEL; /* but not misused */ SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value; SYMBOL_TYPE (s) = mdebug_type_int; @@ -823,8 +753,40 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, case stProc: /* Procedure, usually goes into global block */ case stStaticProc: /* Static procedure, goes into current block */ + /* For stProc symbol records, we need to check the storage class + as well, as only (stProc, scText) entries represent "real" + procedures - See the Compaq document titled "Object File / + Symbol Table Format Specification" for more information. + If the storage class is not scText, we discard the whole block + of symbol records for this stProc. */ + if (sh->st == stProc && sh->sc != scText) + { + char *ext_tsym = ext_sh; + int keep_counting = 1; + SYMR tsym; + + while (keep_counting) + { + ext_tsym += external_sym_size; + (*swap_sym_in) (cur_bfd, ext_tsym, &tsym); + count++; + switch (tsym.st) + { + case stParam: + break; + case stEnd: + keep_counting = 0; + break; + default: + complaint (&symfile_complaints, + "unknown symbol type 0x%x", sh->st); + break; + } + } + break; + } s = new_symbol (name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; + SYMBOL_DOMAIN (s) = VAR_DOMAIN; SYMBOL_CLASS (s) = LOC_BLOCK; /* Type of the return value */ if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil) @@ -832,7 +794,8 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, else { t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name); - if (STREQ (name, "malloc") && t->code == TYPE_CODE_VOID) + if (strcmp (name, "malloc") == 0 + && TYPE_CODE (t) == TYPE_CODE_VOID) { /* I don't know why, but, at least under Alpha GNU/Linux, when linking against a malloc without debugging @@ -867,8 +830,13 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, /* Make a type for the procedure itself */ SYMBOL_TYPE (s) = lookup_function_type (t); + /* All functions in C++ have prototypes. For C we don't have enough + information in the debug info. */ + if (SYMBOL_LANGUAGE (s) == language_cplus) + TYPE_FLAGS (SYMBOL_TYPE (s)) |= TYPE_FLAG_PROTOTYPED; + /* Create and enter a new lexical context */ - b = new_block (top_stack->maxsyms); + b = new_block (FUNCTION_BLOCK); SYMBOL_BLOCK_VALUE (s) = b; BLOCK_FUNCTION (b) = s; BLOCK_START (b) = BLOCK_END (b) = sh->value; @@ -937,7 +905,28 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, switch (tsym.st) { case stEnd: - goto end_of_fields; + /* C++ encodes class types as structures where there the + methods are encoded as stProc. The scope of stProc + symbols also ends with stEnd, thus creating a risk of + taking the wrong stEnd symbol record as the end of + the current struct, which would cause GDB to undercount + the real number of fields in this struct. To make sure + we really reached the right stEnd symbol record, we + check the associated name, and match it against the + struct name. Since method names are mangled while + the class name is not, there is no risk of having a + method whose name is identical to the class name + (in particular constructor method names are different + from the class name). There is therefore no risk that + this check stops the count on the StEnd of a method. + + Also, assume that we're really at the end when tsym.iss + is 0 (issNull). */ + if (tsym.iss == issNull + || strcmp (debug_info->ss + cur_fdr->issBase + tsym.iss, + name) == 0) + goto end_of_fields; + break; case stMember: if (nfields == 0 && type_code == TYPE_CODE_UNDEF) @@ -1006,7 +995,9 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, break; default: - complain (&block_member_complaint, tsym.st); + complaint (&symfile_complaints, + "declaration block contains unhandled symbol type %d", + tsym.st); } } end_of_fields:; @@ -1068,7 +1059,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, if (sh->iss == 0 || name[0] == '.' || name[0] == '\0') TYPE_TAG_NAME (t) = NULL; else - TYPE_TAG_NAME (t) = obconcat (¤t_objfile->symbol_obstack, + TYPE_TAG_NAME (t) = obconcat (¤t_objfile->objfile_obstack, "", "", name); TYPE_CODE (t) = type_code; @@ -1111,17 +1102,18 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, FIELD_TYPE (*f) = t; FIELD_NAME (*f) = debug_info->ss + cur_fdr->issBase + tsym.iss; FIELD_BITSIZE (*f) = 0; + FIELD_STATIC_KIND (*f) = 0; enum_sym = ((struct symbol *) - obstack_alloc (¤t_objfile->symbol_obstack, + obstack_alloc (¤t_objfile->objfile_obstack, sizeof (struct symbol))); memset (enum_sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (enum_sym) = + DEPRECATED_SYMBOL_NAME (enum_sym) = obsavestring (f->name, strlen (f->name), - ¤t_objfile->symbol_obstack); + ¤t_objfile->objfile_obstack); SYMBOL_CLASS (enum_sym) = LOC_CONST; SYMBOL_TYPE (enum_sym) = t; - SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (enum_sym) = VAR_DOMAIN; SYMBOL_VALUE (enum_sym) = tsym.value; if (SYMBOL_VALUE (enum_sym) < 0) unsigned_enum = 0; @@ -1151,7 +1143,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, } s = new_symbol (name); - SYMBOL_NAMESPACE (s) = STRUCT_NAMESPACE; + SYMBOL_DOMAIN (s) = STRUCT_DOMAIN; SYMBOL_CLASS (s) = LOC_TYPEDEF; SYMBOL_VALUE (s) = 0; SYMBOL_TYPE (s) = t; @@ -1179,7 +1171,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, } top_stack->blocktype = stBlock; - b = new_block (top_stack->maxsyms); + b = new_block (NON_FUNCTION_BLOCK); BLOCK_START (b) = sh->value + top_stack->procadr; BLOCK_SUPERBLOCK (b) = top_stack->cur_block; top_stack->cur_block = b; @@ -1199,7 +1191,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, /* Finished with procedure */ struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st); struct mips_extra_func_info *e; - struct block *b; + struct block *b = top_stack->cur_block; struct type *ftype = top_stack->cur_type; int i; @@ -1207,11 +1199,11 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, /* Make up special symbol to contain procedure specific info */ s = new_symbol (MIPS_EFI_SYMBOL_NAME); - SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE; + SYMBOL_DOMAIN (s) = LABEL_DOMAIN; SYMBOL_CLASS (s) = LOC_CONST; SYMBOL_TYPE (s) = mdebug_type_void; e = ((struct mips_extra_func_info *) - obstack_alloc (¤t_objfile->symbol_obstack, + obstack_alloc (¤t_objfile->objfile_obstack, sizeof (struct mips_extra_func_info))); memset (e, 0, sizeof (struct mips_extra_func_info)); SYMBOL_VALUE (s) = (long) e; @@ -1219,9 +1211,6 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, e->pdr.framereg = -1; add_symbol (s, top_stack->cur_block); - /* Reallocate symbols, saving memory */ - b = shrink_block (top_stack->cur_block, top_stack->cur_st); - /* f77 emits proc-level with address bounds==[0,0], So look for such child blocks, and patch them. */ for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++) @@ -1246,13 +1235,17 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, if (nparams > 0) { + struct dict_iterator iter; TYPE_NFIELDS (ftype) = nparams; TYPE_FIELDS (ftype) = (struct field *) TYPE_ALLOC (ftype, nparams * sizeof (struct field)); - for (i = iparams = 0; iparams < nparams; i++) + iparams = 0; + ALL_BLOCK_SYMBOLS (b, iter, sym) { - sym = BLOCK_SYM (b, i); + if (iparams == nparams) + break; + switch (SYMBOL_CLASS (sym)) { case LOC_ARG: @@ -1276,7 +1269,6 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, displacement from the procedure`s start address of the end of this block. */ BLOCK_END (top_stack->cur_block) = sh->value + top_stack->procadr; - shrink_block (top_stack->cur_block, top_stack->cur_st); } else if (sh->sc == scText && top_stack->blocktype == stNil) { @@ -1291,7 +1283,8 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, ; } else - complain (&stEnd_complaint, sh->sc); + complaint (&symfile_complaints, + "stEnd with storage class %d not handled", sh->sc); pop_parse_stack (); /* restore previous lexical context */ break; @@ -1303,6 +1296,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, bitsize = 0; FIELD_TYPE (*f) = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name); FIELD_BITSIZE (*f) = bitsize; + FIELD_STATIC_KIND (*f) = 0; break; case stIndirect: /* forward declaration on Irix5 */ @@ -1350,7 +1344,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, if (has_opaque_xref (cur_fdr, sh)) break; s = new_symbol (name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; + SYMBOL_DOMAIN (s) = VAR_DOMAIN; SYMBOL_CLASS (s) = LOC_TYPEDEF; SYMBOL_BLOCK_VALUE (s) = top_stack->cur_block; SYMBOL_TYPE (s) = t; @@ -1385,7 +1379,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, for anything except pointers or functions. */ } else - TYPE_NAME (SYMBOL_TYPE (s)) = SYMBOL_NAME (s); + TYPE_NAME (SYMBOL_TYPE (s)) = DEPRECATED_SYMBOL_NAME (s); } break; @@ -1402,7 +1396,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend, case stConstant: break; /* constant */ default: - complain (&unknown_mdebug_symtype_complaint, sh->st); + complaint (&symfile_complaints, "unknown symbol type 0x%x", sh->st); break; } @@ -1471,7 +1465,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, /* Handle corrupt aux indices. */ if (aux_index >= (debug_info->fdr + fd)->caux) { - complain (&index_complaint, sym_name); + index_complaint (sym_name); return mdebug_type_int; } ax += aux_index; @@ -1480,7 +1474,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t); if (t->bt >= (sizeof (map_bt) / sizeof (*map_bt))) { - complain (&basic_type_complaint, t->bt, sym_name); + basic_type_complaint (t->bt, sym_name); return mdebug_type_int; } if (map_bt[t->bt]) @@ -1519,7 +1513,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, type_code = TYPE_CODE_ERROR; break; default: - complain (&basic_type_complaint, t->bt, sym_name); + basic_type_complaint (t->bt, sym_name); return mdebug_type_int; } } @@ -1530,9 +1524,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, if (t->fBitfield) { int width = AUX_GET_WIDTH (bigend, ax); - - /* Inhibit core dumps with some cfront generated objects that - corrupt the TIR. */ + /* Inhibit core dumps if TIR is corrupted. */ if (bs == (int *) NULL) { /* Alpha cc -migrate encodes char and unsigned char types @@ -1545,7 +1537,8 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, else if (t->bt == btEnum) ; else - complain (&bad_fbitfield_complaint, sym_name); + complaint (&symfile_complaints, "can't handle TIR fBitfield for %s", + sym_name); } else *bs = width; @@ -1573,7 +1566,8 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, if (rf == -1) { - complain (&bad_indirect_xref_complaint, sym_name); + complaint (&symfile_complaints, + "unable to cross ref btIndirect for %s", sym_name); return mdebug_type_int; } xref_fh = get_rfd (fd, rf); @@ -1604,7 +1598,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, dereference them. */ while (TYPE_CODE (tp) == TYPE_CODE_PTR || TYPE_CODE (tp) == TYPE_CODE_ARRAY) - tp = tp->target_type; + tp = TYPE_TARGET_TYPE (tp); /* Make sure that TYPE_CODE(tp) has an expected type code. Any type may be returned from cross_ref if file indirect entries @@ -1613,7 +1607,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, && TYPE_CODE (tp) != TYPE_CODE_UNION && TYPE_CODE (tp) != TYPE_CODE_ENUM) { - complain (&unexpected_type_code_complaint, sym_name); + unexpected_type_code_complaint (sym_name); } else { @@ -1627,7 +1621,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, || (TYPE_CODE (tp) != TYPE_CODE_ENUM && type_code == TYPE_CODE_ENUM)) { - complain (&bad_tag_guess_complaint, sym_name); + bad_tag_guess_complaint (sym_name); } if (TYPE_CODE (tp) != type_code) @@ -1640,9 +1634,9 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, if (name[0] == '.' || name[0] == '\0') TYPE_TAG_NAME (tp) = NULL; else if (TYPE_TAG_NAME (tp) == NULL - || !STREQ (TYPE_TAG_NAME (tp), name)) + || strcmp (TYPE_TAG_NAME (tp), name) != 0) TYPE_TAG_NAME (tp) = obsavestring (name, strlen (name), - ¤t_objfile->type_obstack); + ¤t_objfile->objfile_obstack); } } @@ -1664,7 +1658,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, are corrupted. */ if (TYPE_CODE (tp) != TYPE_CODE_RANGE) { - complain (&unexpected_type_code_complaint, sym_name); + unexpected_type_code_complaint (sym_name); } else { @@ -1672,12 +1666,13 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, exception is if we guessed wrong re struct/union/enum. */ if (TYPE_CODE (tp) != type_code) { - complain (&bad_tag_guess_complaint, sym_name); + bad_tag_guess_complaint (sym_name); TYPE_CODE (tp) = type_code; } - if (TYPE_NAME (tp) == NULL || !STREQ (TYPE_NAME (tp), name)) + if (TYPE_NAME (tp) == NULL + || strcmp (TYPE_NAME (tp), name) != 0) TYPE_NAME (tp) = obsavestring (name, strlen (name), - ¤t_objfile->type_obstack); + ¤t_objfile->objfile_obstack); } } if (t->bt == btTypedef) @@ -1688,7 +1683,8 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name); if (tp == (struct type *) NULL) { - complain (&unable_to_cross_ref_complaint, sym_name); + complaint (&symfile_complaints, + "unable to cross ref btTypedef for %s", sym_name); tp = mdebug_type_int; } } @@ -1700,11 +1696,11 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, TYPE_FIELDS (tp) = ((struct field *) TYPE_ALLOC (tp, 2 * sizeof (struct field))); TYPE_FIELD_NAME (tp, 0) = obsavestring ("Low", strlen ("Low"), - ¤t_objfile->type_obstack); + ¤t_objfile->objfile_obstack); TYPE_FIELD_BITPOS (tp, 0) = AUX_GET_DNLOW (bigend, ax); ax++; TYPE_FIELD_NAME (tp, 1) = obsavestring ("High", strlen ("High"), - ¤t_objfile->type_obstack); + ¤t_objfile->objfile_obstack); TYPE_FIELD_BITPOS (tp, 1) = AUX_GET_DNHIGH (bigend, ax); ax++; } @@ -1738,7 +1734,7 @@ parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs, /* Complain for illegal continuations due to corrupt aux entries. */ if (t->continued) - complain (&bad_continued_complaint, sym_name); + complaint (&symfile_complaints, "illegal TIR continued for %s", sym_name); return tp; } @@ -1800,7 +1796,8 @@ upgrade_type (int fd, struct type **tpp, int tq, union aux_ext *ax, int bigend, else due to corrupt aux entries. */ if (TYPE_CODE (indx) != TYPE_CODE_INT) { - complain (&array_index_type_complaint, sym_name); + complaint (&symfile_complaints, + "illegal array index type for %s, assuming int", sym_name); indx = mdebug_type_int; } @@ -1850,7 +1847,7 @@ upgrade_type (int fd, struct type **tpp, int tq, union aux_ext *ax, int bigend, return 0; default: - complain (&unknown_type_qual_complaint, tq); + complaint (&symfile_complaints, "unknown type qualifier 0x%x", tq); return 0; } } @@ -1885,7 +1882,9 @@ parse_procedure (PDR *pr, struct symtab *search_symtab, { /* Static procedure at address pr->adr. Sigh. */ /* FIXME-32x64. assuming pr->adr fits in long. */ - complain (&pdr_static_symbol_complaint, (unsigned long) pr->adr); + complaint (&symfile_complaints, + "can't handle PDR for static proc at 0x%lx", + (unsigned long) pr->adr); return; } else @@ -1925,19 +1924,19 @@ parse_procedure (PDR *pr, struct symtab *search_symtab, the same name exists, lookup_symbol will eventually read in the symtab for the global function and clobber cur_fdr. */ FDR *save_cur_fdr = cur_fdr; - s = lookup_symbol (sh_name, NULL, VAR_NAMESPACE, 0, NULL); + s = lookup_symbol (sh_name, NULL, VAR_DOMAIN, 0, NULL); cur_fdr = save_cur_fdr; #else s = mylookup_symbol (sh_name, BLOCKVECTOR_BLOCK (BLOCKVECTOR (search_symtab), STATIC_BLOCK), - VAR_NAMESPACE, + VAR_DOMAIN, LOC_BLOCK); #endif } else s = mylookup_symbol (sh_name, top_stack->cur_block, - VAR_NAMESPACE, LOC_BLOCK); + VAR_DOMAIN, LOC_BLOCK); if (s != 0) { @@ -1945,13 +1944,13 @@ parse_procedure (PDR *pr, struct symtab *search_symtab, } else { - complain (&pdr_for_nonsymbol_complaint, sh_name); + complaint (&symfile_complaints, "PDR for %s, but no symbol", sh_name); #if 1 return; #else /* FIXME -- delete. We can't do symbol allocation now; it's all done. */ s = new_symbol (sh_name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; + SYMBOL_DOMAIN (s) = VAR_DOMAIN; SYMBOL_CLASS (s) = LOC_BLOCK; /* Donno its type, hope int is ok */ SYMBOL_TYPE (s) = lookup_function_type (mdebug_type_int); @@ -1969,7 +1968,7 @@ parse_procedure (PDR *pr, struct symtab *search_symtab, #endif } - i = mylookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, LOC_CONST); + i = mylookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, LOC_CONST); if (i) { @@ -1991,9 +1990,10 @@ parse_procedure (PDR *pr, struct symtab *search_symtab, /* Correct incorrect setjmp procedure descriptor from the library to make backtrace through setjmp work. */ - if (e->pdr.pcreg == 0 && STREQ (sh_name, "setjmp")) + if (e->pdr.pcreg == 0 + && strcmp (sh_name, "setjmp") == 0) { - complain (&bad_setjmp_pdr_complaint, 0); + complaint (&symfile_complaints, "fixing bad setjmp PDR from libc"); e->pdr.pcreg = RA_REGNUM; e->pdr.regmask = 0x80000000; e->pdr.regoffset = -4; @@ -2168,7 +2168,7 @@ parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines, halt = base + fh->cbLine; base += pr->cbLineOffset; - adr = TEXTLOW (pst) + pr->adr - lowest_pdr_addr; + adr = pst->textlow + pr->adr - lowest_pdr_addr; l = adr >> 2; /* in words */ for (lineno = pr->lnLow; base < halt;) @@ -2190,7 +2190,9 @@ parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines, with corrupt binaries. */ if (lt->nitems >= maxlines) { - complain (&bad_linetable_guess_complaint, fdr_name (fh)); + complaint (&symfile_complaints, + "guessed size of linetable for %s incorrectly", + fdr_name (fh)); break; } k = add_line (lt, lineno, l, k); @@ -2199,6 +2201,14 @@ parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines, } } +static void +function_outside_compilation_unit_complaint (const char *arg1) +{ + complaint (&symfile_complaints, + "function `%s' appears to be defined outside of all compilation units", + arg1); +} + /* Master parsing procedure for first-pass reading of file symbols into a partial_symtab. */ @@ -2218,7 +2228,7 @@ parse_partial_symbols (struct objfile *objfile) char *ext_out; char *ext_out_end; EXTR *ext_block; - register EXTR *ext_in; + EXTR *ext_in; EXTR *ext_in_end; SYMR sh; struct partial_symtab *pst; @@ -2251,7 +2261,7 @@ parse_partial_symbols (struct objfile *objfile) && (bfd_get_section_flags (cur_bfd, text_sect) & SEC_RELOC)) relocatable = 1; - extern_tab = (EXTR *) obstack_alloc (&objfile->psymbol_obstack, + extern_tab = (EXTR *) obstack_alloc (&objfile->objfile_obstack, sizeof (EXTR) * hdr->iextMax); includes_allocated = 30; @@ -2295,7 +2305,7 @@ parse_partial_symbols (struct objfile *objfile) /* Allocate the global pending list. */ pending_list = ((struct mdebug_pending **) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, hdr->ifdMax * sizeof (struct mdebug_pending *))); memset (pending_list, 0, hdr->ifdMax * sizeof (struct mdebug_pending *)); @@ -2375,13 +2385,16 @@ parse_partial_symbols (struct objfile *objfile) external symbols. */ if (ext_in->ifd < -1 || ext_in->ifd >= hdr->ifdMax) { - complain (&bad_ext_ifd_complaint, ext_in->ifd, hdr->ifdMax); + complaint (&symfile_complaints, + "bad ifd for external symbol: %d (max %ld)", ext_in->ifd, + hdr->ifdMax); continue; } if (ext_in->asym.iss < 0 || ext_in->asym.iss >= hdr->issExtMax) { - complain (&bad_ext_iss_complaint, ext_in->asym.iss, - hdr->issExtMax); + complaint (&symfile_complaints, + "bad iss for external symbol: %ld (max %ld)", + ext_in->asym.iss, hdr->issExtMax); continue; } @@ -2507,7 +2520,7 @@ parse_partial_symbols (struct objfile *objfile) /* Fall through. */ default: ms_type = mst_unknown; - complain (&unknown_ext_complaint, name); + unknown_ext_complaint (name); } if (!ECOFF_IN_ELF (cur_bfd)) prim_record_minimal_symbol (name, svalue, ms_type, objfile); @@ -2544,13 +2557,11 @@ parse_partial_symbols (struct objfile *objfile) objfile->global_psymbols.next, objfile->static_psymbols.next); pst->read_symtab_private = ((char *) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc))); memset (pst->read_symtab_private, 0, sizeof (struct symloc)); save_pst = pst; - TEXTLOW (pst) = pst->textlow; - TEXTHIGH (pst) = pst->texthigh; FDR_IDX (pst) = f_idx; CUR_BFD (pst) = cur_bfd; DEBUG_SWAP (pst) = debug_swap; @@ -2586,7 +2597,7 @@ parse_partial_symbols (struct objfile *objfile) psymtab_language = prev_language; PST_PRIVATE (pst)->pst_language = psymtab_language; - TEXTHIGH (pst) = TEXTLOW (pst); + pst->texthigh = pst->textlow; /* For stabs-in-ecoff files, the second symbol must be @stab. This symbol is emitted by mips-tfile to signal that the @@ -2601,7 +2612,8 @@ parse_partial_symbols (struct objfile *objfile) ((char *) debug_info->external_sym + (fh->isymBase + 1) * external_sym_size), &sh); - if (STREQ (debug_info->ss + fh->issBase + sh.iss, stabs_symbol)) + if (strcmp (debug_info->ss + fh->issBase + sh.iss, + stabs_symbol) == 0) processing_gcc_compilation = 2; } @@ -2653,10 +2665,10 @@ parse_partial_symbols (struct objfile *objfile) /* Kludge for Irix 5.2 zero fh->adr. */ if (!relocatable - && (TEXTLOW (pst) == 0 || procaddr < TEXTLOW (pst))) - TEXTLOW (pst) = procaddr; - if (high > TEXTHIGH (pst)) - TEXTHIGH (pst) = high; + && (pst->textlow == 0 || procaddr < pst->textlow)) + pst->textlow = procaddr; + if (high > pst->texthigh) + pst->texthigh = high; } } else if (sh.st == stStatic) @@ -2741,9 +2753,6 @@ parse_partial_symbols (struct objfile *objfile) switch (type_code) { - static struct complaint function_outside_compilation_unit = { - "function `%s' appears to be defined outside of all compilation units", 0, 0 - }; char *p; /* * Standard, external, non-debugger, symbols @@ -2925,12 +2934,13 @@ parse_partial_symbols (struct objfile *objfile) things like "break c-exp.y:435" need to work (I suppose the psymtab_include_list could be hashed or put in a binary tree, if profiling shows this is a major hog). */ - if (pst && STREQ (namestring, pst->filename)) + if (pst && strcmp (namestring, pst->filename) == 0) continue; { - register int i; + int i; for (i = 0; i < includes_used; i++) - if (STREQ (namestring, psymtab_include_list[i])) + if (strcmp (namestring, + psymtab_include_list[i]) == 0) { i = -1; break; @@ -2947,7 +2957,7 @@ parse_partial_symbols (struct objfile *objfile) psymtab_include_list = (char **) alloca ((includes_allocated *= 2) * sizeof (char *)); - memcpy ((PTR) psymtab_include_list, (PTR) orig, + memcpy (psymtab_include_list, orig, includes_used * sizeof (char *)); } continue; @@ -2993,7 +3003,7 @@ parse_partial_symbols (struct objfile *objfile) namestring = STATIC_TRANSFORM_NAME (namestring); #endif add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, + VAR_DOMAIN, LOC_STATIC, &objfile->static_psymbols, 0, sh.value, psymtab_language, objfile); @@ -3003,7 +3013,7 @@ parse_partial_symbols (struct objfile *objfile) /* The addresses in these entries are reported to be wrong. See the code that reads 'G's for symtabs. */ add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, + VAR_DOMAIN, LOC_STATIC, &objfile->global_psymbols, 0, sh.value, psymtab_language, objfile); @@ -3021,7 +3031,7 @@ parse_partial_symbols (struct objfile *objfile) && namestring[0] != ' ')) { add_psymbol_to_list (namestring, p - namestring, - STRUCT_NAMESPACE, LOC_TYPEDEF, + STRUCT_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, sh.value, 0, psymtab_language, objfile); @@ -3029,33 +3039,19 @@ parse_partial_symbols (struct objfile *objfile) { /* Also a typedef with the same name. */ add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, sh.value, 0, psymtab_language, objfile); p += 1; } - /* The semantics of C++ state that "struct foo { ... }" - also defines a typedef for "foo". Unfortuantely, cfront - never makes the typedef when translating from C++ to C. - We make the typedef here so that "ptype foo" works as - expected for cfront translated code. */ - else if (psymtab_language == language_cplus) - { - /* Also a typedef with the same name. */ - add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - sh.value, 0, - psymtab_language, objfile); - } } goto check_enum; case 't': if (p != namestring) /* a name is there, not just :T... */ { add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, + VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, sh.value, 0, psymtab_language, objfile); @@ -3117,7 +3113,7 @@ parse_partial_symbols (struct objfile *objfile) /* Note that the value doesn't matter for enum constants in psymtabs, just in symtabs. */ add_psymbol_to_list (p, q - p, - VAR_NAMESPACE, LOC_CONST, + VAR_DOMAIN, LOC_CONST, &objfile->static_psymbols, 0, 0, psymtab_language, objfile); /* Point past the name. */ @@ -3134,7 +3130,7 @@ parse_partial_symbols (struct objfile *objfile) case 'c': /* Constant, e.g. from "const" in Pascal. */ add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, + VAR_DOMAIN, LOC_CONST, &objfile->static_psymbols, sh.value, 0, psymtab_language, objfile); continue; @@ -3146,12 +3142,12 @@ parse_partial_symbols (struct objfile *objfile) char *name = xmalloc (name_len + 1); memcpy (name, namestring, name_len); name[name_len] = '\0'; - complain (&function_outside_compilation_unit, name); + function_outside_compilation_unit_complaint (name); xfree (name); } sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->static_psymbols, 0, sh.value, psymtab_language, objfile); @@ -3167,12 +3163,12 @@ parse_partial_symbols (struct objfile *objfile) char *name = xmalloc (name_len + 1); memcpy (name, namestring, name_len); name[name_len] = '\0'; - complain (&function_outside_compilation_unit, name); + function_outside_compilation_unit_complaint (name); xfree (name); } sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); add_psymbol_to_list (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->global_psymbols, 0, sh.value, psymtab_language, objfile); @@ -3195,9 +3191,6 @@ parse_partial_symbols (struct objfile *objfile) case '9': case '-': case '#': /* for symbol identification (used in live ranges) */ - /* added to support cfront stabs strings */ - case 'Z': /* for definition continuations */ - case 'P': /* for prototypes */ continue; case ':': @@ -3218,7 +3211,8 @@ parse_partial_symbols (struct objfile *objfile) time searching to the end of every string looking for a backslash. */ - complain (&unknown_symchar_complaint, p[1]); + complaint (&symfile_complaints, + "unknown symbol descriptor `%c'", p[1]); /* Ignore it; perhaps it is an extension that we don't know about. */ @@ -3230,10 +3224,11 @@ parse_partial_symbols (struct objfile *objfile) case N_ENDM: #ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* Solaris 2 end of module, finish current partial symbol table. - END_PSYMTAB will set TEXTHIGH (pst) to the proper value, which - is necessary if a module compiled without debugging info - follows this module. */ + /* Solaris 2 end of module, finish current partial + symbol table. END_PSYMTAB will set + pst->texthigh to the proper value, which is + necessary if a module compiled without + debugging info follows this module. */ if (pst) { pst = (struct partial_symtab *) 0; @@ -3244,8 +3239,8 @@ parse_partial_symbols (struct objfile *objfile) continue; case N_RBRAC: - if (sh.value > TEXTHIGH (save_pst)) - TEXTHIGH (save_pst) = sh.value; + if (sh.value > save_pst->texthigh) + save_pst->texthigh = sh.value; continue; case N_EINCL: case N_DSLINE: @@ -3278,8 +3273,8 @@ parse_partial_symbols (struct objfile *objfile) default: /* If we haven't found it yet, ignore it. It's probably some new type we don't know about yet. */ - complain (&unknown_symtype_complaint, - local_hex_string (type_code)); /*CUR_SYMBOL_TYPE*/ + complaint (&symfile_complaints, "unknown symbol type %s", + local_hex_string (type_code)); /*CUR_SYMBOL_TYPE*/ continue; } if (stabstring @@ -3357,6 +3352,39 @@ parse_partial_symbols (struct objfile *objfile) /* FALLTHROUGH */ case stProc: + /* Ignore all parameter symbol records. */ + if (sh.index >= hdr->iauxMax) + { + /* Should not happen, but does when cross-compiling + with the MIPS compiler. FIXME -- pull later. */ + index_complaint (name); + new_sdx = cur_sdx + 1; /* Don't skip at all */ + } + else + new_sdx = AUX_GET_ISYM (fh->fBigendian, + (debug_info->external_aux + + fh->iauxBase + + sh.index)); + + if (new_sdx <= cur_sdx) + { + /* This should not happen either... FIXME. */ + complaint (&symfile_complaints, + "bad proc end in aux found from symbol %s", + name); + new_sdx = cur_sdx + 1; /* Don't skip backward */ + } + + /* For stProc symbol records, we need to check the + storage class as well, as only (stProc, scText) + entries represent "real" procedures - See the + Compaq document titled "Object File / Symbol Table + Format Specification" for more information. If the + storage class is not scText, we discard the whole + block of symbol records for this stProc. */ + if (sh.st == stProc && sh.sc != scText) + goto skip; + /* Usually there is a local and a global stProc symbol for a function. This means that the function name has already been entered into the mimimal symbol table @@ -3370,37 +3398,17 @@ parse_partial_symbols (struct objfile *objfile) symbol table. */ if (sh.st == stProc) add_psymbol_to_list (name, strlen (name), - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->global_psymbols, 0, sh.value, psymtab_language, objfile); else add_psymbol_to_list (name, strlen (name), - VAR_NAMESPACE, LOC_BLOCK, + VAR_DOMAIN, LOC_BLOCK, &objfile->static_psymbols, 0, sh.value, psymtab_language, objfile); - /* Skip over procedure to next one. */ - if (sh.index >= hdr->iauxMax) - { - /* Should not happen, but does when cross-compiling - with the MIPS compiler. FIXME -- pull later. */ - complain (&index_complaint, name); - new_sdx = cur_sdx + 1; /* Don't skip at all */ - } - else - new_sdx = AUX_GET_ISYM (fh->fBigendian, - (debug_info->external_aux - + fh->iauxBase - + sh.index)); procaddr = sh.value; - if (new_sdx <= cur_sdx) - { - /* This should not happen either... FIXME. */ - complain (&aux_index_complaint, name); - new_sdx = cur_sdx + 1; /* Don't skip backward */ - } - cur_sdx = new_sdx; (*swap_sym_in) (cur_bfd, ((char *) debug_info->external_sym @@ -3412,12 +3420,12 @@ parse_partial_symbols (struct objfile *objfile) /* Kludge for Irix 5.2 zero fh->adr. */ if (!relocatable - && (TEXTLOW (pst) == 0 || procaddr < TEXTLOW (pst))) - TEXTLOW (pst) = procaddr; + && (pst->textlow == 0 || procaddr < pst->textlow)) + pst->textlow = procaddr; high = procaddr + sh.value; - if (high > TEXTHIGH (pst)) - TEXTHIGH (pst) = high; + if (high > pst->texthigh) + pst->texthigh = high; continue; case stStatic: /* Variable */ @@ -3464,7 +3472,7 @@ parse_partial_symbols (struct objfile *objfile) && sh.index != cur_sdx + 2) { add_psymbol_to_list (name, strlen (name), - STRUCT_NAMESPACE, LOC_TYPEDEF, + STRUCT_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, 0, (CORE_ADDR) 0, psymtab_language, objfile); @@ -3476,7 +3484,8 @@ parse_partial_symbols (struct objfile *objfile) if (new_sdx <= cur_sdx) { /* This happens with the Ultrix kernel. */ - complain (&block_index_complaint, name); + complaint (&symfile_complaints, + "bad aux index at block symbol %s", name); new_sdx = cur_sdx + 1; /* Don't skip backward */ } cur_sdx = new_sdx; @@ -3496,14 +3505,15 @@ parse_partial_symbols (struct objfile *objfile) default: /* Both complaints are valid: one gives symbol name, the other the offending symbol type. */ - complain (&unknown_sym_complaint, name); - complain (&unknown_st_complaint, sh.st); + complaint (&symfile_complaints, "unknown local symbol %s", + name); + complaint (&symfile_complaints, "with type %d", sh.st); cur_sdx++; continue; } /* Use this gdb symbol */ add_psymbol_to_list (name, strlen (name), - VAR_NAMESPACE, class, + VAR_DOMAIN, class, &objfile->static_psymbols, 0, sh.value, psymtab_language, objfile); skip: @@ -3566,8 +3576,7 @@ parse_partial_symbols (struct objfile *objfile) class = LOC_LABEL; break; default: - complain (&unknown_ext_complaint, - debug_info->ssext + psh->iss); + unknown_ext_complaint (debug_info->ssext + psh->iss); /* Fall through, pretend it's global. */ case stGlobal: /* Global common symbols are resolved by the runtime loader, @@ -3580,7 +3589,7 @@ parse_partial_symbols (struct objfile *objfile) } name = debug_info->ssext + psh->iss; add_psymbol_to_list (name, strlen (name), - VAR_NAMESPACE, class, + VAR_DOMAIN, class, &objfile->global_psymbols, 0, svalue, psymtab_language, objfile); @@ -3591,16 +3600,16 @@ parse_partial_symbols (struct objfile *objfile) empty and put on the free list. */ fdr_to_pst[f_idx].pst = end_psymtab (save_pst, psymtab_include_list, includes_used, - -1, TEXTHIGH (save_pst), + -1, save_pst->texthigh, dependency_list, dependencies_used, textlow_not_set); includes_used = 0; dependencies_used = 0; - if (objfile->ei.entry_point >= TEXTLOW (save_pst) && - objfile->ei.entry_point < TEXTHIGH (save_pst)) + if (objfile->ei.entry_point >= save_pst->textlow && + objfile->ei.entry_point < save_pst->texthigh) { - objfile->ei.entry_file_lowpc = TEXTLOW (save_pst); - objfile->ei.entry_file_highpc = TEXTHIGH (save_pst); + objfile->ei.deprecated_entry_file_lowpc = save_pst->textlow; + objfile->ei.deprecated_entry_file_highpc = save_pst->texthigh; } /* The objfile has its functions reordered if this partial symbol @@ -3616,15 +3625,15 @@ parse_partial_symbols (struct objfile *objfile) other cases. */ save_pst = fdr_to_pst[f_idx].pst; if (save_pst != NULL - && TEXTLOW (save_pst) != 0 + && save_pst->textlow != 0 && !(objfile->flags & OBJF_REORDERED)) { ALL_OBJFILE_PSYMTABS (objfile, pst) { if (save_pst != pst - && TEXTLOW (save_pst) >= TEXTLOW (pst) - && TEXTLOW (save_pst) < TEXTHIGH (pst) - && TEXTHIGH (save_pst) > TEXTHIGH (pst)) + && save_pst->textlow >= pst->textlow + && save_pst->textlow < pst->texthigh + && save_pst->texthigh > pst->texthigh) { objfile->flags |= OBJF_REORDERED; break; @@ -3651,7 +3660,7 @@ parse_partial_symbols (struct objfile *objfile) pst->number_of_dependencies = 0; pst->dependencies = ((struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, ((fh->crfd - 1) * sizeof (struct partial_symtab *)))); for (s_idx = 1; s_idx < fh->crfd; s_idx++) @@ -3664,7 +3673,7 @@ parse_partial_symbols (struct objfile *objfile) &rh); if (rh < 0 || rh >= hdr->ifdMax) { - complain (&bad_file_number_complaint, rh); + complaint (&symfile_complaints, "bad file number %ld", rh); continue; } @@ -3750,7 +3759,7 @@ handle_psymbol_enumerators (struct objfile *objfile, FDR *fh, int stype, /* Note that the value doesn't matter for enum constants in psymtabs, just in symtabs. */ add_psymbol_to_list (name, strlen (name), - VAR_NAMESPACE, LOC_CONST, + VAR_DOMAIN, LOC_CONST, &objfile->static_psymbols, 0, (CORE_ADDR) 0, psymtab_language, objfile); ext_sym += external_sym_size; @@ -3828,7 +3837,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) /* Do nothing if this is a dummy psymtab. */ if (pst->n_global_syms == 0 && pst->n_static_syms == 0 - && TEXTLOW (pst) == 0 && TEXTHIGH (pst) == 0) + && pst->textlow == 0 && pst->texthigh == 0) return; /* Now read the symbols for this symtab */ @@ -3858,8 +3867,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) ((char *) debug_info->external_sym + (fh->isymBase + 1) * external_sym_size), &sh); - if (STREQ (debug_info->ss + fh->issBase + sh.iss, - stabs_symbol)) + if (strcmp (debug_info->ss + fh->issBase + sh.iss, + stabs_symbol) == 0) { /* We indicate that this is a GCC compilation so that certain features will be enabled in stabsread/dbxread. */ @@ -3938,12 +3947,12 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) procedure specific info */ struct mips_extra_func_info *e = ((struct mips_extra_func_info *) - obstack_alloc (¤t_objfile->symbol_obstack, + obstack_alloc (¤t_objfile->objfile_obstack, sizeof (struct mips_extra_func_info))); struct symbol *s = new_symbol (MIPS_EFI_SYMBOL_NAME); memset (e, 0, sizeof (struct mips_extra_func_info)); - SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE; + SYMBOL_DOMAIN (s) = LABEL_DOMAIN; SYMBOL_CLASS (s) = LOC_CONST; SYMBOL_TYPE (s) = mdebug_type_void; SYMBOL_VALUE (s) = (long) e; @@ -3971,19 +3980,15 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) /* These are generated by gcc-2.x, do not complain */ ; else - complain (&stab_unknown_complaint, name); + complaint (&symfile_complaints, "unknown stabs symbol %s", name); } if (! last_symtab_ended) { - st = end_symtab (TEXTHIGH (pst), pst->objfile, SECT_OFF_TEXT (pst->objfile)); + st = end_symtab (pst->texthigh, pst->objfile, SECT_OFF_TEXT (pst->objfile)); end_stabs (); } - /* Sort the symbol table now, we are done adding symbols to it. - We must do this before parse_procedure calls lookup_symbol. */ - sort_symtab_syms (st); - /* There used to be a call to sort_blocks here, but this should not be necessary for stabs symtabs. And as sort_blocks modifies the start address of the GLOBAL_BLOCK to the FIRST_LOCAL_BLOCK, @@ -4037,19 +4042,15 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) int maxlines; EXTR *ext_ptr; - /* How many symbols will we need */ - /* FIXME, this does not count enum values. */ - f_max = pst->n_global_syms + pst->n_static_syms; if (fh == 0) { maxlines = 0; - st = new_symtab ("unknown", f_max, 0, pst->objfile); + st = new_symtab ("unknown", 0, pst->objfile); } else { - f_max += fh->csym + fh->cpd; maxlines = 2 * fh->cline; - st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile); + st = new_symtab (pst->filename, maxlines, pst->objfile); /* The proper language was already determined when building the psymtab, use it. */ @@ -4066,10 +4067,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) top_stack->cur_st = st; top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (st), STATIC_BLOCK); - BLOCK_START (top_stack->cur_block) = TEXTLOW (pst); + BLOCK_START (top_stack->cur_block) = pst->textlow; BLOCK_END (top_stack->cur_block) = 0; top_stack->blocktype = stFile; - top_stack->maxsyms = 2 * f_max; top_stack->cur_type = 0; top_stack->procadr = 0; top_stack->numargs = 0; @@ -4153,10 +4153,6 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st), GLOBAL_BLOCK); top_stack->blocktype = stFile; - top_stack->maxsyms - = (debug_info->symbolic_header.isymMax - + debug_info->symbolic_header.ipdMax - + debug_info->symbolic_header.iextMax); ext_ptr = PST_PRIVATE (pst)->extern_tab; for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++) @@ -4178,9 +4174,6 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename) st->primary = 1; - /* Sort the symbol table now, we are done adding symbols to it. */ - sort_symtab_syms (st); - sort_blocks (st); } @@ -4282,8 +4275,7 @@ cross_ref (int fd, union aux_ext *ax, struct type **tpp, enum type_code type_cod { /* File indirect entry is corrupt. */ *pname = ""; - complain (&bad_rfd_entry_complaint, - sym_name, xref_fd, rn->index); + bad_rfd_entry_complaint (sym_name, xref_fd, rn->index); return result; } @@ -4307,8 +4299,7 @@ cross_ref (int fd, union aux_ext *ax, struct type **tpp, enum type_code type_cod { /* File indirect entry is corrupt. */ *pname = ""; - complain (&bad_rfd_entry_complaint, - sym_name, xref_fd, rn->index); + bad_rfd_entry_complaint (sym_name, xref_fd, rn->index); return result; } @@ -4344,7 +4335,8 @@ cross_ref (int fd, union aux_ext *ax, struct type **tpp, enum type_code type_cod + fh->iauxBase + sh.index)->a_ti, &tir); if (tir.tq0 != tqNil) - complain (&illegal_forward_tq0_complaint, sym_name); + complaint (&symfile_complaints, + "illegal tq0 in forward typedef for %s", sym_name); switch (tir.bt) { case btVoid: @@ -4381,7 +4373,9 @@ cross_ref (int fd, union aux_ext *ax, struct type **tpp, enum type_code type_cod break; default: - complain (&illegal_forward_bt_complaint, tir.bt, sym_name); + complaint (&symfile_complaints, + "illegal bt %d in forward typedef for %s", tir.bt, + sym_name); *tpp = init_type (type_code, 0, 0, (char *) NULL, current_objfile); break; @@ -4425,63 +4419,36 @@ cross_ref (int fd, union aux_ext *ax, struct type **tpp, enum type_code type_cod keeping the symtab sorted */ static struct symbol * -mylookup_symbol (char *name, register struct block *block, - namespace_enum namespace, enum address_class class) +mylookup_symbol (char *name, struct block *block, + domain_enum domain, enum address_class class) { - int i, inc; + struct dict_iterator iter; + int inc; struct symbol *sym; inc = name[0]; - ALL_BLOCK_SYMBOLS (block, i, sym) + ALL_BLOCK_SYMBOLS (block, iter, sym) { - if (SYMBOL_NAME (sym)[0] == inc - && SYMBOL_NAMESPACE (sym) == namespace + if (DEPRECATED_SYMBOL_NAME (sym)[0] == inc + && SYMBOL_DOMAIN (sym) == domain && SYMBOL_CLASS (sym) == class - && strcmp (SYMBOL_NAME (sym), name) == 0) + && strcmp (DEPRECATED_SYMBOL_NAME (sym), name) == 0) return sym; } block = BLOCK_SUPERBLOCK (block); if (block) - return mylookup_symbol (name, block, namespace, class); + return mylookup_symbol (name, block, domain, class); return 0; } -/* Add a new symbol S to a block B. - Infrequently, we will need to reallocate the block to make it bigger. - We only detect this case when adding to top_stack->cur_block, since - that's the only time we know how big the block is. FIXME. */ +/* Add a new symbol S to a block B. */ static void add_symbol (struct symbol *s, struct block *b) { - int nsyms = BLOCK_NSYMS (b)++; - struct block *origb; - struct parse_stack *stackp; - - if (b == top_stack->cur_block && - nsyms >= top_stack->maxsyms) - { - complain (&block_overflow_complaint, SYMBOL_NAME (s)); - /* In this case shrink_block is actually grow_block, since - BLOCK_NSYMS(b) is larger than its current size. */ - origb = b; - b = shrink_block (top_stack->cur_block, top_stack->cur_st); - - /* Now run through the stack replacing pointers to the - original block. shrink_block has already done this - for the blockvector and BLOCK_FUNCTION. */ - for (stackp = top_stack; stackp; stackp = stackp->next) - { - if (stackp->cur_block == origb) - { - stackp->cur_block = b; - stackp->maxsyms = BLOCK_NSYMS (b); - } - } - } - BLOCK_SYM (b, nsyms) = s; + dict_add_symbol (BLOCK_DICT (b), s); } /* Add a new block B to a symtab S */ @@ -4541,7 +4508,7 @@ add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last) static int compare_blocks (const void *arg1, const void *arg2) { - register int addr_diff; + LONGEST addr_diff; struct block **b1 = (struct block **) arg1; struct block **b2 = (struct block **) arg2; @@ -4582,8 +4549,8 @@ sort_blocks (struct symtab *s) compare_blocks); { - register CORE_ADDR high = 0; - register int i, j = BLOCKVECTOR_NBLOCKS (bv); + CORE_ADDR high = 0; + int i, j = BLOCKVECTOR_NBLOCKS (bv); for (i = FIRST_LOCAL_BLOCK; i < j; i++) if (high < BLOCK_END (BLOCKVECTOR_BLOCK (bv, i))) @@ -4603,11 +4570,11 @@ sort_blocks (struct symtab *s) /* Constructor/restructor/destructor procedures */ -/* Allocate a new symtab for NAME. Needs an estimate of how many symbols - MAXSYMS and linenumbers MAXLINES we'll put in it */ +/* Allocate a new symtab for NAME. Needs an estimate of how many + linenumbers MAXLINES we'll put in it */ static struct symtab * -new_symtab (char *name, int maxsyms, int maxlines, struct objfile *objfile) +new_symtab (char *name, int maxlines, struct objfile *objfile) { struct symtab *s = allocate_symtab (name, objfile); @@ -4615,14 +4582,16 @@ new_symtab (char *name, int maxsyms, int maxlines, struct objfile *objfile) /* All symtabs must have at least two blocks */ BLOCKVECTOR (s) = new_bvect (2); - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK) = new_block (maxsyms); - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) = new_block (maxsyms); + BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK) + = new_block (NON_FUNCTION_BLOCK); + BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) + = new_block (NON_FUNCTION_BLOCK); BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)) = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); s->free_code = free_linetable; s->debugformat = obsavestring ("ECOFF", 5, - &objfile->symbol_obstack); + &objfile->objfile_obstack); return (s); } @@ -4639,7 +4608,7 @@ new_psymtab (char *name, struct objfile *objfile) /* Keep a backpointer to the file's symbols */ psymtab->read_symtab_private = ((char *) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc))); memset (psymtab->read_symtab_private, 0, sizeof (struct symloc)); CUR_BFD (psymtab) = cur_bfd; @@ -4700,43 +4669,25 @@ new_bvect (int nblocks) return bv; } -/* Allocate and zero a new block of MAXSYMS symbols */ +/* Allocate and zero a new block, and set its BLOCK_DICT. If function + is non-zero, assume the block is associated to a function, and make + sure that the symbols are stored linearly; otherwise, store them + hashed. */ static struct block * -new_block (int maxsyms) +new_block (enum block_type type) { - int size = sizeof (struct block) + (maxsyms - 1) * sizeof (struct symbol *); + /* FIXME: carlton/2003-09-11: This should use allocate_block to + allocate the block. Which, in turn, suggests that the block + should be allocated on an obstack. */ + struct block *retval = xzalloc (sizeof (struct block)); - return (struct block *) xzalloc (size); -} + if (type == FUNCTION_BLOCK) + BLOCK_DICT (retval) = dict_create_linear_expandable (); + else + BLOCK_DICT (retval) = dict_create_hashed_expandable (); -/* Ooops, too big. Shrink block B in symtab S to its minimal size. - Shrink_block can also be used by add_symbol to grow a block. */ - -static struct block * -shrink_block (struct block *b, struct symtab *s) -{ - struct block *new; - struct blockvector *bv = BLOCKVECTOR (s); - int i; - - /* Just reallocate it and fix references to the old one */ - - new = (struct block *) xrealloc ((void *) b, - (sizeof (struct block) - + ((BLOCK_NSYMS (b) - 1) - * sizeof (struct symbol *)))); - - /* Should chase pointers to old one. Fortunately, that`s just - the block`s function and inferior blocks */ - if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b) - SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) = new; - for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++) - if (BLOCKVECTOR_BLOCK (bv, i) == b) - BLOCKVECTOR_BLOCK (bv, i) = new; - else if (BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) == b) - BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) = new; - return new; + return retval; } /* Create a new symbol with printname NAME */ @@ -4745,14 +4696,12 @@ static struct symbol * new_symbol (char *name) { struct symbol *s = ((struct symbol *) - obstack_alloc (¤t_objfile->symbol_obstack, + obstack_alloc (¤t_objfile->objfile_obstack, sizeof (struct symbol))); memset (s, 0, sizeof (*s)); - SYMBOL_NAME (s) = obsavestring (name, strlen (name), - ¤t_objfile->symbol_obstack); SYMBOL_LANGUAGE (s) = psymtab_language; - SYMBOL_INIT_DEMANGLED_NAME (s, ¤t_objfile->symbol_obstack); + SYMBOL_SET_NAMES (s, name, strlen (name), current_objfile); return s; } @@ -4780,9 +4729,17 @@ elfmdebug_build_psymtabs (struct objfile *objfile, { bfd *abfd = objfile->obfd; struct ecoff_debug_info *info; + struct cleanup *back_to; + + /* FIXME: It's not clear whether we should be getting minimal symbol + information from .mdebug in an ELF file, or whether we will. + Re-initialize the minimal symbol reader in case we do. */ + + init_minimal_symbol_collection (); + back_to = make_cleanup_discard_minimal_symbols (); info = ((struct ecoff_debug_info *) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct ecoff_debug_info))); if (!(*swap->read_debug_info) (abfd, sec, info)) @@ -4790,6 +4747,9 @@ elfmdebug_build_psymtabs (struct objfile *objfile, bfd_errmsg (bfd_get_error ())); mdebug_build_psymtabs (objfile, swap, info); + + install_minimal_symbols (objfile); + do_cleanups (back_to); } @@ -4822,16 +4782,16 @@ fixup_sigtramp (void) /* We have to handle the following cases here: a) The Mips library has a sigtramp label within sigvec. b) Irix has a _sigtramp which we want to use, but it also has sigvec. */ - s = lookup_symbol ("sigvec", 0, VAR_NAMESPACE, 0, NULL); + s = lookup_symbol ("sigvec", 0, VAR_DOMAIN, 0, NULL); if (s != 0) { b0 = SYMBOL_BLOCK_VALUE (s); - s = lookup_symbol ("sigtramp", b0, VAR_NAMESPACE, 0, NULL); + s = lookup_symbol ("sigtramp", b0, VAR_DOMAIN, 0, NULL); } if (s == 0) { /* No sigvec or no sigtramp inside sigvec, try _sigtramp. */ - s = lookup_symbol ("_sigtramp", 0, VAR_NAMESPACE, 0, NULL); + s = lookup_symbol ("_sigtramp", 0, VAR_DOMAIN, 0, NULL); } /* But maybe this program uses its own version of sigvec */ @@ -4857,14 +4817,14 @@ fixup_sigtramp (void) * needed info. Note we make it a nested procedure of sigvec, * which is the way the (assembly) code is actually written. */ - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; + SYMBOL_DOMAIN (s) = VAR_DOMAIN; SYMBOL_CLASS (s) = LOC_BLOCK; SYMBOL_TYPE (s) = init_type (TYPE_CODE_FUNC, 4, 0, (char *) NULL, st->objfile); TYPE_TARGET_TYPE (SYMBOL_TYPE (s)) = mdebug_type_void; /* Need a block to allocate MIPS_EFI_SYMBOL_NAME in */ - b = new_block (1); + b = new_block (NON_FUNCTION_BLOCK); SYMBOL_BLOCK_VALUE (s) = b; BLOCK_START (b) = sigtramp_address; BLOCK_END (b) = sigtramp_end; @@ -4901,13 +4861,13 @@ fixup_sigtramp (void) current_objfile = st->objfile; /* Keep new_symbol happy */ s = new_symbol (MIPS_EFI_SYMBOL_NAME); SYMBOL_VALUE (s) = (long) e; - SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE; + SYMBOL_DOMAIN (s) = LABEL_DOMAIN; SYMBOL_CLASS (s) = LOC_CONST; SYMBOL_TYPE (s) = mdebug_type_void; current_objfile = NULL; } - BLOCK_SYM (b, BLOCK_NSYMS (b)++) = s; + dict_add_symbol (BLOCK_DICT (b), s); } #endif /* TM_MIPS_H */ diff --git a/contrib/gdb/gdb/mem-break.c b/contrib/gdb/gdb/mem-break.c index a67e2a5cbbf..96750c8b8f6 100644 --- a/contrib/gdb/gdb/mem-break.c +++ b/contrib/gdb/gdb/mem-break.c @@ -1,6 +1,8 @@ /* Simulate breakpoints by patching locations in the target system, for GDB. - Copyright 1990, 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2000, + 2002 Free Software Foundation, Inc. + Contributed by Cygnus Support. Written by John Gilmore. This file is part of GDB. @@ -22,7 +24,8 @@ #include "defs.h" -/* This file is only useful if BREAKPOINT is set. If not, we punt. */ +/* This file is only useful if BREAKPOINT_FROM_PC is set. If not, we + punt. */ #include "symtab.h" #include "breakpoint.h" @@ -30,50 +33,6 @@ #include "target.h" -/* Use the program counter to determine the contents and size - of a breakpoint instruction. If no target-dependent macro - BREAKPOINT_FROM_PC has been defined to implement this function, - assume that the breakpoint doesn't depend on the PC, and - use the values of the BIG_BREAKPOINT and LITTLE_BREAKPOINT macros. - Return a pointer to a string of bytes that encode a breakpoint - instruction, stores the length of the string to *lenptr, - and optionally adjust the pc to point to the correct memory location - for inserting the breakpoint. */ - -unsigned char * -memory_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) -{ - /* {BIG_,LITTLE_}BREAKPOINT is the sequence of bytes we insert for a - breakpoint. On some machines, breakpoints are handled by the - target environment and we don't have to worry about them here. */ -#ifdef BIG_BREAKPOINT - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - { - static unsigned char big_break_insn[] = BIG_BREAKPOINT; - *lenptr = sizeof (big_break_insn); - return big_break_insn; - } -#endif -#ifdef LITTLE_BREAKPOINT - if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG) - { - static unsigned char little_break_insn[] = LITTLE_BREAKPOINT; - *lenptr = sizeof (little_break_insn); - return little_break_insn; - } -#endif -#ifdef BREAKPOINT - { - static unsigned char break_insn[] = BREAKPOINT; - *lenptr = sizeof (break_insn); - return break_insn; - } -#endif - *lenptr = 0; - return NULL; -} - - /* Insert a breakpoint on targets that don't have any better breakpoint support. We read the contents of the target location and stash it, then overwrite it with a breakpoint instruction. ADDR is the target @@ -86,7 +45,7 @@ int default_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache) { int val; - unsigned char *bp; + const unsigned char *bp; int bplen; /* Determine appropriate breakpoint contents and size for this address. */ @@ -108,7 +67,7 @@ default_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache) int default_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache) { - unsigned char *bp; + const unsigned char *bp; int bplen; /* Determine appropriate breakpoint contents and size for this address. */ diff --git a/contrib/gdb/gdb/memattr.c b/contrib/gdb/gdb/memattr.c index 7387e8d830d..4ab5dbf1009 100644 --- a/contrib/gdb/gdb/memattr.c +++ b/contrib/gdb/gdb/memattr.c @@ -1,5 +1,6 @@ /* Memory attributes support, for GDB. - Copyright 2001 Free Software Foundation, Inc. + + Copyright 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -46,7 +47,7 @@ create_mem_region (CORE_ADDR lo, CORE_ADDR hi, struct mem_region *n, *new; /* lo == hi is a useless empty region */ - if (lo >= hi) + if (lo >= hi && hi != 0) { printf_unfiltered ("invalid memory region: low >= high\n"); return NULL; @@ -56,8 +57,9 @@ create_mem_region (CORE_ADDR lo, CORE_ADDR hi, while (n) { /* overlapping node */ - if ((lo >= n->lo && lo < n->hi) || - (hi > n->lo && hi <= n->hi)) + if ((lo >= n->lo && (lo < n->hi || n->hi == 0)) + || (hi > n->lo && (hi <= n->hi || n->hi == 0)) + || (lo <= n->lo && (hi >= n->hi || hi == 0))) { printf_unfiltered ("overlapping memory region\n"); return NULL; @@ -110,7 +112,7 @@ lookup_mem_region (CORE_ADDR addr) { if (m->enabled_p == 1) { - if (addr >= m->lo && addr < m->hi) + if (addr >= m->lo && (addr < m->hi || m->hi == 0)) return m; if (addr >= m->hi && lo < m->hi) @@ -238,17 +240,27 @@ mem_info_command (char *args, int from_tty) m->number, m->enabled_p ? 'y' : 'n'); if (TARGET_ADDR_BIT <= 32) - tmp = longest_local_hex_string_custom ((unsigned long) m->lo, "08l"); + tmp = local_hex_string_custom ((unsigned long) m->lo, "08l"); else - tmp = longest_local_hex_string_custom ((unsigned long) m->lo, "016l"); + tmp = local_hex_string_custom ((unsigned long) m->lo, "016l"); printf_filtered ("%s ", tmp); - + if (TARGET_ADDR_BIT <= 32) - tmp = longest_local_hex_string_custom ((unsigned long) m->hi, "08l"); + { + if (m->hi == 0) + tmp = "0x100000000"; + else + tmp = local_hex_string_custom ((unsigned long) m->hi, "08l"); + } else - tmp = longest_local_hex_string_custom ((unsigned long) m->hi, "016l"); - + { + if (m->hi == 0) + tmp = "0x10000000000000000"; + else + tmp = local_hex_string_custom ((unsigned long) m->hi, "016l"); + } + printf_filtered ("%s ", tmp); /* Print a token for each attribute. @@ -502,8 +514,10 @@ mem_delete_command (char *args, int from_tty) dont_repeat (); } +extern initialize_file_ftype _initialize_mem; /* -Wmissing-prototype */ + void -_initialize_mem () +_initialize_mem (void) { add_com ("mem", class_vars, mem_command, "Define attributes for memory region.\n\ diff --git a/contrib/gdb/gdb/mi/mi-cmd-break.c b/contrib/gdb/gdb/mi/mi-cmd-break.c index 5061392fa67..5d15aa98b8a 100644 --- a/contrib/gdb/gdb/mi/mi-cmd-break.c +++ b/contrib/gdb/gdb/mi/mi-cmd-break.c @@ -29,11 +29,6 @@ #include "gdb-events.h" #include "gdb.h" -/* Convenience macro for allocting typesafe memory. */ - -#undef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) - enum { FROM_TTY = 0 diff --git a/contrib/gdb/gdb/mi/mi-cmd-disas.c b/contrib/gdb/gdb/mi/mi-cmd-disas.c index 7596c068271..168ca171666 100644 --- a/contrib/gdb/gdb/mi/mi-cmd-disas.c +++ b/contrib/gdb/gdb/mi/mi-cmd-disas.c @@ -24,67 +24,9 @@ #include "value.h" #include "mi-cmds.h" #include "mi-getopt.h" +#include "gdb_string.h" #include "ui-out.h" - -static int gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, unsigned int len, - disassemble_info * info); -static int compare_lines (const PTR mle1p, const PTR mle2p); - -/* Disassemble functions. FIXME: these do not really belong here. We - should get rid of all the duplicate code in gdb that does the same - thing: disassemble_command() and the gdbtk variation. */ - -/* This Structure is used in mi_cmd_disassemble. - We need a different sort of line table from the normal one cuz we can't - depend upon implicit line-end pc's for lines to do the - reordering in this function. */ - -struct dis_line_entry - { - int line; - CORE_ADDR start_pc; - CORE_ADDR end_pc; - }; - -/* This variable determines where memory used for disassembly is read from. */ -int gdb_disassemble_from_exec = -1; - -/* This is the memory_read_func for gdb_disassemble when we are - disassembling from the exec file. */ -static int -gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, - unsigned int len, disassemble_info * info) -{ - extern struct target_ops exec_ops; - int res; - - errno = 0; - res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops); - - if (res == len) - return 0; - else if (errno == 0) - return EIO; - else - return errno; -} - -static int -compare_lines (const PTR mle1p, const PTR mle2p) -{ - struct dis_line_entry *mle1, *mle2; - int val; - - mle1 = (struct dis_line_entry *) mle1p; - mle2 = (struct dis_line_entry *) mle2p; - - val = mle1->line - mle2->line; - - if (val != 0) - return val; - - return mle1->start_pc - mle2->start_pc; -} +#include "disasm.h" /* The arguments to be passed on the command line and parsed here are: @@ -106,30 +48,15 @@ compare_lines (const PTR mle1p, const PTR mle2p) MODE: 0 or 1 for disassembly only, or mixed source and disassembly, respectively. */ - enum mi_cmd_result mi_cmd_disassemble (char *command, char **argv, int argc) { - CORE_ADDR pc; + enum mi_cmd_result retval; CORE_ADDR start; int mixed_source_and_assembly; - int num_displayed; - static disassemble_info di; - static int di_initialized; - struct symtab *s; - /* To collect the instruction outputted from opcodes. */ - static struct ui_stream *stb = NULL; - - /* parts of the symbolic representation of the address */ - int line; - int offset; - int unmapped; - char *filename = NULL; - char *name = NULL; - /* Which options have we processed ... */ int file_seen = 0; int line_seen = 0; @@ -148,11 +75,10 @@ mi_cmd_disassemble (char *command, char **argv, int argc) int optind = 0; char *optarg; enum opt - { - FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT - }; - static struct mi_opt opts[] = { + FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT + }; + static struct mi_opt opts[] = { {"f", FILE_OPT, 1}, {"l", LINE_OPT, 1}, {"n", NUM_OPT, 1}, @@ -201,16 +127,19 @@ mi_cmd_disassemble (char *command, char **argv, int argc) if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen) || (line_seen && file_seen && !num_seen && !start_seen && !end_seen) - || (!line_seen && !file_seen && !num_seen && start_seen && end_seen))) - error ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode."); + || (!line_seen && !file_seen && !num_seen && start_seen && end_seen))) + error + ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode."); if (argc != 1) - error ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode."); + error + ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode."); mixed_source_and_assembly = atoi (argv[0]); if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1)) error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1."); + /* We must get the function beginning and end where line_num is contained. */ @@ -225,275 +154,10 @@ mi_cmd_disassemble (char *command, char **argv, int argc) error ("mi_cmd_disassemble: No function contains specified address"); } - if (!di_initialized) - { - /* We don't add a cleanup for this, because the allocation of - the stream is done once only for each gdb run, and we need to - keep it around until the end. Hopefully there won't be any - errors in the init code below, that make this function bail - out. */ - stb = ui_out_stream_new (uiout); - INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream, - (fprintf_ftype) fprintf_unfiltered); - di.flavour = bfd_target_unknown_flavour; - di.memory_error_func = dis_asm_memory_error; - di.print_address_func = dis_asm_print_address; - di_initialized = 1; - } - - di.mach = TARGET_PRINT_INSN_INFO->mach; - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - di.endian = BFD_ENDIAN_BIG; - else - di.endian = BFD_ENDIAN_LITTLE; - - /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to - determine whether or not to do disassembly from target memory or from the - exec file: - - If we're debugging a local process, read target memory, instead of the - exec file. This makes disassembly of functions in shared libs work - correctly. Also, read target memory if we are debugging native threads. - - Else, we're debugging a remote process, and should disassemble from the - exec file for speed. However, this is no good if the target modifies its - code (for relocation, or whatever). - */ - - if (gdb_disassemble_from_exec == -1) - { - if (strcmp (target_shortname, "child") == 0 - || strcmp (target_shortname, "procfs") == 0 - || strcmp (target_shortname, "vxprocess") == 0 - || strstr (target_shortname, "-threads") != NULL) - gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */ - else - gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */ - } - - if (gdb_disassemble_from_exec) - di.read_memory_func = gdb_dis_asm_read_memory; - else - di.read_memory_func = dis_asm_read_memory; - - /* If just doing straight assembly, all we need to do is disassemble - everything between low and high. If doing mixed source/assembly, - we've got a totally different path to follow. */ - - if (mixed_source_and_assembly) - { - /* Come here for mixed source/assembly */ - /* The idea here is to present a source-O-centric view of a - function to the user. This means that things are presented - in source order, with (possibly) out of order assembly - immediately following. */ - struct symtab *symtab; - struct linetable_entry *le; - int nlines; - int newlines; - struct dis_line_entry *mle; - struct symtab_and_line sal; - int i; - int out_of_order; - int next_line; - - /* Assume symtab is valid for whole PC range */ - symtab = find_pc_symtab (low); - - if (!symtab || !symtab->linetable) - goto assembly_only; - - /* First, convert the linetable to a bunch of my_line_entry's. */ - - le = symtab->linetable->item; - nlines = symtab->linetable->nitems; - - if (nlines <= 0) - goto assembly_only; - - mle = (struct dis_line_entry *) alloca (nlines * sizeof (struct dis_line_entry)); - - out_of_order = 0; - - /* Copy linetable entries for this function into our data - structure, creating end_pc's and setting out_of_order as - appropriate. */ - - /* First, skip all the preceding functions. */ - - for (i = 0; i < nlines - 1 && le[i].pc < low; i++); - - /* Now, copy all entries before the end of this function. */ - - newlines = 0; - for (; i < nlines - 1 && le[i].pc < high; i++) - { - if (le[i].line == le[i + 1].line - && le[i].pc == le[i + 1].pc) - continue; /* Ignore duplicates */ - - /* Skip any end-of-function markers. */ - if (le[i].line == 0) - continue; - - mle[newlines].line = le[i].line; - if (le[i].line > le[i + 1].line) - out_of_order = 1; - mle[newlines].start_pc = le[i].pc; - mle[newlines].end_pc = le[i + 1].pc; - newlines++; - } - - /* If we're on the last line, and it's part of the function, - then we need to get the end pc in a special way. */ - - if (i == nlines - 1 - && le[i].pc < high) - { - mle[newlines].line = le[i].line; - mle[newlines].start_pc = le[i].pc; - sal = find_pc_line (le[i].pc, 0); - mle[newlines].end_pc = sal.end; - newlines++; - } - - /* Now, sort mle by line #s (and, then by addresses within - lines). */ - - if (out_of_order) - qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines); - - /* Now, for each line entry, emit the specified lines (unless - they have been emitted before), followed by the assembly code - for that line. */ - - next_line = 0; /* Force out first line */ - ui_out_list_begin (uiout, "asm_insns"); - num_displayed = 0; - for (i = 0; i < newlines; i++) - { - int close_list = 1; - /* Print out everything from next_line to the current line. */ - if (mle[i].line >= next_line) - { - if (next_line != 0) - { - /* Just one line to print. */ - if (next_line == mle[i].line) - { - ui_out_tuple_begin (uiout, "src_and_asm_line"); - print_source_lines (symtab, next_line, mle[i].line + 1, 0); - } - else - { - /* Several source lines w/o asm instructions associated. */ - for (; next_line < mle[i].line; next_line++) - { - ui_out_tuple_begin (uiout, "src_and_asm_line"); - print_source_lines (symtab, next_line, mle[i].line + 1, 0); - ui_out_list_begin (uiout, "line_asm_insn"); - ui_out_list_end (uiout); - ui_out_tuple_end (uiout); - } - /* Print the last line and leave list open for - asm instructions to be added. */ - ui_out_tuple_begin (uiout, "src_and_asm_line"); - print_source_lines (symtab, next_line, mle[i].line + 1, 0); - } - } - else - { - ui_out_tuple_begin (uiout, "src_and_asm_line"); - print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0); - } - - next_line = mle[i].line + 1; - ui_out_list_begin (uiout, "line_asm_insn"); - if (i + 1 < newlines && mle[i + 1].line <= mle[i].line) - close_list = 0; - } - for (pc = mle[i].start_pc; pc < mle[i].end_pc;) - { - QUIT; - if (how_many >= 0) - { - if (num_displayed >= how_many) - break; - else - num_displayed++; - } - ui_out_tuple_begin (uiout, NULL); - ui_out_field_core_addr (uiout, "address", pc); - - if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped)) - { - /* We don't care now about line, filename and - unmapped, but we might in the future. */ - ui_out_field_string (uiout, "func-name", name); - ui_out_field_int (uiout, "offset", offset); - } - if (filename != NULL) - xfree (filename); - if (name != NULL) - xfree (name); - - ui_file_rewind (stb->stream); - pc += (*tm_print_insn) (pc, &di); - ui_out_field_stream (uiout, "inst", stb); - ui_file_rewind (stb->stream); - ui_out_tuple_end (uiout); - } - if (close_list) - { - ui_out_list_end (uiout); - ui_out_tuple_end (uiout); - close_list = 0; - } - if (how_many >= 0) - if (num_displayed >= how_many) - break; - } - ui_out_list_end (uiout); - } - else - { - assembly_only: - ui_out_list_begin (uiout, "asm_insns"); - num_displayed = 0; - for (pc = low; pc < high;) - { - QUIT; - if (how_many >= 0) - { - if (num_displayed >= how_many) - break; - else - num_displayed++; - } - ui_out_tuple_begin (uiout, NULL); - ui_out_field_core_addr (uiout, "address", pc); - - if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped)) - { - /* We don't care now about line, filename and - unmapped. But we might in the future. */ - ui_out_field_string (uiout, "func-name", name); - ui_out_field_int (uiout, "offset", offset); - } - if (filename != NULL) - xfree (filename); - if (name != NULL) - xfree (name); - - ui_file_rewind (stb->stream); - pc += (*tm_print_insn) (pc, &di); - ui_out_field_stream (uiout, "inst", stb); - ui_file_rewind (stb->stream); - ui_out_tuple_end (uiout); - } - ui_out_list_end (uiout); - } - gdb_flush (gdb_stdout); + gdb_disassembly (uiout, + file_string, + line_num, + mixed_source_and_assembly, how_many, low, high); return MI_CMD_DONE; } diff --git a/contrib/gdb/gdb/mi/mi-cmd-env.c b/contrib/gdb/gdb/mi/mi-cmd-env.c new file mode 100644 index 00000000000..439c71912bd --- /dev/null +++ b/contrib/gdb/gdb/mi/mi-cmd-env.c @@ -0,0 +1,259 @@ +/* MI Command Set - environment commands. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + + Contributed by Red Hat Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "value.h" +#include "mi-out.h" +#include "mi-cmds.h" +#include "mi-getopt.h" +#include "symtab.h" +#include "target.h" +#include "environ.h" +#include "command.h" +#include "ui-out.h" +#include "top.h" + +#include "gdb_string.h" +#include "gdb_stat.h" + +static void env_mod_path (char *dirname, char **which_path); +extern void _initialize_mi_cmd_env (void); + +static const char path_var_name[] = "PATH"; +static char *orig_path = NULL; + +/* The following is copied from mi-main.c so for m1 and below we can + perform old behavior and use cli commands. If ARGS is non-null, + append it to the CMD. */ +static void +env_execute_cli_command (const char *cmd, const char *args) +{ + if (cmd != 0) + { + struct cleanup *old_cleanups; + char *run; + if (args != NULL) + xasprintf (&run, "%s %s", cmd, args); + else + run = xstrdup (cmd); + old_cleanups = make_cleanup (xfree, run); + execute_command ( /*ui */ run, 0 /*from_tty */ ); + do_cleanups (old_cleanups); + return; + } +} + + +/* Print working directory. */ +enum mi_cmd_result +mi_cmd_env_pwd (char *command, char **argv, int argc) +{ + if (argc > 0) + error ("mi_cmd_env_pwd: No arguments required"); + + if (mi_version (uiout) < 2) + { + env_execute_cli_command ("pwd", NULL); + return MI_CMD_DONE; + } + + /* Otherwise the mi level is 2 or higher. */ + + getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); + ui_out_field_string (uiout, "cwd", gdb_dirbuf); + + return MI_CMD_DONE; +} + +/* Change working directory. */ +enum mi_cmd_result +mi_cmd_env_cd (char *command, char **argv, int argc) +{ + if (argc == 0 || argc > 1) + error ("mi_cmd_env_cd: Usage DIRECTORY"); + + env_execute_cli_command ("cd", argv[0]); + + return MI_CMD_DONE; +} + +static void +env_mod_path (char *dirname, char **which_path) +{ + if (dirname == 0 || dirname[0] == '\0') + return; + + /* Call add_path with last arg 0 to indicate not to parse for + separator characters. */ + add_path (dirname, which_path, 0); +} + +/* Add one or more directories to start of executable search path. */ +enum mi_cmd_result +mi_cmd_env_path (char *command, char **argv, int argc) +{ + char *exec_path; + char *env; + int reset = 0; + int optind = 0; + int i; + char *optarg; + enum opt + { + RESET_OPT + }; + static struct mi_opt opts[] = + { + {"r", RESET_OPT, 0}, + 0 + }; + + dont_repeat (); + + if (mi_version (uiout) < 2) + { + for (i = argc - 1; i >= 0; --i) + env_execute_cli_command ("path", argv[i]); + return MI_CMD_DONE; + } + + /* Otherwise the mi level is 2 or higher. */ + while (1) + { + int opt = mi_getopt ("mi_cmd_env_path", argc, argv, opts, + &optind, &optarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case RESET_OPT: + reset = 1; + break; + } + } + argv += optind; + argc -= optind; + + + if (reset) + { + /* Reset implies resetting to original path first. */ + exec_path = xstrdup (orig_path); + } + else + { + /* Otherwise, get current path to modify. */ + env = get_in_environ (inferior_environ, path_var_name); + + /* Can be null if path is not set. */ + if (!env) + env = ""; + exec_path = xstrdup (env); + } + + for (i = argc - 1; i >= 0; --i) + env_mod_path (argv[i], &exec_path); + + set_in_environ (inferior_environ, path_var_name, exec_path); + xfree (exec_path); + env = get_in_environ (inferior_environ, path_var_name); + ui_out_field_string (uiout, "path", env); + + return MI_CMD_DONE; +} + +/* Add zero or more directories to the front of the source path. */ +enum mi_cmd_result +mi_cmd_env_dir (char *command, char **argv, int argc) +{ + int i; + int optind = 0; + int reset = 0; + char *optarg; + enum opt + { + RESET_OPT + }; + static struct mi_opt opts[] = + { + {"r", RESET_OPT, 0}, + 0 + }; + + dont_repeat (); + + if (mi_version (uiout) < 2) + { + for (i = argc - 1; i >= 0; --i) + env_execute_cli_command ("dir", argv[i]); + return MI_CMD_DONE; + } + + /* Otherwise mi level is 2 or higher. */ + while (1) + { + int opt = mi_getopt ("mi_cmd_env_dir", argc, argv, opts, + &optind, &optarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case RESET_OPT: + reset = 1; + break; + } + } + argv += optind; + argc -= optind; + + if (reset) + { + /* Reset means setting to default path first. */ + xfree (source_path); + init_source_path (); + } + + for (i = argc - 1; i >= 0; --i) + env_mod_path (argv[i], &source_path); + init_last_source_visited (); + + ui_out_field_string (uiout, "source-path", source_path); + forget_cached_source_info (); + + return MI_CMD_DONE; +} + +void +_initialize_mi_cmd_env (void) +{ + char *env; + + /* We want original execution path to reset to, if desired later. */ + env = get_in_environ (inferior_environ, path_var_name); + + /* Can be null if path is not set. */ + if (!env) + env = ""; + orig_path = xstrdup (env); +} diff --git a/contrib/gdb/gdb/mi/mi-cmd-file.c b/contrib/gdb/gdb/mi/mi-cmd-file.c new file mode 100644 index 00000000000..eb1d67a6a8d --- /dev/null +++ b/contrib/gdb/gdb/mi/mi-cmd-file.c @@ -0,0 +1,67 @@ +/* MI Command Set - breakpoint and watchpoint commands. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "mi-cmds.h" +#include "mi-getopt.h" +#include "ui-out.h" +#include "symtab.h" +#include "source.h" + +/* Return to the client the absolute path and line number of the + current file being executed. */ + +enum mi_cmd_result +mi_cmd_file_list_exec_source_file(char *command, char **argv, int argc) +{ + struct symtab_and_line st; + int optind = 0; + char *optarg; + + if ( !mi_valid_noargs("mi_cmd_file_list_exec_source_file", argc, argv) ) + error ("mi_cmd_file_list_exec_source_file: Usage: No args"); + + + /* Set the default file and line, also get them */ + set_default_source_symtab_and_line(); + st = get_current_source_symtab_and_line(); + + /* We should always get a symtab. + Apparently, filename does not need to be tested for NULL. + The documentation in symtab.h suggests it will always be correct */ + if (!st.symtab) + error ("mi_cmd_file_list_exec_source_file: No symtab"); + + /* Extract the fullname if it is not known yet */ + if (st.symtab->fullname == NULL) + symtab_to_filename (st.symtab); + + /* We may not be able to open the file (not available). */ + if (st.symtab->fullname == NULL) + error ("mi_cmd_file_list_exec_source_file: File not found"); + + /* Print to the user the line, filename and fullname */ + ui_out_field_int (uiout, "line", st.line); + ui_out_field_string (uiout, "file", st.symtab->filename); + ui_out_field_string (uiout, "fullname", st.symtab->fullname); + + return MI_CMD_DONE; +} diff --git a/contrib/gdb/gdb/mi/mi-cmd-stack.c b/contrib/gdb/gdb/mi/mi-cmd-stack.c index 0e4bdf4a0e7..7db9ffbea63 100644 --- a/contrib/gdb/gdb/mi/mi-cmd-stack.c +++ b/contrib/gdb/gdb/mi/mi-cmd-stack.c @@ -1,5 +1,5 @@ /* MI Command Set - stack commands. - Copyright 2000, 2002 Free Software Foundation, Inc. + Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -26,11 +26,10 @@ #include "mi-cmds.h" #include "ui-out.h" #include "symtab.h" - -/* FIXME: these should go in some .h file but stack.c doesn't have a - corresponding .h file. These wrappers will be obsolete anyway, once - we pull the plug on the sanitization. */ -extern void select_frame_command_wrapper (char *, int); +#include "block.h" +#include "stack.h" +#include "dictionary.h" +#include "gdb_string.h" static void list_args_or_locals (int locals, int values, struct frame_info *fi); @@ -45,6 +44,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc) int frame_low; int frame_high; int i; + struct cleanup *cleanup_stack; struct frame_info *fi; if (!target_has_stack) @@ -76,7 +76,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc) if (fi == NULL) error ("mi_cmd_stack_list_frames: Not enough frames in stack."); - ui_out_list_begin (uiout, "stack"); + cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack"); /* Now let;s print the frames up to frame_high, or until there are frames in the stack. */ @@ -95,7 +95,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc) 0 /* args */ ); } - ui_out_list_end (uiout); + do_cleanups (cleanup_stack); if (i < frame_high) error ("mi_cmd_stack_list_frames: Not enough frames in stack."); @@ -138,10 +138,26 @@ mi_cmd_stack_info_depth (char *command, char **argv, int argc) enum mi_cmd_result mi_cmd_stack_list_locals (char *command, char **argv, int argc) { + struct frame_info *frame; + enum print_values print_values; + if (argc != 1) error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES"); - list_args_or_locals (1, atoi (argv[0]), selected_frame); + frame = get_selected_frame (); + + if (strcmp (argv[0], "0") == 0 + || strcmp (argv[0], "--no-values") == 0) + print_values = PRINT_NO_VALUES; + else if (strcmp (argv[0], "1") == 0 + || strcmp (argv[0], "--all-values") == 0) + print_values = PRINT_ALL_VALUES; + else if (strcmp (argv[0], "2") == 0 + || strcmp (argv[0], "--simple-values") == 0) + print_values = PRINT_SIMPLE_VALUES; + else + error ("Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\", 2 or \"--simple-values\""); + list_args_or_locals (1, print_values, frame); return MI_CMD_DONE; } @@ -155,6 +171,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc) int frame_high; int i; struct frame_info *fi; + struct cleanup *cleanup_stack_args; if (argc < 1 || argc > 3 || argc == 2) error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]"); @@ -182,7 +199,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc) if (fi == NULL) error ("mi_cmd_stack_list_args: Not enough frames in stack."); - ui_out_list_begin (uiout, "stack-args"); + cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args"); /* Now let's print the frames up to frame_high, or until there are frames in the stack. */ @@ -190,14 +207,15 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc) fi && (i <= frame_high || frame_high == -1); i++, fi = get_prev_frame (fi)) { + struct cleanup *cleanup_frame; QUIT; - ui_out_tuple_begin (uiout, "frame"); + cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); ui_out_field_int (uiout, "level", i); list_args_or_locals (0, atoi (argv[0]), fi); - ui_out_tuple_end (uiout); + do_cleanups (cleanup_frame); } - ui_out_list_end (uiout); + do_cleanups (cleanup_stack_args); if (i < frame_high) error ("mi_cmd_stack_list_args: Not enough frames in stack."); @@ -213,18 +231,21 @@ list_args_or_locals (int locals, int values, struct frame_info *fi) { struct block *block; struct symbol *sym; - int i, nsyms; + struct dict_iterator iter; + int nsyms; + struct cleanup *cleanup_list; static struct ui_stream *stb = NULL; + struct type *type; stb = ui_out_stream_new (uiout); - block = get_frame_block (fi); + block = get_frame_block (fi, 0); - ui_out_list_begin (uiout, locals ? "locals" : "args"); + cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args"); while (block != 0) { - ALL_BLOCK_SYMBOLS (block, i, sym) + ALL_BLOCK_SYMBOLS (block, iter, sym) { int print_me = 0; @@ -248,6 +269,7 @@ list_args_or_locals (int locals, int values, struct frame_info *fi) case LOC_REGPARM_ADDR: /* indirect register arg */ case LOC_LOCAL_ARG: /* stack arg */ case LOC_BASEREG_ARG: /* basereg arg */ + case LOC_COMPUTED_ARG: /* arg with computed location */ if (!locals) print_me = 1; break; @@ -256,29 +278,47 @@ list_args_or_locals (int locals, int values, struct frame_info *fi) case LOC_BASEREG: /* basereg local */ case LOC_STATIC: /* static */ case LOC_REGISTER: /* register */ + case LOC_COMPUTED: /* computed location */ if (locals) print_me = 1; break; } if (print_me) { - if (values) - ui_out_tuple_begin (uiout, NULL); - ui_out_field_string (uiout, "name", SYMBOL_NAME (sym)); + struct cleanup *cleanup_tuple = NULL; + struct symbol *sym2; + if (values != PRINT_NO_VALUES) + cleanup_tuple = + make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym)); - if (values) - { - struct symbol *sym2; - if (!locals) - sym2 = lookup_symbol (SYMBOL_NAME (sym), - block, VAR_NAMESPACE, - (int *) NULL, - (struct symtab **) NULL); - else + if (!locals) + sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym), + block, VAR_DOMAIN, + (int *) NULL, + (struct symtab **) NULL); + else sym2 = sym; + switch (values) + { + case PRINT_SIMPLE_VALUES: + type = check_typedef (sym2->type); + type_print (sym2->type, "", stb->stream, -1); + ui_out_field_stream (uiout, "type", stb); + if (TYPE_CODE (type) != TYPE_CODE_ARRAY + && TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + { + print_variable_value (sym2, fi, stb->stream); + ui_out_field_stream (uiout, "value", stb); + } + do_cleanups (cleanup_tuple); + break; + case PRINT_ALL_VALUES: print_variable_value (sym2, fi, stb->stream); ui_out_field_stream (uiout, "value", stb); - ui_out_tuple_end (uiout); + do_cleanups (cleanup_tuple); + break; } } } @@ -287,7 +327,7 @@ list_args_or_locals (int locals, int values, struct frame_info *fi) else block = BLOCK_SUPERBLOCK (block); } - ui_out_list_end (uiout); + do_cleanups (cleanup_list); ui_out_stream_delete (stb); } @@ -302,8 +342,8 @@ mi_cmd_stack_select_frame (char *command, char **argv, int argc) /* with no args, don't change frame */ if (argc == 0) - select_frame_command_wrapper (0, 1 /* not used */ ); + select_frame_command (0, 1 /* not used */ ); else - select_frame_command_wrapper (argv[0], 1 /* not used */ ); + select_frame_command (argv[0], 1 /* not used */ ); return MI_CMD_DONE; } diff --git a/contrib/gdb/gdb/mi/mi-cmd-var.c b/contrib/gdb/gdb/mi/mi-cmd-var.c index 0c840648bf7..709ed301052 100644 --- a/contrib/gdb/gdb/mi/mi-cmd-var.c +++ b/contrib/gdb/gdb/mi/mi-cmd-var.c @@ -1,5 +1,7 @@ /* MI Command Set - varobj commands. - Copyright 2000 Free Software Foundation, Inc. + + Copyright 2000, 2002, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -26,11 +28,7 @@ #include "varobj.h" #include "value.h" #include - -/* Convenience macro for allocting typesafe memory. */ - -#undef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) +#include "gdb_string.h" extern int varobjdebug; /* defined in varobj.c */ @@ -83,7 +81,7 @@ mi_cmd_var_create (char *command, char **argv, int argc) else { var_type = USE_SPECIFIED_FRAME; - frameaddr = parse_and_eval_address (frame); + frameaddr = string_to_core_addr (frame); } if (varobjdebug) @@ -191,15 +189,15 @@ mi_cmd_var_set_format (char *command, char **argv, int argc) len = strlen (formspec); - if (STREQN (formspec, "natural", len)) + if (strncmp (formspec, "natural", len) == 0) format = FORMAT_NATURAL; - else if (STREQN (formspec, "binary", len)) + else if (strncmp (formspec, "binary", len) == 0) format = FORMAT_BINARY; - else if (STREQN (formspec, "decimal", len)) + else if (strncmp (formspec, "decimal", len) == 0) format = FORMAT_DECIMAL; - else if (STREQN (formspec, "hexadecimal", len)) + else if (strncmp (formspec, "hexadecimal", len) == 0) format = FORMAT_HEXADECIMAL; - else if (STREQN (formspec, "octal", len)) + else if (strncmp (formspec, "octal", len) == 0) format = FORMAT_OCTAL; else error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""); @@ -256,39 +254,58 @@ mi_cmd_var_list_children (char *command, char **argv, int argc) struct varobj *var; struct varobj **childlist; struct varobj **cc; + struct cleanup *cleanup_children; int numchild; char *type; + enum print_values print_values; - if (argc != 1) - error ("mi_cmd_var_list_children: Usage: NAME."); + if (argc != 1 && argc != 2) + error ("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME"); /* Get varobj handle, if a valid var obj name was specified */ - var = varobj_get_handle (argv[0]); + if (argc == 1) var = varobj_get_handle (argv[0]); + else var = varobj_get_handle (argv[1]); if (var == NULL) - error ("mi_cmd_var_list_children: Variable object not found"); + error ("Variable object not found"); numchild = varobj_list_children (var, &childlist); ui_out_field_int (uiout, "numchild", numchild); + if (argc == 2) + if (strcmp (argv[0], "0") == 0 + || strcmp (argv[0], "--no-values") == 0) + print_values = PRINT_NO_VALUES; + else if (strcmp (argv[0], "1") == 0 + || strcmp (argv[0], "--all-values") == 0) + print_values = PRINT_ALL_VALUES; + else + error ("Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\""); + else print_values = PRINT_NO_VALUES; if (numchild <= 0) return MI_CMD_DONE; - ui_out_tuple_begin (uiout, "children"); + if (mi_version (uiout) == 1) + cleanup_children = make_cleanup_ui_out_tuple_begin_end (uiout, "children"); + else + cleanup_children = make_cleanup_ui_out_list_begin_end (uiout, "children"); cc = childlist; while (*cc != NULL) { - ui_out_tuple_begin (uiout, "child"); + struct cleanup *cleanup_child; + cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child"); ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); ui_out_field_string (uiout, "exp", varobj_get_expression (*cc)); ui_out_field_int (uiout, "numchild", varobj_get_num_children (*cc)); + if (print_values) + ui_out_field_string (uiout, "value", varobj_get_value (*cc)); type = varobj_get_type (*cc); /* C++ pseudo-variables (public, private, protected) do not have a type */ if (type) ui_out_field_string (uiout, "type", varobj_get_type (*cc)); - ui_out_tuple_end (uiout); + do_cleanups (cleanup_child); cc++; } - ui_out_tuple_end (uiout); + do_cleanups (cleanup_children); xfree (childlist); return MI_CMD_DONE; } @@ -407,6 +424,7 @@ mi_cmd_var_update (char *command, char **argv, int argc) struct varobj *var; struct varobj **rootlist; struct varobj **cr; + struct cleanup *cleanup; char *name; int nv; @@ -421,10 +439,13 @@ mi_cmd_var_update (char *command, char **argv, int argc) if ((*name == '*') && (*(name + 1) == '\0')) { nv = varobj_list (&rootlist); - ui_out_tuple_begin (uiout, "changelist"); + if (mi_version (uiout) <= 1) + cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "changelist"); + else + cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changelist"); if (nv <= 0) { - ui_out_tuple_end (uiout); + do_cleanups (cleanup); return MI_CMD_DONE; } cr = rootlist; @@ -434,7 +455,7 @@ mi_cmd_var_update (char *command, char **argv, int argc) cr++; } xfree (rootlist); - ui_out_tuple_end (uiout); + do_cleanups (cleanup); } else { @@ -443,9 +464,12 @@ mi_cmd_var_update (char *command, char **argv, int argc) if (var == NULL) error ("mi_cmd_var_update: Variable object not found"); - ui_out_tuple_begin (uiout, "changelist"); + if (mi_version (uiout) <= 1) + cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "changelist"); + else + cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changelist"); varobj_update_one (var); - ui_out_tuple_end (uiout); + do_cleanups (cleanup); } return MI_CMD_DONE; } @@ -459,6 +483,7 @@ varobj_update_one (struct varobj *var) { struct varobj **changelist; struct varobj **cc; + struct cleanup *cleanup = NULL; int nc; nc = varobj_update (&var, &changelist); @@ -471,17 +496,25 @@ varobj_update_one (struct varobj *var) return 1; else if (nc == -1) { + if (mi_version (uiout) > 1) + cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "name", varobj_get_objname(var)); ui_out_field_string (uiout, "in_scope", "false"); + if (mi_version (uiout) > 1) + do_cleanups (cleanup); return -1; } else if (nc == -2) { + if (mi_version (uiout) > 1) + cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "name", varobj_get_objname (var)); ui_out_field_string (uiout, "in_scope", "true"); ui_out_field_string (uiout, "new_type", varobj_get_type(var)); ui_out_field_int (uiout, "new_num_children", varobj_get_num_children(var)); + if (mi_version (uiout) > 1) + do_cleanups (cleanup); } else { @@ -489,9 +522,13 @@ varobj_update_one (struct varobj *var) cc = changelist; while (*cc != NULL) { + if (mi_version (uiout) > 1) + cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); ui_out_field_string (uiout, "in_scope", "true"); ui_out_field_string (uiout, "type_changed", "false"); + if (mi_version (uiout) > 1) + do_cleanups (cleanup); cc++; } xfree (changelist); diff --git a/contrib/gdb/gdb/mi/mi-cmds.c b/contrib/gdb/gdb/mi/mi-cmds.c index 233d06bded2..0dfc2170ec9 100644 --- a/contrib/gdb/gdb/mi/mi-cmds.c +++ b/contrib/gdb/gdb/mi/mi-cmds.c @@ -1,5 +1,7 @@ -/* MI Command Set. - Copyright 2000, 2001 Free Software Foundation, Inc. +/* MI Command Set for GDB, the GNU debugger. + + Copyright 2000, 2001, 2003 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -32,134 +34,138 @@ static void build_table (struct mi_cmd *commands); struct mi_cmd mi_cmds[] = { - {"break-after", "ignore %s", 0}, - {"break-catch", 0, 0}, - {"break-commands", 0, 0}, - {"break-condition", "cond %s", 0}, - {"break-delete", "delete breakpoint %s", 0}, - {"break-disable", "disable breakpoint %s", 0}, - {"break-enable", "enable breakpoint %s", 0}, - {"break-info", "info break %s", 0}, - {"break-insert", 0, 0, mi_cmd_break_insert}, - {"break-list", "info break", 0}, - {"break-watch", 0, 0, mi_cmd_break_watch}, - {"data-disassemble", 0, 0, mi_cmd_disassemble}, - {"data-evaluate-expression", 0, 0, mi_cmd_data_evaluate_expression}, - {"data-list-changed-registers", 0, 0, mi_cmd_data_list_changed_registers}, - {"data-list-register-names", 0, 0, mi_cmd_data_list_register_names}, - {"data-list-register-values", 0, 0, mi_cmd_data_list_register_values}, - {"data-read-memory", 0, 0, mi_cmd_data_read_memory}, - {"data-write-memory", 0, 0, mi_cmd_data_write_memory}, - {"data-write-register-values", 0, 0, mi_cmd_data_write_register_values}, - {"display-delete", 0, 0}, - {"display-disable", 0, 0}, - {"display-enable", 0, 0}, - {"display-insert", 0, 0}, - {"display-list", 0, 0}, - {"environment-cd", "cd %s", 0}, - {"environment-directory", "dir %s", 0}, - {"environment-path", "path %s", 0}, - {"environment-pwd", "pwd", 0}, - {"exec-abort", 0, 0}, - {"exec-arguments", "set args %s", 0}, - {"exec-continue", 0, mi_cmd_exec_continue}, - {"exec-finish", 0, mi_cmd_exec_finish}, - {"exec-interrupt", 0, mi_cmd_exec_interrupt}, - {"exec-next", 0, mi_cmd_exec_next}, - {"exec-next-instruction", 0, mi_cmd_exec_next_instruction}, - {"exec-return", 0, mi_cmd_exec_return}, - {"exec-run", 0, mi_cmd_exec_run}, - {"exec-show-arguments", 0, 0}, - {"exec-signal", 0, 0}, - {"exec-step", 0, mi_cmd_exec_step}, - {"exec-step-instruction", 0, mi_cmd_exec_step_instruction}, - {"exec-until", 0, mi_cmd_exec_until}, - {"file-clear", 0, 0}, - {"file-exec-and-symbols", "file %s", 0}, - {"file-exec-file", "exec-file %s", 0}, - {"file-list-exec-sections", 0, 0}, - {"file-list-exec-source-files", 0, 0}, - {"file-list-shared-libraries", 0, 0}, - {"file-list-symbol-files", 0, 0}, - {"file-symbol-file", "symbol-file %s", 0}, - {"gdb-complete", 0, 0}, - {"gdb-exit", 0, 0, mi_cmd_gdb_exit}, - {"gdb-set", "set %s", 0}, - {"gdb-show", "show %s", 0}, - {"gdb-source", 0, 0}, - {"gdb-version", "show version", 0}, - {"kod-info", 0, 0}, - {"kod-list", 0, 0}, - {"kod-list-object-types", 0, 0}, - {"kod-show", 0, 0}, - {"overlay-auto", 0, 0}, - {"overlay-list-mapping-state", 0, 0}, - {"overlay-list-overlays", 0, 0}, - {"overlay-map", 0, 0}, - {"overlay-off", 0, 0}, - {"overlay-on", 0, 0}, - {"overlay-unmap", 0, 0}, - {"signal-handle", 0, 0}, - {"signal-list-handle-actions", 0, 0}, - {"signal-list-signal-types", 0, 0}, - {"stack-info-depth", 0, 0, mi_cmd_stack_info_depth}, - {"stack-info-frame", 0, 0}, - {"stack-list-arguments", 0, 0, mi_cmd_stack_list_args}, - {"stack-list-exception-handlers", 0, 0}, - {"stack-list-frames", 0, 0, mi_cmd_stack_list_frames}, - {"stack-list-locals", 0, 0, mi_cmd_stack_list_locals}, - {"stack-select-frame", 0, 0, mi_cmd_stack_select_frame}, - {"symbol-info-address", 0, 0}, - {"symbol-info-file", 0, 0}, - {"symbol-info-function", 0, 0}, - {"symbol-info-line", 0, 0}, - {"symbol-info-symbol", 0, 0}, - {"symbol-list-functions", 0, 0}, - {"symbol-list-types", 0, 0}, - {"symbol-list-variables", 0, 0}, - {"symbol-locate", 0, 0}, - {"symbol-type", 0, 0}, - {"target-attach", 0, 0}, - {"target-compare-sections", 0, 0}, - {"target-detach", "detach", 0}, - {"target-download", 0, mi_cmd_target_download}, - {"target-exec-status", 0, 0}, - {"target-list-available-targets", 0, 0}, - {"target-list-current-targets", 0, 0}, - {"target-list-parameters", 0, 0}, - {"target-select", 0, mi_cmd_target_select}, - {"thread-info", 0, 0}, - {"thread-list-all-threads", 0, 0}, - {"thread-list-ids", 0, 0, mi_cmd_thread_list_ids}, - {"thread-select", 0, 0, mi_cmd_thread_select}, - {"trace-actions", 0, 0}, - {"trace-delete", 0, 0}, - {"trace-disable", 0, 0}, - {"trace-dump", 0, 0}, - {"trace-enable", 0, 0}, - {"trace-exists", 0, 0}, - {"trace-find", 0, 0}, - {"trace-frame-number", 0, 0}, - {"trace-info", 0, 0}, - {"trace-insert", 0, 0}, - {"trace-list", 0, 0}, - {"trace-pass-count", 0, 0}, - {"trace-save", 0, 0}, - {"trace-start", 0, 0}, - {"trace-stop", 0, 0}, - {"var-assign", 0, 0, mi_cmd_var_assign}, - {"var-create", 0, 0, mi_cmd_var_create}, - {"var-delete", 0, 0, mi_cmd_var_delete}, - {"var-evaluate-expression", 0, 0, mi_cmd_var_evaluate_expression}, - {"var-info-expression", 0, 0, mi_cmd_var_info_expression}, - {"var-info-num-children", 0, 0, mi_cmd_var_info_num_children}, - {"var-info-type", 0, 0, mi_cmd_var_info_type}, - {"var-list-children", 0, 0, mi_cmd_var_list_children}, - {"var-set-format", 0, 0, mi_cmd_var_set_format}, - {"var-show-attributes", 0, 0, mi_cmd_var_show_attributes}, - {"var-show-format", 0, 0, mi_cmd_var_show_format}, - {"var-update", 0, 0, mi_cmd_var_update}, - {0,} + { "break-after", { "ignore", 1 }, NULL, NULL }, + { "break-catch", { NULL, 0 }, NULL, NULL }, + { "break-commands", { NULL, 0 }, NULL, NULL }, + { "break-condition", { "cond", 1 }, NULL, NULL }, + { "break-delete", { "delete breakpoint", 1 }, NULL, NULL }, + { "break-disable", { "disable breakpoint", 1 }, NULL, NULL }, + { "break-enable", { "enable breakpoint", 1 }, NULL, NULL }, + { "break-info", { "info break", 1 }, NULL, NULL }, + { "break-insert", { NULL, 0 }, 0, mi_cmd_break_insert}, + { "break-list", { "info break", }, NULL, NULL }, + { "break-watch", { NULL, 0 }, 0, mi_cmd_break_watch}, + { "data-disassemble", { NULL, 0 }, 0, mi_cmd_disassemble}, + { "data-evaluate-expression", { NULL, 0 }, 0, mi_cmd_data_evaluate_expression}, + { "data-list-changed-registers", { NULL, 0 }, 0, mi_cmd_data_list_changed_registers}, + { "data-list-register-names", { NULL, 0 }, 0, mi_cmd_data_list_register_names}, + { "data-list-register-values", { NULL, 0 }, 0, mi_cmd_data_list_register_values}, + { "data-read-memory", { NULL, 0 }, 0, mi_cmd_data_read_memory}, + { "data-write-memory", { NULL, 0 }, 0, mi_cmd_data_write_memory}, + { "data-write-register-values", { NULL, 0 }, 0, mi_cmd_data_write_register_values}, + { "display-delete", { NULL, 0 }, NULL, NULL }, + { "display-disable", { NULL, 0 }, NULL, NULL }, + { "display-enable", { NULL, 0 }, NULL, NULL }, + { "display-insert", { NULL, 0 }, NULL, NULL }, + { "display-list", { NULL, 0 }, NULL, NULL }, + { "environment-cd", { NULL, 0 }, 0, mi_cmd_env_cd}, + { "environment-directory", { NULL, 0 }, 0, mi_cmd_env_dir}, + { "environment-path", { NULL, 0 }, 0, mi_cmd_env_path}, + { "environment-pwd", { NULL, 0 }, 0, mi_cmd_env_pwd}, + { "exec-abort", { NULL, 0 }, NULL, NULL }, + { "exec-arguments", { "set args", 1 }, NULL, NULL }, + { "exec-continue", { NULL, 0 }, mi_cmd_exec_continue}, + { "exec-finish", { NULL, 0 }, mi_cmd_exec_finish}, + { "exec-interrupt", { NULL, 0 }, mi_cmd_exec_interrupt}, + { "exec-next", { NULL, 0 }, mi_cmd_exec_next}, + { "exec-next-instruction", { NULL, 0 }, mi_cmd_exec_next_instruction}, + { "exec-return", { NULL, 0 }, mi_cmd_exec_return}, + { "exec-run", { NULL, 0 }, mi_cmd_exec_run}, + { "exec-show-arguments", { NULL, 0 }, NULL, NULL }, + { "exec-signal", { NULL, 0 }, NULL, NULL }, + { "exec-step", { NULL, 0 }, mi_cmd_exec_step}, + { "exec-step-instruction", { NULL, 0 }, mi_cmd_exec_step_instruction}, + { "exec-until", { NULL, 0 }, mi_cmd_exec_until}, + { "file-clear", { NULL, 0 }, NULL, NULL }, + { "file-exec-and-symbols", { "file", 1 }, NULL, NULL }, + { "file-exec-file", { "exec-file", 1 }, NULL, NULL }, + { "file-list-exec-sections", { NULL, 0 }, NULL, NULL }, + { "file-list-exec-source-file", { NULL, 0 }, 0, mi_cmd_file_list_exec_source_file}, + { "file-list-exec-source-files", { NULL, 0 }, NULL, NULL }, + { "file-list-shared-libraries", { NULL, 0 }, NULL, NULL }, + { "file-list-symbol-files", { NULL, 0 }, NULL, NULL }, + { "file-symbol-file", { "symbol-file", 1 }, NULL, NULL }, + { "gdb-complete", { NULL, 0 }, NULL, NULL }, + { "gdb-exit", { NULL, 0 }, 0, mi_cmd_gdb_exit}, + { "gdb-set", { "set", 1 }, NULL, NULL }, + { "gdb-show", { "show", 1 }, NULL, NULL }, + { "gdb-source", { NULL, 0 }, NULL, NULL }, + { "gdb-version", { "show version", 0 }, 0 }, + { "interpreter-exec", { NULL, 0 }, 0, mi_cmd_interpreter_exec}, + { "kod-info", { NULL, 0 }, NULL, NULL }, + { "kod-list", { NULL, 0 }, NULL, NULL }, + { "kod-list-object-types", { NULL, 0 }, NULL, NULL }, + { "kod-show", { NULL, 0 }, NULL, NULL }, + { "overlay-auto", { NULL, 0 }, NULL, NULL }, + { "overlay-list-mapping-state", { NULL, 0 }, NULL, NULL }, + { "overlay-list-overlays", { NULL, 0 }, NULL, NULL }, + { "overlay-map", { NULL, 0 }, NULL, NULL }, + { "overlay-off", { NULL, 0 }, NULL, NULL }, + { "overlay-on", { NULL, 0 }, NULL, NULL }, + { "overlay-unmap", { NULL, 0 }, NULL, NULL }, + { "signal-handle", { NULL, 0 }, NULL, NULL }, + { "signal-list-handle-actions", { NULL, 0 }, NULL, NULL }, + { "signal-list-signal-types", { NULL, 0 }, NULL, NULL }, + { "stack-info-depth", { NULL, 0 }, 0, mi_cmd_stack_info_depth}, + { "stack-info-frame", { NULL, 0 }, NULL, NULL }, + { "stack-list-arguments", { NULL, 0 }, 0, mi_cmd_stack_list_args}, + { "stack-list-exception-handlers", { NULL, 0 }, NULL, NULL }, + { "stack-list-frames", { NULL, 0 }, 0, mi_cmd_stack_list_frames}, + { "stack-list-locals", { NULL, 0 }, 0, mi_cmd_stack_list_locals}, + { "stack-select-frame", { NULL, 0 }, 0, mi_cmd_stack_select_frame}, + { "symbol-info-address", { NULL, 0 }, NULL, NULL }, + { "symbol-info-file", { NULL, 0 }, NULL, NULL }, + { "symbol-info-function", { NULL, 0 }, NULL, NULL }, + { "symbol-info-line", { NULL, 0 }, NULL, NULL }, + { "symbol-info-symbol", { NULL, 0 }, NULL, NULL }, + { "symbol-list-functions", { NULL, 0 }, NULL, NULL }, + { "symbol-list-lines", { NULL, 0 }, 0, mi_cmd_symbol_list_lines}, + { "symbol-list-types", { NULL, 0 }, NULL, NULL }, + { "symbol-list-variables", { NULL, 0 }, NULL, NULL }, + { "symbol-locate", { NULL, 0 }, NULL, NULL }, + { "symbol-type", { NULL, 0 }, NULL, NULL }, + { "target-attach", { NULL, 0 }, NULL, NULL }, + { "target-compare-sections", { NULL, 0 }, NULL, NULL }, + { "target-detach", { "detach", 0 }, 0 }, + { "target-disconnect", { "disconnect", 0 }, 0 }, + { "target-download", { NULL, 0 }, mi_cmd_target_download}, + { "target-exec-status", { NULL, 0 }, NULL, NULL }, + { "target-list-available-targets", { NULL, 0 }, NULL, NULL }, + { "target-list-current-targets", { NULL, 0 }, NULL, NULL }, + { "target-list-parameters", { NULL, 0 }, NULL, NULL }, + { "target-select", { NULL, 0 }, mi_cmd_target_select}, + { "thread-info", { NULL, 0 }, NULL, NULL }, + { "thread-list-all-threads", { NULL, 0 }, NULL, NULL }, + { "thread-list-ids", { NULL, 0 }, 0, mi_cmd_thread_list_ids}, + { "thread-select", { NULL, 0 }, 0, mi_cmd_thread_select}, + { "trace-actions", { NULL, 0 }, NULL, NULL }, + { "trace-delete", { NULL, 0 }, NULL, NULL }, + { "trace-disable", { NULL, 0 }, NULL, NULL }, + { "trace-dump", { NULL, 0 }, NULL, NULL }, + { "trace-enable", { NULL, 0 }, NULL, NULL }, + { "trace-exists", { NULL, 0 }, NULL, NULL }, + { "trace-find", { NULL, 0 }, NULL, NULL }, + { "trace-frame-number", { NULL, 0 }, NULL, NULL }, + { "trace-info", { NULL, 0 }, NULL, NULL }, + { "trace-insert", { NULL, 0 }, NULL, NULL }, + { "trace-list", { NULL, 0 }, NULL, NULL }, + { "trace-pass-count", { NULL, 0 }, NULL, NULL }, + { "trace-save", { NULL, 0 }, NULL, NULL }, + { "trace-start", { NULL, 0 }, NULL, NULL }, + { "trace-stop", { NULL, 0 }, NULL, NULL }, + { "var-assign", { NULL, 0 }, 0, mi_cmd_var_assign}, + { "var-create", { NULL, 0 }, 0, mi_cmd_var_create}, + { "var-delete", { NULL, 0 }, 0, mi_cmd_var_delete}, + { "var-evaluate-expression", { NULL, 0 }, 0, mi_cmd_var_evaluate_expression}, + { "var-info-expression", { NULL, 0 }, 0, mi_cmd_var_info_expression}, + { "var-info-num-children", { NULL, 0 }, 0, mi_cmd_var_info_num_children}, + { "var-info-type", { NULL, 0 }, 0, mi_cmd_var_info_type}, + { "var-list-children", { NULL, 0 }, 0, mi_cmd_var_list_children}, + { "var-set-format", { NULL, 0 }, 0, mi_cmd_var_set_format}, + { "var-show-attributes", { NULL, 0 }, 0, mi_cmd_var_show_attributes}, + { "var-show-format", { NULL, 0 }, 0, mi_cmd_var_show_format}, + { "var-update", { NULL, 0 }, 0, mi_cmd_var_update}, + { NULL, } }; /* Pointer to the mi command table (built at run time) */ diff --git a/contrib/gdb/gdb/mi/mi-cmds.h b/contrib/gdb/gdb/mi/mi-cmds.h index 88775e6f961..545305986c6 100644 --- a/contrib/gdb/gdb/mi/mi-cmds.h +++ b/contrib/gdb/gdb/mi/mi-cmds.h @@ -1,5 +1,7 @@ -/* MI Command Set. - Copyright 2000 Free Software Foundation, Inc. +/* MI Command Set for GDB, the GNU debugger. + + Copyright 2000, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -46,6 +48,12 @@ enum mi_cmd_result MI_CMD_QUIET }; +enum print_values { + PRINT_NO_VALUES, + PRINT_ALL_VALUES, + PRINT_SIMPLE_VALUES +}; + typedef enum mi_cmd_result (mi_cmd_argv_ftype) (char *command, char **argv, int argc); /* Older MI commands have this interface. Retained until all old @@ -64,6 +72,10 @@ extern mi_cmd_argv_ftype mi_cmd_data_list_changed_registers; extern mi_cmd_argv_ftype mi_cmd_data_read_memory; extern mi_cmd_argv_ftype mi_cmd_data_write_memory; extern mi_cmd_argv_ftype mi_cmd_data_write_register_values; +extern mi_cmd_argv_ftype mi_cmd_env_cd; +extern mi_cmd_argv_ftype mi_cmd_env_dir; +extern mi_cmd_argv_ftype mi_cmd_env_path; +extern mi_cmd_argv_ftype mi_cmd_env_pwd; extern mi_cmd_args_ftype mi_cmd_exec_continue; extern mi_cmd_args_ftype mi_cmd_exec_finish; extern mi_cmd_args_ftype mi_cmd_exec_next; @@ -74,12 +86,15 @@ extern mi_cmd_args_ftype mi_cmd_exec_step; extern mi_cmd_args_ftype mi_cmd_exec_step_instruction; extern mi_cmd_args_ftype mi_cmd_exec_until; extern mi_cmd_args_ftype mi_cmd_exec_interrupt; +extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_file; extern mi_cmd_argv_ftype mi_cmd_gdb_exit; +extern mi_cmd_argv_ftype mi_cmd_interpreter_exec; extern mi_cmd_argv_ftype mi_cmd_stack_info_depth; extern mi_cmd_argv_ftype mi_cmd_stack_list_args; extern mi_cmd_argv_ftype mi_cmd_stack_list_frames; extern mi_cmd_argv_ftype mi_cmd_stack_list_locals; extern mi_cmd_argv_ftype mi_cmd_stack_select_frame; +extern mi_cmd_argv_ftype mi_cmd_symbol_list_lines; extern mi_cmd_args_ftype mi_cmd_target_download; extern mi_cmd_args_ftype mi_cmd_target_select; extern mi_cmd_argv_ftype mi_cmd_thread_list_ids; @@ -99,18 +114,26 @@ extern mi_cmd_argv_ftype mi_cmd_var_update; /* Description of a single command. */ +struct mi_cli +{ + /* Corresponding CLI command. If ARGS_P is non-zero, the MI + command's argument list is appended to the CLI command. */ + const char *cmd; + int args_p; +}; + struct mi_cmd - { - /* official name of the command */ - const char *name; - /* If non-null, the corresponding CLI command that can be used to - implement this MI command */ - const char *cli; - /* If non-null, the function implementing the MI command */ - mi_cmd_args_ftype *args_func; - /* If non-null, the function implementing the MI command */ - mi_cmd_argv_ftype *argv_func; - }; +{ + /* official name of the command. */ + const char *name; + /* The corresponding CLI command that can be used to implement this + MI command (if cli.lhs is non NULL). */ + struct mi_cli cli; + /* If non-null, the function implementing the MI command. */ + mi_cmd_args_ftype *args_func; + /* If non-null, the function implementing the MI command. */ + mi_cmd_argv_ftype *argv_func; +}; /* Lookup a command in the mi comand table */ @@ -122,4 +145,8 @@ extern int mi_debug_p; /* Raw console output - FIXME: should this be a parameter? */ extern struct ui_file *raw_stdout; +extern char *mi_error_message; +extern void mi_error_last_message (void); +extern void mi_execute_command (char *cmd, int from_tty); + #endif diff --git a/contrib/gdb/gdb/mi/mi-console.c b/contrib/gdb/gdb/mi/mi-console.c index 5824f833ceb..aca008640fd 100644 --- a/contrib/gdb/gdb/mi/mi-console.c +++ b/contrib/gdb/gdb/mi/mi-console.c @@ -1,5 +1,7 @@ /* MI Console code. - Copyright 2000, 2001 Free Software Foundation, Inc. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -23,11 +25,6 @@ #include "mi-console.h" #include "gdb_string.h" -/* Convenience macro for allocting typesafe memory. */ - -#undef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) - /* MI-console: send output to std-out but correcty encapsulated */ static ui_file_fputs_ftype mi_console_file_fputs; @@ -40,13 +37,14 @@ struct mi_console_file struct ui_file *raw; struct ui_file *buffer; const char *prefix; + char quote; }; int mi_console_file_magic; struct ui_file * mi_console_file_new (struct ui_file *raw, - const char *prefix) + const char *prefix, char quote) { struct ui_file *ui_file = ui_file_new (); struct mi_console_file *mi_console = XMALLOC (struct mi_console_file); @@ -54,6 +52,7 @@ mi_console_file_new (struct ui_file *raw, mi_console->raw = raw; mi_console->buffer = mem_fileopen (); mi_console->prefix = prefix; + mi_console->quote = quote; set_ui_file_fputs (ui_file, mi_console_file_fputs); set_ui_file_flush (ui_file, mi_console_file_flush); set_ui_file_data (ui_file, mi_console, mi_console_file_delete); @@ -99,9 +98,17 @@ mi_console_raw_packet (void *data, if (length_buf > 0) { fputs_unfiltered (mi_console->prefix, mi_console->raw); - fputs_unfiltered ("\"", mi_console->raw); - fputstrn_unfiltered (buf, length_buf, '"', mi_console->raw); - fputs_unfiltered ("\"\n", mi_console->raw); + if (mi_console->quote) + { + fputs_unfiltered ("\"", mi_console->raw); + fputstrn_unfiltered (buf, length_buf, mi_console->quote, mi_console->raw); + fputs_unfiltered ("\"\n", mi_console->raw); + } + else + { + fputstrn_unfiltered (buf, length_buf, 0, mi_console->raw); + fputs_unfiltered ("\n", mi_console->raw); + } gdb_flush (mi_console->raw); } } diff --git a/contrib/gdb/gdb/mi/mi-console.h b/contrib/gdb/gdb/mi/mi-console.h index 6bd03cbd924..bc6c0085398 100644 --- a/contrib/gdb/gdb/mi/mi-console.h +++ b/contrib/gdb/gdb/mi/mi-console.h @@ -22,6 +22,8 @@ #ifndef MI_CONSOLE_H #define MI_CONSOLE_H -extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix); +extern struct ui_file *mi_console_file_new (struct ui_file *raw, + const char *prefix, + char quote); #endif diff --git a/contrib/gdb/gdb/mi/mi-getopt.c b/contrib/gdb/gdb/mi/mi-getopt.c index 59ccdf3efd0..3f2a9021002 100644 --- a/contrib/gdb/gdb/mi/mi-getopt.c +++ b/contrib/gdb/gdb/mi/mi-getopt.c @@ -74,3 +74,19 @@ mi_getopt (const char *prefix, } error ("%s: Unknown option ``%s''", prefix, arg + 1); } + +int +mi_valid_noargs (const char *prefix, int argc, char **argv) +{ + int optind = 0; + char *optarg; + static struct mi_opt opts[] = + { + 0 + }; + + if (mi_getopt (prefix, argc, argv, opts, &optind, &optarg) == -1) + return 1; + else + return 0; +} diff --git a/contrib/gdb/gdb/mi/mi-getopt.h b/contrib/gdb/gdb/mi/mi-getopt.h index 6b31adf029a..17d66fb2654 100644 --- a/contrib/gdb/gdb/mi/mi-getopt.h +++ b/contrib/gdb/gdb/mi/mi-getopt.h @@ -57,4 +57,24 @@ struct mi_opt struct mi_opt; +/* mi_valid_noargs + + Determines if ARGC/ARGV are a valid set of parameters to satisfy + an MI function that is not supposed to recieve any arguments. + + An MI function that should not recieve arguments can still be + passed parameters after the special option '--' such as below. + + Example: The MI function -exec-run takes no args. + However, the client may pass '-exec-run -- -a ...' + See PR-783 + + PREFIX is passed to mi_getopt for an error message. + + This function Returns 1 if the parameter pair ARGC/ARGV are valid + for an MI function that takes no arguments. Otherwise, it returns 0 + and the appropriate error message is displayed by mi_getopt. */ + +extern int mi_valid_noargs (const char *prefix, int argc, char **argv); + #endif diff --git a/contrib/gdb/gdb/mi/mi-interp.c b/contrib/gdb/gdb/mi/mi-interp.c new file mode 100644 index 00000000000..08201ca5bb2 --- /dev/null +++ b/contrib/gdb/gdb/mi/mi-interp.c @@ -0,0 +1,406 @@ +/* MI Interpreter Definitions and Commands for GDB, the GNU debugger. + + Copyright 2002, 2003, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_string.h" +#include "interps.h" +#include "event-top.h" +#include "event-loop.h" +#include "inferior.h" +#include "ui-out.h" +#include "top.h" + +#include "mi-main.h" +#include "mi-cmds.h" +#include "mi-out.h" +#include "mi-console.h" + +struct mi_interp +{ + /* MI's output channels */ + struct ui_file *out; + struct ui_file *err; + struct ui_file *log; + struct ui_file *targ; + struct ui_file *event_channel; + + /* This is the interpreter for the mi... */ + struct interp *mi2_interp; + struct interp *mi1_interp; + struct interp *mi_interp; +}; + +/* These are the interpreter setup, etc. functions for the MI interpreter */ +static void mi_execute_command_wrapper (char *cmd); +static void mi_command_loop (int mi_version); +static char *mi_input (char *); + +/* These are hooks that we put in place while doing interpreter_exec + so we can report interesting things that happened "behind the mi's + back" in this command */ +static int mi_interp_query_hook (const char *ctlstr, va_list ap); + +static void mi3_command_loop (void); +static void mi2_command_loop (void); +static void mi1_command_loop (void); + +static void mi_insert_notify_hooks (void); +static void mi_remove_notify_hooks (void); + +static void * +mi_interpreter_init (void) +{ + struct mi_interp *mi = XMALLOC (struct mi_interp); + + /* Why is this a part of the mi architecture? */ + + mi_setup_architecture_data (); + + /* HACK: We need to force stdout/stderr to point at the console. This avoids + any potential side effects caused by legacy code that is still + using the TUI / fputs_unfiltered_hook. So we set up output channels for + this now, and swap them in when we are run. */ + + raw_stdout = stdio_fileopen (stdout); + + /* Create MI channels */ + mi->out = mi_console_file_new (raw_stdout, "~", '"'); + mi->err = mi_console_file_new (raw_stdout, "&", '"'); + mi->log = mi->err; + mi->targ = mi_console_file_new (raw_stdout, "@", '"'); + mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); + + return mi; +} + +static int +mi_interpreter_resume (void *data) +{ + struct mi_interp *mi = data; + /* As per hack note in mi_interpreter_init, swap in the output channels... */ + + gdb_setup_readline (); + + if (event_loop_p) + { + /* These overwrite some of the initialization done in + _intialize_event_loop. */ + call_readline = gdb_readline2; + input_handler = mi_execute_command_wrapper; + add_file_handler (input_fd, stdin_event_handler, 0); + async_command_editing_p = 0; + /* FIXME: This is a total hack for now. PB's use of the MI implicitly + relies on a bug in the async support which allows asynchronous + commands to leak through the commmand loop. The bug involves + (but is not limited to) the fact that sync_execution was + erroneously initialized to 0. Duplicate by initializing it + thus here... */ + sync_execution = 0; + } + + gdb_stdout = mi->out; + /* Route error and log output through the MI */ + gdb_stderr = mi->err; + gdb_stdlog = mi->log; + /* Route target output through the MI. */ + gdb_stdtarg = mi->targ; + + /* Replace all the hooks that we know about. There really needs to + be a better way of doing this... */ + clear_interpreter_hooks (); + + show_load_progress = mi_load_progress; + + /* If we're _the_ interpreter, take control. */ + if (current_interp_named_p (INTERP_MI1)) + command_loop_hook = mi1_command_loop; + else if (current_interp_named_p (INTERP_MI2)) + command_loop_hook = mi2_command_loop; + else if (current_interp_named_p (INTERP_MI3)) + command_loop_hook = mi3_command_loop; + else + command_loop_hook = mi2_command_loop; + + return 1; +} + +static int +mi_interpreter_suspend (void *data) +{ + gdb_disable_readline (); + return 1; +} + +static int +mi_interpreter_exec (void *data, const char *command) +{ + char *tmp = alloca (strlen (command) + 1); + strcpy (tmp, command); + mi_execute_command_wrapper (tmp); + return 1; +} + +/* Never display the default gdb prompt in mi case. */ +static int +mi_interpreter_prompt_p (void *data) +{ + return 0; +} + +static void +mi_interpreter_exec_continuation (struct continuation_arg *arg) +{ + bpstat_do_actions (&stop_bpstat); + if (!target_executing) + { + fputs_unfiltered ("*stopped", raw_stdout); + mi_out_put (uiout, raw_stdout); + fputs_unfiltered ("\n", raw_stdout); + fputs_unfiltered ("(gdb) \n", raw_stdout); + gdb_flush (raw_stdout); + do_exec_cleanups (ALL_CLEANUPS); + } + else if (target_can_async_p ()) + { + add_continuation (mi_interpreter_exec_continuation, NULL); + } +} + +enum mi_cmd_result +mi_cmd_interpreter_exec (char *command, char **argv, int argc) +{ + struct interp *interp_to_use; + enum mi_cmd_result result = MI_CMD_DONE; + int i; + struct interp_procs *procs; + + if (argc < 2) + { + xasprintf (&mi_error_message, + "mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command"); + return MI_CMD_ERROR; + } + + interp_to_use = interp_lookup (argv[0]); + if (interp_to_use == NULL) + { + xasprintf (&mi_error_message, + "mi_cmd_interpreter_exec: could not find interpreter \"%s\"", + argv[0]); + return MI_CMD_ERROR; + } + + if (!interp_exec_p (interp_to_use)) + { + xasprintf (&mi_error_message, + "mi_cmd_interpreter_exec: interpreter \"%s\" does not support command execution", + argv[0]); + return MI_CMD_ERROR; + } + + /* Insert the MI out hooks, making sure to also call the interpreter's hooks + if it has any. */ + /* KRS: We shouldn't need this... Events should be installed and they should + just ALWAYS fire something out down the MI channel... */ + mi_insert_notify_hooks (); + + /* Now run the code... */ + + for (i = 1; i < argc; i++) + { + char *buff = NULL; + /* Do this in a cleaner way... We want to force execution to be + asynchronous for commands that run the target. */ + if (target_can_async_p () && (strcmp (argv[0], "console") == 0)) + { + int len = strlen (argv[i]); + buff = xmalloc (len + 2); + memcpy (buff, argv[i], len); + buff[len] = '&'; + buff[len + 1] = '\0'; + } + + /* We had to set sync_execution = 0 for the mi (well really for Project + Builder's use of the mi - particularly so interrupting would work. + But for console commands to work, we need to initialize it to 1 - + since that is what the cli expects - before running the command, + and then set it back to 0 when we are done. */ + sync_execution = 1; + if (interp_exec (interp_to_use, argv[i]) < 0) + { + mi_error_last_message (); + result = MI_CMD_ERROR; + break; + } + xfree (buff); + do_exec_error_cleanups (ALL_CLEANUPS); + sync_execution = 0; + } + + mi_remove_notify_hooks (); + + /* Okay, now let's see if the command set the inferior going... + Tricky point - have to do this AFTER resetting the interpreter, since + changing the interpreter will clear out all the continuations for + that interpreter... */ + + if (target_can_async_p () && target_executing) + { + fputs_unfiltered ("^running\n", raw_stdout); + add_continuation (mi_interpreter_exec_continuation, NULL); + } + + return result; +} + +/* + * mi_insert_notify_hooks - This inserts a number of hooks that are meant to produce + * async-notify ("=") MI messages while running commands in another interpreter + * using mi_interpreter_exec. The canonical use for this is to allow access to + * the gdb CLI interpreter from within the MI, while still producing MI style output + * when actions in the CLI command change gdb's state. +*/ + +static void +mi_insert_notify_hooks (void) +{ + query_hook = mi_interp_query_hook; +} + +static void +mi_remove_notify_hooks (void) +{ + query_hook = NULL; +} + +static int +mi_interp_query_hook (const char *ctlstr, va_list ap) +{ + return 1; +} + +static void +mi_execute_command_wrapper (char *cmd) +{ + mi_execute_command (cmd, stdin == instream); +} + +static void +mi1_command_loop (void) +{ + mi_command_loop (1); +} + +static void +mi2_command_loop (void) +{ + mi_command_loop (2); +} + +static void +mi3_command_loop (void) +{ + mi_command_loop (3); +} + +static void +mi_command_loop (int mi_version) +{ +#if 0 + /* HACK: Force stdout/stderr to point at the console. This avoids + any potential side effects caused by legacy code that is still + using the TUI / fputs_unfiltered_hook */ + raw_stdout = stdio_fileopen (stdout); + /* Route normal output through the MIx */ + gdb_stdout = mi_console_file_new (raw_stdout, "~", '"'); + /* Route error and log output through the MI */ + gdb_stderr = mi_console_file_new (raw_stdout, "&", '"'); + gdb_stdlog = gdb_stderr; + /* Route target output through the MI. */ + gdb_stdtarg = mi_console_file_new (raw_stdout, "@", '"'); + /* HACK: Poke the ui_out table directly. Should we be creating a + mi_out object wired up to the above gdb_stdout / gdb_stderr? */ + uiout = mi_out_new (mi_version); + /* HACK: Override any other interpreter hooks. We need to create a + real event table and pass in that. */ + init_ui_hook = 0; + /* command_loop_hook = 0; */ + print_frame_info_listing_hook = 0; + query_hook = 0; + warning_hook = 0; + create_breakpoint_hook = 0; + delete_breakpoint_hook = 0; + modify_breakpoint_hook = 0; + interactive_hook = 0; + registers_changed_hook = 0; + readline_begin_hook = 0; + readline_hook = 0; + readline_end_hook = 0; + register_changed_hook = 0; + memory_changed_hook = 0; + context_hook = 0; + target_wait_hook = 0; + call_command_hook = 0; + error_hook = 0; + error_begin_hook = 0; + show_load_progress = mi_load_progress; +#endif + /* Turn off 8 bit strings in quoted output. Any character with the + high bit set is printed using C's octal format. */ + sevenbit_strings = 1; + /* Tell the world that we're alive */ + fputs_unfiltered ("(gdb) \n", raw_stdout); + gdb_flush (raw_stdout); + if (!event_loop_p) + simplified_command_loop (mi_input, mi_execute_command); + else + start_event_loop (); +} + +static char * +mi_input (char *buf) +{ + return gdb_readline (NULL); +} + +extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ + +void +_initialize_mi_interp (void) +{ + static const struct interp_procs procs = + { + mi_interpreter_init, /* init_proc */ + mi_interpreter_resume, /* resume_proc */ + mi_interpreter_suspend, /* suspend_proc */ + mi_interpreter_exec, /* exec_proc */ + mi_interpreter_prompt_p /* prompt_proc_p */ + }; + + /* The various interpreter levels. */ + interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs)); + interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs)); + interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs)); + + /* "mi" selects the most recent released version. "mi2" was + released as part of GDB 6.0. */ + interp_add (interp_new (INTERP_MI, NULL, mi_out_new (2), &procs)); +} diff --git a/contrib/gdb/gdb/mi/mi-main.c b/contrib/gdb/gdb/mi/mi-main.c index 3a59fc88dec..c46bf636597 100644 --- a/contrib/gdb/gdb/mi/mi-main.c +++ b/contrib/gdb/gdb/mi/mi-main.c @@ -1,5 +1,8 @@ /* MI Command Set. - Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, + Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -33,25 +36,47 @@ #include "mi-console.h" #include "ui-out.h" #include "mi-out.h" +#include "interps.h" #include "event-loop.h" #include "event-top.h" #include "gdbcore.h" /* for write_memory() */ -#include "value.h" /* for write_register_bytes() */ +#include "value.h" /* for deprecated_write_register_bytes() */ #include "regcache.h" #include "gdb.h" +#include "frame.h" +#include "mi-main.h" + #include #include -/* Convenience macro for allocting typesafe memory. */ - -#undef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) - enum { FROM_TTY = 0 }; +/* Enumerations of the actions that may result from calling + captured_mi_execute_command */ + +enum captured_mi_execute_command_actions + { + EXECUTE_COMMAND_DISPLAY_PROMPT, + EXECUTE_COMMAND_SUPRESS_PROMPT, + EXECUTE_COMMAND_DISPLAY_ERROR + }; + +/* This structure is used to pass information from captured_mi_execute_command + to mi_execute_command. */ +struct captured_mi_execute_command_args +{ + /* This return result of the MI command (output) */ + enum mi_cmd_result rc; + + /* What action to perform when the call is finished (output) */ + enum captured_mi_execute_command_actions action; + + /* The command context to be executed (input) */ + struct mi_parse *command; +}; int mi_debug_p; struct ui_file *raw_stdout; @@ -59,33 +84,30 @@ struct ui_file *raw_stdout; /* The token of the last asynchronous command */ static char *last_async_command; static char *previous_async_command; -static char *mi_error_message; +char *mi_error_message; static char *old_regs; extern void _initialize_mi_main (void); -static char *mi_input (char *); -static void mi_execute_command (char *cmd, int from_tty); static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse); -static void mi_execute_cli_command (const char *cli, char *args); +static void mi_execute_cli_command (const char *cmd, int args_p, + const char *args); static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty); -static void mi_execute_command_wrapper (char *cmd); -void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg); +static void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg); static int register_changed_p (int regnum); static int get_register (int regnum, int format); -static void mi_load_progress (const char *section_name, - unsigned long sent_so_far, - unsigned long total_section, - unsigned long total_sent, - unsigned long grand_total); -/* FIXME: these should go in some .h file, but infcmd.c doesn't have a - corresponding .h file. These wrappers will be obsolete anyway, once - we pull the plug on the sanitization. */ -extern void interrupt_target_command_wrapper (char *, int); -extern void return_command_wrapper (char *, int); +/* A helper function which will set mi_error_message to + error_last_message. */ +void +mi_error_last_message (void) +{ + char *s = error_last_message (); + xasprintf (&mi_error_message, "%s", s); + xfree (s); +} /* Command implementations. FIXME: Is this libgdb? No. This is the MI layer that calls libgdb. Any operation used in the below should be @@ -161,17 +183,17 @@ mi_cmd_exec_return (char *args, int from_tty) if (*args) /* Call return_command with from_tty argument equal to 0 so as to avoid being queried. */ - return_command_wrapper (args, 0); + return_command (args, 0); else /* Call return_command with from_tty argument equal to 0 so as to avoid being queried. */ - return_command_wrapper (NULL, 0); + return_command (NULL, 0); /* Because we have called return_command with from_tty = 0, we need to print the frame here. */ - show_and_print_stack_frame (selected_frame, - selected_frame_level, - LOC_AND_ADDRESS); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), + LOC_AND_ADDRESS); return MI_CMD_DONE; } @@ -197,7 +219,7 @@ mi_cmd_exec_interrupt (char *args, int from_tty) "mi_cmd_exec_interrupt: Inferior not executing."); return MI_CMD_ERROR; } - interrupt_target_command_wrapper (args, from_tty); + interrupt_target_command (args, from_tty); if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^done", raw_stdout); @@ -226,8 +248,12 @@ mi_cmd_thread_select (char *command, char **argv, int argc) else rc = gdb_thread_select (uiout, argv[0]); - if (rc == GDB_RC_FAIL) + /* RC is enum gdb_rc if it is successful (>=0) + enum return_reason if not (<0). */ + if ((int) rc < 0 && (enum return_reason) rc == RETURN_ERROR) return MI_CMD_CAUGHT_ERROR; + else if ((int) rc >= 0 && rc == GDB_RC_FAIL) + return MI_CMD_ERROR; else return MI_CMD_DONE; } @@ -257,6 +283,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) { int regnum, numregs; int i; + struct cleanup *cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of @@ -266,7 +293,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) numregs = NUM_REGS + NUM_PSEUDO_REGS; - ui_out_list_begin (uiout, "register-names"); + cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-names"); if (argc == 0) /* No args, just do all the regs */ { @@ -288,6 +315,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) regnum = atoi (argv[i]); if (regnum < 0 || regnum >= numregs) { + do_cleanups (cleanup); xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } @@ -297,7 +325,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) else ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum)); } - ui_out_list_end (uiout); + do_cleanups (cleanup); return MI_CMD_DONE; } @@ -306,6 +334,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) { int regnum, numregs, changed; int i; + struct cleanup *cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of @@ -315,7 +344,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) numregs = NUM_REGS; - ui_out_list_begin (uiout, "changed-registers"); + cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changed-registers"); if (argc == 0) /* No args, just do all the regs */ { @@ -329,6 +358,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) changed = register_changed_p (regnum); if (changed < 0) { + do_cleanups (cleanup); xasprintf (&mi_error_message, "mi_cmd_data_list_changed_registers: Unable to read register contents."); return MI_CMD_ERROR; @@ -351,6 +381,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) changed = register_changed_p (regnum); if (changed < 0) { + do_cleanups (cleanup); xasprintf (&mi_error_message, "mi_cmd_data_list_register_change: Unable to read register contents."); return MI_CMD_ERROR; @@ -360,30 +391,31 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) } else { + do_cleanups (cleanup); xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } } - ui_out_list_end (uiout); + do_cleanups (cleanup); return MI_CMD_DONE; } static int register_changed_p (int regnum) { - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; - if (read_relative_register_raw_bytes (regnum, raw_buffer)) + if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer)) return -1; - if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, - REGISTER_RAW_SIZE (regnum)) == 0) + if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (regnum)) == 0) return 0; /* Found a changed register. Return 1. */ - memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, - REGISTER_RAW_SIZE (regnum)); + memcpy (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (regnum)); return 1; } @@ -400,6 +432,7 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) { int regnum, numregs, format, result; int i; + struct cleanup *list_cleanup, *tuple_cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of @@ -425,7 +458,7 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) return MI_CMD_ERROR; } - ui_out_list_begin (uiout, "register-values"); + list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values"); if (argc == 1) /* No args, beside the format: do all the regs */ { @@ -436,12 +469,15 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) if (REGISTER_NAME (regnum) == NULL || *(REGISTER_NAME (regnum)) == '\0') continue; - ui_out_tuple_begin (uiout, NULL); + tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_int (uiout, "number", regnum); result = get_register (regnum, format); if (result == -1) - return MI_CMD_ERROR; - ui_out_tuple_end (uiout); + { + do_cleanups (list_cleanup); + return MI_CMD_ERROR; + } + do_cleanups (tuple_cleanup); } } @@ -455,20 +491,24 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) && REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\000') { - ui_out_tuple_begin (uiout, NULL); + tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_int (uiout, "number", regnum); result = get_register (regnum, format); if (result == -1) - return MI_CMD_ERROR; - ui_out_tuple_end (uiout); + { + do_cleanups (list_cleanup); + return MI_CMD_ERROR; + } + do_cleanups (tuple_cleanup); } else { + do_cleanups (list_cleanup); xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } } - ui_out_list_end (uiout); + do_cleanups (list_cleanup); return MI_CMD_DONE; } @@ -476,9 +516,12 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) static int get_register (int regnum, int format) { - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); - char *virtual_buffer = alloca (MAX_REGISTER_VIRTUAL_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; + char virtual_buffer[MAX_REGISTER_SIZE]; int optim; + int realnum; + CORE_ADDR addr; + enum lval_type lval; static struct ui_stream *stb = NULL; stb = ui_out_stream_new (uiout); @@ -486,12 +529,9 @@ get_register (int regnum, int format) if (format == 'N') format = 0; - /* read_relative_register_raw_bytes returns a virtual frame pointer - (FRAME_FP (selected_frame)) if regnum == FP_REGNUM instead - of the real contents of the register. To get around this, - use get_saved_register instead. */ - get_saved_register (raw_buffer, &optim, (CORE_ADDR *) NULL, selected_frame, - regnum, (enum lval_type *) NULL); + frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr, + &realnum, raw_buffer); + if (optim) { xasprintf (&mi_error_message, "Optimized out"); @@ -500,13 +540,15 @@ get_register (int regnum, int format) /* Convert raw data to virtual format if necessary. */ - if (REGISTER_CONVERTIBLE (regnum)) + if (DEPRECATED_REGISTER_CONVERTIBLE_P () + && DEPRECATED_REGISTER_CONVERTIBLE (regnum)) { - REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), + DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, + register_type (current_gdbarch, regnum), raw_buffer, virtual_buffer); } else - memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum)); + memcpy (virtual_buffer, raw_buffer, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); if (format == 'r') { @@ -515,10 +557,10 @@ get_register (int regnum, int format) strcpy (buf, "0x"); ptr = buf + 2; - for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++) + for (j = 0; j < DEPRECATED_REGISTER_RAW_SIZE (regnum); j++) { - register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j - : REGISTER_RAW_SIZE (regnum) - 1 - j; + int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j + : DEPRECATED_REGISTER_RAW_SIZE (regnum) - 1 - j; sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]); ptr += 2; } @@ -527,7 +569,7 @@ get_register (int regnum, int format) } else { - val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, 0, + val_print (register_type (current_gdbarch, regnum), virtual_buffer, 0, 0, stb->stream, format, 1, 0, Val_pretty_default); ui_out_field_stream (uiout, "value", stb); ui_out_stream_delete (stb); @@ -600,11 +642,11 @@ mi_cmd_data_write_register_values (char *command, char **argv, int argc) /* Get the value as a number */ value = parse_and_eval_address (argv[i + 1]); /* Get the value into an array */ - buffer = xmalloc (REGISTER_SIZE); + buffer = xmalloc (DEPRECATED_REGISTER_SIZE); old_chain = make_cleanup (xfree, buffer); - store_signed_integer (buffer, REGISTER_SIZE, value); + store_signed_integer (buffer, DEPRECATED_REGISTER_SIZE, value); /* Write it down */ - write_register_bytes (REGISTER_BYTE (regnum), buffer, REGISTER_RAW_SIZE (regnum)); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (regnum), buffer, DEPRECATED_REGISTER_RAW_SIZE (regnum)); /* Free the buffer. */ do_cleanups (old_chain); } @@ -887,19 +929,22 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc) /* Build the result as a two dimentional table. */ { struct ui_stream *stream = ui_out_stream_new (uiout); + struct cleanup *cleanup_list_memory; int row; int row_byte; - ui_out_list_begin (uiout, "memory"); + cleanup_list_memory = make_cleanup_ui_out_list_begin_end (uiout, "memory"); for (row = 0, row_byte = 0; row < nr_rows; row++, row_byte += nr_cols * word_size) { int col; int col_byte; - ui_out_tuple_begin (uiout, NULL); + struct cleanup *cleanup_tuple; + struct cleanup *cleanup_list_data; + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_core_addr (uiout, "addr", addr + row_byte); /* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */ - ui_out_list_begin (uiout, "data"); + cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data"); for (col = 0, col_byte = row_byte; col < nr_cols; col++, col_byte += word_size) @@ -916,7 +961,7 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc) ui_out_field_stream (uiout, NULL, stream); } } - ui_out_list_end (uiout); + do_cleanups (cleanup_list_data); if (aschar) { int byte; @@ -936,10 +981,10 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc) } ui_out_field_stream (uiout, "ascii", stream); } - ui_out_tuple_end (uiout); + do_cleanups (cleanup_tuple); } ui_out_stream_delete (stream); - ui_out_list_end (uiout); + do_cleanups (cleanup_list_memory); } do_cleanups (cleanups); return MI_CMD_DONE; @@ -1034,15 +1079,19 @@ mi_cmd_data_write_memory (char *command, char **argv, int argc) return MI_CMD_DONE; } -/* Execute a command within a safe environment. Return >0 for - ok. Return <0 for supress prompt. Return 0 to have the error - extracted from error_last_message(). */ +/* Execute a command within a safe environment. + Return <0 for error; >=0 for ok. + + args->action will tell mi_execute_command what action + to perfrom after the given command has executed (display/supress + prompt, display error). */ static int -captured_mi_execute_command (void *data) +captured_mi_execute_command (struct ui_out *uiout, void *data) { - struct mi_parse *context = data; - enum mi_cmd_result rc; + struct captured_mi_execute_command_args *args = + (struct captured_mi_execute_command_args *) data; + struct mi_parse *context = args->command; switch (context->op) { @@ -1057,11 +1106,18 @@ captured_mi_execute_command (void *data) condition expression, each function should return an indication of what action is required and then switch on that. */ - rc = mi_cmd_execute (context); + args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; + args->rc = mi_cmd_execute (context); + if (!target_can_async_p () || !target_executing) { - /* print the result if there were no errors */ - if (rc == MI_CMD_DONE) + /* print the result if there were no errors + + Remember that on the way out of executing a command, you have + to directly use the mi_interp's uiout, since the command could + have reset the interpreter, in which case the current uiout + will most likely crash in the mi_out_* routines. */ + if (args->rc == MI_CMD_DONE) { fputs_unfiltered (context->token, raw_stdout); fputs_unfiltered ("^done", raw_stdout); @@ -1069,7 +1125,7 @@ captured_mi_execute_command (void *data) mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); } - else if (rc == MI_CMD_ERROR) + else if (args->rc == MI_CMD_ERROR) { if (mi_error_message) { @@ -1081,18 +1137,22 @@ captured_mi_execute_command (void *data) } mi_out_rewind (uiout); } - else if (rc == MI_CMD_CAUGHT_ERROR) + else if (args->rc == MI_CMD_CAUGHT_ERROR) { mi_out_rewind (uiout); - return 0; + args->action = EXECUTE_COMMAND_DISPLAY_ERROR; + return 1; } else mi_out_rewind (uiout); } else if (sync_execution) - /* Don't print the prompt. We are executing the target in - synchronous mode. */ - return -1; + { + /* Don't print the prompt. We are executing the target in + synchronous mode. */ + args->action = EXECUTE_COMMAND_SUPRESS_PROMPT; + return 1; + } break; case CLI_COMMAND: @@ -1101,19 +1161,28 @@ captured_mi_execute_command (void *data) mi commands */ /* echo the command on the console. */ fprintf_unfiltered (gdb_stdlog, "%s\n", context->command); - /* FIXME: If the command string has something that looks like - a format spec (e.g. %s) we will get a core dump */ - mi_execute_cli_command ("%s", context->command); - /* print the result */ - /* FIXME: Check for errors here. */ - fputs_unfiltered (context->token, raw_stdout); - fputs_unfiltered ("^done", raw_stdout); - mi_out_put (uiout, raw_stdout); - mi_out_rewind (uiout); - fputs_unfiltered ("\n", raw_stdout); + mi_execute_cli_command (context->command, 0, NULL); + + /* If we changed interpreters, DON'T print out anything. */ + if (current_interp_named_p (INTERP_MI) + || current_interp_named_p (INTERP_MI1) + || current_interp_named_p (INTERP_MI2) + || current_interp_named_p (INTERP_MI3)) + { + /* print the result */ + /* FIXME: Check for errors here. */ + fputs_unfiltered (context->token, raw_stdout); + fputs_unfiltered ("^done", raw_stdout); + mi_out_put (uiout, raw_stdout); + mi_out_rewind (uiout); + fputs_unfiltered ("\n", raw_stdout); + args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; + args->rc = MI_CMD_DONE; + } break; } + return 1; } @@ -1122,6 +1191,9 @@ void mi_execute_command (char *cmd, int from_tty) { struct mi_parse *command; + struct captured_mi_execute_command_args args; + struct ui_out *saved_uiout = uiout; + int result; /* This is to handle EOF (^D). We just quit gdb. */ /* FIXME: we should call some API function here. */ @@ -1132,18 +1204,20 @@ mi_execute_command (char *cmd, int from_tty) if (command != NULL) { - /* FIXME: cagney/1999-11-04: Can this use of catch_errors either + /* FIXME: cagney/1999-11-04: Can this use of catch_exceptions either be pushed even further down or even eliminated? */ - int rc = catch_errors (captured_mi_execute_command, command, "", - RETURN_MASK_ALL); - if (rc < 0) + args.command = command; + result = catch_exceptions (uiout, captured_mi_execute_command, &args, "", + RETURN_MASK_ALL); + + if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT) { /* The command is executing synchronously. Bail out early suppressing the finished prompt. */ mi_parse_free (command); return; } - if (rc == 0) + if (args.action == EXECUTE_COMMAND_DISPLAY_ERROR || result < 0) { char *msg = error_last_message (); struct cleanup *cleanup = make_cleanup (xfree, msg); @@ -1206,12 +1280,13 @@ mi_cmd_execute (struct mi_parse *parse) return parse->cmd->args_func (parse->args, 0 /*from_tty */ ); return parse->cmd->argv_func (parse->command, parse->argv, parse->argc); } - else if (parse->cmd->cli != 0) + else if (parse->cmd->cli.cmd != 0) { /* FIXME: DELETE THIS. */ /* The operation is still implemented by a cli command */ /* Must be a synchronous one */ - mi_execute_cli_command (parse->cmd->cli, parse->args); + mi_execute_cli_command (parse->cmd->cli.cmd, parse->cmd->cli.args_p, + parse->args); return MI_CMD_DONE; } else @@ -1227,28 +1302,25 @@ mi_cmd_execute (struct mi_parse *parse) } } -static void -mi_execute_command_wrapper (char *cmd) -{ - mi_execute_command (cmd, stdin == instream); -} - /* FIXME: This is just a hack so we can get some extra commands going. We don't want to channel things through the CLI, but call libgdb directly */ /* Use only for synchronous commands */ void -mi_execute_cli_command (const char *cli, char *args) +mi_execute_cli_command (const char *cmd, int args_p, const char *args) { - if (cli != 0) + if (cmd != 0) { struct cleanup *old_cleanups; char *run; - xasprintf (&run, cli, args); + if (args_p) + xasprintf (&run, "%s %s", cmd, args); + else + run = xstrdup (cmd); if (mi_debug_p) /* FIXME: gdb_???? */ fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n", - cli, run); + cmd, run); old_cleanups = make_cleanup (xfree, run); execute_command ( /*ui */ run, 0 /*from_tty */ ); do_cleanups (old_cleanups); @@ -1335,13 +1407,7 @@ mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg) do_exec_cleanups (ALL_CLEANUPS); } -static char * -mi_input (char *buf) -{ - return gdb_readline (NULL); -} - -static void +void mi_load_progress (const char *section_name, unsigned long sent_so_far, unsigned long total_section, @@ -1353,7 +1419,8 @@ mi_load_progress (const char *section_name, static char *previous_sect_name = NULL; int new_section; - if (!interpreter_p || strncmp (interpreter_p, "mi", 2) != 0) + if (!current_interp_named_p (INTERP_MI) + && !current_interp_named_p (INTERP_MI1)) return; update_threshold.tv_sec = 0; @@ -1373,17 +1440,18 @@ mi_load_progress (const char *section_name, strcmp (previous_sect_name, section_name) : 1); if (new_section) { + struct cleanup *cleanup_tuple; xfree (previous_sect_name); previous_sect_name = xstrdup (section_name); if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("+download", raw_stdout); - ui_out_tuple_begin (uiout, NULL); + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "section", section_name); ui_out_field_int (uiout, "section-size", total_section); ui_out_field_int (uiout, "total-size", grand_total); - ui_out_tuple_end (uiout); + do_cleanups (cleanup_tuple); mi_out_put (uiout, raw_stdout); fputs_unfiltered ("\n", raw_stdout); gdb_flush (raw_stdout); @@ -1392,136 +1460,35 @@ mi_load_progress (const char *section_name, if (delta.tv_sec >= update_threshold.tv_sec && delta.tv_usec >= update_threshold.tv_usec) { + struct cleanup *cleanup_tuple; last_update.tv_sec = time_now.tv_sec; last_update.tv_usec = time_now.tv_usec; if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("+download", raw_stdout); - ui_out_tuple_begin (uiout, NULL); + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "section", section_name); ui_out_field_int (uiout, "section-sent", sent_so_far); ui_out_field_int (uiout, "section-size", total_section); ui_out_field_int (uiout, "total-sent", total_sent); ui_out_field_int (uiout, "total-size", grand_total); - ui_out_tuple_end (uiout); + do_cleanups (cleanup_tuple); mi_out_put (uiout, raw_stdout); fputs_unfiltered ("\n", raw_stdout); gdb_flush (raw_stdout); } } -static void -mi_command_loop (int mi_version) +void +mi_setup_architecture_data (void) { - /* HACK: Force stdout/stderr to point at the console. This avoids - any potential side effects caused by legacy code that is still - using the TUI / fputs_unfiltered_hook */ - raw_stdout = stdio_fileopen (stdout); - /* Route normal output through the MIx */ - gdb_stdout = mi_console_file_new (raw_stdout, "~"); - /* Route error and log output through the MI */ - gdb_stderr = mi_console_file_new (raw_stdout, "&"); - gdb_stdlog = gdb_stderr; - /* Route target output through the MI. */ - gdb_stdtarg = mi_console_file_new (raw_stdout, "@"); - - /* HACK: Poke the ui_out table directly. Should we be creating a - mi_out object wired up to the above gdb_stdout / gdb_stderr? */ - uiout = mi_out_new (mi_version); - - /* HACK: Override any other interpreter hooks. We need to create a - real event table and pass in that. */ - init_ui_hook = 0; - /* command_loop_hook = 0; */ - print_frame_info_listing_hook = 0; - query_hook = 0; - warning_hook = 0; - create_breakpoint_hook = 0; - delete_breakpoint_hook = 0; - modify_breakpoint_hook = 0; - interactive_hook = 0; - registers_changed_hook = 0; - readline_begin_hook = 0; - readline_hook = 0; - readline_end_hook = 0; - register_changed_hook = 0; - memory_changed_hook = 0; - context_hook = 0; - target_wait_hook = 0; - call_command_hook = 0; - error_hook = 0; - error_begin_hook = 0; - show_load_progress = mi_load_progress; - - /* Turn off 8 bit strings in quoted output. Any character with the - high bit set is printed using C's octal format. */ - sevenbit_strings = 1; - - /* Tell the world that we're alive */ - fputs_unfiltered ("(gdb) \n", raw_stdout); - gdb_flush (raw_stdout); - - if (!event_loop_p) - simplified_command_loop (mi_input, mi_execute_command); - else - start_event_loop (); -} - -static void -mi0_command_loop (void) -{ - mi_command_loop (0); -} - -static void -mi1_command_loop (void) -{ - mi_command_loop (1); -} - -static void -setup_architecture_data (void) -{ - /* don't trust REGISTER_BYTES to be zero. */ - old_regs = xmalloc (REGISTER_BYTES + 1); - memset (old_regs, 0, REGISTER_BYTES + 1); -} - -static void -mi_init_ui (char *arg0) -{ - /* Eventually this will contain code that takes control of the - console. */ + old_regs = xmalloc ((NUM_REGS + NUM_PSEUDO_REGS) * MAX_REGISTER_SIZE + 1); + memset (old_regs, 0, (NUM_REGS + NUM_PSEUDO_REGS) * MAX_REGISTER_SIZE + 1); } void _initialize_mi_main (void) { - if (interpreter_p == NULL) - return; - - /* If we're _the_ interpreter, take control. */ - if (strcmp (interpreter_p, "mi0") == 0) - command_loop_hook = mi0_command_loop; - else if (strcmp (interpreter_p, "mi") == 0 - || strcmp (interpreter_p, "mi1") == 0) - command_loop_hook = mi1_command_loop; - else - return; - - init_ui_hook = mi_init_ui; - setup_architecture_data (); - register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL); - register_gdbarch_swap (NULL, 0, setup_architecture_data); - if (event_loop_p) - { - /* These overwrite some of the initialization done in - _intialize_event_loop. */ - call_readline = gdb_readline2; - input_handler = mi_execute_command_wrapper; - add_file_handler (input_fd, stdin_event_handler, 0); - async_command_editing_p = 0; - } - /* FIXME: Should we notify main that we are here as a possible - interpreter? */ + DEPRECATED_REGISTER_GDBARCH_SWAP (old_regs); + deprecated_register_gdbarch_swap (NULL, 0, mi_setup_architecture_data); } diff --git a/contrib/gdb/gdb/mi/mi-main.h b/contrib/gdb/gdb/mi/mi-main.h new file mode 100644 index 00000000000..8e504c6076e --- /dev/null +++ b/contrib/gdb/gdb/mi/mi-main.h @@ -0,0 +1,33 @@ +/* MI Internal Functions for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MI_MAIN_H +#define MI_MAIN_H + +extern void mi_setup_architecture_data (void); + +extern void mi_load_progress (const char *section_name, + unsigned long sent_so_far, + unsigned long total_section, + unsigned long total_sent, + unsigned long grand_total); +#endif + diff --git a/contrib/gdb/gdb/mi/mi-out.c b/contrib/gdb/gdb/mi/mi-out.c index a92ccbeab8e..2be9d17b357 100644 --- a/contrib/gdb/gdb/mi/mi-out.c +++ b/contrib/gdb/gdb/mi/mi-out.c @@ -1,5 +1,7 @@ /* MI Command Set - output generating routines. - Copyright 2000 Free Software Foundation, Inc. + + Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -23,12 +25,6 @@ #include "ui-out.h" #include "mi-out.h" -/* Convenience macro for allocting typesafe memory. */ - -#ifndef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) -#endif - struct ui_out_data { int suppress_field_separator; @@ -36,6 +32,7 @@ struct ui_out_data int mi_version; struct ui_file *buffer; }; +typedef struct ui_out_data mi_out_data; /* These are the MI output functions */ @@ -89,6 +86,7 @@ struct ui_out_impl mi_ui_out_impl = mi_message, mi_wrap_hint, mi_flush, + NULL, 1, /* Needs MI hacks. */ }; @@ -100,9 +98,6 @@ static void mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type); static void mi_close (struct ui_out *uiout, enum ui_out_type type); -static void out_field_fmt (struct ui_out *uiout, int fldno, char *fldname, - char *format,...); - /* Mark beginning of a table */ void @@ -111,16 +106,8 @@ mi_table_begin (struct ui_out *uiout, int nr_rows, const char *tblid) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); mi_open (uiout, tblid, ui_out_type_tuple); - if (data->mi_version == 0) - { - if (nr_rows == 0) - data->suppress_output = 1; - else - mi_open (uiout, "hdr", ui_out_type_list); - return; - } mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/, "nr_rows", nr_rows); mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/, @@ -133,13 +120,11 @@ mi_table_begin (struct ui_out *uiout, void mi_table_body (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; /* close the table header line if there were any headers */ mi_close (uiout, ui_out_type_list); - if (data->mi_version == 0) - return; mi_open (uiout, "body", ui_out_type_list); } @@ -148,13 +133,8 @@ mi_table_body (struct ui_out *uiout) void mi_table_end (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); data->suppress_output = 0; - if (data->mi_version == 0) - { - mi_close (uiout, ui_out_type_tuple); - return; - } mi_close (uiout, ui_out_type_list); /* body */ mi_close (uiout, ui_out_type_tuple); } @@ -166,14 +146,9 @@ mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment, const char *col_name, const char *colhdr) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; - if (data->mi_version == 0) - { - mi_field_string (uiout, 0, width, alignment, 0, colhdr); - return; - } mi_open (uiout, NULL, ui_out_type_tuple); mi_field_int (uiout, 0, 0, 0, "width", width); mi_field_int (uiout, 0, 0, 0, "alignment", alignment); @@ -190,7 +165,7 @@ mi_begin (struct ui_out *uiout, int level, const char *id) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; mi_open (uiout, id, type); @@ -203,7 +178,7 @@ mi_end (struct ui_out *uiout, enum ui_out_type type, int level) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; mi_close (uiout, type); @@ -216,7 +191,7 @@ mi_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align alignment, const char *fldname, int value) { char buffer[20]; /* FIXME: how many chars long a %d can become? */ - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; @@ -230,7 +205,7 @@ void mi_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align alignment, const char *fldname) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; mi_field_string (uiout, fldno, width, alignment, fldname, ""); @@ -247,7 +222,7 @@ mi_field_string (struct ui_out *uiout, const char *fldname, const char *string) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; field_separator (uiout); @@ -268,7 +243,7 @@ mi_field_fmt (struct ui_out *uiout, int fldno, const char *format, va_list args) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; field_separator (uiout); @@ -306,43 +281,18 @@ mi_wrap_hint (struct ui_out *uiout, char *identstring) void mi_flush (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); gdb_flush (data->buffer); } /* local functions */ -/* Like mi_field_fmt, but takes a variable number of args - and makes a va_list and does not insert a separator */ - -/* VARARGS */ -static void -out_field_fmt (struct ui_out *uiout, int fldno, char *fldname, - char *format,...) -{ - struct ui_out_data *data = ui_out_data (uiout); - va_list args; - - field_separator (uiout); - if (fldname) - fprintf_unfiltered (data->buffer, "%s=\"", fldname); - else - fputs_unfiltered ("\"", data->buffer); - - va_start (args, format); - vfprintf_unfiltered (data->buffer, format, args); - - fputs_unfiltered ("\"", data->buffer); - - va_end (args); -} - /* access to ui_out format private members */ static void field_separator (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); if (data->suppress_field_separator) data->suppress_field_separator = 0; else @@ -354,7 +304,7 @@ mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); field_separator (uiout); data->suppress_field_separator = 1; if (name) @@ -365,10 +315,7 @@ mi_open (struct ui_out *uiout, fputc_unfiltered ('{', data->buffer); break; case ui_out_type_list: - if (data->mi_version == 0) - fputc_unfiltered ('{', data->buffer); - else - fputc_unfiltered ('[', data->buffer); + fputc_unfiltered ('[', data->buffer); break; default: internal_error (__FILE__, __LINE__, "bad switch"); @@ -379,17 +326,14 @@ static void mi_close (struct ui_out *uiout, enum ui_out_type type) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); switch (type) { case ui_out_type_tuple: fputc_unfiltered ('}', data->buffer); break; case ui_out_type_list: - if (data->mi_version == 0) - fputc_unfiltered ('}', data->buffer); - else - fputc_unfiltered (']', data->buffer); + fputc_unfiltered (']', data->buffer); break; default: internal_error (__FILE__, __LINE__, "bad switch"); @@ -402,7 +346,7 @@ mi_close (struct ui_out *uiout, void mi_out_buffered (struct ui_out *uiout, char *string) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); fprintf_unfiltered (data->buffer, "%s", string); } @@ -411,7 +355,7 @@ mi_out_buffered (struct ui_out *uiout, char *string) void mi_out_rewind (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); ui_file_rewind (data->buffer); } @@ -427,18 +371,27 @@ void mi_out_put (struct ui_out *uiout, struct ui_file *stream) { - struct ui_out_data *data = ui_out_data (uiout); + mi_out_data *data = ui_out_data (uiout); ui_file_put (data->buffer, do_write, stream); ui_file_rewind (data->buffer); } +/* Current MI version. */ + +int +mi_version (struct ui_out *uiout) +{ + mi_out_data *data = ui_out_data (uiout); + return data->mi_version; +} + /* initalize private members at startup */ struct ui_out * mi_out_new (int mi_version) { int flags = 0; - struct ui_out_data *data = XMALLOC (struct ui_out_data); + mi_out_data *data = XMALLOC (mi_out_data); data->suppress_field_separator = 0; data->suppress_output = 0; data->mi_version = mi_version; diff --git a/contrib/gdb/gdb/mi/mi-out.h b/contrib/gdb/gdb/mi/mi-out.h index 1ae693f4761..817f2eb53b9 100644 --- a/contrib/gdb/gdb/mi/mi-out.h +++ b/contrib/gdb/gdb/mi/mi-out.h @@ -30,4 +30,7 @@ extern void mi_out_put (struct ui_out *uiout, struct ui_file *stream); extern void mi_out_rewind (struct ui_out *uiout); extern void mi_out_buffered (struct ui_out *uiout, char *string); +/* Return the version number of the current MI. */ +extern int mi_version (struct ui_out *uiout); + #endif /* MI_OUT_H */ diff --git a/contrib/gdb/gdb/mi/mi-parse.c b/contrib/gdb/gdb/mi/mi-parse.c index 2ed49b8b773..a0ff8898ff5 100644 --- a/contrib/gdb/gdb/mi/mi-parse.c +++ b/contrib/gdb/gdb/mi/mi-parse.c @@ -1,5 +1,7 @@ /* MI Command Set - MI parser. - Copyright 2000, 2001 Free Software Foundation, Inc. + + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -26,9 +28,6 @@ #include #include "gdb_string.h" -#undef XMALLOC -#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) - static void mi_parse_argv (char *args, struct mi_parse *parse) { @@ -223,7 +222,7 @@ mi_parse (char *cmd) /* For CLI and old ARGS commands, also return the remainder of the command line as a single string. */ if (parse->cmd->args_func != NULL - || parse->cmd->cli != NULL) + || parse->cmd->cli.cmd != NULL) { parse->args = xstrdup (chp); } @@ -232,8 +231,3 @@ mi_parse (char *cmd) parse->op = MI_COMMAND; return parse; } - -void -_initialize_mi_parse (void) -{ -} diff --git a/contrib/gdb/gdb/mi/mi-symbol-cmds.c b/contrib/gdb/gdb/mi/mi-symbol-cmds.c new file mode 100644 index 00000000000..1d86d21d517 --- /dev/null +++ b/contrib/gdb/gdb/mi/mi-symbol-cmds.c @@ -0,0 +1,67 @@ +/* MI Command Set - symbol commands. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "mi-cmds.h" +#include "symtab.h" +#include "ui-out.h" + +/* SYMBOL-LIST-LINES: + + Print the list of all pc addresses and lines of code for + the provided (full or base) source file name. The entries + are sorted in ascending PC order. */ + +enum mi_cmd_result +mi_cmd_symbol_list_lines (char *command, char **argv, int argc) +{ + char *filename; + struct symtab *s; + int i; + struct cleanup *cleanup_stack, *cleanup_tuple; + + if (argc != 1) + error ("mi_cmd_symbol_list_lines: Usage: SOURCE_FILENAME"); + + filename = argv[0]; + s = lookup_symtab (filename); + + if (s == NULL) + error ("mi_cmd_symbol_list_lines: Unknown source file name."); + + /* Now, dump the associated line table. The pc addresses are already + sorted by increasing values in the symbol table, so no need to + perform any other sorting. */ + + cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "lines"); + + if (LINETABLE (s) != NULL && LINETABLE (s)->nitems > 0) + for (i = 0; i < LINETABLE (s)->nitems; i++) + { + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + ui_out_field_core_addr (uiout, "pc", LINETABLE (s)->item[i].pc); + ui_out_field_int (uiout, "line", LINETABLE (s)->item[i].line); + do_cleanups (cleanup_tuple); + } + + do_cleanups (cleanup_stack); + + return MI_CMD_DONE; +} diff --git a/contrib/gdb/gdb/minimon.h b/contrib/gdb/gdb/minimon.h new file mode 100644 index 00000000000..94fd774a375 --- /dev/null +++ b/contrib/gdb/gdb/minimon.h @@ -0,0 +1,601 @@ +/* Definitions and macros for support of AMD's remote debugger, MiniMON. + Copyright 1990, 1991 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* + * Some basic types. FIXME, this should be done by declaring bitfield + * sizes in the structs. We can't portably depend on a "long int" being + * 32 bits, etc. + */ +typedef long int INT32; /* 32 bit integer */ +typedef unsigned long int UINT32; /* 32 bit integer (unsigned) */ +typedef unsigned long int ADDR32; /* 32 bit address */ +typedef unsigned long int INST32; /* 32 bit instruction */ +typedef long int BOOLEAN; /* Boolean value (32 bit) */ +typedef unsigned char BYTE; /* byte (8 bit) */ +typedef short int INT16; /* 16 bit integer */ +typedef unsigned short int UINT16; /* 16 bit integer (unsigned) */ + +/****************************************************************************/ +/************************* Message Information ******************************/ +/****************************************************************************/ + +/* + * Error codes + */ + +/* General errors */ +#define EMUSAGE 1 /* Bad args / flags */ +#define EMFAIL 2 /* Unrecoverable error */ +#define EMBADADDR 3 /* Illegal address */ +#define EMBADREG 4 /* Illegal register */ +#define EMSYNTAX 5 /* Illegal command syntax */ +#define EMACCESS 6 /* Could not access memory */ +#define EMALLOC 7 /* Could not allocate memory */ +#define EMTARGET 8 /* Unknown target type */ +#define EMHINIT 9 /* Could not initialize host */ +#define EMCOMM 10 /* Could not open communication channel */ + +/* Message errors */ +#define EMBADMSG 11 /* Unknown message type */ +#define EMMSG2BIG 12 /* Message to large for buffer */ +#define EMNOSEND 13 /* Could not send message */ +#define EMNORECV 14 /* Could not receive message */ + +#define EMRESET 15 /* Could not RESET target */ +#define EMCONFIG 16 /* Could not get target CONFIG */ +#define EMSTATUS 17 /* Could not get target STATUS */ +#define EMREAD 18 /* Could not READ target memory */ +#define EMWRITE 19 /* Could not WRITE target memory */ +#define EMBKPTSET 20 /* Could not set breakpoint */ +#define EMBKPTRM 21 /* Could not remove breakpoint */ +#define EMBKPTSTAT 22 /* Could not get breakpoint status */ +#define EMBKPTNONE 23 /* All breakpoints in use */ +#define EMBKPTUSED 24 /* Breakpoints already in use */ +#define EMCOPY 25 /* Could not COPY target memory */ +#define EMFILL 26 /* Could not FILL target memory */ +#define EMINIT 27 /* Could not initialize target memory */ +#define EMGO 28 /* Could not start execution */ +#define EMSTEP 29 /* Could not single step */ +#define EMBREAK 30 /* Could not BREAK */ +#define EMHIF 31 /* Could not perform HIF service */ +#define EMCHANNEL0 32 /* Could not read CHANNEL0 */ +#define EMCHANNEL1 33 /* Could not write CHANNEL1 */ + +/* COFF file loader errors */ +#define EMOPEN 34 /* Could not open COFF file */ +#define EMHDR 35 /* Could not read COFF header */ +#define EMMAGIC 36 /* Bad magic number */ +#define EMAOUT 37 /* Could not read COFF a.out header */ +#define EMSCNHDR 38 /* Could not read COFF section header */ +#define EMSCN 39 /* Could not read COFF section */ +#define EMCLOSE 40 /* Could not close COFF file */ + +/* Log file errors */ +#define EMLOGOPEN 41 /* Could not open log file */ +#define EMLOGREAD 42 /* Could not read log file */ +#define EMLOGWRITE 43 /* Could not write to log file */ +#define EMLOGCLOSE 44 /* Could not close log file */ + +/* Command file errors */ +#define EMCMDOPEN 45 /* Could not open command file */ +#define EMCMDREAD 46 /* Could not read command file */ +#define EMCMDWRITE 47 /* Could not write to command file */ +#define EMCMDCLOSE 48 /* Could not close comand file */ + +#define EMTIMEOUT 49 /* Host timed out waiting for a message */ +#define EMCOMMTYPE 50 /* A '-t' flag must be specified */ +#define EMCOMMERR 51 /* Communication error */ +#define EMBAUD 52 /* Invalid baud rate specified */ +/* + * Memory Spaces + */ +#define LOCAL_REG 0 /* Local processor register */ +#define GLOBAL_REG 1 /* Global processor register */ +#define SPECIAL_REG 2 /* Special processor register */ +#define TLB_REG 3 /* Translation Lookaside Buffer */ +#define COPROC_REG 4 /* Coprocessor register */ +#define I_MEM 5 /* Instruction Memory */ +#define D_MEM 6 /* Data Memory */ +#define I_ROM 7 /* Instruction ROM */ +#define D_ROM 8 /* Data ROM */ +#define I_O 9 /* Input/Output */ +#define I_CACHE 10 /* Instruction Cache */ +#define D_CACHE 11 /* Data Cache */ + +/* To supress warnings for zero length array definitions */ +#define DUMMY 1 + +/* + ** Host to target definitions + */ + +#define RESET 0 +#define CONFIG_REQ 1 +#define STATUS_REQ 2 +#define READ_REQ 3 +#define WRITE_REQ 4 +#define BKPT_SET 5 +#define BKPT_RM 6 +#define BKPT_STAT 7 +#define COPY 8 +#define FILL 9 +#define INIT 10 +#define GO 11 +#define STEP 12 +#define BREAK 13 + +#define HIF_CALL_RTN 64 +#define CHANNEL0 65 +#define CHANNEL1_ACK 66 + + +/* + ** Target to host definitions + */ + +#define RESET_ACK 32 +#define CONFIG 33 +#define STATUS 34 +#define READ_ACK 35 +#define WRITE_ACK 36 +#define BKPT_SET_ACK 37 +#define BKPT_RM_ACK 38 +#define BKPT_STAT_ACK 39 +#define COPY_ACK 40 +#define FILL_ACK 41 +#define INIT_ACK 42 +#define HALT 43 + +#define ERROR 63 + +#define HIF_CALL 96 +#define CHANNEL0_ACK 97 +#define CHANNEL1 98 + + +/* A "generic" message */ +struct generic_msg_t + { + INT32 code; /* generic */ + INT32 length; + BYTE byte[DUMMY]; + }; + + +/* A "generic" message (with an INT32 array) */ +struct generic_int32_msg_t + { + INT32 code; /* generic */ + INT32 length; + INT32 int32[DUMMY]; + }; + + +/* + ** Host to target messages + */ + +struct reset_msg_t + { + INT32 code; /* 0 */ + INT32 length; + }; + + +struct config_req_msg_t + { + INT32 code; /* 1 */ + INT32 length; + }; + + +struct status_req_msg_t + { + INT32 code; /* 2 */ + INT32 length; + }; + + +struct read_req_msg_t + { + INT32 code; /* 3 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 byte_count; + }; + + +struct write_req_msg_t + { + INT32 code; /* 4 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 byte_count; + BYTE data[DUMMY]; + }; + + +struct write_r_msg_t + { + INT32 code; /* 4 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 byte_count; + INT32 data[DUMMY]; + }; + + +struct bkpt_set_msg_t + { + INT32 code; /* 5 */ + INT32 length; + INT32 memory_space; + ADDR32 bkpt_addr; + INT32 pass_count; + INT32 bkpt_type; + }; + + +struct bkpt_rm_msg_t + { + INT32 code; /* 6 */ + INT32 length; + INT32 memory_space; + ADDR32 bkpt_addr; + }; + + +struct bkpt_stat_msg_t + { + INT32 code; /* 7 */ + INT32 length; + INT32 memory_space; + ADDR32 bkpt_addr; + }; + + +struct copy_msg_t + { + INT32 code; /* 8 */ + INT32 length; + INT32 source_space; + ADDR32 source_addr; + INT32 dest_space; + ADDR32 dest_addr; + INT32 byte_count; + }; + + +struct fill_msg_t + { + INT32 code; /* 9 */ + INT32 length; + INT32 memory_space; + ADDR32 start_addr; + INT32 fill_count; + INT32 byte_count; + BYTE fill_data[DUMMY]; + }; + + +struct init_msg_t + { + INT32 code; /* 10 */ + INT32 length; + ADDR32 text_start; + ADDR32 text_end; + ADDR32 data_start; + ADDR32 data_end; + ADDR32 entry_point; + INT32 mem_stack_size; + INT32 reg_stack_size; + ADDR32 arg_start; + INT32 os_control; + }; + + +struct go_msg_t + { + INT32 code; /* 11 */ + INT32 length; + }; + + +struct step_msg_t + { + INT32 code; /* 12 */ + INT32 length; + INT32 count; + }; + + +struct break_msg_t + { + INT32 code; /* 13 */ + INT32 length; + }; + + +struct hif_call_rtn_msg_t + { + INT32 code; /* 64 */ + INT32 length; + INT32 service_number; + INT32 gr121; + INT32 gr96; + INT32 gr97; + }; + + +struct channel0_msg_t + { + INT32 code; /* 65 */ + INT32 length; + BYTE data; + }; + + +struct channel1_ack_msg_t + { + INT32 code; /* 66 */ + INT32 length; + }; + + +/* + ** Target to host messages + */ + + +struct reset_ack_msg_t + { + INT32 code; /* 32 */ + INT32 length; + }; + + +struct config_msg_t + { + INT32 code; /* 33 */ + INT32 length; + INT32 processor_id; + INT32 version; + ADDR32 I_mem_start; + INT32 I_mem_size; + ADDR32 D_mem_start; + INT32 D_mem_size; + ADDR32 ROM_start; + INT32 ROM_size; + INT32 max_msg_size; + INT32 max_bkpts; + INT32 coprocessor; + INT32 reserved; + }; + + +struct status_msg_t + { + INT32 code; /* 34 */ + INT32 length; + INT32 msgs_sent; + INT32 msgs_received; + INT32 errors; + INT32 bkpts_hit; + INT32 bkpts_free; + INT32 traps; + INT32 fills; + INT32 spills; + INT32 cycles; + INT32 reserved; + }; + + +struct read_ack_msg_t + { + INT32 code; /* 35 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 byte_count; + BYTE data[DUMMY]; + }; + +struct read_r_ack_msg_t + { + INT32 code; /* 35 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 byte_count; + INT32 data[DUMMY]; + }; + + +struct write_ack_msg_t + { + INT32 code; /* 36 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 byte_count; + }; + + +struct bkpt_set_ack_msg_t + { + INT32 code; /* 37 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 pass_count; + INT32 bkpt_type; + }; + + +struct bkpt_rm_ack_msg_t + { + INT32 code; /* 38 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + }; + + +struct bkpt_stat_ack_msg_t + { + INT32 code; /* 39 */ + INT32 length; + INT32 memory_space; + ADDR32 address; + INT32 pass_count; + INT32 bkpt_type; + }; + + +struct copy_ack_msg_t + { + INT32 code; /* 40 */ + INT32 length; + INT32 source_space; + ADDR32 source_addr; + INT32 dest_space; + ADDR32 dest_addr; + INT32 byte_count; + }; + + +struct fill_ack_msg_t + { + INT32 code; /* 41 */ + INT32 length; + INT32 memory_space; + ADDR32 start_addr; + INT32 fill_count; + INT32 byte_count; + }; + + +struct init_ack_msg_t + { + INT32 code; /* 42 */ + INT32 length; + }; + + +struct halt_msg_t + { + INT32 code; /* 43 */ + INT32 length; + INT32 memory_space; + ADDR32 pc0; + ADDR32 pc1; + INT32 trap_number; + }; + + +struct error_msg_t + { + INT32 code; /* 63 */ + INT32 length; + INT32 error_code; + INT32 memory_space; + ADDR32 address; + }; + + +struct hif_call_msg_t + { + INT32 code; /* 96 */ + INT32 length; + INT32 service_number; + INT32 lr2; + INT32 lr3; + INT32 lr4; + }; + + +struct channel0_ack_msg_t + { + INT32 code; /* 97 */ + INT32 length; + }; + + +struct channel1_msg_t + { + INT32 code; /* 98 */ + INT32 length; + BYTE data[DUMMY]; + }; + + + +/* + ** Union all of the message types together + */ + +union msg_t + { + struct generic_msg_t generic_msg; + struct generic_int32_msg_t generic_int32_msg; + + struct reset_msg_t reset_msg; + struct config_req_msg_t config_req_msg; + struct status_req_msg_t status_req_msg; + struct read_req_msg_t read_req_msg; + struct write_req_msg_t write_req_msg; + struct write_r_msg_t write_r_msg; + struct bkpt_set_msg_t bkpt_set_msg; + struct bkpt_rm_msg_t bkpt_rm_msg; + struct bkpt_stat_msg_t bkpt_stat_msg; + struct copy_msg_t copy_msg; + struct fill_msg_t fill_msg; + struct init_msg_t init_msg; + struct go_msg_t go_msg; + struct step_msg_t step_msg; + struct break_msg_t break_msg; + + struct hif_call_rtn_msg_t hif_call_rtn_msg; + struct channel0_msg_t channel0_msg; + struct channel1_ack_msg_t channel1_ack_msg; + + struct reset_ack_msg_t reset_ack_msg; + struct config_msg_t config_msg; + struct status_msg_t status_msg; + struct read_ack_msg_t read_ack_msg; + struct read_r_ack_msg_t read_r_ack_msg; + struct write_ack_msg_t write_ack_msg; + struct bkpt_set_ack_msg_t bkpt_set_ack_msg; + struct bkpt_rm_ack_msg_t bkpt_rm_ack_msg; + struct bkpt_stat_ack_msg_t bkpt_stat_ack_msg; + struct copy_ack_msg_t copy_ack_msg; + struct fill_ack_msg_t fill_ack_msg; + struct init_ack_msg_t init_ack_msg; + struct halt_msg_t halt_msg; + + struct error_msg_t error_msg; + + struct hif_call_msg_t hif_call_msg; + struct channel0_ack_msg_t channel0_ack_msg; + struct channel1_msg_t channel1_msg; + }; diff --git a/contrib/gdb/gdb/minsyms.c b/contrib/gdb/gdb/minsyms.c index a4997bffda6..83aef9d4428 100644 --- a/contrib/gdb/gdb/minsyms.c +++ b/contrib/gdb/gdb/minsyms.c @@ -1,5 +1,6 @@ /* GDB routines for manipulating the minimal symbol tables. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -91,7 +92,7 @@ msymbol_hash_iw (const char *string) ++string; } } - return hash % MINIMAL_SYMBOL_HASH_SIZE; + return hash; } /* Compute a hash code for a string. */ @@ -102,7 +103,7 @@ msymbol_hash (const char *string) unsigned int hash = 0; for (; *string; ++string) hash = hash * 67 + *string - 113; - return hash % MINIMAL_SYMBOL_HASH_SIZE; + return hash; } /* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE. */ @@ -112,7 +113,8 @@ add_minsym_to_hash_table (struct minimal_symbol *sym, { if (sym->hash_next == NULL) { - unsigned int hash = msymbol_hash (SYMBOL_NAME (sym)); + unsigned int hash + = msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE; sym->hash_next = table[hash]; table[hash] = sym; } @@ -126,7 +128,7 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym, { if (sym->demangled_hash_next == NULL) { - unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym)); + unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE; sym->demangled_hash_next = table[hash]; table[hash] = sym; } @@ -135,17 +137,18 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym, /* Look through all the current minimal symbol tables and find the first minimal symbol that matches NAME. If OBJF is non-NULL, limit - the search to that objfile. If SFILE is non-NULL, limit the search - to that source file. Returns a pointer to the minimal symbol that + the search to that objfile. If SFILE is non-NULL, the only file-scope + symbols considered will be from that source file (global symbols are + still preferred). Returns a pointer to the minimal symbol that matches, or NULL if no match is found. Note: One instance where there may be duplicate minimal symbols with the same name is when the symbol tables for a shared library and the symbol tables for an executable contain global symbols with the same - names (the dynamic linker deals with the duplication). */ + names (the dynamic linker deals with the duplication). */ struct minimal_symbol * -lookup_minimal_symbol (register const char *name, const char *sfile, +lookup_minimal_symbol (const char *name, const char *sfile, struct objfile *objf) { struct objfile *objfile; @@ -154,8 +157,8 @@ lookup_minimal_symbol (register const char *name, const char *sfile, struct minimal_symbol *found_file_symbol = NULL; struct minimal_symbol *trampoline_symbol = NULL; - unsigned int hash = msymbol_hash (name); - unsigned int dem_hash = msymbol_hash_iw (name); + unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; + unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE; #ifdef SOFUN_ADDRESS_MAYBE_MISSING if (sfile != NULL) @@ -186,7 +189,15 @@ lookup_minimal_symbol (register const char *name, const char *sfile, while (msymbol != NULL && found_symbol == NULL) { - if (SYMBOL_MATCHES_NAME (msymbol, name)) + /* FIXME: carlton/2003-02-27: This is an unholy + mixture of linkage names and natural names. If + you want to test the linkage names with strcmp, + do that. If you want to test the natural names + with strcmp_iw, use SYMBOL_MATCHES_NATURAL_NAME. */ + if (strcmp (DEPRECATED_SYMBOL_NAME (msymbol), (name)) == 0 + || (SYMBOL_DEMANGLED_NAME (msymbol) != NULL + && strcmp_iw (SYMBOL_DEMANGLED_NAME (msymbol), + (name)) == 0)) { switch (MSYMBOL_TYPE (msymbol)) { @@ -194,7 +205,8 @@ lookup_minimal_symbol (register const char *name, const char *sfile, case mst_file_data: case mst_file_bss: #ifdef SOFUN_ADDRESS_MAYBE_MISSING - if (sfile == NULL || STREQ (msymbol->filename, sfile)) + if (sfile == NULL + || strcmp (msymbol->filename, sfile) == 0) found_file_symbol = msymbol; #else /* We have neither the ability nor the need to @@ -248,30 +260,21 @@ lookup_minimal_symbol (register const char *name, const char *sfile, } /* Look through all the current minimal symbol tables and find the - first minimal symbol that matches NAME and of text type. - If OBJF is non-NULL, limit - the search to that objfile. If SFILE is non-NULL, limit the search - to that source file. Returns a pointer to the minimal symbol that - matches, or NULL if no match is found. - */ + first minimal symbol that matches NAME and has text type. If OBJF + is non-NULL, limit the search to that objfile. Returns a pointer + to the minimal symbol that matches, or NULL if no match is found. + + This function only searches the mangled (linkage) names. */ struct minimal_symbol * -lookup_minimal_symbol_text (register const char *name, const char *sfile, - struct objfile *objf) +lookup_minimal_symbol_text (const char *name, struct objfile *objf) { struct objfile *objfile; struct minimal_symbol *msymbol; struct minimal_symbol *found_symbol = NULL; struct minimal_symbol *found_file_symbol = NULL; -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - if (sfile != NULL) - { - char *p = strrchr (sfile, '/'); - if (p != NULL) - sfile = p + 1; - } -#endif + unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; for (objfile = object_files; objfile != NULL && found_symbol == NULL; @@ -279,29 +282,18 @@ lookup_minimal_symbol_text (register const char *name, const char *sfile, { if (objf == NULL || objf == objfile) { - for (msymbol = objfile->msymbols; - msymbol != NULL && SYMBOL_NAME (msymbol) != NULL && - found_symbol == NULL; - msymbol++) + for (msymbol = objfile->msymbol_hash[hash]; + msymbol != NULL && found_symbol == NULL; + msymbol = msymbol->hash_next) { - if (SYMBOL_MATCHES_NAME (msymbol, name) && + if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 && (MSYMBOL_TYPE (msymbol) == mst_text || MSYMBOL_TYPE (msymbol) == mst_file_text)) { switch (MSYMBOL_TYPE (msymbol)) { case mst_file_text: -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - if (sfile == NULL || STREQ (msymbol->filename, sfile)) - found_file_symbol = msymbol; -#else - /* We have neither the ability nor the need to - deal with the SFILE parameter. If we find - more than one symbol, just return the latest - one (the user can't expect useful behavior in - that case). */ found_file_symbol = msymbol; -#endif break; default: found_symbol = msymbol; @@ -323,29 +315,22 @@ lookup_minimal_symbol_text (register const char *name, const char *sfile, } /* Look through all the current minimal symbol tables and find the - first minimal symbol that matches NAME and of solib trampoline type. - If OBJF is non-NULL, limit - the search to that objfile. If SFILE is non-NULL, limit the search - to that source file. Returns a pointer to the minimal symbol that - matches, or NULL if no match is found. - */ + first minimal symbol that matches NAME and is a solib trampoline. + If OBJF is non-NULL, limit the search to that objfile. Returns a + pointer to the minimal symbol that matches, or NULL if no match is + found. + + This function only searches the mangled (linkage) names. */ struct minimal_symbol * -lookup_minimal_symbol_solib_trampoline (register const char *name, - const char *sfile, struct objfile *objf) +lookup_minimal_symbol_solib_trampoline (const char *name, + struct objfile *objf) { struct objfile *objfile; struct minimal_symbol *msymbol; struct minimal_symbol *found_symbol = NULL; -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - if (sfile != NULL) - { - char *p = strrchr (sfile, '/'); - if (p != NULL) - sfile = p + 1; - } -#endif + unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; for (objfile = object_files; objfile != NULL && found_symbol == NULL; @@ -353,12 +338,11 @@ lookup_minimal_symbol_solib_trampoline (register const char *name, { if (objf == NULL || objf == objfile) { - for (msymbol = objfile->msymbols; - msymbol != NULL && SYMBOL_NAME (msymbol) != NULL && - found_symbol == NULL; - msymbol++) + for (msymbol = objfile->msymbol_hash[hash]; + msymbol != NULL && found_symbol == NULL; + msymbol = msymbol->hash_next) { - if (SYMBOL_MATCHES_NAME (msymbol, name) && + if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) return msymbol; } @@ -371,7 +355,7 @@ lookup_minimal_symbol_solib_trampoline (register const char *name, /* Search through the minimal symbol table for each objfile and find the symbol whose address is the largest address that is still less - than or equal to PC, and matches SECTION (if non-null). Returns a + than or equal to PC, and matches SECTION (if non-NULL). Returns a pointer to the minimal symbol if such a symbol is found, or NULL if PC is not in a suitable range. Note that we need to look through ALL the minimal symbol tables before deciding on the symbol that @@ -388,13 +372,26 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) struct objfile *objfile; struct minimal_symbol *msymbol; struct minimal_symbol *best_symbol = NULL; + struct obj_section *pc_section; - /* pc has to be in a known section. This ensures that anything beyond - the end of the last segment doesn't appear to be part of the last - function in the last segment. */ - if (find_pc_section (pc) == NULL) + /* PC has to be in a known section. This ensures that anything + beyond the end of the last segment doesn't appear to be part of + the last function in the last segment. */ + pc_section = find_pc_section (pc); + if (pc_section == NULL) return NULL; + /* NOTE: cagney/2004-01-27: Removed code (added 2003-07-19) that was + trying to force the PC into a valid section as returned by + find_pc_section. It broke IRIX 6.5 mdebug which relies on this + code returning an absolute symbol - the problem was that + find_pc_section wasn't returning an absolute section and hence + the code below would skip over absolute symbols. Since the + original problem was with finding a frame's function, and that + uses [indirectly] lookup_minimal_symbol_by_pc, the original + problem has been fixed by having that function use + find_pc_section. */ + for (objfile = object_files; objfile != NULL; objfile = objfile->next) @@ -405,8 +402,9 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) "null symbol". If there are no real symbols, then there is no minimal symbol table at all. */ - if ((msymbol = objfile->msymbols) != NULL) + if (objfile->minimal_symbol_count > 0) { + msymbol = objfile->msymbols; lo = 0; hi = objfile->minimal_symbol_count - 1; @@ -502,54 +500,14 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) struct minimal_symbol * lookup_minimal_symbol_by_pc (CORE_ADDR pc) { - return lookup_minimal_symbol_by_pc_section (pc, find_pc_mapped_section (pc)); + /* NOTE: cagney/2004-01-27: This was using find_pc_mapped_section to + force the section but that (well unless you're doing overlay + debugging) always returns NULL making the call somewhat useless. */ + struct obj_section *section = find_pc_section (pc); + if (section == NULL) + return NULL; + return lookup_minimal_symbol_by_pc_section (pc, section->the_bfd_section); } - -#ifdef SOFUN_ADDRESS_MAYBE_MISSING -CORE_ADDR -find_stab_function_addr (char *namestring, char *filename, - struct objfile *objfile) -{ - struct minimal_symbol *msym; - char *p; - int n; - - p = strchr (namestring, ':'); - if (p == NULL) - p = namestring; - n = p - namestring; - p = alloca (n + 2); - strncpy (p, namestring, n); - p[n] = 0; - - msym = lookup_minimal_symbol (p, filename, objfile); - if (msym == NULL) - { - /* Sun Fortran appends an underscore to the minimal symbol name, - try again with an appended underscore if the minimal symbol - was not found. */ - p[n] = '_'; - p[n + 1] = 0; - msym = lookup_minimal_symbol (p, filename, objfile); - } - - if (msym == NULL && filename != NULL) - { - /* Try again without the filename. */ - p[n] = 0; - msym = lookup_minimal_symbol (p, NULL, objfile); - } - if (msym == NULL && filename != NULL) - { - /* And try again for Sun Fortran, but without the filename. */ - p[n] = '_'; - p[n + 1] = 0; - msym = lookup_minimal_symbol (p, NULL, objfile); - } - - return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym); -} -#endif /* SOFUN_ADDRESS_MAYBE_MISSING */ /* Return leading symbol character for a BFD. If BFD is NULL, @@ -619,8 +577,8 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, asection *bfd_section, struct objfile *objfile) { - register struct msym_bunch *new; - register struct minimal_symbol *msymbol; + struct msym_bunch *new; + struct minimal_symbol *msymbol; if (ms_type == mst_file_text) { @@ -638,7 +596,7 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, const char *tempstring = name; if (tempstring[0] == get_symbol_leading_char (objfile->obfd)) ++tempstring; - if (STREQN (tempstring, "__gnu_compiled", 14)) + if (strncmp (tempstring, "__gnu_compiled", 14) == 0) return (NULL); } } @@ -651,9 +609,10 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, msym_bunch = new; } msymbol = &msym_bunch->contents[msym_bunch_index]; - SYMBOL_NAME (msymbol) = obsavestring ((char *) name, strlen (name), - &objfile->symbol_obstack); SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown); + SYMBOL_LANGUAGE (msymbol) = language_auto; + SYMBOL_SET_NAMES (msymbol, (char *)name, strlen (name), objfile); + SYMBOL_VALUE_ADDRESS (msymbol) = address; SYMBOL_SECTION (msymbol) = section; SYMBOL_BFD_SECTION (msymbol) = bfd_section; @@ -661,6 +620,7 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, MSYMBOL_TYPE (msymbol) = ms_type; /* FIXME: This info, if it remains, needs its own field. */ MSYMBOL_INFO (msymbol) = info; /* FIXME! */ + MSYMBOL_SIZE (msymbol) = 0; /* The hash pointers must be cleared! If they're not, add_minsym_to_hash_table will NOT add this msymbol to the hash table. */ @@ -680,8 +640,8 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, static int compare_minimal_symbols (const void *fn1p, const void *fn2p) { - register const struct minimal_symbol *fn1; - register const struct minimal_symbol *fn2; + const struct minimal_symbol *fn1; + const struct minimal_symbol *fn2; fn1 = (const struct minimal_symbol *) fn1p; fn2 = (const struct minimal_symbol *) fn2p; @@ -697,8 +657,8 @@ compare_minimal_symbols (const void *fn1p, const void *fn2p) else /* addrs are equal: sort by name */ { - char *name1 = SYMBOL_NAME (fn1); - char *name2 = SYMBOL_NAME (fn2); + char *name1 = SYMBOL_LINKAGE_NAME (fn1); + char *name2 = SYMBOL_LINKAGE_NAME (fn2); if (name1 && name2) /* both have names */ return strcmp (name1, name2); @@ -722,7 +682,7 @@ compare_minimal_symbols (const void *fn1p, const void *fn2p) static void do_discard_minimal_symbols_cleanup (void *arg) { - register struct msym_bunch *next; + struct msym_bunch *next; while (msym_bunch != NULL) { @@ -763,7 +723,7 @@ make_cleanup_discard_minimal_symbols (void) Note that we are not concerned here about recovering the space that is potentially freed up, because the strings themselves are allocated - on the symbol_obstack, and will get automatically freed when the symbol + on the objfile_obstack, and will get automatically freed when the symbol table is freed. The caller can free up the unused minimal symbols at the end of the compacted region if their allocation strategy allows it. @@ -788,9 +748,10 @@ compact_minimal_symbols (struct minimal_symbol *msymbol, int mcount, copyfrom = copyto = msymbol; while (copyfrom < msymbol + mcount - 1) { - if (SYMBOL_VALUE_ADDRESS (copyfrom) == - SYMBOL_VALUE_ADDRESS ((copyfrom + 1)) && - (STREQ (SYMBOL_NAME (copyfrom), SYMBOL_NAME ((copyfrom + 1))))) + if (SYMBOL_VALUE_ADDRESS (copyfrom) + == SYMBOL_VALUE_ADDRESS ((copyfrom + 1)) + && strcmp (SYMBOL_LINKAGE_NAME (copyfrom), + SYMBOL_LINKAGE_NAME ((copyfrom + 1))) == 0) { if (MSYMBOL_TYPE ((copyfrom + 1)) == mst_unknown) { @@ -865,12 +826,12 @@ build_minimal_symbol_hash_tables (struct objfile *objfile) void install_minimal_symbols (struct objfile *objfile) { - register int bindex; - register int mcount; - register struct msym_bunch *bunch; - register struct minimal_symbol *msymbols; + int bindex; + int mcount; + struct msym_bunch *bunch; + struct minimal_symbol *msymbols; int alloc_count; - register char leading_char; + char leading_char; if (msym_count > 0) { @@ -880,10 +841,10 @@ install_minimal_symbols (struct objfile *objfile) we will give back the excess space. */ alloc_count = msym_count + objfile->minimal_symbol_count + 1; - obstack_blank (&objfile->symbol_obstack, + obstack_blank (&objfile->objfile_obstack, alloc_count * sizeof (struct minimal_symbol)); msymbols = (struct minimal_symbol *) - obstack_base (&objfile->symbol_obstack); + obstack_base (&objfile->objfile_obstack); /* Copy in the existing minimal symbols, if there are any. */ @@ -905,10 +866,9 @@ install_minimal_symbols (struct objfile *objfile) for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++) { msymbols[mcount] = bunch->contents[bindex]; - SYMBOL_LANGUAGE (&msymbols[mcount]) = language_auto; - if (SYMBOL_NAME (&msymbols[mcount])[0] == leading_char) + if (SYMBOL_LINKAGE_NAME (&msymbols[mcount])[0] == leading_char) { - SYMBOL_NAME (&msymbols[mcount])++; + SYMBOL_LINKAGE_NAME (&msymbols[mcount])++; } } msym_bunch_index = BUNCH_SIZE; @@ -924,10 +884,10 @@ install_minimal_symbols (struct objfile *objfile) mcount = compact_minimal_symbols (msymbols, mcount, objfile); - obstack_blank (&objfile->symbol_obstack, + obstack_blank (&objfile->objfile_obstack, (mcount + 1 - alloc_count) * sizeof (struct minimal_symbol)); msymbols = (struct minimal_symbol *) - obstack_finish (&objfile->symbol_obstack); + obstack_finish (&objfile->objfile_obstack); /* We also terminate the minimal symbol table with a "null symbol", which is *not* included in the size of the table. This makes it @@ -937,14 +897,15 @@ install_minimal_symbols (struct objfile *objfile) symbol count does *not* include this null symbol, which is why it is indexed by mcount and not mcount-1. */ - SYMBOL_NAME (&msymbols[mcount]) = NULL; + SYMBOL_LINKAGE_NAME (&msymbols[mcount]) = NULL; SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0; MSYMBOL_INFO (&msymbols[mcount]) = NULL; + MSYMBOL_SIZE (&msymbols[mcount]) = 0; MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown; SYMBOL_INIT_LANGUAGE_SPECIFIC (&msymbols[mcount], language_unknown); /* Attach the minimal symbol table to the specified objfile. - The strings themselves are also located in the symbol_obstack + The strings themselves are also located in the objfile_obstack of this objfile. */ objfile->minimal_symbol_count = mcount; @@ -957,19 +918,20 @@ install_minimal_symbols (struct objfile *objfile) for (i = 0; i < mcount; i++) { - const char *name = SYMBOL_NAME (&objfile->msymbols[i]); - if (name[0] == '_' && name[1] == 'Z') + /* If a symbol's name starts with _Z and was successfully + demangled, then we can assume we've found a GNU v3 symbol. + For now we set the C++ ABI globally; if the user is + mixing ABIs then the user will need to "set cp-abi" + manually. */ + const char *name = SYMBOL_LINKAGE_NAME (&objfile->msymbols[i]); + if (name[0] == '_' && name[1] == 'Z' + && SYMBOL_DEMANGLED_NAME (&objfile->msymbols[i]) != NULL) { - switch_to_cp_abi ("gnu-v3"); + set_cp_abi_as_auto_default ("gnu-v3"); break; } } } - - /* Now walk through all the minimal symbols, selecting the newly added - ones and attempting to cache their C++ demangled names. */ - for (; mcount-- > 0; msymbols++) - SYMBOL_INIT_DEMANGLED_NAME (msymbols, &objfile->symbol_obstack); /* Now build the hash tables; we can't do this incrementally at an earlier point since we weren't finished with the obstack @@ -1025,7 +987,8 @@ find_solib_trampoline_target (CORE_ADDR pc) ALL_MSYMBOLS (objfile, msymbol) { if (MSYMBOL_TYPE (msymbol) == mst_text - && STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (tsymbol))) + && strcmp (SYMBOL_LINKAGE_NAME (msymbol), + SYMBOL_LINKAGE_NAME (tsymbol)) == 0) return SYMBOL_VALUE_ADDRESS (msymbol); } } diff --git a/contrib/gdb/gdb/mips-nat.c b/contrib/gdb/gdb/mips-nat.c new file mode 100644 index 00000000000..626f770f18d --- /dev/null +++ b/contrib/gdb/gdb/mips-nat.c @@ -0,0 +1,254 @@ +/* Low level DECstation interface to ptrace, for GDB when running native. + Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000, 2001 + Free Software Foundation, Inc. + Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU + and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "gdbcore.h" +#include "regcache.h" +#include +#include +#include +#include +#undef JB_S0 +#undef JB_S1 +#undef JB_S2 +#undef JB_S3 +#undef JB_S4 +#undef JB_S5 +#undef JB_S6 +#undef JB_S7 +#undef JB_SP +#undef JB_S8 +#undef JB_PC +#undef JB_SR +#undef NJBREGS +#include /* For JB_XXX. */ + +/* Size of elements in jmpbuf */ + +#define JB_ELEMENT_SIZE 4 + +/* Map gdb internal register number to ptrace ``address''. + These ``addresses'' are defined in DECstation */ + +static int +register_ptrace_addr (int regno) +{ + return (regno < 32 ? GPR_BASE + regno + : regno == mips_regnum (current_gdbarch)->pc ? PC + : regno == mips_regnum (current_gdbarch)->cause ? CAUSE + : regno == mips_regnum (current_gdbarch)->hi ? MMHI + : regno == mips_regnum (current_gdbarch)->lo ? MMLO + : regno == mips_regnum (current_gdbarch)->fp_control_status ? FPC_CSR + : regno == mips_regnum (current_gdbarch)->fp_implementation_revision ? FPC_EIR + : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) + : 0); +} + +static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); + +/* Get all registers from the inferior */ + +void +fetch_inferior_registers (int regno) +{ + unsigned int regaddr; + char buf[MAX_REGISTER_SIZE]; + int i; + char zerobuf[MAX_REGISTER_SIZE]; + memset (zerobuf, 0, MAX_REGISTER_SIZE); + + deprecated_registers_fetched (); + + for (regno = 1; regno < NUM_REGS; regno++) + { + regaddr = register_ptrace_addr (regno); + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + *(int *) &buf[i] = ptrace (PT_READ_U, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) regaddr, 0); + regaddr += sizeof (int); + } + supply_register (regno, buf); + } + + supply_register (ZERO_REGNUM, zerobuf); + /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */ + supply_register (DEPRECATED_FP_REGNUM, zerobuf); +} + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + +void +store_inferior_registers (int regno) +{ + unsigned int regaddr; + char buf[80]; + + if (regno > 0) + { + if (regno == ZERO_REGNUM || regno == PS_REGNUM + || regno == mips_regnum (current_gdbarch)->badvaddr + || regno == mips_regnum (current_gdbarch)->cause + || regno == mips_regnum (current_gdbarch)->fp_implementation_revision + || regno == DEPRECATED_FP_REGNUM + || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM)) + return; + regaddr = register_ptrace_addr (regno); + errno = 0; + ptrace (PT_WRITE_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, + read_register (regno)); + if (errno != 0) + { + sprintf (buf, "writing register number %d", regno); + perror_with_name (buf); + } + } + else + { + for (regno = 0; regno < NUM_REGS; regno++) + store_inferior_registers (regno); + } +} + + +/* Figure out where the longjmp will land. + We expect the first arg to be a pointer to the jmp_buf structure from which + we extract the pc (JB_PC) that we will land at. The pc is copied into PC. + This routine returns true on success. */ + +int +get_longjmp_target (CORE_ADDR *pc) +{ + CORE_ADDR jb_addr; + char *buf; + + buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT); + jb_addr = read_register (A0_REGNUM); + + if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, + TARGET_PTR_BIT / TARGET_CHAR_BIT)) + return 0; + + *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); + + return 1; +} + +/* Extract the register values out of the core file and store + them where `read_register' will find them. + + CORE_REG_SECT points to the register values themselves, read into memory. + CORE_REG_SIZE is the size of that area. + WHICH says which set of registers we are handling (0 = int, 2 = float + on machines where they are discontiguous). + REG_ADDR is the offset from u.u_ar0 to the register values relative to + core_reg_sect. This is used with old-fashioned core files to + locate the registers in a large upage-plus-stack ".reg" section. + Original upage address X is at location core_reg_sect+x+reg_addr. + */ + +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR reg_addr) +{ + int regno; + unsigned int addr; + int bad_reg = -1; + reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */ + + char zerobuf[MAX_REGISTER_SIZE]; + memset (zerobuf, 0, MAX_REGISTER_SIZE); + + + /* 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 file without a upage, reg_ptr will be zero and this is all a big + NOP. */ + if (reg_ptr > core_reg_size) +#ifdef KERNEL_U_ADDR + reg_ptr -= KERNEL_U_ADDR; +#else + error ("Old mips core file can't be processed on this machine."); +#endif + + for (regno = 0; regno < NUM_REGS; regno++) + { + addr = register_addr (regno, reg_ptr); + if (addr >= core_reg_size) + { + if (bad_reg < 0) + bad_reg = regno; + } + else + { + supply_register (regno, core_reg_sect + addr); + } + } + if (bad_reg >= 0) + { + error ("Register %s not found in core file.", REGISTER_NAME (bad_reg)); + } + supply_register (ZERO_REGNUM, zerobuf); + /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */ + supply_register (DEPRECATED_FP_REGNUM, zerobuf); +} + +/* Return the address in the core dump or inferior of register REGNO. + BLOCKEND is the address of the end of the user structure. */ + +CORE_ADDR +register_addr (int regno, CORE_ADDR blockend) +{ + CORE_ADDR addr; + + if (regno < 0 || regno >= NUM_REGS) + error ("Invalid register number %d.", regno); + + REGISTER_U_ADDR (addr, blockend, regno); + + return addr; +} + + +/* Register that we are able to handle mips core file formats. + FIXME: is this really bfd_target_unknown_flavour? */ + +static struct core_fns mips_core_fns = +{ + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +void +_initialize_core_mips (void) +{ + add_core_fns (&mips_core_fns); +} diff --git a/contrib/gdb/gdb/mips-tdep.c b/contrib/gdb/gdb/mips-tdep.c new file mode 100644 index 00000000000..cd37764eed9 --- /dev/null +++ b/contrib/gdb/gdb/mips-tdep.c @@ -0,0 +1,6190 @@ +/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger. + + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU + and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_string.h" +#include "gdb_assert.h" +#include "frame.h" +#include "inferior.h" +#include "symtab.h" +#include "value.h" +#include "gdbcmd.h" +#include "language.h" +#include "gdbcore.h" +#include "symfile.h" +#include "objfiles.h" +#include "gdbtypes.h" +#include "target.h" +#include "arch-utils.h" +#include "regcache.h" +#include "osabi.h" +#include "mips-tdep.h" +#include "block.h" +#include "reggroups.h" +#include "opcode/mips.h" +#include "elf/mips.h" +#include "elf-bfd.h" +#include "symcat.h" +#include "sim-regno.h" +#include "dis-asm.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "trad-frame.h" + +static const struct objfile_data *mips_pdr_data; + +static void set_reg_offset (CORE_ADDR *saved_regs, int regnum, CORE_ADDR off); +static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum); + +/* A useful bit in the CP0 status register (PS_REGNUM). */ +/* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */ +#define ST0_FR (1 << 26) + +/* The sizes of floating point registers. */ + +enum +{ + MIPS_FPU_SINGLE_REGSIZE = 4, + MIPS_FPU_DOUBLE_REGSIZE = 8 +}; + + +static const char *mips_abi_string; + +static const char *mips_abi_strings[] = { + "auto", + "n32", + "o32", + "n64", + "o64", + "eabi32", + "eabi64", + NULL +}; + +struct frame_extra_info +{ + mips_extra_func_info_t proc_desc; + int num_args; +}; + +/* Various MIPS ISA options (related to stack analysis) can be + overridden dynamically. Establish an enum/array for managing + them. */ + +static const char size_auto[] = "auto"; +static const char size_32[] = "32"; +static const char size_64[] = "64"; + +static const char *size_enums[] = { + size_auto, + size_32, + size_64, + 0 +}; + +/* Some MIPS boards don't support floating point while others only + support single-precision floating-point operations. See also + FP_REGISTER_DOUBLE. */ + +enum mips_fpu_type +{ + MIPS_FPU_DOUBLE, /* Full double precision floating point. */ + MIPS_FPU_SINGLE, /* Single precision floating point (R4650). */ + MIPS_FPU_NONE /* No floating point. */ +}; + +#ifndef MIPS_DEFAULT_FPU_TYPE +#define MIPS_DEFAULT_FPU_TYPE MIPS_FPU_DOUBLE +#endif +static int mips_fpu_type_auto = 1; +static enum mips_fpu_type mips_fpu_type = MIPS_DEFAULT_FPU_TYPE; + +static int mips_debug = 0; + +/* MIPS specific per-architecture information */ +struct gdbarch_tdep +{ + /* from the elf header */ + int elf_flags; + + /* mips options */ + enum mips_abi mips_abi; + enum mips_abi found_abi; + enum mips_fpu_type mips_fpu_type; + int mips_last_arg_regnum; + int mips_last_fp_arg_regnum; + int mips_default_saved_regsize; + int mips_fp_register_double; + int mips_default_stack_argsize; + int default_mask_address_p; + /* Is the target using 64-bit raw integer registers but only + storing a left-aligned 32-bit value in each? */ + int mips64_transfers_32bit_regs_p; + /* Indexes for various registers. IRIX and embedded have + different values. This contains the "public" fields. Don't + add any that do not need to be public. */ + const struct mips_regnum *regnum; + /* Register names table for the current register set. */ + const char **mips_processor_reg_names; +}; + +const struct mips_regnum * +mips_regnum (struct gdbarch *gdbarch) +{ + return gdbarch_tdep (gdbarch)->regnum; +} + +static int +mips_fpa0_regnum (struct gdbarch *gdbarch) +{ + return mips_regnum (gdbarch)->fp0 + 12; +} + +#define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \ + || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64) + +#define MIPS_LAST_FP_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_fp_arg_regnum) + +#define MIPS_LAST_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_arg_regnum) + +#define MIPS_FPU_TYPE (gdbarch_tdep (current_gdbarch)->mips_fpu_type) + +/* MIPS16 function addresses are odd (bit 0 is set). Here are some + functions to test, set, or clear bit 0 of addresses. */ + +static CORE_ADDR +is_mips16_addr (CORE_ADDR addr) +{ + return ((addr) & 1); +} + +static CORE_ADDR +make_mips16_addr (CORE_ADDR addr) +{ + return ((addr) | 1); +} + +static CORE_ADDR +unmake_mips16_addr (CORE_ADDR addr) +{ + return ((addr) & ~1); +} + +/* Return the contents of register REGNUM as a signed integer. */ + +static LONGEST +read_signed_register (int regnum) +{ + void *buf = alloca (register_size (current_gdbarch, regnum)); + deprecated_read_register_gen (regnum, buf); + return (extract_signed_integer + (buf, register_size (current_gdbarch, regnum))); +} + +static LONGEST +read_signed_register_pid (int regnum, ptid_t ptid) +{ + ptid_t save_ptid; + LONGEST retval; + + if (ptid_equal (ptid, inferior_ptid)) + return read_signed_register (regnum); + + save_ptid = inferior_ptid; + + inferior_ptid = ptid; + + retval = read_signed_register (regnum); + + inferior_ptid = save_ptid; + + return retval; +} + +/* Return the MIPS ABI associated with GDBARCH. */ +enum mips_abi +mips_abi (struct gdbarch *gdbarch) +{ + return gdbarch_tdep (gdbarch)->mips_abi; +} + +int +mips_regsize (struct gdbarch *gdbarch) +{ + return (gdbarch_bfd_arch_info (gdbarch)->bits_per_word + / gdbarch_bfd_arch_info (gdbarch)->bits_per_byte); +} + +/* Return the currently configured (or set) saved register size. */ + +static const char *mips_saved_regsize_string = size_auto; + +static unsigned int +mips_saved_regsize (struct gdbarch_tdep *tdep) +{ + if (mips_saved_regsize_string == size_auto) + return tdep->mips_default_saved_regsize; + else if (mips_saved_regsize_string == size_64) + return 8; + else /* if (mips_saved_regsize_string == size_32) */ + return 4; +} + +/* Functions for setting and testing a bit in a minimal symbol that + marks it as 16-bit function. The MSB of the minimal symbol's + "info" field is used for this purpose. + + ELF_MAKE_MSYMBOL_SPECIAL tests whether an ELF symbol is "special", + i.e. refers to a 16-bit function, and sets a "special" bit in a + minimal symbol to mark it as a 16-bit function + + MSYMBOL_IS_SPECIAL tests the "special" bit in a minimal symbol */ + +static void +mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym) +{ + if (((elf_symbol_type *) (sym))->internal_elf_sym.st_other == STO_MIPS16) + { + MSYMBOL_INFO (msym) = (char *) + (((long) MSYMBOL_INFO (msym)) | 0x80000000); + SYMBOL_VALUE_ADDRESS (msym) |= 1; + } +} + +static int +msymbol_is_special (struct minimal_symbol *msym) +{ + return (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0); +} + +/* XFER a value from the big/little/left end of the register. + Depending on the size of the value it might occupy the entire + register or just part of it. Make an allowance for this, aligning + things accordingly. */ + +static void +mips_xfer_register (struct regcache *regcache, int reg_num, int length, + enum bfd_endian endian, bfd_byte * in, + const bfd_byte * out, int buf_offset) +{ + int reg_offset = 0; + gdb_assert (reg_num >= NUM_REGS); + /* Need to transfer the left or right part of the register, based on + the targets byte order. */ + switch (endian) + { + case BFD_ENDIAN_BIG: + reg_offset = register_size (current_gdbarch, reg_num) - length; + break; + case BFD_ENDIAN_LITTLE: + reg_offset = 0; + break; + case BFD_ENDIAN_UNKNOWN: /* Indicates no alignment. */ + reg_offset = 0; + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + if (mips_debug) + fprintf_unfiltered (gdb_stderr, + "xfer $%d, reg offset %d, buf offset %d, length %d, ", + reg_num, reg_offset, buf_offset, length); + if (mips_debug && out != NULL) + { + int i; + fprintf_unfiltered (gdb_stdlog, "out "); + for (i = 0; i < length; i++) + fprintf_unfiltered (gdb_stdlog, "%02x", out[buf_offset + i]); + } + if (in != NULL) + regcache_cooked_read_part (regcache, reg_num, reg_offset, length, + in + buf_offset); + if (out != NULL) + regcache_cooked_write_part (regcache, reg_num, reg_offset, length, + out + buf_offset); + if (mips_debug && in != NULL) + { + int i; + fprintf_unfiltered (gdb_stdlog, "in "); + for (i = 0; i < length; i++) + fprintf_unfiltered (gdb_stdlog, "%02x", in[buf_offset + i]); + } + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); +} + +/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU + compatiblity mode. A return value of 1 means that we have + physical 64-bit registers, but should treat them as 32-bit registers. */ + +static int +mips2_fp_compat (void) +{ + /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not + meaningful. */ + if (register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == + 4) + return 0; + +#if 0 + /* FIXME drow 2002-03-10: This is disabled until we can do it consistently, + in all the places we deal with FP registers. PR gdb/413. */ + /* Otherwise check the FR bit in the status register - it controls + the FP compatiblity mode. If it is clear we are in compatibility + mode. */ + if ((read_register (PS_REGNUM) & ST0_FR) == 0) + return 1; +#endif + + return 0; +} + +/* Indicate that the ABI makes use of double-precision registers + provided by the FPU (rather than combining pairs of registers to + form double-precision values). See also MIPS_FPU_TYPE. */ +#define FP_REGISTER_DOUBLE (gdbarch_tdep (current_gdbarch)->mips_fp_register_double) + +/* The amount of space reserved on the stack for registers. This is + different to MIPS_SAVED_REGSIZE as it determines the alignment of + data allocated after the registers have run out. */ + +static const char *mips_stack_argsize_string = size_auto; + +static unsigned int +mips_stack_argsize (struct gdbarch_tdep *tdep) +{ + if (mips_stack_argsize_string == size_auto) + return tdep->mips_default_stack_argsize; + else if (mips_stack_argsize_string == size_64) + return 8; + else /* if (mips_stack_argsize_string == size_32) */ + return 4; +} + +#define VM_MIN_ADDRESS (CORE_ADDR)0x400000 + +static mips_extra_func_info_t heuristic_proc_desc (CORE_ADDR, CORE_ADDR, + struct frame_info *, int); + +static CORE_ADDR heuristic_proc_start (CORE_ADDR); + +static CORE_ADDR read_next_frame_reg (struct frame_info *, int); + +static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *); + +static mips_extra_func_info_t find_proc_desc (CORE_ADDR pc, + struct frame_info *next_frame, + int cur_frame); + +static CORE_ADDR after_prologue (CORE_ADDR pc, + mips_extra_func_info_t proc_desc); + +static struct type *mips_float_register_type (void); +static struct type *mips_double_register_type (void); + +/* The list of available "set mips " and "show mips " commands */ + +static struct cmd_list_element *setmipscmdlist = NULL; +static struct cmd_list_element *showmipscmdlist = NULL; + +/* Integer registers 0 thru 31 are handled explicitly by + mips_register_name(). Processor specific registers 32 and above + are listed in the followign tables. */ + +enum +{ NUM_MIPS_PROCESSOR_REGS = (90 - 32) }; + +/* Generic MIPS. */ + +static const char *mips_generic_reg_names[NUM_MIPS_PROCESSOR_REGS] = { + "sr", "lo", "hi", "bad", "cause", "pc", + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", + "fsr", "fir", "" /*"fp" */ , "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", +}; + +/* Names of IDT R3041 registers. */ + +static const char *mips_r3041_reg_names[] = { + "sr", "lo", "hi", "bad", "cause", "pc", + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", + "fsr", "fir", "", /*"fp" */ "", + "", "", "bus", "ccfg", "", "", "", "", + "", "", "port", "cmp", "", "", "epc", "prid", +}; + +/* Names of tx39 registers. */ + +static const char *mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = { + "sr", "lo", "hi", "bad", "cause", "pc", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "config", "cache", "debug", "depc", "epc", "" +}; + +/* Names of IRIX registers. */ +static const char *mips_irix_reg_names[NUM_MIPS_PROCESSOR_REGS] = { + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", + "pc", "cause", "bad", "hi", "lo", "fsr", "fir" +}; + + +/* Return the name of the register corresponding to REGNO. */ +static const char * +mips_register_name (int regno) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + /* GPR names for all ABIs other than n32/n64. */ + static char *mips_gpr_names[] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", + }; + + /* GPR names for n32 and n64 ABIs. */ + static char *mips_n32_n64_gpr_names[] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" + }; + + enum mips_abi abi = mips_abi (current_gdbarch); + + /* Map [NUM_REGS .. 2*NUM_REGS) onto the raw registers, but then + don't make the raw register names visible. */ + int rawnum = regno % NUM_REGS; + if (regno < NUM_REGS) + return ""; + + /* The MIPS integer registers are always mapped from 0 to 31. The + names of the registers (which reflects the conventions regarding + register use) vary depending on the ABI. */ + if (0 <= rawnum && rawnum < 32) + { + if (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64) + return mips_n32_n64_gpr_names[rawnum]; + else + return mips_gpr_names[rawnum]; + } + else if (32 <= rawnum && rawnum < NUM_REGS) + { + gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS); + return tdep->mips_processor_reg_names[rawnum - 32]; + } + else + internal_error (__FILE__, __LINE__, + "mips_register_name: bad register number %d", rawnum); +} + +/* Return the groups that a MIPS register can be categorised into. */ + +static int +mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *reggroup) +{ + int vector_p; + int float_p; + int raw_p; + int rawnum = regnum % NUM_REGS; + int pseudo = regnum / NUM_REGS; + if (reggroup == all_reggroup) + return pseudo; + vector_p = TYPE_VECTOR (register_type (gdbarch, regnum)); + float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT; + /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs + (gdbarch), as not all architectures are multi-arch. */ + raw_p = rawnum < NUM_REGS; + if (REGISTER_NAME (regnum) == NULL || REGISTER_NAME (regnum)[0] == '\0') + return 0; + if (reggroup == float_reggroup) + return float_p && pseudo; + if (reggroup == vector_reggroup) + return vector_p && pseudo; + if (reggroup == general_reggroup) + return (!vector_p && !float_p) && pseudo; + /* Save the pseudo registers. Need to make certain that any code + extracting register values from a saved register cache also uses + pseudo registers. */ + if (reggroup == save_reggroup) + return raw_p && pseudo; + /* Restore the same pseudo register. */ + if (reggroup == restore_reggroup) + return raw_p && pseudo; + return 0; +} + +/* Map the symbol table registers which live in the range [1 * + NUM_REGS .. 2 * NUM_REGS) back onto the corresponding raw + registers. Take care of alignment and size problems. */ + +static void +mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int cookednum, void *buf) +{ + int rawnum = cookednum % NUM_REGS; + gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS); + if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum)) + regcache_raw_read (regcache, rawnum, buf); + else if (register_size (gdbarch, rawnum) > + register_size (gdbarch, cookednum)) + { + if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p + || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) + regcache_raw_read_part (regcache, rawnum, 0, 4, buf); + else + regcache_raw_read_part (regcache, rawnum, 4, 4, buf); + } + else + internal_error (__FILE__, __LINE__, "bad register size"); +} + +static void +mips_pseudo_register_write (struct gdbarch *gdbarch, + struct regcache *regcache, int cookednum, + const void *buf) +{ + int rawnum = cookednum % NUM_REGS; + gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS); + if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum)) + regcache_raw_write (regcache, rawnum, buf); + else if (register_size (gdbarch, rawnum) > + register_size (gdbarch, cookednum)) + { + if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p + || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) + regcache_raw_write_part (regcache, rawnum, 0, 4, buf); + else + regcache_raw_write_part (regcache, rawnum, 4, 4, buf); + } + else + internal_error (__FILE__, __LINE__, "bad register size"); +} + +/* Table to translate MIPS16 register field to actual register number. */ +static int mips16_to_32_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 }; + +/* Heuristic_proc_start may hunt through the text section for a long + time across a 2400 baud serial line. Allows the user to limit this + search. */ + +static unsigned int heuristic_fence_post = 0; + +#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */ +#define PROC_HIGH_ADDR(proc) ((proc)->high_addr) /* upper address bound */ +#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset) +#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg) +#define PROC_FRAME_ADJUST(proc) ((proc)->frame_adjust) +#define PROC_REG_MASK(proc) ((proc)->pdr.regmask) +#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask) +#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset) +#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset) +#define PROC_PC_REG(proc) ((proc)->pdr.pcreg) +/* FIXME drow/2002-06-10: If a pointer on the host is bigger than a long, + this will corrupt pdr.iline. Fortunately we don't use it. */ +#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym) +#define _PROC_MAGIC_ 0x0F0F0F0F +#define PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym == _PROC_MAGIC_) +#define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_) + +struct linked_proc_info +{ + struct mips_extra_func_info info; + struct linked_proc_info *next; +} + *linked_proc_desc_table = NULL; + +/* Number of bytes of storage in the actual machine representation for + register N. NOTE: This defines the pseudo register type so need to + rebuild the architecture vector. */ + +static int mips64_transfers_32bit_regs_p = 0; + +static void +set_mips64_transfers_32bit_regs (char *args, int from_tty, + struct cmd_list_element *c) +{ + struct gdbarch_info info; + gdbarch_info_init (&info); + /* FIXME: cagney/2003-11-15: Should be setting a field in "info" + instead of relying on globals. Doing that would let generic code + handle the search for this specific architecture. */ + if (!gdbarch_update_p (info)) + { + mips64_transfers_32bit_regs_p = 0; + error ("32-bit compatibility mode not supported"); + } +} + +/* Convert to/from a register and the corresponding memory value. */ + +static int +mips_convert_register_p (int regnum, struct type *type) +{ + return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && register_size (current_gdbarch, regnum) == 4 + && (regnum % NUM_REGS) >= mips_regnum (current_gdbarch)->fp0 + && (regnum % NUM_REGS) < mips_regnum (current_gdbarch)->fp0 + 32 + && TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8); +} + +static void +mips_register_to_value (struct frame_info *frame, int regnum, + struct type *type, void *to) +{ + get_frame_register (frame, regnum + 0, (char *) to + 4); + get_frame_register (frame, regnum + 1, (char *) to + 0); +} + +static void +mips_value_to_register (struct frame_info *frame, int regnum, + struct type *type, const void *from) +{ + put_frame_register (frame, regnum + 0, (const char *) from + 4); + put_frame_register (frame, regnum + 1, (const char *) from + 0); +} + +/* Return the GDB type object for the "standard" data type of data in + register REG. */ + +static struct type * +mips_register_type (struct gdbarch *gdbarch, int regnum) +{ + gdb_assert (regnum >= 0 && regnum < 2 * NUM_REGS); + if ((regnum % NUM_REGS) >= mips_regnum (current_gdbarch)->fp0 + && (regnum % NUM_REGS) < mips_regnum (current_gdbarch)->fp0 + 32) + { + /* The floating-point registers raw, or cooked, always match + mips_regsize(), and also map 1:1, byte for byte. */ + switch (gdbarch_byte_order (gdbarch)) + { + case BFD_ENDIAN_BIG: + if (mips_regsize (gdbarch) == 4) + return builtin_type_ieee_single_big; + else + return builtin_type_ieee_double_big; + case BFD_ENDIAN_LITTLE: + if (mips_regsize (gdbarch) == 4) + return builtin_type_ieee_single_little; + else + return builtin_type_ieee_double_little; + case BFD_ENDIAN_UNKNOWN: + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + } + else if (regnum >= + (NUM_REGS + mips_regnum (current_gdbarch)->fp_control_status) + && regnum <= NUM_REGS + LAST_EMBED_REGNUM) + /* The pseudo/cooked view of the embedded registers is always + 32-bit. The raw view is handled below. */ + return builtin_type_int32; + else if (regnum >= NUM_REGS && mips_regsize (gdbarch) + && gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p) + /* The target, while using a 64-bit register buffer, is only + transfering 32-bits of each integer register. Reflect this in + the cooked/pseudo register value. */ + return builtin_type_int32; + else if (mips_regsize (gdbarch) == 8) + /* 64-bit ISA. */ + return builtin_type_int64; + else + /* 32-bit ISA. */ + return builtin_type_int32; +} + +/* TARGET_READ_SP -- Remove useless bits from the stack pointer. */ + +static CORE_ADDR +mips_read_sp (void) +{ + return read_signed_register (SP_REGNUM); +} + +/* Should the upper word of 64-bit addresses be zeroed? */ +enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO; + +static int +mips_mask_address_p (struct gdbarch_tdep *tdep) +{ + switch (mask_address_var) + { + case AUTO_BOOLEAN_TRUE: + return 1; + case AUTO_BOOLEAN_FALSE: + return 0; + break; + case AUTO_BOOLEAN_AUTO: + return tdep->default_mask_address_p; + default: + internal_error (__FILE__, __LINE__, "mips_mask_address_p: bad switch"); + return -1; + } +} + +static void +show_mask_address (char *cmd, int from_tty, struct cmd_list_element *c) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + switch (mask_address_var) + { + case AUTO_BOOLEAN_TRUE: + printf_filtered ("The 32 bit mips address mask is enabled\n"); + break; + case AUTO_BOOLEAN_FALSE: + printf_filtered ("The 32 bit mips address mask is disabled\n"); + break; + case AUTO_BOOLEAN_AUTO: + printf_filtered + ("The 32 bit address mask is set automatically. Currently %s\n", + mips_mask_address_p (tdep) ? "enabled" : "disabled"); + break; + default: + internal_error (__FILE__, __LINE__, "show_mask_address: bad switch"); + break; + } +} + +/* Tell if the program counter value in MEMADDR is in a MIPS16 function. */ + +static int +pc_is_mips16 (bfd_vma memaddr) +{ + struct minimal_symbol *sym; + + /* If bit 0 of the address is set, assume this is a MIPS16 address. */ + if (is_mips16_addr (memaddr)) + return 1; + + /* A flag indicating that this is a MIPS16 function is stored by elfread.c in + the high bit of the info field. Use this to decide if the function is + MIPS16 or normal MIPS. */ + sym = lookup_minimal_symbol_by_pc (memaddr); + if (sym) + return msymbol_is_special (sym); + else + return 0; +} + +/* MIPS believes that the PC has a sign extended value. Perhaphs the + all registers should be sign extended for simplicity? */ + +static CORE_ADDR +mips_read_pc (ptid_t ptid) +{ + return read_signed_register_pid (mips_regnum (current_gdbarch)->pc, ptid); +} + +static CORE_ADDR +mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + return frame_unwind_register_signed (next_frame, + NUM_REGS + mips_regnum (gdbarch)->pc); +} + +/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that + dummy frame. The frame ID's base needs to match the TOS value + saved by save_dummy_frame_tos(), and the PC match the dummy frame's + breakpoint. */ + +static struct frame_id +mips_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + return frame_id_build (frame_unwind_register_signed (next_frame, NUM_REGS + SP_REGNUM), + frame_pc_unwind (next_frame)); +} + +static void +mips_write_pc (CORE_ADDR pc, ptid_t ptid) +{ + write_register_pid (mips_regnum (current_gdbarch)->pc, pc, ptid); +} + +/* This returns the PC of the first inst after the prologue. If we can't + find the prologue, then return 0. */ + +static CORE_ADDR +after_prologue (CORE_ADDR pc, mips_extra_func_info_t proc_desc) +{ + struct symtab_and_line sal; + CORE_ADDR func_addr, func_end; + + /* Pass cur_frame == 0 to find_proc_desc. We should not attempt + to read the stack pointer from the current machine state, because + the current machine state has nothing to do with the information + we need from the proc_desc; and the process may or may not exist + right now. */ + if (!proc_desc) + proc_desc = find_proc_desc (pc, NULL, 0); + + if (proc_desc) + { + /* If function is frameless, then we need to do it the hard way. I + strongly suspect that frameless always means prologueless... */ + if (PROC_FRAME_REG (proc_desc) == SP_REGNUM + && PROC_FRAME_OFFSET (proc_desc) == 0) + return 0; + } + + if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) + return 0; /* Unknown */ + + sal = find_pc_line (func_addr, 0); + + if (sal.end < func_end) + return sal.end; + + /* The line after the prologue is after the end of the function. In this + case, tell the caller to find the prologue the hard way. */ + + return 0; +} + +/* Decode a MIPS32 instruction that saves a register in the stack, and + set the appropriate bit in the general register mask or float register mask + to indicate which register is saved. This is a helper function + for mips_find_saved_regs. */ + +static void +mips32_decode_reg_save (t_inst inst, unsigned long *gen_mask, + unsigned long *float_mask) +{ + int reg; + + if ((inst & 0xffe00000) == 0xafa00000 /* sw reg,n($sp) */ + || (inst & 0xffe00000) == 0xafc00000 /* sw reg,n($r30) */ + || (inst & 0xffe00000) == 0xffa00000) /* sd reg,n($sp) */ + { + /* It might be possible to use the instruction to + find the offset, rather than the code below which + is based on things being in a certain order in the + frame, but figuring out what the instruction's offset + is relative to might be a little tricky. */ + reg = (inst & 0x001f0000) >> 16; + *gen_mask |= (1 << reg); + } + else if ((inst & 0xffe00000) == 0xe7a00000 /* swc1 freg,n($sp) */ + || (inst & 0xffe00000) == 0xe7c00000 /* swc1 freg,n($r30) */ + || (inst & 0xffe00000) == 0xf7a00000) /* sdc1 freg,n($sp) */ + + { + reg = ((inst & 0x001f0000) >> 16); + *float_mask |= (1 << reg); + } +} + +/* Decode a MIPS16 instruction that saves a register in the stack, and + set the appropriate bit in the general register or float register mask + to indicate which register is saved. This is a helper function + for mips_find_saved_regs. */ + +static void +mips16_decode_reg_save (t_inst inst, unsigned long *gen_mask) +{ + if ((inst & 0xf800) == 0xd000) /* sw reg,n($sp) */ + { + int reg = mips16_to_32_reg[(inst & 0x700) >> 8]; + *gen_mask |= (1 << reg); + } + else if ((inst & 0xff00) == 0xf900) /* sd reg,n($sp) */ + { + int reg = mips16_to_32_reg[(inst & 0xe0) >> 5]; + *gen_mask |= (1 << reg); + } + else if ((inst & 0xff00) == 0x6200 /* sw $ra,n($sp) */ + || (inst & 0xff00) == 0xfa00) /* sd $ra,n($sp) */ + *gen_mask |= (1 << RA_REGNUM); +} + + +/* Fetch and return instruction from the specified location. If the PC + is odd, assume it's a MIPS16 instruction; otherwise MIPS32. */ + +static t_inst +mips_fetch_instruction (CORE_ADDR addr) +{ + char buf[MIPS_INSTLEN]; + int instlen; + int status; + + if (pc_is_mips16 (addr)) + { + instlen = MIPS16_INSTLEN; + addr = unmake_mips16_addr (addr); + } + else + instlen = MIPS_INSTLEN; + status = read_memory_nobpt (addr, buf, instlen); + if (status) + memory_error (status, addr); + return extract_unsigned_integer (buf, instlen); +} + +static ULONGEST +mips16_fetch_instruction (CORE_ADDR addr) +{ + char buf[MIPS_INSTLEN]; + int instlen; + int status; + + instlen = MIPS16_INSTLEN; + addr = unmake_mips16_addr (addr); + status = read_memory_nobpt (addr, buf, instlen); + if (status) + memory_error (status, addr); + return extract_unsigned_integer (buf, instlen); +} + +static ULONGEST +mips32_fetch_instruction (CORE_ADDR addr) +{ + char buf[MIPS_INSTLEN]; + int instlen; + int status; + instlen = MIPS_INSTLEN; + status = read_memory_nobpt (addr, buf, instlen); + if (status) + memory_error (status, addr); + return extract_unsigned_integer (buf, instlen); +} + + +/* These the fields of 32 bit mips instructions */ +#define mips32_op(x) (x >> 26) +#define itype_op(x) (x >> 26) +#define itype_rs(x) ((x >> 21) & 0x1f) +#define itype_rt(x) ((x >> 16) & 0x1f) +#define itype_immediate(x) (x & 0xffff) + +#define jtype_op(x) (x >> 26) +#define jtype_target(x) (x & 0x03ffffff) + +#define rtype_op(x) (x >> 26) +#define rtype_rs(x) ((x >> 21) & 0x1f) +#define rtype_rt(x) ((x >> 16) & 0x1f) +#define rtype_rd(x) ((x >> 11) & 0x1f) +#define rtype_shamt(x) ((x >> 6) & 0x1f) +#define rtype_funct(x) (x & 0x3f) + +static CORE_ADDR +mips32_relative_offset (unsigned long inst) +{ + long x; + x = itype_immediate (inst); + if (x & 0x8000) /* sign bit set */ + { + x |= 0xffff0000; /* sign extension */ + } + x = x << 2; + return x; +} + +/* Determine whate to set a single step breakpoint while considering + branch prediction */ +static CORE_ADDR +mips32_next_pc (CORE_ADDR pc) +{ + unsigned long inst; + int op; + inst = mips_fetch_instruction (pc); + if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch instruction */ + { + if (itype_op (inst) >> 2 == 5) + /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */ + { + op = (itype_op (inst) & 0x03); + switch (op) + { + case 0: /* BEQL */ + goto equal_branch; + case 1: /* BNEL */ + goto neq_branch; + case 2: /* BLEZL */ + goto less_branch; + case 3: /* BGTZ */ + goto greater_branch; + default: + pc += 4; + } + } + else if (itype_op (inst) == 17 && itype_rs (inst) == 8) + /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */ + { + int tf = itype_rt (inst) & 0x01; + int cnum = itype_rt (inst) >> 2; + int fcrcs = + read_signed_register (mips_regnum (current_gdbarch)-> + fp_control_status); + int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01); + + if (((cond >> cnum) & 0x01) == tf) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; + } + else + pc += 4; /* Not a branch, next instruction is easy */ + } + else + { /* This gets way messy */ + + /* Further subdivide into SPECIAL, REGIMM and other */ + switch (op = itype_op (inst) & 0x07) /* extract bits 28,27,26 */ + { + case 0: /* SPECIAL */ + op = rtype_funct (inst); + switch (op) + { + case 8: /* JR */ + case 9: /* JALR */ + /* Set PC to that address */ + pc = read_signed_register (rtype_rs (inst)); + break; + default: + pc += 4; + } + + break; /* end SPECIAL */ + case 1: /* REGIMM */ + { + op = itype_rt (inst); /* branch condition */ + switch (op) + { + case 0: /* BLTZ */ + case 2: /* BLTZL */ + case 16: /* BLTZAL */ + case 18: /* BLTZALL */ + less_branch: + if (read_signed_register (itype_rs (inst)) < 0) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; /* after the delay slot */ + break; + case 1: /* BGEZ */ + case 3: /* BGEZL */ + case 17: /* BGEZAL */ + case 19: /* BGEZALL */ + if (read_signed_register (itype_rs (inst)) >= 0) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; /* after the delay slot */ + break; + /* All of the other instructions in the REGIMM category */ + default: + pc += 4; + } + } + break; /* end REGIMM */ + case 2: /* J */ + case 3: /* JAL */ + { + unsigned long reg; + reg = jtype_target (inst) << 2; + /* Upper four bits get never changed... */ + pc = reg + ((pc + 4) & 0xf0000000); + } + break; + /* FIXME case JALX : */ + { + unsigned long reg; + reg = jtype_target (inst) << 2; + pc = reg + ((pc + 4) & 0xf0000000) + 1; /* yes, +1 */ + /* Add 1 to indicate 16 bit mode - Invert ISA mode */ + } + break; /* The new PC will be alternate mode */ + case 4: /* BEQ, BEQL */ + equal_branch: + if (read_signed_register (itype_rs (inst)) == + read_signed_register (itype_rt (inst))) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; + break; + case 5: /* BNE, BNEL */ + neq_branch: + if (read_signed_register (itype_rs (inst)) != + read_signed_register (itype_rt (inst))) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; + break; + case 6: /* BLEZ, BLEZL */ + if (read_signed_register (itype_rs (inst) <= 0)) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; + break; + case 7: + default: + greater_branch: /* BGTZ, BGTZL */ + if (read_signed_register (itype_rs (inst) > 0)) + pc += mips32_relative_offset (inst) + 4; + else + pc += 8; + break; + } /* switch */ + } /* else */ + return pc; +} /* mips32_next_pc */ + +/* Decoding the next place to set a breakpoint is irregular for the + mips 16 variant, but fortunately, there fewer instructions. We have to cope + ith extensions for 16 bit instructions and a pair of actual 32 bit instructions. + We dont want to set a single step instruction on the extend instruction + either. + */ + +/* Lots of mips16 instruction formats */ +/* Predicting jumps requires itype,ritype,i8type + and their extensions extItype,extritype,extI8type + */ +enum mips16_inst_fmts +{ + itype, /* 0 immediate 5,10 */ + ritype, /* 1 5,3,8 */ + rrtype, /* 2 5,3,3,5 */ + rritype, /* 3 5,3,3,5 */ + rrrtype, /* 4 5,3,3,3,2 */ + rriatype, /* 5 5,3,3,1,4 */ + shifttype, /* 6 5,3,3,3,2 */ + i8type, /* 7 5,3,8 */ + i8movtype, /* 8 5,3,3,5 */ + i8mov32rtype, /* 9 5,3,5,3 */ + i64type, /* 10 5,3,8 */ + ri64type, /* 11 5,3,3,5 */ + jalxtype, /* 12 5,1,5,5,16 - a 32 bit instruction */ + exiItype, /* 13 5,6,5,5,1,1,1,1,1,1,5 */ + extRitype, /* 14 5,6,5,5,3,1,1,1,5 */ + extRRItype, /* 15 5,5,5,5,3,3,5 */ + extRRIAtype, /* 16 5,7,4,5,3,3,1,4 */ + EXTshifttype, /* 17 5,5,1,1,1,1,1,1,5,3,3,1,1,1,2 */ + extI8type, /* 18 5,6,5,5,3,1,1,1,5 */ + extI64type, /* 19 5,6,5,5,3,1,1,1,5 */ + extRi64type, /* 20 5,6,5,5,3,3,5 */ + extshift64type /* 21 5,5,1,1,1,1,1,1,5,1,1,1,3,5 */ +}; +/* I am heaping all the fields of the formats into one structure and + then, only the fields which are involved in instruction extension */ +struct upk_mips16 +{ + CORE_ADDR offset; + unsigned int regx; /* Function in i8 type */ + unsigned int regy; +}; + + +/* The EXT-I, EXT-ri nad EXT-I8 instructions all have the same format + for the bits which make up the immediatate extension. */ + +static CORE_ADDR +extended_offset (unsigned int extension) +{ + CORE_ADDR value; + value = (extension >> 21) & 0x3f; /* * extract 15:11 */ + value = value << 6; + value |= (extension >> 16) & 0x1f; /* extrace 10:5 */ + value = value << 5; + value |= extension & 0x01f; /* extract 4:0 */ + return value; +} + +/* Only call this function if you know that this is an extendable + instruction, It wont malfunction, but why make excess remote memory references? + If the immediate operands get sign extended or somthing, do it after + the extension is performed. + */ +/* FIXME: Every one of these cases needs to worry about sign extension + when the offset is to be used in relative addressing */ + + +static unsigned int +fetch_mips_16 (CORE_ADDR pc) +{ + char buf[8]; + pc &= 0xfffffffe; /* clear the low order bit */ + target_read_memory (pc, buf, 2); + return extract_unsigned_integer (buf, 2); +} + +static void +unpack_mips16 (CORE_ADDR pc, + unsigned int extension, + unsigned int inst, + enum mips16_inst_fmts insn_format, struct upk_mips16 *upk) +{ + CORE_ADDR offset; + int regx; + int regy; + switch (insn_format) + { + case itype: + { + CORE_ADDR value; + if (extension) + { + value = extended_offset (extension); + value = value << 11; /* rom for the original value */ + value |= inst & 0x7ff; /* eleven bits from instruction */ + } + else + { + value = inst & 0x7ff; + /* FIXME : Consider sign extension */ + } + offset = value; + regx = -1; + regy = -1; + } + break; + case ritype: + case i8type: + { /* A register identifier and an offset */ + /* Most of the fields are the same as I type but the + immediate value is of a different length */ + CORE_ADDR value; + if (extension) + { + value = extended_offset (extension); + value = value << 8; /* from the original instruction */ + value |= inst & 0xff; /* eleven bits from instruction */ + regx = (extension >> 8) & 0x07; /* or i8 funct */ + if (value & 0x4000) /* test the sign bit , bit 26 */ + { + value &= ~0x3fff; /* remove the sign bit */ + value = -value; + } + } + else + { + value = inst & 0xff; /* 8 bits */ + regx = (inst >> 8) & 0x07; /* or i8 funct */ + /* FIXME: Do sign extension , this format needs it */ + if (value & 0x80) /* THIS CONFUSES ME */ + { + value &= 0xef; /* remove the sign bit */ + value = -value; + } + } + offset = value; + regy = -1; + break; + } + case jalxtype: + { + unsigned long value; + unsigned int nexthalf; + value = ((inst & 0x1f) << 5) | ((inst >> 5) & 0x1f); + value = value << 16; + nexthalf = mips_fetch_instruction (pc + 2); /* low bit still set */ + value |= nexthalf; + offset = value; + regx = -1; + regy = -1; + break; + } + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + upk->offset = offset; + upk->regx = regx; + upk->regy = regy; +} + + +static CORE_ADDR +add_offset_16 (CORE_ADDR pc, int offset) +{ + return ((offset << 2) | ((pc + 2) & (0xf0000000))); +} + +static CORE_ADDR +extended_mips16_next_pc (CORE_ADDR pc, + unsigned int extension, unsigned int insn) +{ + int op = (insn >> 11); + switch (op) + { + case 2: /* Branch */ + { + CORE_ADDR offset; + struct upk_mips16 upk; + unpack_mips16 (pc, extension, insn, itype, &upk); + offset = upk.offset; + if (offset & 0x800) + { + offset &= 0xeff; + offset = -offset; + } + pc += (offset << 1) + 2; + break; + } + case 3: /* JAL , JALX - Watch out, these are 32 bit instruction */ + { + struct upk_mips16 upk; + unpack_mips16 (pc, extension, insn, jalxtype, &upk); + pc = add_offset_16 (pc, upk.offset); + if ((insn >> 10) & 0x01) /* Exchange mode */ + pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode */ + else + pc |= 0x01; + break; + } + case 4: /* beqz */ + { + struct upk_mips16 upk; + int reg; + unpack_mips16 (pc, extension, insn, ritype, &upk); + reg = read_signed_register (upk.regx); + if (reg == 0) + pc += (upk.offset << 1) + 2; + else + pc += 2; + break; + } + case 5: /* bnez */ + { + struct upk_mips16 upk; + int reg; + unpack_mips16 (pc, extension, insn, ritype, &upk); + reg = read_signed_register (upk.regx); + if (reg != 0) + pc += (upk.offset << 1) + 2; + else + pc += 2; + break; + } + case 12: /* I8 Formats btez btnez */ + { + struct upk_mips16 upk; + int reg; + unpack_mips16 (pc, extension, insn, i8type, &upk); + /* upk.regx contains the opcode */ + reg = read_signed_register (24); /* Test register is 24 */ + if (((upk.regx == 0) && (reg == 0)) /* BTEZ */ + || ((upk.regx == 1) && (reg != 0))) /* BTNEZ */ + /* pc = add_offset_16(pc,upk.offset) ; */ + pc += (upk.offset << 1) + 2; + else + pc += 2; + break; + } + case 29: /* RR Formats JR, JALR, JALR-RA */ + { + struct upk_mips16 upk; + /* upk.fmt = rrtype; */ + op = insn & 0x1f; + if (op == 0) + { + int reg; + upk.regx = (insn >> 8) & 0x07; + upk.regy = (insn >> 5) & 0x07; + switch (upk.regy) + { + case 0: + reg = upk.regx; + break; + case 1: + reg = 31; + break; /* Function return instruction */ + case 2: + reg = upk.regx; + break; + default: + reg = 31; + break; /* BOGUS Guess */ + } + pc = read_signed_register (reg); + } + else + pc += 2; + break; + } + case 30: + /* This is an instruction extension. Fetch the real instruction + (which follows the extension) and decode things based on + that. */ + { + pc += 2; + pc = extended_mips16_next_pc (pc, insn, fetch_mips_16 (pc)); + break; + } + default: + { + pc += 2; + break; + } + } + return pc; +} + +static CORE_ADDR +mips16_next_pc (CORE_ADDR pc) +{ + unsigned int insn = fetch_mips_16 (pc); + return extended_mips16_next_pc (pc, 0, insn); +} + +/* The mips_next_pc function supports single_step when the remote + target monitor or stub is not developed enough to do a single_step. + It works by decoding the current instruction and predicting where a + branch will go. This isnt hard because all the data is available. + The MIPS32 and MIPS16 variants are quite different */ +CORE_ADDR +mips_next_pc (CORE_ADDR pc) +{ + if (pc & 0x01) + return mips16_next_pc (pc); + else + return mips32_next_pc (pc); +} + +struct mips_frame_cache +{ + CORE_ADDR base; + struct trad_frame_saved_reg *saved_regs; +}; + + +static struct mips_frame_cache * +mips_mdebug_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + mips_extra_func_info_t proc_desc; + struct mips_frame_cache *cache; + struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* r0 bit means kernel trap */ + int kernel_trap; + /* What registers have been saved? Bitmasks. */ + unsigned long gen_mask, float_mask; + + if ((*this_cache) != NULL) + return (*this_cache); + cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); + (*this_cache) = cache; + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + /* Get the mdebug proc descriptor. */ + proc_desc = find_proc_desc (frame_pc_unwind (next_frame), next_frame, 1); + if (proc_desc == NULL) + /* I'm not sure how/whether this can happen. Normally when we + can't find a proc_desc, we "synthesize" one using + heuristic_proc_desc and set the saved_regs right away. */ + return cache; + + /* Extract the frame's base. */ + cache->base = (frame_unwind_register_signed (next_frame, NUM_REGS + PROC_FRAME_REG (proc_desc)) + + PROC_FRAME_OFFSET (proc_desc) - PROC_FRAME_ADJUST (proc_desc)); + + kernel_trap = PROC_REG_MASK (proc_desc) & 1; + gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK (proc_desc); + float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK (proc_desc); + + /* In any frame other than the innermost or a frame interrupted by a + signal, we assume that all registers have been saved. This + assumes that all register saves in a function happen before the + first function call. */ + if (in_prologue (frame_pc_unwind (next_frame), PROC_LOW_ADDR (proc_desc)) + /* Not sure exactly what kernel_trap means, but if it means the + kernel saves the registers without a prologue doing it, we + better not examine the prologue to see whether registers + have been saved yet. */ + && !kernel_trap) + { + /* We need to figure out whether the registers that the + proc_desc claims are saved have been saved yet. */ + + CORE_ADDR addr; + + /* Bitmasks; set if we have found a save for the register. */ + unsigned long gen_save_found = 0; + unsigned long float_save_found = 0; + int mips16; + + /* If the address is odd, assume this is MIPS16 code. */ + addr = PROC_LOW_ADDR (proc_desc); + mips16 = pc_is_mips16 (addr); + + /* Scan through this function's instructions preceding the + current PC, and look for those that save registers. */ + while (addr < frame_pc_unwind (next_frame)) + { + if (mips16) + { + mips16_decode_reg_save (mips16_fetch_instruction (addr), + &gen_save_found); + addr += MIPS16_INSTLEN; + } + else + { + mips32_decode_reg_save (mips32_fetch_instruction (addr), + &gen_save_found, &float_save_found); + addr += MIPS_INSTLEN; + } + } + gen_mask = gen_save_found; + float_mask = float_save_found; + } + + /* Fill in the offsets for the registers which gen_mask says were + saved. */ + { + CORE_ADDR reg_position = (cache->base + + PROC_REG_OFFSET (proc_desc)); + int ireg; + for (ireg = MIPS_NUMREGS - 1; gen_mask; --ireg, gen_mask <<= 1) + if (gen_mask & 0x80000000) + { + cache->saved_regs[NUM_REGS + ireg].addr = reg_position; + reg_position -= mips_saved_regsize (tdep); + } + } + + /* The MIPS16 entry instruction saves $s0 and $s1 in the reverse + order of that normally used by gcc. Therefore, we have to fetch + the first instruction of the function, and if it's an entry + instruction that saves $s0 or $s1, correct their saved addresses. */ + if (pc_is_mips16 (PROC_LOW_ADDR (proc_desc))) + { + ULONGEST inst = mips16_fetch_instruction (PROC_LOW_ADDR (proc_desc)); + if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) + /* entry */ + { + int reg; + int sreg_count = (inst >> 6) & 3; + + /* Check if the ra register was pushed on the stack. */ + CORE_ADDR reg_position = (cache->base + + PROC_REG_OFFSET (proc_desc)); + if (inst & 0x20) + reg_position -= mips_saved_regsize (tdep); + + /* Check if the s0 and s1 registers were pushed on the + stack. */ + /* NOTE: cagney/2004-02-08: Huh? This is doing no such + check. */ + for (reg = 16; reg < sreg_count + 16; reg++) + { + cache->saved_regs[NUM_REGS + reg].addr = reg_position; + reg_position -= mips_saved_regsize (tdep); + } + } + } + + /* Fill in the offsets for the registers which float_mask says were + saved. */ + { + CORE_ADDR reg_position = (cache->base + + PROC_FREG_OFFSET (proc_desc)); + int ireg; + /* Fill in the offsets for the float registers which float_mask + says were saved. */ + for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1) + if (float_mask & 0x80000000) + { + if (mips_saved_regsize (tdep) == 4 + && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + /* On a big endian 32 bit ABI, floating point registers + are paired to form doubles such that the most + significant part is in $f[N+1] and the least + significant in $f[N] vis: $f[N+1] ||| $f[N]. The + registers are also spilled as a pair and stored as a + double. + + When little-endian the least significant part is + stored first leading to the memory order $f[N] and + then $f[N+1]. + + Unfortunately, when big-endian the most significant + part of the double is stored first, and the least + significant is stored second. This leads to the + registers being ordered in memory as firt $f[N+1] and + then $f[N]. + + For the big-endian case make certain that the + addresses point at the correct (swapped) locations + $f[N] and $f[N+1] pair (keep in mind that + reg_position is decremented each time through the + loop). */ + if ((ireg & 1)) + cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->fp0 + ireg] + .addr = reg_position - mips_saved_regsize (tdep); + else + cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->fp0 + ireg] + .addr = reg_position + mips_saved_regsize (tdep); + } + else + cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->fp0 + ireg] + .addr = reg_position; + reg_position -= mips_saved_regsize (tdep); + } + + cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc] + = cache->saved_regs[NUM_REGS + RA_REGNUM]; + } + + /* SP_REGNUM, contains the value and not the address. */ + trad_frame_set_value (cache->saved_regs, NUM_REGS + SP_REGNUM, cache->base); + + return (*this_cache); +} + +static void +mips_mdebug_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame, + this_cache); + (*this_id) = frame_id_build (info->base, frame_func_unwind (next_frame)); +} + +static void +mips_mdebug_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame, + this_cache); + trad_frame_prev_register (next_frame, info->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind mips_mdebug_frame_unwind = +{ + NORMAL_FRAME, + mips_mdebug_frame_this_id, + mips_mdebug_frame_prev_register +}; + +static const struct frame_unwind * +mips_mdebug_frame_sniffer (struct frame_info *next_frame) +{ + return &mips_mdebug_frame_unwind; +} + +static CORE_ADDR +mips_mdebug_frame_base_address (struct frame_info *next_frame, + void **this_cache) +{ + struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame, + this_cache); + return info->base; +} + +static const struct frame_base mips_mdebug_frame_base = { + &mips_mdebug_frame_unwind, + mips_mdebug_frame_base_address, + mips_mdebug_frame_base_address, + mips_mdebug_frame_base_address +}; + +static const struct frame_base * +mips_mdebug_frame_base_sniffer (struct frame_info *next_frame) +{ + return &mips_mdebug_frame_base; +} + +static CORE_ADDR +read_next_frame_reg (struct frame_info *fi, int regno) +{ + /* Always a pseudo. */ + gdb_assert (regno >= NUM_REGS); + if (fi == NULL) + { + LONGEST val; + regcache_cooked_read_signed (current_regcache, regno, &val); + return val; + } + else if ((regno % NUM_REGS) == SP_REGNUM) + /* The SP_REGNUM is special, its value is stored in saved_regs. + In fact, it is so special that it can even only be fetched + using a raw register number! Once this code as been converted + to frame-unwind the problem goes away. */ + return frame_unwind_register_signed (fi, regno % NUM_REGS); + else + return frame_unwind_register_signed (fi, regno); + +} + +/* mips_addr_bits_remove - remove useless address bits */ + +static CORE_ADDR +mips_addr_bits_remove (CORE_ADDR addr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL)) + /* This hack is a work-around for existing boards using PMON, the + simulator, and any other 64-bit targets that doesn't have true + 64-bit addressing. On these targets, the upper 32 bits of + addresses are ignored by the hardware. Thus, the PC or SP are + likely to have been sign extended to all 1s by instruction + sequences that load 32-bit addresses. For example, a typical + piece of code that loads an address is this: + + lui $r2, + ori $r2, + + But the lui sign-extends the value such that the upper 32 bits + may be all 1s. The workaround is simply to mask off these + bits. In the future, gcc may be changed to support true 64-bit + addressing, and this masking will have to be disabled. */ + return addr &= 0xffffffffUL; + else + return addr; +} + +/* mips_software_single_step() is called just before we want to resume + the inferior, if we want to single-step it but there is no hardware + or kernel single-step support (MIPS on GNU/Linux for example). We find + the target of the coming instruction and breakpoint it. + + single_step is also called just after the inferior stops. If we had + set up a simulated single-step, we undo our damage. */ + +void +mips_software_single_step (enum target_signal sig, int insert_breakpoints_p) +{ + static CORE_ADDR next_pc; + typedef char binsn_quantum[BREAKPOINT_MAX]; + static binsn_quantum break_mem; + CORE_ADDR pc; + + if (insert_breakpoints_p) + { + pc = read_register (mips_regnum (current_gdbarch)->pc); + next_pc = mips_next_pc (pc); + + target_insert_breakpoint (next_pc, break_mem); + } + else + target_remove_breakpoint (next_pc, break_mem); +} + +static struct mips_extra_func_info temp_proc_desc; + +/* This hack will go away once the get_prev_frame() code has been + modified to set the frame's type first. That is BEFORE init extra + frame info et.al. is called. This is because it will become + possible to skip the init extra info call for sigtramp and dummy + frames. */ +static CORE_ADDR *temp_saved_regs; + +/* Set a register's saved stack address in temp_saved_regs. If an + address has already been set for this register, do nothing; this + way we will only recognize the first save of a given register in a + function prologue. + + For simplicity, save the address in both [0 .. NUM_REGS) and + [NUM_REGS .. 2*NUM_REGS). Strictly speaking, only the second range + is used as it is only second range (the ABI instead of ISA + registers) that comes into play when finding saved registers in a + frame. */ + +static void +set_reg_offset (CORE_ADDR *saved_regs, int regno, CORE_ADDR offset) +{ + if (saved_regs[regno] == 0) + { + saved_regs[regno + 0 * NUM_REGS] = offset; + saved_regs[regno + 1 * NUM_REGS] = offset; + } +} + + +/* Test whether the PC points to the return instruction at the + end of a function. */ + +static int +mips_about_to_return (CORE_ADDR pc) +{ + if (pc_is_mips16 (pc)) + /* This mips16 case isn't necessarily reliable. Sometimes the compiler + generates a "jr $ra"; other times it generates code to load + the return address from the stack to an accessible register (such + as $a3), then a "jr" using that register. This second case + is almost impossible to distinguish from an indirect jump + used for switch statements, so we don't even try. */ + return mips_fetch_instruction (pc) == 0xe820; /* jr $ra */ + else + return mips_fetch_instruction (pc) == 0x3e00008; /* jr $ra */ +} + + +/* This fencepost looks highly suspicious to me. Removing it also + seems suspicious as it could affect remote debugging across serial + lines. */ + +static CORE_ADDR +heuristic_proc_start (CORE_ADDR pc) +{ + CORE_ADDR start_pc; + CORE_ADDR fence; + int instlen; + int seen_adjsp = 0; + + pc = ADDR_BITS_REMOVE (pc); + start_pc = pc; + fence = start_pc - heuristic_fence_post; + if (start_pc == 0) + return 0; + + if (heuristic_fence_post == UINT_MAX || fence < VM_MIN_ADDRESS) + fence = VM_MIN_ADDRESS; + + instlen = pc_is_mips16 (pc) ? MIPS16_INSTLEN : MIPS_INSTLEN; + + /* search back for previous return */ + for (start_pc -= instlen;; start_pc -= instlen) + if (start_pc < fence) + { + /* It's not clear to me why we reach this point when + stop_soon, but with this test, at least we + don't print out warnings for every child forked (eg, on + decstation). 22apr93 rich@cygnus.com. */ + if (stop_soon == NO_STOP_QUIETLY) + { + static int blurb_printed = 0; + + warning + ("Warning: GDB can't find the start of the function at 0x%s.", + paddr_nz (pc)); + + if (!blurb_printed) + { + /* This actually happens frequently in embedded + development, when you first connect to a board + and your stack pointer and pc are nowhere in + particular. This message needs to give people + in that situation enough information to + determine that it's no big deal. */ + printf_filtered ("\n\ + GDB is unable to find the start of the function at 0x%s\n\ +and thus can't determine the size of that function's stack frame.\n\ +This means that GDB may be unable to access that stack frame, or\n\ +the frames below it.\n\ + This problem is most likely caused by an invalid program counter or\n\ +stack pointer.\n\ + However, if you think GDB should simply search farther back\n\ +from 0x%s for code which looks like the beginning of a\n\ +function, you can increase the range of the search using the `set\n\ +heuristic-fence-post' command.\n", paddr_nz (pc), paddr_nz (pc)); + blurb_printed = 1; + } + } + + return 0; + } + else if (pc_is_mips16 (start_pc)) + { + unsigned short inst; + + /* On MIPS16, any one of the following is likely to be the + start of a function: + entry + addiu sp,-n + daddiu sp,-n + extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */ + inst = mips_fetch_instruction (start_pc); + if (((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */ + || (inst & 0xff80) == 0x6380 /* addiu sp,-n */ + || (inst & 0xff80) == 0xfb80 /* daddiu sp,-n */ + || ((inst & 0xf810) == 0xf010 && seen_adjsp)) /* extend -n */ + break; + else if ((inst & 0xff00) == 0x6300 /* addiu sp */ + || (inst & 0xff00) == 0xfb00) /* daddiu sp */ + seen_adjsp = 1; + else + seen_adjsp = 0; + } + else if (mips_about_to_return (start_pc)) + { + start_pc += 2 * MIPS_INSTLEN; /* skip return, and its delay slot */ + break; + } + + return start_pc; +} + +/* Fetch the immediate value from a MIPS16 instruction. + If the previous instruction was an EXTEND, use it to extend + the upper bits of the immediate value. This is a helper function + for mips16_heuristic_proc_desc. */ + +static int +mips16_get_imm (unsigned short prev_inst, /* previous instruction */ + unsigned short inst, /* current instruction */ + int nbits, /* number of bits in imm field */ + int scale, /* scale factor to be applied to imm */ + int is_signed) /* is the imm field signed? */ +{ + int offset; + + if ((prev_inst & 0xf800) == 0xf000) /* prev instruction was EXTEND? */ + { + offset = ((prev_inst & 0x1f) << 11) | (prev_inst & 0x7e0); + if (offset & 0x8000) /* check for negative extend */ + offset = 0 - (0x10000 - (offset & 0xffff)); + return offset | (inst & 0x1f); + } + else + { + int max_imm = 1 << nbits; + int mask = max_imm - 1; + int sign_bit = max_imm >> 1; + + offset = inst & mask; + if (is_signed && (offset & sign_bit)) + offset = 0 - (max_imm - offset); + return offset * scale; + } +} + + +/* Fill in values in temp_proc_desc based on the MIPS16 instruction + stream from start_pc to limit_pc. */ + +static void +mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, + struct frame_info *next_frame, CORE_ADDR sp) +{ + CORE_ADDR cur_pc; + CORE_ADDR frame_addr = 0; /* Value of $r17, used as frame pointer */ + unsigned short prev_inst = 0; /* saved copy of previous instruction */ + unsigned inst = 0; /* current instruction */ + unsigned entry_inst = 0; /* the entry instruction */ + int reg, offset; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + PROC_FRAME_OFFSET (&temp_proc_desc) = 0; /* size of stack frame */ + PROC_FRAME_ADJUST (&temp_proc_desc) = 0; /* offset of FP from SP */ + + for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS16_INSTLEN) + { + /* Save the previous instruction. If it's an EXTEND, we'll extract + the immediate offset extension from it in mips16_get_imm. */ + prev_inst = inst; + + /* Fetch and decode the instruction. */ + inst = (unsigned short) mips_fetch_instruction (cur_pc); + if ((inst & 0xff00) == 0x6300 /* addiu sp */ + || (inst & 0xff00) == 0xfb00) /* daddiu sp */ + { + offset = mips16_get_imm (prev_inst, inst, 8, 8, 1); + if (offset < 0) /* negative stack adjustment? */ + PROC_FRAME_OFFSET (&temp_proc_desc) -= offset; + else + /* Exit loop if a positive stack adjustment is found, which + usually means that the stack cleanup code in the function + epilogue is reached. */ + break; + } + else if ((inst & 0xf800) == 0xd000) /* sw reg,n($sp) */ + { + offset = mips16_get_imm (prev_inst, inst, 8, 4, 0); + reg = mips16_to_32_reg[(inst & 0x700) >> 8]; + PROC_REG_MASK (&temp_proc_desc) |= (1 << reg); + set_reg_offset (temp_saved_regs, reg, sp + offset); + } + else if ((inst & 0xff00) == 0xf900) /* sd reg,n($sp) */ + { + offset = mips16_get_imm (prev_inst, inst, 5, 8, 0); + reg = mips16_to_32_reg[(inst & 0xe0) >> 5]; + PROC_REG_MASK (&temp_proc_desc) |= (1 << reg); + set_reg_offset (temp_saved_regs, reg, sp + offset); + } + else if ((inst & 0xff00) == 0x6200) /* sw $ra,n($sp) */ + { + offset = mips16_get_imm (prev_inst, inst, 8, 4, 0); + PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM); + set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset); + } + else if ((inst & 0xff00) == 0xfa00) /* sd $ra,n($sp) */ + { + offset = mips16_get_imm (prev_inst, inst, 8, 8, 0); + PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM); + set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset); + } + else if (inst == 0x673d) /* move $s1, $sp */ + { + frame_addr = sp; + PROC_FRAME_REG (&temp_proc_desc) = 17; + } + else if ((inst & 0xff00) == 0x0100) /* addiu $s1,sp,n */ + { + offset = mips16_get_imm (prev_inst, inst, 8, 4, 0); + frame_addr = sp + offset; + PROC_FRAME_REG (&temp_proc_desc) = 17; + PROC_FRAME_ADJUST (&temp_proc_desc) = offset; + } + else if ((inst & 0xFF00) == 0xd900) /* sw reg,offset($s1) */ + { + offset = mips16_get_imm (prev_inst, inst, 5, 4, 0); + reg = mips16_to_32_reg[(inst & 0xe0) >> 5]; + PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; + set_reg_offset (temp_saved_regs, reg, frame_addr + offset); + } + else if ((inst & 0xFF00) == 0x7900) /* sd reg,offset($s1) */ + { + offset = mips16_get_imm (prev_inst, inst, 5, 8, 0); + reg = mips16_to_32_reg[(inst & 0xe0) >> 5]; + PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; + set_reg_offset (temp_saved_regs, reg, frame_addr + offset); + } + else if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */ + entry_inst = inst; /* save for later processing */ + else if ((inst & 0xf800) == 0x1800) /* jal(x) */ + cur_pc += MIPS16_INSTLEN; /* 32-bit instruction */ + } + + /* The entry instruction is typically the first instruction in a function, + and it stores registers at offsets relative to the value of the old SP + (before the prologue). But the value of the sp parameter to this + function is the new SP (after the prologue has been executed). So we + can't calculate those offsets until we've seen the entire prologue, + and can calculate what the old SP must have been. */ + if (entry_inst != 0) + { + int areg_count = (entry_inst >> 8) & 7; + int sreg_count = (entry_inst >> 6) & 3; + + /* The entry instruction always subtracts 32 from the SP. */ + PROC_FRAME_OFFSET (&temp_proc_desc) += 32; + + /* Now we can calculate what the SP must have been at the + start of the function prologue. */ + sp += PROC_FRAME_OFFSET (&temp_proc_desc); + + /* Check if a0-a3 were saved in the caller's argument save area. */ + for (reg = 4, offset = 0; reg < areg_count + 4; reg++) + { + PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; + set_reg_offset (temp_saved_regs, reg, sp + offset); + offset += mips_saved_regsize (tdep); + } + + /* Check if the ra register was pushed on the stack. */ + offset = -4; + if (entry_inst & 0x20) + { + PROC_REG_MASK (&temp_proc_desc) |= 1 << RA_REGNUM; + set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset); + offset -= mips_saved_regsize (tdep); + } + + /* Check if the s0 and s1 registers were pushed on the stack. */ + for (reg = 16; reg < sreg_count + 16; reg++) + { + PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; + set_reg_offset (temp_saved_regs, reg, sp + offset); + offset -= mips_saved_regsize (tdep); + } + } +} + +static void +mips32_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, + struct frame_info *next_frame, CORE_ADDR sp) +{ + CORE_ADDR cur_pc; + CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for frame-pointer */ +restart: + temp_saved_regs = xrealloc (temp_saved_regs, SIZEOF_FRAME_SAVED_REGS); + memset (temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS); + PROC_FRAME_OFFSET (&temp_proc_desc) = 0; + PROC_FRAME_ADJUST (&temp_proc_desc) = 0; /* offset of FP from SP */ + for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSTLEN) + { + unsigned long inst, high_word, low_word; + int reg; + + /* Fetch the instruction. */ + inst = (unsigned long) mips_fetch_instruction (cur_pc); + + /* Save some code by pre-extracting some useful fields. */ + high_word = (inst >> 16) & 0xffff; + low_word = inst & 0xffff; + reg = high_word & 0x1f; + + if (high_word == 0x27bd /* addiu $sp,$sp,-i */ + || high_word == 0x23bd /* addi $sp,$sp,-i */ + || high_word == 0x67bd) /* daddiu $sp,$sp,-i */ + { + if (low_word & 0x8000) /* negative stack adjustment? */ + PROC_FRAME_OFFSET (&temp_proc_desc) += 0x10000 - low_word; + else + /* Exit loop if a positive stack adjustment is found, which + usually means that the stack cleanup code in the function + epilogue is reached. */ + break; + } + else if ((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */ + { + PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; + set_reg_offset (temp_saved_regs, reg, sp + low_word); + } + else if ((high_word & 0xFFE0) == 0xffa0) /* sd reg,offset($sp) */ + { + /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra, + but the register size used is only 32 bits. Make the address + for the saved register point to the lower 32 bits. */ + PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; + set_reg_offset (temp_saved_regs, reg, + sp + low_word + 8 - mips_regsize (current_gdbarch)); + } + else if (high_word == 0x27be) /* addiu $30,$sp,size */ + { + /* Old gcc frame, r30 is virtual frame pointer. */ + if ((long) low_word != PROC_FRAME_OFFSET (&temp_proc_desc)) + frame_addr = sp + low_word; + else if (PROC_FRAME_REG (&temp_proc_desc) == SP_REGNUM) + { + unsigned alloca_adjust; + PROC_FRAME_REG (&temp_proc_desc) = 30; + frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30); + alloca_adjust = (unsigned) (frame_addr - (sp + low_word)); + if (alloca_adjust > 0) + { + /* FP > SP + frame_size. This may be because + * of an alloca or somethings similar. + * Fix sp to "pre-alloca" value, and try again. + */ + sp += alloca_adjust; + goto restart; + } + } + } + /* move $30,$sp. With different versions of gas this will be either + `addu $30,$sp,$zero' or `or $30,$sp,$zero' or `daddu 30,sp,$0'. + Accept any one of these. */ + else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d) + { + /* New gcc frame, virtual frame pointer is at r30 + frame_size. */ + if (PROC_FRAME_REG (&temp_proc_desc) == SP_REGNUM) + { + unsigned alloca_adjust; + PROC_FRAME_REG (&temp_proc_desc) = 30; + frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30); + alloca_adjust = (unsigned) (frame_addr - sp); + if (alloca_adjust > 0) + { + /* FP > SP + frame_size. This may be because + * of an alloca or somethings similar. + * Fix sp to "pre-alloca" value, and try again. + */ + sp += alloca_adjust; + goto restart; + } + } + } + else if ((high_word & 0xFFE0) == 0xafc0) /* sw reg,offset($30) */ + { + PROC_REG_MASK (&temp_proc_desc) |= 1 << reg; + set_reg_offset (temp_saved_regs, reg, frame_addr + low_word); + } + } +} + +static mips_extra_func_info_t +heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc, + struct frame_info *next_frame, int cur_frame) +{ + CORE_ADDR sp; + + if (cur_frame) + sp = read_next_frame_reg (next_frame, NUM_REGS + SP_REGNUM); + else + sp = 0; + + if (start_pc == 0) + return NULL; + memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc)); + temp_saved_regs = xrealloc (temp_saved_regs, SIZEOF_FRAME_SAVED_REGS); + memset (temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS); + PROC_LOW_ADDR (&temp_proc_desc) = start_pc; + PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM; + PROC_PC_REG (&temp_proc_desc) = RA_REGNUM; + + if (start_pc + 200 < limit_pc) + limit_pc = start_pc + 200; + if (pc_is_mips16 (start_pc)) + mips16_heuristic_proc_desc (start_pc, limit_pc, next_frame, sp); + else + mips32_heuristic_proc_desc (start_pc, limit_pc, next_frame, sp); + return &temp_proc_desc; +} + +struct mips_objfile_private +{ + bfd_size_type size; + char *contents; +}; + +/* Global used to communicate between non_heuristic_proc_desc and + compare_pdr_entries within qsort (). */ +static bfd *the_bfd; + +static int +compare_pdr_entries (const void *a, const void *b) +{ + CORE_ADDR lhs = bfd_get_32 (the_bfd, (bfd_byte *) a); + CORE_ADDR rhs = bfd_get_32 (the_bfd, (bfd_byte *) b); + + if (lhs < rhs) + return -1; + else if (lhs == rhs) + return 0; + else + return 1; +} + +static mips_extra_func_info_t +non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr) +{ + CORE_ADDR startaddr; + mips_extra_func_info_t proc_desc; + struct block *b = block_for_pc (pc); + struct symbol *sym; + struct obj_section *sec; + struct mips_objfile_private *priv; + + if (DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0)) + return NULL; + + find_pc_partial_function (pc, NULL, &startaddr, NULL); + if (addrptr) + *addrptr = startaddr; + + priv = NULL; + + sec = find_pc_section (pc); + if (sec != NULL) + { + priv = (struct mips_objfile_private *) objfile_data (sec->objfile, mips_pdr_data); + + /* Search the ".pdr" section generated by GAS. This includes most of + the information normally found in ECOFF PDRs. */ + + the_bfd = sec->objfile->obfd; + if (priv == NULL + && (the_bfd->format == bfd_object + && bfd_get_flavour (the_bfd) == bfd_target_elf_flavour + && elf_elfheader (the_bfd)->e_ident[EI_CLASS] == ELFCLASS64)) + { + /* Right now GAS only outputs the address as a four-byte sequence. + This means that we should not bother with this method on 64-bit + targets (until that is fixed). */ + + priv = obstack_alloc (&sec->objfile->objfile_obstack, + sizeof (struct mips_objfile_private)); + priv->size = 0; + set_objfile_data (sec->objfile, mips_pdr_data, priv); + } + else if (priv == NULL) + { + asection *bfdsec; + + priv = obstack_alloc (&sec->objfile->objfile_obstack, + sizeof (struct mips_objfile_private)); + + bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr"); + if (bfdsec != NULL) + { + priv->size = bfd_section_size (sec->objfile->obfd, bfdsec); + priv->contents = obstack_alloc (&sec->objfile->objfile_obstack, + priv->size); + bfd_get_section_contents (sec->objfile->obfd, bfdsec, + priv->contents, 0, priv->size); + + /* In general, the .pdr section is sorted. However, in the + presence of multiple code sections (and other corner cases) + it can become unsorted. Sort it so that we can use a faster + binary search. */ + qsort (priv->contents, priv->size / 32, 32, + compare_pdr_entries); + } + else + priv->size = 0; + + set_objfile_data (sec->objfile, mips_pdr_data, priv); + } + the_bfd = NULL; + + if (priv->size != 0) + { + int low, mid, high; + char *ptr; + + low = 0; + high = priv->size / 32; + + do + { + CORE_ADDR pdr_pc; + + mid = (low + high) / 2; + + ptr = priv->contents + mid * 32; + pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr); + pdr_pc += ANOFFSET (sec->objfile->section_offsets, + SECT_OFF_TEXT (sec->objfile)); + if (pdr_pc == startaddr) + break; + if (pdr_pc > startaddr) + high = mid; + else + low = mid + 1; + } + while (low != high); + + if (low != high) + { + struct symbol *sym = find_pc_function (pc); + + /* Fill in what we need of the proc_desc. */ + proc_desc = (mips_extra_func_info_t) + obstack_alloc (&sec->objfile->objfile_obstack, + sizeof (struct mips_extra_func_info)); + PROC_LOW_ADDR (proc_desc) = startaddr; + + /* Only used for dummy frames. */ + PROC_HIGH_ADDR (proc_desc) = 0; + + PROC_FRAME_OFFSET (proc_desc) + = bfd_get_32 (sec->objfile->obfd, ptr + 20); + PROC_FRAME_REG (proc_desc) = bfd_get_32 (sec->objfile->obfd, + ptr + 24); + PROC_FRAME_ADJUST (proc_desc) = 0; + PROC_REG_MASK (proc_desc) = bfd_get_32 (sec->objfile->obfd, + ptr + 4); + PROC_FREG_MASK (proc_desc) = bfd_get_32 (sec->objfile->obfd, + ptr + 12); + PROC_REG_OFFSET (proc_desc) = bfd_get_32 (sec->objfile->obfd, + ptr + 8); + PROC_FREG_OFFSET (proc_desc) + = bfd_get_32 (sec->objfile->obfd, ptr + 16); + PROC_PC_REG (proc_desc) = bfd_get_32 (sec->objfile->obfd, + ptr + 28); + proc_desc->pdr.isym = (long) sym; + + return proc_desc; + } + } + } + + if (b == NULL) + return NULL; + + if (startaddr > BLOCK_START (b)) + { + /* This is the "pathological" case referred to in a comment in + print_frame_info. It might be better to move this check into + symbol reading. */ + return NULL; + } + + sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL); + + /* If we never found a PDR for this function in symbol reading, then + examine prologues to find the information. */ + if (sym) + { + proc_desc = (mips_extra_func_info_t) SYMBOL_VALUE (sym); + if (PROC_FRAME_REG (proc_desc) == -1) + return NULL; + else + return proc_desc; + } + else + return NULL; +} + + +static mips_extra_func_info_t +find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame) +{ + mips_extra_func_info_t proc_desc; + CORE_ADDR startaddr = 0; + + proc_desc = non_heuristic_proc_desc (pc, &startaddr); + + if (proc_desc) + { + /* IF this is the topmost frame AND + * (this proc does not have debugging information OR + * the PC is in the procedure prologue) + * THEN create a "heuristic" proc_desc (by analyzing + * the actual code) to replace the "official" proc_desc. + */ + if (next_frame == NULL) + { + struct symtab_and_line val; + struct symbol *proc_symbol = + PROC_DESC_IS_DUMMY (proc_desc) ? 0 : PROC_SYMBOL (proc_desc); + + if (proc_symbol) + { + val = find_pc_line (BLOCK_START + (SYMBOL_BLOCK_VALUE (proc_symbol)), 0); + val.pc = val.end ? val.end : pc; + } + if (!proc_symbol || pc < val.pc) + { + mips_extra_func_info_t found_heuristic = + heuristic_proc_desc (PROC_LOW_ADDR (proc_desc), + pc, next_frame, cur_frame); + if (found_heuristic) + proc_desc = found_heuristic; + } + } + } + else + { + /* Is linked_proc_desc_table really necessary? It only seems to be used + by procedure call dummys. However, the procedures being called ought + to have their own proc_descs, and even if they don't, + heuristic_proc_desc knows how to create them! */ + + struct linked_proc_info *link; + + for (link = linked_proc_desc_table; link; link = link->next) + if (PROC_LOW_ADDR (&link->info) <= pc + && PROC_HIGH_ADDR (&link->info) > pc) + return &link->info; + + if (startaddr == 0) + startaddr = heuristic_proc_start (pc); + + proc_desc = heuristic_proc_desc (startaddr, pc, next_frame, cur_frame); + } + return proc_desc; +} + +/* MIPS stack frames are almost impenetrable. When execution stops, + we basically have to look at symbol information for the function + that we stopped in, which tells us *which* register (if any) is + the base of the frame pointer, and what offset from that register + the frame itself is at. + + This presents a problem when trying to examine a stack in memory + (that isn't executing at the moment), using the "frame" command. We + don't have a PC, nor do we have any registers except SP. + + This routine takes two arguments, SP and PC, and tries to make the + cached frames look as if these two arguments defined a frame on the + cache. This allows the rest of info frame to extract the important + arguments without difficulty. */ + +struct frame_info * +setup_arbitrary_frame (int argc, CORE_ADDR *argv) +{ + if (argc != 2) + error ("MIPS frame specifications require two arguments: sp and pc"); + + return create_new_frame (argv[0], argv[1]); +} + +/* According to the current ABI, should the type be passed in a + floating-point register (assuming that there is space)? When there + is no FPU, FP are not even considered as possibile candidates for + FP registers and, consequently this returns false - forces FP + arguments into integer registers. */ + +static int +fp_register_arg_p (enum type_code typecode, struct type *arg_type) +{ + return ((typecode == TYPE_CODE_FLT + || (MIPS_EABI + && (typecode == TYPE_CODE_STRUCT + || typecode == TYPE_CODE_UNION) + && TYPE_NFIELDS (arg_type) == 1 + && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT)) + && MIPS_FPU_TYPE != MIPS_FPU_NONE); +} + +/* On o32, argument passing in GPRs depends on the alignment of the type being + passed. Return 1 if this type must be aligned to a doubleword boundary. */ + +static int +mips_type_needs_double_align (struct type *type) +{ + enum type_code typecode = TYPE_CODE (type); + + if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8) + return 1; + else if (typecode == TYPE_CODE_STRUCT) + { + if (TYPE_NFIELDS (type) < 1) + return 0; + return mips_type_needs_double_align (TYPE_FIELD_TYPE (type, 0)); + } + else if (typecode == TYPE_CODE_UNION) + { + int i, n; + + n = TYPE_NFIELDS (type); + for (i = 0; i < n; i++) + if (mips_type_needs_double_align (TYPE_FIELD_TYPE (type, i))) + return 1; + return 0; + } + return 0; +} + +/* Adjust the address downward (direction of stack growth) so that it + is correctly aligned for a new stack frame. */ +static CORE_ADDR +mips_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + return align_down (addr, 16); +} + +/* Determine how a return value is stored within the MIPS register + file, given the return type `valtype'. */ + +struct return_value_word +{ + int len; + int reg; + int reg_offset; + int buf_offset; +}; + +static void +return_value_location (struct type *valtype, + struct return_value_word *hi, + struct return_value_word *lo) +{ + int len = TYPE_LENGTH (valtype); + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (TYPE_CODE (valtype) == TYPE_CODE_FLT + && ((MIPS_FPU_TYPE == MIPS_FPU_DOUBLE && (len == 4 || len == 8)) + || (MIPS_FPU_TYPE == MIPS_FPU_SINGLE && len == 4))) + { + if (!FP_REGISTER_DOUBLE && len == 8) + { + /* We need to break a 64bit float in two 32 bit halves and + spread them across a floating-point register pair. */ + lo->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0; + hi->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 0 : 4; + lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && register_size (current_gdbarch, + mips_regnum (current_gdbarch)-> + fp0) == 8) ? 4 : 0); + hi->reg_offset = lo->reg_offset; + lo->reg = mips_regnum (current_gdbarch)->fp0 + 0; + hi->reg = mips_regnum (current_gdbarch)->fp0 + 1; + lo->len = 4; + hi->len = 4; + } + else + { + /* The floating point value fits in a single floating-point + register. */ + lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && register_size (current_gdbarch, + mips_regnum (current_gdbarch)-> + fp0) == 8 + && len == 4) ? 4 : 0); + lo->reg = mips_regnum (current_gdbarch)->fp0; + lo->len = len; + lo->buf_offset = 0; + hi->len = 0; + hi->reg_offset = 0; + hi->buf_offset = 0; + hi->reg = 0; + } + } + else + { + /* Locate a result possibly spread across two registers. */ + int regnum = 2; + lo->reg = regnum + 0; + hi->reg = regnum + 1; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && len < mips_saved_regsize (tdep)) + { + /* "un-left-justify" the value in the low register */ + lo->reg_offset = mips_saved_regsize (tdep) - len; + lo->len = len; + hi->reg_offset = 0; + hi->len = 0; + } + else if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG && len > mips_saved_regsize (tdep) /* odd-size structs */ + && len < mips_saved_regsize (tdep) * 2 + && (TYPE_CODE (valtype) == TYPE_CODE_STRUCT || + TYPE_CODE (valtype) == TYPE_CODE_UNION)) + { + /* "un-left-justify" the value spread across two registers. */ + lo->reg_offset = 2 * mips_saved_regsize (tdep) - len; + lo->len = mips_saved_regsize (tdep) - lo->reg_offset; + hi->reg_offset = 0; + hi->len = len - lo->len; + } + else + { + /* Only perform a partial copy of the second register. */ + lo->reg_offset = 0; + hi->reg_offset = 0; + if (len > mips_saved_regsize (tdep)) + { + lo->len = mips_saved_regsize (tdep); + hi->len = len - mips_saved_regsize (tdep); + } + else + { + lo->len = len; + hi->len = 0; + } + } + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && register_size (current_gdbarch, regnum) == 8 + && mips_saved_regsize (tdep) == 4) + { + /* Account for the fact that only the least-signficant part + of the register is being used */ + lo->reg_offset += 4; + hi->reg_offset += 4; + } + lo->buf_offset = 0; + hi->buf_offset = lo->len; + } +} + +/* Should call_function allocate stack space for a struct return? */ + +static int +mips_eabi_use_struct_convention (int gcc_p, struct type *type) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + return (TYPE_LENGTH (type) > 2 * mips_saved_regsize (tdep)); +} + +/* Should call_function pass struct by reference? + For each architecture, structs are passed either by + value or by reference, depending on their size. */ + +static int +mips_eabi_reg_struct_has_addr (int gcc_p, struct type *type) +{ + enum type_code typecode = TYPE_CODE (check_typedef (type)); + int len = TYPE_LENGTH (check_typedef (type)); + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) + return (len > mips_saved_regsize (tdep)); + + return 0; +} + +static CORE_ADDR +mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + int argreg; + int float_argreg; + int argnum; + int len = 0; + int stack_offset = 0; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + + /* First ensure that the stack and structure return address (if any) + are properly aligned. The stack has to be at least 64-bit + aligned even on 32-bit machines, because doubles must be 64-bit + aligned. For n32 and n64, stack frames need to be 128-bit + aligned, so we round to this widest known alignment. */ + + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); + + /* Now make space on the stack for the args. We allocate more + than necessary for EABI, because the first few arguments are + passed in registers, but that's OK. */ + for (argnum = 0; argnum < nargs; argnum++) + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + mips_stack_argsize (tdep)); + sp -= align_up (len, 16); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_eabi_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); + + /* Initialize the integer and float register pointers. */ + argreg = A0_REGNUM; + float_argreg = mips_fpa0_regnum (current_gdbarch); + + /* The struct_return pointer occupies the first parameter-passing reg. */ + if (struct_return) + { + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_eabi_push_dummy_call: struct_return reg=%d 0x%s\n", + argreg, paddr_nz (struct_addr)); + write_register (argreg++, struct_addr); + } + + /* Now load as many as possible of the first arguments into + registers, and push the rest onto the stack. Loop thru args + from first to last. */ + for (argnum = 0; argnum < nargs; argnum++) + { + char *val; + char valbuf[MAX_REGISTER_SIZE]; + struct value *arg = args[argnum]; + struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + int len = TYPE_LENGTH (arg_type); + enum type_code typecode = TYPE_CODE (arg_type); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_eabi_push_dummy_call: %d len=%d type=%d", + argnum + 1, len, (int) typecode); + + /* The EABI passes structures that do not fit in a register by + reference. */ + if (len > mips_saved_regsize (tdep) + && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) + { + store_unsigned_integer (valbuf, mips_saved_regsize (tdep), + VALUE_ADDRESS (arg)); + typecode = TYPE_CODE_PTR; + len = mips_saved_regsize (tdep); + val = valbuf; + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " push"); + } + else + val = (char *) VALUE_CONTENTS (arg); + + /* 32-bit ABIs always start floating point arguments in an + even-numbered floating point register. Round the FP register + up before the check to see if there are any FP registers + left. Non MIPS_EABI targets also pass the FP in the integer + registers so also round up normal registers. */ + if (!FP_REGISTER_DOUBLE && fp_register_arg_p (typecode, arg_type)) + { + if ((float_argreg & 1)) + float_argreg++; + } + + /* Floating point arguments passed in registers have to be + treated specially. On 32-bit architectures, doubles + are passed in register pairs; the even register gets + the low word, and the odd register gets the high word. + On non-EABI processors, the first two floating point arguments are + also copied to general registers, because MIPS16 functions + don't use float registers for arguments. This duplication of + arguments in general registers can't hurt non-MIPS16 functions + because those registers are normally skipped. */ + /* MIPS_EABI squeezes a struct that contains a single floating + point value into an FP register instead of pushing it onto the + stack. */ + if (fp_register_arg_p (typecode, arg_type) + && float_argreg <= MIPS_LAST_FP_ARG_REGNUM) + { + if (!FP_REGISTER_DOUBLE && len == 8) + { + int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0; + unsigned long regval; + + /* Write the low word of the double to the even register(s). */ + regval = extract_unsigned_integer (val + low_offset, 4); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, 4)); + write_register (float_argreg++, regval); + + /* Write the high word of the double to the odd register(s). */ + regval = extract_unsigned_integer (val + 4 - low_offset, 4); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, 4)); + write_register (float_argreg++, regval); + } + else + { + /* This is a floating point value that fits entirely + in a single register. */ + /* On 32 bit ABI's the float_argreg is further adjusted + above to ensure that it is even register aligned. */ + LONGEST regval = extract_unsigned_integer (val, len); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, len)); + write_register (float_argreg++, regval); + } + } + else + { + /* Copy the argument to general registers or the stack in + register-sized pieces. Large arguments are split between + registers and stack. */ + /* Note: structs whose size is not a multiple of + mips_regsize() are treated specially: Irix cc passes them + in registers where gcc sometimes puts them on the stack. + For maximum compatibility, we will put them in both + places. */ + int odd_sized_struct = ((len > mips_saved_regsize (tdep)) + && (len % mips_saved_regsize (tdep) != 0)); + + /* Note: Floating-point values that didn't fit into an FP + register are only written to memory. */ + while (len > 0) + { + /* Remember if the argument was written to the stack. */ + int stack_used_p = 0; + int partial_len = (len < mips_saved_regsize (tdep) + ? len : mips_saved_regsize (tdep)); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " -- partial=%d", + partial_len); + + /* Write this portion of the argument to the stack. */ + if (argreg > MIPS_LAST_ARG_REGNUM + || odd_sized_struct + || fp_register_arg_p (typecode, arg_type)) + { + /* Should shorter than int integer values be + promoted to int before being stored? */ + int longword_offset = 0; + CORE_ADDR addr; + stack_used_p = 1; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + if (mips_stack_argsize (tdep) == 8 + && (typecode == TYPE_CODE_INT + || typecode == TYPE_CODE_PTR + || typecode == TYPE_CODE_FLT) && len <= 4) + longword_offset = mips_stack_argsize (tdep) - len; + else if ((typecode == TYPE_CODE_STRUCT + || typecode == TYPE_CODE_UNION) + && (TYPE_LENGTH (arg_type) + < mips_stack_argsize (tdep))) + longword_offset = mips_stack_argsize (tdep) - len; + } + + if (mips_debug) + { + fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s", + paddr_nz (stack_offset)); + fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s", + paddr_nz (longword_offset)); + } + + addr = sp + stack_offset + longword_offset; + + if (mips_debug) + { + int i; + fprintf_unfiltered (gdb_stdlog, " @0x%s ", + paddr_nz (addr)); + for (i = 0; i < partial_len; i++) + { + fprintf_unfiltered (gdb_stdlog, "%02x", + val[i] & 0xff); + } + } + write_memory (addr, val, partial_len); + } + + /* Note!!! This is NOT an else clause. Odd sized + structs may go thru BOTH paths. Floating point + arguments will not. */ + /* Write this portion of the argument to a general + purpose register. */ + if (argreg <= MIPS_LAST_ARG_REGNUM + && !fp_register_arg_p (typecode, arg_type)) + { + LONGEST regval = + extract_unsigned_integer (val, partial_len); + + if (mips_debug) + fprintf_filtered (gdb_stdlog, " - reg=%d val=%s", + argreg, + phex (regval, + mips_saved_regsize (tdep))); + write_register (argreg, regval); + argreg++; + } + + len -= partial_len; + val += partial_len; + + /* Compute the the offset into the stack at which we + will copy the next parameter. + + In the new EABI (and the NABI32), the stack_offset + only needs to be adjusted when it has been used. */ + + if (stack_used_p) + stack_offset += align_up (partial_len, + mips_stack_argsize (tdep)); + } + } + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); + } + + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + + /* Return adjusted stack pointer. */ + return sp; +} + +/* Given a return value in `regbuf' with a type `valtype', extract and + copy its value into `valbuf'. */ + +static void +mips_eabi_extract_return_value (struct type *valtype, + char regbuf[], char *valbuf) +{ + struct return_value_word lo; + struct return_value_word hi; + return_value_location (valtype, &hi, &lo); + + memcpy (valbuf + lo.buf_offset, + regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + + lo.reg_offset, lo.len); + + if (hi.len > 0) + memcpy (valbuf + hi.buf_offset, + regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + + hi.reg_offset, hi.len); +} + +/* Given a return value in `valbuf' with a type `valtype', write it's + value into the appropriate register. */ + +static void +mips_eabi_store_return_value (struct type *valtype, char *valbuf) +{ + char raw_buffer[MAX_REGISTER_SIZE]; + struct return_value_word lo; + struct return_value_word hi; + return_value_location (valtype, &hi, &lo); + + memset (raw_buffer, 0, sizeof (raw_buffer)); + memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), + raw_buffer, register_size (current_gdbarch, + lo.reg)); + + if (hi.len > 0) + { + memset (raw_buffer, 0, sizeof (raw_buffer)); + memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), + raw_buffer, + register_size (current_gdbarch, + hi.reg)); + } +} + +/* N32/N64 ABI stuff. */ + +static CORE_ADDR +mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + int argreg; + int float_argreg; + int argnum; + int len = 0; + int stack_offset = 0; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + + /* First ensure that the stack and structure return address (if any) + are properly aligned. The stack has to be at least 64-bit + aligned even on 32-bit machines, because doubles must be 64-bit + aligned. For n32 and n64, stack frames need to be 128-bit + aligned, so we round to this widest known alignment. */ + + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); + + /* Now make space on the stack for the args. */ + for (argnum = 0; argnum < nargs; argnum++) + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + mips_stack_argsize (tdep)); + sp -= align_up (len, 16); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_n32n64_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); + + /* Initialize the integer and float register pointers. */ + argreg = A0_REGNUM; + float_argreg = mips_fpa0_regnum (current_gdbarch); + + /* The struct_return pointer occupies the first parameter-passing reg. */ + if (struct_return) + { + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_n32n64_push_dummy_call: struct_return reg=%d 0x%s\n", + argreg, paddr_nz (struct_addr)); + write_register (argreg++, struct_addr); + } + + /* Now load as many as possible of the first arguments into + registers, and push the rest onto the stack. Loop thru args + from first to last. */ + for (argnum = 0; argnum < nargs; argnum++) + { + char *val; + struct value *arg = args[argnum]; + struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + int len = TYPE_LENGTH (arg_type); + enum type_code typecode = TYPE_CODE (arg_type); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_n32n64_push_dummy_call: %d len=%d type=%d", + argnum + 1, len, (int) typecode); + + val = (char *) VALUE_CONTENTS (arg); + + if (fp_register_arg_p (typecode, arg_type) + && float_argreg <= MIPS_LAST_FP_ARG_REGNUM) + { + /* This is a floating point value that fits entirely + in a single register. */ + /* On 32 bit ABI's the float_argreg is further adjusted + above to ensure that it is even register aligned. */ + LONGEST regval = extract_unsigned_integer (val, len); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, len)); + write_register (float_argreg++, regval); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", + argreg, phex (regval, len)); + write_register (argreg, regval); + argreg += 1; + } + else + { + /* Copy the argument to general registers or the stack in + register-sized pieces. Large arguments are split between + registers and stack. */ + /* Note: structs whose size is not a multiple of + mips_regsize() are treated specially: Irix cc passes them + in registers where gcc sometimes puts them on the stack. + For maximum compatibility, we will put them in both + places. */ + int odd_sized_struct = ((len > mips_saved_regsize (tdep)) + && (len % mips_saved_regsize (tdep) != 0)); + /* Note: Floating-point values that didn't fit into an FP + register are only written to memory. */ + while (len > 0) + { + /* Rememer if the argument was written to the stack. */ + int stack_used_p = 0; + int partial_len = (len < mips_saved_regsize (tdep) + ? len : mips_saved_regsize (tdep)); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " -- partial=%d", + partial_len); + + /* Write this portion of the argument to the stack. */ + if (argreg > MIPS_LAST_ARG_REGNUM + || odd_sized_struct + || fp_register_arg_p (typecode, arg_type)) + { + /* Should shorter than int integer values be + promoted to int before being stored? */ + int longword_offset = 0; + CORE_ADDR addr; + stack_used_p = 1; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + if (mips_stack_argsize (tdep) == 8 + && (typecode == TYPE_CODE_INT + || typecode == TYPE_CODE_PTR + || typecode == TYPE_CODE_FLT) && len <= 4) + longword_offset = mips_stack_argsize (tdep) - len; + } + + if (mips_debug) + { + fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s", + paddr_nz (stack_offset)); + fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s", + paddr_nz (longword_offset)); + } + + addr = sp + stack_offset + longword_offset; + + if (mips_debug) + { + int i; + fprintf_unfiltered (gdb_stdlog, " @0x%s ", + paddr_nz (addr)); + for (i = 0; i < partial_len; i++) + { + fprintf_unfiltered (gdb_stdlog, "%02x", + val[i] & 0xff); + } + } + write_memory (addr, val, partial_len); + } + + /* Note!!! This is NOT an else clause. Odd sized + structs may go thru BOTH paths. Floating point + arguments will not. */ + /* Write this portion of the argument to a general + purpose register. */ + if (argreg <= MIPS_LAST_ARG_REGNUM + && !fp_register_arg_p (typecode, arg_type)) + { + LONGEST regval = + extract_unsigned_integer (val, partial_len); + + /* A non-floating-point argument being passed in a + general register. If a struct or union, and if + the remaining length is smaller than the register + size, we have to adjust the register value on + big endian targets. + + It does not seem to be necessary to do the + same for integral types. + + cagney/2001-07-23: gdb/179: Also, GCC, when + outputting LE O32 with sizeof (struct) < + mips_saved_regsize(), generates a left shift as + part of storing the argument in a register a + register (the left shift isn't generated when + sizeof (struct) >= mips_saved_regsize()). Since + it is quite possible that this is GCC + contradicting the LE/O32 ABI, GDB has not been + adjusted to accommodate this. Either someone + needs to demonstrate that the LE/O32 ABI + specifies such a left shift OR this new ABI gets + identified as such and GDB gets tweaked + accordingly. */ + + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && partial_len < mips_saved_regsize (tdep) + && (typecode == TYPE_CODE_STRUCT || + typecode == TYPE_CODE_UNION)) + regval <<= ((mips_saved_regsize (tdep) - partial_len) * + TARGET_CHAR_BIT); + + if (mips_debug) + fprintf_filtered (gdb_stdlog, " - reg=%d val=%s", + argreg, + phex (regval, + mips_saved_regsize (tdep))); + write_register (argreg, regval); + argreg++; + } + + len -= partial_len; + val += partial_len; + + /* Compute the the offset into the stack at which we + will copy the next parameter. + + In N32 (N64?), the stack_offset only needs to be + adjusted when it has been used. */ + + if (stack_used_p) + stack_offset += align_up (partial_len, + mips_stack_argsize (tdep)); + } + } + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); + } + + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + + /* Return adjusted stack pointer. */ + return sp; +} + +static enum return_value_convention +mips_n32n64_return_value (struct gdbarch *gdbarch, + struct type *type, struct regcache *regcache, + void *readbuf, const void *writebuf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_CODE (type) == TYPE_CODE_ARRAY + || TYPE_LENGTH (type) > 2 * mips_saved_regsize (tdep)) + return RETURN_VALUE_STRUCT_CONVENTION; + else if (TYPE_CODE (type) == TYPE_CODE_FLT + && tdep->mips_fpu_type != MIPS_FPU_NONE) + { + /* A floating-point value belongs in the least significant part + of FP0. */ + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); + mips_xfer_register (regcache, + NUM_REGS + mips_regnum (current_gdbarch)->fp0, + TYPE_LENGTH (type), + TARGET_BYTE_ORDER, readbuf, writebuf, 0); + return RETURN_VALUE_REGISTER_CONVENTION; + } + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT + && TYPE_NFIELDS (type) <= 2 + && TYPE_NFIELDS (type) >= 1 + && ((TYPE_NFIELDS (type) == 1 + && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) + == TYPE_CODE_FLT)) + || (TYPE_NFIELDS (type) == 2 + && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) + == TYPE_CODE_FLT) + && (TYPE_CODE (TYPE_FIELD_TYPE (type, 1)) + == TYPE_CODE_FLT))) + && tdep->mips_fpu_type != MIPS_FPU_NONE) + { + /* A struct that contains one or two floats. Each value is part + in the least significant part of their floating point + register.. */ + int regnum; + int field; + for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0; + field < TYPE_NFIELDS (type); field++, regnum += 2) + { + int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field]) + / TARGET_CHAR_BIT); + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", + offset); + mips_xfer_register (regcache, NUM_REGS + regnum, + TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), + TARGET_BYTE_ORDER, readbuf, writebuf, offset); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION) + { + /* A structure or union. Extract the left justified value, + regardless of the byte order. I.e. DO NOT USE + mips_xfer_lower. */ + int offset; + int regnum; + for (offset = 0, regnum = V0_REGNUM; + offset < TYPE_LENGTH (type); + offset += register_size (current_gdbarch, regnum), regnum++) + { + int xfer = register_size (current_gdbarch, regnum); + if (offset + xfer > TYPE_LENGTH (type)) + xfer = TYPE_LENGTH (type) - offset; + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n", + offset, xfer, regnum); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + else + { + /* A scalar extract each part but least-significant-byte + justified. */ + int offset; + int regnum; + for (offset = 0, regnum = V0_REGNUM; + offset < TYPE_LENGTH (type); + offset += register_size (current_gdbarch, regnum), regnum++) + { + int xfer = register_size (current_gdbarch, regnum); + if (offset + xfer > TYPE_LENGTH (type)) + xfer = TYPE_LENGTH (type) - offset; + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n", + offset, xfer, regnum); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + TARGET_BYTE_ORDER, readbuf, writebuf, offset); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } +} + +/* O32 ABI stuff. */ + +static CORE_ADDR +mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + int argreg; + int float_argreg; + int argnum; + int len = 0; + int stack_offset = 0; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + + /* First ensure that the stack and structure return address (if any) + are properly aligned. The stack has to be at least 64-bit + aligned even on 32-bit machines, because doubles must be 64-bit + aligned. For n32 and n64, stack frames need to be 128-bit + aligned, so we round to this widest known alignment. */ + + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); + + /* Now make space on the stack for the args. */ + for (argnum = 0; argnum < nargs; argnum++) + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + mips_stack_argsize (tdep)); + sp -= align_up (len, 16); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_o32_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); + + /* Initialize the integer and float register pointers. */ + argreg = A0_REGNUM; + float_argreg = mips_fpa0_regnum (current_gdbarch); + + /* The struct_return pointer occupies the first parameter-passing reg. */ + if (struct_return) + { + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_o32_push_dummy_call: struct_return reg=%d 0x%s\n", + argreg, paddr_nz (struct_addr)); + write_register (argreg++, struct_addr); + stack_offset += mips_stack_argsize (tdep); + } + + /* Now load as many as possible of the first arguments into + registers, and push the rest onto the stack. Loop thru args + from first to last. */ + for (argnum = 0; argnum < nargs; argnum++) + { + char *val; + struct value *arg = args[argnum]; + struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + int len = TYPE_LENGTH (arg_type); + enum type_code typecode = TYPE_CODE (arg_type); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_o32_push_dummy_call: %d len=%d type=%d", + argnum + 1, len, (int) typecode); + + val = (char *) VALUE_CONTENTS (arg); + + /* 32-bit ABIs always start floating point arguments in an + even-numbered floating point register. Round the FP register + up before the check to see if there are any FP registers + left. O32/O64 targets also pass the FP in the integer + registers so also round up normal registers. */ + if (!FP_REGISTER_DOUBLE && fp_register_arg_p (typecode, arg_type)) + { + if ((float_argreg & 1)) + float_argreg++; + } + + /* Floating point arguments passed in registers have to be + treated specially. On 32-bit architectures, doubles + are passed in register pairs; the even register gets + the low word, and the odd register gets the high word. + On O32/O64, the first two floating point arguments are + also copied to general registers, because MIPS16 functions + don't use float registers for arguments. This duplication of + arguments in general registers can't hurt non-MIPS16 functions + because those registers are normally skipped. */ + + if (fp_register_arg_p (typecode, arg_type) + && float_argreg <= MIPS_LAST_FP_ARG_REGNUM) + { + if (!FP_REGISTER_DOUBLE && len == 8) + { + int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0; + unsigned long regval; + + /* Write the low word of the double to the even register(s). */ + regval = extract_unsigned_integer (val + low_offset, 4); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, 4)); + write_register (float_argreg++, regval); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", + argreg, phex (regval, 4)); + write_register (argreg++, regval); + + /* Write the high word of the double to the odd register(s). */ + regval = extract_unsigned_integer (val + 4 - low_offset, 4); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, 4)); + write_register (float_argreg++, regval); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", + argreg, phex (regval, 4)); + write_register (argreg++, regval); + } + else + { + /* This is a floating point value that fits entirely + in a single register. */ + /* On 32 bit ABI's the float_argreg is further adjusted + above to ensure that it is even register aligned. */ + LONGEST regval = extract_unsigned_integer (val, len); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, len)); + write_register (float_argreg++, regval); + /* CAGNEY: 32 bit MIPS ABI's always reserve two FP + registers for each argument. The below is (my + guess) to ensure that the corresponding integer + register has reserved the same space. */ + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", + argreg, phex (regval, len)); + write_register (argreg, regval); + argreg += FP_REGISTER_DOUBLE ? 1 : 2; + } + /* Reserve space for the FP register. */ + stack_offset += align_up (len, mips_stack_argsize (tdep)); + } + else + { + /* Copy the argument to general registers or the stack in + register-sized pieces. Large arguments are split between + registers and stack. */ + /* Note: structs whose size is not a multiple of + mips_regsize() are treated specially: Irix cc passes them + in registers where gcc sometimes puts them on the stack. + For maximum compatibility, we will put them in both + places. */ + int odd_sized_struct = ((len > mips_saved_regsize (tdep)) + && (len % mips_saved_regsize (tdep) != 0)); + /* Structures should be aligned to eight bytes (even arg registers) + on MIPS_ABI_O32, if their first member has double precision. */ + if (mips_saved_regsize (tdep) < 8 + && mips_type_needs_double_align (arg_type)) + { + if ((argreg & 1)) + argreg++; + } + /* Note: Floating-point values that didn't fit into an FP + register are only written to memory. */ + while (len > 0) + { + /* Remember if the argument was written to the stack. */ + int stack_used_p = 0; + int partial_len = (len < mips_saved_regsize (tdep) + ? len : mips_saved_regsize (tdep)); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " -- partial=%d", + partial_len); + + /* Write this portion of the argument to the stack. */ + if (argreg > MIPS_LAST_ARG_REGNUM + || odd_sized_struct + || fp_register_arg_p (typecode, arg_type)) + { + /* Should shorter than int integer values be + promoted to int before being stored? */ + int longword_offset = 0; + CORE_ADDR addr; + stack_used_p = 1; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + if (mips_stack_argsize (tdep) == 8 + && (typecode == TYPE_CODE_INT + || typecode == TYPE_CODE_PTR + || typecode == TYPE_CODE_FLT) && len <= 4) + longword_offset = mips_stack_argsize (tdep) - len; + } + + if (mips_debug) + { + fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s", + paddr_nz (stack_offset)); + fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s", + paddr_nz (longword_offset)); + } + + addr = sp + stack_offset + longword_offset; + + if (mips_debug) + { + int i; + fprintf_unfiltered (gdb_stdlog, " @0x%s ", + paddr_nz (addr)); + for (i = 0; i < partial_len; i++) + { + fprintf_unfiltered (gdb_stdlog, "%02x", + val[i] & 0xff); + } + } + write_memory (addr, val, partial_len); + } + + /* Note!!! This is NOT an else clause. Odd sized + structs may go thru BOTH paths. Floating point + arguments will not. */ + /* Write this portion of the argument to a general + purpose register. */ + if (argreg <= MIPS_LAST_ARG_REGNUM + && !fp_register_arg_p (typecode, arg_type)) + { + LONGEST regval = extract_signed_integer (val, partial_len); + /* Value may need to be sign extended, because + mips_regsize() != mips_saved_regsize(). */ + + /* A non-floating-point argument being passed in a + general register. If a struct or union, and if + the remaining length is smaller than the register + size, we have to adjust the register value on + big endian targets. + + It does not seem to be necessary to do the + same for integral types. + + Also don't do this adjustment on O64 binaries. + + cagney/2001-07-23: gdb/179: Also, GCC, when + outputting LE O32 with sizeof (struct) < + mips_saved_regsize(), generates a left shift as + part of storing the argument in a register a + register (the left shift isn't generated when + sizeof (struct) >= mips_saved_regsize()). Since + it is quite possible that this is GCC + contradicting the LE/O32 ABI, GDB has not been + adjusted to accommodate this. Either someone + needs to demonstrate that the LE/O32 ABI + specifies such a left shift OR this new ABI gets + identified as such and GDB gets tweaked + accordingly. */ + + if (mips_saved_regsize (tdep) < 8 + && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && partial_len < mips_saved_regsize (tdep) + && (typecode == TYPE_CODE_STRUCT || + typecode == TYPE_CODE_UNION)) + regval <<= ((mips_saved_regsize (tdep) - partial_len) * + TARGET_CHAR_BIT); + + if (mips_debug) + fprintf_filtered (gdb_stdlog, " - reg=%d val=%s", + argreg, + phex (regval, + mips_saved_regsize (tdep))); + write_register (argreg, regval); + argreg++; + + /* Prevent subsequent floating point arguments from + being passed in floating point registers. */ + float_argreg = MIPS_LAST_FP_ARG_REGNUM + 1; + } + + len -= partial_len; + val += partial_len; + + /* Compute the the offset into the stack at which we + will copy the next parameter. + + In older ABIs, the caller reserved space for + registers that contained arguments. This was loosely + refered to as their "home". Consequently, space is + always allocated. */ + + stack_offset += align_up (partial_len, + mips_stack_argsize (tdep)); + } + } + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); + } + + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + + /* Return adjusted stack pointer. */ + return sp; +} + +static enum return_value_convention +mips_o32_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, + void *readbuf, const void *writebuf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_CODE (type) == TYPE_CODE_ARRAY) + return RETURN_VALUE_STRUCT_CONVENTION; + else if (TYPE_CODE (type) == TYPE_CODE_FLT + && TYPE_LENGTH (type) == 4 && tdep->mips_fpu_type != MIPS_FPU_NONE) + { + /* A single-precision floating-point value. It fits in the + least significant part of FP0. */ + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n"); + mips_xfer_register (regcache, + NUM_REGS + mips_regnum (current_gdbarch)->fp0, + TYPE_LENGTH (type), + TARGET_BYTE_ORDER, readbuf, writebuf, 0); + return RETURN_VALUE_REGISTER_CONVENTION; + } + else if (TYPE_CODE (type) == TYPE_CODE_FLT + && TYPE_LENGTH (type) == 8 && tdep->mips_fpu_type != MIPS_FPU_NONE) + { + /* A double-precision floating-point value. The most + significant part goes in FP1, and the least significant in + FP0. */ + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n"); + switch (TARGET_BYTE_ORDER) + { + case BFD_ENDIAN_LITTLE: + mips_xfer_register (regcache, + NUM_REGS + mips_regnum (current_gdbarch)->fp0 + + 0, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0); + mips_xfer_register (regcache, + NUM_REGS + mips_regnum (current_gdbarch)->fp0 + + 1, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4); + break; + case BFD_ENDIAN_BIG: + mips_xfer_register (regcache, + NUM_REGS + mips_regnum (current_gdbarch)->fp0 + + 1, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0); + mips_xfer_register (regcache, + NUM_REGS + mips_regnum (current_gdbarch)->fp0 + + 0, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4); + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } +#if 0 + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT + && TYPE_NFIELDS (type) <= 2 + && TYPE_NFIELDS (type) >= 1 + && ((TYPE_NFIELDS (type) == 1 + && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) + == TYPE_CODE_FLT)) + || (TYPE_NFIELDS (type) == 2 + && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) + == TYPE_CODE_FLT) + && (TYPE_CODE (TYPE_FIELD_TYPE (type, 1)) + == TYPE_CODE_FLT))) + && tdep->mips_fpu_type != MIPS_FPU_NONE) + { + /* A struct that contains one or two floats. Each value is part + in the least significant part of their floating point + register.. */ + bfd_byte reg[MAX_REGISTER_SIZE]; + int regnum; + int field; + for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0; + field < TYPE_NFIELDS (type); field++, regnum += 2) + { + int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field]) + / TARGET_CHAR_BIT); + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", + offset); + mips_xfer_register (regcache, NUM_REGS + regnum, + TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)), + TARGET_BYTE_ORDER, readbuf, writebuf, offset); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } +#endif +#if 0 + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION) + { + /* A structure or union. Extract the left justified value, + regardless of the byte order. I.e. DO NOT USE + mips_xfer_lower. */ + int offset; + int regnum; + for (offset = 0, regnum = V0_REGNUM; + offset < TYPE_LENGTH (type); + offset += register_size (current_gdbarch, regnum), regnum++) + { + int xfer = register_size (current_gdbarch, regnum); + if (offset + xfer > TYPE_LENGTH (type)) + xfer = TYPE_LENGTH (type) - offset; + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n", + offset, xfer, regnum); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } +#endif + else + { + /* A scalar extract each part but least-significant-byte + justified. o32 thinks registers are 4 byte, regardless of + the ISA. mips_stack_argsize controls this. */ + int offset; + int regnum; + for (offset = 0, regnum = V0_REGNUM; + offset < TYPE_LENGTH (type); + offset += mips_stack_argsize (tdep), regnum++) + { + int xfer = mips_stack_argsize (tdep); + if (offset + xfer > TYPE_LENGTH (type)) + xfer = TYPE_LENGTH (type) - offset; + if (mips_debug) + fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n", + offset, xfer, regnum); + mips_xfer_register (regcache, NUM_REGS + regnum, xfer, + TARGET_BYTE_ORDER, readbuf, writebuf, offset); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } +} + +/* O64 ABI. This is a hacked up kind of 64-bit version of the o32 + ABI. */ + +static CORE_ADDR +mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, + struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + int argreg; + int float_argreg; + int argnum; + int len = 0; + int stack_offset = 0; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* For shared libraries, "t9" needs to point at the function + address. */ + regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr); + + /* Set the return address register to point to the entry point of + the program, where a breakpoint lies in wait. */ + regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr); + + /* First ensure that the stack and structure return address (if any) + are properly aligned. The stack has to be at least 64-bit + aligned even on 32-bit machines, because doubles must be 64-bit + aligned. For n32 and n64, stack frames need to be 128-bit + aligned, so we round to this widest known alignment. */ + + sp = align_down (sp, 16); + struct_addr = align_down (struct_addr, 16); + + /* Now make space on the stack for the args. */ + for (argnum = 0; argnum < nargs; argnum++) + len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), + mips_stack_argsize (tdep)); + sp -= align_up (len, 16); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_o64_push_dummy_call: sp=0x%s allocated %ld\n", + paddr_nz (sp), (long) align_up (len, 16)); + + /* Initialize the integer and float register pointers. */ + argreg = A0_REGNUM; + float_argreg = mips_fpa0_regnum (current_gdbarch); + + /* The struct_return pointer occupies the first parameter-passing reg. */ + if (struct_return) + { + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_o64_push_dummy_call: struct_return reg=%d 0x%s\n", + argreg, paddr_nz (struct_addr)); + write_register (argreg++, struct_addr); + stack_offset += mips_stack_argsize (tdep); + } + + /* Now load as many as possible of the first arguments into + registers, and push the rest onto the stack. Loop thru args + from first to last. */ + for (argnum = 0; argnum < nargs; argnum++) + { + char *val; + struct value *arg = args[argnum]; + struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + int len = TYPE_LENGTH (arg_type); + enum type_code typecode = TYPE_CODE (arg_type); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_o64_push_dummy_call: %d len=%d type=%d", + argnum + 1, len, (int) typecode); + + val = (char *) VALUE_CONTENTS (arg); + + /* 32-bit ABIs always start floating point arguments in an + even-numbered floating point register. Round the FP register + up before the check to see if there are any FP registers + left. O32/O64 targets also pass the FP in the integer + registers so also round up normal registers. */ + if (!FP_REGISTER_DOUBLE && fp_register_arg_p (typecode, arg_type)) + { + if ((float_argreg & 1)) + float_argreg++; + } + + /* Floating point arguments passed in registers have to be + treated specially. On 32-bit architectures, doubles + are passed in register pairs; the even register gets + the low word, and the odd register gets the high word. + On O32/O64, the first two floating point arguments are + also copied to general registers, because MIPS16 functions + don't use float registers for arguments. This duplication of + arguments in general registers can't hurt non-MIPS16 functions + because those registers are normally skipped. */ + + if (fp_register_arg_p (typecode, arg_type) + && float_argreg <= MIPS_LAST_FP_ARG_REGNUM) + { + if (!FP_REGISTER_DOUBLE && len == 8) + { + int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0; + unsigned long regval; + + /* Write the low word of the double to the even register(s). */ + regval = extract_unsigned_integer (val + low_offset, 4); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, 4)); + write_register (float_argreg++, regval); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", + argreg, phex (regval, 4)); + write_register (argreg++, regval); + + /* Write the high word of the double to the odd register(s). */ + regval = extract_unsigned_integer (val + 4 - low_offset, 4); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, 4)); + write_register (float_argreg++, regval); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", + argreg, phex (regval, 4)); + write_register (argreg++, regval); + } + else + { + /* This is a floating point value that fits entirely + in a single register. */ + /* On 32 bit ABI's the float_argreg is further adjusted + above to ensure that it is even register aligned. */ + LONGEST regval = extract_unsigned_integer (val, len); + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", + float_argreg, phex (regval, len)); + write_register (float_argreg++, regval); + /* CAGNEY: 32 bit MIPS ABI's always reserve two FP + registers for each argument. The below is (my + guess) to ensure that the corresponding integer + register has reserved the same space. */ + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s", + argreg, phex (regval, len)); + write_register (argreg, regval); + argreg += FP_REGISTER_DOUBLE ? 1 : 2; + } + /* Reserve space for the FP register. */ + stack_offset += align_up (len, mips_stack_argsize (tdep)); + } + else + { + /* Copy the argument to general registers or the stack in + register-sized pieces. Large arguments are split between + registers and stack. */ + /* Note: structs whose size is not a multiple of + mips_regsize() are treated specially: Irix cc passes them + in registers where gcc sometimes puts them on the stack. + For maximum compatibility, we will put them in both + places. */ + int odd_sized_struct = ((len > mips_saved_regsize (tdep)) + && (len % mips_saved_regsize (tdep) != 0)); + /* Structures should be aligned to eight bytes (even arg registers) + on MIPS_ABI_O32, if their first member has double precision. */ + if (mips_saved_regsize (tdep) < 8 + && mips_type_needs_double_align (arg_type)) + { + if ((argreg & 1)) + argreg++; + } + /* Note: Floating-point values that didn't fit into an FP + register are only written to memory. */ + while (len > 0) + { + /* Remember if the argument was written to the stack. */ + int stack_used_p = 0; + int partial_len = (len < mips_saved_regsize (tdep) + ? len : mips_saved_regsize (tdep)); + + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, " -- partial=%d", + partial_len); + + /* Write this portion of the argument to the stack. */ + if (argreg > MIPS_LAST_ARG_REGNUM + || odd_sized_struct + || fp_register_arg_p (typecode, arg_type)) + { + /* Should shorter than int integer values be + promoted to int before being stored? */ + int longword_offset = 0; + CORE_ADDR addr; + stack_used_p = 1; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + if (mips_stack_argsize (tdep) == 8 + && (typecode == TYPE_CODE_INT + || typecode == TYPE_CODE_PTR + || typecode == TYPE_CODE_FLT) && len <= 4) + longword_offset = mips_stack_argsize (tdep) - len; + } + + if (mips_debug) + { + fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s", + paddr_nz (stack_offset)); + fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s", + paddr_nz (longword_offset)); + } + + addr = sp + stack_offset + longword_offset; + + if (mips_debug) + { + int i; + fprintf_unfiltered (gdb_stdlog, " @0x%s ", + paddr_nz (addr)); + for (i = 0; i < partial_len; i++) + { + fprintf_unfiltered (gdb_stdlog, "%02x", + val[i] & 0xff); + } + } + write_memory (addr, val, partial_len); + } + + /* Note!!! This is NOT an else clause. Odd sized + structs may go thru BOTH paths. Floating point + arguments will not. */ + /* Write this portion of the argument to a general + purpose register. */ + if (argreg <= MIPS_LAST_ARG_REGNUM + && !fp_register_arg_p (typecode, arg_type)) + { + LONGEST regval = extract_signed_integer (val, partial_len); + /* Value may need to be sign extended, because + mips_regsize() != mips_saved_regsize(). */ + + /* A non-floating-point argument being passed in a + general register. If a struct or union, and if + the remaining length is smaller than the register + size, we have to adjust the register value on + big endian targets. + + It does not seem to be necessary to do the + same for integral types. + + Also don't do this adjustment on O64 binaries. + + cagney/2001-07-23: gdb/179: Also, GCC, when + outputting LE O32 with sizeof (struct) < + mips_saved_regsize(), generates a left shift as + part of storing the argument in a register a + register (the left shift isn't generated when + sizeof (struct) >= mips_saved_regsize()). Since + it is quite possible that this is GCC + contradicting the LE/O32 ABI, GDB has not been + adjusted to accommodate this. Either someone + needs to demonstrate that the LE/O32 ABI + specifies such a left shift OR this new ABI gets + identified as such and GDB gets tweaked + accordingly. */ + + if (mips_saved_regsize (tdep) < 8 + && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && partial_len < mips_saved_regsize (tdep) + && (typecode == TYPE_CODE_STRUCT || + typecode == TYPE_CODE_UNION)) + regval <<= ((mips_saved_regsize (tdep) - partial_len) * + TARGET_CHAR_BIT); + + if (mips_debug) + fprintf_filtered (gdb_stdlog, " - reg=%d val=%s", + argreg, + phex (regval, + mips_saved_regsize (tdep))); + write_register (argreg, regval); + argreg++; + + /* Prevent subsequent floating point arguments from + being passed in floating point registers. */ + float_argreg = MIPS_LAST_FP_ARG_REGNUM + 1; + } + + len -= partial_len; + val += partial_len; + + /* Compute the the offset into the stack at which we + will copy the next parameter. + + In older ABIs, the caller reserved space for + registers that contained arguments. This was loosely + refered to as their "home". Consequently, space is + always allocated. */ + + stack_offset += align_up (partial_len, + mips_stack_argsize (tdep)); + } + } + if (mips_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); + } + + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + + /* Return adjusted stack pointer. */ + return sp; +} + +static void +mips_o64_extract_return_value (struct type *valtype, + char regbuf[], char *valbuf) +{ + struct return_value_word lo; + struct return_value_word hi; + return_value_location (valtype, &hi, &lo); + + memcpy (valbuf + lo.buf_offset, + regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + + lo.reg_offset, lo.len); + + if (hi.len > 0) + memcpy (valbuf + hi.buf_offset, + regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + + hi.reg_offset, hi.len); +} + +static void +mips_o64_store_return_value (struct type *valtype, char *valbuf) +{ + char raw_buffer[MAX_REGISTER_SIZE]; + struct return_value_word lo; + struct return_value_word hi; + return_value_location (valtype, &hi, &lo); + + memset (raw_buffer, 0, sizeof (raw_buffer)); + memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), + raw_buffer, register_size (current_gdbarch, + lo.reg)); + + if (hi.len > 0) + { + memset (raw_buffer, 0, sizeof (raw_buffer)); + memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), + raw_buffer, + register_size (current_gdbarch, + hi.reg)); + } +} + +/* Floating point register management. + + Background: MIPS1 & 2 fp registers are 32 bits wide. To support + 64bit operations, these early MIPS cpus treat fp register pairs + (f0,f1) as a single register (d0). Later MIPS cpu's have 64 bit fp + registers and offer a compatibility mode that emulates the MIPS2 fp + model. When operating in MIPS2 fp compat mode, later cpu's split + double precision floats into two 32-bit chunks and store them in + consecutive fp regs. To display 64-bit floats stored in this + fashion, we have to combine 32 bits from f0 and 32 bits from f1. + Throw in user-configurable endianness and you have a real mess. + + The way this works is: + - If we are in 32-bit mode or on a 32-bit processor, then a 64-bit + double-precision value will be split across two logical registers. + The lower-numbered logical register will hold the low-order bits, + regardless of the processor's endianness. + - If we are on a 64-bit processor, and we are looking for a + single-precision value, it will be in the low ordered bits + of a 64-bit GPR (after mfc1, for example) or a 64-bit register + save slot in memory. + - If we are in 64-bit mode, everything is straightforward. + + Note that this code only deals with "live" registers at the top of the + stack. We will attempt to deal with saved registers later, when + the raw/cooked register interface is in place. (We need a general + interface that can deal with dynamic saved register sizes -- fp + regs could be 32 bits wide in one frame and 64 on the frame above + and below). */ + +static struct type * +mips_float_register_type (void) +{ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + return builtin_type_ieee_single_big; + else + return builtin_type_ieee_single_little; +} + +static struct type * +mips_double_register_type (void) +{ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + return builtin_type_ieee_double_big; + else + return builtin_type_ieee_double_little; +} + +/* Copy a 32-bit single-precision value from the current frame + into rare_buffer. */ + +static void +mips_read_fp_register_single (struct frame_info *frame, int regno, + char *rare_buffer) +{ + int raw_size = register_size (current_gdbarch, regno); + char *raw_buffer = alloca (raw_size); + + if (!frame_register_read (frame, regno, raw_buffer)) + error ("can't read register %d (%s)", regno, REGISTER_NAME (regno)); + if (raw_size == 8) + { + /* We have a 64-bit value for this register. Find the low-order + 32 bits. */ + int offset; + + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + offset = 4; + else + offset = 0; + + memcpy (rare_buffer, raw_buffer + offset, 4); + } + else + { + memcpy (rare_buffer, raw_buffer, 4); + } +} + +/* Copy a 64-bit double-precision value from the current frame into + rare_buffer. This may include getting half of it from the next + register. */ + +static void +mips_read_fp_register_double (struct frame_info *frame, int regno, + char *rare_buffer) +{ + int raw_size = register_size (current_gdbarch, regno); + + if (raw_size == 8 && !mips2_fp_compat ()) + { + /* We have a 64-bit value for this register, and we should use + all 64 bits. */ + if (!frame_register_read (frame, regno, rare_buffer)) + error ("can't read register %d (%s)", regno, REGISTER_NAME (regno)); + } + else + { + if ((regno - mips_regnum (current_gdbarch)->fp0) & 1) + internal_error (__FILE__, __LINE__, + "mips_read_fp_register_double: bad access to " + "odd-numbered FP register"); + + /* mips_read_fp_register_single will find the correct 32 bits from + each register. */ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + mips_read_fp_register_single (frame, regno, rare_buffer + 4); + mips_read_fp_register_single (frame, regno + 1, rare_buffer); + } + else + { + mips_read_fp_register_single (frame, regno, rare_buffer); + mips_read_fp_register_single (frame, regno + 1, rare_buffer + 4); + } + } +} + +static void +mips_print_fp_register (struct ui_file *file, struct frame_info *frame, + int regnum) +{ /* do values for FP (float) regs */ + char *raw_buffer; + double doub, flt1; /* doubles extracted from raw hex data */ + int inv1, inv2; + + raw_buffer = + (char *) alloca (2 * + register_size (current_gdbarch, + mips_regnum (current_gdbarch)->fp0)); + + fprintf_filtered (file, "%s:", REGISTER_NAME (regnum)); + fprintf_filtered (file, "%*s", 4 - (int) strlen (REGISTER_NAME (regnum)), + ""); + + if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat ()) + { + /* 4-byte registers: Print hex and floating. Also print even + numbered registers as doubles. */ + mips_read_fp_register_single (frame, regnum, raw_buffer); + flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1); + + print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w', + file); + + fprintf_filtered (file, " flt: "); + if (inv1) + fprintf_filtered (file, " "); + else + fprintf_filtered (file, "%-17.9g", flt1); + + if (regnum % 2 == 0) + { + mips_read_fp_register_double (frame, regnum, raw_buffer); + doub = unpack_double (mips_double_register_type (), raw_buffer, + &inv2); + + fprintf_filtered (file, " dbl: "); + if (inv2) + fprintf_filtered (file, ""); + else + fprintf_filtered (file, "%-24.17g", doub); + } + } + else + { + /* Eight byte registers: print each one as hex, float and double. */ + mips_read_fp_register_single (frame, regnum, raw_buffer); + flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1); + + mips_read_fp_register_double (frame, regnum, raw_buffer); + doub = unpack_double (mips_double_register_type (), raw_buffer, &inv2); + + + print_scalar_formatted (raw_buffer, builtin_type_uint64, 'x', 'g', + file); + + fprintf_filtered (file, " flt: "); + if (inv1) + fprintf_filtered (file, ""); + else + fprintf_filtered (file, "%-17.9g", flt1); + + fprintf_filtered (file, " dbl: "); + if (inv2) + fprintf_filtered (file, ""); + else + fprintf_filtered (file, "%-24.17g", doub); + } +} + +static void +mips_print_register (struct ui_file *file, struct frame_info *frame, + int regnum, int all) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + char raw_buffer[MAX_REGISTER_SIZE]; + int offset; + + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT) + { + mips_print_fp_register (file, frame, regnum); + return; + } + + /* Get the data in raw format. */ + if (!frame_register_read (frame, regnum, raw_buffer)) + { + fprintf_filtered (file, "%s: [Invalid]", REGISTER_NAME (regnum)); + return; + } + + fputs_filtered (REGISTER_NAME (regnum), file); + + /* The problem with printing numeric register names (r26, etc.) is that + the user can't use them on input. Probably the best solution is to + fix it so that either the numeric or the funky (a2, etc.) names + are accepted on input. */ + if (regnum < MIPS_NUMREGS) + fprintf_filtered (file, "(r%d): ", regnum); + else + fprintf_filtered (file, ": "); + + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + offset = + register_size (current_gdbarch, + regnum) - register_size (current_gdbarch, regnum); + else + offset = 0; + + print_scalar_formatted (raw_buffer + offset, + gdbarch_register_type (gdbarch, regnum), 'x', 0, + file); +} + +/* Replacement for generic do_registers_info. + Print regs in pretty columns. */ + +static int +print_fp_register_row (struct ui_file *file, struct frame_info *frame, + int regnum) +{ + fprintf_filtered (file, " "); + mips_print_fp_register (file, frame, regnum); + fprintf_filtered (file, "\n"); + return regnum + 1; +} + + +/* Print a row's worth of GP (int) registers, with name labels above */ + +static int +print_gp_register_row (struct ui_file *file, struct frame_info *frame, + int start_regnum) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + /* do values for GP (int) regs */ + char raw_buffer[MAX_REGISTER_SIZE]; + int ncols = (mips_regsize (gdbarch) == 8 ? 4 : 8); /* display cols per row */ + int col, byte; + int regnum; + + /* For GP registers, we print a separate row of names above the vals */ + fprintf_filtered (file, " "); + for (col = 0, regnum = start_regnum; + col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (*REGISTER_NAME (regnum) == '\0') + continue; /* unused register */ + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == + TYPE_CODE_FLT) + break; /* end the row: reached FP register */ + fprintf_filtered (file, + mips_regsize (current_gdbarch) == 8 ? "%17s" : "%9s", + REGISTER_NAME (regnum)); + col++; + } + /* print the R0 to R31 names */ + if ((start_regnum % NUM_REGS) < MIPS_NUMREGS) + fprintf_filtered (file, "\n R%-4d", start_regnum % NUM_REGS); + else + fprintf_filtered (file, "\n "); + + /* now print the values in hex, 4 or 8 to the row */ + for (col = 0, regnum = start_regnum; + col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (*REGISTER_NAME (regnum) == '\0') + continue; /* unused register */ + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == + TYPE_CODE_FLT) + break; /* end row: reached FP register */ + /* OK: get the data in raw format. */ + if (!frame_register_read (frame, regnum, raw_buffer)) + error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum)); + /* pad small registers */ + for (byte = 0; + byte < (mips_regsize (current_gdbarch) + - register_size (current_gdbarch, regnum)); byte++) + printf_filtered (" "); + /* Now print the register value in hex, endian order. */ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + for (byte = + register_size (current_gdbarch, + regnum) - register_size (current_gdbarch, regnum); + byte < register_size (current_gdbarch, regnum); byte++) + fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]); + else + for (byte = register_size (current_gdbarch, regnum) - 1; + byte >= 0; byte--) + fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]); + fprintf_filtered (file, " "); + col++; + } + if (col > 0) /* ie. if we actually printed anything... */ + fprintf_filtered (file, "\n"); + + return regnum; +} + +/* MIPS_DO_REGISTERS_INFO(): called by "info register" command */ + +static void +mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, int regnum, int all) +{ + if (regnum != -1) /* do one specified register */ + { + gdb_assert (regnum >= NUM_REGS); + if (*(REGISTER_NAME (regnum)) == '\0') + error ("Not a valid register for the current processor type"); + + mips_print_register (file, frame, regnum, 0); + fprintf_filtered (file, "\n"); + } + else + /* do all (or most) registers */ + { + regnum = NUM_REGS; + while (regnum < NUM_REGS + NUM_PSEUDO_REGS) + { + if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == + TYPE_CODE_FLT) + { + if (all) /* true for "INFO ALL-REGISTERS" command */ + regnum = print_fp_register_row (file, frame, regnum); + else + regnum += MIPS_NUMREGS; /* skip floating point regs */ + } + else + regnum = print_gp_register_row (file, frame, regnum); + } + } +} + +/* Is this a branch with a delay slot? */ + +static int is_delayed (unsigned long); + +static int +is_delayed (unsigned long insn) +{ + int i; + for (i = 0; i < NUMOPCODES; ++i) + if (mips_opcodes[i].pinfo != INSN_MACRO + && (insn & mips_opcodes[i].mask) == mips_opcodes[i].match) + break; + return (i < NUMOPCODES + && (mips_opcodes[i].pinfo & (INSN_UNCOND_BRANCH_DELAY + | INSN_COND_BRANCH_DELAY + | INSN_COND_BRANCH_LIKELY))); +} + +int +mips_step_skips_delay (CORE_ADDR pc) +{ + char buf[MIPS_INSTLEN]; + + /* There is no branch delay slot on MIPS16. */ + if (pc_is_mips16 (pc)) + return 0; + + if (target_read_memory (pc, buf, MIPS_INSTLEN) != 0) + /* If error reading memory, guess that it is not a delayed branch. */ + return 0; + return is_delayed ((unsigned long) + extract_unsigned_integer (buf, MIPS_INSTLEN)); +} + +/* Skip the PC past function prologue instructions (32-bit version). + This is a helper function for mips_skip_prologue. */ + +static CORE_ADDR +mips32_skip_prologue (CORE_ADDR pc) +{ + t_inst inst; + CORE_ADDR end_pc; + int seen_sp_adjust = 0; + int load_immediate_bytes = 0; + + /* Find an upper bound on the prologue. */ + end_pc = skip_prologue_using_sal (pc); + if (end_pc == 0) + end_pc = pc + 100; /* Magic. */ + + /* Skip the typical prologue instructions. These are the stack adjustment + instruction and the instructions that save registers on the stack + or in the gcc frame. */ + for (; pc < end_pc; pc += MIPS_INSTLEN) + { + unsigned long high_word; + + inst = mips_fetch_instruction (pc); + high_word = (inst >> 16) & 0xffff; + + if (high_word == 0x27bd /* addiu $sp,$sp,offset */ + || high_word == 0x67bd) /* daddiu $sp,$sp,offset */ + seen_sp_adjust = 1; + else if (inst == 0x03a1e823 || /* subu $sp,$sp,$at */ + inst == 0x03a8e823) /* subu $sp,$sp,$t0 */ + seen_sp_adjust = 1; + else if (((inst & 0xFFE00000) == 0xAFA00000 /* sw reg,n($sp) */ + || (inst & 0xFFE00000) == 0xFFA00000) /* sd reg,n($sp) */ + && (inst & 0x001F0000)) /* reg != $zero */ + continue; + + else if ((inst & 0xFFE00000) == 0xE7A00000) /* swc1 freg,n($sp) */ + continue; + else if ((inst & 0xF3E00000) == 0xA3C00000 && (inst & 0x001F0000)) + /* sx reg,n($s8) */ + continue; /* reg != $zero */ + + /* move $s8,$sp. With different versions of gas this will be either + `addu $s8,$sp,$zero' or `or $s8,$sp,$zero' or `daddu s8,sp,$0'. + Accept any one of these. */ + else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d) + continue; + + else if ((inst & 0xFF9F07FF) == 0x00800021) /* move reg,$a0-$a3 */ + continue; + else if (high_word == 0x3c1c) /* lui $gp,n */ + continue; + else if (high_word == 0x279c) /* addiu $gp,$gp,n */ + continue; + else if (inst == 0x0399e021 /* addu $gp,$gp,$t9 */ + || inst == 0x033ce021) /* addu $gp,$t9,$gp */ + continue; + /* The following instructions load $at or $t0 with an immediate + value in preparation for a stack adjustment via + subu $sp,$sp,[$at,$t0]. These instructions could also initialize + a local variable, so we accept them only before a stack adjustment + instruction was seen. */ + else if (!seen_sp_adjust) + { + if (high_word == 0x3c01 || /* lui $at,n */ + high_word == 0x3c08) /* lui $t0,n */ + { + load_immediate_bytes += MIPS_INSTLEN; /* FIXME!! */ + continue; + } + else if (high_word == 0x3421 || /* ori $at,$at,n */ + high_word == 0x3508 || /* ori $t0,$t0,n */ + high_word == 0x3401 || /* ori $at,$zero,n */ + high_word == 0x3408) /* ori $t0,$zero,n */ + { + load_immediate_bytes += MIPS_INSTLEN; /* FIXME!! */ + continue; + } + else + break; + } + else + break; + } + + /* In a frameless function, we might have incorrectly + skipped some load immediate instructions. Undo the skipping + if the load immediate was not followed by a stack adjustment. */ + if (load_immediate_bytes && !seen_sp_adjust) + pc -= load_immediate_bytes; + return pc; +} + +/* Skip the PC past function prologue instructions (16-bit version). + This is a helper function for mips_skip_prologue. */ + +static CORE_ADDR +mips16_skip_prologue (CORE_ADDR pc) +{ + CORE_ADDR end_pc; + int extend_bytes = 0; + int prev_extend_bytes; + + /* Table of instructions likely to be found in a function prologue. */ + static struct + { + unsigned short inst; + unsigned short mask; + } + table[] = + { + { + 0x6300, 0xff00} + , /* addiu $sp,offset */ + { + 0xfb00, 0xff00} + , /* daddiu $sp,offset */ + { + 0xd000, 0xf800} + , /* sw reg,n($sp) */ + { + 0xf900, 0xff00} + , /* sd reg,n($sp) */ + { + 0x6200, 0xff00} + , /* sw $ra,n($sp) */ + { + 0xfa00, 0xff00} + , /* sd $ra,n($sp) */ + { + 0x673d, 0xffff} + , /* move $s1,sp */ + { + 0xd980, 0xff80} + , /* sw $a0-$a3,n($s1) */ + { + 0x6704, 0xff1c} + , /* move reg,$a0-$a3 */ + { + 0xe809, 0xf81f} + , /* entry pseudo-op */ + { + 0x0100, 0xff00} + , /* addiu $s1,$sp,n */ + { + 0, 0} /* end of table marker */ + }; + + /* Find an upper bound on the prologue. */ + end_pc = skip_prologue_using_sal (pc); + if (end_pc == 0) + end_pc = pc + 100; /* Magic. */ + + /* Skip the typical prologue instructions. These are the stack adjustment + instruction and the instructions that save registers on the stack + or in the gcc frame. */ + for (; pc < end_pc; pc += MIPS16_INSTLEN) + { + unsigned short inst; + int i; + + inst = mips_fetch_instruction (pc); + + /* Normally we ignore an extend instruction. However, if it is + not followed by a valid prologue instruction, we must adjust + the pc back over the extend so that it won't be considered + part of the prologue. */ + if ((inst & 0xf800) == 0xf000) /* extend */ + { + extend_bytes = MIPS16_INSTLEN; + continue; + } + prev_extend_bytes = extend_bytes; + extend_bytes = 0; + + /* Check for other valid prologue instructions besides extend. */ + for (i = 0; table[i].mask != 0; i++) + if ((inst & table[i].mask) == table[i].inst) /* found, get out */ + break; + if (table[i].mask != 0) /* it was in table? */ + continue; /* ignore it */ + else + /* non-prologue */ + { + /* Return the current pc, adjusted backwards by 2 if + the previous instruction was an extend. */ + return pc - prev_extend_bytes; + } + } + return pc; +} + +/* To skip prologues, I use this predicate. Returns either PC itself + if the code at PC does not look like a function prologue; otherwise + returns an address that (if we're lucky) follows the prologue. If + LENIENT, then we must skip everything which is involved in setting + up the frame (it's OK to skip more, just so long as we don't skip + anything which might clobber the registers which are being saved. + We must skip more in the case where part of the prologue is in the + delay slot of a non-prologue instruction). */ + +static CORE_ADDR +mips_skip_prologue (CORE_ADDR pc) +{ + /* See if we can determine the end of the prologue via the symbol table. + If so, then return either PC, or the PC after the prologue, whichever + is greater. */ + + CORE_ADDR post_prologue_pc = after_prologue (pc, NULL); + + if (post_prologue_pc != 0) + return max (pc, post_prologue_pc); + + /* Can't determine prologue from the symbol table, need to examine + instructions. */ + + if (pc_is_mips16 (pc)) + return mips16_skip_prologue (pc); + else + return mips32_skip_prologue (pc); +} + +/* Exported procedure: Is PC in the signal trampoline code */ + +static int +mips_pc_in_sigtramp (CORE_ADDR pc, char *ignore) +{ + if (sigtramp_address == 0) + fixup_sigtramp (); + return (pc >= sigtramp_address && pc < sigtramp_end); +} + +/* Root of all "set mips "/"show mips " commands. This will eventually be + used for all MIPS-specific commands. */ + +static void +show_mips_command (char *args, int from_tty) +{ + help_list (showmipscmdlist, "show mips ", all_commands, gdb_stdout); +} + +static void +set_mips_command (char *args, int from_tty) +{ + printf_unfiltered + ("\"set mips\" must be followed by an appropriate subcommand.\n"); + help_list (setmipscmdlist, "set mips ", all_commands, gdb_stdout); +} + +/* Commands to show/set the MIPS FPU type. */ + +static void +show_mipsfpu_command (char *args, int from_tty) +{ + char *fpu; + switch (MIPS_FPU_TYPE) + { + case MIPS_FPU_SINGLE: + fpu = "single-precision"; + break; + case MIPS_FPU_DOUBLE: + fpu = "double-precision"; + break; + case MIPS_FPU_NONE: + fpu = "absent (none)"; + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + if (mips_fpu_type_auto) + printf_unfiltered + ("The MIPS floating-point coprocessor is set automatically (currently %s)\n", + fpu); + else + printf_unfiltered + ("The MIPS floating-point coprocessor is assumed to be %s\n", fpu); +} + + +static void +set_mipsfpu_command (char *args, int from_tty) +{ + printf_unfiltered + ("\"set mipsfpu\" must be followed by \"double\", \"single\",\"none\" or \"auto\".\n"); + show_mipsfpu_command (args, from_tty); +} + +static void +set_mipsfpu_single_command (char *args, int from_tty) +{ + struct gdbarch_info info; + gdbarch_info_init (&info); + mips_fpu_type = MIPS_FPU_SINGLE; + mips_fpu_type_auto = 0; + /* FIXME: cagney/2003-11-15: Should be setting a field in "info" + instead of relying on globals. Doing that would let generic code + handle the search for this specific architecture. */ + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, "set mipsfpu failed"); +} + +static void +set_mipsfpu_double_command (char *args, int from_tty) +{ + struct gdbarch_info info; + gdbarch_info_init (&info); + mips_fpu_type = MIPS_FPU_DOUBLE; + mips_fpu_type_auto = 0; + /* FIXME: cagney/2003-11-15: Should be setting a field in "info" + instead of relying on globals. Doing that would let generic code + handle the search for this specific architecture. */ + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, "set mipsfpu failed"); +} + +static void +set_mipsfpu_none_command (char *args, int from_tty) +{ + struct gdbarch_info info; + gdbarch_info_init (&info); + mips_fpu_type = MIPS_FPU_NONE; + mips_fpu_type_auto = 0; + /* FIXME: cagney/2003-11-15: Should be setting a field in "info" + instead of relying on globals. Doing that would let generic code + handle the search for this specific architecture. */ + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, "set mipsfpu failed"); +} + +static void +set_mipsfpu_auto_command (char *args, int from_tty) +{ + mips_fpu_type_auto = 1; +} + +/* Attempt to identify the particular processor model by reading the + processor id. NOTE: cagney/2003-11-15: Firstly it isn't clear that + the relevant processor still exists (it dates back to '94) and + secondly this is not the way to do this. The processor type should + be set by forcing an architecture change. */ + +void +deprecated_mips_set_processor_regs_hack (void) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + CORE_ADDR prid; + + prid = read_register (PRID_REGNUM); + + if ((prid & ~0xf) == 0x700) + tdep->mips_processor_reg_names = mips_r3041_reg_names; +} + +/* Just like reinit_frame_cache, but with the right arguments to be + callable as an sfunc. */ + +static void +reinit_frame_cache_sfunc (char *args, int from_tty, + struct cmd_list_element *c) +{ + reinit_frame_cache (); +} + +static int +gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + mips_extra_func_info_t proc_desc; + + /* Search for the function containing this address. Set the low bit + of the address when searching, in case we were given an even address + that is the start of a 16-bit function. If we didn't do this, + the search would fail because the symbol table says the function + starts at an odd address, i.e. 1 byte past the given address. */ + memaddr = ADDR_BITS_REMOVE (memaddr); + proc_desc = non_heuristic_proc_desc (make_mips16_addr (memaddr), NULL); + + /* Make an attempt to determine if this is a 16-bit function. If + the procedure descriptor exists and the address therein is odd, + it's definitely a 16-bit function. Otherwise, we have to just + guess that if the address passed in is odd, it's 16-bits. */ + /* FIXME: cagney/2003-06-26: Is this even necessary? The + disassembler needs to be able to locally determine the ISA, and + not rely on GDB. Otherwize the stand-alone 'objdump -d' will not + work. */ + if (proc_desc) + { + if (pc_is_mips16 (PROC_LOW_ADDR (proc_desc))) + info->mach = bfd_mach_mips16; + } + else + { + if (pc_is_mips16 (memaddr)) + info->mach = bfd_mach_mips16; + } + + /* Round down the instruction address to the appropriate boundary. */ + memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3); + + /* Set the disassembler options. */ + if (tdep->mips_abi == MIPS_ABI_N32 || tdep->mips_abi == MIPS_ABI_N64) + { + /* Set up the disassembler info, so that we get the right + register names from libopcodes. */ + if (tdep->mips_abi == MIPS_ABI_N32) + info->disassembler_options = "gpr-names=n32"; + else + info->disassembler_options = "gpr-names=64"; + info->flavour = bfd_target_elf_flavour; + } + else + /* This string is not recognized explicitly by the disassembler, + but it tells the disassembler to not try to guess the ABI from + the bfd elf headers, such that, if the user overrides the ABI + of a program linked as NewABI, the disassembly will follow the + register naming conventions specified by the user. */ + info->disassembler_options = "gpr-names=32"; + + /* Call the appropriate disassembler based on the target endian-ness. */ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + return print_insn_big_mips (memaddr, info); + else + return print_insn_little_mips (memaddr, info); +} + +/* This function implements the BREAKPOINT_FROM_PC macro. It uses the program + counter value to determine whether a 16- or 32-bit breakpoint should be + used. It returns a pointer to a string of bytes that encode a breakpoint + instruction, stores the length of the string to *lenptr, and adjusts pc + (if necessary) to point to the actual memory location where the + breakpoint should be inserted. */ + +static const unsigned char * +mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +{ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + if (pc_is_mips16 (*pcptr)) + { + static unsigned char mips16_big_breakpoint[] = { 0xe8, 0xa5 }; + *pcptr = unmake_mips16_addr (*pcptr); + *lenptr = sizeof (mips16_big_breakpoint); + return mips16_big_breakpoint; + } + else + { + /* The IDT board uses an unusual breakpoint value, and + sometimes gets confused when it sees the usual MIPS + breakpoint instruction. */ + static unsigned char big_breakpoint[] = { 0, 0x5, 0, 0xd }; + static unsigned char pmon_big_breakpoint[] = { 0, 0, 0, 0xd }; + static unsigned char idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd }; + + *lenptr = sizeof (big_breakpoint); + + if (strcmp (target_shortname, "mips") == 0) + return idt_big_breakpoint; + else if (strcmp (target_shortname, "ddb") == 0 + || strcmp (target_shortname, "pmon") == 0 + || strcmp (target_shortname, "lsi") == 0) + return pmon_big_breakpoint; + else + return big_breakpoint; + } + } + else + { + if (pc_is_mips16 (*pcptr)) + { + static unsigned char mips16_little_breakpoint[] = { 0xa5, 0xe8 }; + *pcptr = unmake_mips16_addr (*pcptr); + *lenptr = sizeof (mips16_little_breakpoint); + return mips16_little_breakpoint; + } + else + { + static unsigned char little_breakpoint[] = { 0xd, 0, 0x5, 0 }; + static unsigned char pmon_little_breakpoint[] = { 0xd, 0, 0, 0 }; + static unsigned char idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 }; + + *lenptr = sizeof (little_breakpoint); + + if (strcmp (target_shortname, "mips") == 0) + return idt_little_breakpoint; + else if (strcmp (target_shortname, "ddb") == 0 + || strcmp (target_shortname, "pmon") == 0 + || strcmp (target_shortname, "lsi") == 0) + return pmon_little_breakpoint; + else + return little_breakpoint; + } + } +} + +/* If PC is in a mips16 call or return stub, return the address of the target + PC, which is either the callee or the caller. There are several + cases which must be handled: + + * If the PC is in __mips16_ret_{d,s}f, this is a return stub and the + target PC is in $31 ($ra). + * If the PC is in __mips16_call_stub_{1..10}, this is a call stub + and the target PC is in $2. + * If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e. + before the jal instruction, this is effectively a call stub + and the the target PC is in $2. Otherwise this is effectively + a return stub and the target PC is in $18. + + See the source code for the stubs in gcc/config/mips/mips16.S for + gory details. + + This function implements the SKIP_TRAMPOLINE_CODE macro. + */ + +static CORE_ADDR +mips_skip_stub (CORE_ADDR pc) +{ + char *name; + CORE_ADDR start_addr; + + /* Find the starting address and name of the function containing the PC. */ + if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0) + return 0; + + /* If the PC is in __mips16_ret_{d,s}f, this is a return stub and the + target PC is in $31 ($ra). */ + if (strcmp (name, "__mips16_ret_sf") == 0 + || strcmp (name, "__mips16_ret_df") == 0) + return read_signed_register (RA_REGNUM); + + if (strncmp (name, "__mips16_call_stub_", 19) == 0) + { + /* If the PC is in __mips16_call_stub_{1..10}, this is a call stub + and the target PC is in $2. */ + if (name[19] >= '0' && name[19] <= '9') + return read_signed_register (2); + + /* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e. + before the jal instruction, this is effectively a call stub + and the the target PC is in $2. Otherwise this is effectively + a return stub and the target PC is in $18. */ + else if (name[19] == 's' || name[19] == 'd') + { + if (pc == start_addr) + { + /* Check if the target of the stub is a compiler-generated + stub. Such a stub for a function bar might have a name + like __fn_stub_bar, and might look like this: + mfc1 $4,$f13 + mfc1 $5,$f12 + mfc1 $6,$f15 + mfc1 $7,$f14 + la $1,bar (becomes a lui/addiu pair) + jr $1 + So scan down to the lui/addi and extract the target + address from those two instructions. */ + + CORE_ADDR target_pc = read_signed_register (2); + t_inst inst; + int i; + + /* See if the name of the target function is __fn_stub_*. */ + if (find_pc_partial_function (target_pc, &name, NULL, NULL) == + 0) + return target_pc; + if (strncmp (name, "__fn_stub_", 10) != 0 + && strcmp (name, "etext") != 0 + && strcmp (name, "_etext") != 0) + return target_pc; + + /* Scan through this _fn_stub_ code for the lui/addiu pair. + The limit on the search is arbitrarily set to 20 + instructions. FIXME. */ + for (i = 0, pc = 0; i < 20; i++, target_pc += MIPS_INSTLEN) + { + inst = mips_fetch_instruction (target_pc); + if ((inst & 0xffff0000) == 0x3c010000) /* lui $at */ + pc = (inst << 16) & 0xffff0000; /* high word */ + else if ((inst & 0xffff0000) == 0x24210000) /* addiu $at */ + return pc | (inst & 0xffff); /* low word */ + } + + /* Couldn't find the lui/addui pair, so return stub address. */ + return target_pc; + } + else + /* This is the 'return' part of a call stub. The return + address is in $r18. */ + return read_signed_register (18); + } + } + return 0; /* not a stub */ +} + + +/* Return non-zero if the PC is inside a call thunk (aka stub or trampoline). + This implements the IN_SOLIB_CALL_TRAMPOLINE macro. */ + +static int +mips_in_call_stub (CORE_ADDR pc, char *name) +{ + CORE_ADDR start_addr; + + /* Find the starting address of the function containing the PC. If the + caller didn't give us a name, look it up at the same time. */ + if (find_pc_partial_function (pc, name ? NULL : &name, &start_addr, NULL) == + 0) + return 0; + + if (strncmp (name, "__mips16_call_stub_", 19) == 0) + { + /* If the PC is in __mips16_call_stub_{1..10}, this is a call stub. */ + if (name[19] >= '0' && name[19] <= '9') + return 1; + /* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e. + before the jal instruction, this is effectively a call stub. */ + else if (name[19] == 's' || name[19] == 'd') + return pc == start_addr; + } + + return 0; /* not a stub */ +} + + +/* Return non-zero if the PC is inside a return thunk (aka stub or trampoline). + This implements the IN_SOLIB_RETURN_TRAMPOLINE macro. */ + +static int +mips_in_return_stub (CORE_ADDR pc, char *name) +{ + CORE_ADDR start_addr; + + /* Find the starting address of the function containing the PC. */ + if (find_pc_partial_function (pc, NULL, &start_addr, NULL) == 0) + return 0; + + /* If the PC is in __mips16_ret_{d,s}f, this is a return stub. */ + if (strcmp (name, "__mips16_ret_sf") == 0 + || strcmp (name, "__mips16_ret_df") == 0) + return 1; + + /* If the PC is in __mips16_call_stub_{s,d}f_{0..10} but not at the start, + i.e. after the jal instruction, this is effectively a return stub. */ + if (strncmp (name, "__mips16_call_stub_", 19) == 0 + && (name[19] == 's' || name[19] == 'd') && pc != start_addr) + return 1; + + return 0; /* not a stub */ +} + + +/* Return non-zero if the PC is in a library helper function that should + be ignored. This implements the IGNORE_HELPER_CALL macro. */ + +int +mips_ignore_helper (CORE_ADDR pc) +{ + char *name; + + /* Find the starting address and name of the function containing the PC. */ + if (find_pc_partial_function (pc, &name, NULL, NULL) == 0) + return 0; + + /* If the PC is in __mips16_ret_{d,s}f, this is a library helper function + that we want to ignore. */ + return (strcmp (name, "__mips16_ret_sf") == 0 + || strcmp (name, "__mips16_ret_df") == 0); +} + + +/* Convert a dbx stab register number (from `r' declaration) to a GDB + [1 * NUM_REGS .. 2 * NUM_REGS) REGNUM. */ + +static int +mips_stab_reg_to_regnum (int num) +{ + int regnum; + if (num >= 0 && num < 32) + regnum = num; + else if (num >= 38 && num < 70) + regnum = num + mips_regnum (current_gdbarch)->fp0 - 38; + else if (num == 70) + regnum = mips_regnum (current_gdbarch)->hi; + else if (num == 71) + regnum = mips_regnum (current_gdbarch)->lo; + else + /* This will hopefully (eventually) provoke a warning. Should + we be calling complaint() here? */ + return NUM_REGS + NUM_PSEUDO_REGS; + return NUM_REGS + regnum; +} + + +/* Convert a dwarf, dwarf2, or ecoff register number to a GDB [1 * + NUM_REGS .. 2 * NUM_REGS) REGNUM. */ + +static int +mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num) +{ + int regnum; + if (num >= 0 && num < 32) + regnum = num; + else if (num >= 32 && num < 64) + regnum = num + mips_regnum (current_gdbarch)->fp0 - 32; + else if (num == 64) + regnum = mips_regnum (current_gdbarch)->hi; + else if (num == 65) + regnum = mips_regnum (current_gdbarch)->lo; + else + /* This will hopefully (eventually) provoke a warning. Should we + be calling complaint() here? */ + return NUM_REGS + NUM_PSEUDO_REGS; + return NUM_REGS + regnum; +} + +static int +mips_register_sim_regno (int regnum) +{ + /* Only makes sense to supply raw registers. */ + gdb_assert (regnum >= 0 && regnum < NUM_REGS); + /* FIXME: cagney/2002-05-13: Need to look at the pseudo register to + decide if it is valid. Should instead define a standard sim/gdb + register numbering scheme. */ + if (REGISTER_NAME (NUM_REGS + regnum) != NULL + && REGISTER_NAME (NUM_REGS + regnum)[0] != '\0') + return regnum; + else + return LEGACY_SIM_REGNO_IGNORE; +} + + +/* Convert an integer into an address. By first converting the value + into a pointer and then extracting it signed, the address is + guarenteed to be correctly sign extended. */ + +static CORE_ADDR +mips_integer_to_address (struct type *type, void *buf) +{ + char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr)); + LONGEST val = unpack_long (type, buf); + store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val); + return extract_signed_integer (tmp, + TYPE_LENGTH (builtin_type_void_data_ptr)); +} + +static void +mips_find_abi_section (bfd *abfd, asection *sect, void *obj) +{ + enum mips_abi *abip = (enum mips_abi *) obj; + const char *name = bfd_get_section_name (abfd, sect); + + if (*abip != MIPS_ABI_UNKNOWN) + return; + + if (strncmp (name, ".mdebug.", 8) != 0) + return; + + if (strcmp (name, ".mdebug.abi32") == 0) + *abip = MIPS_ABI_O32; + else if (strcmp (name, ".mdebug.abiN32") == 0) + *abip = MIPS_ABI_N32; + else if (strcmp (name, ".mdebug.abi64") == 0) + *abip = MIPS_ABI_N64; + else if (strcmp (name, ".mdebug.abiO64") == 0) + *abip = MIPS_ABI_O64; + else if (strcmp (name, ".mdebug.eabi32") == 0) + *abip = MIPS_ABI_EABI32; + else if (strcmp (name, ".mdebug.eabi64") == 0) + *abip = MIPS_ABI_EABI64; + else + warning ("unsupported ABI %s.", name + 8); +} + +static enum mips_abi +global_mips_abi (void) +{ + int i; + + for (i = 0; mips_abi_strings[i] != NULL; i++) + if (mips_abi_strings[i] == mips_abi_string) + return (enum mips_abi) i; + + internal_error (__FILE__, __LINE__, "unknown ABI string"); +} + +static struct gdbarch * +mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + struct gdbarch *gdbarch; + struct gdbarch_tdep *tdep; + int elf_flags; + enum mips_abi mips_abi, found_abi, wanted_abi; + int num_regs; + enum mips_fpu_type fpu_type; + + /* First of all, extract the elf_flags, if available. */ + if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) + elf_flags = elf_elfheader (info.abfd)->e_flags; + else if (arches != NULL) + elf_flags = gdbarch_tdep (arches->gdbarch)->elf_flags; + else + elf_flags = 0; + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_gdbarch_init: elf_flags = 0x%08x\n", elf_flags); + + /* Check ELF_FLAGS to see if it specifies the ABI being used. */ + switch ((elf_flags & EF_MIPS_ABI)) + { + case E_MIPS_ABI_O32: + found_abi = MIPS_ABI_O32; + break; + case E_MIPS_ABI_O64: + found_abi = MIPS_ABI_O64; + break; + case E_MIPS_ABI_EABI32: + found_abi = MIPS_ABI_EABI32; + break; + case E_MIPS_ABI_EABI64: + found_abi = MIPS_ABI_EABI64; + break; + default: + if ((elf_flags & EF_MIPS_ABI2)) + found_abi = MIPS_ABI_N32; + else + found_abi = MIPS_ABI_UNKNOWN; + break; + } + + /* GCC creates a pseudo-section whose name describes the ABI. */ + if (found_abi == MIPS_ABI_UNKNOWN && info.abfd != NULL) + bfd_map_over_sections (info.abfd, mips_find_abi_section, &found_abi); + + /* If we have no usefu BFD information, use the ABI from the last + MIPS architecture (if there is one). */ + if (found_abi == MIPS_ABI_UNKNOWN && info.abfd == NULL && arches != NULL) + found_abi = gdbarch_tdep (arches->gdbarch)->found_abi; + + /* Try the architecture for any hint of the correct ABI. */ + if (found_abi == MIPS_ABI_UNKNOWN + && info.bfd_arch_info != NULL + && info.bfd_arch_info->arch == bfd_arch_mips) + { + switch (info.bfd_arch_info->mach) + { + case bfd_mach_mips3900: + found_abi = MIPS_ABI_EABI32; + break; + case bfd_mach_mips4100: + case bfd_mach_mips5000: + found_abi = MIPS_ABI_EABI64; + break; + case bfd_mach_mips8000: + case bfd_mach_mips10000: + /* On Irix, ELF64 executables use the N64 ABI. The + pseudo-sections which describe the ABI aren't present + on IRIX. (Even for executables created by gcc.) */ + if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour + && elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64) + found_abi = MIPS_ABI_N64; + else + found_abi = MIPS_ABI_N32; + break; + } + } + + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "mips_gdbarch_init: found_abi = %d\n", + found_abi); + + /* What has the user specified from the command line? */ + wanted_abi = global_mips_abi (); + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "mips_gdbarch_init: wanted_abi = %d\n", + wanted_abi); + + /* Now that we have found what the ABI for this binary would be, + check whether the user is overriding it. */ + if (wanted_abi != MIPS_ABI_UNKNOWN) + mips_abi = wanted_abi; + else if (found_abi != MIPS_ABI_UNKNOWN) + mips_abi = found_abi; + else + mips_abi = MIPS_ABI_O32; + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "mips_gdbarch_init: mips_abi = %d\n", + mips_abi); + + /* Also used when doing an architecture lookup. */ + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_gdbarch_init: mips64_transfers_32bit_regs_p = %d\n", + mips64_transfers_32bit_regs_p); + + /* Determine the MIPS FPU type. */ + if (!mips_fpu_type_auto) + fpu_type = mips_fpu_type; + else if (info.bfd_arch_info != NULL + && info.bfd_arch_info->arch == bfd_arch_mips) + switch (info.bfd_arch_info->mach) + { + case bfd_mach_mips3900: + case bfd_mach_mips4100: + case bfd_mach_mips4111: + fpu_type = MIPS_FPU_NONE; + break; + case bfd_mach_mips4650: + fpu_type = MIPS_FPU_SINGLE; + break; + default: + fpu_type = MIPS_FPU_DOUBLE; + break; + } + else if (arches != NULL) + fpu_type = gdbarch_tdep (arches->gdbarch)->mips_fpu_type; + else + fpu_type = MIPS_FPU_DOUBLE; + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_gdbarch_init: fpu_type = %d\n", fpu_type); + + /* try to find a pre-existing architecture */ + for (arches = gdbarch_list_lookup_by_info (arches, &info); + arches != NULL; + arches = gdbarch_list_lookup_by_info (arches->next, &info)) + { + /* MIPS needs to be pedantic about which ABI the object is + using. */ + if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags) + continue; + if (gdbarch_tdep (arches->gdbarch)->mips_abi != mips_abi) + continue; + /* Need to be pedantic about which register virtual size is + used. */ + if (gdbarch_tdep (arches->gdbarch)->mips64_transfers_32bit_regs_p + != mips64_transfers_32bit_regs_p) + continue; + /* Be pedantic about which FPU is selected. */ + if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type) + continue; + return arches->gdbarch; + } + + /* Need a new architecture. Fill in a target specific vector. */ + tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep)); + gdbarch = gdbarch_alloc (&info, tdep); + tdep->elf_flags = elf_flags; + tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p; + tdep->found_abi = found_abi; + tdep->mips_abi = mips_abi; + tdep->mips_fpu_type = fpu_type; + + /* Initially set everything according to the default ABI/ISA. */ + set_gdbarch_short_bit (gdbarch, 16); + set_gdbarch_int_bit (gdbarch, 32); + set_gdbarch_float_bit (gdbarch, 32); + set_gdbarch_double_bit (gdbarch, 64); + set_gdbarch_long_double_bit (gdbarch, 64); + set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p); + set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write); + + set_gdbarch_elf_make_msymbol_special (gdbarch, + mips_elf_make_msymbol_special); + + /* Fill in the OS dependant register numbers and names. */ + { + const char **reg_names; + struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, + struct mips_regnum); + if (info.osabi == GDB_OSABI_IRIX) + { + regnum->fp0 = 32; + regnum->pc = 64; + regnum->cause = 65; + regnum->badvaddr = 66; + regnum->hi = 67; + regnum->lo = 68; + regnum->fp_control_status = 69; + regnum->fp_implementation_revision = 70; + num_regs = 71; + reg_names = mips_irix_reg_names; + } + else + { + regnum->lo = MIPS_EMBED_LO_REGNUM; + regnum->hi = MIPS_EMBED_HI_REGNUM; + regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM; + regnum->cause = MIPS_EMBED_CAUSE_REGNUM; + regnum->pc = MIPS_EMBED_PC_REGNUM; + regnum->fp0 = MIPS_EMBED_FP0_REGNUM; + regnum->fp_control_status = 70; + regnum->fp_implementation_revision = 71; + num_regs = 90; + if (info.bfd_arch_info != NULL + && info.bfd_arch_info->mach == bfd_mach_mips3900) + reg_names = mips_tx39_reg_names; + else + reg_names = mips_generic_reg_names; + } + /* FIXME: cagney/2003-11-15: For MIPS, hasn't PC_REGNUM been + replaced by read_pc? */ + set_gdbarch_pc_regnum (gdbarch, regnum->pc); + set_gdbarch_fp0_regnum (gdbarch, regnum->fp0); + set_gdbarch_num_regs (gdbarch, num_regs); + set_gdbarch_num_pseudo_regs (gdbarch, num_regs); + set_gdbarch_register_name (gdbarch, mips_register_name); + tdep->mips_processor_reg_names = reg_names; + tdep->regnum = regnum; + } + + switch (mips_abi) + { + case MIPS_ABI_O32: + set_gdbarch_push_dummy_call (gdbarch, mips_o32_push_dummy_call); + set_gdbarch_return_value (gdbarch, mips_o32_return_value); + tdep->mips_default_saved_regsize = 4; + tdep->mips_default_stack_argsize = 4; + tdep->mips_fp_register_double = 0; + tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1; + tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1; + tdep->default_mask_address_p = 0; + set_gdbarch_long_bit (gdbarch, 32); + set_gdbarch_ptr_bit (gdbarch, 32); + set_gdbarch_long_long_bit (gdbarch, 64); + break; + case MIPS_ABI_O64: + set_gdbarch_push_dummy_call (gdbarch, mips_o64_push_dummy_call); + set_gdbarch_deprecated_store_return_value (gdbarch, + mips_o64_store_return_value); + set_gdbarch_deprecated_extract_return_value (gdbarch, + mips_o64_extract_return_value); + tdep->mips_default_saved_regsize = 8; + tdep->mips_default_stack_argsize = 8; + tdep->mips_fp_register_double = 1; + tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1; + tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1; + tdep->default_mask_address_p = 0; + set_gdbarch_long_bit (gdbarch, 32); + set_gdbarch_ptr_bit (gdbarch, 32); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_use_struct_convention (gdbarch, + always_use_struct_convention); + break; + case MIPS_ABI_EABI32: + set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call); + set_gdbarch_deprecated_store_return_value (gdbarch, + mips_eabi_store_return_value); + set_gdbarch_deprecated_extract_return_value (gdbarch, + mips_eabi_extract_return_value); + tdep->mips_default_saved_regsize = 4; + tdep->mips_default_stack_argsize = 4; + tdep->mips_fp_register_double = 0; + tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1; + tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1; + tdep->default_mask_address_p = 0; + set_gdbarch_long_bit (gdbarch, 32); + set_gdbarch_ptr_bit (gdbarch, 32); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_eabi_reg_struct_has_addr); + set_gdbarch_use_struct_convention (gdbarch, + mips_eabi_use_struct_convention); + break; + case MIPS_ABI_EABI64: + set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call); + set_gdbarch_deprecated_store_return_value (gdbarch, + mips_eabi_store_return_value); + set_gdbarch_deprecated_extract_return_value (gdbarch, + mips_eabi_extract_return_value); + tdep->mips_default_saved_regsize = 8; + tdep->mips_default_stack_argsize = 8; + tdep->mips_fp_register_double = 1; + tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1; + tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1; + tdep->default_mask_address_p = 0; + set_gdbarch_long_bit (gdbarch, 64); + set_gdbarch_ptr_bit (gdbarch, 64); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_deprecated_reg_struct_has_addr + (gdbarch, mips_eabi_reg_struct_has_addr); + set_gdbarch_use_struct_convention (gdbarch, + mips_eabi_use_struct_convention); + break; + case MIPS_ABI_N32: + set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call); + set_gdbarch_return_value (gdbarch, mips_n32n64_return_value); + tdep->mips_default_saved_regsize = 8; + tdep->mips_default_stack_argsize = 8; + tdep->mips_fp_register_double = 1; + tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1; + tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1; + tdep->default_mask_address_p = 0; + set_gdbarch_long_bit (gdbarch, 32); + set_gdbarch_ptr_bit (gdbarch, 32); + set_gdbarch_long_long_bit (gdbarch, 64); + break; + case MIPS_ABI_N64: + set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call); + set_gdbarch_return_value (gdbarch, mips_n32n64_return_value); + tdep->mips_default_saved_regsize = 8; + tdep->mips_default_stack_argsize = 8; + tdep->mips_fp_register_double = 1; + tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1; + tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1; + tdep->default_mask_address_p = 0; + set_gdbarch_long_bit (gdbarch, 64); + set_gdbarch_ptr_bit (gdbarch, 64); + set_gdbarch_long_long_bit (gdbarch, 64); + break; + default: + internal_error (__FILE__, __LINE__, "unknown ABI in switch"); + } + + /* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE + that could indicate -gp32 BUT gas/config/tc-mips.c contains the + comment: + + ``We deliberately don't allow "-gp32" to set the MIPS_32BITMODE + flag in object files because to do so would make it impossible to + link with libraries compiled without "-gp32". This is + unnecessarily restrictive. + + We could solve this problem by adding "-gp32" multilibs to gcc, + but to set this flag before gcc is built with such multilibs will + break too many systems.'' + + But even more unhelpfully, the default linker output target for + mips64-elf is elf32-bigmips, and has EF_MIPS_32BIT_MODE set, even + for 64-bit programs - you need to change the ABI to change this, + and not all gcc targets support that currently. Therefore using + this flag to detect 32-bit mode would do the wrong thing given + the current gcc - it would make GDB treat these 64-bit programs + as 32-bit programs by default. */ + + set_gdbarch_read_pc (gdbarch, mips_read_pc); + set_gdbarch_write_pc (gdbarch, mips_write_pc); + set_gdbarch_read_sp (gdbarch, mips_read_sp); + + /* Add/remove bits from an address. The MIPS needs be careful to + ensure that all 32 bit addresses are sign extended to 64 bits. */ + set_gdbarch_addr_bits_remove (gdbarch, mips_addr_bits_remove); + + /* Unwind the frame. */ + set_gdbarch_unwind_pc (gdbarch, mips_unwind_pc); + frame_unwind_append_sniffer (gdbarch, mips_mdebug_frame_sniffer); + set_gdbarch_unwind_dummy_id (gdbarch, mips_unwind_dummy_id); + frame_base_append_sniffer (gdbarch, mips_mdebug_frame_base_sniffer); + + /* Map debug register numbers onto internal register numbers. */ + set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum); + set_gdbarch_ecoff_reg_to_regnum (gdbarch, + mips_dwarf_dwarf2_ecoff_reg_to_regnum); + set_gdbarch_dwarf_reg_to_regnum (gdbarch, + mips_dwarf_dwarf2_ecoff_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, + mips_dwarf_dwarf2_ecoff_reg_to_regnum); + set_gdbarch_register_sim_regno (gdbarch, mips_register_sim_regno); + + /* MIPS version of CALL_DUMMY */ + + /* NOTE: cagney/2003-08-05: Eventually call dummy location will be + replaced by a command, and all targets will default to on stack + (regardless of the stack's execute status). */ + set_gdbarch_call_dummy_location (gdbarch, AT_SYMBOL); + set_gdbarch_frame_align (gdbarch, mips_frame_align); + + set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p); + set_gdbarch_register_to_value (gdbarch, mips_register_to_value); + set_gdbarch_value_to_register (gdbarch, mips_value_to_register); + + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc); + + set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue); + + set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address); + set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer); + set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address); + + set_gdbarch_register_type (gdbarch, mips_register_type); + + set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info); + set_gdbarch_pc_in_sigtramp (gdbarch, mips_pc_in_sigtramp); + + set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips); + + /* FIXME: cagney/2003-08-29: The macros HAVE_STEPPABLE_WATCHPOINT, + HAVE_NONSTEPPABLE_WATCHPOINT, and HAVE_CONTINUABLE_WATCHPOINT + need to all be folded into the target vector. Since they are + being used as guards for STOPPED_BY_WATCHPOINT, why not have + STOPPED_BY_WATCHPOINT return the type of watchpoint that the code + is sitting on? */ + set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); + + set_gdbarch_skip_trampoline_code (gdbarch, mips_skip_stub); + + /* NOTE drow/2004-02-11: We overload the core solib trampoline code + to support MIPS16. This is a bad thing. Make sure not to do it + if we have an OS ABI that actually supports shared libraries, since + shared library support is more important. If we have an OS someday + that supports both shared libraries and MIPS16, we'll have to find + a better place for these. */ + if (info.osabi == GDB_OSABI_UNKNOWN) + { + set_gdbarch_in_solib_call_trampoline (gdbarch, mips_in_call_stub); + set_gdbarch_in_solib_return_trampoline (gdbarch, mips_in_return_stub); + } + + /* Hook in OS ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); + + return gdbarch; +} + +static void +mips_abi_update (char *ignore_args, int from_tty, struct cmd_list_element *c) +{ + struct gdbarch_info info; + + /* Force the architecture to update, and (if it's a MIPS architecture) + mips_gdbarch_init will take care of the rest. */ + gdbarch_info_init (&info); + gdbarch_update_p (info); +} + +/* Print out which MIPS ABI is in use. */ + +static void +show_mips_abi (char *ignore_args, int from_tty) +{ + if (gdbarch_bfd_arch_info (current_gdbarch)->arch != bfd_arch_mips) + printf_filtered + ("The MIPS ABI is unknown because the current architecture is not MIPS.\n"); + else + { + enum mips_abi global_abi = global_mips_abi (); + enum mips_abi actual_abi = mips_abi (current_gdbarch); + const char *actual_abi_str = mips_abi_strings[actual_abi]; + + if (global_abi == MIPS_ABI_UNKNOWN) + printf_filtered + ("The MIPS ABI is set automatically (currently \"%s\").\n", + actual_abi_str); + else if (global_abi == actual_abi) + printf_filtered + ("The MIPS ABI is assumed to be \"%s\" (due to user setting).\n", + actual_abi_str); + else + { + /* Probably shouldn't happen... */ + printf_filtered + ("The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n", + actual_abi_str, mips_abi_strings[global_abi]); + } + } +} + +static void +mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + if (tdep != NULL) + { + int ef_mips_arch; + int ef_mips_32bitmode; + /* determine the ISA */ + switch (tdep->elf_flags & EF_MIPS_ARCH) + { + case E_MIPS_ARCH_1: + ef_mips_arch = 1; + break; + case E_MIPS_ARCH_2: + ef_mips_arch = 2; + break; + case E_MIPS_ARCH_3: + ef_mips_arch = 3; + break; + case E_MIPS_ARCH_4: + ef_mips_arch = 4; + break; + default: + ef_mips_arch = 0; + break; + } + /* determine the size of a pointer */ + ef_mips_32bitmode = (tdep->elf_flags & EF_MIPS_32BITMODE); + fprintf_unfiltered (file, + "mips_dump_tdep: tdep->elf_flags = 0x%x\n", + tdep->elf_flags); + fprintf_unfiltered (file, + "mips_dump_tdep: ef_mips_32bitmode = %d\n", + ef_mips_32bitmode); + fprintf_unfiltered (file, + "mips_dump_tdep: ef_mips_arch = %d\n", + ef_mips_arch); + fprintf_unfiltered (file, + "mips_dump_tdep: tdep->mips_abi = %d (%s)\n", + tdep->mips_abi, mips_abi_strings[tdep->mips_abi]); + fprintf_unfiltered (file, + "mips_dump_tdep: mips_mask_address_p() %d (default %d)\n", + mips_mask_address_p (tdep), + tdep->default_mask_address_p); + } + fprintf_unfiltered (file, + "mips_dump_tdep: FP_REGISTER_DOUBLE = %d\n", + FP_REGISTER_DOUBLE); + fprintf_unfiltered (file, + "mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n", + MIPS_DEFAULT_FPU_TYPE, + (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none" + : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single" + : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double" + : "???")); + fprintf_unfiltered (file, "mips_dump_tdep: MIPS_EABI = %d\n", MIPS_EABI); + fprintf_unfiltered (file, + "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n", + MIPS_FPU_TYPE, + (MIPS_FPU_TYPE == MIPS_FPU_NONE ? "none" + : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? "single" + : MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? "double" + : "???")); + fprintf_unfiltered (file, + "mips_dump_tdep: FP_REGISTER_DOUBLE = %d\n", + FP_REGISTER_DOUBLE); + fprintf_unfiltered (file, + "mips_dump_tdep: mips_stack_argsize() = %d\n", + mips_stack_argsize (tdep)); + fprintf_unfiltered (file, "mips_dump_tdep: A0_REGNUM = %d\n", A0_REGNUM); + fprintf_unfiltered (file, + "mips_dump_tdep: ADDR_BITS_REMOVE # %s\n", + XSTRING (ADDR_BITS_REMOVE (ADDR))); + fprintf_unfiltered (file, + "mips_dump_tdep: ATTACH_DETACH # %s\n", + XSTRING (ATTACH_DETACH)); + fprintf_unfiltered (file, + "mips_dump_tdep: DWARF_REG_TO_REGNUM # %s\n", + XSTRING (DWARF_REG_TO_REGNUM (REGNUM))); + fprintf_unfiltered (file, + "mips_dump_tdep: ECOFF_REG_TO_REGNUM # %s\n", + XSTRING (ECOFF_REG_TO_REGNUM (REGNUM))); + fprintf_unfiltered (file, + "mips_dump_tdep: FIRST_EMBED_REGNUM = %d\n", + FIRST_EMBED_REGNUM); + fprintf_unfiltered (file, + "mips_dump_tdep: IGNORE_HELPER_CALL # %s\n", + XSTRING (IGNORE_HELPER_CALL (PC))); + fprintf_unfiltered (file, + "mips_dump_tdep: IN_SOLIB_CALL_TRAMPOLINE # %s\n", + XSTRING (IN_SOLIB_CALL_TRAMPOLINE (PC, NAME))); + fprintf_unfiltered (file, + "mips_dump_tdep: IN_SOLIB_RETURN_TRAMPOLINE # %s\n", + XSTRING (IN_SOLIB_RETURN_TRAMPOLINE (PC, NAME))); + fprintf_unfiltered (file, + "mips_dump_tdep: LAST_EMBED_REGNUM = %d\n", + LAST_EMBED_REGNUM); +#ifdef MACHINE_CPROC_FP_OFFSET + fprintf_unfiltered (file, + "mips_dump_tdep: MACHINE_CPROC_FP_OFFSET = %d\n", + MACHINE_CPROC_FP_OFFSET); +#endif +#ifdef MACHINE_CPROC_PC_OFFSET + fprintf_unfiltered (file, + "mips_dump_tdep: MACHINE_CPROC_PC_OFFSET = %d\n", + MACHINE_CPROC_PC_OFFSET); +#endif +#ifdef MACHINE_CPROC_SP_OFFSET + fprintf_unfiltered (file, + "mips_dump_tdep: MACHINE_CPROC_SP_OFFSET = %d\n", + MACHINE_CPROC_SP_OFFSET); +#endif + fprintf_unfiltered (file, + "mips_dump_tdep: MIPS16_INSTLEN = %d\n", + MIPS16_INSTLEN); + fprintf_unfiltered (file, "mips_dump_tdep: MIPS_DEFAULT_ABI = FIXME!\n"); + fprintf_unfiltered (file, + "mips_dump_tdep: MIPS_EFI_SYMBOL_NAME = multi-arch!!\n"); + fprintf_unfiltered (file, + "mips_dump_tdep: MIPS_INSTLEN = %d\n", MIPS_INSTLEN); + fprintf_unfiltered (file, + "mips_dump_tdep: MIPS_LAST_ARG_REGNUM = %d (%d regs)\n", + MIPS_LAST_ARG_REGNUM, + MIPS_LAST_ARG_REGNUM - A0_REGNUM + 1); + fprintf_unfiltered (file, + "mips_dump_tdep: MIPS_NUMREGS = %d\n", MIPS_NUMREGS); + fprintf_unfiltered (file, + "mips_dump_tdep: mips_saved_regsize() = %d\n", + mips_saved_regsize (tdep)); + fprintf_unfiltered (file, + "mips_dump_tdep: PRID_REGNUM = %d\n", PRID_REGNUM); + fprintf_unfiltered (file, + "mips_dump_tdep: PROC_DESC_IS_DUMMY = function?\n"); + fprintf_unfiltered (file, + "mips_dump_tdep: PROC_FRAME_ADJUST = function?\n"); + fprintf_unfiltered (file, + "mips_dump_tdep: PROC_FRAME_OFFSET = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_FRAME_REG = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_FREG_MASK = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_FREG_OFFSET = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_HIGH_ADDR = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_LOW_ADDR = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_PC_REG = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_REG_MASK = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_REG_OFFSET = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PROC_SYMBOL = function?\n"); + fprintf_unfiltered (file, "mips_dump_tdep: PS_REGNUM = %d\n", PS_REGNUM); + fprintf_unfiltered (file, "mips_dump_tdep: RA_REGNUM = %d\n", RA_REGNUM); +#ifdef SAVED_BYTES + fprintf_unfiltered (file, + "mips_dump_tdep: SAVED_BYTES = %d\n", SAVED_BYTES); +#endif +#ifdef SAVED_FP + fprintf_unfiltered (file, "mips_dump_tdep: SAVED_FP = %d\n", SAVED_FP); +#endif +#ifdef SAVED_PC + fprintf_unfiltered (file, "mips_dump_tdep: SAVED_PC = %d\n", SAVED_PC); +#endif + fprintf_unfiltered (file, + "mips_dump_tdep: SETUP_ARBITRARY_FRAME # %s\n", + XSTRING (SETUP_ARBITRARY_FRAME (NUMARGS, ARGS))); + fprintf_unfiltered (file, + "mips_dump_tdep: SET_PROC_DESC_IS_DUMMY = function?\n"); + fprintf_unfiltered (file, + "mips_dump_tdep: SKIP_TRAMPOLINE_CODE # %s\n", + XSTRING (SKIP_TRAMPOLINE_CODE (PC))); + fprintf_unfiltered (file, + "mips_dump_tdep: SOFTWARE_SINGLE_STEP # %s\n", + XSTRING (SOFTWARE_SINGLE_STEP (SIG, BP_P))); + fprintf_unfiltered (file, + "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P () = %d\n", + SOFTWARE_SINGLE_STEP_P ()); + fprintf_unfiltered (file, + "mips_dump_tdep: STAB_REG_TO_REGNUM # %s\n", + XSTRING (STAB_REG_TO_REGNUM (REGNUM))); +#ifdef STACK_END_ADDR + fprintf_unfiltered (file, + "mips_dump_tdep: STACK_END_ADDR = %d\n", + STACK_END_ADDR); +#endif + fprintf_unfiltered (file, + "mips_dump_tdep: STEP_SKIPS_DELAY # %s\n", + XSTRING (STEP_SKIPS_DELAY (PC))); + fprintf_unfiltered (file, + "mips_dump_tdep: STEP_SKIPS_DELAY_P = %d\n", + STEP_SKIPS_DELAY_P); + fprintf_unfiltered (file, + "mips_dump_tdep: STOPPED_BY_WATCHPOINT # %s\n", + XSTRING (STOPPED_BY_WATCHPOINT (WS))); + fprintf_unfiltered (file, "mips_dump_tdep: T9_REGNUM = %d\n", T9_REGNUM); + fprintf_unfiltered (file, + "mips_dump_tdep: TABULAR_REGISTER_OUTPUT = used?\n"); + fprintf_unfiltered (file, + "mips_dump_tdep: TARGET_CAN_USE_HARDWARE_WATCHPOINT # %s\n", + XSTRING (TARGET_CAN_USE_HARDWARE_WATCHPOINT + (TYPE, CNT, OTHERTYPE))); + fprintf_unfiltered (file, + "mips_dump_tdep: TARGET_HAS_HARDWARE_WATCHPOINTS # %s\n", + XSTRING (TARGET_HAS_HARDWARE_WATCHPOINTS)); +#ifdef TRACE_CLEAR + fprintf_unfiltered (file, + "mips_dump_tdep: TRACE_CLEAR # %s\n", + XSTRING (TRACE_CLEAR (THREAD, STATE))); +#endif +#ifdef TRACE_FLAVOR + fprintf_unfiltered (file, + "mips_dump_tdep: TRACE_FLAVOR = %d\n", TRACE_FLAVOR); +#endif +#ifdef TRACE_FLAVOR_SIZE + fprintf_unfiltered (file, + "mips_dump_tdep: TRACE_FLAVOR_SIZE = %d\n", + TRACE_FLAVOR_SIZE); +#endif +#ifdef TRACE_SET + fprintf_unfiltered (file, + "mips_dump_tdep: TRACE_SET # %s\n", + XSTRING (TRACE_SET (X, STATE))); +#endif +#ifdef UNUSED_REGNUM + fprintf_unfiltered (file, + "mips_dump_tdep: UNUSED_REGNUM = %d\n", UNUSED_REGNUM); +#endif + fprintf_unfiltered (file, "mips_dump_tdep: V0_REGNUM = %d\n", V0_REGNUM); + fprintf_unfiltered (file, + "mips_dump_tdep: VM_MIN_ADDRESS = %ld\n", + (long) VM_MIN_ADDRESS); + fprintf_unfiltered (file, + "mips_dump_tdep: ZERO_REGNUM = %d\n", ZERO_REGNUM); + fprintf_unfiltered (file, + "mips_dump_tdep: _PROC_MAGIC_ = %d\n", _PROC_MAGIC_); +} + +extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */ + +void +_initialize_mips_tdep (void) +{ + static struct cmd_list_element *mipsfpulist = NULL; + struct cmd_list_element *c; + + mips_abi_string = mips_abi_strings[MIPS_ABI_UNKNOWN]; + if (MIPS_ABI_LAST + 1 + != sizeof (mips_abi_strings) / sizeof (mips_abi_strings[0])) + internal_error (__FILE__, __LINE__, "mips_abi_strings out of sync"); + + gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep); + + mips_pdr_data = register_objfile_data (); + + /* Add root prefix command for all "set mips"/"show mips" commands */ + add_prefix_cmd ("mips", no_class, set_mips_command, + "Various MIPS specific commands.", + &setmipscmdlist, "set mips ", 0, &setlist); + + add_prefix_cmd ("mips", no_class, show_mips_command, + "Various MIPS specific commands.", + &showmipscmdlist, "show mips ", 0, &showlist); + + /* Allow the user to override the saved register size. */ + add_show_from_set (add_set_enum_cmd ("saved-gpreg-size", + class_obscure, + size_enums, + &mips_saved_regsize_string, "\ +Set size of general purpose registers saved on the stack.\n\ +This option can be set to one of:\n\ + 32 - Force GDB to treat saved GP registers as 32-bit\n\ + 64 - Force GDB to treat saved GP registers as 64-bit\n\ + auto - Allow GDB to use the target's default setting or autodetect the\n\ + saved GP register size from information contained in the executable.\n\ + (default: auto)", &setmipscmdlist), &showmipscmdlist); + + /* Allow the user to override the argument stack size. */ + add_show_from_set (add_set_enum_cmd ("stack-arg-size", + class_obscure, + size_enums, + &mips_stack_argsize_string, "\ +Set the amount of stack space reserved for each argument.\n\ +This option can be set to one of:\n\ + 32 - Force GDB to allocate 32-bit chunks per argument\n\ + 64 - Force GDB to allocate 64-bit chunks per argument\n\ + auto - Allow GDB to determine the correct setting from the current\n\ + target and executable (default)", &setmipscmdlist), &showmipscmdlist); + + /* Allow the user to override the ABI. */ + c = add_set_enum_cmd + ("abi", class_obscure, mips_abi_strings, &mips_abi_string, + "Set the ABI used by this program.\n" + "This option can be set to one of:\n" + " auto - the default ABI associated with the current binary\n" + " o32\n" + " o64\n" " n32\n" " n64\n" " eabi32\n" " eabi64", &setmipscmdlist); + set_cmd_sfunc (c, mips_abi_update); + add_cmd ("abi", class_obscure, show_mips_abi, + "Show ABI in use by MIPS target", &showmipscmdlist); + + /* Let the user turn off floating point and set the fence post for + heuristic_proc_start. */ + + add_prefix_cmd ("mipsfpu", class_support, set_mipsfpu_command, + "Set use of MIPS floating-point coprocessor.", + &mipsfpulist, "set mipsfpu ", 0, &setlist); + add_cmd ("single", class_support, set_mipsfpu_single_command, + "Select single-precision MIPS floating-point coprocessor.", + &mipsfpulist); + add_cmd ("double", class_support, set_mipsfpu_double_command, + "Select double-precision MIPS floating-point coprocessor.", + &mipsfpulist); + add_alias_cmd ("on", "double", class_support, 1, &mipsfpulist); + add_alias_cmd ("yes", "double", class_support, 1, &mipsfpulist); + add_alias_cmd ("1", "double", class_support, 1, &mipsfpulist); + add_cmd ("none", class_support, set_mipsfpu_none_command, + "Select no MIPS floating-point coprocessor.", &mipsfpulist); + add_alias_cmd ("off", "none", class_support, 1, &mipsfpulist); + add_alias_cmd ("no", "none", class_support, 1, &mipsfpulist); + add_alias_cmd ("0", "none", class_support, 1, &mipsfpulist); + add_cmd ("auto", class_support, set_mipsfpu_auto_command, + "Select MIPS floating-point coprocessor automatically.", + &mipsfpulist); + add_cmd ("mipsfpu", class_support, show_mipsfpu_command, + "Show current use of MIPS floating-point coprocessor target.", + &showlist); + + /* We really would like to have both "0" and "unlimited" work, but + command.c doesn't deal with that. So make it a var_zinteger + because the user can always use "999999" or some such for unlimited. */ + c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger, + (char *) &heuristic_fence_post, "\ +Set the distance searched for the start of a function.\n\ +If you are debugging a stripped executable, GDB needs to search through the\n\ +program for the start of a function. This command sets the distance of the\n\ +search. The only need to set it is when debugging a stripped executable.", &setlist); + /* We need to throw away the frame cache when we set this, since it + might change our ability to get backtraces. */ + set_cmd_sfunc (c, reinit_frame_cache_sfunc); + add_show_from_set (c, &showlist); + + /* Allow the user to control whether the upper bits of 64-bit + addresses should be zeroed. */ + add_setshow_auto_boolean_cmd ("mask-address", no_class, &mask_address_var, "\ +Set zeroing of upper 32 bits of 64-bit addresses.\n\ +Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to \n\ +allow GDB to determine the correct value.\n", "\ +Show zeroing of upper 32 bits of 64-bit addresses.", + NULL, show_mask_address, &setmipscmdlist, &showmipscmdlist); + + /* Allow the user to control the size of 32 bit registers within the + raw remote packet. */ + add_setshow_cmd ("remote-mips64-transfers-32bit-regs", class_obscure, + var_boolean, &mips64_transfers_32bit_regs_p, "\ +Set compatibility with 64-bit MIPS targets that transfer 32-bit quantities.\n\ +Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\ +that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\ +64 bits for others. Use \"off\" to disable compatibility mode", "\ +Show compatibility with 64-bit MIPS targets that transfer 32-bit quantities.\n\ +Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\ +that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\ +64 bits for others. Use \"off\" to disable compatibility mode", set_mips64_transfers_32bit_regs, NULL, &setlist, &showlist); + + /* Debug this files internals. */ + add_show_from_set (add_set_cmd ("mips", class_maintenance, var_zinteger, + &mips_debug, "Set mips debugging.\n\ +When non-zero, mips specific debugging is enabled.", &setdebuglist), &showdebuglist); +} diff --git a/contrib/gdb/gdb/mips-tdep.h b/contrib/gdb/gdb/mips-tdep.h new file mode 100644 index 00000000000..7a00ffaf5e9 --- /dev/null +++ b/contrib/gdb/gdb/mips-tdep.h @@ -0,0 +1,77 @@ +/* Target-dependent header for the MIPS architecture, for GDB, the GNU Debugger. + + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MIPS_TDEP_H +#define MIPS_TDEP_H + +struct gdbarch; + +/* All the possible MIPS ABIs. */ +enum mips_abi + { + MIPS_ABI_UNKNOWN = 0, + MIPS_ABI_N32, + MIPS_ABI_O32, + MIPS_ABI_N64, + MIPS_ABI_O64, + MIPS_ABI_EABI32, + MIPS_ABI_EABI64, + MIPS_ABI_LAST + }; + +/* Return the MIPS ABI associated with GDBARCH. */ +enum mips_abi mips_abi (struct gdbarch *gdbarch); + +/* For wince :-(. */ +extern CORE_ADDR mips_next_pc (CORE_ADDR pc); + +/* Return the "MIPS" register size. Just a short cut to the BFD + architecture's word size. */ +extern int mips_regsize (struct gdbarch *gdbarch); + +/* Return the current index for various MIPS registers. */ +struct mips_regnum +{ + int pc; + int fp0; + int fp_implementation_revision; + int fp_control_status; + int badvaddr; /* Bad vaddr for addressing exception. */ + int cause; /* Describes last exception. */ + int hi; /* Multiply/divide temp. */ + int lo; /* ... */ +}; +extern const struct mips_regnum *mips_regnum (struct gdbarch *gdbarch); + +enum { + MIPS_EMBED_LO_REGNUM = 33, + MIPS_EMBED_HI_REGNUM = 34, + MIPS_EMBED_BADVADDR_REGNUM = 35, + MIPS_EMBED_CAUSE_REGNUM = 36, + MIPS_EMBED_PC_REGNUM = 37, + MIPS_EMBED_FP0_REGNUM = 38 +}; + +/* Defined in mips-tdep.c and used in remote-mips.c */ +extern void deprecated_mips_set_processor_regs_hack (void); + + +#endif /* MIPS_TDEP_H */ diff --git a/contrib/gdb/gdb/mipsnbsd-nat.c b/contrib/gdb/gdb/mipsnbsd-nat.c new file mode 100644 index 00000000000..16521f67617 --- /dev/null +++ b/contrib/gdb/gdb/mipsnbsd-nat.c @@ -0,0 +1,101 @@ +/* Native-dependent code for MIPS systems running NetBSD. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "regcache.h" + +#include "mipsnbsd-tdep.h" + +#include +#include +#include + +/* Determine if PT_GETREGS fetches this register. */ +static int +getregs_supplies (int regno) +{ + return ((regno) >= ZERO_REGNUM && (regno) <= PC_REGNUM); +} + +void +fetch_inferior_registers (int regno) +{ + if (regno == -1 || getregs_supplies (regno)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + mipsnbsd_supply_reg ((char *) ®s, regno); + if (regno != -1) + return; + } + + if (regno == -1 || regno >= FP0_REGNUM) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + mipsnbsd_supply_fpreg ((char *) &fpregs, regno); + } +} + +void +store_inferior_registers (int regno) +{ + if (regno == -1 || getregs_supplies (regno)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + mipsnbsd_fill_reg ((char *) ®s, regno); + + if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't write registers"); + + if (regno != -1) + return; + } + + if (regno == -1 || regno >= FP0_REGNUM) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + mipsnbsd_fill_fpreg ((char *) &fpregs, regno); + + if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't write floating point status"); + } +} diff --git a/contrib/gdb/gdb/mipsnbsd-tdep.c b/contrib/gdb/gdb/mipsnbsd-tdep.c new file mode 100644 index 00000000000..01d8262eff2 --- /dev/null +++ b/contrib/gdb/gdb/mipsnbsd-tdep.c @@ -0,0 +1,370 @@ +/* Target-dependent code for MIPS systems running NetBSD. + Copyright 2002, 2003 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "regcache.h" +#include "target.h" +#include "value.h" +#include "osabi.h" + +#include "nbsd-tdep.h" +#include "mipsnbsd-tdep.h" + +#include "solib-svr4.h" + +/* Conveniently, GDB uses the same register numbering as the + ptrace register structure used by NetBSD/mips. */ + +void +mipsnbsd_supply_reg (char *regs, int regno) +{ + int i; + + for (i = 0; i <= PC_REGNUM; i++) + { + if (regno == i || regno == -1) + { + if (CANNOT_FETCH_REGISTER (i)) + supply_register (i, NULL); + else + supply_register (i, regs + (i * mips_regsize (current_gdbarch))); + } + } +} + +void +mipsnbsd_fill_reg (char *regs, int regno) +{ + int i; + + for (i = 0; i <= PC_REGNUM; i++) + if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i)) + regcache_collect (i, regs + (i * mips_regsize (current_gdbarch))); +} + +void +mipsnbsd_supply_fpreg (char *fpregs, int regno) +{ + int i; + + for (i = FP0_REGNUM; + i <= mips_regnum (current_gdbarch)->fp_implementation_revision; + i++) + { + if (regno == i || regno == -1) + { + if (CANNOT_FETCH_REGISTER (i)) + supply_register (i, NULL); + else + supply_register (i, fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch))); + } + } +} + +void +mipsnbsd_fill_fpreg (char *fpregs, int regno) +{ + int i; + + for (i = FP0_REGNUM; i <= mips_regnum (current_gdbarch)->fp_control_status; + i++) + if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i)) + regcache_collect (i, fpregs + ((i - FP0_REGNUM) * mips_regsize (current_gdbarch))); +} + +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR ignore) +{ + char *regs, *fpregs; + + /* We get everything from one section. */ + if (which != 0) + return; + + regs = core_reg_sect; + fpregs = core_reg_sect + SIZEOF_STRUCT_REG; + + /* Integer registers. */ + mipsnbsd_supply_reg (regs, -1); + + /* Floating point registers. */ + mipsnbsd_supply_fpreg (fpregs, -1); +} + +static void +fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR ignore) +{ + switch (which) + { + case 0: /* Integer registers. */ + if (core_reg_size != SIZEOF_STRUCT_REG) + warning ("Wrong size register set in core file."); + else + mipsnbsd_supply_reg (core_reg_sect, -1); + break; + + case 2: /* Floating point registers. */ + if (core_reg_size != SIZEOF_STRUCT_FPREG) + warning ("Wrong size register set in core file."); + else + mipsnbsd_supply_fpreg (core_reg_sect, -1); + break; + + default: + /* Don't know what kind of register request this is; just ignore it. */ + break; + } +} + +static struct core_fns mipsnbsd_core_fns = +{ + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +static struct core_fns mipsnbsd_elfcore_fns = +{ + bfd_target_elf_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_elfcore_registers, /* core_read_registers */ + NULL /* next */ +}; + +/* Under NetBSD/mips, signal handler invocations can be identified by the + designated code sequence that is used to return from a signal handler. + In particular, the return address of a signal handler points to the + following code sequence: + + addu a0, sp, 16 + li v0, 295 # __sigreturn14 + syscall + + Each instruction has a unique encoding, so we simply attempt to match + the instruction the PC is pointing to with any of the above instructions. + If there is a hit, we know the offset to the start of the designated + sequence and can then check whether we really are executing in the + signal trampoline. If not, -1 is returned, otherwise the offset from the + start of the return sequence is returned. */ + +#define RETCODE_NWORDS 3 +#define RETCODE_SIZE (RETCODE_NWORDS * 4) + +static const unsigned char sigtramp_retcode_mipsel[RETCODE_SIZE] = +{ + 0x10, 0x00, 0xa4, 0x27, /* addu a0, sp, 16 */ + 0x27, 0x01, 0x02, 0x24, /* li v0, 295 */ + 0x0c, 0x00, 0x00, 0x00, /* syscall */ +}; + +static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] = +{ + 0x27, 0xa4, 0x00, 0x10, /* addu a0, sp, 16 */ + 0x24, 0x02, 0x01, 0x27, /* li v0, 295 */ + 0x00, 0x00, 0x00, 0x0c, /* syscall */ +}; + +static LONGEST +mipsnbsd_sigtramp_offset (CORE_ADDR pc) +{ + const char *retcode = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + ? sigtramp_retcode_mipseb : sigtramp_retcode_mipsel; + unsigned char ret[RETCODE_SIZE], w[4]; + LONGEST off; + int i; + + if (read_memory_nobpt (pc, (char *) w, sizeof (w)) != 0) + return -1; + + for (i = 0; i < RETCODE_NWORDS; i++) + { + if (memcmp (w, retcode + (i * 4), 4) == 0) + break; + } + if (i == RETCODE_NWORDS) + return -1; + + off = i * 4; + pc -= off; + + if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0) + return -1; + + if (memcmp (ret, retcode, RETCODE_SIZE) == 0) + return off; + + return -1; +} + +static int +mipsnbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) +{ + return (nbsd_pc_in_sigtramp (pc, func_name) + || mipsnbsd_sigtramp_offset (pc) >= 0); +} + +/* Figure out where the longjmp will land. We expect that we have + just entered longjmp and haven't yet setup the stack frame, so + the args are still in the argument regs. A0_REGNUM points at the + jmp_buf structure from which we extract the PC that we will land + at. The PC is copied into *pc. This routine returns true on + success. */ + +#define NBSD_MIPS_JB_PC (2 * 4) +#define NBSD_MIPS_JB_ELEMENT_SIZE mips_regsize (current_gdbarch) +#define NBSD_MIPS_JB_OFFSET (NBSD_MIPS_JB_PC * \ + NBSD_MIPS_JB_ELEMENT_SIZE) + +static int +mipsnbsd_get_longjmp_target (CORE_ADDR *pc) +{ + CORE_ADDR jb_addr; + char *buf; + + buf = alloca (NBSD_MIPS_JB_ELEMENT_SIZE); + + jb_addr = read_register (A0_REGNUM); + + if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET, buf, + NBSD_MIPS_JB_ELEMENT_SIZE)) + return 0; + + *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE); + + return 1; +} + +static int +mipsnbsd_cannot_fetch_register (int regno) +{ + return (regno == ZERO_REGNUM + || regno == mips_regnum (current_gdbarch)->fp_implementation_revision); +} + +static int +mipsnbsd_cannot_store_register (int regno) +{ + return (regno == ZERO_REGNUM + || regno == mips_regnum (current_gdbarch)->fp_implementation_revision); +} + +/* NetBSD/mips uses a slightly different link_map structure from the + other NetBSD platforms. */ +static struct link_map_offsets * +mipsnbsd_ilp32_solib_svr4_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + lmo.r_debug_size = 16; + + lmo.r_map_offset = 4; + lmo.r_map_size = 4; + + lmo.link_map_size = 24; + + lmo.l_addr_offset = 0; + lmo.l_addr_size = 4; + + lmo.l_name_offset = 8; + lmo.l_name_size = 4; + + lmo.l_next_offset = 16; + lmo.l_next_size = 4; + + lmo.l_prev_offset = 20; + lmo.l_prev_size = 4; + } + + return lmp; +} + +static struct link_map_offsets * +mipsnbsd_lp64_solib_svr4_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + lmo.r_debug_size = 32; + + lmo.r_map_offset = 8; + lmo.r_map_size = 8; + + lmo.link_map_size = 48; + + lmo.l_addr_offset = 0; + lmo.l_addr_size = 8; + + lmo.l_name_offset = 16; + lmo.l_name_size = 8; + + lmo.l_next_offset = 32; + lmo.l_next_size = 8; + + lmo.l_prev_offset = 40; + lmo.l_prev_size = 8; + } + + return lmp; +} + +static void +mipsnbsd_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + set_gdbarch_pc_in_sigtramp (gdbarch, mipsnbsd_pc_in_sigtramp); + + set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target); + + set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register); + set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register); + + set_gdbarch_software_single_step (gdbarch, mips_software_single_step); + + set_solib_svr4_fetch_link_map_offsets (gdbarch, + gdbarch_ptr_bit (gdbarch) == 32 ? + mipsnbsd_ilp32_solib_svr4_fetch_link_map_offsets : + mipsnbsd_lp64_solib_svr4_fetch_link_map_offsets); +} + +void +_initialize_mipsnbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_NETBSD_ELF, + mipsnbsd_init_abi); + + add_core_fns (&mipsnbsd_core_fns); + add_core_fns (&mipsnbsd_elfcore_fns); +} diff --git a/contrib/gdb/gdb/mipsnbsd-tdep.h b/contrib/gdb/gdb/mipsnbsd-tdep.h new file mode 100644 index 00000000000..0feca8784c6 --- /dev/null +++ b/contrib/gdb/gdb/mipsnbsd-tdep.h @@ -0,0 +1,33 @@ +/* Common target dependent code for GDB on MIPS systems running NetBSD. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MIPSNBSD_TDEP_H +#define MIPSNBSD_TDEP_H + +void mipsnbsd_supply_reg (char *, int); +void mipsnbsd_fill_reg (char *, int); + +void mipsnbsd_supply_fpreg (char *, int); +void mipsnbsd_fill_fpreg (char *, int); + +#define SIZEOF_STRUCT_REG (38 * mips_regsize (current_gdbarch)) +#define SIZEOF_STRUCT_FPREG (33 * mips_regsize (current_gdbarch)) + +#endif /* MIPSNBSD_TDEP_H */ diff --git a/contrib/gdb/gdb/mipsread.c b/contrib/gdb/gdb/mipsread.c index 1f869f4b015..f67eeea9819 100644 --- a/contrib/gdb/gdb/mipsread.c +++ b/contrib/gdb/gdb/mipsread.c @@ -1,6 +1,6 @@ /* Read a symbol table in MIPS' format (Third-Eye). Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1998, 1999, 2000, 2001 + 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU. Major work by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support. @@ -29,7 +29,6 @@ #include "gdb_string.h" #include "bfd.h" #include "symtab.h" -#include "symfile.h" #include "objfiles.h" #include "buildsym.h" #include "stabsread.h" @@ -113,15 +112,15 @@ mipscoff_symfile_read (struct objfile *objfile, int mainline) if (mainline && objfile->ei.entry_point != INVALID_ENTRY_POINT - && objfile->ei.entry_file_lowpc == INVALID_ENTRY_LOWPC) + && objfile->ei.deprecated_entry_file_lowpc == INVALID_ENTRY_LOWPC) { struct minimal_symbol *m; m = lookup_minimal_symbol_by_pc (objfile->ei.entry_point); - if (m && SYMBOL_NAME (m + 1)) + if (m && DEPRECATED_SYMBOL_NAME (m + 1)) { - objfile->ei.entry_file_lowpc = SYMBOL_VALUE_ADDRESS (m); - objfile->ei.entry_file_highpc = SYMBOL_VALUE_ADDRESS (m + 1); + objfile->ei.deprecated_entry_file_lowpc = SYMBOL_VALUE_ADDRESS (m); + objfile->ei.deprecated_entry_file_highpc = SYMBOL_VALUE_ADDRESS (m + 1); } } @@ -193,23 +192,23 @@ struct alphacoff_dynsecinfo static void alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, void *sip) { - register struct alphacoff_dynsecinfo *si; + struct alphacoff_dynsecinfo *si; si = (struct alphacoff_dynsecinfo *) sip; - if (STREQ (sectp->name, ".dynsym")) + if (DEPRECATED_STREQ (sectp->name, ".dynsym")) { si->sym_sect = sectp; } - else if (STREQ (sectp->name, ".dynstr")) + else if (DEPRECATED_STREQ (sectp->name, ".dynstr")) { si->str_sect = sectp; } - else if (STREQ (sectp->name, ".dynamic")) + else if (DEPRECATED_STREQ (sectp->name, ".dynamic")) { si->dyninfo_sect = sectp; } - else if (STREQ (sectp->name, ".got")) + else if (DEPRECATED_STREQ (sectp->name, ".got")) { si->got_sect = sectp; } diff --git a/contrib/gdb/gdb/mipsv4-nat.c b/contrib/gdb/gdb/mipsv4-nat.c new file mode 100644 index 00000000000..3a3e7327ef5 --- /dev/null +++ b/contrib/gdb/gdb/mipsv4-nat.c @@ -0,0 +1,168 @@ +/* Native support for MIPS running SVR4, for GDB. + Copyright 1994, 1995, 2000, 2001 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "gdbcore.h" +#include "target.h" +#include "regcache.h" + +#include +#include +#include /* For JB_XXX. */ + +/* Prototypes for supply_gregset etc. */ +#include "gregset.h" + +/* Size of elements in jmpbuf */ + +#define JB_ELEMENT_SIZE 4 + +/* + * See the comment in m68k-tdep.c regarding the utility of these functions. + * + * These definitions are from the MIPS SVR4 ABI, so they may work for + * any MIPS SVR4 target. + */ + +void +supply_gregset (gregset_t *gregsetp) +{ + int regi; + greg_t *regp = &(*gregsetp)[0]; + char zerobuf[MAX_REGISTER_SIZE]; + memset (zerobuf, 0, MAX_REGISTER_SIZE); + + for (regi = 0; regi <= CXT_RA; regi++) + supply_register (regi, (char *) (regp + regi)); + + supply_register (mips_regnum (current_gdbarch)->pc, + (char *) (regp + CXT_EPC)); + supply_register (mips_regnum (current_gdbarch)->hi, + (char *) (regp + CXT_MDHI)); + supply_register (mips_regnum (current_gdbarch)->lo, + (char *) (regp + CXT_MDLO)); + supply_register (mips_regnum (current_gdbarch)->cause, + (char *) (regp + CXT_CAUSE)); + + /* Fill inaccessible registers with zero. */ + supply_register (PS_REGNUM, zerobuf); + supply_register (mips_regnum (current_gdbarch)->badvaddr, zerobuf); + supply_register (DEPRECATED_FP_REGNUM, zerobuf); + supply_register (UNUSED_REGNUM, zerobuf); + for (regi = FIRST_EMBED_REGNUM; regi <= LAST_EMBED_REGNUM; regi++) + supply_register (regi, zerobuf); +} + +void +fill_gregset (gregset_t *gregsetp, int regno) +{ + int regi; + greg_t *regp = &(*gregsetp)[0]; + + for (regi = 0; regi <= 32; regi++) + if ((regno == -1) || (regno == regi)) + *(regp + regi) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)]; + + if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->pc)) + *(regp + CXT_EPC) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->pc)]; + + if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->cause)) + *(regp + CXT_CAUSE) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->cause)]; + + if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->hi)) + *(regp + CXT_MDHI) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->hi)]; + + if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->lo)) + *(regp + CXT_MDLO) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->lo)]; +} + +/* + * Now we do the same thing for floating-point registers. + * We don't bother to condition on FP0 regnum since any + * reasonable MIPS configuration has an R3010 in it. + * + * Again, see the comments in m68k-tdep.c. + */ + +void +supply_fpregset (fpregset_t *fpregsetp) +{ + int regi; + char zerobuf[MAX_REGISTER_SIZE]; + memset (zerobuf, 0, MAX_REGISTER_SIZE); + + for (regi = 0; regi < 32; regi++) + supply_register (mips_regnum (current_gdbarch)->fp0 + regi, + (char *) &fpregsetp->fp_r.fp_regs[regi]); + + supply_register (mips_regnum (current_gdbarch)->fp_control_status, + (char *) &fpregsetp->fp_csr); + + /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */ + supply_register (mips_regnum (current_gdbarch)->fp_implementation_revision, + zerobuf); +} + +void +fill_fpregset (fpregset_t *fpregsetp, int regno) +{ + int regi; + char *from, *to; + + for (regi = mips_regnum (current_gdbarch)->fp0; + regi < mips_regnum (current_gdbarch)->fp0 + 32; regi++) + { + if ((regno == -1) || (regno == regi)) + { + from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)]; + to = (char *) &(fpregsetp->fp_r.fp_regs[regi - mips_regnum (current_gdbarch)->fp0]); + memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regi)); + } + } + + if ((regno == -1) + || (regno == mips_regnum (current_gdbarch)->fp_control_status)) + fpregsetp->fp_csr = *(unsigned *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->fp_control_status)]; +} + + +/* Figure out where the longjmp will land. + We expect the first arg to be a pointer to the jmp_buf structure from which + we extract the pc (_JB_PC) that we will land at. The pc is copied into PC. + This routine returns true on success. */ + +int +get_longjmp_target (CORE_ADDR *pc) +{ + char *buf; + CORE_ADDR jb_addr; + + buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT); + jb_addr = read_register (A0_REGNUM); + + if (target_read_memory (jb_addr + _JB_PC * JB_ELEMENT_SIZE, buf, + TARGET_PTR_BIT / TARGET_CHAR_BIT)) + return 0; + + *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); + + return 1; +} diff --git a/contrib/gdb/gdb/monitor.c b/contrib/gdb/gdb/monitor.c new file mode 100644 index 00000000000..cd4f045375e --- /dev/null +++ b/contrib/gdb/gdb/monitor.c @@ -0,0 +1,2310 @@ +/* Remote debugging interface for boot monitors, for GDB. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + + Contributed by Cygnus Support. Written by Rob Savoye for Cygnus. + Resurrected from the ashes by Stu Grossman. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This file was derived from various remote-* modules. It is a collection + of generic support functions so GDB can talk directly to a ROM based + monitor. This saves use from having to hack an exception based handler + into existence, and makes for quick porting. + + This module talks to a debug monitor called 'MONITOR', which + We communicate with MONITOR via either a direct serial line, or a TCP + (or possibly TELNET) stream to a terminal multiplexor, + which in turn talks to the target board. */ + +/* FIXME 32x64: This code assumes that registers and addresses are at + most 32 bits long. If they can be larger, you will need to declare + values as LONGEST and use %llx or some such to print values when + building commands to send to the monitor. Since we don't know of + any actual 64-bit targets with ROM monitors that use this code, + it's not an issue right now. -sts 4/18/96 */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include +#include +#include "gdb_string.h" +#include +#include "command.h" +#include "serial.h" +#include "monitor.h" +#include "gdbcmd.h" +#include "inferior.h" +#include "gdb_regex.h" +#include "srec.h" +#include "regcache.h" + +static char *dev_name; +static struct target_ops *targ_ops; + +static void monitor_vsprintf (char *sndbuf, char *pattern, va_list args); + +static int readchar (int timeout); + +static void monitor_fetch_register (int regno); +static void monitor_store_register (int regno); + +static void monitor_printable_string (char *newstr, char *oldstr, int len); +static void monitor_error (char *function, char *message, CORE_ADDR memaddr, int len, char *string, int final_char); +static void monitor_detach (char *args, int from_tty); +static void monitor_resume (ptid_t ptid, int step, enum target_signal sig); +static void monitor_interrupt (int signo); +static void monitor_interrupt_twice (int signo); +static void monitor_interrupt_query (void); +static void monitor_wait_cleanup (void *old_timeout); + +static ptid_t monitor_wait (ptid_t ptid, struct target_waitstatus *status); +static void monitor_fetch_registers (int regno); +static void monitor_store_registers (int regno); +static void monitor_prepare_to_store (void); +static int monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, + struct mem_attrib *attrib, + struct target_ops *target); +static void monitor_files_info (struct target_ops *ops); +static int monitor_insert_breakpoint (CORE_ADDR addr, char *shadow); +static int monitor_remove_breakpoint (CORE_ADDR addr, char *shadow); +static void monitor_kill (void); +static void monitor_load (char *file, int from_tty); +static void monitor_mourn_inferior (void); +static void monitor_stop (void); + +static int monitor_read_memory (CORE_ADDR addr, char *myaddr, int len); +static int monitor_write_memory (CORE_ADDR addr, char *myaddr, int len); +static int monitor_write_memory_bytes (CORE_ADDR addr, char *myaddr, int len); +static int monitor_write_memory_block (CORE_ADDR memaddr, + char *myaddr, int len); +static int monitor_expect_regexp (struct re_pattern_buffer *pat, + char *buf, int buflen); +static void monitor_dump_regs (void); +#if 0 +static int from_hex (int a); +static unsigned long get_hex_word (void); +#endif +static void parse_register_dump (char *, int); + +static struct monitor_ops *current_monitor; + +static int hashmark; /* flag set by "set hash" */ + +static int timeout = 30; + +static int in_monitor_wait = 0; /* Non-zero means we are in monitor_wait() */ + +static void (*ofunc) (); /* Old SIGINT signal handler */ + +static CORE_ADDR *breakaddr; + +/* Descriptor for I/O to remote machine. Initialize it to NULL so + that monitor_open knows that we don't have a file open when the + program starts. */ + +static struct serial *monitor_desc = NULL; + +/* Pointer to regexp pattern matching data */ + +static struct re_pattern_buffer register_pattern; +static char register_fastmap[256]; + +static struct re_pattern_buffer getmem_resp_delim_pattern; +static char getmem_resp_delim_fastmap[256]; + +static struct re_pattern_buffer setmem_resp_delim_pattern; +static char setmem_resp_delim_fastmap[256]; + +static struct re_pattern_buffer setreg_resp_delim_pattern; +static char setreg_resp_delim_fastmap[256]; + +static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when + monitor_wait wakes up. */ + +static int first_time = 0; /* is this the first time we're executing after + gaving created the child proccess? */ + +#define TARGET_BUF_SIZE 2048 + +/* Monitor specific debugging information. Typically only useful to + the developer of a new monitor interface. */ + +static void monitor_debug (const char *fmt, ...) ATTR_FORMAT(printf, 1, 2); + +static int monitor_debug_p = 0; + +/* NOTE: This file alternates between monitor_debug_p and remote_debug + when determining if debug information is printed. Perhaphs this + could be simplified. */ + +static void +monitor_debug (const char *fmt, ...) +{ + if (monitor_debug_p) + { + va_list args; + va_start (args, fmt); + vfprintf_filtered (gdb_stdlog, fmt, args); + va_end (args); + } +} + + +/* Convert a string into a printable representation, Return # byte in + the new string. When LEN is >0 it specifies the size of the + string. Otherwize strlen(oldstr) is used. */ + +static void +monitor_printable_string (char *newstr, char *oldstr, int len) +{ + int ch; + int i; + + if (len <= 0) + len = strlen (oldstr); + + for (i = 0; i < len; i++) + { + ch = oldstr[i]; + switch (ch) + { + default: + if (isprint (ch)) + *newstr++ = ch; + + else + { + sprintf (newstr, "\\x%02x", ch & 0xff); + newstr += 4; + } + break; + + case '\\': + *newstr++ = '\\'; + *newstr++ = '\\'; + break; + case '\b': + *newstr++ = '\\'; + *newstr++ = 'b'; + break; + case '\f': + *newstr++ = '\\'; + *newstr++ = 't'; + break; + case '\n': + *newstr++ = '\\'; + *newstr++ = 'n'; + break; + case '\r': + *newstr++ = '\\'; + *newstr++ = 'r'; + break; + case '\t': + *newstr++ = '\\'; + *newstr++ = 't'; + break; + case '\v': + *newstr++ = '\\'; + *newstr++ = 'v'; + break; + } + } + + *newstr++ = '\0'; +} + +/* Print monitor errors with a string, converting the string to printable + representation. */ + +static void +monitor_error (char *function, char *message, + CORE_ADDR memaddr, int len, char *string, int final_char) +{ + int real_len = (len == 0 && string != (char *) 0) ? strlen (string) : len; + char *safe_string = alloca ((real_len * 4) + 1); + monitor_printable_string (safe_string, string, real_len); + + if (final_char) + error ("%s (0x%s): %s: %s%c", function, paddr_nz (memaddr), message, safe_string, final_char); + else + error ("%s (0x%s): %s: %s", function, paddr_nz (memaddr), message, safe_string); +} + +/* Convert hex digit A to a number. */ + +static int +fromhex (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else if (a >= 'A' && a <= 'F') + return a - 'A' + 10; + else + error ("Invalid hex digit %d", a); +} + +/* monitor_vsprintf - similar to vsprintf but handles 64-bit addresses + + This function exists to get around the problem that many host platforms + don't have a printf that can print 64-bit addresses. The %A format + specification is recognized as a special case, and causes the argument + to be printed as a 64-bit hexadecimal address. + + Only format specifiers of the form "[0-9]*[a-z]" are recognized. + If it is a '%s' format, the argument is a string; otherwise the + argument is assumed to be a long integer. + + %% is also turned into a single %. + */ + +static void +monitor_vsprintf (char *sndbuf, char *pattern, va_list args) +{ + char format[10]; + char fmt; + char *p; + int i; + long arg_int; + CORE_ADDR arg_addr; + char *arg_string; + + for (p = pattern; *p; p++) + { + if (*p == '%') + { + /* Copy the format specifier to a separate buffer. */ + format[0] = *p++; + for (i = 1; *p >= '0' && *p <= '9' && i < (int) sizeof (format) - 2; + i++, p++) + format[i] = *p; + format[i] = fmt = *p; + format[i + 1] = '\0'; + + /* Fetch the next argument and print it. */ + switch (fmt) + { + case '%': + strcpy (sndbuf, "%"); + break; + case 'A': + arg_addr = va_arg (args, CORE_ADDR); + strcpy (sndbuf, paddr_nz (arg_addr)); + break; + case 's': + arg_string = va_arg (args, char *); + sprintf (sndbuf, format, arg_string); + break; + default: + arg_int = va_arg (args, long); + sprintf (sndbuf, format, arg_int); + break; + } + sndbuf += strlen (sndbuf); + } + else + *sndbuf++ = *p; + } + *sndbuf = '\0'; +} + + +/* monitor_printf_noecho -- Send data to monitor, but don't expect an echo. + Works just like printf. */ + +void +monitor_printf_noecho (char *pattern,...) +{ + va_list args; + char sndbuf[2000]; + int len; + + va_start (args, pattern); + + monitor_vsprintf (sndbuf, pattern, args); + + len = strlen (sndbuf); + if (len + 1 > sizeof sndbuf) + internal_error (__FILE__, __LINE__, "failed internal consistency check"); + + if (monitor_debug_p) + { + char *safe_string = (char *) alloca ((strlen (sndbuf) * 4) + 1); + monitor_printable_string (safe_string, sndbuf, 0); + fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string); + } + + monitor_write (sndbuf, len); +} + +/* monitor_printf -- Send data to monitor and check the echo. Works just like + printf. */ + +void +monitor_printf (char *pattern,...) +{ + va_list args; + char sndbuf[2000]; + int len; + + va_start (args, pattern); + + monitor_vsprintf (sndbuf, pattern, args); + + len = strlen (sndbuf); + if (len + 1 > sizeof sndbuf) + internal_error (__FILE__, __LINE__, "failed internal consistency check"); + + if (monitor_debug_p) + { + char *safe_string = (char *) alloca ((len * 4) + 1); + monitor_printable_string (safe_string, sndbuf, 0); + fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string); + } + + monitor_write (sndbuf, len); + + /* We used to expect that the next immediate output was the characters we + just output, but sometimes some extra junk appeared before the characters + we expected, like an extra prompt, or a portmaster sending telnet negotiations. + So, just start searching for what we sent, and skip anything unknown. */ + monitor_debug ("ExpectEcho\n"); + monitor_expect (sndbuf, (char *) 0, 0); +} + + +/* Write characters to the remote system. */ + +void +monitor_write (char *buf, int buflen) +{ + if (serial_write (monitor_desc, buf, buflen)) + fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n", + safe_strerror (errno)); +} + + +/* Read a binary character from the remote system, doing all the fancy + timeout stuff, but without interpreting the character in any way, + and without printing remote debug information. */ + +int +monitor_readchar (void) +{ + int c; + int looping; + + do + { + looping = 0; + c = serial_readchar (monitor_desc, timeout); + + if (c >= 0) + c &= 0xff; /* don't lose bit 7 */ + } + while (looping); + + if (c >= 0) + return c; + + if (c == SERIAL_TIMEOUT) + error ("Timeout reading from remote system."); + + perror_with_name ("remote-monitor"); +} + + +/* Read a character from the remote system, doing all the fancy + timeout stuff. */ + +static int +readchar (int timeout) +{ + int c; + static enum + { + last_random, last_nl, last_cr, last_crnl + } + state = last_random; + int looping; + + do + { + looping = 0; + c = serial_readchar (monitor_desc, timeout); + + if (c >= 0) + { + c &= 0x7f; + /* This seems to interfere with proper function of the + input stream */ + if (monitor_debug_p || remote_debug) + { + char buf[2]; + buf[0] = c; + buf[1] = '\0'; + puts_debug ("read -->", buf, "<--"); + } + + } + + /* Canonicialize \n\r combinations into one \r */ + if ((current_monitor->flags & MO_HANDLE_NL) != 0) + { + if ((c == '\r' && state == last_nl) + || (c == '\n' && state == last_cr)) + { + state = last_crnl; + looping = 1; + } + else if (c == '\r') + state = last_cr; + else if (c != '\n') + state = last_random; + else + { + state = last_nl; + c = '\r'; + } + } + } + while (looping); + + if (c >= 0) + return c; + + if (c == SERIAL_TIMEOUT) +#if 0 + /* I fail to see how detaching here can be useful */ + if (in_monitor_wait) /* Watchdog went off */ + { + target_mourn_inferior (); + error ("GDB serial timeout has expired. Target detached.\n"); + } + else +#endif + error ("Timeout reading from remote system."); + + perror_with_name ("remote-monitor"); +} + +/* Scan input from the remote system, until STRING is found. If BUF is non- + zero, then collect input until we have collected either STRING or BUFLEN-1 + chars. In either case we terminate BUF with a 0. If input overflows BUF + because STRING can't be found, return -1, else return number of chars in BUF + (minus the terminating NUL). Note that in the non-overflow case, STRING + will be at the end of BUF. */ + +int +monitor_expect (char *string, char *buf, int buflen) +{ + char *p = string; + int obuflen = buflen; + int c; + + if (monitor_debug_p) + { + char *safe_string = (char *) alloca ((strlen (string) * 4) + 1); + monitor_printable_string (safe_string, string, 0); + fprintf_unfiltered (gdb_stdlog, "MON Expecting '%s'\n", safe_string); + } + + immediate_quit++; + while (1) + { + if (buf) + { + if (buflen < 2) + { + *buf = '\000'; + immediate_quit--; + return -1; + } + + c = readchar (timeout); + if (c == '\000') + continue; + *buf++ = c; + buflen--; + } + else + c = readchar (timeout); + + /* Don't expect any ^C sent to be echoed */ + + if (*p == '\003' || c == *p) + { + p++; + if (*p == '\0') + { + immediate_quit--; + + if (buf) + { + *buf++ = '\000'; + return obuflen - buflen; + } + else + return 0; + } + } + else + { + /* We got a character that doesn't match the string. We need to + back up p, but how far? If we're looking for "..howdy" and the + monitor sends "...howdy"? There's certainly a match in there, + but when we receive the third ".", we won't find it if we just + restart the matching at the beginning of the string. + + This is a Boyer-Moore kind of situation. We want to reset P to + the end of the longest prefix of STRING that is a suffix of + what we've read so far. In the example above, that would be + ".." --- the longest prefix of "..howdy" that is a suffix of + "...". This longest prefix could be the empty string, if C + is nowhere to be found in STRING. + + If this longest prefix is not the empty string, it must contain + C, so let's search from the end of STRING for instances of C, + and see if the portion of STRING before that is a suffix of + what we read before C. Actually, we can search backwards from + p, since we know no prefix can be longer than that. + + Note that we can use STRING itself, along with C, as a record + of what we've received so far. :) */ + int i; + + for (i = (p - string) - 1; i >= 0; i--) + if (string[i] == c) + { + /* Is this prefix a suffix of what we've read so far? + In other words, does + string[0 .. i-1] == string[p - i, p - 1]? */ + if (! memcmp (string, p - i, i)) + { + p = string + i + 1; + break; + } + } + if (i < 0) + p = string; + } + } +} + +/* Search for a regexp. */ + +static int +monitor_expect_regexp (struct re_pattern_buffer *pat, char *buf, int buflen) +{ + char *mybuf; + char *p; + monitor_debug ("MON Expecting regexp\n"); + if (buf) + mybuf = buf; + else + { + mybuf = alloca (TARGET_BUF_SIZE); + buflen = TARGET_BUF_SIZE; + } + + p = mybuf; + while (1) + { + int retval; + + if (p - mybuf >= buflen) + { /* Buffer about to overflow */ + +/* On overflow, we copy the upper half of the buffer to the lower half. Not + great, but it usually works... */ + + memcpy (mybuf, mybuf + buflen / 2, buflen / 2); + p = mybuf + buflen / 2; + } + + *p++ = readchar (timeout); + + retval = re_search (pat, mybuf, p - mybuf, 0, p - mybuf, NULL); + if (retval >= 0) + return 1; + } +} + +/* Keep discarding input until we see the MONITOR prompt. + + The convention for dealing with the prompt is that you + o give your command + o *then* wait for the prompt. + + Thus the last thing that a procedure does with the serial line will + be an monitor_expect_prompt(). Exception: monitor_resume does not + wait for the prompt, because the terminal is being handed over to + the inferior. However, the next thing which happens after that is + a monitor_wait which does wait for the prompt. Note that this + includes abnormal exit, e.g. error(). This is necessary to prevent + getting into states from which we can't recover. */ + +int +monitor_expect_prompt (char *buf, int buflen) +{ + monitor_debug ("MON Expecting prompt\n"); + return monitor_expect (current_monitor->prompt, buf, buflen); +} + +/* Get N 32-bit words from remote, each preceded by a space, and put + them in registers starting at REGNO. */ + +#if 0 +static unsigned long +get_hex_word (void) +{ + unsigned long val; + int i; + int ch; + + do + ch = readchar (timeout); + while (isspace (ch)); + + val = from_hex (ch); + + for (i = 7; i >= 1; i--) + { + ch = readchar (timeout); + if (!isxdigit (ch)) + break; + val = (val << 4) | from_hex (ch); + } + + return val; +} +#endif + +static void +compile_pattern (char *pattern, struct re_pattern_buffer *compiled_pattern, + char *fastmap) +{ + int tmp; + const char *val; + + compiled_pattern->fastmap = fastmap; + + tmp = re_set_syntax (RE_SYNTAX_EMACS); + val = re_compile_pattern (pattern, + strlen (pattern), + compiled_pattern); + re_set_syntax (tmp); + + if (val) + error ("compile_pattern: Can't compile pattern string `%s': %s!", pattern, val); + + if (fastmap) + re_compile_fastmap (compiled_pattern); +} + +/* Open a connection to a remote debugger. NAME is the filename used + for communication. */ + +void +monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty) +{ + char *name; + char **p; + + if (mon_ops->magic != MONITOR_OPS_MAGIC) + error ("Magic number of monitor_ops struct wrong."); + + targ_ops = mon_ops->target; + name = targ_ops->to_shortname; + + if (!args) + error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\ +`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name); + + target_preopen (from_tty); + + /* Setup pattern for register dump */ + + if (mon_ops->register_pattern) + compile_pattern (mon_ops->register_pattern, ®ister_pattern, + register_fastmap); + + if (mon_ops->getmem.resp_delim) + compile_pattern (mon_ops->getmem.resp_delim, &getmem_resp_delim_pattern, + getmem_resp_delim_fastmap); + + if (mon_ops->setmem.resp_delim) + compile_pattern (mon_ops->setmem.resp_delim, &setmem_resp_delim_pattern, + setmem_resp_delim_fastmap); + + if (mon_ops->setreg.resp_delim) + compile_pattern (mon_ops->setreg.resp_delim, &setreg_resp_delim_pattern, + setreg_resp_delim_fastmap); + + unpush_target (targ_ops); + + if (dev_name) + xfree (dev_name); + dev_name = xstrdup (args); + + monitor_desc = serial_open (dev_name); + + if (!monitor_desc) + perror_with_name (dev_name); + + if (baud_rate != -1) + { + if (serial_setbaudrate (monitor_desc, baud_rate)) + { + serial_close (monitor_desc); + perror_with_name (dev_name); + } + } + + serial_raw (monitor_desc); + + serial_flush_input (monitor_desc); + + /* some systems only work with 2 stop bits */ + + serial_setstopbits (monitor_desc, mon_ops->stopbits); + + current_monitor = mon_ops; + + /* See if we can wake up the monitor. First, try sending a stop sequence, + then send the init strings. Last, remove all breakpoints. */ + + if (current_monitor->stop) + { + monitor_stop (); + if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0) + { + monitor_debug ("EXP Open echo\n"); + monitor_expect_prompt (NULL, 0); + } + } + + /* wake up the monitor and see if it's alive */ + for (p = mon_ops->init; *p != NULL; p++) + { + /* Some of the characters we send may not be echoed, + but we hope to get a prompt at the end of it all. */ + + if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0) + monitor_printf (*p); + else + monitor_printf_noecho (*p); + monitor_expect_prompt (NULL, 0); + } + + serial_flush_input (monitor_desc); + + /* Alloc breakpoints */ + if (mon_ops->set_break != NULL) + { + if (mon_ops->num_breakpoints == 0) + mon_ops->num_breakpoints = 8; + + breakaddr = (CORE_ADDR *) xmalloc (mon_ops->num_breakpoints * sizeof (CORE_ADDR)); + memset (breakaddr, 0, mon_ops->num_breakpoints * sizeof (CORE_ADDR)); + } + + /* Remove all breakpoints */ + + if (mon_ops->clr_all_break) + { + monitor_printf (mon_ops->clr_all_break); + monitor_expect_prompt (NULL, 0); + } + + if (from_tty) + printf_unfiltered ("Remote target %s connected to %s\n", name, dev_name); + + push_target (targ_ops); + + inferior_ptid = pid_to_ptid (42000); /* Make run command think we are busy... */ + + /* Give monitor_wait something to read */ + + monitor_printf (current_monitor->line_term); + + start_remote (); +} + +/* Close out all files and local state before this target loses + control. */ + +void +monitor_close (int quitting) +{ + if (monitor_desc) + serial_close (monitor_desc); + + /* Free breakpoint memory */ + if (breakaddr != NULL) + { + xfree (breakaddr); + breakaddr = NULL; + } + + monitor_desc = NULL; +} + +/* Terminate the open connection to the remote debugger. Use this + when you want to detach and do something else with your gdb. */ + +static void +monitor_detach (char *args, int from_tty) +{ + pop_target (); /* calls monitor_close to do the real work */ + if (from_tty) + printf_unfiltered ("Ending remote %s debugging\n", target_shortname); +} + +/* Convert VALSTR into the target byte-ordered value of REGNO and store it. */ + +char * +monitor_supply_register (int regno, char *valstr) +{ + ULONGEST val; + unsigned char regbuf[MAX_REGISTER_SIZE]; + char *p; + + val = 0; + p = valstr; + while (p && *p != '\0') + { + if (*p == '\r' || *p == '\n') + { + while (*p != '\0') + p++; + break; + } + if (isspace (*p)) + { + p++; + continue; + } + if (!isxdigit (*p) && *p != 'x') + { + break; + } + + val <<= 4; + val += fromhex (*p++); + } + monitor_debug ("Supplying Register %d %s\n", regno, valstr); + + if (val == 0 && valstr == p) + error ("monitor_supply_register (%d): bad value from monitor: %s.", + regno, valstr); + + /* supply register stores in target byte order, so swap here */ + + store_unsigned_integer (regbuf, DEPRECATED_REGISTER_RAW_SIZE (regno), val); + + supply_register (regno, regbuf); + + return p; +} + +/* Tell the remote machine to resume. */ + +static void +monitor_resume (ptid_t ptid, int step, enum target_signal sig) +{ + /* Some monitors require a different command when starting a program */ + monitor_debug ("MON resume\n"); + if (current_monitor->flags & MO_RUN_FIRST_TIME && first_time == 1) + { + first_time = 0; + monitor_printf ("run\r"); + if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT) + dump_reg_flag = 1; + return; + } + if (step) + monitor_printf (current_monitor->step); + else + { + if (current_monitor->continue_hook) + (*current_monitor->continue_hook) (); + else + monitor_printf (current_monitor->cont); + if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT) + dump_reg_flag = 1; + } +} + +/* Parse the output of a register dump command. A monitor specific + regexp is used to extract individual register descriptions of the + form REG=VAL. Each description is split up into a name and a value + string which are passed down to monitor specific code. */ + +static void +parse_register_dump (char *buf, int len) +{ + monitor_debug ("MON Parsing register dump\n"); + while (1) + { + int regnamelen, vallen; + char *regname, *val; + /* Element 0 points to start of register name, and element 1 + points to the start of the register value. */ + struct re_registers register_strings; + + memset (®ister_strings, 0, sizeof (struct re_registers)); + + if (re_search (®ister_pattern, buf, len, 0, len, + ®ister_strings) == -1) + break; + + regnamelen = register_strings.end[1] - register_strings.start[1]; + regname = buf + register_strings.start[1]; + vallen = register_strings.end[2] - register_strings.start[2]; + val = buf + register_strings.start[2]; + + current_monitor->supply_register (regname, regnamelen, val, vallen); + + buf += register_strings.end[0]; + len -= register_strings.end[0]; + } +} + +/* Send ^C to target to halt it. Target will respond, and send us a + packet. */ + +static void +monitor_interrupt (int signo) +{ + /* If this doesn't work, try more severe steps. */ + signal (signo, monitor_interrupt_twice); + + if (monitor_debug_p || remote_debug) + fprintf_unfiltered (gdb_stdlog, "monitor_interrupt called\n"); + + target_stop (); +} + +/* The user typed ^C twice. */ + +static void +monitor_interrupt_twice (int signo) +{ + signal (signo, ofunc); + + monitor_interrupt_query (); + + signal (signo, monitor_interrupt); +} + +/* Ask the user what to do when an interrupt is received. */ + +static void +monitor_interrupt_query (void) +{ + target_terminal_ours (); + + if (query ("Interrupted while waiting for the program.\n\ +Give up (and stop debugging it)? ")) + { + target_mourn_inferior (); + throw_exception (RETURN_QUIT); + } + + target_terminal_inferior (); +} + +static void +monitor_wait_cleanup (void *old_timeout) +{ + timeout = *(int *) old_timeout; + signal (SIGINT, ofunc); + in_monitor_wait = 0; +} + + + +static void +monitor_wait_filter (char *buf, + int bufmax, + int *ext_resp_len, + struct target_waitstatus *status) +{ + int resp_len; + do + { + resp_len = monitor_expect_prompt (buf, bufmax); + *ext_resp_len = resp_len; + + if (resp_len <= 0) + fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf); + } + while (resp_len < 0); + + /* Print any output characters that were preceded by ^O. */ + /* FIXME - This would be great as a user settabgle flag */ + if (monitor_debug_p || remote_debug + || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT) + { + int i; + + for (i = 0; i < resp_len - 1; i++) + if (buf[i] == 0x0f) + putchar_unfiltered (buf[++i]); + } +} + + + +/* Wait until the remote machine stops, then return, storing status in + status just as `wait' would. */ + +static ptid_t +monitor_wait (ptid_t ptid, struct target_waitstatus *status) +{ + int old_timeout = timeout; + char buf[TARGET_BUF_SIZE]; + int resp_len; + struct cleanup *old_chain; + + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = 0; + + old_chain = make_cleanup (monitor_wait_cleanup, &old_timeout); + monitor_debug ("MON wait\n"); + +#if 0 + /* This is somthing other than a maintenance command */ + in_monitor_wait = 1; + timeout = watchdog > 0 ? watchdog : -1; +#else + timeout = -1; /* Don't time out -- user program is running. */ +#endif + + ofunc = (void (*)()) signal (SIGINT, monitor_interrupt); + + if (current_monitor->wait_filter) + (*current_monitor->wait_filter) (buf, sizeof (buf), &resp_len, status); + else + monitor_wait_filter (buf, sizeof (buf), &resp_len, status); + +#if 0 /* Transferred to monitor wait filter */ + do + { + resp_len = monitor_expect_prompt (buf, sizeof (buf)); + + if (resp_len <= 0) + fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf); + } + while (resp_len < 0); + + /* Print any output characters that were preceded by ^O. */ + /* FIXME - This would be great as a user settabgle flag */ + if (monitor_debug_p || remote_debug + || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT) + { + int i; + + for (i = 0; i < resp_len - 1; i++) + if (buf[i] == 0x0f) + putchar_unfiltered (buf[++i]); + } +#endif + + signal (SIGINT, ofunc); + + timeout = old_timeout; +#if 0 + if (dump_reg_flag && current_monitor->dump_registers) + { + dump_reg_flag = 0; + monitor_printf (current_monitor->dump_registers); + resp_len = monitor_expect_prompt (buf, sizeof (buf)); + } + + if (current_monitor->register_pattern) + parse_register_dump (buf, resp_len); +#else + monitor_debug ("Wait fetching registers after stop\n"); + monitor_dump_regs (); +#endif + + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = TARGET_SIGNAL_TRAP; + + discard_cleanups (old_chain); + + in_monitor_wait = 0; + + return inferior_ptid; +} + +/* Fetch register REGNO, or all registers if REGNO is -1. Returns + errno value. */ + +static void +monitor_fetch_register (int regno) +{ + const char *name; + char *zerobuf; + char *regbuf; + int i; + + regbuf = alloca (MAX_REGISTER_SIZE * 2 + 1); + zerobuf = alloca (MAX_REGISTER_SIZE); + memset (zerobuf, 0, MAX_REGISTER_SIZE); + + if (current_monitor->regname != NULL) + name = current_monitor->regname (regno); + else + name = current_monitor->regnames[regno]; + monitor_debug ("MON fetchreg %d '%s'\n", regno, name ? name : "(null name)"); + + if (!name || (*name == '\0')) + { + monitor_debug ("No register known for %d\n", regno); + supply_register (regno, zerobuf); + return; + } + + /* send the register examine command */ + + monitor_printf (current_monitor->getreg.cmd, name); + + /* If RESP_DELIM is specified, we search for that as a leading + delimiter for the register value. Otherwise, we just start + searching from the start of the buf. */ + + if (current_monitor->getreg.resp_delim) + { + monitor_debug ("EXP getreg.resp_delim\n"); + monitor_expect (current_monitor->getreg.resp_delim, NULL, 0); + /* Handle case of first 32 registers listed in pairs. */ + if (current_monitor->flags & MO_32_REGS_PAIRED + && (regno & 1) != 0 && regno < 32) + { + monitor_debug ("EXP getreg.resp_delim\n"); + monitor_expect (current_monitor->getreg.resp_delim, NULL, 0); + } + } + + /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */ + if (current_monitor->flags & MO_HEX_PREFIX) + { + int c; + c = readchar (timeout); + while (c == ' ') + c = readchar (timeout); + if ((c == '0') && ((c = readchar (timeout)) == 'x')) + ; + else + error ("Bad value returned from monitor while fetching register %x.", + regno); + } + + /* Read upto the maximum number of hex digits for this register, skipping + spaces, but stop reading if something else is seen. Some monitors + like to drop leading zeros. */ + + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno) * 2; i++) + { + int c; + c = readchar (timeout); + while (c == ' ') + c = readchar (timeout); + + if (!isxdigit (c)) + break; + + regbuf[i] = c; + } + + regbuf[i] = '\000'; /* terminate the number */ + monitor_debug ("REGVAL '%s'\n", regbuf); + + /* If TERM is present, we wait for that to show up. Also, (if TERM + is present), we will send TERM_CMD if that is present. In any + case, we collect all of the output into buf, and then wait for + the normal prompt. */ + + if (current_monitor->getreg.term) + { + monitor_debug ("EXP getreg.term\n"); + monitor_expect (current_monitor->getreg.term, NULL, 0); /* get response */ + } + + if (current_monitor->getreg.term_cmd) + { + monitor_debug ("EMIT getreg.term.cmd\n"); + monitor_printf (current_monitor->getreg.term_cmd); + } + if (!current_monitor->getreg.term || /* Already expected or */ + current_monitor->getreg.term_cmd) /* ack expected */ + monitor_expect_prompt (NULL, 0); /* get response */ + + monitor_supply_register (regno, regbuf); +} + +/* Sometimes, it takes several commands to dump the registers */ +/* This is a primitive for use by variations of monitor interfaces in + case they need to compose the operation. + */ +int +monitor_dump_reg_block (char *block_cmd) +{ + char buf[TARGET_BUF_SIZE]; + int resp_len; + monitor_printf (block_cmd); + resp_len = monitor_expect_prompt (buf, sizeof (buf)); + parse_register_dump (buf, resp_len); + return 1; +} + + +/* Read the remote registers into the block regs. */ +/* Call the specific function if it has been provided */ + +static void +monitor_dump_regs (void) +{ + char buf[TARGET_BUF_SIZE]; + int resp_len; + if (current_monitor->dumpregs) + (*(current_monitor->dumpregs)) (); /* call supplied function */ + else if (current_monitor->dump_registers) /* default version */ + { + monitor_printf (current_monitor->dump_registers); + resp_len = monitor_expect_prompt (buf, sizeof (buf)); + parse_register_dump (buf, resp_len); + } + else + internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Need some way to read registers */ +} + +static void +monitor_fetch_registers (int regno) +{ + monitor_debug ("MON fetchregs\n"); + if (current_monitor->getreg.cmd) + { + if (regno >= 0) + { + monitor_fetch_register (regno); + return; + } + + for (regno = 0; regno < NUM_REGS; regno++) + monitor_fetch_register (regno); + } + else + { + monitor_dump_regs (); + } +} + +/* Store register REGNO, or all if REGNO == 0. Return errno value. */ + +static void +monitor_store_register (int regno) +{ + const char *name; + ULONGEST val; + + if (current_monitor->regname != NULL) + name = current_monitor->regname (regno); + else + name = current_monitor->regnames[regno]; + + if (!name || (*name == '\0')) + { + monitor_debug ("MON Cannot store unknown register\n"); + return; + } + + val = read_register (regno); + monitor_debug ("MON storeg %d %s\n", regno, + phex (val, DEPRECATED_REGISTER_RAW_SIZE (regno))); + + /* send the register deposit command */ + + if (current_monitor->flags & MO_REGISTER_VALUE_FIRST) + monitor_printf (current_monitor->setreg.cmd, val, name); + else if (current_monitor->flags & MO_SETREG_INTERACTIVE) + monitor_printf (current_monitor->setreg.cmd, name); + else + monitor_printf (current_monitor->setreg.cmd, name, val); + + if (current_monitor->setreg.resp_delim) + { + monitor_debug ("EXP setreg.resp_delim\n"); + monitor_expect_regexp (&setreg_resp_delim_pattern, NULL, 0); + if (current_monitor->flags & MO_SETREG_INTERACTIVE) + monitor_printf ("%s\r", paddr_nz (val)); + } + if (current_monitor->setreg.term) + { + monitor_debug ("EXP setreg.term\n"); + monitor_expect (current_monitor->setreg.term, NULL, 0); + if (current_monitor->flags & MO_SETREG_INTERACTIVE) + monitor_printf ("%s\r", paddr_nz (val)); + monitor_expect_prompt (NULL, 0); + } + else + monitor_expect_prompt (NULL, 0); + if (current_monitor->setreg.term_cmd) /* Mode exit required */ + { + monitor_debug ("EXP setreg_termcmd\n"); + monitor_printf ("%s", current_monitor->setreg.term_cmd); + monitor_expect_prompt (NULL, 0); + } +} /* monitor_store_register */ + +/* Store the remote registers. */ + +static void +monitor_store_registers (int regno) +{ + if (regno >= 0) + { + monitor_store_register (regno); + return; + } + + for (regno = 0; regno < NUM_REGS; regno++) + monitor_store_register (regno); +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +monitor_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ +} + +static void +monitor_files_info (struct target_ops *ops) +{ + printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baud_rate); +} + +static int +monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + unsigned int val, hostval; + char *cmd; + int i; + + monitor_debug ("MON write %d %s\n", len, paddr (memaddr)); + + if (current_monitor->flags & MO_ADDR_BITS_REMOVE) + memaddr = ADDR_BITS_REMOVE (memaddr); + + /* Use memory fill command for leading 0 bytes. */ + + if (current_monitor->fill) + { + for (i = 0; i < len; i++) + if (myaddr[i] != 0) + break; + + if (i > 4) /* More than 4 zeros is worth doing */ + { + monitor_debug ("MON FILL %d\n", i); + if (current_monitor->flags & MO_FILL_USES_ADDR) + monitor_printf (current_monitor->fill, memaddr, (memaddr + i) - 1, 0); + else + monitor_printf (current_monitor->fill, memaddr, i, 0); + + monitor_expect_prompt (NULL, 0); + + return i; + } + } + +#if 0 + /* Can't actually use long longs if VAL is an int (nice idea, though). */ + if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->setmem.cmdll) + { + len = 8; + cmd = current_monitor->setmem.cmdll; + } + else +#endif + if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->setmem.cmdl) + { + len = 4; + cmd = current_monitor->setmem.cmdl; + } + else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->setmem.cmdw) + { + len = 2; + cmd = current_monitor->setmem.cmdw; + } + else + { + len = 1; + cmd = current_monitor->setmem.cmdb; + } + + val = extract_unsigned_integer (myaddr, len); + + if (len == 4) + { + hostval = *(unsigned int *) myaddr; + monitor_debug ("Hostval(%08x) val(%08x)\n", hostval, val); + } + + + if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM) + monitor_printf_noecho (cmd, memaddr, val); + else if (current_monitor->flags & MO_SETMEM_INTERACTIVE) + { + + monitor_printf_noecho (cmd, memaddr); + + if (current_monitor->setmem.resp_delim) + { + monitor_debug ("EXP setmem.resp_delim"); + monitor_expect_regexp (&setmem_resp_delim_pattern, NULL, 0); + monitor_printf ("%x\r", val); + } + if (current_monitor->setmem.term) + { + monitor_debug ("EXP setmem.term"); + monitor_expect (current_monitor->setmem.term, NULL, 0); + monitor_printf ("%x\r", val); + } + if (current_monitor->setmem.term_cmd) + { /* Emit this to get out of the memory editing state */ + monitor_printf ("%s", current_monitor->setmem.term_cmd); + /* Drop through to expecting a prompt */ + } + } + else + monitor_printf (cmd, memaddr, val); + + monitor_expect_prompt (NULL, 0); + + return len; +} + + +static int +monitor_write_memory_bytes (CORE_ADDR memaddr, char *myaddr, int len) +{ + unsigned char val; + int written = 0; + if (len == 0) + return 0; + /* Enter the sub mode */ + monitor_printf (current_monitor->setmem.cmdb, memaddr); + monitor_expect_prompt (NULL, 0); + while (len) + { + val = *myaddr; + monitor_printf ("%x\r", val); + myaddr++; + memaddr++; + written++; + /* If we wanted to, here we could validate the address */ + monitor_expect_prompt (NULL, 0); + len--; + } + /* Now exit the sub mode */ + monitor_printf (current_monitor->getreg.term_cmd); + monitor_expect_prompt (NULL, 0); + return written; +} + + +static void +longlongendswap (unsigned char *a) +{ + int i, j; + unsigned char x; + i = 0; + j = 7; + while (i < 4) + { + x = *(a + i); + *(a + i) = *(a + j); + *(a + j) = x; + i++, j--; + } +} +/* Format 32 chars of long long value, advance the pointer */ +static char *hexlate = "0123456789abcdef"; +static char * +longlong_hexchars (unsigned long long value, + char *outbuff) +{ + if (value == 0) + { + *outbuff++ = '0'; + return outbuff; + } + else + { + static unsigned char disbuf[8]; /* disassembly buffer */ + unsigned char *scan, *limit; /* loop controls */ + unsigned char c, nib; + int leadzero = 1; + scan = disbuf; + limit = scan + 8; + { + unsigned long long *dp; + dp = (unsigned long long *) scan; + *dp = value; + } + longlongendswap (disbuf); /* FIXME: ONly on big endian hosts */ + while (scan < limit) + { + c = *scan++; /* a byte of our long long value */ + if (leadzero) + { + if (c == 0) + continue; + else + leadzero = 0; /* henceforth we print even zeroes */ + } + nib = c >> 4; /* high nibble bits */ + *outbuff++ = hexlate[nib]; + nib = c & 0x0f; /* low nibble bits */ + *outbuff++ = hexlate[nib]; + } + return outbuff; + } +} /* longlong_hexchars */ + + + +/* I am only going to call this when writing virtual byte streams. + Which possably entails endian conversions + */ +static int +monitor_write_memory_longlongs (CORE_ADDR memaddr, char *myaddr, int len) +{ + static char hexstage[20]; /* At least 16 digits required, plus null */ + char *endstring; + long long *llptr; + long long value; + int written = 0; + llptr = (unsigned long long *) myaddr; + if (len == 0) + return 0; + monitor_printf (current_monitor->setmem.cmdll, memaddr); + monitor_expect_prompt (NULL, 0); + while (len >= 8) + { + value = *llptr; + endstring = longlong_hexchars (*llptr, hexstage); + *endstring = '\0'; /* NUll terminate for printf */ + monitor_printf ("%s\r", hexstage); + llptr++; + memaddr += 8; + written += 8; + /* If we wanted to, here we could validate the address */ + monitor_expect_prompt (NULL, 0); + len -= 8; + } + /* Now exit the sub mode */ + monitor_printf (current_monitor->getreg.term_cmd); + monitor_expect_prompt (NULL, 0); + return written; +} /* */ + + + +/* ----- MONITOR_WRITE_MEMORY_BLOCK ---------------------------- */ +/* This is for the large blocks of memory which may occur in downloading. + And for monitors which use interactive entry, + And for monitors which do not have other downloading methods. + Without this, we will end up calling monitor_write_memory many times + and do the entry and exit of the sub mode many times + This currently assumes... + MO_SETMEM_INTERACTIVE + ! MO_NO_ECHO_ON_SETMEM + To use this, the you have to patch the monitor_cmds block with + this function. Otherwise, its not tuned up for use by all + monitor variations. + */ + +static int +monitor_write_memory_block (CORE_ADDR memaddr, char *myaddr, int len) +{ + int written; + written = 0; + /* FIXME: This would be a good place to put the zero test */ +#if 1 + if ((len > 8) && (((len & 0x07)) == 0) && current_monitor->setmem.cmdll) + { + return monitor_write_memory_longlongs (memaddr, myaddr, len); + } +#endif + written = monitor_write_memory_bytes (memaddr, myaddr, len); + return written; +} + +/* This is an alternate form of monitor_read_memory which is used for monitors + which can only read a single byte/word/etc. at a time. */ + +static int +monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len) +{ + unsigned int val; + char membuf[sizeof (int) * 2 + 1]; + char *p; + char *cmd; + + monitor_debug ("MON read single\n"); +#if 0 + /* Can't actually use long longs (nice idea, though). In fact, the + call to strtoul below will fail if it tries to convert a value + that's too big to fit in a long. */ + if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->getmem.cmdll) + { + len = 8; + cmd = current_monitor->getmem.cmdll; + } + else +#endif + if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->getmem.cmdl) + { + len = 4; + cmd = current_monitor->getmem.cmdl; + } + else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->getmem.cmdw) + { + len = 2; + cmd = current_monitor->getmem.cmdw; + } + else + { + len = 1; + cmd = current_monitor->getmem.cmdb; + } + + /* Send the examine command. */ + + monitor_printf (cmd, memaddr); + + /* If RESP_DELIM is specified, we search for that as a leading + delimiter for the memory value. Otherwise, we just start + searching from the start of the buf. */ + + if (current_monitor->getmem.resp_delim) + { + monitor_debug ("EXP getmem.resp_delim\n"); + monitor_expect_regexp (&getmem_resp_delim_pattern, NULL, 0); + } + + /* Now, read the appropriate number of hex digits for this loc, + skipping spaces. */ + + /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set. */ + if (current_monitor->flags & MO_HEX_PREFIX) + { + int c; + + c = readchar (timeout); + while (c == ' ') + c = readchar (timeout); + if ((c == '0') && ((c = readchar (timeout)) == 'x')) + ; + else + monitor_error ("monitor_read_memory_single", + "bad response from monitor", + memaddr, 0, NULL, 0); + } + + { + int i; + for (i = 0; i < len * 2; i++) + { + int c; + + while (1) + { + c = readchar (timeout); + if (isxdigit (c)) + break; + if (c == ' ') + continue; + + monitor_error ("monitor_read_memory_single", + "bad response from monitor", + memaddr, i, membuf, 0); + } + membuf[i] = c; + } + membuf[i] = '\000'; /* terminate the number */ + } + +/* If TERM is present, we wait for that to show up. Also, (if TERM is + present), we will send TERM_CMD if that is present. In any case, we collect + all of the output into buf, and then wait for the normal prompt. */ + + if (current_monitor->getmem.term) + { + monitor_expect (current_monitor->getmem.term, NULL, 0); /* get response */ + + if (current_monitor->getmem.term_cmd) + { + monitor_printf (current_monitor->getmem.term_cmd); + monitor_expect_prompt (NULL, 0); + } + } + else + monitor_expect_prompt (NULL, 0); /* get response */ + + p = membuf; + val = strtoul (membuf, &p, 16); + + if (val == 0 && membuf == p) + monitor_error ("monitor_read_memory_single", + "bad value from monitor", + memaddr, 0, membuf, 0); + + /* supply register stores in target byte order, so swap here */ + + store_unsigned_integer (myaddr, len, val); + + return len; +} + +/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's + memory at MEMADDR. Returns length moved. Currently, we do no more + than 16 bytes at a time. */ + +static int +monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + unsigned int val; + char buf[512]; + char *p, *p1; + int resp_len; + int i; + CORE_ADDR dumpaddr; + + if (len <= 0) + { + monitor_debug ("Zero length call to monitor_read_memory\n"); + return 0; + } + + monitor_debug ("MON read block ta(%s) ha(%lx) %d\n", + paddr_nz (memaddr), (long) myaddr, len); + + if (current_monitor->flags & MO_ADDR_BITS_REMOVE) + memaddr = ADDR_BITS_REMOVE (memaddr); + + if (current_monitor->flags & MO_GETMEM_READ_SINGLE) + return monitor_read_memory_single (memaddr, myaddr, len); + + len = min (len, 16); + + /* Some dumpers align the first data with the preceeding 16 + byte boundary. Some print blanks and start at the + requested boundary. EXACT_DUMPADDR + */ + + dumpaddr = (current_monitor->flags & MO_EXACT_DUMPADDR) + ? memaddr : memaddr & ~0x0f; + + /* See if xfer would cross a 16 byte boundary. If so, clip it. */ + if (((memaddr ^ (memaddr + len - 1)) & ~0xf) != 0) + len = ((memaddr + len) & ~0xf) - memaddr; + + /* send the memory examine command */ + + if (current_monitor->flags & MO_GETMEM_NEEDS_RANGE) + monitor_printf (current_monitor->getmem.cmdb, memaddr, memaddr + len); + else if (current_monitor->flags & MO_GETMEM_16_BOUNDARY) + monitor_printf (current_monitor->getmem.cmdb, dumpaddr); + else + monitor_printf (current_monitor->getmem.cmdb, memaddr, len); + + /* If TERM is present, we wait for that to show up. Also, (if TERM + is present), we will send TERM_CMD if that is present. In any + case, we collect all of the output into buf, and then wait for + the normal prompt. */ + + if (current_monitor->getmem.term) + { + resp_len = monitor_expect (current_monitor->getmem.term, buf, sizeof buf); /* get response */ + + if (resp_len <= 0) + monitor_error ("monitor_read_memory", + "excessive response from monitor", + memaddr, resp_len, buf, 0); + + if (current_monitor->getmem.term_cmd) + { + serial_write (monitor_desc, current_monitor->getmem.term_cmd, + strlen (current_monitor->getmem.term_cmd)); + monitor_expect_prompt (NULL, 0); + } + } + else + resp_len = monitor_expect_prompt (buf, sizeof buf); /* get response */ + + p = buf; + + /* If RESP_DELIM is specified, we search for that as a leading + delimiter for the values. Otherwise, we just start searching + from the start of the buf. */ + + if (current_monitor->getmem.resp_delim) + { + int retval, tmp; + struct re_registers resp_strings; + monitor_debug ("MON getmem.resp_delim %s\n", current_monitor->getmem.resp_delim); + + memset (&resp_strings, 0, sizeof (struct re_registers)); + tmp = strlen (p); + retval = re_search (&getmem_resp_delim_pattern, p, tmp, 0, tmp, + &resp_strings); + + if (retval < 0) + monitor_error ("monitor_read_memory", + "bad response from monitor", + memaddr, resp_len, buf, 0); + + p += resp_strings.end[0]; +#if 0 + p = strstr (p, current_monitor->getmem.resp_delim); + if (!p) + monitor_error ("monitor_read_memory", + "bad response from monitor", + memaddr, resp_len, buf, 0); + p += strlen (current_monitor->getmem.resp_delim); +#endif + } + monitor_debug ("MON scanning %d ,%lx '%s'\n", len, (long) p, p); + if (current_monitor->flags & MO_GETMEM_16_BOUNDARY) + { + char c; + int fetched = 0; + i = len; + c = *p; + + + while (!(c == '\000' || c == '\n' || c == '\r') && i > 0) + { + if (isxdigit (c)) + { + if ((dumpaddr >= memaddr) && (i > 0)) + { + val = fromhex (c) * 16 + fromhex (*(p + 1)); + *myaddr++ = val; + if (monitor_debug_p || remote_debug) + fprintf_unfiltered (gdb_stdlog, "[%02x]", val); + --i; + fetched++; + } + ++dumpaddr; + ++p; + } + ++p; /* skip a blank or other non hex char */ + c = *p; + } + if (fetched == 0) + error ("Failed to read via monitor"); + if (monitor_debug_p || remote_debug) + fprintf_unfiltered (gdb_stdlog, "\n"); + return fetched; /* Return the number of bytes actually read */ + } + monitor_debug ("MON scanning bytes\n"); + + for (i = len; i > 0; i--) + { + /* Skip non-hex chars, but bomb on end of string and newlines */ + + while (1) + { + if (isxdigit (*p)) + break; + + if (*p == '\000' || *p == '\n' || *p == '\r') + monitor_error ("monitor_read_memory", + "badly terminated response from monitor", + memaddr, resp_len, buf, 0); + p++; + } + + val = strtoul (p, &p1, 16); + + if (val == 0 && p == p1) + monitor_error ("monitor_read_memory", + "bad value from monitor", + memaddr, resp_len, buf, 0); + + *myaddr++ = val; + + if (i == 1) + break; + + p = p1; + } + + return len; +} + +/* Transfer LEN bytes between target address MEMADDR and GDB address + MYADDR. Returns 0 for success, errno code for failure. TARGET is + unused. */ + +static int +monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, struct target_ops *target) +{ + int res; + + if (write) + { + if (current_monitor->flags & MO_HAS_BLOCKWRITES) + res = monitor_write_memory_block(memaddr, myaddr, len); + else + res = monitor_write_memory(memaddr, myaddr, len); + } + else + { + res = monitor_read_memory(memaddr, myaddr, len); + } + + return res; +} + +static void +monitor_kill (void) +{ + return; /* ignore attempts to kill target system */ +} + +/* All we actually do is set the PC to the start address of exec_bfd, and start + the program at that point. */ + +static void +monitor_create_inferior (char *exec_file, char *args, char **env) +{ + if (args && (*args != '\000')) + error ("Args are not supported by the monitor."); + + first_time = 1; + clear_proceed_status (); + proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0); +} + +/* Clean up when a program exits. + The program actually lives on in the remote processor's RAM, and may be + run again without a download. Don't leave it full of breakpoint + instructions. */ + +static void +monitor_mourn_inferior (void) +{ + unpush_target (targ_ops); + generic_mourn_inferior (); /* Do all the proper things now */ +} + +/* Tell the monitor to add a breakpoint. */ + +static int +monitor_insert_breakpoint (CORE_ADDR addr, char *shadow) +{ + int i; + const unsigned char *bp; + int bplen; + + monitor_debug ("MON inst bkpt %s\n", paddr (addr)); + if (current_monitor->set_break == NULL) + error ("No set_break defined for this monitor"); + + if (current_monitor->flags & MO_ADDR_BITS_REMOVE) + addr = ADDR_BITS_REMOVE (addr); + + /* Determine appropriate breakpoint size for this address. */ + bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen); + + for (i = 0; i < current_monitor->num_breakpoints; i++) + { + if (breakaddr[i] == 0) + { + breakaddr[i] = addr; + monitor_read_memory (addr, shadow, bplen); + monitor_printf (current_monitor->set_break, addr); + monitor_expect_prompt (NULL, 0); + return 0; + } + } + + error ("Too many breakpoints (> %d) for monitor.", current_monitor->num_breakpoints); +} + +/* Tell the monitor to remove a breakpoint. */ + +static int +monitor_remove_breakpoint (CORE_ADDR addr, char *shadow) +{ + int i; + + monitor_debug ("MON rmbkpt %s\n", paddr (addr)); + if (current_monitor->clr_break == NULL) + error ("No clr_break defined for this monitor"); + + if (current_monitor->flags & MO_ADDR_BITS_REMOVE) + addr = ADDR_BITS_REMOVE (addr); + + for (i = 0; i < current_monitor->num_breakpoints; i++) + { + if (breakaddr[i] == addr) + { + breakaddr[i] = 0; + /* some monitors remove breakpoints based on the address */ + if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR) + monitor_printf (current_monitor->clr_break, addr); + else if (current_monitor->flags & MO_CLR_BREAK_1_BASED) + monitor_printf (current_monitor->clr_break, i + 1); + else + monitor_printf (current_monitor->clr_break, i); + monitor_expect_prompt (NULL, 0); + return 0; + } + } + fprintf_unfiltered (gdb_stderr, + "Can't find breakpoint associated with 0x%s\n", + paddr_nz (addr)); + return 1; +} + +/* monitor_wait_srec_ack -- wait for the target to send an acknowledgement for + an S-record. Return non-zero if the ACK is received properly. */ + +static int +monitor_wait_srec_ack (void) +{ + int ch; + + if (current_monitor->flags & MO_SREC_ACK_PLUS) + { + return (readchar (timeout) == '+'); + } + else if (current_monitor->flags & MO_SREC_ACK_ROTATE) + { + /* Eat two backspaces, a "rotating" char (|/-\), and a space. */ + if ((ch = readchar (1)) < 0) + return 0; + if ((ch = readchar (1)) < 0) + return 0; + if ((ch = readchar (1)) < 0) + return 0; + if ((ch = readchar (1)) < 0) + return 0; + } + return 1; +} + +/* monitor_load -- download a file. */ + +static void +monitor_load (char *file, int from_tty) +{ + monitor_debug ("MON load\n"); + + if (current_monitor->load_routine) + current_monitor->load_routine (monitor_desc, file, hashmark); + else + { /* The default is ascii S-records */ + int n; + unsigned long load_offset; + char buf[128]; + + /* enable user to specify address for downloading as 2nd arg to load */ + n = sscanf (file, "%s 0x%lx", buf, &load_offset); + if (n > 1) + file = buf; + else + load_offset = 0; + + monitor_printf (current_monitor->load); + if (current_monitor->loadresp) + monitor_expect (current_monitor->loadresp, NULL, 0); + + load_srec (monitor_desc, file, (bfd_vma) load_offset, + 32, SREC_ALL, hashmark, + current_monitor->flags & MO_SREC_ACK ? + monitor_wait_srec_ack : NULL); + + monitor_expect_prompt (NULL, 0); + } + + /* Finally, make the PC point at the start address */ + if (exec_bfd) + write_pc (bfd_get_start_address (exec_bfd)); + + /* There used to be code here which would clear inferior_ptid and + call clear_symtab_users. None of that should be necessary: + monitor targets should behave like remote protocol targets, and + since generic_load does none of those things, this function + shouldn't either. + + Furthermore, clearing inferior_ptid is *incorrect*. After doing + a load, we still have a valid connection to the monitor, with a + live processor state to fiddle with. The user can type + `continue' or `jump *start' and make the program run. If they do + these things, however, GDB will be talking to a running program + while inferior_ptid is null_ptid; this makes things like + reinit_frame_cache very confused. */ +} + +static void +monitor_stop (void) +{ + monitor_debug ("MON stop\n"); + if ((current_monitor->flags & MO_SEND_BREAK_ON_STOP) != 0) + serial_send_break (monitor_desc); + if (current_monitor->stop) + monitor_printf_noecho (current_monitor->stop); +} + +/* Put a COMMAND string out to MONITOR. Output from MONITOR is placed + in OUTPUT until the prompt is seen. FIXME: We read the characters + ourseleves here cause of a nasty echo. */ + +static void +monitor_rcmd (char *command, + struct ui_file *outbuf) +{ + char *p; + int resp_len; + char buf[1000]; + + if (monitor_desc == NULL) + error ("monitor target not open."); + + p = current_monitor->prompt; + + /* Send the command. Note that if no args were supplied, then we're + just sending the monitor a newline, which is sometimes useful. */ + + monitor_printf ("%s\r", (command ? command : "")); + + resp_len = monitor_expect_prompt (buf, sizeof buf); + + fputs_unfiltered (buf, outbuf); /* Output the response */ +} + +/* Convert hex digit A to a number. */ + +#if 0 +static int +from_hex (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + if (a >= 'A' && a <= 'F') + return a - 'A' + 10; + + error ("Reply contains invalid hex digit 0x%x", a); +} +#endif + +char * +monitor_get_dev_name (void) +{ + return dev_name; +} + +static struct target_ops monitor_ops; + +static void +init_base_monitor_ops (void) +{ + monitor_ops.to_close = monitor_close; + monitor_ops.to_detach = monitor_detach; + monitor_ops.to_resume = monitor_resume; + monitor_ops.to_wait = monitor_wait; + monitor_ops.to_fetch_registers = monitor_fetch_registers; + monitor_ops.to_store_registers = monitor_store_registers; + monitor_ops.to_prepare_to_store = monitor_prepare_to_store; + monitor_ops.to_xfer_memory = monitor_xfer_memory; + monitor_ops.to_files_info = monitor_files_info; + monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint; + monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint; + monitor_ops.to_kill = monitor_kill; + monitor_ops.to_load = monitor_load; + monitor_ops.to_create_inferior = monitor_create_inferior; + monitor_ops.to_mourn_inferior = monitor_mourn_inferior; + monitor_ops.to_stop = monitor_stop; + monitor_ops.to_rcmd = monitor_rcmd; + monitor_ops.to_stratum = process_stratum; + monitor_ops.to_has_all_memory = 1; + monitor_ops.to_has_memory = 1; + monitor_ops.to_has_stack = 1; + monitor_ops.to_has_registers = 1; + monitor_ops.to_has_execution = 1; + monitor_ops.to_magic = OPS_MAGIC; +} /* init_base_monitor_ops */ + +/* Init the target_ops structure pointed at by OPS */ + +void +init_monitor_ops (struct target_ops *ops) +{ + if (monitor_ops.to_magic != OPS_MAGIC) + init_base_monitor_ops (); + + memcpy (ops, &monitor_ops, sizeof monitor_ops); +} + +/* Define additional commands that are usually only used by monitors. */ + +extern initialize_file_ftype _initialize_remote_monitors; /* -Wmissing-prototypes */ + +void +_initialize_remote_monitors (void) +{ + init_base_monitor_ops (); + add_show_from_set (add_set_cmd ("hash", no_class, var_boolean, + (char *) &hashmark, + "Set display of activity while downloading a file.\n\ +When enabled, a hashmark \'#\' is displayed.", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ("monitor", no_class, var_zinteger, + (char *) &monitor_debug_p, + "Set debugging of remote monitor communication.\n\ +When enabled, communication between GDB and the remote monitor\n\ +is displayed.", &setdebuglist), + &showdebuglist); +} diff --git a/contrib/gdb/gdb/monitor.h b/contrib/gdb/gdb/monitor.h new file mode 100644 index 00000000000..2f8ca22a454 --- /dev/null +++ b/contrib/gdb/gdb/monitor.h @@ -0,0 +1,260 @@ +/* Definitions for remote debugging interface for ROM monitors. + Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. + Contributed by Cygnus Support. Written by Rob Savoye for Cygnus. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#ifndef MONITOR_H +#define MONITOR_H + +struct target_waitstatus; +struct serial; + +/* This structure describes the strings necessary to give small command + sequences to the monitor, and parse the response. + + CMD is the actual command typed at the monitor. Usually this has + embedded sequences ala printf, which are substituted with the + arguments appropriate to that type of command. Ie: to examine a + register, we substitute the register name for the first arg. To + modify memory, we substitute the memory location and the new + contents for the first and second args, etc... + + RESP_DELIM used to home in on the response string, and is used to + disambiguate the answer within the pile of text returned by the + monitor. This should be a unique string that immediately precedes + the answer. Ie: if your monitor prints out `PC: 00000001= ' in + response to asking for the PC, you should use `: ' as the + RESP_DELIM. RESP_DELIM may be NULL if the res- ponse is going to + be ignored, or has no particular leading text. + + TERM is the string that the monitor outputs to indicate that it is + idle, and waiting for input. This is usually a prompt of some + sort. In the previous example, it would be `= '. It is important + that TERM really means that the monitor is idle, otherwise GDB may + try to type at it when it isn't ready for input. This is a problem + because many monitors cannot deal with type-ahead. TERM may be + NULL if the normal prompt is output. + + TERM_CMD is used to quit out of the subcommand mode and get back to + the main prompt. TERM_CMD may be NULL if it isn't necessary. It + will also be ignored if TERM is NULL. */ + +struct memrw_cmd + { + char *cmdb; /* Command to send for byte read/write */ + char *cmdw; /* Command for word (16 bit) read/write */ + char *cmdl; /* Command for long (32 bit) read/write */ + char *cmdll; /* Command for long long (64 bit) read/write */ + char *resp_delim; /* String just prior to the desired value */ + char *term; /* Terminating string to search for */ + char *term_cmd; /* String to get out of sub-mode (if necessary) */ + }; + +struct regrw_cmd + { + char *cmd; /* Command to send for reg read/write */ + char *resp_delim; /* String (actually a regexp if getmem) just + prior to the desired value */ + char *term; /* Terminating string to search for */ + char *term_cmd; /* String to get out of sub-mode (if necessary) */ + }; + +struct monitor_ops + { + int flags; /* See below */ + char **init; /* List of init commands. NULL terminated. */ + char *cont; /* continue command */ + char *step; /* single step */ + char *stop; /* Interrupt program string */ + char *set_break; /* set a breakpoint. If NULL, monitor implementation + sets its own to_insert_breakpoint method. */ + char *clr_break; /* clear a breakpoint */ + char *clr_all_break; /* Clear all breakpoints */ + char *fill; /* Memory fill cmd (addr len val) */ + struct memrw_cmd setmem; /* set memory to a value */ + struct memrw_cmd getmem; /* display memory */ + struct regrw_cmd setreg; /* set a register */ + struct regrw_cmd getreg; /* get a register */ + /* Some commands can dump a bunch of registers + at once. This comes as a set of REG=VAL + pairs. This should be called for each pair + of registers that we can parse to supply + GDB with the value of a register. */ + char *dump_registers; /* Command to dump all regs at once */ + char *register_pattern; /* Pattern that picks out register from reg dump */ + void (*supply_register) (char *name, int namelen, char *val, int vallen); + void (*load_routine) (struct serial *desc, char *file, + int hashmark); /* Download routine */ + int (*dumpregs) (void); /* routine to dump all registers */ + int (*continue_hook) (void); /* Emit the continue command */ + int (*wait_filter) (char *buf, /* Maybe contains registers */ + int bufmax, + int *response_length, + struct target_waitstatus * status); + char *load; /* load command */ + char *loadresp; /* Response to load command */ + char *prompt; /* monitor command prompt */ + char *line_term; /* end-of-command delimitor */ + char *cmd_end; /* optional command terminator */ + struct target_ops *target; /* target operations */ + int stopbits; /* number of stop bits */ + char **regnames; /* array of register names in ascii */ + /* deprecated: use regname instead */ + const char *(*regname) (int index); + /* function for dynamic regname array */ + int num_breakpoints; /* If set_break != NULL, number of supported + breakpoints */ + int magic; /* Check value */ + }; + +/* The monitor ops magic number, used to detect if an ops structure doesn't + have the right number of entries filled in. */ + +#define MONITOR_OPS_MAGIC 600925 + +/* Flag definitions. */ + +/* If set, then clear breakpoint command uses address, otherwise it + uses an index returned by the monitor. */ + +#define MO_CLR_BREAK_USES_ADDR 0x1 + +/* If set, then memory fill command uses STARTADDR, ENDADDR+1, VALUE + as args, else it uses STARTADDR, LENGTH, VALUE as args. */ + +#define MO_FILL_USES_ADDR 0x2 + +/* If set, then monitor doesn't automatically supply register dump + when coming back after a continue. */ + +#define MO_NEED_REGDUMP_AFTER_CONT 0x4 + +/* getmem needs start addr and end addr */ + +#define MO_GETMEM_NEEDS_RANGE 0x8 + +/* getmem can only read one loc at a time */ + +#define MO_GETMEM_READ_SINGLE 0x10 + +/* handle \r\n combinations */ + +#define MO_HANDLE_NL 0x20 + +/* don't expect echos in monitor_open */ + +#define MO_NO_ECHO_ON_OPEN 0x40 + +/* If set, send break to stop monitor */ + +#define MO_SEND_BREAK_ON_STOP 0x80 + +/* If set, target sends an ACK after each S-record */ + +#define MO_SREC_ACK 0x100 + +/* Allow 0x prefix on addresses retured from monitor */ + +#define MO_HEX_PREFIX 0x200 + +/* Some monitors require a different command when starting a program */ + +#define MO_RUN_FIRST_TIME 0x400 + +/* Don't expect echos when getting memory */ + +#define MO_NO_ECHO_ON_SETMEM 0x800 + +/* If set, then register store command expects value BEFORE regname */ + +#define MO_REGISTER_VALUE_FIRST 0x1000 + +/* If set, then the monitor displays registers as pairs. */ + +#define MO_32_REGS_PAIRED 0x2000 + +/* If set, then register setting happens interactively. */ + +#define MO_SETREG_INTERACTIVE 0x4000 + +/* If set, then memory setting happens interactively. */ + +#define MO_SETMEM_INTERACTIVE 0x8000 + +/* If set, then memory dumps are always on 16-byte boundaries, even + when less is desired. */ + +#define MO_GETMEM_16_BOUNDARY 0x10000 + +/* If set, then the monitor numbers its breakpoints starting from 1. */ + +#define MO_CLR_BREAK_1_BASED 0x20000 + +/* If set, then the monitor acks srecords with a plus sign. */ + +#define MO_SREC_ACK_PLUS 0x40000 + +/* If set, then the monitor "acks" srecords with rotating lines. */ + +#define MO_SREC_ACK_ROTATE 0x80000 + +/* If set, then remove useless address bits from memory addresses. */ + +#define MO_ADDR_BITS_REMOVE 0x100000 + +/* If set, then display target program output if prefixed by ^O. */ + +#define MO_PRINT_PROGRAM_OUTPUT 0x200000 + +/* Some dump bytes commands align the first data with the preceeding + 16 byte boundary. Some print blanks and start at the exactly the + requested boundary. */ + +#define MO_EXACT_DUMPADDR 0x400000 + +/* Rather entering and exiting the write memory dialog for each word byte, + we can save time by transferring the whole block without exiting + the memory editing mode. You only need to worry about this + if you are doing memory downloading. + This engages a new write function registered with dcache. + */ +#define MO_HAS_BLOCKWRITES 0x800000 + +#define SREC_SIZE 160 + +extern void monitor_open (char *args, struct monitor_ops *ops, int from_tty); +extern void monitor_close (int quitting); +extern char *monitor_supply_register (int regno, char *valstr); +extern int monitor_expect (char *prompt, char *buf, int buflen); +extern int monitor_expect_prompt (char *buf, int buflen); +/* Note: The variable argument functions monitor_printf and + monitor_printf_noecho vararg do not take take standard format style + arguments. Instead they take custom formats interpretered directly + by monitor_vsprintf. */ +extern void monitor_printf (char *, ...); +extern void monitor_printf_noecho (char *, ...); +extern void monitor_write (char *buf, int buflen); +extern int monitor_readchar (void); +extern char *monitor_get_dev_name (void); +extern void init_monitor_ops (struct target_ops *); +extern int monitor_dump_reg_block (char *dump_cmd); + +#endif diff --git a/contrib/gdb/gdb/nbsd-tdep.c b/contrib/gdb/gdb/nbsd-tdep.c new file mode 100644 index 00000000000..a2d8f7d1533 --- /dev/null +++ b/contrib/gdb/gdb/nbsd-tdep.c @@ -0,0 +1,109 @@ +/* Common target-dependent code for NetBSD systems. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_string.h" +#include "solib-svr4.h" + +/* Fetch (and possibly build) an appropriate link_map_offsets + structure for NetBSD targets using the struct offsets defined + in (but without actual reference to that file). + + This makes it possible to access NetBSD shared libraries from a + GDB that was not built on the same platform (for cross debugging). + + We provide versions for ILP32 and LP64 NetBSD targets here. */ + +struct link_map_offsets * +nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + lmo.r_debug_size = 16; + + lmo.r_map_offset = 4; + lmo.r_map_size = 4; + + lmo.link_map_size = 20; + + lmo.l_addr_offset = 0; + lmo.l_addr_size = 4; + + lmo.l_name_offset = 4; + lmo.l_name_size = 4; + + lmo.l_next_offset = 12; + lmo.l_next_size = 4; + + lmo.l_prev_offset = 16; + lmo.l_prev_size = 4; + } + + return lmp; +} + +struct link_map_offsets * +nbsd_lp64_solib_svr4_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + lmo.r_debug_size = 32; + + lmo.r_map_offset = 8; + lmo.r_map_size = 8; + + lmo.link_map_size = 40; + + lmo.l_addr_offset = 0; + lmo.l_addr_size = 8; + + lmo.l_name_offset = 8; + lmo.l_name_size = 8; + + lmo.l_next_offset = 24; + lmo.l_next_size = 8; + + lmo.l_prev_offset = 32; + lmo.l_prev_size = 8; + } + + return lmp; +} + +int +nbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) +{ + /* Check for libc-provided signal trampoline. All such trampolines + have function names which begin with "__sigtramp". */ + + return (func_name != NULL + && strncmp (func_name, "__sigtramp", 10) == 0); +} diff --git a/contrib/gdb/gdb/nbsd-tdep.h b/contrib/gdb/gdb/nbsd-tdep.h new file mode 100644 index 00000000000..9d26ae9f859 --- /dev/null +++ b/contrib/gdb/gdb/nbsd-tdep.h @@ -0,0 +1,30 @@ +/* Common target-dependent definitions for NetBSD systems. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef NBSD_TDEP_H +#define NBSD_TDEP_H + +struct link_map_offsets *nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void); +struct link_map_offsets *nbsd_lp64_solib_svr4_fetch_link_map_offsets (void); + +int nbsd_pc_in_sigtramp (CORE_ADDR, char *); + +#endif /* NBSD_TDEP_H */ diff --git a/contrib/gdb/gdb/nlmread.c b/contrib/gdb/gdb/nlmread.c index eaa9ddeb2f3..4e9c87d3ff0 100644 --- a/contrib/gdb/gdb/nlmread.c +++ b/contrib/gdb/gdb/nlmread.c @@ -27,6 +27,7 @@ #include "objfiles.h" #include "buildsym.h" #include "stabsread.h" +#include "block.h" extern void _initialize_nlmread (void); @@ -190,10 +191,16 @@ nlm_symfile_read (struct objfile *objfile, int mainline) nlm_symtab_read (abfd, offset, objfile); + /* Install any minimal symbols that have been collected as the current + minimal symbols for this objfile. */ + + install_minimal_symbols (objfile); + do_cleanups (back_to); + stabsect_build_psymtabs (objfile, mainline, ".stab", ".stabstr", ".text"); - mainsym = lookup_symbol (main_name (), NULL, VAR_NAMESPACE, NULL, NULL); + mainsym = lookup_symbol (main_name (), NULL, VAR_DOMAIN, NULL, NULL); if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK) @@ -204,13 +211,6 @@ nlm_symfile_read (struct objfile *objfile, int mainline) /* FIXME: We could locate and read the optional native debugging format here and add the symbols to the minimal symbol table. */ - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); } diff --git a/contrib/gdb/gdb/nto-procfs.c b/contrib/gdb/gdb/nto-procfs.c new file mode 100755 index 00000000000..00b409661e6 --- /dev/null +++ b/contrib/gdb/gdb/nto-procfs.c @@ -0,0 +1,1389 @@ +/* Machine independent support for QNX Neutrino /proc (process file system) + for GDB. Written by Colin Burgess at QNX Software Systems Limited. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by QNX Software Systems Ltd. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include +#include +#include +#include +#include +#include +#include "gdb_dirent.h" +#include + +#include "gdb_string.h" +#include "gdbcore.h" +#include "inferior.h" +#include "target.h" +#include "objfiles.h" +#include "gdbthread.h" +#include "nto-tdep.h" +#include "command.h" +#include "regcache.h" + +#define NULL_PID 0 +#define _DEBUG_FLAG_TRACE (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\ + _DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY) + +static struct target_ops procfs_ops; + +int ctl_fd; + +static void (*ofunc) (); + +static procfs_run run; + +static void procfs_open (char *, int); + +static int procfs_can_run (void); + +static ptid_t procfs_wait (ptid_t, struct target_waitstatus *); + +static int procfs_xfer_memory (CORE_ADDR, char *, int, int, + struct mem_attrib *attrib, + struct target_ops *); + +static void procfs_fetch_registers (int); + +static void notice_signals (void); + +static void init_procfs_ops (void); + +static ptid_t do_attach (ptid_t ptid); + +static int procfs_can_use_hw_breakpoint (int, int, int); + +static int procfs_insert_hw_breakpoint (CORE_ADDR, char *); + +static int procfs_remove_hw_breakpoint (CORE_ADDR addr, char *); + +static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type); + +static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type); + +static int procfs_stopped_by_watchpoint (void); + +/* These two globals are only ever set in procfs_open(), but are + referenced elsewhere. 'nto_procfs_node' is a flag used to say + whether we are local, or we should get the current node descriptor + for the remote QNX node. */ +static char nto_procfs_path[PATH_MAX] = { "/proc" }; +static unsigned nto_procfs_node = ND_LOCAL_NODE; + +/* Return the current QNX Node, or error out. This is a simple + wrapper for the netmgr_strtond() function. The reason this + is required is because QNX node descriptors are transient so + we have to re-acquire them every time. */ +static unsigned +nto_node(void) +{ + unsigned node; + + if (ND_NODE_CMP(nto_procfs_node, ND_LOCAL_NODE) == 0) + return ND_LOCAL_NODE; + + node = netmgr_strtond(nto_procfs_path,0); + if (node == -1) + error ("Lost the QNX node. Debug session probably over."); + + return (node); +} + +/* This is called when we call 'target procfs ' from the (gdb) prompt. + For QNX6 (nto), the only valid arg will be a QNX node string, + eg: "/net/some_node". If arg is not a valid QNX node, we will + default to local. */ +static void +procfs_open (char *arg, int from_tty) +{ + char *nodestr; + char *endstr; + char buffer[50]; + int fd, total_size; + procfs_sysinfo *sysinfo; + + /* Set the default node used for spawning to this one, + and only override it if there is a valid arg. */ + + nto_procfs_node = ND_LOCAL_NODE; + nodestr = arg ? xstrdup (arg) : arg; + + init_thread_list (); + + if (nodestr) + { + nto_procfs_node = netmgr_strtond (nodestr, &endstr); + if (nto_procfs_node == -1) + { + if (errno == ENOTSUP) + printf_filtered ("QNX Net Manager not found.\n"); + printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr, + errno, safe_strerror (errno)); + xfree (nodestr); + nodestr = NULL; + nto_procfs_node = ND_LOCAL_NODE; + } + else if (*endstr) + { + if (*(endstr - 1) == '/') + *(endstr - 1) = 0; + else + *endstr = 0; + } + } + snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "", "/proc"); + if (nodestr) + xfree (nodestr); + + fd = open (nto_procfs_path, O_RDONLY); + if (fd == -1) + { + printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno, + safe_strerror (errno)); + error ("Invalid procfs arg"); + } + + sysinfo = (void *) buffer; + if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK) + { + printf_filtered ("Error getting size: %d (%s)\n", errno, + safe_strerror (errno)); + close (fd); + error ("Devctl failed."); + } + else + { + total_size = sysinfo->total_size; + sysinfo = alloca (total_size); + if (!sysinfo) + { + printf_filtered ("Memory error: %d (%s)\n", errno, + safe_strerror (errno)); + close (fd); + error ("alloca failed."); + } + else + { + if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK) + { + printf_filtered ("Error getting sysinfo: %d (%s)\n", errno, + safe_strerror (errno)); + close (fd); + error ("Devctl failed."); + } + else + { + if (sysinfo->type != + nto_map_arch_to_cputype (TARGET_ARCHITECTURE->arch_name)) + { + close (fd); + error ("Invalid target CPU."); + } + } + } + } + close (fd); + printf_filtered ("Debugging using %s\n", nto_procfs_path); +} + +static void +procfs_set_thread (ptid_t ptid) +{ + pid_t tid; + + tid = ptid_get_tid (ptid); + devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0); +} + +/* Return nonzero if the thread TH is still alive. */ +static int +procfs_thread_alive (ptid_t ptid) +{ + pid_t tid; + + tid = ptid_get_tid (ptid); + if (devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0) == EOK) + return 1; + return 0; +} + +void +procfs_find_new_threads (void) +{ + procfs_status status; + pid_t pid; + ptid_t ptid; + + if (ctl_fd == -1) + return; + + pid = ptid_get_pid (inferior_ptid); + + for (status.tid = 1;; ++status.tid) + { + if (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) + != EOK && status.tid != 0) + break; + ptid = ptid_build (pid, 0, status.tid); + if (!in_thread_list (ptid)) + add_thread (ptid); + } + return; +} + +void +procfs_pidlist (char *args, int from_tty) +{ + DIR *dp = NULL; + struct dirent *dirp = NULL; + int fd = -1; + char buf[512]; + procfs_info *pidinfo = NULL; + procfs_debuginfo *info = NULL; + procfs_status *status = NULL; + pid_t num_threads = 0; + pid_t pid; + char name[512]; + + dp = opendir (nto_procfs_path); + if (dp == NULL) + { + fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)", + nto_procfs_path, errno, safe_strerror (errno)); + return; + } + + /* Start scan at first pid. */ + rewinddir (dp); + + do + { + /* Get the right pid and procfs path for the pid. */ + do + { + dirp = readdir (dp); + if (dirp == NULL) + { + closedir (dp); + return; + } + snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name); + pid = atoi (dirp->d_name); + } + while (pid == 0); + + /* Open the procfs path. */ + fd = open (buf, O_RDONLY); + if (fd == -1) + { + fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n", + buf, errno, safe_strerror (errno)); + closedir (dp); + return; + } + + pidinfo = (procfs_info *) buf; + if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK) + { + fprintf_unfiltered (gdb_stderr, + "devctl DCMD_PROC_INFO failed - %d (%s)\n", errno, + safe_strerror (errno)); + break; + } + num_threads = pidinfo->num_threads; + + info = (procfs_debuginfo *) buf; + if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK) + strcpy (name, "unavailable"); + else + strcpy (name, info->path); + + /* Collect state info on all the threads. */ + status = (procfs_status *) buf; + for (status->tid = 1; status->tid <= num_threads; status->tid++) + { + if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK + && status->tid != 0) + break; + if (status->tid != 0) + printf_filtered ("%s - %d/%d\n", name, pid, status->tid); + } + close (fd); + } + while (dirp != NULL); + + close (fd); + closedir (dp); + return; +} + +void +procfs_meminfo (char *args, int from_tty) +{ + procfs_mapinfo *mapinfos = NULL; + static int num_mapinfos = 0; + procfs_mapinfo *mapinfo_p, *mapinfo_p2; + int flags = ~0, err, num, i, j; + + struct + { + procfs_debuginfo info; + char buff[_POSIX_PATH_MAX]; + } map; + + struct info + { + unsigned addr; + unsigned size; + unsigned flags; + unsigned debug_vaddr; + unsigned long long offset; + }; + + struct printinfo + { + unsigned long long ino; + unsigned dev; + struct info text; + struct info data; + char name[256]; + } printme; + + /* Get the number of map entrys. */ + err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num); + if (err != EOK) + { + printf ("failed devctl num mapinfos - %d (%s)\n", err, safe_strerror (err)); + return; + } + + mapinfos = xmalloc (num * sizeof (procfs_mapinfo)); + + num_mapinfos = num; + mapinfo_p = mapinfos; + + /* Fill the map entrys. */ + err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num + * sizeof (procfs_mapinfo), &num); + if (err != EOK) + { + printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err)); + xfree (mapinfos); + return; + } + + num = min (num, num_mapinfos); + + /* Run through the list of mapinfos, and store the data and text info + so we can print it at the bottom of the loop. */ + for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++) + { + if (!(mapinfo_p->flags & flags)) + mapinfo_p->ino = 0; + + if (mapinfo_p->ino == 0) /* Already visited. */ + continue; + + map.info.vaddr = mapinfo_p->vaddr; + + err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); + if (err != EOK) + continue; + + memset (&printme, 0, sizeof printme); + printme.dev = mapinfo_p->dev; + printme.ino = mapinfo_p->ino; + printme.text.addr = mapinfo_p->vaddr; + printme.text.size = mapinfo_p->size; + printme.text.flags = mapinfo_p->flags; + printme.text.offset = mapinfo_p->offset; + printme.text.debug_vaddr = map.info.vaddr; + strcpy (printme.name, map.info.path); + + /* Check for matching data. */ + for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++) + { + if (mapinfo_p2->vaddr != mapinfo_p->vaddr + && mapinfo_p2->ino == mapinfo_p->ino + && mapinfo_p2->dev == mapinfo_p->dev) + { + map.info.vaddr = mapinfo_p2->vaddr; + err = + devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); + if (err != EOK) + continue; + + if (strcmp (map.info.path, printme.name)) + continue; + + /* Lower debug_vaddr is always text, if nessessary, swap. */ + if ((int) map.info.vaddr < (int) printme.text.debug_vaddr) + { + memcpy (&(printme.data), &(printme.text), + sizeof (printme.data)); + printme.text.addr = mapinfo_p2->vaddr; + printme.text.size = mapinfo_p2->size; + printme.text.flags = mapinfo_p2->flags; + printme.text.offset = mapinfo_p2->offset; + printme.text.debug_vaddr = map.info.vaddr; + } + else + { + printme.data.addr = mapinfo_p2->vaddr; + printme.data.size = mapinfo_p2->size; + printme.data.flags = mapinfo_p2->flags; + printme.data.offset = mapinfo_p2->offset; + printme.data.debug_vaddr = map.info.vaddr; + } + mapinfo_p2->ino = 0; + } + } + mapinfo_p->ino = 0; + + printf_filtered ("%s\n", printme.name); + printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size, + printme.text.addr); + printf_filtered ("\t\tflags=%08x\n", printme.text.flags); + printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr); + printf_filtered ("\t\toffset=%016llx\n", printme.text.offset); + if (printme.data.size) + { + printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size, + printme.data.addr); + printf_filtered ("\t\tflags=%08x\n", printme.data.flags); + printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr); + printf_filtered ("\t\toffset=%016llx\n", printme.data.offset); + } + printf_filtered ("\tdev=0x%x\n", printme.dev); + printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino); + } + xfree (mapinfos); + return; +} + +/* Print status information about what we're accessing. */ +static void +procfs_files_info (struct target_ops *ignore) +{ + printf_unfiltered ("\tUsing the running image of %s %s via %s.\n", + attach_flag ? "attached" : "child", + target_pid_to_str (inferior_ptid), nto_procfs_path); +} + +/* Mark our target-struct as eligible for stray "run" and "attach" commands. */ +static int +procfs_can_run (void) +{ + return 1; +} + +/* Attach to process PID, then initialize for debugging it. */ +static void +procfs_attach (char *args, int from_tty) +{ + char *exec_file; + int pid; + + if (!args) + error_no_arg ("process-id to attach"); + + pid = atoi (args); + + if (pid == getpid ()) + error ("Attaching GDB to itself is not a good idea..."); + + if (from_tty) + { + exec_file = (char *) get_exec_file (0); + + if (exec_file) + printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, + target_pid_to_str (pid_to_ptid (pid))); + else + printf_unfiltered ("Attaching to %s\n", + target_pid_to_str (pid_to_ptid (pid))); + + gdb_flush (gdb_stdout); + } + inferior_ptid = do_attach (pid_to_ptid (pid)); + push_target (&procfs_ops); +} + +static void +procfs_post_attach (pid_t pid) +{ +#ifdef SOLIB_CREATE_INFERIOR_HOOK + if (exec_bfd) + SOLIB_CREATE_INFERIOR_HOOK (pid); +#endif +} + +static ptid_t +do_attach (ptid_t ptid) +{ + procfs_status status; + struct sigevent event; + char path[PATH_MAX]; + + snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid)); + ctl_fd = open (path, O_RDWR); + if (ctl_fd == -1) + error ("Couldn't open proc file %s, error %d (%s)", path, errno, + safe_strerror (errno)); + if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK) + error ("Couldn't stop process"); + + /* Define a sigevent for process stopped notification. */ + event.sigev_notify = SIGEV_SIGNAL_THREAD; + event.sigev_signo = SIGUSR1; + event.sigev_code = 0; + event.sigev_value.sival_ptr = NULL; + event.sigev_priority = -1; + devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0); + + if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK + && status.flags & _DEBUG_FLAG_STOPPED) + SignalKill (nto_node(), PIDGET (ptid), 0, SIGCONT, 0, 0); + attach_flag = 1; + nto_init_solib_absolute_prefix (); + return ptid; +} + +/* Ask the user what to do when an interrupt is received. */ +static void +interrupt_query (void) +{ + target_terminal_ours (); + + if (query ("Interrupted while waiting for the program.\n\ +Give up (and stop debugging it)? ")) + { + target_mourn_inferior (); + throw_exception (RETURN_QUIT); + } + + target_terminal_inferior (); +} + +/* The user typed ^C twice. */ +static void +nto_interrupt_twice (int signo) +{ + signal (signo, ofunc); + interrupt_query (); + signal (signo, nto_interrupt_twice); +} + +static void +nto_interrupt (int signo) +{ + /* If this doesn't work, try more severe steps. */ + signal (signo, nto_interrupt_twice); + + target_stop (); +} + +static ptid_t +procfs_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +{ + sigset_t set; + siginfo_t info; + procfs_status status; + static int exit_signo = 0; /* To track signals that cause termination. */ + + ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + + if (ptid_equal (inferior_ptid, null_ptid)) + { + ourstatus->kind = TARGET_WAITKIND_STOPPED; + ourstatus->value.sig = TARGET_SIGNAL_0; + exit_signo = 0; + return null_ptid; + } + + sigemptyset (&set); + sigaddset (&set, SIGUSR1); + + devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); + while (!(status.flags & _DEBUG_FLAG_ISTOP)) + { + ofunc = (void (*)()) signal (SIGINT, nto_interrupt); + sigwaitinfo (&set, &info); + signal (SIGINT, ofunc); + devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); + } + + if (status.flags & _DEBUG_FLAG_SSTEP) + { + ourstatus->kind = TARGET_WAITKIND_STOPPED; + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + } + /* Was it a breakpoint? */ + else if (status.flags & _DEBUG_FLAG_TRACE) + { + ourstatus->kind = TARGET_WAITKIND_STOPPED; + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + } + else if (status.flags & _DEBUG_FLAG_ISTOP) + { + switch (status.why) + { + case _DEBUG_WHY_SIGNALLED: + ourstatus->kind = TARGET_WAITKIND_STOPPED; + ourstatus->value.sig = + target_signal_from_host (status.info.si_signo); + exit_signo = 0; + break; + case _DEBUG_WHY_FAULTED: + ourstatus->kind = TARGET_WAITKIND_STOPPED; + if (status.info.si_signo == SIGTRAP) + { + ourstatus->value.sig = 0; + exit_signo = 0; + } + else + { + ourstatus->value.sig = + target_signal_from_host (status.info.si_signo); + exit_signo = ourstatus->value.sig; + } + break; + + case _DEBUG_WHY_TERMINATED: + { + int waitval = 0; + + waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG); + if (exit_signo) + { + /* Abnormal death. */ + ourstatus->kind = TARGET_WAITKIND_SIGNALLED; + ourstatus->value.sig = exit_signo; + } + else + { + /* Normal death. */ + ourstatus->kind = TARGET_WAITKIND_EXITED; + ourstatus->value.integer = WEXITSTATUS (waitval); + } + exit_signo = 0; + break; + } + + case _DEBUG_WHY_REQUESTED: + /* We are assuming a requested stop is due to a SIGINT. */ + ourstatus->kind = TARGET_WAITKIND_STOPPED; + ourstatus->value.sig = TARGET_SIGNAL_INT; + exit_signo = 0; + break; + } + } + + return inferior_ptid; +} + +/* Read the current values of the inferior's registers, both the + general register set and floating point registers (if supported) + and update gdb's idea of their current values. */ +static void +procfs_fetch_registers (int regno) +{ + union + { + procfs_greg greg; + procfs_fpreg fpreg; + procfs_altreg altreg; + } + reg; + int regsize; + + procfs_set_thread (inferior_ptid); + if (devctl (ctl_fd, DCMD_PROC_GETGREG, ®, sizeof (reg), ®size) == EOK) + nto_supply_gregset ((char *) ®.greg); + if (devctl (ctl_fd, DCMD_PROC_GETFPREG, ®, sizeof (reg), ®size) + == EOK) + nto_supply_fpregset ((char *) ®.fpreg); + if (devctl (ctl_fd, DCMD_PROC_GETALTREG, ®, sizeof (reg), ®size) + == EOK) + nto_supply_altregset ((char *) ®.altreg); +} + +/* Copy LEN bytes to/from inferior's memory starting at MEMADDR + from/to debugger memory starting at MYADDR. Copy from inferior + if DOWRITE is zero or to inferior if DOWRITE is nonzero. + + Returns the length copied, which is either the LEN argument or + zero. This xfer function does not do partial moves, since procfs_ops + doesn't allow memory operations to cross below us in the target stack + anyway. */ +static int +procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite, + struct mem_attrib *attrib, struct target_ops *target) +{ + int nbytes = 0; + + if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr) + { + if (dowrite) + nbytes = write (ctl_fd, myaddr, len); + else + nbytes = read (ctl_fd, myaddr, len); + if (nbytes < 0) + nbytes = 0; + } + return (nbytes); +} + +/* Take a program previously attached to and detaches it. + The program resumes execution and will no longer stop + on signals, etc. We'd better not have left any breakpoints + in the program or it'll die when it hits one. */ +static void +procfs_detach (char *args, int from_tty) +{ + int siggnal = 0; + + if (from_tty) + { + char *exec_file = get_exec_file (0); + if (exec_file == 0) + exec_file = ""; + printf_unfiltered ("Detaching from program: %s %s\n", + exec_file, target_pid_to_str (inferior_ptid)); + gdb_flush (gdb_stdout); + } + if (args) + siggnal = atoi (args); + + if (siggnal) + SignalKill (nto_node(), PIDGET (inferior_ptid), 0, siggnal, 0, 0); + + close (ctl_fd); + ctl_fd = -1; + init_thread_list (); + inferior_ptid = null_ptid; + attach_flag = 0; + unpush_target (&procfs_ops); /* Pop out of handling an inferior. */ +} + +static int +procfs_breakpoint (CORE_ADDR addr, int type, int size) +{ + procfs_break brk; + + brk.type = type; + brk.addr = addr; + brk.size = size; + errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); + if (errno != EOK) + return 1; + return 0; +} + +static int +procfs_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0); +} + +static int +procfs_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1); +} + +static int +procfs_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0); +} + +static int +procfs_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1); +} + +static void +procfs_resume (ptid_t ptid, int step, enum target_signal signo) +{ + int signal_to_pass; + procfs_status status; + + if (ptid_equal (inferior_ptid, null_ptid)) + return; + + procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid : + ptid); + + run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE; + if (step) + run.flags |= _DEBUG_RUN_STEP; + + sigemptyset ((sigset_t *) &run.fault); + sigaddset ((sigset_t *) &run.fault, FLTBPT); + sigaddset ((sigset_t *) &run.fault, FLTTRACE); + sigaddset ((sigset_t *) &run.fault, FLTILL); + sigaddset ((sigset_t *) &run.fault, FLTPRIV); + sigaddset ((sigset_t *) &run.fault, FLTBOUNDS); + sigaddset ((sigset_t *) &run.fault, FLTIOVF); + sigaddset ((sigset_t *) &run.fault, FLTIZDIV); + sigaddset ((sigset_t *) &run.fault, FLTFPE); + /* Peter V will be changing this at some point. */ + sigaddset ((sigset_t *) &run.fault, FLTPAGE); + + run.flags |= _DEBUG_RUN_ARM; + + sigemptyset (&run.trace); + notice_signals (); + signal_to_pass = target_signal_to_host (signo); + + if (signal_to_pass) + { + devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); + signal_to_pass = target_signal_to_host (signo); + if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)) + { + if (signal_to_pass != status.info.si_signo) + { + SignalKill (nto_node(), PIDGET (inferior_ptid), 0, signal_to_pass, + 0, 0); + run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG; + } + else /* Let it kill the program without telling us. */ + sigdelset (&run.trace, signal_to_pass); + } + } + else + run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT; + + errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0); + if (errno != EOK) + { + perror ("run error!\n"); + return; + } +} + +static void +procfs_mourn_inferior (void) +{ + if (!ptid_equal (inferior_ptid, null_ptid)) + { + SignalKill (nto_node(), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0); + close (ctl_fd); + } + inferior_ptid = null_ptid; + init_thread_list (); + unpush_target (&procfs_ops); + generic_mourn_inferior (); + attach_flag = 0; +} + +/* This function breaks up an argument string into an argument + vector suitable for passing to execvp(). + E.g., on "run a b c d" this routine would get as input + the string "a b c d", and as output it would fill in argv with + the four arguments "a", "b", "c", "d". The only additional + functionality is simple quoting. The gdb command: + run a "b c d" f + will fill in argv with the three args "a", "b c d", "e". */ +static void +breakup_args (char *scratch, char **argv) +{ + char *pp, *cp = scratch; + char quoting = 0; + + for (;;) + { + /* Scan past leading separators. */ + quoting = 0; + while (*cp == ' ' || *cp == '\t' || *cp == '\n') + cp++; + + /* Break if at end of string. */ + if (*cp == '\0') + break; + + /* Take an arg. */ + if (*cp == '"') + { + cp++; + quoting = strchr (cp, '"') ? 1 : 0; + } + + *argv++ = cp; + + /* Scan for next arg separator. */ + pp = cp; + if (quoting) + cp = strchr (pp, '"'); + if ((cp == NULL) || (!quoting)) + cp = strchr (pp, ' '); + if (cp == NULL) + cp = strchr (pp, '\t'); + if (cp == NULL) + cp = strchr (pp, '\n'); + + /* No separators => end of string => break. */ + if (cp == NULL) + { + pp = cp; + break; + } + + /* Replace the separator with a terminator. */ + *cp++ = '\0'; + } + + /* Execv requires a null-terminated arg vector. */ + *argv = NULL; +} + +static void +procfs_create_inferior (char *exec_file, char *allargs, char **env) +{ + struct inheritance inherit; + pid_t pid; + int flags, errn; + char **argv, *args; + char *in = "", *out = "", *err = ""; + int fd, fds[3]; + sigset_t set; + + argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) * + sizeof (*argv)); + argv[0] = get_exec_file (1); + if (!argv[0]) + { + if (exec_file) + argv[0] = exec_file; + else + return; + } + + args = xstrdup (allargs); + breakup_args (args, exec_file ? &argv[1] : &argv[0]); + + argv = nto_parse_redirection (argv, &in, &out, &err); + + fds[0] = STDIN_FILENO; + fds[1] = STDOUT_FILENO; + fds[2] = STDERR_FILENO; + + /* If the user specified I/O via gdb's --tty= arg, use it, but only + if the i/o is not also being specified via redirection. */ + if (inferior_io_terminal) + { + if (!in[0]) + in = inferior_io_terminal; + if (!out[0]) + out = inferior_io_terminal; + if (!err[0]) + err = inferior_io_terminal; + } + + if (in[0]) + { + fd = open (in, O_RDONLY); + if (fd == -1) + perror (in); + else + fds[0] = fd; + } + if (out[0]) + { + fd = open (out, O_WRONLY); + if (fd == -1) + perror (out); + else + fds[1] = fd; + } + if (err[0]) + { + fd = open (err, O_WRONLY); + if (fd == -1) + perror (err); + else + fds[2] = fd; + } + + /* Clear any pending SIGUSR1's but keep the behavior the same. */ + signal (SIGUSR1, signal (SIGUSR1, SIG_IGN)); + + sigemptyset (&set); + sigaddset (&set, SIGUSR1); + sigprocmask (SIG_UNBLOCK, &set, NULL); + + memset (&inherit, 0, sizeof (inherit)); + + if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0) + { + inherit.nd = nto_node(); + inherit.flags |= SPAWN_SETND; + inherit.flags &= ~SPAWN_EXEC; + } + inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD; + inherit.pgroup = SPAWN_NEWPGROUP; + pid = spawnp (argv[0], 3, fds, &inherit, argv, + ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0); + xfree (args); + + sigprocmask (SIG_BLOCK, &set, NULL); + + if (pid == -1) + error ("Error spawning %s: %d (%s)", argv[0], errno, safe_strerror (errno)); + + if (fds[0] != STDIN_FILENO) + close (fds[0]); + if (fds[1] != STDOUT_FILENO) + close (fds[1]); + if (fds[2] != STDERR_FILENO) + close (fds[2]); + + inferior_ptid = do_attach (pid_to_ptid (pid)); + + attach_flag = 0; + flags = _DEBUG_FLAG_KLC; /* Kill-on-Last-Close flag. */ + errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0); + if (errn != EOK) + { + /* FIXME: expected warning? */ + /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n", + errn, strerror(errn) ); */ + } + push_target (&procfs_ops); + target_terminal_init (); + +#ifdef SOLIB_CREATE_INFERIOR_HOOK + if (exec_bfd != NULL + || (symfile_objfile != NULL && symfile_objfile->obfd != NULL)) + SOLIB_CREATE_INFERIOR_HOOK (pid); +#endif +} + +static void +procfs_stop (void) +{ + devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0); +} + +static void +procfs_kill_inferior (void) +{ + target_mourn_inferior (); +} + +/* Store register REGNO, or all registers if REGNO == -1, from the contents + of REGISTERS. */ +static void +procfs_prepare_to_store (void) +{ +} + +/* Fill buf with regset and return devctl cmd to do the setting. Return + -1 if we fail to get the regset. Store size of regset in regsize. */ +static int +get_regset (int regset, char *buf, int bufsize, int *regsize) +{ + int dev_get, dev_set; + switch (regset) + { + case NTO_REG_GENERAL: + dev_get = DCMD_PROC_GETGREG; + dev_set = DCMD_PROC_SETGREG; + break; + + case NTO_REG_FLOAT: + dev_get = DCMD_PROC_GETFPREG; + dev_set = DCMD_PROC_SETFPREG; + break; + + case NTO_REG_ALT: + dev_get = DCMD_PROC_GETALTREG; + dev_set = DCMD_PROC_SETALTREG; + break; + + case NTO_REG_SYSTEM: + default: + return -1; + } + if (devctl (ctl_fd, dev_get, &buf, bufsize, regsize) != EOK) + return -1; + + return dev_set; +} + +void +procfs_store_registers (int regno) +{ + union + { + procfs_greg greg; + procfs_fpreg fpreg; + procfs_altreg altreg; + } + reg; + unsigned off; + int len, regset, regsize, dev_set, err; + char *data; + + if (ptid_equal (inferior_ptid, null_ptid)) + return; + procfs_set_thread (inferior_ptid); + + if (regno == -1) + { + for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++) + { + dev_set = get_regset (regset, (char *) ®, + sizeof (reg), ®size); + if (dev_set == -1) + continue; + + if (nto_regset_fill (regset, (char *) ®) == -1) + continue; + + err = devctl (ctl_fd, dev_set, ®, regsize, 0); + if (err != EOK) + fprintf_unfiltered (gdb_stderr, + "Warning unable to write regset %d: %s\n", + regno, safe_strerror (err)); + } + } + else + { + regset = nto_regset_id (regno); + if (regset == -1) + return; + + dev_set = get_regset (regset, (char *) ®, sizeof (reg), ®size); + if (dev_set == -1) + return; + + len = nto_register_area (regno, regset, &off); + + if (len < 1) + return; + + regcache_collect (regno, (char *) ® + off); + + err = devctl (ctl_fd, dev_set, ®, regsize, 0); + if (err != EOK) + fprintf_unfiltered (gdb_stderr, + "Warning unable to write regset %d: %s\n", regno, + safe_strerror (err)); + } +} + +static void +notice_signals (void) +{ + int signo; + + for (signo = 1; signo < NSIG; signo++) + { + if (signal_stop_state (target_signal_from_host (signo)) == 0 + && signal_print_state (target_signal_from_host (signo)) == 0 + && signal_pass_state (target_signal_from_host (signo)) == 1) + sigdelset (&run.trace, signo); + else + sigaddset (&run.trace, signo); + } +} + +/* When the user changes the state of gdb's signal handling via the + "handle" command, this function gets called to see if any change + in the /proc interface is required. It is also called internally + by other /proc interface functions to initialize the state of + the traced signal set. */ +static void +procfs_notice_signals (ptid_t ptid) +{ + sigemptyset (&run.trace); + notice_signals (); +} + +static struct tidinfo * +procfs_thread_info (pid_t pid, short tid) +{ +/* NYI */ + return NULL; +} + +char * +procfs_pid_to_str (ptid_t ptid) +{ + static char buf[1024]; + int pid, tid, n; + struct tidinfo *tip; + + pid = ptid_get_pid (ptid); + tid = ptid_get_tid (ptid); + + n = snprintf (buf, 1023, "process %d", pid); + +#if 0 /* NYI */ + tip = procfs_thread_info (pid, tid); + if (tip != NULL) + snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state); +#endif + + return buf; +} + +static void +init_procfs_ops (void) +{ + procfs_ops.to_shortname = "procfs"; + procfs_ops.to_longname = "QNX Neutrino procfs child process"; + procfs_ops.to_doc = + "QNX Neutrino procfs child process (started by the \"run\" command).\n\ + target procfs "; + procfs_ops.to_open = procfs_open; + procfs_ops.to_attach = procfs_attach; + procfs_ops.to_post_attach = procfs_post_attach; + procfs_ops.to_detach = procfs_detach; + procfs_ops.to_resume = procfs_resume; + procfs_ops.to_wait = procfs_wait; + procfs_ops.to_fetch_registers = procfs_fetch_registers; + procfs_ops.to_store_registers = procfs_store_registers; + procfs_ops.to_prepare_to_store = procfs_prepare_to_store; + procfs_ops.to_xfer_memory = procfs_xfer_memory; + procfs_ops.to_files_info = procfs_files_info; + procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint; + procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint; + procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint; + procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint; + procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint; + procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint; + procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint; + procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint; + procfs_ops.to_terminal_init = terminal_init_inferior; + procfs_ops.to_terminal_inferior = terminal_inferior; + procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output; + procfs_ops.to_terminal_ours = terminal_ours; + procfs_ops.to_terminal_info = child_terminal_info; + procfs_ops.to_kill = procfs_kill_inferior; + procfs_ops.to_create_inferior = procfs_create_inferior; + procfs_ops.to_mourn_inferior = procfs_mourn_inferior; + procfs_ops.to_can_run = procfs_can_run; + procfs_ops.to_notice_signals = procfs_notice_signals; + procfs_ops.to_thread_alive = procfs_thread_alive; + procfs_ops.to_find_new_threads = procfs_find_new_threads; + procfs_ops.to_pid_to_str = procfs_pid_to_str; + procfs_ops.to_stop = procfs_stop; + procfs_ops.to_stratum = process_stratum; + procfs_ops.to_has_all_memory = 1; + procfs_ops.to_has_memory = 1; + procfs_ops.to_has_stack = 1; + procfs_ops.to_has_registers = 1; + procfs_ops.to_has_execution = 1; + procfs_ops.to_magic = OPS_MAGIC; + procfs_ops.to_have_continuable_watchpoint = 1; +} + +#define OSTYPE_NTO 1 + +void +_initialize_procfs (void) +{ + sigset_t set; + + init_procfs_ops (); + add_target (&procfs_ops); + + /* We use SIGUSR1 to gain control after we block waiting for a process. + We use sigwaitevent to wait. */ + sigemptyset (&set); + sigaddset (&set, SIGUSR1); + sigprocmask (SIG_BLOCK, &set, NULL); + + /* Set up trace and fault sets, as gdb expects them. */ + sigemptyset (&run.trace); + notice_signals (); + + /* Stuff some information. */ + nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags; + nto_cpuinfo_valid = 1; + + add_info ("pidlist", procfs_pidlist, "pidlist"); + add_info ("meminfo", procfs_meminfo, "memory information"); +} + + +static int +procfs_hw_watchpoint (int addr, int len, int type) +{ + procfs_break brk; + + switch (type) + { + case 1: /* Read. */ + brk.type = _DEBUG_BREAK_RD; + break; + case 2: /* Read/Write. */ + brk.type = _DEBUG_BREAK_RW; + break; + default: /* Modify. */ +/* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason. */ + brk.type = _DEBUG_BREAK_RW; + } + brk.type |= _DEBUG_BREAK_HW; /* Always ask for HW. */ + brk.addr = addr; + brk.size = len; + + errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); + if (errno != EOK) + { + perror ("Failed to set hardware watchpoint"); + return -1; + } + return 0; +} + +static int +procfs_can_use_hw_breakpoint (int type, int cnt, int othertype) +{ + return 1; +} + +static int +procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type) +{ + return procfs_hw_watchpoint (addr, -1, type); +} + +static int +procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type) +{ + return procfs_hw_watchpoint (addr, len, type); +} + +static int +procfs_stopped_by_watchpoint (void) +{ + return 0; +} diff --git a/contrib/gdb/gdb/nto-tdep.c b/contrib/gdb/gdb/nto-tdep.c new file mode 100755 index 00000000000..056b93f5b1a --- /dev/null +++ b/contrib/gdb/gdb/nto-tdep.c @@ -0,0 +1,337 @@ +/* nto-tdep.c - general QNX Neutrino target functionality. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by QNX Software Systems Ltd. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "gdb_stat.h" +#include "gdb_string.h" +#include "nto-tdep.h" +#include "top.h" +#include "cli/cli-decode.h" +#include "cli/cli-cmds.h" +#include "inferior.h" +#include "gdbarch.h" +#include "bfd.h" +#include "elf-bfd.h" +#include "solib-svr4.h" +#include "gdbcore.h" + +#ifdef __CYGWIN__ +#include +#endif + +#ifdef __CYGWIN__ +static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6"; +#elif defined(__sun__) || defined(linux) +static char default_nto_target[] = "/opt/QNXsdk/target/qnx6"; +#else +static char default_nto_target[] = ""; +#endif + +struct nto_target_ops current_nto_target; + +static char * +nto_target (void) +{ + char *p = getenv ("QNX_TARGET"); + +#ifdef __CYGWIN__ + static char buf[PATH_MAX]; + if (p) + cygwin_conv_to_posix_path (p, buf); + else + cygwin_conv_to_posix_path (default_nto_target, buf); + return buf; +#else + return p ? p : default_nto_target; +#endif +} + +/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86, + CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */ +int +nto_map_arch_to_cputype (const char *arch) +{ + if (!strcmp (arch, "i386") || !strcmp (arch, "x86")) + return CPUTYPE_X86; + if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc")) + return CPUTYPE_PPC; + if (!strcmp (arch, "mips")) + return CPUTYPE_MIPS; + if (!strcmp (arch, "arm")) + return CPUTYPE_ARM; + if (!strcmp (arch, "sh")) + return CPUTYPE_SH; + return CPUTYPE_UNKNOWN; +} + +int +nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname) +{ + char *buf, arch_path[PATH_MAX], *nto_root, *endian; + const char *arch; + char *path_fmt = "%s/lib:%s/usr/lib:%s/usr/photon/lib\ +:%s/usr/photon/dll:%s/lib/dll"; + + nto_root = nto_target (); + if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0) + { + arch = "x86"; + endian = ""; + } + else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0 + || strcmp (TARGET_ARCHITECTURE->arch_name, "powerpc") == 0) + { + arch = "ppc"; + endian = "be"; + } + else + { + arch = TARGET_ARCHITECTURE->arch_name; + endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le"; + } + + sprintf (arch_path, "%s/%s%s", nto_root, arch, endian); + + buf = alloca (strlen (path_fmt) + strlen (arch_path) * 5 + 1); + sprintf (buf, path_fmt, arch_path, arch_path, arch_path, arch_path, + arch_path); + + return openp (buf, 1, solib, o_flags, 0, temp_pathname); +} + +void +nto_init_solib_absolute_prefix (void) +{ + char buf[PATH_MAX * 2], arch_path[PATH_MAX]; + char *nto_root, *endian; + const char *arch; + + nto_root = nto_target (); + if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0) + { + arch = "x86"; + endian = ""; + } + else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0 + || strcmp (TARGET_ARCHITECTURE->arch_name, "powerpc") == 0) + { + arch = "ppc"; + endian = "be"; + } + else + { + arch = TARGET_ARCHITECTURE->arch_name; + endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le"; + } + + sprintf (arch_path, "%s/%s%s", nto_root, arch, endian); + + sprintf (buf, "set solib-absolute-prefix %s", arch_path); + execute_command (buf, 0); +} + +char ** +nto_parse_redirection (char *pargv[], char **pin, char **pout, char **perr) +{ + char **argv; + char *in, *out, *err, *p; + int argc, i, n; + + for (n = 0; pargv[n]; n++); + if (n == 0) + return NULL; + in = ""; + out = ""; + err = ""; + + argv = xcalloc (n + 1, sizeof argv[0]); + argc = n; + for (i = 0, n = 0; n < argc; n++) + { + p = pargv[n]; + if (*p == '>') + { + p++; + if (*p) + out = p; + else + out = pargv[++n]; + } + else if (*p == '<') + { + p++; + if (*p) + in = p; + else + in = pargv[++n]; + } + else if (*p++ == '2' && *p++ == '>') + { + if (*p == '&' && *(p + 1) == '1') + err = out; + else if (*p) + err = p; + else + err = pargv[++n]; + } + else + argv[i++] = pargv[n]; + } + *pin = in; + *pout = out; + *perr = err; + return argv; +} + +/* The struct lm_info, LM_ADDR, and nto_truncate_ptr are copied from + solib-svr4.c to support nto_relocate_section_addresses + which is different from the svr4 version. */ + +struct lm_info +{ + /* Pointer to copy of link map from inferior. The type is char * + rather than void *, so that we may use byte offsets to find the + various fields without the need for a cast. */ + char *lm; +}; + +static CORE_ADDR +LM_ADDR (struct so_list *so) +{ + struct link_map_offsets *lmo = nto_fetch_link_map_offsets (); + + return (CORE_ADDR) extract_signed_integer (so->lm_info->lm + + lmo->l_addr_offset, + lmo->l_addr_size); +} + +static CORE_ADDR +nto_truncate_ptr (CORE_ADDR addr) +{ + if (TARGET_PTR_BIT == sizeof (CORE_ADDR) * 8) + /* We don't need to truncate anything, and the bit twiddling below + will fail due to overflow problems. */ + return addr; + else + return addr & (((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1); +} + +Elf_Internal_Phdr * +find_load_phdr (bfd *abfd) +{ + Elf_Internal_Phdr *phdr; + unsigned int i; + + if (!elf_tdata (abfd)) + return NULL; + + phdr = elf_tdata (abfd)->phdr; + for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) + { + if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) + return phdr; + } + return NULL; +} + +void +nto_relocate_section_addresses (struct so_list *so, struct section_table *sec) +{ + /* Neutrino treats the l_addr base address field in link.h as different than + the base address in the System V ABI and so the offset needs to be + calculated and applied to relocations. */ + Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd); + unsigned vaddr = phdr ? phdr->p_vaddr : 0; + + sec->addr = nto_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr); + sec->endaddr = nto_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr); +} + +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, + int which, CORE_ADDR reg_addr) +{ + nto_regset_t regset; + +/* See corelow.c:get_core_registers for values of WHICH. */ + if (which == 0) + { + memcpy ((char *) ®set, core_reg_sect, + min (core_reg_size, sizeof (regset))); + nto_supply_gregset ((char *) ®set); + } + else if (which == 2) + { + memcpy ((char *) ®set, core_reg_sect, + min (core_reg_size, sizeof (regset))); + nto_supply_fpregset ((char *) ®set); + } +} + +void +nto_dummy_supply_regset (char *regs) +{ + /* Do nothing. */ +} + +/* Register that we are able to handle ELF file formats using standard + procfs "regset" structures. */ +static struct core_fns regset_core_fns = { + bfd_target_elf_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +void +_initialize_nto_tdep (void) +{ + add_setshow_cmd ("nto-debug", class_maintenance, var_zinteger, + &nto_internal_debugging, "Set QNX NTO internal debugging.\n\ +When non-zero, nto specific debug info is\n\ +displayed. Different information is displayed\n\ +for different positive values.", "Show QNX NTO internal debugging.\n", + NULL, NULL, &setdebuglist, &showdebuglist); + + /* We use SIG45 for pulses, or something, so nostop, noprint + and pass them. */ + signal_stop_update (target_signal_from_name ("SIG45"), 0); + signal_print_update (target_signal_from_name ("SIG45"), 0); + signal_pass_update (target_signal_from_name ("SIG45"), 1); + + /* By default we don't want to stop on these two, but we do want to pass. */ +#if defined(SIGSELECT) + signal_stop_update (SIGSELECT, 0); + signal_print_update (SIGSELECT, 0); + signal_pass_update (SIGSELECT, 1); +#endif + +#if defined(SIGPHOTON) + signal_stop_update (SIGPHOTON, 0); + signal_print_update (SIGPHOTON, 0); + signal_pass_update (SIGPHOTON, 1); +#endif + + /* Register core file support. */ + add_core_fns (®set_core_fns); +} diff --git a/contrib/gdb/gdb/nto-tdep.h b/contrib/gdb/gdb/nto-tdep.h new file mode 100755 index 00000000000..e22e8fd525c --- /dev/null +++ b/contrib/gdb/gdb/nto-tdep.h @@ -0,0 +1,156 @@ +/* nto-tdep.h - QNX Neutrino target header. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by QNX Software Systems Ltd. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _NTO_TDEP_H +#define _NTO_TDEP_H + +#include "defs.h" +#include "solist.h" + +/* Generic functions in nto-tdep.c. */ + +extern void nto_init_solib_absolute_prefix (void); + +char **nto_parse_redirection (char *start_argv[], char **in, + char **out, char **err); + +int proc_iterate_over_mappings (int (*func) (int, CORE_ADDR)); + +void nto_relocate_section_addresses (struct so_list *, struct section_table *); + +int nto_map_arch_to_cputype (const char *); + +int nto_find_and_open_solib (char *, unsigned, char **); + +/* Dummy function for initializing nto_target_ops on targets which do + not define a particular regset. */ +void nto_dummy_supply_regset (char *regs); + +/* Target operations defined for Neutrino targets (-nto-tdep.c). */ + +struct nto_target_ops +{ + int nto_internal_debugging; + unsigned nto_cpuinfo_flags; + int nto_cpuinfo_valid; + + int (*nto_regset_id) (int); + void (*nto_supply_gregset) (char *); + void (*nto_supply_fpregset) (char *); + void (*nto_supply_altregset) (char *); + void (*nto_supply_regset) (int, char *); + int (*nto_register_area) (int, int, unsigned *); + int (*nto_regset_fill) (int, char *); + struct link_map_offsets *(*nto_fetch_link_map_offsets) (void); +}; + +extern struct nto_target_ops current_nto_target; + +/* For 'maintenance debug nto-debug' command. */ +#define nto_internal_debugging \ + (current_nto_target.nto_internal_debugging) + +/* The CPUINFO flags from the remote. Currently used by + i386 for fxsave but future proofing other hosts. + This is initialized in procfs_attach or nto_start_remote + depending on our host/target. It would only be invalid + if we were talking to an older pdebug which didn't support + the cpuinfo message. */ +#define nto_cpuinfo_flags \ + (current_nto_target.nto_cpuinfo_flags) + +/* True if successfully retrieved cpuinfo from remote. */ +#define nto_cpuinfo_valid \ + (current_nto_target.nto_cpuinfo_valid) + +/* Given a register, return an id that represents the Neutrino + regset it came from. If reg == -1 update all regsets. */ +#define nto_regset_id(reg) \ + (*current_nto_target.nto_regset_id) (reg) + +#define nto_supply_gregset(regs) \ + (*current_nto_target.nto_supply_gregset) (regs) + +#define nto_supply_fpregset(regs) \ + (*current_nto_target.nto_supply_fpregset) (regs) + +#define nto_supply_altregset(regs) \ + (*current_nto_target.nto_supply_altregset) (regs) + +/* Given a regset, tell gdb about registers stored in data. */ +#define nto_supply_regset(regset, data) \ + (*current_nto_target.nto_supply_regset) (regset, data) + +/* Given a register and regset, calculate the offset into the regset + and stuff it into the last argument. If regno is -1, calculate the + size of the entire regset. Returns length of data, -1 if unknown + regset, 0 if unknown register. */ +#define nto_register_area(reg, regset, off) \ + (*current_nto_target.nto_register_area) (reg, regset, off) + +/* Build the Neutrino register set info into the data buffer. + Return -1 if unknown regset, 0 otherwise. */ +#define nto_regset_fill(regset, data) \ + (*current_nto_target.nto_regset_fill) (regset, data) + +/* Gives the fetch_link_map_offsets function exposure outside of + solib-svr4.c so that we can override relocate_section_addresses(). */ +#define nto_fetch_link_map_offsets() \ + (*current_nto_target.nto_fetch_link_map_offsets) () + +/* Keep this consistant with neutrino syspage.h. */ +enum +{ + CPUTYPE_X86, + CPUTYPE_PPC, + CPUTYPE_MIPS, + CPUTYPE_SPARE, + CPUTYPE_ARM, + CPUTYPE_SH, + CPUTYPE_UNKNOWN +}; + +enum +{ + OSTYPE_QNX4, + OSTYPE_NTO +}; + +/* These correspond to the DSMSG_* versions in dsmsgs.h. */ +enum +{ + NTO_REG_GENERAL, + NTO_REG_FLOAT, + NTO_REG_SYSTEM, + NTO_REG_ALT, + NTO_REG_END +}; + +typedef char qnx_reg64[8]; + +typedef struct _debug_regs +{ + qnx_reg64 padding[1024]; +} nto_regset_t; + +#endif diff --git a/contrib/gdb/gdb/objc-exp.c b/contrib/gdb/gdb/objc-exp.c new file mode 100644 index 00000000000..dfeba70445d --- /dev/null +++ b/contrib/gdb/gdb/objc-exp.c @@ -0,0 +1,3464 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + INT = 258, + FLOAT = 259, + STRING = 260, + NSSTRING = 261, + SELECTOR = 262, + NAME = 263, + TYPENAME = 264, + CLASSNAME = 265, + NAME_OR_INT = 266, + STRUCT = 267, + CLASS = 268, + UNION = 269, + ENUM = 270, + SIZEOF = 271, + UNSIGNED = 272, + COLONCOLON = 273, + TEMPLATE = 274, + ERROR = 275, + SIGNED_KEYWORD = 276, + LONG = 277, + SHORT = 278, + INT_KEYWORD = 279, + CONST_KEYWORD = 280, + VOLATILE_KEYWORD = 281, + DOUBLE_KEYWORD = 282, + VARIABLE = 283, + ASSIGN_MODIFY = 284, + ABOVE_COMMA = 285, + OROR = 286, + ANDAND = 287, + NOTEQUAL = 288, + EQUAL = 289, + GEQ = 290, + LEQ = 291, + RSH = 292, + LSH = 293, + DECREMENT = 294, + INCREMENT = 295, + UNARY = 296, + ARROW = 297, + BLOCKNAME = 298 + }; +#endif +#define INT 258 +#define FLOAT 259 +#define STRING 260 +#define NSSTRING 261 +#define SELECTOR 262 +#define NAME 263 +#define TYPENAME 264 +#define CLASSNAME 265 +#define NAME_OR_INT 266 +#define STRUCT 267 +#define CLASS 268 +#define UNION 269 +#define ENUM 270 +#define SIZEOF 271 +#define UNSIGNED 272 +#define COLONCOLON 273 +#define TEMPLATE 274 +#define ERROR 275 +#define SIGNED_KEYWORD 276 +#define LONG 277 +#define SHORT 278 +#define INT_KEYWORD 279 +#define CONST_KEYWORD 280 +#define VOLATILE_KEYWORD 281 +#define DOUBLE_KEYWORD 282 +#define VARIABLE 283 +#define ASSIGN_MODIFY 284 +#define ABOVE_COMMA 285 +#define OROR 286 +#define ANDAND 287 +#define NOTEQUAL 288 +#define EQUAL 289 +#define GEQ 290 +#define LEQ 291 +#define RSH 292 +#define LSH 293 +#define DECREMENT 294 +#define INCREMENT 295 +#define UNARY 296 +#define ARROW 297 +#define BLOCKNAME 298 + + + + +/* Copy the first part of user declarations. */ +#line 37 "objc-exp.y" + + +#include "defs.h" +#include "gdb_string.h" +#include +#include "expression.h" + +#include "objc-lang.h" /* For objc language constructs. */ + +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "c-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols. */ +#include "top.h" +#include "completer.h" /* For skip_quoted(). */ +#include "block.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, + etc), as well as gratuitiously global symbol names, so we can have + multiple yacc generated parsers in gdb. Note that these are only + the variables produced by yacc. If other parser generators (bison, + byacc, etc) produce additional global names that conflict at link + time, then those parser generators need to be fixed instead of + adding those names to this list. */ + +#define yymaxdepth objc_maxdepth +#define yyparse objc_parse +#define yylex objc_lex +#define yyerror objc_error +#define yylval objc_lval +#define yychar objc_char +#define yydebug objc_debug +#define yypact objc_pact +#define yyr1 objc_r1 +#define yyr2 objc_r2 +#define yydef objc_def +#define yychk objc_chk +#define yypgo objc_pgo +#define yyact objc_act +#define yyexca objc_exca +#define yyerrflag objc_errflag +#define yynerrs objc_nerrs +#define yyps objc_ps +#define yypv objc_pv +#define yys objc_s +#define yy_yys objc_yys +#define yystate objc_state +#define yytmp objc_tmp +#define yyv objc_v +#define yy_yyv objc_yyv +#define yyval objc_val +#define yylloc objc_lloc +#define yyreds objc_reds /* With YYDEBUG defined */ +#define yytoks objc_toks /* With YYDEBUG defined */ +#define yyname objc_name /* With YYDEBUG defined */ +#define yyrule objc_rule /* With YYDEBUG defined */ +#define yylhs objc_yylhs +#define yylen objc_yylen +#define yydefred objc_yydefred +#define yydgoto objc_yydgoto +#define yysindex objc_yysindex +#define yyrindex objc_yyrindex +#define yygindex objc_yygindex +#define yytable objc_yytable +#define yycheck objc_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 0 /* Default to no yydebug support. */ +#endif + +int +yyparse PARAMS ((void)); + +static int +yylex PARAMS ((void)); + +void +yyerror PARAMS ((char *)); + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 126 "objc-exp.y" +typedef union YYSTYPE { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val_int; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; + struct symbol *sym; + struct type *tval; + struct stoken sval; + struct ttype tsym; + struct symtoken ssym; + int voidval; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + struct objc_class_str class; + + struct type **tvec; + int *ivec; + } YYSTYPE; +/* Line 191 of yacc.c. */ +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ +#line 151 "objc-exp.y" + +/* YYSTYPE gets defined by %union. */ +static int +parse_number PARAMS ((char *, int, int, YYSTYPE *)); + + +/* Line 214 of yacc.c. */ + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or xmalloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC xmalloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 89 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 772 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 68 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 29 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 147 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 239 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 298 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 61, 2, 2, 2, 52, 38, 2, + 58, 65, 50, 48, 30, 49, 56, 51, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 64, 2, + 41, 32, 42, 33, 47, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 57, 2, 63, 37, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 66, 36, 67, 62, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 31, 34, 35, 39, 40, + 43, 44, 45, 46, 53, 54, 55, 59, 60 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 11, 15, 18, 21, + 24, 27, 30, 33, 36, 39, 42, 45, 49, 53, + 58, 62, 66, 71, 76, 77, 83, 84, 90, 91, + 97, 99, 101, 103, 106, 110, 113, 116, 117, 123, + 125, 126, 128, 132, 134, 138, 143, 148, 152, 156, + 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, + 200, 204, 208, 212, 216, 220, 224, 228, 234, 238, + 242, 244, 246, 248, 250, 252, 254, 259, 261, 263, + 265, 269, 273, 277, 282, 284, 287, 289, 291, 294, + 297, 300, 304, 308, 310, 313, 315, 318, 320, 324, + 327, 329, 332, 334, 337, 341, 344, 348, 350, 354, + 356, 358, 360, 362, 364, 367, 371, 374, 378, 382, + 387, 390, 394, 396, 399, 402, 405, 408, 411, 414, + 416, 419, 421, 427, 430, 433, 435, 437, 439, 441, + 443, 447, 449, 451, 453, 455, 457, 459 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 69, 0, -1, 71, -1, 70, -1, 91, -1, 72, + -1, 71, 30, 72, -1, 50, 72, -1, 38, 72, + -1, 49, 72, -1, 61, 72, -1, 62, 72, -1, + 54, 72, -1, 53, 72, -1, 72, 54, -1, 72, + 53, -1, 16, 72, -1, 72, 59, 95, -1, 72, + 59, 85, -1, 72, 59, 50, 72, -1, 72, 56, + 95, -1, 72, 56, 85, -1, 72, 56, 50, 72, + -1, 72, 57, 71, 63, -1, -1, 57, 9, 73, + 76, 63, -1, -1, 57, 10, 74, 76, 63, -1, + -1, 57, 72, 75, 76, 63, -1, 95, -1, 77, + -1, 78, -1, 77, 78, -1, 95, 64, 72, -1, + 64, 72, -1, 30, 72, -1, -1, 72, 58, 79, + 81, 65, -1, 66, -1, -1, 72, -1, 81, 30, + 72, -1, 67, -1, 80, 81, 82, -1, 80, 91, + 82, 72, -1, 58, 91, 65, 72, -1, 58, 71, + 65, -1, 72, 47, 72, -1, 72, 50, 72, -1, + 72, 51, 72, -1, 72, 52, 72, -1, 72, 48, + 72, -1, 72, 49, 72, -1, 72, 46, 72, -1, + 72, 45, 72, -1, 72, 40, 72, -1, 72, 39, + 72, -1, 72, 44, 72, -1, 72, 43, 72, -1, + 72, 41, 72, -1, 72, 42, 72, -1, 72, 38, + 72, -1, 72, 37, 72, -1, 72, 36, 72, -1, + 72, 35, 72, -1, 72, 34, 72, -1, 72, 33, + 72, 64, 72, -1, 72, 32, 72, -1, 72, 29, + 72, -1, 3, -1, 11, -1, 4, -1, 84, -1, + 28, -1, 7, -1, 16, 58, 91, 65, -1, 5, + -1, 6, -1, 60, -1, 83, 18, 95, -1, 83, + 18, 95, -1, 92, 18, 95, -1, 92, 18, 62, + 95, -1, 85, -1, 18, 95, -1, 96, -1, 92, + -1, 92, 25, -1, 92, 26, -1, 92, 87, -1, + 92, 25, 87, -1, 92, 26, 87, -1, 50, -1, + 50, 87, -1, 38, -1, 38, 87, -1, 88, -1, + 58, 87, 65, -1, 88, 89, -1, 89, -1, 88, + 90, -1, 90, -1, 57, 63, -1, 57, 3, 63, + -1, 58, 65, -1, 58, 94, 65, -1, 86, -1, + 92, 18, 50, -1, 9, -1, 10, -1, 24, -1, + 22, -1, 23, -1, 22, 24, -1, 17, 22, 24, + -1, 22, 22, -1, 22, 22, 24, -1, 17, 22, + 22, -1, 17, 22, 22, 24, -1, 23, 24, -1, + 17, 23, 24, -1, 27, -1, 22, 27, -1, 12, + 95, -1, 13, 95, -1, 14, 95, -1, 15, 95, + -1, 17, 93, -1, 17, -1, 21, 93, -1, 21, + -1, 19, 95, 41, 91, 42, -1, 25, 92, -1, + 26, 92, -1, 9, -1, 24, -1, 22, -1, 23, + -1, 91, -1, 94, 30, 91, -1, 8, -1, 60, + -1, 9, -1, 10, -1, 11, -1, 8, -1, 60, + -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 231, 231, 232, 235, 242, 243, 248, 252, 256, + 260, 264, 268, 272, 276, 280, 284, 288, 294, 301, + 305, 312, 320, 324, 333, 332, 354, 353, 369, 368, + 377, 379, 382, 383, 386, 388, 390, 397, 394, 404, + 408, 411, 415, 419, 422, 429, 435, 441, 447, 451, + 455, 459, 463, 467, 471, 475, 479, 483, 487, 491, + 495, 499, 503, 507, 511, 515, 519, 523, 527, 531, + 537, 544, 555, 562, 565, 569, 576, 584, 609, 617, + 634, 645, 661, 674, 699, 700, 734, 793, 799, 800, + 801, 803, 805, 809, 811, 813, 815, 817, 820, 822, + 827, 834, 836, 840, 842, 846, 848, 860, 861, 866, + 868, 876, 878, 880, 882, 884, 886, 888, 890, 892, + 894, 896, 898, 900, 902, 905, 908, 911, 914, 916, + 918, 920, 922, 929, 930, 933, 934, 940, 946, 955, + 960, 967, 968, 969, 970, 971, 974, 975 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "INT", "FLOAT", "STRING", "NSSTRING", + "SELECTOR", "NAME", "TYPENAME", "CLASSNAME", "NAME_OR_INT", "STRUCT", + "CLASS", "UNION", "ENUM", "SIZEOF", "UNSIGNED", "COLONCOLON", + "TEMPLATE", "ERROR", "SIGNED_KEYWORD", "LONG", "SHORT", "INT_KEYWORD", + "CONST_KEYWORD", "VOLATILE_KEYWORD", "DOUBLE_KEYWORD", "VARIABLE", + "ASSIGN_MODIFY", "','", "ABOVE_COMMA", "'='", "'?'", "OROR", "ANDAND", + "'|'", "'^'", "'&'", "NOTEQUAL", "EQUAL", "'<'", "'>'", "GEQ", "LEQ", + "RSH", "LSH", "'@'", "'+'", "'-'", "'*'", "'/'", "'%'", "DECREMENT", + "INCREMENT", "UNARY", "'.'", "'['", "'('", "ARROW", "BLOCKNAME", "'!'", + "'~'", "']'", "':'", "')'", "'{'", "'}'", "$accept", "start", + "type_exp", "exp1", "exp", "@1", "@2", "@3", "msglist", "msgarglist", + "msgarg", "@4", "lcurly", "arglist", "rcurly", "block", "variable", + "qualified_name", "ptype", "abs_decl", "direct_abs_decl", "array_mod", + "func_mod", "type", "typebase", "typename", "nonempty_typelist", "name", + "name_not_typename", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 44, 285, 61, 63, 286, 287, 124, 94, 38, 288, + 289, 60, 62, 290, 291, 292, 293, 64, 43, 45, + 42, 47, 37, 294, 295, 296, 46, 91, 40, 297, + 298, 33, 126, 93, 58, 41, 123, 125 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 68, 69, 69, 70, 71, 71, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 73, 72, 74, 72, 75, 72, + 76, 76, 77, 77, 78, 78, 78, 79, 72, 80, + 81, 81, 81, 82, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 83, + 83, 84, 85, 85, 84, 84, 84, 86, 86, 86, + 86, 86, 86, 87, 87, 87, 87, 87, 88, 88, + 88, 88, 88, 89, 89, 90, 90, 91, 91, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 93, 93, 93, 93, 94, + 94, 95, 95, 95, 95, 95, 96, 96 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 3, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, + 3, 3, 4, 4, 0, 5, 0, 5, 0, 5, + 1, 1, 1, 2, 3, 2, 2, 0, 5, 1, + 0, 1, 3, 1, 3, 4, 4, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, + 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, + 3, 3, 3, 4, 1, 2, 1, 1, 2, 2, + 2, 3, 3, 1, 2, 1, 2, 1, 3, 2, + 1, 2, 1, 2, 3, 2, 3, 1, 3, 1, + 1, 1, 1, 1, 2, 3, 2, 3, 3, 4, + 2, 3, 1, 2, 2, 2, 2, 2, 2, 1, + 2, 1, 5, 2, 2, 1, 1, 1, 1, 1, + 3, 1, 1, 1, 1, 1, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 0, 70, 72, 77, 78, 75, 146, 109, 110, 71, + 0, 0, 0, 0, 0, 129, 0, 0, 131, 112, + 113, 111, 0, 0, 122, 74, 0, 0, 0, 0, + 0, 0, 0, 147, 0, 0, 39, 0, 3, 2, + 5, 40, 0, 73, 84, 107, 4, 87, 86, 141, + 143, 144, 145, 142, 124, 125, 126, 127, 0, 16, + 0, 135, 137, 138, 136, 128, 85, 0, 137, 138, + 130, 116, 114, 123, 120, 133, 134, 8, 9, 7, + 13, 12, 24, 26, 28, 0, 0, 10, 11, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 14, 0, 0, 37, 0, 41, + 0, 0, 0, 0, 88, 89, 95, 93, 0, 0, + 90, 97, 100, 102, 0, 0, 118, 115, 121, 0, + 117, 0, 0, 0, 47, 0, 6, 69, 68, 0, + 66, 65, 64, 63, 62, 57, 56, 60, 61, 59, + 58, 55, 54, 48, 52, 53, 49, 50, 51, 143, + 144, 0, 21, 20, 0, 40, 0, 18, 17, 0, + 43, 44, 0, 81, 108, 0, 82, 91, 92, 96, + 94, 0, 103, 105, 0, 139, 87, 0, 0, 99, + 101, 76, 119, 0, 0, 0, 0, 31, 32, 30, + 0, 0, 46, 0, 22, 23, 0, 19, 42, 45, + 83, 104, 98, 0, 0, 106, 132, 36, 35, 25, + 33, 0, 0, 27, 29, 67, 38, 140, 34 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 37, 38, 85, 40, 141, 142, 143, 206, 207, + 208, 175, 41, 120, 181, 42, 43, 44, 45, 130, + 131, 132, 133, 195, 60, 65, 197, 209, 48 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -90 +static const short yypact[] = +{ + 223, -90, -90, -90, -90, -90, -90, -90, -90, -90, + 19, 19, 19, 19, 287, 195, 19, 19, 234, 82, + -9, -90, 307, 307, -90, -90, 223, 223, 223, 223, + 223, 351, 223, 8, 223, 223, -90, 39, -90, 13, + 542, 223, 32, -90, -90, -90, -90, 149, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, 223, 212, + 38, -90, 33, 45, -90, -90, -90, 30, -90, -90, + -90, 83, -90, -90, -90, -90, -90, 212, 212, 212, + 212, 212, 107, 108, 542, -20, 66, 212, 212, -90, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, -90, -90, 436, 223, -90, 480, 542, + -21, 65, 19, 202, 70, 70, 70, 70, -1, 132, + -90, 54, -90, -90, 68, 43, 110, -90, -90, 307, + -90, 113, 113, 113, -90, 223, 542, 542, 542, 509, + 567, 591, 614, 636, 657, 676, 676, 691, 691, 691, + 691, 334, 334, 703, 713, 713, 212, 212, 212, 107, + 108, 223, -90, -90, 4, 223, 223, -90, -90, 223, + -90, -90, 223, 118, -90, 19, -90, -90, -90, -90, + -90, 74, -90, -90, 73, -90, 158, -17, 51, -90, + -90, 415, -90, 106, 223, 223, 87, 113, -90, 88, + 97, 99, 212, 223, 212, -90, -16, 212, 542, 212, + -90, -90, -90, 114, 307, -90, -90, 542, 542, -90, + -90, 88, 223, -90, -90, 475, -90, -90, 542 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short yypgoto[] = +{ + -90, -90, -90, 3, -10, -90, -90, -90, -28, -90, + -44, -90, -90, -7, 50, -90, -90, -71, -90, -89, + -90, 47, 48, 1, 0, 163, -90, -5, -90 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -111 +static const short yytable[] = +{ + 47, 46, 191, 39, 59, 54, 55, 56, 57, 179, + 90, 66, 67, 224, 179, 74, 77, 78, 79, 80, + 81, 84, 75, 76, 87, 88, -79, 49, 50, 51, + 52, 119, 47, 86, 90, 187, 188, 189, 190, 89, + 194, 47, 121, 90, 172, 144, 180, 177, 225, 236, + 122, 49, 50, 51, 52, 136, 135, 137, 47, 134, + 7, 8, 192, 10, 11, 12, 13, 215, 15, 138, + 17, 139, 18, 19, 20, 21, 22, 23, 24, 53, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 53, 71, 185, 72, 140, 126, 73, + 173, 128, 198, 178, 210, 211, 193, 183, 186, 174, + 127, 49, 50, 51, 52, -109, -110, 128, 129, 196, + 186, 145, 180, 201, 202, 212, -80, 221, 222, 196, + 203, 7, 8, 204, 10, 11, 12, 13, 226, 15, + 229, 17, 232, 18, 19, 20, 21, 22, 23, 24, + 233, 214, 234, 230, 184, 119, 217, 123, 216, 218, + 126, 182, 219, 53, 124, 125, 223, 205, 199, 200, + 220, 70, 127, 124, 125, 0, 0, 126, 0, 128, + 129, 212, 0, 0, 227, 228, 126, 193, 196, 127, + 0, 0, 231, 235, 61, 0, 128, 129, 127, 0, + 49, 50, 51, 52, 0, 128, 129, 62, 63, 64, + 0, 0, 238, 0, 196, 237, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 61, 18, 19, 20, 21, 22, 23, + 24, 25, 184, 0, 0, 0, 68, 69, 64, 0, + 0, 26, 53, 0, 185, 113, 114, 0, 115, 116, + 117, 118, 27, 28, 0, 0, 29, 30, 0, 0, + 31, 32, 0, 33, 34, 35, 0, 0, 0, 36, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 0, 18, 19, + 20, 21, 22, 23, 24, 25, 7, 8, 0, 10, + 11, 12, 13, 0, 15, 26, 17, 0, 18, 19, + 20, 21, 22, 23, 24, 0, 27, 28, 0, 0, + 29, 30, 0, 0, 31, 58, 0, 33, 34, 35, + 0, 0, 0, 36, 1, 2, 3, 4, 5, 6, + 82, 83, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 0, 18, 19, 20, 21, 22, 23, 24, 25, + 0, 107, 108, 109, 110, 111, 112, 113, 114, 26, + 115, 116, 117, 118, 0, 0, 0, 0, 0, 0, + 27, 28, 0, 0, 29, 30, 0, 0, 31, 32, + 0, 33, 34, 35, 0, 0, 0, 36, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 0, 18, 19, 20, 21, + 22, 23, 24, 25, 49, 169, 170, 52, 10, 11, + 12, 13, 0, 15, 0, 17, 0, 18, 19, 20, + 21, 22, 23, 24, 0, 0, 0, 0, 29, 30, + 0, 0, 31, 32, 0, 33, 34, 35, 0, 0, + 0, 36, 0, 0, 0, 0, 171, 0, 49, 169, + 170, 52, 10, 11, 12, 13, 53, 15, 0, 17, + 0, 18, 19, 20, 21, 22, 23, 24, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 176, 115, 116, 117, 118, 0, 0, 0, 91, 0, + 53, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 0, 115, 116, 117, 118, 0, + 0, 91, 0, 213, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 0, 115, 116, + 117, 118, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 0, 115, 116, 117, 118, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 0, 115, 116, 117, + 118, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 0, + 115, 116, 117, 118, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 0, 115, 116, 117, 118, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 0, 115, 116, 117, 118, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 0, 115, 116, 117, 118, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 0, 115, 116, 117, + 118, 108, 109, 110, 111, 112, 113, 114, 0, 115, + 116, 117, 118, 110, 111, 112, 113, 114, 0, 115, + 116, 117, 118 +}; + +static const short yycheck[] = +{ + 0, 0, 3, 0, 14, 10, 11, 12, 13, 30, + 30, 16, 17, 30, 30, 24, 26, 27, 28, 29, + 30, 31, 22, 23, 34, 35, 18, 8, 9, 10, + 11, 41, 32, 32, 30, 124, 125, 126, 127, 0, + 129, 41, 41, 30, 115, 65, 67, 118, 65, 65, + 18, 8, 9, 10, 11, 22, 18, 24, 58, 58, + 9, 10, 63, 12, 13, 14, 15, 63, 17, 24, + 19, 41, 21, 22, 23, 24, 25, 26, 27, 60, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 60, 22, 62, 24, 24, 38, 27, + 115, 57, 58, 118, 142, 143, 65, 122, 123, 116, + 50, 8, 9, 10, 11, 18, 18, 57, 58, 129, + 135, 65, 67, 65, 24, 145, 18, 63, 65, 139, + 139, 9, 10, 30, 12, 13, 14, 15, 42, 17, + 63, 19, 64, 21, 22, 23, 24, 25, 26, 27, + 63, 171, 63, 207, 50, 175, 176, 18, 175, 179, + 38, 121, 182, 60, 25, 26, 18, 64, 131, 131, + 185, 18, 50, 25, 26, -1, -1, 38, -1, 57, + 58, 201, -1, -1, 204, 205, 38, 65, 198, 50, + -1, -1, 207, 213, 9, -1, 57, 58, 50, -1, + 8, 9, 10, 11, -1, 57, 58, 22, 23, 24, + -1, -1, 232, -1, 224, 224, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 9, 21, 22, 23, 24, 25, 26, + 27, 28, 50, -1, -1, -1, 22, 23, 24, -1, + -1, 38, 60, -1, 62, 53, 54, -1, 56, 57, + 58, 59, 49, 50, -1, -1, 53, 54, -1, -1, + 57, 58, -1, 60, 61, 62, -1, -1, -1, 66, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, -1, 21, 22, + 23, 24, 25, 26, 27, 28, 9, 10, -1, 12, + 13, 14, 15, -1, 17, 38, 19, -1, 21, 22, + 23, 24, 25, 26, 27, -1, 49, 50, -1, -1, + 53, 54, -1, -1, 57, 58, -1, 60, 61, 62, + -1, -1, -1, 66, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 47, 48, 49, 50, 51, 52, 53, 54, 38, + 56, 57, 58, 59, -1, -1, -1, -1, -1, -1, + 49, 50, -1, -1, 53, 54, -1, -1, 57, 58, + -1, 60, 61, 62, -1, -1, -1, 66, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, -1, 21, 22, 23, 24, + 25, 26, 27, 28, 8, 9, 10, 11, 12, 13, + 14, 15, -1, 17, -1, 19, -1, 21, 22, 23, + 24, 25, 26, 27, -1, -1, -1, -1, 53, 54, + -1, -1, 57, 58, -1, 60, 61, 62, -1, -1, + -1, 66, -1, -1, -1, -1, 50, -1, 8, 9, + 10, 11, 12, 13, 14, 15, 60, 17, -1, 19, + -1, 21, 22, 23, 24, 25, 26, 27, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 50, 56, 57, 58, 59, -1, -1, -1, 29, -1, + 60, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, -1, 56, 57, 58, 59, -1, + -1, 29, -1, 64, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, + 58, 59, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, -1, 56, 57, 58, 59, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, + 59, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, + 56, 57, 58, 59, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, -1, 56, 57, 58, 59, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, -1, 56, 57, 58, 59, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, -1, 56, 57, 58, 59, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, + 59, 48, 49, 50, 51, 52, 53, 54, -1, 56, + 57, 58, 59, 50, 51, 52, 53, 54, -1, 56, + 57, 58, 59 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, + 23, 24, 25, 26, 27, 28, 38, 49, 50, 53, + 54, 57, 58, 60, 61, 62, 66, 69, 70, 71, + 72, 80, 83, 84, 85, 86, 91, 92, 96, 8, + 9, 10, 11, 60, 95, 95, 95, 95, 58, 72, + 92, 9, 22, 23, 24, 93, 95, 95, 22, 23, + 93, 22, 24, 27, 24, 92, 92, 72, 72, 72, + 72, 72, 9, 10, 72, 71, 91, 72, 72, 0, + 30, 29, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 56, 57, 58, 59, 72, + 81, 91, 18, 18, 25, 26, 38, 50, 57, 58, + 87, 88, 89, 90, 91, 18, 22, 24, 24, 41, + 24, 73, 74, 75, 65, 65, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 9, + 10, 50, 85, 95, 71, 79, 50, 85, 95, 30, + 67, 82, 82, 95, 50, 62, 95, 87, 87, 87, + 87, 3, 63, 65, 87, 91, 92, 94, 58, 89, + 90, 65, 24, 91, 30, 64, 76, 77, 78, 95, + 76, 76, 72, 64, 72, 63, 81, 72, 72, 72, + 95, 63, 65, 18, 30, 65, 42, 72, 72, 63, + 78, 95, 64, 63, 63, 72, 65, 91, 72 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to xreallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to xreallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: +#line 236 "objc-exp.y" + { write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(yyvsp[0].tval); + write_exp_elt_opcode(OP_TYPE);} + break; + + case 6: +#line 244 "objc-exp.y" + { write_exp_elt_opcode (BINOP_COMMA); } + break; + + case 7: +#line 249 "objc-exp.y" + { write_exp_elt_opcode (UNOP_IND); } + break; + + case 8: +#line 253 "objc-exp.y" + { write_exp_elt_opcode (UNOP_ADDR); } + break; + + case 9: +#line 257 "objc-exp.y" + { write_exp_elt_opcode (UNOP_NEG); } + break; + + case 10: +#line 261 "objc-exp.y" + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + break; + + case 11: +#line 265 "objc-exp.y" + { write_exp_elt_opcode (UNOP_COMPLEMENT); } + break; + + case 12: +#line 269 "objc-exp.y" + { write_exp_elt_opcode (UNOP_PREINCREMENT); } + break; + + case 13: +#line 273 "objc-exp.y" + { write_exp_elt_opcode (UNOP_PREDECREMENT); } + break; + + case 14: +#line 277 "objc-exp.y" + { write_exp_elt_opcode (UNOP_POSTINCREMENT); } + break; + + case 15: +#line 281 "objc-exp.y" + { write_exp_elt_opcode (UNOP_POSTDECREMENT); } + break; + + case 16: +#line 285 "objc-exp.y" + { write_exp_elt_opcode (UNOP_SIZEOF); } + break; + + case 17: +#line 289 "objc-exp.y" + { write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (STRUCTOP_PTR); } + break; + + case 18: +#line 295 "objc-exp.y" + { /* exp->type::name becomes exp->*(&type::name) */ + /* Note: this doesn't work if name is a + static member! FIXME */ + write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (STRUCTOP_MPTR); } + break; + + case 19: +#line 302 "objc-exp.y" + { write_exp_elt_opcode (STRUCTOP_MPTR); } + break; + + case 20: +#line 306 "objc-exp.y" + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (STRUCTOP_STRUCT); } + break; + + case 21: +#line 313 "objc-exp.y" + { /* exp.type::name becomes exp.*(&type::name) */ + /* Note: this doesn't work if name is a + static member! FIXME */ + write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (STRUCTOP_MEMBER); } + break; + + case 22: +#line 321 "objc-exp.y" + { write_exp_elt_opcode (STRUCTOP_MEMBER); } + break; + + case 23: +#line 325 "objc-exp.y" + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + break; + + case 24: +#line 333 "objc-exp.y" + { + CORE_ADDR class; + + class = lookup_objc_class (copy_name (yyvsp[0].tsym.stoken)); + if (class == 0) + error ("%s is not an ObjC Class", + copy_name (yyvsp[0].tsym.stoken)); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst ((LONGEST) class); + write_exp_elt_opcode (OP_LONG); + start_msglist(); + } + break; + + case 25: +#line 347 "objc-exp.y" + { write_exp_elt_opcode (OP_OBJC_MSGCALL); + end_msglist(); + write_exp_elt_opcode (OP_OBJC_MSGCALL); + } + break; + + case 26: +#line 354 "objc-exp.y" + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst ((LONGEST) yyvsp[0].class.class); + write_exp_elt_opcode (OP_LONG); + start_msglist(); + } + break; + + case 27: +#line 362 "objc-exp.y" + { write_exp_elt_opcode (OP_OBJC_MSGCALL); + end_msglist(); + write_exp_elt_opcode (OP_OBJC_MSGCALL); + } + break; + + case 28: +#line 369 "objc-exp.y" + { start_msglist(); } + break; + + case 29: +#line 371 "objc-exp.y" + { write_exp_elt_opcode (OP_OBJC_MSGCALL); + end_msglist(); + write_exp_elt_opcode (OP_OBJC_MSGCALL); + } + break; + + case 30: +#line 378 "objc-exp.y" + { add_msglist(&yyvsp[0].sval, 0); } + break; + + case 34: +#line 387 "objc-exp.y" + { add_msglist(&yyvsp[-2].sval, 1); } + break; + + case 35: +#line 389 "objc-exp.y" + { add_msglist(0, 1); } + break; + + case 36: +#line 391 "objc-exp.y" + { add_msglist(0, 0); } + break; + + case 37: +#line 397 "objc-exp.y" + { start_arglist (); } + break; + + case 38: +#line 399 "objc-exp.y" + { write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) end_arglist ()); + write_exp_elt_opcode (OP_FUNCALL); } + break; + + case 39: +#line 405 "objc-exp.y" + { start_arglist (); } + break; + + case 41: +#line 412 "objc-exp.y" + { arglist_len = 1; } + break; + + case 42: +#line 416 "objc-exp.y" + { arglist_len++; } + break; + + case 43: +#line 420 "objc-exp.y" + { yyval.lval = end_arglist () - 1; } + break; + + case 44: +#line 423 "objc-exp.y" + { write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_ARRAY); } + break; + + case 45: +#line 430 "objc-exp.y" + { write_exp_elt_opcode (UNOP_MEMVAL); + write_exp_elt_type (yyvsp[-2].tval); + write_exp_elt_opcode (UNOP_MEMVAL); } + break; + + case 46: +#line 436 "objc-exp.y" + { write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (yyvsp[-2].tval); + write_exp_elt_opcode (UNOP_CAST); } + break; + + case 47: +#line 442 "objc-exp.y" + { } + break; + + case 48: +#line 448 "objc-exp.y" + { write_exp_elt_opcode (BINOP_REPEAT); } + break; + + case 49: +#line 452 "objc-exp.y" + { write_exp_elt_opcode (BINOP_MUL); } + break; + + case 50: +#line 456 "objc-exp.y" + { write_exp_elt_opcode (BINOP_DIV); } + break; + + case 51: +#line 460 "objc-exp.y" + { write_exp_elt_opcode (BINOP_REM); } + break; + + case 52: +#line 464 "objc-exp.y" + { write_exp_elt_opcode (BINOP_ADD); } + break; + + case 53: +#line 468 "objc-exp.y" + { write_exp_elt_opcode (BINOP_SUB); } + break; + + case 54: +#line 472 "objc-exp.y" + { write_exp_elt_opcode (BINOP_LSH); } + break; + + case 55: +#line 476 "objc-exp.y" + { write_exp_elt_opcode (BINOP_RSH); } + break; + + case 56: +#line 480 "objc-exp.y" + { write_exp_elt_opcode (BINOP_EQUAL); } + break; + + case 57: +#line 484 "objc-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 58: +#line 488 "objc-exp.y" + { write_exp_elt_opcode (BINOP_LEQ); } + break; + + case 59: +#line 492 "objc-exp.y" + { write_exp_elt_opcode (BINOP_GEQ); } + break; + + case 60: +#line 496 "objc-exp.y" + { write_exp_elt_opcode (BINOP_LESS); } + break; + + case 61: +#line 500 "objc-exp.y" + { write_exp_elt_opcode (BINOP_GTR); } + break; + + case 62: +#line 504 "objc-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + break; + + case 63: +#line 508 "objc-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + break; + + case 64: +#line 512 "objc-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + break; + + case 65: +#line 516 "objc-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + break; + + case 66: +#line 520 "objc-exp.y" + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + break; + + case 67: +#line 524 "objc-exp.y" + { write_exp_elt_opcode (TERNOP_COND); } + break; + + case 68: +#line 528 "objc-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN); } + break; + + case 69: +#line 532 "objc-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode (yyvsp[-1].opcode); + write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } + break; + + case 70: +#line 538 "objc-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (yyvsp[0].typed_val_int.type); + write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 71: +#line 545 "objc-exp.y" + { YYSTYPE val; + parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (val.typed_val_int.type); + write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 72: +#line 556 "objc-exp.y" + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type (yyvsp[0].typed_val_float.type); + write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval); + write_exp_elt_opcode (OP_DOUBLE); } + break; + + case 75: +#line 570 "objc-exp.y" + { + write_exp_elt_opcode (OP_OBJC_SELECTOR); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_OBJC_SELECTOR); } + break; + + case 76: +#line 577 "objc-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + CHECK_TYPEDEF (yyvsp[-1].tval); + write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 77: +#line 585 "objc-exp.y" + { /* C strings are converted into array + constants with an explicit null byte + added at the end. Thus the array upper + bound is the string length. There is no + such thing in C as a completely empty + string. */ + char *sp = yyvsp[0].sval.ptr; int count = yyvsp[0].sval.length; + while (count-- > 0) + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)(*sp++)); + write_exp_elt_opcode (OP_LONG); + } + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)'\0'); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) (yyvsp[0].sval.length)); + write_exp_elt_opcode (OP_ARRAY); } + break; + + case 78: +#line 612 "objc-exp.y" + { write_exp_elt_opcode (OP_OBJC_NSSTRING); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_OBJC_NSSTRING); } + break; + + case 79: +#line 618 "objc-exp.y" + { + if (yyvsp[0].ssym.sym != 0) + yyval.bval = SYMBOL_BLOCK_VALUE (yyvsp[0].ssym.sym); + else + { + struct symtab *tem = + lookup_symtab (copy_name (yyvsp[0].ssym.stoken)); + if (tem) + yyval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK); + else + error ("No file or function \"%s\".", + copy_name (yyvsp[0].ssym.stoken)); + } + } + break; + + case 80: +#line 635 "objc-exp.y" + { struct symbol *tem + = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) + error ("No function \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + yyval.bval = SYMBOL_BLOCK_VALUE (tem); } + break; + + case 81: +#line 646 "objc-exp.y" + { struct symbol *sym; + sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym == 0) + error ("No symbol \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + + write_exp_elt_opcode (OP_VAR_VALUE); + /* block_found is set by lookup_symbol. */ + write_exp_elt_block (block_found); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); } + break; + + case 82: +#line 662 "objc-exp.y" + { + struct type *type = yyvsp[-2].tval; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (type); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_SCOPE); + } + break; + + case 83: +#line 675 "objc-exp.y" + { + struct type *type = yyvsp[-3].tval; + struct stoken tmp_token; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + if (!DEPRECATED_STREQ (type_name_no_tag (type), yyvsp[0].sval.ptr)) + error ("invalid destructor `%s::~%s'", + type_name_no_tag (type), yyvsp[0].sval.ptr); + + tmp_token.ptr = (char*) alloca (yyvsp[0].sval.length + 2); + tmp_token.length = yyvsp[0].sval.length + 1; + tmp_token.ptr[0] = '~'; + memcpy (tmp_token.ptr+1, yyvsp[0].sval.ptr, yyvsp[0].sval.length); + tmp_token.ptr[tmp_token.length] = 0; + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (type); + write_exp_string (tmp_token); + write_exp_elt_opcode (OP_SCOPE); + } + break; + + case 85: +#line 701 "objc-exp.y" + { + char *name = copy_name (yyvsp[0].sval); + struct symbol *sym; + struct minimal_symbol *msymbol; + + sym = + lookup_symbol (name, (const struct block *) NULL, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym) + { + write_exp_elt_opcode (OP_VAR_VALUE); + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + break; + } + + msymbol = lookup_minimal_symbol (name, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", name); + } + break; + + case 86: +#line 735 "objc-exp.y" + { struct symbol *sym = yyvsp[0].ssym.sym; + + if (sym) + { + if (symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block_found, + innermost_block)) + innermost_block = block_found; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not + another more inner frame which happens to + be in the same block. */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + } + else if (yyvsp[0].ssym.is_a_field_of_this) + { + /* C++/ObjC: it hangs off of `this'/'self'. + Must not inadvertently convert from a + method call to data ref. */ + if (innermost_block == 0 || + contained_in (block_found, innermost_block)) + innermost_block = block_found; + write_exp_elt_opcode (OP_OBJC_SELF); + write_exp_elt_opcode (OP_OBJC_SELF); + write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string (yyvsp[0].ssym.stoken); + write_exp_elt_opcode (STRUCTOP_PTR); + } + else + { + struct minimal_symbol *msymbol; + char *arg = copy_name (yyvsp[0].ssym.stoken); + + msymbol = + lookup_minimal_symbol (arg, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (!have_full_symbols () && + !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", + copy_name (yyvsp[0].ssym.stoken)); + } + } + break; + + case 90: +#line 802 "objc-exp.y" + { yyval.tval = follow_types (yyvsp[-1].tval); } + break; + + case 91: +#line 804 "objc-exp.y" + { yyval.tval = follow_types (yyvsp[-2].tval); } + break; + + case 92: +#line 806 "objc-exp.y" + { yyval.tval = follow_types (yyvsp[-2].tval); } + break; + + case 93: +#line 810 "objc-exp.y" + { push_type (tp_pointer); yyval.voidval = 0; } + break; + + case 94: +#line 812 "objc-exp.y" + { push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; } + break; + + case 95: +#line 814 "objc-exp.y" + { push_type (tp_reference); yyval.voidval = 0; } + break; + + case 96: +#line 816 "objc-exp.y" + { push_type (tp_reference); yyval.voidval = yyvsp[0].voidval; } + break; + + case 98: +#line 821 "objc-exp.y" + { yyval.voidval = yyvsp[-1].voidval; } + break; + + case 99: +#line 823 "objc-exp.y" + { + push_type_int (yyvsp[0].lval); + push_type (tp_array); + } + break; + + case 100: +#line 828 "objc-exp.y" + { + push_type_int (yyvsp[0].lval); + push_type (tp_array); + yyval.voidval = 0; + } + break; + + case 101: +#line 835 "objc-exp.y" + { push_type (tp_function); } + break; + + case 102: +#line 837 "objc-exp.y" + { push_type (tp_function); } + break; + + case 103: +#line 841 "objc-exp.y" + { yyval.lval = -1; } + break; + + case 104: +#line 843 "objc-exp.y" + { yyval.lval = yyvsp[-1].typed_val_int.val; } + break; + + case 105: +#line 847 "objc-exp.y" + { yyval.voidval = 0; } + break; + + case 106: +#line 849 "objc-exp.y" + { free (yyvsp[-1].tvec); yyval.voidval = 0; } + break; + + case 108: +#line 862 "objc-exp.y" + { yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); } + break; + + case 109: +#line 867 "objc-exp.y" + { yyval.tval = yyvsp[0].tsym.type; } + break; + + case 110: +#line 869 "objc-exp.y" + { + if (yyvsp[0].class.type == NULL) + error ("No symbol \"%s\" in current context.", + copy_name(yyvsp[0].class.stoken)); + else + yyval.tval = yyvsp[0].class.type; + } + break; + + case 111: +#line 877 "objc-exp.y" + { yyval.tval = builtin_type_int; } + break; + + case 112: +#line 879 "objc-exp.y" + { yyval.tval = builtin_type_long; } + break; + + case 113: +#line 881 "objc-exp.y" + { yyval.tval = builtin_type_short; } + break; + + case 114: +#line 883 "objc-exp.y" + { yyval.tval = builtin_type_long; } + break; + + case 115: +#line 885 "objc-exp.y" + { yyval.tval = builtin_type_unsigned_long; } + break; + + case 116: +#line 887 "objc-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 117: +#line 889 "objc-exp.y" + { yyval.tval = builtin_type_long_long; } + break; + + case 118: +#line 891 "objc-exp.y" + { yyval.tval = builtin_type_unsigned_long_long; } + break; + + case 119: +#line 893 "objc-exp.y" + { yyval.tval = builtin_type_unsigned_long_long; } + break; + + case 120: +#line 895 "objc-exp.y" + { yyval.tval = builtin_type_short; } + break; + + case 121: +#line 897 "objc-exp.y" + { yyval.tval = builtin_type_unsigned_short; } + break; + + case 122: +#line 899 "objc-exp.y" + { yyval.tval = builtin_type_double; } + break; + + case 123: +#line 901 "objc-exp.y" + { yyval.tval = builtin_type_long_double; } + break; + + case 124: +#line 903 "objc-exp.y" + { yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 125: +#line 906 "objc-exp.y" + { yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 126: +#line 909 "objc-exp.y" + { yyval.tval = lookup_union (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 127: +#line 912 "objc-exp.y" + { yyval.tval = lookup_enum (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 128: +#line 915 "objc-exp.y" + { yyval.tval = lookup_unsigned_typename (TYPE_NAME(yyvsp[0].tsym.type)); } + break; + + case 129: +#line 917 "objc-exp.y" + { yyval.tval = builtin_type_unsigned_int; } + break; + + case 130: +#line 919 "objc-exp.y" + { yyval.tval = lookup_signed_typename (TYPE_NAME(yyvsp[0].tsym.type)); } + break; + + case 131: +#line 921 "objc-exp.y" + { yyval.tval = builtin_type_int; } + break; + + case 132: +#line 923 "objc-exp.y" + { yyval.tval = lookup_template_type(copy_name(yyvsp[-3].sval), yyvsp[-1].tval, + expression_context_block); + } + break; + + case 133: +#line 929 "objc-exp.y" + { yyval.tval = yyvsp[0].tval; } + break; + + case 134: +#line 930 "objc-exp.y" + { yyval.tval = yyvsp[0].tval; } + break; + + case 136: +#line 935 "objc-exp.y" + { + yyval.tsym.stoken.ptr = "int"; + yyval.tsym.stoken.length = 3; + yyval.tsym.type = builtin_type_int; + } + break; + + case 137: +#line 941 "objc-exp.y" + { + yyval.tsym.stoken.ptr = "long"; + yyval.tsym.stoken.length = 4; + yyval.tsym.type = builtin_type_long; + } + break; + + case 138: +#line 947 "objc-exp.y" + { + yyval.tsym.stoken.ptr = "short"; + yyval.tsym.stoken.length = 5; + yyval.tsym.type = builtin_type_short; + } + break; + + case 139: +#line 956 "objc-exp.y" + { yyval.tvec = (struct type **) xmalloc (sizeof (struct type *) * 2); + yyval.ivec[0] = 1; /* Number of types in vector. */ + yyval.tvec[1] = yyvsp[0].tval; + } + break; + + case 140: +#line 961 "objc-exp.y" + { int len = sizeof (struct type *) * (++(yyvsp[-2].ivec[0]) + 1); + yyval.tvec = (struct type **) xrealloc ((char *) yyvsp[-2].tvec, len); + yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval; + } + break; + + case 141: +#line 967 "objc-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + case 142: +#line 968 "objc-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + case 143: +#line 969 "objc-exp.y" + { yyval.sval = yyvsp[0].tsym.stoken; } + break; + + case 144: +#line 970 "objc-exp.y" + { yyval.sval = yyvsp[0].class.stoken; } + break; + + case 145: +#line 971 "objc-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + + } + +/* Line 991 of yacc.c. */ + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. Doesn't work in C++ */ +#ifndef __cplusplus +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 985 "objc-exp.y" + + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. LEN is the + number of characters in it. */ + +/*** Needs some error checking for the float case. ***/ + +static int +parse_number (p, len, parsed_float, putithere) + char *p; + int len; + int parsed_float; + YYSTYPE *putithere; +{ + /* FIXME: Shouldn't these be unsigned? We don't deal with negative + values here, and we do kind of silly things like cast to + unsigned. */ + LONGEST n = 0; + LONGEST prevn = 0; + unsigned LONGEST un; + + int i = 0; + int c; + int base = input_radix; + int unsigned_p = 0; + + /* Number of "L" suffixes encountered. */ + int long_p = 0; + + /* We have found a "L" or "U" suffix. */ + int found_suffix = 0; + + unsigned LONGEST high_bit; + struct type *signed_type; + struct type *unsigned_type; + + if (parsed_float) + { + char c; + + /* It's a float since it contains a point or an exponent. */ + + if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) + sscanf (p, "%g", (float *)&putithere->typed_val_float.dval); + else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) + sscanf (p, "%lg", (double *)&putithere->typed_val_float.dval); + else + { +#ifdef PRINTF_HAS_LONG_DOUBLE + sscanf (p, "%Lg", &putithere->typed_val_float.dval); +#else + /* Scan it into a double, then assign it to the long double. + This at least wins with values representable in the range + of doubles. */ + double temp; + sscanf (p, "%lg", &temp); + putithere->typed_val_float.dval = temp; +#endif + } + + /* See if it has `f' or `l' suffix (float or long double). */ + + c = tolower (p[len - 1]); + + if (c == 'f') + putithere->typed_val_float.type = builtin_type_float; + else if (c == 'l') + putithere->typed_val_float.type = builtin_type_long_double; + else if (isdigit (c) || c == '.') + putithere->typed_val_float.type = builtin_type_double; + else + return ERROR; + + return FLOAT; + } + + /* Handle base-switching prefixes 0x, 0t, 0d, and 0. */ + if (p[0] == '0') + switch (p[1]) + { + case 'x': + case 'X': + if (len >= 3) + { + p += 2; + base = 16; + len -= 2; + } + break; + + case 't': + case 'T': + case 'd': + case 'D': + if (len >= 3) + { + p += 2; + base = 10; + len -= 2; + } + break; + + default: + base = 8; + break; + } + + while (len-- > 0) + { + c = *p++; + if (c >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != 'l' && c != 'u') + n *= base; + if (c >= '0' && c <= '9') + { + if (found_suffix) + return ERROR; + n += i = c - '0'; + } + else + { + if (base > 10 && c >= 'a' && c <= 'f') + { + if (found_suffix) + return ERROR; + n += i = c - 'a' + 10; + } + else if (c == 'l') + { + ++long_p; + found_suffix = 1; + } + else if (c == 'u') + { + unsigned_p = 1; + found_suffix = 1; + } + else + return ERROR; /* Char not a digit. */ + } + if (i >= base) + return ERROR; /* Invalid digit in this base. */ + + /* Portably test for overflow (only works for nonzero values, so + make a second check for zero). FIXME: Can't we just make n + and prevn unsigned and avoid this? */ + if (c != 'l' && c != 'u' && (prevn >= n) && n != 0) + unsigned_p = 1; /* Try something unsigned. */ + + /* Portably test for unsigned overflow. + FIXME: This check is wrong; for example it doesn't find + overflow on 0x123456789 when LONGEST is 32 bits. */ + if (c != 'l' && c != 'u' && n != 0) + { + if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n)) + error ("Numeric constant too large."); + } + prevn = n; + } + + /* An integer constant is an int, a long, or a long long. An L + suffix forces it to be long; an LL suffix forces it to be long + long. If not forced to a larger size, it gets the first type of + the above that it fits in. To figure out whether it fits, we + shift it right and see whether anything remains. Note that we + can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one + operation, because many compilers will warn about such a shift + (which always produces a zero result). Sometimes TARGET_INT_BIT + or TARGET_LONG_BIT will be that big, sometimes not. To deal with + the case where it is we just always shift the value more than + once, with fewer bits each time. */ + + un = (unsigned LONGEST)n >> 2; + if (long_p == 0 + && (un >> (TARGET_INT_BIT - 2)) == 0) + { + high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1); + + /* A large decimal (not hex or octal) constant (between INT_MAX + and UINT_MAX) is a long or unsigned long, according to ANSI, + never an unsigned int, but this code treats it as unsigned + int. This probably should be fixed. GCC gives a warning on + such constants. */ + + unsigned_type = builtin_type_unsigned_int; + signed_type = builtin_type_int; + } + else if (long_p <= 1 + && (un >> (TARGET_LONG_BIT - 2)) == 0) + { + high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1); + unsigned_type = builtin_type_unsigned_long; + signed_type = builtin_type_long; + } + else + { + high_bit = (((unsigned LONGEST)1) + << (TARGET_LONG_LONG_BIT - 32 - 1) + << 16 + << 16); + if (high_bit == 0) + /* A long long does not fit in a LONGEST. */ + high_bit = + (unsigned LONGEST)1 << (sizeof (LONGEST) * HOST_CHAR_BIT - 1); + unsigned_type = builtin_type_unsigned_long_long; + signed_type = builtin_type_long_long; + } + + putithere->typed_val_int.val = n; + + /* If the high bit of the worked out type is set then this number + has to be unsigned. */ + + if (unsigned_p || (n & high_bit)) + { + putithere->typed_val_int.type = unsigned_type; + } + else + { + putithere->typed_val_int.type = signed_type; + } + + return INT; +} + +struct token +{ + char *operator; + int token; + enum exp_opcode opcode; +}; + +static const struct token tokentab3[] = + { + {">>=", ASSIGN_MODIFY, BINOP_RSH}, + {"<<=", ASSIGN_MODIFY, BINOP_LSH} + }; + +static const struct token tokentab2[] = + { + {"+=", ASSIGN_MODIFY, BINOP_ADD}, + {"-=", ASSIGN_MODIFY, BINOP_SUB}, + {"*=", ASSIGN_MODIFY, BINOP_MUL}, + {"/=", ASSIGN_MODIFY, BINOP_DIV}, + {"%=", ASSIGN_MODIFY, BINOP_REM}, + {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR}, + {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND}, + {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR}, + {"++", INCREMENT, BINOP_END}, + {"--", DECREMENT, BINOP_END}, + {"->", ARROW, BINOP_END}, + {"&&", ANDAND, BINOP_END}, + {"||", OROR, BINOP_END}, + {"::", COLONCOLON, BINOP_END}, + {"<<", LSH, BINOP_END}, + {">>", RSH, BINOP_END}, + {"==", EQUAL, BINOP_END}, + {"!=", NOTEQUAL, BINOP_END}, + {"<=", LEQ, BINOP_END}, + {">=", GEQ, BINOP_END} + }; + +/* Read one token, getting characters through lexptr. */ + +static int +yylex () +{ + int c, tokchr; + int namelen; + unsigned int i; + char *tokstart; + char *tokptr; + int tempbufindex; + static char *tempbuf; + static int tempbufsize; + + retry: + + tokstart = lexptr; + /* See if it is a special token of length 3. */ + for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) + if (DEPRECATED_STREQN (tokstart, tokentab3[i].operator, 3)) + { + lexptr += 3; + yylval.opcode = tokentab3[i].opcode; + return tokentab3[i].token; + } + + /* See if it is a special token of length 2. */ + for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) + if (DEPRECATED_STREQN (tokstart, tokentab2[i].operator, 2)) + { + lexptr += 2; + yylval.opcode = tokentab2[i].opcode; + return tokentab2[i].token; + } + + c = 0; + switch (tokchr = *tokstart) + { + case 0: + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '\'': + /* We either have a character constant ('0' or '\177' for + example) or we have a quoted symbol reference ('foo(int,int)' + in C++ for example). */ + lexptr++; + c = *lexptr++; + if (c == '\\') + c = parse_escape (&lexptr); + else if (c == '\'') + error ("Empty character constant."); + + yylval.typed_val_int.val = c; + yylval.typed_val_int.type = builtin_type_char; + + c = *lexptr++; + if (c != '\'') + { + namelen = skip_quoted (tokstart) - tokstart; + if (namelen > 2) + { + lexptr = tokstart + namelen; + if (lexptr[-1] != '\'') + error ("Unmatched single quote."); + namelen -= 2; + tokstart++; + goto tryname; + } + error ("Invalid character constant."); + } + return INT; + + case '(': + paren_depth++; + lexptr++; + return '('; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return ')'; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return ','; + + case '.': + /* Might be a floating point number. */ + if (lexptr[1] < '0' || lexptr[1] > '9') + goto symbol; /* Nope, must be a symbol. */ + /* FALL THRU into number case. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + /* It's a number. */ + int got_dot = 0, got_e = 0, toktype = FLOAT; + /* Initialize toktype to anything other than ERROR. */ + char *p = tokstart; + int hex = input_radix > 10; + int local_radix = input_radix; + if (tokchr == '0' && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + hex = 1; + local_radix = 16; + } + else if (tokchr == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) + { + p += 2; + hex = 0; + local_radix = 10; + } + + for (;; ++p) + { + /* This test includes !hex because 'e' is a valid hex digit + and thus does not indicate a floating point number when + the radix is hex. */ + + if (!hex && (*p == 'e' || *p == 'E')) + if (got_e) + toktype = ERROR; /* Only one 'e' in a float. */ + else + got_e = 1; + /* This test does not include !hex, because a '.' always + indicates a decimal floating point number regardless of + the radix. */ + else if (*p == '.') + if (got_dot) + toktype = ERROR; /* Only one '.' in a float. */ + else + got_dot = 1; + else if (got_e && (p[-1] == 'e' || p[-1] == 'E') && + (*p == '-' || *p == '+')) + /* This is the sign of the exponent, not the end of the + number. */ + continue; + /* Always take decimal digits; parse_number handles radix + error. */ + else if (*p >= '0' && *p <= '9') + continue; + /* We will take letters only if hex is true, and only up + to what the input radix would permit. FSF was content + to rely on parse_number to validate; but it leaks. */ + else if (*p >= 'a' && *p <= 'z') + { + if (!hex || *p >= ('a' + local_radix - 10)) + toktype = ERROR; + } + else if (*p >= 'A' && *p <= 'Z') + { + if (!hex || *p >= ('A' + local_radix - 10)) + toktype = ERROR; + } + else break; + } + if (toktype != ERROR) + toktype = parse_number (tokstart, p - tokstart, + got_dot | got_e, &yylval); + if (toktype == ERROR) + { + char *err_copy = (char *) alloca (p - tokstart + 1); + + memcpy (err_copy, tokstart, p - tokstart); + err_copy[p - tokstart] = 0; + error ("Invalid number \"%s\".", err_copy); + } + lexptr = p; + return toktype; + } + + case '+': + case '-': + case '*': + case '/': + case '%': + case '|': + case '&': + case '^': + case '~': + case '!': +#if 0 + case '@': /* Moved out below. */ +#endif + case '<': + case '>': + case '[': + case ']': + case '?': + case ':': + case '=': + case '{': + case '}': + symbol: + lexptr++; + return tokchr; + + case '@': + if (strncmp(tokstart, "@selector", 9) == 0) + { + tokptr = strchr(tokstart, '('); + if (tokptr == NULL) + { + error ("Missing '(' in @selector(...)"); + } + tempbufindex = 0; + tokptr++; /* Skip the '('. */ + do { + /* Grow the static temp buffer if necessary, including + allocating the first one on demand. */ + if (tempbufindex + 1 >= tempbufsize) + { + tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64); + } + tempbuf[tempbufindex++] = *tokptr++; + } while ((*tokptr != ')') && (*tokptr != '\0')); + if (*tokptr++ != ')') + { + error ("Missing ')' in @selector(...)"); + } + tempbuf[tempbufindex] = '\0'; + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = tokptr; + return SELECTOR; + } + if (tokstart[1] != '"') + { + lexptr++; + return tokchr; + } + /* ObjC NextStep NSString constant: fall thru and parse like + STRING. */ + tokstart++; + + case '"': + + /* Build the gdb internal form of the input string in tempbuf, + translating any standard C escape forms seen. Note that the + buffer is null byte terminated *only* for the convenience of + debugging gdb itself and printing the buffer contents when + the buffer contains no embedded nulls. Gdb does not depend + upon the buffer being null byte terminated, it uses the + length string instead. This allows gdb to handle C strings + (as well as strings in other languages) with embedded null + bytes. */ + + tokptr = ++tokstart; + tempbufindex = 0; + + do { + /* Grow the static temp buffer if necessary, including + allocating the first one on demand. */ + if (tempbufindex + 1 >= tempbufsize) + { + tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64); + } + switch (*tokptr) + { + case '\0': + case '"': + /* Do nothing, loop will terminate. */ + break; + case '\\': + tokptr++; + c = parse_escape (&tokptr); + if (c == -1) + { + continue; + } + tempbuf[tempbufindex++] = c; + break; + default: + tempbuf[tempbufindex++] = *tokptr++; + break; + } + } while ((*tokptr != '"') && (*tokptr != '\0')); + if (*tokptr++ != '"') + { + error ("Unterminated string in expression."); + } + tempbuf[tempbufindex] = '\0'; /* See note above. */ + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = tokptr; + return (tokchr == '@' ? NSSTRING : STRING); + } + + if (!(tokchr == '_' || tokchr == '$' || + (tokchr >= 'a' && tokchr <= 'z') || (tokchr >= 'A' && tokchr <= 'Z'))) + /* We must have come across a bad character (e.g. ';'). */ + error ("Invalid character '%c' in expression.", c); + + /* It's a name. See how long it is. */ + namelen = 0; + for (c = tokstart[namelen]; + (c == '_' || c == '$' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) + { + if (c == '<') + { + int i = namelen; + while (tokstart[++i] && tokstart[i] != '>'); + if (tokstart[i] == '>') + namelen = i; + } + c = tokstart[++namelen]; + } + + /* The token "if" terminates the expression and is NOT + removed from the input stream. */ + if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') + { + return 0; + } + + lexptr += namelen; + + tryname: + + /* Catch specific keywords. Should be done with a data structure. */ + switch (namelen) + { + case 8: + if (DEPRECATED_STREQN (tokstart, "unsigned", 8)) + return UNSIGNED; + if (current_language->la_language == language_cplus + && strncmp (tokstart, "template", 8) == 0) + return TEMPLATE; + if (DEPRECATED_STREQN (tokstart, "volatile", 8)) + return VOLATILE_KEYWORD; + break; + case 6: + if (DEPRECATED_STREQN (tokstart, "struct", 6)) + return STRUCT; + if (DEPRECATED_STREQN (tokstart, "signed", 6)) + return SIGNED_KEYWORD; + if (DEPRECATED_STREQN (tokstart, "sizeof", 6)) + return SIZEOF; + if (DEPRECATED_STREQN (tokstart, "double", 6)) + return DOUBLE_KEYWORD; + break; + case 5: + if ((current_language->la_language == language_cplus) + && strncmp (tokstart, "class", 5) == 0) + return CLASS; + if (DEPRECATED_STREQN (tokstart, "union", 5)) + return UNION; + if (DEPRECATED_STREQN (tokstart, "short", 5)) + return SHORT; + if (DEPRECATED_STREQN (tokstart, "const", 5)) + return CONST_KEYWORD; + break; + case 4: + if (DEPRECATED_STREQN (tokstart, "enum", 4)) + return ENUM; + if (DEPRECATED_STREQN (tokstart, "long", 4)) + return LONG; + break; + case 3: + if (DEPRECATED_STREQN (tokstart, "int", 3)) + return INT_KEYWORD; + break; + default: + break; + } + + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + if (*tokstart == '$') + { + write_dollar_variable (yylval.sval); + return VARIABLE; + } + + /* Use token-type BLOCKNAME for symbols that happen to be defined as + functions or symtabs. If this is not so, then ... + Use token-type TYPENAME for symbols that happen to be defined + currently as names of types; NAME for other symbols. + The caller is not constrained to care about the distinction. */ + { + char *tmp = copy_name (yylval.sval); + struct symbol *sym; + int is_a_field_of_this = 0, *need_this; + int hextype; + + if (current_language->la_language == language_cplus || + current_language->la_language == language_objc) + need_this = &is_a_field_of_this; + else + need_this = (int *) NULL; + + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + need_this, + (struct symtab **) NULL); + /* Call lookup_symtab, not lookup_partial_symtab, in case there + are no psymtabs (coff, xcoff, or some future change to blow + away the psymtabs once symbols are read). */ + if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) || + lookup_symtab (tmp)) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return BLOCKNAME; + } + if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + { +#if 1 + /* Despite the following flaw, we need to keep this code + enabled. Because we can get called from + check_stub_method, if we don't handle nested types then + it screws many operations in any program which uses + nested types. */ + /* In "A::x", if x is a member function of A and there + happens to be a type (nested or not, since the stabs + don't make that distinction) named x, then this code + incorrectly thinks we are dealing with nested types + rather than a member function. */ + + char *p; + char *namestart; + struct symbol *best_sym; + + /* Look ahead to detect nested types. This probably should + be done in the grammar, but trying seemed to introduce a + lot of shift/reduce and reduce/reduce conflicts. It's + possible that it could be done, though. Or perhaps a + non-grammar, but less ad hoc, approach would work well. */ + + /* Since we do not currently have any way of distinguishing + a nested type from a non-nested one (the stabs don't tell + us whether a type is nested), we just ignore the + containing type. */ + + p = lexptr; + best_sym = sym; + while (1) + { + /* Skip whitespace. */ + while (*p == ' ' || *p == '\t' || *p == '\n') + ++p; + if (*p == ':' && p[1] == ':') + { + /* Skip the `::'. */ + p += 2; + /* Skip whitespace. */ + while (*p == ' ' || *p == '\t' || *p == '\n') + ++p; + namestart = p; + while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9') + || (*p >= 'a' && *p <= 'z') + || (*p >= 'A' && *p <= 'Z')) + ++p; + if (p != namestart) + { + struct symbol *cur_sym; + /* As big as the whole rest of the expression, + which is at least big enough. */ + char *ncopy = alloca (strlen (tmp) + + strlen (namestart) + 3); + char *tmp1; + + tmp1 = ncopy; + memcpy (tmp1, tmp, strlen (tmp)); + tmp1 += strlen (tmp); + memcpy (tmp1, "::", 2); + tmp1 += 2; + memcpy (tmp1, namestart, p - namestart); + tmp1[p - namestart] = '\0'; + cur_sym = lookup_symbol (ncopy, + expression_context_block, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (cur_sym) + { + if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) + { + best_sym = cur_sym; + lexptr = p; + } + else + break; + } + else + break; + } + else + break; + } + else + break; + } + + yylval.tsym.type = SYMBOL_TYPE (best_sym); +#else /* not 0 */ + yylval.tsym.type = SYMBOL_TYPE (sym); +#endif /* not 0 */ + return TYPENAME; + } + if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) + return TYPENAME; + + /* See if it's an ObjC classname. */ + if (!sym) + { + CORE_ADDR Class = lookup_objc_class(tmp); + if (Class) + { + yylval.class.class = Class; + if ((sym = lookup_struct_typedef (tmp, + expression_context_block, + 1))) + yylval.class.type = SYMBOL_TYPE (sym); + return CLASSNAME; + } + } + + /* Input names that aren't symbols but ARE valid hex numbers, + when the input radix permits them, can be names or numbers + depending on the parse. Note we support radixes > 16 here. */ + if (!sym && + ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || + (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) + { + YYSTYPE newlval; /* Its value is ignored. */ + hextype = parse_number (tokstart, namelen, 0, &newlval); + if (hextype == INT) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME_OR_INT; + } + } + + /* Any other kind of symbol. */ + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME; + } +} + +void +yyerror (msg) + char *msg; +{ + if (*lexptr == '\0') + error("A %s near end of expression.", (msg ? msg : "error")); + else + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), + lexptr); +} + + diff --git a/contrib/gdb/gdb/objc-exp.y b/contrib/gdb/gdb/objc-exp.y new file mode 100644 index 00000000000..f56f68d7a07 --- /dev/null +++ b/contrib/gdb/gdb/objc-exp.y @@ -0,0 +1,1820 @@ +/* YACC parser for C expressions, for GDB. + + Copyright 1986, 1989, 1990, 1991, 1993, 1994, 2002 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Parse a C expression from text in a string, and return the result + as a struct expression pointer. That structure contains arithmetic + operations in reverse polish, with constants represented by + operations that are followed by special data. See expression.h for + the details of the format. What is important here is that it can + be built up sequentially during the process of parsing; the lower + levels of the tree always come first in the result. + + Note that malloc's and realloc's in this file are transformed to + xmalloc and xrealloc respectively by the same sed command in the + makefile that remaps any other malloc/realloc inserted by the + parser generator. Doing this with #defines and trying to control + the interaction with include files ( and for + example) just became too messy, particularly when such includes can + be inserted at random times by the parser generator. */ + +%{ + +#include "defs.h" +#include "gdb_string.h" +#include +#include "expression.h" + +#include "objc-lang.h" /* For objc language constructs. */ + +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "c-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols. */ +#include "top.h" +#include "completer.h" /* For skip_quoted(). */ +#include "block.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, + etc), as well as gratuitiously global symbol names, so we can have + multiple yacc generated parsers in gdb. Note that these are only + the variables produced by yacc. If other parser generators (bison, + byacc, etc) produce additional global names that conflict at link + time, then those parser generators need to be fixed instead of + adding those names to this list. */ + +#define yymaxdepth objc_maxdepth +#define yyparse objc_parse +#define yylex objc_lex +#define yyerror objc_error +#define yylval objc_lval +#define yychar objc_char +#define yydebug objc_debug +#define yypact objc_pact +#define yyr1 objc_r1 +#define yyr2 objc_r2 +#define yydef objc_def +#define yychk objc_chk +#define yypgo objc_pgo +#define yyact objc_act +#define yyexca objc_exca +#define yyerrflag objc_errflag +#define yynerrs objc_nerrs +#define yyps objc_ps +#define yypv objc_pv +#define yys objc_s +#define yy_yys objc_yys +#define yystate objc_state +#define yytmp objc_tmp +#define yyv objc_v +#define yy_yyv objc_yyv +#define yyval objc_val +#define yylloc objc_lloc +#define yyreds objc_reds /* With YYDEBUG defined */ +#define yytoks objc_toks /* With YYDEBUG defined */ +#define yyname objc_name /* With YYDEBUG defined */ +#define yyrule objc_rule /* With YYDEBUG defined */ +#define yylhs objc_yylhs +#define yylen objc_yylen +#define yydefred objc_yydefred +#define yydgoto objc_yydgoto +#define yysindex objc_yysindex +#define yyrindex objc_yyrindex +#define yygindex objc_yygindex +#define yytable objc_yytable +#define yycheck objc_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 0 /* Default to no yydebug support. */ +#endif + +int +yyparse PARAMS ((void)); + +static int +yylex PARAMS ((void)); + +void +yyerror PARAMS ((char *)); + +%} + +/* Although the yacc "value" of an expression is not used, + since the result is stored in the structure being created, + other node types do have values. */ + +%union + { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val_int; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; + struct symbol *sym; + struct type *tval; + struct stoken sval; + struct ttype tsym; + struct symtoken ssym; + int voidval; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + struct objc_class_str class; + + struct type **tvec; + int *ivec; + } + +%{ +/* YYSTYPE gets defined by %union. */ +static int +parse_number PARAMS ((char *, int, int, YYSTYPE *)); +%} + +%type exp exp1 type_exp start variable qualified_name lcurly +%type rcurly +%type type typebase +%type nonempty_typelist +/* %type block */ + +/* Fancy type parsing. */ +%type func_mod direct_abs_decl abs_decl +%type ptype +%type array_mod + +%token INT +%token FLOAT + +/* Both NAME and TYPENAME tokens represent symbols in the input, and + both convey their data as strings. But a TYPENAME is a string that + happens to be defined as a typedef or builtin type name (such as + int or char) and a NAME is any other symbol. Contexts where this + distinction is not important can use the nonterminal "name", which + matches either NAME or TYPENAME. */ + +%token STRING +%token NSSTRING /* ObjC Foundation "NSString" literal */ +%token SELECTOR /* ObjC "@selector" pseudo-operator */ +%token NAME /* BLOCKNAME defined below to give it higher precedence. */ +%token TYPENAME +%token CLASSNAME /* ObjC Class name */ +%type name +%type name_not_typename +%type typename + +/* A NAME_OR_INT is a symbol which is not known in the symbol table, + but which would parse as a valid number in the current input radix. + E.g. "c" when input_radix==16. Depending on the parse, it will be + turned into a name or into a number. */ + +%token NAME_OR_INT + +%token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON +%token TEMPLATE +%token ERROR + +/* Special type cases, put in to allow the parser to distinguish + different legal basetypes. */ +%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD + +%token VARIABLE + +%token ASSIGN_MODIFY + +%left ',' +%left ABOVE_COMMA +%right '=' ASSIGN_MODIFY +%right '?' +%left OROR +%left ANDAND +%left '|' +%left '^' +%left '&' +%left EQUAL NOTEQUAL +%left '<' '>' LEQ GEQ +%left LSH RSH +%left '@' +%left '+' '-' +%left '*' '/' '%' +%right UNARY INCREMENT DECREMENT +%right ARROW '.' '[' '(' +%token BLOCKNAME +%type block +%left COLONCOLON + + +%% + +start : exp1 + | type_exp + ; + +type_exp: type + { write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type($1); + write_exp_elt_opcode(OP_TYPE);} + ; + +/* Expressions, including the comma operator. */ +exp1 : exp + | exp1 ',' exp + { write_exp_elt_opcode (BINOP_COMMA); } + ; + +/* Expressions, not including the comma operator. */ +exp : '*' exp %prec UNARY + { write_exp_elt_opcode (UNOP_IND); } + ; + +exp : '&' exp %prec UNARY + { write_exp_elt_opcode (UNOP_ADDR); } + ; + +exp : '-' exp %prec UNARY + { write_exp_elt_opcode (UNOP_NEG); } + ; + +exp : '!' exp %prec UNARY + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + ; + +exp : '~' exp %prec UNARY + { write_exp_elt_opcode (UNOP_COMPLEMENT); } + ; + +exp : INCREMENT exp %prec UNARY + { write_exp_elt_opcode (UNOP_PREINCREMENT); } + ; + +exp : DECREMENT exp %prec UNARY + { write_exp_elt_opcode (UNOP_PREDECREMENT); } + ; + +exp : exp INCREMENT %prec UNARY + { write_exp_elt_opcode (UNOP_POSTINCREMENT); } + ; + +exp : exp DECREMENT %prec UNARY + { write_exp_elt_opcode (UNOP_POSTDECREMENT); } + ; + +exp : SIZEOF exp %prec UNARY + { write_exp_elt_opcode (UNOP_SIZEOF); } + ; + +exp : exp ARROW name + { write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string ($3); + write_exp_elt_opcode (STRUCTOP_PTR); } + ; + +exp : exp ARROW qualified_name + { /* exp->type::name becomes exp->*(&type::name) */ + /* Note: this doesn't work if name is a + static member! FIXME */ + write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (STRUCTOP_MPTR); } + ; +exp : exp ARROW '*' exp + { write_exp_elt_opcode (STRUCTOP_MPTR); } + ; + +exp : exp '.' name + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string ($3); + write_exp_elt_opcode (STRUCTOP_STRUCT); } + ; + + +exp : exp '.' qualified_name + { /* exp.type::name becomes exp.*(&type::name) */ + /* Note: this doesn't work if name is a + static member! FIXME */ + write_exp_elt_opcode (UNOP_ADDR); + write_exp_elt_opcode (STRUCTOP_MEMBER); } + ; + +exp : exp '.' '*' exp + { write_exp_elt_opcode (STRUCTOP_MEMBER); } + ; + +exp : exp '[' exp1 ']' + { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + ; +/* + * The rules below parse ObjC message calls of the form: + * '[' target selector {':' argument}* ']' + */ + +exp : '[' TYPENAME + { + CORE_ADDR class; + + class = lookup_objc_class (copy_name ($2.stoken)); + if (class == 0) + error ("%s is not an ObjC Class", + copy_name ($2.stoken)); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst ((LONGEST) class); + write_exp_elt_opcode (OP_LONG); + start_msglist(); + } + msglist ']' + { write_exp_elt_opcode (OP_OBJC_MSGCALL); + end_msglist(); + write_exp_elt_opcode (OP_OBJC_MSGCALL); + } + ; + +exp : '[' CLASSNAME + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + write_exp_elt_longcst ((LONGEST) $2.class); + write_exp_elt_opcode (OP_LONG); + start_msglist(); + } + msglist ']' + { write_exp_elt_opcode (OP_OBJC_MSGCALL); + end_msglist(); + write_exp_elt_opcode (OP_OBJC_MSGCALL); + } + ; + +exp : '[' exp + { start_msglist(); } + msglist ']' + { write_exp_elt_opcode (OP_OBJC_MSGCALL); + end_msglist(); + write_exp_elt_opcode (OP_OBJC_MSGCALL); + } + ; + +msglist : name + { add_msglist(&$1, 0); } + | msgarglist + ; + +msgarglist : msgarg + | msgarglist msgarg + ; + +msgarg : name ':' exp + { add_msglist(&$1, 1); } + | ':' exp /* Unnamed arg. */ + { add_msglist(0, 1); } + | ',' exp /* Variable number of args. */ + { add_msglist(0, 0); } + ; + +exp : exp '(' + /* This is to save the value of arglist_len + being accumulated by an outer function call. */ + { start_arglist (); } + arglist ')' %prec ARROW + { write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) end_arglist ()); + write_exp_elt_opcode (OP_FUNCALL); } + ; + +lcurly : '{' + { start_arglist (); } + ; + +arglist : + ; + +arglist : exp + { arglist_len = 1; } + ; + +arglist : arglist ',' exp %prec ABOVE_COMMA + { arglist_len++; } + ; + +rcurly : '}' + { $$ = end_arglist () - 1; } + ; +exp : lcurly arglist rcurly %prec ARROW + { write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) $3); + write_exp_elt_opcode (OP_ARRAY); } + ; + +exp : lcurly type rcurly exp %prec UNARY + { write_exp_elt_opcode (UNOP_MEMVAL); + write_exp_elt_type ($2); + write_exp_elt_opcode (UNOP_MEMVAL); } + ; + +exp : '(' type ')' exp %prec UNARY + { write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type ($2); + write_exp_elt_opcode (UNOP_CAST); } + ; + +exp : '(' exp1 ')' + { } + ; + +/* Binary operators in order of decreasing precedence. */ + +exp : exp '@' exp + { write_exp_elt_opcode (BINOP_REPEAT); } + ; + +exp : exp '*' exp + { write_exp_elt_opcode (BINOP_MUL); } + ; + +exp : exp '/' exp + { write_exp_elt_opcode (BINOP_DIV); } + ; + +exp : exp '%' exp + { write_exp_elt_opcode (BINOP_REM); } + ; + +exp : exp '+' exp + { write_exp_elt_opcode (BINOP_ADD); } + ; + +exp : exp '-' exp + { write_exp_elt_opcode (BINOP_SUB); } + ; + +exp : exp LSH exp + { write_exp_elt_opcode (BINOP_LSH); } + ; + +exp : exp RSH exp + { write_exp_elt_opcode (BINOP_RSH); } + ; + +exp : exp EQUAL exp + { write_exp_elt_opcode (BINOP_EQUAL); } + ; + +exp : exp NOTEQUAL exp + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + ; + +exp : exp LEQ exp + { write_exp_elt_opcode (BINOP_LEQ); } + ; + +exp : exp GEQ exp + { write_exp_elt_opcode (BINOP_GEQ); } + ; + +exp : exp '<' exp + { write_exp_elt_opcode (BINOP_LESS); } + ; + +exp : exp '>' exp + { write_exp_elt_opcode (BINOP_GTR); } + ; + +exp : exp '&' exp + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + ; + +exp : exp '^' exp + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + ; + +exp : exp '|' exp + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + ; + +exp : exp ANDAND exp + { write_exp_elt_opcode (BINOP_LOGICAL_AND); } + ; + +exp : exp OROR exp + { write_exp_elt_opcode (BINOP_LOGICAL_OR); } + ; + +exp : exp '?' exp ':' exp %prec '?' + { write_exp_elt_opcode (TERNOP_COND); } + ; + +exp : exp '=' exp + { write_exp_elt_opcode (BINOP_ASSIGN); } + ; + +exp : exp ASSIGN_MODIFY exp + { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); + write_exp_elt_opcode ($2); + write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } + ; + +exp : INT + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type ($1.type); + write_exp_elt_longcst ((LONGEST)($1.val)); + write_exp_elt_opcode (OP_LONG); } + ; + +exp : NAME_OR_INT + { YYSTYPE val; + parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (val.typed_val_int.type); + write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); + write_exp_elt_opcode (OP_LONG); + } + ; + + +exp : FLOAT + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type ($1.type); + write_exp_elt_dblcst ($1.dval); + write_exp_elt_opcode (OP_DOUBLE); } + ; + +exp : variable + ; + +exp : VARIABLE + /* Already written by write_dollar_variable. */ + ; + +exp : SELECTOR + { + write_exp_elt_opcode (OP_OBJC_SELECTOR); + write_exp_string ($1); + write_exp_elt_opcode (OP_OBJC_SELECTOR); } + ; + +exp : SIZEOF '(' type ')' %prec UNARY + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + CHECK_TYPEDEF ($3); + write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3)); + write_exp_elt_opcode (OP_LONG); } + ; + +exp : STRING + { /* C strings are converted into array + constants with an explicit null byte + added at the end. Thus the array upper + bound is the string length. There is no + such thing in C as a completely empty + string. */ + char *sp = $1.ptr; int count = $1.length; + while (count-- > 0) + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)(*sp++)); + write_exp_elt_opcode (OP_LONG); + } + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)'\0'); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) ($1.length)); + write_exp_elt_opcode (OP_ARRAY); } + ; + +exp : NSSTRING /* ObjC NextStep NSString constant + * of the form '@' '"' string '"'. + */ + { write_exp_elt_opcode (OP_OBJC_NSSTRING); + write_exp_string ($1); + write_exp_elt_opcode (OP_OBJC_NSSTRING); } + ; + +block : BLOCKNAME + { + if ($1.sym != 0) + $$ = SYMBOL_BLOCK_VALUE ($1.sym); + else + { + struct symtab *tem = + lookup_symtab (copy_name ($1.stoken)); + if (tem) + $$ = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK); + else + error ("No file or function \"%s\".", + copy_name ($1.stoken)); + } + } + ; + +block : block COLONCOLON name + { struct symbol *tem + = lookup_symbol (copy_name ($3), $1, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) + error ("No function \"%s\" in specified context.", + copy_name ($3)); + $$ = SYMBOL_BLOCK_VALUE (tem); } + ; + +variable: block COLONCOLON name + { struct symbol *sym; + sym = lookup_symbol (copy_name ($3), $1, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym == 0) + error ("No symbol \"%s\" in specified context.", + copy_name ($3)); + + write_exp_elt_opcode (OP_VAR_VALUE); + /* block_found is set by lookup_symbol. */ + write_exp_elt_block (block_found); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); } + ; + +qualified_name: typebase COLONCOLON name + { + struct type *type = $1; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (type); + write_exp_string ($3); + write_exp_elt_opcode (OP_SCOPE); + } + | typebase COLONCOLON '~' name + { + struct type *type = $1; + struct stoken tmp_token; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + if (!DEPRECATED_STREQ (type_name_no_tag (type), $4.ptr)) + error ("invalid destructor `%s::~%s'", + type_name_no_tag (type), $4.ptr); + + tmp_token.ptr = (char*) alloca ($4.length + 2); + tmp_token.length = $4.length + 1; + tmp_token.ptr[0] = '~'; + memcpy (tmp_token.ptr+1, $4.ptr, $4.length); + tmp_token.ptr[tmp_token.length] = 0; + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (type); + write_exp_string (tmp_token); + write_exp_elt_opcode (OP_SCOPE); + } + ; + +variable: qualified_name + | COLONCOLON name + { + char *name = copy_name ($2); + struct symbol *sym; + struct minimal_symbol *msymbol; + + sym = + lookup_symbol (name, (const struct block *) NULL, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym) + { + write_exp_elt_opcode (OP_VAR_VALUE); + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + break; + } + + msymbol = lookup_minimal_symbol (name, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", name); + } + ; + +variable: name_not_typename + { struct symbol *sym = $1.sym; + + if (sym) + { + if (symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block_found, + innermost_block)) + innermost_block = block_found; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not + another more inner frame which happens to + be in the same block. */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + } + else if ($1.is_a_field_of_this) + { + /* C++/ObjC: it hangs off of `this'/'self'. + Must not inadvertently convert from a + method call to data ref. */ + if (innermost_block == 0 || + contained_in (block_found, innermost_block)) + innermost_block = block_found; + write_exp_elt_opcode (OP_OBJC_SELF); + write_exp_elt_opcode (OP_OBJC_SELF); + write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string ($1.stoken); + write_exp_elt_opcode (STRUCTOP_PTR); + } + else + { + struct minimal_symbol *msymbol; + char *arg = copy_name ($1.stoken); + + msymbol = + lookup_minimal_symbol (arg, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (!have_full_symbols () && + !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", + copy_name ($1.stoken)); + } + } + ; + + +ptype : typebase + /* "const" and "volatile" are curently ignored. A type + qualifier before the type is currently handled in the + typebase rule. The reason for recognizing these here + (shift/reduce conflicts) might be obsolete now that some + pointer to member rules have been deleted. */ + | typebase CONST_KEYWORD + | typebase VOLATILE_KEYWORD + | typebase abs_decl + { $$ = follow_types ($1); } + | typebase CONST_KEYWORD abs_decl + { $$ = follow_types ($1); } + | typebase VOLATILE_KEYWORD abs_decl + { $$ = follow_types ($1); } + ; + +abs_decl: '*' + { push_type (tp_pointer); $$ = 0; } + | '*' abs_decl + { push_type (tp_pointer); $$ = $2; } + | '&' + { push_type (tp_reference); $$ = 0; } + | '&' abs_decl + { push_type (tp_reference); $$ = $2; } + | direct_abs_decl + ; + +direct_abs_decl: '(' abs_decl ')' + { $$ = $2; } + | direct_abs_decl array_mod + { + push_type_int ($2); + push_type (tp_array); + } + | array_mod + { + push_type_int ($1); + push_type (tp_array); + $$ = 0; + } + + | direct_abs_decl func_mod + { push_type (tp_function); } + | func_mod + { push_type (tp_function); } + ; + +array_mod: '[' ']' + { $$ = -1; } + | '[' INT ']' + { $$ = $2.val; } + ; + +func_mod: '(' ')' + { $$ = 0; } + | '(' nonempty_typelist ')' + { free ($2); $$ = 0; } + ; + +/* We used to try to recognize more pointer to member types here, but + that didn't work (shift/reduce conflicts meant that these rules + never got executed). The problem is that + int (foo::bar::baz::bizzle) + is a function type but + int (foo::bar::baz::bizzle::*) + is a pointer to member type. Stroustrup loses again! */ + +type : ptype + | typebase COLONCOLON '*' + { $$ = lookup_member_type (builtin_type_int, $1); } + ; + +typebase /* Implements (approximately): (type-qualifier)* type-specifier. */ + : TYPENAME + { $$ = $1.type; } + | CLASSNAME + { + if ($1.type == NULL) + error ("No symbol \"%s\" in current context.", + copy_name($1.stoken)); + else + $$ = $1.type; + } + | INT_KEYWORD + { $$ = builtin_type_int; } + | LONG + { $$ = builtin_type_long; } + | SHORT + { $$ = builtin_type_short; } + | LONG INT_KEYWORD + { $$ = builtin_type_long; } + | UNSIGNED LONG INT_KEYWORD + { $$ = builtin_type_unsigned_long; } + | LONG LONG + { $$ = builtin_type_long_long; } + | LONG LONG INT_KEYWORD + { $$ = builtin_type_long_long; } + | UNSIGNED LONG LONG + { $$ = builtin_type_unsigned_long_long; } + | UNSIGNED LONG LONG INT_KEYWORD + { $$ = builtin_type_unsigned_long_long; } + | SHORT INT_KEYWORD + { $$ = builtin_type_short; } + | UNSIGNED SHORT INT_KEYWORD + { $$ = builtin_type_unsigned_short; } + | DOUBLE_KEYWORD + { $$ = builtin_type_double; } + | LONG DOUBLE_KEYWORD + { $$ = builtin_type_long_double; } + | STRUCT name + { $$ = lookup_struct (copy_name ($2), + expression_context_block); } + | CLASS name + { $$ = lookup_struct (copy_name ($2), + expression_context_block); } + | UNION name + { $$ = lookup_union (copy_name ($2), + expression_context_block); } + | ENUM name + { $$ = lookup_enum (copy_name ($2), + expression_context_block); } + | UNSIGNED typename + { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); } + | UNSIGNED + { $$ = builtin_type_unsigned_int; } + | SIGNED_KEYWORD typename + { $$ = lookup_signed_typename (TYPE_NAME($2.type)); } + | SIGNED_KEYWORD + { $$ = builtin_type_int; } + | TEMPLATE name '<' type '>' + { $$ = lookup_template_type(copy_name($2), $4, + expression_context_block); + } + /* "const" and "volatile" are curently ignored. A type + qualifier after the type is handled in the ptype rule. I + think these could be too. */ + | CONST_KEYWORD typebase { $$ = $2; } + | VOLATILE_KEYWORD typebase { $$ = $2; } + ; + +typename: TYPENAME + | INT_KEYWORD + { + $$.stoken.ptr = "int"; + $$.stoken.length = 3; + $$.type = builtin_type_int; + } + | LONG + { + $$.stoken.ptr = "long"; + $$.stoken.length = 4; + $$.type = builtin_type_long; + } + | SHORT + { + $$.stoken.ptr = "short"; + $$.stoken.length = 5; + $$.type = builtin_type_short; + } + ; + +nonempty_typelist + : type + { $$ = (struct type **) malloc (sizeof (struct type *) * 2); + $$[0] = 1; /* Number of types in vector. */ + $$[1] = $1; + } + | nonempty_typelist ',' type + { int len = sizeof (struct type *) * (++($1[0]) + 1); + $$ = (struct type **) realloc ((char *) $1, len); + $$[$$[0]] = $3; + } + ; + +name : NAME { $$ = $1.stoken; } + | BLOCKNAME { $$ = $1.stoken; } + | TYPENAME { $$ = $1.stoken; } + | CLASSNAME { $$ = $1.stoken; } + | NAME_OR_INT { $$ = $1.stoken; } + ; + +name_not_typename : NAME + | BLOCKNAME +/* These would be useful if name_not_typename was useful, but it is + just a fake for "variable", so these cause reduce/reduce conflicts + because the parser can't tell whether NAME_OR_INT is a + name_not_typename (=variable, =exp) or just an exp. If + name_not_typename was ever used in an lvalue context where only a + name could occur, this might be useful. */ +/* | NAME_OR_INT */ + ; + +%% + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. LEN is the + number of characters in it. */ + +/*** Needs some error checking for the float case. ***/ + +static int +parse_number (p, len, parsed_float, putithere) + char *p; + int len; + int parsed_float; + YYSTYPE *putithere; +{ + /* FIXME: Shouldn't these be unsigned? We don't deal with negative + values here, and we do kind of silly things like cast to + unsigned. */ + LONGEST n = 0; + LONGEST prevn = 0; + unsigned LONGEST un; + + int i = 0; + int c; + int base = input_radix; + int unsigned_p = 0; + + /* Number of "L" suffixes encountered. */ + int long_p = 0; + + /* We have found a "L" or "U" suffix. */ + int found_suffix = 0; + + unsigned LONGEST high_bit; + struct type *signed_type; + struct type *unsigned_type; + + if (parsed_float) + { + char c; + + /* It's a float since it contains a point or an exponent. */ + + if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) + sscanf (p, "%g", (float *)&putithere->typed_val_float.dval); + else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) + sscanf (p, "%lg", (double *)&putithere->typed_val_float.dval); + else + { +#ifdef PRINTF_HAS_LONG_DOUBLE + sscanf (p, "%Lg", &putithere->typed_val_float.dval); +#else + /* Scan it into a double, then assign it to the long double. + This at least wins with values representable in the range + of doubles. */ + double temp; + sscanf (p, "%lg", &temp); + putithere->typed_val_float.dval = temp; +#endif + } + + /* See if it has `f' or `l' suffix (float or long double). */ + + c = tolower (p[len - 1]); + + if (c == 'f') + putithere->typed_val_float.type = builtin_type_float; + else if (c == 'l') + putithere->typed_val_float.type = builtin_type_long_double; + else if (isdigit (c) || c == '.') + putithere->typed_val_float.type = builtin_type_double; + else + return ERROR; + + return FLOAT; + } + + /* Handle base-switching prefixes 0x, 0t, 0d, and 0. */ + if (p[0] == '0') + switch (p[1]) + { + case 'x': + case 'X': + if (len >= 3) + { + p += 2; + base = 16; + len -= 2; + } + break; + + case 't': + case 'T': + case 'd': + case 'D': + if (len >= 3) + { + p += 2; + base = 10; + len -= 2; + } + break; + + default: + base = 8; + break; + } + + while (len-- > 0) + { + c = *p++; + if (c >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != 'l' && c != 'u') + n *= base; + if (c >= '0' && c <= '9') + { + if (found_suffix) + return ERROR; + n += i = c - '0'; + } + else + { + if (base > 10 && c >= 'a' && c <= 'f') + { + if (found_suffix) + return ERROR; + n += i = c - 'a' + 10; + } + else if (c == 'l') + { + ++long_p; + found_suffix = 1; + } + else if (c == 'u') + { + unsigned_p = 1; + found_suffix = 1; + } + else + return ERROR; /* Char not a digit. */ + } + if (i >= base) + return ERROR; /* Invalid digit in this base. */ + + /* Portably test for overflow (only works for nonzero values, so + make a second check for zero). FIXME: Can't we just make n + and prevn unsigned and avoid this? */ + if (c != 'l' && c != 'u' && (prevn >= n) && n != 0) + unsigned_p = 1; /* Try something unsigned. */ + + /* Portably test for unsigned overflow. + FIXME: This check is wrong; for example it doesn't find + overflow on 0x123456789 when LONGEST is 32 bits. */ + if (c != 'l' && c != 'u' && n != 0) + { + if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n)) + error ("Numeric constant too large."); + } + prevn = n; + } + + /* An integer constant is an int, a long, or a long long. An L + suffix forces it to be long; an LL suffix forces it to be long + long. If not forced to a larger size, it gets the first type of + the above that it fits in. To figure out whether it fits, we + shift it right and see whether anything remains. Note that we + can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one + operation, because many compilers will warn about such a shift + (which always produces a zero result). Sometimes TARGET_INT_BIT + or TARGET_LONG_BIT will be that big, sometimes not. To deal with + the case where it is we just always shift the value more than + once, with fewer bits each time. */ + + un = (unsigned LONGEST)n >> 2; + if (long_p == 0 + && (un >> (TARGET_INT_BIT - 2)) == 0) + { + high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1); + + /* A large decimal (not hex or octal) constant (between INT_MAX + and UINT_MAX) is a long or unsigned long, according to ANSI, + never an unsigned int, but this code treats it as unsigned + int. This probably should be fixed. GCC gives a warning on + such constants. */ + + unsigned_type = builtin_type_unsigned_int; + signed_type = builtin_type_int; + } + else if (long_p <= 1 + && (un >> (TARGET_LONG_BIT - 2)) == 0) + { + high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1); + unsigned_type = builtin_type_unsigned_long; + signed_type = builtin_type_long; + } + else + { + high_bit = (((unsigned LONGEST)1) + << (TARGET_LONG_LONG_BIT - 32 - 1) + << 16 + << 16); + if (high_bit == 0) + /* A long long does not fit in a LONGEST. */ + high_bit = + (unsigned LONGEST)1 << (sizeof (LONGEST) * HOST_CHAR_BIT - 1); + unsigned_type = builtin_type_unsigned_long_long; + signed_type = builtin_type_long_long; + } + + putithere->typed_val_int.val = n; + + /* If the high bit of the worked out type is set then this number + has to be unsigned. */ + + if (unsigned_p || (n & high_bit)) + { + putithere->typed_val_int.type = unsigned_type; + } + else + { + putithere->typed_val_int.type = signed_type; + } + + return INT; +} + +struct token +{ + char *operator; + int token; + enum exp_opcode opcode; +}; + +static const struct token tokentab3[] = + { + {">>=", ASSIGN_MODIFY, BINOP_RSH}, + {"<<=", ASSIGN_MODIFY, BINOP_LSH} + }; + +static const struct token tokentab2[] = + { + {"+=", ASSIGN_MODIFY, BINOP_ADD}, + {"-=", ASSIGN_MODIFY, BINOP_SUB}, + {"*=", ASSIGN_MODIFY, BINOP_MUL}, + {"/=", ASSIGN_MODIFY, BINOP_DIV}, + {"%=", ASSIGN_MODIFY, BINOP_REM}, + {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR}, + {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND}, + {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR}, + {"++", INCREMENT, BINOP_END}, + {"--", DECREMENT, BINOP_END}, + {"->", ARROW, BINOP_END}, + {"&&", ANDAND, BINOP_END}, + {"||", OROR, BINOP_END}, + {"::", COLONCOLON, BINOP_END}, + {"<<", LSH, BINOP_END}, + {">>", RSH, BINOP_END}, + {"==", EQUAL, BINOP_END}, + {"!=", NOTEQUAL, BINOP_END}, + {"<=", LEQ, BINOP_END}, + {">=", GEQ, BINOP_END} + }; + +/* Read one token, getting characters through lexptr. */ + +static int +yylex () +{ + int c, tokchr; + int namelen; + unsigned int i; + char *tokstart; + char *tokptr; + int tempbufindex; + static char *tempbuf; + static int tempbufsize; + + retry: + + tokstart = lexptr; + /* See if it is a special token of length 3. */ + for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) + if (DEPRECATED_STREQN (tokstart, tokentab3[i].operator, 3)) + { + lexptr += 3; + yylval.opcode = tokentab3[i].opcode; + return tokentab3[i].token; + } + + /* See if it is a special token of length 2. */ + for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) + if (DEPRECATED_STREQN (tokstart, tokentab2[i].operator, 2)) + { + lexptr += 2; + yylval.opcode = tokentab2[i].opcode; + return tokentab2[i].token; + } + + c = 0; + switch (tokchr = *tokstart) + { + case 0: + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '\'': + /* We either have a character constant ('0' or '\177' for + example) or we have a quoted symbol reference ('foo(int,int)' + in C++ for example). */ + lexptr++; + c = *lexptr++; + if (c == '\\') + c = parse_escape (&lexptr); + else if (c == '\'') + error ("Empty character constant."); + + yylval.typed_val_int.val = c; + yylval.typed_val_int.type = builtin_type_char; + + c = *lexptr++; + if (c != '\'') + { + namelen = skip_quoted (tokstart) - tokstart; + if (namelen > 2) + { + lexptr = tokstart + namelen; + if (lexptr[-1] != '\'') + error ("Unmatched single quote."); + namelen -= 2; + tokstart++; + goto tryname; + } + error ("Invalid character constant."); + } + return INT; + + case '(': + paren_depth++; + lexptr++; + return '('; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return ')'; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return ','; + + case '.': + /* Might be a floating point number. */ + if (lexptr[1] < '0' || lexptr[1] > '9') + goto symbol; /* Nope, must be a symbol. */ + /* FALL THRU into number case. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + /* It's a number. */ + int got_dot = 0, got_e = 0, toktype = FLOAT; + /* Initialize toktype to anything other than ERROR. */ + char *p = tokstart; + int hex = input_radix > 10; + int local_radix = input_radix; + if (tokchr == '0' && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + hex = 1; + local_radix = 16; + } + else if (tokchr == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) + { + p += 2; + hex = 0; + local_radix = 10; + } + + for (;; ++p) + { + /* This test includes !hex because 'e' is a valid hex digit + and thus does not indicate a floating point number when + the radix is hex. */ + + if (!hex && (*p == 'e' || *p == 'E')) + if (got_e) + toktype = ERROR; /* Only one 'e' in a float. */ + else + got_e = 1; + /* This test does not include !hex, because a '.' always + indicates a decimal floating point number regardless of + the radix. */ + else if (*p == '.') + if (got_dot) + toktype = ERROR; /* Only one '.' in a float. */ + else + got_dot = 1; + else if (got_e && (p[-1] == 'e' || p[-1] == 'E') && + (*p == '-' || *p == '+')) + /* This is the sign of the exponent, not the end of the + number. */ + continue; + /* Always take decimal digits; parse_number handles radix + error. */ + else if (*p >= '0' && *p <= '9') + continue; + /* We will take letters only if hex is true, and only up + to what the input radix would permit. FSF was content + to rely on parse_number to validate; but it leaks. */ + else if (*p >= 'a' && *p <= 'z') + { + if (!hex || *p >= ('a' + local_radix - 10)) + toktype = ERROR; + } + else if (*p >= 'A' && *p <= 'Z') + { + if (!hex || *p >= ('A' + local_radix - 10)) + toktype = ERROR; + } + else break; + } + if (toktype != ERROR) + toktype = parse_number (tokstart, p - tokstart, + got_dot | got_e, &yylval); + if (toktype == ERROR) + { + char *err_copy = (char *) alloca (p - tokstart + 1); + + memcpy (err_copy, tokstart, p - tokstart); + err_copy[p - tokstart] = 0; + error ("Invalid number \"%s\".", err_copy); + } + lexptr = p; + return toktype; + } + + case '+': + case '-': + case '*': + case '/': + case '%': + case '|': + case '&': + case '^': + case '~': + case '!': +#if 0 + case '@': /* Moved out below. */ +#endif + case '<': + case '>': + case '[': + case ']': + case '?': + case ':': + case '=': + case '{': + case '}': + symbol: + lexptr++; + return tokchr; + + case '@': + if (strncmp(tokstart, "@selector", 9) == 0) + { + tokptr = strchr(tokstart, '('); + if (tokptr == NULL) + { + error ("Missing '(' in @selector(...)"); + } + tempbufindex = 0; + tokptr++; /* Skip the '('. */ + do { + /* Grow the static temp buffer if necessary, including + allocating the first one on demand. */ + if (tempbufindex + 1 >= tempbufsize) + { + tempbuf = (char *) realloc (tempbuf, tempbufsize += 64); + } + tempbuf[tempbufindex++] = *tokptr++; + } while ((*tokptr != ')') && (*tokptr != '\0')); + if (*tokptr++ != ')') + { + error ("Missing ')' in @selector(...)"); + } + tempbuf[tempbufindex] = '\0'; + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = tokptr; + return SELECTOR; + } + if (tokstart[1] != '"') + { + lexptr++; + return tokchr; + } + /* ObjC NextStep NSString constant: fall thru and parse like + STRING. */ + tokstart++; + + case '"': + + /* Build the gdb internal form of the input string in tempbuf, + translating any standard C escape forms seen. Note that the + buffer is null byte terminated *only* for the convenience of + debugging gdb itself and printing the buffer contents when + the buffer contains no embedded nulls. Gdb does not depend + upon the buffer being null byte terminated, it uses the + length string instead. This allows gdb to handle C strings + (as well as strings in other languages) with embedded null + bytes. */ + + tokptr = ++tokstart; + tempbufindex = 0; + + do { + /* Grow the static temp buffer if necessary, including + allocating the first one on demand. */ + if (tempbufindex + 1 >= tempbufsize) + { + tempbuf = (char *) realloc (tempbuf, tempbufsize += 64); + } + switch (*tokptr) + { + case '\0': + case '"': + /* Do nothing, loop will terminate. */ + break; + case '\\': + tokptr++; + c = parse_escape (&tokptr); + if (c == -1) + { + continue; + } + tempbuf[tempbufindex++] = c; + break; + default: + tempbuf[tempbufindex++] = *tokptr++; + break; + } + } while ((*tokptr != '"') && (*tokptr != '\0')); + if (*tokptr++ != '"') + { + error ("Unterminated string in expression."); + } + tempbuf[tempbufindex] = '\0'; /* See note above. */ + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = tokptr; + return (tokchr == '@' ? NSSTRING : STRING); + } + + if (!(tokchr == '_' || tokchr == '$' || + (tokchr >= 'a' && tokchr <= 'z') || (tokchr >= 'A' && tokchr <= 'Z'))) + /* We must have come across a bad character (e.g. ';'). */ + error ("Invalid character '%c' in expression.", c); + + /* It's a name. See how long it is. */ + namelen = 0; + for (c = tokstart[namelen]; + (c == '_' || c == '$' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) + { + if (c == '<') + { + int i = namelen; + while (tokstart[++i] && tokstart[i] != '>'); + if (tokstart[i] == '>') + namelen = i; + } + c = tokstart[++namelen]; + } + + /* The token "if" terminates the expression and is NOT + removed from the input stream. */ + if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') + { + return 0; + } + + lexptr += namelen; + + tryname: + + /* Catch specific keywords. Should be done with a data structure. */ + switch (namelen) + { + case 8: + if (DEPRECATED_STREQN (tokstart, "unsigned", 8)) + return UNSIGNED; + if (current_language->la_language == language_cplus + && strncmp (tokstart, "template", 8) == 0) + return TEMPLATE; + if (DEPRECATED_STREQN (tokstart, "volatile", 8)) + return VOLATILE_KEYWORD; + break; + case 6: + if (DEPRECATED_STREQN (tokstart, "struct", 6)) + return STRUCT; + if (DEPRECATED_STREQN (tokstart, "signed", 6)) + return SIGNED_KEYWORD; + if (DEPRECATED_STREQN (tokstart, "sizeof", 6)) + return SIZEOF; + if (DEPRECATED_STREQN (tokstart, "double", 6)) + return DOUBLE_KEYWORD; + break; + case 5: + if ((current_language->la_language == language_cplus) + && strncmp (tokstart, "class", 5) == 0) + return CLASS; + if (DEPRECATED_STREQN (tokstart, "union", 5)) + return UNION; + if (DEPRECATED_STREQN (tokstart, "short", 5)) + return SHORT; + if (DEPRECATED_STREQN (tokstart, "const", 5)) + return CONST_KEYWORD; + break; + case 4: + if (DEPRECATED_STREQN (tokstart, "enum", 4)) + return ENUM; + if (DEPRECATED_STREQN (tokstart, "long", 4)) + return LONG; + break; + case 3: + if (DEPRECATED_STREQN (tokstart, "int", 3)) + return INT_KEYWORD; + break; + default: + break; + } + + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + if (*tokstart == '$') + { + write_dollar_variable (yylval.sval); + return VARIABLE; + } + + /* Use token-type BLOCKNAME for symbols that happen to be defined as + functions or symtabs. If this is not so, then ... + Use token-type TYPENAME for symbols that happen to be defined + currently as names of types; NAME for other symbols. + The caller is not constrained to care about the distinction. */ + { + char *tmp = copy_name (yylval.sval); + struct symbol *sym; + int is_a_field_of_this = 0, *need_this; + int hextype; + + if (current_language->la_language == language_cplus || + current_language->la_language == language_objc) + need_this = &is_a_field_of_this; + else + need_this = (int *) NULL; + + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + need_this, + (struct symtab **) NULL); + /* Call lookup_symtab, not lookup_partial_symtab, in case there + are no psymtabs (coff, xcoff, or some future change to blow + away the psymtabs once symbols are read). */ + if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) || + lookup_symtab (tmp)) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return BLOCKNAME; + } + if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + { +#if 1 + /* Despite the following flaw, we need to keep this code + enabled. Because we can get called from + check_stub_method, if we don't handle nested types then + it screws many operations in any program which uses + nested types. */ + /* In "A::x", if x is a member function of A and there + happens to be a type (nested or not, since the stabs + don't make that distinction) named x, then this code + incorrectly thinks we are dealing with nested types + rather than a member function. */ + + char *p; + char *namestart; + struct symbol *best_sym; + + /* Look ahead to detect nested types. This probably should + be done in the grammar, but trying seemed to introduce a + lot of shift/reduce and reduce/reduce conflicts. It's + possible that it could be done, though. Or perhaps a + non-grammar, but less ad hoc, approach would work well. */ + + /* Since we do not currently have any way of distinguishing + a nested type from a non-nested one (the stabs don't tell + us whether a type is nested), we just ignore the + containing type. */ + + p = lexptr; + best_sym = sym; + while (1) + { + /* Skip whitespace. */ + while (*p == ' ' || *p == '\t' || *p == '\n') + ++p; + if (*p == ':' && p[1] == ':') + { + /* Skip the `::'. */ + p += 2; + /* Skip whitespace. */ + while (*p == ' ' || *p == '\t' || *p == '\n') + ++p; + namestart = p; + while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9') + || (*p >= 'a' && *p <= 'z') + || (*p >= 'A' && *p <= 'Z')) + ++p; + if (p != namestart) + { + struct symbol *cur_sym; + /* As big as the whole rest of the expression, + which is at least big enough. */ + char *ncopy = alloca (strlen (tmp) + + strlen (namestart) + 3); + char *tmp1; + + tmp1 = ncopy; + memcpy (tmp1, tmp, strlen (tmp)); + tmp1 += strlen (tmp); + memcpy (tmp1, "::", 2); + tmp1 += 2; + memcpy (tmp1, namestart, p - namestart); + tmp1[p - namestart] = '\0'; + cur_sym = lookup_symbol (ncopy, + expression_context_block, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (cur_sym) + { + if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) + { + best_sym = cur_sym; + lexptr = p; + } + else + break; + } + else + break; + } + else + break; + } + else + break; + } + + yylval.tsym.type = SYMBOL_TYPE (best_sym); +#else /* not 0 */ + yylval.tsym.type = SYMBOL_TYPE (sym); +#endif /* not 0 */ + return TYPENAME; + } + if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) + return TYPENAME; + + /* See if it's an ObjC classname. */ + if (!sym) + { + CORE_ADDR Class = lookup_objc_class(tmp); + if (Class) + { + yylval.class.class = Class; + if ((sym = lookup_struct_typedef (tmp, + expression_context_block, + 1))) + yylval.class.type = SYMBOL_TYPE (sym); + return CLASSNAME; + } + } + + /* Input names that aren't symbols but ARE valid hex numbers, + when the input radix permits them, can be names or numbers + depending on the parse. Note we support radixes > 16 here. */ + if (!sym && + ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || + (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) + { + YYSTYPE newlval; /* Its value is ignored. */ + hextype = parse_number (tokstart, namelen, 0, &newlval); + if (hextype == INT) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME_OR_INT; + } + } + + /* Any other kind of symbol. */ + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME; + } +} + +void +yyerror (msg) + char *msg; +{ + if (*lexptr == '\0') + error("A %s near end of expression.", (msg ? msg : "error")); + else + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), + lexptr); +} diff --git a/contrib/gdb/gdb/objc-lang.c b/contrib/gdb/gdb/objc-lang.c new file mode 100644 index 00000000000..5c184f35d7a --- /dev/null +++ b/contrib/gdb/gdb/objc-lang.c @@ -0,0 +1,1929 @@ +/* Objective-C language support routines for GDB, the GNU debugger. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + + Contributed by Apple Computer, Inc. + Written by Michael Snyder. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "expression.h" +#include "parser-defs.h" +#include "language.h" +#include "c-lang.h" +#include "objc-lang.h" +#include "complaints.h" +#include "value.h" +#include "symfile.h" +#include "objfiles.h" +#include "gdb_string.h" /* for strchr */ +#include "target.h" /* for target_has_execution */ +#include "gdbcore.h" +#include "gdbcmd.h" +#include "frame.h" +#include "gdb_regex.h" +#include "regcache.h" +#include "block.h" +#include "infcall.h" +#include "valprint.h" +#include "gdb_assert.h" + +#include + +struct objc_object { + CORE_ADDR isa; +}; + +struct objc_class { + CORE_ADDR isa; + CORE_ADDR super_class; + CORE_ADDR name; + long version; + long info; + long instance_size; + CORE_ADDR ivars; + CORE_ADDR methods; + CORE_ADDR cache; + CORE_ADDR protocols; +}; + +struct objc_super { + CORE_ADDR receiver; + CORE_ADDR class; +}; + +struct objc_method { + CORE_ADDR name; + CORE_ADDR types; + CORE_ADDR imp; +}; + +/* Lookup a structure type named "struct NAME", visible in lexical + block BLOCK. If NOERR is nonzero, return zero if NAME is not + suitably defined. */ + +struct symbol * +lookup_struct_typedef (char *name, struct block *block, int noerr) +{ + struct symbol *sym; + + sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0, + (struct symtab **) NULL); + + if (sym == NULL) + { + if (noerr) + return 0; + else + error ("No struct type named %s.", name); + } + if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT) + { + if (noerr) + return 0; + else + error ("This context has class, union or enum %s, not a struct.", + name); + } + return sym; +} + +CORE_ADDR +lookup_objc_class (char *classname) +{ + struct value * function, *classval; + + if (! target_has_execution) + { + /* Can't call into inferior to lookup class. */ + return 0; + } + + if (lookup_minimal_symbol("objc_lookUpClass", 0, 0)) + function = find_function_in_inferior("objc_lookUpClass"); + else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0)) + function = find_function_in_inferior("objc_lookup_class"); + else + { + complaint (&symfile_complaints, "no way to lookup Objective-C classes"); + return 0; + } + + classval = value_string (classname, strlen (classname) + 1); + classval = value_coerce_array (classval); + return (CORE_ADDR) value_as_long (call_function_by_hand (function, + 1, &classval)); +} + +CORE_ADDR +lookup_child_selector (char *selname) +{ + struct value * function, *selstring; + + if (! target_has_execution) + { + /* Can't call into inferior to lookup selector. */ + return 0; + } + + if (lookup_minimal_symbol("sel_getUid", 0, 0)) + function = find_function_in_inferior("sel_getUid"); + else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0)) + function = find_function_in_inferior("sel_get_any_uid"); + else + { + complaint (&symfile_complaints, "no way to lookup Objective-C selectors"); + return 0; + } + + selstring = value_coerce_array (value_string (selname, + strlen (selname) + 1)); + return value_as_long (call_function_by_hand (function, 1, &selstring)); +} + +struct value * +value_nsstring (char *ptr, int len) +{ + struct value *stringValue[3]; + struct value *function, *nsstringValue; + struct symbol *sym; + struct type *type; + + if (!target_has_execution) + return 0; /* Can't call into inferior to create NSString. */ + + sym = lookup_struct_typedef("NSString", 0, 1); + if (sym == NULL) + sym = lookup_struct_typedef("NXString", 0, 1); + if (sym == NULL) + type = lookup_pointer_type(builtin_type_void); + else + type = lookup_pointer_type(SYMBOL_TYPE (sym)); + + stringValue[2] = value_string(ptr, len); + stringValue[2] = value_coerce_array(stringValue[2]); + /* _NSNewStringFromCString replaces "istr" after Lantern2A. */ + if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0)) + { + function = find_function_in_inferior("_NSNewStringFromCString"); + nsstringValue = call_function_by_hand(function, 1, &stringValue[2]); + } + else if (lookup_minimal_symbol("istr", 0, 0)) + { + function = find_function_in_inferior("istr"); + nsstringValue = call_function_by_hand(function, 1, &stringValue[2]); + } + else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0)) + { + function = find_function_in_inferior("+[NSString stringWithCString:]"); + stringValue[0] = value_from_longest + (builtin_type_long, lookup_objc_class ("NSString")); + stringValue[1] = value_from_longest + (builtin_type_long, lookup_child_selector ("stringWithCString:")); + nsstringValue = call_function_by_hand(function, 3, &stringValue[0]); + } + else + error ("NSString: internal error -- no way to create new NSString"); + + VALUE_TYPE(nsstringValue) = type; + return nsstringValue; +} + +/* Objective-C name demangling. */ + +char * +objc_demangle (const char *mangled, int options) +{ + char *demangled, *cp; + + if (mangled[0] == '_' && + (mangled[1] == 'i' || mangled[1] == 'c') && + mangled[2] == '_') + { + cp = demangled = xmalloc(strlen(mangled) + 2); + + if (mangled[1] == 'i') + *cp++ = '-'; /* for instance method */ + else + *cp++ = '+'; /* for class method */ + + *cp++ = '['; /* opening left brace */ + strcpy(cp, mangled+3); /* tack on the rest of the mangled name */ + + while (*cp && *cp == '_') + cp++; /* skip any initial underbars in class name */ + + cp = strchr(cp, '_'); + if (!cp) /* find first non-initial underbar */ + { + xfree(demangled); /* not mangled name */ + return NULL; + } + if (cp[1] == '_') { /* easy case: no category name */ + *cp++ = ' '; /* replace two '_' with one ' ' */ + strcpy(cp, mangled + (cp - demangled) + 2); + } + else { + *cp++ = '('; /* less easy case: category name */ + cp = strchr(cp, '_'); + if (!cp) + { + xfree(demangled); /* not mangled name */ + return NULL; + } + *cp++ = ')'; + *cp++ = ' '; /* overwriting 1st char of method name... */ + strcpy(cp, mangled + (cp - demangled)); /* get it back */ + } + + while (*cp && *cp == '_') + cp++; /* skip any initial underbars in method name */ + + for (; *cp; cp++) + if (*cp == '_') + *cp = ':'; /* replace remaining '_' with ':' */ + + *cp++ = ']'; /* closing right brace */ + *cp++ = 0; /* string terminator */ + return demangled; + } + else + return NULL; /* Not an objc mangled name. */ +} + +/* Print the character C on STREAM as part of the contents of a + literal string whose delimiter is QUOTER. Note that that format + for printing characters and strings is language specific. */ + +static void +objc_emit_char (int c, struct ui_file *stream, int quoter) +{ + + c &= 0xFF; /* Avoid sign bit follies. */ + + if (PRINT_LITERAL_FORM (c)) + { + if (c == '\\' || c == quoter) + { + fputs_filtered ("\\", stream); + } + fprintf_filtered (stream, "%c", c); + } + else + { + switch (c) + { + case '\n': + fputs_filtered ("\\n", stream); + break; + case '\b': + fputs_filtered ("\\b", stream); + break; + case '\t': + fputs_filtered ("\\t", stream); + break; + case '\f': + fputs_filtered ("\\f", stream); + break; + case '\r': + fputs_filtered ("\\r", stream); + break; + case '\033': + fputs_filtered ("\\e", stream); + break; + case '\007': + fputs_filtered ("\\a", stream); + break; + default: + fprintf_filtered (stream, "\\%.3o", (unsigned int) c); + break; + } + } +} + +static void +objc_printchar (int c, struct ui_file *stream) +{ + fputs_filtered ("'", stream); + objc_emit_char (c, stream, '\''); + fputs_filtered ("'", stream); +} + +/* Print the character string STRING, printing at most LENGTH + characters. Printing stops early if the number hits print_max; + repeat counts are printed as appropriate. Print ellipses at the + end if we had to stop before printing LENGTH characters, or if + FORCE_ELLIPSES. */ + +static void +objc_printstr (struct ui_file *stream, char *string, + unsigned int length, int width, int force_ellipses) +{ + unsigned int i; + unsigned int things_printed = 0; + int in_quotes = 0; + int need_comma = 0; + + /* If the string was not truncated due to `set print elements', and + the last byte of it is a null, we don't print that, in + traditional C style. */ + if ((!force_ellipses) && length > 0 && string[length-1] == '\0') + length--; + + if (length == 0) + { + fputs_filtered ("\"\"", stream); + return; + } + + for (i = 0; i < length && things_printed < print_max; ++i) + { + /* Position of the character we are examining to see whether it + is repeated. */ + unsigned int rep1; + /* Number of repetitions we have detected so far. */ + unsigned int reps; + + QUIT; + + if (need_comma) + { + fputs_filtered (", ", stream); + need_comma = 0; + } + + rep1 = i + 1; + reps = 1; + while (rep1 < length && string[rep1] == string[i]) + { + ++rep1; + ++reps; + } + + if (reps > repeat_count_threshold) + { + if (in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\", ", stream); + else + fputs_filtered ("\", ", stream); + in_quotes = 0; + } + objc_printchar (string[i], stream); + fprintf_filtered (stream, " ", reps); + i = rep1 - 1; + things_printed += repeat_count_threshold; + need_comma = 1; + } + else + { + if (!in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + in_quotes = 1; + } + objc_emit_char (string[i], stream, '"'); + ++things_printed; + } + } + + /* Terminate the quotes if necessary. */ + if (in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + } + + if (force_ellipses || i < length) + fputs_filtered ("...", stream); +} + +/* Create a fundamental C type using default reasonable for the + current target. + + Some object/debugging file formats (DWARF version 1, COFF, etc) do + not define fundamental types such as "int" or "double". Others + (stabs or DWARF version 2, etc) do define fundamental types. For + the formats which don't provide fundamental types, gdb can create + such types using this function. + + FIXME: Some compilers distinguish explicitly signed integral types + (signed short, signed int, signed long) from "regular" integral + types (short, int, long) in the debugging information. There is + some disagreement as to how useful this feature is. In particular, + gcc does not support this. Also, only some debugging formats allow + the distinction to be passed on to a debugger. For now, we always + just use "short", "int", or "long" as the type name, for both the + implicit and explicitly signed types. This also makes life easier + for the gdb test suite since we don't have to account for the + differences in output depending upon what the compiler and + debugging format support. We will probably have to re-examine the + issue when gdb starts taking it's fundamental type information + directly from the debugging information supplied by the compiler. + fnf@cygnus.com */ + +static struct type * +objc_create_fundamental_type (struct objfile *objfile, int typeid) +{ + struct type *type = NULL; + + switch (typeid) + { + default: + /* FIXME: For now, if we are asked to produce a type not in + this language, create the equivalent of a C integer type + with the name "". When all the dust settles from + the type reconstruction work, this should probably become + an error. */ + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "", objfile); + warning ("internal error: no C/C++ fundamental type %d", typeid); + break; + case FT_VOID: + type = init_type (TYPE_CODE_VOID, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "void", objfile); + break; + case FT_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "char", objfile); + break; + case FT_SIGNED_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "signed char", objfile); + break; + case FT_UNSIGNED_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned char", objfile); + break; + case FT_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, "short", objfile); + break; + case FT_SIGNED_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, "short", objfile); /* FIXME-fnf */ + break; + case FT_UNSIGNED_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned short", objfile); + break; + case FT_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "int", objfile); + break; + case FT_SIGNED_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "int", objfile); /* FIXME -fnf */ + break; + case FT_UNSIGNED_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned int", objfile); + break; + case FT_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, "long", objfile); + break; + case FT_SIGNED_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, "long", objfile); /* FIXME -fnf */ + break; + case FT_UNSIGNED_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned long", objfile); + break; + case FT_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "long long", objfile); + break; + case FT_SIGNED_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "signed long long", objfile); + break; + case FT_UNSIGNED_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned long long", objfile); + break; + case FT_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_FLOAT_BIT / TARGET_CHAR_BIT, + 0, "float", objfile); + break; + case FT_DBL_PREC_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "double", objfile); + break; + case FT_EXT_PREC_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long double", objfile); + break; + } + return (type); +} + +/* Determine if we are currently in the Objective-C dispatch function. + If so, get the address of the method function that the dispatcher + would call and use that as the function to step into instead. Also + skip over the trampoline for the function (if any). This is better + for the user since they are only interested in stepping into the + method function anyway. */ +static CORE_ADDR +objc_skip_trampoline (CORE_ADDR stop_pc) +{ + CORE_ADDR real_stop_pc; + CORE_ADDR method_stop_pc; + + real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc); + + if (real_stop_pc != 0) + find_objc_msgcall (real_stop_pc, &method_stop_pc); + else + find_objc_msgcall (stop_pc, &method_stop_pc); + + if (method_stop_pc) + { + real_stop_pc = SKIP_TRAMPOLINE_CODE (method_stop_pc); + if (real_stop_pc == 0) + real_stop_pc = method_stop_pc; + } + + return real_stop_pc; +} + + +/* Table mapping opcodes into strings for printing operators + and precedences of the operators. */ + +static const struct op_print objc_op_print_tab[] = + { + {",", BINOP_COMMA, PREC_COMMA, 0}, + {"=", BINOP_ASSIGN, PREC_ASSIGN, 1}, + {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, + {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, + {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0}, + {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0}, + {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0}, + {"==", BINOP_EQUAL, PREC_EQUAL, 0}, + {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0}, + {"<=", BINOP_LEQ, PREC_ORDER, 0}, + {">=", BINOP_GEQ, PREC_ORDER, 0}, + {">", BINOP_GTR, PREC_ORDER, 0}, + {"<", BINOP_LESS, PREC_ORDER, 0}, + {">>", BINOP_RSH, PREC_SHIFT, 0}, + {"<<", BINOP_LSH, PREC_SHIFT, 0}, + {"+", BINOP_ADD, PREC_ADD, 0}, + {"-", BINOP_SUB, PREC_ADD, 0}, + {"*", BINOP_MUL, PREC_MUL, 0}, + {"/", BINOP_DIV, PREC_MUL, 0}, + {"%", BINOP_REM, PREC_MUL, 0}, + {"@", BINOP_REPEAT, PREC_REPEAT, 0}, + {"-", UNOP_NEG, PREC_PREFIX, 0}, + {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, + {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0}, + {"*", UNOP_IND, PREC_PREFIX, 0}, + {"&", UNOP_ADDR, PREC_PREFIX, 0}, + {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0}, + {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, + {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, + {NULL, OP_NULL, PREC_NULL, 0} +}; + +struct type ** const (objc_builtin_types[]) = +{ + &builtin_type_int, + &builtin_type_long, + &builtin_type_short, + &builtin_type_char, + &builtin_type_float, + &builtin_type_double, + &builtin_type_void, + &builtin_type_long_long, + &builtin_type_signed_char, + &builtin_type_unsigned_char, + &builtin_type_unsigned_short, + &builtin_type_unsigned_int, + &builtin_type_unsigned_long, + &builtin_type_unsigned_long_long, + &builtin_type_long_double, + &builtin_type_complex, + &builtin_type_double_complex, + 0 +}; + +const struct language_defn objc_language_defn = { + "objective-c", /* Language name */ + language_objc, + objc_builtin_types, + range_check_off, + type_check_off, + case_sensitive_on, + &exp_descriptor_standard, + objc_parse, + objc_error, + objc_printchar, /* Print a character constant */ + objc_printstr, /* Function to print string constant */ + objc_emit_char, + objc_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 */ + objc_skip_trampoline, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + objc_demangle, /* Language specific symbol demangler */ + {"", "", "", ""}, /* Binary format info */ + {"0%lo", "0", "o", ""}, /* Octal format info */ + {"%ld", "", "d", ""}, /* Decimal format info */ + {"0x%lx", "0x", "x", ""}, /* Hex format info */ + objc_op_print_tab, /* Expression operators for printing */ + 1, /* C-style arrays */ + 0, /* String lower bound */ + &builtin_type_char, /* Type of string elements */ + default_word_break_characters, + LANG_MAGIC +}; + +/* + * ObjC: + * Following functions help construct Objective-C message calls + */ + +struct selname /* For parsing Objective-C. */ + { + struct selname *next; + char *msglist_sel; + int msglist_len; + }; + +static int msglist_len; +static struct selname *selname_chain; +static char *msglist_sel; + +void +start_msglist(void) +{ + struct selname *new = + (struct selname *) xmalloc (sizeof (struct selname)); + + new->next = selname_chain; + new->msglist_len = msglist_len; + new->msglist_sel = msglist_sel; + msglist_len = 0; + msglist_sel = (char *)xmalloc(1); + *msglist_sel = 0; + selname_chain = new; +} + +void +add_msglist(struct stoken *str, int addcolon) +{ + char *s, *p; + int len, plen; + + if (str == 0) { /* Unnamed arg, or... */ + if (addcolon == 0) { /* variable number of args. */ + msglist_len++; + return; + } + p = ""; + plen = 0; + } else { + p = str->ptr; + plen = str->length; + } + len = plen + strlen(msglist_sel) + 2; + s = (char *)xmalloc(len); + strcpy(s, msglist_sel); + strncat(s, p, plen); + xfree(msglist_sel); + msglist_sel = s; + if (addcolon) { + s[len-2] = ':'; + s[len-1] = 0; + msglist_len++; + } else + s[len-2] = '\0'; +} + +int +end_msglist(void) +{ + int val = msglist_len; + struct selname *sel = selname_chain; + char *p = msglist_sel; + CORE_ADDR selid; + + selname_chain = sel->next; + msglist_len = sel->msglist_len; + msglist_sel = sel->msglist_sel; + selid = lookup_child_selector(p); + if (!selid) + error("Can't find selector \"%s\"", p); + write_exp_elt_longcst (selid); + xfree(p); + write_exp_elt_longcst (val); /* Number of args */ + xfree(sel); + + return val; +} + +/* + * Function: specialcmp (char *a, char *b) + * + * Special strcmp: treats ']' and ' ' as end-of-string. + * Used for qsorting lists of objc methods (either by class or selector). + */ + +static int +specialcmp (char *a, char *b) +{ + while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']') + { + if (*a != *b) + return *a - *b; + a++, b++; + } + if (*a && *a != ' ' && *a != ']') + return 1; /* a is longer therefore greater */ + if (*b && *b != ' ' && *b != ']') + return -1; /* a is shorter therefore lesser */ + return 0; /* a and b are identical */ +} + +/* + * Function: compare_selectors (const void *, const void *) + * + * Comparison function for use with qsort. Arguments are symbols or + * msymbols Compares selector part of objc method name alphabetically. + */ + +static int +compare_selectors (const void *a, const void *b) +{ + char *aname, *bname; + + aname = SYMBOL_PRINT_NAME (*(struct symbol **) a); + bname = SYMBOL_PRINT_NAME (*(struct symbol **) b); + if (aname == NULL || bname == NULL) + error ("internal: compare_selectors(1)"); + + aname = strchr(aname, ' '); + bname = strchr(bname, ' '); + if (aname == NULL || bname == NULL) + error ("internal: compare_selectors(2)"); + + return specialcmp (aname+1, bname+1); +} + +/* + * Function: selectors_info (regexp, from_tty) + * + * Implements the "Info selectors" command. Takes an optional regexp + * arg. Lists all objective c selectors that match the regexp. Works + * by grepping thru all symbols for objective c methods. Output list + * is sorted and uniqued. + */ + +static void +selectors_info (char *regexp, int from_tty) +{ + struct objfile *objfile; + struct minimal_symbol *msymbol; + char *name; + char *val; + int matches = 0; + int maxlen = 0; + int ix; + char myregexp[2048]; + char asel[256]; + struct symbol **sym_arr; + int plusminus = 0; + + if (regexp == NULL) + strcpy(myregexp, ".*]"); /* Null input, match all objc methods. */ + else + { + if (*regexp == '+' || *regexp == '-') + { /* User wants only class methods or only instance methods. */ + plusminus = *regexp++; + while (*regexp == ' ' || *regexp == '\t') + regexp++; + } + if (*regexp == '\0') + strcpy(myregexp, ".*]"); + else + { + strcpy(myregexp, regexp); + if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */ + myregexp[strlen(myregexp) - 1] = ']'; /* end of method name */ + else + strcat(myregexp, ".*]"); + } + } + + if (regexp != NULL) + { + val = re_comp (myregexp); + if (val != 0) + error ("Invalid regexp (%s): %s", val, regexp); + } + + /* First time thru is JUST to get max length and count. */ + ALL_MSYMBOLS (objfile, msymbol) + { + QUIT; + name = SYMBOL_NATURAL_NAME (msymbol); + if (name && + (name[0] == '-' || name[0] == '+') && + name[1] == '[') /* Got a method name. */ + { + /* Filter for class/instance methods. */ + if (plusminus && name[0] != plusminus) + continue; + /* Find selector part. */ + name = (char *) strchr(name+2, ' '); + if (regexp == NULL || re_exec(++name) != 0) + { + char *mystart = name; + char *myend = (char *) strchr(mystart, ']'); + + if (myend && (myend - mystart > maxlen)) + maxlen = myend - mystart; /* Get longest selector. */ + matches++; + } + } + } + if (matches) + { + printf_filtered ("Selectors matching \"%s\":\n\n", + regexp ? regexp : "*"); + + sym_arr = alloca (matches * sizeof (struct symbol *)); + matches = 0; + ALL_MSYMBOLS (objfile, msymbol) + { + QUIT; + name = SYMBOL_NATURAL_NAME (msymbol); + if (name && + (name[0] == '-' || name[0] == '+') && + name[1] == '[') /* Got a method name. */ + { + /* Filter for class/instance methods. */ + if (plusminus && name[0] != plusminus) + continue; + /* Find selector part. */ + name = (char *) strchr(name+2, ' '); + if (regexp == NULL || re_exec(++name) != 0) + sym_arr[matches++] = (struct symbol *) msymbol; + } + } + + qsort (sym_arr, matches, sizeof (struct minimal_symbol *), + compare_selectors); + /* Prevent compare on first iteration. */ + asel[0] = 0; + for (ix = 0; ix < matches; ix++) /* Now do the output. */ + { + char *p = asel; + + QUIT; + name = SYMBOL_NATURAL_NAME (sym_arr[ix]); + name = strchr (name, ' ') + 1; + if (p[0] && specialcmp(name, p) == 0) + continue; /* Seen this one already (not unique). */ + + /* Copy selector part. */ + while (*name && *name != ']') + *p++ = *name++; + *p++ = '\0'; + /* Print in columns. */ + puts_filtered_tabular(asel, maxlen + 1, 0); + } + begin_line(); + } + else + printf_filtered ("No selectors matching \"%s\"\n", regexp ? regexp : "*"); +} + +/* + * Function: compare_classes (const void *, const void *) + * + * Comparison function for use with qsort. Arguments are symbols or + * msymbols Compares class part of objc method name alphabetically. + */ + +static int +compare_classes (const void *a, const void *b) +{ + char *aname, *bname; + + aname = SYMBOL_PRINT_NAME (*(struct symbol **) a); + bname = SYMBOL_PRINT_NAME (*(struct symbol **) b); + if (aname == NULL || bname == NULL) + error ("internal: compare_classes(1)"); + + return specialcmp (aname+1, bname+1); +} + +/* + * Function: classes_info(regexp, from_tty) + * + * Implements the "info classes" command for objective c classes. + * Lists all objective c classes that match the optional regexp. + * Works by grepping thru the list of objective c methods. List will + * be sorted and uniqued (since one class may have many methods). + * BUGS: will not list a class that has no methods. + */ + +static void +classes_info (char *regexp, int from_tty) +{ + struct objfile *objfile; + struct minimal_symbol *msymbol; + char *name; + char *val; + int matches = 0; + int maxlen = 0; + int ix; + char myregexp[2048]; + char aclass[256]; + struct symbol **sym_arr; + + if (regexp == NULL) + strcpy(myregexp, ".* "); /* Null input: match all objc classes. */ + else + { + strcpy(myregexp, regexp); + if (myregexp[strlen(myregexp) - 1] == '$') + /* In the method name, the end of the class name is marked by ' '. */ + myregexp[strlen(myregexp) - 1] = ' '; + else + strcat(myregexp, ".* "); + } + + if (regexp != NULL) + { + val = re_comp (myregexp); + if (val != 0) + error ("Invalid regexp (%s): %s", val, regexp); + } + + /* First time thru is JUST to get max length and count. */ + ALL_MSYMBOLS (objfile, msymbol) + { + QUIT; + name = SYMBOL_NATURAL_NAME (msymbol); + if (name && + (name[0] == '-' || name[0] == '+') && + name[1] == '[') /* Got a method name. */ + if (regexp == NULL || re_exec(name+2) != 0) + { + /* Compute length of classname part. */ + char *mystart = name + 2; + char *myend = (char *) strchr(mystart, ' '); + + if (myend && (myend - mystart > maxlen)) + maxlen = myend - mystart; + matches++; + } + } + if (matches) + { + printf_filtered ("Classes matching \"%s\":\n\n", + regexp ? regexp : "*"); + sym_arr = alloca (matches * sizeof (struct symbol *)); + matches = 0; + ALL_MSYMBOLS (objfile, msymbol) + { + QUIT; + name = SYMBOL_NATURAL_NAME (msymbol); + if (name && + (name[0] == '-' || name[0] == '+') && + name[1] == '[') /* Got a method name. */ + if (regexp == NULL || re_exec(name+2) != 0) + sym_arr[matches++] = (struct symbol *) msymbol; + } + + qsort (sym_arr, matches, sizeof (struct minimal_symbol *), + compare_classes); + /* Prevent compare on first iteration. */ + aclass[0] = 0; + for (ix = 0; ix < matches; ix++) /* Now do the output. */ + { + char *p = aclass; + + QUIT; + name = SYMBOL_NATURAL_NAME (sym_arr[ix]); + name += 2; + if (p[0] && specialcmp(name, p) == 0) + continue; /* Seen this one already (not unique). */ + + /* Copy class part of method name. */ + while (*name && *name != ' ') + *p++ = *name++; + *p++ = '\0'; + /* Print in columns. */ + puts_filtered_tabular(aclass, maxlen + 1, 0); + } + begin_line(); + } + else + printf_filtered ("No classes matching \"%s\"\n", regexp ? regexp : "*"); +} + +/* + * Function: find_imps (char *selector, struct symbol **sym_arr) + * + * Input: a string representing a selector + * a pointer to an array of symbol pointers + * possibly a pointer to a symbol found by the caller. + * + * Output: number of methods that implement that selector. Side + * effects: The array of symbol pointers is filled with matching syms. + * + * By analogy with function "find_methods" (symtab.c), builds a list + * of symbols matching the ambiguous input, so that "decode_line_2" + * (symtab.c) can list them and ask the user to choose one or more. + * In this case the matches are objective c methods + * ("implementations") matching an objective c selector. + * + * Note that it is possible for a normal (c-style) function to have + * the same name as an objective c selector. To prevent the selector + * from eclipsing the function, we allow the caller (decode_line_1) to + * search for such a function first, and if it finds one, pass it in + * to us. We will then integrate it into the list. We also search + * for one here, among the minsyms. + * + * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided + * into two parts: debuggable (struct symbol) syms, and + * non_debuggable (struct minimal_symbol) syms. The debuggable + * ones will come first, before NUM_DEBUGGABLE (which will thus + * be the index of the first non-debuggable one). + */ + +/* + * Function: total_number_of_imps (char *selector); + * + * Input: a string representing a selector + * Output: number of methods that implement that selector. + * + * By analogy with function "total_number_of_methods", this allows + * decode_line_1 (symtab.c) to detect if there are objective c methods + * matching the input, and to allocate an array of pointers to them + * which can be manipulated by "decode_line_2" (also in symtab.c). + */ + +char * +parse_selector (char *method, char **selector) +{ + char *s1 = NULL; + char *s2 = NULL; + int found_quote = 0; + + char *nselector = NULL; + + gdb_assert (selector != NULL); + + s1 = method; + + while (isspace (*s1)) + s1++; + if (*s1 == '\'') + { + found_quote = 1; + s1++; + } + while (isspace (*s1)) + s1++; + + nselector = s1; + s2 = s1; + + for (;;) { + if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':')) + *s1++ = *s2; + else if (isspace (*s2)) + ; + else if ((*s2 == '\0') || (*s2 == '\'')) + break; + else + return NULL; + s2++; + } + *s1++ = '\0'; + + while (isspace (*s2)) + s2++; + if (found_quote) + { + if (*s2 == '\'') + s2++; + while (isspace (*s2)) + s2++; + } + + if (selector != NULL) + *selector = nselector; + + return s2; +} + +char * +parse_method (char *method, char *type, char **class, + char **category, char **selector) +{ + char *s1 = NULL; + char *s2 = NULL; + int found_quote = 0; + + char ntype = '\0'; + char *nclass = NULL; + char *ncategory = NULL; + char *nselector = NULL; + + gdb_assert (type != NULL); + gdb_assert (class != NULL); + gdb_assert (category != NULL); + gdb_assert (selector != NULL); + + s1 = method; + + while (isspace (*s1)) + s1++; + if (*s1 == '\'') + { + found_quote = 1; + s1++; + } + while (isspace (*s1)) + s1++; + + if ((s1[0] == '+') || (s1[0] == '-')) + ntype = *s1++; + + while (isspace (*s1)) + s1++; + + if (*s1 != '[') + return NULL; + s1++; + + nclass = s1; + while (isalnum (*s1) || (*s1 == '_')) + s1++; + + s2 = s1; + while (isspace (*s2)) + s2++; + + if (*s2 == '(') + { + s2++; + while (isspace (*s2)) + s2++; + ncategory = s2; + while (isalnum (*s2) || (*s2 == '_')) + s2++; + *s2++ = '\0'; + } + + /* Truncate the class name now that we're not using the open paren. */ + *s1++ = '\0'; + + nselector = s2; + s1 = s2; + + for (;;) { + if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':')) + *s1++ = *s2; + else if (isspace (*s2)) + ; + else if (*s2 == ']') + break; + else + return NULL; + s2++; + } + *s1++ = '\0'; + s2++; + + while (isspace (*s2)) + s2++; + if (found_quote) + { + if (*s2 != '\'') + return NULL; + s2++; + while (isspace (*s2)) + s2++; + } + + if (type != NULL) + *type = ntype; + if (class != NULL) + *class = nclass; + if (category != NULL) + *category = ncategory; + if (selector != NULL) + *selector = nselector; + + return s2; +} + +static void +find_methods (struct symtab *symtab, char type, + const char *class, const char *category, + const char *selector, struct symbol **syms, + unsigned int *nsym, unsigned int *ndebug) +{ + struct objfile *objfile = NULL; + struct minimal_symbol *msymbol = NULL; + struct block *block = NULL; + struct symbol *sym = NULL; + + char *symname = NULL; + + char ntype = '\0'; + char *nclass = NULL; + char *ncategory = NULL; + char *nselector = NULL; + + unsigned int csym = 0; + unsigned int cdebug = 0; + + static char *tmp = NULL; + static unsigned int tmplen = 0; + + gdb_assert (nsym != NULL); + gdb_assert (ndebug != NULL); + + if (symtab) + block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); + + ALL_MSYMBOLS (objfile, msymbol) + { + QUIT; + + if ((msymbol->type != mst_text) && (msymbol->type != mst_file_text)) + /* Not a function or method. */ + continue; + + if (symtab) + if ((SYMBOL_VALUE_ADDRESS (msymbol) < BLOCK_START (block)) || + (SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block))) + /* Not in the specified symtab. */ + continue; + + symname = SYMBOL_NATURAL_NAME (msymbol); + if (symname == NULL) + continue; + + if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '[')) + /* Not a method name. */ + continue; + + while ((strlen (symname) + 1) >= tmplen) + { + tmplen = (tmplen == 0) ? 1024 : tmplen * 2; + tmp = xrealloc (tmp, tmplen); + } + strcpy (tmp, symname); + + if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL) + continue; + + if ((type != '\0') && (ntype != type)) + continue; + + if ((class != NULL) + && ((nclass == NULL) || (strcmp (class, nclass) != 0))) + continue; + + if ((category != NULL) && + ((ncategory == NULL) || (strcmp (category, ncategory) != 0))) + continue; + + if ((selector != NULL) && + ((nselector == NULL) || (strcmp (selector, nselector) != 0))) + continue; + + sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol)); + if (sym != NULL) + { + const char *newsymname = SYMBOL_NATURAL_NAME (sym); + + if (strcmp (symname, newsymname) == 0) + { + /* Found a high-level method sym: swap it into the + lower part of sym_arr (below num_debuggable). */ + if (syms != NULL) + { + syms[csym] = syms[cdebug]; + syms[cdebug] = sym; + } + csym++; + cdebug++; + } + else + { + warning ( +"debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring", + newsymname, symname); + if (syms != NULL) + syms[csym] = (struct symbol *) msymbol; + csym++; + } + } + else + { + /* Found a non-debuggable method symbol. */ + if (syms != NULL) + syms[csym] = (struct symbol *) msymbol; + csym++; + } + } + + if (nsym != NULL) + *nsym = csym; + if (ndebug != NULL) + *ndebug = cdebug; +} + +char *find_imps (struct symtab *symtab, struct block *block, + char *method, struct symbol **syms, + unsigned int *nsym, unsigned int *ndebug) +{ + char type = '\0'; + char *class = NULL; + char *category = NULL; + char *selector = NULL; + + unsigned int csym = 0; + unsigned int cdebug = 0; + + unsigned int ncsym = 0; + unsigned int ncdebug = 0; + + char *buf = NULL; + char *tmp = NULL; + + gdb_assert (nsym != NULL); + gdb_assert (ndebug != NULL); + + if (nsym != NULL) + *nsym = 0; + if (ndebug != NULL) + *ndebug = 0; + + buf = (char *) alloca (strlen (method) + 1); + strcpy (buf, method); + tmp = parse_method (buf, &type, &class, &category, &selector); + + if (tmp == NULL) { + + struct symbol *sym = NULL; + struct minimal_symbol *msym = NULL; + + strcpy (buf, method); + tmp = parse_selector (buf, &selector); + + if (tmp == NULL) + return NULL; + + sym = lookup_symbol (selector, block, VAR_DOMAIN, 0, NULL); + if (sym != NULL) + { + if (syms) + syms[csym] = sym; + csym++; + cdebug++; + } + + if (sym == NULL) + msym = lookup_minimal_symbol (selector, 0, 0); + + if (msym != NULL) + { + if (syms) + syms[csym] = (struct symbol *)msym; + csym++; + } + } + + if (syms != NULL) + find_methods (symtab, type, class, category, selector, + syms + csym, &ncsym, &ncdebug); + else + find_methods (symtab, type, class, category, selector, + NULL, &ncsym, &ncdebug); + + /* If we didn't find any methods, just return. */ + if (ncsym == 0 && ncdebug == 0) + return method; + + /* Take debug symbols from the second batch of symbols and swap them + * with debug symbols from the first batch. Repeat until either the + * second section is out of debug symbols or the first section is + * full of debug symbols. Either way we have all debug symbols + * packed to the beginning of the buffer. + */ + + if (syms != NULL) + { + while ((cdebug < csym) && (ncdebug > 0)) + { + struct symbol *s = NULL; + /* First non-debugging symbol. */ + unsigned int i = cdebug; + /* Last of second batch of debug symbols. */ + unsigned int j = csym + ncdebug - 1; + + s = syms[j]; + syms[j] = syms[i]; + syms[i] = s; + + /* We've moved a symbol from the second debug section to the + first one. */ + cdebug++; + ncdebug--; + } + } + + csym += ncsym; + cdebug += ncdebug; + + if (nsym != NULL) + *nsym = csym; + if (ndebug != NULL) + *ndebug = cdebug; + + if (syms == NULL) + return method + (tmp - buf); + + if (csym > 1) + { + /* Sort debuggable symbols. */ + if (cdebug > 1) + qsort (syms, cdebug, sizeof (struct minimal_symbol *), + compare_classes); + + /* Sort minimal_symbols. */ + if ((csym - cdebug) > 1) + qsort (&syms[cdebug], csym - cdebug, + sizeof (struct minimal_symbol *), compare_classes); + } + /* Terminate the sym_arr list. */ + syms[csym] = 0; + + return method + (tmp - buf); +} + +static void +print_object_command (char *args, int from_tty) +{ + struct value *object, *function, *description; + CORE_ADDR string_addr, object_addr; + int i = 0; + char c = -1; + + if (!args || !*args) + error ( +"The 'print-object' command requires an argument (an Objective-C object)"); + + { + struct expression *expr = parse_expression (args); + struct cleanup *old_chain = + make_cleanup (free_current_contents, &expr); + int pc = 0; + + object = expr->language_defn->la_exp_desc->evaluate_exp + (builtin_type_void_data_ptr, expr, &pc, EVAL_NORMAL); + do_cleanups (old_chain); + } + + /* Validate the address for sanity. */ + object_addr = value_as_long (object); + read_memory (object_addr, &c, 1); + + function = find_function_in_inferior ("_NSPrintForDebugger"); + if (function == NULL) + error ("Unable to locate _NSPrintForDebugger in child process"); + + description = call_function_by_hand (function, 1, &object); + + string_addr = value_as_long (description); + if (string_addr == 0) + error ("object returns null description"); + + read_memory (string_addr + i++, &c, 1); + if (c != '\0') + do + { /* Read and print characters up to EOS. */ + QUIT; + printf_filtered ("%c", c); + read_memory (string_addr + i++, &c, 1); + } while (c != 0); + else + printf_filtered(""); + printf_filtered ("\n"); +} + +/* The data structure 'methcalls' is used to detect method calls (thru + * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.), + * and ultimately find the method being called. + */ + +struct objc_methcall { + char *name; + /* Return instance method to be called. */ + int (*stop_at) (CORE_ADDR, CORE_ADDR *); + /* Start of pc range corresponding to method invocation. */ + CORE_ADDR begin; + /* End of pc range corresponding to method invocation. */ + CORE_ADDR end; +}; + +static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc); +static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc); +static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc); +static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc); + +static struct objc_methcall methcalls[] = { + { "_objc_msgSend", resolve_msgsend, 0, 0}, + { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0}, + { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0}, + { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0}, + { "_objc_getClass", NULL, 0, 0}, + { "_objc_getMetaClass", NULL, 0, 0} +}; + +#define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0])) + +/* The following function, "find_objc_msgsend", fills in the data + * structure "objc_msgs" by finding the addresses of each of the + * (currently four) functions that it holds (of which objc_msgSend is + * the first). This must be called each time symbols are loaded, in + * case the functions have moved for some reason. + */ + +static void +find_objc_msgsend (void) +{ + unsigned int i; + for (i = 0; i < nmethcalls; i++) { + + struct minimal_symbol *func; + + /* Try both with and without underscore. */ + func = lookup_minimal_symbol (methcalls[i].name, NULL, NULL); + if ((func == NULL) && (methcalls[i].name[0] == '_')) { + func = lookup_minimal_symbol (methcalls[i].name + 1, NULL, NULL); + } + if (func == NULL) { + methcalls[i].begin = 0; + methcalls[i].end = 0; + continue; + } + + methcalls[i].begin = SYMBOL_VALUE_ADDRESS (func); + do { + methcalls[i].end = SYMBOL_VALUE_ADDRESS (++func); + } while (methcalls[i].begin == methcalls[i].end); + } +} + +/* find_objc_msgcall (replaces pc_off_limits) + * + * ALL that this function now does is to determine whether the input + * address ("pc") is the address of one of the Objective-C message + * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and + * if so, it returns the address of the method that will be called. + * + * The old function "pc_off_limits" used to do a lot of other things + * in addition, such as detecting shared library jump stubs and + * returning the address of the shlib function that would be called. + * That functionality has been moved into the SKIP_TRAMPOLINE_CODE and + * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target- + * dependent modules. + */ + +struct objc_submethod_helper_data { + int (*f) (CORE_ADDR, CORE_ADDR *); + CORE_ADDR pc; + CORE_ADDR *new_pc; +}; + +static int +find_objc_msgcall_submethod_helper (void * arg) +{ + struct objc_submethod_helper_data *s = + (struct objc_submethod_helper_data *) arg; + + if (s->f (s->pc, s->new_pc) == 0) + return 1; + else + return 0; +} + +static int +find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *), + CORE_ADDR pc, + CORE_ADDR *new_pc) +{ + struct objc_submethod_helper_data s; + + s.f = f; + s.pc = pc; + s.new_pc = new_pc; + + if (catch_errors (find_objc_msgcall_submethod_helper, + (void *) &s, + "Unable to determine target of Objective-C method call (ignoring):\n", + RETURN_MASK_ALL) == 0) + return 1; + else + return 0; +} + +int +find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc) +{ + unsigned int i; + + find_objc_msgsend (); + if (new_pc != NULL) + { + *new_pc = 0; + } + + for (i = 0; i < nmethcalls; i++) + if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end)) + { + if (methcalls[i].stop_at != NULL) + return find_objc_msgcall_submethod (methcalls[i].stop_at, + pc, new_pc); + else + return 0; + } + + return 0; +} + +extern initialize_file_ftype _initialize_objc_language; /* -Wmissing-prototypes */ + +void +_initialize_objc_language (void) +{ + add_language (&objc_language_defn); + add_info ("selectors", selectors_info, /* INFO SELECTORS command. */ + "All Objective-C selectors, or those matching REGEXP."); + add_info ("classes", classes_info, /* INFO CLASSES command. */ + "All Objective-C classes, or those matching REGEXP."); + add_com ("print-object", class_vars, print_object_command, + "Ask an Objective-C object to print itself."); + add_com_alias ("po", "print-object", class_vars, 1); +} + +static void +read_objc_method (CORE_ADDR addr, struct objc_method *method) +{ + method->name = read_memory_unsigned_integer (addr + 0, 4); + method->types = read_memory_unsigned_integer (addr + 4, 4); + method->imp = read_memory_unsigned_integer (addr + 8, 4); +} + +static +unsigned long read_objc_methlist_nmethods (CORE_ADDR addr) +{ + return read_memory_unsigned_integer (addr + 4, 4); +} + +static void +read_objc_methlist_method (CORE_ADDR addr, unsigned long num, + struct objc_method *method) +{ + gdb_assert (num < read_objc_methlist_nmethods (addr)); + read_objc_method (addr + 8 + (12 * num), method); +} + +static void +read_objc_object (CORE_ADDR addr, struct objc_object *object) +{ + object->isa = read_memory_unsigned_integer (addr, 4); +} + +static void +read_objc_super (CORE_ADDR addr, struct objc_super *super) +{ + super->receiver = read_memory_unsigned_integer (addr, 4); + super->class = read_memory_unsigned_integer (addr + 4, 4); +}; + +static void +read_objc_class (CORE_ADDR addr, struct objc_class *class) +{ + class->isa = read_memory_unsigned_integer (addr, 4); + class->super_class = read_memory_unsigned_integer (addr + 4, 4); + class->name = read_memory_unsigned_integer (addr + 8, 4); + class->version = read_memory_unsigned_integer (addr + 12, 4); + class->info = read_memory_unsigned_integer (addr + 16, 4); + class->instance_size = read_memory_unsigned_integer (addr + 18, 4); + class->ivars = read_memory_unsigned_integer (addr + 24, 4); + class->methods = read_memory_unsigned_integer (addr + 28, 4); + class->cache = read_memory_unsigned_integer (addr + 32, 4); + class->protocols = read_memory_unsigned_integer (addr + 36, 4); +} + +static CORE_ADDR +find_implementation_from_class (CORE_ADDR class, CORE_ADDR sel) +{ + CORE_ADDR subclass = class; + + while (subclass != 0) + { + + struct objc_class class_str; + unsigned mlistnum = 0; + + read_objc_class (subclass, &class_str); + + for (;;) + { + CORE_ADDR mlist; + unsigned long nmethods; + unsigned long i; + + mlist = read_memory_unsigned_integer (class_str.methods + + (4 * mlistnum), 4); + if (mlist == 0) + break; + + nmethods = read_objc_methlist_nmethods (mlist); + + for (i = 0; i < nmethods; i++) + { + struct objc_method meth_str; + read_objc_methlist_method (mlist, i, &meth_str); + +#if 0 + fprintf (stderr, + "checking method 0x%lx against selector 0x%lx\n", + meth_str.name, sel); +#endif + + if (meth_str.name == sel) + /* FIXME: hppa arch was doing a pointer dereference + here. There needs to be a better way to do that. */ + return meth_str.imp; + } + mlistnum++; + } + subclass = class_str.super_class; + } + + return 0; +} + +static CORE_ADDR +find_implementation (CORE_ADDR object, CORE_ADDR sel) +{ + struct objc_object ostr; + + if (object == 0) + return 0; + read_objc_object (object, &ostr); + if (ostr.isa == 0) + return 0; + + return find_implementation_from_class (ostr.isa, sel); +} + +#define OBJC_FETCH_POINTER_ARGUMENT(argi) \ + FETCH_POINTER_ARGUMENT (get_current_frame (), argi, builtin_type_void_func_ptr) + +static int +resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc) +{ + CORE_ADDR object; + CORE_ADDR sel; + CORE_ADDR res; + + object = OBJC_FETCH_POINTER_ARGUMENT (0); + sel = OBJC_FETCH_POINTER_ARGUMENT (1); + + res = find_implementation (object, sel); + if (new_pc != 0) + *new_pc = res; + if (res == 0) + return 1; + return 0; +} + +static int +resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc) +{ + CORE_ADDR object; + CORE_ADDR sel; + CORE_ADDR res; + + object = OBJC_FETCH_POINTER_ARGUMENT (1); + sel = OBJC_FETCH_POINTER_ARGUMENT (2); + + res = find_implementation (object, sel); + if (new_pc != 0) + *new_pc = res; + if (res == 0) + return 1; + return 0; +} + +static int +resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc) +{ + struct objc_super sstr; + + CORE_ADDR super; + CORE_ADDR sel; + CORE_ADDR res; + + super = OBJC_FETCH_POINTER_ARGUMENT (0); + sel = OBJC_FETCH_POINTER_ARGUMENT (1); + + read_objc_super (super, &sstr); + if (sstr.class == 0) + return 0; + + res = find_implementation_from_class (sstr.class, sel); + if (new_pc != 0) + *new_pc = res; + if (res == 0) + return 1; + return 0; +} + +static int +resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc) +{ + struct objc_super sstr; + + CORE_ADDR super; + CORE_ADDR sel; + CORE_ADDR res; + + super = OBJC_FETCH_POINTER_ARGUMENT (1); + sel = OBJC_FETCH_POINTER_ARGUMENT (2); + + read_objc_super (super, &sstr); + if (sstr.class == 0) + return 0; + + res = find_implementation_from_class (sstr.class, sel); + if (new_pc != 0) + *new_pc = res; + if (res == 0) + return 1; + return 0; +} diff --git a/contrib/gdb/gdb/objc-lang.h b/contrib/gdb/gdb/objc-lang.h new file mode 100644 index 00000000000..5a11c5dbf16 --- /dev/null +++ b/contrib/gdb/gdb/objc-lang.h @@ -0,0 +1,68 @@ +/* Objective-C language support definitions for GDB, the GNU debugger. + + Copyright 1992 Free Software Foundation, Inc. + + Contributed by Apple Computer, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined(OBJC_LANG_H) +#define OBJC_LANG_H + +struct stoken; + +struct value; +struct block; + +extern int objc_parse (void); /* Defined in c-exp.y */ + +extern void objc_error (char *); /* Defined in c-exp.y */ + +extern int c_val_print (struct type *, char *, int, + CORE_ADDR, struct ui_file *, int, + int, int, enum val_prettyprint); + +extern int c_value_print (struct value *, struct ui_file *, + int, enum val_prettyprint); + +extern CORE_ADDR lookup_objc_class (char *classname); +extern CORE_ADDR lookup_child_selector (char *methodname); + +extern char *objc_demangle (const char *mangled, int options); + +extern int find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc); + +extern char *parse_selector (char *method, char **selector); + +extern char *parse_method (char *method, char *type, + char **class, char **category, + char **selector); + +extern char *find_imps (struct symtab *symtab, struct block *block, + char *method, struct symbol **syms, + unsigned int *nsym, unsigned int *ndebug); + +extern struct value *value_nsstring (char *ptr, int len); + +/* for parsing Objective C */ +extern void start_msglist (void); +extern void add_msglist (struct stoken *str, int addcolon); +extern int end_msglist (void); + +struct symbol *lookup_struct_typedef (char *name, struct block *block, + int noerr); + +#endif diff --git a/contrib/gdb/gdb/objfiles.c b/contrib/gdb/gdb/objfiles.c index e2a6f850554..61790778d18 100644 --- a/contrib/gdb/gdb/objfiles.c +++ b/contrib/gdb/gdb/objfiles.c @@ -1,6 +1,8 @@ /* GDB routines for manipulating objfiles. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Support, using pieces from other GDB modules. This file is part of GDB. @@ -30,30 +32,24 @@ #include "objfiles.h" #include "gdb-stabs.h" #include "target.h" +#include "bcache.h" +#include "gdb_assert.h" #include #include "gdb_stat.h" #include -#include "obstack.h" +#include "gdb_obstack.h" #include "gdb_string.h" +#include "hashtab.h" #include "breakpoint.h" +#include "block.h" +#include "dictionary.h" /* Prototypes for local functions */ -#if defined(USE_MMALLOC) && defined(HAVE_MMAP) - -#include "mmalloc.h" - -static int open_existing_mapped_file (char *, long, int); - -static int open_mapped_file (char *filename, long mtime, int flags); - -static PTR map_to_file (int); - -#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */ - -static void add_to_objfile_sections (bfd *, sec_ptr, PTR); +static void objfile_alloc_data (struct objfile *objfile); +static void objfile_free_data (struct objfile *objfile); /* Externally visible variables that are owned by this module. See declarations in objfile.h for more info. */ @@ -63,8 +59,6 @@ struct objfile *current_objfile; /* For symbol file being read in */ struct objfile *symfile_objfile; /* Main symbol table loaded from */ struct objfile *rt_common_objfile; /* For runtime common symbols */ -int mapped_symbol_files; /* Try to use mapped symbol files */ - /* Locate all mappable sections of a BFD file. objfile_p_char is a char * to get it through bfd_map_over_sections; we cast it back to its proper type. */ @@ -79,7 +73,8 @@ int mapped_symbol_files; /* Try to use mapped symbol files */ the end of the table (objfile->sections_end). */ static void -add_to_objfile_sections (bfd *abfd, sec_ptr asect, PTR objfile_p_char) +add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect, + void *objfile_p_char) { struct objfile *objfile = (struct objfile *) objfile_p_char; struct obj_section section; @@ -98,7 +93,7 @@ add_to_objfile_sections (bfd *abfd, sec_ptr asect, PTR objfile_p_char) section.ovly_mapped = 0; section.addr = bfd_section_vma (abfd, asect); section.endaddr = section.addr + bfd_section_size (abfd, asect); - obstack_grow (&objfile->psymbol_obstack, (char *) §ion, sizeof (section)); + obstack_grow (&objfile->objfile_obstack, (char *) §ion, sizeof (section)); objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1); } @@ -124,13 +119,13 @@ build_objfile_section_table (struct objfile *objfile) /* objfile->sections can be already set when reading a mapped symbol file. I believe that we do need to rebuild the section table in this case (we rebuild other things derived from the bfd), but we - can't free the old one (it's in the psymbol_obstack). So we just + can't free the old one (it's in the objfile_obstack). So we just waste some memory. */ objfile->sections_end = 0; bfd_map_over_sections (objfile->obfd, add_to_objfile_sections, (char *) objfile); objfile->sections = (struct obj_section *) - obstack_finish (&objfile->psymbol_obstack); + obstack_finish (&objfile->objfile_obstack); objfile->sections_end = objfile->sections + (unsigned long) objfile->sections_end; return (0); } @@ -141,10 +136,17 @@ build_objfile_section_table (struct objfile *objfile) new objfile struct. The FLAGS word contains various bits (OBJF_*) that can be taken as - requests for specific operations, like trying to open a mapped - version of the objfile (OBJF_MAPPED). Other bits like - OBJF_SHARED are simply copied through to the new objfile flags - member. */ + requests for specific operations. Other bits like OBJF_SHARED are + simply copied through to the new objfile flags member. */ + +/* NOTE: carlton/2003-02-04: This function is called with args NULL, 0 + by jv-lang.c, to create an artificial objfile used to hold + information about dynamically-loaded Java classes. Unfortunately, + that branch of this function doesn't get tested very frequently, so + it's prone to breakage. (E.g. at one time the name was set to NULL + in that situation, which broke a loop over all names in the dynamic + library loader.) If you change this function, please try to leave + things in a consistent state even if abfd is NULL. */ struct objfile * allocate_objfile (bfd *abfd, int flags) @@ -152,109 +154,6 @@ allocate_objfile (bfd *abfd, int flags) struct objfile *objfile = NULL; struct objfile *last_one = NULL; - if (mapped_symbol_files) - flags |= OBJF_MAPPED; - -#if defined(USE_MMALLOC) && defined(HAVE_MMAP) - if (abfd != NULL) - { - - /* If we can support mapped symbol files, try to open/reopen the - mapped file that corresponds to the file from which we wish to - read symbols. If the objfile is to be mapped, we must malloc - the structure itself using the mmap version, and arrange that - all memory allocation for the objfile uses the mmap routines. - If we are reusing an existing mapped file, from which we get - our objfile pointer, we have to make sure that we update the - pointers to the alloc/free functions in the obstack, in case - these functions have moved within the current gdb. */ - - int fd; - - fd = open_mapped_file (bfd_get_filename (abfd), bfd_get_mtime (abfd), - flags); - if (fd >= 0) - { - PTR md; - - if ((md = map_to_file (fd)) == NULL) - { - close (fd); - } - else if ((objfile = (struct objfile *) mmalloc_getkey (md, 0)) != NULL) - { - /* Update memory corruption handler function addresses. */ - init_malloc (md); - objfile->md = md; - objfile->mmfd = fd; - /* Update pointers to functions to *our* copies */ - obstack_chunkfun (&objfile->psymbol_cache.cache, xmmalloc); - obstack_freefun (&objfile->psymbol_cache.cache, xmfree); - obstack_chunkfun (&objfile->psymbol_obstack, xmmalloc); - obstack_freefun (&objfile->psymbol_obstack, xmfree); - obstack_chunkfun (&objfile->symbol_obstack, xmmalloc); - obstack_freefun (&objfile->symbol_obstack, xmfree); - obstack_chunkfun (&objfile->type_obstack, xmmalloc); - obstack_freefun (&objfile->type_obstack, xmfree); - /* If already in objfile list, unlink it. */ - unlink_objfile (objfile); - /* Forget things specific to a particular gdb, may have changed. */ - objfile->sf = NULL; - } - else - { - - /* Set up to detect internal memory corruption. MUST be - done before the first malloc. See comments in - init_malloc() and mmcheck(). */ - - init_malloc (md); - - objfile = (struct objfile *) - xmmalloc (md, sizeof (struct objfile)); - memset (objfile, 0, sizeof (struct objfile)); - objfile->md = md; - objfile->mmfd = fd; - objfile->flags |= OBJF_MAPPED; - mmalloc_setkey (objfile->md, 0, objfile); - obstack_specify_allocation_with_arg (&objfile->psymbol_cache.cache, - 0, 0, xmmalloc, xmfree, - objfile->md); - obstack_specify_allocation_with_arg (&objfile->psymbol_obstack, - 0, 0, xmmalloc, xmfree, - objfile->md); - obstack_specify_allocation_with_arg (&objfile->symbol_obstack, - 0, 0, xmmalloc, xmfree, - objfile->md); - obstack_specify_allocation_with_arg (&objfile->type_obstack, - 0, 0, xmmalloc, xmfree, - objfile->md); - } - } - - if ((flags & OBJF_MAPPED) && (objfile == NULL)) - { - warning ("symbol table for '%s' will not be mapped", - bfd_get_filename (abfd)); - flags &= ~OBJF_MAPPED; - } - } -#else /* !defined(USE_MMALLOC) || !defined(HAVE_MMAP) */ - - if (flags & OBJF_MAPPED) - { - warning ("mapped symbol tables are not supported on this machine; missing or broken mmap()."); - - /* Turn off the global flag so we don't try to do mapped symbol tables - any more, which shuts up gdb unless the user specifically gives the - "mapped" keyword again. */ - - mapped_symbol_files = 0; - flags &= ~OBJF_MAPPED; - } - -#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */ - /* If we don't support mapped symbol files, didn't ask for the file to be mapped, or failed to open the mapped file for some reason, then revert back to an unmapped objfile. */ @@ -264,17 +163,16 @@ allocate_objfile (bfd *abfd, int flags) objfile = (struct objfile *) xmalloc (sizeof (struct objfile)); memset (objfile, 0, sizeof (struct objfile)); objfile->md = NULL; - obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0, - xmalloc, xfree); - obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc, - xfree); - obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc, - xfree); - obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc, - xfree); - flags &= ~OBJF_MAPPED; + objfile->psymbol_cache = bcache_xmalloc (); + objfile->macro_cache = bcache_xmalloc (); + /* We could use obstack_specify_allocation here instead, but + gdb_obstack.h specifies the alloc/dealloc functions. */ + obstack_init (&objfile->objfile_obstack); + terminate_minimal_symbol_table (objfile); } + objfile_alloc_data (objfile); + /* Update the per-objfile information that comes from the bfd, ensuring that any data that is reference is saved in the per-objfile data region. */ @@ -297,14 +195,22 @@ allocate_objfile (bfd *abfd, int flags) objfile->name, bfd_errmsg (bfd_get_error ())); } } + else + { + objfile->name = mstrsave (objfile->md, "<>"); + } /* Initialize the section indexes for this objfile, so that we can later detect if they are used w/o being properly assigned to. */ - objfile->sect_index_text = -1; - objfile->sect_index_data = -1; - objfile->sect_index_bss = -1; - objfile->sect_index_rodata = -1; + objfile->sect_index_text = -1; + objfile->sect_index_data = -1; + objfile->sect_index_bss = -1; + objfile->sect_index_rodata = -1; + + /* We don't yet have a C++-specific namespace symtab. */ + + objfile->cp_namespace_symtab = NULL; /* Add this file onto the tail of the linked list of other such files. */ @@ -325,6 +231,89 @@ allocate_objfile (bfd *abfd, int flags) return (objfile); } +/* Initialize entry point information for this objfile. */ + +void +init_entry_point_info (struct objfile *objfile) +{ + /* Save startup file's range of PC addresses to help blockframe.c + decide where the bottom of the stack is. */ + + if (bfd_get_file_flags (objfile->obfd) & EXEC_P) + { + /* Executable file -- record its entry point so we'll recognize + the startup file because it contains the entry point. */ + objfile->ei.entry_point = bfd_get_start_address (objfile->obfd); + } + else + { + /* Examination of non-executable.o files. Short-circuit this stuff. */ + objfile->ei.entry_point = INVALID_ENTRY_POINT; + } + objfile->ei.deprecated_entry_file_lowpc = INVALID_ENTRY_LOWPC; + objfile->ei.deprecated_entry_file_highpc = INVALID_ENTRY_HIGHPC; + objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC; + objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC; + objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC; + objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC; +} + +/* Get current entry point address. */ + +CORE_ADDR +entry_point_address (void) +{ + return symfile_objfile ? symfile_objfile->ei.entry_point : 0; +} + +/* Create the terminating entry of OBJFILE's minimal symbol table. + If OBJFILE->msymbols is zero, allocate a single entry from + OBJFILE->objfile_obstack; otherwise, just initialize + OBJFILE->msymbols[OBJFILE->minimal_symbol_count]. */ +void +terminate_minimal_symbol_table (struct objfile *objfile) +{ + if (! objfile->msymbols) + objfile->msymbols = ((struct minimal_symbol *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (objfile->msymbols[0]))); + + { + struct minimal_symbol *m + = &objfile->msymbols[objfile->minimal_symbol_count]; + + memset (m, 0, sizeof (*m)); + /* Don't rely on these enumeration values being 0's. */ + MSYMBOL_TYPE (m) = mst_unknown; + SYMBOL_INIT_LANGUAGE_SPECIFIC (m, language_unknown); + } +} + + +/* Put one object file before a specified on in the global list. + This can be used to make sure an object file is destroyed before + another when using ALL_OBJFILES_SAFE to free all objfiles. */ +void +put_objfile_before (struct objfile *objfile, struct objfile *before_this) +{ + struct objfile **objp; + + unlink_objfile (objfile); + + for (objp = &object_files; *objp != NULL; objp = &((*objp)->next)) + { + if (*objp == before_this) + { + objfile->next = *objp; + *objp = objfile; + return; + } + } + + internal_error (__FILE__, __LINE__, + "put_objfile_before: before objfile not in list"); +} + /* Put OBJFILE at the front of the list. */ void @@ -379,8 +368,8 @@ unlink_objfile (struct objfile *objfile) /* Destroy an objfile and all the symtabs and psymtabs under it. Note - that as much as possible is allocated on the symbol_obstack and - psymbol_obstack, so that the memory can be efficiently freed. + that as much as possible is allocated on the objfile_obstack + so that the memory can be efficiently freed. Things which we do NOT free because they are not in malloc'd memory or not in memory specific to the objfile include: @@ -397,6 +386,18 @@ unlink_objfile (struct objfile *objfile) void free_objfile (struct objfile *objfile) { + if (objfile->separate_debug_objfile) + { + free_objfile (objfile->separate_debug_objfile); + } + + if (objfile->separate_debug_objfile_backlink) + { + /* We freed the separate debug file, make sure the base objfile + doesn't reference it. */ + objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL; + } + /* First do any symbol file specific actions required when we are finished with a particular symbol file. Note that if the objfile is using reusable symbol information (via mmalloc) then each of @@ -441,48 +442,25 @@ free_objfile (struct objfile *objfile) to call this here. */ clear_pc_function_cache (); - /* The last thing we do is free the objfile struct itself for the - non-reusable case, or detach from the mapped file for the - reusable case. Note that the mmalloc_detach or the xmfree() is - the last thing we can do with this objfile. */ + /* The last thing we do is free the objfile struct itself. */ -#if defined(USE_MMALLOC) && defined(HAVE_MMAP) - - if (objfile->flags & OBJF_MAPPED) + objfile_free_data (objfile); + if (objfile->name != NULL) { - /* Remember the fd so we can close it. We can't close it before - doing the detach, and after the detach the objfile is gone. */ - int mmfd; - - mmfd = objfile->mmfd; - mmalloc_detach (objfile->md); - objfile = NULL; - close (mmfd); - } - -#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */ - - /* If we still have an objfile, then either we don't support reusable - objfiles or this one was not reusable. So free it normally. */ - - if (objfile != NULL) - { - if (objfile->name != NULL) - { - xmfree (objfile->md, objfile->name); - } - if (objfile->global_psymbols.list) - xmfree (objfile->md, objfile->global_psymbols.list); - if (objfile->static_psymbols.list) - xmfree (objfile->md, objfile->static_psymbols.list); - /* Free the obstacks for non-reusable objfiles */ - free_bcache (&objfile->psymbol_cache); - obstack_free (&objfile->psymbol_obstack, 0); - obstack_free (&objfile->symbol_obstack, 0); - obstack_free (&objfile->type_obstack, 0); - xmfree (objfile->md, objfile); - objfile = NULL; + xmfree (objfile->md, objfile->name); } + if (objfile->global_psymbols.list) + xmfree (objfile->md, objfile->global_psymbols.list); + if (objfile->static_psymbols.list) + xmfree (objfile->md, objfile->static_psymbols.list); + /* Free the obstacks for non-reusable objfiles */ + bcache_xfree (objfile->psymbol_cache); + bcache_xfree (objfile->macro_cache); + if (objfile->demangled_names_hash) + htab_delete (objfile->demangled_names_hash); + obstack_free (&objfile->objfile_obstack, 0); + xmfree (objfile->md, objfile); + objfile = NULL; } static void @@ -517,7 +495,8 @@ void objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) { struct section_offsets *delta = - (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS); + ((struct section_offsets *) + alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections))); { int i; @@ -560,18 +539,18 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) { struct block *b; struct symbol *sym; - int j; + struct dict_iterator iter; b = BLOCKVECTOR_BLOCK (bv, i); BLOCK_START (b) += ANOFFSET (delta, s->block_line_section); BLOCK_END (b) += ANOFFSET (delta, s->block_line_section); - ALL_BLOCK_SYMBOLS (b, j, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { fixup_symbol_section (sym, objfile); /* The RS6000 code from which this was taken skipped - any symbols in STRUCT_NAMESPACE or UNDEF_NAMESPACE. + any symbols in STRUCT_DOMAIN or UNDEF_DOMAIN. But I'm leaving out that test, on the theory that they can't possibly pass the tests below. */ if ((SYMBOL_CLASS (sym) == LOC_LABEL @@ -586,8 +565,8 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) /* Relocate Extra Function Info for ecoff. */ else if (SYMBOL_CLASS (sym) == LOC_CONST - && SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE - && strcmp (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0) + && SYMBOL_DOMAIN (sym) == LABEL_DOMAIN + && strcmp (DEPRECATED_SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0) ecoff_relocate_efi (sym, ANOFFSET (delta, s->block_line_section)); #endif @@ -678,10 +657,10 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile)); } - if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC) + if (objfile->ei.deprecated_entry_file_lowpc != INVALID_ENTRY_LOWPC) { - objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile)); - objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile)); + objfile->ei.deprecated_entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile)); + objfile->ei.deprecated_entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile)); } if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC) @@ -765,7 +744,7 @@ have_minimal_symbols (void) ALL_OBJFILES (ofp) { - if (ofp->msymbols != NULL) + if (ofp->minimal_symbol_count > 0) { return 1; } @@ -773,176 +752,14 @@ have_minimal_symbols (void) return 0; } -#if defined(USE_MMALLOC) && defined(HAVE_MMAP) - -/* Given the name of a mapped symbol file in SYMSFILENAME, and the timestamp - of the corresponding symbol file in MTIME, try to open an existing file - with the name SYMSFILENAME and verify it is more recent than the base - file by checking it's timestamp against MTIME. - - If SYMSFILENAME does not exist (or can't be stat'd), simply returns -1. - - If SYMSFILENAME does exist, but is out of date, we check to see if the - user has specified creation of a mapped file. If so, we don't issue - any warning message because we will be creating a new mapped file anyway, - overwriting the old one. If not, then we issue a warning message so that - the user will know why we aren't using this existing mapped symbol file. - In either case, we return -1. - - If SYMSFILENAME does exist and is not out of date, but can't be opened for - some reason, then prints an appropriate system error message and returns -1. - - Otherwise, returns the open file descriptor. */ - -static int -open_existing_mapped_file (char *symsfilename, long mtime, int flags) -{ - int fd = -1; - struct stat sbuf; - - if (stat (symsfilename, &sbuf) == 0) - { - if (sbuf.st_mtime < mtime) - { - if (!(flags & OBJF_MAPPED)) - { - warning ("mapped symbol file `%s' is out of date, ignored it", - symsfilename); - } - } - else if ((fd = open (symsfilename, O_RDWR)) < 0) - { - if (error_pre_print) - { - printf_unfiltered (error_pre_print); - } - print_sys_errmsg (symsfilename, errno); - } - } - return (fd); -} - -/* Look for a mapped symbol file that corresponds to FILENAME and is more - recent than MTIME. If MAPPED is nonzero, the user has asked that gdb - use a mapped symbol file for this file, so create a new one if one does - not currently exist. - - If found, then return an open file descriptor for the file, otherwise - return -1. - - This routine is responsible for implementing the policy that generates - the name of the mapped symbol file from the name of a file containing - symbols that gdb would like to read. Currently this policy is to append - ".syms" to the name of the file. - - This routine is also responsible for implementing the policy that - determines where the mapped symbol file is found (the search path). - This policy is that when reading an existing mapped file, a file of - the correct name in the current directory takes precedence over a - file of the correct name in the same directory as the symbol file. - When creating a new mapped file, it is always created in the current - directory. This helps to minimize the chances of a user unknowingly - creating big mapped files in places like /bin and /usr/local/bin, and - allows a local copy to override a manually installed global copy (in - /bin for example). */ - -static int -open_mapped_file (char *filename, long mtime, int flags) -{ - int fd; - char *symsfilename; - - /* First try to open an existing file in the current directory, and - then try the directory where the symbol file is located. */ - - symsfilename = concat ("./", lbasename (filename), ".syms", (char *) NULL); - if ((fd = open_existing_mapped_file (symsfilename, mtime, flags)) < 0) - { - xfree (symsfilename); - symsfilename = concat (filename, ".syms", (char *) NULL); - fd = open_existing_mapped_file (symsfilename, mtime, flags); - } - - /* If we don't have an open file by now, then either the file does not - already exist, or the base file has changed since it was created. In - either case, if the user has specified use of a mapped file, then - create a new mapped file, truncating any existing one. If we can't - create one, print a system error message saying why we can't. - - By default the file is rw for everyone, with the user's umask taking - care of turning off the permissions the user wants off. */ - - if ((fd < 0) && (flags & OBJF_MAPPED)) - { - xfree (symsfilename); - symsfilename = concat ("./", lbasename (filename), ".syms", - (char *) NULL); - if ((fd = open (symsfilename, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) - { - if (error_pre_print) - { - printf_unfiltered (error_pre_print); - } - print_sys_errmsg (symsfilename, errno); - } - } - - xfree (symsfilename); - return (fd); -} - -static PTR -map_to_file (int fd) -{ - PTR md; - CORE_ADDR mapto; - - md = mmalloc_attach (fd, (PTR) 0); - if (md != NULL) - { - mapto = (CORE_ADDR) mmalloc_getkey (md, 1); - md = mmalloc_detach (md); - if (md != NULL) - { - /* FIXME: should figure out why detach failed */ - md = NULL; - } - else if (mapto != (CORE_ADDR) NULL) - { - /* This mapping file needs to be remapped at "mapto" */ - md = mmalloc_attach (fd, (PTR) mapto); - } - else - { - /* This is a freshly created mapping file. */ - mapto = (CORE_ADDR) mmalloc_findbase (20 * 1024 * 1024); - if (mapto != 0) - { - /* To avoid reusing the freshly created mapping file, at the - address selected by mmap, we must truncate it before trying - to do an attach at the address we want. */ - ftruncate (fd, 0); - md = mmalloc_attach (fd, (PTR) mapto); - if (md != NULL) - { - mmalloc_setkey (md, 1, (PTR) mapto); - } - } - } - } - return (md); -} - -#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */ - -/* Returns a section whose range includes PC and SECTION, - or NULL if none found. Note the distinction between the return type, - struct obj_section (which is defined in gdb), and the input type - struct sec (which is a bfd-defined data type). The obj_section - contains a pointer to the bfd struct sec section. */ +/* Returns a section whose range includes PC and SECTION, or NULL if + none found. Note the distinction between the return type, struct + obj_section (which is defined in gdb), and the input type "struct + bfd_section" (which is a bfd-defined data type). The obj_section + contains a pointer to the "struct bfd_section". */ struct obj_section * -find_pc_sect_section (CORE_ADDR pc, struct sec *section) +find_pc_sect_section (CORE_ADDR pc, struct bfd_section *section) { struct obj_section *s; struct objfile *objfile; @@ -979,7 +796,7 @@ in_plt_section (CORE_ADDR pc, char *name) retval = (s != NULL && s->the_bfd_section->name != NULL - && STREQ (s->the_bfd_section->name, ".plt")); + && strcmp (s->the_bfd_section->name, ".plt") == 0); return (retval); } @@ -989,14 +806,91 @@ in_plt_section (CORE_ADDR pc, char *name) int is_in_import_list (char *name, struct objfile *objfile) { - register int i; + int i; if (!objfile || !name || !*name) return 0; for (i = 0; i < objfile->import_list_size; i++) - if (objfile->import_list[i] && STREQ (name, objfile->import_list[i])) + if (objfile->import_list[i] && DEPRECATED_STREQ (name, objfile->import_list[i])) return 1; return 0; } + +/* Keep a registry of per-objfile data-pointers required by other GDB + modules. */ + +struct objfile_data +{ + unsigned index; +}; + +struct objfile_data_registration +{ + struct objfile_data *data; + struct objfile_data_registration *next; +}; + +struct objfile_data_registry +{ + struct objfile_data_registration *registrations; + unsigned num_registrations; +}; + +static struct objfile_data_registry objfile_data_registry = { NULL, 0 }; + +const struct objfile_data * +register_objfile_data (void) +{ + struct objfile_data_registration **curr; + + /* Append new registration. */ + for (curr = &objfile_data_registry.registrations; + *curr != NULL; curr = &(*curr)->next); + + *curr = XMALLOC (struct objfile_data_registration); + (*curr)->next = NULL; + (*curr)->data = XMALLOC (struct objfile_data); + (*curr)->data->index = objfile_data_registry.num_registrations++; + + return (*curr)->data; +} + +static void +objfile_alloc_data (struct objfile *objfile) +{ + gdb_assert (objfile->data == NULL); + objfile->num_data = objfile_data_registry.num_registrations; + objfile->data = XCALLOC (objfile->num_data, void *); +} + +static void +objfile_free_data (struct objfile *objfile) +{ + gdb_assert (objfile->data != NULL); + xfree (objfile->data); + objfile->data = NULL; +} + +void +clear_objfile_data (struct objfile *objfile) +{ + gdb_assert (objfile->data != NULL); + memset (objfile->data, 0, objfile->num_data * sizeof (void *)); +} + +void +set_objfile_data (struct objfile *objfile, const struct objfile_data *data, + void *value) +{ + gdb_assert (data->index < objfile->num_data); + objfile->data[data->index] = value; +} + +void * +objfile_data (struct objfile *objfile, const struct objfile_data *data) +{ + gdb_assert (data->index < objfile->num_data); + return objfile->data[data->index]; +} diff --git a/contrib/gdb/gdb/objfiles.h b/contrib/gdb/gdb/objfiles.h index d1746a970ac..2b8ca7d350f 100644 --- a/contrib/gdb/gdb/objfiles.h +++ b/contrib/gdb/gdb/objfiles.h @@ -1,6 +1,7 @@ /* Definitions for symbol file management in GDB. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -22,7 +23,13 @@ #if !defined (OBJFILES_H) #define OBJFILES_H -#include "bcache.h" +#include "gdb_obstack.h" /* For obstack internals. */ +#include "symfile.h" /* For struct psymbol_allocation_list */ + +struct bcache; +struct htab; +struct symtab; +struct objfile_data; /* This structure maintains information on a per-objfile basis about the "entry point" of the objfile, and the scope within which the entry point @@ -37,14 +44,28 @@ to the user executable's recorded entry point, as if the call had been made directly by the kernel. - The traditional gdb method of using this info is to use the recorded entry - point to set the variables entry_file_lowpc and entry_file_highpc from - the debugging information, where these values are the starting address - (inclusive) and ending address (exclusive) of the instruction space in the - executable which correspond to the "startup file", I.E. crt0.o in most - cases. This file is assumed to be a startup file and frames with pc's - inside it are treated as nonexistent. Setting these variables is necessary - so that backtraces do not fly off the bottom of the stack. + The traditional gdb method of using this info is to use the + recorded entry point to set the variables + deprecated_entry_file_lowpc and deprecated_entry_file_highpc from + the debugging information, where these values are the starting + address (inclusive) and ending address (exclusive) of the + instruction space in the executable which correspond to the + "startup file", I.E. crt0.o in most cases. This file is assumed to + be a startup file and frames with pc's inside it are treated as + nonexistent. Setting these variables is necessary so that + backtraces do not fly off the bottom of the stack. + + NOTE: cagney/2003-09-09: It turns out that this "traditional" + method doesn't work. Corinna writes: ``It turns out that the call + to deprecated_inside_entry_file destroys a meaningful backtrace + under some conditions. E. g. the backtrace tests in the asm-source + testcase are broken for some targets. In this test the functions + are all implemented as part of one file and the testcase is not + necessarily linked with a start file (depending on the target). + What happens is, that the first frame is printed normaly and + following frames are treated as being inside the enttry file then. + This way, only the #0 frame is printed in the backtrace output.'' + Ref "frame.c" "NOTE: vinschen/2003-04-01". Gdb also supports an alternate method to avoid running off the bottom of the stack. @@ -60,14 +81,15 @@ confused. However, we almost always have debugging information available for main(). - These variables are used to save the range of PC values which are valid - within the main() function and within the function containing the process - entry point. If we always consider the frame for main() as the outermost - frame when debugging user code, and the frame for the process entry - point function as the outermost frame when debugging startup code, then - all we have to do is have FRAME_CHAIN_VALID return false whenever a - frame's current PC is within the range specified by these variables. - In essence, we set "ceilings" in the frame chain beyond which we will + These variables are used to save the range of PC values which are + valid within the main() function and within the function containing + the process entry point. If we always consider the frame for + main() as the outermost frame when debugging user code, and the + frame for the process entry point function as the outermost frame + when debugging startup code, then all we have to do is have + DEPRECATED_FRAME_CHAIN_VALID return false whenever a frame's + current PC is within the range specified by these variables. In + essence, we set "ceilings" in the frame chain beyond which we will not proceed when following the frame chain back up the stack. A nice side effect is that we can still debug startup code without @@ -76,17 +98,7 @@ use the block at main, or can't find it for some reason, everything still works as before. And if we have no startup code debugging information but we do have usable information for main(), backtraces - from user code don't go wandering off into the startup code. - - To use this method, define your FRAME_CHAIN_VALID macro like: - - #define FRAME_CHAIN_VALID(chain, thisframe) \ - (chain != 0 \ - && !(inside_main_func ((thisframe)->pc)) \ - && !(inside_entry_func ((thisframe)->pc))) - - and add initializations of the four scope controlling variables inside - the object file / debugging information processing modules. */ + from user code don't go wandering off into the startup code. */ struct entry_info { @@ -108,8 +120,8 @@ struct entry_info /* Start (inclusive) and end (exclusive) of object file containing the entry point. */ - CORE_ADDR entry_file_lowpc; - CORE_ADDR entry_file_highpc; + CORE_ADDR deprecated_entry_file_lowpc; + CORE_ADDR deprecated_entry_file_highpc; /* Start (inclusive) and end (exclusive) of the user code main() function. */ @@ -155,7 +167,7 @@ struct obj_section addresses. */ CORE_ADDR offset; - sec_ptr the_bfd_section; /* BFD section pointer */ + struct bfd_section *the_bfd_section; /* BFD section pointer */ /* Objfile this section is part of. */ struct objfile *objfile; @@ -234,7 +246,8 @@ struct objfile struct objfile *next; - /* The object file's name. Malloc'd; free it if you free this struct. */ + /* The object file's name, tilde-expanded and absolute. + Malloc'd; free it if you free this struct. */ char *name; @@ -268,20 +281,26 @@ struct objfile long mtime; - /* Obstacks to hold objects that should be freed when we load a new symbol + /* Obstack to hold objects that should be freed when we load a new symbol table from this object file. */ - struct obstack psymbol_obstack; /* Partial symbols */ - struct obstack symbol_obstack; /* Full symbols */ - struct obstack type_obstack; /* Types */ + struct obstack objfile_obstack; /* A byte cache where we can stash arbitrary "chunks" of bytes that will not change. */ - struct bcache psymbol_cache; /* Byte cache for partial syms */ + struct bcache *psymbol_cache; /* Byte cache for partial syms */ + struct bcache *macro_cache; /* Byte cache for macros */ + + /* Hash table for mapping symbol names to demangled names. Each + entry in the hash table is actually two consecutive strings, + both null-terminated; the first one is a mangled or linkage + name, and the second is the demangled name or just a zero byte + if the name doesn't demangle. */ + struct htab *demangled_names_hash; /* Vectors of all partial symbols read in from file. The actual data - is stored in the psymbol_obstack. */ + is stored in the objfile_obstack. */ struct psymbol_allocation_list global_psymbols; struct psymbol_allocation_list static_psymbols; @@ -293,7 +312,7 @@ struct objfile when passed a pointer to somewhere in the middle of it. There is also a count of the number of symbols, which does not include the terminating null symbol. The array itself, as well as all the data that it points - to, should be allocated on the symbol_obstack for this file. */ + to, should be allocated on the objfile_obstack for this file. */ struct minimal_symbol *msymbols; int minimal_symbol_count; @@ -323,7 +342,7 @@ struct objfile the memory mapped malloc() package to manage storage for this objfile's data. NULL if we are not. */ - PTR md; + void *md; /* The file descriptor that was used to obtain the mmalloc descriptor for this objfile. If we call mmalloc_detach with the malloc descriptor @@ -354,17 +373,24 @@ struct objfile typically a pointer to malloc'd memory. The symbol reader's finish function is responsible for freeing the memory thusly allocated. */ - PTR sym_private; + void *sym_private; /* Hook for target-architecture-specific information. This must point to memory allocated on one of the obstacks in this objfile, so that it gets freed automatically when reading a new object file. */ - PTR obj_private; + void *obj_private; + + /* Per objfile data-pointers required by other GDB modules. */ + /* FIXME: kettenis/20030711: This mechanism could replace + sym_stab_info, sym_private and obj_private entirely. */ + + void **data; + unsigned num_data; /* Set of relocation offsets to apply to each section. - Currently on the psymbol_obstack (which makes no sense, but I'm + Currently on the objfile_obstack (which makes no sense, but I'm not sure it's harming anything). These offsets indicate that all symbols (including partial and @@ -392,38 +418,46 @@ struct objfile SECTIONS points to the first entry in the table, and SECTIONS_END points to the first location past the last entry in the table. Currently the table is stored on the - psymbol_obstack (which makes no sense, but I'm not sure it's + objfile_obstack (which makes no sense, but I'm not sure it's harming anything). */ struct obj_section *sections, *sections_end; - /* two auxiliary fields, used to hold the fp of separate symbol files */ - FILE *auxf1, *auxf2; - /* Imported symbols */ + /* FIXME: ezannoni 2004-02-10: This is just SOM (HP) specific (see + somread.c). It should not pollute generic objfiles. */ ImportEntry *import_list; int import_list_size; /* Exported symbols */ + /* FIXME: ezannoni 2004-02-10: This is just SOM (HP) specific (see + somread.c). It should not pollute generic objfiles. */ ExportEntry *export_list; int export_list_size; + /* Link to objfile that contains the debug symbols for this one. + One is loaded if this file has an debug link to an existing + debug file with the right checksum */ + struct objfile *separate_debug_objfile; + + /* If this is a separate debug object, this is used as a link to the + actual executable objfile. */ + struct objfile *separate_debug_objfile_backlink; + /* Place to stash various statistics about this objfile */ OBJSTATS; + + /* A symtab that the C++ code uses to stash special symbols + associated to namespaces. */ + + /* FIXME/carlton-2003-06-27: Delete this in a few years once + "possible namespace symbols" go away. */ + struct symtab *cp_namespace_symtab; }; /* Defines for the objfile flag word. */ -/* Gdb can arrange to allocate storage for all objects related to a - particular objfile in a designated section of its address space, - managed at a low level by mmap() and using a special version of - malloc that handles malloc/free/realloc on top of the mmap() interface. - This allows the "internal gdb state" for a particular objfile to be - dumped to a gdb state file and subsequently reloaded at a later time. */ - -#define OBJF_MAPPED (1 << 0) /* Objfile data is mmap'd */ - /* When using mapped/remapped predigested gdb symbol information, we need a flag that indicates that we have previously done an initial symbol table read from this particular objfile. We can't just look for the @@ -474,7 +508,7 @@ extern struct objfile *symfile_objfile; extern struct objfile *rt_common_objfile; -/* When we need to allocate a new type, we need to know which type_obstack +/* When we need to allocate a new type, we need to know which objfile_obstack to allocate the type on, since there is one for each objfile. The places where types are allocated are deeply buried in function call hierarchies which know nothing about objfiles, so rather than trying to pass a @@ -498,8 +532,16 @@ extern struct objfile *object_files; extern struct objfile *allocate_objfile (bfd *, int); +extern void init_entry_point_info (struct objfile *); + +extern CORE_ADDR entry_point_address (void); + extern int build_objfile_section_table (struct objfile *); +extern void terminate_minimal_symbol_table (struct objfile *objfile); + +extern void put_objfile_before (struct objfile *, struct objfile *); + extern void objfile_to_front (struct objfile *); extern void unlink_objfile (struct objfile *); @@ -536,6 +578,17 @@ extern int in_plt_section (CORE_ADDR, char *); extern int is_in_import_list (char *, struct objfile *); +/* Keep a registry of per-objfile data-pointers required by other GDB + modules. */ + +extern const struct objfile_data *register_objfile_data (void); +extern void clear_objfile_data (struct objfile *objfile); +extern void set_objfile_data (struct objfile *objfile, + const struct objfile_data *data, void *value); +extern void *objfile_data (struct objfile *objfile, + const struct objfile_data *data); + + /* Traverse all object files. ALL_OBJFILES_SAFE works even if you delete the objfile during the traversal. */ @@ -560,7 +613,7 @@ extern int is_in_import_list (char *, struct objfile *); /* Traverse all minimal symbols in one objfile. */ #define ALL_OBJFILE_MSYMBOLS(objfile, m) \ - for ((m) = (objfile) -> msymbols; SYMBOL_NAME(m) != NULL; (m)++) + for ((m) = (objfile) -> msymbols; DEPRECATED_SYMBOL_NAME(m) != NULL; (m)++) /* Traverse all symtabs in all objfiles. */ @@ -578,8 +631,7 @@ extern int is_in_import_list (char *, struct objfile *); #define ALL_MSYMBOLS(objfile, m) \ ALL_OBJFILES (objfile) \ - if ((objfile)->msymbols) \ - ALL_OBJFILE_MSYMBOLS (objfile, m) + ALL_OBJFILE_MSYMBOLS (objfile, m) #define ALL_OBJFILE_OSECTIONS(objfile, osect) \ for (osect = objfile->sections; osect < objfile->sections_end; osect++) diff --git a/contrib/gdb/gdb/observer.c b/contrib/gdb/gdb/observer.c new file mode 100644 index 00000000000..fce5f9287d8 --- /dev/null +++ b/contrib/gdb/gdb/observer.c @@ -0,0 +1,222 @@ +/* GDB Notifications to Observers. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* An observer is an entity who is interested in being notified when GDB + reaches certain states, or certain events occur in GDB. The entity being + observed is called the Subject. To receive notifications, the observer + attaches a callback to the subject. One subject can have several + observers. + + This file implements an internal generic low-level event notification + mechanism based on the Observer paradigm described in the book "Design + Patterns". This generic event notification mechansim is then re-used + to implement the exported high-level notification management routines + for all possible notifications. + + The current implementation of the generic observer provides support + for contextual data. This contextual data is given to the subject + when attaching the callback. In return, the subject will provide + this contextual data back to the observer as a parameter of the + callback. + + FIXME: The current support for the contextual data is only partial, + as it lacks a mechanism that would deallocate this data when the + callback is detached. This is not a problem so far, as this contextual + data is only used internally to hold a function pointer. Later on, + if a certain observer needs to provide support for user-level + contextual data, then the generic notification mechanism will need + need to be enhanced to allow the observer to provide a routine to + deallocate the data when attaching the callback. + + This file is currently maintained by hand, but the long term plan + if the number of different notifications starts growing is to create + a new script (observer.sh) that would generate this file, and the + associated documentation. */ + +#include "defs.h" +#include "observer.h" + +/* The internal generic observer. */ + +typedef void (generic_observer_notification_ftype) (const void *data, + const void *args); + +struct observer +{ + generic_observer_notification_ftype *notify; + /* No memory management needed for the following field for now. */ + void *data; +}; + +/* A list of observers, maintained by the subject. A subject is + actually represented by its list of observers. */ + +struct observer_list +{ + struct observer_list *next; + struct observer *observer; +}; + +/* Allocate a struct observer_list, intended to be used as a node + in the list of observers maintained by a subject. */ + +static struct observer_list * +xalloc_observer_list_node (void) +{ + struct observer_list *node = XMALLOC (struct observer_list); + node->observer = XMALLOC (struct observer); + return node; +} + +/* The opposite of xalloc_observer_list_node, frees the memory for + the given node. */ + +static void +xfree_observer_list_node (struct observer_list *node) +{ + xfree (node->observer); + xfree (node); +} + +/* Attach the callback NOTIFY to a SUBJECT. The DATA is also stored, + in order for the subject to provide it back to the observer during + a notification. */ + +static struct observer * +generic_observer_attach (struct observer_list **subject, + generic_observer_notification_ftype * notify, + void *data) +{ + struct observer_list *observer_list = xalloc_observer_list_node (); + + observer_list->next = *subject; + observer_list->observer->notify = notify; + observer_list->observer->data = data; + *subject = observer_list; + + return observer_list->observer; +} + +/* Remove the given OBSERVER from the SUBJECT. Once detached, OBSERVER + should no longer be used, as it is no longer valid. */ + +static void +generic_observer_detach (struct observer_list **subject, + const struct observer *observer) +{ + struct observer_list *previous_node = NULL; + struct observer_list *current_node = *subject; + + while (current_node != NULL) + { + if (current_node->observer == observer) + { + if (previous_node != NULL) + previous_node->next = current_node->next; + else + *subject = current_node->next; + xfree_observer_list_node (current_node); + return; + } + previous_node = current_node; + current_node = current_node->next; + } + + /* We should never reach this point. However, this should not be + a very serious error, so simply report a warning to the user. */ + warning ("Failed to detach observer"); +} + +/* Send a notification to all the observers of SUBJECT. ARGS is passed to + all observers as an argument to the notification callback. */ + +static void +generic_observer_notify (struct observer_list *subject, const void *args) +{ + struct observer_list *current_node = subject; + + while (current_node != NULL) + { + (*current_node->observer->notify) (current_node->observer->data, args); + current_node = current_node->next; + } +} + +/* normal_stop notifications. */ + +static struct observer_list *normal_stop_subject = NULL; + +static void +observer_normal_stop_notification_stub (const void *data, + const void *unused_args) +{ + observer_normal_stop_ftype *notify = (observer_normal_stop_ftype *) data; + (*notify) (); +} + +struct observer * +observer_attach_normal_stop (observer_normal_stop_ftype *f) +{ + return generic_observer_attach (&normal_stop_subject, + &observer_normal_stop_notification_stub, + (void *) f); +} + +void +observer_detach_normal_stop (struct observer *observer) +{ + generic_observer_detach (&normal_stop_subject, observer); +} + +void +observer_notify_normal_stop (void) +{ + generic_observer_notify (normal_stop_subject, NULL); +} + +/* The following code is only used to unit-test the observers from our + testsuite. DO NOT USE IT within observer.c (or anywhere else for + that matter)! */ + +/* If we define these variables and functions as `static', the + compiler will optimize them out. */ + +int observer_test_first_observer = 0; +int observer_test_second_observer = 0; +int observer_test_third_observer = 0; + +void +observer_test_first_notification_function (void) +{ + observer_test_first_observer++; +} + +void +observer_test_second_notification_function (void) +{ + observer_test_second_observer++; +} + +void +observer_test_third_notification_function (void) +{ + observer_test_third_observer++; +} + diff --git a/contrib/gdb/gdb/observer.h b/contrib/gdb/gdb/observer.h new file mode 100644 index 00000000000..8b9a6db5607 --- /dev/null +++ b/contrib/gdb/gdb/observer.h @@ -0,0 +1,35 @@ +/* GDB Notifications to Observers. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef OBSERVER_H +#define OBSERVER_H + +struct observer; + +/* normal_stop notifications. */ + +typedef void (observer_normal_stop_ftype) (void); + +extern struct observer * + observer_attach_normal_stop (observer_normal_stop_ftype *f); +extern void observer_detach_normal_stop (struct observer *observer); +extern void observer_notify_normal_stop (void); + +#endif /* OBSERVER_H */ diff --git a/contrib/gdb/gdb/ocd.c b/contrib/gdb/gdb/ocd.c index 6834eea648f..c53db89f530 100644 --- a/contrib/gdb/gdb/ocd.c +++ b/contrib/gdb/gdb/ocd.c @@ -1,7 +1,7 @@ /* Target communications support for Macraigor Systems' On-Chip Debugging - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -42,18 +42,10 @@ static int ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len); -static int ocd_start_remote (PTR dummy); +static int ocd_start_remote (void *dummy); static int readchar (int timeout); -static void reset_packet (void); - -static void output_packet (void); - -static int get_quoted_char (int timeout); - -static void put_quoted_char (int c); - static void ocd_interrupt (int signo); static void ocd_interrupt_twice (int signo); @@ -70,17 +62,6 @@ static struct target_ops *current_ops = NULL; static int last_run_status; -/* This was 5 seconds, which is a long time to sit and wait. - Unless this is going though some terminal server or multiplexer or - other form of hairy serial connection, I would think 2 seconds would - be plenty. */ - -#if 0 -/* FIXME: Change to allow option to set timeout value on a per target - basis. */ -static int remote_timeout = 2; -#endif - /* Descriptor for I/O to remote machine. Initialize it to NULL so that ocd_open knows that we don't have a file open when the program starts. */ @@ -146,7 +127,7 @@ ocd_error (char *s, int error_code) s = buf; } - error (s); + error ("%s", s); } /* Return nonzero if the thread TH is still alive on the remote system. */ @@ -159,7 +140,6 @@ ocd_thread_alive (ptid_t th) /* Clean up connection to a remote debugger. */ -/* ARGSUSED */ void ocd_close (int quitting) { @@ -171,7 +151,7 @@ ocd_close (int quitting) /* Stub for catch_errors. */ static int -ocd_start_remote (PTR dummy) +ocd_start_remote (void *dummy) { unsigned char buf[10], *p; int pktlen; @@ -211,19 +191,11 @@ ocd_start_remote (PTR dummy) printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n", p[0], p[1], (p[2] << 16) | p[3]); -#if 0 - /* Reset the target */ - - ocd_do_command (OCD_RESET_RUN, &status, &pktlen); -/* ocd_do_command (OCD_RESET, &status, &pktlen); */ -#endif - /* If processor is still running, stop it. */ if (!(status & OCD_FLAG_BDM)) ocd_stop (); -#if 1 /* When using a target box, we want to asynchronously return status when target stops. The OCD_SET_CTL_FLAGS command is ignored by Wigglers.dll when using a parallel Wiggler */ @@ -242,7 +214,6 @@ ocd_start_remote (PTR dummy) if (error_code != 0) ocd_error ("OCD_SET_CTL_FLAGS:", error_code); -#endif immediate_quit--; @@ -254,9 +225,7 @@ ocd_start_remote (PTR dummy) flush_cached_frames (); registers_changed (); stop_pc = read_pc (); - set_current_frame (create_new_frame (read_fp (), stop_pc)); - select_frame (get_current_frame (), 0); - print_stack_frame (selected_frame, -1, 1); + print_stack_frame (get_selected_frame (), -1, 1); buf[0] = OCD_LOG_FILE; buf[1] = 3; /* close existing WIGGLERS.LOG */ @@ -739,7 +708,6 @@ ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) nonzero. Returns length of data written or read; 0 for error. TARGET is ignored. */ -/* ARGSUSED */ int ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write, struct mem_attrib *attrib, struct target_ops *target) @@ -784,112 +752,6 @@ readchar (int timeout) } } -#if 0 -/* Read a character from the data stream, dequoting as necessary. SYN is - treated special. Any SYNs appearing in the data stream are returned as the - distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be - mistaken for real data). */ - -static int -get_quoted_char (int timeout) -{ - int ch; - - ch = readchar (timeout); - - switch (ch) - { - case SERIAL_TIMEOUT: - error ("Timeout in mid-packet, aborting"); - case SYN: - return RAW_SYN; - case DLE: - ch = readchar (timeout); - if (ch == SYN) - return RAW_SYN; - return ch & ~0100; - default: - return ch; - } -} - -static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */ - -static void -reset_packet (void) -{ - pktp = pkt; -} - -static void -output_packet (void) -{ - if (serial_write (ocd_desc, pkt, pktp - pkt)) - perror_with_name ("output_packet: write failed"); - - reset_packet (); -} - -/* Output a quoted character. SYNs and DLEs are quoted. Everything else goes - through untouched. */ - -static void -put_quoted_char (int c) -{ - switch (c) - { - case SYN: - case DLE: - *pktp++ = DLE; - c |= 0100; - } - - *pktp++ = c; -} - -/* Send a packet to the OCD device. The packet framed by a SYN character, - a byte count and a checksum. The byte count only counts the number of - bytes between the count and the checksum. A count of zero actually - means 256. Any SYNs within the packet (including the checksum and - count) must be quoted. The quote character must be quoted as well. - Quoting is done by replacing the character with the two-character sequence - DLE, {char} | 0100. Note that the quoting mechanism has no effect on the - byte count. */ - -static void -stu_put_packet (unsigned char *buf, int len) -{ - unsigned char checksum; - unsigned char c; - - if (len == 0 || len > 256) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Can't represent 0 length packet */ - - reset_packet (); - - checksum = 0; - - put_quoted_char (RAW_SYN); - - c = len; - - do - { - checksum += c; - - put_quoted_char (c); - - c = *buf++; - } - while (len-- > 0); - - put_quoted_char (-checksum & 0xff); - - output_packet (); -} - -#else - /* Send a packet to the OCD device. The packet framed by a SYN character, a byte count and a checksum. The byte count only counts the number of bytes between the count and the checksum. A count of zero actually @@ -925,71 +787,6 @@ ocd_put_packet (unsigned char *buf, int len) if (serial_write (ocd_desc, packet, packet_ptr - packet)) perror_with_name ("output_packet: write failed"); } -#endif - -#if 0 -/* Get a packet from the OCD device. Timeout is only enforced for the - first byte of the packet. Subsequent bytes are expected to arrive in - time <= remote_timeout. Returns a pointer to a static buffer containing - the payload of the packet. *LENP contains the length of the packet. - */ - -static unsigned char * -stu_get_packet (unsigned char cmd, int *lenp, int timeout) -{ - int ch; - int len; - static unsigned char buf[256 + 10], *p; - unsigned char checksum; - -find_packet: - - ch = get_quoted_char (timeout); - - if (ch < 0) - error ("get_packet (readchar): %d", ch); - - if (ch != RAW_SYN) - goto find_packet; - -found_syn: /* Found the start of a packet */ - - p = buf; - checksum = 0; - - len = get_quoted_char (remote_timeout); - - if (len == RAW_SYN) - goto found_syn; - - checksum += len; - - if (len == 0) - len = 256; - - len++; /* Include checksum */ - - while (len-- > 0) - { - ch = get_quoted_char (remote_timeout); - if (ch == RAW_SYN) - goto found_syn; - - *p++ = ch; - checksum += ch; - } - - if (checksum != 0) - goto find_packet; - - if (cmd != buf[0]) - error ("Response phase error. Got 0x%x, expected 0x%x", buf[0], cmd); - - *lenp = p - buf - 1; - return buf; -} - -#else /* Get a packet from the OCD device. Timeout is only enforced for the first byte of the packet. Subsequent bytes are expected to arrive in @@ -1139,7 +936,6 @@ ocd_get_packet (int cmd, int *lenp, int timeout) *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */ return packet; } -#endif /* Execute a simple (one-byte) command. Returns a pointer to the data following the error code. */ @@ -1248,9 +1044,6 @@ ocd_load (char *args, int from_tty) not yet supported fully */ #define BDM_BREAKPOINT {0x0,0x0,0x0,0x0} /* For ppc 8xx */ -#if 0 -#define BDM_BREAKPOINT {0x4a,0xfa} /* BGND insn used for CPU32 */ -#endif /* BDM (at least on CPU32) uses a different breakpoint */ @@ -1353,20 +1146,9 @@ bdm_update_flash_command (char *args, int from_tty) /* discard_cleanups (old_chain); */ } - -static void -bdm_read_register_command (char *args, int from_tty) -{ - /* XXX repeat should go on to the next register */ - - if (!ocd_desc) - error ("Not connected to OCD device."); - - if (!args) - error ("Must specify BDM register number."); - -} +extern initialize_file_ftype _initialize_remote_ocd; /* -Wmissing-prototypes */ + void _initialize_remote_ocd (void) { @@ -1384,5 +1166,4 @@ _initialize_remote_ocd (void) add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list); add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list); add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list); - /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list); */ } diff --git a/contrib/gdb/gdb/ocd.h b/contrib/gdb/gdb/ocd.h index 5fa1fb95235..64d695a00c5 100644 --- a/contrib/gdb/gdb/ocd.h +++ b/contrib/gdb/gdb/ocd.h @@ -21,6 +21,9 @@ #ifndef OCD_H #define OCD_H +struct mem_attrib; +struct target_ops; + /* Wiggler serial protocol definitions */ #define DLE 020 /* Quote char */ diff --git a/contrib/gdb/gdb/osabi.c b/contrib/gdb/gdb/osabi.c new file mode 100644 index 00000000000..3acfc703648 --- /dev/null +++ b/contrib/gdb/gdb/osabi.c @@ -0,0 +1,630 @@ +/* OS ABI variant handling for GDB. + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "osabi.h" +#include "arch-utils.h" +#include "gdbcmd.h" +#include "command.h" + +#include "elf-bfd.h" + +#ifndef GDB_OSABI_DEFAULT +#define GDB_OSABI_DEFAULT GDB_OSABI_UNKNOWN +#endif + +/* State for the "set osabi" command. */ +static enum { osabi_auto, osabi_default, osabi_user } user_osabi_state; +static enum gdb_osabi user_selected_osabi; +static const char *gdb_osabi_available_names[GDB_OSABI_INVALID + 3] = { + "auto", + "default", + "none", + NULL +}; +static const char *set_osabi_string; + +/* This table matches the indices assigned to enum gdb_osabi. Keep + them in sync. */ +static const char * const gdb_osabi_names[] = +{ + "none", + + "SVR4", + "GNU/Hurd", + "Solaris", + "OSF/1", + "GNU/Linux", + "FreeBSD a.out", + "FreeBSD ELF", + "NetBSD a.out", + "NetBSD ELF", + "OpenBSD ELF", + "Windows CE", + "DJGPP", + "NetWare", + "Irix", + "LynxOS", + "Interix", + "HP/UX ELF", + "HP/UX SOM", + + "ARM EABI v1", + "ARM EABI v2", + "ARM APCS", + "QNX Neutrino", + + "Cygwin", + + "" +}; + +const char * +gdbarch_osabi_name (enum gdb_osabi osabi) +{ + if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID) + return gdb_osabi_names[osabi]; + + return gdb_osabi_names[GDB_OSABI_INVALID]; +} + +/* Handler for a given architecture/OS ABI pair. There should be only + one handler for a given OS ABI each architecture family. */ +struct gdb_osabi_handler +{ + struct gdb_osabi_handler *next; + const struct bfd_arch_info *arch_info; + enum gdb_osabi osabi; + void (*init_osabi)(struct gdbarch_info, struct gdbarch *); +}; + +static struct gdb_osabi_handler *gdb_osabi_handler_list; + +void +gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine, + enum gdb_osabi osabi, + void (*init_osabi)(struct gdbarch_info, + struct gdbarch *)) +{ + struct gdb_osabi_handler **handler_p; + const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine); + const char **name_ptr; + + /* Registering an OS ABI handler for "unknown" is not allowed. */ + if (osabi == GDB_OSABI_UNKNOWN) + { + internal_error + (__FILE__, __LINE__, + "gdbarch_register_osabi: An attempt to register a handler for " + "OS ABI \"%s\" for architecture %s was made. The handler will " + "not be registered", + gdbarch_osabi_name (osabi), + bfd_printable_arch_mach (arch, machine)); + return; + } + + gdb_assert (arch_info); + + for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL; + handler_p = &(*handler_p)->next) + { + if ((*handler_p)->arch_info == arch_info + && (*handler_p)->osabi == osabi) + { + internal_error + (__FILE__, __LINE__, + "gdbarch_register_osabi: A handler for OS ABI \"%s\" " + "has already been registered for architecture %s", + gdbarch_osabi_name (osabi), + arch_info->printable_name); + /* If user wants to continue, override previous definition. */ + (*handler_p)->init_osabi = init_osabi; + return; + } + } + + (*handler_p) + = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler)); + (*handler_p)->next = NULL; + (*handler_p)->arch_info = arch_info; + (*handler_p)->osabi = osabi; + (*handler_p)->init_osabi = init_osabi; + + /* Add this OS ABI to the list of enum values for "set osabi", if it isn't + already there. */ + for (name_ptr = gdb_osabi_available_names; *name_ptr; name_ptr ++) + { + if (*name_ptr == gdbarch_osabi_name (osabi)) + return; + } + *name_ptr++ = gdbarch_osabi_name (osabi); + *name_ptr = NULL; +} + + +/* Sniffer to find the OS ABI for a given file's architecture and flavour. + It is legal to have multiple sniffers for each arch/flavour pair, to + disambiguate one OS's a.out from another, for example. The first sniffer + to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should + be careful to claim a file only if it knows for sure what it is. */ +struct gdb_osabi_sniffer +{ + struct gdb_osabi_sniffer *next; + enum bfd_architecture arch; /* bfd_arch_unknown == wildcard */ + enum bfd_flavour flavour; + enum gdb_osabi (*sniffer)(bfd *); +}; + +static struct gdb_osabi_sniffer *gdb_osabi_sniffer_list; + +void +gdbarch_register_osabi_sniffer (enum bfd_architecture arch, + enum bfd_flavour flavour, + enum gdb_osabi (*sniffer_fn)(bfd *)) +{ + struct gdb_osabi_sniffer *sniffer; + + sniffer = + (struct gdb_osabi_sniffer *) xmalloc (sizeof (struct gdb_osabi_sniffer)); + sniffer->arch = arch; + sniffer->flavour = flavour; + sniffer->sniffer = sniffer_fn; + + sniffer->next = gdb_osabi_sniffer_list; + gdb_osabi_sniffer_list = sniffer; +} + + +enum gdb_osabi +gdbarch_lookup_osabi (bfd *abfd) +{ + struct gdb_osabi_sniffer *sniffer; + enum gdb_osabi osabi, match; + int match_specific; + + /* If we aren't in "auto" mode, return the specified OS ABI. */ + if (user_osabi_state == osabi_user) + return user_selected_osabi; + + /* If we don't have a binary, return the default OS ABI (if set) or + an inconclusive result (otherwise). */ + if (abfd == NULL) + { + if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN) + return GDB_OSABI_DEFAULT; + else + return GDB_OSABI_UNINITIALIZED; + } + + match = GDB_OSABI_UNKNOWN; + match_specific = 0; + + for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL; + sniffer = sniffer->next) + { + if ((sniffer->arch == bfd_arch_unknown /* wildcard */ + || sniffer->arch == bfd_get_arch (abfd)) + && sniffer->flavour == bfd_get_flavour (abfd)) + { + osabi = (*sniffer->sniffer) (abfd); + if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID) + { + internal_error + (__FILE__, __LINE__, + "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer " + "for architecture %s flavour %d", + (int) osabi, + bfd_printable_arch_mach (bfd_get_arch (abfd), 0), + (int) bfd_get_flavour (abfd)); + } + else if (osabi != GDB_OSABI_UNKNOWN) + { + /* A specific sniffer always overrides a generic sniffer. + Croak on multiple match if the two matches are of the + same class. If the user wishes to continue, we'll use + the first match. */ + if (match != GDB_OSABI_UNKNOWN) + { + if ((match_specific && sniffer->arch != bfd_arch_unknown) + || (!match_specific && sniffer->arch == bfd_arch_unknown)) + { + internal_error + (__FILE__, __LINE__, + "gdbarch_lookup_osabi: multiple %sspecific OS ABI " + "match for architecture %s flavour %d: first " + "match \"%s\", second match \"%s\"", + match_specific ? "" : "non-", + bfd_printable_arch_mach (bfd_get_arch (abfd), 0), + (int) bfd_get_flavour (abfd), + gdbarch_osabi_name (match), + gdbarch_osabi_name (osabi)); + } + else if (sniffer->arch != bfd_arch_unknown) + { + match = osabi; + match_specific = 1; + } + } + else + { + match = osabi; + if (sniffer->arch != bfd_arch_unknown) + match_specific = 1; + } + } + } + } + + /* If we didn't find a match, but a default was specified at configure + time, return the default. */ + if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN && match == GDB_OSABI_UNKNOWN) + return GDB_OSABI_DEFAULT; + else + return match; +} + + +/* Return non-zero if architecture A can run code written for + architecture B. */ +static int +can_run_code_for (const struct bfd_arch_info *a, const struct bfd_arch_info *b) +{ + /* BFD's 'A->compatible (A, B)' functions return zero if A and B are + incompatible. But if they are compatible, it returns the 'more + featureful' of the two arches. That is, if A can run code + written for B, but B can't run code written for A, then it'll + return A. + + struct bfd_arch_info objects are singletons: that is, there's + supposed to be exactly one instance for a given machine. So you + can tell whether two are equivalent by comparing pointers. */ + return (a == b || a->compatible (a, b) == a); +} + + +void +gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdb_osabi_handler *handler; + + if (info.osabi == GDB_OSABI_UNKNOWN) + { + /* Don't complain about an unknown OSABI. Assume the user knows + what they are doing. */ + return; + } + + for (handler = gdb_osabi_handler_list; handler != NULL; + handler = handler->next) + { + if (handler->osabi != info.osabi) + continue; + + /* If the architecture described by ARCH_INFO can run code for + the architcture we registered the handler for, then the + handler is applicable. Note, though, that if the handler is + for an architecture that is a superset of ARCH_INFO, we can't + use that --- it would be perfectly correct for it to install + gdbarch methods that refer to registers / instructions / + other facilities ARCH_INFO doesn't have. + + NOTE: kettenis/20021027: There may be more than one machine + type that is compatible with the desired machine type. Right + now we simply return the first match, which is fine for now. + However, we might want to do something smarter in the future. */ + /* NOTE: cagney/2003-10-23: The code for "a can_run_code_for b" + is implemented using BFD's compatible method (a->compatible + (b) == a -- the lowest common denominator between a and b is + a). That method's definition of compatible may not be as you + expect. For instance the test "amd64 can run code for i386" + (or more generally "64-bit ISA can run code for the 32-bit + ISA"). BFD doesn't normally consider 32-bit and 64-bit + "compatible" so it doesn't succeed. */ + if (can_run_code_for (info.bfd_arch_info, handler->arch_info)) + { + (*handler->init_osabi) (info, gdbarch); + return; + } + } + + warning + ("A handler for the OS ABI \"%s\" is not built into this configuration\n" + "of GDB. Attempting to continue with the default %s settings.\n", + gdbarch_osabi_name (info.osabi), + info.bfd_arch_info->printable_name); +} + +/* Limit on the amount of data to be read. */ +#define MAX_NOTESZ 128 + +/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. */ + +static int +check_note (bfd *abfd, asection *sect, const char *note, + const char *name, unsigned long descsz, unsigned long type) +{ + unsigned long notesz; + + /* Calculate the size of this note. */ + notesz = strlen (name) + 1; + notesz = ((notesz + 3) & ~3); + notesz += descsz; + notesz = ((notesz + 3) & ~3); + + /* If this assertion triggers, increase MAX_NOTESZ. */ + gdb_assert (notesz <= MAX_NOTESZ); + + /* Check whether SECT is big enough to comtain the complete note. */ + if (notesz > bfd_section_size (abfd, sect)) + return 0; + + /* Check the note name. */ + if (bfd_h_get_32 (abfd, note) != (strlen (name) + 1) + || strcmp (note + 12, name) != 0) + return 0; + + /* Check the descriptor size. */ + if (bfd_h_get_32 (abfd, note + 4) != descsz) + return 0; + + /* Check the note type. */ + if (bfd_h_get_32 (abfd, note + 8) != type) + return 0; + + return 1; +} + +/* Generic sniffer for ELF flavoured files. */ + +void +generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) +{ + enum gdb_osabi *osabi = obj; + const char *name; + unsigned int sectsize; + char *note; + + name = bfd_get_section_name (abfd, sect); + sectsize = bfd_section_size (abfd, sect); + + /* Limit the amount of data to read. */ + if (sectsize > MAX_NOTESZ) + sectsize = MAX_NOTESZ; + + note = alloca (sectsize); + bfd_get_section_contents (abfd, sect, note, 0, sectsize); + + /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */ + if (strcmp (name, ".note.ABI-tag") == 0) + { + /* GNU. */ + if (check_note (abfd, sect, note, "GNU", 16, NT_GNU_ABI_TAG)) + { + unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16); + + switch (abi_tag) + { + case GNU_ABI_TAG_LINUX: + *osabi = GDB_OSABI_LINUX; + break; + + case GNU_ABI_TAG_HURD: + *osabi = GDB_OSABI_HURD; + break; + + case GNU_ABI_TAG_SOLARIS: + *osabi = GDB_OSABI_SOLARIS; + break; + + case GNU_ABI_TAG_FREEBSD: + *osabi = GDB_OSABI_FREEBSD_ELF; + break; + + case GNU_ABI_TAG_NETBSD: + *osabi = GDB_OSABI_NETBSD_ELF; + break; + + default: + internal_error (__FILE__, __LINE__, "\ +generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d", + abi_tag); + } + return; + } + + /* FreeBSD. */ + if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG)) + { + /* There is no need to check the version yet. */ + *osabi = GDB_OSABI_FREEBSD_ELF; + return; + } + + return; + } + + /* .note.netbsd.ident notes, used by NetBSD. */ + if (strcmp (name, ".note.netbsd.ident") == 0 + && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT)) + { + /* There is no need to check the version yet. */ + *osabi = GDB_OSABI_NETBSD_ELF; + return; + } + + /* .note.openbsd.ident notes, used by OpenBSD. */ + if (strcmp (name, ".note.openbsd.ident") == 0 + && check_note (abfd, sect, note, "OpenBSD", 4, NT_OPENBSD_IDENT)) + { + /* There is no need to check the version yet. */ + *osabi = GDB_OSABI_OPENBSD_ELF; + return; + } + + /* .note.netbsdcore.procinfo notes, used by NetBSD. */ + if (strcmp (name, ".note.netbsdcore.procinfo") == 0) + { + *osabi = GDB_OSABI_NETBSD_ELF; + return; + } +} + +static enum gdb_osabi +generic_elf_osabi_sniffer (bfd *abfd) +{ + unsigned int elfosabi; + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; + + elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; + + switch (elfosabi) + { + case ELFOSABI_NONE: + /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the + file are conforming to the base specification for that machine + (there are no OS-specific extensions). In order to determine the + real OS in use we must look for OS notes that have been added. */ + bfd_map_over_sections (abfd, + generic_elf_osabi_sniff_abi_tag_sections, + &osabi); + break; + + case ELFOSABI_FREEBSD: + osabi = GDB_OSABI_FREEBSD_ELF; + break; + + case ELFOSABI_NETBSD: + osabi = GDB_OSABI_NETBSD_ELF; + break; + + case ELFOSABI_LINUX: + osabi = GDB_OSABI_LINUX; + break; + + case ELFOSABI_HURD: + osabi = GDB_OSABI_HURD; + break; + + case ELFOSABI_SOLARIS: + osabi = GDB_OSABI_SOLARIS; + break; + + case ELFOSABI_HPUX: + osabi = GDB_OSABI_HPUX_ELF; + break; + } + + if (osabi == GDB_OSABI_UNKNOWN) + { + /* The FreeBSD folks have been naughty; they stored the string + "FreeBSD" in the padding of the e_ident field of the ELF + header to "brand" their ELF binaries in FreeBSD 3.x. */ + if (strcmp (&elf_elfheader (abfd)->e_ident[8], "FreeBSD") == 0) + osabi = GDB_OSABI_FREEBSD_ELF; + } + + return osabi; +} + +static void +set_osabi (char *args, int from_tty, struct cmd_list_element *c) +{ + struct gdbarch_info info; + + if (strcmp (set_osabi_string, "auto") == 0) + user_osabi_state = osabi_auto; + else if (strcmp (set_osabi_string, "default") == 0) + { + user_selected_osabi = GDB_OSABI_DEFAULT; + user_osabi_state = osabi_user; + } + else if (strcmp (set_osabi_string, "none") == 0) + { + user_selected_osabi = GDB_OSABI_UNKNOWN; + user_osabi_state = osabi_user; + } + else + { + int i; + for (i = 1; i < GDB_OSABI_INVALID; i++) + if (strcmp (set_osabi_string, gdbarch_osabi_name (i)) == 0) + { + user_selected_osabi = i; + user_osabi_state = osabi_user; + break; + } + if (i == GDB_OSABI_INVALID) + internal_error (__FILE__, __LINE__, + "Invalid OS ABI \"%s\" passed to command handler.", + set_osabi_string); + } + + /* NOTE: At some point (true multiple architectures) we'll need to be more + graceful here. */ + gdbarch_info_init (&info); + if (! gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, "Updating OS ABI failed."); +} + +static void +show_osabi (char *args, int from_tty) +{ + if (user_osabi_state == osabi_auto) + printf_filtered ("The current OS ABI is \"auto\" (currently \"%s\").\n", + gdbarch_osabi_name (gdbarch_osabi (current_gdbarch))); + else + printf_filtered ("The current OS ABI is \"%s\".\n", + gdbarch_osabi_name (user_selected_osabi)); + + if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN) + printf_filtered ("The default OS ABI is \"%s\".\n", + gdbarch_osabi_name (GDB_OSABI_DEFAULT)); +} + +extern initialize_file_ftype _initialize_gdb_osabi; /* -Wmissing-prototype */ + +void +_initialize_gdb_osabi (void) +{ + struct cmd_list_element *c; + + if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "") != 0) + internal_error + (__FILE__, __LINE__, + "_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent"); + + /* Register a generic sniffer for ELF flavoured files. */ + gdbarch_register_osabi_sniffer (bfd_arch_unknown, + bfd_target_elf_flavour, + generic_elf_osabi_sniffer); + + /* Register the "set osabi" command. */ + c = add_set_enum_cmd ("osabi", class_support, gdb_osabi_available_names, + &set_osabi_string, "Set OS ABI of target.", &setlist); + + set_cmd_sfunc (c, set_osabi); + add_cmd ("osabi", class_support, show_osabi, "Show OS/ABI of target.", + &showlist); + user_osabi_state = osabi_auto; +} diff --git a/contrib/gdb/gdb/osabi.h b/contrib/gdb/gdb/osabi.h new file mode 100644 index 00000000000..d0e33b35882 --- /dev/null +++ b/contrib/gdb/gdb/osabi.h @@ -0,0 +1,55 @@ +/* OS ABI variant handling for GDB. + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef OSABI_H +#define OSABI_H + +/* Register an OS ABI sniffer. Each arch/flavour may have more than + one sniffer. This is used to e.g. differentiate one OS's a.out from + another. The first sniffer to return something other than + GDB_OSABI_UNKNOWN wins, so a sniffer should be careful to claim a file + only if it knows for sure what it is. */ +void gdbarch_register_osabi_sniffer (enum bfd_architecture, + enum bfd_flavour, + enum gdb_osabi (*)(bfd *)); + +/* Register a handler for an OS ABI variant for a given architecture + and machine type. There should be only one handler for a given OS + ABI for each architecture and machine type combination. */ +void gdbarch_register_osabi (enum bfd_architecture, unsigned long, + enum gdb_osabi, + void (*)(struct gdbarch_info, + struct gdbarch *)); + +/* Lookup the OS ABI corresponding to the specified BFD. */ +enum gdb_osabi gdbarch_lookup_osabi (bfd *); + +/* Initialize the gdbarch for the specified OS ABI variant. */ +void gdbarch_init_osabi (struct gdbarch_info, struct gdbarch *); + +/* Return the name of the specified OS ABI. */ +const char *gdbarch_osabi_name (enum gdb_osabi); + +/* Helper routine for ELF file sniffers. This looks at ABI tag note + sections to determine the OS ABI from the note. It should be called + via bfd_map_over_sections. */ +void generic_elf_osabi_sniff_abi_tag_sections (bfd *, asection *, void *); + +#endif /* OSABI_H */ diff --git a/contrib/gdb/gdb/p-exp.c b/contrib/gdb/gdb/p-exp.c new file mode 100644 index 00000000000..d96a856f6cc --- /dev/null +++ b/contrib/gdb/gdb/p-exp.c @@ -0,0 +1,2974 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + INT = 258, + FLOAT = 259, + STRING = 260, + FIELDNAME = 261, + NAME = 262, + TYPENAME = 263, + NAME_OR_INT = 264, + STRUCT = 265, + CLASS = 266, + SIZEOF = 267, + COLONCOLON = 268, + ERROR = 269, + VARIABLE = 270, + THIS = 271, + TRUEKEYWORD = 272, + FALSEKEYWORD = 273, + ABOVE_COMMA = 274, + ASSIGN = 275, + NOT = 276, + OR = 277, + XOR = 278, + ANDAND = 279, + NOTEQUAL = 280, + GEQ = 281, + LEQ = 282, + MOD = 283, + DIV = 284, + RSH = 285, + LSH = 286, + DECREMENT = 287, + INCREMENT = 288, + UNARY = 289, + ARROW = 290, + BLOCKNAME = 291 + }; +#endif +#define INT 258 +#define FLOAT 259 +#define STRING 260 +#define FIELDNAME 261 +#define NAME 262 +#define TYPENAME 263 +#define NAME_OR_INT 264 +#define STRUCT 265 +#define CLASS 266 +#define SIZEOF 267 +#define COLONCOLON 268 +#define ERROR 269 +#define VARIABLE 270 +#define THIS 271 +#define TRUEKEYWORD 272 +#define FALSEKEYWORD 273 +#define ABOVE_COMMA 274 +#define ASSIGN 275 +#define NOT 276 +#define OR 277 +#define XOR 278 +#define ANDAND 279 +#define NOTEQUAL 280 +#define GEQ 281 +#define LEQ 282 +#define MOD 283 +#define DIV 284 +#define RSH 285 +#define LSH 286 +#define DECREMENT 287 +#define INCREMENT 288 +#define UNARY 289 +#define ARROW 290 +#define BLOCKNAME 291 + + + + +/* Copy the first part of user declarations. */ +#line 46 "p-exp.y" + + +#include "defs.h" +#include "gdb_string.h" +#include +#include "expression.h" +#include "value.h" +#include "parser-defs.h" +#include "language.h" +#include "p-lang.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in gdb. Note that these are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +#define yymaxdepth pascal_maxdepth +#define yyparse pascal_parse +#define yylex pascal_lex +#define yyerror pascal_error +#define yylval pascal_lval +#define yychar pascal_char +#define yydebug pascal_debug +#define yypact pascal_pact +#define yyr1 pascal_r1 +#define yyr2 pascal_r2 +#define yydef pascal_def +#define yychk pascal_chk +#define yypgo pascal_pgo +#define yyact pascal_act +#define yyexca pascal_exca +#define yyerrflag pascal_errflag +#define yynerrs pascal_nerrs +#define yyps pascal_ps +#define yypv pascal_pv +#define yys pascal_s +#define yy_yys pascal_yys +#define yystate pascal_state +#define yytmp pascal_tmp +#define yyv pascal_v +#define yy_yyv pascal_yyv +#define yyval pascal_val +#define yylloc pascal_lloc +#define yyreds pascal_reds /* With YYDEBUG defined */ +#define yytoks pascal_toks /* With YYDEBUG defined */ +#define yyname pascal_name /* With YYDEBUG defined */ +#define yyrule pascal_rule /* With YYDEBUG defined */ +#define yylhs pascal_yylhs +#define yylen pascal_yylen +#define yydefred pascal_yydefred +#define yydgoto pascal_yydgoto +#define yysindex pascal_yysindex +#define yyrindex pascal_yyrindex +#define yygindex pascal_yygindex +#define yytable pascal_yytable +#define yycheck pascal_yycheck + +#ifndef YYDEBUG +#define YYDEBUG 1 /* Default to yydebug support */ +#endif + +#define YYFPRINTF parser_fprintf + +int yyparse (void); + +static int yylex (void); + +void +yyerror (char *); + +static char * uptok (char *, int); + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 130 "p-exp.y" +typedef union YYSTYPE { + LONGEST lval; + struct { + LONGEST val; + struct type *type; + } typed_val_int; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; + struct symbol *sym; + struct type *tval; + struct stoken sval; + struct ttype tsym; + struct symtoken ssym; + int voidval; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + + struct type **tvec; + int *ivec; + } YYSTYPE; +/* Line 191 of yacc.c. */ +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ +#line 154 "p-exp.y" + +/* YYSTYPE gets defined by %union */ +static int +parse_number (char *, int, int, YYSTYPE *); + +static struct type *current_type; + +static void push_current_type (void); +static void pop_current_type (void); +static int search_field; + + +/* Line 214 of yacc.c. */ + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or xmalloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC xmalloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 359 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 52 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 19 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 73 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 123 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 291 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 46, 50, 39, 37, 19, 38, 44, 40, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 28, 26, 29, 2, 36, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 45, 2, 51, 48, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, + 27, 30, 31, 32, 33, 34, 35, 41, 42, 43, + 47, 49 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 15, 19, + 22, 25, 28, 31, 36, 41, 42, 47, 48, 54, + 55, 61, 62, 64, 68, 73, 77, 81, 85, 89, + 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, + 133, 137, 141, 145, 149, 151, 153, 155, 157, 159, + 161, 163, 168, 170, 172, 174, 178, 182, 186, 188, + 191, 193, 195, 197, 201, 204, 206, 209, 212, 214, + 216, 218, 220, 222 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 53, 0, -1, -1, 54, 55, -1, 57, -1, 56, + -1, 67, -1, 58, -1, 57, 19, 58, -1, 58, + 48, -1, 36, 58, -1, 38, 58, -1, 22, 58, + -1, 42, 46, 58, 50, -1, 41, 46, 58, 50, + -1, -1, 58, 44, 59, 6, -1, -1, 58, 45, + 60, 57, 51, -1, -1, 58, 46, 61, 62, 50, + -1, -1, 58, -1, 62, 19, 58, -1, 67, 46, + 58, 50, -1, 46, 57, 50, -1, 58, 39, 58, + -1, 58, 40, 58, -1, 58, 33, 58, -1, 58, + 32, 58, -1, 58, 37, 58, -1, 58, 38, 58, + -1, 58, 35, 58, -1, 58, 34, 58, -1, 58, + 26, 58, -1, 58, 27, 58, -1, 58, 31, 58, + -1, 58, 30, 58, -1, 58, 28, 58, -1, 58, + 29, 58, -1, 58, 25, 58, -1, 58, 24, 58, + -1, 58, 23, 58, -1, 58, 21, 58, -1, 17, + -1, 18, -1, 3, -1, 9, -1, 4, -1, 64, + -1, 15, -1, 12, 46, 67, 50, -1, 5, -1, + 16, -1, 49, -1, 63, 13, 69, -1, 63, 13, + 69, -1, 68, 13, 69, -1, 65, -1, 13, 69, + -1, 70, -1, 68, -1, 66, -1, 68, 13, 39, + -1, 48, 68, -1, 8, -1, 10, 69, -1, 11, + 69, -1, 7, -1, 49, -1, 8, -1, 9, -1, + 7, -1, 49, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 234, 234, 234, 241, 242, 245, 252, 253, 258, + 264, 270, 274, 278, 282, 286, 286, 301, 299, 329, + 326, 338, 339, 341, 345, 360, 366, 370, 374, 378, + 382, 386, 390, 394, 398, 402, 406, 410, 414, 418, + 422, 426, 430, 434, 438, 444, 450, 457, 468, 475, + 478, 482, 490, 515, 542, 559, 570, 586, 601, 602, + 636, 708, 719, 720, 725, 727, 729, 732, 740, 741, + 742, 743, 746, 747 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "INT", "FLOAT", "STRING", "FIELDNAME", + "NAME", "TYPENAME", "NAME_OR_INT", "STRUCT", "CLASS", "SIZEOF", + "COLONCOLON", "ERROR", "VARIABLE", "THIS", "TRUEKEYWORD", + "FALSEKEYWORD", "','", "ABOVE_COMMA", "ASSIGN", "NOT", "OR", "XOR", + "ANDAND", "'='", "NOTEQUAL", "'<'", "'>'", "GEQ", "LEQ", "MOD", "DIV", + "RSH", "LSH", "'@'", "'+'", "'-'", "'*'", "'/'", "DECREMENT", + "INCREMENT", "UNARY", "'.'", "'['", "'('", "ARROW", "'^'", "BLOCKNAME", + "')'", "']'", "$accept", "start", "@1", "normal_start", "type_exp", + "exp1", "exp", "@2", "@3", "@4", "arglist", "block", "variable", + "qualified_name", "ptype", "type", "typebase", "name", + "name_not_typename", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 44, + 274, 275, 276, 277, 278, 279, 61, 280, 60, 62, + 281, 282, 283, 284, 285, 286, 64, 43, 45, 42, + 47, 287, 288, 289, 46, 91, 40, 290, 94, 291, + 41, 93 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 52, 54, 53, 55, 55, 56, 57, 57, 58, + 58, 58, 58, 58, 58, 59, 58, 60, 58, 61, + 58, 62, 62, 62, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 63, 63, 64, 65, 64, 64, + 64, 66, 67, 67, 68, 68, 68, 68, 69, 69, + 69, 69, 70, 70 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 1, 3, 2, + 2, 2, 2, 4, 4, 0, 4, 0, 5, 0, + 5, 0, 1, 3, 4, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, + 1, 4, 1, 1, 1, 3, 3, 3, 1, 2, + 1, 1, 1, 3, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 2, 0, 0, 1, 46, 48, 52, 72, 65, 47, + 0, 0, 0, 0, 50, 53, 44, 45, 0, 0, + 0, 0, 0, 0, 0, 73, 3, 5, 4, 7, + 0, 49, 58, 62, 6, 61, 60, 68, 70, 71, + 69, 66, 67, 0, 59, 12, 0, 10, 11, 0, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 17, 19, 9, 0, 0, 0, 0, + 61, 0, 0, 25, 8, 43, 42, 41, 40, 34, + 35, 38, 39, 37, 36, 29, 28, 33, 32, 30, + 31, 26, 27, 0, 0, 21, 56, 0, 63, 57, + 51, 0, 14, 13, 16, 0, 22, 0, 24, 18, + 0, 20, 23 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char yydefgoto[] = +{ + -1, 1, 2, 26, 27, 28, 29, 103, 104, 105, + 117, 30, 31, 32, 33, 46, 35, 41, 36 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -37 +static const short yypact[] = +{ + -37, 5, 88, -37, -37, -37, -37, -37, -37, -37, + 6, 6, -35, 6, -37, -37, -37, -37, 88, 88, + 88, -29, -27, 88, 10, 12, -37, -37, 8, 201, + 16, -37, -37, -37, -13, 21, -37, -37, -37, -37, + -37, -37, -37, 10, -37, -36, -13, -36, -36, 88, + 88, 11, -37, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, -37, -37, -37, -37, 6, 88, 15, 20, + 43, 117, 145, -37, 201, 201, 226, 250, 273, 294, + 294, 311, 311, 311, 311, 28, 28, 28, 28, 68, + 68, -36, -36, 56, 88, 88, 62, 173, -37, -37, + -37, 38, -37, -37, -37, 9, 201, 44, -37, -37, + 88, -37, 201 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -37, -37, -37, -37, -37, -20, -18, -37, -37, -37, + -37, -37, -37, -37, -37, 14, -17, -7, -37 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -56 +static const yysigned_char yytable[] = +{ + 45, 47, 48, 51, 42, 3, 44, 52, 72, 73, + 74, 43, 75, 37, 38, 39, 34, 49, 8, 50, + 10, 11, 37, 38, 39, -54, 80, 53, 53, 76, + 53, 81, 82, 77, 78, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 108, 40, 111, 79, 24, 107, + 119, 83, 114, 120, 40, 68, 69, 70, 71, 106, + 110, 109, 72, 73, 74, -55, 75, 108, 0, 0, + 0, 0, 0, 0, 115, 0, 0, 116, 0, 0, + 0, 4, 5, 6, 121, 7, 8, 9, 10, 11, + 12, 13, 122, 14, 15, 16, 17, 70, 71, 0, + 18, 0, 72, 73, 74, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 19, 0, 20, 0, 0, 21, + 22, 0, 0, 0, 23, 0, 24, 25, 54, 0, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 0, 68, 69, 70, 71, 0, 0, + 0, 72, 73, 74, 0, 75, 54, 112, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 0, 68, 69, 70, 71, 0, 0, 0, 72, + 73, 74, 0, 75, 54, 113, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 0, + 68, 69, 70, 71, 0, 0, 0, 72, 73, 74, + 0, 75, 54, 118, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 0, 68, 69, + 70, 71, 0, 0, 0, 72, 73, 74, 0, 75, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 0, 68, 69, 70, 71, 0, 0, 0, + 72, 73, 74, 0, 75, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 0, 68, 69, 70, + 71, 0, 0, 0, 72, 73, 74, 0, 75, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 0, + 68, 69, 70, 71, 0, 0, 0, 72, 73, 74, + 0, 75, 60, 61, 62, 63, 64, 65, 66, 67, + 0, 68, 69, 70, 71, 0, 0, 0, 72, 73, + 74, 0, 75, 64, 65, 66, 67, 0, 68, 69, + 70, 71, 0, 0, 0, 72, 73, 74, 0, 75 +}; + +static const yysigned_char yycheck[] = +{ + 18, 19, 20, 23, 11, 0, 13, 24, 44, 45, + 46, 46, 48, 7, 8, 9, 2, 46, 8, 46, + 10, 11, 7, 8, 9, 13, 43, 19, 19, 13, + 19, 49, 50, 46, 13, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 39, 49, 13, 43, 48, 77, + 51, 50, 6, 19, 49, 37, 38, 39, 40, 76, + 50, 78, 44, 45, 46, 13, 48, 39, -1, -1, + -1, -1, -1, -1, 104, -1, -1, 105, -1, -1, + -1, 3, 4, 5, 50, 7, 8, 9, 10, 11, + 12, 13, 120, 15, 16, 17, 18, 39, 40, -1, + 22, -1, 44, 45, 46, -1, 48, -1, -1, -1, + -1, -1, -1, -1, 36, -1, 38, -1, -1, 41, + 42, -1, -1, -1, 46, -1, 48, 49, 21, -1, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, -1, 37, 38, 39, 40, -1, -1, + -1, 44, 45, 46, -1, 48, 21, 50, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, -1, 37, 38, 39, 40, -1, -1, -1, 44, + 45, 46, -1, 48, 21, 50, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, + 37, 38, 39, 40, -1, -1, -1, 44, 45, 46, + -1, 48, 21, 50, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, -1, 37, 38, + 39, 40, -1, -1, -1, 44, 45, 46, -1, 48, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, -1, 37, 38, 39, 40, -1, -1, -1, + 44, 45, 46, -1, 48, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, -1, 37, 38, 39, + 40, -1, -1, -1, 44, 45, 46, -1, 48, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, + 37, 38, 39, 40, -1, -1, -1, 44, 45, 46, + -1, 48, 28, 29, 30, 31, 32, 33, 34, 35, + -1, 37, 38, 39, 40, -1, -1, -1, 44, 45, + 46, -1, 48, 32, 33, 34, 35, -1, 37, 38, + 39, 40, -1, -1, -1, 44, 45, 46, -1, 48 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 53, 54, 0, 3, 4, 5, 7, 8, 9, + 10, 11, 12, 13, 15, 16, 17, 18, 22, 36, + 38, 41, 42, 46, 48, 49, 55, 56, 57, 58, + 63, 64, 65, 66, 67, 68, 70, 7, 8, 9, + 49, 69, 69, 46, 69, 58, 67, 58, 58, 46, + 46, 57, 68, 19, 21, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 37, 38, + 39, 40, 44, 45, 46, 48, 13, 46, 13, 67, + 68, 58, 58, 50, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 59, 60, 61, 69, 58, 39, 69, + 50, 13, 50, 50, 6, 57, 58, 62, 50, 51, + 19, 50, 58 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to xreallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to xreallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 234 "p-exp.y" + { current_type = NULL; + search_field = 0; + } + break; + + case 3: +#line 237 "p-exp.y" + {} + break; + + case 6: +#line 246 "p-exp.y" + { write_exp_elt_opcode(OP_TYPE); + write_exp_elt_type(yyvsp[0].tval); + write_exp_elt_opcode(OP_TYPE); + current_type = yyvsp[0].tval; } + break; + + case 8: +#line 254 "p-exp.y" + { write_exp_elt_opcode (BINOP_COMMA); } + break; + + case 9: +#line 259 "p-exp.y" + { write_exp_elt_opcode (UNOP_IND); + if (current_type) + current_type = TYPE_TARGET_TYPE (current_type); } + break; + + case 10: +#line 265 "p-exp.y" + { write_exp_elt_opcode (UNOP_ADDR); + if (current_type) + current_type = TYPE_POINTER_TYPE (current_type); } + break; + + case 11: +#line 271 "p-exp.y" + { write_exp_elt_opcode (UNOP_NEG); } + break; + + case 12: +#line 275 "p-exp.y" + { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } + break; + + case 13: +#line 279 "p-exp.y" + { write_exp_elt_opcode (UNOP_PREINCREMENT); } + break; + + case 14: +#line 283 "p-exp.y" + { write_exp_elt_opcode (UNOP_PREDECREMENT); } + break; + + case 15: +#line 286 "p-exp.y" + { search_field = 1; } + break; + + case 16: +#line 289 "p-exp.y" + { write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (STRUCTOP_STRUCT); + search_field = 0; + if (current_type) + { while (TYPE_CODE (current_type) == TYPE_CODE_PTR) + current_type = TYPE_TARGET_TYPE (current_type); + current_type = lookup_struct_elt_type ( + current_type, yyvsp[0].sval.ptr, 0); }; + } + break; + + case 17: +#line 301 "p-exp.y" + { char *arrayname; + int arrayfieldindex; + arrayfieldindex = is_pascal_string_type ( + current_type, NULL, NULL, + NULL, NULL, &arrayname); + if (arrayfieldindex) + { + struct stoken stringsval; + stringsval.ptr = alloca (strlen (arrayname) + 1); + stringsval.length = strlen (arrayname); + strcpy (stringsval.ptr, arrayname); + current_type = TYPE_FIELD_TYPE (current_type, + arrayfieldindex - 1); + write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (stringsval); + write_exp_elt_opcode (STRUCTOP_STRUCT); + } + push_current_type (); } + break; + + case 18: +#line 320 "p-exp.y" + { pop_current_type (); + write_exp_elt_opcode (BINOP_SUBSCRIPT); + if (current_type) + current_type = TYPE_TARGET_TYPE (current_type); } + break; + + case 19: +#line 329 "p-exp.y" + { push_current_type (); + start_arglist (); } + break; + + case 20: +#line 332 "p-exp.y" + { write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) end_arglist ()); + write_exp_elt_opcode (OP_FUNCALL); + pop_current_type (); } + break; + + case 22: +#line 340 "p-exp.y" + { arglist_len = 1; } + break; + + case 23: +#line 342 "p-exp.y" + { arglist_len++; } + break; + + case 24: +#line 346 "p-exp.y" + { if (current_type) + { + /* Allow automatic dereference of classes. */ + if ((TYPE_CODE (current_type) == TYPE_CODE_PTR) + && (TYPE_CODE (TYPE_TARGET_TYPE (current_type)) == TYPE_CODE_CLASS) + && (TYPE_CODE (yyvsp[-3].tval) == TYPE_CODE_CLASS)) + write_exp_elt_opcode (UNOP_IND); + } + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (yyvsp[-3].tval); + write_exp_elt_opcode (UNOP_CAST); + current_type = yyvsp[-3].tval; } + break; + + case 25: +#line 361 "p-exp.y" + { } + break; + + case 26: +#line 367 "p-exp.y" + { write_exp_elt_opcode (BINOP_MUL); } + break; + + case 27: +#line 371 "p-exp.y" + { write_exp_elt_opcode (BINOP_DIV); } + break; + + case 28: +#line 375 "p-exp.y" + { write_exp_elt_opcode (BINOP_INTDIV); } + break; + + case 29: +#line 379 "p-exp.y" + { write_exp_elt_opcode (BINOP_REM); } + break; + + case 30: +#line 383 "p-exp.y" + { write_exp_elt_opcode (BINOP_ADD); } + break; + + case 31: +#line 387 "p-exp.y" + { write_exp_elt_opcode (BINOP_SUB); } + break; + + case 32: +#line 391 "p-exp.y" + { write_exp_elt_opcode (BINOP_LSH); } + break; + + case 33: +#line 395 "p-exp.y" + { write_exp_elt_opcode (BINOP_RSH); } + break; + + case 34: +#line 399 "p-exp.y" + { write_exp_elt_opcode (BINOP_EQUAL); } + break; + + case 35: +#line 403 "p-exp.y" + { write_exp_elt_opcode (BINOP_NOTEQUAL); } + break; + + case 36: +#line 407 "p-exp.y" + { write_exp_elt_opcode (BINOP_LEQ); } + break; + + case 37: +#line 411 "p-exp.y" + { write_exp_elt_opcode (BINOP_GEQ); } + break; + + case 38: +#line 415 "p-exp.y" + { write_exp_elt_opcode (BINOP_LESS); } + break; + + case 39: +#line 419 "p-exp.y" + { write_exp_elt_opcode (BINOP_GTR); } + break; + + case 40: +#line 423 "p-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_AND); } + break; + + case 41: +#line 427 "p-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + break; + + case 42: +#line 431 "p-exp.y" + { write_exp_elt_opcode (BINOP_BITWISE_IOR); } + break; + + case 43: +#line 435 "p-exp.y" + { write_exp_elt_opcode (BINOP_ASSIGN); } + break; + + case 44: +#line 439 "p-exp.y" + { write_exp_elt_opcode (OP_BOOL); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_BOOL); } + break; + + case 45: +#line 445 "p-exp.y" + { write_exp_elt_opcode (OP_BOOL); + write_exp_elt_longcst ((LONGEST) yyvsp[0].lval); + write_exp_elt_opcode (OP_BOOL); } + break; + + case 46: +#line 451 "p-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (yyvsp[0].typed_val_int.type); + write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 47: +#line 458 "p-exp.y" + { YYSTYPE val; + parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (val.typed_val_int.type); + write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); + write_exp_elt_opcode (OP_LONG); + } + break; + + case 48: +#line 469 "p-exp.y" + { write_exp_elt_opcode (OP_DOUBLE); + write_exp_elt_type (yyvsp[0].typed_val_float.type); + write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval); + write_exp_elt_opcode (OP_DOUBLE); } + break; + + case 51: +#line 483 "p-exp.y" + { write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_int); + CHECK_TYPEDEF (yyvsp[-1].tval); + write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval)); + write_exp_elt_opcode (OP_LONG); } + break; + + case 52: +#line 491 "p-exp.y" + { /* C strings are converted into array constants with + an explicit null byte added at the end. Thus + the array upper bound is the string length. + There is no such thing in C as a completely empty + string. */ + char *sp = yyvsp[0].sval.ptr; int count = yyvsp[0].sval.length; + while (count-- > 0) + { + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)(*sp++)); + write_exp_elt_opcode (OP_LONG); + } + write_exp_elt_opcode (OP_LONG); + write_exp_elt_type (builtin_type_char); + write_exp_elt_longcst ((LONGEST)'\0'); + write_exp_elt_opcode (OP_LONG); + write_exp_elt_opcode (OP_ARRAY); + write_exp_elt_longcst ((LONGEST) 0); + write_exp_elt_longcst ((LONGEST) (yyvsp[0].sval.length)); + write_exp_elt_opcode (OP_ARRAY); } + break; + + case 53: +#line 516 "p-exp.y" + { + struct value * this_val; + struct type * this_type; + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (OP_THIS); + /* we need type of this */ + this_val = value_of_this (0); + if (this_val) + this_type = this_val->type; + else + this_type = NULL; + if (this_type) + { + if (TYPE_CODE (this_type) == TYPE_CODE_PTR) + { + this_type = TYPE_TARGET_TYPE (this_type); + write_exp_elt_opcode (UNOP_IND); + } + } + + current_type = this_type; + } + break; + + case 54: +#line 543 "p-exp.y" + { + if (yyvsp[0].ssym.sym != 0) + yyval.bval = SYMBOL_BLOCK_VALUE (yyvsp[0].ssym.sym); + else + { + struct symtab *tem = + lookup_symtab (copy_name (yyvsp[0].ssym.stoken)); + if (tem) + yyval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK); + else + error ("No file or function \"%s\".", + copy_name (yyvsp[0].ssym.stoken)); + } + } + break; + + case 55: +#line 560 "p-exp.y" + { struct symbol *tem + = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) + error ("No function \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + yyval.bval = SYMBOL_BLOCK_VALUE (tem); } + break; + + case 56: +#line 571 "p-exp.y" + { struct symbol *sym; + sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym == 0) + error ("No symbol \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + + write_exp_elt_opcode (OP_VAR_VALUE); + /* block_found is set by lookup_symbol. */ + write_exp_elt_block (block_found); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); } + break; + + case 57: +#line 587 "p-exp.y" + { + struct type *type = yyvsp[-2].tval; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + write_exp_elt_opcode (OP_SCOPE); + write_exp_elt_type (type); + write_exp_string (yyvsp[0].sval); + write_exp_elt_opcode (OP_SCOPE); + } + break; + + case 59: +#line 603 "p-exp.y" + { + char *name = copy_name (yyvsp[0].sval); + struct symbol *sym; + struct minimal_symbol *msymbol; + + sym = + lookup_symbol (name, (const struct block *) NULL, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (sym) + { + write_exp_elt_opcode (OP_VAR_VALUE); + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + break; + } + + msymbol = lookup_minimal_symbol (name, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", name); + } + break; + + case 60: +#line 637 "p-exp.y" + { struct symbol *sym = yyvsp[0].ssym.sym; + + if (sym) + { + if (symbol_read_needs_frame (sym)) + { + if (innermost_block == 0 || + contained_in (block_found, + innermost_block)) + innermost_block = block_found; + } + + write_exp_elt_opcode (OP_VAR_VALUE); + /* We want to use the selected frame, not + another more inner frame which happens to + be in the same block. */ + write_exp_elt_block (NULL); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_VALUE); + current_type = sym->type; } + else if (yyvsp[0].ssym.is_a_field_of_this) + { + struct value * this_val; + struct type * this_type; + /* Object pascal: it hangs off of `this'. Must + not inadvertently convert from a method call + to data ref. */ + if (innermost_block == 0 || + contained_in (block_found, innermost_block)) + innermost_block = block_found; + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string (yyvsp[0].ssym.stoken); + write_exp_elt_opcode (STRUCTOP_PTR); + /* we need type of this */ + this_val = value_of_this (0); + if (this_val) + this_type = this_val->type; + else + this_type = NULL; + if (this_type) + current_type = lookup_struct_elt_type ( + this_type, + copy_name (yyvsp[0].ssym.stoken), 0); + else + current_type = NULL; + } + else + { + struct minimal_symbol *msymbol; + char *arg = copy_name (yyvsp[0].ssym.stoken); + + msymbol = + lookup_minimal_symbol (arg, NULL, NULL); + if (msymbol != NULL) + { + write_exp_msymbol (msymbol, + lookup_function_type (builtin_type_int), + builtin_type_int); + } + else if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + else + error ("No symbol \"%s\" in current context.", + copy_name (yyvsp[0].ssym.stoken)); + } + } + break; + + case 63: +#line 721 "p-exp.y" + { yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); } + break; + + case 64: +#line 726 "p-exp.y" + { yyval.tval = lookup_pointer_type (yyvsp[0].tval); } + break; + + case 65: +#line 728 "p-exp.y" + { yyval.tval = yyvsp[0].tsym.type; } + break; + + case 66: +#line 730 "p-exp.y" + { yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 67: +#line 733 "p-exp.y" + { yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), + expression_context_block); } + break; + + case 68: +#line 740 "p-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + case 69: +#line 741 "p-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + case 70: +#line 742 "p-exp.y" + { yyval.sval = yyvsp[0].tsym.stoken; } + break; + + case 71: +#line 743 "p-exp.y" + { yyval.sval = yyvsp[0].ssym.stoken; } + break; + + + } + +/* Line 991 of yacc.c. */ + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. Doesn't work in C++ */ +#ifndef __cplusplus +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 757 "p-exp.y" + + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. + LEN is the number of characters in it. */ + +/*** Needs some error checking for the float case ***/ + +static int +parse_number (p, len, parsed_float, putithere) + char *p; + int len; + int parsed_float; + YYSTYPE *putithere; +{ + /* FIXME: Shouldn't these be unsigned? We don't deal with negative values + here, and we do kind of silly things like cast to unsigned. */ + LONGEST n = 0; + LONGEST prevn = 0; + ULONGEST un; + + int i = 0; + int c; + int base = input_radix; + int unsigned_p = 0; + + /* Number of "L" suffixes encountered. */ + int long_p = 0; + + /* We have found a "L" or "U" suffix. */ + int found_suffix = 0; + + ULONGEST high_bit; + struct type *signed_type; + struct type *unsigned_type; + + if (parsed_float) + { + /* It's a float since it contains a point or an exponent. */ + char c; + int num = 0; /* number of tokens scanned by scanf */ + char saved_char = p[len]; + + p[len] = 0; /* null-terminate the token */ + if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) + num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c); + else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) + num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c); + else + { +#ifdef SCANF_HAS_LONG_DOUBLE + num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c); +#else + /* Scan it into a double, then assign it to the long double. + This at least wins with values representable in the range + of doubles. */ + double temp; + num = sscanf (p, "%lg%c", &temp,&c); + putithere->typed_val_float.dval = temp; +#endif + } + p[len] = saved_char; /* restore the input stream */ + if (num != 1) /* check scanf found ONLY a float ... */ + return ERROR; + /* See if it has `f' or `l' suffix (float or long double). */ + + c = tolower (p[len - 1]); + + if (c == 'f') + putithere->typed_val_float.type = builtin_type_float; + else if (c == 'l') + putithere->typed_val_float.type = builtin_type_long_double; + else if (isdigit (c) || c == '.') + putithere->typed_val_float.type = builtin_type_double; + else + return ERROR; + + return FLOAT; + } + + /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ + if (p[0] == '0') + switch (p[1]) + { + case 'x': + case 'X': + if (len >= 3) + { + p += 2; + base = 16; + len -= 2; + } + break; + + case 't': + case 'T': + case 'd': + case 'D': + if (len >= 3) + { + p += 2; + base = 10; + len -= 2; + } + break; + + default: + base = 8; + break; + } + + while (len-- > 0) + { + c = *p++; + if (c >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != 'l' && c != 'u') + n *= base; + if (c >= '0' && c <= '9') + { + if (found_suffix) + return ERROR; + n += i = c - '0'; + } + else + { + if (base > 10 && c >= 'a' && c <= 'f') + { + if (found_suffix) + return ERROR; + n += i = c - 'a' + 10; + } + else if (c == 'l') + { + ++long_p; + found_suffix = 1; + } + else if (c == 'u') + { + unsigned_p = 1; + found_suffix = 1; + } + else + return ERROR; /* Char not a digit */ + } + if (i >= base) + return ERROR; /* Invalid digit in this base */ + + /* Portably test for overflow (only works for nonzero values, so make + a second check for zero). FIXME: Can't we just make n and prevn + unsigned and avoid this? */ + if (c != 'l' && c != 'u' && (prevn >= n) && n != 0) + unsigned_p = 1; /* Try something unsigned */ + + /* Portably test for unsigned overflow. + FIXME: This check is wrong; for example it doesn't find overflow + on 0x123456789 when LONGEST is 32 bits. */ + if (c != 'l' && c != 'u' && n != 0) + { + if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n)) + error ("Numeric constant too large."); + } + prevn = n; + } + + /* An integer constant is an int, a long, or a long long. An L + suffix forces it to be long; an LL suffix forces it to be long + long. If not forced to a larger size, it gets the first type of + the above that it fits in. To figure out whether it fits, we + shift it right and see whether anything remains. Note that we + can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one + operation, because many compilers will warn about such a shift + (which always produces a zero result). Sometimes TARGET_INT_BIT + or TARGET_LONG_BIT will be that big, sometimes not. To deal with + the case where it is we just always shift the value more than + once, with fewer bits each time. */ + + un = (ULONGEST)n >> 2; + if (long_p == 0 + && (un >> (TARGET_INT_BIT - 2)) == 0) + { + high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1); + + /* A large decimal (not hex or octal) constant (between INT_MAX + and UINT_MAX) is a long or unsigned long, according to ANSI, + never an unsigned int, but this code treats it as unsigned + int. This probably should be fixed. GCC gives a warning on + such constants. */ + + unsigned_type = builtin_type_unsigned_int; + signed_type = builtin_type_int; + } + else if (long_p <= 1 + && (un >> (TARGET_LONG_BIT - 2)) == 0) + { + high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1); + unsigned_type = builtin_type_unsigned_long; + signed_type = builtin_type_long; + } + else + { + int shift; + if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT) + /* A long long does not fit in a LONGEST. */ + shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1); + else + shift = (TARGET_LONG_LONG_BIT - 1); + high_bit = (ULONGEST) 1 << shift; + unsigned_type = builtin_type_unsigned_long_long; + signed_type = builtin_type_long_long; + } + + putithere->typed_val_int.val = n; + + /* If the high bit of the worked out type is set then this number + has to be unsigned. */ + + if (unsigned_p || (n & high_bit)) + { + putithere->typed_val_int.type = unsigned_type; + } + else + { + putithere->typed_val_int.type = signed_type; + } + + return INT; +} + + +struct type_push +{ + struct type *stored; + struct type_push *next; +}; + +static struct type_push *tp_top = NULL; + +static void +push_current_type (void) +{ + struct type_push *tpnew; + tpnew = (struct type_push *) xmalloc (sizeof (struct type_push)); + tpnew->next = tp_top; + tpnew->stored = current_type; + current_type = NULL; + tp_top = tpnew; +} + +static void +pop_current_type (void) +{ + struct type_push *tp = tp_top; + if (tp) + { + current_type = tp->stored; + tp_top = tp->next; + xfree (tp); + } +} + +struct token +{ + char *operator; + int token; + enum exp_opcode opcode; +}; + +static const struct token tokentab3[] = + { + {"shr", RSH, BINOP_END}, + {"shl", LSH, BINOP_END}, + {"and", ANDAND, BINOP_END}, + {"div", DIV, BINOP_END}, + {"not", NOT, BINOP_END}, + {"mod", MOD, BINOP_END}, + {"inc", INCREMENT, BINOP_END}, + {"dec", DECREMENT, BINOP_END}, + {"xor", XOR, BINOP_END} + }; + +static const struct token tokentab2[] = + { + {"or", OR, BINOP_END}, + {"<>", NOTEQUAL, BINOP_END}, + {"<=", LEQ, BINOP_END}, + {">=", GEQ, BINOP_END}, + {":=", ASSIGN, BINOP_END}, + {"::", COLONCOLON, BINOP_END} }; + +/* Allocate uppercased var */ +/* make an uppercased copy of tokstart */ +static char * uptok (tokstart, namelen) + char *tokstart; + int namelen; +{ + int i; + char *uptokstart = (char *)xmalloc(namelen+1); + for (i = 0;i <= namelen;i++) + { + if ((tokstart[i]>='a' && tokstart[i]<='z')) + uptokstart[i] = tokstart[i]-('a'-'A'); + else + uptokstart[i] = tokstart[i]; + } + uptokstart[namelen]='\0'; + return uptokstart; +} +/* Read one token, getting characters through lexptr. */ + + +static int +yylex () +{ + int c; + int namelen; + unsigned int i; + char *tokstart; + char *uptokstart; + char *tokptr; + char *p; + int explen, tempbufindex; + static char *tempbuf; + static int tempbufsize; + + retry: + + prev_lexptr = lexptr; + + tokstart = lexptr; + explen = strlen (lexptr); + /* See if it is a special token of length 3. */ + if (explen > 2) + for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++) + if (strncasecmp (tokstart, tokentab3[i].operator, 3) == 0 + && (!isalpha (tokentab3[i].operator[0]) || explen == 3 + || (!isalpha (tokstart[3]) && !isdigit (tokstart[3]) && tokstart[3] != '_'))) + { + lexptr += 3; + yylval.opcode = tokentab3[i].opcode; + return tokentab3[i].token; + } + + /* See if it is a special token of length 2. */ + if (explen > 1) + for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++) + if (strncasecmp (tokstart, tokentab2[i].operator, 2) == 0 + && (!isalpha (tokentab2[i].operator[0]) || explen == 2 + || (!isalpha (tokstart[2]) && !isdigit (tokstart[2]) && tokstart[2] != '_'))) + { + lexptr += 2; + yylval.opcode = tokentab2[i].opcode; + return tokentab2[i].token; + } + + switch (c = *tokstart) + { + case 0: + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '\'': + /* We either have a character constant ('0' or '\177' for example) + or we have a quoted symbol reference ('foo(int,int)' in object pascal + for example). */ + lexptr++; + c = *lexptr++; + if (c == '\\') + c = parse_escape (&lexptr); + else if (c == '\'') + error ("Empty character constant."); + + yylval.typed_val_int.val = c; + yylval.typed_val_int.type = builtin_type_char; + + c = *lexptr++; + if (c != '\'') + { + namelen = skip_quoted (tokstart) - tokstart; + if (namelen > 2) + { + lexptr = tokstart + namelen; + if (lexptr[-1] != '\'') + error ("Unmatched single quote."); + namelen -= 2; + tokstart++; + uptokstart = uptok(tokstart,namelen); + goto tryname; + } + error ("Invalid character constant."); + } + return INT; + + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return c; + + case '.': + /* Might be a floating point number. */ + if (lexptr[1] < '0' || lexptr[1] > '9') + goto symbol; /* Nope, must be a symbol. */ + /* FALL THRU into number case. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + /* It's a number. */ + int got_dot = 0, got_e = 0, toktype; + char *p = tokstart; + int hex = input_radix > 10; + + if (c == '0' && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + hex = 1; + } + else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) + { + p += 2; + hex = 0; + } + + for (;; ++p) + { + /* This test includes !hex because 'e' is a valid hex digit + and thus does not indicate a floating point number when + the radix is hex. */ + if (!hex && !got_e && (*p == 'e' || *p == 'E')) + got_dot = got_e = 1; + /* This test does not include !hex, because a '.' always indicates + a decimal floating point number regardless of the radix. */ + else if (!got_dot && *p == '.') + got_dot = 1; + else if (got_e && (p[-1] == 'e' || p[-1] == 'E') + && (*p == '-' || *p == '+')) + /* This is the sign of the exponent, not the end of the + number. */ + continue; + /* We will take any letters or digits. parse_number will + complain if past the radix, or if L or U are not final. */ + else if ((*p < '0' || *p > '9') + && ((*p < 'a' || *p > 'z') + && (*p < 'A' || *p > 'Z'))) + break; + } + toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval); + if (toktype == ERROR) + { + char *err_copy = (char *) alloca (p - tokstart + 1); + + memcpy (err_copy, tokstart, p - tokstart); + err_copy[p - tokstart] = 0; + error ("Invalid number \"%s\".", err_copy); + } + lexptr = p; + return toktype; + } + + case '+': + case '-': + case '*': + case '/': + case '|': + case '&': + case '^': + case '~': + case '!': + case '@': + case '<': + case '>': + case '[': + case ']': + case '?': + case ':': + case '=': + case '{': + case '}': + symbol: + lexptr++; + return c; + + case '"': + + /* Build the gdb internal form of the input string in tempbuf, + translating any standard C escape forms seen. Note that the + buffer is null byte terminated *only* for the convenience of + debugging gdb itself and printing the buffer contents when + the buffer contains no embedded nulls. Gdb does not depend + upon the buffer being null byte terminated, it uses the length + string instead. This allows gdb to handle C strings (as well + as strings in other languages) with embedded null bytes */ + + tokptr = ++tokstart; + tempbufindex = 0; + + do { + /* Grow the static temp buffer if necessary, including allocating + the first one on demand. */ + if (tempbufindex + 1 >= tempbufsize) + { + tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64); + } + + switch (*tokptr) + { + case '\0': + case '"': + /* Do nothing, loop will terminate. */ + break; + case '\\': + tokptr++; + c = parse_escape (&tokptr); + if (c == -1) + { + continue; + } + tempbuf[tempbufindex++] = c; + break; + default: + tempbuf[tempbufindex++] = *tokptr++; + break; + } + } while ((*tokptr != '"') && (*tokptr != '\0')); + if (*tokptr++ != '"') + { + error ("Unterminated string in expression."); + } + tempbuf[tempbufindex] = '\0'; /* See note above */ + yylval.sval.ptr = tempbuf; + yylval.sval.length = tempbufindex; + lexptr = tokptr; + return (STRING); + } + + if (!(c == '_' || c == '$' + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + /* We must have come across a bad character (e.g. ';'). */ + error ("Invalid character '%c' in expression.", c); + + /* It's a name. See how long it is. */ + namelen = 0; + for (c = tokstart[namelen]; + (c == '_' || c == '$' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) + { + /* Template parameter lists are part of the name. + FIXME: This mishandles `print $a<4&&$a>3'. */ + if (c == '<') + { + int i = namelen; + int nesting_level = 1; + while (tokstart[++i]) + { + if (tokstart[i] == '<') + nesting_level++; + else if (tokstart[i] == '>') + { + if (--nesting_level == 0) + break; + } + } + if (tokstart[i] == '>') + namelen = i; + else + break; + } + + /* do NOT uppercase internals because of registers !!! */ + c = tokstart[++namelen]; + } + + uptokstart = uptok(tokstart,namelen); + + /* The token "if" terminates the expression and is NOT + removed from the input stream. */ + if (namelen == 2 && uptokstart[0] == 'I' && uptokstart[1] == 'F') + { + return 0; + } + + lexptr += namelen; + + tryname: + + /* Catch specific keywords. Should be done with a data structure. */ + switch (namelen) + { + case 6: + if (DEPRECATED_STREQ (uptokstart, "OBJECT")) + return CLASS; + if (DEPRECATED_STREQ (uptokstart, "RECORD")) + return STRUCT; + if (DEPRECATED_STREQ (uptokstart, "SIZEOF")) + return SIZEOF; + break; + case 5: + if (DEPRECATED_STREQ (uptokstart, "CLASS")) + return CLASS; + if (DEPRECATED_STREQ (uptokstart, "FALSE")) + { + yylval.lval = 0; + return FALSEKEYWORD; + } + break; + case 4: + if (DEPRECATED_STREQ (uptokstart, "TRUE")) + { + yylval.lval = 1; + return TRUEKEYWORD; + } + if (DEPRECATED_STREQ (uptokstart, "SELF")) + { + /* here we search for 'this' like + inserted in FPC stabs debug info */ + static const char this_name[] = "this"; + + if (lookup_symbol (this_name, expression_context_block, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL)) + return THIS; + } + break; + default: + break; + } + + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + if (*tokstart == '$') + { + /* $ is the normal prefix for pascal hexadecimal values + but this conflicts with the GDB use for debugger variables + so in expression to enter hexadecimal values + we still need to use C syntax with 0xff */ + write_dollar_variable (yylval.sval); + return VARIABLE; + } + + /* Use token-type BLOCKNAME for symbols that happen to be defined as + functions or symtabs. If this is not so, then ... + Use token-type TYPENAME for symbols that happen to be defined + currently as names of types; NAME for other symbols. + The caller is not constrained to care about the distinction. */ + { + char *tmp = copy_name (yylval.sval); + struct symbol *sym; + int is_a_field_of_this = 0; + int is_a_field = 0; + int hextype; + + + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + &is_a_field_of_this, + (struct symtab **) NULL); + /* second chance uppercased (as Free Pascal does). */ + if (!sym && !is_a_field_of_this && !is_a_field) + { + for (i = 0; i <= namelen; i++) + { + if ((tmp[i] >= 'a' && tmp[i] <= 'z')) + tmp[i] -= ('a'-'A'); + } + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + &is_a_field_of_this, + (struct symtab **) NULL); + if (sym || is_a_field_of_this || is_a_field) + for (i = 0; i <= namelen; i++) + { + if ((tokstart[i] >= 'a' && tokstart[i] <= 'z')) + tokstart[i] -= ('a'-'A'); + } + } + /* Third chance Capitalized (as GPC does). */ + if (!sym && !is_a_field_of_this && !is_a_field) + { + for (i = 0; i <= namelen; i++) + { + if (i == 0) + { + if ((tmp[i] >= 'a' && tmp[i] <= 'z')) + tmp[i] -= ('a'-'A'); + } + else + if ((tmp[i] >= 'A' && tmp[i] <= 'Z')) + tmp[i] -= ('A'-'a'); + } + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + &is_a_field_of_this, + (struct symtab **) NULL); + if (sym || is_a_field_of_this || is_a_field) + for (i = 0; i <= namelen; i++) + { + if (i == 0) + { + if ((tokstart[i] >= 'a' && tokstart[i] <= 'z')) + tokstart[i] -= ('a'-'A'); + } + else + if ((tokstart[i] >= 'A' && tokstart[i] <= 'Z')) + tokstart[i] -= ('A'-'a'); + } + } + + if (is_a_field) + { + tempbuf = (char *) xrealloc (tempbuf, namelen + 1); + strncpy (tempbuf, tokstart, namelen); tempbuf [namelen] = 0; + yylval.sval.ptr = tempbuf; + yylval.sval.length = namelen; + return FIELDNAME; + } + /* Call lookup_symtab, not lookup_partial_symtab, in case there are + no psymtabs (coff, xcoff, or some future change to blow away the + psymtabs once once symbols are read). */ + if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) || + lookup_symtab (tmp)) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return BLOCKNAME; + } + if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + { +#if 1 + /* Despite the following flaw, we need to keep this code enabled. + Because we can get called from check_stub_method, if we don't + handle nested types then it screws many operations in any + program which uses nested types. */ + /* In "A::x", if x is a member function of A and there happens + to be a type (nested or not, since the stabs don't make that + distinction) named x, then this code incorrectly thinks we + are dealing with nested types rather than a member function. */ + + char *p; + char *namestart; + struct symbol *best_sym; + + /* Look ahead to detect nested types. This probably should be + done in the grammar, but trying seemed to introduce a lot + of shift/reduce and reduce/reduce conflicts. It's possible + that it could be done, though. Or perhaps a non-grammar, but + less ad hoc, approach would work well. */ + + /* Since we do not currently have any way of distinguishing + a nested type from a non-nested one (the stabs don't tell + us whether a type is nested), we just ignore the + containing type. */ + + p = lexptr; + best_sym = sym; + while (1) + { + /* Skip whitespace. */ + while (*p == ' ' || *p == '\t' || *p == '\n') + ++p; + if (*p == ':' && p[1] == ':') + { + /* Skip the `::'. */ + p += 2; + /* Skip whitespace. */ + while (*p == ' ' || *p == '\t' || *p == '\n') + ++p; + namestart = p; + while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9') + || (*p >= 'a' && *p <= 'z') + || (*p >= 'A' && *p <= 'Z')) + ++p; + if (p != namestart) + { + struct symbol *cur_sym; + /* As big as the whole rest of the expression, which is + at least big enough. */ + char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3); + char *tmp1; + + tmp1 = ncopy; + memcpy (tmp1, tmp, strlen (tmp)); + tmp1 += strlen (tmp); + memcpy (tmp1, "::", 2); + tmp1 += 2; + memcpy (tmp1, namestart, p - namestart); + tmp1[p - namestart] = '\0'; + cur_sym = lookup_symbol (ncopy, expression_context_block, + VAR_DOMAIN, (int *) NULL, + (struct symtab **) NULL); + if (cur_sym) + { + if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) + { + best_sym = cur_sym; + lexptr = p; + } + else + break; + } + else + break; + } + else + break; + } + else + break; + } + + yylval.tsym.type = SYMBOL_TYPE (best_sym); +#else /* not 0 */ + yylval.tsym.type = SYMBOL_TYPE (sym); +#endif /* not 0 */ + return TYPENAME; + } + if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) + return TYPENAME; + + /* Input names that aren't symbols but ARE valid hex numbers, + when the input radix permits them, can be names or numbers + depending on the parse. Note we support radixes > 16 here. */ + if (!sym && + ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || + (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) + { + YYSTYPE newlval; /* Its value is ignored. */ + hextype = parse_number (tokstart, namelen, 0, &newlval); + if (hextype == INT) + { + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME_OR_INT; + } + } + + free(uptokstart); + /* Any other kind of symbol */ + yylval.ssym.sym = sym; + yylval.ssym.is_a_field_of_this = is_a_field_of_this; + return NAME; + } +} + +void +yyerror (msg) + char *msg; +{ + if (prev_lexptr) + lexptr = prev_lexptr; + + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); +} + + diff --git a/contrib/gdb/gdb/p-exp.y b/contrib/gdb/gdb/p-exp.y index b0e4daa4040..779424e90d5 100644 --- a/contrib/gdb/gdb/p-exp.y +++ b/contrib/gdb/gdb/p-exp.y @@ -37,8 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ too messy, particularly when such includes can be inserted at random times by the parser generator. */ -/* FIXME: there are still 21 shift/reduce conflicts - Other known bugs or limitations: +/* Known bugs or limitations: - pascal string operations are not supported at all. - there are some problems with boolean types. - Pascal type hexadecimal constants are not supported @@ -57,6 +56,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" /* Required by objfiles.h. */ #include "symfile.h" /* Required by objfiles.h. */ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ +#include "block.h" /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), as well as gratuitiously global symbol names, so we can have multiple @@ -94,6 +94,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yylloc pascal_lloc #define yyreds pascal_reds /* With YYDEBUG defined */ #define yytoks pascal_toks /* With YYDEBUG defined */ +#define yyname pascal_name /* With YYDEBUG defined */ +#define yyrule pascal_rule /* With YYDEBUG defined */ #define yylhs pascal_yylhs #define yylen pascal_yylen #define yydefred pascal_yydefred @@ -105,9 +107,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yycheck pascal_yycheck #ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ +#define YYDEBUG 1 /* Default to yydebug support */ #endif +#define YYFPRINTF parser_fprintf + int yyparse (void); static int yylex (void); @@ -151,9 +155,15 @@ static char * uptok (char *, int); /* YYSTYPE gets defined by %union */ static int parse_number (char *, int, int, YYSTYPE *); + +static struct type *current_type; + +static void push_current_type (void); +static void pop_current_type (void); +static int search_field; %} -%type exp exp1 type_exp start variable qualified_name +%type exp exp1 type_exp start normal_start variable qualified_name %type type typebase /* %type block */ @@ -171,7 +181,8 @@ parse_number (char *, int, int, YYSTYPE *); Contexts where this distinction is not important can use the nonterminal "name", which matches either NAME or TYPENAME. */ -%token STRING +%token STRING +%token FIELDNAME %token NAME /* BLOCKNAME defined below to give it higher precedence. */ %token TYPENAME %type name @@ -195,7 +206,7 @@ parse_number (char *, int, int, YYSTYPE *); /* Object pascal */ %token THIS -%token TRUE FALSE +%token TRUEKEYWORD FALSEKEYWORD %left ',' %left ABOVE_COMMA @@ -212,6 +223,7 @@ parse_number (char *, int, int, YYSTYPE *); %left '*' '/' %right UNARY INCREMENT DECREMENT %right ARROW '.' '[' '(' +%left '^' %token BLOCKNAME %type block %left COLONCOLON @@ -219,15 +231,22 @@ parse_number (char *, int, int, YYSTYPE *); %% -start : exp1 +start : { current_type = NULL; + search_field = 0; + } + normal_start {} + ; + +normal_start : + exp1 | type_exp ; type_exp: type { write_exp_elt_opcode(OP_TYPE); write_exp_elt_type($1); - write_exp_elt_opcode(OP_TYPE);} - ; + write_exp_elt_opcode(OP_TYPE); + current_type = $1; } ; /* Expressions, including the comma operator. */ exp1 : exp @@ -237,10 +256,16 @@ exp1 : exp /* Expressions, not including the comma operator. */ exp : exp '^' %prec UNARY - { write_exp_elt_opcode (UNOP_IND); } + { write_exp_elt_opcode (UNOP_IND); + if (current_type) + current_type = TYPE_TARGET_TYPE (current_type); } + ; exp : '@' exp %prec UNARY - { write_exp_elt_opcode (UNOP_ADDR); } + { write_exp_elt_opcode (UNOP_ADDR); + if (current_type) + current_type = TYPE_POINTER_TYPE (current_type); } + ; exp : '-' exp %prec UNARY { write_exp_elt_opcode (UNOP_NEG); } @@ -258,24 +283,56 @@ exp : DECREMENT '(' exp ')' %prec UNARY { write_exp_elt_opcode (UNOP_PREDECREMENT); } ; -exp : exp '.' name +exp : exp '.' { search_field = 1; } + FIELDNAME + /* name */ { write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string ($3); - write_exp_elt_opcode (STRUCTOP_STRUCT); } - ; - -exp : exp '[' exp1 ']' - { write_exp_elt_opcode (BINOP_SUBSCRIPT); } + write_exp_string ($4); + write_exp_elt_opcode (STRUCTOP_STRUCT); + search_field = 0; + if (current_type) + { while (TYPE_CODE (current_type) == TYPE_CODE_PTR) + current_type = TYPE_TARGET_TYPE (current_type); + current_type = lookup_struct_elt_type ( + current_type, $4.ptr, 0); }; + } ; +exp : exp '[' + /* We need to save the current_type value */ + { char *arrayname; + int arrayfieldindex; + arrayfieldindex = is_pascal_string_type ( + current_type, NULL, NULL, + NULL, NULL, &arrayname); + if (arrayfieldindex) + { + struct stoken stringsval; + stringsval.ptr = alloca (strlen (arrayname) + 1); + stringsval.length = strlen (arrayname); + strcpy (stringsval.ptr, arrayname); + current_type = TYPE_FIELD_TYPE (current_type, + arrayfieldindex - 1); + write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string (stringsval); + write_exp_elt_opcode (STRUCTOP_STRUCT); + } + push_current_type (); } + exp1 ']' + { pop_current_type (); + write_exp_elt_opcode (BINOP_SUBSCRIPT); + if (current_type) + current_type = TYPE_TARGET_TYPE (current_type); } ; exp : exp '(' /* This is to save the value of arglist_len being accumulated by an outer function call. */ - { start_arglist (); } + { push_current_type (); + start_arglist (); } arglist ')' %prec ARROW { write_exp_elt_opcode (OP_FUNCALL); write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_FUNCALL); } + write_exp_elt_opcode (OP_FUNCALL); + pop_current_type (); } ; arglist : @@ -286,9 +343,18 @@ arglist : ; exp : type '(' exp ')' %prec UNARY - { write_exp_elt_opcode (UNOP_CAST); + { if (current_type) + { + /* Allow automatic dereference of classes. */ + if ((TYPE_CODE (current_type) == TYPE_CODE_PTR) + && (TYPE_CODE (TYPE_TARGET_TYPE (current_type)) == TYPE_CODE_CLASS) + && (TYPE_CODE ($1) == TYPE_CODE_CLASS)) + write_exp_elt_opcode (UNOP_IND); + } + write_exp_elt_opcode (UNOP_CAST); write_exp_elt_type ($1); - write_exp_elt_opcode (UNOP_CAST); } + write_exp_elt_opcode (UNOP_CAST); + current_type = $1; } ; exp : '(' exp1 ')' @@ -369,13 +435,13 @@ exp : exp ASSIGN exp { write_exp_elt_opcode (BINOP_ASSIGN); } ; -exp : TRUE +exp : TRUEKEYWORD { write_exp_elt_opcode (OP_BOOL); write_exp_elt_longcst ((LONGEST) $1); write_exp_elt_opcode (OP_BOOL); } ; -exp : FALSE +exp : FALSEKEYWORD { write_exp_elt_opcode (OP_BOOL); write_exp_elt_longcst ((LONGEST) $1); write_exp_elt_opcode (OP_BOOL); } @@ -447,8 +513,28 @@ exp : STRING /* Object pascal */ exp : THIS - { write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); } + { + struct value * this_val; + struct type * this_type; + write_exp_elt_opcode (OP_THIS); + write_exp_elt_opcode (OP_THIS); + /* we need type of this */ + this_val = value_of_this (0); + if (this_val) + this_type = this_val->type; + else + this_type = NULL; + if (this_type) + { + if (TYPE_CODE (this_type) == TYPE_CODE_PTR) + { + this_type = TYPE_TARGET_TYPE (this_type); + write_exp_elt_opcode (UNOP_IND); + } + } + + current_type = this_type; + } ; /* end of object pascal. */ @@ -473,7 +559,7 @@ block : BLOCKNAME block : block COLONCOLON name { struct symbol *tem = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) error ("No function \"%s\" in specified context.", @@ -484,7 +570,7 @@ block : block COLONCOLON name variable: block COLONCOLON name { struct symbol *sym; sym = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (sym == 0) error ("No symbol \"%s\" in specified context.", @@ -521,7 +607,7 @@ variable: qualified_name sym = lookup_symbol (name, (const struct block *) NULL, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (sym) { @@ -567,9 +653,11 @@ variable: name_not_typename write_exp_elt_block (NULL); write_exp_elt_sym (sym); write_exp_elt_opcode (OP_VAR_VALUE); - } + current_type = sym->type; } else if ($1.is_a_field_of_this) { + struct value * this_val; + struct type * this_type; /* Object pascal: it hangs off of `this'. Must not inadvertently convert from a method call to data ref. */ @@ -581,11 +669,23 @@ variable: name_not_typename write_exp_elt_opcode (STRUCTOP_PTR); write_exp_string ($1.stoken); write_exp_elt_opcode (STRUCTOP_PTR); + /* we need type of this */ + this_val = value_of_this (0); + if (this_val) + this_type = this_val->type; + else + this_type = NULL; + if (this_type) + current_type = lookup_struct_elt_type ( + this_type, + copy_name ($1.stoken), 0); + else + current_type = NULL; } else { struct minimal_symbol *msymbol; - register char *arg = copy_name ($1.stoken); + char *arg = copy_name ($1.stoken); msymbol = lookup_minimal_symbol (arg, NULL, NULL); @@ -622,7 +722,9 @@ type : ptype ; typebase /* Implements (approximately): (type-qualifier)* type-specifier */ - : TYPENAME + : '^' typebase + { $$ = lookup_pointer_type ($2); } + | TYPENAME { $$ = $1.type; } | STRUCT name { $$ = lookup_struct (copy_name ($2), @@ -662,20 +764,20 @@ name_not_typename : NAME static int parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; + char *p; + int len; int parsed_float; YYSTYPE *putithere; { /* FIXME: Shouldn't these be unsigned? We don't deal with negative values here, and we do kind of silly things like cast to unsigned. */ - register LONGEST n = 0; - register LONGEST prevn = 0; + LONGEST n = 0; + LONGEST prevn = 0; ULONGEST un; - register int i = 0; - register int c; - register int base = input_radix; + int i = 0; + int c; + int base = input_radix; int unsigned_p = 0; /* Number of "L" suffixes encountered. */ @@ -881,6 +983,38 @@ parse_number (p, len, parsed_float, putithere) return INT; } + +struct type_push +{ + struct type *stored; + struct type_push *next; +}; + +static struct type_push *tp_top = NULL; + +static void +push_current_type (void) +{ + struct type_push *tpnew; + tpnew = (struct type_push *) malloc (sizeof (struct type_push)); + tpnew->next = tp_top; + tpnew->stored = current_type; + current_type = NULL; + tp_top = tpnew; +} + +static void +pop_current_type (void) +{ + struct type_push *tp = tp_top; + if (tp) + { + current_type = tp->stored; + tp_top = tp->next; + xfree (tp); + } +} + struct token { char *operator; @@ -907,8 +1041,8 @@ static const struct token tokentab2[] = {"<>", NOTEQUAL, BINOP_END}, {"<=", LEQ, BINOP_END}, {">=", GEQ, BINOP_END}, - {":=", ASSIGN, BINOP_END} - }; + {":=", ASSIGN, BINOP_END}, + {"::", COLONCOLON, BINOP_END} }; /* Allocate uppercased var */ /* make an uppercased copy of tokstart */ @@ -947,6 +1081,8 @@ yylex () retry: + prev_lexptr = lexptr; + tokstart = lexptr; explen = strlen (lexptr); /* See if it is a special token of length 3. */ @@ -1053,7 +1189,7 @@ yylex () { /* It's a number. */ int got_dot = 0, got_e = 0, toktype; - register char *p = tokstart; + char *p = tokstart; int hex = input_radix > 10; if (c == '0' && (p[1] == 'x' || p[1] == 'X')) @@ -1147,6 +1283,7 @@ yylex () { tempbuf = (char *) realloc (tempbuf, tempbufsize += 64); } + switch (*tokptr) { case '\0': @@ -1232,37 +1369,36 @@ yylex () switch (namelen) { case 6: - if (STREQ (uptokstart, "OBJECT")) + if (DEPRECATED_STREQ (uptokstart, "OBJECT")) return CLASS; - if (STREQ (uptokstart, "RECORD")) + if (DEPRECATED_STREQ (uptokstart, "RECORD")) return STRUCT; - if (STREQ (uptokstart, "SIZEOF")) + if (DEPRECATED_STREQ (uptokstart, "SIZEOF")) return SIZEOF; break; case 5: - if (STREQ (uptokstart, "CLASS")) + if (DEPRECATED_STREQ (uptokstart, "CLASS")) return CLASS; - if (STREQ (uptokstart, "FALSE")) + if (DEPRECATED_STREQ (uptokstart, "FALSE")) { yylval.lval = 0; - return FALSE; + return FALSEKEYWORD; } break; case 4: - if (STREQ (uptokstart, "TRUE")) + if (DEPRECATED_STREQ (uptokstart, "TRUE")) { yylval.lval = 1; - return TRUE; + return TRUEKEYWORD; } - if (STREQ (uptokstart, "SELF")) + if (DEPRECATED_STREQ (uptokstart, "SELF")) { /* here we search for 'this' like inserted in FPC stabs debug info */ - static const char this_name[] = - { /* CPLUS_MARKER,*/ 't', 'h', 'i', 's', '\0' }; + static const char this_name[] = "this"; if (lookup_symbol (this_name, expression_context_block, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL)) return THIS; } @@ -1293,25 +1429,37 @@ yylex () char *tmp = copy_name (yylval.sval); struct symbol *sym; int is_a_field_of_this = 0; + int is_a_field = 0; int hextype; - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, - &is_a_field_of_this, - (struct symtab **) NULL); + + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, + &is_a_field_of_this, + (struct symtab **) NULL); /* second chance uppercased (as Free Pascal does). */ - if (!sym && !is_a_field_of_this) + if (!sym && !is_a_field_of_this && !is_a_field) { for (i = 0; i <= namelen; i++) { if ((tmp[i] >= 'a' && tmp[i] <= 'z')) tmp[i] -= ('a'-'A'); } - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, &is_a_field_of_this, (struct symtab **) NULL); - if (sym || is_a_field_of_this) + if (sym || is_a_field_of_this || is_a_field) for (i = 0; i <= namelen; i++) { if ((tokstart[i] >= 'a' && tokstart[i] <= 'z')) @@ -1319,7 +1467,7 @@ yylex () } } /* Third chance Capitalized (as GPC does). */ - if (!sym && !is_a_field_of_this) + if (!sym && !is_a_field_of_this && !is_a_field) { for (i = 0; i <= namelen; i++) { @@ -1332,11 +1480,16 @@ yylex () if ((tmp[i] >= 'A' && tmp[i] <= 'Z')) tmp[i] -= ('A'-'a'); } - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, + if (search_field && current_type) + is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL); + if (is_a_field) + sym = NULL; + else + sym = lookup_symbol (tmp, expression_context_block, + VAR_DOMAIN, &is_a_field_of_this, (struct symtab **) NULL); - if (sym || is_a_field_of_this) + if (sym || is_a_field_of_this || is_a_field) for (i = 0; i <= namelen; i++) { if (i == 0) @@ -1349,6 +1502,15 @@ yylex () tokstart[i] -= ('A'-'a'); } } + + if (is_a_field) + { + tempbuf = (char *) realloc (tempbuf, namelen + 1); + strncpy (tempbuf, tokstart, namelen); tempbuf [namelen] = 0; + yylval.sval.ptr = tempbuf; + yylval.sval.length = namelen; + return FIELDNAME; + } /* Call lookup_symtab, not lookup_partial_symtab, in case there are no psymtabs (coff, xcoff, or some future change to blow away the psymtabs once once symbols are read). */ @@ -1421,7 +1583,7 @@ yylex () memcpy (tmp1, namestart, p - namestart); tmp1[p - namestart] = '\0'; cur_sym = lookup_symbol (ncopy, expression_context_block, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (cur_sym) { @@ -1481,5 +1643,8 @@ void yyerror (msg) char *msg; { + if (prev_lexptr) + lexptr = prev_lexptr; + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); } diff --git a/contrib/gdb/gdb/p-lang.c b/contrib/gdb/gdb/p-lang.c index 62c8a641a7c..a4025322ca7 100644 --- a/contrib/gdb/gdb/p-lang.c +++ b/contrib/gdb/gdb/p-lang.c @@ -1,5 +1,5 @@ /* Pascal language support routines for GDB, the GNU debugger. - Copyright 2000, 2002 Free Software Foundation, Inc. + Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -20,6 +20,7 @@ /* This file is derived from c-lang.c */ #include "defs.h" +#include "gdb_string.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" @@ -27,6 +28,7 @@ #include "language.h" #include "p-lang.h" #include "valprint.h" +#include "value.h" #include extern void _initialize_pascal_language (void); @@ -44,7 +46,8 @@ extern void _initialize_pascal_language (void); but this does not happen for Free Pascal nor for GPC. */ int is_pascal_string_type (struct type *type,int *length_pos, - int * length_size, int *string_pos, int *char_size) + int *length_size, int *string_pos, int *char_size, + char **arrayname) { if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { @@ -54,11 +57,17 @@ is_pascal_string_type (struct type *type,int *length_pos, && strcmp (TYPE_FIELDS (type)[0].name, "length") == 0 && strcmp (TYPE_FIELDS (type)[1].name, "st") == 0) { - *length_pos = TYPE_FIELD_BITPOS (type, 0) / TARGET_CHAR_BIT; - *length_size = TYPE_FIELD_TYPE (type, 0)->length; - *string_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT; - *char_size = 1; - return 1; + if (length_pos) + *length_pos = TYPE_FIELD_BITPOS (type, 0) / TARGET_CHAR_BIT; + if (length_size) + *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)); + if (string_pos) + *string_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT; + if (char_size) + *char_size = 1; + if (arrayname) + *arrayname = TYPE_FIELDS (type)[1].name; + return 2; }; /* GNU pascal strings. */ /* Three fields: Capacity, length and schema$ or _p_schema. */ @@ -66,12 +75,18 @@ is_pascal_string_type (struct type *type,int *length_pos, && strcmp (TYPE_FIELDS (type)[0].name, "Capacity") == 0 && strcmp (TYPE_FIELDS (type)[1].name, "length") == 0) { - *length_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT; - *length_size = TYPE_FIELD_TYPE (type, 1)->length; - *string_pos = TYPE_FIELD_BITPOS (type, 2) / TARGET_CHAR_BIT; + if (length_pos) + *length_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT; + if (length_size) + *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 1)); + if (string_pos) + *string_pos = TYPE_FIELD_BITPOS (type, 2) / TARGET_CHAR_BIT; /* FIXME: how can I detect wide chars in GPC ?? */ - *char_size = 1; - return 1; + if (char_size) + *char_size = 1; + if (arrayname) + *arrayname = TYPE_FIELDS (type)[2].name; + return 3; }; } return 0; @@ -84,7 +99,7 @@ static void pascal_one_char (int, struct ui_file *, int *); In_quotes is reset to 0 if a char is written with #4 notation */ static void -pascal_one_char (register int c, struct ui_file *stream, int *in_quotes) +pascal_one_char (int c, struct ui_file *stream, int *in_quotes) { c &= 0xFF; /* Avoid sign bit follies */ @@ -117,7 +132,7 @@ static void pascal_emit_char (int c, struct ui_file *stream, int quoter); characters and strings is language specific. */ static void -pascal_emit_char (register int c, struct ui_file *stream, int quoter) +pascal_emit_char (int c, struct ui_file *stream, int quoter) { int in_quotes = 0; pascal_one_char (c, stream, &in_quotes); @@ -143,11 +158,10 @@ void pascal_printstr (struct ui_file *stream, char *string, unsigned int length, int width, int force_ellipses) { - register unsigned int i; + unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; - extern int inspect_it; /* If the string was not truncated due to `set print elements', and the last byte of it is a null, we don't print that, in traditional C @@ -260,7 +274,7 @@ pascal_printstr (struct ui_file *stream, char *string, unsigned int length, struct type * pascal_create_fundamental_type (struct objfile *objfile, int typeid) { - register struct type *type = NULL; + struct type *type = NULL; switch (typeid) { @@ -280,7 +294,7 @@ pascal_create_fundamental_type (struct objfile *objfile, int typeid) 0, "void", objfile); break; case FT_CHAR: - type = init_type (TYPE_CODE_INT, + type = init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT, 0, "char", objfile); break; @@ -437,9 +451,9 @@ const struct language_defn pascal_language_defn = range_check_on, type_check_on, case_sensitive_on, + &exp_descriptor_standard, pascal_parse, pascal_error, - evaluate_subexp_standard, pascal_printchar, /* Print a character constant */ pascal_printstr, /* Function to print string constant */ pascal_emit_char, /* Print a single char */ @@ -447,6 +461,11 @@ const struct language_defn pascal_language_defn = pascal_print_type, /* Print a type using appropriate syntax */ pascal_val_print, /* Print a value using appropriate syntax */ pascal_value_print, /* Print a top-level value */ + NULL, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ {"", "%", "b", ""}, /* Binary format info */ {"0%lo", "0", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -455,6 +474,7 @@ const struct language_defn pascal_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; diff --git a/contrib/gdb/gdb/p-lang.h b/contrib/gdb/gdb/p-lang.h index ca8a0a9de66..39eb0435f09 100644 --- a/contrib/gdb/gdb/p-lang.h +++ b/contrib/gdb/gdb/p-lang.h @@ -38,7 +38,8 @@ extern void pascal_type_print_method_args (char *, char *, /* These are in p-lang.c: */ -extern int is_pascal_string_type (struct type *, int *, int *, int *, int*); +extern int + is_pascal_string_type (struct type *, int *, int *, int *, int *, char **); extern void pascal_printchar (int, struct ui_file *); diff --git a/contrib/gdb/gdb/p-typeprint.c b/contrib/gdb/gdb/p-typeprint.c index f7fc3899ead..a8908b155d2 100644 --- a/contrib/gdb/gdb/p-typeprint.c +++ b/contrib/gdb/gdb/p-typeprint.c @@ -21,7 +21,7 @@ /* This file is derived from p-typeprint.c */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "bfd.h" /* Binary File Description */ #include "symtab.h" #include "gdbtypes.h" @@ -50,7 +50,7 @@ void pascal_print_type (struct type *type, char *varstring, struct ui_file *stream, int show, int level) { - register enum type_code code; + enum type_code code; int demangled_args; code = TYPE_CODE (type); @@ -139,8 +139,8 @@ void pascal_type_print_method_args (char *physname, char *methodname, struct ui_file *stream) { - int is_constructor = STREQN (physname, "__ct__", 6); - int is_destructor = STREQN (physname, "__dt__", 6); + int is_constructor = DEPRECATED_STREQN (physname, "__ct__", 6); + int is_destructor = DEPRECATED_STREQN (physname, "__dt__", 6); if (is_constructor || is_destructor) { @@ -440,9 +440,9 @@ void pascal_type_print_base (struct type *type, struct ui_file *stream, int show, int level) { - register int i; - register int len; - register int lastval; + int i; + int len; + int lastval; enum { s_none, s_public, s_private, s_protected @@ -460,8 +460,8 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show, /* void pointer */ if ((TYPE_CODE (type) == TYPE_CODE_PTR) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)) { - fprintf_filtered (stream, - TYPE_NAME (type) ? TYPE_NAME (type) : "pointer"); + fputs_filtered (TYPE_NAME (type) ? TYPE_NAME (type) : "pointer", + stream); return; } /* When SHOW is zero or less, and there is a valid type name, then always @@ -559,7 +559,7 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show, { QUIT; /* Don't print out virtual function table. */ - if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5) + if (DEPRECATED_STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5) && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; @@ -637,8 +637,8 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show, { char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); - int is_constructor = STREQN (physname, "__ct__", 6); - int is_destructor = STREQN (physname, "__dt__", 6); + int is_constructor = DEPRECATED_STREQN (physname, "__ct__", 6); + int is_destructor = DEPRECATED_STREQN (physname, "__dt__", 6); QUIT; if (TYPE_FN_FIELD_PROTECTED (f, j)) @@ -788,6 +788,14 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show, show - 1, level); break; + case TYPE_CODE_BITSTRING: + fputs_filtered ("BitString", stream); + break; + + case TYPE_CODE_STRING: + fputs_filtered ("String", stream); + break; + default: /* Handle types not explicitly handled by the other cases, such as fundamental types. For these, just print whatever diff --git a/contrib/gdb/gdb/p-valprint.c b/contrib/gdb/gdb/p-valprint.c index 0b89c727e88..eb92f77591c 100644 --- a/contrib/gdb/gdb/p-valprint.c +++ b/contrib/gdb/gdb/p-valprint.c @@ -1,5 +1,5 @@ /* Support for printing Pascal values for GDB, the GNU debugger. - Copyright 2000, 2001 + Copyright 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -21,7 +21,7 @@ /* This file is derived from c-valprint.c */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" @@ -60,7 +60,7 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { - register unsigned int i = 0; /* Number of characters printed */ + unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype; unsigned eltlen; @@ -141,7 +141,8 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset, /* 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 + embedded_offset, TYPE_LENGTH (type)), + /* Extract the address, assume that it is unsigned. */ + print_address_demangle (extract_unsigned_integer (valaddr + embedded_offset, TYPE_LENGTH (type)), stream, demangle); break; } @@ -190,8 +191,8 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset, as GDB does not recognize stabs pascal strings Pascal strings are mapped to records with lowercase names PM */ - if (is_pascal_string_type (elttype, &length_pos, - &length_size, &string_pos, &char_size) + if (is_pascal_string_type (elttype, &length_pos, &length_size, + &string_pos, &char_size, NULL) && addr != 0) { ULONGEST string_length; @@ -213,7 +214,7 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset, && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) { fputs_filtered (" <", stream); - fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream); + fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); fputs_filtered (">", stream); } if (vt_address && vtblprint) @@ -221,13 +222,12 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset, struct value *vt_val; struct symbol *wsym = (struct symbol *) NULL; struct type *wtype; - struct symtab *s; struct block *block = (struct block *) NULL; int is_this_fld; if (msymbol != NULL) - wsym = lookup_symbol (SYMBOL_NAME (msymbol), block, - VAR_NAMESPACE, &is_this_fld, &s); + wsym = lookup_symbol (DEPRECATED_SYMBOL_NAME (msymbol), block, + VAR_DOMAIN, &is_this_fld, NULL); if (wsym) { @@ -272,9 +272,11 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset, if (addressprint) { fprintf_filtered (stream, "@"); + /* Extract the address, assume that it is unsigned. */ print_address_numeric - (extract_address (valaddr + embedded_offset, - TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream); + (extract_unsigned_integer (valaddr + embedded_offset, + TARGET_PTR_BIT / HOST_CHAR_BIT), + 1, stream); if (deref_ref) fputs_filtered (": ", stream); } @@ -312,15 +314,16 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset, /* 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 (extract_address ( - valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8, - TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))), - stream, demangle); + /* Extract the address, assume that it is unsigned. */ + print_address_demangle + (extract_unsigned_integer (valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8, + TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))), + stream, demangle); } else { if (is_pascal_string_type (type, &length_pos, &length_size, - &string_pos, &char_size)) + &string_pos, &char_size, NULL)) { len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size); LA_PRINT_STRING (stream, valaddr + embedded_offset + string_pos, len, char_size, 0); @@ -550,8 +553,8 @@ pascal_value_print (struct value *val, struct ui_file *stream, int format, type is indicated by the quoted string anyway. */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_NAME (type) == NULL && - TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL && - STREQ (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char")) + TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL + && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0) { /* Print nothing */ } @@ -620,13 +623,11 @@ pascal_object_print_class_method (char *valaddr, struct type *type, f = TYPE_FN_FIELDLIST1 (domain, i); len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + check_stub_method_group (domain, i); for (j = 0; j < len2; j++) { - QUIT; if (TYPE_FN_FIELD_VOFFSET (f, j) == offset) { - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (domain, i, j); kind = "virtual "; goto common; } @@ -646,15 +647,11 @@ pascal_object_print_class_method (char *valaddr, struct type *type, f = TYPE_FN_FIELDLIST1 (domain, i); len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + check_stub_method_group (domain, i); for (j = 0; j < len2; j++) { - QUIT; - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (domain, i, j); - if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) - { - goto common; - } + if (DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) + goto common; } } } @@ -664,7 +661,7 @@ common: char *demangled_name; fprintf_filtered (stream, "&"); - fprintf_filtered (stream, kind); + fputs_filtered (kind, stream); demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j), DMGL_ANSI | DMGL_PARAMS); if (demangled_name == NULL) @@ -697,7 +694,7 @@ pascal_object_is_vtbl_ptr_type (struct type *type) char *typename = type_name_no_tag (type); return (typename != NULL - && (STREQ (typename, pascal_vtbl_ptr_name))); + && strcmp (typename, pascal_vtbl_ptr_name) == 0); } /* Return truth value for the assertion that TYPE is of the type @@ -761,7 +758,6 @@ pascal_object_print_value_fields (struct type *type, char *valaddr, fprintf_filtered (stream, ""); else { - extern int inspect_it; int fields_seen = 0; if (dont_print_statmem == 0) @@ -1059,7 +1055,7 @@ pascal_object_print_class_member (char *valaddr, struct type *domain, print it. */ int extra = 0; int bits = 0; - register unsigned int i; + unsigned int i; unsigned len = TYPE_NFIELDS (domain); /* @@ Make VAL into bit offset */ LONGEST val = unpack_long (builtin_type_int, valaddr) << 3; @@ -1084,7 +1080,7 @@ pascal_object_print_class_member (char *valaddr, struct type *domain, if (i < len) { char *name; - fprintf_filtered (stream, prefix); + fputs_filtered (prefix, stream); name = type_name_no_tag (domain); if (name) fputs_filtered (name, stream); @@ -1101,6 +1097,7 @@ pascal_object_print_class_member (char *valaddr, struct type *domain, fprintf_filtered (stream, "%ld", (long int) (val >> 3)); } +extern initialize_file_ftype _initialize_pascal_valprint; /* -Wmissing-prototypes */ void _initialize_pascal_valprint (void) diff --git a/contrib/gdb/gdb/pa64solib.c b/contrib/gdb/gdb/pa64solib.c new file mode 100644 index 00000000000..4e29455606f --- /dev/null +++ b/contrib/gdb/gdb/pa64solib.c @@ -0,0 +1,1247 @@ +/* Handle HP ELF shared libraries for GDB, the GNU Debugger. + + Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, + Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + HP in their infinite stupidity choose not to use standard ELF dynamic + linker interfaces. They also choose not to make their ELF dymamic + linker interfaces compatible with the SOM dynamic linker. The + net result is we can not use either of the existing somsolib.c or + solib.c. What a crock. + + Even more disgusting. This file depends on functions provided only + in certain PA64 libraries. Thus this file is supposed to only be + used native. When will HP ever learn that they need to provide the + same functionality in all their libraries! */ + +#include +#include +#include + +#include "defs.h" + +#include "frame.h" +#include "bfd.h" +#include "libhppa.h" +#include "gdbcore.h" +#include "symtab.h" +#include "breakpoint.h" +#include "symfile.h" +#include "objfiles.h" +#include "inferior.h" +#include "gdb-stabs.h" +#include "gdb_stat.h" +#include "gdbcmd.h" +#include "language.h" +#include "regcache.h" +#include "exec.h" + +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static CORE_ADDR bfd_lookup_symbol (bfd *, char *); +/* This lives in hppa-tdep.c. */ +extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc); + +/* These ought to be defined in some public interface, but aren't. They + identify dynamic linker events. */ +#define DLD_CB_LOAD 1 +#define DLD_CB_UNLOAD 0 + +/* A structure to keep track of all the known shared objects. */ +struct so_list + { + bfd *abfd; + char *name; + struct so_list *next; + struct objfile *objfile; + CORE_ADDR pa64_solib_desc_addr; + struct load_module_desc pa64_solib_desc; + struct section_table *sections; + struct section_table *sections_end; + int loaded; + }; + +static struct so_list *so_list_head; + +/* This is the cumulative size in bytes of the symbol tables of all + shared objects on the so_list_head list. (When we say size, here + we mean of the information before it is brought into memory and + potentially expanded by GDB.) When adding a new shlib, this value + is compared against a threshold size, held by auto_solib_limit (in + megabytes). If adding symbols for the new shlib would cause the + total size to exceed the threshold, then the new shlib's symbols + are not loaded. */ +static LONGEST pa64_solib_total_st_size; + +/* When the threshold is reached for any shlib, we refuse to add + symbols for subsequent shlibs, even if those shlibs' symbols would + be small enough to fit under the threshold. Although this may + result in one, early large shlib preventing the loading of later, + smaller shlibs' symbols, it allows us to issue one informational + message. The alternative, to issue a message for each shlib whose + symbols aren't loaded, could be a big annoyance where the threshold + is exceeded due to a very large number of shlibs. */ +static int pa64_solib_st_size_threshold_exceeded; + +/* When adding fields, be sure to clear them in _initialize_pa64_solib. */ +typedef struct + { + CORE_ADDR dld_flags_addr; + LONGEST dld_flags; + struct bfd_section *dyninfo_sect; + int have_read_dld_descriptor; + int is_valid; + CORE_ADDR load_map; + CORE_ADDR load_map_addr; + struct load_module_desc dld_desc; + } +dld_cache_t; + +static dld_cache_t dld_cache; + +static void pa64_sharedlibrary_info_command (char *, int); + +static void pa64_solib_sharedlibrary_command (char *, int); + +static void *pa64_target_read_memory (void *, CORE_ADDR, size_t, int); + +static int read_dld_descriptor (struct target_ops *, int readsyms); + +static int read_dynamic_info (asection *, dld_cache_t *); + +static void add_to_solist (int, char *, int, struct load_module_desc *, + CORE_ADDR, struct target_ops *); + +/* When examining the shared library for debugging information we have to + look for HP debug symbols, stabs and dwarf2 debug symbols. */ +static char *pa64_debug_section_names[] = { + ".debug_header", ".debug_gntt", ".debug_lntt", ".debug_slt", ".debug_vt", + ".stabs", ".stabstr", ".debug_info", ".debug_abbrev", ".debug_aranges", + ".debug_macinfo", ".debug_line", ".debug_loc", ".debug_pubnames", + ".debug_str", NULL +}; + +/* Return a ballbark figure for the amount of memory GDB will need to + allocate to read in the debug symbols from FILENAME. */ +static LONGEST +pa64_solib_sizeof_symbol_table (char *filename) +{ + bfd *abfd; + int i; + int desc; + char *absolute_name; + LONGEST st_size = (LONGEST) 0; + asection *sect; + + /* We believe that filename was handed to us by the dynamic linker, and + is therefore always an absolute path. */ + desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, + 0, &absolute_name); + if (desc < 0) + { + perror_with_name (filename); + } + filename = absolute_name; + + abfd = bfd_fdopenr (filename, gnutarget, desc); + if (!abfd) + { + close (desc); + make_cleanup (xfree, filename); + error ("\"%s\": can't open to read symbols: %s.", filename, + bfd_errmsg (bfd_get_error ())); + } + + if (!bfd_check_format (abfd, bfd_object)) + { + bfd_close (abfd); + make_cleanup (xfree, filename); + error ("\"%s\": can't read symbols: %s.", filename, + bfd_errmsg (bfd_get_error ())); + } + + /* Sum the sizes of the various sections that compose debug info. */ + for (i = 0; pa64_debug_section_names[i] != NULL; i++) + { + asection *sect; + + sect = bfd_get_section_by_name (abfd, pa64_debug_section_names[i]); + if (sect) + st_size += (LONGEST)bfd_section_size (abfd, sect); + } + + bfd_close (abfd); + xfree (filename); + + /* Unfortunately, just summing the sizes of various debug info + sections isn't a very accurate measurement of how much heap + space the debugger will need to hold them. It also doesn't + account for space needed by linker (aka "minimal") symbols. + + Anecdotal evidence suggests that just summing the sizes of + debug-info-related sections understates the heap space needed + to represent it internally by about an order of magnitude. + + Since it's not exactly brain surgery we're doing here, rather + than attempt to more accurately measure the size of a shlib's + symbol table in GDB's heap, we'll just apply a 10x fudge- + factor to the debug info sections' size-sum. No, this doesn't + account for minimal symbols in non-debuggable shlibs. But it + all roughly washes out in the end. */ + return st_size * (LONGEST) 10; +} + +/* Add a shared library to the objfile list and load its symbols into + GDB's symbol table. */ +static void +pa64_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty, + CORE_ADDR text_addr) +{ + bfd *tmp_bfd; + asection *sec; + obj_private_data_t *obj_private; + struct section_addr_info *section_addrs; + struct cleanup *my_cleanups; + + /* We need the BFD so that we can look at its sections. We open up the + file temporarily, then close it when we are done. */ + tmp_bfd = bfd_openr (name, gnutarget); + if (tmp_bfd == NULL) + { + perror_with_name (name); + return; + } + + if (!bfd_check_format (tmp_bfd, bfd_object)) + { + bfd_close (tmp_bfd); + error ("\"%s\" is not an object file: %s", name, + bfd_errmsg (bfd_get_error ())); + } + + + /* Undo some braindamage from symfile.c. + + First, symfile.c will subtract the VMA of the first .text section + in the shared library that it finds. Undo that. */ + sec = bfd_get_section_by_name (tmp_bfd, ".text"); + text_addr += bfd_section_vma (tmp_bfd, sec); + + /* Now find the true lowest section in the shared library. */ + sec = NULL; + bfd_map_over_sections (tmp_bfd, find_lowest_section, &sec); + + if (sec) + { + /* Subtract out the VMA of the lowest section. */ + text_addr -= bfd_section_vma (tmp_bfd, sec); + + /* ??? Add back in the filepos of that lowest section. */ + text_addr += sec->filepos; + } + + section_addrs = alloc_section_addr_info (bfd_count_sections (tmp_bfd)); + my_cleanups = make_cleanup (xfree, section_addrs); + + /* We are done with the temporary bfd. Get rid of it and make sure + nobody else can us it. */ + bfd_close (tmp_bfd); + tmp_bfd = NULL; + + /* Now let the generic code load up symbols for this library. */ + section_addrs->other[0].addr = text_addr; + section_addrs->other[0].name = ".text"; + so->objfile = symbol_file_add (name, from_tty, section_addrs, 0, OBJF_SHARED); + so->abfd = so->objfile->obfd; + + /* Mark this as a shared library and save private data. */ + so->objfile->flags |= OBJF_SHARED; + + if (so->objfile->obj_private == NULL) + { + obj_private = (obj_private_data_t *) + obstack_alloc (&so->objfile->objfile_obstack, + sizeof (obj_private_data_t)); + obj_private->unwind_info = NULL; + obj_private->so_info = NULL; + so->objfile->obj_private = obj_private; + } + + obj_private = (obj_private_data_t *) so->objfile->obj_private; + obj_private->so_info = so; + obj_private->dp = so->pa64_solib_desc.linkage_ptr; + do_cleanups (my_cleanups); +} + +/* Load debugging information for a shared library. TARGET may be + NULL if we are not attaching to a process or reading a core file. */ + +static void +pa64_solib_load_symbols (struct so_list *so, char *name, int from_tty, + CORE_ADDR text_addr, struct target_ops *target) +{ + struct section_table *p; + asection *sec; + int status; + char buf[4]; + CORE_ADDR presumed_data_start; + + if (text_addr == 0) + text_addr = so->pa64_solib_desc.text_base; + + pa64_solib_add_solib_objfile (so, name, from_tty, text_addr); + + /* Now we need to build a section table for this library since + we might be debugging a core file from a dynamically linked + executable in which the libraries were not privately mapped. */ + if (build_section_table (so->abfd, + &so->sections, + &so->sections_end)) + { + error ("Unable to build section table for shared library\n."); + return; + } + + (so->objfile->section_offsets)->offsets[SECT_OFF_TEXT (so->objfile)] + = so->pa64_solib_desc.text_base; + (so->objfile->section_offsets)->offsets[SECT_OFF_DATA (so->objfile)] + = so->pa64_solib_desc.data_base; + + /* Relocate all the sections based on where they got loaded. */ + for (p = so->sections; p < so->sections_end; p++) + { + if (p->the_bfd_section->flags & SEC_CODE) + { + p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); + p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); + } + else if (p->the_bfd_section->flags & SEC_DATA) + { + p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); + p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); + } + } + + /* Now see if we need to map in the text and data for this shared + library (for example debugging a core file which does not use + private shared libraries.). + + Carefully peek at the first text address in the library. If the + read succeeds, then the libraries were privately mapped and were + included in the core dump file. + + If the peek failed, then the libraries were not privately mapped + and are not in the core file, we'll have to read them in ourselves. */ + status = target_read_memory (text_addr, buf, 4); + if (status != 0) + { + int new, old; + + new = so->sections_end - so->sections; + + old = target_resize_to_sections (target, new); + + /* Copy over the old data before it gets clobbered. */ + memcpy ((char *) (target->to_sections + old), + so->sections, + ((sizeof (struct section_table)) * new)); + } +} + + +/* Add symbols from shared libraries into the symtab list, unless the + size threshold specified by auto_solib_limit (in megabytes) would + be exceeded. */ + +void +pa64_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) +{ + struct minimal_symbol *msymbol; + CORE_ADDR addr; + asection *shlib_info; + int status; + unsigned int dld_flags; + char buf[4], *re_err; + int threshold_warning_given = 0; + int dll_index; + struct load_module_desc dll_desc; + char *dll_path; + + /* First validate our arguments. */ + if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL) + { + error ("Invalid regexp: %s", re_err); + } + + /* If we're debugging a core file, or have attached to a running + process, then pa64_solib_create_inferior_hook will not have been + called. + + We need to first determine if we're dealing with a dynamically + linked executable. If not, then return without an error or warning. + + We also need to examine __dld_flags to determine if the shared library + list is valid and to determine if the libraries have been privately + mapped. */ + if (symfile_objfile == NULL) + return; + + /* First see if the objfile was dynamically linked. */ + shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic"); + if (!shlib_info) + return; + + /* It's got a .dynamic section, make sure it's not empty. */ + if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) + return; + + /* Read in the load map pointer if we have not done so already. */ + if (! dld_cache.have_read_dld_descriptor) + if (! read_dld_descriptor (target, readsyms)) + return; + + /* If the libraries were not mapped private, warn the user. */ + if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0) + warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n"); + + /* For each shaerd library, add it to the shared library list. */ + for (dll_index = 1; ; dll_index++) + { + /* Read in the load module descriptor. */ + if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc), + pa64_target_read_memory, 0, dld_cache.load_map) + == 0) + return; + + /* Get the name of the shared library. */ + dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc), + pa64_target_read_memory, + 0, dld_cache.load_map); + + if (!dll_path) + error ("pa64_solib_add, unable to read shared library path."); + + add_to_solist (from_tty, dll_path, readsyms, &dll_desc, 0, target); + } +} + + +/* This hook gets called just before the first instruction in the + inferior process is executed. + + This is our opportunity to set magic flags in the inferior so + that GDB can be notified when a shared library is mapped in and + to tell the dynamic linker that a private copy of the library is + needed (so GDB can set breakpoints in the library). + + We need to set two flag bits in this routine. + + DT_HP_DEBUG_PRIVATE to indicate that shared libraries should be + mapped private. + + DT_HP_DEBUG_CALLBACK to indicate that we want the dynamic linker to + call the breakpoint routine for significant events. */ + +void +pa64_solib_create_inferior_hook (void) +{ + struct minimal_symbol *msymbol; + unsigned int dld_flags, status; + asection *shlib_info, *interp_sect; + char buf[4]; + struct objfile *objfile; + CORE_ADDR anaddr; + + /* First, remove all the solib event breakpoints. Their addresses + may have changed since the last time we ran the program. */ + remove_solib_event_breakpoints (); + + if (symfile_objfile == NULL) + return; + + /* First see if the objfile was dynamically linked. */ + shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic"); + if (!shlib_info) + return; + + /* It's got a .dynamic section, make sure it's not empty. */ + if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) + return; + + /* Read in the .dynamic section. */ + if (! read_dynamic_info (shlib_info, &dld_cache)) + error ("Unable to read the .dynamic section."); + + /* Turn on the flags we care about. */ + dld_cache.dld_flags |= DT_HP_DEBUG_PRIVATE; + dld_cache.dld_flags |= DT_HP_DEBUG_CALLBACK; + status = target_write_memory (dld_cache.dld_flags_addr, + (char *) &dld_cache.dld_flags, + sizeof (dld_cache.dld_flags)); + if (status != 0) + error ("Unable to modify dynamic linker flags."); + + /* Now we have to create a shared library breakpoint in the dynamic + linker. This can be somewhat tricky since the symbol is inside + the dynamic linker (for which we do not have symbols or a base + load address! Luckily I wrote this code for solib.c years ago. */ + interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); + if (interp_sect) + { + unsigned int interp_sect_size; + char *buf; + CORE_ADDR load_addr; + bfd *tmp_bfd; + CORE_ADDR sym_addr = 0; + + /* Read the contents of the .interp section into a local buffer; + the contents specify the dynamic linker this program uses. */ + interp_sect_size = bfd_section_size (exec_bfd, interp_sect); + buf = alloca (interp_sect_size); + bfd_get_section_contents (exec_bfd, interp_sect, + buf, 0, interp_sect_size); + + /* Now we need to figure out where the dynamic linker was + loaded so that we can load its symbols and place a breakpoint + in the dynamic linker itself. + + This address is stored on the stack. However, I've been unable + to find any magic formula to find it for Solaris (appears to + be trivial on GNU/Linux). Therefore, we have to try an alternate + mechanism to find the dynamic linker's base address. */ + tmp_bfd = bfd_openr (buf, gnutarget); + if (tmp_bfd == NULL) + goto get_out; + + /* Make sure the dynamic linker's really a useful object. */ + if (!bfd_check_format (tmp_bfd, bfd_object)) + { + warning ("Unable to grok dynamic linker %s as an object file", buf); + bfd_close (tmp_bfd); + goto get_out; + } + + /* We find the dynamic linker's base address by examining the + current pc (which point at the entry point for the dynamic + linker) and subtracting the offset of the entry point. + + Also note the breakpoint is the second instruction in the + routine. */ + load_addr = read_pc () - tmp_bfd->start_address; + sym_addr = bfd_lookup_symbol (tmp_bfd, "__dld_break"); + sym_addr = load_addr + sym_addr + 4; + + /* Create the shared library breakpoint. */ + { + struct breakpoint *b + = create_solib_event_breakpoint (sym_addr); + + /* The breakpoint is actually hard-coded into the dynamic linker, + so we don't need to actually insert a breakpoint instruction + there. In fact, the dynamic linker's code is immutable, even to + ttrace, so we shouldn't even try to do that. For cases like + this, we have "permanent" breakpoints. */ + make_breakpoint_permanent (b); + } + + /* We're done with the temporary bfd. */ + bfd_close (tmp_bfd); + } + +get_out: + /* Wipe out all knowledge of old shared libraries since their + mapping can change from one exec to another! */ + while (so_list_head) + { + struct so_list *temp; + + temp = so_list_head; + xfree (so_list_head); + so_list_head = temp->next; + } + clear_symtab_users (); +} + +/* This operation removes the "hook" between GDB and the dynamic linker, + which causes the dld to notify GDB of shared library events. + + After this operation completes, the dld will no longer notify GDB of + shared library events. To resume notifications, GDB must call + pa64_solib_create_inferior_hook. + + This operation does not remove any knowledge of shared libraries which + GDB may already have been notified of. */ + +void +pa64_solib_remove_inferior_hook (int pid) +{ + /* Turn off the DT_HP_DEBUG_CALLBACK bit in the dynamic linker flags. */ + dld_cache.dld_flags &= ~DT_HP_DEBUG_CALLBACK; + target_write_memory (dld_cache.dld_flags_addr, + (char *)&dld_cache.dld_flags, + sizeof (dld_cache.dld_flags)); +} + +/* This function creates a breakpoint on the dynamic linker hook, which + is called when e.g., a shl_load or shl_unload call is made. This + breakpoint will only trigger when a shl_load call is made. + + If filename is NULL, then loads of any dll will be caught. Else, + only loads of the file whose pathname is the string contained by + filename will be caught. + + Undefined behaviour is guaranteed if this function is called before + pa64_solib_create_inferior_hook. */ + +void +pa64_solib_create_catch_load_hook (int pid, int tempflag, char *filename, + char *cond_string) +{ + create_solib_load_event_breakpoint ("", tempflag, filename, cond_string); +} + +/* This function creates a breakpoint on the dynamic linker hook, which + is called when e.g., a shl_load or shl_unload call is made. This + breakpoint will only trigger when a shl_unload call is made. + + If filename is NULL, then unloads of any dll will be caught. Else, + only unloads of the file whose pathname is the string contained by + filename will be caught. + + Undefined behaviour is guaranteed if this function is called before + pa64_solib_create_inferior_hook. */ + +void +pa64_solib_create_catch_unload_hook (int pid, int tempflag, char *filename, + char *cond_string) +{ + create_solib_unload_event_breakpoint ("", tempflag, filename, cond_string); +} + +/* Return nonzero if the dynamic linker has reproted that a library + has been loaded. */ + +int +pa64_solib_have_load_event (int pid) +{ + CORE_ADDR event_kind; + + event_kind = read_register (ARG0_REGNUM); + return (event_kind == DLD_CB_LOAD); +} + +/* Return nonzero if the dynamic linker has reproted that a library + has been unloaded. */ +int +pa64_solib_have_unload_event (int pid) +{ + CORE_ADDR event_kind; + + event_kind = read_register (ARG0_REGNUM); + return (event_kind == DLD_CB_UNLOAD); +} + +/* Return a pointer to a string indicating the pathname of the most + recently loaded library. + + The caller is reposible for copying the string before the inferior is + restarted. */ + +char * +pa64_solib_loaded_library_pathname (int pid) +{ + static char dll_path[MAXPATHLEN]; + CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM); + read_memory_string (dll_path_addr, dll_path, MAXPATHLEN); + return dll_path; +} + +/* Return a pointer to a string indicating the pathname of the most + recently unloaded library. + + The caller is reposible for copying the string before the inferior is + restarted. */ + +char * +pa64_solib_unloaded_library_pathname (int pid) +{ + static char dll_path[MAXPATHLEN]; + CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM); + read_memory_string (dll_path_addr, dll_path, MAXPATHLEN); + return dll_path; +} + +/* Return nonzero if PC is an address inside the dynamic linker. */ + +int +pa64_solib_in_dynamic_linker (int pid, CORE_ADDR pc) +{ + asection *shlib_info; + + if (symfile_objfile == NULL) + return 0; + + if (!dld_cache.have_read_dld_descriptor) + if (!read_dld_descriptor (¤t_target, auto_solib_add)) + return 0; + + return (pc >= dld_cache.dld_desc.text_base + && pc < dld_cache.dld_desc.text_base + dld_cache.dld_desc.text_size); +} + + +/* Return the GOT value for the shared library in which ADDR belongs. If + ADDR isn't in any known shared library, return zero. */ + +CORE_ADDR +pa64_solib_get_got_by_pc (CORE_ADDR addr) +{ + struct so_list *so_list = so_list_head; + CORE_ADDR got_value = 0; + + while (so_list) + { + if (so_list->pa64_solib_desc.text_base <= addr + && ((so_list->pa64_solib_desc.text_base + + so_list->pa64_solib_desc.text_size) + > addr)) + { + got_value = so_list->pa64_solib_desc.linkage_ptr; + break; + } + so_list = so_list->next; + } + return got_value; +} + +/* Return the address of the handle of the shared library in which ADDR + belongs. If ADDR isn't in any known shared library, return zero. + + This function is used in hppa_fix_call_dummy in hppa-tdep.c. */ + +CORE_ADDR +pa64_solib_get_solib_by_pc (CORE_ADDR addr) +{ + struct so_list *so_list = so_list_head; + CORE_ADDR retval = 0; + + while (so_list) + { + if (so_list->pa64_solib_desc.text_base <= addr + && ((so_list->pa64_solib_desc.text_base + + so_list->pa64_solib_desc.text_size) + > addr)) + { + retval = so_list->pa64_solib_desc_addr; + break; + } + so_list = so_list->next; + } + return retval; +} + +/* Dump information about all the currently loaded shared libraries. */ + +static void +pa64_sharedlibrary_info_command (char *ignore, int from_tty) +{ + struct so_list *so_list = so_list_head; + + if (exec_bfd == NULL) + { + printf_unfiltered ("No executable file.\n"); + return; + } + + if (so_list == NULL) + { + printf_unfiltered ("No shared libraries loaded at this time.\n"); + return; + } + + printf_unfiltered ("Shared Object Libraries\n"); + printf_unfiltered (" %-19s%-19s%-19s%-19s\n", + " text start", " text end", + " data start", " data end"); + while (so_list) + { + unsigned int flags; + + printf_unfiltered ("%s", so_list->name); + if (so_list->objfile == NULL) + printf_unfiltered (" (symbols not loaded)"); + if (so_list->loaded == 0) + printf_unfiltered (" (shared library unloaded)"); + printf_unfiltered (" %-18s", + local_hex_string_custom (so_list->pa64_solib_desc.linkage_ptr, + "016l")); + printf_unfiltered ("\n"); + printf_unfiltered ("%-18s", + local_hex_string_custom (so_list->pa64_solib_desc.text_base, + "016l")); + printf_unfiltered (" %-18s", + local_hex_string_custom ((so_list->pa64_solib_desc.text_base + + so_list->pa64_solib_desc.text_size), + "016l")); + printf_unfiltered (" %-18s", + local_hex_string_custom (so_list->pa64_solib_desc.data_base, + "016l")); + printf_unfiltered (" %-18s\n", + local_hex_string_custom ((so_list->pa64_solib_desc.data_base + + so_list->pa64_solib_desc.data_size), + "016l")); + so_list = so_list->next; + } +} + +/* Load up one or more shared libraries as directed by the user. */ + +static void +pa64_solib_sharedlibrary_command (char *args, int from_tty) +{ + dont_repeat (); + pa64_solib_add (args, from_tty, (struct target_ops *) 0, 1); +} + +/* Return the name of the shared library containing ADDR or NULL if ADDR + is not contained in any known shared library. */ + +char * +pa64_solib_address (CORE_ADDR addr) +{ + struct so_list *so = so_list_head; + + while (so) + { + /* Is this address within this shlib's text range? If so, + return the shlib's name. */ + if (addr >= so->pa64_solib_desc.text_base + && addr < (so->pa64_solib_desc.text_base + | so->pa64_solib_desc.text_size)) + return so->name; + + /* Nope, keep looking... */ + so = so->next; + } + + /* No, we couldn't prove that the address is within a shlib. */ + return NULL; +} + +/* We are killing the inferior and restarting the program. */ + +void +pa64_solib_restart (void) +{ + struct so_list *sl = so_list_head; + + /* Before the shlib info vanishes, use it to disable any breakpoints + that may still be active in those shlibs. */ + disable_breakpoints_in_shlibs (0); + + /* Discard all the shlib descriptors. */ + while (sl) + { + struct so_list *next_sl = sl->next; + xfree (sl); + sl = next_sl; + } + so_list_head = NULL; + + pa64_solib_total_st_size = (LONGEST) 0; + pa64_solib_st_size_threshold_exceeded = 0; + + dld_cache.is_valid = 0; + dld_cache.have_read_dld_descriptor = 0; + dld_cache.dld_flags_addr = 0; + dld_cache.load_map = 0; + dld_cache.load_map_addr = 0; + dld_cache.dld_desc.data_base = 0; + dld_cache.dld_flags = 0; + dld_cache.dyninfo_sect = 0; +} + +void +_initialize_pa64_solib (void) +{ + add_com ("sharedlibrary", class_files, pa64_solib_sharedlibrary_command, + "Load shared object library symbols for files matching REGEXP."); + add_info ("sharedlibrary", pa64_sharedlibrary_info_command, + "Status of loaded shared object libraries."); + + add_show_from_set + (add_set_cmd ("auto-solib-add", class_support, var_boolean, + (char *) &auto_solib_add, + "Set autoloading of shared library symbols.\n\ +If \"on\", symbols from all shared object libraries will be loaded\n\ +automatically when the inferior begins execution, when the dynamic linker\n\ +informs gdb that a new library has been loaded, or when attaching to the\n\ +inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ("auto-solib-limit", class_support, var_zinteger, + (char *) &auto_solib_limit, + "Set threshold (in Mb) for autoloading shared library symbols.\n\ +When shared library autoloading is enabled, new libraries will be loaded\n\ +only until the total size of shared library symbols exceeds this\n\ +threshold in megabytes. Is ignored when using `sharedlibrary'.", + &setlist), + &showlist); + + /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how + much data space a process can use. We ought to be reading + MAXDSIZ and setting auto_solib_limit to some large fraction of + that value. If not that, we maybe ought to be setting it smaller + than the default for MAXDSIZ (that being 64Mb, I believe). + However, [1] this threshold is only crudely approximated rather + than actually measured, and [2] 50 Mbytes is too small for + debugging gdb itself. Thus, the arbitrary 100 figure. */ + auto_solib_limit = 100; /* Megabytes */ + + pa64_solib_restart (); +} + +/* Get some HPUX-specific data from a shared lib. */ +CORE_ADDR +so_lib_thread_start_addr (struct so_list *so) +{ + return so->pa64_solib_desc.tls_start_addr; +} + +/* Read the dynamic linker's internal shared library descriptor. + + This must happen after dld starts running, so we can't do it in + read_dynamic_info. Record the fact that we have loaded the + descriptor. If the library is archive bound, then return zero, else + return nonzero. */ + +static int +read_dld_descriptor (struct target_ops *target, int readsyms) +{ + char *dll_path; + asection *dyninfo_sect; + + /* If necessary call read_dynamic_info to extract the contents of the + .dynamic section from the shared library. */ + if (!dld_cache.is_valid) + { + if (symfile_objfile == NULL) + error ("No object file symbols."); + + dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd, + ".dynamic"); + if (!dyninfo_sect) + { + return 0; + } + + if (!read_dynamic_info (dyninfo_sect, &dld_cache)) + error ("Unable to read in .dynamic section information."); + } + + /* Read the load map pointer. */ + if (target_read_memory (dld_cache.load_map_addr, + (char*) &dld_cache.load_map, + sizeof(dld_cache.load_map)) + != 0) + { + error ("Error while reading in load map pointer."); + } + + /* Read in the dld load module descriptor */ + if (dlgetmodinfo (-1, + &dld_cache.dld_desc, + sizeof(dld_cache.dld_desc), + pa64_target_read_memory, + 0, + dld_cache.load_map) + == 0) + { + error ("Error trying to get information about dynamic linker."); + } + + /* Indicate that we have loaded the dld descriptor. */ + dld_cache.have_read_dld_descriptor = 1; + + /* Add dld.sl to the list of known shared libraries so that we can + do unwind, etc. + + ?!? This may not be correct. Consider of dld.sl contains symbols + which are also referenced/defined by the user program or some user + shared library. We need to make absolutely sure that we do not + pollute the namespace from GDB's point of view. */ + dll_path = dlgetname (&dld_cache.dld_desc, + sizeof(dld_cache.dld_desc), + pa64_target_read_memory, + 0, + dld_cache.load_map); + add_to_solist(0, dll_path, readsyms, &dld_cache.dld_desc, 0, target); + + return 1; +} + +/* Read the .dynamic section and extract the information of interest, + which is stored in dld_cache. The routine elf_locate_base in solib.c + was used as a model for this. */ + +static int +read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p) +{ + char *buf; + char *bufend; + CORE_ADDR dyninfo_addr; + int dyninfo_sect_size; + CORE_ADDR entry_addr; + + /* Read in .dynamic section, silently ignore errors. */ + dyninfo_addr = bfd_section_vma (symfile_objfile->obfd, dyninfo_sect); + dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect); + buf = alloca (dyninfo_sect_size); + if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size)) + return 0; + + /* Scan the .dynamic section and record the items of interest. + In particular, DT_HP_DLD_FLAGS */ + for (bufend = buf + dyninfo_sect_size, entry_addr = dyninfo_addr; + buf < bufend; + buf += sizeof (Elf64_Dyn), entry_addr += sizeof (Elf64_Dyn)) + { + Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf; + Elf64_Sxword dyn_tag; + CORE_ADDR dyn_ptr; + char *pbuf; + + pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT); + dyn_tag = bfd_h_get_64 (symfile_objfile->obfd, + (bfd_byte*) &x_dynp->d_tag); + + /* We can't use a switch here because dyn_tag is 64 bits and HP's + lame comiler does not handle 64bit items in switch statements. */ + if (dyn_tag == DT_NULL) + break; + else if (dyn_tag == DT_HP_DLD_FLAGS) + { + /* Set dld_flags_addr and dld_flags in *dld_cache_p */ + dld_cache_p->dld_flags_addr = entry_addr + offsetof(Elf64_Dyn, d_un); + if (target_read_memory (dld_cache_p->dld_flags_addr, + (char*) &dld_cache_p->dld_flags, + sizeof(dld_cache_p->dld_flags)) + != 0) + { + error ("Error while reading in .dynamic section of the program."); + } + } + else if (dyn_tag == DT_HP_LOAD_MAP) + { + /* Dld will place the address of the load map at load_map_addr + after it starts running. */ + if (target_read_memory (entry_addr + offsetof(Elf64_Dyn, + d_un.d_ptr), + (char*) &dld_cache_p->load_map_addr, + sizeof(dld_cache_p->load_map_addr)) + != 0) + { + error ("Error while reading in .dynamic section of the program."); + } + } + else + { + /* tag is not of interest */ + } + } + + /* Record other information and set is_valid to 1. */ + dld_cache_p->dyninfo_sect = dyninfo_sect; + + /* Verify that we read in required info. These fields are re-set to zero + in pa64_solib_restart. */ + + if (dld_cache_p->dld_flags_addr != 0 && dld_cache_p->load_map_addr != 0) + dld_cache_p->is_valid = 1; + else + return 0; + + return 1; +} + +/* Wrapper for target_read_memory to make dlgetmodinfo happy. */ + +static void * +pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident) +{ + if (target_read_memory (ptr, buffer, bufsiz) != 0) + return 0; + return buffer; +} + +/* Called from handle_dynlink_load_event and pa64_solib_add to add + a shared library to so_list_head list and possibly to read in the + debug information for the library. + + If load_module_desc_p is NULL, then the load module descriptor must + be read from the inferior process at the address load_module_desc_addr. */ + +static void +add_to_solist (int from_tty, char *dll_path, int readsyms, + struct load_module_desc *load_module_desc_p, + CORE_ADDR load_module_desc_addr, struct target_ops *target) +{ + struct so_list *new_so, *so_list_tail; + int pa64_solib_st_size_threshhold_exceeded; + LONGEST st_size; + + if (symfile_objfile == NULL) + return; + + so_list_tail = so_list_head; + /* Find the end of the list of shared objects. */ + while (so_list_tail && so_list_tail->next) + { + if (strcmp (so_list_tail->name, dll_path) == 0) + return; + so_list_tail = so_list_tail->next; + } + + if (so_list_tail && strcmp (so_list_tail->name, dll_path) == 0) + return; + + /* Add the shared library to the so_list_head list */ + new_so = (struct so_list *) xmalloc (sizeof (struct so_list)); + memset ((char *)new_so, 0, sizeof (struct so_list)); + if (so_list_head == NULL) + { + so_list_head = new_so; + so_list_tail = new_so; + } + else + { + so_list_tail->next = new_so; + so_list_tail = new_so; + } + + /* Initialize the new_so */ + if (load_module_desc_p) + { + new_so->pa64_solib_desc = *load_module_desc_p; + } + else + { + if (target_read_memory (load_module_desc_addr, + (char*) &new_so->pa64_solib_desc, + sizeof(struct load_module_desc)) + != 0) + { + error ("Error while reading in dynamic library %s", dll_path); + } + } + + new_so->pa64_solib_desc_addr = load_module_desc_addr; + new_so->loaded = 1; + new_so->name = obsavestring (dll_path, strlen(dll_path), + &symfile_objfile->objfile_obstack); + + /* If we are not going to load the library, tell the user if we + haven't already and return. */ + + st_size = pa64_solib_sizeof_symbol_table (dll_path); + pa64_solib_st_size_threshhold_exceeded = + !from_tty + && readsyms + && ( (st_size + pa64_solib_total_st_size) + > (auto_solib_limit * (LONGEST) (1024 * 1024))); + if (pa64_solib_st_size_threshhold_exceeded) + { + pa64_solib_add_solib_objfile (new_so, dll_path, from_tty, 1); + return; + } + + /* Now read in debug info. */ + pa64_solib_total_st_size += st_size; + + /* This fills in new_so->objfile, among others. */ + pa64_solib_load_symbols (new_so, + dll_path, + from_tty, + 0, + target); + return; +} + + +/* + LOCAL FUNCTION + + bfd_lookup_symbol -- lookup the value for a specific symbol + + SYNOPSIS + + CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname) + + DESCRIPTION + + An expensive way to lookup the value of a single symbol for + bfd's that are only temporary anyway. This is used by the + shared library support to find the address of the debugger + interface structures in the shared library. + + Note that 0 is specifically allowed as an error return (no + such symbol). + */ + +static CORE_ADDR +bfd_lookup_symbol (bfd *abfd, char *symname) +{ + unsigned int storage_needed; + asymbol *sym; + asymbol **symbol_table; + unsigned int number_of_symbols; + unsigned int i; + struct cleanup *back_to; + CORE_ADDR symaddr = 0; + + storage_needed = bfd_get_symtab_upper_bound (abfd); + + if (storage_needed > 0) + { + symbol_table = (asymbol **) xmalloc (storage_needed); + back_to = make_cleanup (xfree, symbol_table); + number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); + + for (i = 0; i < number_of_symbols; i++) + { + sym = *symbol_table++; + if (strcmp (sym->name, symname) == 0) + { + /* Bfd symbols are section relative. */ + symaddr = sym->value + sym->section->vma; + break; + } + } + do_cleanups (back_to); + } + return (symaddr); +} + diff --git a/contrib/gdb/gdb/pa64solib.h b/contrib/gdb/gdb/pa64solib.h new file mode 100644 index 00000000000..7a3a068ff8d --- /dev/null +++ b/contrib/gdb/gdb/pa64solib.h @@ -0,0 +1,149 @@ +/* HP PA64 ELF Shared library declarations for GDB, the GNU Debugger. + Copyright 1999, 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Forward decl's for prototypes */ +struct target_ops; +struct objfile; +struct section_offsets; + +/* Called to add symbols from a shared library to gdb's symbol table. */ + +#define SOLIB_ADD(filename, from_tty, targ, readsyms) \ + pa64_solib_add (filename, from_tty, targ, readsyms) + +extern void pa64_solib_add (char *, int, struct target_ops *, int); + +extern CORE_ADDR pa64_solib_get_got_by_pc (CORE_ADDR); + +/* Function to be called when the inferior starts up, to discover the names + of shared libraries that are dynamically linked, the base addresses to + which they are linked, and sufficient information to read in their symbols + at a later time. */ + +#define SOLIB_CREATE_INFERIOR_HOOK(PID) pa64_solib_create_inferior_hook() + +extern void pa64_solib_create_inferior_hook (void); + +/* Function to be called to remove the connection between debugger and + dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK. + (This operation does not remove shared library information from + the debugger, as CLEAR_SOLIB does.) */ +#define SOLIB_REMOVE_INFERIOR_HOOK(PID) pa64_solib_remove_inferior_hook(PID) + +extern void pa64_solib_remove_inferior_hook (int); + +/* This function is called by the "catch load" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is loaded. */ +#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag, filename,cond_string) \ + pa64_solib_create_catch_load_hook (pid, tempflag, filename, cond_string) + +extern void pa64_solib_create_catch_load_hook (int, int, char *, char *); + +/* This function is called by the "catch unload" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is unloaded. */ +#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename, cond_string) \ + pa64_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string) + +extern void pa64_solib_create_catch_unload_hook (int, int, char *, char *); + +/* This function returns TRUE if the dynamic linker has just reported + a load of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. */ +#define SOLIB_HAVE_LOAD_EVENT(pid) \ + pa64_solib_have_load_event (pid) + +extern int pa64_solib_have_load_event (int); + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been loaded. + + This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. */ +#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ + pa64_solib_loaded_library_pathname (pid) + +extern char *pa64_solib_loaded_library_pathname (int); + +/* This function returns TRUE if the dynamic linker has just reported + an unload of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. */ +#define SOLIB_HAVE_UNLOAD_EVENT(pid) \ + pa64_solib_have_unload_event (pid) + +extern int pa64_solib_have_unload_event (int); + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been unloaded. + + This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. */ +#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ + pa64_solib_unloaded_library_pathname (pid) + +extern char *pa64_solib_unloaded_library_pathname (int); + +/* This function returns TRUE if pc is the address of an instruction that + lies within the dynamic linker (such as the event hook, or the dld + itself). + + This function must be used only when a dynamic linker event has been + caught, and the inferior is being stepped out of the hook, or undefined + results are guaranteed. */ +#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ + pa64_solib_in_dynamic_linker (pid, pc) + +extern int pa64_solib_in_dynamic_linker (int, CORE_ADDR); + +/* This function must be called when the inferior is killed, and the program + restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard + any symbol tables. + + Presently, this functionality is not implemented. */ +#define SOLIB_RESTART() \ + pa64_solib_restart () + +extern void pa64_solib_restart (void); + +/* If we can't set a breakpoint, and it's in a shared library, just + disable it. */ + +#define DISABLE_UNSETTABLE_BREAK(addr) (pa64_solib_address(addr) != NULL) + +extern char *pa64_solib_address (CORE_ADDR); /* somsolib.c */ + +/* If ADDR lies in a shared library, return its name. */ + +#define PC_SOLIB(addr) pa64_solib_address (addr) diff --git a/contrib/gdb/gdb/parse.c b/contrib/gdb/gdb/parse.c index b3fbe19950b..374e88ed85d 100644 --- a/contrib/gdb/gdb/parse.c +++ b/contrib/gdb/gdb/parse.c @@ -47,7 +47,20 @@ #include "inferior.h" /* for NUM_PSEUDO_REGS. NOTE: replace with "gdbarch.h" when appropriate. */ #include "doublest.h" +#include "gdb_assert.h" +#include "block.h" +/* Standard set of definitions for printing, dumping, prefixifying, + * and evaluating expressions. */ + +const struct exp_descriptor exp_descriptor_standard = + { + print_subexp_standard, + operator_length_standard, + op_name_standard, + dump_subexp_body_standard, + evaluate_subexp_standard + }; /* Symbols which architectures can redefine. */ @@ -69,11 +82,13 @@ struct expression *expout; int expout_size; int expout_ptr; struct block *expression_context_block; +CORE_ADDR expression_context_pc; struct block *innermost_block; int arglist_len; union type_stack_elt *type_stack; int type_stack_depth, type_stack_size; char *lexptr; +char *prev_lexptr; char *namecopy; int paren_depth; int comma_terminates; @@ -86,8 +101,8 @@ static void free_funcalls (void *ignore); static void prefixify_expression (struct expression *); -static void -prefixify_subexp (struct expression *, struct expression *, int, int); +static void prefixify_subexp (struct expression *, struct expression *, int, + int); void _initialize_parse (void); @@ -102,47 +117,13 @@ struct funcall static struct funcall *funcall_chain; -/* Assign machine-independent names to certain registers - (unless overridden by the REGISTER_NAMES table) */ - -unsigned num_std_regs = 0; -struct std_regs *std_regs; - -/* The generic method for targets to specify how their registers are - named. The mapping can be derived from three sources: - REGISTER_NAME; std_regs; or a target specific alias hook. */ - -int -target_map_name_to_register (char *str, int len) -{ - int i; - - /* Search register name space. */ - for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++) - if (REGISTER_NAME (i) && len == strlen (REGISTER_NAME (i)) - && STREQN (str, REGISTER_NAME (i), len)) - { - return i; - } - - /* Try standard aliases. */ - for (i = 0; i < num_std_regs; i++) - if (std_regs[i].name && len == strlen (std_regs[i].name) - && STREQN (str, std_regs[i].name, len)) - { - return std_regs[i].regnum; - } - - return -1; -} - /* Begin counting arguments for a function call, saving the data about any containing call. */ void start_arglist (void) { - register struct funcall *new; + struct funcall *new; new = (struct funcall *) xmalloc (sizeof (struct funcall)); new->next = funcall_chain; @@ -157,8 +138,8 @@ start_arglist (void) int end_arglist (void) { - register int val = arglist_len; - register struct funcall *call = funcall_chain; + int val = arglist_len; + struct funcall *call = funcall_chain; funcall_chain = call->next; arglist_len = call->arglist_len; xfree (call); @@ -171,7 +152,7 @@ end_arglist (void) static void free_funcalls (void *ignore) { - register struct funcall *call, *next; + struct funcall *call, *next; for (call = funcall_chain; call; call = next) { @@ -293,9 +274,9 @@ write_exp_elt_intern (struct internalvar *expelt) void write_exp_string (struct stoken str) { - register int len = str.length; - register int lenelt; - register char *strdata; + int len = str.length; + int lenelt; + char *strdata; /* Compute the number of expression elements required to hold the string (including a null byte terminator), along with one expression element @@ -342,10 +323,10 @@ write_exp_string (struct stoken str) void write_exp_bitstring (struct stoken str) { - register int bits = str.length; /* length in bits */ - register int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - register int lenelt; - register char *strdata; + int bits = str.length; /* length in bits */ + int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; + int lenelt; + char *strdata; /* Compute the number of expression elements required to hold the bitstring, along with one expression element at each end to record the actual @@ -485,7 +466,8 @@ write_dollar_variable (struct stoken str) /* Handle tokens that refer to machine registers: $ followed by a register name. */ - i = target_map_name_to_register (str.ptr + 1, str.length - 1); + i = frame_map_name_to_regnum (deprecated_selected_frame, + str.ptr + 1, str.length - 1); if (i >= 0) goto handle_register; @@ -502,7 +484,7 @@ write_dollar_variable (struct stoken str) symbol table lookup performance is awful, to put it mildly. */ sym = lookup_symbol (copy_name (str), (struct block *) NULL, - VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL); + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (sym) { write_exp_elt_opcode (OP_VAR_VALUE); @@ -593,7 +575,7 @@ parse_nested_classes_for_hpacc (char *name, int len, char **token, consider *prefixes* of the string; there is no need to look up "B::C" separately as a symbol in the previous example. */ - register char *p; + char *p; char *start, *end; char *prefix = NULL; char *tmp; @@ -677,17 +659,17 @@ parse_nested_classes_for_hpacc (char *name, int len, char **token, if (!done) { /* More tokens to process, so this must be a class/namespace */ - sym_class = lookup_symbol (prefix, 0, STRUCT_NAMESPACE, + sym_class = lookup_symbol (prefix, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL); } else { /* No more tokens, so try as a variable first */ - sym_var = lookup_symbol (prefix, 0, VAR_NAMESPACE, + sym_var = lookup_symbol (prefix, 0, VAR_DOMAIN, 0, (struct symtab **) NULL); /* If failed, try as class/namespace */ if (!sym_var) - sym_class = lookup_symbol (prefix, 0, STRUCT_NAMESPACE, + sym_class = lookup_symbol (prefix, 0, STRUCT_DOMAIN, 0, (struct symtab **) NULL); } @@ -798,12 +780,12 @@ copy_name (struct stoken token) to prefix form (in which we can conveniently print or execute it). */ static void -prefixify_expression (register struct expression *expr) +prefixify_expression (struct expression *expr) { - register int len = + int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts); - register struct expression *temp; - register int inpos = expr->nelts, outpos = 0; + struct expression *temp; + int inpos = expr->nelts, outpos = 0; temp = (struct expression *) alloca (len); @@ -813,18 +795,48 @@ prefixify_expression (register struct expression *expr) prefixify_subexp (temp, expr, inpos, outpos); } -/* Return the number of exp_elements in the subexpression of EXPR - whose last exp_element is at index ENDPOS - 1 in EXPR. */ +/* Return the number of exp_elements in the postfix subexpression + of EXPR whose operator is at index ENDPOS - 1 in EXPR. */ int -length_of_subexp (register struct expression *expr, register int endpos) +length_of_subexp (struct expression *expr, int endpos) { - register int oplen = 1; - register int args = 0; - register int i; + int oplen, args, i; + + operator_length (expr, endpos, &oplen, &args); + + while (args > 0) + { + oplen += length_of_subexp (expr, endpos - oplen); + args--; + } + + return oplen; +} + +/* Sets *OPLENP to the length of the operator whose (last) index is + ENDPOS - 1 in EXPR, and sets *ARGSP to the number of arguments that + operator takes. */ + +void +operator_length (struct expression *expr, int endpos, int *oplenp, int *argsp) +{ + expr->language_defn->la_exp_desc->operator_length (expr, endpos, + oplenp, argsp); +} + +/* Default value for operator_length in exp_descriptor vectors. */ + +void +operator_length_standard (struct expression *expr, int endpos, + int *oplenp, int *argsp) +{ + int oplen = 1; + int args = 0; + int i; if (endpos < 1) - error ("?error in length_of_subexp"); + error ("?error in operator_length_standard"); i = (int) expr->elts[endpos - 1].opcode; @@ -861,6 +873,11 @@ length_of_subexp (register struct expression *expr, register int endpos) args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); break; + case OP_OBJC_MSGCALL: /* Objective C message (method) call */ + oplen = 4; + args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); + break; + case UNOP_MAX: case UNOP_MIN: oplen = 3; @@ -892,6 +909,8 @@ length_of_subexp (register struct expression *expr, register int endpos) /* fall through */ case OP_M2_STRING: case OP_STRING: + case OP_OBJC_NSSTRING: /* Objective C Foundation Class NSString constant */ + case OP_OBJC_SELECTOR: /* Objective C "@selector" pseudo-op */ case OP_NAME: case OP_EXPRSTRING: oplen = longest_to_int (expr->elts[endpos - 2].longconst); @@ -930,6 +949,7 @@ length_of_subexp (register struct expression *expr, register int endpos) /* C++ */ case OP_THIS: + case OP_OBJC_SELF: oplen = 2; break; @@ -937,13 +957,8 @@ length_of_subexp (register struct expression *expr, register int endpos) args = 1 + (i < (int) BINOP_END); } - while (args > 0) - { - oplen += length_of_subexp (expr, endpos - oplen); - args--; - } - - return oplen; + *oplenp = oplen; + *argsp = args; } /* Copy the subexpression ending just before index INEND in INEXPR @@ -951,127 +966,16 @@ length_of_subexp (register struct expression *expr, register int endpos) In the process, convert it from suffix to prefix form. */ static void -prefixify_subexp (register struct expression *inexpr, - struct expression *outexpr, register int inend, int outbeg) +prefixify_subexp (struct expression *inexpr, + struct expression *outexpr, int inend, int outbeg) { - register int oplen = 1; - register int args = 0; - register int i; + int oplen; + int args; + int i; int *arglens; enum exp_opcode opcode; - /* Compute how long the last operation is (in OPLEN), - and also how many preceding subexpressions serve as - arguments for it (in ARGS). */ - - opcode = inexpr->elts[inend - 1].opcode; - switch (opcode) - { - /* C++ */ - case OP_SCOPE: - oplen = longest_to_int (inexpr->elts[inend - 2].longconst); - oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_LONG: - case OP_DOUBLE: - case OP_VAR_VALUE: - oplen = 4; - break; - - case OP_TYPE: - case OP_BOOL: - case OP_LAST: - case OP_REGISTER: - case OP_INTERNALVAR: - oplen = 3; - break; - - case OP_COMPLEX: - oplen = 1; - args = 2; - break; - - case OP_FUNCALL: - case OP_F77_UNDETERMINED_ARGLIST: - oplen = 3; - args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst); - break; - - case UNOP_MIN: - case UNOP_MAX: - oplen = 3; - break; - - case UNOP_CAST: - case UNOP_MEMVAL: - oplen = 3; - args = 1; - break; - - case UNOP_ABS: - case UNOP_CAP: - case UNOP_CHR: - case UNOP_FLOAT: - case UNOP_HIGH: - case UNOP_ODD: - case UNOP_ORD: - case UNOP_TRUNC: - oplen = 1; - args = 1; - break; - - case STRUCTOP_STRUCT: - case STRUCTOP_PTR: - case OP_LABELED: - args = 1; - /* fall through */ - case OP_M2_STRING: - case OP_STRING: - case OP_NAME: - case OP_EXPRSTRING: - oplen = longest_to_int (inexpr->elts[inend - 2].longconst); - oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_BITSTRING: - oplen = longest_to_int (inexpr->elts[inend - 2].longconst); - oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - oplen = 4 + BYTES_TO_EXP_ELEM (oplen); - break; - - case OP_ARRAY: - oplen = 4; - args = longest_to_int (inexpr->elts[inend - 2].longconst); - args -= longest_to_int (inexpr->elts[inend - 3].longconst); - args += 1; - break; - - case TERNOP_COND: - case TERNOP_SLICE: - case TERNOP_SLICE_COUNT: - args = 3; - break; - - case BINOP_ASSIGN_MODIFY: - oplen = 3; - args = 2; - break; - - /* Modula-2 */ - case MULTI_SUBSCRIPT: - oplen = 3; - args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst); - break; - - /* C++ */ - case OP_THIS: - oplen = 2; - break; - - default: - args = 1 + ((int) opcode < (int) BINOP_END); - } + operator_length (inexpr, inend, &oplen, &args); /* Copy the final operator itself, from the end of the input to the beginning of the output. */ @@ -1122,6 +1026,7 @@ parse_exp_1 (char **stringptr, struct block *block, int comma) struct cleanup *old_chain; lexptr = *stringptr; + prev_lexptr = NULL; paren_depth = 0; type_stack_depth = 0; @@ -1134,7 +1039,13 @@ parse_exp_1 (char **stringptr, struct block *block, int comma) old_chain = make_cleanup (free_funcalls, 0 /*ignore*/); funcall_chain = 0; - expression_context_block = block ? block : get_selected_block (); + if (block) + { + expression_context_block = block; + expression_context_pc = BLOCK_START (block); + } + else + expression_context_block = get_selected_block (&expression_context_pc); namecopy = (char *) alloca (strlen (lexptr) + 1); expout_size = 10; @@ -1162,14 +1073,13 @@ parse_exp_1 (char **stringptr, struct block *block, int comma) parser, to a prefix form. */ if (expressiondebug) - dump_prefix_expression (expout, gdb_stdlog, - "before conversion to prefix form"); + dump_raw_expression (expout, gdb_stdlog, + "before conversion to prefix form"); prefixify_expression (expout); if (expressiondebug) - dump_postfix_expression (expout, gdb_stdlog, - "after conversion to prefix form"); + dump_prefix_expression (expout, gdb_stdlog); *stringptr = lexptr; return expout; @@ -1181,7 +1091,7 @@ parse_exp_1 (char **stringptr, struct block *block, int comma) struct expression * parse_expression (char *string) { - register struct expression *exp; + struct expression *exp; exp = parse_exp_1 (&string, 0, 0); if (*string) error ("Junk after end of expression."); @@ -1351,63 +1261,23 @@ build_parse (void) init_type (TYPE_CODE_INT, 1, 0, "", NULL); +} - /* create the std_regs table */ - - num_std_regs = 0; -#ifdef PC_REGNUM - if (PC_REGNUM >= 0) - num_std_regs++; -#endif -#ifdef FP_REGNUM - if (FP_REGNUM >= 0) - num_std_regs++; -#endif -#ifdef SP_REGNUM - if (SP_REGNUM >= 0) - num_std_regs++; -#endif -#ifdef PS_REGNUM - if (PS_REGNUM >= 0) - num_std_regs++; -#endif - /* create an empty table */ - std_regs = xmalloc ((num_std_regs + 1) * sizeof *std_regs); - i = 0; - /* fill it in */ -#ifdef PC_REGNUM - if (PC_REGNUM >= 0) +/* This function avoids direct calls to fprintf + in the parser generated debug code. */ +void +parser_fprintf (FILE *x, const char *y, ...) +{ + va_list args; + va_start (args, y); + if (x == stderr) + vfprintf_unfiltered (gdb_stderr, y, args); + else { - std_regs[i].name = "pc"; - std_regs[i].regnum = PC_REGNUM; - i++; + fprintf_unfiltered (gdb_stderr, " Unknown FILE used.\n"); + vfprintf_unfiltered (gdb_stderr, y, args); } -#endif -#ifdef FP_REGNUM - if (FP_REGNUM >= 0) - { - std_regs[i].name = "fp"; - std_regs[i].regnum = FP_REGNUM; - i++; - } -#endif -#ifdef SP_REGNUM - if (SP_REGNUM >= 0) - { - std_regs[i].name = "sp"; - std_regs[i].regnum = SP_REGNUM; - i++; - } -#endif -#ifdef PS_REGNUM - if (PS_REGNUM >= 0) - { - std_regs[i].name = "ps"; - std_regs[i].regnum = PS_REGNUM; - i++; - } -#endif - memset (&std_regs[i], 0, sizeof (std_regs[i])); + va_end (args); } void @@ -1423,13 +1293,10 @@ _initialize_parse (void) /* FIXME - For the moment, handle types by swapping them in and out. Should be using the per-architecture data-pointer and a large struct. */ - register_gdbarch_swap (&msym_text_symbol_type, sizeof (msym_text_symbol_type), NULL); - register_gdbarch_swap (&msym_data_symbol_type, sizeof (msym_data_symbol_type), NULL); - register_gdbarch_swap (&msym_unknown_symbol_type, sizeof (msym_unknown_symbol_type), NULL); - - register_gdbarch_swap (&num_std_regs, sizeof (std_regs), NULL); - register_gdbarch_swap (&std_regs, sizeof (std_regs), NULL); - register_gdbarch_swap (NULL, 0, build_parse); + DEPRECATED_REGISTER_GDBARCH_SWAP (msym_text_symbol_type); + DEPRECATED_REGISTER_GDBARCH_SWAP (msym_data_symbol_type); + DEPRECATED_REGISTER_GDBARCH_SWAP (msym_unknown_symbol_type); + deprecated_register_gdbarch_swap (NULL, 0, build_parse); add_show_from_set ( add_set_cmd ("expression", class_maintenance, var_zinteger, diff --git a/contrib/gdb/gdb/parser-defs.h b/contrib/gdb/gdb/parser-defs.h index 66e929f6f3a..c84fcad2c1f 100644 --- a/contrib/gdb/gdb/parser-defs.h +++ b/contrib/gdb/gdb/parser-defs.h @@ -1,6 +1,8 @@ /* Parser definitions for GDB. - Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000 Free Software Foundation, Inc. + + Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. + Modified from expread.y by the Department of Computer Science at the State University of New York at Buffalo. @@ -26,14 +28,7 @@ #include "doublest.h" -struct std_regs - { - char *name; - int regnum; - }; - -extern struct std_regs *std_regs; -extern unsigned num_std_regs; +struct block; extern struct expression *expout; extern int expout_size; @@ -44,6 +39,12 @@ extern int expout_ptr; extern struct block *expression_context_block; +/* If expression_context_block is non-zero, then this is the PC within + the block that we want to evaluate expressions at. When debugging + C or C++ code, we use this to find the exact line we're at, and + then look up the macro definitions active at that point. */ +extern CORE_ADDR expression_context_pc; + /* The innermost context required by the stack and register variables we've encountered so far. */ extern struct block *innermost_block; @@ -80,6 +81,14 @@ struct symtoken int is_a_field_of_this; }; +struct objc_class_str + { + struct stoken stoken; + struct type *type; + int class; + }; + + /* For parsing of complicated types. An array should be preceded in the list by the size of the array. */ enum type_pieces @@ -150,6 +159,17 @@ extern int pop_type_int (void); extern int length_of_subexp (struct expression *, int); +extern int dump_subexp (struct expression *, struct ui_file *, int); + +extern int dump_subexp_body_standard (struct expression *, + struct ui_file *, int); + +extern void operator_length (struct expression *, int, int *, int *); + +extern void operator_length_standard (struct expression *, int, int *, int *); + +extern char *op_name_standard (enum exp_opcode); + extern struct type *follow_types (struct type *); /* During parsing of a C expression, the pointer to the next character @@ -157,6 +177,10 @@ extern struct type *follow_types (struct type *); extern char *lexptr; +/* After a token has been recognized, this variable points to it. + Currently used only for error reporting. */ +extern char *prev_lexptr; + /* Tokens that refer to names do so with explicit pointer and length, so they can share the storage that lexptr is parsing. @@ -207,10 +231,49 @@ struct op_print int right_assoc; }; -/* The generic method for targets to specify how their registers are - named. The mapping can be derived from three sources: - REGISTER_NAME; std_regs; or a target specific alias hook. */ +/* Information needed to print, prefixify, and evaluate expressions for + a given language. */ -extern int target_map_name_to_register (char *, int); +struct exp_descriptor + { + /* Print subexpression. */ + void (*print_subexp) (struct expression *, int *, struct ui_file *, + enum precedence); + + /* Returns number of exp_elements needed to represent an operator and + the number of subexpressions it takes. */ + void (*operator_length) (struct expression*, int, int*, int *); + + /* Name of this operator for dumping purposes. */ + char *(*op_name) (enum exp_opcode); + + /* Dump the rest of this (prefix) expression after the operator + itself has been printed. See dump_subexp_body_standard in + (expprint.c). */ + int (*dump_subexp_body) (struct expression *, struct ui_file *, int); + + /* Evaluate an expression. */ + struct value *(*evaluate_exp) (struct type *, struct expression *, + int *, enum noside); + }; + + +/* Default descriptor containing standard definitions of all + elements. */ +extern const struct exp_descriptor exp_descriptor_standard; + +/* Functions used by language-specific extended operators to (recursively) + print/dump subexpressions. */ + +extern void print_subexp (struct expression *, int *, struct ui_file *, + enum precedence); + +extern void print_subexp_standard (struct expression *, int *, + struct ui_file *, enum precedence); + +/* Function used to avoid direct calls to fprintf + in the code generated by the bison parser. */ + +extern void parser_fprintf (FILE *, const char *, ...) ATTR_FORMAT (printf, 2 ,3); #endif /* PARSER_DEFS_H */ diff --git a/contrib/gdb/gdb/ppc-bdm.c b/contrib/gdb/gdb/ppc-bdm.c index b2287ead93e..2355b2c74eb 100644 --- a/contrib/gdb/gdb/ppc-bdm.c +++ b/contrib/gdb/gdb/ppc-bdm.c @@ -201,6 +201,7 @@ bdm_ppc_fetch_registers (int regno) /* if asking for an invalid register */ if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) + || (first_regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) || ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM))) { /* printf("invalid reg request!\n"); */ @@ -289,10 +290,12 @@ bdm_ppc_store_registers (int regno) /* only attempt to write if it's a valid ppc 8xx register */ /* (need to avoid FP regs and MQ reg) */ - if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM))) + if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) + && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) + && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM))) { /* printf("write valid reg %d\n", bdm_regno); */ - ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4); + ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4); } /* else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) @@ -318,14 +321,9 @@ a wiggler, specify wiggler and then the port it is connected to\n\ (e.g. wiggler lpt1)."; /* to_doc */ bdm_ppc_ops.to_open = bdm_ppc_open; bdm_ppc_ops.to_close = ocd_close; - bdm_ppc_ops.to_attach = NULL; - bdm_ppc_ops.to_post_attach = NULL; - bdm_ppc_ops.to_require_attach = NULL; bdm_ppc_ops.to_detach = ocd_detach; - bdm_ppc_ops.to_require_detach = NULL; bdm_ppc_ops.to_resume = ocd_resume; bdm_ppc_ops.to_wait = bdm_ppc_wait; - bdm_ppc_ops.to_post_wait = NULL; bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers; bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers; bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store; @@ -333,50 +331,23 @@ a wiggler, specify wiggler and then the port it is connected to\n\ bdm_ppc_ops.to_files_info = ocd_files_info; bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint; bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint; - bdm_ppc_ops.to_terminal_init = NULL; - bdm_ppc_ops.to_terminal_inferior = NULL; - bdm_ppc_ops.to_terminal_ours_for_output = NULL; - bdm_ppc_ops.to_terminal_ours = NULL; - bdm_ppc_ops.to_terminal_info = NULL; bdm_ppc_ops.to_kill = ocd_kill; bdm_ppc_ops.to_load = ocd_load; - bdm_ppc_ops.to_lookup_symbol = NULL; bdm_ppc_ops.to_create_inferior = ocd_create_inferior; - bdm_ppc_ops.to_post_startup_inferior = NULL; - bdm_ppc_ops.to_acknowledge_created_inferior = NULL; - bdm_ppc_ops.to_clone_and_follow_inferior = NULL; - bdm_ppc_ops.to_post_follow_inferior_by_clone = NULL; - bdm_ppc_ops.to_insert_fork_catchpoint = NULL; - bdm_ppc_ops.to_remove_fork_catchpoint = NULL; - bdm_ppc_ops.to_insert_vfork_catchpoint = NULL; - bdm_ppc_ops.to_remove_vfork_catchpoint = NULL; - bdm_ppc_ops.to_has_forked = NULL; - bdm_ppc_ops.to_has_vforked = NULL; - bdm_ppc_ops.to_can_follow_vfork_prior_to_exec = NULL; - bdm_ppc_ops.to_post_follow_vfork = NULL; - bdm_ppc_ops.to_insert_exec_catchpoint = NULL; - bdm_ppc_ops.to_remove_exec_catchpoint = NULL; - bdm_ppc_ops.to_has_execd = NULL; - bdm_ppc_ops.to_reported_exec_events_per_exec_call = NULL; - bdm_ppc_ops.to_has_exited = NULL; bdm_ppc_ops.to_mourn_inferior = ocd_mourn; - bdm_ppc_ops.to_can_run = 0; - bdm_ppc_ops.to_notice_signals = 0; bdm_ppc_ops.to_thread_alive = ocd_thread_alive; bdm_ppc_ops.to_stop = ocd_stop; - bdm_ppc_ops.to_pid_to_exec_file = NULL; bdm_ppc_ops.to_stratum = process_stratum; - bdm_ppc_ops.DONT_USE = NULL; bdm_ppc_ops.to_has_all_memory = 1; bdm_ppc_ops.to_has_memory = 1; bdm_ppc_ops.to_has_stack = 1; bdm_ppc_ops.to_has_registers = 1; bdm_ppc_ops.to_has_execution = 1; - bdm_ppc_ops.to_sections = NULL; - bdm_ppc_ops.to_sections_end = NULL; bdm_ppc_ops.to_magic = OPS_MAGIC; } /* init_bdm_ppc_ops */ +extern initialize_file_ftype _initialize_bdm_ppc; /* -Wmissing-prototypes */ + void _initialize_bdm_ppc (void) { diff --git a/contrib/gdb/gdb/ppc-sysv-tdep.c b/contrib/gdb/gdb/ppc-sysv-tdep.c new file mode 100644 index 00000000000..60cf986bd72 --- /dev/null +++ b/contrib/gdb/gdb/ppc-sysv-tdep.c @@ -0,0 +1,1002 @@ +/* Target-dependent code for PowerPC systems using the SVR4 ABI + for GDB, the GNU debugger. + + Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "inferior.h" +#include "regcache.h" +#include "value.h" +#include "gdb_string.h" +#include "gdb_assert.h" +#include "ppc-tdep.h" +#include "target.h" +#include "objfiles.h" + +/* Pass the arguments in either registers, or in the stack. Using the + ppc sysv ABI, the first eight words of the argument list (that might + be less than eight parameters if some parameters occupy more than one + word) are passed in r3..r10 registers. float and double parameters are + passed in fpr's, in addition to that. Rest of the parameters if any + are passed in user stack. + + If the function is returning a structure, then the return address is passed + in r3, then the first 7 words of the parametes can be passed in registers, + starting from r4. */ + +CORE_ADDR +ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + const CORE_ADDR saved_sp = read_sp (); + int argspace = 0; /* 0 is an initial wrong guess. */ + int write_pass; + + /* Go through the argument list twice. + + Pass 1: Figure out how much new stack space is required for + arguments and pushed values. Unlike the PowerOpen ABI, the SysV + ABI doesn't reserve any extra space for parameters which are put + in registers, but does always push structures and then pass their + address. + + Pass 2: Replay the same computation but this time also write the + values out to the target. */ + + for (write_pass = 0; write_pass < 2; write_pass++) + { + int argno; + /* Next available floating point register for float and double + arguments. */ + int freg = 1; + /* Next available general register for non-float, non-vector + arguments. */ + int greg = 3; + /* Next available vector register for vector arguments. */ + int vreg = 2; + /* Arguments start above the "LR save word" and "Back chain". */ + int argoffset = 2 * tdep->wordsize; + /* Structures start after the arguments. */ + int structoffset = argoffset + argspace; + + /* If the function is returning a `struct', then the first word + (which will be passed in r3) is used for struct return + address. In that case we should advance one word and start + from r4 register to copy parameters. */ + if (struct_return) + { + if (write_pass) + regcache_cooked_write_signed (regcache, + tdep->ppc_gp0_regnum + greg, + struct_addr); + greg++; + } + + for (argno = 0; argno < nargs; argno++) + { + struct value *arg = args[argno]; + struct type *type = check_typedef (VALUE_TYPE (arg)); + int len = TYPE_LENGTH (type); + char *val = VALUE_CONTENTS (arg); + + if (TYPE_CODE (type) == TYPE_CODE_FLT + && ppc_floating_point_unit_p (current_gdbarch) && len <= 8) + { + /* Floating point value converted to "double" then + passed in an FP register, when the registers run out, + 8 byte aligned stack is used. */ + if (freg <= 8) + { + if (write_pass) + { + /* Always store the floating point value using + the register's floating-point format. */ + char regval[MAX_REGISTER_SIZE]; + struct type *regtype + = register_type (gdbarch, FP0_REGNUM + freg); + convert_typed_floating (val, type, regval, regtype); + regcache_cooked_write (regcache, FP0_REGNUM + freg, + regval); + } + freg++; + } + else + { + /* SysV ABI converts floats to doubles before + writing them to an 8 byte aligned stack location. */ + argoffset = align_up (argoffset, 8); + if (write_pass) + { + char memval[8]; + struct type *memtype; + switch (TARGET_BYTE_ORDER) + { + case BFD_ENDIAN_BIG: + memtype = builtin_type_ieee_double_big; + break; + case BFD_ENDIAN_LITTLE: + memtype = builtin_type_ieee_double_little; + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + convert_typed_floating (val, type, memval, memtype); + write_memory (sp + argoffset, val, len); + } + argoffset += 8; + } + } + else if (len == 8 && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */ + || (!ppc_floating_point_unit_p (current_gdbarch) && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */ + { + /* "long long" or "double" passed in an odd/even + register pair with the low addressed word in the odd + register and the high addressed word in the even + register, or when the registers run out an 8 byte + aligned stack location. */ + if (greg > 9) + { + /* Just in case GREG was 10. */ + greg = 11; + argoffset = align_up (argoffset, 8); + if (write_pass) + write_memory (sp + argoffset, val, len); + argoffset += 8; + } + else if (tdep->wordsize == 8) + { + if (write_pass) + regcache_cooked_write (regcache, + tdep->ppc_gp0_regnum + greg, val); + greg += 1; + } + else + { + /* Must start on an odd register - r3/r4 etc. */ + if ((greg & 1) == 0) + greg++; + if (write_pass) + { + regcache_cooked_write (regcache, + tdep->ppc_gp0_regnum + greg + 0, + val + 0); + regcache_cooked_write (regcache, + tdep->ppc_gp0_regnum + greg + 1, + val + 4); + } + greg += 2; + } + } + else if (len == 16 + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type) && tdep->ppc_vr0_regnum >= 0) + { + /* Vector parameter passed in an Altivec register, or + when that runs out, 16 byte aligned stack location. */ + if (vreg <= 13) + { + if (write_pass) + regcache_cooked_write (current_regcache, + tdep->ppc_vr0_regnum + vreg, val); + vreg++; + } + else + { + argoffset = align_up (argoffset, 16); + if (write_pass) + write_memory (sp + argoffset, val, 16); + argoffset += 16; + } + } + else if (len == 8 + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type) && tdep->ppc_ev0_regnum >= 0) + { + /* Vector parameter passed in an e500 register, or when + that runs out, 8 byte aligned stack location. Note + that since e500 vector and general purpose registers + both map onto the same underlying register set, a + "greg" and not a "vreg" is consumed here. A cooked + write stores the value in the correct locations + within the raw register cache. */ + if (greg <= 10) + { + if (write_pass) + regcache_cooked_write (current_regcache, + tdep->ppc_ev0_regnum + greg, val); + greg++; + } + else + { + argoffset = align_up (argoffset, 8); + if (write_pass) + write_memory (sp + argoffset, val, 8); + argoffset += 8; + } + } + else + { + /* Reduce the parameter down to something that fits in a + "word". */ + char word[MAX_REGISTER_SIZE]; + memset (word, 0, MAX_REGISTER_SIZE); + if (len > tdep->wordsize + || TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION) + { + /* Structs and large values are put on an 8 byte + aligned stack ... */ + structoffset = align_up (structoffset, 8); + if (write_pass) + write_memory (sp + structoffset, val, len); + /* ... and then a "word" pointing to that address is + passed as the parameter. */ + store_unsigned_integer (word, tdep->wordsize, + sp + structoffset); + structoffset += len; + } + else if (TYPE_CODE (type) == TYPE_CODE_INT) + /* Sign or zero extend the "int" into a "word". */ + store_unsigned_integer (word, tdep->wordsize, + unpack_long (type, val)); + else + /* Always goes in the low address. */ + memcpy (word, val, len); + /* Store that "word" in a register, or on the stack. + The words have "4" byte alignment. */ + if (greg <= 10) + { + if (write_pass) + regcache_cooked_write (regcache, + tdep->ppc_gp0_regnum + greg, word); + greg++; + } + else + { + argoffset = align_up (argoffset, tdep->wordsize); + if (write_pass) + write_memory (sp + argoffset, word, tdep->wordsize); + argoffset += tdep->wordsize; + } + } + } + + /* Compute the actual stack space requirements. */ + if (!write_pass) + { + /* Remember the amount of space needed by the arguments. */ + argspace = argoffset; + /* Allocate space for both the arguments and the structures. */ + sp -= (argoffset + structoffset); + /* Ensure that the stack is still 16 byte aligned. */ + sp = align_down (sp, 16); + } + } + + /* Update %sp. */ + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + + /* Write the backchain (it occupies WORDSIZED bytes). */ + write_memory_signed_integer (sp, tdep->wordsize, saved_sp); + + /* Point the inferior function call's return address at the dummy's + breakpoint. */ + regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); + + return sp; +} + +/* Handle the return-value conventions specified by the SysV 32-bit + PowerPC ABI (including all the supplements): + + no floating-point: floating-point values returned using 32-bit + general-purpose registers. + + Altivec: 128-bit vectors returned using vector registers. + + e500: 64-bit vectors returned using the full full 64 bit EV + register, floating-point values returned using 32-bit + general-purpose registers. + + GCC (broken): Small struct values right (instead of left) aligned + when returned in general-purpose registers. */ + +static enum return_value_convention +do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, void *readbuf, + const void *writebuf, int broken_gcc) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_assert (tdep->wordsize == 4); + if (TYPE_CODE (type) == TYPE_CODE_FLT + && TYPE_LENGTH (type) <= 8 + && ppc_floating_point_unit_p (gdbarch)) + { + if (readbuf) + { + /* Floats and doubles stored in "f1". Convert the value to + the required type. */ + char regval[MAX_REGISTER_SIZE]; + struct type *regtype = register_type (gdbarch, FP0_REGNUM + 1); + regcache_cooked_read (regcache, FP0_REGNUM + 1, regval); + convert_typed_floating (regval, regtype, readbuf, type); + } + if (writebuf) + { + /* Floats and doubles stored in "f1". Convert the value to + the register's "double" type. */ + char regval[MAX_REGISTER_SIZE]; + struct type *regtype = register_type (gdbarch, FP0_REGNUM); + convert_typed_floating (writebuf, type, regval, regtype); + regcache_cooked_write (regcache, FP0_REGNUM + 1, regval); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + if ((TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 8) + || (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)) + { + if (readbuf) + { + /* A long long, or a double stored in the 32 bit r3/r4. */ + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, + (bfd_byte *) readbuf + 0); + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, + (bfd_byte *) readbuf + 4); + } + if (writebuf) + { + /* A long long, or a double stored in the 32 bit r3/r4. */ + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, + (const bfd_byte *) writebuf + 0); + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, + (const bfd_byte *) writebuf + 4); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_CODE (type) == TYPE_CODE_INT + && TYPE_LENGTH (type) <= tdep->wordsize) + { + if (readbuf) + { + /* Some sort of integer stored in r3. Since TYPE isn't + bigger than the register, sign extension isn't a problem + - just do everything unsigned. */ + ULONGEST regval; + regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3, + ®val); + store_unsigned_integer (readbuf, TYPE_LENGTH (type), regval); + } + if (writebuf) + { + /* Some sort of integer stored in r3. Use unpack_long since + that should handle any required sign extension. */ + regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, + unpack_long (type, writebuf)); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_LENGTH (type) == 16 + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type) && tdep->ppc_vr0_regnum >= 0) + { + if (readbuf) + { + /* Altivec places the return value in "v2". */ + regcache_cooked_read (regcache, tdep->ppc_vr0_regnum + 2, readbuf); + } + if (writebuf) + { + /* Altivec places the return value in "v2". */ + regcache_cooked_write (regcache, tdep->ppc_vr0_regnum + 2, writebuf); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_LENGTH (type) == 8 + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type) && tdep->ppc_ev0_regnum >= 0) + { + /* The e500 ABI places return values for the 64-bit DSP types + (__ev64_opaque__) in r3. However, in GDB-speak, ev3 + corresponds to the entire r3 value for e500, whereas GDB's r3 + only corresponds to the least significant 32-bits. So place + the 64-bit DSP type's value in ev3. */ + if (readbuf) + regcache_cooked_read (regcache, tdep->ppc_ev0_regnum + 3, readbuf); + if (writebuf) + regcache_cooked_write (regcache, tdep->ppc_ev0_regnum + 3, writebuf); + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (broken_gcc && TYPE_LENGTH (type) <= 8) + { + if (readbuf) + { + /* GCC screwed up. The last register isn't "left" aligned. + Need to extract the least significant part of each + register and then store that. */ + /* Transfer any full words. */ + int word = 0; + while (1) + { + ULONGEST reg; + int len = TYPE_LENGTH (type) - word * tdep->wordsize; + if (len <= 0) + break; + if (len > tdep->wordsize) + len = tdep->wordsize; + regcache_cooked_read_unsigned (regcache, + tdep->ppc_gp0_regnum + 3 + word, + ®); + store_unsigned_integer (((bfd_byte *) readbuf + + word * tdep->wordsize), len, reg); + word++; + } + } + if (writebuf) + { + /* GCC screwed up. The last register isn't "left" aligned. + Need to extract the least significant part of each + register and then store that. */ + /* Transfer any full words. */ + int word = 0; + while (1) + { + ULONGEST reg; + int len = TYPE_LENGTH (type) - word * tdep->wordsize; + if (len <= 0) + break; + if (len > tdep->wordsize) + len = tdep->wordsize; + reg = extract_unsigned_integer (((const bfd_byte *) writebuf + + word * tdep->wordsize), len); + regcache_cooked_write_unsigned (regcache, + tdep->ppc_gp0_regnum + 3 + word, + reg); + word++; + } + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_LENGTH (type) <= 8) + { + if (readbuf) + { + /* This matches SVr4 PPC, it does not match GCC. */ + /* The value is right-padded to 8 bytes and then loaded, as + two "words", into r3/r4. */ + char regvals[MAX_REGISTER_SIZE * 2]; + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, + regvals + 0 * tdep->wordsize); + if (TYPE_LENGTH (type) > tdep->wordsize) + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, + regvals + 1 * tdep->wordsize); + memcpy (readbuf, regvals, TYPE_LENGTH (type)); + } + if (writebuf) + { + /* This matches SVr4 PPC, it does not match GCC. */ + /* The value is padded out to 8 bytes and then loaded, as + two "words" into r3/r4. */ + char regvals[MAX_REGISTER_SIZE * 2]; + memset (regvals, 0, sizeof regvals); + memcpy (regvals, writebuf, TYPE_LENGTH (type)); + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, + regvals + 0 * tdep->wordsize); + if (TYPE_LENGTH (type) > tdep->wordsize) + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, + regvals + 1 * tdep->wordsize); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + return RETURN_VALUE_STRUCT_CONVENTION; +} + +enum return_value_convention +ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, + struct regcache *regcache, void *readbuf, + const void *writebuf) +{ + return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf, + writebuf, 0); +} + +enum return_value_convention +ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, + struct type *valtype, + struct regcache *regcache, + void *readbuf, const void *writebuf) +{ + return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf, + writebuf, 1); +} + +/* Pass the arguments in either registers, or in the stack. Using the + ppc 64 bit SysV ABI. + + This implements a dumbed down version of the ABI. It always writes + values to memory, GPR and FPR, even when not necessary. Doing this + greatly simplifies the logic. */ + +CORE_ADDR +ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + /* By this stage in the proceedings, SP has been decremented by "red + zone size" + "struct return size". Fetch the stack-pointer from + before this and use that as the BACK_CHAIN. */ + const CORE_ADDR back_chain = read_sp (); + /* See for-loop comment below. */ + int write_pass; + /* Size of the Altivec's vector parameter region, the final value is + computed in the for-loop below. */ + LONGEST vparam_size = 0; + /* Size of the general parameter region, the final value is computed + in the for-loop below. */ + LONGEST gparam_size = 0; + /* Kevin writes ... I don't mind seeing tdep->wordsize used in the + calls to align_up(), align_down(), etc. because this makes it + easier to reuse this code (in a copy/paste sense) in the future, + but it is a 64-bit ABI and asserting that the wordsize is 8 bytes + at some point makes it easier to verify that this function is + correct without having to do a non-local analysis to figure out + the possible values of tdep->wordsize. */ + gdb_assert (tdep->wordsize == 8); + + /* Go through the argument list twice. + + Pass 1: Compute the function call's stack space and register + requirements. + + Pass 2: Replay the same computation but this time also write the + values out to the target. */ + + for (write_pass = 0; write_pass < 2; write_pass++) + { + int argno; + /* Next available floating point register for float and double + arguments. */ + int freg = 1; + /* Next available general register for non-vector (but possibly + float) arguments. */ + int greg = 3; + /* Next available vector register for vector arguments. */ + int vreg = 2; + /* The address, at which the next general purpose parameter + (integer, struct, float, ...) should be saved. */ + CORE_ADDR gparam; + /* Address, at which the next Altivec vector parameter should be + saved. */ + CORE_ADDR vparam; + + if (!write_pass) + { + /* During the first pass, GPARAM and VPARAM are more like + offsets (start address zero) than addresses. That way + the accumulate the total stack space each region + requires. */ + gparam = 0; + vparam = 0; + } + else + { + /* Decrement the stack pointer making space for the Altivec + and general on-stack parameters. Set vparam and gparam + to their corresponding regions. */ + vparam = align_down (sp - vparam_size, 16); + gparam = align_down (vparam - gparam_size, 16); + /* Add in space for the TOC, link editor double word, + compiler double word, LR save area, CR save area. */ + sp = align_down (gparam - 48, 16); + } + + /* If the function is returning a `struct', then there is an + extra hidden parameter (which will be passed in r3) + containing the address of that struct.. In that case we + should advance one word and start from r4 register to copy + parameters. This also consumes one on-stack parameter slot. */ + if (struct_return) + { + if (write_pass) + regcache_cooked_write_signed (regcache, + tdep->ppc_gp0_regnum + greg, + struct_addr); + greg++; + gparam = align_up (gparam + tdep->wordsize, tdep->wordsize); + } + + for (argno = 0; argno < nargs; argno++) + { + struct value *arg = args[argno]; + struct type *type = check_typedef (VALUE_TYPE (arg)); + char *val = VALUE_CONTENTS (arg); + if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8) + { + /* Floats and Doubles go in f1 .. f13. They also + consume a left aligned GREG,, and can end up in + memory. */ + if (write_pass) + { + if (ppc_floating_point_unit_p (current_gdbarch) + && freg <= 13) + { + char regval[MAX_REGISTER_SIZE]; + struct type *regtype = register_type (gdbarch, + FP0_REGNUM); + convert_typed_floating (val, type, regval, regtype); + regcache_cooked_write (regcache, FP0_REGNUM + freg, + regval); + } + if (greg <= 10) + { + /* The ABI states "Single precision floating + point values are mapped to the first word in + a single doubleword" and "... floating point + values mapped to the first eight doublewords + of the parameter save area are also passed in + general registers"). + + This code interprets that to mean: store it, + left aligned, in the general register. */ + char regval[MAX_REGISTER_SIZE]; + memset (regval, 0, sizeof regval); + memcpy (regval, val, TYPE_LENGTH (type)); + regcache_cooked_write (regcache, + tdep->ppc_gp0_regnum + greg, + regval); + } + write_memory (gparam, val, TYPE_LENGTH (type)); + } + /* Always consume parameter stack space. */ + freg++; + greg++; + gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); + } + else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type) + && TYPE_CODE (type) == TYPE_CODE_ARRAY + && tdep->ppc_vr0_regnum >= 0) + { + /* In the Altivec ABI, vectors go in the vector + registers v2 .. v13, or when that runs out, a vector + annex which goes above all the normal parameters. + NOTE: cagney/2003-09-21: This is a guess based on the + PowerOpen Altivec ABI. */ + if (vreg <= 13) + { + if (write_pass) + regcache_cooked_write (regcache, + tdep->ppc_vr0_regnum + vreg, val); + vreg++; + } + else + { + if (write_pass) + write_memory (vparam, val, TYPE_LENGTH (type)); + vparam = align_up (vparam + TYPE_LENGTH (type), 16); + } + } + else if ((TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_ENUM) + && TYPE_LENGTH (type) <= 8) + { + /* Scalars get sign[un]extended and go in gpr3 .. gpr10. + They can also end up in memory. */ + if (write_pass) + { + /* Sign extend the value, then store it unsigned. */ + ULONGEST word = unpack_long (type, val); + if (greg <= 10) + regcache_cooked_write_unsigned (regcache, + tdep->ppc_gp0_regnum + + greg, word); + write_memory_unsigned_integer (gparam, tdep->wordsize, + word); + } + greg++; + gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); + } + else + { + int byte; + for (byte = 0; byte < TYPE_LENGTH (type); + byte += tdep->wordsize) + { + if (write_pass && greg <= 10) + { + char regval[MAX_REGISTER_SIZE]; + int len = TYPE_LENGTH (type) - byte; + if (len > tdep->wordsize) + len = tdep->wordsize; + memset (regval, 0, sizeof regval); + /* WARNING: cagney/2003-09-21: As best I can + tell, the ABI specifies that the value should + be left aligned. Unfortunately, GCC doesn't + do this - it instead right aligns even sized + values and puts odd sized values on the + stack. Work around that by putting both a + left and right aligned value into the + register (hopefully no one notices :-^). + Arrrgh! */ + /* Left aligned (8 byte values such as pointers + fill the buffer). */ + memcpy (regval, val + byte, len); + /* Right aligned (but only if even). */ + if (len == 1 || len == 2 || len == 4) + memcpy (regval + tdep->wordsize - len, + val + byte, len); + regcache_cooked_write (regcache, greg, regval); + } + greg++; + } + if (write_pass) + /* WARNING: cagney/2003-09-21: Strictly speaking, this + isn't necessary, unfortunately, GCC appears to get + "struct convention" parameter passing wrong putting + odd sized structures in memory instead of in a + register. Work around this by always writing the + value to memory. Fortunately, doing this + simplifies the code. */ + write_memory (gparam, val, TYPE_LENGTH (type)); + /* Always consume parameter stack space. */ + gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); + } + } + + if (!write_pass) + { + /* Save the true region sizes ready for the second pass. */ + vparam_size = vparam; + /* Make certain that the general parameter save area is at + least the minimum 8 registers (or doublewords) in size. */ + if (greg < 8) + gparam_size = 8 * tdep->wordsize; + else + gparam_size = gparam; + } + } + + /* Update %sp. */ + regcache_cooked_write_signed (regcache, SP_REGNUM, sp); + + /* Write the backchain (it occupies WORDSIZED bytes). */ + write_memory_signed_integer (sp, tdep->wordsize, back_chain); + + /* Point the inferior function call's return address at the dummy's + breakpoint. */ + regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); + + /* Find a value for the TOC register. Every symbol should have both + ".FN" and "FN" in the minimal symbol table. "FN" points at the + FN's descriptor, while ".FN" points at the entry point (which + matches FUNC_ADDR). Need to reverse from FUNC_ADDR back to the + FN's descriptor address (while at the same time being careful to + find "FN" in the same object file as ".FN"). */ + { + /* Find the minimal symbol that corresponds to FUNC_ADDR (should + have the name ".FN"). */ + struct minimal_symbol *dot_fn = lookup_minimal_symbol_by_pc (func_addr); + if (dot_fn != NULL && SYMBOL_LINKAGE_NAME (dot_fn)[0] == '.') + { + /* Get the section that contains FUNC_ADR. Need this for the + "objfile" that it contains. */ + struct obj_section *dot_fn_section = find_pc_section (func_addr); + if (dot_fn_section != NULL && dot_fn_section->objfile != NULL) + { + /* Now find the corresponding "FN" (dropping ".") minimal + symbol's address. Only look for the minimal symbol in + ".FN"'s object file - avoids problems when two object + files (i.e., shared libraries) contain a minimal symbol + with the same name. */ + struct minimal_symbol *fn = + lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL, + dot_fn_section->objfile); + if (fn != NULL) + { + /* Got the address of that descriptor. The TOC is the + second double word. */ + CORE_ADDR toc = + read_memory_unsigned_integer (SYMBOL_VALUE_ADDRESS (fn) + + tdep->wordsize, + tdep->wordsize); + regcache_cooked_write_unsigned (regcache, + tdep->ppc_gp0_regnum + 2, toc); + } + } + } + } + + return sp; +} + + +/* The 64 bit ABI retun value convention. + + Return non-zero if the return-value is stored in a register, return + 0 if the return-value is instead stored on the stack (a.k.a., + struct return convention). + + For a return-value stored in a register: when WRITEBUF is non-NULL, + copy the buffer to the corresponding register return-value location + location; when READBUF is non-NULL, fill the buffer from the + corresponding register return-value location. */ +enum return_value_convention +ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, + struct regcache *regcache, void *readbuf, + const void *writebuf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* Floats and doubles in F1. */ + if (TYPE_CODE (valtype) == TYPE_CODE_FLT && TYPE_LENGTH (valtype) <= 8) + { + char regval[MAX_REGISTER_SIZE]; + struct type *regtype = register_type (gdbarch, FP0_REGNUM); + if (writebuf != NULL) + { + convert_typed_floating (writebuf, valtype, regval, regtype); + regcache_cooked_write (regcache, FP0_REGNUM + 1, regval); + } + if (readbuf != NULL) + { + regcache_cooked_read (regcache, FP0_REGNUM + 1, regval); + convert_typed_floating (regval, regtype, readbuf, valtype); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 8) + { + /* Integers in r3. */ + if (writebuf != NULL) + { + /* Be careful to sign extend the value. */ + regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, + unpack_long (valtype, writebuf)); + } + if (readbuf != NULL) + { + /* Extract the integer from r3. Since this is truncating the + value, there isn't a sign extension problem. */ + ULONGEST regval; + regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3, + ®val); + store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), regval); + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + /* All pointers live in r3. */ + if (TYPE_CODE (valtype) == TYPE_CODE_PTR) + { + /* All pointers live in r3. */ + if (writebuf != NULL) + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf); + if (readbuf != NULL) + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf); + return RETURN_VALUE_REGISTER_CONVENTION; + } + if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY + && TYPE_LENGTH (valtype) <= 8 + && TYPE_CODE (TYPE_TARGET_TYPE (valtype)) == TYPE_CODE_INT + && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1) + { + /* Small character arrays are returned, right justified, in r3. */ + int offset = (register_size (gdbarch, tdep->ppc_gp0_regnum + 3) + - TYPE_LENGTH (valtype)); + if (writebuf != NULL) + regcache_cooked_write_part (regcache, tdep->ppc_gp0_regnum + 3, + offset, TYPE_LENGTH (valtype), writebuf); + if (readbuf != NULL) + regcache_cooked_read_part (regcache, tdep->ppc_gp0_regnum + 3, + offset, TYPE_LENGTH (valtype), readbuf); + return RETURN_VALUE_REGISTER_CONVENTION; + } + /* Big floating point values get stored in adjacent floating + point registers. */ + if (TYPE_CODE (valtype) == TYPE_CODE_FLT + && (TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 32)) + { + if (writebuf || readbuf != NULL) + { + int i; + for (i = 0; i < TYPE_LENGTH (valtype) / 8; i++) + { + if (writebuf != NULL) + regcache_cooked_write (regcache, FP0_REGNUM + 1 + i, + (const bfd_byte *) writebuf + i * 8); + if (readbuf != NULL) + regcache_cooked_read (regcache, FP0_REGNUM + 1 + i, + (bfd_byte *) readbuf + i * 8); + } + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + /* Complex values get returned in f1:f2, need to convert. */ + if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX + && (TYPE_LENGTH (valtype) == 8 || TYPE_LENGTH (valtype) == 16)) + { + if (regcache != NULL) + { + int i; + for (i = 0; i < 2; i++) + { + char regval[MAX_REGISTER_SIZE]; + struct type *regtype = + register_type (current_gdbarch, FP0_REGNUM); + if (writebuf != NULL) + { + convert_typed_floating ((const bfd_byte *) writebuf + + i * (TYPE_LENGTH (valtype) / 2), + valtype, regval, regtype); + regcache_cooked_write (regcache, FP0_REGNUM + 1 + i, + regval); + } + if (readbuf != NULL) + { + regcache_cooked_read (regcache, FP0_REGNUM + 1 + i, regval); + convert_typed_floating (regval, regtype, + (bfd_byte *) readbuf + + i * (TYPE_LENGTH (valtype) / 2), + valtype); + } + } + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + /* Big complex values get stored in f1:f4. */ + if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX && TYPE_LENGTH (valtype) == 32) + { + if (regcache != NULL) + { + int i; + for (i = 0; i < 4; i++) + { + if (writebuf != NULL) + regcache_cooked_write (regcache, FP0_REGNUM + 1 + i, + (const bfd_byte *) writebuf + i * 8); + if (readbuf != NULL) + regcache_cooked_read (regcache, FP0_REGNUM + 1 + i, + (bfd_byte *) readbuf + i * 8); + } + } + return RETURN_VALUE_REGISTER_CONVENTION; + } + return RETURN_VALUE_STRUCT_CONVENTION; +} + +CORE_ADDR +ppc64_sysv_abi_adjust_breakpoint_address (struct gdbarch *gdbarch, + CORE_ADDR bpaddr) +{ + /* PPC64 SYSV specifies that the minimal-symbol "FN" should point at + a function-descriptor while the corresponding minimal-symbol + ".FN" should point at the entry point. Consequently, a command + like "break FN" applied to an object file with only minimal + symbols, will insert the breakpoint into the descriptor at "FN" + and not the function at ".FN". Avoid this confusion by adjusting + any attempt to set a descriptor breakpoint into a corresponding + function breakpoint. Note that GDB warns the user when this + adjustment is applied - that's ok as otherwise the user will have + no way of knowing why their breakpoint at "FN" resulted in the + program stopping at ".FN". */ + return gdbarch_convert_from_func_ptr_addr (gdbarch, bpaddr, ¤t_target); +} diff --git a/contrib/gdb/gdb/ppc-tdep.h b/contrib/gdb/gdb/ppc-tdep.h index 029f87ca673..1c1c9ef21a3 100644 --- a/contrib/gdb/gdb/ppc-tdep.h +++ b/contrib/gdb/gdb/ppc-tdep.h @@ -1,5 +1,5 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright 2000 + Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -22,8 +22,11 @@ #ifndef PPC_TDEP_H #define PPC_TDEP_H +struct gdbarch; struct frame_info; struct value; +struct regcache; +struct type; /* From ppc-linux-tdep.c... */ CORE_ADDR ppc_linux_frame_saved_pc (struct frame_info *fi); @@ -31,11 +34,42 @@ void ppc_linux_init_extra_frame_info (int fromleaf, struct frame_info *); int ppc_linux_frameless_function_invocation (struct frame_info *); void ppc_linux_frame_init_saved_regs (struct frame_info *); CORE_ADDR ppc_linux_frame_chain (struct frame_info *); -CORE_ADDR ppc_sysv_abi_push_arguments (int, struct value **, CORE_ADDR, int, - CORE_ADDR); +enum return_value_convention ppc_sysv_abi_return_value (struct gdbarch *gdbarch, + struct type *valtype, + struct regcache *regcache, + void *readbuf, + const void *writebuf); +enum return_value_convention ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, + struct type *valtype, + struct regcache *regcache, + void *readbuf, + const void *writebuf); +CORE_ADDR ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, + CORE_ADDR func_addr, + struct regcache *regcache, + CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, + int struct_return, + CORE_ADDR struct_addr); +CORE_ADDR ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, + CORE_ADDR func_addr, + struct regcache *regcache, + CORE_ADDR bp_addr, int nargs, + struct value **args, CORE_ADDR sp, + int struct_return, + CORE_ADDR struct_addr); +CORE_ADDR ppc64_sysv_abi_adjust_breakpoint_address (struct gdbarch *gdbarch, + CORE_ADDR bpaddr); int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache); struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void); +void ppc_linux_supply_gregset (char *buf); +void ppc_linux_supply_fpregset (char *buf); +enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, + struct type *valtype, + struct regcache *regcache, + void *readbuf, + const void *writebuf); /* From rs6000-tdep.c... */ CORE_ADDR rs6000_frame_saved_pc (struct frame_info *fi); @@ -45,12 +79,16 @@ void rs6000_frame_init_saved_regs (struct frame_info *); CORE_ADDR rs6000_frame_chain (struct frame_info *); int altivec_register_p (int regno); + +/* Return non-zero when the architecture has an FPU (or at least when + the ABI is using the FPU). */ +int ppc_floating_point_unit_p (struct gdbarch *gdbarch); + /* Private data that this module attaches to struct gdbarch. */ struct gdbarch_tdep { int wordsize; /* size in bytes of fixed-point word */ - int osabi; /* OS / ABI from ELF header */ int *regoff; /* byte offsets in register arrays */ const struct reg *regs; /* from current variant */ int ppc_gp0_regnum; /* GPR register 0 */ @@ -61,9 +99,15 @@ struct gdbarch_tdep int ppc_lr_regnum; /* Link register */ int ppc_ctr_regnum; /* Count register */ int ppc_xer_regnum; /* Integer exception register */ + int ppc_fpscr_regnum; /* Floating point status and condition + register */ int ppc_mq_regnum; /* Multiply/Divide extension register */ int ppc_vr0_regnum; /* First AltiVec register */ int ppc_vrsave_regnum; /* Last AltiVec register */ + int ppc_ev0_regnum; /* First ev register */ + int ppc_ev31_regnum; /* Last ev register */ + int lr_frame_offset; /* Offset to ABI specific location where + link register is saved. */ }; #endif diff --git a/contrib/gdb/gdb/ppcbug-rom.c b/contrib/gdb/gdb/ppcbug-rom.c new file mode 100644 index 00000000000..0619964eef3 --- /dev/null +++ b/contrib/gdb/gdb/ppcbug-rom.c @@ -0,0 +1,225 @@ +/* Remote debugging interface for PPCbug (PowerPC) Rom monitor + for GDB, the GNU debugger. + Copyright 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + Written by Stu Grossman of Cygnus Support + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "monitor.h" +#include "serial.h" +#include "regcache.h" + +static void +ppcbug_supply_register (char *regname, int regnamelen, char *val, int vallen) +{ + int regno = 0; + + if (regnamelen < 2 || regnamelen > 4) + return; + + switch (regname[0]) + { + case 'R': + if (regname[1] < '0' || regname[1] > '9') + return; + if (regnamelen == 2) + regno = regname[1] - '0'; + else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9') + regno = (regname[1] - '0') * 10 + (regname[2] - '0'); + else + return; + break; + case 'F': + if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9') + return; + if (regnamelen == 3) + regno = 32 + regname[2] - '0'; + else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9') + regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0'); + else + return; + break; + case 'I': + if (regnamelen != 2 || regname[1] != 'P') + return; + regno = 64; + break; + case 'M': + if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R') + return; + regno = 65; + break; + case 'C': + if (regnamelen != 2 || regname[1] != 'R') + return; + regno = 66; + break; + case 'S': + if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R') + return; + else if (regname[3] == '8') + regno = 67; + else if (regname[3] == '9') + regno = 68; + else if (regname[3] == '1') + regno = 69; + else if (regname[3] == '0') + regno = 70; + else + return; + break; + default: + return; + } + + monitor_supply_register (regno, val); +} + +/* + * This array of registers needs to match the indexes used by GDB. The + * whole reason this exists is because the various ROM monitors use + * different names than GDB does, and don't support all the + * registers either. So, typing "info reg sp" becomes an "A7". + */ + +static char *ppcbug_regnames[] = +{ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + + "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", + "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", + "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", + "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31", + +/* pc ps cnd lr cnt xer mq */ + "ip", "msr", "cr", "spr8", "spr9", "spr1", "spr0" +}; + +/* + * Define the monitor command strings. Since these are passed directly + * through to a printf style function, we need can include formatting + * strings. We also need a CR or LF on the end. + */ + +static struct target_ops ppcbug_ops0; +static struct target_ops ppcbug_ops1; + +static char *ppcbug_inits[] = +{"\r", NULL}; + +static void +init_ppc_cmds (char *LOAD_CMD, + struct monitor_ops *OPS, + struct target_ops *targops) +{ + OPS->flags = MO_CLR_BREAK_USES_ADDR | MO_HANDLE_NL; + OPS->init = ppcbug_inits; /* Init strings */ + OPS->cont = "g\r"; /* continue command */ + OPS->step = "t\r"; /* single step */ + OPS->stop = NULL; /* interrupt command */ + OPS->set_break = "br %x\r"; /* set a breakpoint */ + OPS->clr_break = "nobr %x\r"; /* clear a breakpoint */ + OPS->clr_all_break = "nobr\r"; /* clear all breakpoints */ + OPS->fill = "bf %x:%x %x;b\r"; /* fill (start count val) */ + OPS->setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */ + OPS->setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */ + OPS->setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */ + OPS->setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ + OPS->setmem.resp_delim = NULL; /* setreg.resp_delim */ + OPS->setmem.term = NULL; /* setreg.term */ + OPS->setmem.term_cmd = NULL; /* setreg.term_cmd */ + OPS->getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */ + OPS->getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */ + OPS->getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */ + OPS->getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ + OPS->getmem.resp_delim = " "; /* getmem.resp_delim */ + OPS->getmem.term = NULL; /* getmem.term */ + OPS->getmem.term_cmd = NULL; /* getmem.term_cmd */ + OPS->setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */ + OPS->setreg.resp_delim = NULL; /* setreg.resp_delim */ + OPS->setreg.term = NULL; /* setreg.term */ + OPS->setreg.term_cmd = NULL; /* setreg.term_cmd */ + OPS->getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */ + OPS->getreg.resp_delim = "="; /* getreg.resp_delim */ + OPS->getreg.term = NULL; /* getreg.term */ + OPS->getreg.term_cmd = NULL; /* getreg.term_cmd */ + OPS->register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ + OPS->supply_register = ppcbug_supply_register; /* supply_register */ + OPS->dump_registers = "rd\r"; /* dump all registers */ + OPS->load_routine = NULL; /* load_routine (defaults to SRECs) */ + OPS->load = LOAD_CMD; /* download command */ + OPS->loadresp = NULL; /* load response */ + OPS->prompt = "PPC1-Bug>"; /* monitor command prompt */ + OPS->line_term = "\r"; /* end-of-line terminator */ + OPS->cmd_end = NULL; /* optional command terminator */ + OPS->target = targops; /* target operations */ + OPS->stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ + OPS->regnames = ppcbug_regnames; /* registers names */ + OPS->magic = MONITOR_OPS_MAGIC; /* magic */ +} + + +static struct monitor_ops ppcbug_cmds0; +static struct monitor_ops ppcbug_cmds1; + +static void +ppcbug_open0 (char *args, int from_tty) +{ + monitor_open (args, &ppcbug_cmds0, from_tty); +} + +static void +ppcbug_open1 (char *args, int from_tty) +{ + monitor_open (args, &ppcbug_cmds1, from_tty); +} + +extern initialize_file_ftype _initialize_ppcbug_rom; /* -Wmissing-prototypes */ + +void +_initialize_ppcbug_rom (void) +{ + init_ppc_cmds ("lo 0\r", &ppcbug_cmds0, &ppcbug_ops0); + init_ppc_cmds ("lo 1\r", &ppcbug_cmds1, &ppcbug_ops1); + init_monitor_ops (&ppcbug_ops0); + + ppcbug_ops0.to_shortname = "ppcbug"; + ppcbug_ops0.to_longname = "PowerPC PPCBug monitor on port 0"; + ppcbug_ops0.to_doc = "Debug via the PowerPC PPCBug monitor using port 0.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + ppcbug_ops0.to_open = ppcbug_open0; + + add_target (&ppcbug_ops0); + + init_monitor_ops (&ppcbug_ops1); + + ppcbug_ops1.to_shortname = "ppcbug1"; + ppcbug_ops1.to_longname = "PowerPC PPCBug monitor on port 1"; + ppcbug_ops1.to_doc = "Debug via the PowerPC PPCBug monitor using port 1.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + ppcbug_ops1.to_open = ppcbug_open1; + + add_target (&ppcbug_ops1); +} diff --git a/contrib/gdb/gdb/ppcnbsd-nat.c b/contrib/gdb/gdb/ppcnbsd-nat.c index 55acf95fb21..ce097d7a59d 100644 --- a/contrib/gdb/gdb/ppcnbsd-nat.c +++ b/contrib/gdb/gdb/ppcnbsd-nat.c @@ -1,6 +1,6 @@ /* Native-dependent code for PowerPC's running NetBSD, for GDB. - Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001 - Free Software Foundation, Inc. + Copyright 2002 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. This file is part of GDB. @@ -22,124 +22,100 @@ #include #include #include -#include #include "defs.h" #include "inferior.h" -#include "gdbcore.h" -#include "ppc-tdep.h" -#include "regcache.h" -#define RF(dst, src) \ - memcpy(®isters[REGISTER_BYTE(dst)], &src, sizeof(src)) - -#define RS(src, dst) \ - memcpy(&dst, ®isters[REGISTER_BYTE(src)], sizeof(dst)) +#include "ppc-tdep.h" +#include "ppcnbsd-tdep.h" + +/* Returns true if PT_GETREGS fetches this register. */ +static int +getregs_supplies (int regno) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + return ((regno >= 0 && regno <= 31) + || regno == tdep->ppc_lr_regnum + || regno == tdep->ppc_cr_regnum + || regno == tdep->ppc_xer_regnum + || regno == tdep->ppc_ctr_regnum + || regno == PC_REGNUM); +} + +/* Like above, but for PT_GETFPREGS. */ +static int +getfpregs_supplies (int regno) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + return ((regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31) + || regno == tdep->ppc_fpscr_regnum); +} void fetch_inferior_registers (int regno) { - struct reg inferior_registers; -#ifdef PT_GETFPREGS - struct fpreg inferior_fp_registers; -#endif - int i; + if (regno == -1 || getregs_supplies (regno)) + { + struct reg regs; - ptrace (PT_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0); - for (i = 0; i < 32; i++) - RF (i, inferior_registers.fixreg[i]); - RF (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum, inferior_registers.lr); - RF (gdbarch_tdep (current_gdbarch)->ppc_cr_regnum, inferior_registers.cr); - RF (gdbarch_tdep (current_gdbarch)->ppc_xer_regnum, inferior_registers.xer); - RF (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum, inferior_registers.ctr); - RF (PC_REGNUM, inferior_registers.pc); + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); -#ifdef PT_GETFPREGS - ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0); - for (i = 0; i < 32; i++) - RF (FP0_REGNUM + i, inferior_fp_registers.fpreg[i]); -#endif + ppcnbsd_supply_reg ((char *) ®s, regno); + if (regno != -1) + return; + } - registers_fetched (); + if (regno == -1 || getfpregs_supplies (regno)) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get FP registers"); + + ppcnbsd_supply_fpreg ((char *) &fpregs, regno); + if (regno != -1) + return; + } } void store_inferior_registers (int regno) { - struct reg inferior_registers; -#ifdef PT_SETFPREGS - struct fpreg inferior_fp_registers; -#endif - int i; + if (regno == -1 || getregs_supplies (regno)) + { + struct reg regs; - for (i = 0; i < 32; i++) - RS (i, inferior_registers.fixreg[i]); - RS (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum, inferior_registers.lr); - RS (gdbarch_tdep (current_gdbarch)->ppc_cr_regnum, inferior_registers.cr); - RS (gdbarch_tdep (current_gdbarch)->ppc_xer_regnum, inferior_registers.xer); - RS (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum, inferior_registers.ctr); - RS (PC_REGNUM, inferior_registers.pc); + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); - ptrace (PT_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0); + ppcnbsd_fill_reg ((char *) ®s, regno); -#ifdef PT_SETFPREGS - for (i = 0; i < 32; i++) - RS (FP0_REGNUM + i, inferior_fp_registers.fpreg[i]); - ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0); -#endif -} - -struct md_core -{ - struct reg intreg; -#ifdef PT_GETFPREGS - struct fpreg freg; -#endif -}; - -void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR ignore) -{ - struct md_core *core_reg = (struct md_core *) core_reg_sect; - int i; - - /* Integer registers */ - for (i = 0; i < 32; i++) - RF (i, core_reg->intreg.fixreg[i]); - RF (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum, core_reg->intreg.lr); - RF (gdbarch_tdep (current_gdbarch)->ppc_cr_regnum, core_reg->intreg.cr); - RF (gdbarch_tdep (current_gdbarch)->ppc_xer_regnum, core_reg->intreg.xer); - RF (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum, core_reg->intreg.ctr); - RF (PC_REGNUM, core_reg->intreg.pc); - -#ifdef PT_FPGETREGS - /* Floating point registers */ - for (i = 0; i < 32; i++) - RF (FP0_REGNUM + i, core_reg->freg.fpreg[i]); -#endif - - registers_fetched (); -} - -/* Register that we are able to handle ppcnbsd core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns ppcnbsd_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -void -_initialize_ppcnbsd_nat (void) -{ - add_core_fns (&ppcnbsd_core_fns); + if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't write registers"); + + if (regno != -1) + return; + } + + if (regno == -1 || getfpregs_supplies (regno)) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get FP registers"); + + ppcnbsd_fill_fpreg ((char *) &fpregs, regno); + + if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't set FP registers"); + } } diff --git a/contrib/gdb/gdb/ppcnbsd-tdep.c b/contrib/gdb/gdb/ppcnbsd-tdep.c new file mode 100644 index 00000000000..adc2a4f1386 --- /dev/null +++ b/contrib/gdb/gdb/ppcnbsd-tdep.c @@ -0,0 +1,250 @@ +/* Target-dependent code for PowerPC systems running NetBSD. + Copyright 2002, 2003 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "regcache.h" +#include "target.h" +#include "breakpoint.h" +#include "value.h" +#include "osabi.h" + +#include "ppc-tdep.h" +#include "ppcnbsd-tdep.h" +#include "nbsd-tdep.h" + +#include "solib-svr4.h" + +#define REG_FIXREG_OFFSET(x) ((x) * 4) +#define REG_LR_OFFSET (32 * 4) +#define REG_CR_OFFSET (33 * 4) +#define REG_XER_OFFSET (34 * 4) +#define REG_CTR_OFFSET (35 * 4) +#define REG_PC_OFFSET (36 * 4) +#define SIZEOF_STRUCT_REG (37 * 4) + +#define FPREG_FPR_OFFSET(x) ((x) * 8) +#define FPREG_FPSCR_OFFSET (32 * 8) +#define SIZEOF_STRUCT_FPREG (33 * 8) + +void +ppcnbsd_supply_reg (char *regs, int regno) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + int i; + + for (i = 0; i <= 31; i++) + { + if (regno == i || regno == -1) + supply_register (i, regs + REG_FIXREG_OFFSET (i)); + } + + if (regno == tdep->ppc_lr_regnum || regno == -1) + supply_register (tdep->ppc_lr_regnum, regs + REG_LR_OFFSET); + + if (regno == tdep->ppc_cr_regnum || regno == -1) + supply_register (tdep->ppc_cr_regnum, regs + REG_CR_OFFSET); + + if (regno == tdep->ppc_xer_regnum || regno == -1) + supply_register (tdep->ppc_xer_regnum, regs + REG_XER_OFFSET); + + if (regno == tdep->ppc_ctr_regnum || regno == -1) + supply_register (tdep->ppc_ctr_regnum, regs + REG_CTR_OFFSET); + + if (regno == PC_REGNUM || regno == -1) + supply_register (PC_REGNUM, regs + REG_PC_OFFSET); +} + +void +ppcnbsd_fill_reg (char *regs, int regno) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + int i; + + for (i = 0; i <= 31; i++) + { + if (regno == i || regno == -1) + regcache_collect (i, regs + REG_FIXREG_OFFSET (i)); + } + + if (regno == tdep->ppc_lr_regnum || regno == -1) + regcache_collect (tdep->ppc_lr_regnum, regs + REG_LR_OFFSET); + + if (regno == tdep->ppc_cr_regnum || regno == -1) + regcache_collect (tdep->ppc_cr_regnum, regs + REG_CR_OFFSET); + + if (regno == tdep->ppc_xer_regnum || regno == -1) + regcache_collect (tdep->ppc_xer_regnum, regs + REG_XER_OFFSET); + + if (regno == tdep->ppc_ctr_regnum || regno == -1) + regcache_collect (tdep->ppc_ctr_regnum, regs + REG_CTR_OFFSET); + + if (regno == PC_REGNUM || regno == -1) + regcache_collect (PC_REGNUM, regs + REG_PC_OFFSET); +} + +void +ppcnbsd_supply_fpreg (char *fpregs, int regno) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + int i; + + for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) + { + if (regno == i || regno == -1) + supply_register (i, fpregs + FPREG_FPR_OFFSET (i - FP0_REGNUM)); + } + + if (regno == tdep->ppc_fpscr_regnum || regno == -1) + supply_register (tdep->ppc_fpscr_regnum, fpregs + FPREG_FPSCR_OFFSET); +} + +void +ppcnbsd_fill_fpreg (char *fpregs, int regno) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + int i; + + for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) + { + if (regno == i || regno == -1) + regcache_collect (i, fpregs + FPREG_FPR_OFFSET (i - FP0_REGNUM)); + } + + if (regno == tdep->ppc_fpscr_regnum || regno == -1) + regcache_collect (tdep->ppc_fpscr_regnum, fpregs + FPREG_FPSCR_OFFSET); +} + +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR ignore) +{ + char *regs, *fpregs; + + /* We get everything from one section. */ + if (which != 0) + return; + + regs = core_reg_sect; + fpregs = core_reg_sect + SIZEOF_STRUCT_REG; + + /* Integer registers. */ + ppcnbsd_supply_reg (regs, -1); + + /* Floating point registers. */ + ppcnbsd_supply_fpreg (fpregs, -1); +} + +static void +fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR ignore) +{ + switch (which) + { + case 0: /* Integer registers. */ + if (core_reg_size != SIZEOF_STRUCT_REG) + warning ("Wrong size register set in core file."); + else + ppcnbsd_supply_reg (core_reg_sect, -1); + break; + + case 2: /* Floating point registers. */ + if (core_reg_size != SIZEOF_STRUCT_FPREG) + warning ("Wrong size FP register set in core file."); + else + ppcnbsd_supply_fpreg (core_reg_sect, -1); + break; + + default: + /* Don't know what kind of register request this is; just ignore it. */ + break; + } +} + +static struct core_fns ppcnbsd_core_fns = +{ + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +static struct core_fns ppcnbsd_elfcore_fns = +{ + bfd_target_elf_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_elfcore_registers, /* core_read_registers */ + NULL /* next */ +}; + +static int +ppcnbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) +{ + /* FIXME: Need to add support for kernel-provided signal trampolines. */ + return (nbsd_pc_in_sigtramp (pc, func_name)); +} + +/* NetBSD is confused. It appears that 1.5 was using the correct SVr4 + convention but, 1.6 switched to the below broken convention. For + the moment use the broken convention. Ulgh!. */ + +static enum return_value_convention +ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *valtype, + struct regcache *regcache, void *readbuf, + const void *writebuf) +{ + if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT + || TYPE_CODE (valtype) == TYPE_CODE_UNION) + && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8) + && TYPE_VECTOR (valtype)) + && !(TYPE_LENGTH (valtype) == 1 + || TYPE_LENGTH (valtype) == 2 + || TYPE_LENGTH (valtype) == 4 + || TYPE_LENGTH (valtype) == 8)) + return RETURN_VALUE_STRUCT_CONVENTION; + else + return ppc_sysv_abi_broken_return_value (gdbarch, valtype, regcache, + readbuf, writebuf); +} + +static void +ppcnbsd_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + set_gdbarch_pc_in_sigtramp (gdbarch, ppcnbsd_pc_in_sigtramp); + /* For NetBSD, this is an on again, off again thing. Some systems + do use the broken struct convention, and some don't. */ + set_gdbarch_return_value (gdbarch, ppcnbsd_return_value); + set_solib_svr4_fetch_link_map_offsets (gdbarch, + nbsd_ilp32_solib_svr4_fetch_link_map_offsets); +} + +void +_initialize_ppcnbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF, + ppcnbsd_init_abi); + + add_core_fns (&ppcnbsd_core_fns); + add_core_fns (&ppcnbsd_elfcore_fns); +} diff --git a/contrib/gdb/gdb/ppcnbsd-tdep.h b/contrib/gdb/gdb/ppcnbsd-tdep.h new file mode 100644 index 00000000000..3eae72d819a --- /dev/null +++ b/contrib/gdb/gdb/ppcnbsd-tdep.h @@ -0,0 +1,30 @@ +/* Common target dependent code for GDB on PowerPC systems running NetBSD. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef PPCNBSD_TDEP_H +#define PPCNBSD_TDEP_H + +void ppcnbsd_supply_reg (char *, int); +void ppcnbsd_fill_reg (char *, int); + +void ppcnbsd_supply_fpreg (char *, int); +void ppcnbsd_fill_fpreg (char *, int); + +#endif /* PPCNBSD_TDEP_H */ diff --git a/contrib/gdb/gdb/printcmd.c b/contrib/gdb/gdb/printcmd.c index 0315227fc6a..9734ec12ed6 100644 --- a/contrib/gdb/gdb/printcmd.c +++ b/contrib/gdb/gdb/printcmd.c @@ -1,7 +1,7 @@ /* Print values for GNU debugger GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -40,6 +40,13 @@ #include "objfiles.h" /* ditto */ #include "completer.h" /* for completion functions */ #include "ui-out.h" +#include "gdb_assert.h" +#include "block.h" +#include "disasm.h" + +#ifdef TUI +#include "tui/tui.h" /* For tui_active et.al. */ +#endif extern int asm_demangle; /* Whether to demangle syms in asm printouts */ extern int addressprint; /* Whether to print hex addresses in HLL " */ @@ -135,13 +142,8 @@ static void enable_display (char *, int); static void disable_display_command (char *, int); -static void disassemble_command (char *, int); - static void printf_command (char *, int); -static void print_frame_nameless_args (struct frame_info *, long, - int, int, struct ui_file *); - static void display_info (char *, int); static void do_one_display (struct display *); @@ -175,8 +177,6 @@ static void print_formatted (struct value *, int, int, struct ui_file *); static struct format_data decode_format (char **, int, int); -static int print_insn (CORE_ADDR, struct ui_file *); - static void sym_info (char *, int); @@ -194,7 +194,7 @@ static struct format_data decode_format (char **string_ptr, int oformat, int osize) { struct format_data val; - register char *p = *string_ptr; + char *p = *string_ptr; val.format = '?'; val.size = '?'; @@ -279,7 +279,7 @@ decode_format (char **string_ptr, int oformat, int osize) This is used to pad hex numbers so they line up. */ static void -print_formatted (struct value *val, register int format, int size, +print_formatted (struct value *val, int format, int size, struct ui_file *stream) { struct type *type = check_typedef (VALUE_TYPE (val)); @@ -310,7 +310,7 @@ print_formatted (struct value *val, register int format, int size, /* We often wrap here if there are long symbolic names. */ wrap_here (" "); next_address = VALUE_ADDRESS (val) - + print_insn (VALUE_ADDRESS (val), stream); + + gdb_print_insn (VALUE_ADDRESS (val), stream); next_section = VALUE_BFD_SECTION (val); break; @@ -319,7 +319,8 @@ print_formatted (struct value *val, register int format, int size, || TYPE_CODE (type) == TYPE_CODE_ARRAY || TYPE_CODE (type) == TYPE_CODE_STRING || TYPE_CODE (type) == TYPE_CODE_STRUCT - || TYPE_CODE (type) == TYPE_CODE_UNION) + || TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_CODE (type) == TYPE_CODE_NAMESPACE) /* If format is 0, use the 'natural' format for * that type of value. If the type is non-scalar, * we have to use language rules to print it as @@ -343,57 +344,47 @@ print_formatted (struct value *val, register int format, int size, with a format. */ void -print_scalar_formatted (char *valaddr, struct type *type, int format, int size, +print_scalar_formatted (void *valaddr, struct type *type, int format, int size, struct ui_file *stream) { - LONGEST val_long; + LONGEST val_long = 0; unsigned int len = TYPE_LENGTH (type); - if (len > sizeof (LONGEST) - && (format == 't' - || format == 'c' - || format == 'o' - || format == 'u' - || format == 'd' - || format == 'x')) + if (len > sizeof(LONGEST) && + (TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_ENUM)) { - if (!TYPE_UNSIGNED (type) - || !extract_long_unsigned_integer (valaddr, len, &val_long)) + switch (format) { - /* We can't print it normally, but we can print it in hex. - Printing it in the wrong radix is more useful than saying - "use /x, you dummy". */ - /* FIXME: we could also do octal or binary if that was the - desired format. */ - /* FIXME: we should be using the size field to give us a - minimum field width to print. */ - - if (format == 'o') - print_octal_chars (stream, valaddr, len); - else if (format == 'd') - print_decimal_chars (stream, valaddr, len); - else if (format == 't') - print_binary_chars (stream, valaddr, len); - else - /* replace with call to print_hex_chars? Looks - like val_print_type_code_int is redoing - work. - edie */ - - val_print_type_code_int (type, valaddr, stream); - + case 'o': + print_octal_chars (stream, valaddr, len); return; - } - - /* If we get here, extract_long_unsigned_integer set val_long. */ + case 'u': + case 'd': + print_decimal_chars (stream, valaddr, len); + return; + case 't': + print_binary_chars (stream, valaddr, len); + return; + case 'x': + print_hex_chars (stream, valaddr, len); + return; + case 'c': + print_char_chars (stream, valaddr, len); + return; + default: + break; + }; } - else if (format != 'f') + + if (format != 'f') val_long = unpack_long (type, valaddr); /* If the value is a pointer, and pointers and addresses are not the - same, then at this point, the value's length is TARGET_ADDR_BIT, not - TYPE_LENGTH (type). */ + same, then at this point, the value's length (in target bytes) is + TARGET_ADDR_BIT/TARGET_CHAR_BIT, not TYPE_LENGTH (type). */ if (TYPE_CODE (type) == TYPE_CODE_PTR) - len = TARGET_ADDR_BIT; + len = TARGET_ADDR_BIT / TARGET_CHAR_BIT; /* If we are printing it as unsigned, truncate it in case it is actually a negative signed value (e.g. "print/u (short)-1" should print 65535 @@ -511,7 +502,7 @@ print_scalar_formatted (char *valaddr, struct type *type, int format, int size, strcpy (buf, local_binary_format_prefix ()); strcat (buf, cp); strcat (buf, local_binary_format_suffix ()); - fprintf_filtered (stream, buf); + fputs_filtered (buf, stream); } break; @@ -625,15 +616,6 @@ build_address_symbolic (CORE_ADDR addr, /* IN */ } } - /* On some targets, add in extra "flag" bits to PC for - disassembly. This should ensure that "rounding errors" in - symbol addresses that are masked for disassembly favour the - the correct symbol. */ - -#ifdef GDB_TARGET_UNMASK_DISAS_PC - addr = GDB_TARGET_UNMASK_DISAS_PC (addr); -#endif - /* First try to find the address in the symbol table, then in the minsyms. Take the closest one. */ @@ -649,10 +631,10 @@ build_address_symbolic (CORE_ADDR addr, /* IN */ if (symbol) { name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)); - if (do_demangle) - name_temp = SYMBOL_SOURCE_NAME (symbol); + if (do_demangle || asm_demangle) + name_temp = SYMBOL_PRINT_NAME (symbol); else - name_temp = SYMBOL_LINKAGE_NAME (symbol); + name_temp = DEPRECATED_SYMBOL_NAME (symbol); } if (msymbol != NULL) @@ -664,23 +646,15 @@ build_address_symbolic (CORE_ADDR addr, /* IN */ symbol = 0; symtab = 0; name_location = SYMBOL_VALUE_ADDRESS (msymbol); - if (do_demangle) - name_temp = SYMBOL_SOURCE_NAME (msymbol); + if (do_demangle || asm_demangle) + name_temp = SYMBOL_PRINT_NAME (msymbol); else - name_temp = SYMBOL_LINKAGE_NAME (msymbol); + name_temp = DEPRECATED_SYMBOL_NAME (msymbol); } } if (symbol == NULL && msymbol == NULL) return 1; - /* On some targets, mask out extra "flag" bits from PC for handsome - disassembly. */ - -#ifdef GDB_TARGET_MASK_DISAS_PC - name_location = GDB_TARGET_MASK_DISAS_PC (name_location); - addr = GDB_TARGET_MASK_DISAS_PC (addr); -#endif - /* If the nearest symbol is too far away, don't print anything symbolic. */ /* For when CORE_ADDR is larger than unsigned int, we do math in @@ -793,12 +767,12 @@ static struct type *examine_g_type; static void do_examine (struct format_data fmt, CORE_ADDR addr, asection *sect) { - register char format = 0; - register char size; - register int count = 1; + char format = 0; + char size; + int count = 1; struct type *val_type = NULL; - register int i; - register int maxelts; + int i; + int maxelts; format = fmt.format; size = fmt.size; @@ -893,8 +867,8 @@ static void print_command_1 (char *exp, int inspect, int voidprint) { struct expression *expr; - register struct cleanup *old_chain = 0; - register char format = 0; + struct cleanup *old_chain = 0; + char format = 0; struct value *val; struct format_data fmt; int cleanup = 0; @@ -923,25 +897,6 @@ print_command_1 (char *exp, int inspect, int voidprint) old_chain = make_cleanup (free_current_contents, &expr); cleanup = 1; val = evaluate_expression (expr); - - /* C++: figure out what type we actually want to print it as. */ - type = VALUE_TYPE (val); - - if (objectprint - && (TYPE_CODE (type) == TYPE_CODE_PTR - || TYPE_CODE (type) == TYPE_CODE_REF) - && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT - || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_UNION)) - { - struct value *v; - - v = value_from_vtable_info (val, TYPE_TARGET_TYPE (type)); - if (v != 0) - { - val = v; - type = VALUE_TYPE (val); - } - } } else val = access_value_history (0); @@ -981,7 +936,6 @@ print_command_1 (char *exp, int inspect, int voidprint) inspect_it = 0; /* Reset print routines to normal */ } -/* ARGSUSED */ static void print_command (char *exp, int from_tty) { @@ -989,7 +943,6 @@ print_command (char *exp, int from_tty) } /* Same as print, except in epoch, it gets its own window */ -/* ARGSUSED */ static void inspect_command (char *exp, int from_tty) { @@ -999,20 +952,18 @@ inspect_command (char *exp, int from_tty) } /* Same as print, except it doesn't print void results. */ -/* ARGSUSED */ static void call_command (char *exp, int from_tty) { print_command_1 (exp, 0, 0); } -/* ARGSUSED */ void output_command (char *exp, int from_tty) { struct expression *expr; - register struct cleanup *old_chain; - register char format = 0; + struct cleanup *old_chain; + char format = 0; struct value *val; struct format_data fmt; @@ -1041,18 +992,16 @@ output_command (char *exp, int from_tty) do_cleanups (old_chain); } -/* ARGSUSED */ static void set_command (char *exp, int from_tty) { struct expression *expr = parse_expression (exp); - register struct cleanup *old_chain = + struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); evaluate_expression (expr); do_cleanups (old_chain); } -/* ARGSUSED */ static void sym_info (char *arg, int from_tty) { @@ -1080,10 +1029,10 @@ sym_info (char *arg, int from_tty) offset = sect_addr - SYMBOL_VALUE_ADDRESS (msymbol); if (offset) printf_filtered ("%s + %u in ", - SYMBOL_SOURCE_NAME (msymbol), offset); + SYMBOL_PRINT_NAME (msymbol), offset); else printf_filtered ("%s in ", - SYMBOL_SOURCE_NAME (msymbol)); + SYMBOL_PRINT_NAME (msymbol)); if (pc_in_unmapped_range (addr, sect)) printf_filtered ("load address range of "); if (section_is_overlay (sect)) @@ -1097,14 +1046,13 @@ sym_info (char *arg, int from_tty) printf_filtered ("No symbol matches %s.\n", arg); } -/* ARGSUSED */ static void address_info (char *exp, int from_tty) { - register struct symbol *sym; - register struct minimal_symbol *msymbol; - register long val; - register long basereg; + struct symbol *sym; + struct minimal_symbol *msymbol; + long val; + long basereg; asection *section; CORE_ADDR load_addr; int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero @@ -1113,7 +1061,7 @@ address_info (char *exp, int from_tty) if (exp == 0) error ("Argument required."); - sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE, + sym = lookup_symbol (exp, get_selected_block (0), VAR_DOMAIN, &is_a_field_of_this, (struct symtab **) NULL); if (sym == NULL) { @@ -1122,7 +1070,11 @@ address_info (char *exp, int from_tty) printf_filtered ("Symbol \""); fprintf_symbol_filtered (gdb_stdout, exp, current_language->la_language, DMGL_ANSI); - printf_filtered ("\" is a field of the local class variable `this'\n"); + printf_filtered ("\" is a field of the local class variable "); + if (current_language->la_language == language_objc) + printf_filtered ("`self'\n"); /* ObjC equivalent of "this" */ + else + printf_filtered ("`this'\n"); return; } @@ -1154,7 +1106,7 @@ address_info (char *exp, int from_tty) } printf_filtered ("Symbol \""); - fprintf_symbol_filtered (gdb_stdout, SYMBOL_NAME (sym), + fprintf_symbol_filtered (gdb_stdout, DEPRECATED_SYMBOL_NAME (sym), current_language->la_language, DMGL_ANSI); printf_filtered ("\" is "); val = SYMBOL_VALUE (sym); @@ -1181,6 +1133,16 @@ address_info (char *exp, int from_tty) } break; + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + /* FIXME: cagney/2004-01-26: It should be possible to + unconditionally call the SYMBOL_OPS method when available. + Unfortunately DWARF 2 stores the frame-base (instead of the + function) location in a function's symbol. Oops! For the + moment enable this when/where applicable. */ + SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout); + break; + case LOC_REGISTER: printf_filtered ("a variable in register %s", REGISTER_NAME (val)); break; @@ -1252,14 +1214,8 @@ address_info (char *exp, int from_tty) case LOC_BLOCK: printf_filtered ("a function at address "); -#ifdef GDB_TARGET_MASK_DISAS_PC - print_address_numeric - (load_addr = GDB_TARGET_MASK_DISAS_PC (BLOCK_START (SYMBOL_BLOCK_VALUE (sym))), - 1, gdb_stdout); -#else print_address_numeric (load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1, gdb_stdout); -#endif if (section_is_overlay (section)) { load_addr = overlay_unmapped_address (load_addr, section); @@ -1273,7 +1229,7 @@ address_info (char *exp, int from_tty) { struct minimal_symbol *msym; - msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL); + msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, NULL); if (msym == NULL) printf_filtered ("unresolved"); else @@ -1293,7 +1249,7 @@ address_info (char *exp, int from_tty) } break; - case LOC_THREAD_LOCAL_STATIC: + case LOC_HP_THREAD_LOCAL_STATIC: printf_filtered ( "a thread-local variable at offset %ld from the thread base register %s", val, REGISTER_NAME (basereg)); @@ -1391,13 +1347,15 @@ static void display_command (char *exp, int from_tty) { struct format_data fmt; - register struct expression *expr; - register struct display *new; + struct expression *expr; + struct display *new; int display_it = 1; #if defined(TUI) - if (tui_version && *exp == '$') - display_it = (tui_set_layout (exp) == TUI_FAILURE); + /* NOTE: cagney/2003-02-13 The `tui_active' was previously + `tui_version'. */ + if (tui_active && exp != NULL && *exp == '$') + display_it = (tui_set_layout_for_display_command (exp) == TUI_FAILURE); #endif if (display_it) @@ -1458,7 +1416,7 @@ free_display (struct display *d) void clear_displays (void) { - register struct display *d; + struct display *d; while ((d = display_chain) != NULL) { @@ -1473,7 +1431,7 @@ clear_displays (void) static void delete_display (int num) { - register struct display *d1, *d; + struct display *d1, *d; if (!display_chain) error ("No display number %d.", num); @@ -1505,9 +1463,9 @@ delete_display (int num) static void undisplay_command (char *args, int from_tty) { - register char *p = args; - register char *p1; - register int num; + char *p = args; + char *p1; + int num; if (args == 0) { @@ -1549,7 +1507,7 @@ do_one_display (struct display *d) return; if (d->block) - within_current_scope = contained_in (get_selected_block (), d->block); + within_current_scope = contained_in (get_selected_block (0), d->block); else within_current_scope = 1; if (!within_current_scope) @@ -1628,7 +1586,7 @@ do_one_display (struct display *d) void do_displays (void) { - register struct display *d; + struct display *d; for (d = display_chain; d; d = d->next) do_one_display (d); @@ -1640,7 +1598,7 @@ do_displays (void) void disable_display (int num) { - register struct display *d; + struct display *d; for (d = display_chain; d; d = d->next) if (d->number == num) @@ -1666,7 +1624,7 @@ disable_current_display (void) static void display_info (char *ignore, int from_tty) { - register struct display *d; + struct display *d; if (!display_chain) printf_unfiltered ("There are no auto-display expressions now.\n"); @@ -1683,7 +1641,7 @@ Num Enb Expression\n"); else if (d->format.format) printf_filtered ("/%c ", d->format.format); print_expression (d->exp, gdb_stdout); - if (d->block && !contained_in (get_selected_block (), d->block)) + if (d->block && !contained_in (get_selected_block (0), d->block)) printf_filtered (" (cannot be evaluated in the current context)"); printf_filtered ("\n"); gdb_flush (gdb_stdout); @@ -1693,10 +1651,10 @@ Num Enb Expression\n"); static void enable_display (char *args, int from_tty) { - register char *p = args; - register char *p1; - register int num; - register struct display *d; + char *p = args; + char *p1; + int num; + struct display *d; if (p == 0) { @@ -1728,13 +1686,12 @@ enable_display (char *args, int from_tty) } } -/* ARGSUSED */ static void disable_display_command (char *args, int from_tty) { - register char *p = args; - register char *p1; - register struct display *d; + char *p = args; + char *p1; + struct display *d; if (p == 0) { @@ -1771,244 +1728,11 @@ print_variable_value (struct symbol *var, struct frame_info *frame, value_print (val, stream, 0, Val_pretty_default); } -/* Print the arguments of a stack frame, given the function FUNC - running in that frame (as a symbol), the info on the frame, - and the number of args according to the stack frame (or -1 if unknown). */ - -/* References here and elsewhere to "number of args according to the - stack frame" appear in all cases to refer to "number of ints of args - according to the stack frame". At least for VAX, i386, isi. */ - -void -print_frame_args (struct symbol *func, struct frame_info *fi, int num, - struct ui_file *stream) -{ - struct block *b = NULL; - int first = 1; - register int i; - register struct symbol *sym; - struct value *val; - /* Offset of next stack argument beyond the one we have seen that is - at the highest offset. - -1 if we haven't come to a stack argument yet. */ - long highest_offset = -1; - int arg_size; - /* Number of ints of arguments that we have printed so far. */ - int args_printed = 0; - struct cleanup *old_chain, *list_chain; - struct ui_stream *stb; - - stb = ui_out_stream_new (uiout); - old_chain = make_cleanup_ui_out_stream_delete (stb); - - if (func) - { - b = SYMBOL_BLOCK_VALUE (func); - ALL_BLOCK_SYMBOLS (b, i, sym) - { - QUIT; - - /* Keep track of the highest stack argument offset seen, and - skip over any kinds of symbols we don't care about. */ - - switch (SYMBOL_CLASS (sym)) - { - case LOC_ARG: - case LOC_REF_ARG: - { - long current_offset = SYMBOL_VALUE (sym); - arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym)); - - /* Compute address of next argument by adding the size of - this argument and rounding to an int boundary. */ - current_offset = - ((current_offset + arg_size + sizeof (int) - 1) - & ~(sizeof (int) - 1)); - - /* If this is the highest offset seen yet, set highest_offset. */ - if (highest_offset == -1 - || (current_offset > highest_offset)) - highest_offset = current_offset; - - /* Add the number of ints we're about to print to args_printed. */ - args_printed += (arg_size + sizeof (int) - 1) / sizeof (int); - } - - /* We care about types of symbols, but don't need to keep track of - stack offsets in them. */ - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_LOCAL_ARG: - case LOC_BASEREG_ARG: - break; - - /* Other types of symbols we just skip over. */ - default: - continue; - } - - /* We have to look up the symbol because arguments can have - two entries (one a parameter, one a local) and the one we - want is the local, which lookup_symbol will find for us. - This includes gcc1 (not gcc2) on the sparc when passing a - small structure and gcc2 when the argument type is float - and it is passed as a double and converted to float by - the prologue (in the latter case the type of the LOC_ARG - symbol is double and the type of the LOC_LOCAL symbol is - float). */ - /* But if the parameter name is null, don't try it. - Null parameter names occur on the RS/6000, for traceback tables. - FIXME, should we even print them? */ - - if (*SYMBOL_NAME (sym)) - { - struct symbol *nsym; - nsym = lookup_symbol - (SYMBOL_NAME (sym), - b, VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL); - if (SYMBOL_CLASS (nsym) == LOC_REGISTER) - { - /* There is a LOC_ARG/LOC_REGISTER pair. This means that - it was passed on the stack and loaded into a register, - or passed in a register and stored in a stack slot. - GDB 3.x used the LOC_ARG; GDB 4.0-4.11 used the LOC_REGISTER. - - Reasons for using the LOC_ARG: - (1) because find_saved_registers may be slow for remote - debugging, - (2) because registers are often re-used and stack slots - rarely (never?) are. Therefore using the stack slot is - much less likely to print garbage. - - Reasons why we might want to use the LOC_REGISTER: - (1) So that the backtrace prints the same value as - "print foo". I see no compelling reason why this needs - to be the case; having the backtrace print the value which - was passed in, and "print foo" print the value as modified - within the called function, makes perfect sense to me. - - Additional note: It might be nice if "info args" displayed - both values. - One more note: There is a case with sparc structure passing - where we need to use the LOC_REGISTER, but this is dealt with - by creating a single LOC_REGPARM in symbol reading. */ - - /* Leave sym (the LOC_ARG) alone. */ - ; - } - else - sym = nsym; - } - - /* Print the current arg. */ - if (!first) - ui_out_text (uiout, ", "); - ui_out_wrap_hint (uiout, " "); - - annotate_arg_begin (); - - list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); - fprintf_symbol_filtered (stb->stream, SYMBOL_SOURCE_NAME (sym), - SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI); - ui_out_field_stream (uiout, "name", stb); - annotate_arg_name_end (); - ui_out_text (uiout, "="); - - /* Avoid value_print because it will deref ref parameters. We just - want to print their addresses. Print ??? for args whose address - we do not know. We pass 2 as "recurse" to val_print because our - standard indentation here is 4 spaces, and val_print indents - 2 for each recurse. */ - val = read_var_value (sym, fi); - - annotate_arg_value (val == NULL ? NULL : VALUE_TYPE (val)); - - if (val) - { - val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0, - VALUE_ADDRESS (val), - stb->stream, 0, 0, 2, Val_no_prettyprint); - ui_out_field_stream (uiout, "value", stb); - } - else - ui_out_text (uiout, "???"); - - /* Invoke ui_out_tuple_end. */ - do_cleanups (list_chain); - - annotate_arg_end (); - - first = 0; - } - } - - /* Don't print nameless args in situations where we don't know - enough about the stack to find them. */ - if (num != -1) - { - long start; - - if (highest_offset == -1) - start = FRAME_ARGS_SKIP; - else - start = highest_offset; - - print_frame_nameless_args (fi, start, num - args_printed, - first, stream); - } - do_cleanups (old_chain); -} - -/* Print nameless args on STREAM. - FI is the frameinfo for this frame, START is the offset - of the first nameless arg, and NUM is the number of nameless args to - print. FIRST is nonzero if this is the first argument (not just - the first nameless arg). */ - -static void -print_frame_nameless_args (struct frame_info *fi, long start, int num, - int first, struct ui_file *stream) -{ - int i; - CORE_ADDR argsaddr; - long arg_value; - - for (i = 0; i < num; i++) - { - QUIT; -#ifdef NAMELESS_ARG_VALUE - NAMELESS_ARG_VALUE (fi, start, &arg_value); -#else - argsaddr = FRAME_ARGS_ADDRESS (fi); - if (!argsaddr) - return; - - arg_value = read_memory_integer (argsaddr + start, sizeof (int)); -#endif - - if (!first) - fprintf_filtered (stream, ", "); - -#ifdef PRINT_NAMELESS_INTEGER - PRINT_NAMELESS_INTEGER (stream, arg_value); -#else -#ifdef PRINT_TYPELESS_INTEGER - PRINT_TYPELESS_INTEGER (stream, builtin_type_int, (LONGEST) arg_value); -#else - fprintf_filtered (stream, "%ld", arg_value); -#endif /* PRINT_TYPELESS_INTEGER */ -#endif /* PRINT_NAMELESS_INTEGER */ - first = 0; - start += sizeof (int); - } -} - -/* ARGSUSED */ static void printf_command (char *arg, int from_tty) { - register char *f = NULL; - register char *s = arg; + char *f = NULL; + char *s = arg; char *string = NULL; struct value **val_args; char *substrings; @@ -2270,139 +1994,10 @@ printf_command (char *arg, int from_tty) current_substring += strlen (current_substring) + 1; } /* Print the portion of the format string after the last argument. */ - printf_filtered (last_arg); + puts_filtered (last_arg); } do_cleanups (old_cleanups); } - -/* Dump a specified section of assembly code. With no command line - arguments, this command will dump the assembly code for the - function surrounding the pc value in the selected frame. With one - argument, it will dump the assembly code surrounding that pc value. - Two arguments are interpeted as bounds within which to dump - assembly. */ - -/* ARGSUSED */ -static void -disassemble_command (char *arg, int from_tty) -{ - CORE_ADDR low, high; - char *name; - CORE_ADDR pc, pc_masked; - char *space_index; -#if 0 - asection *section; -#endif - - name = NULL; - if (!arg) - { - if (!selected_frame) - error ("No frame selected.\n"); - - pc = get_frame_pc (selected_frame); - if (find_pc_partial_function (pc, &name, &low, &high) == 0) - error ("No function contains program counter for selected frame.\n"); -#if defined(TUI) - else if (tui_version) - low = tuiGetLowDisassemblyAddress (low, pc); -#endif - low += FUNCTION_START_OFFSET; - } - else if (!(space_index = (char *) strchr (arg, ' '))) - { - /* One argument. */ - pc = parse_and_eval_address (arg); - if (find_pc_partial_function (pc, &name, &low, &high) == 0) - error ("No function contains specified address.\n"); -#if defined(TUI) - else if (tui_version) - low = tuiGetLowDisassemblyAddress (low, pc); -#endif - low += FUNCTION_START_OFFSET; - } - else - { - /* Two arguments. */ - *space_index = '\0'; - low = parse_and_eval_address (arg); - high = parse_and_eval_address (space_index + 1); - } - -#if defined(TUI) - if (!tui_is_window_visible (DISASSEM_WIN)) -#endif - { - printf_filtered ("Dump of assembler code "); - if (name != NULL) - { - printf_filtered ("for function %s:\n", name); - } - else - { - printf_filtered ("from "); - print_address_numeric (low, 1, gdb_stdout); - printf_filtered (" to "); - print_address_numeric (high, 1, gdb_stdout); - printf_filtered (":\n"); - } - - /* Dump the specified range. */ - pc = low; - -#ifdef GDB_TARGET_MASK_DISAS_PC - pc_masked = GDB_TARGET_MASK_DISAS_PC (pc); -#else - pc_masked = pc; -#endif - - while (pc_masked < high) - { - QUIT; - print_address (pc_masked, gdb_stdout); - printf_filtered (":\t"); - /* We often wrap here if there are long symbolic names. */ - wrap_here (" "); - pc += print_insn (pc, gdb_stdout); - printf_filtered ("\n"); - -#ifdef GDB_TARGET_MASK_DISAS_PC - pc_masked = GDB_TARGET_MASK_DISAS_PC (pc); -#else - pc_masked = pc; -#endif - } - printf_filtered ("End of assembler dump.\n"); - gdb_flush (gdb_stdout); - } -#if defined(TUI) - else - { - tui_show_assembly (low); - } -#endif -} - -/* Print the instruction at address MEMADDR in debugged memory, - on STREAM. Returns length of the instruction, in bytes. */ - -static int -print_insn (CORE_ADDR memaddr, struct ui_file *stream) -{ - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - TARGET_PRINT_INSN_INFO->endian = BFD_ENDIAN_BIG; - else - TARGET_PRINT_INSN_INFO->endian = BFD_ENDIAN_LITTLE; - - if (TARGET_ARCHITECTURE != NULL) - TARGET_PRINT_INSN_INFO->mach = TARGET_ARCHITECTURE->mach; - /* else: should set .mach=0 but some disassemblers don't grok this */ - - TARGET_PRINT_INSN_INFO->stream = stream; - - return TARGET_PRINT_INSN (memaddr, TARGET_PRINT_INSN_INFO); -} - void _initialize_printcmd (void) @@ -2431,15 +2026,6 @@ Defaults for format and size letters are those previously used.\n\ Default count is 1. Default address is following last thing printed\n\ with this command or \"print\".", NULL)); - c = add_com ("disassemble", class_vars, disassemble_command, - "Disassemble a specified section of memory.\n\ -Default is the function surrounding the pc of the selected frame.\n\ -With a single argument, the function surrounding that address is dumped.\n\ -Two arguments are taken as a range of memory to dump."); - c->completer = location_completer; - if (xdb_commands) - add_com_alias ("va", "disassemble", class_xdb, 0); - #if 0 add_com ("whereis", class_vars, whereis_command, "Print line number and file of definition of variable."); @@ -2519,7 +2105,7 @@ You can see these environment settings with the \"show\" command.", NULL)); The argument is the function name and arguments, in the notation of the\n\ current working language. The result is printed and saved in the value\n\ history, if it is not void."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); add_cmd ("variable", class_vars, set_command, "Evaluate expression EXP and assign result to variable VAR, using assignment\n\ @@ -2552,13 +2138,13 @@ resides in memory.\n", "\n\ EXP may be preceded with /FMT, where FMT is a format letter\n\ but no count or size letter (see \"x\" command).", NULL)); - c->completer = location_completer; + set_cmd_completer (c, location_completer); add_com_alias ("p", "print", class_vars, 1); c = add_com ("inspect", class_vars, inspect_command, "Same as \"print\" command, except that if you are running in the epoch\n\ environment, the value is printed in its own window."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); add_show_from_set ( add_set_cmd ("max-symbolic-offset", no_class, var_uinteger, diff --git a/contrib/gdb/gdb/proc-api.c b/contrib/gdb/gdb/proc-api.c index 986691dc83d..e6d30ea01fe 100755 --- a/contrib/gdb/gdb/proc-api.c +++ b/contrib/gdb/gdb/proc-api.c @@ -1,5 +1,7 @@ /* Machine independent support for SVR4 /proc (process file system) for GDB. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + Written by Michael Snyder at Cygnus Solutions. Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others. @@ -36,12 +38,14 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include +#ifdef HAVE_SYS_PROC_H #include /* for struct proc */ +#endif #ifdef HAVE_SYS_USER_H #include /* for struct user */ #endif #include /* for O_RDWR etc. */ -#include +#include "gdb_wait.h" #include "proc-utils.h" @@ -395,9 +399,13 @@ static struct trans rw_table[] = { #ifdef PCCSIG /* solaris */ { PCCSIG, "PCCSIG", "clear current signal" }, #endif +#ifdef PCDSTOP /* solaris */ { PCDSTOP, "PCDSTOP", "post stop request" }, +#endif { PCKILL, "PCKILL", "post a signal" }, +#ifdef PCNICE /* solaris */ { PCNICE, "PCNICE", "set nice priority" }, +#endif #ifdef PCREAD /* solaris */ { PCREAD, "PCREAD", "read from the address space" }, { PCWRITE, "PCWRITE", "write to the address space" }, @@ -417,7 +425,9 @@ static struct trans rw_table[] = { { PCSEXIT, "PCSEXIT", "set traced syscall exit set" }, { PCSFAULT, "PCSFAULT", "set traced fault set" }, { PCSFPREG, "PCSFPREG", "set floating point registers" }, +#ifdef PCSHOLD /* solaris */ { PCSHOLD, "PCSHOLD", "set signal mask" }, +#endif { PCSREG, "PCSREG", "set general registers" }, { PCSSIG, "PCSSIG", "set current signal" }, { PCSTOP, "PCSTOP", "post stop request and wait" }, @@ -431,7 +441,9 @@ static struct trans rw_table[] = { #ifdef PCTWSTOP /* solaris */ { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" }, #endif +#ifdef PCUNKILL /* solaris */ { PCUNKILL, "PCUNKILL", "delete a pending signal" }, +#endif #ifdef PCUNSET /* solaris */ { PCUNSET, "PCUNSET", "unset modes" }, #endif @@ -447,7 +459,7 @@ static off_t lseek_offset; int write_with_trace (int fd, void *varg, size_t len, char *file, int line) { - int i; + int i = ARRAY_SIZE (rw_table) - 1; int ret; procfs_ctl_t *arg = (procfs_ctl_t *) varg; @@ -516,12 +528,14 @@ write_with_trace (int fd, void *varg, size_t len, char *file, int line) proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout, (sysset_t *) &arg[1], 0); break; +#ifdef PCSHOLD case PCSHOLD: fprintf (procfs_file ? procfs_file : stdout, "write (PCSHOLD) "); proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout, (sigset_t *) &arg[1], 0); break; +#endif case PCSSIG: fprintf (procfs_file ? procfs_file : stdout, "write (PCSSIG) "); @@ -540,10 +554,14 @@ write_with_trace (int fd, void *varg, size_t len, char *file, int line) fprintf (procfs_file ? procfs_file : stdout, "clearFlt "); if (arg[1] & PRSTEP) fprintf (procfs_file ? procfs_file : stdout, "step "); +#ifdef PRSABORT if (arg[1] & PRSABORT) fprintf (procfs_file ? procfs_file : stdout, "syscallAbort "); +#endif +#ifdef PRSTOP if (arg[1] & PRSTOP) fprintf (procfs_file ? procfs_file : stdout, "stopReq "); +#endif fprintf (procfs_file ? procfs_file : stdout, "\n"); break; @@ -556,16 +574,6 @@ write_with_trace (int fd, void *varg, size_t len, char *file, int line) break; default: { -#ifdef BREAKPOINT - static unsigned char break_insn[] = BREAKPOINT; - - if (len == sizeof (break_insn) && - memcmp (arg, &break_insn, len) == 0) - fprintf (procfs_file ? procfs_file : stdout, - "write () \n", - (unsigned long) lseek_offset); - else -#endif if (rw_table[i].name) fprintf (procfs_file ? procfs_file : stdout, "write (%s) %s\n", @@ -739,7 +747,7 @@ procfs_note (char *msg, char *file, int line) if (info_verbose) fprintf (procfs_file ? procfs_file : stdout, "%s:%d -- ", file, line); - fprintf (procfs_file ? procfs_file : stdout, msg); + fprintf (procfs_file ? procfs_file : stdout, "%s", msg); if (procfs_file) fflush (procfs_file); } @@ -778,7 +786,7 @@ _initialize_proc_api (void) add_show_from_set (c, &showlist); set_cmd_sfunc (c, set_procfs_trace_cmd); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); c = add_set_cmd ("procfs-file", no_class, var_filename, (char *) &procfs_filename, diff --git a/contrib/gdb/gdb/proc-utils.h b/contrib/gdb/gdb/proc-utils.h index 1c419649184..d9f38a89fef 100644 --- a/contrib/gdb/gdb/proc-utils.h +++ b/contrib/gdb/gdb/proc-utils.h @@ -22,44 +22,37 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ * Pretty-print functions for /proc data */ -extern void -proc_prettyprint_why (unsigned long why, unsigned long what, int verbose); +extern void proc_prettyprint_why (unsigned long why, unsigned long what, + int verbose); -extern void -proc_prettyprint_syscalls (sysset_t *sysset, int verbose); +extern void proc_prettyprint_syscalls (sysset_t *sysset, int verbose); -extern void -proc_prettyprint_syscall (int num, int verbose); +extern void proc_prettyprint_syscall (int num, int verbose); extern void proc_prettyprint_flags (unsigned long flags, int verbose); -extern void -proc_prettyfprint_signalset (FILE *file, sigset_t *sigset, int verbose); +extern void proc_prettyfprint_signalset (FILE *file, sigset_t *sigset, + int verbose); -extern void -proc_prettyfprint_faultset (FILE *file, fltset_t *fltset, int verbose); +extern void proc_prettyfprint_faultset (FILE *file, fltset_t *fltset, + int verbose); -extern void -proc_prettyfprint_syscall (FILE *file, int num, int verbose); +extern void proc_prettyfprint_syscall (FILE *file, int num, int verbose); -extern void -proc_prettyfprint_signal (FILE *file, int signo, int verbose); +extern void proc_prettyfprint_signal (FILE *file, int signo, int verbose); -extern void -proc_prettyfprint_flags (FILE *file, unsigned long flags, int verbose); +extern void proc_prettyfprint_flags (FILE *file, unsigned long flags, + int verbose); -extern void -proc_prettyfprint_why (FILE *file, unsigned long why, - unsigned long what, int verbose); +extern void proc_prettyfprint_why (FILE *file, unsigned long why, + unsigned long what, int verbose); -extern void -proc_prettyfprint_fault (FILE *file, int faultno, int verbose); +extern void proc_prettyfprint_fault (FILE *file, int faultno, int verbose); -extern void -proc_prettyfprint_syscalls (FILE *file, sysset_t *sysset, int verbose); +extern void proc_prettyfprint_syscalls (FILE *file, sysset_t *sysset, + int verbose); -extern void -proc_prettyfprint_status (long, int, int, int); +extern void proc_prettyfprint_status (long, int, int, int); /* * Trace functions for /proc api. diff --git a/contrib/gdb/gdb/procfs.c b/contrib/gdb/gdb/procfs.c new file mode 100644 index 00000000000..352b735c868 --- /dev/null +++ b/contrib/gdb/gdb/procfs.c @@ -0,0 +1,5960 @@ +/* Machine independent support for SVR4 /proc (process file system) for GDB. + + Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + Written by Michael Snyder at Cygnus Solutions. + Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "target.h" +#include "gdbcore.h" +#include "elf-bfd.h" /* for elfcore_write_* */ +#include "gdbcmd.h" +#include "gdbthread.h" + +#if defined (NEW_PROC_API) +#define _STRUCTURED_PROC 1 /* Should be done by configure script. */ +#endif + +#include +#ifdef HAVE_SYS_FAULT_H +#include +#endif +#ifdef HAVE_SYS_SYSCALL_H +#include +#endif +#include +#include "gdb_wait.h" +#include +#include +#include "gdb_string.h" +#include "gdb_assert.h" +#include "inflow.h" +#include "auxv.h" + +/* + * PROCFS.C + * + * This module provides the interface between GDB and the + * /proc file system, which is used on many versions of Unix + * as a means for debuggers to control other processes. + * Examples of the systems that use this interface are: + * Irix + * Solaris + * OSF + * Unixware + * AIX5 + * + * /proc works by imitating a file system: you open a simulated file + * that represents the process you wish to interact with, and + * perform operations on that "file" in order to examine or change + * the state of the other process. + * + * The most important thing to know about /proc and this module + * is that there are two very different interfaces to /proc: + * One that uses the ioctl system call, and + * another that uses read and write system calls. + * This module has to support both /proc interfaces. This means + * that there are two different ways of doing every basic operation. + * + * In order to keep most of the code simple and clean, I have + * defined an interface "layer" which hides all these system calls. + * An ifdef (NEW_PROC_API) determines which interface we are using, + * and most or all occurrances of this ifdef should be confined to + * this interface layer. + */ + + +/* Determine which /proc API we are using: + The ioctl API defines PIOCSTATUS, while + the read/write (multiple fd) API never does. */ + +#ifdef NEW_PROC_API +#include +#include "gdb_dirent.h" /* opendir/readdir, for listing the LWP's */ +#endif + +#include /* for O_RDONLY */ +#include /* for "X_OK" */ +#include "gdb_stat.h" /* for struct stat */ + +/* Note: procfs-utils.h must be included after the above system header + files, because it redefines various system calls using macros. + This may be incompatible with the prototype declarations. */ + +#include "proc-utils.h" + +/* Prototypes for supply_gregset etc. */ +#include "gregset.h" + +/* =================== TARGET_OPS "MODULE" =================== */ + +/* + * This module defines the GDB target vector and its methods. + */ + +static void procfs_open (char *, int); +static void procfs_attach (char *, int); +static void procfs_detach (char *, int); +static void procfs_resume (ptid_t, int, enum target_signal); +static int procfs_can_run (void); +static void procfs_stop (void); +static void procfs_files_info (struct target_ops *); +static void procfs_fetch_registers (int); +static void procfs_store_registers (int); +static void procfs_notice_signals (ptid_t); +static void procfs_prepare_to_store (void); +static void procfs_kill_inferior (void); +static void procfs_mourn_inferior (void); +static void procfs_create_inferior (char *, char *, char **); +static ptid_t procfs_wait (ptid_t, struct target_waitstatus *); +static int procfs_xfer_memory (CORE_ADDR, char *, int, int, + struct mem_attrib *attrib, + struct target_ops *); +static LONGEST procfs_xfer_partial (struct target_ops *ops, + enum target_object object, + const char *annex, + void *readbuf, const void *writebuf, + ULONGEST offset, LONGEST len); + +static int procfs_thread_alive (ptid_t); + +void procfs_find_new_threads (void); +char *procfs_pid_to_str (ptid_t); + +static int proc_find_memory_regions (int (*) (CORE_ADDR, + unsigned long, + int, int, int, + void *), + void *); + +static char * procfs_make_note_section (bfd *, int *); + +static int procfs_can_use_hw_breakpoint (int, int, int); + +struct target_ops procfs_ops; /* the target vector */ + +static void +init_procfs_ops (void) +{ + procfs_ops.to_shortname = "procfs"; + procfs_ops.to_longname = "Unix /proc child process"; + procfs_ops.to_doc = + "Unix /proc child process (started by the \"run\" command)."; + procfs_ops.to_open = procfs_open; + procfs_ops.to_can_run = procfs_can_run; + procfs_ops.to_create_inferior = procfs_create_inferior; + procfs_ops.to_kill = procfs_kill_inferior; + procfs_ops.to_mourn_inferior = procfs_mourn_inferior; + procfs_ops.to_attach = procfs_attach; + procfs_ops.to_detach = procfs_detach; + procfs_ops.to_wait = procfs_wait; + procfs_ops.to_resume = procfs_resume; + procfs_ops.to_prepare_to_store = procfs_prepare_to_store; + procfs_ops.to_fetch_registers = procfs_fetch_registers; + procfs_ops.to_store_registers = procfs_store_registers; + procfs_ops.to_xfer_partial = procfs_xfer_partial; + procfs_ops.to_xfer_memory = procfs_xfer_memory; + procfs_ops.to_insert_breakpoint = memory_insert_breakpoint; + procfs_ops.to_remove_breakpoint = memory_remove_breakpoint; + procfs_ops.to_notice_signals = procfs_notice_signals; + procfs_ops.to_files_info = procfs_files_info; + procfs_ops.to_stop = procfs_stop; + + procfs_ops.to_terminal_init = terminal_init_inferior; + procfs_ops.to_terminal_inferior = terminal_inferior; + procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output; + procfs_ops.to_terminal_ours = terminal_ours; + procfs_ops.to_terminal_save_ours = terminal_save_ours; + procfs_ops.to_terminal_info = child_terminal_info; + + procfs_ops.to_find_new_threads = procfs_find_new_threads; + procfs_ops.to_thread_alive = procfs_thread_alive; + procfs_ops.to_pid_to_str = procfs_pid_to_str; + + procfs_ops.to_has_all_memory = 1; + procfs_ops.to_has_memory = 1; + procfs_ops.to_has_execution = 1; + procfs_ops.to_has_stack = 1; + procfs_ops.to_has_registers = 1; + procfs_ops.to_stratum = process_stratum; + procfs_ops.to_has_thread_control = tc_schedlock; + procfs_ops.to_find_memory_regions = proc_find_memory_regions; + procfs_ops.to_make_corefile_notes = procfs_make_note_section; + procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint; + procfs_ops.to_magic = OPS_MAGIC; +} + +/* =================== END, TARGET_OPS "MODULE" =================== */ + +/* + * World Unification: + * + * Put any typedefs, defines etc. here that are required for + * the unification of code that handles different versions of /proc. + */ + +#ifdef NEW_PROC_API /* Solaris 7 && 8 method for watchpoints */ +#ifdef WA_READ + enum { READ_WATCHFLAG = WA_READ, + WRITE_WATCHFLAG = WA_WRITE, + EXEC_WATCHFLAG = WA_EXEC, + AFTER_WATCHFLAG = WA_TRAPAFTER + }; +#endif +#else /* Irix method for watchpoints */ + enum { READ_WATCHFLAG = MA_READ, + WRITE_WATCHFLAG = MA_WRITE, + EXEC_WATCHFLAG = MA_EXEC, + AFTER_WATCHFLAG = 0 /* trapafter not implemented */ + }; +#endif + +/* gdb_sigset_t */ +#ifdef HAVE_PR_SIGSET_T +typedef pr_sigset_t gdb_sigset_t; +#else +typedef sigset_t gdb_sigset_t; +#endif + +/* sigaction */ +#ifdef HAVE_PR_SIGACTION64_T +typedef pr_sigaction64_t gdb_sigaction_t; +#else +typedef struct sigaction gdb_sigaction_t; +#endif + +/* siginfo */ +#ifdef HAVE_PR_SIGINFO64_T +typedef pr_siginfo64_t gdb_siginfo_t; +#else +typedef struct siginfo gdb_siginfo_t; +#endif + +/* gdb_premptysysset */ +#ifdef premptysysset +#define gdb_premptysysset premptysysset +#else +#define gdb_premptysysset premptyset +#endif + +/* praddsysset */ +#ifdef praddsysset +#define gdb_praddsysset praddsysset +#else +#define gdb_praddsysset praddset +#endif + +/* prdelsysset */ +#ifdef prdelsysset +#define gdb_prdelsysset prdelsysset +#else +#define gdb_prdelsysset prdelset +#endif + +/* prissyssetmember */ +#ifdef prissyssetmember +#define gdb_pr_issyssetmember prissyssetmember +#else +#define gdb_pr_issyssetmember prismember +#endif + +/* As a feature test, saying ``#if HAVE_PRSYSENT_T'' everywhere isn't + as intuitively descriptive as it could be, so we'll define + DYNAMIC_SYSCALLS to mean the same thing. Anyway, at the time of + this writing, this feature is only found on AIX5 systems and + basically means that the set of syscalls is not fixed. I.e, + there's no nice table that one can #include to get all of the + syscall numbers. Instead, they're stored in /proc/PID/sysent + for each process. We are at least guaranteed that they won't + change over the lifetime of the process. But each process could + (in theory) have different syscall numbers. +*/ +#ifdef HAVE_PRSYSENT_T +#define DYNAMIC_SYSCALLS +#endif + + + +/* =================== STRUCT PROCINFO "MODULE" =================== */ + + /* FIXME: this comment will soon be out of date W.R.T. threads. */ + +/* The procinfo struct is a wrapper to hold all the state information + concerning a /proc process. There should be exactly one procinfo + for each process, and since GDB currently can debug only one + process at a time, that means there should be only one procinfo. + All of the LWP's of a process can be accessed indirectly thru the + single process procinfo. + + However, against the day when GDB may debug more than one process, + this data structure is kept in a list (which for now will hold no + more than one member), and many functions will have a pointer to a + procinfo as an argument. + + There will be a separate procinfo structure for use by the (not yet + implemented) "info proc" command, so that we can print useful + information about any random process without interfering with the + inferior's procinfo information. */ + +#ifdef NEW_PROC_API +/* format strings for /proc paths */ +# ifndef CTL_PROC_NAME_FMT +# define MAIN_PROC_NAME_FMT "/proc/%d" +# define CTL_PROC_NAME_FMT "/proc/%d/ctl" +# define AS_PROC_NAME_FMT "/proc/%d/as" +# define MAP_PROC_NAME_FMT "/proc/%d/map" +# define STATUS_PROC_NAME_FMT "/proc/%d/status" +# define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus") +# endif +/* the name of the proc status struct depends on the implementation */ +typedef pstatus_t gdb_prstatus_t; +typedef lwpstatus_t gdb_lwpstatus_t; +#else /* ! NEW_PROC_API */ +/* format strings for /proc paths */ +# ifndef CTL_PROC_NAME_FMT +# define MAIN_PROC_NAME_FMT "/proc/%05d" +# define CTL_PROC_NAME_FMT "/proc/%05d" +# define AS_PROC_NAME_FMT "/proc/%05d" +# define MAP_PROC_NAME_FMT "/proc/%05d" +# define STATUS_PROC_NAME_FMT "/proc/%05d" +# define MAX_PROC_NAME_SIZE sizeof("/proc/ttttppppp") +# endif +/* the name of the proc status struct depends on the implementation */ +typedef prstatus_t gdb_prstatus_t; +typedef prstatus_t gdb_lwpstatus_t; +#endif /* NEW_PROC_API */ + +typedef struct procinfo { + struct procinfo *next; + int pid; /* Process ID */ + int tid; /* Thread/LWP id */ + + /* process state */ + int was_stopped; + int ignore_next_sigstop; + + /* The following four fd fields may be identical, or may contain + several different fd's, depending on the version of /proc + (old ioctl or new read/write). */ + + int ctl_fd; /* File descriptor for /proc control file */ + /* + * The next three file descriptors are actually only needed in the + * read/write, multiple-file-descriptor implemenation (NEW_PROC_API). + * However, to avoid a bunch of #ifdefs in the code, we will use + * them uniformly by (in the case of the ioctl single-file-descriptor + * implementation) filling them with copies of the control fd. + */ + int status_fd; /* File descriptor for /proc status file */ + int as_fd; /* File descriptor for /proc as file */ + + char pathname[MAX_PROC_NAME_SIZE]; /* Pathname to /proc entry */ + + fltset_t saved_fltset; /* Saved traced hardware fault set */ + gdb_sigset_t saved_sigset; /* Saved traced signal set */ + gdb_sigset_t saved_sighold; /* Saved held signal set */ + sysset_t *saved_exitset; /* Saved traced system call exit set */ + sysset_t *saved_entryset; /* Saved traced system call entry set */ + + gdb_prstatus_t prstatus; /* Current process status info */ + +#ifndef NEW_PROC_API + gdb_fpregset_t fpregset; /* Current floating point registers */ +#endif + +#ifdef DYNAMIC_SYSCALLS + int num_syscalls; /* Total number of syscalls */ + char **syscall_names; /* Syscall number to name map */ +#endif + + struct procinfo *thread_list; + + int status_valid : 1; + int gregs_valid : 1; + int fpregs_valid : 1; + int threads_valid: 1; +} procinfo; + +static char errmsg[128]; /* shared error msg buffer */ + +/* Function prototypes for procinfo module: */ + +static procinfo *find_procinfo_or_die (int pid, int tid); +static procinfo *find_procinfo (int pid, int tid); +static procinfo *create_procinfo (int pid, int tid); +static void destroy_procinfo (procinfo * p); +static void do_destroy_procinfo_cleanup (void *); +static void dead_procinfo (procinfo * p, char *msg, int killp); +static int open_procinfo_files (procinfo * p, int which); +static void close_procinfo_files (procinfo * p); +static int sysset_t_size (procinfo *p); +static sysset_t *sysset_t_alloc (procinfo * pi); +#ifdef DYNAMIC_SYSCALLS +static void load_syscalls (procinfo *pi); +static void free_syscalls (procinfo *pi); +static int find_syscall (procinfo *pi, char *name); +#endif /* DYNAMIC_SYSCALLS */ + +/* The head of the procinfo list: */ +static procinfo * procinfo_list; + +/* + * Function: find_procinfo + * + * Search the procinfo list. + * + * Returns: pointer to procinfo, or NULL if not found. + */ + +static procinfo * +find_procinfo (int pid, int tid) +{ + procinfo *pi; + + for (pi = procinfo_list; pi; pi = pi->next) + if (pi->pid == pid) + break; + + if (pi) + if (tid) + { + /* Don't check threads_valid. If we're updating the + thread_list, we want to find whatever threads are already + here. This means that in general it is the caller's + responsibility to check threads_valid and update before + calling find_procinfo, if the caller wants to find a new + thread. */ + + for (pi = pi->thread_list; pi; pi = pi->next) + if (pi->tid == tid) + break; + } + + return pi; +} + +/* + * Function: find_procinfo_or_die + * + * Calls find_procinfo, but errors on failure. + */ + +static procinfo * +find_procinfo_or_die (int pid, int tid) +{ + procinfo *pi = find_procinfo (pid, tid); + + if (pi == NULL) + { + if (tid) + error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.", + pid, tid); + else + error ("procfs: couldn't find pid %d in procinfo list.", pid); + } + return pi; +} + +/* open_with_retry() is a wrapper for open(). The appropriate + open() call is attempted; if unsuccessful, it will be retried as + many times as needed for the EAGAIN and EINTR conditions. + + For other conditions, open_with_retry() will retry the open() a + limited number of times. In addition, a short sleep is imposed + prior to retrying the open(). The reason for this sleep is to give + the kernel a chance to catch up and create the file in question in + the event that GDB "wins" the race to open a file before the kernel + has created it. */ + +static int +open_with_retry (const char *pathname, int flags) +{ + int retries_remaining, status; + + retries_remaining = 2; + + while (1) + { + status = open (pathname, flags); + + if (status >= 0 || retries_remaining == 0) + break; + else if (errno != EINTR && errno != EAGAIN) + { + retries_remaining--; + sleep (1); + } + } + + return status; +} + +/* + * Function: open_procinfo_files + * + * Open the file descriptor for the process or LWP. + * ifdef NEW_PROC_API, we only open the control file descriptor; + * the others are opened lazily as needed. + * else (if not NEW_PROC_API), there is only one real + * file descriptor, but we keep multiple copies of it so that + * the code that uses them does not have to be #ifdef'd. + * + * Return: file descriptor, or zero for failure. + */ + +enum { FD_CTL, FD_STATUS, FD_AS }; + +static int +open_procinfo_files (procinfo *pi, int which) +{ +#ifdef NEW_PROC_API + char tmp[MAX_PROC_NAME_SIZE]; +#endif + int fd; + + /* + * This function is getting ALMOST long enough to break up into several. + * Here is some rationale: + * + * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware): + * There are several file descriptors that may need to be open + * for any given process or LWP. The ones we're intereted in are: + * - control (ctl) write-only change the state + * - status (status) read-only query the state + * - address space (as) read/write access memory + * - map (map) read-only virtual addr map + * Most of these are opened lazily as they are needed. + * The pathnames for the 'files' for an LWP look slightly + * different from those of a first-class process: + * Pathnames for a process (): + * /proc//ctl + * /proc//status + * /proc//as + * /proc//map + * Pathnames for an LWP (lwp-id): + * /proc//lwp//lwpctl + * /proc//lwp//lwpstatus + * An LWP has no map or address space file descriptor, since + * the memory map and address space are shared by all LWPs. + * + * Everyone else (Solaris 2.5, Irix, OSF) + * There is only one file descriptor for each process or LWP. + * For convenience, we copy the same file descriptor into all + * three fields of the procinfo struct (ctl_fd, status_fd, and + * as_fd, see NEW_PROC_API above) so that code that uses them + * doesn't need any #ifdef's. + * Pathname for all: + * /proc/ + * + * Solaris 2.5 LWP's: + * Each LWP has an independent file descriptor, but these + * are not obtained via the 'open' system call like the rest: + * instead, they're obtained thru an ioctl call (PIOCOPENLWP) + * to the file descriptor of the parent process. + * + * OSF threads: + * These do not even have their own independent file descriptor. + * All operations are carried out on the file descriptor of the + * parent process. Therefore we just call open again for each + * thread, getting a new handle for the same 'file'. + */ + +#ifdef NEW_PROC_API + /* + * In this case, there are several different file descriptors that + * we might be asked to open. The control file descriptor will be + * opened early, but the others will be opened lazily as they are + * needed. + */ + + strcpy (tmp, pi->pathname); + switch (which) { /* which file descriptor to open? */ + case FD_CTL: + if (pi->tid) + strcat (tmp, "/lwpctl"); + else + strcat (tmp, "/ctl"); + fd = open_with_retry (tmp, O_WRONLY); + if (fd <= 0) + return 0; /* fail */ + pi->ctl_fd = fd; + break; + case FD_AS: + if (pi->tid) + return 0; /* there is no 'as' file descriptor for an lwp */ + strcat (tmp, "/as"); + fd = open_with_retry (tmp, O_RDWR); + if (fd <= 0) + return 0; /* fail */ + pi->as_fd = fd; + break; + case FD_STATUS: + if (pi->tid) + strcat (tmp, "/lwpstatus"); + else + strcat (tmp, "/status"); + fd = open_with_retry (tmp, O_RDONLY); + if (fd <= 0) + return 0; /* fail */ + pi->status_fd = fd; + break; + default: + return 0; /* unknown file descriptor */ + } +#else /* not NEW_PROC_API */ + /* + * In this case, there is only one file descriptor for each procinfo + * (ie. each process or LWP). In fact, only the file descriptor for + * the process can actually be opened by an 'open' system call. + * The ones for the LWPs have to be obtained thru an IOCTL call + * on the process's file descriptor. + * + * For convenience, we copy each procinfo's single file descriptor + * into all of the fields occupied by the several file descriptors + * of the NEW_PROC_API implementation. That way, the code that uses + * them can be written without ifdefs. + */ + + +#ifdef PIOCTSTATUS /* OSF */ + /* Only one FD; just open it. */ + if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0) + return 0; +#else /* Sol 2.5, Irix, other? */ + if (pi->tid == 0) /* Master procinfo for the process */ + { + fd = open_with_retry (pi->pathname, O_RDWR); + if (fd <= 0) + return 0; /* fail */ + } + else /* LWP thread procinfo */ + { +#ifdef PIOCOPENLWP /* Sol 2.5, thread/LWP */ + procinfo *process; + int lwpid = pi->tid; + + /* Find the procinfo for the entire process. */ + if ((process = find_procinfo (pi->pid, 0)) == NULL) + return 0; /* fail */ + + /* Now obtain the file descriptor for the LWP. */ + if ((fd = ioctl (process->ctl_fd, PIOCOPENLWP, &lwpid)) <= 0) + return 0; /* fail */ +#else /* Irix, other? */ + return 0; /* Don't know how to open threads */ +#endif /* Sol 2.5 PIOCOPENLWP */ + } +#endif /* OSF PIOCTSTATUS */ + pi->ctl_fd = pi->as_fd = pi->status_fd = fd; +#endif /* NEW_PROC_API */ + + return 1; /* success */ +} + +/* + * Function: create_procinfo + * + * Allocate a data structure and link it into the procinfo list. + * (First tries to find a pre-existing one (FIXME: why?) + * + * Return: pointer to new procinfo struct. + */ + +static procinfo * +create_procinfo (int pid, int tid) +{ + procinfo *pi, *parent; + + if ((pi = find_procinfo (pid, tid))) + return pi; /* Already exists, nothing to do. */ + + /* find parent before doing malloc, to save having to cleanup */ + if (tid != 0) + parent = find_procinfo_or_die (pid, 0); /* FIXME: should I + create it if it + doesn't exist yet? */ + + pi = (procinfo *) xmalloc (sizeof (procinfo)); + memset (pi, 0, sizeof (procinfo)); + pi->pid = pid; + pi->tid = tid; + +#ifdef DYNAMIC_SYSCALLS + load_syscalls (pi); +#endif + + pi->saved_entryset = sysset_t_alloc (pi); + pi->saved_exitset = sysset_t_alloc (pi); + + /* Chain into list. */ + if (tid == 0) + { + sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid); + pi->next = procinfo_list; + procinfo_list = pi; + } + else + { +#ifdef NEW_PROC_API + sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid); +#else + sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid); +#endif + pi->next = parent->thread_list; + parent->thread_list = pi; + } + return pi; +} + +/* + * Function: close_procinfo_files + * + * Close all file descriptors associated with the procinfo + */ + +static void +close_procinfo_files (procinfo *pi) +{ + if (pi->ctl_fd > 0) + close (pi->ctl_fd); +#ifdef NEW_PROC_API + if (pi->as_fd > 0) + close (pi->as_fd); + if (pi->status_fd > 0) + close (pi->status_fd); +#endif + pi->ctl_fd = pi->as_fd = pi->status_fd = 0; +} + +/* + * Function: destroy_procinfo + * + * Destructor function. Close, unlink and deallocate the object. + */ + +static void +destroy_one_procinfo (procinfo **list, procinfo *pi) +{ + procinfo *ptr; + + /* Step one: unlink the procinfo from its list */ + if (pi == *list) + *list = pi->next; + else + for (ptr = *list; ptr; ptr = ptr->next) + if (ptr->next == pi) + { + ptr->next = pi->next; + break; + } + + /* Step two: close any open file descriptors */ + close_procinfo_files (pi); + + /* Step three: free the memory. */ +#ifdef DYNAMIC_SYSCALLS + free_syscalls (pi); +#endif + xfree (pi->saved_entryset); + xfree (pi->saved_exitset); + xfree (pi); +} + +static void +destroy_procinfo (procinfo *pi) +{ + procinfo *tmp; + + if (pi->tid != 0) /* destroy a thread procinfo */ + { + tmp = find_procinfo (pi->pid, 0); /* find the parent process */ + destroy_one_procinfo (&tmp->thread_list, pi); + } + else /* destroy a process procinfo and all its threads */ + { + /* First destroy the children, if any; */ + while (pi->thread_list != NULL) + destroy_one_procinfo (&pi->thread_list, pi->thread_list); + /* Then destroy the parent. Genocide!!! */ + destroy_one_procinfo (&procinfo_list, pi); + } +} + +static void +do_destroy_procinfo_cleanup (void *pi) +{ + destroy_procinfo (pi); +} + +enum { NOKILL, KILL }; + +/* + * Function: dead_procinfo + * + * To be called on a non_recoverable error for a procinfo. + * Prints error messages, optionally sends a SIGKILL to the process, + * then destroys the data structure. + */ + +static void +dead_procinfo (procinfo *pi, char *msg, int kill_p) +{ + char procfile[80]; + + if (pi->pathname) + { + print_sys_errmsg (pi->pathname, errno); + } + else + { + sprintf (procfile, "process %d", pi->pid); + print_sys_errmsg (procfile, errno); + } + if (kill_p == KILL) + kill (pi->pid, SIGKILL); + + destroy_procinfo (pi); + error (msg); +} + +/* + * Function: sysset_t_size + * + * Returns the (complete) size of a sysset_t struct. Normally, this + * is just sizeof (syset_t), but in the case of Monterey/64, the actual + * size of sysset_t isn't known until runtime. + */ + +static int +sysset_t_size (procinfo * pi) +{ +#ifndef DYNAMIC_SYSCALLS + return sizeof (sysset_t); +#else + return sizeof (sysset_t) - sizeof (uint64_t) + + sizeof (uint64_t) * ((pi->num_syscalls + (8 * sizeof (uint64_t) - 1)) + / (8 * sizeof (uint64_t))); +#endif +} + +/* Function: sysset_t_alloc + + Allocate and (partially) initialize a sysset_t struct. */ + +static sysset_t * +sysset_t_alloc (procinfo * pi) +{ + sysset_t *ret; + int size = sysset_t_size (pi); + ret = xmalloc (size); +#ifdef DYNAMIC_SYSCALLS + ret->pr_size = (pi->num_syscalls + (8 * sizeof (uint64_t) - 1)) + / (8 * sizeof (uint64_t)); +#endif + return ret; +} + +#ifdef DYNAMIC_SYSCALLS + +/* Function: load_syscalls + + Extract syscall numbers and names from /proc//sysent. Initialize + pi->num_syscalls with the number of syscalls and pi->syscall_names + with the names. (Certain numbers may be skipped in which case the + names for these numbers will be left as NULL.) */ + +#define MAX_SYSCALL_NAME_LENGTH 256 +#define MAX_SYSCALLS 65536 + +static void +load_syscalls (procinfo *pi) +{ + char pathname[MAX_PROC_NAME_SIZE]; + int sysent_fd; + prsysent_t header; + prsyscall_t *syscalls; + int i, size, maxcall; + + pi->num_syscalls = 0; + pi->syscall_names = 0; + + /* Open the file descriptor for the sysent file */ + sprintf (pathname, "/proc/%d/sysent", pi->pid); + sysent_fd = open_with_retry (pathname, O_RDONLY); + if (sysent_fd < 0) + { + error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid); + } + + size = sizeof header - sizeof (prsyscall_t); + if (read (sysent_fd, &header, size) != size) + { + error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid); + } + + if (header.pr_nsyscalls == 0) + { + error ("load_syscalls: /proc/%d/sysent contains no syscalls!", pi->pid); + } + + size = header.pr_nsyscalls * sizeof (prsyscall_t); + syscalls = xmalloc (size); + + if (read (sysent_fd, syscalls, size) != size) + { + xfree (syscalls); + error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid); + } + + /* Find maximum syscall number. This may not be the same as + pr_nsyscalls since that value refers to the number of entries + in the table. (Also, the docs indicate that some system + call numbers may be skipped.) */ + + maxcall = syscalls[0].pr_number; + + for (i = 1; i < header.pr_nsyscalls; i++) + if (syscalls[i].pr_number > maxcall + && syscalls[i].pr_nameoff > 0 + && syscalls[i].pr_number < MAX_SYSCALLS) + maxcall = syscalls[i].pr_number; + + pi->num_syscalls = maxcall+1; + pi->syscall_names = xmalloc (pi->num_syscalls * sizeof (char *)); + + for (i = 0; i < pi->num_syscalls; i++) + pi->syscall_names[i] = NULL; + + /* Read the syscall names in */ + for (i = 0; i < header.pr_nsyscalls; i++) + { + char namebuf[MAX_SYSCALL_NAME_LENGTH]; + int nread; + int callnum; + + if (syscalls[i].pr_number >= MAX_SYSCALLS + || syscalls[i].pr_number < 0 + || syscalls[i].pr_nameoff <= 0 + || (lseek (sysent_fd, (off_t) syscalls[i].pr_nameoff, SEEK_SET) + != (off_t) syscalls[i].pr_nameoff)) + continue; + + nread = read (sysent_fd, namebuf, sizeof namebuf); + if (nread <= 0) + continue; + + callnum = syscalls[i].pr_number; + + if (pi->syscall_names[callnum] != NULL) + { + /* FIXME: Generate warning */ + continue; + } + + namebuf[nread-1] = '\0'; + size = strlen (namebuf) + 1; + pi->syscall_names[callnum] = xmalloc (size); + strncpy (pi->syscall_names[callnum], namebuf, size-1); + pi->syscall_names[callnum][size-1] = '\0'; + } + + close (sysent_fd); + xfree (syscalls); +} + +/* Function: free_syscalls + + Free the space allocated for the syscall names from the procinfo + structure. */ + +static void +free_syscalls (procinfo *pi) +{ + if (pi->syscall_names) + { + int i; + + for (i = 0; i < pi->num_syscalls; i++) + if (pi->syscall_names[i] != NULL) + xfree (pi->syscall_names[i]); + + xfree (pi->syscall_names); + pi->syscall_names = 0; + } +} + +/* Function: find_syscall + + Given a name, look up (and return) the corresponding syscall number. + If no match is found, return -1. */ + +static int +find_syscall (procinfo *pi, char *name) +{ + int i; + for (i = 0; i < pi->num_syscalls; i++) + { + if (pi->syscall_names[i] && strcmp (name, pi->syscall_names[i]) == 0) + return i; + } + return -1; +} +#endif + +/* =================== END, STRUCT PROCINFO "MODULE" =================== */ + +/* =================== /proc "MODULE" =================== */ + +/* + * This "module" is the interface layer between the /proc system API + * and the gdb target vector functions. This layer consists of + * access functions that encapsulate each of the basic operations + * that we need to use from the /proc API. + * + * The main motivation for this layer is to hide the fact that + * there are two very different implementations of the /proc API. + * Rather than have a bunch of #ifdefs all thru the gdb target vector + * functions, we do our best to hide them all in here. + */ + +int proc_get_status (procinfo * pi); +long proc_flags (procinfo * pi); +int proc_why (procinfo * pi); +int proc_what (procinfo * pi); +int proc_set_run_on_last_close (procinfo * pi); +int proc_unset_run_on_last_close (procinfo * pi); +int proc_set_inherit_on_fork (procinfo * pi); +int proc_unset_inherit_on_fork (procinfo * pi); +int proc_set_async (procinfo * pi); +int proc_unset_async (procinfo * pi); +int proc_stop_process (procinfo * pi); +int proc_trace_signal (procinfo * pi, int signo); +int proc_ignore_signal (procinfo * pi, int signo); +int proc_clear_current_fault (procinfo * pi); +int proc_set_current_signal (procinfo * pi, int signo); +int proc_clear_current_signal (procinfo * pi); +int proc_set_gregs (procinfo * pi); +int proc_set_fpregs (procinfo * pi); +int proc_wait_for_stop (procinfo * pi); +int proc_run_process (procinfo * pi, int step, int signo); +int proc_kill (procinfo * pi, int signo); +int proc_parent_pid (procinfo * pi); +int proc_get_nthreads (procinfo * pi); +int proc_get_current_thread (procinfo * pi); +int proc_set_held_signals (procinfo * pi, gdb_sigset_t * sighold); +int proc_set_traced_sysexit (procinfo * pi, sysset_t * sysset); +int proc_set_traced_sysentry (procinfo * pi, sysset_t * sysset); +int proc_set_traced_faults (procinfo * pi, fltset_t * fltset); +int proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset); + +int proc_update_threads (procinfo * pi); +int proc_iterate_over_threads (procinfo * pi, + int (*func) (procinfo *, procinfo *, void *), + void *ptr); + +gdb_gregset_t *proc_get_gregs (procinfo * pi); +gdb_fpregset_t *proc_get_fpregs (procinfo * pi); +sysset_t *proc_get_traced_sysexit (procinfo * pi, sysset_t * save); +sysset_t *proc_get_traced_sysentry (procinfo * pi, sysset_t * save); +fltset_t *proc_get_traced_faults (procinfo * pi, fltset_t * save); +gdb_sigset_t *proc_get_traced_signals (procinfo * pi, gdb_sigset_t * save); +gdb_sigset_t *proc_get_held_signals (procinfo * pi, gdb_sigset_t * save); +gdb_sigset_t *proc_get_pending_signals (procinfo * pi, gdb_sigset_t * save); +gdb_sigaction_t *proc_get_signal_actions (procinfo * pi, gdb_sigaction_t *save); + +void proc_warn (procinfo * pi, char *func, int line); +void proc_error (procinfo * pi, char *func, int line); + +void +proc_warn (procinfo *pi, char *func, int line) +{ + sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname); + print_sys_errmsg (errmsg, errno); +} + +void +proc_error (procinfo *pi, char *func, int line) +{ + sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname); + perror_with_name (errmsg); +} + +/* + * Function: proc_get_status + * + * Updates the status struct in the procinfo. + * There is a 'valid' flag, to let other functions know when + * this function needs to be called (so the status is only + * read when it is needed). The status file descriptor is + * also only opened when it is needed. + * + * Return: non-zero for success, zero for failure. + */ + +int +proc_get_status (procinfo *pi) +{ + /* Status file descriptor is opened "lazily" */ + if (pi->status_fd == 0 && + open_procinfo_files (pi, FD_STATUS) == 0) + { + pi->status_valid = 0; + return 0; + } + +#ifdef NEW_PROC_API + if (lseek (pi->status_fd, 0, SEEK_SET) < 0) + pi->status_valid = 0; /* fail */ + else + { + /* Sigh... I have to read a different data structure, + depending on whether this is a main process or an LWP. */ + if (pi->tid) + pi->status_valid = (read (pi->status_fd, + (char *) &pi->prstatus.pr_lwp, + sizeof (lwpstatus_t)) + == sizeof (lwpstatus_t)); + else + { + pi->status_valid = (read (pi->status_fd, + (char *) &pi->prstatus, + sizeof (gdb_prstatus_t)) + == sizeof (gdb_prstatus_t)); +#if 0 /*def UNIXWARE*/ + if (pi->status_valid && + (pi->prstatus.pr_lwp.pr_flags & PR_ISTOP) && + pi->prstatus.pr_lwp.pr_why == PR_REQUESTED) + /* Unixware peculiarity -- read the damn thing again! */ + pi->status_valid = (read (pi->status_fd, + (char *) &pi->prstatus, + sizeof (gdb_prstatus_t)) + == sizeof (gdb_prstatus_t)); +#endif /* UNIXWARE */ + } + } +#else /* ioctl method */ +#ifdef PIOCTSTATUS /* osf */ + if (pi->tid == 0) /* main process */ + { + /* Just read the danged status. Now isn't that simple? */ + pi->status_valid = + (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0); + } + else + { + int win; + struct { + long pr_count; + tid_t pr_error_thread; + struct prstatus status; + } thread_status; + + thread_status.pr_count = 1; + thread_status.status.pr_tid = pi->tid; + win = (ioctl (pi->status_fd, PIOCTSTATUS, &thread_status) >= 0); + if (win) + { + memcpy (&pi->prstatus, &thread_status.status, + sizeof (pi->prstatus)); + pi->status_valid = 1; + } + } +#else + /* Just read the danged status. Now isn't that simple? */ + pi->status_valid = (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0); +#endif +#endif + + if (pi->status_valid) + { + PROC_PRETTYFPRINT_STATUS (proc_flags (pi), + proc_why (pi), + proc_what (pi), + proc_get_current_thread (pi)); + } + + /* The status struct includes general regs, so mark them valid too */ + pi->gregs_valid = pi->status_valid; +#ifdef NEW_PROC_API + /* In the read/write multiple-fd model, + the status struct includes the fp regs too, so mark them valid too */ + pi->fpregs_valid = pi->status_valid; +#endif + return pi->status_valid; /* True if success, false if failure. */ +} + +/* + * Function: proc_flags + * + * returns the process flags (pr_flags field). + */ + +long +proc_flags (procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; /* FIXME: not a good failure value (but what is?) */ + +#ifdef NEW_PROC_API +# ifdef UNIXWARE + /* UnixWare 7.1 puts process status flags, e.g. PR_ASYNC, in + pstatus_t and LWP status flags, e.g. PR_STOPPED, in lwpstatus_t. + The two sets of flags don't overlap. */ + return pi->prstatus.pr_flags | pi->prstatus.pr_lwp.pr_flags; +# else + return pi->prstatus.pr_lwp.pr_flags; +# endif +#else + return pi->prstatus.pr_flags; +#endif +} + +/* + * Function: proc_why + * + * returns the pr_why field (why the process stopped). + */ + +int +proc_why (procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; /* FIXME: not a good failure value (but what is?) */ + +#ifdef NEW_PROC_API + return pi->prstatus.pr_lwp.pr_why; +#else + return pi->prstatus.pr_why; +#endif +} + +/* + * Function: proc_what + * + * returns the pr_what field (details of why the process stopped). + */ + +int +proc_what (procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; /* FIXME: not a good failure value (but what is?) */ + +#ifdef NEW_PROC_API + return pi->prstatus.pr_lwp.pr_what; +#else + return pi->prstatus.pr_what; +#endif +} + +#ifndef PIOCSSPCACT /* The following is not supported on OSF. */ +/* + * Function: proc_nsysarg + * + * returns the pr_nsysarg field (number of args to the current syscall). + */ + +int +proc_nsysarg (procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; + +#ifdef NEW_PROC_API + return pi->prstatus.pr_lwp.pr_nsysarg; +#else + return pi->prstatus.pr_nsysarg; +#endif +} + +/* + * Function: proc_sysargs + * + * returns the pr_sysarg field (pointer to the arguments of current syscall). + */ + +long * +proc_sysargs (procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + +#ifdef NEW_PROC_API + return (long *) &pi->prstatus.pr_lwp.pr_sysarg; +#else + return (long *) &pi->prstatus.pr_sysarg; +#endif +} + +/* + * Function: proc_syscall + * + * returns the pr_syscall field (id of current syscall if we are in one). + */ + +int +proc_syscall (procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; + +#ifdef NEW_PROC_API + return pi->prstatus.pr_lwp.pr_syscall; +#else + return pi->prstatus.pr_syscall; +#endif +} +#endif /* PIOCSSPCACT */ + +/* + * Function: proc_cursig: + * + * returns the pr_cursig field (current signal). + */ + +long +proc_cursig (struct procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; /* FIXME: not a good failure value (but what is?) */ + +#ifdef NEW_PROC_API + return pi->prstatus.pr_lwp.pr_cursig; +#else + return pi->prstatus.pr_cursig; +#endif +} + +/* + * Function: proc_modify_flag + * + * === I appologize for the messiness of this function. + * === This is an area where the different versions of + * === /proc are more inconsistent than usual. MVS + * + * Set or reset any of the following process flags: + * PR_FORK -- forked child will inherit trace flags + * PR_RLC -- traced process runs when last /proc file closed. + * PR_KLC -- traced process is killed when last /proc file closed. + * PR_ASYNC -- LWP's get to run/stop independently. + * + * There are three methods for doing this function: + * 1) Newest: read/write [PCSET/PCRESET/PCUNSET] + * [Sol6, Sol7, UW] + * 2) Middle: PIOCSET/PIOCRESET + * [Irix, Sol5] + * 3) Oldest: PIOCSFORK/PIOCRFORK/PIOCSRLC/PIOCRRLC + * [OSF, Sol5] + * + * Note: Irix does not define PR_ASYNC. + * Note: OSF does not define PR_KLC. + * Note: OSF is the only one that can ONLY use the oldest method. + * + * Arguments: + * pi -- the procinfo + * flag -- one of PR_FORK, PR_RLC, or PR_ASYNC + * mode -- 1 for set, 0 for reset. + * + * Returns non-zero for success, zero for failure. + */ + +enum { FLAG_RESET, FLAG_SET }; + +static int +proc_modify_flag (procinfo *pi, long flag, long mode) +{ + long win = 0; /* default to fail */ + + /* + * These operations affect the process as a whole, and applying + * them to an individual LWP has the same meaning as applying them + * to the main process. Therefore, if we're ever called with a + * pointer to an LWP's procinfo, let's substitute the process's + * procinfo and avoid opening the LWP's file descriptor + * unnecessarily. + */ + + if (pi->pid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API /* Newest method: UnixWare and newer Solarii */ + /* First normalize the PCUNSET/PCRESET command opcode + (which for no obvious reason has a different definition + from one operating system to the next...) */ +#ifdef PCUNSET +#define GDBRESET PCUNSET +#else +#ifdef PCRESET +#define GDBRESET PCRESET +#endif +#endif + { + procfs_ctl_t arg[2]; + + if (mode == FLAG_SET) /* Set the flag (RLC, FORK, or ASYNC) */ + arg[0] = PCSET; + else /* Reset the flag */ + arg[0] = GDBRESET; + + arg[1] = flag; + win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); + } +#else +#ifdef PIOCSET /* Irix/Sol5 method */ + if (mode == FLAG_SET) /* Set the flag (hopefully RLC, FORK, or ASYNC) */ + { + win = (ioctl (pi->ctl_fd, PIOCSET, &flag) >= 0); + } + else /* Reset the flag */ + { + win = (ioctl (pi->ctl_fd, PIOCRESET, &flag) >= 0); + } + +#else +#ifdef PIOCSRLC /* Oldest method: OSF */ + switch (flag) { + case PR_RLC: + if (mode == FLAG_SET) /* Set run-on-last-close */ + { + win = (ioctl (pi->ctl_fd, PIOCSRLC, NULL) >= 0); + } + else /* Clear run-on-last-close */ + { + win = (ioctl (pi->ctl_fd, PIOCRRLC, NULL) >= 0); + } + break; + case PR_FORK: + if (mode == FLAG_SET) /* Set inherit-on-fork */ + { + win = (ioctl (pi->ctl_fd, PIOCSFORK, NULL) >= 0); + } + else /* Clear inherit-on-fork */ + { + win = (ioctl (pi->ctl_fd, PIOCRFORK, NULL) >= 0); + } + break; + default: + win = 0; /* fail -- unknown flag (can't do PR_ASYNC) */ + break; + } +#endif +#endif +#endif +#undef GDBRESET + /* The above operation renders the procinfo's cached pstatus obsolete. */ + pi->status_valid = 0; + + if (!win) + warning ("procfs: modify_flag failed to turn %s %s", + flag == PR_FORK ? "PR_FORK" : + flag == PR_RLC ? "PR_RLC" : +#ifdef PR_ASYNC + flag == PR_ASYNC ? "PR_ASYNC" : +#endif +#ifdef PR_KLC + flag == PR_KLC ? "PR_KLC" : +#endif + "", + mode == FLAG_RESET ? "off" : "on"); + + return win; +} + +/* + * Function: proc_set_run_on_last_close + * + * Set the run_on_last_close flag. + * Process with all threads will become runnable + * when debugger closes all /proc fds. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_run_on_last_close (procinfo *pi) +{ + return proc_modify_flag (pi, PR_RLC, FLAG_SET); +} + +/* + * Function: proc_unset_run_on_last_close + * + * Reset the run_on_last_close flag. + * Process will NOT become runnable + * when debugger closes its file handles. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_unset_run_on_last_close (procinfo *pi) +{ + return proc_modify_flag (pi, PR_RLC, FLAG_RESET); +} + +#ifdef PR_KLC +/* + * Function: proc_set_kill_on_last_close + * + * Set the kill_on_last_close flag. + * Process with all threads will be killed when debugger + * closes all /proc fds (or debugger exits or dies). + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_kill_on_last_close (procinfo *pi) +{ + return proc_modify_flag (pi, PR_KLC, FLAG_SET); +} + +/* + * Function: proc_unset_kill_on_last_close + * + * Reset the kill_on_last_close flag. + * Process will NOT be killed when debugger + * closes its file handles (or exits or dies). + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_unset_kill_on_last_close (procinfo *pi) +{ + return proc_modify_flag (pi, PR_KLC, FLAG_RESET); +} +#endif /* PR_KLC */ + +/* + * Function: proc_set_inherit_on_fork + * + * Set inherit_on_fork flag. + * If the process forks a child while we are registered for events + * in the parent, then we will also recieve events from the child. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_inherit_on_fork (procinfo *pi) +{ + return proc_modify_flag (pi, PR_FORK, FLAG_SET); +} + +/* + * Function: proc_unset_inherit_on_fork + * + * Reset inherit_on_fork flag. + * If the process forks a child while we are registered for events + * in the parent, then we will NOT recieve events from the child. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_unset_inherit_on_fork (procinfo *pi) +{ + return proc_modify_flag (pi, PR_FORK, FLAG_RESET); +} + +#ifdef PR_ASYNC +/* + * Function: proc_set_async + * + * Set PR_ASYNC flag. + * If one LWP stops because of a debug event (signal etc.), + * the remaining LWPs will continue to run. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_async (procinfo *pi) +{ + return proc_modify_flag (pi, PR_ASYNC, FLAG_SET); +} + +/* + * Function: proc_unset_async + * + * Reset PR_ASYNC flag. + * If one LWP stops because of a debug event (signal etc.), + * then all other LWPs will stop as well. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_unset_async (procinfo *pi) +{ + return proc_modify_flag (pi, PR_ASYNC, FLAG_RESET); +} +#endif /* PR_ASYNC */ + +/* + * Function: proc_stop_process + * + * Request the process/LWP to stop. Does not wait. + * Returns non-zero for success, zero for failure. + */ + +int +proc_stop_process (procinfo *pi) +{ + int win; + + /* + * We might conceivably apply this operation to an LWP, and + * the LWP's ctl file descriptor might not be open. + */ + + if (pi->ctl_fd == 0 && + open_procinfo_files (pi, FD_CTL) == 0) + return 0; + else + { +#ifdef NEW_PROC_API + procfs_ctl_t cmd = PCSTOP; + win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); +#else /* ioctl method */ + win = (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) >= 0); + /* Note: the call also reads the prstatus. */ + if (win) + { + pi->status_valid = 1; + PROC_PRETTYFPRINT_STATUS (proc_flags (pi), + proc_why (pi), + proc_what (pi), + proc_get_current_thread (pi)); + } +#endif + } + + return win; +} + +/* + * Function: proc_wait_for_stop + * + * Wait for the process or LWP to stop (block until it does). + * Returns non-zero for success, zero for failure. + */ + +int +proc_wait_for_stop (procinfo *pi) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + procfs_ctl_t cmd = PCWSTOP; + win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); + /* We been runnin' and we stopped -- need to update status. */ + pi->status_valid = 0; + } +#else /* ioctl method */ + win = (ioctl (pi->ctl_fd, PIOCWSTOP, &pi->prstatus) >= 0); + /* Above call also refreshes the prstatus. */ + if (win) + { + pi->status_valid = 1; + PROC_PRETTYFPRINT_STATUS (proc_flags (pi), + proc_why (pi), + proc_what (pi), + proc_get_current_thread (pi)); + } +#endif + + return win; +} + +/* + * Function: proc_run_process + * + * Make the process or LWP runnable. + * Options (not all are implemented): + * - single-step + * - clear current fault + * - clear current signal + * - abort the current system call + * - stop as soon as finished with system call + * - (ioctl): set traced signal set + * - (ioctl): set held signal set + * - (ioctl): set traced fault set + * - (ioctl): set start pc (vaddr) + * Always clear the current fault. + * Clear the current signal if 'signo' is zero. + * + * Arguments: + * pi the process or LWP to operate on. + * step if true, set the process or LWP to trap after one instr. + * signo if zero, clear the current signal if any. + * if non-zero, set the current signal to this one. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_run_process (procinfo *pi, int step, int signo) +{ + int win; + int runflags; + + /* + * We will probably have to apply this operation to individual threads, + * so make sure the control file descriptor is open. + */ + + if (pi->ctl_fd == 0 && + open_procinfo_files (pi, FD_CTL) == 0) + { + return 0; + } + + runflags = PRCFAULT; /* always clear current fault */ + if (step) + runflags |= PRSTEP; + if (signo == 0) + runflags |= PRCSIG; + else if (signo != -1) /* -1 means do nothing W.R.T. signals */ + proc_set_current_signal (pi, signo); + +#ifdef NEW_PROC_API + { + procfs_ctl_t cmd[2]; + + cmd[0] = PCRUN; + cmd[1] = runflags; + win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); + } +#else /* ioctl method */ + { + prrun_t prrun; + + memset (&prrun, 0, sizeof (prrun)); + prrun.pr_flags = runflags; + win = (ioctl (pi->ctl_fd, PIOCRUN, &prrun) >= 0); + } +#endif + + return win; +} + +/* + * Function: proc_set_traced_signals + * + * Register to trace signals in the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + struct { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char sigset[sizeof (gdb_sigset_t)]; + } arg; + + arg.cmd = PCSTRACE; + memcpy (&arg.sigset, sigset, sizeof (gdb_sigset_t)); + + win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg)); + } +#else /* ioctl method */ + win = (ioctl (pi->ctl_fd, PIOCSTRACE, sigset) >= 0); +#endif + /* The above operation renders the procinfo's cached pstatus obsolete. */ + pi->status_valid = 0; + + if (!win) + warning ("procfs: set_traced_signals failed"); + return win; +} + +/* + * Function: proc_set_traced_faults + * + * Register to trace hardware faults in the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_traced_faults (procinfo *pi, fltset_t *fltset) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + struct { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char fltset[sizeof (fltset_t)]; + } arg; + + arg.cmd = PCSFAULT; + memcpy (&arg.fltset, fltset, sizeof (fltset_t)); + + win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg)); + } +#else /* ioctl method */ + win = (ioctl (pi->ctl_fd, PIOCSFAULT, fltset) >= 0); +#endif + /* The above operation renders the procinfo's cached pstatus obsolete. */ + pi->status_valid = 0; + + return win; +} + +/* + * Function: proc_set_traced_sysentry + * + * Register to trace entry to system calls in the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + struct gdb_proc_ctl_pcsentry { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char sysset[sizeof (sysset_t)]; + } *argp; + int argp_size = sizeof (struct gdb_proc_ctl_pcsentry) + - sizeof (sysset_t) + + sysset_t_size (pi); + + argp = xmalloc (argp_size); + + argp->cmd = PCSENTRY; + memcpy (&argp->sysset, sysset, sysset_t_size (pi)); + + win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size); + xfree (argp); + } +#else /* ioctl method */ + win = (ioctl (pi->ctl_fd, PIOCSENTRY, sysset) >= 0); +#endif + /* The above operation renders the procinfo's cached pstatus obsolete. */ + pi->status_valid = 0; + + return win; +} + +/* + * Function: proc_set_traced_sysexit + * + * Register to trace exit from system calls in the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + struct gdb_proc_ctl_pcsexit { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char sysset[sizeof (sysset_t)]; + } *argp; + int argp_size = sizeof (struct gdb_proc_ctl_pcsexit) + - sizeof (sysset_t) + + sysset_t_size (pi); + + argp = xmalloc (argp_size); + + argp->cmd = PCSEXIT; + memcpy (&argp->sysset, sysset, sysset_t_size (pi)); + + win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size); + xfree (argp); + } +#else /* ioctl method */ + win = (ioctl (pi->ctl_fd, PIOCSEXIT, sysset) >= 0); +#endif + /* The above operation renders the procinfo's cached pstatus obsolete. */ + pi->status_valid = 0; + + return win; +} + +/* + * Function: proc_set_held_signals + * + * Specify the set of blocked / held signals in the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + struct { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char hold[sizeof (gdb_sigset_t)]; + } arg; + + arg.cmd = PCSHOLD; + memcpy (&arg.hold, sighold, sizeof (gdb_sigset_t)); + win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); + } +#else + win = (ioctl (pi->ctl_fd, PIOCSHOLD, sighold) >= 0); +#endif + /* The above operation renders the procinfo's cached pstatus obsolete. */ + pi->status_valid = 0; + + return win; +} + +/* + * Function: proc_get_pending_signals + * + * returns the set of signals that are pending in the process or LWP. + * Will also copy the sigset if 'save' is non-zero. + */ + +gdb_sigset_t * +proc_get_pending_signals (procinfo *pi, gdb_sigset_t *save) +{ + gdb_sigset_t *ret = NULL; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + +#ifdef NEW_PROC_API + ret = &pi->prstatus.pr_lwp.pr_lwppend; +#else + ret = &pi->prstatus.pr_sigpend; +#endif + if (save && ret) + memcpy (save, ret, sizeof (gdb_sigset_t)); + + return ret; +} + +/* + * Function: proc_get_signal_actions + * + * returns the set of signal actions. + * Will also copy the sigactionset if 'save' is non-zero. + */ + +gdb_sigaction_t * +proc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save) +{ + gdb_sigaction_t *ret = NULL; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + +#ifdef NEW_PROC_API + ret = &pi->prstatus.pr_lwp.pr_action; +#else + ret = &pi->prstatus.pr_action; +#endif + if (save && ret) + memcpy (save, ret, sizeof (gdb_sigaction_t)); + + return ret; +} + +/* + * Function: proc_get_held_signals + * + * returns the set of signals that are held / blocked. + * Will also copy the sigset if 'save' is non-zero. + */ + +gdb_sigset_t * +proc_get_held_signals (procinfo *pi, gdb_sigset_t *save) +{ + gdb_sigset_t *ret = NULL; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + +#ifdef UNIXWARE + ret = &pi->prstatus.pr_lwp.pr_context.uc_sigmask; +#else + ret = &pi->prstatus.pr_lwp.pr_lwphold; +#endif /* UNIXWARE */ +#else /* not NEW_PROC_API */ + { + static gdb_sigset_t sigheld; + + if (ioctl (pi->ctl_fd, PIOCGHOLD, &sigheld) >= 0) + ret = &sigheld; + } +#endif /* NEW_PROC_API */ + if (save && ret) + memcpy (save, ret, sizeof (gdb_sigset_t)); + + return ret; +} + +/* + * Function: proc_get_traced_signals + * + * returns the set of signals that are traced / debugged. + * Will also copy the sigset if 'save' is non-zero. + */ + +gdb_sigset_t * +proc_get_traced_signals (procinfo *pi, gdb_sigset_t *save) +{ + gdb_sigset_t *ret = NULL; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + + ret = &pi->prstatus.pr_sigtrace; +#else + { + static gdb_sigset_t sigtrace; + + if (ioctl (pi->ctl_fd, PIOCGTRACE, &sigtrace) >= 0) + ret = &sigtrace; + } +#endif + if (save && ret) + memcpy (save, ret, sizeof (gdb_sigset_t)); + + return ret; +} + +/* + * Function: proc_trace_signal + * + * Add 'signo' to the set of signals that are traced. + * Returns non-zero for success, zero for failure. + */ + +int +proc_trace_signal (procinfo *pi, int signo) +{ + gdb_sigset_t temp; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + if (pi) + { + if (proc_get_traced_signals (pi, &temp)) + { + praddset (&temp, signo); + return proc_set_traced_signals (pi, &temp); + } + } + + return 0; /* failure */ +} + +/* + * Function: proc_ignore_signal + * + * Remove 'signo' from the set of signals that are traced. + * Returns non-zero for success, zero for failure. + */ + +int +proc_ignore_signal (procinfo *pi, int signo) +{ + gdb_sigset_t temp; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + if (pi) + { + if (proc_get_traced_signals (pi, &temp)) + { + prdelset (&temp, signo); + return proc_set_traced_signals (pi, &temp); + } + } + + return 0; /* failure */ +} + +/* + * Function: proc_get_traced_faults + * + * returns the set of hardware faults that are traced /debugged. + * Will also copy the faultset if 'save' is non-zero. + */ + +fltset_t * +proc_get_traced_faults (procinfo *pi, fltset_t *save) +{ + fltset_t *ret = NULL; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + + ret = &pi->prstatus.pr_flttrace; +#else + { + static fltset_t flttrace; + + if (ioctl (pi->ctl_fd, PIOCGFAULT, &flttrace) >= 0) + ret = &flttrace; + } +#endif + if (save && ret) + memcpy (save, ret, sizeof (fltset_t)); + + return ret; +} + +/* + * Function: proc_get_traced_sysentry + * + * returns the set of syscalls that are traced /debugged on entry. + * Will also copy the syscall set if 'save' is non-zero. + */ + +sysset_t * +proc_get_traced_sysentry (procinfo *pi, sysset_t *save) +{ + sysset_t *ret = NULL; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + +#ifndef DYNAMIC_SYSCALLS + ret = &pi->prstatus.pr_sysentry; +#else /* DYNAMIC_SYSCALLS */ + { + static sysset_t *sysentry; + size_t size; + + if (!sysentry) + sysentry = sysset_t_alloc (pi); + ret = sysentry; + if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0) + return NULL; + if (pi->prstatus.pr_sysentry_offset == 0) + { + gdb_premptysysset (sysentry); + } + else + { + int rsize; + + if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysentry_offset, + SEEK_SET) + != (off_t) pi->prstatus.pr_sysentry_offset) + return NULL; + size = sysset_t_size (pi); + gdb_premptysysset (sysentry); + rsize = read (pi->status_fd, sysentry, size); + if (rsize < 0) + return NULL; + } + } +#endif /* DYNAMIC_SYSCALLS */ +#else /* !NEW_PROC_API */ + { + static sysset_t sysentry; + + if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysentry) >= 0) + ret = &sysentry; + } +#endif /* NEW_PROC_API */ + if (save && ret) + memcpy (save, ret, sysset_t_size (pi)); + + return ret; +} + +/* + * Function: proc_get_traced_sysexit + * + * returns the set of syscalls that are traced /debugged on exit. + * Will also copy the syscall set if 'save' is non-zero. + */ + +sysset_t * +proc_get_traced_sysexit (procinfo *pi, sysset_t *save) +{ + sysset_t * ret = NULL; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + if (!pi->status_valid) + if (!proc_get_status (pi)) + return NULL; + +#ifndef DYNAMIC_SYSCALLS + ret = &pi->prstatus.pr_sysexit; +#else /* DYNAMIC_SYSCALLS */ + { + static sysset_t *sysexit; + size_t size; + + if (!sysexit) + sysexit = sysset_t_alloc (pi); + ret = sysexit; + if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0) + return NULL; + if (pi->prstatus.pr_sysexit_offset == 0) + { + gdb_premptysysset (sysexit); + } + else + { + int rsize; + + if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysexit_offset, SEEK_SET) + != (off_t) pi->prstatus.pr_sysexit_offset) + return NULL; + size = sysset_t_size (pi); + gdb_premptysysset (sysexit); + rsize = read (pi->status_fd, sysexit, size); + if (rsize < 0) + return NULL; + } + } +#endif /* DYNAMIC_SYSCALLS */ +#else + { + static sysset_t sysexit; + + if (ioctl (pi->ctl_fd, PIOCGEXIT, &sysexit) >= 0) + ret = &sysexit; + } +#endif + if (save && ret) + memcpy (save, ret, sysset_t_size (pi)); + + return ret; +} + +/* + * Function: proc_clear_current_fault + * + * The current fault (if any) is cleared; the associated signal + * will not be sent to the process or LWP when it resumes. + * Returns non-zero for success, zero for failure. + */ + +int +proc_clear_current_fault (procinfo *pi) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + procfs_ctl_t cmd = PCCFAULT; + win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd)); + } +#else + win = (ioctl (pi->ctl_fd, PIOCCFAULT, 0) >= 0); +#endif + + return win; +} + +/* + * Function: proc_set_current_signal + * + * Set the "current signal" that will be delivered next to the process. + * NOTE: semantics are different from those of KILL. + * This signal will be delivered to the process or LWP + * immediately when it is resumed (even if the signal is held/blocked); + * it will NOT immediately cause another event of interest, and will NOT + * first trap back to the debugger. + * + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_current_signal (procinfo *pi, int signo) +{ + int win; + struct { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char sinfo[sizeof (gdb_siginfo_t)]; + } arg; + gdb_siginfo_t *mysinfo; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef PROCFS_DONT_PIOCSSIG_CURSIG + /* With Alpha OSF/1 procfs, the kernel gets really confused if it + * receives a PIOCSSIG with a signal identical to the current signal, + * it messes up the current signal. Work around the kernel bug. + */ + if (signo > 0 && + signo == proc_cursig (pi)) + return 1; /* I assume this is a success? */ +#endif + + /* The pointer is just a type alias. */ + mysinfo = (gdb_siginfo_t *) &arg.sinfo; + mysinfo->si_signo = signo; + mysinfo->si_code = 0; + mysinfo->si_pid = getpid (); /* ?why? */ + mysinfo->si_uid = getuid (); /* ?why? */ + +#ifdef NEW_PROC_API + arg.cmd = PCSSIG; + win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); +#else + win = (ioctl (pi->ctl_fd, PIOCSSIG, (void *) &arg.sinfo) >= 0); +#endif + + return win; +} + +/* + * Function: proc_clear_current_signal + * + * The current signal (if any) is cleared, and + * is not sent to the process or LWP when it resumes. + * Returns non-zero for success, zero for failure. + */ + +int +proc_clear_current_signal (procinfo *pi) +{ + int win; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + +#ifdef NEW_PROC_API + { + struct { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char sinfo[sizeof (gdb_siginfo_t)]; + } arg; + gdb_siginfo_t *mysinfo; + + arg.cmd = PCSSIG; + /* The pointer is just a type alias. */ + mysinfo = (gdb_siginfo_t *) &arg.sinfo; + mysinfo->si_signo = 0; + mysinfo->si_code = 0; + mysinfo->si_errno = 0; + mysinfo->si_pid = getpid (); /* ?why? */ + mysinfo->si_uid = getuid (); /* ?why? */ + + win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); + } +#else + win = (ioctl (pi->ctl_fd, PIOCSSIG, 0) >= 0); +#endif + + return win; +} + +/* + * Function: proc_get_gregs + * + * Get the general registers for the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +gdb_gregset_t * +proc_get_gregs (procinfo *pi) +{ + if (!pi->status_valid || !pi->gregs_valid) + if (!proc_get_status (pi)) + return NULL; + + /* + * OK, sorry about the ifdef's. + * There's three cases instead of two, because + * in this instance Unixware and Solaris/RW differ. + */ + +#ifdef NEW_PROC_API +#ifdef UNIXWARE /* ugh, a true architecture dependency */ + return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs; +#else /* not Unixware */ + return &pi->prstatus.pr_lwp.pr_reg; +#endif /* Unixware */ +#else /* not NEW_PROC_API */ + return &pi->prstatus.pr_reg; +#endif /* NEW_PROC_API */ +} + +/* + * Function: proc_get_fpregs + * + * Get the floating point registers for the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +gdb_fpregset_t * +proc_get_fpregs (procinfo *pi) +{ +#ifdef NEW_PROC_API + if (!pi->status_valid || !pi->fpregs_valid) + if (!proc_get_status (pi)) + return NULL; + +#ifdef UNIXWARE /* a true architecture dependency */ + return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs; +#else + return &pi->prstatus.pr_lwp.pr_fpreg; +#endif /* Unixware */ + +#else /* not NEW_PROC_API */ + if (pi->fpregs_valid) + return &pi->fpregset; /* already got 'em */ + else + { + if (pi->ctl_fd == 0 && + open_procinfo_files (pi, FD_CTL) == 0) + { + return NULL; + } + else + { +#ifdef PIOCTGFPREG + struct { + long pr_count; + tid_t pr_error_thread; + tfpregset_t thread_1; + } thread_fpregs; + + thread_fpregs.pr_count = 1; + thread_fpregs.thread_1.tid = pi->tid; + + if (pi->tid == 0 && + ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0) + { + pi->fpregs_valid = 1; + return &pi->fpregset; /* got 'em now! */ + } + else if (pi->tid != 0 && + ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0) + { + memcpy (&pi->fpregset, &thread_fpregs.thread_1.pr_fpregs, + sizeof (pi->fpregset)); + pi->fpregs_valid = 1; + return &pi->fpregset; /* got 'em now! */ + } + else + { + return NULL; + } +#else + if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0) + { + pi->fpregs_valid = 1; + return &pi->fpregset; /* got 'em now! */ + } + else + { + return NULL; + } +#endif + } + } +#endif +} + +/* + * Function: proc_set_gregs + * + * Write the general registers back to the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_gregs (procinfo *pi) +{ + gdb_gregset_t *gregs; + int win; + + if ((gregs = proc_get_gregs (pi)) == NULL) + return 0; /* get_regs has already warned */ + + if (pi->ctl_fd == 0 && + open_procinfo_files (pi, FD_CTL) == 0) + { + return 0; + } + else + { +#ifdef NEW_PROC_API + struct { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char gregs[sizeof (gdb_gregset_t)]; + } arg; + + arg.cmd = PCSREG; + memcpy (&arg.gregs, gregs, sizeof (arg.gregs)); + win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); +#else + win = (ioctl (pi->ctl_fd, PIOCSREG, gregs) >= 0); +#endif + } + + /* Policy: writing the regs invalidates our cache. */ + pi->gregs_valid = 0; + return win; +} + +/* + * Function: proc_set_fpregs + * + * Modify the floating point register set of the process or LWP. + * Returns non-zero for success, zero for failure. + */ + +int +proc_set_fpregs (procinfo *pi) +{ + gdb_fpregset_t *fpregs; + int win; + + if ((fpregs = proc_get_fpregs (pi)) == NULL) + return 0; /* get_fpregs has already warned */ + + if (pi->ctl_fd == 0 && + open_procinfo_files (pi, FD_CTL) == 0) + { + return 0; + } + else + { +#ifdef NEW_PROC_API + struct { + procfs_ctl_t cmd; + /* Use char array to avoid alignment issues. */ + char fpregs[sizeof (gdb_fpregset_t)]; + } arg; + + arg.cmd = PCSFPREG; + memcpy (&arg.fpregs, fpregs, sizeof (arg.fpregs)); + win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); +#else +#ifdef PIOCTSFPREG + if (pi->tid == 0) + win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0); + else + { + struct { + long pr_count; + tid_t pr_error_thread; + tfpregset_t thread_1; + } thread_fpregs; + + thread_fpregs.pr_count = 1; + thread_fpregs.thread_1.tid = pi->tid; + memcpy (&thread_fpregs.thread_1.pr_fpregs, fpregs, + sizeof (*fpregs)); + win = (ioctl (pi->ctl_fd, PIOCTSFPREG, &thread_fpregs) >= 0); + } +#else + win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0); +#endif /* osf PIOCTSFPREG */ +#endif /* NEW_PROC_API */ + } + + /* Policy: writing the regs invalidates our cache. */ + pi->fpregs_valid = 0; + return win; +} + +/* + * Function: proc_kill + * + * Send a signal to the proc or lwp with the semantics of "kill()". + * Returns non-zero for success, zero for failure. + */ + +int +proc_kill (procinfo *pi, int signo) +{ + int win; + + /* + * We might conceivably apply this operation to an LWP, and + * the LWP's ctl file descriptor might not be open. + */ + + if (pi->ctl_fd == 0 && + open_procinfo_files (pi, FD_CTL) == 0) + { + return 0; + } + else + { +#ifdef NEW_PROC_API + procfs_ctl_t cmd[2]; + + cmd[0] = PCKILL; + cmd[1] = signo; + win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd)); +#else /* ioctl method */ + /* FIXME: do I need the Alpha OSF fixups present in + procfs.c/unconditionally_kill_inferior? Perhaps only for SIGKILL? */ + win = (ioctl (pi->ctl_fd, PIOCKILL, &signo) >= 0); +#endif + } + + return win; +} + +/* + * Function: proc_parent_pid + * + * Find the pid of the process that started this one. + * Returns the parent process pid, or zero. + */ + +int +proc_parent_pid (procinfo *pi) +{ + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; + + return pi->prstatus.pr_ppid; +} + + +/* Convert a target address (a.k.a. CORE_ADDR) into a host address + (a.k.a void pointer)! */ + +static void * +procfs_address_to_host_pointer (CORE_ADDR addr) +{ + void *ptr; + + gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr)); + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr); + return ptr; +} + +/* + * Function: proc_set_watchpoint + * + */ + +int +proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags) +{ +#if !defined (TARGET_HAS_HARDWARE_WATCHPOINTS) + return 0; +#else +/* Horrible hack! Detect Solaris 2.5, because this doesn't work on 2.5 */ +#if defined (PIOCOPENLWP) || defined (UNIXWARE) /* Solaris 2.5: bail out */ + return 0; +#else + struct { + procfs_ctl_t cmd; + char watch[sizeof (prwatch_t)]; + } arg; + prwatch_t *pwatch; + + pwatch = (prwatch_t *) &arg.watch; + /* NOTE: cagney/2003-02-01: Even more horrible hack. Need to + convert a target address into something that can be stored in a + native data structure. */ +#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */ + pwatch->pr_vaddr = (uintptr_t) procfs_address_to_host_pointer (addr); +#else + pwatch->pr_vaddr = (caddr_t) procfs_address_to_host_pointer (addr); +#endif + pwatch->pr_size = len; + pwatch->pr_wflags = wflags; +#if defined(NEW_PROC_API) && defined (PCWATCH) + arg.cmd = PCWATCH; + return (write (pi->ctl_fd, &arg, sizeof (arg)) == sizeof (arg)); +#else +#if defined (PIOCSWATCH) + return (ioctl (pi->ctl_fd, PIOCSWATCH, pwatch) >= 0); +#else + return 0; /* Fail */ +#endif +#endif +#endif +#endif +} + +#ifdef TM_I386SOL2_H /* Is it hokey to use this? */ + +#include + +/* + * Function: proc_get_LDT_entry + * + * Inputs: + * procinfo *pi; + * int key; + * + * The 'key' is actually the value of the lower 16 bits of + * the GS register for the LWP that we're interested in. + * + * Return: matching ssh struct (LDT entry). + */ + +struct ssd * +proc_get_LDT_entry (procinfo *pi, int key) +{ + static struct ssd *ldt_entry = NULL; +#ifdef NEW_PROC_API + char pathname[MAX_PROC_NAME_SIZE]; + struct cleanup *old_chain = NULL; + int fd; + + /* Allocate space for one LDT entry. + This alloc must persist, because we return a pointer to it. */ + if (ldt_entry == NULL) + ldt_entry = (struct ssd *) xmalloc (sizeof (struct ssd)); + + /* Open the file descriptor for the LDT table. */ + sprintf (pathname, "/proc/%d/ldt", pi->pid); + if ((fd = open_with_retry (pathname, O_RDONLY)) < 0) + { + proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__); + return NULL; + } + /* Make sure it gets closed again! */ + old_chain = make_cleanup_close (fd); + + /* Now 'read' thru the table, find a match and return it. */ + while (read (fd, ldt_entry, sizeof (struct ssd)) == sizeof (struct ssd)) + { + if (ldt_entry->sel == 0 && + ldt_entry->bo == 0 && + ldt_entry->acc1 == 0 && + ldt_entry->acc2 == 0) + break; /* end of table */ + /* If key matches, return this entry. */ + if (ldt_entry->sel == key) + return ldt_entry; + } + /* Loop ended, match not found. */ + return NULL; +#else + int nldt, i; + static int nalloc = 0; + + /* Get the number of LDT entries. */ + if (ioctl (pi->ctl_fd, PIOCNLDT, &nldt) < 0) + { + proc_warn (pi, "proc_get_LDT_entry (PIOCNLDT)", __LINE__); + return NULL; + } + + /* Allocate space for the number of LDT entries. */ + /* This alloc has to persist, 'cause we return a pointer to it. */ + if (nldt > nalloc) + { + ldt_entry = (struct ssd *) + xrealloc (ldt_entry, (nldt + 1) * sizeof (struct ssd)); + nalloc = nldt; + } + + /* Read the whole table in one gulp. */ + if (ioctl (pi->ctl_fd, PIOCLDT, ldt_entry) < 0) + { + proc_warn (pi, "proc_get_LDT_entry (PIOCLDT)", __LINE__); + return NULL; + } + + /* Search the table and return the (first) entry matching 'key'. */ + for (i = 0; i < nldt; i++) + if (ldt_entry[i].sel == key) + return &ldt_entry[i]; + + /* Loop ended, match not found. */ + return NULL; +#endif +} + +#endif /* TM_I386SOL2_H */ + +/* =============== END, non-thread part of /proc "MODULE" =============== */ + +/* =================== Thread "MODULE" =================== */ + +/* NOTE: you'll see more ifdefs and duplication of functions here, + since there is a different way to do threads on every OS. */ + +/* + * Function: proc_get_nthreads + * + * Return the number of threads for the process + */ + +#if defined (PIOCNTHR) && defined (PIOCTLIST) +/* + * OSF version + */ +int +proc_get_nthreads (procinfo *pi) +{ + int nthreads = 0; + + if (ioctl (pi->ctl_fd, PIOCNTHR, &nthreads) < 0) + proc_warn (pi, "procfs: PIOCNTHR failed", __LINE__); + + return nthreads; +} + +#else +#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */ +/* + * Solaris and Unixware version + */ +int +proc_get_nthreads (procinfo *pi) +{ + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; + + /* + * NEW_PROC_API: only works for the process procinfo, + * because the LWP procinfos do not get prstatus filled in. + */ +#ifdef NEW_PROC_API + if (pi->tid != 0) /* find the parent process procinfo */ + pi = find_procinfo_or_die (pi->pid, 0); +#endif + return pi->prstatus.pr_nlwp; +} + +#else +/* + * Default version + */ +int +proc_get_nthreads (procinfo *pi) +{ + return 0; +} +#endif +#endif + +/* + * Function: proc_get_current_thread (LWP version) + * + * Return the ID of the thread that had an event of interest. + * (ie. the one that hit a breakpoint or other traced event). + * All other things being equal, this should be the ID of a + * thread that is currently executing. + */ + +#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */ +/* + * Solaris and Unixware version + */ +int +proc_get_current_thread (procinfo *pi) +{ + /* + * Note: this should be applied to the root procinfo for the process, + * not to the procinfo for an LWP. If applied to the procinfo for + * an LWP, it will simply return that LWP's ID. In that case, + * find the parent process procinfo. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + if (!pi->status_valid) + if (!proc_get_status (pi)) + return 0; + +#ifdef NEW_PROC_API + return pi->prstatus.pr_lwp.pr_lwpid; +#else + return pi->prstatus.pr_who; +#endif +} + +#else +#if defined (PIOCNTHR) && defined (PIOCTLIST) +/* + * OSF version + */ +int +proc_get_current_thread (procinfo *pi) +{ +#if 0 /* FIXME: not ready for prime time? */ + return pi->prstatus.pr_tid; +#else + return 0; +#endif +} + +#else +/* + * Default version + */ +int +proc_get_current_thread (procinfo *pi) +{ + return 0; +} + +#endif +#endif + +/* + * Function: proc_update_threads + * + * Discover the IDs of all the threads within the process, and + * create a procinfo for each of them (chained to the parent). + * + * This unfortunately requires a different method on every OS. + * + * Return: non-zero for success, zero for failure. + */ + +int +proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore) +{ + if (thread && parent) /* sanity */ + { + thread->status_valid = 0; + if (!proc_get_status (thread)) + destroy_one_procinfo (&parent->thread_list, thread); + } + return 0; /* keep iterating */ +} + +#if defined (PIOCLSTATUS) +/* + * Solaris 2.5 (ioctl) version + */ +int +proc_update_threads (procinfo *pi) +{ + gdb_prstatus_t *prstatus; + struct cleanup *old_chain = NULL; + procinfo *thread; + int nlwp, i; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); + + if ((nlwp = proc_get_nthreads (pi)) <= 1) + return 1; /* Process is not multi-threaded; nothing to do. */ + + prstatus = xmalloc (sizeof (gdb_prstatus_t) * (nlwp + 1)); + + old_chain = make_cleanup (xfree, prstatus); + if (ioctl (pi->ctl_fd, PIOCLSTATUS, prstatus) < 0) + proc_error (pi, "update_threads (PIOCLSTATUS)", __LINE__); + + /* Skip element zero, which represents the process as a whole. */ + for (i = 1; i < nlwp + 1; i++) + { + if ((thread = create_procinfo (pi->pid, prstatus[i].pr_who)) == NULL) + proc_error (pi, "update_threads, create_procinfo", __LINE__); + + memcpy (&thread->prstatus, &prstatus[i], sizeof (*prstatus)); + thread->status_valid = 1; + } + pi->threads_valid = 1; + do_cleanups (old_chain); + return 1; +} +#else +#ifdef NEW_PROC_API +/* + * Unixware and Solaris 6 (and later) version + */ +static void +do_closedir_cleanup (void *dir) +{ + closedir (dir); +} + +int +proc_update_threads (procinfo *pi) +{ + char pathname[MAX_PROC_NAME_SIZE + 16]; + struct dirent *direntry; + struct cleanup *old_chain = NULL; + procinfo *thread; + DIR *dirp; + int lwpid; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); + + /* + * Unixware + * + * Note: this brute-force method is the only way I know of + * to accomplish this task on Unixware. This method will + * also work on Solaris 2.6 and 2.7. There is a much simpler + * and more elegant way to do this on Solaris, but the margins + * of this manuscript are too small to write it here... ;-) + */ + + strcpy (pathname, pi->pathname); + strcat (pathname, "/lwp"); + if ((dirp = opendir (pathname)) == NULL) + proc_error (pi, "update_threads, opendir", __LINE__); + + old_chain = make_cleanup (do_closedir_cleanup, dirp); + while ((direntry = readdir (dirp)) != NULL) + if (direntry->d_name[0] != '.') /* skip '.' and '..' */ + { + lwpid = atoi (&direntry->d_name[0]); + if ((thread = create_procinfo (pi->pid, lwpid)) == NULL) + proc_error (pi, "update_threads, create_procinfo", __LINE__); + } + pi->threads_valid = 1; + do_cleanups (old_chain); + return 1; +} +#else +#ifdef PIOCTLIST +/* + * OSF version + */ +int +proc_update_threads (procinfo *pi) +{ + int nthreads, i; + tid_t *threads; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); + + nthreads = proc_get_nthreads (pi); + if (nthreads < 2) + return 0; /* nothing to do for 1 or fewer threads */ + + threads = xmalloc (nthreads * sizeof (tid_t)); + + if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0) + proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__); + + for (i = 0; i < nthreads; i++) + { + if (!find_procinfo (pi->pid, threads[i])) + if (!create_procinfo (pi->pid, threads[i])) + proc_error (pi, "update_threads, create_procinfo", __LINE__); + } + pi->threads_valid = 1; + return 1; +} +#else +/* + * Default version + */ +int +proc_update_threads (procinfo *pi) +{ + return 0; +} +#endif /* OSF PIOCTLIST */ +#endif /* NEW_PROC_API */ +#endif /* SOL 2.5 PIOCLSTATUS */ + +/* + * Function: proc_iterate_over_threads + * + * Description: + * Given a pointer to a function, call that function once + * for each lwp in the procinfo list, until the function + * returns non-zero, in which event return the value + * returned by the function. + * + * Note: this function does NOT call update_threads. + * If you want to discover new threads first, you must + * call that function explicitly. This function just makes + * a quick pass over the currently-known procinfos. + * + * Arguments: + * pi - parent process procinfo + * func - per-thread function + * ptr - opaque parameter for function. + * + * Return: + * First non-zero return value from the callee, or zero. + */ + +int +proc_iterate_over_threads (procinfo *pi, + int (*func) (procinfo *, procinfo *, void *), + void *ptr) +{ + procinfo *thread, *next; + int retval = 0; + + /* + * We should never have to apply this operation to any procinfo + * except the one for the main process. If that ever changes + * for any reason, then take out the following clause and + * replace it with one that makes sure the ctl_fd is open. + */ + + if (pi->tid != 0) + pi = find_procinfo_or_die (pi->pid, 0); + + for (thread = pi->thread_list; thread != NULL; thread = next) + { + next = thread->next; /* in case thread is destroyed */ + if ((retval = (*func) (pi, thread, ptr)) != 0) + break; + } + + return retval; +} + +/* =================== END, Thread "MODULE" =================== */ + +/* =================== END, /proc "MODULE" =================== */ + +/* =================== GDB "MODULE" =================== */ + +/* + * Here are all of the gdb target vector functions and their friends. + */ + +static ptid_t do_attach (ptid_t ptid); +static void do_detach (int signo); +static int register_gdb_signals (procinfo *, gdb_sigset_t *); + +/* + * Function: procfs_debug_inferior + * + * Sets up the inferior to be debugged. + * Registers to trace signals, hardware faults, and syscalls. + * Note: does not set RLC flag: caller may want to customize that. + * + * Returns: zero for success (note! unlike most functions in this module) + * On failure, returns the LINE NUMBER where it failed! + */ + +static int +procfs_debug_inferior (procinfo *pi) +{ + fltset_t traced_faults; + gdb_sigset_t traced_signals; + sysset_t *traced_syscall_entries; + sysset_t *traced_syscall_exits; + int status; + +#ifdef PROCFS_DONT_TRACE_FAULTS + /* On some systems (OSF), we don't trace hardware faults. + Apparently it's enough that we catch them as signals. + Wonder why we don't just do that in general? */ + premptyset (&traced_faults); /* don't trace faults. */ +#else + /* Register to trace hardware faults in the child. */ + prfillset (&traced_faults); /* trace all faults... */ + prdelset (&traced_faults, FLTPAGE); /* except page fault. */ +#endif + if (!proc_set_traced_faults (pi, &traced_faults)) + return __LINE__; + + /* Register to trace selected signals in the child. */ + premptyset (&traced_signals); + if (!register_gdb_signals (pi, &traced_signals)) + return __LINE__; + + + /* Register to trace the 'exit' system call (on entry). */ + traced_syscall_entries = sysset_t_alloc (pi); + gdb_premptysysset (traced_syscall_entries); +#ifdef SYS_exit + gdb_praddsysset (traced_syscall_entries, SYS_exit); +#endif +#ifdef SYS_lwpexit + gdb_praddsysset (traced_syscall_entries, SYS_lwpexit); /* And _lwp_exit... */ +#endif +#ifdef SYS_lwp_exit + gdb_praddsysset (traced_syscall_entries, SYS_lwp_exit); +#endif +#ifdef DYNAMIC_SYSCALLS + { + int callnum = find_syscall (pi, "_exit"); + if (callnum >= 0) + gdb_praddsysset (traced_syscall_entries, callnum); + } +#endif + + status = proc_set_traced_sysentry (pi, traced_syscall_entries); + xfree (traced_syscall_entries); + if (!status) + return __LINE__; + +#ifdef PRFS_STOPEXEC /* defined on OSF */ + /* OSF method for tracing exec syscalls. Quoting: + Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace + exits from exec system calls because of the user level loader. */ + /* FIXME: make nice and maybe move into an access function. */ + { + int prfs_flags; + + if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0) + return __LINE__; + + prfs_flags |= PRFS_STOPEXEC; + + if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0) + return __LINE__; + } +#else /* not PRFS_STOPEXEC */ + /* Everyone else's (except OSF) method for tracing exec syscalls */ + /* GW: Rationale... + Not all systems with /proc have all the exec* syscalls with the same + names. On the SGI, for example, there is no SYS_exec, but there + *is* a SYS_execv. So, we try to account for that. */ + + traced_syscall_exits = sysset_t_alloc (pi); + gdb_premptysysset (traced_syscall_exits); +#ifdef SYS_exec + gdb_praddsysset (traced_syscall_exits, SYS_exec); +#endif +#ifdef SYS_execve + gdb_praddsysset (traced_syscall_exits, SYS_execve); +#endif +#ifdef SYS_execv + gdb_praddsysset (traced_syscall_exits, SYS_execv); +#endif + +#ifdef SYS_lwpcreate + gdb_praddsysset (traced_syscall_exits, SYS_lwpcreate); + gdb_praddsysset (traced_syscall_exits, SYS_lwpexit); +#endif + +#ifdef SYS_lwp_create /* FIXME: once only, please */ + gdb_praddsysset (traced_syscall_exits, SYS_lwp_create); + gdb_praddsysset (traced_syscall_exits, SYS_lwp_exit); +#endif + +#ifdef DYNAMIC_SYSCALLS + { + int callnum = find_syscall (pi, "execve"); + if (callnum >= 0) + gdb_praddsysset (traced_syscall_exits, callnum); + callnum = find_syscall (pi, "ra_execve"); + if (callnum >= 0) + gdb_praddsysset (traced_syscall_exits, callnum); + } +#endif + + status = proc_set_traced_sysexit (pi, traced_syscall_exits); + xfree (traced_syscall_exits); + if (!status) + return __LINE__; + +#endif /* PRFS_STOPEXEC */ + return 0; +} + +static void +procfs_attach (char *args, int from_tty) +{ + char *exec_file; + int pid; + + if (!args) + error_no_arg ("process-id to attach"); + + pid = atoi (args); + if (pid == getpid ()) + error ("Attaching GDB to itself is not a good idea..."); + + if (from_tty) + { + exec_file = get_exec_file (0); + + if (exec_file) + printf_filtered ("Attaching to program `%s', %s\n", + exec_file, target_pid_to_str (pid_to_ptid (pid))); + else + printf_filtered ("Attaching to %s\n", + target_pid_to_str (pid_to_ptid (pid))); + + fflush (stdout); + } + inferior_ptid = do_attach (pid_to_ptid (pid)); + push_target (&procfs_ops); +} + +static void +procfs_detach (char *args, int from_tty) +{ + char *exec_file; + int signo = 0; + + if (from_tty) + { + exec_file = get_exec_file (0); + if (exec_file == 0) + exec_file = ""; + printf_filtered ("Detaching from program: %s %s\n", + exec_file, target_pid_to_str (inferior_ptid)); + fflush (stdout); + } + if (args) + signo = atoi (args); + + do_detach (signo); + inferior_ptid = null_ptid; + unpush_target (&procfs_ops); /* Pop out of handling an inferior */ +} + +static ptid_t +do_attach (ptid_t ptid) +{ + procinfo *pi; + int fail; + + if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL) + perror ("procfs: out of memory in 'attach'"); + + if (!open_procinfo_files (pi, FD_CTL)) + { + fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__); + sprintf (errmsg, "do_attach: couldn't open /proc file for process %d", + PIDGET (ptid)); + dead_procinfo (pi, errmsg, NOKILL); + } + + /* Stop the process (if it isn't already stopped). */ + if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) + { + pi->was_stopped = 1; + proc_prettyprint_why (proc_why (pi), proc_what (pi), 1); + } + else + { + pi->was_stopped = 0; + /* Set the process to run again when we close it. */ + if (!proc_set_run_on_last_close (pi)) + dead_procinfo (pi, "do_attach: couldn't set RLC.", NOKILL); + + /* Now stop the process. */ + if (!proc_stop_process (pi)) + dead_procinfo (pi, "do_attach: couldn't stop the process.", NOKILL); + pi->ignore_next_sigstop = 1; + } + /* Save some of the /proc state to be restored if we detach. */ + if (!proc_get_traced_faults (pi, &pi->saved_fltset)) + dead_procinfo (pi, "do_attach: couldn't save traced faults.", NOKILL); + if (!proc_get_traced_signals (pi, &pi->saved_sigset)) + dead_procinfo (pi, "do_attach: couldn't save traced signals.", NOKILL); + if (!proc_get_traced_sysentry (pi, pi->saved_entryset)) + dead_procinfo (pi, "do_attach: couldn't save traced syscall entries.", + NOKILL); + if (!proc_get_traced_sysexit (pi, pi->saved_exitset)) + dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.", + NOKILL); + if (!proc_get_held_signals (pi, &pi->saved_sighold)) + dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL); + + if ((fail = procfs_debug_inferior (pi)) != 0) + dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL); + + /* Let GDB know that the inferior was attached. */ + attach_flag = 1; + return MERGEPID (pi->pid, proc_get_current_thread (pi)); +} + +static void +do_detach (int signo) +{ + procinfo *pi; + + /* Find procinfo for the main process */ + pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); /* FIXME: threads */ + if (signo) + if (!proc_set_current_signal (pi, signo)) + proc_warn (pi, "do_detach, set_current_signal", __LINE__); + + if (!proc_set_traced_signals (pi, &pi->saved_sigset)) + proc_warn (pi, "do_detach, set_traced_signal", __LINE__); + + if (!proc_set_traced_faults (pi, &pi->saved_fltset)) + proc_warn (pi, "do_detach, set_traced_faults", __LINE__); + + if (!proc_set_traced_sysentry (pi, pi->saved_entryset)) + proc_warn (pi, "do_detach, set_traced_sysentry", __LINE__); + + if (!proc_set_traced_sysexit (pi, pi->saved_exitset)) + proc_warn (pi, "do_detach, set_traced_sysexit", __LINE__); + + if (!proc_set_held_signals (pi, &pi->saved_sighold)) + proc_warn (pi, "do_detach, set_held_signals", __LINE__); + + if (signo || (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))) + if (signo || !(pi->was_stopped) || + query ("Was stopped when attached, make it runnable again? ")) + { + /* Clear any pending signal. */ + if (!proc_clear_current_fault (pi)) + proc_warn (pi, "do_detach, clear_current_fault", __LINE__); + + if (signo == 0 && !proc_clear_current_signal (pi)) + proc_warn (pi, "do_detach, clear_current_signal", __LINE__); + + if (!proc_set_run_on_last_close (pi)) + proc_warn (pi, "do_detach, set_rlc", __LINE__); + } + + attach_flag = 0; + destroy_procinfo (pi); +} + +/* + * fetch_registers + * + * Since the /proc interface cannot give us individual registers, + * we pay no attention to the (regno) argument, and just fetch them all. + * This results in the possibility that we will do unnecessarily many + * fetches, since we may be called repeatedly for individual registers. + * So we cache the results, and mark the cache invalid when the process + * is resumed. + */ + +static void +procfs_fetch_registers (int regno) +{ + gdb_fpregset_t *fpregs; + gdb_gregset_t *gregs; + procinfo *pi; + int pid; + int tid; + + pid = PIDGET (inferior_ptid); + tid = TIDGET (inferior_ptid); + + /* First look up procinfo for the main process. */ + pi = find_procinfo_or_die (pid, 0); + + /* If the event thread is not the same as GDB's requested thread + (ie. inferior_ptid), then look up procinfo for the requested + thread. */ + if ((tid != 0) && + (tid != proc_get_current_thread (pi))) + pi = find_procinfo_or_die (pid, tid); + + if (pi == NULL) + error ("procfs: fetch_registers failed to find procinfo for %s", + target_pid_to_str (inferior_ptid)); + + if ((gregs = proc_get_gregs (pi)) == NULL) + proc_error (pi, "fetch_registers, get_gregs", __LINE__); + + supply_gregset (gregs); + + if (FP0_REGNUM >= 0) /* need floating point? */ + { + if ((regno >= 0 && regno < FP0_REGNUM) + || regno == PC_REGNUM + || regno == DEPRECATED_FP_REGNUM + || regno == SP_REGNUM) + return; /* not a floating point register */ + + if ((fpregs = proc_get_fpregs (pi)) == NULL) + proc_error (pi, "fetch_registers, get_fpregs", __LINE__); + + supply_fpregset (fpregs); + } +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On + machines which store all the registers in one fell swoop, such as + /proc, this makes sure that registers contains all the registers + from the program being debugged. */ + +static void +procfs_prepare_to_store (void) +{ +#ifdef CHILD_PREPARE_TO_STORE + CHILD_PREPARE_TO_STORE (); +#endif +} + +/* + * store_registers + * + * Since the /proc interface will not read individual registers, + * we will cache these requests until the process is resumed, and + * only then write them back to the inferior process. + * + * FIXME: is that a really bad idea? Have to think about cases + * where writing one register might affect the value of others, etc. + */ + +static void +procfs_store_registers (int regno) +{ + gdb_fpregset_t *fpregs; + gdb_gregset_t *gregs; + procinfo *pi; + int pid; + int tid; + + pid = PIDGET (inferior_ptid); + tid = TIDGET (inferior_ptid); + + /* First find procinfo for main process */ + pi = find_procinfo_or_die (pid, 0); + + /* If current lwp for process is not the same as requested thread + (ie. inferior_ptid), then find procinfo for the requested thread. */ + + if ((tid != 0) && + (tid != proc_get_current_thread (pi))) + pi = find_procinfo_or_die (pid, tid); + + if (pi == NULL) + error ("procfs: store_registers: failed to find procinfo for %s", + target_pid_to_str (inferior_ptid)); + + if ((gregs = proc_get_gregs (pi)) == NULL) + proc_error (pi, "store_registers, get_gregs", __LINE__); + + fill_gregset (gregs, regno); + if (!proc_set_gregs (pi)) + proc_error (pi, "store_registers, set_gregs", __LINE__); + + if (FP0_REGNUM >= 0) /* need floating point? */ + { + if ((regno >= 0 && regno < FP0_REGNUM) + || regno == PC_REGNUM + || regno == DEPRECATED_FP_REGNUM + || regno == SP_REGNUM) + return; /* not a floating point register */ + + if ((fpregs = proc_get_fpregs (pi)) == NULL) + proc_error (pi, "store_registers, get_fpregs", __LINE__); + + fill_fpregset (fpregs, regno); + if (!proc_set_fpregs (pi)) + proc_error (pi, "store_registers, set_fpregs", __LINE__); + } +} + +static int +syscall_is_lwp_exit (procinfo *pi, int scall) +{ + +#ifdef SYS_lwp_exit + if (scall == SYS_lwp_exit) + return 1; +#endif +#ifdef SYS_lwpexit + if (scall == SYS_lwpexit) + return 1; +#endif + return 0; +} + +static int +syscall_is_exit (procinfo *pi, int scall) +{ +#ifdef SYS_exit + if (scall == SYS_exit) + return 1; +#endif +#ifdef DYNAMIC_SYSCALLS + if (find_syscall (pi, "_exit") == scall) + return 1; +#endif + return 0; +} + +static int +syscall_is_exec (procinfo *pi, int scall) +{ +#ifdef SYS_exec + if (scall == SYS_exec) + return 1; +#endif +#ifdef SYS_execv + if (scall == SYS_execv) + return 1; +#endif +#ifdef SYS_execve + if (scall == SYS_execve) + return 1; +#endif +#ifdef DYNAMIC_SYSCALLS + if (find_syscall (pi, "_execve")) + return 1; + if (find_syscall (pi, "ra_execve")) + return 1; +#endif + return 0; +} + +static int +syscall_is_lwp_create (procinfo *pi, int scall) +{ +#ifdef SYS_lwp_create + if (scall == SYS_lwp_create) + return 1; +#endif +#ifdef SYS_lwpcreate + if (scall == SYS_lwpcreate) + return 1; +#endif + return 0; +} + +/* + * Function: target_wait + * + * Retrieve the next stop event from the child process. + * If child has not stopped yet, wait for it to stop. + * Translate /proc eventcodes (or possibly wait eventcodes) + * into gdb internal event codes. + * + * Return: id of process (and possibly thread) that incurred the event. + * event codes are returned thru a pointer parameter. + */ + +static ptid_t +procfs_wait (ptid_t ptid, struct target_waitstatus *status) +{ + /* First cut: loosely based on original version 2.1 */ + procinfo *pi; + int wstat; + int temp_tid; + ptid_t retval, temp_ptid; + int why, what, flags; + int retry = 0; + +wait_again: + + retry++; + wstat = 0; + retval = pid_to_ptid (-1); + + /* Find procinfo for main process */ + pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + if (pi) + { + /* We must assume that the status is stale now... */ + pi->status_valid = 0; + pi->gregs_valid = 0; + pi->fpregs_valid = 0; + +#if 0 /* just try this out... */ + flags = proc_flags (pi); + why = proc_why (pi); + if ((flags & PR_STOPPED) && (why == PR_REQUESTED)) + pi->status_valid = 0; /* re-read again, IMMEDIATELY... */ +#endif + /* If child is not stopped, wait for it to stop. */ + if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) && + !proc_wait_for_stop (pi)) + { + /* wait_for_stop failed: has the child terminated? */ + if (errno == ENOENT) + { + int wait_retval; + + /* /proc file not found; presumably child has terminated. */ + wait_retval = wait (&wstat); /* "wait" for the child's exit */ + + if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */ + error ("procfs: couldn't stop process %d: wait returned %d\n", + PIDGET (inferior_ptid), wait_retval); + /* FIXME: might I not just use waitpid? + Or try find_procinfo to see if I know about this child? */ + retval = pid_to_ptid (wait_retval); + } + else if (errno == EINTR) + goto wait_again; + else + { + /* Unknown error from wait_for_stop. */ + proc_error (pi, "target_wait (wait_for_stop)", __LINE__); + } + } + else + { + /* This long block is reached if either: + a) the child was already stopped, or + b) we successfully waited for the child with wait_for_stop. + This block will analyze the /proc status, and translate it + into a waitstatus for GDB. + + If we actually had to call wait because the /proc file + is gone (child terminated), then we skip this block, + because we already have a waitstatus. */ + + flags = proc_flags (pi); + why = proc_why (pi); + what = proc_what (pi); + + if (flags & (PR_STOPPED | PR_ISTOP)) + { +#ifdef PR_ASYNC + /* If it's running async (for single_thread control), + set it back to normal again. */ + if (flags & PR_ASYNC) + if (!proc_unset_async (pi)) + proc_error (pi, "target_wait, unset_async", __LINE__); +#endif + + if (info_verbose) + proc_prettyprint_why (why, what, 1); + + /* The 'pid' we will return to GDB is composed of + the process ID plus the lwp ID. */ + retval = MERGEPID (pi->pid, proc_get_current_thread (pi)); + + switch (why) { + case PR_SIGNALLED: + wstat = (what << 8) | 0177; + break; + case PR_SYSENTRY: + if (syscall_is_lwp_exit (pi, what)) + { + printf_filtered ("[%s exited]\n", + target_pid_to_str (retval)); + delete_thread (retval); + status->kind = TARGET_WAITKIND_SPURIOUS; + return retval; + } + else if (syscall_is_exit (pi, what)) + { + /* Handle SYS_exit call only */ + /* Stopped at entry to SYS_exit. + Make it runnable, resume it, then use + the wait system call to get its exit code. + Proc_run_process always clears the current + fault and signal. + Then return its exit status. */ + pi->status_valid = 0; + wstat = 0; + /* FIXME: what we should do is return + TARGET_WAITKIND_SPURIOUS. */ + if (!proc_run_process (pi, 0, 0)) + proc_error (pi, "target_wait, run_process", __LINE__); + if (attach_flag) + { + /* Don't call wait: simulate waiting for exit, + return a "success" exit code. Bogus: what if + it returns something else? */ + wstat = 0; + retval = inferior_ptid; /* ? ? ? */ + } + else + { + int temp = wait (&wstat); + + /* FIXME: shouldn't I make sure I get the right + event from the right process? If (for + instance) I have killed an earlier inferior + process but failed to clean up after it + somehow, I could get its termination event + here. */ + + /* If wait returns -1, that's what we return to GDB. */ + if (temp < 0) + retval = pid_to_ptid (temp); + } + } + else + { + printf_filtered ("procfs: trapped on entry to "); + proc_prettyprint_syscall (proc_what (pi), 0); + printf_filtered ("\n"); +#ifndef PIOCSSPCACT + { + long i, nsysargs, *sysargs; + + if ((nsysargs = proc_nsysarg (pi)) > 0 && + (sysargs = proc_sysargs (pi)) != NULL) + { + printf_filtered ("%ld syscall arguments:\n", nsysargs); + for (i = 0; i < nsysargs; i++) + printf_filtered ("#%ld: 0x%08lx\n", + i, sysargs[i]); + } + + } +#endif + if (status) + { + /* How to exit gracefully, returning "unknown event" */ + status->kind = TARGET_WAITKIND_SPURIOUS; + return inferior_ptid; + } + else + { + /* How to keep going without returning to wfi: */ + target_resume (ptid, 0, TARGET_SIGNAL_0); + goto wait_again; + } + } + break; + case PR_SYSEXIT: + if (syscall_is_exec (pi, what)) + { + /* Hopefully this is our own "fork-child" execing + the real child. Hoax this event into a trap, and + GDB will see the child about to execute its start + address. */ + wstat = (SIGTRAP << 8) | 0177; + } + else if (syscall_is_lwp_create (pi, what)) + { + /* + * This syscall is somewhat like fork/exec. + * We will get the event twice: once for the parent LWP, + * and once for the child. We should already know about + * the parent LWP, but the child will be new to us. So, + * whenever we get this event, if it represents a new + * thread, simply add the thread to the list. + */ + + /* If not in procinfo list, add it. */ + temp_tid = proc_get_current_thread (pi); + if (!find_procinfo (pi->pid, temp_tid)) + create_procinfo (pi->pid, temp_tid); + + temp_ptid = MERGEPID (pi->pid, temp_tid); + /* If not in GDB's thread list, add it. */ + if (!in_thread_list (temp_ptid)) + { + printf_filtered ("[New %s]\n", + target_pid_to_str (temp_ptid)); + add_thread (temp_ptid); + } + /* Return to WFI, but tell it to immediately resume. */ + status->kind = TARGET_WAITKIND_SPURIOUS; + return inferior_ptid; + } + else if (syscall_is_lwp_exit (pi, what)) + { + printf_filtered ("[%s exited]\n", + target_pid_to_str (retval)); + delete_thread (retval); + status->kind = TARGET_WAITKIND_SPURIOUS; + return retval; + } + else if (0) + { + /* FIXME: Do we need to handle SYS_sproc, + SYS_fork, or SYS_vfork here? The old procfs + seemed to use this event to handle threads on + older (non-LWP) systems, where I'm assuming + that threads were actually separate processes. + Irix, maybe? Anyway, low priority for now. */ + } + else + { + printf_filtered ("procfs: trapped on exit from "); + proc_prettyprint_syscall (proc_what (pi), 0); + printf_filtered ("\n"); +#ifndef PIOCSSPCACT + { + long i, nsysargs, *sysargs; + + if ((nsysargs = proc_nsysarg (pi)) > 0 && + (sysargs = proc_sysargs (pi)) != NULL) + { + printf_filtered ("%ld syscall arguments:\n", nsysargs); + for (i = 0; i < nsysargs; i++) + printf_filtered ("#%ld: 0x%08lx\n", + i, sysargs[i]); + } + } +#endif + status->kind = TARGET_WAITKIND_SPURIOUS; + return inferior_ptid; + } + break; + case PR_REQUESTED: +#if 0 /* FIXME */ + wstat = (SIGSTOP << 8) | 0177; + break; +#else + if (retry < 5) + { + printf_filtered ("Retry #%d:\n", retry); + pi->status_valid = 0; + goto wait_again; + } + else + { + /* If not in procinfo list, add it. */ + temp_tid = proc_get_current_thread (pi); + if (!find_procinfo (pi->pid, temp_tid)) + create_procinfo (pi->pid, temp_tid); + + /* If not in GDB's thread list, add it. */ + temp_ptid = MERGEPID (pi->pid, temp_tid); + if (!in_thread_list (temp_ptid)) + { + printf_filtered ("[New %s]\n", + target_pid_to_str (temp_ptid)); + add_thread (temp_ptid); + } + + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = 0; + return retval; + } +#endif + case PR_JOBCONTROL: + wstat = (what << 8) | 0177; + break; + case PR_FAULTED: + switch (what) { +#ifdef FLTWATCH + case FLTWATCH: + wstat = (SIGTRAP << 8) | 0177; + break; +#endif +#ifdef FLTKWATCH + case FLTKWATCH: + wstat = (SIGTRAP << 8) | 0177; + break; +#endif + /* FIXME: use si_signo where possible. */ + case FLTPRIV: +#if (FLTILL != FLTPRIV) /* avoid "duplicate case" error */ + case FLTILL: +#endif + wstat = (SIGILL << 8) | 0177; + break; + case FLTBPT: +#if (FLTTRACE != FLTBPT) /* avoid "duplicate case" error */ + case FLTTRACE: +#endif + wstat = (SIGTRAP << 8) | 0177; + break; + case FLTSTACK: + case FLTACCESS: +#if (FLTBOUNDS != FLTSTACK) /* avoid "duplicate case" error */ + case FLTBOUNDS: +#endif + wstat = (SIGSEGV << 8) | 0177; + break; + case FLTIOVF: + case FLTIZDIV: +#if (FLTFPE != FLTIOVF) /* avoid "duplicate case" error */ + case FLTFPE: +#endif + wstat = (SIGFPE << 8) | 0177; + break; + case FLTPAGE: /* Recoverable page fault */ + default: /* FIXME: use si_signo if possible for fault */ + retval = pid_to_ptid (-1); + printf_filtered ("procfs:%d -- ", __LINE__); + printf_filtered ("child stopped for unknown reason:\n"); + proc_prettyprint_why (why, what, 1); + error ("... giving up..."); + break; + } + break; /* case PR_FAULTED: */ + default: /* switch (why) unmatched */ + printf_filtered ("procfs:%d -- ", __LINE__); + printf_filtered ("child stopped for unknown reason:\n"); + proc_prettyprint_why (why, what, 1); + error ("... giving up..."); + break; + } + /* + * Got this far without error: + * If retval isn't in the threads database, add it. + */ + if (PIDGET (retval) > 0 && + !ptid_equal (retval, inferior_ptid) && + !in_thread_list (retval)) + { + /* + * We have a new thread. + * We need to add it both to GDB's list and to our own. + * If we don't create a procinfo, resume may be unhappy + * later. + */ + printf_filtered ("[New %s]\n", target_pid_to_str (retval)); + add_thread (retval); + if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL) + create_procinfo (PIDGET (retval), TIDGET (retval)); + + /* In addition, it's possible that this is the first + * new thread we've seen, in which case we may not + * have created entries for inferior_ptid yet. + */ + if (TIDGET (inferior_ptid) != 0) + { + if (!in_thread_list (inferior_ptid)) + add_thread (inferior_ptid); + if (find_procinfo (PIDGET (inferior_ptid), + TIDGET (inferior_ptid)) == NULL) + create_procinfo (PIDGET (inferior_ptid), + TIDGET (inferior_ptid)); + } + } + } + else /* flags do not indicate STOPPED */ + { + /* surely this can't happen... */ + printf_filtered ("procfs:%d -- process not stopped.\n", + __LINE__); + proc_prettyprint_flags (flags, 1); + error ("procfs: ...giving up..."); + } + } + + if (status) + store_waitstatus (status, wstat); + } + + return retval; +} + +/* Perform a partial transfer to/from the specified object. For + memory transfers, fall back to the old memory xfer functions. */ + +static LONGEST +procfs_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + switch (object) + { + case TARGET_OBJECT_MEMORY: + if (readbuf) + return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*write*/, + NULL, ops); + if (writebuf) + return (*ops->to_xfer_memory) (offset, readbuf, len, 1/*write*/, + NULL, ops); + return -1; + +#ifdef NEW_PROC_API + case TARGET_OBJECT_AUXV: + return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf, + offset, len); +#endif + + default: + if (ops->beneath != NULL) + return ops->beneath->to_xfer_partial (ops->beneath, object, annex, + readbuf, writebuf, offset, len); + return -1; + } +} + + +/* Transfer LEN bytes between GDB address MYADDR and target address + MEMADDR. If DOWRITE is non-zero, transfer them to the target, + otherwise transfer them from the target. TARGET is unused. + + The return value is 0 if an error occurred or no bytes were + transferred. Otherwise, it will be a positive value which + indicates the number of bytes transferred between gdb and the + target. (Note that the interface also makes provisions for + negative values, but this capability isn't implemented here.) */ + +static int +procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite, + struct mem_attrib *attrib, struct target_ops *target) +{ + procinfo *pi; + int nbytes = 0; + + /* Find procinfo for main process */ + pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + if (pi->as_fd == 0 && + open_procinfo_files (pi, FD_AS) == 0) + { + proc_warn (pi, "xfer_memory, open_proc_files", __LINE__); + return 0; + } + + if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr) + { + if (dowrite) + { +#ifdef NEW_PROC_API + PROCFS_NOTE ("write memory: "); +#else + PROCFS_NOTE ("write memory: \n"); +#endif + nbytes = write (pi->as_fd, myaddr, len); + } + else + { + PROCFS_NOTE ("read memory: \n"); + nbytes = read (pi->as_fd, myaddr, len); + } + if (nbytes < 0) + { + nbytes = 0; + } + } + return nbytes; +} + +/* + * Function: invalidate_cache + * + * Called by target_resume before making child runnable. + * Mark cached registers and status's invalid. + * If there are "dirty" caches that need to be written back + * to the child process, do that. + * + * File descriptors are also cached. + * As they are a limited resource, we cannot hold onto them indefinitely. + * However, as they are expensive to open, we don't want to throw them + * away indescriminately either. As a compromise, we will keep the + * file descriptors for the parent process, but discard any file + * descriptors we may have accumulated for the threads. + * + * Return value: + * As this function is called by iterate_over_threads, it always + * returns zero (so that iterate_over_threads will keep iterating). + */ + + +static int +invalidate_cache (procinfo *parent, procinfo *pi, void *ptr) +{ + /* + * About to run the child; invalidate caches and do any other cleanup. + */ + +#if 0 + if (pi->gregs_dirty) + if (parent == NULL || + proc_get_current_thread (parent) != pi->tid) + if (!proc_set_gregs (pi)) /* flush gregs cache */ + proc_warn (pi, "target_resume, set_gregs", + __LINE__); + if (FP0_REGNUM >= 0) + if (pi->fpregs_dirty) + if (parent == NULL || + proc_get_current_thread (parent) != pi->tid) + if (!proc_set_fpregs (pi)) /* flush fpregs cache */ + proc_warn (pi, "target_resume, set_fpregs", + __LINE__); +#endif + + if (parent != NULL) + { + /* The presence of a parent indicates that this is an LWP. + Close any file descriptors that it might have open. + We don't do this to the master (parent) procinfo. */ + + close_procinfo_files (pi); + } + pi->gregs_valid = 0; + pi->fpregs_valid = 0; +#if 0 + pi->gregs_dirty = 0; + pi->fpregs_dirty = 0; +#endif + pi->status_valid = 0; + pi->threads_valid = 0; + + return 0; +} + +#if 0 +/* + * Function: make_signal_thread_runnable + * + * A callback function for iterate_over_threads. + * Find the asynchronous signal thread, and make it runnable. + * See if that helps matters any. + */ + +static int +make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr) +{ +#ifdef PR_ASLWP + if (proc_flags (pi) & PR_ASLWP) + { + if (!proc_run_process (pi, 0, -1)) + proc_error (pi, "make_signal_thread_runnable", __LINE__); + return 1; + } +#endif + return 0; +} +#endif + +/* + * Function: target_resume + * + * Make the child process runnable. Normally we will then call + * procfs_wait and wait for it to stop again (unles gdb is async). + * + * Arguments: + * step: if true, then arrange for the child to stop again + * after executing a single instruction. + * signo: if zero, then cancel any pending signal. + * If non-zero, then arrange for the indicated signal + * to be delivered to the child when it runs. + * pid: if -1, then allow any child thread to run. + * if non-zero, then allow only the indicated thread to run. + ******* (not implemented yet) + */ + +static void +procfs_resume (ptid_t ptid, int step, enum target_signal signo) +{ + procinfo *pi, *thread; + int native_signo; + + /* 2.1: + prrun.prflags |= PRSVADDR; + prrun.pr_vaddr = $PC; set resume address + prrun.prflags |= PRSTRACE; trace signals in pr_trace (all) + prrun.prflags |= PRSFAULT; trace faults in pr_fault (all but PAGE) + prrun.prflags |= PRCFAULT; clear current fault. + + PRSTRACE and PRSFAULT can be done by other means + (proc_trace_signals, proc_trace_faults) + PRSVADDR is unnecessary. + PRCFAULT may be replaced by a PIOCCFAULT call (proc_clear_current_fault) + This basically leaves PRSTEP and PRCSIG. + PRCSIG is like PIOCSSIG (proc_clear_current_signal). + So basically PR_STEP is the sole argument that must be passed + to proc_run_process (for use in the prrun struct by ioctl). */ + + /* Find procinfo for main process */ + pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + + /* First cut: ignore pid argument */ + errno = 0; + + /* Convert signal to host numbering. */ + if (signo == 0 || + (signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop)) + native_signo = 0; + else + native_signo = target_signal_to_host (signo); + + pi->ignore_next_sigstop = 0; + + /* Running the process voids all cached registers and status. */ + /* Void the threads' caches first */ + proc_iterate_over_threads (pi, invalidate_cache, NULL); + /* Void the process procinfo's caches. */ + invalidate_cache (NULL, pi, NULL); + + if (PIDGET (ptid) != -1) + { + /* Resume a specific thread, presumably suppressing the others. */ + thread = find_procinfo (PIDGET (ptid), TIDGET (ptid)); + if (thread != NULL) + { + if (thread->tid != 0) + { + /* We're to resume a specific thread, and not the others. + * Set the child process's PR_ASYNC flag. + */ +#ifdef PR_ASYNC + if (!proc_set_async (pi)) + proc_error (pi, "target_resume, set_async", __LINE__); +#endif +#if 0 + proc_iterate_over_threads (pi, + make_signal_thread_runnable, + NULL); +#endif + pi = thread; /* substitute the thread's procinfo for run */ + } + } + } + + if (!proc_run_process (pi, step, native_signo)) + { + if (errno == EBUSY) + warning ("resume: target already running. Pretend to resume, and hope for the best!\n"); + else + proc_error (pi, "target_resume", __LINE__); + } +} + +/* + * Function: register_gdb_signals + * + * Traverse the list of signals that GDB knows about + * (see "handle" command), and arrange for the target + * to be stopped or not, according to these settings. + * + * Returns non-zero for success, zero for failure. + */ + +static int +register_gdb_signals (procinfo *pi, gdb_sigset_t *signals) +{ + int signo; + + for (signo = 0; signo < NSIG; signo ++) + if (signal_stop_state (target_signal_from_host (signo)) == 0 && + signal_print_state (target_signal_from_host (signo)) == 0 && + signal_pass_state (target_signal_from_host (signo)) == 1) + prdelset (signals, signo); + else + praddset (signals, signo); + + return proc_set_traced_signals (pi, signals); +} + +/* + * Function: target_notice_signals + * + * Set up to trace signals in the child process. + */ + +static void +procfs_notice_signals (ptid_t ptid) +{ + gdb_sigset_t signals; + procinfo *pi = find_procinfo_or_die (PIDGET (ptid), 0); + + if (proc_get_traced_signals (pi, &signals) && + register_gdb_signals (pi, &signals)) + return; + else + proc_error (pi, "notice_signals", __LINE__); +} + +/* + * Function: target_files_info + * + * Print status information about the child process. + */ + +static void +procfs_files_info (struct target_ops *ignore) +{ + printf_filtered ("\tUsing the running image of %s %s via /proc.\n", + attach_flag? "attached": "child", + target_pid_to_str (inferior_ptid)); +} + +/* + * Function: target_open + * + * A dummy: you don't open procfs. + */ + +static void +procfs_open (char *args, int from_tty) +{ + error ("Use the \"run\" command to start a Unix child process."); +} + +/* + * Function: target_can_run + * + * This tells GDB that this target vector can be invoked + * for "run" or "attach". + */ + +int procfs_suppress_run = 0; /* Non-zero if procfs should pretend not to + be a runnable target. Used by targets + that can sit atop procfs, such as solaris + thread support. */ + + +static int +procfs_can_run (void) +{ + /* This variable is controlled by modules that sit atop procfs that + may layer their own process structure atop that provided here. + sol-thread.c does this because of the Solaris two-level thread + model. */ + + /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */ + + return !procfs_suppress_run; +} + +/* + * Function: target_stop + * + * Stop the child process asynchronously, as when the + * gdb user types control-c or presses a "stop" button. + * + * Works by sending kill(SIGINT) to the child's process group. + */ + +static void +procfs_stop (void) +{ + kill (-inferior_process_group, SIGINT); +} + +/* + * Function: unconditionally_kill_inferior + * + * Make it die. Wait for it to die. Clean up after it. + * Note: this should only be applied to the real process, + * not to an LWP, because of the check for parent-process. + * If we need this to work for an LWP, it needs some more logic. + */ + +static void +unconditionally_kill_inferior (procinfo *pi) +{ + int parent_pid; + + parent_pid = proc_parent_pid (pi); +#ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL + /* FIXME: use access functions */ + /* Alpha OSF/1-3.x procfs needs a clear of the current signal + before the PIOCKILL, otherwise it might generate a corrupted core + file for the inferior. */ + if (ioctl (pi->ctl_fd, PIOCSSIG, NULL) < 0) + { + printf_filtered ("unconditionally_kill: SSIG failed!\n"); + } +#endif +#ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL + /* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal + to kill the inferior, otherwise it might remain stopped with a + pending SIGKILL. + We do not check the result of the PIOCSSIG, the inferior might have + died already. */ + { + gdb_siginfo_t newsiginfo; + + memset ((char *) &newsiginfo, 0, sizeof (newsiginfo)); + newsiginfo.si_signo = SIGKILL; + newsiginfo.si_code = 0; + newsiginfo.si_errno = 0; + newsiginfo.si_pid = getpid (); + newsiginfo.si_uid = getuid (); + /* FIXME: use proc_set_current_signal */ + ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo); + } +#else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */ + if (!proc_kill (pi, SIGKILL)) + proc_error (pi, "unconditionally_kill, proc_kill", __LINE__); +#endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */ + destroy_procinfo (pi); + + /* If pi is GDB's child, wait for it to die. */ + if (parent_pid == getpid ()) + /* FIXME: should we use waitpid to make sure we get the right event? + Should we check the returned event? */ + { +#if 0 + int status, ret; + + ret = waitpid (pi->pid, &status, 0); +#else + wait (NULL); +#endif + } +} + +/* + * Function: target_kill_inferior + * + * We're done debugging it, and we want it to go away. + * Then we want GDB to forget all about it. + */ + +static void +procfs_kill_inferior (void) +{ + if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */ + { + /* Find procinfo for main process */ + procinfo *pi = find_procinfo (PIDGET (inferior_ptid), 0); + + if (pi) + unconditionally_kill_inferior (pi); + target_mourn_inferior (); + } +} + +/* + * Function: target_mourn_inferior + * + * Forget we ever debugged this thing! + */ + +static void +procfs_mourn_inferior (void) +{ + procinfo *pi; + + if (!ptid_equal (inferior_ptid, null_ptid)) + { + /* Find procinfo for main process */ + pi = find_procinfo (PIDGET (inferior_ptid), 0); + if (pi) + destroy_procinfo (pi); + } + unpush_target (&procfs_ops); + generic_mourn_inferior (); +} + +/* + * Function: init_inferior + * + * When GDB forks to create a runnable inferior process, + * this function is called on the parent side of the fork. + * It's job is to do whatever is necessary to make the child + * ready to be debugged, and then wait for the child to synchronize. + */ + +static void +procfs_init_inferior (int pid) +{ + procinfo *pi; + gdb_sigset_t signals; + int fail; + + /* This routine called on the parent side (GDB side) + after GDB forks the inferior. */ + + push_target (&procfs_ops); + + if ((pi = create_procinfo (pid, 0)) == NULL) + perror ("procfs: out of memory in 'init_inferior'"); + + if (!open_procinfo_files (pi, FD_CTL)) + proc_error (pi, "init_inferior, open_proc_files", __LINE__); + + /* + xmalloc // done + open_procinfo_files // done + link list // done + prfillset (trace) + procfs_notice_signals + prfillset (fault) + prdelset (FLTPAGE) + PIOCWSTOP + PIOCSFAULT + */ + + /* If not stopped yet, wait for it to stop. */ + if (!(proc_flags (pi) & PR_STOPPED) && + !(proc_wait_for_stop (pi))) + dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL); + + /* Save some of the /proc state to be restored if we detach. */ + /* FIXME: Why? In case another debugger was debugging it? + We're it's parent, for Ghu's sake! */ + if (!proc_get_traced_signals (pi, &pi->saved_sigset)) + proc_error (pi, "init_inferior, get_traced_signals", __LINE__); + if (!proc_get_held_signals (pi, &pi->saved_sighold)) + proc_error (pi, "init_inferior, get_held_signals", __LINE__); + if (!proc_get_traced_faults (pi, &pi->saved_fltset)) + proc_error (pi, "init_inferior, get_traced_faults", __LINE__); + if (!proc_get_traced_sysentry (pi, pi->saved_entryset)) + proc_error (pi, "init_inferior, get_traced_sysentry", __LINE__); + if (!proc_get_traced_sysexit (pi, pi->saved_exitset)) + proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__); + + /* Register to trace selected signals in the child. */ + prfillset (&signals); + if (!register_gdb_signals (pi, &signals)) + proc_error (pi, "init_inferior, register_signals", __LINE__); + + if ((fail = procfs_debug_inferior (pi)) != 0) + proc_error (pi, "init_inferior (procfs_debug_inferior)", fail); + + /* FIXME: logically, we should really be turning OFF run-on-last-close, + and possibly even turning ON kill-on-last-close at this point. But + I can't make that change without careful testing which I don't have + time to do right now... */ + /* Turn on run-on-last-close flag so that the child + will die if GDB goes away for some reason. */ + if (!proc_set_run_on_last_close (pi)) + proc_error (pi, "init_inferior, set_RLC", __LINE__); + + /* The 'process ID' we return to GDB is composed of + the actual process ID plus the lwp ID. */ + inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi)); + + /* Typically two, one trap to exec the shell, one to exec the + program being debugged. Defined by "inferior.h". */ + startup_inferior (START_INFERIOR_TRAPS_EXPECTED); +} + +/* + * Function: set_exec_trap + * + * When GDB forks to create a new process, this function is called + * on the child side of the fork before GDB exec's the user program. + * Its job is to make the child minimally debuggable, so that the + * parent GDB process can connect to the child and take over. + * This function should do only the minimum to make that possible, + * and to synchronize with the parent process. The parent process + * should take care of the details. + */ + +static void +procfs_set_exec_trap (void) +{ + /* This routine called on the child side (inferior side) + after GDB forks the inferior. It must use only local variables, + because it may be sharing data space with its parent. */ + + procinfo *pi; + sysset_t *exitset; + + if ((pi = create_procinfo (getpid (), 0)) == NULL) + perror_with_name ("procfs: create_procinfo failed in child."); + + if (open_procinfo_files (pi, FD_CTL) == 0) + { + proc_warn (pi, "set_exec_trap, open_proc_files", __LINE__); + gdb_flush (gdb_stderr); + /* no need to call "dead_procinfo", because we're going to exit. */ + _exit (127); + } + +#ifdef PRFS_STOPEXEC /* defined on OSF */ + /* OSF method for tracing exec syscalls. Quoting: + Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace + exits from exec system calls because of the user level loader. */ + /* FIXME: make nice and maybe move into an access function. */ + { + int prfs_flags; + + if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0) + { + proc_warn (pi, "set_exec_trap (PIOCGSPCACT)", __LINE__); + gdb_flush (gdb_stderr); + _exit (127); + } + prfs_flags |= PRFS_STOPEXEC; + + if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0) + { + proc_warn (pi, "set_exec_trap (PIOCSSPCACT)", __LINE__); + gdb_flush (gdb_stderr); + _exit (127); + } + } +#else /* not PRFS_STOPEXEC */ + /* Everyone else's (except OSF) method for tracing exec syscalls */ + /* GW: Rationale... + Not all systems with /proc have all the exec* syscalls with the same + names. On the SGI, for example, there is no SYS_exec, but there + *is* a SYS_execv. So, we try to account for that. */ + + exitset = sysset_t_alloc (pi); + gdb_premptysysset (exitset); +#ifdef SYS_exec + gdb_praddsysset (exitset, SYS_exec); +#endif +#ifdef SYS_execve + gdb_praddsysset (exitset, SYS_execve); +#endif +#ifdef SYS_execv + gdb_praddsysset (exitset, SYS_execv); +#endif +#ifdef DYNAMIC_SYSCALLS + { + int callnum = find_syscall (pi, "execve"); + + if (callnum >= 0) + gdb_praddsysset (exitset, callnum); + + callnum = find_syscall (pi, "ra_execve"); + if (callnum >= 0) + gdb_praddsysset (exitset, callnum); + } +#endif /* DYNAMIC_SYSCALLS */ + + if (!proc_set_traced_sysexit (pi, exitset)) + { + proc_warn (pi, "set_exec_trap, set_traced_sysexit", __LINE__); + gdb_flush (gdb_stderr); + _exit (127); + } +#endif /* PRFS_STOPEXEC */ + + /* FIXME: should this be done in the parent instead? */ + /* Turn off inherit on fork flag so that all grand-children + of gdb start with tracing flags cleared. */ + if (!proc_unset_inherit_on_fork (pi)) + proc_warn (pi, "set_exec_trap, unset_inherit", __LINE__); + + /* Turn off run on last close flag, so that the child process + cannot run away just because we close our handle on it. + We want it to wait for the parent to attach. */ + if (!proc_unset_run_on_last_close (pi)) + proc_warn (pi, "set_exec_trap, unset_RLC", __LINE__); + + /* FIXME: No need to destroy the procinfo -- + we have our own address space, and we're about to do an exec! */ + /*destroy_procinfo (pi);*/ +} + +/* + * Function: create_inferior + * + * This function is called BEFORE gdb forks the inferior process. + * Its only real responsibility is to set things up for the fork, + * and tell GDB which two functions to call after the fork (one + * for the parent, and one for the child). + * + * This function does a complicated search for a unix shell program, + * which it then uses to parse arguments and environment variables + * to be sent to the child. I wonder whether this code could not + * be abstracted out and shared with other unix targets such as + * infptrace? + */ + +static void +procfs_create_inferior (char *exec_file, char *allargs, char **env) +{ + char *shell_file = getenv ("SHELL"); + char *tryname; + if (shell_file != NULL && strchr (shell_file, '/') == NULL) + { + + /* We will be looking down the PATH to find shell_file. If we + just do this the normal way (via execlp, which operates by + attempting an exec for each element of the PATH until it + finds one which succeeds), then there will be an exec for + each failed attempt, each of which will cause a PR_SYSEXIT + stop, and we won't know how to distinguish the PR_SYSEXIT's + for these failed execs with the ones for successful execs + (whether the exec has succeeded is stored at that time in the + carry bit or some such architecture-specific and + non-ABI-specified place). + + So I can't think of anything better than to search the PATH + now. This has several disadvantages: (1) There is a race + condition; if we find a file now and it is deleted before we + exec it, we lose, even if the deletion leaves a valid file + further down in the PATH, (2) there is no way to know exactly + what an executable (in the sense of "capable of being + exec'd") file is. Using access() loses because it may lose + if the caller is the superuser; failing to use it loses if + there are ACLs or some such. */ + + char *p; + char *p1; + /* FIXME-maybe: might want "set path" command so user can change what + path is used from within GDB. */ + char *path = getenv ("PATH"); + int len; + struct stat statbuf; + + if (path == NULL) + path = "/bin:/usr/bin"; + + tryname = alloca (strlen (path) + strlen (shell_file) + 2); + for (p = path; p != NULL; p = p1 ? p1 + 1: NULL) + { + p1 = strchr (p, ':'); + if (p1 != NULL) + len = p1 - p; + else + len = strlen (p); + strncpy (tryname, p, len); + tryname[len] = '\0'; + strcat (tryname, "/"); + strcat (tryname, shell_file); + if (access (tryname, X_OK) < 0) + continue; + if (stat (tryname, &statbuf) < 0) + continue; + if (!S_ISREG (statbuf.st_mode)) + /* We certainly need to reject directories. I'm not quite + as sure about FIFOs, sockets, etc., but I kind of doubt + that people want to exec() these things. */ + continue; + break; + } + if (p == NULL) + /* Not found. This must be an error rather than merely passing + the file to execlp(), because execlp() would try all the + exec()s, causing GDB to get confused. */ + error ("procfs:%d -- Can't find shell %s in PATH", + __LINE__, shell_file); + + shell_file = tryname; + } + + fork_inferior (exec_file, allargs, env, procfs_set_exec_trap, + procfs_init_inferior, NULL, shell_file); + + /* We are at the first instruction we care about. */ + /* Pedal to the metal... */ + + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0); +} + +/* + * Function: notice_thread + * + * Callback for find_new_threads. + * Calls "add_thread". + */ + +static int +procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr) +{ + ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid); + + if (!in_thread_list (gdb_threadid)) + add_thread (gdb_threadid); + + return 0; +} + +/* + * Function: target_find_new_threads + * + * Query all the threads that the target knows about, + * and give them back to GDB to add to its list. + */ + +void +procfs_find_new_threads (void) +{ + procinfo *pi; + + /* Find procinfo for main process */ + pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + proc_update_threads (pi); + proc_iterate_over_threads (pi, procfs_notice_thread, NULL); +} + +/* + * Function: target_thread_alive + * + * Return true if the thread is still 'alive'. + * + * This guy doesn't really seem to be doing his job. + * Got to investigate how to tell when a thread is really gone. + */ + +static int +procfs_thread_alive (ptid_t ptid) +{ + int proc, thread; + procinfo *pi; + + proc = PIDGET (ptid); + thread = TIDGET (ptid); + /* If I don't know it, it ain't alive! */ + if ((pi = find_procinfo (proc, thread)) == NULL) + return 0; + + /* If I can't get its status, it ain't alive! + What's more, I need to forget about it! */ + if (!proc_get_status (pi)) + { + destroy_procinfo (pi); + return 0; + } + /* I couldn't have got its status if it weren't alive, so it's alive. */ + return 1; +} + +/* + * Function: target_pid_to_str + * + * Return a string to be used to identify the thread in + * the "info threads" display. + */ + +char * +procfs_pid_to_str (ptid_t ptid) +{ + static char buf[80]; + int proc, thread; + procinfo *pi; + + proc = PIDGET (ptid); + thread = TIDGET (ptid); + pi = find_procinfo (proc, thread); + + if (thread == 0) + sprintf (buf, "Process %d", proc); + else + sprintf (buf, "LWP %d", thread); + return &buf[0]; +} + +/* + * Function: procfs_set_watchpoint + * Insert a watchpoint + */ + +int +procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag, + int after) +{ +#ifndef UNIXWARE +#ifndef AIX5 + int pflags = 0; + procinfo *pi; + + pi = find_procinfo_or_die (PIDGET (ptid) == -1 ? + PIDGET (inferior_ptid) : PIDGET (ptid), 0); + + /* Translate from GDB's flags to /proc's */ + if (len > 0) /* len == 0 means delete watchpoint */ + { + switch (rwflag) { /* FIXME: need an enum! */ + case hw_write: /* default watchpoint (write) */ + pflags = WRITE_WATCHFLAG; + break; + case hw_read: /* read watchpoint */ + pflags = READ_WATCHFLAG; + break; + case hw_access: /* access watchpoint */ + pflags = READ_WATCHFLAG | WRITE_WATCHFLAG; + break; + case hw_execute: /* execution HW breakpoint */ + pflags = EXEC_WATCHFLAG; + break; + default: /* Something weird. Return error. */ + return -1; + } + if (after) /* Stop after r/w access is completed. */ + pflags |= AFTER_WATCHFLAG; + } + + if (!proc_set_watchpoint (pi, addr, len, pflags)) + { + if (errno == E2BIG) /* Typical error for no resources */ + return -1; /* fail */ + /* GDB may try to remove the same watchpoint twice. + If a remove request returns no match, don't error. */ + if (errno == ESRCH && len == 0) + return 0; /* ignore */ + proc_error (pi, "set_watchpoint", __LINE__); + } +#endif /* AIX5 */ +#endif /* UNIXWARE */ + return 0; +} + +/* Return non-zero if we can set a hardware watchpoint of type TYPE. TYPE + is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint, + or bp_hardware_watchpoint. CNT is the number of watchpoints used so + far. + + Note: procfs_can_use_hw_breakpoint() is not yet used by all + procfs.c targets due to the fact that some of them still define + TARGET_CAN_USE_HARDWARE_WATCHPOINT. */ + +static int +procfs_can_use_hw_breakpoint (int type, int cnt, int othertype) +{ +#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS + return 0; +#else + /* Due to the way that proc_set_watchpoint() is implemented, host + and target pointers must be of the same size. If they are not, + we can't use hardware watchpoints. This limitation is due to the + fact that proc_set_watchpoint() calls + procfs_address_to_host_pointer(); a close inspection of + procfs_address_to_host_pointer will reveal that an internal error + will be generated when the host and target pointer sizes are + different. */ + if (sizeof (void *) != TYPE_LENGTH (builtin_type_void_data_ptr)) + return 0; + + /* Other tests here??? */ + + return 1; +#endif +} + +/* + * Function: stopped_by_watchpoint + * + * Returns non-zero if process is stopped on a hardware watchpoint fault, + * else returns zero. + */ + +int +procfs_stopped_by_watchpoint (ptid_t ptid) +{ + procinfo *pi; + + pi = find_procinfo_or_die (PIDGET (ptid) == -1 ? + PIDGET (inferior_ptid) : PIDGET (ptid), 0); + + if (!pi) /* If no process, then not stopped by watchpoint! */ + return 0; + + if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) + { + if (proc_why (pi) == PR_FAULTED) + { +#ifdef FLTWATCH + if (proc_what (pi) == FLTWATCH) + return 1; +#endif +#ifdef FLTKWATCH + if (proc_what (pi) == FLTKWATCH) + return 1; +#endif + } + } + return 0; +} + +#ifdef TM_I386SOL2_H +/* + * Function: procfs_find_LDT_entry + * + * Input: + * ptid_t ptid; // The GDB-style pid-plus-LWP. + * + * Return: + * pointer to the corresponding LDT entry. + */ + +struct ssd * +procfs_find_LDT_entry (ptid_t ptid) +{ + gdb_gregset_t *gregs; + int key; + procinfo *pi; + + /* Find procinfo for the lwp. */ + if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL) + { + warning ("procfs_find_LDT_entry: could not find procinfo for %d:%d.", + PIDGET (ptid), TIDGET (ptid)); + return NULL; + } + /* get its general registers. */ + if ((gregs = proc_get_gregs (pi)) == NULL) + { + warning ("procfs_find_LDT_entry: could not read gregs for %d:%d.", + PIDGET (ptid), TIDGET (ptid)); + return NULL; + } + /* Now extract the GS register's lower 16 bits. */ + key = (*gregs)[GS] & 0xffff; + + /* Find the matching entry and return it. */ + return proc_get_LDT_entry (pi, key); +} +#endif /* TM_I386SOL2_H */ + +/* + * Memory Mappings Functions: + */ + +/* + * Function: iterate_over_mappings + * + * Call a callback function once for each mapping, passing it the mapping, + * an optional secondary callback function, and some optional opaque data. + * Quit and return the first non-zero value returned from the callback. + * + * Arguments: + * pi -- procinfo struct for the process to be mapped. + * func -- callback function to be called by this iterator. + * data -- optional opaque data to be passed to the callback function. + * child_func -- optional secondary function pointer to be passed + * to the child function. + * + * Return: First non-zero return value from the callback function, + * or zero. + */ + +static int +iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data, + int (*func) (struct prmap *map, + int (*child_func) (), + void *data)) +{ + char pathname[MAX_PROC_NAME_SIZE]; + struct prmap *prmaps; + struct prmap *prmap; + int funcstat; + int map_fd; + int nmap; +#ifdef NEW_PROC_API + struct stat sbuf; +#endif + + /* Get the number of mappings, allocate space, + and read the mappings into prmaps. */ +#ifdef NEW_PROC_API + /* Open map fd. */ + sprintf (pathname, "/proc/%d/map", pi->pid); + if ((map_fd = open (pathname, O_RDONLY)) < 0) + proc_error (pi, "iterate_over_mappings (open)", __LINE__); + + /* Make sure it gets closed again. */ + make_cleanup_close (map_fd); + + /* Use stat to determine the file size, and compute + the number of prmap_t objects it contains. */ + if (fstat (map_fd, &sbuf) != 0) + proc_error (pi, "iterate_over_mappings (fstat)", __LINE__); + + nmap = sbuf.st_size / sizeof (prmap_t); + prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps)); + if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps)) + != (nmap * sizeof (*prmaps))) + proc_error (pi, "iterate_over_mappings (read)", __LINE__); +#else + /* Use ioctl command PIOCNMAP to get number of mappings. */ + if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0) + proc_error (pi, "iterate_over_mappings (PIOCNMAP)", __LINE__); + + prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps)); + if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0) + proc_error (pi, "iterate_over_mappings (PIOCMAP)", __LINE__); +#endif + + for (prmap = prmaps; nmap > 0; prmap++, nmap--) + if ((funcstat = (*func) (prmap, child_func, data)) != 0) + return funcstat; + + return 0; +} + +/* + * Function: solib_mappings_callback + * + * Calls the supplied callback function once for each mapped address + * space in the process. The callback function receives an open + * file descriptor for the file corresponding to that mapped + * address space (if there is one), and the base address of the + * mapped space. Quit when the callback function returns a + * nonzero value, or at teh end of the mappings. + * + * Returns: the first non-zero return value of the callback function, + * or zero. + */ + +int solib_mappings_callback (struct prmap *map, + int (*func) (int, CORE_ADDR), + void *data) +{ + procinfo *pi = data; + int fd; + +#ifdef NEW_PROC_API + char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)]; + + if (map->pr_vaddr == 0 && map->pr_size == 0) + return -1; /* sanity */ + + if (map->pr_mapname[0] == 0) + { + fd = -1; /* no map file */ + } + else + { + sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname); + /* Note: caller's responsibility to close this fd! */ + fd = open_with_retry (name, O_RDONLY); + /* Note: we don't test the above call for failure; + we just pass the FD on as given. Sometimes there is + no file, so the open may return failure, but that's + not a problem. */ + } +#else + fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr); + /* Note: we don't test the above call for failure; + we just pass the FD on as given. Sometimes there is + no file, so the ioctl may return failure, but that's + not a problem. */ +#endif + return (*func) (fd, (CORE_ADDR) map->pr_vaddr); +} + +/* + * Function: proc_iterate_over_mappings + * + * Uses the unified "iterate_over_mappings" function + * to implement the exported interface to solib-svr4.c. + * + * Given a pointer to a function, call that function once for every + * mapped address space in the process. The callback function + * receives an open file descriptor for the file corresponding to + * that mapped address space (if there is one), and the base address + * of the mapped space. Quit when the callback function returns a + * nonzero value, or at teh end of the mappings. + * + * Returns: the first non-zero return value of the callback function, + * or zero. + */ + +int +proc_iterate_over_mappings (int (*func) (int, CORE_ADDR)) +{ + procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + + return iterate_over_mappings (pi, func, pi, solib_mappings_callback); +} + +/* + * Function: find_memory_regions_callback + * + * Implements the to_find_memory_regions method. + * Calls an external function for each memory region. + * External function will have the signiture: + * + * int callback (CORE_ADDR vaddr, + * unsigned long size, + * int read, int write, int execute, + * void *data); + * + * Returns the integer value returned by the callback. + */ + +static int +find_memory_regions_callback (struct prmap *map, + int (*func) (CORE_ADDR, + unsigned long, + int, int, int, + void *), + void *data) +{ + return (*func) ((CORE_ADDR) map->pr_vaddr, + map->pr_size, + (map->pr_mflags & MA_READ) != 0, + (map->pr_mflags & MA_WRITE) != 0, + (map->pr_mflags & MA_EXEC) != 0, + data); +} + +/* + * Function: proc_find_memory_regions + * + * External interface. Calls a callback function once for each + * mapped memory region in the child process, passing as arguments + * CORE_ADDR virtual_address, + * unsigned long size, + * int read, TRUE if region is readable by the child + * int write, TRUE if region is writable by the child + * int execute TRUE if region is executable by the child. + * + * Stops iterating and returns the first non-zero value + * returned by the callback. + */ + +static int +proc_find_memory_regions (int (*func) (CORE_ADDR, + unsigned long, + int, int, int, + void *), + void *data) +{ + procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + + return iterate_over_mappings (pi, func, data, + find_memory_regions_callback); +} + +/* + * Function: mappingflags + * + * Returns an ascii representation of a memory mapping's flags. + */ + +static char * +mappingflags (long flags) +{ + static char asciiflags[8]; + + strcpy (asciiflags, "-------"); +#if defined (MA_PHYS) + if (flags & MA_PHYS) + asciiflags[0] = 'd'; +#endif + if (flags & MA_STACK) + asciiflags[1] = 's'; + if (flags & MA_BREAK) + asciiflags[2] = 'b'; + if (flags & MA_SHARED) + asciiflags[3] = 's'; + if (flags & MA_READ) + asciiflags[4] = 'r'; + if (flags & MA_WRITE) + asciiflags[5] = 'w'; + if (flags & MA_EXEC) + asciiflags[6] = 'x'; + return (asciiflags); +} + +/* + * Function: info_mappings_callback + * + * Callback function, does the actual work for 'info proc mappings'. + */ + +static int +info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused) +{ + char *data_fmt_string; + + if (TARGET_ADDR_BIT == 32) + data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n"; + else + data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n"; + + printf_filtered (data_fmt_string, + (unsigned long) map->pr_vaddr, + (unsigned long) map->pr_vaddr + map->pr_size - 1, + map->pr_size, +#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */ + (unsigned int) map->pr_offset, +#else + map->pr_off, +#endif + mappingflags (map->pr_mflags)); + + return 0; +} + +/* + * Function: info_proc_mappings + * + * Implement the "info proc mappings" subcommand. + */ + +static void +info_proc_mappings (procinfo *pi, int summary) +{ + char *header_fmt_string; + + if (TARGET_PTR_BIT == 32) + header_fmt_string = "\t%10s %10s %10s %10s %7s\n"; + else + header_fmt_string = " %18s %18s %10s %10s %7s\n"; + + if (summary) + return; /* No output for summary mode. */ + + printf_filtered ("Mapped address spaces:\n\n"); + printf_filtered (header_fmt_string, + "Start Addr", + " End Addr", + " Size", + " Offset", + "Flags"); + + iterate_over_mappings (pi, NULL, NULL, info_mappings_callback); + printf_filtered ("\n"); +} + +/* + * Function: info_proc_cmd + * + * Implement the "info proc" command. + */ + +static void +info_proc_cmd (char *args, int from_tty) +{ + struct cleanup *old_chain; + procinfo *process = NULL; + procinfo *thread = NULL; + char **argv = NULL; + char *tmp = NULL; + int pid = 0; + int tid = 0; + int mappings = 0; + + old_chain = make_cleanup (null_cleanup, 0); + if (args) + { + if ((argv = buildargv (args)) == NULL) + nomem (0); + else + make_cleanup_freeargv (argv); + } + while (argv != NULL && *argv != NULL) + { + if (isdigit (argv[0][0])) + { + pid = strtoul (argv[0], &tmp, 10); + if (*tmp == '/') + tid = strtoul (++tmp, NULL, 10); + } + else if (argv[0][0] == '/') + { + tid = strtoul (argv[0] + 1, NULL, 10); + } + else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0) + { + mappings = 1; + } + else + { + /* [...] */ + } + argv++; + } + if (pid == 0) + pid = PIDGET (inferior_ptid); + if (pid == 0) + error ("No current process: you must name one."); + else + { + /* Have pid, will travel. + First see if it's a process we're already debugging. */ + process = find_procinfo (pid, 0); + if (process == NULL) + { + /* No. So open a procinfo for it, but + remember to close it again when finished. */ + process = create_procinfo (pid, 0); + make_cleanup (do_destroy_procinfo_cleanup, process); + if (!open_procinfo_files (process, FD_CTL)) + proc_error (process, "info proc, open_procinfo_files", __LINE__); + } + } + if (tid != 0) + thread = create_procinfo (pid, tid); + + if (process) + { + printf_filtered ("process %d flags:\n", process->pid); + proc_prettyprint_flags (proc_flags (process), 1); + if (proc_flags (process) & (PR_STOPPED | PR_ISTOP)) + proc_prettyprint_why (proc_why (process), proc_what (process), 1); + if (proc_get_nthreads (process) > 1) + printf_filtered ("Process has %d threads.\n", + proc_get_nthreads (process)); + } + if (thread) + { + printf_filtered ("thread %d flags:\n", thread->tid); + proc_prettyprint_flags (proc_flags (thread), 1); + if (proc_flags (thread) & (PR_STOPPED | PR_ISTOP)) + proc_prettyprint_why (proc_why (thread), proc_what (thread), 1); + } + + if (mappings) + { + info_proc_mappings (process, 0); + } + + do_cleanups (old_chain); +} + +static void +proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode) +{ + procinfo *pi; + sysset_t *sysset; + int syscallnum = 0; + + if (PIDGET (inferior_ptid) <= 0) + error ("you must be debugging a process to use this command."); + + if (args == NULL || args[0] == 0) + error_no_arg ("system call to trace"); + + pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + if (isdigit (args[0])) + { + syscallnum = atoi (args); + if (entry_or_exit == PR_SYSENTRY) + sysset = proc_get_traced_sysentry (pi, NULL); + else + sysset = proc_get_traced_sysexit (pi, NULL); + + if (sysset == NULL) + proc_error (pi, "proc-trace, get_traced_sysset", __LINE__); + + if (mode == FLAG_SET) + gdb_praddsysset (sysset, syscallnum); + else + gdb_prdelsysset (sysset, syscallnum); + + if (entry_or_exit == PR_SYSENTRY) + { + if (!proc_set_traced_sysentry (pi, sysset)) + proc_error (pi, "proc-trace, set_traced_sysentry", __LINE__); + } + else + { + if (!proc_set_traced_sysexit (pi, sysset)) + proc_error (pi, "proc-trace, set_traced_sysexit", __LINE__); + } + } +} + +static void +proc_trace_sysentry_cmd (char *args, int from_tty) +{ + proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET); +} + +static void +proc_trace_sysexit_cmd (char *args, int from_tty) +{ + proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET); +} + +static void +proc_untrace_sysentry_cmd (char *args, int from_tty) +{ + proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET); +} + +static void +proc_untrace_sysexit_cmd (char *args, int from_tty) +{ + proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET); +} + + +void +_initialize_procfs (void) +{ + init_procfs_ops (); + add_target (&procfs_ops); + add_info ("proc", info_proc_cmd, + "Show /proc process information about any running process.\n\ +Specify process id, or use the program being debugged by default.\n\ +Specify keyword 'mappings' for detailed info on memory mappings."); + add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd, + "Give a trace of entries into the syscall."); + add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd, + "Give a trace of exits from the syscall."); + add_com ("proc-untrace-entry", no_class, proc_untrace_sysentry_cmd, + "Cancel a trace of entries into the syscall."); + add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd, + "Cancel a trace of exits from the syscall."); +} + +/* =================== END, GDB "MODULE" =================== */ + + + +/* miscellaneous stubs: */ +/* The following satisfy a few random symbols mostly created by */ +/* the solaris threads implementation, which I will chase down */ +/* later. */ + +/* + * Return a pid for which we guarantee + * we will be able to find a 'live' procinfo. + */ + +ptid_t +procfs_first_available (void) +{ + return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1); +} + +/* =================== GCORE .NOTE "MODULE" =================== */ +#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT) +/* gcore only implemented on solaris and unixware (so far) */ + +static char * +procfs_do_thread_registers (bfd *obfd, ptid_t ptid, + char *note_data, int *note_size) +{ + gdb_gregset_t gregs; + gdb_fpregset_t fpregs; + unsigned long merged_pid; + + merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid); + + fill_gregset (&gregs, -1); +#if defined (UNIXWARE) + note_data = (char *) elfcore_write_lwpstatus (obfd, + note_data, + note_size, + merged_pid, + stop_signal, + &gregs); +#else + note_data = (char *) elfcore_write_prstatus (obfd, + note_data, + note_size, + merged_pid, + stop_signal, + &gregs); +#endif + fill_fpregset (&fpregs, -1); + note_data = (char *) elfcore_write_prfpreg (obfd, + note_data, + note_size, + &fpregs, + sizeof (fpregs)); + return note_data; +} + +struct procfs_corefile_thread_data { + bfd *obfd; + char *note_data; + int *note_size; +}; + +static int +procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data) +{ + struct procfs_corefile_thread_data *args = data; + + if (pi != NULL && thread->tid != 0) + { + ptid_t saved_ptid = inferior_ptid; + inferior_ptid = MERGEPID (pi->pid, thread->tid); + args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid, + args->note_data, + args->note_size); + inferior_ptid = saved_ptid; + } + return 0; +} + +static char * +procfs_make_note_section (bfd *obfd, int *note_size) +{ + struct cleanup *old_chain; + gdb_gregset_t gregs; + gdb_fpregset_t fpregs; + char fname[16] = {'\0'}; + char psargs[80] = {'\0'}; + procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); + char *note_data = NULL; + char *inf_args; + struct procfs_corefile_thread_data thread_args; + char *auxv; + int auxv_len; + + if (get_exec_file (0)) + { + strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname)); + strncpy (psargs, get_exec_file (0), + sizeof (psargs)); + + inf_args = get_inferior_args (); + if (inf_args && *inf_args && + strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs))) + { + strncat (psargs, " ", + sizeof (psargs) - strlen (psargs)); + strncat (psargs, inf_args, + sizeof (psargs) - strlen (psargs)); + } + } + + note_data = (char *) elfcore_write_prpsinfo (obfd, + note_data, + note_size, + fname, + psargs); + +#ifdef UNIXWARE + fill_gregset (&gregs, -1); + note_data = elfcore_write_pstatus (obfd, note_data, note_size, + PIDGET (inferior_ptid), + stop_signal, &gregs); +#endif + + thread_args.obfd = obfd; + thread_args.note_data = note_data; + thread_args.note_size = note_size; + proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args); + + if (thread_args.note_data == note_data) + { + /* iterate_over_threads didn't come up with any threads; + just use inferior_ptid. */ + note_data = procfs_do_thread_registers (obfd, inferior_ptid, + note_data, note_size); + } + else + { + note_data = thread_args.note_data; + } + + auxv_len = target_auxv_read (¤t_target, &auxv); + if (auxv_len > 0) + { + note_data = elfcore_write_note (obfd, note_data, note_size, + "CORE", NT_AUXV, auxv, auxv_len); + xfree (auxv); + } + + make_cleanup (xfree, note_data); + return note_data; +} +#else /* !(Solaris or Unixware) */ +static char * +procfs_make_note_section (bfd *obfd, int *note_size) +{ + error ("gcore not implemented for this host."); + return NULL; /* lint */ +} +#endif /* Solaris or Unixware */ +/* =================== END GCORE .NOTE "MODULE" =================== */ diff --git a/contrib/gdb/gdb/regcache.c b/contrib/gdb/gdb/regcache.c index 28859045e5f..154fc5e0c71 100644 --- a/contrib/gdb/gdb/regcache.c +++ b/contrib/gdb/gdb/regcache.c @@ -1,6 +1,7 @@ /* Cache and manage the values of registers for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, + 2001, 2002, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -25,7 +26,10 @@ #include "gdbarch.h" #include "gdbcmd.h" #include "regcache.h" +#include "reggroups.h" #include "gdb_assert.h" +#include "gdb_string.h" +#include "gdbcmd.h" /* For maintenanceprintlist. */ /* * DATA STRUCTURE @@ -33,6 +37,474 @@ * Here is the actual register cache. */ +/* Per-architecture object describing the layout of a register cache. + Computed once when the architecture is created */ + +struct gdbarch_data *regcache_descr_handle; + +struct regcache_descr +{ + /* The architecture this descriptor belongs to. */ + struct gdbarch *gdbarch; + + /* Is this a ``legacy'' register cache? Such caches reserve space + for raw and pseudo registers and allow access to both. */ + int legacy_p; + + /* The raw register cache. Each raw (or hard) register is supplied + by the target interface. The raw cache should not contain + redundant information - if the PC is constructed from two + registers then those regigisters and not the PC lives in the raw + cache. */ + int nr_raw_registers; + long sizeof_raw_registers; + long sizeof_raw_register_valid_p; + + /* The cooked register space. Each cooked register in the range + [0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw + register. The remaining [NR_RAW_REGISTERS + .. NR_COOKED_REGISTERS) (a.k.a. pseudo regiters) are mapped onto + both raw registers and memory by the architecture methods + gdbarch_register_read and gdbarch_register_write. */ + int nr_cooked_registers; + long sizeof_cooked_registers; + long sizeof_cooked_register_valid_p; + + /* Offset and size (in 8 bit bytes), of reach register in the + register cache. All registers (including those in the range + [NR_RAW_REGISTERS .. NR_COOKED_REGISTERS) are given an offset. + Assigning all registers an offset makes it possible to keep + legacy code, such as that found in read_register_bytes() and + write_register_bytes() working. */ + long *register_offset; + long *sizeof_register; + + /* Cached table containing the type of each register. */ + struct type **register_type; +}; + +static void +init_legacy_regcache_descr (struct gdbarch *gdbarch, + struct regcache_descr *descr) +{ + int i; + /* FIXME: cagney/2002-05-11: gdbarch_data() should take that + ``gdbarch'' as a parameter. */ + gdb_assert (gdbarch != NULL); + + /* Compute the offset of each register. Legacy architectures define + DEPRECATED_REGISTER_BYTE() so use that. */ + /* FIXME: cagney/2002-11-07: Instead of using + DEPRECATED_REGISTER_BYTE() this code should, as is done in + init_regcache_descr(), compute the offets at runtime. This + currently isn't possible as some ISAs define overlapping register + regions - see the mess in read_register_bytes() and + write_register_bytes() registers. */ + descr->sizeof_register + = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long); + descr->register_offset + = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long); + for (i = 0; i < descr->nr_cooked_registers; i++) + { + /* FIXME: cagney/2001-12-04: This code shouldn't need to use + DEPRECATED_REGISTER_BYTE(). Unfortunately, legacy code likes + to lay the buffer out so that certain registers just happen + to overlap. Ulgh! New targets use gdbarch's register + read/write and entirely avoid this uglyness. */ + descr->register_offset[i] = DEPRECATED_REGISTER_BYTE (i); + descr->sizeof_register[i] = DEPRECATED_REGISTER_RAW_SIZE (i); + gdb_assert (MAX_REGISTER_SIZE >= DEPRECATED_REGISTER_RAW_SIZE (i)); + gdb_assert (MAX_REGISTER_SIZE >= DEPRECATED_REGISTER_VIRTUAL_SIZE (i)); + } + + /* Compute the real size of the register buffer. Start out by + trusting DEPRECATED_REGISTER_BYTES, but then adjust it upwards + should that be found to not be sufficient. */ + /* FIXME: cagney/2002-11-05: Instead of using the macro + DEPRECATED_REGISTER_BYTES, this code should, as is done in + init_regcache_descr(), compute the total number of register bytes + using the accumulated offsets. */ + descr->sizeof_cooked_registers = DEPRECATED_REGISTER_BYTES; /* OK */ + for (i = 0; i < descr->nr_cooked_registers; i++) + { + long regend; + /* Keep extending the buffer so that there is always enough + space for all registers. The comparison is necessary since + legacy code is free to put registers in random places in the + buffer separated by holes. Once DEPRECATED_REGISTER_BYTE() + is killed this can be greatly simplified. */ + regend = descr->register_offset[i] + descr->sizeof_register[i]; + if (descr->sizeof_cooked_registers < regend) + descr->sizeof_cooked_registers = regend; + } + /* FIXME: cagney/2002-05-11: Shouldn't be including pseudo-registers + in the register cache. Unfortunately some architectures still + rely on this and the pseudo_register_write() method. */ + descr->sizeof_raw_registers = descr->sizeof_cooked_registers; +} + +static void * +init_regcache_descr (struct gdbarch *gdbarch) +{ + int i; + struct regcache_descr *descr; + gdb_assert (gdbarch != NULL); + + /* Create an initial, zero filled, table. */ + descr = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct regcache_descr); + descr->gdbarch = gdbarch; + + /* Total size of the register space. The raw registers are mapped + directly onto the raw register cache while the pseudo's are + either mapped onto raw-registers or memory. */ + descr->nr_cooked_registers = NUM_REGS + NUM_PSEUDO_REGS; + descr->sizeof_cooked_register_valid_p = NUM_REGS + NUM_PSEUDO_REGS; + + /* Fill in a table of register types. */ + descr->register_type + = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, struct type *); + for (i = 0; i < descr->nr_cooked_registers; i++) + { + if (gdbarch_register_type_p (gdbarch)) + { + gdb_assert (!DEPRECATED_REGISTER_VIRTUAL_TYPE_P ()); /* OK */ + descr->register_type[i] = gdbarch_register_type (gdbarch, i); + } + else + descr->register_type[i] = DEPRECATED_REGISTER_VIRTUAL_TYPE (i); /* OK */ + } + + /* Construct a strictly RAW register cache. Don't allow pseudo's + into the register cache. */ + descr->nr_raw_registers = NUM_REGS; + + /* FIXME: cagney/2002-08-13: Overallocate the register_valid_p + array. This pretects GDB from erant code that accesses elements + of the global register_valid_p[] array in the range [NUM_REGS + .. NUM_REGS + NUM_PSEUDO_REGS). */ + descr->sizeof_raw_register_valid_p = descr->sizeof_cooked_register_valid_p; + + /* If an old style architecture, fill in the remainder of the + register cache descriptor using the register macros. */ + /* NOTE: cagney/2003-06-29: If either of DEPRECATED_REGISTER_BYTE or + DEPRECATED_REGISTER_RAW_SIZE are still present, things are most likely + totally screwed. Ex: an architecture with raw register sizes + smaller than what DEPRECATED_REGISTER_BYTE indicates; non + monotonic DEPRECATED_REGISTER_BYTE values. For GDB 6 check for + these nasty methods and fall back to legacy code when present. + Sigh! */ + if ((!gdbarch_pseudo_register_read_p (gdbarch) + && !gdbarch_pseudo_register_write_p (gdbarch) + && !gdbarch_register_type_p (gdbarch)) + || DEPRECATED_REGISTER_BYTE_P () + || DEPRECATED_REGISTER_RAW_SIZE_P ()) + { + descr->legacy_p = 1; + init_legacy_regcache_descr (gdbarch, descr); + return descr; + } + + /* Lay out the register cache. + + NOTE: cagney/2002-05-22: Only register_type() is used when + constructing the register cache. It is assumed that the + register's raw size, virtual size and type length are all the + same. */ + + { + long offset = 0; + descr->sizeof_register + = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long); + descr->register_offset + = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long); + for (i = 0; i < descr->nr_cooked_registers; i++) + { + descr->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]); + descr->register_offset[i] = offset; + offset += descr->sizeof_register[i]; + gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]); + } + /* Set the real size of the register cache buffer. */ + descr->sizeof_cooked_registers = offset; + } + + /* FIXME: cagney/2002-05-22: Should only need to allocate space for + the raw registers. Unfortunately some code still accesses the + register array directly using the global registers[]. Until that + code has been purged, play safe and over allocating the register + buffer. Ulgh! */ + descr->sizeof_raw_registers = descr->sizeof_cooked_registers; + + /* Sanity check. Confirm that there is agreement between the + regcache and the target's redundant DEPRECATED_REGISTER_BYTE (new + targets should not even be defining it). */ + for (i = 0; i < descr->nr_cooked_registers; i++) + { + if (DEPRECATED_REGISTER_BYTE_P ()) + gdb_assert (descr->register_offset[i] == DEPRECATED_REGISTER_BYTE (i)); +#if 0 + gdb_assert (descr->sizeof_register[i] == DEPRECATED_REGISTER_RAW_SIZE (i)); + gdb_assert (descr->sizeof_register[i] == DEPRECATED_REGISTER_VIRTUAL_SIZE (i)); +#endif + } + /* gdb_assert (descr->sizeof_raw_registers == DEPRECATED_REGISTER_BYTES (i)); */ + + return descr; +} + +static struct regcache_descr * +regcache_descr (struct gdbarch *gdbarch) +{ + return gdbarch_data (gdbarch, regcache_descr_handle); +} + +/* Utility functions returning useful register attributes stored in + the regcache descr. */ + +struct type * +register_type (struct gdbarch *gdbarch, int regnum) +{ + struct regcache_descr *descr = regcache_descr (gdbarch); + gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers); + return descr->register_type[regnum]; +} + +/* Utility functions returning useful register attributes stored in + the regcache descr. */ + +int +register_size (struct gdbarch *gdbarch, int regnum) +{ + struct regcache_descr *descr = regcache_descr (gdbarch); + int size; + gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS)); + size = descr->sizeof_register[regnum]; + /* NB: The deprecated DEPRECATED_REGISTER_RAW_SIZE, if not provided, defaults + to the size of the register's type. */ + gdb_assert (size == DEPRECATED_REGISTER_RAW_SIZE (regnum)); /* OK */ + /* NB: Don't check the register's virtual size. It, in say the case + of the MIPS, may not match the raw size! */ + return size; +} + +/* The register cache for storing raw register values. */ + +struct regcache +{ + struct regcache_descr *descr; + /* The register buffers. A read-only register cache can hold the + full [0 .. NUM_REGS + NUM_PSEUDO_REGS) while a read/write + register cache can only hold [0 .. NUM_REGS). */ + char *registers; + char *register_valid_p; + /* Is this a read-only cache? A read-only cache is used for saving + the target's register state (e.g, across an inferior function + call or just before forcing a function return). A read-only + cache can only be updated via the methods regcache_dup() and + regcache_cpy(). The actual contents are determined by the + reggroup_save and reggroup_restore methods. */ + int readonly_p; +}; + +struct regcache * +regcache_xmalloc (struct gdbarch *gdbarch) +{ + struct regcache_descr *descr; + struct regcache *regcache; + gdb_assert (gdbarch != NULL); + descr = regcache_descr (gdbarch); + regcache = XMALLOC (struct regcache); + regcache->descr = descr; + regcache->registers + = XCALLOC (descr->sizeof_raw_registers, char); + regcache->register_valid_p + = XCALLOC (descr->sizeof_raw_register_valid_p, char); + regcache->readonly_p = 1; + return regcache; +} + +void +regcache_xfree (struct regcache *regcache) +{ + if (regcache == NULL) + return; + xfree (regcache->registers); + xfree (regcache->register_valid_p); + xfree (regcache); +} + +static void +do_regcache_xfree (void *data) +{ + regcache_xfree (data); +} + +struct cleanup * +make_cleanup_regcache_xfree (struct regcache *regcache) +{ + return make_cleanup (do_regcache_xfree, regcache); +} + +/* Return REGCACHE's architecture. */ + +struct gdbarch * +get_regcache_arch (const struct regcache *regcache) +{ + return regcache->descr->gdbarch; +} + +/* Return a pointer to register REGNUM's buffer cache. */ + +static char * +register_buffer (const struct regcache *regcache, int regnum) +{ + return regcache->registers + regcache->descr->register_offset[regnum]; +} + +void +regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read, + void *src) +{ + struct gdbarch *gdbarch = dst->descr->gdbarch; + char buf[MAX_REGISTER_SIZE]; + int regnum; + /* The DST should be `read-only', if it wasn't then the save would + end up trying to write the register values back out to the + target. */ + gdb_assert (dst->readonly_p); + /* Clear the dest. */ + memset (dst->registers, 0, dst->descr->sizeof_cooked_registers); + memset (dst->register_valid_p, 0, dst->descr->sizeof_cooked_register_valid_p); + /* Copy over any registers (identified by their membership in the + save_reggroup) and mark them as valid. The full [0 .. NUM_REGS + + NUM_PSEUDO_REGS) range is checked since some architectures need + to save/restore `cooked' registers that live in memory. */ + for (regnum = 0; regnum < dst->descr->nr_cooked_registers; regnum++) + { + if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup)) + { + int valid = cooked_read (src, regnum, buf); + if (valid) + { + memcpy (register_buffer (dst, regnum), buf, + register_size (gdbarch, regnum)); + dst->register_valid_p[regnum] = 1; + } + } + } +} + +void +regcache_restore (struct regcache *dst, + regcache_cooked_read_ftype *cooked_read, + void *src) +{ + struct gdbarch *gdbarch = dst->descr->gdbarch; + char buf[MAX_REGISTER_SIZE]; + int regnum; + /* The dst had better not be read-only. If it is, the `restore' + doesn't make much sense. */ + gdb_assert (!dst->readonly_p); + /* Copy over any registers, being careful to only restore those that + were both saved and need to be restored. The full [0 .. NUM_REGS + + NUM_PSEUDO_REGS) range is checked since some architectures need + to save/restore `cooked' registers that live in memory. */ + for (regnum = 0; regnum < dst->descr->nr_cooked_registers; regnum++) + { + if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup)) + { + int valid = cooked_read (src, regnum, buf); + if (valid) + regcache_cooked_write (dst, regnum, buf); + } + } +} + +static int +do_cooked_read (void *src, int regnum, void *buf) +{ + struct regcache *regcache = src; + if (!regcache->register_valid_p[regnum] && regcache->readonly_p) + /* Don't even think about fetching a register from a read-only + cache when the register isn't yet valid. There isn't a target + from which the register value can be fetched. */ + return 0; + regcache_cooked_read (regcache, regnum, buf); + return 1; +} + + +void +regcache_cpy (struct regcache *dst, struct regcache *src) +{ + int i; + char *buf; + gdb_assert (src != NULL && dst != NULL); + gdb_assert (src->descr->gdbarch == dst->descr->gdbarch); + gdb_assert (src != dst); + gdb_assert (src->readonly_p || dst->readonly_p); + if (!src->readonly_p) + regcache_save (dst, do_cooked_read, src); + else if (!dst->readonly_p) + regcache_restore (dst, do_cooked_read, src); + else + regcache_cpy_no_passthrough (dst, src); +} + +void +regcache_cpy_no_passthrough (struct regcache *dst, struct regcache *src) +{ + int i; + gdb_assert (src != NULL && dst != NULL); + gdb_assert (src->descr->gdbarch == dst->descr->gdbarch); + /* NOTE: cagney/2002-05-17: Don't let the caller do a no-passthrough + move of data into the current_regcache(). Doing this would be + silly - it would mean that valid_p would be completely invalid. */ + gdb_assert (dst != current_regcache); + memcpy (dst->registers, src->registers, dst->descr->sizeof_raw_registers); + memcpy (dst->register_valid_p, src->register_valid_p, + dst->descr->sizeof_raw_register_valid_p); +} + +struct regcache * +regcache_dup (struct regcache *src) +{ + struct regcache *newbuf; + gdb_assert (current_regcache != NULL); + newbuf = regcache_xmalloc (src->descr->gdbarch); + regcache_cpy (newbuf, src); + return newbuf; +} + +struct regcache * +regcache_dup_no_passthrough (struct regcache *src) +{ + struct regcache *newbuf; + gdb_assert (current_regcache != NULL); + newbuf = regcache_xmalloc (src->descr->gdbarch); + regcache_cpy_no_passthrough (newbuf, src); + return newbuf; +} + +int +regcache_valid_p (struct regcache *regcache, int regnum) +{ + gdb_assert (regcache != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + return regcache->register_valid_p[regnum]; +} + +char * +deprecated_grub_regcache_for_registers (struct regcache *regcache) +{ + return regcache->registers; +} + +/* Global structure containing the current regcache. */ +/* FIXME: cagney/2002-05-11: The two global arrays registers[] and + deprecated_register_valid[] currently point into this structure. */ +struct regcache *current_regcache; + /* NOTE: this is a write-through cache. There is no "dirty" bit for recording if the register values have been changed (eg. by the user). Therefore all registers must be written back to the @@ -40,14 +512,20 @@ /* REGISTERS contains the cached register values (in target byte order). */ -char *registers; +char *deprecated_registers; -/* REGISTER_VALID is 0 if the register needs to be fetched, +/* DEPRECATED_REGISTER_VALID is 0 if the register needs to be fetched, 1 if it has been fetched, and -1 if the register value was not available. - "Not available" means don't try to fetch it again. */ -signed char *register_valid; + "Not available" indicates that the target is not not able to supply + the register at this state. The register may become available at a + later time (after the next resume). This often occures when GDB is + manipulating a target that contains only a snapshot of the entire + system being debugged - some of the registers in such a system may + not have been saved. */ + +signed char *deprecated_register_valid; /* The thread/process associated with the current set of registers. */ @@ -66,7 +544,7 @@ static ptid_t registers_ptid; int register_cached (int regnum) { - return register_valid[regnum]; + return deprecated_register_valid[regnum]; } /* Record that REGNUM's value is cached if STATE is >0, uncached but @@ -75,26 +553,9 @@ register_cached (int regnum) void set_register_cached (int regnum, int state) { - register_valid[regnum] = state; -} - -/* REGISTER_CHANGED - - invalidate a single register REGNUM in the cache */ -void -register_changed (int regnum) -{ - set_register_cached (regnum, 0); -} - -/* If REGNUM >= 0, return a pointer to register REGNUM's cache buffer area, - else return a pointer to the start of the cache buffer. */ - -static char * -register_buffer (int regnum) -{ - gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS)); - return ®isters[REGISTER_BYTE (regnum)]; + gdb_assert (regnum >= 0); + gdb_assert (regnum < current_regcache->descr->nr_raw_registers); + current_regcache->register_valid_p[regnum] = state; } /* Return whether register REGNUM is a real register. */ @@ -105,46 +566,6 @@ real_register (int regnum) return regnum >= 0 && regnum < NUM_REGS; } -/* Return whether register REGNUM is a pseudo register. */ - -static int -pseudo_register (int regnum) -{ - return regnum >= NUM_REGS && regnum < NUM_REGS + NUM_PSEUDO_REGS; -} - -/* Fetch register REGNUM into the cache. */ - -static void -fetch_register (int regnum) -{ - /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store - pseudo-register as a way of handling registers that needed to be - constructed from one or more raw registers. New targets instead - use gdbarch register read/write. */ - if (FETCH_PSEUDO_REGISTER_P () - && pseudo_register (regnum)) - FETCH_PSEUDO_REGISTER (regnum); - else - target_fetch_registers (regnum); -} - -/* Write register REGNUM cached value to the target. */ - -static void -store_register (int regnum) -{ - /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store - pseudo-register as a way of handling registers that needed to be - constructed from one or more raw registers. New targets instead - use gdbarch register read/write. */ - if (STORE_PSEUDO_REGISTER_P () - && pseudo_register (regnum)) - STORE_PSEUDO_REGISTER (regnum); - else - target_store_registers (regnum); -} - /* Low level examining and depositing of registers. The caller is responsible for making sure that the inferior is @@ -170,14 +591,14 @@ registers_changed (void) gdb gives control to the user (ie watchpoints). */ alloca (0); - for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++) + for (i = 0; i < current_regcache->descr->nr_raw_registers; i++) set_register_cached (i, 0); if (registers_changed_hook) registers_changed_hook (); } -/* REGISTERS_FETCHED () +/* DEPRECATED_REGISTERS_FETCHED () Indicate that all registers have been fetched, so mark them all valid. */ @@ -190,7 +611,7 @@ registers_changed (void) this function/hack is eliminated. */ void -registers_fetched (void) +deprecated_registers_fetched (void) { int i; @@ -200,33 +621,33 @@ registers_fetched (void) Fetching all real regs NEVER accounts for pseudo-regs. */ } -/* read_register_bytes and write_register_bytes are generally a *BAD* - idea. They are inefficient because they need to check for partial - updates, which can only be done by scanning through all of the - registers and seeing if the bytes that are being read/written fall - inside of an invalid register. [The main reason this is necessary - is that register sizes can vary, so a simple index won't suffice.] - It is far better to call read_register_gen and write_register_gen - if you want to get at the raw register contents, as it only takes a - regnum as an argument, and therefore can't do a partial register - update. +/* deprecated_read_register_bytes and deprecated_write_register_bytes + are generally a *BAD* idea. They are inefficient because they need + to check for partial updates, which can only be done by scanning + through all of the registers and seeing if the bytes that are being + read/written fall inside of an invalid register. [The main reason + this is necessary is that register sizes can vary, so a simple + index won't suffice.] It is far better to call read_register_gen + and write_register_gen if you want to get at the raw register + contents, as it only takes a regnum as an argument, and therefore + can't do a partial register update. Prior to the recent fixes to check for partial updates, both read - and write_register_bytes always checked to see if any registers - were stale, and then called target_fetch_registers (-1) to update - the whole set. This caused really slowed things down for remote - targets. */ + and deprecated_write_register_bytes always checked to see if any + registers were stale, and then called target_fetch_registers (-1) + to update the whole set. This caused really slowed things down for + remote targets. */ /* Copy INLEN bytes of consecutive data from registers starting with the INREGBYTE'th byte of register data into memory at MYADDR. */ void -read_register_bytes (int in_start, char *in_buf, int in_len) +deprecated_read_register_bytes (int in_start, char *in_buf, int in_len) { int in_end = in_start + in_len; int regnum; - char *reg_buf = alloca (MAX_REGISTER_RAW_SIZE); + char reg_buf[MAX_REGISTER_SIZE]; /* See if we are trying to read bytes from out-of-date registers. If so, update just those registers. */ @@ -240,8 +661,8 @@ read_register_bytes (int in_start, char *in_buf, int in_len) int end; int byte; - reg_start = REGISTER_BYTE (regnum); - reg_len = REGISTER_RAW_SIZE (regnum); + reg_start = DEPRECATED_REGISTER_BYTE (regnum); + reg_len = DEPRECATED_REGISTER_RAW_SIZE (regnum); reg_end = reg_start + reg_len; if (reg_end <= in_start || in_end <= reg_start) @@ -250,7 +671,7 @@ read_register_bytes (int in_start, char *in_buf, int in_len) if (REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\0') /* Force the cache to fetch the entire register. */ - read_register_gen (regnum, reg_buf); + deprecated_read_register_gen (regnum, reg_buf); else /* Legacy note: even though this register is ``invalid'' we still need to return something. It would appear that some @@ -259,7 +680,7 @@ read_register_bytes (int in_start, char *in_buf, int in_len) /* FIXME: cagney/2001-08-18: This is just silly. It defeats the entire register read/write flow of control. Must resist temptation to return 0xdeadbeef. */ - memcpy (reg_buf, registers + reg_start, reg_len); + memcpy (reg_buf, &deprecated_registers[reg_start], reg_len); /* Legacy note: This function, for some reason, allows a NULL input buffer. If the buffer is NULL, the registers are still @@ -303,37 +724,181 @@ legacy_read_register_gen (int regnum, char *myaddr) } if (!register_cached (regnum)) - fetch_register (regnum); + target_fetch_registers (regnum); - memcpy (myaddr, register_buffer (regnum), - REGISTER_RAW_SIZE (regnum)); + memcpy (myaddr, register_buffer (current_regcache, regnum), + DEPRECATED_REGISTER_RAW_SIZE (regnum)); } void -regcache_read (int rawnum, char *buf) +regcache_raw_read (struct regcache *regcache, int regnum, void *buf) { - gdb_assert (rawnum >= 0 && rawnum < (NUM_REGS + NUM_PSEUDO_REGS)); - /* For moment, just use underlying legacy code. Ulgh!!! */ - legacy_read_register_gen (rawnum, buf); + gdb_assert (regcache != NULL && buf != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + if (regcache->descr->legacy_p + && !regcache->readonly_p) + { + gdb_assert (regcache == current_regcache); + /* For moment, just use underlying legacy code. Ulgh!!! This + silently and very indirectly updates the regcache's regcache + via the global deprecated_register_valid[]. */ + legacy_read_register_gen (regnum, buf); + return; + } + /* Make certain that the register cache is up-to-date with respect + to the current thread. This switching shouldn't be necessary + only there is still only one target side register cache. Sigh! + On the bright side, at least there is a regcache object. */ + if (!regcache->readonly_p) + { + gdb_assert (regcache == current_regcache); + if (! ptid_equal (registers_ptid, inferior_ptid)) + { + registers_changed (); + registers_ptid = inferior_ptid; + } + if (!register_cached (regnum)) + target_fetch_registers (regnum); + } + /* Copy the value directly into the register cache. */ + memcpy (buf, register_buffer (regcache, regnum), + regcache->descr->sizeof_register[regnum]); } void -read_register_gen (int regnum, char *buf) +regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val) { - if (! gdbarch_register_read_p (current_gdbarch)) + char *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + regcache_raw_read (regcache, regnum, buf); + (*val) = extract_signed_integer (buf, + regcache->descr->sizeof_register[regnum]); +} + +void +regcache_raw_read_unsigned (struct regcache *regcache, int regnum, + ULONGEST *val) +{ + char *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + regcache_raw_read (regcache, regnum, buf); + (*val) = extract_unsigned_integer (buf, + regcache->descr->sizeof_register[regnum]); +} + +void +regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val) +{ + void *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + store_signed_integer (buf, regcache->descr->sizeof_register[regnum], val); + regcache_raw_write (regcache, regnum, buf); +} + +void +regcache_raw_write_unsigned (struct regcache *regcache, int regnum, + ULONGEST val) +{ + void *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], val); + regcache_raw_write (regcache, regnum, buf); +} + +void +deprecated_read_register_gen (int regnum, char *buf) +{ + gdb_assert (current_regcache != NULL); + gdb_assert (current_regcache->descr->gdbarch == current_gdbarch); + if (current_regcache->descr->legacy_p) { legacy_read_register_gen (regnum, buf); return; } - gdbarch_register_read (current_gdbarch, regnum, buf); + regcache_cooked_read (current_regcache, regnum, buf); } +void +regcache_cooked_read (struct regcache *regcache, int regnum, void *buf) +{ + gdb_assert (regnum >= 0); + gdb_assert (regnum < regcache->descr->nr_cooked_registers); + if (regnum < regcache->descr->nr_raw_registers) + regcache_raw_read (regcache, regnum, buf); + else if (regcache->readonly_p + && regnum < regcache->descr->nr_cooked_registers + && regcache->register_valid_p[regnum]) + /* Read-only register cache, perhaphs the cooked value was cached? */ + memcpy (buf, register_buffer (regcache, regnum), + regcache->descr->sizeof_register[regnum]); + else + gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache, + regnum, buf); +} + +void +regcache_cooked_read_signed (struct regcache *regcache, int regnum, + LONGEST *val) +{ + char *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + regcache_cooked_read (regcache, regnum, buf); + (*val) = extract_signed_integer (buf, + regcache->descr->sizeof_register[regnum]); +} + +void +regcache_cooked_read_unsigned (struct regcache *regcache, int regnum, + ULONGEST *val) +{ + char *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + regcache_cooked_read (regcache, regnum, buf); + (*val) = extract_unsigned_integer (buf, + regcache->descr->sizeof_register[regnum]); +} + +void +regcache_cooked_write_signed (struct regcache *regcache, int regnum, + LONGEST val) +{ + void *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + store_signed_integer (buf, regcache->descr->sizeof_register[regnum], val); + regcache_cooked_write (regcache, regnum, buf); +} + +void +regcache_cooked_write_unsigned (struct regcache *regcache, int regnum, + ULONGEST val) +{ + void *buf; + gdb_assert (regcache != NULL); + gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers); + buf = alloca (regcache->descr->sizeof_register[regnum]); + store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], val); + regcache_cooked_write (regcache, regnum, buf); +} /* Write register REGNUM at MYADDR to the target. MYADDR points at REGISTER_RAW_BYTES(REGNUM), which must be in target byte-order. */ static void -legacy_write_register_gen (int regnum, char *myaddr) +legacy_write_register_gen (int regnum, const void *myaddr) { int size; gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS)); @@ -349,49 +914,100 @@ legacy_write_register_gen (int regnum, char *myaddr) registers_ptid = inferior_ptid; } - size = REGISTER_RAW_SIZE (regnum); + size = DEPRECATED_REGISTER_RAW_SIZE (regnum); if (real_register (regnum)) { /* If we have a valid copy of the register, and new value == old value, then don't bother doing the actual store. */ if (register_cached (regnum) - && memcmp (register_buffer (regnum), myaddr, size) == 0) + && (memcmp (register_buffer (current_regcache, regnum), myaddr, size) + == 0)) return; else target_prepare_to_store (); } - memcpy (register_buffer (regnum), myaddr, size); + memcpy (register_buffer (current_regcache, regnum), myaddr, size); set_register_cached (regnum, 1); - store_register (regnum); + target_store_registers (regnum); } void -regcache_write (int rawnum, char *buf) +regcache_raw_write (struct regcache *regcache, int regnum, const void *buf) { - gdb_assert (rawnum >= 0 && rawnum < (NUM_REGS + NUM_PSEUDO_REGS)); - /* For moment, just use underlying legacy code. Ulgh!!! */ - legacy_write_register_gen (rawnum, buf); + gdb_assert (regcache != NULL && buf != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + gdb_assert (!regcache->readonly_p); + + if (regcache->descr->legacy_p) + { + /* For moment, just use underlying legacy code. Ulgh!!! This + silently and very indirectly updates the regcache's buffers + via the globals deprecated_register_valid[] and registers[]. */ + gdb_assert (regcache == current_regcache); + legacy_write_register_gen (regnum, buf); + return; + } + + /* On the sparc, writing %g0 is a no-op, so we don't even want to + change the registers array if something writes to this register. */ + if (CANNOT_STORE_REGISTER (regnum)) + return; + + /* Make certain that the correct cache is selected. */ + gdb_assert (regcache == current_regcache); + if (! ptid_equal (registers_ptid, inferior_ptid)) + { + registers_changed (); + registers_ptid = inferior_ptid; + } + + /* If we have a valid copy of the register, and new value == old + value, then don't bother doing the actual store. */ + if (regcache_valid_p (regcache, regnum) + && (memcmp (register_buffer (regcache, regnum), buf, + regcache->descr->sizeof_register[regnum]) == 0)) + return; + + target_prepare_to_store (); + memcpy (register_buffer (regcache, regnum), buf, + regcache->descr->sizeof_register[regnum]); + regcache->register_valid_p[regnum] = 1; + target_store_registers (regnum); } void -write_register_gen (int regnum, char *buf) +deprecated_write_register_gen (int regnum, char *buf) { - if (! gdbarch_register_write_p (current_gdbarch)) + gdb_assert (current_regcache != NULL); + gdb_assert (current_regcache->descr->gdbarch == current_gdbarch); + if (current_regcache->descr->legacy_p) { legacy_write_register_gen (regnum, buf); return; } - gdbarch_register_write (current_gdbarch, regnum, buf); + regcache_cooked_write (current_regcache, regnum, buf); +} + +void +regcache_cooked_write (struct regcache *regcache, int regnum, const void *buf) +{ + gdb_assert (regnum >= 0); + gdb_assert (regnum < regcache->descr->nr_cooked_registers); + if (regnum < regcache->descr->nr_raw_registers) + regcache_raw_write (regcache, regnum, buf); + else + gdbarch_pseudo_register_write (regcache->descr->gdbarch, regcache, + regnum, buf); } /* Copy INLEN bytes of consecutive data from memory at MYADDR into registers starting with the MYREGSTART'th byte of register data. */ void -write_register_bytes (int myregstart, char *myaddr, int inlen) +deprecated_write_register_bytes (int myregstart, char *myaddr, int inlen) { int myregend = myregstart + inlen; int regnum; @@ -407,8 +1023,8 @@ write_register_bytes (int myregstart, char *myaddr, int inlen) { int regstart, regend; - regstart = REGISTER_BYTE (regnum); - regend = regstart + REGISTER_RAW_SIZE (regnum); + regstart = DEPRECATED_REGISTER_BYTE (regnum); + regend = regstart + DEPRECATED_REGISTER_RAW_SIZE (regnum); /* Is this register completely outside the range the user is writing? */ if (myregend <= regstart || regend <= myregstart) @@ -416,12 +1032,12 @@ write_register_bytes (int myregstart, char *myaddr, int inlen) /* Is this register completely within the range the user is writing? */ else if (myregstart <= regstart && regend <= myregend) - write_register_gen (regnum, myaddr + (regstart - myregstart)); + deprecated_write_register_gen (regnum, myaddr + (regstart - myregstart)); /* The register partially overlaps the range being written. */ else { - char *regbuf = (char*) alloca (MAX_REGISTER_RAW_SIZE); + char regbuf[MAX_REGISTER_SIZE]; /* What's the overlap between this register's bytes and those the caller wants to write? */ int overlapstart = max (regstart, myregstart); @@ -429,26 +1045,117 @@ write_register_bytes (int myregstart, char *myaddr, int inlen) /* We may be doing a partial update of an invalid register. Update it from the target before scribbling on it. */ - read_register_gen (regnum, regbuf); + deprecated_read_register_gen (regnum, regbuf); - memcpy (registers + overlapstart, + memcpy (&deprecated_registers[overlapstart], myaddr + (overlapstart - myregstart), overlapend - overlapstart); - store_register (regnum); + target_store_registers (regnum); } } } +/* Perform a partial register transfer using a read, modify, write + operation. */ + +typedef void (regcache_read_ftype) (struct regcache *regcache, int regnum, + void *buf); +typedef void (regcache_write_ftype) (struct regcache *regcache, int regnum, + const void *buf); + +static void +regcache_xfer_part (struct regcache *regcache, int regnum, + int offset, int len, void *in, const void *out, + regcache_read_ftype *read, regcache_write_ftype *write) +{ + struct regcache_descr *descr = regcache->descr; + bfd_byte reg[MAX_REGISTER_SIZE]; + gdb_assert (offset >= 0 && offset <= descr->sizeof_register[regnum]); + gdb_assert (len >= 0 && offset + len <= descr->sizeof_register[regnum]); + /* Something to do? */ + if (offset + len == 0) + return; + /* Read (when needed) ... */ + if (in != NULL + || offset > 0 + || offset + len < descr->sizeof_register[regnum]) + { + gdb_assert (read != NULL); + read (regcache, regnum, reg); + } + /* ... modify ... */ + if (in != NULL) + memcpy (in, reg + offset, len); + if (out != NULL) + memcpy (reg + offset, out, len); + /* ... write (when needed). */ + if (out != NULL) + { + gdb_assert (write != NULL); + write (regcache, regnum, reg); + } +} + +void +regcache_raw_read_part (struct regcache *regcache, int regnum, + int offset, int len, void *buf) +{ + struct regcache_descr *descr = regcache->descr; + gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers); + regcache_xfer_part (regcache, regnum, offset, len, buf, NULL, + regcache_raw_read, regcache_raw_write); +} + +void +regcache_raw_write_part (struct regcache *regcache, int regnum, + int offset, int len, const void *buf) +{ + struct regcache_descr *descr = regcache->descr; + gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers); + regcache_xfer_part (regcache, regnum, offset, len, NULL, buf, + regcache_raw_read, regcache_raw_write); +} + +void +regcache_cooked_read_part (struct regcache *regcache, int regnum, + int offset, int len, void *buf) +{ + struct regcache_descr *descr = regcache->descr; + gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers); + regcache_xfer_part (regcache, regnum, offset, len, buf, NULL, + regcache_cooked_read, regcache_cooked_write); +} + +void +regcache_cooked_write_part (struct regcache *regcache, int regnum, + int offset, int len, const void *buf) +{ + struct regcache_descr *descr = regcache->descr; + gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers); + regcache_xfer_part (regcache, regnum, offset, len, NULL, buf, + regcache_cooked_read, regcache_cooked_write); +} + +/* Hack to keep code that view the register buffer as raw bytes + working. */ + +int +register_offset_hack (struct gdbarch *gdbarch, int regnum) +{ + struct regcache_descr *descr = regcache_descr (gdbarch); + gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers); + return descr->register_offset[regnum]; +} /* Return the contents of register REGNUM as an unsigned integer. */ ULONGEST read_register (int regnum) { - char *buf = alloca (REGISTER_RAW_SIZE (regnum)); - read_register_gen (regnum, buf); - return (extract_unsigned_integer (buf, REGISTER_RAW_SIZE (regnum))); + char *buf = alloca (DEPRECATED_REGISTER_RAW_SIZE (regnum)); + deprecated_read_register_gen (regnum, buf); + return (extract_unsigned_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (regnum))); } ULONGEST @@ -472,36 +1179,6 @@ read_register_pid (int regnum, ptid_t ptid) return retval; } -/* Return the contents of register REGNUM as a signed integer. */ - -LONGEST -read_signed_register (int regnum) -{ - void *buf = alloca (REGISTER_RAW_SIZE (regnum)); - read_register_gen (regnum, buf); - return (extract_signed_integer (buf, REGISTER_RAW_SIZE (regnum))); -} - -LONGEST -read_signed_register_pid (int regnum, ptid_t ptid) -{ - ptid_t save_ptid; - LONGEST retval; - - if (ptid_equal (ptid, inferior_ptid)) - return read_signed_register (regnum); - - save_ptid = inferior_ptid; - - inferior_ptid = ptid; - - retval = read_signed_register (regnum); - - inferior_ptid = save_ptid; - - return retval; -} - /* Store VALUE into the raw contents of register number REGNUM. */ void @@ -509,10 +1186,10 @@ write_register (int regnum, LONGEST val) { void *buf; int size; - size = REGISTER_RAW_SIZE (regnum); + size = DEPRECATED_REGISTER_RAW_SIZE (regnum); buf = alloca (size); store_signed_integer (buf, size, (LONGEST) val); - write_register_gen (regnum, buf); + deprecated_write_register_gen (regnum, buf); } void @@ -535,6 +1212,10 @@ write_register_pid (int regnum, CORE_ADDR val, ptid_t ptid) inferior_ptid = save_ptid; } +/* FIXME: kettenis/20030828: We should get rid of supply_register and + regcache_collect in favour of regcache_raw_supply and + regcache_raw_collect. */ + /* SUPPLY_REGISTER() Record that register REGNUM contains VAL. This is used when the @@ -546,23 +1227,9 @@ write_register_pid (int regnum, CORE_ADDR val, ptid_t ptid) fact, and report it to the users of read_register and friends. */ void -supply_register (int regnum, char *val) +supply_register (int regnum, const void *val) { -#if 1 - if (! ptid_equal (registers_ptid, inferior_ptid)) - { - registers_changed (); - registers_ptid = inferior_ptid; - } -#endif - - set_register_cached (regnum, 1); - if (val) - memcpy (register_buffer (regnum), val, - REGISTER_RAW_SIZE (regnum)); - else - memset (register_buffer (regnum), '\000', - REGISTER_RAW_SIZE (regnum)); + regcache_raw_supply (current_regcache, regnum, val); /* On some architectures, e.g. HPPA, there are a few stray bits in some registers, that the rest of the code would like to ignore. */ @@ -570,60 +1237,85 @@ supply_register (int regnum, char *val) /* NOTE: cagney/2001-03-16: The macro CLEAN_UP_REGISTER_VALUE is going to be deprecated. Instead architectures will leave the raw register value as is and instead clean things up as they pass - through the method gdbarch_register_read() clean up the + through the method gdbarch_pseudo_register_read() clean up the values. */ #ifdef DEPRECATED_CLEAN_UP_REGISTER_VALUE - DEPRECATED_CLEAN_UP_REGISTER_VALUE (regnum, register_buffer (regnum)); + DEPRECATED_CLEAN_UP_REGISTER_VALUE \ + (regnum, register_buffer (current_regcache, regnum)); #endif } void regcache_collect (int regnum, void *buf) { - memcpy (buf, register_buffer (regnum), REGISTER_RAW_SIZE (regnum)); + regcache_raw_collect (current_regcache, regnum, buf); } +/* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE. */ -/* read_pc, write_pc, read_sp, write_sp, read_fp, write_fp, etc. - Special handling for registers PC, SP, and FP. */ - -/* NOTE: cagney/2001-02-18: The functions generic_target_read_pc(), - read_pc_pid(), read_pc(), generic_target_write_pc(), - write_pc_pid(), write_pc(), generic_target_read_sp(), read_sp(), - generic_target_write_sp(), write_sp(), generic_target_read_fp(), - read_fp(), generic_target_write_fp(), write_fp will eventually be - moved out of the reg-cache into either frame.[hc] or to the - multi-arch framework. The are not part of the raw register cache. */ - -/* 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. - - 1999-06-08: The following were re-written so that it assumes the - existence of a TARGET_READ_PC et.al. macro. A default generic - version of that macro is made available where needed. - - Since the ``TARGET_READ_PC'' et.al. macro is going to be controlled - by the multi-arch framework, it will eventually be possible to - eliminate the intermediate read_pc_pid(). The client would call - TARGET_READ_PC directly. (cagney). */ - -CORE_ADDR -generic_target_read_pc (ptid_t ptid) +void +regcache_raw_supply (struct regcache *regcache, int regnum, const void *buf) { -#ifdef PC_REGNUM - if (PC_REGNUM >= 0) + void *regbuf; + size_t size; + + gdb_assert (regcache != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + gdb_assert (!regcache->readonly_p); + + /* FIXME: kettenis/20030828: It shouldn't be necessary to handle + CURRENT_REGCACHE specially here. */ + if (regcache == current_regcache + && !ptid_equal (registers_ptid, inferior_ptid)) { - CORE_ADDR pc_val = ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, ptid)); - return pc_val; + registers_changed (); + registers_ptid = inferior_ptid; } -#endif - internal_error (__FILE__, __LINE__, - "generic_target_read_pc"); - return 0; + + regbuf = register_buffer (regcache, regnum); + size = regcache->descr->sizeof_register[regnum]; + + if (buf) + memcpy (regbuf, buf, size); + else + memset (regbuf, 0, size); + + /* Mark the register as cached. */ + regcache->register_valid_p[regnum] = 1; } +/* Collect register REGNUM from REGCACHE and store its contents in BUF. */ + +void +regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf) +{ + const void *regbuf; + size_t size; + + gdb_assert (regcache != NULL && buf != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + + regbuf = register_buffer (regcache, regnum); + size = regcache->descr->sizeof_register[regnum]; + memcpy (buf, regbuf, size); +} + + +/* read_pc, write_pc, read_sp, deprecated_read_fp, etc. Special + handling for registers PC, SP, and FP. */ + +/* NOTE: cagney/2001-02-18: The functions read_pc_pid(), read_pc(), + read_sp(), and deprecated_read_fp(), will eventually be replaced by + per-frame methods. Instead of relying on the global INFERIOR_PTID, + they will use the contextual information provided by the FRAME. + These functions do not belong in the register cache. */ + +/* NOTE: cagney/2003-06-07: The functions generic_target_write_pc(), + write_pc_pid(), write_pc(), and deprecated_read_fp(), all need to + be replaced by something that does not rely on global state. But + what? */ + CORE_ADDR read_pc_pid (ptid_t ptid) { @@ -634,7 +1326,16 @@ read_pc_pid (ptid_t ptid) saved_inferior_ptid = inferior_ptid; inferior_ptid = ptid; - pc_val = TARGET_READ_PC (ptid); + if (TARGET_READ_PC_P ()) + pc_val = TARGET_READ_PC (ptid); + /* Else use per-frame method on get_current_frame. */ + else if (PC_REGNUM >= 0) + { + CORE_ADDR raw_val = read_register_pid (PC_REGNUM, ptid); + pc_val = ADDR_BITS_REMOVE (raw_val); + } + else + internal_error (__FILE__, __LINE__, "read_pc_pid: Unable to find PC"); inferior_ptid = saved_inferior_ptid; return pc_val; @@ -649,17 +1350,11 @@ read_pc (void) void generic_target_write_pc (CORE_ADDR pc, ptid_t ptid) { -#ifdef PC_REGNUM if (PC_REGNUM >= 0) write_register_pid (PC_REGNUM, pc, ptid); - if (NPC_REGNUM >= 0) - write_register_pid (NPC_REGNUM, pc + 4, ptid); - if (NNPC_REGNUM >= 0) - write_register_pid (NNPC_REGNUM, pc + 8, ptid); -#else - internal_error (__FILE__, __LINE__, - "generic_target_write_pc"); -#endif + else + internal_error (__FILE__, __LINE__, + "generic_target_write_pc"); } void @@ -684,81 +1379,38 @@ write_pc (CORE_ADDR pc) /* Cope with strage ways of getting to the stack and frame pointers */ -CORE_ADDR -generic_target_read_sp (void) -{ -#ifdef SP_REGNUM - if (SP_REGNUM >= 0) - return read_register (SP_REGNUM); -#endif - internal_error (__FILE__, __LINE__, - "generic_target_read_sp"); -} - CORE_ADDR read_sp (void) { - return TARGET_READ_SP (); + if (TARGET_READ_SP_P ()) + return TARGET_READ_SP (); + else if (gdbarch_unwind_sp_p (current_gdbarch)) + return get_frame_sp (get_current_frame ()); + else if (SP_REGNUM >= 0) + /* Try SP_REGNUM last: this makes all sorts of [wrong] assumptions + about the architecture so put it at the end. */ + return read_register (SP_REGNUM); + internal_error (__FILE__, __LINE__, "read_sp: Unable to find SP"); } void -generic_target_write_sp (CORE_ADDR val) +deprecated_write_sp (CORE_ADDR val) { -#ifdef SP_REGNUM - if (SP_REGNUM >= 0) - { - write_register (SP_REGNUM, val); - return; - } -#endif - internal_error (__FILE__, __LINE__, - "generic_target_write_sp"); -} - -void -write_sp (CORE_ADDR val) -{ - TARGET_WRITE_SP (val); + gdb_assert (SP_REGNUM >= 0); + write_register (SP_REGNUM, val); } CORE_ADDR -generic_target_read_fp (void) +deprecated_read_fp (void) { -#ifdef FP_REGNUM - if (FP_REGNUM >= 0) - return read_register (FP_REGNUM); -#endif - internal_error (__FILE__, __LINE__, - "generic_target_read_fp"); + if (DEPRECATED_TARGET_READ_FP_P ()) + return DEPRECATED_TARGET_READ_FP (); + else if (DEPRECATED_FP_REGNUM >= 0) + return read_register (DEPRECATED_FP_REGNUM); + else + internal_error (__FILE__, __LINE__, "deprecated_read_fp"); } -CORE_ADDR -read_fp (void) -{ - return TARGET_READ_FP (); -} - -void -generic_target_write_fp (CORE_ADDR val) -{ -#ifdef FP_REGNUM - if (FP_REGNUM >= 0) - { - write_register (FP_REGNUM, val); - return; - } -#endif - internal_error (__FILE__, __LINE__, - "generic_target_write_fp"); -} - -void -write_fp (CORE_ADDR val) -{ - TARGET_WRITE_FP (val); -} - -/* ARGSUSED */ static void reg_flush_command (char *command, int from_tty) { @@ -771,42 +1423,293 @@ reg_flush_command (char *command, int from_tty) static void build_regcache (void) { - int i; - int sizeof_register_valid; - /* Come up with the real size of the registers buffer. */ - int sizeof_registers = REGISTER_BYTES; /* OK use. */ - for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++) - { - long regend; - /* Keep extending the buffer so that there is always enough - space for all registers. The comparison is necessary since - legacy code is free to put registers in random places in the - buffer separated by holes. Once REGISTER_BYTE() is killed - this can be greatly simplified. */ - /* FIXME: cagney/2001-12-04: This code shouldn't need to use - REGISTER_BYTE(). Unfortunatly, legacy code likes to lay the - buffer out so that certain registers just happen to overlap. - Ulgh! New targets use gdbarch's register read/write and - entirely avoid this uglyness. */ - regend = REGISTER_BYTE (i) + REGISTER_RAW_SIZE (i); - if (sizeof_registers < regend) - sizeof_registers = regend; - } - registers = xmalloc (sizeof_registers); - sizeof_register_valid = ((NUM_REGS + NUM_PSEUDO_REGS) - * sizeof (*register_valid)); - register_valid = xmalloc (sizeof_register_valid); - memset (register_valid, 0, sizeof_register_valid); + current_regcache = regcache_xmalloc (current_gdbarch); + current_regcache->readonly_p = 0; + deprecated_registers = deprecated_grub_regcache_for_registers (current_regcache); + deprecated_register_valid = current_regcache->register_valid_p; } +static void +dump_endian_bytes (struct ui_file *file, enum bfd_endian endian, + const unsigned char *buf, long len) +{ + int i; + switch (endian) + { + case BFD_ENDIAN_BIG: + for (i = 0; i < len; i++) + fprintf_unfiltered (file, "%02x", buf[i]); + break; + case BFD_ENDIAN_LITTLE: + for (i = len - 1; i >= 0; i--) + fprintf_unfiltered (file, "%02x", buf[i]); + break; + default: + internal_error (__FILE__, __LINE__, "Bad switch"); + } +} + +enum regcache_dump_what +{ + regcache_dump_none, regcache_dump_raw, regcache_dump_cooked, regcache_dump_groups +}; + +static void +regcache_dump (struct regcache *regcache, struct ui_file *file, + enum regcache_dump_what what_to_dump) +{ + struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); + struct gdbarch *gdbarch = regcache->descr->gdbarch; + int regnum; + int footnote_nr = 0; + int footnote_register_size = 0; + int footnote_register_offset = 0; + int footnote_register_type_name_null = 0; + long register_offset = 0; + unsigned char buf[MAX_REGISTER_SIZE]; + +#if 0 + fprintf_unfiltered (file, "legacy_p %d\n", regcache->descr->legacy_p); + fprintf_unfiltered (file, "nr_raw_registers %d\n", + regcache->descr->nr_raw_registers); + fprintf_unfiltered (file, "nr_cooked_registers %d\n", + regcache->descr->nr_cooked_registers); + fprintf_unfiltered (file, "sizeof_raw_registers %ld\n", + regcache->descr->sizeof_raw_registers); + fprintf_unfiltered (file, "sizeof_raw_register_valid_p %ld\n", + regcache->descr->sizeof_raw_register_valid_p); + fprintf_unfiltered (file, "NUM_REGS %d\n", NUM_REGS); + fprintf_unfiltered (file, "NUM_PSEUDO_REGS %d\n", NUM_PSEUDO_REGS); +#endif + + gdb_assert (regcache->descr->nr_cooked_registers + == (NUM_REGS + NUM_PSEUDO_REGS)); + + for (regnum = -1; regnum < regcache->descr->nr_cooked_registers; regnum++) + { + /* Name. */ + if (regnum < 0) + fprintf_unfiltered (file, " %-10s", "Name"); + else + { + const char *p = REGISTER_NAME (regnum); + if (p == NULL) + p = ""; + else if (p[0] == '\0') + p = "''"; + fprintf_unfiltered (file, " %-10s", p); + } + + /* Number. */ + if (regnum < 0) + fprintf_unfiltered (file, " %4s", "Nr"); + else + fprintf_unfiltered (file, " %4d", regnum); + + /* Relative number. */ + if (regnum < 0) + fprintf_unfiltered (file, " %4s", "Rel"); + else if (regnum < NUM_REGS) + fprintf_unfiltered (file, " %4d", regnum); + else + fprintf_unfiltered (file, " %4d", (regnum - NUM_REGS)); + + /* Offset. */ + if (regnum < 0) + fprintf_unfiltered (file, " %6s ", "Offset"); + else + { + fprintf_unfiltered (file, " %6ld", + regcache->descr->register_offset[regnum]); + if (register_offset != regcache->descr->register_offset[regnum] + || register_offset != DEPRECATED_REGISTER_BYTE (regnum) + || (regnum > 0 + && (regcache->descr->register_offset[regnum] + != (regcache->descr->register_offset[regnum - 1] + + regcache->descr->sizeof_register[regnum - 1]))) + ) + { + if (!footnote_register_offset) + footnote_register_offset = ++footnote_nr; + fprintf_unfiltered (file, "*%d", footnote_register_offset); + } + else + fprintf_unfiltered (file, " "); + register_offset = (regcache->descr->register_offset[regnum] + + regcache->descr->sizeof_register[regnum]); + } + + /* Size. */ + if (regnum < 0) + fprintf_unfiltered (file, " %5s ", "Size"); + else + { + fprintf_unfiltered (file, " %5ld", + regcache->descr->sizeof_register[regnum]); + if ((regcache->descr->sizeof_register[regnum] + != DEPRECATED_REGISTER_RAW_SIZE (regnum)) + || (regcache->descr->sizeof_register[regnum] + != DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)) + || (regcache->descr->sizeof_register[regnum] + != TYPE_LENGTH (register_type (regcache->descr->gdbarch, + regnum))) + ) + { + if (!footnote_register_size) + footnote_register_size = ++footnote_nr; + fprintf_unfiltered (file, "*%d", footnote_register_size); + } + else + fprintf_unfiltered (file, " "); + } + + /* Type. */ + { + const char *t; + if (regnum < 0) + t = "Type"; + else + { + static const char blt[] = "builtin_type"; + t = TYPE_NAME (register_type (regcache->descr->gdbarch, regnum)); + if (t == NULL) + { + char *n; + if (!footnote_register_type_name_null) + footnote_register_type_name_null = ++footnote_nr; + xasprintf (&n, "*%d", footnote_register_type_name_null); + make_cleanup (xfree, n); + t = n; + } + /* Chop a leading builtin_type. */ + if (strncmp (t, blt, strlen (blt)) == 0) + t += strlen (blt); + } + fprintf_unfiltered (file, " %-15s", t); + } + + /* Leading space always present. */ + fprintf_unfiltered (file, " "); + + /* Value, raw. */ + if (what_to_dump == regcache_dump_raw) + { + if (regnum < 0) + fprintf_unfiltered (file, "Raw value"); + else if (regnum >= regcache->descr->nr_raw_registers) + fprintf_unfiltered (file, ""); + else if (!regcache_valid_p (regcache, regnum)) + fprintf_unfiltered (file, ""); + else + { + regcache_raw_read (regcache, regnum, buf); + fprintf_unfiltered (file, "0x"); + dump_endian_bytes (file, TARGET_BYTE_ORDER, buf, + DEPRECATED_REGISTER_RAW_SIZE (regnum)); + } + } + + /* Value, cooked. */ + if (what_to_dump == regcache_dump_cooked) + { + if (regnum < 0) + fprintf_unfiltered (file, "Cooked value"); + else + { + regcache_cooked_read (regcache, regnum, buf); + fprintf_unfiltered (file, "0x"); + dump_endian_bytes (file, TARGET_BYTE_ORDER, buf, + DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); + } + } + + /* Group members. */ + if (what_to_dump == regcache_dump_groups) + { + if (regnum < 0) + fprintf_unfiltered (file, "Groups"); + else + { + const char *sep = ""; + struct reggroup *group; + for (group = reggroup_next (gdbarch, NULL); + group != NULL; + group = reggroup_next (gdbarch, group)) + { + if (gdbarch_register_reggroup_p (gdbarch, regnum, group)) + { + fprintf_unfiltered (file, "%s%s", sep, reggroup_name (group)); + sep = ","; + } + } + } + } + + fprintf_unfiltered (file, "\n"); + } + + if (footnote_register_size) + fprintf_unfiltered (file, "*%d: Inconsistent register sizes.\n", + footnote_register_size); + if (footnote_register_offset) + fprintf_unfiltered (file, "*%d: Inconsistent register offsets.\n", + footnote_register_offset); + if (footnote_register_type_name_null) + fprintf_unfiltered (file, + "*%d: Register type's name NULL.\n", + footnote_register_type_name_null); + do_cleanups (cleanups); +} + +static void +regcache_print (char *args, enum regcache_dump_what what_to_dump) +{ + if (args == NULL) + regcache_dump (current_regcache, gdb_stdout, what_to_dump); + else + { + struct ui_file *file = gdb_fopen (args, "w"); + if (file == NULL) + perror_with_name ("maintenance print architecture"); + regcache_dump (current_regcache, file, what_to_dump); + ui_file_delete (file); + } +} + +static void +maintenance_print_registers (char *args, int from_tty) +{ + regcache_print (args, regcache_dump_none); +} + +static void +maintenance_print_raw_registers (char *args, int from_tty) +{ + regcache_print (args, regcache_dump_raw); +} + +static void +maintenance_print_cooked_registers (char *args, int from_tty) +{ + regcache_print (args, regcache_dump_cooked); +} + +static void +maintenance_print_register_groups (char *args, int from_tty) +{ + regcache_print (args, regcache_dump_groups); +} + +extern initialize_file_ftype _initialize_regcache; /* -Wmissing-prototype */ + void _initialize_regcache (void) { - build_regcache (); - - register_gdbarch_swap (®isters, sizeof (registers), NULL); - register_gdbarch_swap (®ister_valid, sizeof (register_valid), NULL); - register_gdbarch_swap (NULL, 0, build_regcache); + regcache_descr_handle = register_gdbarch_data (init_regcache_descr); + DEPRECATED_REGISTER_GDBARCH_SWAP (current_regcache); + DEPRECATED_REGISTER_GDBARCH_SWAP (deprecated_registers); + DEPRECATED_REGISTER_GDBARCH_SWAP (deprecated_register_valid); + deprecated_register_gdbarch_swap (NULL, 0, build_regcache); add_com ("flushregs", class_maintenance, reg_flush_command, "Force gdb to flush its register cache (maintainer command)"); @@ -814,4 +1717,26 @@ _initialize_regcache (void) /* Initialize the thread/process associated with the current set of registers. For now, -1 is special, and means `no current process'. */ registers_ptid = pid_to_ptid (-1); + + add_cmd ("registers", class_maintenance, + maintenance_print_registers, + "Print the internal register configuration.\ +Takes an optional file parameter.", + &maintenanceprintlist); + add_cmd ("raw-registers", class_maintenance, + maintenance_print_raw_registers, + "Print the internal register configuration including raw values.\ +Takes an optional file parameter.", + &maintenanceprintlist); + add_cmd ("cooked-registers", class_maintenance, + maintenance_print_cooked_registers, + "Print the internal register configuration including cooked values.\ +Takes an optional file parameter.", + &maintenanceprintlist); + add_cmd ("register-groups", class_maintenance, + maintenance_print_register_groups, + "Print the internal register configuration including each register's group.\ +Takes an optional file parameter.", + &maintenanceprintlist); + } diff --git a/contrib/gdb/gdb/regcache.h b/contrib/gdb/gdb/regcache.h index 4e854d31667..26a1b8a38e3 100644 --- a/contrib/gdb/gdb/regcache.h +++ b/contrib/gdb/gdb/regcache.h @@ -1,6 +1,7 @@ /* Cache and manage the values of registers for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, + 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -22,48 +23,224 @@ #ifndef REGCACHE_H #define REGCACHE_H +struct regcache; +struct gdbarch; + +extern struct regcache *current_regcache; + +void regcache_xfree (struct regcache *regcache); +struct cleanup *make_cleanup_regcache_xfree (struct regcache *regcache); +struct regcache *regcache_xmalloc (struct gdbarch *gdbarch); + +/* Return REGCACHE's architecture. */ + +extern struct gdbarch *get_regcache_arch (const struct regcache *regcache); + /* Transfer a raw register [0..NUM_REGS) between core-gdb and the regcache. */ -void regcache_read (int rawnum, char *buf); -void regcache_write (int rawnum, char *buf); +void regcache_raw_read (struct regcache *regcache, int rawnum, void *buf); +void regcache_raw_write (struct regcache *regcache, int rawnum, + const void *buf); +extern void regcache_raw_read_signed (struct regcache *regcache, + int regnum, LONGEST *val); +extern void regcache_raw_read_unsigned (struct regcache *regcache, + int regnum, ULONGEST *val); +extern void regcache_raw_write_signed (struct regcache *regcache, + int regnum, LONGEST val); +extern void regcache_raw_write_unsigned (struct regcache *regcache, + int regnum, ULONGEST val); + +/* Partial transfer of a raw registers. These perform read, modify, + write style operations. */ + +void regcache_raw_read_part (struct regcache *regcache, int regnum, + int offset, int len, void *buf); +void regcache_raw_write_part (struct regcache *regcache, int regnum, + int offset, int len, const void *buf); + +int regcache_valid_p (struct regcache *regcache, int regnum); + +/* Transfer a cooked register [0..NUM_REGS+NUM_PSEUDO_REGS). */ +void regcache_cooked_read (struct regcache *regcache, int rawnum, void *buf); +void regcache_cooked_write (struct regcache *regcache, int rawnum, + const void *buf); + +/* NOTE: cagney/2002-08-13: At present GDB has no reliable mechanism + for indicating when a ``cooked'' register was constructed from + invalid or unavailable ``raw'' registers. One fairly easy way of + adding such a mechanism would be for the cooked functions to return + a register valid indication. Given the possibility of such a + change, the extract functions below use a reference parameter, + rather than a function result. */ + +/* Read a register as a signed/unsigned quantity. */ +extern void regcache_cooked_read_signed (struct regcache *regcache, + int regnum, LONGEST *val); +extern void regcache_cooked_read_unsigned (struct regcache *regcache, + int regnum, ULONGEST *val); +extern void regcache_cooked_write_signed (struct regcache *regcache, + int regnum, LONGEST val); +extern void regcache_cooked_write_unsigned (struct regcache *regcache, + int regnum, ULONGEST val); + +/* Partial transfer of a cooked register. These perform read, modify, + write style operations. */ + +void regcache_cooked_read_part (struct regcache *regcache, int regnum, + int offset, int len, void *buf); +void regcache_cooked_write_part (struct regcache *regcache, int regnum, + int offset, int len, const void *buf); /* Transfer a raw register [0..NUM_REGS) between the regcache and the target. These functions are called by the target in response to a target_fetch_registers() or target_store_registers(). */ -extern void supply_register (int regnum, char *val); +extern void supply_register (int regnum, const void *val); extern void regcache_collect (int regnum, void *buf); +extern void regcache_raw_supply (struct regcache *regcache, + int regnum, const void *buf); +extern void regcache_raw_collect (const struct regcache *regcache, + int regnum, void *buf); -/* DEPRECATED: Character array containing an image of the inferior - programs' registers for the most recently referenced thread. */ +/* The register's ``offset''. -extern char *registers; + FIXME: cagney/2002-11-07: The frame_register() function, when + specifying the real location of a register, does so using that + registers offset in the register cache. That offset is then used + by valops.c to determine the location of the register. The code + should instead use the register's number and a location expression + to describe a value spread across multiple registers or memory. */ -/* DEPRECATED: Character array containing the current state of each - register (unavailable<0, invalid=0, valid>0) for the most recently - referenced thread. */ +extern int register_offset_hack (struct gdbarch *gdbarch, int regnum); -extern signed char *register_valid; + +/* The type of a register. This function is slightly more efficient + then its gdbarch vector counterpart since it returns a precomputed + value stored in a table. + + NOTE: cagney/2002-08-17: The original macro was called + DEPRECATED_REGISTER_VIRTUAL_TYPE. This was because the register + could have different raw and cooked (nee virtual) representations. + The CONVERTABLE methods being used to convert between the two + representations. Current code does not do this. Instead, the + first [0..NUM_REGS) registers are 1:1 raw:cooked, and the type + exactly describes the register's representation. Consequently, the + ``virtual'' has been dropped. + + FIXME: cagney/2002-08-17: A number of architectures, including the + MIPS, are currently broken in this regard. */ + +extern struct type *register_type (struct gdbarch *gdbarch, int regnum); + + +/* Return the size of register REGNUM. All registers should have only + one size. + + FIXME: cagney/2003-02-28: + + Unfortunately, thanks to some legacy architectures, this doesn't + hold. A register's cooked (nee virtual) and raw size can differ + (see MIPS). Such architectures should be using different register + numbers for the different sized views of identical registers. + + Anyway, the up-shot is that, until that mess is fixed, core code + can end up being very confused - should the RAW or VIRTUAL size be + used? As a rule of thumb, use DEPRECATED_REGISTER_VIRTUAL_SIZE in + cooked code, but with the comment: + + OK: REGISTER_VIRTUAL_SIZE + + or just + + OK + + appended to the end of the line. */ + +extern int register_size (struct gdbarch *gdbarch, int regnum); + + +/* Save/restore a register cache. The set of registers saved / + restored into the DST regcache determined by the save_reggroup / + restore_reggroup respectively. COOKED_READ returns zero iff the + register's value can't be returned. */ + +typedef int (regcache_cooked_read_ftype) (void *src, int regnum, void *buf); + +extern void regcache_save (struct regcache *dst, + regcache_cooked_read_ftype *cooked_read, + void *src); +extern void regcache_restore (struct regcache *dst, + regcache_cooked_read_ftype *cooked_read, + void *src); + +/* Copy/duplicate the contents of a register cache. By default, the + operation is pass-through. Writes to DST and reads from SRC will + go through to the target. + + The ``cpy'' functions can not have overlapping SRC and DST buffers. + + ``no passthrough'' versions do not go through to the target. They + only transfer values already in the cache. */ + +extern struct regcache *regcache_dup (struct regcache *regcache); +extern struct regcache *regcache_dup_no_passthrough (struct regcache *regcache); +extern void regcache_cpy (struct regcache *dest, struct regcache *src); +extern void regcache_cpy_no_passthrough (struct regcache *dest, struct regcache *src); + +/* NOTE: cagney/2002-11-02: The below have been superseded by the + regcache_cooked_*() functions found above, and the frame_*() + functions found in "frame.h". Take care though, often more than a + simple substitution is required when updating the code. The + change, as far as practical, should avoid adding references to + global variables (e.g., current_regcache, current_frame, + current_gdbarch or deprecated_selected_frame) and instead refer to + the FRAME or REGCACHE that has been passed into the containing + function as parameters. Consequently, the change typically + involves modifying the containing function so that it takes a FRAME + or REGCACHE parameter. In the case of an architecture vector + method, there should already be a non-deprecated variant that is + parameterized with FRAME or REGCACHE. */ + +extern char *deprecated_grub_regcache_for_registers (struct regcache *); +extern void deprecated_read_register_gen (int regnum, char *myaddr); +extern void deprecated_write_register_gen (int regnum, char *myaddr); +extern void deprecated_read_register_bytes (int regbyte, char *myaddr, + int len); +extern void deprecated_write_register_bytes (int regbyte, char *myaddr, + int len); + +/* Character array containing the current state of each register + (unavailable<0, invalid=0, valid>0) for the most recently + referenced thread. This global is often found in close proximity + to code that is directly manipulating the deprecated_registers[] + array. In such cases, it should be possible to replace the lot + with a call to supply_register(). If you find yourself in dire + straits, still needing access to the cache status bit, the + regcache_valid_p() and set_register_cached() functions are + available. */ +extern signed char *deprecated_register_valid; + +/* Character array containing an image of the inferior programs' + registers for the most recently referenced thread. + + NOTE: cagney/2002-11-14: Target side code should be using + supply_register() and/or regcache_collect() while architecture side + code should use the more generic regcache methods. */ + +extern char *deprecated_registers; + +/* NOTE: cagney/2002-11-05: This function, and its co-conspirator + deprecated_registers[], have been superseeded by supply_register(). */ +extern void deprecated_registers_fetched (void); extern int register_cached (int regnum); extern void set_register_cached (int regnum, int state); -extern void register_changed (int regnum); - extern void registers_changed (void); -extern void registers_fetched (void); - -extern void read_register_bytes (int regbyte, char *myaddr, int len); - -extern void read_register_gen (int regnum, char *myaddr); - -extern void write_register_gen (int regnum, char *myaddr); - -extern void write_register_bytes (int regbyte, char *myaddr, int len); /* Rename to read_unsigned_register()? */ extern ULONGEST read_register (int regnum); @@ -71,10 +248,6 @@ extern ULONGEST read_register (int regnum); /* Rename to read_unsigned_register_pid()? */ extern ULONGEST read_register_pid (int regnum, ptid_t ptid); -extern LONGEST read_signed_register (int regnum); - -extern LONGEST read_signed_register_pid (int regnum, ptid_t ptid); - extern void write_register (int regnum, LONGEST val); extern void write_register_pid (int regnum, CORE_ADDR val, ptid_t ptid); diff --git a/contrib/gdb/gdb/regformats/reg-m68k.dat b/contrib/gdb/gdb/regformats/reg-m68k.dat new file mode 100644 index 00000000000..8928b45282c --- /dev/null +++ b/contrib/gdb/gdb/regformats/reg-m68k.dat @@ -0,0 +1,33 @@ +name:m68k +expedite:sp,fp,pc +32:d0 +32:d1 +32:d2 +32:d3 +32:d4 +32:d5 +32:d6 +32:d7 +32:a0 +32:a1 +32:a2 +32:a3 +32:a4 +32:a5 +32:fp +32:sp +32:ps +32:pc + +96:fp0 +96:fp1 +96:fp2 +96:fp3 +96:fp4 +96:fp5 +96:fp6 +96:fp7 + +32:fpcontrol +32:fpstatus +32:fpiaddr diff --git a/contrib/gdb/gdb/regformats/reg-ppc.dat b/contrib/gdb/gdb/regformats/reg-ppc.dat index d915996cc01..d7f9b88c355 100644 --- a/contrib/gdb/gdb/regformats/reg-ppc.dat +++ b/contrib/gdb/gdb/regformats/reg-ppc.dat @@ -73,4 +73,4 @@ expedite:r1,pc 32:lr 32:ctr 32:xer -0: +32:fpscr diff --git a/contrib/gdb/gdb/regformats/reg-s390.dat b/contrib/gdb/gdb/regformats/reg-s390.dat new file mode 100644 index 00000000000..79e07b969d4 --- /dev/null +++ b/contrib/gdb/gdb/regformats/reg-s390.dat @@ -0,0 +1,53 @@ +name:s390 +expedite:r14,r15,pswa +32:pswm +32:pswa +32:r0 +32:r1 +32:r2 +32:r3 +32:r4 +32:r5 +32:r6 +32:r7 +32:r8 +32:r9 +32:r10 +32:r11 +32:r12 +32:r13 +32:r14 +32:r15 +32:acr0 +32:acr1 +32:acr2 +32:acr3 +32:acr4 +32:acr5 +32:acr6 +32:acr7 +32:acr8 +32:acr9 +32:acr10 +32:acr11 +32:acr12 +32:acr13 +32:acr14 +32:acr15 +32:fpc +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 diff --git a/contrib/gdb/gdb/regformats/reg-s390x.dat b/contrib/gdb/gdb/regformats/reg-s390x.dat new file mode 100644 index 00000000000..2e24f53d0d5 --- /dev/null +++ b/contrib/gdb/gdb/regformats/reg-s390x.dat @@ -0,0 +1,53 @@ +name:s390 +expedite:r14,r15,pswa +64:pswm +64:pswa +64:r0 +64:r1 +64:r2 +64:r3 +64:r4 +64:r5 +64:r6 +64:r7 +64:r8 +64:r9 +64:r10 +64:r11 +64:r12 +64:r13 +64:r14 +64:r15 +32:acr0 +32:acr1 +32:acr2 +32:acr3 +32:acr4 +32:acr5 +32:acr6 +32:acr7 +32:acr8 +32:acr9 +32:acr10 +32:acr11 +32:acr12 +32:acr13 +32:acr14 +32:acr15 +32:fpc +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 diff --git a/contrib/gdb/gdb/regformats/reg-x86-64.dat b/contrib/gdb/gdb/regformats/reg-x86-64.dat index a8a2e8c77b4..dd1f78fa71b 100644 --- a/contrib/gdb/gdb/regformats/reg-x86-64.dat +++ b/contrib/gdb/gdb/regformats/reg-x86-64.dat @@ -1,9 +1,9 @@ name:x86_64 expedite:rbp,rsp,rip 64:rax -64:rdx -64:rcx 64:rbx +64:rcx +64:rdx 64:rsi 64:rdi 64:rbp @@ -18,6 +18,12 @@ expedite:rbp,rsp,rip 64:r15 64:rip 32:eflags +32:cs +32:ss +32:ds +32:es +32:fs +32:gs 80:st0 80:st1 80:st2 diff --git a/contrib/gdb/gdb/reggroups.c b/contrib/gdb/gdb/reggroups.c new file mode 100644 index 00000000000..7dd05628519 --- /dev/null +++ b/contrib/gdb/gdb/reggroups.c @@ -0,0 +1,288 @@ +/* Register groupings for GDB, the GNU debugger. + + Copyright 2002, 2003 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "reggroups.h" +#include "gdbtypes.h" +#include "gdb_assert.h" +#include "regcache.h" +#include "command.h" +#include "gdbcmd.h" /* For maintenanceprintlist. */ + +/* Individual register groups. */ + +struct reggroup +{ + const char *name; + enum reggroup_type type; +}; + +struct reggroup * +reggroup_new (const char *name, enum reggroup_type type) +{ + struct reggroup *group = XMALLOC (struct reggroup); + group->name = name; + group->type = type; + return group; +} + +/* Register group attributes. */ + +const char * +reggroup_name (struct reggroup *group) +{ + return group->name; +} + +enum reggroup_type +reggroup_type (struct reggroup *group) +{ + return group->type; +} + +/* A linked list of groups for the given architecture. */ + +struct reggroup_el +{ + struct reggroup *group; + struct reggroup_el *next; +}; + +struct reggroups +{ + struct reggroup_el *first; + struct reggroup_el **last; +}; + +static struct gdbarch_data *reggroups_data; + +static void * +reggroups_init (struct gdbarch *gdbarch) +{ + struct reggroups *groups = GDBARCH_OBSTACK_ZALLOC (gdbarch, + struct reggroups); + groups->last = &groups->first; + return groups; +} + +/* Add a register group (with attribute values) to the pre-defined + list. */ + +static void +add_group (struct reggroups *groups, struct reggroup *group, + struct reggroup_el *el) +{ + gdb_assert (group != NULL); + el->group = group; + el->next = NULL; + (*groups->last) = el; + groups->last = &el->next; +} + +void +reggroup_add (struct gdbarch *gdbarch, struct reggroup *group) +{ + struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data); + + if (groups == NULL) + { + /* ULGH, called during architecture initialization. Patch + things up. */ + groups = reggroups_init (gdbarch); + set_gdbarch_data (gdbarch, reggroups_data, groups); + } + add_group (groups, group, + GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el)); +} + +/* The default register groups for an architecture. */ + +static struct reggroups default_groups = { NULL, &default_groups.first }; + +/* A register group iterator. */ + +struct reggroup * +reggroup_next (struct gdbarch *gdbarch, struct reggroup *last) +{ + struct reggroups *groups; + struct reggroup_el *el; + + /* Don't allow this function to be called during architecture + creation. If there are no groups, use the default groups list. */ + groups = gdbarch_data (gdbarch, reggroups_data); + gdb_assert (groups != NULL); + if (groups->first == NULL) + groups = &default_groups; + + /* Return the first/next reggroup. */ + if (last == NULL) + return groups->first->group; + for (el = groups->first; el != NULL; el = el->next) + { + if (el->group == last) + { + if (el->next != NULL) + return el->next->group; + else + return NULL; + } + } + return NULL; +} + +/* Is REGNUM a member of REGGROUP? */ +int +default_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) +{ + int vector_p; + int float_p; + int raw_p; + + if (REGISTER_NAME (regnum) == NULL + || *REGISTER_NAME (regnum) == '\0') + return 0; + if (group == all_reggroup) + return 1; + vector_p = TYPE_VECTOR (register_type (gdbarch, regnum)); + float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT; + /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs + (gdbarch), as not all architectures are multi-arch. */ + raw_p = regnum < NUM_REGS; + if (group == float_reggroup) + return float_p; + if (group == vector_reggroup) + return vector_p; + if (group == general_reggroup) + return (!vector_p && !float_p); + if (group == save_reggroup || group == restore_reggroup) + return raw_p; + return 0; +} + +/* Dump out a table of register groups for the current architecture. */ + +static void +reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file) +{ + struct reggroup *group = NULL; + + do + { + /* Group name. */ + { + const char *name; + if (group == NULL) + name = "Group"; + else + name = reggroup_name (group); + fprintf_unfiltered (file, " %-10s", name); + } + + /* Group type. */ + { + const char *type; + if (group == NULL) + type = "Type"; + else + { + switch (reggroup_type (group)) + { + case USER_REGGROUP: + type = "user"; + break; + case INTERNAL_REGGROUP: + type = "internal"; + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } + } + fprintf_unfiltered (file, " %-10s", type); + } + + /* Note: If you change this, be sure to also update the + documentation. */ + + fprintf_unfiltered (file, "\n"); + + group = reggroup_next (gdbarch, group); + } + while (group != NULL); +} + +static void +maintenance_print_reggroups (char *args, int from_tty) +{ + if (args == NULL) + reggroups_dump (current_gdbarch, gdb_stdout); + else + { + struct ui_file *file = gdb_fopen (args, "w"); + if (file == NULL) + perror_with_name ("maintenance print reggroups"); + reggroups_dump (current_gdbarch, file); + ui_file_delete (file); + } +} + +/* Pre-defined register groups. */ +static struct reggroup general_group = { "general", USER_REGGROUP }; +static struct reggroup float_group = { "float", USER_REGGROUP }; +static struct reggroup system_group = { "system", USER_REGGROUP }; +static struct reggroup vector_group = { "vector", USER_REGGROUP }; +static struct reggroup all_group = { "all", USER_REGGROUP }; +static struct reggroup save_group = { "save", INTERNAL_REGGROUP }; +static struct reggroup restore_group = { "restore", INTERNAL_REGGROUP }; + +struct reggroup *const general_reggroup = &general_group; +struct reggroup *const float_reggroup = &float_group; +struct reggroup *const system_reggroup = &system_group; +struct reggroup *const vector_reggroup = &vector_group; +struct reggroup *const all_reggroup = &all_group; +struct reggroup *const save_reggroup = &save_group; +struct reggroup *const restore_reggroup = &restore_group; + +extern initialize_file_ftype _initialize_reggroup; /* -Wmissing-prototypes */ + +void +_initialize_reggroup (void) +{ + reggroups_data = register_gdbarch_data (reggroups_init); + + /* The pre-defined list of groups. */ + add_group (&default_groups, general_reggroup, XMALLOC (struct reggroup_el)); + add_group (&default_groups, float_reggroup, XMALLOC (struct reggroup_el)); + add_group (&default_groups, system_reggroup, XMALLOC (struct reggroup_el)); + add_group (&default_groups, vector_reggroup, XMALLOC (struct reggroup_el)); + add_group (&default_groups, all_reggroup, XMALLOC (struct reggroup_el)); + add_group (&default_groups, save_reggroup, XMALLOC (struct reggroup_el)); + add_group (&default_groups, restore_reggroup, XMALLOC (struct reggroup_el)); + + add_cmd ("reggroups", class_maintenance, + maintenance_print_reggroups, "\ +Print the internal register group names.\n\ +Takes an optional file parameter.", + &maintenanceprintlist); + +} diff --git a/contrib/gdb/gdb/reggroups.h b/contrib/gdb/gdb/reggroups.h new file mode 100644 index 00000000000..22c0a6fcca9 --- /dev/null +++ b/contrib/gdb/gdb/reggroups.h @@ -0,0 +1,64 @@ +/* Register groupings for GDB, the GNU debugger. + + Copyright 2002 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef REGGROUPS_H +#define REGGROUPS_H + +struct gdbarch; +struct reggroup; + +enum reggroup_type { USER_REGGROUP, INTERNAL_REGGROUP }; + +/* Pre-defined, user visible, register groups. */ +extern struct reggroup *const general_reggroup; +extern struct reggroup *const float_reggroup; +extern struct reggroup *const system_reggroup; +extern struct reggroup *const vector_reggroup; +extern struct reggroup *const all_reggroup; + +/* Pre-defined, internal, register groups. */ +extern struct reggroup *const save_reggroup; +extern struct reggroup *const restore_reggroup; + +/* Create a new local register group. */ +extern struct reggroup *reggroup_new (const char *name, + enum reggroup_type type); + +/* Add a register group (with attribute values) to the pre-defined list. */ +extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group); + +/* Register group attributes. */ +extern const char *reggroup_name (struct reggroup *reggroup); +extern enum reggroup_type reggroup_type (struct reggroup *reggroup); + +/* Interator for the architecture's register groups. Pass in NULL, + returns the first group. Pass in a group, returns the next group, + or NULL when the last group is reached. */ +extern struct reggroup *reggroup_next (struct gdbarch *gdbarch, + struct reggroup *last); + +/* Is REGNUM a member of REGGROUP? */ +extern int default_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *reggroup); + +#endif diff --git a/contrib/gdb/gdb/regset.h b/contrib/gdb/gdb/regset.h new file mode 100644 index 00000000000..6172f0fecfd --- /dev/null +++ b/contrib/gdb/gdb/regset.h @@ -0,0 +1,41 @@ +/* Manage register sets. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef REGSET_H +#define REGSET_H 1 + +struct gdbarch; +struct regcache; + +/* Data structure describing a register set. */ + +struct regset +{ + /* Data pointer for private use by the methods below, presumably + providing some sort of description of the register set. */ + const void *descr; + + /* Function supplying a register set to a register cache. */ + void (*supply_regset) (const struct regset *, struct regcache *, + int, const void *, size_t); +}; + +#endif /* regset.h */ diff --git a/contrib/gdb/gdb/remote-e7000.c b/contrib/gdb/gdb/remote-e7000.c new file mode 100644 index 00000000000..c422c947612 --- /dev/null +++ b/contrib/gdb/gdb/remote-e7000.c @@ -0,0 +1,2194 @@ +/* Remote debugging interface for Renesas E7000 ICE, for GDB + + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003 Free Software Foundation, Inc. + + Contributed by Cygnus Support. + + Written by Steve Chamberlain for Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* The E7000 is an in-circuit emulator for the Renesas H8/300-H and + Renesas-SH processor. It has serial port and a lan port. + + The monitor command set makes it difficult to load large ammounts of + data over the lan without using ftp - so try not to issue load + commands when communicating over ethernet; use the ftpload command. + + The monitor pauses for a second when dumping srecords to the serial + line too, so we use a slower per byte mechanism but without the + startup overhead. Even so, it's pretty slow... */ + +#include "defs.h" +#include "gdbcore.h" +#include "gdbarch.h" +#include "inferior.h" +#include "target.h" +#include "value.h" +#include "command.h" +#include "gdb_string.h" +#include "gdbcmd.h" +#include +#include "serial.h" +#include "remote-utils.h" +#include "symfile.h" +#include "regcache.h" +#include +#include + + +#if 1 +#define HARD_BREAKPOINTS /* Now handled by set option. */ +#define BC_BREAKPOINTS use_hard_breakpoints +#endif + +#define CTRLC 0x03 +#define ENQ 0x05 +#define ACK 0x06 +#define CTRLZ 0x1a + +/* This file is used by 2 different targets, sh-elf and h8300. The + h8300 is not multiarched and doesn't use the registers defined in + tm-sh.h. To avoid using a macro GDB_TARGET_IS_SH, we do runtime check + of the target, which requires that these namse below are always + defined also in the h8300 case. */ + +#if !defined (PR_REGNUM) +#define PR_REGNUM -1 +#endif +#if !defined (GBR_REGNUM) +#define GBR_REGNUM -1 +#endif +#if !defined (VBR_REGNUM) +#define VBR_REGNUM -1 +#endif +#if !defined (MACH_REGNUM) +#define MACH_REGNUM -1 +#endif +#if !defined (MACL_REGNUM) +#define MACL_REGNUM -1 +#endif +#if !defined (SR_REGNUM) +#define SR_REGNUM -1 +#endif + +extern void report_transfer_performance (unsigned long, time_t, time_t); + +extern char *sh_processor_type; + +/* Local function declarations. */ + +static void e7000_close (int); + +static void e7000_fetch_register (int); + +static void e7000_store_register (int); + +static void e7000_command (char *, int); + +static void e7000_login_command (char *, int); + +static void e7000_ftp_command (char *, int); + +static void e7000_drain_command (char *, int); + +static void expect (char *); + +static void expect_full_prompt (void); + +static void expect_prompt (void); + +static int e7000_parse_device (char *args, char *dev_name, int baudrate); +/* Variables. */ + +static struct serial *e7000_desc; + +/* Allow user to chose between using hardware breakpoints or memory. */ +static int use_hard_breakpoints = 0; /* use sw breakpoints by default */ + +/* Nonzero if using the tcp serial driver. */ + +static int using_tcp; /* direct tcp connection to target */ +static int using_tcp_remote; /* indirect connection to target + via tcp to controller */ + +/* Nonzero if using the pc isa card. */ + +static int using_pc; + +extern struct target_ops e7000_ops; /* Forward declaration */ + +char *ENQSTRING = "\005"; + +/* Nonzero if some routine (as opposed to the user) wants echoing. + FIXME: Do this reentrantly with an extra parameter. */ + +static int echo; + +static int ctrl_c; + +static int timeout = 20; + +/* Send data to e7000debug. */ + +static void +puts_e7000debug (char *buf) +{ + if (!e7000_desc) + error ("Use \"target e7000 ...\" first."); + + if (remote_debug) + printf_unfiltered ("Sending %s\n", buf); + + if (serial_write (e7000_desc, buf, strlen (buf))) + fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n", safe_strerror (errno)); + + /* And expect to see it echoed, unless using the pc interface */ +#if 0 + if (!using_pc) +#endif + expect (buf); +} + +static void +putchar_e7000 (int x) +{ + char b[1]; + + b[0] = x; + serial_write (e7000_desc, b, 1); +} + +static void +write_e7000 (char *s) +{ + serial_write (e7000_desc, s, strlen (s)); +} + +static int +normal (int x) +{ + if (x == '\n') + return '\r'; + return x; +} + +/* Read a character from the remote system, doing all the fancy timeout + stuff. Handles serial errors and EOF. If TIMEOUT == 0, and no chars, + returns -1, else returns next char. Discards chars > 127. */ + +static int +readchar (int timeout) +{ + int c; + + do + { + c = serial_readchar (e7000_desc, timeout); + } + while (c > 127); + + if (c == SERIAL_TIMEOUT) + { + if (timeout == 0) + return -1; + echo = 0; + error ("Timeout reading from remote system."); + } + else if (c < 0) + error ("Serial communication error"); + + if (remote_debug) + { + putchar_unfiltered (c); + gdb_flush (gdb_stdout); + } + + return normal (c); +} + +#if 0 +char * +tl (int x) +{ + static char b[8][10]; + static int p; + + p++; + p &= 7; + if (x >= ' ') + { + b[p][0] = x; + b[p][1] = 0; + } + else + { + sprintf (b[p], "<%d>", x); + } + + return b[p]; +} +#endif + +/* Scan input from the remote system, until STRING is found. If + DISCARD is non-zero, then discard non-matching input, else print it + out. Let the user break out immediately. */ + +static void +expect (char *string) +{ + char *p = string; + int c; + int nl = 0; + + while (1) + { + c = readchar (timeout); + + if (echo) + { + if (c == '\r' || c == '\n') + { + if (!nl) + putchar_unfiltered ('\n'); + nl = 1; + } + else + { + nl = 0; + putchar_unfiltered (c); + } + gdb_flush (gdb_stdout); + } + if (normal (c) == normal (*p++)) + { + if (*p == '\0') + return; + } + else + { + p = string; + + if (normal (c) == normal (string[0])) + p++; + } + } +} + +/* Keep discarding input until we see the e7000 prompt. + + The convention for dealing with the prompt is that you + o give your command + o *then* wait for the prompt. + + Thus the last thing that a procedure does with the serial line will + be an expect_prompt(). Exception: e7000_resume does not wait for + the prompt, because the terminal is being handed over to the + inferior. However, the next thing which happens after that is a + e7000_wait which does wait for the prompt. Note that this includes + abnormal exit, e.g. error(). This is necessary to prevent getting + into states from which we can't recover. */ + +static void +expect_prompt (void) +{ + expect (":"); +} + +static void +expect_full_prompt (void) +{ + expect ("\r:"); +} + +static int +convert_hex_digit (int ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + return -1; +} + +static int +get_hex (int *start) +{ + int value = convert_hex_digit (*start); + int try; + + *start = readchar (timeout); + while ((try = convert_hex_digit (*start)) >= 0) + { + value <<= 4; + value += try; + *start = readchar (timeout); + } + return value; +} + +#if 0 +/* Get N 32-bit words from remote, each preceded by a space, and put + them in registers starting at REGNO. */ + +static void +get_hex_regs (int n, int regno) +{ + long val; + int i; + + for (i = 0; i < n; i++) + { + int j; + + val = 0; + for (j = 0; j < 8; j++) + val = (val << 4) + get_hex_digit (j == 0); + supply_register (regno++, (char *) &val); + } +} +#endif + +/* This is called not only when we first attach, but also when the + user types "run" after having attached. */ + +static void +e7000_create_inferior (char *execfile, char *args, char **env) +{ + int entry_pt; + + if (args && *args) + error ("Can't pass arguments to remote E7000DEBUG process"); + + if (execfile == 0 || exec_bfd == 0) + error ("No executable file specified"); + + entry_pt = (int) bfd_get_start_address (exec_bfd); + +#ifdef CREATE_INFERIOR_HOOK + CREATE_INFERIOR_HOOK (0); /* No process-ID */ +#endif + + /* The "process" (board) is already stopped awaiting our commands, and + the program is already downloaded. We just set its PC and go. */ + + clear_proceed_status (); + + /* Tell wait_for_inferior that we've started a new process. */ + init_wait_for_inferior (); + + /* Set up the "saved terminal modes" of the inferior + based on what modes we are starting it with. */ + target_terminal_init (); + + /* Install inferior's terminal modes. */ + target_terminal_inferior (); + + /* insert_step_breakpoint (); FIXME, do we need this? */ + proceed ((CORE_ADDR) entry_pt, -1, 0); /* Let 'er rip... */ +} + +/* Open a connection to a remote debugger. NAME is the filename used + for communication. */ + +static int baudrate = 9600; +static char dev_name[100]; + +static char *machine = ""; +static char *user = ""; +static char *passwd = ""; +static char *dir = ""; + +/* Grab the next token and buy some space for it */ + +static char * +next (char **ptr) +{ + char *p = *ptr; + char *s; + char *r; + int l = 0; + + while (*p && *p == ' ') + p++; + s = p; + while (*p && (*p != ' ' && *p != '\t')) + { + l++; + p++; + } + r = xmalloc (l + 1); + memcpy (r, s, l); + r[l] = 0; + *ptr = p; + return r; +} + +static void +e7000_login_command (char *args, int from_tty) +{ + if (args) + { + machine = next (&args); + user = next (&args); + passwd = next (&args); + dir = next (&args); + if (from_tty) + { + printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir); + } + } + else + { + error ("Syntax is ftplogin "); + } +} + +/* Start an ftp transfer from the E7000 to a host */ + +static void +e7000_ftp_command (char *args, int from_tty) +{ + /* FIXME: arbitrary limit on machine names and such. */ + char buf[200]; + + int oldtimeout = timeout; + timeout = remote_timeout; + + sprintf (buf, "ftp %s\r", machine); + puts_e7000debug (buf); + expect (" Username : "); + sprintf (buf, "%s\r", user); + puts_e7000debug (buf); + expect (" Password : "); + write_e7000 (passwd); + write_e7000 ("\r"); + expect ("success\r"); + expect ("FTP>"); + sprintf (buf, "cd %s\r", dir); + puts_e7000debug (buf); + expect ("FTP>"); + sprintf (buf, "ll 0;s:%s\r", args); + puts_e7000debug (buf); + expect ("FTP>"); + puts_e7000debug ("bye\r"); + expect (":"); + timeout = oldtimeout; +} + +static int +e7000_parse_device (char *args, char *dev_name, int baudrate) +{ + char junk[128]; + int n = 0; + if (args && strcasecmp (args, "pc") == 0) + { + strcpy (dev_name, args); + using_pc = 1; + } + else + { + /* FIXME! temp hack to allow use with port master - + target tcp_remote */ + if (args && strncmp (args, "tcp", 10) == 0) + { + char com_type[128]; + n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk); + using_tcp_remote = 1; + n--; + } + else if (args) + { + n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk); + } + + if (n != 1 && n != 2) + { + error ("Bad arguments. Usage:\ttarget e7000 \n\ +or \t\ttarget e7000 [:]\n\ +or \t\ttarget e7000 tcp_remote [:]\n\ +or \t\ttarget e7000 pc\n"); + } + +#if !defined(__GO32__) && !defined(_WIN32) && !defined(__CYGWIN__) + /* FIXME! test for ':' is ambiguous */ + if (n == 1 && strchr (dev_name, ':') == 0) + { + /* Default to normal telnet port */ + /* serial_open will use this to determine tcp communication */ + strcat (dev_name, ":23"); + } +#endif + if (!using_tcp_remote && strchr (dev_name, ':')) + using_tcp = 1; + } + + return n; +} + +/* Stub for catch_errors. */ + +static int +e7000_start_remote (void *dummy) +{ + int loop; + int sync; + int try; + int quit_trying; + + immediate_quit++; /* Allow user to interrupt it */ + + /* Hello? Are you there? */ + sync = 0; + loop = 0; + try = 0; + quit_trying = 20; + putchar_e7000 (CTRLC); + while (!sync && ++try <= quit_trying) + { + int c; + + printf_unfiltered ("[waiting for e7000...]\n"); + + write_e7000 ("\r"); + c = readchar (1); + + /* FIXME! this didn't seem right-> while (c != SERIAL_TIMEOUT) + * we get stuck in this loop ... + * We may never timeout, and never sync up :-( + */ + while (!sync && c != -1) + { + /* Dont echo cr's */ + if (c != '\r') + { + putchar_unfiltered (c); + gdb_flush (gdb_stdout); + } + /* Shouldn't we either break here, or check for sync in inner loop? */ + if (c == ':') + sync = 1; + + if (loop++ == 20) + { + putchar_e7000 (CTRLC); + loop = 0; + } + + QUIT; + + if (quit_flag) + { + putchar_e7000 (CTRLC); + /* Was-> quit_flag = 0; */ + c = -1; + quit_trying = try + 1; /* we don't want to try anymore */ + } + else + { + c = readchar (1); + } + } + } + + if (!sync) + { + fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n", try); + error ("Unable to synchronize with target.\n"); + } + + puts_e7000debug ("\r"); + expect_prompt (); + puts_e7000debug ("b -\r"); /* Clear breakpoints */ + expect_prompt (); + + immediate_quit--; + +/* This is really the job of start_remote however, that makes an assumption + that the target is about to print out a status message of some sort. That + doesn't happen here. */ + + flush_cached_frames (); + registers_changed (); + stop_pc = read_pc (); + print_stack_frame (get_selected_frame (), -1, 1); + + return 1; +} + +static void +e7000_open (char *args, int from_tty) +{ + int n; + + target_preopen (from_tty); + + n = e7000_parse_device (args, dev_name, baudrate); + + push_target (&e7000_ops); + + e7000_desc = serial_open (dev_name); + + if (!e7000_desc) + perror_with_name (dev_name); + + if (serial_setbaudrate (e7000_desc, baudrate)) + { + serial_close (e7000_desc); + perror_with_name (dev_name); + } + serial_raw (e7000_desc); + + /* Start the remote connection; if error (0), discard this target. + In particular, if the user quits, be sure to discard it + (we'd be in an inconsistent state otherwise). */ + if (!catch_errors (e7000_start_remote, (char *) 0, + "Couldn't establish connection to remote target\n", RETURN_MASK_ALL)) + if (from_tty) + printf_filtered ("Remote target %s connected to %s\n", target_shortname, + dev_name); +} + +/* Close out all files and local state before this target loses control. */ + +static void +e7000_close (int quitting) +{ + if (e7000_desc) + { + serial_close (e7000_desc); + e7000_desc = 0; + } +} + +/* Terminate the open connection to the remote debugger. Use this + when you want to detach and do something else with your gdb. */ + +static void +e7000_detach (char *arg, int from_tty) +{ + pop_target (); /* calls e7000_close to do the real work */ + if (from_tty) + printf_unfiltered ("Ending remote %s debugging\n", target_shortname); +} + +/* Tell the remote machine to resume. */ + +static void +e7000_resume (ptid_t ptid, int step, enum target_signal sigal) +{ + if (step) + puts_e7000debug ("S\r"); + else + puts_e7000debug ("G\r"); +} + +/* Read the remote registers into the block REGS. + + For the H8/300 a register dump looks like: + + PC=00021A CCR=80:I******* + ER0 - ER3 0000000A 0000002E 0000002E 00000000 + ER4 - ER7 00000000 00000000 00000000 00FFEFF6 + 000218 MOV.B R1L,R2L + STEP NORMAL END or + BREAK POINT + */ + +char *want_h8300h = "PC=%p CCR=%c\n\ + ER0 - ER3 %0 %1 %2 %3\n\ + ER4 - ER7 %4 %5 %6 %7\n"; + +char *want_nopc_h8300h = "%p CCR=%c\n\ + ER0 - ER3 %0 %1 %2 %3\n\ + ER4 - ER7 %4 %5 %6 %7"; + +char *want_h8300s = "PC=%p CCR=%c\n\ + MACH=\n\ + ER0 - ER3 %0 %1 %2 %3\n\ + ER4 - ER7 %4 %5 %6 %7\n"; + +char *want_nopc_h8300s = "%p CCR=%c EXR=%9\n\ + ER0 - ER3 %0 %1 %2 %3\n\ + ER4 - ER7 %4 %5 %6 %7"; + +char *want_sh = "PC=%16 SR=%22\n\ +PR=%17 GBR=%18 VBR=%19\n\ +MACH=%20 MACL=%21\n\ +R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ +R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n"; + +char *want_nopc_sh = "%16 SR=%22\n\ + PR=%17 GBR=%18 VBR=%19\n\ + MACH=%20 MACL=%21\n\ + R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ + R8-15 %8 %9 %10 %11 %12 %13 %14 %15"; + +char *want_sh3 = "PC=%16 SR=%22\n\ +PR=%17 GBR=%18 VBR=%19\n\ +MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\ +R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ +R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\ +R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\ +R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\ +R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\ +R4_BANK1-R7_BANK1 %37 %38 %39 %40"; + +char *want_nopc_sh3 = "%16 SR=%22\n\ + PR=%17 GBR=%18 VBR=%19\n\ + MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\ + R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\ + R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\ + R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\ + R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\ + R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\ + R4_BANK1-R7_BANK1 %37 %38 %39 %40"; + +static int +gch (void) +{ + return readchar (timeout); +} + +static unsigned int +gbyte (void) +{ + int high = convert_hex_digit (gch ()); + int low = convert_hex_digit (gch ()); + + return (high << 4) + low; +} + +static void +fetch_regs_from_dump (int (*nextchar) (), char *want) +{ + int regno; + char buf[MAX_REGISTER_SIZE]; + + int thischar = nextchar (); + + if (want == NULL) + internal_error (__FILE__, __LINE__, "Register set not selected."); + + while (*want) + { + switch (*want) + { + case '\n': + /* Skip to end of line and then eat all new line type stuff */ + while (thischar != '\n' && thischar != '\r') + thischar = nextchar (); + while (thischar == '\n' || thischar == '\r') + thischar = nextchar (); + want++; + break; + + case ' ': + while (thischar == ' ' + || thischar == '\t' + || thischar == '\r' + || thischar == '\n') + thischar = nextchar (); + want++; + break; + + default: + if (*want == thischar) + { + want++; + if (*want) + thischar = nextchar (); + + } + else if (thischar == ' ' || thischar == '\n' || thischar == '\r') + { + thischar = nextchar (); + } + else + { + error ("out of sync in fetch registers wanted <%s>, got <%c 0x%x>", + want, thischar, thischar); + } + + break; + case '%': + /* Got a register command */ + want++; + switch (*want) + { +#ifdef PC_REGNUM + case 'p': + regno = PC_REGNUM; + want++; + break; +#endif +#ifdef CCR_REGNUM + case 'c': + regno = CCR_REGNUM; + want++; + break; +#endif +#ifdef SP_REGNUM + case 's': + regno = SP_REGNUM; + want++; + break; +#endif +#ifdef DEPRECATED_FP_REGNUM + case 'f': + regno = DEPRECATED_FP_REGNUM; + want++; + break; +#endif + + default: + if (isdigit (want[0])) + { + if (isdigit (want[1])) + { + regno = (want[0] - '0') * 10 + want[1] - '0'; + want += 2; + } + else + { + regno = want[0] - '0'; + want++; + } + } + + else + internal_error (__FILE__, __LINE__, "failed internal consistency check"); + } + store_signed_integer (buf, + DEPRECATED_REGISTER_RAW_SIZE (regno), + (LONGEST) get_hex (&thischar)); + supply_register (regno, buf); + break; + } + } +} + +static void +e7000_fetch_registers (void) +{ + int regno; + char *wanted = NULL; + + puts_e7000debug ("R\r"); + + if (TARGET_ARCHITECTURE->arch == bfd_arch_sh) + { + wanted = want_sh; + switch (TARGET_ARCHITECTURE->mach) + { + case bfd_mach_sh3: + case bfd_mach_sh3e: + case bfd_mach_sh4: + wanted = want_sh3; + } + } + if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300) + { + wanted = want_h8300h; + switch (TARGET_ARCHITECTURE->mach) + { + case bfd_mach_h8300s: + case bfd_mach_h8300sn: + case bfd_mach_h8300sx: + case bfd_mach_h8300sxn: + wanted = want_h8300s; + } + } + + fetch_regs_from_dump (gch, wanted); + + /* And supply the extra ones the simulator uses */ + for (regno = NUM_REALREGS; regno < NUM_REGS; regno++) + { + int buf = 0; + + supply_register (regno, (char *) (&buf)); + } +} + +/* Fetch register REGNO, or all registers if REGNO is -1. Returns + errno value. */ + +static void +e7000_fetch_register (int regno) +{ + e7000_fetch_registers (); +} + +/* Store the remote registers from the contents of the block REGS. */ + +static void +e7000_store_registers (void) +{ + int regno; + + for (regno = 0; regno < NUM_REALREGS; regno++) + e7000_store_register (regno); + + registers_changed (); +} + +/* Store register REGNO, or all if REGNO == 0. Return errno value. */ + +static void +e7000_store_register (int regno) +{ + char buf[200]; + + if (regno == -1) + { + e7000_store_registers (); + return; + } + + if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300) + { + if (regno <= 7) + { + sprintf (buf, ".ER%d %s\r", regno, phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + else if (regno == PC_REGNUM) + { + sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } +#ifdef CCR_REGNUM + else if (regno == CCR_REGNUM) + { + sprintf (buf, ".CCR %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } +#endif + } + + else if (TARGET_ARCHITECTURE->arch == bfd_arch_sh) + { + if (regno == PC_REGNUM) + { + sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + + else if (regno == SR_REGNUM) + { + sprintf (buf, ".SR %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + + else if (regno == PR_REGNUM) + { + sprintf (buf, ".PR %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + + else if (regno == GBR_REGNUM) + { + sprintf (buf, ".GBR %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + + else if (regno == VBR_REGNUM) + { + sprintf (buf, ".VBR %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + + else if (regno == MACH_REGNUM) + { + sprintf (buf, ".MACH %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + + else if (regno == MACL_REGNUM) + { + sprintf (buf, ".MACL %s\r", phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + else + { + sprintf (buf, ".R%d %s\r", regno, phex_nz (read_register (regno), 0)); + puts_e7000debug (buf); + } + } + + expect_prompt (); +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +e7000_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ +} + +static void +e7000_files_info (struct target_ops *ops) +{ + printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate); +} + +static int +stickbyte (char *where, unsigned int what) +{ + static CONST char digs[] = "0123456789ABCDEF"; + + where[0] = digs[(what >> 4) & 0xf]; + where[1] = digs[(what & 0xf) & 0xf]; + + return what; +} + +/* Write a small ammount of memory. */ + +static int +write_small (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + int i; + char buf[200]; + + for (i = 0; i < len; i++) + { + if (((memaddr + i) & 3) == 0 && (i + 3 < len)) + { + /* Can be done with a long word */ + sprintf (buf, "m %s %x%02x%02x%02x;l\r", + paddr_nz (memaddr + i), + myaddr[i], myaddr[i + 1], myaddr[i + 2], myaddr[i + 3]); + puts_e7000debug (buf); + i += 3; + } + else + { + sprintf (buf, "m %s %x\r", paddr_nz (memaddr + i), myaddr[i]); + puts_e7000debug (buf); + } + } + + expect_prompt (); + + return len; +} + +/* Write a large ammount of memory, this only works with the serial + mode enabled. Command is sent as + + il ;s:s\r -> + <- il ;s:s\r + <- ENQ + ACK -> + <- LO s\r + Srecords... + ^Z -> + <- ENQ + ACK -> + <- : + */ + +static int +write_large (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + int i; +#define maxstride 128 + int stride; + + puts_e7000debug ("IL ;S:FK\r"); + expect (ENQSTRING); + putchar_e7000 (ACK); + expect ("LO FK\r"); + + for (i = 0; i < len; i += stride) + { + char compose[maxstride * 2 + 50]; + int address = i + memaddr; + int j; + int check_sum; + int where = 0; + int alen; + + stride = len - i; + if (stride > maxstride) + stride = maxstride; + + compose[where++] = 'S'; + check_sum = 0; + if (address >= 0xffffff) + alen = 4; + else if (address >= 0xffff) + alen = 3; + else + alen = 2; + /* Insert type. */ + compose[where++] = alen - 1 + '0'; + /* Insert length. */ + check_sum += stickbyte (compose + where, alen + stride + 1); + where += 2; + while (alen > 0) + { + alen--; + check_sum += stickbyte (compose + where, address >> (8 * (alen))); + where += 2; + } + + for (j = 0; j < stride; j++) + { + check_sum += stickbyte (compose + where, myaddr[i + j]); + where += 2; + } + stickbyte (compose + where, ~check_sum); + where += 2; + compose[where++] = '\r'; + compose[where++] = '\n'; + compose[where++] = 0; + + serial_write (e7000_desc, compose, where); + j = readchar (0); + if (j == -1) + { + /* This is ok - nothing there */ + } + else if (j == ENQ) + { + /* Hmm, it's trying to tell us something */ + expect (":"); + error ("Error writing memory"); + } + else + { + printf_unfiltered ("@%d}@", j); + while ((j = readchar (0)) > 0) + { + printf_unfiltered ("@{%d}@", j); + } + } + } + + /* Send the trailer record */ + write_e7000 ("S70500000000FA\r"); + putchar_e7000 (CTRLZ); + expect (ENQSTRING); + putchar_e7000 (ACK); + expect (":"); + + return len; +} + +/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's + memory at MEMADDR. Returns length moved. + + Can't use the Srecord load over ethernet, so don't use fast method + then. */ + +static int +e7000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + if (len < 16 || using_tcp || using_pc) + return write_small (memaddr, myaddr, len); + else + return write_large (memaddr, myaddr, len); +} + +/* Read LEN bytes from inferior memory at MEMADDR. Put the result + at debugger address MYADDR. Returns length moved. + + Small transactions we send + m ;l + and receive + 00000000 12345678 ? + */ + +static int +e7000_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + int count; + int c; + int i; + char buf[200]; + /* Starting address of this pass. */ + +/* printf("READ INF %x %x %d\n", memaddr, myaddr, len); */ + if (((memaddr - 1) + len) < memaddr) + { + errno = EIO; + return 0; + } + + sprintf (buf, "m %s;l\r", paddr_nz (memaddr)); + puts_e7000debug (buf); + + for (count = 0; count < len; count += 4) + { + /* Suck away the address */ + c = gch (); + while (c != ' ') + c = gch (); + c = gch (); + if (c == '*') + { /* Some kind of error */ + puts_e7000debug (".\r"); /* Some errors leave us in memory input mode */ + expect_full_prompt (); + return -1; + } + while (c != ' ') + c = gch (); + + /* Now read in the data */ + for (i = 0; i < 4; i++) + { + int b = gbyte (); + if (count + i < len) + { + myaddr[count + i] = b; + } + } + + /* Skip the trailing ? and send a . to end and a cr for more */ + gch (); + gch (); + if (count + 4 >= len) + puts_e7000debug (".\r"); + else + puts_e7000debug ("\r"); + + } + expect_prompt (); + return len; +} + + + +/* + For large transfers we used to send + + + d \r + + and receive +
< D A T A > < ASCII CODE > + 00000000 5F FD FD FF DF 7F DF FF 01 00 01 00 02 00 08 04 "_..............." + 00000010 FF D7 FF 7F D7 F1 7F FF 00 05 00 00 08 00 40 00 "..............@." + 00000020 7F FD FF F7 7F FF FF F7 00 00 00 00 00 00 00 00 "................" + + A cost in chars for each transaction of 80 + 5*n-bytes. + + Large transactions could be done with the srecord load code, but + there is a pause for a second before dumping starts, which slows the + average rate down! + */ + +static int +e7000_read_inferior_memory_large (CORE_ADDR memaddr, unsigned char *myaddr, + int len) +{ + int count; + int c; + char buf[200]; + + /* Starting address of this pass. */ + + if (((memaddr - 1) + len) < memaddr) + { + errno = EIO; + return 0; + } + + sprintf (buf, "d %s %s\r", paddr_nz (memaddr), paddr_nz (memaddr + len - 1)); + puts_e7000debug (buf); + + count = 0; + c = gch (); + + /* skip down to the first ">" */ + while (c != '>') + c = gch (); + /* now skip to the end of that line */ + while (c != '\r') + c = gch (); + c = gch (); + + while (count < len) + { + /* get rid of any white space before the address */ + while (c <= ' ') + c = gch (); + + /* Skip the address */ + get_hex (&c); + + /* read in the bytes on the line */ + while (c != '"' && count < len) + { + if (c == ' ') + c = gch (); + else + { + myaddr[count++] = get_hex (&c); + } + } + /* throw out the rest of the line */ + while (c != '\r') + c = gch (); + } + + /* wait for the ":" prompt */ + while (c != ':') + c = gch (); + + return len; +} + +#if 0 + +static int +fast_but_for_the_pause_e7000_read_inferior_memory (CORE_ADDR memaddr, + char *myaddr, int len) +{ + int loop; + int c; + char buf[200]; + + if (((memaddr - 1) + len) < memaddr) + { + errno = EIO; + return 0; + } + + sprintf (buf, "is %x@%x:s\r", memaddr, len); + puts_e7000debug (buf); + gch (); + c = gch (); + if (c != ENQ) + { + /* Got an error */ + error ("Memory read error"); + } + putchar_e7000 (ACK); + expect ("SV s"); + loop = 1; + while (loop) + { + int type; + int length; + int addr; + int i; + + c = gch (); + switch (c) + { + case ENQ: /* ENQ, at the end */ + loop = 0; + break; + case 'S': + /* Start of an Srecord */ + type = gch (); + length = gbyte (); + switch (type) + { + case '7': /* Termination record, ignore */ + case '0': + case '8': + case '9': + /* Header record - ignore it */ + while (length--) + { + gbyte (); + } + break; + case '1': + case '2': + case '3': + { + int alen; + + alen = type - '0' + 1; + addr = 0; + while (alen--) + { + addr = (addr << 8) + gbyte (); + length--; + } + + for (i = 0; i < length - 1; i++) + myaddr[i + addr - memaddr] = gbyte (); + + gbyte (); /* Ignore checksum */ + } + } + } + } + + putchar_e7000 (ACK); + expect ("TOP ADDRESS ="); + expect ("END ADDRESS ="); + expect (":"); + + return len; +} + +#endif + +/* Transfer LEN bytes between GDB address MYADDR and target address + MEMADDR. If WRITE is non-zero, transfer them to the target, + otherwise transfer them from the target. TARGET is unused. + + Returns the number of bytes transferred. */ + +static int +e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, struct mem_attrib *attrib, + struct target_ops *target) +{ + if (write) + return e7000_write_inferior_memory (memaddr, myaddr, len); + else if (len < 16) + return e7000_read_inferior_memory (memaddr, myaddr, len); + else + return e7000_read_inferior_memory_large (memaddr, myaddr, len); +} + +static void +e7000_kill (void) +{ +} + +static void +e7000_load (char *args, int from_tty) +{ + struct cleanup *old_chain; + asection *section; + bfd *pbfd; + bfd_vma entry; +#define WRITESIZE 0x1000 + char buf[2 + 4 + 4 + WRITESIZE]; /* `DT' + + + */ + char *filename; + int quiet; + int nostart; + time_t start_time, end_time; /* Start and end times of download */ + unsigned long data_count; /* Number of bytes transferred to memory */ + int oldtimeout = timeout; + + timeout = remote_timeout; + + + /* FIXME! change test to test for type of download */ + if (!using_tcp) + { + generic_load (args, from_tty); + return; + } + + /* for direct tcp connections, we can do a fast binary download */ + buf[0] = 'D'; + buf[1] = 'T'; + quiet = 0; + nostart = 0; + filename = NULL; + + while (*args != '\000') + { + char *arg; + + while (isspace (*args)) + args++; + + arg = args; + + while ((*args != '\000') && !isspace (*args)) + args++; + + if (*args != '\000') + *args++ = '\000'; + + if (*arg != '-') + filename = arg; + else if (strncmp (arg, "-quiet", strlen (arg)) == 0) + quiet = 1; + else if (strncmp (arg, "-nostart", strlen (arg)) == 0) + nostart = 1; + else + error ("unknown option `%s'", arg); + } + + if (!filename) + filename = get_exec_file (1); + + pbfd = bfd_openr (filename, gnutarget); + if (pbfd == NULL) + { + perror_with_name (filename); + return; + } + old_chain = make_cleanup_bfd_close (pbfd); + + if (!bfd_check_format (pbfd, bfd_object)) + error ("\"%s\" is not an object file: %s", filename, + bfd_errmsg (bfd_get_error ())); + + start_time = time (NULL); + data_count = 0; + + puts_e7000debug ("mw\r"); + + expect ("\nOK"); + + for (section = pbfd->sections; section; section = section->next) + { + if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) + { + bfd_vma section_address; + bfd_size_type section_size; + file_ptr fptr; + + section_address = bfd_get_section_vma (pbfd, section); + section_size = bfd_get_section_size_before_reloc (section); + + if (!quiet) + printf_filtered ("[Loading section %s at 0x%s (%s bytes)]\n", + bfd_get_section_name (pbfd, section), + paddr_nz (section_address), + paddr_u (section_size)); + + fptr = 0; + + data_count += section_size; + + while (section_size > 0) + { + int count; + static char inds[] = "|/-\\"; + static int k = 0; + + QUIT; + + count = min (section_size, WRITESIZE); + + buf[2] = section_address >> 24; + buf[3] = section_address >> 16; + buf[4] = section_address >> 8; + buf[5] = section_address; + + buf[6] = count >> 24; + buf[7] = count >> 16; + buf[8] = count >> 8; + buf[9] = count; + + bfd_get_section_contents (pbfd, section, buf + 10, fptr, count); + + if (serial_write (e7000_desc, buf, count + 10)) + fprintf_unfiltered (gdb_stderr, + "e7000_load: serial_write failed: %s\n", + safe_strerror (errno)); + + expect ("OK"); + + if (!quiet) + { + printf_unfiltered ("\r%c", inds[k++ % 4]); + gdb_flush (gdb_stdout); + } + + section_address += count; + fptr += count; + section_size -= count; + } + } + } + + write_e7000 ("ED"); + + expect_prompt (); + + end_time = time (NULL); + +/* Finally, make the PC point at the start address */ + + if (exec_bfd) + write_pc (bfd_get_start_address (exec_bfd)); + + inferior_ptid = null_ptid; /* No process now */ + +/* This is necessary because many things were based on the PC at the time that + we attached to the monitor, which is no longer valid now that we have loaded + new code (and just changed the PC). Another way to do this might be to call + normal_stop, except that the stack may not be valid, and things would get + horribly confused... */ + + clear_symtab_users (); + + if (!nostart) + { + entry = bfd_get_start_address (pbfd); + + if (!quiet) + printf_unfiltered ("[Starting %s at 0x%s]\n", filename, paddr_nz (entry)); + +/* start_routine (entry); */ + } + + report_transfer_performance (data_count, start_time, end_time); + + do_cleanups (old_chain); + timeout = oldtimeout; +} + +/* Clean up when a program exits. + + The program actually lives on in the remote processor's RAM, and may be + run again without a download. Don't leave it full of breakpoint + instructions. */ + +static void +e7000_mourn_inferior (void) +{ + remove_breakpoints (); + unpush_target (&e7000_ops); + generic_mourn_inferior (); /* Do all the proper things now */ +} + +#define MAX_BREAKPOINTS 200 +#ifdef HARD_BREAKPOINTS +#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 : MAX_BREAKPOINTS) +#else +#define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS +#endif + +/* Since we can change to soft breakpoints dynamically, we must define + more than enough. Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */ +static CORE_ADDR breakaddr[MAX_BREAKPOINTS] = +{0}; + +static int +e7000_insert_breakpoint (CORE_ADDR addr, char *shadow) +{ + int i; + char buf[200]; +#if 0 + static char nop[2] = NOP; +#endif + + for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++) + if (breakaddr[i] == 0) + { + breakaddr[i] = addr; + /* Save old contents, and insert a nop in the space */ +#ifdef HARD_BREAKPOINTS + if (BC_BREAKPOINTS) + { + sprintf (buf, "BC%d A=%s\r", i + 1, paddr_nz (addr)); + puts_e7000debug (buf); + } + else + { + sprintf (buf, "B %s\r", paddr_nz (addr)); + puts_e7000debug (buf); + } +#else +#if 0 + e7000_read_inferior_memory (addr, shadow, 2); + e7000_write_inferior_memory (addr, nop, 2); +#endif + + sprintf (buf, "B %x\r", addr); + puts_e7000debug (buf); +#endif + expect_prompt (); + return 0; + } + + error ("Too many breakpoints ( > %d) for the E7000\n", + MAX_E7000DEBUG_BREAKPOINTS); + return 1; +} + +static int +e7000_remove_breakpoint (CORE_ADDR addr, char *shadow) +{ + int i; + char buf[200]; + + for (i = 0; i < MAX_E7000DEBUG_BREAKPOINTS; i++) + if (breakaddr[i] == addr) + { + breakaddr[i] = 0; +#ifdef HARD_BREAKPOINTS + if (BC_BREAKPOINTS) + { + sprintf (buf, "BC%d - \r", i + 1); + puts_e7000debug (buf); + } + else + { + sprintf (buf, "B - %s\r", paddr_nz (addr)); + puts_e7000debug (buf); + } + expect_prompt (); +#else + sprintf (buf, "B - %s\r", paddr_nz (addr)); + puts_e7000debug (buf); + expect_prompt (); + +#if 0 + /* Replace the insn under the break */ + e7000_write_inferior_memory (addr, shadow, 2); +#endif +#endif + + return 0; + } + + warning ("Can't find breakpoint associated with 0x%s\n", paddr_nz (addr)); + return 1; +} + +/* Put a command string, in args, out to STDBUG. Output from STDBUG + is placed on the users terminal until the prompt is seen. */ + +static void +e7000_command (char *args, int fromtty) +{ + /* FIXME: arbitrary limit on length of args. */ + char buf[200]; + + echo = 0; + + if (!e7000_desc) + error ("e7000 target not open."); + if (!args) + { + puts_e7000debug ("\r"); + } + else + { + sprintf (buf, "%s\r", args); + puts_e7000debug (buf); + } + + echo++; + ctrl_c = 2; + expect_full_prompt (); + echo--; + ctrl_c = 0; + printf_unfiltered ("\n"); + + /* Who knows what the command did... */ + registers_changed (); +} + + +static void +e7000_drain_command (char *args, int fromtty) +{ + int c; + + puts_e7000debug ("end\r"); + putchar_e7000 (CTRLC); + + while ((c = readchar (1)) != -1) + { + if (quit_flag) + { + putchar_e7000 (CTRLC); + quit_flag = 0; + } + if (c > ' ' && c < 127) + printf_unfiltered ("%c", c & 0xff); + else + printf_unfiltered ("<%x>", c & 0xff); + } +} + +#define NITEMS 7 + +static int +why_stop (void) +{ + static char *strings[NITEMS] = + { + "STEP NORMAL", + "BREAK POINT", + "BREAK KEY", + "BREAK CONDI", + "CYCLE ACCESS", + "ILLEGAL INSTRUCTION", + "WRITE PROTECT", + }; + char *p[NITEMS]; + int c; + int i; + + for (i = 0; i < NITEMS; ++i) + p[i] = strings[i]; + + c = gch (); + while (1) + { + for (i = 0; i < NITEMS; i++) + { + if (c == *(p[i])) + { + p[i]++; + if (*(p[i]) == 0) + { + /* found one of the choices */ + return i; + } + } + else + p[i] = strings[i]; + } + + c = gch (); + } +} + +/* Suck characters, if a string match, then return the strings index + otherwise echo them. */ + +static int +expect_n (char **strings) +{ + char *(ptr[10]); + int n; + int c; + char saveaway[100]; + char *buffer = saveaway; + /* Count number of expect strings */ + + for (n = 0; strings[n]; n++) + { + ptr[n] = strings[n]; + } + + while (1) + { + int i; + int gotone = 0; + + c = readchar (1); + if (c == -1) + { + printf_unfiltered ("[waiting for e7000...]\n"); + } +#ifdef __GO32__ + if (kbhit ()) + { + int k = getkey (); + + if (k == 1) + quit_flag = 1; + } +#endif + if (quit_flag) + { + putchar_e7000 (CTRLC); /* interrupt the running program */ + quit_flag = 0; + } + + for (i = 0; i < n; i++) + { + if (c == ptr[i][0]) + { + ptr[i]++; + if (ptr[i][0] == 0) + { + /* Gone all the way */ + return i; + } + gotone = 1; + } + else + { + ptr[i] = strings[i]; + } + } + + if (gotone) + { + /* Save it up incase we find that there was no match */ + *buffer++ = c; + } + else + { + if (buffer != saveaway) + { + *buffer++ = 0; + printf_unfiltered ("%s", buffer); + buffer = saveaway; + } + if (c != -1) + { + putchar_unfiltered (c); + gdb_flush (gdb_stdout); + } + } + } +} + +/* We subtract two from the pc here rather than use + DECR_PC_AFTER_BREAK since the e7000 doesn't always add two to the + pc, and the simulators never do. */ + +static void +sub2_from_pc (void) +{ + char buf[4]; + char buf2[200]; + + store_signed_integer (buf, + DEPRECATED_REGISTER_RAW_SIZE (PC_REGNUM), + read_register (PC_REGNUM) - 2); + supply_register (PC_REGNUM, buf); + sprintf (buf2, ".PC %s\r", phex_nz (read_register (PC_REGNUM), 0)); + puts_e7000debug (buf2); +} + +#define WAS_SLEEP 0 +#define WAS_INT 1 +#define WAS_RUNNING 2 +#define WAS_OTHER 3 + +static char *estrings[] = +{ + "** SLEEP", + "BREAK !", + "** PC", + "PC", + NULL +}; + +/* Wait until the remote machine stops, then return, storing status in + STATUS just as `wait' would. */ + +static ptid_t +e7000_wait (ptid_t ptid, struct target_waitstatus *status) +{ + int stop_reason; + int regno; + int running_count = 0; + int had_sleep = 0; + int loop = 1; + char *wanted_nopc = NULL; + + /* Then echo chars until PC= string seen */ + gch (); /* Drop cr */ + gch (); /* and space */ + + while (loop) + { + switch (expect_n (estrings)) + { + case WAS_OTHER: + /* how did this happen ? */ + loop = 0; + break; + case WAS_SLEEP: + had_sleep = 1; + putchar_e7000 (CTRLC); + loop = 0; + break; + case WAS_INT: + loop = 0; + break; + case WAS_RUNNING: + running_count++; + if (running_count == 20) + { + printf_unfiltered ("[running...]\n"); + running_count = 0; + } + break; + default: + /* error? */ + break; + } + } + + /* Skip till the PC= */ + expect ("="); + + if (TARGET_ARCHITECTURE->arch == bfd_arch_sh) + { + wanted_nopc = want_nopc_sh; + switch (TARGET_ARCHITECTURE->mach) + { + case bfd_mach_sh3: + case bfd_mach_sh3e: + case bfd_mach_sh4: + wanted_nopc = want_nopc_sh3; + } + } + if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300) + { + wanted_nopc = want_nopc_h8300h; + switch (TARGET_ARCHITECTURE->mach) + { + case bfd_mach_h8300s: + case bfd_mach_h8300sn: + case bfd_mach_h8300sx: + case bfd_mach_h8300sxn: + wanted_nopc = want_nopc_h8300s; + } + } + fetch_regs_from_dump (gch, wanted_nopc); + + /* And supply the extra ones the simulator uses */ + for (regno = NUM_REALREGS; regno < NUM_REGS; regno++) + { + int buf = 0; + supply_register (regno, (char *) &buf); + } + + stop_reason = why_stop (); + expect_full_prompt (); + + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = TARGET_SIGNAL_TRAP; + + switch (stop_reason) + { + case 1: /* Breakpoint */ + write_pc (read_pc ()); /* PC is always off by 2 for breakpoints */ + status->value.sig = TARGET_SIGNAL_TRAP; + break; + case 0: /* Single step */ + status->value.sig = TARGET_SIGNAL_TRAP; + break; + case 2: /* Interrupt */ + if (had_sleep) + { + status->value.sig = TARGET_SIGNAL_TRAP; + sub2_from_pc (); + } + else + { + status->value.sig = TARGET_SIGNAL_INT; + } + break; + case 3: + break; + case 4: + printf_unfiltered ("a cycle address error?\n"); + status->value.sig = TARGET_SIGNAL_UNKNOWN; + break; + case 5: + status->value.sig = TARGET_SIGNAL_ILL; + break; + case 6: + status->value.sig = TARGET_SIGNAL_SEGV; + break; + case 7: /* Anything else (NITEMS + 1) */ + printf_unfiltered ("a write protect error?\n"); + status->value.sig = TARGET_SIGNAL_UNKNOWN; + break; + default: + /* Get the user's attention - this should never happen. */ + internal_error (__FILE__, __LINE__, "failed internal consistency check"); + } + + return inferior_ptid; +} + +/* Stop the running program. */ + +static void +e7000_stop (void) +{ + /* Sending a ^C is supposed to stop the running program. */ + putchar_e7000 (CTRLC); +} + +/* Define the target subroutine names. */ + +struct target_ops e7000_ops; + +static void +init_e7000_ops (void) +{ + e7000_ops.to_shortname = "e7000"; + e7000_ops.to_longname = "Remote Renesas e7000 target"; + e7000_ops.to_doc = "Use a remote Renesas e7000 ICE connected by a serial line;\n\ +or a network connection.\n\ +Arguments are the name of the device for the serial line,\n\ +the speed to connect at in bits per second.\n\ +eg\n\ +target e7000 /dev/ttya 9600\n\ +target e7000 foobar"; + e7000_ops.to_open = e7000_open; + e7000_ops.to_close = e7000_close; + e7000_ops.to_detach = e7000_detach; + e7000_ops.to_resume = e7000_resume; + e7000_ops.to_wait = e7000_wait; + e7000_ops.to_fetch_registers = e7000_fetch_register; + e7000_ops.to_store_registers = e7000_store_register; + e7000_ops.to_prepare_to_store = e7000_prepare_to_store; + e7000_ops.to_xfer_memory = e7000_xfer_inferior_memory; + e7000_ops.to_files_info = e7000_files_info; + e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint; + e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint; + e7000_ops.to_kill = e7000_kill; + e7000_ops.to_load = e7000_load; + e7000_ops.to_create_inferior = e7000_create_inferior; + e7000_ops.to_mourn_inferior = e7000_mourn_inferior; + e7000_ops.to_stop = e7000_stop; + e7000_ops.to_stratum = process_stratum; + e7000_ops.to_has_all_memory = 1; + e7000_ops.to_has_memory = 1; + e7000_ops.to_has_stack = 1; + e7000_ops.to_has_registers = 1; + e7000_ops.to_has_execution = 1; + e7000_ops.to_magic = OPS_MAGIC; +}; + +extern initialize_file_ftype _initialize_remote_e7000; /* -Wmissing-prototypes */ + +void +_initialize_remote_e7000 (void) +{ + init_e7000_ops (); + add_target (&e7000_ops); + + add_com ("e7000", class_obscure, e7000_command, + "Send a command to the e7000 monitor."); + + add_com ("ftplogin", class_obscure, e7000_login_command, + "Login to machine and change to directory."); + + add_com ("ftpload", class_obscure, e7000_ftp_command, + "Fetch and load a file from previously described place."); + + add_com ("drain", class_obscure, e7000_drain_command, + "Drain pending e7000 text buffers."); + + add_show_from_set (add_set_cmd ("usehardbreakpoints", no_class, + var_integer, (char *) &use_hard_breakpoints, + "Set use of hardware breakpoints for all breakpoints.\n", &setlist), + &showlist); +} diff --git a/contrib/gdb/gdb/remote-est.c b/contrib/gdb/gdb/remote-est.c new file mode 100644 index 00000000000..a2c0f7ce2af --- /dev/null +++ b/contrib/gdb/gdb/remote-est.c @@ -0,0 +1,186 @@ +/* Remote debugging interface for EST-300 ICE, for GDB + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + Contributed by Cygnus Support. + + Written by Steve Chamberlain for Cygnus Support. + Re-written by Stu Grossman of Cygnus Support + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "monitor.h" +#include "serial.h" +#include "regcache.h" + +#include "m68k-tdep.h" + +static void est_open (char *args, int from_tty); + +static void +est_supply_register (char *regname, int regnamelen, char *val, int vallen) +{ + int regno; + + if (regnamelen != 2) + return; + + switch (regname[0]) + { + case 'S': + if (regname[1] != 'R') + return; + regno = PS_REGNUM; + break; + case 'P': + if (regname[1] != 'C') + return; + regno = PC_REGNUM; + break; + case 'D': + if (regname[1] < '0' || regname[1] > '7') + return; + regno = regname[1] - '0' + M68K_D0_REGNUM; + break; + case 'A': + if (regname[1] < '0' || regname[1] > '7') + return; + regno = regname[1] - '0' + M68K_A0_REGNUM; + break; + default: + return; + } + + monitor_supply_register (regno, val); +} + +/* + * This array of registers needs to match the indexes used by GDB. The + * whole reason this exists is because the various ROM monitors use + * different names than GDB does, and don't support all the + * registers either. So, typing "info reg sp" becomes a "r30". + */ + +static const char * +est_regname (int index) +{ + + static char *regnames[] = + { + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", + "SR", "PC", + }; + + + if ((index >= (sizeof (regnames) / sizeof (regnames[0]))) + || (index < 0) || (index >= NUM_REGS)) + return NULL; + else + return regnames[index]; +} + +/* + * Define the monitor command strings. Since these are passed directly + * through to a printf style function, we need can include formatting + * strings. We also need a CR or LF on the end. + */ + +static struct target_ops est_ops; + +static char *est_inits[] = +{"he\r", /* Resets the prompt, and clears repeated cmds */ + NULL}; + +static struct monitor_ops est_cmds; + +static void +init_est_cmds (void) +{ + est_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT | + MO_SREC_ACK | MO_SREC_ACK_PLUS; + est_cmds.init = est_inits; /* Init strings */ + est_cmds.cont = "go\r"; /* continue command */ + est_cmds.step = "sidr\r"; /* single step */ + est_cmds.stop = "\003"; /* ^C interrupts the program */ + est_cmds.set_break = "sb %x\r"; /* set a breakpoint */ + est_cmds.clr_break = "rb %x\r"; /* clear a breakpoint */ + est_cmds.clr_all_break = "rb\r"; /* clear all breakpoints */ + est_cmds.fill = "bfb %x %x %x\r"; /* fill (start end val) */ + est_cmds.setmem.cmdb = "smb %x %x\r"; /* setmem.cmdb (addr, value) */ + est_cmds.setmem.cmdw = "smw %x %x\r"; /* setmem.cmdw (addr, value) */ + est_cmds.setmem.cmdl = "sml %x %x\r"; /* setmem.cmdl (addr, value) */ + est_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ + est_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ + est_cmds.setmem.term = NULL; /* setreg.term */ + est_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ + est_cmds.getmem.cmdb = "dmb %x %x\r"; /* getmem.cmdb (addr, len) */ + est_cmds.getmem.cmdw = "dmw %x %x\r"; /* getmem.cmdw (addr, len) */ + est_cmds.getmem.cmdl = "dml %x %x\r"; /* getmem.cmdl (addr, len) */ + est_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ + est_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ + est_cmds.getmem.term = NULL; /* getmem.term */ + est_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ + est_cmds.setreg.cmd = "sr %s %x\r"; /* setreg.cmd (name, value) */ + est_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ + est_cmds.setreg.term = NULL; /* setreg.term */ + est_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ + est_cmds.getreg.cmd = "dr %s\r"; /* getreg.cmd (name) */ + est_cmds.getreg.resp_delim = " = "; /* getreg.resp_delim */ + est_cmds.getreg.term = NULL; /* getreg.term */ + est_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ + est_cmds.dump_registers = "dr\r"; /* dump_registers */ + est_cmds.register_pattern = "\\(\\w+\\) = \\([0-9a-fA-F]+\\)"; /* register_pattern */ + est_cmds.supply_register = est_supply_register; /* supply_register */ + est_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ + est_cmds.load = "dl\r"; /* download command */ + est_cmds.loadresp = "+"; /* load response */ + est_cmds.prompt = ">BKM>"; /* monitor command prompt */ + est_cmds.line_term = "\r"; /* end-of-line terminator */ + est_cmds.cmd_end = NULL; /* optional command terminator */ + est_cmds.target = &est_ops; /* target operations */ + est_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ + est_cmds.regnames = NULL; + est_cmds.regname = est_regname; /*register names*/ + est_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ +} /* init_est_cmds */ + +static void +est_open (char *args, int from_tty) +{ + monitor_open (args, &est_cmds, from_tty); +} + +extern initialize_file_ftype _initialize_est; /* -Wmissing-prototypes */ + +void +_initialize_est (void) +{ + init_est_cmds (); + init_monitor_ops (&est_ops); + + est_ops.to_shortname = "est"; + est_ops.to_longname = "EST background debug monitor"; + est_ops.to_doc = "Debug via the EST BDM.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + est_ops.to_open = est_open; + + add_target (&est_ops); +} diff --git a/contrib/gdb/gdb/remote-fileio.c b/contrib/gdb/gdb/remote-fileio.c new file mode 100644 index 00000000000..281872ec6c0 --- /dev/null +++ b/contrib/gdb/gdb/remote-fileio.c @@ -0,0 +1,1384 @@ +/* Remote File-I/O communications + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* See the GDB User Guide for details of the GDB remote protocol. */ + +#include "defs.h" +#include "gdb_string.h" +#include "gdbcmd.h" +#include "remote.h" +#include "gdb/fileio.h" +#include "gdb_wait.h" +#include "gdb_stat.h" +#include "remote-fileio.h" + +#include +#include +#ifdef __CYGWIN__ +#include /* For cygwin_conv_to_full_posix_path. */ +#endif +#include + +static struct { + int *fd_map; + int fd_map_size; +} remote_fio_data; + +#define FIO_FD_INVALID -1 +#define FIO_FD_CONSOLE_IN -2 +#define FIO_FD_CONSOLE_OUT -3 + +static int remote_fio_system_call_allowed = 0; + +static int +remote_fileio_init_fd_map (void) +{ + int i; + + if (!remote_fio_data.fd_map) + { + remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int)); + remote_fio_data.fd_map_size = 10; + remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN; + remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT; + remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT; + for (i = 3; i < 10; ++i) + remote_fio_data.fd_map[i] = FIO_FD_INVALID; + } + return 3; +} + +static int +remote_fileio_resize_fd_map (void) +{ + if (!remote_fio_data.fd_map) + return remote_fileio_init_fd_map (); + remote_fio_data.fd_map_size += 10; + remote_fio_data.fd_map = + (int *) xrealloc (remote_fio_data.fd_map, + remote_fio_data.fd_map_size * sizeof (int)); + return remote_fio_data.fd_map_size - 10; +} + +static int +remote_fileio_next_free_fd (void) +{ + int i; + + for (i = 0; i < remote_fio_data.fd_map_size; ++i) + if (remote_fio_data.fd_map[i] == FIO_FD_INVALID) + return i; + return remote_fileio_resize_fd_map (); +} + +static int +remote_fileio_fd_to_targetfd (int fd) +{ + int target_fd = remote_fileio_next_free_fd (); + remote_fio_data.fd_map[target_fd] = fd; + return target_fd; +} + +static int +remote_fileio_map_fd (int target_fd) +{ + remote_fileio_init_fd_map (); + if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size) + return FIO_FD_INVALID; + return remote_fio_data.fd_map[target_fd]; +} + +static void +remote_fileio_close_target_fd (int target_fd) +{ + remote_fileio_init_fd_map (); + if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size) + remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID; +} + +static int +remote_fileio_oflags_to_host (long flags) +{ + int hflags = 0; + + if (flags & FILEIO_O_CREAT) + hflags |= O_CREAT; + if (flags & FILEIO_O_EXCL) + hflags |= O_EXCL; + if (flags & FILEIO_O_TRUNC) + hflags |= O_TRUNC; + if (flags & FILEIO_O_APPEND) + hflags |= O_APPEND; + if (flags & FILEIO_O_RDONLY) + hflags |= O_RDONLY; + if (flags & FILEIO_O_WRONLY) + hflags |= O_WRONLY; + if (flags & FILEIO_O_RDWR) + hflags |= O_RDWR; +/* On systems supporting binary and text mode, always open files in + binary mode. */ +#ifdef O_BINARY + hflags |= O_BINARY; +#endif + return hflags; +} + +static mode_t +remote_fileio_mode_to_host (long mode, int open_call) +{ + mode_t hmode = 0; + + if (!open_call) + { + if (mode & FILEIO_S_IFREG) + hmode |= S_IFREG; + if (mode & FILEIO_S_IFDIR) + hmode |= S_IFDIR; + if (mode & FILEIO_S_IFCHR) + hmode |= S_IFCHR; + } + if (mode & FILEIO_S_IRUSR) + hmode |= S_IRUSR; + if (mode & FILEIO_S_IWUSR) + hmode |= S_IWUSR; + if (mode & FILEIO_S_IXUSR) + hmode |= S_IXUSR; + if (mode & FILEIO_S_IRGRP) + hmode |= S_IRGRP; + if (mode & FILEIO_S_IWGRP) + hmode |= S_IWGRP; + if (mode & FILEIO_S_IXGRP) + hmode |= S_IXGRP; + if (mode & FILEIO_S_IROTH) + hmode |= S_IROTH; + if (mode & FILEIO_S_IWOTH) + hmode |= S_IWOTH; + if (mode & FILEIO_S_IXOTH) + hmode |= S_IXOTH; + return hmode; +} + +static LONGEST +remote_fileio_mode_to_target (mode_t mode) +{ + mode_t tmode = 0; + + if (mode & S_IFREG) + tmode |= FILEIO_S_IFREG; + if (mode & S_IFDIR) + tmode |= FILEIO_S_IFDIR; + if (mode & S_IFCHR) + tmode |= FILEIO_S_IFCHR; + if (mode & S_IRUSR) + tmode |= FILEIO_S_IRUSR; + if (mode & S_IWUSR) + tmode |= FILEIO_S_IWUSR; + if (mode & S_IXUSR) + tmode |= FILEIO_S_IXUSR; + if (mode & S_IRGRP) + tmode |= FILEIO_S_IRGRP; + if (mode & S_IWGRP) + tmode |= FILEIO_S_IWGRP; + if (mode & S_IXGRP) + tmode |= FILEIO_S_IXGRP; + if (mode & S_IROTH) + tmode |= FILEIO_S_IROTH; + if (mode & S_IWOTH) + tmode |= FILEIO_S_IWOTH; + if (mode & S_IXOTH) + tmode |= FILEIO_S_IXOTH; + return tmode; +} + +static int +remote_fileio_errno_to_target (int error) +{ + switch (error) + { + case EPERM: + return FILEIO_EPERM; + case ENOENT: + return FILEIO_ENOENT; + case EINTR: + return FILEIO_EINTR; + case EIO: + return FILEIO_EIO; + case EBADF: + return FILEIO_EBADF; + case EACCES: + return FILEIO_EACCES; + case EFAULT: + return FILEIO_EFAULT; + case EBUSY: + return FILEIO_EBUSY; + case EEXIST: + return FILEIO_EEXIST; + case ENODEV: + return FILEIO_ENODEV; + case ENOTDIR: + return FILEIO_ENOTDIR; + case EISDIR: + return FILEIO_EISDIR; + case EINVAL: + return FILEIO_EINVAL; + case ENFILE: + return FILEIO_ENFILE; + case EMFILE: + return FILEIO_EMFILE; + case EFBIG: + return FILEIO_EFBIG; + case ENOSPC: + return FILEIO_ENOSPC; + case ESPIPE: + return FILEIO_ESPIPE; + case EROFS: + return FILEIO_EROFS; + case ENOSYS: + return FILEIO_ENOSYS; + case ENAMETOOLONG: + return FILEIO_ENAMETOOLONG; + } + return FILEIO_EUNKNOWN; +} + +static int +remote_fileio_seek_flag_to_host (long num, int *flag) +{ + if (!flag) + return 0; + switch (num) + { + case FILEIO_SEEK_SET: + *flag = SEEK_SET; + break; + case FILEIO_SEEK_CUR: + *flag = SEEK_CUR; + break; + case FILEIO_SEEK_END: + *flag = SEEK_END; + break; + default: + return -1; + } + return 0; +} + +static int +remote_fileio_extract_long (char **buf, LONGEST *retlong) +{ + char *c; + int sign = 1; + + if (!buf || !*buf || !**buf || !retlong) + return -1; + c = strchr (*buf, ','); + if (c) + *c++ = '\0'; + else + c = strchr (*buf, '\0'); + while (strchr ("+-", **buf)) + { + if (**buf == '-') + sign = -sign; + ++*buf; + } + for (*retlong = 0; **buf; ++*buf) + { + *retlong <<= 4; + if (**buf >= '0' && **buf <= '9') + *retlong += **buf - '0'; + else if (**buf >= 'a' && **buf <= 'f') + *retlong += **buf - 'a' + 10; + else if (**buf >= 'A' && **buf <= 'F') + *retlong += **buf - 'A' + 10; + else + return -1; + } + *retlong *= sign; + *buf = c; + return 0; +} + +static int +remote_fileio_extract_int (char **buf, long *retint) +{ + int ret; + LONGEST retlong; + + if (!retint) + return -1; + ret = remote_fileio_extract_long (buf, &retlong); + if (!ret) + *retint = (long) retlong; + return ret; +} + +static int +remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length) +{ + char *c; + LONGEST retlong; + + if (!buf || !*buf || !**buf || !ptrval || !length) + return -1; + c = strchr (*buf, '/'); + if (!c) + return -1; + *c++ = '\0'; + if (remote_fileio_extract_long (buf, &retlong)) + return -1; + *ptrval = (CORE_ADDR) retlong; + *buf = c; + if (remote_fileio_extract_long (buf, &retlong)) + return -1; + *length = (int) retlong; + return 0; +} + +/* Convert to big endian */ +static void +remote_fileio_to_be (LONGEST num, char *buf, int bytes) +{ + int i; + + for (i = 0; i < bytes; ++i) + buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff; +} + +static void +remote_fileio_to_fio_uint (long num, fio_uint_t fnum) +{ + remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4); +} + +static void +remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum) +{ + remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4); +} + +static void +remote_fileio_to_fio_time (time_t num, fio_time_t fnum) +{ + remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4); +} + +static void +remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum) +{ + remote_fileio_to_be (num, (char *) fnum, 8); +} + +static void +remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum) +{ + remote_fileio_to_be (num, (char *) fnum, 8); +} + +static void +remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst) +{ + /* `st_dev' is set in the calling function */ + remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino); + remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode); + remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink); + remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid); + remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid); + remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev); + remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size); + remote_fileio_to_fio_ulong ((LONGEST) st->st_blksize, fst->fst_blksize); +#if HAVE_STRUCT_STAT_ST_BLOCKS + remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks); +#else + /* FIXME: This is correct for DJGPP, but other systems that don't + have st_blocks, if any, might prefer 512 instead of st_blksize. + (eliz, 30-12-2003) */ + remote_fileio_to_fio_ulong (((LONGEST) st->st_size + st->st_blksize - 1) + / (LONGEST) st->st_blksize, + fst->fst_blocks); +#endif + remote_fileio_to_fio_time (st->st_atime, fst->fst_atime); + remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime); + remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime); +} + +static void +remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv) +{ + remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec); + remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec); +} + +static int remote_fio_ctrl_c_flag = 0; +static int remote_fio_no_longjmp = 0; + +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) +static struct sigaction remote_fio_sa; +static struct sigaction remote_fio_osa; +#else +static void (*remote_fio_ofunc)(int); +#endif + +static void +remote_fileio_sig_init (void) +{ +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + remote_fio_sa.sa_handler = SIG_IGN; + sigemptyset (&remote_fio_sa.sa_mask); + remote_fio_sa.sa_flags = 0; + sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa); +#else + remote_fio_ofunc = signal (SIGINT, SIG_IGN); +#endif +} + +static void +remote_fileio_sig_set (void (*sigint_func)(int)) +{ +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + remote_fio_sa.sa_handler = sigint_func; + sigemptyset (&remote_fio_sa.sa_mask); + remote_fio_sa.sa_flags = 0; + sigaction (SIGINT, &remote_fio_sa, NULL); +#else + signal (SIGINT, sigint_func); +#endif +} + +static void +remote_fileio_sig_exit (void) +{ +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + sigaction (SIGINT, &remote_fio_osa, NULL); +#else + signal (SIGINT, remote_fio_ofunc); +#endif +} + +static void +remote_fileio_ctrl_c_signal_handler (int signo) +{ + remote_fileio_sig_set (SIG_IGN); + remote_fio_ctrl_c_flag = 1; + if (!remote_fio_no_longjmp) + throw_exception (RETURN_QUIT); + remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler); +} + +static void +remote_fileio_reply (int retcode, int error) +{ + char buf[32]; + + remote_fileio_sig_set (SIG_IGN); + strcpy (buf, "F"); + if (retcode < 0) + { + strcat (buf, "-"); + retcode = -retcode; + } + sprintf (buf + strlen (buf), "%x", retcode); + if (error || remote_fio_ctrl_c_flag) + { + if (error && remote_fio_ctrl_c_flag) + error = FILEIO_EINTR; + if (error < 0) + { + strcat (buf, "-"); + error = -error; + } + sprintf (buf + strlen (buf), ",%x", error); + if (remote_fio_ctrl_c_flag) + strcat (buf, ",C"); + } + remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler); + putpkt (buf); +} + +static void +remote_fileio_ioerror (void) +{ + remote_fileio_reply (-1, FILEIO_EIO); +} + +static void +remote_fileio_badfd (void) +{ + remote_fileio_reply (-1, FILEIO_EBADF); +} + +static void +remote_fileio_return_errno (int retcode) +{ + remote_fileio_reply (retcode, + retcode < 0 ? remote_fileio_errno_to_target (errno) : 0); +} + +static void +remote_fileio_return_success (int retcode) +{ + remote_fileio_reply (retcode, 0); +} + +/* Wrapper function for remote_write_bytes() which has the disadvantage to + write only one packet, regardless of the requested number of bytes to + transfer. This wrapper calls remote_write_bytes() as often as needed. */ +static int +remote_fileio_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) +{ + int ret = 0, written; + + while (len > 0 && (written = remote_write_bytes (memaddr, myaddr, len)) > 0) + { + len -= written; + memaddr += written; + myaddr += written; + ret += written; + } + return ret; +} + +static void +remote_fileio_func_open (char *buf) +{ + CORE_ADDR ptrval; + int length, retlength; + long num; + int flags, fd; + mode_t mode; + char *pathname; + struct stat st; + + /* 1. Parameter: Ptr to pathname / length incl. trailing zero */ + if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length)) + { + remote_fileio_ioerror (); + return; + } + /* 2. Parameter: open flags */ + if (remote_fileio_extract_int (&buf, &num)) + { + remote_fileio_ioerror (); + return; + } + flags = remote_fileio_oflags_to_host (num); + /* 3. Parameter: open mode */ + if (remote_fileio_extract_int (&buf, &num)) + { + remote_fileio_ioerror (); + return; + } + mode = remote_fileio_mode_to_host (num, 1); + + /* Request pathname using 'm' packet */ + pathname = alloca (length); + retlength = remote_read_bytes (ptrval, pathname, length); + if (retlength != length) + { + remote_fileio_ioerror (); + return; + } + + /* Check if pathname exists and is not a regular file or directory. If so, + return an appropriate error code. Same for trying to open directories + for writing. */ + if (!stat (pathname, &st)) + { + if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)) + { + remote_fileio_reply (-1, FILEIO_ENODEV); + return; + } + if (S_ISDIR (st.st_mode) + && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR)) + { + remote_fileio_reply (-1, FILEIO_EISDIR); + return; + } + } + + remote_fio_no_longjmp = 1; + fd = open (pathname, flags, mode); + if (fd < 0) + { + remote_fileio_return_errno (-1); + return; + } + + fd = remote_fileio_fd_to_targetfd (fd); + remote_fileio_return_success (fd); +} + +static void +remote_fileio_func_close (char *buf) +{ + long num; + int fd; + + /* Parameter: file descriptor */ + if (remote_fileio_extract_int (&buf, &num)) + { + remote_fileio_ioerror (); + return; + } + fd = remote_fileio_map_fd ((int) num); + if (fd == FIO_FD_INVALID) + { + remote_fileio_badfd (); + return; + } + + remote_fio_no_longjmp = 1; + if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd)) + remote_fileio_return_errno (-1); + remote_fileio_close_target_fd ((int) num); + remote_fileio_return_success (0); +} + +static void +remote_fileio_func_read (char *buf) +{ + long target_fd, num; + LONGEST lnum; + CORE_ADDR ptrval; + int fd, ret, retlength; + char *buffer; + size_t length; + off_t old_offset, new_offset; + + /* 1. Parameter: file descriptor */ + if (remote_fileio_extract_int (&buf, &target_fd)) + { + remote_fileio_ioerror (); + return; + } + fd = remote_fileio_map_fd ((int) target_fd); + if (fd == FIO_FD_INVALID) + { + remote_fileio_badfd (); + return; + } + /* 2. Parameter: buffer pointer */ + if (remote_fileio_extract_long (&buf, &lnum)) + { + remote_fileio_ioerror (); + return; + } + ptrval = (CORE_ADDR) lnum; + /* 3. Parameter: buffer length */ + if (remote_fileio_extract_int (&buf, &num)) + { + remote_fileio_ioerror (); + return; + } + length = (size_t) num; + + switch (fd) + { + case FIO_FD_CONSOLE_OUT: + remote_fileio_badfd (); + return; + case FIO_FD_CONSOLE_IN: + { + static char *remaining_buf = NULL; + static int remaining_length = 0; + + buffer = (char *) xmalloc (32768); + if (remaining_buf) + { + remote_fio_no_longjmp = 1; + if (remaining_length > length) + { + memcpy (buffer, remaining_buf, length); + memmove (remaining_buf, remaining_buf + length, + remaining_length - length); + remaining_length -= length; + ret = length; + } + else + { + memcpy (buffer, remaining_buf, remaining_length); + xfree (remaining_buf); + remaining_buf = NULL; + ret = remaining_length; + } + } + else + { + ret = ui_file_read (gdb_stdtargin, buffer, 32767); + remote_fio_no_longjmp = 1; + if (ret > 0 && (size_t)ret > length) + { + remaining_buf = (char *) xmalloc (ret - length); + remaining_length = ret - length; + memcpy (remaining_buf, buffer + length, remaining_length); + ret = length; + } + } + } + break; + default: + buffer = (char *) xmalloc (length); + /* POSIX defines EINTR behaviour of read in a weird way. It's allowed + for read() to return -1 even if "some" bytes have been read. It + has been corrected in SUSv2 but that doesn't help us much... + Therefore a complete solution must check how many bytes have been + read on EINTR to return a more reliable value to the target */ + old_offset = lseek (fd, 0, SEEK_CUR); + remote_fio_no_longjmp = 1; + ret = read (fd, buffer, length); + if (ret < 0 && errno == EINTR) + { + new_offset = lseek (fd, 0, SEEK_CUR); + /* If some data has been read, return the number of bytes read. + The Ctrl-C flag is set in remote_fileio_reply() anyway */ + if (old_offset != new_offset) + ret = new_offset - old_offset; + } + break; + } + + if (ret > 0) + { + retlength = remote_fileio_write_bytes (ptrval, buffer, ret); + if (retlength != ret) + ret = -1; /* errno has been set to EIO in remote_fileio_write_bytes() */ + } + + if (ret < 0) + remote_fileio_return_errno (-1); + else + remote_fileio_return_success (ret); + + xfree (buffer); +} + +static void +remote_fileio_func_write (char *buf) +{ + long target_fd, num; + LONGEST lnum; + CORE_ADDR ptrval; + int fd, ret, retlength; + char *buffer; + size_t length; + + /* 1. Parameter: file descriptor */ + if (remote_fileio_extract_int (&buf, &target_fd)) + { + remote_fileio_ioerror (); + return; + } + fd = remote_fileio_map_fd ((int) target_fd); + if (fd == FIO_FD_INVALID) + { + remote_fileio_badfd (); + return; + } + /* 2. Parameter: buffer pointer */ + if (remote_fileio_extract_long (&buf, &lnum)) + { + remote_fileio_ioerror (); + return; + } + ptrval = (CORE_ADDR) lnum; + /* 3. Parameter: buffer length */ + if (remote_fileio_extract_int (&buf, &num)) + { + remote_fileio_ioerror (); + return; + } + length = (size_t) num; + + buffer = (char *) xmalloc (length); + retlength = remote_read_bytes (ptrval, buffer, length); + if (retlength != length) + { + xfree (buffer); + remote_fileio_ioerror (); + return; + } + + remote_fio_no_longjmp = 1; + switch (fd) + { + case FIO_FD_CONSOLE_IN: + remote_fileio_badfd (); + return; + case FIO_FD_CONSOLE_OUT: + ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr, buffer, + length); + gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr); + ret = length; + break; + default: + ret = write (fd, buffer, length); + if (ret < 0 && errno == EACCES) + errno = EBADF; /* Cygwin returns EACCESS when writing to a R/O file.*/ + break; + } + + if (ret < 0) + remote_fileio_return_errno (-1); + else + remote_fileio_return_success (ret); + + xfree (buffer); +} + +static void +remote_fileio_func_lseek (char *buf) +{ + long num; + LONGEST lnum; + int fd, flag; + off_t offset, ret; + + /* 1. Parameter: file descriptor */ + if (remote_fileio_extract_int (&buf, &num)) + { + remote_fileio_ioerror (); + return; + } + fd = remote_fileio_map_fd ((int) num); + if (fd == FIO_FD_INVALID) + { + remote_fileio_badfd (); + return; + } + else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT) + { + remote_fileio_reply (-1, FILEIO_ESPIPE); + return; + } + + /* 2. Parameter: offset */ + if (remote_fileio_extract_long (&buf, &lnum)) + { + remote_fileio_ioerror (); + return; + } + offset = (off_t) lnum; + /* 3. Parameter: flag */ + if (remote_fileio_extract_int (&buf, &num)) + { + remote_fileio_ioerror (); + return; + } + if (remote_fileio_seek_flag_to_host (num, &flag)) + { + remote_fileio_reply (-1, FILEIO_EINVAL); + return; + } + + remote_fio_no_longjmp = 1; + ret = lseek (fd, offset, flag); + + if (ret == (off_t) -1) + remote_fileio_return_errno (-1); + else + remote_fileio_return_success (ret); +} + +static void +remote_fileio_func_rename (char *buf) +{ + CORE_ADDR ptrval; + int length, retlength; + char *oldpath, *newpath; + int ret, of, nf; + struct stat ost, nst; + + /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */ + if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length)) + { + remote_fileio_ioerror (); + return; + } + /* Request oldpath using 'm' packet */ + oldpath = alloca (length); + retlength = remote_read_bytes (ptrval, oldpath, length); + if (retlength != length) + { + remote_fileio_ioerror (); + return; + } + /* 2. Parameter: Ptr to newpath / length incl. trailing zero */ + if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length)) + { + remote_fileio_ioerror (); + return; + } + /* Request newpath using 'm' packet */ + newpath = alloca (length); + retlength = remote_read_bytes (ptrval, newpath, length); + if (retlength != length) + { + remote_fileio_ioerror (); + return; + } + + /* Only operate on regular files and directories */ + of = stat (oldpath, &ost); + nf = stat (newpath, &nst); + if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode)) + || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode))) + { + remote_fileio_reply (-1, FILEIO_EACCES); + return; + } + + remote_fio_no_longjmp = 1; + ret = rename (oldpath, newpath); + + if (ret == -1) + { + /* Special case: newpath is a non-empty directory. Some systems + return ENOTEMPTY, some return EEXIST. We coerce that to be + always EEXIST. */ + if (errno == ENOTEMPTY) + errno = EEXIST; +#ifdef __CYGWIN__ + /* Workaround some Cygwin problems with correct errnos. */ + if (errno == EACCES) + { + if (!of && !nf && S_ISDIR (nst.st_mode)) + { + if (S_ISREG (ost.st_mode)) + errno = EISDIR; + else + { + char oldfullpath[PATH_MAX + 1]; + char newfullpath[PATH_MAX + 1]; + int len; + + cygwin_conv_to_full_posix_path (oldpath, oldfullpath); + cygwin_conv_to_full_posix_path (newpath, newfullpath); + len = strlen (oldfullpath); + if (newfullpath[len] == '/' + && !strncmp (oldfullpath, newfullpath, len)) + errno = EINVAL; + else + errno = EEXIST; + } + } + } +#endif + + remote_fileio_return_errno (-1); + } + else + remote_fileio_return_success (ret); +} + +static void +remote_fileio_func_unlink (char *buf) +{ + CORE_ADDR ptrval; + int length, retlength; + char *pathname; + int ret; + struct stat st; + + /* Parameter: Ptr to pathname / length incl. trailing zero */ + if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length)) + { + remote_fileio_ioerror (); + return; + } + /* Request pathname using 'm' packet */ + pathname = alloca (length); + retlength = remote_read_bytes (ptrval, pathname, length); + if (retlength != length) + { + remote_fileio_ioerror (); + return; + } + + /* Only operate on regular files (and directories, which allows to return + the correct return code) */ + if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)) + { + remote_fileio_reply (-1, FILEIO_ENODEV); + return; + } + + remote_fio_no_longjmp = 1; + ret = unlink (pathname); + + if (ret == -1) + remote_fileio_return_errno (-1); + else + remote_fileio_return_success (ret); +} + +static void +remote_fileio_func_stat (char *buf) +{ + CORE_ADDR ptrval; + int ret, length, retlength; + char *pathname; + LONGEST lnum; + struct stat st; + struct fio_stat fst; + + /* 1. Parameter: Ptr to pathname / length incl. trailing zero */ + if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length)) + { + remote_fileio_ioerror (); + return; + } + /* Request pathname using 'm' packet */ + pathname = alloca (length); + retlength = remote_read_bytes (ptrval, pathname, length); + if (retlength != length) + { + remote_fileio_ioerror (); + return; + } + + /* 2. Parameter: Ptr to struct stat */ + if (remote_fileio_extract_long (&buf, &lnum)) + { + remote_fileio_ioerror (); + return; + } + ptrval = (CORE_ADDR) lnum; + + remote_fio_no_longjmp = 1; + ret = stat (pathname, &st); + + if (ret == -1) + { + remote_fileio_return_errno (-1); + return; + } + /* Only operate on regular files and directories */ + if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)) + { + remote_fileio_reply (-1, FILEIO_EACCES); + return; + } + if (ptrval) + { + remote_fileio_to_fio_stat (&st, &fst); + remote_fileio_to_fio_uint (0, fst.fst_dev); + + retlength = remote_fileio_write_bytes (ptrval, (char *) &fst, sizeof fst); + if (retlength != sizeof fst) + { + remote_fileio_return_errno (-1); + return; + } + } + remote_fileio_return_success (ret); +} + +static void +remote_fileio_func_fstat (char *buf) +{ + CORE_ADDR ptrval; + int fd, ret, retlength; + long target_fd; + LONGEST lnum; + struct stat st; + struct fio_stat fst; + struct timeval tv; + + /* 1. Parameter: file descriptor */ + if (remote_fileio_extract_int (&buf, &target_fd)) + { + remote_fileio_ioerror (); + return; + } + fd = remote_fileio_map_fd ((int) target_fd); + if (fd == FIO_FD_INVALID) + { + remote_fileio_badfd (); + return; + } + /* 2. Parameter: Ptr to struct stat */ + if (remote_fileio_extract_long (&buf, &lnum)) + { + remote_fileio_ioerror (); + return; + } + ptrval = (CORE_ADDR) lnum; + + remote_fio_no_longjmp = 1; + if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT) + { + remote_fileio_to_fio_uint (1, fst.fst_dev); + st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR); + st.st_nlink = 1; + st.st_uid = getuid (); + st.st_gid = getgid (); + st.st_rdev = 0; + st.st_size = 0; + st.st_blksize = 512; +#if HAVE_STRUCT_STAT_ST_BLOCKS + st.st_blocks = 0; +#endif + if (!gettimeofday (&tv, NULL)) + st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec; + else + st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0; + ret = 0; + } + else + ret = fstat (fd, &st); + + if (ret == -1) + { + remote_fileio_return_errno (-1); + return; + } + if (ptrval) + { + remote_fileio_to_fio_stat (&st, &fst); + + retlength = remote_fileio_write_bytes (ptrval, (char *) &fst, sizeof fst); + if (retlength != sizeof fst) + { + remote_fileio_return_errno (-1); + return; + } + } + remote_fileio_return_success (ret); +} + +static void +remote_fileio_func_gettimeofday (char *buf) +{ + LONGEST lnum; + CORE_ADDR ptrval; + int ret, retlength; + struct timeval tv; + struct fio_timeval ftv; + + /* 1. Parameter: struct timeval pointer */ + if (remote_fileio_extract_long (&buf, &lnum)) + { + remote_fileio_ioerror (); + return; + } + ptrval = (CORE_ADDR) lnum; + /* 2. Parameter: some pointer value... */ + if (remote_fileio_extract_long (&buf, &lnum)) + { + remote_fileio_ioerror (); + return; + } + /* ...which has to be NULL */ + if (lnum) + { + remote_fileio_reply (-1, FILEIO_EINVAL); + return; + } + + remote_fio_no_longjmp = 1; + ret = gettimeofday (&tv, NULL); + + if (ret == -1) + { + remote_fileio_return_errno (-1); + return; + } + + if (ptrval) + { + remote_fileio_to_fio_timeval (&tv, &ftv); + + retlength = remote_fileio_write_bytes (ptrval, (char *) &ftv, sizeof ftv); + if (retlength != sizeof ftv) + { + remote_fileio_return_errno (-1); + return; + } + } + remote_fileio_return_success (ret); +} + +static void +remote_fileio_func_isatty (char *buf) +{ + long target_fd; + int fd; + + /* Parameter: file descriptor */ + if (remote_fileio_extract_int (&buf, &target_fd)) + { + remote_fileio_ioerror (); + return; + } + remote_fio_no_longjmp = 1; + fd = remote_fileio_map_fd ((int) target_fd); + remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN || + fd == FIO_FD_CONSOLE_OUT ? 1 : 0); +} + +static void +remote_fileio_func_system (char *buf) +{ + CORE_ADDR ptrval; + int ret, length, retlength; + char *cmdline; + + /* Check if system(3) has been explicitely allowed using the + `set remote system-call-allowed 1' command. If not, return + EPERM */ + if (!remote_fio_system_call_allowed) + { + remote_fileio_reply (-1, FILEIO_EPERM); + return; + } + + /* Parameter: Ptr to commandline / length incl. trailing zero */ + if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length)) + { + remote_fileio_ioerror (); + return; + } + /* Request commandline using 'm' packet */ + cmdline = alloca (length); + retlength = remote_read_bytes (ptrval, cmdline, length); + if (retlength != length) + { + remote_fileio_ioerror (); + return; + } + + remote_fio_no_longjmp = 1; + ret = system (cmdline); + + if (ret == -1) + remote_fileio_return_errno (-1); + else + remote_fileio_return_success (WEXITSTATUS (ret)); +} + +static struct { + char *name; + void (*func)(char *); +} remote_fio_func_map[] = { + "open", remote_fileio_func_open, + "close", remote_fileio_func_close, + "read", remote_fileio_func_read, + "write", remote_fileio_func_write, + "lseek", remote_fileio_func_lseek, + "rename", remote_fileio_func_rename, + "unlink", remote_fileio_func_unlink, + "stat", remote_fileio_func_stat, + "fstat", remote_fileio_func_fstat, + "gettimeofday", remote_fileio_func_gettimeofday, + "isatty", remote_fileio_func_isatty, + "system", remote_fileio_func_system, + NULL, NULL +}; + +static int +do_remote_fileio_request (struct ui_out *uiout, void *buf_arg) +{ + char *buf = buf_arg; + char *c; + int idx; + + remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler); + + c = strchr (++buf, ','); + if (c) + *c++ = '\0'; + else + c = strchr (buf, '\0'); + for (idx = 0; remote_fio_func_map[idx].name; ++idx) + if (!strcmp (remote_fio_func_map[idx].name, buf)) + break; + if (!remote_fio_func_map[idx].name) /* ERROR: No such function. */ + return RETURN_ERROR; + remote_fio_func_map[idx].func (c); + return 0; +} + +void +remote_fileio_request (char *buf) +{ + int ex; + + remote_fileio_sig_init (); + + remote_fio_ctrl_c_flag = 0; + remote_fio_no_longjmp = 0; + + ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf, + NULL, RETURN_MASK_ALL); + switch (ex) + { + case RETURN_ERROR: + remote_fileio_reply (-1, FILEIO_ENOSYS); + break; + case RETURN_QUIT: + remote_fileio_reply (-1, FILEIO_EINTR); + break; + default: + break; + } + + remote_fileio_sig_exit (); +} + +static void +set_system_call_allowed (char *args, int from_tty) +{ + if (args) + { + char *arg_end; + int val = strtoul (args, &arg_end, 10); + if (*args && *arg_end == '\0') + { + remote_fio_system_call_allowed = !!val; + return; + } + } + error ("Illegal argument for \"set remote system-call-allowed\" command"); +} + +static void +show_system_call_allowed (char *args, int from_tty) +{ + if (args) + error ("Garbage after \"show remote system-call-allowed\" command: `%s'", args); + printf_unfiltered ("Calling host system(3) call from target is %sallowed\n", + remote_fio_system_call_allowed ? "" : "not "); +} + +void +initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist, + struct cmd_list_element *remote_show_cmdlist) +{ + add_cmd ("system-call-allowed", no_class, + set_system_call_allowed, + "Set if the host system(3) call is allowed for the target.\n", + &remote_set_cmdlist); + add_cmd ("system-call-allowed", no_class, + show_system_call_allowed, + "Show if the host system(3) call is allowed for the target.\n", + &remote_show_cmdlist); +} diff --git a/contrib/gdb/gdb/remote-fileio.h b/contrib/gdb/gdb/remote-fileio.h new file mode 100644 index 00000000000..68c6450e8e3 --- /dev/null +++ b/contrib/gdb/gdb/remote-fileio.h @@ -0,0 +1,38 @@ +/* Remote File-I/O communications + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* See the GDB User Guide for details of the GDB remote protocol. */ + +#ifndef REMOTE_FILEIO_H +#define REMOTE_FILEIO_H + +struct cmd_list_element; + +/* Unified interface to remote fileio, called in remote.c from + remote_wait () and remote_async_wait () */ +extern void remote_fileio_request (char *buf); + +/* Called from _initialize_remote () */ +extern void initialize_remote_fileio ( + struct cmd_list_element *remote_set_cmdlist, + struct cmd_list_element *remote_show_cmdlist); + +#endif diff --git a/contrib/gdb/gdb/remote-hms.c b/contrib/gdb/gdb/remote-hms.c new file mode 100644 index 00000000000..ee40051fb3c --- /dev/null +++ b/contrib/gdb/gdb/remote-hms.c @@ -0,0 +1,159 @@ +/* Remote debugging interface for Renesas HMS Monitor Version 1.0 + Copyright 1995, 1996, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + Contributed by Cygnus Support. Written by Steve Chamberlain + (sac@cygnus.com). + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "monitor.h" +#include "serial.h" +#include "regcache.h" + +static void hms_open (char *args, int from_tty); +static void +hms_supply_register (char *regname, int regnamelen, char *val, int vallen) +{ + int regno; + + if (regnamelen != 2) + return; + if (regname[0] != 'P') + return; + /* We scan off all the registers in one go */ + + val = monitor_supply_register (PC_REGNUM, val); + /* Skip the ccr string */ + while (*val != '=' && *val) + val++; + + val = monitor_supply_register (CCR_REGNUM, val + 1); + + /* Skip up to rest of regs */ + while (*val != '=' && *val) + val++; + + for (regno = 0; regno < 7; regno++) + { + val = monitor_supply_register (regno, val + 1); + } +} + +/* + * This array of registers needs to match the indexes used by GDB. The + * whole reason this exists is because the various ROM monitors use + * different names than GDB does, and don't support all the + * registers either. So, typing "info reg sp" becomes a "r30". + */ + +static char *hms_regnames[] = +{ + "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "CCR", "PC", "", "", "", "" +}; + +/* + * Define the monitor command strings. Since these are passed directly + * through to a printf style function, we need can include formatting + * strings. We also need a CR or LF on the end. + */ + +static struct target_ops hms_ops; + +static char *hms_inits[] = +{"\003", /* Resets the prompt, and clears repeated cmds */ + NULL}; + +static struct monitor_ops hms_cmds; + +static void +init_hms_cmds (void) +{ + hms_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_GETMEM_NEEDS_RANGE; + hms_cmds.init = hms_inits; /* Init strings */ + hms_cmds.cont = "g\r"; /* continue command */ + hms_cmds.step = "s\r"; /* single step */ + hms_cmds.stop = "\003"; /* ^C interrupts the program */ + hms_cmds.set_break = "b %x\r"; /* set a breakpoint */ + hms_cmds.clr_break = "b - %x\r"; /* clear a breakpoint */ + hms_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */ + hms_cmds.fill = "f %x %x %x\r"; /* fill (start end val) */ + hms_cmds.setmem.cmdb = "m.b %x=%x\r"; /* setmem.cmdb (addr, value) */ + hms_cmds.setmem.cmdw = "m.w %x=%x\r"; /* setmem.cmdw (addr, value) */ + hms_cmds.setmem.cmdl = NULL; /* setmem.cmdl (addr, value) */ + hms_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ + hms_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */ + hms_cmds.setmem.term = NULL; /* setreg.term */ + hms_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */ + hms_cmds.getmem.cmdb = "m.b %x %x\r"; /* getmem.cmdb (addr, addr) */ + hms_cmds.getmem.cmdw = "m.w %x %x\r"; /* getmem.cmdw (addr, addr) */ + hms_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, addr) */ + hms_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr) */ + hms_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ + hms_cmds.getmem.term = ">"; /* getmem.term */ + hms_cmds.getmem.term_cmd = "\003"; /* getmem.term_cmd */ + hms_cmds.setreg.cmd = "r %s=%x\r"; /* setreg.cmd (name, value) */ + hms_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ + hms_cmds.setreg.term = NULL; /* setreg.term */ + hms_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ + hms_cmds.getreg.cmd = "r %s\r"; /* getreg.cmd (name) */ + hms_cmds.getreg.resp_delim = " ("; /* getreg.resp_delim */ + hms_cmds.getreg.term = ":"; /* getreg.term */ + hms_cmds.getreg.term_cmd = "\003"; /* getreg.term_cmd */ + hms_cmds.dump_registers = "r\r"; /* dump_registers */ + hms_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */ + hms_cmds.supply_register = hms_supply_register; /* supply_register */ + hms_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ + hms_cmds.load = "tl\r"; /* download command */ + hms_cmds.loadresp = NULL; /* load response */ + hms_cmds.prompt = ">"; /* monitor command prompt */ + hms_cmds.line_term = "\r"; /* end-of-command delimitor */ + hms_cmds.cmd_end = NULL; /* optional command terminator */ + hms_cmds.target = &hms_ops; /* target operations */ + hms_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ + hms_cmds.regnames = hms_regnames; /* registers names */ + hms_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ +} /* init_hms-cmds */ + +static void +hms_open (char *args, int from_tty) +{ + monitor_open (args, &hms_cmds, from_tty); +} + +int write_dos_tick_delay; + +extern initialize_file_ftype _initialize_remote_hms; /* -Wmissing-prototypes */ + +void +_initialize_remote_hms (void) +{ + init_hms_cmds (); + init_monitor_ops (&hms_ops); + + hms_ops.to_shortname = "hms"; + hms_ops.to_longname = "Renesas Microsystems H8/300 debug monitor"; + hms_ops.to_doc = "Debug via the HMS monitor.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + hms_ops.to_open = hms_open; + /* By trial and error I've found that this delay doesn't break things */ + write_dos_tick_delay = 1; + add_target (&hms_ops); +} diff --git a/contrib/gdb/gdb/remote-mips.c b/contrib/gdb/gdb/remote-mips.c new file mode 100644 index 00000000000..c75768406b9 --- /dev/null +++ b/contrib/gdb/gdb/remote-mips.c @@ -0,0 +1,3421 @@ +/* Remote debugging interface for MIPS remote debugging protocol. + + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002 Free Software Foundation, Inc. + + Contributed by Cygnus Support. Written by Ian Lance Taylor + . + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "bfd.h" +#include "symfile.h" +#include "gdbcmd.h" +#include "gdbcore.h" +#include "serial.h" +#include "target.h" +#include "remote-utils.h" +#include "gdb_string.h" +#include "gdb_stat.h" +#include "regcache.h" +#include +#include "mips-tdep.h" + + +/* Breakpoint types. Values 0, 1, and 2 must agree with the watch + types passed by breakpoint.c to target_insert_watchpoint. + Value 3 is our own invention, and is used for ordinary instruction + breakpoints. Value 4 is used to mark an unused watchpoint in tables. */ +enum break_type + { + BREAK_WRITE, /* 0 */ + BREAK_READ, /* 1 */ + BREAK_ACCESS, /* 2 */ + BREAK_FETCH, /* 3 */ + BREAK_UNUSED /* 4 */ + }; + +/* Prototypes for local functions. */ + +static int mips_readchar (int timeout); + +static int mips_receive_header (unsigned char *hdr, int *pgarbage, + int ch, int timeout); + +static int mips_receive_trailer (unsigned char *trlr, int *pgarbage, + int *pch, int timeout); + +static int mips_cksum (const unsigned char *hdr, + const unsigned char *data, int len); + +static void mips_send_packet (const char *s, int get_ack); + +static void mips_send_command (const char *cmd, int prompt); + +static int mips_receive_packet (char *buff, int throw_error, int timeout); + +static ULONGEST mips_request (int cmd, ULONGEST addr, ULONGEST data, + int *perr, int timeout, char *buff); + +static void mips_initialize (void); + +static void mips_open (char *name, int from_tty); + +static void pmon_open (char *name, int from_tty); + +static void ddb_open (char *name, int from_tty); + +static void lsi_open (char *name, int from_tty); + +static void mips_close (int quitting); + +static void mips_detach (char *args, int from_tty); + +static void mips_resume (ptid_t ptid, int step, + enum target_signal siggnal); + +static ptid_t mips_wait (ptid_t ptid, + struct target_waitstatus *status); + +static int mips_map_regno (int regno); + +static void mips_fetch_registers (int regno); + +static void mips_prepare_to_store (void); + +static void mips_store_registers (int regno); + +static unsigned int mips_fetch_word (CORE_ADDR addr); + +static int mips_store_word (CORE_ADDR addr, unsigned int value, + char *old_contents); + +static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, + struct mem_attrib *attrib, + struct target_ops *target); + +static void mips_files_info (struct target_ops *ignore); + +static void mips_create_inferior (char *execfile, char *args, char **env); + +static void mips_mourn_inferior (void); + +static int pmon_makeb64 (unsigned long v, char *p, int n, int *chksum); + +static int pmon_zeroset (int recsize, char **buff, int *amount, + unsigned int *chksum); + +static int pmon_checkset (int recsize, char **buff, int *value); + +static void pmon_make_fastrec (char **outbuf, unsigned char *inbuf, + int *inptr, int inamount, int *recsize, + unsigned int *csum, unsigned int *zerofill); + +static int pmon_check_ack (char *mesg); + +static void pmon_start_download (void); + +static void pmon_end_download (int final, int bintotal); + +static void pmon_download (char *buffer, int length); + +static void pmon_load_fast (char *file); + +static void mips_load (char *file, int from_tty); + +static int mips_make_srec (char *buffer, int type, CORE_ADDR memaddr, + unsigned char *myaddr, int len); + +static int set_breakpoint (CORE_ADDR addr, int len, enum break_type type); + +static int clear_breakpoint (CORE_ADDR addr, int len, enum break_type type); + +static int common_breakpoint (int set, CORE_ADDR addr, int len, + enum break_type type); + +/* Forward declarations. */ +extern struct target_ops mips_ops; +extern struct target_ops pmon_ops; +extern struct target_ops ddb_ops; + /* *INDENT-OFF* */ +/* The MIPS remote debugging interface is built on top of a simple + packet protocol. Each packet is organized as follows: + + SYN The first character is always a SYN (ASCII 026, or ^V). SYN + may not appear anywhere else in the packet. Any time a SYN is + seen, a new packet should be assumed to have begun. + + TYPE_LEN + This byte contains the upper five bits of the logical length + of the data section, plus a single bit indicating whether this + is a data packet or an acknowledgement. The documentation + indicates that this bit is 1 for a data packet, but the actual + board uses 1 for an acknowledgement. The value of the byte is + 0x40 + (ack ? 0x20 : 0) + (len >> 6) + (we always have 0 <= len < 1024). Acknowledgement packets do + not carry data, and must have a data length of 0. + + LEN1 This byte contains the lower six bits of the logical length of + the data section. The value is + 0x40 + (len & 0x3f) + + SEQ This byte contains the six bit sequence number of the packet. + The value is + 0x40 + seq + An acknowlegment packet contains the sequence number of the + packet being acknowledged plus 1 modulo 64. Data packets are + transmitted in sequence. There may only be one outstanding + unacknowledged data packet at a time. The sequence numbers + are independent in each direction. If an acknowledgement for + the previous packet is received (i.e., an acknowledgement with + the sequence number of the packet just sent) the packet just + sent should be retransmitted. If no acknowledgement is + received within a timeout period, the packet should be + retransmitted. This has an unfortunate failure condition on a + high-latency line, as a delayed acknowledgement may lead to an + endless series of duplicate packets. + + DATA The actual data bytes follow. The following characters are + escaped inline with DLE (ASCII 020, or ^P): + SYN (026) DLE S + DLE (020) DLE D + ^C (003) DLE C + ^S (023) DLE s + ^Q (021) DLE q + The additional DLE characters are not counted in the logical + length stored in the TYPE_LEN and LEN1 bytes. + + CSUM1 + CSUM2 + CSUM3 + These bytes contain an 18 bit checksum of the complete + contents of the packet excluding the SEQ byte and the + CSUM[123] bytes. The checksum is simply the twos complement + addition of all the bytes treated as unsigned characters. The + values of the checksum bytes are: + CSUM1: 0x40 + ((cksum >> 12) & 0x3f) + CSUM2: 0x40 + ((cksum >> 6) & 0x3f) + CSUM3: 0x40 + (cksum & 0x3f) + + It happens that the MIPS remote debugging protocol always + communicates with ASCII strings. Because of this, this + implementation doesn't bother to handle the DLE quoting mechanism, + since it will never be required. */ +/* *INDENT-ON* */ + + +/* The SYN character which starts each packet. */ +#define SYN '\026' + +/* The 0x40 used to offset each packet (this value ensures that all of + the header and trailer bytes, other than SYN, are printable ASCII + characters). */ +#define HDR_OFFSET 0x40 + +/* The indices of the bytes in the packet header. */ +#define HDR_INDX_SYN 0 +#define HDR_INDX_TYPE_LEN 1 +#define HDR_INDX_LEN1 2 +#define HDR_INDX_SEQ 3 +#define HDR_LENGTH 4 + +/* The data/ack bit in the TYPE_LEN header byte. */ +#define TYPE_LEN_DA_BIT 0x20 +#define TYPE_LEN_DATA 0 +#define TYPE_LEN_ACK TYPE_LEN_DA_BIT + +/* How to compute the header bytes. */ +#define HDR_SET_SYN(data, len, seq) (SYN) +#define HDR_SET_TYPE_LEN(data, len, seq) \ + (HDR_OFFSET \ + + ((data) ? TYPE_LEN_DATA : TYPE_LEN_ACK) \ + + (((len) >> 6) & 0x1f)) +#define HDR_SET_LEN1(data, len, seq) (HDR_OFFSET + ((len) & 0x3f)) +#define HDR_SET_SEQ(data, len, seq) (HDR_OFFSET + (seq)) + +/* Check that a header byte is reasonable. */ +#define HDR_CHECK(ch) (((ch) & HDR_OFFSET) == HDR_OFFSET) + +/* Get data from the header. These macros evaluate their argument + multiple times. */ +#define HDR_IS_DATA(hdr) \ + (((hdr)[HDR_INDX_TYPE_LEN] & TYPE_LEN_DA_BIT) == TYPE_LEN_DATA) +#define HDR_GET_LEN(hdr) \ + ((((hdr)[HDR_INDX_TYPE_LEN] & 0x1f) << 6) + (((hdr)[HDR_INDX_LEN1] & 0x3f))) +#define HDR_GET_SEQ(hdr) ((unsigned int)(hdr)[HDR_INDX_SEQ] & 0x3f) + +/* The maximum data length. */ +#define DATA_MAXLEN 1023 + +/* The trailer offset. */ +#define TRLR_OFFSET HDR_OFFSET + +/* The indices of the bytes in the packet trailer. */ +#define TRLR_INDX_CSUM1 0 +#define TRLR_INDX_CSUM2 1 +#define TRLR_INDX_CSUM3 2 +#define TRLR_LENGTH 3 + +/* How to compute the trailer bytes. */ +#define TRLR_SET_CSUM1(cksum) (TRLR_OFFSET + (((cksum) >> 12) & 0x3f)) +#define TRLR_SET_CSUM2(cksum) (TRLR_OFFSET + (((cksum) >> 6) & 0x3f)) +#define TRLR_SET_CSUM3(cksum) (TRLR_OFFSET + (((cksum) ) & 0x3f)) + +/* Check that a trailer byte is reasonable. */ +#define TRLR_CHECK(ch) (((ch) & TRLR_OFFSET) == TRLR_OFFSET) + +/* Get data from the trailer. This evaluates its argument multiple + times. */ +#define TRLR_GET_CKSUM(trlr) \ + ((((trlr)[TRLR_INDX_CSUM1] & 0x3f) << 12) \ + + (((trlr)[TRLR_INDX_CSUM2] & 0x3f) << 6) \ + + ((trlr)[TRLR_INDX_CSUM3] & 0x3f)) + +/* The sequence number modulos. */ +#define SEQ_MODULOS (64) + +/* PMON commands to load from the serial port or UDP socket. */ +#define LOAD_CMD "load -b -s tty0\r" +#define LOAD_CMD_UDP "load -b -s udp\r" + +/* The target vectors for the four different remote MIPS targets. + These are initialized with code in _initialize_remote_mips instead + of static initializers, to make it easier to extend the target_ops + vector later. */ +struct target_ops mips_ops, pmon_ops, ddb_ops, lsi_ops; + +enum mips_monitor_type + { + /* IDT/SIM monitor being used: */ + MON_IDT, + /* PMON monitor being used: */ + MON_PMON, /* 3.0.83 [COGENT,EB,FP,NET] Algorithmics Ltd. Nov 9 1995 17:19:50 */ + MON_DDB, /* 2.7.473 [DDBVR4300,EL,FP,NET] Risq Modular Systems, Thu Jun 6 09:28:40 PDT 1996 */ + MON_LSI, /* 4.3.12 [EB,FP], LSI LOGIC Corp. Tue Feb 25 13:22:14 1997 */ + /* Last and unused value, for sizing vectors, etc. */ + MON_LAST + }; +static enum mips_monitor_type mips_monitor = MON_LAST; + +/* The monitor prompt text. If the user sets the PMON prompt + to some new value, the GDB `set monitor-prompt' command must also + be used to inform GDB about the expected prompt. Otherwise, GDB + will not be able to connect to PMON in mips_initialize(). + If the `set monitor-prompt' command is not used, the expected + default prompt will be set according the target: + target prompt + ----- ----- + pmon PMON> + ddb NEC010> + lsi PMON> + */ +static char *mips_monitor_prompt; + +/* Set to 1 if the target is open. */ +static int mips_is_open; + +/* Currently active target description (if mips_is_open == 1) */ +static struct target_ops *current_ops; + +/* Set to 1 while the connection is being initialized. */ +static int mips_initializing; + +/* Set to 1 while the connection is being brought down. */ +static int mips_exiting; + +/* The next sequence number to send. */ +static unsigned int mips_send_seq; + +/* The next sequence number we expect to receive. */ +static unsigned int mips_receive_seq; + +/* The time to wait before retransmitting a packet, in seconds. */ +static int mips_retransmit_wait = 3; + +/* The number of times to try retransmitting a packet before giving up. */ +static int mips_send_retries = 10; + +/* The number of garbage characters to accept when looking for an + SYN for the next packet. */ +static int mips_syn_garbage = 10; + +/* The time to wait for a packet, in seconds. */ +static int mips_receive_wait = 5; + +/* Set if we have sent a packet to the board but have not yet received + a reply. */ +static int mips_need_reply = 0; + +/* Handle used to access serial I/O stream. */ +static struct serial *mips_desc; + +/* UDP handle used to download files to target. */ +static struct serial *udp_desc; +static int udp_in_use; + +/* TFTP filename used to download files to DDB board, in the form + host:filename. */ +static char *tftp_name; /* host:filename */ +static char *tftp_localname; /* filename portion of above */ +static int tftp_in_use; +static FILE *tftp_file; + +/* Counts the number of times the user tried to interrupt the target (usually + via ^C. */ +static int interrupt_count; + +/* If non-zero, means that the target is running. */ +static int mips_wait_flag = 0; + +/* If non-zero, monitor supports breakpoint commands. */ +static int monitor_supports_breakpoints = 0; + +/* Data cache header. */ + +#if 0 /* not used (yet?) */ +static DCACHE *mips_dcache; +#endif + +/* Non-zero means that we've just hit a read or write watchpoint */ +static int hit_watchpoint; + +/* Table of breakpoints/watchpoints (used only on LSI PMON target). + The table is indexed by a breakpoint number, which is an integer + from 0 to 255 returned by the LSI PMON when a breakpoint is set. + */ +#define MAX_LSI_BREAKPOINTS 256 +struct lsi_breakpoint_info + { + enum break_type type; /* type of breakpoint */ + CORE_ADDR addr; /* address of breakpoint */ + int len; /* length of region being watched */ + unsigned long value; /* value to watch */ + } +lsi_breakpoints[MAX_LSI_BREAKPOINTS]; + +/* Error/warning codes returned by LSI PMON for breakpoint commands. + Warning values may be ORed together; error values may not. */ +#define W_WARN 0x100 /* This bit is set if the error code is a warning */ +#define W_MSK 0x101 /* warning: Range feature is supported via mask */ +#define W_VAL 0x102 /* warning: Value check is not supported in hardware */ +#define W_QAL 0x104 /* warning: Requested qualifiers are not supported in hardware */ + +#define E_ERR 0x200 /* This bit is set if the error code is an error */ +#define E_BPT 0x200 /* error: No such breakpoint number */ +#define E_RGE 0x201 /* error: Range is not supported */ +#define E_QAL 0x202 /* error: The requested qualifiers can not be used */ +#define E_OUT 0x203 /* error: Out of hardware resources */ +#define E_NON 0x204 /* error: Hardware breakpoint not supported */ + +struct lsi_error + { + int code; /* error code */ + char *string; /* string associated with this code */ + }; + +struct lsi_error lsi_warning_table[] = +{ + {W_MSK, "Range feature is supported via mask"}, + {W_VAL, "Value check is not supported in hardware"}, + {W_QAL, "Requested qualifiers are not supported in hardware"}, + {0, NULL} +}; + +struct lsi_error lsi_error_table[] = +{ + {E_BPT, "No such breakpoint number"}, + {E_RGE, "Range is not supported"}, + {E_QAL, "The requested qualifiers can not be used"}, + {E_OUT, "Out of hardware resources"}, + {E_NON, "Hardware breakpoint not supported"}, + {0, NULL} +}; + +/* Set to 1 with the 'set monitor-warnings' command to enable printing + of warnings returned by PMON when hardware breakpoints are used. */ +static int monitor_warnings; + + +static void +close_ports (void) +{ + mips_is_open = 0; + serial_close (mips_desc); + + if (udp_in_use) + { + serial_close (udp_desc); + udp_in_use = 0; + } + tftp_in_use = 0; +} + +/* Handle low-level error that we can't recover from. Note that just + error()ing out from target_wait or some such low-level place will cause + all hell to break loose--the rest of GDB will tend to get left in an + inconsistent state. */ + +static NORETURN void +mips_error (char *string,...) +{ + va_list args; + + va_start (args, string); + + target_terminal_ours (); + wrap_here (""); /* Force out any buffered output */ + gdb_flush (gdb_stdout); + if (error_pre_print) + fputs_filtered (error_pre_print, gdb_stderr); + vfprintf_filtered (gdb_stderr, string, args); + fprintf_filtered (gdb_stderr, "\n"); + va_end (args); + gdb_flush (gdb_stderr); + + /* Clean up in such a way that mips_close won't try to talk to the + board (it almost surely won't work since we weren't able to talk to + it). */ + close_ports (); + + printf_unfiltered ("Ending remote MIPS debugging.\n"); + target_mourn_inferior (); + + throw_exception (RETURN_ERROR); +} + +/* putc_readable - print a character, displaying non-printable chars in + ^x notation or in hex. */ + +static void +fputc_readable (int ch, struct ui_file *file) +{ + if (ch == '\n') + fputc_unfiltered ('\n', file); + else if (ch == '\r') + fprintf_unfiltered (file, "\\r"); + else if (ch < 0x20) /* ASCII control character */ + fprintf_unfiltered (file, "^%c", ch + '@'); + else if (ch >= 0x7f) /* non-ASCII characters (rubout or greater) */ + fprintf_unfiltered (file, "[%02x]", ch & 0xff); + else + fputc_unfiltered (ch, file); +} + + +/* puts_readable - print a string, displaying non-printable chars in + ^x notation or in hex. */ + +static void +fputs_readable (const char *string, struct ui_file *file) +{ + int c; + + while ((c = *string++) != '\0') + fputc_readable (c, file); +} + + +/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if + timed out. TIMEOUT specifies timeout value in seconds. + */ + +static int +mips_expect_timeout (const char *string, int timeout) +{ + const char *p = string; + + if (remote_debug) + { + fprintf_unfiltered (gdb_stdlog, "Expected \""); + fputs_readable (string, gdb_stdlog); + fprintf_unfiltered (gdb_stdlog, "\", got \""); + } + + immediate_quit++; + while (1) + { + int c; + + /* Must use serial_readchar() here cuz mips_readchar would get + confused if we were waiting for the mips_monitor_prompt... */ + + c = serial_readchar (mips_desc, timeout); + + if (c == SERIAL_TIMEOUT) + { + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "\": FAIL\n"); + return 0; + } + + if (remote_debug) + fputc_readable (c, gdb_stdlog); + + if (c == *p++) + { + if (*p == '\0') + { + immediate_quit--; + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "\": OK\n"); + return 1; + } + } + else + { + p = string; + if (c == *p) + p++; + } + } +} + +/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if + timed out. The timeout value is hard-coded to 2 seconds. Use + mips_expect_timeout if a different timeout value is needed. + */ + +static int +mips_expect (const char *string) +{ + return mips_expect_timeout (string, remote_timeout); +} + +/* Read a character from the remote, aborting on error. Returns + SERIAL_TIMEOUT on timeout (since that's what serial_readchar() + returns). FIXME: If we see the string mips_monitor_prompt from the + board, then we are debugging on the main console port, and we have + somehow dropped out of remote debugging mode. In this case, we + automatically go back in to remote debugging mode. This is a hack, + put in because I can't find any way for a program running on the + remote board to terminate without also ending remote debugging + mode. I assume users won't have any trouble with this; for one + thing, the IDT documentation generally assumes that the remote + debugging port is not the console port. This is, however, very + convenient for DejaGnu when you only have one connected serial + port. */ + +static int +mips_readchar (int timeout) +{ + int ch; + static int state = 0; + int mips_monitor_prompt_len = strlen (mips_monitor_prompt); + + { + int i; + + i = timeout; + if (i == -1 && watchdog > 0) + i = watchdog; + } + + if (state == mips_monitor_prompt_len) + timeout = 1; + ch = serial_readchar (mips_desc, timeout); + + if (ch == SERIAL_TIMEOUT && timeout == -1) /* Watchdog went off */ + { + target_mourn_inferior (); + error ("Watchdog has expired. Target detached.\n"); + } + + if (ch == SERIAL_EOF) + mips_error ("End of file from remote"); + if (ch == SERIAL_ERROR) + mips_error ("Error reading from remote: %s", safe_strerror (errno)); + if (remote_debug > 1) + { + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + if (ch != SERIAL_TIMEOUT) + fprintf_unfiltered (gdb_stdlog, "Read '%c' %d 0x%x\n", ch, ch, ch); + else + fprintf_unfiltered (gdb_stdlog, "Timed out in read\n"); + } + + /* If we have seen mips_monitor_prompt and we either time out, or + we see a @ (which was echoed from a packet we sent), reset the + board as described above. The first character in a packet after + the SYN (which is not echoed) is always an @ unless the packet is + more than 64 characters long, which ours never are. */ + if ((ch == SERIAL_TIMEOUT || ch == '@') + && state == mips_monitor_prompt_len + && !mips_initializing + && !mips_exiting) + { + if (remote_debug > 0) + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + fprintf_unfiltered (gdb_stdlog, "Reinitializing MIPS debugging mode\n"); + + mips_need_reply = 0; + mips_initialize (); + + state = 0; + + /* At this point, about the only thing we can do is abort the command + in progress and get back to command level as quickly as possible. */ + + error ("Remote board reset, debug protocol re-initialized."); + } + + if (ch == mips_monitor_prompt[state]) + ++state; + else + state = 0; + + return ch; +} + +/* Get a packet header, putting the data in the supplied buffer. + PGARBAGE is a pointer to the number of garbage characters received + so far. CH is the last character received. Returns 0 for success, + or -1 for timeout. */ + +static int +mips_receive_header (unsigned char *hdr, int *pgarbage, int ch, int timeout) +{ + int i; + + while (1) + { + /* Wait for a SYN. mips_syn_garbage is intended to prevent + sitting here indefinitely if the board sends us one garbage + character per second. ch may already have a value from the + last time through the loop. */ + while (ch != SYN) + { + ch = mips_readchar (timeout); + if (ch == SERIAL_TIMEOUT) + return -1; + if (ch != SYN) + { + /* Printing the character here lets the user of gdb see + what the program is outputting, if the debugging is + being done on the console port. Don't use _filtered: + we can't deal with a QUIT out of target_wait and + buffered target output confuses the user. */ + if (!mips_initializing || remote_debug > 0) + { + if (isprint (ch) || isspace (ch)) + { + fputc_unfiltered (ch, gdb_stdtarg); + } + else + { + fputc_readable (ch, gdb_stdtarg); + } + gdb_flush (gdb_stdtarg); + } + + /* Only count unprintable characters. */ + if (! (isprint (ch) || isspace (ch))) + (*pgarbage) += 1; + + if (mips_syn_garbage > 0 + && *pgarbage > mips_syn_garbage) + mips_error ("Debug protocol failure: more than %d characters before a sync.", + mips_syn_garbage); + } + } + + /* Get the packet header following the SYN. */ + for (i = 1; i < HDR_LENGTH; i++) + { + ch = mips_readchar (timeout); + if (ch == SERIAL_TIMEOUT) + return -1; + /* Make sure this is a header byte. */ + if (ch == SYN || !HDR_CHECK (ch)) + break; + + hdr[i] = ch; + } + + /* If we got the complete header, we can return. Otherwise we + loop around and keep looking for SYN. */ + if (i >= HDR_LENGTH) + return 0; + } +} + +/* Get a packet header, putting the data in the supplied buffer. + PGARBAGE is a pointer to the number of garbage characters received + so far. The last character read is returned in *PCH. Returns 0 + for success, -1 for timeout, -2 for error. */ + +static int +mips_receive_trailer (unsigned char *trlr, int *pgarbage, int *pch, int timeout) +{ + int i; + int ch; + + for (i = 0; i < TRLR_LENGTH; i++) + { + ch = mips_readchar (timeout); + *pch = ch; + if (ch == SERIAL_TIMEOUT) + return -1; + if (!TRLR_CHECK (ch)) + return -2; + trlr[i] = ch; + } + return 0; +} + +/* Get the checksum of a packet. HDR points to the packet header. + DATA points to the packet data. LEN is the length of DATA. */ + +static int +mips_cksum (const unsigned char *hdr, const unsigned char *data, int len) +{ + const unsigned char *p; + int c; + int cksum; + + cksum = 0; + + /* The initial SYN is not included in the checksum. */ + c = HDR_LENGTH - 1; + p = hdr + 1; + while (c-- != 0) + cksum += *p++; + + c = len; + p = data; + while (c-- != 0) + cksum += *p++; + + return cksum; +} + +/* Send a packet containing the given ASCII string. */ + +static void +mips_send_packet (const char *s, int get_ack) +{ + /* unsigned */ int len; + unsigned char *packet; + int cksum; + int try; + + len = strlen (s); + if (len > DATA_MAXLEN) + mips_error ("MIPS protocol data packet too long: %s", s); + + packet = (unsigned char *) alloca (HDR_LENGTH + len + TRLR_LENGTH + 1); + + packet[HDR_INDX_SYN] = HDR_SET_SYN (1, len, mips_send_seq); + packet[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (1, len, mips_send_seq); + packet[HDR_INDX_LEN1] = HDR_SET_LEN1 (1, len, mips_send_seq); + packet[HDR_INDX_SEQ] = HDR_SET_SEQ (1, len, mips_send_seq); + + memcpy (packet + HDR_LENGTH, s, len); + + cksum = mips_cksum (packet, packet + HDR_LENGTH, len); + packet[HDR_LENGTH + len + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum); + packet[HDR_LENGTH + len + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum); + packet[HDR_LENGTH + len + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum); + + /* Increment the sequence number. This will set mips_send_seq to + the sequence number we expect in the acknowledgement. */ + mips_send_seq = (mips_send_seq + 1) % SEQ_MODULOS; + + /* We can only have one outstanding data packet, so we just wait for + the acknowledgement here. Keep retransmitting the packet until + we get one, or until we've tried too many times. */ + for (try = 0; try < mips_send_retries; try++) + { + int garbage; + int ch; + + if (remote_debug > 0) + { + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + packet[HDR_LENGTH + len + TRLR_LENGTH] = '\0'; + fprintf_unfiltered (gdb_stdlog, "Writing \"%s\"\n", packet + 1); + } + + if (serial_write (mips_desc, packet, + HDR_LENGTH + len + TRLR_LENGTH) != 0) + mips_error ("write to target failed: %s", safe_strerror (errno)); + + if (!get_ack) + return; + + garbage = 0; + ch = 0; + while (1) + { + unsigned char hdr[HDR_LENGTH + 1]; + unsigned char trlr[TRLR_LENGTH + 1]; + int err; + unsigned int seq; + + /* Get the packet header. If we time out, resend the data + packet. */ + err = mips_receive_header (hdr, &garbage, ch, mips_retransmit_wait); + if (err != 0) + break; + + ch = 0; + + /* If we get a data packet, assume it is a duplicate and + ignore it. FIXME: If the acknowledgement is lost, this + data packet may be the packet the remote sends after the + acknowledgement. */ + if (HDR_IS_DATA (hdr)) + { + int i; + + /* Ignore any errors raised whilst attempting to ignore + packet. */ + + len = HDR_GET_LEN (hdr); + + for (i = 0; i < len; i++) + { + int rch; + + rch = mips_readchar (remote_timeout); + if (rch == SYN) + { + ch = SYN; + break; + } + if (rch == SERIAL_TIMEOUT) + break; + /* ignore the character */ + } + + if (i == len) + (void) mips_receive_trailer (trlr, &garbage, &ch, + remote_timeout); + + /* We don't bother checking the checksum, or providing an + ACK to the packet. */ + continue; + } + + /* If the length is not 0, this is a garbled packet. */ + if (HDR_GET_LEN (hdr) != 0) + continue; + + /* Get the packet trailer. */ + err = mips_receive_trailer (trlr, &garbage, &ch, + mips_retransmit_wait); + + /* If we timed out, resend the data packet. */ + if (err == -1) + break; + + /* If we got a bad character, reread the header. */ + if (err != 0) + continue; + + /* If the checksum does not match the trailer checksum, this + is a bad packet; ignore it. */ + if (mips_cksum (hdr, (unsigned char *) NULL, 0) + != TRLR_GET_CKSUM (trlr)) + continue; + + if (remote_debug > 0) + { + hdr[HDR_LENGTH] = '\0'; + trlr[TRLR_LENGTH] = '\0'; + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + fprintf_unfiltered (gdb_stdlog, "Got ack %d \"%s%s\"\n", + HDR_GET_SEQ (hdr), hdr + 1, trlr); + } + + /* If this ack is for the current packet, we're done. */ + seq = HDR_GET_SEQ (hdr); + if (seq == mips_send_seq) + return; + + /* If this ack is for the last packet, resend the current + packet. */ + if ((seq + 1) % SEQ_MODULOS == mips_send_seq) + break; + + /* Otherwise this is a bad ack; ignore it. Increment the + garbage count to ensure that we do not stay in this loop + forever. */ + ++garbage; + } + } + + mips_error ("Remote did not acknowledge packet"); +} + +/* Receive and acknowledge a packet, returning the data in BUFF (which + should be DATA_MAXLEN + 1 bytes). The protocol documentation + implies that only the sender retransmits packets, so this code just + waits silently for a packet. It returns the length of the received + packet. If THROW_ERROR is nonzero, call error() on errors. If not, + don't print an error message and return -1. */ + +static int +mips_receive_packet (char *buff, int throw_error, int timeout) +{ + int ch; + int garbage; + int len; + unsigned char ack[HDR_LENGTH + TRLR_LENGTH + 1]; + int cksum; + + ch = 0; + garbage = 0; + while (1) + { + unsigned char hdr[HDR_LENGTH]; + unsigned char trlr[TRLR_LENGTH]; + int i; + int err; + + if (mips_receive_header (hdr, &garbage, ch, timeout) != 0) + { + if (throw_error) + mips_error ("Timed out waiting for remote packet"); + else + return -1; + } + + ch = 0; + + /* An acknowledgement is probably a duplicate; ignore it. */ + if (!HDR_IS_DATA (hdr)) + { + len = HDR_GET_LEN (hdr); + /* Check if the length is valid for an ACK, we may aswell + try and read the remainder of the packet: */ + if (len == 0) + { + /* Ignore the error condition, since we are going to + ignore the packet anyway. */ + (void) mips_receive_trailer (trlr, &garbage, &ch, timeout); + } + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + if (remote_debug > 0) + fprintf_unfiltered (gdb_stdlog, "Ignoring unexpected ACK\n"); + continue; + } + + len = HDR_GET_LEN (hdr); + for (i = 0; i < len; i++) + { + int rch; + + rch = mips_readchar (timeout); + if (rch == SYN) + { + ch = SYN; + break; + } + if (rch == SERIAL_TIMEOUT) + { + if (throw_error) + mips_error ("Timed out waiting for remote packet"); + else + return -1; + } + buff[i] = rch; + } + + if (i < len) + { + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + if (remote_debug > 0) + fprintf_unfiltered (gdb_stdlog, + "Got new SYN after %d chars (wanted %d)\n", + i, len); + continue; + } + + err = mips_receive_trailer (trlr, &garbage, &ch, timeout); + if (err == -1) + { + if (throw_error) + mips_error ("Timed out waiting for packet"); + else + return -1; + } + if (err == -2) + { + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + if (remote_debug > 0) + fprintf_unfiltered (gdb_stdlog, "Got SYN when wanted trailer\n"); + continue; + } + + /* If this is the wrong sequence number, ignore it. */ + if (HDR_GET_SEQ (hdr) != mips_receive_seq) + { + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + if (remote_debug > 0) + fprintf_unfiltered (gdb_stdlog, + "Ignoring sequence number %d (want %d)\n", + HDR_GET_SEQ (hdr), mips_receive_seq); + continue; + } + + if (mips_cksum (hdr, buff, len) == TRLR_GET_CKSUM (trlr)) + break; + + if (remote_debug > 0) + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + printf_unfiltered ("Bad checksum; data %d, trailer %d\n", + mips_cksum (hdr, buff, len), + TRLR_GET_CKSUM (trlr)); + + /* The checksum failed. Send an acknowledgement for the + previous packet to tell the remote to resend the packet. */ + ack[HDR_INDX_SYN] = HDR_SET_SYN (0, 0, mips_receive_seq); + ack[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (0, 0, mips_receive_seq); + ack[HDR_INDX_LEN1] = HDR_SET_LEN1 (0, 0, mips_receive_seq); + ack[HDR_INDX_SEQ] = HDR_SET_SEQ (0, 0, mips_receive_seq); + + cksum = mips_cksum (ack, (unsigned char *) NULL, 0); + + ack[HDR_LENGTH + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum); + ack[HDR_LENGTH + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum); + ack[HDR_LENGTH + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum); + + if (remote_debug > 0) + { + ack[HDR_LENGTH + TRLR_LENGTH] = '\0'; + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + printf_unfiltered ("Writing ack %d \"%s\"\n", mips_receive_seq, + ack + 1); + } + + if (serial_write (mips_desc, ack, HDR_LENGTH + TRLR_LENGTH) != 0) + { + if (throw_error) + mips_error ("write to target failed: %s", safe_strerror (errno)); + else + return -1; + } + } + + if (remote_debug > 0) + { + buff[len] = '\0'; + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + printf_unfiltered ("Got packet \"%s\"\n", buff); + } + + /* We got the packet. Send an acknowledgement. */ + mips_receive_seq = (mips_receive_seq + 1) % SEQ_MODULOS; + + ack[HDR_INDX_SYN] = HDR_SET_SYN (0, 0, mips_receive_seq); + ack[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (0, 0, mips_receive_seq); + ack[HDR_INDX_LEN1] = HDR_SET_LEN1 (0, 0, mips_receive_seq); + ack[HDR_INDX_SEQ] = HDR_SET_SEQ (0, 0, mips_receive_seq); + + cksum = mips_cksum (ack, (unsigned char *) NULL, 0); + + ack[HDR_LENGTH + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum); + ack[HDR_LENGTH + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum); + ack[HDR_LENGTH + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum); + + if (remote_debug > 0) + { + ack[HDR_LENGTH + TRLR_LENGTH] = '\0'; + /* Don't use _filtered; we can't deal with a QUIT out of + target_wait, and I think this might be called from there. */ + printf_unfiltered ("Writing ack %d \"%s\"\n", mips_receive_seq, + ack + 1); + } + + if (serial_write (mips_desc, ack, HDR_LENGTH + TRLR_LENGTH) != 0) + { + if (throw_error) + mips_error ("write to target failed: %s", safe_strerror (errno)); + else + return -1; + } + + return len; +} + +/* Optionally send a request to the remote system and optionally wait + for the reply. This implements the remote debugging protocol, + which is built on top of the packet protocol defined above. Each + request has an ADDR argument and a DATA argument. The following + requests are defined: + + \0 don't send a request; just wait for a reply + i read word from instruction space at ADDR + d read word from data space at ADDR + I write DATA to instruction space at ADDR + D write DATA to data space at ADDR + r read register number ADDR + R set register number ADDR to value DATA + c continue execution (if ADDR != 1, set pc to ADDR) + s single step (if ADDR != 1, set pc to ADDR) + + The read requests return the value requested. The write requests + return the previous value in the changed location. The execution + requests return a UNIX wait value (the approximate signal which + caused execution to stop is in the upper eight bits). + + If PERR is not NULL, this function waits for a reply. If an error + occurs, it sets *PERR to 1 and sets errno according to what the + target board reports. */ + +static ULONGEST +mips_request (int cmd, + ULONGEST addr, + ULONGEST data, + int *perr, + int timeout, + char *buff) +{ + char myBuff[DATA_MAXLEN + 1]; + int len; + int rpid; + char rcmd; + int rerrflg; + unsigned long rresponse; + + if (buff == (char *) NULL) + buff = myBuff; + + if (cmd != '\0') + { + if (mips_need_reply) + internal_error (__FILE__, __LINE__, + "mips_request: Trying to send command before reply"); + sprintf (buff, "0x0 %c 0x%s 0x%s", cmd, paddr_nz (addr), paddr_nz (data)); + mips_send_packet (buff, 1); + mips_need_reply = 1; + } + + if (perr == (int *) NULL) + return 0; + + if (!mips_need_reply) + internal_error (__FILE__, __LINE__, + "mips_request: Trying to get reply before command"); + + mips_need_reply = 0; + + len = mips_receive_packet (buff, 1, timeout); + buff[len] = '\0'; + + if (sscanf (buff, "0x%x %c 0x%x 0x%lx", + &rpid, &rcmd, &rerrflg, &rresponse) != 4 + || (cmd != '\0' && rcmd != cmd)) + mips_error ("Bad response from remote board"); + + if (rerrflg != 0) + { + *perr = 1; + + /* FIXME: This will returns MIPS errno numbers, which may or may + not be the same as errno values used on other systems. If + they stick to common errno values, they will be the same, but + if they don't, they must be translated. */ + errno = rresponse; + + return 0; + } + + *perr = 0; + return rresponse; +} + +static void +mips_initialize_cleanups (void *arg) +{ + mips_initializing = 0; +} + +static void +mips_exit_cleanups (void *arg) +{ + mips_exiting = 0; +} + +static void +mips_send_command (const char *cmd, int prompt) +{ + serial_write (mips_desc, cmd, strlen (cmd)); + mips_expect (cmd); + mips_expect ("\n"); + if (prompt) + mips_expect (mips_monitor_prompt); +} + +/* Enter remote (dbx) debug mode: */ +static void +mips_enter_debug (void) +{ + /* Reset the sequence numbers, ready for the new debug sequence: */ + mips_send_seq = 0; + mips_receive_seq = 0; + + if (mips_monitor != MON_IDT) + mips_send_command ("debug\r", 0); + else /* assume IDT monitor by default */ + mips_send_command ("db tty0\r", 0); + + sleep (1); + serial_write (mips_desc, "\r", sizeof "\r" - 1); + + /* We don't need to absorb any spurious characters here, since the + mips_receive_header will eat up a reasonable number of characters + whilst looking for the SYN, however this avoids the "garbage" + being displayed to the user. */ + if (mips_monitor != MON_IDT) + mips_expect ("\r"); + + { + char buff[DATA_MAXLEN + 1]; + if (mips_receive_packet (buff, 1, 3) < 0) + mips_error ("Failed to initialize (didn't receive packet)."); + } +} + +/* Exit remote (dbx) debug mode, returning to the monitor prompt: */ +static int +mips_exit_debug (void) +{ + int err; + struct cleanup *old_cleanups = make_cleanup (mips_exit_cleanups, NULL); + + mips_exiting = 1; + + if (mips_monitor != MON_IDT) + { + /* The DDB (NEC) and MiniRISC (LSI) versions of PMON exit immediately, + so we do not get a reply to this command: */ + mips_request ('x', 0, 0, NULL, mips_receive_wait, NULL); + mips_need_reply = 0; + if (!mips_expect (" break!")) + return -1; + } + else + mips_request ('x', 0, 0, &err, mips_receive_wait, NULL); + + if (!mips_expect (mips_monitor_prompt)) + return -1; + + do_cleanups (old_cleanups); + + return 0; +} + +/* Initialize a new connection to the MIPS board, and make sure we are + really connected. */ + +static void +mips_initialize (void) +{ + int err; + struct cleanup *old_cleanups = make_cleanup (mips_initialize_cleanups, NULL); + int j; + + /* What is this code doing here? I don't see any way it can happen, and + it might mean mips_initializing didn't get cleared properly. + So I'll make it a warning. */ + + if (mips_initializing) + { + warning ("internal error: mips_initialize called twice"); + return; + } + + mips_wait_flag = 0; + mips_initializing = 1; + + /* At this point, the packit protocol isn't responding. We'll try getting + into the monitor, and restarting the protocol. */ + + /* Force the system into the monitor. After this we *should* be at + the mips_monitor_prompt. */ + if (mips_monitor != MON_IDT) + j = 0; /* start by checking if we are already at the prompt */ + else + j = 1; /* start by sending a break */ + for (; j <= 4; j++) + { + switch (j) + { + case 0: /* First, try sending a CR */ + serial_flush_input (mips_desc); + serial_write (mips_desc, "\r", 1); + break; + case 1: /* First, try sending a break */ + serial_send_break (mips_desc); + break; + case 2: /* Then, try a ^C */ + serial_write (mips_desc, "\003", 1); + break; + case 3: /* Then, try escaping from download */ + { + if (mips_monitor != MON_IDT) + { + char tbuff[7]; + + /* We shouldn't need to send multiple termination + sequences, since the target performs line (or + block) reads, and then processes those + packets. In-case we were downloading a large packet + we flush the output buffer before inserting a + termination sequence. */ + serial_flush_output (mips_desc); + sprintf (tbuff, "\r/E/E\r"); + serial_write (mips_desc, tbuff, 6); + } + else + { + char srec[10]; + int i; + + /* We are possibly in binary download mode, having + aborted in the middle of an S-record. ^C won't + work because of binary mode. The only reliable way + out is to send enough termination packets (8 bytes) + to fill up and then overflow the largest size + S-record (255 bytes in this case). This amounts to + 256/8 + 1 packets. + */ + + mips_make_srec (srec, '7', 0, NULL, 0); + + for (i = 1; i <= 33; i++) + { + serial_write (mips_desc, srec, 8); + + if (serial_readchar (mips_desc, 0) >= 0) + break; /* Break immediatly if we get something from + the board. */ + } + } + } + break; + case 4: + mips_error ("Failed to initialize."); + } + + if (mips_expect (mips_monitor_prompt)) + break; + } + + if (mips_monitor != MON_IDT) + { + /* Sometimes PMON ignores the first few characters in the first + command sent after a load. Sending a blank command gets + around that. */ + mips_send_command ("\r", -1); + + /* Ensure the correct target state: */ + if (mips_monitor != MON_LSI) + mips_send_command ("set regsize 64\r", -1); + mips_send_command ("set hostport tty0\r", -1); + mips_send_command ("set brkcmd \"\"\r", -1); + /* Delete all the current breakpoints: */ + mips_send_command ("db *\r", -1); + /* NOTE: PMON does not have breakpoint support through the + "debug" mode, only at the monitor command-line. */ + } + + mips_enter_debug (); + + /* Clear all breakpoints: */ + if ((mips_monitor == MON_IDT + && clear_breakpoint (-1, 0, BREAK_UNUSED) == 0) + || mips_monitor == MON_LSI) + monitor_supports_breakpoints = 1; + else + monitor_supports_breakpoints = 0; + + do_cleanups (old_cleanups); + + /* If this doesn't call error, we have connected; we don't care if + the request itself succeeds or fails. */ + + mips_request ('r', 0, 0, &err, mips_receive_wait, NULL); +} + +/* Open a connection to the remote board. */ +static void +common_open (struct target_ops *ops, char *name, int from_tty, + enum mips_monitor_type new_monitor, + const char *new_monitor_prompt) +{ + char *ptype; + char *serial_port_name; + char *remote_name = 0; + char *local_name = 0; + char **argv; + + if (name == 0) + error ( + "To open a MIPS remote debugging connection, you need to specify what serial\n\ +device is attached to the target board (e.g., /dev/ttya).\n" + "If you want to use TFTP to download to the board, specify the name of a\n" + "temporary file to be used by GDB for downloads as the second argument.\n" + "This filename must be in the form host:filename, where host is the name\n" + "of the host running the TFTP server, and the file must be readable by the\n" + "world. If the local name of the temporary file differs from the name as\n" + "seen from the board via TFTP, specify that name as the third parameter.\n"); + + /* Parse the serial port name, the optional TFTP name, and the + optional local TFTP name. */ + if ((argv = buildargv (name)) == NULL) + nomem (0); + make_cleanup_freeargv (argv); + + serial_port_name = xstrdup (argv[0]); + if (argv[1]) /* remote TFTP name specified? */ + { + remote_name = argv[1]; + if (argv[2]) /* local TFTP filename specified? */ + local_name = argv[2]; + } + + target_preopen (from_tty); + + if (mips_is_open) + unpush_target (current_ops); + + /* Open and initialize the serial port. */ + mips_desc = serial_open (serial_port_name); + if (mips_desc == NULL) + perror_with_name (serial_port_name); + + if (baud_rate != -1) + { + if (serial_setbaudrate (mips_desc, baud_rate)) + { + serial_close (mips_desc); + perror_with_name (serial_port_name); + } + } + + serial_raw (mips_desc); + + /* Open and initialize the optional download port. If it is in the form + hostname#portnumber, it's a UDP socket. If it is in the form + hostname:filename, assume it's the TFTP filename that must be + passed to the DDB board to tell it where to get the load file. */ + if (remote_name) + { + if (strchr (remote_name, '#')) + { + udp_desc = serial_open (remote_name); + if (!udp_desc) + perror_with_name ("Unable to open UDP port"); + udp_in_use = 1; + } + else + { + /* Save the remote and local names of the TFTP temp file. If + the user didn't specify a local name, assume it's the same + as the part of the remote name after the "host:". */ + if (tftp_name) + xfree (tftp_name); + if (tftp_localname) + xfree (tftp_localname); + if (local_name == NULL) + if ((local_name = strchr (remote_name, ':')) != NULL) + local_name++; /* skip over the colon */ + if (local_name == NULL) + local_name = remote_name; /* local name same as remote name */ + tftp_name = xstrdup (remote_name); + tftp_localname = xstrdup (local_name); + tftp_in_use = 1; + } + } + + current_ops = ops; + mips_is_open = 1; + + /* Reset the expected monitor prompt if it's never been set before. */ + if (mips_monitor_prompt == NULL) + mips_monitor_prompt = xstrdup (new_monitor_prompt); + mips_monitor = new_monitor; + + mips_initialize (); + + if (from_tty) + printf_unfiltered ("Remote MIPS debugging using %s\n", serial_port_name); + + /* Switch to using remote target now. */ + push_target (ops); + + /* FIXME: Should we call start_remote here? */ + + /* Try to figure out the processor model if possible. */ + deprecated_mips_set_processor_regs_hack (); + + /* This is really the job of start_remote however, that makes an + assumption that the target is about to print out a status message + of some sort. That doesn't happen here (in fact, it may not be + possible to get the monitor to send the appropriate packet). */ + + flush_cached_frames (); + registers_changed (); + stop_pc = read_pc (); + print_stack_frame (get_selected_frame (), -1, 1); + xfree (serial_port_name); +} + +static void +mips_open (char *name, int from_tty) +{ + const char *monitor_prompt = NULL; + if (TARGET_ARCHITECTURE != NULL + && TARGET_ARCHITECTURE->arch == bfd_arch_mips) + { + switch (TARGET_ARCHITECTURE->mach) + { + case bfd_mach_mips4100: + case bfd_mach_mips4300: + case bfd_mach_mips4600: + case bfd_mach_mips4650: + case bfd_mach_mips5000: + monitor_prompt = " "; + break; + } + } + if (monitor_prompt == NULL) + monitor_prompt = ""; + common_open (&mips_ops, name, from_tty, MON_IDT, monitor_prompt); +} + +static void +pmon_open (char *name, int from_tty) +{ + common_open (&pmon_ops, name, from_tty, MON_PMON, "PMON> "); +} + +static void +ddb_open (char *name, int from_tty) +{ + common_open (&ddb_ops, name, from_tty, MON_DDB, "NEC010>"); +} + +static void +lsi_open (char *name, int from_tty) +{ + int i; + + /* Clear the LSI breakpoint table. */ + for (i = 0; i < MAX_LSI_BREAKPOINTS; i++) + lsi_breakpoints[i].type = BREAK_UNUSED; + + common_open (&lsi_ops, name, from_tty, MON_LSI, "PMON> "); +} + +/* Close a connection to the remote board. */ + +static void +mips_close (int quitting) +{ + if (mips_is_open) + { + /* Get the board out of remote debugging mode. */ + (void) mips_exit_debug (); + + close_ports (); + } +} + +/* Detach from the remote board. */ + +static void +mips_detach (char *args, int from_tty) +{ + if (args) + error ("Argument given to \"detach\" when remotely debugging."); + + pop_target (); + + mips_close (1); + + if (from_tty) + printf_unfiltered ("Ending remote MIPS debugging.\n"); +} + +/* Tell the target board to resume. This does not wait for a reply + from the board, except in the case of single-stepping on LSI boards, + where PMON does return a reply. */ + +static void +mips_resume (ptid_t ptid, int step, enum target_signal siggnal) +{ + int err; + + /* LSI PMON requires returns a reply packet "0x1 s 0x0 0x57f" after + a single step, so we wait for that. */ + mips_request (step ? 's' : 'c', 1, siggnal, + mips_monitor == MON_LSI && step ? &err : (int *) NULL, + mips_receive_wait, NULL); +} + +/* Return the signal corresponding to SIG, where SIG is the number which + the MIPS protocol uses for the signal. */ +static enum target_signal +mips_signal_from_protocol (int sig) +{ + /* We allow a few more signals than the IDT board actually returns, on + the theory that there is at least *some* hope that perhaps the numbering + for these signals is widely agreed upon. */ + if (sig <= 0 + || sig > 31) + return TARGET_SIGNAL_UNKNOWN; + + /* Don't want to use target_signal_from_host because we are converting + from MIPS signal numbers, not host ones. Our internal numbers + match the MIPS numbers for the signals the board can return, which + are: SIGINT, SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP. */ + return (enum target_signal) sig; +} + +/* Wait until the remote stops, and return a wait status. */ + +static ptid_t +mips_wait (ptid_t ptid, struct target_waitstatus *status) +{ + int rstatus; + int err; + char buff[DATA_MAXLEN]; + int rpc, rfp, rsp; + char flags[20]; + int nfields; + int i; + + interrupt_count = 0; + hit_watchpoint = 0; + + /* If we have not sent a single step or continue command, then the + board is waiting for us to do something. Return a status + indicating that it is stopped. */ + if (!mips_need_reply) + { + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = TARGET_SIGNAL_TRAP; + return inferior_ptid; + } + + /* No timeout; we sit here as long as the program continues to execute. */ + mips_wait_flag = 1; + rstatus = mips_request ('\000', 0, 0, &err, -1, buff); + mips_wait_flag = 0; + if (err) + mips_error ("Remote failure: %s", safe_strerror (errno)); + + /* On returning from a continue, the PMON monitor seems to start + echoing back the messages we send prior to sending back the + ACK. The code can cope with this, but to try and avoid the + unnecessary serial traffic, and "spurious" characters displayed + to the user, we cheat and reset the debug protocol. The problems + seems to be caused by a check on the number of arguments, and the + command length, within the monitor causing it to echo the command + as a bad packet. */ + if (mips_monitor == MON_PMON) + { + mips_exit_debug (); + mips_enter_debug (); + } + + /* See if we got back extended status. If so, pick out the pc, fp, sp, etc... */ + + nfields = sscanf (buff, "0x%*x %*c 0x%*x 0x%*x 0x%x 0x%x 0x%x 0x%*x %s", + &rpc, &rfp, &rsp, flags); + if (nfields >= 3) + { + char buf[MAX_REGISTER_SIZE]; + + store_unsigned_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (PC_REGNUM), rpc); + supply_register (PC_REGNUM, buf); + + store_unsigned_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (PC_REGNUM), rfp); + supply_register (30, buf); /* This register they are avoiding and so it is unnamed */ + + store_unsigned_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (SP_REGNUM), rsp); + supply_register (SP_REGNUM, buf); + + store_unsigned_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (DEPRECATED_FP_REGNUM), 0); + supply_register (DEPRECATED_FP_REGNUM, buf); + + if (nfields == 9) + { + int i; + + for (i = 0; i <= 2; i++) + if (flags[i] == 'r' || flags[i] == 'w') + hit_watchpoint = 1; + else if (flags[i] == '\000') + break; + } + } + + if (strcmp (target_shortname, "lsi") == 0) + { +#if 0 + /* If this is an LSI PMON target, see if we just hit a hardrdware watchpoint. + Right now, PMON doesn't give us enough information to determine which + breakpoint we hit. So we have to look up the PC in our own table + of breakpoints, and if found, assume it's just a normal instruction + fetch breakpoint, not a data watchpoint. FIXME when PMON + provides some way to tell us what type of breakpoint it is. */ + int i; + CORE_ADDR pc = read_pc (); + + hit_watchpoint = 1; + for (i = 0; i < MAX_LSI_BREAKPOINTS; i++) + { + if (lsi_breakpoints[i].addr == pc + && lsi_breakpoints[i].type == BREAK_FETCH) + { + hit_watchpoint = 0; + break; + } + } +#else + /* If a data breakpoint was hit, PMON returns the following packet: + 0x1 c 0x0 0x57f 0x1 + The return packet from an ordinary breakpoint doesn't have the + extra 0x01 field tacked onto the end. */ + if (nfields == 1 && rpc == 1) + hit_watchpoint = 1; +#endif + } + + /* NOTE: The following (sig) numbers are defined by PMON: + SPP_SIGTRAP 5 breakpoint + SPP_SIGINT 2 + SPP_SIGSEGV 11 + SPP_SIGBUS 10 + SPP_SIGILL 4 + SPP_SIGFPE 8 + SPP_SIGTERM 15 */ + + /* Translate a MIPS waitstatus. We use constants here rather than WTERMSIG + and so on, because the constants we want here are determined by the + MIPS protocol and have nothing to do with what host we are running on. */ + if ((rstatus & 0xff) == 0) + { + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = (((rstatus) >> 8) & 0xff); + } + else if ((rstatus & 0xff) == 0x7f) + { + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = mips_signal_from_protocol (((rstatus) >> 8) & 0xff); + + /* If the stop PC is in the _exit function, assume + we hit the 'break 0x3ff' instruction in _exit, so this + is not a normal breakpoint. */ + if (strcmp (target_shortname, "lsi") == 0) + { + char *func_name; + CORE_ADDR func_start; + CORE_ADDR pc = read_pc (); + + find_pc_partial_function (pc, &func_name, &func_start, NULL); + if (func_name != NULL && strcmp (func_name, "_exit") == 0 + && func_start == pc) + status->kind = TARGET_WAITKIND_EXITED; + } + } + else + { + status->kind = TARGET_WAITKIND_SIGNALLED; + status->value.sig = mips_signal_from_protocol (rstatus & 0x7f); + } + + return inferior_ptid; +} + +/* We have to map between the register numbers used by gdb and the + register numbers used by the debugging protocol. This function + assumes that we are using tm-mips.h. */ + +#define REGNO_OFFSET 96 + +static int +mips_map_regno (int regno) +{ + if (regno < 32) + return regno; + if (regno >= mips_regnum (current_gdbarch)->fp0 + && regno < mips_regnum (current_gdbarch)->fp0 + 32) + return regno - mips_regnum (current_gdbarch)->fp0 + 32; + else if (regno == mips_regnum (current_gdbarch)->pc) + return REGNO_OFFSET + 0; + else if (regno == mips_regnum (current_gdbarch)->cause) + return REGNO_OFFSET + 1; + else if (regno == mips_regnum (current_gdbarch)->hi) + return REGNO_OFFSET + 2; + else if (regno == mips_regnum (current_gdbarch)->lo) + return REGNO_OFFSET + 3; + else if (regno == mips_regnum (current_gdbarch)->fp_control_status) + return REGNO_OFFSET + 4; + else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision) + return REGNO_OFFSET + 5; + else + /* FIXME: Is there a way to get the status register? */ + return 0; +} + +/* Fetch the remote registers. */ + +static void +mips_fetch_registers (int regno) +{ + unsigned LONGEST val; + int err; + + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + mips_fetch_registers (regno); + return; + } + + if (regno == DEPRECATED_FP_REGNUM || regno == ZERO_REGNUM) + /* DEPRECATED_FP_REGNUM on the mips is a hack which is just + supposed to read zero (see also mips-nat.c). */ + val = 0; + else + { + /* If PMON doesn't support this register, don't waste serial + bandwidth trying to read it. */ + int pmon_reg = mips_map_regno (regno); + if (regno != 0 && pmon_reg == 0) + val = 0; + else + { + /* Unfortunately the PMON version in the Vr4300 board has been + compiled without the 64bit register access commands. This + means we cannot get hold of the full register width. */ + if (mips_monitor == MON_DDB) + val = (unsigned) mips_request ('t', pmon_reg, 0, + &err, mips_receive_wait, NULL); + else + val = mips_request ('r', pmon_reg, 0, + &err, mips_receive_wait, NULL); + if (err) + mips_error ("Can't read register %d: %s", regno, + safe_strerror (errno)); + } + } + + { + char buf[MAX_REGISTER_SIZE]; + + /* We got the number the register holds, but gdb expects to see a + value in the target byte ordering. */ + store_unsigned_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (regno), val); + supply_register (regno, buf); + } +} + +/* Prepare to store registers. The MIPS protocol can store individual + registers, so this function doesn't have to do anything. */ + +static void +mips_prepare_to_store (void) +{ +} + +/* Store remote register(s). */ + +static void +mips_store_registers (int regno) +{ + int err; + + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + mips_store_registers (regno); + return; + } + + mips_request ('R', mips_map_regno (regno), + read_register (regno), + &err, mips_receive_wait, NULL); + if (err) + mips_error ("Can't write register %d: %s", regno, safe_strerror (errno)); +} + +/* Fetch a word from the target board. */ + +static unsigned int +mips_fetch_word (CORE_ADDR addr) +{ + unsigned int val; + int err; + + val = mips_request ('d', addr, 0, &err, mips_receive_wait, NULL); + if (err) + { + /* Data space failed; try instruction space. */ + val = mips_request ('i', addr, 0, &err, + mips_receive_wait, NULL); + if (err) + mips_error ("Can't read address 0x%s: %s", + paddr_nz (addr), safe_strerror (errno)); + } + return val; +} + +/* Store a word to the target board. Returns errno code or zero for + success. If OLD_CONTENTS is non-NULL, put the old contents of that + memory location there. */ + +/* FIXME! make sure only 32-bit quantities get stored! */ +static int +mips_store_word (CORE_ADDR addr, unsigned int val, char *old_contents) +{ + int err; + unsigned int oldcontents; + + oldcontents = mips_request ('D', addr, val, &err, + mips_receive_wait, NULL); + if (err) + { + /* Data space failed; try instruction space. */ + oldcontents = mips_request ('I', addr, val, &err, + mips_receive_wait, NULL); + if (err) + return errno; + } + if (old_contents != NULL) + store_unsigned_integer (old_contents, 4, oldcontents); + return 0; +} + +/* Read or write LEN bytes from inferior memory at MEMADDR, + transferring to or from debugger address MYADDR. Write to inferior + if SHOULD_WRITE is nonzero. Returns length of data written or + read; 0 for error. Note that protocol gives us the correct value + for a longword, since it transfers values in ASCII. We want the + byte values, so we have to swap the longword values. */ + +static int mask_address_p = 1; + +static int +mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, struct target_ops *target) +{ + int i; + CORE_ADDR addr; + int count; + char *buffer; + int status; + + /* PMON targets do not cope well with 64 bit addresses. Mask the + value down to 32 bits. */ + if (mask_address_p) + memaddr &= (CORE_ADDR) 0xffffffff; + + /* Round starting address down to longword boundary. */ + addr = memaddr & ~3; + /* Round ending address up; get number of longwords that makes. */ + count = (((memaddr + len) - addr) + 3) / 4; + /* Allocate buffer of that many longwords. */ + buffer = alloca (count * 4); + + if (write) + { + /* Fill start and end extra bytes of buffer with existing data. */ + if (addr != memaddr || len < 4) + { + /* Need part of initial word -- fetch it. */ + store_unsigned_integer (&buffer[0], 4, mips_fetch_word (addr)); + } + + if (count > 1) + { + /* Need part of last word -- fetch it. FIXME: we do this even + if we don't need it. */ + store_unsigned_integer (&buffer[(count - 1) * 4], 4, + mips_fetch_word (addr + (count - 1) * 4)); + } + + /* Copy data to be written over corresponding part of buffer */ + + memcpy ((char *) buffer + (memaddr & 3), myaddr, len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += 4) + { + status = mips_store_word (addr, + extract_unsigned_integer (&buffer[i * 4], 4), + NULL); + /* Report each kilobyte (we download 32-bit words at a time) */ + if (i % 256 == 255) + { + printf_unfiltered ("*"); + gdb_flush (gdb_stdout); + } + if (status) + { + errno = status; + return 0; + } + /* FIXME: Do we want a QUIT here? */ + } + if (count >= 256) + printf_unfiltered ("\n"); + } + else + { + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += 4) + { + store_unsigned_integer (&buffer[i * 4], 4, mips_fetch_word (addr)); + QUIT; + } + + /* Copy appropriate bytes out of the buffer. */ + memcpy (myaddr, buffer + (memaddr & 3), len); + } + return len; +} + +/* Print info on this target. */ + +static void +mips_files_info (struct target_ops *ignore) +{ + printf_unfiltered ("Debugging a MIPS board over a serial line.\n"); +} + +/* Kill the process running on the board. This will actually only + work if we are doing remote debugging over the console input. I + think that if IDT/sim had the remote debug interrupt enabled on the + right port, we could interrupt the process with a break signal. */ + +static void +mips_kill (void) +{ + if (!mips_wait_flag) + return; + + interrupt_count++; + + if (interrupt_count >= 2) + { + interrupt_count = 0; + + target_terminal_ours (); + + if (query ("Interrupted while waiting for the program.\n\ +Give up (and stop debugging it)? ")) + { + /* Clean up in such a way that mips_close won't try to talk to the + board (it almost surely won't work since we weren't able to talk to + it). */ + mips_wait_flag = 0; + close_ports (); + + printf_unfiltered ("Ending remote MIPS debugging.\n"); + target_mourn_inferior (); + + throw_exception (RETURN_QUIT); + } + + target_terminal_inferior (); + } + + if (remote_debug > 0) + printf_unfiltered ("Sending break\n"); + + serial_send_break (mips_desc); + +#if 0 + if (mips_is_open) + { + char cc; + + /* Send a ^C. */ + cc = '\003'; + serial_write (mips_desc, &cc, 1); + sleep (1); + target_mourn_inferior (); + } +#endif +} + +/* Start running on the target board. */ + +static void +mips_create_inferior (char *execfile, char *args, char **env) +{ + CORE_ADDR entry_pt; + + if (args && *args) + { + warning ("\ +Can't pass arguments to remote MIPS board; arguments ignored."); + /* And don't try to use them on the next "run" command. */ + execute_command ("set args", 0); + } + + if (execfile == 0 || exec_bfd == 0) + error ("No executable file specified"); + + entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd); + + init_wait_for_inferior (); + + /* FIXME: Should we set inferior_ptid here? */ + + proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0); +} + +/* Clean up after a process. Actually nothing to do. */ + +static void +mips_mourn_inferior (void) +{ + if (current_ops != NULL) + unpush_target (current_ops); + generic_mourn_inferior (); +} + +/* We can write a breakpoint and read the shadow contents in one + operation. */ + +/* Insert a breakpoint. On targets that don't have built-in + breakpoint support, we read the contents of the target location and + stash it, then overwrite it with a breakpoint instruction. ADDR is + the target location in the target machine. CONTENTS_CACHE is a + pointer to memory allocated for saving the target contents. It is + guaranteed by the caller to be long enough to save the breakpoint + length returned by BREAKPOINT_FROM_PC. */ + +static int +mips_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + if (monitor_supports_breakpoints) + return set_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH); + else + return memory_insert_breakpoint (addr, contents_cache); +} + +static int +mips_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + if (monitor_supports_breakpoints) + return clear_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH); + else + return memory_remove_breakpoint (addr, contents_cache); +} + +/* Tell whether this target can support a hardware breakpoint. CNT + is the number of hardware breakpoints already installed. This + implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro. */ + +int +mips_can_use_watchpoint (int type, int cnt, int othertype) +{ + return cnt < MAX_LSI_BREAKPOINTS && strcmp (target_shortname, "lsi") == 0; +} + + +/* Compute a don't care mask for the region bounding ADDR and ADDR + LEN - 1. + This is used for memory ref breakpoints. */ + +static unsigned long +calculate_mask (CORE_ADDR addr, int len) +{ + unsigned long mask; + int i; + + mask = addr ^ (addr + len - 1); + + for (i = 32; i >= 0; i--) + if (mask == 0) + break; + else + mask >>= 1; + + mask = (unsigned long) 0xffffffff >> i; + + return mask; +} + + +/* Set a data watchpoint. ADDR and LEN should be obvious. TYPE is 0 + for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write + watchpoint. */ + +int +mips_insert_watchpoint (CORE_ADDR addr, int len, int type) +{ + if (set_breakpoint (addr, len, type)) + return -1; + + return 0; +} + +int +mips_remove_watchpoint (CORE_ADDR addr, int len, int type) +{ + if (clear_breakpoint (addr, len, type)) + return -1; + + return 0; +} + +int +mips_stopped_by_watchpoint (void) +{ + return hit_watchpoint; +} + + +/* Insert a breakpoint. */ + +static int +set_breakpoint (CORE_ADDR addr, int len, enum break_type type) +{ + return common_breakpoint (1, addr, len, type); +} + + +/* Clear a breakpoint. */ + +static int +clear_breakpoint (CORE_ADDR addr, int len, enum break_type type) +{ + return common_breakpoint (0, addr, len, type); +} + + +/* Check the error code from the return packet for an LSI breakpoint + command. If there's no error, just return 0. If it's a warning, + print the warning text and return 0. If it's an error, print + the error text and return 1. is the address of the breakpoint + that was being set. is the error code returned by PMON. + This is a helper function for common_breakpoint. */ + +static int +check_lsi_error (CORE_ADDR addr, int rerrflg) +{ + struct lsi_error *err; + char *saddr = paddr_nz (addr); /* printable address string */ + + if (rerrflg == 0) /* no error */ + return 0; + + /* Warnings can be ORed together, so check them all. */ + if (rerrflg & W_WARN) + { + if (monitor_warnings) + { + int found = 0; + for (err = lsi_warning_table; err->code != 0; err++) + { + if ((err->code & rerrflg) == err->code) + { + found = 1; + fprintf_unfiltered (gdb_stderr, + "common_breakpoint (0x%s): Warning: %s\n", + saddr, + err->string); + } + } + if (!found) + fprintf_unfiltered (gdb_stderr, + "common_breakpoint (0x%s): Unknown warning: 0x%x\n", + saddr, + rerrflg); + } + return 0; + } + + /* Errors are unique, i.e. can't be ORed together. */ + for (err = lsi_error_table; err->code != 0; err++) + { + if ((err->code & rerrflg) == err->code) + { + fprintf_unfiltered (gdb_stderr, + "common_breakpoint (0x%s): Error: %s\n", + saddr, + err->string); + return 1; + } + } + fprintf_unfiltered (gdb_stderr, + "common_breakpoint (0x%s): Unknown error: 0x%x\n", + saddr, + rerrflg); + return 1; +} + + +/* This routine sends a breakpoint command to the remote target. + + is 1 if setting a breakpoint, or 0 if clearing a breakpoint. + is the address of the breakpoint. + the length of the region to break on. + is the type of breakpoint: + 0 = write (BREAK_WRITE) + 1 = read (BREAK_READ) + 2 = read/write (BREAK_ACCESS) + 3 = instruction fetch (BREAK_FETCH) + + Return 0 if successful; otherwise 1. */ + +static int +common_breakpoint (int set, CORE_ADDR addr, int len, enum break_type type) +{ + char buf[DATA_MAXLEN + 1]; + char cmd, rcmd; + int rpid, rerrflg, rresponse, rlen; + int nfields; + + addr = ADDR_BITS_REMOVE (addr); + + if (mips_monitor == MON_LSI) + { + if (set == 0) /* clear breakpoint */ + { + /* The LSI PMON "clear breakpoint" has this form: + 'b' 0x0 + reply: + 'b' 0x0 + + is a breakpoint number returned by an earlier 'B' command. + Possible return codes: OK, E_BPT. */ + + int i; + + /* Search for the breakpoint in the table. */ + for (i = 0; i < MAX_LSI_BREAKPOINTS; i++) + if (lsi_breakpoints[i].type == type + && lsi_breakpoints[i].addr == addr + && lsi_breakpoints[i].len == len) + break; + + /* Clear the table entry and tell PMON to clear the breakpoint. */ + if (i == MAX_LSI_BREAKPOINTS) + { + warning ("common_breakpoint: Attempt to clear bogus breakpoint at %s\n", + paddr_nz (addr)); + return 1; + } + + lsi_breakpoints[i].type = BREAK_UNUSED; + sprintf (buf, "0x0 b 0x%x 0x0", i); + mips_send_packet (buf, 1); + + rlen = mips_receive_packet (buf, 1, mips_receive_wait); + buf[rlen] = '\0'; + + nfields = sscanf (buf, "0x%x b 0x0 0x%x", &rpid, &rerrflg); + if (nfields != 2) + mips_error ("common_breakpoint: Bad response from remote board: %s", buf); + + return (check_lsi_error (addr, rerrflg)); + } + else + /* set a breakpoint */ + { + /* The LSI PMON "set breakpoint" command has this form: + 'B' 0x0 + reply: + 'B' + + The "set data breakpoint" command has this form: + + 'A' [ []] + + where: type= "0x1" = read + "0x2" = write + "0x3" = access (read or write) + + The reply returns two values: + bptn - a breakpoint number, which is a small integer with + possible values of zero through 255. + code - an error return code, a value of zero indicates a + succesful completion, other values indicate various + errors and warnings. + + Possible return codes: OK, W_QAL, E_QAL, E_OUT, E_NON. + + */ + + if (type == BREAK_FETCH) /* instruction breakpoint */ + { + cmd = 'B'; + sprintf (buf, "0x0 B 0x%s 0x0", paddr_nz (addr)); + } + else + /* watchpoint */ + { + cmd = 'A'; + sprintf (buf, "0x0 A 0x%s 0x%x 0x%s", paddr_nz (addr), + type == BREAK_READ ? 1 : (type == BREAK_WRITE ? 2 : 3), + paddr_nz (addr + len - 1)); + } + mips_send_packet (buf, 1); + + rlen = mips_receive_packet (buf, 1, mips_receive_wait); + buf[rlen] = '\0'; + + nfields = sscanf (buf, "0x%x %c 0x%x 0x%x", + &rpid, &rcmd, &rresponse, &rerrflg); + if (nfields != 4 || rcmd != cmd || rresponse > 255) + mips_error ("common_breakpoint: Bad response from remote board: %s", buf); + + if (rerrflg != 0) + if (check_lsi_error (addr, rerrflg)) + return 1; + + /* rresponse contains PMON's breakpoint number. Record the + information for this breakpoint so we can clear it later. */ + lsi_breakpoints[rresponse].type = type; + lsi_breakpoints[rresponse].addr = addr; + lsi_breakpoints[rresponse].len = len; + + return 0; + } + } + else + { + /* On non-LSI targets, the breakpoint command has this form: + 0x0 + is a don't care mask for addresses. + is any combination of `r', `w', or `f' for read/write/fetch. + */ + unsigned long mask; + + mask = calculate_mask (addr, len); + addr &= ~mask; + + if (set) /* set a breakpoint */ + { + char *flags; + switch (type) + { + case BREAK_WRITE: /* write */ + flags = "w"; + break; + case BREAK_READ: /* read */ + flags = "r"; + break; + case BREAK_ACCESS: /* read/write */ + flags = "rw"; + break; + case BREAK_FETCH: /* fetch */ + flags = "f"; + break; + default: + internal_error (__FILE__, __LINE__, "failed internal consistency check"); + } + + cmd = 'B'; + sprintf (buf, "0x0 B 0x%s 0x%s %s", paddr_nz (addr), + paddr_nz (mask), flags); + } + else + { + cmd = 'b'; + sprintf (buf, "0x0 b 0x%s", paddr_nz (addr)); + } + + mips_send_packet (buf, 1); + + rlen = mips_receive_packet (buf, 1, mips_receive_wait); + buf[rlen] = '\0'; + + nfields = sscanf (buf, "0x%x %c 0x%x 0x%x", + &rpid, &rcmd, &rerrflg, &rresponse); + + if (nfields != 4 || rcmd != cmd) + mips_error ("common_breakpoint: Bad response from remote board: %s", + buf); + + if (rerrflg != 0) + { + /* Ddb returns "0x0 b 0x16 0x0\000", whereas + Cogent returns "0x0 b 0xffffffff 0x16\000": */ + if (mips_monitor == MON_DDB) + rresponse = rerrflg; + if (rresponse != 22) /* invalid argument */ + fprintf_unfiltered (gdb_stderr, + "common_breakpoint (0x%s): Got error: 0x%x\n", + paddr_nz (addr), rresponse); + return 1; + } + } + return 0; +} + +static void +send_srec (char *srec, int len, CORE_ADDR addr) +{ + while (1) + { + int ch; + + serial_write (mips_desc, srec, len); + + ch = mips_readchar (remote_timeout); + + switch (ch) + { + case SERIAL_TIMEOUT: + error ("Timeout during download."); + break; + case 0x6: /* ACK */ + return; + case 0x15: /* NACK */ + fprintf_unfiltered (gdb_stderr, "Download got a NACK at byte %s! Retrying.\n", paddr_u (addr)); + continue; + default: + error ("Download got unexpected ack char: 0x%x, retrying.\n", ch); + } + } +} + +/* Download a binary file by converting it to S records. */ + +static void +mips_load_srec (char *args) +{ + bfd *abfd; + asection *s; + char *buffer, srec[1024]; + unsigned int i; + unsigned int srec_frame = 200; + int reclen; + static int hashmark = 1; + + buffer = alloca (srec_frame * 2 + 256); + + abfd = bfd_openr (args, 0); + if (!abfd) + { + printf_filtered ("Unable to open file %s\n", args); + return; + } + + if (bfd_check_format (abfd, bfd_object) == 0) + { + printf_filtered ("File is not an object file\n"); + return; + } + +/* This actually causes a download in the IDT binary format: */ + mips_send_command (LOAD_CMD, 0); + + for (s = abfd->sections; s; s = s->next) + { + if (s->flags & SEC_LOAD) + { + unsigned int numbytes; + + /* FIXME! vma too small????? */ + printf_filtered ("%s\t: 0x%4lx .. 0x%4lx ", s->name, + (long) s->vma, + (long) (s->vma + s->_raw_size)); + gdb_flush (gdb_stdout); + + for (i = 0; i < s->_raw_size; i += numbytes) + { + numbytes = min (srec_frame, s->_raw_size - i); + + bfd_get_section_contents (abfd, s, buffer, i, numbytes); + + reclen = mips_make_srec (srec, '3', s->vma + i, buffer, numbytes); + send_srec (srec, reclen, s->vma + i); + + if (ui_load_progress_hook) + ui_load_progress_hook (s->name, i); + + if (hashmark) + { + putchar_unfiltered ('#'); + gdb_flush (gdb_stdout); + } + + } /* Per-packet (or S-record) loop */ + + putchar_unfiltered ('\n'); + } /* Loadable sections */ + } + if (hashmark) + putchar_unfiltered ('\n'); + + /* Write a type 7 terminator record. no data for a type 7, and there + is no data, so len is 0. */ + + reclen = mips_make_srec (srec, '7', abfd->start_address, NULL, 0); + + send_srec (srec, reclen, abfd->start_address); + + serial_flush_input (mips_desc); +} + +/* + * mips_make_srec -- make an srecord. This writes each line, one at a + * time, each with it's own header and trailer line. + * An srecord looks like this: + * + * byte count-+ address + * start ---+ | | data +- checksum + * | | | | + * S01000006F6B692D746573742E73726563E4 + * S315000448600000000000000000FC00005900000000E9 + * S31A0004000023C1400037DE00F023604000377B009020825000348D + * S30B0004485A0000000000004E + * S70500040000F6 + * + * S
+ * + * Where + * - length + * is the number of bytes following upto the checksum. Note that + * this is not the number of chars following, since it takes two + * chars to represent a byte. + * - type + * is one of: + * 0) header record + * 1) two byte address data record + * 2) three byte address data record + * 3) four byte address data record + * 7) four byte address termination record + * 8) three byte address termination record + * 9) two byte address termination record + * + * - address + * is the start address of the data following, or in the case of + * a termination record, the start address of the image + * - data + * is the data. + * - checksum + * is the sum of all the raw byte data in the record, from the length + * upwards, modulo 256 and subtracted from 255. + * + * This routine returns the length of the S-record. + * + */ + +static int +mips_make_srec (char *buf, int type, CORE_ADDR memaddr, unsigned char *myaddr, + int len) +{ + unsigned char checksum; + int i; + + /* Create the header for the srec. addr_size is the number of bytes in the address, + and 1 is the number of bytes in the count. */ + + /* FIXME!! bigger buf required for 64-bit! */ + buf[0] = 'S'; + buf[1] = type; + buf[2] = len + 4 + 1; /* len + 4 byte address + 1 byte checksum */ + /* This assumes S3 style downloads (4byte addresses). There should + probably be a check, or the code changed to make it more + explicit. */ + buf[3] = memaddr >> 24; + buf[4] = memaddr >> 16; + buf[5] = memaddr >> 8; + buf[6] = memaddr; + memcpy (&buf[7], myaddr, len); + + /* Note that the checksum is calculated on the raw data, not the + hexified data. It includes the length, address and the data + portions of the packet. */ + checksum = 0; + buf += 2; /* Point at length byte */ + for (i = 0; i < len + 4 + 1; i++) + checksum += *buf++; + + *buf = ~checksum; + + return len + 8; +} + +/* The following manifest controls whether we enable the simple flow + control support provided by the monitor. If enabled the code will + wait for an affirmative ACK between transmitting packets. */ +#define DOETXACK (1) + +/* The PMON fast-download uses an encoded packet format constructed of + 3byte data packets (encoded as 4 printable ASCII characters), and + escape sequences (preceded by a '/'): + + 'K' clear checksum + 'C' compare checksum (12bit value, not included in checksum calculation) + 'S' define symbol name (for addr) terminated with "," and padded to 4char boundary + 'Z' zero fill multiple of 3bytes + 'B' byte (12bit encoded value, of 8bit data) + 'A' address (36bit encoded value) + 'E' define entry as original address, and exit load + + The packets are processed in 4 character chunks, so the escape + sequences that do not have any data (or variable length data) + should be padded to a 4 character boundary. The decoder will give + an error if the complete message block size is not a multiple of + 4bytes (size of record). + + The encoding of numbers is done in 6bit fields. The 6bit value is + used to index into this string to get the specific character + encoding for the value: */ +static char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,."; + +/* Convert the number of bits required into an encoded number, 6bits + at a time (range 0..63). Keep a checksum if required (passed + pointer non-NULL). The function returns the number of encoded + characters written into the buffer. */ +static int +pmon_makeb64 (unsigned long v, char *p, int n, int *chksum) +{ + int count = (n / 6); + + if ((n % 12) != 0) + { + fprintf_unfiltered (gdb_stderr, + "Fast encoding bitcount must be a multiple of 12bits: %dbit%s\n", n, (n == 1) ? "" : "s"); + return (0); + } + if (n > 36) + { + fprintf_unfiltered (gdb_stderr, + "Fast encoding cannot process more than 36bits at the moment: %dbits\n", n); + return (0); + } + + /* Deal with the checksum: */ + if (chksum != NULL) + { + switch (n) + { + case 36: + *chksum += ((v >> 24) & 0xFFF); + case 24: + *chksum += ((v >> 12) & 0xFFF); + case 12: + *chksum += ((v >> 0) & 0xFFF); + } + } + + do + { + n -= 6; + *p++ = encoding[(v >> n) & 0x3F]; + } + while (n > 0); + + return (count); +} + +/* Shorthand function (that could be in-lined) to output the zero-fill + escape sequence into the data stream. */ +static int +pmon_zeroset (int recsize, char **buff, int *amount, unsigned int *chksum) +{ + int count; + + sprintf (*buff, "/Z"); + count = pmon_makeb64 (*amount, (*buff + 2), 12, chksum); + *buff += (count + 2); + *amount = 0; + return (recsize + count + 2); +} + +static int +pmon_checkset (int recsize, char **buff, int *value) +{ + int count; + + /* Add the checksum (without updating the value): */ + sprintf (*buff, "/C"); + count = pmon_makeb64 (*value, (*buff + 2), 12, NULL); + *buff += (count + 2); + sprintf (*buff, "\n"); + *buff += 2; /* include zero terminator */ + /* Forcing a checksum validation clears the sum: */ + *value = 0; + return (recsize + count + 3); +} + +/* Amount of padding we leave after at the end of the output buffer, + for the checksum and line termination characters: */ +#define CHECKSIZE (4 + 4 + 4 + 2) +/* zero-fill, checksum, transfer end and line termination space. */ + +/* The amount of binary data loaded from the object file in a single + operation: */ +#define BINCHUNK (1024) + +/* Maximum line of data accepted by the monitor: */ +#define MAXRECSIZE (550) +/* NOTE: This constant depends on the monitor being used. This value + is for PMON 5.x on the Cogent Vr4300 board. */ + +static void +pmon_make_fastrec (char **outbuf, unsigned char *inbuf, int *inptr, + int inamount, int *recsize, unsigned int *csum, + unsigned int *zerofill) +{ + int count = 0; + char *p = *outbuf; + + /* This is a simple check to ensure that our data will fit within + the maximum allowable record size. Each record output is 4bytes + in length. We must allow space for a pending zero fill command, + the record, and a checksum record. */ + while ((*recsize < (MAXRECSIZE - CHECKSIZE)) && ((inamount - *inptr) > 0)) + { + /* Process the binary data: */ + if ((inamount - *inptr) < 3) + { + if (*zerofill != 0) + *recsize = pmon_zeroset (*recsize, &p, zerofill, csum); + sprintf (p, "/B"); + count = pmon_makeb64 (inbuf[*inptr], &p[2], 12, csum); + p += (2 + count); + *recsize += (2 + count); + (*inptr)++; + } + else + { + unsigned int value = ((inbuf[*inptr + 0] << 16) | (inbuf[*inptr + 1] << 8) | inbuf[*inptr + 2]); + /* Simple check for zero data. TODO: A better check would be + to check the last, and then the middle byte for being zero + (if the first byte is not). We could then check for + following runs of zeros, and if above a certain size it is + worth the 4 or 8 character hit of the byte insertions used + to pad to the start of the zeroes. NOTE: This also depends + on the alignment at the end of the zero run. */ + if (value == 0x00000000) + { + (*zerofill)++; + if (*zerofill == 0xFFF) /* 12bit counter */ + *recsize = pmon_zeroset (*recsize, &p, zerofill, csum); + } + else + { + if (*zerofill != 0) + *recsize = pmon_zeroset (*recsize, &p, zerofill, csum); + count = pmon_makeb64 (value, p, 24, csum); + p += count; + *recsize += count; + } + *inptr += 3; + } + } + + *outbuf = p; + return; +} + +static int +pmon_check_ack (char *mesg) +{ +#if defined(DOETXACK) + int c; + + if (!tftp_in_use) + { + c = serial_readchar (udp_in_use ? udp_desc : mips_desc, + remote_timeout); + if ((c == SERIAL_TIMEOUT) || (c != 0x06)) + { + fprintf_unfiltered (gdb_stderr, + "Failed to receive valid ACK for %s\n", mesg); + return (-1); /* terminate the download */ + } + } +#endif /* DOETXACK */ + return (0); +} + +/* pmon_download - Send a sequence of characters to the PMON download port, + which is either a serial port or a UDP socket. */ + +static void +pmon_start_download (void) +{ + if (tftp_in_use) + { + /* Create the temporary download file. */ + if ((tftp_file = fopen (tftp_localname, "w")) == NULL) + perror_with_name (tftp_localname); + } + else + { + mips_send_command (udp_in_use ? LOAD_CMD_UDP : LOAD_CMD, 0); + mips_expect ("Downloading from "); + mips_expect (udp_in_use ? "udp" : "tty0"); + mips_expect (", ^C to abort\r\n"); + } +} + +static int +mips_expect_download (char *string) +{ + if (!mips_expect (string)) + { + fprintf_unfiltered (gdb_stderr, "Load did not complete successfully.\n"); + if (tftp_in_use) + remove (tftp_localname); /* Remove temporary file */ + return 0; + } + else + return 1; +} + +static void +pmon_check_entry_address (char *entry_address, int final) +{ + char hexnumber[9]; /* includes '\0' space */ + mips_expect_timeout (entry_address, tftp_in_use ? 15 : remote_timeout); + sprintf (hexnumber, "%x", final); + mips_expect (hexnumber); + mips_expect ("\r\n"); +} + +static int +pmon_check_total (int bintotal) +{ + char hexnumber[9]; /* includes '\0' space */ + mips_expect ("\r\ntotal = 0x"); + sprintf (hexnumber, "%x", bintotal); + mips_expect (hexnumber); + return mips_expect_download (" bytes\r\n"); +} + +static void +pmon_end_download (int final, int bintotal) +{ + char hexnumber[9]; /* includes '\0' space */ + + if (tftp_in_use) + { + static char *load_cmd_prefix = "load -b -s "; + char *cmd; + struct stat stbuf; + + /* Close off the temporary file containing the load data. */ + fclose (tftp_file); + tftp_file = NULL; + + /* Make the temporary file readable by the world. */ + if (stat (tftp_localname, &stbuf) == 0) + chmod (tftp_localname, stbuf.st_mode | S_IROTH); + + /* Must reinitialize the board to prevent PMON from crashing. */ + mips_send_command ("initEther\r", -1); + + /* Send the load command. */ + cmd = xmalloc (strlen (load_cmd_prefix) + strlen (tftp_name) + 2); + strcpy (cmd, load_cmd_prefix); + strcat (cmd, tftp_name); + strcat (cmd, "\r"); + mips_send_command (cmd, 0); + xfree (cmd); + if (!mips_expect_download ("Downloading from ")) + return; + if (!mips_expect_download (tftp_name)) + return; + if (!mips_expect_download (", ^C to abort\r\n")) + return; + } + + /* Wait for the stuff that PMON prints after the load has completed. + The timeout value for use in the tftp case (15 seconds) was picked + arbitrarily but might be too small for really large downloads. FIXME. */ + switch (mips_monitor) + { + case MON_LSI: + pmon_check_ack ("termination"); + pmon_check_entry_address ("Entry address is ", final); + if (!pmon_check_total (bintotal)) + return; + break; + default: + pmon_check_entry_address ("Entry Address = ", final); + pmon_check_ack ("termination"); + if (!pmon_check_total (bintotal)) + return; + break; + } + + if (tftp_in_use) + remove (tftp_localname); /* Remove temporary file */ +} + +static void +pmon_download (char *buffer, int length) +{ + if (tftp_in_use) + fwrite (buffer, 1, length, tftp_file); + else + serial_write (udp_in_use ? udp_desc : mips_desc, buffer, length); +} + +static void +pmon_load_fast (char *file) +{ + bfd *abfd; + asection *s; + unsigned char *binbuf; + char *buffer; + int reclen; + unsigned int csum = 0; + int hashmark = !tftp_in_use; + int bintotal = 0; + int final = 0; + int finished = 0; + + buffer = (char *) xmalloc (MAXRECSIZE + 1); + binbuf = (unsigned char *) xmalloc (BINCHUNK); + + abfd = bfd_openr (file, 0); + if (!abfd) + { + printf_filtered ("Unable to open file %s\n", file); + return; + } + + if (bfd_check_format (abfd, bfd_object) == 0) + { + printf_filtered ("File is not an object file\n"); + return; + } + + /* Setup the required download state: */ + mips_send_command ("set dlproto etxack\r", -1); + mips_send_command ("set dlecho off\r", -1); + /* NOTE: We get a "cannot set variable" message if the variable is + already defined to have the argument we give. The code doesn't + care, since it just scans to the next prompt anyway. */ + /* Start the download: */ + pmon_start_download (); + + /* Zero the checksum */ + sprintf (buffer, "/Kxx\n"); + reclen = strlen (buffer); + pmon_download (buffer, reclen); + finished = pmon_check_ack ("/Kxx"); + + for (s = abfd->sections; s && !finished; s = s->next) + if (s->flags & SEC_LOAD) /* only deal with loadable sections */ + { + bintotal += s->_raw_size; + final = (s->vma + s->_raw_size); + + printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, (unsigned int) s->vma, + (unsigned int) (s->vma + s->_raw_size)); + gdb_flush (gdb_stdout); + + /* Output the starting address */ + sprintf (buffer, "/A"); + reclen = pmon_makeb64 (s->vma, &buffer[2], 36, &csum); + buffer[2 + reclen] = '\n'; + buffer[3 + reclen] = '\0'; + reclen += 3; /* for the initial escape code and carriage return */ + pmon_download (buffer, reclen); + finished = pmon_check_ack ("/A"); + + if (!finished) + { + unsigned int binamount; + unsigned int zerofill = 0; + char *bp = buffer; + unsigned int i; + + reclen = 0; + + for (i = 0; ((i < s->_raw_size) && !finished); i += binamount) + { + int binptr = 0; + + binamount = min (BINCHUNK, s->_raw_size - i); + + bfd_get_section_contents (abfd, s, binbuf, i, binamount); + + /* This keeps a rolling checksum, until we decide to output + the line: */ + for (; ((binamount - binptr) > 0);) + { + pmon_make_fastrec (&bp, binbuf, &binptr, binamount, &reclen, &csum, &zerofill); + if (reclen >= (MAXRECSIZE - CHECKSIZE)) + { + reclen = pmon_checkset (reclen, &bp, &csum); + pmon_download (buffer, reclen); + finished = pmon_check_ack ("data record"); + if (finished) + { + zerofill = 0; /* do not transmit pending zerofills */ + break; + } + + if (ui_load_progress_hook) + ui_load_progress_hook (s->name, i); + + if (hashmark) + { + putchar_unfiltered ('#'); + gdb_flush (gdb_stdout); + } + + bp = buffer; + reclen = 0; /* buffer processed */ + } + } + } + + /* Ensure no out-standing zerofill requests: */ + if (zerofill != 0) + reclen = pmon_zeroset (reclen, &bp, &zerofill, &csum); + + /* and then flush the line: */ + if (reclen > 0) + { + reclen = pmon_checkset (reclen, &bp, &csum); + /* Currently pmon_checkset outputs the line terminator by + default, so we write out the buffer so far: */ + pmon_download (buffer, reclen); + finished = pmon_check_ack ("record remnant"); + } + } + + putchar_unfiltered ('\n'); + } + + /* Terminate the transfer. We know that we have an empty output + buffer at this point. */ + sprintf (buffer, "/E/E\n"); /* include dummy padding characters */ + reclen = strlen (buffer); + pmon_download (buffer, reclen); + + if (finished) + { /* Ignore the termination message: */ + serial_flush_input (udp_in_use ? udp_desc : mips_desc); + } + else + { /* Deal with termination message: */ + pmon_end_download (final, bintotal); + } + + return; +} + +/* mips_load -- download a file. */ + +static void +mips_load (char *file, int from_tty) +{ + /* Get the board out of remote debugging mode. */ + if (mips_exit_debug ()) + error ("mips_load: Couldn't get into monitor mode."); + + if (mips_monitor != MON_IDT) + pmon_load_fast (file); + else + mips_load_srec (file); + + mips_initialize (); + + /* Finally, make the PC point at the start address */ + if (mips_monitor != MON_IDT) + { + /* Work around problem where PMON monitor updates the PC after a load + to a different value than GDB thinks it has. The following ensures + that the write_pc() WILL update the PC value: */ + deprecated_register_valid[PC_REGNUM] = 0; + } + if (exec_bfd) + write_pc (bfd_get_start_address (exec_bfd)); + + inferior_ptid = null_ptid; /* No process now */ + +/* This is necessary because many things were based on the PC at the time that + we attached to the monitor, which is no longer valid now that we have loaded + new code (and just changed the PC). Another way to do this might be to call + normal_stop, except that the stack may not be valid, and things would get + horribly confused... */ + + clear_symtab_users (); +} + + +/* Pass the command argument as a packet to PMON verbatim. */ + +static void +pmon_command (char *args, int from_tty) +{ + char buf[DATA_MAXLEN + 1]; + int rlen; + + sprintf (buf, "0x0 %s", args); + mips_send_packet (buf, 1); + printf_filtered ("Send packet: %s\n", buf); + + rlen = mips_receive_packet (buf, 1, mips_receive_wait); + buf[rlen] = '\0'; + printf_filtered ("Received packet: %s\n", buf); +} + +extern initialize_file_ftype _initialize_remote_mips; /* -Wmissing-prototypes */ + +void +_initialize_remote_mips (void) +{ + /* Initialize the fields in mips_ops that are common to all four targets. */ + mips_ops.to_longname = "Remote MIPS debugging over serial line"; + mips_ops.to_close = mips_close; + mips_ops.to_detach = mips_detach; + mips_ops.to_resume = mips_resume; + mips_ops.to_fetch_registers = mips_fetch_registers; + mips_ops.to_store_registers = mips_store_registers; + mips_ops.to_prepare_to_store = mips_prepare_to_store; + mips_ops.to_xfer_memory = mips_xfer_memory; + mips_ops.to_files_info = mips_files_info; + mips_ops.to_insert_breakpoint = mips_insert_breakpoint; + mips_ops.to_remove_breakpoint = mips_remove_breakpoint; + mips_ops.to_insert_watchpoint = mips_insert_watchpoint; + mips_ops.to_remove_watchpoint = mips_remove_watchpoint; + mips_ops.to_stopped_by_watchpoint = mips_stopped_by_watchpoint; + mips_ops.to_can_use_hw_breakpoint = mips_can_use_watchpoint; + mips_ops.to_kill = mips_kill; + mips_ops.to_load = mips_load; + mips_ops.to_create_inferior = mips_create_inferior; + mips_ops.to_mourn_inferior = mips_mourn_inferior; + mips_ops.to_stratum = process_stratum; + mips_ops.to_has_all_memory = 1; + mips_ops.to_has_memory = 1; + mips_ops.to_has_stack = 1; + mips_ops.to_has_registers = 1; + mips_ops.to_has_execution = 1; + mips_ops.to_magic = OPS_MAGIC; + + /* Copy the common fields to all four target vectors. */ + pmon_ops = ddb_ops = lsi_ops = mips_ops; + + /* Initialize target-specific fields in the target vectors. */ + mips_ops.to_shortname = "mips"; + mips_ops.to_doc = "\ +Debug a board using the MIPS remote debugging protocol over a serial line.\n\ +The argument is the device it is connected to or, if it contains a colon,\n\ +HOST:PORT to access a board over a network"; + mips_ops.to_open = mips_open; + mips_ops.to_wait = mips_wait; + + pmon_ops.to_shortname = "pmon"; + pmon_ops.to_doc = "\ +Debug a board using the PMON MIPS remote debugging protocol over a serial\n\ +line. The argument is the device it is connected to or, if it contains a\n\ +colon, HOST:PORT to access a board over a network"; + pmon_ops.to_open = pmon_open; + pmon_ops.to_wait = mips_wait; + + ddb_ops.to_shortname = "ddb"; + ddb_ops.to_doc = "\ +Debug a board using the PMON MIPS remote debugging protocol over a serial\n\ +line. The first argument is the device it is connected to or, if it contains\n\ +a colon, HOST:PORT to access a board over a network. The optional second\n\ +parameter is the temporary file in the form HOST:FILENAME to be used for\n\ +TFTP downloads to the board. The optional third parameter is the local name\n\ +of the TFTP temporary file, if it differs from the filename seen by the board."; + ddb_ops.to_open = ddb_open; + ddb_ops.to_wait = mips_wait; + + lsi_ops.to_shortname = "lsi"; + lsi_ops.to_doc = pmon_ops.to_doc; + lsi_ops.to_open = lsi_open; + lsi_ops.to_wait = mips_wait; + + /* Add the targets. */ + add_target (&mips_ops); + add_target (&pmon_ops); + add_target (&ddb_ops); + add_target (&lsi_ops); + + add_show_from_set ( + add_set_cmd ("timeout", no_class, var_zinteger, + (char *) &mips_receive_wait, + "Set timeout in seconds for remote MIPS serial I/O.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("retransmit-timeout", no_class, var_zinteger, + (char *) &mips_retransmit_wait, + "Set retransmit timeout in seconds for remote MIPS serial I/O.\n\ +This is the number of seconds to wait for an acknowledgement to a packet\n\ +before resending the packet.", &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("syn-garbage-limit", no_class, var_zinteger, + (char *) &mips_syn_garbage, + "Set the maximum number of characters to ignore when scanning for a SYN.\n\ +This is the maximum number of characters GDB will ignore when trying to\n\ +synchronize with the remote system. A value of -1 means that there is no limit\n\ +(Note that these characters are printed out even though they are ignored.)", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ("monitor-prompt", class_obscure, var_string, + (char *) &mips_monitor_prompt, + "Set the prompt that GDB expects from the monitor.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("monitor-warnings", class_obscure, var_zinteger, + (char *) &monitor_warnings, + "Set printing of monitor warnings.\n" + "When enabled, monitor warnings about hardware breakpoints " + "will be displayed.", + &setlist), + &showlist); + + add_com ("pmon ", class_obscure, pmon_command, + "Send a packet to PMON (must be in debug mode)."); + + add_show_from_set (add_set_cmd ("mask-address", no_class, + var_boolean, &mask_address_p, + "Set zeroing of upper 32 bits of 64-bit addresses when talking to PMON targets.\n\ +Use \"on\" to enable the masking and \"off\" to disable it.\n", + &setlist), + &showlist); +} diff --git a/contrib/gdb/gdb/remote-rdi.c b/contrib/gdb/gdb/remote-rdi.c index db51dcbcbab..268ed328f6c 100644 --- a/contrib/gdb/gdb/remote-rdi.c +++ b/contrib/gdb/gdb/remote-rdi.c @@ -66,8 +66,6 @@ static void arm_rdi_fetch_registers (int regno); static void arm_rdi_resume (ptid_t pid, int step, enum target_signal siggnal); -static int arm_rdi_start_remote (char *dummy); - static void arm_rdi_open (char *name, int from_tty); static void arm_rdi_create_inferior (char *exec_file, char *args, char **env); @@ -76,22 +74,12 @@ static void arm_rdi_close (int quitting); static void arm_rdi_store_registers (int regno); -static void arm_rdi_mourn (void); - -static void arm_rdi_send (char *buf); - static ptid_t arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status); static void arm_rdi_kill (void); static void arm_rdi_detach (char *args, int from_tty); -static void arm_rdi_interrupt (int signo); - -static void arm_rdi_interrupt_twice (int signo); - -static void interrupt_query (void); - static int arm_rdi_insert_breakpoint (CORE_ADDR, char *); static int arm_rdi_remove_breakpoint (CORE_ADDR, char *); @@ -134,39 +122,30 @@ static struct local_bp_list_entry } *local_bp_list; - -/* Stub for catch_errors. */ - -static int -arm_rdi_start_remote (char *dummy) -{ - return 1; -} - /* Helper callbacks for the "host interface" structure. RDI functions call these to forward output from the target system and so forth. */ -void +static void voiddummy (void *dummy) { fprintf_unfiltered (gdb_stdout, "void dummy\n"); } static void -myprint (PTR arg, const char *format, va_list ap) +myprint (void *arg, const char *format, va_list ap) { vfprintf_unfiltered (gdb_stdout, format, ap); } static void -mywritec (PTR arg, int c) +mywritec (void *arg, int c) { if (isascii (c)) fputc_unfiltered (c, gdb_stdout); } static int -mywrite (PTR arg, char const *buffer, int len) +mywrite (void *arg, char const *buffer, int len) { int i; char *e; @@ -185,7 +164,7 @@ mywrite (PTR arg, char const *buffer, int len) } static void -mypause (PTR arg) +mypause (void *arg) { } @@ -193,13 +172,13 @@ mypause (PTR arg) being interrupted more carefully */ static int -myreadc (PTR arg) +myreadc (void *arg) { return fgetc (stdin); } static char * -mygets (PTR arg, char *buffer, int len) +mygets (void *arg, char *buffer, int len) { return fgets (buffer, len, stdin); } @@ -265,7 +244,7 @@ device is attached to the remote system (e.g. /dev/ttya)."); rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL); if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian) ; /* do nothing, this is the expected return */ - else if (rslt) + else if (rslt != RDIError_NoError) { printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); Adp_CloseDevice (); @@ -273,33 +252,33 @@ device is attached to the remote system (e.g. /dev/ttya)."); } rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } @@ -310,7 +289,7 @@ device is attached to the remote system (e.g. /dev/ttya)."); target_fetch_registers (-1); rslt = angel_RDI_open (1, &gdb_config, NULL, NULL); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); } @@ -318,14 +297,14 @@ device is attached to the remote system (e.g. /dev/ttya)."); arg1 = rom_at_zero ? 0x0 : 0x13b; rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } arg1 = (unsigned long) ""; rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } @@ -397,7 +376,7 @@ arm_rdi_create_inferior (char *exec_file, char *args, char **env) top_of_memory); rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } @@ -408,7 +387,7 @@ arm_rdi_create_inferior (char *exec_file, char *args, char **env) arg1 = (unsigned long) arg_buf; rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } @@ -437,7 +416,7 @@ arm_rdi_close (int quitting) if (!closed_already) { rslt = angel_RDI_close (); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt)); } @@ -459,15 +438,13 @@ arm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal) if (0 /* turn on when hardware supports single-stepping */ ) { rslt = angel_RDI_step (1, &point); - if (rslt) - { - printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt)); - } + if (rslt != RDIError_NoError) + printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt)); } else { char handle[4]; - CORE_ADDR pc; + CORE_ADDR pc = 0; if (step) { @@ -475,43 +452,16 @@ arm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal) pc = arm_get_next_pc (pc); arm_rdi_insert_breakpoint (pc, handle); } + execute_status = rslt = angel_RDI_execute (&point); - if (rslt == RDIError_BreakpointReached) - ; - else if (rslt) - { - printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt)); - } + if (rslt != RDIError_NoError && rslt != RDIError_BreakpointReached) + printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt)); + if (step) - { - arm_rdi_remove_breakpoint (pc, handle); - } + arm_rdi_remove_breakpoint (pc, handle); } } -/* Send ^C to target to halt it. Target will respond, and send us a - packet. */ - -static void -arm_rdi_interrupt (int signo) -{ -} - -static void (*ofunc) (); - -/* The user typed ^C twice. */ -static void -arm_rdi_interrupt_twice (int signo) -{ -} - -/* Ask the user what to do when an interrupt is received. */ - -static void -interrupt_query (void) -{ -} - /* Wait until the remote machine stops, then return, storing status in STATUS just as `wait' would. Returns "pid" (though it's not clear what, if anything, that means in the case of this target). */ @@ -530,7 +480,6 @@ arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status) /* Read the remote registers into the block REGS. */ -/* ARGSUSED */ static void arm_rdi_fetch_registers (int regno) { @@ -541,7 +490,7 @@ arm_rdi_fetch_registers (int regno) if (regno == -1) { rslt = angel_RDI_CPUread (255, 0x27fff, rawregs); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt)); } @@ -571,7 +520,7 @@ arm_rdi_fetch_registers (int regno) rdi_regmask = 1 << regno; rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt)); } @@ -604,7 +553,7 @@ arm_rdi_store_registers (int regno) } else { - read_register_gen (regno, (char *) rawreg); + deprecated_read_register_gen (regno, (char *) rawreg); /* RDI manipulates data in host byte order, so convert now. */ store_unsigned_integer (rawerreg, 4, rawreg[0]); @@ -618,7 +567,7 @@ arm_rdi_store_registers (int regno) rdi_regmask = 1 << regno; rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt)); } @@ -630,7 +579,6 @@ arm_rdi_store_registers (int regno) if SHOULD_WRITE is nonzero. Returns length of data written or read; 0 for error. TARGET is unused. */ -/* ARGSUSED */ static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write, struct mem_attrib *attrib, @@ -641,7 +589,7 @@ arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, if (should_write) { rslt = angel_RDI_write (myaddr, memaddr, &len); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt)); } @@ -649,7 +597,7 @@ arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, else { rslt = angel_RDI_read (memaddr, myaddr, &len); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt)); len = 0; @@ -668,7 +616,7 @@ arm_rdi_files_info (struct target_ops *ignore) unsigned long arg1, arg2; rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } @@ -680,14 +628,14 @@ arm_rdi_files_info (struct target_ops *ignore) printf_filtered ("Target is real hardware.\n"); rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not")); rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); } @@ -701,7 +649,7 @@ arm_rdi_kill (void) int rslt; rslt = angel_RDI_open (1, &gdb_config, NULL, NULL); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); } @@ -736,7 +684,7 @@ arm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache) if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr)) type |= RDIPoint_16Bit; rslt = angel_RDI_setbreak (addr, type, 0, &point); - if (rslt) + if (rslt != RDIError_NoError) { printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt)); } @@ -754,36 +702,27 @@ arm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache) { int rslt; PointHandle point; - struct local_bp_list_entry *entry, *preventry; + struct local_bp_list_entry **entryp, *dead; - for (entry = local_bp_list; entry != NULL; entry = entry->next) + for (entryp = &local_bp_list; *entryp != NULL; entryp = &(*entryp)->next) + if ((*entryp)->addr == addr) + break; + + if (*entryp) { - if (entry->addr == addr) - { - break; - } - preventry = entry; - } - if (entry) - { - rslt = angel_RDI_clearbreak (entry->point); - if (rslt) - { - printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt)); - } + dead = *entryp; + rslt = angel_RDI_clearbreak (dead->point); + if (rslt != RDIError_NoError) + printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt)); + /* Delete the breakpoint entry locally. */ - if (entry == local_bp_list) - { - local_bp_list = entry->next; - } - else - { - preventry->next = entry->next; - } - xfree (entry); + *entryp = dead->next; + xfree (dead); } + return 0; } + static char * rdi_error_message (int err) @@ -1024,6 +963,8 @@ rdilogenable_command (char *args, int from_tty) " try y or n\n", args); } +extern initialize_file_ftype _initialize_remote_rdi; /* -Wmissing-prototypes */ + void _initialize_remote_rdi (void) { @@ -1038,48 +979,48 @@ _initialize_remote_rdi (void) c = add_cmd ("rdilogfile", class_maintenance, rdilogfile_command, - "Set filename for ADP packet log.\n\ -This file is used to log Angel Debugger Protocol packets.\n\ -With a single argument, sets the logfile name to that value.\n\ -Without an argument, shows the current logfile name.\n\ -See also: rdilogenable\n", - &maintenancelist); - c->completer = filename_completer; + "Set filename for ADP packet log.\n" + "This file is used to log Angel Debugger Protocol packets.\n" + "With a single argument, sets the logfile name to that value.\n" + "Without an argument, shows the current logfile name.\n" + "See also: rdilogenable\n", + &maintenancelist); + set_cmd_completer (c, filename_completer); add_cmd ("rdilogenable", class_maintenance, rdilogenable_command, - "Set enable logging of ADP packets.\n\ -This will log ADP packets exchanged between gdb and the\n\ -rdi target device.\n\ -An argument of 1,t,true,y,yes will enable.\n\ -An argument of 0,f,false,n,no will disabled.\n\ -Withough an argument, it will display current state.\n", + "Set enable logging of ADP packets.\n" + "This will log ADP packets exchanged between gdb and the\n" + "rdi target device.\n" + "An argument of 1, t, true, y or yes will enable.\n" + "An argument of 0, f, false, n or no will disabled.\n" + "Withough an argument, it will display current state.\n", &maintenancelist); - add_show_from_set - (add_set_cmd ("rdiromatzero", no_class, - var_boolean, (char *) &rom_at_zero, - "Set target has ROM at addr 0.\n\ -A true value disables vector catching, false enables vector catching.\n\ -This is evaluated at the time the 'target rdi' command is executed\n", - &setlist), - &showlist); + add_setshow_boolean_cmd + ("rdiromatzero", no_class, &rom_at_zero, + "Set target has ROM at addr 0.\n" + "A true value disables vector catching, false enables vector catching.\n" + "This is evaluated at the time the 'target rdi' command is executed\n", + "Show if target has ROM at addr 0.\n", + NULL, NULL, + &setlist, &showlist); - add_show_from_set - (add_set_cmd ("rdiheartbeat", no_class, - var_boolean, (char *) &rdi_heartbeat, - "Set enable for ADP heartbeat packets.\n\ -I don't know why you would want this. If you enable them,\n\ -it will confuse ARM and EPI JTAG interface boxes as well\n\ -as the Angel Monitor.\n", - &setlist), - &showlist); + add_setshow_boolean_cmd + ("rdiheartbeat", no_class, &rdi_heartbeat, + "Set enable for ADP heartbeat packets.\n" + "I don't know why you would want this. If you enable them,\n" + "it will confuse ARM and EPI JTAG interface boxes as well\n" + "as the Angel Monitor.\n", + "Show enable for ADP heartbeat packets.\n", + NULL, NULL, + &setlist, &showlist); } /* A little dummy to make linking with the library succeed. */ -int -Fail (void) +void +Fail (const char *ignored, ...) { - return 0; + } diff --git a/contrib/gdb/gdb/remote-rdp.c b/contrib/gdb/gdb/remote-rdp.c new file mode 100644 index 00000000000..eab68eaf9e4 --- /dev/null +++ b/contrib/gdb/gdb/remote-rdp.c @@ -0,0 +1,1431 @@ +/* Remote debugging for the ARM RDP interface. + + Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003 Free + Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + + */ + + +/* + Much of this file (in particular the SWI stuff) is based on code by + David Taylor (djt1000@uk.ac.cam.hermes). + + I hacked on and simplified it by removing a lot of sexy features he + had added, and some of the (unix specific) workarounds he'd done + for other GDB problems - which if they still exist should be fixed + in GDB, not in a remote-foo thing . I also made it conform more to + the doc I have; which may be wrong. + + Steve Chamberlain (sac@cygnus.com). + */ + + +#include "defs.h" +#include "inferior.h" +#include "value.h" +#include "gdb/callback.h" +#include "command.h" +#include +#include +#include "symfile.h" +#include "remote-utils.h" +#include "gdb_string.h" +#include "gdbcore.h" +#include "regcache.h" +#include "serial.h" + +#include "arm-tdep.h" + +#ifdef HAVE_TIME_H +#include +#endif + +extern struct target_ops remote_rdp_ops; +static struct serial *io; +static host_callback *callback = &default_callback; + +struct + { + int step_info; + int break_info; + int model_info; + int target_info; + int can_step; + char command_line[10]; + int rdi_level; + int rdi_stopped_status; + } +ds; + + + +/* Definitions for the RDP protocol. */ + +#define RDP_MOUTHFULL (1<<6) +#define FPU_COPRO_NUMBER 1 + +#define RDP_OPEN 0 +#define RDP_OPEN_TYPE_COLD 0 +#define RDP_OPEN_TYPE_WARM 1 +#define RDP_OPEN_TYPE_BAUDRATE 2 + +#define RDP_OPEN_BAUDRATE_9600 1 +#define RDP_OPEN_BAUDRATE_19200 2 +#define RDP_OPEN_BAUDRATE_38400 3 + +#define RDP_OPEN_TYPE_RETURN_SEX (1<<3) + +#define RDP_CLOSE 1 + +#define RDP_MEM_READ 2 + +#define RDP_MEM_WRITE 3 + +#define RDP_CPU_READ 4 +#define RDP_CPU_WRITE 5 +#define RDP_CPU_READWRITE_MODE_CURRENT 255 +#define RDP_CPU_READWRITE_MASK_PC (1<<16) +#define RDP_CPU_READWRITE_MASK_CPSR (1<<17) +#define RDP_CPU_READWRITE_MASK_SPSR (1<<18) + +#define RDP_COPRO_READ 6 +#define RDP_COPRO_WRITE 7 +#define RDP_FPU_READWRITE_MASK_FPS (1<<8) + +#define RDP_SET_BREAK 0xa +#define RDP_SET_BREAK_TYPE_PC_EQUAL 0 +#define RDP_SET_BREAK_TYPE_GET_HANDLE (0x10) + +#define RDP_CLEAR_BREAK 0xb + +#define RDP_EXEC 0x10 +#define RDP_EXEC_TYPE_SYNC 0 + +#define RDP_STEP 0x11 + +#define RDP_INFO 0x12 +#define RDP_INFO_ABOUT_STEP 2 +#define RDP_INFO_ABOUT_STEP_GT_1 1 +#define RDP_INFO_ABOUT_STEP_TO_JMP 2 +#define RDP_INFO_ABOUT_STEP_1 4 +#define RDP_INFO_ABOUT_TARGET 0 +#define RDP_INFO_ABOUT_BREAK 1 +#define RDP_INFO_ABOUT_BREAK_COMP 1 +#define RDP_INFO_ABOUT_BREAK_RANGE 2 +#define RDP_INFO_ABOUT_BREAK_BYTE_READ 4 +#define RDP_INFO_ABOUT_BREAK_HALFWORD_READ 8 +#define RDP_INFO_ABOUT_BREAK_WORD_READ (1<<4) +#define RDP_INFO_ABOUT_BREAK_BYTE_WRITE (1<<5) +#define RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE (1<<6) +#define RDP_INFO_ABOUT_BREAK_WORD_WRITE (1<<7) +#define RDP_INFO_ABOUT_BREAK_MASK (1<<8) +#define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9) +#define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10) +#define RDP_INFO_ABOUT_BREAK_COND (1<<11) +#define RDP_INFO_VECTOR_CATCH (0x180) +#define RDP_INFO_ICEBREAKER (7) +#define RDP_INFO_SET_CMDLINE (0x300) + +#define RDP_SELECT_CONFIG (0x16) +#define RDI_ConfigCPU 0 +#define RDI_ConfigSystem 1 +#define RDI_MatchAny 0 +#define RDI_MatchExactly 1 +#define RDI_MatchNoEarlier 2 + +#define RDP_RESET 0x7f + +/* Returns from RDP */ +#define RDP_RES_STOPPED 0x20 +#define RDP_RES_SWI 0x21 +#define RDP_RES_FATAL 0x5e +#define RDP_RES_VALUE 0x5f +#define RDP_RES_VALUE_LITTLE_ENDIAN 240 +#define RDP_RES_VALUE_BIG_ENDIAN 241 +#define RDP_RES_RESET 0x7f +#define RDP_RES_AT_BREAKPOINT 143 +#define RDP_RES_IDUNNO 0xe6 +#define RDP_OSOpReply 0x13 +#define RDP_OSOpWord 2 +#define RDP_OSOpNothing 0 + +static int timeout = 2; + +static char *commandline = NULL; + +static int +remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, + struct mem_attrib *attrib, + struct target_ops *target); + + +/* Stuff for talking to the serial layer. */ + +static unsigned char +get_byte (void) +{ + int c = serial_readchar (io, timeout); + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c); + + if (c == SERIAL_TIMEOUT) + { + if (timeout == 0) + return (unsigned char) c; + + error ("Timeout reading from remote_system"); + } + + return c; +} + +/* Note that the target always speaks little-endian to us, + even if it's a big endian machine. */ +static unsigned int +get_word (void) +{ + unsigned int val = 0; + unsigned int c; + int n; + for (n = 0; n < 4; n++) + { + c = get_byte (); + val |= c << (n * 8); + } + return val; +} + +static void +put_byte (char val) +{ + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "(%02x)\n", val); + serial_write (io, &val, 1); +} + +static void +put_word (int val) +{ + /* We always send in little endian */ + unsigned char b[4]; + b[0] = val; + b[1] = val >> 8; + b[2] = val >> 16; + b[3] = val >> 24; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "(%04x)", val); + + serial_write (io, b, 4); +} + + + +/* Stuff for talking to the RDP layer. */ + +/* This is a bit more fancy that need be so that it syncs even in nasty cases. + + I'be been unable to make it reliably sync up with the change + baudrate open command. It likes to sit and say it's been reset, + with no more action. So I took all that code out. I'd rather sync + reliably at 9600 than wait forever for a possible 19200 connection. + + */ +static void +rdp_init (int cold, int tty) +{ + int sync = 0; + int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM; + int baudtry = 9600; + + time_t now = time (0); + time_t stop_time = now + 10; /* Try and sync for 10 seconds, then give up */ + + + while (time (0) < stop_time && !sync) + { + int restype; + QUIT; + + serial_flush_input (io); + serial_flush_output (io); + + if (tty) + printf_unfiltered ("Trying to connect at %d baud.\n", baudtry); + + /* + ** It seems necessary to reset an EmbeddedICE to get it going. + ** This has the side benefit of displaying the startup banner. + */ + if (cold) + { + put_byte (RDP_RESET); + while ((restype = serial_readchar (io, 1)) > 0) + { + switch (restype) + { + case SERIAL_TIMEOUT: + break; + case RDP_RESET: + /* Sent at start of reset process: ignore */ + break; + default: + printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); + break; + } + } + + if (restype == 0) + { + /* Got end-of-banner mark */ + printf_filtered ("\n"); + } + } + + put_byte (RDP_OPEN); + + put_byte (type | RDP_OPEN_TYPE_RETURN_SEX); + put_word (0); + + while (!sync && (restype = serial_readchar (io, 1)) > 0) + { + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype); + + switch (restype) + { + case SERIAL_TIMEOUT: + break; + + case RDP_RESET: + while ((restype = serial_readchar (io, 1)) == RDP_RESET) + ; + do + { + printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); + } + while ((restype = serial_readchar (io, 1)) > 0); + + if (tty) + { + printf_unfiltered ("\nThe board has sent notification that it was reset.\n"); + printf_unfiltered ("Waiting for it to settle down...\n"); + } + sleep (3); + if (tty) + printf_unfiltered ("\nTrying again.\n"); + cold = 0; + break; + + default: + break; + + case RDP_RES_VALUE: + { + int resval = serial_readchar (io, 1); + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval); + + switch (resval) + { + case SERIAL_TIMEOUT: + break; + case RDP_RES_VALUE_LITTLE_ENDIAN: +#if 0 + /* FIXME: cagney/2003-11-22: Ever since the ARM + was multi-arched (in 2002-02-08), this + assignment has had no effect. There needs to + be some sort of check/decision based on the + current architecture's byte-order vs the remote + target's byte order. For the moment disable + the assignment to keep things building. */ + target_byte_order = BFD_ENDIAN_LITTLE; +#endif + sync = 1; + break; + case RDP_RES_VALUE_BIG_ENDIAN: +#if 0 + /* FIXME: cagney/2003-11-22: Ever since the ARM + was multi-arched (in 2002-02-08), this + assignment has had no effect. There needs to + be some sort of check/decision based on the + current architecture's byte-order vs the remote + target's byte order. For the moment disable + the assignment to keep things building. */ + target_byte_order = BFD_ENDIAN_BIG; +#endif + sync = 1; + break; + default: + break; + } + } + } + } + } + + if (!sync) + { + error ("Couldn't reset the board, try pressing the reset button"); + } +} + + +static void +send_rdp (char *template,...) +{ + char buf[200]; + char *dst = buf; + va_list alist; + va_start (alist, template); + + while (*template) + { + unsigned int val; + int *pi; + int *pstat; + char *pc; + int i; + switch (*template++) + { + case 'b': + val = va_arg (alist, int); + *dst++ = val; + break; + case 'w': + val = va_arg (alist, int); + *dst++ = val; + *dst++ = val >> 8; + *dst++ = val >> 16; + *dst++ = val >> 24; + break; + case 'S': + val = get_byte (); + if (val != RDP_RES_VALUE) + { + printf_unfiltered ("got bad res value of %d, %x\n", val, val); + } + break; + case 'V': + pstat = va_arg (alist, int *); + pi = va_arg (alist, int *); + + *pstat = get_byte (); + /* Check the result was zero, if not read the syndrome */ + if (*pstat) + { + *pi = get_word (); + } + break; + case 'Z': + /* Check the result code */ + switch (get_byte ()) + { + case 0: + /* Success */ + break; + case 253: + /* Target can't do it; never mind */ + printf_unfiltered ("RDP: Insufficient privilege\n"); + return; + case 254: + /* Target can't do it; never mind */ + printf_unfiltered ("RDP: Unimplemented message\n"); + return; + case 255: + error ("Command garbled"); + break; + default: + error ("Corrupt reply from target"); + break; + } + break; + case 'W': + /* Read a word from the target */ + pi = va_arg (alist, int *); + *pi = get_word (); + break; + case 'P': + /* Read in some bytes from the target. */ + pc = va_arg (alist, char *); + val = va_arg (alist, int); + for (i = 0; i < val; i++) + { + pc[i] = get_byte (); + } + break; + case 'p': + /* send what's being pointed at */ + pc = va_arg (alist, char *); + val = va_arg (alist, int); + dst = buf; + serial_write (io, pc, val); + break; + case '-': + /* Send whats in the queue */ + if (dst != buf) + { + serial_write (io, buf, dst - buf); + dst = buf; + } + break; + case 'B': + pi = va_arg (alist, int *); + *pi = get_byte (); + break; + default: + internal_error (__FILE__, __LINE__, "failed internal consistency check"); + } + } + va_end (alist); + + if (dst != buf) + internal_error (__FILE__, __LINE__, "failed internal consistency check"); +} + + +static int +rdp_write (CORE_ADDR memaddr, char *buf, int len) +{ + int res; + int val; + + send_rdp ("bww-p-SV", RDP_MEM_WRITE, memaddr, len, buf, len, &res, &val); + + if (res) + { + return val; + } + return len; +} + + +static int +rdp_read (CORE_ADDR memaddr, char *buf, int len) +{ + int res; + int val; + send_rdp ("bww-S-P-V", + RDP_MEM_READ, memaddr, len, + buf, len, + &res, &val); + if (res) + { + return val; + } + return len; +} + +static void +rdp_fetch_one_register (int mask, char *buf) +{ + int val; + send_rdp ("bbw-SWZ", RDP_CPU_READ, RDP_CPU_READWRITE_MODE_CURRENT, mask, &val); + store_signed_integer (buf, 4, val); +} + +static void +rdp_fetch_one_fpu_register (int mask, char *buf) +{ +#if 0 + /* !!! Since the PIE board doesn't work as documented, + and it doesn't have FPU hardware anyway and since it + slows everything down, I've disabled this. */ + int val; + if (mask == RDP_FPU_READWRITE_MASK_FPS) + { + /* this guy is only a word */ + send_rdp ("bbw-SWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, &val); + store_signed_integer (buf, 4, val); + } + else + { + /* There are 12 bytes long + !! fixme about endianness + */ + int dummy; /* I've seen these come back as four words !! */ + send_rdp ("bbw-SWWWWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, buf + 0, buf + 4, buf + 8, &dummy); + } +#endif + memset (buf, 0, MAX_REGISTER_SIZE); +} + + +static void +rdp_store_one_register (int mask, char *buf) +{ + int val = extract_unsigned_integer (buf, 4); + + send_rdp ("bbww-SZ", + RDP_CPU_WRITE, RDP_CPU_READWRITE_MODE_CURRENT, mask, val); +} + + +static void +rdp_store_one_fpu_register (int mask, char *buf) +{ +#if 0 + /* See comment in fetch_one_fpu_register */ + if (mask == RDP_FPU_READWRITE_MASK_FPS) + { + int val = extract_unsigned_integer (buf, 4); + /* this guy is only a word */ + send_rdp ("bbww-SZ", RDP_COPRO_WRITE, + FPU_COPRO_NUMBER, + mask, val); + } + else + { + /* There are 12 bytes long + !! fixme about endianness + */ + int dummy = 0; + /* I've seen these come as four words, not the three advertized !! */ + printf ("Sending mask %x\n", mask); + send_rdp ("bbwwwww-SZ", + RDP_COPRO_WRITE, + FPU_COPRO_NUMBER, + mask, + *(int *) (buf + 0), + *(int *) (buf + 4), + *(int *) (buf + 8), + 0); + + printf ("done mask %x\n", mask); + } +#endif +} + + +/* Convert between GDB requests and the RDP layer. */ + +static void +remote_rdp_fetch_register (int regno) +{ + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + remote_rdp_fetch_register (regno); + } + else + { + char buf[MAX_REGISTER_SIZE]; + if (regno < 15) + rdp_fetch_one_register (1 << regno, buf); + else if (regno == ARM_PC_REGNUM) + rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_PC, buf); + else if (regno == ARM_PS_REGNUM) + rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_CPSR, buf); + else if (regno == ARM_FPS_REGNUM) + rdp_fetch_one_fpu_register (RDP_FPU_READWRITE_MASK_FPS, buf); + else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) + rdp_fetch_one_fpu_register (1 << (regno - ARM_F0_REGNUM), buf); + else + { + printf ("Help me with fetch reg %d\n", regno); + } + supply_register (regno, buf); + } +} + + +static void +remote_rdp_store_register (int regno) +{ + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + remote_rdp_store_register (regno); + } + else + { + char tmp[MAX_REGISTER_SIZE]; + deprecated_read_register_gen (regno, tmp); + if (regno < 15) + rdp_store_one_register (1 << regno, tmp); + else if (regno == ARM_PC_REGNUM) + rdp_store_one_register (RDP_CPU_READWRITE_MASK_PC, tmp); + else if (regno == ARM_PS_REGNUM) + rdp_store_one_register (RDP_CPU_READWRITE_MASK_CPSR, tmp); + else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) + rdp_store_one_fpu_register (1 << (regno - ARM_F0_REGNUM), tmp); + else + { + printf ("Help me with reg %d\n", regno); + } + } +} + +static void +remote_rdp_kill (void) +{ + callback->shutdown (callback); +} + + +static void +rdp_info (void) +{ + send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_STEP, + &ds.step_info); + send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_BREAK, + &ds.break_info); + send_rdp ("bw-S-WW-Z", RDP_INFO, RDP_INFO_ABOUT_TARGET, + &ds.target_info, + &ds.model_info); + + ds.can_step = ds.step_info & RDP_INFO_ABOUT_STEP_1; + + ds.rdi_level = (ds.target_info >> 5) & 3; +} + + +static void +rdp_execute_start (void) +{ + /* Start it off, but don't wait for it */ + send_rdp ("bb-", RDP_EXEC, RDP_EXEC_TYPE_SYNC); +} + + +static void +rdp_set_command_line (char *command, char *args) +{ + /* + ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems + ** don't implement that, and get all confused at the unexpected text. + ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv + */ + + if (commandline != NULL) + xfree (commandline); + + xasprintf (&commandline, "%s %s", command, args); +} + +static void +rdp_catch_vectors (void) +{ + /* + ** We want the target monitor to intercept the abort vectors + ** i.e. stop the program if any of these are used. + */ + send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH, + /* + ** Specify a bitmask including + ** the reset vector + ** the undefined instruction vector + ** the prefetch abort vector + ** the data abort vector + ** the address exception vector + */ + (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) + ); +} + + + +#define a_byte 1 +#define a_word 2 +#define a_string 3 + + +typedef struct +{ + CORE_ADDR n; + const char *s; +} +argsin; + +#define ABYTE 1 +#define AWORD 2 +#define ASTRING 3 +#define ADDRLEN 4 + +#define SWI_WriteC 0x0 +#define SWI_Write0 0x2 +#define SWI_ReadC 0x4 +#define SWI_CLI 0x5 +#define SWI_GetEnv 0x10 +#define SWI_Exit 0x11 +#define SWI_EnterOS 0x16 + +#define SWI_GetErrno 0x60 +#define SWI_Clock 0x61 + +#define SWI_Time 0x63 +#define SWI_Remove 0x64 +#define SWI_Rename 0x65 +#define SWI_Open 0x66 + +#define SWI_Close 0x68 +#define SWI_Write 0x69 +#define SWI_Read 0x6a +#define SWI_Seek 0x6b +#define SWI_Flen 0x6c + +#define SWI_IsTTY 0x6e +#define SWI_TmpNam 0x6f +#define SWI_InstallHandler 0x70 +#define SWI_GenerateError 0x71 + + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static int translate_open_mode[] = +{ + O_RDONLY, /* "r" */ + O_RDONLY + O_BINARY, /* "rb" */ + O_RDWR, /* "r+" */ + O_RDWR + O_BINARY, /* "r+b" */ + O_WRONLY + O_CREAT + O_TRUNC, /* "w" */ + O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */ + O_RDWR + O_CREAT + O_TRUNC, /* "w+" */ + O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */ + O_WRONLY + O_APPEND + O_CREAT, /* "a" */ + O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */ + O_RDWR + O_APPEND + O_CREAT, /* "a+" */ + O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */ +}; + +static int +exec_swi (int swi, argsin *args) +{ + int i; + char c; + switch (swi) + { + case SWI_WriteC: + callback->write_stdout (callback, &c, 1); + return 0; + case SWI_Write0: + for (i = 0; i < args->n; i++) + callback->write_stdout (callback, args->s, strlen (args->s)); + return 0; + case SWI_ReadC: + callback->read_stdin (callback, &c, 1); + args->n = c; + return 1; + case SWI_CLI: + args->n = callback->system (callback, args->s); + return 1; + case SWI_GetErrno: + args->n = callback->get_errno (callback); + return 1; + case SWI_Time: + args->n = callback->time (callback, NULL); + return 1; + + case SWI_Clock: + /* return number of centi-seconds... */ + args->n = +#ifdef CLOCKS_PER_SEC + (CLOCKS_PER_SEC >= 100) + ? (clock () / (CLOCKS_PER_SEC / 100)) + : ((clock () * 100) / CLOCKS_PER_SEC); +#else + /* presume unix... clock() returns microseconds */ + clock () / 10000; +#endif + return 1; + + case SWI_Remove: + args->n = callback->unlink (callback, args->s); + return 1; + case SWI_Rename: + args->n = callback->rename (callback, args[0].s, args[1].s); + return 1; + + case SWI_Open: + /* Now we need to decode the Demon open mode */ + i = translate_open_mode[args[1].n]; + + /* Filename ":tt" is special: it denotes stdin/out */ + if (strcmp (args->s, ":tt") == 0) + { + if (i == O_RDONLY) /* opening tty "r" */ + args->n = 0 /* stdin */ ; + else + args->n = 1 /* stdout */ ; + } + else + args->n = callback->open (callback, args->s, i); + return 1; + + case SWI_Close: + args->n = callback->close (callback, args->n); + return 1; + + case SWI_Write: + /* Return the number of bytes *not* written */ + args->n = args[1].n - + callback->write (callback, args[0].n, args[1].s, args[1].n); + return 1; + + case SWI_Read: + { + char *copy = alloca (args[2].n); + int done = callback->read (callback, args[0].n, copy, args[2].n); + if (done > 0) + remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0); + args->n = args[2].n - done; + return 1; + } + + case SWI_Seek: + /* Return non-zero on failure */ + args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0; + return 1; + + case SWI_Flen: + { + long old = callback->lseek (callback, args->n, 0, SEEK_CUR); + args->n = callback->lseek (callback, args->n, 0, SEEK_END); + callback->lseek (callback, args->n, old, 0); + return 1; + } + + case SWI_IsTTY: + args->n = callback->isatty (callback, args->n); + return 1; + + case SWI_GetEnv: + if (commandline != NULL) + { + int len = strlen (commandline); + if (len > 255) + { + len = 255; + commandline[255] = '\0'; + } + remote_rdp_xfer_inferior_memory (args[0].n, + commandline, len + 1, 1, 0, 0); + } + else + remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0); + return 1; + + default: + return 0; + } +} + + +static void +handle_swi (void) +{ + argsin args[3]; + char *buf; + int len; + int count = 0; + + int swino = get_word (); + int type = get_byte (); + while (type != 0) + { + switch (type & 0x3) + { + case ABYTE: + args[count].n = get_byte (); + break; + + case AWORD: + args[count].n = get_word (); + break; + + case ASTRING: + /* If the word is under 32 bytes it will be sent otherwise + an address to it is passed. Also: Special case of 255 */ + + len = get_byte (); + if (len > 32) + { + if (len == 255) + { + len = get_word (); + } + buf = alloca (len); + remote_rdp_xfer_inferior_memory (get_word (), + buf, + len, + 0, + 0, + 0); + } + else + { + int i; + buf = alloca (len + 1); + for (i = 0; i < len; i++) + buf[i] = get_byte (); + buf[i] = 0; + } + args[count].n = len; + args[count].s = buf; + break; + + default: + error ("Unimplemented SWI argument"); + } + + type = type >> 2; + count++; + } + + if (exec_swi (swino, args)) + { + /* We have two options here reply with either a byte or a word + which is stored in args[0].n. There is no harm in replying with + a word all the time, so thats what I do! */ + send_rdp ("bbw-", RDP_OSOpReply, RDP_OSOpWord, args[0].n); + } + else + { + send_rdp ("bb-", RDP_OSOpReply, RDP_OSOpNothing); + } +} + +static void +rdp_execute_finish (void) +{ + int running = 1; + + while (running) + { + int res; + res = serial_readchar (io, 1); + while (res == SERIAL_TIMEOUT) + { + QUIT; + printf_filtered ("Waiting for target..\n"); + res = serial_readchar (io, 1); + } + + switch (res) + { + case RDP_RES_SWI: + handle_swi (); + break; + case RDP_RES_VALUE: + send_rdp ("B", &ds.rdi_stopped_status); + running = 0; + break; + case RDP_RESET: + printf_filtered ("Target reset\n"); + running = 0; + break; + default: + printf_filtered ("Ignoring %x\n", res); + break; + } + } +} + + +static void +rdp_execute (void) +{ + rdp_execute_start (); + rdp_execute_finish (); +} + +static int +remote_rdp_insert_breakpoint (CORE_ADDR addr, char *save) +{ + int res; + if (ds.rdi_level > 0) + { + send_rdp ("bwb-SWB", + RDP_SET_BREAK, + addr, + RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE, + save, + &res); + } + else + { + send_rdp ("bwb-SB", + RDP_SET_BREAK, + addr, + RDP_SET_BREAK_TYPE_PC_EQUAL, + &res); + } + return res; +} + +static int +remote_rdp_remove_breakpoint (CORE_ADDR addr, char *save) +{ + int res; + if (ds.rdi_level > 0) + { + send_rdp ("b-p-S-B", + RDP_CLEAR_BREAK, + save, 4, + &res); + } + else + { + send_rdp ("bw-S-B", + RDP_CLEAR_BREAK, + addr, + &res); + } + return res; +} + +static void +rdp_step (void) +{ + if (ds.can_step && 0) + { + /* The pie board can't do steps so I can't test this, and + the other code will always work. */ + int status; + send_rdp ("bbw-S-B", + RDP_STEP, 0, 1, + &status); + } + else + { + char handle[4]; + CORE_ADDR pc = read_register (ARM_PC_REGNUM); + pc = arm_get_next_pc (pc); + remote_rdp_insert_breakpoint (pc, handle); + rdp_execute (); + remote_rdp_remove_breakpoint (pc, handle); + } +} + +static void +remote_rdp_open (char *args, int from_tty) +{ + int not_icebreaker; + + if (!args) + error_no_arg ("serial port device name"); + + baud_rate = 9600; + + target_preopen (from_tty); + + io = serial_open (args); + + if (!io) + perror_with_name (args); + + serial_raw (io); + + rdp_init (1, from_tty); + + + if (from_tty) + { + printf_unfiltered ("Remote RDP debugging using %s at %d baud\n", args, baud_rate); + } + + rdp_info (); + + /* Need to set up the vector interception state */ + rdp_catch_vectors (); + + /* + ** If it's an EmbeddedICE, we need to set the processor config. + ** Assume we can always have ARM7TDI... + */ + send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, ¬_icebreaker); + if (!not_icebreaker) + { + const char *CPU = "ARM7TDI"; + int ICEversion; + int len = strlen (CPU); + + send_rdp ("bbbbw-p-SWZ", + RDP_SELECT_CONFIG, + RDI_ConfigCPU, /* Aspect: set the CPU */ + len, /* The number of bytes in the name */ + RDI_MatchAny, /* We'll take whatever we get */ + 0, /* We'll take whatever version's there */ + CPU, len, + &ICEversion); + } + + /* command line initialised on 'run' */ + + push_target (&remote_rdp_ops); + + callback->init (callback); + flush_cached_frames (); + registers_changed (); + stop_pc = read_pc (); + print_stack_frame (get_selected_frame (), -1, 1); +} + + + +/* Close out all files and local state before this target loses control. */ + +static void +remote_rdp_close (int quitting) +{ + callback->shutdown (callback); + if (io) + serial_close (io); + io = 0; +} + + +/* Resume execution of the target process. STEP says whether to single-step + or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given + to the target, or zero for no signal. */ + +static void +remote_rdp_resume (ptid_t ptid, int step, enum target_signal siggnal) +{ + if (step) + rdp_step (); + else + rdp_execute (); +} + +/* Wait for inferior process to do something. Return pid of child, + or -1 in case of error; store status through argument pointer STATUS, + just as `wait' would. */ + +static ptid_t +remote_rdp_wait (ptid_t ptid, struct target_waitstatus *status) +{ + switch (ds.rdi_stopped_status) + { + default: + case RDP_RES_RESET: + case RDP_RES_SWI: + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = read_register (0); + break; + case RDP_RES_AT_BREAKPOINT: + status->kind = TARGET_WAITKIND_STOPPED; + /* The signal in sigrc is a host signal. That probably + should be fixed. */ + status->value.sig = TARGET_SIGNAL_TRAP; + break; +#if 0 + case rdp_signalled: + status->kind = TARGET_WAITKIND_SIGNALLED; + /* The signal in sigrc is a host signal. That probably + should be fixed. */ + status->value.sig = target_signal_from_host (sigrc); + break; +#endif + } + + return inferior_ptid; +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +remote_rdp_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ +} + +/* Transfer LEN bytes between GDB address MYADDR and target address + MEMADDR. If WRITE is non-zero, transfer them to the target, + otherwise transfer them from the target. TARGET is unused. + + Returns the number of bytes transferred. */ + +static int +remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, struct mem_attrib *attrib, + struct target_ops *target) +{ + /* I infer from D Taylor's code that there's a limit on the amount + we can transfer in one chunk.. */ + int done = 0; + while (done < len) + { + int justdone; + int thisbite = len - done; + if (thisbite > RDP_MOUTHFULL) + thisbite = RDP_MOUTHFULL; + + QUIT; + + if (write) + { + justdone = rdp_write (memaddr + done, myaddr + done, thisbite); + } + else + { + justdone = rdp_read (memaddr + done, myaddr + done, thisbite); + } + + done += justdone; + + if (justdone != thisbite) + break; + } + return done; +} + + + +struct yn +{ + const char *name; + int bit; +}; +static struct yn stepinfo[] = +{ + {"Step more than one instruction", RDP_INFO_ABOUT_STEP_GT_1}, + {"Step to jump", RDP_INFO_ABOUT_STEP_TO_JMP}, + {"Step one instruction", RDP_INFO_ABOUT_STEP_1}, + {0} +}; + +static struct yn breakinfo[] = +{ + {"comparison breakpoints supported", RDP_INFO_ABOUT_BREAK_COMP}, + {"range breakpoints supported", RDP_INFO_ABOUT_BREAK_RANGE}, + {"watchpoints for byte reads supported", RDP_INFO_ABOUT_BREAK_BYTE_READ}, + {"watchpoints for half-word reads supported", RDP_INFO_ABOUT_BREAK_HALFWORD_READ}, + {"watchpoints for word reads supported", RDP_INFO_ABOUT_BREAK_WORD_READ}, + {"watchpoints for byte writes supported", RDP_INFO_ABOUT_BREAK_BYTE_WRITE}, + {"watchpoints for half-word writes supported", RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE}, + {"watchpoints for word writes supported", RDP_INFO_ABOUT_BREAK_WORD_WRITE}, + {"mask break/watch-points supported", RDP_INFO_ABOUT_BREAK_MASK}, +{"thread-specific breakpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_BREAK}, +{"thread-specific watchpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_WATCH}, + {"conditional breakpoints supported", RDP_INFO_ABOUT_BREAK_COND}, + {0} +}; + + +static void +dump_bits (struct yn *t, int info) +{ + while (t->name) + { + printf_unfiltered (" %-45s : %s\n", t->name, (info & t->bit) ? "Yes" : "No"); + t++; + } +} + +static void +remote_rdp_files_info (struct target_ops *target) +{ + printf_filtered ("Target capabilities:\n"); + dump_bits (stepinfo, ds.step_info); + dump_bits (breakinfo, ds.break_info); + printf_unfiltered ("target level RDI %x\n", (ds.target_info >> 5) & 3); +} + + +static void +remote_rdp_create_inferior (char *exec_file, char *allargs, char **env) +{ + CORE_ADDR entry_point; + + if (exec_file == 0 || exec_bfd == 0) + error ("No executable file specified."); + + entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd); + + remote_rdp_kill (); + remove_breakpoints (); + init_wait_for_inferior (); + + /* This gives us a chance to set up the command line */ + rdp_set_command_line (exec_file, allargs); + + inferior_ptid = pid_to_ptid (42); + insert_breakpoints (); /* Needed to get correct instruction in cache */ + + /* + ** RDP targets don't provide any facility to set the top of memory, + ** so we don't bother to look for MEMSIZE in the environment. + */ + + /* Let's go! */ + proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0); +} + +/* Attach doesn't need to do anything */ +static void +remote_rdp_attach (char *args, int from_tty) +{ + return; +} + +/* Define the target subroutine names */ + +struct target_ops remote_rdp_ops; + +static void +init_remote_rdp_ops (void) +{ + remote_rdp_ops.to_shortname = "rdp"; + remote_rdp_ops.to_longname = "Remote Target using the RDProtocol"; + remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol"; + remote_rdp_ops.to_open = remote_rdp_open; + remote_rdp_ops.to_close = remote_rdp_close; + remote_rdp_ops.to_attach = remote_rdp_attach; + remote_rdp_ops.to_resume = remote_rdp_resume; + remote_rdp_ops.to_wait = remote_rdp_wait; + remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register; + remote_rdp_ops.to_store_registers = remote_rdp_store_register; + remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store; + remote_rdp_ops.to_xfer_memory = remote_rdp_xfer_inferior_memory; + remote_rdp_ops.to_files_info = remote_rdp_files_info; + remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint; + remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint; + remote_rdp_ops.to_kill = remote_rdp_kill; + remote_rdp_ops.to_load = generic_load; + remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior; + remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior; + remote_rdp_ops.to_stratum = process_stratum; + remote_rdp_ops.to_has_all_memory = 1; + remote_rdp_ops.to_has_memory = 1; + remote_rdp_ops.to_has_stack = 1; + remote_rdp_ops.to_has_registers = 1; + remote_rdp_ops.to_has_execution = 1; + remote_rdp_ops.to_magic = OPS_MAGIC; +} + +extern initialize_file_ftype _initialize_remote_rdp; /* -Wmissing-prototypes */ + +void +_initialize_remote_rdp (void) +{ + init_remote_rdp_ops (); + add_target (&remote_rdp_ops); +} diff --git a/contrib/gdb/gdb/remote-sds.c b/contrib/gdb/gdb/remote-sds.c new file mode 100644 index 00000000000..d74fd7db242 --- /dev/null +++ b/contrib/gdb/gdb/remote-sds.c @@ -0,0 +1,1130 @@ +/* Remote target communications for serial-line targets using SDS' protocol. + + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This interface was written by studying the behavior of the SDS + monitor on an ADS 821/860 board, and by consulting the + documentation of the monitor that is available on Motorola's web + site. -sts 8/13/97 */ + +#include "defs.h" +#include "gdb_string.h" +#include +#include "frame.h" +#include "inferior.h" +#include "bfd.h" +#include "symfile.h" +#include "target.h" +#include "gdbcmd.h" +#include "objfiles.h" +#include "gdb-stabs.h" +#include "gdbthread.h" +#include "gdbcore.h" +#include "regcache.h" + +#ifdef USG +#include +#endif + +#include +#include "serial.h" + +extern void _initialize_remote_sds (void); + +/* Declarations of local functions. */ + +static int sds_write_bytes (CORE_ADDR, char *, int); + +static int sds_read_bytes (CORE_ADDR, char *, int); + +static void sds_files_info (struct target_ops *ignore); + +static int sds_xfer_memory (CORE_ADDR, char *, int, int, + struct mem_attrib *, struct target_ops *); + +static void sds_prepare_to_store (void); + +static void sds_fetch_registers (int); + +static void sds_resume (ptid_t, int, enum target_signal); + +static int sds_start_remote (void *); + +static void sds_open (char *, int); + +static void sds_close (int); + +static void sds_store_registers (int); + +static void sds_mourn (void); + +static void sds_create_inferior (char *, char *, char **); + +static void sds_load (char *, int); + +static int getmessage (unsigned char *, int); + +static int putmessage (unsigned char *, int); + +static int sds_send (unsigned char *, int); + +static int readchar (int); + +static ptid_t sds_wait (ptid_t, struct target_waitstatus *); + +static void sds_kill (void); + +static int fromhex (int); + +static void sds_detach (char *, int); + +static void sds_interrupt (int); + +static void sds_interrupt_twice (int); + +static void interrupt_query (void); + +static int read_frame (char *); + +static int sds_insert_breakpoint (CORE_ADDR, char *); + +static int sds_remove_breakpoint (CORE_ADDR, char *); + +static void init_sds_ops (void); + +static void sds_command (char *args, int from_tty); + +/* Define the target operations vector. */ + +static struct target_ops sds_ops; + +/* This was 5 seconds, which is a long time to sit and wait. + Unless this is going though some terminal server or multiplexer or + other form of hairy serial connection, I would think 2 seconds would + be plenty. */ + +static int sds_timeout = 2; + +/* Descriptor for I/O to remote machine. Initialize it to NULL so + that sds_open knows that we don't have a file open when the program + starts. */ + +static struct serial *sds_desc = NULL; + +/* This limit comes from the monitor. */ + +#define PBUFSIZ 250 + +/* Maximum number of bytes to read/write at once. The value here + is chosen to fill up a packet (the headers account for the 32). */ +#define MAXBUFBYTES ((PBUFSIZ-32)/2) + +static int next_msg_id; + +static int just_started; + +static int message_pending; + + +/* Clean up connection to a remote debugger. */ + +static void +sds_close (int quitting) +{ + if (sds_desc) + serial_close (sds_desc); + sds_desc = NULL; +} + +/* Stub for catch_errors. */ + +static int +sds_start_remote (void *dummy) +{ + int c; + unsigned char buf[200]; + + immediate_quit++; /* Allow user to interrupt it */ + + /* Ack any packet which the remote side has already sent. */ + serial_write (sds_desc, "{#*\r\n", 5); + serial_write (sds_desc, "{#}\r\n", 5); + + while ((c = readchar (1)) >= 0) + printf_unfiltered ("%c", c); + printf_unfiltered ("\n"); + + next_msg_id = 251; + + buf[0] = 26; + sds_send (buf, 1); + + buf[0] = 0; + sds_send (buf, 1); + + immediate_quit--; + + start_remote (); /* Initialize gdb process mechanisms */ + return 1; +} + +/* Open a connection to a remote debugger. + NAME is the filename used for communication. */ + +static void +sds_open (char *name, int from_tty) +{ + if (name == 0) + error ("To open a remote debug connection, you need to specify what serial\n\ +device is attached to the remote system (e.g. /dev/ttya)."); + + target_preopen (from_tty); + + unpush_target (&sds_ops); + + sds_desc = serial_open (name); + if (!sds_desc) + perror_with_name (name); + + if (baud_rate != -1) + { + if (serial_setbaudrate (sds_desc, baud_rate)) + { + serial_close (sds_desc); + perror_with_name (name); + } + } + + + serial_raw (sds_desc); + + /* If there is something sitting in the buffer we might take it as a + response to a command, which would be bad. */ + serial_flush_input (sds_desc); + + if (from_tty) + { + puts_filtered ("Remote debugging using "); + puts_filtered (name); + puts_filtered ("\n"); + } + push_target (&sds_ops); /* Switch to using remote target now */ + + just_started = 1; + + /* Start the remote connection; if error (0), discard this target. + In particular, if the user quits, be sure to discard it (we'd be + in an inconsistent state otherwise). */ + if (!catch_errors (sds_start_remote, NULL, + "Couldn't establish connection to remote target\n", + RETURN_MASK_ALL)) + pop_target (); +} + +/* This takes a program previously attached to and detaches it. After + this is done, GDB can be used to debug some other program. We + better not have left any breakpoints in the target program or it'll + die when it hits one. */ + +static void +sds_detach (char *args, int from_tty) +{ + char buf[PBUFSIZ]; + + if (args) + error ("Argument given to \"detach\" when remotely debugging."); + +#if 0 + /* Tell the remote target to detach. */ + strcpy (buf, "D"); + sds_send (buf, 1); +#endif + + pop_target (); + if (from_tty) + puts_filtered ("Ending remote debugging.\n"); +} + +/* Convert hex digit A to a number. */ + +static int +fromhex (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else + error ("Reply contains invalid hex digit %d", a); +} + +static int +tob64 (unsigned char *inbuf, char *outbuf, int len) +{ + int i, sum; + char *p; + + if (len % 3 != 0) + error ("bad length"); + + p = outbuf; + for (i = 0; i < len; i += 3) + { + /* Collect the next three bytes into a number. */ + sum = ((long) *inbuf++) << 16; + sum |= ((long) *inbuf++) << 8; + sum |= ((long) *inbuf++); + + /* Spit out 4 6-bit encodings. */ + *p++ = ((sum >> 18) & 0x3f) + '0'; + *p++ = ((sum >> 12) & 0x3f) + '0'; + *p++ = ((sum >> 6) & 0x3f) + '0'; + *p++ = (sum & 0x3f) + '0'; + } + return (p - outbuf); +} + +static int +fromb64 (char *inbuf, char *outbuf, int len) +{ + int i, sum; + + if (len % 4 != 0) + error ("bad length"); + + for (i = 0; i < len; i += 4) + { + /* Collect 4 6-bit digits. */ + sum = (*inbuf++ - '0') << 18; + sum |= (*inbuf++ - '0') << 12; + sum |= (*inbuf++ - '0') << 6; + sum |= (*inbuf++ - '0'); + + /* Now take the resulting 24-bit number and get three bytes out + of it. */ + *outbuf++ = (sum >> 16) & 0xff; + *outbuf++ = (sum >> 8) & 0xff; + *outbuf++ = sum & 0xff; + } + + return (len / 4) * 3; +} + + +/* Tell the remote machine to resume. */ + +static enum target_signal last_sent_signal = TARGET_SIGNAL_0; +int last_sent_step; + +static void +sds_resume (ptid_t ptid, int step, enum target_signal siggnal) +{ + unsigned char buf[PBUFSIZ]; + + last_sent_signal = siggnal; + last_sent_step = step; + + buf[0] = (step ? 21 : 20); + buf[1] = 0; /* (should be signal?) */ + + sds_send (buf, 2); +} + +/* Send a message to target to halt it. Target will respond, and send + us a message pending notice. */ + +static void +sds_interrupt (int signo) +{ + unsigned char buf[PBUFSIZ]; + + /* If this doesn't work, try more severe steps. */ + signal (signo, sds_interrupt_twice); + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "sds_interrupt called\n"); + + buf[0] = 25; + sds_send (buf, 1); +} + +static void (*ofunc) (); + +/* The user typed ^C twice. */ + +static void +sds_interrupt_twice (int signo) +{ + signal (signo, ofunc); + + interrupt_query (); + + signal (signo, sds_interrupt); +} + +/* Ask the user what to do when an interrupt is received. */ + +static void +interrupt_query (void) +{ + target_terminal_ours (); + + if (query ("Interrupted while waiting for the program.\n\ +Give up (and stop debugging it)? ")) + { + target_mourn_inferior (); + throw_exception (RETURN_QUIT); + } + + target_terminal_inferior (); +} + +/* If nonzero, ignore the next kill. */ +int kill_kludge; + +/* Wait until the remote machine stops, then return, storing status in + STATUS just as `wait' would. Returns "pid" (though it's not clear + what, if anything, that means in the case of this target). */ + +static ptid_t +sds_wait (ptid_t ptid, struct target_waitstatus *status) +{ + unsigned char buf[PBUFSIZ]; + int retlen; + + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = 0; + + ofunc = (void (*)()) signal (SIGINT, sds_interrupt); + + signal (SIGINT, ofunc); + + if (just_started) + { + just_started = 0; + status->kind = TARGET_WAITKIND_STOPPED; + return inferior_ptid; + } + + while (1) + { + getmessage (buf, 1); + + if (message_pending) + { + buf[0] = 26; + retlen = sds_send (buf, 1); + if (remote_debug) + { + fprintf_unfiltered (gdb_stdlog, "Signals: %02x%02x %02x %02x\n", + buf[0], buf[1], + buf[2], buf[3]); + } + message_pending = 0; + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = TARGET_SIGNAL_TRAP; + goto got_status; + } + } +got_status: + return inferior_ptid; +} + +static unsigned char sprs[16]; + +/* Read the remote registers into the block REGS. */ +/* Currently we just read all the registers, so we don't use regno. */ + +static void +sds_fetch_registers (int regno) +{ + unsigned char buf[PBUFSIZ]; + int i, retlen; + char *regs = alloca (DEPRECATED_REGISTER_BYTES); + + /* Unimplemented registers read as all bits zero. */ + memset (regs, 0, DEPRECATED_REGISTER_BYTES); + + buf[0] = 18; + buf[1] = 1; + buf[2] = 0; + retlen = sds_send (buf, 3); + + for (i = 0; i < 4 * 6; ++i) + regs[i + 4 * 32 + 8 * 32] = buf[i]; + for (i = 0; i < 4 * 4; ++i) + sprs[i] = buf[i + 4 * 7]; + + buf[0] = 18; + buf[1] = 2; + buf[2] = 0; + retlen = sds_send (buf, 3); + + for (i = 0; i < retlen; i++) + regs[i] = buf[i]; + + /* (should warn about reply too short) */ + + for (i = 0; i < NUM_REGS; i++) + supply_register (i, ®s[DEPRECATED_REGISTER_BYTE (i)]); +} + +/* Prepare to store registers. Since we may send them all, we have to + read out the ones we don't want to change first. */ + +static void +sds_prepare_to_store (void) +{ + /* Make sure the entire registers array is valid. */ + deprecated_read_register_bytes (0, (char *) NULL, DEPRECATED_REGISTER_BYTES); +} + +/* Store register REGNO, or all registers if REGNO == -1, from the contents + of REGISTERS. FIXME: ignores errors. */ + +static void +sds_store_registers (int regno) +{ + unsigned char *p, buf[PBUFSIZ]; + int i; + + /* Store all the special-purpose registers. */ + p = buf; + *p++ = 19; + *p++ = 1; + *p++ = 0; + *p++ = 0; + for (i = 0; i < 4 * 6; i++) + *p++ = deprecated_registers[i + 4 * 32 + 8 * 32]; + for (i = 0; i < 4 * 1; i++) + *p++ = 0; + for (i = 0; i < 4 * 4; i++) + *p++ = sprs[i]; + + sds_send (buf, p - buf); + + /* Store all the general-purpose registers. */ + p = buf; + *p++ = 19; + *p++ = 2; + *p++ = 0; + *p++ = 0; + for (i = 0; i < 4 * 32; i++) + *p++ = deprecated_registers[i]; + + sds_send (buf, p - buf); + +} + +/* Write memory data directly to the remote machine. This does not + inform the data cache; the data cache uses this. MEMADDR is the + address in the remote memory space. MYADDR is the address of the + buffer in our space. LEN is the number of bytes. + + Returns number of bytes transferred, or 0 for error. */ + +static int +sds_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) +{ + int max_buf_size; /* Max size of packet output buffer */ + int origlen; + unsigned char buf[PBUFSIZ]; + int todo; + int i; + + /* Chop the transfer down if necessary */ + + max_buf_size = 150; + + origlen = len; + while (len > 0) + { + todo = min (len, max_buf_size); + + buf[0] = 13; + buf[1] = 0; + buf[2] = (int) (memaddr >> 24) & 0xff; + buf[3] = (int) (memaddr >> 16) & 0xff; + buf[4] = (int) (memaddr >> 8) & 0xff; + buf[5] = (int) (memaddr) & 0xff; + buf[6] = 1; + buf[7] = 0; + + for (i = 0; i < todo; i++) + buf[i + 8] = myaddr[i]; + + sds_send (buf, 8 + todo); + + /* (should look at result) */ + + myaddr += todo; + memaddr += todo; + len -= todo; + } + return origlen; +} + +/* Read memory data directly from the remote machine. This does not + use the data cache; the data cache uses this. MEMADDR is the + address in the remote memory space. MYADDR is the address of the + buffer in our space. LEN is the number of bytes. + + Returns number of bytes transferred, or 0 for error. */ + +static int +sds_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) +{ + int max_buf_size; /* Max size of packet output buffer */ + int origlen, retlen; + unsigned char buf[PBUFSIZ]; + int todo; + int i; + + /* Chop the transfer down if necessary */ + + max_buf_size = 150; + + origlen = len; + while (len > 0) + { + todo = min (len, max_buf_size); + + buf[0] = 12; + buf[1] = 0; + buf[2] = (int) (memaddr >> 24) & 0xff; + buf[3] = (int) (memaddr >> 16) & 0xff; + buf[4] = (int) (memaddr >> 8) & 0xff; + buf[5] = (int) (memaddr) & 0xff; + buf[6] = (int) (todo >> 8) & 0xff; + buf[7] = (int) (todo) & 0xff; + buf[8] = 1; + + retlen = sds_send (buf, 9); + + if (retlen - 2 != todo) + { + return 0; + } + + /* Reply describes memory byte by byte. */ + + for (i = 0; i < todo; i++) + myaddr[i] = buf[i + 2]; + + myaddr += todo; + memaddr += todo; + len -= todo; + } + + return origlen; +} + +/* Read or write LEN bytes from inferior memory at MEMADDR, + transferring to or from debugger address MYADDR. Write to inferior + if SHOULD_WRITE is nonzero. Returns length of data written or + read; 0 for error. TARGET is unused. */ + +static int +sds_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write, + struct mem_attrib *attrib, struct target_ops *target) +{ + int res; + + if (should_write) + res = sds_write_bytes (memaddr, myaddr, len); + else + res = sds_read_bytes (memaddr, myaddr, len); + + return res; +} + + +static void +sds_files_info (struct target_ops *ignore) +{ + puts_filtered ("Debugging over a serial connection, using SDS protocol.\n"); +} + +/* Stuff for dealing with the packets which are part of this protocol. + See comment at top of file for details. */ + +/* Read a single character from the remote end, masking it down to 7 bits. */ + +static int +readchar (int timeout) +{ + int ch; + + ch = serial_readchar (sds_desc, timeout); + + if (remote_debug > 1 && ch >= 0) + fprintf_unfiltered (gdb_stdlog, "%c(%x)", ch, ch); + + switch (ch) + { + case SERIAL_EOF: + error ("Remote connection closed"); + case SERIAL_ERROR: + perror_with_name ("Remote communication error"); + case SERIAL_TIMEOUT: + return ch; + default: + return ch & 0x7f; + } +} + +/* An SDS-style checksum is a sum of the bytes modulo 253. (Presumably + because 253, 254, and 255 are special flags in the protocol.) */ + +static int +compute_checksum (int csum, char *buf, int len) +{ + int i; + + for (i = 0; i < len; ++i) + csum += (unsigned char) buf[i]; + + csum %= 253; + return csum; +} + +/* Send the command in BUF to the remote machine, and read the reply + into BUF also. */ + +static int +sds_send (unsigned char *buf, int len) +{ + putmessage (buf, len); + + return getmessage (buf, 0); +} + +/* Send a message to the remote machine. */ + +static int +putmessage (unsigned char *buf, int len) +{ + int i, enclen; + unsigned char csum = 0; + char buf2[PBUFSIZ], buf3[PBUFSIZ]; + unsigned char header[3]; + char *p; + + /* Copy the packet into buffer BUF2, encapsulating it + and giving it a checksum. */ + + if (len > 170) /* Prosanity check */ + internal_error (__FILE__, __LINE__, "failed internal consistency check"); + + if (remote_debug) + { + fprintf_unfiltered (gdb_stdlog, "Message to send: \""); + for (i = 0; i < len; ++i) + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); + fprintf_unfiltered (gdb_stdlog, "\"\n"); + } + + p = buf2; + *p++ = '$'; + + if (len % 3 != 0) + { + buf[len] = '\0'; + buf[len + 1] = '\0'; + } + + header[1] = next_msg_id; + + header[2] = len; + + csum = compute_checksum (csum, buf, len); + csum = compute_checksum (csum, header + 1, 2); + + header[0] = csum; + + tob64 (header, p, 3); + p += 4; + enclen = tob64 (buf, buf3, ((len + 2) / 3) * 3); + + for (i = 0; i < enclen; ++i) + *p++ = buf3[i]; + *p++ = '\r'; + *p++ = '\n'; + + next_msg_id = (next_msg_id + 3) % 245; + + /* Send it over and over until we get a positive ack. */ + + while (1) + { + if (remote_debug) + { + *p = '\0'; + fprintf_unfiltered (gdb_stdlog, "Sending encoded: \"%s\"", buf2); + fprintf_unfiltered (gdb_stdlog, + " (Checksum %d, id %d, length %d)\n", + header[0], header[1], header[2]); + gdb_flush (gdb_stdlog); + } + if (serial_write (sds_desc, buf2, p - buf2)) + perror_with_name ("putmessage: write failed"); + + return 1; + } +} + +/* Come here after finding the start of the frame. Collect the rest + into BUF. Returns 0 on any error, 1 on success. */ + +static int +read_frame (char *buf) +{ + char *bp; + int c; + + bp = buf; + + while (1) + { + c = readchar (sds_timeout); + + switch (c) + { + case SERIAL_TIMEOUT: + if (remote_debug) + fputs_filtered ("Timeout in mid-message, retrying\n", gdb_stdlog); + return 0; + case '$': + if (remote_debug) + fputs_filtered ("Saw new packet start in middle of old one\n", + gdb_stdlog); + return 0; /* Start a new packet, count retries */ + case '\r': + break; + + case '\n': + { + *bp = '\000'; + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "Received encoded: \"%s\"\n", + buf); + return 1; + } + + default: + if (bp < buf + PBUFSIZ - 1) + { + *bp++ = c; + continue; + } + + *bp = '\0'; + puts_filtered ("Message too long: "); + puts_filtered (buf); + puts_filtered ("\n"); + + return 0; + } + } +} + +/* Read a packet from the remote machine, with error checking, + and store it in BUF. BUF is expected to be of size PBUFSIZ. + If FOREVER, wait forever rather than timing out; this is used + while the target is executing user code. */ + +static int +getmessage (unsigned char *buf, int forever) +{ + int c, c2, c3; + int tries; + int timeout; + int val, i, len, csum; + unsigned char header[3]; + unsigned char inbuf[500]; + + strcpy (buf, "timeout"); + + if (forever) + { + timeout = watchdog > 0 ? watchdog : -1; + } + + else + timeout = sds_timeout; + +#define MAX_TRIES 3 + + for (tries = 1; tries <= MAX_TRIES; tries++) + { + /* This can loop forever if the remote side sends us characters + continuously, but if it pauses, we'll get a zero from readchar + because of timeout. Then we'll count that as a retry. */ + + /* Note that we will only wait forever prior to the start of a packet. + After that, we expect characters to arrive at a brisk pace. They + should show up within sds_timeout intervals. */ + + do + { + c = readchar (timeout); + + if (c == SERIAL_TIMEOUT) + { + if (forever) /* Watchdog went off. Kill the target. */ + { + target_mourn_inferior (); + error ("Watchdog has expired. Target detached.\n"); + } + if (remote_debug) + fputs_filtered ("Timed out.\n", gdb_stdlog); + goto retry; + } + } + while (c != '$' && c != '{'); + + /* We might have seen a "trigraph", a sequence of three characters + that indicate various sorts of communication state. */ + + if (c == '{') + { + /* Read the other two chars of the trigraph. */ + c2 = readchar (timeout); + c3 = readchar (timeout); + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "Trigraph %c%c%c received\n", + c, c2, c3); + if (c3 == '+') + { + message_pending = 1; + return 0; /*???? */ + } + continue; + } + + val = read_frame (inbuf); + + if (val == 1) + { + fromb64 (inbuf, header, 4); + /* (should check out other bits) */ + fromb64 (inbuf + 4, buf, strlen (inbuf) - 4); + + len = header[2]; + + csum = 0; + csum = compute_checksum (csum, buf, len); + csum = compute_checksum (csum, header + 1, 2); + + if (csum != header[0]) + fprintf_unfiltered (gdb_stderr, + "Checksum mismatch: computed %d, received %d\n", + csum, header[0]); + + if (header[2] == 0xff) + fprintf_unfiltered (gdb_stderr, "Requesting resend...\n"); + + if (remote_debug) + { + fprintf_unfiltered (gdb_stdlog, + "... (Got checksum %d, id %d, length %d)\n", + header[0], header[1], header[2]); + fprintf_unfiltered (gdb_stdlog, "Message received: \""); + for (i = 0; i < len; ++i) + { + fprintf_unfiltered (gdb_stdlog, "%02x", (unsigned char) buf[i]); + } + fprintf_unfiltered (gdb_stdlog, "\"\n"); + } + + /* no ack required? */ + return len; + } + + /* Try the whole thing again. */ + retry: + /* need to do something here */ + ; + } + + /* We have tried hard enough, and just can't receive the packet. Give up. */ + + printf_unfiltered ("Ignoring packet error, continuing...\n"); + return 0; +} + +static void +sds_kill (void) +{ + /* Don't try to do anything to the target. */ +} + +static void +sds_mourn (void) +{ + unpush_target (&sds_ops); + generic_mourn_inferior (); +} + +static void +sds_create_inferior (char *exec_file, char *args, char **env) +{ + inferior_ptid = pid_to_ptid (42000); + + /* Clean up from the last time we were running. */ + clear_proceed_status (); + + /* Let the remote process run. */ + proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0); +} + +static void +sds_load (char *filename, int from_tty) +{ + generic_load (filename, from_tty); + + inferior_ptid = null_ptid; +} + +/* The SDS monitor has commands for breakpoint insertion, although it + it doesn't actually manage the breakpoints, it just returns the + replaced instruction back to the debugger. */ + +static int +sds_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + int i, retlen; + unsigned char *p, buf[PBUFSIZ]; + + p = buf; + *p++ = 16; + *p++ = 0; + *p++ = (int) (addr >> 24) & 0xff; + *p++ = (int) (addr >> 16) & 0xff; + *p++ = (int) (addr >> 8) & 0xff; + *p++ = (int) (addr) & 0xff; + + retlen = sds_send (buf, p - buf); + + for (i = 0; i < 4; ++i) + contents_cache[i] = buf[i + 2]; + + return 0; +} + +static int +sds_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + int i, retlen; + unsigned char *p, buf[PBUFSIZ]; + + p = buf; + *p++ = 17; + *p++ = 0; + *p++ = (int) (addr >> 24) & 0xff; + *p++ = (int) (addr >> 16) & 0xff; + *p++ = (int) (addr >> 8) & 0xff; + *p++ = (int) (addr) & 0xff; + for (i = 0; i < 4; ++i) + *p++ = contents_cache[i]; + + retlen = sds_send (buf, p - buf); + + return 0; +} + +static void +init_sds_ops (void) +{ + sds_ops.to_shortname = "sds"; + sds_ops.to_longname = "Remote serial target with SDS protocol"; + sds_ops.to_doc = "Use a remote computer via a serial line; using the SDS protocol.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + sds_ops.to_open = sds_open; + sds_ops.to_close = sds_close; + sds_ops.to_detach = sds_detach; + sds_ops.to_resume = sds_resume; + sds_ops.to_wait = sds_wait; + sds_ops.to_fetch_registers = sds_fetch_registers; + sds_ops.to_store_registers = sds_store_registers; + sds_ops.to_prepare_to_store = sds_prepare_to_store; + sds_ops.to_xfer_memory = sds_xfer_memory; + sds_ops.to_files_info = sds_files_info; + sds_ops.to_insert_breakpoint = sds_insert_breakpoint; + sds_ops.to_remove_breakpoint = sds_remove_breakpoint; + sds_ops.to_kill = sds_kill; + sds_ops.to_load = sds_load; + sds_ops.to_create_inferior = sds_create_inferior; + sds_ops.to_mourn_inferior = sds_mourn; + sds_ops.to_stratum = process_stratum; + sds_ops.to_has_all_memory = 1; + sds_ops.to_has_memory = 1; + sds_ops.to_has_stack = 1; + sds_ops.to_has_registers = 1; + sds_ops.to_has_execution = 1; + sds_ops.to_magic = OPS_MAGIC; +} + +/* Put a command string, in args, out to the monitor and display the + reply message. */ + +static void +sds_command (char *args, int from_tty) +{ + char *p; + int i, len, retlen; + unsigned char buf[1000]; + + /* Convert hexadecimal chars into a byte buffer. */ + p = args; + len = 0; + while (*p != '\0') + { + buf[len++] = fromhex (p[0]) * 16 + fromhex (p[1]); + if (p[1] == '\0') + break; + p += 2; + } + + retlen = sds_send (buf, len); + + printf_filtered ("Reply is "); + for (i = 0; i < retlen; ++i) + { + printf_filtered ("%02x", buf[i]); + } + printf_filtered ("\n"); +} + +void +_initialize_remote_sds (void) +{ + init_sds_ops (); + add_target (&sds_ops); + + add_show_from_set (add_set_cmd ("sdstimeout", no_class, + var_integer, (char *) &sds_timeout, + "Set timeout value for sds read.\n", &setlist), + &showlist); + + add_com ("sds", class_obscure, sds_command, + "Send a command to the SDS monitor."); +} diff --git a/contrib/gdb/gdb/remote-sim.c b/contrib/gdb/gdb/remote-sim.c new file mode 100644 index 00000000000..9b0b3fd99fe --- /dev/null +++ b/contrib/gdb/gdb/remote-sim.c @@ -0,0 +1,900 @@ +/* Generic remote debugging interface for simulators. + + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2004 Free Software Foundation, Inc. + + Contributed by Cygnus Support. + Steve Chamberlain (sac@cygnus.com). + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "value.h" +#include "gdb_string.h" +#include +#include +#include +#include +#include +#include "terminal.h" +#include "target.h" +#include "gdbcore.h" +#include "gdb/callback.h" +#include "gdb/remote-sim.h" +#include "remote-utils.h" +#include "command.h" +#include "regcache.h" +#include "gdb_assert.h" +#include "sim-regno.h" +#include "arch-utils.h" + +/* Prototypes */ + +extern void _initialize_remote_sim (void); + +extern int (*ui_loop_hook) (int signo); + +static void dump_mem (char *buf, int len); + +static void init_callbacks (void); + +static void end_callbacks (void); + +static int gdb_os_write_stdout (host_callback *, const char *, int); + +static void gdb_os_flush_stdout (host_callback *); + +static int gdb_os_write_stderr (host_callback *, const char *, int); + +static void gdb_os_flush_stderr (host_callback *); + +static int gdb_os_poll_quit (host_callback *); + +/* printf_filtered is depreciated */ +static void gdb_os_printf_filtered (host_callback *, const char *, ...); + +static void gdb_os_vprintf_filtered (host_callback *, const char *, va_list); + +static void gdb_os_evprintf_filtered (host_callback *, const char *, va_list); + +static void gdb_os_error (host_callback *, const char *, ...); + +static void gdbsim_fetch_register (int regno); + +static void gdbsim_store_register (int regno); + +static void gdbsim_kill (void); + +static void gdbsim_load (char *prog, int fromtty); + +static void gdbsim_create_inferior (char *exec_file, char *args, char **env); + +static void gdbsim_open (char *args, int from_tty); + +static void gdbsim_close (int quitting); + +static void gdbsim_detach (char *args, int from_tty); + +static void gdbsim_resume (ptid_t ptid, int step, enum target_signal siggnal); + +static ptid_t gdbsim_wait (ptid_t ptid, struct target_waitstatus *status); + +static void gdbsim_prepare_to_store (void); + +static int gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, + int len, int write, + struct mem_attrib *attrib, + struct target_ops *target); + +static void gdbsim_files_info (struct target_ops *target); + +static void gdbsim_mourn_inferior (void); + +static void gdbsim_stop (void); + +void simulator_command (char *args, int from_tty); + +/* Naming convention: + + sim_* are the interface to the simulator (see remote-sim.h). + gdbsim_* are stuff which is internal to gdb. */ + +/* Forward data declarations */ +extern struct target_ops gdbsim_ops; + +static int program_loaded = 0; + +/* We must keep track of whether the simulator has been opened or not because + GDB can call a target's close routine twice, but sim_close doesn't allow + this. We also need to record the result of sim_open so we can pass it + back to the other sim_foo routines. */ +static SIM_DESC gdbsim_desc = 0; + +static void +dump_mem (char *buf, int len) +{ + if (len <= 8) + { + if (len == 8 || len == 4) + { + long l[2]; + memcpy (l, buf, len); + printf_filtered ("\t0x%lx", l[0]); + if (len == 8) + printf_filtered (" 0x%lx", l[1]); + printf_filtered ("\n"); + } + else + { + int i; + printf_filtered ("\t"); + for (i = 0; i < len; i++) + printf_filtered ("0x%x ", buf[i]); + printf_filtered ("\n"); + } + } +} + +static host_callback gdb_callback; +static int callbacks_initialized = 0; + +/* Initialize gdb_callback. */ + +static void +init_callbacks (void) +{ + if (!callbacks_initialized) + { + gdb_callback = default_callback; + gdb_callback.init (&gdb_callback); + gdb_callback.write_stdout = gdb_os_write_stdout; + gdb_callback.flush_stdout = gdb_os_flush_stdout; + gdb_callback.write_stderr = gdb_os_write_stderr; + gdb_callback.flush_stderr = gdb_os_flush_stderr; + gdb_callback.printf_filtered = gdb_os_printf_filtered; + gdb_callback.vprintf_filtered = gdb_os_vprintf_filtered; + gdb_callback.evprintf_filtered = gdb_os_evprintf_filtered; + gdb_callback.error = gdb_os_error; + gdb_callback.poll_quit = gdb_os_poll_quit; + gdb_callback.magic = HOST_CALLBACK_MAGIC; + callbacks_initialized = 1; + } +} + +/* Release callbacks (free resources used by them). */ + +static void +end_callbacks (void) +{ + if (callbacks_initialized) + { + gdb_callback.shutdown (&gdb_callback); + callbacks_initialized = 0; + } +} + +/* GDB version of os_write_stdout callback. */ + +static int +gdb_os_write_stdout (host_callback *p, const char *buf, int len) +{ + int i; + char b[2]; + + ui_file_write (gdb_stdtarg, buf, len); + return len; +} + +/* GDB version of os_flush_stdout callback. */ + +static void +gdb_os_flush_stdout (host_callback *p) +{ + gdb_flush (gdb_stdtarg); +} + +/* GDB version of os_write_stderr callback. */ + +static int +gdb_os_write_stderr (host_callback *p, const char *buf, int len) +{ + int i; + char b[2]; + + for (i = 0; i < len; i++) + { + b[0] = buf[i]; + b[1] = 0; + fputs_unfiltered (b, gdb_stdtargerr); + } + return len; +} + +/* GDB version of os_flush_stderr callback. */ + +static void +gdb_os_flush_stderr (host_callback *p) +{ + gdb_flush (gdb_stdtargerr); +} + +/* GDB version of printf_filtered callback. */ + +static void +gdb_os_printf_filtered (host_callback * p, const char *format,...) +{ + va_list args; + va_start (args, format); + + vfprintf_filtered (gdb_stdout, format, args); + + va_end (args); +} + +/* GDB version of error vprintf_filtered. */ + +static void +gdb_os_vprintf_filtered (host_callback * p, const char *format, va_list ap) +{ + vfprintf_filtered (gdb_stdout, format, ap); +} + +/* GDB version of error evprintf_filtered. */ + +static void +gdb_os_evprintf_filtered (host_callback * p, const char *format, va_list ap) +{ + vfprintf_filtered (gdb_stderr, format, ap); +} + +/* GDB version of error callback. */ + +static void +gdb_os_error (host_callback * p, const char *format,...) +{ + if (error_hook) + (*error_hook) (); + else + { + va_list args; + va_start (args, format); + verror (format, args); + va_end (args); + } +} + +int +one2one_register_sim_regno (int regnum) +{ + /* Only makes sense to supply raw registers. */ + gdb_assert (regnum >= 0 && regnum < NUM_REGS); + return regnum; +} + +static void +gdbsim_fetch_register (int regno) +{ + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + gdbsim_fetch_register (regno); + return; + } + + switch (REGISTER_SIM_REGNO (regno)) + { + case LEGACY_SIM_REGNO_IGNORE: + break; + case SIM_REGNO_DOES_NOT_EXIST: + { + /* For moment treat a `does not exist' register the same way + as an ``unavailable'' register. */ + char buf[MAX_REGISTER_SIZE]; + int nr_bytes; + memset (buf, 0, MAX_REGISTER_SIZE); + supply_register (regno, buf); + set_register_cached (regno, -1); + break; + } + default: + { + static int warn_user = 1; + char buf[MAX_REGISTER_SIZE]; + int nr_bytes; + gdb_assert (regno >= 0 && regno < NUM_REGS); + memset (buf, 0, MAX_REGISTER_SIZE); + nr_bytes = sim_fetch_register (gdbsim_desc, + REGISTER_SIM_REGNO (regno), + buf, DEPRECATED_REGISTER_RAW_SIZE (regno)); + if (nr_bytes > 0 && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (regno) && warn_user) + { + fprintf_unfiltered (gdb_stderr, + "Size of register %s (%d/%d) incorrect (%d instead of %d))", + REGISTER_NAME (regno), + regno, REGISTER_SIM_REGNO (regno), + nr_bytes, DEPRECATED_REGISTER_RAW_SIZE (regno)); + warn_user = 0; + } + /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0' + indicating that GDB and the SIM have different ideas about + which registers are fetchable. */ + /* Else if (nr_bytes < 0): an old simulator, that doesn't + think to return the register size. Just assume all is ok. */ + supply_register (regno, buf); + if (sr_get_debug ()) + { + printf_filtered ("gdbsim_fetch_register: %d", regno); + /* FIXME: We could print something more intelligible. */ + dump_mem (buf, DEPRECATED_REGISTER_RAW_SIZE (regno)); + } + break; + } + } +} + + +static void +gdbsim_store_register (int regno) +{ + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + gdbsim_store_register (regno); + return; + } + else if (REGISTER_SIM_REGNO (regno) >= 0) + { + char tmp[MAX_REGISTER_SIZE]; + int nr_bytes; + deprecated_read_register_gen (regno, tmp); + nr_bytes = sim_store_register (gdbsim_desc, + REGISTER_SIM_REGNO (regno), + tmp, DEPRECATED_REGISTER_RAW_SIZE (regno)); + if (nr_bytes > 0 && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (regno)) + internal_error (__FILE__, __LINE__, + "Register size different to expected"); + /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0' + indicating that GDB and the SIM have different ideas about + which registers are fetchable. */ + if (sr_get_debug ()) + { + printf_filtered ("gdbsim_store_register: %d", regno); + /* FIXME: We could print something more intelligible. */ + dump_mem (tmp, DEPRECATED_REGISTER_RAW_SIZE (regno)); + } + } +} + +/* Kill the running program. This may involve closing any open files + and releasing other resources acquired by the simulated program. */ + +static void +gdbsim_kill (void) +{ + if (sr_get_debug ()) + printf_filtered ("gdbsim_kill\n"); + + /* There is no need to `kill' running simulator - the simulator is + not running */ + inferior_ptid = null_ptid; +} + +/* Load an executable file into the target process. This is expected to + not only bring new code into the target process, but also to update + GDB's symbol tables to match. */ + +static void +gdbsim_load (char *prog, int fromtty) +{ + if (sr_get_debug ()) + printf_filtered ("gdbsim_load: prog \"%s\"\n", prog); + + inferior_ptid = null_ptid; + + /* FIXME: We will print two messages on error. + Need error to either not print anything if passed NULL or need + another routine that doesn't take any arguments. */ + if (sim_load (gdbsim_desc, prog, NULL, fromtty) == SIM_RC_FAIL) + error ("unable to load program"); + + /* FIXME: If a load command should reset the targets registers then + a call to sim_create_inferior() should go here. */ + + program_loaded = 1; +} + + +/* Start an inferior process and set inferior_ptid to its pid. + EXEC_FILE is the file to run. + ARGS is a string containing the arguments to the program. + ENV is the environment vector to pass. Errors reported with error(). + On VxWorks and various standalone systems, we ignore exec_file. */ +/* This is called not only when we first attach, but also when the + user types "run" after having attached. */ + +static void +gdbsim_create_inferior (char *exec_file, char *args, char **env) +{ + int len; + char *arg_buf, **argv; + + if (exec_file == 0 || exec_bfd == 0) + warning ("No executable file specified."); + if (!program_loaded) + warning ("No program loaded."); + + if (sr_get_debug ()) + printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n", + (exec_file ? exec_file : "(NULL)"), + args); + + gdbsim_kill (); + remove_breakpoints (); + init_wait_for_inferior (); + + if (exec_file != NULL) + { + len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10; + arg_buf = (char *) alloca (len); + arg_buf[0] = '\0'; + strcat (arg_buf, exec_file); + strcat (arg_buf, " "); + strcat (arg_buf, args); + argv = buildargv (arg_buf); + make_cleanup_freeargv (argv); + } + else + argv = NULL; + sim_create_inferior (gdbsim_desc, exec_bfd, argv, env); + + inferior_ptid = pid_to_ptid (42); + insert_breakpoints (); /* Needed to get correct instruction in cache */ + + clear_proceed_status (); + + /* NB: Entry point already set by sim_create_inferior. */ + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); +} + +/* The open routine takes the rest of the parameters from the command, + and (if successful) pushes a new target onto the stack. + Targets should supply this routine, if only to provide an error message. */ +/* Called when selecting the simulator. EG: (gdb) target sim name. */ + +static void +gdbsim_open (char *args, int from_tty) +{ + int len; + char *arg_buf; + char **argv; + + if (sr_get_debug ()) + printf_filtered ("gdbsim_open: args \"%s\"\n", args ? args : "(null)"); + + /* Remove current simulator if one exists. Only do this if the simulator + has been opened because sim_close requires it. + This is important because the call to push_target below will cause + sim_close to be called if the simulator is already open, but push_target + is called after sim_open! We can't move the call to push_target before + the call to sim_open because sim_open may invoke `error'. */ + if (gdbsim_desc != NULL) + unpush_target (&gdbsim_ops); + + len = (7 + 1 /* gdbsim */ + + strlen (" -E little") + + strlen (" --architecture=xxxxxxxxxx") + + (args ? strlen (args) : 0) + + 50) /* slack */ ; + arg_buf = (char *) alloca (len); + strcpy (arg_buf, "gdbsim"); /* 7 */ + /* Specify the byte order for the target when it is both selectable + and explicitly specified by the user (not auto detected). */ + switch (selected_byte_order ()) + { + case BFD_ENDIAN_BIG: + strcat (arg_buf, " -E big"); + break; + case BFD_ENDIAN_LITTLE: + strcat (arg_buf, " -E little"); + break; + case BFD_ENDIAN_UNKNOWN: + break; + } + /* Specify the architecture of the target when it has been + explicitly specified */ + if (selected_architecture_name () != NULL) + { + strcat (arg_buf, " --architecture="); + strcat (arg_buf, selected_architecture_name ()); + } + /* finally, any explicit args */ + if (args) + { + strcat (arg_buf, " "); /* 1 */ + strcat (arg_buf, args); + } + argv = buildargv (arg_buf); + if (argv == NULL) + error ("Insufficient memory available to allocate simulator arg list."); + make_cleanup_freeargv (argv); + + init_callbacks (); + gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, argv); + + if (gdbsim_desc == 0) + error ("unable to create simulator instance"); + + push_target (&gdbsim_ops); + target_fetch_registers (-1); + printf_filtered ("Connected to the simulator.\n"); +} + +/* Does whatever cleanup is required for a target that we are no longer + going to be calling. Argument says whether we are quitting gdb and + should not get hung in case of errors, or whether we want a clean + termination even if it takes a while. This routine is automatically + always called just before a routine is popped off the target stack. + Closing file descriptors and freeing memory are typical things it should + do. */ +/* Close out all files and local state before this target loses control. */ + +static void +gdbsim_close (int quitting) +{ + if (sr_get_debug ()) + printf_filtered ("gdbsim_close: quitting %d\n", quitting); + + program_loaded = 0; + + if (gdbsim_desc != NULL) + { + sim_close (gdbsim_desc, quitting); + gdbsim_desc = NULL; + } + + end_callbacks (); + generic_mourn_inferior (); +} + +/* Takes a program previously attached to and detaches it. + The program may resume execution (some targets do, some don't) and will + no longer stop on signals, etc. We better not have left any breakpoints + in the program or it'll die when it hits one. ARGS is arguments + typed by the user (e.g. a signal to send the process). FROM_TTY + says whether to be verbose or not. */ +/* Terminate the open connection to the remote debugger. + Use this when you want to detach and do something else with your gdb. */ + +static void +gdbsim_detach (char *args, int from_tty) +{ + if (sr_get_debug ()) + printf_filtered ("gdbsim_detach: args \"%s\"\n", args); + + pop_target (); /* calls gdbsim_close to do the real work */ + if (from_tty) + printf_filtered ("Ending simulator %s debugging\n", target_shortname); +} + +/* Resume execution of the target process. STEP says whether to single-step + or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given + to the target, or zero for no signal. */ + +static enum target_signal resume_siggnal; +static int resume_step; + +static void +gdbsim_resume (ptid_t ptid, int step, enum target_signal siggnal) +{ + if (PIDGET (inferior_ptid) != 42) + error ("The program is not being run."); + + if (sr_get_debug ()) + printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal); + + resume_siggnal = siggnal; + resume_step = step; +} + +/* Notify the simulator of an asynchronous request to stop. + + The simulator shall ensure that the stop request is eventually + delivered to the simulator. If the call is made while the + simulator is not running then the stop request is processed when + the simulator is next resumed. + + For simulators that do not support this operation, just abort */ + +static void +gdbsim_stop (void) +{ + if (!sim_stop (gdbsim_desc)) + { + quit (); + } +} + +/* GDB version of os_poll_quit callback. + Taken from gdb/util.c - should be in a library */ + +static int +gdb_os_poll_quit (host_callback *p) +{ + if (ui_loop_hook != NULL) + ui_loop_hook (0); + + if (quit_flag) /* gdb's idea of quit */ + { + quit_flag = 0; /* we've stolen it */ + return 1; + } + else if (immediate_quit) + { + return 1; + } + return 0; +} + +/* Wait for inferior process to do something. Return pid of child, + or -1 in case of error; store status through argument pointer STATUS, + just as `wait' would. */ + +static void +gdbsim_cntrl_c (int signo) +{ + gdbsim_stop (); +} + +static ptid_t +gdbsim_wait (ptid_t ptid, struct target_waitstatus *status) +{ + static RETSIGTYPE (*prev_sigint) (); + int sigrc = 0; + enum sim_stop reason = sim_running; + + if (sr_get_debug ()) + printf_filtered ("gdbsim_wait\n"); + +#if defined (HAVE_SIGACTION) && defined (SA_RESTART) + { + struct sigaction sa, osa; + sa.sa_handler = gdbsim_cntrl_c; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (SIGINT, &sa, &osa); + prev_sigint = osa.sa_handler; + } +#else + prev_sigint = signal (SIGINT, gdbsim_cntrl_c); +#endif + sim_resume (gdbsim_desc, resume_step, + target_signal_to_host (resume_siggnal)); + signal (SIGINT, prev_sigint); + resume_step = 0; + + sim_stop_reason (gdbsim_desc, &reason, &sigrc); + + switch (reason) + { + case sim_exited: + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = sigrc; + break; + case sim_stopped: + switch (sigrc) + { + case SIGABRT: + quit (); + break; + case SIGINT: + case SIGTRAP: + default: + status->kind = TARGET_WAITKIND_STOPPED; + /* The signal in sigrc is a host signal. That probably + should be fixed. */ + status->value.sig = target_signal_from_host (sigrc); + break; + } + break; + case sim_signalled: + status->kind = TARGET_WAITKIND_SIGNALLED; + /* The signal in sigrc is a host signal. That probably + should be fixed. */ + status->value.sig = target_signal_from_host (sigrc); + break; + case sim_running: + case sim_polling: + /* FIXME: Is this correct? */ + break; + } + + return inferior_ptid; +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +gdbsim_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ +} + +/* Transfer LEN bytes between GDB address MYADDR and target address + MEMADDR. If WRITE is non-zero, transfer them to the target, + otherwise transfer them from the target. TARGET is unused. + + Returns the number of bytes transferred. */ + +static int +gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, struct mem_attrib *attrib, + struct target_ops *target) +{ + if (!program_loaded) + error ("No program loaded."); + + if (sr_get_debug ()) + { + /* FIXME: Send to something other than STDOUT? */ + printf_filtered ("gdbsim_xfer_inferior_memory: myaddr 0x"); + gdb_print_host_address (myaddr, gdb_stdout); + printf_filtered (", memaddr 0x%s, len %d, write %d\n", + paddr_nz (memaddr), len, write); + if (sr_get_debug () && write) + dump_mem (myaddr, len); + } + + if (write) + { + len = sim_write (gdbsim_desc, memaddr, myaddr, len); + } + else + { + len = sim_read (gdbsim_desc, memaddr, myaddr, len); + if (sr_get_debug () && len > 0) + dump_mem (myaddr, len); + } + return len; +} + +static void +gdbsim_files_info (struct target_ops *target) +{ + char *file = "nothing"; + + if (exec_bfd) + file = bfd_get_filename (exec_bfd); + + if (sr_get_debug ()) + printf_filtered ("gdbsim_files_info: file \"%s\"\n", file); + + if (exec_bfd) + { + printf_filtered ("\tAttached to %s running program %s\n", + target_shortname, file); + sim_info (gdbsim_desc, 0); + } +} + +/* Clear the simulator's notion of what the break points are. */ + +static void +gdbsim_mourn_inferior (void) +{ + if (sr_get_debug ()) + printf_filtered ("gdbsim_mourn_inferior:\n"); + + remove_breakpoints (); + generic_mourn_inferior (); +} + +static int +gdbsim_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + return memory_insert_breakpoint (addr, contents_cache); +} + +static int +gdbsim_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +{ + return memory_remove_breakpoint (addr, contents_cache); +} + +/* Pass the command argument through to the simulator verbatim. The + simulator must do any command interpretation work. */ + +void +simulator_command (char *args, int from_tty) +{ + if (gdbsim_desc == NULL) + { + + /* PREVIOUSLY: The user may give a command before the simulator + is opened. [...] (??? assuming of course one wishes to + continue to allow commands to be sent to unopened simulators, + which isn't entirely unreasonable). */ + + /* The simulator is a builtin abstraction of a remote target. + Consistent with that model, access to the simulator, via sim + commands, is restricted to the period when the channel to the + simulator is open. */ + + error ("Not connected to the simulator target"); + } + + sim_do_command (gdbsim_desc, args); + + /* Invalidate the register cache, in case the simulator command does + something funny. */ + registers_changed (); +} + +/* Define the target subroutine names */ + +struct target_ops gdbsim_ops; + +static void +init_gdbsim_ops (void) +{ + gdbsim_ops.to_shortname = "sim"; + gdbsim_ops.to_longname = "simulator"; + gdbsim_ops.to_doc = "Use the compiled-in simulator."; + gdbsim_ops.to_open = gdbsim_open; + gdbsim_ops.to_close = gdbsim_close; + gdbsim_ops.to_detach = gdbsim_detach; + gdbsim_ops.to_resume = gdbsim_resume; + gdbsim_ops.to_wait = gdbsim_wait; + gdbsim_ops.to_fetch_registers = gdbsim_fetch_register; + gdbsim_ops.to_store_registers = gdbsim_store_register; + gdbsim_ops.to_prepare_to_store = gdbsim_prepare_to_store; + gdbsim_ops.to_xfer_memory = gdbsim_xfer_inferior_memory; + gdbsim_ops.to_files_info = gdbsim_files_info; + gdbsim_ops.to_insert_breakpoint = gdbsim_insert_breakpoint; + gdbsim_ops.to_remove_breakpoint = gdbsim_remove_breakpoint; + gdbsim_ops.to_kill = gdbsim_kill; + gdbsim_ops.to_load = gdbsim_load; + gdbsim_ops.to_create_inferior = gdbsim_create_inferior; + gdbsim_ops.to_mourn_inferior = gdbsim_mourn_inferior; + gdbsim_ops.to_stop = gdbsim_stop; + gdbsim_ops.to_stratum = process_stratum; + gdbsim_ops.to_has_all_memory = 1; + gdbsim_ops.to_has_memory = 1; + gdbsim_ops.to_has_stack = 1; + gdbsim_ops.to_has_registers = 1; + gdbsim_ops.to_has_execution = 1; + gdbsim_ops.to_magic = OPS_MAGIC; + +#ifdef TARGET_REDEFINE_DEFAULT_OPS + TARGET_REDEFINE_DEFAULT_OPS (&gdbsim_ops); +#endif +} + +void +_initialize_remote_sim (void) +{ + init_gdbsim_ops (); + add_target (&gdbsim_ops); + + add_com ("sim ", class_obscure, simulator_command, + "Send a command to the simulator."); +} diff --git a/contrib/gdb/gdb/remote-st.c b/contrib/gdb/gdb/remote-st.c new file mode 100644 index 00000000000..ce4c7ab13e5 --- /dev/null +++ b/contrib/gdb/gdb/remote-st.c @@ -0,0 +1,803 @@ +/* Remote debugging interface for Tandem ST2000 phone switch, for GDB. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, + 2001, 2002 Free Software Foundation, Inc. + + Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This file was derived from remote-eb.c, which did a similar job, but for + an AMD-29K running EBMON. That file was in turn derived from remote.c + as mentioned in the following comment (left in for comic relief): + + "This is like remote.c but is for an esoteric situation-- + having an a29k board in a PC hooked up to a unix machine with + a serial line, and running ctty com1 on the PC, through which + the unix machine can run ebmon. Not to mention that the PC + has PC/NFS, so it can access the same executables that gdb can, + over the net in real time." + + In reality, this module talks to a debug monitor called 'STDEBUG', which + runs in a phone switch. We communicate with STDEBUG via either a direct + serial line, or a TCP (or possibly TELNET) stream to a terminal multiplexor, + which in turn talks to the phone switch. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "gdb_string.h" +#include +#include "serial.h" +#include "regcache.h" + +extern struct target_ops st2000_ops; /* Forward declaration */ + +static void st2000_close (); +static void st2000_fetch_register (); +static void st2000_store_register (); + +#define LOG_FILE "st2000.log" +#if defined (LOG_FILE) +FILE *log_file; +#endif + +static int timeout = 24; + +/* Descriptor for I/O to remote machine. Initialize it to -1 so that + st2000_open knows that we don't have a file open when the program + starts. */ + +static struct serial *st2000_desc; + +/* Send data to stdebug. Works just like printf. */ + +static void +printf_stdebug (char *pattern,...) +{ + va_list args; + char buf[200]; + + va_start (args, pattern); + + vsprintf (buf, pattern, args); + va_end (args); + + if (serial_write (st2000_desc, buf, strlen (buf))) + fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n", + safe_strerror (errno)); +} + +/* Read a character from the remote system, doing all the fancy timeout + stuff. */ + +static int +readchar (int timeout) +{ + int c; + + c = serial_readchar (st2000_desc, timeout); + +#ifdef LOG_FILE + putc (c & 0x7f, log_file); +#endif + + if (c >= 0) + return c & 0x7f; + + if (c == SERIAL_TIMEOUT) + { + if (timeout == 0) + return c; /* Polls shouldn't generate timeout errors */ + + error ("Timeout reading from remote system."); + } + + perror_with_name ("remote-st2000"); +} + +/* Scan input from the remote system, until STRING is found. If DISCARD is + non-zero, then discard non-matching input, else print it out. + Let the user break out immediately. */ +static void +expect (char *string, int discard) +{ + char *p = string; + int c; + + immediate_quit++; + while (1) + { + c = readchar (timeout); + if (c == *p++) + { + if (*p == '\0') + { + immediate_quit--; + return; + } + } + else + { + if (!discard) + { + fwrite (string, 1, (p - 1) - string, stdout); + putchar ((char) c); + fflush (stdout); + } + p = string; + } + } +} + +/* Keep discarding input until we see the STDEBUG prompt. + + The convention for dealing with the prompt is that you + o give your command + o *then* wait for the prompt. + + Thus the last thing that a procedure does with the serial line + will be an expect_prompt(). Exception: st2000_resume does not + wait for the prompt, because the terminal is being handed over + to the inferior. However, the next thing which happens after that + is a st2000_wait which does wait for the prompt. + Note that this includes abnormal exit, e.g. error(). This is + necessary to prevent getting into states from which we can't + recover. */ +static void +expect_prompt (int discard) +{ +#if defined (LOG_FILE) + /* This is a convenient place to do this. The idea is to do it often + enough that we never lose much data if we terminate abnormally. */ + fflush (log_file); +#endif + expect ("dbug> ", discard); +} + +/* Get a hex digit from the remote system & return its value. + If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ +static int +get_hex_digit (int ignore_space) +{ + int ch; + while (1) + { + ch = readchar (timeout); + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else if (ch == ' ' && ignore_space) + ; + else + { + expect_prompt (1); + error ("Invalid hex digit from remote system."); + } + } +} + +/* Get a byte from stdebug and put it in *BYT. Accept any number + leading spaces. */ +static void +get_hex_byte (char *byt) +{ + int val; + + val = get_hex_digit (1) << 4; + val |= get_hex_digit (0); + *byt = val; +} + +/* Get N 32-bit words from remote, each preceded by a space, + and put them in registers starting at REGNO. */ +static void +get_hex_regs (int n, int regno) +{ + long val; + int i; + + for (i = 0; i < n; i++) + { + int j; + + val = 0; + for (j = 0; j < 8; j++) + val = (val << 4) + get_hex_digit (j == 0); + supply_register (regno++, (char *) &val); + } +} + +/* This is called not only when we first attach, but also when the + user types "run" after having attached. */ +static void +st2000_create_inferior (char *execfile, char *args, char **env) +{ + int entry_pt; + + if (args && *args) + error ("Can't pass arguments to remote STDEBUG process"); + + if (execfile == 0 || exec_bfd == 0) + error ("No executable file specified"); + + entry_pt = (int) bfd_get_start_address (exec_bfd); + +/* The "process" (board) is already stopped awaiting our commands, and + the program is already downloaded. We just set its PC and go. */ + + clear_proceed_status (); + + /* Tell wait_for_inferior that we've started a new process. */ + init_wait_for_inferior (); + + /* Set up the "saved terminal modes" of the inferior + based on what modes we are starting it with. */ + target_terminal_init (); + + /* Install inferior's terminal modes. */ + target_terminal_inferior (); + + /* insert_step_breakpoint (); FIXME, do we need this? */ + /* Let 'er rip... */ + proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0); +} + +/* Open a connection to a remote debugger. + NAME is the filename used for communication. */ + +static int baudrate = 9600; +static char dev_name[100]; + +static void +st2000_open (char *args, int from_tty) +{ + int n; + char junk[100]; + + target_preopen (from_tty); + + n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk); + + if (n != 2) + error ("Bad arguments. Usage: target st2000 \n\ +or target st2000 \n"); + + st2000_close (0); + + st2000_desc = serial_open (dev_name); + + if (!st2000_desc) + perror_with_name (dev_name); + + if (serial_setbaudrate (st2000_desc, baudrate)) + { + serial_close (dev_name); + perror_with_name (dev_name); + } + + serial_raw (st2000_desc); + + push_target (&st2000_ops); + +#if defined (LOG_FILE) + log_file = fopen (LOG_FILE, "w"); + if (log_file == NULL) + perror_with_name (LOG_FILE); +#endif + + /* Hello? Are you there? */ + printf_stdebug ("\003"); /* ^C wakes up dbug */ + + expect_prompt (1); + + if (from_tty) + printf ("Remote %s connected to %s\n", target_shortname, + dev_name); +} + +/* Close out all files and local state before this target loses control. */ + +static void +st2000_close (int quitting) +{ + serial_close (st2000_desc); + +#if defined (LOG_FILE) + if (log_file) + { + if (ferror (log_file)) + fprintf_unfiltered (gdb_stderr, "Error writing log file.\n"); + if (fclose (log_file) != 0) + fprintf_unfiltered (gdb_stderr, "Error closing log file.\n"); + } +#endif +} + +/* Terminate the open connection to the remote debugger. + Use this when you want to detach and do something else + with your gdb. */ +static void +st2000_detach (int from_tty) +{ + pop_target (); /* calls st2000_close to do the real work */ + if (from_tty) + printf ("Ending remote %s debugging\n", target_shortname); +} + +/* Tell the remote machine to resume. */ + +static void +st2000_resume (ptid_t ptid, int step, enum target_signal sig) +{ + if (step) + { + printf_stdebug ("ST\r"); + /* Wait for the echo. */ + expect ("ST\r", 1); + } + else + { + printf_stdebug ("GO\r"); + /* Swallow the echo. */ + expect ("GO\r", 1); + } +} + +/* Wait until the remote machine stops, then return, + storing status in STATUS just as `wait' would. */ + +static ptid_t +st2000_wait (ptid_t ptid, struct target_waitstatus *status) +{ + int old_timeout = timeout; + + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = 0; + + timeout = 0; /* Don't time out -- user program is running. */ + + expect_prompt (0); /* Wait for prompt, outputting extraneous text */ + + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = TARGET_SIGNAL_TRAP; + + timeout = old_timeout; + + return inferior_ptid; +} + +/* Return the name of register number REGNO in the form input and + output by STDEBUG. Currently, REGISTER_NAME just happens return + exactly what STDEBUG wants. Lets take advantage of that just as + long as possible! */ + +static char * +get_reg_name (int regno) +{ + static char buf[50]; + const char *p; + char *b; + + b = buf; + + for (p = REGISTER_NAME (regno); *p; p++) + *b++ = toupper (*p); + *b = '\000'; + + return buf; +} + +/* Read the remote registers into the block REGS. */ + +static void +st2000_fetch_registers (void) +{ + int regno; + + /* Yeah yeah, I know this is horribly inefficient. But it isn't done + very often... I'll clean it up later. */ + + for (regno = 0; regno <= PC_REGNUM; regno++) + st2000_fetch_register (regno); +} + +/* Fetch register REGNO, or all registers if REGNO is -1. + Returns errno value. */ +static void +st2000_fetch_register (int regno) +{ + if (regno == -1) + st2000_fetch_registers (); + else + { + char *name = get_reg_name (regno); + printf_stdebug ("DR %s\r", name); + expect (name, 1); + expect (" : ", 1); + get_hex_regs (1, regno); + expect_prompt (1); + } + return; +} + +/* Store the remote registers from the contents of the block REGS. */ + +static void +st2000_store_registers (void) +{ + int regno; + + for (regno = 0; regno <= PC_REGNUM; regno++) + st2000_store_register (regno); + + registers_changed (); +} + +/* Store register REGNO, or all if REGNO == 0. + Return errno value. */ +static void +st2000_store_register (int regno) +{ + if (regno == -1) + st2000_store_registers (); + else + { + printf_stdebug ("PR %s %x\r", get_reg_name (regno), + read_register (regno)); + + expect_prompt (1); + } +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +st2000_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ +} + +static void +st2000_files_info (void) +{ + printf ("\tAttached to %s at %d baud.\n", + dev_name, baudrate); +} + +/* Copy LEN bytes of data from debugger memory at MYADDR + to inferior's memory at MEMADDR. Returns length moved. */ +static int +st2000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + int i; + + for (i = 0; i < len; i++) + { + printf_stdebug ("PM.B %x %x\r", memaddr + i, myaddr[i]); + expect_prompt (1); + } + return len; +} + +/* Read LEN bytes from inferior memory at MEMADDR. Put the result + at debugger address MYADDR. Returns length moved. */ +static int +st2000_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + int i; + + /* Number of bytes read so far. */ + int count; + + /* Starting address of this pass. */ + unsigned long startaddr; + + /* Number of bytes to read in this pass. */ + int len_this_pass; + + /* Note that this code works correctly if startaddr is just less + than UINT_MAX (well, really CORE_ADDR_MAX if there was such a + thing). That is, something like + st2000_read_bytes (CORE_ADDR_MAX - 4, foo, 4) + works--it never adds len to memaddr and gets 0. */ + /* However, something like + st2000_read_bytes (CORE_ADDR_MAX - 3, foo, 4) + doesn't need to work. Detect it and give up if there's an attempt + to do that. */ + if (((memaddr - 1) + len) < memaddr) + { + errno = EIO; + return 0; + } + + startaddr = memaddr; + count = 0; + while (count < len) + { + len_this_pass = 16; + if ((startaddr % 16) != 0) + len_this_pass -= startaddr % 16; + if (len_this_pass > (len - count)) + len_this_pass = (len - count); + + printf_stdebug ("DI.L %x %x\r", startaddr, len_this_pass); + expect (": ", 1); + + for (i = 0; i < len_this_pass; i++) + get_hex_byte (&myaddr[count++]); + + expect_prompt (1); + + startaddr += len_this_pass; + } + return len; +} + +/* Transfer LEN bytes between GDB address MYADDR and target address + MEMADDR. If WRITE is non-zero, transfer them to the target, + otherwise transfer them from the target. TARGET is unused. + + Returns the number of bytes transferred. */ + +static int +st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, struct mem_attrib *attrib, + struct target_ops *target) +{ + if (write) + return st2000_write_inferior_memory (memaddr, myaddr, len); + else + return st2000_read_inferior_memory (memaddr, myaddr, len); +} + +static void +st2000_kill (char *args, int from_tty) +{ + return; /* Ignore attempts to kill target system */ +} + +/* Clean up when a program exits. + + The program actually lives on in the remote processor's RAM, and may be + run again without a download. Don't leave it full of breakpoint + instructions. */ + +static void +st2000_mourn_inferior (void) +{ + remove_breakpoints (); + unpush_target (&st2000_ops); + generic_mourn_inferior (); /* Do all the proper things now */ +} + +#define MAX_STDEBUG_BREAKPOINTS 16 + +static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] = +{0}; + +static int +st2000_insert_breakpoint (CORE_ADDR addr, char *shadow) +{ + int i; + CORE_ADDR bp_addr = addr; + int bp_size = 0; + + BREAKPOINT_FROM_PC (&bp_addr, &bp_size); + + for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++) + if (breakaddr[i] == 0) + { + breakaddr[i] = addr; + + st2000_read_inferior_memory (bp_addr, shadow, bp_size); + printf_stdebug ("BR %x H\r", addr); + expect_prompt (1); + return 0; + } + + fprintf_unfiltered (gdb_stderr, "Too many breakpoints (> 16) for STDBUG\n"); + return 1; +} + +static int +st2000_remove_breakpoint (CORE_ADDR addr, char *shadow) +{ + int i; + + for (i = 0; i < MAX_STDEBUG_BREAKPOINTS; i++) + if (breakaddr[i] == addr) + { + breakaddr[i] = 0; + + printf_stdebug ("CB %d\r", i); + expect_prompt (1); + return 0; + } + + fprintf_unfiltered (gdb_stderr, + "Can't find breakpoint associated with 0x%x\n", addr); + return 1; +} + + +/* Put a command string, in args, out to STDBUG. Output from STDBUG is placed + on the users terminal until the prompt is seen. */ + +static void +st2000_command (char *args, int fromtty) +{ + if (!st2000_desc) + error ("st2000 target not open."); + + if (!args) + error ("Missing command."); + + printf_stdebug ("%s\r", args); + expect_prompt (0); +} + +/* Connect the user directly to STDBUG. This command acts just like the + 'cu' or 'tip' command. Use ~. or ~^D to break out. */ + +/*static struct ttystate ttystate; */ + +static void +cleanup_tty (void) +{ + printf ("\r\n[Exiting connect mode]\r\n"); +/* serial_restore(0, &ttystate); */ +} + +#if 0 +/* This all should now be in serial.c */ + +static void +connect_command (char *args, int fromtty) +{ + fd_set readfds; + int numfds; + int c; + char cur_esc = 0; + + dont_repeat (); + + if (st2000_desc < 0) + error ("st2000 target not open."); + + if (args) + fprintf ("This command takes no args. They have been ignored.\n"); + + printf ("[Entering connect mode. Use ~. or ~^D to escape]\n"); + + serial_raw (0, &ttystate); + + make_cleanup (cleanup_tty, 0); + + FD_ZERO (&readfds); + + while (1) + { + do + { + FD_SET (0, &readfds); + FD_SET (deprecated_serial_fd (st2000_desc), &readfds); + numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0); + } + while (numfds == 0); + + if (numfds < 0) + perror_with_name ("select"); + + if (FD_ISSET (0, &readfds)) + { /* tty input, send to stdebug */ + c = getchar (); + if (c < 0) + perror_with_name ("connect"); + + printf_stdebug ("%c", c); + switch (cur_esc) + { + case 0: + if (c == '\r') + cur_esc = c; + break; + case '\r': + if (c == '~') + cur_esc = c; + else + cur_esc = 0; + break; + case '~': + if (c == '.' || c == '\004') + return; + else + cur_esc = 0; + } + } + + if (FD_ISSET (deprecated_serial_fd (st2000_desc), &readfds)) + { + while (1) + { + c = readchar (0); + if (c < 0) + break; + putchar (c); + } + fflush (stdout); + } + } +} +#endif /* 0 */ + +/* Define the target subroutine names */ + +struct target_ops st2000_ops; + +static void +init_st2000_ops (void) +{ + st2000_ops.to_shortname = "st2000"; + st2000_ops.to_longname = "Remote serial Tandem ST2000 target"; + st2000_ops.to_doc = "Use a remote computer running STDEBUG connected by a serial line;\n\ +or a network connection.\n\ +Arguments are the name of the device for the serial line,\n\ +the speed to connect at in bits per second."; + st2000_ops.to_open = st2000_open; + st2000_ops.to_close = st2000_close; + st2000_ops.to_detach = st2000_detach; + st2000_ops.to_resume = st2000_resume; + st2000_ops.to_wait = st2000_wait; + st2000_ops.to_fetch_registers = st2000_fetch_register; + st2000_ops.to_store_registers = st2000_store_register; + st2000_ops.to_prepare_to_store = st2000_prepare_to_store; + st2000_ops.to_xfer_memory = st2000_xfer_inferior_memory; + st2000_ops.to_files_info = st2000_files_info; + st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint; + st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint; /* Breakpoints */ + st2000_ops.to_kill = st2000_kill; + st2000_ops.to_create_inferior = st2000_create_inferior; + st2000_ops.to_mourn_inferior = st2000_mourn_inferior; + st2000_ops.to_stratum = process_stratum; + st2000_ops.to_has_all_memory = 1; + st2000_ops.to_has_memory = 1; + st2000_ops.to_has_stack = 1; + st2000_ops.to_has_registers = 1; + st2000_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */ + st2000_ops.to_magic = OPS_MAGIC; /* Always the last thing */ +}; + +void +_initialize_remote_st2000 (void) +{ + init_st2000_ops (); + add_target (&st2000_ops); + add_com ("st2000 ", class_obscure, st2000_command, + "Send a command to the STDBUG monitor."); + add_com ("connect", class_obscure, connect_command, + "Connect the terminal directly up to the STDBUG command monitor.\n\ +Use ~. or ~^D to break out."); +} diff --git a/contrib/gdb/gdb/remote-utils.c b/contrib/gdb/gdb/remote-utils.c index e703f3dee35..ba150e34d5d 100644 --- a/contrib/gdb/gdb/remote-utils.c +++ b/contrib/gdb/gdb/remote-utils.c @@ -86,7 +86,7 @@ usage (char *proto, char *junk) fprintf_unfiltered (gdb_stderr, "Unrecognized arguments: `%s'.\n", junk); error ("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\ -where DEVICE is the name of a device or HOST:PORT", proto, proto); +where DEVICE is the name of a device or HOST:PORT", proto); return; } diff --git a/contrib/gdb/gdb/remote-utils.h b/contrib/gdb/gdb/remote-utils.h index 3ca3bb4dcce..cae5d5e238d 100644 --- a/contrib/gdb/gdb/remote-utils.h +++ b/contrib/gdb/gdb/remote-utils.h @@ -22,6 +22,8 @@ #ifndef REMOTE_UTILS_H #define REMOTE_UTILS_H +struct target_ops; + #include "target.h" struct serial; diff --git a/contrib/gdb/gdb/remote-vx.c b/contrib/gdb/gdb/remote-vx.c new file mode 100644 index 00000000000..fd51781b196 --- /dev/null +++ b/contrib/gdb/gdb/remote-vx.c @@ -0,0 +1,1409 @@ +/* Memory-access and commands for remote VxWorks processes, for GDB. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, + 2000, 2001, 2002 Free Software Foundation, Inc. + + Contributed by Wind River Systems and Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "inferior.h" +#include "target.h" +#include "gdbcore.h" +#include "command.h" +#include "symtab.h" +#include "complaints.h" +#include "gdbcmd.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" +#include "objfiles.h" +#include "gdb-stabs.h" +#include "regcache.h" + +#include "gdb_string.h" +#include +#include +#include +#include +#include +#define malloc bogon_malloc /* Sun claims "char *malloc()" not void * */ +#define free bogon_free /* Sun claims "int free()" not void */ +#define realloc bogon_realloc /* Sun claims "char *realloc()", not void * */ +#include +#undef malloc +#undef free +#undef realloc +#include /* UTek's doesn't #incl this */ +#include +#include "vx-share/ptrace.h" +#include "vx-share/xdr_ptrace.h" +#include "vx-share/xdr_ld.h" +#include "vx-share/xdr_rdb.h" +#include "vx-share/dbgRpcLib.h" + +#include + +/* Maximum number of bytes to transfer in a single + PTRACE_{READ,WRITE}DATA request. */ +#define VX_MEMXFER_MAX 4096 + +extern void vx_read_register (); +extern void vx_write_register (); +extern void symbol_file_command (); +extern enum stop_kind stop_soon; /* for wait_for_inferior */ + +static int net_step (); +static int net_ptrace_clnt_call (); /* Forward decl */ +static enum clnt_stat net_clnt_call (); /* Forward decl */ + +/* Target ops structure for accessing memory and such over the net */ + +static struct target_ops vx_ops; + +/* Target ops structure for accessing VxWorks child processes over the net */ + +static struct target_ops vx_run_ops; + +/* Saved name of target host and called function for "info files". + Both malloc'd. */ + +static char *vx_host; +static char *vx_running; /* Called function */ + +/* Nonzero means target that is being debugged remotely has a floating + point processor. */ + +int target_has_fp; + +/* Default error message when the network is forking up. */ + +static const char rpcerr[] = "network target debugging: rpc error"; + +CLIENT *pClient; /* client used in net debugging */ +static int ptraceSock = RPC_ANYSOCK; + +enum clnt_stat net_clnt_call (); +static void parse_args (); + +static struct timeval rpcTimeout = +{10, 0}; + +static char *skip_white_space (); +static char *find_white_space (); + +/* Tell the VxWorks target system to download a file. + The load addresses of the text, data, and bss segments are + stored in *pTextAddr, *pDataAddr, and *pBssAddr (respectively). + Returns 0 for success, -1 for failure. */ + +static int +net_load (char *filename, CORE_ADDR *pTextAddr, CORE_ADDR *pDataAddr, + CORE_ADDR *pBssAddr) +{ + enum clnt_stat status; + struct ldfile ldstruct; + struct timeval load_timeout; + + memset ((char *) &ldstruct, '\0', sizeof (ldstruct)); + + /* We invoke clnt_call () here directly, instead of through + net_clnt_call (), because we need to set a large timeout value. + The load on the target side can take quite a while, easily + more than 10 seconds. The user can kill this call by typing + CTRL-C if there really is a problem with the load. + + Do not change the tv_sec value without checking -- select() imposes + a limit of 10**8 on it for no good reason that I can see... */ + + load_timeout.tv_sec = 99999999; /* A large number, effectively inf. */ + load_timeout.tv_usec = 0; + + status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile, + &ldstruct, load_timeout); + + if (status == RPC_SUCCESS) + { + if (*ldstruct.name == 0) /* load failed on VxWorks side */ + return -1; + *pTextAddr = ldstruct.txt_addr; + *pDataAddr = ldstruct.data_addr; + *pBssAddr = ldstruct.bss_addr; + return 0; + } + else + return -1; +} + +/* returns 0 if successful, errno if RPC failed or VxWorks complains. */ + +static int +net_break (int addr, u_long procnum) +{ + enum clnt_stat status; + int break_status; + Rptrace ptrace_in; /* XXX This is stupid. It doesn't need to be a ptrace + structure. How about something smaller? */ + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + break_status = 0; + + ptrace_in.addr = addr; + ptrace_in.pid = PIDGET (inferior_ptid); + + status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int, + &break_status); + + if (status != RPC_SUCCESS) + return errno; + + if (break_status == -1) + return ENOMEM; + return break_status; /* probably (FIXME) zero */ +} + +/* returns 0 if successful, errno otherwise */ + +static int +vx_insert_breakpoint (int addr) +{ + return net_break (addr, VX_BREAK_ADD); +} + +/* returns 0 if successful, errno otherwise */ + +static int +vx_remove_breakpoint (int addr) +{ + return net_break (addr, VX_BREAK_DELETE); +} + +/* Start an inferior process and sets inferior_ptid 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. + Returns process id. Errors reported with error(). + On VxWorks, we ignore exec_file. */ + +static void +vx_create_inferior (char *exec_file, char *args, char **env) +{ + enum clnt_stat status; + arg_array passArgs; + TASK_START taskStart; + + memset ((char *) &passArgs, '\0', sizeof (passArgs)); + memset ((char *) &taskStart, '\0', sizeof (taskStart)); + + /* parse arguments, put them in passArgs */ + + parse_args (args, &passArgs); + + if (passArgs.arg_array_len == 0) + error ("You must specify a function name to run, and arguments if any"); + + status = net_clnt_call (PROCESS_START, xdr_arg_array, &passArgs, + xdr_TASK_START, &taskStart); + + if ((status != RPC_SUCCESS) || (taskStart.status == -1)) + error ("Can't create process on remote target machine"); + + /* Save the name of the running function */ + vx_running = savestring (passArgs.arg_array_val[0], + strlen (passArgs.arg_array_val[0])); + + push_target (&vx_run_ops); + inferior_ptid = pid_to_ptid (taskStart.pid); + + /* We will get a trace trap after one instruction. + Insert breakpoints and continue. */ + + init_wait_for_inferior (); + + /* Set up the "saved terminal modes" of the inferior + based on what modes we are starting it with. */ + target_terminal_init (); + + /* Install inferior's terminal modes. */ + target_terminal_inferior (); + + stop_soon = STOP_QUIETLY; + wait_for_inferior (); /* Get the task spawn event */ + stop_soon = NO_STOP_QUIETLY; + + /* insert_step_breakpoint (); FIXME, do we need this? */ + proceed (-1, TARGET_SIGNAL_DEFAULT, 0); +} + +/* Fill ARGSTRUCT in argc/argv form with the arguments from the + argument string ARGSTRING. */ + +static void +parse_args (char *arg_string, arg_array *arg_struct) +{ + int arg_count = 0; /* number of arguments */ + int arg_index = 0; + char *p0; + + memset ((char *) arg_struct, '\0', sizeof (arg_array)); + + /* first count how many arguments there are */ + + p0 = arg_string; + while (*p0 != '\0') + { + if (*(p0 = skip_white_space (p0)) == '\0') + break; + p0 = find_white_space (p0); + arg_count++; + } + + arg_struct->arg_array_len = arg_count; + arg_struct->arg_array_val = (char **) xmalloc ((arg_count + 1) + * sizeof (char *)); + + /* now copy argument strings into arg_struct. */ + + while (*(arg_string = skip_white_space (arg_string))) + { + p0 = find_white_space (arg_string); + arg_struct->arg_array_val[arg_index++] = savestring (arg_string, + p0 - arg_string); + arg_string = p0; + } + + arg_struct->arg_array_val[arg_count] = NULL; +} + +/* Advance a string pointer across whitespace and return a pointer + to the first non-white character. */ + +static char * +skip_white_space (char *p) +{ + while (*p == ' ' || *p == '\t') + p++; + return p; +} + +/* Search for the first unquoted whitespace character in a string. + Returns a pointer to the character, or to the null terminator + if no whitespace is found. */ + +static char * +find_white_space (char *p) +{ + int c; + + while ((c = *p) != ' ' && c != '\t' && c) + { + if (c == '\'' || c == '"') + { + while (*++p != c && *p) + { + if (*p == '\\') + p++; + } + if (!*p) + break; + } + p++; + } + return p; +} + +/* Poll the VxWorks target system for an event related + to the debugged task. + Returns -1 if remote wait failed, task status otherwise. */ + +static int +net_wait (RDB_EVENT *pEvent) +{ + int pid; + enum clnt_stat status; + + memset ((char *) pEvent, '\0', sizeof (RDB_EVENT)); + + pid = PIDGET (inferior_ptid); + status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT, + pEvent); + + /* return (status == RPC_SUCCESS)? pEvent->status: -1; */ + if (status == RPC_SUCCESS) + return ((pEvent->status) ? 1 : 0); + else if (status == RPC_TIMEDOUT) + return (1); + else + return (-1); +} + +/* Suspend the remote task. + Returns -1 if suspend fails on target system, 0 otherwise. */ + +static int +net_quit (void) +{ + int pid; + int quit_status; + enum clnt_stat status; + + quit_status = 0; + + /* don't let rdbTask suspend itself by passing a pid of 0 */ + + if ((pid = PIDGET (inferior_ptid)) == 0) + return -1; + + status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int, + &quit_status); + + return (status == RPC_SUCCESS) ? quit_status : -1; +} + +/* Read a register or registers from the remote system. */ + +void +net_read_registers (char *reg_buf, int len, u_long procnum) +{ + int status; + Rptrace ptrace_in; + Ptrace_return ptrace_out; + C_bytes out_data; + char message[100]; + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); + + /* Initialize RPC input argument structure. */ + + ptrace_in.pid = PIDGET (inferior_ptid); + ptrace_in.info.ttype = NOINFO; + + /* Initialize RPC return value structure. */ + + out_data.bytes = reg_buf; + out_data.len = len; + ptrace_out.info.more_data = (caddr_t) & out_data; + + /* Call RPC; take an error exit if appropriate. */ + + status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out); + if (status) + error (rpcerr); + if (ptrace_out.status == -1) + { + errno = ptrace_out.errno_num; + sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS) + ? "general-purpose" + : "floating-point"); + perror_with_name (message); + } +} + +/* Write register values to a VxWorks target. REG_BUF points to a buffer + containing the raw register values, LEN is the length of REG_BUF in + bytes, and PROCNUM is the RPC procedure number (PTRACE_SETREGS or + PTRACE_SETFPREGS). An error exit is taken if the RPC call fails or + if an error status is returned by the remote debug server. This is + a utility routine used by vx_write_register (). */ + +void +net_write_registers (char *reg_buf, int len, u_long procnum) +{ + int status; + Rptrace ptrace_in; + Ptrace_return ptrace_out; + C_bytes in_data; + char message[100]; + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); + + /* Initialize RPC input argument structure. */ + + in_data.bytes = reg_buf; + in_data.len = len; + + ptrace_in.pid = PIDGET (inferior_ptid); + ptrace_in.info.ttype = DATA; + ptrace_in.info.more_data = (caddr_t) & in_data; + + /* Call RPC; take an error exit if appropriate. */ + + status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out); + if (status) + error (rpcerr); + if (ptrace_out.status == -1) + { + errno = ptrace_out.errno_num; + sprintf (message, "writing %s registers", (procnum == PTRACE_SETREGS) + ? "general-purpose" + : "floating-point"); + perror_with_name (message); + } +} + +/* Prepare to store registers. Since we will store all of them, + read out their current values now. */ + +static void +vx_prepare_to_store (void) +{ + /* Fetch all registers, if any of them are not yet fetched. */ + deprecated_read_register_bytes (0, NULL, DEPRECATED_REGISTER_BYTES); +} + +/* Copy LEN bytes to or from remote inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. WRITE is true if writing to the + inferior. TARGET is unused. + Result is the number of bytes written or read (zero if error). The + protocol allows us to return a negative count, indicating that we can't + handle the current address but can handle one N bytes further, but + vxworks doesn't give us that information. */ + +static int +vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, struct target_ops *target) +{ + int status; + Rptrace ptrace_in; + Ptrace_return ptrace_out; + C_bytes data; + enum ptracereq request; + int nleft, nxfer; + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); + + ptrace_in.pid = PIDGET (inferior_ptid); /* XXX pid unnecessary for READDATA */ + ptrace_in.addr = (int) memaddr; /* Where from */ + ptrace_in.data = len; /* How many bytes */ + + if (write) + { + ptrace_in.info.ttype = DATA; + ptrace_in.info.more_data = (caddr_t) & data; + + data.bytes = (caddr_t) myaddr; /* Where from */ + data.len = len; /* How many bytes (again, for XDR) */ + request = PTRACE_WRITEDATA; + } + else + { + ptrace_out.info.more_data = (caddr_t) & data; + request = PTRACE_READDATA; + } + /* Loop until the entire request has been satisfied, transferring + at most VX_MEMXFER_MAX bytes per iteration. Break from the loop + if an error status is returned by the remote debug server. */ + + nleft = len; + status = 0; + + while (nleft > 0 && status == 0) + { + nxfer = min (nleft, VX_MEMXFER_MAX); + + ptrace_in.addr = (int) memaddr; + ptrace_in.data = nxfer; + data.bytes = (caddr_t) myaddr; + data.len = nxfer; + + /* Request a block from the remote debug server; if RPC fails, + report an error and return to debugger command level. */ + + if (net_ptrace_clnt_call (request, &ptrace_in, &ptrace_out)) + error (rpcerr); + + status = ptrace_out.status; + if (status == 0) + { + memaddr += nxfer; + myaddr += nxfer; + nleft -= nxfer; + } + else + { + /* A target-side error has ocurred. Set errno to the error + code chosen by the target so that a later perror () will + say something meaningful. */ + + errno = ptrace_out.errno_num; + } + } + + /* Return the number of bytes transferred. */ + + return (len - nleft); +} + +static void +vx_files_info (void) +{ + printf_unfiltered ("\tAttached to host `%s'", vx_host); + printf_unfiltered (", which has %sfloating point", target_has_fp ? "" : "no "); + printf_unfiltered (".\n"); +} + +static void +vx_run_files_info (void) +{ + printf_unfiltered ("\tRunning %s VxWorks process %s", + vx_running ? "child" : "attached", + local_hex_string (PIDGET (inferior_ptid))); + if (vx_running) + printf_unfiltered (", function `%s'", vx_running); + printf_unfiltered (".\n"); +} + +static void +vx_resume (ptid_t ptid, int step, enum target_signal siggnal) +{ + int status; + Rptrace ptrace_in; + Ptrace_return ptrace_out; + CORE_ADDR cont_addr; + + if (ptid_equal (ptid, minus_one_ptid)) + ptid = inferior_ptid; + + if (siggnal != 0 && siggnal != stop_signal) + error ("Cannot send signals to VxWorks processes"); + + /* Set CONT_ADDR to the address at which we are continuing, + or to 1 if we are continuing from where the program stopped. + This conforms to traditional ptrace () usage, but at the same + time has special meaning for the VxWorks remote debug server. + If the address is not 1, the server knows that the target + program is jumping to a new address, which requires special + handling if there is a breakpoint at the new address. */ + + cont_addr = read_register (PC_REGNUM); + if (cont_addr == stop_pc) + cont_addr = 1; + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); + + ptrace_in.pid = PIDGET (ptid); + ptrace_in.addr = cont_addr; /* Target side insists on this, or it panics. */ + + if (step) + status = net_step (); + else + status = net_ptrace_clnt_call (PTRACE_CONT, &ptrace_in, &ptrace_out); + + if (status) + error (rpcerr); + if (ptrace_out.status == -1) + { + errno = ptrace_out.errno_num; + perror_with_name ("Resuming remote process"); + } +} + +static void +vx_mourn_inferior (void) +{ + pop_target (); /* Pop back to no-child state */ + generic_mourn_inferior (); +} + + +static void vx_add_symbols (char *, int, CORE_ADDR, CORE_ADDR, CORE_ADDR); + +struct find_sect_args + { + CORE_ADDR text_start; + CORE_ADDR data_start; + CORE_ADDR bss_start; + }; + +static void find_sect (bfd *, asection *, void *); + +static void +find_sect (bfd *abfd, asection *sect, void *obj) +{ + struct find_sect_args *args = (struct find_sect_args *) obj; + + if (bfd_get_section_flags (abfd, sect) & (SEC_CODE & SEC_READONLY)) + args->text_start = bfd_get_section_vma (abfd, sect); + else if (bfd_get_section_flags (abfd, sect) & SEC_ALLOC) + { + if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) + { + /* Exclude .ctor and .dtor sections which have SEC_CODE set but not + SEC_DATA. */ + if (bfd_get_section_flags (abfd, sect) & SEC_DATA) + args->data_start = bfd_get_section_vma (abfd, sect); + } + else + args->bss_start = bfd_get_section_vma (abfd, sect); + } +} + +static void +vx_add_symbols (char *name, int from_tty, CORE_ADDR text_addr, + CORE_ADDR data_addr, CORE_ADDR bss_addr) +{ + struct section_offsets *offs; + struct objfile *objfile; + struct find_sect_args ss; + + /* It might be nice to suppress the breakpoint_re_set which happens here + because we are going to do one again after the objfile_relocate. */ + objfile = symbol_file_add (name, from_tty, NULL, 0, 0); + + /* This is a (slightly cheesy) way of superceding the old symbols. A less + cheesy way would be to find the objfile with the same name and + free_objfile it. */ + objfile_to_front (objfile); + + offs = + (struct section_offsets *) + alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + memcpy (offs, objfile->section_offsets, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + + ss.text_start = 0; + ss.data_start = 0; + ss.bss_start = 0; + bfd_map_over_sections (objfile->obfd, find_sect, &ss); + + /* Both COFF and b.out frontends use these SECT_OFF_* values. */ + offs->offsets[SECT_OFF_TEXT (objfile)] = text_addr - ss.text_start; + offs->offsets[SECT_OFF_DATA (objfile)] = data_addr - ss.data_start; + offs->offsets[SECT_OFF_BSS (objfile)] = bss_addr - ss.bss_start; + objfile_relocate (objfile, offs); +} + +/* This function allows the addition of incrementally linked object files. */ + +static void +vx_load_command (char *arg_string, int from_tty) +{ + CORE_ADDR text_addr; + CORE_ADDR data_addr; + CORE_ADDR bss_addr; + + if (arg_string == 0) + error ("The load command takes a file name"); + + arg_string = tilde_expand (arg_string); + make_cleanup (xfree, arg_string); + + dont_repeat (); + + /* Refuse to load the module if a debugged task is running. Doing so + can have a number of unpleasant consequences to the running task. */ + + if (PIDGET (inferior_ptid) != 0 && target_has_execution) + { + if (query ("You may not load a module while the target task is running.\n\ +Kill the target task? ")) + target_kill (); + else + error ("Load canceled."); + } + + QUIT; + immediate_quit++; + if (net_load (arg_string, &text_addr, &data_addr, &bss_addr) == -1) + error ("Load failed on target machine"); + immediate_quit--; + + vx_add_symbols (arg_string, from_tty, text_addr, data_addr, bss_addr); + + /* Getting new symbols may change our opinion about what is + frameless. */ + reinit_frame_cache (); +} + +/* Single step the target program at the source or machine level. + Takes an error exit if rpc fails. + Returns -1 if remote single-step operation fails, else 0. */ + +static int +net_step (void) +{ + enum clnt_stat status; + int step_status; + SOURCE_STEP source_step; + + source_step.taskId = PIDGET (inferior_ptid); + + if (step_range_end) + { + source_step.startAddr = step_range_start; + source_step.endAddr = step_range_end; + } + else + { + source_step.startAddr = 0; + source_step.endAddr = 0; + } + + status = net_clnt_call (VX_SOURCE_STEP, xdr_SOURCE_STEP, &source_step, + xdr_int, &step_status); + + if (status == RPC_SUCCESS) + return step_status; + else + error (rpcerr); +} + +/* Emulate ptrace using RPC calls to the VxWorks target system. + Returns nonzero (-1) if RPC status to VxWorks is bad, 0 otherwise. */ + +static int +net_ptrace_clnt_call (enum ptracereq request, Rptrace *pPtraceIn, + Ptrace_return *pPtraceOut) +{ + enum clnt_stat status; + + status = net_clnt_call (request, xdr_rptrace, pPtraceIn, xdr_ptrace_return, + pPtraceOut); + + if (status != RPC_SUCCESS) + return -1; + + return 0; +} + +/* Query the target for the name of the file from which VxWorks was + booted. pBootFile is the address of a pointer to the buffer to + receive the file name; if the pointer pointed to by pBootFile is + NULL, memory for the buffer will be allocated by XDR. + Returns -1 if rpc failed, 0 otherwise. */ + +static int +net_get_boot_file (char **pBootFile) +{ + enum clnt_stat status; + + status = net_clnt_call (VX_BOOT_FILE_INQ, xdr_void, (char *) 0, + xdr_wrapstring, pBootFile); + return (status == RPC_SUCCESS) ? 0 : -1; +} + +/* Fetch a list of loaded object modules from the VxWorks target + and store in PLOADTABLE. + Returns -1 if rpc failed, 0 otherwise + There's no way to check if the returned loadTable is correct. + VxWorks doesn't check it. */ + +static int +net_get_symbols (ldtabl *pLoadTable) +{ + enum clnt_stat status; + + memset ((char *) pLoadTable, '\0', sizeof (struct ldtabl)); + + status = net_clnt_call (VX_STATE_INQ, xdr_void, 0, xdr_ldtabl, pLoadTable); + return (status == RPC_SUCCESS) ? 0 : -1; +} + +/* Look up a symbol in the VxWorks target's symbol table. + Returns status of symbol read on target side (0=success, -1=fail) + Returns -1 and complain()s if rpc fails. */ + +static int +vx_lookup_symbol (char *name, /* symbol name */ + CORE_ADDR *pAddr) +{ + enum clnt_stat status; + SYMBOL_ADDR symbolAddr; + + *pAddr = 0; + memset ((char *) &symbolAddr, '\0', sizeof (symbolAddr)); + + status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name, + xdr_SYMBOL_ADDR, &symbolAddr); + if (status != RPC_SUCCESS) + { + complaint (&symfile_complaints, "Lost contact with VxWorks target"); + return -1; + } + + *pAddr = symbolAddr.addr; + return symbolAddr.status; +} + +/* Check to see if the VxWorks target has a floating point coprocessor. + Returns 1 if target has floating point processor, 0 otherwise. + Calls error() if rpc fails. */ + +static int +net_check_for_fp (void) +{ + enum clnt_stat status; + bool_t fp = 0; /* true if fp processor is present on target board */ + + status = net_clnt_call (VX_FP_INQUIRE, xdr_void, 0, xdr_bool, &fp); + if (status != RPC_SUCCESS) + error (rpcerr); + + return (int) fp; +} + +/* Establish an RPC connection with the VxWorks target system. + Calls error () if unable to establish connection. */ + +static void +net_connect (char *host) +{ + struct sockaddr_in destAddr; + struct hostent *destHost; + unsigned long addr; + + /* Get the internet address for the given host. Allow a numeric + IP address or a hostname. */ + + addr = inet_addr (host); + if (addr == -1) + { + destHost = (struct hostent *) gethostbyname (host); + if (destHost == NULL) + /* FIXME: Probably should include hostname here in quotes. + For example if the user types "target vxworks vx960 " it should + say "Invalid host `vx960 '." not just "Invalid hostname". */ + error ("Invalid hostname. Couldn't find remote host address."); + addr = *(unsigned long *) destHost->h_addr; + } + + memset (&destAddr, '\0', sizeof (destAddr)); + + destAddr.sin_addr.s_addr = addr; + destAddr.sin_family = AF_INET; + destAddr.sin_port = 0; /* set to actual port that remote + ptrace is listening on. */ + + /* Create a tcp client transport on which to issue + calls to the remote ptrace server. */ + + ptraceSock = RPC_ANYSOCK; + pClient = clnttcp_create (&destAddr, RDBPROG, RDBVERS, &ptraceSock, 0, 0); + /* FIXME, here is where we deal with different version numbers of the + proto */ + + if (pClient == NULL) + { + clnt_pcreateerror ("\tnet_connect"); + error ("Couldn't connect to remote target."); + } +} + +/* Sleep for the specified number of milliseconds + * (assumed to be less than 1000). + * If select () is interrupted, returns immediately; + * takes an error exit if select () fails for some other reason. + */ + +static void +sleep_ms (long ms) +{ + struct timeval select_timeout; + int status; + + select_timeout.tv_sec = 0; + select_timeout.tv_usec = ms * 1000; + + status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, + &select_timeout); + + if (status < 0 && errno != EINTR) + perror_with_name ("select"); +} + +static ptid_t +vx_wait (ptid_t ptid_to_wait_for, struct target_waitstatus *status) +{ + int pid; + RDB_EVENT rdbEvent; + int quit_failed; + + do + { + /* If CTRL-C is hit during this loop, + suspend the inferior process. */ + + quit_failed = 0; + if (quit_flag) + { + quit_failed = (net_quit () == -1); + quit_flag = 0; + } + + /* If a net_quit () or net_wait () call has failed, + allow the user to break the connection with the target. + We can't simply error () out of this loop, since the + data structures representing the state of the inferior + are in an inconsistent state. */ + + if (quit_failed || net_wait (&rdbEvent) == -1) + { + terminal_ours (); + if (query ("Can't %s. Disconnect from target system? ", + (quit_failed) ? "suspend remote task" + : "get status of remote task")) + { + target_mourn_inferior (); + error ("Use the \"target\" command to reconnect."); + } + else + { + terminal_inferior (); + continue; + } + } + + pid = rdbEvent.taskId; + if (pid == 0) + { + sleep_ms (200); /* FIXME Don't kill the network too badly */ + } + else if (pid != PIDGET (inferior_ptid)) + internal_error (__FILE__, __LINE__, + "Bad pid for debugged task: %s\n", + local_hex_string ((unsigned long) pid)); + } + while (pid == 0); + + /* The mostly likely kind. */ + status->kind = TARGET_WAITKIND_STOPPED; + + switch (rdbEvent.eventType) + { + case EVENT_EXIT: + status->kind = TARGET_WAITKIND_EXITED; + /* FIXME is it possible to distinguish between a + normal vs abnormal exit in VxWorks? */ + status->value.integer = 0; + break; + + case EVENT_START: + /* Task was just started. */ + status->value.sig = TARGET_SIGNAL_TRAP; + break; + + case EVENT_STOP: + status->value.sig = TARGET_SIGNAL_TRAP; + /* XXX was it stopped by a signal? act accordingly */ + break; + + case EVENT_BREAK: /* Breakpoint was hit. */ + status->value.sig = TARGET_SIGNAL_TRAP; + break; + + case EVENT_SUSPEND: /* Task was suspended, probably by ^C. */ + status->value.sig = TARGET_SIGNAL_INT; + break; + + case EVENT_BUS_ERR: /* Task made evil nasty reference. */ + status->value.sig = TARGET_SIGNAL_BUS; + break; + + case EVENT_ZERO_DIV: /* Division by zero */ + status->value.sig = TARGET_SIGNAL_FPE; + break; + + case EVENT_SIGNAL: +#ifdef I80960 + status->value.sig = i960_fault_to_signal (rdbEvent.sigType); +#else + /* Back in the old days, before enum target_signal, this code used + to add NSIG to the signal number and claim that PRINT_RANDOM_SIGNAL + would take care of it. But PRINT_RANDOM_SIGNAL has never been + defined except on the i960, so I don't really know what we are + supposed to do on other architectures. */ + status->value.sig = TARGET_SIGNAL_UNKNOWN; +#endif + break; + } /* switch */ + return pid_to_ptid (pid); +} + +static int +symbol_stub (char *arg) +{ + symbol_file_add_main (arg, 0); + return 1; +} + +static int +add_symbol_stub (char *arg) +{ + struct ldfile *pLoadFile = (struct ldfile *) arg; + + printf_unfiltered ("\t%s: ", pLoadFile->name); + vx_add_symbols (pLoadFile->name, 0, pLoadFile->txt_addr, + pLoadFile->data_addr, pLoadFile->bss_addr); + printf_unfiltered ("ok\n"); + return 1; +} +/* Target command for VxWorks target systems. + + Used in vxgdb. Takes the name of a remote target machine + running vxWorks and connects to it to initialize remote network + debugging. */ + +static void +vx_open (char *args, int from_tty) +{ + extern int close (); + char *bootFile; + extern char *source_path; + struct ldtabl loadTable; + struct ldfile *pLoadFile; + int i; + extern CLIENT *pClient; + int symbols_added = 0; + + if (!args) + error_no_arg ("target machine name"); + + target_preopen (from_tty); + + unpush_target (&vx_ops); + printf_unfiltered ("Attaching remote machine across net...\n"); + gdb_flush (gdb_stdout); + + /* Allow the user to kill the connect attempt by typing ^C. + Wait until the call to target_has_fp () completes before + disallowing an immediate quit, since even if net_connect () + is successful, the remote debug server might be hung. */ + + immediate_quit++; + + net_connect (args); + target_has_fp = net_check_for_fp (); + printf_filtered ("Connected to %s.\n", args); + + immediate_quit--; + + push_target (&vx_ops); + + /* Save a copy of the target host's name. */ + vx_host = savestring (args, strlen (args)); + + /* Find out the name of the file from which the target was booted + and load its symbol table. */ + + printf_filtered ("Looking in Unix path for all loaded modules:\n"); + bootFile = NULL; + if (!net_get_boot_file (&bootFile)) + { + if (*bootFile) + { + printf_filtered ("\t%s: ", bootFile); + /* This assumes that the kernel is never relocated. Hope that is an + accurate assumption. */ + if (catch_errors + (symbol_stub, + bootFile, + "Error while reading symbols from boot file:\n", + RETURN_MASK_ALL)) + puts_filtered ("ok\n"); + } + else if (from_tty) + printf_unfiltered ("VxWorks kernel symbols not loaded.\n"); + } + else + error ("Can't retrieve boot file name from target machine."); + + clnt_freeres (pClient, xdr_wrapstring, &bootFile); + + if (net_get_symbols (&loadTable) != 0) + error ("Can't read loaded modules from target machine"); + + i = 0 - 1; + while (++i < loadTable.tbl_size) + { + QUIT; /* FIXME, avoids clnt_freeres below: mem leak */ + pLoadFile = &loadTable.tbl_ent[i]; +#ifdef WRS_ORIG + { + int desc; + struct cleanup *old_chain; + char *fullname = NULL; + + desc = openp (source_path, 0, pLoadFile->name, O_RDONLY, 0, &fullname); + if (desc < 0) + perror_with_name (pLoadFile->name); + old_chain = make_cleanup (close, desc); + add_file_at_addr (fullname, desc, pLoadFile->txt_addr, pLoadFile->data_addr, + pLoadFile->bss_addr); + do_cleanups (old_chain); + } +#else + /* FIXME: Is there something better to search than the PATH? (probably + not the source path, since source might be in different directories + than objects. */ + + if (catch_errors (add_symbol_stub, (char *) pLoadFile, (char *) 0, + RETURN_MASK_ALL)) + symbols_added = 1; +#endif + } + printf_filtered ("Done.\n"); + + clnt_freeres (pClient, xdr_ldtabl, &loadTable); + + /* Getting new symbols may change our opinion about what is + frameless. */ + if (symbols_added) + reinit_frame_cache (); +} + +/* Takes a task started up outside of gdb and ``attaches'' to it. + This stops it cold in its tracks and allows us to start tracing it. */ + +static void +vx_attach (char *args, int from_tty) +{ + unsigned long pid; + char *cptr = 0; + Rptrace ptrace_in; + Ptrace_return ptrace_out; + int status; + + if (!args) + error_no_arg ("process-id to attach"); + + pid = strtoul (args, &cptr, 0); + if ((cptr == args) || (*cptr != '\0')) + error ("Invalid process-id -- give a single number in decimal or 0xhex"); + + if (from_tty) + printf_unfiltered ("Attaching pid %s.\n", + local_hex_string ((unsigned long) pid)); + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); + ptrace_in.pid = pid; + + status = net_ptrace_clnt_call (PTRACE_ATTACH, &ptrace_in, &ptrace_out); + if (status == -1) + error (rpcerr); + if (ptrace_out.status == -1) + { + errno = ptrace_out.errno_num; + perror_with_name ("Attaching remote process"); + } + + /* It worked... */ + + inferior_ptid = pid_to_ptid (pid); + push_target (&vx_run_ops); + + if (vx_running) + xfree (vx_running); + vx_running = 0; +} + +/* detach_command -- + takes a program previously attached to and detaches it. + The program resumes execution and will no longer stop + on signals, etc. We better not have left any breakpoints + in the program or it'll die when it hits one. For this + to work, it may be necessary for the process to have been + previously attached. It *might* work if the program was + started via the normal ptrace (PTRACE_TRACEME). */ + +static void +vx_detach (char *args, int from_tty) +{ + Rptrace ptrace_in; + Ptrace_return ptrace_out; + int signal = 0; + int status; + + if (args) + error ("Argument given to VxWorks \"detach\"."); + + if (from_tty) + printf_unfiltered ("Detaching pid %s.\n", + local_hex_string ( + (unsigned long) PIDGET (inferior_ptid))); + + if (args) /* FIXME, should be possible to leave suspended */ + signal = atoi (args); + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); + ptrace_in.pid = PIDGET (inferior_ptid); + + status = net_ptrace_clnt_call (PTRACE_DETACH, &ptrace_in, &ptrace_out); + if (status == -1) + error (rpcerr); + if (ptrace_out.status == -1) + { + errno = ptrace_out.errno_num; + perror_with_name ("Detaching VxWorks process"); + } + + inferior_ptid = null_ptid; + pop_target (); /* go back to non-executing VxWorks connection */ +} + +/* vx_kill -- takes a running task and wipes it out. */ + +static void +vx_kill (void) +{ + Rptrace ptrace_in; + Ptrace_return ptrace_out; + int status; + + printf_unfiltered ("Killing pid %s.\n", local_hex_string ((unsigned long) PIDGET (inferior_ptid))); + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out)); + ptrace_in.pid = PIDGET (inferior_ptid); + + status = net_ptrace_clnt_call (PTRACE_KILL, &ptrace_in, &ptrace_out); + if (status == -1) + warning (rpcerr); + else if (ptrace_out.status == -1) + { + errno = ptrace_out.errno_num; + perror_with_name ("Killing VxWorks process"); + } + + /* If it gives good status, the process is *gone*, no events remain. + If the kill failed, assume the process is gone anyhow. */ + inferior_ptid = null_ptid; + pop_target (); /* go back to non-executing VxWorks connection */ +} + +/* Clean up from the VxWorks process target as it goes away. */ + +static void +vx_proc_close (int quitting) +{ + inferior_ptid = null_ptid; /* No longer have a process. */ + if (vx_running) + xfree (vx_running); + vx_running = 0; +} + +/* Make an RPC call to the VxWorks target. + Returns RPC status. */ + +static enum clnt_stat +net_clnt_call (enum ptracereq procNum, xdrproc_t inProc, char *in, + xdrproc_t outProc, char *out) +{ + enum clnt_stat status; + + status = clnt_call (pClient, procNum, inProc, in, outProc, out, rpcTimeout); + + if (status != RPC_SUCCESS) + clnt_perrno (status); + + return status; +} + +/* Clean up before losing control. */ + +static void +vx_close (int quitting) +{ + if (pClient) + clnt_destroy (pClient); /* The net connection */ + pClient = 0; + + if (vx_host) + xfree (vx_host); /* The hostname */ + vx_host = 0; +} + +/* A vxprocess target should be started via "run" not "target". */ +static void +vx_proc_open (char *name, int from_tty) +{ + error ("Use the \"run\" command to start a VxWorks process."); +} + +static void +init_vx_ops (void) +{ + vx_ops.to_shortname = "vxworks"; + vx_ops.to_longname = "VxWorks target memory via RPC over TCP/IP"; + vx_ops.to_doc = "Use VxWorks target memory. \n\ +Specify the name of the machine to connect to."; + vx_ops.to_open = vx_open; + vx_ops.to_close = vx_close; + vx_ops.to_attach = vx_attach; + vx_ops.to_xfer_memory = vx_xfer_memory; + vx_ops.to_files_info = vx_files_info; + vx_ops.to_load = vx_load_command; + vx_ops.to_lookup_symbol = vx_lookup_symbol; + vx_ops.to_create_inferior = vx_create_inferior; + vx_ops.to_stratum = core_stratum; + vx_ops.to_has_all_memory = 1; + vx_ops.to_has_memory = 1; + vx_ops.to_magic = OPS_MAGIC; /* Always the last thing */ +}; + +static void +init_vx_run_ops (void) +{ + vx_run_ops.to_shortname = "vxprocess"; + vx_run_ops.to_longname = "VxWorks process"; + vx_run_ops.to_doc = "VxWorks process; started by the \"run\" command."; + vx_run_ops.to_open = vx_proc_open; + vx_run_ops.to_close = vx_proc_close; + vx_run_ops.to_detach = vx_detach; + vx_run_ops.to_resume = vx_resume; + vx_run_ops.to_wait = vx_wait; + vx_run_ops.to_fetch_registers = vx_read_register; + vx_run_ops.to_store_registers = vx_write_register; + vx_run_ops.to_prepare_to_store = vx_prepare_to_store; + vx_run_ops.to_xfer_memory = vx_xfer_memory; + vx_run_ops.to_files_info = vx_run_files_info; + vx_run_ops.to_insert_breakpoint = vx_insert_breakpoint; + vx_run_ops.to_remove_breakpoint = vx_remove_breakpoint; + vx_run_ops.to_kill = vx_kill; + vx_run_ops.to_load = vx_load_command; + vx_run_ops.to_lookup_symbol = vx_lookup_symbol; + vx_run_ops.to_mourn_inferior = vx_mourn_inferior; + vx_run_ops.to_stratum = process_stratum; + vx_run_ops.to_has_memory = 1; + vx_run_ops.to_has_stack = 1; + vx_run_ops.to_has_registers = 1; + vx_run_ops.to_has_execution = 1; + vx_run_ops.to_magic = OPS_MAGIC; +} + +void +_initialize_vx (void) +{ + init_vx_ops (); + add_target (&vx_ops); + init_vx_run_ops (); + add_target (&vx_run_ops); + + add_show_from_set + (add_set_cmd ("vxworks-timeout", class_support, var_uinteger, + (char *) &rpcTimeout.tv_sec, + "Set seconds to wait for rpc calls to return.\n\ +Set the number of seconds to wait for rpc calls to return.", &setlist), + &showlist); +} diff --git a/contrib/gdb/gdb/remote-vx68.c b/contrib/gdb/gdb/remote-vx68.c new file mode 100644 index 00000000000..8cdac6f0278 --- /dev/null +++ b/contrib/gdb/gdb/remote-vx68.c @@ -0,0 +1,160 @@ +/* 68k-dependent portions of the RPC protocol + used with a VxWorks target + + Contributed by Wind River Systems. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include "defs.h" + +#include "vx-share/regPacket.h" +#include "frame.h" +#include "inferior.h" +#include "target.h" +#include "gdbcore.h" +#include "command.h" +#include "symtab.h" +#include "symfile.h" +#include "regcache.h" + +#include "gdb_string.h" +#include +#include +#include +#include +#include + +#ifdef _AIX /* IBM claims "void *malloc()" not char * */ +#define malloc bogon_malloc +#endif + +#include + +#ifdef _AIX +#undef malloc +#endif + +#include /* UTek's doesn't #incl this */ +#include +#include "vx-share/ptrace.h" +#include "vx-share/xdr_ptrace.h" +#include "vx-share/xdr_ld.h" +#include "vx-share/xdr_rdb.h" +#include "vx-share/dbgRpcLib.h" + +/* get rid of value.h if possible */ +#include +#include + +/* Flag set if target has fpu */ + +extern int target_has_fp; + +/* Generic register read/write routines in remote-vx.c. */ + +extern void net_read_registers (); +extern void net_write_registers (); + +/* Read a register or registers from the VxWorks target. + REGNO is the register to read, or -1 for all; currently, + it is ignored. FIXME look at regno to improve efficiency. */ + +void +vx_read_register (int regno) +{ + char mc68k_greg_packet[MC68K_GREG_PLEN]; + char mc68k_fpreg_packet[MC68K_FPREG_PLEN]; + + /* Get general-purpose registers. */ + + net_read_registers (mc68k_greg_packet, MC68K_GREG_PLEN, PTRACE_GETREGS); + + bcopy (&mc68k_greg_packet[MC68K_R_D0], deprecated_registers, + 16 * MC68K_GREG_SIZE); + bcopy (&mc68k_greg_packet[MC68K_R_SR], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)], + MC68K_GREG_SIZE); + bcopy (&mc68k_greg_packet[MC68K_R_PC], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)], + MC68K_GREG_SIZE); + + /* Get floating-point registers, if the target system has them. + Otherwise, zero them. */ + + if (target_has_fp) + { + net_read_registers (mc68k_fpreg_packet, MC68K_FPREG_PLEN, + PTRACE_GETFPREGS); + + bcopy (&mc68k_fpreg_packet[MC68K_R_FP0], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + MC68K_FPREG_SIZE * 8); + bcopy (&mc68k_fpreg_packet[MC68K_R_FPCR], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], + MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8)); + } + else + { + memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + 0, MC68K_FPREG_SIZE * 8); + memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], + 0, MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8)); + } + + /* Mark the register cache valid. */ + + deprecated_registers_fetched (); +} + +/* Store a register or registers into the VxWorks target. + REGNO is the register to store, or -1 for all; currently, + it is ignored. FIXME look at regno to improve efficiency. */ + +void +vx_write_register (int regno) +{ + char mc68k_greg_packet[MC68K_GREG_PLEN]; + char mc68k_fpreg_packet[MC68K_FPREG_PLEN]; + + /* Store general-purpose registers. */ + + bcopy (deprecated_registers, &mc68k_greg_packet[MC68K_R_D0], + 16 * MC68K_GREG_SIZE); + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)], + &mc68k_greg_packet[MC68K_R_SR], MC68K_GREG_SIZE); + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)], + &mc68k_greg_packet[MC68K_R_PC], MC68K_GREG_SIZE); + + net_write_registers (mc68k_greg_packet, MC68K_GREG_PLEN, PTRACE_SETREGS); + + /* Store floating point registers if the target has them. */ + + if (target_has_fp) + { + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + &mc68k_fpreg_packet[MC68K_R_FP0], + MC68K_FPREG_SIZE * 8); + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], + &mc68k_fpreg_packet[MC68K_R_FPCR], + MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8)); + + net_write_registers (mc68k_fpreg_packet, MC68K_FPREG_PLEN, + PTRACE_SETFPREGS); + } +} diff --git a/contrib/gdb/gdb/remote-vxmips.c b/contrib/gdb/gdb/remote-vxmips.c new file mode 100644 index 00000000000..55ba49b98ca --- /dev/null +++ b/contrib/gdb/gdb/remote-vxmips.c @@ -0,0 +1,201 @@ +/* MIPS-dependent portions of the RPC protocol + used with a VxWorks target + + Contributed by Wind River Systems. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include "defs.h" + +#include "vx-share/regPacket.h" +#include "frame.h" +#include "inferior.h" +#include "target.h" +#include "gdbcore.h" +#include "command.h" +#include "symtab.h" +#include "symfile.h" +#include "regcache.h" + +#include "gdb_string.h" +#include +#include +#include +#include +#include +#include +#include /* UTek's doesn't #incl this */ +#include +#include "vx-share/ptrace.h" +#include "vx-share/xdr_ptrace.h" +#include "vx-share/xdr_ld.h" +#include "vx-share/xdr_rdb.h" +#include "vx-share/dbgRpcLib.h" + +/* get rid of value.h if possible */ +#include +#include + +/* Flag set if target has fpu */ + +extern int target_has_fp; + +/* Generic register read/write routines in remote-vx.c. */ + +extern void net_read_registers (); +extern void net_write_registers (); + +/* Read a register or registers from the VxWorks target. + REGNO is the register to read, or -1 for all; currently, + it is ignored. FIXME look at regno to improve efficiency. */ + +void +vx_read_register (int regno) +{ + char mips_greg_packet[MIPS_GREG_PLEN]; + char mips_fpreg_packet[MIPS_FPREG_PLEN]; + + /* Get general-purpose registers. */ + + net_read_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_GETREGS); + + /* this code copies the registers obtained by RPC + stored in a structure(s) like this : + + Register(s) Offset(s) + gp 0-31 0x00 + hi 0x80 + lo 0x84 + sr 0x88 + pc 0x8c + + into a stucture like this: + + 0x00 GP 0-31 + 0x80 SR + 0x84 LO + 0x88 HI + 0x8C BAD --- Not available currently + 0x90 CAUSE --- Not available currently + 0x94 PC + 0x98 FP 0-31 + 0x118 FCSR + 0x11C FIR --- Not available currently + 0x120 FP --- Not available currently + + structure is 0x124 (292) bytes in length */ + + /* Copy the general registers. */ + + bcopy (&mips_greg_packet[MIPS_R_GP0], &deprecated_registers[0], + 32 * MIPS_GREG_SIZE); + + /* Copy SR, LO, HI, and PC. */ + + bcopy (&mips_greg_packet[MIPS_R_SR], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)], MIPS_GREG_SIZE); + bcopy (&mips_greg_packet[MIPS_R_LO], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->lo)], MIPS_GREG_SIZE); + bcopy (&mips_greg_packet[MIPS_R_HI], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->hi)], MIPS_GREG_SIZE); + bcopy (&mips_greg_packet[MIPS_R_PC], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->pc)], MIPS_GREG_SIZE); + + /* If the target has floating point registers, fetch them. + Otherwise, zero the floating point register values in + registers[] for good measure, even though we might not + need to. */ + + if (target_has_fp) + { + net_read_registers (mips_fpreg_packet, MIPS_FPREG_PLEN, + PTRACE_GETFPREGS); + + /* Copy the floating point registers. */ + + bcopy (&mips_fpreg_packet[MIPS_R_FP0], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) * 32); + + /* Copy the floating point control/status register (fpcsr). */ + + bcopy (&mips_fpreg_packet[MIPS_R_FPCSR], + &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->fp_control_status)], + DEPRECATED_REGISTER_RAW_SIZE (mips_regnum (current_gdbarch)->fp_control_status)); + } + else + { + memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + 0, DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) * 32); + memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->fp_control_status)], + 0, DEPRECATED_REGISTER_RAW_SIZE (mips_regnum (current_gdbarch)->fp_control_status)); + } + + /* Mark the register cache valid. */ + + deprecated_registers_fetched (); +} + +/* Store a register or registers into the VxWorks target. + REGNO is the register to store, or -1 for all; currently, + it is ignored. FIXME look at regno to improve efficiency. */ + +vx_write_register (int regno) +{ + char mips_greg_packet[MIPS_GREG_PLEN]; + char mips_fpreg_packet[MIPS_FPREG_PLEN]; + + /* Store general registers. */ + + bcopy (&deprecated_registers[0], &mips_greg_packet[MIPS_R_GP0], + 32 * MIPS_GREG_SIZE); + + /* Copy SR, LO, HI, and PC. */ + + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)], + &mips_greg_packet[MIPS_R_SR], MIPS_GREG_SIZE); + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->lo)], + &mips_greg_packet[MIPS_R_LO], MIPS_GREG_SIZE); + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->hi)], + &mips_greg_packet[MIPS_R_HI], MIPS_GREG_SIZE); + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->pc)], + &mips_greg_packet[MIPS_R_PC], MIPS_GREG_SIZE); + + net_write_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_SETREGS); + + /* Store floating point registers if the target has them. */ + + if (target_has_fp) + { + /* Copy the floating point data registers. */ + + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + &mips_fpreg_packet[MIPS_R_FP0], + DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM) * 32); + + /* Copy the floating point control/status register (fpcsr). */ + + bcopy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->fp_control_status)], + &mips_fpreg_packet[MIPS_R_FPCSR], + DEPRECATED_REGISTER_RAW_SIZE (mips_regnum (current_gdbarch)->fp_control_status)); + + net_write_registers (mips_fpreg_packet, MIPS_FPREG_PLEN, + PTRACE_SETFPREGS); + } +} diff --git a/contrib/gdb/gdb/remote-vxsparc.c b/contrib/gdb/gdb/remote-vxsparc.c new file mode 100644 index 00000000000..118e5173e13 --- /dev/null +++ b/contrib/gdb/gdb/remote-vxsparc.c @@ -0,0 +1,128 @@ +/* SPARC-specific portions of the RPC protocol for VxWorks. + + Contributed by Wind River Systems. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "regcache.h" + +#include "gdb_string.h" + +#include "sparc-tdep.h" + +#include "vx-share/ptrace.h" +#include "vx-share/regPacket.h" + +#define SPARC_R_G1 (SPARC_R_G0 + SPARC_GREG_SIZE) + +const struct sparc_gregset vxsparc_gregset = +{ + SPARC_R_PSR, /* %psr */ + SPARC_R_PC, /* %pc */ + SPARC_R_NPC, /* %npc */ + SPARC_R_Y, /* %y */ + SPARC_R_WIM, /* %wim */ + SPARC_R_TBR, /* %tbr */ + SPARC_R_G1, /* %g1 */ + SPARC_R_I0 /* %l0 */ +}; + +/* Flag set if target has an FPU. */ + +extern int target_has_fp; + +/* Generic register read/write routines in remote-vx.c. */ + +extern void net_read_registers (); +extern void net_write_registers (); + +/* Read a register or registers from the VxWorks target. REGNUM is + the register to read, or -1 for all; currently, it is ignored. + FIXME: Look at REGNUM to improve efficiency. */ + +void +vx_read_register (int regnum) +{ + struct regcache *regcache = current_regcache; + char gregs[SPARC_GREG_PLEN]; + char fpregs[SPARC_FPREG_PLEN]; + CORE_ADDR sp; + + /* Get the general-purpose registers. */ + net_read_registers (gregs, SPARC_GREG_PLEN, PTRACE_GETREGS); + sparc32_supply_gregset (&vxsparc_gregset, regcache, -1, gregs); + + /* If the target has floating-point registers, fetch them. + Otherwise, zero the floating-point register values in GDB's + register cache for good measure, even though we might not need + to. */ + if (target_has_fp) + net_read_registers (fpregs, SPARC_FPREG_PLEN, PTRACE_GETFPREGS); + else + memset (fpregs, 0, SPARC_FPREG_PLEN); + sparc32_supply_fpregset (regcache, -1, fpregs); +} + +/* Store a register or registers into the VxWorks target. REGNUM is + the register to store, or -1 for all; currently, it is ignored. + FIXME: Look at REGNUM to improve efficiency. */ + +void +vx_write_register (int regnum) +{ + struct regcache *regcache = current_regcache; + char gregs[SPARC_GREG_PLEN]; + char fpregs[SPARC_FPREG_PLEN]; + int gregs_p = 1; + int fpregs_p = 1; + CORE_ADDR sp; + + if (regnum != -1) + { + if ((SPARC_G0_REGNUM <= regnum && regnum <= SPARC_I7_REGNUM) + || (SPARC32_Y_REGNUM <= regnum && regnum <= SPARC32_NPC_REGNUM)) + fpregs_p = 0; + else + gregs_p = 0; + } + + /* Store the general-purpose registers. */ + if (gregs_p) + { + sparc32_collect_gregset (&vxsparc_gregset, regcache, -1, gregs); + net_write_registers (gregs, SPARC_GREG_PLEN, PTRACE_SETREGS); + + /* Deal with the stack regs. */ + if (regnum == -1 || regnum == SPARC_SP_REGNUM + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)) + { + ULONGEST sp; + + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + sparc_collect_rwindow (regcache, sp, regnum); + } + } + + /* Store the floating-point registers if the target has them. */ + if (fpregs_p && target_has_fp) + { + sparc32_collect_fpregset (regcache, -1, fpregs); + net_write_registers (fpregs, SPARC_FPREG_PLEN, PTRACE_SETFPREGS); + } +} diff --git a/contrib/gdb/gdb/remote.c b/contrib/gdb/gdb/remote.c index 2d70baf9b78..29bbbc86d80 100644 --- a/contrib/gdb/gdb/remote.c +++ b/contrib/gdb/gdb/remote.c @@ -1,7 +1,8 @@ /* Remote target communications for serial-line targets in custom GDB protocol Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GDB. @@ -55,6 +56,8 @@ #include "gdbcore.h" /* for exec_bfd */ +#include "remote-fileio.h" + /* Prototypes for local functions */ static void cleanup_sigint_signal_handler (void *dummy); static void initialize_sigint_signal_handler (void); @@ -67,10 +70,6 @@ void async_remote_interrupt_twice (gdb_client_data); static void build_remote_gdbarch_data (void); -static int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len); - -static int remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len); - static void remote_files_info (struct target_ops *ignore); static int remote_xfer_memory (CORE_ADDR memaddr, char *myaddr, @@ -86,7 +85,7 @@ static void remote_resume (ptid_t ptid, int step, enum target_signal siggnal); static void remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal); -static int remote_start_remote (PTR); +static int remote_start_remote (struct ui_out *uiout, void *dummy); static void remote_open (char *name, int from_tty); static void remote_async_open (char *name, int from_tty); @@ -94,9 +93,8 @@ static void remote_async_open (char *name, int from_tty); static void extended_remote_open (char *name, int from_tty); static void extended_remote_async_open (char *name, int from_tty); -static void remote_open_1 (char *, int, struct target_ops *, int extended_p); -static void remote_async_open_1 (char *, int, struct target_ops *, - int extended_p); +static void remote_open_1 (char *, int, struct target_ops *, int extended_p, + int async_p); static void remote_close (int quitting); @@ -129,7 +127,6 @@ static void remote_async_kill (void); static int tohex (int nib); static void remote_detach (char *args, int from_tty); -static void remote_async_detach (char *args, int from_tty); static void remote_interrupt (int signo); @@ -155,18 +152,12 @@ static void init_remote_ops (void); static void init_extended_remote_ops (void); -static void init_remote_cisco_ops (void); - -static struct target_ops remote_cisco_ops; - static void remote_stop (void); static int ishex (int ch, int *val); static int stubhex (int ch); -static int remote_query (int /*char */ , char *, char *, int *); - static int hexnumstr (char *, ULONGEST); static int hexnumnstr (char *, ULONGEST, int); @@ -205,16 +196,12 @@ static void show_packet_config_cmd (struct packet_config *config); static void update_packet_config (struct packet_config *config); -/* Define the target subroutine names */ - -void open_remote_target (char *, int, struct target_ops *, int); - void _initialize_remote (void); -/* Description of the remote protocol. Strictly speeking, when the +/* Description of the remote protocol. Strictly speaking, when the target is open()ed, remote.c should create a per-target description of the remote protocol using that target's architecture. - Unfortunatly, the target stack doesn't include local state. For + Unfortunately, the target stack doesn't include local state. For the moment keep the information in the target's architecture object. Sigh.. */ @@ -224,7 +211,7 @@ struct packet_reg long regnum; /* GDB's internal register number. */ LONGEST pnum; /* Remote protocol register number. */ int in_g_packet; /* Always part of G packet. */ - /* long size in bytes; == REGISTER_RAW_SIZE (regnum); at present. */ + /* long size in bytes; == DEPRECATED_REGISTER_RAW_SIZE (regnum); at present. */ /* char *name; == REGISTER_NAME (regnum); at present. */ }; @@ -250,36 +237,42 @@ struct remote_state long remote_packet_size; }; + /* Handle for retreving the remote protocol data from gdbarch. */ static struct gdbarch_data *remote_gdbarch_data_handle; static struct remote_state * -get_remote_state () +get_remote_state (void) { - return gdbarch_data (remote_gdbarch_data_handle); + return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle); } static void * init_remote_state (struct gdbarch *gdbarch) { int regnum; - struct remote_state *rs = xmalloc (sizeof (struct remote_state)); + struct remote_state *rs = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_state); - /* Start out by having the remote protocol mimic the existing - behavour - just copy in the description of the register cache. */ - rs->sizeof_g_packet = REGISTER_BYTES; /* OK use. */ + if (DEPRECATED_REGISTER_BYTES != 0) + rs->sizeof_g_packet = DEPRECATED_REGISTER_BYTES; + else + rs->sizeof_g_packet = 0; /* Assume a 1:1 regnum<->pnum table. */ - rs->regs = xcalloc (NUM_REGS + NUM_PSEUDO_REGS, sizeof (struct packet_reg)); + rs->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS + NUM_PSEUDO_REGS, + struct packet_reg); for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) { struct packet_reg *r = &rs->regs[regnum]; r->pnum = regnum; r->regnum = regnum; - r->offset = REGISTER_BYTE (regnum); + r->offset = DEPRECATED_REGISTER_BYTE (regnum); r->in_g_packet = (regnum < NUM_REGS); - /* ...size = REGISTER_RAW_SIZE (regnum); */ /* ...name = REGISTER_NAME (regnum); */ + + /* Compute packet size by accumulating the size of all registers. */ + if (DEPRECATED_REGISTER_BYTES == 0) + rs->sizeof_g_packet += register_size (current_gdbarch, regnum); } /* Default maximum number of characters in a packet body. Many @@ -299,21 +292,13 @@ init_remote_state (struct gdbarch *gdbarch) little. */ if (rs->sizeof_g_packet > ((rs->remote_packet_size - 32) / 2)) rs->remote_packet_size = (rs->sizeof_g_packet * 2 + 32); - + /* This one is filled in when a ``g'' packet is received. */ rs->actual_register_packet_size = 0; return rs; } -static void -free_remote_state (struct gdbarch *gdbarch, void *pointer) -{ - struct remote_state *data = pointer; - xfree (data->regs); - xfree (data); -} - static struct packet_reg * packet_reg_from_regnum (struct remote_state *rs, long regnum) { @@ -340,7 +325,17 @@ packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum) return NULL; } -/* */ +/* FIXME: graces/2002-08-08: These variables should eventually be + bound to an instance of the target object (as in gdbarch-tdep()), + when such a thing exists. */ + +/* This is set to the data address of the access causing the target + to stop for a watchpoint. */ +static CORE_ADDR remote_watch_data_address; + +/* This is non-zero if taregt stopped for a watchpoint. */ +static int remote_stopped_by_watchpoint_p; + static struct target_ops remote_ops; @@ -374,10 +369,6 @@ static int remote_break; starts. */ static struct serial *remote_desc = NULL; -/* This is set by the target (thru the 'S' message) - to denote that the target is in kernel mode. */ -static int cisco_kernel_mode = 0; - /* This variable sets the number of bits in an address that are to be sent in a memory ("M" or "m") packet. Normally, after stripping leading zeros, the entire address would be sent. This variable @@ -583,7 +574,7 @@ struct packet_config { char *name; char *title; - enum cmd_auto_boolean detect; + enum auto_boolean detect; enum packet_support support; }; @@ -602,13 +593,13 @@ update_packet_config (struct packet_config *config) { switch (config->detect) { - case CMD_AUTO_BOOLEAN_TRUE: + case AUTO_BOOLEAN_TRUE: config->support = PACKET_ENABLE; break; - case CMD_AUTO_BOOLEAN_FALSE: + case AUTO_BOOLEAN_FALSE: config->support = PACKET_DISABLE; break; - case CMD_AUTO_BOOLEAN_AUTO: + case AUTO_BOOLEAN_AUTO: config->support = PACKET_SUPPORT_UNKNOWN; break; } @@ -632,12 +623,12 @@ show_packet_config_cmd (struct packet_config *config) } switch (config->detect) { - case CMD_AUTO_BOOLEAN_AUTO: + case AUTO_BOOLEAN_AUTO: printf_filtered ("Support for remote protocol `%s' (%s) packet is auto-detected, currently %s.\n", config->name, config->title, support); break; - case CMD_AUTO_BOOLEAN_TRUE: - case CMD_AUTO_BOOLEAN_FALSE: + case AUTO_BOOLEAN_TRUE: + case AUTO_BOOLEAN_FALSE: printf_filtered ("Support for remote protocol `%s' (%s) packet is currently %s.\n", config->name, config->title, support); break; @@ -648,11 +639,8 @@ static void add_packet_config_cmd (struct packet_config *config, char *name, char *title, - void (*set_func) (char *args, int from_tty, - struct cmd_list_element * - c), - void (*show_func) (char *name, - int from_tty), + cmd_sfunc_ftype *set_func, + cmd_sfunc_ftype *show_func, struct cmd_list_element **set_remote_list, struct cmd_list_element **show_remote_list, int legacy) @@ -664,7 +652,7 @@ add_packet_config_cmd (struct packet_config *config, char *cmd_name; config->name = name; config->title = title; - config->detect = CMD_AUTO_BOOLEAN_AUTO; + config->detect = AUTO_BOOLEAN_AUTO; config->support = PACKET_SUPPORT_UNKNOWN; xasprintf (&set_doc, "Set use of remote protocol `%s' (%s) packet", name, title); @@ -672,12 +660,10 @@ add_packet_config_cmd (struct packet_config *config, name, title); /* set/show TITLE-packet {auto,on,off} */ xasprintf (&cmd_name, "%s-packet", title); - set_cmd = add_set_auto_boolean_cmd (cmd_name, class_obscure, - &config->detect, set_doc, - set_remote_list); - set_cmd_sfunc (set_cmd, set_func); - show_cmd = add_cmd (cmd_name, class_obscure, show_func, show_doc, - show_remote_list); + add_setshow_auto_boolean_cmd (cmd_name, class_obscure, + &config->detect, set_doc, show_doc, + set_func, show_func, + set_remote_list, show_remote_list); /* set/show remote NAME-packet {auto,on,off} -- legacy */ if (legacy) { @@ -730,7 +716,7 @@ packet_ok (const char *buf, struct packet_config *config) switch (config->support) { case PACKET_ENABLE: - if (config->detect == CMD_AUTO_BOOLEAN_AUTO) + if (config->detect == AUTO_BOOLEAN_AUTO) /* If the stub previously indicated that the packet was supported then there is a protocol error.. */ error ("Protocol error: %s (%s) conflicting enabled responses.", @@ -754,6 +740,23 @@ packet_ok (const char *buf, struct packet_config *config) } } +/* Should we try the 'vCont' (descriptive resume) request? */ +static struct packet_config remote_protocol_vcont; + +static void +set_remote_protocol_vcont_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) +{ + update_packet_config (&remote_protocol_vcont); +} + +static void +show_remote_protocol_vcont_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) +{ + show_packet_config_cmd (&remote_protocol_vcont); +} + /* Should we try the 'qSymbol' (target symbol lookup service) request? */ static struct packet_config remote_protocol_qSymbol; @@ -765,7 +768,8 @@ set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty) +show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_qSymbol); } @@ -781,11 +785,12 @@ set_remote_protocol_e_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_e_packet_cmd (char *args, int from_tty) +show_remote_protocol_e_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_e); } - + /* Should we try the 'E' (step over range / w signal #) request? */ static struct packet_config remote_protocol_E; @@ -798,11 +803,12 @@ set_remote_protocol_E_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_E_packet_cmd (char *args, int from_tty) +show_remote_protocol_E_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_E); } - + /* Should we try the 'P' (set register) request? */ @@ -816,7 +822,8 @@ set_remote_protocol_P_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_P_packet_cmd (char *args, int from_tty) +show_remote_protocol_P_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_P); } @@ -846,7 +853,8 @@ set_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty) +show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]); } @@ -859,7 +867,8 @@ set_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty) +show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]); } @@ -872,7 +881,8 @@ set_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty) +show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP]); } @@ -885,7 +895,8 @@ set_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty) +show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP]); } @@ -898,7 +909,8 @@ set_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty) +show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]); } @@ -906,7 +918,7 @@ show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty) /* For compatibility with older distributions. Provide a ``set remote Z-packet ...'' command that updates all the Z packet types. */ -static enum cmd_auto_boolean remote_Z_packet_detect; +static enum auto_boolean remote_Z_packet_detect; static void set_remote_protocol_Z_packet_cmd (char *args, int from_tty, @@ -921,7 +933,8 @@ set_remote_protocol_Z_packet_cmd (char *args, int from_tty, } static void -show_remote_protocol_Z_packet_cmd (char *args, int from_tty) +show_remote_protocol_Z_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) { int i; for (i = 0; i < NR_Z_PACKET_TYPES; i++) @@ -947,7 +960,7 @@ static struct packet_config remote_protocol_binary_download; This variable (NOT available to the user: auto-detect only!) determines whether GDB will use the new, simpler "ThreadInfo" query or the older, more complex syntax for thread queries. - This is an auto-detect variable (set to true at each connect, + This is an auto-detect variable (set to true at each connect, and set to false when the target fails to recognize it). */ static int use_threadinfo_query; @@ -962,16 +975,33 @@ set_remote_protocol_binary_download_cmd (char *args, } static void -show_remote_protocol_binary_download_cmd (char *args, - int from_tty) +show_remote_protocol_binary_download_cmd (char *args, int from_tty, + struct cmd_list_element *c) { show_packet_config_cmd (&remote_protocol_binary_download); } +/* Should we try the 'qPart:auxv' (target auxiliary vector read) request? */ +static struct packet_config remote_protocol_qPart_auxv; + +static void +set_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) +{ + update_packet_config (&remote_protocol_qPart_auxv); +} + +static void +show_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty, + struct cmd_list_element *c) +{ + show_packet_config_cmd (&remote_protocol_qPart_auxv); +} + /* Tokens for use by the asynchronous signal handlers for SIGINT */ -PTR sigint_remote_twice_token; -PTR sigint_remote_token; +static void *sigint_remote_twice_token; +static void *sigint_remote_token; /* These are pointers to hook functions that may be set in order to modify resume/wait behavior for a particular architecture. */ @@ -1102,7 +1132,7 @@ struct gdb_ext_thread_info #define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2) -char *unpack_varlen_hex (char *buff, int *result); +char *unpack_varlen_hex (char *buff, ULONGEST *result); static char *unpack_nibble (char *buf, int *val); @@ -1141,10 +1171,6 @@ static int remote_unpack_thread_info_response (char *pkt, static int remote_get_threadinfo (threadref * threadid, int fieldset, /*TAG mask */ struct gdb_ext_thread_info *info); -static int adapt_remote_get_threadinfo (gdb_threadref * ref, - int selection, - struct gdb_ext_thread_info *info); - static char *pack_threadlist_request (char *pkt, int startflag, int threadcount, threadref * nextthread); @@ -1223,7 +1249,7 @@ stub_unpack_int (char *buff, int fieldlength) char * unpack_varlen_hex (char *buff, /* packet to parse */ - int *result) + ULONGEST *result) { int nibble; int retval = 0; @@ -1446,7 +1472,7 @@ pack_threadinfo_request (char *pkt, int mode, threadref *id) fetch registers and its stack */ #define TAG_DISPLAY 4 /* A short thing maybe to put on a window */ #define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */ -#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about +#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about the process */ static int @@ -1556,19 +1582,6 @@ remote_get_threadinfo (threadref *threadid, int fieldset, /* TAG mask */ return result; } -/* Unfortunately, 61 bit thread-ids are bigger than the internal - representation of a threadid. */ - -static int -adapt_remote_get_threadinfo (gdb_threadref *ref, int selection, - struct gdb_ext_thread_info *info) -{ - threadref lclref; - - int_to_threadref (&lclref, *ref); - return remote_get_threadinfo (&lclref, selection, info); -} - /* Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32 */ static char * @@ -1747,8 +1760,8 @@ remote_current_thread (ptid_t oldpid) return oldpid; } -/* Find new threads for info threads command. - * Original version, using John Metzler's thread protocol. +/* Find new threads for info threads command. + * Original version, using John Metzler's thread protocol. */ static void @@ -1784,7 +1797,7 @@ remote_threads_info (void) bufp = buf; getpkt (bufp, (rs->remote_packet_size), 0); if (bufp[0] != '\0') /* q packet recognized */ - { + { while (*bufp++ == 'm') /* reply contains one or more TID */ { do @@ -1808,12 +1821,12 @@ remote_threads_info (void) return; } -/* +/* * Collect a descriptive string about the given thread. * The target may say anything it wants to about the thread * (typically info about its blocked / runnable state, name, etc.). * This string will appear in the info threads display. - * + * * Optional: targets are not required to implement this function. */ @@ -1898,7 +1911,6 @@ extended_remote_restart (void) /* Clean up connection to a remote debugger. */ -/* ARGSUSED */ static void remote_close (int quitting) { @@ -1974,8 +1986,10 @@ get_offsets (void) if (symfile_objfile == NULL) return; - offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS); - memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS); + offs = ((struct section_offsets *) + alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections))); + memcpy (offs, symfile_objfile->section_offsets, + SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)); offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr; @@ -1989,132 +2003,19 @@ get_offsets (void) objfile_relocate (symfile_objfile, offs); } -/* - * Cisco version of section offsets: - * - * Instead of having GDB query the target for the section offsets, - * Cisco lets the target volunteer the information! It's also in - * a different format, so here are the functions that will decode - * a section offset packet from a Cisco target. - */ - -/* - * Function: remote_cisco_section_offsets - * - * Returns: zero for success, non-zero for failure - */ - -static int -remote_cisco_section_offsets (bfd_vma text_addr, - bfd_vma data_addr, - bfd_vma bss_addr, - bfd_signed_vma *text_offs, - bfd_signed_vma *data_offs, - bfd_signed_vma *bss_offs) -{ - bfd_vma text_base, data_base, bss_base; - struct minimal_symbol *start; - asection *sect; - bfd *abfd; - int len; - - if (symfile_objfile == NULL) - return -1; /* no can do nothin' */ - - start = lookup_minimal_symbol ("_start", NULL, NULL); - if (start == NULL) - return -1; /* Can't find "_start" symbol */ - - data_base = bss_base = 0; - text_base = SYMBOL_VALUE_ADDRESS (start); - - abfd = symfile_objfile->obfd; - for (sect = abfd->sections; - sect != 0; - sect = sect->next) - { - const char *p = bfd_get_section_name (abfd, sect); - len = strlen (p); - if (strcmp (p + len - 4, "data") == 0) /* ends in "data" */ - if (data_base == 0 || - data_base > bfd_get_section_vma (abfd, sect)) - data_base = bfd_get_section_vma (abfd, sect); - if (strcmp (p + len - 3, "bss") == 0) /* ends in "bss" */ - if (bss_base == 0 || - bss_base > bfd_get_section_vma (abfd, sect)) - bss_base = bfd_get_section_vma (abfd, sect); - } - *text_offs = text_addr - text_base; - *data_offs = data_addr - data_base; - *bss_offs = bss_addr - bss_base; - if (remote_debug) - { - char tmp[128]; - - sprintf (tmp, "VMA: text = 0x"); - sprintf_vma (tmp + strlen (tmp), text_addr); - sprintf (tmp + strlen (tmp), " data = 0x"); - sprintf_vma (tmp + strlen (tmp), data_addr); - sprintf (tmp + strlen (tmp), " bss = 0x"); - sprintf_vma (tmp + strlen (tmp), bss_addr); - fprintf_filtered (gdb_stdlog, tmp); - fprintf_filtered (gdb_stdlog, - "Reloc offset: text = 0x%s data = 0x%s bss = 0x%s\n", - paddr_nz (*text_offs), - paddr_nz (*data_offs), - paddr_nz (*bss_offs)); - } - - return 0; -} - -/* - * Function: remote_cisco_objfile_relocate - * - * Relocate the symbol file for a remote target. - */ - -void -remote_cisco_objfile_relocate (bfd_signed_vma text_off, bfd_signed_vma data_off, - bfd_signed_vma bss_off) -{ - struct section_offsets *offs; - - if (text_off != 0 || data_off != 0 || bss_off != 0) - { - /* FIXME: This code assumes gdb-stabs.h is being used; it's - broken for xcoff, dwarf, sdb-coff, etc. But there is no - simple canonical representation for this stuff. */ - - offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS); - memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS); - - offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_off; - offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_off; - offs->offsets[SECT_OFF_BSS (symfile_objfile)] = bss_off; - - /* First call the standard objfile_relocate. */ - objfile_relocate (symfile_objfile, offs); - - /* Now we need to fix up the section entries already attached to - the exec target. These entries will control memory transfers - from the exec file. */ - - exec_set_section_offsets (text_off, data_off, bss_off); - } -} - /* Stub for catch_errors. */ static int -remote_start_remote_dummy (void *dummy) +remote_start_remote_dummy (struct ui_out *uiout, void *dummy) { start_remote (); /* Initialize gdb process mechanisms */ + /* NOTE: Return something >=0. A -ve value is reserved for + catch_exceptions. */ return 1; } static int -remote_start_remote (PTR dummy) +remote_start_remote (struct ui_out *uiout, void *dummy) { immediate_quit++; /* Allow user to interrupt it */ @@ -2131,7 +2032,9 @@ remote_start_remote (PTR dummy) putpkt ("?"); /* initiate a query from remote machine */ immediate_quit--; - return remote_start_remote_dummy (dummy); + /* NOTE: See comment above in remote_start_remote_dummy(). This + function returns something >=0. */ + return remote_start_remote_dummy (uiout, dummy); } /* Open a connection to a remote debugger. @@ -2140,14 +2043,14 @@ remote_start_remote (PTR dummy) static void remote_open (char *name, int from_tty) { - remote_open_1 (name, from_tty, &remote_ops, 0); + remote_open_1 (name, from_tty, &remote_ops, 0, 0); } /* Just like remote_open, but with asynchronous support. */ static void remote_async_open (char *name, int from_tty) { - remote_async_open_1 (name, from_tty, &remote_async_ops, 0); + remote_open_1 (name, from_tty, &remote_async_ops, 0, 1); } /* Open a connection to a remote debugger using the extended @@ -2156,14 +2059,16 @@ remote_async_open (char *name, int from_tty) static void extended_remote_open (char *name, int from_tty) { - remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */ ); + remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */, + 0 /* async_p */); } /* Just like extended_remote_open, but with asynchronous support. */ static void extended_remote_async_open (char *name, int from_tty) { - remote_async_open_1 (name, from_tty, &extended_async_remote_ops, 1 /*extended_p */ ); + remote_open_1 (name, from_tty, &extended_async_remote_ops, + 1 /*extended_p */, 1 /* async_p */); } /* Generic code for opening a connection to a remote target. */ @@ -2176,11 +2081,13 @@ init_all_packet_configs (void) update_packet_config (&remote_protocol_E); update_packet_config (&remote_protocol_P); update_packet_config (&remote_protocol_qSymbol); + update_packet_config (&remote_protocol_vcont); for (i = 0; i < NR_Z_PACKET_TYPES; i++) update_packet_config (&remote_protocol_Z[i]); /* Force remote_write_bytes to check whether target supports binary downloading. */ update_packet_config (&remote_protocol_binary_download); + update_packet_config (&remote_protocol_qPart_auxv); } /* Symbol look-up. */ @@ -2214,7 +2121,7 @@ remote_check_symbols (struct objfile *objfile) if (sym == NULL) sprintf (msg, "qSymbol::%s", &reply[8]); else - sprintf (msg, "qSymbol:%s:%s", + sprintf (msg, "qSymbol:%s:%s", paddr_nz (SYMBOL_VALUE_ADDRESS (sym)), &reply[8]); putpkt (msg); @@ -2222,10 +2129,31 @@ remote_check_symbols (struct objfile *objfile) } } +static struct serial * +remote_serial_open (char *name) +{ + static int udp_warning = 0; + + /* FIXME: Parsing NAME here is a hack. But we want to warn here instead + of in ser-tcp.c, because it is the remote protocol assuming that the + serial connection is reliable and not the serial connection promising + to be. */ + if (!udp_warning && strncmp (name, "udp:", 4) == 0) + { + warning ("The remote protocol may be unreliable over UDP."); + warning ("Some events may be lost, rendering further debugging " + "impossible."); + udp_warning = 1; + } + + return serial_open (name); +} + static void remote_open_1 (char *name, int from_tty, struct target_ops *target, - int extended_p) + int extended_p, int async_p) { + int ex; struct remote_state *rs = get_remote_state (); if (name == 0) error ("To open a remote debug connection, you need to specify what\n" @@ -2233,13 +2161,14 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.)."); /* See FIXME above */ - wait_forever_enabled_p = 1; + if (!async_p) + wait_forever_enabled_p = 1; target_preopen (from_tty); unpush_target (target); - remote_desc = serial_open (name); + remote_desc = remote_serial_open (name); if (!remote_desc) perror_with_name (name); @@ -2247,7 +2176,12 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, { if (serial_setbaudrate (remote_desc, baud_rate)) { + /* The requested speed could not be set. Error out to + top level after closing remote_desc. Take care to + set remote_desc to NULL to avoid closing remote_desc + more than once. */ serial_close (remote_desc); + remote_desc = NULL; perror_with_name (name); } } @@ -2267,7 +2201,7 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, push_target (target); /* Switch to using remote target now */ init_all_packet_configs (); - + general_thread = -2; continue_thread = -2; @@ -2283,22 +2217,58 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, someday have a notion of debugging several processes. */ inferior_ptid = pid_to_ptid (MAGIC_NULL_PID); + + if (async_p) + { + /* With this target we start out by owning the terminal. */ + remote_async_terminal_ours_p = 1; + + /* FIXME: cagney/1999-09-23: During the initial connection it is + assumed that the target is already ready and able to respond to + requests. Unfortunately remote_start_remote() eventually calls + wait_for_inferior() with no timeout. wait_forever_enabled_p gets + around this. Eventually a mechanism that allows + wait_for_inferior() to expect/get timeouts will be + implemented. */ + wait_forever_enabled_p = 0; + } + #ifdef SOLIB_CREATE_INFERIOR_HOOK /* First delete any symbols previously loaded from shared libraries. */ no_shared_libraries (NULL, 0); #endif - /* Start the remote connection; if error (0), discard this target. - In particular, if the user quits, be sure to discard it - (we'd be in an inconsistent state otherwise). */ - if (!catch_errors (remote_start_remote, NULL, - "Couldn't establish connection to remote target\n", - RETURN_MASK_ALL)) + /* Start the remote connection. If error() or QUIT, discard this + target (we'd otherwise be in an inconsistent state) and then + propogate the error on up the exception chain. This ensures that + the caller doesn't stumble along blindly assuming that the + function succeeded. The CLI doesn't have this problem but other + UI's, such as MI do. + + FIXME: cagney/2002-05-19: Instead of re-throwing the exception, + this function should return an error indication letting the + caller restore the previous state. Unfortunately the command + ``target remote'' is directly wired to this function making that + impossible. On a positive note, the CLI side of this problem has + been fixed - the function set_cmd_context() makes it possible for + all the ``target ....'' commands to share a common callback + function. See cli-dump.c. */ + ex = catch_exceptions (uiout, + remote_start_remote, NULL, + "Couldn't establish connection to remote" + " target\n", + RETURN_MASK_ALL); + if (ex < 0) { pop_target (); - return; + if (async_p) + wait_forever_enabled_p = 1; + throw_exception (ex); } + if (async_p) + wait_forever_enabled_p = 1; + if (extended_p) { /* Tell the remote that we are using the extended protocol. */ @@ -2307,124 +2277,10 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, getpkt (buf, (rs->remote_packet_size), 0); } #ifdef SOLIB_CREATE_INFERIOR_HOOK - /* FIXME: need a master target_open vector from which all - remote_opens can be called, so that stuff like this can + /* FIXME: need a master target_open vector from which all + remote_opens can be called, so that stuff like this can go there. Failing that, the following code must be copied - to the open function for any remote target that wants to - support svr4 shared libraries. */ - - /* Set up to detect and load shared libraries. */ - if (exec_bfd) /* No use without an exec file. */ - { - SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid)); - remote_check_symbols (symfile_objfile); - } -#endif -} - -/* Just like remote_open but with asynchronous support. */ -static void -remote_async_open_1 (char *name, int from_tty, struct target_ops *target, - int extended_p) -{ - struct remote_state *rs = get_remote_state (); - if (name == 0) - error ("To open a remote debug connection, you need to specify what\n" - "serial device is attached to the remote system\n" - "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.)."); - - target_preopen (from_tty); - - unpush_target (target); - - remote_desc = serial_open (name); - if (!remote_desc) - perror_with_name (name); - - if (baud_rate != -1) - { - if (serial_setbaudrate (remote_desc, baud_rate)) - { - serial_close (remote_desc); - perror_with_name (name); - } - } - - serial_raw (remote_desc); - - /* If there is something sitting in the buffer we might take it as a - response to a command, which would be bad. */ - serial_flush_input (remote_desc); - - if (from_tty) - { - puts_filtered ("Remote debugging using "); - puts_filtered (name); - puts_filtered ("\n"); - } - - push_target (target); /* Switch to using remote target now */ - - init_all_packet_configs (); - - general_thread = -2; - continue_thread = -2; - - /* Probe for ability to use "ThreadInfo" query, as required. */ - use_threadinfo_query = 1; - use_threadextra_query = 1; - - /* Without this, some commands which require an active target (such - as kill) won't work. This variable serves (at least) double duty - as both the pid of the target process (if it has such), and as a - flag indicating that a target is active. These functions should - be split out into seperate variables, especially since GDB will - someday have a notion of debugging several processes. */ - inferior_ptid = pid_to_ptid (MAGIC_NULL_PID); - - /* With this target we start out by owning the terminal. */ - remote_async_terminal_ours_p = 1; - - /* FIXME: cagney/1999-09-23: During the initial connection it is - assumed that the target is already ready and able to respond to - requests. Unfortunately remote_start_remote() eventually calls - wait_for_inferior() with no timeout. wait_forever_enabled_p gets - around this. Eventually a mechanism that allows - wait_for_inferior() to expect/get timeouts will be - implemented. */ - wait_forever_enabled_p = 0; - -#ifdef SOLIB_CREATE_INFERIOR_HOOK - /* First delete any symbols previously loaded from shared libraries. */ - no_shared_libraries (NULL, 0); -#endif - - /* Start the remote connection; if error (0), discard this target. - In particular, if the user quits, be sure to discard it - (we'd be in an inconsistent state otherwise). */ - if (!catch_errors (remote_start_remote, NULL, - "Couldn't establish connection to remote target\n", - RETURN_MASK_ALL)) - { - pop_target (); - wait_forever_enabled_p = 1; - return; - } - - wait_forever_enabled_p = 1; - - if (extended_p) - { - /* Tell the remote that we are using the extended protocol. */ - char *buf = alloca (rs->remote_packet_size); - putpkt ("!"); - getpkt (buf, (rs->remote_packet_size), 0); - } -#ifdef SOLIB_CREATE_INFERIOR_HOOK - /* FIXME: need a master target_open vector from which all - remote_opens can be called, so that stuff like this can - go there. Failing that, the following code must be copied - to the open function for any remote target that wants to + to the open function for any remote target that wants to support svr4 shared libraries. */ /* Set up to detect and load shared libraries. */ @@ -2454,15 +2310,19 @@ remote_detach (char *args, int from_tty) strcpy (buf, "D"); remote_send (buf, (rs->remote_packet_size)); + /* Unregister the file descriptor from the event loop. */ + if (target_is_async_p ()) + serial_async (remote_desc, NULL, 0); + target_mourn_inferior (); if (from_tty) puts_filtered ("Ending remote debugging.\n"); - } -/* Same as remote_detach, but with async support. */ +/* Same as remote_detach, but don't send the "D" packet; just disconnect. */ + static void -remote_async_detach (char *args, int from_tty) +remote_disconnect (char *args, int from_tty) { struct remote_state *rs = get_remote_state (); char *buf = alloca (rs->remote_packet_size); @@ -2470,10 +2330,6 @@ remote_async_detach (char *args, int from_tty) if (args) error ("Argument given to \"detach\" when remotely debugging."); - /* Tell the remote target to detach. */ - strcpy (buf, "D"); - remote_send (buf, (rs->remote_packet_size)); - /* Unregister the file descriptor from the event loop. */ if (target_is_async_p ()) serial_async (remote_desc, NULL, 0); @@ -2545,6 +2401,135 @@ bin2hex (const char *bin, char *hex, int count) return i; } +/* Check for the availability of vCont. This function should also check + the response. */ + +static void +remote_vcont_probe (struct remote_state *rs, char *buf) +{ + strcpy (buf, "vCont?"); + putpkt (buf); + getpkt (buf, rs->remote_packet_size, 0); + + /* Make sure that the features we assume are supported. */ + if (strncmp (buf, "vCont", 5) == 0) + { + char *p = &buf[5]; + int support_s, support_S, support_c, support_C; + + support_s = 0; + support_S = 0; + support_c = 0; + support_C = 0; + while (p && *p == ';') + { + p++; + if (*p == 's' && (*(p + 1) == ';' || *(p + 1) == 0)) + support_s = 1; + else if (*p == 'S' && (*(p + 1) == ';' || *(p + 1) == 0)) + support_S = 1; + else if (*p == 'c' && (*(p + 1) == ';' || *(p + 1) == 0)) + support_c = 1; + else if (*p == 'C' && (*(p + 1) == ';' || *(p + 1) == 0)) + support_C = 1; + + p = strchr (p, ';'); + } + + /* If s, S, c, and C are not all supported, we can't use vCont. Clearing + BUF will make packet_ok disable the packet. */ + if (!support_s || !support_S || !support_c || !support_C) + buf[0] = 0; + } + + packet_ok (buf, &remote_protocol_vcont); +} + +/* Resume the remote inferior by using a "vCont" packet. The thread + to be resumed is PTID; STEP and SIGGNAL indicate whether the + resumed thread should be single-stepped and/or signalled. If PTID's + PID is -1, then all threads are resumed; the thread to be stepped and/or + signalled is given in the global INFERIOR_PTID. This function returns + non-zero iff it resumes the inferior. + + This function issues a strict subset of all possible vCont commands at the + moment. */ + +static int +remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal) +{ + struct remote_state *rs = get_remote_state (); + int pid = PIDGET (ptid); + char *buf = NULL, *outbuf; + struct cleanup *old_cleanup; + + buf = xmalloc (rs->remote_packet_size); + old_cleanup = make_cleanup (xfree, buf); + + if (remote_protocol_vcont.support == PACKET_SUPPORT_UNKNOWN) + remote_vcont_probe (rs, buf); + + if (remote_protocol_vcont.support == PACKET_DISABLE) + { + do_cleanups (old_cleanup); + return 0; + } + + /* If we could generate a wider range of packets, we'd have to worry + about overflowing BUF. Should there be a generic + "multi-part-packet" packet? */ + + if (PIDGET (inferior_ptid) == MAGIC_NULL_PID) + { + /* MAGIC_NULL_PTID means that we don't have any active threads, so we + don't have any PID numbers the inferior will understand. Make sure + to only send forms that do not specify a PID. */ + if (step && siggnal != TARGET_SIGNAL_0) + outbuf = xstrprintf ("vCont;S%02x", siggnal); + else if (step) + outbuf = xstrprintf ("vCont;s"); + else if (siggnal != TARGET_SIGNAL_0) + outbuf = xstrprintf ("vCont;C%02x", siggnal); + else + outbuf = xstrprintf ("vCont;c"); + } + else if (pid == -1) + { + /* Resume all threads, with preference for INFERIOR_PTID. */ + if (step && siggnal != TARGET_SIGNAL_0) + outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal, + PIDGET (inferior_ptid)); + else if (step) + outbuf = xstrprintf ("vCont;s:%x;c", PIDGET (inferior_ptid)); + else if (siggnal != TARGET_SIGNAL_0) + outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal, + PIDGET (inferior_ptid)); + else + outbuf = xstrprintf ("vCont;c"); + } + else + { + /* Scheduler locking; resume only PTID. */ + if (step && siggnal != TARGET_SIGNAL_0) + outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, pid); + else if (step) + outbuf = xstrprintf ("vCont;s:%x", pid); + else if (siggnal != TARGET_SIGNAL_0) + outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, pid); + else + outbuf = xstrprintf ("vCont;c:%x", pid); + } + + gdb_assert (outbuf && strlen (outbuf) < rs->remote_packet_size); + make_cleanup (xfree, outbuf); + + putpkt (outbuf); + + do_cleanups (old_cleanup); + + return 1; +} + /* Tell the remote machine to resume. */ static enum target_signal last_sent_signal = TARGET_SIGNAL_0; @@ -2559,11 +2544,6 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal) int pid = PIDGET (ptid); char *p; - if (pid == -1) - set_thread (0, 0); /* run any thread */ - else - set_thread (pid, 0); /* run this thread */ - last_sent_signal = siggnal; last_sent_step = step; @@ -2572,6 +2552,15 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal) if (target_resume_hook) (*target_resume_hook) (); + /* The vCont packet doesn't need to specify threads via Hc. */ + if (remote_vcont_resume (ptid, step, siggnal)) + return; + + /* All other supported resume packets do use Hc, so call set_thread. */ + if (pid == -1) + set_thread (0, 0); /* run any thread */ + else + set_thread (pid, 0); /* run this thread */ /* The s/S/c/C packets do not return status. So if the target does not support the S or C packets, the debug agent returns an empty @@ -2585,7 +2574,7 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal) too is not supported. But that would require another copy of the code to issue the 'e' packet (and fall back to 's' if not supported) in remote_wait(). */ - + if (siggnal != TARGET_SIGNAL_0) { if (remote_protocol_E.support != PACKET_DISABLE) @@ -2644,91 +2633,8 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal) static void remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal) { - struct remote_state *rs = get_remote_state (); - char *buf = alloca (rs->remote_packet_size); - int pid = PIDGET (ptid); - char *p; + remote_resume (ptid, step, siggnal); - if (pid == -1) - set_thread (0, 0); /* run any thread */ - else - set_thread (pid, 0); /* run this thread */ - - last_sent_signal = siggnal; - last_sent_step = step; - - /* A hook for when we need to do something at the last moment before - resumption. */ - if (target_resume_hook) - (*target_resume_hook) (); - - /* The s/S/c/C packets do not return status. So if the target does - not support the S or C packets, the debug agent returns an empty - string which is detected in remote_wait(). This protocol defect - is fixed in the e/E packets. */ - - if (step && step_range_end) - { - /* If the target does not support the 'E' packet, we try the 'S' - packet. Ideally we would fall back to the 'e' packet if that - too is not supported. But that would require another copy of - the code to issue the 'e' packet (and fall back to 's' if not - supported) in remote_wait(). */ - - if (siggnal != TARGET_SIGNAL_0) - { - if (remote_protocol_E.support != PACKET_DISABLE) - { - p = buf; - *p++ = 'E'; - *p++ = tohex (((int) siggnal >> 4) & 0xf); - *p++ = tohex (((int) siggnal) & 0xf); - *p++ = ','; - p += hexnumstr (p, (ULONGEST) step_range_start); - *p++ = ','; - p += hexnumstr (p, (ULONGEST) step_range_end); - *p++ = 0; - - putpkt (buf); - getpkt (buf, (rs->remote_packet_size), 0); - - if (packet_ok (buf, &remote_protocol_E) == PACKET_OK) - goto register_event_loop; - } - } - else - { - if (remote_protocol_e.support != PACKET_DISABLE) - { - p = buf; - *p++ = 'e'; - p += hexnumstr (p, (ULONGEST) step_range_start); - *p++ = ','; - p += hexnumstr (p, (ULONGEST) step_range_end); - *p++ = 0; - - putpkt (buf); - getpkt (buf, (rs->remote_packet_size), 0); - - if (packet_ok (buf, &remote_protocol_e) == PACKET_OK) - goto register_event_loop; - } - } - } - - if (siggnal != TARGET_SIGNAL_0) - { - buf[0] = step ? 'S' : 'C'; - buf[1] = tohex (((int) siggnal >> 4) & 0xf); - buf[2] = tohex ((int) siggnal & 0xf); - buf[3] = '\0'; - } - else - strcpy (buf, step ? "s" : "c"); - - putpkt (buf); - -register_event_loop: /* We are about to start executing the inferior, let's register it with the event loop. NOTE: this is the one place where all the execution commands end up. We could alternatively do this in each @@ -2950,7 +2856,7 @@ remote_console_output (char *msg) /* Wait until the remote machine stops, then return, storing status in STATUS just as `wait' would. - Returns "pid", which in the case of a multi-threaded + Returns "pid", which in the case of a multi-threaded remote OS, is the thread-id. */ static ptid_t @@ -2958,7 +2864,8 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status) { struct remote_state *rs = get_remote_state (); unsigned char *buf = alloca (rs->remote_packet_size); - int thread_num = -1; + ULONGEST thread_num = -1; + ULONGEST addr; status->kind = TARGET_WAITKIND_EXITED; status->value.integer = 0; @@ -2976,15 +2883,20 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status) if (target_wait_loop_hook) (*target_wait_loop_hook) (); + remote_stopped_by_watchpoint_p = 0; + switch (buf[0]) { case 'E': /* Error of some sort */ warning ("Remote failure reply: %s", buf); continue; + case 'F': /* File-I/O request */ + remote_fileio_request (buf); + continue; case 'T': /* Status with PC, SP, FP, ... */ { int i; - char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE); + char regs[MAX_REGISTER_SIZE]; /* Expedited reply, containing Signal, {regno, reg} repeat */ /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where @@ -2999,24 +2911,52 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status) unsigned char *p1; char *p_temp; int fieldsize; + LONGEST pnum = 0; - /* Read the ``P'' register number. */ - LONGEST pnum = strtol ((const char *) p, &p_temp, 16); - p1 = (unsigned char *) p_temp; + /* If the packet contains a register number save it in pnum + and set p1 to point to the character following it. + Otherwise p1 points to p. */ + + /* If this packet is an awatch packet, don't parse the 'a' + as a register number. */ + + if (strncmp (p, "awatch", strlen("awatch")) != 0) + { + /* Read the ``P'' register number. */ + pnum = strtol (p, &p_temp, 16); + p1 = (unsigned char *) p_temp; + } + else + p1 = p; if (p1 == p) /* No register number present here */ { - p1 = (unsigned char *) strchr ((const char *) p, ':'); + p1 = (unsigned char *) strchr (p, ':'); if (p1 == NULL) warning ("Malformed packet(a) (missing colon): %s\n\ Packet: '%s'\n", p, buf); - if (strncmp ((const char *) p, "thread", p1 - p) == 0) + if (strncmp (p, "thread", p1 - p) == 0) { p_temp = unpack_varlen_hex (++p1, &thread_num); record_currthread (thread_num); p = (unsigned char *) p_temp; } + else if ((strncmp (p, "watch", p1 - p) == 0) + || (strncmp (p, "rwatch", p1 - p) == 0) + || (strncmp (p, "awatch", p1 - p) == 0)) + { + remote_stopped_by_watchpoint_p = 1; + p = unpack_varlen_hex (++p1, &addr); + remote_watch_data_address = (CORE_ADDR)addr; + } + else + { + /* Silently skip unknown optional info. */ + p_temp = strchr (p1 + 1, ';'); + if (p_temp) + p = (unsigned char *) p_temp; + } } else { @@ -3024,27 +2964,22 @@ Packet: '%s'\n", p = p1; if (*p++ != ':') - warning ("Malformed packet(b) (missing colon): %s\n\ -Packet: '%s'\n", - p, buf); + error ("Malformed packet(b) (missing colon): %s\nPacket: '%s'\n", + p, buf); if (reg == NULL) - warning ("Remote sent bad register number %s: %s\n\ -Packet: '%s'\n", - phex_nz (pnum, 0), p, buf); + error ("Remote sent bad register number %s: %s\nPacket: '%s'\n", + phex_nz (pnum, 0), p, buf); - fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum)); + fieldsize = hex2bin (p, regs, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum)); p += 2 * fieldsize; - if (fieldsize < REGISTER_RAW_SIZE (reg->regnum)) + if (fieldsize < DEPRECATED_REGISTER_RAW_SIZE (reg->regnum)) warning ("Remote reply is too short: %s", buf); supply_register (reg->regnum, regs); } if (*p++ != ';') - { - warning ("Remote register badly formatted: %s", buf); - warning (" here: %s", p); - } + error ("Remote register badly formatted: %s\nhere: %s", buf, p); } } /* fall through */ @@ -3055,70 +2990,10 @@ Packet: '%s'\n", if (buf[3] == 'p') { - /* Export Cisco kernel mode as a convenience variable - (so that it can be used in the GDB prompt if desired). */ - - if (cisco_kernel_mode == 1) - set_internalvar (lookup_internalvar ("cisco_kernel_mode"), - value_from_string ("PDEBUG-")); - cisco_kernel_mode = 0; thread_num = strtol ((const char *) &buf[4], NULL, 16); record_currthread (thread_num); } - else if (buf[3] == 'k') - { - /* Export Cisco kernel mode as a convenience variable - (so that it can be used in the GDB prompt if desired). */ - - if (cisco_kernel_mode == 1) - set_internalvar (lookup_internalvar ("cisco_kernel_mode"), - value_from_string ("KDEBUG-")); - cisco_kernel_mode = 1; - } goto got_status; - case 'N': /* Cisco special: status and offsets */ - { - bfd_vma text_addr, data_addr, bss_addr; - bfd_signed_vma text_off, data_off, bss_off; - unsigned char *p1; - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = (enum target_signal) - (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))); - - if (symfile_objfile == NULL) - { - warning ("Relocation packet received with no symbol file. \ -Packet Dropped"); - goto got_status; - } - - /* Relocate object file. Buffer format is NAATT;DD;BB - * where AA is the signal number, TT is the new text - * address, DD * is the new data address, and BB is the - * new bss address. */ - - p = &buf[3]; - text_addr = strtoul (p, (char **) &p1, 16); - if (p1 == p || *p1 != ';') - warning ("Malformed relocation packet: Packet '%s'", buf); - p = p1 + 1; - data_addr = strtoul (p, (char **) &p1, 16); - if (p1 == p || *p1 != ';') - warning ("Malformed relocation packet: Packet '%s'", buf); - p = p1 + 1; - bss_addr = strtoul (p, (char **) &p1, 16); - if (p1 == p) - warning ("Malformed relocation packet: Packet '%s'", buf); - - if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr, - &text_off, &data_off, &bss_off) - == 0) - if (text_off != 0 || data_off != 0 || bss_off != 0) - remote_cisco_objfile_relocate (text_off, data_off, bss_off); - - goto got_status; - } case 'W': /* Target exited */ { /* The remote process exited. */ @@ -3172,11 +3047,14 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status) { struct remote_state *rs = get_remote_state (); unsigned char *buf = alloca (rs->remote_packet_size); - int thread_num = -1; + ULONGEST thread_num = -1; + ULONGEST addr; status->kind = TARGET_WAITKIND_EXITED; status->value.integer = 0; + remote_stopped_by_watchpoint_p = 0; + while (1) { unsigned char *p; @@ -3201,10 +3079,13 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status) case 'E': /* Error of some sort */ warning ("Remote failure reply: %s", buf); continue; + case 'F': /* File-I/O request */ + remote_fileio_request (buf); + continue; case 'T': /* Status with PC, SP, FP, ... */ { int i; - char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE); + char regs[MAX_REGISTER_SIZE]; /* Expedited reply, containing Signal, {regno, reg} repeat */ /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where @@ -3219,51 +3100,75 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status) unsigned char *p1; char *p_temp; int fieldsize; + long pnum = 0; - /* Read the register number */ - long pnum = strtol ((const char *) p, &p_temp, 16); - p1 = (unsigned char *) p_temp; + /* If the packet contains a register number, save it in pnum + and set p1 to point to the character following it. + Otherwise p1 points to p. */ + + /* If this packet is an awatch packet, don't parse the 'a' + as a register number. */ + + if (!strncmp (p, "awatch", strlen ("awatch")) != 0) + { + /* Read the register number. */ + pnum = strtol (p, &p_temp, 16); + p1 = (unsigned char *) p_temp; + } + else + p1 = p; if (p1 == p) /* No register number present here */ { - p1 = (unsigned char *) strchr ((const char *) p, ':'); + p1 = (unsigned char *) strchr (p, ':'); if (p1 == NULL) - warning ("Malformed packet(a) (missing colon): %s\n\ -Packet: '%s'\n", - p, buf); - if (strncmp ((const char *) p, "thread", p1 - p) == 0) + error ("Malformed packet(a) (missing colon): %s\nPacket: '%s'\n", + p, buf); + if (strncmp (p, "thread", p1 - p) == 0) { p_temp = unpack_varlen_hex (++p1, &thread_num); record_currthread (thread_num); p = (unsigned char *) p_temp; } + else if ((strncmp (p, "watch", p1 - p) == 0) + || (strncmp (p, "rwatch", p1 - p) == 0) + || (strncmp (p, "awatch", p1 - p) == 0)) + { + remote_stopped_by_watchpoint_p = 1; + p = unpack_varlen_hex (++p1, &addr); + remote_watch_data_address = (CORE_ADDR)addr; + } + else + { + /* Silently skip unknown optional info. */ + p_temp = (unsigned char *) strchr (p1 + 1, ';'); + if (p_temp) + p = p_temp; + } } + else { struct packet_reg *reg = packet_reg_from_pnum (rs, pnum); p = p1; if (*p++ != ':') - warning ("Malformed packet(b) (missing colon): %s\n\ -Packet: '%s'\n", - p, buf); + error ("Malformed packet(b) (missing colon): %s\nPacket: '%s'\n", + p, buf); if (reg == NULL) - warning ("Remote sent bad register number %ld: %s\n\ -Packet: '%s'\n", - pnum, p, buf); + error ("Remote sent bad register number %ld: %s\nPacket: '%s'\n", + pnum, p, buf); - fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum)); + fieldsize = hex2bin (p, regs, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum)); p += 2 * fieldsize; - if (fieldsize < REGISTER_RAW_SIZE (reg->regnum)) + if (fieldsize < DEPRECATED_REGISTER_RAW_SIZE (reg->regnum)) warning ("Remote reply is too short: %s", buf); supply_register (reg->regnum, regs); } if (*p++ != ';') - { - warning ("Remote register badly formatted: %s", buf); - warning (" here: %s", p); - } + error ("Remote register badly formatted: %s\nhere: %s", + buf, p); } } /* fall through */ @@ -3274,70 +3179,10 @@ Packet: '%s'\n", if (buf[3] == 'p') { - /* Export Cisco kernel mode as a convenience variable - (so that it can be used in the GDB prompt if desired). */ - - if (cisco_kernel_mode == 1) - set_internalvar (lookup_internalvar ("cisco_kernel_mode"), - value_from_string ("PDEBUG-")); - cisco_kernel_mode = 0; thread_num = strtol ((const char *) &buf[4], NULL, 16); record_currthread (thread_num); } - else if (buf[3] == 'k') - { - /* Export Cisco kernel mode as a convenience variable - (so that it can be used in the GDB prompt if desired). */ - - if (cisco_kernel_mode == 1) - set_internalvar (lookup_internalvar ("cisco_kernel_mode"), - value_from_string ("KDEBUG-")); - cisco_kernel_mode = 1; - } goto got_status; - case 'N': /* Cisco special: status and offsets */ - { - bfd_vma text_addr, data_addr, bss_addr; - bfd_signed_vma text_off, data_off, bss_off; - unsigned char *p1; - - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = (enum target_signal) - (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))); - - if (symfile_objfile == NULL) - { - warning ("Relocation packet recieved with no symbol file. \ -Packet Dropped"); - goto got_status; - } - - /* Relocate object file. Buffer format is NAATT;DD;BB - * where AA is the signal number, TT is the new text - * address, DD * is the new data address, and BB is the - * new bss address. */ - - p = &buf[3]; - text_addr = strtoul (p, (char **) &p1, 16); - if (p1 == p || *p1 != ';') - warning ("Malformed relocation packet: Packet '%s'", buf); - p = p1 + 1; - data_addr = strtoul (p, (char **) &p1, 16); - if (p1 == p || *p1 != ';') - warning ("Malformed relocation packet: Packet '%s'", buf); - p = p1 + 1; - bss_addr = strtoul (p, (char **) &p1, 16); - if (p1 == p) - warning ("Malformed relocation packet: Packet '%s'", buf); - - if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr, - &text_off, &data_off, &bss_off) - == 0) - if (text_off != 0 || data_off != 0 || bss_off != 0) - remote_cisco_objfile_relocate (text_off, data_off, bss_off); - - goto got_status; - } case 'W': /* Target exited */ { /* The remote process exited. */ @@ -3395,7 +3240,6 @@ static int register_bytes_found; /* Read the remote registers into the block REGS. */ /* Currently we just read all the registers, so we don't use regnum. */ -/* ARGSUSED */ static void remote_fetch_registers (int regnum) { @@ -3481,9 +3325,23 @@ remote_fetch_registers (int regnum) struct packet_reg *r = &rs->regs[i]; if (r->in_g_packet) { - supply_register (r->regnum, regs + r->offset); - if (buf[r->offset * 2] == 'x') - set_register_cached (i, -1); + if (r->offset * 2 >= strlen (buf)) + /* A short packet that didn't include the register's + value, this implies that the register is zero (and + not that the register is unavailable). Supply that + zero value. */ + regcache_raw_supply (current_regcache, r->regnum, NULL); + else if (buf[r->offset * 2] == 'x') + { + gdb_assert (r->offset * 2 < strlen (buf)); + /* The register isn't available, mark it as such (at + the same time setting the value to zero). */ + regcache_raw_supply (current_regcache, r->regnum, NULL); + set_register_cached (i, -1); + } + else + regcache_raw_supply (current_regcache, r->regnum, + regs + r->offset); } } } @@ -3496,15 +3354,19 @@ remote_fetch_registers (int regnum) static void remote_prepare_to_store (void) { + struct remote_state *rs = get_remote_state (); + int i; + char buf[MAX_REGISTER_SIZE]; + /* Make sure the entire registers array is valid. */ switch (remote_protocol_P.support) { case PACKET_DISABLE: case PACKET_SUPPORT_UNKNOWN: - /* NOTE: This isn't rs->sizeof_g_packet because here, we are - forcing the register cache to read its and not the target - registers. */ - read_register_bytes (0, (char *) NULL, REGISTER_BYTES); /* OK use. */ + /* Make sure all the necessary registers are cached. */ + for (i = 0; i < NUM_REGS; i++) + if (rs->regs[i].in_g_packet) + regcache_raw_read (current_regcache, rs->regs[i].regnum, buf); break; case PACKET_ENABLE: break; @@ -3521,14 +3383,14 @@ store_register_using_P (int regnum) struct packet_reg *reg = packet_reg_from_regnum (rs, regnum); /* Try storing a single register. */ char *buf = alloca (rs->remote_packet_size); - char *regp = alloca (MAX_REGISTER_RAW_SIZE); + char regp[MAX_REGISTER_SIZE]; char *p; int i; sprintf (buf, "P%s=", phex_nz (reg->pnum, 0)); p = buf + strlen (buf); regcache_collect (reg->regnum, regp); - bin2hex (regp, p, REGISTER_RAW_SIZE (reg->regnum)); + bin2hex (regp, p, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum)); remote_send (buf, rs->remote_packet_size); return buf[0] != '\0'; @@ -3685,7 +3547,7 @@ check_binary_download (CORE_ADDR addr) { char *buf = alloca (rs->remote_packet_size); char *p; - + p = buf; *p++ = 'X'; p += hexnumstr (p, (ULONGEST) addr); @@ -3693,7 +3555,7 @@ check_binary_download (CORE_ADDR addr) p += hexnumstr (p, (ULONGEST) 0); *p++ = ':'; *p = '\0'; - + putpkt_binary (buf, (int) (p - buf)); getpkt (buf, (rs->remote_packet_size), 0); @@ -3725,46 +3587,49 @@ check_binary_download (CORE_ADDR addr) Returns number of bytes transferred, or 0 (setting errno) for error. Only transfer a single packet. */ -static int +int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) { unsigned char *buf; - int max_buf_size; /* Max size of packet output buffer */ unsigned char *p; unsigned char *plen; long sizeof_buf; int plenlen; int todo; int nr_bytes; + int payload_size; + unsigned char *payload_start; - /* Verify that the target can support a binary download */ + /* Verify that the target can support a binary download. */ check_binary_download (memaddr); - /* Determine the max packet size. */ - max_buf_size = get_memory_write_packet_size (); - sizeof_buf = max_buf_size + 1; /* Space for trailing NUL */ + /* Compute the size, and then allocate space for the largest + possible packet. Include space for an extra trailing NUL. */ + sizeof_buf = get_memory_write_packet_size () + 1; buf = alloca (sizeof_buf); - /* Subtract header overhead from max payload size - $M,:#nn */ - max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4; + /* Compute the size of the actual payload by subtracting out the + packet header and footer overhead: "$M,:...#nn". */ + payload_size = (get_memory_write_packet_size () - (strlen ("$M,:#NN") + + hexnumlen (memaddr) + + hexnumlen (len))); - /* construct "M"","":" */ - /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */ - p = buf; + /* Construct the packet header: "[MX],:". */ - /* Append [XM]. Compute a best guess of the number of bytes + /* Append "[XM]". Compute a best guess of the number of bytes actually transfered. */ + p = buf; switch (remote_protocol_binary_download.support) { case PACKET_ENABLE: *p++ = 'X'; /* Best guess at number of bytes that will fit. */ - todo = min (len, max_buf_size); + todo = min (len, payload_size); break; case PACKET_DISABLE: *p++ = 'M'; /* num bytes that will fit */ - todo = min (len, max_buf_size / 2); + todo = min (len, payload_size / 2); break; case PACKET_SUPPORT_UNKNOWN: internal_error (__FILE__, __LINE__, @@ -3772,21 +3637,26 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) default: internal_error (__FILE__, __LINE__, "bad switch"); } - - /* Append */ + + /* Append "". */ memaddr = remote_address_masked (memaddr); p += hexnumstr (p, (ULONGEST) memaddr); + + /* Append ",". */ *p++ = ','; - - /* Append . Retain the location/size of . It may - need to be adjusted once the packet body has been created. */ + + /* Append . Retain the location/size of . It may need to + be adjusted once the packet body has been created. */ plen = p; plenlen = hexnumstr (p, (ULONGEST) todo); p += plenlen; + + /* Append ":". */ *p++ = ':'; *p = '\0'; - - /* Append the packet body. */ + + /* Append the packet body. */ + payload_start = p; switch (remote_protocol_binary_download.support) { case PACKET_ENABLE: @@ -3794,7 +3664,7 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) increasing byte addresses. Only escape certain critical characters. */ for (nr_bytes = 0; - (nr_bytes < todo) && (p - buf) < (max_buf_size - 2); + (nr_bytes < todo) && (p - payload_start) < payload_size; nr_bytes++) { switch (myaddr[nr_bytes] & 0xff) @@ -3813,11 +3683,10 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) } if (nr_bytes < todo) { - /* Escape chars have filled up the buffer prematurely, + /* Escape chars have filled up the buffer prematurely, and we have actually sent fewer bytes than planned. Fix-up the length field of the packet. Use the same number of characters as before. */ - plen += hexnumnstr (plen, (ULONGEST) nr_bytes, plenlen); *plen = ':'; /* overwrite \0 from hexnumnstr() */ } @@ -3835,10 +3704,10 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) default: internal_error (__FILE__, __LINE__, "bad switch"); } - + putpkt_binary (buf, (int) (p - buf)); getpkt (buf, sizeof_buf, 0); - + if (buf[0] == 'E') { /* There is no correspondance between what the remote protocol @@ -3848,7 +3717,7 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) errno = EIO; return 0; } - + /* Return NR_BYTES, not TODO, in case escape chars caused us to send fewer bytes than we'd planned. */ return nr_bytes; @@ -3869,7 +3738,7 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) caller and its callers caller ;-) already contains code for handling partial reads. */ -static int +int remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) { char *buf; @@ -3904,7 +3773,9 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) putpkt (buf); getpkt (buf, sizeof_buf, 0); - if (buf[0] == 'E') + if (buf[0] == 'E' + && isxdigit (buf[1]) && isxdigit (buf[2]) + && buf[3] == '\0') { /* There is no correspondance between what the remote protocol uses for errors and errno codes. We would like a cleaner way of @@ -3936,7 +3807,6 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) SHOULD_WRITE is nonzero. Returns length of data written or read; 0 for error. TARGET is unused. */ -/* ARGSUSED */ static int remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len, int should_write, struct mem_attrib *attrib, @@ -3946,7 +3816,10 @@ remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len, int targ_len; int res; - REMOTE_TRANSLATE_XFER_ADDRESS (mem_addr, mem_len, &targ_addr, &targ_len); + /* Should this be the selected frame? */ + gdbarch_remote_translate_xfer_address (current_gdbarch, current_regcache, + mem_addr, mem_len, + &targ_addr, &targ_len); if (targ_len <= 0) return 0; @@ -3958,73 +3831,6 @@ remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len, return res; } - -#if 0 -/* Enable after 4.12. */ - -void -remote_search (int len, char *data, char *mask, CORE_ADDR startaddr, - int increment, CORE_ADDR lorange, CORE_ADDR hirange, - CORE_ADDR *addr_found, char *data_found) -{ - if (increment == -4 && len == 4) - { - long mask_long, data_long; - long data_found_long; - CORE_ADDR addr_we_found; - char *buf = alloca (rs->remote_packet_size); - long returned_long[2]; - char *p; - - mask_long = extract_unsigned_integer (mask, len); - data_long = extract_unsigned_integer (data, len); - sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long); - putpkt (buf); - getpkt (buf, (rs->remote_packet_size), 0); - if (buf[0] == '\0') - { - /* The stub doesn't support the 't' request. We might want to - remember this fact, but on the other hand the stub could be - switched on us. Maybe we should remember it only until - the next "target remote". */ - generic_search (len, data, mask, startaddr, increment, lorange, - hirange, addr_found, data_found); - return; - } - - if (buf[0] == 'E') - /* There is no correspondance between what the remote protocol uses - for errors and errno codes. We would like a cleaner way of - representing errors (big enough to include errno codes, bfd_error - codes, and others). But for now just use EIO. */ - memory_error (EIO, startaddr); - p = buf; - addr_we_found = 0; - while (*p != '\0' && *p != ',') - addr_we_found = (addr_we_found << 4) + fromhex (*p++); - if (*p == '\0') - error ("Protocol error: short return for search"); - - data_found_long = 0; - while (*p != '\0' && *p != ',') - data_found_long = (data_found_long << 4) + fromhex (*p++); - /* Ignore anything after this comma, for future extensions. */ - - if (addr_we_found < lorange || addr_we_found >= hirange) - { - *addr_found = 0; - return; - } - - *addr_found = addr_we_found; - *data_found = store_unsigned_integer (data_we_found, len); - return; - } - generic_search (len, data, mask, startaddr, increment, lorange, - hirange, addr_found, data_found); -} -#endif /* 0 */ - static void remote_files_info (struct target_ops *ignore) { @@ -4217,8 +4023,6 @@ putpkt_binary (char *buf, int cnt) } } -static int remote_cisco_mode; - /* Come here after finding the start of the frame. Collect the rest into BUF, verifying the checksum, length, and handling run-length compression. No more than sizeof_buf-1 characters are read so that @@ -4265,7 +4069,7 @@ read_frame (char *buf, check_0 = readchar (remote_timeout); if (check_0 >= 0) check_1 = readchar (remote_timeout); - + if (check_0 == SERIAL_TIMEOUT || check_1 == SERIAL_TIMEOUT) { if (remote_debug) @@ -4300,28 +4104,13 @@ read_frame (char *buf, int repeat; csum += c; - if (remote_cisco_mode == 0) - { - c = readchar (remote_timeout); - csum += c; - repeat = c - ' ' + 3; /* Compute repeat count */ - } - else - { - /* Cisco's run-length encoding variant uses two - hex chars to represent the repeat count. */ - - c = readchar (remote_timeout); - csum += c; - repeat = fromhex (c) << 4; - c = readchar (remote_timeout); - csum += c; - repeat += fromhex (c); - } + c = readchar (remote_timeout); + csum += c; + repeat = c - ' ' + 3; /* Compute repeat count */ /* The character before ``*'' is repeated. */ - if (repeat > 0 && repeat <= 255 + if (repeat > 0 && repeat <= 255 && bc > 0 && bc + repeat - 1 < sizeof_buf - 1) { @@ -4522,7 +4311,7 @@ extended_remote_mourn (void) { /* We do _not_ want to mourn the target like this; this will remove the extended remote target from the target stack, - and the next time the user says "run" it'll fail. + and the next time the user says "run" it'll fail. FIXME: What is the right thing to do here? */ #if 0 @@ -4540,7 +4329,7 @@ remote_mourn_1 (struct target_ops *target) /* In the extended protocol we want to be able to do things like "run" and have them basically work as expected. So we need - a special create_inferior function. + a special create_inferior function. FIXME: One day add support for changing the exec file we're debugging, arguments and an environment. */ @@ -4594,61 +4383,62 @@ extended_remote_async_create_inferior (char *exec_file, char *args, char **env) } -/* On some machines, e.g. 68k, we may use a different breakpoint instruction - than other targets; in those use REMOTE_BREAKPOINT instead of just - BREAKPOINT. Also, bi-endian targets may define LITTLE_REMOTE_BREAKPOINT - and BIG_REMOTE_BREAKPOINT. If none of these are defined, we just call - the standard routines that are in mem-break.c. */ +/* On some machines, e.g. 68k, we may use a different breakpoint + instruction than other targets; in those use + DEPRECATED_REMOTE_BREAKPOINT instead of just BREAKPOINT_FROM_PC. + Also, bi-endian targets may define + DEPRECATED_LITTLE_REMOTE_BREAKPOINT and + DEPRECATED_BIG_REMOTE_BREAKPOINT. If none of these are defined, we + just call the standard routines that are in mem-break.c. */ -/* FIXME, these ought to be done in a more dynamic fashion. For instance, - the choice of breakpoint instruction affects target program design and - vice versa, and by making it user-tweakable, the special code here - goes away and we need fewer special GDB configurations. */ +/* NOTE: cagney/2003-06-08: This is silly. A remote and simulator + target should use an identical BREAKPOINT_FROM_PC. As for native, + the ARCH-OS-tdep.c code can override the default. */ -#if defined (LITTLE_REMOTE_BREAKPOINT) && defined (BIG_REMOTE_BREAKPOINT) && !defined(REMOTE_BREAKPOINT) -#define REMOTE_BREAKPOINT +#if defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && defined (DEPRECATED_BIG_REMOTE_BREAKPOINT) && !defined(DEPRECATED_REMOTE_BREAKPOINT) +#define DEPRECATED_REMOTE_BREAKPOINT #endif -#ifdef REMOTE_BREAKPOINT +#ifdef DEPRECATED_REMOTE_BREAKPOINT /* If the target isn't bi-endian, just pretend it is. */ -#if !defined (LITTLE_REMOTE_BREAKPOINT) && !defined (BIG_REMOTE_BREAKPOINT) -#define LITTLE_REMOTE_BREAKPOINT REMOTE_BREAKPOINT -#define BIG_REMOTE_BREAKPOINT REMOTE_BREAKPOINT +#if !defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && !defined (DEPRECATED_BIG_REMOTE_BREAKPOINT) +#define DEPRECATED_LITTLE_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT +#define DEPRECATED_BIG_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT #endif -static unsigned char big_break_insn[] = BIG_REMOTE_BREAKPOINT; -static unsigned char little_break_insn[] = LITTLE_REMOTE_BREAKPOINT; +static unsigned char big_break_insn[] = DEPRECATED_BIG_REMOTE_BREAKPOINT; +static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT; -#endif /* REMOTE_BREAKPOINT */ +#endif /* DEPRECATED_REMOTE_BREAKPOINT */ -/* Insert a breakpoint on targets that don't have any better breakpoint - support. We read the contents of the target location and stash it, - then overwrite it with a breakpoint instruction. ADDR is the target - location in the target machine. CONTENTS_CACHE is a pointer to - memory allocated for saving the target contents. It is guaranteed - by the caller to be long enough to save sizeof BREAKPOINT bytes (this - is accomplished via BREAKPOINT_MAX). */ +/* Insert a breakpoint on targets that don't have any better + breakpoint support. We read the contents of the target location + and stash it, then overwrite it with a breakpoint instruction. + ADDR is the target location in the target machine. CONTENTS_CACHE + is a pointer to memory allocated for saving the target contents. + It is guaranteed by the caller to be long enough to save the number + of bytes returned by BREAKPOINT_FROM_PC. */ static int remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache) { struct remote_state *rs = get_remote_state (); -#ifdef REMOTE_BREAKPOINT +#ifdef DEPRECATED_REMOTE_BREAKPOINT int val; -#endif +#endif int bp_size; /* Try the "Z" s/w breakpoint packet if it is not already disabled. If it succeeds, then set the support to PACKET_ENABLE. If it fails, and the user has explicitly requested the Z support then report an error, otherwise, mark it disabled and go on. */ - + if (remote_protocol_Z[Z_PACKET_SOFTWARE_BP].support != PACKET_DISABLE) { char *buf = alloca (rs->remote_packet_size); char *p = buf; - + addr = remote_address_masked (addr); *(p++) = 'Z'; *(p++) = '0'; @@ -4656,7 +4446,7 @@ remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache) p += hexnumstr (p, (ULONGEST) addr); BREAKPOINT_FROM_PC (&addr, &bp_size); sprintf (p, ",%d", bp_size); - + putpkt (buf); getpkt (buf, (rs->remote_packet_size), 0); @@ -4671,7 +4461,7 @@ remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache) } } -#ifdef REMOTE_BREAKPOINT +#ifdef DEPRECATED_REMOTE_BREAKPOINT val = target_read_memory (addr, contents_cache, sizeof big_break_insn); if (val == 0) @@ -4687,7 +4477,7 @@ remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache) return val; #else return memory_insert_breakpoint (addr, contents_cache); -#endif /* REMOTE_BREAKPOINT */ +#endif /* DEPRECATED_REMOTE_BREAKPOINT */ } static int @@ -4700,7 +4490,7 @@ remote_remove_breakpoint (CORE_ADDR addr, char *contents_cache) { char *buf = alloca (rs->remote_packet_size); char *p = buf; - + *(p++) = 'z'; *(p++) = '0'; *(p++) = ','; @@ -4709,18 +4499,18 @@ remote_remove_breakpoint (CORE_ADDR addr, char *contents_cache) p += hexnumstr (p, (ULONGEST) addr); BREAKPOINT_FROM_PC (&addr, &bp_size); sprintf (p, ",%d", bp_size); - + putpkt (buf); getpkt (buf, (rs->remote_packet_size), 0); return (buf[0] == 'E'); } -#ifdef REMOTE_BREAKPOINT +#ifdef DEPRECATED_REMOTE_BREAKPOINT return target_write_memory (addr, contents_cache, sizeof big_break_insn); #else return memory_remove_breakpoint (addr, contents_cache); -#endif /* REMOTE_BREAKPOINT */ +#endif /* DEPRECATED_REMOTE_BREAKPOINT */ } static int @@ -4743,10 +4533,7 @@ watchpoint_to_Z_packet (int type) } } -/* FIXME: This function should be static and a member of the remote - target vector. */ - -int +static int remote_insert_watchpoint (CORE_ADDR addr, int len, int type) { struct remote_state *rs = get_remote_state (); @@ -4758,13 +4545,13 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type) error ("Can't set hardware watchpoints without the '%s' (%s) packet\n", remote_protocol_Z[packet].name, remote_protocol_Z[packet].title); - + sprintf (buf, "Z%x,", packet); p = strchr (buf, '\0'); addr = remote_address_masked (addr); p += hexnumstr (p, (ULONGEST) addr); sprintf (p, ",%x", len); - + putpkt (buf); getpkt (buf, (rs->remote_packet_size), 0); @@ -4780,10 +4567,8 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type) "remote_insert_watchpoint: reached end of function"); } -/* FIXME: This function should be static and a member of the remote - target vector. */ -int +static int remote_remove_watchpoint (CORE_ADDR addr, int len, int type) { struct remote_state *rs = get_remote_state (); @@ -4795,7 +4580,7 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type) error ("Can't clear hardware watchpoints without the '%s' (%s) packet\n", remote_protocol_Z[packet].name, remote_protocol_Z[packet].title); - + sprintf (buf, "z%x,", packet); p = strchr (buf, '\0'); addr = remote_address_masked (addr); @@ -4816,25 +4601,73 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type) "remote_remove_watchpoint: reached end of function"); } -/* FIXME: This function should be static and a member of the remote - target vector. */ -int -remote_insert_hw_breakpoint (CORE_ADDR addr, int len) +int remote_hw_watchpoint_limit = -1; +int remote_hw_breakpoint_limit = -1; + +static int +remote_check_watch_resources (int type, int cnt, int ot) { + if (type == bp_hardware_breakpoint) + { + if (remote_hw_breakpoint_limit == 0) + return 0; + else if (remote_hw_breakpoint_limit < 0) + return 1; + else if (cnt <= remote_hw_breakpoint_limit) + return 1; + } + else + { + if (remote_hw_watchpoint_limit == 0) + return 0; + else if (remote_hw_watchpoint_limit < 0) + return 1; + else if (ot) + return -1; + else if (cnt <= remote_hw_watchpoint_limit) + return 1; + } + return -1; +} + +static int +remote_stopped_by_watchpoint (void) +{ + return remote_stopped_by_watchpoint_p; +} + +static CORE_ADDR +remote_stopped_data_address (void) +{ + if (remote_stopped_by_watchpoint ()) + return remote_watch_data_address; + return (CORE_ADDR)0; +} + + +static int +remote_insert_hw_breakpoint (CORE_ADDR addr, char *shadow) +{ + int len = 0; struct remote_state *rs = get_remote_state (); char *buf = alloca (rs->remote_packet_size); char *p = buf; - + + /* The length field should be set to the size of a breakpoint + instruction. */ + + BREAKPOINT_FROM_PC (&addr, &len); + if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE) error ("Can't set hardware breakpoint without the '%s' (%s) packet\n", remote_protocol_Z[Z_PACKET_HARDWARE_BP].name, remote_protocol_Z[Z_PACKET_HARDWARE_BP].title); - + *(p++) = 'Z'; *(p++) = '1'; *(p++) = ','; - + addr = remote_address_masked (addr); p += hexnumstr (p, (ULONGEST) addr); sprintf (p, ",%x", len); @@ -4851,35 +4684,39 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, int len) return 0; } internal_error (__FILE__, __LINE__, - "remote_remove_watchpoint: reached end of function"); + "remote_insert_hw_breakpoint: reached end of function"); } -/* FIXME: This function should be static and a member of the remote - target vector. */ -int -remote_remove_hw_breakpoint (CORE_ADDR addr, int len) +static int +remote_remove_hw_breakpoint (CORE_ADDR addr, char *shadow) { + int len; struct remote_state *rs = get_remote_state (); char *buf = alloca (rs->remote_packet_size); char *p = buf; - + + /* The length field should be set to the size of a breakpoint + instruction. */ + + BREAKPOINT_FROM_PC (&addr, &len); + if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE) error ("Can't clear hardware breakpoint without the '%s' (%s) packet\n", remote_protocol_Z[Z_PACKET_HARDWARE_BP].name, remote_protocol_Z[Z_PACKET_HARDWARE_BP].title); - + *(p++) = 'z'; *(p++) = '1'; *(p++) = ','; - + addr = remote_address_masked (addr); p += hexnumstr (p, (ULONGEST) addr); sprintf (p, ",%x", len); putpkt(buf); getpkt (buf, (rs->remote_packet_size), 0); - + switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_HARDWARE_BP])) { case PACKET_ERROR: @@ -4889,7 +4726,7 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, int len) return 0; } internal_error (__FILE__, __LINE__, - "remote_remove_watchpoint: reached end of function"); + "remote_remove_hw_breakpoint: reached end of function"); } /* Some targets are only capable of doing downloads, and afterwards @@ -4909,18 +4746,6 @@ push_remote_target (char *name, int from_tty) remote_open (name, from_tty); } -/* Other targets want to use the entire remote serial module but with - certain remote_ops overridden. */ - -void -open_remote_target (char *name, int from_tty, struct target_ops *target, - int extended_p) -{ - printf_filtered ("Selecting the %sremote protocol\n", - (extended_p ? "extended-" : "")); - remote_open_1 (name, from_tty, target, extended_p); -} - /* Table used by the crc32 function to calcuate the checksum. */ static unsigned long crc32_table[256] = @@ -5013,8 +4838,8 @@ compare_sections_command (char *args, int from_tty) getpkt (buf, (rs->remote_packet_size), 0); if (buf[0] == 'E') - error ("target memory fault, section %s, range 0x%08x -- 0x%08x", - sectname, lma, lma + size); + error ("target memory fault, section %s, range 0x%s -- 0x%s", + sectname, paddr (lma), paddr (lma + size)); if (buf[0] != 'C') error ("remote target does not support this operation"); @@ -5040,41 +4865,86 @@ the loaded file\n"); printf_filtered ("No loaded section named '%s'.\n", args); } -static int -remote_query (int query_type, char *buf, char *outbuf, int *bufsiz) +static LONGEST +remote_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, const void *writebuf, + ULONGEST offset, LONGEST len) { struct remote_state *rs = get_remote_state (); int i; char *buf2 = alloca (rs->remote_packet_size); char *p2 = &buf2[0]; + char query_type; - if (!bufsiz) - error ("null pointer to remote bufer size specified"); + /* Only handle reads. */ + if (writebuf != NULL || readbuf == NULL) + return -1; - /* minimum outbuf size is (rs->remote_packet_size) - if bufsiz is not large enough let - the caller know and return what the minimum size is */ - /* Note: a zero bufsiz can be used to query the minimum buffer size */ - if (*bufsiz < (rs->remote_packet_size)) + /* Map pre-existing objects onto letters. DO NOT do this for new + objects!!! Instead specify new query packets. */ + switch (object) { - *bufsiz = (rs->remote_packet_size); + case TARGET_OBJECT_KOD: + query_type = 'K'; + break; + case TARGET_OBJECT_AVR: + query_type = 'R'; + break; + + case TARGET_OBJECT_AUXV: + if (remote_protocol_qPart_auxv.support != PACKET_DISABLE) + { + unsigned int total = 0; + while (len > 0) + { + LONGEST n = min ((rs->remote_packet_size - 2) / 2, len); + snprintf (buf2, rs->remote_packet_size, + "qPart:auxv:read::%s,%s", + phex_nz (offset, sizeof offset), + phex_nz (n, sizeof n)); + i = putpkt (buf2); + if (i < 0) + return total > 0 ? total : i; + buf2[0] = '\0'; + getpkt (buf2, rs->remote_packet_size, 0); + if (packet_ok (buf2, &remote_protocol_qPart_auxv) != PACKET_OK) + return total > 0 ? total : -1; + if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0') + break; /* Got EOF indicator. */ + /* Got some data. */ + i = hex2bin (buf2, readbuf, len); + if (i > 0) + { + readbuf = (void *) ((char *) readbuf + i); + offset += i; + len -= i; + total += i; + } + } + return total; + } + return -1; + + default: return -1; } + /* Note: a zero OFFSET and LEN can be used to query the minimum + buffer size. */ + if (offset == 0 && len == 0) + return (rs->remote_packet_size); + /* Minimum outbuf size is (rs->remote_packet_size) - if bufsiz is + not large enough let the caller. */ + if (len < (rs->remote_packet_size)) + return -1; + len = rs->remote_packet_size; + /* except for querying the minimum buffer size, target must be open */ if (!remote_desc) error ("remote query is only available after target open"); - /* we only take uppercase letters as query types, at least for now */ - if ((query_type < 'A') || (query_type > 'Z')) - error ("invalid remote query type"); - - if (!buf) - error ("null remote query specified"); - - if (!outbuf) - error ("remote query requires a buffer to receive data"); - - outbuf[0] = '\0'; + gdb_assert (annex != NULL); + gdb_assert (readbuf != NULL); *p2++ = 'q'; *p2++ = query_type; @@ -5084,27 +4954,23 @@ remote_query (int query_type, char *buf, char *outbuf, int *bufsiz) plus one extra in case we are debugging (remote_debug), we have PBUFZIZ - 7 left to pack the query string */ i = 0; - while (buf[i] && (i < ((rs->remote_packet_size) - 8))) + while (annex[i] && (i < ((rs->remote_packet_size) - 8))) { - /* bad caller may have sent forbidden characters */ - if ((!isprint (buf[i])) || (buf[i] == '$') || (buf[i] == '#')) - error ("illegal characters in query string"); - - *p2++ = buf[i]; + /* Bad caller may have sent forbidden characters. */ + gdb_assert (isprint (annex[i]) && annex[i] != '$' && annex[i] != '#'); + *p2++ = annex[i]; i++; } - *p2 = buf[i]; - - if (buf[i]) - error ("query larger than available buffer"); + *p2 = '\0'; + gdb_assert (annex[i] == '\0'); i = putpkt (buf2); if (i < 0) return i; - getpkt (outbuf, *bufsiz, 0); + getpkt (readbuf, len, 0); - return 0; + return strlen (readbuf); } static void @@ -5357,6 +5223,7 @@ Specify the serial device it is connected to\n\ remote_ops.to_open = remote_open; remote_ops.to_close = remote_close; remote_ops.to_detach = remote_detach; + remote_ops.to_disconnect = remote_disconnect; remote_ops.to_resume = remote_resume; remote_ops.to_wait = remote_wait; remote_ops.to_fetch_registers = remote_fetch_registers; @@ -5366,6 +5233,13 @@ Specify the serial device it is connected to\n\ remote_ops.to_files_info = remote_files_info; remote_ops.to_insert_breakpoint = remote_insert_breakpoint; remote_ops.to_remove_breakpoint = remote_remove_breakpoint; + remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; + remote_ops.to_stopped_data_address = remote_stopped_data_address; + remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources; + remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint; + remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint; + remote_ops.to_insert_watchpoint = remote_insert_watchpoint; + remote_ops.to_remove_watchpoint = remote_remove_watchpoint; remote_ops.to_kill = remote_kill; remote_ops.to_load = generic_load; remote_ops.to_mourn_inferior = remote_mourn; @@ -5374,7 +5248,7 @@ Specify the serial device it is connected to\n\ remote_ops.to_pid_to_str = remote_pid_to_str; remote_ops.to_extra_thread_info = remote_threads_extra_info; remote_ops.to_stop = remote_stop; - remote_ops.to_query = remote_query; + remote_ops.to_xfer_partial = remote_xfer_partial; remote_ops.to_rcmd = remote_rcmd; remote_ops.to_stratum = process_stratum; remote_ops.to_has_all_memory = 1; @@ -5405,394 +5279,6 @@ Specify the serial device it is connected to (e.g. /dev/ttya).", extended_remote_ops.to_mourn_inferior = extended_remote_mourn; } -/* - * Command: info remote-process - * - * This implements Cisco's version of the "info proc" command. - * - * This query allows the target stub to return an arbitrary string - * (or strings) giving arbitrary information about the target process. - * This is optional; the target stub isn't required to implement it. - * - * Syntax: qfProcessInfo request first string - * qsProcessInfo request subsequent string - * reply: 'O' - * 'l' last reply (empty) - */ - -static void -remote_info_process (char *args, int from_tty) -{ - struct remote_state *rs = get_remote_state (); - char *buf = alloca (rs->remote_packet_size); - - if (remote_desc == 0) - error ("Command can only be used when connected to the remote target."); - - putpkt ("qfProcessInfo"); - getpkt (buf, (rs->remote_packet_size), 0); - if (buf[0] == 0) - return; /* Silently: target does not support this feature. */ - - if (buf[0] == 'E') - error ("info proc: target error."); - - while (buf[0] == 'O') /* Capitol-O packet */ - { - remote_console_output (&buf[1]); - putpkt ("qsProcessInfo"); - getpkt (buf, (rs->remote_packet_size), 0); - } -} - -/* - * Target Cisco - */ - -static void -remote_cisco_open (char *name, int from_tty) -{ - if (name == 0) - error ("To open a remote debug connection, you need to specify what \n" - "device is attached to the remote system (e.g. host:port)."); - - /* See FIXME above */ - wait_forever_enabled_p = 1; - - target_preopen (from_tty); - - unpush_target (&remote_cisco_ops); - - remote_desc = serial_open (name); - if (!remote_desc) - perror_with_name (name); - - /* - * If a baud rate was specified on the gdb command line it will - * be greater than the initial value of -1. If it is, use it otherwise - * default to 9600 - */ - - baud_rate = (baud_rate > 0) ? baud_rate : 9600; - if (serial_setbaudrate (remote_desc, baud_rate)) - { - serial_close (remote_desc); - perror_with_name (name); - } - - serial_raw (remote_desc); - - /* If there is something sitting in the buffer we might take it as a - response to a command, which would be bad. */ - serial_flush_input (remote_desc); - - if (from_tty) - { - puts_filtered ("Remote debugging using "); - puts_filtered (name); - puts_filtered ("\n"); - } - - remote_cisco_mode = 1; - - push_target (&remote_cisco_ops); /* Switch to using cisco target now */ - - init_all_packet_configs (); - - general_thread = -2; - continue_thread = -2; - - /* Probe for ability to use "ThreadInfo" query, as required. */ - use_threadinfo_query = 1; - use_threadextra_query = 1; - - /* Without this, some commands which require an active target (such - as kill) won't work. This variable serves (at least) double duty - as both the pid of the target process (if it has such), and as a - flag indicating that a target is active. These functions should - be split out into seperate variables, especially since GDB will - someday have a notion of debugging several processes. */ - inferior_ptid = pid_to_ptid (MAGIC_NULL_PID); - - /* Start the remote connection; if error (0), discard this target. */ - - if (!catch_errors (remote_start_remote_dummy, (char *) 0, - "Couldn't establish connection to remote target\n", - RETURN_MASK_ALL)) - { - pop_target (); - return; - } -} - -static void -remote_cisco_close (int quitting) -{ - remote_cisco_mode = 0; - remote_close (quitting); -} - -static void -remote_cisco_mourn (void) -{ - remote_mourn_1 (&remote_cisco_ops); -} - -enum -{ - READ_MORE, - FATAL_ERROR, - ENTER_DEBUG, - DISCONNECT_TELNET -} -minitelnet_return; - -/* Shared between readsocket() and readtty(). The size is arbitrary, - however all targets are known to support a 400 character packet. */ -static char tty_input[400]; - -static int escape_count; -static int echo_check; -extern int quit_flag; - -static int -readsocket (void) -{ - int data; - - /* Loop until the socket doesn't have any more data */ - - while ((data = readchar (0)) >= 0) - { - /* Check for the escape sequence */ - if (data == '|') - { - /* If this is the fourth escape, get out */ - if (++escape_count == 4) - { - return ENTER_DEBUG; - } - else - { /* This is a '|', but not the fourth in a row. - Continue without echoing it. If it isn't actually - one of four in a row, it'll be echoed later. */ - continue; - } - } - else - /* Not a '|' */ - { - /* Ensure any pending '|'s are flushed. */ - - for (; escape_count > 0; escape_count--) - putchar ('|'); - } - - if (data == '\r') /* If this is a return character, */ - continue; /* - just supress it. */ - - if (echo_check != -1) /* Check for echo of user input. */ - { - if (tty_input[echo_check] == data) - { - gdb_assert (echo_check <= sizeof (tty_input)); - echo_check++; /* Character matched user input: */ - continue; /* Continue without echoing it. */ - } - else if ((data == '\n') && (tty_input[echo_check] == '\r')) - { /* End of the line (and of echo checking). */ - echo_check = -1; /* No more echo supression */ - continue; /* Continue without echoing. */ - } - else - { /* Failed check for echo of user input. - We now have some suppressed output to flush! */ - int j; - - for (j = 0; j < echo_check; j++) - putchar (tty_input[j]); - echo_check = -1; - } - } - putchar (data); /* Default case: output the char. */ - } - - if (data == SERIAL_TIMEOUT) /* Timeout returned from readchar. */ - return READ_MORE; /* Try to read some more */ - else - return FATAL_ERROR; /* Trouble, bail out */ -} - -static int -readtty (void) -{ - int tty_bytecount; - - /* First, read a buffer full from the terminal */ - tty_bytecount = read (fileno (stdin), tty_input, sizeof (tty_input) - 1); - if (tty_bytecount == -1) - { - perror ("readtty: read failed"); - return FATAL_ERROR; - } - - /* Remove a quoted newline. */ - if (tty_input[tty_bytecount - 1] == '\n' && - tty_input[tty_bytecount - 2] == '\\') /* line ending in backslash */ - { - tty_input[--tty_bytecount] = 0; /* remove newline */ - tty_input[--tty_bytecount] = 0; /* remove backslash */ - } - - /* Turn trailing newlines into returns */ - if (tty_input[tty_bytecount - 1] == '\n') - tty_input[tty_bytecount - 1] = '\r'; - - /* If the line consists of a ~, enter debugging mode. */ - if ((tty_input[0] == '~') && (tty_bytecount == 2)) - return ENTER_DEBUG; - - /* Make this a zero terminated string and write it out */ - tty_input[tty_bytecount] = 0; - if (serial_write (remote_desc, tty_input, tty_bytecount)) - { - perror_with_name ("readtty: write failed"); - return FATAL_ERROR; - } - - return READ_MORE; -} - -static int -minitelnet (void) -{ - fd_set input; /* file descriptors for select */ - int tablesize; /* max number of FDs for select */ - int status; - int quit_count = 0; - - extern int escape_count; /* global shared by readsocket */ - extern int echo_check; /* ditto */ - - escape_count = 0; - echo_check = -1; - - tablesize = 8 * sizeof (input); - - for (;;) - { - /* Check for anything from our socket - doesn't block. Note that - this must be done *before* the select as there may be - buffered I/O waiting to be processed. */ - - if ((status = readsocket ()) == FATAL_ERROR) - { - error ("Debugging terminated by communications error"); - } - else if (status != READ_MORE) - { - return (status); - } - - fflush (stdout); /* Flush output before blocking */ - - /* Now block on more socket input or TTY input */ - - FD_ZERO (&input); - FD_SET (fileno (stdin), &input); - FD_SET (deprecated_serial_fd (remote_desc), &input); - - status = select (tablesize, &input, 0, 0, 0); - if ((status == -1) && (errno != EINTR)) - { - error ("Communications error on select %d", errno); - } - - /* Handle Control-C typed */ - - if (quit_flag) - { - if ((++quit_count) == 2) - { - if (query ("Interrupt GDB? ")) - { - printf_filtered ("Interrupted by user.\n"); - throw_exception (RETURN_QUIT); - } - quit_count = 0; - } - quit_flag = 0; - - if (remote_break) - serial_send_break (remote_desc); - else - serial_write (remote_desc, "\003", 1); - - continue; - } - - /* Handle console input */ - - if (FD_ISSET (fileno (stdin), &input)) - { - quit_count = 0; - echo_check = 0; - status = readtty (); - if (status == READ_MORE) - continue; - - return status; /* telnet session ended */ - } - } -} - -static ptid_t -remote_cisco_wait (ptid_t ptid, struct target_waitstatus *status) -{ - if (minitelnet () != ENTER_DEBUG) - { - error ("Debugging session terminated by protocol error"); - } - putpkt ("?"); - return remote_wait (ptid, status); -} - -static void -init_remote_cisco_ops (void) -{ - remote_cisco_ops.to_shortname = "cisco"; - remote_cisco_ops.to_longname = "Remote serial target in cisco-specific protocol"; - remote_cisco_ops.to_doc = - "Use a remote machine via TCP, using a cisco-specific protocol.\n\ -Specify the serial device it is connected to (e.g. host:2020)."; - remote_cisco_ops.to_open = remote_cisco_open; - remote_cisco_ops.to_close = remote_cisco_close; - remote_cisco_ops.to_detach = remote_detach; - remote_cisco_ops.to_resume = remote_resume; - remote_cisco_ops.to_wait = remote_cisco_wait; - remote_cisco_ops.to_fetch_registers = remote_fetch_registers; - remote_cisco_ops.to_store_registers = remote_store_registers; - remote_cisco_ops.to_prepare_to_store = remote_prepare_to_store; - remote_cisco_ops.to_xfer_memory = remote_xfer_memory; - remote_cisco_ops.to_files_info = remote_files_info; - remote_cisco_ops.to_insert_breakpoint = remote_insert_breakpoint; - remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint; - remote_cisco_ops.to_kill = remote_kill; - remote_cisco_ops.to_load = generic_load; - remote_cisco_ops.to_mourn_inferior = remote_cisco_mourn; - remote_cisco_ops.to_thread_alive = remote_thread_alive; - remote_cisco_ops.to_find_new_threads = remote_threads_info; - remote_cisco_ops.to_pid_to_str = remote_pid_to_str; - remote_cisco_ops.to_extra_thread_info = remote_threads_extra_info; - remote_cisco_ops.to_stratum = process_stratum; - remote_cisco_ops.to_has_all_memory = 1; - remote_cisco_ops.to_has_memory = 1; - remote_cisco_ops.to_has_stack = 1; - remote_cisco_ops.to_has_registers = 1; - remote_cisco_ops.to_has_execution = 1; - remote_cisco_ops.to_magic = OPS_MAGIC; -} - static int remote_can_async_p (void) { @@ -5856,7 +5342,8 @@ init_remote_async_ops (void) Specify the serial device it is connected to (e.g. /dev/ttya)."; remote_async_ops.to_open = remote_async_open; remote_async_ops.to_close = remote_close; - remote_async_ops.to_detach = remote_async_detach; + remote_async_ops.to_detach = remote_detach; + remote_async_ops.to_disconnect = remote_disconnect; remote_async_ops.to_resume = remote_async_resume; remote_async_ops.to_wait = remote_async_wait; remote_async_ops.to_fetch_registers = remote_fetch_registers; @@ -5866,6 +5353,13 @@ Specify the serial device it is connected to (e.g. /dev/ttya)."; remote_async_ops.to_files_info = remote_files_info; remote_async_ops.to_insert_breakpoint = remote_insert_breakpoint; remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint; + remote_async_ops.to_can_use_hw_breakpoint = remote_check_watch_resources; + remote_async_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint; + remote_async_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint; + remote_async_ops.to_insert_watchpoint = remote_insert_watchpoint; + remote_async_ops.to_remove_watchpoint = remote_remove_watchpoint; + remote_async_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; + remote_async_ops.to_stopped_data_address = remote_stopped_data_address; remote_async_ops.to_terminal_inferior = remote_async_terminal_inferior; remote_async_ops.to_terminal_ours = remote_async_terminal_ours; remote_async_ops.to_kill = remote_async_kill; @@ -5876,7 +5370,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya)."; remote_async_ops.to_pid_to_str = remote_pid_to_str; remote_async_ops.to_extra_thread_info = remote_threads_extra_info; remote_async_ops.to_stop = remote_stop; - remote_async_ops.to_query = remote_query; + remote_async_ops.to_xfer_partial = remote_xfer_partial; remote_async_ops.to_rcmd = remote_rcmd; remote_async_ops.to_stratum = process_stratum; remote_async_ops.to_has_all_memory = 1; @@ -5919,13 +5413,16 @@ set_remote_cmd (char *args, int from_tty) static void show_remote_cmd (char *args, int from_tty) { - - show_remote_protocol_Z_packet_cmd (args, from_tty); - show_remote_protocol_e_packet_cmd (args, from_tty); - show_remote_protocol_E_packet_cmd (args, from_tty); - show_remote_protocol_P_packet_cmd (args, from_tty); - show_remote_protocol_qSymbol_packet_cmd (args, from_tty); - show_remote_protocol_binary_download_cmd (args, from_tty); + /* FIXME: cagney/2002-06-15: This function should iterate over + remote_show_cmdlist for a list of sub commands to show. */ + show_remote_protocol_Z_packet_cmd (args, from_tty, NULL); + show_remote_protocol_e_packet_cmd (args, from_tty, NULL); + show_remote_protocol_E_packet_cmd (args, from_tty, NULL); + show_remote_protocol_P_packet_cmd (args, from_tty, NULL); + show_remote_protocol_qSymbol_packet_cmd (args, from_tty, NULL); + show_remote_protocol_vcont_packet_cmd (args, from_tty, NULL); + show_remote_protocol_binary_download_cmd (args, from_tty, NULL); + show_remote_protocol_qPart_auxv_packet_cmd (args, from_tty, NULL); } static void @@ -5959,14 +5456,12 @@ _initialize_remote (void) struct cmd_list_element *tmpcmd; /* architecture specific data */ - remote_gdbarch_data_handle = register_gdbarch_data (init_remote_state, - free_remote_state); + remote_gdbarch_data_handle = register_gdbarch_data (init_remote_state); /* Old tacky stuff. NOTE: This comes after the remote protocol so that the remote protocol has been initialized. */ - register_gdbarch_swap (&remote_address_size, - sizeof (&remote_address_size), NULL); - register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data); + DEPRECATED_REGISTER_GDBARCH_SWAP (remote_address_size); + deprecated_register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data); init_remote_ops (); add_target (&remote_ops); @@ -5980,9 +5475,6 @@ _initialize_remote (void) init_extended_async_remote_ops (); add_target (&extended_async_remote_ops); - init_remote_cisco_ops (); - add_target (&remote_cisco_ops); - /* Hook into new objfile notification. */ remote_new_objfile_chain = target_new_objfile_hook; target_new_objfile_hook = remote_new_objfile; @@ -6020,11 +5512,11 @@ response packet. GDB supplies the initial `$' character, and the\n\ terminating `#' character and checksum.", &maintenancelist); - add_show_from_set - (add_set_boolean_cmd ("remotebreak", no_class, &remote_break, - "Set whether to send break if interrupted.\n", - &setlist), - &showlist); + add_setshow_boolean_cmd ("remotebreak", no_class, &remote_break, + "Set whether to send break if interrupted.\n", + "Show whether to send break if interrupted.\n", + NULL, NULL, + &setlist, &showlist); /* Install commands for configuring memory read/write packets. */ @@ -6059,6 +5551,19 @@ terminating `#' character and checksum.", "Show the maximum number of bytes per memory-read packet.\n", &remote_show_cmdlist); + add_setshow_cmd ("hardware-watchpoint-limit", no_class, + var_zinteger, &remote_hw_watchpoint_limit, "\ +Set the maximum number of target hardware watchpoints.\n\ +Specify a negative limit for unlimited.", "\ +Show the maximum number of target hardware watchpoints.\n", + NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist); + add_setshow_cmd ("hardware-breakpoint-limit", no_class, + var_zinteger, &remote_hw_breakpoint_limit, "\ +Set the maximum number of target hardware breakpoints.\n\ +Specify a negative limit for unlimited.", "\ +Show the maximum number of target hardware breakpoints.\n", + NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist); + add_show_from_set (add_set_cmd ("remoteaddresssize", class_obscure, var_integer, (char *) &remote_address_size, @@ -6083,8 +5588,12 @@ in a memory packet.\n", &showlist); #endif - add_info ("remote-process", remote_info_process, - "Query the remote system for process info."); + add_packet_config_cmd (&remote_protocol_vcont, + "vCont", "verbose-resume", + set_remote_protocol_vcont_packet_cmd, + show_remote_protocol_vcont_packet_cmd, + &remote_set_cmdlist, &remote_show_cmdlist, + 0); add_packet_config_cmd (&remote_protocol_qSymbol, "qSymbol", "symbol-lookup", @@ -6101,7 +5610,7 @@ in a memory packet.\n", 0); /* Disable by default. The ``e'' packet has nasty interactions with the threading code - it relies on global state. */ - remote_protocol_e.detect = CMD_AUTO_BOOLEAN_FALSE; + remote_protocol_e.detect = AUTO_BOOLEAN_FALSE; update_packet_config (&remote_protocol_e); add_packet_config_cmd (&remote_protocol_E, @@ -6112,7 +5621,7 @@ in a memory packet.\n", 0); /* Disable by default. The ``e'' packet has nasty interactions with the threading code - it relies on global state. */ - remote_protocol_E.detect = CMD_AUTO_BOOLEAN_FALSE; + remote_protocol_E.detect = AUTO_BOOLEAN_FALSE; update_packet_config (&remote_protocol_E); add_packet_config_cmd (&remote_protocol_P, @@ -6157,13 +5666,22 @@ in a memory packet.\n", &remote_set_cmdlist, &remote_show_cmdlist, 0); + add_packet_config_cmd (&remote_protocol_qPart_auxv, + "qPart_auxv", "read-aux-vector", + set_remote_protocol_qPart_auxv_packet_cmd, + show_remote_protocol_qPart_auxv_packet_cmd, + &remote_set_cmdlist, &remote_show_cmdlist, + 0); + /* Keep the old ``set remote Z-packet ...'' working. */ - tmpcmd = add_set_auto_boolean_cmd ("Z-packet", class_obscure, - &remote_Z_packet_detect, - "\ -Set use of remote protocol `Z' packets", &remote_set_cmdlist); - set_cmd_sfunc (tmpcmd, set_remote_protocol_Z_packet_cmd); - add_cmd ("Z-packet", class_obscure, show_remote_protocol_Z_packet_cmd, - "Show use of remote protocol `Z' packets ", - &remote_show_cmdlist); + add_setshow_auto_boolean_cmd ("Z-packet", class_obscure, + &remote_Z_packet_detect, "\ +Set use of remote protocol `Z' packets", + "Show use of remote protocol `Z' packets ", + set_remote_protocol_Z_packet_cmd, + show_remote_protocol_Z_packet_cmd, + &remote_set_cmdlist, &remote_show_cmdlist); + + /* Eventually initialize fileio. See fileio.c */ + initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist); } diff --git a/contrib/gdb/gdb/remote.h b/contrib/gdb/gdb/remote.h index e2171b27efd..7c0df32ad6f 100644 --- a/contrib/gdb/gdb/remote.h +++ b/contrib/gdb/gdb/remote.h @@ -54,4 +54,11 @@ extern void remote_cisco_objfile_relocate (bfd_signed_vma text_off, extern void async_remote_interrupt_twice (void *arg); +extern int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len); + +extern int remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len); + +extern void (*target_resume_hook) (void); +extern void (*target_wait_loop_hook) (void); + #endif diff --git a/contrib/gdb/gdb/rom68k-rom.c b/contrib/gdb/gdb/rom68k-rom.c new file mode 100644 index 00000000000..2ddba0acf5b --- /dev/null +++ b/contrib/gdb/gdb/rom68k-rom.c @@ -0,0 +1,264 @@ +/* Remote target glue for the ROM68K ROM monitor. + Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcore.h" +#include "target.h" +#include "monitor.h" +#include "serial.h" +#include "regcache.h" +#include "value.h" + +#include "m68k-tdep.h" + +static void rom68k_open (char *args, int from_tty); + +/* Return true if C is a hex digit. + We can't use isxdigit here: that is affected by the current locale; + ROM68K is not. */ +static int +is_hex_digit (int c) +{ + return (('0' <= c && c <= '9') + || ('a' <= c && c <= 'f') + || ('A' <= c && c <= 'F')); +} + + +/* Convert hex digit A to a number. */ +static int +hex_digit_value (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else if (a >= 'A' && a <= 'F') + return a - 'A' + 10; + else + error ("Invalid hex digit %d", a); +} + + +/* Return true iff C is a whitespace character. + We can't use isspace here: that is affected by the current locale; + ROM68K is not. */ +static int +is_whitespace (int c) +{ + return (c == ' ' + || c == '\r' + || c == '\n' + || c == '\t' + || c == '\f'); +} + + +/* Parse a string of hex digits starting at HEX, supply them as the + value of register REGNO, skip any whitespace, and return a pointer + to the next character. + + There is a function in monitor.c, monitor_supply_register, which is + supposed to do this job. However, there is some rather odd stuff + in there (whitespace characters don't terminate numbers, for + example) that is incorrect for ROM68k. It's basically impossible + to safely tweak monitor_supply_register --- it's used by a zillion + other monitors; who knows what behaviors they're depending on. So + instead, we'll just use our own function, which can behave exactly + the way we want it to. */ +static char * +rom68k_supply_one_register (int regno, unsigned char *hex) +{ + ULONGEST value; + unsigned char regbuf[MAX_REGISTER_SIZE]; + + value = 0; + while (*hex != '\0') + if (is_hex_digit (*hex)) + value = (value * 16) + hex_digit_value (*hex++); + else + break; + + /* Skip any whitespace. */ + while (is_whitespace (*hex)) + hex++; + + store_unsigned_integer (regbuf, DEPRECATED_REGISTER_RAW_SIZE (regno), value); + supply_register (regno, regbuf); + + return hex; +} + + +static void +rom68k_supply_register (char *regname, int regnamelen, char *val, int vallen) +{ + int numregs; + int regno; + + numregs = 1; + regno = -1; + + if (regnamelen == 2) + switch (regname[0]) + { + case 'S': + if (regname[1] == 'R') + regno = PS_REGNUM; + break; + case 'P': + if (regname[1] == 'C') + regno = PC_REGNUM; + break; + case 'D': + if (regname[1] != 'R') + break; + regno = M68K_D0_REGNUM; + numregs = 8; + break; + case 'A': + if (regname[1] != 'R') + break; + regno = M68K_A0_REGNUM; + numregs = 7; + break; + } + else if (regnamelen == 3) + switch (regname[0]) + { + case 'I': + if (regname[1] == 'S' && regname[2] == 'P') + regno = SP_REGNUM; + } + + if (regno >= 0) + while (numregs-- > 0) + val = rom68k_supply_one_register (regno++, val); +} + +/* This array of registers need to match the indexes used by GDB. + This exists because the various ROM monitors use different strings + than does GDB, and don't necessarily support all the registers + either. So, typing "info reg sp" becomes a "r30". */ + +static const char * +rom68k_regname (int index) +{ + + static char *regnames[] = + { + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "ISP", + "SR", "PC" + }; + + if ((index >= (sizeof (regnames) / sizeof(regnames[0]))) + || (index < 0) || (index >= NUM_REGS)) + return NULL; + else + return regnames[index]; + +} + +/* Define the monitor command strings. Since these are passed directly + through to a printf style function, we may include formatting + strings. We also need a CR or LF on the end. */ + +static struct target_ops rom68k_ops; + +static char *rom68k_inits[] = +{".\r\r", NULL}; /* Exits pm/pr & download cmds */ + +static struct monitor_ops rom68k_cmds; + +static void +init_rom68k_cmds (void) +{ + rom68k_cmds.flags = MO_PRINT_PROGRAM_OUTPUT; + rom68k_cmds.init = rom68k_inits; /* monitor init string */ + rom68k_cmds.cont = "go\r"; + rom68k_cmds.step = "st\r"; + rom68k_cmds.stop = NULL; + rom68k_cmds.set_break = "db %x\r"; + rom68k_cmds.clr_break = "cb %x\r"; + rom68k_cmds.clr_all_break = "cb *\r"; + rom68k_cmds.fill = "fm %x %x %x\r"; + rom68k_cmds.setmem.cmdb = "pm %x %x\r"; + rom68k_cmds.setmem.cmdw = "pm.w %x %x\r"; + rom68k_cmds.setmem.cmdl = "pm.l %x %x\r"; + rom68k_cmds.setmem.cmdll = NULL; + rom68k_cmds.setmem.resp_delim = NULL; + rom68k_cmds.setmem.term = NULL; + rom68k_cmds.setmem.term_cmd = NULL; + rom68k_cmds.getmem.cmdb = "dm %x %x\r"; + rom68k_cmds.getmem.cmdw = "dm.w %x %x\r"; + rom68k_cmds.getmem.cmdl = "dm.l %x %x\r"; + rom68k_cmds.getmem.cmdll = NULL; + rom68k_cmds.getmem.resp_delim = " "; + rom68k_cmds.getmem.term = NULL; + rom68k_cmds.getmem.term_cmd = NULL; + rom68k_cmds.setreg.cmd = "pr %s %x\r"; + rom68k_cmds.setreg.resp_delim = NULL; + rom68k_cmds.setreg.term = NULL; + rom68k_cmds.setreg.term_cmd = NULL; + rom68k_cmds.getreg.cmd = "pr %s\r"; + rom68k_cmds.getreg.resp_delim = ": "; + rom68k_cmds.getreg.term = "= "; + rom68k_cmds.getreg.term_cmd = ".\r"; + rom68k_cmds.dump_registers = "dr\r"; + rom68k_cmds.register_pattern = + "\\(\\w+\\)=\\([0-9a-fA-F]+\\( +[0-9a-fA-F]+\\b\\)*\\)"; + rom68k_cmds.supply_register = rom68k_supply_register; + rom68k_cmds.load_routine = NULL; + rom68k_cmds.load = "dc\r"; + rom68k_cmds.loadresp = "Waiting for S-records from host... "; + rom68k_cmds.prompt = "ROM68K :-> "; + rom68k_cmds.line_term = "\r"; + rom68k_cmds.cmd_end = ".\r"; + rom68k_cmds.target = &rom68k_ops; + rom68k_cmds.stopbits = SERIAL_1_STOPBITS; + rom68k_cmds.regnames = NULL; + rom68k_cmds.regname = rom68k_regname; + rom68k_cmds.magic = MONITOR_OPS_MAGIC; +} /* init_rom68k_cmds */ + +static void +rom68k_open (char *args, int from_tty) +{ + monitor_open (args, &rom68k_cmds, from_tty); +} + +extern initialize_file_ftype _initialize_rom68k; /* -Wmissing-prototypes */ + +void +_initialize_rom68k (void) +{ + init_rom68k_cmds (); + init_monitor_ops (&rom68k_ops); + + rom68k_ops.to_shortname = "rom68k"; + rom68k_ops.to_longname = "Rom68k debug monitor for the IDP Eval board"; + rom68k_ops.to_doc = "Debug on a Motorola IDP eval board running the ROM68K monitor.\n\ +Specify the serial device it is connected to (e.g. /dev/ttya)."; + rom68k_ops.to_open = rom68k_open; + + add_target (&rom68k_ops); +} diff --git a/contrib/gdb/gdb/s390-nat.c b/contrib/gdb/gdb/s390-nat.c new file mode 100644 index 00000000000..b8da548f05a --- /dev/null +++ b/contrib/gdb/gdb/s390-nat.c @@ -0,0 +1,359 @@ +/* S390 native-dependent code for GDB, the GNU debugger. + Copyright 2001, 2003 Free Software Foundation, Inc + + Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + for IBM Deutschland Entwicklung GmbH, IBM Corporation. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "defs.h" +#include "tm.h" +#include "regcache.h" +#include "inferior.h" + +#include "s390-tdep.h" + +#include +#include +#include +#include +#include +#include + + +/* Map registers to gregset/ptrace offsets. + These arrays are defined in s390-tdep.c. */ + +#ifdef __s390x__ +#define regmap_gregset s390x_regmap_gregset +#else +#define regmap_gregset s390_regmap_gregset +#endif + +#define regmap_fpregset s390_regmap_fpregset + +/* When debugging a 32-bit executable running under a 64-bit kernel, + we have to fix up the 64-bit registers we get from the kernel + to make them look like 32-bit registers. */ +#ifdef __s390x__ +#define SUBOFF(i) \ + ((TARGET_PTR_BIT == 32 \ + && ((i) == S390_PSWA_REGNUM \ + || ((i) >= S390_R0_REGNUM && (i) <= S390_R15_REGNUM)))? 4 : 0) +#else +#define SUBOFF(i) 0 +#endif + + +/* Fill GDB's register array with the general-purpose register values + in *REGP. */ +void +supply_gregset (gregset_t *regp) +{ + int i; + for (i = 0; i < S390_NUM_REGS; i++) + if (regmap_gregset[i] != -1) + regcache_raw_supply (current_regcache, i, + (char *)regp + regmap_gregset[i] + SUBOFF (i)); +} + +/* Fill register REGNO (if it is a general-purpose register) in + *REGP with the value in GDB's register array. If REGNO is -1, + do this for all registers. */ +void +fill_gregset (gregset_t *regp, int regno) +{ + int i; + for (i = 0; i < S390_NUM_REGS; i++) + if (regmap_gregset[i] != -1) + if (regno == -1 || regno == i) + regcache_raw_collect (current_regcache, i, + (char *)regp + regmap_gregset[i] + SUBOFF (i)); +} + +/* Fill GDB's register array with the floating-point register values + in *REGP. */ +void +supply_fpregset (fpregset_t *regp) +{ + int i; + for (i = 0; i < S390_NUM_REGS; i++) + if (regmap_fpregset[i] != -1) + regcache_raw_supply (current_regcache, i, + ((char *)regp) + regmap_fpregset[i]); +} + +/* Fill register REGNO (if it is a general-purpose register) in + *REGP with the value in GDB's register array. If REGNO is -1, + do this for all registers. */ +void +fill_fpregset (fpregset_t *regp, int regno) +{ + int i; + for (i = 0; i < S390_NUM_REGS; i++) + if (regmap_fpregset[i] != -1) + if (regno == -1 || regno == i) + regcache_raw_collect (current_regcache, i, + ((char *)regp) + regmap_fpregset[i]); +} + +/* Find the TID for the current inferior thread to use with ptrace. */ +static int +s390_inferior_tid (void) +{ + /* GNU/Linux LWP ID's are process ID's. */ + int tid = TIDGET (inferior_ptid); + if (tid == 0) + tid = PIDGET (inferior_ptid); /* Not a threaded program. */ + + return tid; +} + +/* Fetch all general-purpose registers from process/thread TID and + store their values in GDB's register cache. */ +static void +fetch_regs (int tid) +{ + gregset_t regs; + ptrace_area parea; + + parea.len = sizeof (regs); + parea.process_addr = (addr_t) ®s; + parea.kernel_addr = offsetof (struct user_regs_struct, psw); + if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) + perror_with_name ("Couldn't get registers"); + + supply_gregset (®s); +} + +/* Store all valid general-purpose registers in GDB's register cache + into the process/thread specified by TID. */ +static void +store_regs (int tid, int regnum) +{ + gregset_t regs; + ptrace_area parea; + + parea.len = sizeof (regs); + parea.process_addr = (addr_t) ®s; + parea.kernel_addr = offsetof (struct user_regs_struct, psw); + if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) + perror_with_name ("Couldn't get registers"); + + fill_gregset (®s, regnum); + + if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0) + perror_with_name ("Couldn't write registers"); +} + +/* Fetch all floating-point registers from process/thread TID and store + their values in GDB's register cache. */ +static void +fetch_fpregs (int tid) +{ + fpregset_t fpregs; + ptrace_area parea; + + parea.len = sizeof (fpregs); + parea.process_addr = (addr_t) &fpregs; + parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs); + if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) + perror_with_name ("Couldn't get floating point status"); + + supply_fpregset (&fpregs); +} + +/* Store all valid floating-point registers in GDB's register cache + into the process/thread specified by TID. */ +static void +store_fpregs (int tid, int regnum) +{ + fpregset_t fpregs; + ptrace_area parea; + + parea.len = sizeof (fpregs); + parea.process_addr = (addr_t) &fpregs; + parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs); + if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) + perror_with_name ("Couldn't get floating point status"); + + fill_fpregset (&fpregs, regnum); + + if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0) + perror_with_name ("Couldn't write floating point status"); +} + +/* Fetch register REGNUM from the child process. If REGNUM is -1, do + this for all registers. */ +void +fetch_inferior_registers (int regnum) +{ + int tid = s390_inferior_tid (); + + if (regnum == -1 + || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1)) + fetch_regs (tid); + + if (regnum == -1 + || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1)) + fetch_fpregs (tid); +} + +/* Store register REGNUM back into the child process. If REGNUM is + -1, do this for all registers. */ +void +store_inferior_registers (int regnum) +{ + int tid = s390_inferior_tid (); + + if (regnum == -1 + || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1)) + store_regs (tid, regnum); + + if (regnum == -1 + || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1)) + store_fpregs (tid, regnum); +} + + +/* Hardware-assisted watchpoint handling. */ + +/* We maintain a list of all currently active watchpoints in order + to properly handle watchpoint removal. + + The only thing we actually need is the total address space area + spanned by the watchpoints. */ + +struct watch_area +{ + struct watch_area *next; + CORE_ADDR lo_addr; + CORE_ADDR hi_addr; +}; + +static struct watch_area *watch_base = NULL; + +int +s390_stopped_by_watchpoint (void) +{ + per_lowcore_bits per_lowcore; + ptrace_area parea; + + /* Speed up common case. */ + if (!watch_base) + return 0; + + parea.len = sizeof (per_lowcore); + parea.process_addr = (addr_t) & per_lowcore; + parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore); + if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea) < 0) + perror_with_name ("Couldn't retrieve watchpoint status"); + + return per_lowcore.perc_storage_alteration == 1 + && per_lowcore.perc_store_real_address == 0; +} + +static void +s390_fix_watch_points (void) +{ + int tid = s390_inferior_tid (); + + per_struct per_info; + ptrace_area parea; + + CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0; + struct watch_area *area; + + for (area = watch_base; area; area = area->next) + { + watch_lo_addr = min (watch_lo_addr, area->lo_addr); + watch_hi_addr = max (watch_hi_addr, area->hi_addr); + } + + parea.len = sizeof (per_info); + parea.process_addr = (addr_t) & per_info; + parea.kernel_addr = offsetof (struct user_regs_struct, per_info); + if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0) + perror_with_name ("Couldn't retrieve watchpoint status"); + + if (watch_base) + { + per_info.control_regs.bits.em_storage_alteration = 1; + per_info.control_regs.bits.storage_alt_space_ctl = 1; + } + else + { + per_info.control_regs.bits.em_storage_alteration = 0; + per_info.control_regs.bits.storage_alt_space_ctl = 0; + } + per_info.starting_addr = watch_lo_addr; + per_info.ending_addr = watch_hi_addr; + + if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0) + perror_with_name ("Couldn't modify watchpoint status"); +} + +int +s390_insert_watchpoint (CORE_ADDR addr, int len) +{ + struct watch_area *area = xmalloc (sizeof (struct watch_area)); + if (!area) + return -1; + + area->lo_addr = addr; + area->hi_addr = addr + len - 1; + + area->next = watch_base; + watch_base = area; + + s390_fix_watch_points (); + return 0; +} + +int +s390_remove_watchpoint (CORE_ADDR addr, int len) +{ + struct watch_area *area, **parea; + + for (parea = &watch_base; *parea; parea = &(*parea)->next) + if ((*parea)->lo_addr == addr + && (*parea)->hi_addr == addr + len - 1) + break; + + if (!*parea) + { + fprintf_unfiltered (gdb_stderr, + "Attempt to remove nonexistent watchpoint.\n"); + return -1; + } + + area = *parea; + *parea = area->next; + xfree (area); + + s390_fix_watch_points (); + return 0; +} + + +int +kernel_u_size (void) +{ + return sizeof (struct user); +} + diff --git a/contrib/gdb/gdb/s390-tdep.c b/contrib/gdb/gdb/s390-tdep.c new file mode 100644 index 00000000000..0f8f65d2f76 --- /dev/null +++ b/contrib/gdb/gdb/s390-tdep.c @@ -0,0 +1,3102 @@ +/* Target-dependent code for GDB, the GNU debugger. + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + for IBM Deutschland Entwicklung GmbH, IBM Corporation. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "frame.h" +#include "inferior.h" +#include "symtab.h" +#include "target.h" +#include "gdbcore.h" +#include "gdbcmd.h" +#include "objfiles.h" +#include "tm.h" +#include "../bfd/bfd.h" +#include "floatformat.h" +#include "regcache.h" +#include "trad-frame.h" +#include "frame-base.h" +#include "frame-unwind.h" +#include "dwarf2-frame.h" +#include "reggroups.h" +#include "regset.h" +#include "value.h" +#include "gdb_assert.h" +#include "dis-asm.h" +#include "solib-svr4.h" /* For struct link_map_offsets. */ + +#include "s390-tdep.h" + + +/* The tdep structure. */ + +struct gdbarch_tdep +{ + /* ABI version. */ + enum { ABI_LINUX_S390, ABI_LINUX_ZSERIES } abi; + + /* Core file register sets. */ + const struct regset *gregset; + int sizeof_gregset; + + const struct regset *fpregset; + int sizeof_fpregset; +}; + + +/* Register information. */ + +struct s390_register_info +{ + char *name; + struct type **type; +}; + +static struct s390_register_info s390_register_info[S390_NUM_TOTAL_REGS] = +{ + /* Program Status Word. */ + { "pswm", &builtin_type_long }, + { "pswa", &builtin_type_long }, + + /* General Purpose Registers. */ + { "r0", &builtin_type_long }, + { "r1", &builtin_type_long }, + { "r2", &builtin_type_long }, + { "r3", &builtin_type_long }, + { "r4", &builtin_type_long }, + { "r5", &builtin_type_long }, + { "r6", &builtin_type_long }, + { "r7", &builtin_type_long }, + { "r8", &builtin_type_long }, + { "r9", &builtin_type_long }, + { "r10", &builtin_type_long }, + { "r11", &builtin_type_long }, + { "r12", &builtin_type_long }, + { "r13", &builtin_type_long }, + { "r14", &builtin_type_long }, + { "r15", &builtin_type_long }, + + /* Access Registers. */ + { "acr0", &builtin_type_int }, + { "acr1", &builtin_type_int }, + { "acr2", &builtin_type_int }, + { "acr3", &builtin_type_int }, + { "acr4", &builtin_type_int }, + { "acr5", &builtin_type_int }, + { "acr6", &builtin_type_int }, + { "acr7", &builtin_type_int }, + { "acr8", &builtin_type_int }, + { "acr9", &builtin_type_int }, + { "acr10", &builtin_type_int }, + { "acr11", &builtin_type_int }, + { "acr12", &builtin_type_int }, + { "acr13", &builtin_type_int }, + { "acr14", &builtin_type_int }, + { "acr15", &builtin_type_int }, + + /* Floating Point Control Word. */ + { "fpc", &builtin_type_int }, + + /* Floating Point Registers. */ + { "f0", &builtin_type_double }, + { "f1", &builtin_type_double }, + { "f2", &builtin_type_double }, + { "f3", &builtin_type_double }, + { "f4", &builtin_type_double }, + { "f5", &builtin_type_double }, + { "f6", &builtin_type_double }, + { "f7", &builtin_type_double }, + { "f8", &builtin_type_double }, + { "f9", &builtin_type_double }, + { "f10", &builtin_type_double }, + { "f11", &builtin_type_double }, + { "f12", &builtin_type_double }, + { "f13", &builtin_type_double }, + { "f14", &builtin_type_double }, + { "f15", &builtin_type_double }, + + /* Pseudo registers. */ + { "pc", &builtin_type_void_func_ptr }, + { "cc", &builtin_type_int }, +}; + +/* Return the name of register REGNUM. */ +static const char * +s390_register_name (int regnum) +{ + gdb_assert (regnum >= 0 && regnum < S390_NUM_TOTAL_REGS); + return s390_register_info[regnum].name; +} + +/* Return the GDB type object for the "standard" data type of data in + register REGNUM. */ +static struct type * +s390_register_type (struct gdbarch *gdbarch, int regnum) +{ + gdb_assert (regnum >= 0 && regnum < S390_NUM_TOTAL_REGS); + return *s390_register_info[regnum].type; +} + +/* DWARF Register Mapping. */ + +static int s390_dwarf_regmap[] = +{ + /* General Purpose Registers. */ + S390_R0_REGNUM, S390_R1_REGNUM, S390_R2_REGNUM, S390_R3_REGNUM, + S390_R4_REGNUM, S390_R5_REGNUM, S390_R6_REGNUM, S390_R7_REGNUM, + S390_R8_REGNUM, S390_R9_REGNUM, S390_R10_REGNUM, S390_R11_REGNUM, + S390_R12_REGNUM, S390_R13_REGNUM, S390_R14_REGNUM, S390_R15_REGNUM, + + /* Floating Point Registers. */ + S390_F0_REGNUM, S390_F2_REGNUM, S390_F4_REGNUM, S390_F6_REGNUM, + S390_F1_REGNUM, S390_F3_REGNUM, S390_F5_REGNUM, S390_F7_REGNUM, + S390_F8_REGNUM, S390_F10_REGNUM, S390_F12_REGNUM, S390_F14_REGNUM, + S390_F9_REGNUM, S390_F11_REGNUM, S390_F13_REGNUM, S390_F15_REGNUM, + + /* Control Registers (not mapped). */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + /* Access Registers. */ + S390_A0_REGNUM, S390_A1_REGNUM, S390_A2_REGNUM, S390_A3_REGNUM, + S390_A4_REGNUM, S390_A5_REGNUM, S390_A6_REGNUM, S390_A7_REGNUM, + S390_A8_REGNUM, S390_A9_REGNUM, S390_A10_REGNUM, S390_A11_REGNUM, + S390_A12_REGNUM, S390_A13_REGNUM, S390_A14_REGNUM, S390_A15_REGNUM, + + /* Program Status Word. */ + S390_PSWM_REGNUM, + S390_PSWA_REGNUM +}; + +/* Convert DWARF register number REG to the appropriate register + number used by GDB. */ +static int +s390_dwarf_reg_to_regnum (int reg) +{ + int regnum = -1; + + if (reg >= 0 || reg < ARRAY_SIZE (s390_dwarf_regmap)) + regnum = s390_dwarf_regmap[reg]; + + if (regnum == -1) + warning ("Unmapped DWARF Register #%d encountered\n", reg); + + return regnum; +} + +/* Pseudo registers - PC and condition code. */ + +static void +s390_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, void *buf) +{ + ULONGEST val; + + switch (regnum) + { + case S390_PC_REGNUM: + regcache_raw_read_unsigned (regcache, S390_PSWA_REGNUM, &val); + store_unsigned_integer (buf, 4, val & 0x7fffffff); + break; + + case S390_CC_REGNUM: + regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &val); + store_unsigned_integer (buf, 4, (val >> 12) & 3); + break; + + default: + internal_error (__FILE__, __LINE__, "invalid regnum"); + } +} + +static void +s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, const void *buf) +{ + ULONGEST val, psw; + + switch (regnum) + { + case S390_PC_REGNUM: + val = extract_unsigned_integer (buf, 4); + regcache_raw_read_unsigned (regcache, S390_PSWA_REGNUM, &psw); + psw = (psw & 0x80000000) | (val & 0x7fffffff); + regcache_raw_write_unsigned (regcache, S390_PSWA_REGNUM, psw); + break; + + case S390_CC_REGNUM: + val = extract_unsigned_integer (buf, 4); + regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &psw); + psw = (psw & ~((ULONGEST)3 << 12)) | ((val & 3) << 12); + regcache_raw_write_unsigned (regcache, S390_PSWM_REGNUM, psw); + break; + + default: + internal_error (__FILE__, __LINE__, "invalid regnum"); + } +} + +static void +s390x_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, void *buf) +{ + ULONGEST val; + + switch (regnum) + { + case S390_PC_REGNUM: + regcache_raw_read (regcache, S390_PSWA_REGNUM, buf); + break; + + case S390_CC_REGNUM: + regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &val); + store_unsigned_integer (buf, 4, (val >> 44) & 3); + break; + + default: + internal_error (__FILE__, __LINE__, "invalid regnum"); + } +} + +static void +s390x_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, const void *buf) +{ + ULONGEST val, psw; + + switch (regnum) + { + case S390_PC_REGNUM: + regcache_raw_write (regcache, S390_PSWA_REGNUM, buf); + break; + + case S390_CC_REGNUM: + val = extract_unsigned_integer (buf, 4); + regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &psw); + psw = (psw & ~((ULONGEST)3 << 44)) | ((val & 3) << 44); + regcache_raw_write_unsigned (regcache, S390_PSWM_REGNUM, psw); + break; + + default: + internal_error (__FILE__, __LINE__, "invalid regnum"); + } +} + +/* 'float' values are stored in the upper half of floating-point + registers, even though we are otherwise a big-endian platform. */ + +static int +s390_convert_register_p (int regno, struct type *type) +{ + return (regno >= S390_F0_REGNUM && regno <= S390_F15_REGNUM) + && TYPE_LENGTH (type) < 8; +} + +static void +s390_register_to_value (struct frame_info *frame, int regnum, + struct type *valtype, void *out) +{ + char in[8]; + int len = TYPE_LENGTH (valtype); + gdb_assert (len < 8); + + get_frame_register (frame, regnum, in); + memcpy (out, in, len); +} + +static void +s390_value_to_register (struct frame_info *frame, int regnum, + struct type *valtype, const void *in) +{ + char out[8]; + int len = TYPE_LENGTH (valtype); + gdb_assert (len < 8); + + memset (out, 0, 8); + memcpy (out, in, len); + put_frame_register (frame, regnum, out); +} + +/* Register groups. */ + +static int +s390_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Registers displayed via 'info regs'. */ + if (group == general_reggroup) + return (regnum >= S390_R0_REGNUM && regnum <= S390_R15_REGNUM) + || regnum == S390_PC_REGNUM + || regnum == S390_CC_REGNUM; + + /* Registers displayed via 'info float'. */ + if (group == float_reggroup) + return (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM) + || regnum == S390_FPC_REGNUM; + + /* Registers that need to be saved/restored in order to + push or pop frames. */ + if (group == save_reggroup || group == restore_reggroup) + return regnum != S390_PSWM_REGNUM && regnum != S390_PSWA_REGNUM; + + return default_register_reggroup_p (gdbarch, regnum, group); +} + + +/* Core file register sets. */ + +int s390_regmap_gregset[S390_NUM_REGS] = +{ + /* Program Status Word. */ + 0x00, 0x04, + /* General Purpose Registers. */ + 0x08, 0x0c, 0x10, 0x14, + 0x18, 0x1c, 0x20, 0x24, + 0x28, 0x2c, 0x30, 0x34, + 0x38, 0x3c, 0x40, 0x44, + /* Access Registers. */ + 0x48, 0x4c, 0x50, 0x54, + 0x58, 0x5c, 0x60, 0x64, + 0x68, 0x6c, 0x70, 0x74, + 0x78, 0x7c, 0x80, 0x84, + /* Floating Point Control Word. */ + -1, + /* Floating Point Registers. */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, +}; + +int s390x_regmap_gregset[S390_NUM_REGS] = +{ + 0x00, 0x08, + /* General Purpose Registers. */ + 0x10, 0x18, 0x20, 0x28, + 0x30, 0x38, 0x40, 0x48, + 0x50, 0x58, 0x60, 0x68, + 0x70, 0x78, 0x80, 0x88, + /* Access Registers. */ + 0x90, 0x94, 0x98, 0x9c, + 0xa0, 0xa4, 0xa8, 0xac, + 0xb0, 0xb4, 0xb8, 0xbc, + 0xc0, 0xc4, 0xc8, 0xcc, + /* Floating Point Control Word. */ + -1, + /* Floating Point Registers. */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, +}; + +int s390_regmap_fpregset[S390_NUM_REGS] = +{ + /* Program Status Word. */ + -1, -1, + /* General Purpose Registers. */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* Access Registers. */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* Floating Point Control Word. */ + 0x00, + /* Floating Point Registers. */ + 0x08, 0x10, 0x18, 0x20, + 0x28, 0x30, 0x38, 0x40, + 0x48, 0x50, 0x58, 0x60, + 0x68, 0x70, 0x78, 0x80, +}; + +/* Supply register REGNUM from the register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ +static void +s390_supply_regset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *regs, size_t len) +{ + const int *offset = regset->descr; + int i; + + for (i = 0; i < S390_NUM_REGS; i++) + { + if ((regnum == i || regnum == -1) && offset[i] != -1) + regcache_raw_supply (regcache, i, (const char *)regs + offset[i]); + } +} + +static const struct regset s390_gregset = { + s390_regmap_gregset, + s390_supply_regset +}; + +static const struct regset s390x_gregset = { + s390x_regmap_gregset, + s390_supply_regset +}; + +static const struct regset s390_fpregset = { + s390_regmap_fpregset, + s390_supply_regset +}; + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ +const struct regset * +s390_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset) + return tdep->gregset; + + if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset) + return tdep->fpregset; + + return NULL; +} + + +/* Prologue analysis. */ + +/* When we analyze a prologue, we're really doing 'abstract + interpretation' or 'pseudo-evaluation': running the function's code + in simulation, but using conservative approximations of the values + it would have when it actually runs. For example, if our function + starts with the instruction: + + ahi r1, 42 # add halfword immediate 42 to r1 + + we don't know exactly what value will be in r1 after executing this + instruction, but we do know it'll be 42 greater than its original + value. + + If we then see an instruction like: + + ahi r1, 22 # add halfword immediate 22 to r1 + + we still don't know what r1's value is, but again, we can say it is + now 64 greater than its original value. + + If the next instruction were: + + lr r2, r1 # set r2 to r1's value + + then we can say that r2's value is now the original value of r1 + plus 64. And so on. + + Of course, this can only go so far before it gets unreasonable. If + we wanted to be able to say anything about the value of r1 after + the instruction: + + xr r1, r3 # exclusive-or r1 and r3, place result in r1 + + then things would get pretty complex. But remember, we're just + doing a conservative approximation; if exclusive-or instructions + aren't relevant to prologues, we can just say r1's value is now + 'unknown'. We can ignore things that are too complex, if that loss + of information is acceptable for our application. + + Once you've reached an instruction that you don't know how to + simulate, you stop. Now you examine the state of the registers and + stack slots you've kept track of. For example: + + - To see how large your stack frame is, just check the value of sp; + if it's the original value of sp minus a constant, then that + constant is the stack frame's size. If the sp's value has been + marked as 'unknown', then that means the prologue has done + something too complex for us to track, and we don't know the + frame size. + + - To see whether we've saved the SP in the current frame's back + chain slot, we just check whether the current value of the back + chain stack slot is the original value of the sp. + + Sure, this takes some work. But prologue analyzers aren't + quick-and-simple pattern patching to recognize a few fixed prologue + forms any more; they're big, hairy functions. Along with inferior + function calls, prologue analysis accounts for a substantial + portion of the time needed to stabilize a GDB port. So I think + it's worthwhile to look for an approach that will be easier to + understand and maintain. In the approach used here: + + - It's easier to see that the analyzer is correct: you just see + whether the analyzer properly (albiet conservatively) simulates + the effect of each instruction. + + - It's easier to extend the analyzer: you can add support for new + instructions, and know that you haven't broken anything that + wasn't already broken before. + + - It's orthogonal: to gather new information, you don't need to + complicate the code for each instruction. As long as your domain + of conservative values is already detailed enough to tell you + what you need, then all the existing instruction simulations are + already gathering the right data for you. + + A 'struct prologue_value' is a conservative approximation of the + real value the register or stack slot will have. */ + +struct prologue_value { + + /* What sort of value is this? This determines the interpretation + of subsequent fields. */ + enum { + + /* We don't know anything about the value. This is also used for + values we could have kept track of, when doing so would have + been too complex and we don't want to bother. The bottom of + our lattice. */ + pv_unknown, + + /* A known constant. K is its value. */ + pv_constant, + + /* The value that register REG originally had *UPON ENTRY TO THE + FUNCTION*, plus K. If K is zero, this means, obviously, just + the value REG had upon entry to the function. REG is a GDB + register number. Before we start interpreting, we initialize + every register R to { pv_register, R, 0 }. */ + pv_register, + + } kind; + + /* The meanings of the following fields depend on 'kind'; see the + comments for the specific 'kind' values. */ + int reg; + CORE_ADDR k; +}; + + +/* Set V to be unknown. */ +static void +pv_set_to_unknown (struct prologue_value *v) +{ + v->kind = pv_unknown; +} + + +/* Set V to the constant K. */ +static void +pv_set_to_constant (struct prologue_value *v, CORE_ADDR k) +{ + v->kind = pv_constant; + v->k = k; +} + + +/* Set V to the original value of register REG, plus K. */ +static void +pv_set_to_register (struct prologue_value *v, int reg, CORE_ADDR k) +{ + v->kind = pv_register; + v->reg = reg; + v->k = k; +} + + +/* If one of *A and *B is a constant, and the other isn't, swap the + pointers as necessary to ensure that *B points to the constant. + This can reduce the number of cases we need to analyze in the + functions below. */ +static void +pv_constant_last (struct prologue_value **a, + struct prologue_value **b) +{ + if ((*a)->kind == pv_constant + && (*b)->kind != pv_constant) + { + struct prologue_value *temp = *a; + *a = *b; + *b = temp; + } +} + + +/* Set SUM to the sum of A and B. SUM, A, and B may point to the same + 'struct prologue_value' object. */ +static void +pv_add (struct prologue_value *sum, + struct prologue_value *a, + struct prologue_value *b) +{ + pv_constant_last (&a, &b); + + /* We can handle adding constants to registers, and other constants. */ + if (b->kind == pv_constant + && (a->kind == pv_register + || a->kind == pv_constant)) + { + sum->kind = a->kind; + sum->reg = a->reg; /* not meaningful if a is pv_constant, but + harmless */ + sum->k = a->k + b->k; + } + + /* Anything else we don't know how to add. We don't have a + representation for, say, the sum of two registers, or a multiple + of a register's value (adding a register to itself). */ + else + sum->kind = pv_unknown; +} + + +/* Add the constant K to V. */ +static void +pv_add_constant (struct prologue_value *v, CORE_ADDR k) +{ + struct prologue_value pv_k; + + /* Rather than thinking of all the cases we can and can't handle, + we'll just let pv_add take care of that for us. */ + pv_set_to_constant (&pv_k, k); + pv_add (v, v, &pv_k); +} + + +/* Subtract B from A, and put the result in DIFF. + + This isn't quite the same as negating B and adding it to A, since + we don't have a representation for the negation of anything but a + constant. For example, we can't negate { pv_register, R1, 10 }, + but we do know that { pv_register, R1, 10 } minus { pv_register, + R1, 5 } is { pv_constant, , 5 }. + + This means, for example, that we can subtract two stack addresses; + they're both relative to the original SP. Since the frame pointer + is set based on the SP, its value will be the original SP plus some + constant (probably zero), so we can use its value just fine. */ +static void +pv_subtract (struct prologue_value *diff, + struct prologue_value *a, + struct prologue_value *b) +{ + pv_constant_last (&a, &b); + + /* We can subtract a constant from another constant, or from a + register. */ + if (b->kind == pv_constant + && (a->kind == pv_register + || a->kind == pv_constant)) + { + diff->kind = a->kind; + diff->reg = a->reg; /* not always meaningful, but harmless */ + diff->k = a->k - b->k; + } + + /* We can subtract a register from itself, yielding a constant. */ + else if (a->kind == pv_register + && b->kind == pv_register + && a->reg == b->reg) + { + diff->kind = pv_constant; + diff->k = a->k - b->k; + } + + /* We don't know how to subtract anything else. */ + else + diff->kind = pv_unknown; +} + + +/* Set AND to the logical and of A and B. */ +static void +pv_logical_and (struct prologue_value *and, + struct prologue_value *a, + struct prologue_value *b) +{ + pv_constant_last (&a, &b); + + /* We can 'and' two constants. */ + if (a->kind == pv_constant + && b->kind == pv_constant) + { + and->kind = pv_constant; + and->k = a->k & b->k; + } + + /* We can 'and' anything with the constant zero. */ + else if (b->kind == pv_constant + && b->k == 0) + { + and->kind = pv_constant; + and->k = 0; + } + + /* We can 'and' anything with ~0. */ + else if (b->kind == pv_constant + && b->k == ~ (CORE_ADDR) 0) + *and = *a; + + /* We can 'and' a register with itself. */ + else if (a->kind == pv_register + && b->kind == pv_register + && a->reg == b->reg + && a->k == b->k) + *and = *a; + + /* Otherwise, we don't know. */ + else + pv_set_to_unknown (and); +} + + +/* Return non-zero iff A and B are identical expressions. + + This is not the same as asking if the two values are equal; the + result of such a comparison would have to be a pv_boolean, and + asking whether two 'unknown' values were equal would give you + pv_maybe. Same for comparing, say, { pv_register, R1, 0 } and { + pv_register, R2, 0}. Instead, this is asking whether the two + representations are the same. */ +static int +pv_is_identical (struct prologue_value *a, + struct prologue_value *b) +{ + if (a->kind != b->kind) + return 0; + + switch (a->kind) + { + case pv_unknown: + return 1; + case pv_constant: + return (a->k == b->k); + case pv_register: + return (a->reg == b->reg && a->k == b->k); + default: + gdb_assert (0); + } +} + + +/* Return non-zero if A is the original value of register number R + plus K, zero otherwise. */ +static int +pv_is_register (struct prologue_value *a, int r, CORE_ADDR k) +{ + return (a->kind == pv_register + && a->reg == r + && a->k == k); +} + + +/* A prologue-value-esque boolean type, including "maybe", when we + can't figure out whether something is true or not. */ +enum pv_boolean { + pv_maybe, + pv_definite_yes, + pv_definite_no, +}; + + +/* Decide whether a reference to SIZE bytes at ADDR refers exactly to + an element of an array. The array starts at ARRAY_ADDR, and has + ARRAY_LEN values of ELT_SIZE bytes each. If ADDR definitely does + refer to an array element, set *I to the index of the referenced + element in the array, and return pv_definite_yes. If it definitely + doesn't, return pv_definite_no. If we can't tell, return pv_maybe. + + If the reference does touch the array, but doesn't fall exactly on + an element boundary, or doesn't refer to the whole element, return + pv_maybe. */ +static enum pv_boolean +pv_is_array_ref (struct prologue_value *addr, + CORE_ADDR size, + struct prologue_value *array_addr, + CORE_ADDR array_len, + CORE_ADDR elt_size, + int *i) +{ + struct prologue_value offset; + + /* Note that, since ->k is a CORE_ADDR, and CORE_ADDR is unsigned, + if addr is *before* the start of the array, then this isn't going + to be negative... */ + pv_subtract (&offset, addr, array_addr); + + if (offset.kind == pv_constant) + { + /* This is a rather odd test. We want to know if the SIZE bytes + at ADDR don't overlap the array at all, so you'd expect it to + be an || expression: "if we're completely before || we're + completely after". But with unsigned arithmetic, things are + different: since it's a number circle, not a number line, the + right values for offset.k are actually one contiguous range. */ + if (offset.k <= -size + && offset.k >= array_len * elt_size) + return pv_definite_no; + else if (offset.k % elt_size != 0 + || size != elt_size) + return pv_maybe; + else + { + *i = offset.k / elt_size; + return pv_definite_yes; + } + } + else + return pv_maybe; +} + + + +/* Decoding S/390 instructions. */ + +/* Named opcode values for the S/390 instructions we recognize. Some + instructions have their opcode split across two fields; those are the + op1_* and op2_* enums. */ +enum + { + op1_lhi = 0xa7, op2_lhi = 0x08, + op1_lghi = 0xa7, op2_lghi = 0x09, + op_lr = 0x18, + op_lgr = 0xb904, + op_l = 0x58, + op1_ly = 0xe3, op2_ly = 0x58, + op1_lg = 0xe3, op2_lg = 0x04, + op_lm = 0x98, + op1_lmy = 0xeb, op2_lmy = 0x98, + op1_lmg = 0xeb, op2_lmg = 0x04, + op_st = 0x50, + op1_sty = 0xe3, op2_sty = 0x50, + op1_stg = 0xe3, op2_stg = 0x24, + op_std = 0x60, + op_stm = 0x90, + op1_stmy = 0xeb, op2_stmy = 0x90, + op1_stmg = 0xeb, op2_stmg = 0x24, + op1_aghi = 0xa7, op2_aghi = 0x0b, + op1_ahi = 0xa7, op2_ahi = 0x0a, + op_ar = 0x1a, + op_agr = 0xb908, + op_a = 0x5a, + op1_ay = 0xe3, op2_ay = 0x5a, + op1_ag = 0xe3, op2_ag = 0x08, + op_sr = 0x1b, + op_sgr = 0xb909, + op_s = 0x5b, + op1_sy = 0xe3, op2_sy = 0x5b, + op1_sg = 0xe3, op2_sg = 0x09, + op_nr = 0x14, + op_ngr = 0xb980, + op_la = 0x41, + op1_lay = 0xe3, op2_lay = 0x71, + op1_larl = 0xc0, op2_larl = 0x00, + op_basr = 0x0d, + op_bas = 0x4d, + op_bcr = 0x07, + op_bc = 0x0d, + op1_bras = 0xa7, op2_bras = 0x05, + op1_brasl= 0xc0, op2_brasl= 0x05, + op1_brc = 0xa7, op2_brc = 0x04, + op1_brcl = 0xc0, op2_brcl = 0x04, + }; + + +/* Read a single instruction from address AT. */ + +#define S390_MAX_INSTR_SIZE 6 +static int +s390_readinstruction (bfd_byte instr[], CORE_ADDR at) +{ + static int s390_instrlen[] = { 2, 4, 4, 6 }; + int instrlen; + + if (read_memory_nobpt (at, &instr[0], 2)) + return -1; + instrlen = s390_instrlen[instr[0] >> 6]; + if (instrlen > 2) + { + if (read_memory_nobpt (at + 2, &instr[2], instrlen - 2)) + return -1; + } + return instrlen; +} + + +/* The functions below are for recognizing and decoding S/390 + instructions of various formats. Each of them checks whether INSN + is an instruction of the given format, with the specified opcodes. + If it is, it sets the remaining arguments to the values of the + instruction's fields, and returns a non-zero value; otherwise, it + returns zero. + + These functions' arguments appear in the order they appear in the + instruction, not in the machine-language form. So, opcodes always + come first, even though they're sometimes scattered around the + instructions. And displacements appear before base and extension + registers, as they do in the assembly syntax, not at the end, as + they do in the machine language. */ +static int +is_ri (bfd_byte *insn, int op1, int op2, unsigned int *r1, int *i2) +{ + if (insn[0] == op1 && (insn[1] & 0xf) == op2) + { + *r1 = (insn[1] >> 4) & 0xf; + /* i2 is a 16-bit signed quantity. */ + *i2 = (((insn[2] << 8) | insn[3]) ^ 0x8000) - 0x8000; + return 1; + } + else + return 0; +} + + +static int +is_ril (bfd_byte *insn, int op1, int op2, + unsigned int *r1, int *i2) +{ + if (insn[0] == op1 && (insn[1] & 0xf) == op2) + { + *r1 = (insn[1] >> 4) & 0xf; + /* i2 is a signed quantity. If the host 'int' is 32 bits long, + no sign extension is necessary, but we don't want to assume + that. */ + *i2 = (((insn[2] << 24) + | (insn[3] << 16) + | (insn[4] << 8) + | (insn[5])) ^ 0x80000000) - 0x80000000; + return 1; + } + else + return 0; +} + + +static int +is_rr (bfd_byte *insn, int op, unsigned int *r1, unsigned int *r2) +{ + if (insn[0] == op) + { + *r1 = (insn[1] >> 4) & 0xf; + *r2 = insn[1] & 0xf; + return 1; + } + else + return 0; +} + + +static int +is_rre (bfd_byte *insn, int op, unsigned int *r1, unsigned int *r2) +{ + if (((insn[0] << 8) | insn[1]) == op) + { + /* Yes, insn[3]. insn[2] is unused in RRE format. */ + *r1 = (insn[3] >> 4) & 0xf; + *r2 = insn[3] & 0xf; + return 1; + } + else + return 0; +} + + +static int +is_rs (bfd_byte *insn, int op, + unsigned int *r1, unsigned int *r3, unsigned int *d2, unsigned int *b2) +{ + if (insn[0] == op) + { + *r1 = (insn[1] >> 4) & 0xf; + *r3 = insn[1] & 0xf; + *b2 = (insn[2] >> 4) & 0xf; + *d2 = ((insn[2] & 0xf) << 8) | insn[3]; + return 1; + } + else + return 0; +} + + +static int +is_rsy (bfd_byte *insn, int op1, int op2, + unsigned int *r1, unsigned int *r3, unsigned int *d2, unsigned int *b2) +{ + if (insn[0] == op1 + && insn[5] == op2) + { + *r1 = (insn[1] >> 4) & 0xf; + *r3 = insn[1] & 0xf; + *b2 = (insn[2] >> 4) & 0xf; + /* The 'long displacement' is a 20-bit signed integer. */ + *d2 = ((((insn[2] & 0xf) << 8) | insn[3] | (insn[4] << 12)) + ^ 0x80000) - 0x80000; + return 1; + } + else + return 0; +} + + +static int +is_rx (bfd_byte *insn, int op, + unsigned int *r1, unsigned int *d2, unsigned int *x2, unsigned int *b2) +{ + if (insn[0] == op) + { + *r1 = (insn[1] >> 4) & 0xf; + *x2 = insn[1] & 0xf; + *b2 = (insn[2] >> 4) & 0xf; + *d2 = ((insn[2] & 0xf) << 8) | insn[3]; + return 1; + } + else + return 0; +} + + +static int +is_rxy (bfd_byte *insn, int op1, int op2, + unsigned int *r1, unsigned int *d2, unsigned int *x2, unsigned int *b2) +{ + if (insn[0] == op1 + && insn[5] == op2) + { + *r1 = (insn[1] >> 4) & 0xf; + *x2 = insn[1] & 0xf; + *b2 = (insn[2] >> 4) & 0xf; + /* The 'long displacement' is a 20-bit signed integer. */ + *d2 = ((((insn[2] & 0xf) << 8) | insn[3] | (insn[4] << 12)) + ^ 0x80000) - 0x80000; + return 1; + } + else + return 0; +} + + +/* Set ADDR to the effective address for an X-style instruction, like: + + L R1, D2(X2, B2) + + Here, X2 and B2 are registers, and D2 is a signed 20-bit + constant; the effective address is the sum of all three. If either + X2 or B2 are zero, then it doesn't contribute to the sum --- this + means that r0 can't be used as either X2 or B2. + + GPR is an array of general register values, indexed by GPR number, + not GDB register number. */ +static void +compute_x_addr (struct prologue_value *addr, + struct prologue_value *gpr, + int d2, unsigned int x2, unsigned int b2) +{ + /* We can't just add stuff directly in addr; it might alias some of + the registers we need to read. */ + struct prologue_value result; + + pv_set_to_constant (&result, d2); + if (x2) + pv_add (&result, &result, &gpr[x2]); + if (b2) + pv_add (&result, &result, &gpr[b2]); + + *addr = result; +} + + +/* The number of GPR and FPR spill slots in an S/390 stack frame. We + track general-purpose registers r2 -- r15, and floating-point + registers f0, f2, f4, and f6. */ +#define S390_NUM_SPILL_SLOTS (14 + 4) +#define S390_NUM_GPRS 16 +#define S390_NUM_FPRS 16 + +struct s390_prologue_data { + + /* The size of a GPR or FPR. */ + int gpr_size; + int fpr_size; + + /* The general-purpose registers. */ + struct prologue_value gpr[S390_NUM_GPRS]; + + /* The floating-point registers. */ + struct prologue_value fpr[S390_NUM_FPRS]; + + /* The register spill stack slots in the caller's frame --- + general-purpose registers r2 through r15, and floating-point + registers. spill[i] is where gpr i+2 gets spilled; + spill[(14, 15, 16, 17)] is where (f0, f2, f4, f6) get spilled. */ + struct prologue_value spill[S390_NUM_SPILL_SLOTS]; + + /* The value of the back chain slot. This is only valid if the stack + pointer is known to be less than its original value --- that is, + if we have indeed allocated space on the stack. */ + struct prologue_value back_chain; +}; + + +/* If the SIZE bytes at ADDR are a stack slot we're actually tracking, + return pv_definite_yes and set *STACK to point to the slot. If + we're sure that they are not any of our stack slots, then return + pv_definite_no. Otherwise, return pv_maybe. + + DATA describes our current state (registers and stack slots). */ +static enum pv_boolean +s390_on_stack (struct prologue_value *addr, + CORE_ADDR size, + struct s390_prologue_data *data, + struct prologue_value **stack) +{ + struct prologue_value gpr_spill_addr; + struct prologue_value fpr_spill_addr; + struct prologue_value back_chain_addr; + int i; + enum pv_boolean b; + + /* Construct the addresses of the spill arrays and the back chain. */ + pv_set_to_register (&gpr_spill_addr, S390_SP_REGNUM, 2 * data->gpr_size); + pv_set_to_register (&fpr_spill_addr, S390_SP_REGNUM, 16 * data->gpr_size); + back_chain_addr = data->gpr[S390_SP_REGNUM - S390_R0_REGNUM]; + + /* We have to check for GPR and FPR references using two separate + calls to pv_is_array_ref, since the GPR and FPR spill slots are + different sizes. (SPILL is an array, but the thing it tracks + isn't really an array.) */ + + /* Was it a reference to the GPR spill array? */ + b = pv_is_array_ref (addr, size, &gpr_spill_addr, 14, data->gpr_size, &i); + if (b == pv_definite_yes) + { + *stack = &data->spill[i]; + return pv_definite_yes; + } + if (b == pv_maybe) + return pv_maybe; + + /* Was it a reference to the FPR spill array? */ + b = pv_is_array_ref (addr, size, &fpr_spill_addr, 4, data->fpr_size, &i); + if (b == pv_definite_yes) + { + *stack = &data->spill[14 + i]; + return pv_definite_yes; + } + if (b == pv_maybe) + return pv_maybe; + + /* Was it a reference to the back chain? + This isn't quite right. We ought to check whether we have + actually allocated any new frame at all. */ + b = pv_is_array_ref (addr, size, &back_chain_addr, 1, data->gpr_size, &i); + if (b == pv_definite_yes) + { + *stack = &data->back_chain; + return pv_definite_yes; + } + if (b == pv_maybe) + return pv_maybe; + + /* All the above queries returned definite 'no's. */ + return pv_definite_no; +} + + +/* Do a SIZE-byte store of VALUE to ADDR. */ +static void +s390_store (struct prologue_value *addr, + CORE_ADDR size, + struct prologue_value *value, + struct s390_prologue_data *data) +{ + struct prologue_value *stack; + + /* We can do it if it's definitely a reference to something on the stack. */ + if (s390_on_stack (addr, size, data, &stack) == pv_definite_yes) + { + *stack = *value; + return; + } + + /* Note: If s390_on_stack returns pv_maybe, you might think we should + forget our cached values, as any of those might have been hit. + + However, we make the assumption that --since the fields we track + are save areas private to compiler, and never directly exposed to + the user-- every access to our data is explicit. Hence, every + memory access we cannot follow can't hit our data. */ +} + +/* Do a SIZE-byte load from ADDR into VALUE. */ +static void +s390_load (struct prologue_value *addr, + CORE_ADDR size, + struct prologue_value *value, + struct s390_prologue_data *data) +{ + struct prologue_value *stack; + + /* If it's a load from an in-line constant pool, then we can + simulate that, under the assumption that the code isn't + going to change between the time the processor actually + executed it creating the current frame, and the time when + we're analyzing the code to unwind past that frame. */ + if (addr->kind == pv_constant) + { + struct section_table *secp; + secp = target_section_by_addr (¤t_target, addr->k); + if (secp != NULL + && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section) + & SEC_READONLY)) + { + pv_set_to_constant (value, read_memory_integer (addr->k, size)); + return; + } + } + + /* If it's definitely a reference to something on the stack, + we can do that. */ + if (s390_on_stack (addr, size, data, &stack) == pv_definite_yes) + { + *value = *stack; + return; + } + + /* Otherwise, we don't know the value. */ + pv_set_to_unknown (value); +} + + +/* Analyze the prologue of the function starting at START_PC, + continuing at most until CURRENT_PC. Initialize DATA to + hold all information we find out about the state of the registers + and stack slots. Return the address of the instruction after + the last one that changed the SP, FP, or back chain; or zero + on error. */ +static CORE_ADDR +s390_analyze_prologue (struct gdbarch *gdbarch, + CORE_ADDR start_pc, + CORE_ADDR current_pc, + struct s390_prologue_data *data) +{ + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + + /* Our return value: + The address of the instruction after the last one that changed + the SP, FP, or back chain; zero if we got an error trying to + read memory. */ + CORE_ADDR result = start_pc; + + /* The current PC for our abstract interpretation. */ + CORE_ADDR pc; + + /* The address of the next instruction after that. */ + CORE_ADDR next_pc; + + /* Set up everything's initial value. */ + { + int i; + + /* For the purpose of prologue tracking, we consider the GPR size to + be equal to the ABI word size, even if it is actually larger + (i.e. when running a 32-bit binary under a 64-bit kernel). */ + data->gpr_size = word_size; + data->fpr_size = 8; + + for (i = 0; i < S390_NUM_GPRS; i++) + pv_set_to_register (&data->gpr[i], S390_R0_REGNUM + i, 0); + + for (i = 0; i < S390_NUM_FPRS; i++) + pv_set_to_register (&data->fpr[i], S390_F0_REGNUM + i, 0); + + for (i = 0; i < S390_NUM_SPILL_SLOTS; i++) + pv_set_to_unknown (&data->spill[i]); + + pv_set_to_unknown (&data->back_chain); + } + + /* Start interpreting instructions, until we hit the frame's + current PC or the first branch instruction. */ + for (pc = start_pc; pc > 0 && pc < current_pc; pc = next_pc) + { + bfd_byte insn[S390_MAX_INSTR_SIZE]; + int insn_len = s390_readinstruction (insn, pc); + + /* Fields for various kinds of instructions. */ + unsigned int b2, r1, r2, x2, r3; + int i2, d2; + + /* The values of SP, FP, and back chain before this instruction, + for detecting instructions that change them. */ + struct prologue_value pre_insn_sp, pre_insn_fp, pre_insn_back_chain; + + /* If we got an error trying to read the instruction, report it. */ + if (insn_len < 0) + { + result = 0; + break; + } + + next_pc = pc + insn_len; + + pre_insn_sp = data->gpr[S390_SP_REGNUM - S390_R0_REGNUM]; + pre_insn_fp = data->gpr[S390_FRAME_REGNUM - S390_R0_REGNUM]; + pre_insn_back_chain = data->back_chain; + + /* LHI r1, i2 --- load halfword immediate */ + if (word_size == 4 + && is_ri (insn, op1_lhi, op2_lhi, &r1, &i2)) + pv_set_to_constant (&data->gpr[r1], i2); + + /* LGHI r1, i2 --- load halfword immediate (64-bit version) */ + else if (word_size == 8 + && is_ri (insn, op1_lghi, op2_lghi, &r1, &i2)) + pv_set_to_constant (&data->gpr[r1], i2); + + /* LR r1, r2 --- load from register */ + else if (word_size == 4 + && is_rr (insn, op_lr, &r1, &r2)) + data->gpr[r1] = data->gpr[r2]; + + /* LGR r1, r2 --- load from register (64-bit version) */ + else if (word_size == 8 + && is_rre (insn, op_lgr, &r1, &r2)) + data->gpr[r1] = data->gpr[r2]; + + /* L r1, d2(x2, b2) --- load */ + else if (word_size == 4 + && is_rx (insn, op_l, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 4, &data->gpr[r1], data); + } + + /* LY r1, d2(x2, b2) --- load (long-displacement version) */ + else if (word_size == 4 + && is_rxy (insn, op1_ly, op2_ly, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 4, &data->gpr[r1], data); + } + + /* LG r1, d2(x2, b2) --- load (64-bit version) */ + else if (word_size == 8 + && is_rxy (insn, op1_lg, op2_lg, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 8, &data->gpr[r1], data); + } + + /* ST r1, d2(x2, b2) --- store */ + else if (word_size == 4 + && is_rx (insn, op_st, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_store (&addr, 4, &data->gpr[r1], data); + } + + /* STY r1, d2(x2, b2) --- store (long-displacement version) */ + else if (word_size == 4 + && is_rxy (insn, op1_sty, op2_sty, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_store (&addr, 4, &data->gpr[r1], data); + } + + /* STG r1, d2(x2, b2) --- store (64-bit version) */ + else if (word_size == 8 + && is_rxy (insn, op1_stg, op2_stg, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_store (&addr, 8, &data->gpr[r1], data); + } + + /* STD r1, d2(x2,b2) --- store floating-point register */ + else if (is_rx (insn, op_std, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_store (&addr, 8, &data->fpr[r1], data); + } + + /* STM r1, r3, d2(b2) --- store multiple */ + else if (word_size == 4 + && is_rs (insn, op_stm, &r1, &r3, &d2, &b2)) + { + int regnum; + int offset; + struct prologue_value addr; + + for (regnum = r1, offset = 0; + regnum <= r3; + regnum++, offset += 4) + { + compute_x_addr (&addr, data->gpr, d2 + offset, 0, b2); + s390_store (&addr, 4, &data->gpr[regnum], data); + } + } + + /* STMY r1, r3, d2(b2) --- store multiple (long-displacement version) */ + else if (word_size == 4 + && is_rsy (insn, op1_stmy, op2_stmy, &r1, &r3, &d2, &b2)) + { + int regnum; + int offset; + struct prologue_value addr; + + for (regnum = r1, offset = 0; + regnum <= r3; + regnum++, offset += 4) + { + compute_x_addr (&addr, data->gpr, d2 + offset, 0, b2); + s390_store (&addr, 4, &data->gpr[regnum], data); + } + } + + /* STMG r1, r3, d2(b2) --- store multiple (64-bit version) */ + else if (word_size == 8 + && is_rsy (insn, op1_stmg, op2_stmg, &r1, &r3, &d2, &b2)) + { + int regnum; + int offset; + struct prologue_value addr; + + for (regnum = r1, offset = 0; + regnum <= r3; + regnum++, offset += 8) + { + compute_x_addr (&addr, data->gpr, d2 + offset, 0, b2); + s390_store (&addr, 8, &data->gpr[regnum], data); + } + } + + /* AHI r1, i2 --- add halfword immediate */ + else if (word_size == 4 + && is_ri (insn, op1_ahi, op2_ahi, &r1, &i2)) + pv_add_constant (&data->gpr[r1], i2); + + /* AGHI r1, i2 --- add halfword immediate (64-bit version) */ + else if (word_size == 8 + && is_ri (insn, op1_aghi, op2_aghi, &r1, &i2)) + pv_add_constant (&data->gpr[r1], i2); + + /* AR r1, r2 -- add register */ + else if (word_size == 4 + && is_rr (insn, op_ar, &r1, &r2)) + pv_add (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]); + + /* AGR r1, r2 -- add register (64-bit version) */ + else if (word_size == 8 + && is_rre (insn, op_agr, &r1, &r2)) + pv_add (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]); + + /* A r1, d2(x2, b2) -- add */ + else if (word_size == 4 + && is_rx (insn, op_a, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + struct prologue_value value; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 4, &value, data); + + pv_add (&data->gpr[r1], &data->gpr[r1], &value); + } + + /* AY r1, d2(x2, b2) -- add (long-displacement version) */ + else if (word_size == 4 + && is_rxy (insn, op1_ay, op2_ay, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + struct prologue_value value; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 4, &value, data); + + pv_add (&data->gpr[r1], &data->gpr[r1], &value); + } + + /* AG r1, d2(x2, b2) -- add (64-bit version) */ + else if (word_size == 8 + && is_rxy (insn, op1_ag, op2_ag, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + struct prologue_value value; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 8, &value, data); + + pv_add (&data->gpr[r1], &data->gpr[r1], &value); + } + + /* SR r1, r2 -- subtract register */ + else if (word_size == 4 + && is_rr (insn, op_sr, &r1, &r2)) + pv_subtract (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]); + + /* SGR r1, r2 -- subtract register (64-bit version) */ + else if (word_size == 8 + && is_rre (insn, op_sgr, &r1, &r2)) + pv_subtract (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]); + + /* S r1, d2(x2, b2) -- subtract */ + else if (word_size == 4 + && is_rx (insn, op_s, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + struct prologue_value value; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 4, &value, data); + + pv_subtract (&data->gpr[r1], &data->gpr[r1], &value); + } + + /* SY r1, d2(x2, b2) -- subtract (long-displacement version) */ + else if (word_size == 4 + && is_rxy (insn, op1_sy, op2_sy, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + struct prologue_value value; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 4, &value, data); + + pv_subtract (&data->gpr[r1], &data->gpr[r1], &value); + } + + /* SG r1, d2(x2, b2) -- subtract (64-bit version) */ + else if (word_size == 8 + && is_rxy (insn, op1_sg, op2_sg, &r1, &d2, &x2, &b2)) + { + struct prologue_value addr; + struct prologue_value value; + + compute_x_addr (&addr, data->gpr, d2, x2, b2); + s390_load (&addr, 8, &value, data); + + pv_subtract (&data->gpr[r1], &data->gpr[r1], &value); + } + + /* NR r1, r2 --- logical and */ + else if (word_size == 4 + && is_rr (insn, op_nr, &r1, &r2)) + pv_logical_and (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]); + + /* NGR r1, r2 >--- logical and (64-bit version) */ + else if (word_size == 8 + && is_rre (insn, op_ngr, &r1, &r2)) + pv_logical_and (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]); + + /* LA r1, d2(x2, b2) --- load address */ + else if (is_rx (insn, op_la, &r1, &d2, &x2, &b2)) + compute_x_addr (&data->gpr[r1], data->gpr, d2, x2, b2); + + /* LAY r1, d2(x2, b2) --- load address (long-displacement version) */ + else if (is_rxy (insn, op1_lay, op2_lay, &r1, &d2, &x2, &b2)) + compute_x_addr (&data->gpr[r1], data->gpr, d2, x2, b2); + + /* LARL r1, i2 --- load address relative long */ + else if (is_ril (insn, op1_larl, op2_larl, &r1, &i2)) + pv_set_to_constant (&data->gpr[r1], pc + i2 * 2); + + /* BASR r1, 0 --- branch and save + Since r2 is zero, this saves the PC in r1, but doesn't branch. */ + else if (is_rr (insn, op_basr, &r1, &r2) + && r2 == 0) + pv_set_to_constant (&data->gpr[r1], next_pc); + + /* BRAS r1, i2 --- branch relative and save */ + else if (is_ri (insn, op1_bras, op2_bras, &r1, &i2)) + { + pv_set_to_constant (&data->gpr[r1], next_pc); + next_pc = pc + i2 * 2; + + /* We'd better not interpret any backward branches. We'll + never terminate. */ + if (next_pc <= pc) + break; + } + + /* Terminate search when hitting any other branch instruction. */ + else if (is_rr (insn, op_basr, &r1, &r2) + || is_rx (insn, op_bas, &r1, &d2, &x2, &b2) + || is_rr (insn, op_bcr, &r1, &r2) + || is_rx (insn, op_bc, &r1, &d2, &x2, &b2) + || is_ri (insn, op1_brc, op2_brc, &r1, &i2) + || is_ril (insn, op1_brcl, op2_brcl, &r1, &i2) + || is_ril (insn, op1_brasl, op2_brasl, &r2, &i2)) + break; + + else + /* An instruction we don't know how to simulate. The only + safe thing to do would be to set every value we're tracking + to 'unknown'. Instead, we'll be optimistic: we assume that + we *can* interpret every instruction that the compiler uses + to manipulate any of the data we're interested in here -- + then we can just ignore anything else. */ + ; + + /* Record the address after the last instruction that changed + the FP, SP, or backlink. Ignore instructions that changed + them back to their original values --- those are probably + restore instructions. (The back chain is never restored, + just popped.) */ + { + struct prologue_value *sp = &data->gpr[S390_SP_REGNUM - S390_R0_REGNUM]; + struct prologue_value *fp = &data->gpr[S390_FRAME_REGNUM - S390_R0_REGNUM]; + + if ((! pv_is_identical (&pre_insn_sp, sp) + && ! pv_is_register (sp, S390_SP_REGNUM, 0)) + || (! pv_is_identical (&pre_insn_fp, fp) + && ! pv_is_register (fp, S390_FRAME_REGNUM, 0)) + || ! pv_is_identical (&pre_insn_back_chain, &data->back_chain)) + result = next_pc; + } + } + + return result; +} + +/* Advance PC across any function entry prologue instructions to reach + some "real" code. */ +static CORE_ADDR +s390_skip_prologue (CORE_ADDR pc) +{ + struct s390_prologue_data data; + CORE_ADDR skip_pc; + skip_pc = s390_analyze_prologue (current_gdbarch, pc, (CORE_ADDR)-1, &data); + return skip_pc ? skip_pc : pc; +} + +/* Return true if we are in the functin's epilogue, i.e. after the + instruction that destroyed the function's stack frame. */ +static int +s390_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + + /* In frameless functions, there's not frame to destroy and thus + we don't care about the epilogue. + + In functions with frame, the epilogue sequence is a pair of + a LM-type instruction that restores (amongst others) the + return register %r14 and the stack pointer %r15, followed + by a branch 'br %r14' --or equivalent-- that effects the + actual return. + + In that situation, this function needs to return 'true' in + exactly one case: when pc points to that branch instruction. + + Thus we try to disassemble the one instructions immediately + preceeding pc and check whether it is an LM-type instruction + modifying the stack pointer. + + Note that disassembling backwards is not reliable, so there + is a slight chance of false positives here ... */ + + bfd_byte insn[6]; + unsigned int r1, r3, b2; + int d2; + + if (word_size == 4 + && !read_memory_nobpt (pc - 4, insn, 4) + && is_rs (insn, op_lm, &r1, &r3, &d2, &b2) + && r3 == S390_SP_REGNUM - S390_R0_REGNUM) + return 1; + + if (word_size == 4 + && !read_memory_nobpt (pc - 6, insn, 6) + && is_rsy (insn, op1_lmy, op2_lmy, &r1, &r3, &d2, &b2) + && r3 == S390_SP_REGNUM - S390_R0_REGNUM) + return 1; + + if (word_size == 8 + && !read_memory_nobpt (pc - 6, insn, 6) + && is_rsy (insn, op1_lmg, op2_lmg, &r1, &r3, &d2, &b2) + && r3 == S390_SP_REGNUM - S390_R0_REGNUM) + return 1; + + return 0; +} + + +/* Normal stack frames. */ + +struct s390_unwind_cache { + + CORE_ADDR func; + CORE_ADDR frame_base; + CORE_ADDR local_base; + + struct trad_frame_saved_reg *saved_regs; +}; + +static int +s390_prologue_frame_unwind_cache (struct frame_info *next_frame, + struct s390_unwind_cache *info) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + struct s390_prologue_data data; + struct prologue_value *fp = &data.gpr[S390_FRAME_REGNUM - S390_R0_REGNUM]; + struct prologue_value *sp = &data.gpr[S390_SP_REGNUM - S390_R0_REGNUM]; + int slot_num; + CORE_ADDR slot_addr; + CORE_ADDR func; + CORE_ADDR result; + ULONGEST reg; + CORE_ADDR prev_sp; + int frame_pointer; + int size; + + /* Try to find the function start address. If we can't find it, we don't + bother searching for it -- with modern compilers this would be mostly + pointless anyway. Trust that we'll either have valid DWARF-2 CFI data + or else a valid backchain ... */ + func = frame_func_unwind (next_frame); + if (!func) + return 0; + + /* Try to analyze the prologue. */ + result = s390_analyze_prologue (gdbarch, func, + frame_pc_unwind (next_frame), &data); + if (!result) + return 0; + + /* If this was successful, we should have found the instruction that + sets the stack pointer register to the previous value of the stack + pointer minus the frame size. */ + if (sp->kind != pv_register || sp->reg != S390_SP_REGNUM) + return 0; + + /* A frame size of zero at this point can mean either a real + frameless function, or else a failure to find the prologue. + Perform some sanity checks to verify we really have a + frameless function. */ + if (sp->k == 0) + { + /* If the next frame is a NORMAL_FRAME, this frame *cannot* have frame + size zero. This is only possible if the next frame is a sentinel + frame, a dummy frame, or a signal trampoline frame. */ + if (get_frame_type (next_frame) == NORMAL_FRAME + /* For some reason, sentinel frames are NORMAL_FRAMEs + -- but they have negative frame level. */ + && frame_relative_level (next_frame) >= 0) + return 0; + + /* If we really have a frameless function, %r14 must be valid + -- in particular, it must point to a different function. */ + reg = frame_unwind_register_unsigned (next_frame, S390_RETADDR_REGNUM); + reg = gdbarch_addr_bits_remove (gdbarch, reg) - 1; + if (get_pc_function_start (reg) == func) + { + /* However, there is one case where it *is* valid for %r14 + to point to the same function -- if this is a recursive + call, and we have stopped in the prologue *before* the + stack frame was allocated. + + Recognize this case by looking ahead a bit ... */ + + struct s390_prologue_data data2; + struct prologue_value *sp = &data2.gpr[S390_SP_REGNUM - S390_R0_REGNUM]; + + if (!(s390_analyze_prologue (gdbarch, func, (CORE_ADDR)-1, &data2) + && sp->kind == pv_register + && sp->reg == S390_SP_REGNUM + && sp->k != 0)) + return 0; + } + } + + + /* OK, we've found valid prologue data. */ + size = -sp->k; + + /* If the frame pointer originally also holds the same value + as the stack pointer, we're probably using it. If it holds + some other value -- even a constant offset -- it is most + likely used as temp register. */ + if (pv_is_identical (sp, fp)) + frame_pointer = S390_FRAME_REGNUM; + else + frame_pointer = S390_SP_REGNUM; + + /* If we've detected a function with stack frame, we'll still have to + treat it as frameless if we're currently within the function epilog + code at a point where the frame pointer has already been restored. + This can only happen in an innermost frame. */ + if (size > 0 + && (get_frame_type (next_frame) != NORMAL_FRAME + || frame_relative_level (next_frame) < 0)) + { + /* See the comment in s390_in_function_epilogue_p on why this is + not completely reliable ... */ + if (s390_in_function_epilogue_p (gdbarch, frame_pc_unwind (next_frame))) + { + memset (&data, 0, sizeof (data)); + size = 0; + frame_pointer = S390_SP_REGNUM; + } + } + + /* Once we know the frame register and the frame size, we can unwind + the current value of the frame register from the next frame, and + add back the frame size to arrive that the previous frame's + stack pointer value. */ + prev_sp = frame_unwind_register_unsigned (next_frame, frame_pointer) + size; + + /* Scan the spill array; if a spill slot says it holds the + original value of some register, then record that slot's + address as the place that register was saved. */ + + /* Slots for %r2 .. %r15. */ + for (slot_num = 0, slot_addr = prev_sp + 2 * data.gpr_size; + slot_num < 14; + slot_num++, slot_addr += data.gpr_size) + { + struct prologue_value *slot = &data.spill[slot_num]; + + if (slot->kind == pv_register + && slot->k == 0) + info->saved_regs[slot->reg].addr = slot_addr; + } + + /* Slots for %f0 .. %f6. */ + for (slot_num = 14, slot_addr = prev_sp + 16 * data.gpr_size; + slot_num < S390_NUM_SPILL_SLOTS; + slot_num++, slot_addr += data.fpr_size) + { + struct prologue_value *slot = &data.spill[slot_num]; + + if (slot->kind == pv_register + && slot->k == 0) + info->saved_regs[slot->reg].addr = slot_addr; + } + + /* Function return will set PC to %r14. */ + info->saved_regs[S390_PC_REGNUM] = info->saved_regs[S390_RETADDR_REGNUM]; + + /* In frameless functions, we unwind simply by moving the return + address to the PC. However, if we actually stored to the + save area, use that -- we might only think the function frameless + because we're in the middle of the prologue ... */ + if (size == 0 + && !trad_frame_addr_p (info->saved_regs, S390_PC_REGNUM)) + { + info->saved_regs[S390_PC_REGNUM].realreg = S390_RETADDR_REGNUM; + } + + /* Another sanity check: unless this is a frameless function, + we should have found spill slots for SP and PC. + If not, we cannot unwind further -- this happens e.g. in + libc's thread_start routine. */ + if (size > 0) + { + if (!trad_frame_addr_p (info->saved_regs, S390_SP_REGNUM) + || !trad_frame_addr_p (info->saved_regs, S390_PC_REGNUM)) + prev_sp = -1; + } + + /* We use the current value of the frame register as local_base, + and the top of the register save area as frame_base. */ + if (prev_sp != -1) + { + info->frame_base = prev_sp + 16*word_size + 32; + info->local_base = prev_sp - size; + } + + info->func = func; + return 1; +} + +static void +s390_backchain_frame_unwind_cache (struct frame_info *next_frame, + struct s390_unwind_cache *info) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + CORE_ADDR backchain; + ULONGEST reg; + LONGEST sp; + + /* Get the backchain. */ + reg = frame_unwind_register_unsigned (next_frame, S390_SP_REGNUM); + backchain = read_memory_unsigned_integer (reg, word_size); + + /* A zero backchain terminates the frame chain. As additional + sanity check, let's verify that the spill slot for SP in the + save area pointed to by the backchain in fact links back to + the save area. */ + if (backchain != 0 + && safe_read_memory_integer (backchain + 15*word_size, word_size, &sp) + && (CORE_ADDR)sp == backchain) + { + /* We don't know which registers were saved, but it will have + to be at least %r14 and %r15. This will allow us to continue + unwinding, but other prev-frame registers may be incorrect ... */ + info->saved_regs[S390_SP_REGNUM].addr = backchain + 15*word_size; + info->saved_regs[S390_RETADDR_REGNUM].addr = backchain + 14*word_size; + + /* Function return will set PC to %r14. */ + info->saved_regs[S390_PC_REGNUM] = info->saved_regs[S390_RETADDR_REGNUM]; + + /* We use the current value of the frame register as local_base, + and the top of the register save area as frame_base. */ + info->frame_base = backchain + 16*word_size + 32; + info->local_base = reg; + } + + info->func = frame_pc_unwind (next_frame); +} + +static struct s390_unwind_cache * +s390_frame_unwind_cache (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct s390_unwind_cache *info; + if (*this_prologue_cache) + return *this_prologue_cache; + + info = FRAME_OBSTACK_ZALLOC (struct s390_unwind_cache); + *this_prologue_cache = info; + info->saved_regs = trad_frame_alloc_saved_regs (next_frame); + info->func = -1; + info->frame_base = -1; + info->local_base = -1; + + /* Try to use prologue analysis to fill the unwind cache. + If this fails, fall back to reading the stack backchain. */ + if (!s390_prologue_frame_unwind_cache (next_frame, info)) + s390_backchain_frame_unwind_cache (next_frame, info); + + return info; +} + +static void +s390_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct s390_unwind_cache *info + = s390_frame_unwind_cache (next_frame, this_prologue_cache); + + if (info->frame_base == -1) + return; + + *this_id = frame_id_build (info->frame_base, info->func); +} + +static void +s390_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) +{ + struct s390_unwind_cache *info + = s390_frame_unwind_cache (next_frame, this_prologue_cache); + trad_frame_prev_register (next_frame, info->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); +} + +static const struct frame_unwind s390_frame_unwind = { + NORMAL_FRAME, + s390_frame_this_id, + s390_frame_prev_register +}; + +static const struct frame_unwind * +s390_frame_sniffer (struct frame_info *next_frame) +{ + return &s390_frame_unwind; +} + + +/* Code stubs and their stack frames. For things like PLTs and NULL + function calls (where there is no true frame and the return address + is in the RETADDR register). */ + +struct s390_stub_unwind_cache +{ + CORE_ADDR frame_base; + struct trad_frame_saved_reg *saved_regs; +}; + +static struct s390_stub_unwind_cache * +s390_stub_frame_unwind_cache (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + struct s390_stub_unwind_cache *info; + ULONGEST reg; + + if (*this_prologue_cache) + return *this_prologue_cache; + + info = FRAME_OBSTACK_ZALLOC (struct s390_stub_unwind_cache); + *this_prologue_cache = info; + info->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + /* The return address is in register %r14. */ + info->saved_regs[S390_PC_REGNUM].realreg = S390_RETADDR_REGNUM; + + /* Retrieve stack pointer and determine our frame base. */ + reg = frame_unwind_register_unsigned (next_frame, S390_SP_REGNUM); + info->frame_base = reg + 16*word_size + 32; + + return info; +} + +static void +s390_stub_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct s390_stub_unwind_cache *info + = s390_stub_frame_unwind_cache (next_frame, this_prologue_cache); + *this_id = frame_id_build (info->frame_base, frame_pc_unwind (next_frame)); +} + +static void +s390_stub_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) +{ + struct s390_stub_unwind_cache *info + = s390_stub_frame_unwind_cache (next_frame, this_prologue_cache); + trad_frame_prev_register (next_frame, info->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); +} + +static const struct frame_unwind s390_stub_frame_unwind = { + NORMAL_FRAME, + s390_stub_frame_this_id, + s390_stub_frame_prev_register +}; + +static const struct frame_unwind * +s390_stub_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + bfd_byte insn[S390_MAX_INSTR_SIZE]; + + /* If the current PC points to non-readable memory, we assume we + have trapped due to an invalid function pointer call. We handle + the non-existing current function like a PLT stub. */ + if (in_plt_section (pc, NULL) + || s390_readinstruction (insn, pc) < 0) + return &s390_stub_frame_unwind; + return NULL; +} + + +/* Signal trampoline stack frames. */ + +struct s390_sigtramp_unwind_cache { + CORE_ADDR frame_base; + struct trad_frame_saved_reg *saved_regs; +}; + +static struct s390_sigtramp_unwind_cache * +s390_sigtramp_frame_unwind_cache (struct frame_info *next_frame, + void **this_prologue_cache) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + struct s390_sigtramp_unwind_cache *info; + ULONGEST this_sp, prev_sp; + CORE_ADDR next_ra, next_cfa, sigreg_ptr; + int i; + + if (*this_prologue_cache) + return *this_prologue_cache; + + info = FRAME_OBSTACK_ZALLOC (struct s390_sigtramp_unwind_cache); + *this_prologue_cache = info; + info->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + this_sp = frame_unwind_register_unsigned (next_frame, S390_SP_REGNUM); + next_ra = frame_pc_unwind (next_frame); + next_cfa = this_sp + 16*word_size + 32; + + /* New-style RT frame: + retcode + alignment (8 bytes) + siginfo (128 bytes) + ucontext (contains sigregs at offset 5 words) */ + if (next_ra == next_cfa) + { + sigreg_ptr = next_cfa + 8 + 128 + 5*word_size; + } + + /* Old-style RT frame and all non-RT frames: + old signal mask (8 bytes) + pointer to sigregs */ + else + { + sigreg_ptr = read_memory_unsigned_integer (next_cfa + 8, word_size); + } + + /* The sigregs structure looks like this: + long psw_mask; + long psw_addr; + long gprs[16]; + int acrs[16]; + int fpc; + int __pad; + double fprs[16]; */ + + /* Let's ignore the PSW mask, it will not be restored anyway. */ + sigreg_ptr += word_size; + + /* Next comes the PSW address. */ + info->saved_regs[S390_PC_REGNUM].addr = sigreg_ptr; + sigreg_ptr += word_size; + + /* Then the GPRs. */ + for (i = 0; i < 16; i++) + { + info->saved_regs[S390_R0_REGNUM + i].addr = sigreg_ptr; + sigreg_ptr += word_size; + } + + /* Then the ACRs. */ + for (i = 0; i < 16; i++) + { + info->saved_regs[S390_A0_REGNUM + i].addr = sigreg_ptr; + sigreg_ptr += 4; + } + + /* The floating-point control word. */ + info->saved_regs[S390_FPC_REGNUM].addr = sigreg_ptr; + sigreg_ptr += 8; + + /* And finally the FPRs. */ + for (i = 0; i < 16; i++) + { + info->saved_regs[S390_F0_REGNUM + i].addr = sigreg_ptr; + sigreg_ptr += 8; + } + + /* Restore the previous frame's SP. */ + prev_sp = read_memory_unsigned_integer ( + info->saved_regs[S390_SP_REGNUM].addr, + word_size); + + /* Determine our frame base. */ + info->frame_base = prev_sp + 16*word_size + 32; + + return info; +} + +static void +s390_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct s390_sigtramp_unwind_cache *info + = s390_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache); + *this_id = frame_id_build (info->frame_base, frame_pc_unwind (next_frame)); +} + +static void +s390_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) +{ + struct s390_sigtramp_unwind_cache *info + = s390_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache); + trad_frame_prev_register (next_frame, info->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); +} + +static const struct frame_unwind s390_sigtramp_frame_unwind = { + SIGTRAMP_FRAME, + s390_sigtramp_frame_this_id, + s390_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +s390_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + bfd_byte sigreturn[2]; + + if (read_memory_nobpt (pc, sigreturn, 2)) + return NULL; + + if (sigreturn[0] != 0x0a /* svc */) + return NULL; + + if (sigreturn[1] != 119 /* sigreturn */ + && sigreturn[1] != 173 /* rt_sigreturn */) + return NULL; + + return &s390_sigtramp_frame_unwind; +} + + +/* Frame base handling. */ + +static CORE_ADDR +s390_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct s390_unwind_cache *info + = s390_frame_unwind_cache (next_frame, this_cache); + return info->frame_base; +} + +static CORE_ADDR +s390_local_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct s390_unwind_cache *info + = s390_frame_unwind_cache (next_frame, this_cache); + return info->local_base; +} + +static const struct frame_base s390_frame_base = { + &s390_frame_unwind, + s390_frame_base_address, + s390_local_base_address, + s390_local_base_address +}; + +static CORE_ADDR +s390_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST pc; + pc = frame_unwind_register_unsigned (next_frame, S390_PC_REGNUM); + return gdbarch_addr_bits_remove (gdbarch, pc); +} + +static CORE_ADDR +s390_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST sp; + sp = frame_unwind_register_unsigned (next_frame, S390_SP_REGNUM); + return gdbarch_addr_bits_remove (gdbarch, sp); +} + + +/* DWARF-2 frame support. */ + +static void +s390_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, + struct dwarf2_frame_state_reg *reg) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + switch (tdep->abi) + { + case ABI_LINUX_S390: + /* Call-saved registers. */ + if ((regnum >= S390_R6_REGNUM && regnum <= S390_R15_REGNUM) + || regnum == S390_F4_REGNUM + || regnum == S390_F6_REGNUM) + reg->how = DWARF2_FRAME_REG_SAME_VALUE; + + /* Call-clobbered registers. */ + else if ((regnum >= S390_R0_REGNUM && regnum <= S390_R5_REGNUM) + || (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM + && regnum != S390_F4_REGNUM && regnum != S390_F6_REGNUM)) + reg->how = DWARF2_FRAME_REG_UNDEFINED; + + /* The return address column. */ + else if (regnum == S390_PC_REGNUM) + reg->how = DWARF2_FRAME_REG_RA; + break; + + case ABI_LINUX_ZSERIES: + /* Call-saved registers. */ + if ((regnum >= S390_R6_REGNUM && regnum <= S390_R15_REGNUM) + || (regnum >= S390_F8_REGNUM && regnum <= S390_F15_REGNUM)) + reg->how = DWARF2_FRAME_REG_SAME_VALUE; + + /* Call-clobbered registers. */ + else if ((regnum >= S390_R0_REGNUM && regnum <= S390_R5_REGNUM) + || (regnum >= S390_F0_REGNUM && regnum <= S390_F7_REGNUM)) + reg->how = DWARF2_FRAME_REG_UNDEFINED; + + /* The return address column. */ + else if (regnum == S390_PC_REGNUM) + reg->how = DWARF2_FRAME_REG_RA; + break; + } +} + + +/* Dummy function calls. */ + +/* Return non-zero if TYPE is an integer-like type, zero otherwise. + "Integer-like" types are those that should be passed the way + integers are: integers, enums, ranges, characters, and booleans. */ +static int +is_integer_like (struct type *type) +{ + enum type_code code = TYPE_CODE (type); + + return (code == TYPE_CODE_INT + || code == TYPE_CODE_ENUM + || code == TYPE_CODE_RANGE + || code == TYPE_CODE_CHAR + || code == TYPE_CODE_BOOL); +} + +/* Return non-zero if TYPE is a pointer-like type, zero otherwise. + "Pointer-like" types are those that should be passed the way + pointers are: pointers and references. */ +static int +is_pointer_like (struct type *type) +{ + enum type_code code = TYPE_CODE (type); + + return (code == TYPE_CODE_PTR + || code == TYPE_CODE_REF); +} + + +/* Return non-zero if TYPE is a `float singleton' or `double + singleton', zero otherwise. + + A `T singleton' is a struct type with one member, whose type is + either T or a `T singleton'. So, the following are all float + singletons: + + struct { float x }; + struct { struct { float x; } x; }; + struct { struct { struct { float x; } x; } x; }; + + ... and so on. + + All such structures are passed as if they were floats or doubles, + as the (revised) ABI says. */ +static int +is_float_singleton (struct type *type) +{ + if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) + { + struct type *singleton_type = TYPE_FIELD_TYPE (type, 0); + CHECK_TYPEDEF (singleton_type); + + return (TYPE_CODE (singleton_type) == TYPE_CODE_FLT + || is_float_singleton (singleton_type)); + } + + return 0; +} + + +/* Return non-zero if TYPE is a struct-like type, zero otherwise. + "Struct-like" types are those that should be passed as structs are: + structs and unions. + + As an odd quirk, not mentioned in the ABI, GCC passes float and + double singletons as if they were a plain float, double, etc. (The + corresponding union types are handled normally.) So we exclude + those types here. *shrug* */ +static int +is_struct_like (struct type *type) +{ + enum type_code code = TYPE_CODE (type); + + return (code == TYPE_CODE_UNION + || (code == TYPE_CODE_STRUCT && ! is_float_singleton (type))); +} + + +/* Return non-zero if TYPE is a float-like type, zero otherwise. + "Float-like" types are those that should be passed as + floating-point values are. + + You'd think this would just be floats, doubles, long doubles, etc. + But as an odd quirk, not mentioned in the ABI, GCC passes float and + double singletons as if they were a plain float, double, etc. (The + corresponding union types are handled normally.) So we include + those types here. *shrug* */ +static int +is_float_like (struct type *type) +{ + return (TYPE_CODE (type) == TYPE_CODE_FLT + || is_float_singleton (type)); +} + + +static int +is_power_of_two (unsigned int n) +{ + return ((n & (n - 1)) == 0); +} + +/* Return non-zero if TYPE should be passed as a pointer to a copy, + zero otherwise. */ +static int +s390_function_arg_pass_by_reference (struct type *type) +{ + unsigned length = TYPE_LENGTH (type); + if (length > 8) + return 1; + + /* FIXME: All complex and vector types are also returned by reference. */ + return is_struct_like (type) && !is_power_of_two (length); +} + +/* Return non-zero if TYPE should be passed in a float register + if possible. */ +static int +s390_function_arg_float (struct type *type) +{ + unsigned length = TYPE_LENGTH (type); + if (length > 8) + return 0; + + return is_float_like (type); +} + +/* Return non-zero if TYPE should be passed in an integer register + (or a pair of integer registers) if possible. */ +static int +s390_function_arg_integer (struct type *type) +{ + unsigned length = TYPE_LENGTH (type); + if (length > 8) + return 0; + + return is_integer_like (type) + || is_pointer_like (type) + || (is_struct_like (type) && is_power_of_two (length)); +} + +/* Return ARG, a `SIMPLE_ARG', sign-extended or zero-extended to a full + word as required for the ABI. */ +static LONGEST +extend_simple_arg (struct value *arg) +{ + struct type *type = VALUE_TYPE (arg); + + /* Even structs get passed in the least significant bits of the + register / memory word. It's not really right to extract them as + an integer, but it does take care of the extension. */ + if (TYPE_UNSIGNED (type)) + return extract_unsigned_integer (VALUE_CONTENTS (arg), + TYPE_LENGTH (type)); + else + return extract_signed_integer (VALUE_CONTENTS (arg), + TYPE_LENGTH (type)); +} + + +/* Return the alignment required by TYPE. */ +static int +alignment_of (struct type *type) +{ + int alignment; + + if (is_integer_like (type) + || is_pointer_like (type) + || TYPE_CODE (type) == TYPE_CODE_FLT) + alignment = TYPE_LENGTH (type); + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION) + { + int i; + + alignment = 1; + for (i = 0; i < TYPE_NFIELDS (type); i++) + { + int field_alignment = alignment_of (TYPE_FIELD_TYPE (type, i)); + + if (field_alignment > alignment) + alignment = field_alignment; + } + } + else + alignment = 1; + + /* Check that everything we ever return is a power of two. Lots of + code doesn't want to deal with aligning things to arbitrary + boundaries. */ + gdb_assert ((alignment & (alignment - 1)) == 0); + + return alignment; +} + + +/* Put the actual parameter values pointed to by ARGS[0..NARGS-1] in + place to be passed to a function, as specified by the "GNU/Linux + for S/390 ELF Application Binary Interface Supplement". + + SP is the current stack pointer. We must put arguments, links, + padding, etc. whereever they belong, and return the new stack + pointer value. + + If STRUCT_RETURN is non-zero, then the function we're calling is + going to return a structure by value; STRUCT_ADDR is the address of + a block we've allocated for it on the stack. + + Our caller has taken care of any type promotions needed to satisfy + prototypes or the old K&R argument-passing rules. */ +static CORE_ADDR +s390_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + ULONGEST orig_sp; + int i; + + /* If the i'th argument is passed as a reference to a copy, then + copy_addr[i] is the address of the copy we made. */ + CORE_ADDR *copy_addr = alloca (nargs * sizeof (CORE_ADDR)); + + /* Build the reference-to-copy area. */ + for (i = 0; i < nargs; i++) + { + struct value *arg = args[i]; + struct type *type = VALUE_TYPE (arg); + unsigned length = TYPE_LENGTH (type); + + if (s390_function_arg_pass_by_reference (type)) + { + sp -= length; + sp = align_down (sp, alignment_of (type)); + write_memory (sp, VALUE_CONTENTS (arg), length); + copy_addr[i] = sp; + } + } + + /* Reserve space for the parameter area. As a conservative + simplification, we assume that everything will be passed on the + stack. Since every argument larger than 8 bytes will be + passed by reference, we use this simple upper bound. */ + sp -= nargs * 8; + + /* After all that, make sure it's still aligned on an eight-byte + boundary. */ + sp = align_down (sp, 8); + + /* Finally, place the actual parameters, working from SP towards + higher addresses. The code above is supposed to reserve enough + space for this. */ + { + int fr = 0; + int gr = 2; + CORE_ADDR starg = sp; + + /* A struct is returned using general register 2. */ + if (struct_return) + { + regcache_cooked_write_unsigned (regcache, S390_R0_REGNUM + gr, + struct_addr); + gr++; + } + + for (i = 0; i < nargs; i++) + { + struct value *arg = args[i]; + struct type *type = VALUE_TYPE (arg); + unsigned length = TYPE_LENGTH (type); + + if (s390_function_arg_pass_by_reference (type)) + { + if (gr <= 6) + { + regcache_cooked_write_unsigned (regcache, S390_R0_REGNUM + gr, + copy_addr[i]); + gr++; + } + else + { + write_memory_unsigned_integer (starg, word_size, copy_addr[i]); + starg += word_size; + } + } + else if (s390_function_arg_float (type)) + { + /* The GNU/Linux for S/390 ABI uses FPRs 0 and 2 to pass arguments, + the GNU/Linux for zSeries ABI uses 0, 2, 4, and 6. */ + if (fr <= (tdep->abi == ABI_LINUX_S390 ? 2 : 6)) + { + /* When we store a single-precision value in an FP register, + it occupies the leftmost bits. */ + regcache_cooked_write_part (regcache, S390_F0_REGNUM + fr, + 0, length, VALUE_CONTENTS (arg)); + fr += 2; + } + else + { + /* When we store a single-precision value in a stack slot, + it occupies the rightmost bits. */ + starg = align_up (starg + length, word_size); + write_memory (starg - length, VALUE_CONTENTS (arg), length); + } + } + else if (s390_function_arg_integer (type) && length <= word_size) + { + if (gr <= 6) + { + /* Integer arguments are always extended to word size. */ + regcache_cooked_write_signed (regcache, S390_R0_REGNUM + gr, + extend_simple_arg (arg)); + gr++; + } + else + { + /* Integer arguments are always extended to word size. */ + write_memory_signed_integer (starg, word_size, + extend_simple_arg (arg)); + starg += word_size; + } + } + else if (s390_function_arg_integer (type) && length == 2*word_size) + { + if (gr <= 5) + { + regcache_cooked_write (regcache, S390_R0_REGNUM + gr, + VALUE_CONTENTS (arg)); + regcache_cooked_write (regcache, S390_R0_REGNUM + gr + 1, + VALUE_CONTENTS (arg) + word_size); + gr += 2; + } + else + { + /* If we skipped r6 because we couldn't fit a DOUBLE_ARG + in it, then don't go back and use it again later. */ + gr = 7; + + write_memory (starg, VALUE_CONTENTS (arg), length); + starg += length; + } + } + else + internal_error (__FILE__, __LINE__, "unknown argument type"); + } + } + + /* Allocate the standard frame areas: the register save area, the + word reserved for the compiler (which seems kind of meaningless), + and the back chain pointer. */ + sp -= 16*word_size + 32; + + /* Write the back chain pointer into the first word of the stack + frame. This is needed to unwind across a dummy frame. */ + regcache_cooked_read_unsigned (regcache, S390_SP_REGNUM, &orig_sp); + write_memory_unsigned_integer (sp, word_size, orig_sp); + + /* Store return address. */ + regcache_cooked_write_unsigned (regcache, S390_RETADDR_REGNUM, bp_addr); + + /* Store updated stack pointer. */ + regcache_cooked_write_unsigned (regcache, S390_SP_REGNUM, sp); + + /* We need to return the 'stack part' of the frame ID, + which is actually the top of the register save area + allocated on the original stack. */ + return orig_sp + 16*word_size + 32; +} + +/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that + dummy frame. The frame ID's base needs to match the TOS value + returned by push_dummy_call, and the PC match the dummy frame's + breakpoint. */ +static struct frame_id +s390_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + CORE_ADDR this_sp = s390_unwind_sp (gdbarch, next_frame); + CORE_ADDR prev_sp = read_memory_unsigned_integer (this_sp, word_size); + + return frame_id_build (prev_sp + 16*word_size + 32, + frame_pc_unwind (next_frame)); +} + +static CORE_ADDR +s390_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + /* Both the 32- and 64-bit ABI's say that the stack pointer should + always be aligned on an eight-byte boundary. */ + return (addr & -8); +} + + +/* Function return value access. */ + +static enum return_value_convention +s390_return_value_convention (struct gdbarch *gdbarch, struct type *type) +{ + int length = TYPE_LENGTH (type); + if (length > 8) + return RETURN_VALUE_STRUCT_CONVENTION; + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_ARRAY: + return RETURN_VALUE_STRUCT_CONVENTION; + + default: + return RETURN_VALUE_REGISTER_CONVENTION; + } +} + +static enum return_value_convention +s390_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, void *out, const void *in) +{ + int word_size = gdbarch_ptr_bit (gdbarch) / 8; + int length = TYPE_LENGTH (type); + enum return_value_convention rvc = + s390_return_value_convention (gdbarch, type); + if (in) + { + switch (rvc) + { + case RETURN_VALUE_REGISTER_CONVENTION: + if (TYPE_CODE (type) == TYPE_CODE_FLT) + { + /* When we store a single-precision value in an FP register, + it occupies the leftmost bits. */ + regcache_cooked_write_part (regcache, S390_F0_REGNUM, + 0, length, in); + } + else if (length <= word_size) + { + /* Integer arguments are always extended to word size. */ + if (TYPE_UNSIGNED (type)) + regcache_cooked_write_unsigned (regcache, S390_R2_REGNUM, + extract_unsigned_integer (in, length)); + else + regcache_cooked_write_signed (regcache, S390_R2_REGNUM, + extract_signed_integer (in, length)); + } + else if (length == 2*word_size) + { + regcache_cooked_write (regcache, S390_R2_REGNUM, in); + regcache_cooked_write (regcache, S390_R3_REGNUM, + (const char *)in + word_size); + } + else + internal_error (__FILE__, __LINE__, "invalid return type"); + break; + + case RETURN_VALUE_STRUCT_CONVENTION: + error ("Cannot set function return value."); + break; + } + } + else if (out) + { + switch (rvc) + { + case RETURN_VALUE_REGISTER_CONVENTION: + if (TYPE_CODE (type) == TYPE_CODE_FLT) + { + /* When we store a single-precision value in an FP register, + it occupies the leftmost bits. */ + regcache_cooked_read_part (regcache, S390_F0_REGNUM, + 0, length, out); + } + else if (length <= word_size) + { + /* Integer arguments occupy the rightmost bits. */ + regcache_cooked_read_part (regcache, S390_R2_REGNUM, + word_size - length, length, out); + } + else if (length == 2*word_size) + { + regcache_cooked_read (regcache, S390_R2_REGNUM, out); + regcache_cooked_read (regcache, S390_R3_REGNUM, + (char *)out + word_size); + } + else + internal_error (__FILE__, __LINE__, "invalid return type"); + break; + + case RETURN_VALUE_STRUCT_CONVENTION: + error ("Function return value unknown."); + break; + } + } + + return rvc; +} + + +/* Breakpoints. */ + +static const unsigned char * +s390_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +{ + static unsigned char breakpoint[] = { 0x0, 0x1 }; + + *lenptr = sizeof (breakpoint); + return breakpoint; +} + + +/* Address handling. */ + +static CORE_ADDR +s390_addr_bits_remove (CORE_ADDR addr) +{ + return addr & 0x7fffffff; +} + +static int +s390_address_class_type_flags (int byte_size, int dwarf2_addr_class) +{ + if (byte_size == 4) + return TYPE_FLAG_ADDRESS_CLASS_1; + else + return 0; +} + +static const char * +s390_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags) +{ + if (type_flags & TYPE_FLAG_ADDRESS_CLASS_1) + return "mode32"; + else + return NULL; +} + +static int +s390_address_class_name_to_type_flags (struct gdbarch *gdbarch, const char *name, + int *type_flags_ptr) +{ + if (strcmp (name, "mode32") == 0) + { + *type_flags_ptr = TYPE_FLAG_ADDRESS_CLASS_1; + return 1; + } + else + return 0; +} + + +/* Link map offsets. */ + +static struct link_map_offsets * +s390_svr4_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + lmo.r_debug_size = 8; + + lmo.r_map_offset = 4; + lmo.r_map_size = 4; + + lmo.link_map_size = 20; + + lmo.l_addr_offset = 0; + lmo.l_addr_size = 4; + + lmo.l_name_offset = 4; + lmo.l_name_size = 4; + + lmo.l_next_offset = 12; + lmo.l_next_size = 4; + + lmo.l_prev_offset = 16; + lmo.l_prev_size = 4; + } + + return lmp; +} + +static struct link_map_offsets * +s390x_svr4_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + lmo.r_debug_size = 16; /* All we need. */ + + lmo.r_map_offset = 8; + lmo.r_map_size = 8; + + lmo.link_map_size = 40; /* All we need. */ + + lmo.l_addr_offset = 0; + lmo.l_addr_size = 8; + + lmo.l_name_offset = 8; + lmo.l_name_size = 8; + + lmo.l_next_offset = 24; + lmo.l_next_size = 8; + + lmo.l_prev_offset = 32; + lmo.l_prev_size = 8; + } + + return lmp; +} + + +/* Set up gdbarch struct. */ + +static struct gdbarch * +s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + struct gdbarch *gdbarch; + struct gdbarch_tdep *tdep; + + /* First see if there is already a gdbarch that can satisfy the request. */ + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != NULL) + return arches->gdbarch; + + /* None found: is the request for a s390 architecture? */ + if (info.bfd_arch_info->arch != bfd_arch_s390) + return NULL; /* No; then it's not for us. */ + + /* Yes: create a new gdbarch for the specified machine type. */ + tdep = XCALLOC (1, struct gdbarch_tdep); + gdbarch = gdbarch_alloc (&info, tdep); + + set_gdbarch_believe_pcc_promotion (gdbarch, 0); + set_gdbarch_char_signed (gdbarch, 0); + + /* Amount PC must be decremented by after a breakpoint. This is + often the number of bytes returned by BREAKPOINT_FROM_PC but not + always. */ + set_gdbarch_decr_pc_after_break (gdbarch, 2); + /* Stack grows downward. */ + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_breakpoint_from_pc (gdbarch, s390_breakpoint_from_pc); + set_gdbarch_skip_prologue (gdbarch, s390_skip_prologue); + set_gdbarch_in_function_epilogue_p (gdbarch, s390_in_function_epilogue_p); + + set_gdbarch_pc_regnum (gdbarch, S390_PC_REGNUM); + set_gdbarch_sp_regnum (gdbarch, S390_SP_REGNUM); + set_gdbarch_fp0_regnum (gdbarch, S390_F0_REGNUM); + set_gdbarch_num_regs (gdbarch, S390_NUM_REGS); + set_gdbarch_num_pseudo_regs (gdbarch, S390_NUM_PSEUDO_REGS); + set_gdbarch_register_name (gdbarch, s390_register_name); + set_gdbarch_register_type (gdbarch, s390_register_type); + set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); + set_gdbarch_dwarf_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); + set_gdbarch_convert_register_p (gdbarch, s390_convert_register_p); + set_gdbarch_register_to_value (gdbarch, s390_register_to_value); + set_gdbarch_value_to_register (gdbarch, s390_value_to_register); + set_gdbarch_register_reggroup_p (gdbarch, s390_register_reggroup_p); + set_gdbarch_regset_from_core_section (gdbarch, + s390_regset_from_core_section); + + /* Inferior function calls. */ + set_gdbarch_push_dummy_call (gdbarch, s390_push_dummy_call); + set_gdbarch_unwind_dummy_id (gdbarch, s390_unwind_dummy_id); + set_gdbarch_frame_align (gdbarch, s390_frame_align); + set_gdbarch_return_value (gdbarch, s390_return_value); + + /* Frame handling. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); + dwarf2_frame_set_init_reg (gdbarch, s390_dwarf2_frame_init_reg); + frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); + frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer); + frame_unwind_append_sniffer (gdbarch, s390_stub_frame_sniffer); + frame_unwind_append_sniffer (gdbarch, s390_sigtramp_frame_sniffer); + frame_unwind_append_sniffer (gdbarch, s390_frame_sniffer); + frame_base_set_default (gdbarch, &s390_frame_base); + set_gdbarch_unwind_pc (gdbarch, s390_unwind_pc); + set_gdbarch_unwind_sp (gdbarch, s390_unwind_sp); + + switch (info.bfd_arch_info->mach) + { + case bfd_mach_s390_31: + tdep->abi = ABI_LINUX_S390; + + tdep->gregset = &s390_gregset; + tdep->sizeof_gregset = s390_sizeof_gregset; + tdep->fpregset = &s390_fpregset; + tdep->sizeof_fpregset = s390_sizeof_fpregset; + + set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove); + set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, s390_pseudo_register_write); + set_solib_svr4_fetch_link_map_offsets (gdbarch, + s390_svr4_fetch_link_map_offsets); + + break; + case bfd_mach_s390_64: + tdep->abi = ABI_LINUX_ZSERIES; + + tdep->gregset = &s390x_gregset; + tdep->sizeof_gregset = s390x_sizeof_gregset; + tdep->fpregset = &s390_fpregset; + tdep->sizeof_fpregset = s390_sizeof_fpregset; + + set_gdbarch_long_bit (gdbarch, 64); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_ptr_bit (gdbarch, 64); + set_gdbarch_pseudo_register_read (gdbarch, s390x_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, s390x_pseudo_register_write); + set_solib_svr4_fetch_link_map_offsets (gdbarch, + s390x_svr4_fetch_link_map_offsets); + set_gdbarch_address_class_type_flags (gdbarch, + s390_address_class_type_flags); + set_gdbarch_address_class_type_flags_to_name (gdbarch, + s390_address_class_type_flags_to_name); + set_gdbarch_address_class_name_to_type_flags (gdbarch, + s390_address_class_name_to_type_flags); + break; + } + + set_gdbarch_print_insn (gdbarch, print_insn_s390); + + return gdbarch; +} + + + +extern initialize_file_ftype _initialize_s390_tdep; /* -Wmissing-prototypes */ + +void +_initialize_s390_tdep (void) +{ + + /* Hook us into the gdbarch mechanism. */ + register_gdbarch_init (bfd_arch_s390, s390_gdbarch_init); +} diff --git a/contrib/gdb/gdb/s390-tdep.h b/contrib/gdb/gdb/s390-tdep.h new file mode 100644 index 00000000000..241c1feb2f2 --- /dev/null +++ b/contrib/gdb/gdb/s390-tdep.h @@ -0,0 +1,105 @@ +/* Target-dependent code for GDB, the GNU debugger. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef S390_TDEP_H +#define S390_TDEP_H + +/* Register information. */ + +/* Program Status Word. */ +#define S390_PSWM_REGNUM 0 +#define S390_PSWA_REGNUM 1 +/* General Purpose Registers. */ +#define S390_R0_REGNUM 2 +#define S390_R1_REGNUM 3 +#define S390_R2_REGNUM 4 +#define S390_R3_REGNUM 5 +#define S390_R4_REGNUM 6 +#define S390_R5_REGNUM 7 +#define S390_R6_REGNUM 8 +#define S390_R7_REGNUM 9 +#define S390_R8_REGNUM 10 +#define S390_R9_REGNUM 11 +#define S390_R10_REGNUM 12 +#define S390_R11_REGNUM 13 +#define S390_R12_REGNUM 14 +#define S390_R13_REGNUM 15 +#define S390_R14_REGNUM 16 +#define S390_R15_REGNUM 17 +/* Access Registers. */ +#define S390_A0_REGNUM 18 +#define S390_A1_REGNUM 19 +#define S390_A2_REGNUM 20 +#define S390_A3_REGNUM 21 +#define S390_A4_REGNUM 22 +#define S390_A5_REGNUM 23 +#define S390_A6_REGNUM 24 +#define S390_A7_REGNUM 25 +#define S390_A8_REGNUM 26 +#define S390_A9_REGNUM 27 +#define S390_A10_REGNUM 28 +#define S390_A11_REGNUM 29 +#define S390_A12_REGNUM 30 +#define S390_A13_REGNUM 31 +#define S390_A14_REGNUM 32 +#define S390_A15_REGNUM 33 +/* Floating Point Control Word. */ +#define S390_FPC_REGNUM 34 +/* Floating Point Registers. */ +#define S390_F0_REGNUM 35 +#define S390_F1_REGNUM 36 +#define S390_F2_REGNUM 37 +#define S390_F3_REGNUM 38 +#define S390_F4_REGNUM 39 +#define S390_F5_REGNUM 40 +#define S390_F6_REGNUM 41 +#define S390_F7_REGNUM 42 +#define S390_F8_REGNUM 43 +#define S390_F9_REGNUM 44 +#define S390_F10_REGNUM 45 +#define S390_F11_REGNUM 46 +#define S390_F12_REGNUM 47 +#define S390_F13_REGNUM 48 +#define S390_F14_REGNUM 49 +#define S390_F15_REGNUM 50 +/* Total. */ +#define S390_NUM_REGS 51 + +/* Pseudo registers -- PC and condition code. */ +#define S390_PC_REGNUM S390_NUM_REGS +#define S390_CC_REGNUM (S390_NUM_REGS+1) +#define S390_NUM_PSEUDO_REGS 2 +#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2) + +/* Special register usage. */ +#define S390_SP_REGNUM S390_R15_REGNUM +#define S390_RETADDR_REGNUM S390_R14_REGNUM +#define S390_FRAME_REGNUM S390_R11_REGNUM + +/* Core file register sets, defined in s390-tdep.c. */ +#define s390_sizeof_gregset 0x90 +extern int s390_regmap_gregset[S390_NUM_REGS]; +#define s390x_sizeof_gregset 0xd8 +extern int s390x_regmap_gregset[S390_NUM_REGS]; +#define s390_sizeof_fpregset 0x88 +extern int s390_regmap_fpregset[S390_NUM_REGS]; + +#endif + diff --git a/contrib/gdb/gdb/scm-exp.c b/contrib/gdb/gdb/scm-exp.c index 7464ecfc6bf..41d78afad71 100644 --- a/contrib/gdb/gdb/scm-exp.c +++ b/contrib/gdb/gdb/scm-exp.c @@ -1,5 +1,6 @@ /* Scheme/Guile language support routines for GDB, the GNU debugger. - Copyright 1995, 1996, 2000 Free Software Foundation, Inc. + + Copyright 1995, 1996, 2000, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -237,7 +238,7 @@ scm_read_token (int c, int weird) static int scm_skip_ws (void) { - register int c; + int c; while (1) switch ((c = *lexptr++)) { diff --git a/contrib/gdb/gdb/scm-lang.c b/contrib/gdb/gdb/scm-lang.c index 30ca763c1da..872dcaf89fc 100644 --- a/contrib/gdb/gdb/scm-lang.c +++ b/contrib/gdb/gdb/scm-lang.c @@ -1,6 +1,7 @@ /* Scheme/Guile language support routines for GDB, the GNU debugger. - Copyright 1995, 1996, 1998, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1995, 1996, 1998, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -29,8 +30,10 @@ #include "c-lang.h" #include "scm-lang.h" #include "scm-tags.h" +#include "source.h" #include "gdb_string.h" #include "gdbcore.h" +#include "infcall.h" extern void _initialize_scheme_language (void); static struct value *evaluate_subexp_scm (struct type *, struct expression *, @@ -86,7 +89,7 @@ scm_get_field (LONGEST svalue, int index) or Boolean (CONTEXT == TYPE_CODE_BOOL). */ LONGEST -scm_unpack (struct type *type, char *valaddr, enum type_code context) +scm_unpack (struct type *type, const char *valaddr, enum type_code context) { if (is_scmvalue_type (type)) { @@ -133,9 +136,11 @@ scm_unpack (struct type *type, char *valaddr, enum type_code context) static int in_eval_c (void) { - if (current_source_symtab && current_source_symtab->filename) + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + if (cursal.symtab && cursal.symtab->filename) { - char *filename = current_source_symtab->filename; + char *filename = cursal.symtab->filename; int len = strlen (filename); if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0) return 1; @@ -162,7 +167,7 @@ scm_lookup_name (char *str) if (in_eval_c () && (sym = lookup_symbol ("env", expression_context_block, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL)) != NULL) args[2] = value_of_variable (sym, expression_context_block); else @@ -176,11 +181,11 @@ scm_lookup_name (char *str) sym = lookup_symbol (str, expression_context_block, - VAR_NAMESPACE, (int *) NULL, + VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); if (sym) return value_of_variable (sym, NULL); - error ("No symbol \"%s\" in current context."); + error ("No symbol \"%s\" in current context.", str); } struct value * @@ -197,8 +202,8 @@ scm_evaluate_string (char *str, int len) } static struct value * -evaluate_subexp_scm (struct type *expect_type, register struct expression *exp, - register int *pos, enum noside noside) +evaluate_subexp_scm (struct type *expect_type, struct expression *exp, + int *pos, enum noside noside) { enum exp_opcode op = exp->elts[*pos].opcode; int len, pc; @@ -228,6 +233,15 @@ nosideret: return value_from_longest (builtin_type_long, (LONGEST) 1); } +const struct exp_descriptor exp_descriptor_scm = +{ + print_subexp_standard, + operator_length_standard, + op_name_standard, + dump_subexp_body_standard, + evaluate_subexp_scm +}; + const struct language_defn scm_language_defn = { "scheme", /* Language name */ @@ -236,9 +250,9 @@ const struct language_defn scm_language_defn = range_check_off, type_check_off, case_sensitive_off, + &exp_descriptor_scm, scm_parse, c_error, - evaluate_subexp_scm, scm_printchar, /* Print a character constant */ scm_printstr, /* Function to print string constant */ NULL, /* Function to print a single character */ @@ -246,6 +260,11 @@ const struct language_defn scm_language_defn = c_print_type, /* Print a type using appropriate syntax */ scm_val_print, /* Print a value using appropriate syntax */ scm_value_print, /* Print a top-level value */ + NULL, /* Language specific skip_trampoline */ + value_of_this, /* value_of_this */ + basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ + basic_lookup_transparent_type,/* lookup_transparent_type */ + NULL, /* Language specific symbol demangler */ {"", "", "", ""}, /* Binary format info */ {"#o%lo", "#o", "o", ""}, /* Octal format info */ {"%ld", "", "d", ""}, /* Decimal format info */ @@ -254,6 +273,7 @@ const struct language_defn scm_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ &builtin_type_char, /* Type of string elements */ + default_word_break_characters, LANG_MAGIC }; diff --git a/contrib/gdb/gdb/scm-lang.h b/contrib/gdb/gdb/scm-lang.h index 713b0309028..6e24be56c90 100644 --- a/contrib/gdb/gdb/scm-lang.h +++ b/contrib/gdb/gdb/scm-lang.h @@ -1,5 +1,7 @@ /* Scheme/Guile language support routines for GDB, the GNU debugger. - Copyright 1995, 1996, 1998, 1999, 2000 Free Software Foundation, Inc. + + Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software + Foundation, Inc. This file is part of GDB. @@ -67,4 +69,4 @@ extern struct type *builtin_type_scm; extern int scm_parse (void); -extern LONGEST scm_unpack (struct type *, char *, enum type_code); +extern LONGEST scm_unpack (struct type *, const char *, enum type_code); diff --git a/contrib/gdb/gdb/sentinel-frame.c b/contrib/gdb/gdb/sentinel-frame.c new file mode 100644 index 00000000000..94c1ee31311 --- /dev/null +++ b/contrib/gdb/gdb/sentinel-frame.c @@ -0,0 +1,92 @@ +/* Code dealing with register stack frames, for GDB, the GNU debugger. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software + Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#include "defs.h" +#include "regcache.h" +#include "sentinel-frame.h" +#include "inferior.h" +#include "frame-unwind.h" + +struct frame_unwind_cache +{ + struct regcache *regcache; +}; + +void * +sentinel_frame_cache (struct regcache *regcache) +{ + struct frame_unwind_cache *cache = + FRAME_OBSTACK_ZALLOC (struct frame_unwind_cache); + cache->regcache = regcache; + return cache; +} + +/* Here the register value is taken direct from the register cache. */ + +static void +sentinel_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimized, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnum, void *bufferp) +{ + struct frame_unwind_cache *cache = *this_prologue_cache; + /* Describe the register's location. A reg-frame maps all registers + onto the corresponding hardware register. */ + *optimized = 0; + *lvalp = lval_register; + *addrp = register_offset_hack (current_gdbarch, regnum); + *realnum = regnum; + + /* If needed, find and return the value of the register. */ + if (bufferp != NULL) + { + /* Return the actual value. */ + /* Use the regcache_cooked_read() method so that it, on the fly, + constructs either a raw or pseudo register from the raw + register cache. */ + regcache_cooked_read (cache->regcache, regnum, bufferp); + } +} + +static void +sentinel_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + /* The sentinel frame is used as a starting point for creating the + previous (inner most) frame. That frame's THIS_ID method will be + called to determine the inner most frame's ID. Not this one. */ + internal_error (__FILE__, __LINE__, "sentinel_frame_this_id called"); +} + +const struct frame_unwind sentinel_frame_unwinder = +{ + /* Should the sentinel frame be given a special type? */ + NORMAL_FRAME, + sentinel_frame_this_id, + sentinel_frame_prev_register +}; + +const struct frame_unwind *const sentinel_frame_unwind = &sentinel_frame_unwinder; diff --git a/contrib/gdb/gdb/sentinel-frame.h b/contrib/gdb/gdb/sentinel-frame.h new file mode 100644 index 00000000000..9b69f42154b --- /dev/null +++ b/contrib/gdb/gdb/sentinel-frame.h @@ -0,0 +1,41 @@ +/* Code dealing with register stack frames, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined (SENTINEL_FRAME_H) +#define SENTINEL_FRAME_H 1 + +struct frame_unwind; +struct regcache; + +/* Implement the sentinel frame. The sentinel frame terminates the + inner most end of the frame chain. If unwound, it returns the + information need to construct an inner-most frame. */ + +/* Pump prime the sentinel frame's cache. Since this needs the + REGCACHE provide that here. */ + +extern void *sentinel_frame_cache (struct regcache *regcache); + +/* At present there is only one type of sentinel frame. */ + +extern const struct frame_unwind *const sentinel_frame_unwind; + +#endif /* !defined (SENTINEL_FRAME_H) */ diff --git a/contrib/gdb/gdb/ser-e7kpc.c b/contrib/gdb/gdb/ser-e7kpc.c new file mode 100644 index 00000000000..1efe1420575 --- /dev/null +++ b/contrib/gdb/gdb/ser-e7kpc.c @@ -0,0 +1,436 @@ +/* Remote serial interface using Renesas E7000 PC ISA card in a PC + Copyright 1994, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#if defined __GO32__ || defined _WIN32 +#include "serial.h" +#include "gdb_string.h" + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#ifdef __GO32__ +#include +#endif + +static int e7000pc_open (struct serial *scb, const char *name); +static void e7000pc_raw (struct serial *scb); +static int e7000pc_readchar (struct serial *scb, int timeout); +static int e7000pc_setbaudrate (struct serial *scb, int rate); +static int e7000pc_write (struct serial *scb, const char *str, int len); +static void e7000pc_close (struct serial *scb); +static serial_ttystate e7000pc_get_tty_state (struct serial *scb); +static int e7000pc_set_tty_state (struct serial *scb, serial_ttystate state); + +#define OFF_DPD 0x0000 +#define OFF_DDP 0x1000 +#define OFF_CPD 0x2000 +#define OFF_CDP 0x2400 +#define OFF_FA 0x3000 +#define OFF_FB 0x3002 +#define OFF_FC 0x3004 +#define OFF_IRQTOD 0x3008 +#define OFF_IRQTOP 0x300a +#define OFF_READY 0x300c +#define OFF_PON 0x300e + +#define IDLE 0x0000 +#define CMD_CI 0x4349 +#define CMD_CO 0x434f +#define CMD_LO 0x4c4f +#define CMD_LS 0x4c53 +#define CMD_SV 0x5356 +#define CMD_SS 0x5353 +#define CMD_OK 0x4f4b +#define CMD_ER 0x4552 +#define CMD_NF 0x4e46 +#define CMD_AB 0x4142 +#define CMD_ED 0x4544 +#define CMD_CE 0x4345 + +static unsigned long fa; +static unsigned long irqtod; +static unsigned long ready; +static unsigned long fb; +static unsigned long cpd; +static unsigned long cdp; +static unsigned long ready; +static unsigned long pon; +static unsigned long irqtop; +static unsigned long board_at; + +#ifdef __GO32__ + +#define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);} +#define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);} +#define GET_BYTE(x) ( dosmemget(x,1,&bb), bb) +#define GET_WORD(x) ( dosmemget(x,2,&sb), sb) +static unsigned char bb; +static unsigned short sb; + +#else /* win32 */ + +#define SET_BYTE(x,y) *(volatile unsigned char *)(x) = (y) +#define SET_WORD(x,y) *(volatile unsigned short *)(x) = (y) +#define GET_BYTE(x) (*(volatile unsigned char *)(x)) +#define GET_WORD(x) (*(volatile unsigned short *)(x)) +#define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN)) +#define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN)) +#endif + +static struct sw + { + int sw; + int addr; + } +sigs[] = +{ + { + 0x14, 0xd0000 + } + , + { + 0x15, 0xd4000 + } + , + { + 0x16, 0xd8000 + } + , + { + 0x17, 0xdc000 + } + , + 0 +}; + +#define get_ds_base() 0 + +static int +e7000pc_init (void) +{ + int try; + unsigned long dsbase; + + dsbase = get_ds_base (); + + /* Look around in memory for the board's signature */ + + for (try = 0; sigs[try].sw; try++) + { + int val; + board_at = sigs[try].addr - dsbase; + fa = board_at + OFF_FA; + fb = board_at + OFF_FB; + cpd = board_at + OFF_CPD; + cdp = board_at + OFF_CDP; + ready = board_at + OFF_READY; + pon = board_at + OFF_PON; + irqtop = board_at + OFF_IRQTOP; + irqtod = board_at + OFF_IRQTOD; + + val = GET_WORD (ready); + + if (val == (0xaaa0 | sigs[try].sw)) + { + if (GET_WORD (pon) & 0xf) + { + SET_WORD (fa, 0); + SET_WORD (fb, 0); + + SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */ + SET_WORD (ready, 1); + printf_filtered ("\nConnected to the E7000PC at address 0x%x\n", + sigs[try].addr); + return 1; + } + error ("The E7000 PC board is working, but the E7000 is turned off.\n"); + return 0; + } + } + + error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\ +and that the switch settings are correct. Some other DOS programs can \n\ +stop the board from working. Try starting from a very minimal boot, \n\ +perhaps you need to disable EMM386 over the region where the board has\n\ +its I/O space, remove other unneeded cards, etc etc\n"); + return 0; + +} + +static int pbuf_size; +static int pbuf_index; + +/* Return next byte from cdp. If no more, then return -1. */ + +static int +e7000_get (void) +{ + static char pbuf[1000]; + char tmp[1000]; + int x; + + if (pbuf_index < pbuf_size) + { + x = pbuf[pbuf_index++]; + } + else if ((GET_WORD (fb) & 1)) + { + int i; + pbuf_size = GET_WORD (cdp + 2); + + dosmemget (cdp + 8, pbuf_size + 1, tmp); + + /* Tell the E7000 we've eaten */ + SET_WORD (fb, 0); + /* Swap it around */ + for (i = 0; i < pbuf_size; i++) + { + pbuf[i] = tmp[i ^ 1]; + } + pbuf_index = 0; + x = pbuf[pbuf_index++]; + } + else + { + x = -1; + } + return x; +} + +/* Works just like read(), except that it takes a TIMEOUT in seconds. Note + that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */ + +static int +dosasync_read (int fd, char *buf, int len, int timeout) +{ + long now; + long then; + int i = 0; + + /* Then look for some more if we're still hungry */ + time (&now); + then = now + timeout; + while (i < len) + { + int ch = e7000_get (); + + /* While there's room in the buffer, and we've already + read the stuff in, suck it over */ + if (ch != -1) + { + buf[i++] = ch; + while (i < len && pbuf_index < pbuf_size) + { + ch = e7000_get (); + if (ch == -1) + break; + buf[i++] = ch; + } + } + + time (&now); + + if (timeout == 0) + return i; + if (now >= then && timeout > 0) + { + return i; + } + } + return len; +} + + +static int +dosasync_write (int fd, const char *buf, int len) +{ + int i; + char dummy[1000]; + + /* Construct copy locally */ + ((short *) dummy)[0] = CMD_CI; + ((short *) dummy)[1] = len; + ((short *) dummy)[2] = 0; + ((short *) dummy)[3] = 0; + for (i = 0; i < len; i++) + { + dummy[(8 + i) ^ 1] = buf[i]; + } + + /* Wait for the card to get ready */ + while (GET_WORD (fa) & 1); + + /* Blast onto the ISA card */ + dosmemput (dummy, 8 + len + 1, cpd); + + SET_WORD (fa, 1); + SET_WORD (irqtod, 1); /* Interrupt the E7000 */ + + return len; +} + +static int +e7000pc_open (struct serial *scb, const char *name) +{ + if (strncasecmp (name, "pc", 2) != 0) + { + errno = ENOENT; + return -1; + } + + scb->fd = e7000pc_init (); + + if (!scb->fd) + return -1; + + return 0; +} + +static int +e7000pc_noop (struct serial *scb) +{ + return 0; +} + +static void +e7000pc_raw (struct serial *scb) +{ + /* Always in raw mode */ +} + +static int +e7000pc_readchar (struct serial *scb, int timeout) +{ + char buf; + +top: + + if (dosasync_read (scb->fd, &buf, 1, timeout)) + { + if (buf == 0) + goto top; + return buf; + } + else + return SERIAL_TIMEOUT; +} + +struct e7000pc_ttystate +{ + int dummy; +}; + +/* e7000pc_{get set}_tty_state() are both dummys to fill out the function + vector. Someday, they may do something real... */ + +static serial_ttystate +e7000pc_get_tty_state (struct serial *scb) +{ + struct e7000pc_ttystate *state; + + state = (struct e7000pc_ttystate *) xmalloc (sizeof *state); + + return (serial_ttystate) state; +} + +static int +e7000pc_set_tty_state (struct serial *scb, serial_ttystate ttystate) +{ + return 0; +} + +static int +e7000pc_noflush_set_tty_state (struct serial *scb, + serial_ttystate new_ttystate, + serial_ttystate old_ttystate) +{ + return 0; +} + +static void +e7000pc_print_tty_state (struct serial *scb, + serial_ttystate ttystate, + struct ui_file *stream) +{ + /* Nothing to print. */ + return; +} + +static int +e7000pc_setbaudrate (struct serial *scb, int rate) +{ + return 0; +} + +static int +e7000pc_setstopbits (struct serial *scb, int rate) +{ + return 0; +} + +static int +e7000pc_write (struct serial *scb, const char *str, int len) +{ + dosasync_write (scb->fd, str, len); + + return 0; +} + +static void +e7000pc_close (struct serial *scb) +{ +} + +static struct serial_ops e7000pc_ops = +{ + "pc", + 0, + e7000pc_open, + e7000pc_close, + e7000pc_readchar, + e7000pc_write, + e7000pc_noop, /* flush output */ + e7000pc_noop, /* flush input */ + e7000pc_noop, /* send break -- currently used only for nindy */ + e7000pc_raw, + e7000pc_get_tty_state, + e7000pc_set_tty_state, + e7000pc_print_tty_state, + e7000pc_noflush_set_tty_state, + e7000pc_setbaudrate, + e7000pc_setstopbits, + e7000pc_noop, /* wait for output to drain */ +}; + +#endif /*_WIN32 or __GO32__*/ + +extern initialize_file_ftype _initialize_ser_e7000pc; /* -Wmissing-prototypes */ + +void +_initialize_ser_e7000pc (void) +{ +#if defined __GO32__ || defined _WIN32 + serial_add_interface (&e7000pc_ops); +#endif +} diff --git a/contrib/gdb/gdb/ser-go32.c b/contrib/gdb/gdb/ser-go32.c new file mode 100644 index 00000000000..cea01cdf221 --- /dev/null +++ b/contrib/gdb/gdb/ser-go32.c @@ -0,0 +1,964 @@ +/* Remote serial interface for local (hardwired) serial ports for GO32. + Copyright 1992, 1993, 2000, 2001 Free Software Foundation, Inc. + + Contributed by Nigel Stephens, Algorithmics Ltd. (nigel@algor.co.uk). + + This version uses DPMI interrupts to handle buffered i/o + without the separate "asynctsr" program. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcmd.h" +#include "serial.h" +#include "gdb_string.h" + + +/* + * NS16550 UART registers + */ + +#define COM1ADDR 0x3f8 +#define COM2ADDR 0x2f8 +#define COM3ADDR 0x3e8 +#define COM4ADDR 0x3e0 + +#define com_data 0 /* data register (R/W) */ +#define com_dlbl 0 /* divisor latch low (W) */ +#define com_ier 1 /* interrupt enable (W) */ +#define com_dlbh 1 /* divisor latch high (W) */ +#define com_iir 2 /* interrupt identification (R) */ +#define com_fifo 2 /* FIFO control (W) */ +#define com_lctl 3 /* line control register (R/W) */ +#define com_cfcr 3 /* line control register (R/W) */ +#define com_mcr 4 /* modem control register (R/W) */ +#define com_lsr 5 /* line status register (R/W) */ +#define com_msr 6 /* modem status register (R/W) */ + +/* + * Constants for computing 16 bit baud rate divisor (lower byte + * in com_dlbl, upper in com_dlbh) from 1.8432MHz crystal. Divisor is + * 1.8432 MHz / (16 * X) for X bps. If the baud rate can't be set + * to within +- (desired_rate*SPEED_TOLERANCE/1000) bps, we fail. + */ +#define COMTICK (1843200/16) +#define SPEED_TOLERANCE 30 /* thousandths; real == desired +- 3.0% */ + +/* interrupt enable register */ +#define IER_ERXRDY 0x1 /* int on rx ready */ +#define IER_ETXRDY 0x2 /* int on tx ready */ +#define IER_ERLS 0x4 /* int on line status change */ +#define IER_EMSC 0x8 /* int on modem status change */ + +/* interrupt identification register */ +#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ +#define IIR_IMASK 0xf /* interrupt cause mask */ +#define IIR_NOPEND 0x1 /* nothing pending */ +#define IIR_RLS 0x6 /* receive line status */ +#define IIR_RXRDY 0x4 /* receive ready */ +#define IIR_RXTOUT 0xc /* receive timeout */ +#define IIR_TXRDY 0x2 /* transmit ready */ +#define IIR_MLSC 0x0 /* modem status */ + + +/* fifo control register */ +#define FIFO_ENABLE 0x01 /* enable fifo */ +#define FIFO_RCV_RST 0x02 /* reset receive fifo */ +#define FIFO_XMT_RST 0x04 /* reset transmit fifo */ +#define FIFO_DMA_MODE 0x08 /* enable dma mode */ +#define FIFO_TRIGGER_1 0x00 /* trigger at 1 char */ +#define FIFO_TRIGGER_4 0x40 /* trigger at 4 chars */ +#define FIFO_TRIGGER_8 0x80 /* trigger at 8 chars */ +#define FIFO_TRIGGER_14 0xc0 /* trigger at 14 chars */ + +/* character format control register */ +#define CFCR_DLAB 0x80 /* divisor latch */ +#define CFCR_SBREAK 0x40 /* send break */ +#define CFCR_PZERO 0x30 /* zero parity */ +#define CFCR_PONE 0x20 /* one parity */ +#define CFCR_PEVEN 0x10 /* even parity */ +#define CFCR_PODD 0x00 /* odd parity */ +#define CFCR_PENAB 0x08 /* parity enable */ +#define CFCR_STOPB 0x04 /* 2 stop bits */ +#define CFCR_8BITS 0x03 /* 8 data bits */ +#define CFCR_7BITS 0x02 /* 7 data bits */ +#define CFCR_6BITS 0x01 /* 6 data bits */ +#define CFCR_5BITS 0x00 /* 5 data bits */ + +/* modem control register */ +#define MCR_LOOPBACK 0x10 /* loopback */ +#define MCR_IENABLE 0x08 /* output 2 = int enable */ +#define MCR_DRS 0x04 /* output 1 = xxx */ +#define MCR_RTS 0x02 /* enable RTS */ +#define MCR_DTR 0x01 /* enable DTR */ + +/* line status register */ +#define LSR_RCV_FIFO 0x80 /* error in receive fifo */ +#define LSR_TSRE 0x40 /* transmitter empty */ +#define LSR_TXRDY 0x20 /* transmitter ready */ +#define LSR_BI 0x10 /* break detected */ +#define LSR_FE 0x08 /* framing error */ +#define LSR_PE 0x04 /* parity error */ +#define LSR_OE 0x02 /* overrun error */ +#define LSR_RXRDY 0x01 /* receiver ready */ +#define LSR_RCV_MASK 0x1f + +/* modem status register */ +#define MSR_DCD 0x80 +#define MSR_RI 0x40 +#define MSR_DSR 0x20 +#define MSR_CTS 0x10 +#define MSR_DDCD 0x08 +#define MSR_TERI 0x04 +#define MSR_DDSR 0x02 +#define MSR_DCTS 0x01 + +#include +#include +#include +#include +typedef unsigned long u_long; + +/* 16550 rx fifo trigger point */ +#define FIFO_TRIGGER FIFO_TRIGGER_4 + +/* input buffer size */ +#define CBSIZE 4096 + +#define RAWHZ 18 + +#ifdef DOS_STATS +#define CNT_RX 16 +#define CNT_TX 17 +#define CNT_STRAY 18 +#define CNT_ORUN 19 +#define NCNT 20 + +static int intrcnt; +static int cnts[NCNT]; +static char *cntnames[NCNT] = +{ + /* h/w interrupt counts. */ + "mlsc", "nopend", "txrdy", "?3", + "rxrdy", "?5", "rls", "?7", + "?8", "?9", "?a", "?b", + "rxtout", "?d", "?e", "?f", + /* s/w counts. */ + "rxcnt", "txcnt", "stray", "swoflo" +}; + +#define COUNT(x) cnts[x]++ +#else +#define COUNT(x) +#endif + +/* Main interrupt controller port addresses. */ +#define ICU_BASE 0x20 +#define ICU_OCW2 (ICU_BASE + 0) +#define ICU_MASK (ICU_BASE + 1) + +/* Original interrupt controller mask register. */ +unsigned char icu_oldmask; + +/* Maximum of 8 interrupts (we don't handle the slave icu yet). */ +#define NINTR 8 + +static struct intrupt + { + char inuse; + struct dos_ttystate *port; + _go32_dpmi_seginfo old_rmhandler; + _go32_dpmi_seginfo old_pmhandler; + _go32_dpmi_seginfo new_rmhandler; + _go32_dpmi_seginfo new_pmhandler; + _go32_dpmi_registers regs; + } +intrupts[NINTR]; + + +static struct dos_ttystate + { + int base; + int irq; + int refcnt; + struct intrupt *intrupt; + int fifo; + int baudrate; + unsigned char cbuf[CBSIZE]; + unsigned int first; + unsigned int count; + int txbusy; + unsigned char old_mcr; + int ferr; + int perr; + int oflo; + int msr; + } +ports[4] = +{ + { + COM1ADDR, 4, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 + } + , + { + COM2ADDR, 3, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 + } + , + { + COM3ADDR, 4, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 + } + , + { + COM4ADDR, 3, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +static int dos_open (struct serial *scb, const char *name); +static void dos_raw (struct serial *scb); +static int dos_readchar (struct serial *scb, int timeout); +static int dos_setbaudrate (struct serial *scb, int rate); +static int dos_write (struct serial *scb, const char *str, int len); +static void dos_close (struct serial *scb); +static serial_ttystate dos_get_tty_state (struct serial *scb); +static int dos_set_tty_state (struct serial *scb, serial_ttystate state); +static int dos_baudconv (int rate); + +#define inb(p,a) inportb((p)->base + (a)) +#define outb(p,a,v) outportb((p)->base + (a), (v)) +#define disable() asm volatile ("cli"); +#define enable() asm volatile ("sti"); + + +static int +dos_getc (volatile struct dos_ttystate *port) +{ + int c; + + if (port->count == 0) + return -1; + + c = port->cbuf[port->first]; + disable (); + port->first = (port->first + 1) & (CBSIZE - 1); + port->count--; + enable (); + return c; +} + + +static int +dos_putc (int c, struct dos_ttystate *port) +{ + if (port->count >= CBSIZE - 1) + return -1; + port->cbuf[(port->first + port->count) & (CBSIZE - 1)] = c; + port->count++; + return 0; +} + + + +static void +dos_comisr (int irq) +{ + struct dos_ttystate *port; + unsigned char iir, lsr, c; + + disable (); /* Paranoia */ + outportb (ICU_OCW2, 0x20); /* End-Of-Interrupt */ +#ifdef DOS_STATS + ++intrcnt; +#endif + + port = intrupts[irq].port; + if (!port) + { + COUNT (CNT_STRAY); + return; /* not open */ + } + + while (1) + { + iir = inb (port, com_iir) & IIR_IMASK; + switch (iir) + { + + case IIR_RLS: + lsr = inb (port, com_lsr); + goto rx; + + case IIR_RXTOUT: + case IIR_RXRDY: + lsr = 0; + + rx: + do + { + c = inb (port, com_data); + if (lsr & (LSR_BI | LSR_FE | LSR_PE | LSR_OE)) + { + if (lsr & (LSR_BI | LSR_FE)) + port->ferr++; + else if (lsr & LSR_PE) + port->perr++; + if (lsr & LSR_OE) + port->oflo++; + } + + if (dos_putc (c, port) < 0) + { + COUNT (CNT_ORUN); + } + else + { + COUNT (CNT_RX); + } + } + while ((lsr = inb (port, com_lsr)) & LSR_RXRDY); + break; + + case IIR_MLSC: + /* could be used to flowcontrol Tx */ + port->msr = inb (port, com_msr); + break; + + case IIR_TXRDY: + port->txbusy = 0; + break; + + case IIR_NOPEND: + /* no more pending interrupts, all done */ + return; + + default: + /* unexpected interrupt, ignore */ + break; + } + COUNT (iir); + } +} + +#define ISRNAME(x) dos_comisr##x +#define ISR(x) static void ISRNAME(x)(void) {dos_comisr(x);} + +ISR (0) ISR (1) ISR (2) ISR (3) /* OK */ +ISR (4) ISR (5) ISR (6) ISR (7) /* OK */ + +typedef void (*isr_t) (void); + +static isr_t isrs[NINTR] = + { + ISRNAME (0), ISRNAME (1), ISRNAME (2), ISRNAME (3), + ISRNAME (4), ISRNAME (5), ISRNAME (6), ISRNAME (7) + }; + + + +static struct intrupt * +dos_hookirq (unsigned int irq) +{ + struct intrupt *intr; + unsigned int vec; + isr_t isr; + + if (irq >= NINTR) + return 0; + + intr = &intrupts[irq]; + if (intr->inuse) + return 0; + + vec = 0x08 + irq; + isr = isrs[irq]; + + /* setup real mode handler */ + _go32_dpmi_get_real_mode_interrupt_vector (vec, &intr->old_rmhandler); + + intr->new_rmhandler.pm_selector = _go32_my_cs (); + intr->new_rmhandler.pm_offset = (u_long) isr; + if (_go32_dpmi_allocate_real_mode_callback_iret (&intr->new_rmhandler, + &intr->regs)) + { + return 0; + } + + if (_go32_dpmi_set_real_mode_interrupt_vector (vec, &intr->new_rmhandler)) + { + return 0; + } + + /* setup protected mode handler */ + _go32_dpmi_get_protected_mode_interrupt_vector (vec, &intr->old_pmhandler); + + intr->new_pmhandler.pm_selector = _go32_my_cs (); + intr->new_pmhandler.pm_offset = (u_long) isr; + _go32_dpmi_allocate_iret_wrapper (&intr->new_pmhandler); + + if (_go32_dpmi_set_protected_mode_interrupt_vector (vec, + &intr->new_pmhandler)) + { + return 0; + } + + /* setup interrupt controller mask */ + disable (); + outportb (ICU_MASK, inportb (ICU_MASK) & ~(1 << irq)); + enable (); + + intr->inuse = 1; + return intr; +} + + +static void +dos_unhookirq (struct intrupt *intr) +{ + unsigned int irq, vec; + unsigned char mask; + + irq = intr - intrupts; + vec = 0x08 + irq; + + /* restore old interrupt mask bit */ + mask = 1 << irq; + disable (); + outportb (ICU_MASK, inportb (ICU_MASK) | (mask & icu_oldmask)); + enable (); + + /* remove real mode handler */ + _go32_dpmi_set_real_mode_interrupt_vector (vec, &intr->old_rmhandler); + _go32_dpmi_free_real_mode_callback (&intr->new_rmhandler); + + /* remove protected mode handler */ + _go32_dpmi_set_protected_mode_interrupt_vector (vec, &intr->old_pmhandler); + _go32_dpmi_free_iret_wrapper (&intr->new_pmhandler); + intr->inuse = 0; +} + + + +static int +dos_open (struct serial *scb, const char *name) +{ + struct dos_ttystate *port; + int fd, i; + + if (strncasecmp (name, "/dev/", 5) == 0) + name += 5; + else if (strncasecmp (name, "\\dev\\", 5) == 0) + name += 5; + + if (strlen (name) != 4 || strncasecmp (name, "com", 3) != 0) + { + errno = ENOENT; + return -1; + } + + if (name[3] < '1' || name[3] > '4') + { + errno = ENOENT; + return -1; + } + + /* FIXME: this is a Bad Idea (tm)! One should *never* invent file + handles, since they might be already used by other files/devices. + The Right Way to do this is to create a real handle by dup()'ing + some existing one. */ + fd = name[3] - '1'; + port = &ports[fd]; + if (port->refcnt++ > 0) + { + /* Device already opened another user. Just point at it. */ + scb->fd = fd; + return 0; + } + + /* force access to ID reg */ + outb (port, com_cfcr, 0); + outb (port, com_iir, 0); + for (i = 0; i < 17; i++) + { + if ((inb (port, com_iir) & 0x38) == 0) + goto ok; + (void) inb (port, com_data); /* clear recv */ + } + errno = ENODEV; + return -1; + +ok: + /* disable all interrupts in chip */ + outb (port, com_ier, 0); + + /* tentatively enable 16550 fifo, and see if it responds */ + outb (port, com_fifo, + FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER); + sleep (1); + port->fifo = ((inb (port, com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK); + + /* clear pending status reports. */ + (void) inb (port, com_lsr); + (void) inb (port, com_msr); + + /* enable external interrupt gate (to avoid floating IRQ) */ + outb (port, com_mcr, MCR_IENABLE); + + /* hook up interrupt handler and initialise icu */ + port->intrupt = dos_hookirq (port->irq); + if (!port->intrupt) + { + outb (port, com_mcr, 0); + outb (port, com_fifo, 0); + errno = ENODEV; + return -1; + } + + disable (); + + /* record port */ + port->intrupt->port = port; + scb->fd = fd; + + /* clear rx buffer, tx busy flag and overflow count */ + port->first = port->count = 0; + port->txbusy = 0; + port->oflo = 0; + + /* set default baud rate and mode: 9600,8,n,1 */ + i = dos_baudconv (port->baudrate = 9600); + outb (port, com_cfcr, CFCR_DLAB); + outb (port, com_dlbl, i & 0xff); + outb (port, com_dlbh, i >> 8); + outb (port, com_cfcr, CFCR_8BITS); + + /* enable all interrupts */ + outb (port, com_ier, IER_ETXRDY | IER_ERXRDY | IER_ERLS | IER_EMSC); + + /* enable DTR & RTS */ + outb (port, com_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE); + + enable (); + + return 0; +} + + +static void +dos_close (struct serial *scb) +{ + struct dos_ttystate *port; + struct intrupt *intrupt; + + if (!scb) + return; + + port = &ports[scb->fd]; + + if (port->refcnt-- > 1) + return; + + if (!(intrupt = port->intrupt)) + return; + + /* disable interrupts, fifo, flow control */ + disable (); + port->intrupt = 0; + intrupt->port = 0; + outb (port, com_fifo, 0); + outb (port, com_ier, 0); + enable (); + + /* unhook handler, and disable interrupt gate */ + dos_unhookirq (intrupt); + outb (port, com_mcr, 0); + + /* Check for overflow errors */ + if (port->oflo) + { + fprintf_unfiltered (gdb_stderr, + "Serial input overruns occurred.\n"); + fprintf_unfiltered (gdb_stderr, "This system %s handle %d baud.\n", + port->fifo ? "cannot" : "needs a 16550 to", + port->baudrate); + } +} + + + +static int +dos_noop (struct serial *scb) +{ + return 0; +} + +static void +dos_raw (struct serial *scb) +{ + /* Always in raw mode */ +} + +static int +dos_readchar (struct serial *scb, int timeout) +{ + struct dos_ttystate *port = &ports[scb->fd]; + long then; + int c; + + then = rawclock () + (timeout * RAWHZ); + while ((c = dos_getc (port)) < 0) + { + if (timeout >= 0 && (rawclock () - then) >= 0) + return SERIAL_TIMEOUT; + } + + return c; +} + + +static serial_ttystate +dos_get_tty_state (struct serial *scb) +{ + struct dos_ttystate *port = &ports[scb->fd]; + struct dos_ttystate *state; + + /* Are they asking about a port we opened? */ + if (port->refcnt <= 0) + { + /* We've never heard about this port. We should fail this call, + unless they are asking about one of the 3 standard handles, + in which case we pretend the handle was open by us if it is + connected to a terminal device. This is beacuse Unix + terminals use the serial interface, so GDB expects the + standard handles to go through here. */ + if (scb->fd >= 3 || !isatty (scb->fd)) + return NULL; + } + + state = (struct dos_ttystate *) xmalloc (sizeof *state); + *state = *port; + return (serial_ttystate) state; +} + +static int +dos_set_tty_state (struct serial *scb, serial_ttystate ttystate) +{ + struct dos_ttystate *state; + + state = (struct dos_ttystate *) ttystate; + dos_setbaudrate (scb, state->baudrate); + return 0; +} + +static int +dos_noflush_set_tty_state (struct serial *scb, serial_ttystate new_ttystate, + serial_ttystate old_ttystate) +{ + struct dos_ttystate *state; + + state = (struct dos_ttystate *) new_ttystate; + dos_setbaudrate (scb, state->baudrate); + return 0; +} + +static int +dos_flush_input (struct serial *scb) +{ + struct dos_ttystate *port = &ports[scb->fd]; + disable (); + port->first = port->count = 0; + if (port->fifo) + outb (port, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_TRIGGER); + enable (); + return 0; +} + +static void +dos_print_tty_state (struct serial *scb, serial_ttystate ttystate, + struct ui_file *stream) +{ + /* Nothing to print */ + return; +} + +static int +dos_baudconv (int rate) +{ + long x, err; + + if (rate <= 0) + return -1; + +#define divrnd(n, q) (((n) * 2 / (q) + 1) / 2) /* divide and round off */ + x = divrnd (COMTICK, rate); + if (x <= 0) + return -1; + + err = divrnd (1000 * COMTICK, x * rate) - 1000; + if (err < 0) + err = -err; + if (err > SPEED_TOLERANCE) + return -1; +#undef divrnd + return x; +} + + +static int +dos_setbaudrate (struct serial *scb, int rate) +{ + struct dos_ttystate *port = &ports[scb->fd]; + + if (port->baudrate != rate) + { + int x; + unsigned char cfcr; + + x = dos_baudconv (rate); + if (x <= 0) + { + fprintf_unfiltered (gdb_stderr, "%d: impossible baudrate\n", rate); + errno = EINVAL; + return -1; + } + + disable (); + cfcr = inb (port, com_cfcr); + + outb (port, com_cfcr, CFCR_DLAB); + outb (port, com_dlbl, x & 0xff); + outb (port, com_dlbh, x >> 8); + outb (port, com_cfcr, cfcr); + port->baudrate = rate; + enable (); + } + + return 0; +} + +static int +dos_setstopbits (struct serial *scb, int num) +{ + struct dos_ttystate *port = &ports[scb->fd]; + unsigned char cfcr; + + disable (); + cfcr = inb (port, com_cfcr); + + switch (num) + { + case SERIAL_1_STOPBITS: + outb (port, com_cfcr, cfcr & ~CFCR_STOPB); + break; + case SERIAL_1_AND_A_HALF_STOPBITS: + case SERIAL_2_STOPBITS: + outb (port, com_cfcr, cfcr | CFCR_STOPB); + break; + default: + enable (); + return 1; + } + enable (); + + return 0; +} + +static int +dos_write (struct serial *scb, const char *str, int len) +{ + volatile struct dos_ttystate *port = &ports[scb->fd]; + int fifosize = port->fifo ? 16 : 1; + long then; + int cnt; + + while (len > 0) + { + /* send the data, fifosize bytes at a time */ + cnt = fifosize > len ? len : fifosize; + port->txbusy = 1; + /* Francisco Pastor says OUTSB messes + up the communications with UARTs with FIFOs. */ +#ifdef UART_FIFO_WORKS + outportsb (port->base + com_data, str, cnt); + str += cnt; + len -= cnt; +#else + for ( ; cnt > 0; cnt--, len--) + outportb (port->base + com_data, *str++); +#endif +#ifdef DOS_STATS + cnts[CNT_TX] += cnt; +#endif + /* wait for transmission to complete (max 1 sec) */ + then = rawclock () + RAWHZ; + while (port->txbusy) + { + if ((rawclock () - then) >= 0) + { + errno = EIO; + return SERIAL_ERROR; + } + } + } + return 0; +} + + +static int +dos_sendbreak (struct serial *scb) +{ + volatile struct dos_ttystate *port = &ports[scb->fd]; + unsigned char cfcr; + long then; + + cfcr = inb (port, com_cfcr); + outb (port, com_cfcr, cfcr | CFCR_SBREAK); + + /* 0.25 sec delay */ + then = rawclock () + RAWHZ / 4; + while ((rawclock () - then) < 0) + continue; + + outb (port, com_cfcr, cfcr); + return 0; +} + + +static struct serial_ops dos_ops = +{ + "hardwire", + 0, + dos_open, + dos_close, + dos_readchar, + dos_write, + dos_noop, /* flush output */ + dos_flush_input, + dos_sendbreak, + dos_raw, + dos_get_tty_state, + dos_set_tty_state, + dos_print_tty_state, + dos_noflush_set_tty_state, + dos_setbaudrate, + dos_setstopbits, + dos_noop, /* wait for output to drain */ + (void (*)(struct serial *, int))NULL /* change into async mode */ +}; + + +static void +dos_info (char *arg, int from_tty) +{ + struct dos_ttystate *port; +#ifdef DOS_STATS + int i; +#endif + + for (port = ports; port < &ports[4]; port++) + { + if (port->baudrate == 0) + continue; + printf_filtered ("Port:\tCOM%ld (%sactive)\n", (long)(port - ports) + 1, + port->intrupt ? "" : "not "); + printf_filtered ("Addr:\t0x%03x (irq %d)\n", port->base, port->irq); + printf_filtered ("16550:\t%s\n", port->fifo ? "yes" : "no"); + printf_filtered ("Speed:\t%d baud\n", port->baudrate); + printf_filtered ("Errs:\tframing %d parity %d overflow %d\n\n", + port->ferr, port->perr, port->oflo); + } + +#ifdef DOS_STATS + printf_filtered ("\nTotal interrupts: %d\n", intrcnt); + for (i = 0; i < NCNT; i++) + if (cnts[i]) + printf_filtered ("%s:\t%d\n", cntnames[i], cnts[i]); +#endif +} + + +void +_initialize_ser_dos (void) +{ + serial_add_interface (&dos_ops); + + /* Save original interrupt mask register. */ + icu_oldmask = inportb (ICU_MASK); + + /* Mark fixed motherboard irqs as inuse. */ + intrupts[0].inuse = /* timer tick */ + intrupts[1].inuse = /* keyboard */ + intrupts[2].inuse = 1; /* slave icu */ + + add_show_from_set ( + add_set_cmd ("com1base", class_obscure, var_zinteger, + (char *) &ports[0].base, + "Set COM1 base i/o port address.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("com1irq", class_obscure, var_zinteger, + (char *) &ports[0].irq, + "Set COM1 interrupt request.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("com2base", class_obscure, var_zinteger, + (char *) &ports[1].base, + "Set COM2 base i/o port address.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("com2irq", class_obscure, var_zinteger, + (char *) &ports[1].irq, + "Set COM2 interrupt request.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("com3base", class_obscure, var_zinteger, + (char *) &ports[2].base, + "Set COM3 base i/o port address.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("com3irq", class_obscure, var_zinteger, + (char *) &ports[2].irq, + "Set COM3 interrupt request.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("com4base", class_obscure, var_zinteger, + (char *) &ports[3].base, + "Set COM4 base i/o port address.", + &setlist), + &showlist); + + add_show_from_set ( + add_set_cmd ("com4irq", class_obscure, var_zinteger, + (char *) &ports[3].irq, + "Set COM4 interrupt request.", + &setlist), + &showlist); + + add_info ("serial", dos_info, + "Print DOS serial port status."); +} diff --git a/contrib/gdb/gdb/ser-pipe.c b/contrib/gdb/gdb/ser-pipe.c index bca0e54e4ba..3e04973f854 100644 --- a/contrib/gdb/gdb/ser-pipe.c +++ b/contrib/gdb/gdb/ser-pipe.c @@ -98,7 +98,7 @@ pipe_open (struct serial *scb, const char *name) for (old = pidlist; old; old = old->next) close (fileno (old->fp)); /* don't allow a flush */ #endif - execl ("/bin/sh", "sh", "-c", name, NULL); + execl ("/bin/sh", "sh", "-c", name, (char *) 0); _exit (127); } @@ -138,7 +138,7 @@ void _initialize_ser_pipe (void) { struct serial_ops *ops = XMALLOC (struct serial_ops); - memset (ops, sizeof (struct serial_ops), 0); + memset (ops, 0, sizeof (struct serial_ops)); ops->name = "pipe"; ops->next = 0; ops->open = pipe_open; diff --git a/contrib/gdb/gdb/ser-tcp.c b/contrib/gdb/gdb/ser-tcp.c index 6dc82846b6f..a9a87143cb3 100644 --- a/contrib/gdb/gdb/ser-tcp.c +++ b/contrib/gdb/gdb/ser-tcp.c @@ -42,8 +42,8 @@ #include #include "gdb_string.h" -static int tcp_open (struct serial *scb, const char *name); -static void tcp_close (struct serial *scb); +static int net_open (struct serial *scb, const char *name); +static void net_close (struct serial *scb); extern int (*ui_loop_hook) (int); void _initialize_ser_tcp (void); @@ -55,17 +55,27 @@ void _initialize_ser_tcp (void); /* Open a tcp socket */ static int -tcp_open (struct serial *scb, const char *name) +net_open (struct serial *scb, const char *name) { char *port_str, hostname[100]; int n, port, tmp; + int use_udp; struct hostent *hostent; struct sockaddr_in sockaddr; + use_udp = 0; + if (strncmp (name, "udp:", 4) == 0) + { + use_udp = 1; + name = name + 4; + } + else if (strncmp (name, "tcp:", 4) == 0) + name = name + 4; + port_str = strchr (name, ':'); if (!port_str) - error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */ + error ("net_open: No colon in host name!"); /* Shouldn't ever happen */ tmp = min (port_str - name, (int) sizeof hostname - 1); strncpy (hostname, name, tmp); /* Don't want colon */ @@ -84,7 +94,11 @@ tcp_open (struct serial *scb, const char *name) return -1; } - scb->fd = socket (PF_INET, SOCK_STREAM, 0); + if (use_udp) + scb->fd = socket (PF_INET, SOCK_DGRAM, 0); + else + scb->fd = socket (PF_INET, SOCK_STREAM, 0); + if (scb->fd < 0) return -1; @@ -102,7 +116,7 @@ tcp_open (struct serial *scb, const char *name) if (n < 0 && errno != EINPROGRESS) { - tcp_close (scb); + net_close (scb); return -1; } @@ -124,7 +138,7 @@ tcp_open (struct serial *scb, const char *name) if (ui_loop_hook (0)) { errno = EINTR; - tcp_close (scb); + net_close (scb); return -1; } } @@ -142,7 +156,7 @@ tcp_open (struct serial *scb, const char *name) { if (polls > TIMEOUT * POLL_INTERVAL) errno = ETIMEDOUT; - tcp_close (scb); + net_close (scb); return -1; } } @@ -156,20 +170,23 @@ tcp_open (struct serial *scb, const char *name) { if (err) errno = err; - tcp_close (scb); + net_close (scb); return -1; } } - + /* turn off nonblocking */ tmp = 0; ioctl (scb->fd, FIONBIO, &tmp); - /* Disable Nagle algorithm. Needed in some cases. */ - tmp = 1; - setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY, - (char *)&tmp, sizeof (tmp)); - + if (use_udp == 0) + { + /* Disable Nagle algorithm. Needed in some cases. */ + tmp = 1; + setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY, + (char *)&tmp, sizeof (tmp)); + } + /* If we don't do this, then GDB simply exits when the remote side dies. */ signal (SIGPIPE, SIG_IGN); @@ -178,7 +195,7 @@ tcp_open (struct serial *scb, const char *name) } static void -tcp_close (struct serial *scb) +net_close (struct serial *scb) { if (scb->fd < 0) return; @@ -191,11 +208,11 @@ void _initialize_ser_tcp (void) { struct serial_ops *ops = XMALLOC (struct serial_ops); - memset (ops, sizeof (struct serial_ops), 0); + memset (ops, 0, sizeof (struct serial_ops)); ops->name = "tcp"; ops->next = 0; - ops->open = tcp_open; - ops->close = tcp_close; + ops->open = net_open; + ops->close = net_close; ops->readchar = ser_unix_readchar; ops->write = ser_unix_write; ops->flush_output = ser_unix_nop_flush_output; diff --git a/contrib/gdb/gdb/ser-unix.c b/contrib/gdb/gdb/ser-unix.c index f7ab28ae750..38b6716d2ee 100644 --- a/contrib/gdb/gdb/ser-unix.c +++ b/contrib/gdb/gdb/ser-unix.c @@ -1,6 +1,7 @@ /* Serial interface for local (hardwired) serial ports on Un*x like systems - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -1324,7 +1325,7 @@ ser_unix_async (struct serial *scb, case FD_SCHEDULED: delete_file_handler (scb->fd); break; - NOTHING_SCHEDULED: + case NOTHING_SCHEDULED: break; default: /* TIMER SCHEDULED */ delete_timer (scb->async_state); @@ -1337,7 +1338,7 @@ void _initialize_ser_hardwire (void) { struct serial_ops *ops = XMALLOC (struct serial_ops); - memset (ops, sizeof (struct serial_ops), 0); + memset (ops, 0, sizeof (struct serial_ops)); ops->name = "hardwire"; ops->next = 0; ops->open = hardwire_open; diff --git a/contrib/gdb/gdb/ser-unix.h b/contrib/gdb/gdb/ser-unix.h index 861694fb806..3bdf0bcb0ee 100644 --- a/contrib/gdb/gdb/ser-unix.h +++ b/contrib/gdb/gdb/ser-unix.h @@ -1,5 +1,6 @@ /* Serial interface for UN*X file-descriptor based connection. - Copyright 1999, 2000 Free Software Foundation, Inc. + + Copyright 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -21,8 +22,8 @@ #ifndef SER_UNIX_H #define SER_UNIX_H -#undef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) +struct serial; +struct ui_file; /* Generic UNIX/FD functions */ diff --git a/contrib/gdb/gdb/serial.c b/contrib/gdb/gdb/serial.c index 22964eb3f98..ada5631dce9 100644 --- a/contrib/gdb/gdb/serial.c +++ b/contrib/gdb/gdb/serial.c @@ -1,7 +1,7 @@ /* Generic serial interface routines - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -58,9 +58,6 @@ static const char logbase_ascii[] = "ascii"; static const char *logbase_enums[] = {logbase_hex, logbase_octal, logbase_ascii, NULL}; static const char *serial_logbase = logbase_ascii; - -#undef XMALLOC -#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) static int serial_current_type = 0; diff --git a/contrib/gdb/gdb/serial.h b/contrib/gdb/gdb/serial.h index 97d68f32a04..7495b709d57 100644 --- a/contrib/gdb/gdb/serial.h +++ b/contrib/gdb/gdb/serial.h @@ -22,6 +22,8 @@ #ifndef SERIAL_H #define SERIAL_H +struct ui_file; + /* For most routines, if a failure is indicated, then errno should be examined. */ diff --git a/contrib/gdb/gdb/signals/signals.c b/contrib/gdb/gdb/signals/signals.c index 774d70ab84e..c808d1fdeae 100644 --- a/contrib/gdb/gdb/signals/signals.c +++ b/contrib/gdb/gdb/signals/signals.c @@ -25,10 +25,25 @@ #else #include "defs.h" #include "target.h" +#include "gdb_string.h" #endif #include +/* Always use __SIGRTMIN if it's available. SIGRTMIN is the lowest + _available_ realtime signal, not the lowest supported; glibc takes + several for its own use. */ + +#ifndef REALTIME_LO +# if defined(__SIGRTMIN) +# define REALTIME_LO __SIGRTMIN +# define REALTIME_HI __SIGRTMAX +# elif defined(SIGRTMIN) +# define REALTIME_LO SIGRTMIN +# define REALTIME_HI SIGRTMAX +# endif +#endif + /* This table must match in order and size the signals in enum target_signal in target.h. */ /* *INDENT-OFF* */ @@ -180,7 +195,11 @@ static struct { {"SIG126", "Real-time event 126"}, {"SIG127", "Real-time event 127"}, -#if defined(MACH) || defined(__MACH__) + {"SIGINFO", "Information request"}, + + {NULL, "Unknown signal"}, + {NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"}, + /* Mach exceptions */ {"EXC_BAD_ACCESS", "Could not access memory"}, {"EXC_BAD_INSTRUCTION", "Illegal instruction/operand"}, @@ -188,11 +207,6 @@ static struct { {"EXC_EMULATION", "Emulation instruction"}, {"EXC_SOFTWARE", "Software generated exception"}, {"EXC_BREAKPOINT", "Breakpoint"}, -#endif - {"SIGINFO", "Information request"}, - - {NULL, "Unknown signal"}, - {NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"}, /* Last entry, used to check whether the table is the right size. */ {NULL, "TARGET_SIGNAL_MAGIC"} @@ -237,9 +251,10 @@ target_signal_from_name (char *name) /* This ugly cast brought to you by the native VAX compiler. */ for (sig = TARGET_SIGNAL_HUP; - signals[sig].name != NULL; + sig < TARGET_SIGNAL_LAST; sig = (enum target_signal) ((int) sig + 1)) - if (strcmp (name, signals[sig].name) == 0) + if (signals[sig].name != NULL + && strcmp (name, signals[sig].name) == 0) return sig; return TARGET_SIGNAL_UNKNOWN; } @@ -491,19 +506,6 @@ target_signal_from_host (int hostsig) } #endif -#if defined (SIGRTMIN) - if (hostsig >= SIGRTMIN && hostsig <= SIGRTMAX) - { - /* This block of TARGET_SIGNAL_REALTIME value is in order. */ - if (33 <= hostsig && hostsig <= 63) - return (enum target_signal) - (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33); - else if (hostsig == 64) - return TARGET_SIGNAL_REALTIME_64; - else - error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal"); - } -#endif return TARGET_SIGNAL_UNKNOWN; } @@ -516,6 +518,8 @@ static int do_target_signal_to_host (enum target_signal oursig, int *oursig_ok) { + int retsig; + *oursig_ok = 1; switch (oursig) { @@ -740,53 +744,33 @@ do_target_signal_to_host (enum target_signal oursig, default: #if defined (REALTIME_LO) + retsig = 0; + if (oursig >= TARGET_SIGNAL_REALTIME_33 && oursig <= TARGET_SIGNAL_REALTIME_63) { /* This block of signals is continuous, and TARGET_SIGNAL_REALTIME_33 is 33 by definition. */ - int retsig = - (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33; - if (retsig >= REALTIME_LO && retsig < REALTIME_HI) - return retsig; + retsig = (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33; } -#if (REALTIME_LO < 33) else if (oursig == TARGET_SIGNAL_REALTIME_32) { /* TARGET_SIGNAL_REALTIME_32 isn't contiguous with TARGET_SIGNAL_REALTIME_33. It is 32 by definition. */ - return 32; + retsig = 32; } -#endif -#if (REALTIME_HI > 64) - if (oursig >= TARGET_SIGNAL_REALTIME_64 + else if (oursig >= TARGET_SIGNAL_REALTIME_64 && oursig <= TARGET_SIGNAL_REALTIME_127) { /* This block of signals is continuous, and TARGET_SIGNAL_REALTIME_64 is 64 by definition. */ - int retsig = - (int) oursig - (int) TARGET_SIGNAL_REALTIME_64 + 64; - if (retsig >= REALTIME_LO && retsig < REALTIME_HI) - return retsig; + retsig = (int) oursig - (int) TARGET_SIGNAL_REALTIME_64 + 64; } - -#endif + + if (retsig >= REALTIME_LO && retsig < REALTIME_HI) + return retsig; #endif -#if defined (SIGRTMIN) - if (oursig >= TARGET_SIGNAL_REALTIME_33 - && oursig <= TARGET_SIGNAL_REALTIME_63) - { - /* This block of signals is continuous, and - TARGET_SIGNAL_REALTIME_33 is 33 by definition. */ - int retsig = - (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33; - if (retsig >= SIGRTMIN && retsig <= SIGRTMAX) - return retsig; - } - else if (oursig == TARGET_SIGNAL_REALTIME_64) - return 64; -#endif *oursig_ok = 0; return 0; } @@ -835,6 +819,8 @@ Use \"info signals\" for a list of symbolic signals."); } #ifndef GDBSERVER +extern initialize_file_ftype _initialize_signals; /* -Wmissing-prototype */ + void _initialize_signals (void) { diff --git a/contrib/gdb/gdb/sim-regno.h b/contrib/gdb/gdb/sim-regno.h new file mode 100644 index 00000000000..5a7057b6b04 --- /dev/null +++ b/contrib/gdb/gdb/sim-regno.h @@ -0,0 +1,45 @@ +/* Generic remote debugging interface for simulators. + + Copyright 2002 Free Software Foundation, Inc. + + Contributed by Red Hat, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef SIM_REGNO_H +#define SIM_REGNO_H + +/* The REGISTER_SIM_REGNO(REGNUM) method, when there is a + corresponding simulator register, returns that register number as a + cardinal. When there is no corresponding register, it returns a + negative value. */ + +enum sim_regno { + /* Normal sane architecture. The simulator is known to not model + this register. */ + SIM_REGNO_DOES_NOT_EXIST = -1, + /* For possible backward compatibility. The register cache doesn't + have a corresponding name. Skip the register entirely. */ + LEGACY_SIM_REGNO_IGNORE = -2 +}; + +/* Treat all raw registers as valid. */ + +extern int one2one_register_sim_regno (int regnum); + +#endif diff --git a/contrib/gdb/gdb/sol-thread.c b/contrib/gdb/gdb/sol-thread.c index 50caed39d99..3ac2a34d62b 100644 --- a/contrib/gdb/gdb/sol-thread.c +++ b/contrib/gdb/gdb/sol-thread.c @@ -1,5 +1,5 @@ /* Low level interface for debugging Solaris threads for GDB, the GNU debugger. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -55,13 +55,15 @@ #include "target.h" #include "inferior.h" #include -#include +#include "gdb_stat.h" #include #include "gdbcmd.h" #include "gdbcore.h" #include "regcache.h" #include "symfile.h" +#include "gdb_string.h" + extern struct target_ops sol_thread_ops; /* Forward declaration */ extern struct target_ops sol_core_ops; /* Forward declaration */ @@ -109,7 +111,7 @@ static void sol_core_close (int quitting); static void init_sol_thread_ops (void); static void init_sol_core_ops (void); -/* Default definitions: These must be defined in tm.h +/* Default definitions: These must be defined in tm.h if they are to be shared with a process module such as procfs. */ #define GET_PID(ptid) ptid_get_pid (ptid) @@ -125,56 +127,56 @@ static void init_sol_core_ops (void); /* Pointers to routines from lithread_db resolved by dlopen() */ static void (*p_td_log) (const int on_off); -static td_err_e (*p_td_ta_new) (const struct ps_prochandle * ph_p, +static td_err_e (*p_td_ta_new) (const struct ps_prochandle * ph_p, td_thragent_t ** ta_pp); static td_err_e (*p_td_ta_delete) (td_thragent_t * ta_p); static td_err_e (*p_td_init) (void); -static td_err_e (*p_td_ta_get_ph) (const td_thragent_t * ta_p, +static td_err_e (*p_td_ta_get_ph) (const td_thragent_t * ta_p, struct ps_prochandle ** ph_pp); -static td_err_e (*p_td_ta_get_nthreads) (const td_thragent_t * ta_p, +static td_err_e (*p_td_ta_get_nthreads) (const td_thragent_t * ta_p, int *nthread_p); -static td_err_e (*p_td_ta_tsd_iter) (const td_thragent_t * ta_p, - td_key_iter_f * cb, +static td_err_e (*p_td_ta_tsd_iter) (const td_thragent_t * ta_p, + td_key_iter_f * cb, void *cbdata_p); -static td_err_e (*p_td_ta_thr_iter) (const td_thragent_t * ta_p, - td_thr_iter_f * cb, - void *cbdata_p, +static td_err_e (*p_td_ta_thr_iter) (const td_thragent_t * ta_p, + td_thr_iter_f * cb, + void *cbdata_p, td_thr_state_e state, - int ti_pri, - sigset_t * ti_sigmask_p, + int ti_pri, + sigset_t * ti_sigmask_p, unsigned ti_user_flags); static td_err_e (*p_td_thr_validate) (const td_thrhandle_t * th_p); -static td_err_e (*p_td_thr_tsd) (const td_thrhandle_t * th_p, - const thread_key_t key, +static td_err_e (*p_td_thr_tsd) (const td_thrhandle_t * th_p, + const thread_key_t key, void **data_pp); -static td_err_e (*p_td_thr_get_info) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_get_info) (const td_thrhandle_t * th_p, td_thrinfo_t * ti_p); -static td_err_e (*p_td_thr_getfpregs) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_getfpregs) (const td_thrhandle_t * th_p, prfpregset_t * fpregset); -static td_err_e (*p_td_thr_getxregsize) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_getxregsize) (const td_thrhandle_t * th_p, int *xregsize); -static td_err_e (*p_td_thr_getxregs) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_getxregs) (const td_thrhandle_t * th_p, const caddr_t xregset); -static td_err_e (*p_td_thr_sigsetmask) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_sigsetmask) (const td_thrhandle_t * th_p, const sigset_t ti_sigmask); -static td_err_e (*p_td_thr_setprio) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_setprio) (const td_thrhandle_t * th_p, const int ti_pri); -static td_err_e (*p_td_thr_setsigpending) (const td_thrhandle_t * th_p, - const uchar_t ti_pending_flag, +static td_err_e (*p_td_thr_setsigpending) (const td_thrhandle_t * th_p, + const uchar_t ti_pending_flag, const sigset_t ti_pending); -static td_err_e (*p_td_thr_setfpregs) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_setfpregs) (const td_thrhandle_t * th_p, const prfpregset_t * fpregset); -static td_err_e (*p_td_thr_setxregs) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_setxregs) (const td_thrhandle_t * th_p, const caddr_t xregset); -static td_err_e (*p_td_ta_map_id2thr) (const td_thragent_t * ta_p, - thread_t tid, +static td_err_e (*p_td_ta_map_id2thr) (const td_thragent_t * ta_p, + thread_t tid, td_thrhandle_t * th_p); -static td_err_e (*p_td_ta_map_lwp2thr) (const td_thragent_t * ta_p, - lwpid_t lwpid, +static td_err_e (*p_td_ta_map_lwp2thr) (const td_thragent_t * ta_p, + lwpid_t lwpid, td_thrhandle_t * th_p); -static td_err_e (*p_td_thr_getgregs) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_getgregs) (const td_thrhandle_t * th_p, prgregset_t regset); -static td_err_e (*p_td_thr_setgregs) (const td_thrhandle_t * th_p, +static td_err_e (*p_td_thr_setgregs) (const td_thrhandle_t * th_p, const prgregset_t regset); /* @@ -399,8 +401,6 @@ lwp_to_thread (ptid_t lwp) /* Most target vector functions from here on actually just pass through to procfs.c, as they don't need to do anything specific for threads. */ - -/* ARGSUSED */ static void sol_thread_open (char *arg, int from_tty) { @@ -646,9 +646,10 @@ sol_thread_store_registers (int regno) if (regno != -1) { /* Not writing all the regs */ - /* save new register value */ - char* old_value = (char*) alloca (REGISTER_SIZE); - memcpy (old_value, ®isters[REGISTER_BYTE (regno)], REGISTER_SIZE); + char old_value[MAX_REGISTER_SIZE]; + + /* Save new register value. */ + regcache_collect (regno, old_value); val = p_td_thr_getgregs (&thandle, gregset); if (val != TD_OK) @@ -659,8 +660,8 @@ sol_thread_store_registers (int regno) error ("sol_thread_store_registers: td_thr_getfpregs %s", td_err_string (val)); - /* restore new register value */ - memcpy (®isters[REGISTER_BYTE (regno)], old_value, REGISTER_SIZE); + /* Restore new register value. */ + supply_register (regno, old_value); #if 0 /* thread_db doesn't seem to handle this right */ @@ -738,7 +739,7 @@ sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite, /* Note: don't need to call switch_to_thread; we're just reading memory. */ if (target_has_execution) - retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, + retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attrib, target); else retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len, @@ -749,6 +750,37 @@ sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite, return retval; } +/* Perform partial transfers on OBJECT. See target_read_partial + and target_write_partial for details of each variant. One, and + only one, of readbuf or writebuf must be non-NULL. */ + +static LONGEST +sol_thread_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + int retval; + struct cleanup *old_chain; + + old_chain = save_inferior_ptid (); + + if (is_thread (inferior_ptid) || /* A thread */ + !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */ + inferior_ptid = procfs_first_available (); /* Find any live lwp. */ + /* Note: don't need to call switch_to_thread; we're just reading memory. */ + + if (target_has_execution) + retval = procfs_ops.to_xfer_partial (ops, object, annex, + readbuf, writebuf, offset, len); + else + retval = orig_core_ops.to_xfer_partial (ops, object, annex, + readbuf, writebuf, offset, len); + + do_cleanups (old_chain); + + return retval; +} + /* Print status information about what we're accessing. */ static void @@ -797,7 +829,7 @@ sol_thread_create_inferior (char *exec_file, char *allargs, char **env) those variables don't show up until the library gets mapped and the symbol table is read in. */ -/* This new_objfile event is now managed by a chained function pointer. +/* This new_objfile event is now managed by a chained function pointer. * It is the callee's responsability to call the next client on the chain. */ @@ -863,7 +895,7 @@ sol_thread_can_run (void) return procfs_suppress_run; } -/* +/* LOCAL FUNCTION @@ -1027,10 +1059,10 @@ rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr, /* FIXME: passing 0 as attrib argument. */ if (target_has_execution) - cc = procfs_ops.to_xfer_memory (addr, buf, size, + cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, 0, &procfs_ops); else - cc = orig_core_ops.to_xfer_memory (addr, buf, size, + cc = orig_core_ops.to_xfer_memory (addr, buf, size, dowrite, 0, &core_ops); if (cc < 0) @@ -1047,10 +1079,10 @@ rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr, else if (cc == 0) { if (dowrite == 0) - warning ("rw_common (): unable to read at addr 0x%lx", + warning ("rw_common (): unable to read at addr 0x%lx", (long) addr); else - warning ("rw_common (): unable to write at addr 0x%lx", + warning ("rw_common (): unable to write at addr 0x%lx", (long) addr); do_cleanups (old_chain); @@ -1429,7 +1461,7 @@ sol_core_files_info (struct target_ops *t) } /* Worker bee for info sol-thread command. This is a callback function that - gets called once for each Solaris thread (ie. not kernel thread) in the + gets called once for each Solaris thread (ie. not kernel thread) in the inferior. Print anything interesting that we can think of. */ static int @@ -1474,7 +1506,7 @@ info_cb (const td_thrhandle_t *th, void *s) struct minimal_symbol *msym; msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc); if (msym) - printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym)); + printf_filtered (" startfunc: %s\n", DEPRECATED_SYMBOL_NAME (msym)); else printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc)); } @@ -1485,7 +1517,7 @@ info_cb (const td_thrhandle_t *th, void *s) struct minimal_symbol *msym; msym = lookup_minimal_symbol_by_pc (ti.ti_pc); if (msym) - printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym)); + printf_filtered (" - Sleep func: %s\n", DEPRECATED_SYMBOL_NAME (msym)); else printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc)); } @@ -1511,10 +1543,10 @@ info_solthreads (char *args, int from_tty) } static int -sol_find_memory_regions (int (*func) (CORE_ADDR, - unsigned long, - int, int, int, - void *), +sol_find_memory_regions (int (*func) (CORE_ADDR, + unsigned long, + int, int, int, + void *), void *data) { return procfs_ops.to_find_memory_regions (func, data); @@ -1540,7 +1572,6 @@ init_sol_thread_ops (void) sol_thread_ops.to_longname = "Solaris threads and pthread."; sol_thread_ops.to_doc = "Solaris threads and pthread support."; sol_thread_ops.to_open = sol_thread_open; - sol_thread_ops.to_close = 0; sol_thread_ops.to_attach = sol_thread_attach; sol_thread_ops.to_detach = sol_thread_detach; sol_thread_ops.to_resume = sol_thread_resume; @@ -1549,6 +1580,7 @@ init_sol_thread_ops (void) sol_thread_ops.to_store_registers = sol_thread_store_registers; sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store; sol_thread_ops.to_xfer_memory = sol_thread_xfer_memory; + sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial; sol_thread_ops.to_files_info = sol_thread_files_info; sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint; sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint; @@ -1556,10 +1588,9 @@ init_sol_thread_ops (void) sol_thread_ops.to_terminal_inferior = terminal_inferior; sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output; sol_thread_ops.to_terminal_ours = terminal_ours; + sol_thread_ops.to_terminal_save_ours = terminal_save_ours; sol_thread_ops.to_terminal_info = child_terminal_info; sol_thread_ops.to_kill = sol_thread_kill_inferior; - sol_thread_ops.to_load = 0; - sol_thread_ops.to_lookup_symbol = 0; sol_thread_ops.to_create_inferior = sol_thread_create_inferior; sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior; sol_thread_ops.to_can_run = sol_thread_can_run; @@ -1575,8 +1606,6 @@ init_sol_thread_ops (void) sol_thread_ops.to_has_registers = 1; sol_thread_ops.to_has_execution = 1; sol_thread_ops.to_has_thread_control = tc_none; - sol_thread_ops.to_sections = 0; - sol_thread_ops.to_sections_end = 0; sol_thread_ops.to_find_memory_regions = sol_find_memory_regions; sol_thread_ops.to_make_corefile_notes = sol_make_note_section; sol_thread_ops.to_magic = OPS_MAGIC; @@ -1593,30 +1622,17 @@ init_sol_core_ops (void) sol_core_ops.to_close = sol_core_close; sol_core_ops.to_attach = sol_thread_attach; sol_core_ops.to_detach = sol_core_detach; - /* sol_core_ops.to_resume = 0; */ - /* sol_core_ops.to_wait = 0; */ sol_core_ops.to_fetch_registers = sol_thread_fetch_registers; - /* sol_core_ops.to_store_registers = 0; */ - /* sol_core_ops.to_prepare_to_store = 0; */ sol_core_ops.to_xfer_memory = sol_thread_xfer_memory; + sol_core_ops.to_xfer_partial = sol_thread_xfer_partial; sol_core_ops.to_files_info = sol_core_files_info; sol_core_ops.to_insert_breakpoint = ignore; sol_core_ops.to_remove_breakpoint = ignore; - /* sol_core_ops.to_terminal_init = 0; */ - /* sol_core_ops.to_terminal_inferior = 0; */ - /* sol_core_ops.to_terminal_ours_for_output = 0; */ - /* sol_core_ops.to_terminal_ours = 0; */ - /* sol_core_ops.to_terminal_info = 0; */ - /* sol_core_ops.to_kill = 0; */ - /* sol_core_ops.to_load = 0; */ - /* sol_core_ops.to_lookup_symbol = 0; */ sol_core_ops.to_create_inferior = sol_thread_create_inferior; sol_core_ops.to_stratum = core_stratum; - sol_core_ops.to_has_all_memory = 0; sol_core_ops.to_has_memory = 1; sol_core_ops.to_has_stack = 1; sol_core_ops.to_has_registers = 1; - sol_core_ops.to_has_execution = 0; sol_core_ops.to_has_thread_control = tc_none; sol_core_ops.to_thread_alive = sol_thread_alive; sol_core_ops.to_pid_to_str = solaris_pid_to_str; @@ -1625,8 +1641,6 @@ init_sol_core_ops (void) in procinfo list" where is the pid of the process that produced the core file. Disable it for now. */ /* sol_core_ops.to_find_new_threads = sol_find_new_threads; */ - sol_core_ops.to_sections = 0; - sol_core_ops.to_sections_end = 0; sol_core_ops.to_magic = OPS_MAGIC; } diff --git a/contrib/gdb/gdb/solib-legacy.c b/contrib/gdb/gdb/solib-legacy.c index ca730c4ad9b..a87eb21511a 100644 --- a/contrib/gdb/gdb/solib-legacy.c +++ b/contrib/gdb/gdb/solib-legacy.c @@ -19,7 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define _SYSCALL32 /* for Sparc64 cross Sparc32 */ #include "defs.h" #include "gdbcore.h" #include "solib-svr4.h" @@ -143,6 +142,8 @@ legacy_svr4_fetch_link_map_offsets (void) #endif /* HAVE_LINK_H */ +extern initialize_file_ftype _initialize_svr4_lm; /* -Wmissing-prototypes */ + void _initialize_svr4_lm (void) { diff --git a/contrib/gdb/gdb/solib-osf.c b/contrib/gdb/gdb/solib-osf.c index a00e488ee04..b5dca60750d 100644 --- a/contrib/gdb/gdb/solib-osf.c +++ b/contrib/gdb/gdb/solib-osf.c @@ -321,7 +321,7 @@ osf_solib_create_inferior_hook (void) out what we need to know about them. */ clear_proceed_status (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { @@ -334,10 +334,10 @@ osf_solib_create_inferior_hook (void) But we are stopped in the runtime loader and we do not have symbols for the runtime loader. So heuristic_proc_start will be called and will put out an annoying warning. - Delaying the resetting of stop_soon_quietly until after symbol loading + Delaying the resetting of stop_soon until after symbol loading suppresses the warning. */ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; /* Enable breakpoints disabled (unnecessarily) by clear_solib(). */ re_enable_breakpoints_in_shlibs (); @@ -359,7 +359,14 @@ static int open_map (struct read_map_ctxt *ctxt) { #ifdef USE_LDR_ROUTINES - ctxt->proc = ldr_my_process (); + /* Note: As originally written, ldr_my_process() was used to obtain + the value for ctxt->proc. This is incorrect, however, since + ldr_my_process() retrieves the "unique identifier" associated + with the current process (i.e. GDB) and not the one being + debugged. Presumably, the pid of the process being debugged is + compatible with the "unique identifier" used by the ldr_ + routines, so we use that. */ + ctxt->proc = ptid_get_pid (inferior_ptid); if (ldr_xattach (ctxt->proc) != 0) return 0; ctxt->next = LDR_NULL_MODULE; diff --git a/contrib/gdb/gdb/solib-sunos.c b/contrib/gdb/gdb/solib-sunos.c index 0f81d05efa4..a88e7b735e8 100644 --- a/contrib/gdb/gdb/solib-sunos.c +++ b/contrib/gdb/gdb/solib-sunos.c @@ -1,6 +1,6 @@ /* Handle SunOS shared libraries for GDB, the GNU Debugger. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, - 2001 + 2001, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -39,6 +39,8 @@ #include "gdbcore.h" #include "inferior.h" #include "solist.h" +#include "bcache.h" +#include "regcache.h" /* Link map info to include in an allocated so_list entry */ @@ -66,14 +68,16 @@ static char *main_name_list[] = NULL }; -/* Macro to extract an address from a solib structure. - When GDB is configured for some 32-bit targets (e.g. Solaris 2.7 - sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is - 64 bits. We have to extract only the significant bits of addresses - to get the right address when accessing the core file BFD. */ +/* Macro to extract an address from a solib structure. When GDB is + configured for some 32-bit targets (e.g. Solaris 2.7 sparc), BFD is + configured to handle 64-bit targets, so CORE_ADDR is 64 bits. We + have to extract only the significant bits of addresses to get the + right address when accessing the core file BFD. + + Assume that the address is unsigned. */ #define SOLIB_EXTRACT_ADDRESS(MEMBER) \ - extract_address (&(MEMBER), sizeof (MEMBER)) + extract_unsigned_integer (&(MEMBER), sizeof (MEMBER)) /* local data declarations */ @@ -106,7 +110,9 @@ LM_NEXT (struct so_list *so) int lm_next_offset = offsetof (struct link_map, lm_next); int lm_next_size = fieldsize (struct link_map, lm_next); - return extract_address (so->lm_info->lm + lm_next_offset, lm_next_size); + /* Assume that the address is unsigned. */ + return extract_unsigned_integer (so->lm_info->lm + lm_next_offset, + lm_next_size); } static CORE_ADDR @@ -115,7 +121,9 @@ LM_NAME (struct so_list *so) int lm_name_offset = offsetof (struct link_map, lm_name); int lm_name_size = fieldsize (struct link_map, lm_name); - return extract_address (so->lm_info->lm + lm_name_offset, lm_name_size); + /* Assume that the address is unsigned. */ + return extract_unsigned_integer (so->lm_info->lm + lm_name_offset, + lm_name_size); } static CORE_ADDR debug_base; /* Base of dynamic linker structures */ @@ -135,14 +143,9 @@ allocate_rt_common_objfile (void) objfile = (struct objfile *) xmalloc (sizeof (struct objfile)); memset (objfile, 0, sizeof (struct objfile)); objfile->md = NULL; - obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0, - xmalloc, xfree); - obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc, - xfree); - obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc, - xfree); - obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc, - xfree); + objfile->psymbol_cache = bcache_xmalloc (); + objfile->macro_cache = bcache_xmalloc (); + obstack_init (&objfile->objfile_obstack); objfile->name = mstrsave (objfile->md, "rt_common"); /* Add this file onto the tail of the linked list of other such files. */ @@ -177,11 +180,11 @@ solib_add_common_symbols (CORE_ADDR rtc_symp) if (rt_common_objfile != NULL && rt_common_objfile->minimal_symbol_count) { - obstack_free (&rt_common_objfile->symbol_obstack, 0); - obstack_specify_allocation (&rt_common_objfile->symbol_obstack, 0, 0, - xmalloc, xfree); + obstack_free (&rt_common_objfile->objfile_obstack, 0); + obstack_init (&rt_common_objfile->objfile_obstack); rt_common_objfile->minimal_symbol_count = 0; rt_common_objfile->msymbols = NULL; + terminate_minimal_symbol_table (rt_common_objfile); } init_minimal_symbol_collection (); @@ -826,7 +829,7 @@ sunos_solib_create_inferior_hook (void) out what we need to know about them. */ clear_proceed_status (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { @@ -834,7 +837,7 @@ sunos_solib_create_inferior_hook (void) wait_for_inferior (); } while (stop_signal != TARGET_SIGNAL_TRAP); - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; /* We are now either at the "mapping complete" breakpoint (or somewhere else, a condition we aren't prepared to deal with anyway), so adjust diff --git a/contrib/gdb/gdb/solib-svr4.c b/contrib/gdb/gdb/solib-svr4.c index 9c71509b643..4f4664cc017 100644 --- a/contrib/gdb/gdb/solib-svr4.c +++ b/contrib/gdb/gdb/solib-svr4.c @@ -1,6 +1,7 @@ /* Handle SVR4 shared libraries for GDB, the GNU Debugger. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, - 2001 + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, + 2000, 2001, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -37,12 +38,16 @@ #include "solist.h" #include "solib-svr4.h" +#include "bfd-target.h" +#include "exec.h" + #ifndef SVR4_FETCH_LINK_MAP_OFFSETS #define SVR4_FETCH_LINK_MAP_OFFSETS() svr4_fetch_link_map_offsets () #endif static struct link_map_offsets *svr4_fetch_link_map_offsets (void); static struct link_map_offsets *legacy_fetch_link_map_offsets (void); +static int svr4_have_link_map_offsets (void); /* fetch_link_map_offsets_gdbarch_data is a handle used to obtain the architecture specific link map offsets fetching function. */ @@ -80,6 +85,17 @@ static char *solib_break_names[] = "_dl_debug_state", "rtld_db_dlactivity", "_rtld_debug_state", + + /* On the 64-bit PowerPC, the linker symbol with the same name as + the C function points to a function descriptor, not to the entry + point. The linker symbol whose name is the C function name + prefixed with a '.' points to the function's entry point. So + when we look through this table, we ignore symbols that point + into the data section (thus skipping the descriptor's symbol), + and eventually try this one, giving us the real entry point + address. */ + "._dl_debug_state", + NULL }; @@ -92,6 +108,7 @@ static char *bkpt_names[] = SOLIB_BKPT_NAME, /* Prefer configured name if it exists. */ #endif "_start", + "__start", "main", NULL }; @@ -103,14 +120,16 @@ static char *main_name_list[] = NULL }; -/* Macro to extract an address from a solib structure. - When GDB is configured for some 32-bit targets (e.g. Solaris 2.7 - sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is - 64 bits. We have to extract only the significant bits of addresses - to get the right address when accessing the core file BFD. */ +/* Macro to extract an address from a solib structure. When GDB is + configured for some 32-bit targets (e.g. Solaris 2.7 sparc), BFD is + configured to handle 64-bit targets, so CORE_ADDR is 64 bits. We + have to extract only the significant bits of addresses to get the + right address when accessing the core file BFD. + + Assume that the address is unsigned. */ #define SOLIB_EXTRACT_ADDRESS(MEMBER) \ - extract_address (&(MEMBER), sizeof (MEMBER)) + extract_unsigned_integer (&(MEMBER), sizeof (MEMBER)) /* local data declarations */ @@ -130,7 +149,9 @@ LM_NEXT (struct so_list *so) { struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); - return extract_address (so->lm_info->lm + lmo->l_next_offset, lmo->l_next_size); + /* Assume that the address is unsigned. */ + return extract_unsigned_integer (so->lm_info->lm + lmo->l_next_offset, + lmo->l_next_size); } static CORE_ADDR @@ -138,7 +159,9 @@ LM_NAME (struct so_list *so) { struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); - return extract_address (so->lm_info->lm + lmo->l_name_offset, lmo->l_name_size); + /* Assume that the address is unsigned. */ + return extract_unsigned_integer (so->lm_info->lm + lmo->l_name_offset, + lmo->l_name_size); } static int @@ -146,8 +169,9 @@ IGNORE_FIRST_LINK_MAP_ENTRY (struct so_list *so) { struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); - return extract_address (so->lm_info->lm + lmo->l_prev_offset, - lmo->l_prev_size) == 0; + /* Assume that the address is unsigned. */ + return extract_unsigned_integer (so->lm_info->lm + lmo->l_prev_offset, + lmo->l_prev_size) == 0; } static CORE_ADDR debug_base; /* Base of dynamic linker structures */ @@ -157,7 +181,7 @@ static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ static int match_main (char *); -static CORE_ADDR bfd_lookup_symbol (bfd *, char *); +static CORE_ADDR bfd_lookup_symbol (bfd *, char *, flagword); /* @@ -167,7 +191,7 @@ static CORE_ADDR bfd_lookup_symbol (bfd *, char *); SYNOPSIS - CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname) + CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname, flagword sect_flags) DESCRIPTION @@ -176,12 +200,15 @@ static CORE_ADDR bfd_lookup_symbol (bfd *, char *); shared library support to find the address of the debugger interface structures in the shared library. + If SECT_FLAGS is non-zero, only match symbols in sections whose + flags include all those in SECT_FLAGS. + Note that 0 is specifically allowed as an error return (no such symbol). */ static CORE_ADDR -bfd_lookup_symbol (bfd *abfd, char *symname) +bfd_lookup_symbol (bfd *abfd, char *symname, flagword sect_flags) { long storage_needed; asymbol *sym; @@ -196,13 +223,14 @@ bfd_lookup_symbol (bfd *abfd, char *symname) if (storage_needed > 0) { symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (xfree, (PTR) symbol_table); + back_to = make_cleanup (xfree, symbol_table); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); for (i = 0; i < number_of_symbols; i++) { sym = *symbol_table++; - if (STREQ (sym->name, symname)) + if (strcmp (sym->name, symname) == 0 + && (sym->section->flags & sect_flags) == sect_flags) { /* Bfd symbols are section relative. */ symaddr = sym->value + sym->section->vma; @@ -223,13 +251,15 @@ bfd_lookup_symbol (bfd *abfd, char *symname) if (storage_needed > 0) { symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (xfree, (PTR) symbol_table); + back_to = make_cleanup (xfree, symbol_table); number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table); for (i = 0; i < number_of_symbols; i++) { sym = *symbol_table++; - if (STREQ (sym->name, symname)) + + if (strcmp (sym->name, symname) == 0 + && (sym->section->flags & sect_flags) == sect_flags) { /* Bfd symbols are section relative. */ symaddr = sym->value + sym->section->vma; @@ -335,7 +365,7 @@ look_for_base (int fd, CORE_ADDR baseaddr) for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++) { - address = bfd_lookup_symbol (interp_bfd, *symbolp); + address = bfd_lookup_symbol (interp_bfd, *symbolp, 0); if (address != 0) { break; @@ -396,7 +426,7 @@ look_for_base (int fd, CORE_ADDR baseaddr) static CORE_ADDR elf_locate_base (void) { - sec_ptr dyninfo_sect; + struct bfd_section *dyninfo_sect; int dyninfo_sect_size; CORE_ADDR dyninfo_addr; char *buf; @@ -445,15 +475,16 @@ elf_locate_base (void) else if (dyn_tag == DT_MIPS_RLD_MAP) { char *pbuf; + int pbuf_size = TARGET_PTR_BIT / HOST_CHAR_BIT; - pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT); + pbuf = alloca (pbuf_size); /* DT_MIPS_RLD_MAP contains a pointer to the address of the dynamic link structure. */ dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr); - if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf))) + if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) return 0; - return extract_unsigned_integer (pbuf, sizeof (pbuf)); + return extract_unsigned_integer (pbuf, pbuf_size); } } } @@ -476,6 +507,20 @@ elf_locate_base (void) (bfd_byte *) x_dynp->d_un.d_ptr); return dyn_ptr; } + else if (dyn_tag == DT_MIPS_RLD_MAP) + { + char *pbuf; + int pbuf_size = TARGET_PTR_BIT / HOST_CHAR_BIT; + + pbuf = alloca (pbuf_size); + /* DT_MIPS_RLD_MAP contains a pointer to the address + of the dynamic link structure. */ + dyn_ptr = bfd_h_get_64 (exec_bfd, + (bfd_byte *) x_dynp->d_un.d_ptr); + if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) + return 0; + return extract_unsigned_integer (pbuf, pbuf_size); + } } } @@ -526,9 +571,10 @@ locate_base (void) /* Check to see if we have a currently valid address, and if so, avoid doing all this work again and just return the cached address. If we have no cached address, try to locate it in the dynamic info - section for ELF executables. */ + section for ELF executables. There's no point in doing any of this + though if we don't have some link map offsets to work with. */ - if (debug_base == 0) + if (debug_base == 0 && svr4_have_link_map_offsets ()) { if (exec_bfd != NULL && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour) @@ -569,7 +615,8 @@ first_link_map_member (void) read_memory (debug_base + lmo->r_map_offset, r_map_buf, lmo->r_map_size); - lm = extract_address (r_map_buf, lmo->r_map_size); + /* Assume that the address is unsigned. */ + lm = extract_unsigned_integer (r_map_buf, lmo->r_map_size); /* FIXME: Perhaps we should validate the info somehow, perhaps by checking r_version for a known version number, or r_state for @@ -627,8 +674,9 @@ open_symbol_file_object (void *from_ttyp) /* Read address of name from target memory to GDB. */ read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size); - /* Convert the address to host format. */ - l_name = extract_address (l_name_buf, lmo->l_name_size); + /* Convert the address to host format. Assume that the address is + unsigned. */ + l_name = extract_unsigned_integer (l_name_buf, lmo->l_name_size); /* Free l_name_buf. */ do_cleanups (cleanups); @@ -761,6 +809,78 @@ svr4_current_sos (void) return head; } +/* Get the address of the link_map for a given OBJFILE. Loop through + the link maps, and return the address of the one corresponding to + the given objfile. Note that this function takes into account that + objfile can be the main executable, not just a shared library. The + main executable has always an empty name field in the linkmap. */ + +CORE_ADDR +svr4_fetch_objfile_link_map (struct objfile *objfile) +{ + CORE_ADDR lm; + + if ((debug_base = locate_base ()) == 0) + return 0; /* failed somehow... */ + + /* Position ourselves on the first link map. */ + lm = first_link_map_member (); + while (lm) + { + /* Get info on the layout of the r_debug and link_map structures. */ + struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); + int errcode; + char *buffer; + struct lm_info objfile_lm_info; + struct cleanup *old_chain; + CORE_ADDR name_address; + char *l_name_buf = xmalloc (lmo->l_name_size); + old_chain = make_cleanup (xfree, l_name_buf); + + /* Set up the buffer to contain the portion of the link_map + structure that gdb cares about. Note that this is not the + whole link_map structure. */ + objfile_lm_info.lm = xmalloc (lmo->link_map_size); + make_cleanup (xfree, objfile_lm_info.lm); + memset (objfile_lm_info.lm, 0, lmo->link_map_size); + + /* Read the link map into our internal structure. */ + read_memory (lm, objfile_lm_info.lm, lmo->link_map_size); + + /* Read address of name from target memory to GDB. */ + read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size); + + /* Extract this object's name. Assume that the address is + unsigned. */ + name_address = extract_unsigned_integer (l_name_buf, lmo->l_name_size); + target_read_string (name_address, &buffer, + SO_NAME_MAX_PATH_SIZE - 1, &errcode); + make_cleanup (xfree, buffer); + if (errcode != 0) + { + warning ("svr4_fetch_objfile_link_map: Can't read pathname for load map: %s\n", + safe_strerror (errcode)); + } + else + { + /* Is this the linkmap for the file we want? */ + /* If the file is not a shared library and has no name, + we are sure it is the main executable, so we return that. */ + if ((buffer && strcmp (buffer, objfile->name) == 0) + || (!(objfile->flags & OBJF_SHARED) && (strcmp (buffer, "") == 0))) + { + do_cleanups (old_chain); + return lm; + } + } + /* Not the file we wanted, continue checking. Assume that the + address is unsigned. */ + lm = extract_unsigned_integer (objfile_lm_info.lm + lmo->l_next_offset, + lmo->l_next_size); + do_cleanups (old_chain); + } + return 0; +} /* On some systems, the only way to recognize the link map entry for the main executable file is by looking at its name. Return @@ -795,6 +915,24 @@ svr4_in_dynsym_resolve_code (CORE_ADDR pc) || in_plt_section (pc, NULL)); } +/* Given an executable's ABFD and target, compute the entry-point + address. */ + +static CORE_ADDR +exec_entry_point (struct bfd *abfd, struct target_ops *targ) +{ + /* KevinB wrote ... for most targets, the address returned by + bfd_get_start_address() is the entry point for the start + function. But, for some targets, bfd_get_start_address() returns + the address of a function descriptor from which the entry point + address may be extracted. This address is extracted by + gdbarch_convert_from_func_ptr_addr(). The method + gdbarch_convert_from_func_ptr_addr() is the merely the identify + function for targets which don't use function descriptors. */ + return gdbarch_convert_from_func_ptr_addr (current_gdbarch, + bfd_get_start_address (abfd), + targ); +} /* @@ -868,6 +1006,7 @@ enable_break (void) int load_addr_found = 0; struct so_list *inferior_sos; bfd *tmp_bfd = NULL; + struct target_ops *tmp_bfd_target; int tmp_fd = -1; char *tmp_pathname = NULL; CORE_ADDR sym_addr = 0; @@ -903,6 +1042,11 @@ enable_break (void) goto bkpt_at_symbol; } + /* Now convert the TMP_BFD into a target. That way target, as + well as BFD operations can be used. Note that closing the + target will also close the underlying bfd. */ + tmp_bfd_target = target_bfd_reopen (tmp_bfd); + /* If the entry in _DYNAMIC for the dynamic linker has already been filled in, we can read its base address from there. */ inferior_sos = svr4_current_sos (); @@ -926,7 +1070,8 @@ enable_break (void) the current pc (which should point at the entry point for the dynamic linker) and subtracting the offset of the entry point. */ if (!load_addr_found) - load_addr = read_pc () - tmp_bfd->start_address; + load_addr = (read_pc () + - exec_entry_point (tmp_bfd, tmp_bfd_target)); /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ @@ -950,13 +1095,23 @@ enable_break (void) /* Now try to set a breakpoint in the dynamic linker. */ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { - sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep); + /* On ABI's that use function descriptors, there are usually + two linker symbols associated with each C function: one + pointing at the actual entry point of the machine code, + and one pointing at the function's descriptor. The + latter symbol has the same name as the C function. + + What we're looking for here is the machine code entry + point, so we are only interested in symbols in code + sections. */ + sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep, SEC_CODE); if (sym_addr != 0) break; } - /* We're done with the temporary bfd. */ - bfd_close (tmp_bfd); + /* We're done with both the temporary bfd and target. Remember, + closing the target closes the underlying bfd. */ + target_close (tmp_bfd_target, 0); if (sym_addr != 0) { @@ -1075,7 +1230,7 @@ svr4_relocate_main_executable (void) interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect == NULL && (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0 - && bfd_get_start_address (exec_bfd) != pc) + && (exec_entry_point (exec_bfd, &exec_ops) != pc)) { struct cleanup *old_chain; struct section_offsets *new_offsets; @@ -1107,7 +1262,7 @@ svr4_relocate_main_executable (void) The same language also appears in Edition 4.0 of the System V ABI and is left unspecified in some of the earlier editions. */ - displacement = pc - bfd_get_start_address (exec_bfd); + displacement = pc - exec_entry_point (exec_bfd, &exec_ops); changed = 0; new_offsets = xcalloc (symfile_objfile->num_sections, @@ -1186,6 +1341,13 @@ svr4_solib_create_inferior_hook (void) /* Relocate the main executable if necessary. */ svr4_relocate_main_executable (); + if (!svr4_have_link_map_offsets ()) + { + warning ("no shared library support for this OS / ABI"); + return; + + } + if (!enable_break ()) { warning ("shared library handler failed to enable breakpoint"); @@ -1203,7 +1365,7 @@ svr4_solib_create_inferior_hook (void) out what we need to know about them. */ clear_proceed_status (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { @@ -1211,7 +1373,7 @@ svr4_solib_create_inferior_hook (void) wait_for_inferior (); } while (stop_signal != TARGET_SIGNAL_TRAP); - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; #endif /* defined(_SCO_DS) */ } @@ -1292,7 +1454,7 @@ static struct link_map_offsets * svr4_fetch_link_map_offsets (void) { struct link_map_offsets *(*flmo)(void) = - gdbarch_data (fetch_link_map_offsets_gdbarch_data); + gdbarch_data (current_gdbarch, fetch_link_map_offsets_gdbarch_data); if (flmo == NULL) { @@ -1305,6 +1467,20 @@ svr4_fetch_link_map_offsets (void) return (flmo ()); } +/* Return 1 if a link map offset fetcher has been defined, 0 otherwise. */ +static int +svr4_have_link_map_offsets (void) +{ + struct link_map_offsets *(*flmo)(void) = + gdbarch_data (current_gdbarch, fetch_link_map_offsets_gdbarch_data); + if (flmo == NULL + || (flmo == legacy_fetch_link_map_offsets + && legacy_svr4_fetch_link_map_offsets_hook == NULL)) + return 0; + else + return 1; +} + /* set_solib_svr4_fetch_link_map_offsets() is intended to be called by a _gdbarch_init() function. It is used to establish an architecture specific link_map_offsets fetcher for the architecture @@ -1317,33 +1493,102 @@ set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch, set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo); } -/* Initialize the architecture specific link_map_offsets fetcher. - This is called after _gdbarch_init() has set up its struct - gdbarch for the new architecture, so care must be taken to use the - value set by set_solib_svr4_fetch_link_map_offsets(), above. We - do, however, attempt to provide a reasonable alternative (for - native targets anyway) if the _gdbarch_init() fails to call +/* Initialize the architecture-specific link_map_offsets fetcher. + This is called after _gdbarch_init() has set up its `struct + gdbarch' for the new architecture, and is only called if the + link_map_offsets fetcher isn't already initialized (which is + usually done by calling set_solib_svr4_fetch_link_map_offsets() + above in _gdbarch_init()). Therefore we attempt to provide a + reasonable alternative (for native targets anyway) if the + _gdbarch_init() fails to call set_solib_svr4_fetch_link_map_offsets(). */ static void * init_fetch_link_map_offsets (struct gdbarch *gdbarch) { - struct link_map_offsets *(*flmo) = - gdbarch_data (fetch_link_map_offsets_gdbarch_data); - - if (flmo == NULL) - return legacy_fetch_link_map_offsets; - else - return flmo; + return legacy_fetch_link_map_offsets; } +/* Most OS'es that have SVR4-style ELF dynamic libraries define a + `struct r_debug' and a `struct link_map' that are binary compatible + with the origional SVR4 implementation. */ + +/* Fetch (and possibly build) an appropriate `struct link_map_offsets' + for an ILP32 SVR4 system. */ + +struct link_map_offsets * +svr4_ilp32_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + /* Everything we need is in the first 8 bytes. */ + lmo.r_debug_size = 8; + lmo.r_map_offset = 4; + lmo.r_map_size = 4; + + /* Everything we need is in the first 20 bytes. */ + lmo.link_map_size = 20; + lmo.l_addr_offset = 0; + lmo.l_addr_size = 4; + lmo.l_name_offset = 4; + lmo.l_name_size = 4; + lmo.l_next_offset = 12; + lmo.l_next_size = 4; + lmo.l_prev_offset = 16; + lmo.l_prev_size = 4; + } + + return lmp; +} + +/* Fetch (and possibly build) an appropriate `struct link_map_offsets' + for an LP64 SVR4 system. */ + +struct link_map_offsets * +svr4_lp64_fetch_link_map_offsets (void) +{ + static struct link_map_offsets lmo; + static struct link_map_offsets *lmp = NULL; + + if (lmp == NULL) + { + lmp = &lmo; + + /* Everything we need is in the first 16 bytes. */ + lmo.r_debug_size = 16; + lmo.r_map_offset = 8; + lmo.r_map_size = 8; + + /* Everything we need is in the first 40 bytes. */ + lmo.link_map_size = 40; + lmo.l_addr_offset = 0; + lmo.l_addr_size = 8; + lmo.l_name_offset = 8; + lmo.l_name_size = 8; + lmo.l_next_offset = 24; + lmo.l_next_size = 8; + lmo.l_prev_offset = 32; + lmo.l_prev_size = 8; + } + + return lmp; +} + + static struct target_so_ops svr4_so_ops; +extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */ + void _initialize_svr4_solib (void) { fetch_link_map_offsets_gdbarch_data = - register_gdbarch_data (init_fetch_link_map_offsets, 0); + register_gdbarch_data (init_fetch_link_map_offsets); svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses; svr4_so_ops.free_so = svr4_free_so; diff --git a/contrib/gdb/gdb/solib-svr4.h b/contrib/gdb/gdb/solib-svr4.h index 8611dff8e6e..d76c7f51459 100644 --- a/contrib/gdb/gdb/solib-svr4.h +++ b/contrib/gdb/gdb/solib-svr4.h @@ -1,5 +1,6 @@ /* Handle shared libraries for GDB, the GNU Debugger. - Copyright 2000 + + Copyright 2000, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -19,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +struct objfile; + /* Critical offsets and sizes which describe struct r_debug and struct link_map on SVR4-like targets. All offsets and sizes are in bytes unless otherwise specified. */ @@ -72,7 +75,16 @@ struct link_map_offsets extern void set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch, struct link_map_offsets *(*func) (void)); +/* This function is called by thread_db.c. Return the address of the + link map for the given objfile. */ +extern CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile); + /* legacy_svr4_fetch_link_map_offsets_hook is a pointer to a function which is used to fetch link map offsets. It will only be set by solib-legacy.c, if at all. */ extern struct link_map_offsets *(*legacy_svr4_fetch_link_map_offsets_hook)(void); + +/* Fetch (and possibly build) an appropriate `struct link_map_offsets' + for ILP32 and LP64 SVR4 systems. */ +extern struct link_map_offsets *svr4_ilp32_fetch_link_map_offsets (void); +extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void); diff --git a/contrib/gdb/gdb/solib.c b/contrib/gdb/gdb/solib.c index c47c438d99e..a98c3bdfed7 100644 --- a/contrib/gdb/gdb/solib.c +++ b/contrib/gdb/gdb/solib.c @@ -1,7 +1,7 @@ /* Handle shared libraries for GDB, the GNU Debugger. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -40,8 +40,9 @@ #include "gdbcmd.h" #include "completer.h" #include "filenames.h" /* for DOSish file names */ - +#include "exec.h" #include "solist.h" +#include "readline/readline.h" /* external data declarations */ @@ -56,7 +57,7 @@ static int solib_cleanup_queued = 0; /* make_run_cleanup called */ /* Local function prototypes */ -static void do_clear_solib (PTR); +static void do_clear_solib (void *); /* If non-zero, this is a prefix that will be added to the front of the name shared libraries with an absolute filename for loading. */ @@ -86,12 +87,19 @@ static char *solib_search_path = NULL; (or set of directories, as in LD_LIBRARY_PATH) to search for all shared libraries if not found in SOLIB_ABSOLUTE_PREFIX. - Search order: - * If path is absolute, look in SOLIB_ABSOLUTE_PREFIX. - * If path is absolute or relative, look for it literally (unmodified). + Search algorithm: + * If there is a solib_absolute_prefix and path is absolute: + * Search for solib_absolute_prefix/path. + * else + * Look for it literally (unmodified). * Look in SOLIB_SEARCH_PATH. - * Look in inferior's $PATH. - * Look in inferior's $LD_LIBRARY_PATH. + * If available, use target defined search function. + * If solib_absolute_prefix is NOT set, perform the following two searches: + * Look in inferior's $PATH. + * Look in inferior's $LD_LIBRARY_PATH. + * + * The last check avoids doing this search when targetting remote + * machines since solib_absolute_prefix will almost always be set. RETURNS @@ -146,7 +154,7 @@ solib_open (char *in_pathname, char **found_pathname) in_pathname++; } - /* If not found, next search the solib_search_path (if any). */ + /* If not found, search the solib_search_path (if any). */ if (found_file < 0 && solib_search_path != NULL) found_file = openp (solib_search_path, 1, in_pathname, O_RDONLY, 0, &temp_pathname); @@ -159,14 +167,19 @@ solib_open (char *in_pathname, char **found_pathname) 1, lbasename (in_pathname), O_RDONLY, 0, &temp_pathname); + /* If not found, try to use target supplied solib search method */ + if (found_file < 0 && TARGET_SO_FIND_AND_OPEN_SOLIB != NULL) + found_file = TARGET_SO_FIND_AND_OPEN_SOLIB + (in_pathname, O_RDONLY, &temp_pathname); + /* If not found, next search the inferior's $PATH environment variable. */ - if (found_file < 0 && solib_search_path != NULL) + if (found_file < 0 && solib_absolute_prefix == NULL) found_file = openp (get_in_environ (inferior_environ, "PATH"), 1, in_pathname, O_RDONLY, 0, &temp_pathname); /* If not found, next search the inferior's $LD_LIBRARY_PATH environment variable. */ - if (found_file < 0 && solib_search_path != NULL) + if (found_file < 0 && solib_absolute_prefix == NULL) found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"), 1, in_pathname, O_RDONLY, 0, &temp_pathname); @@ -206,7 +219,7 @@ solib_open (char *in_pathname, char **found_pathname) */ static int -solib_map_sections (PTR arg) +solib_map_sections (void *arg) { struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */ char *filename; @@ -237,7 +250,7 @@ solib_map_sections (PTR arg) /* Leave bfd open, core_xfer_memory and "info files" need it. */ so->abfd = abfd; - abfd->cacheable = 1; + bfd_set_cacheable (abfd, 1); /* copy full path name into so_name, so that later symbol_file_add can find it */ @@ -262,7 +275,7 @@ solib_map_sections (PTR arg) object's file by the base address to which the object was actually mapped. */ TARGET_SO_RELOCATE_SECTION_ADDRESSES (so, p); - if (STREQ (p->the_bfd_section->name, ".text")) + if (strcmp (p->the_bfd_section->name, ".text") == 0) { so->textsection = p; } @@ -323,9 +336,9 @@ free_so (struct so_list *so) /* A small stub to get us past the arg-passing pinhole of catch_errors. */ static int -symbol_add_stub (PTR arg) +symbol_add_stub (void *arg) { - register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ + struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ struct section_addr_info *sap; /* Have we already loaded this shared object? */ @@ -375,7 +388,7 @@ symbol_add_stub (PTR arg) the section table. But we only use this for core files and processes we've just attached to, so that's okay. */ -void +static void update_solib_list (int from_tty, struct target_ops *target) { struct so_list *inferior = TARGET_SO_CURRENT_SOS (); @@ -386,7 +399,7 @@ update_solib_list (int from_tty, struct target_ops *target) symbols now! */ if (attach_flag && symfile_objfile == NULL) - catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, (PTR) &from_tty, + catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, &from_tty, "Error reading attached process's symbol file.\n", RETURN_MASK_ALL); @@ -614,7 +627,7 @@ solib_add (char *pattern, int from_tty, struct target_ops *target, int readsyms) static void info_sharedlibrary_command (char *ignore, int from_tty) { - register struct so_list *so = NULL; /* link map state variable */ + struct so_list *so = NULL; /* link map state variable */ int header_done = 0; int addr_width; char *addr_fmt; @@ -652,13 +665,13 @@ info_sharedlibrary_command (char *ignore, int from_tty) printf_unfiltered ("%-*s", addr_width, so->textsection != NULL - ? longest_local_hex_string_custom ( + ? local_hex_string_custom ( (LONGEST) so->textsection->addr, addr_fmt) : ""); printf_unfiltered ("%-*s", addr_width, so->textsection != NULL - ? longest_local_hex_string_custom ( + ? local_hex_string_custom ( (LONGEST) so->textsection->endaddr, addr_fmt) : ""); @@ -696,7 +709,7 @@ info_sharedlibrary_command (char *ignore, int from_tty) char * solib_address (CORE_ADDR address) { - register struct so_list *so = 0; /* link map state variable */ + struct so_list *so = 0; /* link map state variable */ for (so = so_list_head; so; so = so->next) { @@ -754,7 +767,7 @@ clear_solib (void) } static void -do_clear_solib (PTR dummy) +do_clear_solib (void *dummy) { solib_cleanup_queued = 0; clear_solib (); @@ -843,6 +856,15 @@ no_shared_libraries (char *ignored, int from_tty) do_clear_solib (NULL); } +static void +reload_shared_libraries (char *ignored, int from_tty) +{ + no_shared_libraries (NULL, from_tty); + solib_add (NULL, from_tty, NULL, auto_solib_add); +} + +extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */ + void _initialize_solib (void) { @@ -872,7 +894,12 @@ inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", For other (relative) files, you can add values using `set solib-search-path'.", &setlist); add_show_from_set (c, &showlist); - c->completer = filename_completer; + set_cmd_cfunc (c, reload_shared_libraries); + set_cmd_completer (c, filename_completer); + + /* Set the default value of "solib-absolute-prefix" from the sysroot, if + one is set. */ + solib_absolute_prefix = xstrdup (gdb_sysroot); c = add_set_cmd ("solib-search-path", class_support, var_string, (char *) &solib_search_path, @@ -880,5 +907,6 @@ For other (relative) files, you can add values using `set solib-search-path'.", This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.", &setlist); add_show_from_set (c, &showlist); - c->completer = filename_completer; + set_cmd_cfunc (c, reload_shared_libraries); + set_cmd_completer (c, filename_completer); } diff --git a/contrib/gdb/gdb/solib.h b/contrib/gdb/gdb/solib.h index 76f287b2269..cb4ba2d382a 100644 --- a/contrib/gdb/gdb/solib.h +++ b/contrib/gdb/gdb/solib.h @@ -1,5 +1,5 @@ /* Shared library declarations for GDB, the GNU Debugger. - Copyright 1992, 1993, 1995, 1998, 1999, 2000, 2001 + Copyright 1992, 1993, 1995, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -19,6 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef SOLIB_H +#define SOLIB_H + /* Forward decl's for prototypes */ struct target_ops; @@ -54,100 +57,6 @@ extern void solib_add (char *, int, struct target_ops *, int); extern void solib_create_inferior_hook (void); /* solib.c */ -/* This function is called by the "catch load" command. It allows - the debugger to be notified by the dynamic linker when a specified - library file (or any library file, if filename is NULL) is loaded. - - Presently, this functionality is not implemented. - */ -#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \ - error("catch of library loads/unloads not yet implemented on this platform") - -/* This function is called by the "catch unload" command. It allows - the debugger to be notified by the dynamic linker when a specified - library file (or any library file, if filename is NULL) is unloaded. - - Presently, this functionality is not implemented. - */ -#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \ - error("catch of library loads/unloads not yet implemented on this platform") - -/* This function returns TRUE if the dynamic linker has just reported - a load of a library. - - This function must be used only when the inferior has stopped in - the dynamic linker hook, or undefined results are guaranteed. - - Presently, this functionality is not implemented. - */ - -/* - #define SOLIB_HAVE_LOAD_EVENT(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_HAVE_LOAD_EVENT(pid) \ -(0) - -/* This function returns a pointer to the string representation of the - pathname of the dynamically-linked library that has just been loaded. - - This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE, - or undefined results are guaranteed. - - This string's contents are only valid immediately after the inferior - has stopped in the dynamic linker hook, and becomes invalid as soon - as the inferior is continued. Clients should make a copy of this - string if they wish to continue the inferior and then access the string. - - Presently, this functionality is not implemented. - */ - -/* - #define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ -(0) - -/* This function returns TRUE if the dynamic linker has just reported - an unload of a library. - - This function must be used only when the inferior has stopped in - the dynamic linker hook, or undefined results are guaranteed. - - Presently, this functionality is not implemented. - */ -/* - #define SOLIB_HAVE_UNLOAD_EVENT(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_HAVE_UNLOAD_EVENT(pid) \ -(0) - -/* This function returns a pointer to the string representation of the - pathname of the dynamically-linked library that has just been unloaded. - - This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE, - or undefined results are guaranteed. - - This string's contents are only valid immediately after the inferior - has stopped in the dynamic linker hook, and becomes invalid as soon - as the inferior is continued. Clients should make a copy of this - string if they wish to continue the inferior and then access the string. - - Presently, this functionality is not implemented. - */ -/* - #define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ - error("catch of library loads/unloads not yet implemented on this platform") - */ - -#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ -(0) - /* This function returns TRUE if pc is the address of an instruction that lies within the dynamic linker (such as the event hook, or the dld itself). @@ -197,3 +106,5 @@ extern int in_solib_dynsym_resolve_code (CORE_ADDR); /* solib.c */ /* Discard symbols that were auto-loaded from shared libraries. */ extern void no_shared_libraries (char *ignored, int from_tty); + +#endif /* SOLIB_H */ diff --git a/contrib/gdb/gdb/solist.h b/contrib/gdb/gdb/solist.h index dd1100c31cf..8e5c4321855 100644 --- a/contrib/gdb/gdb/solist.h +++ b/contrib/gdb/gdb/solist.h @@ -99,6 +99,12 @@ struct target_so_ops /* Determine if PC lies in the dynamic symbol resolution code of the run time loader */ int (*in_dynsym_resolve_code) (CORE_ADDR pc); + + /* Extra hook for finding and opening a solib. Convenience function + for remote debuggers finding host libs */ + int (*find_and_open_solib) (char *soname, + unsigned o_flags, char **temp_pathname); + }; void free_so (struct so_list *so); @@ -122,5 +128,7 @@ extern struct target_so_ops *current_target_so_ops; (current_target_so_ops->open_symbol_file_object) #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \ (current_target_so_ops->in_dynsym_resolve_code) +#define TARGET_SO_FIND_AND_OPEN_SOLIB \ + (current_target_so_ops->find_and_open_solib) #endif diff --git a/contrib/gdb/gdb/somread.c b/contrib/gdb/gdb/somread.c new file mode 100644 index 00000000000..4ffa4c1c9e4 --- /dev/null +++ b/contrib/gdb/gdb/somread.c @@ -0,0 +1,736 @@ +/* Read HP PA/Risc object files for GDB. + Copyright 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, + 2004 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "bfd.h" +#include +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" +#include "buildsym.h" +#include "stabsread.h" +#include "gdb-stabs.h" +#include "complaints.h" +#include "gdb_string.h" +#include "demangle.h" +#include "som.h" +#include "libhppa.h" + +/* Various things we might complain about... */ + +static int init_import_symbols (struct objfile *objfile); + +static void som_symfile_init (struct objfile *); + +static void som_new_init (struct objfile *); + +static void som_symfile_read (struct objfile *, int); + +static void som_symfile_finish (struct objfile *); + +static void som_symtab_read (bfd *, struct objfile *, + struct section_offsets *); + +static void som_symfile_offsets (struct objfile *, struct section_addr_info *); + +/* FIXME: These should really be in a common header somewhere */ + +extern void hpread_build_psymtabs (struct objfile *, int); + +extern void hpread_symfile_finish (struct objfile *); + +extern void hpread_symfile_init (struct objfile *); + +extern void do_pxdb (bfd *); + +/* + + LOCAL FUNCTION + + som_symtab_read -- read the symbol table of a SOM file + + SYNOPSIS + + void som_symtab_read (bfd *abfd, struct objfile *objfile, + struct section_offsets *section_offsets) + + DESCRIPTION + + Given an open bfd, a base address to relocate symbols to, and a + flag that specifies whether or not this bfd is for an executable + or not (may be shared library for example), add all the global + function and data symbols to the minimal symbol table. + */ + +static void +som_symtab_read (bfd *abfd, struct objfile *objfile, + struct section_offsets *section_offsets) +{ + unsigned int number_of_symbols; + int val, dynamic; + char *stringtab; + asection *shlib_info; + struct symbol_dictionary_record *buf, *bufp, *endbufp; + char *symname; + CONST int symsize = sizeof (struct symbol_dictionary_record); + CORE_ADDR text_offset, data_offset; + + + text_offset = ANOFFSET (section_offsets, 0); + data_offset = ANOFFSET (section_offsets, 1); + + number_of_symbols = bfd_get_symcount (abfd); + + /* FIXME (alloca): could be quite large. */ + buf = alloca (symsize * number_of_symbols); + bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET); + val = bfd_bread (buf, symsize * number_of_symbols, abfd); + if (val != symsize * number_of_symbols) + error ("Couldn't read symbol dictionary!"); + + /* FIXME (alloca): could be quite large. */ + stringtab = alloca (obj_som_stringtab_size (abfd)); + bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET); + val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd); + if (val != obj_som_stringtab_size (abfd)) + error ("Can't read in HP string table."); + + /* We need to determine if objfile is a dynamic executable (so we + can do the right thing for ST_ENTRY vs ST_CODE symbols). + + There's nothing in the header which easily allows us to do + this. + + This code used to rely upon the existence of a $SHLIB_INFO$ + section to make this determination. HP claims that it is + more accurate to check for a nonzero text offset, but they + have not provided any information about why that test is + more accurate. */ + dynamic = (text_offset != 0); + + endbufp = buf + number_of_symbols; + for (bufp = buf; bufp < endbufp; ++bufp) + { + enum minimal_symbol_type ms_type; + + QUIT; + + switch (bufp->symbol_scope) + { + case SS_UNIVERSAL: + case SS_EXTERNAL: + switch (bufp->symbol_type) + { + case ST_SYM_EXT: + case ST_ARG_EXT: + continue; + + case ST_CODE: + case ST_PRI_PROG: + case ST_SEC_PROG: + case ST_MILLICODE: + symname = bufp->name.n_strx + stringtab; + ms_type = mst_text; + bufp->symbol_value += text_offset; + bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); + break; + + case ST_ENTRY: + symname = bufp->name.n_strx + stringtab; + /* For a dynamic executable, ST_ENTRY symbols are + the stubs, while the ST_CODE symbol is the real + function. */ + if (dynamic) + ms_type = mst_solib_trampoline; + else + ms_type = mst_text; + bufp->symbol_value += text_offset; + bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); + break; + + case ST_STUB: + symname = bufp->name.n_strx + stringtab; + ms_type = mst_solib_trampoline; + bufp->symbol_value += text_offset; + bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); + break; + + case ST_DATA: + symname = bufp->name.n_strx + stringtab; + bufp->symbol_value += data_offset; + ms_type = mst_data; + break; + default: + continue; + } + break; + +#if 0 + /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */ + case SS_GLOBAL: +#endif + case SS_LOCAL: + switch (bufp->symbol_type) + { + case ST_SYM_EXT: + case ST_ARG_EXT: + continue; + + case ST_CODE: + symname = bufp->name.n_strx + stringtab; + ms_type = mst_file_text; + bufp->symbol_value += text_offset; + bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); + + check_strange_names: + /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local + label prefixes for stabs, constant data, etc. So we need + only filter out L$ symbols which are left in due to + limitations in how GAS generates SOM relocations. + + When linking in the HPUX C-library the HP linker has + the nasty habit of placing section symbols from the literal + subspaces in the middle of the program's text. Filter + those out as best we can. Check for first and last character + being '$'. + + And finally, the newer HP compilers emit crud like $PIC_foo$N + in some circumstance (PIC code I guess). It's also claimed + that they emit D$ symbols too. What stupidity. */ + if ((symname[0] == 'L' && symname[1] == '$') + || (symname[0] == '$' && symname[strlen (symname) - 1] == '$') + || (symname[0] == 'D' && symname[1] == '$') + || (strncmp (symname, "$PIC", 4) == 0)) + continue; + break; + + case ST_PRI_PROG: + case ST_SEC_PROG: + case ST_MILLICODE: + symname = bufp->name.n_strx + stringtab; + ms_type = mst_file_text; + bufp->symbol_value += text_offset; + bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); + break; + + case ST_ENTRY: + symname = bufp->name.n_strx + stringtab; + /* SS_LOCAL symbols in a shared library do not have + export stubs, so we do not have to worry about + using mst_file_text vs mst_solib_trampoline here like + we do for SS_UNIVERSAL and SS_EXTERNAL symbols above. */ + ms_type = mst_file_text; + bufp->symbol_value += text_offset; + bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); + break; + + case ST_STUB: + symname = bufp->name.n_strx + stringtab; + ms_type = mst_solib_trampoline; + bufp->symbol_value += text_offset; + bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); + break; + + + case ST_DATA: + symname = bufp->name.n_strx + stringtab; + bufp->symbol_value += data_offset; + ms_type = mst_file_data; + goto check_strange_names; + + default: + continue; + } + break; + + /* This can happen for common symbols when -E is passed to the + final link. No idea _why_ that would make the linker force + common symbols to have an SS_UNSAT scope, but it does. + + This also happens for weak symbols, but their type is + ST_DATA. */ + case SS_UNSAT: + switch (bufp->symbol_type) + { + case ST_STORAGE: + case ST_DATA: + symname = bufp->name.n_strx + stringtab; + bufp->symbol_value += data_offset; + ms_type = mst_data; + break; + + default: + continue; + } + break; + + default: + continue; + } + + if (bufp->name.n_strx > obj_som_stringtab_size (abfd)) + error ("Invalid symbol data; bad HP string table offset: %d", + bufp->name.n_strx); + + prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type, + objfile); + } +} + +/* Scan and build partial symbols for a symbol file. + We have been initialized by a call to som_symfile_init, which + currently does nothing. + + SECTION_OFFSETS is a set of offsets to apply to relocate the symbols + in each section. This is ignored, as it isn't needed for SOM. + + MAINLINE is true if we are reading the main symbol + table (as opposed to a shared lib or dynamically loaded file). + + This function only does the minimum work necessary for letting the + user "name" things symbolically; it does not read the entire symtab. + Instead, it reads the external and static symbols and puts them in partial + symbol tables. When more extensive information is requested of a + file, the corresponding partial symbol table is mutated into a full + fledged symbol table by going back and reading the symbols + for real. + + We look for sections with specific names, to tell us what debug + format to look for: FIXME!!! + + somstab_build_psymtabs() handles STABS symbols. + + Note that SOM files have a "minimal" symbol table, which is vaguely + reminiscent of a COFF symbol table, but has only the minimal information + necessary for linking. We process this also, and use the information to + build gdb's minimal symbol table. This gives us some minimal debugging + capability even for files compiled without -g. */ + +static void +som_symfile_read (struct objfile *objfile, int mainline) +{ + bfd *abfd = objfile->obfd; + struct cleanup *back_to; + + do_pxdb (symfile_bfd_open (objfile->name)); + + init_minimal_symbol_collection (); + back_to = make_cleanup_discard_minimal_symbols (); + + /* Read in the import list and the export list. Currently + the export list isn't used; the import list is used in + hp-symtab-read.c to handle static vars declared in other + shared libraries. */ + init_import_symbols (objfile); +#if 0 /* Export symbols not used today 1997-08-05 */ + init_export_symbols (objfile); +#else + objfile->export_list = NULL; + objfile->export_list_size = 0; +#endif + + /* Process the normal SOM symbol table first. + This reads in the DNTT and string table, but doesn't + actually scan the DNTT. It does scan the linker symbol + table and thus build up a "minimal symbol table". */ + + som_symtab_read (abfd, objfile, objfile->section_offsets); + + /* Install any minimal symbols that have been collected as the current + minimal symbols for this objfile. + Further symbol-reading is done incrementally, file-by-file, + in a step known as "psymtab-to-symtab" expansion. hp-symtab-read.c + contains the code to do the actual DNTT scanning and symtab building. */ + install_minimal_symbols (objfile); + do_cleanups (back_to); + + /* Now read information from the stabs debug sections. + This is a no-op for SOM. + Perhaps it is intended for some kind of mixed STABS/SOM + situation? */ + stabsect_build_psymtabs (objfile, mainline, + "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$"); + + /* Now read the native debug information. + This builds the psymtab. This used to be done via a scan of + the DNTT, but is now done via the PXDB-built quick-lookup tables + together with a scan of the GNTT. See hp-psymtab-read.c. */ + hpread_build_psymtabs (objfile, mainline); + + /* Force hppa-tdep.c to re-read the unwind descriptors. */ + objfile->obj_private = NULL; +} + +/* Initialize anything that needs initializing when a completely new symbol + file is specified (not just adding some symbols from another file, e.g. a + shared library). + + We reinitialize buildsym, since we may be reading stabs from a SOM file. */ + +static void +som_new_init (struct objfile *ignore) +{ + stabsread_new_init (); + buildsym_new_init (); +} + +/* Perform any local cleanups required when we are done with a particular + objfile. I.E, we are in the process of discarding all symbol information + for an objfile, freeing up all memory held for it, and unlinking the + objfile struct from the global list of known objfiles. */ + +static void +som_symfile_finish (struct objfile *objfile) +{ + if (objfile->sym_stab_info != NULL) + { + xmfree (objfile->md, objfile->sym_stab_info); + } + hpread_symfile_finish (objfile); +} + +/* SOM specific initialization routine for reading symbols. */ + +static void +som_symfile_init (struct objfile *objfile) +{ + /* SOM objects may be reordered, so set OBJF_REORDERED. If we + find this causes a significant slowdown in gdb then we could + set it in the debug symbol readers only when necessary. */ + objfile->flags |= OBJF_REORDERED; + hpread_symfile_init (objfile); +} + +/* SOM specific parsing routine for section offsets. + + Plain and simple for now. */ + +static void +som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs) +{ + int i; + CORE_ADDR text_addr; + + objfile->num_sections = bfd_count_sections (objfile->obfd); + objfile->section_offsets = (struct section_offsets *) + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + + /* FIXME: ezannoni 2000-04-20 The section names in SOM are not + .text, .data, etc, but $TEXT$, $DATA$,... We should initialize + SET_OFF_* from bfd. (See default_symfile_offsets()). But I don't + know the correspondence between SOM sections and GDB's idea of + section names. So for now we default to what is was before these + changes.*/ + objfile->sect_index_text = 0; + objfile->sect_index_data = 1; + objfile->sect_index_bss = 2; + objfile->sect_index_rodata = 3; + + /* First see if we're a shared library. If so, get the section + offsets from the library, else get them from addrs. */ + if (!som_solib_section_offsets (objfile, objfile->section_offsets)) + { + /* Note: Here is OK to compare with ".text" because this is the + name that gdb itself gives to that section, not the SOM + name. */ + for (i = 0; i < objfile->num_sections && addrs->other[i].name; i++) + if (strcmp (addrs->other[i].name, ".text") == 0) + break; + text_addr = addrs->other[i].addr; + + for (i = 0; i < objfile->num_sections; i++) + (objfile->section_offsets)->offsets[i] = text_addr; + } +} + +/* Read in and initialize the SOM import list which is present + for all executables and shared libraries. The import list + consists of the symbols that are referenced in OBJFILE but + not defined there. (Variables that are imported are dealt + with as "loc_indirect" vars.) + Return value = number of import symbols read in. */ +static int +init_import_symbols (struct objfile *objfile) +{ + unsigned int import_list; + unsigned int import_list_size; + unsigned int string_table; + unsigned int string_table_size; + char *string_buffer; + int i; + int j; + int k; + asection *text_section; /* section handle */ + unsigned int dl_header[12]; /* SOM executable header */ + + /* A struct for an entry in the SOM import list */ + typedef struct + { + int name; /* index into the string table */ + short dont_care1; /* we don't use this */ + unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */ + unsigned int reserved2:8; /* not used */ + } + SomImportEntry; + + /* We read 100 entries in at a time from the disk file. */ +#define SOM_READ_IMPORTS_NUM 100 +#define SOM_READ_IMPORTS_CHUNK_SIZE (sizeof (SomImportEntry) * SOM_READ_IMPORTS_NUM) + SomImportEntry buffer[SOM_READ_IMPORTS_NUM]; + + /* Initialize in case we error out */ + objfile->import_list = NULL; + objfile->import_list_size = 0; + + /* It doesn't work, for some reason, to read in space $TEXT$; + the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */ + text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$"); + if (!text_section) + return 0; + /* Get the SOM executable header */ + bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int)); + + /* Check header version number for 10.x HP-UX */ + /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912. + FIXME: Change for future HP-UX releases and mods to the SOM executable format */ + if (dl_header[0] != 93092112) + return 0; + + import_list = dl_header[4]; + import_list_size = dl_header[5]; + if (!import_list_size) + return 0; + string_table = dl_header[10]; + string_table_size = dl_header[11]; + if (!string_table_size) + return 0; + + /* Suck in SOM string table */ + string_buffer = (char *) xmalloc (string_table_size); + bfd_get_section_contents (objfile->obfd, text_section, string_buffer, + string_table, string_table_size); + + /* Allocate import list in the psymbol obstack; this has nothing + to do with psymbols, just a matter of convenience. We want the + import list to be freed when the objfile is deallocated */ + objfile->import_list + = (ImportEntry *) obstack_alloc (&objfile->objfile_obstack, + import_list_size * sizeof (ImportEntry)); + + /* Read in the import entries, a bunch at a time */ + for (j = 0, k = 0; + j < (import_list_size / SOM_READ_IMPORTS_NUM); + j++) + { + bfd_get_section_contents (objfile->obfd, text_section, buffer, + import_list + j * SOM_READ_IMPORTS_CHUNK_SIZE, + SOM_READ_IMPORTS_CHUNK_SIZE); + for (i = 0; i < SOM_READ_IMPORTS_NUM; i++, k++) + { + if (buffer[i].type != (unsigned char) 0) + { + objfile->import_list[k] + = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1); + strcpy (objfile->import_list[k], string_buffer + buffer[i].name); + /* Some day we might want to record the type and other information too */ + } + else /* null type */ + objfile->import_list[k] = NULL; + + } + } + + /* Get the leftovers */ + if (k < import_list_size) + bfd_get_section_contents (objfile->obfd, text_section, buffer, + import_list + k * sizeof (SomImportEntry), + (import_list_size - k) * sizeof (SomImportEntry)); + for (i = 0; k < import_list_size; i++, k++) + { + if (buffer[i].type != (unsigned char) 0) + { + objfile->import_list[k] + = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1); + strcpy (objfile->import_list[k], string_buffer + buffer[i].name); + /* Some day we might want to record the type and other information too */ + } + else + objfile->import_list[k] = NULL; + } + + objfile->import_list_size = import_list_size; + xfree (string_buffer); + return import_list_size; +} + +/* Read in and initialize the SOM export list which is present + for all executables and shared libraries. The import list + consists of the symbols that are referenced in OBJFILE but + not defined there. (Variables that are imported are dealt + with as "loc_indirect" vars.) + Return value = number of import symbols read in. */ +int +init_export_symbols (struct objfile *objfile) +{ + unsigned int export_list; + unsigned int export_list_size; + unsigned int string_table; + unsigned int string_table_size; + char *string_buffer; + int i; + int j; + int k; + asection *text_section; /* section handle */ + unsigned int dl_header[12]; /* SOM executable header */ + + /* A struct for an entry in the SOM export list */ + typedef struct + { + int next; /* for hash table use -- we don't use this */ + int name; /* index into string table */ + int value; /* offset or plabel */ + int dont_care1; /* not used */ + unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */ + char dont_care2; /* not used */ + short dont_care3; /* not used */ + } + SomExportEntry; + + /* We read 100 entries in at a time from the disk file. */ +#define SOM_READ_EXPORTS_NUM 100 +#define SOM_READ_EXPORTS_CHUNK_SIZE (sizeof (SomExportEntry) * SOM_READ_EXPORTS_NUM) + SomExportEntry buffer[SOM_READ_EXPORTS_NUM]; + + /* Initialize in case we error out */ + objfile->export_list = NULL; + objfile->export_list_size = 0; + + /* It doesn't work, for some reason, to read in space $TEXT$; + the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */ + text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$"); + if (!text_section) + return 0; + /* Get the SOM executable header */ + bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int)); + + /* Check header version number for 10.x HP-UX */ + /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912. + FIXME: Change for future HP-UX releases and mods to the SOM executable format */ + if (dl_header[0] != 93092112) + return 0; + + export_list = dl_header[8]; + export_list_size = dl_header[9]; + if (!export_list_size) + return 0; + string_table = dl_header[10]; + string_table_size = dl_header[11]; + if (!string_table_size) + return 0; + + /* Suck in SOM string table */ + string_buffer = (char *) xmalloc (string_table_size); + bfd_get_section_contents (objfile->obfd, text_section, string_buffer, + string_table, string_table_size); + + /* Allocate export list in the psymbol obstack; this has nothing + to do with psymbols, just a matter of convenience. We want the + export list to be freed when the objfile is deallocated */ + objfile->export_list + = (ExportEntry *) obstack_alloc (&objfile->objfile_obstack, + export_list_size * sizeof (ExportEntry)); + + /* Read in the export entries, a bunch at a time */ + for (j = 0, k = 0; + j < (export_list_size / SOM_READ_EXPORTS_NUM); + j++) + { + bfd_get_section_contents (objfile->obfd, text_section, buffer, + export_list + j * SOM_READ_EXPORTS_CHUNK_SIZE, + SOM_READ_EXPORTS_CHUNK_SIZE); + for (i = 0; i < SOM_READ_EXPORTS_NUM; i++, k++) + { + if (buffer[i].type != (unsigned char) 0) + { + objfile->export_list[k].name + = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1); + strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name); + objfile->export_list[k].address = buffer[i].value; + /* Some day we might want to record the type and other information too */ + } + else + /* null type */ + { + objfile->export_list[k].name = NULL; + objfile->export_list[k].address = 0; + } + } + } + + /* Get the leftovers */ + if (k < export_list_size) + bfd_get_section_contents (objfile->obfd, text_section, buffer, + export_list + k * sizeof (SomExportEntry), + (export_list_size - k) * sizeof (SomExportEntry)); + for (i = 0; k < export_list_size; i++, k++) + { + if (buffer[i].type != (unsigned char) 0) + { + objfile->export_list[k].name + = (char *) obstack_alloc (&objfile->objfile_obstack, strlen (string_buffer + buffer[i].name) + 1); + strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name); + /* Some day we might want to record the type and other information too */ + objfile->export_list[k].address = buffer[i].value; + } + else + { + objfile->export_list[k].name = NULL; + objfile->export_list[k].address = 0; + } + } + + objfile->export_list_size = export_list_size; + xfree (string_buffer); + return export_list_size; +} + + + +/* Register that we are able to handle SOM object file formats. */ + +static struct sym_fns som_sym_fns = +{ + bfd_target_som_flavour, + som_new_init, /* sym_new_init: init anything gbl to entire symtab */ + som_symfile_init, /* sym_init: read initial info, setup for sym_read() */ + som_symfile_read, /* sym_read: read a symbol file into symtab */ + som_symfile_finish, /* sym_finish: finished with file, cleanup */ + som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */ + NULL /* next: pointer to next struct sym_fns */ +}; + +void +_initialize_somread (void) +{ + add_symtab_fns (&som_sym_fns); +} diff --git a/contrib/gdb/gdb/somsolib.c b/contrib/gdb/gdb/somsolib.c new file mode 100644 index 00000000000..d8c971b3540 --- /dev/null +++ b/contrib/gdb/gdb/somsolib.c @@ -0,0 +1,1624 @@ +/* Handle HP SOM shared libraries for GDB, the GNU Debugger. + + Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, + 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Written by the Center for Software Science at the Univerity of Utah + and by Cygnus Support. */ + + +#include "defs.h" + +#include "frame.h" +#include "bfd.h" +#include "som.h" +#include "libhppa.h" +#include "gdbcore.h" +#include "symtab.h" +#include "breakpoint.h" +#include "symfile.h" +#include "objfiles.h" +#include "inferior.h" +#include "gdb-stabs.h" +#include "gdb_stat.h" +#include "gdbcmd.h" +#include "language.h" +#include "regcache.h" +#include "gdb_assert.h" +#include "exec.h" + +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* Uncomment this to turn on some debugging output. + */ + +/* #define SOLIB_DEBUG + */ + +/* This lives in hppa-tdep.c. */ +extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc); + +/* These ought to be defined in some public interface, but aren't. They + define the meaning of the various bits in the distinguished __dld_flags + variable that is declared in every debuggable a.out on HP-UX, and that + is shared between the debugger and the dynamic linker. + */ +#define DLD_FLAGS_MAPPRIVATE 0x1 +#define DLD_FLAGS_HOOKVALID 0x2 +#define DLD_FLAGS_LISTVALID 0x4 +#define DLD_FLAGS_BOR_ENABLE 0x8 + +/* TODO: + + * Support for hpux8 dynamic linker. */ + +/* The basic structure which describes a dynamically loaded object. This + data structure is private to the dynamic linker and isn't found in + any HPUX include file. */ + +struct som_solib_mapped_entry + { + /* The name of the library. */ + char *name; + + /* Version of this structure (it is expected to change again in hpux10). */ + unsigned char struct_version; + + /* Binding mode for this library. */ + unsigned char bind_mode; + + /* Version of this library. */ + short library_version; + + /* Start of text address, + * link-time text location (length of text area), + * end of text address. */ + CORE_ADDR text_addr; + CORE_ADDR text_link_addr; + CORE_ADDR text_end; + + /* Start of data, start of bss and end of data. */ + CORE_ADDR data_start; + CORE_ADDR bss_start; + CORE_ADDR data_end; + + /* Value of linkage pointer (%r19). */ + CORE_ADDR got_value; + + /* Next entry. */ + struct som_solib_mapped_entry *next; + + /* There are other fields, but I don't have information as to what is + contained in them. */ + + /* For versions from HPUX-10.30 and up */ + + /* Address in target of offset from thread-local register of + * start of this thread's data. I.e., the first thread-local + * variable in this shared library starts at *(tsd_start_addr) + * from that area pointed to by cr27 (mpsfu_hi). + * + * We do the indirection as soon as we read it, so from then + * on it's the offset itself. + */ + CORE_ADDR tsd_start_addr; + + /* Following this are longwords holding: + + * ?, ?, ?, ptr to -1, ptr to-1, ptr to lib name (leaf name), + * ptr to __data_start, ptr to __data_end + */ + + + }; + +/* A structure to keep track of all the known shared objects. */ +struct so_list + { + struct som_solib_mapped_entry som_solib; + struct objfile *objfile; + bfd *abfd; + struct section_table *sections; + struct section_table *sections_end; +/* elz: added this field to store the address in target space (in the + library) of the library descriptor (handle) which we read into + som_solib_mapped_entry structure */ + CORE_ADDR solib_addr; + struct so_list *next; + + }; + +static struct so_list *so_list_head; + + +/* This is the cumulative size in bytes of the symbol tables of all + shared objects on the so_list_head list. (When we say size, here + we mean of the information before it is brought into memory and + potentially expanded by GDB.) When adding a new shlib, this value + is compared against the threshold size, held by auto_solib_limit + (in megabytes). If adding symbols for the new shlib would cause + the total size to exceed the threshold, then the new shlib's + symbols are not loaded. */ +static LONGEST som_solib_total_st_size; + +/* When the threshold is reached for any shlib, we refuse to add + symbols for subsequent shlibs, even if those shlibs' symbols would + be small enough to fit under the threshold. (Although this may + result in one, early large shlib preventing the loading of later, + smalller shlibs' symbols, it allows us to issue one informational + message. The alternative, to issue a message for each shlib whose + symbols aren't loaded, could be a big annoyance where the threshold + is exceeded due to a very large number of shlibs.) + */ +static int som_solib_st_size_threshold_exceeded; + +/* These addresses should be filled in by som_solib_create_inferior_hook. + They are also used elsewhere in this module. + */ +typedef struct + { + CORE_ADDR address; + struct unwind_table_entry *unwind; + } +addr_and_unwind_t; + +/* When adding fields, be sure to clear them in _initialize_som_solib. */ +static struct + { + int is_valid; + addr_and_unwind_t hook; + addr_and_unwind_t hook_stub; + addr_and_unwind_t load; + addr_and_unwind_t load_stub; + addr_and_unwind_t unload; + addr_and_unwind_t unload2; + addr_and_unwind_t unload_stub; + } +dld_cache; + + + +static void som_sharedlibrary_info_command (char *, int); + +static void som_solib_sharedlibrary_command (char *, int); + +static LONGEST +som_solib_sizeof_symbol_table (char *filename) +{ + bfd *abfd; + int desc; + char *absolute_name; + LONGEST st_size = (LONGEST) 0; + asection *sect; + + /* We believe that filename was handed to us by the dynamic linker, and + is therefore always an absolute path. + */ + desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, 0, &absolute_name); + if (desc < 0) + { + perror_with_name (filename); + } + filename = absolute_name; + + abfd = bfd_fdopenr (filename, gnutarget, desc); + if (!abfd) + { + close (desc); + make_cleanup (xfree, filename); + error ("\"%s\": can't open to read symbols: %s.", filename, + bfd_errmsg (bfd_get_error ())); + } + + if (!bfd_check_format (abfd, bfd_object)) /* Reads in section info */ + { + bfd_close (abfd); /* This also closes desc */ + make_cleanup (xfree, filename); + error ("\"%s\": can't read symbols: %s.", filename, + bfd_errmsg (bfd_get_error ())); + } + + /* Sum the sizes of the various sections that compose debug info. */ + + /* This contains non-DOC information. */ + sect = bfd_get_section_by_name (abfd, "$DEBUG$"); + if (sect) + st_size += (LONGEST) bfd_section_size (abfd, sect); + + /* This contains DOC information. */ + sect = bfd_get_section_by_name (abfd, "$PINFO$"); + if (sect) + st_size += (LONGEST) bfd_section_size (abfd, sect); + + bfd_close (abfd); /* This also closes desc */ + xfree (filename); + + /* Unfortunately, just summing the sizes of various debug info + sections isn't a very accurate measurement of how much heap + space the debugger will need to hold them. It also doesn't + account for space needed by linker (aka "minimal") symbols. + + Anecdotal evidence suggests that just summing the sizes of + debug-info-related sections understates the heap space needed + to represent it internally by about an order of magnitude. + + Since it's not exactly brain surgery we're doing here, rather + than attempt to more accurately measure the size of a shlib's + symbol table in GDB's heap, we'll just apply a 10x fudge- + factor to the debug info sections' size-sum. No, this doesn't + account for minimal symbols in non-debuggable shlibs. But it + all roughly washes out in the end. + */ + return st_size * (LONGEST) 10; +} + + +static void +som_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty, + CORE_ADDR text_addr) +{ + obj_private_data_t *obj_private; + struct obj_section *s; + + so->objfile = symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED); + so->abfd = so->objfile->obfd; + + /* syms_from_objfile has bizarre section offset code, + so I do my own right here. */ + for (s = so->objfile->sections; s < so->objfile->sections_end; s++) + { + flagword aflag = bfd_get_section_flags(so->abfd, s->the_bfd_section); + if (aflag & SEC_CODE) + { + s->addr += so->som_solib.text_addr - so->som_solib.text_link_addr; + s->endaddr += so->som_solib.text_addr - so->som_solib.text_link_addr; + } + else if (aflag & SEC_DATA) + { + s->addr += so->som_solib.data_start; + s->endaddr += so->som_solib.data_start; + } + else + ; + } + + /* Mark this as a shared library and save private data. + */ + so->objfile->flags |= OBJF_SHARED; + + if (so->objfile->obj_private == NULL) + { + obj_private = (obj_private_data_t *) + obstack_alloc (&so->objfile->objfile_obstack, + sizeof (obj_private_data_t)); + obj_private->unwind_info = NULL; + obj_private->so_info = NULL; + so->objfile->obj_private = obj_private; + } + + obj_private = (obj_private_data_t *) so->objfile->obj_private; + obj_private->so_info = so; + + if (!bfd_check_format (so->abfd, bfd_object)) + { + error ("\"%s\": not in executable format: %s.", + name, bfd_errmsg (bfd_get_error ())); + } +} + + +static void +som_solib_load_symbols (struct so_list *so, char *name, int from_tty, + CORE_ADDR text_addr, struct target_ops *target) +{ + struct section_table *p; + int status; + char buf[4]; + CORE_ADDR presumed_data_start; + +#ifdef SOLIB_DEBUG + printf ("--Adding symbols for shared library \"%s\"\n", name); +#endif + + som_solib_add_solib_objfile (so, name, from_tty, text_addr); + + /* Now we need to build a section table for this library since + we might be debugging a core file from a dynamically linked + executable in which the libraries were not privately mapped. */ + if (build_section_table (so->abfd, + &so->sections, + &so->sections_end)) + { + error ("Unable to build section table for shared library\n."); + return; + } + + /* Relocate all the sections based on where they got loaded. */ + for (p = so->sections; p < so->sections_end; p++) + { + if (p->the_bfd_section->flags & SEC_CODE) + { + p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); + p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); + } + else if (p->the_bfd_section->flags & SEC_DATA) + { + p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); + p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); + } + } + + /* Now see if we need to map in the text and data for this shared + library (for example debugging a core file which does not use + private shared libraries.). + + Carefully peek at the first text address in the library. If the + read succeeds, then the libraries were privately mapped and were + included in the core dump file. + + If the peek failed, then the libraries were not privately mapped + and are not in the core file, we'll have to read them in ourselves. */ + status = target_read_memory (text_addr, buf, 4); + if (status != 0) + { + int old, new; + + new = so->sections_end - so->sections; + + old = target_resize_to_sections (target, new); + + /* Copy over the old data before it gets clobbered. */ + memcpy ((char *) (target->to_sections + old), + so->sections, + ((sizeof (struct section_table)) * new)); + } +} + + +/* FIXME: cagney/2003-02-01: This just isn't right. Given an address + within the target's address space, this converts the value into an + address within the host's (i.e., GDB's) address space. Given that + the host/target address spaces are separate, this can't be right. */ + +static void * +hpux_address_to_host_pointer_hack (CORE_ADDR addr) +{ + void *ptr; + + gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr)); + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr); + return ptr; +} + +/* Add symbols from shared libraries into the symtab list, unless the + size threshold specified by auto_solib_limit (in megabytes) would + be exceeded. */ + +void +som_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) +{ + struct minimal_symbol *msymbol; + struct so_list *so_list_tail; + CORE_ADDR addr; + asection *shlib_info; + int status; + unsigned int dld_flags; + char buf[4], *re_err; + int threshold_warning_given = 0; + + /* First validate our arguments. */ + re_err = re_comp (arg_string ? arg_string : "."); + if (re_err != NULL) + { + error ("Invalid regexp: %s", re_err); + } + + /* If we're debugging a core file, or have attached to a running + process, then som_solib_create_inferior_hook will not have been + called. + + We need to first determine if we're dealing with a dynamically + linked executable. If not, then return without an error or warning. + + We also need to examine __dld_flags to determine if the shared library + list is valid and to determine if the libraries have been privately + mapped. */ + if (symfile_objfile == NULL) + return; + + /* First see if the objfile was dynamically linked. */ + shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$"); + if (!shlib_info) + return; + + /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */ + if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) + return; + + msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); + if (msymbol == NULL) + { + error ("Unable to find __dld_flags symbol in object file.\n"); + return; + } + + addr = SYMBOL_VALUE_ADDRESS (msymbol); + /* Read the current contents. */ + status = target_read_memory (addr, buf, 4); + if (status != 0) + { + error ("Unable to read __dld_flags\n"); + return; + } + dld_flags = extract_unsigned_integer (buf, 4); + + /* __dld_list may not be valid. If not, then we punt, warning the user if + we were called as a result of the add-symfile command. + */ + if ((dld_flags & DLD_FLAGS_LISTVALID) == 0) + { + if (from_tty) + error ("__dld_list is not valid according to __dld_flags.\n"); + return; + } + + /* If the libraries were not mapped private, warn the user. */ + if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0) + warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n"); + + msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL); + if (!msymbol) + { + /* Older crt0.o files (hpux8) don't have __dld_list as a symbol, + but the data is still available if you know where to look. */ + msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); + if (!msymbol) + { + error ("Unable to find dynamic library list.\n"); + return; + } + addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8; + } + else + addr = SYMBOL_VALUE_ADDRESS (msymbol); + + status = target_read_memory (addr, buf, 4); + if (status != 0) + { + error ("Unable to find dynamic library list.\n"); + return; + } + + addr = extract_unsigned_integer (buf, 4); + + /* If addr is zero, then we're using an old dynamic loader which + doesn't maintain __dld_list. We'll have to use a completely + different approach to get shared library information. */ + if (addr == 0) + goto old_dld; + + /* Using the information in __dld_list is the preferred method + to get at shared library information. It doesn't depend on + any functions in /opt/langtools/lib/end.o and has a chance of working + with hpux10 when it is released. */ + status = target_read_memory (addr, buf, 4); + if (status != 0) + { + error ("Unable to find dynamic library list.\n"); + return; + } + + /* addr now holds the address of the first entry in the dynamic + library list. */ + addr = extract_unsigned_integer (buf, 4); + + /* Now that we have a pointer to the dynamic library list, walk + through it and add the symbols for each library. */ + + so_list_tail = so_list_head; + /* Find the end of the list of shared objects. */ + while (so_list_tail && so_list_tail->next) + so_list_tail = so_list_tail->next; + +#ifdef SOLIB_DEBUG + printf ("--About to read shared library list data\n"); +#endif + + /* "addr" will always point to the base of the + * current data entry describing the current + * shared library. + */ + while (1) + { + CORE_ADDR name_addr, text_addr; + unsigned int name_len; + char *name; + struct so_list *new_so; + struct so_list *so_list = so_list_head; + struct stat statbuf; + LONGEST st_size; + int is_main_program; + + if (addr == 0) + break; + + /* Get a pointer to the name of this library. */ + status = target_read_memory (addr, buf, 4); + if (status != 0) + goto err; + + name_addr = extract_unsigned_integer (buf, 4); + name_len = 0; + while (1) + { + target_read_memory (name_addr + name_len, buf, 1); + if (status != 0) + goto err; + + name_len++; + if (*buf == '\0') + break; + } + name = alloca (name_len); + status = target_read_memory (name_addr, name, name_len); + if (status != 0) + goto err; + + /* See if we've already loaded something with this name. */ + while (so_list) + { + if (!strcmp (so_list->som_solib.name, name)) + break; + so_list = so_list->next; + } + + /* See if the file exists. If not, give a warning, but don't + die. */ + status = stat (name, &statbuf); + if (status == -1) + { + warning ("Can't find file %s referenced in dld_list.", name); + + status = target_read_memory (addr + 36, buf, 4); + if (status != 0) + goto err; + + addr = (CORE_ADDR) extract_unsigned_integer (buf, 4); + continue; + } + + /* If we've already loaded this one or it's the main program, skip it. */ + is_main_program = (strcmp (name, symfile_objfile->name) == 0); + if (so_list || is_main_program) + { + /* This is the "next" pointer in the strcuture. + */ + status = target_read_memory (addr + 36, buf, 4); + if (status != 0) + goto err; + + addr = (CORE_ADDR) extract_unsigned_integer (buf, 4); + + /* Record the main program's symbol table size. */ + if (is_main_program && !so_list) + { + st_size = som_solib_sizeof_symbol_table (name); + som_solib_total_st_size += st_size; + } + + /* Was this a shlib that we noted but didn't load the symbols for? + If so, were we invoked this time from the command-line, via + a 'sharedlibrary' or 'add-symbol-file' command? If yes to + both, we'd better load the symbols this time. + */ + if (from_tty && so_list && !is_main_program && (so_list->objfile == NULL)) + som_solib_load_symbols (so_list, + name, + from_tty, + so_list->som_solib.text_addr, + target); + + continue; + } + + name = obsavestring (name, name_len - 1, + &symfile_objfile->objfile_obstack); + + status = target_read_memory (addr + 8, buf, 4); + if (status != 0) + goto err; + + text_addr = extract_unsigned_integer (buf, 4); + + new_so = (struct so_list *) xmalloc (sizeof (struct so_list)); + memset ((char *) new_so, 0, sizeof (struct so_list)); + if (so_list_head == NULL) + { + so_list_head = new_so; + so_list_tail = new_so; + } + else + { + so_list_tail->next = new_so; + so_list_tail = new_so; + } + + /* Fill in all the entries in GDB's shared library list. + */ + + new_so->solib_addr = addr; + new_so->som_solib.name = name; + status = target_read_memory (addr + 4, buf, 4); + if (status != 0) + goto err; + + new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1); + new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1); + /* Following is "high water mark", highest version number + * seen, rather than plain version number. + */ + new_so->som_solib.library_version = extract_unsigned_integer (buf, 2); + new_so->som_solib.text_addr = text_addr; + + /* Q: What about longword at "addr + 8"? + * A: It's read above, out of order, into "text_addr". + */ + + status = target_read_memory (addr + 12, buf, 4); + if (status != 0) + goto err; + + new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4); + + status = target_read_memory (addr + 16, buf, 4); + if (status != 0) + goto err; + + new_so->som_solib.text_end = extract_unsigned_integer (buf, 4); + + status = target_read_memory (addr + 20, buf, 4); + if (status != 0) + goto err; + + new_so->som_solib.data_start = extract_unsigned_integer (buf, 4); + + status = target_read_memory (addr + 24, buf, 4); + if (status != 0) + goto err; + + new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4); + + status = target_read_memory (addr + 28, buf, 4); + if (status != 0) + goto err; + + new_so->som_solib.data_end = extract_unsigned_integer (buf, 4); + + status = target_read_memory (addr + 32, buf, 4); + if (status != 0) + goto err; + + new_so->som_solib.got_value = extract_unsigned_integer (buf, 4); + + status = target_read_memory (addr + 36, buf, 4); + if (status != 0) + goto err; + + /* FIXME: cagney/2003-02-01: I think som_solib.next should be a + CORE_ADDR. */ + new_so->som_solib.next = + hpux_address_to_host_pointer_hack (extract_unsigned_integer (buf, 4)); + + /* Note that we don't re-set "addr" to the next pointer + * until after we've read the trailing data. + */ + + status = target_read_memory (addr + 40, buf, 4); + new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4); + if (status != 0) + goto err; + + /* Now indirect via that value! + */ + status = target_read_memory (new_so->som_solib.tsd_start_addr, buf, 4); + new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4); + if (status != 0) + goto err; +#ifdef SOLIB_DEBUG + printf ("\n+ library \"%s\" is described at 0x%x\n", name, addr); + printf (" 'version' is %d\n", new_so->som_solib.struct_version); + printf (" 'bind_mode' is %d\n", new_so->som_solib.bind_mode); + printf (" 'library_version' is %d\n", new_so->som_solib.library_version); + printf (" 'text_addr' is 0x%x\n", new_so->som_solib.text_addr); + printf (" 'text_link_addr' is 0x%x\n", new_so->som_solib.text_link_addr); + printf (" 'text_end' is 0x%x\n", new_so->som_solib.text_end); + printf (" 'data_start' is 0x%x\n", new_so->som_solib.data_start); + printf (" 'bss_start' is 0x%x\n", new_so->som_solib.bss_start); + printf (" 'data_end' is 0x%x\n", new_so->som_solib.data_end); + printf (" 'got_value' is %x\n", new_so->som_solib.got_value); + printf (" 'next' is 0x%x\n", new_so->som_solib.next); + printf (" 'tsd_start_addr' is 0x%x\n", new_so->som_solib.tsd_start_addr); +#endif + + /* Go on to the next shared library descriptor. + */ + addr = (CORE_ADDR) new_so->som_solib.next; + + + + /* At this point, we have essentially hooked the shlib into the + "info share" command. However, we haven't yet loaded its + symbol table. We must now decide whether we ought to, i.e., + whether doing so would exceed the symbol table size threshold. + + If the threshold has just now been exceeded, then we'll issue + a warning message (which explains how to load symbols manually, + if the user so desires). + + If the threshold has just now or previously been exceeded, + we'll just add the shlib to the list of object files, but won't + actually load its symbols. (This is more useful than it might + sound, for it allows us to e.g., still load and use the shlibs' + unwind information for stack tracebacks.) + */ + + /* Note that we DON'T want to preclude the user from using the + add-symbol-file command! Thus, we only worry about the threshold + when we're invoked for other reasons. + */ + st_size = som_solib_sizeof_symbol_table (name); + som_solib_st_size_threshold_exceeded = + !from_tty && + auto_solib_limit > 0 && + readsyms && + ((st_size + som_solib_total_st_size) > (auto_solib_limit * (LONGEST) (1024 * 1024))); + + if (som_solib_st_size_threshold_exceeded) + { + if (!threshold_warning_given) + warning ("Symbols for some libraries have not been loaded, because\ndoing so would exceed the size threshold specified by auto-solib-limit.\nTo manually load symbols, use the 'sharedlibrary' command.\nTo raise the threshold, set auto-solib-limit to a larger value and rerun\nthe program.\n"); + threshold_warning_given = 1; + + /* We'll still make note of this shlib, even if we don't + read its symbols. This allows us to use its unwind + information well enough to know how to e.g., correctly + do a traceback from a PC within the shlib, even if we + can't symbolize those PCs... + */ + som_solib_add_solib_objfile (new_so, name, from_tty, text_addr); + continue; + } + + som_solib_total_st_size += st_size; + + /* This fills in new_so->objfile, among others. */ + som_solib_load_symbols (new_so, name, from_tty, text_addr, target); + } + +#ifdef SOLIB_DEBUG + printf ("--Done reading shared library data\n"); +#endif + + /* Getting new symbols may change our opinion about what is + frameless. */ + reinit_frame_cache (); + return; + +old_dld: + error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n"); + return; + +err: + error ("Error while reading dynamic library list.\n"); + return; +} + + +/* This hook gets called just before the first instruction in the + inferior process is executed. + + This is our opportunity to set magic flags in the inferior so + that GDB can be notified when a shared library is mapped in and + to tell the dynamic linker that a private copy of the library is + needed (so GDB can set breakpoints in the library). + + __dld_flags is the location of the magic flags; as of this implementation + there are 3 flags of interest: + + bit 0 when set indicates that private copies of the libraries are needed + bit 1 when set indicates that the callback hook routine is valid + bit 2 when set indicates that the dynamic linker should maintain the + __dld_list structure when loading/unloading libraries. + + Note that shared libraries are not mapped in at this time, so we have + run the inferior until the libraries are mapped in. Typically this + means running until the "_start" is called. */ + +void +som_solib_create_inferior_hook (void) +{ + struct minimal_symbol *msymbol; + unsigned int dld_flags, status, have_endo; + asection *shlib_info; + char buf[4]; + struct objfile *objfile; + CORE_ADDR anaddr; + + /* First, remove all the solib event breakpoints. Their addresses + may have changed since the last time we ran the program. */ + remove_solib_event_breakpoints (); + + if (symfile_objfile == NULL) + return; + + /* First see if the objfile was dynamically linked. */ + shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$"); + if (!shlib_info) + return; + + /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */ + if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) + return; + + have_endo = 0; + /* Slam the pid of the process into __d_pid. + + We used to warn when this failed, but that warning is only useful + on very old HP systems (hpux9 and older). The warnings are an + annoyance to users of modern systems and foul up the testsuite as + well. As a result, the warnings have been disabled. */ + msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile); + if (msymbol == NULL) + goto keep_going; + + anaddr = SYMBOL_VALUE_ADDRESS (msymbol); + store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); + status = target_write_memory (anaddr, buf, 4); + if (status != 0) + { + warning ("Unable to write __d_pid"); + warning ("Suggest linking with /opt/langtools/lib/end.o."); + warning ("GDB will be unable to track shl_load/shl_unload calls"); + goto keep_going; + } + + /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook; + This will force the dynamic linker to call __d_trap when significant + events occur. + + Note that the above is the pre-HP-UX 9.0 behaviour. At 9.0 and above, + the dld provides an export stub named "__d_trap" as well as the + function named "__d_trap" itself, but doesn't provide "_DLD_HOOK". + We'll look first for the old flavor and then the new. + */ + msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile); + if (msymbol == NULL) + msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); + if (msymbol == NULL) + { + warning ("Unable to find _DLD_HOOK symbol in object file."); + warning ("Suggest linking with /opt/langtools/lib/end.o."); + warning ("GDB will be unable to track shl_load/shl_unload calls"); + goto keep_going; + } + anaddr = SYMBOL_VALUE_ADDRESS (msymbol); + dld_cache.hook.address = anaddr; + + /* Grrr, this might not be an export symbol! We have to find the + export stub. */ + ALL_OBJFILES (objfile) + { + struct unwind_table_entry *u; + struct minimal_symbol *msymbol2; + + /* What a crock. */ + msymbol2 = lookup_minimal_symbol_solib_trampoline (DEPRECATED_SYMBOL_NAME (msymbol), + objfile); + /* Found a symbol with the right name. */ + if (msymbol2) + { + struct unwind_table_entry *u; + /* It must be a shared library trampoline. */ + if (SYMBOL_TYPE (msymbol2) != mst_solib_trampoline) + continue; + + /* It must also be an export stub. */ + u = find_unwind_entry (SYMBOL_VALUE (msymbol2)); + if (!u || u->stub_unwind.stub_type != EXPORT) + continue; + + /* OK. Looks like the correct import stub. */ + anaddr = SYMBOL_VALUE (msymbol2); + dld_cache.hook_stub.address = anaddr; + } + } + store_unsigned_integer (buf, 4, anaddr); + + msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile); + if (msymbol == NULL) + { + warning ("Unable to find __dld_hook symbol in object file."); + warning ("Suggest linking with /opt/langtools/lib/end.o."); + warning ("GDB will be unable to track shl_load/shl_unload calls"); + goto keep_going; + } + anaddr = SYMBOL_VALUE_ADDRESS (msymbol); + status = target_write_memory (anaddr, buf, 4); + + /* Now set a shlib_event breakpoint at __d_trap so we can track + significant shared library events. */ + msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); + if (msymbol == NULL) + { + warning ("Unable to find __dld_d_trap symbol in object file."); + warning ("Suggest linking with /opt/langtools/lib/end.o."); + warning ("GDB will be unable to track shl_load/shl_unload calls"); + goto keep_going; + } + create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol)); + + /* We have all the support usually found in end.o, so we can track + shl_load and shl_unload calls. */ + have_endo = 1; + +keep_going: + + /* Get the address of __dld_flags, if no such symbol exists, then we can + not debug the shared code. */ + msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); + if (msymbol == NULL) + { + error ("Unable to find __dld_flags symbol in object file.\n"); + } + + anaddr = SYMBOL_VALUE_ADDRESS (msymbol); + + /* Read the current contents. */ + status = target_read_memory (anaddr, buf, 4); + if (status != 0) + { + error ("Unable to read __dld_flags\n"); + } + dld_flags = extract_unsigned_integer (buf, 4); + + /* Turn on the flags we care about. */ + dld_flags |= DLD_FLAGS_MAPPRIVATE; + if (have_endo) + dld_flags |= DLD_FLAGS_HOOKVALID; + store_unsigned_integer (buf, 4, dld_flags); + status = target_write_memory (anaddr, buf, 4); + if (status != 0) + { + error ("Unable to write __dld_flags\n"); + } + + /* Now find the address of _start and set a breakpoint there. + We still need this code for two reasons: + + * Not all sites have /opt/langtools/lib/end.o, so it's not always + possible to track the dynamic linker's events. + + * At this time no events are triggered for shared libraries + loaded at startup time (what a crock). */ + + msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile); + if (msymbol == NULL) + { + error ("Unable to find _start symbol in object file.\n"); + } + + anaddr = SYMBOL_VALUE_ADDRESS (msymbol); + + /* Make the breakpoint at "_start" a shared library event breakpoint. */ + create_solib_event_breakpoint (anaddr); + + /* Wipe out all knowledge of old shared libraries since their + mapping can change from one exec to another! */ + while (so_list_head) + { + struct so_list *temp; + + temp = so_list_head; + xfree (so_list_head); + so_list_head = temp->next; + } + clear_symtab_users (); +} + +/* This operation removes the "hook" between GDB and the dynamic linker, + which causes the dld to notify GDB of shared library events. + + After this operation completes, the dld will no longer notify GDB of + shared library events. To resume notifications, GDB must call + som_solib_create_inferior_hook. + + This operation does not remove any knowledge of shared libraries which + GDB may already have been notified of. + */ +void +som_solib_remove_inferior_hook (int pid) +{ + CORE_ADDR addr; + struct minimal_symbol *msymbol; + int status; + char dld_flags_buffer[4]; + unsigned int dld_flags_value; + struct cleanup *old_cleanups = save_inferior_ptid (); + + /* Ensure that we're really operating on the specified process. */ + inferior_ptid = pid_to_ptid (pid); + + /* We won't bother to remove the solib breakpoints from this process. + + In fact, on PA64 the breakpoint is hard-coded into the dld callback, + and thus we're not supposed to remove it. + + Rather, we'll merely clear the dld_flags bit that enables callbacks. + */ + msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); + + addr = SYMBOL_VALUE_ADDRESS (msymbol); + status = target_read_memory (addr, dld_flags_buffer, 4); + + dld_flags_value = extract_unsigned_integer (dld_flags_buffer, 4); + + dld_flags_value &= ~DLD_FLAGS_HOOKVALID; + store_unsigned_integer (dld_flags_buffer, 4, dld_flags_value); + status = target_write_memory (addr, dld_flags_buffer, 4); + + do_cleanups (old_cleanups); +} + + +/* This function creates a breakpoint on the dynamic linker hook, which + is called when e.g., a shl_load or shl_unload call is made. This + breakpoint will only trigger when a shl_load call is made. + + If filename is NULL, then loads of any dll will be caught. Else, + only loads of the file whose pathname is the string contained by + filename will be caught. + + Undefined behaviour is guaranteed if this function is called before + som_solib_create_inferior_hook. + */ +void +som_solib_create_catch_load_hook (int pid, int tempflag, char *filename, + char *cond_string) +{ + create_solib_load_event_breakpoint ("__d_trap", tempflag, filename, cond_string); +} + +/* This function creates a breakpoint on the dynamic linker hook, which + is called when e.g., a shl_load or shl_unload call is made. This + breakpoint will only trigger when a shl_unload call is made. + + If filename is NULL, then unloads of any dll will be caught. Else, + only unloads of the file whose pathname is the string contained by + filename will be caught. + + Undefined behaviour is guaranteed if this function is called before + som_solib_create_inferior_hook. + */ +void +som_solib_create_catch_unload_hook (int pid, int tempflag, char *filename, + char *cond_string) +{ + create_solib_unload_event_breakpoint ("__d_trap", tempflag, filename, cond_string); +} + +int +som_solib_have_load_event (int pid) +{ + CORE_ADDR event_kind; + + event_kind = read_register (ARG0_REGNUM); + return (event_kind == SHL_LOAD); +} + +int +som_solib_have_unload_event (int pid) +{ + CORE_ADDR event_kind; + + event_kind = read_register (ARG0_REGNUM); + return (event_kind == SHL_UNLOAD); +} + +static char * +som_solib_library_pathname (int pid) +{ + CORE_ADDR dll_handle_address; + CORE_ADDR dll_pathname_address; + struct som_solib_mapped_entry dll_descriptor; + char *p; + static char dll_pathname[1024]; + + /* Read the descriptor of this newly-loaded library. */ + dll_handle_address = read_register (ARG1_REGNUM); + read_memory (dll_handle_address, (char *) &dll_descriptor, sizeof (dll_descriptor)); + + /* We can find a pointer to the dll's pathname within the descriptor. */ + dll_pathname_address = (CORE_ADDR) dll_descriptor.name; + + /* Read the pathname, one byte at a time. */ + p = dll_pathname; + for (;;) + { + char b; + read_memory (dll_pathname_address++, (char *) &b, 1); + *p++ = b; + if (b == '\0') + break; + } + + return dll_pathname; +} + +char * +som_solib_loaded_library_pathname (int pid) +{ + if (!som_solib_have_load_event (pid)) + error ("Must have a load event to use this query"); + + return som_solib_library_pathname (pid); +} + +char * +som_solib_unloaded_library_pathname (int pid) +{ + if (!som_solib_have_unload_event (pid)) + error ("Must have an unload event to use this query"); + + return som_solib_library_pathname (pid); +} + +static void +som_solib_desire_dynamic_linker_symbols (void) +{ + struct objfile *objfile; + struct unwind_table_entry *u; + struct minimal_symbol *dld_msymbol; + + /* Do we already know the value of these symbols? If so, then + we've no work to do. + + (If you add clauses to this test, be sure to likewise update the + test within the loop.) + */ + if (dld_cache.is_valid) + return; + + ALL_OBJFILES (objfile) + { + dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile); + if (dld_msymbol != NULL) + { + dld_cache.load.address = SYMBOL_VALUE (dld_msymbol); + dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address); + } + + dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load", + objfile); + if (dld_msymbol != NULL) + { + if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) + { + u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); + if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) + { + dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol); + dld_cache.load_stub.unwind = u; + } + } + } + + dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile); + if (dld_msymbol != NULL) + { + dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol); + dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address); + + /* ??rehrauer: I'm not sure exactly what this is, but it appears + that on some HPUX 10.x versions, there's two unwind regions to + cover the body of "shl_unload", the second being 4 bytes past + the end of the first. This is a large hack to handle that + case, but since I don't seem to have any legitimate way to + look for this thing via the symbol table... + */ + if (dld_cache.unload.unwind != NULL) + { + u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4); + if (u != NULL) + { + dld_cache.unload2.address = u->region_start; + dld_cache.unload2.unwind = u; + } + } + } + + dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload", + objfile); + if (dld_msymbol != NULL) + { + if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) + { + u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); + if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) + { + dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol); + dld_cache.unload_stub.unwind = u; + } + } + } + + /* Did we find everything we were looking for? If so, stop. */ + if ((dld_cache.load.address != 0) + && (dld_cache.load_stub.address != 0) + && (dld_cache.unload.address != 0) + && (dld_cache.unload_stub.address != 0)) + { + dld_cache.is_valid = 1; + break; + } + } + + dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address); + dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address); + + /* We're prepared not to find some of these symbols, which is why + this function is a "desire" operation, and not a "require". + */ +} + +int +som_solib_in_dynamic_linker (int pid, CORE_ADDR pc) +{ + struct unwind_table_entry *u_pc; + + /* Are we in the dld itself? + + ??rehrauer: Large hack -- We'll assume that any address in a + shared text region is the dld's text. This would obviously + fall down if the user attached to a process, whose shlibs + weren't mapped to a (writeable) private region. However, in + that case the debugger probably isn't able to set the fundamental + breakpoint in the dld callback anyways, so this hack should be + safe. + */ + if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000) + return 1; + + /* Cache the address of some symbols that are part of the dynamic + linker, if not already known. + */ + som_solib_desire_dynamic_linker_symbols (); + + /* Are we in the dld callback? Or its export stub? */ + u_pc = find_unwind_entry (pc); + if (u_pc == NULL) + return 0; + + if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind)) + return 1; + + /* Or the interface of the dld (i.e., "shl_load" or friends)? */ + if ((u_pc == dld_cache.load.unwind) + || (u_pc == dld_cache.unload.unwind) + || (u_pc == dld_cache.unload2.unwind) + || (u_pc == dld_cache.load_stub.unwind) + || (u_pc == dld_cache.unload_stub.unwind)) + return 1; + + /* Apparently this address isn't part of the dld's text. */ + return 0; +} + + +/* Return the GOT value for the shared library in which ADDR belongs. If + ADDR isn't in any known shared library, return zero. */ + +CORE_ADDR +som_solib_get_got_by_pc (CORE_ADDR addr) +{ + struct so_list *so_list = so_list_head; + CORE_ADDR got_value = 0; + + while (so_list) + { + if (so_list->som_solib.text_addr <= addr + && so_list->som_solib.text_end > addr) + { + got_value = so_list->som_solib.got_value; + break; + } + so_list = so_list->next; + } + return got_value; +} + +/* elz: + Return the address of the handle of the shared library + in which ADDR belongs. If + ADDR isn't in any known shared library, return zero. */ +/* this function is used in hppa_fix_call_dummy in hppa-tdep.c */ + +CORE_ADDR +som_solib_get_solib_by_pc (CORE_ADDR addr) +{ + struct so_list *so_list = so_list_head; + + while (so_list) + { + if (so_list->som_solib.text_addr <= addr + && so_list->som_solib.text_end > addr) + { + break; + } + so_list = so_list->next; + } + if (so_list) + return so_list->solib_addr; + else + return 0; +} + + +int +som_solib_section_offsets (struct objfile *objfile, + struct section_offsets *offsets) +{ + struct so_list *so_list = so_list_head; + + while (so_list) + { + /* Oh what a pain! We need the offsets before so_list->objfile + is valid. The BFDs will never match. Make a best guess. */ + if (strstr (objfile->name, so_list->som_solib.name)) + { + asection *private_section; + + /* The text offset is easy. */ + offsets->offsets[SECT_OFF_TEXT (objfile)] + = (so_list->som_solib.text_addr + - so_list->som_solib.text_link_addr); + offsets->offsets[SECT_OFF_RODATA (objfile)] + = ANOFFSET (offsets, SECT_OFF_TEXT (objfile)); + + /* We should look at presumed_dp in the SOM header, but + that's not easily available. This should be OK though. */ + private_section = bfd_get_section_by_name (objfile->obfd, + "$PRIVATE$"); + if (!private_section) + { + warning ("Unable to find $PRIVATE$ in shared library!"); + offsets->offsets[SECT_OFF_DATA (objfile)] = 0; + offsets->offsets[SECT_OFF_BSS (objfile)] = 0; + return 1; + } + offsets->offsets[SECT_OFF_DATA (objfile)] + = (so_list->som_solib.data_start - private_section->vma); + offsets->offsets[SECT_OFF_BSS (objfile)] + = ANOFFSET (offsets, SECT_OFF_DATA (objfile)); + return 1; + } + so_list = so_list->next; + } + return 0; +} + +/* Dump information about all the currently loaded shared libraries. */ + +static void +som_sharedlibrary_info_command (char *ignore, int from_tty) +{ + struct so_list *so_list = so_list_head; + + if (exec_bfd == NULL) + { + printf_unfiltered ("No executable file.\n"); + return; + } + + if (so_list == NULL) + { + printf_unfiltered ("No shared libraries loaded at this time.\n"); + return; + } + + printf_unfiltered ("Shared Object Libraries\n"); + printf_unfiltered (" %-12s%-12s%-12s%-12s%-12s%-12s\n", + " flags", " tstart", " tend", " dstart", " dend", " dlt"); + while (so_list) + { + unsigned int flags; + + flags = so_list->som_solib.struct_version << 24; + flags |= so_list->som_solib.bind_mode << 16; + flags |= so_list->som_solib.library_version; + printf_unfiltered ("%s", so_list->som_solib.name); + if (so_list->objfile == NULL) + printf_unfiltered (" (symbols not loaded)"); + printf_unfiltered ("\n"); + printf_unfiltered (" %-12s", local_hex_string_custom (flags, "08l")); + printf_unfiltered ("%-12s", + local_hex_string_custom (so_list->som_solib.text_addr, "08l")); + printf_unfiltered ("%-12s", + local_hex_string_custom (so_list->som_solib.text_end, "08l")); + printf_unfiltered ("%-12s", + local_hex_string_custom (so_list->som_solib.data_start, "08l")); + printf_unfiltered ("%-12s", + local_hex_string_custom (so_list->som_solib.data_end, "08l")); + printf_unfiltered ("%-12s\n", + local_hex_string_custom (so_list->som_solib.got_value, "08l")); + so_list = so_list->next; + } +} + +static void +som_solib_sharedlibrary_command (char *args, int from_tty) +{ + dont_repeat (); + som_solib_add (args, from_tty, (struct target_ops *) 0, 1); +} + + + +char * +som_solib_address (CORE_ADDR addr) +{ + struct so_list *so = so_list_head; + + while (so) + { + /* Is this address within this shlib's text range? If so, + return the shlib's name. + */ + if ((addr >= so->som_solib.text_addr) && (addr <= so->som_solib.text_end)) + return so->som_solib.name; + + /* Nope, keep looking... */ + so = so->next; + } + + /* No, we couldn't prove that the address is within a shlib. */ + return NULL; +} + + +void +som_solib_restart (void) +{ + struct so_list *sl = so_list_head; + + /* Before the shlib info vanishes, use it to disable any breakpoints + that may still be active in those shlibs. + */ + disable_breakpoints_in_shlibs (0); + + /* Discard all the shlib descriptors. + */ + while (sl) + { + struct so_list *next_sl = sl->next; + xfree (sl); + sl = next_sl; + } + so_list_head = NULL; + + som_solib_total_st_size = (LONGEST) 0; + som_solib_st_size_threshold_exceeded = 0; + + dld_cache.is_valid = 0; + + dld_cache.hook.address = 0; + dld_cache.hook.unwind = NULL; + + dld_cache.hook_stub.address = 0; + dld_cache.hook_stub.unwind = NULL; + + dld_cache.load.address = 0; + dld_cache.load.unwind = NULL; + + dld_cache.load_stub.address = 0; + dld_cache.load_stub.unwind = NULL; + + dld_cache.unload.address = 0; + dld_cache.unload.unwind = NULL; + + dld_cache.unload2.address = 0; + dld_cache.unload2.unwind = NULL; + + dld_cache.unload_stub.address = 0; + dld_cache.unload_stub.unwind = NULL; +} + + +/* LOCAL FUNCTION + + no_shared_libraries -- handle command to explicitly discard symbols + from shared libraries. + + DESCRIPTION + + Implements the command "nosharedlibrary", which discards symbols + that have been auto-loaded from shared libraries. Symbols from + shared libraries that were added by explicit request of the user + are not discarded. Also called from remote.c. */ + +void +no_shared_libraries (char *ignored, int from_tty) +{ + /* FIXME */ +} + + +void +_initialize_som_solib (void) +{ + add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command, + "Load shared object library symbols for files matching REGEXP."); + add_info ("sharedlibrary", som_sharedlibrary_info_command, + "Status of loaded shared object libraries."); + + add_show_from_set + (add_set_cmd ("auto-solib-add", class_support, var_boolean, + (char *) &auto_solib_add, + "Set autoloading of shared library symbols.\n\ +If \"on\", symbols from all shared object libraries will be loaded\n\ +automatically when the inferior begins execution, when the dynamic linker\n\ +informs gdb that a new library has been loaded, or when attaching to the\n\ +inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ("auto-solib-limit", class_support, var_zinteger, + (char *) &auto_solib_limit, + "Set threshold (in Mb) for autoloading shared library symbols.\n\ +When shared library autoloading is enabled, new libraries will be loaded\n\ +only until the total size of shared library symbols exceeds this\n\ +threshold in megabytes. Is ignored when using `sharedlibrary'.", + &setlist), + &showlist); + + /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how + much data space a process can use. We ought to be reading + MAXDSIZ and setting auto_solib_limit to some large fraction of + that value. If not that, we maybe ought to be setting it smaller + than the default for MAXDSIZ (that being 64Mb, I believe). + However, [1] this threshold is only crudely approximated rather + than actually measured, and [2] 50 Mbytes is too small for + debugging gdb itself. Thus, the arbitrary 100 figure. */ + auto_solib_limit = 100; /* Megabytes */ + + som_solib_restart (); +} + +/* Get some HPUX-specific data from a shared lib. + */ +CORE_ADDR +so_lib_thread_start_addr (struct so_list *so) +{ + return so->som_solib.tsd_start_addr; +} diff --git a/contrib/gdb/gdb/somsolib.h b/contrib/gdb/gdb/somsolib.h new file mode 100644 index 00000000000..c2414118843 --- /dev/null +++ b/contrib/gdb/gdb/somsolib.h @@ -0,0 +1,178 @@ +/* HP SOM Shared library declarations for GDB, the GNU Debugger. + + Copyright 1992, 1994, 1995, 1998, 1999, 2000, 2003 Free Software + Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Written by the Center for Software Science at the Univerity of Utah + and by Cygnus Support. */ + +#ifndef SOMSOLIB_H +#define SOMSOLIB_H + +/* Forward decl's for prototypes */ +struct target_ops; +struct objfile; +struct section_offsets; + +/* Called to add symbols from a shared library to gdb's symbol table. */ + +#define SOLIB_ADD(filename, from_tty, targ, readsyms) \ + som_solib_add (filename, from_tty, targ, readsyms) + +extern void som_solib_add (char *, int, struct target_ops *, int); + +extern CORE_ADDR som_solib_get_got_by_pc (CORE_ADDR); + +extern int som_solib_section_offsets (struct objfile *, + struct section_offsets *); + +/* Function to be called when the inferior starts up, to discover the names + of shared libraries that are dynamically linked, the base addresses to + which they are linked, and sufficient information to read in their symbols + at a later time. */ + +#define SOLIB_CREATE_INFERIOR_HOOK(PID) som_solib_create_inferior_hook() + +extern void som_solib_create_inferior_hook (void); + +/* Function to be called to remove the connection between debugger and + dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK. + (This operation does not remove shared library information from + the debugger, as CLEAR_SOLIB does.) + */ +#define SOLIB_REMOVE_INFERIOR_HOOK(PID) som_solib_remove_inferior_hook(PID) + +extern void som_solib_remove_inferior_hook (int); + +/* This function is called by the "catch load" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is loaded. + */ +#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag, filename,cond_string) \ + som_solib_create_catch_load_hook (pid, tempflag, filename, cond_string) + +extern void som_solib_create_catch_load_hook (int, int, char *, char *); + +/* This function is called by the "catch unload" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is unloaded. + */ +#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename, cond_string) \ + som_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string) + +extern void som_solib_create_catch_unload_hook (int, int, char *, char *); + +/* This function returns TRUE if the dynamic linker has just reported + a load of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. + */ +#define SOLIB_HAVE_LOAD_EVENT(pid) \ + som_solib_have_load_event (pid) + +extern int som_solib_have_load_event (int); + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been loaded. + + This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. + */ +#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ + som_solib_loaded_library_pathname (pid) + +extern char *som_solib_loaded_library_pathname (int); + +/* This function returns TRUE if the dynamic linker has just reported + an unload of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. + */ +#define SOLIB_HAVE_UNLOAD_EVENT(pid) \ + som_solib_have_unload_event (pid) + +extern int som_solib_have_unload_event (int); + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been unloaded. + + This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. + */ +#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ + som_solib_unloaded_library_pathname (pid) + +extern char *som_solib_unloaded_library_pathname (int); + +/* This function returns TRUE if pc is the address of an instruction that + lies within the dynamic linker (such as the event hook, or the dld + itself). + + This function must be used only when a dynamic linker event has been + caught, and the inferior is being stepped out of the hook, or undefined + results are guaranteed. + */ +#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ + som_solib_in_dynamic_linker (pid, pc) + +extern int som_solib_in_dynamic_linker (int, CORE_ADDR); + +/* This function must be called when the inferior is killed, and the program + restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard + any symbol tables. + + Presently, this functionality is not implemented. + */ +#define SOLIB_RESTART() \ + som_solib_restart () + +extern void som_solib_restart (void); + +/* If we can't set a breakpoint, and it's in a shared library, just + disable it. */ + +#define DISABLE_UNSETTABLE_BREAK(addr) (som_solib_address(addr) != NULL) + +extern char *som_solib_address (CORE_ADDR); /* somsolib.c */ + +/* If ADDR lies in a shared library, return its name. */ + +#define PC_SOLIB(addr) som_solib_address (addr) + +extern CORE_ADDR som_solib_get_solib_by_pc (CORE_ADDR addr); + +struct so_list; +extern CORE_ADDR so_lib_thread_start_addr (struct so_list *so); + +extern void no_shared_libraries (char *ignored, int from_tty); + +#endif diff --git a/contrib/gdb/gdb/source.c b/contrib/gdb/gdb/source.c index ee4998d9a49..92cdce426e6 100644 --- a/contrib/gdb/gdb/source.c +++ b/contrib/gdb/gdb/source.c @@ -1,6 +1,6 @@ /* List lines of source files for GDB, the GNU debugger. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -44,6 +44,7 @@ #include "filenames.h" /* for DOSish file names */ #include "completer.h" #include "ui-out.h" +#include "readline/readline.h" #ifdef CRLF_SOURCE_FILES @@ -79,10 +80,6 @@ static void forward_search_command (char *, int); static void line_info (char *, int); -static void list_command (char *, int); - -static void ambiguous_line_spec (struct symtabs_and_lines *); - static void source_info (char *, int); static void show_directories (char *, int); @@ -94,11 +91,11 @@ char *source_path; /* Symtab of default file for listing lines of. */ -struct symtab *current_source_symtab; +static struct symtab *current_source_symtab; /* Default next line to list. */ -int current_source_line; +static int current_source_line; /* Default number of lines to print with commands like "list". This is based on guessing how many long (i.e. more than chars_per_line @@ -123,6 +120,93 @@ static int first_line_listed; static struct symtab *last_source_visited = NULL; static int last_source_error = 0; +/* Return the first line listed by print_source_lines. + Used by command interpreters to request listing from + a previous point. */ + +int +get_first_line_listed (void) +{ + return first_line_listed; +} + +/* Return the default number of lines to print with commands like the + cli "list". The caller of print_source_lines must use this to + calculate the end line and use it in the call to print_source_lines + as it does not automatically use this value. */ + +int +get_lines_to_list (void) +{ + return lines_to_list; +} + +/* Return the current source file for listing and next line to list. + NOTE: The returned sal pc and end fields are not valid. */ + +struct symtab_and_line +get_current_source_symtab_and_line (void) +{ + struct symtab_and_line cursal; + + cursal.symtab = current_source_symtab; + cursal.line = current_source_line; + cursal.pc = 0; + cursal.end = 0; + + return cursal; +} + +/* If the current source file for listing is not set, try and get a default. + Usually called before get_current_source_symtab_and_line() is called. + It may err out if a default cannot be determined. + We must be cautious about where it is called, as it can recurse as the + process of determining a new default may call the caller! + Use get_current_source_symtab_and_line only to get whatever + we have without erroring out or trying to get a default. */ + +void +set_default_source_symtab_and_line (void) +{ + struct symtab_and_line cursal; + + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + + /* Pull in a current source symtab if necessary */ + if (current_source_symtab == 0) + select_source_symtab (0); +} + +/* Return the current default file for listing and next line to list + (the returned sal pc and end fields are not valid.) + and set the current default to whatever is in SAL. + NOTE: The returned sal pc and end fields are not valid. */ + +struct symtab_and_line +set_current_source_symtab_and_line (const struct symtab_and_line *sal) +{ + struct symtab_and_line cursal; + + cursal.symtab = current_source_symtab; + cursal.line = current_source_line; + + current_source_symtab = sal->symtab; + current_source_line = sal->line; + cursal.pc = 0; + cursal.end = 0; + + return cursal; +} + +/* Reset any information stored about a default file and line to print. */ + +void +clear_current_source_symtab_and_line (void) +{ + current_source_symtab = 0; + current_source_line = 0; +} /* Set the source file default for the "list" command to be S. @@ -133,7 +217,7 @@ static int last_source_error = 0; before we need to would make things slower than necessary. */ void -select_source_symtab (register struct symtab *s) +select_source_symtab (struct symtab *s) { struct symtabs_and_lines sals; struct symtab_and_line sal; @@ -153,7 +237,7 @@ select_source_symtab (register struct symtab *s) /* Make the default place to list be the function `main' if one exists. */ - if (lookup_symbol (main_name (), 0, VAR_NAMESPACE, 0, NULL)) + if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0, NULL)) { sals = decode_line_spec (main_name (), 1); sal = sals.sals[0]; @@ -174,7 +258,7 @@ select_source_symtab (register struct symtab *s) { char *name = s->filename; int len = strlen (name); - if (!(len > 2 && (STREQ (&name[len - 2], ".h")))) + if (!(len > 2 && (DEPRECATED_STREQ (&name[len - 2], ".h")))) { current_source_symtab = s; } @@ -191,7 +275,7 @@ select_source_symtab (register struct symtab *s) { char *name = ps->filename; int len = strlen (name); - if (!(len > 2 && (STREQ (&name[len - 2], ".h")))) + if (!(len > 2 && (DEPRECATED_STREQ (&name[len - 2], ".h")))) { cs_pst = ps; } @@ -231,8 +315,8 @@ show_directories (char *ignore, int from_tty) void forget_cached_source_info (void) { - register struct symtab *s; - register struct objfile *objfile; + struct symtab *s; + struct objfile *objfile; struct partial_symtab *pst; for (objfile = object_files; objfile != NULL; objfile = objfile->next) @@ -272,6 +356,12 @@ init_source_path (void) forget_cached_source_info (); } +void +init_last_source_visited (void) +{ + last_source_visited = NULL; +} + /* Add zero or more directories to the front of the source path. */ void @@ -301,6 +391,18 @@ directory_command (char *dirname, int from_tty) void mod_path (char *dirname, char **which_path) +{ + add_path (dirname, which_path, 1); +} + +/* Workhorse of mod_path. Takes an extra argument to determine + if dirname should be parsed for separators that indicate multiple + directories. This allows for interfaces that pre-parse the dirname + and allow specification of traditional separator characters such + as space or tab. */ + +void +add_path (char *dirname, char **which_path, int parse_separators) { char *old = *which_path; int prefix = 0; @@ -314,13 +416,20 @@ mod_path (char *dirname, char **which_path) do { char *name = dirname; - register char *p; + char *p; struct stat st; { - char *separator = strchr (name, DIRNAME_SEPARATOR); - char *space = strchr (name, ' '); - char *tab = strchr (name, '\t'); + char *separator = NULL; + char *space = NULL; + char *tab = NULL; + + if (parse_separators) + { + separator = strchr (name, DIRNAME_SEPARATOR); + space = strchr (name, ' '); + tab = strchr (name, '\t'); + } if (separator == 0 && space == 0 && tab == 0) p = dirname = name + strlen (name); @@ -415,7 +524,7 @@ mod_path (char *dirname, char **which_path) append: { - register unsigned int len = strlen (name); + unsigned int len = strlen (name); p = *which_path; while (1) @@ -451,7 +560,8 @@ mod_path (char *dirname, char **which_path) tinybuf[0] = DIRNAME_SEPARATOR; tinybuf[1] = '\0'; - /* If we have already tacked on a name(s) in this command, be sure they stay on the front as we tack on some more. */ + /* If we have already tacked on a name(s) in this command, be sure they stay + on the front as we tack on some more. */ if (prefix) { char *temp, c; @@ -482,7 +592,7 @@ mod_path (char *dirname, char **which_path) static void source_info (char *ignore, int from_tty) { - register struct symtab *s = current_source_symtab; + struct symtab *s = current_source_symtab; if (!s) { @@ -500,9 +610,28 @@ source_info (char *ignore, int from_tty) printf_filtered ("Source language is %s.\n", language_str (s->language)); printf_filtered ("Compiled with %s debugging format.\n", s->debugformat); + printf_filtered ("%s preprocessor macro info.\n", + s->macro_table ? "Includes" : "Does not include"); } +/* Return True if the file NAME exists and is a regular file */ +static int +is_regular_file (const char *name) +{ + struct stat st; + const int status = stat (name, &st); + + /* Stat should never fail except when the file does not exist. + If stat fails, analyze the source of error and return True + unless the file does not exist, to avoid returning false results + on obscure systems where stat does not work as expected. + */ + if (status != 0) + return (errno != ENOENT); + + return S_ISREG (st.st_mode); +} /* Open a file named STRING, searching path PATH (dir names sep by some char) using mode MODE and protection bits PROT in the calls to open. @@ -514,7 +643,7 @@ source_info (char *ignore, int from_tty) get that particular version of foo or an error message). If FILENAME_OPENED is non-null, set it to a newly allocated string naming - the actual file opened (this string will always start with a "/". We + the actual file opened (this string will always start with a "/"). We have to take special pains to avoid doubling the "/" between the directory and the file, sigh! Emacs gets confuzzed by this when we print the source file name!!! @@ -523,17 +652,17 @@ source_info (char *ignore, int from_tty) Otherwise, return -1, with errno set for the last name we tried to open. */ /* >>>> This should only allow files of certain types, - >>>> eg executable, non-directory */ + >>>> eg executable, non-directory */ int openp (const char *path, int try_cwd_first, const char *string, int mode, int prot, char **filename_opened) { - register int fd; - register char *filename; + int fd; + char *filename; const char *p; const char *p1; - register int len; + int len; int alloclen; if (!path) @@ -546,11 +675,21 @@ openp (const char *path, int try_cwd_first, const char *string, if (try_cwd_first || IS_ABSOLUTE_PATH (string)) { int i; - filename = alloca (strlen (string) + 1); - strcpy (filename, string); - fd = open (filename, mode, prot); - if (fd >= 0) - goto done; + + if (is_regular_file (string)) + { + filename = alloca (strlen (string) + 1); + strcpy (filename, string); + fd = open (filename, mode, prot); + if (fd >= 0) + goto done; + } + else + { + filename = NULL; + fd = -1; + } + for (i = 0; string[i]; i++) if (IS_DIR_SEPARATOR (string[i])) goto done; @@ -601,18 +740,26 @@ openp (const char *path, int try_cwd_first, const char *string, strcat (filename + len, SLASH_STRING); strcat (filename, string); - fd = open (filename, mode); - if (fd >= 0) - break; + if (is_regular_file (filename)) + { + fd = open (filename, mode); + if (fd >= 0) + break; + } } done: if (filename_opened) { + /* If a file was opened, canonicalize its filename. Use xfullpath + rather than gdb_realpath to avoid resolving the basename part + of filenames when the associated file is a symbolic link. This + fixes a potential inconsistency between the filenames known to + GDB and the filenames it prints in the annotations. */ if (fd < 0) *filename_opened = NULL; else if (IS_ABSOLUTE_PATH (filename)) - *filename_opened = gdb_realpath (filename); + *filename_opened = xfullpath (filename); else { /* Beware the // my son, the Emacs barfs, the botch that catch... */ @@ -621,7 +768,7 @@ done: IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) ? "" : SLASH_STRING, filename, NULL); - *filename_opened = gdb_realpath (f); + *filename_opened = xfullpath (f); xfree (f); } } @@ -758,7 +905,7 @@ void find_source_lines (struct symtab *s, int desc) { struct stat st; - register char *data, *p, *end; + char *data, *p, *end; int nlines = 0; int lines_allocated = 1000; int *line_charpos; @@ -870,10 +1017,10 @@ source_line_charpos (struct symtab *s, int line) /* Return the line number of character position POS in symtab S. */ int -source_charpos_line (register struct symtab *s, register int chr) +source_charpos_line (struct symtab *s, int chr) { - register int line = 0; - register int *lnp; + int line = 0; + int *lnp; if (s == 0 || s->line_charpos == 0) return 0; @@ -900,7 +1047,7 @@ source_charpos_line (register struct symtab *s, register int chr) static int get_filename_and_charpos (struct symtab *s, char **fullname) { - register int desc, linenums_changed = 0; + int desc, linenums_changed = 0; desc = open_source_file (s); if (desc < 0) @@ -958,9 +1105,9 @@ static void print_source_lines_base (struct symtab *s, int line, int stopline, static void print_source_lines_base (struct symtab *s, int line, int stopline, int noerror) { - register int c; - register int desc; - register FILE *stream; + int c; + int desc; + FILE *stream; int nlines = stopline - line; /* Regardless of whether we can open the file, set current_source_symtab. */ @@ -1083,199 +1230,6 @@ print_source_lines (struct symtab *s, int line, int stopline, int noerror) print_source_lines_base (s, line, stopline, noerror); } - - -/* Print a list of files and line numbers which a user may choose from - in order to list a function which was specified ambiguously (as with - `list classname::overloadedfuncname', for example). The vector in - SALS provides the filenames and line numbers. */ - -static void -ambiguous_line_spec (struct symtabs_and_lines *sals) -{ - int i; - - for (i = 0; i < sals->nelts; ++i) - printf_filtered ("file: \"%s\", line number: %d\n", - sals->sals[i].symtab->filename, sals->sals[i].line); -} - -static void -list_command (char *arg, int from_tty) -{ - struct symtabs_and_lines sals, sals_end; - struct symtab_and_line sal, sal_end; - struct symbol *sym; - char *arg1; - int no_end = 1; - int dummy_end = 0; - int dummy_beg = 0; - int linenum_beg = 0; - char *p; - - if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); - - /* Pull in a current source symtab if necessary */ - if (current_source_symtab == 0 && - (arg == 0 || arg[0] == '+' || arg[0] == '-')) - select_source_symtab (0); - - /* "l" or "l +" lists next ten lines. */ - - if (arg == 0 || STREQ (arg, "+")) - { - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); - print_source_lines (current_source_symtab, current_source_line, - current_source_line + lines_to_list, 0); - return; - } - - /* "l -" lists previous ten lines, the ones before the ten just listed. */ - if (STREQ (arg, "-")) - { - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); - print_source_lines (current_source_symtab, - max (first_line_listed - lines_to_list, 1), - first_line_listed, 0); - return; - } - - /* Now if there is only one argument, decode it in SAL - and set NO_END. - If there are two arguments, decode them in SAL and SAL_END - and clear NO_END; however, if one of the arguments is blank, - set DUMMY_BEG or DUMMY_END to record that fact. */ - - arg1 = arg; - if (*arg1 == ',') - dummy_beg = 1; - else - { - sals = decode_line_1 (&arg1, 0, 0, 0, 0); - - if (!sals.nelts) - return; /* C++ */ - if (sals.nelts > 1) - { - ambiguous_line_spec (&sals); - xfree (sals.sals); - return; - } - - sal = sals.sals[0]; - xfree (sals.sals); - } - - /* Record whether the BEG arg is all digits. */ - - for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++); - linenum_beg = (p == arg1); - - while (*arg1 == ' ' || *arg1 == '\t') - arg1++; - if (*arg1 == ',') - { - no_end = 0; - arg1++; - while (*arg1 == ' ' || *arg1 == '\t') - arg1++; - if (*arg1 == 0) - dummy_end = 1; - else - { - if (dummy_beg) - sals_end = decode_line_1 (&arg1, 0, 0, 0, 0); - else - sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0); - if (sals_end.nelts == 0) - return; - if (sals_end.nelts > 1) - { - ambiguous_line_spec (&sals_end); - xfree (sals_end.sals); - return; - } - sal_end = sals_end.sals[0]; - xfree (sals_end.sals); - } - } - - if (*arg1) - error ("Junk at end of line specification."); - - if (!no_end && !dummy_beg && !dummy_end - && sal.symtab != sal_end.symtab) - error ("Specified start and end are in different files."); - if (dummy_beg && dummy_end) - error ("Two empty args do not say what lines to list."); - - /* if line was specified by address, - first print exactly which line, and which file. - In this case, sal.symtab == 0 means address is outside - of all known source files, not that user failed to give a filename. */ - if (*arg == '*') - { - if (sal.symtab == 0) - /* FIXME-32x64--assumes sal.pc fits in long. */ - error ("No source file for address %s.", - local_hex_string ((unsigned long) sal.pc)); - sym = find_pc_function (sal.pc); - if (sym) - { - print_address_numeric (sal.pc, 1, gdb_stdout); - printf_filtered (" is in "); - fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout); - printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line); - } - else - { - print_address_numeric (sal.pc, 1, gdb_stdout); - printf_filtered (" is at %s:%d.\n", - sal.symtab->filename, sal.line); - } - } - - /* If line was not specified by just a line number, - and it does not imply a symtab, it must be an undebuggable symbol - which means no source code. */ - - if (!linenum_beg && sal.symtab == 0) - error ("No line number known for %s.", arg); - - /* If this command is repeated with RET, - turn it into the no-arg variant. */ - - if (from_tty) - *arg = 0; - - if (dummy_beg && sal_end.symtab == 0) - error ("No default source file yet. Do \"help list\"."); - if (dummy_beg) - print_source_lines (sal_end.symtab, - max (sal_end.line - (lines_to_list - 1), 1), - sal_end.line + 1, 0); - else if (sal.symtab == 0) - error ("No default source file yet. Do \"help list\"."); - else if (no_end) - { - int first_line = sal.line - lines_to_list / 2; - - if (first_line < 1) first_line = 1; - - print_source_lines (sal.symtab, first_line, first_line + lines_to_list, - 0); - } - else - print_source_lines (sal.symtab, sal.line, - (dummy_end - ? sal.line + lines_to_list - : sal_end.line + 1), - 0); -} - /* Print info on range of pc's in a specified line. */ static void @@ -1286,7 +1240,7 @@ line_info (char *arg, int from_tty) CORE_ADDR start_pc, end_pc; int i; - INIT_SAL (&sal); /* initialize to zeroes */ + init_sal (&sal); /* initialize to zeroes */ if (arg == 0) { @@ -1375,13 +1329,12 @@ line_info (char *arg, int from_tty) /* Commands to search the source file for a regexp. */ -/* ARGSUSED */ static void forward_search_command (char *regex, int from_tty) { - register int c; - register int desc; - register FILE *stream; + int c; + int desc; + FILE *stream; int line; char *msg; @@ -1389,7 +1342,7 @@ forward_search_command (char *regex, int from_tty) msg = (char *) re_comp (regex); if (msg) - error (msg); + error ("%s", msg); if (current_source_symtab == 0) select_source_symtab (0); @@ -1418,7 +1371,7 @@ forward_search_command (char *regex, int from_tty) while (1) { static char *buf = NULL; - register char *p; + char *p; int cursize, newsize; cursize = 256; @@ -1471,13 +1424,12 @@ forward_search_command (char *regex, int from_tty) fclose (stream); } -/* ARGSUSED */ static void reverse_search_command (char *regex, int from_tty) { - register int c; - register int desc; - register FILE *stream; + int c; + int desc; + FILE *stream; int line; char *msg; @@ -1485,7 +1437,7 @@ reverse_search_command (char *regex, int from_tty) msg = (char *) re_comp (regex); if (msg) - error (msg); + error ("%s", msg); if (current_source_symtab == 0) select_source_symtab (0); @@ -1515,7 +1467,7 @@ reverse_search_command (char *regex, int from_tty) { /* FIXME!!! We walk right off the end of buf if we get a long line!!! */ char buf[4096]; /* Should be reasonable??? */ - register char *p = buf; + char *p = buf; c = getc (stream); if (c == EOF) @@ -1586,7 +1538,7 @@ With no argument, reset the search path to $cdir:$cwd, the default.", if (dbx_commands) add_com_alias ("use", "directory", class_files, 0); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_cmd ("directories", no_class, show_directories, "Current search path for finding source files.\n\ @@ -1635,29 +1587,6 @@ The matching line number is also stored as the value of \"$_\"."); add_com_alias ("?", "reverse-search", class_files, 0); } - add_com ("list", class_files, list_command, - concat ("List specified function or line.\n\ -With no argument, lists ten more lines after or around previous listing.\n\ -\"list -\" lists the ten lines before a previous ten-line listing.\n\ -One argument specifies a line, and ten lines are listed around that line.\n\ -Two arguments with comma between specify starting and ending lines to list.\n\ -", "\ -Lines can be specified in these ways:\n\ - LINENUM, to list around that line in current file,\n\ - FILE:LINENUM, to list around that line in that file,\n\ - FUNCTION, to list around beginning of that function,\n\ - FILE:FUNCTION, to distinguish among like-named static functions.\n\ - *ADDRESS, to list around the line containing that address.\n\ -With two args if one is empty it stands for ten lines away from the other arg.", NULL)); - - if (!xdb_commands) - add_com_alias ("l", "list", class_files, 1); - else - add_com_alias ("v", "list", class_files, 1); - - if (dbx_commands) - add_com_alias ("file", "list", class_files, 1); - add_show_from_set (add_set_cmd ("listsize", class_support, var_uinteger, (char *) &lines_to_list, diff --git a/contrib/gdb/gdb/source.h b/contrib/gdb/gdb/source.h index 8dbf8517056..7cfed1ae0e8 100644 --- a/contrib/gdb/gdb/source.h +++ b/contrib/gdb/gdb/source.h @@ -21,6 +21,8 @@ #ifndef SOURCE_H #define SOURCE_H +struct symtab; + /* Open a source file given a symtab S. Returns a file descriptor or negative number for error. */ extern int open_source_file (struct symtab *s); @@ -31,4 +33,36 @@ extern int open_source_file (struct symtab *s); lines. */ extern void find_source_lines (struct symtab *s, int desc); +/* Return the first line listed by print_source_lines. + Used by command interpreters to request listing from + a previous point. */ +extern int get_first_line_listed (void); + +/* Return the default number of lines to print with commands like the + cli "list". The caller of print_source_lines must use this to + calculate the end line and use it in the call to print_source_lines + as it does not automatically use this value. */ +extern int get_lines_to_list (void); + +/* Return the current source file for listing and next line to list. + NOTE: The returned sal pc and end fields are not valid. */ +extern struct symtab_and_line get_current_source_symtab_and_line (void); + +/* If the current source file for listing is not set, try and get a default. + Usually called before get_current_source_symtab_and_line() is called. + It may err out if a default cannot be determined. + We must be cautious about where it is called, as it can recurse as the + process of determining a new default may call the caller! + Use get_current_source_symtab_and_line only to get whatever + we have without erroring out or trying to get a default. */ +extern void set_default_source_symtab_and_line (void); + +/* Return the current default file for listing and next line to list + (the returned sal pc and end fields are not valid.) + and set the current default to whatever is in SAL. + NOTE: The returned sal pc and end fields are not valid. */ +extern struct symtab_and_line set_current_source_symtab_and_line (const struct symtab_and_line *); + +/* Reset any information stored about a default file and line to print. */ +extern void clear_current_source_symtab_and_line (void); #endif diff --git a/contrib/gdb/gdb/sparc-nat.c b/contrib/gdb/gdb/sparc-nat.c index 7069c3a9ce3..955e65e3140 100644 --- a/contrib/gdb/gdb/sparc-nat.c +++ b/contrib/gdb/gdb/sparc-nat.c @@ -1,6 +1,6 @@ -/* Functions specific to running gdb native on a SPARC running SunOS4. - Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. +/* Native-dependent code for SPARC. + + Copyright 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -21,327 +21,310 @@ #include "defs.h" #include "inferior.h" -#include "target.h" -#include "gdbcore.h" #include "regcache.h" +#include "target.h" -#ifdef HAVE_SYS_PARAM_H -#include -#endif +#include "gdb_assert.h" #include +#include "gdb_string.h" #include -#include -#ifdef __linux__ -#include -#else +#include "gdb_wait.h" +#ifdef HAVE_MACHINE_REG_H #include #endif -#include -/* We don't store all registers immediately when requested, since they - get sent over in large chunks anyway. Instead, we accumulate most - of the changes and send them over once. "deferred_stores" keeps - track of which sets of registers we have locally-changed copies of, - so we only need send the groups that have changed. */ +#include "sparc-tdep.h" +#include "sparc-nat.h" -#define INT_REGS 1 -#define STACK_REGS 2 -#define FP_REGS 4 +/* With some trickery we can use the code in this file for most (if + not all) ptrace(2) based SPARC systems, which includes SunOS 4, + GNU/Linux and the various SPARC BSD's. -/* Fetch one or more registers from the inferior. REGNO == -1 to get - them all. We actually fetch more than requested, when convenient, - marking them as valid so we won't fetch them again. */ + First, we need a data structure for use with ptrace(2). SunOS has + `struct regs' and `struct fp_status' in . BSD's + have `struct reg' and `struct fpreg' in . GNU/Linux + has the same structures as SunOS 4, but they're in , + which is a kernel header. As a general rule we avoid including + GNU/Linux kernel headers. Fortunately GNU/Linux has a `gregset_t' + and a `fpregset_t' that are equivalent to `struct regs' and `struct + fp_status' in , which is automatically included by + . Settling on using the `gregset_t' and `fpregset_t' + typedefs, providing them for the other systems, therefore solves + the puzzle. */ -void -fetch_inferior_registers (int regno) -{ - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int i; +#ifdef HAVE_MACHINE_REG_H +#ifdef HAVE_STRUCT_REG +typedef struct reg gregset_t; +typedef struct fpreg fpregset_t; +#else +typedef struct regs gregset_t; +typedef struct fp_status fpregset_t; +#endif +#endif - /* We should never be called with deferred stores, because a prerequisite - for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */ - if (deferred_stores) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); +/* Second, we need to remap the BSD ptrace(2) requests to their SunOS + equivalents. GNU/Linux already follows SunOS here. */ - DO_DEFERRED_STORES; +#ifndef PTRACE_GETREGS +#define PTRACE_GETREGS PT_GETREGS +#endif - /* Global and Out regs are fetched directly, as well as the control - registers. If we're getting one of the in or local regs, - and the stack pointer has not yet been fetched, - we have to do that first, since they're found in memory relative - to the stack pointer. */ - if (regno < O7_REGNUM /* including -1 */ - || regno >= Y_REGNUM - || (!register_valid[SP_REGNUM] && regno < I7_REGNUM)) - { - if (0 != ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0)) - perror ("ptrace_getregs"); +#ifndef PTRACE_SETREGS +#define PTRACE_SETREGS PT_SETREGS +#endif - registers[REGISTER_BYTE (0)] = 0; - memcpy (®isters[REGISTER_BYTE (1)], &inferior_registers.r_g1, - 15 * REGISTER_RAW_SIZE (G0_REGNUM)); - *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; - *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; - *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc; - *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; +#ifndef PTRACE_GETFPREGS +#define PTRACE_GETFPREGS PT_GETFPREGS +#endif - for (i = G0_REGNUM; i <= O7_REGNUM; i++) - register_valid[i] = 1; - register_valid[Y_REGNUM] = 1; - register_valid[PS_REGNUM] = 1; - register_valid[PC_REGNUM] = 1; - register_valid[NPC_REGNUM] = 1; - /* If we don't set these valid, read_register_bytes() rereads - all the regs every time it is called! FIXME. */ - register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */ - register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */ - register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */ - } +#ifndef PTRACE_SETFPREGS +#define PTRACE_SETFPREGS PT_SETFPREGS +#endif - /* Floating point registers */ - if (regno == -1 || - regno == FPS_REGNUM || - (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)) - { - if (0 != ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fp_registers, - 0)) - perror ("ptrace_getfpregs"); - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, - sizeof inferior_fp_registers.fpu_fr); - memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], - &inferior_fp_registers.Fpu_fsr, - sizeof (FPU_FSR_TYPE)); - for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) - register_valid[i] = 1; - register_valid[FPS_REGNUM] = 1; - } +/* Register set description. */ +const struct sparc_gregset *sparc_gregset; +void (*sparc_supply_gregset) (const struct sparc_gregset *, + struct regcache *, int , const void *); +void (*sparc_collect_gregset) (const struct sparc_gregset *, + const struct regcache *, int, void *); +void (*sparc_supply_fpregset) (struct regcache *, int , const void *); +void (*sparc_collect_fpregset) (const struct regcache *, int , void *); +int (*sparc_gregset_supplies_p) (int); +int (*sparc_fpregset_supplies_p) (int); - /* These regs are saved on the stack by the kernel. Only read them - all (16 ptrace calls!) if we really need them. */ - if (regno == -1) - { - CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)]; - target_read_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM)); - for (i = L0_REGNUM; i <= I7_REGNUM; i++) - register_valid[i] = 1; - } - else if (regno >= L0_REGNUM && regno <= I7_REGNUM) - { - CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)]; - i = REGISTER_BYTE (regno); - if (register_valid[regno]) - printf_unfiltered ("register %d valid and read\n", regno); - target_read_memory (sp + i - REGISTER_BYTE (L0_REGNUM), - ®isters[i], REGISTER_RAW_SIZE (regno)); - register_valid[regno] = 1; - } -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (int regno) -{ - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int wanna_store = INT_REGS + STACK_REGS + FP_REGS; - - /* First decide which pieces of machine-state we need to modify. - Default for regno == -1 case is all pieces. */ - if (regno >= 0) - if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32) - { - wanna_store = FP_REGS; - } - else - { - if (regno == SP_REGNUM) - wanna_store = INT_REGS + STACK_REGS; - else if (regno < L0_REGNUM || regno > I7_REGNUM) - wanna_store = INT_REGS; - else if (regno == FPS_REGNUM) - wanna_store = FP_REGS; - else - wanna_store = STACK_REGS; - } - - /* See if we're forcing the stores to happen now, or deferring. */ - if (regno == -2) - { - wanna_store = deferred_stores; - deferred_stores = 0; - } - else - { - if (wanna_store == STACK_REGS) - { - /* Fall through and just store one stack reg. If we deferred - it, we'd have to store them all, or remember more info. */ - } - else - { - deferred_stores |= wanna_store; - return; - } - } - - if (wanna_store & STACK_REGS) - { - CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)]; - - if (regno < 0 || regno == SP_REGNUM) - { - if (!register_valid[L0_REGNUM + 5]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - target_write_memory (sp, - ®isters[REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM)); - } - else - { - if (!register_valid[regno]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - target_write_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM), - ®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno)); - } - - } - - if (wanna_store & INT_REGS) - { - if (!register_valid[G1_REGNUM]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - memcpy (&inferior_registers.r_g1, ®isters[REGISTER_BYTE (G1_REGNUM)], - 15 * REGISTER_RAW_SIZE (G1_REGNUM)); - - inferior_registers.r_ps = - *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)]; - inferior_registers.r_pc = - *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)]; - inferior_registers.r_npc = - *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)]; - inferior_registers.r_y = - *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)]; - - if (0 != ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_registers, 0)) - perror ("ptrace_setregs"); - } - - if (wanna_store & FP_REGS) - { - if (!register_valid[FP0_REGNUM + 9]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], - sizeof inferior_fp_registers.fpu_fr); - memcpy (&inferior_fp_registers.Fpu_fsr, - ®isters[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE)); - if (0 != - ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0)) - perror ("ptrace_setfpregs"); - } -} - -/* Provide registers to GDB from a core file. - - CORE_REG_SECT points to an array of bytes, which are the contents - of a `note' from a core file which BFD thinks might contain - register contents. CORE_REG_SIZE is its size. - - WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set - 2 --- the floating-point register set - - IGNORE is unused. */ - -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR ignore) -{ - - if (which == 0) - { - - /* Integer registers */ - -#define gregs ((struct regs *)core_reg_sect) - /* G0 *always* holds 0. */ - *(int *) ®isters[REGISTER_BYTE (0)] = 0; - - /* The globals and output registers. */ - memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, - 15 * REGISTER_RAW_SIZE (G1_REGNUM)); - *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps; - *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc; - *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc; - *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y; - - /* My best guess at where to get the locals and input - registers is exactly where they usually are, right above - the stack pointer. If the core dump was caused by a bus error - from blowing away the stack pointer (as is possible) then this - won't work, but it's worth the try. */ - { - int sp; - - sp = *(int *) ®isters[REGISTER_BYTE (SP_REGNUM)]; - if (0 != target_read_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM))) - { - /* fprintf_unfiltered so user can still use gdb */ - fprintf_unfiltered (gdb_stderr, - "Couldn't read input and local registers from core file\n"); - } - } - } - else if (which == 2) - { - - /* Floating point registers */ - -#define fpuregs ((struct fpu *) core_reg_sect) - if (core_reg_size >= sizeof (struct fpu)) - { - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs, - sizeof (fpuregs->fpu_regs)); - memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr, - sizeof (FPU_FSR_TYPE)); - } - else - fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n"); - } -} +/* Determine whether `gregset_t' contains register REGNUM. */ int -kernel_u_size (void) +sparc32_gregset_supplies_p (int regnum) { - return (sizeof (struct user)); + /* Integer registers. */ + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM) + || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM) + || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM)) + return 1; + + /* Control registers. */ + if (regnum == SPARC32_PC_REGNUM + || regnum == SPARC32_NPC_REGNUM + || regnum == SPARC32_PSR_REGNUM + || regnum == SPARC32_Y_REGNUM) + return 1; + + return 0; } - -/* Register that we are able to handle sparc core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ +/* Determine whether `fpregset_t' contains register REGNUM. */ -static struct core_fns sparc_core_fns = +int +sparc32_fpregset_supplies_p (int regnum) { - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; + /* Floating-point registers. */ + if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) + return 1; + + /* Control registers. */ + if (regnum == SPARC32_FSR_REGNUM) + return 1; + + return 0; +} + +/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this + for all registers (including the floating-point registers). */ void -_initialize_core_sparc (void) +fetch_inferior_registers (int regnum) { - add_core_fns (&sparc_core_fns); + struct regcache *regcache = current_regcache; + int pid; + + /* NOTE: cagney/2002-12-03: This code assumes that the currently + selected light weight processes' registers can be written + directly into the selected thread's register cache. This works + fine when given an 1:1 LWP:thread model (such as found on + GNU/Linux) but will, likely, have problems when used on an N:1 + (userland threads) or N:M (userland multiple LWP) model. In the + case of the latter two, the LWP's registers do not necessarily + belong to the selected thread (the LWP could be in the middle of + executing the thread switch code). + + These functions should instead be paramaterized with an explicit + object (struct regcache, struct thread_info?) into which the LWPs + registers can be written. */ + pid = TIDGET (inferior_ptid); + if (pid == 0) + pid = PIDGET (inferior_ptid); + + if (regnum == SPARC_G0_REGNUM) + { + regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL); + return; + } + + if (regnum == -1 || sparc_gregset_supplies_p (regnum)) + { + gregset_t regs; + + if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + sparc_supply_gregset (sparc_gregset, regcache, -1, ®s); + if (regnum != -1) + return; + } + + if (regnum == -1 || sparc_fpregset_supplies_p (regnum)) + { + fpregset_t fpregs; + + if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + sparc_supply_fpregset (regcache, -1, &fpregs); + } +} + +void +store_inferior_registers (int regnum) +{ + struct regcache *regcache = current_regcache; + int pid; + + /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers + about threaded assumptions. */ + pid = TIDGET (inferior_ptid); + if (pid == 0) + pid = PIDGET (inferior_ptid); + + if (regnum == -1 || sparc_gregset_supplies_p (regnum)) + { + gregset_t regs; + + if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + sparc_collect_gregset (sparc_gregset, regcache, regnum, ®s); + + if (ptrace (PTRACE_SETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't write registers"); + + /* Deal with the stack regs. */ + if (regnum == -1 || regnum == SPARC_SP_REGNUM + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)) + { + ULONGEST sp; + + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + sparc_collect_rwindow (regcache, sp, regnum); + } + + if (regnum != -1) + return; + } + + if (regnum == -1 || sparc_fpregset_supplies_p (regnum)) + { + fpregset_t fpregs, saved_fpregs; + + if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating-point registers"); + + memcpy (&saved_fpregs, &fpregs, sizeof (fpregs)); + sparc_collect_fpregset (regcache, regnum, &fpregs); + + /* Writing the floating-point registers will fail on NetBSD with + EINVAL if the inferior process doesn't have an FPU state + (i.e. if it didn't use the FPU yet). Therefore we don't try + to write the registers if nothing changed. */ + if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0) + { + if (ptrace (PTRACE_SETFPREGS, pid, + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't write floating-point registers"); + } + + if (regnum != -1) + return; + } +} + + +/* Fetch StackGhost Per-Process XOR cookie. */ + +LONGEST +sparc_xfer_wcookie (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, const void *writebuf, + ULONGEST offset, LONGEST len) +{ + unsigned long wcookie = 0; + char *buf = (char *)&wcookie; + + gdb_assert (object == TARGET_OBJECT_WCOOKIE); + gdb_assert (readbuf && writebuf == NULL); + + if (offset >= sizeof (unsigned long)) + return -1; + +#ifdef PT_WCOOKIE + /* If PT_WCOOKIE is defined (by ), assume we're + running on an OpenBSD release that uses StackGhost (3.1 or + later). As of release 3.4, OpenBSD doesn't use a randomized + cookie yet, but a future release probably will. */ + { + int pid; + + pid = TIDGET (inferior_ptid); + if (pid == 0) + pid = PIDGET (inferior_ptid); + + /* Sanity check. The proper type for a cookie is register_t, but + we can't assume that this type exists on all systems supported + by the code in this file. */ + gdb_assert (sizeof (wcookie) == sizeof (register_t)); + + /* Fetch the cookie. */ + if (ptrace (PT_WCOOKIE, pid, (PTRACE_ARG3_TYPE) &wcookie, 0) == -1) + { + if (errno != EINVAL) + perror_with_name ("Couldn't get StackGhost cookie"); + + /* Although PT_WCOOKIE is defined on OpenBSD 3.1 and later, + the request wasn't implemented until after OpenBSD 3.4. If + the kernel doesn't support the PT_WCOOKIE request, assume + we're running on a kernel that uses non-randomized cookies. */ + wcookie = 0x3; + } + } +#endif /* PT_WCOOKIE */ + + if (len > sizeof (unsigned long) - offset) + len = sizeof (unsigned long) - offset; + + memcpy (readbuf, buf + offset, len); + return len; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc_nat (void); + +void +_initialize_sparc_nat (void) +{ + /* Deafult to using SunOS 4 register sets. */ + if (sparc_gregset == NULL) + sparc_gregset = &sparc32_sunos4_gregset; + if (sparc_supply_gregset == NULL) + sparc_supply_gregset = sparc32_supply_gregset; + if (sparc_collect_gregset == NULL) + sparc_collect_gregset = sparc32_collect_gregset; + if (sparc_supply_fpregset == NULL) + sparc_supply_fpregset = sparc32_supply_fpregset; + if (sparc_collect_fpregset == NULL) + sparc_collect_fpregset = sparc32_collect_fpregset; + if (sparc_gregset_supplies_p == NULL) + sparc_gregset_supplies_p = sparc32_gregset_supplies_p; + if (sparc_fpregset_supplies_p == NULL) + sparc_fpregset_supplies_p = sparc32_fpregset_supplies_p; } diff --git a/contrib/gdb/gdb/sparc-nat.h b/contrib/gdb/gdb/sparc-nat.h new file mode 100644 index 00000000000..8f99b1eea11 --- /dev/null +++ b/contrib/gdb/gdb/sparc-nat.h @@ -0,0 +1,40 @@ +/* Native-dependent code for SPARC. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef SPARC_NAT_H +#define SPARC_NAT_H 1 + +struct sparc_gregset; + +extern const struct sparc_gregset *sparc_gregset; +extern void (*sparc_supply_gregset) (const struct sparc_gregset *, + struct regcache *, int , const void *); +extern void (*sparc_collect_gregset) (const struct sparc_gregset *, + const struct regcache *, int, void *); +extern void (*sparc_supply_fpregset) (struct regcache *, int , const void *); +extern void (*sparc_collect_fpregset) (const struct regcache *, int , void *); +extern int (*sparc_gregset_supplies_p) (int); +extern int (*sparc_fpregset_supplies_p) (int); + +extern int sparc32_gregset_supplies_p (int regnum); +extern int sparc32_fpregset_supplies_p (int regnum); + +#endif /* sparc-nat.h */ diff --git a/contrib/gdb/gdb/sparc-sol2-nat.c b/contrib/gdb/gdb/sparc-sol2-nat.c new file mode 100644 index 00000000000..61ca7120f32 --- /dev/null +++ b/contrib/gdb/gdb/sparc-sol2-nat.c @@ -0,0 +1,98 @@ +/* Native-dependent code for Solaris SPARC. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "regcache.h" + +#include +#include "gregset.h" + +#include "sparc-tdep.h" + +/* This file provids the (temporary) glue between the Solaris SPARC + target dependent code and the machine independent SVR4 /proc + support. */ + +/* Solaris 7 (Solaris 2.7, SunOS 5.7) and up support two process data + models, the traditional 32-bit data model (ILP32) and the 64-bit + data model (LP64). The format of /proc depends on the data model + of the observer (the controlling process, GDB in our case). The + Solaris header files conveniently define PR_MODEL_NATIVE to the + data model of the controlling process. If its value is + PR_MODEL_LP64, we know that GDB is being compiled as a 64-bit + program. + + GNU/Linux uses the same formats as Solaris for its core files (but + not for ptrace(2)). The GNU/Linux headers don't define + PR_MODEL_NATIVE though. Therefore we rely on the __arch64__ define + provided by GCC to determine the appropriate data model. + + Note that a 32-bit GDB won't be able to debug a 64-bit target + process using /proc on Solaris. */ + +#if (defined (__arch64__) || \ + (defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64))) + +#include "sparc64-tdep.h" + +#define sparc_supply_gregset sparc64_supply_gregset +#define sparc_supply_fpregset sparc64_supply_fpregset +#define sparc_collect_gregset sparc64_collect_gregset +#define sparc_collect_fpregset sparc64_collect_fpregset + +#define sparc_sol2_gregset sparc64_sol2_gregset +#define sparc_sol2_fpregset sparc64_sol2_fpregset + +#else + +#define sparc_supply_gregset sparc32_supply_gregset +#define sparc_supply_fpregset sparc32_supply_fpregset +#define sparc_collect_gregset sparc32_collect_gregset +#define sparc_collect_fpregset sparc32_collect_fpregset + +#define sparc_sol2_gregset sparc32_sol2_gregset +#define sparc_sol2_fpregset sparc32_sol2_fpregset + +#endif + +void +supply_gregset (prgregset_t *gregs) +{ + sparc_supply_gregset (&sparc_sol2_gregset, current_regcache, -1, gregs); +} + +void +supply_fpregset (prfpregset_t *fpregs) +{ + sparc_supply_fpregset (current_regcache, -1, fpregs); +} + +void +fill_gregset (prgregset_t *gregs, int regnum) +{ + sparc_collect_gregset (&sparc_sol2_gregset, current_regcache, regnum, gregs); +} + +void +fill_fpregset (prfpregset_t *fpregs, int regnum) +{ + sparc_collect_fpregset (current_regcache, regnum, fpregs); +} diff --git a/contrib/gdb/gdb/sparc-sol2-tdep.c b/contrib/gdb/gdb/sparc-sol2-tdep.c new file mode 100644 index 00000000000..5f65b7826d1 --- /dev/null +++ b/contrib/gdb/gdb/sparc-sol2-tdep.c @@ -0,0 +1,201 @@ +/* Target-dependent code for Solaris SPARC. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "symtab.h" +#include "objfiles.h" +#include "osabi.h" +#include "regcache.h" +#include "target.h" +#include "trad-frame.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "sparc-tdep.h" + +/* From . */ +const struct sparc_gregset sparc32_sol2_gregset = +{ + 32 * 4, /* %psr */ + 33 * 4, /* %pc */ + 34 * 4, /* %npc */ + 35 * 4, /* %y */ + 36 * 4, /* %wim */ + 37 * 4, /* %tbr */ + 1 * 4, /* %g1 */ + 16 * 4, /* %l0 */ +}; + + +/* The Solaris signal trampolines reside in libc. For normal signals, + the function `sigacthandler' is used. This signal trampoline will + call the signal handler using the System V calling convention, + where the third argument is a pointer to an instance of + `ucontext_t', which has a member `uc_mcontext' that contains the + saved registers. Incidentally, the kernel passes the `ucontext_t' + pointer as the third argument of the signal trampoline too, and + `sigacthandler' simply passes it on. However, if you link your + program with "-L/usr/ucblib -R/usr/ucblib -lucb", the function + `ucbsigvechandler' will be used, which invokes the using the BSD + convention, where the third argument is a pointer to an instance of + `struct sigcontext'. It is the `ucbsigvechandler' function that + converts the `ucontext_t' to a `sigcontext', and back. Unless the + signal handler modifies the `struct sigcontext' we can safely + ignore this. */ + +int +sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + return (name && (strcmp (name, "sigacthandler") == 0 + || strcmp (name, "ucbsigvechandler") == 0)); +} + +static struct sparc_frame_cache * +sparc32_sol2_sigtramp_frame_cache (struct frame_info *next_frame, + void **this_cache) +{ + struct sparc_frame_cache *cache; + CORE_ADDR mcontext_addr, addr; + int regnum; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + gdb_assert (cache == *this_cache); + + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + /* The third argument is a pointer to an instance of `ucontext_t', + which has a member `uc_mcontext' that contains the saved + registers. */ + regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM); + mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 40; + + cache->saved_regs[SPARC32_PSR_REGNUM].addr = mcontext_addr + 0 * 4; + cache->saved_regs[SPARC32_PC_REGNUM].addr = mcontext_addr + 1 * 4; + cache->saved_regs[SPARC32_NPC_REGNUM].addr = mcontext_addr + 2 * 4; + cache->saved_regs[SPARC32_Y_REGNUM].addr = mcontext_addr + 3 * 4; + + /* Since %g0 is always zero, keep the identity encoding. */ + for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4; + regnum <= SPARC_O7_REGNUM; regnum++, addr += 4) + cache->saved_regs[regnum].addr = addr; + + if (get_frame_memory_unsigned (next_frame, mcontext_addr + 19 * 4, 4)) + { + /* The register windows haven't been flushed. */ + for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) + trad_frame_set_unknown (cache->saved_regs, regnum); + } + else + { + addr = cache->saved_regs[SPARC_SP_REGNUM].addr; + addr = get_frame_memory_unsigned (next_frame, addr, 4); + for (regnum = SPARC_L0_REGNUM; + regnum <= SPARC_I7_REGNUM; regnum++, addr += 4) + cache->saved_regs[regnum].addr = addr; + } + + return cache; +} + +static void +sparc32_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache); + + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + sparc32_sol2_sigtramp_frame_this_id, + sparc32_sol2_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +sparc32_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (sparc_sol2_pc_in_sigtramp (pc, name)) + return &sparc32_sol2_sigtramp_frame_unwind; + + return NULL; +} + + +void +sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Solaris has SVR4-style shared libraries... */ + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + + /* ...which means that we need some special handling when doing + prologue analysis. */ + tdep->plt_entry_size = 12; + + /* Solaris has kernel-assisted single-stepping support. */ + set_gdbarch_software_single_step (gdbarch, NULL); + + set_gdbarch_pc_in_sigtramp (gdbarch, sparc_sol2_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, sparc32_sol2_sigtramp_frame_sniffer); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc_sol2_tdep (void); + +void +_initialize_sparc_sol2_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_sparc, 0, + GDB_OSABI_SOLARIS, sparc32_sol2_init_abi); +} diff --git a/contrib/gdb/gdb/sparc-tdep.c b/contrib/gdb/gdb/sparc-tdep.c index b2380b4f135..ac8eb48f439 100644 --- a/contrib/gdb/gdb/sparc-tdep.c +++ b/contrib/gdb/gdb/sparc-tdep.c @@ -1,6 +1,6 @@ -/* Target-dependent code for the SPARC for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* Target-dependent code for SPARC. + + Copyright 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -19,150 +19,61 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* ??? Support for calling functions from gdb in sparc64 is unfinished. */ - #include "defs.h" #include "arch-utils.h" +#include "dis-asm.h" +#include "floatformat.h" #include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "gdbtypes.h" #include "inferior.h" -#include "obstack.h" +#include "symtab.h" +#include "objfiles.h" +#include "osabi.h" +#include "regcache.h" #include "target.h" #include "value.h" -#include "bfd.h" + +#include "gdb_assert.h" #include "gdb_string.h" -#include "regcache.h" -#ifdef USE_PROC_FS -#include -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" -#endif +#include "sparc-tdep.h" -#include "gdbcore.h" +struct regset; -#include "symfile.h" /* for 'entry_point_address' */ +/* This file implements the The SPARC 32-bit ABI as defined by the + section "Low-Level System Information" of the SPARC Compliance + Definition (SCD) 2.4.1, which is the 32-bit System V psABI for + SPARC. The SCD lists changes with respect to the origional 32-bit + psABI as defined in the "System V ABI, SPARC Processor + Supplement". -/* - * Some local macros that have multi-arch and non-multi-arch versions: - */ + Note that if we talk about SunOS, we mean SunOS 4.x, which was + BSD-based, which is sometimes (retroactively?) referred to as + Solaris 1.x. If we talk about Solaris we mean Solaris 2.x and + above (Solaris 7, 8 and 9 are nothing but Solaris 2.7, 2.8 and 2.9 + suffering from severe version number inflation). Solaris 2.x is + also known as SunOS 5.x, since that's what uname(1) says. Solaris + 2.x is SVR4-based. */ -#if (GDB_MULTI_ARCH > 0) +/* Please use the sparc32_-prefix for 32-bit specific code, the + sparc64_-prefix for 64-bit specific code and the sparc_-prefix for + code that can handle both. The 64-bit specific code lives in + sparc64-tdep.c; don't add any here. */ -/* Does the target have Floating Point registers? */ -#define SPARC_HAS_FPU (gdbarch_tdep (current_gdbarch)->has_fpu) -/* Number of bytes devoted to Floating Point registers: */ -#define FP_REGISTER_BYTES (gdbarch_tdep (current_gdbarch)->fp_register_bytes) -/* Highest numbered Floating Point register. */ -#define FP_MAX_REGNUM (gdbarch_tdep (current_gdbarch)->fp_max_regnum) -/* Size of a general (integer) register: */ -#define SPARC_INTREG_SIZE (gdbarch_tdep (current_gdbarch)->intreg_size) -/* Offset within the call dummy stack of the saved registers. */ -#define DUMMY_REG_SAVE_OFFSET (gdbarch_tdep (current_gdbarch)->reg_save_offset) +/* The SPARC Floating-Point Quad-Precision format is similar to + big-endian IA-64 Quad-recision format. */ +#define floatformat_sparc_quad floatformat_ia64_quad_big -#else /* non-multi-arch */ +/* The stack pointer is offset from the stack frame by a BIAS of 2047 + (0x7ff) for 64-bit code. BIAS is likely to be defined on SPARC + hosts, so undefine it first. */ +#undef BIAS +#define BIAS 2047 - -/* Does the target have Floating Point registers? */ -#if defined(TARGET_SPARCLET) || defined(TARGET_SPARCLITE) -#define SPARC_HAS_FPU 0 -#else -#define SPARC_HAS_FPU 1 -#endif - -/* Number of bytes devoted to Floating Point registers: */ -#if (GDB_TARGET_IS_SPARC64) -#define FP_REGISTER_BYTES (64 * 4) -#else -#if (SPARC_HAS_FPU) -#define FP_REGISTER_BYTES (32 * 4) -#else -#define FP_REGISTER_BYTES 0 -#endif -#endif - -/* Highest numbered Floating Point register. */ -#if (GDB_TARGET_IS_SPARC64) -#define FP_MAX_REGNUM (FP0_REGNUM + 48) -#else -#define FP_MAX_REGNUM (FP0_REGNUM + 32) -#endif - -/* Size of a general (integer) register: */ -#define SPARC_INTREG_SIZE (REGISTER_RAW_SIZE (G0_REGNUM)) - -/* Offset within the call dummy stack of the saved registers. */ -#if (GDB_TARGET_IS_SPARC64) -#define DUMMY_REG_SAVE_OFFSET (128 + 16) -#else -#define DUMMY_REG_SAVE_OFFSET 0x60 -#endif - -#endif /* GDB_MULTI_ARCH */ - -struct gdbarch_tdep - { - int has_fpu; - int fp_register_bytes; - int y_regnum; - int fp_max_regnum; - int intreg_size; - int reg_save_offset; - int call_dummy_call_offset; - int print_insn_mach; - }; - -/* Now make GDB_TARGET_IS_SPARC64 a runtime test. */ -/* FIXME MVS: or try testing bfd_arch_info.arch and bfd_arch_info.mach ... - * define GDB_TARGET_IS_SPARC64 \ - * (TARGET_ARCHITECTURE->arch == bfd_arch_sparc && \ - * (TARGET_ARCHITECTURE->mach == bfd_mach_sparc_v9 || \ - * TARGET_ARCHITECTURE->mach == bfd_mach_sparc_v9a)) - */ - -/* From infrun.c */ -extern int stop_after_trap; - -/* We don't store all registers immediately when requested, since they - get sent over in large chunks anyway. Instead, we accumulate most - of the changes and send them over once. "deferred_stores" keeps - track of which sets of registers we have locally-changed copies of, - so we only need send the groups that have changed. */ - -int deferred_stores = 0; /* Accumulated stores we want to do eventually. */ - - -/* Some machines, such as Fujitsu SPARClite 86x, have a bi-endian mode - where instructions are big-endian and data are little-endian. - This flag is set when we detect that the target is of this type. */ - -int bi_endian = 0; - - -/* Fetch a single instruction. Even on bi-endian machines - such as sparc86x, instructions are always big-endian. */ - -static unsigned long -fetch_instruction (CORE_ADDR pc) -{ - unsigned long retval; - int i; - unsigned char buf[4]; - - read_memory (pc, buf, sizeof (buf)); - - /* Start at the most significant end of the integer, and work towards - the least significant. */ - retval = 0; - for (i = 0; i < sizeof (buf); ++i) - retval = (retval << 8) | buf[i]; - return retval; -} - - -/* Branches with prediction are treated like their non-predicting cousins. */ -/* FIXME: What about floating point branches? */ - -/* Macros to extract fields from sparc instructions. */ +/* Macros to extract fields from SPARC instructions. */ #define X_OP(i) (((i) >> 30) & 0x3) #define X_RD(i) (((i) >> 25) & 0x1f) #define X_A(i) (((i) >> 29) & 1) @@ -170,3040 +81,1408 @@ fetch_instruction (CORE_ADDR pc) #define X_OP2(i) (((i) >> 22) & 0x7) #define X_IMM22(i) ((i) & 0x3fffff) #define X_OP3(i) (((i) >> 19) & 0x3f) -#define X_RS1(i) (((i) >> 14) & 0x1f) #define X_I(i) (((i) >> 13) & 1) -#define X_IMM13(i) ((i) & 0x1fff) /* Sign extension macros. */ -#define X_SIMM13(i) ((X_IMM13 (i) ^ 0x1000) - 0x1000) #define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000) -#define X_CC(i) (((i) >> 20) & 3) -#define X_P(i) (((i) >> 19) & 1) #define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000) -#define X_RCOND(i) (((i) >> 25) & 7) -#define X_DISP16(i) ((((((i) >> 6) && 0xc000) | ((i) & 0x3fff)) ^ 0x8000) - 0x8000) -#define X_FCN(i) (((i) >> 25) & 31) -typedef enum +/* Fetch the instruction at PC. Instructions are always big-endian + even if the processor operates in little-endian mode. */ + +unsigned long +sparc_fetch_instruction (CORE_ADDR pc) { - Error, not_branch, bicc, bicca, ba, baa, ticc, ta, done_retry -} branch_type; + unsigned char buf[4]; + unsigned long insn; + int i; -/* Simulate single-step ptrace call for sun4. Code written by Gary - Beihl (beihl@mcc.com). */ + /* If we can't read the instruction at PC, return zero. */ + if (target_read_memory (pc, buf, sizeof (buf))) + return 0; -/* npc4 and next_pc describe the situation at the time that the - step-breakpoint was set, not necessary the current value of NPC_REGNUM. */ -static CORE_ADDR next_pc, npc4, target; -static int brknpc4, brktrg; -typedef char binsn_quantum[BREAKPOINT_MAX]; -static binsn_quantum break_mem[3]; - -static branch_type isbranch (long, CORE_ADDR, CORE_ADDR *); - -/* single_step() is called just before we want to resume the inferior, - if we want to single-step it but there is no hardware or kernel single-step - support (as on all SPARCs). We find all the possible targets of the - coming instruction and breakpoint them. - - single_step is also called just after the inferior stops. If we had - set up a simulated single-step, we undo our damage. */ - -void -sparc_software_single_step (enum target_signal ignore, /* pid, but we don't need it */ - int insert_breakpoints_p) -{ - branch_type br; - CORE_ADDR pc; - long pc_instruction; - - if (insert_breakpoints_p) - { - /* Always set breakpoint for NPC. */ - next_pc = read_register (NPC_REGNUM); - npc4 = next_pc + 4; /* branch not taken */ - - target_insert_breakpoint (next_pc, break_mem[0]); - /* printf_unfiltered ("set break at %x\n",next_pc); */ - - pc = read_register (PC_REGNUM); - pc_instruction = fetch_instruction (pc); - br = isbranch (pc_instruction, pc, &target); - brknpc4 = brktrg = 0; - - if (br == bicca) - { - /* Conditional annulled branch will either end up at - npc (if taken) or at npc+4 (if not taken). - Trap npc+4. */ - brknpc4 = 1; - target_insert_breakpoint (npc4, break_mem[1]); - } - else if (br == baa && target != next_pc) - { - /* Unconditional annulled branch will always end up at - the target. */ - brktrg = 1; - target_insert_breakpoint (target, break_mem[2]); - } - else if (GDB_TARGET_IS_SPARC64 && br == done_retry) - { - brktrg = 1; - target_insert_breakpoint (target, break_mem[2]); - } - } - else - { - /* Remove breakpoints */ - target_remove_breakpoint (next_pc, break_mem[0]); - - if (brknpc4) - target_remove_breakpoint (npc4, break_mem[1]); - - if (brktrg) - target_remove_breakpoint (target, break_mem[2]); - } + insn = 0; + for (i = 0; i < sizeof (buf); i++) + insn = (insn << 8) | buf[i]; + return insn; } -struct frame_extra_info + +/* OpenBSD/sparc includes StackGhost, which according to the author's + website http://stackghost.cerias.purdue.edu "... transparently and + automatically protects applications' stack frames; more + specifically, it guards the return pointers. The protection + mechanisms require no application source or binary modification and + imposes only a negligible performance penalty." + + The same website provides the following description of how + StackGhost works: + + "StackGhost interfaces with the kernel trap handler that would + normally write out registers to the stack and the handler that + would read them back in. By XORing a cookie into the + return-address saved in the user stack when it is actually written + to the stack, and then XOR it out when the return-address is pulled + from the stack, StackGhost can cause attacker corrupted return + pointers to behave in a manner the attacker cannot predict. + StackGhost can also use several unused bits in the return pointer + to detect a smashed return pointer and abort the process." + + For GDB this means that whenever we're reading %i7 from a stack + frame's window save area, we'll have to XOR the cookie. + + More information on StackGuard can be found on in: + + Mike Frantzen and Mike Shuey. "StackGhost: Hardware Facilitated + Stack Protection." 2001. Published in USENIX Security Symposium + '01. */ + +/* Fetch StackGhost Per-Process XOR cookie. */ + +ULONGEST +sparc_fetch_wcookie (void) { - CORE_ADDR bottom; - int in_prologue; - int flat; - /* Following fields only relevant for flat frames. */ - CORE_ADDR pc_addr; - CORE_ADDR fp_addr; - /* Add this to ->frame to get the value of the stack pointer at the - time of the register saves. */ - int sp_offset; -}; + struct target_ops *ops = ¤t_target; + char buf[8]; + int len; -/* Call this for each newly created frame. For SPARC, we need to - calculate the bottom of the frame, and do some extra work if the - prologue has been generated via the -mflat option to GCC. In - particular, we need to know where the previous fp and the pc have - been stashed, since their exact position within the frame may vary. */ + len = target_read_partial (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8); + if (len == -1) + return 0; -void -sparc_init_extra_frame_info (int fromleaf, struct frame_info *fi) -{ - char *name; - CORE_ADDR prologue_start, prologue_end; - int insn; + /* We should have either an 32-bit or an 64-bit cookie. */ + gdb_assert (len == 4 || len == 8); - fi->extra_info = (struct frame_extra_info *) - frame_obstack_alloc (sizeof (struct frame_extra_info)); - frame_saved_regs_zalloc (fi); - - fi->extra_info->bottom = - (fi->next ? - (fi->frame == fi->next->frame ? fi->next->extra_info->bottom : - fi->next->frame) : read_sp ()); - - /* If fi->next is NULL, then we already set ->frame by passing read_fp() - to create_new_frame. */ - if (fi->next) - { - char *buf; - - buf = alloca (MAX_REGISTER_RAW_SIZE); - - /* Compute ->frame as if not flat. If it is flat, we'll change - it later. */ - if (fi->next->next != NULL - && (fi->next->next->signal_handler_caller - || frame_in_dummy (fi->next->next)) - && frameless_look_for_prologue (fi->next)) - { - /* A frameless function interrupted by a signal did not change - the frame pointer, fix up frame pointer accordingly. */ - fi->frame = FRAME_FP (fi->next); - fi->extra_info->bottom = fi->next->extra_info->bottom; - } - else - { - /* Should we adjust for stack bias here? */ - get_saved_register (buf, 0, 0, fi, FP_REGNUM, 0); - fi->frame = extract_address (buf, REGISTER_RAW_SIZE (FP_REGNUM)); - - if (GDB_TARGET_IS_SPARC64 && (fi->frame & 1)) - fi->frame += 2047; - } - } - - /* Decide whether this is a function with a ``flat register window'' - frame. For such functions, the frame pointer is actually in %i7. */ - fi->extra_info->flat = 0; - fi->extra_info->in_prologue = 0; - if (find_pc_partial_function (fi->pc, &name, &prologue_start, &prologue_end)) - { - /* See if the function starts with an add (which will be of a - negative number if a flat frame) to the sp. FIXME: Does not - handle large frames which will need more than one instruction - to adjust the sp. */ - insn = fetch_instruction (prologue_start); - if (X_OP (insn) == 2 && X_RD (insn) == 14 && X_OP3 (insn) == 0 - && X_I (insn) && X_SIMM13 (insn) < 0) - { - int offset = X_SIMM13 (insn); - - /* Then look for a save of %i7 into the frame. */ - insn = fetch_instruction (prologue_start + 4); - if (X_OP (insn) == 3 - && X_RD (insn) == 31 - && X_OP3 (insn) == 4 - && X_RS1 (insn) == 14) - { - char *buf; - - buf = alloca (MAX_REGISTER_RAW_SIZE); - - /* We definitely have a flat frame now. */ - fi->extra_info->flat = 1; - - fi->extra_info->sp_offset = offset; - - /* Overwrite the frame's address with the value in %i7. */ - get_saved_register (buf, 0, 0, fi, I7_REGNUM, 0); - fi->frame = extract_address (buf, REGISTER_RAW_SIZE (I7_REGNUM)); - - if (GDB_TARGET_IS_SPARC64 && (fi->frame & 1)) - fi->frame += 2047; - - /* Record where the fp got saved. */ - fi->extra_info->fp_addr = - fi->frame + fi->extra_info->sp_offset + X_SIMM13 (insn); - - /* Also try to collect where the pc got saved to. */ - fi->extra_info->pc_addr = 0; - insn = fetch_instruction (prologue_start + 12); - if (X_OP (insn) == 3 - && X_RD (insn) == 15 - && X_OP3 (insn) == 4 - && X_RS1 (insn) == 14) - fi->extra_info->pc_addr = - fi->frame + fi->extra_info->sp_offset + X_SIMM13 (insn); - } - } - else - { - /* Check if the PC is in the function prologue before a SAVE - instruction has been executed yet. If so, set the frame - to the current value of the stack pointer and set - the in_prologue flag. */ - CORE_ADDR addr; - struct symtab_and_line sal; - - sal = find_pc_line (prologue_start, 0); - if (sal.line == 0) /* no line info, use PC */ - prologue_end = fi->pc; - else if (sal.end < prologue_end) - prologue_end = sal.end; - if (fi->pc < prologue_end) - { - for (addr = prologue_start; addr < fi->pc; addr += 4) - { - insn = read_memory_integer (addr, 4); - if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c) - break; /* SAVE seen, stop searching */ - } - if (addr >= fi->pc) - { - fi->extra_info->in_prologue = 1; - fi->frame = read_register (SP_REGNUM); - } - } - } - } - if (fi->next && fi->frame == 0) - { - /* Kludge to cause init_prev_frame_info to destroy the new frame. */ - fi->frame = fi->next->frame; - fi->pc = fi->next->pc; - } + return extract_unsigned_integer (buf, len); } + -CORE_ADDR -sparc_frame_chain (struct frame_info *frame) -{ - /* Value that will cause FRAME_CHAIN_VALID to not worry about the chain - value. If it really is zero, we detect it later in - sparc_init_prev_frame. */ - return (CORE_ADDR) 1; -} - -CORE_ADDR -sparc_extract_struct_value_address (char *regbuf) -{ - return extract_address (regbuf + REGISTER_BYTE (O0_REGNUM), - REGISTER_RAW_SIZE (O0_REGNUM)); -} - -/* Find the pc saved in frame FRAME. */ - -CORE_ADDR -sparc_frame_saved_pc (struct frame_info *frame) -{ - char *buf; - CORE_ADDR addr; - - buf = alloca (MAX_REGISTER_RAW_SIZE); - if (frame->signal_handler_caller) - { - /* This is the signal trampoline frame. - Get the saved PC from the sigcontext structure. */ - -#ifndef SIGCONTEXT_PC_OFFSET -#define SIGCONTEXT_PC_OFFSET 12 -#endif - - CORE_ADDR sigcontext_addr; - char *scbuf; - int saved_pc_offset = SIGCONTEXT_PC_OFFSET; - char *name = NULL; - - scbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT); - - /* Solaris2 ucbsigvechandler passes a pointer to a sigcontext - as the third parameter. The offset to the saved pc is 12. */ - find_pc_partial_function (frame->pc, &name, - (CORE_ADDR *) NULL, (CORE_ADDR *) NULL); - if (name && STREQ (name, "ucbsigvechandler")) - saved_pc_offset = 12; - - /* The sigcontext address is contained in register O2. */ - get_saved_register (buf, (int *) NULL, (CORE_ADDR *) NULL, - frame, O0_REGNUM + 2, (enum lval_type *) NULL); - sigcontext_addr = extract_address (buf, REGISTER_RAW_SIZE (O0_REGNUM + 2)); - - /* Don't cause a memory_error when accessing sigcontext in case the - stack layout has changed or the stack is corrupt. */ - target_read_memory (sigcontext_addr + saved_pc_offset, - scbuf, sizeof (scbuf)); - return extract_address (scbuf, sizeof (scbuf)); - } - else if (frame->extra_info->in_prologue || - (frame->next != NULL && - (frame->next->signal_handler_caller || - frame_in_dummy (frame->next)) && - frameless_look_for_prologue (frame))) - { - /* A frameless function interrupted by a signal did not save - the PC, it is still in %o7. */ - get_saved_register (buf, (int *) NULL, (CORE_ADDR *) NULL, - frame, O7_REGNUM, (enum lval_type *) NULL); - return PC_ADJUST (extract_address (buf, SPARC_INTREG_SIZE)); - } - if (frame->extra_info->flat) - addr = frame->extra_info->pc_addr; - else - addr = frame->extra_info->bottom + FRAME_SAVED_I0 + - SPARC_INTREG_SIZE * (I7_REGNUM - I0_REGNUM); - - if (addr == 0) - /* A flat frame leaf function might not save the PC anywhere, - just leave it in %o7. */ - return PC_ADJUST (read_register (O7_REGNUM)); - - read_memory (addr, buf, SPARC_INTREG_SIZE); - return PC_ADJUST (extract_address (buf, SPARC_INTREG_SIZE)); -} - -/* Since an individual frame in the frame cache is defined by two - arguments (a frame pointer and a stack pointer), we need two - arguments to get info for an arbitrary stack frame. This routine - takes two arguments and makes the cached frames look as if these - two arguments defined a frame on the cache. This allows the rest - of info frame to extract the important arguments without - difficulty. */ - -struct frame_info * -setup_arbitrary_frame (int argc, CORE_ADDR *argv) -{ - struct frame_info *frame; - - if (argc != 2) - error ("Sparc frame specifications require two arguments: fp and sp"); - - frame = create_new_frame (argv[0], 0); - - if (!frame) - internal_error (__FILE__, __LINE__, - "create_new_frame returned invalid frame"); - - frame->extra_info->bottom = argv[1]; - frame->pc = FRAME_SAVED_PC (frame); - return frame; -} - -/* Given a pc value, skip it forward past the function prologue by - disassembling instructions that appear to be a prologue. - - If FRAMELESS_P is set, we are only testing to see if the function - is frameless. This allows a quicker answer. - - This routine should be more specific in its actions; making sure - that it uses the same register in the initial prologue section. */ - -static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *, - CORE_ADDR *); +/* Return the contents if register REGNUM as an address. */ static CORE_ADDR -examine_prologue (CORE_ADDR start_pc, int frameless_p, struct frame_info *fi, - CORE_ADDR *saved_regs) +sparc_address_from_register (int regnum) { - int insn; + ULONGEST addr; + + regcache_cooked_read_unsigned (current_regcache, regnum, &addr); + return addr; +} + + +/* The functions on this page are intended to be used to classify + function arguments. */ + +/* Check whether TYPE is "Integral or Pointer". */ + +static int +sparc_integral_or_pointer_p (const struct type *type) +{ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_BOOL: + case TYPE_CODE_CHAR: + case TYPE_CODE_ENUM: + case TYPE_CODE_RANGE: + { + /* We have byte, half-word, word and extended-word/doubleword + integral types. The doubleword is an extension to the + origional 32-bit ABI by the SCD 2.4.x. */ + int len = TYPE_LENGTH (type); + return (len == 1 || len == 2 || len == 4 || len == 8); + } + return 1; + case TYPE_CODE_PTR: + case TYPE_CODE_REF: + { + /* Allow either 32-bit or 64-bit pointers. */ + int len = TYPE_LENGTH (type); + return (len == 4 || len == 8); + } + return 1; + default: + break; + } + + return 0; +} + +/* Check whether TYPE is "Floating". */ + +static int +sparc_floating_p (const struct type *type) +{ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_FLT: + { + int len = TYPE_LENGTH (type); + return (len == 4 || len == 8 || len == 16); + } + default: + break; + } + + return 0; +} + +/* Check whether TYPE is "Structure or Union". */ + +static int +sparc_structure_or_union_p (const struct type *type) +{ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + return 1; + default: + break; + } + + return 0; +} + +/* Register information. */ + +static const char *sparc32_register_names[] = +{ + "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", + "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", + "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", + + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", + + "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" +}; + +/* Total number of registers. */ +#define SPARC32_NUM_REGS ARRAY_SIZE (sparc32_register_names) + +/* We provide the aliases %d0..%d30 for the floating registers as + "psuedo" registers. */ + +static const char *sparc32_pseudo_register_names[] = +{ + "d0", "d2", "d4", "d6", "d8", "d10", "d12", "d14", + "d16", "d18", "d20", "d22", "d24", "d26", "d28", "d30" +}; + +/* Total number of pseudo registers. */ +#define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names) + +/* Return the name of register REGNUM. */ + +static const char * +sparc32_register_name (int regnum) +{ + if (regnum >= 0 && regnum < SPARC32_NUM_REGS) + return sparc32_register_names[regnum]; + + if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS) + return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS]; + + return NULL; +} + +/* Return the GDB type object for the "standard" data type of data in + register REGNUM. */ + +static struct type * +sparc32_register_type (struct gdbarch *gdbarch, int regnum) +{ + if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) + return builtin_type_float; + + if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) + return builtin_type_double; + + if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM) + return builtin_type_void_data_ptr; + + if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM) + return builtin_type_void_func_ptr; + + return builtin_type_int32; +} + +static void +sparc32_pseudo_register_read (struct gdbarch *gdbarch, + struct regcache *regcache, + int regnum, void *buf) +{ + gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); + + regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); + regcache_raw_read (regcache, regnum, buf); + regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 4); +} + +static void +sparc32_pseudo_register_write (struct gdbarch *gdbarch, + struct regcache *regcache, + int regnum, const void *buf) +{ + gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); + + regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); + regcache_raw_write (regcache, regnum, buf); + regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 4); +} + + +static CORE_ADDR +sparc32_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, + CORE_ADDR funcaddr, int using_gcc, + struct value **args, int nargs, + struct type *value_type, + CORE_ADDR *real_pc, CORE_ADDR *bp_addr) +{ + *bp_addr = sp - 4; + *real_pc = funcaddr; + + if (using_struct_return (value_type, using_gcc)) + { + char buf[4]; + + /* This is an UNIMP instruction. */ + store_unsigned_integer (buf, 4, TYPE_LENGTH (value_type) & 0x1fff); + write_memory (sp - 8, buf, 4); + return sp - 8; + } + + return sp - 4; +} + +static CORE_ADDR +sparc32_store_arguments (struct regcache *regcache, int nargs, + struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + /* Number of words in the "parameter array". */ + int num_elements = 0; + int element = 0; + int i; + + for (i = 0; i < nargs; i++) + { + struct type *type = VALUE_TYPE (args[i]); + int len = TYPE_LENGTH (type); + + if (sparc_structure_or_union_p (type) + || (sparc_floating_p (type) && len == 16)) + { + /* Structure, Union and Quad-Precision Arguments. */ + sp -= len; + + /* Use doubleword alignment for these values. That's always + correct, and wasting a few bytes shouldn't be a problem. */ + sp &= ~0x7; + + write_memory (sp, VALUE_CONTENTS (args[i]), len); + args[i] = value_from_pointer (lookup_pointer_type (type), sp); + num_elements++; + } + else if (sparc_floating_p (type)) + { + /* Floating arguments. */ + gdb_assert (len == 4 || len == 8); + num_elements += (len / 4); + } + else + { + /* Integral and pointer arguments. */ + gdb_assert (sparc_integral_or_pointer_p (type)); + + if (len < 4) + args[i] = value_cast (builtin_type_int32, args[i]); + num_elements += ((len + 3) / 4); + } + } + + /* Always allocate at least six words. */ + sp -= max (6, num_elements) * 4; + + /* The psABI says that "Software convention requires space for the + struct/union return value pointer, even if the word is unused." */ + sp -= 4; + + /* The psABI says that "Although software convention and the + operating system require every stack frame to be doubleword + aligned." */ + sp &= ~0x7; + + for (i = 0; i < nargs; i++) + { + char *valbuf = VALUE_CONTENTS (args[i]); + struct type *type = VALUE_TYPE (args[i]); + int len = TYPE_LENGTH (type); + + gdb_assert (len == 4 || len == 8); + + if (element < 6) + { + int regnum = SPARC_O0_REGNUM + element; + + regcache_cooked_write (regcache, regnum, valbuf); + if (len > 4 && element < 5) + regcache_cooked_write (regcache, regnum + 1, valbuf + 4); + } + + /* Always store the argument in memory. */ + write_memory (sp + 4 + element * 4, valbuf, len); + element += len / 4; + } + + gdb_assert (element == num_elements); + + if (struct_return) + { + char buf[4]; + + store_unsigned_integer (buf, 4, struct_addr); + write_memory (sp, buf, 4); + } + + return sp; +} + +static CORE_ADDR +sparc32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + CORE_ADDR call_pc = (struct_return ? (bp_addr - 12) : (bp_addr - 8)); + + /* Set return address. */ + regcache_cooked_write_unsigned (regcache, SPARC_O7_REGNUM, call_pc); + + /* Set up function arguments. */ + sp = sparc32_store_arguments (regcache, nargs, args, sp, + struct_return, struct_addr); + + /* Allocate the 16-word window save area. */ + sp -= 16 * 4; + + /* Stack should be doubleword aligned at this point. */ + gdb_assert (sp % 8 == 0); + + /* Finally, update the stack pointer. */ + regcache_cooked_write_unsigned (regcache, SPARC_SP_REGNUM, sp); + + return sp; +} + + +/* Use the program counter to determine the contents and size of a + breakpoint instruction. Return a pointer to a string of bytes that + encode a breakpoint instruction, store the length of the string in + *LEN and optionally adjust *PC to point to the correct memory + location for inserting the breakpoint. */ + +static const unsigned char * +sparc_breakpoint_from_pc (CORE_ADDR *pc, int *len) +{ + static unsigned char break_insn[] = { 0x91, 0xd0, 0x20, 0x01 }; + + *len = sizeof (break_insn); + return break_insn; +} + + +/* Allocate and initialize a frame cache. */ + +static struct sparc_frame_cache * +sparc_alloc_frame_cache (void) +{ + struct sparc_frame_cache *cache; + int i; + + cache = FRAME_OBSTACK_ZALLOC (struct sparc_frame_cache); + + /* Base address. */ + cache->base = 0; + cache->pc = 0; + + /* Frameless until proven otherwise. */ + cache->frameless_p = 1; + + cache->struct_return_p = 0; + + return cache; +} + +CORE_ADDR +sparc_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, + struct sparc_frame_cache *cache) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + unsigned long insn; + int offset = 0; int dest = -1; - CORE_ADDR pc = start_pc; - int is_flat = 0; - insn = fetch_instruction (pc); + if (current_pc <= pc) + return current_pc; - /* Recognize the `sethi' insn and record its destination. */ - if (X_OP (insn) == 0 && X_OP2 (insn) == 4) + /* We have to handle to "Procedure Linkage Table" (PLT) special. On + SPARC the linker usually defines a symbol (typically + _PROCEDURE_LINKAGE_TABLE_) at the start of the .plt section. + This symbol makes us end up here with PC pointing at the start of + the PLT and CURRENT_PC probably pointing at a PLT entry. If we + would do our normal prologue analysis, we would probably conclude + that we've got a frame when in reality we don't, since the + dynamic linker patches up the first PLT with some code that + starts with a SAVE instruction. Patch up PC such that it points + at the start of our PLT entry. */ + if (tdep->plt_entry_size > 0 && in_plt_section (current_pc, NULL)) + pc = current_pc - ((current_pc - pc) % tdep->plt_entry_size); + + insn = sparc_fetch_instruction (pc); + + /* Recognize a SETHI insn and record its destination. */ + if (X_OP (insn) == 0 && X_OP2 (insn) == 0x04) { dest = X_RD (insn); - pc += 4; - insn = fetch_instruction (pc); + offset += 4; + + insn = sparc_fetch_instruction (pc + 4); } - /* Recognize an add immediate value to register to either %g1 or - the destination register recorded above. Actually, this might - well recognize several different arithmetic operations. - It doesn't check that rs1 == rd because in theory "sub %g0, 5, %g1" - followed by "save %sp, %g1, %sp" is a valid prologue (Not that - I imagine any compiler really does that, however). */ - if (X_OP (insn) == 2 - && X_I (insn) + /* Allow for an arithmetic operation on DEST or %g1. */ + if (X_OP (insn) == 2 && X_I (insn) && (X_RD (insn) == 1 || X_RD (insn) == dest)) { - pc += 4; - insn = fetch_instruction (pc); + offset += 4; + + insn = sparc_fetch_instruction (pc + 8); } - /* Recognize any SAVE insn. */ - if (X_OP (insn) == 2 && X_OP3 (insn) == 60) + /* Check for the SAVE instruction that sets up the frame. */ + if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c) { - pc += 4; - if (frameless_p) /* If the save is all we care about, */ - return pc; /* return before doing more work */ - insn = fetch_instruction (pc); - } - /* Recognize add to %sp. */ - else if (X_OP (insn) == 2 && X_RD (insn) == 14 && X_OP3 (insn) == 0) - { - pc += 4; - if (frameless_p) /* If the add is all we care about, */ - return pc; /* return before doing more work */ - is_flat = 1; - insn = fetch_instruction (pc); - /* Recognize store of frame pointer (i7). */ - if (X_OP (insn) == 3 - && X_RD (insn) == 31 - && X_OP3 (insn) == 4 - && X_RS1 (insn) == 14) - { - pc += 4; - insn = fetch_instruction (pc); - - /* Recognize sub %sp, , %i7. */ - if (X_OP (insn) == 2 - && X_OP3 (insn) == 4 - && X_RS1 (insn) == 14 - && X_RD (insn) == 31) - { - pc += 4; - insn = fetch_instruction (pc); - } - else - return pc; - } - else - return pc; - } - else - /* Without a save or add instruction, it's not a prologue. */ - return start_pc; - - while (1) - { - /* Recognize stores into the frame from the input registers. - This recognizes all non alternate stores of an input register, - into a location offset from the frame pointer between - +68 and +92. */ - - /* The above will fail for arguments that are promoted - (eg. shorts to ints or floats to doubles), because the compiler - will pass them in positive-offset frame space, but the prologue - will save them (after conversion) in negative frame space at an - unpredictable offset. Therefore I am going to remove the - restriction on the target-address of the save, on the theory - that any unbroken sequence of saves from input registers must - be part of the prologue. In un-optimized code (at least), I'm - fairly sure that the compiler would emit SOME other instruction - (eg. a move or add) before emitting another save that is actually - a part of the function body. - - Besides, the reserved stack space is different for SPARC64 anyway. - - MVS 4/23/2000 */ - - if (X_OP (insn) == 3 - && (X_OP3 (insn) & 0x3c) == 4 /* Store, non-alternate. */ - && (X_RD (insn) & 0x18) == 0x18 /* Input register. */ - && X_I (insn) /* Immediate mode. */ - && X_RS1 (insn) == 30) /* Off of frame pointer. */ - ; /* empty statement -- fall thru to end of loop */ - else if (GDB_TARGET_IS_SPARC64 - && X_OP (insn) == 3 - && (X_OP3 (insn) & 0x3c) == 12 /* store, extended (64-bit) */ - && (X_RD (insn) & 0x18) == 0x18 /* input register */ - && X_I (insn) /* immediate mode */ - && X_RS1 (insn) == 30) /* off of frame pointer */ - ; /* empty statement -- fall thru to end of loop */ - else if (X_OP (insn) == 3 - && (X_OP3 (insn) & 0x3c) == 36 /* store, floating-point */ - && X_I (insn) /* immediate mode */ - && X_RS1 (insn) == 30) /* off of frame pointer */ - ; /* empty statement -- fall thru to end of loop */ - else if (is_flat - && X_OP (insn) == 3 - && X_OP3 (insn) == 4 /* store? */ - && X_RS1 (insn) == 14) /* off of frame pointer */ - { - if (saved_regs && X_I (insn)) - saved_regs[X_RD (insn)] = - fi->frame + fi->extra_info->sp_offset + X_SIMM13 (insn); - } - else - break; - pc += 4; - insn = fetch_instruction (pc); + cache->frameless_p = 0; + return pc + offset + 4; } return pc; } -CORE_ADDR -sparc_skip_prologue (CORE_ADDR start_pc, int frameless_p) +static CORE_ADDR +sparc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - return examine_prologue (start_pc, frameless_p, NULL, NULL); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + return frame_unwind_register_unsigned (next_frame, tdep->pc_regnum); } -/* Check instruction at ADDR to see if it is a branch. - All non-annulled instructions will go to NPC or will trap. - Set *TARGET if we find a candidate branch; set to zero if not. +/* Return PC of first real instruction of the function starting at + START_PC. */ - This isn't static as it's used by remote-sa.sparc.c. */ - -static branch_type -isbranch (long instruction, CORE_ADDR addr, CORE_ADDR *target) +static CORE_ADDR +sparc32_skip_prologue (CORE_ADDR start_pc) { - branch_type val = not_branch; - long int offset = 0; /* Must be signed for sign-extend. */ + struct symtab_and_line sal; + CORE_ADDR func_start, func_end; + struct sparc_frame_cache cache; - *target = 0; + /* This is the preferred method, find the end of the prologue by + using the debugging information. */ + if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end)) + { + sal = find_pc_line (func_start, 0); - if (X_OP (instruction) == 0 - && (X_OP2 (instruction) == 2 - || X_OP2 (instruction) == 6 - || X_OP2 (instruction) == 1 - || X_OP2 (instruction) == 3 - || X_OP2 (instruction) == 5 - || (GDB_TARGET_IS_SPARC64 && X_OP2 (instruction) == 7))) - { - if (X_COND (instruction) == 8) - val = X_A (instruction) ? baa : ba; - else - val = X_A (instruction) ? bicca : bicc; - switch (X_OP2 (instruction)) - { - case 7: - if (!GDB_TARGET_IS_SPARC64) - break; - /* else fall thru */ - case 2: - case 6: - offset = 4 * X_DISP22 (instruction); - break; - case 1: - case 5: - offset = 4 * X_DISP19 (instruction); - break; - case 3: - offset = 4 * X_DISP16 (instruction); - break; - } - *target = addr + offset; - } - else if (GDB_TARGET_IS_SPARC64 - && X_OP (instruction) == 2 - && X_OP3 (instruction) == 62) - { - if (X_FCN (instruction) == 0) - { - /* done */ - *target = read_register (TNPC_REGNUM); - val = done_retry; - } - else if (X_FCN (instruction) == 1) - { - /* retry */ - *target = read_register (TPC_REGNUM); - val = done_retry; - } + if (sal.end < func_end + && start_pc <= sal.end) + return sal.end; } - return val; + return sparc_analyze_prologue (start_pc, 0xffffffffUL, &cache); } - -/* Find register number REGNUM relative to FRAME and put its - (raw) contents in *RAW_BUFFER. Set *OPTIMIZED if the variable - was optimized out (and thus can't be fetched). If the variable - was fetched from memory, set *ADDRP to where it was fetched from, - otherwise it was fetched from a register. - The argument RAW_BUFFER must point to aligned memory. */ +/* Normal frames. */ -void -sparc_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp, - struct frame_info *frame, int regnum, - enum lval_type *lval) +struct sparc_frame_cache * +sparc_frame_cache (struct frame_info *next_frame, void **this_cache) { - struct frame_info *frame1; - CORE_ADDR addr; + struct sparc_frame_cache *cache; - if (!target_has_registers) - error ("No registers."); + if (*this_cache) + return *this_cache; - if (optimized) - *optimized = 0; + cache = sparc_alloc_frame_cache (); + *this_cache = cache; - addr = 0; - - /* FIXME This code extracted from infcmd.c; should put elsewhere! */ - if (frame == NULL) + cache->pc = frame_func_unwind (next_frame); + if (cache->pc != 0) { - /* error ("No selected frame."); */ - if (!target_has_registers) - error ("The program has no registers now."); - if (selected_frame == NULL) - error ("No selected frame."); - /* Try to use selected frame */ - frame = get_prev_frame (selected_frame); - if (frame == 0) - error ("Cmd not meaningful in the outermost frame."); + CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame); + sparc_analyze_prologue (cache->pc, addr_in_block, cache); } - - frame1 = frame->next; - - /* Get saved PC from the frame info if not in innermost frame. */ - if (regnum == PC_REGNUM && frame1 != NULL) + if (cache->frameless_p) { - if (lval != NULL) - *lval = not_lval; - if (raw_buffer != NULL) + /* This function is frameless, so %fp (%i6) holds the frame + pointer for our calling frame. Use %sp (%o6) as this frame's + base address. */ + cache->base = + frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM); + } + else + { + /* For normal frames, %fp (%i6) holds the frame pointer, the + base address for the current stack frame. */ + cache->base = + frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); + } + + return cache; +} + +struct sparc_frame_cache * +sparc32_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct sparc_frame_cache *cache; + struct symbol *sym; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + + sym = find_pc_function (cache->pc); + if (sym) + { + struct type *type = check_typedef (SYMBOL_TYPE (sym)); + enum type_code code = TYPE_CODE (type); + + if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD) { - /* Put it back in target format. */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->pc); + type = check_typedef (TYPE_TARGET_TYPE (type)); + if (sparc_structure_or_union_p (type) + || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)) + cache->struct_return_p = 1; + } + } + + return cache; +} + +static void +sparc32_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc32_frame_cache (next_frame, this_cache); + + /* This marks the outermost frame. */ + if (cache->base == 0) + return; + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc32_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc32_frame_cache (next_frame, this_cache); + + if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + CORE_ADDR pc = (regnum == SPARC32_NPC_REGNUM) ? 4 : 0; + + /* If this functions has a Structure, Union or + Quad-Precision return value, we have to skip the UNIMP + instruction that encodes the size of the structure. */ + if (cache->struct_return_p) + pc += 4; + + regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM; + pc += frame_unwind_register_unsigned (next_frame, regnum) + 8; + store_unsigned_integer (valuep, 4, pc); } - if (addrp != NULL) - *addrp = 0; return; } - while (frame1 != NULL) + /* Handle StackGhost. */ + { + ULONGEST wcookie = sparc_fetch_wcookie (); + + if (wcookie != 0 && !cache->frameless_p && regnum == SPARC_I7_REGNUM) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4; + ULONGEST i7; + + /* Read the value in from memory. */ + i7 = get_frame_memory_unsigned (next_frame, addr, 4); + store_unsigned_integer (valuep, 4, i7 ^ wcookie); + } + return; + } + } + + /* The previous frame's `local' and `in' registers have been saved + in the register save area. */ + if (!cache->frameless_p + && regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) { - /* FIXME MVS: wrong test for dummy frame at entry. */ - - if (frame1->pc >= (frame1->extra_info->bottom ? - frame1->extra_info->bottom : read_sp ()) - && frame1->pc <= FRAME_FP (frame1)) - { - /* Dummy frame. All but the window regs are in there somewhere. - The window registers are saved on the stack, just like in a - normal frame. */ - if (regnum >= G1_REGNUM && regnum < G1_REGNUM + 7) - addr = frame1->frame + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE - - (FP_REGISTER_BYTES + 8 * SPARC_INTREG_SIZE); - else if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8) - addr = (frame1->prev->extra_info->bottom - + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE - + FRAME_SAVED_I0); - else if (regnum >= L0_REGNUM && regnum < L0_REGNUM + 8) - addr = (frame1->prev->extra_info->bottom - + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE - + FRAME_SAVED_L0); - else if (regnum >= O0_REGNUM && regnum < O0_REGNUM + 8) - addr = frame1->frame + (regnum - O0_REGNUM) * SPARC_INTREG_SIZE - - (FP_REGISTER_BYTES + 16 * SPARC_INTREG_SIZE); - else if (SPARC_HAS_FPU && - regnum >= FP0_REGNUM && regnum < FP0_REGNUM + 32) - addr = frame1->frame + (regnum - FP0_REGNUM) * 4 - - (FP_REGISTER_BYTES); - else if (GDB_TARGET_IS_SPARC64 && SPARC_HAS_FPU && - regnum >= FP0_REGNUM + 32 && regnum < FP_MAX_REGNUM) - addr = frame1->frame + 32 * 4 + (regnum - FP0_REGNUM - 32) * 8 - - (FP_REGISTER_BYTES); - else if (regnum >= Y_REGNUM && regnum < NUM_REGS) - addr = frame1->frame + (regnum - Y_REGNUM) * SPARC_INTREG_SIZE - - (FP_REGISTER_BYTES + 24 * SPARC_INTREG_SIZE); - } - else if (frame1->extra_info->flat) + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = cache->base + (regnum - SPARC_L0_REGNUM) * 4; + *realnump = -1; + if (valuep) { + struct gdbarch *gdbarch = get_frame_arch (next_frame); - if (regnum == RP_REGNUM) - addr = frame1->extra_info->pc_addr; - else if (regnum == I7_REGNUM) - addr = frame1->extra_info->fp_addr; - else - { - CORE_ADDR func_start; - CORE_ADDR *regs; - - regs = alloca (NUM_REGS * sizeof (CORE_ADDR)); - memset (regs, 0, NUM_REGS * sizeof (CORE_ADDR)); - - find_pc_partial_function (frame1->pc, NULL, &func_start, NULL); - examine_prologue (func_start, 0, frame1, regs); - addr = regs[regnum]; - } + /* Read the value in from memory. */ + read_memory (*addrp, valuep, register_size (gdbarch, regnum)); } - else - { - /* Normal frame. Local and In registers are saved on stack. */ - if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8) - addr = (frame1->prev->extra_info->bottom - + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE - + FRAME_SAVED_I0); - else if (regnum >= L0_REGNUM && regnum < L0_REGNUM + 8) - addr = (frame1->prev->extra_info->bottom - + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE - + FRAME_SAVED_L0); - else if (regnum >= O0_REGNUM && regnum < O0_REGNUM + 8) - { - /* Outs become ins. */ - get_saved_register (raw_buffer, optimized, addrp, frame1, - (regnum - O0_REGNUM + I0_REGNUM), lval); - return; - } - } - if (addr != 0) - break; - frame1 = frame1->next; + return; } - if (addr != 0) - { - if (lval != NULL) - *lval = lval_memory; - if (regnum == SP_REGNUM) - { - if (raw_buffer != NULL) - { - /* Put it back in target format. */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), addr); - } - if (addrp != NULL) - *addrp = 0; - return; - } - if (raw_buffer != NULL) - read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum)); - } - else - { - if (lval != NULL) - *lval = lval_register; - addr = REGISTER_BYTE (regnum); - if (raw_buffer != NULL) - read_register_gen (regnum, raw_buffer); - } - if (addrp != NULL) - *addrp = addr; + + /* The previous frame's `out' registers are accessable as the + current frame's `in' registers. */ + if (!cache->frameless_p + && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) + regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM); + + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); } -/* Push an empty stack frame, and record in it the current PC, regs, etc. - - We save the non-windowed registers and the ins. The locals and outs - are new; they don't need to be saved. The i's and l's of - the last frame were already saved on the stack. */ - -/* Definitely see tm-sparc.h for more doc of the frame format here. */ - -/* See tm-sparc.h for how this is calculated. */ - -#define DUMMY_STACK_REG_BUF_SIZE \ - (((8+8+8) * SPARC_INTREG_SIZE) + FP_REGISTER_BYTES) -#define DUMMY_STACK_SIZE \ - (DUMMY_STACK_REG_BUF_SIZE + DUMMY_REG_SAVE_OFFSET) - -void -sparc_push_dummy_frame (void) +static const struct frame_unwind sparc32_frame_unwind = { - CORE_ADDR sp, old_sp; - char *register_temp; + NORMAL_FRAME, + sparc32_frame_this_id, + sparc32_frame_prev_register +}; - register_temp = alloca (DUMMY_STACK_SIZE); +static const struct frame_unwind * +sparc32_frame_sniffer (struct frame_info *next_frame) +{ + return &sparc32_frame_unwind; +} + - old_sp = sp = read_sp (); +static CORE_ADDR +sparc32_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct sparc_frame_cache *cache = + sparc32_frame_cache (next_frame, this_cache); - if (GDB_TARGET_IS_SPARC64) - { - /* PC, NPC, CCR, FSR, FPRS, Y, ASI */ - read_register_bytes (REGISTER_BYTE (PC_REGNUM), ®ister_temp[0], - REGISTER_RAW_SIZE (PC_REGNUM) * 7); - read_register_bytes (REGISTER_BYTE (PSTATE_REGNUM), - ®ister_temp[7 * SPARC_INTREG_SIZE], - REGISTER_RAW_SIZE (PSTATE_REGNUM)); - /* FIXME: not sure what needs to be saved here. */ - } - else - { - /* Y, PS, WIM, TBR, PC, NPC, FPS, CPS regs */ - read_register_bytes (REGISTER_BYTE (Y_REGNUM), ®ister_temp[0], - REGISTER_RAW_SIZE (Y_REGNUM) * 8); - } - - read_register_bytes (REGISTER_BYTE (O0_REGNUM), - ®ister_temp[8 * SPARC_INTREG_SIZE], - SPARC_INTREG_SIZE * 8); - - read_register_bytes (REGISTER_BYTE (G0_REGNUM), - ®ister_temp[16 * SPARC_INTREG_SIZE], - SPARC_INTREG_SIZE * 8); - - if (SPARC_HAS_FPU) - read_register_bytes (REGISTER_BYTE (FP0_REGNUM), - ®ister_temp[24 * SPARC_INTREG_SIZE], - FP_REGISTER_BYTES); - - sp -= DUMMY_STACK_SIZE; - - write_sp (sp); - - write_memory (sp + DUMMY_REG_SAVE_OFFSET, ®ister_temp[0], - DUMMY_STACK_REG_BUF_SIZE); - - if (strcmp (target_shortname, "sim") != 0) - { - write_fp (old_sp); - - /* Set return address register for the call dummy to the current PC. */ - write_register (I7_REGNUM, read_pc () - 8); - } - else - { - /* The call dummy will write this value to FP before executing - the 'save'. This ensures that register window flushes work - correctly in the simulator. */ - write_register (G0_REGNUM + 1, read_register (FP_REGNUM)); - - /* The call dummy will write this value to FP after executing - the 'save'. */ - write_register (G0_REGNUM + 2, old_sp); - - /* The call dummy will write this value to the return address (%i7) after - executing the 'save'. */ - write_register (G0_REGNUM + 3, read_pc () - 8); - - /* Set the FP that the call dummy will be using after the 'save'. - This makes backtraces from an inferior function call work properly. */ - write_register (FP_REGNUM, old_sp); - } + return cache->base; } -/* sparc_frame_find_saved_regs (). This function is here only because - pop_frame uses it. Note there is an interesting corner case which - I think few ports of GDB get right--if you are popping a frame - which does not save some register that *is* saved by a more inner - frame (such a frame will never be a dummy frame because dummy - frames save all registers). Rewriting pop_frame to use - get_saved_register would solve this problem and also get rid of the - ugly duplication between sparc_frame_find_saved_regs and - get_saved_register. +static const struct frame_base sparc32_frame_base = +{ + &sparc32_frame_unwind, + sparc32_frame_base_address, + sparc32_frame_base_address, + sparc32_frame_base_address +}; - Stores, into an array of CORE_ADDR, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. +static struct frame_id +sparc_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + CORE_ADDR sp; - Note that on register window machines, we are currently making the - assumption that window registers are being saved somewhere in the - frame in which they are being used. If they are stored in an - inferior frame, find_saved_register will break. + sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM); + return frame_id_build (sp, frame_pc_unwind (next_frame)); +} + - On the Sun 4, the only time all registers are saved is when - a dummy frame is involved. Otherwise, the only saved registers - are the LOCAL and IN registers which are saved as a result - of the "save/restore" opcodes. This condition is determined - by address rather than by value. - - The "pc" is not stored in a frame on the SPARC. (What is stored - is a return address minus 8.) sparc_pop_frame knows how to - deal with that. Other routines might or might not. - - See tm-sparc.h (PUSH_DUMMY_FRAME and friends) for CRITICAL information - about how this works. */ - -static void sparc_frame_find_saved_regs (struct frame_info *, CORE_ADDR *); +/* Extract from an array REGBUF containing the (raw) register state, a + function return value of TYPE, and copy that into VALBUF. */ static void -sparc_frame_find_saved_regs (struct frame_info *fi, CORE_ADDR *saved_regs_addr) +sparc32_extract_return_value (struct type *type, struct regcache *regcache, + void *valbuf) { - register int regnum; - CORE_ADDR frame_addr = FRAME_FP (fi); + int len = TYPE_LENGTH (type); + char buf[8]; - if (!fi) - internal_error (__FILE__, __LINE__, - "Bad frame info struct in FRAME_FIND_SAVED_REGS"); + gdb_assert (!sparc_structure_or_union_p (type)); + gdb_assert (!(sparc_floating_p (type) && len == 16)); - memset (saved_regs_addr, 0, NUM_REGS * sizeof (CORE_ADDR)); - - if (fi->pc >= (fi->extra_info->bottom ? - fi->extra_info->bottom : read_sp ()) - && fi->pc <= FRAME_FP (fi)) + if (sparc_floating_p (type)) { - /* Dummy frame. All but the window regs are in there somewhere. */ - for (regnum = G1_REGNUM; regnum < G1_REGNUM + 7; regnum++) - saved_regs_addr[regnum] = - frame_addr + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE - - DUMMY_STACK_REG_BUF_SIZE + 16 * SPARC_INTREG_SIZE; - - for (regnum = I0_REGNUM; regnum < I0_REGNUM + 8; regnum++) - saved_regs_addr[regnum] = - frame_addr + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE - - DUMMY_STACK_REG_BUF_SIZE + 8 * SPARC_INTREG_SIZE; - - if (SPARC_HAS_FPU) - for (regnum = FP0_REGNUM; regnum < FP_MAX_REGNUM; regnum++) - saved_regs_addr[regnum] = frame_addr + (regnum - FP0_REGNUM) * 4 - - DUMMY_STACK_REG_BUF_SIZE + 24 * SPARC_INTREG_SIZE; - - if (GDB_TARGET_IS_SPARC64) - { - for (regnum = PC_REGNUM; regnum < PC_REGNUM + 7; regnum++) - { - saved_regs_addr[regnum] = - frame_addr + (regnum - PC_REGNUM) * SPARC_INTREG_SIZE - - DUMMY_STACK_REG_BUF_SIZE; - } - saved_regs_addr[PSTATE_REGNUM] = - frame_addr + 8 * SPARC_INTREG_SIZE - DUMMY_STACK_REG_BUF_SIZE; - } - else - for (regnum = Y_REGNUM; regnum < NUM_REGS; regnum++) - saved_regs_addr[regnum] = - frame_addr + (regnum - Y_REGNUM) * SPARC_INTREG_SIZE - - DUMMY_STACK_REG_BUF_SIZE; - - frame_addr = fi->extra_info->bottom ? - fi->extra_info->bottom : read_sp (); - } - else if (fi->extra_info->flat) - { - CORE_ADDR func_start; - find_pc_partial_function (fi->pc, NULL, &func_start, NULL); - examine_prologue (func_start, 0, fi, saved_regs_addr); - - /* Flat register window frame. */ - saved_regs_addr[RP_REGNUM] = fi->extra_info->pc_addr; - saved_regs_addr[I7_REGNUM] = fi->extra_info->fp_addr; + /* Floating return values. */ + regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf); + if (len > 4) + regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4); + memcpy (valbuf, buf, len); } else { - /* Normal frame. Just Local and In registers */ - frame_addr = fi->extra_info->bottom ? - fi->extra_info->bottom : read_sp (); - for (regnum = L0_REGNUM; regnum < L0_REGNUM + 8; regnum++) - saved_regs_addr[regnum] = - (frame_addr + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE - + FRAME_SAVED_L0); - for (regnum = I0_REGNUM; regnum < I0_REGNUM + 8; regnum++) - saved_regs_addr[regnum] = - (frame_addr + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE - + FRAME_SAVED_I0); - } - if (fi->next) - { - if (fi->extra_info->flat) + /* Integral and pointer return values. */ + gdb_assert (sparc_integral_or_pointer_p (type)); + + regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf); + if (len > 4) { - saved_regs_addr[O7_REGNUM] = fi->extra_info->pc_addr; + regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + 4); + gdb_assert (len == 8); + memcpy (valbuf, buf, 8); } else { - /* Pull off either the next frame pointer or the stack pointer */ - CORE_ADDR next_next_frame_addr = - (fi->next->extra_info->bottom ? - fi->next->extra_info->bottom : read_sp ()); - for (regnum = O0_REGNUM; regnum < O0_REGNUM + 8; regnum++) - saved_regs_addr[regnum] = - (next_next_frame_addr - + (regnum - O0_REGNUM) * SPARC_INTREG_SIZE - + FRAME_SAVED_I0); + /* Just stripping off any unused bytes should preserve the + signed-ness just fine. */ + memcpy (valbuf, buf + 4 - len, len); } } - /* Otherwise, whatever we would get from ptrace(GETREGS) is accurate */ - /* FIXME -- should this adjust for the sparc64 offset? */ - saved_regs_addr[SP_REGNUM] = FRAME_FP (fi); } -/* Discard from the stack the innermost frame, restoring all saved registers. +/* Write into the appropriate registers a function return value stored + in VALBUF of type TYPE. */ - Note that the values stored in fsr by get_frame_saved_regs are *in - the context of the called frame*. What this means is that the i - regs of fsr must be restored into the o regs of the (calling) frame that - we pop into. We don't care about the output regs of the calling frame, - since unless it's a dummy frame, it won't have any output regs in it. +static void +sparc32_store_return_value (struct type *type, struct regcache *regcache, + const void *valbuf) +{ + int len = TYPE_LENGTH (type); + char buf[8]; - We never have to bother with %l (local) regs, since the called routine's - locals get tossed, and the calling routine's locals are already saved - on its stack. */ + gdb_assert (!sparc_structure_or_union_p (type)); + gdb_assert (!(sparc_floating_p (type) && len == 16)); -/* Definitely see tm-sparc.h for more doc of the frame format here. */ + if (sparc_floating_p (type)) + { + /* Floating return values. */ + memcpy (buf, valbuf, len); + regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf); + if (len > 4) + regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4); + } + else + { + /* Integral and pointer return values. */ + gdb_assert (sparc_integral_or_pointer_p (type)); + + if (len > 4) + { + gdb_assert (len == 8); + memcpy (buf, valbuf, 8); + regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + 4); + } + else + { + /* ??? Do we need to do any sign-extension here? */ + memcpy (buf + 4 - len, valbuf, len); + } + regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf); + } +} + +static enum return_value_convention +sparc32_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, void *readbuf, + const void *writebuf) +{ + if (sparc_structure_or_union_p (type) + || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)) + return RETURN_VALUE_STRUCT_CONVENTION; + + if (readbuf) + sparc32_extract_return_value (type, regcache, readbuf); + if (writebuf) + sparc32_store_return_value (type, regcache, writebuf); + + return RETURN_VALUE_REGISTER_CONVENTION; +} + +#if 0 +/* NOTE: cagney/2004-01-17: For the moment disable this method. The + architecture and CORE-gdb will need new code (and a replacement for + DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS) before this can be made to + work robustly. Here is a possible function signature: */ +/* NOTE: cagney/2004-01-17: So far only the 32-bit SPARC ABI has been + identifed as having a way to robustly recover the address of a + struct-convention return-value (after the function has returned). + For all other ABIs so far examined, the calling convention makes no + guarenteed that the register containing the return-value will be + preserved and hence that the return-value's address can be + recovered. */ +/* Extract from REGCACHE, which contains the (raw) register state, the + address in which a function should return its structure value, as a + CORE_ADDR. */ + +static CORE_ADDR +sparc32_extract_struct_value_address (struct regcache *regcache) +{ + ULONGEST sp; + + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + return read_memory_unsigned_integer (sp + 64, 4); +} +#endif + +static int +sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type) +{ + return (sparc_structure_or_union_p (type) + || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)); +} + + +/* The SPARC Architecture doesn't have hardware single-step support, + and most operating systems don't implement it either, so we provide + software single-step mechanism. */ + +static CORE_ADDR +sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc) +{ + unsigned long insn = sparc_fetch_instruction (pc); + int conditional_p = X_COND (insn) & 0x7; + int branch_p = 0; + long offset = 0; /* Must be signed for sign-extend. */ + + if (X_OP (insn) == 0 && X_OP2 (insn) == 3 && (insn & 0x1000000) == 0) + { + /* Branch on Integer Register with Prediction (BPr). */ + branch_p = 1; + conditional_p = 1; + } + else if (X_OP (insn) == 0 && X_OP2 (insn) == 6) + { + /* Branch on Floating-Point Condition Codes (FBfcc). */ + branch_p = 1; + offset = 4 * X_DISP22 (insn); + } + else if (X_OP (insn) == 0 && X_OP2 (insn) == 5) + { + /* Branch on Floating-Point Condition Codes with Prediction + (FBPfcc). */ + branch_p = 1; + offset = 4 * X_DISP19 (insn); + } + else if (X_OP (insn) == 0 && X_OP2 (insn) == 2) + { + /* Branch on Integer Condition Codes (Bicc). */ + branch_p = 1; + offset = 4 * X_DISP22 (insn); + } + else if (X_OP (insn) == 0 && X_OP2 (insn) == 1) + { + /* Branch on Integer Condition Codes with Prediction (BPcc). */ + branch_p = 1; + offset = 4 * X_DISP19 (insn); + } + + /* FIXME: Handle DONE and RETRY instructions. */ + + /* FIXME: Handle the Trap instruction. */ + + if (branch_p) + { + if (conditional_p) + { + /* For conditional branches, return nPC + 4 iff the annul + bit is 1. */ + return (X_A (insn) ? *npc + 4 : 0); + } + else + { + /* For unconditional branches, return the target if its + specified condition is "always" and return nPC + 4 if the + condition is "never". If the annul bit is 1, set *NPC to + zero. */ + if (X_COND (insn) == 0x0) + pc = *npc, offset = 4; + if (X_A (insn)) + *npc = 0; + + gdb_assert (offset != 0); + return pc + offset; + } + } + + return 0; +} void -sparc_pop_frame (void) +sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) { - register struct frame_info *frame = get_current_frame (); - register CORE_ADDR pc; - CORE_ADDR *fsr; - char *raw_buffer; - int regnum; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + static CORE_ADDR npc, nnpc; + static char npc_save[4], nnpc_save[4]; - fsr = alloca (NUM_REGS * sizeof (CORE_ADDR)); - raw_buffer = alloca (REGISTER_BYTES); - sparc_frame_find_saved_regs (frame, &fsr[0]); - if (SPARC_HAS_FPU) + if (insert_breakpoints_p) { - if (fsr[FP0_REGNUM]) - { - read_memory (fsr[FP0_REGNUM], raw_buffer, FP_REGISTER_BYTES); - write_register_bytes (REGISTER_BYTE (FP0_REGNUM), - raw_buffer, FP_REGISTER_BYTES); - } - if (!(GDB_TARGET_IS_SPARC64)) - { - if (fsr[FPS_REGNUM]) - { - read_memory (fsr[FPS_REGNUM], raw_buffer, SPARC_INTREG_SIZE); - write_register_gen (FPS_REGNUM, raw_buffer); - } - if (fsr[CPS_REGNUM]) - { - read_memory (fsr[CPS_REGNUM], raw_buffer, SPARC_INTREG_SIZE); - write_register_gen (CPS_REGNUM, raw_buffer); - } - } + CORE_ADDR pc; + + pc = sparc_address_from_register (tdep->pc_regnum); + npc = sparc_address_from_register (tdep->npc_regnum); + + /* Analyze the instruction at PC. */ + nnpc = sparc_analyze_control_transfer (pc, &npc); + if (npc != 0) + target_insert_breakpoint (npc, npc_save); + if (nnpc != 0) + target_insert_breakpoint (nnpc, nnpc_save); + + /* Assert that we have set at least one breakpoint, and that + they're not set at the same spot. */ + gdb_assert (npc != 0 || nnpc != 0); + gdb_assert (nnpc != npc); } - if (fsr[G1_REGNUM]) - { - read_memory (fsr[G1_REGNUM], raw_buffer, 7 * SPARC_INTREG_SIZE); - write_register_bytes (REGISTER_BYTE (G1_REGNUM), raw_buffer, - 7 * SPARC_INTREG_SIZE); - } - - if (frame->extra_info->flat) - { - /* Each register might or might not have been saved, need to test - individually. */ - for (regnum = L0_REGNUM; regnum < L0_REGNUM + 8; ++regnum) - if (fsr[regnum]) - write_register (regnum, read_memory_integer (fsr[regnum], - SPARC_INTREG_SIZE)); - for (regnum = I0_REGNUM; regnum < I0_REGNUM + 8; ++regnum) - if (fsr[regnum]) - write_register (regnum, read_memory_integer (fsr[regnum], - SPARC_INTREG_SIZE)); - - /* Handle all outs except stack pointer (o0-o5; o7). */ - for (regnum = O0_REGNUM; regnum < O0_REGNUM + 6; ++regnum) - if (fsr[regnum]) - write_register (regnum, read_memory_integer (fsr[regnum], - SPARC_INTREG_SIZE)); - if (fsr[O0_REGNUM + 7]) - write_register (O0_REGNUM + 7, - read_memory_integer (fsr[O0_REGNUM + 7], - SPARC_INTREG_SIZE)); - - write_sp (frame->frame); - } - else if (fsr[I0_REGNUM]) - { - CORE_ADDR sp; - - char *reg_temp; - - reg_temp = alloca (REGISTER_BYTES); - - read_memory (fsr[I0_REGNUM], raw_buffer, 8 * SPARC_INTREG_SIZE); - - /* Get the ins and locals which we are about to restore. Just - moving the stack pointer is all that is really needed, except - store_inferior_registers is then going to write the ins and - locals from the registers array, so we need to muck with the - registers array. */ - sp = fsr[SP_REGNUM]; - - if (GDB_TARGET_IS_SPARC64 && (sp & 1)) - sp += 2047; - - read_memory (sp, reg_temp, SPARC_INTREG_SIZE * 16); - - /* Restore the out registers. - Among other things this writes the new stack pointer. */ - write_register_bytes (REGISTER_BYTE (O0_REGNUM), raw_buffer, - SPARC_INTREG_SIZE * 8); - - write_register_bytes (REGISTER_BYTE (L0_REGNUM), reg_temp, - SPARC_INTREG_SIZE * 16); - } - - if (!(GDB_TARGET_IS_SPARC64)) - if (fsr[PS_REGNUM]) - write_register (PS_REGNUM, - read_memory_integer (fsr[PS_REGNUM], - REGISTER_RAW_SIZE (PS_REGNUM))); - - if (fsr[Y_REGNUM]) - write_register (Y_REGNUM, - read_memory_integer (fsr[Y_REGNUM], - REGISTER_RAW_SIZE (Y_REGNUM))); - if (fsr[PC_REGNUM]) - { - /* Explicitly specified PC (and maybe NPC) -- just restore them. */ - write_register (PC_REGNUM, - read_memory_integer (fsr[PC_REGNUM], - REGISTER_RAW_SIZE (PC_REGNUM))); - if (fsr[NPC_REGNUM]) - write_register (NPC_REGNUM, - read_memory_integer (fsr[NPC_REGNUM], - REGISTER_RAW_SIZE (NPC_REGNUM))); - } - else if (frame->extra_info->flat) - { - if (frame->extra_info->pc_addr) - pc = PC_ADJUST ((CORE_ADDR) - read_memory_integer (frame->extra_info->pc_addr, - REGISTER_RAW_SIZE (PC_REGNUM))); - else - { - /* I think this happens only in the innermost frame, if so then - it is a complicated way of saying - "pc = read_register (O7_REGNUM);". */ - char *buf; - - buf = alloca (MAX_REGISTER_RAW_SIZE); - get_saved_register (buf, 0, 0, frame, O7_REGNUM, 0); - pc = PC_ADJUST (extract_address - (buf, REGISTER_RAW_SIZE (O7_REGNUM))); - } - - write_register (PC_REGNUM, pc); - write_register (NPC_REGNUM, pc + 4); - } - else if (fsr[I7_REGNUM]) - { - /* Return address in %i7 -- adjust it, then restore PC and NPC from it */ - pc = PC_ADJUST ((CORE_ADDR) read_memory_integer (fsr[I7_REGNUM], - SPARC_INTREG_SIZE)); - write_register (PC_REGNUM, pc); - write_register (NPC_REGNUM, pc + 4); - } - flush_cached_frames (); -} - -/* On the Sun 4 under SunOS, the compile will leave a fake insn which - encodes the structure size being returned. If we detect such - a fake insn, step past it. */ - -CORE_ADDR -sparc_pc_adjust (CORE_ADDR pc) -{ - unsigned long insn; - char buf[4]; - int err; - - err = target_read_memory (pc + 8, buf, 4); - insn = extract_unsigned_integer (buf, 4); - if ((err == 0) && (insn & 0xffc00000) == 0) - return pc + 12; else - return pc + 8; + { + if (npc != 0) + target_remove_breakpoint (npc, npc_save); + if (nnpc != 0) + target_remove_breakpoint (nnpc, nnpc_save); + } } -/* If pc is in a shared library trampoline, return its target. - The SunOs 4.x linker rewrites the jump table entries for PIC - compiled modules in the main executable to bypass the dynamic linker - with jumps of the form - sethi %hi(addr),%g1 - jmp %g1+%lo(addr) - and removes the corresponding jump table relocation entry in the - dynamic relocations. - find_solib_trampoline_target relies on the presence of the jump - table relocation entry, so we have to detect these jump instructions - by hand. */ - -CORE_ADDR -sunos4_skip_trampoline_code (CORE_ADDR pc) +static void +sparc_write_pc (CORE_ADDR pc, ptid_t ptid) { - unsigned long insn1; - char buf[4]; - int err; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - err = target_read_memory (pc, buf, 4); - insn1 = extract_unsigned_integer (buf, 4); - if (err == 0 && (insn1 & 0xffc00000) == 0x03000000) - { - unsigned long insn2; - - err = target_read_memory (pc + 4, buf, 4); - insn2 = extract_unsigned_integer (buf, 4); - if (err == 0 && (insn2 & 0xffffe000) == 0x81c06000) - { - CORE_ADDR target_pc = (insn1 & 0x3fffff) << 10; - int delta = insn2 & 0x1fff; - - /* Sign extend the displacement. */ - if (delta & 0x1000) - delta |= ~0x1fff; - return target_pc + delta; - } - } - return find_solib_trampoline_target (pc); + write_register_pid (tdep->pc_regnum, pc, ptid); + write_register_pid (tdep->npc_regnum, pc + 4, ptid); } -#ifdef USE_PROC_FS /* Target dependent support for /proc */ -/* *INDENT-OFF* */ -/* The /proc interface divides the target machine's register set up into - two different sets, the general register set (gregset) and the floating - point register set (fpregset). For each set, there is an ioctl to get - the current register set and another ioctl to set the current values. - - The actual structure passed through the ioctl interface is, of course, - naturally machine dependent, and is different for each set of registers. - For the sparc for example, the general register set is typically defined - by: - - typedef int gregset_t[38]; - - #define R_G0 0 - ... - #define R_TBR 37 - - and the floating point set by: - - typedef struct prfpregset { - union { - u_long pr_regs[32]; - double pr_dregs[16]; - } pr_fr; - void * pr_filler; - u_long pr_fsr; - u_char pr_qcnt; - u_char pr_q_entrysize; - u_char pr_en; - u_long pr_q[64]; - } prfpregset_t; - - These routines provide the packing and unpacking of gregset_t and - fpregset_t formatted data. - - */ -/* *INDENT-ON* */ - -/* Given a pointer to a general register set in /proc format (gregset_t *), - unpack the register contents and supply them as gdb's idea of the current - register values. */ - -void -supply_gregset (gdb_gregset_t *gregsetp) -{ - prgreg_t *regp = (prgreg_t *) gregsetp; - int regi, offset = 0; - - /* If the host is 64-bit sparc, but the target is 32-bit sparc, - then the gregset may contain 64-bit ints while supply_register - is expecting 32-bit ints. Compensate. */ - if (sizeof (regp[0]) == 8 && SPARC_INTREG_SIZE == 4) - offset = 4; - - /* GDB register numbers for Gn, On, Ln, In all match /proc reg numbers. */ - /* FIXME MVS: assumes the order of the first 32 elements... */ - for (regi = G0_REGNUM; regi <= I7_REGNUM; regi++) - { - supply_register (regi, ((char *) (regp + regi)) + offset); - } - - /* These require a bit more care. */ - supply_register (PC_REGNUM, ((char *) (regp + R_PC)) + offset); - supply_register (NPC_REGNUM, ((char *) (regp + R_nPC)) + offset); - supply_register (Y_REGNUM, ((char *) (regp + R_Y)) + offset); - - if (GDB_TARGET_IS_SPARC64) - { -#ifdef R_CCR - supply_register (CCR_REGNUM, ((char *) (regp + R_CCR)) + offset); -#else - supply_register (CCR_REGNUM, NULL); -#endif -#ifdef R_FPRS - supply_register (FPRS_REGNUM, ((char *) (regp + R_FPRS)) + offset); -#else - supply_register (FPRS_REGNUM, NULL); -#endif -#ifdef R_ASI - supply_register (ASI_REGNUM, ((char *) (regp + R_ASI)) + offset); -#else - supply_register (ASI_REGNUM, NULL); -#endif - } - else /* sparc32 */ - { -#ifdef R_PS - supply_register (PS_REGNUM, ((char *) (regp + R_PS)) + offset); -#else - supply_register (PS_REGNUM, NULL); -#endif - - /* For 64-bit hosts, R_WIM and R_TBR may not be defined. - Steal R_ASI and R_FPRS, and hope for the best! */ - -#if !defined (R_WIM) && defined (R_ASI) -#define R_WIM R_ASI -#endif - -#if !defined (R_TBR) && defined (R_FPRS) -#define R_TBR R_FPRS -#endif - -#if defined (R_WIM) - supply_register (WIM_REGNUM, ((char *) (regp + R_WIM)) + offset); -#else - supply_register (WIM_REGNUM, NULL); -#endif - -#if defined (R_TBR) - supply_register (TBR_REGNUM, ((char *) (regp + R_TBR)) + offset); -#else - supply_register (TBR_REGNUM, NULL); -#endif - } - - /* Fill inaccessible registers with zero. */ - if (GDB_TARGET_IS_SPARC64) - { - /* - * don't know how to get value of any of the following: - */ - supply_register (VER_REGNUM, NULL); - supply_register (TICK_REGNUM, NULL); - supply_register (PIL_REGNUM, NULL); - supply_register (PSTATE_REGNUM, NULL); - supply_register (TSTATE_REGNUM, NULL); - supply_register (TBA_REGNUM, NULL); - supply_register (TL_REGNUM, NULL); - supply_register (TT_REGNUM, NULL); - supply_register (TPC_REGNUM, NULL); - supply_register (TNPC_REGNUM, NULL); - supply_register (WSTATE_REGNUM, NULL); - supply_register (CWP_REGNUM, NULL); - supply_register (CANSAVE_REGNUM, NULL); - supply_register (CANRESTORE_REGNUM, NULL); - supply_register (CLEANWIN_REGNUM, NULL); - supply_register (OTHERWIN_REGNUM, NULL); - supply_register (ASR16_REGNUM, NULL); - supply_register (ASR17_REGNUM, NULL); - supply_register (ASR18_REGNUM, NULL); - supply_register (ASR19_REGNUM, NULL); - supply_register (ASR20_REGNUM, NULL); - supply_register (ASR21_REGNUM, NULL); - supply_register (ASR22_REGNUM, NULL); - supply_register (ASR23_REGNUM, NULL); - supply_register (ASR24_REGNUM, NULL); - supply_register (ASR25_REGNUM, NULL); - supply_register (ASR26_REGNUM, NULL); - supply_register (ASR27_REGNUM, NULL); - supply_register (ASR28_REGNUM, NULL); - supply_register (ASR29_REGNUM, NULL); - supply_register (ASR30_REGNUM, NULL); - supply_register (ASR31_REGNUM, NULL); - supply_register (ICC_REGNUM, NULL); - supply_register (XCC_REGNUM, NULL); - } - else - { - supply_register (CPS_REGNUM, NULL); - } -} - -void -fill_gregset (gdb_gregset_t *gregsetp, int regno) -{ - prgreg_t *regp = (prgreg_t *) gregsetp; - int regi, offset = 0; - - /* If the host is 64-bit sparc, but the target is 32-bit sparc, - then the gregset may contain 64-bit ints while supply_register - is expecting 32-bit ints. Compensate. */ - if (sizeof (regp[0]) == 8 && SPARC_INTREG_SIZE == 4) - offset = 4; - - for (regi = 0; regi <= R_I7; regi++) - if ((regno == -1) || (regno == regi)) - read_register_gen (regi, (char *) (regp + regi) + offset); - - if ((regno == -1) || (regno == PC_REGNUM)) - read_register_gen (PC_REGNUM, (char *) (regp + R_PC) + offset); - - if ((regno == -1) || (regno == NPC_REGNUM)) - read_register_gen (NPC_REGNUM, (char *) (regp + R_nPC) + offset); - - if ((regno == -1) || (regno == Y_REGNUM)) - read_register_gen (Y_REGNUM, (char *) (regp + R_Y) + offset); - - if (GDB_TARGET_IS_SPARC64) - { -#ifdef R_CCR - if (regno == -1 || regno == CCR_REGNUM) - read_register_gen (CCR_REGNUM, ((char *) (regp + R_CCR)) + offset); -#endif -#ifdef R_FPRS - if (regno == -1 || regno == FPRS_REGNUM) - read_register_gen (FPRS_REGNUM, ((char *) (regp + R_FPRS)) + offset); -#endif -#ifdef R_ASI - if (regno == -1 || regno == ASI_REGNUM) - read_register_gen (ASI_REGNUM, ((char *) (regp + R_ASI)) + offset); -#endif - } - else /* sparc32 */ - { -#ifdef R_PS - if (regno == -1 || regno == PS_REGNUM) - read_register_gen (PS_REGNUM, ((char *) (regp + R_PS)) + offset); -#endif - - /* For 64-bit hosts, R_WIM and R_TBR may not be defined. - Steal R_ASI and R_FPRS, and hope for the best! */ - -#if !defined (R_WIM) && defined (R_ASI) -#define R_WIM R_ASI -#endif - -#if !defined (R_TBR) && defined (R_FPRS) -#define R_TBR R_FPRS -#endif - -#if defined (R_WIM) - if (regno == -1 || regno == WIM_REGNUM) - read_register_gen (WIM_REGNUM, ((char *) (regp + R_WIM)) + offset); -#else - if (regno == -1 || regno == WIM_REGNUM) - read_register_gen (WIM_REGNUM, NULL); -#endif - -#if defined (R_TBR) - if (regno == -1 || regno == TBR_REGNUM) - read_register_gen (TBR_REGNUM, ((char *) (regp + R_TBR)) + offset); -#else - if (regno == -1 || regno == TBR_REGNUM) - read_register_gen (TBR_REGNUM, NULL); -#endif - } -} - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), unpack the register contents and supply them as gdb's - idea of the current floating point register values. */ - -void -supply_fpregset (gdb_fpregset_t *fpregsetp) -{ - register int regi; - char *from; - - if (!SPARC_HAS_FPU) - return; - - for (regi = FP0_REGNUM; regi < FP_MAX_REGNUM; regi++) - { - from = (char *) &fpregsetp->pr_fr.pr_regs[regi - FP0_REGNUM]; - supply_register (regi, from); - } - - if (GDB_TARGET_IS_SPARC64) - { - /* - * don't know how to get value of the following. - */ - supply_register (FSR_REGNUM, NULL); /* zero it out for now */ - supply_register (FCC0_REGNUM, NULL); - supply_register (FCC1_REGNUM, NULL); /* don't know how to get value */ - supply_register (FCC2_REGNUM, NULL); /* don't know how to get value */ - supply_register (FCC3_REGNUM, NULL); /* don't know how to get value */ - } - else - { - supply_register (FPS_REGNUM, (char *) &(fpregsetp->pr_fsr)); - } -} - -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), update the register specified by REGNO from gdb's idea - of the current floating point register set. If REGNO is -1, update - them all. */ -/* This will probably need some changes for sparc64. */ - -void -fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) -{ - int regi; - char *to; - char *from; - - if (!SPARC_HAS_FPU) - return; - - for (regi = FP0_REGNUM; regi < FP_MAX_REGNUM; regi++) - { - if ((regno == -1) || (regno == regi)) - { - from = (char *) ®isters[REGISTER_BYTE (regi)]; - to = (char *) &fpregsetp->pr_fr.pr_regs[regi - FP0_REGNUM]; - memcpy (to, from, REGISTER_RAW_SIZE (regi)); - } - } - - if (!(GDB_TARGET_IS_SPARC64)) /* FIXME: does Sparc64 have this register? */ - if ((regno == -1) || (regno == FPS_REGNUM)) - { - from = (char *)®isters[REGISTER_BYTE (FPS_REGNUM)]; - to = (char *) &fpregsetp->pr_fsr; - memcpy (to, from, REGISTER_RAW_SIZE (FPS_REGNUM)); - } -} - -#endif /* USE_PROC_FS */ - -/* Because of Multi-arch, GET_LONGJMP_TARGET is always defined. So test - for a definition of JB_PC. */ -#ifdef JB_PC - -/* Figure out where the longjmp will land. We expect that we have just entered - longjmp and haven't yet setup the stack frame, so the args are still in the - output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we - extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. - This routine returns true on success */ - -int -get_longjmp_target (CORE_ADDR *pc) -{ - CORE_ADDR jb_addr; -#define LONGJMP_TARGET_SIZE 4 - char buf[LONGJMP_TARGET_SIZE]; - - jb_addr = read_register (O0_REGNUM); - - if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, - LONGJMP_TARGET_SIZE)) - return 0; - - *pc = extract_address (buf, LONGJMP_TARGET_SIZE); - - return 1; -} -#endif /* GET_LONGJMP_TARGET */ - -#ifdef STATIC_TRANSFORM_NAME -/* SunPRO (3.0 at least), encodes the static variables. This is not - related to C++ mangling, it is done for C too. */ +/* Unglobalize NAME. */ char * -sunpro_static_transform_name (char *name) +sparc_stabs_unglobalize_name (char *name) { - char *p; + /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop, + SunPRO) convert file static variables into global values, a + process known as globalization. In order to do this, the + compiler will create a unique prefix and prepend it to each file + static variable. For static variables within a function, this + globalization prefix is followed by the function name (nested + static variables within a function are supposed to generate a + warning message, and are left alone). The procedure is + documented in the Stabs Interface Manual, which is distrubuted + with the compilers, although version 4.0 of the manual seems to + be incorrect in some places, at least for SPARC. The + globalization prefix is encoded into an N_OPT stab, with the form + "G=". The globalization prefix always seems to start + with a dollar sign '$'; a dot '.' is used as a seperator. So we + simply strip everything up until the last dot. */ + if (name[0] == '$') { - /* For file-local statics there will be a dollar sign, a bunch - of junk (the contents of which match a string given in the - N_OPT), a period and the name. For function-local statics - there will be a bunch of junk (which seems to change the - second character from 'A' to 'B'), a period, the name of the - function, and the name. So just skip everything before the - last period. */ - p = strrchr (name, '.'); - if (p != NULL) - name = p + 1; + char *p = strrchr (name, '.'); + if (p) + return p + 1; } + return name; } -#endif /* STATIC_TRANSFORM_NAME */ -/* Utilities for printing registers. - Page numbers refer to the SPARC Architecture Manual. */ +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ -static void dump_ccreg (char *, int); - -static void -dump_ccreg (char *reg, int val) +const struct regset * +sparc_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) { - /* page 41 */ - printf_unfiltered ("%s:%s,%s,%s,%s", reg, - val & 8 ? "N" : "NN", - val & 4 ? "Z" : "NZ", - val & 2 ? "O" : "NO", - val & 1 ? "C" : "NC"); -} + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -static char * -decode_asi (int val) -{ - /* page 72 */ - switch (val) - { - case 4: - return "ASI_NUCLEUS"; - case 0x0c: - return "ASI_NUCLEUS_LITTLE"; - case 0x10: - return "ASI_AS_IF_USER_PRIMARY"; - case 0x11: - return "ASI_AS_IF_USER_SECONDARY"; - case 0x18: - return "ASI_AS_IF_USER_PRIMARY_LITTLE"; - case 0x19: - return "ASI_AS_IF_USER_SECONDARY_LITTLE"; - case 0x80: - return "ASI_PRIMARY"; - case 0x81: - return "ASI_SECONDARY"; - case 0x82: - return "ASI_PRIMARY_NOFAULT"; - case 0x83: - return "ASI_SECONDARY_NOFAULT"; - case 0x88: - return "ASI_PRIMARY_LITTLE"; - case 0x89: - return "ASI_SECONDARY_LITTLE"; - case 0x8a: - return "ASI_PRIMARY_NOFAULT_LITTLE"; - case 0x8b: - return "ASI_SECONDARY_NOFAULT_LITTLE"; - default: - return NULL; - } -} + if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset) + return tdep->gregset; -/* PRINT_REGISTER_HOOK routine. - Pretty print various registers. */ -/* FIXME: Would be nice if this did some fancy things for 32 bit sparc. */ + if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset) + return tdep->fpregset; -void -sparc_print_register_hook (int regno) -{ - ULONGEST val; - - /* Handle double/quad versions of lower 32 fp regs. */ - if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32 - && (regno & 1) == 0) - { - char value[16]; - - if (!read_relative_register_raw_bytes (regno, value) - && !read_relative_register_raw_bytes (regno + 1, value + 4)) - { - printf_unfiltered ("\t"); - print_floating (value, builtin_type_double, gdb_stdout); - } -#if 0 /* FIXME: gdb doesn't handle long doubles */ - if ((regno & 3) == 0) - { - if (!read_relative_register_raw_bytes (regno + 2, value + 8) - && !read_relative_register_raw_bytes (regno + 3, value + 12)) - { - printf_unfiltered ("\t"); - print_floating (value, builtin_type_long_double, gdb_stdout); - } - } -#endif - return; - } - -#if 0 /* FIXME: gdb doesn't handle long doubles */ - /* Print upper fp regs as long double if appropriate. */ - if (regno >= FP0_REGNUM + 32 && regno < FP_MAX_REGNUM - /* We test for even numbered regs and not a multiple of 4 because - the upper fp regs are recorded as doubles. */ - && (regno & 1) == 0) - { - char value[16]; - - if (!read_relative_register_raw_bytes (regno, value) - && !read_relative_register_raw_bytes (regno + 1, value + 8)) - { - printf_unfiltered ("\t"); - print_floating (value, builtin_type_long_double, gdb_stdout); - } - return; - } -#endif - - /* FIXME: Some of these are priviledged registers. - Not sure how they should be handled. */ - -#define BITS(n, mask) ((int) (((val) >> (n)) & (mask))) - - val = read_register (regno); - - /* pages 40 - 60 */ - if (GDB_TARGET_IS_SPARC64) - switch (regno) - { - case CCR_REGNUM: - printf_unfiltered ("\t"); - dump_ccreg ("xcc", val >> 4); - printf_unfiltered (", "); - dump_ccreg ("icc", val & 15); - break; - case FPRS_REGNUM: - printf ("\tfef:%d, du:%d, dl:%d", - BITS (2, 1), BITS (1, 1), BITS (0, 1)); - break; - case FSR_REGNUM: - { - static char *fcc[4] = - {"=", "<", ">", "?"}; - static char *rd[4] = - {"N", "0", "+", "-"}; - /* Long, but I'd rather leave it as is and use a wide screen. */ - printf_filtered ("\t0:%s, 1:%s, 2:%s, 3:%s, rd:%s, tem:%d, ", - fcc[BITS (10, 3)], fcc[BITS (32, 3)], - fcc[BITS (34, 3)], fcc[BITS (36, 3)], - rd[BITS (30, 3)], BITS (23, 31)); - printf_filtered ("ns:%d, ver:%d, ftt:%d, qne:%d, aexc:%d, cexc:%d", - BITS (22, 1), BITS (17, 7), BITS (14, 7), - BITS (13, 1), BITS (5, 31), BITS (0, 31)); - break; - } - case ASI_REGNUM: - { - char *asi = decode_asi (val); - if (asi != NULL) - printf ("\t%s", asi); - break; - } - case VER_REGNUM: - printf ("\tmanuf:%d, impl:%d, mask:%d, maxtl:%d, maxwin:%d", - BITS (48, 0xffff), BITS (32, 0xffff), - BITS (24, 0xff), BITS (8, 0xff), BITS (0, 31)); - break; - case PSTATE_REGNUM: - { - static char *mm[4] = - {"tso", "pso", "rso", "?"}; - printf_filtered ("\tcle:%d, tle:%d, mm:%s, red:%d, ", - BITS (9, 1), BITS (8, 1), - mm[BITS (6, 3)], BITS (5, 1)); - printf_filtered ("pef:%d, am:%d, priv:%d, ie:%d, ag:%d", - BITS (4, 1), BITS (3, 1), BITS (2, 1), - BITS (1, 1), BITS (0, 1)); - break; - } - case TSTATE_REGNUM: - /* FIXME: print all 4? */ - break; - case TT_REGNUM: - /* FIXME: print all 4? */ - break; - case TPC_REGNUM: - /* FIXME: print all 4? */ - break; - case TNPC_REGNUM: - /* FIXME: print all 4? */ - break; - case WSTATE_REGNUM: - printf ("\tother:%d, normal:%d", BITS (3, 7), BITS (0, 7)); - break; - case CWP_REGNUM: - printf ("\t%d", BITS (0, 31)); - break; - case CANSAVE_REGNUM: - printf ("\t%-2d before spill", BITS (0, 31)); - break; - case CANRESTORE_REGNUM: - printf ("\t%-2d before fill", BITS (0, 31)); - break; - case CLEANWIN_REGNUM: - printf ("\t%-2d before clean", BITS (0, 31)); - break; - case OTHERWIN_REGNUM: - printf ("\t%d", BITS (0, 31)); - break; - } - else /* Sparc32 */ - switch (regno) - { - case PS_REGNUM: - printf ("\ticc:%c%c%c%c, pil:%d, s:%d, ps:%d, et:%d, cwp:%d", - BITS (23, 1) ? 'N' : '-', BITS (22, 1) ? 'Z' : '-', - BITS (21, 1) ? 'V' : '-', BITS (20, 1) ? 'C' : '-', - BITS (8, 15), BITS (7, 1), BITS (6, 1), BITS (5, 1), - BITS (0, 31)); - break; - case FPS_REGNUM: - { - static char *fcc[4] = - {"=", "<", ">", "?"}; - static char *rd[4] = - {"N", "0", "+", "-"}; - /* Long, but I'd rather leave it as is and use a wide screen. */ - printf ("\trd:%s, tem:%d, ns:%d, ver:%d, ftt:%d, qne:%d, " - "fcc:%s, aexc:%d, cexc:%d", - rd[BITS (30, 3)], BITS (23, 31), BITS (22, 1), BITS (17, 7), - BITS (14, 7), BITS (13, 1), fcc[BITS (10, 3)], BITS (5, 31), - BITS (0, 31)); - break; - } - } - -#undef BITS + return NULL; } -int -gdb_print_insn_sparc (bfd_vma memaddr, disassemble_info *info) -{ - /* It's necessary to override mach again because print_insn messes it up. */ - info->mach = TARGET_ARCHITECTURE->mach; - return print_insn_sparc (memaddr, info); -} - -/* The SPARC passes the arguments on the stack; arguments smaller - than an int are promoted to an int. The first 6 words worth of - args are also passed in registers o0 - o5. */ - -CORE_ADDR -sparc32_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) -{ - int i, j, oregnum; - int accumulate_size = 0; - struct sparc_arg - { - char *contents; - int len; - int offset; - }; - struct sparc_arg *sparc_args = - (struct sparc_arg *) alloca (nargs * sizeof (struct sparc_arg)); - struct sparc_arg *m_arg; - - /* Promote arguments if necessary, and calculate their stack offsets - and sizes. */ - for (i = 0, m_arg = sparc_args; i < nargs; i++, m_arg++) - { - struct value *arg = args[i]; - struct type *arg_type = check_typedef (VALUE_TYPE (arg)); - /* Cast argument to long if necessary as the compiler does it too. */ - switch (TYPE_CODE (arg_type)) - { - case TYPE_CODE_INT: - case TYPE_CODE_BOOL: - case TYPE_CODE_CHAR: - case TYPE_CODE_RANGE: - case TYPE_CODE_ENUM: - if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long)) - { - arg_type = builtin_type_long; - arg = value_cast (arg_type, arg); - } - break; - default: - break; - } - m_arg->len = TYPE_LENGTH (arg_type); - m_arg->offset = accumulate_size; - accumulate_size = (accumulate_size + m_arg->len + 3) & ~3; - m_arg->contents = VALUE_CONTENTS (arg); - } - - /* Make room for the arguments on the stack. */ - accumulate_size += CALL_DUMMY_STACK_ADJUST; - sp = ((sp - accumulate_size) & ~7) + CALL_DUMMY_STACK_ADJUST; - - /* `Push' arguments on the stack. */ - for (i = 0, oregnum = 0, m_arg = sparc_args; - i < nargs; - i++, m_arg++) - { - write_memory (sp + m_arg->offset, m_arg->contents, m_arg->len); - for (j = 0; - j < m_arg->len && oregnum < 6; - j += SPARC_INTREG_SIZE, oregnum++) - write_register_gen (O0_REGNUM + oregnum, m_arg->contents + j); - } - - return sp; -} - - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -void -sparc32_extract_return_value (struct type *type, char *regbuf, char *valbuf) -{ - int typelen = TYPE_LENGTH (type); - int regsize = REGISTER_RAW_SIZE (O0_REGNUM); - - if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU) - memcpy (valbuf, ®buf[REGISTER_BYTE (FP0_REGNUM)], typelen); - else - memcpy (valbuf, - ®buf[O0_REGNUM * regsize + - (typelen >= regsize - || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE ? 0 - : regsize - typelen)], - typelen); -} - - -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. On SPARCs with FPUs, - float values are returned in %f0 (and %f1). In all other cases, - values are returned in register %o0. */ - -void -sparc_store_return_value (struct type *type, char *valbuf) -{ - int regno; - char *buffer; - - buffer = alloca (MAX_REGISTER_RAW_SIZE); - - if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU) - /* Floating-point values are returned in the register pair */ - /* formed by %f0 and %f1 (doubles are, anyway). */ - regno = FP0_REGNUM; - else - /* Other values are returned in register %o0. */ - regno = O0_REGNUM; - - /* Add leading zeros to the value. */ - if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (regno)) - { - memset (buffer, 0, REGISTER_RAW_SIZE (regno)); - memcpy (buffer + REGISTER_RAW_SIZE (regno) - TYPE_LENGTH (type), valbuf, - TYPE_LENGTH (type)); - write_register_gen (regno, buffer); - } - else - write_register_bytes (REGISTER_BYTE (regno), valbuf, TYPE_LENGTH (type)); -} - -extern void -sparclet_store_return_value (struct type *type, char *valbuf) -{ - /* Other values are returned in register %o0. */ - write_register_bytes (REGISTER_BYTE (O0_REGNUM), valbuf, - TYPE_LENGTH (type)); -} - - -#ifndef CALL_DUMMY_CALL_OFFSET -#define CALL_DUMMY_CALL_OFFSET \ - (gdbarch_tdep (current_gdbarch)->call_dummy_call_offset) -#endif /* CALL_DUMMY_CALL_OFFSET */ - -/* Insert the function address into a call dummy instruction sequence - stored at DUMMY. - - For structs and unions, if the function was compiled with Sun cc, - it expects 'unimp' after the call. But gcc doesn't use that - (twisted) convention. So leave a nop there for gcc (FIX_CALL_DUMMY - can assume it is operating on a pristine CALL_DUMMY, not one that - has already been customized for a different function). */ - -void -sparc_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, - struct type *value_type, int using_gcc) -{ - int i; - - /* Store the relative adddress of the target function into the - 'call' instruction. */ - store_unsigned_integer (dummy + CALL_DUMMY_CALL_OFFSET, 4, - (0x40000000 - | (((fun - (pc + CALL_DUMMY_CALL_OFFSET)) >> 2) - & 0x3fffffff))); - - /* If the called function returns an aggregate value, fill in the UNIMP - instruction containing the size of the returned aggregate return value, - which follows the call instruction. - For details see the SPARC Architecture Manual Version 8, Appendix D.3. - - Adjust the call_dummy_breakpoint_offset for the bp_call_dummy breakpoint - to the proper address in the call dummy, so that `finish' after a stop - in a call dummy works. - Tweeking current_gdbarch is not an optimal solution, but the call to - sparc_fix_call_dummy is immediately followed by a call to run_stack_dummy, - which is the only function where dummy_breakpoint_offset is actually - used, if it is non-zero. */ - if (TYPE_CODE (value_type) == TYPE_CODE_STRUCT - || TYPE_CODE (value_type) == TYPE_CODE_UNION) - { - store_unsigned_integer (dummy + CALL_DUMMY_CALL_OFFSET + 8, 4, - TYPE_LENGTH (value_type) & 0x1fff); - set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 0x30); - } - else - set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 0x2c); - - if (!(GDB_TARGET_IS_SPARC64)) - { - /* If this is not a simulator target, change the first four - instructions of the call dummy to NOPs. Those instructions - include a 'save' instruction and are designed to work around - problems with register window flushing in the simulator. */ - - if (strcmp (target_shortname, "sim") != 0) - { - for (i = 0; i < 4; i++) - store_unsigned_integer (dummy + (i * 4), 4, 0x01000000); - } - } - - /* If this is a bi-endian target, GDB has written the call dummy - in little-endian order. We must byte-swap it back to big-endian. */ - if (bi_endian) - { - for (i = 0; i < CALL_DUMMY_LENGTH; i += 4) - { - char tmp = dummy[i]; - dummy[i] = dummy[i + 3]; - dummy[i + 3] = tmp; - tmp = dummy[i + 1]; - dummy[i + 1] = dummy[i + 2]; - dummy[i + 2] = tmp; - } - } -} - - -/* Set target byte order based on machine type. */ - -static int -sparc_target_architecture_hook (const bfd_arch_info_type *ap) -{ - int i, j; - - if (ap->mach == bfd_mach_sparc_sparclite_le) - { - target_byte_order = BFD_ENDIAN_LITTLE; - bi_endian = 1; - } - else - bi_endian = 0; - return 1; -} - - -/* - * Module "constructor" function. - */ - -static struct gdbarch * sparc_gdbarch_init (struct gdbarch_info info, - struct gdbarch_list *arches); - -void -_initialize_sparc_tdep (void) -{ - /* Hook us into the gdbarch mechanism. */ - register_gdbarch_init (bfd_arch_sparc, sparc_gdbarch_init); - - tm_print_insn = gdb_print_insn_sparc; - tm_print_insn_info.mach = TM_PRINT_INSN_MACH; /* Selects sparc/sparclite */ - target_architecture_hook = sparc_target_architecture_hook; -} - -/* Compensate for stack bias. Note that we currently don't handle - mixed 32/64 bit code. */ - -CORE_ADDR -sparc64_read_sp (void) -{ - CORE_ADDR sp = read_register (SP_REGNUM); - - if (sp & 1) - sp += 2047; - return sp; -} - -CORE_ADDR -sparc64_read_fp (void) -{ - CORE_ADDR fp = read_register (FP_REGNUM); - - if (fp & 1) - fp += 2047; - return fp; -} - -void -sparc64_write_sp (CORE_ADDR val) -{ - CORE_ADDR oldsp = read_register (SP_REGNUM); - if (oldsp & 1) - write_register (SP_REGNUM, val - 2047); - else - write_register (SP_REGNUM, val); -} - -void -sparc64_write_fp (CORE_ADDR val) -{ - CORE_ADDR oldfp = read_register (FP_REGNUM); - if (oldfp & 1) - write_register (FP_REGNUM, val - 2047); - else - write_register (FP_REGNUM, val); -} - -/* The SPARC 64 ABI passes floating-point arguments in FP0 to FP31, - and all other arguments in O0 to O5. They are also copied onto - the stack in the correct places. Apparently (empirically), - structs of less than 16 bytes are passed member-by-member in - separate registers, but I am unable to figure out the algorithm. - Some members go in floating point regs, but I don't know which. - - FIXME: Handle small structs (less than 16 bytes containing floats). - - The counting regimen for using both integer and FP registers - for argument passing is rather odd -- a single counter is used - for both; this means that if the arguments alternate between - int and float, we will waste every other register of both types. */ - -CORE_ADDR -sparc64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_retaddr) -{ - int i, j, register_counter = 0; - CORE_ADDR tempsp; - struct type *sparc_intreg_type = - TYPE_LENGTH (builtin_type_long) == SPARC_INTREG_SIZE ? - builtin_type_long : builtin_type_long_long; - - sp = (sp & ~(((unsigned long) SPARC_INTREG_SIZE) - 1UL)); - - /* Figure out how much space we'll need. */ - for (i = nargs - 1; i >= 0; i--) - { - int len = TYPE_LENGTH (check_typedef (VALUE_TYPE (args[i]))); - struct value *copyarg = args[i]; - int copylen = len; - - if (copylen < SPARC_INTREG_SIZE) - { - copyarg = value_cast (sparc_intreg_type, copyarg); - copylen = SPARC_INTREG_SIZE; - } - sp -= copylen; - } - - /* Round down. */ - sp = sp & ~7; - tempsp = sp; - - /* if STRUCT_RETURN, then first argument is the struct return location. */ - if (struct_return) - write_register (O0_REGNUM + register_counter++, struct_retaddr); - - /* Now write the arguments onto the stack, while writing FP - arguments into the FP registers, and other arguments into the - first six 'O' registers. */ - - for (i = 0; i < nargs; i++) - { - int len = TYPE_LENGTH (check_typedef (VALUE_TYPE (args[i]))); - struct value *copyarg = args[i]; - enum type_code typecode = TYPE_CODE (VALUE_TYPE (args[i])); - int copylen = len; - - if (typecode == TYPE_CODE_INT || - typecode == TYPE_CODE_BOOL || - typecode == TYPE_CODE_CHAR || - typecode == TYPE_CODE_RANGE || - typecode == TYPE_CODE_ENUM) - if (len < SPARC_INTREG_SIZE) - { - /* Small ints will all take up the size of one intreg on - the stack. */ - copyarg = value_cast (sparc_intreg_type, copyarg); - copylen = SPARC_INTREG_SIZE; - } - - write_memory (tempsp, VALUE_CONTENTS (copyarg), copylen); - tempsp += copylen; - - /* Corner case: Structs consisting of a single float member are floats. - * FIXME! I don't know about structs containing multiple floats! - * Structs containing mixed floats and ints are even more weird. - */ - - - - /* Separate float args from all other args. */ - if (typecode == TYPE_CODE_FLT && SPARC_HAS_FPU) - { - if (register_counter < 16) - { - /* This arg gets copied into a FP register. */ - int fpreg; - - switch (len) { - case 4: /* Single-precision (float) */ - fpreg = FP0_REGNUM + 2 * register_counter + 1; - register_counter += 1; - break; - case 8: /* Double-precision (double) */ - fpreg = FP0_REGNUM + 2 * register_counter; - register_counter += 1; - break; - case 16: /* Quad-precision (long double) */ - fpreg = FP0_REGNUM + 2 * register_counter; - register_counter += 2; - break; - default: - internal_error (__FILE__, __LINE__, "bad switch"); - } - write_register_bytes (REGISTER_BYTE (fpreg), - VALUE_CONTENTS (args[i]), - len); - } - } - else /* all other args go into the first six 'o' registers */ - { - for (j = 0; - j < len && register_counter < 6; - j += SPARC_INTREG_SIZE) - { - int oreg = O0_REGNUM + register_counter; - - write_register_gen (oreg, VALUE_CONTENTS (copyarg) + j); - register_counter += 1; - } - } - } - return sp; -} - -/* Values <= 32 bytes are returned in o0-o3 (floating-point values are - returned in f0-f3). */ - -void -sp64_extract_return_value (struct type *type, char *regbuf, char *valbuf, - int bitoffset) -{ - int typelen = TYPE_LENGTH (type); - int regsize = REGISTER_RAW_SIZE (O0_REGNUM); - - if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU) - { - memcpy (valbuf, ®buf[REGISTER_BYTE (FP0_REGNUM)], typelen); - return; - } - - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - || (TYPE_LENGTH (type) > 32)) - { - memcpy (valbuf, - ®buf[O0_REGNUM * regsize + - (typelen >= regsize ? 0 : regsize - typelen)], - typelen); - return; - } - else - { - char *o0 = ®buf[O0_REGNUM * regsize]; - char *f0 = ®buf[FP0_REGNUM * regsize]; - int x; - - for (x = 0; x < TYPE_NFIELDS (type); x++) - { - struct field *f = &TYPE_FIELDS (type)[x]; - /* FIXME: We may need to handle static fields here. */ - int whichreg = (f->loc.bitpos + bitoffset) / 32; - int remainder = ((f->loc.bitpos + bitoffset) % 32) / 8; - int where = (f->loc.bitpos + bitoffset) / 8; - int size = TYPE_LENGTH (f->type); - int typecode = TYPE_CODE (f->type); - - if (typecode == TYPE_CODE_STRUCT) - { - sp64_extract_return_value (f->type, - regbuf, - valbuf, - bitoffset + f->loc.bitpos); - } - else if (typecode == TYPE_CODE_FLT && SPARC_HAS_FPU) - { - memcpy (valbuf + where, &f0[whichreg * 4] + remainder, size); - } - else - { - memcpy (valbuf + where, &o0[whichreg * 4] + remainder, size); - } - } - } -} - -extern void -sparc64_extract_return_value (struct type *type, char *regbuf, char *valbuf) -{ - sp64_extract_return_value (type, regbuf, valbuf, 0); -} - -extern void -sparclet_extract_return_value (struct type *type, - char *regbuf, - char *valbuf) -{ - regbuf += REGISTER_RAW_SIZE (O0_REGNUM) * 8; - if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (O0_REGNUM)) - regbuf += REGISTER_RAW_SIZE (O0_REGNUM) - TYPE_LENGTH (type); - - memcpy ((void *) valbuf, regbuf, TYPE_LENGTH (type)); -} - - -extern CORE_ADDR -sparc32_stack_align (CORE_ADDR addr) -{ - return ((addr + 7) & -8); -} - -extern CORE_ADDR -sparc64_stack_align (CORE_ADDR addr) -{ - return ((addr + 15) & -16); -} - -extern void -sparc_print_extra_frame_info (struct frame_info *fi) -{ - if (fi && fi->extra_info && fi->extra_info->flat) - printf_filtered (" flat, pc saved at 0x%s, fp saved at 0x%s\n", - paddr_nz (fi->extra_info->pc_addr), - paddr_nz (fi->extra_info->fp_addr)); -} - -/* MULTI_ARCH support */ - -static char * -sparc32_register_name (int regno) -{ - static char *register_names[] = - { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - - "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" - }; - - if (regno < 0 || - regno >= (sizeof (register_names) / sizeof (register_names[0]))) - return NULL; - else - return register_names[regno]; -} - -static char * -sparc64_register_name (int regno) -{ - static char *register_names[] = - { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", - "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", - - "pc", "npc", "ccr", "fsr", "fprs", "y", "asi", "ver", - "tick", "pil", "pstate", "tstate", "tba", "tl", "tt", "tpc", - "tnpc", "wstate", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", - "asr16", "asr17", "asr18", "asr19", "asr20", "asr21", "asr22", "asr23", - "asr24", "asr25", "asr26", "asr27", "asr28", "asr29", "asr30", "asr31", - /* These are here at the end to simplify removing them if we have to. */ - "icc", "xcc", "fcc0", "fcc1", "fcc2", "fcc3" - }; - - if (regno < 0 || - regno >= (sizeof (register_names) / sizeof (register_names[0]))) - return NULL; - else - return register_names[regno]; -} - -static char * -sparclite_register_name (int regno) -{ - static char *register_names[] = - { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - - "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr", - "dia1", "dia2", "dda1", "dda2", "ddv1", "ddv2", "dcr", "dsr" - }; - - if (regno < 0 || - regno >= (sizeof (register_names) / sizeof (register_names[0]))) - return NULL; - else - return register_names[regno]; -} - -static char * -sparclet_register_name (int regno) -{ - static char *register_names[] = - { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "", "", "", "", "", "", "", "", /* no floating point registers */ - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - - "y", "psr", "wim", "tbr", "pc", "npc", "", "", /* no FPSR or CPSR */ - "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", - - /* ASR15 ASR19 (don't display them) */ - "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22" - /* None of the rest get displayed */ -#if 0 - "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", - "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", - "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", - "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", - "apsr" -#endif /* 0 */ - }; - - if (regno < 0 || - regno >= (sizeof (register_names) / sizeof (register_names[0]))) - return NULL; - else - return register_names[regno]; -} - -CORE_ADDR -sparc_push_return_address (CORE_ADDR pc_unused, CORE_ADDR sp) -{ - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) - { - /* The return PC of the dummy_frame is the former 'current' PC - (where we were before we made the target function call). - This is saved in %i7 by push_dummy_frame. - - We will save the 'call dummy location' (ie. the address - to which the target function will return) in %o7. - This address will actually be the program's entry point. - There will be a special call_dummy breakpoint there. */ - - write_register (O7_REGNUM, - CALL_DUMMY_ADDRESS () - 8); - } - - return sp; -} - -/* Should call_function allocate stack space for a struct return? */ - -static int -sparc64_use_struct_convention (int gcc_p, struct type *type) -{ - return (TYPE_LENGTH (type) > 32); -} - -/* Store the address of the place in which to copy the structure the - subroutine will return. This is called from call_function_by_hand. - The ultimate mystery is, tho, what is the value "16"? - - MVS: That's the offset from where the sp is now, to where the - subroutine is gonna expect to find the struct return address. */ - -static void -sparc32_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - char *val; - CORE_ADDR o7; - - val = alloca (SPARC_INTREG_SIZE); - store_unsigned_integer (val, SPARC_INTREG_SIZE, addr); - write_memory (sp + (16 * SPARC_INTREG_SIZE), val, SPARC_INTREG_SIZE); - - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) - { - /* Now adjust the value of the link register, which was previously - stored by push_return_address. Functions that return structs are - peculiar in that they return to link register + 12, rather than - link register + 8. */ - - o7 = read_register (O7_REGNUM); - write_register (O7_REGNUM, o7 - 4); - } -} - -static void -sparc64_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - /* FIXME: V9 uses %o0 for this. */ - /* FIXME MVS: Only for small enough structs!!! */ - - target_write_memory (sp + (16 * SPARC_INTREG_SIZE), - (char *) &addr, SPARC_INTREG_SIZE); -#if 0 - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) - { - /* Now adjust the value of the link register, which was previously - stored by push_return_address. Functions that return structs are - peculiar in that they return to link register + 12, rather than - link register + 8. */ - - write_register (O7_REGNUM, read_register (O7_REGNUM) - 4); - } -#endif -} - -/* Default target data type for register REGNO. */ - -static struct type * -sparc32_register_virtual_type (int regno) -{ - if (regno == PC_REGNUM || - regno == FP_REGNUM || - regno == SP_REGNUM) - return builtin_type_unsigned_int; - if (regno < 32) - return builtin_type_int; - if (regno < 64) - return builtin_type_float; - return builtin_type_int; -} - -static struct type * -sparc64_register_virtual_type (int regno) -{ - if (regno == PC_REGNUM || - regno == FP_REGNUM || - regno == SP_REGNUM) - return builtin_type_unsigned_long_long; - if (regno < 32) - return builtin_type_long_long; - if (regno < 64) - return builtin_type_float; - if (regno < 80) - return builtin_type_double; - return builtin_type_long_long; -} - -/* Number of bytes of storage in the actual machine representation for - register REGNO. */ - -static int -sparc32_register_size (int regno) -{ - return 4; -} - -static int -sparc64_register_size (int regno) -{ - return (regno < 32 ? 8 : regno < 64 ? 4 : 8); -} - -/* Index within the `registers' buffer of the first byte of the space - for register REGNO. */ - -static int -sparc32_register_byte (int regno) -{ - return (regno * 4); -} - -static int -sparc64_register_byte (int regno) -{ - if (regno < 32) - return regno * 8; - else if (regno < 64) - return 32 * 8 + (regno - 32) * 4; - else if (regno < 80) - return 32 * 8 + 32 * 4 + (regno - 64) * 8; - else - return 64 * 8 + (regno - 80) * 8; -} - -/* Advance PC across any function entry prologue instructions to reach - some "real" code. SKIP_PROLOGUE_FRAMELESS_P advances the PC past - some of the prologue, but stops as soon as it knows that the - function has a frame. Its result is equal to its input PC if the - function is frameless, unequal otherwise. */ - -static CORE_ADDR -sparc_gdbarch_skip_prologue (CORE_ADDR ip) -{ - return examine_prologue (ip, 0, NULL, NULL); -} - -/* Immediately after a function call, return the saved pc. - Can't go through the frames for this because on some machines - the new frame is not set up until the new function executes - some instructions. */ - -static CORE_ADDR -sparc_saved_pc_after_call (struct frame_info *fi) -{ - return sparc_pc_adjust (read_register (RP_REGNUM)); -} - -/* Convert registers between 'raw' and 'virtual' formats. - They are the same on sparc, so there's nothing to do. */ - -static void -sparc_convert_to_virtual (int regnum, struct type *type, char *from, char *to) -{ /* do nothing (should never be called) */ -} - -static void -sparc_convert_to_raw (struct type *type, int regnum, char *from, char *to) -{ /* do nothing (should never be called) */ -} - -/* Init saved regs: nothing to do, just a place-holder function. */ - -static void -sparc_frame_init_saved_regs (struct frame_info *fi_ignored) -{ /* no-op */ -} - -/* gdbarch fix call dummy: - All this function does is rearrange the arguments before calling - sparc_fix_call_dummy (which does the real work). */ - -static void -sparc_gdbarch_fix_call_dummy (char *dummy, - CORE_ADDR pc, - CORE_ADDR fun, - int nargs, - struct value **args, - struct type *type, - int gcc_p) -{ - if (CALL_DUMMY_LOCATION == ON_STACK) - sparc_fix_call_dummy (dummy, pc, fun, type, gcc_p); -} - -/* Coerce float to double: a no-op. */ - -static int -sparc_coerce_float_to_double (struct type *formal, struct type *actual) -{ - return 1; -} - -/* CALL_DUMMY_ADDRESS: fetch the breakpoint address for a call dummy. */ - -static CORE_ADDR -sparc_call_dummy_address (void) -{ - return (CALL_DUMMY_START_OFFSET) + CALL_DUMMY_BREAKPOINT_OFFSET; -} - -/* Supply the Y register number to those that need it. */ - -int -sparc_y_regnum (void) -{ - return gdbarch_tdep (current_gdbarch)->y_regnum; -} - -int -sparc_reg_struct_has_addr (int gcc_p, struct type *type) -{ - if (GDB_TARGET_IS_SPARC64) - return (TYPE_LENGTH (type) > 32); - else - return (gcc_p != 1); -} - -int -sparc_intreg_size (void) -{ - return SPARC_INTREG_SIZE; -} - -static int -sparc_return_value_on_stack (struct type *type) -{ - if (TYPE_CODE (type) == TYPE_CODE_FLT && - TYPE_LENGTH (type) > 8) - return 1; - else - return 0; -} - -/* - * Gdbarch "constructor" function. - */ - -#define SPARC32_CALL_DUMMY_ON_STACK - -#define SPARC_SP_REGNUM 14 -#define SPARC_FP_REGNUM 30 -#define SPARC_FP0_REGNUM 32 -#define SPARC32_NPC_REGNUM 69 -#define SPARC32_PC_REGNUM 68 -#define SPARC32_Y_REGNUM 64 -#define SPARC64_PC_REGNUM 80 -#define SPARC64_NPC_REGNUM 81 -#define SPARC64_Y_REGNUM 85 static struct gdbarch * -sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct gdbarch_tdep *tdep; + struct gdbarch *gdbarch; - static LONGEST call_dummy_32[] = - { 0xbc100001, 0x9de38000, 0xbc100002, 0xbe100003, - 0xda03a058, 0xd803a054, 0xd603a050, 0xd403a04c, - 0xd203a048, 0x40000000, 0xd003a044, 0x01000000, - 0x91d02001, 0x01000000 - }; - static LONGEST call_dummy_64[] = - { 0x9de3bec0fd3fa7f7LL, 0xf93fa7eff53fa7e7LL, - 0xf13fa7dfed3fa7d7LL, 0xe93fa7cfe53fa7c7LL, - 0xe13fa7bfdd3fa7b7LL, 0xd93fa7afd53fa7a7LL, - 0xd13fa79fcd3fa797LL, 0xc93fa78fc53fa787LL, - 0xc13fa77fcc3fa777LL, 0xc83fa76fc43fa767LL, - 0xc03fa75ffc3fa757LL, 0xf83fa74ff43fa747LL, - 0xf03fa73f01000000LL, 0x0100000001000000LL, - 0x0100000091580000LL, 0xd027a72b93500000LL, - 0xd027a72791480000LL, 0xd027a72391400000LL, - 0xd027a71fda5ba8a7LL, 0xd85ba89fd65ba897LL, - 0xd45ba88fd25ba887LL, 0x9fc02000d05ba87fLL, - 0x0100000091d02001LL, 0x0100000001000000LL - }; - static LONGEST call_dummy_nil[] = {0}; - - /* First see if there is already a gdbarch that can satisfy the request. */ + /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; - /* None found: is the request for a sparc architecture? */ - if (info.bfd_arch_info->arch != bfd_arch_sparc) - return NULL; /* No; then it's not for us. */ - - /* Yes: create a new gdbarch for the specified machine type. */ - tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep)); + /* Allocate space for the new architecture. */ + tdep = XMALLOC (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); - /* First set settings that are common for all sparc architectures. */ - set_gdbarch_believe_pcc_promotion (gdbarch, 1); - set_gdbarch_breakpoint_from_pc (gdbarch, memory_breakpoint_from_pc); - set_gdbarch_coerce_float_to_double (gdbarch, - sparc_coerce_float_to_double); - set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); - set_gdbarch_call_dummy_p (gdbarch, 1); - set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 1); - set_gdbarch_decr_pc_after_break (gdbarch, 0); - set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); - set_gdbarch_extract_struct_value_address (gdbarch, - sparc_extract_struct_value_address); - set_gdbarch_fix_call_dummy (gdbarch, sparc_gdbarch_fix_call_dummy); - set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT); - set_gdbarch_fp_regnum (gdbarch, SPARC_FP_REGNUM); - set_gdbarch_fp0_regnum (gdbarch, SPARC_FP0_REGNUM); - set_gdbarch_frame_args_address (gdbarch, default_frame_address); - set_gdbarch_frame_chain (gdbarch, sparc_frame_chain); - set_gdbarch_frame_init_saved_regs (gdbarch, sparc_frame_init_saved_regs); - set_gdbarch_frame_locals_address (gdbarch, default_frame_address); - set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); - set_gdbarch_frame_saved_pc (gdbarch, sparc_frame_saved_pc); - set_gdbarch_frameless_function_invocation (gdbarch, - frameless_look_for_prologue); - set_gdbarch_get_saved_register (gdbarch, sparc_get_saved_register); - set_gdbarch_init_extra_frame_info (gdbarch, sparc_init_extra_frame_info); + tdep->pc_regnum = SPARC32_PC_REGNUM; + tdep->npc_regnum = SPARC32_NPC_REGNUM; + tdep->gregset = NULL; + tdep->sizeof_gregset = 0; + tdep->fpregset = NULL; + tdep->sizeof_fpregset = 0; + tdep->plt_entry_size = 0; + + set_gdbarch_long_double_bit (gdbarch, 128); + set_gdbarch_long_double_format (gdbarch, &floatformat_sparc_quad); + + set_gdbarch_num_regs (gdbarch, SPARC32_NUM_REGS); + set_gdbarch_register_name (gdbarch, sparc32_register_name); + set_gdbarch_register_type (gdbarch, sparc32_register_type); + set_gdbarch_num_pseudo_regs (gdbarch, SPARC32_NUM_PSEUDO_REGS); + set_gdbarch_pseudo_register_read (gdbarch, sparc32_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, sparc32_pseudo_register_write); + + /* Register numbers of various important registers. */ + set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM); /* %sp */ + set_gdbarch_pc_regnum (gdbarch, SPARC32_PC_REGNUM); /* %pc */ + set_gdbarch_fp0_regnum (gdbarch, SPARC_F0_REGNUM); /* %f0 */ + + /* Call dummy code. */ + set_gdbarch_call_dummy_location (gdbarch, ON_STACK); + set_gdbarch_push_dummy_code (gdbarch, sparc32_push_dummy_code); + set_gdbarch_push_dummy_call (gdbarch, sparc32_push_dummy_call); + + set_gdbarch_return_value (gdbarch, sparc32_return_value); + set_gdbarch_stabs_argument_has_addr + (gdbarch, sparc32_stabs_argument_has_addr); + + set_gdbarch_skip_prologue (gdbarch, sparc32_skip_prologue); + + /* Stack grows downward. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); - set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT); - set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT); - set_gdbarch_max_register_raw_size (gdbarch, 8); - set_gdbarch_max_register_virtual_size (gdbarch, 8); - set_gdbarch_pop_frame (gdbarch, sparc_pop_frame); - set_gdbarch_push_return_address (gdbarch, sparc_push_return_address); - set_gdbarch_push_dummy_frame (gdbarch, sparc_push_dummy_frame); - set_gdbarch_read_pc (gdbarch, generic_target_read_pc); - set_gdbarch_register_convert_to_raw (gdbarch, sparc_convert_to_raw); - set_gdbarch_register_convert_to_virtual (gdbarch, - sparc_convert_to_virtual); - set_gdbarch_register_convertible (gdbarch, - generic_register_convertible_not); - set_gdbarch_reg_struct_has_addr (gdbarch, sparc_reg_struct_has_addr); - set_gdbarch_return_value_on_stack (gdbarch, sparc_return_value_on_stack); - set_gdbarch_saved_pc_after_call (gdbarch, sparc_saved_pc_after_call); - set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); - set_gdbarch_skip_prologue (gdbarch, sparc_gdbarch_skip_prologue); - set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM); - set_gdbarch_use_generic_dummy_frames (gdbarch, 0); - set_gdbarch_write_pc (gdbarch, generic_target_write_pc); - /* - * Settings that depend only on 32/64 bit word size - */ + set_gdbarch_breakpoint_from_pc (gdbarch, sparc_breakpoint_from_pc); - switch (info.bfd_arch_info->mach) - { - case bfd_mach_sparc: - case bfd_mach_sparc_sparclet: - case bfd_mach_sparc_sparclite: - case bfd_mach_sparc_v8plus: - case bfd_mach_sparc_v8plusa: - case bfd_mach_sparc_sparclite_le: - /* 32-bit machine types: */ + set_gdbarch_frame_args_skip (gdbarch, 8); -#ifdef SPARC32_CALL_DUMMY_ON_STACK - set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack); - set_gdbarch_call_dummy_address (gdbarch, sparc_call_dummy_address); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0x30); - set_gdbarch_call_dummy_length (gdbarch, 0x38); - set_gdbarch_call_dummy_location (gdbarch, ON_STACK); - set_gdbarch_call_dummy_words (gdbarch, call_dummy_32); -#else - set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point); - set_gdbarch_call_dummy_address (gdbarch, entry_point_address); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0); - set_gdbarch_call_dummy_length (gdbarch, 0); - set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT); - set_gdbarch_call_dummy_words (gdbarch, call_dummy_nil); -#endif - set_gdbarch_call_dummy_stack_adjust (gdbarch, 68); - set_gdbarch_call_dummy_start_offset (gdbarch, 0); - set_gdbarch_frame_args_skip (gdbarch, 68); - set_gdbarch_function_start_offset (gdbarch, 0); - set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT); - set_gdbarch_npc_regnum (gdbarch, SPARC32_NPC_REGNUM); - set_gdbarch_pc_regnum (gdbarch, SPARC32_PC_REGNUM); - set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT); - set_gdbarch_push_arguments (gdbarch, sparc32_push_arguments); - set_gdbarch_read_fp (gdbarch, generic_target_read_fp); - set_gdbarch_read_sp (gdbarch, generic_target_read_sp); + set_gdbarch_print_insn (gdbarch, print_insn_sparc); - set_gdbarch_register_byte (gdbarch, sparc32_register_byte); - set_gdbarch_register_raw_size (gdbarch, sparc32_register_size); - set_gdbarch_register_size (gdbarch, 4); - set_gdbarch_register_virtual_size (gdbarch, sparc32_register_size); - set_gdbarch_register_virtual_type (gdbarch, - sparc32_register_virtual_type); -#ifdef SPARC32_CALL_DUMMY_ON_STACK - set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_32)); -#else - set_gdbarch_sizeof_call_dummy_words (gdbarch, 0); -#endif - set_gdbarch_stack_align (gdbarch, sparc32_stack_align); - set_gdbarch_store_struct_return (gdbarch, sparc32_store_struct_return); - set_gdbarch_use_struct_convention (gdbarch, - generic_use_struct_convention); - set_gdbarch_write_fp (gdbarch, generic_target_write_fp); - set_gdbarch_write_sp (gdbarch, generic_target_write_sp); - tdep->y_regnum = SPARC32_Y_REGNUM; - tdep->fp_max_regnum = SPARC_FP0_REGNUM + 32; - tdep->intreg_size = 4; - tdep->reg_save_offset = 0x60; - tdep->call_dummy_call_offset = 0x24; - break; + set_gdbarch_software_single_step (gdbarch, sparc_software_single_step); + set_gdbarch_write_pc (gdbarch, sparc_write_pc); - case bfd_mach_sparc_v9: - case bfd_mach_sparc_v9a: - /* 64-bit machine types: */ - default: /* Any new machine type is likely to be 64-bit. */ + set_gdbarch_unwind_dummy_id (gdbarch, sparc_unwind_dummy_id); -#ifdef SPARC64_CALL_DUMMY_ON_STACK - set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack); - set_gdbarch_call_dummy_address (gdbarch, sparc_call_dummy_address); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 8 * 4); - set_gdbarch_call_dummy_length (gdbarch, 192); - set_gdbarch_call_dummy_location (gdbarch, ON_STACK); - set_gdbarch_call_dummy_start_offset (gdbarch, 148); - set_gdbarch_call_dummy_words (gdbarch, call_dummy_64); -#else - set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point); - set_gdbarch_call_dummy_address (gdbarch, entry_point_address); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0); - set_gdbarch_call_dummy_length (gdbarch, 0); - set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT); - set_gdbarch_call_dummy_start_offset (gdbarch, 0); - set_gdbarch_call_dummy_words (gdbarch, call_dummy_nil); -#endif - set_gdbarch_call_dummy_stack_adjust (gdbarch, 128); - set_gdbarch_frame_args_skip (gdbarch, 136); - set_gdbarch_function_start_offset (gdbarch, 0); - set_gdbarch_long_bit (gdbarch, 8 * TARGET_CHAR_BIT); - set_gdbarch_npc_regnum (gdbarch, SPARC64_NPC_REGNUM); - set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM); - set_gdbarch_ptr_bit (gdbarch, 8 * TARGET_CHAR_BIT); - set_gdbarch_push_arguments (gdbarch, sparc64_push_arguments); - /* NOTE different for at_entry */ - set_gdbarch_read_fp (gdbarch, sparc64_read_fp); - set_gdbarch_read_sp (gdbarch, sparc64_read_sp); - /* Some of the registers aren't 64 bits, but it's a lot simpler just - to assume they all are (since most of them are). */ - set_gdbarch_register_byte (gdbarch, sparc64_register_byte); - set_gdbarch_register_raw_size (gdbarch, sparc64_register_size); - set_gdbarch_register_size (gdbarch, 8); - set_gdbarch_register_virtual_size (gdbarch, sparc64_register_size); - set_gdbarch_register_virtual_type (gdbarch, - sparc64_register_virtual_type); -#ifdef SPARC64_CALL_DUMMY_ON_STACK - set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_64)); -#else - set_gdbarch_sizeof_call_dummy_words (gdbarch, 0); -#endif - set_gdbarch_stack_align (gdbarch, sparc64_stack_align); - set_gdbarch_store_struct_return (gdbarch, sparc64_store_struct_return); - set_gdbarch_use_struct_convention (gdbarch, - sparc64_use_struct_convention); - set_gdbarch_write_fp (gdbarch, sparc64_write_fp); - set_gdbarch_write_sp (gdbarch, sparc64_write_sp); - tdep->y_regnum = SPARC64_Y_REGNUM; - tdep->fp_max_regnum = SPARC_FP0_REGNUM + 48; - tdep->intreg_size = 8; - tdep->reg_save_offset = 0x90; - tdep->call_dummy_call_offset = 148 + 4 * 5; - break; - } + set_gdbarch_unwind_pc (gdbarch, sparc_unwind_pc); - /* - * Settings that vary per-architecture: - */ + frame_base_set_default (gdbarch, &sparc32_frame_base); - switch (info.bfd_arch_info->mach) - { - case bfd_mach_sparc: - set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 72); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparc32_register_name); - set_gdbarch_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 32 * 4; - tdep->print_insn_mach = bfd_mach_sparc; - break; - case bfd_mach_sparc_sparclet: - set_gdbarch_extract_return_value (gdbarch, - sparclet_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 32 + 32 + 8 + 8 + 8); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparclet_register_name); - set_gdbarch_store_return_value (gdbarch, sparclet_store_return_value); - tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 0; - tdep->print_insn_mach = bfd_mach_sparc_sparclet; - break; - case bfd_mach_sparc_sparclite: - set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 80); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparclite_register_name); - set_gdbarch_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 0; - tdep->print_insn_mach = bfd_mach_sparc_sparclite; - break; - case bfd_mach_sparc_v8plus: - set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 72); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparc32_register_name); - set_gdbarch_store_return_value (gdbarch, sparc_store_return_value); - tdep->print_insn_mach = bfd_mach_sparc; - tdep->fp_register_bytes = 32 * 4; - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ - break; - case bfd_mach_sparc_v8plusa: - set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 72); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparc32_register_name); - set_gdbarch_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 32 * 4; - tdep->print_insn_mach = bfd_mach_sparc; - break; - case bfd_mach_sparc_sparclite_le: - set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 80); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparclite_register_name); - set_gdbarch_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 0; - tdep->print_insn_mach = bfd_mach_sparc_sparclite; - break; - case bfd_mach_sparc_v9: - set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 125); - set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8); - set_gdbarch_register_name (gdbarch, sparc64_register_name); - set_gdbarch_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 64 * 4; - tdep->print_insn_mach = bfd_mach_sparc_v9a; - break; - case bfd_mach_sparc_v9a: - set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value); - set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); - set_gdbarch_num_regs (gdbarch, 125); - set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8); - set_gdbarch_register_name (gdbarch, sparc64_register_name); - set_gdbarch_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 64 * 4; - tdep->print_insn_mach = bfd_mach_sparc_v9a; - break; - } + /* Hook in ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); + + frame_unwind_append_sniffer (gdbarch, sparc32_frame_sniffer); + + /* If we have register sets, enable the generic core file support. */ + if (tdep->gregset) + set_gdbarch_regset_from_core_section (gdbarch, + sparc_regset_from_core_section); return gdbarch; } + +/* Helper functions for dealing with register windows. */ +void +sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum) +{ + int offset = 0; + char buf[8]; + int i; + + if (sp & 1) + { + /* Registers are 64-bit. */ + sp += BIAS; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + { + target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8); + regcache_raw_supply (regcache, i, buf); + } + } + } + else + { + /* Registers are 32-bit. Toss any sign-extension of the stack + pointer. */ + sp &= 0xffffffffUL; + + /* Clear out the top half of the temporary buffer, and put the + register value in the bottom half if we're in 64-bit mode. */ + if (gdbarch_ptr_bit (current_gdbarch) == 64) + { + memset (buf, 0, 4); + offset = 4; + } + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + { + target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 4), + buf + offset, 4); + + /* Handle StackGhost. */ + if (i == SPARC_I7_REGNUM) + { + ULONGEST wcookie = sparc_fetch_wcookie (); + ULONGEST i7 = extract_unsigned_integer (buf + offset, 4); + + store_unsigned_integer (buf + offset, 4, i7 ^ wcookie); + } + + regcache_raw_supply (regcache, i, buf); + } + } + } +} + +void +sparc_collect_rwindow (const struct regcache *regcache, + CORE_ADDR sp, int regnum) +{ + int offset = 0; + char buf[8]; + int i; + + if (sp & 1) + { + /* Registers are 64-bit. */ + sp += BIAS; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i) + { + regcache_raw_collect (regcache, i, buf); + target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8); + } + } + } + else + { + /* Registers are 32-bit. Toss any sign-extension of the stack + pointer. */ + sp &= 0xffffffffUL; + + /* Only use the bottom half if we're in 64-bit mode. */ + if (gdbarch_ptr_bit (current_gdbarch) == 64) + offset = 4; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i) + { + regcache_raw_collect (regcache, i, buf); + + /* Handle StackGhost. */ + if (i == SPARC_I7_REGNUM) + { + ULONGEST wcookie = sparc_fetch_wcookie (); + ULONGEST i7 = extract_unsigned_integer (buf + offset, 4); + + store_unsigned_integer (buf + offset, 4, i7 ^ wcookie); + } + + target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 4), + buf + offset, 4); + } + } + } +} + +/* Helper functions for dealing with register sets. */ + +void +sparc32_supply_gregset (const struct sparc_gregset *gregset, + struct regcache *regcache, + int regnum, const void *gregs) +{ + const char *regs = gregs; + int i; + + if (regnum == SPARC32_PSR_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, + regs + gregset->r_psr_offset); + + if (regnum == SPARC32_PC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_PC_REGNUM, + regs + gregset->r_pc_offset); + + if (regnum == SPARC32_NPC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, + regs + gregset->r_npc_offset); + + if (regnum == SPARC32_Y_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_Y_REGNUM, + regs + gregset->r_y_offset); + + if (regnum == SPARC_G0_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL); + + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) + { + int offset = gregset->r_g1_offset; + + for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + offset); + offset += 4; + } + } + + if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) + { + /* Not all of the register set variants include Locals and + Inputs. For those that don't, we read them off the stack. */ + if (gregset->r_l0_offset == -1) + { + ULONGEST sp; + + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + sparc_supply_rwindow (regcache, sp, regnum); + } + else + { + int offset = gregset->r_l0_offset; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + offset); + offset += 4; + } + } + } +} + +void +sparc32_collect_gregset (const struct sparc_gregset *gregset, + const struct regcache *regcache, + int regnum, void *gregs) +{ + char *regs = gregs; + int i; + + if (regnum == SPARC32_PSR_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, + regs + gregset->r_psr_offset); + + if (regnum == SPARC32_PC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_PC_REGNUM, + regs + gregset->r_pc_offset); + + if (regnum == SPARC32_NPC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_NPC_REGNUM, + regs + gregset->r_npc_offset); + + if (regnum == SPARC32_Y_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_Y_REGNUM, + regs + gregset->r_y_offset); + + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) + { + int offset = gregset->r_g1_offset; + + /* %g0 is always zero. */ + for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_collect (regcache, i, regs + offset); + offset += 4; + } + } + + if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) + { + /* Not all of the register set variants include Locals and + Inputs. For those that don't, we read them off the stack. */ + if (gregset->r_l0_offset != -1) + { + int offset = gregset->r_l0_offset; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_collect (regcache, i, regs + offset); + offset += 4; + } + } + } +} + +void +sparc32_supply_fpregset (struct regcache *regcache, + int regnum, const void *fpregs) +{ + const char *regs = fpregs; + int i; + + for (i = 0; i < 32; i++) + { + if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) + regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); + } + + if (regnum == SPARC32_FSR_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4); +} + +void +sparc32_collect_fpregset (const struct regcache *regcache, + int regnum, void *fpregs) +{ + char *regs = fpregs; + int i; + + for (i = 0; i < 32; i++) + { + if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) + regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); + } + + if (regnum == SPARC32_FSR_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4); +} + + +/* SunOS 4. */ + +/* From . */ +const struct sparc_gregset sparc32_sunos4_gregset = +{ + 0 * 4, /* %psr */ + 1 * 4, /* %pc */ + 2 * 4, /* %npc */ + 3 * 4, /* %y */ + -1, /* %wim */ + -1, /* %tbr */ + 4 * 4, /* %g1 */ + -1 /* %l0 */ +}; + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc_tdep (void); + +void +_initialize_sparc_tdep (void) +{ + register_gdbarch_init (bfd_arch_sparc, sparc32_gdbarch_init); +} diff --git a/contrib/gdb/gdb/sparc-tdep.h b/contrib/gdb/gdb/sparc-tdep.h new file mode 100644 index 00000000000..bbfbb422d9c --- /dev/null +++ b/contrib/gdb/gdb/sparc-tdep.h @@ -0,0 +1,204 @@ +/* Target-dependent code for SPARC. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef SPARC_TDEP_H +#define SPARC_TDEP_H 1 + +struct frame_info; +struct gdbarch; +struct regcache; +struct regset; +struct trad_frame_saved_reg; + +/* Register offsets for the general-purpose register set. */ + +struct sparc_gregset +{ + int r_psr_offset; + int r_pc_offset; + int r_npc_offset; + int r_y_offset; + int r_wim_offset; + int r_tbr_offset; + int r_g1_offset; + int r_l0_offset; + int r_y_size; +}; + +/* SPARC architecture-specific information. */ + +struct gdbarch_tdep +{ + /* Register numbers for the PN and nPC registers. The definitions + for (64-bit) UltraSPARC differ from the (32-bit) SPARC + definitions. */ + int pc_regnum; + int npc_regnum; + + /* Register sets. */ + struct regset *gregset; + size_t sizeof_gregset; + struct regset *fpregset; + size_t sizeof_fpregset; + + /* Offset of saved PC in jmp_buf. */ + int jb_pc_offset; + + /* Size of an Procedure Linkage Table (PLT) entry, 0 if we shouldn't + treat the PLT special when doing prologue analysis. */ + size_t plt_entry_size; +}; + +/* Register numbers of various important registers. */ + +enum sparc_regnum +{ + SPARC_G0_REGNUM, /* %g0 */ + SPARC_G1_REGNUM, + SPARC_G2_REGNUM, + SPARC_G3_REGNUM, + SPARC_G4_REGNUM, + SPARC_G5_REGNUM, + SPARC_G6_REGNUM, + SPARC_G7_REGNUM, /* %g7 */ + SPARC_O0_REGNUM, /* %o0 */ + SPARC_O1_REGNUM, + SPARC_O2_REGNUM, + SPARC_O3_REGNUM, + SPARC_O4_REGNUM, + SPARC_O5_REGNUM, + SPARC_SP_REGNUM, /* %sp (%o6) */ + SPARC_O7_REGNUM, /* %o7 */ + SPARC_L0_REGNUM, /* %l0 */ + SPARC_L1_REGNUM, + SPARC_L2_REGNUM, + SPARC_L3_REGNUM, + SPARC_L4_REGNUM, + SPARC_L5_REGNUM, + SPARC_L6_REGNUM, + SPARC_L7_REGNUM, /* %l7 */ + SPARC_I0_REGNUM, /* %i0 */ + SPARC_I1_REGNUM, + SPARC_I2_REGNUM, + SPARC_I3_REGNUM, + SPARC_I4_REGNUM, + SPARC_I5_REGNUM, + SPARC_FP_REGNUM, /* %fp (%i6) */ + SPARC_I7_REGNUM, /* %i7 */ + SPARC_F0_REGNUM, /* %f0 */ + SPARC_F1_REGNUM, + SPARC_F31_REGNUM /* %f31 */ + = SPARC_F0_REGNUM + 31 +}; + +enum sparc32_regnum +{ + SPARC32_Y_REGNUM /* %y */ + = SPARC_F31_REGNUM + 1, + SPARC32_PSR_REGNUM, /* %psr */ + SPARC32_WIM_REGNUM, /* %wim */ + SPARC32_TBR_REGNUM, /* %tbr */ + SPARC32_PC_REGNUM, /* %pc */ + SPARC32_NPC_REGNUM, /* %npc */ + SPARC32_FSR_REGNUM, /* %fsr */ + SPARC32_CSR_REGNUM, /* %csr */ + + /* Pseudo registers. */ + SPARC32_D0_REGNUM, /* %d0 */ + SPARC32_D30_REGNUM /* %d30 */ + = SPARC32_D0_REGNUM + 15 +}; + + +struct sparc_frame_cache +{ + /* Base address. */ + CORE_ADDR base; + CORE_ADDR pc; + + /* Do we have a frame? */ + int frameless_p; + + /* Do we have a Structure, Union or Quad-Precision return value?. */ + int struct_return_p; + + /* Table of saved registers. */ + struct trad_frame_saved_reg *saved_regs; +}; + +/* Fetch the instruction at PC. */ +extern unsigned long sparc_fetch_instruction (CORE_ADDR pc); + +/* Fetch StackGhost Per-Process XOR cookie. */ +extern ULONGEST sparc_fetch_wcookie (void); + +extern CORE_ADDR sparc_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, + struct sparc_frame_cache *cache); + +extern struct sparc_frame_cache * + sparc_frame_cache (struct frame_info *next_frame, void **this_cache); + +extern struct sparc_frame_cache * + sparc32_frame_cache (struct frame_info *next_frame, void **this_cache); + + + +extern void sparc_software_single_step (enum target_signal sig, + int insert_breakpoints_p); + +extern void sparc_supply_rwindow (struct regcache *regcache, + CORE_ADDR sp, int regnum); +extern void sparc_collect_rwindow (const struct regcache *regcache, + CORE_ADDR sp, int regnum); + +/* Register offsets for SunOS 4. */ +extern const struct sparc_gregset sparc32_sunos4_gregset; + +extern void sparc32_supply_gregset (const struct sparc_gregset *gregset, + struct regcache *regcache, + int regnum, const void *gregs); +extern void sparc32_collect_gregset (const struct sparc_gregset *gregset, + const struct regcache *regcache, + int regnum, void *gregs); +extern void sparc32_supply_fpregset (struct regcache *regcache, + int regnum, const void *fpregs); +extern void sparc32_collect_fpregset (const struct regcache *regcache, + int regnum, void *fpregs); + +/* Functions and variables exported from sparc-sol2-tdep.c. */ + +/* Register offsets for Solaris 2. */ +extern const struct sparc_gregset sparc32_sol2_gregset; + +extern int sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name); + +extern void sparc32_sol2_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch); + +/* Functions and variables exported from sparcnbsd-tdep.c. */ + +/* Register offsets for NetBSD. */ +extern const struct sparc_gregset sparc32nbsd_gregset; + +extern struct trad_frame_saved_reg * + sparc32nbsd_sigcontext_saved_regs (struct frame_info *next_frame); + +#endif /* sparc-tdep.h */ diff --git a/contrib/gdb/gdb/sparc64-nat.c b/contrib/gdb/gdb/sparc64-nat.c new file mode 100644 index 00000000000..40a8b3b3904 --- /dev/null +++ b/contrib/gdb/gdb/sparc64-nat.c @@ -0,0 +1,87 @@ +/* Native-dependent code for GNU/Linux UltraSPARC. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbarch.h" + +#include "sparc64-tdep.h" +#include "sparc-nat.h" + +/* Determine whether `gregset_t' contains register REGNUM. */ + +static int +sparc64_gregset_supplies_p (int regnum) +{ + if (gdbarch_ptr_bit (current_gdbarch) == 32) + return sparc32_gregset_supplies_p (regnum); + + /* Integer registers. */ + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM) + || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM) + || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM)) + return 1; + + /* Control registers. */ + if (regnum == SPARC64_PC_REGNUM + || regnum == SPARC64_NPC_REGNUM + || regnum == SPARC64_STATE_REGNUM + || regnum == SPARC64_Y_REGNUM + || regnum == SPARC64_FPRS_REGNUM) + return 1; + + return 0; +} + +/* Determine whether `fpregset_t' contains register REGNUM. */ + +static int +sparc64_fpregset_supplies_p (int regnum) +{ + if (gdbarch_ptr_bit (current_gdbarch) == 32) + return sparc32_fpregset_supplies_p (regnum); + + /* Floating-point registers. */ + if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) + || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM)) + return 1; + + /* Control registers. */ + if (regnum == SPARC64_FSR_REGNUM) + return 1; + + return 0; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc64_nat (void); + +void +_initialize_sparc64_nat (void) +{ + sparc_supply_gregset = sparc64_supply_gregset; + sparc_collect_gregset = sparc64_collect_gregset; + sparc_supply_fpregset = sparc64_supply_fpregset; + sparc_collect_fpregset = sparc64_collect_fpregset; + sparc_gregset_supplies_p = sparc64_gregset_supplies_p; + sparc_fpregset_supplies_p = sparc64_fpregset_supplies_p; +} diff --git a/contrib/gdb/gdb/sparc64-sol2-tdep.c b/contrib/gdb/gdb/sparc64-sol2-tdep.c new file mode 100644 index 00000000000..079f3c502e7 --- /dev/null +++ b/contrib/gdb/gdb/sparc64-sol2-tdep.c @@ -0,0 +1,182 @@ +/* Target-dependent code for Solaris UltraSPARC. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "frame-unwind.h" +#include "gdbarch.h" +#include "symtab.h" +#include "objfiles.h" +#include "osabi.h" +#include "trad-frame.h" + +#include "gdb_assert.h" + +#include "sparc64-tdep.h" + +/* From . */ +const struct sparc_gregset sparc64_sol2_gregset = +{ + 32 * 8, /* "tstate" */ + 33 * 8, /* %pc */ + 34 * 8, /* %npc */ + 35 * 8, /* %y */ + -1, /* %wim */ + -1, /* %tbr */ + 1 * 8, /* %g1 */ + 16 * 8, /* %l0 */ + 8 /* sizeof (%y) */ +}; + + +static struct sparc_frame_cache * +sparc64_sol2_sigtramp_frame_cache (struct frame_info *next_frame, + void **this_cache) +{ + struct sparc_frame_cache *cache; + CORE_ADDR mcontext_addr, addr; + int regnum; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + gdb_assert (cache == *this_cache); + + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + /* The third argument is a pointer to an instance of `ucontext_t', + which has a member `uc_mcontext' that contains the saved + registers. */ + regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM); + mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 64; + + cache->saved_regs[SPARC64_CCR_REGNUM].addr = mcontext_addr + 0 * 8; + cache->saved_regs[SPARC64_PC_REGNUM].addr = mcontext_addr + 1 * 8; + cache->saved_regs[SPARC64_NPC_REGNUM].addr = mcontext_addr + 2 * 8; + cache->saved_regs[SPARC64_Y_REGNUM].addr = mcontext_addr + 3 * 8; + cache->saved_regs[SPARC64_ASI_REGNUM].addr = mcontext_addr + 19 * 8; + cache->saved_regs[SPARC64_FPRS_REGNUM].addr = mcontext_addr + 20 * 8; + + /* Since %g0 is always zero, keep the identity encoding. */ + for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 8; + regnum <= SPARC_O7_REGNUM; regnum++, addr += 8) + cache->saved_regs[regnum].addr = addr; + + if (get_frame_memory_unsigned (next_frame, mcontext_addr + 21 * 8, 8)) + { + /* The register windows haven't been flushed. */ + for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) + trad_frame_set_unknown (cache->saved_regs, regnum); + } + else + { + CORE_ADDR sp; + + addr = cache->saved_regs[SPARC_SP_REGNUM].addr; + sp = get_frame_memory_unsigned (next_frame, addr, 8); + for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS; + regnum <= SPARC_I7_REGNUM; regnum++, addr += 8) + cache->saved_regs[regnum].addr = addr; + } + + return cache; +} + +static void +sparc64_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc64_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); + + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + sparc64_sol2_sigtramp_frame_this_id, + sparc64_sol2_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +sparc64_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (sparc_sol2_pc_in_sigtramp (pc, name)) + return &sparc64_sol2_sigtramp_frame_unwind; + + return NULL; +} + + +void +sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + set_gdbarch_pc_in_sigtramp (gdbarch, sparc_sol2_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, sparc64_sol2_sigtramp_frame_sniffer); + + sparc64_init_abi (info, gdbarch); + + /* Solaris has SVR4-style shared libraries... */ + set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + + /* ...which means that we need some special handling when doing + prologue analysis. */ + tdep->plt_entry_size = 16; + + /* Solaris has kernel-assisted single-stepping support. */ + set_gdbarch_software_single_step (gdbarch, NULL); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc64_sol2_tdep (void); + +void +_initialize_sparc64_sol2_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, + GDB_OSABI_SOLARIS, sparc64_sol2_init_abi); +} diff --git a/contrib/gdb/gdb/sparc64-tdep.c b/contrib/gdb/gdb/sparc64-tdep.c new file mode 100644 index 00000000000..8aad619eeae --- /dev/null +++ b/contrib/gdb/gdb/sparc64-tdep.c @@ -0,0 +1,1433 @@ +/* Target-dependent code for UltraSPARC. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "floatformat.h" +#include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "gdbtypes.h" +#include "inferior.h" +#include "symtab.h" +#include "objfiles.h" +#include "osabi.h" +#include "regcache.h" +#include "target.h" +#include "value.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "sparc64-tdep.h" + +/* This file implements the The SPARC 64-bit ABI as defined by the + section "Low-Level System Information" of the SPARC Compliance + Definition (SCD) 2.4.1, which is the 64-bit System V psABI for + SPARC. */ + +/* Please use the sparc32_-prefix for 32-bit specific code, the + sparc64_-prefix for 64-bit specific code and the sparc_-prefix for + code can handle both. */ + +/* The functions on this page are intended to be used to classify + function arguments. */ + +/* Return the contents if register REGNUM as an address. */ + +static CORE_ADDR +sparc_address_from_register (int regnum) +{ + ULONGEST addr; + + regcache_cooked_read_unsigned (current_regcache, regnum, &addr); + return addr; +} + +/* Check whether TYPE is "Integral or Pointer". */ + +static int +sparc64_integral_or_pointer_p (const struct type *type) +{ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_BOOL: + case TYPE_CODE_CHAR: + case TYPE_CODE_ENUM: + case TYPE_CODE_RANGE: + { + int len = TYPE_LENGTH (type); + gdb_assert (len == 1 || len == 2 || len == 4 || len == 8); + } + return 1; + case TYPE_CODE_PTR: + case TYPE_CODE_REF: + { + int len = TYPE_LENGTH (type); + gdb_assert (len == 8); + } + return 1; + default: + break; + } + + return 0; +} + +/* Check whether TYPE is "Floating". */ + +static int +sparc64_floating_p (const struct type *type) +{ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_FLT: + { + int len = TYPE_LENGTH (type); + gdb_assert (len == 4 || len == 8 || len == 16); + } + return 1; + default: + break; + } + + return 0; +} + +/* Check whether TYPE is "Structure or Union". */ + +static int +sparc64_structure_or_union_p (const struct type *type) +{ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + return 1; + default: + break; + } + + return 0; +} + +/* Register information. */ + +struct sparc64_register_info +{ + char *name; + struct type **type; +}; + +static struct sparc64_register_info sparc64_register_info[] = +{ + { "g0", &builtin_type_int64 }, + { "g1", &builtin_type_int64 }, + { "g2", &builtin_type_int64 }, + { "g3", &builtin_type_int64 }, + { "g4", &builtin_type_int64 }, + { "g5", &builtin_type_int64 }, + { "g6", &builtin_type_int64 }, + { "g7", &builtin_type_int64 }, + + { "o0", &builtin_type_int64 }, + { "o1", &builtin_type_int64 }, + { "o2", &builtin_type_int64 }, + { "o3", &builtin_type_int64 }, + { "o4", &builtin_type_int64 }, + { "o5", &builtin_type_int64 }, + { "sp", &builtin_type_void_data_ptr }, + { "o7", &builtin_type_int64 }, + + { "l0", &builtin_type_int64 }, + { "l1", &builtin_type_int64 }, + { "l2", &builtin_type_int64 }, + { "l3", &builtin_type_int64 }, + { "l4", &builtin_type_int64 }, + { "l5", &builtin_type_int64 }, + { "l6", &builtin_type_int64 }, + { "l7", &builtin_type_int64 }, + + { "i0", &builtin_type_int64 }, + { "i1", &builtin_type_int64 }, + { "i2", &builtin_type_int64 }, + { "i3", &builtin_type_int64 }, + { "i4", &builtin_type_int64 }, + { "i5", &builtin_type_int64 }, + { "fp", &builtin_type_void_data_ptr }, + { "i7", &builtin_type_int64 }, + + { "f0", &builtin_type_float }, + { "f1", &builtin_type_float }, + { "f2", &builtin_type_float }, + { "f3", &builtin_type_float }, + { "f4", &builtin_type_float }, + { "f5", &builtin_type_float }, + { "f6", &builtin_type_float }, + { "f7", &builtin_type_float }, + { "f8", &builtin_type_float }, + { "f9", &builtin_type_float }, + { "f10", &builtin_type_float }, + { "f11", &builtin_type_float }, + { "f12", &builtin_type_float }, + { "f13", &builtin_type_float }, + { "f14", &builtin_type_float }, + { "f15", &builtin_type_float }, + { "f16", &builtin_type_float }, + { "f17", &builtin_type_float }, + { "f18", &builtin_type_float }, + { "f19", &builtin_type_float }, + { "f20", &builtin_type_float }, + { "f21", &builtin_type_float }, + { "f22", &builtin_type_float }, + { "f23", &builtin_type_float }, + { "f24", &builtin_type_float }, + { "f25", &builtin_type_float }, + { "f26", &builtin_type_float }, + { "f27", &builtin_type_float }, + { "f28", &builtin_type_float }, + { "f29", &builtin_type_float }, + { "f30", &builtin_type_float }, + { "f31", &builtin_type_float }, + { "f32", &builtin_type_double }, + { "f34", &builtin_type_double }, + { "f36", &builtin_type_double }, + { "f38", &builtin_type_double }, + { "f40", &builtin_type_double }, + { "f42", &builtin_type_double }, + { "f44", &builtin_type_double }, + { "f46", &builtin_type_double }, + { "f48", &builtin_type_double }, + { "f50", &builtin_type_double }, + { "f52", &builtin_type_double }, + { "f54", &builtin_type_double }, + { "f56", &builtin_type_double }, + { "f58", &builtin_type_double }, + { "f60", &builtin_type_double }, + { "f62", &builtin_type_double }, + + { "pc", &builtin_type_void_func_ptr }, + { "npc", &builtin_type_void_func_ptr }, + + /* This raw register contains the contents of %cwp, %pstate, %asi + and %ccr as laid out in a %tstate register. */ + /* FIXME: Give it a name until we start using register groups. */ + { "state", &builtin_type_int64 }, + + { "fsr", &builtin_type_int64 }, + { "fprs", &builtin_type_int64 }, + + /* "Although Y is a 64-bit register, its high-order 32 bits are + reserved and always read as 0." */ + { "y", &builtin_type_int64 } +}; + +/* Total number of registers. */ +#define SPARC64_NUM_REGS ARRAY_SIZE (sparc64_register_info) + +/* We provide the aliases %d0..%d62 and %q0..%q60 for the floating + registers as "psuedo" registers. */ + +static struct sparc64_register_info sparc64_pseudo_register_info[] = +{ + { "cwp", &builtin_type_int64 }, + { "pstate", &builtin_type_int64 }, + { "asi", &builtin_type_int64 }, + { "ccr", &builtin_type_int64 }, + + { "d0", &builtin_type_double }, + { "d2", &builtin_type_double }, + { "d4", &builtin_type_double }, + { "d6", &builtin_type_double }, + { "d8", &builtin_type_double }, + { "d10", &builtin_type_double }, + { "d12", &builtin_type_double }, + { "d14", &builtin_type_double }, + { "d16", &builtin_type_double }, + { "d18", &builtin_type_double }, + { "d20", &builtin_type_double }, + { "d22", &builtin_type_double }, + { "d24", &builtin_type_double }, + { "d26", &builtin_type_double }, + { "d28", &builtin_type_double }, + { "d30", &builtin_type_double }, + { "d32", &builtin_type_double }, + { "d34", &builtin_type_double }, + { "d36", &builtin_type_double }, + { "d38", &builtin_type_double }, + { "d40", &builtin_type_double }, + { "d42", &builtin_type_double }, + { "d44", &builtin_type_double }, + { "d46", &builtin_type_double }, + { "d48", &builtin_type_double }, + { "d50", &builtin_type_double }, + { "d52", &builtin_type_double }, + { "d54", &builtin_type_double }, + { "d56", &builtin_type_double }, + { "d58", &builtin_type_double }, + { "d60", &builtin_type_double }, + { "d62", &builtin_type_double }, + + { "q0", &builtin_type_long_double }, + { "q4", &builtin_type_long_double }, + { "q8", &builtin_type_long_double }, + { "q12", &builtin_type_long_double }, + { "q16", &builtin_type_long_double }, + { "q20", &builtin_type_long_double }, + { "q24", &builtin_type_long_double }, + { "q28", &builtin_type_long_double }, + { "q32", &builtin_type_long_double }, + { "q36", &builtin_type_long_double }, + { "q40", &builtin_type_long_double }, + { "q44", &builtin_type_long_double }, + { "q48", &builtin_type_long_double }, + { "q52", &builtin_type_long_double }, + { "q56", &builtin_type_long_double }, + { "q60", &builtin_type_long_double } +}; + +/* Total number of pseudo registers. */ +#define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_info) + +/* Return the name of register REGNUM. */ + +static const char * +sparc64_register_name (int regnum) +{ + if (regnum >= 0 && regnum < SPARC64_NUM_REGS) + return sparc64_register_info[regnum].name; + + if (regnum >= SPARC64_NUM_REGS + && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS) + return sparc64_pseudo_register_info[regnum - SPARC64_NUM_REGS].name; + + return NULL; +} + +/* Return the GDB type object for the "standard" data type of data in + register REGNUM. */ + +static struct type * +sparc64_register_type (struct gdbarch *gdbarch, int regnum) +{ + if (regnum >= SPARC64_NUM_REGS + && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS) + return *sparc64_pseudo_register_info[regnum - SPARC64_NUM_REGS].type; + + gdb_assert (regnum >= 0 && regnum < SPARC64_NUM_REGS); + return *sparc64_register_info[regnum].type; +} + +static void +sparc64_pseudo_register_read (struct gdbarch *gdbarch, + struct regcache *regcache, + int regnum, void *buf) +{ + gdb_assert (regnum >= SPARC64_NUM_REGS); + + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) + { + regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM); + regcache_raw_read (regcache, regnum, buf); + regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 4); + } + else if (regnum >= SPARC64_D32_REGNUM && regnum <= SPARC64_D62_REGNUM) + { + regnum = SPARC64_F32_REGNUM + (regnum - SPARC64_D32_REGNUM); + regcache_raw_read (regcache, regnum, buf); + } + else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM) + { + regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM); + regcache_raw_read (regcache, regnum, buf); + regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 4); + regcache_raw_read (regcache, regnum + 2, ((char *)buf) + 8); + regcache_raw_read (regcache, regnum + 3, ((char *)buf) + 12); + } + else if (regnum >= SPARC64_Q32_REGNUM && regnum <= SPARC64_Q60_REGNUM) + { + regnum = SPARC64_F32_REGNUM + 2 * (regnum - SPARC64_Q32_REGNUM); + regcache_raw_read (regcache, regnum, buf); + regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 8); + } + else if (regnum == SPARC64_CWP_REGNUM + || regnum == SPARC64_PSTATE_REGNUM + || regnum == SPARC64_ASI_REGNUM + || regnum == SPARC64_CCR_REGNUM) + { + ULONGEST state; + + regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state); + switch (regnum) + { + case SPARC64_CWP_REGNUM: + state = (state >> 0) & ((1 << 5) - 1); + break; + case SPARC64_PSTATE_REGNUM: + state = (state >> 8) & ((1 << 12) - 1); + break; + case SPARC64_ASI_REGNUM: + state = (state >> 24) & ((1 << 8) - 1); + break; + case SPARC64_CCR_REGNUM: + state = (state >> 32) & ((1 << 8) - 1); + break; + } + store_unsigned_integer (buf, 8, state); + } +} + +static void +sparc64_pseudo_register_write (struct gdbarch *gdbarch, + struct regcache *regcache, + int regnum, const void *buf) +{ + gdb_assert (regnum >= SPARC64_NUM_REGS); + + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) + { + regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM); + regcache_raw_write (regcache, regnum, buf); + regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 4); + } + else if (regnum >= SPARC64_D32_REGNUM && regnum <= SPARC64_D62_REGNUM) + { + regnum = SPARC64_F32_REGNUM + (regnum - SPARC64_D32_REGNUM); + regcache_raw_write (regcache, regnum, buf); + } + else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM) + { + regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM); + regcache_raw_write (regcache, regnum, buf); + regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 4); + regcache_raw_write (regcache, regnum + 2, ((const char *)buf) + 8); + regcache_raw_write (regcache, regnum + 3, ((const char *)buf) + 12); + } + else if (regnum >= SPARC64_Q32_REGNUM && regnum <= SPARC64_Q60_REGNUM) + { + regnum = SPARC64_F32_REGNUM + 2 * (regnum - SPARC64_Q32_REGNUM); + regcache_raw_write (regcache, regnum, buf); + regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 8); + } + else if (regnum == SPARC64_CWP_REGNUM + || regnum == SPARC64_PSTATE_REGNUM + || regnum == SPARC64_ASI_REGNUM + || regnum == SPARC64_CCR_REGNUM) + { + ULONGEST state, bits; + + regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state); + bits = extract_unsigned_integer (buf, 8); + switch (regnum) + { + case SPARC64_CWP_REGNUM: + state |= ((bits & ((1 << 5) - 1)) << 0); + break; + case SPARC64_PSTATE_REGNUM: + state |= ((bits & ((1 << 12) - 1)) << 8); + break; + case SPARC64_ASI_REGNUM: + state |= ((bits & ((1 << 8) - 1)) << 24); + break; + case SPARC64_CCR_REGNUM: + state |= ((bits & ((1 << 8) - 1)) << 32); + break; + } + regcache_raw_write_unsigned (regcache, SPARC64_STATE_REGNUM, state); + } +} + + +/* Return PC of first real instruction of the function starting at + START_PC. */ + +static CORE_ADDR +sparc64_skip_prologue (CORE_ADDR start_pc) +{ + struct symtab_and_line sal; + CORE_ADDR func_start, func_end; + struct sparc_frame_cache cache; + + /* This is the preferred method, find the end of the prologue by + using the debugging information. */ + if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end)) + { + sal = find_pc_line (func_start, 0); + + if (sal.end < func_end + && start_pc <= sal.end) + return sal.end; + } + + return sparc_analyze_prologue (start_pc, 0xffffffffffffffffULL, &cache); +} + +/* Normal frames. */ + +static struct sparc_frame_cache * +sparc64_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + return sparc_frame_cache (next_frame, this_cache); +} + +static void +sparc64_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc64_frame_cache (next_frame, this_cache); + + /* This marks the outermost frame. */ + if (cache->base == 0) + return; + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc64_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc64_frame_cache (next_frame, this_cache); + + if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + CORE_ADDR pc = (regnum == SPARC64_NPC_REGNUM) ? 4 : 0; + + regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM; + pc += frame_unwind_register_unsigned (next_frame, regnum) + 8; + store_unsigned_integer (valuep, 8, pc); + } + return; + } + + /* The previous frame's `local' and `in' registers have been saved + in the register save area. */ + if (!cache->frameless_p + && regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = cache->base + BIAS + (regnum - SPARC_L0_REGNUM) * 8; + *realnump = -1; + if (valuep) + { + struct gdbarch *gdbarch = get_frame_arch (next_frame); + + /* Read the value in from memory. */ + read_memory (*addrp, valuep, register_size (gdbarch, regnum)); + } + return; + } + + /* The previous frame's `out' registers are accessable as the + current frame's `in' registers. */ + if (!cache->frameless_p + && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) + regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM); + + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc64_frame_unwind = +{ + NORMAL_FRAME, + sparc64_frame_this_id, + sparc64_frame_prev_register +}; + +static const struct frame_unwind * +sparc64_frame_sniffer (struct frame_info *next_frame) +{ + return &sparc64_frame_unwind; +} + + +static CORE_ADDR +sparc64_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct sparc_frame_cache *cache = + sparc64_frame_cache (next_frame, this_cache); + + /* ??? Should we take BIAS into account here? */ + return cache->base; +} + +static const struct frame_base sparc64_frame_base = +{ + &sparc64_frame_unwind, + sparc64_frame_base_address, + sparc64_frame_base_address, + sparc64_frame_base_address +}; + +/* Check whether TYPE must be 16-byte aligned. */ + +static int +sparc64_16_byte_align_p (struct type *type) +{ + if (sparc64_floating_p (type) && TYPE_LENGTH (type) == 16) + return 1; + + if (sparc64_structure_or_union_p (type)) + { + int i; + + for (i = 0; i < TYPE_NFIELDS (type); i++) + { + struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i)); + + if (sparc64_16_byte_align_p (subtype)) + return 1; + } + } + + return 0; +} + +/* Store floating fields of element ELEMENT of an "parameter array" + that has type TYPE and is stored at BITPOS in VALBUF in the + apropriate registers of REGCACHE. This function can be called + recursively and therefore handles floating types in addition to + structures. */ + +static void +sparc64_store_floating_fields (struct regcache *regcache, struct type *type, + char *valbuf, int element, int bitpos) +{ + gdb_assert (element < 16); + + if (sparc64_floating_p (type)) + { + int len = TYPE_LENGTH (type); + int regnum; + + if (len == 16) + { + gdb_assert (bitpos == 0); + gdb_assert ((element % 2) == 0); + + regnum = SPARC64_Q0_REGNUM + element / 2; + regcache_cooked_write (regcache, regnum, valbuf); + } + else if (len == 8) + { + gdb_assert (bitpos == 0 || bitpos == 64); + + regnum = SPARC64_D0_REGNUM + element + bitpos / 64; + regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8)); + } + else + { + gdb_assert (len == 4); + gdb_assert (bitpos % 32 == 0 && bitpos >= 0 && bitpos < 128); + + regnum = SPARC_F0_REGNUM + element * 2 + bitpos / 32; + regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8)); + } + } + else if (sparc64_structure_or_union_p (type)) + { + int i; + + for (i = 0; i < TYPE_NFIELDS (type); i++) + { + struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i)); + int subpos = bitpos + TYPE_FIELD_BITPOS (type, i); + + sparc64_store_floating_fields (regcache, subtype, valbuf, + element, subpos); + } + + /* GCC has an interesting bug. If TYPE is a structure that has + a single `float' member, GCC doesn't treat it as a structure + at all, but rather as an ordinary `float' argument. This + argument will be stored in %f1, as required by the psABI. + However, as a member of a structure the psABI requires it to + be stored in %f0. This bug is present in GCC 3.3.2, but + probably in older releases to. To appease GCC, if a + structure has only a single `float' member, we store its + value in %f1 too (we already have stored in %f0). */ + if (TYPE_NFIELDS (type) == 1) + { + struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, 0)); + + if (sparc64_floating_p (subtype) && TYPE_LENGTH (subtype) == 4) + regcache_cooked_write (regcache, SPARC_F1_REGNUM, valbuf); + } + } +} + +/* Fetch floating fields from a variable of type TYPE from the + appropriate registers for BITPOS in REGCACHE and store it at BITPOS + in VALBUF. This function can be called recursively and therefore + handles floating types in addition to structures. */ + +static void +sparc64_extract_floating_fields (struct regcache *regcache, struct type *type, + char *valbuf, int bitpos) +{ + if (sparc64_floating_p (type)) + { + int len = TYPE_LENGTH (type); + int regnum; + + if (len == 16) + { + gdb_assert (bitpos == 0 || bitpos == 128); + + regnum = SPARC64_Q0_REGNUM + bitpos / 128; + regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); + } + else if (len == 8) + { + gdb_assert (bitpos % 64 == 0 && bitpos >= 0 && bitpos < 256); + + regnum = SPARC64_D0_REGNUM + bitpos / 64; + regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); + } + else + { + gdb_assert (len == 4); + gdb_assert (bitpos % 32 == 0 && bitpos >= 0 && bitpos < 256); + + regnum = SPARC_F0_REGNUM + bitpos / 32; + regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); + } + } + else if (sparc64_structure_or_union_p (type)) + { + int i; + + for (i = 0; i < TYPE_NFIELDS (type); i++) + { + struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i)); + int subpos = bitpos + TYPE_FIELD_BITPOS (type, i); + + sparc64_extract_floating_fields (regcache, subtype, valbuf, subpos); + } + } +} + +/* Store the NARGS arguments ARGS and STRUCT_ADDR (if STRUCT_RETURN is + non-zero) in REGCACHE and on the stack (starting from address SP). */ + +static CORE_ADDR +sparc64_store_arguments (struct regcache *regcache, int nargs, + struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + /* Number of extended words in the "parameter array". */ + int num_elements = 0; + int element = 0; + int i; + + /* Take BIAS into account. */ + sp += BIAS; + + /* First we calculate the number of extended words in the "parameter + array". While doing so we also convert some of the arguments. */ + + if (struct_return) + num_elements++; + + for (i = 0; i < nargs; i++) + { + struct type *type = VALUE_TYPE (args[i]); + int len = TYPE_LENGTH (type); + + if (sparc64_structure_or_union_p (type)) + { + /* Structure or Union arguments. */ + if (len <= 16) + { + if (num_elements % 2 && sparc64_16_byte_align_p (type)) + num_elements++; + num_elements += ((len + 7) / 8); + } + else + { + /* The psABI says that "Structures or unions larger than + sixteen bytes are copied by the caller and passed + indirectly; the caller will pass the address of a + correctly aligned structure value. This sixty-four + bit address will occupy one word in the parameter + array, and may be promoted to an %o register like any + other pointer value." Allocate memory for these + values on the stack. */ + sp -= len; + + /* Use 16-byte alignment for these values. That's + always correct, and wasting a few bytes shouldn't be + a problem. */ + sp &= ~0xf; + + write_memory (sp, VALUE_CONTENTS (args[i]), len); + args[i] = value_from_pointer (lookup_pointer_type (type), sp); + num_elements++; + } + } + else if (sparc64_floating_p (type)) + { + /* Floating arguments. */ + + if (len == 16) + { + /* The psABI says that "Each quad-precision parameter + value will be assigned to two extended words in the + parameter array. */ + num_elements += 2; + + /* The psABI says that "Long doubles must be + quad-aligned, and thus a hole might be introduced + into the parameter array to force alignment." Skip + an element if necessary. */ + if (num_elements % 2) + num_elements++; + } + else + num_elements++; + } + else + { + /* Integral and pointer arguments. */ + gdb_assert (sparc64_integral_or_pointer_p (type)); + + /* The psABI says that "Each argument value of integral type + smaller than an extended word will be widened by the + caller to an extended word according to the signed-ness + of the argument type." */ + if (len < 8) + args[i] = value_cast (builtin_type_int64, args[i]); + num_elements++; + } + } + + /* Allocate the "parameter array". */ + sp -= num_elements * 8; + + /* The psABI says that "Every stack frame must be 16-byte aligned." */ + sp &= ~0xf; + + /* Now we store the arguments in to the "paramater array". Some + Integer or Pointer arguments and Structure or Union arguments + will be passed in %o registers. Some Floating arguments and + floating members of structures are passed in floating-point + registers. However, for functions with variable arguments, + floating arguments are stored in an %0 register, and for + functions without a prototype floating arguments are stored in + both a floating-point and an %o registers, or a floating-point + register and memory. To simplify the logic here we always pass + arguments in memory, an %o register, and a floating-point + register if appropriate. This should be no problem since the + contents of any unused memory or registers in the "parameter + array" are undefined. */ + + if (struct_return) + { + regcache_cooked_write_unsigned (regcache, SPARC_O0_REGNUM, struct_addr); + element++; + } + + for (i = 0; i < nargs; i++) + { + char *valbuf = VALUE_CONTENTS (args[i]); + struct type *type = VALUE_TYPE (args[i]); + int len = TYPE_LENGTH (type); + int regnum = -1; + char buf[16]; + + if (sparc64_structure_or_union_p (type)) + { + /* Structure or Union arguments. */ + gdb_assert (len <= 16); + memset (buf, 0, sizeof (buf)); + valbuf = memcpy (buf, valbuf, len); + + if (element % 2 && sparc64_16_byte_align_p (type)) + element++; + + if (element < 6) + { + regnum = SPARC_O0_REGNUM + element; + if (len > 8 && element < 5) + regcache_cooked_write (regcache, regnum + 1, valbuf + 8); + } + + if (element < 16) + sparc64_store_floating_fields (regcache, type, valbuf, element, 0); + } + else if (sparc64_floating_p (type)) + { + /* Floating arguments. */ + if (len == 16) + { + if (element % 2) + element++; + if (element < 16) + regnum = SPARC64_Q0_REGNUM + element / 2; + } + else if (len == 8) + { + if (element < 16) + regnum = SPARC64_D0_REGNUM + element; + } + else + { + /* The psABI says "Each single-precision parameter value + will be assigned to one extended word in the + parameter array, and right-justified within that + word; the left half (even floatregister) is + undefined." Even though the psABI says that "the + left half is undefined", set it to zero here. */ + memset (buf, 0, 4); + memcpy (buf + 4, valbuf, 4); + valbuf = buf; + len = 8; + if (element < 16) + regnum = SPARC64_D0_REGNUM + element; + } + } + else + { + /* Integral and pointer arguments. */ + gdb_assert (len == 8); + if (element < 6) + regnum = SPARC_O0_REGNUM + element; + } + + if (regnum != -1) + { + regcache_cooked_write (regcache, regnum, valbuf); + + /* If we're storing the value in a floating-point register, + also store it in the corresponding %0 register(s). */ + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM) + { + gdb_assert (element < 6); + regnum = SPARC_O0_REGNUM + element; + regcache_cooked_write (regcache, regnum, valbuf); + } + else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM) + { + gdb_assert (element < 6); + regnum = SPARC_O0_REGNUM + element; + regcache_cooked_write (regcache, regnum, valbuf); + regcache_cooked_write (regcache, regnum + 1, valbuf); + } + } + + /* Always store the argument in memeory. */ + write_memory (sp + element * 8, valbuf, len); + element += ((len + 7) / 8); + } + + gdb_assert (element == num_elements); + + /* Take BIAS into account. */ + sp -= BIAS; + return sp; +} + +static CORE_ADDR +sparc64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + /* Set return address. */ + regcache_cooked_write_unsigned (regcache, SPARC_O7_REGNUM, bp_addr - 8); + + /* Set up function arguments. */ + sp = sparc64_store_arguments (regcache, nargs, args, sp, + struct_return, struct_addr); + + /* Allocate the register save area. */ + sp -= 16 * 8; + + /* Stack should be 16-byte aligned at this point. */ + gdb_assert ((sp + BIAS) % 16 == 0); + + /* Finally, update the stack pointer. */ + regcache_cooked_write_unsigned (regcache, SPARC_SP_REGNUM, sp); + + return sp; +} + + +/* Extract from an array REGBUF containing the (raw) register state, a + function return value of TYPE, and copy that into VALBUF. */ + +static void +sparc64_extract_return_value (struct type *type, struct regcache *regcache, + void *valbuf) +{ + int len = TYPE_LENGTH (type); + char buf[32]; + int i; + + if (sparc64_structure_or_union_p (type)) + { + /* Structure or Union return values. */ + gdb_assert (len <= 32); + + for (i = 0; i < ((len + 7) / 8); i++) + regcache_cooked_read (regcache, SPARC_O0_REGNUM + i, buf + i * 8); + if (TYPE_CODE (type) != TYPE_CODE_UNION) + sparc64_extract_floating_fields (regcache, type, buf, 0); + memcpy (valbuf, buf, len); + } + else if (sparc64_floating_p (type)) + { + /* Floating return values. */ + for (i = 0; i < len / 4; i++) + regcache_cooked_read (regcache, SPARC_F0_REGNUM + i, buf + i * 4); + memcpy (valbuf, buf, len); + } + else + { + /* Integral and pointer return values. */ + gdb_assert (sparc64_integral_or_pointer_p (type)); + + /* Just stripping off any unused bytes should preserve the + signed-ness just fine. */ + regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf); + memcpy (valbuf, buf + 8 - len, len); + } +} + +/* Write into the appropriate registers a function return value stored + in VALBUF of type TYPE. */ + +static void +sparc64_store_return_value (struct type *type, struct regcache *regcache, + const void *valbuf) +{ + int len = TYPE_LENGTH (type); + char buf[16]; + int i; + + if (sparc64_structure_or_union_p (type)) + { + /* Structure or Union return values. */ + gdb_assert (len <= 32); + + /* Simplify matters by storing the complete value (including + floating members) into %o0 and %o1. Floating members are + also store in the appropriate floating-point registers. */ + memset (buf, 0, sizeof (buf)); + memcpy (buf, valbuf, len); + for (i = 0; i < ((len + 7) / 8); i++) + regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 8); + if (TYPE_CODE (type) != TYPE_CODE_UNION) + sparc64_store_floating_fields (regcache, type, buf, 0, 0); + } + else if (sparc64_floating_p (type)) + { + /* Floating return values. */ + memcpy (buf, valbuf, len); + for (i = 0; i < len / 4; i++) + regcache_cooked_write (regcache, SPARC_F0_REGNUM + i, buf + i * 4); + } + else + { + /* Integral and pointer return values. */ + gdb_assert (sparc64_integral_or_pointer_p (type)); + + /* ??? Do we need to do any sign-extension here? */ + memset (buf, 0, 8); + memcpy (buf + 8 - len, valbuf, len); + regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf); + } +} + +static enum return_value_convention +sparc64_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, void *readbuf, + const void *writebuf) +{ + if (TYPE_LENGTH (type) > 32) + return RETURN_VALUE_STRUCT_CONVENTION; + + if (readbuf) + sparc64_extract_return_value (type, regcache, readbuf); + if (writebuf) + sparc64_store_return_value (type, regcache, writebuf); + + return RETURN_VALUE_REGISTER_CONVENTION; +} + + +void +sparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + tdep->pc_regnum = SPARC64_PC_REGNUM; + tdep->npc_regnum = SPARC64_NPC_REGNUM; + + /* This is what all the fuss is about. */ + set_gdbarch_long_bit (gdbarch, 64); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_ptr_bit (gdbarch, 64); + + set_gdbarch_num_regs (gdbarch, SPARC64_NUM_REGS); + set_gdbarch_register_name (gdbarch, sparc64_register_name); + set_gdbarch_register_type (gdbarch, sparc64_register_type); + set_gdbarch_num_pseudo_regs (gdbarch, SPARC64_NUM_PSEUDO_REGS); + set_gdbarch_pseudo_register_read (gdbarch, sparc64_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, sparc64_pseudo_register_write); + + /* Register numbers of various important registers. */ + set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM); /* %pc */ + + /* Call dummy code. */ + set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT); + set_gdbarch_push_dummy_code (gdbarch, NULL); + set_gdbarch_push_dummy_call (gdbarch, sparc64_push_dummy_call); + + set_gdbarch_return_value (gdbarch, sparc64_return_value); + set_gdbarch_stabs_argument_has_addr + (gdbarch, default_stabs_argument_has_addr); + + set_gdbarch_skip_prologue (gdbarch, sparc64_skip_prologue); + + frame_unwind_append_sniffer (gdbarch, sparc64_frame_sniffer); + frame_base_set_default (gdbarch, &sparc64_frame_base); +} + + +/* Helper functions for dealing with register sets. */ + +#define TSTATE_CWP 0x000000000000001fULL +#define TSTATE_ICC 0x0000000f00000000ULL +#define TSTATE_XCC 0x000000f000000000ULL + +#define PSR_S 0x00000080 +#define PSR_ICC 0x00f00000 +#define PSR_VERS 0x0f000000 +#define PSR_IMPL 0xf0000000 +#define PSR_V8PLUS 0xff000000 +#define PSR_XCC 0x000f0000 + +void +sparc64_supply_gregset (const struct sparc_gregset *gregset, + struct regcache *regcache, + int regnum, const void *gregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + const char *regs = gregs; + int i; + + if (sparc32) + { + if (regnum == SPARC32_PSR_REGNUM || regnum == -1) + { + int offset = gregset->r_tstate_offset; + ULONGEST tstate, psr; + char buf[4]; + + tstate = extract_unsigned_integer (regs + offset, 8); + psr = ((tstate & TSTATE_CWP) | PSR_S | ((tstate & TSTATE_ICC) >> 12) + | ((tstate & TSTATE_XCC) >> 20) | PSR_V8PLUS); + store_unsigned_integer (buf, 4, psr); + regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, buf); + } + + if (regnum == SPARC32_PC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_PC_REGNUM, + regs + gregset->r_pc_offset + 4); + + if (regnum == SPARC32_NPC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, + regs + gregset->r_npc_offset + 4); + + if (regnum == SPARC32_Y_REGNUM || regnum == -1) + { + int offset = gregset->r_y_offset + 8 - gregset->r_y_size; + regcache_raw_supply (regcache, SPARC32_Y_REGNUM, regs + offset); + } + } + else + { + if (regnum == SPARC64_STATE_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC64_STATE_REGNUM, + regs + gregset->r_tstate_offset); + + if (regnum == SPARC64_PC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC64_PC_REGNUM, + regs + gregset->r_pc_offset); + + if (regnum == SPARC64_NPC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC64_NPC_REGNUM, + regs + gregset->r_npc_offset); + + if (regnum == SPARC64_Y_REGNUM || regnum == -1) + { + char buf[8]; + + memset (buf, 0, 8); + memcpy (buf + 8 - gregset->r_y_size, + regs + gregset->r_y_offset, gregset->r_y_size); + regcache_raw_supply (regcache, SPARC64_Y_REGNUM, buf); + } + + if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1) + && gregset->r_fprs_offset != -1) + regcache_raw_supply (regcache, SPARC64_FPRS_REGNUM, + regs + gregset->r_fprs_offset); + } + + if (regnum == SPARC_G0_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL); + + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) + { + int offset = gregset->r_g1_offset; + + if (sparc32) + offset += 4; + + for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + offset); + offset += 8; + } + } + + if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) + { + /* Not all of the register set variants include Locals and + Inputs. For those that don't, we read them off the stack. */ + if (gregset->r_l0_offset == -1) + { + ULONGEST sp; + + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + sparc_supply_rwindow (regcache, sp, regnum); + } + else + { + int offset = gregset->r_l0_offset; + + if (sparc32) + offset += 4; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + offset); + offset += 8; + } + } + } +} + +void +sparc64_collect_gregset (const struct sparc_gregset *gregset, + const struct regcache *regcache, + int regnum, void *gregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + char *regs = gregs; + int i; + + if (sparc32) + { + if (regnum == SPARC32_PSR_REGNUM || regnum == -1) + { + int offset = gregset->r_tstate_offset; + ULONGEST tstate, psr; + char buf[8]; + + tstate = extract_unsigned_integer (regs + offset, 8); + regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, buf); + psr = extract_unsigned_integer (buf, 4); + tstate |= (psr & PSR_ICC) << 12; + if ((psr & (PSR_VERS | PSR_IMPL)) == PSR_V8PLUS) + tstate |= (psr & PSR_XCC) << 20; + store_unsigned_integer (buf, 8, tstate); + memcpy (regs + offset, buf, 8); + } + + if (regnum == SPARC32_PC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_PC_REGNUM, + regs + gregset->r_pc_offset + 4); + + if (regnum == SPARC32_NPC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_NPC_REGNUM, + regs + gregset->r_npc_offset + 4); + + if (regnum == SPARC32_Y_REGNUM || regnum == -1) + { + int offset = gregset->r_y_offset + 8 - gregset->r_y_size; + regcache_raw_collect (regcache, SPARC32_Y_REGNUM, regs + offset); + } + } + else + { + if (regnum == SPARC64_STATE_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC64_STATE_REGNUM, + regs + gregset->r_tstate_offset); + + if (regnum == SPARC64_PC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC64_PC_REGNUM, + regs + gregset->r_pc_offset); + + if (regnum == SPARC64_NPC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC64_NPC_REGNUM, + regs + gregset->r_npc_offset); + + if (regnum == SPARC64_Y_REGNUM || regnum == -1) + { + char buf[8]; + + regcache_raw_collect (regcache, SPARC64_Y_REGNUM, buf); + memcpy (regs + gregset->r_y_offset, + buf + 8 - gregset->r_y_size, gregset->r_y_size); + } + + if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1) + && gregset->r_fprs_offset != -1) + regcache_raw_collect (regcache, SPARC64_FPRS_REGNUM, + regs + gregset->r_fprs_offset); + + } + + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) + { + int offset = gregset->r_g1_offset; + + if (sparc32) + offset += 4; + + /* %g0 is always zero. */ + for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_collect (regcache, i, regs + offset); + offset += 8; + } + } + + if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) + { + /* Not all of the register set variants include Locals and + Inputs. For those that don't, we read them off the stack. */ + if (gregset->r_l0_offset != -1) + { + int offset = gregset->r_l0_offset; + + if (sparc32) + offset += 4; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_collect (regcache, i, regs + offset); + offset += 8; + } + } + } +} + +void +sparc64_supply_fpregset (struct regcache *regcache, + int regnum, const void *fpregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + const char *regs = fpregs; + int i; + + for (i = 0; i < 32; i++) + { + if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) + regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); + } + + if (sparc32) + { + if (regnum == SPARC32_FSR_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_FSR_REGNUM, + regs + (32 * 4) + (16 * 8) + 4); + } + else + { + for (i = 0; i < 16; i++) + { + if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1) + regcache_raw_supply (regcache, SPARC64_F32_REGNUM + i, + regs + (32 * 4) + (i * 8)); + } + + if (regnum == SPARC64_FSR_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC64_FSR_REGNUM, + regs + (32 * 4) + (16 * 8)); + } +} + +void +sparc64_collect_fpregset (const struct regcache *regcache, + int regnum, void *fpregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + char *regs = fpregs; + int i; + + for (i = 0; i < 32; i++) + { + if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) + regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); + } + + if (sparc32) + { + if (regnum == SPARC32_FSR_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_FSR_REGNUM, + regs + (32 * 4) + (16 * 8) + 4); + } + else + { + for (i = 0; i < 16; i++) + { + if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1) + regcache_raw_collect (regcache, SPARC64_F32_REGNUM + i, + regs + (32 * 4) + (i * 8)); + } + + if (regnum == SPARC64_FSR_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC64_FSR_REGNUM, + regs + (32 * 4) + (16 * 8)); + } +} diff --git a/contrib/gdb/gdb/sparc64-tdep.h b/contrib/gdb/gdb/sparc64-tdep.h new file mode 100644 index 00000000000..c3073b90b3a --- /dev/null +++ b/contrib/gdb/gdb/sparc64-tdep.h @@ -0,0 +1,123 @@ +/* Target-dependent code for UltraSPARC. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef SPARC64_TDEP_H +#define SPARC64_TDEP_H 1 + +struct frame_info; +struct gdbarch; +struct regcache; +struct sparc_gregset; +struct trad_frame_saved_reg; + +#include "sparc-tdep.h" + +/* The stack pointer is offset from the stack frame by a BIAS of 2047 + (0x7ff) for 64-bit code. BIAS is likely to be defined on SPARC + hosts, so undefine it first. */ +#undef BIAS +#define BIAS 2047 + +/* Register offsets for the general-purpose register set. */ + +/* UltraSPARC doesn't have %psr. */ +#define r_tstate_offset r_psr_offset + +/* UltraSPARC doesn't have %wim either. */ +#define r_fprs_offset r_wim_offset + +/* Register numbers of various important registers. */ + +enum sparc64_regnum +{ + SPARC64_F32_REGNUM /* %f32 */ + = SPARC_F0_REGNUM + 32, + SPARC64_F62_REGNUM /* %f62 */ + = SPARC64_F32_REGNUM + 15, + SPARC64_PC_REGNUM, /* %pc */ + SPARC64_NPC_REGNUM, /* %npc */ + SPARC64_STATE_REGNUM, + SPARC64_FSR_REGNUM, /* %fsr */ + SPARC64_FPRS_REGNUM, /* %fprs */ + SPARC64_Y_REGNUM, /* %y */ + + /* Pseudo registers. */ + SPARC64_CWP_REGNUM, /* %cwp */ + SPARC64_PSTATE_REGNUM, /* %pstate */ + SPARC64_ASI_REGNUM, /* %asi */ + SPARC64_CCR_REGNUM, /* %ccr */ + SPARC64_D0_REGNUM, /* %d0 */ + SPARC64_D10_REGNUM /* %d10 */ + = SPARC64_D0_REGNUM + 5, + SPARC64_D30_REGNUM /* %d30 */ + = SPARC64_D0_REGNUM + 15, + SPARC64_D32_REGNUM /* %d32 */ + = SPARC64_D0_REGNUM + 16, + SPARC64_D62_REGNUM /* %d62 */ + = SPARC64_D0_REGNUM + 31, + SPARC64_Q0_REGNUM, /* %q0 */ + SPARC64_Q8_REGNUM /* %q8 */ + = SPARC64_Q0_REGNUM + 2, + SPARC64_Q28_REGNUM /* %q28 */ + = SPARC64_Q0_REGNUM + 7, + SPARC64_Q32_REGNUM /* %q32 */ + = SPARC64_Q0_REGNUM + 8, + SPARC64_Q60_REGNUM /* %q60 */ + = SPARC64_Q0_REGNUM + 15 +}; + +extern void sparc64_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch); + +extern void sparc64_supply_gregset (const struct sparc_gregset *gregset, + struct regcache *regcache, + int regnum, const void *gregs); +extern void sparc64_collect_gregset (const struct sparc_gregset *gregset, + const struct regcache *regcache, + int regnum, void *gregs); +extern void sparc64_supply_fpregset (struct regcache *regcache, + int regnum, const void *fpregs); +extern void sparc64_collect_fpregset (const struct regcache *regcache, + int regnum, void *fpregs); + +/* Functions and variables exported from sparc64-sol2-tdep.c. */ + +/* Register offsets for Solaris 2. */ +extern const struct sparc_gregset sparc64_sol2_gregset; + +extern void sparc64_sol2_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch); + +/* Variables exported from sparc64fbsd-tdep.c. */ + +/* Register offsets for FreeBSD/sparc64. */ +extern const struct sparc_gregset sparc64fbsd_gregset; + +/* Functions and variables exported from sparc64nbsd-tdep.c. */ + +/* Register offsets for NetBSD/sparc64. */ +extern const struct sparc_gregset sparc64nbsd_gregset; + +extern struct trad_frame_saved_reg * + sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr, + struct frame_info *next_frame); + +#endif /* sparc64-tdep.h */ diff --git a/contrib/gdb/gdb/sparc64fbsd-nat.c b/contrib/gdb/gdb/sparc64fbsd-nat.c new file mode 100644 index 00000000000..09bf12a4c00 --- /dev/null +++ b/contrib/gdb/gdb/sparc64fbsd-nat.c @@ -0,0 +1,34 @@ +/* Native-dependent code for FreeBSD/sparc64. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "sparc64-tdep.h" +#include "sparc-nat.h" + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc64fbsd_nat (void); + +void +_initialize_sparc64fbsd_nat (void) +{ + sparc_gregset = &sparc64fbsd_gregset; +} diff --git a/contrib/gdb/gdb/sparc64fbsd-tdep.c b/contrib/gdb/gdb/sparc64fbsd-tdep.c new file mode 100644 index 00000000000..3c1335df431 --- /dev/null +++ b/contrib/gdb/gdb/sparc64fbsd-tdep.c @@ -0,0 +1,225 @@ +/* Target-dependent code for FreeBSD/sparc64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "osabi.h" +#include "regcache.h" +#include "regset.h" +#include "target.h" +#include "trad-frame.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "sparc64-tdep.h" + +/* From . */ +const struct sparc_gregset sparc64fbsd_gregset = +{ + 26 * 8, /* "tstate" */ + 25 * 8, /* %pc */ + 24 * 8, /* %npc */ + 28 * 8, /* %y */ + 16 * 8, /* %fprs */ + -1, + 1 * 8, /* %g1 */ + -1, /* %l0 */ + 8 /* sizeof (%y) */ +}; + + +static void +sparc64fbsd_supply_gregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + sparc64_supply_gregset (regset->descr, regcache, regnum, gregs); +} + +static void +sparc64fbsd_supply_fpregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *fpregs, size_t len) +{ + sparc64_supply_fpregset (regcache, regnum, fpregs); +} + + +/* Signal trampolines. */ + +static int +sparc64fbsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + return (name && strcmp (name, "__sigtramp") == 0); +} + +static struct sparc_frame_cache * +sparc64fbsd_sigtramp_frame_cache (struct frame_info *next_frame, + void **this_cache) +{ + struct sparc_frame_cache *cache; + CORE_ADDR addr, mcontext_addr, sp; + LONGEST fprs; + int regnum; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + gdb_assert (cache == *this_cache); + + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + /* The third argument is a pointer to an instance of `ucontext_t', + which has a member `uc_mcontext' that contains the saved + registers. */ + addr = frame_unwind_register_unsigned (next_frame, SPARC_O2_REGNUM); + mcontext_addr = addr + 64; + + /* The following registers travel in the `mc_local' slots of + `mcontext_t'. */ + addr = mcontext_addr + 16 * 8; + cache->saved_regs[SPARC64_FPRS_REGNUM].addr = addr + 0 * 8; + cache->saved_regs[SPARC64_FSR_REGNUM].addr = addr + 1 * 8; + + /* The following registers travel in the `mc_in' slots of + `mcontext_t'. */ + addr = mcontext_addr + 24 * 8; + cache->saved_regs[SPARC64_NPC_REGNUM].addr = addr + 0 * 8; + cache->saved_regs[SPARC64_PC_REGNUM].addr = addr + 1 * 8; + cache->saved_regs[SPARC64_STATE_REGNUM].addr = addr + 2 * 8; + cache->saved_regs[SPARC64_Y_REGNUM].addr = addr + 4 * 8; + + /* The `global' and `out' registers travel in the `mc_global' and + `mc_out' slots of `mcontext_t', except for %g0. Since %g0 is + always zero, keep the identity encoding. */ + for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 8; + regnum <= SPARC_O7_REGNUM; regnum++, addr += 8) + cache->saved_regs[regnum].addr = addr; + + /* The `local' and `in' registers have been saved in the register + save area. */ + addr = cache->saved_regs[SPARC_SP_REGNUM].addr; + sp = get_frame_memory_unsigned (next_frame, addr, 8); + for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS; + regnum <= SPARC_I7_REGNUM; regnum++, addr += 8) + cache->saved_regs[regnum].addr = addr; + + /* The floating-point registers are only saved if the FEF bit in + %fprs has been set. */ + +#define FPRS_FEF (1 << 2) + + addr = cache->saved_regs[SPARC64_FPRS_REGNUM].addr; + fprs = get_frame_memory_unsigned (next_frame, addr, 8); + if (fprs & FPRS_FEF) + { + for (regnum = SPARC_F0_REGNUM, addr = mcontext_addr + 32 * 8; + regnum <= SPARC_F31_REGNUM; regnum++, addr += 4) + cache->saved_regs[regnum].addr = addr; + + for (regnum = SPARC64_F32_REGNUM; + regnum <= SPARC64_F62_REGNUM; regnum++, addr += 8) + cache->saved_regs[regnum].addr = addr; + } + + return cache; +} + +static void +sparc64fbsd_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc64fbsd_sigtramp_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc64fbsd_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc64fbsd_sigtramp_frame_cache (next_frame, this_cache); + + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + sparc64fbsd_sigtramp_frame_this_id, + sparc64fbsd_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +sparc64fbsd_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (sparc64fbsd_pc_in_sigtramp (pc, name)) + return &sparc64fbsd_sigtramp_frame_unwind; + + return NULL; +} + + +static void +sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = &sparc64fbsd_gregset; + tdep->gregset->supply_regset = sparc64fbsd_supply_gregset; + tdep->sizeof_gregset = 256; + + tdep->fpregset = XMALLOC (struct regset); + tdep->fpregset->supply_regset = sparc64fbsd_supply_fpregset; + tdep->sizeof_fpregset = 272; + + set_gdbarch_pc_in_sigtramp (gdbarch, sparc64fbsd_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, sparc64fbsd_sigtramp_frame_sniffer); + + sparc64_init_abi (info, gdbarch); +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc64fbsd_tdep (void); + +void +_initialize_sparc64fbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, + GDB_OSABI_FREEBSD_ELF, sparc64fbsd_init_abi); +} diff --git a/contrib/gdb/gdb/sparc64nbsd-nat.c b/contrib/gdb/gdb/sparc64nbsd-nat.c new file mode 100644 index 00000000000..91577039eb3 --- /dev/null +++ b/contrib/gdb/gdb/sparc64nbsd-nat.c @@ -0,0 +1,139 @@ +/* Native-dependent code for NetBSD/sparc64. + + Copyright 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "sparc64-tdep.h" +#include "sparc-nat.h" + +/* NetBSD is different from the other OSes that support both SPARC and + UltraSPARC in that the result of ptrace(2) depends on whether the + traced process is 32-bit or 64-bit. */ + +static void +sparc64nbsd_supply_gregset (const struct sparc_gregset *gregset, + struct regcache *regcache, + int regnum, const void *gregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + + if (sparc32) + sparc32_supply_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs); + else + sparc64_supply_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs); +} + +static void +sparc64nbsd_collect_gregset (const struct sparc_gregset *gregset, + const struct regcache *regcache, + int regnum, void *gregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + + if (sparc32) + sparc32_collect_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs); + else + sparc64_collect_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs); +} + +static void +sparc64nbsd_supply_fpregset (struct regcache *regcache, + int regnum, const void *fpregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + + if (sparc32) + sparc32_supply_fpregset (regcache, regnum, fpregs); + else + sparc64_supply_fpregset (regcache, regnum, fpregs); +} + +static void +sparc64nbsd_collect_fpregset (const struct regcache *regcache, + int regnum, void *fpregs) +{ + int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32); + + if (sparc32) + sparc32_collect_fpregset (regcache, regnum, fpregs); + else + sparc64_collect_fpregset (regcache, regnum, fpregs); +} + +/* Determine whether `gregset_t' contains register REGNUM. */ + +static int +sparc64nbsd_gregset_supplies_p (int regnum) +{ + if (gdbarch_ptr_bit (current_gdbarch) == 32) + return sparc32_gregset_supplies_p (regnum); + + /* Integer registers. */ + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM) + || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM) + || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM)) + return 1; + + /* Control registers. */ + if (regnum == SPARC64_PC_REGNUM + || regnum == SPARC64_NPC_REGNUM + || regnum == SPARC64_STATE_REGNUM + || regnum == SPARC64_Y_REGNUM) + return 1; + + return 0; +} + +/* Determine whether `fpregset_t' contains register REGNUM. */ + +static int +sparc64nbsd_fpregset_supplies_p (int regnum) +{ + if (gdbarch_ptr_bit (current_gdbarch) == 32) + return sparc32_fpregset_supplies_p (regnum); + + /* Floating-point registers. */ + if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) + || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM)) + return 1; + + /* Control registers. */ + if (regnum == SPARC64_FSR_REGNUM) + return 1; + + return 0; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparcnbsd_nat (void); + +void +_initialize_sparcnbsd_nat (void) +{ + sparc_supply_gregset = sparc64nbsd_supply_gregset; + sparc_collect_gregset = sparc64nbsd_collect_gregset; + sparc_supply_fpregset = sparc64nbsd_supply_fpregset; + sparc_collect_fpregset = sparc64nbsd_collect_fpregset; + sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p; + sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p; +} diff --git a/contrib/gdb/gdb/sparc64nbsd-tdep.c b/contrib/gdb/gdb/sparc64nbsd-tdep.c new file mode 100644 index 00000000000..8e7987008e7 --- /dev/null +++ b/contrib/gdb/gdb/sparc64nbsd-tdep.c @@ -0,0 +1,256 @@ +/* Target-dependent code for NetBSD/sparc64. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + Based on code contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "osabi.h" +#include "regcache.h" +#include "regset.h" +#include "symtab.h" +#include "solib-svr4.h" +#include "trad-frame.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "sparc64-tdep.h" +#include "nbsd-tdep.h" + +/* From . */ +const struct sparc_gregset sparc64nbsd_gregset = +{ + 0 * 8, /* "tstate" */ + 1 * 8, /* %pc */ + 2 * 8, /* %npc */ + 3 * 8, /* %y */ + -1, /* %fprs */ + -1, + 5 * 8, /* %g1 */ + -1, /* %l0 */ + 4 /* sizeof (%y) */ +}; + + +static void +sparc64nbsd_supply_gregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + sparc64_supply_gregset (regset->descr, regcache, regnum, gregs); +} + +static void +sparc64nbsd_supply_fpregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *fpregs, size_t len) +{ + sparc64_supply_fpregset (regcache, regnum, fpregs); +} + + +/* Signal trampolines. */ + +/* The following variables describe the location of an on-stack signal + trampoline. The current values correspond to the memory layout for + NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and + up, since NetBSD uses signal trampolines provided by libc now. */ + +static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL; +static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL; + +static int +sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end) + return 1; + + return nbsd_pc_in_sigtramp (pc, name); +} + +struct trad_frame_saved_reg * +sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr, + struct frame_info *next_frame) +{ + struct trad_frame_saved_reg *saved_regs; + CORE_ADDR addr, sp; + int regnum, delta; + + saved_regs = trad_frame_alloc_saved_regs (next_frame); + + /* The registers are saved in bits and pieces scattered all over the + place. The code below records their location on the assumption + that the part of the signal trampoline that saves the state has + been executed. */ + + saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8; + saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16; + saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24; + saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32; + saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40; + saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48; + + /* The remaining `global' registers and %y are saved in the `local' + registers. */ + delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM; + for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++) + saved_regs[regnum].realreg = regnum + delta; + saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM; + + /* The remaining `out' registers can be found in the current frame's + `in' registers. */ + delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM; + for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++) + saved_regs[regnum].realreg = regnum + delta; + saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM; + + /* The `local' and `in' registers have been saved in the register + save area. */ + addr = saved_regs[SPARC_SP_REGNUM].addr; + sp = get_frame_memory_unsigned (next_frame, addr, 8); + for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS; + regnum <= SPARC_I7_REGNUM; regnum++, addr += 8) + saved_regs[regnum].addr = addr; + + /* TODO: Handle the floating-point registers. */ + + return saved_regs; +} + +static struct sparc_frame_cache * +sparc64nbsd_sigcontext_frame_cache (struct frame_info *next_frame, + void **this_cache) +{ + struct sparc_frame_cache *cache; + CORE_ADDR addr; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + gdb_assert (cache == *this_cache); + + /* If we couldn't find the frame's function, we're probably dealing + with an on-stack signal trampoline. */ + if (cache->pc == 0) + { + cache->pc = sparc64nbsd_sigtramp_start; + + /* Since we couldn't find the frame's function, the cache was + initialized under the assumption that we're frameless. */ + cache->frameless_p = 0; + addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); + cache->base = addr; + } + + /* We find the appropriate instance of `struct sigcontext' at a + fixed offset in the signal frame. */ + addr = cache->base + BIAS + 128 + 8; + cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, next_frame); + + return cache; +} + +static void +sparc64nbsd_sigcontext_frame_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc64nbsd_sigcontext_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc64nbsd_sigcontext_frame_cache (next_frame, this_cache); + + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind = +{ + SIGTRAMP_FRAME, + sparc64nbsd_sigcontext_frame_this_id, + sparc64nbsd_sigcontext_frame_prev_register +}; + +static const struct frame_unwind * +sparc64nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (sparc64nbsd_pc_in_sigtramp (pc, name)) + { + if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21)) + return &sparc64nbsd_sigcontext_frame_unwind; + } + + return NULL; +} + + +static void +sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = &sparc64nbsd_gregset; + tdep->gregset->supply_regset = sparc64nbsd_supply_gregset; + tdep->sizeof_gregset = 160; + + tdep->fpregset = XMALLOC (struct regset); + tdep->fpregset->supply_regset = sparc64nbsd_supply_fpregset; + tdep->sizeof_fpregset = 272; + + set_gdbarch_pc_in_sigtramp (gdbarch, sparc64nbsd_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, sparc64nbsd_sigtramp_frame_sniffer); + + sparc64_init_abi (info, gdbarch); + + set_solib_svr4_fetch_link_map_offsets + (gdbarch, nbsd_lp64_solib_svr4_fetch_link_map_offsets); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc64nbsd_tdep (void); + +void +_initialize_sparc64nbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, + GDB_OSABI_NETBSD_ELF, sparc64nbsd_init_abi); +} diff --git a/contrib/gdb/gdb/sparc64obsd-tdep.c b/contrib/gdb/gdb/sparc64obsd-tdep.c new file mode 100644 index 00000000000..190a46be1fa --- /dev/null +++ b/contrib/gdb/gdb/sparc64obsd-tdep.c @@ -0,0 +1,210 @@ +/* Target-dependent code for OpenBSD/sparc64. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "frame-unwind.h" +#include "osabi.h" +#include "regset.h" +#include "symtab.h" +#include "solib-svr4.h" +#include "trad-frame.h" + +#include "gdb_assert.h" + +#include "sparc64-tdep.h" +#include "nbsd-tdep.h" + +/* OpenBSD uses the traditional NetBSD core file format, even for + ports that use ELF. The core files don't use multiple register + sets. Instead, the general-purpose and floating-point registers + are lumped together in a single section. Unlike on NetBSD, OpenBSD + uses a different layout for its general-purpose registers than the + layout used for ptrace(2). */ + +/* From . */ +const struct sparc_gregset sparc64obsd_core_gregset = +{ + 0 * 8, /* "tstate" */ + 1 * 8, /* %pc */ + 2 * 8, /* %npc */ + 3 * 8, /* %y */ + -1, /* %fprs */ + -1, + 7 * 8, /* %g1 */ + 22 * 8, /* %l0 */ + 4 /* sizeof (%y) */ +}; + +static void +sparc64obsd_supply_gregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + const char *regs = gregs; + + sparc64_supply_gregset (regset->descr, regcache, regnum, regs); + sparc64_supply_fpregset (regcache, regnum, regs + 288); +} + + +/* Signal trampolines. */ + +/* The OpenBSD kernel maps the signal trampoline at some random + location in user space, which means that the traditional BSD way of + detecting it won't work. + + The signal trampoline will be mapped at an address that is page + aligned. We recognize the signal trampoline by the looking for the + sigreturn system call. */ + +static const int sparc64obsd_page_size = 8192; + +static int +sparc64obsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + CORE_ADDR start_pc = (pc & ~(sparc64obsd_page_size - 1)); + unsigned long insn; + + if (name) + return 0; + + /* Check for "restore %g0, SYS_sigreturn, %g1". */ + insn = sparc_fetch_instruction (start_pc + 0xe8); + if (insn != 0x83e82067) + return 0; + + /* Check for "t ST_SYSCALL". */ + insn = sparc_fetch_instruction (start_pc + 0xf0); + if (insn != 0x91d02000) + return 0; + + return 1; +} + +static struct sparc_frame_cache * +sparc64obsd_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct sparc_frame_cache *cache; + CORE_ADDR addr; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + gdb_assert (cache == *this_cache); + + /* If we couldn't find the frame's function, we're probably dealing + with an on-stack signal trampoline. */ + if (cache->pc == 0) + { + cache->pc = frame_pc_unwind (next_frame); + cache->pc &= ~(sparc64obsd_page_size - 1); + + /* Since we couldn't find the frame's function, the cache was + initialized under the assumption that we're frameless. */ + cache->frameless_p = 0; + addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); + cache->base = addr; + } + + /* We find the appropriate instance of `struct sigcontext' at a + fixed offset in the signal frame. */ + addr = cache->base + BIAS + 128 + 16; + cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, next_frame); + + return cache; +} + +static void +sparc64obsd_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc64obsd_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc64obsd_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc64obsd_frame_cache (next_frame, this_cache); + + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc64obsd_frame_unwind = +{ + SIGTRAMP_FRAME, + sparc64obsd_frame_this_id, + sparc64obsd_frame_prev_register +}; + +static const struct frame_unwind * +sparc64obsd_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (sparc64obsd_pc_in_sigtramp (pc, name)) + return &sparc64obsd_frame_unwind; + + return NULL; +} + + +static void +sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = &sparc64obsd_core_gregset; + tdep->gregset->supply_regset = sparc64obsd_supply_gregset; + tdep->sizeof_gregset = 832; + + set_gdbarch_pc_in_sigtramp (gdbarch, sparc64obsd_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, sparc64obsd_sigtramp_frame_sniffer); + + sparc64_init_abi (info, gdbarch); + + set_solib_svr4_fetch_link_map_offsets + (gdbarch, nbsd_lp64_solib_svr4_fetch_link_map_offsets); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc64obsd_tdep (void); + +void +_initialize_sparc64obsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, + GDB_OSABI_OPENBSD_ELF, sparc64obsd_init_abi); +} diff --git a/contrib/gdb/gdb/sparcnbsd-nat.c b/contrib/gdb/gdb/sparcnbsd-nat.c new file mode 100644 index 00000000000..9038ea334b6 --- /dev/null +++ b/contrib/gdb/gdb/sparcnbsd-nat.c @@ -0,0 +1,34 @@ +/* Native-dependent code for NetBSD/sparc. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "sparc-tdep.h" +#include "sparc-nat.h" + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparcnbsd_nat (void); + +void +_initialize_sparcnbsd_nat (void) +{ + sparc_gregset = &sparc32nbsd_gregset; +} diff --git a/contrib/gdb/gdb/sparcnbsd-tdep.c b/contrib/gdb/gdb/sparcnbsd-tdep.c new file mode 100644 index 00000000000..b1be7eb5b12 --- /dev/null +++ b/contrib/gdb/gdb/sparcnbsd-tdep.c @@ -0,0 +1,358 @@ +/* Target-dependent code for NetBSD/sparc. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "floatformat.h" +#include "frame.h" +#include "frame-unwind.h" +#include "gdbcore.h" +#include "osabi.h" +#include "regcache.h" +#include "regset.h" +#include "solib-svr4.h" +#include "symtab.h" +#include "trad-frame.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "sparc-tdep.h" +#include "nbsd-tdep.h" + +const struct sparc_gregset sparc32nbsd_gregset = +{ + 0 * 4, /* %psr */ + 1 * 4, /* %pc */ + 2 * 4, /* %npc */ + 3 * 4, /* %y */ + -1, /* %wim */ + -1, /* %tbr */ + 5 * 4, /* %g1 */ + -1 /* %l0 */ +}; + +static void +sparc32nbsd_supply_gregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + sparc32_supply_gregset (regset->descr, regcache, regnum, gregs); + + /* Traditional NetBSD core files don't use multiple register sets. + Instead, the general-purpose and floating-point registers are + lumped together in a single section. */ + if (len >= 212) + sparc32_supply_fpregset (regcache, regnum, (const char *) gregs + 80); +} + +static void +sparc32nbsd_supply_fpregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *fpregs, size_t len) +{ + sparc32_supply_fpregset (regcache, regnum, fpregs); +} + + +/* Signal trampolines. */ + +/* The following variables describe the location of an on-stack signal + trampoline. The current values correspond to the memory layout for + NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and + up, since NetBSD uses signal trampolines provided by libc now. */ + +static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0; +static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0; + +static int +sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end) + return 1; + + return nbsd_pc_in_sigtramp (pc, name); +} + +struct trad_frame_saved_reg * +sparc32nbsd_sigcontext_saved_regs (struct frame_info *next_frame) +{ + struct trad_frame_saved_reg *saved_regs; + CORE_ADDR addr, sigcontext_addr; + int regnum, delta; + ULONGEST psr; + + saved_regs = trad_frame_alloc_saved_regs (next_frame); + + /* We find the appropriate instance of `struct sigcontext' at a + fixed offset in the signal frame. */ + addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); + sigcontext_addr = addr + 64 + 16; + + /* The registers are saved in bits and pieces scattered all over the + place. The code below records their location on the assumption + that the part of the signal trampoline that saves the state has + been executed. */ + + saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8; + saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12; + saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16; + saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20; + saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24; + saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28; + + /* The remaining `global' registers and %y are saved in the `local' + registers. */ + delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM; + for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++) + saved_regs[regnum].realreg = regnum + delta; + saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM; + + /* The remaining `out' registers can be found in the current frame's + `in' registers. */ + delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM; + for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++) + saved_regs[regnum].realreg = regnum + delta; + saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM; + + /* The `local' and `in' registers have been saved in the register + save area. */ + addr = saved_regs[SPARC_SP_REGNUM].addr; + addr = get_frame_memory_unsigned (next_frame, addr, 4); + for (regnum = SPARC_L0_REGNUM; + regnum <= SPARC_I7_REGNUM; regnum++, addr += 4) + saved_regs[regnum].addr = addr; + + /* Handle StackGhost. */ + { + ULONGEST wcookie = sparc_fetch_wcookie (); + + if (wcookie != 0) + { + ULONGEST i7; + + addr = saved_regs[SPARC_I7_REGNUM].addr; + i7 = get_frame_memory_unsigned (next_frame, addr, 4); + trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie); + } + } + + /* The floating-point registers are only saved if the EF bit in %prs + has been set. */ + +#define PSR_EF 0x00001000 + + addr = saved_regs[SPARC32_PSR_REGNUM].addr; + psr = get_frame_memory_unsigned (next_frame, addr, 4); + if (psr & PSR_EF) + { + CORE_ADDR sp; + + sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM); + saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96; + for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8; + regnum <= SPARC_F31_REGNUM; regnum++, addr += 4) + saved_regs[regnum].addr = addr; + } + + return saved_regs; +} + +static struct sparc_frame_cache * +sparc32nbsd_sigcontext_frame_cache (struct frame_info *next_frame, + void **this_cache) +{ + struct sparc_frame_cache *cache; + CORE_ADDR addr; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + gdb_assert (cache == *this_cache); + + /* If we couldn't find the frame's function, we're probably dealing + with an on-stack signal trampoline. */ + if (cache->pc == 0) + { + cache->pc = sparc32nbsd_sigtramp_start; + + /* Since we couldn't find the frame's function, the cache was + initialized under the assumption that we're frameless. */ + cache->frameless_p = 0; + addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); + cache->base = addr; + } + + cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (next_frame); + + return cache; +} + +static void +sparc32nbsd_sigcontext_frame_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc32nbsd_sigcontext_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc32nbsd_sigcontext_frame_cache (next_frame, this_cache); + + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind = +{ + SIGTRAMP_FRAME, + sparc32nbsd_sigcontext_frame_this_id, + sparc32nbsd_sigcontext_frame_prev_register +}; + +static const struct frame_unwind * +sparc32nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (sparc32nbsd_pc_in_sigtramp (pc, name)) + { + if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21)) + return &sparc32nbsd_sigcontext_frame_unwind; + } + + return NULL; +} + + +/* Return non-zero if we are in a shared library trampoline code stub. */ + +static int +sparcnbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name) +{ + return (name && !strcmp (name, "_DYNAMIC")); +} + +static void +sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* NetBSD doesn't support the 128-bit `long double' from the psABI. */ + set_gdbarch_long_double_bit (gdbarch, 64); + set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); + + tdep->gregset = XMALLOC (struct regset); + tdep->gregset->descr = &sparc32nbsd_gregset; + tdep->gregset->supply_regset = sparc32nbsd_supply_gregset; + tdep->sizeof_gregset = 20 * 4; + + tdep->fpregset = XMALLOC (struct regset); + tdep->fpregset->supply_regset = sparc32nbsd_supply_fpregset; + tdep->sizeof_fpregset = 33 * 4; + + set_gdbarch_pc_in_sigtramp (gdbarch, sparc32nbsd_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer); +} + +static void +sparc32nbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + sparc32nbsd_init_abi (info, gdbarch); + + set_gdbarch_in_solib_call_trampoline + (gdbarch, sparcnbsd_aout_in_solib_call_trampoline); +} + +static void +sparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + sparc32nbsd_init_abi (info, gdbarch); + + set_solib_svr4_fetch_link_map_offsets + (gdbarch, nbsd_ilp32_solib_svr4_fetch_link_map_offsets); +} + +static enum gdb_osabi +sparcnbsd_aout_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0) + return GDB_OSABI_NETBSD_AOUT; + + return GDB_OSABI_UNKNOWN; +} + +/* OpenBSD uses the traditional NetBSD core file format, even for + ports that use ELF. Therefore, if the default OS ABI is OpenBSD + ELF, we return that instead of NetBSD a.out. This is mainly for + the benfit of OpenBSD/sparc64, which inherits the sniffer below + since we include this file for an OpenBSD/sparc64 target. For + OpenBSD/sparc, the NetBSD a.out OS ABI is probably similar enough + to both the OpenBSD a.out and the OpenBSD ELF OS ABI. */ +#if defined (GDB_OSABI_DEFAULT) && (GDB_OSABI_DEFAULT == GDB_OSABI_OPENBSD_ELF) +#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF +#else +#define GDB_OSABI_NETBSD_CORE GDB_OSABI_NETBSD_AOUT +#endif + +static enum gdb_osabi +sparcnbsd_core_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) + return GDB_OSABI_NETBSD_CORE; + + return GDB_OSABI_UNKNOWN; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparcnbsd_tdep (void); + +void +_initialize_sparnbsd_tdep (void) +{ + gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour, + sparcnbsd_aout_osabi_sniffer); + + /* BFD doesn't set the architecture for NetBSD style a.out core + files. */ + gdbarch_register_osabi_sniffer (bfd_arch_unknown, bfd_target_unknown_flavour, + sparcnbsd_core_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_AOUT, + sparc32nbsd_aout_init_abi); + gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_ELF, + sparc32nbsd_elf_init_abi); +} diff --git a/contrib/gdb/gdb/sparcobsd-tdep.c b/contrib/gdb/gdb/sparcobsd-tdep.c new file mode 100644 index 00000000000..108e255ed13 --- /dev/null +++ b/contrib/gdb/gdb/sparcobsd-tdep.c @@ -0,0 +1,171 @@ +/* Target-dependent code for OpenBSD/sparc. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "floatformat.h" +#include "frame.h" +#include "frame-unwind.h" +#include "osabi.h" +#include "solib-svr4.h" +#include "symtab.h" +#include "trad-frame.h" + +#include "gdb_assert.h" + +#include "sparc-tdep.h" +#include "nbsd-tdep.h" + +/* Signal trampolines. */ + +/* The OpenBSD kernel maps the signal trampoline at some random + location in user space, which means that the traditional BSD way of + detecting it won't work. + + The signal trampoline will be mapped at an address that is page + aligned. We recognize the signal trampoline by the looking for the + sigreturn system call. */ + +static const int sparc32obsd_page_size = 4096; + +static int +sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1)); + unsigned long insn; + + if (name) + return 0; + + /* Check for "restore %g0, SYS_sigreturn, %g1". */ + insn = sparc_fetch_instruction (start_pc + 0xec); + if (insn != 0x83e82067) + return 0; + + /* Check for "t ST_SYSCALL". */ + insn = sparc_fetch_instruction (start_pc + 0xf4); + if (insn != 0x91d02000) + return 0; + + return 1; +} + +static struct sparc_frame_cache * +sparc32obsd_frame_cache (struct frame_info *next_frame, void **this_cache) +{ + struct sparc_frame_cache *cache; + CORE_ADDR addr; + + if (*this_cache) + return *this_cache; + + cache = sparc_frame_cache (next_frame, this_cache); + gdb_assert (cache == *this_cache); + + /* If we couldn't find the frame's function, we're probably dealing + with an on-stack signal trampoline. */ + if (cache->pc == 0) + { + cache->pc = frame_pc_unwind (next_frame); + cache->pc &= ~(sparc32obsd_page_size - 1); + + /* Since we couldn't find the frame's function, the cache was + initialized under the assumption that we're frameless. */ + cache->frameless_p = 0; + addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); + cache->base = addr; + } + + cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (next_frame); + + return cache; +} + +static void +sparc32obsd_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct sparc_frame_cache *cache = + sparc32obsd_frame_cache (next_frame, this_cache); + + (*this_id) = frame_id_build (cache->base, cache->pc); +} + +static void +sparc32obsd_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct sparc_frame_cache *cache = + sparc32obsd_frame_cache (next_frame, this_cache); + + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} + +static const struct frame_unwind sparc32obsd_frame_unwind = +{ + SIGTRAMP_FRAME, + sparc32obsd_frame_this_id, + sparc32obsd_frame_prev_register +}; + +static const struct frame_unwind * +sparc32obsd_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (sparc32obsd_pc_in_sigtramp (pc, name)) + return &sparc32obsd_frame_unwind; + + return NULL; +} + + +static void +sparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* OpenBSD doesn't support the 128-bit `long double' from the psABI. */ + set_gdbarch_long_double_bit (gdbarch, 64); + set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); + + set_gdbarch_pc_in_sigtramp (gdbarch, sparc32obsd_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, sparc32obsd_sigtramp_frame_sniffer); + + set_solib_svr4_fetch_link_map_offsets + (gdbarch, nbsd_ilp32_solib_svr4_fetch_link_map_offsets); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc32obsd_tdep (void); + +void +_initialize_sparc32obsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD_ELF, + sparc32obsd_init_abi); +} diff --git a/contrib/gdb/gdb/srec.h b/contrib/gdb/gdb/srec.h new file mode 100644 index 00000000000..8189a9b95ec --- /dev/null +++ b/contrib/gdb/gdb/srec.h @@ -0,0 +1,39 @@ +/* S-record download support for GDB, the GNU debugger. + Copyright 1995, 1996, 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +struct serial; + +void load_srec (struct serial *desc, const char *file, bfd_vma load_offset, + int maxrecsize, int flags, int hashmark, + int (*waitack) (void)); + +/* S-record capability flags */ + +/* Which record types are supported */ +#define SREC_2_BYTE_ADDR 0x00000001 +#define SREC_3_BYTE_ADDR 0x00000002 +#define SREC_4_BYTE_ADDR 0x00000004 +#define SREC_TERM_SHIFT 3 + +#define SREC_ALL (SREC_2_BYTE_ADDR | SREC_3_BYTE_ADDR | SREC_4_BYTE_ADDR \ + | ((SREC_2_BYTE_ADDR | SREC_3_BYTE_ADDR | SREC_4_BYTE_ADDR) \ + << SREC_TERM_SHIFT)) + +#define SREC_BINARY 0x00000040 /* Supports binary form of S-records */ diff --git a/contrib/gdb/gdb/stabsread.c b/contrib/gdb/gdb/stabsread.c index 5b115467538..5cee516bcb3 100644 --- a/contrib/gdb/gdb/stabsread.c +++ b/contrib/gdb/gdb/stabsread.c @@ -1,7 +1,8 @@ /* Support routines for decoding "stabs" debugging information format. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -29,7 +30,7 @@ #include "defs.h" #include "gdb_string.h" #include "bfd.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" @@ -44,6 +45,8 @@ #include "demangle.h" #include "language.h" #include "doublest.h" +#include "cp-abi.h" +#include "cp-support.h" #include @@ -87,8 +90,6 @@ static void read_one_struct_field (struct field_info *, char **, char *, struct type *, struct objfile *); -static char *get_substring (char **, int); - static struct type *dbx_alloc_type (int[2], struct objfile *); static long read_huge_number (char **, int, int *); @@ -103,6 +104,8 @@ static void fix_common_block (struct symbol *, int); static int read_type_number (char **, int *); +static struct type *read_type (char **, struct objfile *); + static struct type *read_range_type (char **, int[2], struct objfile *); static struct type *read_sun_builtin_type (char **, int[2], struct objfile *); @@ -132,60 +135,32 @@ read_tilde_fields (struct field_info *, char **, struct type *, static int attach_fn_fields_to_type (struct field_info *, struct type *); -static int -attach_fields_to_type (struct field_info *, struct type *, struct objfile *); +static int attach_fields_to_type (struct field_info *, struct type *, + struct objfile *); static struct type *read_struct_type (char **, struct type *, + enum type_code, struct objfile *); static struct type *read_array_type (char **, struct type *, struct objfile *); -static struct type **read_args (char **, int, struct objfile *); +static struct field *read_args (char **, int, struct objfile *, int *, int *); + +static void add_undefined_type (struct type *); static int read_cpp_abbrev (struct field_info *, char **, struct type *, struct objfile *); -/* new functions added for cfront support */ - -static int -copy_cfront_struct_fields (struct field_info *, struct type *, - struct objfile *); - -static char *get_cfront_method_physname (char *); - -static int -read_cfront_baseclasses (struct field_info *, char **, - struct type *, struct objfile *); - -static int -read_cfront_static_fields (struct field_info *, char **, - struct type *, struct objfile *); -static int -read_cfront_member_functions (struct field_info *, char **, - struct type *, struct objfile *); - -/* end new functions added for cfront support */ - -static void -add_live_range (struct objfile *, struct symbol *, CORE_ADDR, CORE_ADDR); - -static int resolve_live_range (struct objfile *, struct symbol *, char *); +static char *find_name_end (char *name); static int process_reference (char **string); -static CORE_ADDR ref_search_value (int refnum); - -static int -resolve_symbol_reference (struct objfile *, struct symbol *, char *); - void stabsread_clear_cache (void); -static const char vptr_name[] = -{'_', 'v', 'p', 't', 'r', CPLUS_MARKER, '\0'}; -static const char vb_name[] = -{'_', 'v', 'b', CPLUS_MARKER, '\0'}; +static const char vptr_name[] = "_vptr$"; +static const char vb_name[] = "_vb$"; /* Define this as 1 if a pcc declaration of a char or short argument gives the correct address. Otherwise assume pcc gives the @@ -195,51 +170,26 @@ static const char vb_name[] = #if !defined (BELIEVE_PCC_PROMOTION) #define BELIEVE_PCC_PROMOTION 0 #endif -#if !defined (BELIEVE_PCC_PROMOTION_TYPE) -#define BELIEVE_PCC_PROMOTION_TYPE 0 -#endif -static struct complaint invalid_cpp_abbrev_complaint = -{"invalid C++ abbreviation `%s'", 0, 0}; +static void +invalid_cpp_abbrev_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "invalid C++ abbreviation `%s'", arg1); +} -static struct complaint invalid_cpp_type_complaint = -{"C++ abbreviated type name unknown at symtab pos %d", 0, 0}; +static void +reg_value_complaint (int arg1, int arg2, const char *arg3) +{ + complaint (&symfile_complaints, + "register number %d too large (max %d) in symbol %s", arg1, arg2, + arg3); +} -static struct complaint member_fn_complaint = -{"member function type missing, got '%c'", 0, 0}; - -static struct complaint const_vol_complaint = -{"const/volatile indicator missing, got '%c'", 0, 0}; - -static struct complaint error_type_complaint = -{"couldn't parse type; debugger out of date?", 0, 0}; - -static struct complaint invalid_member_complaint = -{"invalid (minimal) member type data format at symtab pos %d.", 0, 0}; - -static struct complaint range_type_base_complaint = -{"base type %d of range type is not defined", 0, 0}; - -static struct complaint reg_value_complaint = -{"register number %d too large (max %d) in symbol %s", 0, 0}; - -static struct complaint vtbl_notfound_complaint = -{"virtual function table pointer not found when defining class `%s'", 0, 0}; - -static struct complaint unrecognized_cplus_name_complaint = -{"Unknown C++ symbol name `%s'", 0, 0}; - -static struct complaint rs6000_builtin_complaint = -{"Unknown builtin type %d", 0, 0}; - -static struct complaint unresolved_sym_chain_complaint = -{"%s: common block `%s' from global_sym_chain unresolved", 0, 0}; - -static struct complaint stabs_general_complaint = -{"%s", 0, 0}; - -static struct complaint lrs_general_complaint = -{"%s", 0, 0}; +static void +stabs_general_complaint (const char *arg1) +{ + complaint (&symfile_complaints, "%s", arg1); +} /* Make a list of forward references which haven't been defined. */ @@ -255,34 +205,6 @@ static struct symbol *current_symbol = NULL; *(pp) = next_symbol_text (objfile); \ } while (0) -/* FIXME: These probably should be our own types (like rs6000_builtin_type - has its own types) rather than builtin_type_*. */ -static struct type **os9k_type_vector[] = -{ - 0, - &builtin_type_int, - &builtin_type_char, - &builtin_type_long, - &builtin_type_short, - &builtin_type_unsigned_char, - &builtin_type_unsigned_short, - &builtin_type_unsigned_long, - &builtin_type_unsigned_int, - &builtin_type_float, - &builtin_type_double, - &builtin_type_void, - &builtin_type_long_double -}; - -static void os9k_init_type_vector (struct type **); - -static void -os9k_init_type_vector (struct type **tv) -{ - unsigned int i; - for (i = 0; i < sizeof (os9k_type_vector) / sizeof (struct type **); i++) - tv[i] = (os9k_type_vector[i] == 0 ? 0 : *(os9k_type_vector[i])); -} /* Look up a dbx type-number pair. Return the address of the slot where the type for that number-pair is stored. @@ -291,14 +213,14 @@ os9k_init_type_vector (struct type **tv) This can be used for finding the type associated with that pair or for associating a new type with the pair. */ -struct type ** +static struct type ** dbx_lookup_type (int typenums[2]) { - register int filenum = typenums[0]; - register int index = typenums[1]; + int filenum = typenums[0]; + int index = typenums[1]; unsigned old_len; - register int real_filenum; - register struct header_file *f; + int real_filenum; + struct header_file *f; int f_orig_length; if (filenum == -1) /* -1,-1 is for temporary types. */ @@ -306,11 +228,9 @@ dbx_lookup_type (int typenums[2]) if (filenum < 0 || filenum >= n_this_object_header_files) { - static struct complaint msg = - {"\ -Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", - 0, 0}; - complain (&msg, filenum, index, symnum); + complaint (&symfile_complaints, + "Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", + filenum, index, symnum); goto error_return; } @@ -349,10 +269,6 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", (type_vector_length * sizeof (struct type *))); memset (&type_vector[old_len], 0, (type_vector_length - old_len) * sizeof (struct type *)); - - if (os9k_stabs) - /* Deal with OS9000 fundamental types. */ - os9k_init_type_vector (type_vector); } return (&type_vector[index]); } @@ -401,7 +317,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", static struct type * dbx_alloc_type (int typenums[2], struct objfile *objfile) { - register struct type **type_addr; + struct type **type_addr; if (typenums[0] == -1) { @@ -463,14 +379,14 @@ patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs, ld will remove it from the executable. There is then a N_GSYM stab for it, but no regular (C_EXT) symbol. */ sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - SYMBOL_NAME (sym) = - obsavestring (name, pp - name, &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = + obsavestring (name, pp - name, &objfile->objfile_obstack); pp += 2; if (*(pp - 1) == 'F' || *(pp - 1) == 'f') { @@ -513,7 +429,7 @@ patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs, Returns 0 for success, -1 for error. */ static int -read_type_number (register char **pp, register int *typenums) +read_type_number (char **pp, int *typenums) { int nbits; if (**pp == '(') @@ -542,596 +458,6 @@ read_type_number (register char **pp, register int *typenums) #define VISIBILITY_PUBLIC '2' /* Stabs character for public field */ #define VISIBILITY_IGNORE '9' /* Optimized out or zero length */ -#define CFRONT_VISIBILITY_PRIVATE '2' /* Stabs character for private field */ -#define CFRONT_VISIBILITY_PUBLIC '1' /* Stabs character for public field */ - -/* This code added to support parsing of ARM/Cfront stabs strings */ - -/* Get substring from string up to char c, advance string pointer past - suibstring. */ - -static char * -get_substring (char **p, int c) -{ - char *str; - str = *p; - *p = strchr (*p, c); - if (*p) - { - **p = 0; - (*p)++; - } - else - str = 0; - return str; -} - -/* Physname gets strcat'd onto sname in order to recreate the mangled - name (see funtion gdb_mangle_name in gdbtypes.c). For cfront, make - the physname look like that of g++ - take out the initial mangling - eg: for sname="a" and fname="foo__1aFPFs_i" return "FPFs_i" */ - -static char * -get_cfront_method_physname (char *fname) -{ - int len = 0; - /* FIXME would like to make this generic for g++ too, but - that is already handled in read_member_funcctions */ - char *p = fname; - - /* search ahead to find the start of the mangled suffix */ - if (*p == '_' && *(p + 1) == '_') /* compiler generated; probably a ctor/dtor */ - p += 2; - while (p && (unsigned) ((p + 1) - fname) < strlen (fname) && *(p + 1) != '_') - p = strchr (p, '_'); - if (!(p && *p == '_' && *(p + 1) == '_')) - error ("Invalid mangled function name %s", fname); - p += 2; /* advance past '__' */ - - /* struct name length and name of type should come next; advance past it */ - while (isdigit (*p)) - { - len = len * 10 + (*p - '0'); - p++; - } - p += len; - - return p; -} - -/* Read base classes within cfront class definition. - eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; - ^^^^^^^^^^^^^^^^^^ - - A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; - ^ - */ - -static int -read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type, - struct objfile *objfile) -{ - static struct complaint msg_unknown = - {"\ - Unsupported token in stabs string %s.\n", - 0, 0}; - static struct complaint msg_notfound = - {"\ - Unable to find base type for %s.\n", - 0, 0}; - int bnum = 0; - char *p; - int i; - struct nextfield *new; - - if (**pp == ';') /* no base classes; return */ - { - ++(*pp); - return 1; - } - - /* first count base classes so we can allocate space before parsing */ - for (p = *pp; p && *p && *p != ';'; p++) - { - if (*p == ' ') - bnum++; - } - bnum++; /* add one more for last one */ - - /* now parse the base classes until we get to the start of the methods - (code extracted and munged from read_baseclasses) */ - ALLOCATE_CPLUS_STRUCT_TYPE (type); - TYPE_N_BASECLASSES (type) = bnum; - - /* allocate space */ - { - int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type)); - char *pointer; - - pointer = (char *) TYPE_ALLOC (type, num_bytes); - TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer; - } - B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type)); - - for (i = 0; i < TYPE_N_BASECLASSES (type); i++) - { - new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (xfree, new); - memset (new, 0, sizeof (struct nextfield)); - new->next = fip->list; - fip->list = new; - FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */ - - STABS_CONTINUE (pp, objfile); - - /* virtual? eg: v2@Bvir */ - if (**pp == 'v') - { - SET_TYPE_FIELD_VIRTUAL (type, i); - ++(*pp); - } - - /* access? eg: 2@Bvir */ - /* Note: protected inheritance not supported in cfront */ - switch (*(*pp)++) - { - case CFRONT_VISIBILITY_PRIVATE: - new->visibility = VISIBILITY_PRIVATE; - break; - case CFRONT_VISIBILITY_PUBLIC: - new->visibility = VISIBILITY_PUBLIC; - break; - default: - /* Bad visibility format. Complain and treat it as - public. */ - { - static struct complaint msg = - { - "Unknown visibility `%c' for baseclass", 0, 0}; - complain (&msg, new->visibility); - new->visibility = VISIBILITY_PUBLIC; - } - } - - /* "@" comes next - eg: @Bvir */ - if (**pp != '@') - { - complain (&msg_unknown, *pp); - return 1; - } - ++(*pp); - - - /* Set the bit offset of the portion of the object corresponding - to this baseclass. Always zero in the absence of - multiple inheritance. */ - /* Unable to read bit position from stabs; - Assuming no multiple inheritance for now FIXME! */ - /* We may have read this in the structure definition; - now we should fixup the members to be the actual base classes */ - FIELD_BITPOS (new->field) = 0; - - /* Get the base class name and type */ - { - char *bname; /* base class name */ - struct symbol *bsym; /* base class */ - char *p1, *p2; - p1 = strchr (*pp, ' '); - p2 = strchr (*pp, ';'); - if (p1 < p2) - bname = get_substring (pp, ' '); - else - bname = get_substring (pp, ';'); - if (!bname || !*bname) - { - complain (&msg_unknown, *pp); - return 1; - } - /* FIXME! attach base info to type */ - bsym = lookup_symbol (bname, 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name */ - if (bsym) - { - new->field.type = SYMBOL_TYPE (bsym); - new->field.name = type_name_no_tag (new->field.type); - } - else - { - complain (&msg_notfound, *pp); - return 1; - } - } - - /* If more base classes to parse, loop again. - We ate the last ' ' or ';' in get_substring, - so on exit we will have skipped the trailing ';' */ - /* if invalid, return 0; add code to detect - FIXME! */ - } - return 1; -} - -/* read cfront member functions. - pp points to string starting with list of functions - eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - */ - -static int -read_cfront_member_functions (struct field_info *fip, char **pp, - struct type *type, struct objfile *objfile) -{ - /* This code extracted from read_member_functions - so as to do the similar thing for our funcs */ - - int nfn_fields = 0; - int length = 0; - /* Total number of member functions defined in this class. If the class - defines two `f' functions, and one `g' function, then this will have - the value 3. */ - int total_length = 0; - int i; - struct next_fnfield - { - struct next_fnfield *next; - struct fn_field fn_field; - } - *sublist; - struct type *look_ahead_type; - struct next_fnfieldlist *new_fnlist; - struct next_fnfield *new_sublist; - char *main_fn_name; - char *fname; - struct symbol *ref_func = 0; - - /* Process each list until we find the end of the member functions. - eg: p = "__ct__1AFv foo__1AFv ;;;" */ - - STABS_CONTINUE (pp, objfile); /* handle \\ */ - - while (**pp != ';' && (fname = get_substring (pp, ' '), fname)) - { - int is_static = 0; - int sublist_count = 0; - char *pname; - if (fname[0] == '*') /* static member */ - { - is_static = 1; - sublist_count++; - fname++; - } - ref_func = lookup_symbol (fname, 0, VAR_NAMESPACE, 0, 0); /* demangled name */ - if (!ref_func) - { - static struct complaint msg = - {"\ - Unable to find function symbol for %s\n", - 0, 0}; - complain (&msg, fname); - continue; - } - sublist = NULL; - look_ahead_type = NULL; - length = 0; - - new_fnlist = (struct next_fnfieldlist *) - xmalloc (sizeof (struct next_fnfieldlist)); - make_cleanup (xfree, new_fnlist); - memset (new_fnlist, 0, sizeof (struct next_fnfieldlist)); - - /* The following is code to work around cfront generated stabs. - The stabs contains full mangled name for each field. - We try to demangle the name and extract the field name out of it. */ - { - char *dem, *dem_p, *dem_args; - int dem_len; - dem = cplus_demangle (fname, DMGL_ANSI | DMGL_PARAMS); - if (dem != NULL) - { - dem_p = strrchr (dem, ':'); - if (dem_p != 0 && *(dem_p - 1) == ':') - dem_p++; - /* get rid of args */ - dem_args = strchr (dem_p, '('); - if (dem_args == NULL) - dem_len = strlen (dem_p); - else - dem_len = dem_args - dem_p; - main_fn_name = - obsavestring (dem_p, dem_len, &objfile->type_obstack); - } - else - { - main_fn_name = - obsavestring (fname, strlen (fname), &objfile->type_obstack); - } - } /* end of code for cfront work around */ - - new_fnlist->fn_fieldlist.name = main_fn_name; - -/*-------------------------------------------------*/ - /* Set up the sublists - Sublists are stuff like args, static, visibility, etc. - so in ARM, we have to set that info some other way. - Multiple sublists happen if overloading - eg: foo::26=##1;:;2A.; - In g++, we'd loop here thru all the sublists... */ - - new_sublist = - (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield)); - make_cleanup (xfree, new_sublist); - memset (new_sublist, 0, sizeof (struct next_fnfield)); - - /* eat 1; from :;2A.; */ - new_sublist->fn_field.type = SYMBOL_TYPE (ref_func); /* normally takes a read_type */ - /* Make this type look like a method stub for gdb */ - TYPE_FLAGS (new_sublist->fn_field.type) |= TYPE_FLAG_STUB; - TYPE_CODE (new_sublist->fn_field.type) = TYPE_CODE_METHOD; - - /* If this is just a stub, then we don't have the real name here. */ - if (TYPE_STUB (new_sublist->fn_field.type)) - { - if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type)) - TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type; - new_sublist->fn_field.is_stub = 1; - } - - /* physname used later in mangling; eg PFs_i,5 for foo__1aFPFs_i - physname gets strcat'd in order to recreate the onto mangled name */ - pname = get_cfront_method_physname (fname); - new_sublist->fn_field.physname = savestring (pname, strlen (pname)); - - - /* Set this member function's visibility fields. - Unable to distinguish access from stabs definition! - Assuming public for now. FIXME! - (for private, set new_sublist->fn_field.is_private = 1, - for public, set new_sublist->fn_field.is_protected = 1) */ - - /* Unable to distinguish const/volatile from stabs definition! - Assuming normal for now. FIXME! */ - - new_sublist->fn_field.is_const = 0; - new_sublist->fn_field.is_volatile = 0; /* volatile not implemented in cfront */ - - /* Set virtual/static function info - How to get vtable offsets ? - Assuming normal for now FIXME!! - For vtables, figure out from whence this virtual function came. - It may belong to virtual function table of - one of its baseclasses. - set: - new_sublist -> fn_field.voffset = vtable offset, - new_sublist -> fn_field.fcontext = look_ahead_type; - where look_ahead_type is type of baseclass */ - if (is_static) - new_sublist->fn_field.voffset = VOFFSET_STATIC; - else /* normal member function. */ - new_sublist->fn_field.voffset = 0; - new_sublist->fn_field.fcontext = 0; - - - /* Prepare new sublist */ - new_sublist->next = sublist; - sublist = new_sublist; - length++; - - /* In g++, we loop thu sublists - now we set from functions. */ - new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) - obstack_alloc (&objfile->type_obstack, - sizeof (struct fn_field) * length); - memset (new_fnlist->fn_fieldlist.fn_fields, 0, - sizeof (struct fn_field) * length); - for (i = length; (i--, sublist); sublist = sublist->next) - { - new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field; - } - - new_fnlist->fn_fieldlist.length = length; - new_fnlist->next = fip->fnlist; - fip->fnlist = new_fnlist; - nfn_fields++; - total_length += length; - STABS_CONTINUE (pp, objfile); /* handle \\ */ - } /* end of loop */ - - if (nfn_fields) - { - /* type should already have space */ - TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) - TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields); - memset (TYPE_FN_FIELDLISTS (type), 0, - sizeof (struct fn_fieldlist) * nfn_fields); - TYPE_NFN_FIELDS (type) = nfn_fields; - TYPE_NFN_FIELDS_TOTAL (type) = total_length; - } - - /* end of scope for reading member func */ - - /* eg: ";;" */ - - /* Skip trailing ';' and bump count of number of fields seen */ - if (**pp == ';') - (*pp)++; - else - return 0; - return 1; -} - -/* This routine fixes up partial cfront types that were created - while parsing the stabs. The main need for this function is - to add information such as methods to classes. - Examples of "p": "sA;;__ct__1AFv foo__1AFv ;;;" */ -int -resolve_cfront_continuation (struct objfile *objfile, struct symbol *sym, - char *p) -{ - struct symbol *ref_sym = 0; - char *sname; - /* snarfed from read_struct_type */ - struct field_info fi; - struct type *type; - struct cleanup *back_to; - - /* Need to make sure that fi isn't gunna conflict with struct - in case struct already had some fnfs */ - fi.list = NULL; - fi.fnlist = NULL; - back_to = make_cleanup (null_cleanup, 0); - - /* We only accept structs, classes and unions at the moment. - Other continuation types include t (typedef), r (long dbl), ... - We may want to add support for them as well; - right now they are handled by duplicating the symbol information - into the type information (see define_symbol) */ - if (*p != 's' /* structs */ - && *p != 'c' /* class */ - && *p != 'u') /* union */ - return 0; /* only handle C++ types */ - p++; - - /* Get symbol typs name and validate - eg: p = "A;;__ct__1AFv foo__1AFv ;;;" */ - sname = get_substring (&p, ';'); - if (!sname || strcmp (sname, SYMBOL_NAME (sym))) - error ("Internal error: base symbol type name does not match\n"); - - /* Find symbol's internal gdb reference using demangled_name. - This is the real sym that we want; - sym was a temp hack to make debugger happy */ - ref_sym = lookup_symbol (SYMBOL_NAME (sym), 0, STRUCT_NAMESPACE, 0, 0); - type = SYMBOL_TYPE (ref_sym); - - - /* Now read the baseclasses, if any, read the regular C struct or C++ - class member fields, attach the fields to the type, read the C++ - member functions, attach them to the type, and then read any tilde - field (baseclass specifier for the class holding the main vtable). */ - - if (!read_cfront_baseclasses (&fi, &p, type, objfile) - /* g++ does this next, but cfront already did this: - || !read_struct_fields (&fi, &p, type, objfile) */ - || !copy_cfront_struct_fields (&fi, type, objfile) - || !read_cfront_member_functions (&fi, &p, type, objfile) - || !read_cfront_static_fields (&fi, &p, type, objfile) - || !attach_fields_to_type (&fi, type, objfile) - || !attach_fn_fields_to_type (&fi, type) - /* g++ does this next, but cfront doesn't seem to have this: - || !read_tilde_fields (&fi, &p, type, objfile) */ - ) - { - type = error_type (&p, objfile); - } - - do_cleanups (back_to); - return 0; -} -/* End of code added to support parsing of ARM/Cfront stabs strings */ - - -/* This routine fixes up symbol references/aliases to point to the original - symbol definition. Returns 0 on failure, non-zero on success. */ - -static int -resolve_symbol_reference (struct objfile *objfile, struct symbol *sym, char *p) -{ - int refnum; - struct symbol *ref_sym = 0; - struct alias_list *alias; - - /* If this is not a symbol reference return now. */ - if (*p != '#') - return 0; - - /* Use "#" as the name; we'll fix the name later. - We stored the original symbol name as "#=" - so we can now search for "#" to resolving the reference. - We'll fix the names later by removing the "#" or "#=" */ - -/*---------------------------------------------------------*/ - /* Get the reference id number, and - advance p past the names so we can parse the rest. - eg: id=2 for p : "2=", "2=z:r(0,1)" "2:r(0,1);l(#5,#6),l(#7,#4)" */ -/*---------------------------------------------------------*/ - - /* This gets reference name from string. sym may not have a name. */ - - /* Get the reference number associated with the reference id in the - gdb stab string. From that reference number, get the main/primary - symbol for this alias. */ - refnum = process_reference (&p); - ref_sym = ref_search (refnum); - if (!ref_sym) - { - complain (&lrs_general_complaint, "symbol for reference not found"); - return 0; - } - - /* Parse the stab of the referencing symbol - now that we have the referenced symbol. - Add it as a new symbol and a link back to the referenced symbol. - eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */ - - - /* If the stab symbol table and string contain: - RSYM 0 5 00000000 868 #15=z:r(0,1) - LBRAC 0 0 00000000 899 #5= - SLINE 0 16 00000003 923 #6= - Then the same symbols can be later referenced by: - RSYM 0 5 00000000 927 #15:r(0,1);l(#5,#6) - This is used in live range splitting to: - 1) specify that a symbol (#15) is actually just a new storage - class for a symbol (#15=z) which was previously defined. - 2) specify that the beginning and ending ranges for a symbol - (#15) are the values of the beginning (#5) and ending (#6) - symbols. */ - - /* Read number as reference id. - eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */ - /* FIXME! Might I want to use SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - in case of "l(0,0)"? */ - -/*--------------------------------------------------*/ - /* Add this symbol to the reference list. */ -/*--------------------------------------------------*/ - - alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack, - sizeof (struct alias_list)); - if (!alias) - { - complain (&lrs_general_complaint, "Unable to allocate alias list memory"); - return 0; - } - - alias->next = 0; - alias->sym = sym; - - if (!SYMBOL_ALIASES (ref_sym)) - { - SYMBOL_ALIASES (ref_sym) = alias; - } - else - { - struct alias_list *temp; - - /* Get to the end of the list. */ - for (temp = SYMBOL_ALIASES (ref_sym); - temp->next; - temp = temp->next) - ; - temp->next = alias; - } - - /* Want to fix up name so that other functions (eg. valops) - will correctly print the name. - Don't add_symbol_to_list so that lookup_symbol won't find it. - nope... needed for fixups. */ - SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym); - - /* Done! */ - return 1; -} - /* Structure for storing pointers to reference definitions for fast lookup during "process_later". */ @@ -1198,16 +524,6 @@ ref_search (int refnum) return ref_map[refnum].sym; } -/* Return value for the reference REFNUM. */ - -static CORE_ADDR -ref_search_value (int refnum) -{ - if (refnum < 0 || refnum > ref_count) - return 0; - return ref_map[refnum].value; -} - /* Parse a reference id in STRING and return the resulting reference number. Move STRING beyond the reference id. */ @@ -1260,16 +576,15 @@ symbol_reference_defined (char **string) } } -/* ARGSUSED */ struct symbol * define_symbol (CORE_ADDR valu, char *string, int desc, int type, struct objfile *objfile) { - register struct symbol *sym; - char *p = (char *) strchr (string, ':'); + struct symbol *sym; + char *p = (char *) find_name_end (string); int deftype; int synonym = 0; - register int i; + int i; /* We would like to eliminate nameless symbols, but keep their types. E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer @@ -1297,7 +612,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, nameless = (p == string || ((string[0] == ' ') && (string[1] == ':'))); current_symbol = sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); switch (type & N_TYPE) @@ -1330,17 +645,17 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, switch (string[1]) { case 't': - SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"), - &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"), + &objfile->objfile_obstack); break; case 'v': /* $vtbl_ptr_type */ - /* Was: SYMBOL_NAME (sym) = "vptr"; */ + /* Was: DEPRECATED_SYMBOL_NAME (sym) = "vptr"; */ goto normal; case 'e': - SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"), - &objfile->symbol_obstack); + DEPRECATED_SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"), + &objfile->objfile_obstack); break; case '_': @@ -1354,82 +669,16 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, #endif default: - complain (&unrecognized_cplus_name_complaint, string); + complaint (&symfile_complaints, "Unknown C++ symbol name `%s'", + string); goto normal; /* Do *something* with it */ } } - else if (string[0] == '#') - { - /* Special GNU C extension for referencing symbols. */ - char *s; - int refnum, nlen; - - /* If STRING defines a new reference id, then add it to the - reference map. Else it must be referring to a previously - defined symbol, so add it to the alias list of the previously - defined symbol. */ - s = string; - refnum = symbol_reference_defined (&s); - if (refnum >= 0) - ref_add (refnum, sym, string, SYMBOL_VALUE (sym)); - else if (!resolve_symbol_reference (objfile, sym, string)) - return NULL; - - /* S..P contains the name of the symbol. We need to store - the correct name into SYMBOL_NAME. */ - nlen = p - s; - if (refnum >= 0) - { - if (nlen > 0) - { - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, nlen); - strncpy (SYMBOL_NAME (sym), s, nlen); - SYMBOL_NAME (sym)[nlen] = '\0'; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - } - else - /* FIXME! Want SYMBOL_NAME (sym) = 0; - Get error if leave name 0. So give it something. */ - { - nlen = p - string; - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, nlen); - strncpy (SYMBOL_NAME (sym), string, nlen); - SYMBOL_NAME (sym)[nlen] = '\0'; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - } - } - /* Advance STRING beyond the reference id. */ - string = s; - } else { normal: SYMBOL_LANGUAGE (sym) = current_subfile->language; - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, ((p - string) + 1)); - /* Open-coded memcpy--saves function call time. */ - /* FIXME: Does it really? Try replacing with simple strcpy and - try it on an executable with a large symbol table. */ - /* FIXME: considering that gcc can open code memcpy anyway, I - doubt it. xoxorich. */ - { - register char *p1 = string; - register char *p2 = SYMBOL_NAME (sym); - while (p1 != p) - { - *p2++ = *p1++; - } - *p2++ = '\0'; - } - - /* If this symbol is from a C++ compilation, then attempt to cache the - demangled form for future reference. This is a typical time versus - space tradeoff, that was decided in favor of time because it sped up - C++ symbol lookups by a factor of about 20. */ - - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, string, p - string, objfile); } p++; @@ -1463,7 +712,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, { SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_TYPE (sym) = error_type (&p, objfile); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); return sym; } @@ -1489,7 +738,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile, FT_DBL_PREC_FLOAT); dbl_valu = (char *) - obstack_alloc (&objfile->symbol_obstack, + obstack_alloc (&objfile->objfile_obstack, TYPE_LENGTH (SYMBOL_TYPE (sym))); store_typed_floating (dbl_valu, SYMBOL_TYPE (sym), d); SYMBOL_VALUE_BYTES (sym) = dbl_valu; @@ -1556,7 +805,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = error_type (&p, objfile); } } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); return sym; @@ -1564,7 +813,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* The name of a caught exception. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_LABEL; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_VALUE_ADDRESS (sym) = valu; add_symbol_to_list (sym, &local_symbols); break; @@ -1573,7 +822,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* A static function definition. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); /* fall into process_function_types. */ @@ -1584,9 +833,13 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC) SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); - /* All functions in C++ have prototypes. */ - if (SYMBOL_LANGUAGE (sym) == language_cplus) - TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED; + /* All functions in C++ have prototypes. Stabs does not offer an + explicit way to identify prototyped or unprototyped functions, + but both GCC and Sun CC emit stabs for the "call-as" type rather + than the "declared-as" type for unprototyped functions, so + we treat all functions as if they were prototyped. This is used + primarily for promotion when calling the function from GDB. */ + TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED; /* fall into process_prototype_types */ @@ -1640,7 +893,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* A global function definition. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &global_symbols); goto process_function_types; @@ -1651,14 +904,14 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, These definitions appear at the end of the namelist. */ SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; /* Don't add symbol references to global_sym_chain. Symbol references don't have valid names and wont't match up with minimal symbols when the global_sym_chain is relocated. We'll fixup symbol references when we fixup the defining symbol. */ - if (SYMBOL_NAME (sym) && SYMBOL_NAME (sym)[0] != '#') + if (DEPRECATED_SYMBOL_NAME (sym) && DEPRECATED_SYMBOL_NAME (sym)[0] != '#') { - i = hashname (SYMBOL_NAME (sym)); + i = hashname (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i]; global_sym_chain[i] = sym; } @@ -1673,7 +926,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_LOCAL; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -1691,15 +944,9 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, else SYMBOL_TYPE (sym) = read_type (&p, objfile); - /* Normally this is a parameter, a LOC_ARG. On the i960, it - can also be a LOC_LOCAL_ARG depending on symbol type. */ -#ifndef DBX_PARM_SYMBOL_CLASS -#define DBX_PARM_SYMBOL_CLASS(type) LOC_ARG -#endif - - SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type); + SYMBOL_CLASS (sym) = LOC_ARG; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG) @@ -1806,12 +1053,12 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), - NUM_REGS + NUM_PSEUDO_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_PRINT_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -1822,25 +1069,28 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), - NUM_REGS + NUM_PSEUDO_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_PRINT_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; if (within_function) { - /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same - name to represent an argument passed in a register. - GCC uses 'P' for the same case. So if we find such a symbol pair - we combine it into one 'P' symbol. For Sun cc we need to do this - regardless of REG_STRUCT_HAS_ADDR, because the compiler puts out - the 'p' symbol even if it never saves the argument onto the stack. + /* Sun cc uses a pair of symbols, one 'p' and one 'r', with + the same name to represent an argument passed in a + register. GCC uses 'P' for the same case. So if we find + such a symbol pair we combine it into one 'P' symbol. + For Sun cc we need to do this regardless of + stabs_argument_has_addr, because the compiler puts out + the 'p' symbol even if it never saves the argument onto + the stack. - On most machines, we want to preserve both symbols, so that - we can still get information about what is going on with the - stack (VAX for computing args_printed, using stack slots instead - of saved registers in backtraces, etc.). + On most machines, we want to preserve both symbols, so + that we can still get information about what is going on + with the stack (VAX for computing args_printed, using + stack slots instead of saved registers in backtraces, + etc.). Note that this code illegally combines main(argc) struct foo argc; { register struct foo argc; } @@ -1849,22 +1099,15 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, if (local_symbols && local_symbols->nsyms > 0 -#ifndef USE_REGISTER_NOT_ARG - && REG_STRUCT_HAS_ADDR_P () - && REG_STRUCT_HAS_ADDR (processing_gcc_compilation, - SYMBOL_TYPE (sym)) - && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_SET - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_BITSTRING) -#endif - ) + && gdbarch_stabs_argument_has_addr (current_gdbarch, + SYMBOL_TYPE (sym))) { struct symbol *prev_sym; prev_sym = local_symbols->symbol[local_symbols->nsyms - 1]; if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG || SYMBOL_CLASS (prev_sym) == LOC_ARG) - && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME (sym))) + && strcmp (DEPRECATED_SYMBOL_NAME (prev_sym), + DEPRECATED_SYMBOL_NAME (sym)) == 0) { SYMBOL_CLASS (prev_sym) = LOC_REGPARM; /* Use the type from the LOC_REGISTER; that is the type @@ -1887,22 +1130,23 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; #ifdef STATIC_TRANSFORM_NAME - if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym))) + if (IS_STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym))) { struct minimal_symbol *msym; - msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile); + msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, objfile); if (msym != NULL) { - SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)); + DEPRECATED_SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym); } } #endif - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); break; case 't': + /* Typedef */ SYMBOL_TYPE (sym) = read_type (&p, objfile); /* For a nameless type, we don't want a create a symbol, thus we @@ -1912,7 +1156,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; /* C++ vagaries: we may have a type which is derived from a base type which did not have its name defined when the derived class was output. We fill in the derived class's @@ -1937,7 +1181,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, extern const char vtbl_ptr_name[]; if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR - && strcmp (SYMBOL_NAME (sym), vtbl_ptr_name)) + && strcmp (DEPRECATED_SYMBOL_NAME (sym), vtbl_ptr_name)) || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC) { /* If we are giving a name to a type such as "pointer to @@ -1977,11 +1221,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, /* Pascal accepts names for pointer types. */ if (current_subfile->language == language_pascal) { - TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NAME (sym); + TYPE_NAME (SYMBOL_TYPE (sym)) = DEPRECATED_SYMBOL_NAME (sym); } } else - TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NAME (sym); + TYPE_NAME (SYMBOL_TYPE (sym)) = DEPRECATED_SYMBOL_NAME (sym); } add_symbol_to_list (sym, &file_symbols); @@ -1994,15 +1238,9 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, if (synonym) p++; - /* The semantics of C++ state that "struct foo { ... }" also defines - a typedef for "foo". Unfortunately, cfront never makes the typedef - when translating C++ into C. We make the typedef here so that - "ptype foo" works as expected for cfront translated code. */ - else if (current_subfile->language == language_cplus) - synonym = 1; SYMBOL_TYPE (sym) = read_type (&p, objfile); - + /* For a nameless type, we don't want a create a symbol, thus we did not use `sym'. Return without further processing. */ if (nameless) @@ -2010,24 +1248,24 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0) TYPE_TAG_NAME (SYMBOL_TYPE (sym)) - = obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym)); + = obconcat (&objfile->objfile_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym)); add_symbol_to_list (sym, &file_symbols); if (synonym) { /* Clone the sym and then modify it. */ - register struct symbol *typedef_sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + struct symbol *typedef_sym = (struct symbol *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); *typedef_sym = *sym; SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF; SYMBOL_VALUE (typedef_sym) = valu; - SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN; if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) - = obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym)); + = obconcat (&objfile->objfile_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym)); add_symbol_to_list (typedef_sym, &file_symbols); } break; @@ -2038,21 +1276,18 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; #ifdef STATIC_TRANSFORM_NAME - if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym))) + if (IS_STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym))) { struct minimal_symbol *msym; - msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile); + msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, objfile); if (msym != NULL) { - SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)); + DEPRECATED_SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym); } } #endif - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (os9k_stabs) - add_symbol_to_list (sym, &global_symbols); - else + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -2061,7 +1296,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_REF_ARG; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -2072,12 +1307,12 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS) { - complain (®_value_complaint, SYMBOL_VALUE (sym), - NUM_REGS + NUM_PSEUDO_REGS, - SYMBOL_SOURCE_NAME (sym)); + reg_value_complaint (SYMBOL_VALUE (sym), + NUM_REGS + NUM_PSEUDO_REGS, + SYMBOL_PRINT_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; @@ -2089,199 +1324,39 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, SYMBOL_TYPE (sym) = read_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_LOCAL; SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &local_symbols); break; - /* New code added to support cfront stabs strings. - Note: case 'P' already handled above */ - case 'Z': - /* Cfront type continuation coming up! - Find the original definition and add to it. - We'll have to do this for the typedef too, - since we cloned the symbol to define a type in read_type. - Stabs info examples: - __1C :Ztl - foo__1CFv :ZtF (first def foo__1CFv:F(0,3);(0,24)) - C:ZsC;;__ct__1CFv func1__1CFv func2__1CFv ... ;;; - where C is the name of the class. - Unfortunately, we can't lookup the original symbol yet 'cuz - we haven't finished reading all the symbols. - Instead, we save it for processing later */ - process_later (sym, p, resolve_cfront_continuation); - SYMBOL_TYPE (sym) = error_type (&p, objfile); /* FIXME! change later */ - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_VALUE (sym) = 0; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - /* Don't add to list - we'll delete it later when - we add the continuation to the real sym */ - return sym; - /* End of new code added to support cfront stabs strings */ - default: SYMBOL_TYPE (sym) = error_type (&p, objfile); SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_VALUE (sym) = 0; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; add_symbol_to_list (sym, &file_symbols); break; } - /* When passing structures to a function, some systems sometimes pass - the address in a register, not the structure itself. */ + /* Some systems pass variables of certain types by reference instead + of by value, i.e. they will pass the address of a structure (in a + register or on the stack) instead of the structure itself. */ - if (REG_STRUCT_HAS_ADDR_P () - && REG_STRUCT_HAS_ADDR (processing_gcc_compilation, SYMBOL_TYPE (sym)) + if (gdbarch_stabs_argument_has_addr (current_gdbarch, SYMBOL_TYPE (sym)) && (SYMBOL_CLASS (sym) == LOC_REGPARM || SYMBOL_CLASS (sym) == LOC_ARG)) { - struct type *symbol_type = check_typedef (SYMBOL_TYPE (sym)); - - if ((TYPE_CODE (symbol_type) == TYPE_CODE_STRUCT) - || (TYPE_CODE (symbol_type) == TYPE_CODE_UNION) - || (TYPE_CODE (symbol_type) == TYPE_CODE_BITSTRING) - || (TYPE_CODE (symbol_type) == TYPE_CODE_SET)) - { - /* If REG_STRUCT_HAS_ADDR yields non-zero we have to convert - LOC_REGPARM to LOC_REGPARM_ADDR for structures and unions. */ - if (SYMBOL_CLASS (sym) == LOC_REGPARM) - SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; - /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th - and subsequent arguments on the sparc, for example). */ - else if (SYMBOL_CLASS (sym) == LOC_ARG) - SYMBOL_CLASS (sym) = LOC_REF_ARG; - } + /* We have to convert LOC_REGPARM to LOC_REGPARM_ADDR (for + variables passed in a register). */ + if (SYMBOL_CLASS (sym) == LOC_REGPARM) + SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR; + /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th + and subsequent arguments on SPARC, for example). */ + else if (SYMBOL_CLASS (sym) == LOC_ARG) + SYMBOL_CLASS (sym) = LOC_REF_ARG; } - /* Is there more to parse? For example LRS/alias information? */ - while (*p && *p == ';') - { - p++; - if (*p && p[0] == 'l' && p[1] == '(') - { - /* GNU extensions for live range splitting may be appended to - the end of the stab string. eg. "l(#1,#2);l(#3,#5)" */ - - /* Resolve the live range and add it to SYM's live range list. */ - if (!resolve_live_range (objfile, sym, p)) - return NULL; - - /* Find end of live range info. */ - p = strchr (p, ')'); - if (!*p || *p != ')') - { - complain (&lrs_general_complaint, "live range format not recognized"); - return NULL; - } - p++; - } - } return sym; } -/* Add the live range found in P to the symbol SYM in objfile OBJFILE. Returns - non-zero on success, zero otherwise. */ - -static int -resolve_live_range (struct objfile *objfile, struct symbol *sym, char *p) -{ - int refnum; - CORE_ADDR start, end; - - /* Sanity check the beginning of the stabs string. */ - if (!*p || *p != 'l') - { - complain (&lrs_general_complaint, "live range string 1"); - return 0; - } - p++; - - if (!*p || *p != '(') - { - complain (&lrs_general_complaint, "live range string 2"); - return 0; - } - p++; - - /* Get starting value of range and advance P past the reference id. - - ?!? In theory, the process_reference should never fail, but we should - catch that case just in case the compiler scrogged the stabs. */ - refnum = process_reference (&p); - start = ref_search_value (refnum); - if (!start) - { - complain (&lrs_general_complaint, "Live range symbol not found 1"); - return 0; - } - - if (!*p || *p != ',') - { - complain (&lrs_general_complaint, "live range string 3"); - return 0; - } - p++; - - /* Get ending value of range and advance P past the reference id. - - ?!? In theory, the process_reference should never fail, but we should - catch that case just in case the compiler scrogged the stabs. */ - refnum = process_reference (&p); - end = ref_search_value (refnum); - if (!end) - { - complain (&lrs_general_complaint, "Live range symbol not found 2"); - return 0; - } - - if (!*p || *p != ')') - { - complain (&lrs_general_complaint, "live range string 4"); - return 0; - } - - /* Now that we know the bounds of the range, add it to the - symbol. */ - add_live_range (objfile, sym, start, end); - - return 1; -} - -/* Add a new live range defined by START and END to the symbol SYM - in objfile OBJFILE. */ - -static void -add_live_range (struct objfile *objfile, struct symbol *sym, CORE_ADDR start, - CORE_ADDR end) -{ - struct range_list *r, *rs; - - if (start >= end) - { - complain (&lrs_general_complaint, "end of live range follows start"); - return; - } - - /* Alloc new live range structure. */ - r = (struct range_list *) - obstack_alloc (&objfile->type_obstack, - sizeof (struct range_list)); - r->start = start; - r->end = end; - r->next = 0; - - /* Append this range to the symbol's range list. */ - if (!SYMBOL_RANGES (sym)) - SYMBOL_RANGES (sym) = r; - else - { - /* Get the last range for the symbol. */ - for (rs = SYMBOL_RANGES (sym); rs->next; rs = rs->next) - ; - rs->next = r; - } -} - - /* Skip rest of this symbol and return an error type. General notes on error recovery: error_type always skips to the @@ -2314,7 +1389,7 @@ add_live_range (struct objfile *objfile, struct symbol *sym, CORE_ADDR start, static struct type * error_type (char **pp, struct objfile *objfile) { - complain (&error_type_complaint); + complaint (&symfile_complaints, "couldn't parse type; debugger out of date?"); while (1) { /* Skip to end of symbol. */ @@ -2343,10 +1418,10 @@ error_type (char **pp, struct objfile *objfile) assume that type information starts with a digit, '-', or '(' in deciding whether to call read_type. */ -struct type * -read_type (register char **pp, struct objfile *objfile) +static struct type * +read_type (char **pp, struct objfile *objfile) { - register struct type *type = 0; + struct type *type = 0; struct type *type1; int typenums[2]; char type_descriptor; @@ -2358,6 +1433,9 @@ read_type (register char **pp, struct objfile *objfile) /* Used to distinguish string and bitstring from char-array and set. */ int is_string = 0; + /* Used to distinguish vector from array. */ + int is_vector = 0; + /* Read type number if present. The type number may be omitted. for instance in a two-dimensional array declared with type "ar1;1;10;ar1;1;10;4". */ @@ -2368,11 +1446,21 @@ read_type (register char **pp, struct objfile *objfile) if (read_type_number (pp, typenums) != 0) return error_type (pp, objfile); - /* Type is not being defined here. Either it already exists, - or this is a forward reference to it. dbx_alloc_type handles - both cases. */ if (**pp != '=') - return dbx_alloc_type (typenums, objfile); + { + /* Type is not being defined here. Either it already + exists, or this is a forward reference to it. + dbx_alloc_type handles both cases. */ + type = dbx_alloc_type (typenums, objfile); + + /* If this is a forward reference, arrange to complain if it + doesn't get patched up by the time we're done + reading. */ + if (TYPE_CODE (type) == TYPE_CODE_UNDEF) + add_undefined_type (type); + + return type; + } /* Type is being defined here. */ /* Skip the '='. @@ -2421,9 +1509,8 @@ again: { /* Complain and keep going, so compilers can invent new cross-reference types. */ - static struct complaint msg = - {"Unrecognized cross-reference type `%c'", 0, 0}; - complain (&msg, (*pp)[0]); + complaint (&symfile_complaints, + "Unrecognized cross-reference type `%c'", (*pp)[0]); code = TYPE_CODE_STRUCT; break; } @@ -2450,7 +1537,7 @@ again: return error_type (pp, objfile); } to = type_name = - (char *) obstack_alloc (&objfile->type_obstack, p - *pp + 1); + (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1); /* Copy the name. */ from = *pp + 1; @@ -2463,11 +1550,9 @@ again: *pp = from + 1; } - /* Now check to see whether the type has already been - declared. This was written for arrays of cross-referenced - types before we had TYPE_CODE_TARGET_STUBBED, so I'm pretty - sure it is not necessary anymore. But it might be a good - idea, to save a little memory. */ + /* If this type has already been declared, then reuse the same + type, rather than allocating a new one. This saves some + memory. */ for (ppt = file_symbols; ppt; ppt = ppt->next) for (i = 0; i < ppt->nsyms; i++) @@ -2475,12 +1560,14 @@ again: struct symbol *sym = ppt->symbol[i]; if (SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE + && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && (TYPE_CODE (SYMBOL_TYPE (sym)) == code) - && STREQ (SYMBOL_NAME (sym), type_name)) + && strcmp (DEPRECATED_SYMBOL_NAME (sym), type_name) == 0) { - obstack_free (&objfile->type_obstack, type_name); + obstack_free (&objfile->objfile_obstack, type_name); type = SYMBOL_TYPE (sym); + if (typenums[0] != -1) + *dbx_lookup_type (typenums) = type; return type; } } @@ -2536,7 +1623,24 @@ again: the related problems with unnecessarily stubbed types; someone motivated should attempt to clean up the issue here as well. Once a type pointed to has been created it - should not be modified. */ + should not be modified. + + Well, it's not *absolutely* wrong. Constructing recursive + types (trees, linked lists) necessarily entails modifying + types after creating them. Constructing any loop structure + entails side effects. The Dwarf 2 reader does handle this + more gracefully (it never constructs more than once + instance of a type object, so it doesn't have to copy type + objects wholesale), but it still mutates type objects after + other folks have references to them. + + Keep in mind that this circularity/mutation issue shows up + at the source language level, too: C's "incomplete types", + for example. So the proper cleanup, I think, would be to + limit GDB's type smashing to match exactly those required + by the source language. So GDB could have a + "complete_this_type" function, but never create unnecessary + copies of a type otherwise. */ replace_type (type, xtype); TYPE_NAME (type) = NULL; TYPE_TAG_NAME (type) = NULL; @@ -2556,7 +1660,7 @@ again: forward-referenced), and we must change it to a pointer, function, reference, or whatever, *in-place*. */ - case '*': + case '*': /* Pointer to another type */ type1 = read_type (pp, objfile); type = make_pointer_type (type1, dbx_lookup_type (typenums)); break; @@ -2567,21 +1671,6 @@ again: break; case 'f': /* Function returning another type */ - if (os9k_stabs && **pp == '(') - { - /* Function prototype; parse it. - We must conditionalize this on os9k_stabs because otherwise - it could be confused with a Sun-style (1,3) typenumber - (I think). */ - struct type *t; - ++*pp; - while (**pp != ')') - { - t = read_type (pp, objfile); - if (**pp == ',') - ++ * pp; - } - } type1 = read_type (pp, objfile); type = make_function_type (type1, dbx_lookup_type (typenums)); break; @@ -2626,11 +1715,9 @@ again: ++*pp; else { - static struct complaint msg = { - "Prototyped function type didn't end arguments with `#':\n%s", - 0, 0 - }; - complain (&msg, type_start); + complaint (&symfile_complaints, + "Prototyped function type didn't end arguments with `#':\n%s", + type_start); } /* If there is just one argument whose type is `void', then @@ -2662,22 +1749,12 @@ again: } case 'k': /* Const qualifier on some type (Sun) */ - case 'c': /* Const qualifier on some type (OS9000) */ - /* Because 'c' means other things to AIX and 'k' is perfectly good, - only accept 'c' in the os9k_stabs case. */ - if (type_descriptor == 'c' && !os9k_stabs) - return error_type (pp, objfile); type = read_type (pp, objfile); type = make_cv_type (1, TYPE_VOLATILE (type), type, dbx_lookup_type (typenums)); break; case 'B': /* Volatile qual on some type (Sun) */ - case 'i': /* Volatile qual on some type (OS9000) */ - /* Because 'i' means other things to AIX and 'B' is perfectly good, - only accept 'i' in the os9k_stabs case. */ - if (type_descriptor == 'i' && !os9k_stabs) - return error_type (pp, objfile); type = read_type (pp, objfile); type = make_cv_type (TYPE_CONST (type), 1, type, dbx_lookup_type (typenums)); @@ -2714,16 +1791,22 @@ again: switch (*attr) { - case 's': + case 's': /* Size attribute */ type_size = atoi (attr + 1); if (type_size <= 0) type_size = -1; break; - case 'S': + case 'S': /* String attribute */ + /* FIXME: check to see if following type is array? */ is_string = 1; break; + case 'V': /* Vector attribute */ + /* FIXME: check to see if following type is array? */ + is_vector = 1; + break; + default: /* Ignore unrecognized type attributes, so future compilers can invent new ones. */ @@ -2743,7 +1826,9 @@ again: (*pp)++; return_type = read_type (pp, objfile); if (*(*pp)++ != ';') - complain (&invalid_member_complaint, symnum); + complaint (&symfile_complaints, + "invalid (minimal) member type data format at symtab pos %d.", + symnum); type = allocate_stub_method (return_type); if (typenums[0] != -1) *dbx_lookup_type (typenums) = type; @@ -2752,7 +1837,8 @@ again: { struct type *domain = read_type (pp, objfile); struct type *return_type; - struct type **args; + struct field *args; + int nargs, varargs; if (**pp != ',') /* Invalid member type data format. */ @@ -2761,9 +1847,10 @@ again: ++(*pp); return_type = read_type (pp, objfile); - args = read_args (pp, ';', objfile); + args = read_args (pp, ';', objfile, &nargs, &varargs); type = dbx_alloc_type (typenums, objfile); - smash_to_method_type (type, domain, return_type, args); + smash_to_method_type (type, domain, return_type, args, + nargs, varargs); } break; @@ -2774,10 +1861,6 @@ again: break; case 'b': - if (os9k_stabs) - /* Const and volatile qualified type. */ - type = read_type (pp, objfile); - else { /* Sun ACC builtin int type */ type = read_sun_builtin_type (pp, typenums, objfile); @@ -2801,18 +1884,21 @@ again: case 's': /* Struct type */ case 'u': /* Union type */ - type = dbx_alloc_type (typenums, objfile); - switch (type_descriptor) - { - case 's': - TYPE_CODE (type) = TYPE_CODE_STRUCT; - break; - case 'u': - TYPE_CODE (type) = TYPE_CODE_UNION; - break; - } - type = read_struct_type (pp, type, objfile); - break; + { + enum type_code type_code = TYPE_CODE_UNDEF; + type = dbx_alloc_type (typenums, objfile); + switch (type_descriptor) + { + case 's': + type_code = TYPE_CODE_STRUCT; + break; + case 'u': + type_code = TYPE_CODE_UNION; + break; + } + type = read_struct_type (pp, type, type_code, objfile); + break; + } case 'a': /* Array type */ if (**pp != 'r') @@ -2823,9 +1909,11 @@ again: type = read_array_type (pp, type, objfile); if (is_string) TYPE_CODE (type) = TYPE_CODE_STRING; + if (is_vector) + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; break; - case 'S': + case 'S': /* Set or bitstring type */ type1 = read_type (pp, objfile); type = create_set_type ((struct type *) NULL, type1); if (is_string) @@ -2867,7 +1955,7 @@ rs6000_builtin_type (int typenum) if (typenum >= 0 || typenum < -NUMBER_RECOGNIZED) { - complain (&rs6000_builtin_complaint, typenum); + complaint (&symfile_complaints, "Unknown builtin type %d", typenum); return builtin_type_error; } if (negative_types[-typenum] != NULL) @@ -2978,10 +2066,14 @@ rs6000_builtin_type (int typenum) case 25: /* Complex type consisting of two IEEE single precision values. */ rettype = init_type (TYPE_CODE_COMPLEX, 8, 0, "complex", NULL); + TYPE_TARGET_TYPE (rettype) = init_type (TYPE_CODE_FLT, 4, 0, "float", + NULL); break; case 26: /* Complex type consisting of two IEEE double precision values. */ rettype = init_type (TYPE_CODE_COMPLEX, 16, 0, "double complex", NULL); + TYPE_TARGET_TYPE (rettype) = init_type (TYPE_CODE_FLT, 8, 0, "double", + NULL); break; case 27: rettype = init_type (TYPE_CODE_INT, 1, 0, "integer*1", NULL); @@ -3016,6 +2108,31 @@ rs6000_builtin_type (int typenum) /* This page contains subroutines of read_type. */ +/* Replace *OLD_NAME with the method name portion of PHYSNAME. */ + +static void +update_method_name_from_physname (char **old_name, char *physname) +{ + char *method_name; + + method_name = method_name_from_physname (physname); + + if (method_name == NULL) + { + complaint (&symfile_complaints, + "Method has bad physname %s\n", physname); + return; + } + + if (strcmp (*old_name, method_name) != 0) + { + xfree (*old_name); + *old_name = method_name; + } + else + xfree (method_name); +} + /* Read member function stabs info for C++ classes. The form of each member function data is: @@ -3037,7 +2154,6 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, { int nfn_fields = 0; int length = 0; - int skip_method; /* Total number of member functions defined in this class. If the class defines two `f' functions, and one `g' function, then this will have the value 3. */ @@ -3053,7 +2169,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, struct next_fnfieldlist *new_fnlist; struct next_fnfield *new_sublist; char *main_fn_name; - register char *p; + char *p; /* Process each list until we find something that is not a member function or find the end of the functions. */ @@ -3077,36 +2193,6 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, look_ahead_type = NULL; length = 0; - skip_method = 0; - if (p - *pp == strlen ("__base_ctor") - && strncmp (*pp, "__base_ctor", strlen ("__base_ctor")) == 0) - skip_method = 1; - else if (p - *pp == strlen ("__base_dtor") - && strncmp (*pp, "__base_dtor", strlen ("__base_dtor")) == 0) - skip_method = 1; - else if (p - *pp == strlen ("__deleting_dtor") - && strncmp (*pp, "__deleting_dtor", - strlen ("__deleting_dtor")) == 0) - skip_method = 1; - - if (skip_method) - { - /* Skip past '::'. */ - *pp = p + 2; - /* Read the type. */ - read_type (pp, objfile); - /* Skip past the colon, mangled name, semicolon, flags, and final - semicolon. */ - while (**pp != ';') - (*pp) ++; - (*pp) ++; - while (**pp != ';') - (*pp) ++; - (*pp) ++; - - continue; - } - new_fnlist = (struct next_fnfieldlist *) xmalloc (sizeof (struct next_fnfieldlist)); make_cleanup (xfree, new_fnlist); @@ -3123,8 +2209,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, /* This lets the user type "break operator+". We could just put in "+" as the name, but that wouldn't work for "*". */ - static char opname[32] = - {'o', 'p', CPLUS_MARKER}; + static char opname[32] = "op$"; char *o = opname + 3; /* Skip past '::'. */ @@ -3232,7 +2317,8 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, case '.': break; default: - complain (&const_vol_complaint, **pp); + complaint (&symfile_complaints, + "const/volatile indicator missing, got '%c'", **pp); break; } @@ -3287,17 +2373,35 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, } case '?': /* static member function. */ - new_sublist->fn_field.voffset = VOFFSET_STATIC; - if (strncmp (new_sublist->fn_field.physname, - main_fn_name, strlen (main_fn_name))) - { - new_sublist->fn_field.is_stub = 1; - } - break; + { + int slen = strlen (main_fn_name); + + new_sublist->fn_field.voffset = VOFFSET_STATIC; + + /* For static member functions, we can't tell if they + are stubbed, as they are put out as functions, and not as + methods. + GCC v2 emits the fully mangled name if + dbxout.c:flag_minimal_debug is not set, so we have to + detect a fully mangled physname here and set is_stub + accordingly. Fully mangled physnames in v2 start with + the member function name, followed by two underscores. + GCC v3 currently always emits stubbed member functions, + but with fully mangled physnames, which start with _Z. */ + if (!(strncmp (new_sublist->fn_field.physname, + main_fn_name, slen) == 0 + && new_sublist->fn_field.physname[slen] == '_' + && new_sublist->fn_field.physname[slen + 1] == '_')) + { + new_sublist->fn_field.is_stub = 1; + } + break; + } default: /* error */ - complain (&member_fn_complaint, (*pp)[-1]); + complaint (&symfile_complaints, + "member function type missing, got '%c'", (*pp)[-1]); /* Fall through into normal member function. */ case '.': @@ -3315,23 +2419,192 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type, while (**pp != ';' && **pp != '\0'); (*pp)++; - - new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) - obstack_alloc (&objfile->type_obstack, - sizeof (struct fn_field) * length); - memset (new_fnlist->fn_fieldlist.fn_fields, 0, - sizeof (struct fn_field) * length); - for (i = length; (i--, sublist); sublist = sublist->next) - { - new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field; - } - - new_fnlist->fn_fieldlist.length = length; - new_fnlist->next = fip->fnlist; - fip->fnlist = new_fnlist; - nfn_fields++; - total_length += length; STABS_CONTINUE (pp, objfile); + + /* Skip GCC 3.X member functions which are duplicates of the callable + constructor/destructor. */ + if (strcmp (main_fn_name, "__base_ctor") == 0 + || strcmp (main_fn_name, "__base_dtor") == 0 + || strcmp (main_fn_name, "__deleting_dtor") == 0) + { + xfree (main_fn_name); + } + else + { + int has_stub = 0; + int has_destructor = 0, has_other = 0; + int is_v3 = 0; + struct next_fnfield *tmp_sublist; + + /* Various versions of GCC emit various mostly-useless + strings in the name field for special member functions. + + For stub methods, we need to defer correcting the name + until we are ready to unstub the method, because the current + name string is used by gdb_mangle_name. The only stub methods + of concern here are GNU v2 operators; other methods have their + names correct (see caveat below). + + For non-stub methods, in GNU v3, we have a complete physname. + Therefore we can safely correct the name now. This primarily + affects constructors and destructors, whose name will be + __comp_ctor or __comp_dtor instead of Foo or ~Foo. Cast + operators will also have incorrect names; for instance, + "operator int" will be named "operator i" (i.e. the type is + mangled). + + For non-stub methods in GNU v2, we have no easy way to + know if we have a complete physname or not. For most + methods the result depends on the platform (if CPLUS_MARKER + can be `$' or `.', it will use minimal debug information, or + otherwise the full physname will be included). + + Rather than dealing with this, we take a different approach. + For v3 mangled names, we can use the full physname; for v2, + we use cplus_demangle_opname (which is actually v2 specific), + because the only interesting names are all operators - once again + barring the caveat below. Skip this process if any method in the + group is a stub, to prevent our fouling up the workings of + gdb_mangle_name. + + The caveat: GCC 2.95.x (and earlier?) put constructors and + destructors in the same method group. We need to split this + into two groups, because they should have different names. + So for each method group we check whether it contains both + routines whose physname appears to be a destructor (the physnames + for and destructors are always provided, due to quirks in v2 + mangling) and routines whose physname does not appear to be a + destructor. If so then we break up the list into two halves. + Even if the constructors and destructors aren't in the same group + the destructor will still lack the leading tilde, so that also + needs to be fixed. + + So, to summarize what we expect and handle here: + + Given Given Real Real Action + method name physname physname method name + + __opi [none] __opi__3Foo operator int opname + [now or later] + Foo _._3Foo _._3Foo ~Foo separate and + rename + operator i _ZN3FoocviEv _ZN3FoocviEv operator int demangle + __comp_ctor _ZN3FooC1ERKS_ _ZN3FooC1ERKS_ Foo demangle + */ + + tmp_sublist = sublist; + while (tmp_sublist != NULL) + { + if (tmp_sublist->fn_field.is_stub) + has_stub = 1; + if (tmp_sublist->fn_field.physname[0] == '_' + && tmp_sublist->fn_field.physname[1] == 'Z') + is_v3 = 1; + + if (is_destructor_name (tmp_sublist->fn_field.physname)) + has_destructor++; + else + has_other++; + + tmp_sublist = tmp_sublist->next; + } + + if (has_destructor && has_other) + { + struct next_fnfieldlist *destr_fnlist; + struct next_fnfield *last_sublist; + + /* Create a new fn_fieldlist for the destructors. */ + + destr_fnlist = (struct next_fnfieldlist *) + xmalloc (sizeof (struct next_fnfieldlist)); + make_cleanup (xfree, destr_fnlist); + memset (destr_fnlist, 0, sizeof (struct next_fnfieldlist)); + destr_fnlist->fn_fieldlist.name + = obconcat (&objfile->objfile_obstack, "", "~", + new_fnlist->fn_fieldlist.name); + + destr_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct fn_field) * has_destructor); + memset (destr_fnlist->fn_fieldlist.fn_fields, 0, + sizeof (struct fn_field) * has_destructor); + tmp_sublist = sublist; + last_sublist = NULL; + i = 0; + while (tmp_sublist != NULL) + { + if (!is_destructor_name (tmp_sublist->fn_field.physname)) + { + tmp_sublist = tmp_sublist->next; + continue; + } + + destr_fnlist->fn_fieldlist.fn_fields[i++] + = tmp_sublist->fn_field; + if (last_sublist) + last_sublist->next = tmp_sublist->next; + else + sublist = tmp_sublist->next; + last_sublist = tmp_sublist; + tmp_sublist = tmp_sublist->next; + } + + destr_fnlist->fn_fieldlist.length = has_destructor; + destr_fnlist->next = fip->fnlist; + fip->fnlist = destr_fnlist; + nfn_fields++; + total_length += has_destructor; + length -= has_destructor; + } + else if (is_v3) + { + /* v3 mangling prevents the use of abbreviated physnames, + so we can do this here. There are stubbed methods in v3 + only: + - in -gstabs instead of -gstabs+ + - or for static methods, which are output as a function type + instead of a method type. */ + + update_method_name_from_physname (&new_fnlist->fn_fieldlist.name, + sublist->fn_field.physname); + } + else if (has_destructor && new_fnlist->fn_fieldlist.name[0] != '~') + { + new_fnlist->fn_fieldlist.name = concat ("~", main_fn_name, NULL); + xfree (main_fn_name); + } + else if (!has_stub) + { + char dem_opname[256]; + int ret; + ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name, + dem_opname, DMGL_ANSI); + if (!ret) + ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name, + dem_opname, 0); + if (ret) + new_fnlist->fn_fieldlist.name + = obsavestring (dem_opname, strlen (dem_opname), + &objfile->objfile_obstack); + } + + new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct fn_field) * length); + memset (new_fnlist->fn_fieldlist.fn_fields, 0, + sizeof (struct fn_field) * length); + for (i = length; (i--, sublist); sublist = sublist->next) + { + new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field; + } + + new_fnlist->fn_fieldlist.length = length; + new_fnlist->next = fip->fnlist; + fip->fnlist = new_fnlist; + nfn_fields++; + total_length += length; + } } if (nfn_fields) @@ -3357,7 +2630,7 @@ static int read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; char *name; char cpp_abbrev; struct type *context; @@ -3386,24 +2659,26 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, name = ""; } fip->list->field.name = - obconcat (&objfile->type_obstack, vptr_name, name, ""); + obconcat (&objfile->objfile_obstack, vptr_name, name, ""); break; case 'b': /* $vb -- a virtual bsomethingorother */ name = type_name_no_tag (context); if (name == NULL) { - complain (&invalid_cpp_type_complaint, symnum); + complaint (&symfile_complaints, + "C++ abbreviated type name unknown at symtab pos %d", + symnum); name = "FOO"; } fip->list->field.name = - obconcat (&objfile->type_obstack, vb_name, name, ""); + obconcat (&objfile->objfile_obstack, vb_name, name, ""); break; default: - complain (&invalid_cpp_abbrev_complaint, *pp); + invalid_cpp_abbrev_complaint (*pp); fip->list->field.name = - obconcat (&objfile->type_obstack, + obconcat (&objfile->objfile_obstack, "INVALID_CPLUSPLUS_ABBREV", "", ""); break; } @@ -3414,7 +2689,7 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, p = ++(*pp); if (p[-1] != ':') { - complain (&invalid_cpp_abbrev_complaint, *pp); + invalid_cpp_abbrev_complaint (*pp); return 0; } fip->list->field.type = read_type (pp, objfile); @@ -3435,7 +2710,7 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type, } else { - complain (&invalid_cpp_abbrev_complaint, *pp); + invalid_cpp_abbrev_complaint (*pp); /* We have no idea what syntax an unrecognized abbrev would have, so better return 0. If we returned 1, we would need to at least advance *pp to avoid an infinite loop. */ @@ -3448,37 +2723,8 @@ static void read_one_struct_field (struct field_info *fip, char **pp, char *p, struct type *type, struct objfile *objfile) { - /* The following is code to work around cfront generated stabs. - The stabs contains full mangled name for each field. - We try to demangle the name and extract the field name out of it. - */ - if (ARM_DEMANGLING && current_subfile->language == language_cplus) - { - char save_p; - char *dem, *dem_p; - save_p = *p; - *p = '\0'; - dem = cplus_demangle (*pp, DMGL_ANSI | DMGL_PARAMS); - if (dem != NULL) - { - dem_p = strrchr (dem, ':'); - if (dem_p != 0 && *(dem_p - 1) == ':') - dem_p++; - FIELD_NAME (fip->list->field) = - obsavestring (dem_p, strlen (dem_p), &objfile->type_obstack); - } - else - { - FIELD_NAME (fip->list->field) = - obsavestring (*pp, p - *pp, &objfile->type_obstack); - } - *p = save_p; - } - /* end of code for cfront work around */ - - else - fip->list->field.name = - obsavestring (*pp, p - *pp, &objfile->type_obstack); + fip->list->field.name = + obsavestring (*pp, p - *pp, &objfile->objfile_obstack); *pp = p + 1; /* This means we have a visibility for a field coming. */ @@ -3519,7 +2765,7 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p, else if (**pp != ',') { /* Bad structure-type format. */ - complain (&stabs_general_complaint, "bad structure-type format"); + stabs_general_complaint ("bad structure-type format"); return; } @@ -3530,13 +2776,13 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p, FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits); if (nbits != 0) { - complain (&stabs_general_complaint, "bad structure-type format"); + stabs_general_complaint ("bad structure-type format"); return; } FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits); if (nbits != 0) { - complain (&stabs_general_complaint, "bad structure-type format"); + stabs_general_complaint ("bad structure-type format"); return; } } @@ -3615,7 +2861,7 @@ static int read_struct_fields (struct field_info *fip, char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; struct nextfield *new; /* We better set p right now, in case there are no fields at all... */ @@ -3630,8 +2876,6 @@ read_struct_fields (struct field_info *fip, char **pp, struct type *type, while (**pp != ';' && **pp != '\0') { - if (os9k_stabs && **pp == ',') - break; STABS_CONTINUE (pp, objfile); /* Get space to record the next field's data. */ new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); @@ -3676,8 +2920,9 @@ read_struct_fields (struct field_info *fip, char **pp, struct type *type, } if (p[0] == ':' && p[1] == ':') { - /* chill the list of fields: the last entry (at the head) is a - partially constructed entry which we now scrub. */ + /* (the deleted) chill the list of fields: the last entry (at + the head) is a partially constructed entry which we now + scrub. */ fip->list = fip->list->next; } return 1; @@ -3773,10 +3018,8 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type, default: /* Unknown character. Complain and treat it as non-virtual. */ { - static struct complaint msg = - { - "Unknown virtual character `%c' for baseclass", 0, 0}; - complain (&msg, **pp); + complaint (&symfile_complaints, + "Unknown virtual character `%c' for baseclass", **pp); } } ++(*pp); @@ -3792,11 +3035,9 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type, /* Bad visibility format. Complain and treat it as public. */ { - static struct complaint msg = - { - "Unknown visibility `%c' for baseclass", 0, 0 - }; - complain (&msg, new->visibility); + complaint (&symfile_complaints, + "Unknown visibility `%c' for baseclass", + new->visibility); new->visibility = VISIBILITY_PUBLIC; } } @@ -3841,7 +3082,7 @@ static int read_tilde_fields (struct field_info *fip, char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; STABS_CONTINUE (pp, objfile); @@ -3893,15 +3134,18 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type, i >= TYPE_N_BASECLASSES (t); --i) { - if (!strncmp (TYPE_FIELD_NAME (t, i), vptr_name, - sizeof (vptr_name) - 1)) + char *name = TYPE_FIELD_NAME (t, i); + if (!strncmp (name, vptr_name, sizeof (vptr_name) - 2) + && is_cplus_marker (name[sizeof (vptr_name) - 2])) { TYPE_VPTR_FIELDNO (type) = i; goto gotit; } } /* Virtual function table field not found. */ - complain (&vtbl_notfound_complaint, TYPE_NAME (type)); + complaint (&symfile_complaints, + "virtual function table pointer not found when defining class `%s'", + TYPE_NAME (type)); return 0; } else @@ -3917,9 +3161,9 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type, } static int -attach_fn_fields_to_type (struct field_info *fip, register struct type *type) +attach_fn_fields_to_type (struct field_info *fip, struct type *type) { - register int n; + int n; for (n = TYPE_NFN_FIELDS (type); fip->fnlist != NULL; @@ -3931,150 +3175,17 @@ attach_fn_fields_to_type (struct field_info *fip, register struct type *type) return 1; } -/* read cfront class static data. - pp points to string starting with the list of static data - eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;; - ^^^^^^^^ - - A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;; - ^ - */ - -static int -read_cfront_static_fields (struct field_info *fip, char **pp, struct type *type, - struct objfile *objfile) -{ - struct nextfield *new; - struct type *stype; - char *sname; - struct symbol *ref_static = 0; - - if (**pp == ';') /* no static data; return */ - { - ++(*pp); - return 1; - } - - /* Process each field in the list until we find the terminating ";" */ - - /* eg: p = "as__1A ;;;" */ - STABS_CONTINUE (pp, objfile); /* handle \\ */ - while (**pp != ';' && (sname = get_substring (pp, ' '), sname)) - { - ref_static = lookup_symbol (sname, 0, VAR_NAMESPACE, 0, 0); /*demangled_name */ - if (!ref_static) - { - static struct complaint msg = - {"\ - Unable to find symbol for static data field %s\n", - 0, 0}; - complain (&msg, sname); - continue; - } - stype = SYMBOL_TYPE (ref_static); - - /* allocate a new fip */ - new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (xfree, new); - memset (new, 0, sizeof (struct nextfield)); - new->next = fip->list; - fip->list = new; - - /* set visibility */ - /* FIXME! no way to tell visibility from stabs??? */ - new->visibility = VISIBILITY_PUBLIC; - - /* set field info into fip */ - fip->list->field.type = stype; - - /* set bitpos & bitsize */ - SET_FIELD_PHYSNAME (fip->list->field, savestring (sname, strlen (sname))); - - /* set name field */ - /* The following is code to work around cfront generated stabs. - The stabs contains full mangled name for each field. - We try to demangle the name and extract the field name out of it. - */ - if (ARM_DEMANGLING) - { - char *dem, *dem_p; - dem = cplus_demangle (sname, DMGL_ANSI | DMGL_PARAMS); - if (dem != NULL) - { - dem_p = strrchr (dem, ':'); - if (dem_p != 0 && *(dem_p - 1) == ':') - dem_p++; - fip->list->field.name = - obsavestring (dem_p, strlen (dem_p), &objfile->type_obstack); - } - else - { - fip->list->field.name = - obsavestring (sname, strlen (sname), &objfile->type_obstack); - } - } /* end of code for cfront work around */ - } /* loop again for next static field */ - return 1; -} - -/* Copy structure fields to fip so attach_fields_to_type will work. - type has already been created with the initial instance data fields. - Now we want to be able to add the other members to the class, - so we want to add them back to the fip and reattach them again - once we have collected all the class members. */ - -static int -copy_cfront_struct_fields (struct field_info *fip, struct type *type, - struct objfile *objfile) -{ - int nfields = TYPE_NFIELDS (type); - int i; - struct nextfield *new; - - /* Copy the fields into the list of fips and reset the types - to remove the old fields */ - - for (i = 0; i < nfields; i++) - { - /* allocate a new fip */ - new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (xfree, new); - memset (new, 0, sizeof (struct nextfield)); - new->next = fip->list; - fip->list = new; - - /* copy field info into fip */ - new->field = TYPE_FIELD (type, i); - /* set visibility */ - if (TYPE_FIELD_PROTECTED (type, i)) - new->visibility = VISIBILITY_PROTECTED; - else if (TYPE_FIELD_PRIVATE (type, i)) - new->visibility = VISIBILITY_PRIVATE; - else - new->visibility = VISIBILITY_PUBLIC; - } - /* Now delete the fields from the type since we will be - allocing new space once we get the rest of the fields - in attach_fields_to_type. - The pointer TYPE_FIELDS(type) is left dangling but should - be freed later by objstack_free */ - TYPE_FIELDS (type) = 0; - TYPE_NFIELDS (type) = 0; - - return 1; -} - /* Create the vector of fields, and record how big it is. We need this info to record proper virtual function table information for this class's virtual functions. */ static int -attach_fields_to_type (struct field_info *fip, register struct type *type, +attach_fields_to_type (struct field_info *fip, struct type *type, struct objfile *objfile) { - register int nfields = 0; - register int non_public_fields = 0; - register struct nextfield *scan; + int nfields = 0; + int non_public_fields = 0; + struct nextfield *scan; /* Count up the number of fields that we have, as well as taking note of whether or not there are any non-public fields, which requires us to @@ -4143,10 +3254,8 @@ attach_fields_to_type (struct field_info *fip, register struct type *type, default: /* Unknown visibility. Complain and treat it as public. */ { - static struct complaint msg = - { - "Unknown visibility `%c' for field", 0, 0}; - complain (&msg, fip->list->visibility); + complaint (&symfile_complaints, "Unknown visibility `%c' for field", + fip->list->visibility); } break; } @@ -4155,6 +3264,42 @@ attach_fields_to_type (struct field_info *fip, register struct type *type, return 1; } + +/* Complain that the compiler has emitted more than one definition for the + structure type TYPE. */ +static void +complain_about_struct_wipeout (struct type *type) +{ + char *name = ""; + char *kind = ""; + + if (TYPE_TAG_NAME (type)) + { + name = TYPE_TAG_NAME (type); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: kind = "struct "; break; + case TYPE_CODE_UNION: kind = "union "; break; + case TYPE_CODE_ENUM: kind = "enum "; break; + default: kind = ""; + } + } + else if (TYPE_NAME (type)) + { + name = TYPE_NAME (type); + kind = ""; + } + else + { + name = ""; + kind = ""; + } + + complaint (&symfile_complaints, + "struct/union type gets multiply defined: %s%s", kind, name); +} + + /* Read the description of a structure (or union type) and return an object describing the type. @@ -4170,7 +3315,8 @@ attach_fields_to_type (struct field_info *fip, register struct type *type, */ static struct type * -read_struct_type (char **pp, struct type *type, struct objfile *objfile) +read_struct_type (char **pp, struct type *type, enum type_code type_code, + struct objfile *objfile) { struct cleanup *back_to; struct field_info fi; @@ -4178,9 +3324,30 @@ read_struct_type (char **pp, struct type *type, struct objfile *objfile) fi.list = NULL; fi.fnlist = NULL; + /* When describing struct/union/class types in stabs, G++ always drops + all qualifications from the name. So if you've got: + struct A { ... struct B { ... }; ... }; + then G++ will emit stabs for `struct A::B' that call it simply + `struct B'. Obviously, if you've got a real top-level definition for + `struct B', or other nested definitions, this is going to cause + problems. + + Obviously, GDB can't fix this by itself, but it can at least avoid + scribbling on existing structure type objects when new definitions + appear. */ + if (! (TYPE_CODE (type) == TYPE_CODE_UNDEF + || TYPE_STUB (type))) + { + complain_about_struct_wipeout (type); + + /* It's probably best to return the type unchanged. */ + return type; + } + back_to = make_cleanup (null_cleanup, 0); INIT_CPLUS_SPECIFIC (type); + TYPE_CODE (type) = type_code; TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; /* First comes the total size in bytes. */ @@ -4207,8 +3374,6 @@ read_struct_type (char **pp, struct type *type, struct objfile *objfile) type = error_type (pp, objfile); } - /* Fix up any cv-qualified versions of this type. */ - finish_cv_type (type); do_cleanups (back_to); return (type); } @@ -4219,7 +3384,7 @@ read_struct_type (char **pp, struct type *type, struct objfile *objfile) array. */ static struct type * -read_array_type (register char **pp, register struct type *type, +read_array_type (char **pp, struct type *type, struct objfile *objfile) { struct type *index_type, *element_type, *range_type; @@ -4234,9 +3399,6 @@ read_array_type (register char **pp, register struct type *type, Fortran adjustable arrays use Adigits or Tdigits for lower or upper; for these, produce a type like float[][]. */ - if (os9k_stabs) - index_type = builtin_type_int; - else { index_type = read_type (pp, objfile); if (**pp != ';') @@ -4250,7 +3412,8 @@ read_array_type (register char **pp, register struct type *type, (*pp)++; adjustable = 1; } - lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits); + lower = read_huge_number (pp, ';', &nbits); + if (nbits != 0) return error_type (pp, objfile); @@ -4284,13 +3447,13 @@ read_array_type (register char **pp, register struct type *type, Also defines the symbols that represent the values of the type. */ static struct type * -read_enum_type (register char **pp, register struct type *type, +read_enum_type (char **pp, struct type *type, struct objfile *objfile) { - register char *p; + char *p; char *name; - register long n; - register struct symbol *sym; + long n; + struct symbol *sym; int nsyms = 0; struct pending **symlist; struct pending *osyms, *syms; @@ -4310,16 +3473,6 @@ read_enum_type (register char **pp, register struct type *type, osyms = *symlist; o_nsyms = osyms ? osyms->nsyms : 0; - if (os9k_stabs) - { - /* Size. Perhaps this does not have to be conditionalized on - os9k_stabs (assuming the name of an enum constant can't start - with a digit). */ - read_huge_number (pp, 0, &nbits); - if (nbits != 0) - return error_type (pp, objfile); - } - /* The aix4 compiler emits an extra field before the enum members; my guess is it's a type of some sort. Just ignore it. */ if (**pp == '-') @@ -4341,19 +3494,19 @@ read_enum_type (register char **pp, register struct type *type, p = *pp; while (*p != ':') p++; - name = obsavestring (*pp, p - *pp, &objfile->symbol_obstack); + name = obsavestring (*pp, p - *pp, &objfile->objfile_obstack); *pp = p + 1; n = read_huge_number (pp, ',', &nbits); if (nbits != 0) return error_type (pp, objfile); sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = name; + DEPRECATED_SYMBOL_NAME (sym) = name; SYMBOL_LANGUAGE (sym) = current_subfile->language; SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_VALUE (sym) = n; if (n < 0) unsigned_enum = 0; @@ -4392,7 +3545,7 @@ read_enum_type (register char **pp, register struct type *type, { struct symbol *xsym = syms->symbol[j]; SYMBOL_TYPE (xsym) = type; - TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym); + TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym); TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); TYPE_FIELD_BITSIZE (type, n) = 0; } @@ -4494,6 +3647,7 @@ read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile) int nbits; int details; int nbytes; + struct type *rettype; /* The first number has more details about the type, for example FN_COMPLEX. */ @@ -4508,9 +3662,12 @@ read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile) if (details == NF_COMPLEX || details == NF_COMPLEX16 || details == NF_COMPLEX32) - /* This is a type we can't handle, but we do know the size. - We also will be able to give it a name. */ - return init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile); + { + rettype = init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile); + TYPE_TARGET_TYPE (rettype) + = init_type (TYPE_CODE_FLT, nbytes / 2, 0, NULL, objfile); + return rettype; + } return init_type (TYPE_CODE_FLT, nbytes, 0, NULL, objfile); } @@ -4553,10 +3710,7 @@ read_huge_number (char **pp, int end, int *bits) p++; } - if (os9k_stabs) - upper_limit = ULONG_MAX / radix; - else - upper_limit = LONG_MAX / radix; + upper_limit = LONG_MAX / radix; while ((c = *p++) >= '0' && c < ('0' + radix)) { @@ -4750,11 +3904,7 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile) /* Special case: char is defined (Who knows why) as a subrange of itself with range 0-127. */ else if (self_subrange && n2 == 0 && n3 == 127) - return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile); - - else if (current_symbol && SYMBOL_LANGUAGE (current_symbol) == language_chill - && !self_subrange) - goto handle_true_range; + return init_type (TYPE_CODE_INT, 1, TYPE_FLAG_NOSIGN, NULL, objfile); /* We used to do this only for subrange of self or subrange of int. */ else if (n2 == 0) @@ -4816,7 +3966,8 @@ handle_true_range: static struct type *range_type_index; - complain (&range_type_base_complaint, rangenums[1]); + complaint (&symfile_complaints, + "base type %d of range type is not defined", rangenums[1]); if (range_type_index == NULL) range_type_index = init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, @@ -4832,38 +3983,39 @@ handle_true_range: and terminated with END. Return the list of types read in, or (struct type **)-1 if there is an error. */ -static struct type ** -read_args (char **pp, int end, struct objfile *objfile) +static struct field * +read_args (char **pp, int end, struct objfile *objfile, int *nargsp, + int *varargsp) { /* FIXME! Remove this arbitrary limit! */ - struct type *types[1024], **rval; /* allow for fns of 1023 parameters */ - int n = 0; + struct type *types[1024]; /* allow for fns of 1023 parameters */ + int n = 0, i; + struct field *rval; while (**pp != end) { if (**pp != ',') /* Invalid argument list: no ','. */ - return (struct type **) -1; + return (struct field *) -1; (*pp)++; STABS_CONTINUE (pp, objfile); types[n++] = read_type (pp, objfile); } (*pp)++; /* get past `end' (the ':' character) */ - if (n == 1) - { - rval = (struct type **) xmalloc (2 * sizeof (struct type *)); - } - else if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID) - { - rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *)); - memset (rval + n, 0, sizeof (struct type *)); - } + if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID) + *varargsp = 1; else { - rval = (struct type **) xmalloc (n * sizeof (struct type *)); + n--; + *varargsp = 0; } - memcpy (rval, types, n * sizeof (struct type *)); + + rval = (struct field *) xmalloc (n * sizeof (struct field)); + memset (rval, 0, n * sizeof (struct field)); + for (i = 0; i < n; i++) + rval[i].type = types[i]; + *nargsp = n; return rval; } @@ -4891,16 +4043,13 @@ common_block_start (char *name, struct objfile *objfile) { if (common_block_name != NULL) { - static struct complaint msg = - { - "Invalid symbol data: common block within common block", - 0, 0}; - complain (&msg); + complaint (&symfile_complaints, + "Invalid symbol data: common block within common block"); } common_block = local_symbols; common_block_i = local_symbols ? local_symbols->nsyms : 0; common_block_name = obsavestring (name, strlen (name), - &objfile->symbol_obstack); + &objfile->objfile_obstack); } /* Process a N_ECOMM symbol. */ @@ -4921,17 +4070,15 @@ common_block_end (struct objfile *objfile) if (common_block_name == NULL) { - static struct complaint msg = - {"ECOMM symbol unmatched by BCOMM", 0, 0}; - complain (&msg); + complaint (&symfile_complaints, "ECOMM symbol unmatched by BCOMM"); return; } sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); - /* Note: common_block_name already saved on symbol_obstack */ - SYMBOL_NAME (sym) = common_block_name; + /* Note: common_block_name already saved on objfile_obstack */ + DEPRECATED_SYMBOL_NAME (sym) = common_block_name; SYMBOL_CLASS (sym) = LOC_BLOCK; /* Now we copy all the symbols which have been defined since the BCOMM. */ @@ -4958,7 +4105,7 @@ common_block_end (struct objfile *objfile) /* Should we be putting local_symbols back to what it was? Does it matter? */ - i = hashname (SYMBOL_NAME (sym)); + i = hashname (DEPRECATED_SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i]; global_sym_chain[i] = sym; common_block_name = NULL; @@ -4974,7 +4121,7 @@ fix_common_block (struct symbol *sym, int valu) struct pending *next = (struct pending *) SYMBOL_TYPE (sym); for (; next; next = next->next) { - register int j; + int j; for (j = next->nsyms - 1; j >= 0; j--) SYMBOL_VALUE_ADDRESS (next->symbol[j]) += valu; } @@ -4987,7 +4134,7 @@ fix_common_block (struct symbol *sym, int valu) /* Add a type to the list of undefined types to be checked through once this file has been read in. */ -void +static void add_undefined_type (struct type *type) { if (undef_types_length == undef_types_allocated) @@ -5036,9 +4183,7 @@ cleanup_undefined_types (void) if (typename == NULL) { - static struct complaint msg = - {"need a type name", 0, 0}; - complain (&msg); + complaint (&symfile_complaints, "need a type name"); break; } for (ppt = file_symbols; ppt; ppt = ppt->next) @@ -5048,14 +4193,11 @@ cleanup_undefined_types (void) struct symbol *sym = ppt->symbol[i]; if (SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE + && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE (*type)) - && STREQ (SYMBOL_NAME (sym), typename)) - { - memcpy (*type, SYMBOL_TYPE (sym), - sizeof (struct type)); - } + && strcmp (DEPRECATED_SYMBOL_NAME (sym), typename) == 0) + replace_type (*type, SYMBOL_TYPE (sym)); } } } @@ -5064,10 +4206,10 @@ cleanup_undefined_types (void) default: { - static struct complaint msg = - {"\ -GDB internal error. cleanup_undefined_types with bad type %d.", 0, 0}; - complain (&msg, TYPE_CODE (*type)); + complaint (&symfile_complaints, + "forward-referenced types left unresolved, " + "type code %d.", + TYPE_CODE (*type)); } break; } @@ -5085,7 +4227,7 @@ scan_file_globals (struct objfile *objfile) { int hash; struct minimal_symbol *msymbol; - struct symbol *sym, *prev, *rsym; + struct symbol *sym, *prev; struct objfile *resolve_objfile; /* SVR4 based linkers copy referenced global symbols from shared @@ -5111,7 +4253,7 @@ scan_file_globals (struct objfile *objfile) return; for (msymbol = resolve_objfile->msymbols; - msymbol && SYMBOL_NAME (msymbol) != NULL; + msymbol && DEPRECATED_SYMBOL_NAME (msymbol) != NULL; msymbol++) { QUIT; @@ -5132,16 +4274,13 @@ scan_file_globals (struct objfile *objfile) /* Get the hash index and check all the symbols under that hash index. */ - hash = hashname (SYMBOL_NAME (msymbol)); + hash = hashname (DEPRECATED_SYMBOL_NAME (msymbol)); for (sym = global_sym_chain[hash]; sym;) { - if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] && - STREQ (SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1)) + if (DEPRECATED_SYMBOL_NAME (msymbol)[0] == DEPRECATED_SYMBOL_NAME (sym)[0] && + strcmp (DEPRECATED_SYMBOL_NAME (msymbol) + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0) { - - struct alias_list *aliases; - /* Splice this symbol out of the hash chain and assign the value we have to it. */ if (prev) @@ -5156,38 +4295,21 @@ scan_file_globals (struct objfile *objfile) /* Check to see whether we need to fix up a common block. */ /* Note: this code might be executed several times for the same symbol if there are multiple references. */ - - /* If symbol has aliases, do minimal symbol fixups for each. - These live aliases/references weren't added to - global_sym_chain hash but may also need to be fixed up. */ - /* FIXME: Maybe should have added aliases to the global chain, resolved symbol name, then treated aliases as normal - symbols? Still, we wouldn't want to add_to_list. */ - /* Now do the same for each alias of this symbol */ - rsym = sym; - aliases = SYMBOL_ALIASES (sym); - while (rsym) + if (sym) { - if (SYMBOL_CLASS (rsym) == LOC_BLOCK) + if (SYMBOL_CLASS (sym) == LOC_BLOCK) { - fix_common_block (rsym, + fix_common_block (sym, SYMBOL_VALUE_ADDRESS (msymbol)); } else { - SYMBOL_VALUE_ADDRESS (rsym) + SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol); } - SYMBOL_SECTION (rsym) = SYMBOL_SECTION (msymbol); - if (aliases) - { - rsym = aliases->sym; - aliases = aliases->next; - } - else - rsym = NULL; + SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol); } - if (prev) { sym = SYMBOL_VALUE_CHAIN (prev); @@ -5227,8 +4349,9 @@ scan_file_globals (struct objfile *objfile) if (SYMBOL_CLASS (prev) == LOC_STATIC) SYMBOL_CLASS (prev) = LOC_UNRESOLVED; else - complain (&unresolved_sym_chain_complaint, - objfile->name, SYMBOL_NAME (prev)); + complaint (&symfile_complaints, + "%s: common block `%s' from global_sym_chain unresolved", + objfile->name, DEPRECATED_SYMBOL_NAME (prev)); } } memset (global_sym_chain, 0, sizeof (global_sym_chain)); @@ -5268,8 +4391,6 @@ start_stabs (void) /* FIXME: If common_block_name is not already NULL, we should complain(). */ common_block_name = NULL; - - os9k_stabs = 0; } /* Call after end_symtab() */ @@ -5297,6 +4418,32 @@ finish_global_stabs (struct objfile *objfile) } } +/* Find the end of the name, delimited by a ':', but don't match + ObjC symbols which look like -[Foo bar::]:bla. */ +static char * +find_name_end (char *name) +{ + char *s = name; + if (s[0] == '-' || *s == '+') + { + /* Must be an ObjC method symbol. */ + if (s[1] != '[') + { + error ("invalid symbol name \"%s\"", name); + } + s = strchr (s, ']'); + if (s == NULL) + { + error ("invalid symbol name \"%s\"", name); + } + return strchr (s, ':'); + } + else + { + return strchr (s, ':'); + } +} + /* Initializer for this module */ void diff --git a/contrib/gdb/gdb/stabsread.h b/contrib/gdb/gdb/stabsread.h index 59504da552b..531f9a1f000 100644 --- a/contrib/gdb/gdb/stabsread.h +++ b/contrib/gdb/gdb/stabsread.h @@ -1,6 +1,6 @@ /* Include file for stabs debugging format support functions. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1999, 2000 Free Software Foundation, Inc. + 1996, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -19,6 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +struct objfile; + /* Definitions, prototypes, etc for stabs debugging format support functions. @@ -128,19 +130,10 @@ EXTERN int n_this_object_header_files; EXTERN int n_allocated_this_object_header_files; -extern struct complaint unknown_symtype_complaint; -extern struct complaint unknown_symchar_complaint; - -extern struct type *read_type (char **, struct objfile *); - extern void cleanup_undefined_types (void); -extern struct type **dbx_lookup_type (int[2]); - extern long read_number (char **, int); -extern void add_undefined_type (struct type *); - extern struct symbol *define_symbol (CORE_ADDR, char *, int, int, struct objfile *); @@ -154,9 +147,6 @@ extern void end_stabs (void); extern void finish_global_stabs (struct objfile *objfile); - -EXTERN int os9k_stabs; - /* COFF files can have multiple .stab sections, if they are linked using --split-by-reloc. This linked list is used to pass the information into the functions in dbxread.c. */ @@ -182,15 +172,14 @@ extern struct partial_symtab *end_psymtab (struct partial_symtab *pst, int number_dependencies, int textlow_not_set); -extern void -process_one_symbol (int, int, CORE_ADDR, char *, - struct section_offsets *, struct objfile *); +extern void process_one_symbol (int, int, CORE_ADDR, char *, + struct section_offsets *, struct objfile *); -extern void elfstab_build_psymtabs - (struct objfile *objfile, - int mainline, - file_ptr staboff, unsigned int stabsize, - file_ptr stabstroffset, unsigned int stabstrsize); +extern void elfstab_build_psymtabs (struct objfile *objfile, + int mainline, + asection *stabsect, + file_ptr stabstroffset, + unsigned int stabstrsize); extern void coffstab_build_psymtabs (struct objfile *objfile, @@ -205,20 +194,12 @@ extern void stabsect_build_psymtabs extern void elfstab_offset_sections (struct objfile *, struct partial_symtab *); - -extern void process_later - (struct symbol *, char *, - int (*f) (struct objfile *, struct symbol *, char *)); - extern int symbol_reference_defined (char **); extern void ref_add (int, struct symbol *, char *, CORE_ADDR); extern struct symbol *ref_search (int); -extern int resolve_cfront_continuation - (struct objfile *objfile, struct symbol *sym, char *p); - extern void free_header_files (void); extern void init_header_files (void); diff --git a/contrib/gdb/gdb/stack.c b/contrib/gdb/gdb/stack.c index 68f16b653c3..18d9a7c303e 100644 --- a/contrib/gdb/gdb/stack.c +++ b/contrib/gdb/gdb/stack.c @@ -1,8 +1,8 @@ /* Print and select stack frames for GDB, the GNU debugger. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Software Foundation, Inc. This file is part of GDB. @@ -33,11 +33,18 @@ #include "gdbcmd.h" #include "gdbcore.h" #include "target.h" +#include "source.h" #include "breakpoint.h" #include "demangle.h" #include "inferior.h" #include "annotate.h" #include "ui-out.h" +#include "block.h" +#include "stack.h" +#include "gdb_assert.h" +#include "dictionary.h" +#include "reggroups.h" +#include "regcache.h" /* Prototypes for exported functions. */ @@ -51,8 +58,6 @@ void _initialize_stack (void); /* Prototypes for local functions. */ -static void return_command (char *, int); - static void down_command (char *, int); static void down_silently_base (char *); @@ -69,8 +74,6 @@ void frame_command (char *, int); static void current_frame_command (char *, int); -static void select_frame_command (char *, int); - static void print_frame_arg_vars (struct frame_info *, struct ui_file *); static void catch_info (char *, int); @@ -97,10 +100,6 @@ static void print_frame (struct frame_info *fi, int args, struct symtab_and_line sal); -static void print_frame_info_base (struct frame_info *, int, int, int); - -static void print_stack_frame_base (struct frame_info *, int, int); - static void backtrace_command (char *, int); struct frame_info *parse_frame_specification (char *); @@ -108,18 +107,6 @@ struct frame_info *parse_frame_specification (char *); static void frame_info (char *, int); extern int addressprint; /* Print addresses, or stay symbolic only? */ -extern int lines_to_list; /* # of lines "list" command shows by default */ - -/* The "selected" stack frame is used by default for local and arg access. - May be zero, for no selected frame. */ - -struct frame_info *selected_frame; - -/* Level of the selected frame: - 0 for innermost, 1 for its caller, ... - or -1 for frame specified by address with no defined level. */ - -int selected_frame_level; /* Zero means do things normally; we are interacting directly with the user. One means print the full filename and linenumber when a @@ -138,21 +125,6 @@ struct print_stack_frame_args int args; }; -static int print_stack_frame_base_stub (char *); - -/* Show and print the frame arguments. - Pass the args the way catch_errors wants them. */ -static int show_and_print_stack_frame_stub (void *args); -static int -show_and_print_stack_frame_stub (void *args) -{ - struct print_stack_frame_args *p = (struct print_stack_frame_args *) args; - - print_frame_info (p->fi, p->level, p->source, p->args); - - return 0; -} - /* Show or print the frame arguments. Pass the args the way catch_errors wants them. */ static int print_stack_frame_stub (void *args); @@ -161,83 +133,10 @@ print_stack_frame_stub (void *args) { struct print_stack_frame_args *p = (struct print_stack_frame_args *) args; - print_frame_info_base (p->fi, p->level, p->source, p->args); + print_frame_info (p->fi, p->level, p->source, p->args); return 0; } -/* Print a stack frame briefly. FRAME_INFI should be the frame info - and LEVEL should be its level in the stack (or -1 for level not - defined). */ - -/* Pass the args the way catch_errors wants them. */ -static int -print_stack_frame_base_stub (char *args) -{ - struct print_stack_frame_args *p = (struct print_stack_frame_args *) args; - - print_frame_info_base (p->fi, p->level, p->source, p->args); - return 0; -} - -/* print the frame arguments to the terminal. - Pass the args the way catch_errors wants them. */ -static int print_only_stack_frame_stub (void *); -static int -print_only_stack_frame_stub (void *args) -{ - struct print_stack_frame_args *p = (struct print_stack_frame_args *) args; - - print_frame_info_base (p->fi, p->level, p->source, p->args); - return 0; -} - -/* Print a stack frame briefly. FRAME_INFI should be the frame info - and LEVEL should be its level in the stack (or -1 for level not defined). - This prints the level, the function executing, the arguments, - and the file name and line number. - If the pc is not at the beginning of the source line, - the actual pc is printed at the beginning. - - If SOURCE is 1, print the source line as well. - If SOURCE is -1, print ONLY the source line. */ - -static void -print_stack_frame_base (struct frame_info *fi, int level, int source) -{ - struct print_stack_frame_args args; - - args.fi = fi; - args.level = level; - args.source = source; - args.args = 1; - - catch_errors (print_stack_frame_stub, &args, "", RETURN_MASK_ALL); -} - -/* Show and print a stack frame briefly. FRAME_INFI should be the frame info - and LEVEL should be its level in the stack (or -1 for level not defined). - This prints the level, the function executing, the arguments, - and the file name and line number. - If the pc is not at the beginning of the source line, - the actual pc is printed at the beginning. - - If SOURCE is 1, print the source line as well. - If SOURCE is -1, print ONLY the source line. */ - -void -show_and_print_stack_frame (struct frame_info *fi, int level, int source) -{ - struct print_stack_frame_args args; - - args.fi = fi; - args.level = level; - args.source = source; - args.args = 1; - - catch_errors (show_and_print_stack_frame_stub, &args, "", RETURN_MASK_ALL); -} - - /* Show or print a stack frame briefly. FRAME_INFI should be the frame info and LEVEL should be its level in the stack (or -1 for level not defined). This prints the level, the function executing, the arguments, @@ -259,30 +158,7 @@ print_stack_frame (struct frame_info *fi, int level, int source) args.args = 1; catch_errors (print_stack_frame_stub, (char *) &args, "", RETURN_MASK_ALL); -} - -/* Print a stack frame briefly. FRAME_INFI should be the frame info - and LEVEL should be its level in the stack (or -1 for level not defined). - This prints the level, the function executing, the arguments, - and the file name and line number. - If the pc is not at the beginning of the source line, - the actual pc is printed at the beginning. - - If SOURCE is 1, print the source line as well. - If SOURCE is -1, print ONLY the source line. */ - -void -print_only_stack_frame (struct frame_info *fi, int level, int source) -{ - struct print_stack_frame_args args; - - args.fi = fi; - args.level = level; - args.source = source; - args.args = 1; - - catch_errors (print_only_stack_frame_stub, &args, "", RETURN_MASK_ALL); -} +} struct print_args_args { @@ -291,17 +167,242 @@ struct print_args_args struct ui_file *stream; }; -static int print_args_stub (PTR); +static int print_args_stub (void *); + +/* Print nameless args on STREAM. + FI is the frameinfo for this frame, START is the offset + of the first nameless arg, and NUM is the number of nameless args to + print. FIRST is nonzero if this is the first argument (not just + the first nameless arg). */ + +static void +print_frame_nameless_args (struct frame_info *fi, long start, int num, + int first, struct ui_file *stream) +{ + int i; + CORE_ADDR argsaddr; + long arg_value; + + for (i = 0; i < num; i++) + { + QUIT; + argsaddr = get_frame_args_address (fi); + if (!argsaddr) + return; + arg_value = read_memory_integer (argsaddr + start, sizeof (int)); + if (!first) + fprintf_filtered (stream, ", "); + fprintf_filtered (stream, "%ld", arg_value); + first = 0; + start += sizeof (int); + } +} + +/* Print the arguments of a stack frame, given the function FUNC + running in that frame (as a symbol), the info on the frame, + and the number of args according to the stack frame (or -1 if unknown). */ + +/* References here and elsewhere to "number of args according to the + stack frame" appear in all cases to refer to "number of ints of args + according to the stack frame". At least for VAX, i386, isi. */ + +static void +print_frame_args (struct symbol *func, struct frame_info *fi, int num, + struct ui_file *stream) +{ + struct block *b = NULL; + int first = 1; + struct dict_iterator iter; + struct symbol *sym; + struct value *val; + /* Offset of next stack argument beyond the one we have seen that is + at the highest offset. + -1 if we haven't come to a stack argument yet. */ + long highest_offset = -1; + int arg_size; + /* Number of ints of arguments that we have printed so far. */ + int args_printed = 0; + struct cleanup *old_chain, *list_chain; + struct ui_stream *stb; + + stb = ui_out_stream_new (uiout); + old_chain = make_cleanup_ui_out_stream_delete (stb); + + if (func) + { + b = SYMBOL_BLOCK_VALUE (func); + + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + QUIT; + + /* Keep track of the highest stack argument offset seen, and + skip over any kinds of symbols we don't care about. */ + + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: + case LOC_REF_ARG: + { + long current_offset = SYMBOL_VALUE (sym); + arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym)); + + /* Compute address of next argument by adding the size of + this argument and rounding to an int boundary. */ + current_offset = + ((current_offset + arg_size + sizeof (int) - 1) + & ~(sizeof (int) - 1)); + + /* If this is the highest offset seen yet, set highest_offset. */ + if (highest_offset == -1 + || (current_offset > highest_offset)) + highest_offset = current_offset; + + /* Add the number of ints we're about to print to args_printed. */ + args_printed += (arg_size + sizeof (int) - 1) / sizeof (int); + } + + /* We care about types of symbols, but don't need to keep track of + stack offsets in them. */ + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL_ARG: + case LOC_BASEREG_ARG: + case LOC_COMPUTED_ARG: + break; + + /* Other types of symbols we just skip over. */ + default: + continue; + } + + /* We have to look up the symbol because arguments can have + two entries (one a parameter, one a local) and the one we + want is the local, which lookup_symbol will find for us. + This includes gcc1 (not gcc2) on the sparc when passing a + small structure and gcc2 when the argument type is float + and it is passed as a double and converted to float by + the prologue (in the latter case the type of the LOC_ARG + symbol is double and the type of the LOC_LOCAL symbol is + float). */ + /* But if the parameter name is null, don't try it. + Null parameter names occur on the RS/6000, for traceback tables. + FIXME, should we even print them? */ + + if (*DEPRECATED_SYMBOL_NAME (sym)) + { + struct symbol *nsym; + nsym = lookup_symbol + (DEPRECATED_SYMBOL_NAME (sym), + b, VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); + if (SYMBOL_CLASS (nsym) == LOC_REGISTER) + { + /* There is a LOC_ARG/LOC_REGISTER pair. This means that + it was passed on the stack and loaded into a register, + or passed in a register and stored in a stack slot. + GDB 3.x used the LOC_ARG; GDB 4.0-4.11 used the LOC_REGISTER. + + Reasons for using the LOC_ARG: + (1) because find_saved_registers may be slow for remote + debugging, + (2) because registers are often re-used and stack slots + rarely (never?) are. Therefore using the stack slot is + much less likely to print garbage. + + Reasons why we might want to use the LOC_REGISTER: + (1) So that the backtrace prints the same value as + "print foo". I see no compelling reason why this needs + to be the case; having the backtrace print the value which + was passed in, and "print foo" print the value as modified + within the called function, makes perfect sense to me. + + Additional note: It might be nice if "info args" displayed + both values. + One more note: There is a case with sparc structure passing + where we need to use the LOC_REGISTER, but this is dealt with + by creating a single LOC_REGPARM in symbol reading. */ + + /* Leave sym (the LOC_ARG) alone. */ + ; + } + else + sym = nsym; + } + + /* Print the current arg. */ + if (!first) + ui_out_text (uiout, ", "); + ui_out_wrap_hint (uiout, " "); + + annotate_arg_begin (); + + list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (sym), + SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI); + ui_out_field_stream (uiout, "name", stb); + annotate_arg_name_end (); + ui_out_text (uiout, "="); + + /* Avoid value_print because it will deref ref parameters. We just + want to print their addresses. Print ??? for args whose address + we do not know. We pass 2 as "recurse" to val_print because our + standard indentation here is 4 spaces, and val_print indents + 2 for each recurse. */ + val = read_var_value (sym, fi); + + annotate_arg_value (val == NULL ? NULL : VALUE_TYPE (val)); + + if (val) + { + val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0, + VALUE_ADDRESS (val), + stb->stream, 0, 0, 2, Val_no_prettyprint); + ui_out_field_stream (uiout, "value", stb); + } + else + ui_out_text (uiout, "???"); + + /* Invoke ui_out_tuple_end. */ + do_cleanups (list_chain); + + annotate_arg_end (); + + first = 0; + } + } + + /* Don't print nameless args in situations where we don't know + enough about the stack to find them. */ + if (num != -1) + { + long start; + + if (highest_offset == -1) + start = FRAME_ARGS_SKIP; + else + start = highest_offset; + + print_frame_nameless_args (fi, start, num - args_printed, + first, stream); + } + do_cleanups (old_chain); +} /* Pass the args the way catch_errors wants them. */ static int -print_args_stub (PTR args) +print_args_stub (void *args) { int numargs; struct print_args_args *p = (struct print_args_args *) args; - numargs = FRAME_NUM_ARGS (p->fi); + if (FRAME_NUM_ARGS_P ()) + { + numargs = FRAME_NUM_ARGS (p->fi); + gdb_assert (numargs >= 0); + } + else + numargs = -1; print_frame_args (p->func, p->fi, numargs, p->stream); return 0; } @@ -316,69 +417,59 @@ print_args_stub (PTR args) LOCATION: Print only location LOC_AND_SRC: Print location and source line. */ -static void -print_frame_info_base (struct frame_info *fi, int level, int source, int args) +void +print_frame_info (struct frame_info *fi, int level, int source, int args) { struct symtab_and_line sal; int source_print; int location_print; -#if 0 - char buf[MAX_REGISTER_RAW_SIZE]; - CORE_ADDR sp; - - /* On the 68k, this spends too much time in m68k_find_saved_regs. */ - - /* Get the value of SP_REGNUM relative to the frame. */ - get_saved_register (buf, (int *) NULL, (CORE_ADDR *) NULL, - FRAME_INFO_ID (fi), SP_REGNUM, (enum lval_type *) NULL); - sp = extract_address (buf, REGISTER_RAW_SIZE (SP_REGNUM)); - - /* This is not a perfect test, because if a function alloca's some - memory, puts some code there, and then jumps into it, then the test - will succeed even though there is no call dummy. Probably best is - to check for a bp_call_dummy breakpoint. */ - if (PC_IN_CALL_DUMMY (fi->pc, sp, fi->frame)) -#else - if (frame_in_dummy (fi)) -#endif + if (get_frame_type (fi) == DUMMY_FRAME + || get_frame_type (fi) == SIGTRAMP_FRAME) { - annotate_frame_begin (level == -1 ? 0 : level, fi->pc); + struct cleanup *uiout_cleanup + = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); + + annotate_frame_begin (level == -1 ? 0 : level, get_frame_pc (fi)); /* Do this regardless of SOURCE because we don't have any source to list for this frame. */ if (level >= 0) - printf_filtered ("#%-2d ", level); - annotate_function_call (); - printf_filtered ("\n"); - annotate_frame_end (); - return; - } - if (fi->signal_handler_caller) - { - annotate_frame_begin (level == -1 ? 0 : level, fi->pc); + { + ui_out_text (uiout, "#"); + ui_out_field_fmt_int (uiout, 2, ui_left, "level", level); + } + if (ui_out_is_mi_like_p (uiout)) + { + annotate_frame_address (); + ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi)); + annotate_frame_address_end (); + } - /* Do this regardless of SOURCE because we don't have any source - to list for this frame. */ - if (level >= 0) - printf_filtered ("#%-2d ", level); - annotate_signal_handler_caller (); - printf_filtered ("\n"); + if (get_frame_type (fi) == DUMMY_FRAME) + { + annotate_function_call (); + ui_out_field_string (uiout, "func", ""); + } + else if (get_frame_type (fi) == SIGTRAMP_FRAME) + { + annotate_signal_handler_caller (); + ui_out_field_string (uiout, "func", ""); + } + ui_out_text (uiout, "\n"); annotate_frame_end (); + + do_cleanups (uiout_cleanup); return; } /* If fi is not the innermost frame, that normally means that fi->pc - points to *after* the call instruction, and we want to get the line - containing the call, never the next line. But if the next frame is - a signal_handler_caller or a dummy frame, then the next frame was - not entered as the result of a call, and we want to get the line - containing fi->pc. */ - sal = - find_pc_line (fi->pc, - fi->next != NULL - && !fi->next->signal_handler_caller - && !frame_in_dummy (fi->next)); + points to *after* the call instruction, and we want to get the + line containing the call, never the next line. But if the next + frame is a SIGTRAMP_FRAME or a DUMMY_FRAME, then the next frame + was not entered as the result of a call, and we want to get the + line containing fi->pc. */ + find_frame_sal (fi, &sal); location_print = (source == LOCATION || source == LOC_AND_ADDRESS @@ -389,21 +480,22 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args) source_print = (source == SRC_LINE || source == SRC_AND_LOC); + if (sal.symtab) + set_current_source_symtab_and_line (&sal); + if (source_print && sal.symtab) { + struct symtab_and_line cursal; int done = 0; - int mid_statement = (source == SRC_LINE) && (fi->pc != sal.pc); + int mid_statement = (source == SRC_LINE) && (get_frame_pc (fi) != sal.pc); if (annotation_level) done = identify_source_line (sal.symtab, sal.line, mid_statement, - fi->pc); + get_frame_pc (fi)); if (!done) { if (print_frame_info_listing_hook) - { - print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0); - current_source_symtab = sal.symtab; - } + print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0); else { /* We used to do this earlier, but that is clearly @@ -416,18 +508,22 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args) ability to decide for themselves if it is desired. */ if (addressprint && mid_statement) { - ui_out_field_core_addr (uiout, "addr", fi->pc); + ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi)); ui_out_text (uiout, "\t"); } print_source_lines (sal.symtab, sal.line, sal.line + 1, 0); } } - current_source_line = max (sal.line - lines_to_list / 2, 1); + /* Make sure we have at least a default source file */ + set_default_source_symtab_and_line (); + cursal = get_current_source_symtab_and_line (); + cursal.line = max (sal.line - get_lines_to_list () / 2, 1); + set_current_source_symtab_and_line (&cursal); } if (source != 0) - set_default_breakpoint (1, fi->pc, sal.symtab, sal.line); + set_default_breakpoint (1, get_frame_pc (fi), sal.symtab, sal.line); annotate_frame_end (); @@ -442,7 +538,7 @@ print_frame (struct frame_info *fi, struct symtab_and_line sal) { struct symbol *func; - register char *funname = 0; + char *funname = 0; enum language funlang = language_unknown; struct ui_stream *stb; struct cleanup *old_chain; @@ -451,7 +547,7 @@ print_frame (struct frame_info *fi, stb = ui_out_stream_new (uiout); old_chain = make_cleanup_ui_out_stream_delete (stb); - func = find_pc_function (fi->pc); + func = find_pc_function (get_frame_address_in_block (fi)); if (func) { /* In certain pathological cases, the symtabs give the wrong @@ -470,7 +566,7 @@ print_frame (struct frame_info *fi, ever changed many parts of GDB will need to be changed (and we'll create a find_pc_minimal_function or some such). */ - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_address_in_block (fi)); if (msymbol != NULL && (SYMBOL_VALUE_ADDRESS (msymbol) > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) @@ -486,12 +582,12 @@ print_frame (struct frame_info *fi, /* We also don't know anything about the function besides its address and name. */ func = 0; - funname = SYMBOL_NAME (msymbol); + funname = DEPRECATED_SYMBOL_NAME (msymbol); funlang = SYMBOL_LANGUAGE (msymbol); } else { - /* I'd like to use SYMBOL_SOURCE_NAME() here, to display the + /* I'd like to use SYMBOL_PRINT_NAME() here, to display the demangled name that we already have stored in the symbol table, but we stored a version with DMGL_PARAMS turned on, and here we don't want to display parameters. So call @@ -503,7 +599,7 @@ print_frame (struct frame_info *fi, here, while we still have our hands on the function symbol.) */ char *demangled; - funname = SYMBOL_NAME (func); + funname = DEPRECATED_SYMBOL_NAME (func); funlang = SYMBOL_LANGUAGE (func); if (funlang == language_cplus) { @@ -512,35 +608,36 @@ print_frame (struct frame_info *fi, /* If the demangler fails, try the demangled name from the symbol table. This'll have parameters, but that's preferable to diplaying a mangled name. */ - funname = SYMBOL_SOURCE_NAME (func); + funname = SYMBOL_PRINT_NAME (func); } } } else { - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_address_in_block (fi)); if (msymbol != NULL) { - funname = SYMBOL_NAME (msymbol); + funname = DEPRECATED_SYMBOL_NAME (msymbol); funlang = SYMBOL_LANGUAGE (msymbol); } } - annotate_frame_begin (level == -1 ? 0 : level, fi->pc); + annotate_frame_begin (level == -1 ? 0 : level, get_frame_pc (fi)); list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); if (level >= 0) { ui_out_text (uiout, "#"); - ui_out_field_fmt (uiout, "level", "%-2d", level); - ui_out_spaces (uiout, 1); + ui_out_field_fmt_int (uiout, 2, ui_left, "level", level); } if (addressprint) - if (fi->pc != sal.pc || !sal.symtab || source == LOC_AND_ADDRESS) + if (get_frame_pc (fi) != sal.pc + || !sal.symtab + || source == LOC_AND_ADDRESS) { annotate_frame_address (); - ui_out_field_core_addr (uiout, "addr", fi->pc); + ui_out_field_core_addr (uiout, "addr", get_frame_pc (fi)); annotate_frame_address_end (); ui_out_text (uiout, " in "); } @@ -585,7 +682,7 @@ print_frame (struct frame_info *fi, #ifdef PC_SOLIB if (!funname || (!sal.symtab || !sal.symtab->filename)) { - char *lib = PC_SOLIB (fi->pc); + char *lib = PC_SOLIB (get_frame_pc (fi)); if (lib) { annotate_frame_where (); @@ -602,16 +699,6 @@ print_frame (struct frame_info *fi, do_cleanups (old_chain); } - -/* Show or print the frame info. If this is the tui, it will be shown in - the source display */ -void -print_frame_info (struct frame_info *fi, register int level, int source, - int args) -{ - print_frame_info_base (fi, level, source, args); -} - /* Show the frame info. If this is the tui, it will be shown in the source display otherwise, nothing is done */ void @@ -677,9 +764,9 @@ parse_frame_specification (char *frame_exp) switch (numargs) { case 0: - if (selected_frame == NULL) + if (deprecated_selected_frame == NULL) error ("No selected frame."); - return selected_frame; + return deprecated_selected_frame; /* NOTREACHED */ case 1: { @@ -704,20 +791,20 @@ parse_frame_specification (char *frame_exp) really should be used instead of spaces to delimit; using spaces normally works in an expression). */ #ifdef SETUP_ARBITRARY_FRAME - error ("No frame %d", args[0]); + error ("No frame %s", paddr_d (args[0])); #endif /* If (s)he specifies the frame with an address, he deserves what (s)he gets. Still, give the highest one that matches. */ for (fid = get_current_frame (); - fid && fid->frame != args[0]; + fid && get_frame_base (fid) != args[0]; fid = get_prev_frame (fid)) ; if (fid) while ((tfid = get_prev_frame (fid)) && - (tfid->frame == args[0])) + (get_frame_base (tfid) == args[0])) fid = tfid; /* We couldn't identify the frame as an existing frame, but @@ -739,16 +826,6 @@ parse_frame_specification (char *frame_exp) /* NOTREACHED */ } -/* FRAME_ARGS_ADDRESS_CORRECT is just like FRAME_ARGS_ADDRESS except - that if it is unsure about the answer, it returns 0 - instead of guessing (this happens on the VAX and i960, for example). - - On most machines, we never have to guess about the args address, - so FRAME_ARGS_ADDRESS{,_CORRECT} are the same. */ -#if !defined (FRAME_ARGS_ADDRESS_CORRECT) -#define FRAME_ARGS_ADDRESS_CORRECT FRAME_ARGS_ADDRESS -#endif - /* Print verbosely the selected frame or the frame at address ADDR. This means absolutely all information in the frame is printed. */ @@ -763,23 +840,37 @@ frame_info (char *addr_exp, int from_tty) int i, count, numregs; char *funname = 0; enum language funlang = language_unknown; + const char *pc_regname; if (!target_has_stack) error ("No stack."); + /* Name of the value returned by get_frame_pc(). Per comments, "pc" + is not a good name. */ + if (PC_REGNUM >= 0) + /* OK, this is weird. The PC_REGNUM hardware register's value can + easily not match that of the internal value returned by + get_frame_pc(). */ + pc_regname = REGISTER_NAME (PC_REGNUM); + else + /* But then, this is weird to. Even without PC_REGNUM, an + architectures will often have a hardware register called "pc", + and that register's value, again, can easily not match + get_frame_pc(). */ + pc_regname = "pc"; + fi = parse_frame_specification (addr_exp); if (fi == NULL) error ("Invalid frame specified."); - sal = find_pc_line (fi->pc, - fi->next != NULL - && !fi->next->signal_handler_caller - && !frame_in_dummy (fi->next)); + find_frame_sal (fi, &sal); func = get_frame_function (fi); - s = find_pc_symtab (fi->pc); + /* FIXME: cagney/2002-11-28: Why bother? Won't sal.symtab contain + the same value. */ + s = find_pc_symtab (get_frame_pc (fi)); if (func) { - /* I'd like to use SYMBOL_SOURCE_NAME() here, to display + /* I'd like to use SYMBOL_PRINT_NAME() here, to display * the demangled name that we already have stored in * the symbol table, but we stored a version with * DMGL_PARAMS turned on, and here we don't want @@ -793,7 +884,7 @@ frame_info (char *addr_exp, int from_tty) * have our hands on the function symbol.) */ char *demangled; - funname = SYMBOL_NAME (func); + funname = DEPRECATED_SYMBOL_NAME (func); funlang = SYMBOL_LANGUAGE (func); if (funlang == language_cplus) { @@ -803,34 +894,35 @@ frame_info (char *addr_exp, int from_tty) * but that's preferable to diplaying a mangled name. */ if (demangled == NULL) - funname = SYMBOL_SOURCE_NAME (func); + funname = SYMBOL_PRINT_NAME (func); } } else { - register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_pc (fi)); if (msymbol != NULL) { - funname = SYMBOL_NAME (msymbol); + funname = DEPRECATED_SYMBOL_NAME (msymbol); funlang = SYMBOL_LANGUAGE (msymbol); } } calling_frame_info = get_prev_frame (fi); - if (!addr_exp && selected_frame_level >= 0) + if (!addr_exp && frame_relative_level (deprecated_selected_frame) >= 0) { - printf_filtered ("Stack level %d, frame at ", selected_frame_level); - print_address_numeric (fi->frame, 1, gdb_stdout); + printf_filtered ("Stack level %d, frame at ", + frame_relative_level (deprecated_selected_frame)); + print_address_numeric (get_frame_base (fi), 1, gdb_stdout); printf_filtered (":\n"); } else { printf_filtered ("Stack frame at "); - print_address_numeric (fi->frame, 1, gdb_stdout); + print_address_numeric (get_frame_base (fi), 1, gdb_stdout); printf_filtered (":\n"); } - printf_filtered (" %s = ", REGISTER_NAME (PC_REGNUM)); - print_address_numeric (fi->pc, 1, gdb_stdout); + printf_filtered (" %s = ", pc_regname); + print_address_numeric (get_frame_pc (fi), 1, gdb_stdout); wrap_here (" "); if (funname) @@ -844,13 +936,14 @@ frame_info (char *addr_exp, int from_tty) printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line); puts_filtered ("; "); wrap_here (" "); - printf_filtered ("saved %s ", REGISTER_NAME (PC_REGNUM)); - print_address_numeric (FRAME_SAVED_PC (fi), 1, gdb_stdout); + printf_filtered ("saved %s ", pc_regname); + print_address_numeric (frame_pc_unwind (fi), 1, gdb_stdout); printf_filtered ("\n"); { int frameless; - frameless = FRAMELESS_FUNCTION_INVOCATION (fi); + frameless = (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P () + && DEPRECATED_FRAMELESS_FUNCTION_INVOCATION (fi)); if (frameless) printf_filtered (" (FRAMELESS),"); } @@ -858,28 +951,27 @@ frame_info (char *addr_exp, int from_tty) if (calling_frame_info) { printf_filtered (" called by frame at "); - print_address_numeric (calling_frame_info->frame, 1, gdb_stdout); + print_address_numeric (get_frame_base (calling_frame_info), + 1, gdb_stdout); } - if (fi->next && calling_frame_info) + if (get_next_frame (fi) && calling_frame_info) puts_filtered (","); wrap_here (" "); - if (fi->next) + if (get_next_frame (fi)) { printf_filtered (" caller of frame at "); - print_address_numeric (fi->next->frame, 1, gdb_stdout); + print_address_numeric (get_frame_base (get_next_frame (fi)), 1, + gdb_stdout); } - if (fi->next || calling_frame_info) + if (get_next_frame (fi) || calling_frame_info) puts_filtered ("\n"); if (s) - printf_filtered (" source language %s.\n", language_str (s->language)); - -#ifdef PRINT_EXTRA_FRAME_INFO - PRINT_EXTRA_FRAME_INFO (fi); -#endif + printf_filtered (" source language %s.\n", + language_str (s->language)); { /* Address of the argument list for this frame, or 0. */ - CORE_ADDR arg_list = FRAME_ARGS_ADDRESS_CORRECT (fi); + CORE_ADDR arg_list = get_frame_args_address (fi); /* Number of args for this frame, or -1 if unknown. */ int numargs; @@ -891,22 +983,29 @@ frame_info (char *addr_exp, int from_tty) print_address_numeric (arg_list, 1, gdb_stdout); printf_filtered (","); - numargs = FRAME_NUM_ARGS (fi); - if (numargs < 0) - puts_filtered (" args: "); - else if (numargs == 0) - puts_filtered (" no args."); - else if (numargs == 1) - puts_filtered (" 1 arg: "); + if (!FRAME_NUM_ARGS_P ()) + { + numargs = -1; + puts_filtered (" args: "); + } else - printf_filtered (" %d args: ", numargs); + { + numargs = FRAME_NUM_ARGS (fi); + gdb_assert (numargs >= 0); + if (numargs == 0) + puts_filtered (" no args."); + else if (numargs == 1) + puts_filtered (" 1 arg: "); + else + printf_filtered (" %d args: ", numargs); + } print_frame_args (func, fi, numargs, gdb_stdout); puts_filtered ("\n"); } } { /* Address of the local variables for this frame, or 0. */ - CORE_ADDR arg_list = FRAME_LOCALS_ADDRESS (fi); + CORE_ADDR arg_list = get_frame_locals_address (fi); if (arg_list == 0) printf_filtered (" Locals at unknown address,"); @@ -918,39 +1017,89 @@ frame_info (char *addr_exp, int from_tty) } } - FRAME_INIT_SAVED_REGS (fi); - if (fi->saved_regs != NULL) - { - /* The sp is special; what's returned isn't the save address, but - actually the value of the previous frame's sp. */ - printf_filtered (" Previous frame's sp is "); - print_address_numeric (fi->saved_regs[SP_REGNUM], 1, gdb_stdout); - printf_filtered ("\n"); - count = 0; - numregs = NUM_REGS + NUM_PSEUDO_REGS; - for (i = 0; i < numregs; i++) - if (fi->saved_regs[i] && i != SP_REGNUM) + if (DEPRECATED_FRAME_INIT_SAVED_REGS_P () + && deprecated_get_frame_saved_regs (fi) == NULL) + DEPRECATED_FRAME_INIT_SAVED_REGS (fi); + /* Print as much information as possible on the location of all the + registers. */ + { + enum lval_type lval; + int optimized; + CORE_ADDR addr; + int realnum; + int count; + int i; + int need_nl = 1; + + /* The sp is special; what's displayed isn't the save address, but + the value of the previous frame's sp. This is a legacy thing, + at one stage the frame cached the previous frame's SP instead + of its address, hence it was easiest to just display the cached + value. */ + if (SP_REGNUM >= 0) + { + /* Find out the location of the saved stack pointer with out + actually evaluating it. */ + frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr, + &realnum, NULL); + if (!optimized && lval == not_lval) { - if (count == 0) - puts_filtered (" Saved registers:\n "); - else - puts_filtered (","); - wrap_here (" "); - printf_filtered (" %s at ", REGISTER_NAME (i)); - print_address_numeric (fi->saved_regs[i], 1, gdb_stdout); - count++; + char value[MAX_REGISTER_SIZE]; + CORE_ADDR sp; + frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr, + &realnum, value); + /* NOTE: cagney/2003-05-22: This is assuming that the + stack pointer was packed as an unsigned integer. That + may or may not be valid. */ + sp = extract_unsigned_integer (value, DEPRECATED_REGISTER_RAW_SIZE (SP_REGNUM)); + printf_filtered (" Previous frame's sp is "); + print_address_numeric (sp, 1, gdb_stdout); + printf_filtered ("\n"); + need_nl = 0; } - if (count) - puts_filtered ("\n"); - } - else - { - /* We could get some information about saved registers by - calling get_saved_register on each register. Which info goes - with which frame is necessarily lost, however, and I suspect - that the users don't care whether they get the info. */ + else if (!optimized && lval == lval_memory) + { + printf_filtered (" Previous frame's sp at "); + print_address_numeric (addr, 1, gdb_stdout); + printf_filtered ("\n"); + need_nl = 0; + } + else if (!optimized && lval == lval_register) + { + printf_filtered (" Previous frame's sp in %s\n", + REGISTER_NAME (realnum)); + need_nl = 0; + } + /* else keep quiet. */ + } + + count = 0; + numregs = NUM_REGS + NUM_PSEUDO_REGS; + for (i = 0; i < numregs; i++) + if (i != SP_REGNUM + && gdbarch_register_reggroup_p (current_gdbarch, i, all_reggroup)) + { + /* Find out the location of the saved register without + fetching the corresponding value. */ + frame_register_unwind (fi, i, &optimized, &lval, &addr, &realnum, + NULL); + /* For moment, only display registers that were saved on the + stack. */ + if (!optimized && lval == lval_memory) + { + if (count == 0) + puts_filtered (" Saved registers:\n "); + else + puts_filtered (","); + wrap_here (" "); + printf_filtered (" %s at ", REGISTER_NAME (i)); + print_address_numeric (addr, 1, gdb_stdout); + count++; + } + } + if (count || need_nl) puts_filtered ("\n"); - } + } } #if 0 @@ -988,10 +1137,10 @@ static void backtrace_command_1 (char *count_exp, int show_locals, int from_tty) { struct frame_info *fi; - register int count; - register int i; - register struct frame_info *trailing; - register int trailing_level; + int count; + int i; + struct frame_info *trailing; + int trailing_level; if (!target_has_stack) error ("No stack."); @@ -1055,7 +1204,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) fi = get_prev_frame (fi)) { QUIT; - ps = find_pc_psymtab (fi->pc); + ps = find_pc_psymtab (get_frame_address_in_block (fi)); if (ps) PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in */ } @@ -1071,7 +1220,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) means further attempts to backtrace would fail (on the other hand, perhaps the code does or could be fixed to make sure the frame->prev field gets set to NULL in that case). */ - print_frame_info_base (fi, trailing_level + i, 0, 1); + print_frame_info (fi, trailing_level + i, 0, 1); if (show_locals) print_frame_local_vars (fi, 1, gdb_stdout); } @@ -1158,14 +1307,15 @@ backtrace_full_command (char *arg, int from_tty) Return 1 if any variables were printed; 0 otherwise. */ static int -print_block_frame_locals (struct block *b, register struct frame_info *fi, - int num_tabs, register struct ui_file *stream) +print_block_frame_locals (struct block *b, struct frame_info *fi, + int num_tabs, struct ui_file *stream) { - register int i, j; - register struct symbol *sym; - register int values_printed = 0; + struct dict_iterator iter; + int j; + struct symbol *sym; + int values_printed = 0; - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { switch (SYMBOL_CLASS (sym)) { @@ -1173,10 +1323,11 @@ print_block_frame_locals (struct block *b, register struct frame_info *fi, case LOC_REGISTER: case LOC_STATIC: case LOC_BASEREG: + case LOC_COMPUTED: values_printed = 1; for (j = 0; j < num_tabs; j++) fputs_filtered ("\t", stream); - fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); + fputs_filtered (SYMBOL_PRINT_NAME (sym), stream); fputs_filtered (" = ", stream); print_variable_value (sym, fi, stream); fprintf_filtered (stream, "\n"); @@ -1194,15 +1345,15 @@ print_block_frame_locals (struct block *b, register struct frame_info *fi, static int print_block_frame_labels (struct block *b, int *have_default, - register struct ui_file *stream) + struct ui_file *stream) { - register int i; - register struct symbol *sym; - register int values_printed = 0; + struct dict_iterator iter; + struct symbol *sym; + int values_printed = 0; - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { - if (STREQ (SYMBOL_NAME (sym), "default")) + if (DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (sym), "default")) { if (*have_default) continue; @@ -1213,7 +1364,7 @@ print_block_frame_labels (struct block *b, int *have_default, struct symtab_and_line sal; sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0); values_printed = 1; - fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); + fputs_filtered (SYMBOL_PRINT_NAME (sym), stream); if (addressprint) { fprintf_filtered (stream, " "); @@ -1235,11 +1386,11 @@ print_block_frame_labels (struct block *b, int *have_default, on the function running in FRAME. */ static void -print_frame_local_vars (register struct frame_info *fi, register int num_tabs, - register struct ui_file *stream) +print_frame_local_vars (struct frame_info *fi, int num_tabs, + struct ui_file *stream) { - register struct block *block = get_frame_block (fi); - register int values_printed = 0; + struct block *block = get_frame_block (fi, 0); + int values_printed = 0; if (block == 0) { @@ -1268,15 +1419,15 @@ print_frame_local_vars (register struct frame_info *fi, register int num_tabs, /* Same, but print labels. */ static void -print_frame_label_vars (register struct frame_info *fi, int this_level_only, - register struct ui_file *stream) +print_frame_label_vars (struct frame_info *fi, int this_level_only, + struct ui_file *stream) { - register struct blockvector *bl; - register struct block *block = get_frame_block (fi); - register int values_printed = 0; + struct blockvector *bl; + struct block *block = get_frame_block (fi, 0); + int values_printed = 0; int index, have_default = 0; char *blocks_printed; - CORE_ADDR pc = fi->pc; + CORE_ADDR pc = get_frame_pc (fi); if (block == 0) { @@ -1335,13 +1486,12 @@ print_frame_label_vars (register struct frame_info *fi, int this_level_only, } } -/* ARGSUSED */ void locals_info (char *args, int from_tty) { - if (!selected_frame) + if (!deprecated_selected_frame) error ("No frame selected."); - print_frame_local_vars (selected_frame, 0, gdb_stdout); + print_frame_local_vars (deprecated_selected_frame, 0, gdb_stdout); } static void @@ -1358,29 +1508,29 @@ catch_info (char *ignore, int from_tty) system to find the list of active handlers, etc. */ fprintf_filtered (gdb_stdout, "Info catch not supported with this target/compiler combination.\n"); #if 0 - if (!selected_frame) + if (!deprecated_selected_frame) error ("No frame selected."); #endif } else { /* Assume g++ compiled code -- old v 4.16 behaviour */ - if (!selected_frame) + if (!deprecated_selected_frame) error ("No frame selected."); - print_frame_label_vars (selected_frame, 0, gdb_stdout); + print_frame_label_vars (deprecated_selected_frame, 0, gdb_stdout); } } static void -print_frame_arg_vars (register struct frame_info *fi, - register struct ui_file *stream) +print_frame_arg_vars (struct frame_info *fi, + struct ui_file *stream) { struct symbol *func = get_frame_function (fi); - register struct block *b; - register int i; - register struct symbol *sym, *sym2; - register int values_printed = 0; + struct block *b; + struct dict_iterator iter; + struct symbol *sym, *sym2; + int values_printed = 0; if (func == 0) { @@ -1389,7 +1539,7 @@ print_frame_arg_vars (register struct frame_info *fi, } b = SYMBOL_BLOCK_VALUE (func); - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { switch (SYMBOL_CLASS (sym)) { @@ -1399,8 +1549,9 @@ print_frame_arg_vars (register struct frame_info *fi, case LOC_REGPARM: case LOC_REGPARM_ADDR: case LOC_BASEREG_ARG: + case LOC_COMPUTED_ARG: values_printed = 1; - fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); + fputs_filtered (SYMBOL_PRINT_NAME (sym), stream); fputs_filtered (" = ", stream); /* We have to look up the symbol because arguments can have @@ -1414,8 +1565,8 @@ print_frame_arg_vars (register struct frame_info *fi, float). There are also LOC_ARG/LOC_REGISTER pairs which are not combined in symbol-reading. */ - sym2 = lookup_symbol (SYMBOL_NAME (sym), - b, VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL); + sym2 = lookup_symbol (DEPRECATED_SYMBOL_NAME (sym), + b, VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); print_variable_value (sym2, fi, stream); fprintf_filtered (stream, "\n"); break; @@ -1434,9 +1585,9 @@ print_frame_arg_vars (register struct frame_info *fi, void args_info (char *ignore, int from_tty) { - if (!selected_frame) + if (!deprecated_selected_frame) error ("No frame selected."); - print_frame_arg_vars (selected_frame, gdb_stdout); + print_frame_arg_vars (deprecated_selected_frame, gdb_stdout); } @@ -1448,70 +1599,49 @@ args_plus_locals_info (char *ignore, int from_tty) } -/* Select frame FI, and note that its stack level is LEVEL. - LEVEL may be -1 if an actual level number is not known. */ - -void -select_frame (struct frame_info *fi, int level) +/* Select frame FI. Also print the stack frame and show the source if + this is the tui version. */ +static void +select_and_print_frame (struct frame_info *fi) { - register struct symtab *s; - - selected_frame = fi; - selected_frame_level = level; - if (selected_frame_level_changed_hook) - selected_frame_level_changed_hook (level); - - /* Ensure that symbols for this frame are read in. Also, determine the - source language of this frame, and switch to it if desired. */ + select_frame (fi); if (fi) { - s = find_pc_symtab (fi->pc); - if (s - && s->language != current_language->la_language - && s->language != language_unknown - && language_mode == language_mode_auto) - { - set_language (s->language); - } + print_stack_frame (fi, frame_relative_level (fi), 1); } } - -/* Select frame FI, noting that its stack level is LEVEL. Also print - the stack frame and show the source if this is the tui version. */ -void -select_and_print_frame (struct frame_info *fi, int level) -{ - select_frame (fi, level); - if (fi) - { - print_stack_frame (fi, level, 1); - } -} - - -/* Store the selected frame and its level into *FRAMEP and *LEVELP. - If there is no selected frame, *FRAMEP is set to NULL. */ - -void -record_selected_frame (CORE_ADDR *frameaddrp, int *levelp) -{ - *frameaddrp = selected_frame ? selected_frame->frame : 0; - *levelp = selected_frame_level; -} - /* Return the symbol-block in which the selected frame is executing. - Can return zero under various legitimate circumstances. */ + Can return zero under various legitimate circumstances. + + If ADDR_IN_BLOCK is non-zero, set *ADDR_IN_BLOCK to the relevant + code address within the block returned. We use this to decide + which macros are in scope. */ struct block * -get_selected_block (void) +get_selected_block (CORE_ADDR *addr_in_block) { if (!target_has_stack) return 0; - if (!selected_frame) - return get_current_block (); - return get_frame_block (selected_frame); + /* NOTE: cagney/2002-11-28: Why go to all this effort to not create + a selected/current frame? Perhaphs this function is called, + indirectly, by WFI in "infrun.c" where avoiding the creation of + an inner most frame is very important (it slows down single + step). I suspect, though that this was true in the deep dark + past but is no longer the case. A mindless look at all the + callers tends to support this theory. I think we should be able + to assume that there is always a selcted frame. */ + /* gdb_assert (deprecated_selected_frame != NULL); So, do you feel + lucky? */ + if (!deprecated_selected_frame) + { + CORE_ADDR pc = read_pc (); + if (addr_in_block != NULL) + *addr_in_block = pc; + return block_for_pc (pc); + } + return get_frame_block (deprecated_selected_frame, addr_in_block); } /* Find a frame a certain number of levels away from FRAME. @@ -1524,11 +1654,11 @@ get_selected_block (void) how much farther the original request asked to go. */ struct frame_info * -find_relative_frame (register struct frame_info *frame, - register int *level_offset_ptr) +find_relative_frame (struct frame_info *frame, + int *level_offset_ptr) { - register struct frame_info *prev; - register struct frame_info *frame1; + struct frame_info *prev; + struct frame_info *frame1; /* Going up is simple: just do get_prev_frame enough times or until initial frame is reached. */ @@ -1561,39 +1691,20 @@ find_relative_frame (register struct frame_info *frame, and select it. See parse_frame_specification for more info on proper frame expressions. */ -/* ARGSUSED */ void -select_frame_command_wrapper (char *level_exp, int from_tty) -{ - select_frame_command (level_exp, from_tty); -} - -static void select_frame_command (char *level_exp, int from_tty) { - register struct frame_info *frame, *frame1; - unsigned int level = 0; + struct frame_info *frame; + int level = frame_relative_level (deprecated_selected_frame); if (!target_has_stack) error ("No stack."); frame = parse_frame_specification (level_exp); - /* Try to figure out what level this frame is. But if there is - no current stack, don't error out -- let the user set one. */ - frame1 = 0; - if (get_current_frame ()) - { - for (frame1 = get_prev_frame (0); - frame1 && frame1 != frame; - frame1 = get_prev_frame (frame1)) - level++; - } - - if (!frame1) - level = 0; - - select_frame (frame, level); + select_frame (frame); + if (level != frame_relative_level (deprecated_selected_frame)) + selected_frame_level_changed_event (frame_relative_level (deprecated_selected_frame)); } /* The "frame" command. With no arg, print selected frame briefly. @@ -1604,7 +1715,8 @@ void frame_command (char *level_exp, int from_tty) { select_frame_command (level_exp, from_tty); - show_and_print_stack_frame (selected_frame, selected_frame_level, 1); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); } /* The XDB Compatibility command to print the current frame. */ @@ -1612,31 +1724,32 @@ frame_command (char *level_exp, int from_tty) static void current_frame_command (char *level_exp, int from_tty) { - if (target_has_stack == 0 || selected_frame == 0) + if (target_has_stack == 0 || deprecated_selected_frame == 0) error ("No stack."); - print_only_stack_frame (selected_frame, selected_frame_level, 1); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); } /* Select the frame up one or COUNT stack levels from the previously selected frame, and print it briefly. */ -/* ARGSUSED */ static void up_silently_base (char *count_exp) { - register struct frame_info *fi; + struct frame_info *fi; int count = 1, count1; if (count_exp) count = parse_and_eval_long (count_exp); count1 = count; - if (target_has_stack == 0 || selected_frame == 0) + if (target_has_stack == 0 || deprecated_selected_frame == 0) error ("No stack."); - fi = find_relative_frame (selected_frame, &count1); + fi = find_relative_frame (deprecated_selected_frame, &count1); if (count1 != 0 && count_exp == 0) error ("Initial frame selected; you cannot go up."); - select_frame (fi, selected_frame_level + count - count1); + select_frame (fi); + selected_frame_level_changed_event (frame_relative_level (deprecated_selected_frame)); } static void @@ -1649,26 +1762,26 @@ static void up_command (char *count_exp, int from_tty) { up_silently_base (count_exp); - show_and_print_stack_frame (selected_frame, selected_frame_level, 1); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); } /* Select the frame down one or COUNT stack levels from the previously selected frame, and print it briefly. */ -/* ARGSUSED */ static void down_silently_base (char *count_exp) { - register struct frame_info *frame; + struct frame_info *frame; int count = -1, count1; if (count_exp) count = -parse_and_eval_long (count_exp); count1 = count; - if (target_has_stack == 0 || selected_frame == 0) + if (target_has_stack == 0 || deprecated_selected_frame == 0) error ("No stack."); - frame = find_relative_frame (selected_frame, &count1); + frame = find_relative_frame (deprecated_selected_frame, &count1); if (count1 != 0 && count_exp == 0) { @@ -1680,10 +1793,10 @@ down_silently_base (char *count_exp) error ("Bottom (i.e., innermost) frame selected; you cannot go down."); } - select_frame (frame, selected_frame_level + count - count1); + select_frame (frame); + selected_frame_level_changed_event (frame_relative_level (deprecated_selected_frame)); } -/* ARGSUSED */ static void down_silently_command (char *count_exp, int from_tty) { @@ -1694,94 +1807,162 @@ static void down_command (char *count_exp, int from_tty) { down_silently_base (count_exp); - show_and_print_stack_frame (selected_frame, selected_frame_level, 1); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); } void -return_command_wrapper (char *retval_exp, int from_tty) -{ - return_command (retval_exp, from_tty); -} - -static void return_command (char *retval_exp, int from_tty) { struct symbol *thisfun; - CORE_ADDR selected_frame_addr; - CORE_ADDR selected_frame_pc; - struct frame_info *frame; struct value *return_value = NULL; + const char *query_prefix = ""; - if (selected_frame == NULL) + /* FIXME: cagney/2003-10-20: Perform a minimal existance test on the + target. If that fails, error out. For the moment don't rely on + get_selected_frame as it's error message is the the singularly + obscure "No registers". */ + if (!target_has_registers) error ("No selected frame."); - thisfun = get_frame_function (selected_frame); - selected_frame_addr = FRAME_FP (selected_frame); - selected_frame_pc = selected_frame->pc; - - /* Compute the return value (if any -- possibly getting errors here). */ + thisfun = get_frame_function (get_selected_frame ()); + /* Compute the return value. If the computation triggers an error, + let it bail. If the return type can't be handled, set + RETURN_VALUE to NULL, and QUERY_PREFIX to an informational + message. */ if (retval_exp) { struct type *return_type = NULL; + /* Compute the return value. Should the computation fail, this + call throws an error. */ return_value = parse_and_eval (retval_exp); - /* Cast return value to the return type of the function. */ + /* Cast return value to the return type of the function. Should + the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); if (return_type == NULL) return_type = builtin_type_int; return_value = value_cast (return_type, return_value); - /* Make sure we have fully evaluated it, since - it might live in the stack frame we're about to pop. */ + /* Make sure the value is fully evaluated. It may live in the + stack frame we're about to pop. */ if (VALUE_LAZY (return_value)) value_fetch_lazy (return_value); + + if (TYPE_CODE (return_type) == TYPE_CODE_VOID) + /* If the return-type is "void", don't try to find the + return-value's location. However, do still evaluate the + return expression so that, even when the expression result + is discarded, side effects such as "return i++" still + occure. */ + return_value = NULL; + /* FIXME: cagney/2004-01-17: If the architecture implements both + return_value and extract_returned_value_address, should allow + "return" to work - don't set return_value to NULL. */ + else if (!gdbarch_return_value_p (current_gdbarch) + && (TYPE_CODE (return_type) == TYPE_CODE_STRUCT + || TYPE_CODE (return_type) == TYPE_CODE_UNION)) + { + /* NOTE: cagney/2003-10-20: Compatibility hack for legacy + code. Old architectures don't expect STORE_RETURN_VALUE + to be called with with a small struct that needs to be + stored in registers. Don't start doing it now. */ + query_prefix = "\ +A structure or union return type is not supported by this architecture.\n\ +If you continue, the return value that you specified will be ignored.\n"; + return_value = NULL; + } + else if (using_struct_return (return_type, 0)) + { + query_prefix = "\ +The location at which to store the function's return value is unknown.\n\ +If you continue, the return value that you specified will be ignored.\n"; + return_value = NULL; + } } - /* If interactive, require confirmation. */ - + /* Does an interactive user really want to do this? Include + information, such as how well GDB can handle the return value, in + the query message. */ if (from_tty) { - if (thisfun != 0) - { - if (!query ("Make %s return now? ", SYMBOL_SOURCE_NAME (thisfun))) - { - error ("Not confirmed."); - /* NOTREACHED */ - } - } - else if (!query ("Make selected stack frame return now? ")) - error ("Not confirmed."); + int confirmed; + if (thisfun == NULL) + confirmed = query ("%sMake selected stack frame return now? ", + query_prefix); + else + confirmed = query ("%sMake %s return now? ", query_prefix, + SYMBOL_PRINT_NAME (thisfun)); + if (!confirmed) + error ("Not confirmed"); } - /* Do the real work. Pop until the specified frame is current. We - use this method because the selected_frame is not valid after - a POP_FRAME. The pc comparison makes this work even if the - selected frame shares its fp with another frame. */ + /* NOTE: cagney/2003-01-18: Is this silly? Rather than pop each + frame in turn, should this code just go straight to the relevant + frame and pop that? */ - while (selected_frame_addr != (frame = get_current_frame ())->frame - || selected_frame_pc != frame->pc) - POP_FRAME; + /* First discard all frames inner-to the selected frame (making the + selected frame current). */ + { + struct frame_id selected_id = get_frame_id (get_selected_frame ()); + while (!frame_id_eq (selected_id, get_frame_id (get_current_frame ()))) + { + if (frame_id_inner (selected_id, get_frame_id (get_current_frame ()))) + /* Caught in the safety net, oops! We've gone way past the + selected frame. */ + error ("Problem while popping stack frames (corrupt stack?)"); + frame_pop (get_current_frame ()); + } + } - /* Then pop that frame. */ + /* Second discard the selected frame (which is now also the current + frame). */ + frame_pop (get_current_frame ()); - POP_FRAME; + /* Store RETURN_VAUE in the just-returned register set. */ + if (return_value != NULL) + { + struct type *return_type = VALUE_TYPE (return_value); + if (!gdbarch_return_value_p (current_gdbarch)) + { + STORE_RETURN_VALUE (return_type, current_regcache, + VALUE_CONTENTS (return_value)); + } + /* FIXME: cagney/2004-01-17: If extract_returned_value_address + is available and the function is using + RETURN_VALUE_STRUCT_CONVENTION, should use it to find the + address of the returned value so that it can be assigned. */ + else + { + gdb_assert (gdbarch_return_value (current_gdbarch, return_type, + NULL, NULL, NULL) + == RETURN_VALUE_REGISTER_CONVENTION); + gdbarch_return_value (current_gdbarch, return_type, + current_regcache, NULL /*read*/, + VALUE_CONTENTS (return_value) /*write*/); + } + } - /* Compute the return value (if any) and store in the place - for return values. */ - - if (retval_exp) - set_return_value (return_value); - - /* If we are at the end of a call dummy now, pop the dummy frame too. */ - - if (CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (), - FRAME_FP (get_current_frame ()))) - POP_FRAME; + /* If we are at the end of a call dummy now, pop the dummy frame + too. */ + /* NOTE: cagney/2003-01-18: Is this silly? Instead of popping all + the frames in sequence, should this code just pop the dummy frame + directly? */ +#ifdef DEPRECATED_CALL_DUMMY_HAS_COMPLETED + /* Since all up-to-date architectures return direct to the dummy + breakpoint address, a dummy frame has, by definition, always + completed. Hence this method is no longer needed. */ + if (DEPRECATED_CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (), + get_frame_base (get_current_frame ()))) + frame_pop (get_current_frame ()); +#else + if (get_frame_type (get_current_frame ()) == DUMMY_FRAME) + frame_pop (get_current_frame ()); +#endif /* If interactive, print the frame that is now current. */ - if (from_tty) frame_command ("0", 1); else @@ -1830,8 +2011,8 @@ func_command (char *arg, int from_tty) do { for (i = 0; (i < sals.nelts && !found); i++) - found = (fp->pc >= func_bounds[i].low && - fp->pc < func_bounds[i].high); + found = (get_frame_pc (fp) >= func_bounds[i].low && + get_frame_pc (fp) < func_bounds[i].high); if (!found) { level = 1; @@ -1845,8 +2026,8 @@ func_command (char *arg, int from_tty) if (!found) printf_filtered ("'%s' not within current stack frame.\n", arg); - else if (fp != selected_frame) - select_and_print_frame (fp, level); + else if (fp != deprecated_selected_frame) + select_and_print_frame (fp); } /* Gets the language of the current frame. */ @@ -1854,12 +2035,19 @@ func_command (char *arg, int from_tty) enum language get_frame_language (void) { - register struct symtab *s; + struct symtab *s; enum language flang; /* The language of the current frame */ - if (selected_frame) + if (deprecated_selected_frame) { - s = find_pc_symtab (selected_frame->pc); + /* We determine the current frame language by looking up its + associated symtab. To retrieve this symtab, we use the frame PC. + However we cannot use the frame pc as is, because it usually points + to the instruction following the "call", which is sometimes the first + instruction of another function. So we rely on + get_frame_address_in_block(), it provides us with a PC which is + guaranteed to be inside the frame's code block. */ + s = find_pc_symtab (get_frame_address_in_block (deprecated_selected_frame)); if (s) flang = s->language; else diff --git a/contrib/gdb/gdb/stack.h b/contrib/gdb/gdb/stack.h new file mode 100644 index 00000000000..0891c94c051 --- /dev/null +++ b/contrib/gdb/gdb/stack.h @@ -0,0 +1,27 @@ +/* Stack manipulation commands, for GDB the GNU Debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef STACK_H +#define STACK_H + +void select_frame_command (char *level_exp, int from_tty); + +#endif /* #ifndef STACK_H */ diff --git a/contrib/gdb/gdb/standalone.c b/contrib/gdb/gdb/standalone.c new file mode 100644 index 00000000000..906e37a2b6e --- /dev/null +++ b/contrib/gdb/gdb/standalone.c @@ -0,0 +1,580 @@ +/* Interface to bare machine for GDB running as kernel debugger. + + Copyright 1986, 1989, 1991, 1992, 1993, 1995, 1996, 2000, 2001, + 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include "gdb_stat.h" + +#if defined (SIGTSTP) && defined (SIGIO) +#include +#include +#endif /* SIGTSTP and SIGIO defined (must be 4.2) */ + +#include "defs.h" +#include +#include "symtab.h" +#include "frame.h" +#include "inferior.h" +#include "gdb_wait.h" + + +/* Random system calls, mostly no-ops to prevent link problems */ + +ioctl (int desc, int code, int arg) +{ +} + +int (*signal ()) () +{ +} + +kill (void) +{ +} + +getpid (void) +{ + return 0; +} + +sigsetmask (void) +{ +} + +chdir (void) +{ +} + +char * +getcwd (char *buf, unsigned int len) +{ + buf[0] = '/'; + buf[1] = 0; + return buf; +} + +/* Used to check for existence of .gdbinit. Say no. */ + +access (void) +{ + return -1; +} + +exit (void) +{ + error ("Fatal error; restarting."); +} + +/* Reading "files". The contents of some files are written into kdb's + data area before it is run. These files are used to contain the + symbol table for kdb to load, and the source files (in case the + kdb user wants to print them). The symbols are stored in a file + named "kdb-symbols" in a.out format (except that all the text and + data have been stripped to save room). + + The files are stored in the following format: + int number of bytes of data for this file, including these four. + char[] name of the file, ending with a null. + padding to multiple of 4 boundary. + char[] file contents. The length can be deduced from what was + specified before. There is no terminating null here. + + If the int at the front is zero, it means there are no more files. + + Opening a file in kdb returns a nonzero value to indicate success, + but the value does not matter. Only one file can be open, and only + for reading. All the primitives for input from the file know + which file is open and ignore what is specified for the descriptor + or for the stdio stream. + + Input with fgetc can be done either on the file that is open + or on stdin (which reads from the terminal through tty_input () */ + +/* Address of data for the files stored in format described above. */ +char *files_start; + +/* The file stream currently open: */ + +char *sourcebeg; /* beginning of contents */ +int sourcesize; /* size of contents */ +char *sourceptr; /* current read pointer */ +int sourceleft; /* number of bytes to eof */ + +/* "descriptor" for the file now open. + Incremented at each close. + If specified descriptor does not match this, + it means the program is trying to use a closed descriptor. + We report an error for that. */ + +int sourcedesc; + +open (char *filename, int modes) +{ + char *next; + + if (modes) + { + errno = EROFS; + return -1; + } + + if (sourceptr) + { + errno = EMFILE; + return -1; + } + + for (next = files_start; *(int *) next; next += *(int *) next) + { + if (!strcmp (next + 4, filename)) + { + sourcebeg = next + 4 + strlen (next + 4) + 1; + sourcebeg = (char *) (((int) sourcebeg + 3) & (-4)); + sourceptr = sourcebeg; + sourcesize = next + *(int *) next - sourceptr; + sourceleft = sourcesize; + return sourcedesc; + } + } + return 0; +} + +close (int desc) +{ + sourceptr = 0; + sourcedesc++; + /* Don't let sourcedesc get big enough to be confused with stdin. */ + if (sourcedesc == 100) + sourcedesc = 5; +} + +FILE * +fopen (char *filename, char *modes) +{ + return (FILE *) open (filename, *modes == 'w'); +} + +FILE * +fdopen (int desc) +{ + return (FILE *) desc; +} + +fclose (int desc) +{ + close (desc); +} + +fstat (int desc, struct stat *statbuf) +{ + if (desc != sourcedesc) + { + errno = EBADF; + return -1; + } + statbuf->st_size = sourcesize; +} + +myread (int desc, char *destptr, int size, char *filename) +{ + int len = min (sourceleft, size); + + if (desc != sourcedesc) + { + errno = EBADF; + return -1; + } + + memcpy (destptr, sourceptr, len); + sourceleft -= len; + return len; +} + +int +fread (int bufp, int numelts, int eltsize, int stream) +{ + int elts = min (numelts, sourceleft / eltsize); + int len = elts * eltsize; + + if (stream != sourcedesc) + { + errno = EBADF; + return -1; + } + + memcpy (bufp, sourceptr, len); + sourceleft -= len; + return elts; +} + +int +fgetc (int desc) +{ + + if (desc == (int) stdin) + return tty_input (); + + if (desc != sourcedesc) + { + errno = EBADF; + return -1; + } + + if (sourceleft-- <= 0) + return EOF; + return *sourceptr++; +} + +lseek (int desc, int pos) +{ + + if (desc != sourcedesc) + { + errno = EBADF; + return -1; + } + + if (pos < 0 || pos > sourcesize) + { + errno = EINVAL; + return -1; + } + + sourceptr = sourcebeg + pos; + sourceleft = sourcesize - pos; +} + +/* Output in kdb can go only to the terminal, so the stream + specified may be ignored. */ + +printf (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) +{ + char buffer[1024]; + sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9); + display_string (buffer); +} + +fprintf (int ign, int a1, int a2, int a3, int a4, int a5, int a6, int a7, + int a8, int a9) +{ + char buffer[1024]; + sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9); + display_string (buffer); +} + +fwrite (char *buf, int numelts, int size, int stream) +{ + int i = numelts * size; + while (i-- > 0) + fputc (*buf++, stream); +} + +fputc (int c, int ign) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + display_string (buf); +} + +/* sprintf refers to this, but loading this from the + library would cause fflush to be loaded from it too. + In fact there should be no need to call this (I hope). */ + +_flsbuf (void) +{ + error ("_flsbuf was actually called."); +} + +fflush (int ign) +{ +} + +/* Entries into core and inflow, needed only to make things link ok. */ + +exec_file_command (void) +{ +} + +core_file_command (void) +{ +} + +char * +get_exec_file (int err) +{ + /* Makes one printout look reasonable; value does not matter otherwise. */ + return "run"; +} + +/* Nonzero if there is a core file. */ + +have_core_file_p (void) +{ + return 0; +} + +kill_command (void) +{ + inferior_ptid = null_ptid; +} + +terminal_inferior (void) +{ +} + +terminal_ours (void) +{ +} + +terminal_init_inferior (void) +{ +} + +write_inferior_register (void) +{ +} + +read_inferior_register (void) +{ +} + +read_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + memcpy (myaddr, memaddr, len); +} + +/* Always return 0 indicating success. */ + +write_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + memcpy (memaddr, myaddr, len); + return 0; +} + +static REGISTER_TYPE saved_regs[NUM_REGS]; + +REGISTER_TYPE +read_register (int regno) +{ + if (regno < 0 || regno >= NUM_REGS) + error ("Register number %d out of range.", regno); + return saved_regs[regno]; +} + +void +write_register (int regno, REGISTER_TYPE value) +{ + if (regno < 0 || regno >= NUM_REGS) + error ("Register number %d out of range.", regno); + saved_regs[regno] = value; +} + +/* System calls needed in relation to running the "inferior". */ + +vfork (void) +{ + /* Just appear to "succeed". Say the inferior's pid is 1. */ + return 1; +} + +/* These are called by code that normally runs in the inferior + that has just been forked. That code never runs, when standalone, + and these definitions are so it will link without errors. */ + +ptrace (void) +{ +} + +setpgrp (void) +{ +} + +execle (void) +{ +} + +_exit (void) +{ +} + +/* Malloc calls these. */ + +malloc_warning (char *str) +{ + printf ("\n%s.\n\n", str); +} + +char *next_free; +char *memory_limit; + +char * +sbrk (int amount) +{ + if (next_free + amount > memory_limit) + return (char *) -1; + next_free += amount; + return next_free - amount; +} + +/* Various ways malloc might ask where end of memory is. */ + +char * +ulimit (void) +{ + return memory_limit; +} + +int +vlimit (void) +{ + return memory_limit - next_free; +} + +getrlimit (struct rlimit *addr) +{ + addr->rlim_cur = memory_limit - next_free; +} + +/* Context switching to and from program being debugged. */ + +/* GDB calls here to run the user program. + The frame pointer for this function is saved in + gdb_stack by save_frame_pointer; then we restore + all of the user program's registers, including PC and PS. */ + +static int fault_code; +static REGISTER_TYPE gdb_stack; + +resume (void) +{ + REGISTER_TYPE restore[NUM_REGS]; + + PUSH_FRAME_PTR; + save_frame_pointer (); + + memcpy (restore, saved_regs, sizeof restore); + POP_REGISTERS; + /* Control does not drop through here! */ +} + +save_frame_pointer (CORE_ADDR val) +{ + gdb_stack = val; +} + +/* Fault handlers call here, running in the user program stack. + They must first push a fault code, + old PC, old PS, and any other info about the fault. + The exact format is machine-dependent and is known only + in the definition of PUSH_REGISTERS. */ + +fault (void) +{ + /* Transfer all registers and fault code to the stack + in canonical order: registers in order of GDB register number, + followed by fault code. */ + PUSH_REGISTERS; + + /* Transfer them to saved_regs and fault_code. */ + save_registers (); + + restore_gdb (); + /* Control does not reach here */ +} + +restore_gdb (void) +{ + CORE_ADDR new_fp = gdb_stack; + /* Switch to GDB's stack */ + POP_FRAME_PTR; + /* Return from the function `resume'. */ +} + +/* Assuming register contents and fault code have been pushed on the stack as + arguments to this function, copy them into the standard place + for the program's registers while GDB is running. */ + +save_registers (int firstreg) +{ + memcpy (saved_regs, &firstreg, sizeof saved_regs); + fault_code = (&firstreg)[NUM_REGS]; +} + +/* Store into the structure such as `wait' would return + the information on why the program faulted, + converted into a machine-independent signal number. */ + +static int fault_table[] = FAULT_TABLE; + +int +wait (WAITTYPE *w) +{ + WSETSTOP (*w, fault_table[fault_code / FAULT_CODE_UNITS]); + return PIDGET (inferior_ptid); +} + +/* Allocate a big space in which files for kdb to read will be stored. + Whatever is left is where malloc can allocate storage. + + Initialize it, so that there will be space in the executable file + for it. Then the files can be put into kdb by writing them into + kdb's executable file. */ + +/* The default size is as much space as we expect to be available + for kdb to use! */ + +#ifndef HEAP_SIZE +#define HEAP_SIZE 400000 +#endif + +char heap[HEAP_SIZE] = +{0}; + +#ifndef STACK_SIZE +#define STACK_SIZE 100000 +#endif + +int kdb_stack_beg[STACK_SIZE / sizeof (int)]; +int kdb_stack_end; + +_initialize_standalone (void) +{ + char *next; + + /* Find start of data on files. */ + + files_start = heap; + + /* Find the end of the data on files. */ + + for (next = files_start; *(int *) next; next += *(int *) next) + { + } + + /* That is where free storage starts for sbrk to give out. */ + next_free = next; + + memory_limit = heap + sizeof heap; +} diff --git a/contrib/gdb/gdb/std-regs.c b/contrib/gdb/gdb/std-regs.c new file mode 100644 index 00000000000..368720dd95b --- /dev/null +++ b/contrib/gdb/gdb/std-regs.c @@ -0,0 +1,160 @@ +/* Builtin frame register, for GDB, the GNU debugger. + + Copyright 2002 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "user-regs.h" +#include "frame.h" +#include "gdbtypes.h" +#include "value.h" +#include "gdb_string.h" + +/* Types that describe the various builtin registers. */ + +static struct type *builtin_type_frame_reg; + +/* Constructors for those types. */ + +static void +build_builtin_type_frame_reg (void) +{ + /* $frame. */ + if (builtin_type_frame_reg == NULL) + { +#if 0 + struct frame + { + void *base; + }; +#endif + builtin_type_frame_reg = init_composite_type ("frame", TYPE_CODE_STRUCT); + append_composite_type_field (builtin_type_frame_reg, "base", + builtin_type_void_data_ptr); + } +} + +static struct value * +value_of_builtin_frame_reg (struct frame_info *frame) +{ + struct value *val; + char *buf; + build_builtin_type_frame_reg (); + val = allocate_value (builtin_type_frame_reg); + VALUE_LVAL (val) = not_lval; + buf = VALUE_CONTENTS_RAW (val); + memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0); + /* frame.base. */ + if (frame != NULL) + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, + get_frame_base (frame)); + buf += TYPE_LENGTH (builtin_type_void_data_ptr); + /* frame.XXX. */ + return val; +} + +static struct value * +value_of_builtin_frame_fp_reg (struct frame_info *frame) +{ + if (DEPRECATED_FP_REGNUM >= 0) + /* NOTE: cagney/2003-04-24: Since the mere presence of "fp" in the + register name table overrides this built-in $fp register, there + is no real reason for this DEPRECATED_FP_REGNUM trickery here. + An architecture wanting to implement "$fp" as alias for a raw + register can do so by adding "fp" to register name table (mind + you, doing this is probably a dangerous thing). */ + return value_of_register (DEPRECATED_FP_REGNUM, frame); + else + { + struct value *val = allocate_value (builtin_type_void_data_ptr); + char *buf = VALUE_CONTENTS_RAW (val); + if (frame == NULL) + memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0); + else + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, + get_frame_base_address (frame)); + return val; + } +} + +static struct value * +value_of_builtin_frame_pc_reg (struct frame_info *frame) +{ + if (PC_REGNUM >= 0) + return value_of_register (PC_REGNUM, frame); + else + { + struct value *val = allocate_value (builtin_type_void_data_ptr); + char *buf = VALUE_CONTENTS_RAW (val); + if (frame == NULL) + memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0); + else + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, + get_frame_pc (frame)); + return val; + } +} + +static struct value * +value_of_builtin_frame_sp_reg (struct frame_info *frame) +{ +#ifdef SP_REGNUM + if (SP_REGNUM >= 0) + return value_of_register (SP_REGNUM, frame); +#endif + error ("Standard register ``$sp'' is not available for this target"); +} + +static struct value * +value_of_builtin_frame_ps_reg (struct frame_info *frame) +{ +#ifdef PS_REGNUM + if (PS_REGNUM >= 0) + return value_of_register (PS_REGNUM, frame); +#endif + error ("Standard register ``$ps'' is not available for this target"); +} + +extern initialize_file_ftype _initialize_frame_reg; /* -Wmissing-prototypes */ + +void +_initialize_frame_reg (void) +{ + /* FIXME: cagney/2002-02-08: At present the local builtin types + can't be initialized using _initialize*() or gdbarch. Due mainly + to non-multi-arch targets, GDB initializes things piece meal and, + as a consequence can leave these types NULL. */ + DEPRECATED_REGISTER_GDBARCH_SWAP (builtin_type_frame_reg); + + /* Frame based $fp, $pc, $sp and $ps. These only come into play + when the target does not define its own version of these + registers. */ + user_reg_add_builtin ("fp", value_of_builtin_frame_fp_reg); + user_reg_add_builtin ("pc", value_of_builtin_frame_pc_reg); + user_reg_add_builtin ("sp", value_of_builtin_frame_sp_reg); + user_reg_add_builtin ("ps", value_of_builtin_frame_ps_reg); + + /* NOTE: cagney/2002-04-05: For moment leave the $frame / $gdbframe + / $gdb.frame disabled. It isn't yet clear which of the many + options is the best. */ + if (0) + user_reg_add_builtin ("frame", value_of_builtin_frame_reg); +} diff --git a/contrib/gdb/gdb/stop-gdb.c b/contrib/gdb/gdb/stop-gdb.c new file mode 100644 index 00000000000..ee84609664c --- /dev/null +++ b/contrib/gdb/gdb/stop-gdb.c @@ -0,0 +1,109 @@ +/* A client to make GDB return to command level in Mach 3. + Copyright 1992, 1993, 1994, 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Authors: Jukka Virtanen and Peter Stout . + + A simple client to make GDB (versions 4.4 and later) on Mach 3 return + to the command level when it is waiting for the inferior to stop. + + Actions: Lookup the send right to the GDB message port from the + NetMsgServer. + + Send an asynchronous message with msgh_id + GDB_MESSAGE_ID_STOP to that port. + */ + +#include + +#include "defs.h" + +#include +#include +#include +#include +#include + +void +main (int argc, char **argv) +{ + kern_return_t kr; + mach_msg_header_t msg; + mach_port_t gdb_port; + char *host; + char *name; + + if (argc == 1) + argv[argc++] = GDB_DEF_NAME; + + if (argc != 2) + { + fprintf (stderr, "Usage : %s \n", argv[0]); + exit (1); + } + + /* Allow the user to specify a remote host. */ + host = strchr (argv[1], '@'); + if (host) + *(host++) = '\0'; + else + host = (char *) ""; + + name = malloc (strlen (argv[1]) + sizeof (GDB_NAME_PREFIX)); + if (name == NULL) + { + fprintf (stderr, "Unable to allocate memory for name."); + exit (1); + } + + strcpy (name, GDB_NAME_PREFIX); + strcat (name, argv[1]); + + /* Look up the GDB service port. For convenience, add the + GDB_NAME_PREFIX the argument before looking up the name. + For backwards compatibility, do it without. */ + + kr = netname_look_up (name_server_port, host, name, &gdb_port); + if (kr == NETNAME_NOT_CHECKED_IN) + kr = netname_look_up (name_server_port, host, argv[1], &gdb_port); + if (kr != KERN_SUCCESS) + { + fprintf (stderr, "Unable to lookup the GDB service port: %s.\n", + mach_error_string (kr)); + exit (1); + } + + /* Code generated by mig stub generator, with minor cleanups :-) + + simpleroutine stop_inferior(gdb_port : mach_port_t); */ + + msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); + msg.msgh_remote_port = gdb_port; + msg.msgh_local_port = MACH_PORT_NULL; + msg.msgh_size = sizeof (msg); + msg.msgh_seqno = 0; + msg.msgh_id = GDB_MESSAGE_ID_STOP; + + kr = mach_msg_send (&msg); + if (kr != KERN_SUCCESS) + fprintf (stderr, "Message not sent, return code %d : %s\n", kr, + mach_error_string (kr)); + + exit (kr != KERN_SUCCESS); +} diff --git a/contrib/gdb/gdb/sun3-nat.c b/contrib/gdb/gdb/sun3-nat.c new file mode 100644 index 00000000000..6c52d3388c2 --- /dev/null +++ b/contrib/gdb/gdb/sun3-nat.c @@ -0,0 +1,166 @@ +/* Host-dependent code for Sun-3 for GDB, the GNU debugger. + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996, 1999, 2000, 2001 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "gdbcore.h" +#include "regcache.h" + +#include +#define KERNEL /* To get floating point reg definitions */ +#include + +static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); + +void +fetch_inferior_registers (int regno) +{ + struct regs inferior_registers; + struct fp_status inferior_fp_registers; + + deprecated_registers_fetched (); + + ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) & inferior_registers); + + if (FP0_REGNUM >= 0) + ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) & inferior_fp_registers); + + memcpy (deprecated_registers, &inferior_registers, 16 * 4); + if (FP0_REGNUM >= 0) + memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + &inferior_fp_registers, sizeof inferior_fp_registers.fps_regs); + + *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; + *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; + if (FP0_REGNUM >= 0) + memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], + &inferior_fp_registers.fps_control, + sizeof inferior_fp_registers - + sizeof inferior_fp_registers.fps_regs); +} + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + +void +store_inferior_registers (int regno) +{ + struct regs inferior_registers; + struct fp_status inferior_fp_registers; + + memcpy (&inferior_registers, deprecated_registers, 16 * 4); + if (FP0_REGNUM >= 0) + memcpy (&inferior_fp_registers, + &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + sizeof inferior_fp_registers.fps_regs); + + inferior_registers.r_ps = *(int *) &&deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)]; + inferior_registers.r_pc = *(int *) &&deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)]; + + if (FP0_REGNUM >= 0) + memcpy (&inferior_fp_registers.fps_control, + &&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], + sizeof inferior_fp_registers - + sizeof inferior_fp_registers.fps_regs); + + ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) & inferior_registers); + if (FP0_REGNUM >= 0) + ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) & inferior_fp_registers); +} + + +/* All of this stuff is only relevant if both host and target are sun3. */ + +/* Provide registers to GDB from a core file. + + CORE_REG_SECT points to an array of bytes, which were obtained from + a core file which BFD thinks might contain register contents. + CORE_REG_SIZE is its size. + + WHICH says which register set corelow suspects this is: + 0 --- the general-purpose register set + 2 --- the floating-point register set + + REG_ADDR isn't used. */ + +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, + int which, CORE_ADDR reg_addr) +{ + struct regs *regs = (struct regs *) core_reg_sect; + + if (which == 0) + { + if (core_reg_size < sizeof (struct regs)) + error ("Can't find registers in core file"); + + memcpy (&deprecated_registers, (char *) regs, 16 * 4); + supply_register (PS_REGNUM, (char *) ®s->r_ps); + supply_register (PC_REGNUM, (char *) ®s->r_pc); + + } + else if (which == 2) + { + +#define fpustruct ((struct fpu *) core_reg_sect) + + if (core_reg_size >= sizeof (struct fpu)) + { + if (FP0_REGNUM >= 0) + { + memcpy (&&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], + fpustruct->f_fpstatus.fps_regs, + sizeof fpustruct->f_fpstatus.fps_regs); + memcpy (&&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPC_REGNUM)], + &fpustruct->f_fpstatus.fps_control, + sizeof fpustruct->f_fpstatus - + sizeof fpustruct->f_fpstatus.fps_regs); + } + } + else + fprintf_unfiltered (gdb_stderr, + "Couldn't read float regs from core file\n"); + } +} + + +/* Register that we are able to handle sun3 core file formats. + FIXME: is this really bfd_target_unknown_flavour? */ + +static struct core_fns sun3_core_fns = +{ + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +void +_initialize_core_sun3 (void) +{ + add_core_fns (&sun3_core_fns); +} diff --git a/contrib/gdb/gdb/symfile.c b/contrib/gdb/gdb/symfile.c index c3c18bff153..19ae2943301 100644 --- a/contrib/gdb/gdb/symfile.c +++ b/contrib/gdb/gdb/symfile.c @@ -1,7 +1,7 @@ /* Generic symbol file reading for the GNU debugger, GDB. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "bfdlink.h" #include "symtab.h" #include "gdbtypes.h" #include "gdbcore.h" @@ -31,15 +32,22 @@ #include "value.h" #include "symfile.h" #include "objfiles.h" +#include "source.h" #include "gdbcmd.h" #include "breakpoint.h" #include "language.h" #include "complaints.h" #include "demangle.h" #include "inferior.h" /* for write_pc */ +#include "filenames.h" /* for DOSish file names */ #include "gdb-stabs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "completer.h" +#include "bcache.h" +#include "hashtab.h" +#include "readline/readline.h" +#include "gdb_assert.h" +#include "block.h" #include #include @@ -80,21 +88,6 @@ static void clear_symtab_users_cleanup (void *ignore); /* Global variables owned by this file */ int readnow_symbol_files; /* Read full symbols immediately */ -struct complaint oldsyms_complaint = -{ - "Replacing old symbols for `%s'", 0, 0 -}; - -struct complaint empty_symtab_complaint = -{ - "Empty symbol table found for `%s'", 0, 0 -}; - -struct complaint unknown_option_complaint = -{ - "Unknown option `%s' ignored", 0, 0 -}; - /* External variables and functions referenced. */ extern void report_transfer_performance (unsigned long, time_t, time_t); @@ -116,6 +109,8 @@ static void add_symbol_file_command (char *, int); static void add_shared_symbol_files_command (char *, int); +static void reread_separate_symbols (struct objfile *objfile); + static void cashier_psymtab (struct partial_symtab *); bfd *symfile_bfd_open (char *); @@ -160,6 +155,8 @@ static void set_ext_lang_command (char *args, int from_tty); static void info_ext_lang_command (char *args, int from_tty); +static char *find_separate_debug_file (struct objfile *objfile); + static void init_filename_language_table (void); void _initialize_symfile (void); @@ -202,66 +199,17 @@ int auto_solib_add = 1; int auto_solib_limit; -/* Since this function is called from within qsort, in an ANSI environment - it must conform to the prototype for qsort, which specifies that the - comparison function takes two "void *" pointers. */ - -static int -compare_symbols (const void *s1p, const void *s2p) -{ - register struct symbol **s1, **s2; - - s1 = (struct symbol **) s1p; - s2 = (struct symbol **) s2p; - return (strcmp (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2))); -} - -/* - - LOCAL FUNCTION - - compare_psymbols -- compare two partial symbols by name - - DESCRIPTION - - Given pointers to pointers to two partial symbol table entries, - compare them by name and return -N, 0, or +N (ala strcmp). - Typically used by sorting routines like qsort(). - - NOTES - - Does direct compare of first two characters before punting - and passing to strcmp for longer compares. Note that the - original version had a bug whereby two null strings or two - identically named one character strings would return the - comparison of memory following the null byte. - - */ +/* This compares two partial symbols by names, using strcmp_iw_ordered + for the comparison. */ static int compare_psymbols (const void *s1p, const void *s2p) { - register struct partial_symbol **s1, **s2; - register char *st1, *st2; + struct partial_symbol *const *s1 = s1p; + struct partial_symbol *const *s2 = s2p; - s1 = (struct partial_symbol **) s1p; - s2 = (struct partial_symbol **) s2p; - st1 = SYMBOL_SOURCE_NAME (*s1); - st2 = SYMBOL_SOURCE_NAME (*s2); - - - if ((st1[0] - st2[0]) || !st1[0]) - { - return (st1[0] - st2[0]); - } - else if ((st1[1] - st2[1]) || !st1[1]) - { - return (st1[1] - st2[1]); - } - else - { - return (strcmp (st1, st2)); - } + return strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*s1), + SYMBOL_NATURAL_NAME (*s2)); } void @@ -274,54 +222,22 @@ sort_pst_symbols (struct partial_symtab *pst) compare_psymbols); } -/* Call sort_block_syms to sort alphabetically the symbols of one block. */ - -void -sort_block_syms (register struct block *b) -{ - qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), - sizeof (struct symbol *), compare_symbols); -} - -/* Call sort_symtab_syms to sort alphabetically - the symbols of each block of one symtab. */ - -void -sort_symtab_syms (register struct symtab *s) -{ - register struct blockvector *bv; - int nbl; - int i; - register struct block *b; - - if (s == 0) - return; - bv = BLOCKVECTOR (s); - nbl = BLOCKVECTOR_NBLOCKS (bv); - for (i = 0; i < nbl; i++) - { - b = BLOCKVECTOR_BLOCK (bv, i); - if (BLOCK_SHOULD_SORT (b)) - sort_block_syms (b); - } -} - /* Make a null terminated copy of the string at PTR with SIZE characters in the obstack pointed to by OBSTACKP . Returns the address of the copy. Note that the string at PTR does not have to be null terminated, I.E. it may be part of a larger string and we are only saving a substring. */ char * -obsavestring (char *ptr, int size, struct obstack *obstackp) +obsavestring (const char *ptr, int size, struct obstack *obstackp) { - register char *p = (char *) obstack_alloc (obstackp, size + 1); + char *p = (char *) obstack_alloc (obstackp, size + 1); /* Open-coded memcpy--saves function call time. These strings are usually short. FIXME: Is this really still true with a compiler that can inline memcpy? */ { - register char *p1 = ptr; - register char *p2 = p; - char *end = ptr + size; + const char *p1 = ptr; + char *p2 = p; + const char *end = ptr + size; while (p1 != end) *p2++ = *p1++; } @@ -336,8 +252,8 @@ char * obconcat (struct obstack *obstackp, const char *s1, const char *s2, const char *s3) { - register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1; - register char *val = (char *) obstack_alloc (obstackp, len); + int len = strlen (s1) + strlen (s2) + strlen (s3) + 1; + char *val = (char *) obstack_alloc (obstackp, len); strcpy (val, s1); strcat (val, s2); strcat (val, s3); @@ -360,7 +276,7 @@ decrement_reading_symtab (void *dummy) case inline. */ struct symtab * -psymtab_to_symtab (register struct partial_symtab *pst) +psymtab_to_symtab (struct partial_symtab *pst) { /* If it's been looked up before, return it. */ if (pst->symtab) @@ -378,41 +294,6 @@ psymtab_to_symtab (register struct partial_symtab *pst) return pst->symtab; } -/* Initialize entry point information for this objfile. */ - -void -init_entry_point_info (struct objfile *objfile) -{ - /* Save startup file's range of PC addresses to help blockframe.c - decide where the bottom of the stack is. */ - - if (bfd_get_file_flags (objfile->obfd) & EXEC_P) - { - /* Executable file -- record its entry point so we'll recognize - the startup file because it contains the entry point. */ - objfile->ei.entry_point = bfd_get_start_address (objfile->obfd); - } - else - { - /* Examination of non-executable.o files. Short-circuit this stuff. */ - objfile->ei.entry_point = INVALID_ENTRY_POINT; - } - objfile->ei.entry_file_lowpc = INVALID_ENTRY_LOWPC; - objfile->ei.entry_file_highpc = INVALID_ENTRY_HIGHPC; - objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC; - objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC; - objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC; - objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC; -} - -/* Get current entry point address. */ - -CORE_ADDR -entry_point_address (void) -{ - return symfile_objfile ? symfile_objfile->ei.entry_point : 0; -} - /* Remember the lowest-addressed loadable section we've seen. This function is called via bfd_map_over_sections. @@ -423,7 +304,7 @@ entry_point_address (void) lowest-addressed loadable section. */ void -find_lowest_section (bfd *abfd, asection *sect, PTR obj) +find_lowest_section (bfd *abfd, asection *sect, void *obj) { asection **lowest = (asection **) obj; @@ -439,6 +320,22 @@ find_lowest_section (bfd *abfd, asection *sect, PTR obj) *lowest = sect; } +/* Create a new section_addr_info, with room for NUM_SECTIONS. */ + +struct section_addr_info * +alloc_section_addr_info (size_t num_sections) +{ + struct section_addr_info *sap; + size_t size; + + size = (sizeof (struct section_addr_info) + + sizeof (struct other_sections) * (num_sections - 1)); + sap = (struct section_addr_info *) xmalloc (size); + memset (sap, 0, size); + sap->num_sections = num_sections; + + return sap; +} /* Build (allocate and populate) a section_addr_info struct from an existing section table. */ @@ -451,14 +348,13 @@ build_section_addr_info_from_section_table (const struct section_table *start, const struct section_table *stp; int oidx; - sap = xmalloc (sizeof (struct section_addr_info)); - memset (sap, 0, sizeof (struct section_addr_info)); + sap = alloc_section_addr_info (end - start); for (stp = start, oidx = 0; stp != end; stp++) { if (bfd_get_section_flags (stp->bfd, stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD) - && oidx < MAX_SECTIONS) + && oidx < end - start) { sap->other[oidx].addr = stp->addr; sap->other[oidx].name @@ -479,50 +375,20 @@ free_section_addr_info (struct section_addr_info *sap) { int idx; - for (idx = 0; idx < MAX_SECTIONS; idx++) + for (idx = 0; idx < sap->num_sections; idx++) if (sap->other[idx].name) xfree (sap->other[idx].name); xfree (sap); } -/* Parse the user's idea of an offset for dynamic linking, into our idea - of how to represent it for fast symbol reading. This is the default - version of the sym_fns.sym_offsets function for symbol readers that - don't need to do anything special. It allocates a section_offsets table - for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */ - -void -default_symfile_offsets (struct objfile *objfile, - struct section_addr_info *addrs) +/* Initialize OBJFILE's sect_index_* members. */ +static void +init_objfile_sect_indices (struct objfile *objfile) { + asection *sect; int i; - asection *sect = NULL; - - objfile->num_sections = SECT_OFF_MAX; - objfile->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS); - memset (objfile->section_offsets, 0, SIZEOF_SECTION_OFFSETS); - - /* Now calculate offsets for section that were specified by the - caller. */ - for (i = 0; i < MAX_SECTIONS && addrs->other[i].name; i++) - { - struct other_sections *osp ; - - osp = &addrs->other[i] ; - if (osp->addr == 0) - continue; - - /* Record all sections in offsets */ - /* The section_offsets in the objfile are here filled in using - the BFD index. */ - (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr; - } - - /* Remember the bfd indexes for the .text, .data, .bss and - .rodata sections. */ - + sect = bfd_get_section_by_name (objfile->obfd, ".text"); if (sect) objfile->sect_index_text = sect->index; @@ -569,13 +435,73 @@ default_symfile_offsets (struct objfile *objfile, } } + +/* Parse the user's idea of an offset for dynamic linking, into our idea + of how to represent it for fast symbol reading. This is the default + version of the sym_fns.sym_offsets function for symbol readers that + don't need to do anything special. It allocates a section_offsets table + for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */ + +void +default_symfile_offsets (struct objfile *objfile, + struct section_addr_info *addrs) +{ + int i; + + objfile->num_sections = bfd_count_sections (objfile->obfd); + objfile->section_offsets = (struct section_offsets *) + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + memset (objfile->section_offsets, 0, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + + /* Now calculate offsets for section that were specified by the + caller. */ + for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + { + struct other_sections *osp ; + + osp = &addrs->other[i] ; + if (osp->addr == 0) + continue; + + /* Record all sections in offsets */ + /* The section_offsets in the objfile are here filled in using + the BFD index. */ + (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr; + } + + /* Remember the bfd indexes for the .text, .data, .bss and + .rodata sections. */ + init_objfile_sect_indices (objfile); +} + + /* Process a symbol file, as either the main file or as a dynamically loaded file. OBJFILE is where the symbols are to be read from. - ADDR is the address where the text segment was loaded, unless the - objfile is the main symbol file, in which case it is zero. + ADDRS is the list of section load addresses. If the user has given + an 'add-symbol-file' command, then this is the list of offsets and + addresses he or she provided as arguments to the command; or, if + we're handling a shared library, these are the actual addresses the + sections are loaded at, according to the inferior's dynamic linker + (as gleaned by GDB's shared library code). We convert each address + into an offset from the section VMA's as it appears in the object + file, and then call the file's sym_offsets function to convert this + into a format-specific offset table --- a `struct section_offsets'. + If ADDRS is non-zero, OFFSETS must be zero. + + OFFSETS is a table of section offsets already in the right + format-specific representation. NUM_OFFSETS is the number of + elements present in OFFSETS->offsets. If OFFSETS is non-zero, we + assume this is the proper table the call to sym_offsets described + above would produce. Instead of calling sym_offsets, we just dump + it right into objfile->section_offsets. (When we're re-reading + symbols from an objfile, we don't have the original load address + list any more; all we have is the section offset table.) If + OFFSETS is non-zero, ADDRS must be zero. MAINLINE is nonzero if this is the main symbol file, or zero if it's an extra symbol file such as dynamically loaded code. @@ -584,33 +510,41 @@ default_symfile_offsets (struct objfile *objfile, the symbol reading (and complaints can be more terse about it). */ void -syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, - int mainline, int verbo) +syms_from_objfile (struct objfile *objfile, + struct section_addr_info *addrs, + struct section_offsets *offsets, + int num_offsets, + int mainline, + int verbo) { - asection *lower_sect; - asection *sect; - CORE_ADDR lower_offset; - struct section_addr_info local_addr; + struct section_addr_info *local_addr = NULL; struct cleanup *old_chain; - int i; - /* If ADDRS is NULL, initialize the local section_addr_info struct and - point ADDRS to it. We now establish the convention that an addr of - zero means no load address was specified. */ - - if (addrs == NULL) - { - memset (&local_addr, 0, sizeof (local_addr)); - addrs = &local_addr; - } + gdb_assert (! (addrs && offsets)); init_entry_point_info (objfile); find_sym_fns (objfile); + if (objfile->sf == NULL) + return; /* No symbols. */ + /* Make sure that partially constructed symbol tables will be cleaned up if an error occurs during symbol reading. */ old_chain = make_cleanup_free_objfile (objfile); + /* If ADDRS and OFFSETS are both NULL, put together a dummy address + list. We now establish the convention that an addr of zero means + no load address was specified. */ + if (! addrs && ! offsets) + { + local_addr + = alloc_section_addr_info (bfd_count_sections (objfile->obfd)); + make_cleanup (xfree, local_addr); + addrs = local_addr; + } + + /* Now either addrs or offsets is non-zero. */ + if (mainline) { /* We will modify the main symbol table, make sure that all its users @@ -639,15 +573,20 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, We no longer warn if the lowest section is not a text segment (as happens for the PA64 port. */ - if (!mainline) + if (!mainline && addrs && addrs->other[0].name) { + asection *lower_sect; + asection *sect; + CORE_ADDR lower_offset; + int i; + /* Find lowest loadable section to be used as starting point for continguous sections. FIXME!! won't work without call to find .text first, but this assumes text is lowest section. */ lower_sect = bfd_get_section_by_name (objfile->obfd, ".text"); if (lower_sect == NULL) bfd_map_over_sections (objfile->obfd, find_lowest_section, - (PTR) &lower_sect); + &lower_sect); if (lower_sect == NULL) warning ("no loadable sections found in added symbol-file %s", objfile->name); @@ -662,39 +601,41 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, else lower_offset = 0; - /* Calculate offsets for the loadable sections. + /* Calculate offsets for the loadable sections. FIXME! Sections must be in order of increasing loadable section so that contiguous sections can use the lower-offset!!! - Adjust offsets if the segments are not contiguous. - If the section is contiguous, its offset should be set to + Adjust offsets if the segments are not contiguous. + If the section is contiguous, its offset should be set to the offset of the highest loadable section lower than it (the loadable section directly below it in memory). this_offset = lower_offset = lower_addr - lower_orig_addr */ - /* Calculate offsets for sections. */ - for (i=0 ; i < MAX_SECTIONS && addrs->other[i].name; i++) - { - if (addrs->other[i].addr != 0) - { - sect = bfd_get_section_by_name (objfile->obfd, addrs->other[i].name); - if (sect) - { - addrs->other[i].addr -= bfd_section_vma (objfile->obfd, sect); - lower_offset = addrs->other[i].addr; - /* This is the index used by BFD. */ - addrs->other[i].sectindex = sect->index ; - } - else - { - warning ("section %s not found in %s", addrs->other[i].name, - objfile->name); - addrs->other[i].addr = 0; - } - } - else - addrs->other[i].addr = lower_offset; - } + for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + { + if (addrs->other[i].addr != 0) + { + sect = bfd_get_section_by_name (objfile->obfd, + addrs->other[i].name); + if (sect) + { + addrs->other[i].addr + -= bfd_section_vma (objfile->obfd, sect); + lower_offset = addrs->other[i].addr; + /* This is the index used by BFD. */ + addrs->other[i].sectindex = sect->index ; + } + else + { + warning ("section %s not found in %s", + addrs->other[i].name, + objfile->name); + addrs->other[i].addr = 0; + } + } + else + addrs->other[i].addr = lower_offset; + } } /* Initialize symbol reading routines for this objfile, allow complaints to @@ -702,11 +643,25 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, initial symbol reading for this file. */ (*objfile->sf->sym_init) (objfile); - clear_complaints (1, verbo); + clear_complaints (&symfile_complaints, 1, verbo); - (*objfile->sf->sym_offsets) (objfile, addrs); + if (addrs) + (*objfile->sf->sym_offsets) (objfile, addrs); + else + { + size_t size = SIZEOF_N_SECTION_OFFSETS (num_offsets); -#ifndef IBM6000_TARGET + /* Just copy in the offset table directly as given to us. */ + objfile->num_sections = num_offsets; + objfile->section_offsets + = ((struct section_offsets *) + obstack_alloc (&objfile->objfile_obstack, size)); + memcpy (objfile->section_offsets, offsets, size); + + init_objfile_sect_indices (objfile); + } + +#ifndef DEPRECATED_IBM6000_TARGET /* This is a SVR4/SunOS specific hack, I think. In any event, it screws RS/6000. sym_offsets should be doing this sort of thing, because it knows the mapping between bfd sections and @@ -740,7 +695,7 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, int i; for (i = 0; - !s_addr && i < MAX_SECTIONS && addrs->other[i].name; + !s_addr && i < addrs->num_sections && addrs->other[i].name; i++) if (strcmp (bfd_section_name (s->objfile->obfd, s->the_bfd_section), @@ -754,17 +709,10 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, s->offset += s_addr; } } -#endif /* not IBM6000_TARGET */ +#endif /* not DEPRECATED_IBM6000_TARGET */ (*objfile->sf->sym_read) (objfile, mainline); - if (!have_partial_symbols () && !have_full_symbols ()) - { - wrap_here (""); - printf_filtered ("(no debugging symbols found)..."); - wrap_here (""); - } - /* Don't allow char * to have a typename (else would get caddr_t). Ditto void *. FIXME: Check whether this is now done by all the symbol readers themselves (many of them now do), and if so remove @@ -781,13 +729,6 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, /* Discard cleanups as symbol reading was successful. */ discard_cleanups (old_chain); - - /* Call this after reading in a new symbol table to give target - dependent code a crack at the new symbols. For instance, this - could be used to update the values of target-specific symbols GDB - needs to keep track of (such as _sigtramp, or whatever). */ - - TARGET_SYMFILE_POSTREAD (objfile); } /* Perform required actions after either reading in the initial @@ -814,7 +755,7 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo) } /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (0, verbo); + clear_complaints (&symfile_complaints, 0, verbo); } /* Process a symbol file, as either the main file or as a dynamically @@ -822,21 +763,31 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo) NAME is the file name (which will be tilde-expanded and made absolute herein) (but we don't free or modify NAME itself). - FROM_TTY says how verbose to be. MAINLINE specifies whether this - is the main symbol file, or whether it's an extra symbol file such - as dynamically loaded code. If !mainline, ADDR is the address - where the text segment was loaded. + + FROM_TTY says how verbose to be. + + MAINLINE specifies whether this is the main symbol file, or whether + it's an extra symbol file such as dynamically loaded code. + + ADDRS, OFFSETS, and NUM_OFFSETS are as described for + syms_from_objfile, above. ADDRS is ignored when MAINLINE is + non-zero. Upon success, returns a pointer to the objfile that was added. Upon failure, jumps back to command level (never returns). */ - -struct objfile * -symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, - int mainline, int flags) +static struct objfile * +symbol_file_add_with_addrs_or_offsets (char *name, int from_tty, + struct section_addr_info *addrs, + struct section_offsets *offsets, + int num_offsets, + int mainline, int flags) { struct objfile *objfile; struct partial_symtab *psymtab; + char *debugfile; bfd *abfd; + struct section_addr_info *orig_addrs; + struct cleanup *my_cleanups; /* Open a bfd for the file, and give user a chance to burp if we'd be interactively wiping out any existing symbols. */ @@ -851,42 +802,32 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, objfile = allocate_objfile (abfd, flags); - /* If the objfile uses a mapped symbol file, and we have a psymtab for - it, then skip reading any symbols at this time. */ - - if ((objfile->flags & OBJF_MAPPED) && (objfile->flags & OBJF_SYMS)) + orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd)); + my_cleanups = make_cleanup (xfree, orig_addrs); + if (addrs) { - /* We mapped in an existing symbol table file that already has had - initial symbol reading performed, so we can skip that part. Notify - the user that instead of reading the symbols, they have been mapped. - */ - if (from_tty || info_verbose) + int i; + orig_addrs->num_sections = addrs->num_sections; + for (i = 0; i < addrs->num_sections; i++) + orig_addrs->other[i] = addrs->other[i]; + } + + /* We either created a new mapped symbol table, mapped an existing + symbol table file which has not had initial symbol reading + performed, or need to read an unmapped symbol table. */ + if (from_tty || info_verbose) + { + if (pre_add_symbol_hook) + pre_add_symbol_hook (name); + else { - printf_filtered ("Mapped symbols for %s...", name); + printf_unfiltered ("Reading symbols from %s...", name); wrap_here (""); gdb_flush (gdb_stdout); } - init_entry_point_info (objfile); - find_sym_fns (objfile); - } - else - { - /* We either created a new mapped symbol table, mapped an existing - symbol table file which has not had initial symbol reading - performed, or need to read an unmapped symbol table. */ - if (from_tty || info_verbose) - { - if (pre_add_symbol_hook) - pre_add_symbol_hook (name); - else - { - printf_filtered ("Reading symbols from %s...", name); - wrap_here (""); - gdb_flush (gdb_stdout); - } - } - syms_from_objfile (objfile, addrs, mainline, from_tty); } + syms_from_objfile (objfile, addrs, offsets, num_offsets, + mainline, from_tty); /* We now have at least a partial symbol table. Check to see if the user requested that all symbols be read on initial access via either @@ -897,7 +838,7 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, { if (from_tty || info_verbose) { - printf_filtered ("expanding to full symbols..."); + printf_unfiltered ("expanding to full symbols..."); wrap_here (""); gdb_flush (gdb_stdout); } @@ -910,17 +851,56 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, } } + debugfile = find_separate_debug_file (objfile); + if (debugfile) + { + if (addrs != NULL) + { + objfile->separate_debug_objfile + = symbol_file_add (debugfile, from_tty, orig_addrs, 0, flags); + } + else + { + objfile->separate_debug_objfile + = symbol_file_add (debugfile, from_tty, NULL, 0, flags); + } + objfile->separate_debug_objfile->separate_debug_objfile_backlink + = objfile; + + /* Put the separate debug object before the normal one, this is so that + usage of the ALL_OBJFILES_SAFE macro will stay safe. */ + put_objfile_before (objfile->separate_debug_objfile, objfile); + + xfree (debugfile); + } + + if (!have_partial_symbols () && !have_full_symbols ()) + { + wrap_here (""); + printf_unfiltered ("(no debugging symbols found)..."); + wrap_here (""); + } + if (from_tty || info_verbose) { if (post_add_symbol_hook) post_add_symbol_hook (); else { - printf_filtered ("done.\n"); - gdb_flush (gdb_stdout); + printf_unfiltered ("done.\n"); } } + /* We print some messages regardless of whether 'from_tty || + info_verbose' is true, so make sure they go out at the right + time. */ + gdb_flush (gdb_stdout); + + do_cleanups (my_cleanups); + + if (objfile->sf == NULL) + return objfile; /* No symbols. */ + new_symfile_objfile (objfile, mainline, from_tty); if (target_new_objfile_hook) @@ -929,6 +909,19 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, return (objfile); } + +/* Process a symbol file, as either the main file or as a dynamically + loaded file. See symbol_file_add_with_addrs_or_offsets's comments + for details. */ +struct objfile * +symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, + int mainline, int flags) +{ + return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, + mainline, flags); +} + + /* Call symbol_file_add() with default values and update whatever is affected by the loading of a new main(). Used when the file is supplied in the gdb command line @@ -985,6 +978,144 @@ symbol_file_clear (int from_tty) #endif } +static char * +get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) +{ + asection *sect; + bfd_size_type debuglink_size; + unsigned long crc32; + char *contents; + int crc_offset; + unsigned char *p; + + sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink"); + + if (sect == NULL) + return NULL; + + debuglink_size = bfd_section_size (objfile->obfd, sect); + + contents = xmalloc (debuglink_size); + bfd_get_section_contents (objfile->obfd, sect, contents, + (file_ptr)0, (bfd_size_type)debuglink_size); + + /* Crc value is stored after the filename, aligned up to 4 bytes. */ + crc_offset = strlen (contents) + 1; + crc_offset = (crc_offset + 3) & ~3; + + crc32 = bfd_get_32 (objfile->obfd, (bfd_byte *) (contents + crc_offset)); + + *crc32_out = crc32; + return contents; +} + +static int +separate_debug_file_exists (const char *name, unsigned long crc) +{ + unsigned long file_crc = 0; + int fd; + char buffer[8*1024]; + int count; + + fd = open (name, O_RDONLY | O_BINARY); + if (fd < 0) + return 0; + + while ((count = read (fd, buffer, sizeof (buffer))) > 0) + file_crc = gnu_debuglink_crc32 (file_crc, buffer, count); + + close (fd); + + return crc == file_crc; +} + +static char *debug_file_directory = NULL; + +#if ! defined (DEBUG_SUBDIRECTORY) +#define DEBUG_SUBDIRECTORY ".debug" +#endif + +static char * +find_separate_debug_file (struct objfile *objfile) +{ + asection *sect; + char *basename; + char *dir; + char *debugfile; + char *name_copy; + bfd_size_type debuglink_size; + unsigned long crc32; + int i; + + basename = get_debug_link_info (objfile, &crc32); + + if (basename == NULL) + return NULL; + + dir = xstrdup (objfile->name); + + /* Strip off the final filename part, leaving the directory name, + followed by a slash. Objfile names should always be absolute and + tilde-expanded, so there should always be a slash in there + somewhere. */ + for (i = strlen(dir) - 1; i >= 0; i--) + { + if (IS_DIR_SEPARATOR (dir[i])) + break; + } + gdb_assert (i >= 0 && IS_DIR_SEPARATOR (dir[i])); + dir[i+1] = '\0'; + + debugfile = alloca (strlen (debug_file_directory) + 1 + + strlen (dir) + + strlen (DEBUG_SUBDIRECTORY) + + strlen ("/") + + strlen (basename) + + 1); + + /* First try in the same directory as the original file. */ + strcpy (debugfile, dir); + strcat (debugfile, basename); + + if (separate_debug_file_exists (debugfile, crc32)) + { + xfree (basename); + xfree (dir); + return xstrdup (debugfile); + } + + /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ + strcpy (debugfile, dir); + strcat (debugfile, DEBUG_SUBDIRECTORY); + strcat (debugfile, "/"); + strcat (debugfile, basename); + + if (separate_debug_file_exists (debugfile, crc32)) + { + xfree (basename); + xfree (dir); + return xstrdup (debugfile); + } + + /* Then try in the global debugfile directory. */ + strcpy (debugfile, debug_file_directory); + strcat (debugfile, "/"); + strcat (debugfile, dir); + strcat (debugfile, basename); + + if (separate_debug_file_exists (debugfile, crc32)) + { + xfree (basename); + xfree (dir); + return xstrdup (debugfile); + } + + xfree (basename); + xfree (dir); + return NULL; +} + + /* This is the symbol-file command. Read the file, analyze its symbols, and add a struct symtab to a symtab list. The syntax of the command is rather bizarre--(1) buildargv implements various @@ -1022,20 +1153,16 @@ symbol_file_command (char *args, int from_tty) cleanups = make_cleanup_freeargv (argv); while (*argv != NULL) { - if (STREQ (*argv, "-mapped")) - flags |= OBJF_MAPPED; - else - if (STREQ (*argv, "-readnow")) - flags |= OBJF_READNOW; - else - if (**argv == '-') - error ("unknown option `%s'", *argv); - else - { - name = *argv; - - symbol_file_add_main_1 (name, from_tty, flags); - } + if (strcmp (*argv, "-readnow") == 0) + flags |= OBJF_READNOW; + else if (**argv == '-') + error ("unknown option `%s'", *argv); + else + { + name = *argv; + + symbol_file_add_main_1 (name, from_tty, flags); + } argv++; } @@ -1124,7 +1251,7 @@ symfile_bfd_open (char *name) error ("\"%s\": can't open to read symbols: %s.", name, bfd_errmsg (bfd_get_error ())); } - sym_bfd->cacheable = 1; + bfd_set_cacheable (sym_bfd, 1); if (!bfd_check_format (sym_bfd, bfd_object)) { @@ -1176,9 +1303,10 @@ find_sym_fns (struct objfile *objfile) enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd); char *our_target = bfd_get_target (objfile->obfd); - /* Special kludge for apollo. See dstread.c. */ - if (STREQN (our_target, "apollo", 6)) - our_flavour = (enum bfd_flavour) -2; + if (our_flavour == bfd_target_srec_flavour + || our_flavour == bfd_target_ihex_flavour + || our_flavour == bfd_target_tekhex_flavour) + return; /* No symbols. */ for (sf = symtab_fns; sf != NULL; sf = sf->next) { @@ -1402,11 +1530,11 @@ generic_load (char *args, int from_tty) for other targets too. */ write_pc (entry); - /* FIXME: are we supposed to call symbol_file_add or not? According to - a comment from remote-mips.c (where a call to symbol_file_add was - commented out), making the call confuses GDB if more than one file is - loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c - does. */ + /* FIXME: are we supposed to call symbol_file_add or not? According + to a comment from remote-mips.c (where a call to symbol_file_add + was commented out), making the call confuses GDB if more than one + file is loaded in. Some targets do (e.g., remote-vx.c) but + others don't (or didn't - perhaphs they have all been deleted). */ print_transfer_performance (gdb_stdout, cbdata.data_count, cbdata.write_count, end_time - start_time); @@ -1464,7 +1592,6 @@ print_transfer_performance (struct ui_file *stream, instead a call to target_link() (in target.c) would supply the value to use. We are now discontinuing this type of ad hoc syntax. */ -/* ARGSUSED */ static void add_symbol_file_command (char *args, int from_tty) { @@ -1479,15 +1606,21 @@ add_symbol_file_command (char *args, int from_tty) int expecting_sec_name = 0; int expecting_sec_addr = 0; - struct + struct sect_opt { char *name; char *value; - } sect_opts[SECT_OFF_MAX]; + }; - struct section_addr_info section_addrs; + struct section_addr_info *section_addrs; + struct sect_opt *sect_opts = NULL; + size_t num_sect_opts = 0; struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL); + num_sect_opts = 16; + sect_opts = (struct sect_opt *) xmalloc (num_sect_opts + * sizeof (struct sect_opt)); + dont_repeat (); if (args == NULL) @@ -1496,9 +1629,6 @@ add_symbol_file_command (char *args, int from_tty) /* Make a copy of the string that we can safely write into. */ args = xstrdup (args); - /* Ensure section_addrs is initialized */ - memset (§ion_addrs, 0, sizeof (section_addrs)); - while (*args != '\000') { /* Any leading spaces? */ @@ -1531,7 +1661,14 @@ add_symbol_file_command (char *args, int from_tty) to load the program. */ sect_opts[section_index].name = ".text"; sect_opts[section_index].value = arg; - section_index++; + if (++section_index > num_sect_opts) + { + num_sect_opts *= 2; + sect_opts = ((struct sect_opt *) + xrealloc (sect_opts, + num_sect_opts + * sizeof (struct sect_opt))); + } } else { @@ -1540,19 +1677,13 @@ add_symbol_file_command (char *args, int from_tty) if (*arg == '-') { - if (strcmp (arg, "-mapped") == 0) - flags |= OBJF_MAPPED; - else - if (strcmp (arg, "-readnow") == 0) - flags |= OBJF_READNOW; - else - if (strcmp (arg, "-s") == 0) - { - if (section_index >= SECT_OFF_MAX) - error ("Too many sections specified."); - expecting_sec_name = 1; - expecting_sec_addr = 1; - } + if (strcmp (arg, "-readnow") == 0) + flags |= OBJF_READNOW; + else if (strcmp (arg, "-s") == 0) + { + expecting_sec_name = 1; + expecting_sec_addr = 1; + } } else { @@ -1566,7 +1697,14 @@ add_symbol_file_command (char *args, int from_tty) { sect_opts[section_index].value = arg; expecting_sec_addr = 0; - section_index++; + if (++section_index > num_sect_opts) + { + num_sect_opts *= 2; + sect_opts = ((struct sect_opt *) + xrealloc (sect_opts, + num_sect_opts + * sizeof (struct sect_opt))); + } } else error ("USAGE: add-symbol-file [-mapped] [-readnow] [-s ]*"); @@ -1581,24 +1719,22 @@ add_symbol_file_command (char *args, int from_tty) statements because local_hex_string returns a local static string. */ - printf_filtered ("add symbol table from file \"%s\" at\n", filename); + printf_unfiltered ("add symbol table from file \"%s\" at\n", filename); + section_addrs = alloc_section_addr_info (section_index); + make_cleanup (xfree, section_addrs); for (i = 0; i < section_index; i++) { CORE_ADDR addr; char *val = sect_opts[i].value; char *sec = sect_opts[i].name; - val = sect_opts[i].value; - if (val[0] == '0' && val[1] == 'x') - addr = strtoul (val+2, NULL, 16); - else - addr = strtoul (val, NULL, 10); + addr = parse_and_eval_address (val); /* Here we store the section offsets in the order they were entered on the command line. */ - section_addrs.other[sec_num].name = sec; - section_addrs.other[sec_num].addr = addr; - printf_filtered ("\t%s_addr = %s\n", + section_addrs->other[sec_num].name = sec; + section_addrs->other[sec_num].addr = addr; + printf_unfiltered ("\t%s_addr = %s\n", sec, local_hex_string ((unsigned long)addr)); sec_num++; @@ -1613,7 +1749,7 @@ add_symbol_file_command (char *args, int from_tty) if (from_tty && (!query ("%s", ""))) error ("Not confirmed."); - symbol_file_add (filename, from_tty, §ion_addrs, 0, flags); + symbol_file_add (filename, from_tty, section_addrs, 0, flags); /* Getting new symbols may change our opinion about what is frameless. */ @@ -1651,7 +1787,7 @@ reread_symbols (void) { if (objfile->obfd) { -#ifdef IBM6000_TARGET +#ifdef DEPRECATED_IBM6000_TARGET /* If this object is from a shared library, then you should stat on the library name, not member name. */ @@ -1663,7 +1799,7 @@ reread_symbols (void) if (res != 0) { /* FIXME, should use print_sys_errmsg but it's not filtered. */ - printf_filtered ("`%s' has disappeared; keeping its symbols.\n", + printf_unfiltered ("`%s' has disappeared; keeping its symbols.\n", objfile->name); continue; } @@ -1675,7 +1811,7 @@ reread_symbols (void) int num_offsets; char *obfd_filename; - printf_filtered ("`%s' has changed; re-reading symbols.\n", + printf_unfiltered ("`%s' has changed; re-reading symbols.\n", objfile->name); /* There are various functions like symbol_file_add, @@ -1708,10 +1844,12 @@ reread_symbols (void) bfd_errmsg (bfd_get_error ())); /* Save the offsets, we will nuke them with the rest of the - psymbol_obstack. */ + objfile_obstack. */ num_offsets = objfile->num_sections; - offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS); - memcpy (offsets, objfile->section_offsets, SIZEOF_SECTION_OFFSETS); + offsets = ((struct section_offsets *) + alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets))); + memcpy (offsets, objfile->section_offsets, + SIZEOF_N_SECTION_OFFSETS (num_offsets)); /* Nuke all the state that we will re-read. Much of the following code which sets things to NULL really is necessary to tell @@ -1729,21 +1867,30 @@ reread_symbols (void) sizeof (objfile->static_psymbols)); /* Free the obstacks for non-reusable objfiles */ - free_bcache (&objfile->psymbol_cache); - obstack_free (&objfile->psymbol_obstack, 0); - obstack_free (&objfile->symbol_obstack, 0); - obstack_free (&objfile->type_obstack, 0); + bcache_xfree (objfile->psymbol_cache); + objfile->psymbol_cache = bcache_xmalloc (); + bcache_xfree (objfile->macro_cache); + objfile->macro_cache = bcache_xmalloc (); + if (objfile->demangled_names_hash != NULL) + { + htab_delete (objfile->demangled_names_hash); + objfile->demangled_names_hash = NULL; + } + obstack_free (&objfile->objfile_obstack, 0); objfile->sections = NULL; objfile->symtabs = NULL; objfile->psymtabs = NULL; objfile->free_psymtabs = NULL; + objfile->cp_namespace_symtab = NULL; objfile->msymbols = NULL; + objfile->sym_private = NULL; objfile->minimal_symbol_count = 0; memset (&objfile->msymbol_hash, 0, sizeof (objfile->msymbol_hash)); memset (&objfile->msymbol_demangled_hash, 0, sizeof (objfile->msymbol_demangled_hash)); objfile->fundamental_types = NULL; + clear_objfile_data (objfile); if (objfile->sf != NULL) { (*objfile->sf->sym_finish) (objfile); @@ -1751,27 +1898,27 @@ reread_symbols (void) /* We never make this a mapped file. */ objfile->md = NULL; - /* obstack_specify_allocation also initializes the obstack so - it is empty. */ - obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0, - xmalloc, xfree); - obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, - xmalloc, xfree); - obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, - xmalloc, xfree); - obstack_specify_allocation (&objfile->type_obstack, 0, 0, - xmalloc, xfree); + objfile->psymbol_cache = bcache_xmalloc (); + objfile->macro_cache = bcache_xmalloc (); + /* obstack_init also initializes the obstack so it is + empty. We could use obstack_specify_allocation but + gdb_obstack.h specifies the alloc/dealloc + functions. */ + obstack_init (&objfile->objfile_obstack); if (build_objfile_section_table (objfile)) { error ("Can't find the file sections in `%s': %s", objfile->name, bfd_errmsg (bfd_get_error ())); } + terminate_minimal_symbol_table (objfile); /* We use the same section offsets as from last time. I'm not sure whether that is always correct for shared libraries. */ objfile->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS); - memcpy (objfile->section_offsets, offsets, SIZEOF_SECTION_OFFSETS); + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (num_offsets)); + memcpy (objfile->section_offsets, offsets, + SIZEOF_N_SECTION_OFFSETS (num_offsets)); objfile->num_sections = num_offsets; /* What the hell is sym_new_init for, anyway? The concept of @@ -1786,7 +1933,7 @@ reread_symbols (void) } (*objfile->sf->sym_init) (objfile); - clear_complaints (1, 1); + clear_complaints (&symfile_complaints, 1, 1); /* The "mainline" parameter is a hideous hack; I think leaving it zero is OK since dbxread.c also does what it needs to do if objfile->global_psymbols.size is 0. */ @@ -1794,13 +1941,13 @@ reread_symbols (void) if (!have_partial_symbols () && !have_full_symbols ()) { wrap_here (""); - printf_filtered ("(no debugging symbols found)\n"); + printf_unfiltered ("(no debugging symbols found)\n"); wrap_here (""); } objfile->flags |= OBJF_SYMS; /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (0, 1); + clear_complaints (&symfile_complaints, 0, 1); /* Getting new symbols may change our opinion about what is frameless. */ @@ -1815,13 +1962,7 @@ reread_symbols (void) again now. */ objfile->mtime = new_modtime; reread_one = 1; - - /* Call this after reading in a new symbol table to give target - dependent code a crack at the new symbols. For instance, this - could be used to update the values of target-specific symbols GDB - needs to keep track of (such as _sigtramp, or whatever). */ - - TARGET_SYMFILE_POSTREAD (objfile); + reread_separate_symbols (objfile); } } } @@ -1829,6 +1970,72 @@ reread_symbols (void) if (reread_one) clear_symtab_users (); } + + +/* Handle separate debug info for OBJFILE, which has just been + re-read: + - If we had separate debug info before, but now we don't, get rid + of the separated objfile. + - If we didn't have separated debug info before, but now we do, + read in the new separated debug info file. + - If the debug link points to a different file, toss the old one + and read the new one. + This function does *not* handle the case where objfile is still + using the same separate debug info file, but that file's timestamp + has changed. That case should be handled by the loop in + reread_symbols already. */ +static void +reread_separate_symbols (struct objfile *objfile) +{ + char *debug_file; + unsigned long crc32; + + /* Does the updated objfile's debug info live in a + separate file? */ + debug_file = find_separate_debug_file (objfile); + + if (objfile->separate_debug_objfile) + { + /* There are two cases where we need to get rid of + the old separated debug info objfile: + - if the new primary objfile doesn't have + separated debug info, or + - if the new primary objfile has separate debug + info, but it's under a different filename. + + If the old and new objfiles both have separate + debug info, under the same filename, then we're + okay --- if the separated file's contents have + changed, we will have caught that when we + visited it in this function's outermost + loop. */ + if (! debug_file + || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0) + free_objfile (objfile->separate_debug_objfile); + } + + /* If the new objfile has separate debug info, and we + haven't loaded it already, do so now. */ + if (debug_file + && ! objfile->separate_debug_objfile) + { + /* Use the same section offset table as objfile itself. + Preserve the flags from objfile that make sense. */ + objfile->separate_debug_objfile + = (symbol_file_add_with_addrs_or_offsets + (debug_file, + info_verbose, /* from_tty: Don't override the default. */ + 0, /* No addr table. */ + objfile->section_offsets, objfile->num_sections, + 0, /* Not mainline. See comments about this above. */ + objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW + | OBJF_USERLOADED))); + objfile->separate_debug_objfile->separate_debug_objfile_backlink + = objfile; + } +} + + @@ -1948,9 +2155,7 @@ init_filename_language_table (void) add_filename_language (".c++", language_cplus); add_filename_language (".java", language_java); add_filename_language (".class", language_java); - add_filename_language (".ch", language_chill); - add_filename_language (".c186", language_chill); - add_filename_language (".c286", language_chill); + add_filename_language (".m", language_objc); add_filename_language (".f", language_fortran); add_filename_language (".F", language_fortran); add_filename_language (".s", language_asm); @@ -1993,17 +2198,17 @@ deduce_language_from_filename (char *filename) struct symtab * allocate_symtab (char *filename, struct objfile *objfile) { - register struct symtab *symtab; + struct symtab *symtab; symtab = (struct symtab *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct symtab)); + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab)); memset (symtab, 0, sizeof (*symtab)); symtab->filename = obsavestring (filename, strlen (filename), - &objfile->symbol_obstack); + &objfile->objfile_obstack); symtab->fullname = NULL; symtab->language = deduce_language_from_filename (filename); symtab->debugformat = obsavestring ("unknown", 7, - &objfile->symbol_obstack); + &objfile->objfile_obstack); /* Hook it to the objfile it comes from */ @@ -2034,12 +2239,12 @@ allocate_psymtab (char *filename, struct objfile *objfile) } else psymtab = (struct partial_symtab *) - obstack_alloc (&objfile->psymbol_obstack, + obstack_alloc (&objfile->objfile_obstack, sizeof (struct partial_symtab)); memset (psymtab, 0, sizeof (struct partial_symtab)); psymtab->filename = obsavestring (filename, strlen (filename), - &objfile->psymbol_obstack); + &objfile->objfile_obstack); psymtab->symtab = NULL; /* Prepend it to the psymtab list for the objfile it belongs to. @@ -2103,8 +2308,7 @@ clear_symtab_users (void) clear_internalvars (); breakpoint_re_set (); set_default_breakpoint (0, 0, 0, 0); - current_source_symtab = 0; - current_source_line = 0; + clear_current_source_symtab_and_line (); clear_pc_function_cache (); if (target_new_objfile_hook) target_new_objfile_hook (NULL); @@ -2189,7 +2393,7 @@ cashier_psymtab (struct partial_symtab *pst) partial_symbol lists (global_psymbols/static_psymbols) that this psymtab points to. These just take up space until all the psymtabs are reclaimed. Ditto the dependencies list and - filename, which are all in the psymbol_obstack. */ + filename, which are all in the objfile_obstack. */ /* We need to cashier any psymtab that has this one as a dependency... */ again: @@ -2233,9 +2437,9 @@ free_named_symtabs (char *name) compilation units. We want to blow away any old info about these compilation units, regardless of which objfiles they arrived in. --gnu. */ - register struct symtab *s; - register struct symtab *prev; - register struct partial_symtab *ps; + struct symtab *s; + struct symtab *prev; + struct partial_symtab *ps; struct blockvector *bv; int blewit = 0; @@ -2252,7 +2456,7 @@ free_named_symtabs (char *name) again2: for (ps = partial_symtab_list; ps; ps = ps->next) { - if (STREQ (name, ps->filename)) + if (strcmp (name, ps->filename) == 0) { cashier_psymtab (ps); /* Blow it away...and its little dog, too. */ goto again2; /* Must restart, chain has been munged */ @@ -2263,7 +2467,7 @@ again2: for (s = symtab_list; s; s = s->next) { - if (STREQ (name, s->filename)) + if (strcmp (name, s->filename) == 0) break; prev = s; } @@ -2290,15 +2494,16 @@ again2: || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK))) { - complain (&oldsyms_complaint, name); - + complaint (&symfile_complaints, "Replacing old symbols for `%s'", + name); clear_symtab_users_queued++; make_cleanup (clear_symtab_users_once, 0); blewit = 1; } else { - complain (&empty_symtab_complaint, name); + complaint (&symfile_complaints, "Empty symbol table found for `%s'", + name); } free_symtab (s); @@ -2344,16 +2549,28 @@ start_psymtab_common (struct objfile *objfile, } /* Add a symbol with a long value to a psymtab. - Since one arg is a struct, we pass in a ptr and deref it (sigh). */ + Since one arg is a struct, we pass in a ptr and deref it (sigh). + Return the partial symbol that has been added. */ -void -add_psymbol_to_list (char *name, int namelength, namespace_enum namespace, +/* NOTE: carlton/2003-09-11: The reason why we return the partial + symbol is so that callers can get access to the symbol's demangled + name, which they don't have any cheap way to determine otherwise. + (Currenly, dwarf2read.c is the only file who uses that information, + though it's possible that other readers might in the future.) + Elena wasn't thrilled about that, and I don't blame her, but we + couldn't come up with a better way to get that information. If + it's needed in other situations, we could consider breaking up + SYMBOL_SET_NAMES to provide access to the demangled name lookup + cache. */ + +const struct partial_symbol * +add_psymbol_to_list (char *name, int namelength, domain_enum domain, enum address_class class, struct psymbol_allocation_list *list, long val, /* Value as a long */ CORE_ADDR coreaddr, /* Value as a CORE_ADDR */ enum language language, struct objfile *objfile) { - register struct partial_symbol *psym; + struct partial_symbol *psym; char *buf = alloca (namelength + 1); /* psymbol is static so that there will be no uninitialized gaps in the structure which might contain random data, causing cache misses in @@ -2363,7 +2580,6 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace, /* Create local copy of the partial symbol */ memcpy (buf, name, namelength); buf[namelength] = '\0'; - SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache); /* val and coreaddr are mutually exclusive, one of them *will* be zero */ if (val != 0) { @@ -2375,12 +2591,14 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace, } SYMBOL_SECTION (&psymbol) = 0; SYMBOL_LANGUAGE (&psymbol) = language; - PSYMBOL_NAMESPACE (&psymbol) = namespace; + PSYMBOL_DOMAIN (&psymbol) = domain; PSYMBOL_CLASS (&psymbol) = class; - SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language); + + SYMBOL_SET_NAMES (&psymbol, buf, namelength, objfile); /* Stash the partial symbol away in the cache */ - psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache); + psym = deprecated_bcache (&psymbol, sizeof (struct partial_symbol), + objfile->psymbol_cache); /* Save pointer to partial symbol in psymtab, growing symtab if needed. */ if (list->next >= list->list + list->size) @@ -2389,6 +2607,8 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace, } *list->next++ = psym; OBJSTAT (objfile, n_psyms++); + + return psym; } /* Add a symbol with a long value to a psymtab. This differs from @@ -2397,14 +2617,14 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace, void add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name, - int dem_namelength, namespace_enum namespace, + int dem_namelength, domain_enum domain, enum address_class class, struct psymbol_allocation_list *list, long val, /* Value as a long */ CORE_ADDR coreaddr, /* Value as a CORE_ADDR */ enum language language, struct objfile *objfile) { - register struct partial_symbol *psym; + struct partial_symbol *psym; char *buf = alloca (namelength + 1); /* psymbol is static so that there will be no uninitialized gaps in the structure which might contain random data, causing cache misses in @@ -2415,7 +2635,8 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name, memcpy (buf, name, namelength); buf[namelength] = '\0'; - SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache); + DEPRECATED_SYMBOL_NAME (&psymbol) = deprecated_bcache (buf, namelength + 1, + objfile->psymbol_cache); buf = alloca (dem_namelength + 1); memcpy (buf, dem_name, dem_namelength); @@ -2426,12 +2647,8 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name, case language_c: case language_cplus: SYMBOL_CPLUS_DEMANGLED_NAME (&psymbol) = - bcache (buf, dem_namelength + 1, &objfile->psymbol_cache); + deprecated_bcache (buf, dem_namelength + 1, objfile->psymbol_cache); break; - case language_chill: - SYMBOL_CHILL_DEMANGLED_NAME (&psymbol) = - bcache (buf, dem_namelength + 1, &objfile->psymbol_cache); - /* FIXME What should be done for the default case? Ignoring for now. */ } @@ -2446,12 +2663,13 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name, } SYMBOL_SECTION (&psymbol) = 0; SYMBOL_LANGUAGE (&psymbol) = language; - PSYMBOL_NAMESPACE (&psymbol) = namespace; + PSYMBOL_DOMAIN (&psymbol) = domain; PSYMBOL_CLASS (&psymbol) = class; SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language); /* Stash the partial symbol away in the cache */ - psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache); + psym = deprecated_bcache (&psymbol, sizeof (struct partial_symbol), + objfile->psymbol_cache); /* Save pointer to partial symbol in psymtab, growing symtab if needed. */ if (list->next >= list->list + list->size) @@ -2471,11 +2689,11 @@ init_psymbol_list (struct objfile *objfile, int total_symbols) if (objfile->global_psymbols.list) { - xmfree (objfile->md, (PTR) objfile->global_psymbols.list); + xmfree (objfile->md, objfile->global_psymbols.list); } if (objfile->static_psymbols.list) { - xmfree (objfile->md, (PTR) objfile->static_psymbols.list); + xmfree (objfile->md, objfile->static_psymbols.list); } /* Current best guess is that approximately a twentieth @@ -2691,7 +2909,7 @@ pc_in_mapped_range (CORE_ADDR pc, asection *section) /* Return true if the mapped ranges of sections A and B overlap, false otherwise. */ -int +static int sections_overlap (asection *a, asection *b) { /* FIXME: need bfd *, so we can use bfd_section_vma methods. */ @@ -2893,7 +3111,7 @@ the 'overlay manual' command."); sec2->the_bfd_section)) { if (info_verbose) - printf_filtered ("Note: section %s unmapped by overlap\n", + printf_unfiltered ("Note: section %s unmapped by overlap\n", bfd_section_name (objfile->obfd, sec2->the_bfd_section)); sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2 */ @@ -2943,7 +3161,7 @@ overlay_auto_command (char *args, int from_tty) overlay_debugging = ovly_auto; enable_overlay_breakpoints (); if (info_verbose) - printf_filtered ("Automatic overlay debugging enabled."); + printf_unfiltered ("Automatic overlay debugging enabled."); } /* Function: overlay_manual_command @@ -2956,7 +3174,7 @@ overlay_manual_command (char *args, int from_tty) overlay_debugging = ovly_on; disable_overlay_breakpoints (); if (info_verbose) - printf_filtered ("Overlay debugging enabled."); + printf_unfiltered ("Overlay debugging enabled."); } /* Function: overlay_off_command @@ -2969,7 +3187,7 @@ overlay_off_command (char *args, int from_tty) overlay_debugging = ovly_off; disable_overlay_breakpoints (); if (info_verbose) - printf_filtered ("Overlay debugging disabled."); + printf_unfiltered ("Overlay debugging disabled."); } static void @@ -3247,6 +3465,45 @@ simple_overlay_update (struct obj_section *osect) } } +/* Set the output sections and output offsets for section SECTP in + ABFD. The relocation code in BFD will read these offsets, so we + need to be sure they're initialized. We map each section to itself, + with no offset; this means that SECTP->vma will be honored. */ + +static void +symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy) +{ + sectp->output_section = sectp; + sectp->output_offset = 0; +} + +/* Relocate the contents of a debug section SECTP in ABFD. The + contents are stored in BUF if it is non-NULL, or returned in a + malloc'd buffer otherwise. + + For some platforms and debug info formats, shared libraries contain + relocations against the debug sections (particularly for DWARF-2; + one affected platform is PowerPC GNU/Linux, although it depends on + the version of the linker in use). Also, ELF object files naturally + have unresolved relocations for their debug sections. We need to apply + the relocations in order to get the locations of symbols correct. */ + +bfd_byte * +symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf) +{ + /* We're only interested in debugging sections with relocation + information. */ + if ((sectp->flags & SEC_RELOC) == 0) + return NULL; + if ((sectp->flags & SEC_DEBUGGING) == 0) + return NULL; + + /* We will handle section offsets properly elsewhere, so relocate as if + all sections begin at 0. */ + bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL); + + return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL); +} void _initialize_symfile (void) @@ -3257,7 +3514,7 @@ _initialize_symfile (void) "Load symbol table from executable file FILE.\n\ The `file' command can also load symbol tables, as well as setting the file\n\ to execute.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command, "Usage: add-symbol-file FILE ADDR [-s -s ...]\n\ @@ -3265,9 +3522,9 @@ Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\ ADDR is the starting address of the file's text.\n\ The optional arguments are section-name section-address pairs and\n\ should be specified if the data and bss segments are not contiguous\n\ -with the text. SECT is a section name to be loaded at SECT_ADDR.", +with the text. SECT is a section name to be loaded at SECT_ADDR.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); c = add_cmd ("add-shared-symbol-files", class_files, add_shared_symbol_files_command, @@ -3279,7 +3536,7 @@ with the text. SECT is a section name to be loaded at SECT_ADDR.", c = add_cmd ("load", class_files, load_command, "Dynamically load FILE into the running program, and record its symbols\n\ for access from GDB.", &cmdlist); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_show_from_set (add_set_cmd ("symbol-reloading", class_support, var_boolean, @@ -3336,4 +3593,18 @@ Usage: set extension-language .foo bar", "cache.\n", &setlist), &showlist); + + debug_file_directory = xstrdup (DEBUGDIR); + c = (add_set_cmd + ("debug-file-directory", class_support, var_string, + (char *) &debug_file_directory, + "Set the directory where separate debug symbols are searched for.\n" + "Separate debug symbols are first searched for in the same\n" + "directory as the binary, then in the `" DEBUG_SUBDIRECTORY + "' subdirectory,\n" + "and lastly at the path of the directory of the binary with\n" + "the global debug-file directory prepended\n", + &setlist)); + add_show_from_set (c, &showlist); + set_cmd_completer (c, filename_completer); } diff --git a/contrib/gdb/gdb/symfile.h b/contrib/gdb/gdb/symfile.h index 39eb3080f13..baa353e494c 100644 --- a/contrib/gdb/gdb/symfile.h +++ b/contrib/gdb/gdb/symfile.h @@ -1,7 +1,7 @@ /* Definitions for reading symbol files into GDB. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -25,135 +25,147 @@ /* This file requires that you first include "bfd.h". */ -/* Partial symbols are stored in the psymbol_cache and pointers to them - are kept in a dynamically grown array that is obtained from malloc and - grown as necessary via realloc. Each objfile typically has two of these, - one for global symbols and one for static symbols. Although this adds - a level of indirection for storing or accessing the partial symbols, - it allows us to throw away duplicate psymbols and set all pointers - to the single saved instance. */ +/* Opaque declarations. */ +struct section_table; +struct objfile; +struct obstack; +struct block; + +/* Partial symbols are stored in the psymbol_cache and pointers to + them are kept in a dynamically grown array that is obtained from + malloc and grown as necessary via realloc. Each objfile typically + has two of these, one for global symbols and one for static + symbols. Although this adds a level of indirection for storing or + accessing the partial symbols, it allows us to throw away duplicate + psymbols and set all pointers to the single saved instance. */ struct psymbol_allocation_list - { +{ - /* Pointer to beginning of dynamically allocated array of pointers to - partial symbols. The array is dynamically expanded as necessary to - accommodate more pointers. */ + /* Pointer to beginning of dynamically allocated array of pointers + to partial symbols. The array is dynamically expanded as + necessary to accommodate more pointers. */ - struct partial_symbol **list; + struct partial_symbol **list; - /* Pointer to next available slot in which to store a pointer to a partial - symbol. */ + /* Pointer to next available slot in which to store a pointer to a + partial symbol. */ - struct partial_symbol **next; + struct partial_symbol **next; - /* Number of allocated pointer slots in current dynamic array (not the - number of bytes of storage). The "next" pointer will always point - somewhere between list[0] and list[size], and when at list[size] the - array will be expanded on the next attempt to store a pointer. */ + /* Number of allocated pointer slots in current dynamic array (not + the number of bytes of storage). The "next" pointer will always + point somewhere between list[0] and list[size], and when at + list[size] the array will be expanded on the next attempt to + store a pointer. */ - int size; - }; + int size; +}; /* Define an array of addresses to accommodate non-contiguous dynamic loading of modules. This is for use when entering commands, so we - can keep track of the section names until we read the file and - can map them to bfd sections. This structure is also used by - solib.c to communicate the section addresses in shared objects to - symbol_file_add (). */ - -#define MAX_SECTIONS 64 -struct section_addr_info + can keep track of the section names until we read the file and can + map them to bfd sections. This structure is also used by solib.c + to communicate the section addresses in shared objects to + symbol_file_add (). */ + +struct section_addr_info { + /* The number of sections for which address information is + available. */ + size_t num_sections; /* Sections whose names are file format dependent. */ struct other_sections { CORE_ADDR addr; char *name; int sectindex; - } other[MAX_SECTIONS]; + } other[1]; }; /* Structure to keep track of symbol reading functions for various object file types. */ struct sym_fns - { +{ - /* BFD flavour that we handle, or (as a special kludge, see xcoffread.c, - (enum bfd_flavour)-1 for xcoff). */ + /* BFD flavour that we handle, or (as a special kludge, see + xcoffread.c, (enum bfd_flavour)-1 for xcoff). */ - enum bfd_flavour sym_flavour; + enum bfd_flavour sym_flavour; - /* Initializes anything that is global to the entire symbol table. It is - called during symbol_file_add, when we begin debugging an entirely new - program. */ + /* Initializes anything that is global to the entire symbol table. + It is called during symbol_file_add, when we begin debugging an + entirely new program. */ - void (*sym_new_init) (struct objfile *); + void (*sym_new_init) (struct objfile *); - /* Reads any initial information from a symbol file, and initializes the - struct sym_fns SF in preparation for sym_read(). It is called every - time we read a symbol file for any reason. */ + /* Reads any initial information from a symbol file, and initializes + the struct sym_fns SF in preparation for sym_read(). It is + called every time we read a symbol file for any reason. */ - void (*sym_init) (struct objfile *); + void (*sym_init) (struct objfile *); - /* sym_read (objfile, mainline) - Reads a symbol file into a psymtab (or possibly a symtab). - OBJFILE is the objfile struct for the file we are reading. - MAINLINE is 1 if this is the - main symbol table being read, and 0 if a secondary - symbol file (e.g. shared library or dynamically loaded file) - is being read. */ + /* sym_read (objfile, mainline) Reads a symbol file into a psymtab + (or possibly a symtab). OBJFILE is the objfile struct for the + file we are reading. MAINLINE is 1 if this is the main symbol + table being read, and 0 if a secondary symbol file (e.g. shared + library or dynamically loaded file) is being read. */ - void (*sym_read) (struct objfile *, int); + void (*sym_read) (struct objfile *, int); - /* Called when we are finished with an objfile. Should do all cleanup - that is specific to the object file format for the particular objfile. */ + /* Called when we are finished with an objfile. Should do all + cleanup that is specific to the object file format for the + particular objfile. */ - void (*sym_finish) (struct objfile *); + void (*sym_finish) (struct objfile *); - /* This function produces a file-dependent section_offsets structure, - allocated in the objfile's storage, and based on the parameter. - The parameter is currently a CORE_ADDR (FIXME!) for backward compatibility - with the higher levels of GDB. It should probably be changed to - a string, where NULL means the default, and others are parsed in a file - dependent way. */ + /* This function produces a file-dependent section_offsets + structure, allocated in the objfile's storage, and based on the + parameter. The parameter is currently a CORE_ADDR (FIXME!) for + backward compatibility with the higher levels of GDB. It should + probably be changed to a string, where NULL means the default, + and others are parsed in a file dependent way. */ - void (*sym_offsets) (struct objfile *, struct section_addr_info *); + void (*sym_offsets) (struct objfile *, struct section_addr_info *); - /* Finds the next struct sym_fns. They are allocated and initialized - in whatever module implements the functions pointed to; an - initializer calls add_symtab_fns to add them to the global chain. */ + /* Finds the next struct sym_fns. They are allocated and + initialized in whatever module implements the functions pointed + to; an initializer calls add_symtab_fns to add them to the global + chain. */ - struct sym_fns *next; + struct sym_fns *next; - }; +}; /* The default version of sym_fns.sym_offsets for readers that don't do anything special. */ -extern void -default_symfile_offsets (struct objfile *objfile, struct section_addr_info *); +extern void default_symfile_offsets (struct objfile *objfile, + struct section_addr_info *); -extern void -extend_psymbol_list (struct psymbol_allocation_list *, struct objfile *); +extern void extend_psymbol_list (struct psymbol_allocation_list *, + struct objfile *); -/* Add any kind of symbol to a psymbol_allocation_list. */ +/* Add any kind of symbol to a psymbol_allocation_list. */ /* #include "demangle.h" */ -extern void -add_psymbol_to_list (char *, int, namespace_enum, enum address_class, - struct psymbol_allocation_list *, long, CORE_ADDR, - enum language, struct objfile *); +extern const +struct partial_symbol *add_psymbol_to_list (char *, int, domain_enum, + enum address_class, + struct psymbol_allocation_list *, + long, CORE_ADDR, + enum language, struct objfile *); -extern void -add_psymbol_with_dem_name_to_list (char *, int, char *, int, namespace_enum, - enum address_class, - struct psymbol_allocation_list *, - long, CORE_ADDR, - enum language, struct objfile *); +extern void add_psymbol_with_dem_name_to_list (char *, int, char *, int, + domain_enum, + enum address_class, + struct psymbol_allocation_list + *, long, CORE_ADDR, + enum language, + struct objfile *); extern void init_psymbol_list (struct objfile *, int); @@ -168,28 +180,33 @@ extern void fill_in_vptr_fieldno (struct type *); extern void add_symtab_fns (struct sym_fns *); -extern void init_entry_point_info (struct objfile *); - -extern void -syms_from_objfile (struct objfile *, struct section_addr_info *, int, int); +extern void syms_from_objfile (struct objfile *, + struct section_addr_info *, + struct section_offsets *, int, int, int); extern void new_symfile_objfile (struct objfile *, int, int); extern struct objfile *symbol_file_add (char *, int, struct section_addr_info *, int, int); -/* Build (allocate and populate) a section_addr_info struct from - an existing section table. */ +/* Create a new section_addr_info, with room for NUM_SECTIONS. */ -struct section_table; -extern struct section_addr_info * -build_section_addr_info_from_section_table (const struct section_table *start, - const struct section_table *end); +extern struct section_addr_info *alloc_section_addr_info (size_t + num_sections); -/* Free all memory allocated by build_section_addr_info_from_section_table. */ +/* Build (allocate and populate) a section_addr_info struct from an + existing section table. */ -extern void -free_section_addr_info (struct section_addr_info *); +extern struct section_addr_info + *build_section_addr_info_from_section_table (const struct section_table + *start, + const struct section_table + *end); + +/* Free all memory allocated by + build_section_addr_info_from_section_table. */ + +extern void free_section_addr_info (struct section_addr_info *); extern struct partial_symtab *start_psymtab_common (struct objfile *, @@ -198,20 +215,14 @@ extern struct partial_symtab *start_psymtab_common (struct objfile *, struct partial_symbol **, struct partial_symbol **); -/* Sorting your symbols for fast lookup or alphabetical printing. */ +/* Make a copy of the string at PTR with SIZE characters in the symbol + obstack (and add a null character at the end in the copy). Returns + the address of the copy. */ -extern void sort_block_syms (struct block *); +extern char *obsavestring (const char *, int, struct obstack *); -extern void sort_symtab_syms (struct symtab *); - -/* Make a copy of the string at PTR with SIZE characters in the symbol obstack - (and add a null character at the end in the copy). - Returns the address of the copy. */ - -extern char *obsavestring (char *, int, struct obstack *); - -/* Concatenate strings S1, S2 and S3; return the new string. - Space is found in the symbol_obstack. */ +/* Concatenate strings S1, S2 and S3; return the new string. Space is + found in the OBSTACKP */ extern char *obconcat (struct obstack *obstackp, const char *, const char *, const char *); @@ -226,7 +237,7 @@ extern char *obconcat (struct obstack *obstackp, const char *, const char *, this flag and then add the shared library symbols as needed. Note that there is a potential for confusion, since if the shared library symbols are not loaded, commands like "info fun" will *not* - report all the functions that are actually present. */ + report all the functions that are actually present. */ extern int auto_solib_add; @@ -235,75 +246,76 @@ extern int auto_solib_add; known to the debugger would cause the total shared library symbol size to exceed this threshhold, then the shlib's symbols are not added. The threshold is ignored if the user explicitly asks for a - shlib to be added, such as when using the "sharedlibrary" - command. */ + shlib to be added, such as when using the "sharedlibrary" command. */ extern int auto_solib_limit; /* From symfile.c */ -extern CORE_ADDR entry_point_address (void); - extern struct partial_symtab *allocate_psymtab (char *, struct objfile *); extern void discard_psymtab (struct partial_symtab *); -extern void find_lowest_section (bfd *, asection *, PTR); +extern void find_lowest_section (bfd *, asection *, void *); extern bfd *symfile_bfd_open (char *); extern int get_section_index (struct objfile *, char *); /* Utility functions for overlay sections: */ -extern enum overlay_debugging_state { - ovly_off, - ovly_on, +extern enum overlay_debugging_state +{ + ovly_off, + ovly_on, ovly_auto } overlay_debugging; extern int overlay_cache_invalid; -/* return the "mapped" overlay section containing the PC */ +/* Return the "mapped" overlay section containing the PC. */ extern asection *find_pc_mapped_section (CORE_ADDR); -/* return any overlay section containing the PC (even in its LMA region) */ +/* Return any overlay section containing the PC (even in its LMA + region). */ extern asection *find_pc_overlay (CORE_ADDR); -/* return true if the section is an overlay */ +/* Return true if the section is an overlay. */ extern int section_is_overlay (asection *); -/* return true if the overlay section is currently "mapped" */ +/* Return true if the overlay section is currently "mapped". */ extern int section_is_mapped (asection *); -/* return true if pc belongs to section's VMA */ +/* Return true if pc belongs to section's VMA. */ extern CORE_ADDR pc_in_mapped_range (CORE_ADDR, asection *); -/* return true if pc belongs to section's LMA */ +/* Return true if pc belongs to section's LMA. */ extern CORE_ADDR pc_in_unmapped_range (CORE_ADDR, asection *); -/* map an address from a section's LMA to its VMA */ +/* Map an address from a section's LMA to its VMA. */ extern CORE_ADDR overlay_mapped_address (CORE_ADDR, asection *); -/* map an address from a section's VMA to its LMA */ +/* Map an address from a section's VMA to its LMA. */ extern CORE_ADDR overlay_unmapped_address (CORE_ADDR, asection *); -/* convert an address in an overlay section (force into VMA range) */ +/* Convert an address in an overlay section (force into VMA range). */ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *); -/* Load symbols from a file. */ +/* Load symbols from a file. */ extern void symbol_file_add_main (char *args, int from_tty); -/* Clear GDB symbol tables. */ +/* Clear GDB symbol tables. */ extern void symbol_file_clear (int from_tty); +extern bfd_byte *symfile_relocate_debug_section (bfd *abfd, asection *sectp, + bfd_byte * buf); + /* From dwarfread.c */ -extern void -dwarf_build_psymtabs (struct objfile *, int, file_ptr, unsigned int, - file_ptr, unsigned int); +extern void dwarf_build_psymtabs (struct objfile *, int, file_ptr, + unsigned int, file_ptr, unsigned int); /* From dwarf2read.c */ -extern int dwarf2_has_info (bfd * abfd); +extern int dwarf2_has_info (bfd *abfd); extern void dwarf2_build_psymtabs (struct objfile *, int); extern void dwarf2_build_frame_info (struct objfile *); @@ -312,17 +324,17 @@ extern void dwarf2_build_frame_info (struct objfile *); /* Hack to force structures to exist before use in parameter list. */ struct ecoff_debug_hack - { - struct ecoff_debug_swap *a; - struct ecoff_debug_info *b; - }; -extern void -mdebug_build_psymtabs (struct objfile *, - const struct ecoff_debug_swap *, - struct ecoff_debug_info *); +{ + struct ecoff_debug_swap *a; + struct ecoff_debug_info *b; +}; -extern void -elfmdebug_build_psymtabs (struct objfile *, - const struct ecoff_debug_swap *, asection *); +extern void mdebug_build_psymtabs (struct objfile *, + const struct ecoff_debug_swap *, + struct ecoff_debug_info *); + +extern void elfmdebug_build_psymtabs (struct objfile *, + const struct ecoff_debug_swap *, + asection *); #endif /* !defined(SYMFILE_H) */ diff --git a/contrib/gdb/gdb/symmisc.c b/contrib/gdb/gdb/symmisc.c index 3c129886e5b..c17bda4783d 100644 --- a/contrib/gdb/gdb/symmisc.c +++ b/contrib/gdb/gdb/symmisc.c @@ -1,6 +1,8 @@ /* Do various things to symbol tables (other than lookup), for GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -27,11 +29,15 @@ #include "objfiles.h" #include "breakpoint.h" #include "command.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "language.h" #include "bcache.h" +#include "block.h" +#include "gdb_regex.h" +#include "dictionary.h" #include "gdb_string.h" +#include "readline/readline.h" #ifndef DEV_TTY #define DEV_TTY "/dev/tty" @@ -75,24 +81,30 @@ struct print_symbol_args struct ui_file *outfile; }; -static int print_symbol (PTR); +static int print_symbol (void *); static void free_symtab_block (struct objfile *, struct block *); /* Free a struct block <- B and all the symbols defined in that block. */ +/* FIXME: carlton/2003-04-28: I don't believe this is currently ever + used. */ + static void free_symtab_block (struct objfile *objfile, struct block *b) { - register int i, n; - n = BLOCK_NSYMS (b); - for (i = 0; i < n; i++) + struct dict_iterator iter; + struct symbol *sym; + + ALL_BLOCK_SYMBOLS (b, iter, sym) { - xmfree (objfile->md, SYMBOL_NAME (BLOCK_SYM (b, i))); - xmfree (objfile->md, (PTR) BLOCK_SYM (b, i)); + xmfree (objfile->md, DEPRECATED_SYMBOL_NAME (sym)); + xmfree (objfile->md, sym); } - xmfree (objfile->md, (PTR) b); + + dict_free (BLOCK_DICT (b)); + xmfree (objfile->md, b); } /* Free all the storage associated with the struct symtab <- S. @@ -104,10 +116,10 @@ free_symtab_block (struct objfile *objfile, struct block *b) It is s->free_code that says which alternative to use. */ void -free_symtab (register struct symtab *s) +free_symtab (struct symtab *s) { - register int i, n; - register struct blockvector *bv; + int i, n; + struct blockvector *bv; switch (s->free_code) { @@ -126,30 +138,30 @@ free_symtab (register struct symtab *s) for (i = 0; i < n; i++) free_symtab_block (s->objfile, BLOCKVECTOR_BLOCK (bv, i)); /* Free the blockvector itself. */ - xmfree (s->objfile->md, (PTR) bv); + xmfree (s->objfile->md, bv); /* Also free the linetable. */ case free_linetable: - /* Everything will be freed either by our `free_ptr' + /* Everything will be freed either by our `free_func' or by some other symtab, except for our linetable. Free that now. */ if (LINETABLE (s)) - xmfree (s->objfile->md, (PTR) LINETABLE (s)); + xmfree (s->objfile->md, LINETABLE (s)); break; } /* If there is a single block of memory to free, free it. */ - if (s->free_ptr != NULL) - xmfree (s->objfile->md, s->free_ptr); + if (s->free_func != NULL) + s->free_func (s); /* Free source-related stuff */ if (s->line_charpos != NULL) - xmfree (s->objfile->md, (PTR) s->line_charpos); + xmfree (s->objfile->md, s->line_charpos); if (s->fullname != NULL) xmfree (s->objfile->md, s->fullname); if (s->debugformat != NULL) xmfree (s->objfile->md, s->debugformat); - xmfree (s->objfile->md, (PTR) s); + xmfree (s->objfile->md, s); } void @@ -161,7 +173,7 @@ print_symbol_bcache_statistics (void) ALL_OBJFILES (objfile) { printf_filtered ("Byte cache statistics for '%s':\n", objfile->name); - print_bcache_statistics (&objfile->psymbol_cache, "partial symbol cache"); + print_bcache_statistics (objfile->psymbol_cache, "partial symbol cache"); } immediate_quit--; } @@ -170,6 +182,9 @@ void print_objfile_statistics (void) { struct objfile *objfile; + struct symtab *s; + struct partial_symtab *ps; + int i, linetables, blockvectors; immediate_quit++; ALL_OBJFILES (objfile) @@ -190,17 +205,37 @@ print_objfile_statistics (void) if (OBJSTAT (objfile, n_types) > 0) printf_filtered (" Number of \"types\" defined: %d\n", OBJSTAT (objfile, n_types)); + i = 0; + ALL_OBJFILE_PSYMTABS (objfile, ps) + { + if (ps->readin == 0) + i++; + } + printf_filtered (" Number of psym tables (not yet expanded): %d\n", i); + i = linetables = blockvectors = 0; + ALL_OBJFILE_SYMTABS (objfile, s) + { + i++; + if (s->linetable != NULL) + linetables++; + if (s->primary == 1) + blockvectors++; + } + printf_filtered (" Number of symbol tables: %d\n", i); + printf_filtered (" Number of symbol tables with line tables: %d\n", + linetables); + printf_filtered (" Number of symbol tables with blockvectors: %d\n", + blockvectors); + if (OBJSTAT (objfile, sz_strtab) > 0) printf_filtered (" Space used by a.out string tables: %d\n", OBJSTAT (objfile, sz_strtab)); - printf_filtered (" Total memory used for psymbol obstack: %d\n", - obstack_memory_used (&objfile->psymbol_obstack)); + printf_filtered (" Total memory used for objfile obstack: %d\n", + obstack_memory_used (&objfile->objfile_obstack)); printf_filtered (" Total memory used for psymbol cache: %d\n", - obstack_memory_used (&objfile->psymbol_cache.cache)); - printf_filtered (" Total memory used for symbol obstack: %d\n", - obstack_memory_used (&objfile->symbol_obstack)); - printf_filtered (" Total memory used for type obstack: %d\n", - obstack_memory_used (&objfile->type_obstack)); + bcache_memory_used (objfile->psymbol_cache)); + printf_filtered (" Total memory used for macro cache: %d\n", + bcache_memory_used (objfile->macro_cache)); } immediate_quit--; } @@ -275,7 +310,7 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile) return; } for (index = 0, msymbol = objfile->msymbols; - SYMBOL_NAME (msymbol) != NULL; msymbol++, index++) + DEPRECATED_SYMBOL_NAME (msymbol) != NULL; msymbol++, index++) { switch (msymbol->type) { @@ -312,7 +347,7 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile) } fprintf_filtered (outfile, "[%2d] %c ", index, ms_type); print_address_numeric (SYMBOL_VALUE_ADDRESS (msymbol), 1, outfile); - fprintf_filtered (outfile, " %s", SYMBOL_NAME (msymbol)); + fprintf_filtered (outfile, " %s", DEPRECATED_SYMBOL_NAME (msymbol)); if (SYMBOL_BFD_SECTION (msymbol)) fprintf_filtered (outfile, " section %s", bfd_section_name (objfile->obfd, @@ -357,7 +392,7 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab, " Full symtab was read (at "); gdb_print_host_address (psymtab->symtab, outfile); fprintf_filtered (outfile, " by function at "); - gdb_print_host_address ((PTR) psymtab->read_symtab, outfile); + gdb_print_host_address (psymtab->read_symtab, outfile); fprintf_filtered (outfile, ")\n"); } @@ -406,12 +441,13 @@ static void dump_symtab (struct objfile *objfile, struct symtab *symtab, struct ui_file *outfile) { - register int i, j; + int i; + struct dict_iterator iter; int len, blen; - register struct linetable *l; + struct linetable *l; struct blockvector *bv; struct symbol *sym; - register struct block *b; + struct block *b; int depth; fprintf_filtered (outfile, "\nSymtab for file %s\n", symtab->filename); @@ -455,14 +491,17 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab, fprintf_filtered (outfile, " under "); gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile); } - blen = BLOCK_NSYMS (b); - fprintf_filtered (outfile, ", %d syms in ", blen); + /* drow/2002-07-10: We could save the total symbols count + even if we're using a hashtable, but nothing else but this message + wants it. */ + fprintf_filtered (outfile, ", %d syms/buckets in ", + dict_size (BLOCK_DICT (b))); print_address_numeric (BLOCK_START (b), 1, outfile); fprintf_filtered (outfile, ".."); print_address_numeric (BLOCK_END (b), 1, outfile); if (BLOCK_FUNCTION (b)) { - fprintf_filtered (outfile, ", function %s", SYMBOL_NAME (BLOCK_FUNCTION (b))); + fprintf_filtered (outfile, ", function %s", DEPRECATED_SYMBOL_NAME (BLOCK_FUNCTION (b))); if (SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)) != NULL) { fprintf_filtered (outfile, ", %s", @@ -472,9 +511,9 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab, if (BLOCK_GCC_COMPILED (b)) fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED (b)); fprintf_filtered (outfile, "\n"); - /* Now print each symbol in this block. */ - /* FIXMED: Sort? */ - ALL_BLOCK_SYMBOLS (b, j, sym) + /* Now print each symbol in this block (in no particular order, if + we're using a hashtable). */ + ALL_BLOCK_SYMBOLS (b, iter, sym) { struct print_symbol_args s; s.symbol = sym; @@ -536,7 +575,7 @@ Arguments missing: an output file name and an optional symbol file name"); immediate_quit++; ALL_SYMTABS (objfile, s) - if (symname == NULL || (STREQ (symname, s->filename))) + if (symname == NULL || strcmp (symname, s->filename) == 0) dump_symtab (objfile, s, outfile); immediate_quit--; do_cleanups (cleanups); @@ -548,16 +587,16 @@ Arguments missing: an output file name and an optional symbol file name"); 1 for success. */ static int -print_symbol (PTR args) +print_symbol (void *args) { struct symbol *symbol = ((struct print_symbol_args *) args)->symbol; int depth = ((struct print_symbol_args *) args)->depth; struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile; print_spaces (depth, outfile); - if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE) + if (SYMBOL_DOMAIN (symbol) == LABEL_DOMAIN) { - fprintf_filtered (outfile, "label %s at ", SYMBOL_SOURCE_NAME (symbol)); + fprintf_filtered (outfile, "label %s at ", SYMBOL_PRINT_NAME (symbol)); print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile); if (SYMBOL_BFD_SECTION (symbol)) fprintf_filtered (outfile, " section %s\n", @@ -567,7 +606,7 @@ print_symbol (PTR args) fprintf_filtered (outfile, "\n"); return 1; } - if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE) + if (SYMBOL_DOMAIN (symbol) == STRUCT_DOMAIN) { if (TYPE_TAG_NAME (SYMBOL_TYPE (symbol))) { @@ -580,7 +619,7 @@ print_symbol (PTR args) ? "enum" : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT ? "struct" : "union")), - SYMBOL_NAME (symbol)); + DEPRECATED_SYMBOL_NAME (symbol)); LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth); } fprintf_filtered (outfile, ";\n"); @@ -592,14 +631,14 @@ print_symbol (PTR args) if (SYMBOL_TYPE (symbol)) { /* Print details of types, except for enums where it's clutter. */ - LA_PRINT_TYPE (SYMBOL_TYPE (symbol), SYMBOL_SOURCE_NAME (symbol), + LA_PRINT_TYPE (SYMBOL_TYPE (symbol), SYMBOL_PRINT_NAME (symbol), outfile, TYPE_CODE (SYMBOL_TYPE (symbol)) != TYPE_CODE_ENUM, depth); fprintf_filtered (outfile, "; "); } else - fprintf_filtered (outfile, "%s ", SYMBOL_SOURCE_NAME (symbol)); + fprintf_filtered (outfile, "%s ", SYMBOL_PRINT_NAME (symbol)); switch (SYMBOL_CLASS (symbol)) { @@ -709,6 +748,11 @@ print_symbol (PTR args) SYMBOL_BFD_SECTION (symbol))); break; + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + fprintf_filtered (outfile, "computed at runtime"); + break; + case LOC_UNRESOLVED: fprintf_filtered (outfile, "unresolved"); break; @@ -770,7 +814,7 @@ maintenance_print_psymbols (char *args, int from_tty) immediate_quit++; ALL_PSYMTABS (objfile, ps) - if (symname == NULL || (STREQ (symname, ps->filename))) + if (symname == NULL || strcmp (symname, ps->filename) == 0) dump_psymtab (objfile, ps, outfile); immediate_quit--; do_cleanups (cleanups); @@ -783,28 +827,28 @@ print_partial_symbols (struct partial_symbol **p, int count, char *what, fprintf_filtered (outfile, " %s partial symbols:\n", what); while (count-- > 0) { - fprintf_filtered (outfile, " `%s'", SYMBOL_NAME (*p)); + fprintf_filtered (outfile, " `%s'", DEPRECATED_SYMBOL_NAME (*p)); if (SYMBOL_DEMANGLED_NAME (*p) != NULL) { fprintf_filtered (outfile, " `%s'", SYMBOL_DEMANGLED_NAME (*p)); } fputs_filtered (", ", outfile); - switch (SYMBOL_NAMESPACE (*p)) + switch (SYMBOL_DOMAIN (*p)) { - case UNDEF_NAMESPACE: - fputs_filtered ("undefined namespace, ", outfile); + case UNDEF_DOMAIN: + fputs_filtered ("undefined domain, ", outfile); break; - case VAR_NAMESPACE: + case VAR_DOMAIN: /* This is the usual thing -- don't print it */ break; - case STRUCT_NAMESPACE: - fputs_filtered ("struct namespace, ", outfile); + case STRUCT_DOMAIN: + fputs_filtered ("struct domain, ", outfile); break; - case LABEL_NAMESPACE: - fputs_filtered ("label namespace, ", outfile); + case LABEL_DOMAIN: + fputs_filtered ("label domain, ", outfile); break; default: - fputs_filtered (", ", outfile); + fputs_filtered (", ", outfile); break; } switch (SYMBOL_CLASS (*p)) @@ -860,6 +904,10 @@ print_partial_symbols (struct partial_symbol **p, int count, char *what, case LOC_OPTIMIZED_OUT: fputs_filtered ("optimized out", outfile); break; + case LOC_COMPUTED: + case LOC_COMPUTED_ARG: + fputs_filtered ("computed at runtime", outfile); + break; default: fputs_filtered ("", outfile); break; @@ -913,7 +961,7 @@ maintenance_print_msymbols (char *args, int from_tty) immediate_quit++; ALL_OBJFILES (objfile) - if (symname == NULL || (STREQ (symname, objfile->name))) + if (symname == NULL || strcmp (symname, objfile->name) == 0) dump_msymbols (objfile, outfile); immediate_quit--; fprintf_filtered (outfile, "\n\n"); @@ -933,18 +981,157 @@ maintenance_print_objfiles (char *ignore, int from_tty) immediate_quit--; } + +/* List all the symbol tables whose names match REGEXP (optional). */ +void +maintenance_info_symtabs (char *regexp, int from_tty) +{ + struct objfile *objfile; + + if (regexp) + re_comp (regexp); + + ALL_OBJFILES (objfile) + { + struct symtab *symtab; + + /* We don't want to print anything for this objfile until we + actually find a symtab whose name matches. */ + int printed_objfile_start = 0; + + ALL_OBJFILE_SYMTABS (objfile, symtab) + if (! regexp + || re_exec (symtab->filename)) + { + if (! printed_objfile_start) + { + printf_filtered ("{ objfile %s ", objfile->name); + wrap_here (" "); + printf_filtered ("((struct objfile *) %p)\n", objfile); + printed_objfile_start = 1; + } + + printf_filtered (" { symtab %s ", symtab->filename); + wrap_here (" "); + printf_filtered ("((struct symtab *) %p)\n", symtab); + printf_filtered (" dirname %s\n", + symtab->dirname ? symtab->dirname : "(null)"); + printf_filtered (" fullname %s\n", + symtab->fullname ? symtab->fullname : "(null)"); + printf_filtered (" blockvector ((struct blockvector *) %p)%s\n", + symtab->blockvector, + symtab->primary ? " (primary)" : ""); + printf_filtered (" debugformat %s\n", symtab->debugformat); + printf_filtered (" }\n"); + } + + if (printed_objfile_start) + printf_filtered ("}\n"); + } +} + + +/* List all the partial symbol tables whose names match REGEXP (optional). */ +void +maintenance_info_psymtabs (char *regexp, int from_tty) +{ + struct objfile *objfile; + + if (regexp) + re_comp (regexp); + + ALL_OBJFILES (objfile) + { + struct partial_symtab *psymtab; + + /* We don't want to print anything for this objfile until we + actually find a symtab whose name matches. */ + int printed_objfile_start = 0; + + ALL_OBJFILE_PSYMTABS (objfile, psymtab) + if (! regexp + || re_exec (psymtab->filename)) + { + if (! printed_objfile_start) + { + printf_filtered ("{ objfile %s ", objfile->name); + wrap_here (" "); + printf_filtered ("((struct objfile *) %p)\n", objfile); + printed_objfile_start = 1; + } + + printf_filtered (" { psymtab %s ", psymtab->filename); + wrap_here (" "); + printf_filtered ("((struct partial_symtab *) %p)\n", psymtab); + printf_filtered (" readin %s\n", + psymtab->readin ? "yes" : "no"); + printf_filtered (" fullname %s\n", + psymtab->fullname ? psymtab->fullname : "(null)"); + printf_filtered (" text addresses "); + print_address_numeric (psymtab->textlow, 1, gdb_stdout); + printf_filtered (" -- "); + print_address_numeric (psymtab->texthigh, 1, gdb_stdout); + printf_filtered ("\n"); + printf_filtered (" globals "); + if (psymtab->n_global_syms) + { + printf_filtered ("(* (struct partial_symbol **) %p @ %d)\n", + (psymtab->objfile->global_psymbols.list + + psymtab->globals_offset), + psymtab->n_global_syms); + } + else + printf_filtered ("(none)\n"); + printf_filtered (" statics "); + if (psymtab->n_static_syms) + { + printf_filtered ("(* (struct partial_symbol **) %p @ %d)\n", + (psymtab->objfile->static_psymbols.list + + psymtab->statics_offset), + psymtab->n_static_syms); + } + else + printf_filtered ("(none)\n"); + printf_filtered (" dependencies "); + if (psymtab->number_of_dependencies) + { + int i; + + printf_filtered ("{\n"); + for (i = 0; i < psymtab->number_of_dependencies; i++) + { + struct partial_symtab *dep = psymtab->dependencies[i]; + + /* Note the string concatenation there --- no comma. */ + printf_filtered (" psymtab %s " + "((struct partial_symtab *) %p)\n", + dep->filename, dep); + } + printf_filtered (" }\n"); + } + else + printf_filtered ("(none)\n"); + printf_filtered (" }\n"); + } + + if (printed_objfile_start) + printf_filtered ("}\n"); + } +} + + /* Check consistency of psymtabs and symtabs. */ void maintenance_check_symtabs (char *ignore, int from_tty) { - register struct symbol *sym; - register struct partial_symbol **psym; - register struct symtab *s = NULL; - register struct partial_symtab *ps; + struct symbol *sym; + struct partial_symbol **psym; + struct symtab *s = NULL; + struct partial_symtab *ps; struct blockvector *bv; - register struct objfile *objfile; - register struct block *b; + struct objfile *objfile; + struct block *b; int length; ALL_PSYMTABS (objfile, ps) @@ -958,12 +1145,12 @@ maintenance_check_symtabs (char *ignore, int from_tty) length = ps->n_static_syms; while (length--) { - sym = lookup_block_symbol (b, SYMBOL_NAME (*psym), - SYMBOL_NAMESPACE (*psym)); + sym = lookup_block_symbol (b, DEPRECATED_SYMBOL_NAME (*psym), + NULL, SYMBOL_DOMAIN (*psym)); if (!sym) { printf_filtered ("Static symbol `"); - puts_filtered (SYMBOL_NAME (*psym)); + puts_filtered (DEPRECATED_SYMBOL_NAME (*psym)); printf_filtered ("' only found in "); puts_filtered (ps->filename); printf_filtered (" psymtab\n"); @@ -975,12 +1162,12 @@ maintenance_check_symtabs (char *ignore, int from_tty) length = ps->n_global_syms; while (length--) { - sym = lookup_block_symbol (b, SYMBOL_NAME (*psym), - SYMBOL_NAMESPACE (*psym)); + sym = lookup_block_symbol (b, DEPRECATED_SYMBOL_NAME (*psym), + NULL, SYMBOL_DOMAIN (*psym)); if (!sym) { printf_filtered ("Global symbol `"); - puts_filtered (SYMBOL_NAME (*psym)); + puts_filtered (DEPRECATED_SYMBOL_NAME (*psym)); printf_filtered ("' only found in "); puts_filtered (ps->filename); printf_filtered (" psymtab\n"); @@ -1023,7 +1210,7 @@ maintenance_check_symtabs (char *ignore, int from_tty) static int block_depth (struct block *block) { - register int i = 0; + int i = 0; while ((block = BLOCK_SUPERBLOCK (block)) != NULL) { i++; @@ -1037,7 +1224,7 @@ block_depth (struct block *block) be freed in free_objfile(). */ void -extend_psymbol_list (register struct psymbol_allocation_list *listp, +extend_psymbol_list (struct psymbol_allocation_list *listp, struct objfile *objfile) { int new_size; diff --git a/contrib/gdb/gdb/symtab.c b/contrib/gdb/gdb/symtab.c index e464b0bc374..6995891b5ae 100644 --- a/contrib/gdb/gdb/symtab.c +++ b/contrib/gdb/gdb/symtab.c @@ -1,8 +1,8 @@ /* Symbol table lookup for the GNU debugger, GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GDB. @@ -38,9 +38,15 @@ #include "demangle.h" #include "inferior.h" #include "linespec.h" +#include "source.h" #include "filenames.h" /* for FILENAME_CMP */ +#include "objc-lang.h" -#include "obstack.h" +#include "hashtab.h" + +#include "gdb_obstack.h" +#include "block.h" +#include "dictionary.h" #include #include @@ -49,11 +55,6 @@ #include #include "cp-abi.h" -/* Prototype for one function in parser-defs.h, - instead of including that entire file. */ - -extern char *find_template_name_end (char *); - /* Prototypes for local functions */ static void completion_list_add_name (char *, char *, int, char *, char *); @@ -76,18 +77,42 @@ static int find_line_common (struct linetable *, int, int *); char *operator_chars (char *p, char **end); -static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, - const char *, int, - namespace_enum); +static struct symbol *lookup_symbol_aux (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + int *is_a_field_of_this, + struct symtab **symtab); -static struct symbol *lookup_symbol_aux (const char *name, const - struct block *block, const - namespace_enum namespace, int - *is_a_field_of_this, struct - symtab **symtab); +static +struct symbol *lookup_symbol_aux_local (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab); +static +struct symbol *lookup_symbol_aux_symtabs (int block_index, + const char *name, + const char *linkage_name, + const domain_enum domain, + struct symtab **symtab); -static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr); +static +struct symbol *lookup_symbol_aux_psymtabs (int block_index, + const char *name, + const char *linkage_name, + const domain_enum domain, + struct symtab **symtab); + +#if 0 +static +struct symbol *lookup_symbol_aux_minsyms (const char *name, + const char *linkage_name, + const domain_enum domain, + int *is_a_field_of_this, + struct symtab **symtab); +#endif /* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */ /* Signals the presence of objects compiled by HP compilers */ @@ -97,14 +122,12 @@ static void fixup_section (struct general_symbol_info *, struct objfile *); static int file_matches (char *, char **, int); -static void print_symbol_info (namespace_enum, +static void print_symbol_info (domain_enum, struct symtab *, struct symbol *, int, char *); static void print_msymbol_info (struct minimal_symbol *); -static void symtab_symbol_info (char *, namespace_enum, int); - -static void overload_list_add_symbol (struct symbol *sym, char *oload_name); +static void symtab_symbol_info (char *, domain_enum, int); void _initialize_symtab (void); @@ -119,19 +142,6 @@ struct type *builtin_type_error; const struct block *block_found; -/* While the C++ support is still in flux, issue a possibly helpful hint on - using the new command completion feature on single quoted demangled C++ - symbols. Remove when loose ends are cleaned up. FIXME -fnf */ - -static void -cplusplus_hint (char *name) -{ - while (*name == '\'') - name++; - printf_filtered ("Hint: try '%s or '%s\n", name, name); - printf_filtered ("(Note leading single quote.)\n"); -} - /* Check for a symtab of a specific name; first in symtabs, then in psymtabs. *If* there is no '/' in the name, a match after a '/' in the symtab filename will also work. */ @@ -139,15 +149,21 @@ cplusplus_hint (char *name) struct symtab * lookup_symtab (const char *name) { - register struct symtab *s; - register struct partial_symtab *ps; - register struct objfile *objfile; + struct symtab *s; + struct partial_symtab *ps; + struct objfile *objfile; char *real_path = NULL; + char *full_path = NULL; /* Here we are interested in canonicalizing an absolute path, not absolutizing a relative path. */ if (IS_ABSOLUTE_PATH (name)) - real_path = gdb_realpath (name); + { + full_path = xfullpath (name); + make_cleanup (xfree, full_path); + real_path = gdb_realpath (name); + make_cleanup (xfree, real_path); + } got_symtab: @@ -157,24 +173,32 @@ got_symtab: { if (FILENAME_CMP (name, s->filename) == 0) { - xfree (real_path); return s; } + /* If the user gave us an absolute path, try to find the file in this symtab and use its absolute path. */ + + if (full_path != NULL) + { + const char *fp = symtab_to_filename (s); + if (FILENAME_CMP (full_path, fp) == 0) + { + return s; + } + } + if (real_path != NULL) { - char *rp = symtab_to_filename (s); + char *rp = gdb_realpath (symtab_to_filename (s)); + make_cleanup (xfree, rp); if (FILENAME_CMP (real_path, rp) == 0) { - xfree (real_path); return s; } } } - xfree (real_path); - /* Now, search for a matching tail (only if name doesn't have any dirs) */ if (lbasename (name) == name) @@ -218,39 +242,58 @@ got_symtab: struct partial_symtab * lookup_partial_symtab (const char *name) { - register struct partial_symtab *pst; - register struct objfile *objfile; + struct partial_symtab *pst; + struct objfile *objfile; + char *full_path = NULL; char *real_path = NULL; /* Here we are interested in canonicalizing an absolute path, not absolutizing a relative path. */ if (IS_ABSOLUTE_PATH (name)) - real_path = gdb_realpath (name); + { + full_path = xfullpath (name); + make_cleanup (xfree, full_path); + real_path = gdb_realpath (name); + make_cleanup (xfree, real_path); + } ALL_PSYMTABS (objfile, pst) { if (FILENAME_CMP (name, pst->filename) == 0) { - xfree (real_path); return (pst); } + /* If the user gave us an absolute path, try to find the file in this symtab and use its absolute path. */ - if (real_path != NULL) + if (full_path != NULL) { if (pst->fullname == NULL) source_full_path_of (pst->filename, &pst->fullname); if (pst->fullname != NULL - && FILENAME_CMP (real_path, pst->fullname) == 0) + && FILENAME_CMP (full_path, pst->fullname) == 0) + { + return pst; + } + } + + if (real_path != NULL) + { + char *rp = NULL; + if (pst->fullname == NULL) + source_full_path_of (pst->filename, &pst->fullname); + if (pst->fullname != NULL) + { + rp = gdb_realpath (pst->fullname); + make_cleanup (xfree, rp); + } + if (rp != NULL && FILENAME_CMP (real_path, rp) == 0) { - xfree (real_path); return pst; } } } - xfree (real_path); - /* Now, search for a matching tail (only if name doesn't have any dirs) */ if (lbasename (name) == name) @@ -300,7 +343,7 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) is_full_physname_constructor = is_constructor_name (physname); is_constructor = - is_full_physname_constructor || (newname && STREQ (field_name, newname)); + is_full_physname_constructor || (newname && strcmp (field_name, newname) == 0); if (!is_destructor) is_destructor = (strncmp (physname, "__dt", 4) == 0); @@ -348,16 +391,296 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) strcat (mangled_name, physname); return (mangled_name); } + + +/* Initialize the language dependent portion of a symbol + depending upon the language for the symbol. */ +void +symbol_init_language_specific (struct general_symbol_info *gsymbol, + enum language language) +{ + gsymbol->language = language; + if (gsymbol->language == language_cplus + || gsymbol->language == language_java + || gsymbol->language == language_objc) + { + gsymbol->language_specific.cplus_specific.demangled_name = NULL; + } + else + { + memset (&gsymbol->language_specific, 0, + sizeof (gsymbol->language_specific)); + } +} + +/* Functions to initialize a symbol's mangled name. */ + +/* Create the hash table used for demangled names. Each hash entry is + a pair of strings; one for the mangled name and one for the demangled + name. The entry is hashed via just the mangled name. */ + +static void +create_demangled_names_hash (struct objfile *objfile) +{ + /* Choose 256 as the starting size of the hash table, somewhat arbitrarily. + The hash table code will round this up to the next prime number. + Choosing a much larger table size wastes memory, and saves only about + 1% in symbol reading. */ + + objfile->demangled_names_hash = htab_create_alloc_ex + (256, htab_hash_string, (int (*) (const void *, const void *)) streq, + NULL, objfile->md, xmcalloc, xmfree); +} + +/* Try to determine the demangled name for a symbol, based on the + language of that symbol. If the language is set to language_auto, + it will attempt to find any demangling algorithm that works and + then set the language appropriately. The returned name is allocated + by the demangler and should be xfree'd. */ + +static char * +symbol_find_demangled_name (struct general_symbol_info *gsymbol, + const char *mangled) +{ + char *demangled = NULL; + + if (gsymbol->language == language_unknown) + gsymbol->language = language_auto; + + if (gsymbol->language == language_objc + || gsymbol->language == language_auto) + { + demangled = + objc_demangle (mangled, 0); + if (demangled != NULL) + { + gsymbol->language = language_objc; + return demangled; + } + } + if (gsymbol->language == language_cplus + || gsymbol->language == language_auto) + { + demangled = + cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); + if (demangled != NULL) + { + gsymbol->language = language_cplus; + return demangled; + } + } + if (gsymbol->language == language_java) + { + demangled = + cplus_demangle (mangled, + DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA); + if (demangled != NULL) + { + gsymbol->language = language_java; + return demangled; + } + } + return NULL; +} + +/* Set both the mangled and demangled (if any) names for GSYMBOL based + on LINKAGE_NAME and LEN. The hash table corresponding to OBJFILE + is used, and the memory comes from that objfile's objfile_obstack. + LINKAGE_NAME is copied, so the pointer can be discarded after + calling this function. */ + +/* We have to be careful when dealing with Java names: when we run + into a Java minimal symbol, we don't know it's a Java symbol, so it + gets demangled as a C++ name. This is unfortunate, but there's not + much we can do about it: but when demangling partial symbols and + regular symbols, we'd better not reuse the wrong demangled name. + (See PR gdb/1039.) We solve this by putting a distinctive prefix + on Java names when storing them in the hash table. */ + +/* FIXME: carlton/2003-03-13: This is an unfortunate situation. I + don't mind the Java prefix so much: different languages have + different demangling requirements, so it's only natural that we + need to keep language data around in our demangling cache. But + it's not good that the minimal symbol has the wrong demangled name. + Unfortunately, I can't think of any easy solution to that + problem. */ + +#define JAVA_PREFIX "##JAVA$$" +#define JAVA_PREFIX_LEN 8 + +void +symbol_set_names (struct general_symbol_info *gsymbol, + const char *linkage_name, int len, struct objfile *objfile) +{ + char **slot; + /* A 0-terminated copy of the linkage name. */ + const char *linkage_name_copy; + /* A copy of the linkage name that might have a special Java prefix + added to it, for use when looking names up in the hash table. */ + const char *lookup_name; + /* The length of lookup_name. */ + int lookup_len; + + if (objfile->demangled_names_hash == NULL) + create_demangled_names_hash (objfile); + + /* The stabs reader generally provides names that are not + NUL-terminated; most of the other readers don't do this, so we + can just use the given copy, unless we're in the Java case. */ + if (gsymbol->language == language_java) + { + char *alloc_name; + lookup_len = len + JAVA_PREFIX_LEN; + + alloc_name = alloca (lookup_len + 1); + memcpy (alloc_name, JAVA_PREFIX, JAVA_PREFIX_LEN); + memcpy (alloc_name + JAVA_PREFIX_LEN, linkage_name, len); + alloc_name[lookup_len] = '\0'; + + lookup_name = alloc_name; + linkage_name_copy = alloc_name + JAVA_PREFIX_LEN; + } + else if (linkage_name[len] != '\0') + { + char *alloc_name; + lookup_len = len; + + alloc_name = alloca (lookup_len + 1); + memcpy (alloc_name, linkage_name, len); + alloc_name[lookup_len] = '\0'; + + lookup_name = alloc_name; + linkage_name_copy = alloc_name; + } + else + { + lookup_len = len; + lookup_name = linkage_name; + linkage_name_copy = linkage_name; + } + + slot = (char **) htab_find_slot (objfile->demangled_names_hash, + lookup_name, INSERT); + + /* If this name is not in the hash table, add it. */ + if (*slot == NULL) + { + char *demangled_name = symbol_find_demangled_name (gsymbol, + linkage_name_copy); + int demangled_len = demangled_name ? strlen (demangled_name) : 0; + + /* If there is a demangled name, place it right after the mangled name. + Otherwise, just place a second zero byte after the end of the mangled + name. */ + *slot = obstack_alloc (&objfile->objfile_obstack, + lookup_len + demangled_len + 2); + memcpy (*slot, lookup_name, lookup_len + 1); + if (demangled_name != NULL) + { + memcpy (*slot + lookup_len + 1, demangled_name, demangled_len + 1); + xfree (demangled_name); + } + else + (*slot)[lookup_len + 1] = '\0'; + } + + gsymbol->name = *slot + lookup_len - len; + if ((*slot)[lookup_len + 1] != '\0') + gsymbol->language_specific.cplus_specific.demangled_name + = &(*slot)[lookup_len + 1]; + else + gsymbol->language_specific.cplus_specific.demangled_name = NULL; +} + +/* Initialize the demangled name of GSYMBOL if possible. Any required space + to store the name is obtained from the specified obstack. The function + symbol_set_names, above, should be used instead where possible for more + efficient memory usage. */ + +void +symbol_init_demangled_name (struct general_symbol_info *gsymbol, + struct obstack *obstack) +{ + char *mangled = gsymbol->name; + char *demangled = NULL; + + demangled = symbol_find_demangled_name (gsymbol, mangled); + if (gsymbol->language == language_cplus + || gsymbol->language == language_java + || gsymbol->language == language_objc) + { + if (demangled) + { + gsymbol->language_specific.cplus_specific.demangled_name + = obsavestring (demangled, strlen (demangled), obstack); + xfree (demangled); + } + else + gsymbol->language_specific.cplus_specific.demangled_name = NULL; + } + else + { + /* Unknown language; just clean up quietly. */ + if (demangled) + xfree (demangled); + } +} + +/* Return the source code name of a symbol. In languages where + demangling is necessary, this is the demangled name. */ + +char * +symbol_natural_name (const struct general_symbol_info *gsymbol) +{ + if ((gsymbol->language == language_cplus + || gsymbol->language == language_java + || gsymbol->language == language_objc) + && (gsymbol->language_specific.cplus_specific.demangled_name != NULL)) + { + return gsymbol->language_specific.cplus_specific.demangled_name; + } + else + { + return gsymbol->name; + } +} + +/* Return the demangled name for a symbol based on the language for + that symbol. If no demangled name exists, return NULL. */ +char * +symbol_demangled_name (struct general_symbol_info *gsymbol) +{ + if (gsymbol->language == language_cplus + || gsymbol->language == language_java + || gsymbol->language == language_objc) + return gsymbol->language_specific.cplus_specific.demangled_name; + + else + return NULL; +} + +/* Initialize the structure fields to zero values. */ +void +init_sal (struct symtab_and_line *sal) +{ + sal->symtab = 0; + sal->section = 0; + sal->line = 0; + sal->pc = 0; + sal->end = 0; +} -/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */ - +/* Find which partial symtab contains PC and SECTION. Return 0 if + none. We return the psymtab that contains a symbol whose address + exactly matches PC, or, if we cannot find an exact match, the + psymtab that contains a symbol whose address is closest to PC. */ struct partial_symtab * find_pc_sect_psymtab (CORE_ADDR pc, asection *section) { - register struct partial_symtab *pst; - register struct objfile *objfile; + struct partial_symtab *pst; + struct objfile *objfile; struct minimal_symbol *msymbol; /* If we know that this is not a text address, return failure. This is @@ -377,6 +700,8 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) if (pc >= pst->textlow && pc < pst->texthigh) { struct partial_symtab *tpst; + struct partial_symtab *best_pst = pst; + struct partial_symbol *best_psym = NULL; /* An objfile that has its functions reordered might have many partial symbol tables containing the PC, but @@ -389,6 +714,13 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) if (msymbol == NULL) return (pst); + /* The code range of partial symtabs sometimes overlap, so, in + the loop below, we need to check all partial symtabs and + find the one that fits better for the given PC address. We + select the partial symtab that contains a symbol whose + address is closest to the PC address. By closest we mean + that find_pc_sect_symbol returns the symbol with address + that is closest and still less than the given PC. */ for (tpst = pst; tpst != NULL; tpst = tpst->next) { if (pc >= tpst->textlow && pc < tpst->texthigh) @@ -400,9 +732,33 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) && SYMBOL_VALUE_ADDRESS (p) == SYMBOL_VALUE_ADDRESS (msymbol)) return (tpst); + if (p != NULL) + { + /* We found a symbol in this partial symtab which + matches (or is closest to) PC, check whether it + is closer than our current BEST_PSYM. Since + this symbol address is necessarily lower or + equal to PC, the symbol closer to PC is the + symbol which address is the highest. */ + /* This way we return the psymtab which contains + such best match symbol. This can help in cases + where the symbol information/debuginfo is not + complete, like for instance on IRIX6 with gcc, + where no debug info is emitted for + statics. (See also the nodebug.exp + testcase.) */ + if (best_psym == NULL + || SYMBOL_VALUE_ADDRESS (p) + > SYMBOL_VALUE_ADDRESS (best_psym)) + { + best_psym = p; + best_pst = tpst; + } + } + } } - return (pst); + return (best_pst); } } return (NULL); @@ -444,7 +800,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, pp++) { p = *pp; - if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE + if (SYMBOL_DOMAIN (p) == VAR_DOMAIN && SYMBOL_CLASS (p) == LOC_BLOCK && pc >= SYMBOL_VALUE_ADDRESS (p) && (SYMBOL_VALUE_ADDRESS (p) > best_pc @@ -468,7 +824,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, pp++) { p = *pp; - if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE + if (SYMBOL_DOMAIN (p) == VAR_DOMAIN && SYMBOL_CLASS (p) == LOC_BLOCK && pc >= SYMBOL_VALUE_ADDRESS (p) && (SYMBOL_VALUE_ADDRESS (p) > best_pc @@ -543,7 +899,7 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) } /* Find the definition for a specified symbol name NAME - in namespace NAMESPACE, visible from lexical block BLOCK. + in domain DOMAIN, visible from lexical block BLOCK. Returns the struct symbol pointer, or zero if no symbol is found. If SYMTAB is non-NULL, store the symbol table in which the symbol was found there, or NULL if not found. @@ -557,22 +913,38 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) attractive to put in some QUIT's (though I'm not really sure whether it can run long enough to be really important). But there are a few calls for which it would appear to be bad news to quit - out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and - nindy_frame_chain_valid in nindy-tdep.c. (Note that there is C++ - code below which can error(), but that probably doesn't affect - these calls since they are looking for a known variable and thus - can probably assume it will never hit the C++ code). */ + out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note + that there is C++ code below which can error(), but that probably + doesn't affect these calls since they are looking for a known + variable and thus can probably assume it will never hit the C++ + code). */ struct symbol * lookup_symbol (const char *name, const struct block *block, - const namespace_enum namespace, int *is_a_field_of_this, + const domain_enum domain, int *is_a_field_of_this, struct symtab **symtab) { - char *modified_name = NULL; - char *modified_name2 = NULL; + char *demangled_name = NULL; + const char *modified_name = NULL; + const char *mangled_name = NULL; int needtofreename = 0; struct symbol *returnval; + modified_name = name; + + /* If we are using C++ language, demangle the name before doing a lookup, so + we can always binary search. */ + if (current_language->la_language == language_cplus) + { + demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); + if (demangled_name) + { + mangled_name = name; + modified_name = demangled_name; + needtofreename = 1; + } + } + if (case_sensitivity == case_sensitive_off) { char *copy; @@ -585,120 +957,51 @@ lookup_symbol (const char *name, const struct block *block, copy[len] = 0; modified_name = copy; } - else - modified_name = (char *) name; - /* If we are using C++ language, demangle the name before doing a lookup, so - we can always binary search. */ - if (current_language->la_language == language_cplus) - { - modified_name2 = cplus_demangle (modified_name, DMGL_ANSI | DMGL_PARAMS); - if (modified_name2) - { - modified_name = modified_name2; - needtofreename = 1; - } - } - - returnval = lookup_symbol_aux (modified_name, block, namespace, - is_a_field_of_this, symtab); + returnval = lookup_symbol_aux (modified_name, mangled_name, block, + domain, is_a_field_of_this, symtab); if (needtofreename) - xfree (modified_name2); + xfree (demangled_name); return returnval; } +/* Behave like lookup_symbol_aux except that NAME is the natural name + of the symbol that we're looking for and, if LINKAGE_NAME is + non-NULL, ensure that the symbol's linkage name matches as + well. */ + static struct symbol * -lookup_symbol_aux (const char *name, const struct block *block, - const namespace_enum namespace, int *is_a_field_of_this, - struct symtab **symtab) +lookup_symbol_aux (const char *name, const char *linkage_name, + const struct block *block, const domain_enum domain, + int *is_a_field_of_this, struct symtab **symtab) { - register struct symbol *sym; - register struct symtab *s = NULL; - register struct partial_symtab *ps; - register struct blockvector *bv; - register struct objfile *objfile = NULL; - register struct block *b; - register struct minimal_symbol *msymbol; + struct symbol *sym; + /* Make sure we do something sensible with is_a_field_of_this, since + the callers that set this parameter to some non-null value will + certainly use it later and expect it to be either 0 or 1. + If we don't set it, the contents of is_a_field_of_this are + undefined. */ + if (is_a_field_of_this != NULL) + *is_a_field_of_this = 0; - /* Search specified block and its superiors. */ + /* Search specified block and its superiors. Don't search + STATIC_BLOCK or GLOBAL_BLOCK. */ - while (block != 0) + sym = lookup_symbol_aux_local (name, linkage_name, block, domain, + symtab); + if (sym != NULL) + return sym; + + /* If requested to do so by the caller and if appropriate for the + current language, check to see if NAME is a field of `this'. */ + + if (current_language->la_value_of_this != NULL + && is_a_field_of_this != NULL) { - sym = lookup_block_symbol (block, name, namespace); - if (sym) - { - block_found = block; - if (symtab != NULL) - { - /* Search the list of symtabs for one which contains the - address of the start of this block. */ - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - if (BLOCK_START (b) <= BLOCK_START (block) - && BLOCK_END (b) > BLOCK_START (block)) - goto found; - } - found: - *symtab = s; - } + struct value *v = current_language->la_value_of_this (0); - return fixup_symbol_section (sym, objfile); - } - block = BLOCK_SUPERBLOCK (block); - } - - /* FIXME: this code is never executed--block is always NULL at this - point. What is it trying to do, anyway? We already should have - checked the STATIC_BLOCK above (it is the superblock of top-level - blocks). Why is VAR_NAMESPACE special-cased? */ - /* Don't need to mess with the psymtabs; if we have a block, - that file is read in. If we don't, then we deal later with - all the psymtab stuff that needs checking. */ - /* Note (RT): The following never-executed code looks unnecessary to me also. - * If we change the code to use the original (passed-in) - * value of 'block', we could cause it to execute, but then what - * would it do? The STATIC_BLOCK of the symtab containing the passed-in - * 'block' was already searched by the above code. And the STATIC_BLOCK's - * of *other* symtabs (those files not containing 'block' lexically) - * should not contain 'block' address-wise. So we wouldn't expect this - * code to find any 'sym''s that were not found above. I vote for - * deleting the following paragraph of code. - */ - if (namespace == VAR_NAMESPACE && block != NULL) - { - struct block *b; - /* Find the right symtab. */ - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - if (BLOCK_START (b) <= BLOCK_START (block) - && BLOCK_END (b) > BLOCK_START (block)) - { - sym = lookup_block_symbol (b, name, VAR_NAMESPACE); - if (sym) - { - block_found = b; - if (symtab != NULL) - *symtab = s; - return fixup_symbol_section (sym, objfile); - } - } - } - } - - - /* C++: If requested to do so by the caller, - check to see if NAME is a field of `this'. */ - if (is_a_field_of_this) - { - struct value *v = value_of_this (0); - - *is_a_field_of_this = 0; if (v && check_field (v, name)) { *is_a_field_of_this = 1; @@ -708,16 +1011,130 @@ lookup_symbol_aux (const char *name, const struct block *block, } } - /* Now search all global blocks. Do the symtab's first, then - check the psymtab's. If a psymtab indicates the existence - of the desired name as a global, then do psymtab-to-symtab + /* Now do whatever is appropriate for the current language to look + up static and global variables. */ + + sym = current_language->la_lookup_symbol_nonlocal (name, linkage_name, + block, domain, + symtab); + if (sym != NULL) + return sym; + + /* Now search all static file-level symbols. Not strictly correct, + but more useful than an error. Do the symtabs first, then check + the psymtabs. If a psymtab indicates the existence of the + desired name as a file-level static, then do psymtab-to-symtab conversion on the fly and return the found symbol. */ + sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, + domain, symtab); + if (sym != NULL) + return sym; + + sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, + domain, symtab); + if (sym != NULL) + return sym; + + if (symtab != NULL) + *symtab = NULL; + return NULL; +} + +/* Check to see if the symbol is defined in BLOCK or its superiors. + Don't search STATIC_BLOCK or GLOBAL_BLOCK. */ + +static struct symbol * +lookup_symbol_aux_local (const char *name, const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab) +{ + struct symbol *sym; + const struct block *static_block = block_static_block (block); + + /* Check if either no block is specified or it's a global block. */ + + if (static_block == NULL) + return NULL; + + while (block != static_block) + { + sym = lookup_symbol_aux_block (name, linkage_name, block, domain, + symtab); + if (sym != NULL) + return sym; + block = BLOCK_SUPERBLOCK (block); + } + + /* We've reached the static block without finding a result. */ + + return NULL; +} + +/* Look up a symbol in a block; if found, locate its symtab, fixup the + symbol, and set block_found appropriately. */ + +struct symbol * +lookup_symbol_aux_block (const char *name, const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab) +{ + struct symbol *sym; + struct objfile *objfile = NULL; + struct blockvector *bv; + struct block *b; + struct symtab *s = NULL; + + sym = lookup_block_symbol (block, name, linkage_name, domain); + if (sym) + { + block_found = block; + if (symtab != NULL) + { + /* Search the list of symtabs for one which contains the + address of the start of this block. */ + ALL_SYMTABS (objfile, s) + { + bv = BLOCKVECTOR (s); + b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + if (BLOCK_START (b) <= BLOCK_START (block) + && BLOCK_END (b) > BLOCK_START (block)) + goto found; + } + found: + *symtab = s; + } + + return fixup_symbol_section (sym, objfile); + } + + return NULL; +} + +/* Check to see if the symbol is defined in one of the symtabs. + BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK, + depending on whether or not we want to search global symbols or + static symbols. */ + +static struct symbol * +lookup_symbol_aux_symtabs (int block_index, + const char *name, const char *linkage_name, + const domain_enum domain, + struct symtab **symtab) +{ + struct symbol *sym; + struct objfile *objfile; + struct blockvector *bv; + const struct block *block; + struct symtab *s; + ALL_SYMTABS (objfile, s) { bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, namespace); + block = BLOCKVECTOR_BLOCK (bv, block_index); + sym = lookup_block_symbol (block, name, linkage_name, domain); if (sym) { block_found = block; @@ -727,17 +1144,121 @@ lookup_symbol_aux (const char *name, const struct block *block, } } -#ifndef HPUXHPPA + return NULL; +} - /* Check for the possibility of the symbol being a function or - a mangled variable that is stored in one of the minimal symbol tables. - Eventually, all global symbols might be resolved in this way. */ +/* Check to see if the symbol is defined in one of the partial + symtabs. BLOCK_INDEX should be either GLOBAL_BLOCK or + STATIC_BLOCK, depending on whether or not we want to search global + symbols or static symbols. */ - if (namespace == VAR_NAMESPACE) +static struct symbol * +lookup_symbol_aux_psymtabs (int block_index, const char *name, + const char *linkage_name, + const domain_enum domain, + struct symtab **symtab) +{ + struct symbol *sym; + struct objfile *objfile; + struct blockvector *bv; + const struct block *block; + struct partial_symtab *ps; + struct symtab *s; + const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0); + + ALL_PSYMTABS (objfile, ps) + { + if (!ps->readin + && lookup_partial_symbol (ps, name, linkage_name, + psymtab_index, domain)) + { + s = PSYMTAB_TO_SYMTAB (ps); + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, block_index); + sym = lookup_block_symbol (block, name, linkage_name, domain); + if (!sym) + { + /* This shouldn't be necessary, but as a last resort try + looking in the statics even though the psymtab claimed + the symbol was global, or vice-versa. It's possible + that the psymtab gets it wrong in some cases. */ + + /* FIXME: carlton/2002-09-30: Should we really do that? + If that happens, isn't it likely to be a GDB error, in + which case we should fix the GDB error rather than + silently dealing with it here? So I'd vote for + removing the check for the symbol in the other + block. */ + block = BLOCKVECTOR_BLOCK (bv, + block_index == GLOBAL_BLOCK ? + STATIC_BLOCK : GLOBAL_BLOCK); + sym = lookup_block_symbol (block, name, linkage_name, domain); + if (!sym) + error ("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s).", + block_index == GLOBAL_BLOCK ? "global" : "static", + name, ps->filename, name, name); + } + if (symtab != NULL) + *symtab = s; + return fixup_symbol_section (sym, objfile); + } + } + + return NULL; +} + +#if 0 +/* Check for the possibility of the symbol being a function or a + mangled variable that is stored in one of the minimal symbol + tables. Eventually, all global symbols might be resolved in this + way. */ + +/* NOTE: carlton/2002-12-05: At one point, this function was part of + lookup_symbol_aux, and what are now 'return' statements within + lookup_symbol_aux_minsyms returned from lookup_symbol_aux, even if + sym was NULL. As far as I can tell, this was basically accidental; + it didn't happen every time that msymbol was non-NULL, but only if + some additional conditions held as well, and it caused problems + with HP-generated symbol tables. */ + +/* NOTE: carlton/2003-05-14: This function was once used as part of + lookup_symbol. It is currently unnecessary for correctness + reasons, however, and using it doesn't seem to be any faster than + using lookup_symbol_aux_psymtabs, so I'm commenting it out. */ + +static struct symbol * +lookup_symbol_aux_minsyms (const char *name, + const char *linkage_name, + const domain_enum domain, + int *is_a_field_of_this, + struct symtab **symtab) +{ + struct symbol *sym; + struct blockvector *bv; + const struct block *block; + struct minimal_symbol *msymbol; + struct symtab *s; + + if (domain == VAR_DOMAIN) { msymbol = lookup_minimal_symbol (name, NULL, NULL); + if (msymbol != NULL) { + /* OK, we found a minimal symbol in spite of not finding any + symbol. There are various possible explanations for + this. One possibility is the symbol exists in code not + compiled -g. Another possibility is that the 'psymtab' + isn't doing its job. A third possibility, related to #2, + is that we were confused by name-mangling. For instance, + maybe the psymtab isn't doing its job because it only + know about demangled names, but we were given a mangled + name... */ + + /* We first use the address in the msymbol to try to locate + the appropriate symtab. Note that find_pc_sect_symtab() + has a side-effect of doing psymtab-to-symtab expansion, + for the found symtab. */ s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol), SYMBOL_BFD_SECTION (msymbol)); if (s != NULL) @@ -745,190 +1266,43 @@ lookup_symbol_aux (const char *name, const struct block *block, /* This is a function which has a symtab for its address. */ bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); + + /* This call used to pass `SYMBOL_LINKAGE_NAME (msymbol)' as the + `name' argument to lookup_block_symbol. But the name + of a minimal symbol is always mangled, so that seems + to be clearly the wrong thing to pass as the + unmangled name. */ + sym = + lookup_block_symbol (block, name, linkage_name, domain); /* We kept static functions in minimal symbol table as well as in static scope. We want to find them in the symbol table. */ if (!sym) { block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); + sym = lookup_block_symbol (block, name, + linkage_name, domain); } - /* sym == 0 if symbol was found in the minimal symbol table - but not in the symtab. - Return 0 to use the msymbol definition of "foo_". + /* NOTE: carlton/2002-12-04: The following comment was + taken from a time when two versions of this function + were part of the body of lookup_symbol_aux: this + comment was taken from the version of the function + that was #ifdef HPUXHPPA, and the comment was right + before the 'return NULL' part of lookup_symbol_aux. + (Hence the "Fall through and return 0" comment.) + Elena did some digging into the situation for + Fortran, and she reports: - This happens for Fortran "foo_" symbols, - which are "foo" in the symtab. + "I asked around (thanks to Jeff Knaggs), and I think + the story for Fortran goes like this: - This can also happen if "asm" is used to make a - regular symbol but not a debugging symbol, e.g. - asm(".globl _main"); - asm("_main:"); - */ - - if (symtab != NULL) - *symtab = s; - return fixup_symbol_section (sym, objfile); - } - else if (MSYMBOL_TYPE (msymbol) != mst_text - && MSYMBOL_TYPE (msymbol) != mst_file_text - && !STREQ (name, SYMBOL_NAME (msymbol))) - { - /* This is a mangled variable, look it up by its - mangled name. */ - return lookup_symbol_aux (SYMBOL_NAME (msymbol), block, - namespace, is_a_field_of_this, symtab); - } - /* There are no debug symbols for this file, or we are looking - for an unmangled variable. - Try to find a matching static symbol below. */ - } - } - -#endif - - ALL_PSYMTABS (objfile, ps) - { - if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace)) - { - s = PSYMTAB_TO_SYMTAB (ps); - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, namespace); - if (!sym) - { - /* This shouldn't be necessary, but as a last resort - * try looking in the statics even though the psymtab - * claimed the symbol was global. It's possible that - * the psymtab gets it wrong in some cases. - */ - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, namespace); - if (!sym) - error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\ -%s may be an inlined function, or may be a template function\n\ -(if a template, try specifying an instantiation: %s).", - name, ps->filename, name, name); - } - if (symtab != NULL) - *symtab = s; - return fixup_symbol_section (sym, objfile); - } - } - - /* Now search all static file-level symbols. - Not strictly correct, but more useful than an error. - Do the symtabs first, then check the psymtabs. - If a psymtab indicates the existence - of the desired name as a file-level static, then do psymtab-to-symtab - conversion on the fly and return the found symbol. */ - - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, namespace); - if (sym) - { - block_found = block; - if (symtab != NULL) - *symtab = s; - return fixup_symbol_section (sym, objfile); - } - } - - ALL_PSYMTABS (objfile, ps) - { - if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace)) - { - s = PSYMTAB_TO_SYMTAB (ps); - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, namespace); - if (!sym) - { - /* This shouldn't be necessary, but as a last resort - * try looking in the globals even though the psymtab - * claimed the symbol was static. It's possible that - * the psymtab gets it wrong in some cases. - */ - block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, namespace); - if (!sym) - error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\ -%s may be an inlined function, or may be a template function\n\ -(if a template, try specifying an instantiation: %s).", - name, ps->filename, name, name); - } - if (symtab != NULL) - *symtab = s; - return fixup_symbol_section (sym, objfile); - } - } - -#ifdef HPUXHPPA - - /* Check for the possibility of the symbol being a function or - a global variable that is stored in one of the minimal symbol tables. - The "minimal symbol table" is built from linker-supplied info. - - RT: I moved this check to last, after the complete search of - the global (p)symtab's and static (p)symtab's. For HP-generated - symbol tables, this check was causing a premature exit from - lookup_symbol with NULL return, and thus messing up symbol lookups - of things like "c::f". It seems to me a check of the minimal - symbol table ought to be a last resort in any case. I'm vaguely - worried about the comment below which talks about FORTRAN routines "foo_" - though... is it saying we need to do the "minsym" check before - the static check in this case? - */ - - if (namespace == VAR_NAMESPACE) - { - msymbol = lookup_minimal_symbol (name, NULL, NULL); - if (msymbol != NULL) - { - /* OK, we found a minimal symbol in spite of not - * finding any symbol. There are various possible - * explanations for this. One possibility is the symbol - * exists in code not compiled -g. Another possibility - * is that the 'psymtab' isn't doing its job. - * A third possibility, related to #2, is that we were confused - * by name-mangling. For instance, maybe the psymtab isn't - * doing its job because it only know about demangled - * names, but we were given a mangled name... - */ - - /* We first use the address in the msymbol to try to - * locate the appropriate symtab. Note that find_pc_symtab() - * has a side-effect of doing psymtab-to-symtab expansion, - * for the found symtab. - */ - s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)); - if (s != NULL) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); - /* We kept static functions in minimal symbol table as well as - in static scope. We want to find them in the symbol table. */ - if (!sym) - { - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); - } - /* If we found one, return it */ - if (sym) - { - if (symtab != NULL) - *symtab = s; - return sym; - } + "Apparently, in older Fortrans, '_' was not part of + the user namespace. g77 attached a final '_' to + procedure names as the exported symbols for linkage + (foo_) , but the symbols went in the debug info just + like 'foo'. The rationale behind this is not + completely clear, and maybe it was done to other + symbols as well, not just procedures." */ /* If we get here with sym == 0, the symbol was found in the minimal symbol table @@ -947,39 +1321,118 @@ lookup_symbol_aux (const char *name, const struct block *block, asm(".globl _main"); asm("_main:"); */ - } - /* If the lookup-by-address fails, try repeating the - * entire lookup process with the symbol name from - * the msymbol (if different from the original symbol name). - */ - else if (MSYMBOL_TYPE (msymbol) != mst_text - && MSYMBOL_TYPE (msymbol) != mst_file_text - && !STREQ (name, SYMBOL_NAME (msymbol))) - { - return lookup_symbol_aux (SYMBOL_NAME (msymbol), block, - namespace, is_a_field_of_this, symtab); + if (symtab != NULL && sym != NULL) + *symtab = s; + return fixup_symbol_section (sym, s->objfile); } } } -#endif - - if (symtab != NULL) - *symtab = NULL; - return 0; + return NULL; } - -/* Look, in partial_symtab PST, for symbol NAME. Check the global - symbols if GLOBAL, the static symbols if not */ +#endif /* 0 */ -static struct partial_symbol * -lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global, - namespace_enum namespace) +/* A default version of lookup_symbol_nonlocal for use by languages + that can't think of anything better to do. This implements the C + lookup rules. */ + +struct symbol * +basic_lookup_symbol_nonlocal (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab) +{ + struct symbol *sym; + + /* NOTE: carlton/2003-05-19: The comments below were written when + this (or what turned into this) was part of lookup_symbol_aux; + I'm much less worried about these questions now, since these + decisions have turned out well, but I leave these comments here + for posterity. */ + + /* NOTE: carlton/2002-12-05: There is a question as to whether or + not it would be appropriate to search the current global block + here as well. (That's what this code used to do before the + is_a_field_of_this check was moved up.) On the one hand, it's + redundant with the lookup_symbol_aux_symtabs search that happens + next. On the other hand, if decode_line_1 is passed an argument + like filename:var, then the user presumably wants 'var' to be + searched for in filename. On the third hand, there shouldn't be + multiple global variables all of which are named 'var', and it's + not like decode_line_1 has ever restricted its search to only + global variables in a single filename. All in all, only + searching the static block here seems best: it's correct and it's + cleanest. */ + + /* NOTE: carlton/2002-12-05: There's also a possible performance + issue here: if you usually search for global symbols in the + current file, then it would be slightly better to search the + current global block before searching all the symtabs. But there + are other factors that have a much greater effect on performance + than that one, so I don't think we should worry about that for + now. */ + + sym = lookup_symbol_static (name, linkage_name, block, domain, symtab); + if (sym != NULL) + return sym; + + return lookup_symbol_global (name, linkage_name, domain, symtab); +} + +/* Lookup a symbol in the static block associated to BLOCK, if there + is one; do nothing if BLOCK is NULL or a global block. */ + +struct symbol * +lookup_symbol_static (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab) +{ + const struct block *static_block = block_static_block (block); + + if (static_block != NULL) + return lookup_symbol_aux_block (name, linkage_name, static_block, + domain, symtab); + else + return NULL; +} + +/* Lookup a symbol in all files' global blocks (searching psymtabs if + necessary). */ + +struct symbol * +lookup_symbol_global (const char *name, + const char *linkage_name, + const domain_enum domain, + struct symtab **symtab) +{ + struct symbol *sym; + + sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, + domain, symtab); + if (sym != NULL) + return sym; + + return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, + domain, symtab); +} + +/* Look, in partial_symtab PST, for symbol whose natural name is NAME. + If LINKAGE_NAME is non-NULL, check in addition that the symbol's + linkage name matches it. Check the global symbols if GLOBAL, the + static symbols if not */ + +struct partial_symbol * +lookup_partial_symbol (struct partial_symtab *pst, const char *name, + const char *linkage_name, int global, + domain_enum domain) { struct partial_symbol *temp; struct partial_symbol **start, **psym; - struct partial_symbol **top, **bottom, **center; + struct partial_symbol **top, **real_top, **bottom, **center; int length = (global ? pst->n_global_syms : pst->n_static_syms); int do_linear_search = 1; @@ -996,12 +1449,14 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global, do_linear_search = 0; /* Binary search. This search is guaranteed to end with center - pointing at the earliest partial symbol with the correct - name. At that point *all* partial symbols with that name - will be checked against the correct namespace. */ + pointing at the earliest partial symbol whose name might be + correct. At that point *all* partial symbols with an + appropriate name will be checked against the correct + domain. */ bottom = start; top = start + length - 1; + real_top = top; while (top > bottom) { center = bottom + (top - bottom) / 2; @@ -1012,7 +1467,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global, { do_linear_search = 1; } - if (strcmp (SYMBOL_SOURCE_NAME (*center), name) >= 0) + if (strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*center), name) >= 0) { top = center; } @@ -1024,12 +1479,12 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global, if (!(top == bottom)) internal_error (__FILE__, __LINE__, "failed internal consistency check"); - /* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so - we don't have to force a linear search on C++. Probably holds true - for JAVA as well, no way to check.*/ - while (SYMBOL_MATCHES_NAME (*top,name)) + while (top <= real_top + && (linkage_name != NULL + ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0 + : SYMBOL_MATCHES_NATURAL_NAME (*top,name))) { - if (SYMBOL_NAMESPACE (*top) == namespace) + if (SYMBOL_DOMAIN (*top) == domain) { return (*top); } @@ -1044,9 +1499,11 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global, { for (psym = start; psym < start + length; psym++) { - if (namespace == SYMBOL_NAMESPACE (*psym)) + if (domain == SYMBOL_DOMAIN (*psym)) { - if (SYMBOL_MATCHES_NAME (*psym, name)) + if (linkage_name != NULL + ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0 + : SYMBOL_MATCHES_NATURAL_NAME (*psym, name)) { return (*psym); } @@ -1057,23 +1514,31 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global, return (NULL); } -/* Look up a type named NAME in the struct_namespace. The type returned - must not be opaque -- i.e., must have at least one field defined - - This code was modelled on lookup_symbol -- the parts not relevant to looking - up types were just left out. In particular it's assumed here that types - are available in struct_namespace and only at file-static or global blocks. */ - +/* Look up a type named NAME in the struct_domain. The type returned + must not be opaque -- i.e., must have at least one field + defined. */ struct type * lookup_transparent_type (const char *name) { - register struct symbol *sym; - register struct symtab *s = NULL; - register struct partial_symtab *ps; + return current_language->la_lookup_transparent_type (name); +} + +/* The standard implementation of lookup_transparent_type. This code + was modeled on lookup_symbol -- the parts not relevant to looking + up types were just left out. In particular it's assumed here that + types are available in struct_domain and only at file-static or + global blocks. */ + +struct type * +basic_lookup_transparent_type (const char *name) +{ + struct symbol *sym; + struct symtab *s = NULL; + struct partial_symtab *ps; struct blockvector *bv; - register struct objfile *objfile; - register struct block *block; + struct objfile *objfile; + struct block *block; /* Now search all the global symbols. Do the symtab's first, then check the psymtab's. If a psymtab indicates the existence @@ -1084,7 +1549,7 @@ lookup_transparent_type (const char *name) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) { return SYMBOL_TYPE (sym); @@ -1093,12 +1558,13 @@ lookup_transparent_type (const char *name) ALL_PSYMTABS (objfile, ps) { - if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_NAMESPACE)) + if (!ps->readin && lookup_partial_symbol (ps, name, NULL, + 1, STRUCT_DOMAIN)) { s = PSYMTAB_TO_SYMTAB (ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); if (!sym) { /* This shouldn't be necessary, but as a last resort @@ -1107,7 +1573,7 @@ lookup_transparent_type (const char *name) * the psymtab gets it wrong in some cases. */ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); if (!sym) error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\ %s may be an inlined function, or may be a template function\n\ @@ -1131,7 +1597,7 @@ lookup_transparent_type (const char *name) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) { return SYMBOL_TYPE (sym); @@ -1140,12 +1606,12 @@ lookup_transparent_type (const char *name) ALL_PSYMTABS (objfile, ps) { - if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_NAMESPACE)) + if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN)) { s = PSYMTAB_TO_SYMTAB (ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); if (!sym) { /* This shouldn't be necessary, but as a last resort @@ -1154,7 +1620,7 @@ lookup_transparent_type (const char *name) * the psymtab gets it wrong in some cases. */ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); if (!sym) error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\ %s may be an inlined function, or may be a template function\n\ @@ -1176,12 +1642,12 @@ lookup_transparent_type (const char *name) struct partial_symtab * find_main_psymtab (void) { - register struct partial_symtab *pst; - register struct objfile *objfile; + struct partial_symtab *pst; + struct objfile *objfile; ALL_PSYMTABS (objfile, pst) { - if (lookup_partial_symbol (pst, main_name (), 1, VAR_NAMESPACE)) + if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN)) { return (pst); } @@ -1189,202 +1655,75 @@ find_main_psymtab (void) return (NULL); } -/* Search BLOCK for symbol NAME in NAMESPACE. +/* Search BLOCK for symbol NAME in DOMAIN. Note that if NAME is the demangled form of a C++ symbol, we will fail to find a match during the binary search of the non-encoded names, but for now we don't worry about the slight inefficiency of looking for a match we'll never find, since it will go pretty quick. Once the binary search terminates, we drop through and do a straight linear - search on the symbols. Each symbol which is marked as being a C++ - symbol (language_cplus set) has both the encoded and non-encoded names - tested for a match. */ + search on the symbols. Each symbol which is marked as being a ObjC/C++ + symbol (language_cplus or language_objc set) has both the encoded and + non-encoded names tested for a match. + + If LINKAGE_NAME is non-NULL, verify that any symbol we find has this + particular mangled name. +*/ struct symbol * -lookup_block_symbol (register const struct block *block, const char *name, - const namespace_enum namespace) +lookup_block_symbol (const struct block *block, const char *name, + const char *linkage_name, + const domain_enum domain) { - register int bot, top, inc; - register struct symbol *sym; - register struct symbol *sym_found = NULL; - register int do_linear_search = 1; + struct dict_iterator iter; + struct symbol *sym; - /* If the blocks's symbols were sorted, start with a binary search. */ - - if (BLOCK_SHOULD_SORT (block)) + if (!BLOCK_FUNCTION (block)) { - /* Reset the linear search flag so if the binary search fails, we - won't do the linear search once unless we find some reason to - do so */ - - do_linear_search = 0; - top = BLOCK_NSYMS (block); - bot = 0; - - /* Advance BOT to not far before the first symbol whose name is NAME. */ - - while (1) + for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter); + sym != NULL; + sym = dict_iter_name_next (name, &iter)) { - inc = (top - bot + 1); - /* No need to keep binary searching for the last few bits worth. */ - if (inc < 4) - { - break; - } - inc = (inc >> 1) + bot; - sym = BLOCK_SYM (block, inc); - if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java)) - { - do_linear_search = 1; - } - if (SYMBOL_SOURCE_NAME (sym)[0] < name[0]) - { - bot = inc; - } - else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0]) - { - top = inc; - } - else if (strcmp (SYMBOL_SOURCE_NAME (sym), name) < 0) - { - bot = inc; - } - else - { - top = inc; - } - } - - /* Now scan forward until we run out of symbols, find one whose - name is greater than NAME, or find one we want. If there is - more than one symbol with the right name and namespace, we - return the first one; I believe it is now impossible for us - to encounter two symbols with the same name and namespace - here, because blocks containing argument symbols are no - longer sorted. */ - - top = BLOCK_NSYMS (block); - while (bot < top) - { - sym = BLOCK_SYM (block, bot); - if (SYMBOL_NAMESPACE (sym) == namespace && - SYMBOL_MATCHES_NAME (sym, name)) - { - return sym; - } - if (SYMBOL_SOURCE_NAME (sym)[0] > name[0]) - { - break; - } - bot++; + if (SYMBOL_DOMAIN (sym) == domain + && (linkage_name != NULL + ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1)) + return sym; } + return NULL; } - - /* Here if block isn't sorted, or we fail to find a match during the - binary search above. If during the binary search above, we find a - symbol which is a Java symbol, then we have re-enabled the linear - search flag which was reset when starting the binary search. - - This loop is equivalent to the loop above, but hacked greatly for speed. - - Note that parameter symbols do not always show up last in the - list; this loop makes sure to take anything else other than - parameter symbols first; it only uses parameter symbols as a - last resort. Note that this only takes up extra computation - time on a match. */ - - if (do_linear_search) + else { - top = BLOCK_NSYMS (block); - bot = 0; - while (bot < top) + /* Note that parameter symbols do not always show up last in the + list; this loop makes sure to take anything else other than + parameter symbols first; it only uses parameter symbols as a + last resort. Note that this only takes up extra computation + time on a match. */ + + struct symbol *sym_found = NULL; + + for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter); + sym != NULL; + sym = dict_iter_name_next (name, &iter)) { - sym = BLOCK_SYM (block, bot); - if (SYMBOL_NAMESPACE (sym) == namespace && - SYMBOL_MATCHES_NAME (sym, name)) + if (SYMBOL_DOMAIN (sym) == domain + && (linkage_name != NULL + ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1)) { - /* If SYM has aliases, then use any alias that is active - at the current PC. If no alias is active at the current - PC, then use the main symbol. - - ?!? Is checking the current pc correct? Is this routine - ever called to look up a symbol from another context? - - FIXME: No, it's not correct. If someone sets a - conditional breakpoint at an address, then the - breakpoint's `struct expression' should refer to the - `struct symbol' appropriate for the breakpoint's - address, which may not be the PC. - - Even if it were never called from another context, - it's totally bizarre for lookup_symbol's behavior to - depend on the value of the inferior's current PC. We - should pass in the appropriate PC as well as the - block. The interface to lookup_symbol should change - to require the caller to provide a PC. */ - - if (SYMBOL_ALIASES (sym)) - sym = find_active_alias (sym, read_pc ()); - sym_found = sym; if (SYMBOL_CLASS (sym) != LOC_ARG && SYMBOL_CLASS (sym) != LOC_LOCAL_ARG && SYMBOL_CLASS (sym) != LOC_REF_ARG && SYMBOL_CLASS (sym) != LOC_REGPARM && SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR && - SYMBOL_CLASS (sym) != LOC_BASEREG_ARG) + SYMBOL_CLASS (sym) != LOC_BASEREG_ARG && + SYMBOL_CLASS (sym) != LOC_COMPUTED_ARG) { break; } } - bot++; } + return (sym_found); /* Will be NULL if not found. */ } - return (sym_found); /* Will be NULL if not found. */ -} - -/* Given a main symbol SYM and ADDR, search through the alias - list to determine if an alias is active at ADDR and return - the active alias. - - If no alias is active, then return SYM. */ - -static struct symbol * -find_active_alias (struct symbol *sym, CORE_ADDR addr) -{ - struct range_list *r; - struct alias_list *aliases; - - /* If we have aliases, check them first. */ - aliases = SYMBOL_ALIASES (sym); - - while (aliases) - { - if (!SYMBOL_RANGES (aliases->sym)) - return aliases->sym; - for (r = SYMBOL_RANGES (aliases->sym); r; r = r->next) - { - if (r->start <= addr && r->end > addr) - return aliases->sym; - } - aliases = aliases->next; - } - - /* Nothing found, return the main symbol. */ - return sym; -} - - -/* Return the symbol for the function which contains a specified - lexical block, described by a struct block BL. */ - -struct symbol * -block_function (struct block *bl) -{ - while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0) - bl = BLOCK_SUPERBLOCK (bl); - - return BLOCK_FUNCTION (bl); } /* Find the symtab associated with PC and SECTION. Look through the @@ -1393,12 +1732,12 @@ block_function (struct block *bl) struct symtab * find_pc_sect_symtab (CORE_ADDR pc, asection *section) { - register struct block *b; + struct block *b; struct blockvector *bv; - register struct symtab *s = NULL; - register struct symtab *best_s = NULL; - register struct partial_symtab *ps; - register struct objfile *objfile; + struct symtab *s = NULL; + struct symtab *best_s = NULL; + struct partial_symtab *ps; + struct objfile *objfile; CORE_ADDR distance = 0; struct minimal_symbol *msymbol; @@ -1455,15 +1794,16 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section) } if (section != 0) { - int i; + struct dict_iterator iter; + struct symbol *sym = NULL; - for (i = 0; i < b->nsyms; i++) + ALL_BLOCK_SYMBOLS (b, iter, sym) { - fixup_symbol_section (b->sym[i], objfile); - if (section == SYMBOL_BFD_SECTION (b->sym[i])) + fixup_symbol_section (sym, objfile); + if (section == SYMBOL_BFD_SECTION (sym)) break; } - if (i >= b->nsyms) + if (sym == NULL) continue; /* no symbol in this symtab matches section */ } distance = BLOCK_END (b) - BLOCK_START (b); @@ -1500,96 +1840,6 @@ find_pc_symtab (CORE_ADDR pc) } -#if 0 - -/* Find the closest symbol value (of any sort -- function or variable) - for a given address value. Slow but complete. (currently unused, - mainly because it is too slow. We could fix it if each symtab and - psymtab had contained in it the addresses ranges of each of its - sections, which also would be required to make things like "info - line *0x2345" cause psymtabs to be converted to symtabs). */ - -struct symbol * -find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp) -{ - struct symtab *symtab, *best_symtab; - struct objfile *objfile; - register int bot, top; - register struct symbol *sym; - register CORE_ADDR sym_addr; - struct block *block; - int blocknum; - - /* Info on best symbol seen so far */ - - register CORE_ADDR best_sym_addr = 0; - struct symbol *best_sym = 0; - - /* FIXME -- we should pull in all the psymtabs, too! */ - ALL_SYMTABS (objfile, symtab) - { - /* Search the global and static blocks in this symtab for - the closest symbol-address to the desired address. */ - - for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++) - { - QUIT; - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum); - top = BLOCK_NSYMS (block); - for (bot = 0; bot < top; bot++) - { - sym = BLOCK_SYM (block, bot); - switch (SYMBOL_CLASS (sym)) - { - case LOC_STATIC: - case LOC_LABEL: - sym_addr = SYMBOL_VALUE_ADDRESS (sym); - break; - - case LOC_INDIRECT: - sym_addr = SYMBOL_VALUE_ADDRESS (sym); - /* An indirect symbol really lives at *sym_addr, - * so an indirection needs to be done. - * However, I am leaving this commented out because it's - * expensive, and it's possible that symbolization - * could be done without an active process (in - * case this read_memory will fail). RT - sym_addr = read_memory_unsigned_integer - (sym_addr, TARGET_PTR_BIT / TARGET_CHAR_BIT); - */ - break; - - case LOC_BLOCK: - sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - break; - - default: - continue; - } - - if (sym_addr <= addr) - if (sym_addr > best_sym_addr) - { - /* Quit if we found an exact match. */ - best_sym = sym; - best_sym_addr = sym_addr; - best_symtab = symtab; - if (sym_addr == addr) - goto done; - } - } - } - } - -done: - if (symtabp) - *symtabp = best_symtab; - if (symaddrp) - *symaddrp = best_sym_addr; - return best_sym; -} -#endif /* 0 */ - /* Find the source file and line number for a given PC value and SECTION. Return a structure containing a symtab pointer, a line number, and a pc range for the entire source line. @@ -1608,13 +1858,13 @@ done: /* If it's worth the effort, we could be using a binary search. */ struct symtab_and_line -find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent) +find_pc_sect_line (CORE_ADDR pc, struct bfd_section *section, int notcurrent) { struct symtab *s; - register struct linetable *l; - register int len; - register int i; - register struct linetable_entry *item; + struct linetable *l; + int len; + int i; + struct linetable_entry *item; struct symtab_and_line val; struct blockvector *bv; struct minimal_symbol *msymbol; @@ -1644,7 +1894,7 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent) But what we want is the statement containing the instruction. Fudge the pc to make sure we get that. */ - INIT_SAL (&val); /* initialize to zeroes */ + init_sal (&val); /* initialize to zeroes */ /* It's tempting to assume that, if we can't find debugging info for any function enclosing PC, that we shouldn't search for line @@ -1704,7 +1954,8 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent) if (msymbol != NULL) if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) { - mfunsym = lookup_minimal_symbol_text (SYMBOL_NAME (msymbol), NULL, NULL); + mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol), + NULL); if (mfunsym == NULL) /* I eliminated this warning since it is coming out * in the following situation: @@ -1715,12 +1966,12 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent) * so of course we can't find the real func/line info, * but the "break" still works, and the warning is annoying. * So I commented out the warning. RT */ - /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ; + /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ; /* fall through */ else if (SYMBOL_VALUE (mfunsym) == SYMBOL_VALUE (msymbol)) /* Avoid infinite recursion */ /* See above comment about why warning is commented out */ - /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ; + /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ; /* fall through */ else return find_pc_line (SYMBOL_VALUE (mfunsym), 0); @@ -1786,9 +2037,11 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent) the first line, prev will not be set. */ /* Is this file's best line closer than the best in the other files? - If so, record this file, and its best line, as best so far. */ + If so, record this file, and its best line, as best so far. Don't + save prev if it represents the end of a function (i.e. line number + 0) instead of a real line. */ - if (prev && (!best || prev->pc > best->pc)) + if (prev && prev->line && (!best || prev->pc > best->pc)) { best = prev; best_symtab = s; @@ -1915,7 +2168,7 @@ find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match) struct linetable *l; int ind; - if (!STREQ (symtab->filename, s->filename)) + if (strcmp (symtab->filename, s->filename) != 0) continue; l = LINETABLE (s); ind = find_line_common (l, line, &exact); @@ -2021,11 +2274,11 @@ find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr, Set *EXACT_MATCH nonzero if the value returned is an exact match. */ static int -find_line_common (register struct linetable *l, register int lineno, +find_line_common (struct linetable *l, int lineno, int *exact_match) { - register int i; - register int len; + int i; + int len; /* BEST is the smallest linenumber > LINENO so far seen, or 0 if none has been seen so far. @@ -2042,7 +2295,7 @@ find_line_common (register struct linetable *l, register int lineno, len = l->nitems; for (i = 0; i < len; i++) { - register struct linetable_entry *item = &(l->item[i]); + struct linetable_entry *item = &(l->item[i]); if (item->line == lineno) { @@ -2104,10 +2357,6 @@ find_function_start_sal (struct symbol *sym, int funfirstline) } sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0); -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* Convex: no need to suppress code on first line, if any */ - sal.pc = pc; -#else /* Check if SKIP_PROLOGUE left us in mid-line, and the next line is still part of the same function. */ if (sal.pc != pc @@ -2120,7 +2369,6 @@ find_function_start_sal (struct symbol *sym, int funfirstline) sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0); } sal.pc = pc; -#endif return sal; } @@ -2150,7 +2398,7 @@ operator_chars (char *p, char **end) if (isalpha (*p) || *p == '_' || *p == '$') { - register char *q = p + 1; + char *q = p + 1; while (isalnum (*q) || *q == '_' || *q == '$') q++; *end = q; @@ -2340,9 +2588,9 @@ output_source_filename (char *name, int *first) static void sources_info (char *ignore, int from_tty) { - register struct symtab *s; - register struct partial_symtab *ps; - register struct objfile *objfile; + struct symtab *s; + struct partial_symtab *ps; + struct objfile *objfile; int first; if (!have_full_symbols () && !have_partial_symbols ()) @@ -2424,8 +2672,8 @@ compare_search_syms (const void *sa, const void *sb) struct symbol_search **sym_a = (struct symbol_search **) sa; struct symbol_search **sym_b = (struct symbol_search **) sb; - return strcmp (SYMBOL_SOURCE_NAME ((*sym_a)->symbol), - SYMBOL_SOURCE_NAME ((*sym_b)->symbol)); + return strcmp (SYMBOL_PRINT_NAME ((*sym_a)->symbol), + SYMBOL_PRINT_NAME ((*sym_b)->symbol)); } /* Sort the ``nfound'' symbols in the list after prevtail. Leave @@ -2467,10 +2715,10 @@ sort_search_symbols (struct symbol_search *prevtail, int nfound) returning the results in *MATCHES. Only symbols of KIND are searched: - FUNCTIONS_NAMESPACE - search all functions - TYPES_NAMESPACE - search all type names - METHODS_NAMESPACE - search all methods NOT IMPLEMENTED - VARIABLES_NAMESPACE - search all symbols, excluding functions, type names, + FUNCTIONS_DOMAIN - search all functions + TYPES_DOMAIN - search all type names + METHODS_DOMAIN - search all methods NOT IMPLEMENTED + VARIABLES_DOMAIN - search all symbols, excluding functions, type names, and constants (enums) free_search_symbols should be called when *MATCHES is no longer needed. @@ -2479,17 +2727,17 @@ sort_search_symbols (struct symbol_search *prevtail, int nfound) separately alphabetized. */ void -search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], +search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], struct symbol_search **matches) { - register struct symtab *s; - register struct partial_symtab *ps; - register struct blockvector *bv; + struct symtab *s; + struct partial_symtab *ps; + struct blockvector *bv; struct blockvector *prev_bv = 0; - register struct block *b; - register int i = 0; - register int j; - register struct symbol *sym; + struct block *b; + int i = 0; + struct dict_iterator iter; + struct symbol *sym; struct partial_symbol **psym; struct objfile *objfile; struct minimal_symbol *msymbol; @@ -2516,13 +2764,13 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], struct symbol_search *tail; struct cleanup *old_chain = NULL; - if (kind < VARIABLES_NAMESPACE) - error ("must search on specific namespace"); + if (kind < VARIABLES_DOMAIN) + error ("must search on specific domain"); - ourtype = types[(int) (kind - VARIABLES_NAMESPACE)]; - ourtype2 = types2[(int) (kind - VARIABLES_NAMESPACE)]; - ourtype3 = types3[(int) (kind - VARIABLES_NAMESPACE)]; - ourtype4 = types4[(int) (kind - VARIABLES_NAMESPACE)]; + ourtype = types[(int) (kind - VARIABLES_DOMAIN)]; + ourtype2 = types2[(int) (kind - VARIABLES_DOMAIN)]; + ourtype3 = types3[(int) (kind - VARIABLES_DOMAIN)]; + ourtype4 = types4[(int) (kind - VARIABLES_DOMAIN)]; sr = *matches = NULL; tail = NULL; @@ -2602,12 +2850,13 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], /* If it would match (logic taken from loop below) load the file and go on to the next one */ if (file_matches (ps->filename, files, nfiles) - && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym)) - && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF + && ((regexp == NULL + || re_exec (SYMBOL_NATURAL_NAME (*psym)) != 0) + && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (*psym) != LOC_TYPEDEF && SYMBOL_CLASS (*psym) != LOC_BLOCK) - || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK) - || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF) - || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)))) + || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK) + || (kind == TYPES_DOMAIN && SYMBOL_CLASS (*psym) == LOC_TYPEDEF) + || (kind == METHODS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK)))) { PSYMTAB_TO_SYMTAB (ps); keep_going = 0; @@ -2630,7 +2879,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], any matching symbols without debug info. */ - if (nfiles == 0 && (kind == VARIABLES_NAMESPACE || kind == FUNCTIONS_NAMESPACE)) + if (nfiles == 0 && (kind == VARIABLES_DOMAIN || kind == FUNCTIONS_DOMAIN)) { ALL_MSYMBOLS (objfile, msymbol) { @@ -2639,14 +2888,21 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype4) { - if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol)) + if (regexp == NULL + || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0) { if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))) { - if (kind == FUNCTIONS_NAMESPACE - || lookup_symbol (SYMBOL_NAME (msymbol), + /* FIXME: carlton/2003-02-04: Given that the + semantics of lookup_symbol keeps on changing + slightly, it would be a nice idea if we had a + function lookup_symbol_minsym that found the + symbol associated to a given minimal symbol (if + any). */ + if (kind == FUNCTIONS_DOMAIN + || lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), (struct block *) NULL, - VAR_NAMESPACE, + VAR_DOMAIN, 0, (struct symtab **) NULL) == NULL) found_misc = 1; } @@ -2669,18 +2925,18 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], struct symbol_search *prevtail = tail; int nfound = 0; b = BLOCKVECTOR_BLOCK (bv, i); - for (j = 0; j < BLOCK_NSYMS (b); j++) + ALL_BLOCK_SYMBOLS (b, iter, sym) { QUIT; - sym = BLOCK_SYM (b, j); if (file_matches (s->filename, files, nfiles) - && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym)) - && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF + && ((regexp == NULL + || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0) + && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF && SYMBOL_CLASS (sym) != LOC_BLOCK && SYMBOL_CLASS (sym) != LOC_CONST) - || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK) - || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF) - || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)))) + || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK) + || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + || (kind == METHODS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)))) { /* match */ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search)); @@ -2719,7 +2975,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], /* If there are no eyes, avoid all contact. I mean, if there are no debug symbols, then print directly from the msymbol_vector. */ - if (found_misc || kind != FUNCTIONS_NAMESPACE) + if (found_misc || kind != FUNCTIONS_DOMAIN) { ALL_MSYMBOLS (objfile, msymbol) { @@ -2728,15 +2984,16 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype4) { - if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol)) + if (regexp == NULL + || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0) { /* Functions: Look up by address. */ - if (kind != FUNCTIONS_NAMESPACE || + if (kind != FUNCTIONS_DOMAIN || (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))) { /* Variables/Absolutes: Look up by name */ - if (lookup_symbol (SYMBOL_NAME (msymbol), - (struct block *) NULL, VAR_NAMESPACE, + if (lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), + (struct block *) NULL, VAR_DOMAIN, 0, (struct symtab **) NULL) == NULL) { /* match */ @@ -2771,7 +3028,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], regarding the match to gdb_stdout. */ static void -print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym, +print_symbol_info (domain_enum kind, struct symtab *s, struct symbol *sym, int block, char *last) { if (last == NULL || strcmp (last, s->filename) != 0) @@ -2781,49 +3038,25 @@ print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym, fputs_filtered (":\n", gdb_stdout); } - if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK) + if (kind != TYPES_DOMAIN && block == STATIC_BLOCK) printf_filtered ("static "); /* Typedef that is not a C++ class */ - if (kind == TYPES_NAMESPACE - && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE) + if (kind == TYPES_DOMAIN + && SYMBOL_DOMAIN (sym) != STRUCT_DOMAIN) typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout); /* variable, func, or typedef-that-is-c++-class */ - else if (kind < TYPES_NAMESPACE || - (kind == TYPES_NAMESPACE && - SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE)) + else if (kind < TYPES_DOMAIN || + (kind == TYPES_DOMAIN && + SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN)) { type_print (SYMBOL_TYPE (sym), (SYMBOL_CLASS (sym) == LOC_TYPEDEF - ? "" : SYMBOL_SOURCE_NAME (sym)), + ? "" : SYMBOL_PRINT_NAME (sym)), gdb_stdout, 0); printf_filtered (";\n"); } - else - { -#if 0 - /* Tiemann says: "info methods was never implemented." */ - char *demangled_name; - c_type_print_base (TYPE_FN_FIELD_TYPE (t, block), - gdb_stdout, 0, 0); - c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (t, block), - gdb_stdout, 0); - if (TYPE_FN_FIELD_STUB (t, block)) - check_stub_method (TYPE_DOMAIN_TYPE (type), j, block); - demangled_name = - cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, block), - DMGL_ANSI | DMGL_PARAMS); - if (demangled_name == NULL) - fprintf_filtered (stream, "", - TYPE_FN_FIELD_PHYSNAME (t, block)); - else - { - fputs_filtered (demangled_name, stream); - xfree (demangled_name); - } -#endif - } } /* This help function for symtab_symbol_info() prints information @@ -2835,14 +3068,14 @@ print_msymbol_info (struct minimal_symbol *msymbol) char *tmp; if (TARGET_ADDR_BIT <= 32) - tmp = longest_local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol) - & (CORE_ADDR) 0xffffffff, - "08l"); + tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol) + & (CORE_ADDR) 0xffffffff, + "08l"); else - tmp = longest_local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol), - "016l"); + tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol), + "016l"); printf_filtered ("%s %s\n", - tmp, SYMBOL_SOURCE_NAME (msymbol)); + tmp, SYMBOL_PRINT_NAME (msymbol)); } /* This is the guts of the commands "info functions", "info types", and @@ -2851,7 +3084,7 @@ print_msymbol_info (struct minimal_symbol *msymbol) matches. */ static void -symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty) +symtab_symbol_info (char *regexp, domain_enum kind, int from_tty) { static char *classnames[] = @@ -2869,7 +3102,7 @@ symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty) printf_filtered (regexp ? "All %ss matching regular expression \"%s\":\n" : "All defined %ss:\n", - classnames[(int) (kind - VARIABLES_NAMESPACE)], regexp); + classnames[(int) (kind - VARIABLES_DOMAIN)], regexp); for (p = symbols; p != NULL; p = p->next) { @@ -2901,31 +3134,22 @@ symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty) static void variables_info (char *regexp, int from_tty) { - symtab_symbol_info (regexp, VARIABLES_NAMESPACE, from_tty); + symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty); } static void functions_info (char *regexp, int from_tty) { - symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty); + symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty); } static void types_info (char *regexp, int from_tty) { - symtab_symbol_info (regexp, TYPES_NAMESPACE, from_tty); + symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty); } -#if 0 -/* Tiemann says: "info methods was never implemented." */ -static void -methods_info (char *regexp) -{ - symtab_symbol_info (regexp, METHODS_NAMESPACE, 0, from_tty); -} -#endif /* 0 */ - /* Breakpoint all functions matching regular expression. */ void @@ -2941,22 +3165,22 @@ rbreak_command (char *regexp, int from_tty) struct symbol_search *p; struct cleanup *old_chain; - search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss); + search_symbols (regexp, FUNCTIONS_DOMAIN, 0, (char **) NULL, &ss); old_chain = make_cleanup_free_search_symbols (ss); for (p = ss; p != NULL; p = p->next) { if (p->msymbol == NULL) { - char *string = (char *) alloca (strlen (p->symtab->filename) - + strlen (SYMBOL_NAME (p->symbol)) - + 4); + char *string = alloca (strlen (p->symtab->filename) + + strlen (SYMBOL_LINKAGE_NAME (p->symbol)) + + 4); strcpy (string, p->symtab->filename); strcat (string, ":'"); - strcat (string, SYMBOL_NAME (p->symbol)); + strcat (string, SYMBOL_LINKAGE_NAME (p->symbol)); strcat (string, "'"); break_command (string, from_tty); - print_symbol_info (FUNCTIONS_NAMESPACE, + print_symbol_info (FUNCTIONS_DOMAIN, p->symtab, p->symbol, p->block, @@ -2964,9 +3188,9 @@ rbreak_command (char *regexp, int from_tty) } else { - break_command (SYMBOL_NAME (p->msymbol), from_tty); + break_command (SYMBOL_LINKAGE_NAME (p->msymbol), from_tty); printf_filtered (" %s;\n", - SYMBOL_SOURCE_NAME (p->msymbol)); + SYMBOL_PRINT_NAME (p->msymbol)); } } @@ -2974,19 +3198,6 @@ rbreak_command (char *regexp, int from_tty) } -/* Return Nonzero if block a is lexically nested within block b, - or if a and b have the same pc range. - Return zero otherwise. */ -int -contained_in (struct block *a, struct block *b) -{ - if (!a || !b) - return 0; - return BLOCK_START (a) >= BLOCK_START (b) - && BLOCK_END (a) <= BLOCK_END (b); -} - - /* Helper routine for make_symbol_completion_list. */ static int return_val_size; @@ -2994,17 +3205,8 @@ static int return_val_index; static char **return_val; #define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \ - do { \ - if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \ - /* Put only the mangled name on the list. */ \ - /* Advantage: "b foo" completes to "b foo(int, int)" */ \ - /* Disadvantage: "b foo__i" doesn't complete. */ \ completion_list_add_name \ - (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \ - else \ - completion_list_add_name \ - (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \ - } while (0) + (SYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word)) /* Test to see if the symbol specified by SYMNAME (which is already demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN @@ -3059,6 +3261,112 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len, } } +/* ObjC: In case we are completing on a selector, look as the msymbol + again and feed all the selectors into the mill. */ + +static void +completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text, + int sym_text_len, char *text, char *word) +{ + static char *tmp = NULL; + static unsigned int tmplen = 0; + + char *method, *category, *selector; + char *tmp2 = NULL; + + method = SYMBOL_NATURAL_NAME (msymbol); + + /* Is it a method? */ + if ((method[0] != '-') && (method[0] != '+')) + return; + + if (sym_text[0] == '[') + /* Complete on shortened method method. */ + completion_list_add_name (method + 1, sym_text, sym_text_len, text, word); + + while ((strlen (method) + 1) >= tmplen) + { + if (tmplen == 0) + tmplen = 1024; + else + tmplen *= 2; + tmp = xrealloc (tmp, tmplen); + } + selector = strchr (method, ' '); + if (selector != NULL) + selector++; + + category = strchr (method, '('); + + if ((category != NULL) && (selector != NULL)) + { + memcpy (tmp, method, (category - method)); + tmp[category - method] = ' '; + memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1); + completion_list_add_name (tmp, sym_text, sym_text_len, text, word); + if (sym_text[0] == '[') + completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word); + } + + if (selector != NULL) + { + /* Complete on selector only. */ + strcpy (tmp, selector); + tmp2 = strchr (tmp, ']'); + if (tmp2 != NULL) + *tmp2 = '\0'; + + completion_list_add_name (tmp, sym_text, sym_text_len, text, word); + } +} + +/* Break the non-quoted text based on the characters which are in + symbols. FIXME: This should probably be language-specific. */ + +static char * +language_search_unquoted_string (char *text, char *p) +{ + for (; p > text; --p) + { + if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0') + continue; + else + { + if ((current_language->la_language == language_objc)) + { + if (p[-1] == ':') /* might be part of a method name */ + continue; + else if (p[-1] == '[' && (p[-2] == '-' || p[-2] == '+')) + p -= 2; /* beginning of a method name */ + else if (p[-1] == ' ' || p[-1] == '(' || p[-1] == ')') + { /* might be part of a method name */ + char *t = p; + + /* Seeing a ' ' or a '(' is not conclusive evidence + that we are in the middle of a method name. However, + finding "-[" or "+[" should be pretty un-ambiguous. + Unfortunately we have to find it now to decide. */ + + while (t > text) + if (isalnum (t[-1]) || t[-1] == '_' || + t[-1] == ' ' || t[-1] == ':' || + t[-1] == '(' || t[-1] == ')') + --t; + else + break; + + if (t[-1] == '[' && (t[-2] == '-' || t[-2] == '+')) + p = t - 2; /* method name detected */ + /* else we leave with p unchanged */ + } + } + break; + } + } + return p; +} + + /* Return a NULL terminated array of all symbols (regardless of class) which begin by matching TEXT. If the answer is no symbols, then the return value is an array which contains only a NULL pointer. @@ -3069,13 +3377,14 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len, char ** make_symbol_completion_list (char *text, char *word) { - register struct symbol *sym; - register struct symtab *s; - register struct partial_symtab *ps; - register struct minimal_symbol *msymbol; - register struct objfile *objfile; - register struct block *b, *surrounding_static_block = 0; - register int i, j; + struct symbol *sym; + struct symtab *s; + struct partial_symtab *ps; + struct minimal_symbol *msymbol; + struct objfile *objfile; + struct block *b, *surrounding_static_block = 0; + struct dict_iterator iter; + int j; struct partial_symbol **psym; /* The symbol we are completing on. Points in same buffer as text. */ char *sym_text; @@ -3181,12 +3490,14 @@ make_symbol_completion_list (char *text, char *word) { QUIT; COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word); + + completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word); } /* Search upwards from currently selected frame (so that we can complete on local vars. */ - for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b)) + for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) { if (!BLOCK_SUPERBLOCK (b)) { @@ -3196,8 +3507,9 @@ make_symbol_completion_list (char *text, char *word) /* Also catch fields of types defined in this places which match our text string. Only complete on types visible from current context. */ - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { + QUIT; COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); if (SYMBOL_CLASS (sym) == LOC_TYPEDEF) { @@ -3226,7 +3538,7 @@ make_symbol_completion_list (char *text, char *word) { QUIT; b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); } @@ -3239,7 +3551,7 @@ make_symbol_completion_list (char *text, char *word) /* Don't do this block twice. */ if (b == surrounding_static_block) continue; - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); } @@ -3254,10 +3566,10 @@ make_symbol_completion_list (char *text, char *word) char ** make_file_symbol_completion_list (char *text, char *word, char *srcfile) { - register struct symbol *sym; - register struct symtab *s; - register struct block *b; - register int i; + struct symbol *sym; + struct symtab *s; + struct block *b; + struct dict_iterator iter; /* The symbol we are completing on. Points in same buffer as text. */ char *sym_text; /* Length of sym_text. */ @@ -3303,16 +3615,8 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile) } else { - /* It is not a quoted string. Break it based on the characters - which are in symbols. */ - while (p > text) - { - if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0') - --p; - else - break; - } - sym_text = p; + /* Not a quoted string. */ + sym_text = language_search_unquoted_string (text, p); } } @@ -3344,13 +3648,13 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile) symbols which match. */ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); } b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); - ALL_BLOCK_SYMBOLS (b, i, sym) + ALL_BLOCK_SYMBOLS (b, iter, sym) { COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); } @@ -3425,9 +3729,9 @@ not_interesting_fname (const char *fname) char ** make_source_files_completion_list (char *text, char *word) { - register struct symtab *s; - register struct partial_symtab *ps; - register struct objfile *objfile; + struct symtab *s; + struct partial_symtab *ps; + struct objfile *objfile; int first = 1; int list_alloced = 1; int list_used = 0; @@ -3591,192 +3895,78 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start) return func_addr <= pc && pc < sal.end; } +/* Given PC at the function's start address, attempt to find the + prologue end using SAL information. Return zero if the skip fails. -/* Begin overload resolution functions */ -/* Helper routine for make_symbol_completion_list. */ + A non-optimized prologue traditionally has one SAL for the function + and a second for the function body. A single line function has + them both pointing at the same line. -static int sym_return_val_size; -static int sym_return_val_index; -static struct symbol **sym_return_val; + An optimized prologue is similar but the prologue may contain + instructions (SALs) from the instruction body. Need to skip those + while not getting into the function body. -/* Test to see if the symbol specified by SYMNAME (which is already - demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN - characters. If so, add it to the current completion list. */ + The functions end point and an increasing SAL line are used as + indicators of the prologue's endpoint. -static void -overload_list_add_symbol (struct symbol *sym, char *oload_name) + This code is based on the function refine_prologue_limit (versions + found in both ia64 and ppc). */ + +CORE_ADDR +skip_prologue_using_sal (CORE_ADDR func_addr) { - int newsize; - int i; + struct symtab_and_line prologue_sal; + CORE_ADDR start_pc; + CORE_ADDR end_pc; - /* Get the demangled name without parameters */ - char *sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI); - if (!sym_name) + /* Get an initial range for the function. */ + find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc); + start_pc += FUNCTION_START_OFFSET; + + prologue_sal = find_pc_line (start_pc, 0); + if (prologue_sal.line != 0) { - sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1); - strcpy (sym_name, SYMBOL_NAME (sym)); - } - - /* skip symbols that cannot match */ - if (strcmp (sym_name, oload_name) != 0) - { - xfree (sym_name); - return; - } - - /* If there is no type information, we can't do anything, so skip */ - if (SYMBOL_TYPE (sym) == NULL) - return; - - /* skip any symbols that we've already considered. */ - for (i = 0; i < sym_return_val_index; ++i) - if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i]))) - return; - - /* We have a match for an overload instance, so add SYM to the current list - * of overload instances */ - if (sym_return_val_index + 3 > sym_return_val_size) - { - newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *); - sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize); - } - sym_return_val[sym_return_val_index++] = sym; - sym_return_val[sym_return_val_index] = NULL; - - xfree (sym_name); -} - -/* Return a null-terminated list of pointers to function symbols that - * match name of the supplied symbol FSYM. - * This is used in finding all overloaded instances of a function name. - * This has been modified from make_symbol_completion_list. */ - - -struct symbol ** -make_symbol_overload_list (struct symbol *fsym) -{ - register struct symbol *sym; - register struct symtab *s; - register struct partial_symtab *ps; - register struct objfile *objfile; - register struct block *b, *surrounding_static_block = 0; - register int i; - /* The name we are completing on. */ - char *oload_name = NULL; - /* Length of name. */ - int oload_name_len = 0; - - /* Look for the symbol we are supposed to complete on. - * FIXME: This should be language-specific. */ - - oload_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_ARM | DMGL_ANSI); - if (!oload_name) - { - oload_name = (char *) xmalloc (strlen (SYMBOL_NAME (fsym)) + 1); - strcpy (oload_name, SYMBOL_NAME (fsym)); - } - oload_name_len = strlen (oload_name); - - sym_return_val_size = 100; - sym_return_val_index = 0; - sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *)); - sym_return_val[0] = NULL; - - /* Look through the partial symtabs for all symbols which begin - by matching OLOAD_NAME. Make sure we read that symbol table in. */ - - ALL_PSYMTABS (objfile, ps) - { - struct partial_symbol **psym; - - /* If the psymtab's been read in we'll get it when we search - through the blockvector. */ - if (ps->readin) - continue; - - for (psym = objfile->global_psymbols.list + ps->globals_offset; - psym < (objfile->global_psymbols.list + ps->globals_offset - + ps->n_global_syms); - psym++) - { - /* If interrupted, then quit. */ - QUIT; - /* This will cause the symbol table to be read if it has not yet been */ - s = PSYMTAB_TO_SYMTAB (ps); - } - - for (psym = objfile->static_psymbols.list + ps->statics_offset; - psym < (objfile->static_psymbols.list + ps->statics_offset - + ps->n_static_syms); - psym++) - { - QUIT; - /* This will cause the symbol table to be read if it has not yet been */ - s = PSYMTAB_TO_SYMTAB (ps); - } - } - - /* Search upwards from currently selected frame (so that we can - complete on local vars. */ - - for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b)) - { - if (!BLOCK_SUPERBLOCK (b)) + while (prologue_sal.end < end_pc) { - surrounding_static_block = b; /* For elimination of dups */ - } + struct symtab_and_line sal; - /* Also catch fields of types defined in this places which match our - text string. Only complete on types visible from current context. */ - - ALL_BLOCK_SYMBOLS (b, i, sym) - { - overload_list_add_symbol (sym, oload_name); + sal = find_pc_line (prologue_sal.end, 0); + if (sal.line == 0) + break; + /* Assume that a consecutive SAL for the same (or larger) + line mark the prologue -> body transition. */ + if (sal.line >= prologue_sal.line) + break; + /* The case in which compiler's optimizer/scheduler has + moved instructions into the prologue. We look ahead in + the function looking for address ranges whose + corresponding line number is less the first one that we + found for the function. This is more conservative then + refine_prologue_limit which scans a large number of SALs + looking for any in the prologue */ + prologue_sal = sal; } } - - /* Go through the symtabs and check the externs and statics for - symbols which match. */ - - ALL_SYMTABS (objfile, s) - { - QUIT; - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); - ALL_BLOCK_SYMBOLS (b, i, sym) - { - overload_list_add_symbol (sym, oload_name); - } - } - - ALL_SYMTABS (objfile, s) - { - QUIT; - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); - /* Don't do this block twice. */ - if (b == surrounding_static_block) - continue; - ALL_BLOCK_SYMBOLS (b, i, sym) - { - overload_list_add_symbol (sym, oload_name); - } - } - - xfree (oload_name); - - return (sym_return_val); + return prologue_sal.end; } - -/* End of overload resolution functions */ struct symtabs_and_lines decode_line_spec (char *string, int funfirstline) { struct symtabs_and_lines sals; + struct symtab_and_line cursal; + if (string == 0) error ("Empty line specification."); + + /* We use whatever is set as the current source line. We do not try + and get a default or it will recursively call us! */ + cursal = get_current_source_symtab_and_line (); + sals = decode_line_1 (&string, funfirstline, - current_source_symtab, current_source_line, - (char ***) NULL); + cursal.symtab, cursal.line, + (char ***) NULL, NULL); + if (*string) error ("Junk at end of line specification: %s", string); return sals; @@ -3833,13 +4023,6 @@ _initialize_symtab (void) add_info ("types", types_info, "All type names, or those matching REGEXP."); -#if 0 - add_info ("methods", methods_info, - "All method names, or those matching REGEXP::REGEXP.\n\ -If the class qualifier is omitted, it is assumed to be the current scope.\n\ -If the first REGEXP is omitted, then all methods matching the second REGEXP\n\ -are listed."); -#endif add_info ("sources", sources_info, "Source files in the program."); diff --git a/contrib/gdb/gdb/symtab.h b/contrib/gdb/gdb/symtab.h index 5c11e75cada..5a6c3984bd1 100644 --- a/contrib/gdb/gdb/symtab.h +++ b/contrib/gdb/gdb/symtab.h @@ -1,7 +1,8 @@ /* Symbol table definitions for GDB. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -23,106 +24,147 @@ #if !defined (SYMTAB_H) #define SYMTAB_H 1 -/* Some definitions and declarations to go with use of obstacks. */ +/* Opaque declarations. */ +struct ui_file; +struct frame_info; +struct symbol; +struct obstack; +struct objfile; +struct block; +struct blockvector; +struct axs_value; +struct agent_expr; + +/* Some of the structures in this file are space critical. + The space-critical structures are: + + struct general_symbol_info + struct symbol + struct partial_symbol + + These structures are layed out to encourage good packing. + They use ENUM_BITFIELD and short int fields, and they order the + structure members so that fields less than a word are next + to each other so they can be packed together. */ + +/* Rearranged: used ENUM_BITFIELD and rearranged field order in + all the space critical structures (plus struct minimal_symbol). + Memory usage dropped from 99360768 bytes to 90001408 bytes. + I measured this with before-and-after tests of + "HEAD-old-gdb -readnow HEAD-old-gdb" and + "HEAD-new-gdb -readnow HEAD-old-gdb" on native i686-pc-linux-gnu, + red hat linux 8, with LD_LIBRARY_PATH=/usr/lib/debug, + typing "maint space 1" at the first command prompt. + + Here is another measurement (from andrew c): + # no /usr/lib/debug, just plain glibc, like a normal user + gdb HEAD-old-gdb + (gdb) break internal_error + (gdb) run + (gdb) maint internal-error + (gdb) backtrace + (gdb) maint space 1 + + gdb gdb_6_0_branch 2003-08-19 space used: 8896512 + gdb HEAD 2003-08-19 space used: 8904704 + gdb HEAD 2003-08-21 space used: 8396800 (+symtab.h) + gdb HEAD 2003-08-21 space used: 8265728 (+gdbtypes.h) + + The third line shows the savings from the optimizations in symtab.h. + The fourth line shows the savings from the optimizations in + gdbtypes.h. Both optimizations are in gdb HEAD now. + + --chastain 2003-08-21 */ -#include "obstack.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free xfree -/* Don't do this; it means that if some .o's are compiled with GNU C - and some are not (easy to do accidentally the way we configure - things; also it is a pain to have to "make clean" every time you - want to switch compilers), then GDB dies a horrible death. */ -/* GNU C supports enums that are bitfields. Some compilers don't. */ -#if 0 && defined(__GNUC__) && !defined(BYTE_BITFIELD) -#define BYTE_BITFIELD :8; -#else -#define BYTE_BITFIELD /*nothing */ -#endif /* Define a structure for the information that is common to all symbol types, including minimal symbols, partial symbols, and full symbols. In a multilanguage environment, some language specific information may need to - be recorded along with each symbol. + be recorded along with each symbol. */ - These fields are ordered to encourage good packing, since we frequently - have tens or hundreds of thousands of these. */ +/* This structure is space critical. See space comments at the top. */ struct general_symbol_info +{ + /* Name of the symbol. This is a required field. Storage for the + name is allocated on the objfile_obstack for the associated + objfile. For languages like C++ that make a distinction between + the mangled name and demangled name, this is the mangled + name. */ + + char *name; + + /* Value of the symbol. Which member of this union to use, and what + it means, depends on what kind of symbol this is and its + SYMBOL_CLASS. See comments there for more details. All of these + are in host byte order (though what they point to might be in + target byte order, e.g. LOC_CONST_BYTES). */ + + union { - /* Name of the symbol. This is a required field. Storage for the name is - allocated on the psymbol_obstack or symbol_obstack for the associated - objfile. */ + /* The fact that this is a long not a LONGEST mainly limits the + range of a LOC_CONST. Since LOC_CONST_BYTES exists, I'm not + sure that is a big deal. */ + long ivalue; - char *name; + struct block *block; - /* Value of the symbol. Which member of this union to use, and what - it means, depends on what kind of symbol this is and its - SYMBOL_CLASS. See comments there for more details. All of these - are in host byte order (though what they point to might be in - target byte order, e.g. LOC_CONST_BYTES). */ + char *bytes; - union - { - /* The fact that this is a long not a LONGEST mainly limits the - range of a LOC_CONST. Since LOC_CONST_BYTES exists, I'm not - sure that is a big deal. */ - long ivalue; + CORE_ADDR address; - struct block *block; + /* for opaque typedef struct chain */ - char *bytes; + struct symbol *chain; + } + value; - CORE_ADDR address; + /* Since one and only one language can apply, wrap the language specific + information inside a union. */ - /* for opaque typedef struct chain */ + union + { + struct cplus_specific + { + /* This is in fact used for C++, Java, and Objective C. */ + char *demangled_name; + } + cplus_specific; + } + language_specific; - struct symbol *chain; - } - value; + /* Record the source code language that applies to this symbol. + This is used to select one of the fields from the language specific + union above. */ - /* Since one and only one language can apply, wrap the language specific - information inside a union. */ + ENUM_BITFIELD(language) language : 8; - union - { - struct cplus_specific /* For C++ */ - /* and Java */ - { - char *demangled_name; - } - cplus_specific; - struct chill_specific /* For Chill */ - { - char *demangled_name; - } - chill_specific; - } - language_specific; + /* Which section is this symbol in? This is an index into + section_offsets for this objfile. Negative means that the symbol + does not get relocated relative to a section. + Disclaimer: currently this is just used for xcoff, so don't + expect all symbol-reading code to set it correctly (the ELF code + also tries to set it correctly). */ - /* Record the source code language that applies to this symbol. - This is used to select one of the fields from the language specific - union above. */ + short section; - enum language language BYTE_BITFIELD; + /* The bfd section associated with this symbol. */ - /* Which section is this symbol in? This is an index into - section_offsets for this objfile. Negative means that the symbol - does not get relocated relative to a section. - Disclaimer: currently this is just used for xcoff, so don't - expect all symbol-reading code to set it correctly (the ELF code - also tries to set it correctly). */ - - short section; - - /* The bfd section associated with this symbol. */ - - asection *bfd_section; - }; + asection *bfd_section; +}; extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *); -#define SYMBOL_NAME(symbol) (symbol)->ginfo.name +/* Note that all the following SYMBOL_* macros are used with the + SYMBOL argument being either a partial symbol, a minimal symbol or + a full symbol. All three types have a ginfo field. In particular + the SYMBOL_INIT_LANGUAGE_SPECIFIC, SYMBOL_INIT_DEMANGLED_NAME, + SYMBOL_DEMANGLED_NAME macros cannot be entirely substituted by + functions, unless the callers are changed to pass in the ginfo + field only, instead of the SYMBOL parameter. */ + +#define DEPRECATED_SYMBOL_NAME(symbol) (symbol)->ginfo.name #define SYMBOL_VALUE(symbol) (symbol)->ginfo.value.ivalue #define SYMBOL_VALUE_ADDRESS(symbol) (symbol)->ginfo.value.address #define SYMBOL_VALUE_BYTES(symbol) (symbol)->ginfo.value.bytes @@ -135,131 +177,71 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *); #define SYMBOL_CPLUS_DEMANGLED_NAME(symbol) \ (symbol)->ginfo.language_specific.cplus_specific.demangled_name -/* Macro that initializes the language dependent portion of a symbol +/* Initializes the language dependent portion of a symbol depending upon the language for the symbol. */ +#define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \ + (symbol_init_language_specific (&(symbol)->ginfo, (language))) +extern void symbol_init_language_specific (struct general_symbol_info *symbol, + enum language language); -#define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \ - do { \ - SYMBOL_LANGUAGE (symbol) = language; \ - if (SYMBOL_LANGUAGE (symbol) == language_cplus \ - || SYMBOL_LANGUAGE (symbol) == language_java \ - ) \ - { \ - SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \ - } \ - else if (SYMBOL_LANGUAGE (symbol) == language_chill) \ - { \ - SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; \ - } \ - else \ - { \ - memset (&(symbol)->ginfo.language_specific, 0, \ - sizeof ((symbol)->ginfo.language_specific)); \ - } \ - } while (0) +#define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \ + (symbol_init_demangled_name (&(symbol)->ginfo, (obstack))) +extern void symbol_init_demangled_name (struct general_symbol_info *symbol, + struct obstack *obstack); -/* Macro that attempts to initialize the demangled name for a symbol, - based on the language of that symbol. If the language is set to - language_auto, it will attempt to find any demangling algorithm - that works and then set the language appropriately. If no demangling - of any kind is found, the language is set back to language_unknown, - so we can avoid doing this work again the next time we encounter - the symbol. Any required space to store the name is obtained from the - specified obstack. */ +#define SYMBOL_SET_NAMES(symbol,linkage_name,len,objfile) \ + symbol_set_names (&(symbol)->ginfo, linkage_name, len, objfile) +extern void symbol_set_names (struct general_symbol_info *symbol, + const char *linkage_name, int len, + struct objfile *objfile); -#define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \ - do { \ - char *demangled = NULL; \ - if (SYMBOL_LANGUAGE (symbol) == language_unknown) \ - SYMBOL_LANGUAGE (symbol) = language_auto; \ - if (SYMBOL_LANGUAGE (symbol) == language_cplus \ - || SYMBOL_LANGUAGE (symbol) == language_auto) \ - { \ - demangled = \ - cplus_demangle (SYMBOL_NAME (symbol), DMGL_PARAMS | DMGL_ANSI);\ - if (demangled != NULL) \ - { \ - SYMBOL_LANGUAGE (symbol) = language_cplus; \ - SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = \ - obsavestring (demangled, strlen (demangled), (obstack)); \ - xfree (demangled); \ - } \ - else \ - { \ - SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \ - } \ - } \ - if (SYMBOL_LANGUAGE (symbol) == language_java) \ - { \ - demangled = \ - cplus_demangle (SYMBOL_NAME (symbol), \ - DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA); \ - if (demangled != NULL) \ - { \ - SYMBOL_LANGUAGE (symbol) = language_java; \ - SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = \ - obsavestring (demangled, strlen (demangled), (obstack)); \ - xfree (demangled); \ - } \ - else \ - { \ - SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \ - } \ - } \ - if (demangled == NULL \ - && (SYMBOL_LANGUAGE (symbol) == language_chill \ - || SYMBOL_LANGUAGE (symbol) == language_auto)) \ - { \ - demangled = \ - chill_demangle (SYMBOL_NAME (symbol)); \ - if (demangled != NULL) \ - { \ - SYMBOL_LANGUAGE (symbol) = language_chill; \ - SYMBOL_CHILL_DEMANGLED_NAME (symbol) = \ - obsavestring (demangled, strlen (demangled), (obstack)); \ - xfree (demangled); \ - } \ - else \ - { \ - SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; \ - } \ - } \ - } while (0) +/* Now come lots of name accessor macros. Short version as to when to + use which: Use SYMBOL_NATURAL_NAME to refer to the name of the + symbol in the original source code. Use SYMBOL_LINKAGE_NAME if you + want to know what the linker thinks the symbol's name is. Use + SYMBOL_PRINT_NAME for output. Use SYMBOL_DEMANGLED_NAME if you + specifically need to know whether SYMBOL_NATURAL_NAME and + SYMBOL_LINKAGE_NAME are different. Don't use + DEPRECATED_SYMBOL_NAME at all: instances of that macro should be + replaced by SYMBOL_NATURAL_NAME, SYMBOL_LINKAGE_NAME, or perhaps + SYMBOL_PRINT_NAME. */ -/* Macro that returns the demangled name for a symbol based on the language - for that symbol. If no demangled name exists, returns NULL. */ +/* Return SYMBOL's "natural" name, i.e. the name that it was called in + the original source code. In languages like C++ where symbols may + be mangled for ease of manipulation by the linker, this is the + demangled name. */ -#define SYMBOL_DEMANGLED_NAME(symbol) \ - (SYMBOL_LANGUAGE (symbol) == language_cplus \ - || SYMBOL_LANGUAGE (symbol) == language_java \ - ? SYMBOL_CPLUS_DEMANGLED_NAME (symbol) \ - : (SYMBOL_LANGUAGE (symbol) == language_chill \ - ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) \ - : NULL)) +#define SYMBOL_NATURAL_NAME(symbol) \ + (symbol_natural_name (&(symbol)->ginfo)) +extern char *symbol_natural_name (const struct general_symbol_info *symbol); -#define SYMBOL_CHILL_DEMANGLED_NAME(symbol) \ - (symbol)->ginfo.language_specific.chill_specific.demangled_name +/* Return SYMBOL's name from the point of view of the linker. In + languages like C++ where symbols may be mangled for ease of + manipulation by the linker, this is the mangled name; otherwise, + it's the same as SYMBOL_NATURAL_NAME. This is currently identical + to DEPRECATED_SYMBOL_NAME, but please use SYMBOL_LINKAGE_NAME when + appropriate: it conveys the additional semantic information that + you really have thought about the issue and decided that you mean + SYMBOL_LINKAGE_NAME instead of SYMBOL_NATURAL_NAME. */ -/* Macro that returns the "natural source name" of a symbol. In C++ this is - the "demangled" form of the name if demangle is on and the "mangled" form - of the name if demangle is off. In other languages this is just the - symbol name. The result should never be NULL. */ +#define SYMBOL_LINKAGE_NAME(symbol) (symbol)->ginfo.name -#define SYMBOL_SOURCE_NAME(symbol) \ - (demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - ? SYMBOL_DEMANGLED_NAME (symbol) \ - : SYMBOL_NAME (symbol)) +/* Return the demangled name for a symbol based on the language for + that symbol. If no demangled name exists, return NULL. */ +#define SYMBOL_DEMANGLED_NAME(symbol) \ + (symbol_demangled_name (&(symbol)->ginfo)) +extern char *symbol_demangled_name (struct general_symbol_info *symbol); -/* Macro that returns the "natural assembly name" of a symbol. In C++ this is - the "mangled" form of the name if demangle is off, or if demangle is on and - asm_demangle is off. Otherwise if asm_demangle is on it is the "demangled" - form. In other languages this is just the symbol name. The result should - never be NULL. */ +/* Macro that returns a version of the name of a symbol that is + suitable for output. In C++ this is the "demangled" form of the + name if demangle is on and the "mangled" form of the name if + demangle is off. In other languages this is just the symbol name. + The result should never be NULL. Don't use this for internal + purposes (e.g. storing in a hashtable): it's only suitable for + output. */ -#define SYMBOL_LINKAGE_NAME(symbol) \ - (demangle && asm_demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - ? SYMBOL_DEMANGLED_NAME (symbol) \ - : SYMBOL_NAME (symbol)) +#define SYMBOL_PRINT_NAME(symbol) \ + (demangle ? SYMBOL_NATURAL_NAME (symbol) : SYMBOL_LINKAGE_NAME (symbol)) /* Macro that tests a symbol for a match against a specified name string. First test the unencoded name, then looks for and test a C++ encoded @@ -268,20 +250,44 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *); "foo :: bar (int, long)". Evaluates to zero if the match fails, or nonzero if it succeeds. */ -#define SYMBOL_MATCHES_NAME(symbol, name) \ - (STREQ (SYMBOL_NAME (symbol), (name)) \ - || (SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - && strcmp_iw (SYMBOL_DEMANGLED_NAME (symbol), (name)) == 0)) +/* Macro that tests a symbol for a match against a specified name + string. It tests against SYMBOL_NATURAL_NAME, and it ignores + whitespace and trailing parentheses. (See strcmp_iw for details + about its behavior.) */ -/* Macro that tests a symbol for an re-match against the last compiled regular - expression. First test the unencoded name, then look for and test a C++ - encoded name if it exists. - Evaluates to zero if the match fails, or nonzero if it succeeds. */ +#define SYMBOL_MATCHES_NATURAL_NAME(symbol, name) \ + (strcmp_iw (SYMBOL_NATURAL_NAME (symbol), (name)) == 0) -#define SYMBOL_MATCHES_REGEXP(symbol) \ - (re_exec (SYMBOL_NAME (symbol)) != 0 \ - || (SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - && re_exec (SYMBOL_DEMANGLED_NAME (symbol)) != 0)) +/* Classification types for a minimal symbol. These should be taken as + "advisory only", since if gdb can't easily figure out a + classification it simply selects mst_unknown. It may also have to + guess when it can't figure out which is a better match between two + types (mst_data versus mst_bss) for example. Since the minimal + symbol info is sometimes derived from the BFD library's view of a + file, we need to live with what information bfd supplies. */ + +enum minimal_symbol_type +{ + mst_unknown = 0, /* Unknown type, the default */ + mst_text, /* Generally executable instructions */ + mst_data, /* Generally initialized data */ + mst_bss, /* Generally uninitialized data */ + mst_abs, /* Generally absolute (nonrelocatable) */ + /* GDB uses mst_solib_trampoline for the start address of a shared + library trampoline entry. Breakpoints for shared library functions + are put there if the shared library is not yet loaded. + After the shared library is loaded, lookup_minimal_symbol will + prefer the minimal symbol from the shared library (usually + a mst_text symbol) over the mst_solib_trampoline symbol, and the + breakpoints will be moved to their true address in the shared + library via breakpoint_re_set. */ + mst_solib_trampoline, /* Shared library trampoline code */ + /* For the mst_file* types, the names are only guaranteed to be unique + within a given .o file. */ + mst_file_text, /* Static version of mst_text */ + mst_file_data, /* Static version of mst_data */ + mst_file_bss /* Static version of mst_bss */ +}; /* Define a simple structure used to hold some very basic information about all defined global symbols (text, data, bss, abs, etc). The only required @@ -296,497 +302,399 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *); used to figure out what full symbol table entries need to be read in. */ struct minimal_symbol - { +{ - /* The general symbol info required for all types of symbols. + /* The general symbol info required for all types of symbols. - The SYMBOL_VALUE_ADDRESS contains the address that this symbol - corresponds to. */ + The SYMBOL_VALUE_ADDRESS contains the address that this symbol + corresponds to. */ - struct general_symbol_info ginfo; + struct general_symbol_info ginfo; - /* The info field is available for caching machine-specific information - so it doesn't have to rederive the info constantly (over a serial line). - It is initialized to zero and stays that way until target-dependent code - sets it. Storage for any data pointed to by this field should be allo- - cated on the symbol_obstack for the associated objfile. - The type would be "void *" except for reasons of compatibility with older - compilers. This field is optional. + /* The info field is available for caching machine-specific + information so it doesn't have to rederive the info constantly + (over a serial line). It is initialized to zero and stays that + way until target-dependent code sets it. Storage for any data + pointed to by this field should be allocated on the + objfile_obstack for the associated objfile. The type would be + "void *" except for reasons of compatibility with older + compilers. This field is optional. - Currently, the AMD 29000 tdep.c uses it to remember things it has decoded - from the instructions in the function header, and the MIPS-16 code uses - it to identify 16-bit procedures. */ + Currently, the AMD 29000 tdep.c uses it to remember things it has decoded + from the instructions in the function header, and the MIPS-16 code uses + it to identify 16-bit procedures. */ - char *info; + char *info; + + /* Size of this symbol. end_psymtab in dbxread.c uses this + information to calculate the end of the partial symtab based on the + address of the last symbol plus the size of the last symbol. */ + + unsigned long size; #ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* Which source file is this symbol in? Only relevant for mst_file_*. */ - char *filename; + /* Which source file is this symbol in? Only relevant for mst_file_*. */ + char *filename; #endif - /* Classification types for this symbol. These should be taken as "advisory - only", since if gdb can't easily figure out a classification it simply - selects mst_unknown. It may also have to guess when it can't figure out - which is a better match between two types (mst_data versus mst_bss) for - example. Since the minimal symbol info is sometimes derived from the - BFD library's view of a file, we need to live with what information bfd - supplies. */ + /* Classification type for this minimal symbol. */ - enum minimal_symbol_type - { - mst_unknown = 0, /* Unknown type, the default */ - mst_text, /* Generally executable instructions */ - mst_data, /* Generally initialized data */ - mst_bss, /* Generally uninitialized data */ - mst_abs, /* Generally absolute (nonrelocatable) */ - /* GDB uses mst_solib_trampoline for the start address of a shared - library trampoline entry. Breakpoints for shared library functions - are put there if the shared library is not yet loaded. - After the shared library is loaded, lookup_minimal_symbol will - prefer the minimal symbol from the shared library (usually - a mst_text symbol) over the mst_solib_trampoline symbol, and the - breakpoints will be moved to their true address in the shared - library via breakpoint_re_set. */ - mst_solib_trampoline, /* Shared library trampoline code */ - /* For the mst_file* types, the names are only guaranteed to be unique - within a given .o file. */ - mst_file_text, /* Static version of mst_text */ - mst_file_data, /* Static version of mst_data */ - mst_file_bss /* Static version of mst_bss */ - } - type BYTE_BITFIELD; + ENUM_BITFIELD(minimal_symbol_type) type : 8; - /* Minimal symbols with the same hash key are kept on a linked - list. This is the link. */ + /* Minimal symbols with the same hash key are kept on a linked + list. This is the link. */ - struct minimal_symbol *hash_next; + struct minimal_symbol *hash_next; - /* Minimal symbols are stored in two different hash tables. This is - the `next' pointer for the demangled hash table. */ + /* Minimal symbols are stored in two different hash tables. This is + the `next' pointer for the demangled hash table. */ - struct minimal_symbol *demangled_hash_next; - }; + struct minimal_symbol *demangled_hash_next; +}; #define MSYMBOL_INFO(msymbol) (msymbol)->info +#define MSYMBOL_SIZE(msymbol) (msymbol)->size #define MSYMBOL_TYPE(msymbol) (msymbol)->type -/* All of the name-scope contours of the program - are represented by `struct block' objects. - All of these objects are pointed to by the blockvector. - - Each block represents one name scope. - Each lexical context has its own block. - - The blockvector begins with some special blocks. - The GLOBAL_BLOCK contains all the symbols defined in this compilation - whose scope is the entire program linked together. - The STATIC_BLOCK contains all the symbols whose scope is the - entire compilation excluding other separate compilations. - Blocks starting with the FIRST_LOCAL_BLOCK are not special. - - Each block records a range of core addresses for the code that - is in the scope of the block. The STATIC_BLOCK and GLOBAL_BLOCK - give, for the range of code, the entire range of code produced - by the compilation that the symbol segment belongs to. - - The blocks appear in the blockvector - in order of increasing starting-address, - and, within that, in order of decreasing ending-address. - - This implies that within the body of one function - the blocks appear in the order of a depth-first tree walk. */ - -struct blockvector - { - /* Number of blocks in the list. */ - int nblocks; - /* The blocks themselves. */ - struct block *block[1]; - }; - -#define BLOCKVECTOR_NBLOCKS(blocklist) (blocklist)->nblocks -#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n] - -/* Special block numbers */ - -#define GLOBAL_BLOCK 0 -#define STATIC_BLOCK 1 -#define FIRST_LOCAL_BLOCK 2 - -struct block - { - - /* Addresses in the executable code that are in this block. */ - - CORE_ADDR startaddr; - CORE_ADDR endaddr; - - /* The symbol that names this block, if the block is the body of a - function; otherwise, zero. */ - - struct symbol *function; - - /* The `struct block' for the containing block, or 0 if none. - - The superblock of a top-level local block (i.e. a function in the - case of C) is the STATIC_BLOCK. The superblock of the - STATIC_BLOCK is the GLOBAL_BLOCK. */ - - struct block *superblock; - - /* Version of GCC used to compile the function corresponding - to this block, or 0 if not compiled with GCC. When possible, - GCC should be compatible with the native compiler, or if that - is not feasible, the differences should be fixed during symbol - reading. As of 16 Apr 93, this flag is never used to distinguish - between gcc2 and the native compiler. - - If there is no function corresponding to this block, this meaning - of this flag is undefined. */ - - unsigned char gcc_compile_flag; - - /* Number of local symbols. */ - - int nsyms; - - /* The symbols. If some of them are arguments, then they must be - in the order in which we would like to print them. */ - - struct symbol *sym[1]; - }; - -#define BLOCK_START(bl) (bl)->startaddr -#define BLOCK_END(bl) (bl)->endaddr -#define BLOCK_NSYMS(bl) (bl)->nsyms -#define BLOCK_SYM(bl, n) (bl)->sym[n] -#define BLOCK_FUNCTION(bl) (bl)->function -#define BLOCK_SUPERBLOCK(bl) (bl)->superblock -#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag - -/* Macro to loop through all symbols in a block BL. - i counts which symbol we are looking at, and sym points to the current - symbol. */ -#define ALL_BLOCK_SYMBOLS(bl, i, sym) \ - for ((i) = 0, (sym) = BLOCK_SYM ((bl), (i)); \ - (i) < BLOCK_NSYMS ((bl)); \ - ++(i), (sym) = BLOCK_SYM ((bl), (i))) - -/* Nonzero if symbols of block BL should be sorted alphabetically. - Don't sort a block which corresponds to a function. If we did the - sorting would have to preserve the order of the symbols for the - arguments. */ - -#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40 && BLOCK_FUNCTION (bl) == NULL) - - /* Represent one symbol name; a variable, constant, function or typedef. */ -/* Different name spaces for symbols. Looking up a symbol specifies a - namespace and ignores symbol definitions in other name spaces. */ +/* Different name domains for symbols. Looking up a symbol specifies a + domain and ignores symbol definitions in other name domains. */ -typedef enum - { - /* UNDEF_NAMESPACE is used when a namespace has not been discovered or - none of the following apply. This usually indicates an error either - in the symbol information or in gdb's handling of symbols. */ +typedef enum domain_enum_tag +{ + /* UNDEF_DOMAIN is used when a domain has not been discovered or + none of the following apply. This usually indicates an error either + in the symbol information or in gdb's handling of symbols. */ - UNDEF_NAMESPACE, + UNDEF_DOMAIN, - /* VAR_NAMESPACE is the usual namespace. In C, this contains variables, - function names, typedef names and enum type values. */ + /* VAR_DOMAIN is the usual domain. In C, this contains variables, + function names, typedef names and enum type values. */ - VAR_NAMESPACE, + VAR_DOMAIN, - /* STRUCT_NAMESPACE is used in C to hold struct, union and enum type names. - Thus, if `struct foo' is used in a C program, it produces a symbol named - `foo' in the STRUCT_NAMESPACE. */ + /* STRUCT_DOMAIN is used in C to hold struct, union and enum type names. + Thus, if `struct foo' is used in a C program, it produces a symbol named + `foo' in the STRUCT_DOMAIN. */ - STRUCT_NAMESPACE, + STRUCT_DOMAIN, - /* LABEL_NAMESPACE may be used for names of labels (for gotos); - currently it is not used and labels are not recorded at all. */ + /* LABEL_DOMAIN may be used for names of labels (for gotos); + currently it is not used and labels are not recorded at all. */ - LABEL_NAMESPACE, + LABEL_DOMAIN, - /* Searching namespaces. These overlap with VAR_NAMESPACE, providing - some granularity with the search_symbols function. */ + /* Searching domains. These overlap with VAR_DOMAIN, providing + some granularity with the search_symbols function. */ - /* Everything in VAR_NAMESPACE minus FUNCTIONS_-, TYPES_-, and - METHODS_NAMESPACE */ - VARIABLES_NAMESPACE, + /* Everything in VAR_DOMAIN minus FUNCTIONS_-, TYPES_-, and + METHODS_DOMAIN */ + VARIABLES_DOMAIN, - /* All functions -- for some reason not methods, though. */ - FUNCTIONS_NAMESPACE, + /* All functions -- for some reason not methods, though. */ + FUNCTIONS_DOMAIN, - /* All defined types */ - TYPES_NAMESPACE, + /* All defined types */ + TYPES_DOMAIN, - /* All class methods -- why is this separated out? */ - METHODS_NAMESPACE - - } -namespace_enum; + /* All class methods -- why is this separated out? */ + METHODS_DOMAIN +} +domain_enum; /* An address-class says where to find the value of a symbol. */ enum address_class - { - /* Not used; catches errors */ +{ + /* Not used; catches errors */ - LOC_UNDEF, + LOC_UNDEF, - /* Value is constant int SYMBOL_VALUE, host byteorder */ + /* Value is constant int SYMBOL_VALUE, host byteorder */ - LOC_CONST, + LOC_CONST, - /* Value is at fixed address SYMBOL_VALUE_ADDRESS */ + /* Value is at fixed address SYMBOL_VALUE_ADDRESS */ - LOC_STATIC, + LOC_STATIC, - /* Value is in register. SYMBOL_VALUE is the register number. */ + /* Value is in register. SYMBOL_VALUE is the register number. */ - LOC_REGISTER, + LOC_REGISTER, - /* It's an argument; the value is at SYMBOL_VALUE offset in arglist. */ + /* It's an argument; the value is at SYMBOL_VALUE offset in arglist. */ - LOC_ARG, + LOC_ARG, - /* Value address is at SYMBOL_VALUE offset in arglist. */ + /* Value address is at SYMBOL_VALUE offset in arglist. */ - LOC_REF_ARG, + LOC_REF_ARG, - /* Value is in register number SYMBOL_VALUE. Just like LOC_REGISTER - except this is an argument. Probably the cleaner way to handle - this would be to separate address_class (which would include - separate ARG and LOCAL to deal with FRAME_ARGS_ADDRESS versus - FRAME_LOCALS_ADDRESS), and an is_argument flag. + /* Value is in register number SYMBOL_VALUE. Just like LOC_REGISTER + except this is an argument. Probably the cleaner way to handle + this would be to separate address_class (which would include + separate ARG and LOCAL to deal with the frame's arguments + (get_frame_args_address) versus the frame's locals + (get_frame_locals_address), and an is_argument flag. - For some symbol formats (stabs, for some compilers at least), - the compiler generates two symbols, an argument and a register. - In some cases we combine them to a single LOC_REGPARM in symbol - reading, but currently not for all cases (e.g. it's passed on the - stack and then loaded into a register). */ + For some symbol formats (stabs, for some compilers at least), + the compiler generates two symbols, an argument and a register. + In some cases we combine them to a single LOC_REGPARM in symbol + reading, but currently not for all cases (e.g. it's passed on the + stack and then loaded into a register). */ - LOC_REGPARM, + LOC_REGPARM, - /* Value is in specified register. Just like LOC_REGPARM except the - register holds the address of the argument instead of the argument - itself. This is currently used for the passing of structs and unions - on sparc and hppa. It is also used for call by reference where the - address is in a register, at least by mipsread.c. */ + /* Value is in specified register. Just like LOC_REGPARM except the + register holds the address of the argument instead of the argument + itself. This is currently used for the passing of structs and unions + on sparc and hppa. It is also used for call by reference where the + address is in a register, at least by mipsread.c. */ - LOC_REGPARM_ADDR, + LOC_REGPARM_ADDR, - /* Value is a local variable at SYMBOL_VALUE offset in stack frame. */ + /* Value is a local variable at SYMBOL_VALUE offset in stack frame. */ - LOC_LOCAL, + LOC_LOCAL, - /* Value not used; definition in SYMBOL_TYPE. Symbols in the namespace - STRUCT_NAMESPACE all have this class. */ + /* Value not used; definition in SYMBOL_TYPE. Symbols in the domain + STRUCT_DOMAIN all have this class. */ - LOC_TYPEDEF, + LOC_TYPEDEF, - /* Value is address SYMBOL_VALUE_ADDRESS in the code */ + /* Value is address SYMBOL_VALUE_ADDRESS in the code */ - LOC_LABEL, + LOC_LABEL, - /* In a symbol table, value is SYMBOL_BLOCK_VALUE of a `struct block'. - In a partial symbol table, SYMBOL_VALUE_ADDRESS is the start address - of the block. Function names have this class. */ + /* In a symbol table, value is SYMBOL_BLOCK_VALUE of a `struct block'. + In a partial symbol table, SYMBOL_VALUE_ADDRESS is the start address + of the block. Function names have this class. */ - LOC_BLOCK, + LOC_BLOCK, - /* Value is a constant byte-sequence pointed to by SYMBOL_VALUE_BYTES, in - target byte order. */ + /* Value is a constant byte-sequence pointed to by SYMBOL_VALUE_BYTES, in + target byte order. */ - LOC_CONST_BYTES, + LOC_CONST_BYTES, - /* Value is arg at SYMBOL_VALUE offset in stack frame. Differs from - LOC_LOCAL in that symbol is an argument; differs from LOC_ARG in - that we find it in the frame (FRAME_LOCALS_ADDRESS), not in the - arglist (FRAME_ARGS_ADDRESS). Added for i960, which passes args - in regs then copies to frame. */ + /* Value is arg at SYMBOL_VALUE offset in stack frame. Differs from + LOC_LOCAL in that symbol is an argument; differs from LOC_ARG in + that we find it in the frame (get_frame_locals_address), not in + the arglist (get_frame_args_address). Added for i960, which + passes args in regs then copies to frame. */ - LOC_LOCAL_ARG, + LOC_LOCAL_ARG, - /* Value is at SYMBOL_VALUE offset from the current value of - register number SYMBOL_BASEREG. This exists mainly for the same - things that LOC_LOCAL and LOC_ARG do; but we need to do this - instead because on 88k DWARF gives us the offset from the - frame/stack pointer, rather than the offset from the "canonical - frame address" used by COFF, stabs, etc., and we don't know how - to convert between these until we start examining prologues. + /* Value is at SYMBOL_VALUE offset from the current value of + register number SYMBOL_BASEREG. This exists mainly for the same + things that LOC_LOCAL and LOC_ARG do; but we need to do this + instead because on 88k DWARF gives us the offset from the + frame/stack pointer, rather than the offset from the "canonical + frame address" used by COFF, stabs, etc., and we don't know how + to convert between these until we start examining prologues. - Note that LOC_BASEREG is much less general than a DWARF expression. - We don't need the generality (at least not yet), and storing a general - DWARF expression would presumably take up more space than the existing - scheme. */ + Note that LOC_BASEREG is much less general than a DWARF expression. + We don't need the generality (at least not yet), and storing a general + DWARF expression would presumably take up more space than the existing + scheme. */ - LOC_BASEREG, + LOC_BASEREG, - /* Same as LOC_BASEREG but it is an argument. */ + /* Same as LOC_BASEREG but it is an argument. */ - LOC_BASEREG_ARG, + LOC_BASEREG_ARG, - /* Value is at fixed address, but the address of the variable has - to be determined from the minimal symbol table whenever the - variable is referenced. - This happens if debugging information for a global symbol is - emitted and the corresponding minimal symbol is defined - in another object file or runtime common storage. - The linker might even remove the minimal symbol if the global - symbol is never referenced, in which case the symbol remains - unresolved. */ + /* Value is at fixed address, but the address of the variable has + to be determined from the minimal symbol table whenever the + variable is referenced. + This happens if debugging information for a global symbol is + emitted and the corresponding minimal symbol is defined + in another object file or runtime common storage. + The linker might even remove the minimal symbol if the global + symbol is never referenced, in which case the symbol remains + unresolved. */ - LOC_UNRESOLVED, + LOC_UNRESOLVED, - /* Value is at a thread-specific location calculated by a - target-specific method. */ + /* Value is at a thread-specific location calculated by a + target-specific method. This is used only by hppa. */ - LOC_THREAD_LOCAL_STATIC, + LOC_HP_THREAD_LOCAL_STATIC, - /* The variable does not actually exist in the program. - The value is ignored. */ + /* The variable does not actually exist in the program. + The value is ignored. */ - LOC_OPTIMIZED_OUT, + LOC_OPTIMIZED_OUT, - /* The variable is static, but actually lives at * (address). - * I.e. do an extra indirection to get to it. - * This is used on HP-UX to get at globals that are allocated - * in shared libraries, where references from images other - * than the one where the global was allocated are done - * with a level of indirection. - */ + /* The variable is static, but actually lives at * (address). + * I.e. do an extra indirection to get to it. + * This is used on HP-UX to get at globals that are allocated + * in shared libraries, where references from images other + * than the one where the global was allocated are done + * with a level of indirection. + */ - LOC_INDIRECT + LOC_INDIRECT, - }; + /* The variable's address is computed by a set of location + functions (see "struct location_funcs" below). */ + LOC_COMPUTED, -/* Linked list of symbol's live ranges. */ + /* Same as LOC_COMPUTED, but for function arguments. */ + LOC_COMPUTED_ARG +}; -struct range_list - { - CORE_ADDR start; - CORE_ADDR end; - struct range_list *next; - }; +/* The methods needed to implement a symbol class. These methods can + use the symbol's .aux_value for additional per-symbol information. -/* Linked list of aliases for a particular main/primary symbol. */ -struct alias_list - { - struct symbol *sym; - struct alias_list *next; - }; + At present this is only used to implement location expressions. */ + +struct symbol_ops +{ + + /* Return the value of the variable SYMBOL, relative to the stack + frame FRAME. If the variable has been optimized out, return + zero. + + Iff `read_needs_frame (SYMBOL)' is zero, then FRAME may be zero. */ + + struct value *(*read_variable) (struct symbol * symbol, + struct frame_info * frame); + + /* Return non-zero if we need a frame to find the value of the SYMBOL. */ + int (*read_needs_frame) (struct symbol * symbol); + + /* Write to STREAM a natural-language description of the location of + SYMBOL. */ + int (*describe_location) (struct symbol * symbol, struct ui_file * stream); + + /* Tracepoint support. Append bytecodes to the tracepoint agent + expression AX that push the address of the object SYMBOL. Set + VALUE appropriately. Note --- for objects in registers, this + needn't emit any code; as long as it sets VALUE properly, then + the caller will generate the right code in the process of + treating this as an lvalue or rvalue. */ + + void (*tracepoint_var_ref) (struct symbol * symbol, struct agent_expr * ax, + struct axs_value * value); +}; + +/* This structure is space critical. See space comments at the top. */ struct symbol +{ + + /* The general symbol info required for all types of symbols. */ + + struct general_symbol_info ginfo; + + /* Data type of value */ + + struct type *type; + + /* Domain code. */ + + ENUM_BITFIELD(domain_enum_tag) domain : 6; + + /* Address class */ + /* NOTE: cagney/2003-11-02: The fields "aclass" and "ops" contain + overlapping information. By creating a per-aclass ops vector, or + using the aclass as an index into an ops table, the aclass and + ops fields can be merged. The latter, for instance, would shave + 32-bits from each symbol (relative to a symbol lookup, any table + index overhead would be in the noise). */ + + ENUM_BITFIELD(address_class) aclass : 6; + + /* Line number of definition. FIXME: Should we really make the assumption + that nobody will try to debug files longer than 64K lines? What about + machine generated programs? */ + + unsigned short line; + + /* Method's for symbol's of this class. */ + /* NOTE: cagney/2003-11-02: See comment above attached to "aclass". */ + + const struct symbol_ops *ops; + + /* Some symbols require additional information to be recorded on a + per- symbol basis. Stash those values here. */ + + union { + /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */ + short basereg; + /* An arbitrary data pointer. Note that this data must be + allocated using the same obstack as the symbol itself. */ + /* So far it is only used by LOC_COMPUTED and LOC_COMPUTED_ARG to + find the location location information. For a LOC_BLOCK symbol + for a function in a compilation unit compiled with DWARF 2 + information, this is information used internally by the DWARF 2 + code --- specifically, the location expression for the frame + base for this function. */ + /* FIXME drow/2003-02-21: For the LOC_BLOCK case, it might be better + to add a magic symbol to the block containing this information, + or to have a generic debug info annotation slot for symbols. */ + void *ptr; + } + aux_value; - /* The general symbol info required for all types of symbols. */ - - struct general_symbol_info ginfo; - - /* Data type of value */ - - struct type *type; - - /* Name space code. */ - -#ifdef __MFC4__ - /* FIXME: don't conflict with C++'s namespace */ - /* would be safer to do a global change for all namespace identifiers. */ -#define namespace _namespace -#endif - namespace_enum namespace BYTE_BITFIELD; - - /* Address class */ - - enum address_class aclass BYTE_BITFIELD; - - /* Line number of definition. FIXME: Should we really make the assumption - that nobody will try to debug files longer than 64K lines? What about - machine generated programs? */ - - unsigned short line; - - /* Some symbols require an additional value to be recorded on a per- - symbol basis. Stash those values here. */ - - union - { - /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */ - short basereg; - } - aux_value; + struct symbol *hash_next; +}; - /* Link to a list of aliases for this symbol. - Only a "primary/main symbol may have aliases. */ - struct alias_list *aliases; - - /* List of ranges where this symbol is active. This is only - used by alias symbols at the current time. */ - struct range_list *ranges; - }; - - -#define SYMBOL_NAMESPACE(symbol) (symbol)->namespace +#define SYMBOL_DOMAIN(symbol) (symbol)->domain #define SYMBOL_CLASS(symbol) (symbol)->aclass #define SYMBOL_TYPE(symbol) (symbol)->type #define SYMBOL_LINE(symbol) (symbol)->line #define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg -#define SYMBOL_ALIASES(symbol) (symbol)->aliases -#define SYMBOL_RANGES(symbol) (symbol)->ranges +#define SYMBOL_OBJFILE(symbol) (symbol)->aux_value.objfile +#define SYMBOL_OPS(symbol) (symbol)->ops +#define SYMBOL_LOCATION_BATON(symbol) (symbol)->aux_value.ptr -/* A partial_symbol records the name, namespace, and address class of +/* A partial_symbol records the name, domain, and address class of symbols whose types we have not parsed yet. For functions, it also contains their memory address, so we can find them from a PC value. Each partial_symbol sits in a partial_symtab, all of which are chained on a partial symtab list and which points to the corresponding normal symtab once the partial_symtab has been referenced. */ +/* This structure is space critical. See space comments at the top. */ + struct partial_symbol - { +{ - /* The general symbol info required for all types of symbols. */ + /* The general symbol info required for all types of symbols. */ - struct general_symbol_info ginfo; + struct general_symbol_info ginfo; - /* Name space code. */ + /* Name space code. */ - namespace_enum namespace BYTE_BITFIELD; + ENUM_BITFIELD(domain_enum_tag) domain : 6; - /* Address class (for info_symbols) */ + /* Address class (for info_symbols) */ - enum address_class aclass BYTE_BITFIELD; + ENUM_BITFIELD(address_class) aclass : 6; - }; +}; -#define PSYMBOL_NAMESPACE(psymbol) (psymbol)->namespace +#define PSYMBOL_DOMAIN(psymbol) (psymbol)->domain #define PSYMBOL_CLASS(psymbol) (psymbol)->aclass -/* Source-file information. This describes the relation between source files, - line numbers and addresses in the program text. */ - -struct sourcevector - { - int length; /* Number of source files described */ - struct source *source[1]; /* Descriptions of the files */ - }; - /* Each item represents a line-->pc (or the reverse) mapping. This is somewhat more wasteful of space than one might wish, but since only the files which are actually debugged are read in to core, we don't waste much space. */ struct linetable_entry - { - int line; - CORE_ADDR pc; - }; +{ + int line; + CORE_ADDR pc; +}; /* The order of entries in the linetable is significant. They should be sorted by increasing values of the pc field. If there is more than @@ -806,22 +714,14 @@ struct linetable_entry zero length. */ struct linetable - { - int nitems; +{ + int nitems; - /* Actually NITEMS elements. If you don't like this use of the - `struct hack', you can shove it up your ANSI (seriously, if the - committee tells us how to do it, we can probably go along). */ - struct linetable_entry item[1]; - }; - -/* All the information on one source file. */ - -struct source - { - char *name; /* Name of file */ - struct linetable contents; - }; + /* Actually NITEMS elements. If you don't like this use of the + `struct hack', you can shove it up your ANSI (seriously, if the + committee tells us how to do it, we can probably go along). */ + struct linetable_entry item[1]; +}; /* How to relocate the symbols from each section in a symbol file. Each struct contains an array of offsets. @@ -834,114 +734,118 @@ struct source extract offset values in the struct. */ struct section_offsets - { - CORE_ADDR offsets[1]; /* As many as needed. */ - }; +{ + CORE_ADDR offsets[1]; /* As many as needed. */ +}; #define ANOFFSET(secoff, whichone) \ ((whichone == -1) \ ? (internal_error (__FILE__, __LINE__, "Section index is uninitialized"), -1) \ : secoff->offsets[whichone]) -/* The maximum possible size of a section_offsets table. */ - -#define SIZEOF_SECTION_OFFSETS \ +/* The size of a section_offsets table for N sections. */ +#define SIZEOF_N_SECTION_OFFSETS(n) \ (sizeof (struct section_offsets) \ - + sizeof (((struct section_offsets *) 0)->offsets) * (SECT_OFF_MAX-1)) + + sizeof (((struct section_offsets *) 0)->offsets) * ((n)-1)) /* Each source file or header is represented by a struct symtab. These objects are chained through the `next' field. */ struct symtab +{ + + /* Chain of all existing symtabs. */ + + struct symtab *next; + + /* List of all symbol scope blocks for this symtab. May be shared + between different symtabs (and normally is for all the symtabs + in a given compilation unit). */ + + struct blockvector *blockvector; + + /* Table mapping core addresses to line numbers for this file. + Can be NULL if none. Never shared between different symtabs. */ + + struct linetable *linetable; + + /* Section in objfile->section_offsets for the blockvector and + the linetable. Probably always SECT_OFF_TEXT. */ + + int block_line_section; + + /* If several symtabs share a blockvector, exactly one of them + should be designated the primary, so that the blockvector + is relocated exactly once by objfile_relocate. */ + + int primary; + + /* The macro table for this symtab. Like the blockvector, this + may be shared between different symtabs --- and normally is for + all the symtabs in a given compilation unit. */ + struct macro_table *macro_table; + + /* Name of this source file. */ + + char *filename; + + /* Directory in which it was compiled, or NULL if we don't know. */ + + char *dirname; + + /* This component says how to free the data we point to: + free_contents => do a tree walk and free each object. + free_nothing => do nothing; some other symtab will free + the data this one uses. + free_linetable => free just the linetable. FIXME: Is this redundant + with the primary field? */ + + enum free_code { + free_nothing, free_contents, free_linetable + } + free_code; - /* Chain of all existing symtabs. */ + /* A function to call to free space, if necessary. This is IN + ADDITION to the action indicated by free_code. */ - struct symtab *next; + void (*free_func)(struct symtab *symtab); - /* List of all symbol scope blocks for this symtab. May be shared - between different symtabs (and normally is for all the symtabs - in a given compilation unit). */ + /* Total number of lines found in source file. */ - struct blockvector *blockvector; + int nlines; - /* Table mapping core addresses to line numbers for this file. - Can be NULL if none. Never shared between different symtabs. */ + /* line_charpos[N] is the position of the (N-1)th line of the + source file. "position" means something we can lseek() to; it + is not guaranteed to be useful any other way. */ - struct linetable *linetable; + int *line_charpos; - /* Section in objfile->section_offsets for the blockvector and - the linetable. Probably always SECT_OFF_TEXT. */ + /* Language of this source file. */ - int block_line_section; + enum language language; - /* If several symtabs share a blockvector, exactly one of them - should be designated the primary, so that the blockvector - is relocated exactly once by objfile_relocate. */ + /* String that identifies the format of the debugging information, such + as "stabs", "dwarf 1", "dwarf 2", "coff", etc. This is mostly useful + for automated testing of gdb but may also be information that is + useful to the user. */ - int primary; + char *debugformat; - /* Name of this source file. */ + /* String of version information. May be zero. */ - char *filename; + char *version; - /* Directory in which it was compiled, or NULL if we don't know. */ + /* Full name of file as found by searching the source path. + NULL if not yet known. */ - char *dirname; + char *fullname; - /* This component says how to free the data we point to: - free_contents => do a tree walk and free each object. - free_nothing => do nothing; some other symtab will free - the data this one uses. - free_linetable => free just the linetable. FIXME: Is this redundant - with the primary field? */ + /* Object file from which this symbol information was read. */ - enum free_code - { - free_nothing, free_contents, free_linetable - } - free_code; + struct objfile *objfile; - /* Pointer to one block of storage to be freed, if nonzero. */ - /* This is IN ADDITION to the action indicated by free_code. */ - - char *free_ptr; - - /* Total number of lines found in source file. */ - - int nlines; - - /* line_charpos[N] is the position of the (N-1)th line of the - source file. "position" means something we can lseek() to; it - is not guaranteed to be useful any other way. */ - - int *line_charpos; - - /* Language of this source file. */ - - enum language language; - - /* String that identifies the format of the debugging information, such - as "stabs", "dwarf 1", "dwarf 2", "coff", etc. This is mostly useful - for automated testing of gdb but may also be information that is - useful to the user. */ - - char *debugformat; - - /* String of version information. May be zero. */ - - char *version; - - /* Full name of file as found by searching the source path. - NULL if not yet known. */ - - char *fullname; - - /* Object file from which this symbol information was read. */ - - struct objfile *objfile; - - }; +}; #define BLOCKVECTOR(symtab) (symtab)->blockvector #define LINETABLE(symtab) (symtab)->linetable @@ -955,92 +859,92 @@ struct symtab Even after the source file has been read into a symtab, the partial_symtab remains around. They are allocated on an obstack, - psymbol_obstack. FIXME, this is bad for dynamic linking or VxWorks- + objfile_obstack. FIXME, this is bad for dynamic linking or VxWorks- style execution of a bunch of .o's. */ struct partial_symtab - { +{ - /* Chain of all existing partial symtabs. */ + /* Chain of all existing partial symtabs. */ - struct partial_symtab *next; + struct partial_symtab *next; - /* Name of the source file which this partial_symtab defines */ + /* Name of the source file which this partial_symtab defines */ - char *filename; + char *filename; - /* Full path of the source file. NULL if not known. */ + /* Full path of the source file. NULL if not known. */ - char *fullname; + char *fullname; - /* Information about the object file from which symbols should be read. */ + /* Information about the object file from which symbols should be read. */ - struct objfile *objfile; + struct objfile *objfile; - /* Set of relocation offsets to apply to each section. */ + /* Set of relocation offsets to apply to each section. */ - struct section_offsets *section_offsets; + struct section_offsets *section_offsets; - /* Range of text addresses covered by this file; texthigh is the - beginning of the next section. */ + /* Range of text addresses covered by this file; texthigh is the + beginning of the next section. */ - CORE_ADDR textlow; - CORE_ADDR texthigh; + CORE_ADDR textlow; + CORE_ADDR texthigh; - /* Array of pointers to all of the partial_symtab's which this one - depends on. Since this array can only be set to previous or - the current (?) psymtab, this dependency tree is guaranteed not - to have any loops. "depends on" means that symbols must be read - for the dependencies before being read for this psymtab; this is - for type references in stabs, where if foo.c includes foo.h, declarations - in foo.h may use type numbers defined in foo.c. For other debugging - formats there may be no need to use dependencies. */ + /* Array of pointers to all of the partial_symtab's which this one + depends on. Since this array can only be set to previous or + the current (?) psymtab, this dependency tree is guaranteed not + to have any loops. "depends on" means that symbols must be read + for the dependencies before being read for this psymtab; this is + for type references in stabs, where if foo.c includes foo.h, declarations + in foo.h may use type numbers defined in foo.c. For other debugging + formats there may be no need to use dependencies. */ - struct partial_symtab **dependencies; + struct partial_symtab **dependencies; - int number_of_dependencies; + int number_of_dependencies; - /* Global symbol list. This list will be sorted after readin to - improve access. Binary search will be the usual method of - finding a symbol within it. globals_offset is an integer offset - within global_psymbols[]. */ + /* Global symbol list. This list will be sorted after readin to + improve access. Binary search will be the usual method of + finding a symbol within it. globals_offset is an integer offset + within global_psymbols[]. */ - int globals_offset; - int n_global_syms; + int globals_offset; + int n_global_syms; - /* Static symbol list. This list will *not* be sorted after readin; - to find a symbol in it, exhaustive search must be used. This is - reasonable because searches through this list will eventually - lead to either the read in of a files symbols for real (assumed - to take a *lot* of time; check) or an error (and we don't care - how long errors take). This is an offset and size within - static_psymbols[]. */ + /* Static symbol list. This list will *not* be sorted after readin; + to find a symbol in it, exhaustive search must be used. This is + reasonable because searches through this list will eventually + lead to either the read in of a files symbols for real (assumed + to take a *lot* of time; check) or an error (and we don't care + how long errors take). This is an offset and size within + static_psymbols[]. */ - int statics_offset; - int n_static_syms; + int statics_offset; + int n_static_syms; - /* Pointer to symtab eventually allocated for this source file, 0 if - !readin or if we haven't looked for the symtab after it was readin. */ + /* Pointer to symtab eventually allocated for this source file, 0 if + !readin or if we haven't looked for the symtab after it was readin. */ - struct symtab *symtab; + struct symtab *symtab; - /* Pointer to function which will read in the symtab corresponding to - this psymtab. */ + /* Pointer to function which will read in the symtab corresponding to + this psymtab. */ - void (*read_symtab) (struct partial_symtab *); + void (*read_symtab) (struct partial_symtab *); - /* Information that lets read_symtab() locate the part of the symbol table - that this psymtab corresponds to. This information is private to the - format-dependent symbol reading routines. For further detail examine - the various symbol reading modules. Should really be (void *) but is - (char *) as with other such gdb variables. (FIXME) */ + /* Information that lets read_symtab() locate the part of the symbol table + that this psymtab corresponds to. This information is private to the + format-dependent symbol reading routines. For further detail examine + the various symbol reading modules. Should really be (void *) but is + (char *) as with other such gdb variables. (FIXME) */ - char *read_symtab_private; + char *read_symtab_private; - /* Non-zero if the symtab corresponding to this psymtab has been readin */ + /* Non-zero if the symtab corresponding to this psymtab has been readin */ - unsigned char readin; - }; + unsigned char readin; +}; /* A fast way to get from a psymtab to its symtab (after the first time). */ #define PSYMTAB_TO_SYMTAB(pst) \ @@ -1062,14 +966,6 @@ struct partial_symtab /* External variables and functions for the objects described above. */ -/* This symtab variable specifies the current file for printing source lines */ - -extern struct symtab *current_source_symtab; - -/* This is the next line to print for listing source lines. */ - -extern int current_source_line; - /* See the comment in symfile.c about how current_objfile is used. */ extern struct objfile *current_objfile; @@ -1091,13 +987,60 @@ extern struct symtab *lookup_symtab (const char *); /* lookup a symbol by name (optional block, optional symtab) */ extern struct symbol *lookup_symbol (const char *, const struct block *, - const namespace_enum, int *, + const domain_enum, int *, struct symtab **); +/* A default version of lookup_symbol_nonlocal for use by languages + that can't think of anything better to do. */ + +extern struct symbol *basic_lookup_symbol_nonlocal (const char *, + const char *, + const struct block *, + const domain_enum, + struct symtab **); + +/* Some helper functions for languages that need to write their own + lookup_symbol_nonlocal functions. */ + +/* Lookup a symbol in the static block associated to BLOCK, if there + is one; do nothing if BLOCK is NULL or a global block. */ + +extern struct symbol *lookup_symbol_static (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab); + +/* Lookup a symbol in all files' global blocks (searching psymtabs if + necessary). */ + +extern struct symbol *lookup_symbol_global (const char *name, + const char *linkage_name, + const domain_enum domain, + struct symtab **symtab); + +/* Lookup a symbol within the block BLOCK. This, unlike + lookup_symbol_block, will set SYMTAB and BLOCK_FOUND correctly, and + will fix up the symbol if necessary. */ + +extern struct symbol *lookup_symbol_aux_block (const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + struct symtab **symtab); + +/* Lookup a partial symbol. */ + +extern struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, + const char *, + const char *, int, + domain_enum); + /* lookup a symbol by name, within a specified block */ extern struct symbol *lookup_block_symbol (const struct block *, const char *, - const namespace_enum); + const char *, + const domain_enum); /* lookup a [struct, union, enum] by name, within a specified block */ @@ -1107,10 +1050,6 @@ extern struct type *lookup_union (char *, struct block *); extern struct type *lookup_enum (char *, struct block *); -/* lookup the function corresponding to the block */ - -extern struct symbol *block_function (struct block *); - /* from blockframe.c: */ /* lookup the function symbol corresponding to the address */ @@ -1123,14 +1062,13 @@ extern struct symbol *find_pc_sect_function (CORE_ADDR, asection *); /* lookup function from address, return name, start addr and end addr */ -extern int -find_pc_partial_function (CORE_ADDR, char **, CORE_ADDR *, CORE_ADDR *); +extern int find_pc_partial_function (CORE_ADDR, char **, CORE_ADDR *, + CORE_ADDR *); extern void clear_pc_function_cache (void); -extern int -find_pc_sect_partial_function (CORE_ADDR, asection *, - char **, CORE_ADDR *, CORE_ADDR *); +extern int find_pc_sect_partial_function (CORE_ADDR, asection *, + char **, CORE_ADDR *, CORE_ADDR *); /* from symtab.c: */ @@ -1166,11 +1104,10 @@ extern struct partial_symbol *find_pc_sect_psymbol (struct partial_symtab *, extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *); -extern int contained_in (struct block *, struct block *); - extern void reread_symbols (void); extern struct type *lookup_transparent_type (const char *); +extern struct type *basic_lookup_transparent_type (const char *); /* Macro for name of symbol to indicate a file compiled with gcc. */ @@ -1195,10 +1132,6 @@ extern struct minimal_symbol *prim_record_minimal_symbol_and_info enum minimal_symbol_type, char *info, int section, asection * bfd_section, struct objfile *); -#ifdef SOFUN_ADDRESS_MAYBE_MISSING -extern CORE_ADDR find_stab_function_addr (char *, char *, struct objfile *); -#endif - extern unsigned int msymbol_hash_iw (const char *); extern unsigned int msymbol_hash (const char *); @@ -1212,11 +1145,9 @@ extern struct minimal_symbol *lookup_minimal_symbol (const char *, struct objfile *); extern struct minimal_symbol *lookup_minimal_symbol_text (const char *, - const char *, struct objfile *); struct minimal_symbol *lookup_minimal_symbol_solib_trampoline (const char *, - const char *, struct objfile *); @@ -1242,31 +1173,25 @@ extern void install_minimal_symbols (struct objfile *); extern void msymbols_sort (struct objfile *objfile); struct symtab_and_line - { - struct symtab *symtab; - asection *section; - /* Line number. Line numbers start at 1 and proceed through symtab->nlines. - 0 is never a valid line number; it is used to indicate that line number - information is not available. */ - int line; +{ + struct symtab *symtab; + asection *section; + /* Line number. Line numbers start at 1 and proceed through symtab->nlines. + 0 is never a valid line number; it is used to indicate that line number + information is not available. */ + int line; - CORE_ADDR pc; - CORE_ADDR end; - }; + CORE_ADDR pc; + CORE_ADDR end; +}; -#define INIT_SAL(sal) { \ - (sal)->symtab = 0; \ - (sal)->section = 0; \ - (sal)->line = 0; \ - (sal)->pc = 0; \ - (sal)->end = 0; \ -} +extern void init_sal (struct symtab_and_line *sal); struct symtabs_and_lines - { - struct symtab_and_line *sals; - int nelts; - }; +{ + struct symtab_and_line *sals; + int nelts; +}; @@ -1277,22 +1202,22 @@ struct symtabs_and_lines /* Enums for exception-handling support */ enum exception_event_kind - { - EX_EVENT_THROW, - EX_EVENT_CATCH - }; +{ + EX_EVENT_THROW, + EX_EVENT_CATCH +}; /* Type for returning info about an exception */ struct exception_event_record - { - enum exception_event_kind kind; - struct symtab_and_line throw_sal; - struct symtab_and_line catch_sal; - /* This may need to be extended in the future, if - some platforms allow reporting more information, - such as point of rethrow, type of exception object, - type expected by catch clause, etc. */ - }; +{ + enum exception_event_kind kind; + struct symtab_and_line throw_sal; + struct symtab_and_line catch_sal; + /* This may need to be extended in the future, if + some platforms allow reporting more information, + such as point of rethrow, type of exception object, + type expected by catch clause, etc. */ +}; #define CURRENT_EXCEPTION_KIND (current_exception_event->kind) #define CURRENT_EXCEPTION_CATCH_SAL (current_exception_event->catch_sal) @@ -1314,19 +1239,12 @@ extern struct symtab_and_line find_pc_line (CORE_ADDR, int); extern struct symtab_and_line find_pc_sect_line (CORE_ADDR, asection *, int); -/* Given an address, return the nearest symbol at or below it in memory. - Optionally return the symtab it's from through 2nd arg, and the - address in inferior memory of the symbol through 3rd arg. */ - -extern struct symbol *find_addr_symbol (CORE_ADDR, struct symtab **, - CORE_ADDR *); - /* Given a symtab and line number, return the pc there. */ extern int find_line_pc (struct symtab *, int, CORE_ADDR *); -extern int -find_line_pc_range (struct symtab_and_line, CORE_ADDR *, CORE_ADDR *); +extern int find_line_pc_range (struct symtab_and_line, CORE_ADDR *, + CORE_ADDR *); extern void resolve_sal_pc (struct symtab_and_line *); @@ -1347,6 +1265,10 @@ void maintenance_print_msymbols (char *, int); void maintenance_print_objfiles (char *, int); +void maintenance_info_symtabs (char *, int); + +void maintenance_info_psymtabs (char *, int); + void maintenance_check_symtabs (char *, int); /* maint.c */ @@ -1375,8 +1297,6 @@ extern char **make_symbol_completion_list (char *, char *); extern char **make_file_symbol_completion_list (char *, char *, char *); -extern struct symbol **make_symbol_overload_list (struct symbol *); - extern char **make_source_files_completion_list (char *, char *); /* symtab.c */ @@ -1385,14 +1305,8 @@ extern struct partial_symtab *find_main_psymtab (void); extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *); -extern struct symtab_and_line find_function_start_sal (struct symbol *sym, int); - -/* blockframe.c */ - -extern struct blockvector *blockvector_for_pc (CORE_ADDR, int *); - -extern struct blockvector *blockvector_for_pc_sect (CORE_ADDR, asection *, - int *, struct symtab *); +extern struct symtab_and_line find_function_start_sal (struct symbol *sym, + int); /* symfile.c */ @@ -1404,6 +1318,8 @@ extern enum language deduce_language_from_filename (char *); extern int in_prologue (CORE_ADDR pc, CORE_ADDR func_start); +extern CORE_ADDR skip_prologue_using_sal (CORE_ADDR func_addr); + extern struct symbol *fixup_symbol_section (struct symbol *, struct objfile *); @@ -1416,36 +1332,37 @@ extern struct partial_symbol *fixup_psymbol_section (struct partial_symbol /* When using search_symbols, a list of the following structs is returned. Callers must free the search list using free_search_symbols! */ struct symbol_search - { - /* The block in which the match was found. Could be, for example, - STATIC_BLOCK or GLOBAL_BLOCK. */ - int block; +{ + /* The block in which the match was found. Could be, for example, + STATIC_BLOCK or GLOBAL_BLOCK. */ + int block; - /* Information describing what was found. + /* Information describing what was found. - If symtab abd symbol are NOT NULL, then information was found - for this match. */ - struct symtab *symtab; - struct symbol *symbol; + If symtab abd symbol are NOT NULL, then information was found + for this match. */ + struct symtab *symtab; + struct symbol *symbol; - /* If msymbol is non-null, then a match was made on something for - which only minimal_symbols exist. */ - struct minimal_symbol *msymbol; + /* If msymbol is non-null, then a match was made on something for + which only minimal_symbols exist. */ + struct minimal_symbol *msymbol; - /* A link to the next match, or NULL for the end. */ - struct symbol_search *next; - }; + /* A link to the next match, or NULL for the end. */ + struct symbol_search *next; +}; -extern void search_symbols (char *, namespace_enum, int, char **, +extern void search_symbols (char *, domain_enum, int, char **, struct symbol_search **); extern void free_search_symbols (struct symbol_search *); -extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search *); +extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search + *); /* The name of the ``main'' function. FIXME: cagney/2001-03-20: Can't make main_name() const since some of the calling code currently assumes that the string isn't const. */ extern void set_main_name (const char *name); -extern /*const*/ char *main_name (void); +extern /*const */ char *main_name (void); #endif /* !defined(SYMTAB_H) */ diff --git a/contrib/gdb/gdb/target.c b/contrib/gdb/gdb/target.c index d5f205fda0f..ff47ac13bf7 100644 --- a/contrib/gdb/gdb/target.c +++ b/contrib/gdb/gdb/target.c @@ -1,7 +1,8 @@ /* Select target systems and architectures at runtime for GDB. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Support. This file is part of GDB. @@ -35,23 +36,21 @@ #include "dcache.h" #include #include "regcache.h" - -extern int errno; +#include "gdb_assert.h" +#include "gdbcore.h" static void target_info (char *, int); -static void cleanup_target (struct target_ops *); - static void maybe_kill_then_create_inferior (char *, char *, char **); -static void default_clone_and_follow_inferior (int, int *); - static void maybe_kill_then_attach (char *, int); static void kill_or_be_killed (int); static void default_terminal_info (char *, int); +static int default_region_size_ok_for_hw_watchpoint (int); + static int nosymbol (char *, CORE_ADDR *); static void tcomplain (void); @@ -62,17 +61,21 @@ static int return_zero (void); static int return_one (void); +static int return_minus_one (void); + void target_ignore (void); static void target_command (char *, int); static struct target_ops *find_default_run_target (char *); -static void update_current_target (void); - static void nosupport_runtime (void); -static void normal_target_post_startup_inferior (ptid_t ptid); +static LONGEST default_xfer_partial (struct target_ops *ops, + enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, + ULONGEST offset, LONGEST len); /* Transfer LEN bytes between target address MEMADDR and GDB address MYADDR. Returns 0 for success, errno code for failure (which @@ -80,8 +83,8 @@ static void normal_target_post_startup_inferior (ptid_t ptid); partial transfers, try either target_read_memory_partial or target_write_memory_partial). */ -static int -target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write); +static int target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write); static void init_dummy_target (void); @@ -93,6 +96,8 @@ static void debug_to_attach (char *, int); static void debug_to_detach (char *, int); +static void debug_to_disconnect (char *, int); + static void debug_to_resume (ptid_t, int, enum target_signal); static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *); @@ -103,9 +108,8 @@ static void debug_to_store_registers (int); static void debug_to_prepare_to_store (void); -static int -debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, - struct target_ops *); +static int debug_to_xfer_memory (CORE_ADDR, char *, int, int, + struct mem_attrib *, struct target_ops *); static void debug_to_files_info (struct target_ops *); @@ -113,12 +117,30 @@ static int debug_to_insert_breakpoint (CORE_ADDR, char *); static int debug_to_remove_breakpoint (CORE_ADDR, char *); +static int debug_to_can_use_hw_breakpoint (int, int, int); + +static int debug_to_insert_hw_breakpoint (CORE_ADDR, char *); + +static int debug_to_remove_hw_breakpoint (CORE_ADDR, char *); + +static int debug_to_insert_watchpoint (CORE_ADDR, int, int); + +static int debug_to_remove_watchpoint (CORE_ADDR, int, int); + +static int debug_to_stopped_by_watchpoint (void); + +static CORE_ADDR debug_to_stopped_data_address (void); + +static int debug_to_region_size_ok_for_hw_watchpoint (int); + static void debug_to_terminal_init (void); static void debug_to_terminal_inferior (void); static void debug_to_terminal_ours_for_output (void); +static void debug_to_terminal_save_ours (void); + static void debug_to_terminal_ours (void); static void debug_to_terminal_info (char *, int); @@ -141,8 +163,6 @@ static int debug_to_thread_alive (ptid_t); static void debug_to_stop (void); -static int debug_to_query (int /*char */ , char *, char *, int *); - /* Pointer to array of target architecture structures; the size of the array; the current index into the array; the allocated size of the array. */ @@ -159,7 +179,7 @@ static struct target_ops dummy_target; /* Top of target stack. */ -struct target_stack_item *target_stack; +static struct target_ops *target_stack; /* The target structure we are currently using to talk to a process or file or whatever "inferior" we have. */ @@ -185,7 +205,6 @@ DCACHE *target_dcache; /* The user just typed 'target' without the name of a target. */ -/* ARGSUSED */ static void target_command (char *arg, int from_tty) { @@ -198,6 +217,10 @@ target_command (char *arg, int from_tty) void add_target (struct target_ops *t) { + /* Provide default values for all "must have" methods. */ + if (t->to_xfer_partial == NULL) + t->to_xfer_partial = default_xfer_partial; + if (!target_structs) { target_struct_allocsize = DEFAULT_ALLOCSIZE; @@ -212,7 +235,6 @@ add_target (struct target_ops *t) target_struct_allocsize * sizeof (*target_structs)); } target_structs[target_struct_size++] = t; -/* cleanup_target (t); */ if (targetlist == NULL) add_prefix_cmd ("target", class_run, target_command, @@ -239,7 +261,6 @@ target_load (char *arg, int from_tty) (*current_target.to_load) (arg, from_tty); } -/* ARGSUSED */ static int nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write, struct target_ops *t) @@ -261,14 +282,12 @@ noprocess (void) error ("You can't do that without a process to debug."); } -/* ARGSUSED */ static int nosymbol (char *name, CORE_ADDR *addrp) { return 1; /* Symbol does not exist in target env */ } -/* ARGSUSED */ static void nosupport_runtime (void) { @@ -279,7 +298,6 @@ nosupport_runtime (void) } -/* ARGSUSED */ static void default_terminal_info (char *args, int from_tty) { @@ -327,22 +345,121 @@ maybe_kill_then_create_inferior (char *exec, char *args, char **env) target_create_inferior (exec, args, env); } -static void -default_clone_and_follow_inferior (int child_pid, int *followed_child) -{ - target_clone_and_follow_inferior (child_pid, followed_child); -} +/* Go through the target stack from top to bottom, copying over zero + entries in current_target, then filling in still empty entries. In + effect, we are doing class inheritance through the pushed target + vectors. -/* Clean up a target struct so it no longer has any zero pointers in it. - We default entries, at least to stubs that print error messages. */ + NOTE: cagney/2003-10-17: The problem with this inheritance, as it + is currently implemented, is that it discards any knowledge of + which target an inherited method originally belonged to. + Consequently, new new target methods should instead explicitly and + locally search the target stack for the target that can handle the + request. */ static void -cleanup_target (struct target_ops *t) +update_current_target (void) { + struct target_ops *t; + + /* First, reset curren'ts contents. */ + memset (¤t_target, 0, sizeof (current_target)); + +#define INHERIT(FIELD, TARGET) \ + if (!current_target.FIELD) \ + current_target.FIELD = (TARGET)->FIELD + + for (t = target_stack; t; t = t->beneath) + { + INHERIT (to_shortname, t); + INHERIT (to_longname, t); + INHERIT (to_doc, t); + INHERIT (to_open, t); + INHERIT (to_close, t); + INHERIT (to_attach, t); + INHERIT (to_post_attach, t); + INHERIT (to_detach, t); + INHERIT (to_disconnect, t); + INHERIT (to_resume, t); + INHERIT (to_wait, t); + INHERIT (to_post_wait, t); + INHERIT (to_fetch_registers, t); + INHERIT (to_store_registers, t); + INHERIT (to_prepare_to_store, t); + INHERIT (to_xfer_memory, t); + INHERIT (to_files_info, t); + INHERIT (to_insert_breakpoint, t); + INHERIT (to_remove_breakpoint, t); + INHERIT (to_can_use_hw_breakpoint, t); + INHERIT (to_insert_hw_breakpoint, t); + INHERIT (to_remove_hw_breakpoint, t); + INHERIT (to_insert_watchpoint, t); + INHERIT (to_remove_watchpoint, t); + INHERIT (to_stopped_data_address, t); + INHERIT (to_stopped_by_watchpoint, t); + INHERIT (to_have_continuable_watchpoint, t); + INHERIT (to_region_size_ok_for_hw_watchpoint, t); + INHERIT (to_terminal_init, t); + INHERIT (to_terminal_inferior, t); + INHERIT (to_terminal_ours_for_output, t); + INHERIT (to_terminal_ours, t); + INHERIT (to_terminal_save_ours, t); + INHERIT (to_terminal_info, t); + INHERIT (to_kill, t); + INHERIT (to_load, t); + INHERIT (to_lookup_symbol, t); + INHERIT (to_create_inferior, t); + INHERIT (to_post_startup_inferior, t); + INHERIT (to_acknowledge_created_inferior, t); + INHERIT (to_insert_fork_catchpoint, t); + INHERIT (to_remove_fork_catchpoint, t); + INHERIT (to_insert_vfork_catchpoint, t); + INHERIT (to_remove_vfork_catchpoint, t); + INHERIT (to_follow_fork, t); + INHERIT (to_insert_exec_catchpoint, t); + INHERIT (to_remove_exec_catchpoint, t); + INHERIT (to_reported_exec_events_per_exec_call, t); + INHERIT (to_has_exited, t); + INHERIT (to_mourn_inferior, t); + INHERIT (to_can_run, t); + INHERIT (to_notice_signals, t); + INHERIT (to_thread_alive, t); + INHERIT (to_find_new_threads, t); + INHERIT (to_pid_to_str, t); + INHERIT (to_extra_thread_info, t); + INHERIT (to_stop, t); + /* Do not inherit to_xfer_partial. */ + INHERIT (to_rcmd, t); + INHERIT (to_enable_exception_callback, t); + INHERIT (to_get_current_exception_event, t); + INHERIT (to_pid_to_exec_file, t); + INHERIT (to_stratum, t); + INHERIT (to_has_all_memory, t); + INHERIT (to_has_memory, t); + INHERIT (to_has_stack, t); + INHERIT (to_has_registers, t); + INHERIT (to_has_execution, t); + INHERIT (to_has_thread_control, t); + INHERIT (to_sections, t); + INHERIT (to_sections_end, t); + INHERIT (to_can_async_p, t); + INHERIT (to_is_async_p, t); + INHERIT (to_async, t); + INHERIT (to_async_mask_value, t); + INHERIT (to_find_memory_regions, t); + INHERIT (to_make_corefile_notes, t); + INHERIT (to_get_thread_local_address, t); + INHERIT (to_magic, t); + } +#undef INHERIT + + /* Clean up a target struct so it no longer has any zero pointers in + it. Some entries are defaulted to a method that print an error, + others are hard-wired to a standard recursive default. */ #define de_fault(field, value) \ - if (!t->field) \ - t->field = value + if (!current_target.field) \ + current_target.field = value de_fault (to_open, (void (*) (char *, int)) @@ -355,14 +472,12 @@ cleanup_target (struct target_ops *t) de_fault (to_post_attach, (void (*) (int)) target_ignore); - de_fault (to_require_attach, - maybe_kill_then_attach); de_fault (to_detach, (void (*) (char *, int)) target_ignore); - de_fault (to_require_detach, - (void (*) (int, char *, int)) - target_ignore); + de_fault (to_disconnect, + (void (*) (char *, int)) + tcomplain); de_fault (to_resume, (void (*) (ptid_t, int, enum target_signal)) noprocess); @@ -391,6 +506,29 @@ cleanup_target (struct target_ops *t) memory_insert_breakpoint); de_fault (to_remove_breakpoint, memory_remove_breakpoint); + de_fault (to_can_use_hw_breakpoint, + (int (*) (int, int, int)) + return_zero); + de_fault (to_insert_hw_breakpoint, + (int (*) (CORE_ADDR, char *)) + return_minus_one); + de_fault (to_remove_hw_breakpoint, + (int (*) (CORE_ADDR, char *)) + return_minus_one); + de_fault (to_insert_watchpoint, + (int (*) (CORE_ADDR, int, int)) + return_minus_one); + de_fault (to_remove_watchpoint, + (int (*) (CORE_ADDR, int, int)) + return_minus_one); + de_fault (to_stopped_by_watchpoint, + (int (*) (void)) + return_zero); + de_fault (to_stopped_data_address, + (CORE_ADDR (*) (void)) + return_zero); + de_fault (to_region_size_ok_for_hw_watchpoint, + default_region_size_ok_for_hw_watchpoint); de_fault (to_terminal_init, (void (*) (void)) target_ignore); @@ -403,6 +541,9 @@ cleanup_target (struct target_ops *t) de_fault (to_terminal_ours, (void (*) (void)) target_ignore); + de_fault (to_terminal_save_ours, + (void (*) (void)) + target_ignore); de_fault (to_terminal_info, default_terminal_info); de_fault (to_kill, @@ -422,11 +563,6 @@ cleanup_target (struct target_ops *t) de_fault (to_acknowledge_created_inferior, (void (*) (int)) target_ignore); - de_fault (to_clone_and_follow_inferior, - default_clone_and_follow_inferior); - de_fault (to_post_follow_inferior_by_clone, - (void (*) (void)) - target_ignore); de_fault (to_insert_fork_catchpoint, (int (*) (int)) tcomplain); @@ -439,17 +575,8 @@ cleanup_target (struct target_ops *t) de_fault (to_remove_vfork_catchpoint, (int (*) (int)) tcomplain); - de_fault (to_has_forked, - (int (*) (int, int *)) - return_zero); - de_fault (to_has_vforked, - (int (*) (int, int *)) - return_zero); - de_fault (to_can_follow_vfork_prior_to_exec, - (int (*) (void)) - return_zero); - de_fault (to_post_follow_vfork, - (void (*) (int, int, int, int)) + de_fault (to_follow_fork, + (int (*) (int)) target_ignore); de_fault (to_insert_exec_catchpoint, (int (*) (int)) @@ -457,15 +584,9 @@ cleanup_target (struct target_ops *t) de_fault (to_remove_exec_catchpoint, (int (*) (int)) tcomplain); - de_fault (to_has_execd, - (int (*) (int, char **)) - return_zero); de_fault (to_reported_exec_events_per_exec_call, (int (*) (void)) return_one); - de_fault (to_has_syscall_event, - (int (*) (int, enum target_waitkind *, int *)) - return_zero); de_fault (to_has_exited, (int (*) (int, int, int *)) return_zero); @@ -489,6 +610,7 @@ cleanup_target (struct target_ops *t) de_fault (to_stop, (void (*) (void)) target_ignore); + current_target.to_xfer_partial = default_xfer_partial; de_fault (to_rcmd, (void (*) (char *, struct ui_file *)) tcomplain); @@ -511,109 +633,11 @@ cleanup_target (struct target_ops *t) (void (*) (void (*) (enum inferior_event_type, void*), void*)) tcomplain); #undef de_fault -} -/* Go through the target stack from top to bottom, copying over zero entries in - current_target. In effect, we are doing class inheritance through the - pushed target vectors. */ - -static void -update_current_target (void) -{ - struct target_stack_item *item; - struct target_ops *t; - - /* First, reset current_target */ - memset (¤t_target, 0, sizeof current_target); - - for (item = target_stack; item; item = item->next) - { - t = item->target_ops; - -#define INHERIT(FIELD, TARGET) \ - if (!current_target.FIELD) \ - current_target.FIELD = TARGET->FIELD - - INHERIT (to_shortname, t); - INHERIT (to_longname, t); - INHERIT (to_doc, t); - INHERIT (to_open, t); - INHERIT (to_close, t); - INHERIT (to_attach, t); - INHERIT (to_post_attach, t); - INHERIT (to_require_attach, t); - INHERIT (to_detach, t); - INHERIT (to_require_detach, t); - INHERIT (to_resume, t); - INHERIT (to_wait, t); - INHERIT (to_post_wait, t); - INHERIT (to_fetch_registers, t); - INHERIT (to_store_registers, t); - INHERIT (to_prepare_to_store, t); - INHERIT (to_xfer_memory, t); - INHERIT (to_files_info, t); - INHERIT (to_insert_breakpoint, t); - INHERIT (to_remove_breakpoint, t); - INHERIT (to_terminal_init, t); - INHERIT (to_terminal_inferior, t); - INHERIT (to_terminal_ours_for_output, t); - INHERIT (to_terminal_ours, t); - INHERIT (to_terminal_info, t); - INHERIT (to_kill, t); - INHERIT (to_load, t); - INHERIT (to_lookup_symbol, t); - INHERIT (to_create_inferior, t); - INHERIT (to_post_startup_inferior, t); - INHERIT (to_acknowledge_created_inferior, t); - INHERIT (to_clone_and_follow_inferior, t); - INHERIT (to_post_follow_inferior_by_clone, t); - INHERIT (to_insert_fork_catchpoint, t); - INHERIT (to_remove_fork_catchpoint, t); - INHERIT (to_insert_vfork_catchpoint, t); - INHERIT (to_remove_vfork_catchpoint, t); - INHERIT (to_has_forked, t); - INHERIT (to_has_vforked, t); - INHERIT (to_can_follow_vfork_prior_to_exec, t); - INHERIT (to_post_follow_vfork, t); - INHERIT (to_insert_exec_catchpoint, t); - INHERIT (to_remove_exec_catchpoint, t); - INHERIT (to_has_execd, t); - INHERIT (to_reported_exec_events_per_exec_call, t); - INHERIT (to_has_syscall_event, t); - INHERIT (to_has_exited, t); - INHERIT (to_mourn_inferior, t); - INHERIT (to_can_run, t); - INHERIT (to_notice_signals, t); - INHERIT (to_thread_alive, t); - INHERIT (to_find_new_threads, t); - INHERIT (to_pid_to_str, t); - INHERIT (to_extra_thread_info, t); - INHERIT (to_stop, t); - INHERIT (to_query, t); - INHERIT (to_rcmd, t); - INHERIT (to_enable_exception_callback, t); - INHERIT (to_get_current_exception_event, t); - INHERIT (to_pid_to_exec_file, t); - INHERIT (to_stratum, t); - INHERIT (DONT_USE, t); - INHERIT (to_has_all_memory, t); - INHERIT (to_has_memory, t); - INHERIT (to_has_stack, t); - INHERIT (to_has_registers, t); - INHERIT (to_has_execution, t); - INHERIT (to_has_thread_control, t); - INHERIT (to_sections, t); - INHERIT (to_sections_end, t); - INHERIT (to_can_async_p, t); - INHERIT (to_is_async_p, t); - INHERIT (to_async, t); - INHERIT (to_async_mask_value, t); - INHERIT (to_find_memory_regions, t); - INHERIT (to_make_corefile_notes, t); - INHERIT (to_magic, t); - -#undef INHERIT - } + /* Finally, position the target-stack beneath the squashed + "current_target". That way code looking for a non-inherited + target method can quickly and simply find it. */ + current_target.beneath = target_stack; } /* Push a new target type into the stack of the existing target accessors, @@ -629,7 +653,7 @@ update_current_target (void) int push_target (struct target_ops *t) { - struct target_stack_item *cur, *prev, *tmp; + struct target_ops **cur; /* Check magic number. If wrong, it probably means someone changed the struct definition, but not all the places that initialize one. */ @@ -641,51 +665,37 @@ push_target (struct target_ops *t) internal_error (__FILE__, __LINE__, "failed internal consistency check"); } - /* Find the proper stratum to install this target in. */ - - for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next) + /* Find the proper stratum to install this target in. */ + for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath) { - if ((int) (t->to_stratum) >= (int) (cur->target_ops->to_stratum)) + if ((int) (t->to_stratum) >= (int) (*cur)->to_stratum) break; } - /* If there's already targets at this stratum, remove them. */ - - if (cur) - while (t->to_stratum == cur->target_ops->to_stratum) - { - /* There's already something on this stratum. Close it off. */ - if (cur->target_ops->to_close) - (cur->target_ops->to_close) (0); - if (prev) - prev->next = cur->next; /* Unchain old target_ops */ - else - target_stack = cur->next; /* Unchain first on list */ - tmp = cur->next; - xfree (cur); - cur = tmp; - } + /* If there's already targets at this stratum, remove them. */ + /* FIXME: cagney/2003-10-15: I think this should be poping all + targets to CUR, and not just those at this stratum level. */ + while ((*cur) != NULL && t->to_stratum == (*cur)->to_stratum) + { + /* There's already something at this stratum level. Close it, + and un-hook it from the stack. */ + struct target_ops *tmp = (*cur); + (*cur) = (*cur)->beneath; + tmp->beneath = NULL; + target_close (tmp, 0); + } /* We have removed all targets in our stratum, now add the new one. */ - - tmp = (struct target_stack_item *) - xmalloc (sizeof (struct target_stack_item)); - tmp->next = cur; - tmp->target_ops = t; - - if (prev) - prev->next = tmp; - else - target_stack = tmp; + t->beneath = (*cur); + (*cur) = t; update_current_target (); - cleanup_target (¤t_target); /* Fill in the gaps */ - if (targetdebug) setup_target_debug (); - return prev != 0; + /* Not on top? */ + return (t != target_stack); } /* Remove a target_ops vector from the stack, wherever it may be. @@ -694,32 +704,35 @@ push_target (struct target_ops *t) int unpush_target (struct target_ops *t) { - struct target_stack_item *cur, *prev; - - if (t->to_close) - t->to_close (0); /* Let it clean up */ + struct target_ops **cur; + struct target_ops *tmp; /* Look for the specified target. Note that we assume that a target can only occur once in the target stack. */ - for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next) - if (cur->target_ops == t) - break; + for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath) + { + if ((*cur) == t) + break; + } - if (!cur) + if ((*cur) == NULL) return 0; /* Didn't find target_ops, quit now */ + /* NOTE: cagney/2003-12-06: In '94 the close call was made + unconditional by moving it to before the above check that the + target was in the target stack (something about "Change the way + pushing and popping of targets work to support target overlays + and inheritance"). This doesn't make much sense - only open + targets should be closed. */ + target_close (t, 0); + /* Unchain the target */ - - if (!prev) - target_stack = cur->next; - else - prev->next = cur->next; - - xfree (cur); /* Release the target_stack_item */ + tmp = (*cur); + (*cur) = (*cur)->beneath; + tmp->beneath = NULL; update_current_target (); - cleanup_target (¤t_target); return 1; } @@ -727,8 +740,8 @@ unpush_target (struct target_ops *t) void pop_target (void) { - (current_target.to_close) (0); /* Let it clean up */ - if (unpush_target (target_stack->target_ops) == 1) + target_close (¤t_target, 0); /* Let it clean up */ + if (unpush_target (target_stack) == 1) return; fprintf_unfiltered (gdb_stderr, @@ -813,6 +826,21 @@ done: return nbytes_read; } +/* Find a section containing ADDR. */ +struct section_table * +target_section_by_addr (struct target_ops *target, CORE_ADDR addr) +{ + struct section_table *secp; + for (secp = target->to_sections; + secp < target->to_sections_end; + secp++) + { + if (addr >= secp->addr && addr < secp->endaddr) + return secp; + } + return NULL; +} + /* Read LEN bytes of target memory at address MEMADDR, placing the results in GDB's memory at MYADDR. Returns either 0 for success or an errno value if any error occurs. @@ -849,7 +877,6 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, int res; int done = 0; struct target_ops *t; - struct target_stack_item *item; /* Zero length requests are ok and require no work. */ if (len == 0) @@ -861,22 +888,15 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, if (!write && trust_readonly) { - /* User-settable option, "trust-readonly". If true, then - memory from any SEC_READONLY bfd section may be read - directly from the bfd file. */ - struct section_table *secp; - - for (secp = current_target.to_sections; - secp < current_target.to_sections_end; - secp++) - { - if (bfd_get_section_flags (secp->bfd, secp->the_bfd_section) - & SEC_READONLY) - if (memaddr >= secp->addr && memaddr < secp->endaddr) - return xfer_memory (memaddr, myaddr, len, 0, - attrib, ¤t_target); - } + /* User-settable option, "trust-readonly-sections". If true, + then memory from any SEC_READONLY bfd section may be read + directly from the bfd file. */ + secp = target_section_by_addr (¤t_target, memaddr); + if (secp != NULL + && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section) + & SEC_READONLY)) + return xfer_memory (memaddr, myaddr, len, 0, attrib, ¤t_target); } /* The quick case is that the top target can handle the transfer. */ @@ -886,9 +906,8 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, /* If res <= 0 then we call it again in the loop. Ah well. */ if (res <= 0) { - for (item = target_stack; item; item = item->next) + for (t = target_stack; t != NULL; t = t->beneath) { - t = item->target_ops; if (!t->to_has_memory) continue; @@ -1056,12 +1075,145 @@ target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err) return target_xfer_memory_partial (memaddr, buf, len, 1, err); } -/* ARGSUSED */ +/* More generic transfers. */ + +static LONGEST +default_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + if (object == TARGET_OBJECT_MEMORY + && ops->to_xfer_memory != NULL) + /* If available, fall back to the target's "to_xfer_memory" + method. */ + { + int xfered = -1; + errno = 0; + if (writebuf != NULL) + { + void *buffer = xmalloc (len); + struct cleanup *cleanup = make_cleanup (xfree, buffer); + memcpy (buffer, writebuf, len); + xfered = ops->to_xfer_memory (offset, buffer, len, 1/*write*/, NULL, + ops); + do_cleanups (cleanup); + } + if (readbuf != NULL) + xfered = ops->to_xfer_memory (offset, readbuf, len, 0/*read*/, NULL, + ops); + if (xfered > 0) + return xfered; + else if (xfered == 0 && errno == 0) + /* "to_xfer_memory" uses 0, cross checked against ERRNO as one + indication of an error. */ + return 0; + else + return -1; + } + else if (ops->beneath != NULL) + return ops->beneath->to_xfer_partial (ops->beneath, object, annex, + readbuf, writebuf, offset, len); + else + return -1; +} + +/* Target vector read/write partial wrapper functions. + + NOTE: cagney/2003-10-21: I wonder if having "to_xfer_partial + (inbuf, outbuf)", instead of separate read/write methods, make life + easier. */ + +LONGEST +target_read_partial (struct target_ops *ops, + enum target_object object, + const char *annex, void *buf, + ULONGEST offset, LONGEST len) +{ + gdb_assert (ops->to_xfer_partial != NULL); + return ops->to_xfer_partial (ops, object, annex, buf, NULL, offset, len); +} + +LONGEST +target_write_partial (struct target_ops *ops, + enum target_object object, + const char *annex, const void *buf, + ULONGEST offset, LONGEST len) +{ + gdb_assert (ops->to_xfer_partial != NULL); + return ops->to_xfer_partial (ops, object, annex, NULL, buf, offset, len); +} + +/* Wrappers to perform the full transfer. */ +LONGEST +target_read (struct target_ops *ops, + enum target_object object, + const char *annex, void *buf, + ULONGEST offset, LONGEST len) +{ + LONGEST xfered = 0; + while (xfered < len) + { + LONGEST xfer = target_read_partial (ops, object, annex, + (bfd_byte *) buf + xfered, + offset + xfered, len - xfered); + /* Call an observer, notifying them of the xfer progress? */ + if (xfer <= 0) + /* Call memory_error? */ + return -1; + xfered += xfer; + QUIT; + } + return len; +} + +LONGEST +target_write (struct target_ops *ops, + enum target_object object, + const char *annex, const void *buf, + ULONGEST offset, LONGEST len) +{ + LONGEST xfered = 0; + while (xfered < len) + { + LONGEST xfer = target_write_partial (ops, object, annex, + (bfd_byte *) buf + xfered, + offset + xfered, len - xfered); + /* Call an observer, notifying them of the xfer progress? */ + if (xfer <= 0) + /* Call memory_error? */ + return -1; + xfered += xfer; + QUIT; + } + return len; +} + +/* Memory transfer methods. */ + +void +get_target_memory (struct target_ops *ops, CORE_ADDR addr, void *buf, + LONGEST len) +{ + if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, buf, addr, len) + != len) + memory_error (EIO, addr); +} + +ULONGEST +get_target_memory_unsigned (struct target_ops *ops, + CORE_ADDR addr, int len) +{ + char buf[sizeof (ULONGEST)]; + + gdb_assert (len <= sizeof (buf)); + get_target_memory (ops, addr, buf, len); + return extract_unsigned_integer (buf, len); +} + static void target_info (char *args, int from_tty) { struct target_ops *t; - struct target_stack_item *item; int has_all_mem = 0; if (symfile_objfile != NULL) @@ -1072,10 +1224,8 @@ target_info (char *args, int from_tty) return; #endif - for (item = target_stack; item; item = item->next) + for (t = target_stack; t != NULL; t = t->beneath) { - t = item->target_ops; - if (!t->to_has_memory) continue; @@ -1125,10 +1275,20 @@ target_detach (char *args, int from_tty) (current_target.to_detach) (args, from_tty); } +void +target_disconnect (char *args, int from_tty) +{ + /* Handle any optimized stores to the inferior. */ +#ifdef DO_DEFERRED_STORES + DO_DEFERRED_STORES; +#endif + (current_target.to_disconnect) (args, from_tty); +} + void target_link (char *modname, CORE_ADDR *t_reloc) { - if (STREQ (current_target.to_shortname, "rombug")) + if (DEPRECATED_STREQ (current_target.to_shortname, "rombug")) { (current_target.to_lookup_symbol) (modname, t_reloc); if (*t_reloc == 0) @@ -1187,26 +1347,6 @@ find_default_attach (char *args, int from_tty) return; } -void -find_default_require_attach (char *args, int from_tty) -{ - struct target_ops *t; - - t = find_default_run_target ("require_attach"); - (t->to_require_attach) (args, from_tty); - return; -} - -void -find_default_require_detach (int pid, char *args, int from_tty) -{ - struct target_ops *t; - - t = find_default_run_target ("require_detach"); - (t->to_require_detach) (pid, args, from_tty); - return; -} - void find_default_create_inferior (char *exec_file, char *allargs, char **env) { @@ -1217,14 +1357,10 @@ find_default_create_inferior (char *exec_file, char *allargs, char **env) return; } -void -find_default_clone_and_follow_inferior (int child_pid, int *followed_child) +static int +default_region_size_ok_for_hw_watchpoint (int byte_count) { - struct target_ops *t; - - t = find_default_run_target ("run"); - (t->to_clone_and_follow_inferior) (child_pid, followed_child); - return; + return (byte_count <= TYPE_LENGTH (builtin_type_void_data_ptr)); } static int @@ -1239,6 +1375,12 @@ return_one (void) return 1; } +static int +return_minus_one (void) +{ + return -1; +} + /* * Resize the to_sections pointer. Also make sure that anyone that * was holding on to an old value of it gets updated. @@ -1378,16 +1520,7 @@ find_core_target (void) struct target_ops * find_target_beneath (struct target_ops *t) { - struct target_stack_item *cur; - - for (cur = target_stack; cur; cur = cur->next) - if (cur->target_ops == t) - break; - - if (cur == NULL || cur->next == NULL) - return NULL; - else - return cur->next->target_ops; + return t->beneath; } @@ -1468,26 +1601,7 @@ normal_pid_to_str (ptid_t ptid) return buf; } -/* Some targets (such as ttrace-based HPUX) don't allow us to request - notification of inferior events such as fork and vork immediately - after the inferior is created. (This because of how gdb gets an - inferior created via invoking a shell to do it. In such a scenario, - if the shell init file has commands in it, the shell will fork and - exec for each of those commands, and we will see each such fork - event. Very bad.) - - This function is used by all targets that allow us to request - notification of forks, etc at inferior creation time; e.g., in - target_acknowledge_forked_child. - */ -static void -normal_target_post_startup_inferior (ptid_t ptid) -{ - /* This space intentionally left blank. */ -} - /* Error-catcher for target_find_memory_regions */ -/* ARGSUSED */ static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2) { error ("No target."); @@ -1495,7 +1609,6 @@ static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2) } /* Error-catcher for target_make_corefile_notes */ -/* ARGSUSED */ static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2) { error ("No target."); @@ -1512,14 +1625,12 @@ init_dummy_target (void) dummy_target.to_longname = "None"; dummy_target.to_doc = ""; dummy_target.to_attach = find_default_attach; - dummy_target.to_require_attach = find_default_require_attach; - dummy_target.to_require_detach = find_default_require_detach; dummy_target.to_create_inferior = find_default_create_inferior; - dummy_target.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior; dummy_target.to_pid_to_str = normal_pid_to_str; dummy_target.to_stratum = dummy_stratum; dummy_target.to_find_memory_regions = dummy_find_memory_regions; dummy_target.to_make_corefile_notes = dummy_make_corefile_notes; + dummy_target.to_xfer_partial = default_xfer_partial; dummy_target.to_magic = OPS_MAGIC; } @@ -1537,11 +1648,19 @@ debug_to_open (char *args, int from_tty) static void debug_to_close (int quitting) { - debug_target.to_close (quitting); - + target_close (&debug_target, quitting); fprintf_unfiltered (gdb_stdlog, "target_close (%d)\n", quitting); } +void +target_close (struct target_ops *targ, int quitting) +{ + if (targ->to_xclose != NULL) + targ->to_xclose (targ, quitting); + else if (targ->to_close != NULL) + targ->to_close (quitting); +} + static void debug_to_attach (char *args, int from_tty) { @@ -1559,15 +1678,6 @@ debug_to_post_attach (int pid) fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid); } -static void -debug_to_require_attach (char *args, int from_tty) -{ - debug_target.to_require_attach (args, from_tty); - - fprintf_unfiltered (gdb_stdlog, - "target_require_attach (%s, %d)\n", args, from_tty); -} - static void debug_to_detach (char *args, int from_tty) { @@ -1577,12 +1687,12 @@ debug_to_detach (char *args, int from_tty) } static void -debug_to_require_detach (int pid, char *args, int from_tty) +debug_to_disconnect (char *args, int from_tty) { - debug_target.to_require_detach (pid, args, from_tty); + debug_target.to_disconnect (args, from_tty); - fprintf_unfiltered (gdb_stdlog, - "target_require_detach (%d, %s, %d)\n", pid, args, from_tty); + fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n", + args, from_tty); } static void @@ -1652,32 +1762,48 @@ debug_to_post_wait (ptid_t ptid, int status) PIDGET (ptid), status); } +static void +debug_print_register (const char * func, int regno) +{ + fprintf_unfiltered (gdb_stdlog, "%s ", func); + if (regno >= 0 && regno < NUM_REGS + NUM_PSEUDO_REGS + && REGISTER_NAME (regno) != NULL && REGISTER_NAME (regno)[0] != '\0') + fprintf_unfiltered (gdb_stdlog, "(%s)", REGISTER_NAME (regno)); + else + fprintf_unfiltered (gdb_stdlog, "(%d)", regno); + if (regno >= 0) + { + int i; + unsigned char buf[MAX_REGISTER_SIZE]; + deprecated_read_register_gen (regno, buf); + fprintf_unfiltered (gdb_stdlog, " = "); + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i++) + { + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); + } + if (DEPRECATED_REGISTER_RAW_SIZE (regno) <= sizeof (LONGEST)) + { + fprintf_unfiltered (gdb_stdlog, " 0x%s %s", + paddr_nz (read_register (regno)), + paddr_d (read_register (regno))); + } + } + fprintf_unfiltered (gdb_stdlog, "\n"); +} + static void debug_to_fetch_registers (int regno) { debug_target.to_fetch_registers (regno); - - fprintf_unfiltered (gdb_stdlog, "target_fetch_registers (%s)", - regno != -1 ? REGISTER_NAME (regno) : "-1"); - if (regno != -1) - fprintf_unfiltered (gdb_stdlog, " = 0x%lx %ld", - (unsigned long) read_register (regno), - (unsigned long) read_register (regno)); - fprintf_unfiltered (gdb_stdlog, "\n"); + debug_print_register ("target_fetch_registers", regno); } static void debug_to_store_registers (int regno) { debug_target.to_store_registers (regno); - - if (regno >= 0 && regno < NUM_REGS) - fprintf_unfiltered (gdb_stdlog, "target_store_registers (%s) = 0x%lx %ld\n", - REGISTER_NAME (regno), - (unsigned long) read_register (regno), - (unsigned long) read_register (regno)); - else - fprintf_unfiltered (gdb_stdlog, "target_store_registers (%d)\n", regno); + debug_print_register ("target_store_registers", regno); + fprintf_unfiltered (gdb_stdlog, "\n"); } static void @@ -1759,6 +1885,116 @@ debug_to_remove_breakpoint (CORE_ADDR addr, char *save) return retval; } +static int +debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty) +{ + int retval; + + retval = debug_target.to_can_use_hw_breakpoint (type, cnt, from_tty); + + fprintf_unfiltered (gdb_stdlog, + "target_can_use_hw_breakpoint (%ld, %ld, %ld) = %ld\n", + (unsigned long) type, + (unsigned long) cnt, + (unsigned long) from_tty, + (unsigned long) retval); + return retval; +} + +static int +debug_to_region_size_ok_for_hw_watchpoint (int byte_count) +{ + CORE_ADDR retval; + + retval = debug_target.to_region_size_ok_for_hw_watchpoint (byte_count); + + fprintf_unfiltered (gdb_stdlog, + "TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (%ld) = 0x%lx\n", + (unsigned long) byte_count, + (unsigned long) retval); + return retval; +} + +static int +debug_to_stopped_by_watchpoint (void) +{ + int retval; + + retval = debug_target.to_stopped_by_watchpoint (); + + fprintf_unfiltered (gdb_stdlog, + "STOPPED_BY_WATCHPOINT () = %ld\n", + (unsigned long) retval); + return retval; +} + +static CORE_ADDR +debug_to_stopped_data_address (void) +{ + CORE_ADDR retval; + + retval = debug_target.to_stopped_data_address (); + + fprintf_unfiltered (gdb_stdlog, + "target_stopped_data_address () = 0x%lx\n", + (unsigned long) retval); + return retval; +} + +static int +debug_to_insert_hw_breakpoint (CORE_ADDR addr, char *save) +{ + int retval; + + retval = debug_target.to_insert_hw_breakpoint (addr, save); + + fprintf_unfiltered (gdb_stdlog, + "target_insert_hw_breakpoint (0x%lx, xxx) = %ld\n", + (unsigned long) addr, + (unsigned long) retval); + return retval; +} + +static int +debug_to_remove_hw_breakpoint (CORE_ADDR addr, char *save) +{ + int retval; + + retval = debug_target.to_remove_hw_breakpoint (addr, save); + + fprintf_unfiltered (gdb_stdlog, + "target_remove_hw_breakpoint (0x%lx, xxx) = %ld\n", + (unsigned long) addr, + (unsigned long) retval); + return retval; +} + +static int +debug_to_insert_watchpoint (CORE_ADDR addr, int len, int type) +{ + int retval; + + retval = debug_target.to_insert_watchpoint (addr, len, type); + + fprintf_unfiltered (gdb_stdlog, + "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n", + (unsigned long) addr, len, type, (unsigned long) retval); + return retval; +} + +static int +debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type) +{ + int retval; + + retval = debug_target.to_insert_watchpoint (addr, len, type); + + fprintf_unfiltered (gdb_stdlog, + "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n", + (unsigned long) addr, len, type, (unsigned long) retval); + return retval; +} + static void debug_to_terminal_init (void) { @@ -1791,6 +2027,14 @@ debug_to_terminal_ours (void) fprintf_unfiltered (gdb_stdlog, "target_terminal_ours ()\n"); } +static void +debug_to_terminal_save_ours (void) +{ + debug_target.to_terminal_save_ours (); + + fprintf_unfiltered (gdb_stdlog, "target_terminal_save_ours ()\n"); +} + static void debug_to_terminal_info (char *arg, int from_tty) { @@ -1855,24 +2099,6 @@ debug_to_acknowledge_created_inferior (int pid) pid); } -static void -debug_to_clone_and_follow_inferior (int child_pid, int *followed_child) -{ - debug_target.to_clone_and_follow_inferior (child_pid, followed_child); - - fprintf_unfiltered (gdb_stdlog, - "target_clone_and_follow_inferior (%d, %d)\n", - child_pid, *followed_child); -} - -static void -debug_to_post_follow_inferior_by_clone (void) -{ - debug_target.to_post_follow_inferior_by_clone (); - - fprintf_unfiltered (gdb_stdlog, "target_post_follow_inferior_by_clone ()\n"); -} - static int debug_to_insert_fork_catchpoint (int pid) { @@ -1926,53 +2152,14 @@ debug_to_remove_vfork_catchpoint (int pid) } static int -debug_to_has_forked (int pid, int *child_pid) +debug_to_follow_fork (int follow_child) { - int has_forked; + int retval = debug_target.to_follow_fork (follow_child); - has_forked = debug_target.to_has_forked (pid, child_pid); + fprintf_unfiltered (gdb_stdlog, "target_follow_fork (%d) = %d\n", + follow_child, retval); - fprintf_unfiltered (gdb_stdlog, "target_has_forked (%d, %d) = %d\n", - pid, *child_pid, has_forked); - - return has_forked; -} - -static int -debug_to_has_vforked (int pid, int *child_pid) -{ - int has_vforked; - - has_vforked = debug_target.to_has_vforked (pid, child_pid); - - fprintf_unfiltered (gdb_stdlog, "target_has_vforked (%d, %d) = %d\n", - pid, *child_pid, has_vforked); - - return has_vforked; -} - -static int -debug_to_can_follow_vfork_prior_to_exec (void) -{ - int can_immediately_follow_vfork; - - can_immediately_follow_vfork = debug_target.to_can_follow_vfork_prior_to_exec (); - - fprintf_unfiltered (gdb_stdlog, "target_can_follow_vfork_prior_to_exec () = %d\n", - can_immediately_follow_vfork); - - return can_immediately_follow_vfork; -} - -static void -debug_to_post_follow_vfork (int parent_pid, int followed_parent, int child_pid, - int followed_child) -{ - debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child); - - fprintf_unfiltered (gdb_stdlog, - "target_post_follow_vfork (%d, %d, %d, %d)\n", - parent_pid, followed_parent, child_pid, followed_child); + return retval; } static int @@ -2001,20 +2188,6 @@ debug_to_remove_exec_catchpoint (int pid) return retval; } -static int -debug_to_has_execd (int pid, char **execd_pathname) -{ - int has_execd; - - has_execd = debug_target.to_has_execd (pid, execd_pathname); - - fprintf_unfiltered (gdb_stdlog, "target_has_execd (%d, %s) = %d\n", - pid, (*execd_pathname ? *execd_pathname : ""), - has_execd); - - return has_execd; -} - static int debug_to_reported_exec_events_per_exec_call (void) { @@ -2029,36 +2202,6 @@ debug_to_reported_exec_events_per_exec_call (void) return reported_exec_events; } -static int -debug_to_has_syscall_event (int pid, enum target_waitkind *kind, - int *syscall_id) -{ - int has_syscall_event; - char *kind_spelling = "??"; - - has_syscall_event = debug_target.to_has_syscall_event (pid, kind, syscall_id); - if (has_syscall_event) - { - switch (*kind) - { - case TARGET_WAITKIND_SYSCALL_ENTRY: - kind_spelling = "SYSCALL_ENTRY"; - break; - case TARGET_WAITKIND_SYSCALL_RETURN: - kind_spelling = "SYSCALL_RETURN"; - break; - default: - break; - } - } - - fprintf_unfiltered (gdb_stdlog, - "target_has_syscall_event (%d, %s, %d) = %d\n", - pid, kind_spelling, *syscall_id, has_syscall_event); - - return has_syscall_event; -} - static int debug_to_has_exited (int pid, int wait_status, int *exit_status) { @@ -2130,14 +2273,21 @@ debug_to_stop (void) fprintf_unfiltered (gdb_stdlog, "target_stop ()\n"); } -static int -debug_to_query (int type, char *req, char *resp, int *siz) +static LONGEST +debug_to_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, const void *writebuf, + ULONGEST offset, LONGEST len) { - int retval; + LONGEST retval; - retval = debug_target.to_query (type, req, resp, siz); + retval = debug_target.to_xfer_partial (&debug_target, object, annex, + readbuf, writebuf, offset, len); - fprintf_unfiltered (gdb_stdlog, "target_query (%c, %s, %s, %d) = %d\n", type, req, resp, *siz, retval); + fprintf_unfiltered (gdb_stdlog, + "target_xfer_partial (%d, %s, 0x%lx, 0x%lx, 0x%s, %s) = %s\n", + (int) object, (annex ? annex : "(null)"), + (long) readbuf, (long) writebuf, paddr_nz (offset), + paddr_d (len), paddr_d (retval)); return retval; } @@ -2192,9 +2342,8 @@ setup_target_debug (void) current_target.to_close = debug_to_close; current_target.to_attach = debug_to_attach; current_target.to_post_attach = debug_to_post_attach; - current_target.to_require_attach = debug_to_require_attach; current_target.to_detach = debug_to_detach; - current_target.to_require_detach = debug_to_require_detach; + current_target.to_disconnect = debug_to_disconnect; current_target.to_resume = debug_to_resume; current_target.to_wait = debug_to_wait; current_target.to_post_wait = debug_to_post_wait; @@ -2205,10 +2354,19 @@ setup_target_debug (void) current_target.to_files_info = debug_to_files_info; current_target.to_insert_breakpoint = debug_to_insert_breakpoint; current_target.to_remove_breakpoint = debug_to_remove_breakpoint; + current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint; + current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint; + current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint; + current_target.to_insert_watchpoint = debug_to_insert_watchpoint; + current_target.to_remove_watchpoint = debug_to_remove_watchpoint; + current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint; + current_target.to_stopped_data_address = debug_to_stopped_data_address; + current_target.to_region_size_ok_for_hw_watchpoint = debug_to_region_size_ok_for_hw_watchpoint; current_target.to_terminal_init = debug_to_terminal_init; current_target.to_terminal_inferior = debug_to_terminal_inferior; current_target.to_terminal_ours_for_output = debug_to_terminal_ours_for_output; current_target.to_terminal_ours = debug_to_terminal_ours; + current_target.to_terminal_save_ours = debug_to_terminal_save_ours; current_target.to_terminal_info = debug_to_terminal_info; current_target.to_kill = debug_to_kill; current_target.to_load = debug_to_load; @@ -2216,21 +2374,14 @@ setup_target_debug (void) current_target.to_create_inferior = debug_to_create_inferior; current_target.to_post_startup_inferior = debug_to_post_startup_inferior; current_target.to_acknowledge_created_inferior = debug_to_acknowledge_created_inferior; - current_target.to_clone_and_follow_inferior = debug_to_clone_and_follow_inferior; - current_target.to_post_follow_inferior_by_clone = debug_to_post_follow_inferior_by_clone; current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint; current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint; current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint; current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint; - current_target.to_has_forked = debug_to_has_forked; - current_target.to_has_vforked = debug_to_has_vforked; - current_target.to_can_follow_vfork_prior_to_exec = debug_to_can_follow_vfork_prior_to_exec; - current_target.to_post_follow_vfork = debug_to_post_follow_vfork; + current_target.to_follow_fork = debug_to_follow_fork; current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint; current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint; - current_target.to_has_execd = debug_to_has_execd; current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call; - current_target.to_has_syscall_event = debug_to_has_syscall_event; current_target.to_has_exited = debug_to_has_exited; current_target.to_mourn_inferior = debug_to_mourn_inferior; current_target.to_can_run = debug_to_can_run; @@ -2238,7 +2389,7 @@ setup_target_debug (void) current_target.to_thread_alive = debug_to_thread_alive; current_target.to_find_new_threads = debug_to_find_new_threads; current_target.to_stop = debug_to_stop; - current_target.to_query = debug_to_query; + current_target.to_xfer_partial = debug_to_xfer_partial; current_target.to_rcmd = debug_to_rcmd; current_target.to_enable_exception_callback = debug_to_enable_exception_callback; current_target.to_get_current_exception_event = debug_to_get_current_exception_event; @@ -2283,16 +2434,15 @@ initialize_targets (void) When non-zero, target debugging is enabled.", &setdebuglist), &showdebuglist); - add_show_from_set - (add_set_boolean_cmd - ("trust-readonly-sections", class_support, - &trust_readonly, - "Set mode for reading from readonly sections.\n\ + add_setshow_boolean_cmd ("trust-readonly-sections", class_support, + &trust_readonly, "\ +Set mode for reading from readonly sections.\n\ When this mode is on, memory reads from readonly sections (such as .text)\n\ will be read from the object file instead of from the target. This will\n\ -result in significant performance improvement for remote targets.", - &setlist), - &showlist); +result in significant performance improvement for remote targets.", "\ +Show mode for reading from readonly sections.\n", + NULL, NULL, + &setlist, &showlist); add_com ("monitor", class_obscure, do_monitor_command, "Send a command to the remote monitor (remote targets only)."); diff --git a/contrib/gdb/gdb/target.h b/contrib/gdb/gdb/target.h index b5d036ba5de..2d8ce372fc5 100644 --- a/contrib/gdb/gdb/target.h +++ b/contrib/gdb/gdb/target.h @@ -1,6 +1,8 @@ /* Interface between GDB and target environments, including files and processes - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002 Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Support. Written by John Gilmore. This file is part of GDB. @@ -23,13 +25,18 @@ #if !defined (TARGET_H) #define TARGET_H +struct objfile; +struct ui_file; +struct mem_attrib; +struct target_ops; + /* This include file defines the interface between the main part of the debugger, and the part which is target-specific, or specific to the communications interface between us and the target. - A TARGET is an interface between the debugger and a particular - kind of file or process. Targets can be STACKED in STRATA, + A TARGET is an interface between the debugger and a particular + kind of file or process. Targets can be STACKED in STRATA, so that more than one target can potentially respond to a request. In particular, memory accesses will walk down the stack of targets until they find a target that is interested in handling that particular @@ -112,8 +119,8 @@ enum target_waitkind inferior. */ TARGET_WAITKIND_SPURIOUS, - /* This is used for target async and extended-async - only. Remote_async_wait() returns this when there is an event + /* An event has occured, but we should wait again. + Remote_async_wait() returns this when there is an event on the inferior, but the rest of the world is not interested in it. The inferior has not stopped, but has just sent some output to the console, for instance. In this case, we want to go back @@ -148,7 +155,7 @@ enum inferior_event_type INF_QUIT_REQ, /* Process a normal inferior event which will result in target_wait being called. */ - INF_REG_EVENT, + INF_REG_EVENT, /* Deal with an error on the inferior. */ INF_ERROR, /* We are called because a timer went off. */ @@ -171,6 +178,95 @@ extern char *target_signal_to_name (enum target_signal); /* Given a name (SIGHUP, etc.), return its signal. */ enum target_signal target_signal_from_name (char *); +/* Request the transfer of up to LEN 8-bit bytes of the target's + OBJECT. The OFFSET, for a seekable object, specifies the starting + point. The ANNEX can be used to provide additional data-specific + information to the target. + + Return the number of bytes actually transfered, zero when no + further transfer is possible, and -1 when the transfer is not + supported. + + NOTE: cagney/2003-10-17: The current interface does not support a + "retry" mechanism. Instead it assumes that at least one byte will + be transfered on each call. + + NOTE: cagney/2003-10-17: The current interface can lead to + fragmented transfers. Lower target levels should not implement + hacks, such as enlarging the transfer, in an attempt to compensate + for this. Instead, the target stack should be extended so that it + implements supply/collect methods and a look-aside object cache. + With that available, the lowest target can safely and freely "push" + data up the stack. + + NOTE: cagney/2003-10-17: Unlike the old query and the memory + transfer mechanisms, these methods are explicitly parameterized by + the target that it should be applied to. + + NOTE: cagney/2003-10-17: Just like the old query and memory xfer + methods, these new methods perform partial transfers. The only + difference is that these new methods thought to include "partial" + in the name. The old code's failure to do this lead to much + confusion and duplication of effort as each target object attempted + to locally take responsibility for something it didn't have to + worry about. + + NOTE: cagney/2003-10-17: With a TARGET_OBJECT_KOD object, for + backward compatibility with the "target_query" method that this + replaced, when OFFSET and LEN are both zero, return the "minimum" + buffer size. See "remote.c" for further information. */ + +enum target_object +{ + /* Kernel Object Display transfer. See "kod.c" and "remote.c". */ + TARGET_OBJECT_KOD, + /* AVR target specific transfer. See "avr-tdep.c" and "remote.c". */ + TARGET_OBJECT_AVR, + /* Transfer up-to LEN bytes of memory starting at OFFSET. */ + TARGET_OBJECT_MEMORY, + /* Kernel Unwind Table. See "ia64-tdep.c". */ + TARGET_OBJECT_UNWIND_TABLE, + /* Transfer auxilliary vector. */ + TARGET_OBJECT_AUXV, + /* StackGhost cookie. See "sparc-tdep.c". */ + TARGET_OBJECT_WCOOKIE + + /* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */ +}; + +extern LONGEST target_read_partial (struct target_ops *ops, + enum target_object object, + const char *annex, void *buf, + ULONGEST offset, LONGEST len); + +extern LONGEST target_write_partial (struct target_ops *ops, + enum target_object object, + const char *annex, const void *buf, + ULONGEST offset, LONGEST len); + +/* Wrappers to perform the full transfer. */ +extern LONGEST target_read (struct target_ops *ops, + enum target_object object, + const char *annex, void *buf, + ULONGEST offset, LONGEST len); + +extern LONGEST target_write (struct target_ops *ops, + enum target_object object, + const char *annex, const void *buf, + ULONGEST offset, LONGEST len); + +/* Wrappers to target read/write that perform memory transfers. They + throw an error if the memory transfer fails. + + NOTE: cagney/2003-10-23: The naming schema is lifted from + "frame.h". The parameter order is lifted from get_frame_memory, + which in turn lifted it from read_memory. */ + +extern void get_target_memory (struct target_ops *ops, CORE_ADDR addr, + void *buf, LONGEST len); +extern ULONGEST get_target_memory_unsigned (struct target_ops *ops, + CORE_ADDR addr, int len); + /* If certain kinds of activity happen, target_wait should perform callbacks. */ @@ -184,18 +280,28 @@ struct thread_info; /* fwd decl for parameter list below: */ struct target_ops { + struct target_ops *beneath; /* To the target under this one. */ char *to_shortname; /* Name this target type */ char *to_longname; /* Name for printing */ char *to_doc; /* Documentation. Does not include trailing newline, and starts with a one-line descrip- tion (probably similar to to_longname). */ + /* Per-target scratch pad. */ + void *to_data; + /* The open routine takes the rest of the parameters from the + command, and (if successful) pushes a new target onto the + stack. Targets should supply this routine, if only to provide + an error message. */ void (*to_open) (char *, int); + /* Old targets with a static target vector provide "to_close". + New re-entrant targets provide "to_xclose" and that is expected + to xfree everything (including the "struct target_ops"). */ + void (*to_xclose) (struct target_ops *targ, int quitting); void (*to_close) (int); void (*to_attach) (char *, int); void (*to_post_attach) (int); - void (*to_require_attach) (char *, int); void (*to_detach) (char *, int); - void (*to_require_detach) (int, char *, int); + void (*to_disconnect) (char *, int); void (*to_resume) (ptid_t, int, enum target_signal); ptid_t (*to_wait) (ptid_t, struct target_waitstatus *); void (*to_post_wait) (ptid_t, int); @@ -222,40 +328,27 @@ struct target_ops something at MEMADDR + N. */ int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr, - int len, int write, + int len, int write, struct mem_attrib *attrib, struct target_ops *target); -#if 0 - /* Enable this after 4.12. */ - - /* Search target memory. Start at STARTADDR and take LEN bytes of - target memory, and them with MASK, and compare to DATA. If they - match, set *ADDR_FOUND to the address we found it at, store the data - we found at LEN bytes starting at DATA_FOUND, and return. If - not, add INCREMENT to the search address and keep trying until - the search address is outside of the range [LORANGE,HIRANGE). - - If we don't find anything, set *ADDR_FOUND to (CORE_ADDR)0 and - return. */ - - void (*to_search) (int len, char *data, char *mask, - CORE_ADDR startaddr, int increment, - CORE_ADDR lorange, CORE_ADDR hirange, - CORE_ADDR * addr_found, char *data_found); - -#define target_search(len, data, mask, startaddr, increment, lorange, hirange, addr_found, data_found) \ - (*current_target.to_search) (len, data, mask, startaddr, increment, \ - lorange, hirange, addr_found, data_found) -#endif /* 0 */ - void (*to_files_info) (struct target_ops *); int (*to_insert_breakpoint) (CORE_ADDR, char *); int (*to_remove_breakpoint) (CORE_ADDR, char *); + int (*to_can_use_hw_breakpoint) (int, int, int); + int (*to_insert_hw_breakpoint) (CORE_ADDR, char *); + int (*to_remove_hw_breakpoint) (CORE_ADDR, char *); + int (*to_remove_watchpoint) (CORE_ADDR, int, int); + int (*to_insert_watchpoint) (CORE_ADDR, int, int); + int (*to_stopped_by_watchpoint) (void); + int to_have_continuable_watchpoint; + CORE_ADDR (*to_stopped_data_address) (void); + int (*to_region_size_ok_for_hw_watchpoint) (int); void (*to_terminal_init) (void); void (*to_terminal_inferior) (void); void (*to_terminal_ours_for_output) (void); void (*to_terminal_ours) (void); + void (*to_terminal_save_ours) (void); void (*to_terminal_info) (char *, int); void (*to_kill) (void); void (*to_load) (char *, int); @@ -263,21 +356,14 @@ struct target_ops void (*to_create_inferior) (char *, char *, char **); void (*to_post_startup_inferior) (ptid_t); void (*to_acknowledge_created_inferior) (int); - void (*to_clone_and_follow_inferior) (int, int *); - void (*to_post_follow_inferior_by_clone) (void); int (*to_insert_fork_catchpoint) (int); int (*to_remove_fork_catchpoint) (int); int (*to_insert_vfork_catchpoint) (int); int (*to_remove_vfork_catchpoint) (int); - int (*to_has_forked) (int, int *); - int (*to_has_vforked) (int, int *); - int (*to_can_follow_vfork_prior_to_exec) (void); - void (*to_post_follow_vfork) (int, int, int, int); + int (*to_follow_fork) (int); int (*to_insert_exec_catchpoint) (int); int (*to_remove_exec_catchpoint) (int); - int (*to_has_execd) (int, char **); int (*to_reported_exec_events_per_exec_call) (void); - int (*to_has_syscall_event) (int, enum target_waitkind *, int *); int (*to_has_exited) (int, int, int *); void (*to_mourn_inferior) (void); int (*to_can_run) (void); @@ -287,7 +373,6 @@ struct target_ops char *(*to_pid_to_str) (ptid_t); char *(*to_extra_thread_info) (struct thread_info *); void (*to_stop) (void); - int (*to_query) (int /*char */ , char *, char *, int *); void (*to_rcmd) (char *command, struct ui_file *output); struct symtab_and_line *(*to_enable_exception_callback) (enum exception_event_kind, @@ -295,8 +380,6 @@ struct target_ops struct exception_event_record *(*to_get_current_exception_event) (void); char *(*to_pid_to_exec_file) (int pid); enum strata to_stratum; - struct target_ops - *DONT_USE; /* formerly to_next */ int to_has_all_memory; int to_has_memory; int to_has_stack; @@ -313,12 +396,30 @@ struct target_ops void (*to_async) (void (*cb) (enum inferior_event_type, void *context), void *context); int to_async_mask_value; - int (*to_find_memory_regions) (int (*) (CORE_ADDR, - unsigned long, - int, int, int, - void *), + int (*to_find_memory_regions) (int (*) (CORE_ADDR, + unsigned long, + int, int, int, + void *), void *); char * (*to_make_corefile_notes) (bfd *, int *); + + /* Return the thread-local address at OFFSET in the + thread-local storage for the thread PTID and the shared library + or executable file given by OBJFILE. If that block of + thread-local storage hasn't been allocated yet, this function + may return an error. */ + CORE_ADDR (*to_get_thread_local_address) (ptid_t ptid, + struct objfile *objfile, + CORE_ADDR offset); + + /* Perform partial transfers on OBJECT. See target_read_partial + and target_write_partial for details of each variant. One, and + only one, of readbuf or writebuf must be non-NULL. */ + LONGEST (*to_xfer_partial) (struct target_ops *ops, + enum target_object object, const char *annex, + void *readbuf, const void *writebuf, + ULONGEST offset, LONGEST len); + int to_magic; /* Need sub-structure for target machine related rather than comm related? */ @@ -335,50 +436,28 @@ struct target_ops extern struct target_ops current_target; -/* An item on the target stack. */ - -struct target_stack_item - { - struct target_stack_item *next; - struct target_ops *target_ops; - }; - -/* The target stack. */ - -extern struct target_stack_item *target_stack; - /* Define easy words for doing these operations on our current target. */ #define target_shortname (current_target.to_shortname) #define target_longname (current_target.to_longname) -/* The open routine takes the rest of the parameters from the command, - and (if successful) pushes a new target onto the stack. - Targets should supply this routine, if only to provide an error message. */ +/* Does whatever cleanup is required for a target that we are no + longer going to be calling. QUITTING indicates that GDB is exiting + and should not get hung on an error (otherwise it is important to + perform clean termination, even if it takes a while). This routine + is automatically always called when popping the target off the + target stack (to_beneath is undefined). Closing file descriptors + and freeing all memory allocated memory are typical things it + should do. */ -#define target_open(name, from_tty) \ - do { \ - dcache_invalidate (target_dcache); \ - (*current_target.to_open) (name, from_tty); \ - } while (0) - -/* Does whatever cleanup is required for a target that we are no longer - going to be calling. Argument says whether we are quitting gdb and - should not get hung in case of errors, or whether we want a clean - termination even if it takes a while. This routine is automatically - always called just before a routine is popped off the target stack. - Closing file descriptors and freeing memory are typical things it should - do. */ - -#define target_close(quitting) \ - (*current_target.to_close) (quitting) +void target_close (struct target_ops *targ, int quitting); /* Attaches to a process on the target side. Arguments are as passed to the `attach' command by the user. This routine can be called when the target is not on the target-stack, if the target_can_run - routine returns 1; in that case, it must push itself onto the stack. + routine returns 1; in that case, it must push itself onto the stack. Upon exit, the target should be ready for normal operations, and - should be ready to deliver the status of the process immediately + should be ready to deliver the status of the process immediately (without waiting) to an upcoming target_wait call. */ #define target_attach(args, from_tty) \ @@ -392,17 +471,6 @@ extern struct target_stack_item *target_stack; #define target_post_attach(pid) \ (*current_target.to_post_attach) (pid) -/* Attaches to a process on the target side, if not already attached. - (If already attached, takes no action.) - - This operation can be used to follow the child process of a fork. - On some targets, such child processes of an original inferior process - are automatically under debugger control, and thus do not require an - actual attach operation. */ - -#define target_require_attach(args, from_tty) \ - (*current_target.to_require_attach) (args, from_tty) - /* Takes a program previously attached to and detaches it. The program may resume execution (some targets do, some don't) and will no longer stop on signals, etc. We better not have left any breakpoints @@ -412,20 +480,10 @@ extern struct target_stack_item *target_stack; extern void target_detach (char *, int); -/* Detaches from a process on the target side, if not already dettached. - (If already detached, takes no action.) +/* Disconnect from the current target without resuming it (leaving it + waiting for a debugger). */ - This operation can be used to follow the parent process of a fork. - On some targets, such child processes of an original inferior process - are automatically under debugger control, and thus do require an actual - detach operation. - - PID is the process id of the child to detach from. - ARGS is arguments typed by the user (e.g. a signal to send the process). - FROM_TTY says whether to be verbose or not. */ - -#define target_require_detach(pid, args, from_tty) \ - (*current_target.to_require_detach) (pid, args, from_tty) +extern void target_disconnect (char *, int); /* Resume execution of the target process PTID. STEP says whether to single-step or to run free; SIGGNAL is the signal to be given to @@ -494,10 +552,10 @@ extern int target_read_memory (CORE_ADDR memaddr, char *myaddr, int len); extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len); -extern int xfer_memory (CORE_ADDR, char *, int, int, +extern int xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *); -extern int child_xfer_memory (CORE_ADDR, char *, int, int, +extern int child_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *); /* Make a single attempt at transfering LEN bytes. On a successful @@ -506,11 +564,11 @@ extern int child_xfer_memory (CORE_ADDR, char *, int, int, of bytes actually transfered is not defined) and ERR is set to a non-zero error indication. */ -extern int -target_read_memory_partial (CORE_ADDR addr, char *buf, int len, int *err); +extern int target_read_memory_partial (CORE_ADDR addr, char *buf, int len, + int *err); -extern int -target_write_memory_partial (CORE_ADDR addr, char *buf, int len, int *err); +extern int target_write_memory_partial (CORE_ADDR addr, char *buf, int len, + int *err); extern char *child_pid_to_exec_file (int); @@ -526,10 +584,6 @@ extern void child_post_startup_inferior (ptid_t); extern void child_acknowledge_created_inferior (int); -extern void child_clone_and_follow_inferior (int, int *); - -extern void child_post_follow_inferior_by_clone (void); - extern int child_insert_fork_catchpoint (int); extern int child_remove_fork_catchpoint (int); @@ -538,30 +592,28 @@ extern int child_insert_vfork_catchpoint (int); extern int child_remove_vfork_catchpoint (int); -extern int child_has_forked (int, int *); - -extern int child_has_vforked (int, int *); - extern void child_acknowledge_created_inferior (int); -extern int child_can_follow_vfork_prior_to_exec (void); - -extern void child_post_follow_vfork (int, int, int, int); +extern int child_follow_fork (int); extern int child_insert_exec_catchpoint (int); extern int child_remove_exec_catchpoint (int); -extern int child_has_execd (int, char **); - extern int child_reported_exec_events_per_exec_call (void); -extern int child_has_syscall_event (int, enum target_waitkind *, int *); - extern int child_has_exited (int, int, int *); extern int child_thread_alive (ptid_t); +/* From infrun.c. */ + +extern int inferior_has_forked (int pid, int *child_pid); + +extern int inferior_has_vforked (int pid, int *child_pid); + +extern int inferior_has_execd (int pid, char **execd_pathname); + /* From exec.c */ extern void print_section_info (struct target_ops *, bfd *); @@ -571,18 +623,18 @@ extern void print_section_info (struct target_ops *, bfd *); #define target_files_info() \ (*current_target.to_files_info) (¤t_target) -/* Insert a breakpoint at address ADDR in the target machine. - SAVE is a pointer to memory allocated for saving the - target contents. It is guaranteed by the caller to be long enough - to save "sizeof BREAKPOINT" bytes. Result is 0 for success, or - an errno value. */ +/* Insert a breakpoint at address ADDR in the target machine. SAVE is + a pointer to memory allocated for saving the target contents. It + is guaranteed by the caller to be long enough to save the number of + breakpoint bytes indicated by BREAKPOINT_FROM_PC. Result is 0 for + success, or an errno value. */ #define target_insert_breakpoint(addr, save) \ (*current_target.to_insert_breakpoint) (addr, save) /* Remove a breakpoint at address ADDR in the target machine. - SAVE is a pointer to the same save area - that was previously passed to target_insert_breakpoint. + SAVE is a pointer to the same save area + that was previously passed to target_insert_breakpoint. Result is 0 for success, or an errno value. */ #define target_remove_breakpoint(addr, save) \ @@ -618,6 +670,14 @@ extern void print_section_info (struct target_ops *, bfd *); #define target_terminal_ours() \ (*current_target.to_terminal_ours) () +/* Save our terminal settings. + This is called from TUI after entering or leaving the curses + mode. Since curses modifies our terminal this call is here + to take this change into account. */ + +#define target_terminal_save_ours() \ + (*current_target.to_terminal_save_ours) () + /* Print useful information about our terminal status, if such a thing exists. */ @@ -675,33 +735,6 @@ extern void target_load (char *arg, int from_tty); #define target_acknowledge_created_inferior(pid) \ (*current_target.to_acknowledge_created_inferior) (pid) -/* An inferior process has been created via a fork() or similar - system call. This function will clone the debugger, then ensure - that CHILD_PID is attached to by that debugger. - - FOLLOWED_CHILD is set TRUE on return *for the clone debugger only*, - and FALSE otherwise. (The original and clone debuggers can use this - to determine which they are, if need be.) - - (This is not a terribly useful feature without a GUI to prevent - the two debuggers from competing for shell input.) */ - -#define target_clone_and_follow_inferior(child_pid,followed_child) \ - (*current_target.to_clone_and_follow_inferior) (child_pid, followed_child) - -/* This operation is intended to be used as the last in a sequence of - steps taken when following both parent and child of a fork. This - is used by a clone of the debugger, which will follow the child. - - The original debugger has detached from this process, and the - clone has attached to it. - - On some targets, this requires a bit of cleanup to make it work - correctly. */ - -#define target_post_follow_inferior_by_clone() \ - (*current_target.to_post_follow_inferior_by_clone) () - /* On some targets, we can catch an inferior fork or vfork event when it occurs. These functions insert/remove an already-created catchpoint for such events. */ @@ -718,42 +751,16 @@ extern void target_load (char *arg, int from_tty); #define target_remove_vfork_catchpoint(pid) \ (*current_target.to_remove_vfork_catchpoint) (pid) -/* Returns TRUE if PID has invoked the fork() system call. And, - also sets CHILD_PID to the process id of the other ("child") - inferior process that was created by that call. */ +/* If the inferior forks or vforks, this function will be called at + the next resume in order to perform any bookkeeping and fiddling + necessary to continue debugging either the parent or child, as + requested, and releasing the other. Information about the fork + or vfork event is available via get_last_target_status (). + This function returns 1 if the inferior should not be resumed + (i.e. there is another event pending). */ -#define target_has_forked(pid,child_pid) \ - (*current_target.to_has_forked) (pid,child_pid) - -/* Returns TRUE if PID has invoked the vfork() system call. And, - also sets CHILD_PID to the process id of the other ("child") - inferior process that was created by that call. */ - -#define target_has_vforked(pid,child_pid) \ - (*current_target.to_has_vforked) (pid,child_pid) - -/* Some platforms (such as pre-10.20 HP-UX) don't allow us to do - anything to a vforked child before it subsequently calls exec(). - On such platforms, we say that the debugger cannot "follow" the - child until it has vforked. - - This function should be defined to return 1 by those targets - which can allow the debugger to immediately follow a vforked - child, and 0 if they cannot. */ - -#define target_can_follow_vfork_prior_to_exec() \ - (*current_target.to_can_follow_vfork_prior_to_exec) () - -/* An inferior process has been created via a vfork() system call. - The debugger has followed the parent, the child, or both. The - process of setting up for that follow may have required some - target-specific trickery to track the sequence of reported events. - If so, this function should be defined by those targets that - require the debugger to perform cleanup or initialization after - the vfork follow. */ - -#define target_post_follow_vfork(parent_pid,followed_parent,child_pid,followed_child) \ - (*current_target.to_post_follow_vfork) (parent_pid,followed_parent,child_pid,followed_child) +#define target_follow_fork(follow_child) \ + (*current_target.to_follow_fork) (follow_child) /* On some targets, we can catch an inferior exec event when it occurs. These functions insert/remove an already-created @@ -765,13 +772,6 @@ extern void target_load (char *arg, int from_tty); #define target_remove_exec_catchpoint(pid) \ (*current_target.to_remove_exec_catchpoint) (pid) -/* Returns TRUE if PID has invoked a flavor of the exec() system call. - And, also sets EXECD_PATHNAME to the pathname of the executable - file that was passed to exec(), and is now being executed. */ - -#define target_has_execd(pid,execd_pathname) \ - (*current_target.to_has_execd) (pid,execd_pathname) - /* Returns the number of exec events that are reported when a process invokes a flavor of the exec() system call on this target, if exec events are being reported. */ @@ -779,13 +779,6 @@ extern void target_load (char *arg, int from_tty); #define target_reported_exec_events_per_exec_call() \ (*current_target.to_reported_exec_events_per_exec_call) () -/* Returns TRUE if PID has reported a syscall event. And, also sets - KIND to the appropriate TARGET_WAITKIND_, and sets SYSCALL_ID to - the unique integer ID of the syscall. */ - -#define target_has_syscall_event(pid,kind,syscall_id) \ - (*current_target.to_has_syscall_event) (pid,kind,syscall_id) - /* Returns TRUE if PID has exited. And, also sets EXIT_STATUS to the exit code of PID, if any. */ @@ -793,7 +786,7 @@ extern void target_load (char *arg, int from_tty); (*current_target.to_has_exited) (pid,wait_status,exit_status) /* The debugger has completed a blocking wait() call. There is now - some process event that must be processed. This function should + some process event that must be processed. This function should be defined by those targets that require the debugger to perform cleanup or internal state changes in response to the process event. */ @@ -828,16 +821,6 @@ extern void target_load (char *arg, int from_tty); #define target_stop current_target.to_stop -/* Queries the target side for some information. The first argument is a - letter specifying the type of the query, which is used to determine who - should process it. The second argument is a string that specifies which - information is desired and the third is a buffer that carries back the - response from the target side. The fourth parameter is the size of the - output buffer supplied. */ - -#define target_query(query_type, query, resp_buffer, bufffer_size) \ - (*current_target.to_query) (query_type, query, resp_buffer, bufffer_size) - /* Send the specified COMMAND to the target's monitor (shell,interpreter) for execution. The result of the query is placed in OUTBUF. */ @@ -847,7 +830,7 @@ extern void target_load (char *arg, int from_tty); /* Get the symbol information for a breakpointable routine called when - an exception event occurs. + an exception event occurs. Intended mainly for C++, and for those platforms/implementations where such a callback mechanism is available, e.g. HP-UX with ANSI C++ (aCC). Some compilers (e.g. g++) support @@ -861,11 +844,6 @@ extern void target_load (char *arg, int from_tty); #define target_get_current_exception_event() \ (*current_target.to_get_current_exception_event) () -/* Pointer to next target in the chain, e.g. a core file and an exec file. */ - -#define target_next \ - (current_target.to_next) - /* Does the target include all of memory, or only part of it? This determines whether we look up the target chain for other parts of memory if this target can't satisfy a request. */ @@ -919,15 +897,15 @@ extern void target_load (char *arg, int from_tty); #define target_async(CALLBACK,CONTEXT) \ (current_target.to_async((CALLBACK), (CONTEXT))) -/* This is to be used ONLY within run_stack_dummy(). It - provides a workaround, to have inferior function calls done in - sychronous mode, even though the target is asynchronous. After +/* This is to be used ONLY within call_function_by_hand(). It provides + a workaround, to have inferior function calls done in sychronous + mode, even though the target is asynchronous. After target_async_mask(0) is called, calls to target_can_async_p() will return FALSE , so that target_resume() will not try to start the target asynchronously. After the inferior stops, we IMMEDIATELY restore the previous nature of the target, by calling target_async_mask(1). After that, target_can_async_p() will return - TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED. + TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED. FIXME ezannoni 1999-12-13: we won't need this once we move the turning async on and off to the single execution commands, @@ -936,7 +914,7 @@ extern void target_load (char *arg, int from_tty); #define target_async_mask_value \ (current_target.to_async_mask_value) -extern int target_async_mask (int mask); +extern int target_async_mask (int mask); extern void target_link (char *, CORE_ADDR *); @@ -964,7 +942,7 @@ extern char *normal_pid_to_str (ptid_t ptid); * New Objfile Event Hook: * * Sometimes a GDB component wants to get notified whenever a new - * objfile is loaded. Mainly this is used by thread-debugging + * objfile is loaded. Mainly this is used by thread-debugging * implementations that need to know when symbols for the target * thread implemenation are available. * @@ -1009,7 +987,7 @@ extern void (*target_new_objfile_hook) (struct objfile *); * Iterator function for target memory regions. * Calls a callback function once for each memory region 'mapped' * in the child process. Defined as a simple macro rather than - * as a function macro so that it can be tested for nullity. + * as a function macro so that it can be tested for nullity. */ #define target_find_memory_regions(FUNC, DATA) \ @@ -1022,11 +1000,11 @@ extern void (*target_new_objfile_hook) (struct objfile *); #define target_make_corefile_notes(BFD, SIZE_P) \ (current_target.to_make_corefile_notes) (BFD, SIZE_P) -/* Hook to call target-dependent code after reading in a new symbol table. */ - -#ifndef TARGET_SYMFILE_POSTREAD -#define TARGET_SYMFILE_POSTREAD(OBJFILE) -#endif +/* Thread-local values. */ +#define target_get_thread_local_address \ + (current_target.to_get_thread_local_address) +#define target_get_thread_local_address_p() \ + (target_get_thread_local_address != NULL) /* Hook to call target dependent code just after inferior target process has started. */ @@ -1041,7 +1019,15 @@ extern void (*target_new_objfile_hook) (struct objfile *); write). */ #ifndef STOPPED_BY_WATCHPOINT -#define STOPPED_BY_WATCHPOINT(w) 0 +#define STOPPED_BY_WATCHPOINT(w) \ + (*current_target.to_stopped_by_watchpoint) () +#endif + +/* Non-zero if we have continuable watchpoints */ + +#ifndef HAVE_CONTINUABLE_WATCHPOINT +#define HAVE_CONTINUABLE_WATCHPOINT \ + (current_target.to_have_continuable_watchpoint) #endif /* HP-UX supplies these operations, which respectively disable and enable @@ -1056,20 +1042,24 @@ extern void (*target_new_objfile_hook) (struct objfile *); #define TARGET_ENABLE_HW_WATCHPOINTS(pid) #endif -/* Provide defaults for systems that don't support hardware watchpoints. */ +/* Provide defaults for hardware watchpoint functions. */ -#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS +/* If the *_hw_beakpoint functions have not been defined + elsewhere use the definitions in the target vector. */ /* Returns non-zero if we can set a hardware watchpoint of type TYPE. TYPE is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint. CNT is the number of such watchpoints used so far (including this one?). OTHERTYPE is who knows what... */ -#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0 +#ifndef TARGET_CAN_USE_HARDWARE_WATCHPOINT +#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) \ + (*current_target.to_can_use_hw_breakpoint) (TYPE, CNT, OTHERTYPE); +#endif #if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT) #define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \ - ((LONGEST)(byte_count) <= REGISTER_SIZE) + (*current_target.to_region_size_ok_for_hw_watchpoint) (byte_count) #endif @@ -1077,25 +1067,25 @@ extern void (*target_new_objfile_hook) (struct objfile *); for write, 1 for read, and 2 for read/write accesses. Returns 0 for success, non-zero for failure. */ -#define target_remove_watchpoint(ADDR,LEN,TYPE) -1 -#define target_insert_watchpoint(ADDR,LEN,TYPE) -1 +#ifndef target_insert_watchpoint +#define target_insert_watchpoint(addr, len, type) \ + (*current_target.to_insert_watchpoint) (addr, len, type) -#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */ +#define target_remove_watchpoint(addr, len, type) \ + (*current_target.to_remove_watchpoint) (addr, len, type) +#endif #ifndef target_insert_hw_breakpoint -#define target_remove_hw_breakpoint(ADDR,SHADOW) -1 -#define target_insert_hw_breakpoint(ADDR,SHADOW) -1 +#define target_insert_hw_breakpoint(addr, save) \ + (*current_target.to_insert_hw_breakpoint) (addr, save) + +#define target_remove_hw_breakpoint(addr, save) \ + (*current_target.to_remove_hw_breakpoint) (addr, save) #endif #ifndef target_stopped_data_address -#define target_stopped_data_address() 0 -#endif - -/* If defined, then we need to decr pc by this much after a hardware break- - point. Presumably this overrides DECR_PC_AFTER_BREAK... */ - -#ifndef DECR_PC_AFTER_HW_BREAK -#define DECR_PC_AFTER_HW_BREAK 0 +#define target_stopped_data_address() \ + (*current_target.to_stopped_data_address) () #endif /* Sometimes gdb may pick up what appears to be a valid target address @@ -1163,16 +1153,15 @@ struct section_table CORE_ADDR addr; /* Lowest address in section */ CORE_ADDR endaddr; /* 1+highest address in section */ - sec_ptr the_bfd_section; + struct bfd_section *the_bfd_section; bfd *bfd; /* BFD file pointer */ }; -/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR. - Returns 0 if OK, 1 on error. */ +/* Return the "section" containing the specified address. */ +struct section_table *target_section_by_addr (struct target_ops *target, + CORE_ADDR addr); -extern int -build_section_table (bfd *, struct section_table **, struct section_table **); /* From mem-break.c */ @@ -1184,8 +1173,6 @@ extern int default_memory_remove_breakpoint (CORE_ADDR, char *); extern int default_memory_insert_breakpoint (CORE_ADDR, char *); -extern breakpoint_from_pc_fn memory_breakpoint_from_pc; - /* From target.c */ @@ -1195,22 +1182,16 @@ extern void noprocess (void); extern void find_default_attach (char *, int); -extern void find_default_require_attach (char *, int); - -extern void find_default_require_detach (int, char *, int); - extern void find_default_create_inferior (char *, char *, char **); -extern void find_default_clone_and_follow_inferior (int, int *); - extern struct target_ops *find_run_target (void); extern struct target_ops *find_core_target (void); extern struct target_ops *find_target_beneath (struct target_ops *); -extern int -target_resize_to_sections (struct target_ops *target, int num_added); +extern int target_resize_to_sections (struct target_ops *target, + int num_added); extern void remove_target_sections (bfd *abfd); diff --git a/contrib/gdb/gdb/thread-db.c b/contrib/gdb/gdb/thread-db.c index 2e7620ec48d..804f48a8073 100644 --- a/contrib/gdb/gdb/thread-db.c +++ b/contrib/gdb/gdb/thread-db.c @@ -1,5 +1,6 @@ /* libthread_db assisted debugging support, generic parts. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -32,6 +33,7 @@ #include "objfiles.h" #include "target.h" #include "regcache.h" +#include "solib-svr4.h" #ifndef LIBTHREAD_DB_SO #define LIBTHREAD_DB_SO "libthread_db.so.1" @@ -52,7 +54,7 @@ static struct target_ops thread_db_ops; static struct target_ops *target_beneath; /* Pointer to the next function on the objfile event chain. */ -static void (*target_new_objfile_chain) (struct objfile *objfile); +static void (*target_new_objfile_chain) (struct objfile * objfile); /* Non-zero if we're using this module's target vector. */ static int using_thread_db; @@ -78,15 +80,16 @@ static td_thragent_t *thread_agent; static td_err_e (*td_init_p) (void); -static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta); +static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps, + td_thragent_t **ta); static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt, td_thrhandle_t *__th); -static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid, - td_thrhandle_t *th); +static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, + lwpid_t lwpid, td_thrhandle_t *th); static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta, - td_thr_iter_f *callback, - void *cbdata_p, td_thr_state_e state, - int ti_pri, sigset_t *ti_sigmask_p, + td_thr_iter_f *callback, void *cbdata_p, + td_thr_state_e state, int ti_pri, + sigset_t *ti_sigmask_p, unsigned int ti_user_flags); static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta, td_event_e event, td_notify_t *ptr); @@ -106,7 +109,12 @@ static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th, const gdb_prfpregset_t *fpregs); static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th, prgregset_t gregs); -static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event); +static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, + int event); + +static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th, + void *map_address, + size_t offset, void **address); /* Location of the thread creation event breakpoint. The code at this location in the child process will be called by the pthread library @@ -120,6 +128,8 @@ static CORE_ADDR td_death_bp_addr; /* Prototypes for local functions. */ static void thread_db_find_new_threads (void); +static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, + const td_thrinfo_t *ti_p, int verbose); /* Building process ids. */ @@ -135,10 +145,17 @@ static void thread_db_find_new_threads (void); #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid) +/* Use "struct private_thread_info" to cache thread state. This is + a substantial optimization. */ + struct private_thread_info { - /* Cached LWP id. Must come first, see lin-lwp.c. */ - lwpid_t lwpid; + /* Cached thread state. */ + unsigned int th_valid:1; + unsigned int ti_valid:1; + + td_thrhandle_t th; + td_thrinfo_t ti; }; @@ -222,15 +239,102 @@ thread_db_state_str (td_thr_state_e state) } } +/* A callback function for td_ta_thr_iter, which we use to map all + threads to LWPs. + THP is a handle to the current thread; if INFOP is not NULL, the + struct thread_info associated with this thread is returned in + *INFOP. */ + +static int +thread_get_info_callback (const td_thrhandle_t *thp, void *infop) +{ + td_thrinfo_t ti; + td_err_e err; + struct thread_info *thread_info; + ptid_t thread_ptid; + + err = td_thr_get_info_p (thp, &ti); + if (err != TD_OK) + error ("thread_get_info_callback: cannot get thread info: %s", + thread_db_err_str (err)); + + /* Fill the cache. */ + thread_ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid)); + thread_info = find_thread_pid (thread_ptid); + + if (thread_info == NULL) + { + /* New thread. Attach to it now (why wait?). */ + attach_thread (thread_ptid, thp, &ti, 1); + thread_info = find_thread_pid (thread_ptid); + gdb_assert (thread_info != NULL); + } + + memcpy (&thread_info->private->th, thp, sizeof (*thp)); + thread_info->private->th_valid = 1; + memcpy (&thread_info->private->ti, &ti, sizeof (ti)); + thread_info->private->ti_valid = 1; + + if (infop != NULL) + *(struct thread_info **) infop = thread_info; + + return 0; +} + +/* Accessor functions for the thread_db information, with caching. */ + +static void +thread_db_map_id2thr (struct thread_info *thread_info, int fatal) +{ + td_err_e err; + + if (thread_info->private->th_valid) + return; + + err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid), + &thread_info->private->th); + if (err != TD_OK) + { + if (fatal) + error ("Cannot find thread %ld: %s", + (long) GET_THREAD (thread_info->ptid), + thread_db_err_str (err)); + } + else + thread_info->private->th_valid = 1; +} + +static td_thrinfo_t * +thread_db_get_info (struct thread_info *thread_info) +{ + td_err_e err; + + if (thread_info->private->ti_valid) + return &thread_info->private->ti; + + if (!thread_info->private->th_valid) + thread_db_map_id2thr (thread_info, 1); + + err = + td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti); + if (err != TD_OK) + error ("thread_db_get_info: cannot get thread info: %s", + thread_db_err_str (err)); + + thread_info->private->ti_valid = 1; + return &thread_info->private->ti; +} + /* Convert between user-level thread ids and LWP ids. */ static ptid_t thread_from_lwp (ptid_t ptid) { - td_thrinfo_t ti; td_thrhandle_t th; td_err_e err; + struct thread_info *thread_info; + ptid_t thread_ptid; if (GET_LWP (ptid) == 0) ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid)); @@ -239,36 +343,29 @@ thread_from_lwp (ptid_t ptid) err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th); if (err != TD_OK) - error ("Cannot find user-level thread for LWP %d: %s", + error ("Cannot find user-level thread for LWP %ld: %s", GET_LWP (ptid), thread_db_err_str (err)); - err = td_thr_get_info_p (&th, &ti); - if (err != TD_OK) - error ("Cannot get thread info: %s", thread_db_err_str (err)); + thread_info = NULL; + thread_get_info_callback (&th, &thread_info); + gdb_assert (thread_info && thread_info->private->ti_valid); - return BUILD_THREAD (ti.ti_tid, GET_PID (ptid)); + return BUILD_THREAD (thread_info->private->ti.ti_tid, GET_PID (ptid)); } static ptid_t lwp_from_thread (ptid_t ptid) { - td_thrinfo_t ti; - td_thrhandle_t th; - td_err_e err; + struct thread_info *thread_info; + ptid_t thread_ptid; if (!is_thread (ptid)) return ptid; - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th); - if (err != TD_OK) - error ("Cannot find thread %ld: %s", - (long) GET_THREAD (ptid), thread_db_err_str (err)); + thread_info = find_thread_pid (ptid); + thread_db_get_info (thread_info); - err = td_thr_get_info_p (&th, &ti); - if (err != TD_OK) - error ("Cannot get thread info: %s", thread_db_err_str (err)); - - return BUILD_LWP (ti.ti_lid, GET_PID (ptid)); + return BUILD_LWP (thread_info->private->ti.ti_lid, GET_PID (ptid)); } @@ -278,6 +375,15 @@ thread_db_init (struct target_ops *target) target_beneath = target; } +static void * +verbose_dlsym (void *handle, const char *name) +{ + void *sym = dlsym (handle, name); + if (sym == NULL) + warning ("Symbol \"%s\" not found in libthread_db: %s", name, dlerror ()); + return sym; +} + static int thread_db_load (void) { @@ -286,52 +392,58 @@ thread_db_load (void) handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW); if (handle == NULL) - return 0; + { + fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n", + LIBTHREAD_DB_SO, dlerror ()); + fprintf_filtered (gdb_stderr, + "GDB will not be able to debug pthreads.\n\n"); + return 0; + } /* Initialize pointers to the dynamic library functions we will use. Essential functions first. */ - td_init_p = dlsym (handle, "td_init"); + td_init_p = verbose_dlsym (handle, "td_init"); if (td_init_p == NULL) return 0; - td_ta_new_p = dlsym (handle, "td_ta_new"); + td_ta_new_p = verbose_dlsym (handle, "td_ta_new"); if (td_ta_new_p == NULL) return 0; - td_ta_map_id2thr_p = dlsym (handle, "td_ta_map_id2thr"); + td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr"); if (td_ta_map_id2thr_p == NULL) return 0; - td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr"); + td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr"); if (td_ta_map_lwp2thr_p == NULL) return 0; - td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter"); + td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter"); if (td_ta_thr_iter_p == NULL) return 0; - td_thr_validate_p = dlsym (handle, "td_thr_validate"); + td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate"); if (td_thr_validate_p == NULL) return 0; - td_thr_get_info_p = dlsym (handle, "td_thr_get_info"); + td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info"); if (td_thr_get_info_p == NULL) return 0; - td_thr_getfpregs_p = dlsym (handle, "td_thr_getfpregs"); + td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs"); if (td_thr_getfpregs_p == NULL) return 0; - td_thr_getgregs_p = dlsym (handle, "td_thr_getgregs"); + td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs"); if (td_thr_getgregs_p == NULL) return 0; - td_thr_setfpregs_p = dlsym (handle, "td_thr_setfpregs"); + td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs"); if (td_thr_setfpregs_p == NULL) return 0; - td_thr_setgregs_p = dlsym (handle, "td_thr_setgregs"); + td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs"); if (td_thr_setgregs_p == NULL) return 0; @@ -348,10 +460,31 @@ thread_db_load (void) td_ta_set_event_p = dlsym (handle, "td_ta_set_event"); td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg"); td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable"); + td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr"); return 1; } +static td_err_e +enable_thread_event (td_thragent_t *thread_agent, int event, CORE_ADDR *bp) +{ + td_notify_t notify; + td_err_e err; + + /* Get the breakpoint address for thread EVENT. */ + err = td_ta_event_addr_p (thread_agent, event, ¬ify); + if (err != TD_OK) + return err; + + /* Set up the breakpoint. */ + (*bp) = gdbarch_convert_from_func_ptr_addr (current_gdbarch, + (CORE_ADDR) notify.u.bptaddr, + ¤t_target); + create_thread_event_breakpoint ((*bp)); + + return TD_OK; +} + static void enable_thread_event_reporting (void) { @@ -385,9 +518,11 @@ enable_thread_event_reporting (void) /* Delete previous thread event breakpoints, if any. */ remove_thread_event_breakpoints (); + td_create_bp_addr = 0; + td_death_bp_addr = 0; - /* Get address for thread creation breakpoint. */ - err = td_ta_event_addr_p (thread_agent, TD_CREATE, ¬ify); + /* Set up the thread creation event. */ + err = enable_thread_event (thread_agent, TD_CREATE, &td_create_bp_addr); if (err != TD_OK) { warning ("Unable to get location for thread creation breakpoint: %s", @@ -395,22 +530,14 @@ enable_thread_event_reporting (void) return; } - /* Set up the breakpoint. */ - td_create_bp_addr = (CORE_ADDR) notify.u.bptaddr; - create_thread_event_breakpoint (td_create_bp_addr); - - /* Get address for thread death breakpoint. */ - err = td_ta_event_addr_p (thread_agent, TD_DEATH, ¬ify); + /* Set up the thread death event. */ + err = enable_thread_event (thread_agent, TD_DEATH, &td_death_bp_addr); if (err != TD_OK) { warning ("Unable to get location for thread death breakpoint: %s", thread_db_err_str (err)); return; } - - /* Set up the breakpoint. */ - td_death_bp_addr = (CORE_ADDR) notify.u.bptaddr; - create_thread_event_breakpoint (td_death_bp_addr); } static void @@ -457,32 +584,35 @@ check_thread_signals (void) #endif } -static void -disable_thread_signals (void) -{ -#ifdef GET_THREAD_SIGNALS - if (thread_signals) - { - int i; - - for (i = 1; i < NSIG; i++) - { - if (sigismember (&thread_stop_set, i)) - signal_stop_update (target_signal_from_host (i), 1); - if (sigismember (&thread_print_set, i)) - signal_print_update (target_signal_from_host (i), 1); - } - - thread_signals = 0; - } -#endif -} - static void thread_db_new_objfile (struct objfile *objfile) { td_err_e err; + /* First time through, report that libthread_db was successfuly + loaded. Can't print this in in thread_db_load as, at that stage, + the interpreter and it's console haven't started. The real + problem here is that libthread_db is loaded too early - it should + only be loaded when there is a program to debug. */ + { + static int dejavu; + if (!dejavu) + { + Dl_info info; + const char *library = NULL; + /* Try dladdr. */ + if (dladdr ((*td_ta_new_p), &info) != 0) + library = info.dli_fname; + /* Try dlinfo? */ + if (library == NULL) + /* Paranoid - don't let a NULL path slip through. */ + library = LIBTHREAD_DB_SO; + printf_unfiltered ("Using host libthread_db library \"%s\".\n", + library); + dejavu = 1; + } + } + /* Don't attempt to use thread_db on targets which can not run (core files). */ if (objfile == NULL || !target_has_execution) @@ -520,6 +650,8 @@ thread_db_new_objfile (struct objfile *objfile) break; case TD_OK: + printf_unfiltered ("[Thread debugging using libthread_db enabled]\n"); + /* The thread library was detected. Activate the thread_db target. */ push_target (&thread_db_ops); using_thread_db = 1; @@ -552,7 +684,7 @@ thread_db_new_objfile (struct objfile *objfile) break; } - quit: +quit: if (target_new_objfile_chain) target_new_objfile_chain (objfile); } @@ -566,13 +698,13 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, check_thread_signals (); - if (verbose) - printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid)); - /* Add the thread to GDB's thread list. */ tp = add_thread (ptid); tp->private = xmalloc (sizeof (struct private_thread_info)); - tp->private->lwpid = ti_p->ti_lid; + memset (tp->private, 0, sizeof (struct private_thread_info)); + + if (verbose) + printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid)); if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE) return; /* A zombie thread -- do not attach. */ @@ -603,7 +735,7 @@ thread_db_attach (char *args, int from_tty) /* ...and perform the remaining initialization steps. */ enable_thread_event_reporting (); - thread_db_find_new_threads(); + thread_db_find_new_threads (); } static void @@ -629,6 +761,19 @@ thread_db_detach (char *args, int from_tty) target_beneath->to_detach (args, from_tty); } +static int +clear_lwpid_callback (struct thread_info *thread, void *dummy) +{ + /* If we know that our thread implementation is 1-to-1, we could save + a certain amount of information; it's not clear how much, so we + are always conservative. */ + + thread->private->th_valid = 0; + thread->private->ti_valid = 0; + + return 0; +} + static void thread_db_resume (ptid_t ptid, int step, enum target_signal signo) { @@ -639,6 +784,9 @@ thread_db_resume (ptid_t ptid, int step, enum target_signal signo) else if (is_thread (ptid)) ptid = lwp_from_thread (ptid); + /* Clear cached data which may not be valid after the resume. */ + iterate_over_threads (clear_lwpid_callback, NULL); + target_beneath->to_resume (ptid, step, signo); do_cleanups (old_chain); @@ -655,63 +803,73 @@ check_event (ptid_t ptid) td_thrinfo_t ti; td_err_e err; CORE_ADDR stop_pc; + int loop = 0; /* Bail out early if we're not at a thread event breakpoint. */ stop_pc = read_pc_pid (ptid) - DECR_PC_AFTER_BREAK; if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr) return; - err = td_ta_event_getmsg_p (thread_agent, &msg); - if (err != TD_OK) + /* If we are at a create breakpoint, we do not know what new lwp + was created and cannot specifically locate the event message for it. + We have to call td_ta_event_getmsg() to get + the latest message. Since we have no way of correlating whether + the event message we get back corresponds to our breakpoint, we must + loop and read all event messages, processing them appropriately. + This guarantees we will process the correct message before continuing + from the breakpoint. + + Currently, death events are not enabled. If they are enabled, + the death event can use the td_thr_event_getmsg() interface to + get the message specifically for that lwp and avoid looping + below. */ + + loop = 1; + + do { - if (err == TD_NOMSG) - return; + err = td_ta_event_getmsg_p (thread_agent, &msg); + if (err != TD_OK) + { + if (err == TD_NOMSG) + return; - error ("Cannot get thread event message: %s", thread_db_err_str (err)); - } - - err = td_thr_get_info_p (msg.th_p, &ti); - if (err != TD_OK) - error ("Cannot get thread info: %s", thread_db_err_str (err)); - - ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid)); - - switch (msg.event) - { - case TD_CREATE: -#if 0 - /* FIXME: kettenis/2000-08-26: Since we use td_ta_event_getmsg, - there is no guarantee that the breakpoint will match the - event. Should we use td_thr_event_getmsg instead? */ - - if (stop_pc != td_create_bp_addr) - error ("Thread creation event doesn't match breakpoint."); -#endif - - /* We may already know about this thread, for instance when the - user has issued the `info threads' command before the SIGTRAP - for hitting the thread creation breakpoint was reported. */ - if (!in_thread_list (ptid)) - attach_thread (ptid, msg.th_p, &ti, 1); - return; - - case TD_DEATH: -#if 0 - /* FIXME: See TD_CREATE. */ - - if (stop_pc != td_death_bp_addr) - error ("Thread death event doesn't match breakpoint."); -#endif - - if (!in_thread_list (ptid)) - error ("Spurious thread death event."); - - detach_thread (ptid, 1); - return; - - default: - error ("Spurious thread event."); + error ("Cannot get thread event message: %s", + thread_db_err_str (err)); + } + + err = td_thr_get_info_p (msg.th_p, &ti); + if (err != TD_OK) + error ("Cannot get thread info: %s", thread_db_err_str (err)); + + ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid)); + + switch (msg.event) + { + case TD_CREATE: + + /* We may already know about this thread, for instance when the + user has issued the `info threads' command before the SIGTRAP + for hitting the thread creation breakpoint was reported. */ + if (!in_thread_list (ptid)) + attach_thread (ptid, msg.th_p, &ti, 1); + + break; + + case TD_DEATH: + + if (!in_thread_list (ptid)) + error ("Spurious thread death event."); + + detach_thread (ptid, 1); + + break; + + default: + error ("Spurious thread event."); + } } + while (loop); } static ptid_t @@ -746,8 +904,7 @@ thread_db_wait (ptid_t ptid, struct target_waitstatus *ourstatus) static int thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, - struct target_ops *target) + struct mem_attrib *attrib, struct target_ops *target) { struct cleanup *old_chain = save_inferior_ptid (); int xfer; @@ -762,7 +919,9 @@ thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, inferior_ptid = lwp_from_thread (inferior_ptid); } - xfer = target_beneath->to_xfer_memory (memaddr, myaddr, len, write, attrib, target); + xfer = + target_beneath->to_xfer_memory (memaddr, myaddr, len, write, attrib, + target); do_cleanups (old_chain); return xfer; @@ -771,7 +930,7 @@ thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, static void thread_db_fetch_registers (int regno) { - td_thrhandle_t th; + struct thread_info *thread_info; prgregset_t gregset; gdb_prfpregset_t fpregset; td_err_e err; @@ -783,17 +942,15 @@ thread_db_fetch_registers (int regno) return; } - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); - if (err != TD_OK) - error ("Cannot find thread %ld: %s", - (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); + thread_info = find_thread_pid (inferior_ptid); + thread_db_map_id2thr (thread_info, 1); - err = td_thr_getgregs_p (&th, gregset); + err = td_thr_getgregs_p (&thread_info->private->th, gregset); if (err != TD_OK) error ("Cannot fetch general-purpose registers for thread %ld: %s", (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); - err = td_thr_getfpregs_p (&th, &fpregset); + err = td_thr_getfpregs_p (&thread_info->private->th, &fpregset); if (err != TD_OK) error ("Cannot get floating-point registers for thread %ld: %s", (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); @@ -808,10 +965,10 @@ thread_db_fetch_registers (int regno) static void thread_db_store_registers (int regno) { - td_thrhandle_t th; prgregset_t gregset; gdb_prfpregset_t fpregset; td_err_e err; + struct thread_info *thread_info; if (!is_thread (inferior_ptid)) { @@ -820,16 +977,14 @@ thread_db_store_registers (int regno) return; } - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); - if (err != TD_OK) - error ("Cannot find thread %ld: %s", - (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); + thread_info = find_thread_pid (inferior_ptid); + thread_db_map_id2thr (thread_info, 1); if (regno != -1) { - char raw[MAX_REGISTER_RAW_SIZE]; + char raw[MAX_REGISTER_SIZE]; - read_register_gen (regno, raw); + deprecated_read_register_gen (regno, raw); thread_db_fetch_registers (-1); supply_register (regno, raw); } @@ -837,11 +992,11 @@ thread_db_store_registers (int regno) fill_gregset ((gdb_gregset_t *) gregset, -1); fill_fpregset (&fpregset, -1); - err = td_thr_setgregs_p (&th, gregset); + err = td_thr_setgregs_p (&thread_info->private->th, gregset); if (err != TD_OK) error ("Cannot store general-purpose registers for thread %ld: %s", (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); - err = td_thr_setfpregs_p (&th, &fpregset); + err = td_thr_setfpregs_p (&thread_info->private->th, &fpregset); if (err != TD_OK) error ("Cannot store floating-point registers for thread %ld: %s", (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); @@ -893,30 +1048,51 @@ thread_db_mourn_inferior (void) proc_handle.pid = 0; target_beneath->to_mourn_inferior (); + + /* Detach thread_db target ops if not dealing with a statically + linked threaded program. This allows a corefile to be debugged + after finishing debugging of a threaded program. At present, + debugging a statically-linked threaded program is broken, but + the check is added below in the event that it is fixed in the + future. */ + if (!keep_thread_db) + { + unpush_target (&thread_db_ops); + using_thread_db = 0; + } } static int thread_db_thread_alive (ptid_t ptid) { td_thrhandle_t th; - td_thrinfo_t ti; td_err_e err; if (is_thread (ptid)) { - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th); + struct thread_info *thread_info; + thread_info = find_thread_pid (ptid); + + thread_db_map_id2thr (thread_info, 0); + if (!thread_info->private->th_valid) + return 0; + + err = td_thr_validate_p (&thread_info->private->th); if (err != TD_OK) return 0; - err = td_thr_validate_p (&th); - if (err != TD_OK) - return 0; + if (!thread_info->private->ti_valid) + { + err = + td_thr_get_info_p (&thread_info->private->th, + &thread_info->private->ti); + if (err != TD_OK) + return 0; + thread_info->private->ti_valid = 1; + } - err = td_thr_get_info_p (&th, &ti); - if (err != TD_OK) - return 0; - - if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) + if (thread_info->private->ti.ti_state == TD_THR_UNKNOWN + || thread_info->private->ti.ti_state == TD_THR_ZOMBIE) return 0; /* A zombie thread. */ return 1; @@ -937,7 +1113,8 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data) err = td_thr_get_info_p (th_p, &ti); if (err != TD_OK) - error ("Cannot get thread info: %s", thread_db_err_str (err)); + error ("find_new_threads_callback: cannot get thread info: %s", + thread_db_err_str (err)); if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) return 0; /* A zombie -- ignore. */ @@ -969,29 +1146,31 @@ thread_db_pid_to_str (ptid_t ptid) if (is_thread (ptid)) { static char buf[64]; - td_thrhandle_t th; - td_thrinfo_t ti; + td_thrinfo_t *ti_p; td_err_e err; + struct thread_info *thread_info; - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th); - if (err != TD_OK) - error ("Cannot find thread %ld: %s", - (long) GET_THREAD (ptid), thread_db_err_str (err)); + thread_info = find_thread_pid (ptid); + thread_db_map_id2thr (thread_info, 0); + if (!thread_info->private->th_valid) + { + snprintf (buf, sizeof (buf), "Thread %ld (Missing)", + GET_THREAD (ptid)); + return buf; + } - err = td_thr_get_info_p (&th, &ti); - if (err != TD_OK) - error ("Cannot get thread info for thread %ld: %s", - (long) GET_THREAD (ptid), thread_db_err_str (err)); + ti_p = thread_db_get_info (thread_info); - if (ti.ti_state == TD_THR_ACTIVE && ti.ti_lid != 0) + if (ti_p->ti_state == TD_THR_ACTIVE && ti_p->ti_lid != 0) { snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)", - (long) ti.ti_tid, ti.ti_lid); + (long) ti_p->ti_tid, ti_p->ti_lid); } else { snprintf (buf, sizeof (buf), "Thread %ld (%s)", - (long) ti.ti_tid, thread_db_state_str (ti.ti_state)); + (long) ti_p->ti_tid, + thread_db_state_str (ti_p->ti_state)); } return buf; @@ -1003,6 +1182,95 @@ thread_db_pid_to_str (ptid_t ptid) return normal_pid_to_str (ptid); } +/* Get the address of the thread local variable in OBJFILE which is + stored at OFFSET within the thread local storage for thread PTID. */ + +static CORE_ADDR +thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile, + CORE_ADDR offset) +{ + if (is_thread (ptid)) + { + int objfile_is_library = (objfile->flags & OBJF_SHARED); + td_err_e err; + void *address; + CORE_ADDR lm; + struct thread_info *thread_info; + + /* glibc doesn't provide the needed interface. */ + if (!td_thr_tls_get_addr_p) + error ("Cannot find thread-local variables in this thread library."); + + /* Get the address of the link map for this objfile. */ + lm = svr4_fetch_objfile_link_map (objfile); + + /* Whoops, we couldn't find one. Bail out. */ + if (!lm) + { + if (objfile_is_library) + error ("Cannot find shared library `%s' link_map in dynamic" + " linker's module list", objfile->name); + else + error ("Cannot find executable file `%s' link_map in dynamic" + " linker's module list", objfile->name); + } + + /* Get info about the thread. */ + thread_info = find_thread_pid (ptid); + thread_db_map_id2thr (thread_info, 1); + + /* Finally, get the address of the variable. */ + err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *) lm, + offset, &address); + +#ifdef THREAD_DB_HAS_TD_NOTALLOC + /* The memory hasn't been allocated, yet. */ + if (err == TD_NOTALLOC) + { + /* Now, if libthread_db provided the initialization image's + address, we *could* try to build a non-lvalue value from + the initialization image. */ + if (objfile_is_library) + error ("The inferior has not yet allocated storage for" + " thread-local variables in\n" + "the shared library `%s'\n" + "for the thread %ld", + objfile->name, (long) GET_THREAD (ptid)); + else + error ("The inferior has not yet allocated storage for" + " thread-local variables in\n" + "the executable `%s'\n" + "for the thread %ld", + objfile->name, (long) GET_THREAD (ptid)); + } +#endif + + /* Something else went wrong. */ + if (err != TD_OK) + { + if (objfile_is_library) + error ("Cannot find thread-local storage for thread %ld, " + "shared library %s:\n%s", + (long) GET_THREAD (ptid), + objfile->name, thread_db_err_str (err)); + else + error ("Cannot find thread-local storage for thread %ld, " + "executable file %s:\n%s", + (long) GET_THREAD (ptid), + objfile->name, thread_db_err_str (err)); + } + + /* Cast assuming host == target. Joy. */ + return (CORE_ADDR) address; + } + + if (target_beneath->to_get_thread_local_address) + return target_beneath->to_get_thread_local_address (ptid, objfile, + offset); + + error ("Cannot find thread-local values on this target."); +} + static void init_thread_db_ops (void) { @@ -1025,6 +1293,8 @@ init_thread_db_ops (void) thread_db_ops.to_pid_to_str = thread_db_pid_to_str; thread_db_ops.to_stratum = thread_stratum; thread_db_ops.to_has_thread_control = tc_schedlock; + thread_db_ops.to_get_thread_local_address + = thread_db_get_thread_local_address; thread_db_ops.to_magic = OPS_MAGIC; } diff --git a/contrib/gdb/gdb/thread.c b/contrib/gdb/gdb/thread.c index b9c1f0265ec..f8cc18d72a2 100644 --- a/contrib/gdb/gdb/thread.c +++ b/contrib/gdb/gdb/thread.c @@ -1,7 +1,7 @@ /* Multi-process/thread control for GDB, the GNU debugger. Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. @@ -34,6 +34,7 @@ #include "gdbcmd.h" #include "regcache.h" #include "gdb.h" +#include "gdb_string.h" #include #include @@ -254,14 +255,17 @@ in_thread_list (ptid_t ptid) /* Print a list of thread ids currently known, and the total number of threads. To be used from within catch_errors. */ -static int -do_captured_list_thread_ids (struct ui_out *uiout, - void *arg) +static int +do_captured_list_thread_ids (struct ui_out *uiout, void *arg) { struct thread_info *tp; int num = 0; + struct cleanup *cleanup_chain; - ui_out_tuple_begin (uiout, "thread-ids"); + prune_threads (); + target_find_new_threads (); + + cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids"); for (tp = thread_list; tp; tp = tp->next) { @@ -269,7 +273,7 @@ do_captured_list_thread_ids (struct ui_out *uiout, ui_out_field_int (uiout, "thread-id", tp->num); } - ui_out_tuple_end (uiout); + do_cleanups (cleanup_chain); ui_out_field_int (uiout, "number-of-threads", num); return GDB_RC_OK; } @@ -286,24 +290,21 @@ gdb_list_thread_ids (struct ui_out *uiout) /* Load infrun state for the thread PID. */ void -load_infrun_state (ptid_t ptid, - CORE_ADDR *prev_pc, - CORE_ADDR *prev_func_start, - char **prev_func_name, +load_infrun_state (ptid_t ptid, + CORE_ADDR *prev_pc, int *trap_expected, struct breakpoint **step_resume_breakpoint, struct breakpoint **through_sigtramp_breakpoint, - CORE_ADDR *step_range_start, + CORE_ADDR *step_range_start, CORE_ADDR *step_range_end, - CORE_ADDR *step_frame_address, + struct frame_id *step_frame_id, int *handling_longjmp, - int *another_trap, + int *another_trap, int *stepping_through_solib_after_catch, bpstat *stepping_through_solib_catchpoints, int *stepping_through_sigtramp, - int *current_line, - struct symtab **current_symtab, - CORE_ADDR *step_sp) + int *current_line, + struct symtab **current_symtab, CORE_ADDR *step_sp) { struct thread_info *tp; @@ -314,18 +315,18 @@ load_infrun_state (ptid_t ptid, return; *prev_pc = tp->prev_pc; - *prev_func_start = tp->prev_func_start; - *prev_func_name = tp->prev_func_name; *trap_expected = tp->trap_expected; *step_resume_breakpoint = tp->step_resume_breakpoint; *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint; *step_range_start = tp->step_range_start; *step_range_end = tp->step_range_end; - *step_frame_address = tp->step_frame_address; + *step_frame_id = tp->step_frame_id; *handling_longjmp = tp->handling_longjmp; *another_trap = tp->another_trap; - *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch; - *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints; + *stepping_through_solib_after_catch = + tp->stepping_through_solib_after_catch; + *stepping_through_solib_catchpoints = + tp->stepping_through_solib_catchpoints; *stepping_through_sigtramp = tp->stepping_through_sigtramp; *current_line = tp->current_line; *current_symtab = tp->current_symtab; @@ -335,24 +336,21 @@ load_infrun_state (ptid_t ptid, /* Save infrun state for the thread PID. */ void -save_infrun_state (ptid_t ptid, - CORE_ADDR prev_pc, - CORE_ADDR prev_func_start, - char *prev_func_name, +save_infrun_state (ptid_t ptid, + CORE_ADDR prev_pc, int trap_expected, struct breakpoint *step_resume_breakpoint, struct breakpoint *through_sigtramp_breakpoint, - CORE_ADDR step_range_start, + CORE_ADDR step_range_start, CORE_ADDR step_range_end, - CORE_ADDR step_frame_address, + const struct frame_id *step_frame_id, int handling_longjmp, - int another_trap, + int another_trap, int stepping_through_solib_after_catch, bpstat stepping_through_solib_catchpoints, - int stepping_through_sigtramp, + int stepping_through_sigtramp, int current_line, - struct symtab *current_symtab, - CORE_ADDR step_sp) + struct symtab *current_symtab, CORE_ADDR step_sp) { struct thread_info *tp; @@ -363,14 +361,12 @@ save_infrun_state (ptid_t ptid, return; tp->prev_pc = prev_pc; - tp->prev_func_start = prev_func_start; - tp->prev_func_name = prev_func_name; tp->trap_expected = trap_expected; tp->step_resume_breakpoint = step_resume_breakpoint; tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint; tp->step_range_start = step_range_start; tp->step_range_end = step_range_end; - tp->step_frame_address = step_frame_address; + tp->step_frame_id = (*step_frame_id); tp->handling_longjmp = handling_longjmp; tp->another_trap = another_trap; tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch; @@ -421,14 +417,14 @@ info_threads_command (char *arg, int from_tty) struct thread_info *tp; ptid_t current_ptid; struct frame_info *cur_frame; - int saved_frame_level = selected_frame_level; + int saved_frame_level = frame_relative_level (get_selected_frame ()); int counter; char *extra_info; - /* Avoid coredumps which would happen if we tried to access a NULL - selected_frame. */ - if (!target_has_stack) - error ("No stack."); + /* Check that there really is a frame. This happens when a simulator + is connected but not loaded or running, for instance. */ + if (legacy_frame_p (current_gdbarch) && saved_frame_level < 0) + error ("No frame."); prune_threads (); target_find_new_threads (); @@ -452,10 +448,7 @@ info_threads_command (char *arg, int from_tty) puts_filtered (" "); switch_to_thread (tp->ptid); - if (selected_frame) - print_only_stack_frame (selected_frame, -1, 0); - else - printf_filtered ("[No stack.]\n"); + print_stack_frame (get_selected_frame (), -1, 0); } switch_to_thread (current_ptid); @@ -467,16 +460,16 @@ info_threads_command (char *arg, int from_tty) * of the stack (leaf frame). */ counter = saved_frame_level; - cur_frame = find_relative_frame (selected_frame, &counter); + cur_frame = find_relative_frame (get_selected_frame (), &counter); if (counter != 0) { /* Ooops, can't restore, tell user where we are. */ warning ("Couldn't restore frame in current thread, at frame 0"); - print_stack_frame (selected_frame, -1, 0); + print_stack_frame (get_selected_frame (), -1, 0); } else { - select_frame (cur_frame, saved_frame_level); + select_frame (cur_frame); } /* re-show current frame. */ @@ -495,13 +488,13 @@ switch_to_thread (ptid_t ptid) flush_cached_frames (); registers_changed (); stop_pc = read_pc (); - select_frame (get_current_frame (), 0); + select_frame (get_current_frame ()); } static void restore_current_thread (ptid_t ptid) { - if (! ptid_equal (ptid, inferior_ptid)) + if (!ptid_equal (ptid, inferior_ptid)) { switch_to_thread (ptid); print_stack_frame (get_current_frame (), 0, -1); @@ -566,14 +559,13 @@ thread_apply_all_command (char *cmd, int from_tty) switch_to_thread (tp->ptid); #ifdef HPUXHPPA printf_filtered ("\nThread %d (%s):\n", - tp->num, - target_tid_to_str (inferior_ptid)); + tp->num, target_tid_to_str (inferior_ptid)); #else printf_filtered ("\nThread %d (%s):\n", tp->num, target_pid_to_str (inferior_ptid)); #endif execute_command (cmd, from_tty); - strcpy (cmd, saved_cmd); /* Restore exact command used previously */ + strcpy (cmd, saved_cmd); /* Restore exact command used previously */ } do_cleanups (saved_cmd_cleanup_chain); @@ -685,8 +677,7 @@ thread_command (char *tidstr, int from_tty) } static int -do_captured_thread_select (struct ui_out *uiout, - void *tidstr) +do_captured_thread_select (struct ui_out *uiout, void *tidstr) { int num; struct thread_info *tp; @@ -713,13 +704,13 @@ do_captured_thread_select (struct ui_out *uiout, #endif ui_out_text (uiout, ")]"); - print_stack_frame (selected_frame, selected_frame_level, 1); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), 1); return GDB_RC_OK; } enum gdb_rc -gdb_thread_select (struct ui_out *uiout, - char *tidstr) +gdb_thread_select (struct ui_out *uiout, char *tidstr) { return catch_exceptions (uiout, do_captured_thread_select, tidstr, NULL, RETURN_MASK_ALL); @@ -738,16 +729,14 @@ _initialize_thread (void) add_prefix_cmd ("thread", class_run, thread_command, "Use this command to switch between threads.\n\ -The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, - &cmdlist); +The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, &cmdlist); add_prefix_cmd ("apply", class_run, thread_apply_command, "Apply a command to a list of threads.", &thread_apply_list, "apply ", 1, &thread_cmd_list); add_cmd ("all", class_run, thread_apply_all_command, - "Apply a command to all threads.", - &thread_apply_list); + "Apply a command to all threads.", &thread_apply_list); if (!xdb_commands) add_com_alias ("t", "thread", class_run, 1); diff --git a/contrib/gdb/gdb/top.c b/contrib/gdb/gdb/top.c index 972a5578f8f..d6bdfd09284 100644 --- a/contrib/gdb/gdb/top.c +++ b/contrib/gdb/gdb/top.c @@ -1,7 +1,7 @@ /* Top level stuff for GDB, the GNU debugger. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -27,6 +27,7 @@ #include "cli/cli-cmds.h" #include "cli/cli-script.h" #include "cli/cli-setshow.h" +#include "cli/cli-decode.h" #include "symtab.h" #include "inferior.h" #include @@ -46,8 +47,8 @@ #include "gdb_assert.h" /* readline include files */ -#include -#include +#include "readline/readline.h" +#include "readline/history.h" /* readline defines this. */ #undef savestring @@ -81,7 +82,7 @@ int inhibit_gdbinit = 0; /* If nonzero, and GDB has been configured to be able to use windows, attempt to open them upon startup. */ -int use_windows = 1; +int use_windows = 0; extern char lang_frame_mismatch_warn[]; /* language.c */ @@ -146,7 +147,7 @@ int baud_rate = -1; In mid-1996, remote_timeout was moved from remote.c to top.c and it began being used in other remote-* targets. It appears that the default was changed to 20 seconds at that time, perhaps because the - Hitachi E7000 ICE didn't always respond in a timely manner. + Renesas E7000 ICE didn't always respond in a timely manner. But if 5 seconds is a long time to sit and wait for retransmissions, 20 seconds is far worse. This demonstrates the difficulty of using @@ -170,6 +171,11 @@ int target_executing = 0; /* Level of control structure. */ static int control_level; +/* Sbrk location on entry to main. Used for statistics only. */ +#ifdef HAVE_SBRK +char *lim_at_start; +#endif + /* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ #ifndef STOP_SIGNAL @@ -377,6 +383,7 @@ catcher (catch_exceptions_ftype *func, int *func_val, enum return_reason *func_caught, char *errstring, + char **gdberrmsg, return_mask mask) { SIGJMP_BUF *saved_catch; @@ -422,7 +429,14 @@ catcher (catch_exceptions_ftype *func, if (!caught) val = (*func) (func_uiout, func_args); else - val = 0; + { + val = 0; + /* If caller wants a copy of the low-level error message, make one. + This is used in the case of a silent error whereby the caller + may optionally want to issue the message. */ + if (gdberrmsg) + *gdberrmsg = error_last_message (); + } catch_return = saved_catch; /* FIXME: cagney/1999-11-05: A correct FUNC implementation will @@ -470,7 +484,25 @@ catch_exceptions (struct ui_out *uiout, { int val; enum return_reason caught; - catcher (func, uiout, func_args, &val, &caught, errstring, mask); + catcher (func, uiout, func_args, &val, &caught, errstring, NULL, mask); + gdb_assert (val >= 0); + gdb_assert (caught <= 0); + if (caught < 0) + return caught; + return val; +} + +int +catch_exceptions_with_msg (struct ui_out *uiout, + catch_exceptions_ftype *func, + void *func_args, + char *errstring, + char **gdberrmsg, + return_mask mask) +{ + int val; + enum return_reason caught; + catcher (func, uiout, func_args, &val, &caught, errstring, gdberrmsg, mask); gdb_assert (val >= 0); gdb_assert (caught <= 0); if (caught < 0) @@ -484,7 +516,7 @@ struct catch_errors_args void *func_args; }; -int +static int do_catch_errors (struct ui_out *uiout, void *data) { struct catch_errors_args *args = data; @@ -500,7 +532,8 @@ catch_errors (catch_errors_ftype *func, void *func_args, char *errstring, struct catch_errors_args args; args.func = func; args.func_args = func_args; - catcher (do_catch_errors, uiout, &args, &val, &caught, errstring, mask); + catcher (do_catch_errors, uiout, &args, &val, &caught, errstring, + NULL, mask); if (caught != 0) return 0; return val; @@ -634,8 +667,8 @@ do_chdir_cleanup (void *old_dir) void execute_command (char *p, int from_tty) { - register struct cmd_list_element *c; - register enum language flang; + struct cmd_list_element *c; + enum language flang; static int warned = 0; char *line; @@ -663,10 +696,10 @@ execute_command (char *p, int from_tty) /* If the target is running, we allow only a limited set of commands. */ if (event_loop_p && target_can_async_p () && target_executing) - if (!strcmp (c->name, "help") - && !strcmp (c->name, "pwd") - && !strcmp (c->name, "show") - && !strcmp (c->name, "stop")) + if (strcmp (c->name, "help") != 0 + && strcmp (c->name, "pwd") != 0 + && strcmp (c->name, "show") != 0 + && strcmp (c->name, "stop") != 0) error ("Cannot execute this command while the target is running."); /* Pass null arg rather than an empty one. */ @@ -693,12 +726,7 @@ execute_command (char *p, int from_tty) } /* If this command has been pre-hooked, run the hook first. */ - if ((c->hook_pre) && (!c->hook_in)) - { - c->hook_in = 1; /* Prevent recursive hooking */ - execute_user_command (c->hook_pre, (char *) 0); - c->hook_in = 0; /* Allow hook to work again once it is complete */ - } + execute_cmd_pre_hook (c); if (c->flags & DEPRECATED_WARN_USER) deprecated_cmd_warning (&line); @@ -707,20 +735,15 @@ execute_command (char *p, int from_tty) execute_user_command (c, arg); else if (c->type == set_cmd || c->type == show_cmd) do_setshow_command (arg, from_tty & caution, c); - else if (c->func == NULL) + else if (!cmd_func_p (c)) error ("That is not a command, just a help topic."); else if (call_command_hook) call_command_hook (c, arg, from_tty & caution); else - (*c->func) (c, arg, from_tty & caution); + cmd_func (c, arg, from_tty & caution); /* If this command has been post-hooked, run the hook last. */ - if ((c->hook_post) && (!c->hook_in)) - { - c->hook_in = 1; /* Prevent recursive hooking */ - execute_user_command (c->hook_post, (char *) 0); - c->hook_in = 0; /* allow hook to work again once it is complete */ - } + execute_cmd_post_hook (c); } @@ -791,10 +814,8 @@ command_loop (void) if (display_space) { #ifdef HAVE_SBRK - extern char **environ; char *lim = (char *) sbrk (0); - - space_at_cmd_start = (long) (lim - (char *) &environ); + space_at_cmd_start = lim - lim_at_start; #endif } @@ -814,9 +835,8 @@ command_loop (void) if (display_space) { #ifdef HAVE_SBRK - extern char **environ; char *lim = (char *) sbrk (0); - long space_now = lim - (char *) &environ; + long space_now = lim - lim_at_start; long space_diff = space_now - space_at_cmd_start; printf_unfiltered ("Space used: %ld (%c%ld for this command)\n", @@ -956,6 +976,29 @@ static int write_history_p; static int history_size; static char *history_filename; +/* This is like readline(), but it has some gdb-specific behavior. + gdb can use readline in both the synchronous and async modes during + a single gdb invocation. At the ordinary top-level prompt we might + be using the async readline. That means we can't use + rl_pre_input_hook, since it doesn't work properly in async mode. + However, for a secondary prompt (" >", such as occurs during a + `define'), gdb just calls readline() directly, running it in + synchronous mode. So for operate-and-get-next to work in this + situation, we have to switch the hooks around. That is what + gdb_readline_wrapper is for. */ +char * +gdb_readline_wrapper (char *prompt) +{ + /* Set the hook that works in this case. */ + if (event_loop_p && after_char_processing_hook) + { + rl_pre_input_hook = (Function *) after_char_processing_hook; + after_char_processing_hook = NULL; + } + + return readline (prompt); +} + #ifdef STOP_SIGNAL static void @@ -1045,8 +1088,8 @@ static int operate_saved_history = -1; /* This is put on the appropriate hook and helps operate-and-get-next do its work. */ -void -gdb_rl_operate_and_get_next_completion () +static void +gdb_rl_operate_and_get_next_completion (void) { int delta = where_history () - operate_saved_history; /* The `key' argument to rl_get_previous_history is ignored. */ @@ -1068,6 +1111,8 @@ gdb_rl_operate_and_get_next_completion () static int gdb_rl_operate_and_get_next (int count, int key) { + int where; + if (event_loop_p) { /* Use the async hook. */ @@ -1080,8 +1125,20 @@ gdb_rl_operate_and_get_next (int count, int key) rl_pre_input_hook = (Function *) gdb_rl_operate_and_get_next_completion; } - /* Add 1 because we eventually want the next line. */ - operate_saved_history = where_history () + 1; + /* Find the current line, and find the next line to use. */ + where = where_history(); + + /* FIXME: kettenis/20020817: max_input_history is renamed into + history_max_entries in readline-4.2. When we do a new readline + import, we should probably change it here too, even though + readline maintains backwards compatibility for now by still + defining max_input_history. */ + if ((history_is_stifled () && (history_length >= max_input_history)) || + (where >= history_length - 1)) + operate_saved_history = where; + else + operate_saved_history = where + 1; + return rl_newline (1, key); } @@ -1105,7 +1162,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) { static char *linebuffer = 0; static unsigned linelength = 0; - register char *p; + char *p; char *p1; char *rl; char *local_prompt = prompt_arg; @@ -1171,9 +1228,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) if (annotation_level > 1 && instream == stdin) { - printf_unfiltered ("\n\032\032pre-"); - printf_unfiltered (annotation_suffix); - printf_unfiltered ("\n"); + puts_unfiltered ("\n\032\032pre-"); + puts_unfiltered (annotation_suffix); + puts_unfiltered ("\n"); } /* Don't use fancy stuff if not talking to stdin. */ @@ -1183,7 +1240,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) } else if (command_editing_p && instream == stdin && ISATTY (instream)) { - rl = readline (local_prompt); + rl = gdb_readline_wrapper (local_prompt); } else { @@ -1192,9 +1249,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) if (annotation_level > 1 && instream == stdin) { - printf_unfiltered ("\n\032\032post-"); - printf_unfiltered (annotation_suffix); - printf_unfiltered ("\n"); + puts_unfiltered ("\n\032\032post-"); + puts_unfiltered (annotation_suffix); + puts_unfiltered ("\n"); } if (!rl || rl == (char *) EOF) @@ -1236,7 +1293,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) #define SERVER_COMMAND_LENGTH 7 server_command = (p - linebuffer > SERVER_COMMAND_LENGTH) - && STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH); + && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0; if (server_command) { /* Note that we don't set `line'. Between this and the check in @@ -1329,7 +1386,7 @@ print_gdb_version (struct ui_file *stream) /* Second line is a copyright notice. */ - fprintf_filtered (stream, "Copyright 2002 Free Software Foundation, Inc.\n"); + fprintf_filtered (stream, "Copyright 2004 Free Software Foundation, Inc.\n"); /* Following the copyright is a brief statement that the program is free software, that users are free to copy and change it on @@ -1345,7 +1402,7 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n" /* After the required info we print the configuration information. */ fprintf_filtered (stream, "This GDB was configured as \""); - if (!STREQ (host_name, target_name)) + if (strcmp (host_name, target_name) != 0) { fprintf_filtered (stream, "--host=%s --target=%s", host_name, target_name); } @@ -1358,267 +1415,13 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n" /* get_prompt: access method for the GDB prompt string. */ -#define MAX_PROMPT_SIZE 256 - -/* - * int get_prompt_1 (char * buf); - * - * Work-horse for get_prompt (called via catch_errors). - * Argument is buffer to hold the formatted prompt. - * - * Returns: 1 for success (use formatted prompt) - * 0 for failure (use gdb_prompt_string). - */ - -static int gdb_prompt_escape; - -static int -get_prompt_1 (void *data) -{ - char *formatted_prompt = data; - char *local_prompt; - - if (event_loop_p) - local_prompt = PROMPT (0); - else - local_prompt = gdb_prompt_string; - - - if (gdb_prompt_escape == 0) - { - return 0; /* do no formatting */ - } - else - /* formatted prompt */ - { - char fmt[40], *promptp, *outp, *tmp; - struct value *arg_val; - DOUBLEST doubleval; - LONGEST longval; - CORE_ADDR addrval; - - int i, len; - struct type *arg_type, *elt_type; - - promptp = local_prompt; - outp = formatted_prompt; - - while (*promptp != '\0') - { - int available = MAX_PROMPT_SIZE - (outp - formatted_prompt) - 1; - - if (*promptp != gdb_prompt_escape) - { - if (available >= 1) /* overflow protect */ - *outp++ = *promptp++; - } - else - { - /* GDB prompt string contains escape char. Parse for arg. - Two consecutive escape chars followed by arg followed by - a comma means to insert the arg using a default format. - Otherwise a printf format string may be included between - the two escape chars. eg: - %%foo, insert foo using default format - %2.2f%foo, insert foo using "%2.2f" format - A mismatch between the format string and the data type - of "foo" is an error (which we don't know how to protect - against). */ - - fmt[0] = '\0'; /* assume null format string */ - if (promptp[1] == gdb_prompt_escape) /* double esc char */ - { - promptp += 2; /* skip past two escape chars. */ - } - else - { - /* extract format string from between two esc chars */ - i = 0; - do - { - fmt[i++] = *promptp++; /* copy format string */ - } - while (i < sizeof (fmt) - 1 && - *promptp != gdb_prompt_escape && - *promptp != '\0'); - - if (*promptp != gdb_prompt_escape) - error ("Syntax error at prompt position %d", - promptp - local_prompt); - else - { - promptp++; /* skip second escape char */ - fmt[i++] = '\0'; /* terminate the format string */ - } - } - - arg_val = parse_to_comma_and_eval (&promptp); - if (*promptp == ',') - promptp++; /* skip past the comma */ - arg_type = check_typedef (VALUE_TYPE (arg_val)); - switch (TYPE_CODE (arg_type)) - { - case TYPE_CODE_ARRAY: - elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type)); - if (TYPE_LENGTH (arg_type) > 0 && - TYPE_LENGTH (elt_type) == 1 && - TYPE_CODE (elt_type) == TYPE_CODE_INT) - { - int len = TYPE_LENGTH (arg_type); - - if (VALUE_LAZY (arg_val)) - value_fetch_lazy (arg_val); - tmp = VALUE_CONTENTS (arg_val); - - if (len > available) - len = available; /* overflow protect */ - - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (fmt[0] != 0) - sprintf (outp, fmt, tmp); - else - strncpy (outp, tmp, len); - outp[len] = '\0'; - } - break; - case TYPE_CODE_PTR: - elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type)); - addrval = value_as_address (arg_val); - - if (TYPE_LENGTH (elt_type) == 1 && - TYPE_CODE (elt_type) == TYPE_CODE_INT && - addrval != 0) - { - /* display it as a string */ - char *default_fmt = "%s"; - char *tmp; - int err = 0; - - /* Limiting the number of bytes that the following call - will read protects us from sprintf overflow later. */ - i = target_read_string (addrval, /* src */ - &tmp, /* dest */ - available, /* len */ - &err); - if (err) /* read failed */ - error ("%s on target_read", safe_strerror (err)); - - tmp[i] = '\0'; /* force-terminate string */ - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - tmp); - xfree (tmp); - } - else - { - /* display it as a pointer */ - char *default_fmt = "0x%x"; - - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - (long) addrval); - } - break; - case TYPE_CODE_FLT: - { - char *default_fmt = "%g"; - - doubleval = value_as_double (arg_val); - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - (double) doubleval); - break; - } - case TYPE_CODE_INT: - { - char *default_fmt = "%d"; - - longval = value_as_long (arg_val); - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - (long) longval); - break; - } - case TYPE_CODE_BOOL: - { - /* no default format for bool */ - longval = value_as_long (arg_val); - if (available >= 8 /*? */ ) /* overflow protect */ - { - if (longval) - strcpy (outp, ""); - else - strcpy (outp, ""); - } - break; - } - case TYPE_CODE_ENUM: - { - /* no default format for enum */ - longval = value_as_long (arg_val); - len = TYPE_NFIELDS (arg_type); - /* find enum name if possible */ - for (i = 0; i < len; i++) - if (TYPE_FIELD_BITPOS (arg_type, i) == longval) - break; /* match -- end loop */ - - if (i < len) /* enum name found */ - { - char *name = TYPE_FIELD_NAME (arg_type, i); - - strncpy (outp, name, available); - /* in casel available < strlen (name), */ - outp[available] = '\0'; - } - else - { - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, "%ld", (long) longval); - } - break; - } - case TYPE_CODE_VOID: - *outp = '\0'; - break; /* void type -- no output */ - default: - error ("bad data type at prompt position %d", - promptp - local_prompt); - break; - } - outp += strlen (outp); - } - } - *outp++ = '\0'; /* terminate prompt string */ - return 1; - } -} - char * get_prompt (void) { - static char buf[MAX_PROMPT_SIZE]; - - if (catch_errors (get_prompt_1, buf, "bad formatted prompt: ", - RETURN_MASK_ALL)) - { - return &buf[0]; /* successful formatted prompt */ - } + if (event_loop_p) + return PROMPT (0); else - { - /* Prompt could not be formatted. */ - if (event_loop_p) - return PROMPT (0); - else - return gdb_prompt_string; - } + return gdb_prompt_string; } void @@ -1656,19 +1459,53 @@ quit_confirm (void) else s = "The program is running. Exit anyway? "; - if (!query (s)) + if (!query ("%s", s)) return 0; } return 1; } +/* Helper routine for quit_force that requires error handling. */ + +struct qt_args +{ + char *args; + int from_tty; +}; + +static int +quit_target (void *arg) +{ + struct qt_args *qt = (struct qt_args *)arg; + + if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) + { + if (attach_flag) + target_detach (qt->args, qt->from_tty); + else + target_kill (); + } + + /* UDI wants this, to kill the TIP. */ + target_close (¤t_target, 1); + + /* Save the history information if it is appropriate to do so. */ + if (write_history_p && history_filename) + write_history (history_filename); + + do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */ + + return 0; +} + /* Quit without asking for confirmation. */ void quit_force (char *args, int from_tty) { int exit_code = 0; + struct qt_args qt; /* An optional expression may be used to cause gdb to terminate with the value of that expression. */ @@ -1679,22 +1516,12 @@ quit_force (char *args, int from_tty) exit_code = (int) value_as_long (val); } - if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) - { - if (attach_flag) - target_detach (args, from_tty); - else - target_kill (); - } + qt.args = args; + qt.from_tty = from_tty; - /* UDI wants this, to kill the TIP. */ - target_close (1); - - /* Save the history information if it is appropriate to do so. */ - if (write_history_p && history_filename) - write_history (history_filename); - - do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */ + /* We want to handle any quit errors and exit regardless. */ + catch_errors (quit_target, &qt, + "Quitting: ", RETURN_MASK_ALL); exit (exit_code); } @@ -1708,7 +1535,6 @@ input_from_terminal_p (void) return gdb_has_a_terminal () && (instream == stdin) & caution; } -/* ARGSUSED */ static void dont_repeat_command (char *ignored, int from_tty) { @@ -1794,7 +1620,6 @@ show_commands (char *args, int from_tty) } /* Called by do_setshow_command. */ -/* ARGSUSED */ static void set_history_size_command (char *args, int from_tty, struct cmd_list_element *c) { @@ -1809,7 +1634,6 @@ set_history_size_command (char *args, int from_tty, struct cmd_list_element *c) } } -/* ARGSUSED */ void set_history (char *args, int from_tty) { @@ -1817,7 +1641,6 @@ set_history (char *args, int from_tty) help_list (sethistlist, "set history ", -1, gdb_stdout); } -/* ARGSUSED */ void show_history (char *args, int from_tty) { @@ -1827,7 +1650,6 @@ show_history (char *args, int from_tty) int info_verbose = 0; /* Default verbose msgs off */ /* Called by do_setshow_command. An elaborate joke. */ -/* ARGSUSED */ void set_verbose (char *args, int from_tty, struct cmd_list_element *c) { @@ -1916,7 +1738,6 @@ init_main (void) if (annotation_level > 1) set_async_annotation_level (NULL, 0, NULL); } - gdb_prompt_escape = 0; /* default to none. */ /* Set the important stuff up for command editing. */ command_editing_p = 1; @@ -1924,11 +1745,11 @@ init_main (void) write_history_p = 0; /* Setup important stuff for command line editing. */ - rl_completion_entry_function = (int (*)()) readline_line_completion_function; - rl_completer_word_break_characters = - get_gdb_completer_word_break_characters (); + rl_completion_entry_function = readline_line_completion_function; + rl_completer_word_break_characters = default_word_break_characters (); rl_completer_quote_characters = get_gdb_completer_quote_characters (); rl_readline_name = "gdb"; + rl_terminal_name = getenv ("TERM"); /* The name for this defun comes from Bash, where it originated. 15 is Control-o, the same binding this function has in Bash. */ @@ -1955,13 +1776,6 @@ init_main (void) set_cmd_sfunc (c, set_async_prompt); } - add_show_from_set - (add_set_cmd ("prompt-escape-char", class_support, var_zinteger, - (char *) &gdb_prompt_escape, - "Set escape character for formatting of gdb's prompt", - &setlist), - &showlist); - add_com ("dont-repeat", class_support, dont_repeat_command, "Don't repeat this command.\n\ Primarily used inside of user-defined commands that should not be repeated when\n\ hitting return."); @@ -1999,7 +1813,7 @@ Without an argument, saving is enabled.", &sethistlist), &showhistlist); c = add_set_cmd ("size", no_class, var_integer, (char *) &history_size, - "Set the size of the command history, \n\ + "Set the size of the command history,\n\ ie. the number of previous commands to keep a record of.", &sethistlist); add_show_from_set (c, &showhistlist); set_cmd_sfunc (c, set_history_size_command); @@ -2007,8 +1821,8 @@ ie. the number of previous commands to keep a record of.", &sethistlist); c = add_set_cmd ("filename", no_class, var_filename, (char *) &history_filename, "Set the filename in which to record the command history\n\ - (the list of previous commands of which a record is kept).", &sethistlist); - c->completer = filename_completer; +(the list of previous commands of which a record is kept).", &sethistlist); + set_cmd_completer (c, filename_completer); add_show_from_set (c, &showhistlist); add_show_from_set @@ -2095,19 +1909,4 @@ gdb_init (char *argv0) it wants GDB to revert to the CLI, it should clear init_ui_hook. */ if (init_ui_hook) init_ui_hook (argv0); - - /* Install the default UI */ - if (!init_ui_hook) - { - uiout = cli_out_new (gdb_stdout); - - /* All the interpreters should have had a look at things by now. - Initialize the selected interpreter. */ - if (interpreter_p) - { - fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n", - interpreter_p); - exit (1); - } - } } diff --git a/contrib/gdb/gdb/top.h b/contrib/gdb/gdb/top.h index ca0b3d13dc6..88b7e7a6cde 100644 --- a/contrib/gdb/gdb/top.h +++ b/contrib/gdb/gdb/top.h @@ -56,7 +56,6 @@ extern char *get_prompt (void); extern void set_prompt (char *); /* From random places. */ -extern int mapped_symbol_files; extern int readnow_symbol_files; /* Perform _initialize initialization */ @@ -70,5 +69,16 @@ extern char *source_error; extern char *source_pre_error; extern int history_expansion_p; extern int server_command; +extern char *lim_at_start; + +extern void show_commands (char *args, int from_tty); + +extern void set_history (char *, int); + +extern void show_history (char *, int); + +extern void set_verbose (char *, int, struct cmd_list_element *); + +extern void do_restore_instream_cleanup (void *stream); #endif diff --git a/contrib/gdb/gdb/tracepoint.c b/contrib/gdb/gdb/tracepoint.c index 860b483ac43..39c6877c2a8 100644 --- a/contrib/gdb/gdb/tracepoint.c +++ b/contrib/gdb/gdb/tracepoint.c @@ -1,6 +1,6 @@ /* Tracing functionality for remote targets in custom GDB protocol - Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -37,13 +37,15 @@ #include "regcache.h" #include "completer.h" #include "gdb-events.h" +#include "block.h" +#include "dictionary.h" #include "ax.h" #include "ax-gdb.h" /* readline include files */ -#include -#include +#include "readline/readline.h" +#include "readline/history.h" /* readline defines this. */ #undef savestring @@ -73,16 +75,6 @@ extern int addressprint; /* Print machine addresses? */ */ extern void output_command (char *, int); -extern void registers_info (char *, int); -extern void args_info (char *, int); -extern void locals_info (char *, int); - - -/* If this definition isn't overridden by the header files, assume - that isatty and fileno exist on this system. */ -#ifndef ISATTY -#define ISATTY(FP) (isatty (fileno (FP))) -#endif /* Tracepoint.c: @@ -190,7 +182,7 @@ trace_error (char *buf) if (*++buf == '0') /* general case: */ error ("tracepoint.c: error in outgoing packet."); else - error ("tracepoint.c: error in outgoing packet at field #%d.", + error ("tracepoint.c: error in outgoing packet at field #%ld.", strtol (buf, NULL, 16)); case '2': error ("trace API error 0x%s.", ++buf); @@ -274,7 +266,7 @@ set_traceframe_context (CORE_ADDR trace_pc) set_internalvar (lookup_internalvar ("trace_file"), value_from_pointer (charstar, (LONGEST) 0)); set_internalvar (lookup_internalvar ("trace_line"), - value_from_pointer (builtin_type_int, (LONGEST) - 1)); + value_from_longest (builtin_type_int, (LONGEST) - 1)); return; } @@ -289,12 +281,12 @@ set_traceframe_context (CORE_ADDR trace_pc) /* save func name as "$trace_func", a debugger variable visible to users */ if (traceframe_fun == NULL || - SYMBOL_NAME (traceframe_fun) == NULL) + DEPRECATED_SYMBOL_NAME (traceframe_fun) == NULL) set_internalvar (lookup_internalvar ("trace_func"), value_from_pointer (charstar, (LONGEST) 0)); else { - len = strlen (SYMBOL_NAME (traceframe_fun)); + len = strlen (DEPRECATED_SYMBOL_NAME (traceframe_fun)); func_range = create_range_type (func_range, builtin_type_int, 0, len - 1); func_string = create_array_type (func_string, @@ -302,7 +294,7 @@ set_traceframe_context (CORE_ADDR trace_pc) func_val = allocate_value (func_string); VALUE_TYPE (func_val) = func_string; memcpy (VALUE_CONTENTS_RAW (func_val), - SYMBOL_NAME (traceframe_fun), + DEPRECATED_SYMBOL_NAME (traceframe_fun), len); func_val->modifiable = 0; set_internalvar (lookup_internalvar ("trace_func"), func_val); @@ -342,7 +334,7 @@ set_traceframe_context (CORE_ADDR trace_pc) static struct tracepoint * set_raw_tracepoint (struct symtab_and_line sal) { - register struct tracepoint *t, *tc; + struct tracepoint *t, *tc; struct cleanup *old_chain; t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint)); @@ -400,7 +392,7 @@ trace_command (char *arg, int from_tty) printf_filtered ("TRACE %s\n", arg); addr_start = arg; - sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical); + sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical, NULL); addr_end = arg; if (!sals.nelts) return; /* ??? Presumably decode_line_1 has already warned? */ @@ -502,11 +494,11 @@ tracepoints_info (char *tpnum_exp, int from_tty) char *tmp; if (TARGET_ADDR_BIT <= 32) - tmp = longest_local_hex_string_custom (t->address - & (CORE_ADDR) 0xffffffff, - "08l"); + tmp = local_hex_string_custom (t->address + & (CORE_ADDR) 0xffffffff, + "08l"); else - tmp = longest_local_hex_string_custom (t->address, "016l"); + tmp = local_hex_string_custom (t->address, "016l"); printf_filtered ("%s ", tmp); } @@ -518,7 +510,7 @@ tracepoints_info (char *tpnum_exp, int from_tty) if (sym) { fputs_filtered ("in ", gdb_stdout); - fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout); + fputs_filtered (SYMBOL_PRINT_NAME (sym), gdb_stdout); wrap_here (wrap_indent); fputs_filtered (" at ", gdb_stdout); } @@ -854,7 +846,7 @@ read_actions (struct tracepoint *t) line = (*readline_hook) (prompt); else if (instream == stdin && ISATTY (instream)) { - line = readline (prompt); + line = gdb_readline_wrapper (prompt); if (line && *line) /* add it to command history */ add_history (line); } @@ -922,6 +914,10 @@ validate_actionline (char **line, struct tracepoint *t) struct cleanup *old_chain = NULL; char *p; + /* if EOF is typed, *line is NULL */ + if (*line == NULL) + return END; + for (p = *line; isspace ((int) *p);) p++; @@ -969,14 +965,14 @@ validate_actionline (char **line, struct tracepoint *t) if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST) { warning ("constant %s (value %ld) will not be collected.", - SYMBOL_NAME (exp->elts[2].symbol), + DEPRECATED_SYMBOL_NAME (exp->elts[2].symbol), SYMBOL_VALUE (exp->elts[2].symbol)); return BADLINE; } else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT) { warning ("%s is optimized away and cannot be collected.", - SYMBOL_NAME (exp->elts[2].symbol)); + DEPRECATED_SYMBOL_NAME (exp->elts[2].symbol)); return BADLINE; } } @@ -1124,7 +1120,7 @@ memrange_sortmerge (struct collection_list *memranges) { if (memranges->list[a].type == memranges->list[b].type && memranges->list[b].start - memranges->list[a].end <= - MAX_REGISTER_VIRTUAL_SIZE) + MAX_REGISTER_SIZE) { /* memrange b starts before memrange a ends; merge them. */ if (memranges->list[b].end > memranges->list[a].end) @@ -1196,11 +1192,11 @@ collect_symbol (struct collection_list *collect, struct symbol *sym, { default: printf_filtered ("%s: don't know symbol class %d\n", - SYMBOL_NAME (sym), SYMBOL_CLASS (sym)); + DEPRECATED_SYMBOL_NAME (sym), SYMBOL_CLASS (sym)); break; case LOC_CONST: printf_filtered ("constant %s (value %ld) will not be collected.\n", - SYMBOL_NAME (sym), SYMBOL_VALUE (sym)); + DEPRECATED_SYMBOL_NAME (sym), SYMBOL_VALUE (sym)); break; case LOC_STATIC: offset = SYMBOL_VALUE_ADDRESS (sym); @@ -1210,7 +1206,7 @@ collect_symbol (struct collection_list *collect, struct symbol *sym, sprintf_vma (tmp, offset); printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n", - SYMBOL_NAME (sym), len, tmp /* address */); + DEPRECATED_SYMBOL_NAME (sym), len, tmp /* address */); } add_memrange (collect, -1, offset, len); /* 0 == memory */ break; @@ -1218,18 +1214,18 @@ collect_symbol (struct collection_list *collect, struct symbol *sym, case LOC_REGPARM: reg = SYMBOL_VALUE (sym); if (info_verbose) - printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym)); + printf_filtered ("LOC_REG[parm] %s: ", DEPRECATED_SYMBOL_NAME (sym)); add_register (collect, reg); /* check for doubles stored in two registers */ /* FIXME: how about larger types stored in 3 or more regs? */ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT && - len > REGISTER_RAW_SIZE (reg)) + len > DEPRECATED_REGISTER_RAW_SIZE (reg)) add_register (collect, reg + 1); break; case LOC_REF_ARG: printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n"); printf_filtered (" (will not collect %s)\n", - SYMBOL_NAME (sym)); + DEPRECATED_SYMBOL_NAME (sym)); break; case LOC_ARG: reg = frame_regno; @@ -1237,7 +1233,7 @@ collect_symbol (struct collection_list *collect, struct symbol *sym, if (info_verbose) { printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ", - SYMBOL_NAME (sym), len); + DEPRECATED_SYMBOL_NAME (sym), len); printf_vma (offset); printf_filtered (" from frame ptr reg %d\n", reg); } @@ -1249,7 +1245,7 @@ collect_symbol (struct collection_list *collect, struct symbol *sym, if (info_verbose) { printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ", - SYMBOL_NAME (sym), len); + DEPRECATED_SYMBOL_NAME (sym), len); printf_vma (offset); printf_filtered (" from reg %d\n", reg); } @@ -1262,7 +1258,7 @@ collect_symbol (struct collection_list *collect, struct symbol *sym, if (info_verbose) { printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ", - SYMBOL_NAME (sym), len); + DEPRECATED_SYMBOL_NAME (sym), len); printf_vma (offset); printf_filtered (" from frame ptr reg %d\n", reg); } @@ -1275,18 +1271,18 @@ collect_symbol (struct collection_list *collect, struct symbol *sym, if (info_verbose) { printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ", - SYMBOL_NAME (sym), len); + DEPRECATED_SYMBOL_NAME (sym), len); printf_vma (offset); printf_filtered (" from basereg %d\n", reg); } add_memrange (collect, reg, offset, len); break; case LOC_UNRESOLVED: - printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym)); + printf_filtered ("Don't know LOC_UNRESOLVED %s\n", DEPRECATED_SYMBOL_NAME (sym)); break; case LOC_OPTIMIZED_OUT: printf_filtered ("%s has been optimized out of existence.\n", - SYMBOL_NAME (sym)); + DEPRECATED_SYMBOL_NAME (sym)); break; } } @@ -1298,19 +1294,20 @@ add_local_symbols (struct collection_list *collect, CORE_ADDR pc, { struct symbol *sym; struct block *block; - int i, count = 0; + struct dict_iterator iter; + int count = 0; block = block_for_pc (pc); while (block != 0) { QUIT; /* allow user to bail out with ^C */ - ALL_BLOCK_SYMBOLS (block, i, sym) + ALL_BLOCK_SYMBOLS (block, iter, sym) { switch (SYMBOL_CLASS (sym)) { default: warning ("don't know how to trace local symbol %s", - SYMBOL_NAME (sym)); + DEPRECATED_SYMBOL_NAME (sym)); case LOC_LOCAL: case LOC_STATIC: case LOC_REGISTER: @@ -1866,7 +1863,7 @@ finish_tfind_command (char *msg, struct symbol *old_func; char *reply; - old_frame_addr = FRAME_FP (get_current_frame ()); + old_frame_addr = get_frame_base (get_current_frame ()); old_func = find_pc_function (read_pc ()); putpkt (msg); @@ -1928,7 +1925,7 @@ finish_tfind_command (char *msg, flush_cached_frames (); registers_changed (); - select_frame (get_current_frame (), 0); + select_frame (get_current_frame ()); set_traceframe_num (target_frameno); set_tracepoint_num (target_tracept); if (target_frameno == -1) @@ -1952,13 +1949,15 @@ finish_tfind_command (char *msg, if (old_func == find_pc_function (read_pc ()) && (old_frame_addr == 0 || - FRAME_FP (get_current_frame ()) == 0 || - old_frame_addr == FRAME_FP (get_current_frame ()))) + get_frame_base (get_current_frame ()) == 0 || + old_frame_addr == get_frame_base (get_current_frame ()))) source_only = -1; else source_only = 1; - print_stack_frame (selected_frame, selected_frame_level, source_only); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), + source_only); do_displays (); } } @@ -2070,10 +2069,12 @@ trace_find_tracepoint_command (char *args, int from_tty) if (target_is_remote ()) { if (args == 0 || *args == 0) - if (tracepoint_number == -1) - error ("No current tracepoint -- please supply an argument."); - else - tdp = tracepoint_number; /* default is current TDP */ + { + if (tracepoint_number == -1) + error ("No current tracepoint -- please supply an argument."); + else + tdp = tracepoint_number; /* default is current TDP */ + } else tdp = parse_and_eval_long (args); @@ -2105,7 +2106,7 @@ trace_find_line_command (char *args, int from_tty) { if (args == 0 || *args == 0) { - sal = find_pc_line ((get_current_frame ())->pc, 0); + sal = find_pc_line (get_frame_pc (get_current_frame ()), 0); sals.nelts = 1; sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); @@ -2280,7 +2281,7 @@ tracepoint_save_command (char *args, int from_tty) pathname = tilde_expand (args); if (!(fp = fopen (pathname, "w"))) error ("Unable to open file '%s' for saving tracepoints (%s)", - args, strerror (errno)); + args, safe_strerror (errno)); xfree (pathname); ALL_TRACEPOINTS (tp) @@ -2338,12 +2339,13 @@ scope_info (char *args, int from_tty) struct minimal_symbol *msym; struct block *block; char **canonical, *symname, *save_args = args; - int i, j, count = 0; + struct dict_iterator iter; + int j, count = 0; if (args == 0 || *args == 0) error ("requires an argument (function, line or *addr) to define a scope"); - sals = decode_line_1 (&args, 1, NULL, 0, &canonical); + sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL); if (sals.nelts == 0) return; /* presumably decode_line_1 has already warned */ @@ -2354,14 +2356,14 @@ scope_info (char *args, int from_tty) while (block != 0) { QUIT; /* allow user to bail out with ^C */ - ALL_BLOCK_SYMBOLS (block, i, sym) + ALL_BLOCK_SYMBOLS (block, iter, sym) { QUIT; /* allow user to bail out with ^C */ if (count == 0) printf_filtered ("Scope for %s:\n", save_args); count++; - symname = SYMBOL_NAME (sym); + symname = DEPRECATED_SYMBOL_NAME (sym); if (symname == NULL || *symname == '\0') continue; /* probably botched, certainly useless */ @@ -2437,7 +2439,7 @@ scope_info (char *args, int from_tty) REGISTER_NAME (SYMBOL_BASEREG (sym))); break; case LOC_UNRESOLVED: - msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL); + msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, NULL); if (msym == NULL) printf_filtered ("Unresolved Static"); else @@ -2513,7 +2515,7 @@ trace_dump_command (char *args, int from_tty) to the tracepoint PC. If not, then the current frame was collected during single-stepping. */ - stepping_frame = (t->address != read_pc ()); + stepping_frame = (t->address != (read_pc () - DECR_PC_AFTER_BREAK)); for (action = t->actions; action; action = action->next) { @@ -2677,7 +2679,7 @@ last tracepoint set."); c = add_com ("save-tracepoints", class_trace, tracepoint_save_command, "Save current tracepoint definitions as a script.\n\ Use the 'source' command in another debug session to restore them."); - c->completer = filename_completer; + set_cmd_completer (c, filename_completer); add_com ("tdump", class_trace, trace_dump_command, "Print everything collected at the current tracepoint."); @@ -2800,7 +2802,7 @@ Argument may be a line number, function name, or '*' plus an address.\n\ For a line number or function, trace at the start of its code.\n\ If an address is specified, trace at that exact address.\n\n\ Do \"help tracepoints\" for info on other tracepoint commands."); - c->completer = location_completer; + set_cmd_completer (c, location_completer); add_com_alias ("tp", "trace", class_alias, 0); add_com_alias ("tr", "trace", class_alias, 1); diff --git a/contrib/gdb/gdb/trad-frame.c b/contrib/gdb/gdb/trad-frame.c new file mode 100644 index 00000000000..f397f5d8241 --- /dev/null +++ b/contrib/gdb/gdb/trad-frame.c @@ -0,0 +1,134 @@ +/* Traditional frame unwind support, for GDB the GNU Debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "trad-frame.h" +#include "regcache.h" + +/* A traditional frame is unwound by analysing the function prologue + and using the information gathered to track registers. For + non-optimized frames, the technique is reliable (just need to check + for all potential instruction sequences). */ + +struct trad_frame_saved_reg * +trad_frame_alloc_saved_regs (struct frame_info *next_frame) +{ + int regnum; + struct gdbarch *gdbarch = get_frame_arch (next_frame); + int numregs = NUM_REGS + NUM_PSEUDO_REGS; + struct trad_frame_saved_reg *this_saved_regs + = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg); + for (regnum = 0; regnum < numregs; regnum++) + { + this_saved_regs[regnum].realreg = regnum; + this_saved_regs[regnum].addr = -1; + } + return this_saved_regs; +} + +enum { REG_VALUE = -1, REG_UNKNOWN = -2 }; + +int +trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) +{ + return (this_saved_regs[regnum].realreg == REG_VALUE); +} + +int +trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) +{ + return (this_saved_regs[regnum].realreg >= 0 + && this_saved_regs[regnum].addr != -1); +} + +int +trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum) +{ + return (this_saved_regs[regnum].realreg >= 0 + && this_saved_regs[regnum].addr == -1); +} + +void +trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[], + int regnum, LONGEST val) +{ + /* Make the REALREG invalid, indicating that the ADDR contains the + register's value. */ + this_saved_regs[regnum].realreg = REG_VALUE; + this_saved_regs[regnum].addr = val; +} + +void +trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[], + int regnum) +{ + /* Make the REALREG invalid, indicating that the value is not known. */ + this_saved_regs[regnum].realreg = REG_UNKNOWN; + this_saved_regs[regnum].addr = -1; +} + +void +trad_frame_prev_register (struct frame_info *next_frame, + struct trad_frame_saved_reg this_saved_regs[], + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realregp, void *bufferp) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + if (trad_frame_addr_p (this_saved_regs, regnum)) + { + /* The register was saved in memory. */ + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = this_saved_regs[regnum].addr; + *realregp = -1; + if (bufferp != NULL) + { + /* Read the value in from memory. */ + get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp, + register_size (gdbarch, regnum)); + } + } + else if (trad_frame_realreg_p (this_saved_regs, regnum)) + { + /* Ask the next frame to return the value of the register. */ + frame_register_unwind (next_frame, this_saved_regs[regnum].realreg, + optimizedp, lvalp, addrp, realregp, bufferp); + } + else if (trad_frame_value_p (this_saved_regs, regnum)) + { + /* The register's value is available. */ + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realregp = -1; + if (bufferp != NULL) + store_unsigned_integer (bufferp, register_size (gdbarch, regnum), + this_saved_regs[regnum].addr); + } + else + { + error ("Register %s not available", + gdbarch_register_name (gdbarch, regnum)); + } +} diff --git a/contrib/gdb/gdb/trad-frame.h b/contrib/gdb/gdb/trad-frame.h new file mode 100644 index 00000000000..55720c7e836 --- /dev/null +++ b/contrib/gdb/gdb/trad-frame.h @@ -0,0 +1,88 @@ +/* Traditional frame unwind support, for GDB the GNU Debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TRAD_FRAME_H +#define TRAD_FRAME_H + +struct frame_info; + +/* A traditional saved regs table, indexed by REGNUM, encoding where + the value of REGNUM for the previous frame can be found in this + frame. + + The table is initialized with an identity encoding (ADDR == -1, + REALREG == REGNUM) indicating that the value of REGNUM in the + previous frame can be found in register REGNUM (== REALREG) in this + frame. + + The initial encoding can then be changed: + + Modify ADDR (REALREG >= 0, ADDR != -1) to indicate that the value + of register REGNUM in the previous frame can be found in memory at + ADDR in this frame (addr_p, !realreg_p, !value_p). + + Modify REALREG (REALREG >= 0, ADDR == -1) to indicate that the + value of register REGNUM in the previous frame is found in register + REALREG in this frame (!addr_p, realreg_p, !value_p). + + Call trad_frame_set_value (REALREG == -1) to indicate that the + value of register REGNUM in the previous frame is found in ADDR + (!addr_p, !realreg_p, value_p). + + Call trad_frame_set_unknown (REALREG == -2) to indicate that the + register's value is not known. */ + +struct trad_frame_saved_reg +{ + LONGEST addr; /* A CORE_ADDR fits in a longest. */ + int realreg; +}; + +/* Encode REGNUM value in the trad-frame. */ +void trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[], + int regnum, LONGEST val); + +/* Mark REGNUM as unknown. */ +void trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[], + int regnum); + +/* Convenience functions, return non-zero if the register has been + encoded as specified. */ +int trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum); +int trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum); +int trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum); + + +/* Return a freshly allocated (and initialized) trad_frame array. */ +struct trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct frame_info *next_frame); + +/* Given the trad_frame info, return the location of the specified + register. */ +void trad_frame_prev_register (struct frame_info *next_frame, + struct trad_frame_saved_reg this_saved_regs[], + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realregp, void *bufferp); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-command.c b/contrib/gdb/gdb/tui/tui-command.c new file mode 100644 index 00000000000..399ef85b8c5 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-command.c @@ -0,0 +1,131 @@ +/* Specific command window processing. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-win.h" +#include "tui/tui-io.h" + +#include "gdb_curses.h" +#include "gdb_string.h" + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/* Dispatch the correct tui function based upon the control character. */ +unsigned int +tui_dispatch_ctrl_char (unsigned int ch) +{ + struct tui_win_info *win_info = tui_win_with_focus (); + WINDOW *w = TUI_CMD_WIN->generic.handle; + + /* + ** If the command window has the logical focus, or no-one does + ** assume it is the command window; in this case, pass the + ** character on through and do nothing here. + */ + if (win_info == NULL || win_info == TUI_CMD_WIN) + return ch; + else + { + unsigned int c = 0, ch_copy = ch; + int i; + char *term; + + /* If this is an xterm, page next/prev keys aren't returned + ** by keypad as a single char, so we must handle them here. + ** Seems like a bug in the curses library? + */ + term = (char *) getenv ("TERM"); + for (i = 0; (term && term[i]); i++) + term[i] = toupper (term[i]); + if ((strcmp (term, "XTERM") == 0) && key_is_start_sequence (ch)) + { + unsigned int page_ch = 0; + unsigned int tmp_char; + + tmp_char = 0; + while (!key_is_end_sequence (tmp_char)) + { + tmp_char = (int) wgetch (w); + if (tmp_char == ERR) + { + return ch; + } + if (!tmp_char) + break; + if (tmp_char == 53) + page_ch = KEY_PPAGE; + else if (tmp_char == 54) + page_ch = KEY_NPAGE; + else + { + return 0; + } + } + ch_copy = page_ch; + } + + switch (ch_copy) + { + case KEY_NPAGE: + tui_scroll_forward (win_info, 0); + break; + case KEY_PPAGE: + tui_scroll_backward (win_info, 0); + break; + case KEY_DOWN: + case KEY_SF: + tui_scroll_forward (win_info, 1); + break; + case KEY_UP: + case KEY_SR: + tui_scroll_backward (win_info, 1); + break; + case KEY_RIGHT: + tui_scroll_left (win_info, 1); + break; + case KEY_LEFT: + tui_scroll_right (win_info, 1); + break; + case '\f': + tui_refresh_all_win (); + break; + default: + c = ch_copy; + break; + } + return c; + } +} diff --git a/contrib/gdb/gdb/tui/tui-command.h b/contrib/gdb/gdb/tui/tui-command.h new file mode 100644 index 00000000000..9653bf07ee5 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-command.h @@ -0,0 +1,30 @@ +/* Specific command window processing. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_COMMAND_H +#define TUI_COMMAND_H + +extern unsigned int tui_dispatch_ctrl_char (unsigned int); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-data.c b/contrib/gdb/gdb/tui/tui-data.c new file mode 100644 index 00000000000..800d72a069f --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-data.c @@ -0,0 +1,924 @@ +/* TUI data manipulation routines. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" + +#include "gdb_string.h" +#include "gdb_curses.h" + +/**************************** +** GLOBAL DECLARATIONS +****************************/ +struct tui_win_info *(tui_win_list[MAX_MAJOR_WINDOWS]); + +/*************************** +** Private data +****************************/ +static enum tui_layout_type current_layout = UNDEFINED_LAYOUT; +static int term_height, term_width; +static struct tui_gen_win_info _locator; +static struct tui_gen_win_info exec_info[2]; +static struct tui_win_info * src_win_list[2]; +static struct tui_list source_windows = {(void **) src_win_list, 0}; +static int default_tab_len = DEFAULT_TAB_LEN; +static struct tui_win_info * win_with_focus = (struct tui_win_info *) NULL; +static struct tui_layout_def layout_def = +{SRC_WIN, /* DISPLAY_MODE */ + FALSE, /* SPLIT */ + TUI_UNDEFINED_REGS, /* REGS_DISPLAY_TYPE */ + TUI_SFLOAT_REGS}; /* FLOAT_REGS_DISPLAY_TYPE */ +static int win_resized = FALSE; + + +/********************************* +** Static function forward decls +**********************************/ +static void free_content (tui_win_content, int, enum tui_win_type); +static void free_content_elements (tui_win_content, int, enum tui_win_type); + + + +/********************************* +** PUBLIC FUNCTIONS +**********************************/ + +int +tui_win_is_source_type (enum tui_win_type win_type) +{ + return (win_type == SRC_WIN || win_type == DISASSEM_WIN); +} + +int +tui_win_is_auxillary (enum tui_win_type win_type) +{ + return (win_type > MAX_MAJOR_WINDOWS); +} + +int +tui_win_has_locator (struct tui_win_info *win_info) +{ + return (win_info != NULL \ + && win_info->detail.source_info.has_locator); +} + +void +tui_set_win_highlight (struct tui_win_info *win_info, int highlight) +{ + if (win_info != NULL) + win_info->is_highlighted = highlight; +} + +/****************************************** +** ACCESSORS & MUTATORS FOR PRIVATE DATA +******************************************/ + +/* Answer a whether the terminal window has been resized or not. */ +int +tui_win_resized (void) +{ + return win_resized; +} + + +/* Set a whether the terminal window has been resized or not. */ +void +tui_set_win_resized_to (int resized) +{ + win_resized = resized; +} + + +/* Answer a pointer to the current layout definition. */ +struct tui_layout_def * +tui_layout_def (void) +{ + return &layout_def; +} + + +/* Answer the window with the logical focus. */ +struct tui_win_info * +tui_win_with_focus (void) +{ + return win_with_focus; +} + + +/* Set the window that has the logical focus. */ +void +tui_set_win_with_focus (struct tui_win_info * win_info) +{ + win_with_focus = win_info; +} + + +/* Answer the length in chars, of tabs. */ +int +tui_default_tab_len (void) +{ + return default_tab_len; +} + + +/* Set the length in chars, of tabs. */ +void +tui_set_default_tab_len (int len) +{ + default_tab_len = len; +} + + +/* Accessor for the current source window. Usually there is only one + source window (either source or disassembly), but both can be + displayed at the same time. */ +struct tui_list * +tui_source_windows (void) +{ + return &source_windows; +} + + +/* Clear the list of source windows. Usually there is only one source + window (either source or disassembly), but both can be displayed at + the same time. */ +void +tui_clear_source_windows (void) +{ + source_windows.list[0] = NULL; + source_windows.list[1] = NULL; + source_windows.count = 0; +} + + +/* Clear the pertinant detail in the source windows. */ +void +tui_clear_source_windows_detail (void) +{ + int i; + + for (i = 0; i < (tui_source_windows ())->count; i++) + tui_clear_win_detail ((struct tui_win_info *) (tui_source_windows ())->list[i]); +} + + +/* Add a window to the list of source windows. Usually there is only + one source window (either source or disassembly), but both can be + displayed at the same time. */ +void +tui_add_to_source_windows (struct tui_win_info * win_info) +{ + if (source_windows.count < 2) + source_windows.list[source_windows.count++] = (void *) win_info; +} + + +/* Clear the pertinant detail in the windows. */ +void +tui_clear_win_detail (struct tui_win_info * win_info) +{ + if (win_info != NULL) + { + switch (win_info->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + win_info->detail.source_info.start_line_or_addr.addr = 0; + win_info->detail.source_info.horizontal_offset = 0; + break; + case CMD_WIN: + win_info->detail.command_info.cur_line = + win_info->detail.command_info.curch = 0; + break; + case DATA_WIN: + win_info->detail.data_display_info.data_content = + (tui_win_content) NULL; + win_info->detail.data_display_info.data_content_count = 0; + win_info->detail.data_display_info.regs_content = + (tui_win_content) NULL; + win_info->detail.data_display_info.regs_content_count = 0; + win_info->detail.data_display_info.regs_display_type = + TUI_UNDEFINED_REGS; + win_info->detail.data_display_info.regs_column_count = 1; + win_info->detail.data_display_info.display_regs = FALSE; + break; + default: + break; + } + } +} + + +/* Accessor for the source execution info ptr. */ +struct tui_gen_win_info * +tui_source_exec_info_win_ptr (void) +{ + return &exec_info[0]; +} + + +/* Accessor for the disassem execution info ptr. */ +struct tui_gen_win_info * +tui_disassem_exec_info_win_ptr (void) +{ + return &exec_info[1]; +} + + +/* Accessor for the locator win info. Answers a pointer to the static + locator win info struct. */ +struct tui_gen_win_info * +tui_locator_win_info_ptr (void) +{ + return &_locator; +} + + +/* Accessor for the term_height. */ +int +tui_term_height (void) +{ + return term_height; +} + + +/* Mutator for the term height. */ +void +tui_set_term_height_to (int h) +{ + term_height = h; +} + + +/* Accessor for the term_width. */ +int +tui_term_width (void) +{ + return term_width; +} + + +/* Mutator for the term_width. */ +void +tui_set_term_width_to (int w) +{ + term_width = w; +} + + +/* Accessor for the current layout. */ +enum tui_layout_type +tui_current_layout (void) +{ + return current_layout; +} + + +/* Mutator for the current layout. */ +void +tui_set_current_layout_to (enum tui_layout_type new_layout) +{ + current_layout = new_layout; +} + + +/* Set the origin of the window. */ +void +set_gen_win_origin (struct tui_gen_win_info * win_info, int x, int y) +{ + win_info->origin.x = x; + win_info->origin.y = y; +} + + +/***************************** +** OTHER PUBLIC FUNCTIONS +*****************************/ + + +/* Answer the next window in the list, cycling back to the top if + necessary. */ +struct tui_win_info * +tui_next_win (struct tui_win_info * cur_win) +{ + enum tui_win_type type = cur_win->generic.type; + struct tui_win_info * next_win = (struct tui_win_info *) NULL; + + if (cur_win->generic.type == CMD_WIN) + type = SRC_WIN; + else + type = cur_win->generic.type + 1; + while (type != cur_win->generic.type && (next_win == NULL)) + { + if (tui_win_list[type] && tui_win_list[type]->generic.is_visible) + next_win = tui_win_list[type]; + else + { + if (type == CMD_WIN) + type = SRC_WIN; + else + type++; + } + } + + return next_win; +} + + +/* Answer the prev window in the list, cycling back to the bottom if + necessary. */ +struct tui_win_info * +tui_prev_win (struct tui_win_info * cur_win) +{ + enum tui_win_type type = cur_win->generic.type; + struct tui_win_info * prev = (struct tui_win_info *) NULL; + + if (cur_win->generic.type == SRC_WIN) + type = CMD_WIN; + else + type = cur_win->generic.type - 1; + while (type != cur_win->generic.type && (prev == NULL)) + { + if (tui_win_list[type]->generic.is_visible) + prev = tui_win_list[type]; + else + { + if (type == SRC_WIN) + type = CMD_WIN; + else + type--; + } + } + + return prev; +} + + +/* Answer the window represented by name. */ +struct tui_win_info * +tui_partial_win_by_name (char *name) +{ + struct tui_win_info * win_info = (struct tui_win_info *) NULL; + + if (name != (char *) NULL) + { + int i = 0; + + while (i < MAX_MAJOR_WINDOWS && win_info == NULL) + { + if (tui_win_list[i] != 0) + { + char *cur_name = tui_win_name (&tui_win_list[i]->generic); + if (strlen (name) <= strlen (cur_name) && + strncmp (name, cur_name, strlen (name)) == 0) + win_info = tui_win_list[i]; + } + i++; + } + } + + return win_info; +} + + +/* Answer the name of the window. */ +char * +tui_win_name (struct tui_gen_win_info * win_info) +{ + char *name = (char *) NULL; + + switch (win_info->type) + { + case SRC_WIN: + name = SRC_NAME; + break; + case CMD_WIN: + name = CMD_NAME; + break; + case DISASSEM_WIN: + name = DISASSEM_NAME; + break; + case DATA_WIN: + name = DATA_NAME; + break; + default: + name = ""; + break; + } + + return name; +} + + +void +tui_initialize_static_data (void) +{ + tui_init_generic_part (tui_source_exec_info_win_ptr ()); + tui_init_generic_part (tui_disassem_exec_info_win_ptr ()); + tui_init_generic_part (tui_locator_win_info_ptr ()); +} + + +struct tui_gen_win_info * +tui_alloc_generic_win_info (void) +{ + struct tui_gen_win_info * win; + + if ((win = (struct tui_gen_win_info *) xmalloc ( + sizeof (struct tui_gen_win_info *))) != (struct tui_gen_win_info *) NULL) + tui_init_generic_part (win); + + return win; +} + + +void +tui_init_generic_part (struct tui_gen_win_info * win) +{ + win->width = + win->height = + win->origin.x = + win->origin.y = + win->viewport_height = + win->content_size = + win->last_visible_line = 0; + win->handle = (WINDOW *) NULL; + win->content = NULL; + win->content_in_use = + win->is_visible = FALSE; + win->title = 0; +} + + +/* + ** init_content_element(). + */ +void +init_content_element (struct tui_win_element * element, enum tui_win_type type) +{ + element->highlight = FALSE; + switch (type) + { + case SRC_WIN: + case DISASSEM_WIN: + element->which_element.source.line = (char *) NULL; + element->which_element.source.line_or_addr.line_no = 0; + element->which_element.source.is_exec_point = FALSE; + element->which_element.source.has_break = FALSE; + break; + case DATA_WIN: + tui_init_generic_part (&element->which_element.data_window); + element->which_element.data_window.type = DATA_ITEM_WIN; + ((struct tui_gen_win_info *) & element->which_element.data_window)->content = + (void **) tui_alloc_content (1, DATA_ITEM_WIN); + ((struct tui_gen_win_info *) + & element->which_element.data_window)->content_size = 1; + break; + case CMD_WIN: + element->which_element.command.line = (char *) NULL; + break; + case DATA_ITEM_WIN: + element->which_element.data.name = (char *) NULL; + element->which_element.data.type = TUI_REGISTER; + element->which_element.data.item_no = UNDEFINED_ITEM; + element->which_element.data.value = NULL; + element->which_element.data.highlight = FALSE; + element->which_element.data.content = (char*) NULL; + break; + case LOCATOR_WIN: + element->which_element.locator.file_name[0] = + element->which_element.locator.proc_name[0] = (char) 0; + element->which_element.locator.line_no = 0; + element->which_element.locator.addr = 0; + break; + case EXEC_INFO_WIN: + memset(element->which_element.simple_string, ' ', + sizeof(element->which_element.simple_string)); + break; + default: + break; + } +} + +void +init_win_info (struct tui_win_info * win_info) +{ + tui_init_generic_part (&win_info->generic); + win_info->can_highlight = + win_info->is_highlighted = FALSE; + switch (win_info->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + win_info->detail.source_info.execution_info = (struct tui_gen_win_info *) NULL; + win_info->detail.source_info.has_locator = FALSE; + win_info->detail.source_info.horizontal_offset = 0; + win_info->detail.source_info.start_line_or_addr.addr = 0; + win_info->detail.source_info.filename = 0; + break; + case DATA_WIN: + win_info->detail.data_display_info.data_content = (tui_win_content) NULL; + win_info->detail.data_display_info.data_content_count = 0; + win_info->detail.data_display_info.regs_content = (tui_win_content) NULL; + win_info->detail.data_display_info.regs_content_count = 0; + win_info->detail.data_display_info.regs_display_type = + TUI_UNDEFINED_REGS; + win_info->detail.data_display_info.regs_column_count = 1; + win_info->detail.data_display_info.display_regs = FALSE; + win_info->detail.data_display_info.current_group = 0; + break; + case CMD_WIN: + win_info->detail.command_info.cur_line = 0; + win_info->detail.command_info.curch = 0; + break; + default: + win_info->detail.opaque = NULL; + break; + } +} + + +struct tui_win_info * +tui_alloc_win_info (enum tui_win_type type) +{ + struct tui_win_info * win_info = (struct tui_win_info *) NULL; + + win_info = (struct tui_win_info *) xmalloc (sizeof (struct tui_win_info)); + if ((win_info != NULL)) + { + win_info->generic.type = type; + init_win_info (win_info); + } + + return win_info; +} + + +/* Allocates the content and elements in a block. */ +tui_win_content +tui_alloc_content (int num_elements, enum tui_win_type type) +{ + tui_win_content content = (tui_win_content) NULL; + char *element_block_ptr = (char *) NULL; + int i; + + if ((content = (tui_win_content) + xmalloc (sizeof (struct tui_win_element *) * num_elements)) != (tui_win_content) NULL) + { /* + ** All windows, except the data window, can allocate the elements + ** in a chunk. The data window cannot because items can be + ** added/removed from the data display by the user at any time. + */ + if (type != DATA_WIN) + { + if ((element_block_ptr = (char *) + xmalloc (sizeof (struct tui_win_element) * num_elements)) != (char *) NULL) + { + for (i = 0; i < num_elements; i++) + { + content[i] = (struct tui_win_element *) element_block_ptr; + init_content_element (content[i], type); + element_block_ptr += sizeof (struct tui_win_element); + } + } + else + { + xfree (content); + content = (tui_win_content) NULL; + } + } + } + + return content; +} + + +/* Adds the input number of elements to the windows's content. If no + content has been allocated yet, alloc_content() is called to do + this. The index of the first element added is returned, unless + there is a memory allocation error, in which case, (-1) is + returned. */ +int +tui_add_content_elements (struct tui_gen_win_info * win_info, int num_elements) +{ + struct tui_win_element * element_ptr; + int i, index_start; + + if (win_info->content == NULL) + { + win_info->content = (void **) tui_alloc_content (num_elements, win_info->type); + index_start = 0; + } + else + index_start = win_info->content_size; + if (win_info->content != NULL) + { + for (i = index_start; (i < num_elements + index_start); i++) + { + if ((element_ptr = (struct tui_win_element *) + xmalloc (sizeof (struct tui_win_element))) != (struct tui_win_element *) NULL) + { + win_info->content[i] = (void *) element_ptr; + init_content_element (element_ptr, win_info->type); + win_info->content_size++; + } + else /* things must be really hosed now! We ran out of memory!? */ + return (-1); + } + } + + return index_start; +} + + +/* Delete all curses windows associated with win_info, leaving everything + else intact. */ +void +tui_del_window (struct tui_win_info * win_info) +{ + struct tui_gen_win_info * generic_win; + + switch (win_info->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + generic_win = tui_locator_win_info_ptr (); + if (generic_win != (struct tui_gen_win_info *) NULL) + { + tui_delete_win (generic_win->handle); + generic_win->handle = (WINDOW *) NULL; + generic_win->is_visible = FALSE; + } + if (win_info->detail.source_info.filename) + { + xfree (win_info->detail.source_info.filename); + win_info->detail.source_info.filename = 0; + } + generic_win = win_info->detail.source_info.execution_info; + if (generic_win != (struct tui_gen_win_info *) NULL) + { + tui_delete_win (generic_win->handle); + generic_win->handle = (WINDOW *) NULL; + generic_win->is_visible = FALSE; + } + break; + case DATA_WIN: + if (win_info->generic.content != NULL) + { + tui_del_data_windows (win_info->detail.data_display_info.regs_content, + win_info->detail.data_display_info.regs_content_count); + tui_del_data_windows (win_info->detail.data_display_info.data_content, + win_info->detail.data_display_info.data_content_count); + } + break; + default: + break; + } + if (win_info->generic.handle != (WINDOW *) NULL) + { + tui_delete_win (win_info->generic.handle); + win_info->generic.handle = (WINDOW *) NULL; + win_info->generic.is_visible = FALSE; + } +} + + +void +tui_free_window (struct tui_win_info * win_info) +{ + struct tui_gen_win_info * generic_win; + + switch (win_info->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + generic_win = tui_locator_win_info_ptr (); + if (generic_win != (struct tui_gen_win_info *) NULL) + { + tui_delete_win (generic_win->handle); + generic_win->handle = (WINDOW *) NULL; + } + tui_free_win_content (generic_win); + if (win_info->detail.source_info.filename) + { + xfree (win_info->detail.source_info.filename); + win_info->detail.source_info.filename = 0; + } + generic_win = win_info->detail.source_info.execution_info; + if (generic_win != (struct tui_gen_win_info *) NULL) + { + tui_delete_win (generic_win->handle); + generic_win->handle = (WINDOW *) NULL; + tui_free_win_content (generic_win); + } + break; + case DATA_WIN: + if (win_info->generic.content != NULL) + { + tui_free_data_content (win_info->detail.data_display_info.regs_content, + win_info->detail.data_display_info.regs_content_count); + win_info->detail.data_display_info.regs_content = + (tui_win_content) NULL; + win_info->detail.data_display_info.regs_content_count = 0; + tui_free_data_content (win_info->detail.data_display_info.data_content, + win_info->detail.data_display_info.data_content_count); + win_info->detail.data_display_info.data_content = + (tui_win_content) NULL; + win_info->detail.data_display_info.data_content_count = 0; + win_info->detail.data_display_info.regs_display_type = + TUI_UNDEFINED_REGS; + win_info->detail.data_display_info.regs_column_count = 1; + win_info->detail.data_display_info.display_regs = FALSE; + win_info->generic.content = NULL; + win_info->generic.content_size = 0; + } + break; + default: + break; + } + if (win_info->generic.handle != (WINDOW *) NULL) + { + tui_delete_win (win_info->generic.handle); + win_info->generic.handle = (WINDOW *) NULL; + tui_free_win_content (&win_info->generic); + } + if (win_info->generic.title) + xfree (win_info->generic.title); + xfree (win_info); +} + + +void +tui_free_all_source_wins_content (void) +{ + int i; + + for (i = 0; i < (tui_source_windows ())->count; i++) + { + struct tui_win_info * win_info = (struct tui_win_info *) (tui_source_windows ())->list[i]; + + if (win_info != NULL) + { + tui_free_win_content (&(win_info->generic)); + tui_free_win_content (win_info->detail.source_info.execution_info); + } + } +} + + +void +tui_free_win_content (struct tui_gen_win_info * win_info) +{ + if (win_info->content != NULL) + { + free_content ((tui_win_content) win_info->content, + win_info->content_size, + win_info->type); + win_info->content = NULL; + } + win_info->content_size = 0; +} + + +void +tui_del_data_windows (tui_win_content content, int content_size) +{ + int i; + + /* + ** Remember that data window content elements are of type struct tui_gen_win_info *, + ** each of which whose single element is a data element. + */ + for (i = 0; i < content_size; i++) + { + struct tui_gen_win_info * generic_win = &content[i]->which_element.data_window; + + if (generic_win != (struct tui_gen_win_info *) NULL) + { + tui_delete_win (generic_win->handle); + generic_win->handle = (WINDOW *) NULL; + generic_win->is_visible = FALSE; + } + } +} + + +void +tui_free_data_content (tui_win_content content, int content_size) +{ + int i; + + /* + ** Remember that data window content elements are of type struct tui_gen_win_info *, + ** each of which whose single element is a data element. + */ + for (i = 0; i < content_size; i++) + { + struct tui_gen_win_info * generic_win = &content[i]->which_element.data_window; + + if (generic_win != (struct tui_gen_win_info *) NULL) + { + tui_delete_win (generic_win->handle); + generic_win->handle = (WINDOW *) NULL; + tui_free_win_content (generic_win); + } + } + free_content (content, + content_size, + DATA_WIN); +} + + +/********************************** +** LOCAL STATIC FUNCTIONS ** +**********************************/ + + +static void +free_content (tui_win_content content, int content_size, enum tui_win_type win_type) +{ + if (content != (tui_win_content) NULL) + { + free_content_elements (content, content_size, win_type); + xfree (content); + } +} + + +/* + ** free_content_elements(). + */ +static void +free_content_elements (tui_win_content content, int content_size, enum tui_win_type type) +{ + if (content != (tui_win_content) NULL) + { + int i; + + if (type == SRC_WIN || type == DISASSEM_WIN) + { + /* free whole source block */ + xfree (content[0]->which_element.source.line); + } + else + { + for (i = 0; i < content_size; i++) + { + struct tui_win_element * element; + + element = content[i]; + if (element != (struct tui_win_element *) NULL) + { + switch (type) + { + case DATA_WIN: + xfree (element); + break; + case DATA_ITEM_WIN: + /* + ** Note that data elements are not allocated + ** in a single block, but individually, as needed. + */ + if (element->which_element.data.type != TUI_REGISTER) + xfree ((void *)element->which_element.data.name); + xfree (element->which_element.data.value); + xfree (element->which_element.data.content); + xfree (element); + break; + case CMD_WIN: + xfree (element->which_element.command.line); + break; + default: + break; + } + } + } + } + if (type != DATA_WIN && type != DATA_ITEM_WIN) + xfree (content[0]); /* free the element block */ + } +} diff --git a/contrib/gdb/gdb/tui/tui-data.h b/contrib/gdb/gdb/tui/tui-data.h new file mode 100644 index 00000000000..02bebb4e2be --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-data.h @@ -0,0 +1,351 @@ +/* TUI data manipulation routines. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_DATA_H +#define TUI_DATA_H + +#include "tui/tui.h" /* For enum tui_win_type. */ +#include "gdb_curses.h" /* For WINDOW. */ + +/* This is a point definition. */ +struct tui_point +{ + int x, y; +}; + +/* Generic window information */ +struct tui_gen_win_info +{ + WINDOW *handle; /* window handle */ + enum tui_win_type type; /* type of window */ + int width; /* window width */ + int height; /* window height */ + struct tui_point origin; /* origin of window */ + void **content; /* content of window */ + int content_size; /* Size of content (# of elements) */ + int content_in_use; /* Can it be used, or is it already used? */ + int viewport_height; /* viewport height */ + int last_visible_line; /* index of last visible line */ + int is_visible; /* whether the window is visible or not */ + char *title; /* Window title to display. */ +}; + +/* Constant definitions */ +#define DEFAULT_TAB_LEN 8 +#define NO_SRC_STRING "[ No Source Available ]" +#define NO_DISASSEM_STRING "[ No Assembly Available ]" +#define NO_REGS_STRING "[ Register Values Unavailable ]" +#define NO_DATA_STRING "[ No Data Values Displayed ]" +#define MAX_CONTENT_COUNT 100 +#define SRC_NAME "SRC" +#define CMD_NAME "CMD" +#define DATA_NAME "REGS" +#define DISASSEM_NAME "ASM" +#define TUI_NULL_STR "" +#define DEFAULT_HISTORY_COUNT 25 +#define BOX_WINDOW TRUE +#define DONT_BOX_WINDOW FALSE +#define HILITE TRUE +#define NO_HILITE FALSE +#define WITH_LOCATOR TRUE +#define NO_LOCATOR FALSE +#define EMPTY_SOURCE_PROMPT TRUE +#define NO_EMPTY_SOURCE_PROMPT FALSE +#define UNDEFINED_ITEM -1 +#define MIN_WIN_HEIGHT 3 +#define MIN_CMD_WIN_HEIGHT 3 + +/* Strings to display in the TUI status line. */ +#define PROC_PREFIX "In: " +#define LINE_PREFIX "Line: " +#define PC_PREFIX "PC: " +#define SINGLE_KEY "(SingleKey)" + +/* Minimum/Maximum length of some fields displayed in the TUI status line. */ +#define MIN_LINE_WIDTH 4 /* Use at least 4 digits for line numbers. */ +#define MIN_PROC_WIDTH 12 +#define MAX_TARGET_WIDTH 10 +#define MAX_PID_WIDTH 14 + +#define TUI_FLOAT_REGS_NAME "$FREGS" +#define TUI_FLOAT_REGS_NAME_LOWER "$fregs" +#define TUI_GENERAL_REGS_NAME "$GREGS" +#define TUI_GENERAL_REGS_NAME_LOWER "$gregs" +#define TUI_SPECIAL_REGS_NAME "$SREGS" +#define TUI_SPECIAL_REGS_NAME_LOWER "$sregs" +#define TUI_GENERAL_SPECIAL_REGS_NAME "$REGS" +#define TUI_GENERAL_SPECIAL_REGS_NAME_LOWER "$regs" + +/* Scroll direction enum. */ +enum tui_scroll_direction +{ + FORWARD_SCROLL, + BACKWARD_SCROLL, + LEFT_SCROLL, + RIGHT_SCROLL +}; + + +/* General list struct. */ +struct tui_list +{ + void **list; + int count; +}; + + +/* The kinds of layouts available */ +enum tui_layout_type +{ + SRC_COMMAND, + DISASSEM_COMMAND, + SRC_DISASSEM_COMMAND, + SRC_DATA_COMMAND, + DISASSEM_DATA_COMMAND, + UNDEFINED_LAYOUT +}; + +/* Basic data types that can be displayed in the data window. */ +enum tui_data_type +{ + TUI_REGISTER, + TUI_SCALAR, + TUI_COMPLEX, + TUI_STRUCT +}; + +/* Types of register displays */ +enum tui_register_display_type +{ + TUI_UNDEFINED_REGS, + TUI_GENERAL_REGS, + TUI_SFLOAT_REGS, + TUI_DFLOAT_REGS, + TUI_SPECIAL_REGS, + TUI_GENERAL_AND_SPECIAL_REGS +}; + +/* Structure describing source line or line address */ +union tui_line_or_address +{ + int line_no; + CORE_ADDR addr; +}; + +/* Current Layout definition */ +struct tui_layout_def +{ + enum tui_win_type display_mode; + int split; + enum tui_register_display_type regs_display_type; + enum tui_register_display_type float_regs_display_type; +}; + +/* Elements in the Source/Disassembly Window */ +struct tui_source_element +{ + char *line; + union tui_line_or_address line_or_addr; + int is_exec_point; + int has_break; +}; + + +/* Elements in the data display window content */ +struct tui_data_element +{ + const char *name; + int item_no; /* the register number, or data display number */ + enum tui_data_type type; + void *value; + int highlight; + char *content; +}; + + +/* Elements in the command window content */ +struct tui_command_element +{ + char *line; +}; + + +#define MAX_LOCATOR_ELEMENT_LEN 100 + +/* Elements in the locator window content */ +struct tui_locator_element +{ + char file_name[MAX_LOCATOR_ELEMENT_LEN]; + char proc_name[MAX_LOCATOR_ELEMENT_LEN]; + int line_no; + CORE_ADDR addr; +}; + +/* Flags to tell what kind of breakpoint is at current line. */ +#define TUI_BP_ENABLED 0x01 +#define TUI_BP_DISABLED 0x02 +#define TUI_BP_HIT 0x04 +#define TUI_BP_CONDITIONAL 0x08 +#define TUI_BP_HARDWARE 0x10 + +/* Position of breakpoint markers in the exec info string. */ +#define TUI_BP_HIT_POS 0 +#define TUI_BP_BREAK_POS 1 +#define TUI_EXEC_POS 2 +#define TUI_EXECINFO_SIZE 4 + +typedef char tui_exec_info_content[TUI_EXECINFO_SIZE]; + +/* An content element in a window */ +union tui_which_element +{ + struct tui_source_element source; /* the source elements */ + struct tui_gen_win_info data_window; /* data display elements */ + struct tui_data_element data; /* elements of data_window */ + struct tui_command_element command; /* command elements */ + struct tui_locator_element locator; /* locator elements */ + tui_exec_info_content simple_string; /* simple char based elements */ +}; + +struct tui_win_element +{ + int highlight; + union tui_which_element which_element; +}; + + +/* This describes the content of the window. */ +typedef struct tui_win_element **tui_win_content; + + +/* This struct defines the specific information about a data display window */ +struct tui_data_info +{ + tui_win_content data_content; /* start of data display content */ + int data_content_count; + tui_win_content regs_content; /* start of regs display content */ + int regs_content_count; + enum tui_register_display_type regs_display_type; + int regs_column_count; + int display_regs; /* Should regs be displayed at all? */ + struct reggroup *current_group; +}; + + +struct tui_source_info +{ + int has_locator; /* Does locator belongs to this window? */ + /* Execution information window. */ + struct tui_gen_win_info *execution_info; + int horizontal_offset; /* used for horizontal scroll */ + union tui_line_or_address start_line_or_addr; + char* filename; +}; + + +struct tui_command_info +{ + int cur_line; /* The current line position */ + int curch; /* The current cursor position */ + int start_line; +}; + + +/* This defines information about each logical window */ +struct tui_win_info +{ + struct tui_gen_win_info generic; /* general window information */ + union + { + struct tui_source_info source_info; + struct tui_data_info data_display_info; + struct tui_command_info command_info; + void *opaque; + } + detail; + int can_highlight; /* Can this window ever be highlighted? */ + int is_highlighted; /* Is this window highlighted? */ +}; + +extern int tui_win_is_source_type (enum tui_win_type win_type); +extern int tui_win_is_auxillary (enum tui_win_type win_type); +extern int tui_win_has_locator (struct tui_win_info *win_info); +extern void tui_set_win_highlight (struct tui_win_info *win_info, + int highlight); + + +/* Global Data */ +extern struct tui_win_info *(tui_win_list[MAX_MAJOR_WINDOWS]); + +#define TUI_SRC_WIN tui_win_list[SRC_WIN] +#define TUI_DISASM_WIN tui_win_list[DISASSEM_WIN] +#define TUI_DATA_WIN tui_win_list[DATA_WIN] +#define TUI_CMD_WIN tui_win_list[CMD_WIN] + +/* Data Manipulation Functions */ +extern void tui_initialize_static_data (void); +extern struct tui_gen_win_info *tui_alloc_generic_win_info (void); +extern struct tui_win_info *tui_alloc_win_info (enum tui_win_type); +extern void tui_init_generic_part (struct tui_gen_win_info *); +extern void tui_init_win_info (struct tui_win_info *); +extern tui_win_content tui_alloc_content (int, enum tui_win_type); +extern int tui_add_content_elements (struct tui_gen_win_info *, int); +extern void tui_init_content_element (struct tui_win_element *, enum tui_win_type); +extern void tui_free_window (struct tui_win_info *); +extern void tui_free_win_content (struct tui_gen_win_info *); +extern void tui_free_data_content (tui_win_content, int); +extern void tui_free_all_source_wins_content (void); +extern void tui_del_window (struct tui_win_info *); +extern void tui_del_data_windows (tui_win_content, int); +extern struct tui_win_info *tui_partial_win_by_name (char *); +extern char *tui_win_name (struct tui_gen_win_info *); +extern enum tui_layout_type tui_current_layout (void); +extern void tui_set_current_layout_to (enum tui_layout_type); +extern int tui_term_height (void); +extern void tui_set_term_height_to (int); +extern int tui_term_width (void); +extern void tui_set_term_width_to (int); +extern void tui_set_gen_win_origin (struct tui_gen_win_info *, int, int); +extern struct tui_gen_win_info *tui_locator_win_info_ptr (void); +extern struct tui_gen_win_info *tui_source_exec_info_win_ptr (void); +extern struct tui_gen_win_info *tui_disassem_exec_info_win_ptr (void); +extern struct tui_list * tui_source_windows (void); +extern void tui_clear_source_windows (void); +extern void tui_clear_source_windows_detail (void); +extern void tui_clear_win_detail (struct tui_win_info * win_info); +extern void tui_add_to_source_windows (struct tui_win_info *); +extern int tui_default_tab_len (void); +extern void tui_set_default_tab_len (int); +extern struct tui_win_info *tui_win_with_focus (void); +extern void tui_set_win_with_focus (struct tui_win_info *); +extern struct tui_layout_def * tui_layout_def (void); +extern int tui_win_resized (void); +extern void tui_set_win_resized_to (int); + +extern struct tui_win_info *tui_next_win (struct tui_win_info *); +extern struct tui_win_info *tui_prev_win (struct tui_win_info *); + +extern void tui_add_to_source_windows (struct tui_win_info * win_info); + +#endif /* TUI_DATA_H */ diff --git a/contrib/gdb/gdb/tui/tui-disasm.c b/contrib/gdb/gdb/tui/tui-disasm.c new file mode 100644 index 00000000000..9c3072bf74e --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-disasm.c @@ -0,0 +1,397 @@ +/* Disassembly display. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" +#include "value.h" +#include "source.h" +#include "disasm.h" +#include "gdb_string.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-win.h" +#include "tui/tui-layout.h" +#include "tui/tui-winsource.h" +#include "tui/tui-stack.h" +#include "tui/tui-file.h" + +#include "gdb_curses.h" + +struct tui_asm_line +{ + CORE_ADDR addr; + char* addr_string; + char* insn; +}; + +/* Function to set the disassembly window's content. + Disassemble count lines starting at pc. + Return address of the count'th instruction after pc. */ +static CORE_ADDR +tui_disassemble (struct tui_asm_line* asm_lines, CORE_ADDR pc, int count) +{ + struct ui_file *gdb_dis_out; + + /* now init the ui_file structure */ + gdb_dis_out = tui_sfileopen (256); + + /* Now construct each line */ + for (; count > 0; count--, asm_lines++) + { + if (asm_lines->addr_string) + xfree (asm_lines->addr_string); + if (asm_lines->insn) + xfree (asm_lines->insn); + + print_address (pc, gdb_dis_out); + asm_lines->addr = pc; + asm_lines->addr_string = xstrdup (tui_file_get_strbuf (gdb_dis_out)); + + ui_file_rewind (gdb_dis_out); + + pc = pc + gdb_print_insn (pc, gdb_dis_out); + + asm_lines->insn = xstrdup (tui_file_get_strbuf (gdb_dis_out)); + + /* reset the buffer to empty */ + ui_file_rewind (gdb_dis_out); + } + ui_file_delete (gdb_dis_out); + return pc; +} + +/* Find the disassembly address that corresponds to FROM lines + above or below the PC. Variable sized instructions are taken + into account by the algorithm. */ +static CORE_ADDR +tui_find_disassembly_address (CORE_ADDR pc, int from) +{ + CORE_ADDR new_low; + int max_lines; + int i; + struct tui_asm_line* asm_lines; + + max_lines = (from > 0) ? from : - from; + if (max_lines <= 1) + return pc; + + asm_lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line) + * max_lines); + memset (asm_lines, 0, sizeof (struct tui_asm_line) * max_lines); + + new_low = pc; + if (from > 0) + { + tui_disassemble (asm_lines, pc, max_lines); + new_low = asm_lines[max_lines - 1].addr; + } + else + { + CORE_ADDR last_addr; + int pos; + struct minimal_symbol* msymbol; + + /* Find backward an address which is a symbol + and for which disassembling from that address will fill + completely the window. */ + pos = max_lines - 1; + do { + new_low -= 1 * max_lines; + msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0); + + if (msymbol) + new_low = SYMBOL_VALUE_ADDRESS (msymbol); + else + new_low += 1 * max_lines; + + tui_disassemble (asm_lines, new_low, max_lines); + last_addr = asm_lines[pos].addr; + } while (last_addr > pc && msymbol); + + /* Scan forward disassembling one instruction at a time + until the last visible instruction of the window + matches the pc. We keep the disassembled instructions + in the 'lines' window and shift it downward (increasing + its addresses). */ + if (last_addr < pc) + do + { + CORE_ADDR next_addr; + + pos++; + if (pos >= max_lines) + pos = 0; + + next_addr = tui_disassemble (&asm_lines[pos], last_addr, 1); + + /* If there are some problems while disassembling exit. */ + if (next_addr <= last_addr) + break; + last_addr = next_addr; + } while (last_addr <= pc); + pos++; + if (pos >= max_lines) + pos = 0; + new_low = asm_lines[pos].addr; + } + for (i = 0; i < max_lines; i++) + { + xfree (asm_lines[i].addr_string); + xfree (asm_lines[i].insn); + } + return new_low; +} + +/* Function to set the disassembly window's content. */ +enum tui_status +tui_set_disassem_content (CORE_ADDR pc) +{ + enum tui_status ret = TUI_FAILURE; + int i; + int offset = TUI_DISASM_WIN->detail.source_info.horizontal_offset; + int line_width, max_lines; + CORE_ADDR cur_pc; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + int tab_len = tui_default_tab_len (); + struct tui_asm_line* asm_lines; + int insn_pos; + int addr_size, max_size; + char* line; + + if (pc == 0) + return TUI_FAILURE; + + ret = tui_alloc_source_buffer (TUI_DISASM_WIN); + if (ret != TUI_SUCCESS) + return ret; + + TUI_DISASM_WIN->detail.source_info.start_line_or_addr.addr = pc; + cur_pc = (CORE_ADDR) + (((struct tui_win_element *) locator->content[0])->which_element.locator.addr); + + max_lines = TUI_DISASM_WIN->generic.height - 2; /* account for hilite */ + + /* Get temporary table that will hold all strings (addr & insn). */ + asm_lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line) + * max_lines); + memset (asm_lines, 0, sizeof (struct tui_asm_line) * max_lines); + + line_width = TUI_DISASM_WIN->generic.width - 1; + + tui_disassemble (asm_lines, pc, max_lines); + + /* See what is the maximum length of an address and of a line. */ + addr_size = 0; + max_size = 0; + for (i = 0; i < max_lines; i++) + { + size_t len = strlen (asm_lines[i].addr_string); + if (len > addr_size) + addr_size = len; + + len = strlen (asm_lines[i].insn) + tab_len; + if (len > max_size) + max_size = len; + } + max_size += addr_size + tab_len; + + /* Allocate memory to create each line. */ + line = (char*) alloca (max_size); + insn_pos = (1 + (addr_size / tab_len)) * tab_len; + + /* Now construct each line */ + for (i = 0; i < max_lines; i++) + { + struct tui_win_element * element; + struct tui_source_element* src; + int cur_len; + + element = (struct tui_win_element *) TUI_DISASM_WIN->generic.content[i]; + src = &element->which_element.source; + strcpy (line, asm_lines[i].addr_string); + cur_len = strlen (line); + + /* Add spaces to make the instructions start on the same column */ + while (cur_len < insn_pos) + { + strcat (line, " "); + cur_len++; + } + + strcat (line, asm_lines[i].insn); + + /* Now copy the line taking the offset into account */ + if (strlen (line) > offset) + strcpy (src->line, &line[offset]); + else + src->line[0] = '\0'; + + src->line_or_addr.addr = asm_lines[i].addr; + src->is_exec_point = asm_lines[i].addr == cur_pc; + + /* See whether there is a breakpoint installed. */ + src->has_break = (!src->is_exec_point + && breakpoint_here_p (pc) != no_breakpoint_here); + + xfree (asm_lines[i].addr_string); + xfree (asm_lines[i].insn); + } + TUI_DISASM_WIN->generic.content_size = i; + return TUI_SUCCESS; +} + + +/* Function to display the disassembly window with disassembled code. */ +void +tui_show_disassem (CORE_ADDR start_addr) +{ + struct symtab *s = find_pc_symtab (start_addr); + struct tui_win_info * win_with_focus = tui_win_with_focus (); + union tui_line_or_address val; + + val.addr = start_addr; + tui_add_win_to_layout (DISASSEM_WIN); + tui_update_source_window (TUI_DISASM_WIN, s, val, FALSE); + /* + ** if the focus was in the src win, put it in the asm win, if the + ** source view isn't split + */ + if (tui_current_layout () != SRC_DISASSEM_COMMAND && win_with_focus == TUI_SRC_WIN) + tui_set_win_focus_to (TUI_DISASM_WIN); + + return; +} + + +/* Function to display the disassembly window. */ +void +tui_show_disassem_and_update_source (CORE_ADDR start_addr) +{ + struct symtab_and_line sal; + + tui_show_disassem (start_addr); + if (tui_current_layout () == SRC_DISASSEM_COMMAND) + { + union tui_line_or_address val; + + /* + ** Update what is in the source window if it is displayed too, + ** note that it follows what is in the disassembly window and visa-versa + */ + sal = find_pc_line (start_addr, 0); + val.line_no = sal.line; + tui_update_source_window (TUI_SRC_WIN, sal.symtab, val, TRUE); + if (sal.symtab) + { + set_current_source_symtab_and_line (&sal); + tui_update_locator_filename (sal.symtab->filename); + } + else + tui_update_locator_filename ("?"); + } + + return; +} + +CORE_ADDR +tui_get_begin_asm_address (void) +{ + struct tui_gen_win_info * locator; + struct tui_locator_element * element; + CORE_ADDR addr; + + locator = tui_locator_win_info_ptr (); + element = &((struct tui_win_element *) locator->content[0])->which_element.locator; + + if (element->addr == 0) + { + struct minimal_symbol *main_symbol; + + /* Find address of the start of program. + Note: this should be language specific. */ + main_symbol = lookup_minimal_symbol ("main", NULL, NULL); + if (main_symbol == 0) + main_symbol = lookup_minimal_symbol ("MAIN", NULL, NULL); + if (main_symbol == 0) + main_symbol = lookup_minimal_symbol ("_start", NULL, NULL); + if (main_symbol) + addr = SYMBOL_VALUE_ADDRESS (main_symbol); + else + addr = 0; + } + else /* the target is executing */ + addr = element->addr; + + return addr; +} + +/* Determine what the low address will be to display in the TUI's + disassembly window. This may or may not be the same as the + low address input. */ +CORE_ADDR +tui_get_low_disassembly_address (CORE_ADDR low, CORE_ADDR pc) +{ + int pos; + + /* Determine where to start the disassembly so that the pc is about in the + middle of the viewport. */ + pos = tui_default_win_viewport_height (DISASSEM_WIN, DISASSEM_COMMAND) / 2; + pc = tui_find_disassembly_address (pc, -pos); + + if (pc < low) + pc = low; + return pc; +} + +/* Scroll the disassembly forward or backward vertically. */ +void +tui_vertical_disassem_scroll (enum tui_scroll_direction scroll_direction, + int num_to_scroll) +{ + if (TUI_DISASM_WIN->generic.content != NULL) + { + CORE_ADDR pc; + tui_win_content content; + struct symtab *s; + union tui_line_or_address val; + int max_lines, dir; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + content = (tui_win_content) TUI_DISASM_WIN->generic.content; + if (cursal.symtab == (struct symtab *) NULL) + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + else + s = cursal.symtab; + + /* account for hilite */ + max_lines = TUI_DISASM_WIN->generic.height - 2; + pc = content[0]->which_element.source.line_or_addr.addr; + dir = (scroll_direction == FORWARD_SCROLL) ? max_lines : - max_lines; + + val.addr = tui_find_disassembly_address (pc, dir); + tui_update_source_window_as_is (TUI_DISASM_WIN, s, val, FALSE); + } +} diff --git a/contrib/gdb/gdb/tui/tui-disasm.h b/contrib/gdb/gdb/tui/tui-disasm.h new file mode 100644 index 00000000000..e72aba1f3f1 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-disasm.h @@ -0,0 +1,37 @@ +/* Disassembly display. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_DISASM_H +#define TUI_DISASM_H + +#include "tui/tui.h" /* For enum tui_status. */ +#include "tui/tui-data.h" /* For enum tui_scroll_direction. */ + +extern enum tui_status tui_set_disassem_content (CORE_ADDR); +extern void tui_show_disassem (CORE_ADDR); +extern void tui_show_disassem_and_update_source (CORE_ADDR); +extern void tui_vertical_disassem_scroll (enum tui_scroll_direction, int); +extern CORE_ADDR tui_get_begin_asm_address (void); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-file.c b/contrib/gdb/gdb/tui/tui-file.c new file mode 100644 index 00000000000..5d2740ef066 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-file.c @@ -0,0 +1,238 @@ +/* UI_FILE - a generic STDIO like output stream. + Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "ui-file.h" +#include "tui/tui-file.h" +#include "tui/tui-io.h" + +#include "tui.h" + +#include "gdb_string.h" + +/* A ``struct ui_file'' that is compatible with all the legacy + code. */ + +/* new */ +enum streamtype +{ + afile, + astring +}; + +/* new */ +struct tui_stream +{ + int *ts_magic; + enum streamtype ts_streamtype; + FILE *ts_filestream; + char *ts_strbuf; + int ts_buflen; +}; + +static ui_file_flush_ftype tui_file_flush; +extern ui_file_fputs_ftype tui_file_fputs; +static ui_file_isatty_ftype tui_file_isatty; +static ui_file_rewind_ftype tui_file_rewind; +static ui_file_put_ftype tui_file_put; +static ui_file_delete_ftype tui_file_delete; +static struct ui_file *tui_file_new (void); +static int tui_file_magic; + +static struct ui_file * +tui_file_new (void) +{ + struct tui_stream *tui = xmalloc (sizeof (struct tui_stream)); + struct ui_file *file = ui_file_new (); + set_ui_file_data (file, tui, tui_file_delete); + set_ui_file_flush (file, tui_file_flush); + set_ui_file_fputs (file, tui_file_fputs); + set_ui_file_isatty (file, tui_file_isatty); + set_ui_file_rewind (file, tui_file_rewind); + set_ui_file_put (file, tui_file_put); + tui->ts_magic = &tui_file_magic; + return file; +} + +static void +tui_file_delete (struct ui_file *file) +{ + struct tui_stream *tmpstream = ui_file_data (file); + if (tmpstream->ts_magic != &tui_file_magic) + internal_error (__FILE__, __LINE__, + "tui_file_delete: bad magic number"); + if ((tmpstream->ts_streamtype == astring) && + (tmpstream->ts_strbuf != NULL)) + { + xfree (tmpstream->ts_strbuf); + } + xfree (tmpstream); +} + +struct ui_file * +tui_fileopen (FILE *stream) +{ + struct ui_file *file = tui_file_new (); + struct tui_stream *tmpstream = ui_file_data (file); + tmpstream->ts_streamtype = afile; + tmpstream->ts_filestream = stream; + tmpstream->ts_strbuf = NULL; + tmpstream->ts_buflen = 0; + return file; +} + +struct ui_file * +tui_sfileopen (int n) +{ + struct ui_file *file = tui_file_new (); + struct tui_stream *tmpstream = ui_file_data (file); + tmpstream->ts_streamtype = astring; + tmpstream->ts_filestream = NULL; + if (n > 0) + { + tmpstream->ts_strbuf = xmalloc ((n + 1) * sizeof (char)); + tmpstream->ts_strbuf[0] = '\0'; + } + else + /* Do not allocate the buffer now. The first time something is printed + one will be allocated by tui_file_adjust_strbuf() */ + tmpstream->ts_strbuf = NULL; + tmpstream->ts_buflen = n; + return file; +} + +static int +tui_file_isatty (struct ui_file *file) +{ + struct tui_stream *stream = ui_file_data (file); + if (stream->ts_magic != &tui_file_magic) + internal_error (__FILE__, __LINE__, + "tui_file_isatty: bad magic number"); + if (stream->ts_streamtype == afile) + return (isatty (fileno (stream->ts_filestream))); + else + return 0; +} + +static void +tui_file_rewind (struct ui_file *file) +{ + struct tui_stream *stream = ui_file_data (file); + if (stream->ts_magic != &tui_file_magic) + internal_error (__FILE__, __LINE__, + "tui_file_rewind: bad magic number"); + stream->ts_strbuf[0] = '\0'; +} + +static void +tui_file_put (struct ui_file *file, + ui_file_put_method_ftype *write, + void *dest) +{ + struct tui_stream *stream = ui_file_data (file); + if (stream->ts_magic != &tui_file_magic) + internal_error (__FILE__, __LINE__, + "tui_file_put: bad magic number"); + if (stream->ts_streamtype == astring) + write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf)); +} + +/* All TUI I/O sent to the *_filtered and *_unfiltered functions + eventually ends up here. The fputs_unfiltered_hook is primarily + used by GUIs to collect all output and send it to the GUI, instead + of the controlling terminal. Only output to gdb_stdout and + gdb_stderr are sent to the hook. Everything else is sent on to + fputs to allow file I/O to be handled appropriately. */ + +/* FIXME: Should be broken up and moved to a TUI specific file. */ + +void +tui_file_fputs (const char *linebuffer, struct ui_file *file) +{ + struct tui_stream *stream = ui_file_data (file); + + if (stream->ts_streamtype == astring) + { + tui_file_adjust_strbuf (strlen (linebuffer), file); + strcat (stream->ts_strbuf, linebuffer); + } + else + { + tui_puts (linebuffer); + } +} + +char * +tui_file_get_strbuf (struct ui_file *file) +{ + struct tui_stream *stream = ui_file_data (file); + if (stream->ts_magic != &tui_file_magic) + internal_error (__FILE__, __LINE__, + "tui_file_get_strbuf: bad magic number"); + return (stream->ts_strbuf); +} + +/* adjust the length of the buffer by the amount necessary + to accomodate appending a string of length N to the buffer contents */ +void +tui_file_adjust_strbuf (int n, struct ui_file *file) +{ + struct tui_stream *stream = ui_file_data (file); + int non_null_chars; + if (stream->ts_magic != &tui_file_magic) + internal_error (__FILE__, __LINE__, + "tui_file_adjust_strbuf: bad magic number"); + + if (stream->ts_streamtype != astring) + return; + + if (stream->ts_strbuf) + { + /* There is already a buffer allocated */ + non_null_chars = strlen (stream->ts_strbuf); + + if (n > (stream->ts_buflen - non_null_chars - 1)) + { + stream->ts_buflen = n + non_null_chars + 1; + stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen); + } + } + else + /* No buffer yet, so allocate one of the desired size */ + stream->ts_strbuf = xmalloc ((n + 1) * sizeof (char)); +} + +static void +tui_file_flush (struct ui_file *file) +{ + struct tui_stream *stream = ui_file_data (file); + if (stream->ts_magic != &tui_file_magic) + internal_error (__FILE__, __LINE__, + "tui_file_flush: bad magic number"); + + switch (stream->ts_streamtype) + { + case astring: + break; + case afile: + fflush (stream->ts_filestream); + break; + } +} diff --git a/contrib/gdb/gdb/tui/tui-file.h b/contrib/gdb/gdb/tui/tui-file.h new file mode 100644 index 00000000000..ea0729716d2 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-file.h @@ -0,0 +1,29 @@ +/* UI_FILE - a generic STDIO like output stream. + Copyright 1999, 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_FILE_H +#define TUI_FILE_H + +extern struct ui_file *tui_fileopen (FILE *); +extern struct ui_file *tui_sfileopen (int); +extern char *tui_file_get_strbuf (struct ui_file *); +extern void tui_file_adjust_strbuf (int, struct ui_file *); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-hooks.c b/contrib/gdb/gdb/tui/tui-hooks.c new file mode 100644 index 00000000000..a864be28276 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-hooks.c @@ -0,0 +1,320 @@ +/* GDB hooks for TUI. + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "inferior.h" +#include "command.h" +#include "bfd.h" +#include "symfile.h" +#include "objfiles.h" +#include "target.h" +#include "gdbcore.h" +#include "event-loop.h" +#include "event-top.h" +#include "frame.h" +#include "breakpoint.h" +#include "gdb-events.h" +#include "ui-out.h" +#include "top.h" +#include "readline/readline.h" +#include +#include + +#include "tui/tui.h" +#include "tui/tui-hooks.h" +#include "tui/tui-data.h" +#include "tui/tui-layout.h" +#include "tui/tui-io.h" +#include "tui/tui-regs.h" +#include "tui/tui-win.h" +#include "tui/tui-stack.h" +#include "tui/tui-windata.h" +#include "tui/tui-winsource.h" + +#include "gdb_curses.h" + +int tui_target_has_run = 0; + +static void (* tui_target_new_objfile_chain) (struct objfile*); + +static void +tui_new_objfile_hook (struct objfile* objfile) +{ + if (tui_active) + tui_display_main (); + + if (tui_target_new_objfile_chain) + tui_target_new_objfile_chain (objfile); +} + +static int +tui_query_hook (const char * msg, va_list argp) +{ + int retval; + int ans2; + int answer; + + /* Automatically answer "yes" if input is not from a terminal. */ + if (!input_from_terminal_p ()) + return 1; + + echo (); + while (1) + { + wrap_here (""); /* Flush any buffered output */ + gdb_flush (gdb_stdout); + + vfprintf_filtered (gdb_stdout, msg, argp); + printf_filtered ("(y or n) "); + + wrap_here (""); + gdb_flush (gdb_stdout); + + answer = tui_getc (stdin); + clearerr (stdin); /* in case of C-d */ + if (answer == EOF) /* C-d */ + { + retval = 1; + break; + } + /* Eat rest of input line, to EOF or newline */ + if (answer != '\n') + do + { + ans2 = tui_getc (stdin); + clearerr (stdin); + } + while (ans2 != EOF && ans2 != '\n' && ans2 != '\r'); + + if (answer >= 'a') + answer -= 040; + if (answer == 'Y') + { + retval = 1; + break; + } + if (answer == 'N') + { + retval = 0; + break; + } + printf_filtered ("Please answer y or n.\n"); + } + noecho (); + return retval; +} + +/* Prevent recursion of registers_changed_hook(). */ +static int tui_refreshing_registers = 0; + +static void +tui_registers_changed_hook (void) +{ + struct frame_info *fi; + + fi = deprecated_selected_frame; + if (fi && tui_refreshing_registers == 0) + { + tui_refreshing_registers = 1; +#if 0 + tui_check_data_values (fi); +#endif + tui_refreshing_registers = 0; + } +} + +static void +tui_register_changed_hook (int regno) +{ + struct frame_info *fi; + + fi = deprecated_selected_frame; + if (fi && tui_refreshing_registers == 0) + { + tui_refreshing_registers = 1; + tui_check_data_values (fi); + tui_refreshing_registers = 0; + } +} + +/* Breakpoint creation hook. + Update the screen to show the new breakpoint. */ +static void +tui_event_create_breakpoint (int number) +{ + tui_update_all_breakpoint_info (); +} + +/* Breakpoint deletion hook. + Refresh the screen to update the breakpoint marks. */ +static void +tui_event_delete_breakpoint (int number) +{ + tui_update_all_breakpoint_info (); +} + +static void +tui_event_modify_breakpoint (int number) +{ + tui_update_all_breakpoint_info (); +} + +static void +tui_event_default (int number) +{ + ; +} + +static struct gdb_events *tui_old_event_hooks; + +static struct gdb_events tui_event_hooks = +{ + tui_event_create_breakpoint, + tui_event_delete_breakpoint, + tui_event_modify_breakpoint, + tui_event_default, + tui_event_default, + tui_event_default +}; + +/* Called when going to wait for the target. + Leave curses mode and setup program mode. */ +static ptid_t +tui_target_wait_hook (ptid_t pid, struct target_waitstatus *status) +{ + ptid_t res; + + /* Leave tui mode (optional). */ +#if 0 + if (tui_active) + { + target_terminal_ours (); + endwin (); + target_terminal_inferior (); + } +#endif + tui_target_has_run = 1; + res = target_wait (pid, status); + + if (tui_active) + { + /* TODO: need to refresh (optional). */ + } + return res; +} + +/* The selected frame has changed. This is happens after a target + stop or when the user explicitly changes the frame (up/down/thread/...). */ +static void +tui_selected_frame_level_changed_hook (int level) +{ + struct frame_info *fi; + + fi = deprecated_selected_frame; + /* Ensure that symbols for this frame are read in. Also, determine the + source language of this frame, and switch to it if desired. */ + if (fi) + { + struct symtab *s; + + s = find_pc_symtab (get_frame_pc (fi)); + /* elz: this if here fixes the problem with the pc not being displayed + in the tui asm layout, with no debug symbols. The value of s + would be 0 here, and select_source_symtab would abort the + command by calling the 'error' function */ + if (s) + select_source_symtab (s); + + /* Display the frame position (even if there is no symbols). */ + tui_show_frame_info (fi); + + /* Refresh the register window if it's visible. */ + if (tui_is_window_visible (DATA_WIN)) + { + tui_refreshing_registers = 1; + tui_check_data_values (fi); + tui_refreshing_registers = 0; + } + } +} + +/* Called from print_frame_info to list the line we stopped in. */ +static void +tui_print_frame_info_listing_hook (struct symtab *s, int line, + int stopline, int noerror) +{ + select_source_symtab (s); + tui_show_frame_info (deprecated_selected_frame); +} + +/* Called when the target process died or is detached. + Update the status line. */ +static void +tui_detach_hook (void) +{ + tui_show_frame_info (0); + tui_display_main (); +} + +/* Install the TUI specific hooks. */ +void +tui_install_hooks (void) +{ + target_wait_hook = tui_target_wait_hook; + selected_frame_level_changed_hook = tui_selected_frame_level_changed_hook; + print_frame_info_listing_hook = tui_print_frame_info_listing_hook; + + query_hook = tui_query_hook; + + /* Install the event hooks. */ + tui_old_event_hooks = set_gdb_event_hooks (&tui_event_hooks); + + registers_changed_hook = tui_registers_changed_hook; + register_changed_hook = tui_register_changed_hook; + detach_hook = tui_detach_hook; +} + +/* Remove the TUI specific hooks. */ +void +tui_remove_hooks (void) +{ + target_wait_hook = 0; + selected_frame_level_changed_hook = 0; + print_frame_info_listing_hook = 0; + query_hook = 0; + registers_changed_hook = 0; + register_changed_hook = 0; + detach_hook = 0; + + /* Restore the previous event hooks. */ + set_gdb_event_hooks (tui_old_event_hooks); +} + +void _initialize_tui_hooks (void); + +void +_initialize_tui_hooks (void) +{ + /* Install the permanent hooks. */ + tui_target_new_objfile_chain = target_new_objfile_hook; + target_new_objfile_hook = tui_new_objfile_hook; +} diff --git a/contrib/gdb/gdb/tui/tui-hooks.h b/contrib/gdb/gdb/tui/tui-hooks.h new file mode 100644 index 00000000000..fa1137dfa22 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-hooks.h @@ -0,0 +1,28 @@ +/* External/Public TUI hools header file, for GDB the GNU debugger. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_HOOKS_H +#define TUI_HOOKS_H + +extern void tui_install_hooks (void); +extern void tui_remove_hooks (void); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-interp.c b/contrib/gdb/gdb/tui/tui-interp.c new file mode 100644 index 00000000000..1e1d6432321 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-interp.c @@ -0,0 +1,210 @@ +/* TUI Interpreter definitions for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "interps.h" +#include "top.h" +#include "event-top.h" +#include "event-loop.h" +#include "ui-out.h" +#include "cli-out.h" +#include "tui/tui-data.h" +#include "readline/readline.h" +#include "tui/tui-win.h" +#include "tui/tui.h" +#include "tui/tui-io.h" + +/* Set to 1 when the TUI mode must be activated when we first start gdb. */ +static int tui_start_enabled = 0; + +/* Cleanup the tui before exiting. */ + +static void +tui_exit (void) +{ + /* Disable the tui. Curses mode is left leaving the screen + in a clean state (see endwin()). */ + tui_disable (); +} + +/* These implement the TUI interpreter. */ + +static void * +tui_init (void) +{ + /* Install exit handler to leave the screen in a good shape. */ + atexit (tui_exit); + + tui_initialize_static_data (); + + tui_initialize_io (); + tui_initialize_readline (); + + return NULL; +} + +static int +tui_resume (void *data) +{ + struct ui_file *stream; + + /* gdb_setup_readline will change gdb_stdout. If the TUI was previously + writing to gdb_stdout, then set it to the new gdb_stdout afterwards. */ + + stream = cli_out_set_stream (tui_old_uiout, gdb_stdout); + if (stream != gdb_stdout) + { + cli_out_set_stream (tui_old_uiout, stream); + stream = NULL; + } + + gdb_setup_readline (); + + if (stream != NULL) + cli_out_set_stream (tui_old_uiout, gdb_stdout); + + if (tui_start_enabled) + tui_enable (); + return 1; +} + +static int +tui_suspend (void *data) +{ + tui_start_enabled = tui_active; + tui_disable (); + return 1; +} + +/* Display the prompt if we are silent. */ + +static int +tui_display_prompt_p (void *data) +{ + if (interp_quiet_p (NULL)) + return 0; + else + return 1; +} + +static int +tui_exec (void *data, const char *command_str) +{ + internal_error (__FILE__, __LINE__, "tui_exec called"); +} + + +/* Initialize all the necessary variables, start the event loop, + register readline, and stdin, start the loop. */ + +static void +tui_command_loop (void *data) +{ + int length; + char *a_prompt; + char *gdb_prompt = get_prompt (); + + /* If we are using readline, set things up and display the first + prompt, otherwise just print the prompt. */ + if (async_command_editing_p) + { + /* Tell readline what the prompt to display is and what function + it will need to call after a whole line is read. This also + displays the first prompt. */ + length = strlen (PREFIX (0)) + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1; + a_prompt = (char *) xmalloc (length); + strcpy (a_prompt, PREFIX (0)); + strcat (a_prompt, gdb_prompt); + strcat (a_prompt, SUFFIX (0)); + rl_callback_handler_install (a_prompt, input_handler); + } + else + display_gdb_prompt (0); + + /* Loop until there is nothing to do. This is the entry point to the + event loop engine. gdb_do_one_event, called via catch_errors() + will process one event for each invocation. It blocks waits for + an event and then processes it. >0 when an event is processed, 0 + when catch_errors() caught an error and <0 when there are no + longer any event sources registered. */ + while (1) + { + int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); + if (result < 0) + break; + + /* Update gdb output according to TUI mode. Since catch_errors + preserves the uiout from changing, this must be done at top + level of event loop. */ + if (tui_active) + uiout = tui_out; + else + uiout = tui_old_uiout; + + if (result == 0) + { + /* FIXME: this should really be a call to a hook that is + interface specific, because interfaces can display the + prompt in their own way. */ + display_gdb_prompt (0); + /* This call looks bizarre, but it is required. If the user + entered a command that caused an error, + after_char_processing_hook won't be called from + rl_callback_read_char_wrapper. Using a cleanup there + won't work, since we want this function to be called + after a new prompt is printed. */ + if (after_char_processing_hook) + (*after_char_processing_hook) (); + /* Maybe better to set a flag to be checked somewhere as to + whether display the prompt or not. */ + } + } + + /* We are done with the event loop. There are no more event sources + to listen to. So we exit GDB. */ + return; +} + +void +_initialize_tui_interp (void) +{ + static const struct interp_procs procs = { + tui_init, + tui_resume, + tui_suspend, + tui_exec, + tui_display_prompt_p, + tui_command_loop, + }; + struct interp *tui_interp; + + /* Create a default uiout builder for the TUI. */ + tui_out = tui_out_new (gdb_stdout); + interp_add (interp_new ("tui", NULL, tui_out, &procs)); + if (interpreter_p && strcmp (interpreter_p, "tui") == 0) + tui_start_enabled = 1; + + if (interpreter_p && strcmp (interpreter_p, INTERP_CONSOLE) == 0) + { + xfree (interpreter_p); + interpreter_p = xstrdup ("tui"); + } +} diff --git a/contrib/gdb/gdb/tui/tui-io.c b/contrib/gdb/gdb/tui/tui-io.c new file mode 100644 index 00000000000..addb3b003c4 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-io.c @@ -0,0 +1,708 @@ +/* TUI support I/O functions. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "terminal.h" +#include "target.h" +#include "event-loop.h" +#include "event-top.h" +#include "command.h" +#include "top.h" +#include "readline/readline.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-io.h" +#include "tui/tui-command.h" +#include "tui/tui-win.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-file.h" +#include "ui-out.h" +#include "cli-out.h" +#include +#include +#include + +#include "gdb_curses.h" + +int +key_is_start_sequence (int ch) +{ + return (ch == 27); +} + +int +key_is_end_sequence (int ch) +{ + return (ch == 126); +} + +int +key_is_backspace (int ch) +{ + return (ch == 8); +} + +int +key_is_command_char (int ch) +{ + return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE) + || (ch == KEY_LEFT) || (ch == KEY_RIGHT) + || (ch == KEY_UP) || (ch == KEY_DOWN) + || (ch == KEY_SF) || (ch == KEY_SR) + || (ch == (int)'\f') || key_is_start_sequence (ch)); +} + +/* Use definition from readline 4.3. */ +#undef CTRL_CHAR +#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) + +/* This file controls the IO interactions between gdb and curses. + When the TUI is enabled, gdb has two modes a curses and a standard + mode. + + In curses mode, the gdb outputs are made in a curses command window. + For this, the gdb_stdout and gdb_stderr are redirected to the specific + ui_file implemented by TUI. The output is handled by tui_puts(). + The input is also controlled by curses with tui_getc(). The readline + library uses this function to get its input. Several readline hooks + are installed to redirect readline output to the TUI (see also the + note below). + + In normal mode, the gdb outputs are restored to their origin, that + is as if TUI is not used. Readline also uses its original getc() + function with stdin. + + Note SCz/2001-07-21: the current readline is not clean in its management of + the output. Even if we install a redisplay handler, it sometimes writes on + a stdout file. It is important to redirect every output produced by + readline, otherwise the curses window will be garbled. This is implemented + with a pipe that TUI reads and readline writes to. A gdb input handler + is created so that reading the pipe is handled automatically. + This will probably not work on non-Unix platforms. The best fix is + to make readline clean enougth so that is never write on stdout. + + Note SCz/2002-09-01: we now use more readline hooks and it seems that + with them we don't need the pipe anymore (verified by creating the pipe + and closing its end so that write causes a SIGPIPE). The old pipe code + is still there and can be conditionally removed by + #undef TUI_USE_PIPE_FOR_READLINE. */ + +/* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */ +#define TUI_USE_PIPE_FOR_READLINE +/*#undef TUI_USE_PIPE_FOR_READLINE*/ + +/* TUI output files. */ +static struct ui_file *tui_stdout; +static struct ui_file *tui_stderr; +struct ui_out *tui_out; + +/* GDB output files in non-curses mode. */ +static struct ui_file *tui_old_stdout; +static struct ui_file *tui_old_stderr; +struct ui_out *tui_old_uiout; + +/* Readline previous hooks. */ +static Function *tui_old_rl_getc_function; +static VFunction *tui_old_rl_redisplay_function; +static VFunction *tui_old_rl_prep_terminal; +static VFunction *tui_old_rl_deprep_terminal; +static int tui_old_readline_echoing_p; + +/* Readline output stream. + Should be removed when readline is clean. */ +static FILE *tui_rl_outstream; +static FILE *tui_old_rl_outstream; +#ifdef TUI_USE_PIPE_FOR_READLINE +static int tui_readline_pipe[2]; +#endif + +/* The last gdb prompt that was registered in readline. + This may be the main gdb prompt or a secondary prompt. */ +static char *tui_rl_saved_prompt; + +static unsigned int tui_handle_resize_during_io (unsigned int); + +static void +tui_putc (char c) +{ + char buf[2]; + + buf[0] = c; + buf[1] = 0; + tui_puts (buf); +} + +/* Print the string in the curses command window. */ +void +tui_puts (const char *string) +{ + static int tui_skip_line = -1; + char c; + WINDOW *w; + + w = TUI_CMD_WIN->generic.handle; + while ((c = *string++) != 0) + { + /* Catch annotation and discard them. We need two \032 and + discard until a \n is seen. */ + if (c == '\032') + { + tui_skip_line++; + } + else if (tui_skip_line != 1) + { + tui_skip_line = -1; + waddch (w, c); + } + else if (c == '\n') + tui_skip_line = -1; + } + getyx (w, TUI_CMD_WIN->detail.command_info.cur_line, + TUI_CMD_WIN->detail.command_info.curch); + TUI_CMD_WIN->detail.command_info.start_line = TUI_CMD_WIN->detail.command_info.cur_line; + + /* We could defer the following. */ + wrefresh (w); + fflush (stdout); +} + +/* Readline callback. + Redisplay the command line with its prompt after readline has + changed the edited text. */ +void +tui_redisplay_readline (void) +{ + int prev_col; + int height; + int col, line; + int c_pos; + int c_line; + int in; + WINDOW *w; + char *prompt; + int start_line; + + /* Detect when we temporarily left SingleKey and now the readline + edit buffer is empty, automatically restore the SingleKey mode. */ + if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0) + tui_set_key_mode (TUI_SINGLE_KEY_MODE); + + if (tui_current_key_mode == TUI_SINGLE_KEY_MODE) + prompt = ""; + else + prompt = tui_rl_saved_prompt; + + c_pos = -1; + c_line = -1; + w = TUI_CMD_WIN->generic.handle; + start_line = TUI_CMD_WIN->detail.command_info.start_line; + wmove (w, start_line, 0); + prev_col = 0; + height = 1; + for (in = 0; prompt && prompt[in]; in++) + { + waddch (w, prompt[in]); + getyx (w, line, col); + if (col < prev_col) + height++; + prev_col = col; + } + for (in = 0; in < rl_end; in++) + { + unsigned char c; + + c = (unsigned char) rl_line_buffer[in]; + if (in == rl_point) + { + getyx (w, c_line, c_pos); + } + + if (CTRL_CHAR (c) || c == RUBOUT) + { + waddch (w, '^'); + waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?'); + } + else + { + waddch (w, c); + } + if (c == '\n') + { + getyx (w, TUI_CMD_WIN->detail.command_info.start_line, + TUI_CMD_WIN->detail.command_info.curch); + } + getyx (w, line, col); + if (col < prev_col) + height++; + prev_col = col; + } + wclrtobot (w); + getyx (w, TUI_CMD_WIN->detail.command_info.start_line, + TUI_CMD_WIN->detail.command_info.curch); + if (c_line >= 0) + { + wmove (w, c_line, c_pos); + TUI_CMD_WIN->detail.command_info.cur_line = c_line; + TUI_CMD_WIN->detail.command_info.curch = c_pos; + } + TUI_CMD_WIN->detail.command_info.start_line -= height - 1; + + wrefresh (w); + fflush(stdout); +} + +/* Readline callback to prepare the terminal. It is called once + each time we enter readline. Terminal is already setup in curses mode. */ +static void +tui_prep_terminal (int notused1) +{ + /* Save the prompt registered in readline to correctly display it. + (we can't use gdb_prompt() due to secondary prompts and can't use + rl_prompt because it points to an alloca buffer). */ + xfree (tui_rl_saved_prompt); + tui_rl_saved_prompt = xstrdup (rl_prompt); +} + +/* Readline callback to restore the terminal. It is called once + each time we leave readline. There is nothing to do in curses mode. */ +static void +tui_deprep_terminal (void) +{ +} + +#ifdef TUI_USE_PIPE_FOR_READLINE +/* Read readline output pipe and feed the command window with it. + Should be removed when readline is clean. */ +static void +tui_readline_output (int code, gdb_client_data data) +{ + int size; + char buf[256]; + + size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1); + if (size > 0 && tui_active) + { + buf[size] = 0; + tui_puts (buf); + } +} +#endif + +/* Return the portion of PATHNAME that should be output when listing + possible completions. If we are hacking filename completion, we + are only interested in the basename, the portion following the + final slash. Otherwise, we return what we were passed. + + Comes from readline/complete.c */ +static char * +printable_part (char *pathname) +{ + char *temp; + + temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL; +#if defined (__MSDOS__) + if (rl_filename_completion_desired && temp == 0 && isalpha (pathname[0]) && pathname[1] == ':') + temp = pathname + 1; +#endif + return (temp ? ++temp : pathname); +} + +/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we + are using it, check for and output a single character for `special' + filenames. Return the number of characters we output. */ + +#define PUTX(c) \ + do { \ + if (CTRL_CHAR (c)) \ + { \ + tui_puts ("^"); \ + tui_putc (UNCTRL (c)); \ + printed_len += 2; \ + } \ + else if (c == RUBOUT) \ + { \ + tui_puts ("^?"); \ + printed_len += 2; \ + } \ + else \ + { \ + tui_putc (c); \ + printed_len++; \ + } \ + } while (0) + +static int +print_filename (char *to_print, char *full_pathname) +{ + int printed_len = 0; + char *s; + + for (s = to_print; *s; s++) + { + PUTX (*s); + } + return printed_len; +} + +/* The user must press "y" or "n". Non-zero return means "y" pressed. + Comes from readline/complete.c */ +static int +get_y_or_n (void) +{ + extern int _rl_abort_internal (); + int c; + + for (;;) + { + c = rl_read_key (); + if (c == 'y' || c == 'Y' || c == ' ') + return (1); + if (c == 'n' || c == 'N' || c == RUBOUT) + return (0); + if (c == ABORT_CHAR) + _rl_abort_internal (); + beep (); + } +} + +/* A convenience function for displaying a list of strings in + columnar format on readline's output stream. MATCHES is the list + of strings, in argv format, LEN is the number of strings in MATCHES, + and MAX is the length of the longest string in MATCHES. + + Comes from readline/complete.c and modified to write in + the TUI command window using tui_putc/tui_puts. */ +static void +tui_rl_display_match_list (char **matches, int len, int max) +{ + typedef int QSFUNC (const void *, const void *); + extern int _rl_qsort_string_compare (const void*, const void*); + extern int _rl_print_completions_horizontally; + + int count, limit, printed_len; + int i, j, k, l; + char *temp; + + /* Screen dimension correspond to the TUI command window. */ + int screenwidth = TUI_CMD_WIN->generic.width; + + /* If there are many items, then ask the user if she really wants to + see them all. */ + if (len >= rl_completion_query_items) + { + char msg[256]; + + sprintf (msg, "\nDisplay all %d possibilities? (y or n)", len); + tui_puts (msg); + if (get_y_or_n () == 0) + { + tui_puts ("\n"); + return; + } + } + + /* How many items of MAX length can we fit in the screen window? */ + max += 2; + limit = screenwidth / max; + if (limit != 1 && (limit * max == screenwidth)) + limit--; + + /* Avoid a possible floating exception. If max > screenwidth, + limit will be 0 and a divide-by-zero fault will result. */ + if (limit == 0) + limit = 1; + + /* How many iterations of the printing loop? */ + count = (len + (limit - 1)) / limit; + + /* Watch out for special case. If LEN is less than LIMIT, then + just do the inner printing loop. + 0 < len <= limit implies count = 1. */ + + /* Sort the items if they are not already sorted. */ + if (rl_ignore_completion_duplicates == 0) + qsort (matches + 1, len, sizeof (char *), + (QSFUNC *)_rl_qsort_string_compare); + + tui_putc ('\n'); + + if (_rl_print_completions_horizontally == 0) + { + /* Print the sorted items, up-and-down alphabetically, like ls. */ + for (i = 1; i <= count; i++) + { + for (j = 0, l = i; j < limit; j++) + { + if (l > len || matches[l] == 0) + break; + else + { + temp = printable_part (matches[l]); + printed_len = print_filename (temp, matches[l]); + + if (j + 1 < limit) + for (k = 0; k < max - printed_len; k++) + tui_putc (' '); + } + l += count; + } + tui_putc ('\n'); + } + } + else + { + /* Print the sorted items, across alphabetically, like ls -x. */ + for (i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + printed_len = print_filename (temp, matches[i]); + /* Have we reached the end of this line? */ + if (matches[i+1]) + { + if (i && (limit > 1) && (i % limit) == 0) + tui_putc ('\n'); + else + for (k = 0; k < max - printed_len; k++) + tui_putc (' '); + } + } + tui_putc ('\n'); + } +} + +/* Setup the IO for curses or non-curses mode. + - In non-curses mode, readline and gdb use the standard input and + standard output/error directly. + - In curses mode, the standard output/error is controlled by TUI + with the tui_stdout and tui_stderr. The output is redirected in + the curses command window. Several readline callbacks are installed + so that readline asks for its input to the curses command window + with wgetch(). */ +void +tui_setup_io (int mode) +{ + extern int readline_echoing_p; + + if (mode) + { + /* Redirect readline to TUI. */ + tui_old_rl_redisplay_function = rl_redisplay_function; + tui_old_rl_deprep_terminal = rl_deprep_term_function; + tui_old_rl_prep_terminal = rl_prep_term_function; + tui_old_rl_getc_function = rl_getc_function; + tui_old_rl_outstream = rl_outstream; + tui_old_readline_echoing_p = readline_echoing_p; + rl_redisplay_function = tui_redisplay_readline; + rl_deprep_term_function = tui_deprep_terminal; + rl_prep_term_function = tui_prep_terminal; + rl_getc_function = tui_getc; + readline_echoing_p = 0; + rl_outstream = tui_rl_outstream; + rl_prompt = 0; + rl_completion_display_matches_hook = tui_rl_display_match_list; + rl_already_prompted = 0; + + /* Keep track of previous gdb output. */ + tui_old_stdout = gdb_stdout; + tui_old_stderr = gdb_stderr; + tui_old_uiout = uiout; + + /* Reconfigure gdb output. */ + gdb_stdout = tui_stdout; + gdb_stderr = tui_stderr; + gdb_stdlog = gdb_stdout; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ + uiout = tui_out; + + /* Save tty for SIGCONT. */ + savetty (); + } + else + { + /* Restore gdb output. */ + gdb_stdout = tui_old_stdout; + gdb_stderr = tui_old_stderr; + gdb_stdlog = gdb_stdout; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ + uiout = tui_old_uiout; + + /* Restore readline. */ + rl_redisplay_function = tui_old_rl_redisplay_function; + rl_deprep_term_function = tui_old_rl_deprep_terminal; + rl_prep_term_function = tui_old_rl_prep_terminal; + rl_getc_function = tui_old_rl_getc_function; + rl_outstream = tui_old_rl_outstream; + rl_completion_display_matches_hook = 0; + readline_echoing_p = tui_old_readline_echoing_p; + rl_already_prompted = 0; + + /* Save tty for SIGCONT. */ + savetty (); + } +} + +#ifdef SIGCONT +/* Catch SIGCONT to restore the terminal and refresh the screen. */ +static void +tui_cont_sig (int sig) +{ + if (tui_active) + { + /* Restore the terminal setting because another process (shell) + might have changed it. */ + resetty (); + + /* Force a refresh of the screen. */ + tui_refresh_all_win (); + + /* Update cursor position on the screen. */ + wmove (TUI_CMD_WIN->generic.handle, + TUI_CMD_WIN->detail.command_info.start_line, + TUI_CMD_WIN->detail.command_info.curch); + wrefresh (TUI_CMD_WIN->generic.handle); + } + signal (sig, tui_cont_sig); +} +#endif + +/* Initialize the IO for gdb in curses mode. */ +void +tui_initialize_io (void) +{ +#ifdef SIGCONT + signal (SIGCONT, tui_cont_sig); +#endif + + /* Create tui output streams. */ + tui_stdout = tui_fileopen (stdout); + tui_stderr = tui_fileopen (stderr); + tui_out = tui_out_new (tui_stdout); + + /* Create the default UI. It is not created because we installed + a init_ui_hook. */ + tui_old_uiout = uiout = cli_out_new (gdb_stdout); + +#ifdef TUI_USE_PIPE_FOR_READLINE + /* Temporary solution for readline writing to stdout: + redirect readline output in a pipe, read that pipe and + output the content in the curses command window. */ + if (pipe (tui_readline_pipe) != 0) + { + fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline"); + exit (1); + } + tui_rl_outstream = fdopen (tui_readline_pipe[1], "w"); + if (tui_rl_outstream == 0) + { + fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output"); + exit (1); + } + setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0); + +#ifdef O_NONBLOCK + (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK); +#else +#ifdef O_NDELAY + (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY); +#endif +#endif + add_file_handler (tui_readline_pipe[0], tui_readline_output, 0); +#else + tui_rl_outstream = stdout; +#endif +} + +/* Get a character from the command window. This is called from the readline + package. */ +int +tui_getc (FILE *fp) +{ + int ch; + WINDOW *w; + + w = TUI_CMD_WIN->generic.handle; + +#ifdef TUI_USE_PIPE_FOR_READLINE + /* Flush readline output. */ + tui_readline_output (GDB_READABLE, 0); +#endif + + ch = wgetch (w); + ch = tui_handle_resize_during_io (ch); + + /* The \n must be echoed because it will not be printed by readline. */ + if (ch == '\n') + { + /* When hitting return with an empty input, gdb executes the last + command. If we emit a newline, this fills up the command window + with empty lines with gdb prompt at beginning. Instead of that, + stay on the same line but provide a visual effect to show the + user we recognized the command. */ + if (rl_end == 0) + { + wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0); + + /* Clear the line. This will blink the gdb prompt since + it will be redrawn at the same line. */ + wclrtoeol (w); + wrefresh (w); + napms (20); + } + else + { + wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, + TUI_CMD_WIN->detail.command_info.curch); + waddch (w, ch); + } + } + + if (key_is_command_char (ch)) + { /* Handle prev/next/up/down here */ + ch = tui_dispatch_ctrl_char (ch); + } + + if (ch == '\n' || ch == '\r' || ch == '\f') + TUI_CMD_WIN->detail.command_info.curch = 0; + if (ch == KEY_BACKSPACE) + return '\b'; + + return ch; +} + + +/* Cleanup when a resize has occured. + Returns the character that must be processed. */ +static unsigned int +tui_handle_resize_during_io (unsigned int original_ch) +{ + if (tui_win_resized ()) + { + tui_refresh_all_win (); + dont_repeat (); + tui_set_win_resized_to (FALSE); + return '\n'; + } + else + return original_ch; +} diff --git a/contrib/gdb/gdb/tui/tui-io.h b/contrib/gdb/gdb/tui/tui-io.h new file mode 100644 index 00000000000..06d085de93f --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-io.h @@ -0,0 +1,55 @@ +/* TUI support I/O functions. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_IO_H +#define TUI_IO_H + +struct ui_out; + +/* Print the string in the curses command window. */ +extern void tui_puts (const char *); + +/* Setup the IO for curses or non-curses mode. */ +extern void tui_setup_io (int mode); + +/* Initialize the IO for gdb in curses mode. */ +extern void tui_initialize_io (void); + +/* Get a character from the command window. */ +extern int tui_getc (FILE *); + +/* Readline callback. + Redisplay the command line with its prompt after readline has + changed the edited text. */ +extern void tui_redisplay_readline (void); + +extern struct ui_out *tui_out; +extern struct ui_out *tui_old_uiout; + +extern int key_is_start_sequence (int ch); +extern int key_is_end_sequence (int ch); +extern int key_is_backspace (int ch); +extern int key_is_command_char (int ch); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-layout.c b/contrib/gdb/gdb/tui/tui-layout.c new file mode 100644 index 00000000000..f2d4412414d --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-layout.c @@ -0,0 +1,1072 @@ +/* TUI layout window management. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "command.h" +#include "symtab.h" +#include "frame.h" +#include "source.h" +#include + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-windata.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-stack.h" +#include "tui/tui-regs.h" +#include "tui/tui-win.h" +#include "tui/tui-winsource.h" +#include "tui/tui-disasm.h" + +#include "gdb_string.h" +#include "gdb_curses.h" + +/******************************* +** Static Local Decls +********************************/ +static void show_layout (enum tui_layout_type); +static void init_gen_win_info (struct tui_gen_win_info *, enum tui_win_type, int, int, int, int); +static void init_and_make_win (void **, enum tui_win_type, int, int, int, int, int); +static void show_source_or_disasm_and_command (enum tui_layout_type); +static void make_source_or_disasm_window (struct tui_win_info * *, enum tui_win_type, int, int); +static void make_command_window (struct tui_win_info * *, int, int); +static void make_source_window (struct tui_win_info * *, int, int); +static void make_disasm_window (struct tui_win_info * *, int, int); +static void make_data_window (struct tui_win_info * *, int, int); +static void show_source_command (void); +static void show_disasm_command (void); +static void show_source_disasm_command (void); +static void show_data (enum tui_layout_type); +static enum tui_layout_type next_layout (void); +static enum tui_layout_type prev_layout (void); +static void tui_layout_command (char *, int); +static void tui_toggle_layout_command (char *, int); +static void tui_toggle_split_layout_command (char *, int); +static CORE_ADDR extract_display_start_addr (void); +static void tui_handle_xdb_layout (struct tui_layout_def *); + + +/*************************************** +** DEFINITIONS +***************************************/ + +#define LAYOUT_USAGE "Usage: layout prev | next | \n" + +/* Show the screen layout defined. */ +static void +show_layout (enum tui_layout_type layout) +{ + enum tui_layout_type cur_layout = tui_current_layout (); + + if (layout != cur_layout) + { + /* + ** Since the new layout may cause changes in window size, we + ** should free the content and reallocate on next display of + ** source/asm + */ + tui_free_all_source_wins_content (); + tui_clear_source_windows (); + if (layout == SRC_DATA_COMMAND || layout == DISASSEM_DATA_COMMAND) + { + show_data (layout); + tui_refresh_all (tui_win_list); + } + else + { + /* First make the current layout be invisible */ + tui_make_all_invisible (); + tui_make_invisible (tui_locator_win_info_ptr ()); + + switch (layout) + { + /* Now show the new layout */ + case SRC_COMMAND: + show_source_command (); + tui_add_to_source_windows (TUI_SRC_WIN); + break; + case DISASSEM_COMMAND: + show_disasm_command (); + tui_add_to_source_windows (TUI_DISASM_WIN); + break; + case SRC_DISASSEM_COMMAND: + show_source_disasm_command (); + tui_add_to_source_windows (TUI_SRC_WIN); + tui_add_to_source_windows (TUI_DISASM_WIN); + break; + default: + break; + } + } + } +} + + +/* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND, + SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND. + If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or + UNDEFINED_LAYOUT, then the data window is populated according to + regs_display_type. */ +enum tui_status +tui_set_layout (enum tui_layout_type layout_type, + enum tui_register_display_type regs_display_type) +{ + enum tui_status status = TUI_SUCCESS; + + if (layout_type != UNDEFINED_LAYOUT || regs_display_type != TUI_UNDEFINED_REGS) + { + enum tui_layout_type cur_layout = tui_current_layout (), new_layout = UNDEFINED_LAYOUT; + int regs_populate = FALSE; + CORE_ADDR addr = extract_display_start_addr (); + struct tui_win_info * new_win_with_focus = (struct tui_win_info *) NULL; + struct tui_win_info * win_with_focus = tui_win_with_focus (); + struct tui_layout_def * layout_def = tui_layout_def (); + + + if (layout_type == UNDEFINED_LAYOUT && + regs_display_type != TUI_UNDEFINED_REGS) + { + if (cur_layout == SRC_DISASSEM_COMMAND) + new_layout = DISASSEM_DATA_COMMAND; + else if (cur_layout == SRC_COMMAND || cur_layout == SRC_DATA_COMMAND) + new_layout = SRC_DATA_COMMAND; + else if (cur_layout == DISASSEM_COMMAND || + cur_layout == DISASSEM_DATA_COMMAND) + new_layout = DISASSEM_DATA_COMMAND; + } + else + new_layout = layout_type; + + regs_populate = (new_layout == SRC_DATA_COMMAND || + new_layout == DISASSEM_DATA_COMMAND || + regs_display_type != TUI_UNDEFINED_REGS); + if (new_layout != cur_layout || regs_display_type != TUI_UNDEFINED_REGS) + { + if (new_layout != cur_layout) + { + show_layout (new_layout); + /* + ** Now determine where focus should be + */ + if (win_with_focus != TUI_CMD_WIN) + { + switch (new_layout) + { + case SRC_COMMAND: + tui_set_win_focus_to (TUI_SRC_WIN); + layout_def->display_mode = SRC_WIN; + layout_def->split = FALSE; + break; + case DISASSEM_COMMAND: + /* the previous layout was not showing + ** code. this can happen if there is no + ** source available: + ** 1. if the source file is in another dir OR + ** 2. if target was compiled without -g + ** We still want to show the assembly though! + */ + addr = tui_get_begin_asm_address (); + tui_set_win_focus_to (TUI_DISASM_WIN); + layout_def->display_mode = DISASSEM_WIN; + layout_def->split = FALSE; + break; + case SRC_DISASSEM_COMMAND: + /* the previous layout was not showing + ** code. this can happen if there is no + ** source available: + ** 1. if the source file is in another dir OR + ** 2. if target was compiled without -g + ** We still want to show the assembly though! + */ + addr = tui_get_begin_asm_address (); + if (win_with_focus == TUI_SRC_WIN) + tui_set_win_focus_to (TUI_SRC_WIN); + else + tui_set_win_focus_to (TUI_DISASM_WIN); + layout_def->split = TRUE; + break; + case SRC_DATA_COMMAND: + if (win_with_focus != TUI_DATA_WIN) + tui_set_win_focus_to (TUI_SRC_WIN); + else + tui_set_win_focus_to (TUI_DATA_WIN); + layout_def->display_mode = SRC_WIN; + layout_def->split = FALSE; + break; + case DISASSEM_DATA_COMMAND: + /* the previous layout was not showing + ** code. this can happen if there is no + ** source available: + ** 1. if the source file is in another dir OR + ** 2. if target was compiled without -g + ** We still want to show the assembly though! + */ + addr = tui_get_begin_asm_address (); + if (win_with_focus != TUI_DATA_WIN) + tui_set_win_focus_to (TUI_DISASM_WIN); + else + tui_set_win_focus_to (TUI_DATA_WIN); + layout_def->display_mode = DISASSEM_WIN; + layout_def->split = FALSE; + break; + default: + break; + } + } + if (new_win_with_focus != (struct tui_win_info *) NULL) + tui_set_win_focus_to (new_win_with_focus); + /* + ** Now update the window content + */ + if (!regs_populate && + (new_layout == SRC_DATA_COMMAND || + new_layout == DISASSEM_DATA_COMMAND)) + tui_display_all_data (); + + tui_update_source_windows_with_addr (addr); + } + if (regs_populate) + { + tui_show_registers (TUI_DATA_WIN->detail.data_display_info.current_group); + } + } + } + else + status = TUI_FAILURE; + + return status; +} + +/* Add the specified window to the layout in a logical way. This + means setting up the most logical layout given the window to be + added. */ +void +tui_add_win_to_layout (enum tui_win_type type) +{ + enum tui_layout_type cur_layout = tui_current_layout (); + + switch (type) + { + case SRC_WIN: + if (cur_layout != SRC_COMMAND && + cur_layout != SRC_DISASSEM_COMMAND && + cur_layout != SRC_DATA_COMMAND) + { + tui_clear_source_windows_detail (); + if (cur_layout == DISASSEM_DATA_COMMAND) + show_layout (SRC_DATA_COMMAND); + else + show_layout (SRC_COMMAND); + } + break; + case DISASSEM_WIN: + if (cur_layout != DISASSEM_COMMAND && + cur_layout != SRC_DISASSEM_COMMAND && + cur_layout != DISASSEM_DATA_COMMAND) + { + tui_clear_source_windows_detail (); + if (cur_layout == SRC_DATA_COMMAND) + show_layout (DISASSEM_DATA_COMMAND); + else + show_layout (DISASSEM_COMMAND); + } + break; + case DATA_WIN: + if (cur_layout != SRC_DATA_COMMAND && + cur_layout != DISASSEM_DATA_COMMAND) + { + if (cur_layout == DISASSEM_COMMAND) + show_layout (DISASSEM_DATA_COMMAND); + else + show_layout (SRC_DATA_COMMAND); + } + break; + default: + break; + } +} + + +/* Answer the height of a window. If it hasn't been created yet, + answer what the height of a window would be based upon its type and + the layout. */ +int +tui_default_win_height (enum tui_win_type type, enum tui_layout_type layout) +{ + int h; + + if (tui_win_list[type] != (struct tui_win_info *) NULL) + h = tui_win_list[type]->generic.height; + else + { + switch (layout) + { + case SRC_COMMAND: + case DISASSEM_COMMAND: + if (TUI_CMD_WIN == NULL) + h = tui_term_height () / 2; + else + h = tui_term_height () - TUI_CMD_WIN->generic.height; + break; + case SRC_DISASSEM_COMMAND: + case SRC_DATA_COMMAND: + case DISASSEM_DATA_COMMAND: + if (TUI_CMD_WIN == NULL) + h = tui_term_height () / 3; + else + h = (tui_term_height () - TUI_CMD_WIN->generic.height) / 2; + break; + default: + h = 0; + break; + } + } + + return h; +} + + +/* Answer the height of a window. If it hasn't been created yet, + answer what the height of a window would be based upon its type and + the layout. */ +int +tui_default_win_viewport_height (enum tui_win_type type, + enum tui_layout_type layout) +{ + int h; + + h = tui_default_win_height (type, layout); + + if (tui_win_list[type] == TUI_CMD_WIN) + h -= 1; + else + h -= 2; + + return h; +} + + +/* Function to initialize gdb commands, for tui window layout + manipulation. */ +void +_initialize_tui_layout (void) +{ + add_com ("layout", class_tui, tui_layout_command, + "Change the layout of windows.\n\ +Usage: layout prev | next | \n\ +Layout names are:\n\ + src : Displays source and command windows.\n\ + asm : Displays disassembly and command windows.\n\ + split : Displays source, disassembly and command windows.\n\ + regs : Displays register window. If existing layout\n\ + is source/command or assembly/command, the \n\ + register window is displayed. If the\n\ + source/assembly/command (split) is displayed, \n\ + the register window is displayed with \n\ + the window that has current logical focus.\n"); + if (xdb_commands) + { + add_com ("td", class_tui, tui_toggle_layout_command, + "Toggle between Source/Command and Disassembly/Command layouts.\n"); + add_com ("ts", class_tui, tui_toggle_split_layout_command, + "Toggle between Source/Command or Disassembly/Command and \n\ +Source/Disassembly/Command layouts.\n"); + } +} + + +/************************* +** STATIC LOCAL FUNCTIONS +**************************/ + + +/* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, + REGS, $REGS, $GREGS, $FREGS, $SREGS. */ +enum tui_status +tui_set_layout_for_display_command (const char *layout_name) +{ + enum tui_status status = TUI_SUCCESS; + + if (layout_name != (char *) NULL) + { + int i; + char *buf_ptr; + enum tui_layout_type new_layout = UNDEFINED_LAYOUT; + enum tui_register_display_type dpy_type = TUI_UNDEFINED_REGS; + enum tui_layout_type cur_layout = tui_current_layout (); + + buf_ptr = (char *) xstrdup (layout_name); + for (i = 0; (i < strlen (layout_name)); i++) + buf_ptr[i] = toupper (buf_ptr[i]); + + /* First check for ambiguous input */ + if (strlen (buf_ptr) <= 1 && (*buf_ptr == 'S' || *buf_ptr == '$')) + { + warning ("Ambiguous command input.\n"); + status = TUI_FAILURE; + } + else + { + if (subset_compare (buf_ptr, "SRC")) + new_layout = SRC_COMMAND; + else if (subset_compare (buf_ptr, "ASM")) + new_layout = DISASSEM_COMMAND; + else if (subset_compare (buf_ptr, "SPLIT")) + new_layout = SRC_DISASSEM_COMMAND; + else if (subset_compare (buf_ptr, "REGS") || + subset_compare (buf_ptr, TUI_GENERAL_SPECIAL_REGS_NAME) || + subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME) || + subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME) || + subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME)) + { + if (cur_layout == SRC_COMMAND || cur_layout == SRC_DATA_COMMAND) + new_layout = SRC_DATA_COMMAND; + else + new_layout = DISASSEM_DATA_COMMAND; + +/* could ifdef out the following code. when compile with -z, there are null + pointer references that cause a core dump if 'layout regs' is the first + layout command issued by the user. HP has asked us to hook up this code + - edie epstein + */ + if (subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME)) + { + if (TUI_DATA_WIN->detail.data_display_info.regs_display_type != + TUI_SFLOAT_REGS && + TUI_DATA_WIN->detail.data_display_info.regs_display_type != + TUI_DFLOAT_REGS) + dpy_type = TUI_SFLOAT_REGS; + else + dpy_type = + TUI_DATA_WIN->detail.data_display_info.regs_display_type; + } + else if (subset_compare (buf_ptr, + TUI_GENERAL_SPECIAL_REGS_NAME)) + dpy_type = TUI_GENERAL_AND_SPECIAL_REGS; + else if (subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME)) + dpy_type = TUI_GENERAL_REGS; + else if (subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME)) + dpy_type = TUI_SPECIAL_REGS; + else if (TUI_DATA_WIN) + { + if (TUI_DATA_WIN->detail.data_display_info.regs_display_type != + TUI_UNDEFINED_REGS) + dpy_type = + TUI_DATA_WIN->detail.data_display_info.regs_display_type; + else + dpy_type = TUI_GENERAL_REGS; + } + +/* end of potential ifdef + */ + +/* if ifdefed out code above, then assume that the user wishes to display the + general purpose registers + */ + +/* dpy_type = TUI_GENERAL_REGS; + */ + } + else if (subset_compare (buf_ptr, "NEXT")) + new_layout = next_layout (); + else if (subset_compare (buf_ptr, "PREV")) + new_layout = prev_layout (); + else + status = TUI_FAILURE; + xfree (buf_ptr); + + tui_set_layout (new_layout, dpy_type); + } + } + else + status = TUI_FAILURE; + + return status; +} + + +static CORE_ADDR +extract_display_start_addr (void) +{ + enum tui_layout_type cur_layout = tui_current_layout (); + CORE_ADDR addr; + CORE_ADDR pc; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + switch (cur_layout) + { + case SRC_COMMAND: + case SRC_DATA_COMMAND: + find_line_pc (cursal.symtab, + TUI_SRC_WIN->detail.source_info.start_line_or_addr.line_no, + &pc); + addr = pc; + break; + case DISASSEM_COMMAND: + case SRC_DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.addr; + break; + default: + addr = 0; + break; + } + + return addr; +} + + +static void +tui_handle_xdb_layout (struct tui_layout_def * layout_def) +{ + if (layout_def->split) + { + tui_set_layout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS); + tui_set_win_focus_to (tui_win_list[layout_def->display_mode]); + } + else + { + if (layout_def->display_mode == SRC_WIN) + tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS); + else + tui_set_layout (DISASSEM_DATA_COMMAND, layout_def->regs_display_type); + } +} + + +static void +tui_toggle_layout_command (char *arg, int from_tty) +{ + struct tui_layout_def * layout_def = tui_layout_def (); + + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (layout_def->display_mode == SRC_WIN) + layout_def->display_mode = DISASSEM_WIN; + else + layout_def->display_mode = SRC_WIN; + + if (!layout_def->split) + tui_handle_xdb_layout (layout_def); +} + + +static void +tui_toggle_split_layout_command (char *arg, int from_tty) +{ + struct tui_layout_def * layout_def = tui_layout_def (); + + /* Make sure the curses mode is enabled. */ + tui_enable (); + layout_def->split = (!layout_def->split); + tui_handle_xdb_layout (layout_def); +} + + +static void +tui_layout_command (char *arg, int from_tty) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + + /* Switch to the selected layout. */ + if (tui_set_layout_for_display_command (arg) != TUI_SUCCESS) + warning ("Invalid layout specified.\n%s", LAYOUT_USAGE); + +} + +/* Answer the previous layout to cycle to. */ +static enum tui_layout_type +next_layout (void) +{ + enum tui_layout_type new_layout; + + new_layout = tui_current_layout (); + if (new_layout == UNDEFINED_LAYOUT) + new_layout = SRC_COMMAND; + else + { + new_layout++; + if (new_layout == UNDEFINED_LAYOUT) + new_layout = SRC_COMMAND; + } + + return new_layout; +} + + +/* Answer the next layout to cycle to. */ +static enum tui_layout_type +prev_layout (void) +{ + enum tui_layout_type new_layout; + + new_layout = tui_current_layout (); + if (new_layout == SRC_COMMAND) + new_layout = DISASSEM_DATA_COMMAND; + else + { + new_layout--; + if (new_layout == UNDEFINED_LAYOUT) + new_layout = DISASSEM_DATA_COMMAND; + } + + return new_layout; +} + + + +static void +make_command_window (struct tui_win_info * * win_info_ptr, int height, int origin_y) +{ + init_and_make_win ((void **) win_info_ptr, + CMD_WIN, + height, + tui_term_width (), + 0, + origin_y, + DONT_BOX_WINDOW); + + (*win_info_ptr)->can_highlight = FALSE; +} + + +/* + ** make_source_window(). + */ +static void +make_source_window (struct tui_win_info * * win_info_ptr, int height, int origin_y) +{ + make_source_or_disasm_window (win_info_ptr, SRC_WIN, height, origin_y); + + return; +} /* make_source_window */ + + +/* + ** make_disasm_window(). + */ +static void +make_disasm_window (struct tui_win_info * * win_info_ptr, int height, int origin_y) +{ + make_source_or_disasm_window (win_info_ptr, DISASSEM_WIN, height, origin_y); + + return; +} /* make_disasm_window */ + + +static void +make_data_window (struct tui_win_info * * win_info_ptr, int height, int origin_y) +{ + init_and_make_win ((void **) win_info_ptr, + DATA_WIN, + height, + tui_term_width (), + 0, + origin_y, + BOX_WINDOW); +} + + + +/* Show the Source/Command layout. */ +static void +show_source_command (void) +{ + show_source_or_disasm_and_command (SRC_COMMAND); +} + + +/* Show the Dissassem/Command layout. */ +static void +show_disasm_command (void) +{ + show_source_or_disasm_and_command (DISASSEM_COMMAND); +} + + +/* Show the Source/Disassem/Command layout. */ +static void +show_source_disasm_command (void) +{ + if (tui_current_layout () != SRC_DISASSEM_COMMAND) + { + int cmd_height, src_height, asm_height; + + if (TUI_CMD_WIN != NULL) + cmd_height = TUI_CMD_WIN->generic.height; + else + cmd_height = tui_term_height () / 3; + + src_height = (tui_term_height () - cmd_height) / 2; + asm_height = tui_term_height () - (src_height + cmd_height); + + if (TUI_SRC_WIN == NULL) + make_source_window (&TUI_SRC_WIN, src_height, 0); + else + { + init_gen_win_info (&TUI_SRC_WIN->generic, + TUI_SRC_WIN->generic.type, + src_height, + TUI_SRC_WIN->generic.width, + TUI_SRC_WIN->detail.source_info.execution_info->width, + 0); + TUI_SRC_WIN->can_highlight = TRUE; + init_gen_win_info (TUI_SRC_WIN->detail.source_info.execution_info, + EXEC_INFO_WIN, + src_height, + 3, + 0, + 0); + tui_make_visible (&TUI_SRC_WIN->generic); + tui_make_visible (TUI_SRC_WIN->detail.source_info.execution_info); + TUI_SRC_WIN->detail.source_info.has_locator = FALSE;; + } + if (TUI_SRC_WIN != NULL) + { + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + + tui_show_source_content (TUI_SRC_WIN); + if (TUI_DISASM_WIN == NULL) + { + make_disasm_window (&TUI_DISASM_WIN, asm_height, src_height - 1); + init_and_make_win ((void **) & locator, + LOCATOR_WIN, + 2 /* 1 */ , + tui_term_width (), + 0, + (src_height + asm_height) - 1, + DONT_BOX_WINDOW); + } + else + { + init_gen_win_info (locator, + LOCATOR_WIN, + 2 /* 1 */ , + tui_term_width (), + 0, + (src_height + asm_height) - 1); + TUI_DISASM_WIN->detail.source_info.has_locator = TRUE; + init_gen_win_info ( + &TUI_DISASM_WIN->generic, + TUI_DISASM_WIN->generic.type, + asm_height, + TUI_DISASM_WIN->generic.width, + TUI_DISASM_WIN->detail.source_info.execution_info->width, + src_height - 1); + init_gen_win_info (TUI_DISASM_WIN->detail.source_info.execution_info, + EXEC_INFO_WIN, + asm_height, + 3, + 0, + src_height - 1); + TUI_DISASM_WIN->can_highlight = TRUE; + tui_make_visible (&TUI_DISASM_WIN->generic); + tui_make_visible (TUI_DISASM_WIN->detail.source_info.execution_info); + } + if (TUI_DISASM_WIN != NULL) + { + TUI_SRC_WIN->detail.source_info.has_locator = FALSE; + TUI_DISASM_WIN->detail.source_info.has_locator = TRUE; + tui_make_visible (locator); + tui_show_locator_content (); + tui_show_source_content (TUI_DISASM_WIN); + + if (TUI_CMD_WIN == NULL) + make_command_window (&TUI_CMD_WIN, + cmd_height, + tui_term_height () - cmd_height); + else + { + init_gen_win_info (&TUI_CMD_WIN->generic, + TUI_CMD_WIN->generic.type, + TUI_CMD_WIN->generic.height, + TUI_CMD_WIN->generic.width, + 0, + TUI_CMD_WIN->generic.origin.y); + TUI_CMD_WIN->can_highlight = FALSE; + tui_make_visible (&TUI_CMD_WIN->generic); + } + if (TUI_CMD_WIN != NULL) + tui_refresh_win (&TUI_CMD_WIN->generic); + } + } + tui_set_current_layout_to (SRC_DISASSEM_COMMAND); + } +} + + +/* Show the Source/Data/Command or the Dissassembly/Data/Command + layout. */ +static void +show_data (enum tui_layout_type new_layout) +{ + int total_height = (tui_term_height () - TUI_CMD_WIN->generic.height); + int src_height, data_height; + enum tui_win_type win_type; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + + + data_height = total_height / 2; + src_height = total_height - data_height; + tui_make_all_invisible (); + tui_make_invisible (locator); + make_data_window (&TUI_DATA_WIN, data_height, 0); + TUI_DATA_WIN->can_highlight = TRUE; + if (new_layout == SRC_DATA_COMMAND) + win_type = SRC_WIN; + else + win_type = DISASSEM_WIN; + if (tui_win_list[win_type] == NULL) + { + if (win_type == SRC_WIN) + make_source_window (&tui_win_list[win_type], src_height, data_height - 1); + else + make_disasm_window (&tui_win_list[win_type], src_height, data_height - 1); + init_and_make_win ((void **) & locator, + LOCATOR_WIN, + 2 /* 1 */ , + tui_term_width (), + 0, + total_height - 1, + DONT_BOX_WINDOW); + } + else + { + init_gen_win_info (&tui_win_list[win_type]->generic, + tui_win_list[win_type]->generic.type, + src_height, + tui_win_list[win_type]->generic.width, + tui_win_list[win_type]->detail.source_info.execution_info->width, + data_height - 1); + init_gen_win_info (tui_win_list[win_type]->detail.source_info.execution_info, + EXEC_INFO_WIN, + src_height, + 3, + 0, + data_height - 1); + tui_make_visible (&tui_win_list[win_type]->generic); + tui_make_visible (tui_win_list[win_type]->detail.source_info.execution_info); + init_gen_win_info (locator, + LOCATOR_WIN, + 2 /* 1 */ , + tui_term_width (), + 0, + total_height - 1); + } + tui_win_list[win_type]->detail.source_info.has_locator = TRUE; + tui_make_visible (locator); + tui_show_locator_content (); + tui_add_to_source_windows (tui_win_list[win_type]); + tui_set_current_layout_to (new_layout); +} + +/* + ** init_gen_win_info(). + */ +static void +init_gen_win_info (struct tui_gen_win_info * win_info, enum tui_win_type type, + int height, int width, int origin_x, int origin_y) +{ + int h = height; + + win_info->type = type; + win_info->width = width; + win_info->height = h; + if (h > 1) + { + win_info->viewport_height = h - 1; + if (win_info->type != CMD_WIN) + win_info->viewport_height--; + } + else + win_info->viewport_height = 1; + win_info->origin.x = origin_x; + win_info->origin.y = origin_y; + + return; +} /* init_gen_win_info */ + +/* + ** init_and_make_win(). + */ +static void +init_and_make_win (void ** win_info_ptr, enum tui_win_type win_type, + int height, int width, int origin_x, int origin_y, int box_it) +{ + void *opaque_win_info = *win_info_ptr; + struct tui_gen_win_info * generic; + + if (opaque_win_info == NULL) + { + if (tui_win_is_auxillary (win_type)) + opaque_win_info = (void *) tui_alloc_generic_win_info (); + else + opaque_win_info = (void *) tui_alloc_win_info (win_type); + } + if (tui_win_is_auxillary (win_type)) + generic = (struct tui_gen_win_info *) opaque_win_info; + else + generic = &((struct tui_win_info *) opaque_win_info)->generic; + + if (opaque_win_info != NULL) + { + init_gen_win_info (generic, win_type, height, width, origin_x, origin_y); + if (!tui_win_is_auxillary (win_type)) + { + if (generic->type == CMD_WIN) + ((struct tui_win_info *) opaque_win_info)->can_highlight = FALSE; + else + ((struct tui_win_info *) opaque_win_info)->can_highlight = TRUE; + } + tui_make_window (generic, box_it); + } + *win_info_ptr = opaque_win_info; +} + + +static void +make_source_or_disasm_window (struct tui_win_info * * win_info_ptr, enum tui_win_type type, + int height, int origin_y) +{ + struct tui_gen_win_info * execution_info = (struct tui_gen_win_info *) NULL; + + /* + ** Create the exeuction info window. + */ + if (type == SRC_WIN) + execution_info = tui_source_exec_info_win_ptr (); + else + execution_info = tui_disassem_exec_info_win_ptr (); + init_and_make_win ((void **) & execution_info, + EXEC_INFO_WIN, + height, + 3, + 0, + origin_y, + DONT_BOX_WINDOW); + /* + ** Now create the source window. + */ + init_and_make_win ((void **) win_info_ptr, + type, + height, + tui_term_width () - execution_info->width, + execution_info->width, + origin_y, + BOX_WINDOW); + + (*win_info_ptr)->detail.source_info.execution_info = execution_info; +} + + +/* Show the Source/Command or the Disassem layout. */ +static void +show_source_or_disasm_and_command (enum tui_layout_type layout_type) +{ + if (tui_current_layout () != layout_type) + { + struct tui_win_info * *win_info_ptr; + int src_height, cmd_height; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + + if (TUI_CMD_WIN != NULL) + cmd_height = TUI_CMD_WIN->generic.height; + else + cmd_height = tui_term_height () / 3; + src_height = tui_term_height () - cmd_height; + + + if (layout_type == SRC_COMMAND) + win_info_ptr = &TUI_SRC_WIN; + else + win_info_ptr = &TUI_DISASM_WIN; + + if ((*win_info_ptr) == NULL) + { + if (layout_type == SRC_COMMAND) + make_source_window (win_info_ptr, src_height - 1, 0); + else + make_disasm_window (win_info_ptr, src_height - 1, 0); + init_and_make_win ((void **) & locator, + LOCATOR_WIN, + 2 /* 1 */ , + tui_term_width (), + 0, + src_height - 1, + DONT_BOX_WINDOW); + } + else + { + init_gen_win_info (locator, + LOCATOR_WIN, + 2 /* 1 */ , + tui_term_width (), + 0, + src_height - 1); + (*win_info_ptr)->detail.source_info.has_locator = TRUE; + init_gen_win_info ( + &(*win_info_ptr)->generic, + (*win_info_ptr)->generic.type, + src_height - 1, + (*win_info_ptr)->generic.width, + (*win_info_ptr)->detail.source_info.execution_info->width, + 0); + init_gen_win_info ((*win_info_ptr)->detail.source_info.execution_info, + EXEC_INFO_WIN, + src_height - 1, + 3, + 0, + 0); + (*win_info_ptr)->can_highlight = TRUE; + tui_make_visible (&(*win_info_ptr)->generic); + tui_make_visible ((*win_info_ptr)->detail.source_info.execution_info); + } + if ((*win_info_ptr) != NULL) + { + (*win_info_ptr)->detail.source_info.has_locator = TRUE; + tui_make_visible (locator); + tui_show_locator_content (); + tui_show_source_content (*win_info_ptr); + + if (TUI_CMD_WIN == NULL) + { + make_command_window (&TUI_CMD_WIN, cmd_height, src_height); + tui_refresh_win (&TUI_CMD_WIN->generic); + } + else + { + init_gen_win_info (&TUI_CMD_WIN->generic, + TUI_CMD_WIN->generic.type, + TUI_CMD_WIN->generic.height, + TUI_CMD_WIN->generic.width, + TUI_CMD_WIN->generic.origin.x, + TUI_CMD_WIN->generic.origin.y); + TUI_CMD_WIN->can_highlight = FALSE; + tui_make_visible (&TUI_CMD_WIN->generic); + } + } + tui_set_current_layout_to (layout_type); + } +} diff --git a/contrib/gdb/gdb/tui/tui-layout.h b/contrib/gdb/gdb/tui/tui-layout.h new file mode 100644 index 00000000000..5df1f0be9f1 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-layout.h @@ -0,0 +1,38 @@ +/* TUI layout window management. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_LAYOUT_H +#define TUI_LAYOUT_H + +#include "tui/tui.h" +#include "tui/tui-data.h" + +extern void tui_add_win_to_layout (enum tui_win_type); +extern int tui_default_win_height (enum tui_win_type, enum tui_layout_type); +extern int tui_default_win_viewport_height (enum tui_win_type, + enum tui_layout_type); +extern enum tui_status tui_set_layout (enum tui_layout_type, + enum tui_register_display_type); + +#endif /*TUI_LAYOUT_H */ diff --git a/contrib/gdb/gdb/tui/tui-main.c b/contrib/gdb/gdb/tui/tui-main.c new file mode 100644 index 00000000000..920d83884f0 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-main.c @@ -0,0 +1,37 @@ +/* Main function for TUI gdb. + + Copyright 2002, 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "main.h" +#include "gdb_string.h" +#include "interps.h" + +int +main (int argc, char **argv) +{ + struct captured_main_args args; + memset (&args, 0, sizeof args); + args.argc = argc; + args.argv = argv; + args.use_windows = 0; + args.interpreter_p = INTERP_TUI; + return gdb_main (&args); +} diff --git a/contrib/gdb/gdb/tui/tui-out.c b/contrib/gdb/gdb/tui/tui-out.c new file mode 100644 index 00000000000..1c2af689044 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-out.c @@ -0,0 +1,413 @@ +/* Output generating routines for GDB CLI. + + Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + Contributed by Cygnus Solutions. + Written by Fernando Nasser for Cygnus. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "ui-out.h" +#include "tui.h" +#include "gdb_string.h" +#include "gdb_assert.h" + +struct ui_out_data + { + struct ui_file *stream; + int suppress_output; + int line; + int start_of_line; + }; +typedef struct ui_out_data tui_out_data; + +/* These are the CLI output functions */ + +static void tui_table_begin (struct ui_out *uiout, int nbrofcols, + int nr_rows, const char *tblid); +static void tui_table_body (struct ui_out *uiout); +static void tui_table_end (struct ui_out *uiout); +static void tui_table_header (struct ui_out *uiout, int width, + enum ui_align alig, const char *col_name, + const char *colhdr); +static void tui_begin (struct ui_out *uiout, enum ui_out_type type, + int level, const char *lstid); +static void tui_end (struct ui_out *uiout, enum ui_out_type type, int level); +static void tui_field_int (struct ui_out *uiout, int fldno, int width, + enum ui_align alig, const char *fldname, int value); +static void tui_field_skip (struct ui_out *uiout, int fldno, int width, + enum ui_align alig, const char *fldname); +static void tui_field_string (struct ui_out *uiout, int fldno, int width, + enum ui_align alig, const char *fldname, + const char *string); +static void tui_field_fmt (struct ui_out *uiout, int fldno, + int width, enum ui_align align, + const char *fldname, const char *format, + va_list args); +static void tui_spaces (struct ui_out *uiout, int numspaces); +static void tui_text (struct ui_out *uiout, const char *string); +static void tui_message (struct ui_out *uiout, int verbosity, + const char *format, va_list args); +static void tui_wrap_hint (struct ui_out *uiout, char *identstring); +static void tui_flush (struct ui_out *uiout); + +/* This is the CLI ui-out implementation functions vector */ + +/* FIXME: This can be initialized dynamically after default is set to + handle initial output in main.c */ + +static struct ui_out_impl tui_ui_out_impl = +{ + tui_table_begin, + tui_table_body, + tui_table_end, + tui_table_header, + tui_begin, + tui_end, + tui_field_int, + tui_field_skip, + tui_field_string, + tui_field_fmt, + tui_spaces, + tui_text, + tui_message, + tui_wrap_hint, + tui_flush, + NULL, + 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ +}; + +/* Prototypes for local functions */ + +extern void _initialize_tui_out (void); + +static void field_separator (void); + +static void out_field_fmt (struct ui_out *uiout, int fldno, + const char *fldname, + const char *format,...); + +/* local variables */ + +/* (none yet) */ + +/* Mark beginning of a table */ + +void +tui_table_begin (struct ui_out *uiout, int nbrofcols, + int nr_rows, + const char *tblid) +{ + tui_out_data *data = ui_out_data (uiout); + if (nr_rows == 0) + data->suppress_output = 1; + else + /* Only the table suppresses the output and, fortunately, a table + is not a recursive data structure. */ + gdb_assert (data->suppress_output == 0); +} + +/* Mark beginning of a table body */ + +void +tui_table_body (struct ui_out *uiout) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + /* first, close the table header line */ + tui_text (uiout, "\n"); +} + +/* Mark end of a table */ + +void +tui_table_end (struct ui_out *uiout) +{ + tui_out_data *data = ui_out_data (uiout); + data->suppress_output = 0; +} + +/* Specify table header */ + +void +tui_table_header (struct ui_out *uiout, int width, enum ui_align alignment, + const char *col_name, + const char *colhdr) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + tui_field_string (uiout, 0, width, alignment, 0, colhdr); +} + +/* Mark beginning of a list */ + +void +tui_begin (struct ui_out *uiout, + enum ui_out_type type, + int level, + const char *id) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; +} + +/* Mark end of a list */ + +void +tui_end (struct ui_out *uiout, + enum ui_out_type type, + int level) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; +} + +/* output an int field */ + +void +tui_field_int (struct ui_out *uiout, int fldno, int width, + enum ui_align alignment, + const char *fldname, int value) +{ + char buffer[20]; /* FIXME: how many chars long a %d can become? */ + + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + + /* Don't print line number, keep it for later. */ + if (data->start_of_line == 0 && strcmp (fldname, "line") == 0) + { + data->start_of_line ++; + data->line = value; + return; + } + data->start_of_line ++; + sprintf (buffer, "%d", value); + tui_field_string (uiout, fldno, width, alignment, fldname, buffer); +} + +/* used to ommit a field */ + +void +tui_field_skip (struct ui_out *uiout, int fldno, int width, + enum ui_align alignment, + const char *fldname) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + tui_field_string (uiout, fldno, width, alignment, fldname, ""); +} + +/* other specific tui_field_* end up here so alignment and field + separators are both handled by tui_field_string */ + +void +tui_field_string (struct ui_out *uiout, + int fldno, + int width, + enum ui_align align, + const char *fldname, + const char *string) +{ + int before = 0; + int after = 0; + + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + + if (fldname && data->line > 0 && strcmp (fldname, "file") == 0) + { + data->start_of_line ++; + if (data->line > 0) + { + tui_show_source (string, data->line); + } + return; + } + + data->start_of_line ++; + if ((align != ui_noalign) && string) + { + before = width - strlen (string); + if (before <= 0) + before = 0; + else + { + if (align == ui_right) + after = 0; + else if (align == ui_left) + { + after = before; + before = 0; + } + else + /* ui_center */ + { + after = before / 2; + before -= after; + } + } + } + + if (before) + ui_out_spaces (uiout, before); + if (string) + out_field_fmt (uiout, fldno, fldname, "%s", string); + if (after) + ui_out_spaces (uiout, after); + + if (align != ui_noalign) + field_separator (); +} + +/* This is the only field function that does not align */ + +void +tui_field_fmt (struct ui_out *uiout, int fldno, + int width, enum ui_align align, + const char *fldname, + const char *format, + va_list args) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + + data->start_of_line ++; + vfprintf_filtered (data->stream, format, args); + + if (align != ui_noalign) + field_separator (); +} + +void +tui_spaces (struct ui_out *uiout, int numspaces) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + print_spaces_filtered (numspaces, data->stream); +} + +void +tui_text (struct ui_out *uiout, const char *string) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + data->start_of_line ++; + if (data->line > 0) + { + if (strchr (string, '\n') != 0) + { + data->line = -1; + data->start_of_line = 0; + } + return; + } + if (strchr (string, '\n')) + data->start_of_line = 0; + fputs_filtered (string, data->stream); +} + +void +tui_message (struct ui_out *uiout, int verbosity, + const char *format, va_list args) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + if (ui_out_get_verblvl (uiout) >= verbosity) + vfprintf_unfiltered (data->stream, format, args); +} + +void +tui_wrap_hint (struct ui_out *uiout, char *identstring) +{ + tui_out_data *data = ui_out_data (uiout); + if (data->suppress_output) + return; + wrap_here (identstring); +} + +void +tui_flush (struct ui_out *uiout) +{ + tui_out_data *data = ui_out_data (uiout); + gdb_flush (data->stream); +} + +/* local functions */ + +/* Like tui_field_fmt, but takes a variable number of args + and makes a va_list and does not insert a separator */ + +/* VARARGS */ +static void +out_field_fmt (struct ui_out *uiout, int fldno, + const char *fldname, + const char *format,...) +{ + tui_out_data *data = ui_out_data (uiout); + va_list args; + + va_start (args, format); + vfprintf_filtered (data->stream, format, args); + + va_end (args); +} + +/* access to ui_out format private members */ + +static void +field_separator (void) +{ + tui_out_data *data = ui_out_data (uiout); + fputc_filtered (' ', data->stream); +} + +/* initalize private members at startup */ + +struct ui_out * +tui_out_new (struct ui_file *stream) +{ + int flags = 0; + + tui_out_data *data = XMALLOC (tui_out_data); + data->stream = stream; + data->suppress_output = 0; + data->line = -1; + data->start_of_line = 0; + return ui_out_new (&tui_ui_out_impl, data, flags); +} + +/* standard gdb initialization hook */ +void +_initialize_tui_out (void) +{ + /* nothing needs to be done */ +} diff --git a/contrib/gdb/gdb/tui/tui-regs.c b/contrib/gdb/gdb/tui/tui-regs.c new file mode 100644 index 00000000000..abb92a43336 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-regs.c @@ -0,0 +1,754 @@ +/* TUI display registers in window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "gdbcmd.h" +#include "frame.h" +#include "regcache.h" +#include "inferior.h" +#include "target.h" +#include "gdb_string.h" +#include "tui/tui-layout.h" +#include "tui/tui-win.h" +#include "tui/tui-windata.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-file.h" +#include "reggroups.h" + +#include "gdb_curses.h" + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ +static void +tui_display_register (struct tui_data_element *data, + struct tui_gen_win_info *win_info); + +static enum tui_status +tui_show_register_group (struct gdbarch *gdbarch, struct reggroup *group, + struct frame_info *frame, int refresh_values_only); + +static enum tui_status +tui_get_register (struct gdbarch *gdbarch, struct frame_info *frame, + struct tui_data_element *data, int regnum, int *changedp); +static void tui_register_format + (struct gdbarch *, struct frame_info *, struct tui_data_element*, int); +static void tui_scroll_regs_forward_command (char *, int); +static void tui_scroll_regs_backward_command (char *, int); + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + +/* Answer the number of the last line in the regs display. If there + are no registers (-1) is returned. */ +int +tui_last_regs_line_no (void) +{ + int num_lines = (-1); + + if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) + { + num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count / + TUI_DATA_WIN->detail.data_display_info.regs_column_count); + if (TUI_DATA_WIN->detail.data_display_info.regs_content_count % + TUI_DATA_WIN->detail.data_display_info.regs_column_count) + num_lines++; + } + return num_lines; +} + + +/* Answer the line number that the register element at element_no is + on. If element_no is greater than the number of register elements + there are, -1 is returned. */ +int +tui_line_from_reg_element_no (int element_no) +{ + if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) + { + int i, line = (-1); + + i = 1; + while (line == (-1)) + { + if (element_no < + (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i)) + line = i - 1; + else + i++; + } + + return line; + } + else + return (-1); +} + + +/* Answer the index of the first element in line_no. If line_no is past + the register area (-1) is returned. */ +int +tui_first_reg_element_no_inline (int line_no) +{ + if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) + <= TUI_DATA_WIN->detail.data_display_info.regs_content_count) + return ((line_no + 1) * + TUI_DATA_WIN->detail.data_display_info.regs_column_count) - + TUI_DATA_WIN->detail.data_display_info.regs_column_count; + else + return (-1); +} + + +/* Answer the index of the last element in line_no. If line_no is + past the register area (-1) is returned. */ +int +tui_last_reg_element_no_in_line (int line_no) +{ + if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <= + TUI_DATA_WIN->detail.data_display_info.regs_content_count) + return ((line_no + 1) * + TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1; + else + return (-1); +} + +/* Show the registers of the given group in the data window + and refresh the window. */ +void +tui_show_registers (struct reggroup *group) +{ + enum tui_status ret = TUI_FAILURE; + struct tui_data_info *display_info; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + + /* Make sure the register window is visible. If not, select an + appropriate layout. */ + if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible) + tui_set_layout_for_display_command (DATA_NAME); + + display_info = &TUI_DATA_WIN->detail.data_display_info; + if (group == 0) + group = general_reggroup; + + /* Say that registers should be displayed, even if there is a problem. */ + display_info->display_regs = TRUE; + + if (target_has_registers && target_has_stack && target_has_memory) + { + ret = tui_show_register_group (current_gdbarch, group, + get_current_frame (), + group == display_info->current_group); + } + if (ret == TUI_FAILURE) + { + display_info->current_group = 0; + tui_erase_data_content (NO_REGS_STRING); + } + else + { + int i; + + /* Clear all notation of changed values */ + for (i = 0; i < display_info->regs_content_count; i++) + { + struct tui_gen_win_info *data_item_win; + struct tui_win_element *win; + + data_item_win = &display_info->regs_content[i] + ->which_element.data_window; + win = (struct tui_win_element *) data_item_win->content[0]; + win->which_element.data.highlight = FALSE; + } + display_info->current_group = group; + tui_display_all_data (); + } +} + + +/* Set the data window to display the registers of the register group + using the given frame. Values are refreshed only when refresh_values_only + is TRUE. */ + +static enum tui_status +tui_show_register_group (struct gdbarch *gdbarch, struct reggroup *group, + struct frame_info *frame, int refresh_values_only) +{ + enum tui_status ret = TUI_FAILURE; + int nr_regs; + int allocated_here = FALSE; + int regnum, pos; + char title[80]; + struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; + + /* Make a new title showing which group we display. */ + snprintf (title, sizeof (title) - 1, "Register group: %s", + reggroup_name (group)); + xfree (TUI_DATA_WIN->generic.title); + TUI_DATA_WIN->generic.title = xstrdup (title); + + /* See how many registers must be displayed. */ + nr_regs = 0; + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + /* Must be in the group and have a name. */ + if (gdbarch_register_reggroup_p (gdbarch, regnum, group) + && gdbarch_register_name (gdbarch, regnum) != 0) + nr_regs++; + } + + if (display_info->regs_content_count > 0 && !refresh_values_only) + { + tui_free_data_content (display_info->regs_content, + display_info->regs_content_count); + display_info->regs_content_count = 0; + } + + if (display_info->regs_content_count <= 0) + { + display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN); + allocated_here = TRUE; + refresh_values_only = FALSE; + } + + if (display_info->regs_content != (tui_win_content) NULL) + { + if (!refresh_values_only || allocated_here) + { + TUI_DATA_WIN->generic.content = (void*) NULL; + TUI_DATA_WIN->generic.content_size = 0; + tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs); + display_info->regs_content + = (tui_win_content) TUI_DATA_WIN->generic.content; + display_info->regs_content_count = nr_regs; + } + + /* Now set the register names and values */ + pos = 0; + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + struct tui_gen_win_info *data_item_win; + struct tui_data_element *data; + const char *name; + + if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) + continue; + + name = gdbarch_register_name (gdbarch, regnum); + if (name == 0) + continue; + + data_item_win = + &display_info->regs_content[pos]->which_element.data_window; + data = + &((struct tui_win_element *) data_item_win->content[0])->which_element.data; + if (data) + { + if (!refresh_values_only) + { + data->item_no = regnum; + data->name = name; + data->highlight = FALSE; + } + if (data->value == (void*) NULL) + data->value = (void*) xmalloc (MAX_REGISTER_SIZE); + + tui_get_register (gdbarch, frame, data, regnum, 0); + } + pos++; + } + + TUI_DATA_WIN->generic.content_size = + display_info->regs_content_count + display_info->data_content_count; + ret = TUI_SUCCESS; + } + + return ret; +} + +/* Function to display the registers in the content from + 'start_element_no' until the end of the register content or the end + of the display height. No checking for displaying past the end of + the registers is done here. */ +void +tui_display_registers_from (int start_element_no) +{ + struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; + + if (display_info->regs_content != (tui_win_content) NULL && + display_info->regs_content_count > 0) + { + int i = start_element_no; + int j, value_chars_wide, item_win_width, cur_y; + + int max_len = 0; + for (i = 0; i < display_info->regs_content_count; i++) + { + struct tui_data_element *data; + struct tui_gen_win_info *data_item_win; + char *p; + int len; + + data_item_win = &display_info->regs_content[i]->which_element.data_window; + data = &((struct tui_win_element *) + data_item_win->content[0])->which_element.data; + len = 0; + p = data->content; + if (p != 0) + while (*p) + { + if (*p++ == '\t') + len = 8 * ((len / 8) + 1); + else + len++; + } + + if (len > max_len) + max_len = len; + } + item_win_width = max_len + 1; + i = start_element_no; + + display_info->regs_column_count = + (TUI_DATA_WIN->generic.width - 2) / item_win_width; + if (display_info->regs_column_count == 0) + display_info->regs_column_count = 1; + item_win_width = + (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count; + + /* + ** Now create each data "sub" window, and write the display into it. + */ + cur_y = 1; + while (i < display_info->regs_content_count && + cur_y <= TUI_DATA_WIN->generic.viewport_height) + { + for (j = 0; + (j < display_info->regs_column_count && + i < display_info->regs_content_count); j++) + { + struct tui_gen_win_info * data_item_win; + struct tui_data_element * data_element_ptr; + + /* create the window if necessary */ + data_item_win = &display_info->regs_content[i] + ->which_element.data_window; + data_element_ptr = &((struct tui_win_element *) + data_item_win->content[0])->which_element.data; + if (data_item_win->handle != (WINDOW*) NULL + && (data_item_win->height != 1 + || data_item_win->width != item_win_width + || data_item_win->origin.x != (item_win_width * j) + 1 + || data_item_win->origin.y != cur_y)) + { + tui_delete_win (data_item_win->handle); + data_item_win->handle = 0; + } + + if (data_item_win->handle == (WINDOW *) NULL) + { + data_item_win->height = 1; + data_item_win->width = item_win_width; + data_item_win->origin.x = (item_win_width * j) + 1; + data_item_win->origin.y = cur_y; + tui_make_window (data_item_win, DONT_BOX_WINDOW); + scrollok (data_item_win->handle, FALSE); + } + touchwin (data_item_win->handle); + + /* Get the printable representation of the register + and display it. */ + tui_display_register (data_element_ptr, data_item_win); + i++; /* next register */ + } + cur_y++; /* next row; */ + } + } +} + + +/* Function to display the registers in the content from + 'start_element_no' on 'start_line_no' until the end of the register + content or the end of the display height. This function checks + that we won't display off the end of the register display. */ +void +tui_display_reg_element_at_line (int start_element_no, int start_line_no) +{ + if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL && + TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) + { + int element_no = start_element_no; + + if (start_element_no != 0 && start_line_no != 0) + { + int last_line_no, first_line_on_last_page; + + last_line_no = tui_last_regs_line_no (); + first_line_on_last_page = last_line_no - (TUI_DATA_WIN->generic.height - 2); + if (first_line_on_last_page < 0) + first_line_on_last_page = 0; + /* + ** If there is no other data displayed except registers, + ** and the element_no causes us to scroll past the end of the + ** registers, adjust what element to really start the display at. + */ + if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0 && + start_line_no > first_line_on_last_page) + element_no = tui_first_reg_element_no_inline (first_line_on_last_page); + } + tui_display_registers_from (element_no); + } +} + + + +/* Function to display the registers starting at line line_no in the + data window. Answers the line number that the display actually + started from. If nothing is displayed (-1) is returned. */ +int +tui_display_registers_from_line (int line_no, int force_display) +{ + if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) + { + int line, element_no; + + if (line_no < 0) + line = 0; + else if (force_display) + { /* + ** If we must display regs (force_display is true), then make + ** sure that we don't display off the end of the registers. + */ + if (line_no >= tui_last_regs_line_no ()) + { + if ((line = tui_line_from_reg_element_no ( + TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0) + line = 0; + } + else + line = line_no; + } + else + line = line_no; + + element_no = tui_first_reg_element_no_inline (line); + if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) + tui_display_reg_element_at_line (element_no, line); + else + line = (-1); + + return line; + } + + return (-1); /* nothing was displayed */ +} + + +/* This function check all displayed registers for changes in values, + given a particular frame. If the values have changed, they are + updated with the new value and highlighted. */ +void +tui_check_register_values (struct frame_info *frame) +{ + if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible) + { + struct tui_data_info *display_info + = &TUI_DATA_WIN->detail.data_display_info; + + if (display_info->regs_content_count <= 0 && display_info->display_regs) + tui_show_registers (display_info->current_group); + else + { + int i, j; + + for (i = 0; (i < display_info->regs_content_count); i++) + { + struct tui_data_element *data; + struct tui_gen_win_info *data_item_win_ptr; + int was_hilighted; + + data_item_win_ptr = &display_info->regs_content[i]-> + which_element.data_window; + data = &((struct tui_win_element *) + data_item_win_ptr->content[0])->which_element.data; + was_hilighted = data->highlight; + + tui_get_register (current_gdbarch, frame, data, + data->item_no, &data->highlight); + + if (data->highlight || was_hilighted) + { + tui_display_register (data, data_item_win_ptr); + } + } + } + } +} + +/* Display a register in a window. If hilite is TRUE, + then the value will be displayed in reverse video */ +static void +tui_display_register (struct tui_data_element *data, + struct tui_gen_win_info *win_info) +{ + if (win_info->handle != (WINDOW *) NULL) + { + int i; + + if (data->highlight) + wstandout (win_info->handle); + + wmove (win_info->handle, 0, 0); + for (i = 1; i < win_info->width; i++) + waddch (win_info->handle, ' '); + wmove (win_info->handle, 0, 0); + if (data->content) + waddstr (win_info->handle, data->content); + + if (data->highlight) + wstandend (win_info->handle); + tui_refresh_win (win_info); + } +} + +static void +tui_reg_next_command (char *arg, int from_tty) +{ + if (TUI_DATA_WIN != 0) + { + struct reggroup *group + = TUI_DATA_WIN->detail.data_display_info.current_group; + + group = reggroup_next (current_gdbarch, group); + if (group == 0) + group = reggroup_next (current_gdbarch, 0); + + if (group) + tui_show_registers (group); + } +} + +static void +tui_reg_float_command (char *arg, int from_tty) +{ + tui_show_registers (float_reggroup); +} + +static void +tui_reg_general_command (char *arg, int from_tty) +{ + tui_show_registers (general_reggroup); +} + +static void +tui_reg_system_command (char *arg, int from_tty) +{ + tui_show_registers (system_reggroup); +} + +static struct cmd_list_element *tuireglist; + +static void +tui_reg_command (char *args, int from_tty) +{ + printf_unfiltered ("\"tui reg\" must be followed by the name of a " + "tui reg command.\n"); + help_list (tuireglist, "tui reg ", -1, gdb_stdout); +} + +void +_initialize_tui_regs (void) +{ + struct cmd_list_element **tuicmd; + + tuicmd = tui_get_cmd_list (); + + add_prefix_cmd ("reg", class_tui, tui_reg_command, + "TUI commands to control the register window.", + &tuireglist, "tui reg ", 0, + tuicmd); + + add_cmd ("float", class_tui, tui_reg_float_command, + "Display only floating point registers\n", + &tuireglist); + add_cmd ("general", class_tui, tui_reg_general_command, + "Display only general registers\n", + &tuireglist); + add_cmd ("system", class_tui, tui_reg_system_command, + "Display only system registers\n", + &tuireglist); + add_cmd ("next", class_tui, tui_reg_next_command, + "Display next register group\n", + &tuireglist); + + if (xdb_commands) + { + add_com ("fr", class_tui, tui_reg_float_command, + "Display only floating point registers\n"); + add_com ("gr", class_tui, tui_reg_general_command, + "Display only general registers\n"); + add_com ("sr", class_tui, tui_reg_system_command, + "Display only special registers\n"); + add_com ("+r", class_tui, tui_scroll_regs_forward_command, + "Scroll the registers window forward\n"); + add_com ("-r", class_tui, tui_scroll_regs_backward_command, + "Scroll the register window backward\n"); + } +} + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ + +extern int pagination_enabled; + +static void +tui_restore_gdbout (void *ui) +{ + ui_file_delete (gdb_stdout); + gdb_stdout = (struct ui_file*) ui; + pagination_enabled = 1; +} + +/* Get the register from the frame and make a printable representation + of it in the data element. */ +static void +tui_register_format (struct gdbarch *gdbarch, struct frame_info *frame, + struct tui_data_element *data_element, int regnum) +{ + struct ui_file *stream; + struct ui_file *old_stdout; + const char *name; + struct cleanup *cleanups; + char *p, *s; + int pos; + struct type *type = gdbarch_register_type (gdbarch, regnum); + + name = gdbarch_register_name (gdbarch, regnum); + if (name == 0) + { + return; + } + + pagination_enabled = 0; + old_stdout = gdb_stdout; + stream = tui_sfileopen (256); + gdb_stdout = stream; + cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout); + if (TYPE_VECTOR (type) != 0 && 0) + { + char buf[MAX_REGISTER_SIZE]; + int len; + + len = register_size (current_gdbarch, regnum); + fprintf_filtered (stream, "%-14s ", name); + get_frame_register (frame, regnum, buf); + print_scalar_formatted (buf, type, 'f', len, stream); + } + else + { + gdbarch_print_registers_info (current_gdbarch, stream, + frame, regnum, 1); + } + + /* Save formatted output in the buffer. */ + p = tui_file_get_strbuf (stream); + + /* Remove the possible \n. */ + s = strrchr (p, '\n'); + if (s && s[1] == 0) + *s = 0; + + xfree (data_element->content); + data_element->content = xstrdup (p); + do_cleanups (cleanups); +} + +/* Get the register value from the given frame and format it for + the display. When changep is set, check if the new register value + has changed with respect to the previous call. */ +static enum tui_status +tui_get_register (struct gdbarch *gdbarch, struct frame_info *frame, + struct tui_data_element *data, int regnum, int *changedp) +{ + enum tui_status ret = TUI_FAILURE; + + if (changedp) + *changedp = FALSE; + if (target_has_registers) + { + char buf[MAX_REGISTER_SIZE]; + + get_frame_register (frame, regnum, buf); + /* NOTE: cagney/2003-03-13: This is bogus. It is refering to + the register cache and not the frame which could have pulled + the register value off the stack. */ + if (register_cached (regnum) >= 0) + { + if (changedp) + { + int size = register_size (gdbarch, regnum); + char *old = (char*) data->value; + int i; + + for (i = 0; i < size; i++) + if (buf[i] != old[i]) + { + *changedp = TRUE; + old[i] = buf[i]; + } + } + + /* Reformat the data content if the value changed. */ + if (changedp == 0 || *changedp == TRUE) + tui_register_format (gdbarch, frame, data, regnum); + ret = TUI_SUCCESS; + } + } + return ret; +} + +static void +tui_scroll_regs_forward_command (char *arg, int from_tty) +{ + tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1); +} + + +static void +tui_scroll_regs_backward_command (char *arg, int from_tty) +{ + tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1); +} diff --git a/contrib/gdb/gdb/tui/tui-regs.h b/contrib/gdb/gdb/tui/tui-regs.h new file mode 100644 index 00000000000..01e2fba1b6d --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-regs.h @@ -0,0 +1,39 @@ +/* TUI display registers in window. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_REGS_H +#define TUI_REGS_H + +#include "tui/tui-data.h" /* For struct tui_register_display_type. */ + +extern void tui_check_register_values (struct frame_info *); +extern void tui_show_registers (struct reggroup *group); +extern void tui_display_registers_from (int); +extern int tui_display_registers_from_line (int, int); +extern int tui_last_regs_line_no (void); +extern int tui_first_reg_element_inline (int); +extern int tui_line_from_reg_element_no (int); +extern int tui_first_reg_element_no_inline (int lineno); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-source.c b/contrib/gdb/gdb/tui/tui-source.c new file mode 100644 index 00000000000..d5154b11da1 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-source.c @@ -0,0 +1,352 @@ +/* TUI display source window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include +#include "symtab.h" +#include "frame.h" +#include "breakpoint.h" +#include "source.h" +#include "symtab.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-stack.h" +#include "tui/tui-winsource.h" +#include "tui/tui-source.h" + +#include "gdb_string.h" +#include "gdb_curses.h" + +/* Function to display source in the source window. */ +enum tui_status +tui_set_source_content (struct symtab *s, int line_no, int noerror) +{ + enum tui_status ret = TUI_FAILURE; + + if (s != (struct symtab *) NULL && s->filename != (char *) NULL) + { + FILE *stream; + int i, desc, c, line_width, nlines; + char *src_line = 0; + + if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS) + { + line_width = TUI_SRC_WIN->generic.width - 1; + /* Take hilite (window border) into account, when calculating + the number of lines */ + nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no; + desc = open_source_file (s); + if (desc < 0) + { + if (!noerror) + { + char *name = alloca (strlen (s->filename) + 100); + sprintf (name, "%s:%d", s->filename, line_no); + print_sys_errmsg (name, errno); + } + ret = TUI_FAILURE; + } + else + { + if (s->line_charpos == 0) + find_source_lines (s, desc); + + if (line_no < 1 || line_no > s->nlines) + { + close (desc); + printf_unfiltered ( + "Line number %d out of range; %s has %d lines.\n", + line_no, s->filename, s->nlines); + } + else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0) + { + close (desc); + perror_with_name (s->filename); + } + else + { + int offset, cur_line_no, cur_line, cur_len, threshold; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + struct tui_source_info * src = &TUI_SRC_WIN->detail.source_info; + + if (TUI_SRC_WIN->generic.title) + xfree (TUI_SRC_WIN->generic.title); + TUI_SRC_WIN->generic.title = xstrdup (s->filename); + + if (src->filename) + xfree (src->filename); + src->filename = xstrdup (s->filename); + + /* Determine the threshold for the length of the line + and the offset to start the display. */ + offset = src->horizontal_offset; + threshold = (line_width - 1) + offset; + stream = fdopen (desc, FOPEN_RT); + clearerr (stream); + cur_line = 0; + cur_line_no = src->start_line_or_addr.line_no = line_no; + if (offset > 0) + src_line = (char *) xmalloc ( + (threshold + 1) * sizeof (char)); + while (cur_line < nlines) + { + struct tui_win_element * element = (struct tui_win_element *) + TUI_SRC_WIN->generic.content[cur_line]; + + /* get the first character in the line */ + c = fgetc (stream); + + if (offset == 0) + src_line = ((struct tui_win_element *) + TUI_SRC_WIN->generic.content[ + cur_line])->which_element.source.line; + /* Init the line with the line number */ + sprintf (src_line, "%-6d", cur_line_no); + cur_len = strlen (src_line); + i = cur_len - + ((cur_len / tui_default_tab_len ()) * tui_default_tab_len ()); + while (i < tui_default_tab_len ()) + { + src_line[cur_len] = ' '; + i++; + cur_len++; + } + src_line[cur_len] = (char) 0; + + /* Set whether element is the execution point and + whether there is a break point on it. */ + element->which_element.source.line_or_addr.line_no = + cur_line_no; + element->which_element.source.is_exec_point = + (strcmp (((struct tui_win_element *) + locator->content[0])->which_element.locator.file_name, + s->filename) == 0 + && cur_line_no == ((struct tui_win_element *) + locator->content[0])->which_element.locator.line_no); + if (c != EOF) + { + i = strlen (src_line) - 1; + do + { + if ((c != '\n') && + (c != '\r') && (++i < threshold)) + { + if (c < 040 && c != '\t') + { + src_line[i++] = '^'; + src_line[i] = c + 0100; + } + else if (c == 0177) + { + src_line[i++] = '^'; + src_line[i] = '?'; + } + else + { /* Store the charcter in the line + buffer. If it is a tab, then + translate to the correct number of + chars so we don't overwrite our + buffer. */ + if (c == '\t') + { + int j, max_tab_len = tui_default_tab_len (); + + for (j = i - ( + (i / max_tab_len) * max_tab_len); + ((j < max_tab_len) && + i < threshold); + i++, j++) + src_line[i] = ' '; + i--; + } + else + src_line[i] = c; + } + src_line[i + 1] = 0; + } + else + { /* If we have not reached EOL, then eat + chars until we do */ + while (c != EOF && c != '\n' && c != '\r') + c = fgetc (stream); + } + } + while (c != EOF && c != '\n' && c != '\r' && + i < threshold && (c = fgetc (stream))); + } + /* Now copy the line taking the offset into account */ + if (strlen (src_line) > offset) + strcpy (((struct tui_win_element *) TUI_SRC_WIN->generic.content[ + cur_line])->which_element.source.line, + &src_line[offset]); + else + ((struct tui_win_element *) + TUI_SRC_WIN->generic.content[ + cur_line])->which_element.source.line[0] = (char) 0; + cur_line++; + cur_line_no++; + } + if (offset > 0) + xfree (src_line); + fclose (stream); + TUI_SRC_WIN->generic.content_size = nlines; + ret = TUI_SUCCESS; + } + } + } + } + return ret; +} + + +/* elz: this function sets the contents of the source window to empty + except for a line in the middle with a warning message about the + source not being available. This function is called by + tui_erase_source_contents(), which in turn is invoked when the + source files cannot be accessed. */ + +void +tui_set_source_content_nil (struct tui_win_info * win_info, char *warning_string) +{ + int line_width; + int n_lines; + int curr_line = 0; + + line_width = win_info->generic.width - 1; + n_lines = win_info->generic.height - 2; + + /* set to empty each line in the window, except for the one + which contains the message */ + while (curr_line < win_info->generic.content_size) + { + /* set the information related to each displayed line + to null: i.e. the line number is 0, there is no bp, + it is not where the program is stopped */ + + struct tui_win_element * element = + (struct tui_win_element *) win_info->generic.content[curr_line]; + element->which_element.source.line_or_addr.line_no = 0; + element->which_element.source.is_exec_point = FALSE; + element->which_element.source.has_break = FALSE; + + /* set the contents of the line to blank */ + element->which_element.source.line[0] = (char) 0; + + /* if the current line is in the middle of the screen, then we + want to display the 'no source available' message in it. + Note: the 'weird' arithmetic with the line width and height + comes from the function tui_erase_source_content(). We need + to keep the screen and the window's actual contents in synch. */ + + if (curr_line == (n_lines / 2 + 1)) + { + int i; + int xpos; + int warning_length = strlen (warning_string); + char *src_line; + + src_line = element->which_element.source.line; + + if (warning_length >= ((line_width - 1) / 2)) + xpos = 1; + else + xpos = (line_width - 1) / 2 - warning_length; + + for (i = 0; i < xpos; i++) + src_line[i] = ' '; + + sprintf (src_line + i, "%s", warning_string); + + for (i = xpos + warning_length; i < line_width; i++) + src_line[i] = ' '; + + src_line[i] = '\n'; + + } /* end if */ + + curr_line++; + + } /* end while */ +} + + +/* Function to display source in the source window. This function + initializes the horizontal scroll to 0. */ +void +tui_show_symtab_source (struct symtab *s, union tui_line_or_address line, int noerror) +{ + TUI_SRC_WIN->detail.source_info.horizontal_offset = 0; + tui_update_source_window_as_is (TUI_SRC_WIN, s, line, noerror); +} + + +/* Answer whether the source is currently displayed in the source + window. */ +int +tui_source_is_displayed (char *fname) +{ + return (TUI_SRC_WIN->generic.content_in_use && + (strcmp (((struct tui_win_element *) (tui_locator_win_info_ptr ())-> + content[0])->which_element.locator.file_name, fname) == 0)); +} + + +/* Scroll the source forward or backward vertically. */ +void +tui_vertical_source_scroll (enum tui_scroll_direction scroll_direction, + int num_to_scroll) +{ + if (TUI_SRC_WIN->generic.content != NULL) + { + union tui_line_or_address l; + struct symtab *s; + tui_win_content content = (tui_win_content) TUI_SRC_WIN->generic.content; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + if (cursal.symtab == (struct symtab *) NULL) + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + else + s = cursal.symtab; + + if (scroll_direction == FORWARD_SCROLL) + { + l.line_no = content[0]->which_element.source.line_or_addr.line_no + + num_to_scroll; + if (l.line_no > s->nlines) + /*line = s->nlines - win_info->generic.content_size + 1; */ + /*elz: fix for dts 23398 */ + l.line_no = content[0]->which_element.source.line_or_addr.line_no; + } + else + { + l.line_no = content[0]->which_element.source.line_or_addr.line_no - + num_to_scroll; + if (l.line_no <= 0) + l.line_no = 1; + } + + print_source_lines (s, l.line_no, l.line_no + 1, 0); + } +} diff --git a/contrib/gdb/gdb/tui/tui-source.h b/contrib/gdb/gdb/tui/tui-source.h new file mode 100644 index 00000000000..3b61ca4374d --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-source.h @@ -0,0 +1,40 @@ +/* TUI display source window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_SOURCE_H +#define TUI_SOURCE_H + +#include "tui/tui-data.h" + +struct symtab; +struct tui_win_info; + +extern void tui_set_source_content_nil (struct tui_win_info *, char *); + +extern enum tui_status tui_set_source_content (struct symtab *, int, int); +extern void tui_show_symtab_source (struct symtab *, union tui_line_or_address, int); +extern int tui_source_is_displayed (char *); +extern void tui_vertical_source_scroll (enum tui_scroll_direction, int); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-stack.c b/contrib/gdb/gdb/tui/tui-stack.c new file mode 100644 index 00000000000..0ee538988f4 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-stack.c @@ -0,0 +1,427 @@ +/* TUI display locator. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" +#include "command.h" +#include "inferior.h" +#include "target.h" +#include "top.h" +#include "gdb_string.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-stack.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-source.h" +#include "tui/tui-winsource.h" +#include "tui/tui-file.h" + +#include "gdb_curses.h" + +/* Get a printable name for the function at the address. + The symbol name is demangled if demangling is turned on. + Returns a pointer to a static area holding the result. */ +static char* tui_get_function_from_frame (struct frame_info *fi); + +/* Set the filename portion of the locator. */ +static void tui_set_locator_filename (const char *filename); + +/* Update the locator, with the provided arguments. */ +static void tui_set_locator_info (const char *filename, const char *procname, + int lineno, CORE_ADDR addr); + +static void tui_update_command (char *, int); + + +/* Create the status line to display as much information as we + can on this single line: target name, process number, current + function, current line, current PC, SingleKey mode. */ +static char* +tui_make_status_line (struct tui_locator_element* loc) +{ + char* string; + char line_buf[50], *pname; + char* buf; + int status_size; + int i, proc_width; + const char* pid_name; + const char* pc_buf; + int target_width; + int pid_width; + int line_width; + int pc_width; + struct ui_file *pc_out; + + if (ptid_equal (inferior_ptid, null_ptid)) + pid_name = "No process"; + else + pid_name = target_pid_to_str (inferior_ptid); + + target_width = strlen (target_shortname); + if (target_width > MAX_TARGET_WIDTH) + target_width = MAX_TARGET_WIDTH; + + pid_width = strlen (pid_name); + if (pid_width > MAX_PID_WIDTH) + pid_width = MAX_PID_WIDTH; + + status_size = tui_term_width (); + string = (char *) xmalloc (status_size + 1); + buf = (char*) alloca (status_size + 1); + + /* Translate line number and obtain its size. */ + if (loc->line_no > 0) + sprintf (line_buf, "%d", loc->line_no); + else + strcpy (line_buf, "??"); + line_width = strlen (line_buf); + if (line_width < MIN_LINE_WIDTH) + line_width = MIN_LINE_WIDTH; + + /* Translate PC address. */ + pc_out = tui_sfileopen (128); + print_address_numeric (loc->addr, 1, pc_out); + pc_buf = tui_file_get_strbuf (pc_out); + pc_width = strlen (pc_buf); + + /* First determine the amount of proc name width we have available. + The +1 are for a space separator between fields. + The -1 are to take into account the \0 counted by sizeof. */ + proc_width = (status_size + - (target_width + 1) + - (pid_width + 1) + - (sizeof (PROC_PREFIX) - 1 + 1) + - (sizeof (LINE_PREFIX) - 1 + line_width + 1) + - (sizeof (PC_PREFIX) - 1 + pc_width + 1) + - (tui_current_key_mode == TUI_SINGLE_KEY_MODE + ? (sizeof (SINGLE_KEY) - 1 + 1) + : 0)); + + /* If there is no room to print the function name, try by removing + some fields. */ + if (proc_width < MIN_PROC_WIDTH) + { + proc_width += target_width + 1; + target_width = 0; + if (proc_width < MIN_PROC_WIDTH) + { + proc_width += pid_width + 1; + pid_width = 0; + if (proc_width <= MIN_PROC_WIDTH) + { + proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1; + pc_width = 0; + if (proc_width < 0) + { + proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1; + line_width = 0; + if (proc_width < 0) + proc_width = 0; + } + } + } + } + + /* Now convert elements to string form */ + pname = loc->proc_name; + + /* Now create the locator line from the string version + of the elements. We could use sprintf() here but + that wouldn't ensure that we don't overrun the size + of the allocated buffer. strcat_to_buf() will. */ + *string = (char) 0; + + if (target_width > 0) + { + sprintf (buf, "%*.*s ", + -target_width, target_width, target_shortname); + strcat_to_buf (string, status_size, buf); + } + if (pid_width > 0) + { + sprintf (buf, "%*.*s ", + -pid_width, pid_width, pid_name); + strcat_to_buf (string, status_size, buf); + } + + /* Show whether we are in SingleKey mode. */ + if (tui_current_key_mode == TUI_SINGLE_KEY_MODE) + { + strcat_to_buf (string, status_size, SINGLE_KEY); + strcat_to_buf (string, status_size, " "); + } + + /* procedure/class name */ + if (proc_width > 0) + { + if (strlen (pname) > proc_width) + sprintf (buf, "%s%*.*s* ", PROC_PREFIX, + 1 - proc_width, proc_width - 1, pname); + else + sprintf (buf, "%s%*.*s ", PROC_PREFIX, + -proc_width, proc_width, pname); + strcat_to_buf (string, status_size, buf); + } + + if (line_width > 0) + { + sprintf (buf, "%s%*.*s ", LINE_PREFIX, + -line_width, line_width, line_buf); + strcat_to_buf (string, status_size, buf); + } + if (pc_width > 0) + { + strcat_to_buf (string, status_size, PC_PREFIX); + strcat_to_buf (string, status_size, pc_buf); + } + + + for (i = strlen (string); i < status_size; i++) + string[i] = ' '; + string[status_size] = (char) 0; + + ui_file_delete (pc_out); + return string; +} + +/* Get a printable name for the function at the address. + The symbol name is demangled if demangling is turned on. + Returns a pointer to a static area holding the result. */ +static char* +tui_get_function_from_frame (struct frame_info *fi) +{ + static char name[256]; + struct ui_file *stream = tui_sfileopen (256); + char *p; + + print_address_symbolic (get_frame_pc (fi), stream, demangle, ""); + p = tui_file_get_strbuf (stream); + + /* Use simple heuristics to isolate the function name. The symbol can + be demangled and we can have function parameters. Remove them because + the status line is too short to display them. */ + if (*p == '<') + p++; + strncpy (name, p, sizeof (name)); + p = strchr (name, '('); + if (!p) + p = strchr (name, '>'); + if (p) + *p = 0; + p = strchr (name, '+'); + if (p) + *p = 0; + ui_file_delete (stream); + return name; +} + +void +tui_show_locator_content (void) +{ + char *string; + struct tui_gen_win_info * locator; + + locator = tui_locator_win_info_ptr (); + + if (locator != NULL && locator->handle != (WINDOW *) NULL) + { + struct tui_win_element * element; + + element = (struct tui_win_element *) locator->content[0]; + + string = tui_make_status_line (&element->which_element.locator); + wmove (locator->handle, 0, 0); + wstandout (locator->handle); + waddstr (locator->handle, string); + wclrtoeol (locator->handle); + wstandend (locator->handle); + tui_refresh_win (locator); + wmove (locator->handle, 0, 0); + xfree (string); + locator->content_in_use = TRUE; + } +} + + +/* Set the filename portion of the locator. */ +static void +tui_set_locator_filename (const char *filename) +{ + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + struct tui_locator_element * element; + + if (locator->content[0] == NULL) + { + tui_set_locator_info (filename, NULL, 0, 0); + return; + } + + element = &((struct tui_win_element *) locator->content[0])->which_element.locator; + element->file_name[0] = 0; + strcat_to_buf (element->file_name, MAX_LOCATOR_ELEMENT_LEN, filename); +} + +/* Update the locator, with the provided arguments. */ +static void +tui_set_locator_info (const char *filename, const char *procname, int lineno, + CORE_ADDR addr) +{ + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + struct tui_locator_element * element; + + /* Allocate the locator content if necessary. */ + if (locator->content_size <= 0) + { + locator->content = (void **) tui_alloc_content (1, locator->type); + locator->content_size = 1; + } + + element = &((struct tui_win_element *) locator->content[0])->which_element.locator; + element->proc_name[0] = (char) 0; + strcat_to_buf (element->proc_name, MAX_LOCATOR_ELEMENT_LEN, procname); + element->line_no = lineno; + element->addr = addr; + tui_set_locator_filename (filename); +} + +/* Update only the filename portion of the locator. */ +void +tui_update_locator_filename (const char *filename) +{ + tui_set_locator_filename (filename); + tui_show_locator_content (); +} + +/* Function to print the frame information for the TUI. */ +void +tui_show_frame_info (struct frame_info *fi) +{ + struct tui_win_info * win_info; + int i; + + if (fi) + { + int start_line, i; + CORE_ADDR low; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + int source_already_displayed; + struct symtab_and_line sal; + + find_frame_sal (fi, &sal); + + source_already_displayed = sal.symtab != 0 + && tui_source_is_displayed (sal.symtab->filename); + tui_set_locator_info (sal.symtab == 0 ? "??" : sal.symtab->filename, + tui_get_function_from_frame (fi), + sal.line, + get_frame_pc (fi)); + tui_show_locator_content (); + start_line = 0; + for (i = 0; i < (tui_source_windows ())->count; i++) + { + union tui_which_element *item; + win_info = (struct tui_win_info *) (tui_source_windows ())->list[i]; + + item = &((struct tui_win_element *) locator->content[0])->which_element; + if (win_info == TUI_SRC_WIN) + { + start_line = (item->locator.line_no - + (win_info->generic.viewport_height / 2)) + 1; + if (start_line <= 0) + start_line = 1; + } + else + { + if (find_pc_partial_function (get_frame_pc (fi), (char **) NULL, + &low, (CORE_ADDR) NULL) == 0) + error ("No function contains program counter for selected frame.\n"); + else + low = tui_get_low_disassembly_address (low, get_frame_pc (fi)); + } + + if (win_info == TUI_SRC_WIN) + { + union tui_line_or_address l; + l.line_no = start_line; + if (!(source_already_displayed + && tui_line_is_displayed (item->locator.line_no, win_info, TRUE))) + tui_update_source_window (win_info, sal.symtab, l, TRUE); + else + { + l.line_no = item->locator.line_no; + tui_set_is_exec_point_at (l, win_info); + } + } + else + { + if (win_info == TUI_DISASM_WIN) + { + union tui_line_or_address a; + a.addr = low; + if (!tui_addr_is_displayed (item->locator.addr, win_info, TRUE)) + tui_update_source_window (win_info, sal.symtab, a, TRUE); + else + { + a.addr = item->locator.addr; + tui_set_is_exec_point_at (a, win_info); + } + } + } + tui_update_exec_info (win_info); + } + } + else + { + tui_set_locator_info (NULL, NULL, 0, (CORE_ADDR) 0); + tui_show_locator_content (); + for (i = 0; i < (tui_source_windows ())->count; i++) + { + win_info = (struct tui_win_info *) (tui_source_windows ())->list[i]; + tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT); + tui_update_exec_info (win_info); + } + } +} + +/* Function to initialize gdb commands, for tui window stack + manipulation. */ +void +_initialize_tui_stack (void) +{ + add_com ("update", class_tui, tui_update_command, + "Update the source window and locator to display the current " + "execution point.\n"); +} + +/* Command to update the display with the current execution point. */ +static void +tui_update_command (char *arg, int from_tty) +{ + char cmd[sizeof("frame 0")]; + + strcpy (cmd, "frame 0"); + execute_command (cmd, from_tty); +} diff --git a/contrib/gdb/gdb/tui/tui-stack.h b/contrib/gdb/gdb/tui/tui-stack.h new file mode 100644 index 00000000000..65725b3fd2f --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-stack.h @@ -0,0 +1,34 @@ +/* TUI display locator. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_STACK_H +#define TUI_STACK_H + +struct frame_info; + +extern void tui_update_locator_filename (const char *); +extern void tui_show_locator_content (void); +extern void tui_show_frame_info (struct frame_info *); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-win.c b/contrib/gdb/gdb/tui/tui-win.c new file mode 100644 index 00000000000..1c67baa8b01 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-win.c @@ -0,0 +1,1520 @@ +/* TUI window generic functions. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This module contains procedures for handling tui window functions + like resize, scrolling, scrolling, changing focus, etc. + + Author: Susan B. Macchia */ + +#include "defs.h" +#include "command.h" +#include "symtab.h" +#include "breakpoint.h" +#include "frame.h" +#include "cli/cli-cmds.h" +#include "top.h" +#include "source.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-stack.h" +#include "tui/tui-regs.h" +#include "tui/tui-disasm.h" +#include "tui/tui-source.h" +#include "tui/tui-winsource.h" +#include "tui/tui-windata.h" + +#include "gdb_curses.h" + +#include "gdb_string.h" +#include +#include "readline/readline.h" + +/******************************* +** Static Local Decls +********************************/ +static void make_visible_with_new_height (struct tui_win_info *); +static void make_invisible_and_set_new_height (struct tui_win_info *, int); +static enum tui_status tui_adjust_win_heights (struct tui_win_info *, int); +static int new_height_ok (struct tui_win_info *, int); +static void tui_set_tab_width_command (char *, int); +static void tui_refresh_all_command (char *, int); +static void tui_set_win_height_command (char *, int); +static void tui_xdb_set_win_height_command (char *, int); +static void tui_all_windows_info (char *, int); +static void tui_set_focus_command (char *, int); +static void tui_scroll_forward_command (char *, int); +static void tui_scroll_backward_command (char *, int); +static void tui_scroll_left_command (char *, int); +static void tui_scroll_right_command (char *, int); +static void parse_scrolling_args (char *, struct tui_win_info * *, int *); + + +/*************************************** +** DEFINITIONS +***************************************/ +#define WIN_HEIGHT_USAGE "Usage: winheight [+ | -] <#lines>\n" +#define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n" +#define FOCUS_USAGE "Usage: focus { | next | prev}\n" + +/*************************************** +** PUBLIC FUNCTIONS +***************************************/ + +#ifndef ACS_LRCORNER +# define ACS_LRCORNER '+' +#endif +#ifndef ACS_LLCORNER +# define ACS_LLCORNER '+' +#endif +#ifndef ACS_ULCORNER +# define ACS_ULCORNER '+' +#endif +#ifndef ACS_URCORNER +# define ACS_URCORNER '+' +#endif +#ifndef ACS_HLINE +# define ACS_HLINE '-' +#endif +#ifndef ACS_VLINE +# define ACS_VLINE '|' +#endif + +/* Possible values for tui-border-kind variable. */ +static const char *tui_border_kind_enums[] = { + "space", + "ascii", + "acs", + NULL +}; + +/* Possible values for tui-border-mode and tui-active-border-mode. */ +static const char *tui_border_mode_enums[] = { + "normal", + "standout", + "reverse", + "half", + "half-standout", + "bold", + "bold-standout", + NULL +}; + +struct tui_translate +{ + const char *name; + int value; +}; + +/* Translation table for border-mode variables. + The list of values must be terminated by a NULL. + After the NULL value, an entry defines the default. */ +struct tui_translate tui_border_mode_translate[] = { + { "normal", A_NORMAL }, + { "standout", A_STANDOUT }, + { "reverse", A_REVERSE }, + { "half", A_DIM }, + { "half-standout", A_DIM | A_STANDOUT }, + { "bold", A_BOLD }, + { "bold-standout", A_BOLD | A_STANDOUT }, + { 0, 0 }, + { "normal", A_NORMAL } +}; + +/* Translation tables for border-kind, one for each border + character (see wborder, border curses operations). + -1 is used to indicate the ACS because ACS characters + are determined at run time by curses (depends on terminal). */ +struct tui_translate tui_border_kind_translate_vline[] = { + { "space", ' ' }, + { "ascii", '|' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '|' } +}; + +struct tui_translate tui_border_kind_translate_hline[] = { + { "space", ' ' }, + { "ascii", '-' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '-' } +}; + +struct tui_translate tui_border_kind_translate_ulcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + +struct tui_translate tui_border_kind_translate_urcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + +struct tui_translate tui_border_kind_translate_llcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + +struct tui_translate tui_border_kind_translate_lrcorner[] = { + { "space", ' ' }, + { "ascii", '+' }, + { "acs", -1 }, + { 0, 0 }, + { "ascii", '+' } +}; + + +/* Tui configuration variables controlled with set/show command. */ +const char *tui_active_border_mode = "bold-standout"; +const char *tui_border_mode = "normal"; +const char *tui_border_kind = "acs"; + +/* Tui internal configuration variables. These variables are + updated by tui_update_variables to reflect the tui configuration + variables. */ +chtype tui_border_vline; +chtype tui_border_hline; +chtype tui_border_ulcorner; +chtype tui_border_urcorner; +chtype tui_border_llcorner; +chtype tui_border_lrcorner; + +int tui_border_attrs; +int tui_active_border_attrs; + +/* Identify the item in the translation table. + When the item is not recognized, use the default entry. */ +static struct tui_translate * +translate (const char *name, struct tui_translate *table) +{ + while (table->name) + { + if (name && strcmp (table->name, name) == 0) + return table; + table++; + } + + /* Not found, return default entry. */ + table++; + return table; +} + +/* Update the tui internal configuration according to gdb settings. + Returns 1 if the configuration has changed and the screen should + be redrawn. */ +int +tui_update_variables (void) +{ + int need_redraw = 0; + struct tui_translate *entry; + + entry = translate (tui_border_mode, tui_border_mode_translate); + if (tui_border_attrs != entry->value) + { + tui_border_attrs = entry->value; + need_redraw = 1; + } + entry = translate (tui_active_border_mode, tui_border_mode_translate); + if (tui_active_border_attrs != entry->value) + { + tui_active_border_attrs = entry->value; + need_redraw = 1; + } + + /* If one corner changes, all characters are changed. + Only check the first one. The ACS characters are determined at + run time by curses terminal management. */ + entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner); + if (tui_border_lrcorner != (chtype) entry->value) + { + tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value; + need_redraw = 1; + } + entry = translate (tui_border_kind, tui_border_kind_translate_llcorner); + tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner); + tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_urcorner); + tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_hline); + tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value; + + entry = translate (tui_border_kind, tui_border_kind_translate_vline); + tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value; + + return need_redraw; +} + +static void +set_tui_cmd (char *args, int from_tty) +{ +} + +static void +show_tui_cmd (char *args, int from_tty) +{ +} + +static struct cmd_list_element *tuilist; + +static void +tui_command (char *args, int from_tty) +{ + printf_unfiltered ("\"tui\" must be followed by the name of a " + "tui command.\n"); + help_list (tuilist, "tui ", -1, gdb_stdout); +} + +struct cmd_list_element ** +tui_get_cmd_list () +{ + if (tuilist == 0) + add_prefix_cmd ("tui", class_tui, tui_command, + "Text User Interface commands.", + &tuilist, "tui ", 0, &cmdlist); + return &tuilist; +} + +/* Function to initialize gdb commands, for tui window manipulation. */ +void +_initialize_tui_win (void) +{ + struct cmd_list_element *c; + static struct cmd_list_element *tui_setlist; + static struct cmd_list_element *tui_showlist; + + /* Define the classes of commands. + They will appear in the help list in the reverse of this order. */ + add_prefix_cmd ("tui", class_tui, set_tui_cmd, + "TUI configuration variables", + &tui_setlist, "set tui ", + 0/*allow-unknown*/, &setlist); + add_prefix_cmd ("tui", class_tui, show_tui_cmd, + "TUI configuration variables", + &tui_showlist, "show tui ", + 0/*allow-unknown*/, &showlist); + + add_com ("refresh", class_tui, tui_refresh_all_command, + "Refresh the terminal display.\n"); + if (xdb_commands) + add_com_alias ("U", "refresh", class_tui, 0); + add_com ("tabset", class_tui, tui_set_tab_width_command, + "Set the width (in characters) of tab stops.\n\ +Usage: tabset \n"); + add_com ("winheight", class_tui, tui_set_win_height_command, + "Set the height of a specified window.\n\ +Usage: winheight [+ | -] <#lines>\n\ +Window names are:\n\ +src : the source window\n\ +cmd : the command window\n\ +asm : the disassembly window\n\ +regs : the register display\n"); + add_com_alias ("wh", "winheight", class_tui, 0); + add_info ("win", tui_all_windows_info, + "List of all displayed windows.\n"); + add_com ("focus", class_tui, tui_set_focus_command, + "Set focus to named window or next/prev window.\n\ +Usage: focus { | next | prev}\n\ +Valid Window names are:\n\ +src : the source window\n\ +asm : the disassembly window\n\ +regs : the register display\n\ +cmd : the command window\n"); + add_com_alias ("fs", "focus", class_tui, 0); + add_com ("+", class_tui, tui_scroll_forward_command, + "Scroll window forward.\nUsage: + [win] [n]\n"); + add_com ("-", class_tui, tui_scroll_backward_command, + "Scroll window backward.\nUsage: - [win] [n]\n"); + add_com ("<", class_tui, tui_scroll_left_command, + "Scroll window forward.\nUsage: < [win] [n]\n"); + add_com (">", class_tui, tui_scroll_right_command, + "Scroll window backward.\nUsage: > [win] [n]\n"); + if (xdb_commands) + add_com ("w", class_xdb, tui_xdb_set_win_height_command, + "XDB compatibility command for setting the height of a command window.\n\ +Usage: w <#lines>\n"); + + /* Define the tui control variables. */ + c = add_set_enum_cmd + ("border-kind", no_class, + tui_border_kind_enums, &tui_border_kind, + "Set the kind of border for TUI windows.\n" + "This variable controls the border of TUI windows:\n" + "space use a white space\n" + "ascii use ascii characters + - | for the border\n" + "acs use the Alternate Character Set\n", + &tui_setlist); + add_show_from_set (c, &tui_showlist); + + c = add_set_enum_cmd + ("border-mode", no_class, + tui_border_mode_enums, &tui_border_mode, + "Set the attribute mode to use for the TUI window borders.\n" + "This variable controls the attributes to use for the window borders:\n" + "normal normal display\n" + "standout use highlight mode of terminal\n" + "reverse use reverse video mode\n" + "half use half bright\n" + "half-standout use half bright and standout mode\n" + "bold use extra bright or bold\n" + "bold-standout use extra bright or bold with standout mode\n", + &tui_setlist); + add_show_from_set (c, &tui_showlist); + + c = add_set_enum_cmd + ("active-border-mode", no_class, + tui_border_mode_enums, &tui_active_border_mode, + "Set the attribute mode to use for the active TUI window border.\n" + "This variable controls the attributes to use for the active window border:\n" + "normal normal display\n" + "standout use highlight mode of terminal\n" + "reverse use reverse video mode\n" + "half use half bright\n" + "half-standout use half bright and standout mode\n" + "bold use extra bright or bold\n" + "bold-standout use extra bright or bold with standout mode\n", + &tui_setlist); + add_show_from_set (c, &tui_showlist); +} + +/* Update gdb's knowledge of the terminal size. */ +void +tui_update_gdb_sizes (void) +{ + char cmd[50]; + int screenheight, screenwidth; + + rl_get_screen_size (&screenheight, &screenwidth); + /* Set to TUI command window dimension or use readline values. */ + sprintf (cmd, "set width %d", + tui_active ? TUI_CMD_WIN->generic.width : screenwidth); + execute_command (cmd, 0); + sprintf (cmd, "set height %d", + tui_active ? TUI_CMD_WIN->generic.height : screenheight); + execute_command (cmd, 0); +} + + +/* Set the logical focus to win_info. */ +void +tui_set_win_focus_to (struct tui_win_info * win_info) +{ + if (win_info != NULL) + { + struct tui_win_info * win_with_focus = tui_win_with_focus (); + + if (win_with_focus != NULL + && win_with_focus->generic.type != CMD_WIN) + tui_unhighlight_win (win_with_focus); + tui_set_win_with_focus (win_info); + if (win_info->generic.type != CMD_WIN) + tui_highlight_win (win_info); + } +} + + +void +tui_scroll_forward (struct tui_win_info * win_to_scroll, int num_to_scroll) +{ + if (win_to_scroll != TUI_CMD_WIN) + { + int _num_to_scroll = num_to_scroll; + + if (num_to_scroll == 0) + _num_to_scroll = win_to_scroll->generic.height - 3; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If win_to_scroll is the + ** command window do nothing since the term should handle it. + */ + if (win_to_scroll == TUI_SRC_WIN) + tui_vertical_source_scroll (FORWARD_SCROLL, _num_to_scroll); + else if (win_to_scroll == TUI_DISASM_WIN) + tui_vertical_disassem_scroll (FORWARD_SCROLL, _num_to_scroll); + else if (win_to_scroll == TUI_DATA_WIN) + tui_vertical_data_scroll (FORWARD_SCROLL, _num_to_scroll); + } +} + +void +tui_scroll_backward (struct tui_win_info * win_to_scroll, int num_to_scroll) +{ + if (win_to_scroll != TUI_CMD_WIN) + { + int _num_to_scroll = num_to_scroll; + + if (num_to_scroll == 0) + _num_to_scroll = win_to_scroll->generic.height - 3; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If win_to_scroll is the + ** command window do nothing since the term should handle it. + */ + if (win_to_scroll == TUI_SRC_WIN) + tui_vertical_source_scroll (BACKWARD_SCROLL, _num_to_scroll); + else if (win_to_scroll == TUI_DISASM_WIN) + tui_vertical_disassem_scroll (BACKWARD_SCROLL, _num_to_scroll); + else if (win_to_scroll == TUI_DATA_WIN) + tui_vertical_data_scroll (BACKWARD_SCROLL, _num_to_scroll); + } +} + + +void +tui_scroll_left (struct tui_win_info * win_to_scroll, int num_to_scroll) +{ + if (win_to_scroll != TUI_CMD_WIN) + { + int _num_to_scroll = num_to_scroll; + + if (_num_to_scroll == 0) + _num_to_scroll = 1; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If win_to_scroll is the + ** command window do nothing since the term should handle it. + */ + if (win_to_scroll == TUI_SRC_WIN || win_to_scroll == TUI_DISASM_WIN) + tui_horizontal_source_scroll (win_to_scroll, LEFT_SCROLL, _num_to_scroll); + } +} + + +void +tui_scroll_right (struct tui_win_info * win_to_scroll, int num_to_scroll) +{ + if (win_to_scroll != TUI_CMD_WIN) + { + int _num_to_scroll = num_to_scroll; + + if (_num_to_scroll == 0) + _num_to_scroll = 1; + /* + ** If we are scrolling the source or disassembly window, do a + ** "psuedo" scroll since not all of the source is in memory, + ** only what is in the viewport. If win_to_scroll is the + ** command window do nothing since the term should handle it. + */ + if (win_to_scroll == TUI_SRC_WIN || win_to_scroll == TUI_DISASM_WIN) + tui_horizontal_source_scroll (win_to_scroll, RIGHT_SCROLL, _num_to_scroll); + } +} + + +/* Scroll a window. Arguments are passed through a va_list. */ +void +tui_scroll (enum tui_scroll_direction direction, + struct tui_win_info * win_to_scroll, + int num_to_scroll) +{ + switch (direction) + { + case FORWARD_SCROLL: + tui_scroll_forward (win_to_scroll, num_to_scroll); + break; + case BACKWARD_SCROLL: + tui_scroll_backward (win_to_scroll, num_to_scroll); + break; + case LEFT_SCROLL: + tui_scroll_left (win_to_scroll, num_to_scroll); + break; + case RIGHT_SCROLL: + tui_scroll_right (win_to_scroll, num_to_scroll); + break; + default: + break; + } +} + + +void +tui_refresh_all_win (void) +{ + enum tui_win_type type; + + clearok (curscr, TRUE); + tui_refresh_all (tui_win_list); + for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++) + { + if (tui_win_list[type] && tui_win_list[type]->generic.is_visible) + { + switch (type) + { + case SRC_WIN: + case DISASSEM_WIN: + tui_show_source_content (tui_win_list[type]); + tui_check_and_display_highlight_if_needed (tui_win_list[type]); + tui_erase_exec_info_content (tui_win_list[type]); + tui_update_exec_info (tui_win_list[type]); + break; + case DATA_WIN: + tui_refresh_data_win (); + break; + default: + break; + } + } + } + tui_show_locator_content (); +} + + +/* Resize all the windows based on the the terminal size. This + function gets called from within the readline sinwinch handler. */ +void +tui_resize_all (void) +{ + int height_diff, width_diff; + int screenheight, screenwidth; + + rl_get_screen_size (&screenheight, &screenwidth); + width_diff = screenwidth - tui_term_width (); + height_diff = screenheight - tui_term_height (); + if (height_diff || width_diff) + { + enum tui_layout_type cur_layout = tui_current_layout (); + struct tui_win_info * win_with_focus = tui_win_with_focus (); + struct tui_win_info *first_win; + struct tui_win_info *second_win; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + enum tui_win_type win_type; + int new_height, split_diff, cmd_split_diff, num_wins_displayed = 2; + +#ifdef HAVE_RESIZE_TERM + resize_term (screenheight, screenwidth); +#endif + /* turn keypad off while we resize */ + if (win_with_focus != TUI_CMD_WIN) + keypad (TUI_CMD_WIN->generic.handle, FALSE); + tui_update_gdb_sizes (); + tui_set_term_height_to (screenheight); + tui_set_term_width_to (screenwidth); + if (cur_layout == SRC_DISASSEM_COMMAND || + cur_layout == SRC_DATA_COMMAND || cur_layout == DISASSEM_DATA_COMMAND) + num_wins_displayed++; + split_diff = height_diff / num_wins_displayed; + cmd_split_diff = split_diff; + if (height_diff % num_wins_displayed) + { + if (height_diff < 0) + cmd_split_diff--; + else + cmd_split_diff++; + } + /* now adjust each window */ + clear (); + refresh (); + switch (cur_layout) + { + case SRC_COMMAND: + case DISASSEM_COMMAND: + first_win = (struct tui_win_info *) (tui_source_windows ())->list[0]; + first_win->generic.width += width_diff; + locator->width += width_diff; + /* check for invalid heights */ + if (height_diff == 0) + new_height = first_win->generic.height; + else if ((first_win->generic.height + split_diff) >= + (screenheight - MIN_CMD_WIN_HEIGHT - 1)) + new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1; + else if ((first_win->generic.height + split_diff) <= 0) + new_height = MIN_WIN_HEIGHT; + else + new_height = first_win->generic.height + split_diff; + + make_invisible_and_set_new_height (first_win, new_height); + TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; + TUI_CMD_WIN->generic.width += width_diff; + new_height = screenheight - TUI_CMD_WIN->generic.origin.y; + make_invisible_and_set_new_height (TUI_CMD_WIN, new_height); + make_visible_with_new_height (first_win); + make_visible_with_new_height (TUI_CMD_WIN); + if (first_win->generic.content_size <= 0) + tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT); + break; + default: + if (cur_layout == SRC_DISASSEM_COMMAND) + { + first_win = TUI_SRC_WIN; + first_win->generic.width += width_diff; + second_win = TUI_DISASM_WIN; + second_win->generic.width += width_diff; + } + else + { + first_win = TUI_DATA_WIN; + first_win->generic.width += width_diff; + second_win = (struct tui_win_info *) (tui_source_windows ())->list[0]; + second_win->generic.width += width_diff; + } + /* Change the first window's height/width */ + /* check for invalid heights */ + if (height_diff == 0) + new_height = first_win->generic.height; + else if ((first_win->generic.height + + second_win->generic.height + (split_diff * 2)) >= + (screenheight - MIN_CMD_WIN_HEIGHT - 1)) + new_height = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2; + else if ((first_win->generic.height + split_diff) <= 0) + new_height = MIN_WIN_HEIGHT; + else + new_height = first_win->generic.height + split_diff; + make_invisible_and_set_new_height (first_win, new_height); + + locator->width += width_diff; + + /* Change the second window's height/width */ + /* check for invalid heights */ + if (height_diff == 0) + new_height = second_win->generic.height; + else if ((first_win->generic.height + + second_win->generic.height + (split_diff * 2)) >= + (screenheight - MIN_CMD_WIN_HEIGHT - 1)) + { + new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1; + if (new_height % 2) + new_height = (new_height / 2) + 1; + else + new_height /= 2; + } + else if ((second_win->generic.height + split_diff) <= 0) + new_height = MIN_WIN_HEIGHT; + else + new_height = second_win->generic.height + split_diff; + second_win->generic.origin.y = first_win->generic.height - 1; + make_invisible_and_set_new_height (second_win, new_height); + + /* Change the command window's height/width */ + TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; + make_invisible_and_set_new_height ( + TUI_CMD_WIN, TUI_CMD_WIN->generic.height + cmd_split_diff); + make_visible_with_new_height (first_win); + make_visible_with_new_height (second_win); + make_visible_with_new_height (TUI_CMD_WIN); + if (first_win->generic.content_size <= 0) + tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT); + if (second_win->generic.content_size <= 0) + tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT); + break; + } + /* + ** Now remove all invisible windows, and their content so that they get + ** created again when called for with the new size + */ + for (win_type = SRC_WIN; (win_type < MAX_MAJOR_WINDOWS); win_type++) + { + if (win_type != CMD_WIN && (tui_win_list[win_type] != NULL) + && !tui_win_list[win_type]->generic.is_visible) + { + tui_free_window (tui_win_list[win_type]); + tui_win_list[win_type] = (struct tui_win_info *) NULL; + } + } + tui_set_win_resized_to (TRUE); + /* turn keypad back on, unless focus is in the command window */ + if (win_with_focus != TUI_CMD_WIN) + keypad (TUI_CMD_WIN->generic.handle, TRUE); + } +} + + +/* SIGWINCH signal handler for the tui. This signal handler is always + called, even when the readline package clears signals because it is + set as the old_sigwinch() (TUI only). */ +void +tui_sigwinch_handler (int signal) +{ + /* + ** Say that a resize was done so that the readline can do it + ** later when appropriate. + */ + tui_set_win_resized_to (TRUE); +} + + + +/************************* +** STATIC LOCAL FUNCTIONS +**************************/ + + +static void +tui_scroll_forward_command (char *arg, int from_tty) +{ + int num_to_scroll = 1; + struct tui_win_info * win_to_scroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg == (char *) NULL) + parse_scrolling_args (arg, &win_to_scroll, (int *) NULL); + else + parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); + tui_scroll (FORWARD_SCROLL, win_to_scroll, num_to_scroll); +} + + +static void +tui_scroll_backward_command (char *arg, int from_tty) +{ + int num_to_scroll = 1; + struct tui_win_info * win_to_scroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg == (char *) NULL) + parse_scrolling_args (arg, &win_to_scroll, (int *) NULL); + else + parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); + tui_scroll (BACKWARD_SCROLL, win_to_scroll, num_to_scroll); +} + + +static void +tui_scroll_left_command (char *arg, int from_tty) +{ + int num_to_scroll; + struct tui_win_info * win_to_scroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); + tui_scroll (LEFT_SCROLL, win_to_scroll, num_to_scroll); +} + + +static void +tui_scroll_right_command (char *arg, int from_tty) +{ + int num_to_scroll; + struct tui_win_info * win_to_scroll; + + /* Make sure the curses mode is enabled. */ + tui_enable (); + parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); + tui_scroll (RIGHT_SCROLL, win_to_scroll, num_to_scroll); +} + + +/* Set focus to the window named by 'arg'. */ +static void +tui_set_focus (char *arg, int from_tty) +{ + if (arg != (char *) NULL) + { + char *buf_ptr = (char *) xstrdup (arg); + int i; + struct tui_win_info * win_info = (struct tui_win_info *) NULL; + + for (i = 0; (i < strlen (buf_ptr)); i++) + buf_ptr[i] = toupper (arg[i]); + + if (subset_compare (buf_ptr, "NEXT")) + win_info = tui_next_win (tui_win_with_focus ()); + else if (subset_compare (buf_ptr, "PREV")) + win_info = tui_prev_win (tui_win_with_focus ()); + else + win_info = tui_partial_win_by_name (buf_ptr); + + if (win_info == (struct tui_win_info *) NULL || !win_info->generic.is_visible) + warning ("Invalid window specified. \n\ +The window name specified must be valid and visible.\n"); + else + { + tui_set_win_focus_to (win_info); + keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN)); + } + + if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible) + tui_refresh_data_win (); + xfree (buf_ptr); + printf_filtered ("Focus set to %s window.\n", + tui_win_name ((struct tui_gen_win_info *) tui_win_with_focus ())); + } + else + warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE); +} + +static void +tui_set_focus_command (char *arg, int from_tty) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + tui_set_focus (arg, from_tty); +} + + +static void +tui_all_windows_info (char *arg, int from_tty) +{ + enum tui_win_type type; + struct tui_win_info * win_with_focus = tui_win_with_focus (); + + for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) + if (tui_win_list[type] && tui_win_list[type]->generic.is_visible) + { + if (win_with_focus == tui_win_list[type]) + printf_filtered (" %s\t(%d lines) \n", + tui_win_name (&tui_win_list[type]->generic), + tui_win_list[type]->generic.height); + else + printf_filtered (" %s\t(%d lines)\n", + tui_win_name (&tui_win_list[type]->generic), + tui_win_list[type]->generic.height); + } +} + + +static void +tui_refresh_all_command (char *arg, int from_tty) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + + tui_refresh_all_win (); +} + + +/* Set the height of the specified window. */ +static void +tui_set_tab_width_command (char *arg, int from_tty) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg != (char *) NULL) + { + int ts; + + ts = atoi (arg); + if (ts > 0) + tui_set_default_tab_len (ts); + else + warning ("Tab widths greater than 0 must be specified.\n"); + } +} + + +/* Set the height of the specified window. */ +static void +tui_set_win_height (char *arg, int from_tty) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg != (char *) NULL) + { + char *buf = xstrdup (arg); + char *buf_ptr = buf; + char *wname = (char *) NULL; + int new_height, i; + struct tui_win_info * win_info; + + wname = buf_ptr; + buf_ptr = strchr (buf_ptr, ' '); + if (buf_ptr != (char *) NULL) + { + *buf_ptr = (char) 0; + + /* + ** Validate the window name + */ + for (i = 0; i < strlen (wname); i++) + wname[i] = toupper (wname[i]); + win_info = tui_partial_win_by_name (wname); + + if (win_info == (struct tui_win_info *) NULL || !win_info->generic.is_visible) + warning ("Invalid window specified. \n\ +The window name specified must be valid and visible.\n"); + else + { + /* Process the size */ + while (*(++buf_ptr) == ' ') + ; + + if (*buf_ptr != (char) 0) + { + int negate = FALSE; + int fixed_size = TRUE; + int input_no;; + + if (*buf_ptr == '+' || *buf_ptr == '-') + { + if (*buf_ptr == '-') + negate = TRUE; + fixed_size = FALSE; + buf_ptr++; + } + input_no = atoi (buf_ptr); + if (input_no > 0) + { + if (negate) + input_no *= (-1); + if (fixed_size) + new_height = input_no; + else + new_height = win_info->generic.height + input_no; + /* + ** Now change the window's height, and adjust all + ** other windows around it + */ + if (tui_adjust_win_heights (win_info, + new_height) == TUI_FAILURE) + warning ("Invalid window height specified.\n%s", + WIN_HEIGHT_USAGE); + else + tui_update_gdb_sizes (); + } + else + warning ("Invalid window height specified.\n%s", + WIN_HEIGHT_USAGE); + } + } + } + else + printf_filtered (WIN_HEIGHT_USAGE); + + if (buf != (char *) NULL) + xfree (buf); + } + else + printf_filtered (WIN_HEIGHT_USAGE); +} + +/* Set the height of the specified window, with va_list. */ +static void +tui_set_win_height_command (char *arg, int from_tty) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + tui_set_win_height (arg, from_tty); +} + + +/* XDB Compatibility command for setting the window height. This will + increase or decrease the command window by the specified amount. */ +static void +tui_xdb_set_win_height (char *arg, int from_tty) +{ + /* Make sure the curses mode is enabled. */ + tui_enable (); + if (arg != (char *) NULL) + { + int input_no = atoi (arg); + + if (input_no > 0) + { /* Add 1 for the locator */ + int new_height = tui_term_height () - (input_no + 1); + + if (!new_height_ok (tui_win_list[CMD_WIN], new_height) || + tui_adjust_win_heights (tui_win_list[CMD_WIN], + new_height) == TUI_FAILURE) + warning ("Invalid window height specified.\n%s", + XDBWIN_HEIGHT_USAGE); + } + else + warning ("Invalid window height specified.\n%s", + XDBWIN_HEIGHT_USAGE); + } + else + warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE); +} + +/* Set the height of the specified window, with va_list. */ +static void +tui_xdb_set_win_height_command (char *arg, int from_tty) +{ + tui_xdb_set_win_height (arg, from_tty); +} + + +/* Function to adjust all window heights around the primary. */ +static enum tui_status +tui_adjust_win_heights (struct tui_win_info * primary_win_info, int new_height) +{ + enum tui_status status = TUI_FAILURE; + + if (new_height_ok (primary_win_info, new_height)) + { + status = TUI_SUCCESS; + if (new_height != primary_win_info->generic.height) + { + int diff; + struct tui_win_info * win_info; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + enum tui_layout_type cur_layout = tui_current_layout (); + + diff = (new_height - primary_win_info->generic.height) * (-1); + if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND) + { + struct tui_win_info * src_win_info; + + make_invisible_and_set_new_height (primary_win_info, new_height); + if (primary_win_info->generic.type == CMD_WIN) + { + win_info = (struct tui_win_info *) (tui_source_windows ())->list[0]; + src_win_info = win_info; + } + else + { + win_info = tui_win_list[CMD_WIN]; + src_win_info = primary_win_info; + } + make_invisible_and_set_new_height (win_info, + win_info->generic.height + diff); + TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; + make_visible_with_new_height (win_info); + make_visible_with_new_height (primary_win_info); + if (src_win_info->generic.content_size <= 0) + tui_erase_source_content (src_win_info, EMPTY_SOURCE_PROMPT); + } + else + { + struct tui_win_info *first_win; + struct tui_win_info *second_win; + + if (cur_layout == SRC_DISASSEM_COMMAND) + { + first_win = TUI_SRC_WIN; + second_win = TUI_DISASM_WIN; + } + else + { + first_win = TUI_DATA_WIN; + second_win = (struct tui_win_info *) (tui_source_windows ())->list[0]; + } + if (primary_win_info == TUI_CMD_WIN) + { /* + ** Split the change in height accross the 1st & 2nd windows + ** adjusting them as well. + */ + int first_split_diff = diff / 2; /* subtract the locator */ + int second_split_diff = first_split_diff; + + if (diff % 2) + { + if (first_win->generic.height > + second_win->generic.height) + if (diff < 0) + first_split_diff--; + else + first_split_diff++; + else + { + if (diff < 0) + second_split_diff--; + else + second_split_diff++; + } + } + /* make sure that the minimum hieghts are honored */ + while ((first_win->generic.height + first_split_diff) < 3) + { + first_split_diff++; + second_split_diff--; + } + while ((second_win->generic.height + second_split_diff) < 3) + { + second_split_diff++; + first_split_diff--; + } + make_invisible_and_set_new_height ( + first_win, + first_win->generic.height + first_split_diff); + second_win->generic.origin.y = first_win->generic.height - 1; + make_invisible_and_set_new_height ( + second_win, second_win->generic.height + second_split_diff); + TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; + make_invisible_and_set_new_height (TUI_CMD_WIN, new_height); + } + else + { + if ((TUI_CMD_WIN->generic.height + diff) < 1) + { /* + ** If there is no way to increase the command window + ** take real estate from the 1st or 2nd window. + */ + if ((TUI_CMD_WIN->generic.height + diff) < 1) + { + int i; + for (i = TUI_CMD_WIN->generic.height + diff; + (i < 1); i++) + if (primary_win_info == first_win) + second_win->generic.height--; + else + first_win->generic.height--; + } + } + if (primary_win_info == first_win) + make_invisible_and_set_new_height (first_win, new_height); + else + make_invisible_and_set_new_height ( + first_win, + first_win->generic.height); + second_win->generic.origin.y = first_win->generic.height - 1; + if (primary_win_info == second_win) + make_invisible_and_set_new_height (second_win, new_height); + else + make_invisible_and_set_new_height ( + second_win, second_win->generic.height); + TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1; + if ((TUI_CMD_WIN->generic.height + diff) < 1) + make_invisible_and_set_new_height (TUI_CMD_WIN, 1); + else + make_invisible_and_set_new_height ( + TUI_CMD_WIN, TUI_CMD_WIN->generic.height + diff); + } + make_visible_with_new_height (TUI_CMD_WIN); + make_visible_with_new_height (second_win); + make_visible_with_new_height (first_win); + if (first_win->generic.content_size <= 0) + tui_erase_source_content (first_win, EMPTY_SOURCE_PROMPT); + if (second_win->generic.content_size <= 0) + tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT); + } + } + } + + return status; +} + + +/* Function make the target window (and auxillary windows associated + with the targer) invisible, and set the new height and location. */ +static void +make_invisible_and_set_new_height (struct tui_win_info * win_info, int height) +{ + int i; + struct tui_gen_win_info * gen_win_info; + + tui_make_invisible (&win_info->generic); + win_info->generic.height = height; + if (height > 1) + win_info->generic.viewport_height = height - 1; + else + win_info->generic.viewport_height = height; + if (win_info != TUI_CMD_WIN) + win_info->generic.viewport_height--; + + /* Now deal with the auxillary windows associated with win_info */ + switch (win_info->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + gen_win_info = win_info->detail.source_info.execution_info; + tui_make_invisible (gen_win_info); + gen_win_info->height = height; + gen_win_info->origin.y = win_info->generic.origin.y; + if (height > 1) + gen_win_info->viewport_height = height - 1; + else + gen_win_info->viewport_height = height; + if (win_info != TUI_CMD_WIN) + gen_win_info->viewport_height--; + + if (tui_win_has_locator (win_info)) + { + gen_win_info = tui_locator_win_info_ptr (); + tui_make_invisible (gen_win_info); + gen_win_info->origin.y = win_info->generic.origin.y + height; + } + break; + case DATA_WIN: + /* delete all data item windows */ + for (i = 0; i < win_info->generic.content_size; i++) + { + gen_win_info = (struct tui_gen_win_info *) & ((struct tui_win_element *) + win_info->generic.content[i])->which_element.data_window; + tui_delete_win (gen_win_info->handle); + gen_win_info->handle = (WINDOW *) NULL; + } + break; + default: + break; + } +} + + +/* Function to make the windows with new heights visible. This means + re-creating the windows' content since the window had to be + destroyed to be made invisible. */ +static void +make_visible_with_new_height (struct tui_win_info * win_info) +{ + struct symtab *s; + + tui_make_visible (&win_info->generic); + tui_check_and_display_highlight_if_needed (win_info); + switch (win_info->generic.type) + { + case SRC_WIN: + case DISASSEM_WIN: + tui_free_win_content (win_info->detail.source_info.execution_info); + tui_make_visible (win_info->detail.source_info.execution_info); + if (win_info->generic.content != NULL) + { + union tui_line_or_address line_or_addr; + struct symtab_and_line cursal + = get_current_source_symtab_and_line (); + + if (win_info->generic.type == SRC_WIN) + line_or_addr.line_no = + win_info->detail.source_info.start_line_or_addr.line_no; + else + line_or_addr.addr = + win_info->detail.source_info.start_line_or_addr.addr; + tui_free_win_content (&win_info->generic); + tui_update_source_window (win_info, cursal.symtab, line_or_addr, TRUE); + } + else if (deprecated_selected_frame != (struct frame_info *) NULL) + { + union tui_line_or_address line; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + if (win_info->generic.type == SRC_WIN) + line.line_no = cursal.line; + else + { + find_line_pc (s, cursal.line, &line.addr); + } + tui_update_source_window (win_info, s, line, TRUE); + } + if (tui_win_has_locator (win_info)) + { + tui_make_visible (tui_locator_win_info_ptr ()); + tui_show_locator_content (); + } + break; + case DATA_WIN: + tui_display_all_data (); + break; + case CMD_WIN: + win_info->detail.command_info.cur_line = 0; + win_info->detail.command_info.curch = 0; + wmove (win_info->generic.handle, + win_info->detail.command_info.cur_line, + win_info->detail.command_info.curch); + break; + default: + break; + } +} + + +static int +new_height_ok (struct tui_win_info * primary_win_info, int new_height) +{ + int ok = (new_height < tui_term_height ()); + + if (ok) + { + int diff; + enum tui_layout_type cur_layout = tui_current_layout (); + + diff = (new_height - primary_win_info->generic.height) * (-1); + if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND) + { + ok = ((primary_win_info->generic.type == CMD_WIN && + new_height <= (tui_term_height () - 4) && + new_height >= MIN_CMD_WIN_HEIGHT) || + (primary_win_info->generic.type != CMD_WIN && + new_height <= (tui_term_height () - 2) && + new_height >= MIN_WIN_HEIGHT)); + if (ok) + { /* check the total height */ + struct tui_win_info * win_info; + + if (primary_win_info == TUI_CMD_WIN) + win_info = (struct tui_win_info *) (tui_source_windows ())->list[0]; + else + win_info = TUI_CMD_WIN; + ok = ((new_height + + (win_info->generic.height + diff)) <= tui_term_height ()); + } + } + else + { + int cur_total_height, total_height, min_height = 0; + struct tui_win_info *first_win; + struct tui_win_info *second_win; + + if (cur_layout == SRC_DISASSEM_COMMAND) + { + first_win = TUI_SRC_WIN; + second_win = TUI_DISASM_WIN; + } + else + { + first_win = TUI_DATA_WIN; + second_win = (struct tui_win_info *) (tui_source_windows ())->list[0]; + } + /* + ** We could simply add all the heights to obtain the same result + ** but below is more explicit since we subtract 1 for the + ** line that the first and second windows share, and add one + ** for the locator. + */ + total_height = cur_total_height = + (first_win->generic.height + second_win->generic.height - 1) + + TUI_CMD_WIN->generic.height + 1 /*locator */ ; + if (primary_win_info == TUI_CMD_WIN) + { + /* locator included since first & second win share a line */ + ok = ((first_win->generic.height + + second_win->generic.height + diff) >= + (MIN_WIN_HEIGHT * 2) && + new_height >= MIN_CMD_WIN_HEIGHT); + if (ok) + { + total_height = new_height + (first_win->generic.height + + second_win->generic.height + diff); + min_height = MIN_CMD_WIN_HEIGHT; + } + } + else + { + min_height = MIN_WIN_HEIGHT; + /* + ** First see if we can increase/decrease the command + ** window. And make sure that the command window is + ** at least 1 line + */ + ok = ((TUI_CMD_WIN->generic.height + diff) > 0); + if (!ok) + { /* + ** Looks like we have to increase/decrease one of + ** the other windows + */ + if (primary_win_info == first_win) + ok = (second_win->generic.height + diff) >= min_height; + else + ok = (first_win->generic.height + diff) >= min_height; + } + if (ok) + { + if (primary_win_info == first_win) + total_height = new_height + + second_win->generic.height + + TUI_CMD_WIN->generic.height + diff; + else + total_height = new_height + + first_win->generic.height + + TUI_CMD_WIN->generic.height + diff; + } + } + /* + ** Now make sure that the proposed total height doesn't exceed + ** the old total height. + */ + if (ok) + ok = (new_height >= min_height && total_height <= cur_total_height); + } + } + + return ok; +} + + +static void +parse_scrolling_args (char *arg, struct tui_win_info * * win_to_scroll, + int *num_to_scroll) +{ + if (num_to_scroll) + *num_to_scroll = 0; + *win_to_scroll = tui_win_with_focus (); + + /* + ** First set up the default window to scroll, in case there is no + ** window name arg + */ + if (arg != (char *) NULL) + { + char *buf, *buf_ptr; + + /* process the number of lines to scroll */ + buf = buf_ptr = xstrdup (arg); + if (isdigit (*buf_ptr)) + { + char *num_str; + + num_str = buf_ptr; + buf_ptr = strchr (buf_ptr, ' '); + if (buf_ptr != (char *) NULL) + { + *buf_ptr = (char) 0; + if (num_to_scroll) + *num_to_scroll = atoi (num_str); + buf_ptr++; + } + else if (num_to_scroll) + *num_to_scroll = atoi (num_str); + } + + /* process the window name if one is specified */ + if (buf_ptr != (char *) NULL) + { + char *wname; + int i; + + if (*buf_ptr == ' ') + while (*(++buf_ptr) == ' ') + ; + + if (*buf_ptr != (char) 0) + wname = buf_ptr; + else + wname = "?"; + + /* Validate the window name */ + for (i = 0; i < strlen (wname); i++) + wname[i] = toupper (wname[i]); + *win_to_scroll = tui_partial_win_by_name (wname); + + if (*win_to_scroll == (struct tui_win_info *) NULL || + !(*win_to_scroll)->generic.is_visible) + warning ("Invalid window specified. \n\ +The window name specified must be valid and visible.\n"); + else if (*win_to_scroll == TUI_CMD_WIN) + *win_to_scroll = (struct tui_win_info *) (tui_source_windows ())->list[0]; + } + xfree (buf); + } +} diff --git a/contrib/gdb/gdb/tui/tui-win.h b/contrib/gdb/gdb/tui/tui-win.h new file mode 100644 index 00000000000..1e9b86f441c --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-win.h @@ -0,0 +1,59 @@ +/* TUI window generic functions. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_WIN_H +#define TUI_WIN_H + +#include "tui/tui-data.h" + +struct tui_win_info; + +extern void tui_scroll_forward (struct tui_win_info *, int); +extern void tui_scroll_backward (struct tui_win_info *, int); +extern void tui_scroll_left (struct tui_win_info *, int); +extern void tui_scroll_right (struct tui_win_info *, int); +extern void tui_scroll (enum tui_scroll_direction, struct tui_win_info *, int); +extern void tui_set_win_focus_to (struct tui_win_info *); +extern void tui_resize_all (void); +extern void tui_refresh_all_win (void); +extern void tui_sigwinch_handler (int); + +extern chtype tui_border_ulcorner; +extern chtype tui_border_urcorner; +extern chtype tui_border_lrcorner; +extern chtype tui_border_llcorner; +extern chtype tui_border_vline; +extern chtype tui_border_hline; +extern int tui_border_attrs; +extern int tui_active_border_attrs; + +extern int tui_update_variables (void); + +/* Update gdb's knowledge of the terminal size. */ +extern void tui_update_gdb_sizes (void); + +/* Create or get the TUI command list. */ +struct cmd_list_element **tui_get_cmd_list (); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-windata.c b/contrib/gdb/gdb/tui/tui-windata.c new file mode 100644 index 00000000000..3c98cf60d68 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-windata.c @@ -0,0 +1,304 @@ +/* Data/register window display. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-regs.h" + +#include "gdb_string.h" +#include "gdb_curses.h" + + +/***************************************** +** STATIC LOCAL FUNCTIONS FORWARD DECLS ** +******************************************/ + + + +/***************************************** +** PUBLIC FUNCTIONS ** +******************************************/ + + +/* Answer the index first element displayed. If none are displayed, + then return (-1). */ +int +tui_first_data_item_displayed (void) +{ + int element_no = (-1); + int i; + + for (i = 0; (i < TUI_DATA_WIN->generic.content_size && element_no < 0); i++) + { + struct tui_gen_win_info * data_item_win; + + data_item_win = &((tui_win_content) + TUI_DATA_WIN->generic.content)[i]->which_element.data_window; + if (data_item_win->handle != (WINDOW *) NULL && data_item_win->is_visible) + element_no = i; + } + + return element_no; +} + + +/* Answer the index of the first element in line_no. If line_no is + past the data area (-1) is returned. */ +int +tui_first_data_element_no_in_line (int line_no) +{ + int first_element_no = (-1); + + /* + ** First see if there is a register on line_no, and if so, set the + ** first element number + */ + if ((first_element_no = tui_first_reg_element_no_inline (line_no)) == -1) + { /* + ** Looking at the general data, the 1st element on line_no + */ + } + + return first_element_no; +} + + +/* Function to delete all the item windows in the data window. This + is usually done when the data window is scrolled. */ +void +tui_delete_data_content_windows (void) +{ + int i; + struct tui_gen_win_info * data_item_win_ptr; + + for (i = 0; (i < TUI_DATA_WIN->generic.content_size); i++) + { + data_item_win_ptr = &((tui_win_content) + TUI_DATA_WIN->generic.content)[i]->which_element.data_window; + tui_delete_win (data_item_win_ptr->handle); + data_item_win_ptr->handle = (WINDOW *) NULL; + data_item_win_ptr->is_visible = FALSE; + } +} + + +void +tui_erase_data_content (char *prompt) +{ + werase (TUI_DATA_WIN->generic.handle); + tui_check_and_display_highlight_if_needed (TUI_DATA_WIN); + if (prompt != (char *) NULL) + { + int half_width = (TUI_DATA_WIN->generic.width - 2) / 2; + int x_pos; + + if (strlen (prompt) >= half_width) + x_pos = 1; + else + x_pos = half_width - strlen (prompt); + mvwaddstr (TUI_DATA_WIN->generic.handle, + (TUI_DATA_WIN->generic.height / 2), + x_pos, + prompt); + } + wrefresh (TUI_DATA_WIN->generic.handle); +} + + +/* This function displays the data that is in the data window's + content. It does not set the content. */ +void +tui_display_all_data (void) +{ + if (TUI_DATA_WIN->generic.content_size <= 0) + tui_erase_data_content (NO_DATA_STRING); + else + { + tui_erase_data_content ((char *) NULL); + tui_delete_data_content_windows (); + tui_check_and_display_highlight_if_needed (TUI_DATA_WIN); + tui_display_registers_from (0); + /* + ** Then display the other data + */ + if (TUI_DATA_WIN->detail.data_display_info.data_content != + (tui_win_content) NULL && + TUI_DATA_WIN->detail.data_display_info.data_content_count > 0) + { + } + } +} + + +/* Function to display the data starting at line, line_no, in the data + window. */ +void +tui_display_data_from_line (int line_no) +{ + int _line_no = line_no; + + if (line_no < 0) + _line_no = 0; + + tui_check_and_display_highlight_if_needed (TUI_DATA_WIN); + + /* there is no general data, force regs to display (if there are any) */ + if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0) + tui_display_registers_from_line (_line_no, TRUE); + else + { + int element_no, start_line_no; + int regs_last_line = tui_last_regs_line_no (); + + + /* display regs if we can */ + if (tui_display_registers_from_line (_line_no, FALSE) < 0) + { /* + ** _line_no is past the regs display, so calc where the + ** start data element is + */ + if (regs_last_line < _line_no) + { /* figure out how many lines each element is to obtain + the start element_no */ + } + } + else + { /* + ** calculate the starting element of the data display, given + ** regs_last_line and how many lines each element is, up to + ** _line_no + */ + } + /* Now display the data , starting at element_no */ + } +} + + +/* Display data starting at element element_no. */ +void +tui_display_data_from (int element_no, int reuse_windows) +{ + int first_line = (-1); + + if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) + first_line = tui_line_from_reg_element_no (element_no); + else + { /* calculate the first_line from the element number */ + } + + if (first_line >= 0) + { + tui_erase_data_content ((char *) NULL); + if (!reuse_windows) + tui_delete_data_content_windows (); + tui_display_data_from_line (first_line); + } +} + + +/* Function to redisplay the contents of the data window. */ +void +tui_refresh_data_win (void) +{ + tui_erase_data_content ((char *) NULL); + if (TUI_DATA_WIN->generic.content_size > 0) + { + int first_element = tui_first_data_item_displayed (); + + if (first_element >= 0) /* re-use existing windows */ + tui_display_data_from (first_element, TRUE); + } +} + + +/* Function to check the data values and hilite any that have changed. */ +void +tui_check_data_values (struct frame_info *frame) +{ + tui_check_register_values (frame); + + /* Now check any other data values that there are */ + if (TUI_DATA_WIN != NULL && TUI_DATA_WIN->generic.is_visible) + { + int i; + + for (i = 0; TUI_DATA_WIN->detail.data_display_info.data_content_count; i++) + { +#ifdef LATER + tui_data_element_ptr data_element_ptr; + struct tui_gen_win_info * data_item_win_ptr; + Opaque new_value; + + data_item_ptr = &TUI_DATA_WIN->detail.data_display_info. + data_content[i]->which_element.data_window; + data_element_ptr = &((tui_win_content) + data_item_win_ptr->content)[0]->which_element.data; + if value + has changed (data_element_ptr, frame, &new_value) + { + data_element_ptr->value = new_value; + update the display with the new value, hiliting it. + } +#endif + } + } +} + + +/* Scroll the data window vertically forward or backward. */ +void +tui_vertical_data_scroll (enum tui_scroll_direction scroll_direction, int num_to_scroll) +{ + int first_element_no; + int first_line = (-1); + + first_element_no = tui_first_data_item_displayed (); + if (first_element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) + first_line = tui_line_from_reg_element_no (first_element_no); + else + { /* calculate the first line from the element number which is in + ** the general data content + */ + } + + if (first_line >= 0) + { + int last_element_no, last_line; + + if (scroll_direction == FORWARD_SCROLL) + first_line += num_to_scroll; + else + first_line -= num_to_scroll; + tui_erase_data_content ((char *) NULL); + tui_delete_data_content_windows (); + tui_display_data_from_line (first_line); + } +} + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ diff --git a/contrib/gdb/gdb/tui/tui-windata.h b/contrib/gdb/gdb/tui/tui-windata.h new file mode 100644 index 00000000000..10123a3fad9 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-windata.h @@ -0,0 +1,41 @@ +/* Data/register window display. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_WINDATA_H +#define TUI_WINDATA_H + +#include "tui/tui-data.h" + +extern void tui_erase_data_content (char *); +extern void tui_display_all_data (void); +extern void tui_check_data_values (struct frame_info *); +extern void tui_display_data_from_line (int); +extern int tui_first_data_item_displayed (void); +extern int tui_first_data_element_no_in_line (int); +extern void tui_delete_data_content_windows (void); +extern void tui_refresh_data_win (void); +extern void tui_display_data_from (int, int); +extern void tui_vertical_data_scroll (enum tui_scroll_direction, int); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-wingeneral.c b/contrib/gdb/gdb/tui/tui-wingeneral.c new file mode 100644 index 00000000000..3dc62d5d508 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-wingeneral.c @@ -0,0 +1,276 @@ +/* General window behavior. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-win.h" + +#include "gdb_curses.h" + +/*********************** +** PUBLIC FUNCTIONS +***********************/ + +/* Refresh the window. */ +void +tui_refresh_win (struct tui_gen_win_info * win_info) +{ + if (win_info->type == DATA_WIN && win_info->content_size > 0) + { + int i; + + for (i = 0; (i < win_info->content_size); i++) + { + struct tui_gen_win_info * data_item_win_ptr; + + data_item_win_ptr = &((tui_win_content) + win_info->content)[i]->which_element.data_window; + if (data_item_win_ptr != NULL + && data_item_win_ptr->handle != (WINDOW *) NULL) + wrefresh (data_item_win_ptr->handle); + } + } + else if (win_info->type == CMD_WIN) + { + /* Do nothing */ + } + else + { + if (win_info->handle != (WINDOW *) NULL) + wrefresh (win_info->handle); + } + + return; +} + + +/* Function to delete the curses window, checking for NULL. */ +void +tui_delete_win (WINDOW * window) +{ + if (window != (WINDOW *) NULL) + delwin (window); + + return; +} + + +/* Draw a border arround the window. */ +void +box_win (struct tui_gen_win_info * win_info, int highlight_flag) +{ + if (win_info && win_info->handle) + { + WINDOW *win; + int attrs; + + win = win_info->handle; + if (highlight_flag == HILITE) + attrs = tui_active_border_attrs; + else + attrs = tui_border_attrs; + + wattron (win, attrs); + wborder (win, tui_border_vline, tui_border_vline, + tui_border_hline, tui_border_hline, + tui_border_ulcorner, tui_border_urcorner, + tui_border_llcorner, tui_border_lrcorner); + if (win_info->title) + mvwaddstr (win, 0, 3, win_info->title); + wattroff (win, attrs); + } +} + + +void +tui_unhighlight_win (struct tui_win_info * win_info) +{ + if (win_info != NULL && win_info->generic.handle != (WINDOW *) NULL) + { + box_win ((struct tui_gen_win_info *) win_info, NO_HILITE); + wrefresh (win_info->generic.handle); + tui_set_win_highlight (win_info, 0); + } +} + + +void +tui_highlight_win (struct tui_win_info * win_info) +{ + if (win_info != NULL + && win_info->can_highlight + && win_info->generic.handle != (WINDOW *) NULL) + { + box_win ((struct tui_gen_win_info *) win_info, HILITE); + wrefresh (win_info->generic.handle); + tui_set_win_highlight (win_info, 1); + } +} + +void +tui_check_and_display_highlight_if_needed (struct tui_win_info * win_info) +{ + if (win_info != NULL && win_info->generic.type != CMD_WIN) + { + if (win_info->is_highlighted) + tui_highlight_win (win_info); + else + tui_unhighlight_win (win_info); + + } + return; +} + + +void +tui_make_window (struct tui_gen_win_info * win_info, int box_it) +{ + WINDOW *handle; + + handle = newwin (win_info->height, + win_info->width, + win_info->origin.y, + win_info->origin.x); + win_info->handle = handle; + if (handle != (WINDOW *) NULL) + { + if (box_it == BOX_WINDOW) + box_win (win_info, NO_HILITE); + win_info->is_visible = TRUE; + scrollok (handle, TRUE); + } +} + + +/* We can't really make windows visible, or invisible. So we have to + delete the entire window when making it visible, and create it + again when making it visible. */ +static void +make_visible (struct tui_gen_win_info *win_info, int visible) +{ + /* Don't tear down/recreate command window */ + if (win_info->type == CMD_WIN) + return; + + if (visible) + { + if (!win_info->is_visible) + { + tui_make_window (win_info, + (win_info->type != CMD_WIN + && !tui_win_is_auxillary (win_info->type))); + win_info->is_visible = TRUE; + } + } + else if (!visible && + win_info->is_visible && win_info->handle != (WINDOW *) NULL) + { + win_info->is_visible = FALSE; + tui_delete_win (win_info->handle); + win_info->handle = (WINDOW *) NULL; + } + + return; +} + +void +tui_make_visible (struct tui_gen_win_info *win_info) +{ + make_visible (win_info, 1); +} + +void +tui_make_invisible (struct tui_gen_win_info *win_info) +{ + make_visible (win_info, 0); +} + + +/* Makes all windows invisible (except the command and locator windows). */ +static void +make_all_visible (int visible) +{ + int i; + + for (i = 0; i < MAX_MAJOR_WINDOWS; i++) + { + if (tui_win_list[i] != NULL + && ((tui_win_list[i])->generic.type) != CMD_WIN) + { + if (tui_win_is_source_type ((tui_win_list[i])->generic.type)) + make_visible ((tui_win_list[i])->detail.source_info.execution_info, + visible); + make_visible ((struct tui_gen_win_info *) tui_win_list[i], visible); + } + } + + return; +} + +void +tui_make_all_visible (void) +{ + make_all_visible (1); +} + +void +tui_make_all_invisible (void) +{ + make_all_visible (0); +} + +/* Function to refresh all the windows currently displayed. */ + +void +tui_refresh_all (struct tui_win_info * * list) +{ + enum tui_win_type type; + struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); + + for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++) + { + if (list[type] && list[type]->generic.is_visible) + { + if (type == SRC_WIN || type == DISASSEM_WIN) + { + touchwin (list[type]->detail.source_info.execution_info->handle); + tui_refresh_win (list[type]->detail.source_info.execution_info); + } + touchwin (list[type]->generic.handle); + tui_refresh_win (&list[type]->generic); + } + } + if (locator->is_visible) + { + touchwin (locator->handle); + tui_refresh_win (locator); + } +} + + +/********************************* +** Local Static Functions +*********************************/ diff --git a/contrib/gdb/gdb/tui/tui-wingeneral.h b/contrib/gdb/gdb/tui/tui-wingeneral.h new file mode 100644 index 00000000000..306d79402c0 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-wingeneral.h @@ -0,0 +1,45 @@ +/* General window behavior. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_WINGENERAL_H +#define TUI_WINGENERAL_H + +struct tui_win_info; +struct tui_gen_win_info; + +extern void tui_unhighlight_win (struct tui_win_info *); +extern void tui_make_visible (struct tui_gen_win_info *); +extern void tui_make_invisible (struct tui_gen_win_info *); +extern void tui_make_all_visible (void); +extern void tui_make_all_invisible (void); +extern void tui_make_window (struct tui_gen_win_info *, int); +extern struct tui_win_info *tui_copy_win (struct tui_win_info *); +extern void tui_box_win (struct tui_gen_win_info *, int); +extern void tui_highlight_win (struct tui_win_info *); +extern void tui_check_and_display_highlight_if_needed (struct tui_win_info *); +extern void tui_refresh_all (struct tui_win_info **); +extern void tui_delete_win (WINDOW * window); +extern void tui_refresh_win (struct tui_gen_win_info *); + +#endif diff --git a/contrib/gdb/gdb/tui/tui-winsource.c b/contrib/gdb/gdb/tui/tui-winsource.c new file mode 100644 index 00000000000..de19d25c239 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-winsource.c @@ -0,0 +1,654 @@ +/* TUI display source/assembly window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include +#include "symtab.h" +#include "frame.h" +#include "breakpoint.h" +#include "value.h" +#include "source.h" + +#include "tui/tui.h" +#include "tui/tui-data.h" +#include "tui/tui-stack.h" +#include "tui/tui-win.h" +#include "tui/tui-wingeneral.h" +#include "tui/tui-winsource.h" +#include "tui/tui-source.h" +#include "tui/tui-disasm.h" + +#include "gdb_string.h" +#include "gdb_curses.h" + +/* Function to display the "main" routine. */ +void +tui_display_main (void) +{ + if ((tui_source_windows ())->count > 0) + { + CORE_ADDR addr; + + addr = tui_get_begin_asm_address (); + if (addr != (CORE_ADDR) 0) + { + struct symtab_and_line sal; + + tui_update_source_windows_with_addr (addr); + sal = find_pc_line (addr, 0); + if (sal.symtab) + tui_update_locator_filename (sal.symtab->filename); + else + tui_update_locator_filename ("??"); + } + } +} + + + +/* Function to display source in the source window. This function + initializes the horizontal scroll to 0. */ +void +tui_update_source_window (struct tui_win_info * win_info, struct symtab *s, + union tui_line_or_address line_or_addr, int noerror) +{ + win_info->detail.source_info.horizontal_offset = 0; + tui_update_source_window_as_is (win_info, s, line_or_addr, noerror); + + return; +} + + +/* Function to display source in the source/asm window. This function + shows the source as specified by the horizontal offset. */ +void +tui_update_source_window_as_is (struct tui_win_info * win_info, struct symtab *s, + union tui_line_or_address line_or_addr, int noerror) +{ + enum tui_status ret; + + if (win_info->generic.type == SRC_WIN) + ret = tui_set_source_content (s, line_or_addr.line_no, noerror); + else + ret = tui_set_disassem_content (line_or_addr.addr); + + if (ret == TUI_FAILURE) + { + tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT); + tui_clear_exec_info_content (win_info); + } + else + { + tui_update_breakpoint_info (win_info, 0); + tui_show_source_content (win_info); + tui_update_exec_info (win_info); + if (win_info->generic.type == SRC_WIN) + { + struct symtab_and_line sal; + + sal.line = line_or_addr.line_no + + (win_info->generic.content_size - 2); + sal.symtab = s; + set_current_source_symtab_and_line (&sal); + /* + ** If the focus was in the asm win, put it in the src + ** win if we don't have a split layout + */ + if (tui_win_with_focus () == TUI_DISASM_WIN && + tui_current_layout () != SRC_DISASSEM_COMMAND) + tui_set_win_focus_to (TUI_SRC_WIN); + } + } + + + return; +} + + +/* Function to ensure that the source and/or disassemly windows + reflect the input address. */ +void +tui_update_source_windows_with_addr (CORE_ADDR addr) +{ + if (addr != 0) + { + struct symtab_and_line sal; + union tui_line_or_address l; + + switch (tui_current_layout ()) + { + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + tui_show_disassem (addr); + break; + case SRC_DISASSEM_COMMAND: + tui_show_disassem_and_update_source (addr); + break; + default: + sal = find_pc_line (addr, 0); + l.line_no = sal.line; + tui_show_symtab_source (sal.symtab, l, FALSE); + break; + } + } + else + { + int i; + + for (i = 0; i < (tui_source_windows ())->count; i++) + { + struct tui_win_info * win_info = (struct tui_win_info *) (tui_source_windows ())->list[i]; + + tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT); + tui_clear_exec_info_content (win_info); + } + } +} + +/* Function to ensure that the source and/or disassemly windows + reflect the input address. */ +void +tui_update_source_windows_with_line (struct symtab *s, int line) +{ + CORE_ADDR pc; + union tui_line_or_address l; + + switch (tui_current_layout ()) + { + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + find_line_pc (s, line, &pc); + tui_update_source_windows_with_addr (pc); + break; + default: + l.line_no = line; + tui_show_symtab_source (s, l, FALSE); + if (tui_current_layout () == SRC_DISASSEM_COMMAND) + { + find_line_pc (s, line, &pc); + tui_show_disassem (pc); + } + break; + } + + return; +} + +void +tui_clear_source_content (struct tui_win_info * win_info, int display_prompt) +{ + if (win_info != NULL) + { + int i; + + win_info->generic.content_in_use = FALSE; + tui_erase_source_content (win_info, display_prompt); + for (i = 0; i < win_info->generic.content_size; i++) + { + struct tui_win_element * element = + (struct tui_win_element *) win_info->generic.content[i]; + element->which_element.source.has_break = FALSE; + element->which_element.source.is_exec_point = FALSE; + } + } +} + + +void +tui_erase_source_content (struct tui_win_info * win_info, int display_prompt) +{ + int x_pos; + int half_width = (win_info->generic.width - 2) / 2; + + if (win_info->generic.handle != (WINDOW *) NULL) + { + werase (win_info->generic.handle); + tui_check_and_display_highlight_if_needed (win_info); + if (display_prompt == EMPTY_SOURCE_PROMPT) + { + char *no_src_str; + + if (win_info->generic.type == SRC_WIN) + no_src_str = NO_SRC_STRING; + else + no_src_str = NO_DISASSEM_STRING; + if (strlen (no_src_str) >= half_width) + x_pos = 1; + else + x_pos = half_width - strlen (no_src_str); + mvwaddstr (win_info->generic.handle, + (win_info->generic.height / 2), + x_pos, + no_src_str); + + /* elz: added this function call to set the real contents of + the window to what is on the screen, so that later calls + to refresh, do display + the correct stuff, and not the old image */ + + tui_set_source_content_nil (win_info, no_src_str); + } + tui_refresh_win (&win_info->generic); + } +} + + +/* Redraw the complete line of a source or disassembly window. */ +static void +tui_show_source_line (struct tui_win_info * win_info, int lineno) +{ + struct tui_win_element * line; + int x, y; + + line = (struct tui_win_element *) win_info->generic.content[lineno - 1]; + if (line->which_element.source.is_exec_point) + wattron (win_info->generic.handle, A_STANDOUT); + + mvwaddstr (win_info->generic.handle, lineno, 1, + line->which_element.source.line); + if (line->which_element.source.is_exec_point) + wattroff (win_info->generic.handle, A_STANDOUT); + + /* Clear to end of line but stop before the border. */ + getyx (win_info->generic.handle, y, x); + while (x + 1 < win_info->generic.width) + { + waddch (win_info->generic.handle, ' '); + getyx (win_info->generic.handle, y, x); + } +} + +void +tui_show_source_content (struct tui_win_info * win_info) +{ + if (win_info->generic.content_size > 0) + { + int lineno; + + for (lineno = 1; lineno <= win_info->generic.content_size; lineno++) + tui_show_source_line (win_info, lineno); + } + else + tui_erase_source_content (win_info, TRUE); + + tui_check_and_display_highlight_if_needed (win_info); + tui_refresh_win (&win_info->generic); + win_info->generic.content_in_use = TRUE; +} + + +/* Scroll the source forward or backward horizontally. */ +void +tui_horizontal_source_scroll (struct tui_win_info * win_info, + enum tui_scroll_direction direction, + int num_to_scroll) +{ + if (win_info->generic.content != NULL) + { + int offset; + struct symtab *s; + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + + if (cursal.symtab == (struct symtab *) NULL) + s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); + else + s = cursal.symtab; + + if (direction == LEFT_SCROLL) + offset = win_info->detail.source_info.horizontal_offset + num_to_scroll; + else + { + if ((offset = + win_info->detail.source_info.horizontal_offset - num_to_scroll) < 0) + offset = 0; + } + win_info->detail.source_info.horizontal_offset = offset; + tui_update_source_window_as_is (win_info, s, + ((struct tui_win_element *) + win_info->generic.content[0])->which_element.source.line_or_addr, + FALSE); + } + + return; +} + + +/* Set or clear the has_break flag in the line whose line is line_no. */ +void +tui_set_is_exec_point_at (union tui_line_or_address l, struct tui_win_info * win_info) +{ + int changed = 0; + int i; + tui_win_content content = (tui_win_content) win_info->generic.content; + + i = 0; + while (i < win_info->generic.content_size) + { + int new_state; + + if (content[i]->which_element.source.line_or_addr.addr == l.addr) + new_state = TRUE; + else + new_state = FALSE; + if (new_state != content[i]->which_element.source.is_exec_point) + { + changed++; + content[i]->which_element.source.is_exec_point = new_state; + tui_show_source_line (win_info, i + 1); + } + i++; + } + if (changed) + tui_refresh_win (&win_info->generic); +} + +/* Update the execution windows to show the active breakpoints. + This is called whenever a breakpoint is inserted, removed or + has its state changed. */ +void +tui_update_all_breakpoint_info (void) +{ + struct tui_list *list = tui_source_windows (); + int i; + + for (i = 0; i < list->count; i++) + { + struct tui_win_info * win = (struct tui_win_info *) list->list[i]; + + if (tui_update_breakpoint_info (win, FALSE)) + { + tui_update_exec_info (win); + } + } +} + + +/* Scan the source window and the breakpoints to update the + has_break information for each line. + Returns 1 if something changed and the execution window + must be refreshed. */ +int +tui_update_breakpoint_info (struct tui_win_info * win, int current_only) +{ + int i; + int need_refresh = 0; + struct tui_source_info * src = &win->detail.source_info; + + for (i = 0; i < win->generic.content_size; i++) + { + struct breakpoint *bp; + extern struct breakpoint *breakpoint_chain; + int mode; + struct tui_source_element* line; + + line = &((struct tui_win_element *) win->generic.content[i])->which_element.source; + if (current_only && !line->is_exec_point) + continue; + + /* Scan each breakpoint to see if the current line has something to + do with it. Identify enable/disabled breakpoints as well as + those that we already hit. */ + mode = 0; + for (bp = breakpoint_chain; + bp != (struct breakpoint *) NULL; + bp = bp->next) + { + if ((win == TUI_SRC_WIN + && bp->source_file + && (strcmp (src->filename, bp->source_file) == 0) + && bp->line_number == line->line_or_addr.line_no) + || (win == TUI_DISASM_WIN + && bp->loc->address == line->line_or_addr.addr)) + { + if (bp->enable_state == bp_disabled) + mode |= TUI_BP_DISABLED; + else + mode |= TUI_BP_ENABLED; + if (bp->hit_count) + mode |= TUI_BP_HIT; + if (bp->cond) + mode |= TUI_BP_CONDITIONAL; + if (bp->type == bp_hardware_breakpoint) + mode |= TUI_BP_HARDWARE; + } + } + if (line->has_break != mode) + { + line->has_break = mode; + need_refresh = 1; + } + } + return need_refresh; +} + + +/* Function to initialize the content of the execution info window, + based upon the input window which is either the source or + disassembly window. */ +enum tui_status +tui_set_exec_info_content (struct tui_win_info * win_info) +{ + enum tui_status ret = TUI_SUCCESS; + + if (win_info->detail.source_info.execution_info != (struct tui_gen_win_info *) NULL) + { + struct tui_gen_win_info * exec_info_ptr = win_info->detail.source_info.execution_info; + + if (exec_info_ptr->content == NULL) + exec_info_ptr->content = + (void **) tui_alloc_content (win_info->generic.height, + exec_info_ptr->type); + if (exec_info_ptr->content != NULL) + { + int i; + + tui_update_breakpoint_info (win_info, 1); + for (i = 0; i < win_info->generic.content_size; i++) + { + struct tui_win_element * element; + struct tui_win_element * src_element; + int mode; + + element = (struct tui_win_element *) exec_info_ptr->content[i]; + src_element = (struct tui_win_element *) win_info->generic.content[i]; + + memset(element->which_element.simple_string, ' ', + sizeof(element->which_element.simple_string)); + element->which_element.simple_string[TUI_EXECINFO_SIZE - 1] = 0; + + /* Now update the exec info content based upon the state + of each line as indicated by the source content. */ + mode = src_element->which_element.source.has_break; + if (mode & TUI_BP_HIT) + element->which_element.simple_string[TUI_BP_HIT_POS] = + (mode & TUI_BP_HARDWARE) ? 'H' : 'B'; + else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED)) + element->which_element.simple_string[TUI_BP_HIT_POS] = + (mode & TUI_BP_HARDWARE) ? 'h' : 'b'; + + if (mode & TUI_BP_ENABLED) + element->which_element.simple_string[TUI_BP_BREAK_POS] = '+'; + else if (mode & TUI_BP_DISABLED) + element->which_element.simple_string[TUI_BP_BREAK_POS] = '-'; + + if (src_element->which_element.source.is_exec_point) + element->which_element.simple_string[TUI_EXEC_POS] = '>'; + } + exec_info_ptr->content_size = win_info->generic.content_size; + } + else + ret = TUI_FAILURE; + } + + return ret; +} + + +void +tui_show_exec_info_content (struct tui_win_info * win_info) +{ + struct tui_gen_win_info * exec_info = win_info->detail.source_info.execution_info; + int cur_line; + + werase (exec_info->handle); + tui_refresh_win (exec_info); + for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++) + mvwaddstr (exec_info->handle, + cur_line, + 0, + ((struct tui_win_element *) + exec_info->content[cur_line - 1])->which_element.simple_string); + tui_refresh_win (exec_info); + exec_info->content_in_use = TRUE; +} + + +void +tui_erase_exec_info_content (struct tui_win_info * win_info) +{ + struct tui_gen_win_info * exec_info = win_info->detail.source_info.execution_info; + + werase (exec_info->handle); + tui_refresh_win (exec_info); +} + +void +tui_clear_exec_info_content (struct tui_win_info * win_info) +{ + win_info->detail.source_info.execution_info->content_in_use = FALSE; + tui_erase_exec_info_content (win_info); + + return; +} + +/* Function to update the execution info window. */ +void +tui_update_exec_info (struct tui_win_info * win_info) +{ + tui_set_exec_info_content (win_info); + tui_show_exec_info_content (win_info); +} + +enum tui_status +tui_alloc_source_buffer (struct tui_win_info *win_info) +{ + char *src_line_buf; + int i, line_width, max_lines; + enum tui_status ret = TUI_FAILURE; + + max_lines = win_info->generic.height; /* less the highlight box */ + line_width = win_info->generic.width - 1; + /* + ** Allocate the buffer for the source lines. Do this only once since they + ** will be re-used for all source displays. The only other time this will + ** be done is when a window's size changes. + */ + if (win_info->generic.content == NULL) + { + src_line_buf = (char *) xmalloc ((max_lines * line_width) * sizeof (char)); + if (src_line_buf == (char *) NULL) + fputs_unfiltered ( + "Unable to Allocate Memory for Source or Disassembly Display.\n", + gdb_stderr); + else + { + /* allocate the content list */ + if ((win_info->generic.content = + (void **) tui_alloc_content (max_lines, SRC_WIN)) == NULL) + { + xfree (src_line_buf); + src_line_buf = (char *) NULL; + fputs_unfiltered ( + "Unable to Allocate Memory for Source or Disassembly Display.\n", + gdb_stderr); + } + } + for (i = 0; i < max_lines; i++) + ((struct tui_win_element *) + win_info->generic.content[i])->which_element.source.line = + src_line_buf + (line_width * i); + ret = TUI_SUCCESS; + } + else + ret = TUI_SUCCESS; + + return ret; +} + + +/* Answer whether the a particular line number or address is displayed + in the current source window. */ +int +tui_line_is_displayed (int line, struct tui_win_info * win_info, + int check_threshold) +{ + int is_displayed = FALSE; + int i, threshold; + + if (check_threshold) + threshold = SCROLL_THRESHOLD; + else + threshold = 0; + i = 0; + while (i < win_info->generic.content_size - threshold && !is_displayed) + { + is_displayed = (((struct tui_win_element *) + win_info->generic.content[i])->which_element.source.line_or_addr.line_no + == (int) line); + i++; + } + + return is_displayed; +} + + +/* Answer whether the a particular line number or address is displayed + in the current source window. */ +int +tui_addr_is_displayed (CORE_ADDR addr, struct tui_win_info * win_info, + int check_threshold) +{ + int is_displayed = FALSE; + int i, threshold; + + if (check_threshold) + threshold = SCROLL_THRESHOLD; + else + threshold = 0; + i = 0; + while (i < win_info->generic.content_size - threshold && !is_displayed) + { + is_displayed = (((struct tui_win_element *) + win_info->generic.content[i])->which_element.source.line_or_addr.addr + == addr); + i++; + } + + return is_displayed; +} + + +/***************************************** +** STATIC LOCAL FUNCTIONS ** +******************************************/ diff --git a/contrib/gdb/gdb/tui/tui-winsource.h b/contrib/gdb/gdb/tui/tui-winsource.h new file mode 100644 index 00000000000..e64589ba5f2 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui-winsource.h @@ -0,0 +1,73 @@ +/* TUI display source/assembly window. + + Copyright 1998, 1999, 2000, 2001, 2002, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_SOURCEWIN_H +#define TUI_SOURCEWIN_H + +#include "tui/tui-data.h" + +struct tui_win_info; + +/* Update the execution windows to show the active breakpoints. This + is called whenever a breakpoint is inserted, removed or has its + state changed. */ +extern void tui_update_all_breakpoint_info (void); + +/* Scan the source window and the breakpoints to update the hasBreak + information for each line. Returns 1 if something changed and the + execution window must be refreshed. */ +extern int tui_update_breakpoint_info (struct tui_win_info * win, + int current_only); + +/* Function to display the "main" routine. */ +extern void tui_display_main (void); +extern void tui_update_source_window (struct tui_win_info *, struct symtab *, + union tui_line_or_address, int); +extern void tui_update_source_window_as_is (struct tui_win_info *, + struct symtab *, + union tui_line_or_address, int); +extern void tui_update_source_windows_with_addr (CORE_ADDR); +extern void tui_update_source_windows_with_line (struct symtab *, int); +extern void tui_clear_source_content (struct tui_win_info *, int); +extern void tui_erase_source_content (struct tui_win_info *, int); +extern void tui_show_source_content (struct tui_win_info *); +extern void tui_horizontal_source_scroll (struct tui_win_info *, + enum tui_scroll_direction, int); +extern enum tui_status tui_set_exec_info_content (struct tui_win_info *); +extern void tui_show_exec_info_content (struct tui_win_info *); +extern void tui_erase_exec_info_content (struct tui_win_info *); +extern void tui_clear_exec_info_content (struct tui_win_info *); +extern void tui_update_exec_info (struct tui_win_info *); + +extern void tui_set_is_exec_point_at (union tui_line_or_address, + struct tui_win_info *); +extern enum tui_status tui_alloc_source_buffer (struct tui_win_info *); +extern int tui_line_is_displayed (int, struct tui_win_info *, int); +extern int tui_addr_is_displayed (CORE_ADDR, struct tui_win_info *, int); + + +/* Constant definitions. */ +#define SCROLL_THRESHOLD 2 /* threshold for lazy scroll */ + +#endif diff --git a/contrib/gdb/gdb/tui/tui.c b/contrib/gdb/gdb/tui/tui.c new file mode 100644 index 00000000000..d6f344f43d5 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui.c @@ -0,0 +1,590 @@ +/* General functions for the WDB TUI. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcmd.h" +#include "tui/tui.h" +#include "tui/tui-hooks.h" +#include "tui/tui-data.h" +#include "tui/tui-layout.h" +#include "tui/tui-io.h" +#include "tui/tui-regs.h" +#include "tui/tui-stack.h" +#include "tui/tui-win.h" +#include "tui/tui-winsource.h" +#include "tui/tui-windata.h" +#include "target.h" +#include "frame.h" +#include "breakpoint.h" +#include "inferior.h" +#include "symtab.h" +#include "source.h" + +#include +#include +#include +#ifdef HAVE_TERM_H +#include +#endif +#include +#include +#if 0 +#include +#endif +#include + +#include "gdb_curses.h" + +/* This redefines CTRL if it is not already defined, so it must come + after terminal state releated include files like and + "gdb_ncurses.h". */ +#include "readline/readline.h" + +/* Tells whether the TUI is active or not. */ +int tui_active = 0; +static int tui_finish_init = 1; + +enum tui_key_mode tui_current_key_mode = TUI_COMMAND_MODE; + +struct tui_char_command +{ + unsigned char key; + const char* cmd; +}; + +/* Key mapping to gdb commands when the TUI is using the single key mode. */ +static const struct tui_char_command tui_commands[] = { + { 'c', "continue" }, + { 'd', "down" }, + { 'f', "finish" }, + { 'n', "next" }, + { 'r', "run" }, + { 's', "step" }, + { 'u', "up" }, + { 'v', "info locals" }, + { 'w', "where" }, + { 0, 0 }, +}; + +static Keymap tui_keymap; +static Keymap tui_readline_standard_keymap; + +/* TUI readline command. + Switch the output mode between TUI/standard gdb. */ +static int +tui_rl_switch_mode (int notused1, int notused2) +{ + if (tui_active) + { + tui_disable (); + rl_prep_terminal (0); + } + else + { + rl_deprep_terminal (); + tui_enable (); + } + + /* Clear the readline in case switching occurred in middle of something. */ + if (rl_end) + rl_kill_text (0, rl_end); + + /* Since we left the curses mode, the terminal mode is restored to + some previous state. That state may not be suitable for readline + to work correctly (it may be restored in line mode). We force an + exit of the current readline so that readline is re-entered and it + will be able to setup the terminal for its needs. By re-entering + in readline, we also redisplay its prompt in the non-curses mode. */ + rl_newline (1, '\n'); + + /* Make sure the \n we are returning does not repeat the last command. */ + dont_repeat (); + return 0; +} + +/* TUI readline command. + Change the TUI layout to show a next layout. + This function is bound to CTRL-X 2. It is intended to provide + a functionality close to the Emacs split-window command. We always + show two windows (src+asm), (src+regs) or (asm+regs). */ +static int +tui_rl_change_windows (int notused1, int notused2) +{ + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); + + if (tui_active) + { + enum tui_layout_type new_layout; + enum tui_register_display_type regs_type = TUI_UNDEFINED_REGS; + + new_layout = tui_current_layout (); + + /* Select a new layout to have a rolling layout behavior + with always two windows (except when undefined). */ + switch (new_layout) + { + case SRC_COMMAND: + new_layout = SRC_DISASSEM_COMMAND; + break; + + case DISASSEM_COMMAND: + new_layout = SRC_DISASSEM_COMMAND; + break; + + case SRC_DATA_COMMAND: + new_layout = SRC_DISASSEM_COMMAND; + break; + + case SRC_DISASSEM_COMMAND: + new_layout = DISASSEM_DATA_COMMAND; + break; + + case DISASSEM_DATA_COMMAND: + new_layout = SRC_DATA_COMMAND; + break; + + default: + new_layout = SRC_COMMAND; + break; + } + tui_set_layout (new_layout, regs_type); + } + return 0; +} + +/* TUI readline command. + Delete the second TUI window to only show one. */ +static int +tui_rl_delete_other_windows (int notused1, int notused2) +{ + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); + + if (tui_active) + { + enum tui_layout_type new_layout; + enum tui_register_display_type regs_type = TUI_UNDEFINED_REGS; + + new_layout = tui_current_layout (); + + /* Kill one window. */ + switch (new_layout) + { + case SRC_COMMAND: + case SRC_DATA_COMMAND: + case SRC_DISASSEM_COMMAND: + default: + new_layout = SRC_COMMAND; + break; + + case DISASSEM_COMMAND: + case DISASSEM_DATA_COMMAND: + new_layout = DISASSEM_COMMAND; + break; + } + tui_set_layout (new_layout, regs_type); + } + return 0; +} + +/* TUI readline command. + Switch the active window to give the focus to a next window. */ +static int +tui_rl_other_window (int count, int key) +{ + struct tui_win_info * win_info; + + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); + + win_info = tui_next_win (tui_win_with_focus ()); + if (win_info) + { + tui_set_win_focus_to (win_info); + if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible) + tui_refresh_data_win (); + keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN)); + } + return 0; +} + +/* TUI readline command. + Execute the gdb command bound to the specified key. */ +static int +tui_rl_command_key (int count, int key) +{ + int i; + + reinitialize_more_filter (); + for (i = 0; tui_commands[i].cmd; i++) + { + if (tui_commands[i].key == key) + { + /* Must save the command because it can be modified + by execute_command. */ + char* cmd = alloca (strlen (tui_commands[i].cmd) + 1); + strcpy (cmd, tui_commands[i].cmd); + execute_command (cmd, TRUE); + return 0; + } + } + return 0; +} + +/* TUI readline command. + Temporarily leave the TUI SingleKey mode to allow editing + a gdb command with the normal readline. Once the command + is executed, the TUI SingleKey mode is installed back. */ +static int +tui_rl_command_mode (int count, int key) +{ + tui_set_key_mode (TUI_ONE_COMMAND_MODE); + return rl_insert (count, key); +} + +/* TUI readline command. + Switch between TUI SingleKey mode and gdb readline editing. */ +static int +tui_rl_next_keymap (int notused1, int notused2) +{ + if (!tui_active) + tui_rl_switch_mode (0/*notused*/, 0/*notused*/); + + tui_set_key_mode (tui_current_key_mode == TUI_COMMAND_MODE + ? TUI_SINGLE_KEY_MODE : TUI_COMMAND_MODE); + return 0; +} + +/* Readline hook to redisplay ourself the gdb prompt. + In the SingleKey mode, the prompt is not printed so that + the command window is cleaner. It will be displayed if + we temporarily leave the SingleKey mode. */ +static int +tui_rl_startup_hook (void) +{ + rl_already_prompted = 1; + if (tui_current_key_mode != TUI_COMMAND_MODE) + tui_set_key_mode (TUI_SINGLE_KEY_MODE); + tui_redisplay_readline (); + return 0; +} + +/* Change the TUI key mode by installing the appropriate readline keymap. */ +void +tui_set_key_mode (enum tui_key_mode mode) +{ + tui_current_key_mode = mode; + rl_set_keymap (mode == TUI_SINGLE_KEY_MODE + ? tui_keymap : tui_readline_standard_keymap); + tui_show_locator_content (); +} + +/* Initialize readline and configure the keymap for the switching + key shortcut. */ +void +tui_initialize_readline (void) +{ + int i; + Keymap tui_ctlx_keymap; + + rl_initialize (); + + rl_add_defun ("tui-switch-mode", tui_rl_switch_mode, -1); + rl_add_defun ("gdb-command", tui_rl_command_key, -1); + rl_add_defun ("next-keymap", tui_rl_next_keymap, -1); + + tui_keymap = rl_make_bare_keymap (); + tui_ctlx_keymap = rl_make_bare_keymap (); + tui_readline_standard_keymap = rl_get_keymap (); + + for (i = 0; tui_commands[i].cmd; i++) + rl_bind_key_in_map (tui_commands[i].key, tui_rl_command_key, tui_keymap); + + rl_generic_bind (ISKMAP, "\\C-x", (char*) tui_ctlx_keymap, tui_keymap); + + /* Bind all other keys to tui_rl_command_mode so that we switch + temporarily from SingleKey mode and can enter a gdb command. */ + for (i = ' '; i < 0x7f; i++) + { + int j; + + for (j = 0; tui_commands[j].cmd; j++) + if (tui_commands[j].key == i) + break; + + if (tui_commands[j].cmd) + continue; + + rl_bind_key_in_map (i, tui_rl_command_mode, tui_keymap); + } + + rl_bind_key_in_map ('a', tui_rl_switch_mode, emacs_ctlx_keymap); + rl_bind_key_in_map ('a', tui_rl_switch_mode, tui_ctlx_keymap); + rl_bind_key_in_map ('A', tui_rl_switch_mode, emacs_ctlx_keymap); + rl_bind_key_in_map ('A', tui_rl_switch_mode, tui_ctlx_keymap); + rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, emacs_ctlx_keymap); + rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, tui_ctlx_keymap); + rl_bind_key_in_map ('1', tui_rl_delete_other_windows, emacs_ctlx_keymap); + rl_bind_key_in_map ('1', tui_rl_delete_other_windows, tui_ctlx_keymap); + rl_bind_key_in_map ('2', tui_rl_change_windows, emacs_ctlx_keymap); + rl_bind_key_in_map ('2', tui_rl_change_windows, tui_ctlx_keymap); + rl_bind_key_in_map ('o', tui_rl_other_window, emacs_ctlx_keymap); + rl_bind_key_in_map ('o', tui_rl_other_window, tui_ctlx_keymap); + rl_bind_key_in_map ('q', tui_rl_next_keymap, tui_keymap); + rl_bind_key_in_map ('s', tui_rl_next_keymap, emacs_ctlx_keymap); + rl_bind_key_in_map ('s', tui_rl_next_keymap, tui_ctlx_keymap); +} + +/* Enter in the tui mode (curses). + When in normal mode, it installs the tui hooks in gdb, redirects + the gdb output, configures the readline to work in tui mode. + When in curses mode, it does nothing. */ +void +tui_enable (void) +{ + if (tui_active) + return; + + /* To avoid to initialize curses when gdb starts, there is a defered + curses initialization. This initialization is made only once + and the first time the curses mode is entered. */ + if (tui_finish_init) + { + WINDOW *w; + + w = initscr (); + + cbreak (); + noecho (); + /*timeout (1);*/ + nodelay(w, FALSE); + nl(); + keypad (w, TRUE); + rl_initialize (); + tui_set_term_height_to (LINES); + tui_set_term_width_to (COLS); + def_prog_mode (); + + tui_show_frame_info (0); + tui_set_layout (SRC_COMMAND, TUI_UNDEFINED_REGS); + tui_set_win_focus_to (TUI_SRC_WIN); + keypad (TUI_CMD_WIN->generic.handle, TRUE); + wrefresh (TUI_CMD_WIN->generic.handle); + tui_finish_init = 0; + } + else + { + /* Save the current gdb setting of the terminal. + Curses will restore this state when endwin() is called. */ + def_shell_mode (); + clearok (stdscr, TRUE); + } + + /* Install the TUI specific hooks. */ + tui_install_hooks (); + rl_startup_hook = tui_rl_startup_hook; + + tui_update_variables (); + + tui_setup_io (1); + + tui_active = 1; + if (deprecated_selected_frame) + tui_show_frame_info (deprecated_selected_frame); + + /* Restore TUI keymap. */ + tui_set_key_mode (tui_current_key_mode); + tui_refresh_all_win (); + + /* Update gdb's knowledge of its terminal. */ + target_terminal_save_ours (); + tui_update_gdb_sizes (); +} + +/* Leave the tui mode. + Remove the tui hooks and configure the gdb output and readline + back to their original state. The curses mode is left so that + the terminal setting is restored to the point when we entered. */ +void +tui_disable (void) +{ + if (!tui_active) + return; + + /* Restore initial readline keymap. */ + rl_set_keymap (tui_readline_standard_keymap); + + /* Remove TUI hooks. */ + tui_remove_hooks (); + rl_startup_hook = 0; + rl_already_prompted = 0; + + /* Leave curses and restore previous gdb terminal setting. */ + endwin (); + + /* gdb terminal has changed, update gdb internal copy of it + so that terminal management with the inferior works. */ + tui_setup_io (0); + + /* Update gdb's knowledge of its terminal. */ + target_terminal_save_ours (); + + tui_active = 0; + tui_update_gdb_sizes (); +} + +void +strcat_to_buf (char *buf, int buflen, const char *item_to_add) +{ + if (item_to_add != (char *) NULL && buf != (char *) NULL) + { + if ((strlen (buf) + strlen (item_to_add)) <= buflen) + strcat (buf, item_to_add); + else + strncat (buf, item_to_add, (buflen - strlen (buf))); + } +} + +#if 0 +/* Solaris defines CTRL. */ +#ifndef CTRL +#define CTRL(x) (x & ~0140) +#endif + +#define FILEDES 2 +#define CHK(val, dft) (val<=0 ? dft : val) + +static void +tui_reset (void) +{ + struct termio mode; + + /* + ** reset the teletype mode bits to a sensible state. + ** Copied tset.c + */ +#if ! defined (USG) && defined (TIOCGETC) + struct tchars tbuf; +#endif /* !USG && TIOCGETC */ +#ifdef UCB_NTTY + struct ltchars ltc; + + if (ldisc == NTTYDISC) + { + ioctl (FILEDES, TIOCGLTC, <c); + ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z')); + ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y')); + ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R')); + ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O')); + ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W')); + ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V')); + ioctl (FILEDES, TIOCSLTC, <c); + } +#endif /* UCB_NTTY */ +#ifndef USG +#ifdef TIOCGETC + ioctl (FILEDES, TIOCGETC, &tbuf); + tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?')); + tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\')); + tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q')); + tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S')); + tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D')); + /* brkc is left alone */ + ioctl (FILEDES, TIOCSETC, &tbuf); +#endif /* TIOCGETC */ + mode.sg_flags &= ~(RAW +#ifdef CBREAK + | CBREAK +#endif /* CBREAK */ + | VTDELAY | ALLDELAY); + mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP; +#else /*USG */ + ioctl (FILEDES, TCGETA, &mode); + mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?')); + mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\')); + mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D')); + + mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF); + mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON); + mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | + NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY); + mode.c_oflag |= (OPOST | ONLCR); + mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL); +#ifndef hp9000s800 + mode.c_cflag |= (CS8 | CREAD); +#else /*hp9000s800 */ + mode.c_cflag |= (CS8 | CSTOPB | CREAD); +#endif /* hp9000s800 */ + mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH); + mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK); + ioctl (FILEDES, TCSETAW, &mode); +#endif /* USG */ + + return; +} +#endif + +void +tui_show_source (const char *file, int line) +{ + struct symtab_and_line cursal = get_current_source_symtab_and_line (); + /* make sure that the source window is displayed */ + tui_add_win_to_layout (SRC_WIN); + + tui_update_source_windows_with_line (cursal.symtab, line); + tui_update_locator_filename (file); +} + +void +tui_show_assembly (CORE_ADDR addr) +{ + tui_add_win_to_layout (DISASSEM_WIN); + tui_update_source_windows_with_addr (addr); +} + +int +tui_is_window_visible (enum tui_win_type type) +{ + if (tui_active == 0) + return 0; + + if (tui_win_list[type] == 0) + return 0; + + return tui_win_list[type]->generic.is_visible; +} + +int +tui_get_command_dimension (int *width, int *height) +{ + if (!tui_active || (TUI_CMD_WIN == NULL)) + { + return 0; + } + + *width = TUI_CMD_WIN->generic.width; + *height = TUI_CMD_WIN->generic.height; + return 1; +} diff --git a/contrib/gdb/gdb/tui/tui.h b/contrib/gdb/gdb/tui/tui.h new file mode 100644 index 00000000000..d7b741c68a5 --- /dev/null +++ b/contrib/gdb/gdb/tui/tui.h @@ -0,0 +1,100 @@ +/* External/Public TUI Header File. + + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, + Inc. + + Contributed by Hewlett-Packard Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef TUI_H +#define TUI_H + +struct ui_file; + +extern void strcat_to_buf (char *, int, const char *); + +/* Types of error returns. */ +enum tui_status +{ + TUI_SUCCESS, + TUI_FAILURE +}; + +/* Types of windows */ +enum tui_win_type +{ + SRC_WIN = 0, + DISASSEM_WIN, + DATA_WIN, + CMD_WIN, + /* This must ALWAYS be AFTER the major windows last. */ + MAX_MAJOR_WINDOWS, + /* Auxillary windows. */ + LOCATOR_WIN, + EXEC_INFO_WIN, + DATA_ITEM_WIN, + /* This must ALWAYS be next to last. */ + MAX_WINDOWS, + UNDEFINED_WIN /* LAST */ +}; + +/* GENERAL TUI FUNCTIONS */ +/* tui.c */ +extern CORE_ADDR tui_get_low_disassembly_address (CORE_ADDR, CORE_ADDR); +extern void tui_show_assembly (CORE_ADDR addr); +extern int tui_is_window_visible (enum tui_win_type type); +extern int tui_get_command_dimension (int *width, int *height); + +/* Initialize readline and configure the keymap for the switching + key shortcut. */ +extern void tui_initialize_readline (void); + +/* Enter in the tui mode (curses). */ +extern void tui_enable (void); + +/* Leave the tui mode. */ +extern void tui_disable (void); + +enum tui_key_mode +{ + /* Plain command mode to enter gdb commands. */ + TUI_COMMAND_MODE, + + /* SingleKey mode with some keys bound to gdb commands. */ + TUI_SINGLE_KEY_MODE, + + /* Read/edit one command and return to SingleKey after it's processed. */ + TUI_ONE_COMMAND_MODE +}; + +extern enum tui_key_mode tui_current_key_mode; + +/* Change the TUI key mode by installing the appropriate readline keymap. */ +extern void tui_set_key_mode (enum tui_key_mode mode); + +extern int tui_active; + +extern void tui_show_source (const char *file, int line); + +extern struct ui_out *tui_out_new (struct ui_file *stream); + +/* tui-layout.c */ +extern enum tui_status tui_set_layout_for_display_command (const char *name); + +#endif diff --git a/contrib/gdb/gdb/typeprint.c b/contrib/gdb/gdb/typeprint.c index b56610d3ac0..82ca5f17474 100644 --- a/contrib/gdb/gdb/typeprint.c +++ b/contrib/gdb/gdb/typeprint.c @@ -1,6 +1,7 @@ /* Language independent support for printing types for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 1999, - 2000, 2001 Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, + 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -20,7 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "obstack.h" +#include "gdb_obstack.h" #include "bfd.h" /* Binary File Description */ #include "symtab.h" #include "gdbtypes.h" @@ -32,7 +33,7 @@ #include "target.h" #include "language.h" #include "cp-abi.h" - +#include "typeprint.h" #include "gdb_string.h" #include @@ -66,16 +67,16 @@ typedef_print (struct type *type, struct symbol *new, struct ui_file *stream) fprintf_filtered (stream, "typedef "); type_print (type, "", stream, 0); if (TYPE_NAME ((SYMBOL_TYPE (new))) == 0 - || !STREQ (TYPE_NAME ((SYMBOL_TYPE (new))), SYMBOL_NAME (new))) - fprintf_filtered (stream, " %s", SYMBOL_SOURCE_NAME (new)); + || strcmp (TYPE_NAME ((SYMBOL_TYPE (new))), DEPRECATED_SYMBOL_NAME (new)) != 0) + fprintf_filtered (stream, " %s", SYMBOL_PRINT_NAME (new)); break; #endif #ifdef _LANG_m2 case language_m2: fprintf_filtered (stream, "TYPE "); - if (!TYPE_NAME (SYMBOL_TYPE (new)) || - !STREQ (TYPE_NAME (SYMBOL_TYPE (new)), SYMBOL_NAME (new))) - fprintf_filtered (stream, "%s = ", SYMBOL_SOURCE_NAME (new)); + if (!TYPE_NAME (SYMBOL_TYPE (new)) + || strcmp (TYPE_NAME ((SYMBOL_TYPE (new))), DEPRECATED_SYMBOL_NAME (new)) != 0) + fprintf_filtered (stream, "%s = ", SYMBOL_PRINT_NAME (new)); else fprintf_filtered (stream, " = "); type_print (type, "", stream, 0); @@ -84,18 +85,7 @@ typedef_print (struct type *type, struct symbol *new, struct ui_file *stream) #ifdef _LANG_pascal case language_pascal: fprintf_filtered (stream, "type "); - fprintf_filtered (stream, "%s = ", SYMBOL_SOURCE_NAME (new)); - type_print (type, "", stream, 0); - break; -#endif -#ifdef _LANG_chill - case language_chill: - fprintf_filtered (stream, "SYNMODE "); - if (!TYPE_NAME (SYMBOL_TYPE (new)) || - !STREQ (TYPE_NAME (SYMBOL_TYPE (new)), SYMBOL_NAME (new))) - fprintf_filtered (stream, "%s = ", SYMBOL_SOURCE_NAME (new)); - else - fprintf_filtered (stream, " = "); + fprintf_filtered (stream, "%s = ", SYMBOL_PRINT_NAME (new)); type_print (type, "", stream, 0); break; #endif @@ -127,7 +117,7 @@ whatis_exp (char *exp, int show) { struct expression *expr; struct value *val; - register struct cleanup *old_chain = NULL; + struct cleanup *old_chain = NULL; struct type *real_type = NULL; struct type *type; int full = 0; @@ -183,7 +173,6 @@ whatis_exp (char *exp, int show) do_cleanups (old_chain); } -/* ARGSUSED */ static void whatis_command (char *exp, int from_tty) { @@ -210,13 +199,12 @@ ptype_eval (struct expression *exp) /* TYPENAME is either the name of a type, or an expression. */ -/* ARGSUSED */ static void ptype_command (char *typename, int from_tty) { - register struct type *type; + struct type *type; struct expression *expr; - register struct cleanup *old_chain; + struct cleanup *old_chain; if (typename == NULL) { @@ -317,6 +305,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream) case TYPE_CODE_MEMBER: case TYPE_CODE_METHOD: case TYPE_CODE_REF: + case TYPE_CODE_NAMESPACE: error ("internal error: unhandled type in print_type_scalar"); break; @@ -334,8 +323,8 @@ void maintenance_print_type (char *typename, int from_tty) { struct value *val; - register struct type *type; - register struct cleanup *old_chain; + struct type *type; + struct cleanup *old_chain; struct expression *expr; if (typename != NULL) diff --git a/contrib/gdb/gdb/typeprint.h b/contrib/gdb/gdb/typeprint.h index c57cc58c7ef..f2de1c57015 100644 --- a/contrib/gdb/gdb/typeprint.h +++ b/contrib/gdb/gdb/typeprint.h @@ -22,6 +22,8 @@ #ifndef TYPEPRINT_H #define TYPEPRINT_H +struct ui_file; + void print_type_scalar (struct type * type, LONGEST, struct ui_file *); void c_type_print_varspec_suffix (struct type *, struct ui_file *, int, diff --git a/contrib/gdb/gdb/ui-file.c b/contrib/gdb/gdb/ui-file.c index 86655e9c2f7..6ad5414b19f 100644 --- a/contrib/gdb/gdb/ui-file.c +++ b/contrib/gdb/gdb/ui-file.c @@ -1,5 +1,6 @@ /* UI_FILE - a generic STDIO like output stream. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -24,12 +25,12 @@ #include "ui-file.h" #include "gdb_string.h" -#undef XMALLOC -#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) +#include static ui_file_isatty_ftype null_file_isatty; static ui_file_write_ftype null_file_write; static ui_file_fputs_ftype null_file_fputs; +static ui_file_read_ftype null_file_read; static ui_file_flush_ftype null_file_flush; static ui_file_delete_ftype null_file_delete; static ui_file_rewind_ftype null_file_rewind; @@ -41,6 +42,7 @@ struct ui_file ui_file_flush_ftype *to_flush; ui_file_write_ftype *to_write; ui_file_fputs_ftype *to_fputs; + ui_file_read_ftype *to_read; ui_file_delete_ftype *to_delete; ui_file_isatty_ftype *to_isatty; ui_file_rewind_ftype *to_rewind; @@ -58,6 +60,7 @@ ui_file_new (void) set_ui_file_flush (file, null_file_flush); set_ui_file_write (file, null_file_write); set_ui_file_fputs (file, null_file_fputs); + set_ui_file_read (file, null_file_read); set_ui_file_isatty (file, null_file_isatty); set_ui_file_rewind (file, null_file_rewind); set_ui_file_put (file, null_file_put); @@ -125,6 +128,15 @@ null_file_write (struct ui_file *file, } } +static long +null_file_read (struct ui_file *file, + char *buf, + long sizeof_buf) +{ + errno = EBADF; + return 0; +} + static void null_file_fputs (const char *buf, struct ui_file *file) { @@ -188,6 +200,12 @@ ui_file_write (struct ui_file *file, file->to_write (file, buf, length_buf); } +long +ui_file_read (struct ui_file *file, char *buf, long length_buf) +{ + return file->to_read (file, buf, length_buf); +} + void fputs_unfiltered (const char *buf, struct ui_file *file) { @@ -225,6 +243,12 @@ set_ui_file_write (struct ui_file *file, file->to_write = write; } +void +set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read) +{ + file->to_read = read; +} + void set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs) { @@ -385,6 +409,7 @@ mem_file_write (struct ui_file *file, static ui_file_write_ftype stdio_file_write; static ui_file_fputs_ftype stdio_file_fputs; +static ui_file_read_ftype stdio_file_read; static ui_file_isatty_ftype stdio_file_isatty; static ui_file_delete_ftype stdio_file_delete; static struct ui_file *stdio_file_new (FILE * file, int close_p); @@ -411,6 +436,7 @@ stdio_file_new (FILE *file, int close_p) set_ui_file_flush (ui_file, stdio_file_flush); set_ui_file_write (ui_file, stdio_file_write); set_ui_file_fputs (ui_file, stdio_file_fputs); + set_ui_file_read (ui_file, stdio_file_read); set_ui_file_isatty (ui_file, stdio_file_isatty); return ui_file; } @@ -439,6 +465,16 @@ stdio_file_flush (struct ui_file *file) fflush (stdio->file); } +static long +stdio_file_read (struct ui_file *file, char *buf, long length_buf) +{ + struct stdio_file *stdio = ui_file_data (file); + if (stdio->magic != &stdio_file_magic) + internal_error (__FILE__, __LINE__, + "stdio_file_read: bad magic number"); + return read (fileno (stdio->file), buf, length_buf); +} + static void stdio_file_write (struct ui_file *file, const char *buf, long length_buf) { @@ -485,3 +521,97 @@ gdb_fopen (char *name, char *mode) return NULL; return stdio_file_new (f, 1); } + +/* ``struct ui_file'' implementation that maps onto two ui-file objects. */ + +static ui_file_write_ftype tee_file_write; +static ui_file_fputs_ftype tee_file_fputs; +static ui_file_isatty_ftype tee_file_isatty; +static ui_file_delete_ftype tee_file_delete; +static ui_file_flush_ftype tee_file_flush; + +static int tee_file_magic; + +struct tee_file + { + int *magic; + struct ui_file *one, *two; + int close_one, close_two; + }; + +struct ui_file * +tee_file_new (struct ui_file *one, int close_one, + struct ui_file *two, int close_two) +{ + struct ui_file *ui_file = ui_file_new (); + struct tee_file *tee = xmalloc (sizeof (struct tee_file)); + tee->magic = &tee_file_magic; + tee->one = one; + tee->two = two; + tee->close_one = close_one; + tee->close_two = close_two; + set_ui_file_data (ui_file, tee, tee_file_delete); + set_ui_file_flush (ui_file, tee_file_flush); + set_ui_file_write (ui_file, tee_file_write); + set_ui_file_fputs (ui_file, tee_file_fputs); + set_ui_file_isatty (ui_file, tee_file_isatty); + return ui_file; +} + +static void +tee_file_delete (struct ui_file *file) +{ + struct tee_file *tee = ui_file_data (file); + if (tee->magic != &tee_file_magic) + internal_error (__FILE__, __LINE__, + "tee_file_delete: bad magic number"); + if (tee->close_one) + ui_file_delete (tee->one); + if (tee->close_two) + ui_file_delete (tee->two); + + xfree (tee); +} + +static void +tee_file_flush (struct ui_file *file) +{ + struct tee_file *tee = ui_file_data (file); + if (tee->magic != &tee_file_magic) + internal_error (__FILE__, __LINE__, + "tee_file_flush: bad magic number"); + tee->one->to_flush (tee->one); + tee->two->to_flush (tee->two); +} + +static void +tee_file_write (struct ui_file *file, const char *buf, long length_buf) +{ + struct tee_file *tee = ui_file_data (file); + if (tee->magic != &tee_file_magic) + internal_error (__FILE__, __LINE__, + "tee_file_write: bad magic number"); + ui_file_write (tee->one, buf, length_buf); + ui_file_write (tee->two, buf, length_buf); +} + +static void +tee_file_fputs (const char *linebuffer, struct ui_file *file) +{ + struct tee_file *tee = ui_file_data (file); + if (tee->magic != &tee_file_magic) + internal_error (__FILE__, __LINE__, + "tee_file_fputs: bad magic number"); + tee->one->to_fputs (linebuffer, tee->one); + tee->two->to_fputs (linebuffer, tee->two); +} + +static int +tee_file_isatty (struct ui_file *file) +{ + struct tee_file *tee = ui_file_data (file); + if (tee->magic != &tee_file_magic) + internal_error (__FILE__, __LINE__, + "tee_file_isatty: bad magic number"); + return (0); +} diff --git a/contrib/gdb/gdb/ui-file.h b/contrib/gdb/gdb/ui-file.h index 3c351939797..8b28d1a4139 100644 --- a/contrib/gdb/gdb/ui-file.h +++ b/contrib/gdb/gdb/ui-file.h @@ -41,6 +41,9 @@ extern void set_ui_file_write (struct ui_file *stream, ui_file_write_ftype *fput typedef void (ui_file_fputs_ftype) (const char *, struct ui_file * stream); extern void set_ui_file_fputs (struct ui_file *stream, ui_file_fputs_ftype * fputs); +typedef long (ui_file_read_ftype) (struct ui_file * stream, char *buf, long length_buf); +extern void set_ui_file_read (struct ui_file *stream, ui_file_read_ftype *fread); + typedef int (ui_file_isatty_ftype) (struct ui_file * stream); extern void set_ui_file_isatty (struct ui_file *stream, ui_file_isatty_ftype * isatty); @@ -78,6 +81,8 @@ extern char *ui_file_xstrdup (struct ui_file *file, long *length); +extern long ui_file_read (struct ui_file *file, char *buf, long length_buf); + /* Create/open a memory based file. Can be used as a scratch buffer for collecting output. */ extern struct ui_file *mem_fileopen (void); @@ -90,4 +95,11 @@ extern struct ui_file *stdio_fileopen (FILE *file); /* Open NAME returning an STDIO based UI_FILE. */ extern struct ui_file *gdb_fopen (char *name, char *mode); +/* Create a file which writes to both ONE and TWO. CLOSE_ONE + and CLOSE_TWO indicate whether the original files should be + closed when the new file is closed. */ +struct ui_file *tee_file_new (struct ui_file *one, + int close_one, + struct ui_file *two, + int close_two); #endif diff --git a/contrib/gdb/gdb/ui-out.c b/contrib/gdb/gdb/ui-out.c index 06db646de3d..854ec490ddf 100644 --- a/contrib/gdb/gdb/ui-out.c +++ b/contrib/gdb/gdb/ui-out.c @@ -1,5 +1,7 @@ /* Output generating routines for GDB. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Solutions. Written by Fernando Nasser for Cygnus. @@ -27,11 +29,6 @@ #include "ui-out.h" #include "gdb_assert.h" -/* Convenience macro for allocting typesafe memory. */ - -#undef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) - /* table header structures */ struct ui_out_hdr @@ -48,7 +45,7 @@ struct ui_out_hdr is always available. Stack/nested level 0 is reserved for the top-level result. */ -enum { MAX_UI_OUT_LEVELS = 5 }; +enum { MAX_UI_OUT_LEVELS = 6 }; struct ui_out_level { @@ -209,6 +206,7 @@ struct ui_out_impl default_ui_out_impl = default_message, default_wrap_hint, default_flush, + NULL, 0, /* Does not need MI hacks. */ }; @@ -257,6 +255,7 @@ static void uo_message (struct ui_out *uiout, int verbosity, const char *format, va_list args); static void uo_wrap_hint (struct ui_out *uiout, char *identstring); static void uo_flush (struct ui_out *uiout); +static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream); /* Prototypes for local functions */ @@ -270,13 +269,11 @@ static void clear_header_list (struct ui_out *uiout); static void verify_field (struct ui_out *uiout, int *fldno, int *width, int *align); -static void init_ui_out_state (struct ui_out *uiout); - /* exported functions (ui_out API) */ /* Mark beginning of a table */ -void +static void ui_out_table_begin (struct ui_out *uiout, int nbrofcols, int nr_rows, const char *tblid) @@ -321,7 +318,7 @@ columns."); uo_table_body (uiout); } -void +static void ui_out_table_end (struct ui_out *uiout) { if (!uiout->table.flag) @@ -354,6 +351,22 @@ and before table_body."); uo_table_header (uiout, width, alignment, col_name, colhdr); } +static void +do_cleanup_table_end (void *data) +{ + struct ui_out *ui_out = data; + + ui_out_table_end (ui_out); +} + +struct cleanup * +make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, int nr_cols, + int nr_rows, const char *tblid) +{ + ui_out_table_begin (ui_out, nr_cols, nr_rows, tblid); + return make_cleanup (do_cleanup_table_end, ui_out); +} + void ui_out_begin (struct ui_out *uiout, enum ui_out_type type, @@ -390,19 +403,6 @@ specified after table_body."); uo_begin (uiout, type, new_level, id); } -void -ui_out_list_begin (struct ui_out *uiout, - const char *id) -{ - ui_out_begin (uiout, ui_out_type_list, id); -} - -void -ui_out_tuple_begin (struct ui_out *uiout, const char *id) -{ - ui_out_begin (uiout, ui_out_type_tuple, id); -} - void ui_out_end (struct ui_out *uiout, enum ui_out_type type) @@ -411,18 +411,6 @@ ui_out_end (struct ui_out *uiout, uo_end (uiout, type, old_level); } -void -ui_out_list_end (struct ui_out *uiout) -{ - ui_out_end (uiout, ui_out_type_list); -} - -void -ui_out_tuple_end (struct ui_out *uiout) -{ - ui_out_end (uiout, ui_out_type_tuple); -} - struct ui_out_end_cleanup_data { struct ui_out *uiout; @@ -448,20 +436,11 @@ make_cleanup_ui_out_end (struct ui_out *uiout, return make_cleanup (do_cleanup_end, end_cleanup_data); } -struct cleanup * -make_cleanup_ui_out_begin_end (struct ui_out *uiout, - enum ui_out_type type, - const char *id) -{ - ui_out_begin (uiout, type, id); - return make_cleanup_ui_out_end (uiout, type); -} - struct cleanup * make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout, const char *id) { - ui_out_tuple_begin (uiout, id); + ui_out_begin (uiout, ui_out_type_tuple, id); return make_cleanup_ui_out_end (uiout, ui_out_type_tuple); } @@ -469,7 +448,7 @@ struct cleanup * make_cleanup_ui_out_list_begin_end (struct ui_out *uiout, const char *id) { - ui_out_list_begin (uiout, id); + ui_out_begin (uiout, ui_out_type_list, id); return make_cleanup_ui_out_end (uiout, ui_out_type_list); } @@ -488,6 +467,23 @@ ui_out_field_int (struct ui_out *uiout, uo_field_int (uiout, fldno, width, align, fldname, value); } +void +ui_out_field_fmt_int (struct ui_out *uiout, + int input_width, + enum ui_align input_align, + const char *fldname, + int value) +{ + int fldno; + int width; + int align; + struct ui_out_level *current = current_level (uiout); + + verify_field (uiout, &fldno, &width, &align); + + uo_field_int (uiout, fldno, input_width, input_align, fldname, value); +} + void ui_out_field_core_addr (struct ui_out *uiout, const char *fldname, @@ -495,9 +491,14 @@ ui_out_field_core_addr (struct ui_out *uiout, { char addstr[20]; - /* FIXME-32x64: need a print_address_numeric with field width */ + /* FIXME: cagney/2002-05-03: Need local_address_string() function + that returns the language localized string formatted to a width + based on TARGET_ADDR_BIT. */ /* print_address_numeric (address, 1, local_stream); */ - strcpy (addstr, local_hex_string_custom ((unsigned long) address, "08l")); + if (TARGET_ADDR_BIT <= 32) + strcpy (addstr, local_hex_string_custom (address, "08l")); + else + strcpy (addstr, local_hex_string_custom (address, "016l")); ui_out_field_string (uiout, fldname, addstr); } @@ -637,6 +638,12 @@ ui_out_flush (struct ui_out *uiout) uo_flush (uiout); } +int +ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream) +{ + return uo_redirect (uiout, outstream); +} + /* set the flags specified by the mask given */ int ui_out_set_flags (struct ui_out *uiout, int mask) @@ -980,6 +987,15 @@ uo_flush (struct ui_out *uiout) uiout->impl->flush (uiout); } +int +uo_redirect (struct ui_out *uiout, struct ui_file *outstream) +{ + if (!uiout->impl->redirect) + return -1; + uiout->impl->redirect (uiout, outstream); + return 0; +} + /* local functions */ /* list of column headers manipulation routines */ diff --git a/contrib/gdb/gdb/ui-out.h b/contrib/gdb/gdb/ui-out.h index 797c2fe960d..5e19aff9a89 100644 --- a/contrib/gdb/gdb/ui-out.h +++ b/contrib/gdb/gdb/ui-out.h @@ -27,7 +27,7 @@ struct ui_out; struct ui_out_data; - +struct ui_file; /* the current ui_out */ @@ -88,37 +88,31 @@ extern struct cleanup *ui_out_begin_cleanup_end (struct ui_out *uiout, implied structure: ``table = { hdr = { header, ... } , body = [ { field, ... }, ... ] }''. If NR_ROWS is negative then there is at least one row. */ - -extern void ui_out_table_begin (struct ui_out *uiout, int nbrofcols, - int nr_rows, const char *tblid); - extern void ui_out_table_header (struct ui_out *uiout, int width, enum ui_align align, const char *col_name, const char *colhdr); extern void ui_out_table_body (struct ui_out *uiout); -extern void ui_out_table_end (struct ui_out *uiout); - +extern struct cleanup *make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, + int nr_cols, + int nr_rows, + const char *tblid); /* Compatibility wrappers. */ -extern void ui_out_list_begin (struct ui_out *uiout, const char *id); - -extern void ui_out_list_end (struct ui_out *uiout); - extern struct cleanup *make_cleanup_ui_out_list_begin_end (struct ui_out *uiout, const char *id); -extern void ui_out_tuple_begin (struct ui_out *uiout, const char *id); - -extern void ui_out_tuple_end (struct ui_out *uiout); - extern struct cleanup *make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout, const char *id); extern void ui_out_field_int (struct ui_out *uiout, const char *fldname, int value); +extern void ui_out_field_fmt_int (struct ui_out *uiout, int width, + enum ui_align align, const char *fldname, + int value); + extern void ui_out_field_core_addr (struct ui_out *uiout, const char *fldname, CORE_ADDR address); @@ -237,6 +231,8 @@ typedef void (message_ftype) (struct ui_out * uiout, int verbosity, const char *format, va_list args); typedef void (wrap_hint_ftype) (struct ui_out * uiout, char *identstring); typedef void (flush_ftype) (struct ui_out * uiout); +typedef int (redirect_ftype) (struct ui_out * uiout, + struct ui_file * outstream); /* ui-out-impl */ @@ -260,6 +256,7 @@ struct ui_out_impl message_ftype *message; wrap_hint_ftype *wrap_hint; flush_ftype *flush; + redirect_ftype *redirect; int is_mi_like_p; }; @@ -272,4 +269,8 @@ extern struct ui_out *ui_out_new (struct ui_out_impl *impl, struct ui_out_data *data, int flags); +/* Redirect the ouptut of a ui_out object temporarily. */ + +extern int ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream); + #endif /* UI_OUT_H */ diff --git a/contrib/gdb/gdb/user-regs.c b/contrib/gdb/gdb/user-regs.c new file mode 100644 index 00000000000..9de177f2843 --- /dev/null +++ b/contrib/gdb/gdb/user-regs.c @@ -0,0 +1,211 @@ +/* User visible, per-frame registers, for GDB, the GNU debugger. + + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "user-regs.h" +#include "gdbtypes.h" +#include "gdb_string.h" +#include "gdb_assert.h" +#include "frame.h" + +/* A table of user registers. + + User registers have regnum's that live above of the range [0 + .. NUM_REGS + NUM_PSEUDO_REGS) (which is controlled by the target). + The target should never see a user register's regnum value. + + Always append, never delete. By doing this, the relative regnum + (offset from NUM_REGS + NUM_PSEUDO_REGS) assigned to each user + register never changes. */ + +struct user_reg +{ + const char *name; + struct value *(*read) (struct frame_info * frame); + struct user_reg *next; +}; + +/* This structure is named gdb_user_regs instead of user_regs to avoid + conflicts with any "struct user_regs" in system headers. For instance, + on ARM GNU/Linux native builds, nm-linux.h includes includes + includes includes , which + declares "struct user_regs". */ + +struct gdb_user_regs +{ + struct user_reg *first; + struct user_reg **last; +}; + +static void +append_user_reg (struct gdb_user_regs *regs, const char *name, + user_reg_read_ftype *read, struct user_reg *reg) +{ + /* The caller is responsible for allocating memory needed to store + the register. By doing this, the function can operate on a + register list stored in the common heap or a specific obstack. */ + gdb_assert (reg != NULL); + reg->name = name; + reg->read = read; + reg->next = NULL; + (*regs->last) = reg; + regs->last = &(*regs->last)->next; +} + +/* An array of the builtin user registers. */ + +static struct gdb_user_regs builtin_user_regs = { NULL, &builtin_user_regs.first }; + +void +user_reg_add_builtin (const char *name, user_reg_read_ftype *read) +{ + append_user_reg (&builtin_user_regs, name, read, + XMALLOC (struct user_reg)); +} + +/* Per-architecture user registers. Start with the builtin user + registers and then, again, append. */ + +static struct gdbarch_data *user_regs_data; + +static void * +user_regs_init (struct gdbarch *gdbarch) +{ + struct user_reg *reg; + struct gdb_user_regs *regs = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdb_user_regs); + regs->last = ®s->first; + for (reg = builtin_user_regs.first; reg != NULL; reg = reg->next) + append_user_reg (regs, reg->name, reg->read, + GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg)); + return regs; +} + +void +user_reg_add (struct gdbarch *gdbarch, const char *name, + user_reg_read_ftype *read) +{ + struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data); + if (regs == NULL) + { + /* ULGH, called during architecture initialization. Patch + things up. */ + regs = user_regs_init (gdbarch); + set_gdbarch_data (gdbarch, user_regs_data, regs); + } + append_user_reg (regs, name, read, + GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg)); +} + +int +user_reg_map_name_to_regnum (struct gdbarch *gdbarch, const char *name, + int len) +{ + /* Make life easy, set the len to something reasonable. */ + if (len < 0) + len = strlen (name); + + /* Search register name space first - always let an architecture + specific register override the user registers. */ + { + int i; + int maxregs = (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)); + for (i = 0; i < maxregs; i++) + { + const char *regname = gdbarch_register_name (gdbarch, i); + if (regname != NULL && len == strlen (regname) + && strncmp (regname, name, len) == 0) + { + return i; + } + } + } + + /* Search the user name space. */ + { + struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data); + struct user_reg *reg; + int nr; + for (nr = 0, reg = regs->first; reg != NULL; reg = reg->next, nr++) + { + if ((len < 0 && strcmp (reg->name, name)) + || (len == strlen (reg->name) + && strncmp (reg->name, name, len) == 0)) + return NUM_REGS + NUM_PSEUDO_REGS + nr; + } + } + + return -1; +} + +static struct user_reg * +usernum_to_user_reg (struct gdbarch *gdbarch, int usernum) +{ + struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data); + struct user_reg *reg; + for (reg = regs->first; reg != NULL; reg = reg->next) + { + if (usernum == 0) + return reg; + usernum--; + } + return NULL; +} + +const char * +user_reg_map_regnum_to_name (struct gdbarch *gdbarch, int regnum) +{ + int maxregs = (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)); + if (regnum < 0) + return NULL; + else if (regnum < maxregs) + return gdbarch_register_name (gdbarch, regnum); + else + { + struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs); + if (reg == NULL) + return NULL; + else + return reg->name; + } +} + +struct value * +value_of_user_reg (int regnum, struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + int maxregs = (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)); + struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs); + gdb_assert (reg != NULL); + return reg->read (frame); +} + +extern initialize_file_ftype _initialize_user_regs; /* -Wmissing-prototypes */ + +void +_initialize_user_regs (void) +{ + user_regs_data = register_gdbarch_data (user_regs_init); +} diff --git a/contrib/gdb/gdb/user-regs.h b/contrib/gdb/gdb/user-regs.h new file mode 100644 index 00000000000..d845c8a3263 --- /dev/null +++ b/contrib/gdb/gdb/user-regs.h @@ -0,0 +1,71 @@ +/* Per-frame user registers, for GDB, the GNU debugger. + + Copyright 2002, 2003 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef USER_REGS_H +#define USER_REGS_H + +/* Implement both builtin, and architecture specific, per-frame user + visible registers. + + Builtin registers apply to all architectures, where as architecture + specific registers are present when the architecture is selected. + + These registers are assigned register numbers outside the + architecture's register range [0 .. NUM_REGS + NUM_PSEUDO_REGS). + Their values should be constructed using per-frame information. */ + +/* TODO: cagney/2003-06-27: Need to think more about how these + registers are added, read, and modified. At present they are kind + of assumed to be read-only. Should it, for instance, return a + register descriptor that contains all the relvent access methods. */ + +struct frame_info; +struct gdbarch; + +/* Given an architecture, map a user visible register name onto its + index. */ + +extern int user_reg_map_name_to_regnum (struct gdbarch *gdbarch, + const char *str, int len); + +extern const char *user_reg_map_regnum_to_name (struct gdbarch *gdbarch, + int regnum); + +/* Return the value of the frame register in the specified frame. + + Note; These methods return a "struct value" instead of the raw + bytes as, at the time the register is being added, the type needed + to describe the register has not bee initialized. */ + +typedef struct value *(user_reg_read_ftype) (struct frame_info *frame); +extern struct value *value_of_user_reg (int regnum, struct frame_info *frame); + +/* Add a builtin register (present in all architectures). */ +extern void user_reg_add_builtin (const char *name, + user_reg_read_ftype *read); + +/* Add a per-architecture frame register. */ +extern void user_reg_add (struct gdbarch *gdbarch, const char *name, + user_reg_read_ftype *read); + +#endif diff --git a/contrib/gdb/gdb/utils.c b/contrib/gdb/gdb/utils.c index 75f65e14458..30ccebe7378 100644 --- a/contrib/gdb/gdb/utils.c +++ b/contrib/gdb/gdb/utils.c @@ -1,7 +1,8 @@ /* General utility routines for GDB, the GNU debugger. + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -20,29 +21,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that - "defs.h" should be included first. Unfortunatly some systems - (currently Debian GNU/Linux) include the via - and they clash with "bfd.h"'s definiton of true/false. The correct - fix is to remove true/false from "bfd.h", however, until that - happens, hack around it by including "config.h" and - first. */ - -#include "config.h" - -#ifdef HAVE_CURSES_H -#include -#endif -#ifdef HAVE_TERM_H -#include -#endif - #include "defs.h" #include "gdb_assert.h" #include #include "gdb_string.h" #include "event-top.h" +#ifdef TUI +#include "tui/tui.h" /* For tui_get_command_dimension. */ +#endif + #ifdef __GO32__ #include #endif @@ -60,23 +48,28 @@ #include "demangle.h" #include "expression.h" #include "language.h" +#include "charset.h" #include "annotate.h" +#include "filenames.h" -#include "inferior.h" /* for signed_pointer_to_address */ +#include "inferior.h" /* for signed_pointer_to_address */ #include /* For MAXPATHLEN */ -#include - -#ifdef USE_MMALLOC -#include "mmalloc.h" +#ifdef HAVE_CURSES_H +#include #endif +#ifdef HAVE_TERM_H +#include +#endif + +#include "readline/readline.h" #ifdef NEED_DECLARATION_MALLOC -extern PTR malloc (); +extern PTR malloc (); /* OK: PTR */ #endif #ifdef NEED_DECLARATION_REALLOC -extern PTR realloc (); +extern PTR realloc (); /* OK: PTR */ #endif #ifdef NEED_DECLARATION_FREE extern void free (); @@ -87,9 +80,6 @@ extern void free (); extern char *canonicalize_file_name (const char *); #endif -#undef XMALLOC -#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) - /* readline defines this. */ #undef savestring @@ -106,14 +96,11 @@ static void vfprintf_maybe_filtered (struct ui_file *, const char *, static void fputs_maybe_filtered (const char *, struct ui_file *, int); -#if defined (USE_MMALLOC) && !defined (NO_MMCHECK) -static void malloc_botch (void); -#endif +static void do_my_cleanups (struct cleanup **, struct cleanup *); static void prompt_for_continue (void); -static void set_width_command (char *, int, struct cmd_list_element *); - +static void set_screen_size (void); static void set_width (void); /* Chain of cleanup actions established with make_cleanup, @@ -124,7 +111,7 @@ static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */ static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */ static struct cleanup *exec_cleanup_chain; /* cleaned up on each execution command */ /* cleaned up on each error from within an execution command */ -static struct cleanup *exec_error_cleanup_chain; +static struct cleanup *exec_error_cleanup_chain; /* Pointer to what is left to do for an execution command after the target stops. Used only in asynchronous mode, by targets that @@ -154,13 +141,13 @@ int quit_flag; int immediate_quit; -/* Nonzero means that encoded C++ names should be printed out in their - C++ form rather than raw. */ +/* Nonzero means that encoded C++/ObjC names should be printed out in their + C++/ObjC form rather than raw. */ int demangle = 1; -/* Nonzero means that encoded C++ names should be printed out in their - C++ form even in assembler language displays. If this is set, but +/* Nonzero means that encoded C++/ObjC names should be printed out in their + C++/ObjC form even in assembler language displays. If this is set, but DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls. */ int asm_demangle = 0; @@ -277,9 +264,9 @@ struct cleanup * make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, void *arg) { - register struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); - register struct cleanup *old_chain = *pmy_chain; + struct cleanup *new + = (struct cleanup *) xmalloc (sizeof (struct cleanup)); + struct cleanup *old_chain = *pmy_chain; new->next = *pmy_chain; new->function = function; @@ -293,40 +280,40 @@ make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, until we get back to the point OLD_CHAIN in the cleanup_chain. */ void -do_cleanups (register struct cleanup *old_chain) +do_cleanups (struct cleanup *old_chain) { do_my_cleanups (&cleanup_chain, old_chain); } void -do_final_cleanups (register struct cleanup *old_chain) +do_final_cleanups (struct cleanup *old_chain) { do_my_cleanups (&final_cleanup_chain, old_chain); } void -do_run_cleanups (register struct cleanup *old_chain) +do_run_cleanups (struct cleanup *old_chain) { do_my_cleanups (&run_cleanup_chain, old_chain); } void -do_exec_cleanups (register struct cleanup *old_chain) +do_exec_cleanups (struct cleanup *old_chain) { do_my_cleanups (&exec_cleanup_chain, old_chain); } void -do_exec_error_cleanups (register struct cleanup *old_chain) +do_exec_error_cleanups (struct cleanup *old_chain) { do_my_cleanups (&exec_error_cleanup_chain, old_chain); } -void -do_my_cleanups (register struct cleanup **pmy_chain, - register struct cleanup *old_chain) +static void +do_my_cleanups (struct cleanup **pmy_chain, + struct cleanup *old_chain) { - register struct cleanup *ptr; + struct cleanup *ptr; while ((ptr = *pmy_chain) != old_chain) { *pmy_chain = ptr->next; /* Do this first incase recursion */ @@ -339,28 +326,28 @@ do_my_cleanups (register struct cleanup **pmy_chain, until we get back to the point OLD_CHAIN in the cleanup_chain. */ void -discard_cleanups (register struct cleanup *old_chain) +discard_cleanups (struct cleanup *old_chain) { discard_my_cleanups (&cleanup_chain, old_chain); } void -discard_final_cleanups (register struct cleanup *old_chain) +discard_final_cleanups (struct cleanup *old_chain) { discard_my_cleanups (&final_cleanup_chain, old_chain); } void -discard_exec_error_cleanups (register struct cleanup *old_chain) +discard_exec_error_cleanups (struct cleanup *old_chain) { discard_my_cleanups (&exec_error_cleanup_chain, old_chain); } void -discard_my_cleanups (register struct cleanup **pmy_chain, - register struct cleanup *old_chain) +discard_my_cleanups (struct cleanup **pmy_chain, + struct cleanup *old_chain) { - register struct cleanup *ptr; + struct cleanup *ptr; while ((ptr = *pmy_chain) != old_chain) { *pmy_chain = ptr->next; @@ -438,7 +425,6 @@ free_current_contents (void *ptr) In such cases, we may not be certain where the first cleanup is, unless we have a do-nothing one to always use as the base. */ -/* ARGSUSED */ void null_cleanup (void *arg) { @@ -452,7 +438,8 @@ add_continuation (void (*continuation_hook) (struct continuation_arg *), { struct continuation *continuation_ptr; - continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation)); + continuation_ptr = + (struct continuation *) xmalloc (sizeof (struct continuation)); continuation_ptr->continuation_hook = continuation_hook; continuation_ptr->arg_list = arg_list; continuation_ptr->next = cmd_continuation; @@ -482,12 +469,12 @@ do_all_continuations (void) /* Work now on the list we have set aside. */ while (continuation_ptr) - { - (continuation_ptr->continuation_hook) (continuation_ptr->arg_list); - saved_continuation = continuation_ptr; - continuation_ptr = continuation_ptr->next; - xfree (saved_continuation); - } + { + (continuation_ptr->continuation_hook) (continuation_ptr->arg_list); + saved_continuation = continuation_ptr; + continuation_ptr = continuation_ptr->next; + xfree (saved_continuation); + } } /* Walk down the cmd_continuation list, and get rid of all the @@ -514,7 +501,8 @@ add_intermediate_continuation (void (*continuation_hook) { struct continuation *continuation_ptr; - continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation)); + continuation_ptr = + (struct continuation *) xmalloc (sizeof (struct continuation)); continuation_ptr->continuation_hook = continuation_hook; continuation_ptr->arg_list = arg_list; continuation_ptr->next = intermediate_continuation; @@ -544,12 +532,12 @@ do_all_intermediate_continuations (void) /* Work now on the list we have set aside. */ while (continuation_ptr) - { - (continuation_ptr->continuation_hook) (continuation_ptr->arg_list); - saved_continuation = continuation_ptr; - continuation_ptr = continuation_ptr->next; - xfree (saved_continuation); - } + { + (continuation_ptr->continuation_hook) (continuation_ptr->arg_list); + saved_continuation = continuation_ptr; + continuation_ptr = continuation_ptr->next; + xfree (saved_continuation); + } } /* Walk down the cmd_continuation list, and get rid of all the @@ -566,9 +554,9 @@ discard_all_intermediate_continuations (void) xfree (continuation_ptr); } } - + /* Print a warning message. The first argument STRING is the warning message, used as an fprintf format string, the second is the va_list of arguments for that string. A warning is unfiltered (not @@ -586,7 +574,7 @@ vwarning (const char *string, va_list args) wrap_here (""); /* Force out any buffered output */ gdb_flush (gdb_stdout); if (warning_pre_print) - fprintf_unfiltered (gdb_stderr, warning_pre_print); + fputs_unfiltered (warning_pre_print, gdb_stderr); vfprintf_unfiltered (gdb_stderr, string, args); fprintf_unfiltered (gdb_stderr, "\n"); va_end (args); @@ -600,7 +588,7 @@ vwarning (const char *string, va_list args) does not force the return to command level. */ void -warning (const char *string,...) +warning (const char *string, ...) { va_list args; va_start (args, string); @@ -622,7 +610,7 @@ verror (const char *string, va_list args) } NORETURN void -error (const char *string,...) +error (const char *string, ...) { va_list args; va_start (args, string); @@ -636,6 +624,38 @@ do_write (void *data, const char *buffer, long length_buffer) ui_file_write (data, buffer, length_buffer); } +/* Cause a silent error to occur. Any error message is recorded + though it is not issued. */ +NORETURN void +error_silent (const char *string, ...) +{ + va_list args; + struct ui_file *tmp_stream = mem_fileopen (); + va_start (args, string); + make_cleanup_ui_file_delete (tmp_stream); + vfprintf_unfiltered (tmp_stream, string, args); + /* Copy the stream into the GDB_LASTERR buffer. */ + ui_file_rewind (gdb_lasterr); + ui_file_put (tmp_stream, do_write, gdb_lasterr); + va_end (args); + + throw_exception (RETURN_ERROR); +} + +/* Output an error message including any pre-print text to gdb_stderr. */ +void +error_output_message (char *pre_print, char *msg) +{ + target_terminal_ours (); + wrap_here (""); /* Force out any buffered output */ + gdb_flush (gdb_stdout); + annotate_error_begin (); + if (pre_print) + fputs_filtered (pre_print, gdb_stderr); + fputs_filtered (msg, gdb_stderr); + fprintf_filtered (gdb_stderr, "\n"); +} + NORETURN void error_stream (struct ui_file *stream) { @@ -652,7 +672,7 @@ error_stream (struct ui_file *stream) gdb_flush (gdb_stdout); annotate_error_begin (); if (error_pre_print) - fprintf_filtered (gdb_stderr, error_pre_print); + fputs_filtered (error_pre_print, gdb_stderr); ui_file_put (stream, do_write, gdb_stderr); fprintf_filtered (gdb_stderr, "\n"); @@ -667,7 +687,7 @@ error_last_message (void) long len; return ui_file_xstrdup (gdb_lasterr, &len); } - + /* This is to be called by main() at the very beginning */ void @@ -676,56 +696,112 @@ error_init (void) gdb_lasterr = mem_fileopen (); } -/* Print a message reporting an internal error. Ask the user if they - want to continue, dump core, or just exit. */ +/* Print a message reporting an internal error/warning. Ask the user + if they want to continue, dump core, or just exit. Return + something to indicate a quit. */ -NORETURN void -internal_verror (const char *file, int line, - const char *fmt, va_list ap) +struct internal_problem { - static char msg[] = "Internal GDB error: recursive internal error.\n"; - static int dejavu = 0; + const char *name; + /* FIXME: cagney/2002-08-15: There should be ``maint set/show'' + commands available for controlling these variables. */ + enum auto_boolean should_quit; + enum auto_boolean should_dump_core; +}; + +/* Report a problem, internal to GDB, to the user. Once the problem + has been reported, and assuming GDB didn't quit, the caller can + either allow execution to resume or throw an error. */ + +static void +internal_vproblem (struct internal_problem *problem, + const char *file, int line, const char *fmt, va_list ap) +{ + static int dejavu; int quit_p; int dump_core_p; + char *reason; - /* don't allow infinite error recursion. */ - switch (dejavu) + /* Don't allow infinite error/warning recursion. */ + { + static char msg[] = "Recursive internal problem.\n"; + switch (dejavu) + { + case 0: + dejavu = 1; + break; + case 1: + dejavu = 2; + fputs_unfiltered (msg, gdb_stderr); + abort (); /* NOTE: GDB has only three calls to abort(). */ + default: + dejavu = 3; + write (STDERR_FILENO, msg, sizeof (msg)); + exit (1); + } + } + + /* Try to get the message out and at the start of a new line. */ + target_terminal_ours (); + begin_line (); + + /* Create a string containing the full error/warning message. Need + to call query with this full string, as otherwize the reason + (error/warning) and question become separated. Format using a + style similar to a compiler error message. Include extra detail + so that the user knows that they are living on the edge. */ + { + char *msg; + xvasprintf (&msg, fmt, ap); + xasprintf (&reason, "\ +%s:%d: %s: %s\n\ +A problem internal to GDB has been detected,\n\ +further debugging may prove unreliable.", file, line, problem->name, msg); + xfree (msg); + make_cleanup (xfree, reason); + } + + switch (problem->should_quit) { - case 0: - dejavu = 1; + case AUTO_BOOLEAN_AUTO: + /* Default (yes/batch case) is to quit GDB. When in batch mode + this lessens the likelhood of GDB going into an infinate + loop. */ + quit_p = query ("%s\nQuit this debugging session? ", reason); + break; + case AUTO_BOOLEAN_TRUE: + quit_p = 1; + break; + case AUTO_BOOLEAN_FALSE: + quit_p = 0; break; - case 1: - dejavu = 2; - fputs_unfiltered (msg, gdb_stderr); - abort (); /* NOTE: GDB has only three calls to abort(). */ default: - dejavu = 3; - write (STDERR_FILENO, msg, sizeof (msg)); - exit (1); + internal_error (__FILE__, __LINE__, "bad switch"); } - /* Try to get the message out */ - target_terminal_ours (); - fprintf_unfiltered (gdb_stderr, "%s:%d: gdb-internal-error: ", file, line); - vfprintf_unfiltered (gdb_stderr, fmt, ap); - fputs_unfiltered ("\n", gdb_stderr); - - /* Default (yes/batch case) is to quit GDB. When in batch mode this - lessens the likelhood of GDB going into an infinate loop. */ - quit_p = query ("\ -An internal GDB error was detected. This may make further\n\ -debugging unreliable. Quit this debugging session? "); - - /* Default (yes/batch case) is to dump core. This leaves a GDB - dropping so that it is easier to see that something went wrong to - GDB. */ - dump_core_p = query ("\ -Create a core file containing the current state of GDB? "); + switch (problem->should_dump_core) + { + case AUTO_BOOLEAN_AUTO: + /* Default (yes/batch case) is to dump core. This leaves a GDB + `dropping' so that it is easier to see that something went + wrong in GDB. */ + dump_core_p = query ("%s\nCreate a core file of GDB? ", reason); + break; + break; + case AUTO_BOOLEAN_TRUE: + dump_core_p = 1; + break; + case AUTO_BOOLEAN_FALSE: + dump_core_p = 0; + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } if (quit_p) { if (dump_core_p) - abort (); /* NOTE: GDB has only three calls to abort(). */ + abort (); /* NOTE: GDB has only three calls to abort(). */ else exit (1); } @@ -734,11 +810,21 @@ Create a core file containing the current state of GDB? "); if (dump_core_p) { if (fork () == 0) - abort (); /* NOTE: GDB has only three calls to abort(). */ + abort (); /* NOTE: GDB has only three calls to abort(). */ } } dejavu = 0; +} + +static struct internal_problem internal_error_problem = { + "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO +}; + +NORETURN void +internal_verror (const char *file, int line, const char *fmt, va_list ap) +{ + internal_vproblem (&internal_error_problem, file, line, fmt, ap); throw_exception (RETURN_ERROR); } @@ -747,11 +833,29 @@ internal_error (const char *file, int line, const char *string, ...) { va_list ap; va_start (ap, string); - internal_verror (file, line, string, ap); va_end (ap); } +static struct internal_problem internal_warning_problem = { + "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO +}; + +void +internal_vwarning (const char *file, int line, const char *fmt, va_list ap) +{ + internal_vproblem (&internal_warning_problem, file, line, fmt, ap); +} + +void +internal_warning (const char *file, int line, const char *string, ...) +{ + va_list ap; + va_start (ap, string); + internal_vwarning (file, line, string, ap); + va_end (ap); +} + /* The strerror() function can return NULL for errno values that are out of range. Provide a "safe" version that always returns a printable string. */ @@ -762,7 +866,8 @@ safe_strerror (int errnum) char *msg; static char buf[32]; - if ((msg = strerror (errnum)) == NULL) + msg = strerror (errnum); + if (msg == NULL) { sprintf (buf, "(undocumented errno %d)", errnum); msg = buf; @@ -845,7 +950,7 @@ quit (void) /* Don't use *_filtered; we don't want to prompt the user to continue. */ if (quit_pre_print) - fprintf_unfiltered (gdb_stderr, quit_pre_print); + fputs_unfiltered (quit_pre_print, gdb_stderr); #ifdef __MSDOS__ /* No steenking SIGINT will ever be coming our way when the @@ -853,13 +958,13 @@ quit (void) fprintf_unfiltered (gdb_stderr, "Quit\n"); #else if (job_control - /* If there is no terminal switching for this target, then we can't - possibly get screwed by the lack of job control. */ + /* If there is no terminal switching for this target, then we can't + possibly get screwed by the lack of job control. */ || current_target.to_terminal_ours == NULL) fprintf_unfiltered (gdb_stderr, "Quit\n"); else fprintf_unfiltered (gdb_stderr, - "Quit (expect signal SIGINT when the program is resumed)\n"); + "Quit (expect signal SIGINT when the program is resumed)\n"); #endif throw_exception (RETURN_QUIT); } @@ -874,25 +979,16 @@ request_quit (int signo) about USG defines and stuff like that. */ signal (signo, request_quit); -#ifdef REQUEST_QUIT - REQUEST_QUIT; -#else if (immediate_quit) quit (); -#endif } /* Memory management stuff (malloc friends). */ -#if !defined (USE_MMALLOC) - -/* NOTE: These must use PTR so that their definition matches the - declaration found in "mmalloc.h". */ - static void * mmalloc (void *md, size_t size) { - return malloc (size); /* NOTE: GDB's only call to malloc() */ + return malloc (size); /* NOTE: GDB's only call to malloc() */ } static void * @@ -901,77 +997,28 @@ mrealloc (void *md, void *ptr, size_t size) if (ptr == 0) /* Guard against old realloc's */ return mmalloc (md, size); else - return realloc (ptr, size); /* NOTE: GDB's only call to ralloc() */ + return realloc (ptr, size); /* NOTE: GDB's only call to ralloc() */ } static void * mcalloc (void *md, size_t number, size_t size) { - return calloc (number, size); /* NOTE: GDB's only call to calloc() */ + return calloc (number, size); /* NOTE: GDB's only call to calloc() */ } static void mfree (void *md, void *ptr) { - free (ptr); /* NOTE: GDB's only call to free() */ + free (ptr); /* NOTE: GDB's only call to free() */ } -#endif /* USE_MMALLOC */ - -#if !defined (USE_MMALLOC) || defined (NO_MMCHECK) - +/* This used to do something interesting with USE_MMALLOC. + * It can be retired any time. -- chastain 2004-01-19. */ void init_malloc (void *md) { } -#else /* Have mmalloc and want corruption checking */ - -static void -malloc_botch (void) -{ - fprintf_unfiltered (gdb_stderr, "Memory corruption\n"); - internal_error (__FILE__, __LINE__, "failed internal consistency check"); -} - -/* Attempt to install hooks in mmalloc/mrealloc/mfree for the heap specified - by MD, to detect memory corruption. Note that MD may be NULL to specify - the default heap that grows via sbrk. - - Note that for freshly created regions, we must call mmcheckf prior to any - mallocs in the region. Otherwise, any region which was allocated prior to - installing the checking hooks, which is later reallocated or freed, will - fail the checks! The mmcheck function only allows initial hooks to be - installed before the first mmalloc. However, anytime after we have called - mmcheck the first time to install the checking hooks, we can call it again - to update the function pointer to the memory corruption handler. - - Returns zero on failure, non-zero on success. */ - -#ifndef MMCHECK_FORCE -#define MMCHECK_FORCE 0 -#endif - -void -init_malloc (void *md) -{ - if (!mmcheckf (md, malloc_botch, MMCHECK_FORCE)) - { - /* Don't use warning(), which relies on current_target being set - to something other than dummy_target, until after - initialize_all_files(). */ - - fprintf_unfiltered - (gdb_stderr, "warning: failed to install memory consistency checks; "); - fprintf_unfiltered - (gdb_stderr, "configuration should define NO_MMCHECK or MMCHECK_FORCE\n"); - } - - mmtrace (); -} - -#endif /* Have mmalloc and want corruption checking */ - /* Called when a memory allocation fails, with the number of bytes of memory requested in SIZE. */ @@ -981,12 +1028,12 @@ nomem (long size) if (size > 0) { internal_error (__FILE__, __LINE__, - "virtual memory exhausted: can't allocate %ld bytes.", size); + "virtual memory exhausted: can't allocate %ld bytes.", + size); } else { - internal_error (__FILE__, __LINE__, - "virtual memory exhausted."); + internal_error (__FILE__, __LINE__, "virtual memory exhausted."); } } @@ -1005,16 +1052,15 @@ xmmalloc (void *md, size_t size) { void *val; + /* See libiberty/xmalloc.c. This function need's to match that's + semantics. It never returns NULL. */ if (size == 0) - { - val = NULL; - } - else - { - val = mmalloc (md, size); - if (val == NULL) - nomem (size); - } + size = 1; + + val = mmalloc (md, size); + if (val == NULL) + nomem (size); + return (val); } @@ -1023,27 +1069,18 @@ xmrealloc (void *md, void *ptr, size_t size) { void *val; + /* See libiberty/xmalloc.c. This function need's to match that's + semantics. It never returns NULL. */ if (size == 0) - { - if (ptr != NULL) - mfree (md, ptr); - val = NULL; - } + size = 1; + + if (ptr != NULL) + val = mrealloc (md, ptr, size); else - { - if (ptr != NULL) - { - val = mrealloc (md, ptr, size); - } - else - { - val = mmalloc (md, size); - } - if (val == NULL) - { - nomem (size); - } - } + val = mmalloc (md, size); + if (val == NULL) + nomem (size); + return (val); } @@ -1051,14 +1088,19 @@ void * xmcalloc (void *md, size_t number, size_t size) { void *mem; + + /* See libiberty/xmalloc.c. This function need's to match that's + semantics. It never returns NULL. */ if (number == 0 || size == 0) - mem = NULL; - else { - mem = mcalloc (md, number, size); - if (mem == NULL) - nomem (number * size); + number = 1; + size = 1; } + + mem = mcalloc (md, number, size); + if (mem == NULL) + nomem (number * size); + return mem; } @@ -1080,19 +1122,19 @@ xmfree (void *md, void *ptr) /* NOTE: These are declared using PTR to ensure consistency with "libiberty.h". xfree() is GDB local. */ -PTR +PTR /* OK: PTR */ xmalloc (size_t size) { return xmmalloc (NULL, size); } -PTR -xrealloc (PTR ptr, size_t size) +PTR /* OK: PTR */ +xrealloc (PTR ptr, size_t size) /* OK: PTR */ { return xmrealloc (NULL, ptr, size); } -PTR +PTR /* OK: PTR */ xcalloc (size_t number, size_t size) { return xmcalloc (NULL, number, size); @@ -1108,6 +1150,17 @@ xfree (void *ptr) /* Like asprintf/vasprintf but get an internal_error if the call fails. */ +char * +xstrprintf (const char *format, ...) +{ + char *ret; + va_list args; + va_start (args, format); + xvasprintf (&ret, format, args); + va_end (args); + return ret; +} + void xasprintf (char **ret, const char *format, ...) { @@ -1125,14 +1178,12 @@ xvasprintf (char **ret, const char *format, va_list ap) badly format string; or something else. */ if ((*ret) == NULL) internal_error (__FILE__, __LINE__, - "vasprintf returned NULL buffer (errno %d)", - errno); + "vasprintf returned NULL buffer (errno %d)", errno); /* A negative status with a non-NULL buffer shouldn't never happen. But to be sure. */ if (status < 0) internal_error (__FILE__, __LINE__, - "vasprintf call failed (errno %d)", - errno); + "vasprintf call failed (errno %d)", errno); } @@ -1142,7 +1193,7 @@ xvasprintf (char **ret, const char *format, va_list ap) int myread (int desc, char *addr, int len) { - register int val; + int val; int orglen = len; while (len > 0) @@ -1165,7 +1216,7 @@ myread (int desc, char *addr, int len) char * savestring (const char *ptr, size_t size) { - register char *p = (char *) xmalloc (size + 1); + char *p = (char *) xmalloc (size + 1); memcpy (p, ptr, size); p[size] = 0; return p; @@ -1174,7 +1225,7 @@ savestring (const char *ptr, size_t size) char * msavestring (void *md, const char *ptr, size_t size) { - register char *p = (char *) xmmalloc (md, size + 1); + char *p = (char *) xmmalloc (md, size + 1); memcpy (p, ptr, size); p[size] = 0; return p; @@ -1187,7 +1238,7 @@ mstrsave (void *md, const char *ptr) } void -print_spaces (register int n, register struct ui_file *file) +print_spaces (int n, struct ui_file *file) { fputs_unfiltered (n_spaces (n), file); } @@ -1195,7 +1246,7 @@ print_spaces (register int n, register struct ui_file *file) /* Print a host address. */ void -gdb_print_host_address (void *addr, struct ui_file *stream) +gdb_print_host_address (const void *addr, struct ui_file *stream) { /* We could use the %p conversion specifier to fprintf if we had any @@ -1212,11 +1263,11 @@ gdb_print_host_address (void *addr, struct ui_file *stream) /* VARARGS */ int -query (const char *ctlstr,...) +query (const char *ctlstr, ...) { va_list args; - register int answer; - register int ans2; + int answer; + int ans2; int retval; va_start (args, ctlstr); @@ -1258,7 +1309,7 @@ query (const char *ctlstr,...) if (answer != '\n') do { - ans2 = fgetc (stdin); + ans2 = fgetc (stdin); clearerr (stdin); } while (ans2 != EOF && ans2 != '\n' && ans2 != '\r'); @@ -1284,6 +1335,162 @@ query (const char *ctlstr,...) } +/* This function supports the nquery() and yquery() functions. + Ask user a y-or-n question and return 0 if answer is no, 1 if + answer is yes, or default the answer to the specified default. + DEFCHAR is either 'y' or 'n' and refers to the default answer. + CTLSTR is the control string and should end in "? ". It should + not say how to answer, because we do that. + ARGS are the arguments passed along with the CTLSTR argument to + printf. */ + +static int +defaulted_query (const char *ctlstr, const char defchar, va_list args) +{ + int answer; + int ans2; + int retval; + int def_value; + char def_answer, not_def_answer; + char *y_string, *n_string; + + /* Set up according to which answer is the default. */ + if (defchar == 'y') + { + def_value = 1; + def_answer = 'Y'; + not_def_answer = 'N'; + y_string = "[y]"; + n_string = "n"; + } + else + { + def_value = 0; + def_answer = 'N'; + not_def_answer = 'Y'; + y_string = "y"; + n_string = "[n]"; + } + + if (query_hook) + { + return query_hook (ctlstr, args); + } + + /* Automatically answer default value if input is not from a terminal. */ + if (!input_from_terminal_p ()) + return def_value; + + while (1) + { + wrap_here (""); /* Flush any buffered output */ + gdb_flush (gdb_stdout); + + if (annotation_level > 1) + printf_filtered ("\n\032\032pre-query\n"); + + vfprintf_filtered (gdb_stdout, ctlstr, args); + printf_filtered ("(%s or %s) ", y_string, n_string); + + if (annotation_level > 1) + printf_filtered ("\n\032\032query\n"); + + wrap_here (""); + gdb_flush (gdb_stdout); + + answer = fgetc (stdin); + clearerr (stdin); /* in case of C-d */ + if (answer == EOF) /* C-d */ + { + retval = def_value; + break; + } + /* Eat rest of input line, to EOF or newline */ + if (answer != '\n') + do + { + ans2 = fgetc (stdin); + clearerr (stdin); + } + while (ans2 != EOF && ans2 != '\n' && ans2 != '\r'); + + if (answer >= 'a') + answer -= 040; + /* Check answer. For the non-default, the user must specify + the non-default explicitly. */ + if (answer == not_def_answer) + { + retval = !def_value; + break; + } + /* Otherwise, for the default, the user may either specify + the required input or have it default by entering nothing. */ + if (answer == def_answer || answer == '\n' || + answer == '\r' || answer == EOF) + { + retval = def_value; + break; + } + /* Invalid entries are not defaulted and require another selection. */ + printf_filtered ("Please answer %s or %s.\n", + y_string, n_string); + } + + if (annotation_level > 1) + printf_filtered ("\n\032\032post-query\n"); + return retval; +} + + +/* Ask user a y-or-n question and return 0 if answer is no, 1 if + answer is yes, or 0 if answer is defaulted. + Takes three args which are given to printf to print the question. + The first, a control string, should end in "? ". + It should not say how to answer, because we do that. */ + +int +nquery (const char *ctlstr, ...) +{ + va_list args; + + va_start (args, ctlstr); + return defaulted_query (ctlstr, 'n', args); + va_end (args); +} + +/* Ask user a y-or-n question and return 0 if answer is no, 1 if + answer is yes, or 1 if answer is defaulted. + Takes three args which are given to printf to print the question. + The first, a control string, should end in "? ". + It should not say how to answer, because we do that. */ + +int +yquery (const char *ctlstr, ...) +{ + va_list args; + + va_start (args, ctlstr); + return defaulted_query (ctlstr, 'y', args); + va_end (args); +} + +/* Print an error message saying that we couldn't make sense of a + \^mumble sequence in a string or character constant. START and END + indicate a substring of some larger string that contains the + erroneous backslash sequence, missing the initial backslash. */ +static NORETURN int +no_control_char_error (const char *start, const char *end) +{ + int len = end - start; + char *copy = alloca (end - start + 1); + + memcpy (copy, start, len); + copy[len] = '\0'; + + error ("There is no control character `\\%s' in the `%s' character set.", + copy, target_charset ()); +} + /* Parse a C escape sequence. STRING_PTR points to a variable containing a pointer to the string to parse. That pointer should point to the character after the \. That pointer @@ -1302,67 +1509,91 @@ query (const char *ctlstr,...) int parse_escape (char **string_ptr) { - register int c = *(*string_ptr)++; - switch (c) - { - case 'a': - return 007; /* Bell (alert) char */ - case 'b': - return '\b'; - case 'e': /* Escape character */ - return 033; - case 'f': - return '\f'; - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case 'v': - return '\v'; - case '\n': - return -2; - case 0: - (*string_ptr)--; - return 0; - case '^': - c = *(*string_ptr)++; - if (c == '\\') - c = parse_escape (string_ptr); - if (c == '?') - return 0177; - return (c & 0200) | (c & 037); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': + int target_char; + int c = *(*string_ptr)++; + if (c_parse_backslash (c, &target_char)) + return target_char; + else + switch (c) { - register int i = c - '0'; - register int count = 0; - while (++count < 3) - { - if ((c = *(*string_ptr)++) >= '0' && c <= '7') - { - i *= 8; - i += c - '0'; - } - else - { - (*string_ptr)--; - break; - } - } - return i; + case '\n': + return -2; + case 0: + (*string_ptr)--; + return 0; + case '^': + { + /* Remember where this escape sequence started, for reporting + errors. */ + char *sequence_start_pos = *string_ptr - 1; + + c = *(*string_ptr)++; + + if (c == '?') + { + /* XXXCHARSET: What is `delete' in the host character set? */ + c = 0177; + + if (!host_char_to_target (c, &target_char)) + error ("There is no character corresponding to `Delete' " + "in the target character set `%s'.", host_charset ()); + + return target_char; + } + else if (c == '\\') + target_char = parse_escape (string_ptr); + else + { + if (!host_char_to_target (c, &target_char)) + no_control_char_error (sequence_start_pos, *string_ptr); + } + + /* Now target_char is something like `c', and we want to find + its control-character equivalent. */ + if (!target_char_to_control_char (target_char, &target_char)) + no_control_char_error (sequence_start_pos, *string_ptr); + + return target_char; + } + + /* XXXCHARSET: we need to use isdigit and value-of-digit + methods of the host character set here. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int i = c - '0'; + int count = 0; + while (++count < 3) + { + c = (**string_ptr); + if (c >= '0' && c <= '7') + { + (*string_ptr)++; + i *= 8; + i += c - '0'; + } + else + { + break; + } + } + return i; + } + default: + if (!host_char_to_target (c, &target_char)) + error + ("The escape sequence `\%c' is equivalent to plain `%c', which" + " has no equivalent\n" "in the `%s' character set.", c, c, + target_charset ()); + return target_char; } - default: - return c; - } } /* Print the character C on STREAM as part of the contents of a literal @@ -1438,19 +1669,21 @@ fputstr_unfiltered (const char *str, int quoter, struct ui_file *stream) } void -fputstrn_unfiltered (const char *str, int n, int quoter, struct ui_file *stream) +fputstrn_unfiltered (const char *str, int n, int quoter, + struct ui_file *stream) { int i; for (i = 0; i < n; i++) printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter); } - /* Number of lines per page or UINT_MAX if paging is disabled. */ static unsigned int lines_per_page; + /* Number of chars per line or UINT_MAX if line folding is disabled. */ static unsigned int chars_per_line; + /* Current count of lines printed on this page, chars on this line. */ static unsigned int lines_printed, chars_printed; @@ -1479,7 +1712,8 @@ static char *wrap_indent; static int wrap_column; -/* Inialize the lines and chars per page */ +/* Inialize the number of lines per page and chars per line. */ + void init_page_info (void) { @@ -1487,68 +1721,67 @@ init_page_info (void) if (!tui_get_command_dimension (&chars_per_line, &lines_per_page)) #endif { - /* These defaults will be used if we are unable to get the correct - values from termcap. */ + int rows, cols; + #if defined(__GO32__) - lines_per_page = ScreenRows (); - chars_per_line = ScreenCols (); + rows = ScreenRows (); + cols = ScreenCols (); + lines_per_page = rows; + chars_per_line = cols; #else - lines_per_page = 24; - chars_per_line = 80; + /* Make sure Readline has initialized its terminal settings. */ + rl_reset_terminal (NULL); -#if !defined (_WIN32) - /* No termcap under MPW, although might be cool to do something - by looking at worksheet or console window sizes. */ - /* Initialize the screen height and width from termcap. */ - { - char *termtype = getenv ("TERM"); + /* Get the screen size from Readline. */ + rl_get_screen_size (&rows, &cols); + lines_per_page = rows; + chars_per_line = cols; - /* Positive means success, nonpositive means failure. */ - int status; - - /* 2048 is large enough for all known terminals, according to the - GNU termcap manual. */ - char term_buffer[2048]; - - if (termtype) - { - status = tgetent (term_buffer, termtype); - if (status > 0) - { - int val; - int running_in_emacs = getenv ("EMACS") != NULL; - - val = tgetnum ("li"); - if (val >= 0 && !running_in_emacs) - lines_per_page = val; - else - /* The number of lines per page is not mentioned - in the terminal description. This probably means - that paging is not useful (e.g. emacs shell window), - so disable paging. */ - lines_per_page = UINT_MAX; - - val = tgetnum ("co"); - if (val >= 0) - chars_per_line = val; - } - } - } -#endif /* MPW */ + /* Readline should have fetched the termcap entry for us. */ + if (tgetnum ("li") < 0 || getenv ("EMACS")) + { + /* The number of lines per page is not mentioned in the + terminal description. This probably means that paging is + not useful (e.g. emacs shell window), so disable paging. */ + lines_per_page = UINT_MAX; + } + /* FIXME: Get rid of this junk. */ #if defined(SIGWINCH) && defined(SIGWINCH_HANDLER) - - /* If there is a better way to determine the window size, use it. */ SIGWINCH_HANDLER (SIGWINCH); #endif -#endif + /* If the output is not a terminal, don't paginate it. */ if (!ui_file_isatty (gdb_stdout)) lines_per_page = UINT_MAX; - } /* the command_line_version */ +#endif + } + + set_screen_size (); set_width (); } +/* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE. */ + +static void +set_screen_size (void) +{ + int rows = lines_per_page; + int cols = chars_per_line; + + if (rows <= 0) + rows = INT_MAX; + + if (cols <= 0) + rl_get_screen_size (NULL, &cols); + + /* Update Readline's idea of the terminal size. */ + rl_set_screen_size (rows, cols); +} + +/* Reinitialize WRAP_BUFFER according to the current value of + CHARS_PER_LINE. */ + static void set_width (void) { @@ -1562,16 +1795,22 @@ set_width (void) } else wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2); - wrap_pointer = wrap_buffer; /* Start it at the beginning */ + wrap_pointer = wrap_buffer; /* Start it at the beginning. */ } -/* ARGSUSED */ static void set_width_command (char *args, int from_tty, struct cmd_list_element *c) { + set_screen_size (); set_width (); } +static void +set_height_command (char *args, int from_tty, struct cmd_list_element *c) +{ + set_screen_size (); +} + /* Wait, so the user can read what's on the screen. Prompt the user to continue by pressing RETURN. */ @@ -1605,7 +1844,7 @@ prompt_for_continue (void) /* Call readline, not gdb_readline, because GO32 readline handles control-C whereas control-C to gdb_readline will cause the user to get dumped out to DOS. */ - ignore = readline (cont_prompt); + ignore = gdb_readline_wrapper (cont_prompt); if (annotation_level > 1) printf_unfiltered ("\n\032\032post-prompt-for-continue\n"); @@ -1698,6 +1937,51 @@ wrap_here (char *indent) } } +/* Print input string to gdb_stdout, filtered, with wrap, + arranging strings in columns of n chars. String can be + right or left justified in the column. Never prints + trailing spaces. String should never be longer than + width. FIXME: this could be useful for the EXAMINE + command, which currently doesn't tabulate very well */ + +void +puts_filtered_tabular (char *string, int width, int right) +{ + int spaces = 0; + int stringlen; + char *spacebuf; + + gdb_assert (chars_per_line > 0); + if (chars_per_line == UINT_MAX) + { + fputs_filtered (string, gdb_stdout); + fputs_filtered ("\n", gdb_stdout); + return; + } + + if (((chars_printed - 1) / width + 2) * width >= chars_per_line) + fputs_filtered ("\n", gdb_stdout); + + if (width >= chars_per_line) + width = chars_per_line - 1; + + stringlen = strlen (string); + + if (chars_printed > 0) + spaces = width - (chars_printed - 1) % width - 1; + if (right) + spaces += width - stringlen; + + spacebuf = alloca (spaces + 1); + spacebuf[spaces] = '\0'; + while (spaces--) + spacebuf[spaces] = ' '; + + fputs_filtered (spacebuf, gdb_stdout); + fputs_filtered (string, gdb_stdout); +} + + /* Ensure that whatever gets printed next, using the filtered output commands, starts at the beginning of the line. I.E. if there is any pending output for the current line, flush it and start a new @@ -1751,8 +2035,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream, while (*lineptr) { /* Possible new page. */ - if (filter && - (lines_printed >= lines_per_page - 1)) + if (filter && (lines_printed >= lines_per_page - 1)) prompt_for_continue (); while (*lineptr && *lineptr != '\n') @@ -1800,7 +2083,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream, if (wrap_column) { fputs_unfiltered (wrap_indent, stream); - *wrap_pointer = '\0'; /* Null-terminate saved stuff */ + *wrap_pointer = '\0'; /* Null-terminate saved stuff */ fputs_unfiltered (wrap_buffer, stream); /* and eject it */ /* FIXME, this strlen is what prevents wrap_indent from containing tabs. However, if we recurse to print it @@ -2014,7 +2297,7 @@ vprintf_unfiltered (const char *format, va_list args) } void -fprintf_filtered (struct ui_file * stream, const char *format,...) +fprintf_filtered (struct ui_file *stream, const char *format, ...) { va_list args; va_start (args, format); @@ -2023,7 +2306,7 @@ fprintf_filtered (struct ui_file * stream, const char *format,...) } void -fprintf_unfiltered (struct ui_file * stream, const char *format,...) +fprintf_unfiltered (struct ui_file *stream, const char *format, ...) { va_list args; va_start (args, format); @@ -2035,7 +2318,8 @@ fprintf_unfiltered (struct ui_file * stream, const char *format,...) Called as fprintfi_filtered (spaces, stream, format, ...); */ void -fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...) +fprintfi_filtered (int spaces, struct ui_file *stream, const char *format, + ...) { va_list args; va_start (args, format); @@ -2047,7 +2331,7 @@ fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...) void -printf_filtered (const char *format,...) +printf_filtered (const char *format, ...) { va_list args; va_start (args, format); @@ -2057,7 +2341,7 @@ printf_filtered (const char *format,...) void -printf_unfiltered (const char *format,...) +printf_unfiltered (const char *format, ...) { va_list args; va_start (args, format); @@ -2069,7 +2353,7 @@ printf_unfiltered (const char *format,...) Called as printfi_filtered (spaces, format, ...); */ void -printfi_filtered (int spaces, const char *format,...) +printfi_filtered (int spaces, const char *format, ...) { va_list args; va_start (args, format); @@ -2125,7 +2409,7 @@ print_spaces_filtered (int n, struct ui_file *stream) fputs_filtered (n_spaces (n), stream); } -/* C++ demangler stuff. */ +/* C++/ObjC demangler stuff. */ /* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language LANG, using demangling args ARG_MODE, and print it filtered to STREAM. @@ -2133,8 +2417,8 @@ print_spaces_filtered (int n, struct ui_file *stream) demangling is off, the name is printed in its "raw" form. */ void -fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang, - int arg_mode) +fprintf_symbol_filtered (struct ui_file *stream, char *name, + enum language lang, int arg_mode) { char *demangled; @@ -2147,21 +2431,7 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang, } else { - switch (lang) - { - case language_cplus: - demangled = cplus_demangle (name, arg_mode); - break; - case language_java: - demangled = cplus_demangle (name, arg_mode | DMGL_JAVA); - break; - case language_chill: - demangled = chill_demangle (name); - break; - default: - demangled = NULL; - break; - } + demangled = language_demangle (language_def (lang), name, arg_mode); fputs_filtered (demangled ? demangled : name, stream); if (demangled != NULL) { @@ -2205,6 +2475,94 @@ strcmp_iw (const char *string1, const char *string2) } return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0'); } + +/* This is like strcmp except that it ignores whitespace and treats + '(' as the first non-NULL character in terms of ordering. Like + strcmp (and unlike strcmp_iw), it returns negative if STRING1 < + STRING2, 0 if STRING2 = STRING2, and positive if STRING1 > STRING2 + according to that ordering. + + If a list is sorted according to this function and if you want to + find names in the list that match some fixed NAME according to + strcmp_iw(LIST_ELT, NAME), then the place to start looking is right + where this function would put NAME. + + Here are some examples of why using strcmp to sort is a bad idea: + + Whitespace example: + + Say your partial symtab contains: "foo", "goo". Then, if + we try to do a search for "foo", strcmp will locate this + after "foo" and before "goo". Then lookup_partial_symbol + will start looking at strings beginning with "goo", and will never + see the correct match of "foo". + + Parenthesis example: + + In practice, this is less like to be an issue, but I'll give it a + shot. Let's assume that '$' is a legitimate character to occur in + symbols. (Which may well even be the case on some systems.) Then + say that the partial symbol table contains "foo$" and "foo(int)". + strcmp will put them in this order, since '$' < '('. Now, if the + user searches for "foo", then strcmp will sort "foo" before "foo$". + Then lookup_partial_symbol will notice that strcmp_iw("foo$", + "foo") is false, so it won't proceed to the actual match of + "foo(int)" with "foo". */ + +int +strcmp_iw_ordered (const char *string1, const char *string2) +{ + while ((*string1 != '\0') && (*string2 != '\0')) + { + while (isspace (*string1)) + { + string1++; + } + while (isspace (*string2)) + { + string2++; + } + if (*string1 != *string2) + { + break; + } + if (*string1 != '\0') + { + string1++; + string2++; + } + } + + switch (*string1) + { + /* Characters are non-equal unless they're both '\0'; we want to + make sure we get the comparison right according to our + comparison in the cases where one of them is '\0' or '('. */ + case '\0': + if (*string2 == '\0') + return 0; + else + return -1; + case '(': + if (*string2 == '\0') + return 1; + else + return -1; + default: + if (*string2 == '(') + return 1; + else + return *string1 - *string2; + } +} + +/* A simple comparison function with opposite semantics to strcmp. */ + +int +streq (const char *lhs, const char *rhs) +{ + return !strcmp (lhs, rhs); +} /* @@ -2217,11 +2575,11 @@ int subset_compare (char *string_to_compare, char *template_string) { int match; - if (template_string != (char *) NULL && string_to_compare != (char *) NULL && - strlen (string_to_compare) <= strlen (template_string)) - match = (strncmp (template_string, - string_to_compare, - strlen (string_to_compare)) == 0); + if (template_string != (char *) NULL && string_to_compare != (char *) NULL + && strlen (string_to_compare) <= strlen (template_string)) + match = + (strncmp + (template_string, string_to_compare, strlen (string_to_compare)) == 0); else match = 0; return match; @@ -2248,39 +2606,29 @@ initialize_utils (void) { struct cmd_list_element *c; - c = add_set_cmd ("width", class_support, var_uinteger, - (char *) &chars_per_line, + c = add_set_cmd ("width", class_support, var_uinteger, &chars_per_line, "Set number of characters gdb thinks are in a line.", &setlist); add_show_from_set (c, &showlist); set_cmd_sfunc (c, set_width_command); - add_show_from_set - (add_set_cmd ("height", class_support, - var_uinteger, (char *) &lines_per_page, - "Set number of lines gdb thinks are in a page.", &setlist), - &showlist); + c = add_set_cmd ("height", class_support, var_uinteger, &lines_per_page, + "Set number of lines gdb thinks are in a page.", &setlist); + add_show_from_set (c, &showlist); + set_cmd_sfunc (c, set_height_command); init_page_info (); - /* If the output is not a terminal, don't paginate it. */ - if (!ui_file_isatty (gdb_stdout)) - lines_per_page = UINT_MAX; - - set_width_command ((char *) NULL, 0, c); - add_show_from_set (add_set_cmd ("demangle", class_support, var_boolean, (char *) &demangle, - "Set demangling of encoded C++ names when displaying symbols.", - &setprintlist), - &showprintlist); + "Set demangling of encoded C++/ObjC names when displaying symbols.", + &setprintlist), &showprintlist); add_show_from_set (add_set_cmd ("pagination", class_support, var_boolean, (char *) &pagination_enabled, - "Set state of pagination.", &setlist), - &showlist); + "Set state of pagination.", &setlist), &showlist); if (xdb_commands) { @@ -2294,15 +2642,13 @@ initialize_utils (void) (add_set_cmd ("sevenbit-strings", class_support, var_boolean, (char *) &sevenbit_strings, "Set printing of 8-bit characters in strings as \\nnn.", - &setprintlist), - &showprintlist); + &setprintlist), &showprintlist); add_show_from_set (add_set_cmd ("asm-demangle", class_support, var_boolean, (char *) &asm_demangle, - "Set demangling of C++ names in disassembly listings.", - &setprintlist), - &showprintlist); + "Set demangling of C++/ObjC names in disassembly listings.", + &setprintlist), &showprintlist); } /* Machine specific function to handle SIGWINCH signal. */ @@ -2310,9 +2656,7 @@ initialize_utils (void) #ifdef SIGWINCH_HANDLER_BODY SIGWINCH_HANDLER_BODY #endif - /* print routines to handle variable size regs, etc. */ - /* temporary storage using circular buffer */ #define NUMCELLS 16 #define CELLSIZE 32 @@ -2361,19 +2705,17 @@ decimal2str (char *paddr_str, char *sign, ULONGEST addr) switch (i) { case 1: - sprintf (paddr_str, "%s%lu", - sign, temp[0]); + sprintf (paddr_str, "%s%lu", sign, temp[0]); break; case 2: - sprintf (paddr_str, "%s%lu%09lu", - sign, temp[1], temp[0]); + sprintf (paddr_str, "%s%lu%09lu", sign, temp[1], temp[0]); break; case 3: - sprintf (paddr_str, "%s%lu%09lu%09lu", - sign, temp[2], temp[1], temp[0]); + sprintf (paddr_str, "%s%lu%09lu%09lu", sign, temp[2], temp[1], temp[0]); break; default: - internal_error (__FILE__, __LINE__, "failed internal consistency check"); + internal_error (__FILE__, __LINE__, + "failed internal consistency check"); } } @@ -2439,8 +2781,7 @@ phex_nz (ULONGEST l, int sizeof_l) if (high == 0) sprintf (str, "%lx", (unsigned long) (l & 0xffffffff)); else - sprintf (str, "%lx%08lx", - high, (unsigned long) (l & 0xffffffff)); + sprintf (str, "%lx%08lx", high, (unsigned long) (l & 0xffffffff)); break; } case 4: @@ -2459,28 +2800,6 @@ phex_nz (ULONGEST l, int sizeof_l) } -/* Convert to / from the hosts pointer to GDB's internal CORE_ADDR - using the target's conversion routines. */ -CORE_ADDR -host_pointer_to_address (void *ptr) -{ - if (sizeof (ptr) != TYPE_LENGTH (builtin_type_void_data_ptr)) - internal_error (__FILE__, __LINE__, - "core_addr_to_void_ptr: bad cast"); - return POINTER_TO_ADDRESS (builtin_type_void_data_ptr, &ptr); -} - -void * -address_to_host_pointer (CORE_ADDR addr) -{ - void *ptr; - if (sizeof (ptr) != TYPE_LENGTH (builtin_type_void_data_ptr)) - internal_error (__FILE__, __LINE__, - "core_addr_to_void_ptr: bad cast"); - ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr); - return ptr; -} - /* Convert a CORE_ADDR into a string. */ const char * core_addr_to_string (const CORE_ADDR addr) @@ -2513,7 +2832,7 @@ string_to_core_addr (const char *my_string) { if (isdigit (my_string[i])) addr = (my_string[i] - '0') + (addr * 16); - else if (isxdigit (my_string[i])) + else if (isxdigit (my_string[i])) addr = (tolower (my_string[i]) - 'a' + 0xa) + (addr * 16); else internal_error (__FILE__, __LINE__, "invalid hex"); @@ -2537,29 +2856,204 @@ string_to_core_addr (const char *my_string) char * gdb_realpath (const char *filename) { + /* Method 1: The system has a compile time upper bound on a filename + path. Use that and realpath() to canonicalize the name. This is + the most common case. Note that, if there isn't a compile time + upper bound, you want to avoid realpath() at all costs. */ #if defined(HAVE_REALPATH) + { # if defined (PATH_MAX) - char buf[PATH_MAX]; + char buf[PATH_MAX]; # define USE_REALPATH # elif defined (MAXPATHLEN) - char buf[MAXPATHLEN]; -# define USE_REALPATH -# elif defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA) - char *buf = alloca ((size_t)pathconf ("/", _PC_PATH_MAX)); + char buf[MAXPATHLEN]; # define USE_REALPATH # endif +# if defined (USE_REALPATH) + const char *rp = realpath (filename, buf); + if (rp == NULL) + rp = filename; + return xstrdup (rp); +# endif + } #endif /* HAVE_REALPATH */ -#if defined(USE_REALPATH) - char *rp = realpath (filename, buf); - return xstrdup (rp ? rp : filename); -#elif defined(HAVE_CANONICALIZE_FILE_NAME) - char *rp = canonicalize_file_name (filename); - if (rp == NULL) - return xstrdup (filename); - else - return rp; -#else - return xstrdup (filename); + /* Method 2: The host system (i.e., GNU) has the function + canonicalize_file_name() which malloc's a chunk of memory and + returns that, use that. */ +#if defined(HAVE_CANONICALIZE_FILE_NAME) + { + char *rp = canonicalize_file_name (filename); + if (rp == NULL) + return xstrdup (filename); + else + return rp; + } #endif + + /* FIXME: cagney/2002-11-13: + + Method 2a: Use realpath() with a NULL buffer. Some systems, due + to the problems described in in method 3, have modified their + realpath() implementation so that it will allocate a buffer when + NULL is passed in. Before this can be used, though, some sort of + configure time test would need to be added. Otherwize the code + will likely core dump. */ + + /* Method 3: Now we're getting desperate! The system doesn't have a + compile time buffer size and no alternative function. Query the + OS, using pathconf(), for the buffer limit. Care is needed + though, some systems do not limit PATH_MAX (return -1 for + pathconf()) making it impossible to pass a correctly sized buffer + to realpath() (it could always overflow). On those systems, we + skip this. */ +#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA) + { + /* Find out the max path size. */ + long path_max = pathconf ("/", _PC_PATH_MAX); + if (path_max > 0) + { + /* PATH_MAX is bounded. */ + char *buf = alloca (path_max); + char *rp = realpath (filename, buf); + return xstrdup (rp ? rp : filename); + } + } +#endif + + /* This system is a lost cause, just dup the buffer. */ + return xstrdup (filename); +} + +/* Return a copy of FILENAME, with its directory prefix canonicalized + by gdb_realpath. */ + +char * +xfullpath (const char *filename) +{ + const char *base_name = lbasename (filename); + char *dir_name; + char *real_path; + char *result; + + /* Extract the basename of filename, and return immediately + a copy of filename if it does not contain any directory prefix. */ + if (base_name == filename) + return xstrdup (filename); + + dir_name = alloca ((size_t) (base_name - filename + 2)); + /* Allocate enough space to store the dir_name + plus one extra + character sometimes needed under Windows (see below), and + then the closing \000 character */ + strncpy (dir_name, filename, base_name - filename); + dir_name[base_name - filename] = '\000'; + +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* We need to be careful when filename is of the form 'd:foo', which + is equivalent of d:./foo, which is totally different from d:/foo. */ + if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') + { + dir_name[2] = '.'; + dir_name[3] = '\000'; + } +#endif + + /* Canonicalize the directory prefix, and build the resulting + filename. If the dirname realpath already contains an ending + directory separator, avoid doubling it. */ + real_path = gdb_realpath (dir_name); + if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) + result = concat (real_path, base_name, NULL); + else + result = concat (real_path, SLASH_STRING, base_name, NULL); + + xfree (real_path); + return result; +} + + +/* This is the 32-bit CRC function used by the GNU separate debug + facility. An executable may contain a section named + .gnu_debuglink, which holds the name of a separate executable file + containing its debug info, and a checksum of that file's contents, + computed using this function. */ +unsigned long +gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len) +{ + static const unsigned long crc32_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d + }; + unsigned char *end; + + crc = ~crc & 0xffffffff; + for (end = buf + len; buf < end; ++buf) + crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); + return ~crc & 0xffffffff;; +} + +ULONGEST +align_up (ULONGEST v, int n) +{ + /* Check that N is really a power of two. */ + gdb_assert (n && (n & (n-1)) == 0); + return (v + n - 1) & -n; +} + +ULONGEST +align_down (ULONGEST v, int n) +{ + /* Check that N is really a power of two. */ + gdb_assert (n && (n & (n-1)) == 0); + return (v & -n); } diff --git a/contrib/gdb/gdb/uw-thread.c b/contrib/gdb/gdb/uw-thread.c index 617cfbd9f81..cc6ed6daf4c 100755 --- a/contrib/gdb/gdb/uw-thread.c +++ b/contrib/gdb/gdb/uw-thread.c @@ -116,6 +116,14 @@ /* Prototypes for supply_gregset etc. */ #include "gregset.h" +/* Offset from SP to first arg on stack at first instruction of a + function. We provide a default here that's right for most, if not + all, targets that use this file. */ + +#ifndef SP_ARG0 +#define SP_ARG0 (1 * 4) +#endif + /* Whether to emit debugging output. */ #define DEBUG 0 diff --git a/contrib/gdb/gdb/valarith.c b/contrib/gdb/gdb/valarith.c index 5852ac6a8a1..03282eade74 100644 --- a/contrib/gdb/gdb/valarith.c +++ b/contrib/gdb/gdb/valarith.c @@ -1,7 +1,8 @@ /* Perform arithmetic and other operations on values, for GDB. + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software + Foundation, Inc. This file is part of GDB. @@ -30,6 +31,7 @@ #include "gdb_string.h" #include "doublest.h" #include +#include "infcall.h" /* Define whether or not the C operator '/' truncates towards zero for differently signed operands (truncation direction is undefined in C). */ @@ -43,12 +45,50 @@ static struct value *value_subscripted_rvalue (struct value *, struct value *, i void _initialize_valarith (void); +/* Given a pointer, return the size of its target. + If the pointer type is void *, then return 1. + If the target type is incomplete, then error out. + This isn't a general purpose function, but just a + helper for value_sub & value_add. +*/ + +static LONGEST +find_size_for_pointer_math (struct type *ptr_type) +{ + LONGEST sz = -1; + struct type *ptr_target; + + ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type)); + + sz = TYPE_LENGTH (ptr_target); + if (sz == 0) + { + if (TYPE_CODE (ptr_type) == TYPE_CODE_VOID) + sz = 1; + else + { + char *name; + + name = TYPE_NAME (ptr_target); + if (name == NULL) + name = TYPE_TAG_NAME (ptr_target); + if (name == NULL) + error ("Cannot perform pointer math on incomplete types, " + "try casting to a known type, or void *."); + else + error ("Cannot perform pointer math on incomplete type \"%s\", " + "try casting to a known type, or void *.", name); + } + } + return sz; +} + struct value * value_add (struct value *arg1, struct value *arg2) { struct value *valint; struct value *valptr; - register int len; + LONGEST sz; struct type *type1, *type2, *valptrtype; COERCE_NUMBER (arg1); @@ -77,12 +117,12 @@ value_add (struct value *arg1, struct value *arg2) valint = arg1; valptrtype = type2; } - len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype))); - if (len == 0) - len = 1; /* For (void *) */ + + sz = find_size_for_pointer_math (valptrtype); + retval = value_from_pointer (valptrtype, value_as_address (valptr) - + (len * value_as_long (valint))); + + (sz * value_as_long (valint))); VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr); return retval; } @@ -104,7 +144,8 @@ value_sub (struct value *arg1, struct value *arg2) if (TYPE_CODE (type2) == TYPE_CODE_INT) { /* pointer - integer. */ - LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); + LONGEST sz = find_size_for_pointer_math (type1); + return value_from_pointer (type1, (value_as_address (arg1) - (sz * value_as_long (arg2)))); @@ -236,6 +277,7 @@ value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound else VALUE_LVAL (v) = VALUE_LVAL (array); VALUE_ADDRESS (v) = VALUE_ADDRESS (array); + VALUE_REGNO (v) = VALUE_REGNO (array); VALUE_OFFSET (v) = VALUE_OFFSET (array) + elt_offs; return v; } @@ -759,7 +801,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) case BINOP_EXP: v = pow (v1, v2); if (errno) - error ("Cannot perform exponentiation: %s", strerror (errno)); + error ("Cannot perform exponentiation: %s", safe_strerror (errno)); break; default: @@ -820,7 +862,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) /* Integral operations here. */ /* FIXME: Also mixed integral/booleans, with result an integer. */ /* FIXME: This implements ANSI C rules (also correct for C++). - What about FORTRAN and chill? */ + What about FORTRAN and (the deleted) chill ? */ { unsigned int promoted_len1 = TYPE_LENGTH (type1); unsigned int promoted_len2 = TYPE_LENGTH (type2); @@ -897,7 +939,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) case BINOP_EXP: v = pow (v1, v2); if (errno) - error ("Cannot perform exponentiation: %s", strerror (errno)); + error ("Cannot perform exponentiation: %s", safe_strerror (errno)); break; case BINOP_REM: @@ -907,12 +949,6 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) case BINOP_MOD: /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, v1 mod 0 has a defined value, v1. */ - /* Chill specifies that v2 must be > 0, so check for that. */ - if (current_language->la_language == language_chill - && value_as_long (arg2) <= 0) - { - error ("Second operand of MOD must be greater than zero."); - } if (v2 == 0) { v = v1; @@ -1021,7 +1057,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) case BINOP_EXP: v = pow (v1, v2); if (errno) - error ("Cannot perform exponentiation: %s", strerror (errno)); + error ("Cannot perform exponentiation: %s", safe_strerror (errno)); break; case BINOP_REM: @@ -1031,12 +1067,6 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) case BINOP_MOD: /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, X mod 0 has a defined value, X. */ - /* Chill specifies that v2 must be > 0, so check for that. */ - if (current_language->la_language == language_chill - && v2 <= 0) - { - error ("Second operand of MOD must be greater than zero."); - } if (v2 == 0) { v = v1; @@ -1128,8 +1158,8 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) int value_logical_not (struct value *arg1) { - register int len; - register char *p; + int len; + char *p; struct type *type1; COERCE_NUMBER (arg1); @@ -1186,8 +1216,8 @@ value_strcmp (struct value *arg1, struct value *arg2) int value_equal (struct value *arg1, struct value *arg2) { - register int len; - register char *p1, *p2; + int len; + char *p1, *p2; struct type *type1, *type2; enum type_code code1; enum type_code code2; @@ -1245,8 +1275,8 @@ value_equal (struct value *arg1, struct value *arg2) int value_less (struct value *arg1, struct value *arg2) { - register enum type_code code1; - register enum type_code code2; + enum type_code code1; + enum type_code code2; struct type *type1, *type2; COERCE_NUMBER (arg1); @@ -1287,8 +1317,8 @@ value_less (struct value *arg1, struct value *arg2) struct value * value_neg (struct value *arg1) { - register struct type *type; - register struct type *result_type = VALUE_TYPE (arg1); + struct type *type; + struct type *result_type = VALUE_TYPE (arg1); COERCE_REF (arg1); COERCE_ENUM (arg1); @@ -1299,8 +1329,8 @@ value_neg (struct value *arg1) return value_from_double (result_type, -value_as_double (arg1)); else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_BOOL) { - /* Perform integral promotion for ANSI C/C++. - FIXME: What about FORTRAN and chill ? */ + /* Perform integral promotion for ANSI C/C++. FIXME: What about + FORTRAN and (the deleted) chill ? */ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) result_type = builtin_type_int; @@ -1316,8 +1346,8 @@ value_neg (struct value *arg1) struct value * value_complement (struct value *arg1) { - register struct type *type; - register struct type *result_type = VALUE_TYPE (arg1); + struct type *type; + struct type *result_type = VALUE_TYPE (arg1); int typecode; COERCE_REF (arg1); diff --git a/contrib/gdb/gdb/valops.c b/contrib/gdb/gdb/valops.c index 4532da73aea..60422779a14 100644 --- a/contrib/gdb/gdb/valops.c +++ b/contrib/gdb/gdb/valops.c @@ -1,6 +1,6 @@ /* Perform non-arithmetic operations on values, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -33,9 +33,15 @@ #include "gdbcmd.h" #include "regcache.h" #include "cp-abi.h" +#include "block.h" +#include "infcall.h" +#include "dictionary.h" +#include "cp-support.h" #include #include "gdb_string.h" +#include "gdb_assert.h" +#include "cp-support.h" /* Flag indicating HP compilers were used; needed to correctly handle some value operations with HP aCC code/runtime. */ @@ -44,11 +50,8 @@ extern int hp_som_som_object_present; extern int overload_debug; /* Local functions. */ -static int typecmp (int staticp, struct type *t1[], struct value *t2[]); - -static CORE_ADDR find_function_addr (struct value *, struct type **); -static struct value *value_arg_coerce (struct value *, struct type *, int); - +static int typecmp (int staticp, int varargs, int nargs, + struct field t1[], struct value *t2[]); static CORE_ADDR value_push (CORE_ADDR, struct value *); @@ -59,14 +62,61 @@ static struct value *search_struct_method (char *, struct value **, struct value **, int, int *, struct type *); +static int find_oload_champ_namespace (struct type **arg_types, int nargs, + const char *func_name, + const char *qualified_name, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv); + +static +int find_oload_champ_namespace_loop (struct type **arg_types, int nargs, + const char *func_name, + const char *qualified_name, + int namespace_len, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv, + int *oload_champ); + +static int find_oload_champ (struct type **arg_types, int nargs, int method, + int num_fns, + struct fn_field *fns_ptr, + struct symbol **oload_syms, + struct badness_vector **oload_champ_bv); + +static int oload_method_static (int method, struct fn_field *fns_ptr, + int index); + +enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE }; + +static enum +oload_classification classify_oload_match (struct badness_vector + * oload_champ_bv, + int nargs, + int static_offset); + static int check_field_in (struct type *, const char *); +static struct value *value_struct_elt_for_reference (struct type *domain, + int offset, + struct type *curtype, + char *name, + struct type *intype, + enum noside noside); + +static struct value *value_namespace_elt (const struct type *curtype, + char *name, + enum noside noside); + +static struct value *value_maybe_namespace_elt (const struct type *curtype, + char *name, + enum noside noside); + static CORE_ADDR allocate_space_in_inferior (int); static struct value *cast_into_complex (struct type *, struct value *); static struct fn_field *find_method_list (struct value ** argp, char *method, - int offset, int *static_memfuncp, + int offset, struct type *type, int *num_fns, struct type **basetype, int *boffset); @@ -81,22 +131,13 @@ static int auto_abandon = 0; int overload_resolution = 0; -/* This boolean tells what gdb should do if a signal is received while in - a function called from gdb (call dummy). If set, gdb unwinds the stack - and restore the context to what as it was before the call. - The default is to stop in the frame where the signal was received. */ - -int unwind_on_signal_p = 0; - - - /* Find the address of function name NAME in the inferior. */ struct value * -find_function_in_inferior (char *name) +find_function_in_inferior (const char *name) { - register struct symbol *sym; - sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL); + struct symbol *sym; + sym = lookup_symbol (name, 0, VAR_DOMAIN, 0, NULL); if (sym != NULL) { if (SYMBOL_CLASS (sym) != LOC_BLOCK) @@ -136,7 +177,7 @@ struct value * value_allocate_space_in_inferior (int len) { struct value *blocklen; - struct value *val = find_function_in_inferior ("malloc"); + struct value *val = find_function_in_inferior (NAME_OF_MALLOC); blocklen = value_from_longest (builtin_type_int, (LONGEST) len); val = call_function_by_hand (val, 1, &blocklen); @@ -164,9 +205,9 @@ allocate_space_in_inferior (int len) struct value * value_cast (struct type *type, struct value *arg2) { - register enum type_code code1; - register enum type_code code2; - register int scalar; + enum type_code code1; + enum type_code code2; + int scalar; struct type *type2; int convert_to_boolean = 0; @@ -359,18 +400,11 @@ value_cast (struct type *type, struct value *arg2) value_zero (t1, not_lval), 0, t1, 1); if (v) { - struct value *v2 = value_ind (arg2); - VALUE_ADDRESS (v2) -= VALUE_ADDRESS (v) - + VALUE_OFFSET (v); - - /* JYG: adjust the new pointer value and - embedded offset. */ - v2->aligner.contents[0] -= VALUE_EMBEDDED_OFFSET (v); - VALUE_EMBEDDED_OFFSET (v2) = 0; - - v2 = value_addr (v2); - VALUE_TYPE (v2) = type; - return v2; + CORE_ADDR addr2 = value_as_address (arg2); + addr2 -= (VALUE_ADDRESS (v) + + VALUE_OFFSET (v) + + VALUE_EMBEDDED_OFFSET (v)); + return value_from_pointer (type, addr2); } } } @@ -381,49 +415,6 @@ value_cast (struct type *type, struct value *arg2) VALUE_POINTED_TO_OFFSET (arg2) = 0; /* pai: chk_val */ return arg2; } - else if (chill_varying_type (type)) - { - struct type *range1, *range2, *eltype1, *eltype2; - struct value *val; - int count1, count2; - LONGEST low_bound, high_bound; - char *valaddr, *valaddr_data; - /* For lint warning about eltype2 possibly uninitialized: */ - eltype2 = NULL; - if (code2 == TYPE_CODE_BITSTRING) - error ("not implemented: converting bitstring to varying type"); - if ((code2 != TYPE_CODE_ARRAY && code2 != TYPE_CODE_STRING) - || (eltype1 = check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1))), - eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)), - (TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2) - /* || TYPE_CODE (eltype1) != TYPE_CODE (eltype2) */ ))) - error ("Invalid conversion to varying type"); - range1 = TYPE_FIELD_TYPE (TYPE_FIELD_TYPE (type, 1), 0); - range2 = TYPE_FIELD_TYPE (type2, 0); - if (get_discrete_bounds (range1, &low_bound, &high_bound) < 0) - count1 = -1; - else - count1 = high_bound - low_bound + 1; - if (get_discrete_bounds (range2, &low_bound, &high_bound) < 0) - count1 = -1, count2 = 0; /* To force error before */ - else - count2 = high_bound - low_bound + 1; - if (count2 > count1) - error ("target varying type is too small"); - val = allocate_value (type); - valaddr = VALUE_CONTENTS_RAW (val); - valaddr_data = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8; - /* Set val's __var_length field to count2. */ - store_signed_integer (valaddr, TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)), - count2); - /* Set the __var_data field to count2 elements copied from arg2. */ - memcpy (valaddr_data, VALUE_CONTENTS (arg2), - count2 * TYPE_LENGTH (eltype2)); - /* Zero the rest of the __var_data field of val. */ - memset (valaddr_data + count2 * TYPE_LENGTH (eltype2), '\0', - (count1 - count2) * TYPE_LENGTH (eltype2)); - return val; - } else if (VALUE_LVAL (arg2) == lval_memory) { return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2), @@ -537,10 +528,11 @@ value_fetch_lazy (struct value *val) struct value * value_assign (struct value *toval, struct value *fromval) { - register struct type *type; + struct type *type; struct value *val; - char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; int use_buffer = 0; + struct frame_id old_frame; if (!toval->modifiable) error ("Left operand of assignment is not a modifiable lvalue."); @@ -554,22 +546,10 @@ value_assign (struct value *toval, struct value *fromval) COERCE_ARRAY (fromval); CHECK_TYPEDEF (type); - /* If TOVAL is a special machine register requiring conversion - of program values to a special raw format, - convert FROMVAL's contents now, with result in `raw_buffer', - and set USE_BUFFER to the number of bytes to write. */ - - if (VALUE_REGNO (toval) >= 0) - { - int regno = VALUE_REGNO (toval); - if (REGISTER_CONVERTIBLE (regno)) - { - struct type *fromtype = check_typedef (VALUE_TYPE (fromval)); - REGISTER_CONVERT_TO_RAW (fromtype, regno, - VALUE_CONTENTS (fromval), raw_buffer); - use_buffer = REGISTER_RAW_SIZE (regno); - } - } + /* Since modifying a register can trash the frame chain, and modifying memory + can trash the frame cache, we save the old frame and then restore the new + frame afterwards. */ + old_frame = get_frame_id (deprecated_selected_frame); switch (VALUE_LVAL (toval)) { @@ -607,7 +587,7 @@ value_assign (struct value *toval, struct value *fromval) if (changed_len > (int) sizeof (LONGEST)) error ("Can't handle bitfields which don't fit in a %d bit word.", - sizeof (LONGEST) * HOST_CHAR_BIT); + (int) sizeof (LONGEST) * HOST_CHAR_BIT); read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), buffer, changed_len); @@ -632,146 +612,138 @@ value_assign (struct value *toval, struct value *fromval) write_memory (changed_addr, dest_buffer, changed_len); if (memory_changed_hook) memory_changed_hook (changed_addr, changed_len); + target_changed_event (); } break; - case lval_register: - if (VALUE_BITSIZE (toval)) - { - char buffer[sizeof (LONGEST)]; - int len = - REGISTER_RAW_SIZE (VALUE_REGNO (toval)) - VALUE_OFFSET (toval); - - if (len > (int) sizeof (LONGEST)) - error ("Can't handle bitfields in registers larger than %d bits.", - sizeof (LONGEST) * HOST_CHAR_BIT); - - if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval) - > len * HOST_CHAR_BIT) - /* Getting this right would involve being very careful about - byte order. */ - error ("Can't assign to bitfields that cross register " - "boundaries."); - - read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - buffer, len); - modify_field (buffer, value_as_long (fromval), - VALUE_BITPOS (toval), VALUE_BITSIZE (toval)); - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - buffer, len); - } - else if (use_buffer) - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - raw_buffer, use_buffer); - else - { - /* Do any conversion necessary when storing this type to more - than one register. */ -#ifdef REGISTER_CONVERT_FROM_TYPE - memcpy (raw_buffer, VALUE_CONTENTS (fromval), TYPE_LENGTH (type)); - REGISTER_CONVERT_FROM_TYPE (VALUE_REGNO (toval), type, raw_buffer); - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - raw_buffer, TYPE_LENGTH (type)); -#else - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - VALUE_CONTENTS (fromval), TYPE_LENGTH (type)); -#endif - } - /* Assigning to the stack pointer, frame pointer, and other - (architecture and calling convention specific) registers may - cause the frame cache to be out of date. We just do this - on all assignments to registers for simplicity; I doubt the slowdown - matters. */ - reinit_frame_cache (); - break; - case lval_reg_frame_relative: + case lval_register: { - /* value is stored in a series of registers in the frame - specified by the structure. Copy that value out, modify - it, and copy it back in. */ - int amount_to_copy = (VALUE_BITSIZE (toval) ? 1 : TYPE_LENGTH (type)); - int reg_size = REGISTER_RAW_SIZE (VALUE_FRAME_REGNUM (toval)); - int byte_offset = VALUE_OFFSET (toval) % reg_size; - int reg_offset = VALUE_OFFSET (toval) / reg_size; - int amount_copied; - - /* Make the buffer large enough in all cases. */ - /* FIXME (alloca): Not safe for very large data types. */ - char *buffer = (char *) alloca (amount_to_copy - + sizeof (LONGEST) - + MAX_REGISTER_RAW_SIZE); - - int regno; struct frame_info *frame; + int value_reg; /* Figure out which frame this is in currently. */ - for (frame = get_current_frame (); - frame && FRAME_FP (frame) != VALUE_FRAME (toval); - frame = get_prev_frame (frame)) - ; + if (VALUE_LVAL (toval) == lval_register) + { + frame = get_current_frame (); + value_reg = VALUE_REGNO (toval); + } + else + { + frame = frame_find_by_id (VALUE_FRAME_ID (toval)); + value_reg = VALUE_FRAME_REGNUM (toval); + } if (!frame) error ("Value being assigned to is no longer active."); - - amount_to_copy += (reg_size - amount_to_copy % reg_size); - - /* Copy it out. */ - for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset, - amount_copied = 0); - amount_copied < amount_to_copy; - amount_copied += reg_size, regno++) + + if (VALUE_LVAL (toval) == lval_reg_frame_relative + && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval), type)) { - get_saved_register (buffer + amount_copied, - (int *) NULL, (CORE_ADDR *) NULL, - frame, regno, (enum lval_type *) NULL); + /* If TOVAL is a special machine register requiring + conversion of program values to a special raw format. */ + VALUE_TO_REGISTER (frame, VALUE_FRAME_REGNUM (toval), + type, VALUE_CONTENTS (fromval)); } - - /* Modify what needs to be modified. */ - if (VALUE_BITSIZE (toval)) - modify_field (buffer + byte_offset, - value_as_long (fromval), - VALUE_BITPOS (toval), VALUE_BITSIZE (toval)); - else if (use_buffer) - memcpy (buffer + byte_offset, raw_buffer, use_buffer); else - memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval), - TYPE_LENGTH (type)); - - /* Copy it back. */ - for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset, - amount_copied = 0); - amount_copied < amount_to_copy; - amount_copied += reg_size, regno++) { - enum lval_type lval; - CORE_ADDR addr; - int optim; + /* TOVAL is stored in a series of registers in the frame + specified by the structure. Copy that value out, + modify it, and copy it back in. */ + int amount_copied; + int amount_to_copy; + char *buffer; + int reg_offset; + int byte_offset; + int regno; - /* Just find out where to put it. */ - get_saved_register ((char *) NULL, - &optim, &addr, frame, regno, &lval); + /* Locate the first register that falls in the value that + needs to be transfered. Compute the offset of the + value in that register. */ + { + int offset; + for (reg_offset = value_reg, offset = 0; + offset + DEPRECATED_REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval); + reg_offset++); + byte_offset = VALUE_OFFSET (toval) - offset; + } - if (optim) - error ("Attempt to assign to a value that was optimized out."); - if (lval == lval_memory) - write_memory (addr, buffer + amount_copied, reg_size); - else if (lval == lval_register) - write_register_bytes (addr, buffer + amount_copied, reg_size); + /* Compute the number of register aligned values that need + to be copied. */ + if (VALUE_BITSIZE (toval)) + amount_to_copy = byte_offset + 1; else - error ("Attempt to assign to an unmodifiable value."); - } + amount_to_copy = byte_offset + TYPE_LENGTH (type); + + /* And a bounce buffer. Be slightly over generous. */ + buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE); + /* Copy it in. */ + for (regno = reg_offset, amount_copied = 0; + amount_copied < amount_to_copy; + amount_copied += DEPRECATED_REGISTER_RAW_SIZE (regno), regno++) + frame_register_read (frame, regno, buffer + amount_copied); + + /* Modify what needs to be modified. */ + if (VALUE_BITSIZE (toval)) + modify_field (buffer + byte_offset, + value_as_long (fromval), + VALUE_BITPOS (toval), VALUE_BITSIZE (toval)); + else if (use_buffer) + memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer); + else + memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval), + TYPE_LENGTH (type)); + + /* Copy it out. */ + for (regno = reg_offset, amount_copied = 0; + amount_copied < amount_to_copy; + amount_copied += DEPRECATED_REGISTER_RAW_SIZE (regno), regno++) + put_frame_register (frame, regno, buffer + amount_copied); + + } if (register_changed_hook) register_changed_hook (-1); + target_changed_event (); + break; } - break; - - + default: error ("Left operand of assignment is not an lvalue."); } + /* Assigning to the stack pointer, frame pointer, and other + (architecture and calling convention specific) registers may + cause the frame cache to be out of date. Assigning to memory + also can. We just do this on all assignments to registers or + memory, for simplicity's sake; I doubt the slowdown matters. */ + switch (VALUE_LVAL (toval)) + { + case lval_memory: + case lval_register: + case lval_reg_frame_relative: + + reinit_frame_cache (); + + /* Having destoroyed the frame cache, restore the selected frame. */ + + /* FIXME: cagney/2002-11-02: There has to be a better way of + doing this. Instead of constantly saving/restoring the + frame. Why not create a get_selected_frame() function that, + having saved the selected frame's ID can automatically + re-find the previously selected frame automatically. */ + + { + struct frame_info *fi = frame_find_by_id (old_frame); + if (fi != NULL) + select_frame (fi); + } + + break; + default: + break; + } + /* If the field does not entirely fill a LONGEST, then zero the sign bits. If the field is signed, and is negative, then sign extend. */ if ((VALUE_BITSIZE (toval) > 0) @@ -835,9 +807,9 @@ value_of_variable (struct symbol *var, struct block *b) if (!frame) { if (BLOCK_FUNCTION (b) - && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b))) + && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b))) error ("No frame is currently executing in block %s.", - SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b))); + SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b))); else error ("No frame is currently executing in specified block"); } @@ -845,7 +817,7 @@ value_of_variable (struct symbol *var, struct block *b) val = read_var_value (var, frame); if (!val) - error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var)); + error ("Address of symbol \"%s\" is unknown.", SYMBOL_PRINT_NAME (var)); return val; } @@ -876,7 +848,7 @@ value_of_variable (struct symbol *var, struct block *b) struct value * value_coerce_array (struct value *arg1) { - register struct type *type = check_typedef (VALUE_TYPE (arg1)); + struct type *type = check_typedef (VALUE_TYPE (arg1)); if (VALUE_LVAL (arg1) != lval_memory) error ("Attempt to take address of value not located in memory."); @@ -960,9 +932,9 @@ value_ind (struct value *arg1) to do. "long long" variables are rare enough that BUILTIN_TYPE_LONGEST would seem to be a mistake. */ if (TYPE_CODE (base_type) == TYPE_CODE_INT) - return value_at (builtin_type_int, - (CORE_ADDR) value_as_long (arg1), - VALUE_BFD_SECTION (arg1)); + return value_at_lazy (builtin_type_int, + (CORE_ADDR) value_as_long (arg1), + VALUE_BFD_SECTION (arg1)); else if (TYPE_CODE (base_type) == TYPE_CODE_PTR) { struct type *enc_type; @@ -996,8 +968,8 @@ value_ind (struct value *arg1) CORE_ADDR push_word (CORE_ADDR sp, ULONGEST word) { - register int len = REGISTER_SIZE; - char *buffer = alloca (MAX_REGISTER_RAW_SIZE); + int len = DEPRECATED_REGISTER_SIZE; + char buffer[MAX_REGISTER_SIZE]; store_unsigned_integer (buffer, len, word); if (INNER_THAN (1, 2)) @@ -1045,11 +1017,11 @@ push_bytes (CORE_ADDR sp, char *buffer, int len) it to be an argument to a function. */ static CORE_ADDR -value_push (register CORE_ADDR sp, struct value *arg) +value_push (CORE_ADDR sp, struct value *arg) { - register int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg)); - register int container_len = len; - register int offset; + int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg)); + int container_len = len; + int offset; /* How big is the container we're going to put this value in? */ if (PARM_BOUNDARY) @@ -1079,8 +1051,8 @@ value_push (register CORE_ADDR sp, struct value *arg) } CORE_ADDR -default_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) +legacy_push_arguments (int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) { /* ASSERT ( !struct_return); */ int i; @@ -1089,714 +1061,6 @@ default_push_arguments (int nargs, struct value **args, CORE_ADDR sp, return sp; } - -/* Functions to use for the COERCE_FLOAT_TO_DOUBLE gdbarch method. - - How you should pass arguments to a function depends on whether it - was defined in K&R style or prototype style. If you define a - function using the K&R syntax that takes a `float' argument, then - callers must pass that argument as a `double'. If you define the - function using the prototype syntax, then you must pass the - argument as a `float', with no promotion. - - Unfortunately, on certain older platforms, the debug info doesn't - indicate reliably how each function was defined. A function type's - TYPE_FLAG_PROTOTYPED flag may be clear, even if the function was - defined in prototype style. When calling a function whose - TYPE_FLAG_PROTOTYPED flag is clear, GDB consults the - COERCE_FLOAT_TO_DOUBLE gdbarch method to decide what to do. - - For modern targets, it is proper to assume that, if the prototype - flag is clear, that can be trusted: `float' arguments should be - promoted to `double'. You should register the function - `standard_coerce_float_to_double' to get this behavior. - - For some older targets, if the prototype flag is clear, that - doesn't tell us anything. So we guess that, if we don't have a - type for the formal parameter (i.e., the first argument to - COERCE_FLOAT_TO_DOUBLE is null), then we should promote it; - otherwise, we should leave it alone. The function - `default_coerce_float_to_double' provides this behavior; it is the - default value, for compatibility with older configurations. */ -int -default_coerce_float_to_double (struct type *formal, struct type *actual) -{ - return formal == NULL; -} - - -int -standard_coerce_float_to_double (struct type *formal, struct type *actual) -{ - return 1; -} - - -/* Perform the standard coercions that are specified - for arguments to be passed to C functions. - - If PARAM_TYPE is non-NULL, it is the expected parameter type. - IS_PROTOTYPED is non-zero if the function declaration is prototyped. */ - -static struct value * -value_arg_coerce (struct value *arg, struct type *param_type, - int is_prototyped) -{ - register struct type *arg_type = check_typedef (VALUE_TYPE (arg)); - register struct type *type - = param_type ? check_typedef (param_type) : arg_type; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_REF: - if (TYPE_CODE (arg_type) != TYPE_CODE_REF - && TYPE_CODE (arg_type) != TYPE_CODE_PTR) - { - arg = value_addr (arg); - VALUE_TYPE (arg) = param_type; - return arg; - } - break; - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_BOOL: - case TYPE_CODE_ENUM: - /* If we don't have a prototype, coerce to integer type if necessary. */ - if (!is_prototyped) - { - if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) - type = builtin_type_int; - } - /* Currently all target ABIs require at least the width of an integer - type for an argument. We may have to conditionalize the following - type coercion for future targets. */ - if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) - type = builtin_type_int; - break; - case TYPE_CODE_FLT: - /* FIXME: We should always convert floats to doubles in the - non-prototyped case. As many debugging formats include - no information about prototyping, we have to live with - COERCE_FLOAT_TO_DOUBLE for now. */ - if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE (param_type, arg_type)) - { - if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) - type = builtin_type_double; - else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double)) - type = builtin_type_long_double; - } - break; - case TYPE_CODE_FUNC: - type = lookup_pointer_type (type); - break; - case TYPE_CODE_ARRAY: - if (current_language->c_style_arrays) - type = lookup_pointer_type (TYPE_TARGET_TYPE (type)); - break; - case TYPE_CODE_UNDEF: - case TYPE_CODE_PTR: - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_VOID: - case TYPE_CODE_SET: - case TYPE_CODE_RANGE: - case TYPE_CODE_STRING: - case TYPE_CODE_BITSTRING: - case TYPE_CODE_ERROR: - case TYPE_CODE_MEMBER: - case TYPE_CODE_METHOD: - case TYPE_CODE_COMPLEX: - default: - break; - } - - return value_cast (type, arg); -} - -/* Determine a function's address and its return type from its value. - Calls error() if the function is not valid for calling. */ - -static CORE_ADDR -find_function_addr (struct value *function, struct type **retval_type) -{ - register struct type *ftype = check_typedef (VALUE_TYPE (function)); - register enum type_code code = TYPE_CODE (ftype); - struct type *value_type; - CORE_ADDR funaddr; - - /* If it's a member function, just look at the function - part of it. */ - - /* Determine address to call. */ - if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD) - { - funaddr = VALUE_ADDRESS (function); - value_type = TYPE_TARGET_TYPE (ftype); - } - else if (code == TYPE_CODE_PTR) - { - funaddr = value_as_address (function); - ftype = check_typedef (TYPE_TARGET_TYPE (ftype)); - if (TYPE_CODE (ftype) == TYPE_CODE_FUNC - || TYPE_CODE (ftype) == TYPE_CODE_METHOD) - { - funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr); - value_type = TYPE_TARGET_TYPE (ftype); - } - else - value_type = builtin_type_int; - } - else if (code == TYPE_CODE_INT) - { - /* Handle the case of functions lacking debugging info. - Their values are characters since their addresses are char */ - if (TYPE_LENGTH (ftype) == 1) - funaddr = value_as_address (value_addr (function)); - else - /* Handle integer used as address of a function. */ - funaddr = (CORE_ADDR) value_as_long (function); - - value_type = builtin_type_int; - } - else - error ("Invalid data type for function to be called."); - - *retval_type = value_type; - return funaddr; -} - -/* All this stuff with a dummy frame may seem unnecessarily complicated - (why not just save registers in GDB?). The purpose of pushing a dummy - frame which looks just like a real frame is so that if you call a - function and then hit a breakpoint (get a signal, etc), "backtrace" - will look right. Whether the backtrace needs to actually show the - stack at the time the inferior function was called is debatable, but - it certainly needs to not display garbage. So if you are contemplating - making dummy frames be different from normal frames, consider that. */ - -/* Perform a function call in the inferior. - ARGS is a vector of values of arguments (NARGS of them). - FUNCTION is a value, the function to be called. - Returns a value representing what the function returned. - May fail to return, if a breakpoint or signal is hit - during the execution of the function. - - ARGS is modified to contain coerced values. */ - -static struct value * -hand_function_call (struct value *function, int nargs, struct value **args) -{ - register CORE_ADDR sp; - register int i; - int rc; - CORE_ADDR start_sp; - /* CALL_DUMMY is an array of words (REGISTER_SIZE), but each word - is in host byte order. Before calling FIX_CALL_DUMMY, we byteswap it - and remove any extra bytes which might exist because ULONGEST is - bigger than REGISTER_SIZE. - - NOTE: This is pretty wierd, as the call dummy is actually a - sequence of instructions. But CISC machines will have - to pack the instructions into REGISTER_SIZE units (and - so will RISC machines for which INSTRUCTION_SIZE is not - REGISTER_SIZE). - - NOTE: This is pretty stupid. CALL_DUMMY should be in strict - target byte order. */ - - static ULONGEST *dummy; - int sizeof_dummy1; - char *dummy1; - CORE_ADDR old_sp; - struct type *value_type; - unsigned char struct_return; - CORE_ADDR struct_addr = 0; - struct inferior_status *inf_status; - struct cleanup *old_chain; - CORE_ADDR funaddr; - int using_gcc; /* Set to version of gcc in use, or zero if not gcc */ - CORE_ADDR real_pc; - struct type *param_type = NULL; - struct type *ftype = check_typedef (SYMBOL_TYPE (function)); - int n_method_args = 0; - - dummy = alloca (SIZEOF_CALL_DUMMY_WORDS); - sizeof_dummy1 = REGISTER_SIZE * SIZEOF_CALL_DUMMY_WORDS / sizeof (ULONGEST); - dummy1 = alloca (sizeof_dummy1); - memcpy (dummy, CALL_DUMMY_WORDS, SIZEOF_CALL_DUMMY_WORDS); - - if (!target_has_execution) - noprocess (); - - inf_status = save_inferior_status (1); - old_chain = make_cleanup_restore_inferior_status (inf_status); - - /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers - (and POP_FRAME for restoring them). (At least on most machines) - they are saved on the stack in the inferior. */ - PUSH_DUMMY_FRAME; - - old_sp = sp = read_sp (); - - if (INNER_THAN (1, 2)) - { - /* Stack grows down */ - sp -= sizeof_dummy1; - start_sp = sp; - } - else - { - /* Stack grows up */ - start_sp = sp; - sp += sizeof_dummy1; - } - - funaddr = find_function_addr (function, &value_type); - CHECK_TYPEDEF (value_type); - - { - struct block *b = block_for_pc (funaddr); - /* If compiled without -g, assume GCC 2. */ - using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b)); - } - - /* Are we returning a value using a structure return or a normal - value return? */ - - struct_return = using_struct_return (function, funaddr, value_type, - using_gcc); - - /* Create a call sequence customized for this function - and the number of arguments for it. */ - for (i = 0; i < (int) (SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); i++) - store_unsigned_integer (&dummy1[i * REGISTER_SIZE], - REGISTER_SIZE, - (ULONGEST) dummy[i]); - -#ifdef GDB_TARGET_IS_HPPA - real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, - value_type, using_gcc); -#else - FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, - value_type, using_gcc); - real_pc = start_sp; -#endif - - if (CALL_DUMMY_LOCATION == ON_STACK) - { - write_memory (start_sp, (char *) dummy1, sizeof_dummy1); - } - - if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END) - { - /* Convex Unix prohibits executing in the stack segment. */ - /* Hope there is empty room at the top of the text segment. */ - extern CORE_ADDR text_end; - static int checked = 0; - if (!checked) - for (start_sp = text_end - sizeof_dummy1; start_sp < text_end; ++start_sp) - if (read_memory_integer (start_sp, 1) != 0) - error ("text segment full -- no place to put call"); - checked = 1; - sp = old_sp; - real_pc = text_end - sizeof_dummy1; - write_memory (real_pc, (char *) dummy1, sizeof_dummy1); - } - - if (CALL_DUMMY_LOCATION == AFTER_TEXT_END) - { - extern CORE_ADDR text_end; - int errcode; - sp = old_sp; - real_pc = text_end; - errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1); - if (errcode != 0) - error ("Cannot write text segment -- call_function failed"); - } - - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) - { - real_pc = funaddr; - } - -#ifdef lint - sp = old_sp; /* It really is used, for some ifdef's... */ -#endif - - if (TYPE_CODE (ftype) == TYPE_CODE_METHOD) - { - i = 0; - while (TYPE_CODE (TYPE_ARG_TYPES (ftype)[i]) != TYPE_CODE_VOID) - i++; - n_method_args = i; - if (nargs < i) - error ("too few arguments in method call"); - } - else if (nargs < TYPE_NFIELDS (ftype)) - error ("too few arguments in function call"); - - for (i = nargs - 1; i >= 0; i--) - { - /* Assume that methods are always prototyped, unless they are off the - end (which we should only be allowing if there is a ``...''). - FIXME. */ - if (TYPE_CODE (ftype) == TYPE_CODE_METHOD) - { - if (i < n_method_args) - args[i] = value_arg_coerce (args[i], TYPE_ARG_TYPES (ftype)[i], 1); - else - args[i] = value_arg_coerce (args[i], NULL, 0); - } - - /* If we're off the end of the known arguments, do the standard - promotions. FIXME: if we had a prototype, this should only - be allowed if ... were present. */ - if (i >= TYPE_NFIELDS (ftype)) - args[i] = value_arg_coerce (args[i], NULL, 0); - - else - { - param_type = TYPE_FIELD_TYPE (ftype, i); - args[i] = value_arg_coerce (args[i], param_type, TYPE_PROTOTYPED (ftype)); - } - - /*elz: this code is to handle the case in which the function to be called - has a pointer to function as parameter and the corresponding actual argument - is the address of a function and not a pointer to function variable. - In aCC compiled code, the calls through pointers to functions (in the body - of the function called by hand) are made via $$dyncall_external which - requires some registers setting, this is taken care of if we call - via a function pointer variable, but not via a function address. - In cc this is not a problem. */ - - if (using_gcc == 0) - if (param_type) - /* if this parameter is a pointer to function */ - if (TYPE_CODE (param_type) == TYPE_CODE_PTR) - if (TYPE_CODE (param_type->target_type) == TYPE_CODE_FUNC) - /* elz: FIXME here should go the test about the compiler used - to compile the target. We want to issue the error - message only if the compiler used was HP's aCC. - If we used HP's cc, then there is no problem and no need - to return at this point */ - if (using_gcc == 0) /* && compiler == aCC */ - /* go see if the actual parameter is a variable of type - pointer to function or just a function */ - if (args[i]->lval == not_lval) - { - char *arg_name; - if (find_pc_partial_function ((CORE_ADDR) args[i]->aligner.contents[0], &arg_name, NULL, NULL)) - error ("\ -You cannot use function <%s> as argument. \n\ -You must use a pointer to function type variable. Command ignored.", arg_name); - } - } - - if (REG_STRUCT_HAS_ADDR_P ()) - { - /* This is a machine like the sparc, where we may need to pass a - pointer to the structure, not the structure itself. */ - for (i = nargs - 1; i >= 0; i--) - { - struct type *arg_type = check_typedef (VALUE_TYPE (args[i])); - if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT - || TYPE_CODE (arg_type) == TYPE_CODE_UNION - || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY - || TYPE_CODE (arg_type) == TYPE_CODE_STRING - || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING - || TYPE_CODE (arg_type) == TYPE_CODE_SET - || (TYPE_CODE (arg_type) == TYPE_CODE_FLT - && TYPE_LENGTH (arg_type) > 8) - ) - && REG_STRUCT_HAS_ADDR (using_gcc, arg_type)) - { - CORE_ADDR addr; - int len; /* = TYPE_LENGTH (arg_type); */ - int aligned_len; - arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i])); - len = TYPE_LENGTH (arg_type); - - if (STACK_ALIGN_P ()) - /* MVS 11/22/96: I think at least some of this - stack_align code is really broken. Better to let - PUSH_ARGUMENTS adjust the stack in a target-defined - manner. */ - aligned_len = STACK_ALIGN (len); - else - aligned_len = len; - if (INNER_THAN (1, 2)) - { - /* stack grows downward */ - sp -= aligned_len; - /* ... so the address of the thing we push is the - stack pointer after we push it. */ - addr = sp; - } - else - { - /* The stack grows up, so the address of the thing - we push is the stack pointer before we push it. */ - addr = sp; - sp += aligned_len; - } - /* Push the structure. */ - write_memory (addr, VALUE_CONTENTS_ALL (args[i]), len); - /* The value we're going to pass is the address of the - thing we just pushed. */ - /*args[i] = value_from_longest (lookup_pointer_type (value_type), - (LONGEST) addr); */ - args[i] = value_from_pointer (lookup_pointer_type (arg_type), - addr); - } - } - } - - - /* Reserve space for the return structure to be written on the - stack, if necessary */ - - if (struct_return) - { - int len = TYPE_LENGTH (value_type); - if (STACK_ALIGN_P ()) - /* MVS 11/22/96: I think at least some of this stack_align - code is really broken. Better to let PUSH_ARGUMENTS adjust - the stack in a target-defined manner. */ - len = STACK_ALIGN (len); - if (INNER_THAN (1, 2)) - { - /* stack grows downward */ - sp -= len; - struct_addr = sp; - } - else - { - /* stack grows upward */ - struct_addr = sp; - sp += len; - } - } - - /* elz: on HPPA no need for this extra alignment, maybe it is needed - on other architectures. This is because all the alignment is - taken care of in the above code (ifdef REG_STRUCT_HAS_ADDR) and - in hppa_push_arguments */ - if (EXTRA_STACK_ALIGNMENT_NEEDED) - { - /* MVS 11/22/96: I think at least some of this stack_align code - is really broken. Better to let PUSH_ARGUMENTS adjust the - stack in a target-defined manner. */ - if (STACK_ALIGN_P () && INNER_THAN (1, 2)) - { - /* If stack grows down, we must leave a hole at the top. */ - int len = 0; - - for (i = nargs - 1; i >= 0; i--) - len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i])); - if (CALL_DUMMY_STACK_ADJUST_P) - len += CALL_DUMMY_STACK_ADJUST; - sp -= STACK_ALIGN (len) - len; - } - } - - sp = PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr); - - if (PUSH_RETURN_ADDRESS_P ()) - /* for targets that use no CALL_DUMMY */ - /* There are a number of targets now which actually don't write - any CALL_DUMMY instructions into the target, but instead just - save the machine state, push the arguments, and jump directly - to the callee function. Since this doesn't actually involve - executing a JSR/BSR instruction, the return address must be set - up by hand, either by pushing onto the stack or copying into a - return-address register as appropriate. Formerly this has been - done in PUSH_ARGUMENTS, but that's overloading its - functionality a bit, so I'm making it explicit to do it here. */ - sp = PUSH_RETURN_ADDRESS (real_pc, sp); - - if (STACK_ALIGN_P () && !INNER_THAN (1, 2)) - { - /* If stack grows up, we must leave a hole at the bottom, note - that sp already has been advanced for the arguments! */ - if (CALL_DUMMY_STACK_ADJUST_P) - sp += CALL_DUMMY_STACK_ADJUST; - sp = STACK_ALIGN (sp); - } - -/* XXX This seems wrong. For stacks that grow down we shouldn't do - anything here! */ - /* MVS 11/22/96: I think at least some of this stack_align code is - really broken. Better to let PUSH_ARGUMENTS adjust the stack in - a target-defined manner. */ - if (CALL_DUMMY_STACK_ADJUST_P) - if (INNER_THAN (1, 2)) - { - /* stack grows downward */ - sp -= CALL_DUMMY_STACK_ADJUST; - } - - /* Store the address at which the structure is supposed to be - written. Note that this (and the code which reserved the space - above) assumes that gcc was used to compile this function. Since - it doesn't cost us anything but space and if the function is pcc - it will ignore this value, we will make that assumption. - - Also note that on some machines (like the sparc) pcc uses a - convention like gcc's. */ - - if (struct_return) - STORE_STRUCT_RETURN (struct_addr, sp); - - /* Write the stack pointer. This is here because the statements above - might fool with it. On SPARC, this write also stores the register - window into the right place in the new stack frame, which otherwise - wouldn't happen. (See store_inferior_registers in sparc-nat.c.) */ - write_sp (sp); - - if (SAVE_DUMMY_FRAME_TOS_P ()) - SAVE_DUMMY_FRAME_TOS (sp); - - { - char *retbuf = (char*) alloca (REGISTER_BYTES); - char *name; - struct symbol *symbol; - - name = NULL; - symbol = find_pc_function (funaddr); - if (symbol) - { - name = SYMBOL_SOURCE_NAME (symbol); - } - else - { - /* Try the minimal symbols. */ - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr); - - if (msymbol) - { - name = SYMBOL_SOURCE_NAME (msymbol); - } - } - if (name == NULL) - { - char format[80]; - sprintf (format, "at %s", local_hex_format ()); - name = alloca (80); - /* FIXME-32x64: assumes funaddr fits in a long. */ - sprintf (name, format, (unsigned long) funaddr); - } - - /* Execute the stack dummy routine, calling FUNCTION. - When it is done, discard the empty frame - after storing the contents of all regs into retbuf. */ - rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf); - - if (rc == 1) - { - /* We stopped inside the FUNCTION because of a random signal. - Further execution of the FUNCTION is not allowed. */ - - if (unwind_on_signal_p) - { - /* The user wants the context restored. */ - - /* We must get back to the frame we were before the dummy call. */ - POP_FRAME; - - /* FIXME: Insert a bunch of wrap_here; name can be very long if it's - a C++ name with arguments and stuff. */ - error ("\ -The program being debugged was signaled while in a function called from GDB.\n\ -GDB has restored the context to what it was before the call.\n\ -To change this behavior use \"set unwindonsignal off\"\n\ -Evaluation of the expression containing the function (%s) will be abandoned.", - name); - } - else - { - /* The user wants to stay in the frame where we stopped (default).*/ - - /* If we did the cleanups, we would print a spurious error - message (Unable to restore previously selected frame), - would write the registers from the inf_status (which is - wrong), and would do other wrong things. */ - discard_cleanups (old_chain); - discard_inferior_status (inf_status); - - /* FIXME: Insert a bunch of wrap_here; name can be very long if it's - a C++ name with arguments and stuff. */ - error ("\ -The program being debugged was signaled while in a function called from GDB.\n\ -GDB remains in the frame where the signal was received.\n\ -To change this behavior use \"set unwindonsignal on\"\n\ -Evaluation of the expression containing the function (%s) will be abandoned.", - name); - } - } - - if (rc == 2) - { - /* We hit a breakpoint inside the FUNCTION. */ - - /* If we did the cleanups, we would print a spurious error - message (Unable to restore previously selected frame), - would write the registers from the inf_status (which is - wrong), and would do other wrong things. */ - discard_cleanups (old_chain); - discard_inferior_status (inf_status); - - /* The following error message used to say "The expression - which contained the function call has been discarded." It - is a hard concept to explain in a few words. Ideally, GDB - would be able to resume evaluation of the expression when - the function finally is done executing. Perhaps someday - this will be implemented (it would not be easy). */ - - /* FIXME: Insert a bunch of wrap_here; name can be very long if it's - a C++ name with arguments and stuff. */ - error ("\ -The program being debugged stopped while in a function called from GDB.\n\ -When the function (%s) is done executing, GDB will silently\n\ -stop (instead of continuing to evaluate the expression containing\n\ -the function call).", name); - } - - /* If we get here the called FUNCTION run to completion. */ - do_cleanups (old_chain); - - /* Figure out the value returned by the function. */ -/* elz: I defined this new macro for the hppa architecture only. - this gives us a way to get the value returned by the function from the stack, - at the same address we told the function to put it. - We cannot assume on the pa that r28 still contains the address of the returned - structure. Usually this will be overwritten by the callee. - I don't know about other architectures, so I defined this macro - */ - -#ifdef VALUE_RETURNED_FROM_STACK - if (struct_return) - return (struct value *) VALUE_RETURNED_FROM_STACK (value_type, struct_addr); -#endif - - return value_being_returned (value_type, retbuf, struct_return); - } -} - -struct value * -call_function_by_hand (struct value *function, int nargs, struct value **args) -{ - if (CALL_DUMMY_P) - { - return hand_function_call (function, nargs, args); - } - else - { - error ("Cannot invoke functions on this machine."); - } -} - - - /* Create a value for an array by allocating space in the inferior, copying the data into that space, and then setting up an array value. @@ -1923,13 +1187,14 @@ value_bitstring (char *ptr, int len) } /* See if we can pass arguments in T2 to a function which takes arguments - of types T1. Both t1 and t2 are NULL-terminated vectors. If some - arguments need coercion of some sort, then the coerced values are written - into T2. Return value is 0 if the arguments could be matched, or the - position at which they differ if not. + of types T1. T1 is a list of NARGS arguments, and T2 is a NULL-terminated + vector. If some arguments need coercion of some sort, then the coerced + values are written into T2. Return value is 0 if the arguments could be + matched, or the position at which they differ if not. STATICP is nonzero if the T1 argument list came from a - static member function. + static member function. T2 will still include the ``this'' pointer, + but it will be skipped. For non-static member functions, we ignore the first argument, which is the type of the instance variable. This is because we want @@ -1938,27 +1203,30 @@ value_bitstring (char *ptr, int len) requested operation is type secure, shouldn't we? FIXME. */ static int -typecmp (int staticp, struct type *t1[], struct value *t2[]) +typecmp (int staticp, int varargs, int nargs, + struct field t1[], struct value *t2[]) { int i; if (t2 == 0) - return 1; - if (staticp && t1 == 0) - return t2[1] != 0; - if (t1 == 0) - return 1; - if (TYPE_CODE (t1[0]) == TYPE_CODE_VOID) - return 0; - if (t1[!staticp] == 0) - return 0; - for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++) + internal_error (__FILE__, __LINE__, "typecmp: no argument list"); + + /* Skip ``this'' argument if applicable. T2 will always include THIS. */ + if (staticp) + t2 ++; + + for (i = 0; + (i < nargs) && TYPE_CODE (t1[i].type) != TYPE_CODE_VOID; + i++) { struct type *tt1, *tt2; + if (!t2[i]) return i + 1; - tt1 = check_typedef (t1[i]); + + tt1 = check_typedef (t1[i].type); tt2 = check_typedef (VALUE_TYPE (t2[i])); + if (TYPE_CODE (tt1) == TYPE_CODE_REF /* We should be doing hairy argument matching, as below. */ && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1))) == TYPE_CODE (tt2))) @@ -1994,12 +1262,12 @@ typecmp (int staticp, struct type *t1[], struct value *t2[]) /* We should be doing much hairier argument matching (see section 13.2 of the ARM), but as a quick kludge, just check for the same type code. */ - if (TYPE_CODE (t1[i]) != TYPE_CODE (VALUE_TYPE (t2[i]))) + if (TYPE_CODE (t1[i].type) != TYPE_CODE (VALUE_TYPE (t2[i]))) return i + 1; } - if (!t1[i]) + if (varargs || t2[i] == NULL) return 0; - return t2[i] ? i + 1 : 0; + return i + 1; } /* Helper function used by value_struct_elt to recurse through baseclasses. @@ -2012,7 +1280,7 @@ typecmp (int staticp, struct type *t1[], struct value *t2[]) static struct value * search_struct_field (char *name, struct value *arg1, int offset, - register struct type *type, int looking_for_baseclass) + struct type *type, int looking_for_baseclass) { int i; int nbases = TYPE_N_BASECLASSES (type); @@ -2028,11 +1296,18 @@ search_struct_field (char *name, struct value *arg1, int offset, { struct value *v; if (TYPE_FIELD_STATIC (type, i)) - v = value_static_field (type, i); + { + v = value_static_field (type, i); + if (v == 0) + error ("field %s is nonexistent or has been optimised out", + name); + } else - v = value_primitive_field (arg1, offset, i, type); - if (v == 0) - error ("there is no field named %s", name); + { + v = value_primitive_field (arg1, offset, i, type); + if (v == 0) + error ("there is no field named %s", name); + } return v; } @@ -2048,19 +1323,22 @@ search_struct_field (char *name, struct value *arg1, int offset, /* Look for a match through the fields of an anonymous union, or anonymous struct. C++ provides anonymous unions. - In the GNU Chill implementation of variant record types, - each has an (anonymous) union type, - each member of the union represents a . - Each is represented as a struct, - with a member for each . */ + In the GNU Chill (now deleted from GDB) + implementation of variant record types, each + has an (anonymous) union type, + each member of the union represents a . Each is + represented as a struct, with a member for each + . */ struct value *v; int new_offset = offset; - /* This is pretty gross. In G++, the offset in an anonymous - union is relative to the beginning of the enclosing struct. - In the GNU Chill implementation of variant records, - the bitpos is zero in an anonymous union field, so we + /* This is pretty gross. In G++, the offset in an + anonymous union is relative to the beginning of the + enclosing struct. In the GNU Chill (now deleted + from GDB) implementation of variant records, the + bitpos is zero in an anonymous union field, so we have to add the offset of the union here. */ if (TYPE_CODE (field_type) == TYPE_CODE_STRUCT || (TYPE_NFIELDS (field_type) > 0 @@ -2242,7 +1520,7 @@ find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr, static struct value * search_struct_method (char *name, struct value **arg1p, struct value **args, int offset, - int *static_memfuncp, register struct type *type) + int *static_memfuncp, struct type *type) { int i; struct value *v; @@ -2269,12 +1547,11 @@ search_struct_method (char *name, struct value **arg1p, struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); name_matched = 1; + check_stub_method_group (type, i); if (j > 0 && args == 0) error ("cannot resolve overloaded method `%s': no arguments supplied", name); else if (j == 0 && args == 0) { - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (type, i, j); v = value_fn_field (arg1p, f, j, type, offset); if (v != NULL) return v; @@ -2282,9 +1559,9 @@ search_struct_method (char *name, struct value **arg1p, else while (j >= 0) { - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (type, i, j); if (!typecmp (TYPE_FN_FIELD_STATIC_P (f, j), + TYPE_VARARGS (TYPE_FN_FIELD_TYPE (f, j)), + TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f, j)), TYPE_FN_FIELD_ARGS (f, j), args)) { if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) @@ -2388,7 +1665,7 @@ struct value * value_struct_elt (struct value **argp, struct value **args, char *name, int *static_memfuncp, char *err) { - register struct type *t; + struct type *t; struct value *v; COERCE_ARRAY (*argp); @@ -2497,7 +1774,6 @@ value_struct_elt (struct value **argp, struct value **args, * ARGP is a pointer to a pointer to a value (the object) * METHOD is a string containing the method name * OFFSET is the offset within the value - * STATIC_MEMFUNCP is set if the method is static * TYPE is the assumed type of the object * NUM_FNS is the number of overloaded instances * BASETYPE is set to the actual type of the subobject where the method is found @@ -2505,7 +1781,7 @@ value_struct_elt (struct value **argp, struct value **args, static struct fn_field * find_method_list (struct value **argp, char *method, int offset, - int *static_memfuncp, struct type *type, int *num_fns, + struct type *type, int *num_fns, struct type **basetype, int *boffset) { int i; @@ -2521,10 +1797,17 @@ find_method_list (struct value **argp, char *method, int offset, char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i); if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0)) { - *num_fns = TYPE_FN_FIELDLIST_LENGTH (type, i); + int len = TYPE_FN_FIELDLIST_LENGTH (type, i); + struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); + + *num_fns = len; *basetype = type; *boffset = offset; - return TYPE_FN_FIELDLIST1 (type, i); + + /* Resolve any stub methods. */ + check_stub_method_group (type, i); + + return f; } } @@ -2564,7 +1847,8 @@ find_method_list (struct value **argp, char *method, int offset, base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8; } f = find_method_list (argp, method, base_offset + offset, - static_memfuncp, TYPE_BASECLASS (type, i), num_fns, basetype, boffset); + TYPE_BASECLASS (type, i), num_fns, basetype, + boffset); if (f) return f; } @@ -2575,15 +1859,14 @@ find_method_list (struct value **argp, char *method, int offset, * ARGP is a pointer to a pointer to a value (the object) * METHOD is the method name * OFFSET is the offset within the value contents - * STATIC_MEMFUNCP is set if the method is static * NUM_FNS is the number of overloaded instances * BASETYPE is set to the type of the base subobject that defines the method * BOFFSET is the offset of the base subobject which defines the method */ struct fn_field * value_find_oload_method_list (struct value **argp, char *method, int offset, - int *static_memfuncp, int *num_fns, - struct type **basetype, int *boffset) + int *num_fns, struct type **basetype, + int *boffset) { struct type *t; @@ -2606,12 +1889,7 @@ value_find_oload_method_list (struct value **argp, char *method, int offset, && TYPE_CODE (t) != TYPE_CODE_UNION) error ("Attempt to extract a component of a value that is not a struct or union"); - /* Assume it's not static, unless we see that it is. */ - if (static_memfuncp) - *static_memfuncp = 0; - - return find_method_list (argp, method, 0, static_memfuncp, t, num_fns, basetype, boffset); - + return find_method_list (argp, method, 0, t, num_fns, basetype, boffset); } /* Given an array of argument types (ARGTYPES) (which includes an @@ -2647,19 +1925,10 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, int lax, struct value **objp, struct symbol *fsym, struct value **valp, struct symbol **symp, int *staticp) { - int nparms; - struct type **parm_types; - int champ_nparms = 0; struct value *obj = (objp ? *objp : NULL); - short oload_champ = -1; /* Index of best overloaded function */ - short oload_ambiguous = 0; /* Current ambiguity state for overload resolution */ - /* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */ - short oload_ambig_champ = -1; /* 2nd contender for best match */ - short oload_non_standard = 0; /* did we have to use non-standard conversions? */ - short oload_incompatible = 0; /* are args supplied incompatible with any function? */ + int oload_champ; /* Index of best overloaded function */ - struct badness_vector *bv; /* A measure of how good an overloaded instance is */ struct badness_vector *oload_champ_bv = NULL; /* The measure for the current best match */ struct value *temp = obj; @@ -2668,18 +1937,17 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, int num_fns = 0; /* Number of overloaded instances being considered */ struct type *basetype = NULL; int boffset; - register int jj; - register int ix; + int ix; + int static_offset; + struct cleanup *old_cleanups = NULL; - char *obj_type_name = NULL; + const char *obj_type_name = NULL; char *func_name = NULL; + enum oload_classification match_quality; /* Get the list of overloaded methods or functions */ if (method) { - int i; - int len; - struct type *domain; obj_type_name = TYPE_NAME (VALUE_TYPE (obj)); /* Hack: evaluate_subexp_standard often passes in a pointer value rather than the object itself, so try again */ @@ -2688,7 +1956,6 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (VALUE_TYPE (obj))); fns_ptr = value_find_oload_method_list (&temp, name, 0, - staticp, &num_fns, &basetype, &boffset); if (!fns_ptr || !num_fns) @@ -2696,149 +1963,45 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, obj_type_name, (obj_type_name && *obj_type_name) ? "::" : "", name); - domain = TYPE_DOMAIN_TYPE (fns_ptr[0].type); - len = TYPE_NFN_FIELDS (domain); - /* NOTE: dan/2000-03-10: This stuff is for STABS, which won't - give us the info we need directly in the types. We have to - use the method stub conversion to get it. Be aware that this - is by no means perfect, and if you use STABS, please move to - DWARF-2, or something like it, because trying to improve - overloading using STABS is really a waste of time. */ - for (i = 0; i < len; i++) - { - int j; - struct fn_field *f = TYPE_FN_FIELDLIST1 (domain, i); - int len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); - - for (j = 0; j < len2; j++) - { - if (TYPE_FN_FIELD_STUB (f, j) && (!strcmp_iw (TYPE_FN_FIELDLIST_NAME (domain,i),name))) - check_stub_method (domain, i, j); - } - } + /* If we are dealing with stub method types, they should have + been resolved by find_method_list via value_find_oload_method_list + above. */ + gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL); + oload_champ = find_oload_champ (arg_types, nargs, method, num_fns, + fns_ptr, oload_syms, &oload_champ_bv); } else { - int i = -1; - func_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_NO_OPTS); + const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym); + func_name = cp_func_name (qualified_name); /* If the name is NULL this must be a C-style function. Just return the same symbol. */ - if (!func_name) + if (func_name == NULL) { *symp = fsym; return 0; } - oload_syms = make_symbol_overload_list (fsym); - while (oload_syms[++i]) - num_fns++; - if (!num_fns) - error ("Couldn't find function %s", func_name); + old_cleanups = make_cleanup (xfree, func_name); + make_cleanup (xfree, oload_syms); + make_cleanup (xfree, oload_champ_bv); + + oload_champ = find_oload_champ_namespace (arg_types, nargs, + func_name, + qualified_name, + &oload_syms, + &oload_champ_bv); } - oload_champ_bv = NULL; + /* Check how bad the best match is. */ - /* Consider each candidate in turn */ - for (ix = 0; ix < num_fns; ix++) - { - if (method) - { - /* For static member functions, we won't have a this pointer, but nothing - else seems to handle them right now, so we just pretend ourselves */ - nparms=0; + match_quality + = classify_oload_match (oload_champ_bv, nargs, + oload_method_static (method, fns_ptr, + oload_champ)); - if (TYPE_FN_FIELD_ARGS(fns_ptr,ix)) - { - while (TYPE_CODE(TYPE_FN_FIELD_ARGS(fns_ptr,ix)[nparms]) != TYPE_CODE_VOID) - nparms++; - } - } - else - { - /* If it's not a method, this is the proper place */ - nparms=TYPE_NFIELDS(SYMBOL_TYPE(oload_syms[ix])); - } - - /* Prepare array of parameter types */ - parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *))); - for (jj = 0; jj < nparms; jj++) - parm_types[jj] = (method - ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj]) - : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj)); - - /* Compare parameter types to supplied argument types */ - bv = rank_function (parm_types, nparms, arg_types, nargs); - - if (!oload_champ_bv) - { - oload_champ_bv = bv; - oload_champ = 0; - champ_nparms = nparms; - } - else - /* See whether current candidate is better or worse than previous best */ - switch (compare_badness (bv, oload_champ_bv)) - { - case 0: - oload_ambiguous = 1; /* top two contenders are equally good */ - oload_ambig_champ = ix; - break; - case 1: - oload_ambiguous = 2; /* incomparable top contenders */ - oload_ambig_champ = ix; - break; - case 2: - oload_champ_bv = bv; /* new champion, record details */ - oload_ambiguous = 0; - oload_champ = ix; - oload_ambig_champ = -1; - champ_nparms = nparms; - break; - case 3: - default: - break; - } - xfree (parm_types); - if (overload_debug) - { - if (method) - fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms); - else - fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms); - for (jj = 0; jj < nargs; jj++) - fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]); - fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous); - } - } /* end loop over all candidates */ - /* NOTE: dan/2000-03-10: Seems to be a better idea to just pick one - if they have the exact same goodness. This is because there is no - way to differentiate based on return type, which we need to in - cases like overloads of .begin() */ -#if 0 - if (oload_ambiguous) - { - if (method) - error ("Cannot resolve overloaded method %s%s%s to unique instance; disambiguate by specifying function signature", - obj_type_name, - (obj_type_name && *obj_type_name) ? "::" : "", - name); - else - error ("Cannot resolve overloaded function %s to unique instance; disambiguate by specifying function signature", - func_name); - } -#endif - - /* Check how bad the best match is */ - for (ix = 1; ix <= nargs; ix++) - { - if (oload_champ_bv->rank[ix] >= 100) - oload_incompatible = 1; /* truly mismatched types */ - - else if (oload_champ_bv->rank[ix] >= 10) - oload_non_standard = 1; /* non-standard type conversions needed */ - } - if (oload_incompatible) + if (match_quality == INCOMPATIBLE) { if (method) error ("Cannot resolve method %s%s%s to any overloaded instance", @@ -2849,7 +2012,7 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, error ("Cannot resolve function %s to any overloaded instance", func_name); } - else if (oload_non_standard) + else if (match_quality == NON_STANDARD) { if (method) warning ("Using non-standard conversion to match method %s%s%s to supplied arguments", @@ -2863,6 +2026,8 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, if (method) { + if (staticp != NULL) + *staticp = oload_method_static (method, fns_ptr, oload_champ); if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ)) *valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset); else @@ -2871,7 +2036,6 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, else { *symp = oload_syms[oload_champ]; - xfree (func_name); } if (objp) @@ -2883,7 +2047,279 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, } *objp = temp; } - return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0); + if (old_cleanups != NULL) + do_cleanups (old_cleanups); + + switch (match_quality) + { + case INCOMPATIBLE: + return 100; + case NON_STANDARD: + return 10; + default: /* STANDARD */ + return 0; + } +} + +/* Find the best overload match, searching for FUNC_NAME in namespaces + contained in QUALIFIED_NAME until it either finds a good match or + runs out of namespaces. It stores the overloaded functions in + *OLOAD_SYMS, and the badness vector in *OLOAD_CHAMP_BV. The + calling function is responsible for freeing *OLOAD_SYMS and + *OLOAD_CHAMP_BV. */ + +static int +find_oload_champ_namespace (struct type **arg_types, int nargs, + const char *func_name, + const char *qualified_name, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv) +{ + int oload_champ; + + find_oload_champ_namespace_loop (arg_types, nargs, + func_name, + qualified_name, 0, + oload_syms, oload_champ_bv, + &oload_champ); + + return oload_champ; +} + +/* Helper function for find_oload_champ_namespace; NAMESPACE_LEN is + how deep we've looked for namespaces, and the champ is stored in + OLOAD_CHAMP. The return value is 1 if the champ is a good one, 0 + if it isn't. + + It is the caller's responsibility to free *OLOAD_SYMS and + *OLOAD_CHAMP_BV. */ + +static int +find_oload_champ_namespace_loop (struct type **arg_types, int nargs, + const char *func_name, + const char *qualified_name, + int namespace_len, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv, + int *oload_champ) +{ + int next_namespace_len = namespace_len; + int searched_deeper = 0; + int num_fns = 0; + struct cleanup *old_cleanups; + int new_oload_champ; + struct symbol **new_oload_syms; + struct badness_vector *new_oload_champ_bv; + char *new_namespace; + + if (next_namespace_len != 0) + { + gdb_assert (qualified_name[next_namespace_len] == ':'); + next_namespace_len += 2; + } + next_namespace_len + += cp_find_first_component (qualified_name + next_namespace_len); + + /* Initialize these to values that can safely be xfree'd. */ + *oload_syms = NULL; + *oload_champ_bv = NULL; + + /* First, see if we have a deeper namespace we can search in. If we + get a good match there, use it. */ + + if (qualified_name[next_namespace_len] == ':') + { + searched_deeper = 1; + + if (find_oload_champ_namespace_loop (arg_types, nargs, + func_name, qualified_name, + next_namespace_len, + oload_syms, oload_champ_bv, + oload_champ)) + { + return 1; + } + }; + + /* If we reach here, either we're in the deepest namespace or we + didn't find a good match in a deeper namespace. But, in the + latter case, we still have a bad match in a deeper namespace; + note that we might not find any match at all in the current + namespace. (There's always a match in the deepest namespace, + because this overload mechanism only gets called if there's a + function symbol to start off with.) */ + + old_cleanups = make_cleanup (xfree, *oload_syms); + old_cleanups = make_cleanup (xfree, *oload_champ_bv); + new_namespace = alloca (namespace_len + 1); + strncpy (new_namespace, qualified_name, namespace_len); + new_namespace[namespace_len] = '\0'; + new_oload_syms = make_symbol_overload_list (func_name, + new_namespace); + while (new_oload_syms[num_fns]) + ++num_fns; + + new_oload_champ = find_oload_champ (arg_types, nargs, 0, num_fns, + NULL, new_oload_syms, + &new_oload_champ_bv); + + /* Case 1: We found a good match. Free earlier matches (if any), + and return it. Case 2: We didn't find a good match, but we're + not the deepest function. Then go with the bad match that the + deeper function found. Case 3: We found a bad match, and we're + the deepest function. Then return what we found, even though + it's a bad match. */ + + if (new_oload_champ != -1 + && classify_oload_match (new_oload_champ_bv, nargs, 0) == STANDARD) + { + *oload_syms = new_oload_syms; + *oload_champ = new_oload_champ; + *oload_champ_bv = new_oload_champ_bv; + do_cleanups (old_cleanups); + return 1; + } + else if (searched_deeper) + { + xfree (new_oload_syms); + xfree (new_oload_champ_bv); + discard_cleanups (old_cleanups); + return 0; + } + else + { + gdb_assert (new_oload_champ != -1); + *oload_syms = new_oload_syms; + *oload_champ = new_oload_champ; + *oload_champ_bv = new_oload_champ_bv; + discard_cleanups (old_cleanups); + return 0; + } +} + +/* Look for a function to take NARGS args of types ARG_TYPES. Find + the best match from among the overloaded methods or functions + (depending on METHOD) given by FNS_PTR or OLOAD_SYMS, respectively. + The number of methods/functions in the list is given by NUM_FNS. + Return the index of the best match; store an indication of the + quality of the match in OLOAD_CHAMP_BV. + + It is the caller's responsibility to free *OLOAD_CHAMP_BV. */ + +static int +find_oload_champ (struct type **arg_types, int nargs, int method, + int num_fns, struct fn_field *fns_ptr, + struct symbol **oload_syms, + struct badness_vector **oload_champ_bv) +{ + int ix; + struct badness_vector *bv; /* A measure of how good an overloaded instance is */ + int oload_champ = -1; /* Index of best overloaded function */ + int oload_ambiguous = 0; /* Current ambiguity state for overload resolution */ + /* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */ + + *oload_champ_bv = NULL; + + /* Consider each candidate in turn */ + for (ix = 0; ix < num_fns; ix++) + { + int jj; + int static_offset = oload_method_static (method, fns_ptr, ix); + int nparms; + struct type **parm_types; + + if (method) + { + nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix)); + } + else + { + /* If it's not a method, this is the proper place */ + nparms=TYPE_NFIELDS(SYMBOL_TYPE(oload_syms[ix])); + } + + /* Prepare array of parameter types */ + parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *))); + for (jj = 0; jj < nparms; jj++) + parm_types[jj] = (method + ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj].type) + : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj)); + + /* Compare parameter types to supplied argument types. Skip THIS for + static methods. */ + bv = rank_function (parm_types, nparms, arg_types + static_offset, + nargs - static_offset); + + if (!*oload_champ_bv) + { + *oload_champ_bv = bv; + oload_champ = 0; + } + else + /* See whether current candidate is better or worse than previous best */ + switch (compare_badness (bv, *oload_champ_bv)) + { + case 0: + oload_ambiguous = 1; /* top two contenders are equally good */ + break; + case 1: + oload_ambiguous = 2; /* incomparable top contenders */ + break; + case 2: + *oload_champ_bv = bv; /* new champion, record details */ + oload_ambiguous = 0; + oload_champ = ix; + break; + case 3: + default: + break; + } + xfree (parm_types); + if (overload_debug) + { + if (method) + fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms); + else + fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms); + for (jj = 0; jj < nargs - static_offset; jj++) + fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]); + fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous); + } + } + + return oload_champ; +} + +/* Return 1 if we're looking at a static method, 0 if we're looking at + a non-static method or a function that isn't a method. */ + +static int +oload_method_static (int method, struct fn_field *fns_ptr, int index) +{ + if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, index)) + return 1; + else + return 0; +} + +/* Check how good an overload match OLOAD_CHAMP_BV represents. */ + +static enum oload_classification +classify_oload_match (struct badness_vector *oload_champ_bv, + int nargs, + int static_offset) +{ + int ix; + + for (ix = 1; ix <= nargs - static_offset; ix++) + { + if (oload_champ_bv->rank[ix] >= 100) + return INCOMPATIBLE; /* truly mismatched types */ + else if (oload_champ_bv->rank[ix] >= 10) + return NON_STANDARD; /* non-standard type conversions needed */ + } + + return STANDARD; /* Only standard conversions needed. */ } /* C++: return 1 is NAME is a legitimate name for the destructor @@ -2905,7 +2341,7 @@ destructor_name_p (const char *name, const struct type *type) len = strlen (dname); else len = cp - dname; - if (strlen (name + 1) != len || !STREQN (dname, name + 1, len)) + if (strlen (name + 1) != len || strncmp (dname, name + 1, len) != 0) error ("name of destructor must equal name of class"); else return 1; @@ -2918,9 +2354,9 @@ destructor_name_p (const char *name, const struct type *type) target structure/union is defined, otherwise, return 0. */ static int -check_field_in (register struct type *type, const char *name) +check_field_in (struct type *type, const char *name) { - register int i; + int i; for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) { @@ -2961,7 +2397,7 @@ check_field_in (register struct type *type, const char *name) int check_field (struct value *arg1, const char *name) { - register struct type *t; + struct type *t; COERCE_ARRAY (arg1); @@ -2987,6 +2423,31 @@ check_field (struct value *arg1, const char *name) return check_field_in (t, name); } +/* C++: Given an aggregate type CURTYPE, and a member name NAME, + return the appropriate member. This function is used to resolve + user expressions of the form "DOMAIN::NAME". For more details on + what happens, see the comment before + value_struct_elt_for_reference. */ + +struct value * +value_aggregate_elt (struct type *curtype, + char *name, + enum noside noside) +{ + switch (TYPE_CODE (curtype)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL, + noside); + case TYPE_CODE_NAMESPACE: + return value_namespace_elt (curtype, name, noside); + default: + internal_error (__FILE__, __LINE__, + "non-aggregate type in value_aggregate_elt"); + } +} + /* C++: Given an aggregate type CURTYPE, and a member name NAME, return the address of this member as a "pointer to member" type. If INTYPE is non-null, then it will be the type @@ -2994,13 +2455,14 @@ check_field (struct value *arg1, const char *name) "pointers to member functions". This function is used to resolve user expressions of the form "DOMAIN::NAME". */ -struct value * +static struct value * value_struct_elt_for_reference (struct type *domain, int offset, struct type *curtype, char *name, - struct type *intype) + struct type *intype, + enum noside noside) { - register struct type *t = curtype; - register int i; + struct type *t = curtype; + int i; struct value *v; if (TYPE_CODE (t) != TYPE_CODE_STRUCT @@ -3011,13 +2473,13 @@ value_struct_elt_for_reference (struct type *domain, int offset, { char *t_field_name = TYPE_FIELD_NAME (t, i); - if (t_field_name && STREQ (t_field_name, name)) + if (t_field_name && strcmp (t_field_name, name) == 0) { if (TYPE_FIELD_STATIC (t, i)) { v = value_static_field (t, i); if (v == NULL) - error ("Internal error: could not find static variable %s", + error ("static field %s has been optimized out", name); return v; } @@ -3058,11 +2520,13 @@ value_struct_elt_for_reference (struct type *domain, int offset, else if (cplus_demangle_opname (t_field_name, dem_opname, 0)) t_field_name = dem_opname; } - if (t_field_name && STREQ (t_field_name, name)) + if (t_field_name && strcmp (t_field_name, name) == 0) { int j = TYPE_FN_FIELDLIST_LENGTH (t, i); struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i); + check_stub_method_group (t, i); + if (intype == 0 && j > 1) error ("non-unique member `%s' requires type instantiation", name); if (intype) @@ -3076,8 +2540,6 @@ value_struct_elt_for_reference (struct type *domain, int offset, else j = 0; - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (t, i, j); if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) { return value_from_longest @@ -3089,7 +2551,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, else { struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), - 0, VAR_NAMESPACE, 0, NULL); + 0, VAR_DOMAIN, 0, NULL); if (s == NULL) { v = 0; @@ -3120,13 +2582,63 @@ value_struct_elt_for_reference (struct type *domain, int offset, offset + base_offset, TYPE_BASECLASS (t, i), name, - intype); + intype, + noside); if (v) return v; } - return 0; + + /* As a last chance, pretend that CURTYPE is a namespace, and look + it up that way; this (frequently) works for types nested inside + classes. */ + + return value_maybe_namespace_elt (curtype, name, noside); } +/* C++: Return the member NAME of the namespace given by the type + CURTYPE. */ + +static struct value * +value_namespace_elt (const struct type *curtype, + char *name, + enum noside noside) +{ + struct value *retval = value_maybe_namespace_elt (curtype, name, + noside); + + if (retval == NULL) + error ("No symbol \"%s\" in namespace \"%s\".", name, + TYPE_TAG_NAME (curtype)); + + return retval; +} + +/* A helper function used by value_namespace_elt and + value_struct_elt_for_reference. It looks up NAME inside the + context CURTYPE; this works if CURTYPE is a namespace or if CURTYPE + is a class and NAME refers to a type in CURTYPE itself (as opposed + to, say, some base class of CURTYPE). */ + +static struct value * +value_maybe_namespace_elt (const struct type *curtype, + char *name, + enum noside noside) +{ + const char *namespace_name = TYPE_TAG_NAME (curtype); + struct symbol *sym; + + sym = cp_lookup_symbol_namespace (namespace_name, name, NULL, + get_selected_block (0), VAR_DOMAIN, + NULL); + + if (sym == NULL) + return NULL; + else if ((noside == EVAL_AVOID_SIDE_EFFECTS) + && (SYMBOL_CLASS (sym) == LOC_TYPEDEF)) + return allocate_value (SYMBOL_TYPE (sym)); + else + return value_of_variable (sym, get_selected_block (0)); +} /* Given a pointer value V, find the real (RTTI) type of the object it points to. @@ -3208,20 +2720,18 @@ value_full_object (struct value *argp, struct type *rtype, int xfull, int xtop, -/* C++: return the value of the class instance variable, if one exists. +/* Return the value of the local variable, if one exists. Flag COMPLAIN signals an error if the request is made in an inappropriate context. */ struct value * -value_of_this (int complain) +value_of_local (const char *name, int complain) { struct symbol *func, *sym; struct block *b; - int i; - static const char funny_this[] = "this"; - struct value *this; + struct value * ret; - if (selected_frame == 0) + if (deprecated_selected_frame == 0) { if (complain) error ("no frame selected"); @@ -3229,40 +2739,52 @@ value_of_this (int complain) return 0; } - func = get_frame_function (selected_frame); + func = get_frame_function (deprecated_selected_frame); if (!func) { if (complain) - error ("no `this' in nameless context"); + error ("no `%s' in nameless context", name); else return 0; } b = SYMBOL_BLOCK_VALUE (func); - i = BLOCK_NSYMS (b); - if (i <= 0) + if (dict_empty (BLOCK_DICT (b))) { if (complain) - error ("no args, no `this'"); + error ("no args, no `%s'", name); else return 0; } /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER symbol instead of the LOC_ARG one (if both exist). */ - sym = lookup_block_symbol (b, funny_this, VAR_NAMESPACE); + sym = lookup_block_symbol (b, name, NULL, VAR_DOMAIN); if (sym == NULL) { if (complain) - error ("current stack frame not in method"); + error ("current stack frame does not contain a variable named `%s'", name); else return NULL; } - this = read_var_value (sym, selected_frame); - if (this == 0 && complain) - error ("`this' argument at unknown address"); - return this; + ret = read_var_value (sym, deprecated_selected_frame); + if (ret == 0 && complain) + error ("`%s' argument unreadable", name); + return ret; +} + +/* C++/Objective-C: return the value of the class instance variable, + if one exists. Flag COMPLAIN signals an error if the request is + made in an inappropriate context. */ + +struct value * +value_of_this (int complain) +{ + if (current_language->la_language == language_objc) + return value_of_local ("self", complain); + else + return value_of_local ("this", complain); } /* Create a slice (sub-string, sub-array) of ARRAY, that is LENGTH elements @@ -3273,7 +2795,7 @@ struct value * value_slice (struct value *array, int lowbound, int length) { struct type *slice_range_type, *slice_type, *range_type; - LONGEST lowerbound, upperbound, offset; + LONGEST lowerbound, upperbound; struct value *slice; struct type *array_type; array_type = check_typedef (VALUE_TYPE (array)); @@ -3286,10 +2808,7 @@ value_slice (struct value *array, int lowbound, int length) if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0) error ("slice from bad array or bitstring"); if (lowbound < lowerbound || length < 0 - || lowbound + length - 1 > upperbound - /* Chill allows zero-length strings but not arrays. */ - || (current_language->la_language == language_chill - && length == 0 && TYPE_CODE (array_type) == TYPE_CODE_ARRAY)) + || lowbound + length - 1 > upperbound) error ("slice out of range"); /* FIXME-type-allocation: need a way to free this type when we are done with it. */ @@ -3324,7 +2843,7 @@ value_slice (struct value *array, int lowbound, int length) else { struct type *element_type = TYPE_TARGET_TYPE (array_type); - offset + LONGEST offset = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type)); slice_type = create_array_type ((struct type *) NULL, element_type, slice_range_type); @@ -3345,19 +2864,6 @@ value_slice (struct value *array, int lowbound, int length) return slice; } -/* Assuming chill_varying_type (VARRAY) is true, return an equivalent - value as a fixed-length array. */ - -struct value * -varying_to_slice (struct value *varray) -{ - struct type *vtype = check_typedef (VALUE_TYPE (varray)); - LONGEST length = unpack_long (TYPE_FIELD_TYPE (vtype, 0), - VALUE_CONTENTS (varray) - + TYPE_FIELD_BITPOS (vtype, 0) / 8); - return value_slice (value_primitive_field (varray, 0, 1, vtype), 0, length); -} - /* Create a value for a FORTRAN complex number. Currently most of the time values are coerced to COMPLEX*16 (i.e. a complex number composed of 2 doubles. This really should be a smarter routine @@ -3425,14 +2931,4 @@ _initialize_valops (void) &setlist), &showlist); overload_resolution = 1; - - add_show_from_set ( - add_set_cmd ("unwindonsignal", no_class, var_boolean, - (char *) &unwind_on_signal_p, -"Set unwinding of stack if a signal is received while in a call dummy.\n\ -The unwindonsignal lets the user determine what gdb should do if a signal\n\ -is received while in a function called from gdb (call dummy). If set, gdb\n\ -unwinds the stack and restore the context to what as it was before the call.\n\ -The default is to stop in the frame where the signal was received.", &setlist), - &showlist); } diff --git a/contrib/gdb/gdb/valprint.c b/contrib/gdb/gdb/valprint.c index 131769b67a4..294e09f58ab 100644 --- a/contrib/gdb/gdb/valprint.c +++ b/contrib/gdb/gdb/valprint.c @@ -1,7 +1,8 @@ /* Print values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, + Inc. This file is part of GDB. @@ -28,7 +29,6 @@ #include "gdbcore.h" #include "gdbcmd.h" #include "target.h" -#include "obstack.h" #include "language.h" #include "annotate.h" #include "valprint.h" @@ -42,9 +42,6 @@ static int partial_memory_read (CORE_ADDR memaddr, char *myaddr, int len, int *errnoptr); -static void print_hex_chars (struct ui_file *, unsigned char *, - unsigned int); - static void show_print (char *, int); static void set_print (char *, int); @@ -205,12 +202,8 @@ val_print_type_code_int (struct type *type, char *valaddr, } else { -#ifdef PRINT_TYPELESS_INTEGER - PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr)); -#else print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, unpack_long (type, valaddr)); -#endif } } @@ -332,22 +325,22 @@ print_longest (struct ui_file *stream, int format, int use_local, fprintf_filtered (stream, use_local ? local_decimal_format_custom ("ll") : "%lld", - val_long); + (long long) val_long); break; case 'u': - fprintf_filtered (stream, "%llu", val_long); + fprintf_filtered (stream, "%llu", (long long) val_long); break; case 'x': fprintf_filtered (stream, use_local ? local_hex_format_custom ("ll") : "%llx", - val_long); + (unsigned long long) val_long); break; case 'o': fprintf_filtered (stream, use_local ? local_octal_format_custom ("ll") : "%llo", - val_long); + (unsigned long long) val_long); break; case 'b': fprintf_filtered (stream, local_hex_format_custom ("02ll"), val_long); @@ -414,109 +407,6 @@ print_longest (struct ui_file *stream, int format, int use_local, #endif /* CC_HAS_LONG_LONG || PRINTF_HAS_LONG_LONG */ } -#if 0 -void -strcat_longest (int format, int use_local, LONGEST val_long, char *buf, - int buflen) -{ -/* FIXME: Use buflen to avoid buffer overflow. */ -#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG) - long vtop, vbot; - - vtop = val_long >> (sizeof (long) * HOST_CHAR_BIT); - vbot = (long) val_long; - - if ((format == 'd' && (val_long < INT_MIN || val_long > INT_MAX)) - || ((format == 'u' || format == 'x') && (unsigned long long) val_long > UINT_MAX)) - { - sprintf (buf, "0x%lx%08lx", vtop, vbot); - return; - } -#endif - -#ifdef PRINTF_HAS_LONG_LONG - switch (format) - { - case 'd': - sprintf (buf, - (use_local ? local_decimal_format_custom ("ll") : "%lld"), - val_long); - break; - case 'u': - sprintf (buf, "%llu", val_long); - break; - case 'x': - sprintf (buf, - (use_local ? local_hex_format_custom ("ll") : "%llx"), - - val_long); - break; - case 'o': - sprintf (buf, - (use_local ? local_octal_format_custom ("ll") : "%llo"), - val_long); - break; - case 'b': - sprintf (buf, local_hex_format_custom ("02ll"), val_long); - break; - case 'h': - sprintf (buf, local_hex_format_custom ("04ll"), val_long); - break; - case 'w': - sprintf (buf, local_hex_format_custom ("08ll"), val_long); - break; - case 'g': - sprintf (buf, local_hex_format_custom ("016ll"), val_long); - break; - default: - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } -#else /* !PRINTF_HAS_LONG_LONG */ - /* In the following it is important to coerce (val_long) to a long. It does - nothing if !LONG_LONG, but it will chop off the top half (which we know - we can ignore) if the host supports long longs. */ - - switch (format) - { - case 'd': - sprintf (buf, (use_local ? local_decimal_format_custom ("l") : "%ld"), - ((long) val_long)); - break; - case 'u': - sprintf (buf, "%lu", ((unsigned long) val_long)); - break; - case 'x': - sprintf (buf, (use_local ? local_hex_format_custom ("l") : "%lx"), - ((long) val_long)); - break; - case 'o': - sprintf (buf, (use_local ? local_octal_format_custom ("l") : "%lo"), - ((long) val_long)); - break; - case 'b': - sprintf (buf, local_hex_format_custom ("02l"), - ((long) val_long)); - break; - case 'h': - sprintf (buf, local_hex_format_custom ("04l"), - ((long) val_long)); - break; - case 'w': - sprintf (buf, local_hex_format_custom ("08l"), - ((long) val_long)); - break; - case 'g': - sprintf (buf, local_hex_format_custom ("016l"), - ((long) val_long)); - break; - default: - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - } - -#endif /* !PRINTF_HAS_LONG_LONG */ -} -#endif - /* This used to be a macro, but I don't think it is called often enough to merit such treatment. */ /* Convert a LONGEST to an int. This is used in contexts (e.g. number of @@ -559,9 +449,9 @@ print_floating (char *valaddr, struct type *type, struct ui_file *stream) if (floatformat_is_negative (fmt, valaddr)) fprintf_filtered (stream, "-"); fprintf_filtered (stream, "nan("); - fprintf_filtered (stream, local_hex_format_prefix ()); - fprintf_filtered (stream, floatformat_mantissa (fmt, valaddr)); - fprintf_filtered (stream, local_hex_format_suffix ()); + fputs_filtered (local_hex_format_prefix (), stream); + fputs_filtered (floatformat_mantissa (fmt, valaddr), stream); + fputs_filtered (local_hex_format_suffix (), stream); fprintf_filtered (stream, ")"); return; } @@ -622,7 +512,7 @@ print_binary_chars (struct ui_file *stream, unsigned char *valaddr, /* FIXME: We should be not printing leading zeroes in most cases. */ - fprintf_filtered (stream, local_binary_format_prefix ()); + fputs_filtered (local_binary_format_prefix (), stream); if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { for (p = valaddr; @@ -660,7 +550,7 @@ print_binary_chars (struct ui_file *stream, unsigned char *valaddr, } } } - fprintf_filtered (stream, local_binary_format_suffix ()); + fputs_filtered (local_binary_format_suffix (), stream); } /* VALADDR points to an integer of LEN bytes. @@ -709,7 +599,7 @@ print_octal_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len) cycle = (len * BITS_IN_BYTES) % BITS_IN_OCTAL; carry = 0; - fprintf_filtered (stream, local_octal_format_prefix ()); + fputs_filtered (local_octal_format_prefix (), stream); if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { for (p = valaddr; @@ -808,7 +698,7 @@ print_octal_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len) } } - fprintf_filtered (stream, local_octal_format_suffix ()); + fputs_filtered (local_octal_format_suffix (), stream); } /* VALADDR points to an integer of LEN bytes. @@ -851,7 +741,7 @@ print_decimal_chars (struct ui_file *stream, unsigned char *valaddr, digits[i] = 0; } - fprintf_filtered (stream, local_decimal_format_prefix ()); + fputs_filtered (local_decimal_format_prefix (), stream); /* Ok, we have an unknown number of bytes of data to be printed in * decimal. @@ -948,19 +838,19 @@ print_decimal_chars (struct ui_file *stream, unsigned char *valaddr, } xfree (digits); - fprintf_filtered (stream, local_decimal_format_suffix ()); + fputs_filtered (local_decimal_format_suffix (), stream); } /* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */ -static void +void print_hex_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len) { unsigned char *p; /* FIXME: We should be not printing leading zeroes in most cases. */ - fprintf_filtered (stream, local_hex_format_prefix ()); + fputs_filtered (local_hex_format_prefix (), stream); if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { for (p = valaddr; @@ -979,7 +869,41 @@ print_hex_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len) fprintf_filtered (stream, "%02x", *p); } } - fprintf_filtered (stream, local_hex_format_suffix ()); + fputs_filtered (local_hex_format_suffix (), stream); +} + +/* VALADDR points to a char integer of LEN bytes. Print it out in appropriate language form on stream. + Omit any leading zero chars. */ + +void +print_char_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len) +{ + unsigned char *p; + + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + p = valaddr; + while (p < valaddr + len - 1 && *p == 0) + ++p; + + while (p < valaddr + len) + { + LA_EMIT_CHAR (*p, stream, '\''); + ++p; + } + } + else + { + p = valaddr + len - 1; + while (p > valaddr && *p == 0) + --p; + + while (p >= valaddr) + { + LA_EMIT_CHAR (*p, stream, '\''); + --p; + } + } } /* Called by various _val_print routines to print elements of an @@ -1290,14 +1214,12 @@ val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream) knows what they really did here. Radix setting is confusing, e.g. setting the input radix to "10" never changes it! */ -/* ARGSUSED */ static void set_input_radix (char *args, int from_tty, struct cmd_list_element *c) { - set_input_radix_1 (from_tty, *(unsigned *) c->var); + set_input_radix_1 (from_tty, input_radix); } -/* ARGSUSED */ static void set_input_radix_1 (int from_tty, unsigned radix) { @@ -1310,6 +1232,8 @@ set_input_radix_1 (int from_tty, unsigned radix) if (radix < 2) { + /* FIXME: cagney/2002-03-17: This needs to revert the bad radix + value. */ error ("Nonsense input radix ``decimal %u''; input radix unchanged.", radix); } @@ -1321,11 +1245,10 @@ set_input_radix_1 (int from_tty, unsigned radix) } } -/* ARGSUSED */ static void set_output_radix (char *args, int from_tty, struct cmd_list_element *c) { - set_output_radix_1 (from_tty, *(unsigned *) c->var); + set_output_radix_1 (from_tty, output_radix); } static void @@ -1345,6 +1268,8 @@ set_output_radix_1 (int from_tty, unsigned radix) output_format = 'o'; /* octal */ break; default: + /* FIXME: cagney/2002-03-17: This needs to revert the bad radix + value. */ error ("Unsupported output radix ``decimal %u''; output radix unchanged.", radix); } @@ -1381,7 +1306,6 @@ set_radix (char *arg, int from_tty) /* Show both the input and output radices. */ -/*ARGSUSED */ static void show_radix (char *arg, int from_tty) { @@ -1403,7 +1327,6 @@ show_radix (char *arg, int from_tty) } -/*ARGSUSED */ static void set_print (char *arg, int from_tty) { @@ -1412,7 +1335,6 @@ set_print (char *arg, int from_tty) help_list (setprintlist, "set print ", -1, gdb_stdout); } -/*ARGSUSED */ static void show_print (char *args, int from_tty) { diff --git a/contrib/gdb/gdb/valprint.h b/contrib/gdb/gdb/valprint.h index 52314aaa191..647b4bdc37d 100644 --- a/contrib/gdb/gdb/valprint.h +++ b/contrib/gdb/gdb/valprint.h @@ -33,6 +33,12 @@ extern int objectprint; /* Controls looking up an object's derived type extern unsigned int print_max; /* Max # of chars for strings/vectors */ +/* Flag to low-level print routines that this value is being printed + in an epoch window. We'd like to pass this as a parameter, but + every routine would need to take it. Perhaps we can encapsulate + this in the I/O stream once we have GNU stdio. */ +extern int inspect_it; + /* Print repeat counts if there are more than this many repetitions of an element in an array. Referenced by the low level language dependent print routines. */ @@ -57,4 +63,10 @@ extern void print_octal_chars (struct ui_file *, unsigned char *, extern void print_decimal_chars (struct ui_file *, unsigned char *, unsigned int); + +extern void print_hex_chars (struct ui_file *, unsigned char *, + unsigned int); + +extern void print_char_chars (struct ui_file *, unsigned char *, + unsigned int); #endif diff --git a/contrib/gdb/gdb/value.h b/contrib/gdb/gdb/value.h index d6fa9ff9c1f..690edb96e89 100644 --- a/contrib/gdb/gdb/value.h +++ b/contrib/gdb/gdb/value.h @@ -1,6 +1,7 @@ /* Definitions for values of C expressions, for GDB. + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -24,97 +25,109 @@ #define VALUE_H 1 #include "doublest.h" +#include "frame.h" /* For struct frame_id. */ -/* - * The structure which defines the type of a value. It should never - * be possible for a program lval value to survive over a call to the inferior - * (ie to be put into the history list or an internal variable). - */ +struct block; +struct expression; +struct regcache; +struct symbol; +struct type; +struct ui_file; + +/* The structure which defines the type of a value. It should never + be possible for a program lval value to survive over a call to the + inferior (i.e. to be put into the history list or an internal + variable). */ struct value +{ + /* Type of value; either not an lval, or one of the various + different possible kinds of lval. */ + enum lval_type lval; + + /* Is it modifiable? Only relevant if lval != not_lval. */ + int modifiable; + + /* Location of value (if lval). */ + union { - /* Type of value; either not an lval, or one of the various - different possible kinds of lval. */ - enum lval_type lval; - /* Is it modifiable? Only relevant if lval != not_lval. */ - int modifiable; - /* Location of value (if lval). */ - union - { - /* If lval == lval_memory, this is the address in the inferior. - If lval == lval_register, this is the byte offset into the - registers structure. */ - CORE_ADDR address; - /* Pointer to internal variable. */ - struct internalvar *internalvar; - /* Number of register. Only used with - lval_reg_frame_relative. */ - int regnum; - } - location; - /* Describes offset of a value within lval of a structure in bytes. - If lval == lval_memory, this is an offset to the address. - If lval == lval_register, this is a further offset from - location.address within the registers structure. - Note also the member embedded_offset below. */ - int offset; - /* Only used for bitfields; number of bits contained in them. */ - int bitsize; - /* Only used for bitfields; position of start of field. - For BITS_BIG_ENDIAN=0 targets, it is the position of the LSB. - For BITS_BIG_ENDIAN=1 targets, it is the position of the MSB. */ + /* If lval == lval_memory, this is the address in the inferior. + If lval == lval_register, this is the byte offset into the + registers structure. */ + CORE_ADDR address; + + /* Pointer to internal variable. */ + struct internalvar *internalvar; + + /* Number of register. Only used with lval_reg_frame_relative. */ + int regnum; + } location; + + /* Describes offset of a value within lval of a structure in bytes. + If lval == lval_memory, this is an offset to the address. + If lval == lval_register, this is a further offset from + location.address within the registers structure. + Note also the member embedded_offset below. */ + int offset; + + /* Only used for bitfields; number of bits contained in them. */ + int bitsize; + + /* Only used for bitfields; position of start of field. + For BITS_BIG_ENDIAN=0 targets, it is the position of the LSB. + For BITS_BIG_ENDIAN=1 targets, it is the position of the MSB. */ int bitpos; - /* Frame value is relative to. In practice, this address is only - used if the value is stored in several registers in other than - the current frame, and these registers have not all been saved - at the same place in memory. This will be described in the - lval enum above as "lval_reg_frame_relative". */ - CORE_ADDR frame_addr; - /* Type of the value. */ - struct type *type; + /* Frame value is relative to. In practice, this ID is only used if + the value is stored in several registers in other than the + current frame, and these registers have not all been saved at the + same place in memory. This will be described in the lval enum + above as "lval_reg_frame_relative". */ + struct frame_id frame_id; - /* If a value represents a C++ object, then the `type' field gives - the object's compile-time type. If the object actually belongs - to some class derived from `type', perhaps with other base - classes and additional members, then `type' is just a subobject - of the real thing, and the full object is probably larger than - `type' would suggest. + /* Type of the value. */ + struct type *type; - If `type' is a dynamic class (i.e. one with a vtable), then GDB - can actually determine the object's run-time type by looking at - the run-time type information in the vtable. When this - information is available, we may elect to read in the entire - object, for several reasons: + /* If a value represents a C++ object, then the `type' field gives + the object's compile-time type. If the object actually belongs + to some class derived from `type', perhaps with other base + classes and additional members, then `type' is just a subobject + of the real thing, and the full object is probably larger than + `type' would suggest. - - When printing the value, the user would probably rather see - the full object, not just the limited portion apparent from - the compile-time type. + If `type' is a dynamic class (i.e. one with a vtable), then GDB + can actually determine the object's run-time type by looking at + the run-time type information in the vtable. When this + information is available, we may elect to read in the entire + object, for several reasons: - - If `type' has virtual base classes, then even printing - `type' alone may require reaching outside the `type' - portion of the object to wherever the virtual base class - has been stored. + - When printing the value, the user would probably rather see the + full object, not just the limited portion apparent from the + compile-time type. - When we store the entire object, `enclosing_type' is the - run-time type --- the complete object --- and `embedded_offset' - is the offset of `type' within that larger type, in bytes. The - VALUE_CONTENTS macro takes `embedded_offset' into account, so - most GDB code continues to see the `type' portion of the value, - just as the inferior would. + - If `type' has virtual base classes, then even printing `type' + alone may require reaching outside the `type' portion of the + object to wherever the virtual base class has been stored. - If `type' is a pointer to an object, then `enclosing_type' is a - pointer to the object's run-time type, and `pointed_to_offset' - is the offset in bytes from the full object to the pointed-to - object --- that is, the value `embedded_offset' would have if - we followed the pointer and fetched the complete object. (I - don't really see the point. Why not just determine the - run-time type when you indirect, and avoid the special case? - The contents don't matter until you indirect anyway.) + When we store the entire object, `enclosing_type' is the run-time + type -- the complete object -- and `embedded_offset' is the + offset of `type' within that larger type, in bytes. The + VALUE_CONTENTS macro takes `embedded_offset' into account, so + most GDB code continues to see the `type' portion of the value, + just as the inferior would. - If we're not doing anything fancy, `enclosing_type' is equal to - `type', and `embedded_offset' is zero, so everything works - normally. */ + If `type' is a pointer to an object, then `enclosing_type' is a + pointer to the object's run-time type, and `pointed_to_offset' is + the offset in bytes from the full object to the pointed-to object + -- that is, the value `embedded_offset' would have if we + followed the pointer and fetched the complete object. (I don't + really see the point. Why not just determine the run-time type + when you indirect, and avoid the special case? The contents + don't matter until you indirect anyway.) + + If we're not doing anything fancy, `enclosing_type' is equal to + `type', and `embedded_offset' is zero, so everything works + normally. */ struct type *enclosing_type; int embedded_offset; int pointed_to_offset; @@ -125,22 +138,13 @@ struct value list. */ struct value *next; - /* ??? When is this used? */ - union - { - CORE_ADDR memaddr; - char *myaddr; - } - substring_addr; - - /* Register number if the value is from a register. Is not kept - if you take a field of a structure that is stored in a - register. Shouldn't it be? */ + /* Register number if the value is from a register. */ short regno; - /* If zero, contents of this value are in the contents field. - If nonzero, contents are in inferior memory at address - in the location.address field plus the offset field - (and the lval field should be lval_memory). + + /* If zero, contents of this value are in the contents field. If + nonzero, contents are in inferior memory at address in the + location.address field plus the offset field (and the lval + field should be lval_memory). WARNING: This field is used by the code which handles watchpoints (see breakpoint.c) to decide whether a particular @@ -153,52 +157,59 @@ struct value lazy flag is set and reset, be sure to consider this use as well! */ char lazy; + /* If nonzero, this is the value of a variable which does not actually exist in the program. */ char optimized_out; + /* The BFD section associated with this value. */ asection *bfd_section; + /* Actual contents of the value. For use of this value; setting it uses the stuff above. Not valid if lazy is nonzero. Target byte-order. We force it to be aligned properly for any possible value. Note that a value therefore extends beyond what is declared here. */ union - { - long contents[1]; - double force_double_align; - LONGEST force_longlong_align; - char *literal_data; - } - aligner; - /* Do not add any new members here -- contents above will trash them */ - }; + { + long contents[1]; + DOUBLEST force_doublest_align; + LONGEST force_longest_align; + CORE_ADDR force_core_addr_align; + void *force_pointer_align; + } aligner; + /* Do not add any new members here -- contents above will trash them. */ +}; #define VALUE_TYPE(val) (val)->type #define VALUE_ENCLOSING_TYPE(val) (val)->enclosing_type #define VALUE_LAZY(val) (val)->lazy + /* VALUE_CONTENTS and VALUE_CONTENTS_RAW both return the address of - the gdb buffer used to hold a copy of the contents of the lval. - VALUE_CONTENTS is used when the contents of the buffer are needed -- - it uses value_fetch_lazy() to load the buffer from the process being - debugged if it hasn't already been loaded. VALUE_CONTENTS_RAW is - used when data is being stored into the buffer, or when it is - certain that the contents of the buffer are valid. + the gdb buffer used to hold a copy of the contents of the lval. + VALUE_CONTENTS is used when the contents of the buffer are needed + -- it uses value_fetch_lazy() to load the buffer from the process + being debugged if it hasn't already been loaded. + VALUE_CONTENTS_RAW is used when data is being stored into the + buffer, or when it is certain that the contents of the buffer are + valid. + Note: The contents pointer is adjusted by the offset required to get to the real subobject, if the value happens to represent - something embedded in a larger run-time object. */ + something embedded in a larger run-time object. */ -#define VALUE_CONTENTS_RAW(val) ((char *) (val)->aligner.contents + (val)->embedded_offset) -#define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\ - VALUE_CONTENTS_RAW(val)) +#define VALUE_CONTENTS_RAW(val) \ + ((char *) (val)->aligner.contents + (val)->embedded_offset) +#define VALUE_CONTENTS(val) \ + ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)), VALUE_CONTENTS_RAW(val)) /* The ALL variants of the above two macros do not adjust the returned - pointer by the embedded_offset value. */ + pointer by the embedded_offset value. */ #define VALUE_CONTENTS_ALL_RAW(val) ((char *) (val)->aligner.contents) -#define VALUE_CONTENTS_ALL(val) ((void) (VALUE_LAZY(val) && value_fetch_lazy(val)),\ - VALUE_CONTENTS_ALL_RAW(val)) - +#define VALUE_CONTENTS_ALL(val) \ + ((void) (VALUE_LAZY(val) && value_fetch_lazy(val)), \ + VALUE_CONTENTS_ALL_RAW(val)) extern int value_fetch_lazy (struct value *val); @@ -206,7 +217,7 @@ extern int value_fetch_lazy (struct value *val); #define VALUE_ADDRESS(val) (val)->location.address #define VALUE_INTERNALVAR(val) (val)->location.internalvar #define VALUE_FRAME_REGNUM(val) ((val)->location.regnum) -#define VALUE_FRAME(val) ((val)->frame_addr) +#define VALUE_FRAME_ID(val) ((val)->frame_id) #define VALUE_OFFSET(val) (val)->offset #define VALUE_BITSIZE(val) (val)->bitsize #define VALUE_BITPOS(val) (val)->bitpos @@ -217,16 +228,17 @@ extern int value_fetch_lazy (struct value *val); #define VALUE_POINTED_TO_OFFSET(val) ((val)->pointed_to_offset) #define VALUE_BFD_SECTION(val) ((val)->bfd_section) -/* Convert a REF to the object referenced. */ +/* Convert a REF to the object referenced. */ -#define COERCE_REF(arg) \ -do { struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg));\ - if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF) \ - arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp), \ - unpack_pointer (VALUE_TYPE (arg), \ - VALUE_CONTENTS (arg)), \ - VALUE_BFD_SECTION (arg)); \ - } while (0) +#define COERCE_REF(arg) \ + do { \ + struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg)); \ + if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF) \ + arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp), \ + unpack_pointer (VALUE_TYPE (arg), \ + VALUE_CONTENTS (arg)), \ + VALUE_BFD_SECTION (arg)); \ + } while (0) /* If ARG is an array, convert it to a pointer. If ARG is an enum, convert it to an integer. @@ -234,40 +246,42 @@ do { struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg));\ References are dereferenced. */ -#define COERCE_ARRAY(arg) \ -do { COERCE_REF(arg); \ - if (current_language->c_style_arrays \ - && TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY) \ - arg = value_coerce_array (arg); \ - if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC) \ - arg = value_coerce_function (arg); \ -} while (0) +#define COERCE_ARRAY(arg) \ + do { \ + COERCE_REF(arg); \ + if (current_language->c_style_arrays \ + && TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY) \ + arg = value_coerce_array (arg); \ + if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC) \ + arg = value_coerce_function (arg); \ + } while (0) -#define COERCE_NUMBER(arg) \ - do { COERCE_ARRAY(arg); COERCE_ENUM(arg); } while (0) +#define COERCE_NUMBER(arg) \ + do { COERCE_ARRAY(arg); COERCE_ENUM(arg); } while (0) -#define COERCE_VARYING_ARRAY(arg, real_arg_type) \ -{ if (chill_varying_type (real_arg_type)) \ - arg = varying_to_slice (arg), real_arg_type = VALUE_TYPE (arg); } +/* NOTE: cagney/2002-12-17: This macro was handling a chill language + problem but that language has gone away. */ +#define COERCE_VARYING_ARRAY(arg, real_arg_type) /* If ARG is an enum, convert it to an integer. */ -#define COERCE_ENUM(arg) { \ - if (TYPE_CODE (check_typedef (VALUE_TYPE (arg))) == TYPE_CODE_ENUM) \ - arg = value_cast (builtin_type_unsigned_int, arg); \ -} +#define COERCE_ENUM(arg) \ + do { \ + if (TYPE_CODE (check_typedef (VALUE_TYPE (arg))) == TYPE_CODE_ENUM) \ + arg = value_cast (builtin_type_unsigned_int, arg); \ + } while (0) /* Internal variables (variables for convenience of use of debugger) are recorded as a chain of these structures. */ struct internalvar - { - struct internalvar *next; - char *name; - struct value *value; - }; +{ + struct internalvar *next; + char *name; + struct value *value; +}; -/* Pointer to member function. Depends on compiler implementation. */ +/* Pointer to member function. Depends on compiler implementation. */ #define METHOD_PTR_IS_VIRTUAL(ADDR) ((ADDR) & 0x80000000) #define METHOD_PTR_FROM_VOFFSET(OFFSET) (0x80000000 + (OFFSET)) @@ -284,31 +298,23 @@ struct fn_field; extern void print_address_demangle (CORE_ADDR, struct ui_file *, int); extern LONGEST value_as_long (struct value *val); - extern DOUBLEST value_as_double (struct value *val); - extern CORE_ADDR value_as_address (struct value *val); -extern LONGEST unpack_long (struct type *type, char *valaddr); - -extern DOUBLEST unpack_double (struct type *type, char *valaddr, int *invp); - -extern CORE_ADDR unpack_pointer (struct type *type, char *valaddr); - -extern LONGEST unpack_field_as_long (struct type *type, char *valaddr, +extern LONGEST unpack_long (struct type *type, const char *valaddr); +extern DOUBLEST unpack_double (struct type *type, const char *valaddr, + int *invp); +extern CORE_ADDR unpack_pointer (struct type *type, const char *valaddr); +extern LONGEST unpack_field_as_long (struct type *type, const char *valaddr, int fieldno); extern struct value *value_from_longest (struct type *type, LONGEST num); - extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr); - extern struct value *value_from_double (struct type *type, DOUBLEST num); - extern struct value *value_from_string (char *string); extern struct value *value_at (struct type *type, CORE_ADDR addr, asection * sect); - extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr, asection * sect); @@ -317,7 +323,8 @@ extern struct value *value_from_register (struct type *type, int regnum, extern struct value *value_of_variable (struct symbol *var, struct block *b); -extern struct value *value_of_register (int regnum); +extern struct value *value_of_register (int regnum, + struct frame_info *frame); extern int symbol_read_needs_frame (struct symbol *); @@ -372,16 +379,14 @@ extern struct value *value_struct_elt (struct value **argp, char *name, int *static_memfuncp, char *err); -extern struct value *value_struct_elt_for_reference (struct type *domain, - int offset, - struct type *curtype, - char *name, - struct type *intype); +extern struct value *value_aggregate_elt (struct type *curtype, + char *name, + enum noside noside); extern struct value *value_static_field (struct type *type, int fieldno); extern struct fn_field *value_find_oload_method_list (struct value **, char *, - int, int *, int *, + int, int *, struct type **, int *); extern int find_overload_match (struct type **arg_types, int nargs, @@ -411,20 +416,14 @@ extern struct value *value_repeat (struct value *arg1, int count); extern struct value *value_subscript (struct value *array, struct value *idx); -extern struct value *value_from_vtable_info (struct value *arg, - struct type *type); - -extern struct value *value_being_returned (struct type *valtype, - char *retbuf, int struct_return); +extern struct value *register_value_being_returned (struct type *valtype, + struct regcache *retbuf); extern struct value *value_in (struct value *element, struct value *set); extern int value_bit_index (struct type *type, char *addr, int index); -extern int using_struct_return (struct value *function, CORE_ADDR funcaddr, - struct type *value_type, int gcc_p); - -extern void set_return_value (struct value *val); +extern int using_struct_return (struct type *value_type, int gcc_p); extern struct value *evaluate_expression (struct expression *exp); @@ -494,8 +493,8 @@ extern void release_value (struct value *val); extern int record_latest_value (struct value *val); -extern void -modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize); +extern void modify_field (char *addr, LONGEST fieldval, int bitpos, + int bitsize); extern void type_print (struct type * type, char *varstring, struct ui_file * stream, int show); @@ -551,25 +550,20 @@ extern struct value *varying_to_slice (struct value *); extern struct value *value_slice (struct value *, int, int); -extern struct value *call_function_by_hand (struct value *, int, - struct value **); - -extern int default_coerce_float_to_double (struct type *, struct type *); - -extern int standard_coerce_float_to_double (struct type *, struct type *); - extern struct value *value_literal_complex (struct value *, struct value *, struct type *); extern void find_rt_vbase_offset (struct type *, struct type *, char *, int, int *, int *); -extern struct value *find_function_in_inferior (char *); +extern struct value *find_function_in_inferior (const char *); extern struct value *value_allocate_space_in_inferior (int); -extern CORE_ADDR default_push_arguments (int nargs, struct value ** args, - CORE_ADDR sp, int struct_return, - CORE_ADDR struct_addr); +extern CORE_ADDR legacy_push_arguments (int nargs, struct value ** args, + CORE_ADDR sp, int struct_return, + CORE_ADDR struct_addr); + +extern struct value *value_of_local (const char *name, int complain); #endif /* !defined (VALUE_H) */ diff --git a/contrib/gdb/gdb/values.c b/contrib/gdb/gdb/values.c index 9445d9c4561..87baf2144b9 100644 --- a/contrib/gdb/gdb/values.c +++ b/contrib/gdb/gdb/values.c @@ -1,7 +1,8 @@ /* Low level packing and unpacking of values for GDB, the GNU Debugger. + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2002. - Free Software Foundation, Inc. + 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003 Free Software + Foundation, Inc. This file is part of GDB. @@ -34,6 +35,8 @@ #include "demangle.h" #include "doublest.h" #include "gdb_assert.h" +#include "regcache.h" +#include "block.h" /* Prototypes for exported functions. */ @@ -41,8 +44,6 @@ void _initialize_values (void); /* Prototypes for local functions. */ -static struct value *value_headof (struct value *, struct type *, struct type *); - static void show_values (char *, int); static void show_convenience (char *, int); @@ -89,7 +90,7 @@ allocate_value (struct type *type) VALUE_ENCLOSING_TYPE (val) = type; VALUE_LVAL (val) = not_lval; VALUE_ADDRESS (val) = 0; - VALUE_FRAME (val) = 0; + VALUE_FRAME_ID (val) = null_frame_id; VALUE_OFFSET (val) = 0; VALUE_BITPOS (val) = 0; VALUE_BITSIZE (val) = 0; @@ -213,7 +214,7 @@ value_release_to_mark (struct value *mark) struct value * value_copy (struct value *arg) { - register struct type *encl_type = VALUE_ENCLOSING_TYPE (arg); + struct type *encl_type = VALUE_ENCLOSING_TYPE (arg); struct value *val = allocate_value (encl_type); VALUE_TYPE (val) = VALUE_TYPE (arg); VALUE_LVAL (val) = VALUE_LVAL (arg); @@ -221,7 +222,7 @@ value_copy (struct value *arg) VALUE_OFFSET (val) = VALUE_OFFSET (arg); VALUE_BITPOS (val) = VALUE_BITPOS (arg); VALUE_BITSIZE (val) = VALUE_BITSIZE (arg); - VALUE_FRAME (val) = VALUE_FRAME (arg); + VALUE_FRAME_ID (val) = VALUE_FRAME_ID (arg); VALUE_REGNO (val) = VALUE_REGNO (arg); VALUE_LAZY (val) = VALUE_LAZY (arg); VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg); @@ -290,8 +291,8 @@ struct value * access_value_history (int num) { struct value_history_chunk *chunk; - register int i; - register int absnum = num; + int i; + int absnum = num; if (absnum <= 0) absnum += value_history_count; @@ -328,7 +329,7 @@ void clear_value_history (void) { struct value_history_chunk *next; - register int i; + int i; struct value *val; while (value_history_chain) @@ -346,7 +347,7 @@ clear_value_history (void) static void show_values (char *num_exp, int from_tty) { - register int i; + int i; struct value *val; static int num = 1; @@ -403,10 +404,10 @@ static struct internalvar *internalvars; struct internalvar * lookup_internalvar (char *name) { - register struct internalvar *var; + struct internalvar *var; for (var = internalvars; var; var = var->next) - if (STREQ (var->name, name)) + if (strcmp (var->name, name) == 0) return var; var = (struct internalvar *) xmalloc (sizeof (struct internalvar)); @@ -423,11 +424,6 @@ value_of_internalvar (struct internalvar *var) { struct value *val; -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - return VALUE_OF_TRAPPED_INTERNALVAR (var); -#endif - val = value_copy (var->value); if (VALUE_LAZY (val)) value_fetch_lazy (val); @@ -440,12 +436,7 @@ void set_internalvar_component (struct internalvar *var, int offset, int bitpos, int bitsize, struct value *newval) { - register char *addr = VALUE_CONTENTS (var->value) + offset; - -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - SET_TRAPPED_INTERNALVAR (var, newval, bitpos, bitsize, offset); -#endif + char *addr = VALUE_CONTENTS (var->value) + offset; if (bitsize) modify_field (addr, value_as_long (newval), @@ -459,11 +450,6 @@ set_internalvar (struct internalvar *var, struct value *val) { struct value *newval; -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - SET_TRAPPED_INTERNALVAR (var, val, 0, 0, 0); -#endif - newval = value_copy (val); newval->modifiable = 1; @@ -497,7 +483,7 @@ internalvar_name (struct internalvar *var) void clear_internalvars (void) { - register struct internalvar *var; + struct internalvar *var; while (internalvars) { @@ -512,15 +498,11 @@ clear_internalvars (void) static void show_convenience (char *ignore, int from_tty) { - register struct internalvar *var; + struct internalvar *var; int varseen = 0; for (var = internalvars; var; var = var->next) { -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - continue; -#endif if (!varseen) { varseen = 1; @@ -680,11 +662,11 @@ value_as_address (struct value *val) to an INT (or some size). After all, it is only an offset. */ LONGEST -unpack_long (struct type *type, char *valaddr) +unpack_long (struct type *type, const char *valaddr) { - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); - register int nosign = TYPE_UNSIGNED (type); + enum type_code code = TYPE_CODE (type); + int len = TYPE_LENGTH (type); + int nosign = TYPE_UNSIGNED (type); if (current_language->la_language == language_scm && is_scmvalue_type (type)) @@ -729,7 +711,7 @@ unpack_long (struct type *type, char *valaddr) format, result is in host format. */ DOUBLEST -unpack_double (struct type *type, char *valaddr, int *invp) +unpack_double (struct type *type, const char *valaddr, int *invp) { enum type_code code; int len; @@ -757,7 +739,14 @@ unpack_double (struct type *type, char *valaddr, int *invp) also not defined either. Oops! Hopefully someone will add both the missing floatformat - definitions and floatformat_is_invalid() function. */ + definitions and the new cases for floatformat_is_valid (). */ + + if (!floatformat_is_valid (floatformat_from_type (type), valaddr)) + { + *invp = 1; + return 0.0; + } + return extract_typed_floating (valaddr, type); } else if (nosign) @@ -786,7 +775,7 @@ unpack_double (struct type *type, char *valaddr, int *invp) to an INT (or some size). After all, it is only an offset. */ CORE_ADDR -unpack_pointer (struct type *type, char *valaddr) +unpack_pointer (struct type *type, const char *valaddr) { /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure whether we want this to be true eventually. */ @@ -794,22 +783,25 @@ unpack_pointer (struct type *type, char *valaddr) } -/* Get the value of the FIELDN'th field (which must be static) of TYPE. */ +/* Get the value of the FIELDN'th field (which must be static) of + TYPE. Return NULL if the field doesn't exist or has been + optimized out. */ struct value * value_static_field (struct type *type, int fieldno) { - CORE_ADDR addr; - asection *sect; + struct value *retval; + if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno)) { - addr = TYPE_FIELD_STATIC_PHYSADDR (type, fieldno); - sect = NULL; + retval = value_at (TYPE_FIELD_TYPE (type, fieldno), + TYPE_FIELD_STATIC_PHYSADDR (type, fieldno), + NULL); } else { char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno); - struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL); + struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0, NULL); if (sym == NULL) { /* With some compilers, e.g. HP aCC, static data members are reported @@ -819,27 +811,25 @@ value_static_field (struct type *type, int fieldno) return NULL; else { - addr = SYMBOL_VALUE_ADDRESS (msym); - sect = SYMBOL_BFD_SECTION (msym); + retval = value_at (TYPE_FIELD_TYPE (type, fieldno), + SYMBOL_VALUE_ADDRESS (msym), + SYMBOL_BFD_SECTION (msym)); } } else { - /* Anything static that isn't a constant, has an address */ - if (SYMBOL_CLASS (sym) != LOC_CONST) - { - addr = SYMBOL_VALUE_ADDRESS (sym); - sect = SYMBOL_BFD_SECTION (sym); - } - /* However, static const's do not, the value is already known. */ - else - { - return value_from_longest (TYPE_FIELD_TYPE (type, fieldno), SYMBOL_VALUE (sym)); - } + /* SYM should never have a SYMBOL_CLASS which will require + read_var_value to use the FRAME parameter. */ + if (symbol_read_needs_frame (sym)) + warning ("static field's value depends on the current " + "frame - bad debug info?"); + retval = read_var_value (sym, NULL); } - SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), addr); + if (retval && VALUE_LVAL (retval) == lval_memory) + SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), + VALUE_ADDRESS (retval)); } - return value_at (TYPE_FIELD_TYPE (type, fieldno), addr, sect); + return retval; } /* Change the enclosing type of a value object VAL to NEW_ENCL_TYPE. @@ -862,7 +852,9 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type) struct value *prev; new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type)); - + + VALUE_ENCLOSING_TYPE (new_val) = new_encl_type; + /* We have to make sure this ends up in the same place in the value chain as the original copy, so it's clean-up behavior is the same. If the value has been released, this is a waste of time, but there @@ -891,10 +883,10 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type) struct value * value_primitive_field (struct value *arg1, int offset, - register int fieldno, register struct type *arg_type) + int fieldno, struct type *arg_type) { struct value *v; - register struct type *type; + struct type *type; CHECK_TYPEDEF (arg_type); type = TYPE_FIELD_TYPE (arg_type, fieldno); @@ -960,7 +952,7 @@ value_primitive_field (struct value *arg1, int offset, FIELDNO says which field. */ struct value * -value_field (struct value *arg1, register int fieldno) +value_field (struct value *arg1, int fieldno) { return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1)); } @@ -978,12 +970,12 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty int offset) { struct value *v; - register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); + struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); struct symbol *sym; struct minimal_symbol *msym; - sym = lookup_symbol (physname, 0, VAR_NAMESPACE, 0, NULL); + sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0, NULL); if (sym != NULL) { msym = NULL; @@ -1020,93 +1012,6 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty return v; } -/* ARG is a pointer to an object we know to be at least - a DTYPE. BTYPE is the most derived basetype that has - already been searched (and need not be searched again). - After looking at the vtables between BTYPE and DTYPE, - return the most derived type we find. The caller must - be satisfied when the return value == DTYPE. - - FIXME-tiemann: should work with dossier entries as well. - NOTICE - djb: I see no good reason at all to keep this function now that - we have RTTI support. It's used in literally one place, and it's - hard to keep this function up to date when it's purpose is served - by value_rtti_type efficiently. - Consider it gone for 5.1. */ - -static struct value * -value_headof (struct value *in_arg, struct type *btype, struct type *dtype) -{ - /* First collect the vtables we must look at for this object. */ - struct value *arg; - struct value *vtbl; - struct symbol *sym; - char *demangled_name; - struct minimal_symbol *msymbol; - - btype = TYPE_VPTR_BASETYPE (dtype); - CHECK_TYPEDEF (btype); - arg = in_arg; - if (btype != dtype) - arg = value_cast (lookup_pointer_type (btype), arg); - if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_REF) - { - /* - * Copy the value, but change the type from (T&) to (T*). - * We keep the same location information, which is efficient, - * and allows &(&X) to get the location containing the reference. - */ - arg = value_copy (arg); - VALUE_TYPE (arg) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg))); - } - if (VALUE_ADDRESS(value_field (value_ind(arg), TYPE_VPTR_FIELDNO (btype)))==0) - return arg; - - vtbl = value_ind (value_field (value_ind (arg), TYPE_VPTR_FIELDNO (btype))); - /* Turn vtable into typeinfo function */ - VALUE_OFFSET(vtbl)+=4; - - msymbol = lookup_minimal_symbol_by_pc ( value_as_address(value_ind(vtbl)) ); - if (msymbol == NULL - || (demangled_name = SYMBOL_NAME (msymbol)) == NULL) - { - /* If we expected to find a vtable, but did not, let the user - know that we aren't happy, but don't throw an error. - FIXME: there has to be a better way to do this. */ - struct type *error_type = (struct type *) xmalloc (sizeof (struct type)); - memcpy (error_type, VALUE_TYPE (in_arg), sizeof (struct type)); - TYPE_NAME (error_type) = savestring ("suspicious *", sizeof ("suspicious *")); - VALUE_TYPE (in_arg) = error_type; - return in_arg; - } - demangled_name = cplus_demangle(demangled_name,DMGL_ANSI); - *(strchr (demangled_name, ' ')) = '\0'; - - sym = lookup_symbol (demangled_name, 0, VAR_NAMESPACE, 0, 0); - if (sym == NULL) - error ("could not find type declaration for `%s'", demangled_name); - - arg = in_arg; - VALUE_TYPE (arg) = lookup_pointer_type (SYMBOL_TYPE (sym)); - return arg; -} - -/* ARG is a pointer object of type TYPE. If TYPE has virtual - function tables, probe ARG's tables (including the vtables - of its baseclasses) to figure out the most derived type that ARG - could actually be a pointer to. */ - -struct value * -value_from_vtable_info (struct value *arg, struct type *type) -{ - /* Take care of preliminaries. */ - if (TYPE_VPTR_FIELDNO (type) < 0) - fill_in_vptr_fieldno (type); - if (TYPE_VPTR_FIELDNO (type) < 0) - return 0; - - return value_headof (arg, 0, type); -} /* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at VALADDR. @@ -1123,7 +1028,7 @@ value_from_vtable_info (struct value *arg, struct type *type) If the field is signed, we also do sign extension. */ LONGEST -unpack_field_as_long (struct type *type, char *valaddr, int fieldno) +unpack_field_as_long (struct type *type, const char *valaddr, int fieldno) { ULONGEST val; ULONGEST valmask; @@ -1209,11 +1114,11 @@ modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize) /* Convert C numbers into newly allocated values */ struct value * -value_from_longest (struct type *type, register LONGEST num) +value_from_longest (struct type *type, LONGEST num) { struct value *val = allocate_value (type); - register enum type_code code; - register int len; + enum type_code code; + int len; retry: code = TYPE_CODE (type); len = TYPE_LENGTH (type); @@ -1284,8 +1189,8 @@ value_from_double (struct type *type, DOUBLEST num) { struct value *val = allocate_value (type); struct type *base_type = check_typedef (type); - register enum type_code code = TYPE_CODE (base_type); - register int len = TYPE_LENGTH (base_type); + enum type_code code = TYPE_CODE (base_type); + int len = TYPE_LENGTH (base_type); if (code == TYPE_CODE_FLT) { @@ -1297,47 +1202,54 @@ value_from_double (struct type *type, DOUBLEST num) return val; } -/* Deal with the value that is "about to be returned". */ +/* Deal with the return-value of a function that has "just returned". -/* Return the value that a function returning now - would be returning to its caller, assuming its type is VALTYPE. - RETBUF is where we look for what ought to be the contents - of the registers (in raw form). This is because it is often - desirable to restore old values to those registers - after saving the contents of interest, and then call - this function using the saved values. - struct_return is non-zero when the function in question is - using the structure return conventions on the machine in question; - 0 when it is using the value returning conventions (this often - means returning pointer to where structure is vs. returning value). */ + Extract the return-value (as a "struct value") that a function, + using register convention, has just returned to its caller. Assume + that the type of the function is VALTYPE, and that the "just + returned" register state is found in RETBUF. + + The function has "just returned" because GDB halts a returning + function by setting a breakpoint at the return address (in the + caller), and not the return instruction (in the callee). + + Because, in the case of a return from an inferior function call, + GDB needs to restore the inferiors registers, RETBUF is normally a + copy of the inferior's registers. */ -/* ARGSUSED */ struct value * -value_being_returned (struct type *valtype, char *retbuf, int struct_return) +register_value_being_returned (struct type *valtype, struct regcache *retbuf) { - struct value *val; - CORE_ADDR addr; + struct value *val = allocate_value (valtype); - /* If this is not defined, just use EXTRACT_RETURN_VALUE instead. */ - if (EXTRACT_STRUCT_VALUE_ADDRESS_P ()) - if (struct_return) - { - addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf); - if (!addr) - error ("Function return value unknown."); - return value_at (valtype, addr, NULL); - } + /* If the function returns void, don't bother fetching the return + value. See also "using_struct_return". */ + if (TYPE_CODE (valtype) == TYPE_CODE_VOID) + return val; - val = allocate_value (valtype); - CHECK_TYPEDEF (valtype); - EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val)); + if (!gdbarch_return_value_p (current_gdbarch)) + { + /* NOTE: cagney/2003-10-20: Unlike "gdbarch_return_value", the + EXTRACT_RETURN_VALUE and USE_STRUCT_CONVENTION methods do not + handle the edge case of a function returning a small + structure / union in registers. */ + CHECK_TYPEDEF (valtype); + EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val)); + return val; + } + /* This function only handles "register convention". */ + gdb_assert (gdbarch_return_value (current_gdbarch, valtype, + NULL, NULL, NULL) + == RETURN_VALUE_REGISTER_CONVENTION); + gdbarch_return_value (current_gdbarch, valtype, retbuf, + VALUE_CONTENTS_RAW (val) /*read*/, NULL /*write*/); return val; } -/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of - EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc - and TYPE is the type (which is known to be struct, union or array). +/* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of + EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc and TYPE + is the type (which is known to be struct, union or array). On most machines, the struct convention is used unless we are using gcc and the type is of a special size. */ @@ -1360,52 +1272,45 @@ generic_use_struct_convention (int gcc_p, struct type *value_type) || TYPE_LENGTH (value_type) == 8)); } -/* Return true if the function specified is using the structure returning - convention on this machine to return arguments, or 0 if it is using - the value returning convention. FUNCTION is the value representing - the function, FUNCADDR is the address of the function, and VALUE_TYPE - is the type returned by the function. GCC_P is nonzero if compiled +/* Return true if the function returning the specified type is using + the convention of returning structures in memory (passing in the + address as a hidden first parameter). GCC_P is nonzero if compiled with GCC. */ -/* ARGSUSED */ int -using_struct_return (struct value *function, CORE_ADDR funcaddr, - struct type *value_type, int gcc_p) +using_struct_return (struct type *value_type, int gcc_p) { - register enum type_code code = TYPE_CODE (value_type); + enum type_code code = TYPE_CODE (value_type); if (code == TYPE_CODE_ERROR) error ("Function return type unknown."); - if (code == TYPE_CODE_STRUCT - || code == TYPE_CODE_UNION - || code == TYPE_CODE_ARRAY - || RETURN_VALUE_ON_STACK (value_type)) - return USE_STRUCT_CONVENTION (gcc_p, value_type); + if (code == TYPE_CODE_VOID) + /* A void return value is never in memory. See also corresponding + code in "register_value_being_returned". */ + return 0; - return 0; + if (!gdbarch_return_value_p (current_gdbarch)) + { + /* FIXME: cagney/2003-10-01: The below is dead. Instead an + architecture should implement "gdbarch_return_value". Using + that new function it is possible to exactly specify the ABIs + "struct return" vs "register return" conventions. */ + if (code == TYPE_CODE_STRUCT + || code == TYPE_CODE_UNION + || code == TYPE_CODE_ARRAY + || RETURN_VALUE_ON_STACK (value_type)) + return USE_STRUCT_CONVENTION (gcc_p, value_type); + else + return 0; + } + + /* Probe the architecture for the return-value convention. */ + return (gdbarch_return_value (current_gdbarch, value_type, + NULL, NULL, NULL) + == RETURN_VALUE_STRUCT_CONVENTION); } -/* Store VAL so it will be returned if a function returns now. - Does not verify that VAL's type matches what the current - function wants to return. */ - -void -set_return_value (struct value *val) -{ - struct type *type = check_typedef (VALUE_TYPE (val)); - register enum type_code code = TYPE_CODE (type); - - if (code == TYPE_CODE_ERROR) - error ("Function return type unknown."); - - if (code == TYPE_CODE_STRUCT - || code == TYPE_CODE_UNION) /* FIXME, implement struct return. */ - error ("GDB does not support specifying a struct or union return value."); - - STORE_RETURN_VALUE (type, VALUE_CONTENTS (val)); -} - void _initialize_values (void) { diff --git a/contrib/gdb/gdb/varobj.c b/contrib/gdb/gdb/varobj.c index f56b7aa1fd1..c662518c82f 100644 --- a/contrib/gdb/gdb/varobj.c +++ b/contrib/gdb/gdb/varobj.c @@ -23,6 +23,7 @@ #include "language.h" #include "wrapper.h" #include "gdbcmd.h" +#include "gdb_string.h" #include #include "varobj.h" @@ -52,7 +53,7 @@ struct varobj_root struct block *valid_block; /* The frame for this expression */ - CORE_ADDR frame; + struct frame_id frame; /* If 1, "update" always recomputes the frame & valid block using the currently selected frame. */ @@ -110,6 +111,9 @@ struct varobj /* The format of the output for this object */ enum varobj_display_formats format; + + /* Was this variable updated via a varobj_set_value operation */ + int updated; }; /* Every variable keeps a linked list of its children, described @@ -392,6 +396,27 @@ static struct vlist **varobj_table; /* Creates a varobj (not its children) */ +/* Return the full FRAME which corresponds to the given CORE_ADDR + or NULL if no FRAME on the chain corresponds to CORE_ADDR. */ + +static struct frame_info * +find_frame_addr_in_frame_chain (CORE_ADDR frame_addr) +{ + struct frame_info *frame = NULL; + + if (frame_addr == (CORE_ADDR) 0) + return NULL; + + while (1) + { + frame = get_prev_frame (frame); + if (frame == NULL) + return NULL; + if (get_frame_base_address (frame) == frame_addr) + return frame; + } +} + struct varobj * varobj_create (char *objname, char *expression, CORE_ADDR frame, enum varobj_type type) @@ -416,8 +441,14 @@ varobj_create (char *objname, /* Allow creator to specify context of variable */ if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME)) - fi = selected_frame; + fi = deprecated_selected_frame; else + /* FIXME: cagney/2002-11-23: This code should be doing a + lookup using the frame ID and not just the frame's + ``address''. This, of course, means an interface change. + However, with out that interface change ISAs, such as the + ia64 with its two stacks, won't work. Similar goes for the + case where there is a frameless function. */ fi = find_frame_addr_in_frame_chain (frame); /* frame = -2 means always use selected frame */ @@ -426,7 +457,7 @@ varobj_create (char *objname, block = NULL; if (fi != NULL) - block = get_frame_block (fi); + block = get_frame_block (fi, 0); p = expression; innermost_block = NULL; @@ -456,9 +487,9 @@ varobj_create (char *objname, Since select_frame is so benign, just call it for all cases. */ if (fi != NULL) { - var->root->frame = FRAME_FP (fi); - old_fi = selected_frame; - select_frame (fi, -1); + var->root->frame = get_frame_id (fi); + old_fi = deprecated_selected_frame; + select_frame (fi); } /* We definitively need to catch errors here. @@ -485,7 +516,7 @@ varobj_create (char *objname, /* Reset the selected frame */ if (fi != NULL) - select_frame (old_fi, -1); + select_frame (old_fi); } /* If the variable object name is null, that means this @@ -514,13 +545,13 @@ char * varobj_gen_name (void) { static int id = 0; - char obj_name[31]; + char *obj_name; /* generate a name for this object */ id++; - sprintf (obj_name, "var%d", id); + xasprintf (&obj_name, "var%d", id); - return xstrdup (obj_name); + return obj_name; } /* Given an "objname", returns the pointer to the corresponding varobj @@ -752,6 +783,7 @@ int varobj_set_value (struct varobj *var, char *expression) { struct value *val; + int error; int offset = 0; /* The argument "expression" contains the variable's new value. @@ -777,6 +809,8 @@ varobj_set_value (struct varobj *var, char *expression) return 0; } + if (!my_value_equal (var->value, value, &error)) + var->updated = 1; if (!gdb_value_assign (var->value, value, &val)) return 0; value_free (var->value); @@ -850,7 +884,8 @@ varobj_update (struct varobj **varp, struct varobj ***changelist) struct value *new; struct vstack *stack = NULL; struct vstack *result = NULL; - struct frame_info *old_fi; + struct frame_id old_fid; + struct frame_info *fi; /* sanity check: have we been passed a pointer? */ if (changelist == NULL) @@ -863,7 +898,7 @@ varobj_update (struct varobj **varp, struct varobj ***changelist) /* Save the selected stack frame, since we will need to change it in order to evaluate expressions. */ - old_fi = selected_frame; + old_fid = get_frame_id (deprecated_selected_frame); /* Update the root variable. value_of_root can return NULL if the variable is no longer around, i.e. we stepped out of @@ -891,10 +926,11 @@ varobj_update (struct varobj **varp, struct varobj ***changelist) /* If values are not equal, note that it's changed. There a couple of exceptions here, though. We don't want some types to be reported as "changed". */ - else if (type_changeable (*varp) - && !my_value_equal ((*varp)->value, new, &error2)) + else if (type_changeable (*varp) && + ((*varp)->updated || !my_value_equal ((*varp)->value, new, &error2))) { vpush (&result, *varp); + (*varp)->updated = 0; changed++; /* error2 replaces var->error since this new value WILL replace the old one. */ @@ -931,10 +967,12 @@ varobj_update (struct varobj **varp, struct varobj ***changelist) /* Update this variable */ new = value_of_child (v->parent, v->index); - if (type_changeable (v) && !my_value_equal (v->value, new, &error2)) + if (type_changeable (v) && + (v->updated || !my_value_equal (v->value, new, &error2))) { /* Note that it's changed */ vpush (&result, v); + v->updated = 0; changed++; } /* error2 replaces v->error since this new value @@ -983,7 +1021,9 @@ varobj_update (struct varobj **varp, struct varobj ***changelist) } /* Restore selected frame */ - select_frame (old_fi, -1); + fi = frame_find_by_id (old_fid); + if (fi) + select_frame (fi); if (type_changed) return -2; @@ -1190,7 +1230,7 @@ child_exists (struct varobj *var, char *name) for (vc = var->children; vc != NULL; vc = vc->next) { - if (STREQ (vc->child->name, name)) + if (strcmp (vc->child->name, name) == 0) return vc->child; } @@ -1210,14 +1250,11 @@ create_child (struct varobj *parent, int index, char *name) child->name = name; child->index = index; child->value = value_of_child (parent, index); - if ((!CPLUS_FAKE_CHILD(child) && child->value == NULL) || parent->error) + if ((!CPLUS_FAKE_CHILD (child) && child->value == NULL) || parent->error) child->error = 1; child->parent = parent; child->root = parent->root; - childs_name = - (char *) xmalloc ((strlen (parent->obj_name) + strlen (name) + 2) * - sizeof (char)); - sprintf (childs_name, "%s.%s", parent->obj_name, name); + xasprintf (&childs_name, "%s.%s", parent->obj_name, name); child->obj_name = childs_name; install_variable (child); @@ -1293,6 +1330,7 @@ new_variable (void) var->children = NULL; var->format = 0; var->root = NULL; + var->updated = 0; return var; } @@ -1306,7 +1344,7 @@ new_root_variable (void) var->root->lang = NULL; var->root->exp = NULL; var->root->valid_block = NULL; - var->root->frame = (CORE_ADDR) -1; + var->root->frame = null_frame_id; var->root->use_selected_frame = 0; var->root->rootvar = NULL; @@ -1341,17 +1379,19 @@ make_cleanup_free_variable (struct varobj *var) return make_cleanup (do_free_variable_cleanup, var); } -/* This returns the type of the variable. This skips past typedefs - and returns the real type of the variable. It also dereferences - pointers and references. */ +/* This returns the type of the variable. It also skips past typedefs + to return the real type of the variable. + + NOTE: TYPE_TARGET_TYPE should NOT be used anywhere in this file + except within get_target_type and get_type. */ static struct type * get_type (struct varobj *var) { struct type *type; type = var->type; - while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF) - type = TYPE_TARGET_TYPE (type); + if (type != NULL) + type = check_typedef (type); return type; } @@ -1372,15 +1412,18 @@ get_type_deref (struct varobj *var) } /* This returns the target type (or NULL) of TYPE, also skipping - past typedefs, just like get_type (). */ + past typedefs, just like get_type (). + + NOTE: TYPE_TARGET_TYPE should NOT be used anywhere in this file + except within get_target_type and get_type. */ static struct type * get_target_type (struct type *type) { if (type != NULL) { type = TYPE_TARGET_TYPE (type); - while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF) - type = TYPE_TARGET_TYPE (type); + if (type != NULL) + type = check_typedef (type); } return type; @@ -1645,8 +1688,8 @@ value_of_child (struct varobj *parent, int index) if (value != NULL && VALUE_LAZY (value)) { /* If we fail to fetch the value of the child, return - NULL so that callers notice that we're leaving an - error message. */ + NULL so that callers notice that we're leaving an + error message. */ if (!gdb_value_fetch_lazy (value)) value = NULL; } @@ -1794,14 +1837,7 @@ c_name_of_child (struct varobj *parent, int index) switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: - { - /* We never get here unless parent->num_children is greater than 0... */ - int len = 1; - while ((int) pow ((double) 10, (double) len) < index) - len++; - name = (char *) xmalloc (1 + len * sizeof (char)); - sprintf (name, "%d", index); - } + xasprintf (&name, "%d", index); break; case TYPE_CODE_STRUCT: @@ -1820,9 +1856,7 @@ c_name_of_child (struct varobj *parent, int index) break; default: - name = - (char *) xmalloc ((strlen (parent->name) + 2) * sizeof (char)); - sprintf (name, "*%s", parent->name); + xasprintf (&name, "*%s", parent->name); break; } break; @@ -1855,14 +1889,11 @@ c_value_of_root (struct varobj **var_handle) else { reinit_frame_cache (); - - - fi = find_frame_addr_in_frame_chain (var->root->frame); - + fi = frame_find_by_id (var->root->frame); within_scope = fi != NULL; /* FIXME: select_frame could fail */ if (within_scope) - select_frame (fi, -1); + select_frame (fi); } if (within_scope) @@ -1929,7 +1960,8 @@ c_value_of_child (struct varobj *parent, int index) case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure"); + gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, + "vstructure"); break; case TYPE_CODE_PTR: @@ -1937,7 +1969,8 @@ c_value_of_child (struct varobj *parent, int index) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure"); + gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, + "vstructure"); break; default: @@ -1967,7 +2000,7 @@ c_type_of_child (struct varobj *parent, int index) switch (TYPE_CODE (parent->type)) { case TYPE_CODE_ARRAY: - type = TYPE_TARGET_TYPE (parent->type); + type = get_target_type (parent->type); break; case TYPE_CODE_STRUCT: @@ -1976,7 +2009,7 @@ c_type_of_child (struct varobj *parent, int index) break; case TYPE_CODE_PTR: - switch (TYPE_CODE (TYPE_TARGET_TYPE (parent->type))) + switch (TYPE_CODE (get_target_type (parent->type))) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: @@ -1984,7 +2017,7 @@ c_type_of_child (struct varobj *parent, int index) break; default: - type = TYPE_TARGET_TYPE (parent->type); + type = get_target_type (parent->type); break; } break; @@ -2024,12 +2057,10 @@ c_variable_editable (struct varobj *var) static char * c_value_of_variable (struct varobj *var) { - struct type *type; - /* BOGUS: if val_print sees a struct/class, it will print out its children instead of "{...}" */ - type = get_type (var); - switch (TYPE_CODE (type)) + + switch (TYPE_CODE (get_type (var))) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: @@ -2038,19 +2069,14 @@ c_value_of_variable (struct varobj *var) case TYPE_CODE_ARRAY: { - char number[18]; - sprintf (number, "[%d]", var->num_children); - return xstrdup (number); + char *number; + xasprintf (&number, "[%d]", var->num_children); + return (number); } /* break; */ default: { - long dummy; - struct ui_file *stb = mem_fileopen (); - struct cleanup *old_chain = make_cleanup_ui_file_delete (stb); - char *thevalue; - if (var->value == NULL) { /* This can happen if we attempt to get the value of a struct @@ -2060,18 +2086,22 @@ c_value_of_variable (struct varobj *var) } else { + long dummy; + struct ui_file *stb = mem_fileopen (); + struct cleanup *old_chain = make_cleanup_ui_file_delete (stb); + char *thevalue; + if (VALUE_LAZY (var->value)) gdb_value_fetch_lazy (var->value); - val_print (VALUE_TYPE (var->value), VALUE_CONTENTS_RAW (var->value), 0, - VALUE_ADDRESS (var->value), - stb, format_code[(int) var->format], 1, 0, 0); + val_print (VALUE_TYPE (var->value), + VALUE_CONTENTS_RAW (var->value), 0, + VALUE_ADDRESS (var->value), stb, + format_code[(int) var->format], 1, 0, 0); thevalue = ui_file_xstrdup (stb, &dummy); do_cleanups (old_chain); - } - return thevalue; } - /* break; */ + } } } @@ -2118,9 +2148,9 @@ cplus_number_of_children (struct varobj *var) type = get_type_deref (var->parent); cplus_class_num_children (type, kids); - if (STREQ (var->name, "public")) + if (strcmp (var->name, "public") == 0) children = kids[v_public]; - else if (STREQ (var->name, "private")) + else if (strcmp (var->name, "private") == 0) children = kids[v_private]; else children = kids[v_protected]; @@ -2171,7 +2201,6 @@ cplus_name_of_child (struct varobj *parent, int index) { char *name; struct type *type; - int children[3]; if (CPLUS_FAKE_CHILD (parent)) { @@ -2186,54 +2215,97 @@ cplus_name_of_child (struct varobj *parent, int index) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - cplus_class_num_children (type, children); - if (CPLUS_FAKE_CHILD (parent)) { - int i; + /* The fields of the class type are ordered as they + appear in the class. We are given an index for a + particular access control type ("public","protected", + or "private"). We must skip over fields that don't + have the access control we are looking for to properly + find the indexed field. */ + int type_index = TYPE_N_BASECLASSES (type); + if (strcmp (parent->name, "private") == 0) + { + while (index >= 0) + { + if (TYPE_VPTR_BASETYPE (type) == type + && type_index == TYPE_VPTR_FIELDNO (type)) + ; /* ignore vptr */ + else if (TYPE_FIELD_PRIVATE (type, type_index)) + --index; + ++type_index; + } + --type_index; + } + else if (strcmp (parent->name, "protected") == 0) + { + while (index >= 0) + { + if (TYPE_VPTR_BASETYPE (type) == type + && type_index == TYPE_VPTR_FIELDNO (type)) + ; /* ignore vptr */ + else if (TYPE_FIELD_PROTECTED (type, type_index)) + --index; + ++type_index; + } + --type_index; + } + else + { + while (index >= 0) + { + if (TYPE_VPTR_BASETYPE (type) == type + && type_index == TYPE_VPTR_FIELDNO (type)) + ; /* ignore vptr */ + else if (!TYPE_FIELD_PRIVATE (type, type_index) && + !TYPE_FIELD_PROTECTED (type, type_index)) + --index; + ++type_index; + } + --type_index; + } - /* Skip over vptr, if it exists. */ - if (TYPE_VPTR_BASETYPE (type) == type - && index >= TYPE_VPTR_FIELDNO (type)) - index++; - - /* FIXME: This assumes that type orders - inherited, public, private, protected */ - i = index + TYPE_N_BASECLASSES (type); - if (STREQ (parent->name, "private") || STREQ (parent->name, "protected")) - i += children[v_public]; - if (STREQ (parent->name, "protected")) - i += children[v_private]; - - name = TYPE_FIELD_NAME (type, i); + name = TYPE_FIELD_NAME (type, type_index); } else if (index < TYPE_N_BASECLASSES (type)) + /* We are looking up the name of a base class */ name = TYPE_FIELD_NAME (type, index); else { + int children[3]; + cplus_class_num_children(type, children); + /* Everything beyond the baseclasses can - only be "public", "private", or "protected" */ + only be "public", "private", or "protected" + + The special "fake" children are always output by varobj in + this order. So if INDEX == 2, it MUST be "protected". */ index -= TYPE_N_BASECLASSES (type); switch (index) { case 0: - if (children[v_public] != 0) - { - name = "public"; - break; - } + if (children[v_public] > 0) + name = "public"; + else if (children[v_private] > 0) + name = "private"; + else + name = "protected"; + break; case 1: - if (children[v_private] != 0) + if (children[v_public] > 0) { - name = "private"; - break; + if (children[v_private] > 0) + name = "private"; + else + name = "protected"; } + else if (children[v_private] > 0) + name = "protected"; + break; case 2: - if (children[v_protected] != 0) - { - name = "protected"; - break; - } + /* Must be protected */ + name = "protected"; + break; default: /* error! */ break; diff --git a/contrib/gdb/gdb/version.in b/contrib/gdb/gdb/version.in index 26d99a283f2..f3b5af39e43 100644 --- a/contrib/gdb/gdb/version.in +++ b/contrib/gdb/gdb/version.in @@ -1 +1 @@ -5.2.1 +6.1.1 diff --git a/contrib/gdb/gdb/win32-nat.c b/contrib/gdb/gdb/win32-nat.c new file mode 100644 index 00000000000..8b26916e2b7 --- /dev/null +++ b/contrib/gdb/gdb/win32-nat.c @@ -0,0 +1,2460 @@ +/* Target-vector operations for controlling win32 child processes, for GDB. + + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free + Software Foundation, Inc. + + Contributed by Cygnus Solutions, A Red Hat Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without eve nthe implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Originally by Steve Chamberlain, sac@cygnus.com */ + +/* We assume we're being built with and will be used for cygwin. */ + +#include "defs.h" +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" +#include "target.h" +#include "gdbcore.h" +#include "command.h" +#include "completer.h" +#include "regcache.h" +#include "top.h" +#include +#include +#include +#include +#include +#include +#include + +#include "buildsym.h" +#include "symfile.h" +#include "objfiles.h" +#include "gdb_string.h" +#include "gdbthread.h" +#include "gdbcmd.h" +#include +#include +#include "exec.h" + +#include "i386-tdep.h" +#include "i387-tdep.h" + +/* The ui's event loop. */ +extern int (*ui_loop_hook) (int signo); + +/* If we're not using the old Cygwin header file set, define the + following which never should have been in the generic Win32 API + headers in the first place since they were our own invention... */ +#ifndef _GNU_H_WINDOWS_H +enum + { + FLAG_TRACE_BIT = 0x100, + CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT) + }; +#endif +#include +#include + +#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \ + | CONTEXT_EXTENDED_REGISTERS + +static unsigned dr[8]; +static int debug_registers_changed; +static int debug_registers_used; + +/* The string sent by cygwin when it processes a signal. + FIXME: This should be in a cygwin include file. */ +#define CYGWIN_SIGNAL_STRING "cygwin: signal" + +#define CHECK(x) check (x, __FILE__,__LINE__) +#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x +#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x +#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x +#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x + +/* Forward declaration */ +extern struct target_ops child_ops; + +static void child_stop (void); +static int win32_child_thread_alive (ptid_t); +void child_kill_inferior (void); + +static enum target_signal last_sig = TARGET_SIGNAL_0; +/* Set if a signal was received from the debugged process */ + +/* Thread information structure used to track information that is + not available in gdb's thread structure. */ +typedef struct thread_info_struct + { + struct thread_info_struct *next; + DWORD id; + HANDLE h; + char *name; + int suspend_count; + int reload_context; + CONTEXT context; + STACKFRAME sf; + } +thread_info; + +static thread_info thread_head; + +/* The process and thread handles for the above context. */ + +static DEBUG_EVENT current_event; /* The current debug event from + WaitForDebugEvent */ +static HANDLE current_process_handle; /* Currently executing process */ +static thread_info *current_thread; /* Info on currently selected thread */ +static DWORD main_thread_id; /* Thread ID of the main thread */ + +/* Counts of things. */ +static int exception_count = 0; +static int event_count = 0; +static int saw_create; + +/* User options. */ +static int new_console = 0; +static int new_group = 1; +static int debug_exec = 0; /* show execution */ +static int debug_events = 0; /* show events from kernel */ +static int debug_memory = 0; /* show target memory accesses */ +static int debug_exceptions = 0; /* show target exceptions */ +static int useshell = 0; /* use shell for subprocesses */ + +/* This vector maps GDB's idea of a register's number into an address + in the win32 exception context vector. + + It also contains the bit mask needed to load the register in question. + + One day we could read a reg, we could inspect the context we + already have loaded, if it doesn't have the bit set that we need, + we read that set of registers in using GetThreadContext. If the + context already contains what we need, we just unpack it. Then to + write a register, first we have to ensure that the context contains + the other regs of the group, and then we copy the info in and set + out bit. */ + +#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x)) +static const int mappings[] = +{ + context_offset (Eax), + context_offset (Ecx), + context_offset (Edx), + context_offset (Ebx), + context_offset (Esp), + context_offset (Ebp), + context_offset (Esi), + context_offset (Edi), + context_offset (Eip), + context_offset (EFlags), + context_offset (SegCs), + context_offset (SegSs), + context_offset (SegDs), + context_offset (SegEs), + context_offset (SegFs), + context_offset (SegGs), + context_offset (FloatSave.RegisterArea[0 * 10]), + context_offset (FloatSave.RegisterArea[1 * 10]), + context_offset (FloatSave.RegisterArea[2 * 10]), + context_offset (FloatSave.RegisterArea[3 * 10]), + context_offset (FloatSave.RegisterArea[4 * 10]), + context_offset (FloatSave.RegisterArea[5 * 10]), + context_offset (FloatSave.RegisterArea[6 * 10]), + context_offset (FloatSave.RegisterArea[7 * 10]), + context_offset (FloatSave.ControlWord), + context_offset (FloatSave.StatusWord), + context_offset (FloatSave.TagWord), + context_offset (FloatSave.ErrorSelector), + context_offset (FloatSave.ErrorOffset), + context_offset (FloatSave.DataSelector), + context_offset (FloatSave.DataOffset), + context_offset (FloatSave.ErrorSelector) + /* XMM0-7 */ , + context_offset (ExtendedRegisters[10*16]), + context_offset (ExtendedRegisters[11*16]), + context_offset (ExtendedRegisters[12*16]), + context_offset (ExtendedRegisters[13*16]), + context_offset (ExtendedRegisters[14*16]), + context_offset (ExtendedRegisters[15*16]), + context_offset (ExtendedRegisters[16*16]), + context_offset (ExtendedRegisters[17*16]), + /* MXCSR */ + context_offset (ExtendedRegisters[24]) +}; + +#undef context_offset + +/* This vector maps the target's idea of an exception (extracted + from the DEBUG_EVENT structure) to GDB's idea. */ + +struct xlate_exception + { + int them; + enum target_signal us; + }; + +static const struct xlate_exception + xlate[] = +{ + {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV}, + {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV}, + {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP}, + {DBG_CONTROL_C, TARGET_SIGNAL_INT}, + {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP}, + {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE}, + {-1, -1}}; + +static void +check (BOOL ok, const char *file, int line) +{ + if (!ok) + printf_filtered ("error return %s:%d was %lu\n", file, line, + GetLastError ()); +} + +/* Find a thread record given a thread id. + If get_context then also retrieve the context for this + thread. */ +static thread_info * +thread_rec (DWORD id, int get_context) +{ + thread_info *th; + + for (th = &thread_head; (th = th->next) != NULL;) + if (th->id == id) + { + if (!th->suspend_count && get_context) + { + if (get_context > 0 && id != current_event.dwThreadId) + th->suspend_count = SuspendThread (th->h) + 1; + else if (get_context < 0) + th->suspend_count = -1; + th->reload_context = 1; + } + return th; + } + + return NULL; +} + +/* Add a thread to the thread list */ +static thread_info * +child_add_thread (DWORD id, HANDLE h) +{ + thread_info *th; + + if ((th = thread_rec (id, FALSE))) + return th; + + th = (thread_info *) xmalloc (sizeof (*th)); + memset (th, 0, sizeof (*th)); + th->id = id; + th->h = h; + th->next = thread_head.next; + thread_head.next = th; + add_thread (pid_to_ptid (id)); + /* Set the debug registers for the new thread in they are used. */ + if (debug_registers_used) + { + /* Only change the value of the debug registers. */ + th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + CHECK (GetThreadContext (th->h, &th->context)); + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + /* th->context.Dr6 = dr[6]; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr[7]; + CHECK (SetThreadContext (th->h, &th->context)); + th->context.ContextFlags = 0; + } + return th; +} + +/* Clear out any old thread list and reintialize it to a + pristine state. */ +static void +child_init_thread_list (void) +{ + thread_info *th = &thread_head; + + DEBUG_EVENTS (("gdb: child_init_thread_list\n")); + init_thread_list (); + while (th->next != NULL) + { + thread_info *here = th->next; + th->next = here->next; + (void) CloseHandle (here->h); + xfree (here); + } +} + +/* Delete a thread from the list of threads */ +static void +child_delete_thread (DWORD id) +{ + thread_info *th; + + if (info_verbose) + printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id))); + delete_thread (pid_to_ptid (id)); + + for (th = &thread_head; + th->next != NULL && th->next->id != id; + th = th->next) + continue; + + if (th->next != NULL) + { + thread_info *here = th->next; + th->next = here->next; + CloseHandle (here->h); + xfree (here); + } +} + +static void +do_child_fetch_inferior_registers (int r) +{ + char *context_offset = ((char *) ¤t_thread->context) + mappings[r]; + long l; + + if (!current_thread) + return; /* Windows sometimes uses a non-existent thread id in its + events */ + + if (current_thread->reload_context) + { + thread_info *th = current_thread; + th->context.ContextFlags = CONTEXT_DEBUGGER_DR; + GetThreadContext (th->h, &th->context); + /* Copy dr values from that thread. */ + dr[0] = th->context.Dr0; + dr[1] = th->context.Dr1; + dr[2] = th->context.Dr2; + dr[3] = th->context.Dr3; + dr[6] = th->context.Dr6; + dr[7] = th->context.Dr7; + current_thread->reload_context = 0; + } + +#define I387_ST0_REGNUM I386_ST0_REGNUM + + if (r == I387_FISEG_REGNUM) + { + l = *((long *) context_offset) & 0xffff; + supply_register (r, (char *) &l); + } + else if (r == I387_FOP_REGNUM) + { + l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); + supply_register (r, (char *) &l); + } + else if (r >= 0) + supply_register (r, context_offset); + else + { + for (r = 0; r < NUM_REGS; r++) + do_child_fetch_inferior_registers (r); + } + +#undef I387_ST0_REGNUM +} + +static void +child_fetch_inferior_registers (int r) +{ + current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); + /* Check if current_thread exists. Windows sometimes uses a non-existent + thread id in its events */ + if (current_thread) + do_child_fetch_inferior_registers (r); +} + +static void +do_child_store_inferior_registers (int r) +{ + if (!current_thread) + /* Windows sometimes uses a non-existent thread id in its events */; + else if (r >= 0) + regcache_collect (r, ((char *) ¤t_thread->context) + mappings[r]); + else + { + for (r = 0; r < NUM_REGS; r++) + do_child_store_inferior_registers (r); + } +} + +/* Store a new register value into the current thread context */ +static void +child_store_inferior_registers (int r) +{ + current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); + /* Check if current_thread exists. Windows sometimes uses a non-existent + thread id in its events */ + if (current_thread) + do_child_store_inferior_registers (r); +} + +static int psapi_loaded = 0; +static HMODULE psapi_module_handle = NULL; +static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL; +static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL; +static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL; + +int +psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret) +{ + DWORD len; + MODULEINFO mi; + int i; + HMODULE dh_buf[1]; + HMODULE *DllHandle = dh_buf; + DWORD cbNeeded; + BOOL ok; + + if (!psapi_loaded || + psapi_EnumProcessModules == NULL || + psapi_GetModuleInformation == NULL || + psapi_GetModuleFileNameExA == NULL) + { + if (psapi_loaded) + goto failed; + psapi_loaded = 1; + psapi_module_handle = LoadLibrary ("psapi.dll"); + if (!psapi_module_handle) + { + /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */ + goto failed; + } + psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules"); + psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation"); + psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle, + "GetModuleFileNameExA"); + if (psapi_EnumProcessModules == NULL || + psapi_GetModuleInformation == NULL || + psapi_GetModuleFileNameExA == NULL) + goto failed; + } + + cbNeeded = 0; + ok = (*psapi_EnumProcessModules) (current_process_handle, + DllHandle, + sizeof (HMODULE), + &cbNeeded); + + if (!ok || !cbNeeded) + goto failed; + + DllHandle = (HMODULE *) alloca (cbNeeded); + if (!DllHandle) + goto failed; + + ok = (*psapi_EnumProcessModules) (current_process_handle, + DllHandle, + cbNeeded, + &cbNeeded); + if (!ok) + goto failed; + + for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++) + { + if (!(*psapi_GetModuleInformation) (current_process_handle, + DllHandle[i], + &mi, + sizeof (mi))) + error ("Can't get module info"); + + len = (*psapi_GetModuleFileNameExA) (current_process_handle, + DllHandle[i], + dll_name_ret, + MAX_PATH); + if (len == 0) + error ("Error getting dll name: %u\n", (unsigned) GetLastError ()); + + if ((DWORD) (mi.lpBaseOfDll) == BaseAddress) + return 1; + } + +failed: + dll_name_ret[0] = '\0'; + return 0; +} + +/* Encapsulate the information required in a call to + symbol_file_add_args */ +struct safe_symbol_file_add_args +{ + char *name; + int from_tty; + struct section_addr_info *addrs; + int mainline; + int flags; + struct ui_file *err, *out; + struct objfile *ret; +}; + +/* Maintain a linked list of "so" information. */ +struct so_stuff +{ + struct so_stuff *next; + DWORD load_addr; + DWORD end_addr; + int loaded; + struct objfile *objfile; + char name[1]; +} solib_start, *solib_end; + +/* Call symbol_file_add with stderr redirected. We don't care if there + are errors. */ +static int +safe_symbol_file_add_stub (void *argv) +{ +#define p ((struct safe_symbol_file_add_args *)argv) + struct so_stuff *so = &solib_start; + + while ((so = so->next)) + if (so->loaded && strcasecmp (so->name, p->name) == 0) + return 0; + p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags); + return !!p->ret; +#undef p +} + +/* Restore gdb's stderr after calling symbol_file_add */ +static void +safe_symbol_file_add_cleanup (void *p) +{ +#define sp ((struct safe_symbol_file_add_args *)p) + gdb_flush (gdb_stderr); + gdb_flush (gdb_stdout); + ui_file_delete (gdb_stderr); + ui_file_delete (gdb_stdout); + gdb_stderr = sp->err; + gdb_stdout = sp->out; +#undef sp +} + +/* symbol_file_add wrapper that prevents errors from being displayed. */ +static struct objfile * +safe_symbol_file_add (char *name, int from_tty, + struct section_addr_info *addrs, + int mainline, int flags) +{ + struct safe_symbol_file_add_args p; + struct cleanup *cleanup; + + cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p); + + p.err = gdb_stderr; + p.out = gdb_stdout; + gdb_flush (gdb_stderr); + gdb_flush (gdb_stdout); + gdb_stderr = ui_file_new (); + gdb_stdout = ui_file_new (); + p.name = name; + p.from_tty = from_tty; + p.addrs = addrs; + p.mainline = mainline; + p.flags = flags; + catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR); + + do_cleanups (cleanup); + return p.ret; +} + +/* Remember the maximum DLL length for printing in info dll command. */ +int max_dll_name_len; + +static void +register_loaded_dll (const char *name, DWORD load_addr) +{ + struct so_stuff *so; + char ppath[MAX_PATH + 1]; + char buf[MAX_PATH + 1]; + char cwd[MAX_PATH + 1]; + char *p; + WIN32_FIND_DATA w32_fd; + HANDLE h = FindFirstFile(name, &w32_fd); + MEMORY_BASIC_INFORMATION m; + size_t len; + + if (h == INVALID_HANDLE_VALUE) + strcpy (buf, name); + else + { + FindClose (h); + strcpy (buf, name); + if (GetCurrentDirectory (MAX_PATH + 1, cwd)) + { + p = strrchr (buf, '\\'); + if (p) + p[1] = '\0'; + SetCurrentDirectory (buf); + GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p); + SetCurrentDirectory (cwd); + } + } + + cygwin_conv_to_posix_path (buf, ppath); + so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1); + so->loaded = 0; + so->load_addr = load_addr; + if (VirtualQueryEx (current_process_handle, (void *) load_addr, &m, + sizeof (m))) + so->end_addr = (DWORD) m.AllocationBase + m.RegionSize; + else + so->end_addr = load_addr + 0x2000; /* completely arbitrary */ + + so->next = NULL; + so->objfile = NULL; + strcpy (so->name, ppath); + + solib_end->next = so; + solib_end = so; + len = strlen (ppath); + if (len > max_dll_name_len) + max_dll_name_len = len; +} + +char * +get_image_name (HANDLE h, void *address, int unicode) +{ + static char buf[(2 * MAX_PATH) + 1]; + DWORD size = unicode ? sizeof (WCHAR) : sizeof (char); + char *address_ptr; + int len = 0; + char b[2]; + DWORD done; + + /* Attempt to read the name of the dll that was detected. + This is documented to work only when actively debugging + a program. It will not work for attached processes. */ + if (address == NULL) + return NULL; + + /* See if we could read the address of a string, and that the + address isn't null. */ + if (!ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done) + || done != sizeof (address_ptr) || !address_ptr) + return NULL; + + /* Find the length of the string */ + while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done) + && (b[0] != 0 || b[size - 1] != 0) && done == size) + continue; + + if (!unicode) + ReadProcessMemory (h, address_ptr, buf, len, &done); + else + { + WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR)); + ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR), + &done); + + WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0); + } + + return buf; +} + +/* Wait for child to do something. Return pid of child, or -1 in case + of error; store status through argument pointer OURSTATUS. */ +static int +handle_load_dll (void *dummy) +{ + LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; + char dll_buf[MAX_PATH + 1]; + char *dll_name = NULL; + char *p; + + dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; + + if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf)) + dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; + + dll_name = dll_buf; + + if (*dll_name == '\0') + dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode); + if (!dll_name) + return 1; + + register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000); + + return 1; +} + +static int +handle_unload_dll (void *dummy) +{ + DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000; + struct so_stuff *so; + + for (so = &solib_start; so->next != NULL; so = so->next) + if (so->next->load_addr == lpBaseOfDll) + { + struct so_stuff *sodel = so->next; + so->next = sodel->next; + if (!so->next) + solib_end = so; + if (sodel->objfile) + free_objfile (sodel->objfile); + xfree(sodel); + return 1; + } + error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll); + + return 0; +} + +char * +solib_address (CORE_ADDR address) +{ + struct so_stuff *so; + for (so = &solib_start; so->next != NULL; so = so->next) + if (address >= so->load_addr && address <= so->end_addr) + return so->name; + return NULL; +} + +/* Return name of last loaded DLL. */ +char * +child_solib_loaded_library_pathname (int pid) +{ + return !solib_end || !solib_end->name[0] ? NULL : solib_end->name; +} + +/* Clear list of loaded DLLs. */ +void +child_clear_solibs (void) +{ + struct so_stuff *so, *so1 = solib_start.next; + + while ((so = so1) != NULL) + { + so1 = so->next; + xfree (so); + } + + solib_start.next = NULL; + solib_start.objfile = NULL; + solib_end = &solib_start; + max_dll_name_len = sizeof ("DLL Name") - 1; +} + +/* Get the loaded address of all sections, given that .text was loaded + at text_load. Assumes that all sections are subject to the same + relocation offset. Returns NULL if problems occur or if the + sections were not relocated. */ + +static struct section_addr_info * +get_relocated_section_addrs (bfd *abfd, CORE_ADDR text_load) +{ + struct section_addr_info *result = NULL; + int section_count = bfd_count_sections (abfd); + asection *text_section = bfd_get_section_by_name (abfd, ".text"); + CORE_ADDR text_vma; + + if (!text_section) + { + /* Couldn't get the .text section. Weird. */ + } + + else if (text_load == (text_vma = bfd_get_section_vma (abfd, text_section))) + { + /* DLL wasn't relocated. */ + } + + else + { + /* Figure out all sections' loaded addresses. The offset here is + such that taking a bfd_get_section_vma() result and adding + offset will give the real load address of the section. */ + + CORE_ADDR offset = text_load - text_vma; + + struct section_table *table_start = NULL; + struct section_table *table_end = NULL; + struct section_table *iter = NULL; + + build_section_table (abfd, &table_start, &table_end); + + for (iter = table_start; iter < table_end; ++iter) + { + /* Relocated addresses. */ + iter->addr += offset; + iter->endaddr += offset; + } + + result = build_section_addr_info_from_section_table (table_start, + table_end); + + xfree (table_start); + } + + return result; +} + +/* Add DLL symbol information. */ +static struct objfile * +solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr) +{ + struct section_addr_info *addrs = NULL; + static struct objfile *result = NULL; + bfd *abfd = NULL; + + /* The symbols in a dll are offset by 0x1000, which is the + the offset from 0 of the first byte in an image - because + of the file header and the section alignment. */ + + if (!name || !name[0]) + return NULL; + + abfd = bfd_openr (name, "pei-i386"); + + if (!abfd) + { + /* pei failed - try pe */ + abfd = bfd_openr (name, "pe-i386"); + } + + if (abfd) + { + if (bfd_check_format (abfd, bfd_object)) + { + addrs = get_relocated_section_addrs (abfd, load_addr); + } + + bfd_close (abfd); + } + + if (addrs) + { + result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED); + free_section_addr_info (addrs); + } + else + { + /* Fallback on handling just the .text section. */ + struct cleanup *my_cleanups; + + addrs = alloc_section_addr_info (1); + my_cleanups = make_cleanup (xfree, addrs); + addrs->other[0].name = ".text"; + addrs->other[0].addr = load_addr; + + result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED); + do_cleanups (my_cleanups); + } + + return result; +} + +/* Load DLL symbol info. */ +void +dll_symbol_command (char *args, int from_tty) +{ + int n; + dont_repeat (); + + if (args == NULL) + error ("dll-symbols requires a file name"); + + n = strlen (args); + if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0) + { + char *newargs = (char *) alloca (n + 4 + 1); + strcpy (newargs, args); + strcat (newargs, ".dll"); + args = newargs; + } + + safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED); +} + +/* List currently loaded DLLs. */ +void +info_dll_command (char *ignore, int from_tty) +{ + struct so_stuff *so = &solib_start; + + if (!so->next) + return; + + printf_filtered ("%*s Load Address\n", -max_dll_name_len, "DLL Name"); + while ((so = so->next) != NULL) + printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr); + + return; +} + +/* Handle DEBUG_STRING output from child process. + Cygwin prepends its messages with a "cygwin:". Interpret this as + a Cygwin signal. Otherwise just print the string as a warning. */ +static int +handle_output_debug_string (struct target_waitstatus *ourstatus) +{ + char *s; + int gotasig = FALSE; + + if (!target_read_string + ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0) + || !s || !*s) + return gotasig; + + if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0) + { + if (strncmp (s, "cYg", 3) != 0) + warning ("%s", s); + } + else + { + char *p; + int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0); + gotasig = target_signal_from_host (sig); + ourstatus->value.sig = gotasig; + if (gotasig) + ourstatus->kind = TARGET_WAITKIND_STOPPED; + } + + xfree (s); + return gotasig; +} + +static int +display_selector (HANDLE thread, DWORD sel) +{ + LDT_ENTRY info; + if (GetThreadSelectorEntry (thread, sel, &info)) + { + int base, limit; + printf_filtered ("0x%03lx: ", sel); + if (!info.HighWord.Bits.Pres) + { + puts_filtered ("Segment not present\n"); + return 0; + } + base = (info.HighWord.Bits.BaseHi << 24) + + (info.HighWord.Bits.BaseMid << 16) + + info.BaseLow; + limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow; + if (info.HighWord.Bits.Granularity) + limit = (limit << 12) | 0xfff; + printf_filtered ("base=0x%08x limit=0x%08x", base, limit); + if (info.HighWord.Bits.Default_Big) + puts_filtered(" 32-bit "); + else + puts_filtered(" 16-bit "); + switch ((info.HighWord.Bits.Type & 0xf) >> 1) + { + case 0: + puts_filtered ("Data (Read-Only, Exp-up"); + break; + case 1: + puts_filtered ("Data (Read/Write, Exp-up"); + break; + case 2: + puts_filtered ("Unused segment ("); + break; + case 3: + puts_filtered ("Data (Read/Write, Exp-down"); + break; + case 4: + puts_filtered ("Code (Exec-Only, N.Conf"); + break; + case 5: + puts_filtered ("Code (Exec/Read, N.Conf"); + break; + case 6: + puts_filtered ("Code (Exec-Only, Conf"); + break; + case 7: + puts_filtered ("Code (Exec/Read, Conf"); + break; + default: + printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type); + } + if ((info.HighWord.Bits.Type & 0x1) == 0) + puts_filtered(", N.Acc"); + puts_filtered (")\n"); + if ((info.HighWord.Bits.Type & 0x10) == 0) + puts_filtered("System selector "); + printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl); + if (info.HighWord.Bits.Granularity) + puts_filtered ("Page granular.\n"); + else + puts_filtered ("Byte granular.\n"); + return 1; + } + else + { + printf_filtered ("Invalid selector 0x%lx.\n",sel); + return 0; + } +} + +static void +display_selectors (char * args, int from_tty) +{ + if (!current_thread) + { + puts_filtered ("Impossible to display selectors now.\n"); + return; + } + if (!args) + { + + puts_filtered ("Selector $cs\n"); + display_selector (current_thread->h, + current_thread->context.SegCs); + puts_filtered ("Selector $ds\n"); + display_selector (current_thread->h, + current_thread->context.SegDs); + puts_filtered ("Selector $es\n"); + display_selector (current_thread->h, + current_thread->context.SegEs); + puts_filtered ("Selector $ss\n"); + display_selector (current_thread->h, + current_thread->context.SegSs); + puts_filtered ("Selector $fs\n"); + display_selector (current_thread->h, + current_thread->context.SegFs); + puts_filtered ("Selector $gs\n"); + display_selector (current_thread->h, + current_thread->context.SegGs); + } + else + { + int sel; + sel = parse_and_eval_long (args); + printf_filtered ("Selector \"%s\"\n",args); + display_selector (current_thread->h, sel); + } +} + +static struct cmd_list_element *info_w32_cmdlist = NULL; + +static void +info_w32_command (char *args, int from_tty) +{ + help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout); +} + + +#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \ + printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \ + (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress) + +static int +handle_exception (struct target_waitstatus *ourstatus) +{ + thread_info *th; + DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; + + ourstatus->kind = TARGET_WAITKIND_STOPPED; + + /* Record the context of the current thread */ + th = thread_rec (current_event.dwThreadId, -1); + + switch (code) + { + case EXCEPTION_ACCESS_VIOLATION: + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION"); + ourstatus->value.sig = TARGET_SIGNAL_SEGV; + break; + case STATUS_STACK_OVERFLOW: + DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW"); + ourstatus->value.sig = TARGET_SIGNAL_SEGV; + break; + case STATUS_FLOAT_DENORMAL_OPERAND: + DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_INEXACT_RESULT: + DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_INVALID_OPERATION: + DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_OVERFLOW: + DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_STACK_CHECK: + DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_UNDERFLOW: + DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_DIVIDE_BY_ZERO: + DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_INTEGER_DIVIDE_BY_ZERO: + DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_INTEGER_OVERFLOW: + DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW"); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case EXCEPTION_BREAKPOINT: + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT"); + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + break; + case DBG_CONTROL_C: + DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C"); + ourstatus->value.sig = TARGET_SIGNAL_INT; + break; + case DBG_CONTROL_BREAK: + DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK"); + ourstatus->value.sig = TARGET_SIGNAL_INT; + break; + case EXCEPTION_SINGLE_STEP: + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP"); + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION"); + ourstatus->value.sig = TARGET_SIGNAL_ILL; + break; + case EXCEPTION_PRIV_INSTRUCTION: + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION"); + ourstatus->value.sig = TARGET_SIGNAL_ILL; + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION"); + ourstatus->value.sig = TARGET_SIGNAL_ILL; + break; + default: + if (current_event.u.Exception.dwFirstChance) + return 0; + printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n", + current_event.u.Exception.ExceptionRecord.ExceptionCode, + (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress); + ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; + break; + } + exception_count++; + last_sig = ourstatus->value.sig; + return 1; +} + +/* Resume all artificially suspended threads if we are continuing + execution */ +static BOOL +child_continue (DWORD continue_status, int id) +{ + int i; + thread_info *th; + BOOL res; + + DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n", + current_event.dwProcessId, current_event.dwThreadId, + continue_status == DBG_CONTINUE ? + "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED")); + res = ContinueDebugEvent (current_event.dwProcessId, + current_event.dwThreadId, + continue_status); + continue_status = 0; + if (res) + for (th = &thread_head; (th = th->next) != NULL;) + if (((id == -1) || (id == (int) th->id)) && th->suspend_count) + { + + for (i = 0; i < th->suspend_count; i++) + (void) ResumeThread (th->h); + th->suspend_count = 0; + if (debug_registers_changed) + { + /* Only change the value of the debug registers */ + th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + /* th->context.Dr6 = dr[6]; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr[7]; + CHECK (SetThreadContext (th->h, &th->context)); + th->context.ContextFlags = 0; + } + } + + debug_registers_changed = 0; + return res; +} + +/* Called in pathological case where Windows fails to send a + CREATE_PROCESS_DEBUG_EVENT after an attach. */ +DWORD +fake_create_process (void) +{ + current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, + current_event.dwProcessId); + main_thread_id = current_event.dwThreadId; + current_thread = child_add_thread (main_thread_id, + current_event.u.CreateThread.hThread); + return main_thread_id; +} + +/* Get the next event from the child. Return 1 if the event requires + handling by WFI (or whatever). + */ +static int +get_child_debug_event (int pid, struct target_waitstatus *ourstatus) +{ + BOOL debug_event; + DWORD continue_status, event_code; + thread_info *th; + static thread_info dummy_thread_info; + int retval = 0; + + last_sig = TARGET_SIGNAL_0; + + if (!(debug_event = WaitForDebugEvent (¤t_event, 1000))) + goto out; + + event_count++; + continue_status = DBG_CONTINUE; + + event_code = current_event.dwDebugEventCode; + ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + th = NULL; + + switch (event_code) + { + case CREATE_THREAD_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "CREATE_THREAD_DEBUG_EVENT")); + if (saw_create != 1) + { + if (!saw_create && attach_flag) + { + /* Kludge around a Windows bug where first event is a create + thread event. Caused when attached process does not have + a main thread. */ + retval = ourstatus->value.related_pid = fake_create_process (); + saw_create++; + } + break; + } + /* Record the existence of this thread */ + th = child_add_thread (current_event.dwThreadId, + current_event.u.CreateThread.hThread); + if (info_verbose) + printf_unfiltered ("[New %s]\n", + target_pid_to_str ( + pid_to_ptid (current_event.dwThreadId))); + retval = current_event.dwThreadId; + break; + + case EXIT_THREAD_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "EXIT_THREAD_DEBUG_EVENT")); + if (current_event.dwThreadId != main_thread_id) + { + child_delete_thread (current_event.dwThreadId); + th = &dummy_thread_info; + } + break; + + case CREATE_PROCESS_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "CREATE_PROCESS_DEBUG_EVENT")); + CloseHandle (current_event.u.CreateProcessInfo.hFile); + if (++saw_create != 1) + { + CloseHandle (current_event.u.CreateProcessInfo.hProcess); + break; + } + + current_process_handle = current_event.u.CreateProcessInfo.hProcess; + if (main_thread_id) + child_delete_thread (main_thread_id); + main_thread_id = current_event.dwThreadId; + /* Add the main thread */ + th = child_add_thread (main_thread_id, + current_event.u.CreateProcessInfo.hThread); + retval = ourstatus->value.related_pid = current_event.dwThreadId; + break; + + case EXIT_PROCESS_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "EXIT_PROCESS_DEBUG_EVENT")); + if (saw_create != 1) + break; + ourstatus->kind = TARGET_WAITKIND_EXITED; + ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; + CloseHandle (current_process_handle); + retval = main_thread_id; + break; + + case LOAD_DLL_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "LOAD_DLL_DEBUG_EVENT")); + CloseHandle (current_event.u.LoadDll.hFile); + if (saw_create != 1) + break; + catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL); + registers_changed (); /* mark all regs invalid */ + ourstatus->kind = TARGET_WAITKIND_LOADED; + ourstatus->value.integer = 0; + retval = main_thread_id; + re_enable_breakpoints_in_shlibs (); + break; + + case UNLOAD_DLL_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "UNLOAD_DLL_DEBUG_EVENT")); + if (saw_create != 1) + break; + catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL); + registers_changed (); /* mark all regs invalid */ + /* ourstatus->kind = TARGET_WAITKIND_UNLOADED; + does not exist yet. */ + break; + + case EXCEPTION_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "EXCEPTION_DEBUG_EVENT")); + if (saw_create != 1) + break; + if (handle_exception (ourstatus)) + retval = current_event.dwThreadId; + break; + + case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */ + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "OUTPUT_DEBUG_STRING_EVENT")); + if (saw_create != 1) + break; + if (handle_output_debug_string (ourstatus)) + retval = main_thread_id; + break; + + default: + if (saw_create != 1) + break; + printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n", + (DWORD) current_event.dwProcessId, + (DWORD) current_event.dwThreadId); + printf_unfiltered (" unknown event code %ld\n", + current_event.dwDebugEventCode); + break; + } + + if (!retval || saw_create != 1) + CHECK (child_continue (continue_status, -1)); + else + { + inferior_ptid = pid_to_ptid (retval); + current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE); + } + +out: + return retval; +} + +/* Wait for interesting events to occur in the target process. */ +static ptid_t +child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +{ + int pid = PIDGET (ptid); + + /* We loop when we get a non-standard exception rather than return + with a SPURIOUS because resume can try and step or modify things, + which needs a current_thread->h. But some of these exceptions mark + the birth or death of threads, which mean that the current thread + isn't necessarily what you think it is. */ + + while (1) + { + int retval = get_child_debug_event (pid, ourstatus); + if (retval) + return pid_to_ptid (retval); + else + { + int detach = 0; + + if (ui_loop_hook != NULL) + detach = ui_loop_hook (0); + + if (detach) + child_kill_inferior (); + } + } +} + +static void +do_initial_child_stuff (DWORD pid) +{ + extern int stop_after_trap; + int i; + + last_sig = TARGET_SIGNAL_0; + event_count = 0; + exception_count = 0; + debug_registers_changed = 0; + debug_registers_used = 0; + for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++) + dr[i] = 0; + current_event.dwProcessId = pid; + memset (¤t_event, 0, sizeof (current_event)); + push_target (&child_ops); + child_init_thread_list (); + disable_breakpoints_in_shlibs (1); + child_clear_solibs (); + clear_proceed_status (); + init_wait_for_inferior (); + + target_terminal_init (); + target_terminal_inferior (); + + while (1) + { + stop_after_trap = 1; + wait_for_inferior (); + if (stop_signal != TARGET_SIGNAL_TRAP) + resume (0, stop_signal); + else + break; + } + stop_after_trap = 0; + return; +} + +/* Since Windows XP, detaching from a process is supported by Windows. + The following code tries loading the appropriate functions dynamically. + If loading these functions succeeds use them to actually detach from + the inferior process, otherwise behave as usual, pretending that + detach has worked. */ +static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL); +static BOOL WINAPI (*DebugActiveProcessStop)(DWORD); + +static int +has_detach_ability (void) +{ + static HMODULE kernel32 = NULL; + + if (!kernel32) + kernel32 = LoadLibrary ("kernel32.dll"); + if (kernel32) + { + if (!DebugSetProcessKillOnExit) + DebugSetProcessKillOnExit = GetProcAddress (kernel32, + "DebugSetProcessKillOnExit"); + if (!DebugActiveProcessStop) + DebugActiveProcessStop = GetProcAddress (kernel32, + "DebugActiveProcessStop"); + if (DebugSetProcessKillOnExit && DebugActiveProcessStop) + return 1; + } + return 0; +} + +/* Try to set or remove a user privilege to the current process. Return -1 + if that fails, the previous setting of that privilege otherwise. + + This code is copied from the Cygwin source code and rearranged to allow + dynamically loading of the needed symbols from advapi32 which is only + available on NT/2K/XP. */ +static int +set_process_privilege (const char *privilege, BOOL enable) +{ + static HMODULE advapi32 = NULL; + static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE); + static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID); + static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, + DWORD, PTOKEN_PRIVILEGES, PDWORD); + + HANDLE token_hdl = NULL; + LUID restore_priv; + TOKEN_PRIVILEGES new_priv, orig_priv; + int ret = -1; + DWORD size; + + if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */ + return 0; + + if (!advapi32) + { + if (!(advapi32 = LoadLibrary ("advapi32.dll"))) + goto out; + if (!OpenProcessToken) + OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken"); + if (!LookupPrivilegeValue) + LookupPrivilegeValue = GetProcAddress (advapi32, + "LookupPrivilegeValueA"); + if (!AdjustTokenPrivileges) + AdjustTokenPrivileges = GetProcAddress (advapi32, + "AdjustTokenPrivileges"); + if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges) + { + advapi32 = NULL; + goto out; + } + } + + if (!OpenProcessToken (GetCurrentProcess (), + TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, + &token_hdl)) + goto out; + + if (!LookupPrivilegeValue (NULL, privilege, &restore_priv)) + goto out; + + new_priv.PrivilegeCount = 1; + new_priv.Privileges[0].Luid = restore_priv; + new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0; + + if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv, + sizeof orig_priv, &orig_priv, &size)) + goto out; +#if 0 + /* Disabled, otherwise every `attach' in an unprivileged user session + would raise the "Failed to get SE_DEBUG_NAME privilege" warning in + child_attach(). */ + /* AdjustTokenPrivileges returns TRUE even if the privilege could not + be enabled. GetLastError () returns an correct error code, though. */ + if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED) + goto out; +#endif + + ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0; + +out: + if (token_hdl) + CloseHandle (token_hdl); + + return ret; +} + +/* Attach to process PID, then initialize for debugging it. */ +static void +child_attach (char *args, int from_tty) +{ + BOOL ok; + DWORD pid; + + if (!args) + error_no_arg ("process-id to attach"); + + if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0) + { + printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n"); + printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n"); + } + + pid = strtoul (args, 0, 0); /* Windows pid */ + + ok = DebugActiveProcess (pid); + saw_create = 0; + + if (!ok) + { + /* Try fall back to Cygwin pid */ + pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid); + + if (pid > 0) + ok = DebugActiveProcess (pid); + + if (!ok) + error ("Can't attach to process."); + } + + if (has_detach_ability ()) + DebugSetProcessKillOnExit (FALSE); + + attach_flag = 1; + + if (from_tty) + { + char *exec_file = (char *) get_exec_file (0); + + if (exec_file) + printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, + target_pid_to_str (pid_to_ptid (pid))); + else + printf_unfiltered ("Attaching to %s\n", + target_pid_to_str (pid_to_ptid (pid))); + + gdb_flush (gdb_stdout); + } + + do_initial_child_stuff (pid); + target_terminal_ours (); +} + +static void +child_detach (char *args, int from_tty) +{ + int detached = 1; + + if (has_detach_ability ()) + { + delete_command (NULL, 0); + child_continue (DBG_CONTINUE, -1); + if (!DebugActiveProcessStop (current_event.dwProcessId)) + { + error ("Can't detach process %lu (error %lu)", + current_event.dwProcessId, GetLastError ()); + detached = 0; + } + DebugSetProcessKillOnExit (FALSE); + } + if (detached && from_tty) + { + char *exec_file = get_exec_file (0); + if (exec_file == 0) + exec_file = ""; + printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file, + current_event.dwProcessId); + gdb_flush (gdb_stdout); + } + inferior_ptid = null_ptid; + unpush_target (&child_ops); +} + +/* Print status information about what we're accessing. */ + +static void +child_files_info (struct target_ops *ignore) +{ + printf_unfiltered ("\tUsing the running image of %s %s.\n", + attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); +} + +static void +child_open (char *arg, int from_tty) +{ + error ("Use the \"run\" command to start a Unix child process."); +} + +/* Start an inferior win32 child process and sets inferior_ptid 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(). */ + +static void +child_create_inferior (char *exec_file, char *allargs, char **env) +{ + char *winenv; + char *temp; + int envlen; + int i; + STARTUPINFO si; + PROCESS_INFORMATION pi; + BOOL ret; + DWORD flags; + char *args; + char real_path[MAXPATHLEN]; + char *toexec; + char shell[MAX_PATH + 1]; /* Path to shell */ + const char *sh; + int tty; + int ostdin, ostdout, ostderr; + + if (!exec_file) + error ("No executable specified, use `target exec'.\n"); + + memset (&si, 0, sizeof (si)); + si.cb = sizeof (si); + + if (!useshell) + { + flags = DEBUG_ONLY_THIS_PROCESS; + cygwin_conv_to_win32_path (exec_file, real_path); + toexec = real_path; + } + else + { + char *newallargs; + sh = getenv ("SHELL"); + if (!sh) + sh = "/bin/sh"; + cygwin_conv_to_win32_path (sh, shell); + newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file) + + strlen (allargs) + 2); + sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs); + allargs = newallargs; + toexec = shell; + flags = DEBUG_PROCESS; + } + + if (new_group) + flags |= CREATE_NEW_PROCESS_GROUP; + + if (new_console) + flags |= CREATE_NEW_CONSOLE; + + attach_flag = 0; + + args = alloca (strlen (toexec) + strlen (allargs) + 2); + strcpy (args, toexec); + strcat (args, " "); + strcat (args, allargs); + + /* Prepare the environment vars for CreateProcess. */ + { + /* This code used to assume all env vars were file names and would + translate them all to win32 style. That obviously doesn't work in the + general case. The current rule is that we only translate PATH. + We need to handle PATH because we're about to call CreateProcess and + it uses PATH to find DLL's. Fortunately PATH has a well-defined value + in both posix and win32 environments. cygwin.dll will change it back + to posix style if necessary. */ + + static const char *conv_path_names[] = + { + "PATH=", + 0 + }; + + /* CreateProcess takes the environment list as a null terminated set of + strings (i.e. two nulls terminate the list). */ + + /* Get total size for env strings. */ + for (envlen = 0, i = 0; env[i] && *env[i]; i++) + { + int j, len; + + for (j = 0; conv_path_names[j]; j++) + { + len = strlen (conv_path_names[j]); + if (strncmp (conv_path_names[j], env[i], len) == 0) + { + if (cygwin_posix_path_list_p (env[i] + len)) + envlen += len + + cygwin_posix_to_win32_path_list_buf_size (env[i] + len); + else + envlen += strlen (env[i]) + 1; + break; + } + } + if (conv_path_names[j] == NULL) + envlen += strlen (env[i]) + 1; + } + + winenv = alloca (envlen + 1); + + /* Copy env strings into new buffer. */ + for (temp = winenv, i = 0; env[i] && *env[i]; i++) + { + int j, len; + + for (j = 0; conv_path_names[j]; j++) + { + len = strlen (conv_path_names[j]); + if (strncmp (conv_path_names[j], env[i], len) == 0) + { + if (cygwin_posix_path_list_p (env[i] + len)) + { + memcpy (temp, env[i], len); + cygwin_posix_to_win32_path_list (env[i] + len, temp + len); + } + else + strcpy (temp, env[i]); + break; + } + } + if (conv_path_names[j] == NULL) + strcpy (temp, env[i]); + + temp += strlen (temp) + 1; + } + + /* Final nil string to terminate new env. */ + *temp = 0; + } + + if (!inferior_io_terminal) + tty = ostdin = ostdout = ostderr = -1; + else + { + tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY); + if (tty < 0) + { + print_sys_errmsg (inferior_io_terminal, errno); + ostdin = ostdout = ostderr = -1; + } + else + { + ostdin = dup (0); + ostdout = dup (1); + ostderr = dup (2); + dup2 (tty, 0); + dup2 (tty, 1); + dup2 (tty, 2); + } + } + + ret = CreateProcess (0, + args, /* command line */ + NULL, /* Security */ + NULL, /* thread */ + TRUE, /* inherit handles */ + flags, /* start flags */ + winenv, + NULL, /* current directory */ + &si, + &pi); + if (tty >= 0) + { + close (tty); + dup2 (ostdin, 0); + dup2 (ostdout, 1); + dup2 (ostderr, 2); + close (ostdin); + close (ostdout); + close (ostderr); + } + + if (!ret) + error ("Error creating process %s, (error %d)\n", exec_file, (unsigned) GetLastError ()); + + CloseHandle (pi.hThread); + CloseHandle (pi.hProcess); + + if (useshell && shell[0] != '\0') + saw_create = -1; + else + saw_create = 0; + + do_initial_child_stuff (pi.dwProcessId); + + /* child_continue (DBG_CONTINUE, -1); */ + proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0); +} + +static void +child_mourn_inferior (void) +{ + (void) child_continue (DBG_CONTINUE, -1); + i386_cleanup_dregs(); + unpush_target (&child_ops); + generic_mourn_inferior (); +} + +/* Send a SIGINT to the process group. This acts just like the user typed a + ^C on the controlling terminal. */ + +static void +child_stop (void) +{ + DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n")); + CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId)); + registers_changed (); /* refresh register state */ +} + +int +child_xfer_memory (CORE_ADDR memaddr, char *our, int len, + int write, struct mem_attrib *mem, + struct target_ops *target) +{ + DWORD done = 0; + if (write) + { + DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n", + len, (DWORD) memaddr)); + if (!WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our, + len, &done)) + done = 0; + FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len); + } + else + { + DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n", + len, (DWORD) memaddr)); + if (!ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, + len, &done)) + done = 0; + } + return done; +} + +void +child_kill_inferior (void) +{ + CHECK (TerminateProcess (current_process_handle, 0)); + + for (;;) + { + if (!child_continue (DBG_CONTINUE, -1)) + break; + if (!WaitForDebugEvent (¤t_event, INFINITE)) + break; + if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) + break; + } + + CHECK (CloseHandle (current_process_handle)); + + /* this may fail in an attached process so don't check. */ + if (current_thread && current_thread->h) + (void) CloseHandle (current_thread->h); + target_mourn_inferior (); /* or just child_mourn_inferior? */ +} + +void +child_resume (ptid_t ptid, int step, enum target_signal sig) +{ + thread_info *th; + DWORD continue_status = DBG_CONTINUE; + + int pid = PIDGET (ptid); + + if (sig != TARGET_SIGNAL_0) + { + if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) + { + DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig)); + } + else if (sig == last_sig) + continue_status = DBG_EXCEPTION_NOT_HANDLED; + else +#if 0 +/* This code does not seem to work, because + the kernel does probably not consider changes in the ExceptionRecord + structure when passing the exception to the inferior. + Note that this seems possible in the exception handler itself. */ + { + int i; + for (i = 0; xlate[i].them != -1; i++) + if (xlate[i].us == sig) + { + current_event.u.Exception.ExceptionRecord.ExceptionCode = + xlate[i].them; + continue_status = DBG_EXCEPTION_NOT_HANDLED; + break; + } + if (continue_status == DBG_CONTINUE) + { + DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig)); + } + } +#endif + DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n", + last_sig)); + } + + last_sig = TARGET_SIGNAL_0; + + DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n", + pid, step, sig)); + + /* Get context for currently selected thread */ + th = thread_rec (current_event.dwThreadId, FALSE); + if (th) + { + if (step) + { + /* Single step by setting t bit */ + child_fetch_inferior_registers (PS_REGNUM); + th->context.EFlags |= FLAG_TRACE_BIT; + } + + if (th->context.ContextFlags) + { + if (debug_registers_changed) + { + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + /* th->context.Dr6 = dr[6]; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr[7]; + } + CHECK (SetThreadContext (th->h, &th->context)); + th->context.ContextFlags = 0; + } + } + + /* Allow continuing with the same signal that interrupted us. + Otherwise complain. */ + + child_continue (continue_status, pid); +} + +static void +child_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ +} + +static int +child_can_run (void) +{ + return 1; +} + +static void +child_close (int x) +{ + DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n", + PIDGET (inferior_ptid))); +} + +struct target_ops child_ops; + +static void +init_child_ops (void) +{ + child_ops.to_shortname = "child"; + child_ops.to_longname = "Win32 child process"; + child_ops.to_doc = "Win32 child process (started by the \"run\" command)."; + child_ops.to_open = child_open; + child_ops.to_close = child_close; + child_ops.to_attach = child_attach; + child_ops.to_detach = child_detach; + child_ops.to_resume = child_resume; + child_ops.to_wait = child_wait; + child_ops.to_fetch_registers = child_fetch_inferior_registers; + child_ops.to_store_registers = child_store_inferior_registers; + child_ops.to_prepare_to_store = child_prepare_to_store; + child_ops.to_xfer_memory = child_xfer_memory; + child_ops.to_files_info = child_files_info; + child_ops.to_insert_breakpoint = memory_insert_breakpoint; + child_ops.to_remove_breakpoint = memory_remove_breakpoint; + child_ops.to_terminal_init = terminal_init_inferior; + child_ops.to_terminal_inferior = terminal_inferior; + child_ops.to_terminal_ours_for_output = terminal_ours_for_output; + child_ops.to_terminal_ours = terminal_ours; + child_ops.to_terminal_save_ours = terminal_save_ours; + child_ops.to_terminal_info = child_terminal_info; + child_ops.to_kill = child_kill_inferior; + child_ops.to_create_inferior = child_create_inferior; + child_ops.to_mourn_inferior = child_mourn_inferior; + child_ops.to_can_run = child_can_run; + child_ops.to_thread_alive = win32_child_thread_alive; + child_ops.to_pid_to_str = cygwin_pid_to_str; + child_ops.to_stop = child_stop; + child_ops.to_stratum = process_stratum; + child_ops.to_has_all_memory = 1; + child_ops.to_has_memory = 1; + child_ops.to_has_stack = 1; + child_ops.to_has_registers = 1; + child_ops.to_has_execution = 1; + child_ops.to_magic = OPS_MAGIC; +} + +void +_initialize_win32_nat (void) +{ + struct cmd_list_element *c; + + init_child_ops (); + + c = add_com ("dll-symbols", class_files, dll_symbol_command, + "Load dll library symbols from FILE."); + set_cmd_completer (c, filename_completer); + + add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1); + + add_show_from_set (add_set_cmd ("shell", class_support, var_boolean, + (char *) &useshell, + "Set use of shell to start subprocess.", + &setlist), + &showlist); + + add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean, + (char *) &new_console, + "Set creation of new console when creating child process.", + &setlist), + &showlist); + + add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean, + (char *) &new_group, + "Set creation of new group when creating child process.", + &setlist), + &showlist); + + add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean, + (char *) &debug_exec, + "Set whether to display execution in child process.", + &setlist), + &showlist); + + add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean, + (char *) &debug_events, + "Set whether to display kernel events in child process.", + &setlist), + &showlist); + + add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean, + (char *) &debug_memory, + "Set whether to display memory accesses in child process.", + &setlist), + &showlist); + + add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean, + (char *) &debug_exceptions, + "Set whether to display kernel exceptions in child process.", + &setlist), + &showlist); + + add_info ("dll", info_dll_command, "Status of loaded DLLs."); + add_info_alias ("sharedlibrary", "dll", 1); + + add_prefix_cmd ("w32", class_info, info_w32_command, + "Print information specific to Win32 debugging.", + &info_w32_cmdlist, "info w32 ", 0, &infolist); + + add_cmd ("selector", class_info, display_selectors, + "Display selectors infos.", + &info_w32_cmdlist); + + add_target (&child_ops); +} + +/* Hardware watchpoint support, adapted from go32-nat.c code. */ + +/* Pass the address ADDR to the inferior in the I'th debug register. + Here we just store the address in dr array, the registers will be + actually set up when child_continue is called. */ +void +cygwin_set_dr (int i, CORE_ADDR addr) +{ + if (i < 0 || i > 3) + internal_error (__FILE__, __LINE__, + "Invalid register %d in cygwin_set_dr.\n", i); + dr[i] = (unsigned) addr; + debug_registers_changed = 1; + debug_registers_used = 1; +} + +/* Pass the value VAL to the inferior in the DR7 debug control + register. Here we just store the address in D_REGS, the watchpoint + will be actually set up in child_wait. */ +void +cygwin_set_dr7 (unsigned val) +{ + dr[7] = val; + debug_registers_changed = 1; + debug_registers_used = 1; +} + +/* Get the value of the DR6 debug status register from the inferior. + Here we just return the value stored in dr[6] + by the last call to thread_rec for current_event.dwThreadId id. */ +unsigned +cygwin_get_dr6 (void) +{ + return dr[6]; +} + +/* Determine if the thread referenced by "pid" is alive + by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0 + it means that the pid has died. Otherwise it is assumed to be alive. */ +static int +win32_child_thread_alive (ptid_t ptid) +{ + int pid = PIDGET (ptid); + + return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ? + FALSE : TRUE; +} + +/* Convert pid to printable format. */ +char * +cygwin_pid_to_str (ptid_t ptid) +{ + static char buf[80]; + int pid = PIDGET (ptid); + + if ((DWORD) pid == current_event.dwProcessId) + sprintf (buf, "process %d", pid); + else + sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid); + return buf; +} + +static int +core_dll_symbols_add (char *dll_name, DWORD base_addr) +{ + struct objfile *objfile; + char *objfile_basename; + const char *dll_basename; + + if (!(dll_basename = strrchr (dll_name, '/'))) + dll_basename = dll_name; + else + dll_basename++; + + ALL_OBJFILES (objfile) + { + objfile_basename = strrchr (objfile->name, '/'); + + if (objfile_basename && + strcmp (dll_basename, objfile_basename + 1) == 0) + { + printf_unfiltered ("%08lx:%s (symbols previously loaded)\n", + base_addr, dll_name); + goto out; + } + } + + register_loaded_dll (dll_name, base_addr + 0x1000); + solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000); + + out: + return 1; + } + + typedef struct + { + struct target_ops *target; + bfd_vma addr; + } map_code_section_args; + + static void + map_single_dll_code_section (bfd * abfd, asection * sect, void *obj) + { + int old; + int update_coreops; + struct section_table *new_target_sect_ptr; + + map_code_section_args *args = (map_code_section_args *) obj; + struct target_ops *target = args->target; + if (sect->flags & SEC_CODE) + { + update_coreops = core_ops.to_sections == target->to_sections; + + if (target->to_sections) + { + old = target->to_sections_end - target->to_sections; + target->to_sections = (struct section_table *) + xrealloc ((char *) target->to_sections, + (sizeof (struct section_table)) * (1 + old)); + } + else + { + old = 0; + target->to_sections = (struct section_table *) + xmalloc ((sizeof (struct section_table))); + } + target->to_sections_end = target->to_sections + (1 + old); + + /* Update the to_sections field in the core_ops structure + if needed. */ + if (update_coreops) + { + core_ops.to_sections = target->to_sections; + core_ops.to_sections_end = target->to_sections_end; + } + new_target_sect_ptr = target->to_sections + old; + new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect); + new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) + + bfd_section_size (abfd, sect);; + new_target_sect_ptr->the_bfd_section = sect; + new_target_sect_ptr->bfd = abfd; + } + } + + static int + dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target) +{ + bfd *dll_bfd; + map_code_section_args map_args; + asection *lowest_sect; + char *name; + if (dll_name == NULL || target == NULL) + return 0; + name = xstrdup (dll_name); + dll_bfd = bfd_openr (name, "pei-i386"); + if (dll_bfd == NULL) + return 0; + + if (bfd_check_format (dll_bfd, bfd_object)) + { + lowest_sect = bfd_get_section_by_name (dll_bfd, ".text"); + if (lowest_sect == NULL) + return 0; + map_args.target = target; + map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect); + + bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args)); + } + + return 1; +} + +static void +core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj) +{ + struct target_ops *target = (struct target_ops *) obj; + + DWORD base_addr; + + int dll_name_size; + char *dll_name = NULL; + char *buf = NULL; + struct win32_pstatus *pstatus; + char *p; + + if (strncmp (sect->name, ".module", 7)) + return; + + buf = (char *) xmalloc (sect->_raw_size + 1); + if (!buf) + { + printf_unfiltered ("memory allocation failed for %s\n", sect->name); + goto out; + } + if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size)) + goto out; + + pstatus = (struct win32_pstatus *) buf; + + memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr)); + dll_name_size = pstatus->data.module_info.module_name_size; + if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size) + goto out; + + dll_name = (char *) xmalloc (dll_name_size + 1); + if (!dll_name) + { + printf_unfiltered ("memory allocation failed for %s\n", sect->name); + goto out; + } + strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size); + + while ((p = strchr (dll_name, '\\'))) + *p = '/'; + + if (!core_dll_symbols_add (dll_name, (DWORD) base_addr)) + printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name); + + if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target)) + printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name); + +out: + if (buf) + xfree (buf); + if (dll_name) + xfree (dll_name); + return; +} + +void +child_solib_add (char *filename, int from_tty, struct target_ops *target, + int readsyms) +{ + if (!readsyms) + return; + if (core_bfd) + { + child_clear_solibs (); + bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target); + } + else + { + if (solib_end && solib_end->name) + solib_end->objfile = solib_symbols_add (solib_end->name, from_tty, + solib_end->load_addr); + } +} + +static void +fetch_elf_core_registers (char *core_reg_sect, + unsigned core_reg_size, + int which, + CORE_ADDR reg_addr) +{ + int r; + if (core_reg_size < sizeof (CONTEXT)) + { + error ("Core file register section too small (%u bytes).", core_reg_size); + return; + } + for (r = 0; r < NUM_REGS; r++) + supply_register (r, core_reg_sect + mappings[r]); +} + +static struct core_fns win32_elf_core_fns = +{ + bfd_target_elf_flavour, + default_check_format, + default_core_sniffer, + fetch_elf_core_registers, + NULL +}; + +void +_initialize_core_win32 (void) +{ + add_core_fns (&win32_elf_core_fns); +} + +void +_initialize_check_for_gdb_ini (void) +{ + char *homedir; + if (inhibit_gdbinit) + return; + + homedir = getenv ("HOME"); + if (homedir) + { + char *p; + char *oldini = (char *) alloca (strlen (homedir) + + sizeof ("/gdb.ini")); + strcpy (oldini, homedir); + p = strchr (oldini, '\0'); + if (p > oldini && p[-1] != '/') + *p++ = '/'; + strcpy (p, "gdb.ini"); + if (access (oldini, 0) == 0) + { + int len = strlen (oldini); + char *newini = alloca (len + 1); + sprintf (newini, "%.*s.gdbinit", + (int) (len - (sizeof ("gdb.ini") - 1)), oldini); + warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini); + } + } +} diff --git a/contrib/gdb/gdb/wince-stub.c b/contrib/gdb/gdb/wince-stub.c new file mode 100644 index 00000000000..ce872d8137e --- /dev/null +++ b/contrib/gdb/gdb/wince-stub.c @@ -0,0 +1,592 @@ +/* wince-stub.c -- debugging stub for a Windows CE device + + Copyright 1999, 2000 Free Software Foundation, Inc. + Contributed by Cygnus Solutions, A Red Hat Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without eve nthe implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/* by Christopher Faylor (cgf@cygnus.com) */ + +#include +#include +#include +#include "wince-stub.h" + +#define MALLOC(n) (void *) LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, (UINT)(n)) +#define REALLOC(s, n) (void *) LocalReAlloc ((HLOCAL)(s), (UINT)(n), LMEM_MOVEABLE) +#define FREE(s) LocalFree ((HLOCAL)(s)) + +static int skip_next_id = 0; /* Don't read next API code from socket */ + +/* v-style interface for handling varying argument list error messages. + Displays the error message in a dialog box and exits when user clicks + on OK. */ +static void +vstub_error (LPCWSTR fmt, va_list args) +{ + WCHAR buf[4096]; + wvsprintfW (buf, fmt, args); + + MessageBoxW (NULL, buf, L"GDB", MB_ICONERROR); + WSACleanup (); + ExitThread (1); +} + +/* The standard way to display an error message and exit. */ +static void +stub_error (LPCWSTR fmt, ...) +{ + va_list args; + va_start (args, fmt); + vstub_error (fmt, args); +} + +/* Allocate a limited pool of memory, reallocating over unused + buffers. This assumes that there will never be more than four + "buffers" required which, so far, is a safe assumption. */ +static LPVOID +mempool (unsigned int len) +{ + static int outn = -1; + static LPWSTR outs[4] = {NULL, NULL, NULL, NULL}; + + if (++outn >= (sizeof (outs) / sizeof (outs[0]))) + outn = 0; + + /* Allocate space for the converted string, reusing any previously allocated + space, if applicable. */ + if (outs[outn]) + FREE (outs[outn]); + outs[outn] = (LPWSTR) MALLOC (len); + + return outs[outn]; +} + +/* Standard "oh well" can't communicate error. Someday this might attempt + synchronization. */ +static void +attempt_resync (LPCWSTR huh, int s) +{ + stub_error (L"lost synchronization with host attempting %s. Error %d", huh, WSAGetLastError ()); +} + +/* Read arbitrary stuff from a socket. */ +static int +sockread (LPCWSTR huh, int s, void *str, size_t n) +{ + for (;;) + { + if (recv (s, str, n, 0) == (int) n) + return n; + attempt_resync (huh, s); + } +} + +/* Write arbitrary stuff to a socket. */ +static int +sockwrite (LPCWSTR huh, int s, const void *str, size_t n) +{ + for (;;) + { + if (send (s, str, n, 0) == (int) n) + return n; + attempt_resync (huh, s); + } +} + +/* Get a an ID (possibly) and a DWORD from the host gdb. + Don't bother with the id if the main loop has already + read it. */ +static DWORD +getdword (LPCWSTR huh, int s, gdb_wince_id what_this) +{ + DWORD n; + gdb_wince_id what; + + if (skip_next_id) + skip_next_id = 0; + else + do + if (sockread (huh, s, &what, sizeof (what)) != sizeof (what)) + stub_error (L"error getting record type from host - %s.", huh); + while (what_this != what); + + if (sockread (huh, s, &n, sizeof (n)) != sizeof (n)) + stub_error (L"error getting %s from host.", huh); + + return n; +} + +/* Get a an ID (possibly) and a WORD from the host gdb. + Don't bother with the id if the main loop has already + read it. */ +static WORD +getword (LPCWSTR huh, int s, gdb_wince_id what_this) +{ + WORD n; + gdb_wince_id what; + + if (skip_next_id) + skip_next_id = 0; + else + do + if (sockread (huh, s, &what, sizeof (what)) != sizeof (what)) + stub_error (L"error getting record type from host - %s.", huh); + while (what_this != what); + + if (sockread (huh, s, &n, sizeof (n)) != sizeof (n)) + stub_error (L"error getting %s from host.", huh); + + return n; +} + +/* Handy defines for getting various types of values. */ +#define gethandle(huh, s, what) (HANDLE) getdword ((huh), (s), (what)) +#define getpvoid(huh, s, what) (LPVOID) getdword ((huh), (s), (what)) +#define getlen(huh, s, what) (gdb_wince_len) getword ((huh), (s), (what)) + +/* Get an arbitrary block of memory from the gdb host. This comes in + two chunks an id/dword representing the length and the stream of memory + itself. Returns a pointer, allocated via mempool, to a memory buffer. */ +static LPWSTR +getmemory (LPCWSTR huh, int s, gdb_wince_id what, gdb_wince_len *inlen) +{ + LPVOID p; + gdb_wince_len dummy; + + if (!inlen) + inlen = &dummy; + + *inlen = getlen (huh, s, what); + + p = mempool ((unsigned int) *inlen); /* FIXME: check for error */ + + if ((gdb_wince_len) sockread (huh, s, p, *inlen) != *inlen) + stub_error (L"error getting string from host."); + + return p; +} + +/* Output an id/dword to the host */ +static void +putdword (LPCWSTR huh, int s, gdb_wince_id what, DWORD n) +{ + if (sockwrite (huh, s, &what, sizeof (what)) != sizeof (what)) + stub_error (L"error writing record id for %s to host.", huh); + if (sockwrite (huh, s, &n, sizeof (n)) != sizeof (n)) + stub_error (L"error writing %s to host.", huh); +} + +/* Output an id/word to the host */ +static void +putword (LPCWSTR huh, int s, gdb_wince_id what, WORD n) +{ + if (sockwrite (huh, s, &what, sizeof (what)) != sizeof (what)) + stub_error (L"error writing record id for %s to host.", huh); + if (sockwrite (huh, s, &n, sizeof (n)) != sizeof (n)) + stub_error (L"error writing %s to host.", huh); +} + +/* Convenience define for outputting a "gdb_wince_len" type. */ +#define putlen(huh, s, what, n) putword ((huh), (s), (what), (gdb_wince_len) (n)) + +/* Put an arbitrary block of memory to the gdb host. This comes in + two chunks an id/dword representing the length and the stream of memory + itself. */ +static void +putmemory (LPCWSTR huh, int s, gdb_wince_id what, const void *mem, gdb_wince_len len) +{ + putlen (huh, s, what, len); + if (((short) len > 0) && (gdb_wince_len) sockwrite (huh, s, mem, len) != len) + stub_error (L"error writing memory to host."); +} + +/* Output the result of an operation to the host. If res != 0, sends a block of + memory starting at mem of len bytes. If res == 0, sends -GetLastError () and + avoids sending the mem. */ +static void +putresult (LPCWSTR huh, gdb_wince_result res, int s, gdb_wince_id what, const void *mem, gdb_wince_len len) +{ + if (!res) + len = -(int) GetLastError (); + putmemory (huh, s, what, mem, len); +} + +static HANDLE curproc; /* Currently unused, but nice for debugging */ + +/* Emulate CreateProcess. Returns &pi if no error. */ +static void +create_process (int s) +{ + LPWSTR exec_file = getmemory (L"CreateProcess exec_file", s, GDB_CREATEPROCESS, NULL); + LPWSTR args = getmemory (L"CreateProcess args", s, GDB_CREATEPROCESS, NULL); + DWORD flags = getdword (L"CreateProcess flags", s, GDB_CREATEPROCESS); + PROCESS_INFORMATION pi; + gdb_wince_result res; + + res = CreateProcessW (exec_file, + args, /* command line */ + NULL, /* Security */ + NULL, /* thread */ + FALSE, /* inherit handles */ + flags, /* start flags */ + NULL, + NULL, /* current directory */ + NULL, + &pi); + putresult (L"CreateProcess", res, s, GDB_CREATEPROCESS, &pi, sizeof (pi)); + curproc = pi.hProcess; +} + +/* Emulate TerminateProcess. Returns return value of TerminateProcess if + no error. + *** NOTE: For some unknown reason, TerminateProcess seems to always return + an ACCESS_DENIED (on Windows CE???) error. So, force a TRUE value for now. */ +static void +terminate_process (int s) +{ + gdb_wince_result res; + HANDLE h = gethandle (L"TerminateProcess handle", s, GDB_TERMINATEPROCESS); + + res = TerminateProcess (h, 0) || 1; /* Doesn't seem to work on SH so default to TRUE */ + putresult (L"Terminate process result", res, s, GDB_TERMINATEPROCESS, + &res, sizeof (res)); +} + +static int stepped = 0; +/* Handle single step instruction. FIXME: unneded? */ +static void +flag_single_step (int s) +{ + stepped = 1; + skip_next_id = 0; +} + +struct skipper +{ + wchar_t *s; + int nskip; +} skippy[] = +{ + {L"Undefined Instruction:", 1}, + {L"Data Abort:", 2}, + {NULL, 0} +}; + +static int +skip_message (DEBUG_EVENT *ev) +{ + char s[80]; + DWORD nread; + struct skipper *skp; + int nbytes = ev->u.DebugString.nDebugStringLength; + + if (nbytes > sizeof(s)) + nbytes = sizeof(s); + + memset (s, 0, sizeof (s)); + if (!ReadProcessMemory (curproc, ev->u.DebugString.lpDebugStringData, + s, nbytes, &nread)) + return 0; + + for (skp = skippy; skp->s != NULL; skp++) + if (wcsncmp ((wchar_t *) s, skp->s, wcslen (skp->s)) == 0) + return skp->nskip; + + return 0; +} + +/* Emulate WaitForDebugEvent. Returns the debug event on success. */ +static void +wait_for_debug_event (int s) +{ + DWORD ms = getdword (L"WaitForDebugEvent ms", s, GDB_WAITFORDEBUGEVENT); + gdb_wince_result res; + DEBUG_EVENT ev; + static int skip_next = 0; + + for (;;) + { + res = WaitForDebugEvent (&ev, ms); + + if (ev.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) + { + if (skip_next) + { + skip_next--; + goto ignore; + } + if (skip_next = skip_message (&ev)) + goto ignore; + } + + putresult (L"WaitForDebugEvent event", res, s, GDB_WAITFORDEBUGEVENT, + &ev, sizeof (ev)); + break; + + ignore: + ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE); + } + + return; +} + +/* Emulate GetThreadContext. Returns CONTEXT structure on success. */ +static void +get_thread_context (int s) +{ + CONTEXT c; + HANDLE h = gethandle (L"GetThreadContext handle", s, GDB_GETTHREADCONTEXT); + gdb_wince_result res; + + memset (&c, 0, sizeof (c)); + c.ContextFlags = getdword (L"GetThreadContext flags", s, GDB_GETTHREADCONTEXT); + + res = (gdb_wince_result) GetThreadContext (h, &c); + putresult (L"GetThreadContext data", res, s, GDB_GETTHREADCONTEXT, + &c, sizeof (c)); +} + +/* Emulate GetThreadContext. Returns success of SetThreadContext. */ +static void +set_thread_context (int s) +{ + gdb_wince_result res; + HANDLE h = gethandle (L"SetThreadContext handle", s, GDB_SETTHREADCONTEXT); + LPCONTEXT pc = (LPCONTEXT) getmemory (L"SetThreadContext context", s, + GDB_SETTHREADCONTEXT, NULL); + + res = SetThreadContext (h, pc); + putresult (L"SetThreadContext result", res, s, GDB_SETTHREADCONTEXT, + &res, sizeof (res)); +} + +/* Emulate ReadProcessMemory. Returns memory read on success. */ +static void +read_process_memory (int s) +{ + HANDLE h = gethandle (L"ReadProcessMemory handle", s, GDB_READPROCESSMEMORY); + LPVOID p = getpvoid (L"ReadProcessMemory base", s, GDB_READPROCESSMEMORY); + gdb_wince_len len = getlen (L"ReadProcessMemory size", s, GDB_READPROCESSMEMORY); + LPVOID buf = mempool ((unsigned int) len); + DWORD outlen; + gdb_wince_result res; + + outlen = 0; + res = (gdb_wince_result) ReadProcessMemory (h, p, buf, len, &outlen); + putresult (L"ReadProcessMemory data", res, s, GDB_READPROCESSMEMORY, + buf, (gdb_wince_len) outlen); +} + +/* Emulate WriteProcessMemory. Returns WriteProcessMemory success. */ +static void +write_process_memory (int s) +{ + HANDLE h = gethandle (L"WriteProcessMemory handle", s, GDB_WRITEPROCESSMEMORY); + LPVOID p = getpvoid (L"WriteProcessMemory base", s, GDB_WRITEPROCESSMEMORY); + gdb_wince_len len; + LPVOID buf = getmemory (L"WriteProcessMemory buf", s, GDB_WRITEPROCESSMEMORY, &len); + DWORD outlen; + gdb_wince_result res; + + outlen = 0; + res = WriteProcessMemory (h, p, buf, (DWORD) len, &outlen); + putresult (L"WriteProcessMemory data", res, s, GDB_WRITEPROCESSMEMORY, + (gdb_wince_len *) & outlen, sizeof (gdb_wince_len)); +} + +/* Return non-zero to gdb host if given thread is alive. */ +static void +thread_alive (int s) +{ + HANDLE h = gethandle (L"ThreadAlive handle", s, GDB_THREADALIVE); + gdb_wince_result res; + + res = WaitForSingleObject (h, 0) == WAIT_OBJECT_0 ? 1 : 0; + putresult (L"WriteProcessMemory data", res, s, GDB_THREADALIVE, + &res, sizeof (res)); +} + +/* Emulate SuspendThread. Returns value returned from SuspendThread. */ +static void +suspend_thread (int s) +{ + DWORD res; + HANDLE h = gethandle (L"SuspendThread handle", s, GDB_SUSPENDTHREAD); + res = SuspendThread (h); + putdword (L"SuspendThread result", s, GDB_SUSPENDTHREAD, res); +} + +/* Emulate ResumeThread. Returns value returned from ResumeThread. */ +static void +resume_thread (int s) +{ + DWORD res; + HANDLE h = gethandle (L"ResumeThread handle", s, GDB_RESUMETHREAD); + res = ResumeThread (h); + putdword (L"ResumeThread result", s, GDB_RESUMETHREAD, res); +} + +/* Emulate ContinueDebugEvent. Returns ContinueDebugEvent success. */ +static void +continue_debug_event (int s) +{ + gdb_wince_result res; + DWORD pid = getdword (L"ContinueDebugEvent pid", s, GDB_CONTINUEDEBUGEVENT); + DWORD tid = getdword (L"ContinueDebugEvent tid", s, GDB_CONTINUEDEBUGEVENT); + DWORD status = getdword (L"ContinueDebugEvent status", s, GDB_CONTINUEDEBUGEVENT); + res = (gdb_wince_result) ContinueDebugEvent (pid, tid, status); + putresult (L"ContinueDebugEvent result", res, s, GDB_CONTINUEDEBUGEVENT, &res, sizeof (res)); +} + +/* Emulate CloseHandle. Returns CloseHandle success. */ +static void +close_handle (int s) +{ + gdb_wince_result res; + HANDLE h = gethandle (L"CloseHandle handle", s, GDB_CLOSEHANDLE); + res = (gdb_wince_result) CloseHandle (h); + putresult (L"CloseHandle result", res, s, GDB_CLOSEHANDLE, &res, sizeof (res)); +} + +/* Main loop for reading requests from gdb host on the socket. */ +static void +dispatch (int s) +{ + gdb_wince_id id; + + /* Continue reading from socket until receive a GDB_STOPSUB. */ + while (sockread (L"Dispatch", s, &id, sizeof (id)) > 0) + { + skip_next_id = 1; + switch (id) + { + case GDB_CREATEPROCESS: + create_process (s); + break; + case GDB_TERMINATEPROCESS: + terminate_process (s); + break; + case GDB_WAITFORDEBUGEVENT: + wait_for_debug_event (s); + break; + case GDB_GETTHREADCONTEXT: + get_thread_context (s); + break; + case GDB_SETTHREADCONTEXT: + set_thread_context (s); + break; + case GDB_READPROCESSMEMORY: + read_process_memory (s); + break; + case GDB_WRITEPROCESSMEMORY: + write_process_memory (s); + break; + case GDB_THREADALIVE: + thread_alive (s); + break; + case GDB_SUSPENDTHREAD: + suspend_thread (s); + break; + case GDB_RESUMETHREAD: + resume_thread (s); + break; + case GDB_CONTINUEDEBUGEVENT: + continue_debug_event (s); + break; + case GDB_CLOSEHANDLE: + close_handle (s); + break; + case GDB_STOPSTUB: + terminate_process (s); + return; + case GDB_SINGLESTEP: + flag_single_step (s); + break; + default: + { + WCHAR buf[80]; + wsprintfW (buf, L"Invalid command id received: %d", id); + MessageBoxW (NULL, buf, L"GDB", MB_ICONERROR); + skip_next_id = 0; + } + } + } +} + +/* The Windows Main entry point */ +int WINAPI +WinMain (HINSTANCE hi, HINSTANCE hp, LPWSTR cmd, int show) +{ + struct hostent *h; + int s; + struct WSAData wd; + struct sockaddr_in sin; + int tmp; + LPWSTR whost; + char host[80]; + + whost = wcschr (cmd, L' '); /* Look for argument. */ + + /* If no host is specified, just use default */ + if (whost) + { + /* Eat any spaces. */ + while (*whost == L' ' || *whost == L'\t') + whost++; + + wcstombs (host, whost, 80); /* Convert from UNICODE to ascii */ + } + + /* Winsock initialization. */ + if (WSAStartup (MAKEWORD (1, 1), &wd)) + stub_error (L"Couldn't initialize WINSOCK."); + + /* If whost was specified, first try it. If it was not specified or the + host lookup failed, try the Windows CE magic ppp_peer lookup. ppp_peer + is supposed to be the Windows host sitting on the other end of the + serial cable. */ + if (whost && *whost && (h = gethostbyname (host)) != NULL) + /* nothing to do */ ; + else if ((h = gethostbyname ("ppp_peer")) == NULL) + stub_error (L"Couldn't get IP address of host system. Error %d", WSAGetLastError ()); + + /* Get a socket. */ + if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) + stub_error (L"Couldn't connect to host system. Error %d", WSAGetLastError ()); + + /* Allow rapid reuse of the port. */ + tmp = 1; + setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp)); + + /* Set up the information for connecting to the host gdb process. */ + memset (&sin, 0, sizeof (sin)); + sin.sin_family = h->h_addrtype; + memcpy (&sin.sin_addr, h->h_addr, h->h_length); + sin.sin_port = htons (7000); /* FIXME: This should be configurable */ + + /* Connect to host */ + if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) + stub_error (L"Couldn't connect to host gdb."); + + /* Read from socket until told to exit. */ + dispatch (s); + WSACleanup (); + return 0; +} diff --git a/contrib/gdb/gdb/wince-stub.h b/contrib/gdb/gdb/wince-stub.h new file mode 100644 index 00000000000..21e9002116f --- /dev/null +++ b/contrib/gdb/gdb/wince-stub.h @@ -0,0 +1,48 @@ +/* wince-stub.h -- Definitions for commnicating with the WinCE stub. + + Copyright 1999, 2000 Free Software Foundation, Inc. + Contributed by Cygnus Solutions, A Red Hat Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without eve nthe implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/* by Christopher Faylor (cgf@cygnus.com) */ + +enum win_func + { + GDB_CREATEPROCESS = 42, + GDB_TERMINATEPROCESS, + GDB_WAITFORDEBUGEVENT, + GDB_GETTHREADCONTEXT, + GDB_SETTHREADCONTEXT, + GDB_READPROCESSMEMORY, + GDB_WRITEPROCESSMEMORY, + GDB_THREADALIVE, + GDB_SUSPENDTHREAD, + GDB_RESUMETHREAD, + GDB_CONTINUEDEBUGEVENT, + GDB_CLOSEHANDLE, + GDB_STOPSTUB, + GDB_SINGLESTEP, + GDB_SETBREAK, + GDB_INVALID + }; + +typedef unsigned char gdb_wince_id; +typedef unsigned short gdb_wince_len; +typedef short gdb_wince_result; diff --git a/contrib/gdb/gdb/wince.c b/contrib/gdb/gdb/wince.c new file mode 100644 index 00000000000..f15bbd4fa0f --- /dev/null +++ b/contrib/gdb/gdb/wince.c @@ -0,0 +1,2049 @@ +/* Target-vector operations for controlling Windows CE child processes, for GDB. + Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + Contributed by Cygnus Solutions, A Red Hat Company. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/* by Christopher Faylor (cgf@cygnus.com) */ + +/* We assume we're being built with and will be used for cygwin. */ + +#ifdef SHx +#undef SH4 +#define SH4 /* Just to get all of the CONTEXT defines. */ +#endif + +#include "defs.h" +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" +#include "target.h" +#include "gdbcore.h" +#include "command.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "buildsym.h" +#include "symfile.h" +#include "objfiles.h" +#include "gdb_string.h" +#include "gdbthread.h" +#include "gdbcmd.h" +#include +#include "wince-stub.h" +#include +#include "regcache.h" +#ifdef MIPS +#include "mips-tdep.h" +#endif + +/* The ui's event loop. */ +extern int (*ui_loop_hook) (int signo); + +/* If we're not using the old Cygwin header file set, define the + following which never should have been in the generic Win32 API + headers in the first place since they were our own invention... */ +#ifndef _GNU_H_WINDOWS_H +#define FLAG_TRACE_BIT 0x100 +#ifdef CONTEXT_FLOATING_POINT +#define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT) +#else +#define CONTEXT_DEBUGGER0 (CONTEXT_FULL) +#endif +#endif + +#ifdef SH4 +#define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3) +#else +#define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0 +#endif +/* The string sent by cygwin when it processes a signal. + FIXME: This should be in a cygwin include file. */ +#define CYGWIN_SIGNAL_STRING "cygwin: signal" + +#define CHECK(x) check (x, __FILE__,__LINE__) +#define DEBUG_EXEC(x) if (debug_exec) printf x +#define DEBUG_EVENTS(x) if (debug_events) printf x +#define DEBUG_MEM(x) if (debug_memory) printf x +#define DEBUG_EXCEPT(x) if (debug_exceptions) printf x + +static int connection_initialized = 0; /* True if we've initialized a RAPI session. */ + +/* The directory where the stub and executable files are uploaded. */ +static const char *remote_directory = "\\gdb"; + +/* The types automatic upload available. */ +static enum + { + UPLOAD_ALWAYS = 0, + UPLOAD_NEWER = 1, + UPLOAD_NEVER = 2 + } +upload_when = UPLOAD_NEWER; + +/* Valid options for 'set remoteupload'. Note that options + must track upload_when enum. */ +static struct opts + { + const char *name; + int abbrev; + } +upload_options[3] = +{ + { + "always", 1 + } + , + { + "newer", 3 + } + , + { + "never", 3 + } +}; + +static char *remote_upload = NULL; /* Set by set remoteupload */ +static int remote_add_host = 0; + +/* Forward declaration */ +extern struct target_ops child_ops; + +static int win32_child_thread_alive (ptid_t); +void child_kill_inferior (void); + +static int last_sig = 0; /* Set if a signal was received from the + debugged process */ + +/* Thread information structure used to track information that is + not available in gdb's thread structure. */ +typedef struct thread_info_struct + { + struct thread_info_struct *next; + DWORD id; + HANDLE h; + char *name; + int suspend_count; + int stepped; /* True if stepped. */ + CORE_ADDR step_pc; + unsigned long step_prev; + CONTEXT context; + } +thread_info; + +static thread_info thread_head = +{NULL}; +static thread_info * thread_rec (DWORD id, int get_context); + +/* The process and thread handles for the above context. */ + +static DEBUG_EVENT current_event; /* The current debug event from + WaitForDebugEvent */ +static HANDLE current_process_handle; /* Currently executing process */ +static thread_info *current_thread; /* Info on currently selected thread */ +static thread_info *this_thread; /* Info on thread returned by wait_for_debug_event */ +static DWORD main_thread_id; /* Thread ID of the main thread */ + +/* Counts of things. */ +static int exception_count = 0; +static int event_count = 0; + +/* User options. */ +static int debug_exec = 0; /* show execution */ +static int debug_events = 0; /* show events from kernel */ +static int debug_memory = 0; /* show target memory accesses */ +static int debug_exceptions = 0; /* show target exceptions */ + +/* An array of offset mappings into a Win32 Context structure. + This is a one-to-one mapping which is indexed by gdb's register + numbers. It retrieves an offset into the context structure where + the 4 byte register is located. + An offset value of -1 indicates that Win32 does not provide this + register in it's CONTEXT structure. regptr will return zero for this + register. + + This is used by the regptr function. */ +#define context_offset(x) ((int)&(((PCONTEXT)NULL)->x)) +static const int mappings[NUM_REGS + 1] = +{ +#ifdef __i386__ + context_offset (Eax), + context_offset (Ecx), + context_offset (Edx), + context_offset (Ebx), + context_offset (Esp), + context_offset (Ebp), + context_offset (Esi), + context_offset (Edi), + context_offset (Eip), + context_offset (EFlags), + context_offset (SegCs), + context_offset (SegSs), + context_offset (SegDs), + context_offset (SegEs), + context_offset (SegFs), + context_offset (SegGs), + context_offset (FloatSave.RegisterArea[0 * 10]), + context_offset (FloatSave.RegisterArea[1 * 10]), + context_offset (FloatSave.RegisterArea[2 * 10]), + context_offset (FloatSave.RegisterArea[3 * 10]), + context_offset (FloatSave.RegisterArea[4 * 10]), + context_offset (FloatSave.RegisterArea[5 * 10]), + context_offset (FloatSave.RegisterArea[6 * 10]), + context_offset (FloatSave.RegisterArea[7 * 10]), +#elif defined(SHx) + context_offset (R0), + context_offset (R1), + context_offset (R2), + context_offset (R3), + context_offset (R4), + context_offset (R5), + context_offset (R6), + context_offset (R7), + context_offset (R8), + context_offset (R9), + context_offset (R10), + context_offset (R11), + context_offset (R12), + context_offset (R13), + context_offset (R14), + context_offset (R15), + context_offset (Fir), + context_offset (PR), /* Procedure Register */ + context_offset (GBR), /* Global Base Register */ + context_offset (MACH), /* Accumulate */ + context_offset (MACL), /* Multiply */ + context_offset (Psr), + context_offset (Fpul), + context_offset (Fpscr), + context_offset (FRegs[0]), + context_offset (FRegs[1]), + context_offset (FRegs[2]), + context_offset (FRegs[3]), + context_offset (FRegs[4]), + context_offset (FRegs[5]), + context_offset (FRegs[6]), + context_offset (FRegs[7]), + context_offset (FRegs[8]), + context_offset (FRegs[9]), + context_offset (FRegs[10]), + context_offset (FRegs[11]), + context_offset (FRegs[12]), + context_offset (FRegs[13]), + context_offset (FRegs[14]), + context_offset (FRegs[15]), + context_offset (xFRegs[0]), + context_offset (xFRegs[1]), + context_offset (xFRegs[2]), + context_offset (xFRegs[3]), + context_offset (xFRegs[4]), + context_offset (xFRegs[5]), + context_offset (xFRegs[6]), + context_offset (xFRegs[7]), + context_offset (xFRegs[8]), + context_offset (xFRegs[9]), + context_offset (xFRegs[10]), + context_offset (xFRegs[11]), + context_offset (xFRegs[12]), + context_offset (xFRegs[13]), + context_offset (xFRegs[14]), + context_offset (xFRegs[15]), +#elif defined(MIPS) + context_offset (IntZero), + context_offset (IntAt), + context_offset (IntV0), + context_offset (IntV1), + context_offset (IntA0), + context_offset (IntA1), + context_offset (IntA2), + context_offset (IntA3), + context_offset (IntT0), + context_offset (IntT1), + context_offset (IntT2), + context_offset (IntT3), + context_offset (IntT4), + context_offset (IntT5), + context_offset (IntT6), + context_offset (IntT7), + context_offset (IntS0), + context_offset (IntS1), + context_offset (IntS2), + context_offset (IntS3), + context_offset (IntS4), + context_offset (IntS5), + context_offset (IntS6), + context_offset (IntS7), + context_offset (IntT8), + context_offset (IntT9), + context_offset (IntK0), + context_offset (IntK1), + context_offset (IntGp), + context_offset (IntSp), + context_offset (IntS8), + context_offset (IntRa), + context_offset (Psr), + context_offset (IntLo), + context_offset (IntHi), + -1, /* bad */ + -1, /* cause */ + context_offset (Fir), + context_offset (FltF0), + context_offset (FltF1), + context_offset (FltF2), + context_offset (FltF3), + context_offset (FltF4), + context_offset (FltF5), + context_offset (FltF6), + context_offset (FltF7), + context_offset (FltF8), + context_offset (FltF9), + context_offset (FltF10), + context_offset (FltF11), + context_offset (FltF12), + context_offset (FltF13), + context_offset (FltF14), + context_offset (FltF15), + context_offset (FltF16), + context_offset (FltF17), + context_offset (FltF18), + context_offset (FltF19), + context_offset (FltF20), + context_offset (FltF21), + context_offset (FltF22), + context_offset (FltF23), + context_offset (FltF24), + context_offset (FltF25), + context_offset (FltF26), + context_offset (FltF27), + context_offset (FltF28), + context_offset (FltF29), + context_offset (FltF30), + context_offset (FltF31), + context_offset (Fsr), + context_offset (Fir), + -1, /* fp */ +#elif defined(ARM) + context_offset (R0), + context_offset (R1), + context_offset (R2), + context_offset (R3), + context_offset (R4), + context_offset (R5), + context_offset (R6), + context_offset (R7), + context_offset (R8), + context_offset (R9), + context_offset (R10), + context_offset (R11), + context_offset (R12), + context_offset (Sp), + context_offset (Lr), + context_offset (Pc), + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + context_offset (Psr), +#endif + -1 +}; + +/* Return a pointer into a CONTEXT field indexed by gdb register number. + Return a pointer to an address pointing to zero if there is no + corresponding CONTEXT field for the given register number. + */ +static ULONG * +regptr (LPCONTEXT c, int r) +{ + static ULONG zero = 0; + ULONG *p; + if (mappings[r] < 0) + p = &zero; + else + p = (ULONG *) (((char *) c) + mappings[r]); + return p; +} + +/******************** Beginning of stub interface ********************/ + +/* Stub interface description: + + The Windows CE stub implements a crude RPC. The hand-held device + connects to gdb using port 7000. gdb and the stub then communicate + using packets where: + + byte 0: command id (e.g. Create Process) + + byte 1-4: DWORD + + byte 1-2: WORD + + byte 1-2: length + byte 3-n: arbitrary memory. + + The interface is deterministic, i.e., if the stub expects a DWORD then + the gdb server should send a DWORD. + */ + +/* Note: In the functions below, the `huh' parameter is a string passed from the + function containing a descriptive string concerning the current operation. + This is used for error reporting. + + The 'what' parameter is a command id as found in wince-stub.h. + + Hopefully, the rest of the parameters are self-explanatory. + */ + +static int s; /* communication socket */ + +/* v-style interface for handling varying argyment list error messages. + Displays the error message in a dialog box and exits when user clicks + on OK. */ +static void +vstub_error (LPCSTR fmt, va_list * args) +{ + char buf[4096]; + vsprintf (buf, fmt, args); + s = -1; + error ("%s", buf); +} + +/* The standard way to display an error message and exit. */ +static void +stub_error (LPCSTR fmt,...) +{ + va_list args; + va_start (args, fmt); + vstub_error (fmt, args); +} + +/* Standard "oh well" can't communicate error. Someday this might attempt + synchronization. */ +static void +attempt_resync (LPCSTR huh, int s) +{ + stub_error ("lost synchronization with target attempting %s", huh); +} + +/* Read arbitrary stuff from a socket. */ +static int +sockread (LPCSTR huh, int s, void *str, size_t n) +{ + for (;;) + { + if (recv (s, str, n, 0) == n) + return n; + attempt_resync (huh, s); + } +} + +/* Write arbitrary stuff to a socket. */ +static int +sockwrite (LPCSTR huh, const void *str, size_t n) +{ + for (;;) + { + if (send (s, str, n, 0) == n) + return n; + attempt_resync (huh, s); + } +} + +/* Output an id/dword to the host */ +static void +putdword (LPCSTR huh, gdb_wince_id what, DWORD n) +{ + if (sockwrite (huh, &what, sizeof (what)) != sizeof (what)) + stub_error ("error writing record id to host for %s", huh); + if (sockwrite (huh, &n, sizeof (n)) != sizeof (n)) + stub_error ("error writing %s to host.", huh); +} + +/* Output an id/word to the host */ +static void +putword (LPCSTR huh, gdb_wince_id what, WORD n) +{ + if (sockwrite (huh, &what, sizeof (what)) != sizeof (what)) + stub_error ("error writing record id to host for %s", huh); + if (sockwrite (huh, &n, sizeof (n)) != sizeof (n)) + stub_error ("error writing %s host.", huh); +} + +/* Convenience define for outputting a "gdb_wince_len" type. */ +#define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n)) + +/* Put an arbitrary block of memory to the gdb host. This comes in + two chunks an id/dword representing the length and the stream of memory + itself. */ +static void +putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len) +{ + putlen (huh, what, len); + if (((short) len > 0) && sockwrite (huh, mem, len) != len) + stub_error ("error writing %s to host.", huh); +} + +/* Output the result of an operation to the host. If res != 0, sends a block of + memory starting at mem of len bytes. If res == 0, sends -GetLastError () and + avoids sending the mem. */ +static DWORD +getdword (LPCSTR huh, gdb_wince_id what_this) +{ + DWORD n; + gdb_wince_id what; + do + if (sockread (huh, s, &what, sizeof (what)) != sizeof (what)) + stub_error ("error getting record type from host - %s.", huh); + while (what_this != what); + + if (sockread (huh, s, &n, sizeof (n)) != sizeof (n)) + stub_error ("error getting %s from host.", huh); + + return n; +} + +/* Get a an ID (possibly) and a WORD from the host gdb. + Don't bother with the id if the main loop has already + read it. */ +static WORD +getword (LPCSTR huh, gdb_wince_id what_this) +{ + WORD n; + gdb_wince_id what; + do + if (sockread (huh, s, &what, sizeof (what)) != sizeof (what)) + stub_error ("error getting record type from host - %s.", huh); + while (what_this != what); + + if (sockread (huh, s, &n, sizeof (n)) != sizeof (n)) + stub_error ("error getting %s from host.", huh); + + return n; +} + +/* Handy defines for getting/putting various types of values. */ +#define gethandle(huh, what) (HANDLE) getdword ((huh), (what)) +#define getpvoid(huh, what) (LPVOID) getdword ((huh), (what)) +#define getlen(huh, what) (gdb_wince_len) getword ((huh), (what)) +#define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h)) +#define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p)) + +/* Retrieve the result of an operation from the stub. If nbytes < 0) then nbytes + is actually an error and nothing else follows. Use SetLastError to remember this. + if nbytes > 0, retrieve a block of *nbytes into buf. + */ +int +getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes) +{ + gdb_wince_len dummy; + if (nbytes == NULL) + nbytes = &dummy; + + *nbytes = getlen (huh, what); + + if ((short) *nbytes < 0) + { + SetLastError (-(short) *nbytes); + return 0; + } + + if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes) + stub_error ("couldn't read information from wince stub - %s", huh); + + return 1; +} + +/* Convert "narrow" string to "wide". Manipulates a buffer ring of 8 + buffers which hold the translated string. This is an arbitrary limit + but it is approximately double the current needs of this module. + */ +LPWSTR +towide (const char *s, gdb_wince_len * out_len) +{ + static int n = -1; + static LPWSTR outs[8] = + {NULL /*, NULL, etc. */ }; + gdb_wince_len dummy; + + if (!out_len) + out_len = &dummy; + + /* First determine the length required to hold the converted string. */ + *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0); + if (!*out_len) + return NULL; /* The conversion failed */ + + if (++n >= (sizeof (outs) / sizeof (outs[0]))) + n = 0; /* wrap */ + + /* Allocate space for the converted string, reusing any previously allocated + space, if applicable. Note that if outs[n] is NULL, xrealloc will act as + a malloc (under cygwin, at least). + */ + outs[n] = (LPWSTR) xrealloc (outs[n], *out_len); + memset (outs[n], 0, *out_len); + (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len); + return outs[n]; +} + +/******************** Emulation routines start here. ******************** + + The functions below are modelled after their Win32 counterparts. They are named + similarly to Win32 and take exactly the same arguments except where otherwise noted. + They communicate with the stub on the hand-held device by sending their arguments + over the socket and waiting for results from the socket. + + There is one universal change. In cases where a length is expected to be returned + in a DWORD, we use a gdb_wince_len type instead. Currently this is an unsigned short + which is smaller than the standard Win32 DWORD. This is done to minimize unnecessary + traffic since the connection to Windows CE can be slow. To change this, modify the + typedef in wince-stub.h and change the putlen/getlen macros in this file and in + the stub. +*/ + +static int +create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi) +{ + gdb_wince_len len; + LPWSTR buf; + + buf = towide (exec_file, &len); + putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len); + buf = towide (args, &len); + putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len); + putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags); + return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL); +} + +/* Emulate TerminateProcess. Don't bother with the second argument since CE + ignores it. + */ +static int +terminate_process (HANDLE h) +{ + gdb_wince_result res; + if (s < 0) + return 1; + puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h); + return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL); +} + +static int +wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms) +{ + if (s < 0) + return 1; + putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms); + return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL); +} + +static int +get_thread_context (HANDLE h, CONTEXT * c) +{ + if (s < 0) + return 1; + puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h); + putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags); + return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL); +} + +static int +set_thread_context (HANDLE h, CONTEXT * c) +{ + gdb_wince_result res; + if (s < 0) + return 1; + puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h); + putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c)); + return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL); +} + +static int +read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes) +{ + if (s < 0) + return 1; + puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h); + putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where); + putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len); + + return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes); +} + +static int +write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes) +{ + if (s < 0) + return 1; + puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h); + putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where); + putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len); + + return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL); +} + +static int +remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) +{ + gdb_wince_len nbytes; + if (!read_process_memory (current_process_handle, (LPCVOID) memaddr, + (LPVOID) myaddr, len, &nbytes)) + return -1; + return nbytes; +} + +static int +remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) +{ + gdb_wince_len nbytes; + if (!write_process_memory (current_process_handle, (LPCVOID) memaddr, + (LPCVOID) myaddr, len, &nbytes)) + return -1; + return nbytes; +} + +/* This is not a standard Win32 function. It instructs the stub to return TRUE + if the thread referenced by HANDLE h is alive. + */ +static int +thread_alive (HANDLE h) +{ + gdb_wince_result res; + if (s < 0) + return 1; + puthandle ("ThreadAlive handle", GDB_THREADALIVE, h); + return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL); +} + +static int +suspend_thread (HANDLE h) +{ + if (s < 0) + return 1; + puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h); + return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD); +} + +static int +resume_thread (HANDLE h) +{ + if (s < 0) + return 1; + puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h); + return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD); +} + +static int +continue_debug_event (DWORD pid, DWORD tid, DWORD status) +{ + gdb_wince_result res; + if (s < 0) + return 0; + putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid); + putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid); + putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status); + return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL); +} + +static int +close_handle (HANDLE h) +{ + gdb_wince_result res; + if (s < 0) + return 1; + puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h); + return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL); +} + +/* This is not a standard Win32 interface. This function tells the stub + to terminate. + */ +static void +stop_stub (void) +{ + if (s < 0) + return; + (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0); + s = -1; +} + +/******************** End of emulation routines. ********************/ +/******************** End of stub interface ********************/ + +#define check_for_step(a, x) (x) + +#ifdef MIPS +static void +undoSStep (thread_info * th) +{ + if (th->stepped) + { + memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev); + th->stepped = 0; + } +} + +void +wince_software_single_step (enum target_signal ignore, + int insert_breakpoints_p) +{ + unsigned long pc; + thread_info *th = current_thread; /* Info on currently selected thread */ + CORE_ADDR mips_next_pc (CORE_ADDR pc); + + if (!insert_breakpoints_p) + { + undoSStep (th); + return; + } + + th->stepped = 1; + pc = read_register (PC_REGNUM); + th->step_pc = mips_next_pc (pc); + th->step_prev = 0; + memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev); + return; +} +#elif SHx +/* Renesas SH architecture instruction encoding masks */ + +#define COND_BR_MASK 0xff00 +#define UCOND_DBR_MASK 0xe000 +#define UCOND_RBR_MASK 0xf0df +#define TRAPA_MASK 0xff00 + +#define COND_DISP 0x00ff +#define UCOND_DISP 0x0fff +#define UCOND_REG 0x0f00 + +/* Renesas SH instruction opcodes */ + +#define BF_INSTR 0x8b00 +#define BT_INSTR 0x8900 +#define BRA_INSTR 0xa000 +#define BSR_INSTR 0xb000 +#define JMP_INSTR 0x402b +#define JSR_INSTR 0x400b +#define RTS_INSTR 0x000b +#define RTE_INSTR 0x002b +#define TRAPA_INSTR 0xc300 +#define SSTEP_INSTR 0xc3ff + + +#define T_BIT_MASK 0x0001 + +static CORE_ADDR +sh_get_next_pc (CONTEXT *c) +{ + short *instrMem; + int displacement; + int reg; + unsigned short opcode; + + instrMem = (short *) c->Fir; + + opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode)); + + if ((opcode & COND_BR_MASK) == BT_INSTR) + { + if (c->Psr & T_BIT_MASK) + { + displacement = (opcode & COND_DISP) << 1; + if (displacement & 0x80) + displacement |= 0xffffff00; + /* + * Remember PC points to second instr. + * after PC of branch ... so add 4 + */ + instrMem = (short *) (c->Fir + displacement + 4); + } + else + instrMem += 1; + } + else if ((opcode & COND_BR_MASK) == BF_INSTR) + { + if (c->Psr & T_BIT_MASK) + instrMem += 1; + else + { + displacement = (opcode & COND_DISP) << 1; + if (displacement & 0x80) + displacement |= 0xffffff00; + /* + * Remember PC points to second instr. + * after PC of branch ... so add 4 + */ + instrMem = (short *) (c->Fir + displacement + 4); + } + } + else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR) + { + displacement = (opcode & UCOND_DISP) << 1; + if (displacement & 0x0800) + displacement |= 0xfffff000; + + /* + * Remember PC points to second instr. + * after PC of branch ... so add 4 + */ + instrMem = (short *) (c->Fir + displacement + 4); + } + else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR) + { + reg = (char) ((opcode & UCOND_REG) >> 8); + + instrMem = (short *) *regptr (c, reg); + } + else if (opcode == RTS_INSTR) + instrMem = (short *) c->PR; + else if (opcode == RTE_INSTR) + instrMem = (short *) *regptr (c, 15); + else if ((opcode & TRAPA_MASK) == TRAPA_INSTR) + instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2); + else + instrMem += 1; + + return (CORE_ADDR) instrMem; +} +/* Single step (in a painstaking fashion) by inspecting the current + instruction and setting a breakpoint on the "next" instruction + which would be executed. This code hails from sh-stub.c. + */ +static void +undoSStep (thread_info * th) +{ + if (th->stepped) + { + memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev); + th->stepped = 0; + } + return; +} + +/* Single step (in a painstaking fashion) by inspecting the current + instruction and setting a breakpoint on the "next" instruction + which would be executed. This code hails from sh-stub.c. + */ +void +wince_software_single_step (enum target_signal ignore, + int insert_breakpoints_p) +{ + thread_info *th = current_thread; /* Info on currently selected thread */ + + if (!insert_breakpoints_p) + { + undoSStep (th); + return; + } + + th->stepped = 1; + th->step_pc = sh_get_next_pc (&th->context); + th->step_prev = 0; + memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev); + return; +} +#elif defined (ARM) +#undef check_for_step + +static enum target_signal +check_for_step (DEBUG_EVENT *ev, enum target_signal x) +{ + thread_info *th = thread_rec (ev->dwThreadId, 1); + + if (th->stepped && + th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress) + return TARGET_SIGNAL_TRAP; + else + return x; +} + +/* Single step (in a painstaking fashion) by inspecting the current + instruction and setting a breakpoint on the "next" instruction + which would be executed. This code hails from sh-stub.c. + */ +static void +undoSStep (thread_info * th) +{ + if (th->stepped) + { + memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev); + th->stepped = 0; + } +} + +void +wince_software_single_step (enum target_signal ignore, + int insert_breakpoints_p) +{ + unsigned long pc; + thread_info *th = current_thread; /* Info on currently selected thread */ + CORE_ADDR mips_next_pc (CORE_ADDR pc); + + if (!insert_breakpoints_p) + { + undoSStep (th); + return; + } + + th->stepped = 1; + pc = read_register (PC_REGNUM); + th->step_pc = arm_get_next_pc (pc); + th->step_prev = 0; + memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev); + return; +} +#endif + +/* Find a thread record given a thread id. + If get_context then also retrieve the context for this + thread. */ +static thread_info * +thread_rec (DWORD id, int get_context) +{ + thread_info *th; + + for (th = &thread_head; (th = th->next) != NULL;) + if (th->id == id) + { + if (!th->suspend_count && get_context) + { + if (get_context > 0 && th != this_thread) + th->suspend_count = suspend_thread (th->h) + 1; + else if (get_context < 0) + th->suspend_count = -1; + + th->context.ContextFlags = CONTEXT_DEBUGGER; + get_thread_context (th->h, &th->context); + } + return th; + } + + return NULL; +} + +/* Add a thread to the thread list */ +static thread_info * +child_add_thread (DWORD id, HANDLE h) +{ + thread_info *th; + + if ((th = thread_rec (id, FALSE))) + return th; + + th = (thread_info *) xmalloc (sizeof (*th)); + memset (th, 0, sizeof (*th)); + th->id = id; + th->h = h; + th->next = thread_head.next; + thread_head.next = th; + add_thread (id); + return th; +} + +/* Clear out any old thread list and reintialize it to a + pristine state. */ +static void +child_init_thread_list (void) +{ + thread_info *th = &thread_head; + + DEBUG_EVENTS (("gdb: child_init_thread_list\n")); + init_thread_list (); + while (th->next != NULL) + { + thread_info *here = th->next; + th->next = here->next; + (void) close_handle (here->h); + xfree (here); + } +} + +/* Delete a thread from the list of threads */ +static void +child_delete_thread (DWORD id) +{ + thread_info *th; + + if (info_verbose) + printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id)); + delete_thread (id); + + for (th = &thread_head; + th->next != NULL && th->next->id != id; + th = th->next) + continue; + + if (th->next != NULL) + { + thread_info *here = th->next; + th->next = here->next; + close_handle (here->h); + xfree (here); + } +} + +static void +check (BOOL ok, const char *file, int line) +{ + if (!ok) + printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ()); +} + +static void +do_child_fetch_inferior_registers (int r) +{ + if (r >= 0) + { + supply_register (r, (char *) regptr (¤t_thread->context, r)); + } + else + { + for (r = 0; r < NUM_REGS; r++) + do_child_fetch_inferior_registers (r); + } +} + +static void +child_fetch_inferior_registers (int r) +{ + current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); + do_child_fetch_inferior_registers (r); +} + +static void +do_child_store_inferior_registers (int r) +{ + if (r >= 0) + deprecated_read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]); + else + { + for (r = 0; r < NUM_REGS; r++) + do_child_store_inferior_registers (r); + } +} + +/* Store a new register value into the current thread context */ +static void +child_store_inferior_registers (int r) +{ + current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); + do_child_store_inferior_registers (r); +} + +/* Wait for child to do something. Return pid of child, or -1 in case + of error; store status through argument pointer OURSTATUS. */ + +static int +handle_load_dll (void *dummy) +{ + LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; + char dll_buf[MAX_PATH + 1]; + char *p, *bufp, *imgp, *dll_name, *dll_basename; + int len; + + dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; + if (!event->lpImageName) + return 1; + + len = 0; + for (bufp = dll_buf, imgp = event->lpImageName; + bufp < dll_buf + sizeof (dll_buf); + bufp += 16, imgp += 16) + { + gdb_wince_len nbytes = 0; + (void) read_process_memory (current_process_handle, + imgp, bufp, 16, &nbytes); + + if (!nbytes && bufp == dll_buf) + return 1; /* couldn't read it */ + for (p = bufp; p < bufp + nbytes; p++) + { + len++; + if (*p == '\0') + goto out; + if (event->fUnicode) + p++; + } + if (!nbytes) + break; + } + +out: + if (!len) + return 1; +#if 0 + dll_buf[len] = '\0'; +#endif + dll_name = alloca (len); + + if (!dll_name) + return 1; + + if (!event->fUnicode) + memcpy (dll_name, dll_buf, len); + else + WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len, + dll_name, len, 0, 0); + + while ((p = strchr (dll_name, '\\'))) + *p = '/'; + + /* FIXME!! It would be nice to define one symbol which pointed to the + front of the dll if we can't find any symbols. */ + + if (!(dll_basename = strrchr (dll_name, '/'))) + dll_basename = dll_name; + else + dll_basename++; + + /* The symbols in a dll are offset by 0x1000, which is the + the offset from 0 of the first byte in an image - because + of the file header and the section alignment. + + FIXME: Is this the real reason that we need the 0x1000 ? */ + + printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name); + printf_unfiltered ("\n"); + + return 1; +} + +/* Handle DEBUG_STRING output from child process. */ +static void +handle_output_debug_string (struct target_waitstatus *ourstatus) +{ + char p[256]; + char s[255]; + char *q; + gdb_wince_len nbytes_read; + gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength; + + if (nbytes > 255) + nbytes = 255; + + memset (p, 0, sizeof (p)); + if (!read_process_memory (current_process_handle, + current_event.u.DebugString.lpDebugStringData, + &p, nbytes, &nbytes_read) + || !*p) + return; + + memset (s, 0, sizeof (s)); + WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) p, (int) nbytes_read, s, + sizeof (s) - 1, NULL, NULL); + q = strchr (s, '\n'); + if (q != NULL) + { + *q = '\0'; + if (*--q = '\r') + *q = '\0'; + } + + warning (s); + + return; +} + +/* Handle target exceptions. */ +static int +handle_exception (struct target_waitstatus *ourstatus) +{ +#if 0 + if (current_event.u.Exception.dwFirstChance) + return 0; +#endif + + ourstatus->kind = TARGET_WAITKIND_STOPPED; + + switch (current_event.u.Exception.ExceptionRecord.ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n", + (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress)); + ourstatus->value.sig = TARGET_SIGNAL_SEGV; + break; + case STATUS_STACK_OVERFLOW: + DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n", + (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress)); + ourstatus->value.sig = TARGET_SIGNAL_SEGV; + break; + case EXCEPTION_BREAKPOINT: + DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n", + (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress)); + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + break; + case DBG_CONTROL_C: + DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n", + (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress)); + ourstatus->value.sig = TARGET_SIGNAL_INT; + /* User typed CTRL-C. Continue with this status */ + last_sig = SIGINT; /* FIXME - should check pass state */ + break; + case EXCEPTION_SINGLE_STEP: + DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n", + (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress)); + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n", + current_event.u.Exception.ExceptionRecord.ExceptionAddress)); + ourstatus->value.sig = check_for_step (¤t_event, TARGET_SIGNAL_ILL); + break; + default: + /* This may be a structured exception handling exception. In + that case, we want to let the program try to handle it, and + only break if we see the exception a second time. */ + + printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n", + current_event.u.Exception.ExceptionRecord.ExceptionCode, + current_event.u.Exception.ExceptionRecord.ExceptionAddress); + ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; + break; + } + exception_count++; + return 1; +} + +/* Resume all artificially suspended threads if we are continuing + execution */ +static BOOL +child_continue (DWORD continue_status, int id) +{ + int i; + thread_info *th; + BOOL res; + + DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n", + (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId)); + res = continue_debug_event (current_event.dwProcessId, + current_event.dwThreadId, + continue_status); + if (res) + for (th = &thread_head; (th = th->next) != NULL;) + if (((id == -1) || (id == th->id)) && th->suspend_count) + { + for (i = 0; i < th->suspend_count; i++) + (void) resume_thread (th->h); + th->suspend_count = 0; + } + + return res; +} + +/* Get the next event from the child. Return 1 if the event requires + handling by WFI (or whatever). + */ +static int +get_child_debug_event (int pid, struct target_waitstatus *ourstatus, + DWORD target_event_code, int *retval) +{ + int breakout = 0; + BOOL debug_event; + DWORD continue_status, event_code; + thread_info *th = NULL; + static thread_info dummy_thread_info; + + if (!(debug_event = wait_for_debug_event (¤t_event, 1000))) + { + *retval = 0; + goto out; + } + + event_count++; + continue_status = DBG_CONTINUE; + *retval = 0; + + event_code = current_event.dwDebugEventCode; + breakout = event_code == target_event_code; + + switch (event_code) + { + case CREATE_THREAD_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "CREATE_THREAD_DEBUG_EVENT")); + /* Record the existence of this thread */ + th = child_add_thread (current_event.dwThreadId, + current_event.u.CreateThread.hThread); + if (info_verbose) + printf_unfiltered ("[New %s]\n", + target_pid_to_str (current_event.dwThreadId)); + break; + + case EXIT_THREAD_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "EXIT_THREAD_DEBUG_EVENT")); + child_delete_thread (current_event.dwThreadId); + th = &dummy_thread_info; + break; + + case CREATE_PROCESS_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "CREATE_PROCESS_DEBUG_EVENT")); + current_process_handle = current_event.u.CreateProcessInfo.hProcess; + + main_thread_id = current_event.dwThreadId; + inferior_ptid = pid_to_ptid (main_thread_id); + /* Add the main thread */ + th = child_add_thread (PIDGET (inferior_ptid), + current_event.u.CreateProcessInfo.hThread); + break; + + case EXIT_PROCESS_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "EXIT_PROCESS_DEBUG_EVENT")); + ourstatus->kind = TARGET_WAITKIND_EXITED; + ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; + close_handle (current_process_handle); + *retval = current_event.dwProcessId; + breakout = 1; + break; + + case LOAD_DLL_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "LOAD_DLL_DEBUG_EVENT")); + catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL); + registers_changed (); /* mark all regs invalid */ + break; + + case UNLOAD_DLL_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "UNLOAD_DLL_DEBUG_EVENT")); + break; /* FIXME: don't know what to do here */ + + case EXCEPTION_DEBUG_EVENT: + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "EXCEPTION_DEBUG_EVENT")); + if (handle_exception (ourstatus)) + *retval = current_event.dwThreadId; + else + { + continue_status = DBG_EXCEPTION_NOT_HANDLED; + breakout = 0; + } + break; + + case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */ + DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + "OUTPUT_DEBUG_STRING_EVENT")); + handle_output_debug_string ( ourstatus); + break; + default: + printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n", + current_event.dwProcessId, + current_event.dwThreadId); + printf_unfiltered (" unknown event code %d\n", + current_event.dwDebugEventCode); + break; + } + + if (breakout) + this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE); + else + CHECK (child_continue (continue_status, -1)); + +out: + return breakout; +} + +/* Wait for interesting events to occur in the target process. */ +static ptid_t +child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +{ + DWORD event_code; + int retval; + int pid = PIDGET (ptid); + + /* We loop when we get a non-standard exception rather than return + with a SPURIOUS because resume can try and step or modify things, + which needs a current_thread->h. But some of these exceptions mark + the birth or death of threads, which mean that the current thread + isn't necessarily what you think it is. */ + + while (1) + if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval)) + return pid_to_ptid (retval); + else + { + int detach = 0; + + if (ui_loop_hook != NULL) + detach = ui_loop_hook (0); + + if (detach) + child_kill_inferior (); + } +} + +/* Print status information about what we're accessing. */ + +static void +child_files_info (struct target_ops *ignore) +{ + printf_unfiltered ("\tUsing the running image of child %s.\n", + target_pid_to_str (inferior_ptid)); +} + +static void +child_open (char *arg, int from_tty) +{ + error ("Use the \"run\" command to start a child process."); +} + +#define FACTOR (0x19db1ded53ea710LL) +#define NSPERSEC 10000000 + +/* Convert a Win32 time to "UNIX" format. */ +long +to_time_t (FILETIME * ptr) +{ + /* A file time is the number of 100ns since jan 1 1601 + stuffed into two long words. + A time_t is the number of seconds since jan 1 1970. */ + + long rem; + long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime); + x -= FACTOR; /* number of 100ns between 1601 and 1970 */ + rem = x % ((long long) NSPERSEC); + rem += (NSPERSEC / 2); + x /= (long long) NSPERSEC; /* number of 100ns in a second */ + x += (long long) (rem / NSPERSEC); + return x; +} + +/* Upload a file to the remote device depending on the user's + 'set remoteupload' specification. */ +char * +upload_to_device (const char *to, const char *from) +{ + HANDLE h; + const char *dir = remote_directory ?: "\\gdb"; + int len; + static char *remotefile = NULL; + LPWSTR wstr; + char *p; + DWORD err; + const char *in_to = to; + FILETIME crtime, actime, wrtime; + time_t utime; + struct stat st; + int fd; + + /* Look for a path separator and only use trailing part. */ + while ((p = strpbrk (to, "/\\")) != NULL) + to = p + 1; + + if (!*to) + error ("no filename found to upload - %s.", in_to); + + len = strlen (dir) + strlen (to) + 2; + remotefile = (char *) xrealloc (remotefile, len); + strcpy (remotefile, dir); + strcat (remotefile, "\\"); + strcat (remotefile, to); + + if (upload_when == UPLOAD_NEVER) + return remotefile; /* Don't bother uploading. */ + + /* Open the source. */ + if ((fd = openp (getenv ("PATH"), TRUE, (char *) from, O_RDONLY, 0, NULL)) < 0) + error ("couldn't open %s", from); + + /* Get the time for later comparison. */ + if (fstat (fd, &st)) + st.st_mtime = (time_t) - 1; + + /* Always attempt to create the directory on the remote system. */ + wstr = towide (dir, NULL); + (void) CeCreateDirectory (wstr, NULL); + + /* Attempt to open the remote file, creating it if it doesn't exist. */ + wstr = towide (remotefile, NULL); + h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + /* Some kind of problem? */ + err = CeGetLastError (); + if (h == NULL || h == INVALID_HANDLE_VALUE) + error ("error opening file \"%s\". Windows error %d.", + remotefile, err); + + CeGetFileTime (h, &crtime, &actime, &wrtime); + utime = to_time_t (&wrtime); +#if 0 + if (utime < st.st_mtime) + { + char buf[80]; + strcpy (buf, ctime(&utime)); + printf ("%s < %s\n", buf, ctime(&st.st_mtime)); + } +#endif + /* See if we need to upload the file. */ + if (upload_when == UPLOAD_ALWAYS || + err != ERROR_ALREADY_EXISTS || + !CeGetFileTime (h, &crtime, &actime, &wrtime) || + to_time_t (&wrtime) < st.st_mtime) + { + DWORD nbytes; + char buf[4096]; + int n; + + /* Upload the file. */ + while ((n = read (fd, buf, sizeof (buf))) > 0) + if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL)) + error ("error writing to remote device - %d.", + CeGetLastError ()); + } + + close (fd); + if (!CeCloseHandle (h)) + error ("error closing remote file - %d.", CeGetLastError ()); + + return remotefile; +} + +/* Initialize the connection to the remote device. */ +static void +wince_initialize (void) +{ + int tmp; + char args[256]; + char *hostname; + struct sockaddr_in sin; + char *stub_file_name; + int s0; + PROCESS_INFORMATION pi; + + if (!connection_initialized) + switch (CeRapiInit ()) + { + case 0: + connection_initialized = 1; + break; + default: + CeRapiUninit (); + error ("Can't initialize connection to remote device.\n"); + break; + } + + /* Upload the stub to the handheld device. */ + stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB); + strcpy (args, stub_file_name); + + if (remote_add_host) + { + strcat (args, " "); + hostname = strchr (args, '\0'); + if (gethostname (hostname, sizeof (args) - strlen (args))) + error ("couldn't get hostname of this system."); + } + + /* Get a socket. */ + if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0) + stub_error ("Couldn't connect to host system."); + + /* Allow rapid reuse of the port. */ + tmp = 1; + (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp)); + + + /* Set up the information for connecting to the host gdb process. */ + memset (&sin, 0, sizeof (sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons (7000); /* FIXME: This should be configurable */ + + if (bind (s0, (struct sockaddr *) &sin, sizeof (sin))) + error ("couldn't bind socket"); + + if (listen (s0, 1)) + error ("Couldn't open socket for listening.\n"); + + /* Start up the stub on the remote device. */ + if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL), + NULL, NULL, 0, 0, NULL, NULL, NULL, &pi)) + error ("Unable to start remote stub '%s'. Windows CE error %d.", + stub_file_name, CeGetLastError ()); + + /* Wait for a connection */ + + if ((s = accept (s0, NULL, NULL)) < 0) + error ("couldn't set up server for connection."); + + close (s0); +} + +/* Start an inferior win32 child process and sets inferior_ptid 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(). */ +static void +child_create_inferior (char *exec_file, char *args, char **env) +{ + PROCESS_INFORMATION pi; + struct target_waitstatus dummy; + int ret; + DWORD flags, event_code; + char *exec_and_args; + + if (!exec_file) + error ("No executable specified, use `target exec'.\n"); + + flags = DEBUG_PROCESS; + + wince_initialize (); /* Make sure we've got a connection. */ + + exec_file = upload_to_device (exec_file, exec_file); + + while (*args == ' ') + args++; + + /* Allocate space for "commandargs" */ + if (*args == '\0') + { + exec_and_args = alloca (strlen (exec_file) + 1); + strcpy (exec_and_args, exec_file); + } + else + { + exec_and_args = alloca (strlen (exec_file + strlen (args) + 2)); + sprintf (exec_and_args, "%s %s", exec_file, args); + } + + memset (&pi, 0, sizeof (pi)); + /* Execute the process */ + if (!create_process (exec_file, exec_and_args, flags, &pi)) + error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ()); + + exception_count = 0; + event_count = 0; + + current_process_handle = pi.hProcess; + current_event.dwProcessId = pi.dwProcessId; + memset (¤t_event, 0, sizeof (current_event)); + current_event.dwThreadId = pi.dwThreadId; + inferior_ptid = pid_to_ptid (current_event.dwThreadId); + push_target (&child_ops); + child_init_thread_list (); + child_add_thread (pi.dwThreadId, pi.hThread); + init_wait_for_inferior (); + clear_proceed_status (); + target_terminal_init (); + target_terminal_inferior (); + + /* Run until process and threads are loaded */ + while (!get_child_debug_event (PIDGET (inferior_ptid), &dummy, + CREATE_PROCESS_DEBUG_EVENT, &ret)) + continue; + + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0); +} + +/* Chile has gone bye-bye. */ +static void +child_mourn_inferior (void) +{ + (void) child_continue (DBG_CONTINUE, -1); + unpush_target (&child_ops); + stop_stub (); + CeRapiUninit (); + connection_initialized = 0; + generic_mourn_inferior (); +} + +/* Move memory from child to/from gdb. */ +int +child_xfer_memory (CORE_ADDR memaddr, char *our, int len, int write, + struct mem_attrib *attrib, + struct target_ops *target) +{ + if (len <= 0) + return 0; + + if (write) + res = remote_write_bytes (memaddr, our, len); + else + res = remote_read_bytes (memaddr, our, len); + + return res; +} + +/* Terminate the process and wait for child to tell us it has completed. */ +void +child_kill_inferior (void) +{ + CHECK (terminate_process (current_process_handle)); + + for (;;) + { + if (!child_continue (DBG_CONTINUE, -1)) + break; + if (!wait_for_debug_event (¤t_event, INFINITE)) + break; + if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) + break; + } + + CHECK (close_handle (current_process_handle)); + close_handle (current_thread->h); + target_mourn_inferior (); /* or just child_mourn_inferior? */ +} + +/* Resume the child after an exception. */ +void +child_resume (ptid_t ptid, int step, enum target_signal sig) +{ + thread_info *th; + DWORD continue_status = last_sig > 0 && last_sig < NSIG ? + DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE; + int pid = PIDGET (ptid); + + DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n", + pid, step, sig)); + + /* Get context for currently selected thread */ + th = thread_rec (current_event.dwThreadId, FALSE); + + if (th->context.ContextFlags) + { + CHECK (set_thread_context (th->h, &th->context)); + th->context.ContextFlags = 0; + } + + /* Allow continuing with the same signal that interrupted us. + Otherwise complain. */ + if (sig && sig != last_sig) + fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig); + + last_sig = 0; + child_continue (continue_status, pid); +} + +static void +child_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ +} + +static int +child_can_run (void) +{ + return 1; +} + +static void +child_close (void) +{ + DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n", + PIDGET (inferior_ptid))); +} + +/* Explicitly upload file to remotedir */ + +static void +child_load (char *file, int from_tty) +{ + upload_to_device (file, file); +} + +struct target_ops child_ops; + +static void +init_child_ops (void) +{ + memset (&child_ops, 0, sizeof (child_ops)); + child_ops.to_shortname = (char *) "child"; + child_ops.to_longname = (char *) "Windows CE process"; + child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command)."; + child_ops.to_open = child_open; + child_ops.to_close = child_close; + child_ops.to_resume = child_resume; + child_ops.to_wait = child_wait; + child_ops.to_fetch_registers = child_fetch_inferior_registers; + child_ops.to_store_registers = child_store_inferior_registers; + child_ops.to_prepare_to_store = child_prepare_to_store; + child_ops.to_xfer_memory = child_xfer_memory; + child_ops.to_files_info = child_files_info; + child_ops.to_insert_breakpoint = memory_insert_breakpoint; + child_ops.to_remove_breakpoint = memory_remove_breakpoint; + child_ops.to_terminal_init = terminal_init_inferior; + child_ops.to_terminal_inferior = terminal_inferior; + child_ops.to_terminal_ours_for_output = terminal_ours_for_output; + child_ops.to_terminal_ours = terminal_ours; + child_ops.to_terminal_save_ours = terminal_save_ours; + child_ops.to_terminal_info = child_terminal_info; + child_ops.to_kill = child_kill_inferior; + child_ops.to_load = child_load; + child_ops.to_create_inferior = child_create_inferior; + child_ops.to_mourn_inferior = child_mourn_inferior; + child_ops.to_can_run = child_can_run; + child_ops.to_thread_alive = win32_child_thread_alive; + child_ops.to_stratum = process_stratum; + child_ops.to_has_all_memory = 1; + child_ops.to_has_memory = 1; + child_ops.to_has_stack = 1; + child_ops.to_has_registers = 1; + child_ops.to_has_execution = 1; + child_ops.to_magic = OPS_MAGIC; +} + + +/* Handle 'set remoteupload' parameter. */ + +#define replace_upload(what) \ + upload_when = what; \ + remote_upload = xrealloc (remote_upload, strlen (upload_options[upload_when].name) + 1); \ + strcpy (remote_upload, upload_options[upload_when].name); + +static void +set_upload_type (char *ignore, int from_tty) +{ + int i, len; + char *bad_option; + + if (!remote_upload || !remote_upload[0]) + { + replace_upload (UPLOAD_NEWER); + if (from_tty) + printf_unfiltered ("Upload upload_options are: always, newer, never.\n"); + return; + } + + len = strlen (remote_upload); + for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++) + if (len >= upload_options[i].abbrev && + strncasecmp (remote_upload, upload_options[i].name, len) == 0) + { + replace_upload (i); + return; + } + + bad_option = remote_upload; + replace_upload (UPLOAD_NEWER); + error ("Unknown upload type: %s.", bad_option); +} + +void +_initialize_wince (void) +{ + struct cmd_list_element *set; + init_child_ops (); + + add_show_from_set + (add_set_cmd ((char *) "remotedirectory", no_class, + var_string_noescape, (char *) &remote_directory, + (char *) "Set directory for remote upload.\n", + &setlist), + &showlist); + remote_directory = xstrdup (remote_directory); + + set = add_set_cmd ((char *) "remoteupload", no_class, + var_string_noescape, (char *) &remote_upload, + (char *) "Set how to upload executables to remote device.\n", + &setlist); + add_show_from_set (set, &showlist); + set_cmd_cfunc (set, set_upload_type); + set_upload_type (NULL, 0); + + add_show_from_set + (add_set_cmd ((char *) "debugexec", class_support, var_boolean, + (char *) &debug_exec, + (char *) "Set whether to display execution in child process.", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean, + (char *) &remote_add_host, + (char *) "\ +Set whether to add this host to remote stub arguments for\n\ +debugging over a network.", &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ((char *) "debugevents", class_support, var_boolean, + (char *) &debug_events, + (char *) "Set whether to display kernel events in child process.", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ((char *) "debugmemory", class_support, var_boolean, + (char *) &debug_memory, + (char *) "Set whether to display memory accesses in child process.", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean, + (char *) &debug_exceptions, + (char *) "Set whether to display kernel exceptions in child process.", + &setlist), + &showlist); + + add_target (&child_ops); +} + +/* Determine if the thread referenced by "pid" is alive + by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0 + it means that the pid has died. Otherwise it is assumed to be alive. */ +static int +win32_child_thread_alive (ptid_t ptid) +{ + int pid = PIDGET (ptid); + return thread_alive (thread_rec (pid, FALSE)->h); +} + +/* Convert pid to printable format. */ +char * +cygwin_pid_to_str (int pid) +{ + static char buf[80]; + if (pid == current_event.dwProcessId) + sprintf (buf, "process %d", pid); + else + sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid); + return buf; +} diff --git a/contrib/gdb/gdb/wrapper.h b/contrib/gdb/gdb/wrapper.h index 977a77d04cd..b287b29db1e 100644 --- a/contrib/gdb/gdb/wrapper.h +++ b/contrib/gdb/gdb/wrapper.h @@ -21,6 +21,8 @@ #include "gdb.h" struct value; +struct expression; +struct block; /* Use this struct to pass arguments to wrapper routines. */ struct gdb_wrapper_arguments; diff --git a/contrib/gdb/gdb/xcoffread.c b/contrib/gdb/gdb/xcoffread.c new file mode 100644 index 00000000000..759dfcb1fb7 --- /dev/null +++ b/contrib/gdb/gdb/xcoffread.c @@ -0,0 +1,3033 @@ +/* Read AIX xcoff symbol tables and convert to internal format, for GDB. + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. + Derived from coffread.c, dbxread.c, and a lot of hacking. + Contributed by IBM Corporation. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "bfd.h" + +#include +#include +#include +#include "gdb_string.h" + +#include +#ifndef NO_SYS_FILE +#include +#endif +#include "gdb_stat.h" + +#include "coff/internal.h" +#include "libcoff.h" /* FIXME, internal data from BFD */ +#include "coff/xcoff.h" +#include "libxcoff.h" +#include "coff/rs6000.h" + +#include "symtab.h" +#include "gdbtypes.h" +/* FIXME: ezannoni/2004-02-13 Verify if the include below is really needed. */ +#include "symfile.h" +#include "objfiles.h" +#include "buildsym.h" +#include "stabsread.h" +#include "expression.h" +#include "complaints.h" + +#include "gdb-stabs.h" + +/* For interface with stabsread.c. */ +#include "aout/stab_gnu.h" + + +/* We put a pointer to this structure in the read_symtab_private field + of the psymtab. */ + +struct symloc + { + + /* First symbol number for this file. */ + + int first_symnum; + + /* Number of symbols in the section of the symbol table devoted to + this file's symbols (actually, the section bracketed may contain + more than just this file's symbols). If numsyms is 0, the only + reason for this thing's existence is the dependency list. Nothing + else will happen when it is read in. */ + + int numsyms; + + /* Position of the start of the line number information for this psymtab. */ + unsigned int lineno_off; + }; + +/* Remember what we deduced to be the source language of this psymtab. */ + +static enum language psymtab_language = language_unknown; + + +/* Simplified internal version of coff symbol table information */ + +struct coff_symbol + { + char *c_name; + int c_symnum; /* symbol number of this entry */ + int c_naux; /* 0 if syment only, 1 if syment + auxent */ + long c_value; + unsigned char c_sclass; + int c_secnum; + unsigned int c_type; + }; + +/* last function's saved coff symbol `cs' */ + +static struct coff_symbol fcn_cs_saved; + +static bfd *symfile_bfd; + +/* Core address of start and end of text of current source file. + This is calculated from the first function seen after a C_FILE + symbol. */ + + +static CORE_ADDR cur_src_end_addr; + +/* Core address of the end of the first object file. */ + +static CORE_ADDR first_object_file_end; + +/* initial symbol-table-debug-string vector length */ + +#define INITIAL_STABVECTOR_LENGTH 40 + +/* Nonzero if within a function (so symbols should be local, + if nothing says specifically). */ + +int within_function; + +/* Size of a COFF symbol. I think it is always 18, so I'm not sure + there is any reason not to just use a #define, but might as well + ask BFD for the size and store it here, I guess. */ + +static unsigned local_symesz; + +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 */ + + /* Pointer to the string table. */ + char *strtbl; + + /* Pointer to debug section. */ + char *debugsec; + + /* Pointer to the a.out symbol table. */ + char *symtbl; + + /* Number of symbols in symtbl. */ + int symtbl_num_syms; + + /* Offset in data section to TOC anchor. */ + CORE_ADDR toc_offset; + }; + +static void +bf_notfound_complaint (void) +{ + complaint (&symfile_complaints, "line numbers off, `.bf' symbol not found"); +} + +static void +ef_complaint (int arg1) +{ + complaint (&symfile_complaints, + "Mismatched .ef symbol ignored starting at symnum %d", arg1); +} + +static void +eb_complaint (int arg1) +{ + complaint (&symfile_complaints, + "Mismatched .eb symbol ignored starting at symnum %d", arg1); +} + +static void xcoff_initial_scan (struct objfile *, int); + +static void scan_xcoff_symtab (struct objfile *); + +static char *xcoff_next_symbol_text (struct objfile *); + +static void record_include_begin (struct coff_symbol *); + +static void +enter_line_range (struct subfile *, unsigned, unsigned, + CORE_ADDR, CORE_ADDR, unsigned *); + +static void init_stringtab (bfd *, file_ptr, struct objfile *); + +static void xcoff_symfile_init (struct objfile *); + +static void xcoff_new_init (struct objfile *); + +static void xcoff_symfile_finish (struct objfile *); + +static void xcoff_symfile_offsets (struct objfile *, + struct section_addr_info *addrs); + +static char *coff_getfilename (union internal_auxent *, struct objfile *); + +static void read_symbol (struct internal_syment *, int); + +static int read_symbol_lineno (int); + +static CORE_ADDR read_symbol_nvalue (int); + +static struct symbol *process_xcoff_symbol (struct coff_symbol *, + struct objfile *); + +static void read_xcoff_symtab (struct partial_symtab *); + +#if 0 +static void add_stab_to_list (char *, struct pending_stabs **); +#endif + +static int compare_lte (const void *, const void *); + +static struct linetable *arrange_linetable (struct linetable *); + +static void record_include_end (struct coff_symbol *); + +static void process_linenos (CORE_ADDR, CORE_ADDR); + + +/* Translate from a COFF section number (target_index) to a SECT_OFF_* + code. */ +static int secnum_to_section (int, struct objfile *); +static asection *secnum_to_bfd_section (int, struct objfile *); + +struct find_targ_sec_arg + { + int targ_index; + int *resultp; + asection **bfd_sect; + struct objfile *objfile; + }; + +static void find_targ_sec (bfd *, asection *, void *); + +static void +find_targ_sec (bfd *abfd, asection *sect, void *obj) +{ + struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj; + struct objfile *objfile = args->objfile; + if (sect->target_index == args->targ_index) + { + /* This is the section. Figure out what SECT_OFF_* code it is. */ + if (bfd_get_section_flags (abfd, sect) & SEC_CODE) + *args->resultp = SECT_OFF_TEXT (objfile); + else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) + *args->resultp = SECT_OFF_DATA (objfile); + else + *args->resultp = sect->index; + *args->bfd_sect = sect; + } +} + +/* Return the section number (SECT_OFF_*) that CS points to. */ +static int +secnum_to_section (int secnum, struct objfile *objfile) +{ + int off = SECT_OFF_TEXT (objfile); + asection *sect = NULL; + struct find_targ_sec_arg args; + args.targ_index = secnum; + args.resultp = &off; + args.bfd_sect = § + args.objfile = objfile; + bfd_map_over_sections (objfile->obfd, find_targ_sec, &args); + return off; +} + +/* Return the BFD section that CS points to. */ +static asection * +secnum_to_bfd_section (int secnum, struct objfile *objfile) +{ + int off = SECT_OFF_TEXT (objfile); + asection *sect = NULL; + struct find_targ_sec_arg args; + args.targ_index = secnum; + args.resultp = &off; + args.bfd_sect = § + args.objfile = objfile; + bfd_map_over_sections (objfile->obfd, find_targ_sec, &args); + return sect; +} + +/* add a given stab string into given stab vector. */ + +#if 0 + +static void +add_stab_to_list (char *stabname, struct pending_stabs **stabvector) +{ + if (*stabvector == NULL) + { + *stabvector = (struct pending_stabs *) + xmalloc (sizeof (struct pending_stabs) + + INITIAL_STABVECTOR_LENGTH * sizeof (char *)); + (*stabvector)->count = 0; + (*stabvector)->length = INITIAL_STABVECTOR_LENGTH; + } + else if ((*stabvector)->count >= (*stabvector)->length) + { + (*stabvector)->length += INITIAL_STABVECTOR_LENGTH; + *stabvector = (struct pending_stabs *) + xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) + + (*stabvector)->length * sizeof (char *)); + } + (*stabvector)->stab[(*stabvector)->count++] = stabname; +} + +#endif + /* *INDENT-OFF* */ +/* Linenos are processed on a file-by-file basis. + + Two reasons: + + 1) xlc (IBM's native c compiler) postpones static function code + emission to the end of a compilation unit. This way it can + determine if those functions (statics) are needed or not, and + can do some garbage collection (I think). This makes line + numbers and corresponding addresses unordered, and we end up + with a line table like: + + + lineno addr + foo() 10 0x100 + 20 0x200 + 30 0x300 + + foo3() 70 0x400 + 80 0x500 + 90 0x600 + + static foo2() + 40 0x700 + 50 0x800 + 60 0x900 + + and that breaks gdb's binary search on line numbers, if the + above table is not sorted on line numbers. And that sort + should be on function based, since gcc can emit line numbers + like: + + 10 0x100 - for the init/test part of a for stmt. + 20 0x200 + 30 0x300 + 10 0x400 - for the increment part of a for stmt. + + arrange_linetable() will do this sorting. + + 2) aix symbol table might look like: + + c_file // beginning of a new file + .bi // beginning of include file + .ei // end of include file + .bi + .ei + + basically, .bi/.ei pairs do not necessarily encapsulate + their scope. They need to be recorded, and processed later + on when we come the end of the compilation unit. + Include table (inclTable) and process_linenos() handle + that. */ +/* *INDENT-ON* */ + + + +/* compare line table entry addresses. */ + +static int +compare_lte (const void *lte1p, const void *lte2p) +{ + struct linetable_entry *lte1 = (struct linetable_entry *) lte1p; + struct linetable_entry *lte2 = (struct linetable_entry *) lte2p; + return lte1->pc - lte2->pc; +} + +/* Given a line table with function entries are marked, arrange its functions + in ascending order and strip off function entry markers and return it in + a newly created table. If the old one is good enough, return the old one. */ +/* FIXME: I think all this stuff can be replaced by just passing + sort_linevec = 1 to end_symtab. */ + +static struct linetable * +arrange_linetable (struct linetable *oldLineTb) +{ + int ii, jj, newline, /* new line count */ + function_count; /* # of functions */ + + struct linetable_entry *fentry; /* function entry vector */ + int fentry_size; /* # of function entries */ + struct linetable *newLineTb; /* new line table */ + +#define NUM_OF_FUNCTIONS 20 + + fentry_size = NUM_OF_FUNCTIONS; + fentry = (struct linetable_entry *) + xmalloc (fentry_size * sizeof (struct linetable_entry)); + + for (function_count = 0, ii = 0; ii < oldLineTb->nitems; ++ii) + { + + if (oldLineTb->item[ii].line == 0) + { /* function entry found. */ + + if (function_count >= fentry_size) + { /* make sure you have room. */ + fentry_size *= 2; + fentry = (struct linetable_entry *) + xrealloc (fentry, fentry_size * sizeof (struct linetable_entry)); + } + fentry[function_count].line = ii; + fentry[function_count].pc = oldLineTb->item[ii].pc; + ++function_count; + } + } + + if (function_count == 0) + { + xfree (fentry); + return oldLineTb; + } + else if (function_count > 1) + qsort (fentry, function_count, sizeof (struct linetable_entry), compare_lte); + + /* allocate a new line table. */ + newLineTb = (struct linetable *) + xmalloc + (sizeof (struct linetable) + + (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry)); + + /* if line table does not start with a function beginning, copy up until + a function begin. */ + + newline = 0; + if (oldLineTb->item[0].line != 0) + for (newline = 0; + newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline) + newLineTb->item[newline] = oldLineTb->item[newline]; + + /* Now copy function lines one by one. */ + + for (ii = 0; ii < function_count; ++ii) + { + for (jj = fentry[ii].line + 1; + jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0; + ++jj, ++newline) + newLineTb->item[newline] = oldLineTb->item[jj]; + } + xfree (fentry); + newLineTb->nitems = oldLineTb->nitems - function_count; + return newLineTb; +} + +/* include file support: C_BINCL/C_EINCL pairs will be kept in the + following `IncludeChain'. At the end of each symtab (end_symtab), + we will determine if we should create additional symtab's to + represent if (the include files. */ + + +typedef struct _inclTable +{ + char *name; /* include filename */ + + /* Offsets to the line table. end points to the last entry which is + part of this include file. */ + int begin, end; + + struct subfile *subfile; + unsigned funStartLine; /* start line # of its function */ +} +InclTable; + +#define INITIAL_INCLUDE_TABLE_LENGTH 20 +static InclTable *inclTable; /* global include table */ +static int inclIndx; /* last entry to table */ +static int inclLength; /* table length */ +static int inclDepth; /* nested include depth */ + +static void allocate_include_entry (void); + +static void +record_include_begin (struct coff_symbol *cs) +{ + if (inclDepth) + { + /* In xcoff, we assume include files cannot be nested (not in .c files + of course, but in corresponding .s files.). */ + + /* This can happen with old versions of GCC. + GCC 2.3.3-930426 does not exhibit this on a test case which + a user said produced the message for him. */ + complaint (&symfile_complaints, "Nested C_BINCL symbols"); + } + ++inclDepth; + + allocate_include_entry (); + + inclTable[inclIndx].name = cs->c_name; + inclTable[inclIndx].begin = cs->c_value; +} + +static void +record_include_end (struct coff_symbol *cs) +{ + InclTable *pTbl; + + if (inclDepth == 0) + { + complaint (&symfile_complaints, "Mismatched C_BINCL/C_EINCL pair"); + } + + allocate_include_entry (); + + pTbl = &inclTable[inclIndx]; + pTbl->end = cs->c_value; + + --inclDepth; + ++inclIndx; +} + +static void +allocate_include_entry (void) +{ + if (inclTable == NULL) + { + inclTable = (InclTable *) + xmalloc (sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH); + memset (inclTable, + '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH); + inclLength = INITIAL_INCLUDE_TABLE_LENGTH; + inclIndx = 0; + } + else if (inclIndx >= inclLength) + { + inclLength += INITIAL_INCLUDE_TABLE_LENGTH; + inclTable = (InclTable *) + xrealloc (inclTable, sizeof (InclTable) * inclLength); + memset (inclTable + inclLength - INITIAL_INCLUDE_TABLE_LENGTH, + '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH); + } +} + +/* Global variable to pass the psymtab down to all the routines involved + in psymtab to symtab processing. */ +static struct partial_symtab *this_symtab_psymtab; + +/* given the start and end addresses of a compilation unit (or a csect, + at times) process its lines and create appropriate line vectors. */ + +static void +process_linenos (CORE_ADDR start, CORE_ADDR end) +{ + int offset, ii; + file_ptr max_offset = + ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) + ->max_lineno_offset; + + /* subfile structure for the main compilation unit. */ + struct subfile main_subfile; + + /* In the main source file, any time we see a function entry, we + reset this variable to function's absolute starting line number. + All the following line numbers in the function are relative to + this, and we record absolute line numbers in record_line(). */ + + unsigned int main_source_baseline = 0; + + unsigned *firstLine; + + offset = + ((struct symloc *) this_symtab_psymtab->read_symtab_private)->lineno_off; + if (offset == 0) + goto return_after_cleanup; + + memset (&main_subfile, '\0', sizeof (main_subfile)); + + if (inclIndx == 0) + /* All source lines were in the main source file. None in include files. */ + + enter_line_range (&main_subfile, offset, 0, start, end, + &main_source_baseline); + + else + { + /* There was source with line numbers in include files. */ + + int linesz = + coff_data (this_symtab_psymtab->objfile->obfd)->local_linesz; + main_source_baseline = 0; + + for (ii = 0; ii < inclIndx; ++ii) + { + struct subfile *tmpSubfile; + + /* If there is main file source before include file, enter it. */ + if (offset < inclTable[ii].begin) + { + enter_line_range + (&main_subfile, offset, inclTable[ii].begin - linesz, + start, 0, &main_source_baseline); + } + + /* Have a new subfile for the include file. */ + + tmpSubfile = inclTable[ii].subfile = + (struct subfile *) xmalloc (sizeof (struct subfile)); + + memset (tmpSubfile, '\0', sizeof (struct subfile)); + firstLine = &(inclTable[ii].funStartLine); + + /* Enter include file's lines now. */ + enter_line_range (tmpSubfile, inclTable[ii].begin, + inclTable[ii].end, start, 0, firstLine); + + if (offset <= inclTable[ii].end) + offset = inclTable[ii].end + linesz; + } + + /* All the include files' line have been processed at this point. Now, + enter remaining lines of the main file, if any left. */ + if (offset < max_offset + 1 - linesz) + { + enter_line_range (&main_subfile, offset, 0, start, end, + &main_source_baseline); + } + } + + /* Process main file's line numbers. */ + if (main_subfile.line_vector) + { + struct linetable *lineTb, *lv; + + lv = main_subfile.line_vector; + + /* Line numbers are not necessarily ordered. xlc compilation will + put static function to the end. */ + + lineTb = arrange_linetable (lv); + if (lv == lineTb) + { + current_subfile->line_vector = (struct linetable *) + xrealloc (lv, (sizeof (struct linetable) + + lv->nitems * sizeof (struct linetable_entry))); + } + else + { + xfree (lv); + current_subfile->line_vector = lineTb; + } + + current_subfile->line_vector_length = + current_subfile->line_vector->nitems; + } + + /* Now, process included files' line numbers. */ + + for (ii = 0; ii < inclIndx; ++ii) + { + if ((inclTable[ii].subfile)->line_vector) /* Useless if!!! FIXMEmgo */ + { + struct linetable *lineTb, *lv; + + lv = (inclTable[ii].subfile)->line_vector; + + /* Line numbers are not necessarily ordered. xlc compilation will + put static function to the end. */ + + lineTb = arrange_linetable (lv); + + push_subfile (); + + /* For the same include file, we might want to have more than one + subfile. This happens if we have something like: + + ...... + #include "foo.h" + ...... + #include "foo.h" + ...... + + while foo.h including code in it. (stupid but possible) + Since start_subfile() looks at the name and uses an + existing one if finds, we need to provide a fake name and + fool it. */ + +#if 0 + start_subfile (inclTable[ii].name, (char *) 0); +#else + { + /* Pick a fake name that will produce the same results as this + one when passed to deduce_language_from_filename. Kludge on + top of kludge. */ + char *fakename = strrchr (inclTable[ii].name, '.'); + if (fakename == NULL) + fakename = " ?"; + start_subfile (fakename, (char *) 0); + xfree (current_subfile->name); + } + current_subfile->name = xstrdup (inclTable[ii].name); +#endif + + if (lv == lineTb) + { + current_subfile->line_vector = + (struct linetable *) xrealloc + (lv, (sizeof (struct linetable) + + lv->nitems * sizeof (struct linetable_entry))); + + } + else + { + xfree (lv); + current_subfile->line_vector = lineTb; + } + + current_subfile->line_vector_length = + current_subfile->line_vector->nitems; + start_subfile (pop_subfile (), (char *) 0); + } + } + +return_after_cleanup: + + /* We don't want to keep alloc/free'ing the global include file table. */ + inclIndx = 0; + + /* Start with a fresh subfile structure for the next file. */ + memset (&main_subfile, '\0', sizeof (struct subfile)); +} + +void +aix_process_linenos (void) +{ + /* process line numbers and enter them into line vector */ + process_linenos (last_source_start_addr, cur_src_end_addr); +} + + +/* Enter a given range of lines into the line vector. + can be called in the following two ways: + enter_line_range (subfile, beginoffset, endoffset, startaddr, 0, firstLine) or + enter_line_range (subfile, beginoffset, 0, startaddr, endaddr, firstLine) + + endoffset points to the last line table entry that we should pay + attention to. */ + +static void +enter_line_range (struct subfile *subfile, unsigned beginoffset, unsigned endoffset, /* offsets to line table */ + CORE_ADDR startaddr, /* offsets to line table */ + CORE_ADDR endaddr, unsigned *firstLine) +{ + unsigned int curoffset; + CORE_ADDR addr; + void *ext_lnno; + struct internal_lineno int_lnno; + unsigned int limit_offset; + bfd *abfd; + int linesz; + + if (endoffset == 0 && startaddr == 0 && endaddr == 0) + return; + curoffset = beginoffset; + limit_offset = + ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) + ->max_lineno_offset; + + if (endoffset != 0) + { + if (endoffset >= limit_offset) + { + complaint (&symfile_complaints, + "Bad line table offset in C_EINCL directive"); + return; + } + limit_offset = endoffset; + } + else + limit_offset -= 1; + + abfd = this_symtab_psymtab->objfile->obfd; + linesz = coff_data (abfd)->local_linesz; + ext_lnno = alloca (linesz); + + while (curoffset <= limit_offset) + { + bfd_seek (abfd, curoffset, SEEK_SET); + bfd_bread (ext_lnno, linesz, abfd); + bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno); + + /* Find the address this line represents. */ + addr = (int_lnno.l_lnno + ? int_lnno.l_addr.l_paddr + : read_symbol_nvalue (int_lnno.l_addr.l_symndx)); + addr += ANOFFSET (this_symtab_psymtab->objfile->section_offsets, + SECT_OFF_TEXT (this_symtab_psymtab->objfile)); + + if (addr < startaddr || (endaddr && addr >= endaddr)) + return; + + if (int_lnno.l_lnno == 0) + { + *firstLine = read_symbol_lineno (int_lnno.l_addr.l_symndx); + record_line (subfile, 0, addr); + --(*firstLine); + } + else + record_line (subfile, *firstLine + int_lnno.l_lnno, addr); + curoffset += linesz; + } +} + + +/* Save the vital information for use when closing off the current file. + NAME is the file name the symbols came from, START_ADDR is the first + text address for the file, and SIZE is the number of bytes of text. */ + +#define complete_symtab(name, start_addr) { \ + last_source_file = savestring (name, strlen (name)); \ + last_source_start_addr = start_addr; \ +} + + +/* Refill the symbol table input buffer + and set the variables that control fetching entries from it. + Reports an error if no data available. + This function can read past the end of the symbol table + (into the string table) but this does no harm. */ + +/* Reading symbol table has to be fast! Keep the followings as macros, rather + than functions. */ + +#define RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, SECTION, OBJFILE) \ +{ \ + char *namestr; \ + namestr = (NAME); \ + if (namestr[0] == '.') ++namestr; \ + prim_record_minimal_symbol_and_info (namestr, (ADDR), (TYPE), \ + (char *)NULL, (SECTION), (asection *)NULL, (OBJFILE)); \ + misc_func_recorded = 1; \ +} + + +/* xcoff has static blocks marked in `.bs', `.es' pairs. They cannot be + nested. At any given time, a symbol can only be in one static block. + This is the base address of current static block, zero if non exists. */ + +static int static_block_base = 0; + +/* Section number for the current static block. */ + +static int static_block_section = -1; + +/* true if space for symbol name has been allocated. */ + +static int symname_alloced = 0; + +/* Next symbol to read. Pointer into raw seething symbol table. */ + +static char *raw_symbol; + +/* This is the function which stabsread.c calls to get symbol + continuations. */ + +static char * +xcoff_next_symbol_text (struct objfile *objfile) +{ + struct internal_syment symbol; + char *retval; + /* FIXME: is this the same as the passed arg? */ + objfile = this_symtab_psymtab->objfile; + + bfd_coff_swap_sym_in (objfile->obfd, raw_symbol, &symbol); + if (symbol.n_zeroes) + { + complaint (&symfile_complaints, "Unexpected symbol continuation"); + + /* Return something which points to '\0' and hope the symbol reading + code does something reasonable. */ + retval = ""; + } + else if (symbol.n_sclass & 0x80) + { + retval = + ((struct coff_symfile_info *) objfile->sym_private)->debugsec + + symbol.n_offset; + raw_symbol += + coff_data (objfile->obfd)->local_symesz; + ++symnum; + } + else + { + complaint (&symfile_complaints, "Unexpected symbol continuation"); + + /* Return something which points to '\0' and hope the symbol reading + code does something reasonable. */ + retval = ""; + } + return retval; +} + +/* Read symbols for a given partial symbol table. */ + +static void +read_xcoff_symtab (struct partial_symtab *pst) +{ + struct objfile *objfile = pst->objfile; + bfd *abfd = objfile->obfd; + char *raw_auxptr; /* Pointer to first raw aux entry for sym */ + char *strtbl = ((struct coff_symfile_info *) objfile->sym_private)->strtbl; + char *debugsec = + ((struct coff_symfile_info *) objfile->sym_private)->debugsec; + char *debugfmt = bfd_xcoff_is_xcoff64 (abfd) ? "XCOFF64" : "XCOFF"; + + struct internal_syment symbol[1]; + union internal_auxent main_aux; + struct coff_symbol cs[1]; + CORE_ADDR file_start_addr = 0; + CORE_ADDR file_end_addr = 0; + + int next_file_symnum = -1; + unsigned int max_symnum; + int just_started = 1; + int depth = 0; + int fcn_start_addr = 0; + + struct coff_symbol fcn_stab_saved; + + /* fcn_cs_saved is global because process_xcoff_symbol needs it. */ + union internal_auxent fcn_aux_saved; + struct context_stack *new; + + char *filestring = " _start_ "; /* Name of the current file. */ + + char *last_csect_name; /* last seen csect's name and value */ + CORE_ADDR last_csect_val; + int last_csect_sec; + + this_symtab_psymtab = pst; + + /* Get the appropriate COFF "constants" related to the file we're + handling. */ + local_symesz = coff_data (abfd)->local_symesz; + + last_source_file = NULL; + last_csect_name = 0; + last_csect_val = 0; + + start_stabs (); + start_symtab (filestring, (char *) NULL, file_start_addr); + record_debugformat (debugfmt); + symnum = ((struct symloc *) pst->read_symtab_private)->first_symnum; + max_symnum = + symnum + ((struct symloc *) pst->read_symtab_private)->numsyms; + first_object_file_end = 0; + + raw_symbol = + ((struct coff_symfile_info *) objfile->sym_private)->symtbl + + symnum * local_symesz; + + while (symnum < max_symnum) + { + + QUIT; /* make this command interruptable. */ + + /* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */ + /* read one symbol into `cs' structure. After processing the + whole symbol table, only string table will be kept in memory, + symbol table and debug section of xcoff will be freed. Thus + we can mark symbols with names in string table as + `alloced'. */ + { + int ii; + + /* Swap and align the symbol into a reasonable C structure. */ + bfd_coff_swap_sym_in (abfd, raw_symbol, symbol); + + cs->c_symnum = symnum; + cs->c_naux = symbol->n_numaux; + if (symbol->n_zeroes) + { + symname_alloced = 0; + /* We must use the original, unswapped, name here so the name field + pointed to by cs->c_name will persist throughout xcoffread. If + we use the new field, it gets overwritten for each symbol. */ + cs->c_name = ((struct external_syment *) raw_symbol)->e.e_name; + /* If it's exactly E_SYMNMLEN characters long it isn't + '\0'-terminated. */ + if (cs->c_name[E_SYMNMLEN - 1] != '\0') + { + char *p; + p = obstack_alloc (&objfile->objfile_obstack, E_SYMNMLEN + 1); + strncpy (p, cs->c_name, E_SYMNMLEN); + p[E_SYMNMLEN] = '\0'; + cs->c_name = p; + symname_alloced = 1; + } + } + else if (symbol->n_sclass & 0x80) + { + cs->c_name = debugsec + symbol->n_offset; + symname_alloced = 0; + } + else + { + /* in string table */ + cs->c_name = strtbl + (int) symbol->n_offset; + symname_alloced = 1; + } + cs->c_value = symbol->n_value; + cs->c_sclass = symbol->n_sclass; + cs->c_secnum = symbol->n_scnum; + cs->c_type = (unsigned) symbol->n_type; + + raw_symbol += local_symesz; + ++symnum; + + /* Save addr of first aux entry. */ + raw_auxptr = raw_symbol; + + /* Skip all the auxents associated with this symbol. */ + for (ii = symbol->n_numaux; ii; --ii) + { + raw_symbol += coff_data (abfd)->local_auxesz; + ++symnum; + } + } + + /* if symbol name starts with ".$" or "$", ignore it. */ + if (cs->c_name[0] == '$' + || (cs->c_name[1] == '$' && cs->c_name[0] == '.')) + continue; + + if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) + { + if (last_source_file) + { + pst->symtab = + end_symtab (cur_src_end_addr, objfile, SECT_OFF_TEXT (objfile)); + end_stabs (); + } + + start_stabs (); + start_symtab ("_globals_", (char *) NULL, (CORE_ADDR) 0); + record_debugformat (debugfmt); + cur_src_end_addr = first_object_file_end; + /* done with all files, everything from here on is globals */ + } + + if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT) + && cs->c_naux == 1) + { + /* Dealing with a symbol with a csect entry. */ + +#define CSECT(PP) ((PP)->x_csect) +#define CSECT_LEN(PP) (CSECT(PP).x_scnlen.l) +#define CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp)) +#define CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp)) +#define CSECT_SCLAS(PP) (CSECT(PP).x_smclas) + + /* Convert the auxent to something we can access. */ + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); + + switch (CSECT_SMTYP (&main_aux)) + { + + case XTY_ER: + /* Ignore all external references. */ + continue; + + case XTY_SD: + /* A section description. */ + { + switch (CSECT_SCLAS (&main_aux)) + { + + case XMC_PR: + { + + /* A program csect is seen. We have to allocate one + symbol table for each program csect. Normally gdb + prefers one symtab for each source file. In case + of AIX, one source file might include more than one + [PR] csect, and they don't have to be adjacent in + terms of the space they occupy in memory. Thus, one + single source file might get fragmented in the + memory and gdb's file start and end address + approach does not work! GCC (and I think xlc) seem + to put all the code in the unnamed program csect. */ + + if (last_csect_name) + { + complete_symtab (filestring, file_start_addr); + cur_src_end_addr = file_end_addr; + end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile)); + end_stabs (); + start_stabs (); + /* Give all csects for this source file the same + name. */ + start_symtab (filestring, NULL, (CORE_ADDR) 0); + record_debugformat (debugfmt); + } + + /* If this is the very first csect seen, + basically `__start'. */ + if (just_started) + { + first_object_file_end + = cs->c_value + CSECT_LEN (&main_aux); + just_started = 0; + } + + file_start_addr = + cs->c_value + ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)); + file_end_addr = file_start_addr + CSECT_LEN (&main_aux); + + if (cs->c_name && (cs->c_name[0] == '.' + || cs->c_name[0] == '@')) + { + last_csect_name = cs->c_name; + last_csect_val = cs->c_value; + last_csect_sec = secnum_to_section (cs->c_secnum, objfile); + } + } + continue; + + /* All other symbols are put into the minimal symbol + table only. */ + + case XMC_RW: + continue; + + case XMC_TC0: + continue; + + case XMC_TC: + continue; + + default: + /* Ignore the symbol. */ + continue; + } + } + break; + + case XTY_LD: + + switch (CSECT_SCLAS (&main_aux)) + { + case XMC_PR: + /* a function entry point. */ + function_entry_point: + + fcn_start_addr = cs->c_value; + + /* save the function header info, which will be used + when `.bf' is seen. */ + fcn_cs_saved = *cs; + fcn_aux_saved = main_aux; + continue; + + case XMC_GL: + /* shared library function trampoline code entry point. */ + continue; + + case XMC_DS: + /* The symbols often have the same names as debug symbols for + functions, and confuse lookup_symbol. */ + continue; + + default: + /* xlc puts each variable in a separate csect, so we get + an XTY_SD for each variable. But gcc puts several + variables in a csect, so that each variable only gets + an XTY_LD. This will typically be XMC_RW; I suspect + XMC_RO and XMC_BS might be possible too. + These variables are put in the minimal symbol table + only. */ + continue; + } + break; + + case XTY_CM: + /* Common symbols are put into the minimal symbol table only. */ + continue; + + default: + break; + } + } + + /* If explicitly specified as a function, treat is as one. This check + evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur + after the above CSECT check. */ + if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF) + { + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); + goto function_entry_point; + } + + switch (cs->c_sclass) + { + + case C_FILE: + + /* c_value field contains symnum of next .file entry in table + or symnum of first global after last .file. */ + + next_file_symnum = cs->c_value; + + /* Complete symbol table for last object file containing + debugging information. */ + + /* Whether or not there was a csect in the previous file, we + have to call `end_stabs' and `start_stabs' to reset + type_vector, line_vector, etc. structures. */ + + complete_symtab (filestring, file_start_addr); + cur_src_end_addr = file_end_addr; + end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile)); + end_stabs (); + + /* XCOFF, according to the AIX 3.2 documentation, puts the filename + in cs->c_name. But xlc 1.3.0.2 has decided to do things the + standard COFF way and put it in the auxent. We use the auxent if + the symbol is ".file" and an auxent exists, otherwise use the symbol + itself. Simple enough. */ + if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0) + { + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); + filestring = coff_getfilename (&main_aux, objfile); + } + else + filestring = cs->c_name; + + start_stabs (); + start_symtab (filestring, (char *) NULL, (CORE_ADDR) 0); + record_debugformat (debugfmt); + last_csect_name = 0; + + /* reset file start and end addresses. A compilation unit with no text + (only data) should have zero file boundaries. */ + file_start_addr = file_end_addr = 0; + break; + + case C_FUN: + fcn_stab_saved = *cs; + break; + + case C_FCN: + if (DEPRECATED_STREQ (cs->c_name, ".bf")) + { + CORE_ADDR off = ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)); + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); + + within_function = 1; + + new = push_context (0, fcn_start_addr + off); + + new->name = define_symbol + (fcn_cs_saved.c_value + off, + fcn_stab_saved.c_name, 0, 0, objfile); + if (new->name != NULL) + SYMBOL_SECTION (new->name) = SECT_OFF_TEXT (objfile); + } + else if (DEPRECATED_STREQ (cs->c_name, ".ef")) + { + + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); + + /* The value of .ef is the address of epilogue code; + not useful for gdb. */ + /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno + contains number of lines to '}' */ + + if (context_stack_depth <= 0) + { /* We attempted to pop an empty context stack */ + ef_complaint (cs->c_symnum); + within_function = 0; + break; + } + new = pop_context (); + /* Stack must be empty now. */ + if (context_stack_depth > 0 || new == NULL) + { + ef_complaint (cs->c_symnum); + within_function = 0; + break; + } + + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, + (fcn_cs_saved.c_value + + fcn_aux_saved.x_sym.x_misc.x_fsize + + ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile))), + objfile); + within_function = 0; + } + break; + + case C_BSTAT: + /* Begin static block. */ + { + struct internal_syment symbol; + + read_symbol (&symbol, cs->c_value); + static_block_base = symbol.n_value; + static_block_section = + secnum_to_section (symbol.n_scnum, objfile); + } + break; + + case C_ESTAT: + /* End of static block. */ + static_block_base = 0; + static_block_section = -1; + break; + + case C_ARG: + case C_REGPARM: + case C_REG: + case C_TPDEF: + case C_STRTAG: + case C_UNTAG: + case C_ENTAG: + { + complaint (&symfile_complaints, "Unrecognized storage class %d.", + cs->c_sclass); + } + break; + + case C_LABEL: + case C_NULL: + /* Ignore these. */ + break; + + case C_HIDEXT: + case C_STAT: + break; + + case C_BINCL: + /* beginning of include file */ + /* In xlc output, C_BINCL/C_EINCL pair doesn't show up in sorted + order. Thus, when wee see them, we might not know enough info + to process them. Thus, we'll be saving them into a table + (inclTable) and postpone their processing. */ + + record_include_begin (cs); + break; + + case C_EINCL: + /* End of include file. */ + /* See the comment after case C_BINCL. */ + record_include_end (cs); + break; + + case C_BLOCK: + if (DEPRECATED_STREQ (cs->c_name, ".bb")) + { + depth++; + new = push_context (depth, + (cs->c_value + + ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)))); + } + else if (DEPRECATED_STREQ (cs->c_name, ".eb")) + { + if (context_stack_depth <= 0) + { /* We attempted to pop an empty context stack */ + eb_complaint (cs->c_symnum); + break; + } + new = pop_context (); + if (depth-- != new->depth) + { + eb_complaint (cs->c_symnum); + break; + } + if (local_symbols && context_stack_depth > 0) + { + /* Make a block for the local symbols within. */ + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, + (cs->c_value + + ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile))), + objfile); + } + local_symbols = new->locals; + } + break; + + default: + process_xcoff_symbol (cs, objfile); + break; + } + } + + if (last_source_file) + { + struct symtab *s; + + complete_symtab (filestring, file_start_addr); + cur_src_end_addr = file_end_addr; + s = end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile)); + /* When reading symbols for the last C_FILE of the objfile, try + to make sure that we set pst->symtab to the symtab for the + file, not to the _globals_ symtab. I'm not sure whether this + actually works right or when/if it comes up. */ + if (pst->symtab == NULL) + pst->symtab = s; + end_stabs (); + } +} + +#define SYMBOL_DUP(SYMBOL1, SYMBOL2) \ + (SYMBOL2) = (struct symbol *) \ + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); \ + *(SYMBOL2) = *(SYMBOL1); + + +#define SYMNAME_ALLOC(NAME, ALLOCED) \ + (ALLOCED) ? (NAME) : obsavestring ((NAME), strlen (NAME), &objfile->objfile_obstack); + + +static struct type *func_symbol_type; +static struct type *var_symbol_type; + +/* process one xcoff symbol. */ + +static struct symbol * +process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile) +{ + struct symbol onesymbol; + struct symbol *sym = &onesymbol; + struct symbol *sym2 = NULL; + char *name, *pp; + + int sec; + CORE_ADDR off; + + if (cs->c_secnum < 0) + { + /* The value is a register number, offset within a frame, etc., + and does not get relocated. */ + off = 0; + sec = -1; + } + else + { + sec = secnum_to_section (cs->c_secnum, objfile); + off = ANOFFSET (objfile->section_offsets, sec); + } + + name = cs->c_name; + if (name[0] == '.') + ++name; + + memset (sym, '\0', sizeof (struct symbol)); + + /* default assumptions */ + SYMBOL_VALUE_ADDRESS (sym) = cs->c_value + off; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + SYMBOL_SECTION (sym) = secnum_to_section (cs->c_secnum, objfile); + + if (ISFCN (cs->c_type)) + { + /* At this point, we don't know the type of the function. This + will be patched with the type from its stab entry later on in + patch_block_stabs (), unless the file was compiled without -g. */ + + DEPRECATED_SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); + SYMBOL_TYPE (sym) = func_symbol_type; + + SYMBOL_CLASS (sym) = LOC_BLOCK; + SYMBOL_DUP (sym, sym2); + + if (cs->c_sclass == C_EXT) + add_symbol_to_list (sym2, &global_symbols); + else if (cs->c_sclass == C_HIDEXT || cs->c_sclass == C_STAT) + add_symbol_to_list (sym2, &file_symbols); + } + else + { + /* In case we can't figure out the type, provide default. */ + SYMBOL_TYPE (sym) = var_symbol_type; + + switch (cs->c_sclass) + { +#if 0 + /* The values of functions and global symbols are now resolved + via the global_sym_chain in stabsread.c. */ + case C_FUN: + if (fcn_cs_saved.c_sclass == C_EXT) + add_stab_to_list (name, &global_stabs); + else + add_stab_to_list (name, &file_stabs); + break; + + case C_GSYM: + add_stab_to_list (name, &global_stabs); + break; +#endif + + case C_BCOMM: + common_block_start (cs->c_name, objfile); + break; + + case C_ECOMM: + common_block_end (objfile); + break; + + default: + complaint (&symfile_complaints, "Unexpected storage class: %d", + cs->c_sclass); + /* FALLTHROUGH */ + + case C_DECL: + case C_PSYM: + case C_RPSYM: + case C_ECOML: + case C_LSYM: + case C_RSYM: + case C_GSYM: + + { + sym = define_symbol (cs->c_value + off, cs->c_name, 0, 0, objfile); + if (sym != NULL) + { + SYMBOL_SECTION (sym) = sec; + } + return sym; + } + + case C_STSYM: + + /* For xlc (not GCC), the 'V' symbol descriptor is used for + all statics and we need to distinguish file-scope versus + function-scope using within_function. We do this by + changing the string we pass to define_symbol to use 'S' + where we need to, which is not necessarily super-clean, + but seems workable enough. */ + + if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL) + return NULL; + + ++pp; + if (*pp == 'V' && !within_function) + *pp = 'S'; + sym = define_symbol ((cs->c_value + + ANOFFSET (objfile->section_offsets, + static_block_section)), + cs->c_name, 0, 0, objfile); + if (sym != NULL) + { + SYMBOL_VALUE_ADDRESS (sym) += static_block_base; + SYMBOL_SECTION (sym) = static_block_section; + } + return sym; + + } + } + return sym2; +} + +/* Extract the file name from the aux entry of a C_FILE symbol. + Result is in static storage and is only good for temporary use. */ + +static char * +coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile) +{ + static char buffer[BUFSIZ]; + + if (aux_entry->x_file.x_n.x_zeroes == 0) + strcpy (buffer, + ((struct coff_symfile_info *) objfile->sym_private)->strtbl + + aux_entry->x_file.x_n.x_offset); + else + { + strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN); + buffer[FILNMLEN] = '\0'; + } + return (buffer); +} + +/* Set *SYMBOL to symbol number symno in symtbl. */ +static void +read_symbol (struct internal_syment *symbol, int symno) +{ + int nsyms = + ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) + ->symtbl_num_syms; + char *stbl = + ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private) + ->symtbl; + if (symno < 0 || symno >= nsyms) + { + complaint (&symfile_complaints, "Invalid symbol offset"); + symbol->n_value = 0; + symbol->n_scnum = -1; + return; + } + bfd_coff_swap_sym_in (this_symtab_psymtab->objfile->obfd, + stbl + (symno * local_symesz), + symbol); +} + +/* Get value corresponding to symbol number symno in symtbl. */ + +static CORE_ADDR +read_symbol_nvalue (int symno) +{ + struct internal_syment symbol[1]; + + read_symbol (symbol, symno); + return symbol->n_value; +} + + +/* Find the address of the function corresponding to symno, where + symno is the symbol pointed to by the linetable. */ + +static int +read_symbol_lineno (int symno) +{ + struct objfile *objfile = this_symtab_psymtab->objfile; + int xcoff64 = bfd_xcoff_is_xcoff64 (objfile->obfd); + + struct coff_symfile_info *info = + (struct coff_symfile_info *)objfile->sym_private; + int nsyms = info->symtbl_num_syms; + char *stbl = info->symtbl; + char *strtbl = info->strtbl; + + struct internal_syment symbol[1]; + union internal_auxent main_aux[1]; + + if (symno < 0) + { + bf_notfound_complaint (); + return 0; + } + + /* Note that just searching for a short distance (e.g. 50 symbols) + is not enough, at least in the following case. + + .extern foo + [many .stabx entries] + [a few functions, referring to foo] + .globl foo + .bf + + What happens here is that the assembler moves the .stabx entries + to right before the ".bf" for foo, but the symbol for "foo" is before + all the stabx entries. See PR gdb/2222. */ + + /* Maintaining a table of .bf entries might be preferable to this search. + If I understand things correctly it would need to be done only for + the duration of a single psymtab to symtab conversion. */ + while (symno < nsyms) + { + bfd_coff_swap_sym_in (symfile_bfd, + stbl + (symno * local_symesz), symbol); + if (symbol->n_sclass == C_FCN) + { + char *name = xcoff64 ? strtbl + symbol->n_offset : symbol->n_name; + if (DEPRECATED_STREQ (name, ".bf")) + goto gotit; + } + symno += symbol->n_numaux + 1; + } + + bf_notfound_complaint (); + return 0; + +gotit: + /* take aux entry and return its lineno */ + symno++; + bfd_coff_swap_aux_in (objfile->obfd, stbl + symno * local_symesz, + symbol->n_type, symbol->n_sclass, + 0, symbol->n_numaux, main_aux); + + return main_aux->x_sym.x_misc.x_lnsz.x_lnno; +} + +/* Support for line number handling */ + +/* This function is called for every section; it finds the outer limits + * of the line table (minimum and maximum file offset) so that the + * mainline code can read the whole thing for efficiency. + */ +static void +find_linenos (struct bfd *abfd, struct bfd_section *asect, void *vpinfo) +{ + struct coff_symfile_info *info; + int size, count; + file_ptr offset, maxoff; + + count = asect->lineno_count; + + if (!DEPRECATED_STREQ (asect->name, ".text") || count == 0) + return; + + size = count * coff_data (abfd)->local_linesz; + info = (struct coff_symfile_info *) vpinfo; + offset = asect->line_filepos; + maxoff = offset + size; + + if (offset < info->min_lineno_offset || info->min_lineno_offset == 0) + info->min_lineno_offset = offset; + + if (maxoff > info->max_lineno_offset) + info->max_lineno_offset = maxoff; +} + +static void xcoff_psymtab_to_symtab_1 (struct partial_symtab *); + +static void +xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst) +{ + struct cleanup *old_chain; + int i; + + if (!pst) + return; + + if (pst->readin) + { + fprintf_unfiltered + (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", + pst->filename); + return; + } + + /* Read in all partial symtabs on which this one is dependent */ + for (i = 0; i < pst->number_of_dependencies; i++) + if (!pst->dependencies[i]->readin) + { + /* Inform about additional files that need to be read in. */ + if (info_verbose) + { + fputs_filtered (" ", gdb_stdout); + wrap_here (""); + fputs_filtered ("and ", gdb_stdout); + wrap_here (""); + printf_filtered ("%s...", pst->dependencies[i]->filename); + wrap_here (""); /* Flush output */ + gdb_flush (gdb_stdout); + } + xcoff_psymtab_to_symtab_1 (pst->dependencies[i]); + } + + if (((struct symloc *) pst->read_symtab_private)->numsyms != 0) + { + /* Init stuff necessary for reading in symbols. */ + stabsread_init (); + buildsym_init (); + old_chain = make_cleanup (really_free_pendings, 0); + + read_xcoff_symtab (pst); + + do_cleanups (old_chain); + } + + pst->readin = 1; +} + +static void xcoff_psymtab_to_symtab (struct partial_symtab *); + +/* Read in all of the symbols for a given psymtab for real. + Be verbose about it if the user wants that. */ + +static void +xcoff_psymtab_to_symtab (struct partial_symtab *pst) +{ + bfd *sym_bfd; + + if (!pst) + return; + + if (pst->readin) + { + fprintf_unfiltered + (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", + pst->filename); + return; + } + + if (((struct symloc *) pst->read_symtab_private)->numsyms != 0 + || pst->number_of_dependencies) + { + /* Print the message now, before reading the string table, + to avoid disconcerting pauses. */ + if (info_verbose) + { + printf_filtered ("Reading in symbols for %s...", pst->filename); + gdb_flush (gdb_stdout); + } + + sym_bfd = pst->objfile->obfd; + + next_symbol_text_func = xcoff_next_symbol_text; + + xcoff_psymtab_to_symtab_1 (pst); + + /* Match with global symbols. This only needs to be done once, + after all of the symtabs and dependencies have been read in. */ + scan_file_globals (pst->objfile); + + /* Finish up the debug error message. */ + if (info_verbose) + printf_filtered ("done.\n"); + } +} + +static void +xcoff_new_init (struct objfile *objfile) +{ + stabsread_new_init (); + buildsym_new_init (); +} + +/* Do initialization in preparation for reading symbols from OBJFILE. + + We will only be called if this is an XCOFF or XCOFF-like file. + BFD handles figuring out the format of the file, and code in symfile.c + uses BFD's determination to vector to us. */ + +static void +xcoff_symfile_init (struct objfile *objfile) +{ + /* Allocate struct to keep track of the symfile */ + objfile->sym_private = xmmalloc (objfile->md, + sizeof (struct coff_symfile_info)); + + /* XCOFF objects may be reordered, so set OBJF_REORDERED. If we + find this causes a significant slowdown in gdb then we could + set it in the debug symbol readers only when necessary. */ + objfile->flags |= OBJF_REORDERED; + + init_entry_point_info (objfile); +} + +/* Perform any local cleanups required when we are done with a particular + objfile. I.E, we are in the process of discarding all symbol information + for an objfile, freeing up all memory held for it, and unlinking the + objfile struct from the global list of known objfiles. */ + +static void +xcoff_symfile_finish (struct objfile *objfile) +{ + if (objfile->sym_private != NULL) + { + xmfree (objfile->md, objfile->sym_private); + } + + /* Start with a fresh include table for the next objfile. */ + if (inclTable) + { + xfree (inclTable); + inclTable = NULL; + } + inclIndx = inclLength = inclDepth = 0; +} + + +static void +init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile) +{ + long length; + int val; + unsigned char lengthbuf[4]; + char *strtbl; + + ((struct coff_symfile_info *) objfile->sym_private)->strtbl = NULL; + + if (bfd_seek (abfd, offset, SEEK_SET) < 0) + error ("cannot seek to string table in %s: %s", + bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); + + val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd); + length = bfd_h_get_32 (abfd, lengthbuf); + + /* If no string table is needed, then the file may end immediately + after the symbols. Just return with `strtbl' set to NULL. */ + + if (val != sizeof lengthbuf || length < sizeof lengthbuf) + return; + + /* Allocate string table from objfile_obstack. We will need this table + as long as we have its symbol table around. */ + + strtbl = (char *) obstack_alloc (&objfile->objfile_obstack, length); + ((struct coff_symfile_info *) objfile->sym_private)->strtbl = strtbl; + + /* Copy length buffer, the first byte is usually zero and is + used for stabs with a name length of zero. */ + memcpy (strtbl, lengthbuf, sizeof lengthbuf); + if (length == sizeof lengthbuf) + return; + + val = bfd_bread (strtbl + sizeof lengthbuf, length - sizeof lengthbuf, abfd); + + if (val != length - sizeof lengthbuf) + error ("cannot read string table from %s: %s", + bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); + if (strtbl[length - 1] != '\0') + error ("bad symbol file: string table does not end with null character"); + + return; +} + +/* If we have not yet seen a function for this psymtab, this is 0. If we + have seen one, it is the offset in the line numbers of the line numbers + for the psymtab. */ +static unsigned int first_fun_line_offset; + +static struct partial_symtab *xcoff_start_psymtab + (struct objfile *, char *, int, + struct partial_symbol **, struct partial_symbol **); + +/* Allocate and partially fill a partial symtab. It will be + completely filled at the end of the symbol list. + + SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR + is the address relative to which its symbols are (incremental) or 0 + (normal). */ + +static struct partial_symtab * +xcoff_start_psymtab (struct objfile *objfile, char *filename, int first_symnum, + struct partial_symbol **global_syms, + struct partial_symbol **static_syms) +{ + struct partial_symtab *result = + start_psymtab_common (objfile, objfile->section_offsets, + filename, + /* We fill in textlow later. */ + 0, + global_syms, static_syms); + + result->read_symtab_private = (char *) + obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc)); + ((struct symloc *) result->read_symtab_private)->first_symnum = first_symnum; + result->read_symtab = xcoff_psymtab_to_symtab; + + /* Deduce the source language from the filename for this psymtab. */ + psymtab_language = deduce_language_from_filename (filename); + + return result; +} + +static struct partial_symtab *xcoff_end_psymtab + (struct partial_symtab *, char **, int, int, + struct partial_symtab **, int, int); + +/* Close off the current usage of PST. + Returns PST, or NULL if the partial symtab was empty and thrown away. + + CAPPING_SYMBOL_NUMBER is the end of pst (exclusive). + + INCLUDE_LIST, NUM_INCLUDES, DEPENDENCY_LIST, and NUMBER_DEPENDENCIES + are the information for includes and dependencies. */ + +static struct partial_symtab * +xcoff_end_psymtab (struct partial_symtab *pst, char **include_list, + int num_includes, int capping_symbol_number, + struct partial_symtab **dependency_list, + int number_dependencies, int textlow_not_set) +{ + int i; + struct objfile *objfile = pst->objfile; + + if (capping_symbol_number != -1) + ((struct symloc *) pst->read_symtab_private)->numsyms = + capping_symbol_number + - ((struct symloc *) pst->read_symtab_private)->first_symnum; + ((struct symloc *) pst->read_symtab_private)->lineno_off = + first_fun_line_offset; + first_fun_line_offset = 0; + pst->n_global_syms = + objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset); + pst->n_static_syms = + objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset); + + pst->number_of_dependencies = number_dependencies; + if (number_dependencies) + { + pst->dependencies = (struct partial_symtab **) + obstack_alloc (&objfile->objfile_obstack, + number_dependencies * sizeof (struct partial_symtab *)); + memcpy (pst->dependencies, dependency_list, + number_dependencies * sizeof (struct partial_symtab *)); + } + else + pst->dependencies = 0; + + for (i = 0; i < num_includes; i++) + { + struct partial_symtab *subpst = + allocate_psymtab (include_list[i], objfile); + + subpst->section_offsets = pst->section_offsets; + subpst->read_symtab_private = + (char *) obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symloc)); + ((struct symloc *) subpst->read_symtab_private)->first_symnum = 0; + ((struct symloc *) subpst->read_symtab_private)->numsyms = 0; + subpst->textlow = 0; + subpst->texthigh = 0; + + /* We could save slight bits of space by only making one of these, + shared by the entire set of include files. FIXME-someday. */ + subpst->dependencies = (struct partial_symtab **) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct partial_symtab *)); + subpst->dependencies[0] = pst; + subpst->number_of_dependencies = 1; + + subpst->globals_offset = + subpst->n_global_syms = + subpst->statics_offset = + subpst->n_static_syms = 0; + + subpst->readin = 0; + subpst->symtab = 0; + subpst->read_symtab = pst->read_symtab; + } + + sort_pst_symbols (pst); + + /* If there is already a psymtab or symtab for a file of this name, + remove it. (If there is a symtab, more drastic things also + happen.) This happens in VxWorks. */ + 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. */ + /* Empty psymtabs happen as a result of header files which don't have + any symbols in them. There can be a lot of them. */ + + discard_psymtab (pst); + + /* Indicate that psymtab was thrown away. */ + pst = (struct partial_symtab *) NULL; + } + return pst; +} + +static void swap_sym (struct internal_syment *, + union internal_auxent *, char **, char **, + unsigned int *, struct objfile *); + +/* Swap raw symbol at *RAW and put the name in *NAME, the symbol in + *SYMBOL, the first auxent in *AUX. Advance *RAW and *SYMNUMP over + the symbol and its auxents. */ + +static void +swap_sym (struct internal_syment *symbol, union internal_auxent *aux, + char **name, char **raw, unsigned int *symnump, + struct objfile *objfile) +{ + bfd_coff_swap_sym_in (objfile->obfd, *raw, symbol); + if (symbol->n_zeroes) + { + /* If it's exactly E_SYMNMLEN characters long it isn't + '\0'-terminated. */ + if (symbol->n_name[E_SYMNMLEN - 1] != '\0') + { + /* FIXME: wastes memory for symbols which we don't end up putting + into the minimal symbols. */ + char *p; + p = obstack_alloc (&objfile->objfile_obstack, E_SYMNMLEN + 1); + strncpy (p, symbol->n_name, E_SYMNMLEN); + p[E_SYMNMLEN] = '\0'; + *name = p; + } + else + /* Point to the unswapped name as that persists as long as the + objfile does. */ + *name = ((struct external_syment *) *raw)->e.e_name; + } + else if (symbol->n_sclass & 0x80) + { + *name = ((struct coff_symfile_info *) objfile->sym_private)->debugsec + + symbol->n_offset; + } + else + { + *name = ((struct coff_symfile_info *) objfile->sym_private)->strtbl + + symbol->n_offset; + } + ++*symnump; + *raw += coff_data (objfile->obfd)->local_symesz; + if (symbol->n_numaux > 0) + { + bfd_coff_swap_aux_in (objfile->obfd, *raw, symbol->n_type, + symbol->n_sclass, 0, symbol->n_numaux, aux); + + *symnump += symbol->n_numaux; + *raw += coff_data (objfile->obfd)->local_symesz * symbol->n_numaux; + } +} + +static void +function_outside_compilation_unit_complaint (const char *arg1) +{ + complaint (&symfile_complaints, + "function `%s' appears to be defined outside of all compilation units", + arg1); +} + +static void +scan_xcoff_symtab (struct objfile *objfile) +{ + CORE_ADDR toc_offset = 0; /* toc offset value in data section. */ + char *filestring = NULL; + + char *namestring; + int past_first_source_file = 0; + bfd *abfd; + asection *bfd_sect; + unsigned int nsyms; + + /* Current partial symtab */ + struct partial_symtab *pst; + + /* List of current psymtab's include files */ + char **psymtab_include_list; + int includes_allocated; + int includes_used; + + /* Index within current psymtab dependency list */ + struct partial_symtab **dependency_list; + int dependencies_used, dependencies_allocated; + + char *sraw_symbol; + struct internal_syment symbol; + union internal_auxent main_aux[5]; + unsigned int ssymnum; + + char *last_csect_name = NULL; /* last seen csect's name and value */ + CORE_ADDR last_csect_val = 0; + int last_csect_sec = 0; + int misc_func_recorded = 0; /* true if any misc. function */ + int textlow_not_set = 1; + + pst = (struct partial_symtab *) 0; + + includes_allocated = 30; + includes_used = 0; + psymtab_include_list = (char **) alloca (includes_allocated * + sizeof (char *)); + + dependencies_allocated = 30; + dependencies_used = 0; + dependency_list = + (struct partial_symtab **) alloca (dependencies_allocated * + sizeof (struct partial_symtab *)); + + last_source_file = NULL; + + abfd = objfile->obfd; + + sraw_symbol = ((struct coff_symfile_info *) objfile->sym_private)->symtbl; + nsyms = ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms; + ssymnum = 0; + while (ssymnum < nsyms) + { + int sclass; + + QUIT; + + bfd_coff_swap_sym_in (abfd, sraw_symbol, &symbol); + sclass = symbol.n_sclass; + + switch (sclass) + { + case C_EXT: + case C_HIDEXT: + { + /* The CSECT auxent--always the last auxent. */ + union internal_auxent csect_aux; + unsigned int symnum_before = ssymnum; + + swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, + &ssymnum, objfile); + if (symbol.n_numaux > 1) + { + bfd_coff_swap_aux_in + (objfile->obfd, + sraw_symbol - coff_data (abfd)->local_symesz, + symbol.n_type, + symbol.n_sclass, + symbol.n_numaux - 1, + symbol.n_numaux, + &csect_aux); + } + else + csect_aux = main_aux[0]; + + /* If symbol name starts with ".$" or "$", ignore it. */ + if (namestring[0] == '$' + || (namestring[0] == '.' && namestring[1] == '$')) + break; + + switch (csect_aux.x_csect.x_smtyp & 0x7) + { + case XTY_SD: + switch (csect_aux.x_csect.x_smclas) + { + case XMC_PR: + if (last_csect_name) + { + /* If no misc. function recorded in the last + seen csect, enter it as a function. This + will take care of functions like strcmp() + compiled by xlc. */ + + if (!misc_func_recorded) + { + RECORD_MINIMAL_SYMBOL + (last_csect_name, last_csect_val, + mst_text, last_csect_sec, + objfile); + } + + if (pst != NULL) + { + /* We have to allocate one psymtab for + each program csect, because their text + sections need not be adjacent. */ + xcoff_end_psymtab + (pst, psymtab_include_list, includes_used, + symnum_before, dependency_list, + dependencies_used, textlow_not_set); + includes_used = 0; + dependencies_used = 0; + /* Give all psymtabs for this source file the same + name. */ + pst = xcoff_start_psymtab + (objfile, + filestring, + symnum_before, + objfile->global_psymbols.next, + objfile->static_psymbols.next); + } + } + /* Activate the misc_func_recorded mechanism for + compiler- and linker-generated CSECTs like ".strcmp" + and "@FIX1". */ + if (namestring && (namestring[0] == '.' + || namestring[0] == '@')) + { + last_csect_name = namestring; + last_csect_val = symbol.n_value; + last_csect_sec = + secnum_to_section (symbol.n_scnum, objfile); + } + if (pst != NULL) + { + CORE_ADDR highval = + symbol.n_value + csect_aux.x_csect.x_scnlen.l; + if (highval > pst->texthigh) + pst->texthigh = highval; + if (pst->textlow == 0 || symbol.n_value < pst->textlow) + pst->textlow = symbol.n_value; + } + misc_func_recorded = 0; + break; + + case XMC_RW: + case XMC_TD: + /* Data variables are recorded in the minimal symbol + table, except for section symbols. */ + if (*namestring != '.') + prim_record_minimal_symbol_and_info + (namestring, symbol.n_value, + sclass == C_HIDEXT ? mst_file_data : mst_data, + NULL, secnum_to_section (symbol.n_scnum, objfile), + NULL, objfile); + break; + + case XMC_TC0: + if (toc_offset) + warning ("More than one XMC_TC0 symbol found."); + toc_offset = symbol.n_value; + + /* Make TOC offset relative to start address of section. */ + bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile); + if (bfd_sect) + toc_offset -= bfd_section_vma (objfile->obfd, bfd_sect); + break; + + case XMC_TC: + /* These symbols tell us where the TOC entry for a + variable is, not the variable itself. */ + break; + + default: + break; + } + break; + + case XTY_LD: + switch (csect_aux.x_csect.x_smclas) + { + case XMC_PR: + /* A function entry point. */ + + if (first_fun_line_offset == 0 && symbol.n_numaux > 1) + first_fun_line_offset = + main_aux[0].x_sym.x_fcnary.x_fcn.x_lnnoptr; + RECORD_MINIMAL_SYMBOL + (namestring, symbol.n_value, + sclass == C_HIDEXT ? mst_file_text : mst_text, + secnum_to_section (symbol.n_scnum, objfile), + objfile); + break; + + case XMC_GL: + /* shared library function trampoline code entry + point. */ + + /* record trampoline code entries as + mst_solib_trampoline symbol. When we lookup mst + symbols, we will choose mst_text over + mst_solib_trampoline. */ + RECORD_MINIMAL_SYMBOL + (namestring, symbol.n_value, + mst_solib_trampoline, + secnum_to_section (symbol.n_scnum, objfile), + objfile); + break; + + case XMC_DS: + /* The symbols often have the same names as + debug symbols for functions, and confuse + lookup_symbol. */ + break; + + default: + + /* xlc puts each variable in a separate csect, + so we get an XTY_SD for each variable. But + gcc puts several variables in a csect, so + that each variable only gets an XTY_LD. We + still need to record them. This will + typically be XMC_RW; I suspect XMC_RO and + XMC_BS might be possible too. */ + if (*namestring != '.') + prim_record_minimal_symbol_and_info + (namestring, symbol.n_value, + sclass == C_HIDEXT ? mst_file_data : mst_data, + NULL, secnum_to_section (symbol.n_scnum, objfile), + NULL, objfile); + break; + } + break; + + case XTY_CM: + switch (csect_aux.x_csect.x_smclas) + { + case XMC_RW: + case XMC_BS: + /* Common variables are recorded in the minimal symbol + table, except for section symbols. */ + if (*namestring != '.') + prim_record_minimal_symbol_and_info + (namestring, symbol.n_value, + sclass == C_HIDEXT ? mst_file_bss : mst_bss, + NULL, secnum_to_section (symbol.n_scnum, objfile), + NULL, objfile); + break; + } + break; + + default: + break; + } + } + break; + case C_FILE: + { + unsigned int symnum_before; + + symnum_before = ssymnum; + swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, + &ssymnum, objfile); + + /* See if the last csect needs to be recorded. */ + + if (last_csect_name && !misc_func_recorded) + { + + /* If no misc. function recorded in the last seen csect, enter + it as a function. This will take care of functions like + strcmp() compiled by xlc. */ + + RECORD_MINIMAL_SYMBOL + (last_csect_name, last_csect_val, + mst_text, last_csect_sec, objfile); + } + + if (pst) + { + xcoff_end_psymtab (pst, psymtab_include_list, includes_used, + symnum_before, dependency_list, + dependencies_used, textlow_not_set); + includes_used = 0; + dependencies_used = 0; + } + first_fun_line_offset = 0; + + /* XCOFF, according to the AIX 3.2 documentation, puts the + filename in cs->c_name. But xlc 1.3.0.2 has decided to + do things the standard COFF way and put it in the auxent. + We use the auxent if the symbol is ".file" and an auxent + exists, otherwise use the symbol itself. */ + if (!strcmp (namestring, ".file") && symbol.n_numaux > 0) + { + filestring = coff_getfilename (&main_aux[0], objfile); + } + else + filestring = namestring; + + pst = xcoff_start_psymtab (objfile, + filestring, + symnum_before, + objfile->global_psymbols.next, + objfile->static_psymbols.next); + last_csect_name = NULL; + } + break; + + default: + { + complaint (&symfile_complaints, + "Storage class %d not recognized during scan", sclass); + } + /* FALLTHROUGH */ + + /* C_FCN is .bf and .ef symbols. I think it is sufficient + to handle only the C_FUN and C_EXT. */ + case C_FCN: + + case C_BSTAT: + case C_ESTAT: + case C_ARG: + case C_REGPARM: + case C_REG: + case C_TPDEF: + case C_STRTAG: + case C_UNTAG: + case C_ENTAG: + case C_LABEL: + case C_NULL: + + /* C_EINCL means we are switching back to the main file. But there + is no reason to care; the only thing we want to know about + includes is the names of all the included (.h) files. */ + case C_EINCL: + + case C_BLOCK: + + /* I don't think C_STAT is used in xcoff; C_HIDEXT appears to be + used instead. */ + case C_STAT: + + /* I don't think the name of the common block (as opposed to the + variables within it) is something which is user visible + currently. */ + case C_BCOMM: + case C_ECOMM: + + case C_PSYM: + case C_RPSYM: + + /* I think we can ignore C_LSYM; types on xcoff seem to use C_DECL + so C_LSYM would appear to be only for locals. */ + case C_LSYM: + + case C_AUTO: + case C_RSYM: + { + /* We probably could save a few instructions by assuming that + C_LSYM, C_PSYM, etc., never have auxents. */ + int naux1 = symbol.n_numaux + 1; + ssymnum += naux1; + sraw_symbol += bfd_coff_symesz (abfd) * naux1; + } + break; + + case C_BINCL: + { + /* Mark down an include file in the current psymtab */ + enum language tmp_language; + swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, + &ssymnum, objfile); + + tmp_language = deduce_language_from_filename (namestring); + + /* Only change the psymtab's language if we've learned + something useful (eg. tmp_language is not language_unknown). + In addition, to match what start_subfile does, never change + from C++ to C. */ + if (tmp_language != language_unknown + && (tmp_language != language_c + || psymtab_language != language_cplus)) + psymtab_language = tmp_language; + + /* In C++, one may expect the same filename to come round many + times, when code is coming alternately from the main file + and from inline functions in other files. So I check to see + if this is a file we've seen before -- either the main + source file, or a previously included file. + + This seems to be a lot of time to be spending on N_SOL, but + things like "break c-exp.y:435" need to work (I + suppose the psymtab_include_list could be hashed or put + in a binary tree, if profiling shows this is a major hog). */ + if (pst && DEPRECATED_STREQ (namestring, pst->filename)) + continue; + { + int i; + for (i = 0; i < includes_used; i++) + if (DEPRECATED_STREQ (namestring, psymtab_include_list[i])) + { + i = -1; + break; + } + if (i == -1) + continue; + } + psymtab_include_list[includes_used++] = namestring; + if (includes_used >= includes_allocated) + { + char **orig = psymtab_include_list; + + psymtab_include_list = (char **) + alloca ((includes_allocated *= 2) * + sizeof (char *)); + memcpy (psymtab_include_list, orig, + includes_used * sizeof (char *)); + } + continue; + } + case C_FUN: + /* The value of the C_FUN is not the address of the function (it + appears to be the address before linking), but as long as it + is smaller than the actual address, then find_pc_partial_function + will use the minimal symbols instead. I hope. */ + + case C_GSYM: + case C_ECOML: + case C_DECL: + case C_STSYM: + { + char *p; + swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol, + &ssymnum, objfile); + + p = (char *) strchr (namestring, ':'); + if (!p) + continue; /* Not a debugging symbol. */ + + /* Main processing section for debugging symbols which + the initial read through the symbol tables needs to worry + about. If we reach this point, the symbol which we are + considering is definitely one we are interested in. + p must also contain the (valid) index into the namestring + which indicates the debugging type symbol. */ + + switch (p[1]) + { + case 'S': + symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)); +#ifdef STATIC_TRANSFORM_NAME + namestring = STATIC_TRANSFORM_NAME (namestring); +#endif + add_psymbol_to_list (namestring, p - namestring, + VAR_DOMAIN, LOC_STATIC, + &objfile->static_psymbols, + 0, symbol.n_value, + psymtab_language, objfile); + continue; + + case 'G': + symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)); + /* The addresses in these entries are reported to be + wrong. See the code that reads 'G's for symtabs. */ + add_psymbol_to_list (namestring, p - namestring, + VAR_DOMAIN, LOC_STATIC, + &objfile->global_psymbols, + 0, symbol.n_value, + psymtab_language, objfile); + continue; + + case 'T': + /* When a 'T' entry is defining an anonymous enum, it + may have a name which is the empty string, or a + single space. Since they're not really defining a + symbol, those shouldn't go in the partial symbol + table. We do pick up the elements of such enums at + 'check_enum:', below. */ + if (p >= namestring + 2 + || (p == namestring + 1 + && namestring[0] != ' ')) + { + add_psymbol_to_list (namestring, p - namestring, + STRUCT_DOMAIN, LOC_TYPEDEF, + &objfile->static_psymbols, + symbol.n_value, 0, + psymtab_language, objfile); + if (p[2] == 't') + { + /* Also a typedef with the same name. */ + add_psymbol_to_list (namestring, p - namestring, + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->static_psymbols, + symbol.n_value, 0, + psymtab_language, objfile); + p += 1; + } + } + goto check_enum; + + case 't': + if (p != namestring) /* a name is there, not just :T... */ + { + add_psymbol_to_list (namestring, p - namestring, + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->static_psymbols, + symbol.n_value, 0, + psymtab_language, objfile); + } + check_enum: + /* If this is an enumerated type, we need to + add all the enum constants to the partial symbol + table. This does not cover enums without names, e.g. + "enum {a, b} c;" in C, but fortunately those are + rare. There is no way for GDB to find those from the + enum type without spending too much time on it. Thus + to solve this problem, the compiler needs to put out the + enum in a nameless type. GCC2 does this. */ + + /* We are looking for something of the form + ":" ("t" | "T") [ "="] "e" + { ":" ","} ";". */ + + /* Skip over the colon and the 't' or 'T'. */ + p += 2; + /* This type may be given a number. Also, numbers can come + in pairs like (0,26). Skip over it. */ + while ((*p >= '0' && *p <= '9') + || *p == '(' || *p == ',' || *p == ')' + || *p == '=') + p++; + + if (*p++ == 'e') + { + /* The aix4 compiler emits extra crud before the members. */ + if (*p == '-') + { + /* Skip over the type (?). */ + while (*p != ':') + p++; + + /* Skip over the colon. */ + p++; + } + + /* We have found an enumerated type. */ + /* According to comments in read_enum_type + a comma could end it instead of a semicolon. + I don't know where that happens. + Accept either. */ + while (*p && *p != ';' && *p != ',') + { + char *q; + + /* Check for and handle cretinous dbx symbol name + continuation! */ + if (*p == '\\' || (*p == '?' && p[1] == '\0')) + p = next_symbol_text (objfile); + + /* Point to the character after the name + of the enum constant. */ + for (q = p; *q && *q != ':'; q++) + ; + /* Note that the value doesn't matter for + enum constants in psymtabs, just in symtabs. */ + add_psymbol_to_list (p, q - p, + VAR_DOMAIN, LOC_CONST, + &objfile->static_psymbols, 0, + 0, psymtab_language, objfile); + /* Point past the name. */ + p = q; + /* Skip over the value. */ + while (*p && *p != ',') + p++; + /* Advance past the comma. */ + if (*p) + p++; + } + } + continue; + + case 'c': + /* Constant, e.g. from "const" in Pascal. */ + add_psymbol_to_list (namestring, p - namestring, + VAR_DOMAIN, LOC_CONST, + &objfile->static_psymbols, symbol.n_value, + 0, psymtab_language, objfile); + continue; + + case 'f': + if (! pst) + { + int name_len = p - namestring; + char *name = xmalloc (name_len + 1); + memcpy (name, namestring, name_len); + name[name_len] = '\0'; + function_outside_compilation_unit_complaint (name); + xfree (name); + } + symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + add_psymbol_to_list (namestring, p - namestring, + VAR_DOMAIN, LOC_BLOCK, + &objfile->static_psymbols, + 0, symbol.n_value, + psymtab_language, objfile); + continue; + + /* Global functions were ignored here, but now they + are put into the global psymtab like one would expect. + They're also in the minimal symbol table. */ + case 'F': + if (! pst) + { + int name_len = p - namestring; + char *name = xmalloc (name_len + 1); + memcpy (name, namestring, name_len); + name[name_len] = '\0'; + function_outside_compilation_unit_complaint (name); + xfree (name); + } + symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + add_psymbol_to_list (namestring, p - namestring, + VAR_DOMAIN, LOC_BLOCK, + &objfile->global_psymbols, + 0, symbol.n_value, + psymtab_language, objfile); + continue; + + /* Two things show up here (hopefully); static symbols of + local scope (static used inside braces) or extensions + of structure symbols. We can ignore both. */ + case 'V': + case '(': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + case '#': /* for symbol identification (used in live ranges) */ + continue; + + case ':': + /* It is a C++ nested symbol. We don't need to record it + (I don't think); if we try to look up foo::bar::baz, + then symbols for the symtab containing foo should get + read in, I think. */ + /* Someone says sun cc puts out symbols like + /foo/baz/maclib::/usr/local/bin/maclib, + which would get here with a symbol type of ':'. */ + continue; + + default: + /* Unexpected symbol descriptor. The second and subsequent stabs + of a continued stab can show up here. The question is + whether they ever can mimic a normal stab--it would be + nice if not, since we certainly don't want to spend the + time searching to the end of every string looking for + a backslash. */ + + complaint (&symfile_complaints, + "unknown symbol descriptor `%c'", p[1]); + + /* Ignore it; perhaps it is an extension that we don't + know about. */ + continue; + } + } + } + } + + if (pst) + { + xcoff_end_psymtab (pst, psymtab_include_list, includes_used, + ssymnum, dependency_list, + dependencies_used, textlow_not_set); + } + + /* Record the toc offset value of this symbol table into objfile structure. + If no XMC_TC0 is found, toc_offset should be zero. Another place to obtain + this information would be file auxiliary header. */ + + ((struct coff_symfile_info *) objfile->sym_private)->toc_offset = toc_offset; +} + +/* Return the toc offset value for a given objfile. */ + +CORE_ADDR +get_toc_offset (struct objfile *objfile) +{ + if (objfile) + return ((struct coff_symfile_info *) objfile->sym_private)->toc_offset; + return 0; +} + +/* Scan and build partial symbols for a symbol file. + We have been initialized by a call to dbx_symfile_init, which + put all the relevant info into a "struct dbx_symfile_info", + hung off the objfile structure. + + SECTION_OFFSETS contains offsets relative to which the symbols in the + various sections are (depending where the sections were actually loaded). + MAINLINE is true if we are reading the main symbol + table (as opposed to a shared lib or dynamically loaded file). */ + +static void +xcoff_initial_scan (struct objfile *objfile, int mainline) +{ + bfd *abfd; + int val; + struct cleanup *back_to; + int num_symbols; /* # of symbols */ + file_ptr symtab_offset; /* symbol table and */ + file_ptr stringtab_offset; /* string table file offsets */ + struct coff_symfile_info *info; + char *name; + unsigned int size; + + info = (struct coff_symfile_info *) objfile->sym_private; + symfile_bfd = abfd = objfile->obfd; + name = objfile->name; + + num_symbols = bfd_get_symcount (abfd); /* # of symbols */ + symtab_offset = obj_sym_filepos (abfd); /* symbol table file offset */ + stringtab_offset = symtab_offset + + num_symbols * coff_data (abfd)->local_symesz; + + info->min_lineno_offset = 0; + info->max_lineno_offset = 0; + bfd_map_over_sections (abfd, find_linenos, info); + + if (num_symbols > 0) + { + /* Read the string table. */ + init_stringtab (abfd, stringtab_offset, objfile); + + /* Read the .debug section, if present. */ + { + struct bfd_section *secp; + bfd_size_type length; + char *debugsec = NULL; + + secp = bfd_get_section_by_name (abfd, ".debug"); + if (secp) + { + length = bfd_section_size (abfd, secp); + if (length) + { + debugsec = + (char *) obstack_alloc (&objfile->objfile_obstack, length); + + if (!bfd_get_section_contents (abfd, secp, debugsec, + (file_ptr) 0, length)) + { + error ("Error reading .debug section of `%s': %s", + name, bfd_errmsg (bfd_get_error ())); + } + } + } + ((struct coff_symfile_info *) objfile->sym_private)->debugsec = + debugsec; + } + } + + /* Read the symbols. We keep them in core because we will want to + access them randomly in read_symbol*. */ + val = bfd_seek (abfd, symtab_offset, SEEK_SET); + if (val < 0) + error ("Error reading symbols from %s: %s", + name, bfd_errmsg (bfd_get_error ())); + size = coff_data (abfd)->local_symesz * num_symbols; + ((struct coff_symfile_info *) objfile->sym_private)->symtbl = + obstack_alloc (&objfile->objfile_obstack, size); + ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms = + num_symbols; + + val = bfd_bread (((struct coff_symfile_info *) objfile->sym_private)->symtbl, + size, abfd); + if (val != size) + perror_with_name ("reading symbol table"); + + /* If we are reinitializing, or if we have never loaded syms yet, init */ + if (mainline + || (objfile->global_psymbols.size == 0 + && objfile->static_psymbols.size == 0)) + /* I'm not sure how how good num_symbols is; the rule of thumb in + init_psymbol_list was developed for a.out. On the one hand, + num_symbols includes auxents. On the other hand, it doesn't + include N_SLINE. */ + init_psymbol_list (objfile, num_symbols); + + free_pending_blocks (); + back_to = make_cleanup (really_free_pendings, 0); + + init_minimal_symbol_collection (); + make_cleanup_discard_minimal_symbols (); + + /* Now that the symbol table data of the executable file are all in core, + process them and define symbols accordingly. */ + + scan_xcoff_symtab (objfile); + + /* Install any minimal symbols that have been collected as the current + minimal symbols for this objfile. */ + + install_minimal_symbols (objfile); + + do_cleanups (back_to); +} + +static void +xcoff_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs) +{ + asection *sect = NULL; + int i; + + objfile->num_sections = bfd_count_sections (objfile->obfd); + objfile->section_offsets = (struct section_offsets *) + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + + /* Initialize the section indexes for future use. */ + sect = bfd_get_section_by_name (objfile->obfd, ".text"); + if (sect) + objfile->sect_index_text = sect->index; + + sect = bfd_get_section_by_name (objfile->obfd, ".data"); + if (sect) + objfile->sect_index_data = sect->index; + + sect = bfd_get_section_by_name (objfile->obfd, ".bss"); + if (sect) + objfile->sect_index_bss = sect->index; + + sect = bfd_get_section_by_name (objfile->obfd, ".rodata"); + if (sect) + objfile->sect_index_rodata = sect->index; + + for (i = 0; i < objfile->num_sections; ++i) + { + /* syms_from_objfile kindly subtracts from addr the + bfd_section_vma of the .text section. This strikes me as + wrong--whether the offset to be applied to symbol reading is + relative to the start address of the section depends on the + symbol format. In any event, this whole "addr" concept is + pretty broken (it doesn't handle any section but .text + sensibly), so just ignore the addr parameter and use 0. + rs6000-nat.c will set the correct section offsets via + objfile_relocate. */ + (objfile->section_offsets)->offsets[i] = 0; + } +} + +/* Register our ability to parse symbols for xcoff BFD files. */ + +static struct sym_fns xcoff_sym_fns = +{ + + /* It is possible that coff and xcoff should be merged as + they do have fundamental similarities (for example, the extra storage + classes used for stabs could presumably be recognized in any COFF file). + However, in addition to obvious things like all the csect hair, there are + some subtler differences between xcoffread.c and coffread.c, notably + the fact that coffread.c has no need to read in all the symbols, but + xcoffread.c reads all the symbols and does in fact randomly access them + (in C_BSTAT and line number processing). */ + + bfd_target_xcoff_flavour, + + xcoff_new_init, /* sym_new_init: init anything gbl to entire symtab */ + xcoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ + xcoff_initial_scan, /* sym_read: read a symbol file into symtab */ + xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */ + xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */ + NULL /* next: pointer to next struct sym_fns */ +}; + +void +_initialize_xcoffread (void) +{ + add_symtab_fns (&xcoff_sym_fns); + + func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0, + "", NULL); + TYPE_TARGET_TYPE (func_symbol_type) = builtin_type_int; + var_symbol_type = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0, + "", NULL); +} diff --git a/contrib/gdb/gdb/xcoffsolib.c b/contrib/gdb/gdb/xcoffsolib.c new file mode 100644 index 00000000000..99d2cc8e8f7 --- /dev/null +++ b/contrib/gdb/gdb/xcoffsolib.c @@ -0,0 +1,196 @@ +/* Shared library support for RS/6000 (xcoff) object files, for GDB. + Copyright 1991, 1992, 1995, 1996, 1999, 2000, 2001 + Free Software Foundation, Inc. + Contributed by IBM Corporation. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "bfd.h" +#include "xcoffsolib.h" +#include "inferior.h" +#include "gdbcmd.h" +#include "symfile.h" +#include "frame.h" +#include "gdb_regex.h" + + +/* If ADDR lies in a shared library, return its name. + Note that returned name points to static data whose content is overwritten + by each call. */ + +char * +xcoff_solib_address (CORE_ADDR addr) +{ + static char *buffer = NULL; + struct vmap *vp = vmap; + + /* The first vmap entry is for the exec file. */ + + if (vp == NULL) + return NULL; + for (vp = vp->nxt; vp; vp = vp->nxt) + if (vp->tstart <= addr && addr < vp->tend) + { + xfree (buffer); + xasprintf (&buffer, "%s%s%s%s", + vp->name, + *vp->member ? "(" : "", + vp->member, + *vp->member ? ")" : ""); + return buffer; + } + return NULL; +} + +static void solib_info (char *, int); +static void sharedlibrary_command (char *pattern, int from_tty); + +static void +solib_info (char *args, int from_tty) +{ + struct vmap *vp = vmap; + + /* Check for new shared libraries loaded with load (). */ + if (! ptid_equal (inferior_ptid, null_ptid)) + xcoff_relocate_symtab (PIDGET (inferior_ptid)); + + if (vp == NULL || vp->nxt == NULL) + { + printf_unfiltered ("No shared libraries loaded at this time.\n"); + return; + } + + /* Skip over the first vmap, it is the main program, always loaded. */ + vp = vp->nxt; + + printf_unfiltered ("\ +Text Range Data Range Syms Shared Object Library\n"); + + for (; vp != NULL; vp = vp->nxt) + { + printf_unfiltered ("0x%s-0x%s 0x%s-0x%s %s %s%s%s%s\n", + paddr (vp->tstart),paddr (vp->tend), + paddr (vp->dstart), paddr (vp->dend), + vp->loaded ? "Yes" : "No ", + vp->name, + *vp->member ? "(" : "", + vp->member, + *vp->member ? ")" : ""); + } +} + +static void +sharedlibrary_command (char *pattern, int from_tty) +{ + dont_repeat (); + + /* Check for new shared libraries loaded with load (). */ + if (! ptid_equal (inferior_ptid, null_ptid)) + xcoff_relocate_symtab (PIDGET (inferior_ptid)); + + if (pattern) + { + char *re_err = re_comp (pattern); + + if (re_err) + error ("Invalid regexp: %s", re_err); + } + + /* Walk the list of currently loaded shared libraries, and read + symbols for any that match the pattern --- or any whose symbols + aren't already loaded, if no pattern was given. */ + { + int any_matches = 0; + int loaded_any_symbols = 0; + struct vmap *vp = vmap; + + if (!vp) + return; + + /* skip over the first vmap, it is the main program, always loaded. */ + for (vp = vp->nxt; vp; vp = vp->nxt) + if (! pattern + || re_exec (vp->name) + || (*vp->member && re_exec (vp->member))) + { + any_matches = 1; + + if (vp->loaded) + { + if (from_tty) + printf_unfiltered ("Symbols already loaded for %s\n", + vp->name); + } + else + { + if (vmap_add_symbols (vp)) + loaded_any_symbols = 1; + } + } + + if (from_tty && pattern && ! any_matches) + printf_unfiltered + ("No loaded shared libraries match the pattern `%s'.\n", pattern); + + if (loaded_any_symbols) + { + /* Getting new symbols may change our opinion about what is + frameless. */ + reinit_frame_cache (); + } + } +} + +/* LOCAL FUNCTION + + no_shared_libraries -- handle command to explicitly discard symbols + from shared libraries. + + DESCRIPTION + + Implements the command "nosharedlibrary", which discards symbols + that have been auto-loaded from shared libraries. Symbols from + shared libraries that were added by explicit request of the user + are not discarded. Also called from remote.c. */ + +void +no_shared_libraries (char *ignored, int from_tty) +{ + /* FIXME */ +} + +void +_initialize_xcoffsolib (void) +{ + add_com ("sharedlibrary", class_files, sharedlibrary_command, + "Load shared object library symbols for files matching REGEXP."); + add_info ("sharedlibrary", solib_info, + "Status of loaded shared object libraries"); + + add_show_from_set + (add_set_cmd ("auto-solib-add", class_support, var_boolean, + (char *) &auto_solib_add, + "Set autoloading of shared library symbols.\n\ +If \"on\", symbols from all shared object libraries will be loaded\n\ +automatically when the inferior begins execution, when the dynamic linker\n\ +informs gdb that a new library has been loaded, or when attaching to the\n\ +inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", + &setlist), + &showlist); +} diff --git a/contrib/gdb/gdb/xmodem.c b/contrib/gdb/gdb/xmodem.c new file mode 100644 index 00000000000..7b8d77d1055 --- /dev/null +++ b/contrib/gdb/gdb/xmodem.c @@ -0,0 +1,275 @@ +/* XMODEM support for GDB, the GNU debugger. + Copyright 1995, 2000, 2001 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "serial.h" +#include "target.h" +#include "xmodem.h" + +/* These definitions are for xmodem protocol. */ + +#define SOH 0x01 +#define STX 0x02 +#define ACK 0x06 +#define NAK 0x15 +#define EOT 0x04 +#define CANCEL 0x18 + +static int blknum; /* XMODEM block number */ +static int crcflag; /* Sez we are using CRC's instead of cksums */ + +static int +readchar (struct serial *desc, int timeout) +{ + int c; + + c = serial_readchar (desc, timeout); + + if (remote_debug > 0) + fputc_unfiltered (c, gdb_stdlog); + + if (c >= 0) + return c; + + if (c == SERIAL_TIMEOUT) + error ("Timeout reading from remote system."); + + perror_with_name ("xmodem.c:readchar()"); +} + +#define CRC16 0x1021 /* Generator polynomial (X^16 + X^12 + X^5 + 1) */ + +static unsigned short *crctab; + +/* Call this to init the fast CRC-16 calculation table. */ + +static void +crcinit (void) +{ + static int crctab_inited = 0; + int val; + + if (crctab_inited == 1) + return; + + crctab = xmalloc (256 * sizeof (short)); + + for (val = 0; val <= 255; val++) + { + int i; + unsigned int crc; + + crc = val << 8; + + for (i = 0; i < 8; ++i) + { + crc <<= 1; + + if (crc & 0x10000) + crc ^= CRC16; + } + + crctab[val] = crc; + } + + crctab_inited = 1; +} + +/* Calculate a CRC-16 for the LEN byte message pointed at by P. */ + +static unsigned short +docrc (unsigned char *p, int len) +{ + unsigned short crc = 0; + + while (len-- > 0) + crc = (crc << 8) ^ crctab[(crc >> 8) ^ *p++]; + + return crc; +} + +/* Start up the transmit process. Reset state variables. Wait for receiver to + send NAK or CRC request. */ + +int +xmodem_init_xfer (struct serial *desc) +{ + int c; + int i; + + blknum = 1; + crcflag = 0; + crcinit (); + + for (i = 1; i <= 10; i++) + { + c = readchar (desc, 6); + + switch (c) + { + case 'C': + crcflag = 1; + case NAK: + return 0; + default: + fprintf_unfiltered (gdb_stderr, "xmodem_init_xfer: Got unexpected character %c (0%o)\n", c, c); + continue; + case CANCEL: /* target aborted load */ + fprintf_unfiltered (gdb_stderr, "Got a CANCEL from the target.\n"); + continue; + } + } + error ("xmodem_init_xfer: Too many unexpected characters."); +} + +/* Take 128 bytes of data and make a packet out of it. + + * Each packet looks like this: + * +-----+-------+-------+------+-----+ + * | SOH | Seq1. | Seq2. | data | SUM | + * +-----+-------+-------+------+-----+ + * SOH = 0x01 + * Seq1 = The sequence number. + * Seq2 = The complement of the sequence number. + * Data = A 128 bytes of data. + * SUM = Add the contents of the 128 bytes and use the low-order + * 8 bits of the result. + * + * send_xmodem_packet fills in the XMODEM fields of PACKET and sends it to the + * remote system. PACKET must be XMODEM_PACKETSIZE bytes long. The data must + * start 3 bytes after the beginning of the packet to leave room for the + * XMODEM header. LEN is the length of the data portion of the packet (and + * must be <= 128 bytes). If it is < 128 bytes, ^Z padding will be added. + */ + +void +xmodem_send_packet (struct serial *desc, unsigned char *packet, int len, int hashmark) +{ + int i; + int retries; + int pktlen; + int datasize; + + /* build the packet header */ + + packet[1] = blknum; + packet[2] = ~blknum; + + blknum++; + + if (len <= XMODEM_DATASIZE) + { + packet[0] = SOH; + datasize = XMODEM_DATASIZE; + } + else if (len <= XMODEM_1KDATASIZE) + { + packet[0] = STX; + datasize = XMODEM_1KDATASIZE; + } + else + internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Packet way too large */ + + /* Add ^Z padding if packet < 128 (or 1024) bytes */ + + memset (packet + 3 + len, '\026', datasize - len); + + if (crcflag) + { + int crc; + + crc = docrc (packet + 3, datasize); + + packet[3 + datasize] = crc >> 8; + packet[3 + datasize + 1] = crc; + pktlen = datasize + 5; + } + else + { + int sum; + + sum = 0; + for (i = 3; i < datasize + 3; i++) + sum += packet[i]; + + packet[3 + datasize] = sum; /* add the checksum */ + pktlen = datasize + 4; + } + + for (retries = 3; retries >= 0; retries--) + { + int c; + + serial_write (desc, packet, pktlen); + + c = readchar (desc, 3); + switch (c) + { + case ACK: + return; + case NAK: + if (!hashmark) + continue; + putchar_unfiltered ('-'); + gdb_flush (gdb_stdout); + continue; + case CANCEL: + error ("xmodem_send_packet: Transfer aborted by receiver."); + default: + fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c); + continue; + } + } + + serial_write (desc, "\004", 1); /* Send an EOT */ + + error ("xmodem_send_packet: Excessive retries."); +} + +/* Finish off the transfer. Send out the EOT, and wait for an ACK. */ + +void +xmodem_finish_xfer (struct serial *desc) +{ + int retries; + + for (retries = 10; retries >= 0; retries--) + { + int c; + + serial_write (desc, "\004", 1); /* Send an EOT */ + + c = readchar (desc, 3); + switch (c) + { + case ACK: + return; + case NAK: + continue; + case CANCEL: + error ("xmodem_finish_xfer: Transfer aborted by receiver."); + default: + fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c); + continue; + } + } + + error ("xmodem_finish_xfer: Excessive retries."); +} diff --git a/contrib/gdb/gdb/xmodem.h b/contrib/gdb/gdb/xmodem.h new file mode 100644 index 00000000000..83aa24f71ec --- /dev/null +++ b/contrib/gdb/gdb/xmodem.h @@ -0,0 +1,32 @@ +/* XMODEM support for GDB, the GNU debugger. + Copyright 1995, 2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +struct serial; + +int xmodem_init_xfer (struct serial *desc); +void send_xmodem_packet (struct serial *desc, unsigned char *packet, int len, + int hashmark); +void xmodem_finish_xfer (struct serial *desc); + +#define XMODEM_DATASIZE 128 /* The data size is ALWAYS 128 */ +#define XMODEM_1KDATASIZE 1024 /* Unless it's 1024!!! */ +#define XMODEM_PACKETSIZE 133 /* data + packet headers and crc */ +#define XMODEM_1KPACKETSIZE 1024 + 5 /* data + packet headers and crc */ +#define XMODEM_DATAOFFSET 3 /* Offset to start of actual data */ diff --git a/contrib/gdb/gettext.m4 b/contrib/gdb/gettext.m4 new file mode 100644 index 00000000000..6735696cb9a --- /dev/null +++ b/contrib/gdb/gettext.m4 @@ -0,0 +1,344 @@ +# This file is derived from `gettext.m4'. The difference is that the +# included macros assume Cygnus-style source and build trees. + +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 3 + +AC_DEFUN([CY_WITH_NLS], + [AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + USE_INCLUDED_LIBINTL=no + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested]) + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, + [AC_TRY_LINK([#include ], [return (int) gettext ("")], + gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) + + if test "$gt_cv_func_gettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for gettext in libintl], + gt_cv_func_gettext_libintl, + [AC_TRY_LINK([], [return (int) gettext ("")], + gt_cv_func_gettext_libintl=yes, + gt_cv_func_gettext_libintl=no)])]) + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT, 1, + [Define as 1 if you have gettext and don't want to use GNU gettext.]) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + ]) + + dnl In the standard gettext, we would now check for catgets. + dnl However, we never want to use catgets for our releases. + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_SUBST(MSGFMT) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/../intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext programs is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN([CY_GNU_GETTEXT], + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h values.h sys/param.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next]) + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + AC_CHECK_FUNCS(stpcpy) + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function]) + fi + + AM_LC_MESSAGES + CY_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl The reference to in the installed file + dnl must be resolved because we cannot expect the users of this + dnl to define HAVE_LOCALE_H. + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include " + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header . Take care yourself. */" + fi + AC_SUBST(INCLUDE_LOCALE_H) + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux libc-5 and the normal X/Open format + if test -f $srcdir/po2tbl.sed.in; then + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed + fi + dnl po2tbl.sed is always needed. + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/po2tbl.sed.in > po2tbl.sed + fi + + dnl In the intl/Makefile.in we have a special dependency which makes + dnl only sense for gettext. We comment this out for non-gettext + dnl packages. + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + AC_SUBST(GT_NO) + AC_SUBST(GT_YES) + + MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs" + AC_SUBST(MKINSTALLDIRS) + + dnl *** For now the libtool support in intl/Makefile is not for real. + l= + AC_SUBST(l) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. But only do this if the po directory + dnl exists in srcdir and contains POTFILES.in. + if test -f $srcdir/po/POTFILES.in; then + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + fi + ]) + +# Search path for a program which passes the given test. +# Ulrich Drepper , 1996. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# Check whether LC_MESSAGES is available in . +# Ulrich Drepper , 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +AC_DEFUN([AM_LC_MESSAGES], + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your locale.h file contains LC_MESSAGES.]) + fi + fi]) diff --git a/contrib/gdb/include/COPYING b/contrib/gdb/include/COPYING new file mode 100644 index 00000000000..d60c31a97a5 --- /dev/null +++ b/contrib/gdb/include/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/contrib/gdb/include/MAINTAINERS b/contrib/gdb/include/MAINTAINERS new file mode 100644 index 00000000000..d59a3bd7f88 --- /dev/null +++ b/contrib/gdb/include/MAINTAINERS @@ -0,0 +1 @@ +See ../binutils/MAINTAINERS diff --git a/contrib/gdb/include/alloca-conf.h b/contrib/gdb/include/alloca-conf.h new file mode 100644 index 00000000000..9c3eea396c1 --- /dev/null +++ b/contrib/gdb/include/alloca-conf.h @@ -0,0 +1,24 @@ +#include "config.h" + +#if defined(__GNUC__) && !defined(C_ALLOCA) +# ifndef alloca +# define alloca __builtin_alloca +# endif +#else /* ! defined (__GNUC__) */ +# ifdef _AIX + #pragma alloca +# else +# if defined(HAVE_ALLOCA_H) && !defined(C_ALLOCA) +# include +# else /* ! defined (HAVE_ALLOCA_H) */ +# ifdef __STDC__ +extern PTR alloca (size_t); +# else /* ! defined (__STDC__) */ +extern PTR alloca (); +# endif /* ! defined (__STDC__) */ +# endif /* ! defined (HAVE_ALLOCA_H) */ +# ifdef _WIN32 +# include +# endif +# endif /* ! defined (_AIX) */ +#endif /* ! defined (__GNUC__) */ diff --git a/contrib/gdb/include/ansidecl.h b/contrib/gdb/include/ansidecl.h new file mode 100644 index 00000000000..d2c87768ce2 --- /dev/null +++ b/contrib/gdb/include/ansidecl.h @@ -0,0 +1,315 @@ +/* ANSI and traditional C compatability macros + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* ANSI and traditional C compatibility macros + + ANSI C is assumed if __STDC__ is #defined. + + Macro ANSI C definition Traditional C definition + ----- ---- - ---------- ----------- - ---------- + ANSI_PROTOTYPES 1 not defined + PTR `void *' `char *' + PTRCONST `void *const' `char *' + LONG_DOUBLE `long double' `double' + const not defined `' + volatile not defined `' + signed not defined `' + VA_START(ap, var) va_start(ap, var) va_start(ap) + + Note that it is safe to write "void foo();" indicating a function + with no return value, in all K+R compilers we have been able to test. + + For declaring functions with prototypes, we also provide these: + + PARAMS ((prototype)) + -- for functions which take a fixed number of arguments. Use this + when declaring the function. When defining the function, write a + K+R style argument list. For example: + + char *strcpy PARAMS ((char *dest, char *source)); + ... + char * + strcpy (dest, source) + char *dest; + char *source; + { ... } + + + VPARAMS ((prototype, ...)) + -- for functions which take a variable number of arguments. Use + PARAMS to declare the function, VPARAMS to define it. For example: + + int printf PARAMS ((const char *format, ...)); + ... + int + printf VPARAMS ((const char *format, ...)) + { + ... + } + + For writing functions which take variable numbers of arguments, we + also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These + hide the differences between K+R and C89 more + thoroughly than the simple VA_START() macro mentioned above. + + VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. + Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls + corresponding to the list of fixed arguments. Then use va_arg + normally to get the variable arguments, or pass your va_list object + around. You do not declare the va_list yourself; VA_OPEN does it + for you. + + Here is a complete example: + + int + printf VPARAMS ((const char *format, ...)) + { + int result; + + VA_OPEN (ap, format); + VA_FIXEDARG (ap, const char *, format); + + result = vfprintf (stdout, format, ap); + VA_CLOSE (ap); + + return result; + } + + + You can declare variables either before or after the VA_OPEN, + VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning + and end of a block. They must appear at the same nesting level, + and any variables declared after VA_OPEN go out of scope at + VA_CLOSE. Unfortunately, with a K+R compiler, that includes the + argument list. You can have multiple instances of VA_OPEN/VA_CLOSE + pairs in a single function in case you need to traverse the + argument list more than once. + + For ease of writing code which uses GCC extensions but needs to be + portable to other compilers, we provide the GCC_VERSION macro that + simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various + wrappers around __attribute__. Also, __extension__ will be #defined + to nothing if it doesn't work. See below. + + This header also defines a lot of obsolete macros: + CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, + AND, DOTS, NOARGS. Don't use them. */ + +#ifndef _ANSIDECL_H +#define _ANSIDECL_H 1 + +/* Every source file includes this file, + so they will all get the switch for lint. */ +/* LINTLIBRARY */ + +/* Using MACRO(x,y) in cpp #if conditionals does not work with some + older preprocessors. Thus we can't define something like this: + +#define HAVE_GCC_VERSION(MAJOR, MINOR) \ + (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) + +and then test "#if HAVE_GCC_VERSION(2,7)". + +So instead we use the macro below and test it against specific values. */ + +/* This macro simplifies testing whether we are using gcc, and if it + is of a particular minimum version. (Both major & minor numbers are + significant.) This macro will evaluate to 0 if we are not using + gcc at all. */ +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) +#endif /* GCC_VERSION */ + +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus)) +/* All known AIX compilers implement these things (but don't always + define __STDC__). The RISC/OS MIPS compiler defines these things + in SVR4 mode, but does not define __STDC__. */ +/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other + C++ compilers, does not define __STDC__, though it acts as if this + was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ + +#define ANSI_PROTOTYPES 1 +#define PTR void * +#define PTRCONST void *const +#define LONG_DOUBLE long double + +#define PARAMS(ARGS) ARGS +#define VPARAMS(ARGS) ARGS +#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) + +/* variadic function helper macros */ +/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's + use without inhibiting further decls and without declaring an + actual variable. */ +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy +#define VA_CLOSE(AP) } va_end(AP); } +#define VA_FIXEDARG(AP, T, N) struct Qdmy + +#undef const +#undef volatile +#undef signed + +/* inline requires special treatment; it's in C99, and GCC >=2.7 supports + it too, but it's not in C89. */ +#undef inline +#if __STDC_VERSION__ > 199901L +/* it's a keyword */ +#else +# if GCC_VERSION >= 2007 +# define inline __inline__ /* __inline__ prevents -pedantic warnings */ +# else +# define inline /* nothing */ +# endif +#endif + +/* These are obsolete. Do not use. */ +#ifndef IN_GCC +#define CONST const +#define VOLATILE volatile +#define SIGNED signed + +#define PROTO(type, name, arglist) type name arglist +#define EXFUN(name, proto) name proto +#define DEFUN(name, arglist, args) name(args) +#define DEFUN_VOID(name) name(void) +#define AND , +#define DOTS , ... +#define NOARGS void +#endif /* ! IN_GCC */ + +#else /* Not ANSI C. */ + +#undef ANSI_PROTOTYPES +#define PTR char * +#define PTRCONST PTR +#define LONG_DOUBLE double + +#define PARAMS(args) () +#define VPARAMS(args) (va_alist) va_dcl +#define VA_START(va_list, var) va_start(va_list) + +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy +#define VA_CLOSE(AP) } va_end(AP); } +#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) + +/* some systems define these in header files for non-ansi mode */ +#undef const +#undef volatile +#undef signed +#undef inline +#define const +#define volatile +#define signed +#define inline + +#ifndef IN_GCC +#define CONST +#define VOLATILE +#define SIGNED + +#define PROTO(type, name, arglist) type name () +#define EXFUN(name, proto) name() +#define DEFUN(name, arglist, args) name arglist args; +#define DEFUN_VOID(name) name() +#define AND ; +#define DOTS +#define NOARGS +#endif /* ! IN_GCC */ + +#endif /* ANSI C. */ + +/* Define macros for some gcc attributes. This permits us to use the + macros freely, and know that they will come into play for the + version of gcc in which they are supported. */ + +#if (GCC_VERSION < 2007) +# define __attribute__(x) +#endif + +/* Attribute __malloc__ on functions was valid as of gcc 2.96. */ +#ifndef ATTRIBUTE_MALLOC +# if (GCC_VERSION >= 2096) +# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define ATTRIBUTE_MALLOC +# endif /* GNUC >= 2.96 */ +#endif /* ATTRIBUTE_MALLOC */ + +/* Attributes on labels were valid as of gcc 2.93. */ +#ifndef ATTRIBUTE_UNUSED_LABEL +# if (GCC_VERSION >= 2093) +# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED +# else +# define ATTRIBUTE_UNUSED_LABEL +# endif /* GNUC >= 2.93 */ +#endif /* ATTRIBUTE_UNUSED_LABEL */ + +#ifndef ATTRIBUTE_UNUSED +#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#endif /* ATTRIBUTE_UNUSED */ + +#ifndef ATTRIBUTE_NORETURN +#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) +#endif /* ATTRIBUTE_NORETURN */ + +/* Attribute `nonnull' was valid as of gcc 3.3. */ +#ifndef ATTRIBUTE_NONNULL +# if (GCC_VERSION >= 3003) +# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) +# else +# define ATTRIBUTE_NONNULL(m) +# endif /* GNUC >= 3.3 */ +#endif /* ATTRIBUTE_NONNULL */ + +/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. + This was the case for the `printf' format attribute by itself + before GCC 3.3, but as of 3.3 we need to add the `nonnull' + attribute to retain this behavior. */ +#ifndef ATTRIBUTE_PRINTF +#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) +#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) +#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) +#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) +#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) +#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) +#endif /* ATTRIBUTE_PRINTF */ + +/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A + NULL format specifier was allowed as of gcc 3.3. */ +#ifndef ATTRIBUTE_NULL_PRINTF +# if (GCC_VERSION >= 3003) +# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) +# else +# define ATTRIBUTE_NULL_PRINTF(m, n) +# endif /* GNUC >= 3.3 */ +# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) +# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) +# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) +# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) +# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) +#endif /* ATTRIBUTE_NULL_PRINTF */ + +/* We use __extension__ in some places to suppress -pedantic warnings + about GCC extensions. This feature didn't work properly before + gcc 2.8. */ +#if GCC_VERSION < 2008 +#define __extension__ +#endif + +#endif /* ansidecl.h */ diff --git a/contrib/gdb/include/bfdlink.h b/contrib/gdb/include/bfdlink.h new file mode 100644 index 00000000000..a989f64f4ca --- /dev/null +++ b/contrib/gdb/include/bfdlink.h @@ -0,0 +1,686 @@ +/* bfdlink.h -- header file for BFD link routines + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. + Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef BFDLINK_H +#define BFDLINK_H + +/* Which symbols to strip during a link. */ +enum bfd_link_strip +{ + strip_none, /* Don't strip any symbols. */ + strip_debugger, /* Strip debugging symbols. */ + strip_some, /* keep_hash is the list of symbols to keep. */ + strip_all /* Strip all symbols. */ +}; + +/* Which local symbols to discard during a link. This is irrelevant + if strip_all is used. */ +enum bfd_link_discard +{ + discard_sec_merge, /* Discard local temporary symbols in SEC_MERGE + sections. */ + discard_none, /* Don't discard any locals. */ + discard_l, /* Discard local temporary symbols. */ + discard_all /* Discard all locals. */ +}; + +/* Describes the type of hash table entry structure being used. + Different hash table structure have different fields and so + support different linking features. */ +enum bfd_link_hash_table_type + { + bfd_link_generic_hash_table, + bfd_link_elf_hash_table + }; + +/* These are the possible types of an entry in the BFD link hash + table. */ + +enum bfd_link_hash_type +{ + bfd_link_hash_new, /* Symbol is new. */ + bfd_link_hash_undefined, /* Symbol seen before, but undefined. */ + bfd_link_hash_undefweak, /* Symbol is weak and undefined. */ + bfd_link_hash_defined, /* Symbol is defined. */ + bfd_link_hash_defweak, /* Symbol is weak and defined. */ + bfd_link_hash_common, /* Symbol is common. */ + bfd_link_hash_indirect, /* Symbol is an indirect link. */ + bfd_link_hash_warning /* Like indirect, but warn if referenced. */ +}; + +enum bfd_link_common_skip_ar_aymbols +{ + bfd_link_common_skip_none, + bfd_link_common_skip_text, + bfd_link_common_skip_data, + bfd_link_common_skip_all +}; + +/* The linking routines use a hash table which uses this structure for + its elements. */ + +struct bfd_link_hash_entry +{ + /* Base hash table entry structure. */ + struct bfd_hash_entry root; + + /* Type of this entry. */ + enum bfd_link_hash_type type; + + /* Undefined and common symbols are kept in a linked list through + this field. This field is not in the union because that would + force us to remove entries from the list when we changed their + type, which would force the list to be doubly linked, which would + waste more memory. When an undefined or common symbol is + created, it should be added to this list, the head of which is in + the link hash table itself. As symbols are defined, they need + not be removed from the list; anything which reads the list must + doublecheck the symbol type. + + Weak symbols are not kept on this list. + + Defined and defweak symbols use this field as a reference marker. + If the field is not NULL, or this structure is the tail of the + undefined symbol list, the symbol has been referenced. If the + symbol is undefined and becomes defined, this field will + automatically be non-NULL since the symbol will have been on the + undefined symbol list. */ + struct bfd_link_hash_entry *und_next; + + /* A union of information depending upon the type. */ + union + { + /* Nothing is kept for bfd_hash_new. */ + /* bfd_link_hash_undefined, bfd_link_hash_undefweak. */ + struct + { + bfd *abfd; /* BFD symbol was found in. */ + } undef; + /* bfd_link_hash_defined, bfd_link_hash_defweak. */ + struct + { + bfd_vma value; /* Symbol value. */ + asection *section; /* Symbol section. */ + } def; + /* bfd_link_hash_indirect, bfd_link_hash_warning. */ + struct + { + struct bfd_link_hash_entry *link; /* Real symbol. */ + const char *warning; /* Warning (bfd_link_hash_warning only). */ + } i; + /* bfd_link_hash_common. */ + struct + { + /* The linker needs to know three things about common + symbols: the size, the alignment, and the section in + which the symbol should be placed. We store the size + here, and we allocate a small structure to hold the + section and the alignment. The alignment is stored as a + power of two. We don't store all the information + directly because we don't want to increase the size of + the union; this structure is a major space user in the + linker. */ + bfd_size_type size; /* Common symbol size. */ + struct bfd_link_hash_common_entry + { + unsigned int alignment_power; /* Alignment. */ + asection *section; /* Symbol section. */ + } *p; + } c; + } u; +}; + +/* This is the link hash table. It is a derived class of + bfd_hash_table. */ + +struct bfd_link_hash_table +{ + /* The hash table itself. */ + struct bfd_hash_table table; + /* The back end which created this hash table. This indicates the + type of the entries in the hash table, which is sometimes + important information when linking object files of different + types together. */ + const bfd_target *creator; + /* A linked list of undefined and common symbols, linked through the + next field in the bfd_link_hash_entry structure. */ + struct bfd_link_hash_entry *undefs; + /* Entries are added to the tail of the undefs list. */ + struct bfd_link_hash_entry *undefs_tail; + /* The type of the link hash table. */ + enum bfd_link_hash_table_type type; +}; + +/* Look up an entry in a link hash table. If FOLLOW is TRUE, this + follows bfd_link_hash_indirect and bfd_link_hash_warning links to + the real symbol. */ +extern struct bfd_link_hash_entry *bfd_link_hash_lookup + (struct bfd_link_hash_table *, const char *, bfd_boolean create, + bfd_boolean copy, bfd_boolean follow); + +/* Look up an entry in the main linker hash table if the symbol might + be wrapped. This should only be used for references to an + undefined symbol, not for definitions of a symbol. */ + +extern struct bfd_link_hash_entry *bfd_wrapped_link_hash_lookup + (bfd *, struct bfd_link_info *, const char *, bfd_boolean, + bfd_boolean, bfd_boolean); + +/* Traverse a link hash table. */ +extern void bfd_link_hash_traverse + (struct bfd_link_hash_table *, + bfd_boolean (*) (struct bfd_link_hash_entry *, void *), + void *); + +/* Add an entry to the undefs list. */ +extern void bfd_link_add_undef + (struct bfd_link_hash_table *, struct bfd_link_hash_entry *); + +struct bfd_sym_chain +{ + struct bfd_sym_chain *next; + const char *name; +}; + +/* How to handle unresolved symbols. + There are four possibilities which are enumerated below: */ +enum report_method +{ + /* This is the initial value when then link_info structure is created. + It allows the various stages of the linker to determine whether they + allowed to set the value. */ + RM_NOT_YET_SET = 0, + RM_IGNORE, + RM_GENERATE_WARNING, + RM_GENERATE_ERROR +}; + +/* This structure holds all the information needed to communicate + between BFD and the linker when doing a link. */ + +struct bfd_link_info +{ + /* TRUE if BFD should generate a relocatable object file. */ + unsigned int relocatable: 1; + + /* TRUE if BFD should generate relocation information in the final + executable. */ + unsigned int emitrelocations: 1; + + /* TRUE if BFD should generate a "task linked" object file, + similar to relocatable but also with globals converted to + statics. */ + unsigned int task_link: 1; + + /* TRUE if BFD should generate a shared object. */ + unsigned int shared: 1; + + /* TRUE if BFD should pre-bind symbols in a shared object. */ + unsigned int symbolic: 1; + + /* TRUE if BFD should export all symbols in the dynamic symbol table + of an executable, rather than only those used. */ + unsigned int export_dynamic: 1; + + /* TRUE if shared objects should be linked directly, not shared. */ + unsigned int static_link: 1; + + /* TRUE if the output file should be in a traditional format. This + is equivalent to the setting of the BFD_TRADITIONAL_FORMAT flag + on the output file, but may be checked when reading the input + files. */ + unsigned int traditional_format: 1; + + /* TRUE if we want to produced optimized output files. This might + need much more time and therefore must be explicitly selected. */ + unsigned int optimize: 1; + + /* TRUE if ok to have multiple definition. */ + unsigned int allow_multiple_definition: 1; + + /* TRUE if ok to have version with no definition. */ + unsigned int allow_undefined_version: 1; + + /* TRUE if symbols should be retained in memory, FALSE if they + should be freed and reread. */ + unsigned int keep_memory: 1; + + /* TRUE if every symbol should be reported back via the notice + callback. */ + unsigned int notice_all: 1; + + /* TRUE if executable should not contain copy relocs. + Setting this true may result in a non-sharable text segment. */ + unsigned int nocopyreloc: 1; + + /* TRUE if the new ELF dynamic tags are enabled. */ + unsigned int new_dtags: 1; + + /* TRUE if non-PLT relocs should be merged into one reloc section + and sorted so that relocs against the same symbol come together. */ + unsigned int combreloc: 1; + + /* TRUE if .eh_frame_hdr section and PT_GNU_EH_FRAME ELF segment + should be created. */ + unsigned int eh_frame_hdr: 1; + + /* TRUE if global symbols in discarded sections should be stripped. */ + unsigned int strip_discarded: 1; + + /* TRUE if the final relax pass is needed. */ + unsigned int need_relax_finalize: 1; + + /* TRUE if generating a position independent executable. */ + unsigned int pie: 1; + + /* TRUE if generating an executable, position independent or not. */ + unsigned int executable : 1; + + /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W|PF_X + flags. */ + unsigned int execstack: 1; + + /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W + flags. */ + unsigned int noexecstack: 1; + + /* What to do with unresolved symbols in an object file. + When producing static binaries the default is GENERATE_ERROR. + When producing dynamic binaries the default is IGNORE. The + assumption with dynamic binaries is that the reference will be + resolved at load/execution time. */ + enum report_method unresolved_syms_in_objects; + + /* What to do with unresolved symbols in a shared library. + The same defaults apply. */ + enum report_method unresolved_syms_in_shared_libs; + + /* Which symbols to strip. */ + enum bfd_link_strip strip; + + /* Which local symbols to discard. */ + enum bfd_link_discard discard; + + /* Criteria for skipping symbols when detemining + whether to include an object from an archive. */ + enum bfd_link_common_skip_ar_aymbols common_skip_ar_aymbols; + + /* Function callbacks. */ + const struct bfd_link_callbacks *callbacks; + + /* Hash table handled by BFD. */ + struct bfd_link_hash_table *hash; + + /* Hash table of symbols to keep. This is NULL unless strip is + strip_some. */ + struct bfd_hash_table *keep_hash; + + /* Hash table of symbols to report back via the notice callback. If + this is NULL, and notice_all is FALSE, then no symbols are + reported back. */ + struct bfd_hash_table *notice_hash; + + /* Hash table of symbols which are being wrapped (the --wrap linker + option). If this is NULL, no symbols are being wrapped. */ + struct bfd_hash_table *wrap_hash; + + /* The list of input BFD's involved in the link. These are chained + together via the link_next field. */ + bfd *input_bfds; + + /* If a symbol should be created for each input BFD, this is section + where those symbols should be placed. It must be a section in + the output BFD. It may be NULL, in which case no such symbols + will be created. This is to support CREATE_OBJECT_SYMBOLS in the + linker command language. */ + asection *create_object_symbols_section; + + /* List of global symbol names that are starting points for marking + sections against garbage collection. */ + struct bfd_sym_chain *gc_sym_list; + + /* If a base output file is wanted, then this points to it */ + void *base_file; + + /* The function to call when the executable or shared object is + loaded. */ + const char *init_function; + + /* The function to call when the executable or shared object is + unloaded. */ + const char *fini_function; + + /* Non-zero if auto-import thunks for DATA items in pei386 DLLs + should be generated/linked against. Set to 1 if this feature + is explicitly requested by the user, -1 if enabled by default. */ + int pei386_auto_import; + + /* Non-zero if runtime relocs for DATA items with non-zero addends + in pei386 DLLs should be generated. Set to 1 if this feature + is explicitly requested by the user, -1 if enabled by default. */ + int pei386_runtime_pseudo_reloc; + + /* How many spare .dynamic DT_NULL entries should be added? */ + unsigned int spare_dynamic_tags; + + /* May be used to set DT_FLAGS for ELF. */ + bfd_vma flags; + + /* May be used to set DT_FLAGS_1 for ELF. */ + bfd_vma flags_1; +}; + +/* This structures holds a set of callback functions. These are + called by the BFD linker routines. The first argument to each + callback function is the bfd_link_info structure being used. Each + function returns a boolean value. If the function returns FALSE, + then the BFD function which called it will return with a failure + indication. */ + +struct bfd_link_callbacks +{ + /* A function which is called when an object is added from an + archive. ABFD is the archive element being added. NAME is the + name of the symbol which caused the archive element to be pulled + in. */ + bfd_boolean (*add_archive_element) + (struct bfd_link_info *, bfd *abfd, const char *name); + /* A function which is called when a symbol is found with multiple + definitions. NAME is the symbol which is defined multiple times. + OBFD is the old BFD, OSEC is the old section, OVAL is the old + value, NBFD is the new BFD, NSEC is the new section, and NVAL is + the new value. OBFD may be NULL. OSEC and NSEC may be + bfd_com_section or bfd_ind_section. */ + bfd_boolean (*multiple_definition) + (struct bfd_link_info *, const char *name, + bfd *obfd, asection *osec, bfd_vma oval, + bfd *nbfd, asection *nsec, bfd_vma nval); + /* A function which is called when a common symbol is defined + multiple times. NAME is the symbol appearing multiple times. + OBFD is the BFD of the existing symbol; it may be NULL if this is + not known. OTYPE is the type of the existing symbol, which may + be bfd_link_hash_defined, bfd_link_hash_defweak, + bfd_link_hash_common, or bfd_link_hash_indirect. If OTYPE is + bfd_link_hash_common, OSIZE is the size of the existing symbol. + NBFD is the BFD of the new symbol. NTYPE is the type of the new + symbol, one of bfd_link_hash_defined, bfd_link_hash_common, or + bfd_link_hash_indirect. If NTYPE is bfd_link_hash_common, NSIZE + is the size of the new symbol. */ + bfd_boolean (*multiple_common) + (struct bfd_link_info *, const char *name, + bfd *obfd, enum bfd_link_hash_type otype, bfd_vma osize, + bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize); + /* A function which is called to add a symbol to a set. ENTRY is + the link hash table entry for the set itself (e.g., + __CTOR_LIST__). RELOC is the relocation to use for an entry in + the set when generating a relocatable file, and is also used to + get the size of the entry when generating an executable file. + ABFD, SEC and VALUE identify the value to add to the set. */ + bfd_boolean (*add_to_set) + (struct bfd_link_info *, struct bfd_link_hash_entry *entry, + bfd_reloc_code_real_type reloc, bfd *abfd, asection *sec, bfd_vma value); + /* A function which is called when the name of a g++ constructor or + destructor is found. This is only called by some object file + formats. CONSTRUCTOR is TRUE for a constructor, FALSE for a + destructor. This will use BFD_RELOC_CTOR when generating a + relocatable file. NAME is the name of the symbol found. ABFD, + SECTION and VALUE are the value of the symbol. */ + bfd_boolean (*constructor) + (struct bfd_link_info *, bfd_boolean constructor, const char *name, + bfd *abfd, asection *sec, bfd_vma value); + /* A function which is called to issue a linker warning. For + example, this is called when there is a reference to a warning + symbol. WARNING is the warning to be issued. SYMBOL is the name + of the symbol which triggered the warning; it may be NULL if + there is none. ABFD, SECTION and ADDRESS identify the location + which trigerred the warning; either ABFD or SECTION or both may + be NULL if the location is not known. */ + bfd_boolean (*warning) + (struct bfd_link_info *, const char *warning, const char *symbol, + bfd *abfd, asection *section, bfd_vma address); + /* A function which is called when a relocation is attempted against + an undefined symbol. NAME is the symbol which is undefined. + ABFD, SECTION and ADDRESS identify the location from which the + reference is made. FATAL indicates whether an undefined symbol is + a fatal error or not. In some cases SECTION may be NULL. */ + bfd_boolean (*undefined_symbol) + (struct bfd_link_info *, const char *name, bfd *abfd, + asection *section, bfd_vma address, bfd_boolean fatal); + /* A function which is called when a reloc overflow occurs. NAME is + the name of the symbol or section the reloc is against, + RELOC_NAME is the name of the relocation, and ADDEND is any + addend that is used. ABFD, SECTION and ADDRESS identify the + location at which the overflow occurs; if this is the result of a + bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then + ABFD will be NULL. */ + bfd_boolean (*reloc_overflow) + (struct bfd_link_info *, const char *name, const char *reloc_name, + bfd_vma addend, bfd *abfd, asection *section, bfd_vma address); + /* A function which is called when a dangerous reloc is performed. + The canonical example is an a29k IHCONST reloc which does not + follow an IHIHALF reloc. MESSAGE is an appropriate message. + ABFD, SECTION and ADDRESS identify the location at which the + problem occurred; if this is the result of a + bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then + ABFD will be NULL. */ + bfd_boolean (*reloc_dangerous) + (struct bfd_link_info *, const char *message, + bfd *abfd, asection *section, bfd_vma address); + /* A function which is called when a reloc is found to be attached + to a symbol which is not being written out. NAME is the name of + the symbol. ABFD, SECTION and ADDRESS identify the location of + the reloc; if this is the result of a + bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then + ABFD will be NULL. */ + bfd_boolean (*unattached_reloc) + (struct bfd_link_info *, const char *name, + bfd *abfd, asection *section, bfd_vma address); + /* A function which is called when a symbol in notice_hash is + defined or referenced. NAME is the symbol. ABFD, SECTION and + ADDRESS are the value of the symbol. If SECTION is + bfd_und_section, this is a reference. */ + bfd_boolean (*notice) + (struct bfd_link_info *, const char *name, + bfd *abfd, asection *section, bfd_vma address); + /* A function which is called for reporting a linker error. ID is the + error identifier. The remaining input is the same as einfo () in + ld. */ + bfd_boolean (*error_handler) + (int id, const char *fmt, ...); + +/* Identifiers of linker error messages used by error_handler. */ +#define LD_DEFINITION_IN_DISCARDED_SECTION 1 +}; + +/* The linker builds link_order structures which tell the code how to + include input data in the output file. */ + +/* These are the types of link_order structures. */ + +enum bfd_link_order_type +{ + bfd_undefined_link_order, /* Undefined. */ + bfd_indirect_link_order, /* Built from a section. */ + bfd_data_link_order, /* Set to explicit data. */ + bfd_section_reloc_link_order, /* Relocate against a section. */ + bfd_symbol_reloc_link_order /* Relocate against a symbol. */ +}; + +/* This is the link_order structure itself. These form a chain + attached to the section whose contents they are describing. */ + +struct bfd_link_order +{ + /* Next link_order in chain. */ + struct bfd_link_order *next; + /* Type of link_order. */ + enum bfd_link_order_type type; + /* Offset within output section. */ + bfd_vma offset; + /* Size within output section. */ + bfd_size_type size; + /* Type specific information. */ + union + { + struct + { + /* Section to include. If this is used, then + section->output_section must be the section the + link_order is attached to, section->output_offset must + equal the link_order offset field, and section->_raw_size + must equal the link_order size field. Maybe these + restrictions should be relaxed someday. */ + asection *section; + } indirect; + struct + { + /* Size of contents, or zero when contents size == size + within output section. + A non-zero value allows filling of the output section + with an arbitrary repeated pattern. */ + unsigned int size; + /* Data to put into file. */ + bfd_byte *contents; + } data; + struct + { + /* Description of reloc to generate. Used for + bfd_section_reloc_link_order and + bfd_symbol_reloc_link_order. */ + struct bfd_link_order_reloc *p; + } reloc; + } u; +}; + +/* A linker order of type bfd_section_reloc_link_order or + bfd_symbol_reloc_link_order means to create a reloc against a + section or symbol, respectively. This is used to implement -Ur to + generate relocs for the constructor tables. The + bfd_link_order_reloc structure describes the reloc that BFD should + create. It is similar to a arelent, but I didn't use arelent + because the linker does not know anything about most symbols, and + any asymbol structure it creates will be partially meaningless. + This information could logically be in the bfd_link_order struct, + but I didn't want to waste the space since these types of relocs + are relatively rare. */ + +struct bfd_link_order_reloc +{ + /* Reloc type. */ + bfd_reloc_code_real_type reloc; + + union + { + /* For type bfd_section_reloc_link_order, this is the section + the reloc should be against. This must be a section in the + output BFD, not any of the input BFDs. */ + asection *section; + /* For type bfd_symbol_reloc_link_order, this is the name of the + symbol the reloc should be against. */ + const char *name; + } u; + + /* Addend to use. The object file should contain zero. The BFD + backend is responsible for filling in the contents of the object + file correctly. For some object file formats (e.g., COFF) the + addend must be stored into in the object file, and for some + (e.g., SPARC a.out) it is kept in the reloc. */ + bfd_vma addend; +}; + +/* Allocate a new link_order for a section. */ +extern struct bfd_link_order *bfd_new_link_order (bfd *, asection *); + +/* These structures are used to describe version information for the + ELF linker. These structures could be manipulated entirely inside + BFD, but it would be a pain. Instead, the regular linker sets up + these structures, and then passes them into BFD. */ + +/* Glob pattern for a version. */ + +struct bfd_elf_version_expr +{ + /* Next glob pattern for this version. */ + struct bfd_elf_version_expr *next; + /* Glob pattern. */ + const char *pattern; + /* NULL for a glob pattern, otherwise a straight symbol. */ + const char *symbol; + /* Defined by ".symver". */ + unsigned int symver : 1; + /* Defined by version script. */ + unsigned int script : 1; + /* Pattern type. */ +#define BFD_ELF_VERSION_C_TYPE 1 +#define BFD_ELF_VERSION_CXX_TYPE 2 +#define BFD_ELF_VERSION_JAVA_TYPE 4 + unsigned int mask : 3; +}; + +struct bfd_elf_version_expr_head +{ + /* List of all patterns, both wildcards and non-wildcards. */ + struct bfd_elf_version_expr *list; + /* Hash table for non-wildcards. */ + void *htab; + /* Remaining patterns. */ + struct bfd_elf_version_expr *remaining; + /* What kind of pattern types are present in list (bitmask). */ + unsigned int mask; +}; + +/* Version dependencies. */ + +struct bfd_elf_version_deps +{ + /* Next dependency for this version. */ + struct bfd_elf_version_deps *next; + /* The version which this version depends upon. */ + struct bfd_elf_version_tree *version_needed; +}; + +/* A node in the version tree. */ + +struct bfd_elf_version_tree +{ + /* Next version. */ + struct bfd_elf_version_tree *next; + /* Name of this version. */ + const char *name; + /* Version number. */ + unsigned int vernum; + /* Regular expressions for global symbols in this version. */ + struct bfd_elf_version_expr_head globals; + /* Regular expressions for local symbols in this version. */ + struct bfd_elf_version_expr_head locals; + /* List of versions which this version depends upon. */ + struct bfd_elf_version_deps *deps; + /* Index of the version name. This is used within BFD. */ + unsigned int name_indx; + /* Whether this version tree was used. This is used within BFD. */ + int used; + /* Matching hook. */ + struct bfd_elf_version_expr *(*match) + (struct bfd_elf_version_expr_head *head, + struct bfd_elf_version_expr *prev, const char *sym); +}; + +#endif diff --git a/contrib/gdb/include/bin-bugs.h b/contrib/gdb/include/bin-bugs.h new file mode 100644 index 00000000000..3c97715add4 --- /dev/null +++ b/contrib/gdb/include/bin-bugs.h @@ -0,0 +1,3 @@ +#ifndef REPORT_BUGS_TO +#define REPORT_BUGS_TO "bug-binutils@gnu.org" +#endif diff --git a/contrib/gdb/include/bout.h b/contrib/gdb/include/bout.h new file mode 100644 index 00000000000..a69e280cb18 --- /dev/null +++ b/contrib/gdb/include/bout.h @@ -0,0 +1,191 @@ +/* This file is a modified version of 'a.out.h'. It is to be used in all + GNU tools modified to support the i80960 (or tools that operate on + object files created by such tools). + + Copyright 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* All i80960 development is done in a CROSS-DEVELOPMENT environment. I.e., + object code is generated on, and executed under the direction of a symbolic + debugger running on, a host system. We do not want to be subject to the + vagaries of which host it is or whether it supports COFF or a.out format, + or anything else. We DO want to: + + o always generate the same format object files, regardless of host. + + o have an 'a.out' header that we can modify for our own purposes + (the 80960 is typically an embedded processor and may require + enhanced linker support that the normal a.out.h header can't + accommodate). + + As for byte-ordering, the following rules apply: + + o Text and data that is actually downloaded to the target is always + in i80960 (little-endian) order. + + o All other numbers (in the header, symbols, relocation directives) + are in host byte-order: object files CANNOT be lifted from a + little-end host and used on a big-endian (or vice versa) without + modification. + ==> THIS IS NO LONGER TRUE USING BFD. WE CAN GENERATE ANY BYTE ORDER + FOR THE HEADER, AND READ ANY BYTE ORDER. PREFERENCE WOULD BE TO + USE LITTLE-ENDIAN BYTE ORDER THROUGHOUT, REGARDLESS OF HOST. <== + + o The downloader ('comm960') takes care to generate a pseudo-header + with correct (i80960) byte-ordering before shipping text and data + off to the NINDY monitor in the target systems. Symbols and + relocation info are never sent to the target. */ + +#define BMAGIC 0415 +/* We don't accept the following (see N_BADMAG macro). + They're just here so GNU code will compile. */ +#define OMAGIC 0407 /* old impure format */ +#define NMAGIC 0410 /* read-only text */ +#define ZMAGIC 0413 /* demand load format */ + +/* FILE HEADER + All 'lengths' are given as a number of bytes. + All 'alignments' are for relinkable files only; an alignment of + 'n' indicates the corresponding segment must begin at an + address that is a multiple of (2**n). */ +struct external_exec + { + /* Standard stuff */ + unsigned char e_info[4]; /* Identifies this as a b.out file */ + unsigned char e_text[4]; /* Length of text */ + unsigned char e_data[4]; /* Length of data */ + unsigned char e_bss[4]; /* Length of uninitialized data area */ + unsigned char e_syms[4]; /* Length of symbol table */ + unsigned char e_entry[4]; /* Runtime start address */ + unsigned char e_trsize[4]; /* Length of text relocation info */ + unsigned char e_drsize[4]; /* Length of data relocation info */ + + /* Added for i960 */ + unsigned char e_tload[4]; /* Text runtime load address */ + unsigned char e_dload[4]; /* Data runtime load address */ + unsigned char e_talign[1]; /* Alignment of text segment */ + unsigned char e_dalign[1]; /* Alignment of data segment */ + unsigned char e_balign[1]; /* Alignment of bss segment */ + unsigned char e_relaxable[1];/* Assembled with enough info to allow linker to relax */ + }; + +#define EXEC_BYTES_SIZE (sizeof (struct external_exec)) + +/* These macros use the a_xxx field names, since they operate on the exec + structure after it's been byte-swapped and realigned on the host machine. */ +#define N_BADMAG(x) (((x).a_info)!=BMAGIC) +#define N_TXTOFF(x) EXEC_BYTES_SIZE +#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text ) +#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data ) +#define N_TRELOFF N_TROFF +#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize ) +#define N_DRELOFF N_DROFF +#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize ) +#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) +#define N_DATADDR(x) ( (x).a_dload ) + +/* Address of text segment in memory after it is loaded. */ +#if !defined (N_TXTADDR) +#define N_TXTADDR(x) 0 +#endif + +/* A single entry in the symbol table. */ +struct nlist + { + union + { + char* n_name; + struct nlist * n_next; + long n_strx; /* Index into string table */ + } n_un; + + unsigned char n_type; /* See below */ + char n_other; /* Used in i80960 support -- see below */ + short n_desc; + unsigned long n_value; + }; + + +/* Legal values of n_type. */ +#define N_UNDF 0 /* Undefined symbol */ +#define N_ABS 2 /* Absolute symbol */ +#define N_TEXT 4 /* Text symbol */ +#define N_DATA 6 /* Data symbol */ +#define N_BSS 8 /* BSS symbol */ +#define N_FN 31 /* Filename symbol */ + +#define N_EXT 1 /* External symbol (OR'd in with one of above) */ +#define N_TYPE 036 /* Mask for all the type bits */ +#define N_STAB 0340 /* Mask for all bits used for SDB entries */ + +/* MEANING OF 'n_other' + + If non-zero, the 'n_other' fields indicates either a leaf procedure or + a system procedure, as follows: + + 1 <= n_other <= 32 : + The symbol is the entry point to a system procedure. + 'n_value' is the address of the entry, as for any other + procedure. The system procedure number (which can be used in + a 'calls' instruction) is (n_other-1). These entries come from + '.sysproc' directives. + + n_other == N_CALLNAME + the symbol is the 'call' entry point to a leaf procedure. + The *next* symbol in the symbol table must be the corresponding + 'bal' entry point to the procedure (see following). These + entries come from '.leafproc' directives in which two different + symbols are specified (the first one is represented here). + + + n_other == N_BALNAME + the symbol is the 'bal' entry point to a leaf procedure. + These entries result from '.leafproc' directives in which only + one symbol is specified, or in which the same symbol is + specified twice. + + Note that an N_CALLNAME entry *must* have a corresponding N_BALNAME entry, + but not every N_BALNAME entry must have an N_CALLNAME entry. */ +#define N_CALLNAME ((char)-1) +#define N_BALNAME ((char)-2) +#define IS_CALLNAME(x) (N_CALLNAME == (x)) +#define IS_BALNAME(x) (N_BALNAME == (x)) +#define IS_OTHER(x) ((x)>0 && (x) <=32) + +#define b_out_relocation_info relocation_info +struct relocation_info + { + int r_address; /* File address of item to be relocated. */ + unsigned +#define r_index r_symbolnum + r_symbolnum:24, /* Index of symbol on which relocation is based, + if r_extern is set. Otherwise set to + either N_TEXT, N_DATA, or N_BSS to + indicate section on which relocation is + based. */ + r_pcrel:1, /* 1 => relocate PC-relative; else absolute + On i960, pc-relative implies 24-bit + address, absolute implies 32-bit. */ + r_length:2, /* Number of bytes to relocate: + 0 => 1 byte + 1 => 2 bytes -- used for 13 bit pcrel + 2 => 4 bytes. */ + r_extern:1, + r_bsr:1, /* Something for the GNU NS32K assembler. */ + r_disp:1, /* Something for the GNU NS32K assembler. */ + r_callj:1, /* 1 if relocation target is an i960 'callj'. */ + r_relaxable:1; /* 1 if enough info is left to relax the data. */ +}; diff --git a/contrib/gdb/include/demangle.h b/contrib/gdb/include/demangle.h new file mode 100644 index 00000000000..6e995e4817d --- /dev/null +++ b/contrib/gdb/include/demangle.h @@ -0,0 +1,533 @@ +/* Defs for interface to demanglers. + Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, + 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#if !defined (DEMANGLE_H) +#define DEMANGLE_H + +#include "libiberty.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Options passed to cplus_demangle (in 2nd parameter). */ + +#define DMGL_NO_OPTS 0 /* For readability... */ +#define DMGL_PARAMS (1 << 0) /* Include function args */ +#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ +#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */ +#define DMGL_VERBOSE (1 << 3) /* Include implementation details. */ +#define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */ + +#define DMGL_AUTO (1 << 8) +#define DMGL_GNU (1 << 9) +#define DMGL_LUCID (1 << 10) +#define DMGL_ARM (1 << 11) +#define DMGL_HP (1 << 12) /* For the HP aCC compiler; + same as ARM except for + template arguments, etc. */ +#define DMGL_EDG (1 << 13) +#define DMGL_GNU_V3 (1 << 14) +#define DMGL_GNAT (1 << 15) + +/* If none of these are set, use 'current_demangling_style' as the default. */ +#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT) + +/* Enumeration of possible demangling styles. + + Lucid and ARM styles are still kept logically distinct, even though + they now both behave identically. The resulting style is actual the + union of both. I.E. either style recognizes both "__pt__" and "__rf__" + for operator "->", even though the first is lucid style and the second + is ARM style. (FIXME?) */ + +extern enum demangling_styles +{ + no_demangling = -1, + unknown_demangling = 0, + auto_demangling = DMGL_AUTO, + gnu_demangling = DMGL_GNU, + lucid_demangling = DMGL_LUCID, + arm_demangling = DMGL_ARM, + hp_demangling = DMGL_HP, + edg_demangling = DMGL_EDG, + gnu_v3_demangling = DMGL_GNU_V3, + java_demangling = DMGL_JAVA, + gnat_demangling = DMGL_GNAT +} current_demangling_style; + +/* Define string names for the various demangling styles. */ + +#define NO_DEMANGLING_STYLE_STRING "none" +#define AUTO_DEMANGLING_STYLE_STRING "auto" +#define GNU_DEMANGLING_STYLE_STRING "gnu" +#define LUCID_DEMANGLING_STYLE_STRING "lucid" +#define ARM_DEMANGLING_STYLE_STRING "arm" +#define HP_DEMANGLING_STYLE_STRING "hp" +#define EDG_DEMANGLING_STYLE_STRING "edg" +#define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3" +#define JAVA_DEMANGLING_STYLE_STRING "java" +#define GNAT_DEMANGLING_STYLE_STRING "gnat" + +/* Some macros to test what demangling style is active. */ + +#define CURRENT_DEMANGLING_STYLE current_demangling_style +#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) +#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) +#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) +#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM) +#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP) +#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG) +#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3) +#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA) +#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT) + +/* Provide information about the available demangle styles. This code is + pulled from gdb into libiberty because it is useful to binutils also. */ + +extern const struct demangler_engine +{ + const char *const demangling_style_name; + const enum demangling_styles demangling_style; + const char *const demangling_style_doc; +} libiberty_demanglers[]; + +extern char * +cplus_demangle PARAMS ((const char *mangled, int options)); + +extern int +cplus_demangle_opname PARAMS ((const char *opname, char *result, int options)); + +extern const char * +cplus_mangle_opname PARAMS ((const char *opname, int options)); + +/* Note: This sets global state. FIXME if you care about multi-threading. */ + +extern void +set_cplus_marker_for_demangling PARAMS ((int ch)); + +extern enum demangling_styles +cplus_demangle_set_style PARAMS ((enum demangling_styles style)); + +extern enum demangling_styles +cplus_demangle_name_to_style PARAMS ((const char *name)); + +/* V3 ABI demangling entry points, defined in cp-demangle.c. */ +extern char* +cplus_demangle_v3 PARAMS ((const char* mangled, int options)); + +extern char* +java_demangle_v3 PARAMS ((const char* mangled)); + + +enum gnu_v3_ctor_kinds { + gnu_v3_complete_object_ctor = 1, + gnu_v3_base_object_ctor, + gnu_v3_complete_object_allocating_ctor +}; + +/* Return non-zero iff NAME is the mangled form of a constructor name + in the G++ V3 ABI demangling style. Specifically, return an `enum + gnu_v3_ctor_kinds' value indicating what kind of constructor + it is. */ +extern enum gnu_v3_ctor_kinds + is_gnu_v3_mangled_ctor PARAMS ((const char *name)); + + +enum gnu_v3_dtor_kinds { + gnu_v3_deleting_dtor = 1, + gnu_v3_complete_object_dtor, + gnu_v3_base_object_dtor +}; + +/* Return non-zero iff NAME is the mangled form of a destructor name + in the G++ V3 ABI demangling style. Specifically, return an `enum + gnu_v3_dtor_kinds' value, indicating what kind of destructor + it is. */ +extern enum gnu_v3_dtor_kinds + is_gnu_v3_mangled_dtor PARAMS ((const char *name)); + +/* The V3 demangler works in two passes. The first pass builds a tree + representation of the mangled name, and the second pass turns the + tree representation into a demangled string. Here we define an + interface to permit a caller to build their own tree + representation, which they can pass to the demangler to get a + demangled string. This can be used to canonicalize user input into + something which the demangler might output. It could also be used + by other demanglers in the future. */ + +/* These are the component types which may be found in the tree. Many + component types have one or two subtrees, referred to as left and + right (a component type with only one subtree puts it in the left + subtree). */ + +enum demangle_component_type +{ + /* A name, with a length and a pointer to a string. */ + DEMANGLE_COMPONENT_NAME, + /* A qualified name. The left subtree is a class or namespace or + some such thing, and the right subtree is a name qualified by + that class. */ + DEMANGLE_COMPONENT_QUAL_NAME, + /* A local name. The left subtree describes a function, and the + right subtree is a name which is local to that function. */ + DEMANGLE_COMPONENT_LOCAL_NAME, + /* A typed name. The left subtree is a name, and the right subtree + describes that name as a function. */ + DEMANGLE_COMPONENT_TYPED_NAME, + /* A template. The left subtree is a template name, and the right + subtree is a template argument list. */ + DEMANGLE_COMPONENT_TEMPLATE, + /* A template parameter. This holds a number, which is the template + parameter index. */ + DEMANGLE_COMPONENT_TEMPLATE_PARAM, + /* A constructor. This holds a name and the kind of + constructor. */ + DEMANGLE_COMPONENT_CTOR, + /* A destructor. This holds a name and the kind of destructor. */ + DEMANGLE_COMPONENT_DTOR, + /* A vtable. This has one subtree, the type for which this is a + vtable. */ + DEMANGLE_COMPONENT_VTABLE, + /* A VTT structure. This has one subtree, the type for which this + is a VTT. */ + DEMANGLE_COMPONENT_VTT, + /* A construction vtable. The left subtree is the type for which + this is a vtable, and the right subtree is the derived type for + which this vtable is built. */ + DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, + /* A typeinfo structure. This has one subtree, the type for which + this is the tpeinfo structure. */ + DEMANGLE_COMPONENT_TYPEINFO, + /* A typeinfo name. This has one subtree, the type for which this + is the typeinfo name. */ + DEMANGLE_COMPONENT_TYPEINFO_NAME, + /* A typeinfo function. This has one subtree, the type for which + this is the tpyeinfo function. */ + DEMANGLE_COMPONENT_TYPEINFO_FN, + /* A thunk. This has one subtree, the name for which this is a + thunk. */ + DEMANGLE_COMPONENT_THUNK, + /* A virtual thunk. This has one subtree, the name for which this + is a virtual thunk. */ + DEMANGLE_COMPONENT_VIRTUAL_THUNK, + /* A covariant thunk. This has one subtree, the name for which this + is a covariant thunk. */ + DEMANGLE_COMPONENT_COVARIANT_THUNK, + /* A Java class. This has one subtree, the type. */ + DEMANGLE_COMPONENT_JAVA_CLASS, + /* A guard variable. This has one subtree, the name for which this + is a guard variable. */ + DEMANGLE_COMPONENT_GUARD, + /* A reference temporary. This has one subtree, the name for which + this is a temporary. */ + DEMANGLE_COMPONENT_REFTEMP, + /* A standard substitution. This holds the name of the + substitution. */ + DEMANGLE_COMPONENT_SUB_STD, + /* The restrict qualifier. The one subtree is the type which is + being qualified. */ + DEMANGLE_COMPONENT_RESTRICT, + /* The volatile qualifier. The one subtree is the type which is + being qualified. */ + DEMANGLE_COMPONENT_VOLATILE, + /* The const qualifier. The one subtree is the type which is being + qualified. */ + DEMANGLE_COMPONENT_CONST, + /* The restrict qualifier modifying a member function. The one + subtree is the type which is being qualified. */ + DEMANGLE_COMPONENT_RESTRICT_THIS, + /* The volatile qualifier modifying a member function. The one + subtree is the type which is being qualified. */ + DEMANGLE_COMPONENT_VOLATILE_THIS, + /* The const qualifier modifying a member function. The one subtree + is the type which is being qualified. */ + DEMANGLE_COMPONENT_CONST_THIS, + /* A vendor qualifier. The left subtree is the type which is being + qualified, and the right subtree is the name of the + qualifier. */ + DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL, + /* A pointer. The one subtree is the type which is being pointed + to. */ + DEMANGLE_COMPONENT_POINTER, + /* A reference. The one subtree is the type which is being + referenced. */ + DEMANGLE_COMPONENT_REFERENCE, + /* A complex type. The one subtree is the base type. */ + DEMANGLE_COMPONENT_COMPLEX, + /* An imaginary type. The one subtree is the base type. */ + DEMANGLE_COMPONENT_IMAGINARY, + /* A builtin type. This holds the builtin type information. */ + DEMANGLE_COMPONENT_BUILTIN_TYPE, + /* A vendor's builtin type. This holds the name of the type. */ + DEMANGLE_COMPONENT_VENDOR_TYPE, + /* A function type. The left subtree is the return type. The right + subtree is a list of ARGLIST nodes. Either or both may be + NULL. */ + DEMANGLE_COMPONENT_FUNCTION_TYPE, + /* An array type. The left subtree is the dimension, which may be + NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an + expression. The right subtree is the element type. */ + DEMANGLE_COMPONENT_ARRAY_TYPE, + /* A pointer to member type. The left subtree is the class type, + and the right subtree is the member type. CV-qualifiers appear + on the latter. */ + DEMANGLE_COMPONENT_PTRMEM_TYPE, + /* An argument list. The left subtree is the current argument, and + the right subtree is either NULL or another ARGLIST node. */ + DEMANGLE_COMPONENT_ARGLIST, + /* A template argument list. The left subtree is the current + template argument, and the right subtree is either NULL or + another TEMPLATE_ARGLIST node. */ + DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, + /* An operator. This holds information about a standard + operator. */ + DEMANGLE_COMPONENT_OPERATOR, + /* An extended operator. This holds the number of arguments, and + the name of the extended operator. */ + DEMANGLE_COMPONENT_EXTENDED_OPERATOR, + /* A typecast, represented as a unary operator. The one subtree is + the type to which the argument should be cast. */ + DEMANGLE_COMPONENT_CAST, + /* A unary expression. The left subtree is the operator, and the + right subtree is the single argument. */ + DEMANGLE_COMPONENT_UNARY, + /* A binary expression. The left subtree is the operator, and the + right subtree is a BINARY_ARGS. */ + DEMANGLE_COMPONENT_BINARY, + /* Arguments to a binary expression. The left subtree is the first + argument, and the right subtree is the second argument. */ + DEMANGLE_COMPONENT_BINARY_ARGS, + /* A trinary expression. The left subtree is the operator, and the + right subtree is a TRINARY_ARG1. */ + DEMANGLE_COMPONENT_TRINARY, + /* Arguments to a trinary expression. The left subtree is the first + argument, and the right subtree is a TRINARY_ARG2. */ + DEMANGLE_COMPONENT_TRINARY_ARG1, + /* More arguments to a trinary expression. The left subtree is the + second argument, and the right subtree is the third argument. */ + DEMANGLE_COMPONENT_TRINARY_ARG2, + /* A literal. The left subtree is the type, and the right subtree + is the value, represented as a DEMANGLE_COMPONENT_NAME. */ + DEMANGLE_COMPONENT_LITERAL, + /* A negative literal. Like LITERAL, but the value is negated. + This is a minor hack: the NAME used for LITERAL points directly + to the mangled string, but since negative numbers are mangled + using 'n' instead of '-', we want a way to indicate a negative + number which involves neither modifying the mangled string nor + allocating a new copy of the literal in memory. */ + DEMANGLE_COMPONENT_LITERAL_NEG +}; + +/* Types which are only used internally. */ + +struct demangle_operator_info; +struct demangle_builtin_type_info; + +/* A node in the tree representation is an instance of a struct + demangle_component. Note that the field names of the struct are + not well protected against macros defined by the file including + this one. We can fix this if it ever becomes a problem. */ + +struct demangle_component +{ + /* The type of this component. */ + enum demangle_component_type type; + + union + { + /* For DEMANGLE_COMPONENT_NAME. */ + struct + { + /* A pointer to the name (which need not NULL terminated) and + its length. */ + const char *s; + int len; + } s_name; + + /* For DEMANGLE_COMPONENT_OPERATOR. */ + struct + { + /* Operator. */ + const struct demangle_operator_info *op; + } s_operator; + + /* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */ + struct + { + /* Number of arguments. */ + int args; + /* Name. */ + struct demangle_component *name; + } s_extended_operator; + + /* For DEMANGLE_COMPONENT_CTOR. */ + struct + { + /* Kind of constructor. */ + enum gnu_v3_ctor_kinds kind; + /* Name. */ + struct demangle_component *name; + } s_ctor; + + /* For DEMANGLE_COMPONENT_DTOR. */ + struct + { + /* Kind of destructor. */ + enum gnu_v3_dtor_kinds kind; + /* Name. */ + struct demangle_component *name; + } s_dtor; + + /* For DEMANGLE_COMPONENT_BUILTIN_TYPE. */ + struct + { + /* Builtin type. */ + const struct demangle_builtin_type_info *type; + } s_builtin; + + /* For DEMANGLE_COMPONENT_SUB_STD. */ + struct + { + /* Standard substitution string. */ + const char* string; + /* Length of string. */ + int len; + } s_string; + + /* For DEMANGLE_COMPONENT_TEMPLATE_PARAM. */ + struct + { + /* Template parameter index. */ + long number; + } s_number; + + /* For other types. */ + struct + { + /* Left (or only) subtree. */ + struct demangle_component *left; + /* Right subtree. */ + struct demangle_component *right; + } s_binary; + + } u; +}; + +/* People building mangled trees are expected to allocate instances of + struct demangle_component themselves. They can then call one of + the following functions to fill them in. */ + +/* Fill in most component types with a left subtree and a right + subtree. Returns non-zero on success, zero on failure, such as an + unrecognized or inappropriate component type. */ + +extern int +cplus_demangle_fill_component PARAMS ((struct demangle_component *fill, + enum demangle_component_type, + struct demangle_component *left, + struct demangle_component *right)); + +/* Fill in a DEMANGLE_COMPONENT_NAME. Returns non-zero on success, + zero for bad arguments. */ + +extern int +cplus_demangle_fill_name PARAMS ((struct demangle_component *fill, + const char *, int)); + +/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the + builtin type (e.g., "int", etc.). Returns non-zero on success, + zero if the type is not recognized. */ + +extern int +cplus_demangle_fill_builtin_type PARAMS ((struct demangle_component *fill, + const char *typename)); + +/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the + operator and the number of arguments which it takes (the latter is + used to disambiguate operators which can be both binary and unary, + such as '-'). Returns non-zero on success, zero if the operator is + not recognized. */ + +extern int +cplus_demangle_fill_operator PARAMS ((struct demangle_component *fill, + const char *opname, int args)); + +/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the + number of arguments and the name. Returns non-zero on success, + zero for bad arguments. */ + +extern int +cplus_demangle_fill_extended_operator PARAMS ((struct demangle_component *fill, + int numargs, + struct demangle_component *nm)); + +/* Fill in a DEMANGLE_COMPONENT_CTOR. Returns non-zero on success, + zero for bad arguments. */ + +extern int +cplus_demangle_fill_ctor PARAMS ((struct demangle_component *fill, + enum gnu_v3_ctor_kinds kind, + struct demangle_component *name)); + +/* Fill in a DEMANGLE_COMPONENT_DTOR. Returns non-zero on success, + zero for bad arguments. */ + +extern int +cplus_demangle_fill_dtor PARAMS ((struct demangle_component *fill, + enum gnu_v3_dtor_kinds kind, + struct demangle_component *name)); + +/* This function translates a mangled name into a struct + demangle_component tree. The first argument is the mangled name. + The second argument is DMGL_* options. This returns a pointer to a + tree on success, or NULL on failure. On success, the third + argument is set to a block of memory allocated by malloc. This + block should be passed to free when the tree is no longer + needed. */ + +extern struct demangle_component * +cplus_demangle_v3_components PARAMS ((const char *mangled, + int options, + void **mem)); + +/* This function takes a struct demangle_component tree and returns + the corresponding demangled string. The first argument is DMGL_* + options. The second is the tree to demangle. The third is a guess + at the length of the demangled string, used to initially allocate + the return buffer. The fourth is a pointer to a size_t. On + success, this function returns a buffer allocated by malloc(), and + sets the size_t pointed to by the fourth argument to the size of + the allocated buffer (not the length of the returned string). On + failure, this function returns NULL, and sets the size_t pointed to + by the fourth argument to 0 for an invalid tree, or to 1 for a + memory allocation error. */ + +extern char * +cplus_demangle_print PARAMS ((int options, + const struct demangle_component *tree, + int estimated_length, + size_t *p_allocated_size)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* DEMANGLE_H */ diff --git a/contrib/gdb/include/dis-asm.h b/contrib/gdb/include/dis-asm.h new file mode 100644 index 00000000000..3670c518986 --- /dev/null +++ b/contrib/gdb/include/dis-asm.h @@ -0,0 +1,317 @@ +/* Interface between the opcode library and its callers. + + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Written by Cygnus Support, 1993. + + The opcode library (libopcodes.a) provides instruction decoders for + a large variety of instruction sets, callable with an identical + interface, for making instruction-processing programs more independent + of the instruction set being processed. */ + +#ifndef DIS_ASM_H +#define DIS_ASM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bfd.h" + +typedef int (*fprintf_ftype) (void *, const char*, ...); + +enum dis_insn_type { + dis_noninsn, /* Not a valid instruction */ + dis_nonbranch, /* Not a branch instruction */ + dis_branch, /* Unconditional branch */ + dis_condbranch, /* Conditional branch */ + dis_jsr, /* Jump to subroutine */ + dis_condjsr, /* Conditional jump to subroutine */ + dis_dref, /* Data reference instruction */ + dis_dref2 /* Two data references in instruction */ +}; + +/* This struct is passed into the instruction decoding routine, + and is passed back out into each callback. The various fields are used + for conveying information from your main routine into your callbacks, + for passing information into the instruction decoders (such as the + addresses of the callback functions), or for passing information + back from the instruction decoders to their callers. + + It must be initialized before it is first passed; this can be done + by hand, or using one of the initialization macros below. */ + +typedef struct disassemble_info { + fprintf_ftype fprintf_func; + void *stream; + void *application_data; + + /* Target description. We could replace this with a pointer to the bfd, + but that would require one. There currently isn't any such requirement + so to avoid introducing one we record these explicitly. */ + /* The bfd_flavour. This can be bfd_target_unknown_flavour. */ + enum bfd_flavour flavour; + /* The bfd_arch value. */ + enum bfd_architecture arch; + /* The bfd_mach value. */ + unsigned long mach; + /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */ + enum bfd_endian endian; + /* An arch/mach-specific bitmask of selected instruction subsets, mainly + for processors with run-time-switchable instruction sets. The default, + zero, means that there is no constraint. CGEN-based opcodes ports + may use ISA_foo masks. */ + unsigned long insn_sets; + + /* Some targets need information about the current section to accurately + display insns. If this is NULL, the target disassembler function + will have to make its best guess. */ + asection *section; + + /* An array of pointers to symbols either at the location being disassembled + or at the start of the function being disassembled. The array is sorted + so that the first symbol is intended to be the one used. The others are + present for any misc. purposes. This is not set reliably, but if it is + not NULL, it is correct. */ + asymbol **symbols; + /* Number of symbols in array. */ + int num_symbols; + + /* For use by the disassembler. + The top 16 bits are reserved for public use (and are documented here). + The bottom 16 bits are for the internal use of the disassembler. */ + unsigned long flags; +#define INSN_HAS_RELOC 0x80000000 + void *private_data; + + /* Function used to get bytes to disassemble. MEMADDR is the + address of the stuff to be disassembled, MYADDR is the address to + put the bytes in, and LENGTH is the number of bytes to read. + INFO is a pointer to this struct. + Returns an errno value or 0 for success. */ + int (*read_memory_func) + (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, + struct disassemble_info *info); + + /* Function which should be called if we get an error that we can't + recover from. STATUS is the errno value from read_memory_func and + MEMADDR is the address that we were trying to read. INFO is a + pointer to this struct. */ + void (*memory_error_func) + (int status, bfd_vma memaddr, struct disassemble_info *info); + + /* Function called to print ADDR. */ + void (*print_address_func) + (bfd_vma addr, struct disassemble_info *info); + + /* Function called to determine if there is a symbol at the given ADDR. + If there is, the function returns 1, otherwise it returns 0. + This is used by ports which support an overlay manager where + the overlay number is held in the top part of an address. In + some circumstances we want to include the overlay number in the + address, (normally because there is a symbol associated with + that address), but sometimes we want to mask out the overlay bits. */ + int (* symbol_at_address_func) + (bfd_vma addr, struct disassemble_info * info); + + /* Function called to check if a SYMBOL is can be displayed to the user. + This is used by some ports that want to hide special symbols when + displaying debugging outout. */ + bfd_boolean (* symbol_is_valid) + (asymbol *, struct disassemble_info * info); + + /* These are for buffer_read_memory. */ + bfd_byte *buffer; + bfd_vma buffer_vma; + unsigned int buffer_length; + + /* This variable may be set by the instruction decoder. It suggests + the number of bytes objdump should display on a single line. If + the instruction decoder sets this, it should always set it to + the same value in order to get reasonable looking output. */ + int bytes_per_line; + + /* The next two variables control the way objdump displays the raw data. */ + /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */ + /* output will look like this: + 00: 00000000 00000000 + with the chunks displayed according to "display_endian". */ + int bytes_per_chunk; + enum bfd_endian display_endian; + + /* Number of octets per incremented target address + Normally one, but some DSPs have byte sizes of 16 or 32 bits. */ + unsigned int octets_per_byte; + + /* Results from instruction decoders. Not all decoders yet support + this information. This info is set each time an instruction is + decoded, and is only valid for the last such instruction. + + To determine whether this decoder supports this information, set + insn_info_valid to 0, decode an instruction, then check it. */ + + char insn_info_valid; /* Branch info has been set. */ + char branch_delay_insns; /* How many sequential insn's will run before + a branch takes effect. (0 = normal) */ + char data_size; /* Size of data reference in insn, in bytes */ + enum dis_insn_type insn_type; /* Type of instruction */ + bfd_vma target; /* Target address of branch or dref, if known; + zero if unknown. */ + bfd_vma target2; /* Second target address for dref2 */ + + /* Command line options specific to the target disassembler. */ + char * disassembler_options; + +} disassemble_info; + + +/* Standard disassemblers. Disassemble one instruction at the given + target address. Return number of octets processed. */ +typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); + +extern int print_insn_big_mips (bfd_vma, disassemble_info *); +extern int print_insn_little_mips (bfd_vma, disassemble_info *); +extern int print_insn_i386 (bfd_vma, disassemble_info *); +extern int print_insn_i386_att (bfd_vma, disassemble_info *); +extern int print_insn_i386_intel (bfd_vma, disassemble_info *); +extern int print_insn_ia64 (bfd_vma, disassemble_info *); +extern int print_insn_i370 (bfd_vma, disassemble_info *); +extern int print_insn_m68hc11 (bfd_vma, disassemble_info *); +extern int print_insn_m68hc12 (bfd_vma, disassemble_info *); +extern int print_insn_m68k (bfd_vma, disassemble_info *); +extern int print_insn_z8001 (bfd_vma, disassemble_info *); +extern int print_insn_z8002 (bfd_vma, disassemble_info *); +extern int print_insn_h8300 (bfd_vma, disassemble_info *); +extern int print_insn_h8300h (bfd_vma, disassemble_info *); +extern int print_insn_h8300s (bfd_vma, disassemble_info *); +extern int print_insn_h8500 (bfd_vma, disassemble_info *); +extern int print_insn_alpha (bfd_vma, disassemble_info *); +extern int print_insn_big_arm (bfd_vma, disassemble_info *); +extern int print_insn_little_arm (bfd_vma, disassemble_info *); +extern int print_insn_sparc (bfd_vma, disassemble_info *); +extern int print_insn_big_a29k (bfd_vma, disassemble_info *); +extern int print_insn_little_a29k (bfd_vma, disassemble_info *); +extern int print_insn_avr (bfd_vma, disassemble_info *); +extern int print_insn_d10v (bfd_vma, disassemble_info *); +extern int print_insn_d30v (bfd_vma, disassemble_info *); +extern int print_insn_dlx (bfd_vma, disassemble_info *); +extern int print_insn_fr30 (bfd_vma, disassemble_info *); +extern int print_insn_hppa (bfd_vma, disassemble_info *); +extern int print_insn_i860 (bfd_vma, disassemble_info *); +extern int print_insn_i960 (bfd_vma, disassemble_info *); +extern int print_insn_ip2k (bfd_vma, disassemble_info *); +extern int print_insn_m32r (bfd_vma, disassemble_info *); +extern int print_insn_m88k (bfd_vma, disassemble_info *); +extern int print_insn_mcore (bfd_vma, disassemble_info *); +extern int print_insn_mmix (bfd_vma, disassemble_info *); +extern int print_insn_mn10200 (bfd_vma, disassemble_info *); +extern int print_insn_mn10300 (bfd_vma, disassemble_info *); +extern int print_insn_msp430 (bfd_vma, disassemble_info *); +extern int print_insn_ns32k (bfd_vma, disassemble_info *); +extern int print_insn_openrisc (bfd_vma, disassemble_info *); +extern int print_insn_big_or32 (bfd_vma, disassemble_info *); +extern int print_insn_little_or32 (bfd_vma, disassemble_info *); +extern int print_insn_pdp11 (bfd_vma, disassemble_info *); +extern int print_insn_pj (bfd_vma, disassemble_info *); +extern int print_insn_big_powerpc (bfd_vma, disassemble_info *); +extern int print_insn_little_powerpc (bfd_vma, disassemble_info *); +extern int print_insn_rs6000 (bfd_vma, disassemble_info *); +extern int print_insn_s390 (bfd_vma, disassemble_info *); +extern int print_insn_sh (bfd_vma, disassemble_info *); +extern int print_insn_tic30 (bfd_vma, disassemble_info *); +extern int print_insn_tic4x (bfd_vma, disassemble_info *); +extern int print_insn_tic54x (bfd_vma, disassemble_info *); +extern int print_insn_tic80 (bfd_vma, disassemble_info *); +extern int print_insn_v850 (bfd_vma, disassemble_info *); +extern int print_insn_vax (bfd_vma, disassemble_info *); +extern int print_insn_w65 (bfd_vma, disassemble_info *); +extern int print_insn_xstormy16 (bfd_vma, disassemble_info *); +extern int print_insn_xtensa (bfd_vma, disassemble_info *); +extern int print_insn_sh64 (bfd_vma, disassemble_info *); +extern int print_insn_sh64x_media (bfd_vma, disassemble_info *); +extern int print_insn_frv (bfd_vma, disassemble_info *); +extern int print_insn_iq2000 (bfd_vma, disassemble_info *); + +extern disassembler_ftype arc_get_disassembler (void *); +extern disassembler_ftype cris_get_disassembler (bfd *); + +extern void print_mips_disassembler_options (FILE *); +extern void print_ppc_disassembler_options (FILE *); +extern void print_arm_disassembler_options (FILE *); +extern void parse_arm_disassembler_option (char *); +extern int get_arm_regname_num_options (void); +extern int set_arm_regname_option (int); +extern int get_arm_regnames (int, const char **, const char **, const char ***); +extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *); + +/* Fetch the disassembler for a given BFD, if that support is available. */ +extern disassembler_ftype disassembler (bfd *); + +/* Amend the disassemble_info structure as necessary for the target architecture. + Should only be called after initialising the info->arch field. */ +extern void disassemble_init_for_target (struct disassemble_info * info); + +/* Document any target specific options available from the disassembler. */ +extern void disassembler_usage (FILE *); + + +/* This block of definitions is for particular callers who read instructions + into a buffer before calling the instruction decoder. */ + +/* Here is a function which callers may wish to use for read_memory_func. + It gets bytes from a buffer. */ +extern int buffer_read_memory + (bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *); + +/* This function goes with buffer_read_memory. + It prints a message using info->fprintf_func and info->stream. */ +extern void perror_memory (int, bfd_vma, struct disassemble_info *); + + +/* Just print the address in hex. This is included for completeness even + though both GDB and objdump provide their own (to print symbolic + addresses). */ +extern void generic_print_address + (bfd_vma, struct disassemble_info *); + +/* Always true. */ +extern int generic_symbol_at_address + (bfd_vma, struct disassemble_info *); + +/* Also always true. */ +extern bfd_boolean generic_symbol_is_valid + (asymbol *, struct disassemble_info *); + +/* Method to initialize a disassemble_info struct. This should be + called by all applications creating such a struct. */ +extern void init_disassemble_info (struct disassemble_info *info, void *stream, + fprintf_ftype fprintf_func); + +/* For compatibility with existing code. */ +#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \ + init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC)) +#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \ + init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC)) + + +#ifdef __cplusplus +} +#endif + +#endif /* ! defined (DIS_ASM_H) */ diff --git a/contrib/gdb/include/dyn-string.h b/contrib/gdb/include/dyn-string.h new file mode 100644 index 00000000000..85f88b12cf6 --- /dev/null +++ b/contrib/gdb/include/dyn-string.h @@ -0,0 +1,63 @@ +/* An abstract string datatype. + Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. + Contributed by Mark Mitchell (mark@markmitchell.com). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +typedef struct dyn_string +{ + int allocated; /* The amount of space allocated for the string. */ + int length; /* The actual length of the string. */ + char *s; /* The string itself, NUL-terminated. */ +}* dyn_string_t; + +/* The length STR, in bytes, not including the terminating NUL. */ +#define dyn_string_length(STR) \ + ((STR)->length) + +/* The NTBS in which the contents of STR are stored. */ +#define dyn_string_buf(STR) \ + ((STR)->s) + +/* Compare DS1 to DS2 with strcmp. */ +#define dyn_string_compare(DS1, DS2) \ + (strcmp ((DS1)->s, (DS2)->s)) + + +extern int dyn_string_init PARAMS ((struct dyn_string *, int)); +extern dyn_string_t dyn_string_new PARAMS ((int)); +extern void dyn_string_delete PARAMS ((dyn_string_t)); +extern char *dyn_string_release PARAMS ((dyn_string_t)); +extern dyn_string_t dyn_string_resize PARAMS ((dyn_string_t, int)); +extern void dyn_string_clear PARAMS ((dyn_string_t)); +extern int dyn_string_copy PARAMS ((dyn_string_t, dyn_string_t)); +extern int dyn_string_copy_cstr PARAMS ((dyn_string_t, const char *)); +extern int dyn_string_prepend PARAMS ((dyn_string_t, dyn_string_t)); +extern int dyn_string_prepend_cstr PARAMS ((dyn_string_t, const char *)); +extern int dyn_string_insert PARAMS ((dyn_string_t, int, + dyn_string_t)); +extern int dyn_string_insert_cstr PARAMS ((dyn_string_t, int, + const char *)); +extern int dyn_string_insert_char PARAMS ((dyn_string_t, int, int)); +extern int dyn_string_append PARAMS ((dyn_string_t, dyn_string_t)); +extern int dyn_string_append_cstr PARAMS ((dyn_string_t, const char *)); +extern int dyn_string_append_char PARAMS ((dyn_string_t, int)); +extern int dyn_string_substring PARAMS ((dyn_string_t, + dyn_string_t, int, int)); +extern int dyn_string_eq PARAMS ((dyn_string_t, dyn_string_t)); diff --git a/contrib/gdb/include/fibheap.h b/contrib/gdb/include/fibheap.h new file mode 100644 index 00000000000..4eebaf13ba6 --- /dev/null +++ b/contrib/gdb/include/fibheap.h @@ -0,0 +1,86 @@ +/* A Fibonacci heap datatype. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Daniel Berlin (dan@cgsoftware.com). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Fibonacci heaps are somewhat complex, but, there's an article in + DDJ that explains them pretty well: + + http://www.ddj.com/articles/1997/9701/9701o/9701o.htm?topic=algoritms + + Introduction to algorithms by Corman and Rivest also goes over them. + + The original paper that introduced them is "Fibonacci heaps and their + uses in improved network optimization algorithms" by Tarjan and + Fredman (JACM 34(3), July 1987). + + Amortized and real worst case time for operations: + + ExtractMin: O(lg n) amortized. O(n) worst case. + DecreaseKey: O(1) amortized. O(lg n) worst case. + Insert: O(2) amortized. O(1) actual. + Union: O(1) amortized. O(1) actual. */ + +#ifndef _FIBHEAP_H_ +#define _FIBHEAP_H_ + +#include "ansidecl.h" + +typedef long fibheapkey_t; + +typedef struct fibheap +{ + size_t nodes; + struct fibnode *min; + struct fibnode *root; +} *fibheap_t; + +typedef struct fibnode +{ + struct fibnode *parent; + struct fibnode *child; + struct fibnode *left; + struct fibnode *right; + fibheapkey_t key; + void *data; +#ifdef __GNUC__ + __extension__ unsigned long int degree : 31; + __extension__ unsigned long int mark : 1; +#else + unsigned int degree : 31; + unsigned int mark : 1; +#endif +} *fibnode_t; + +extern fibheap_t fibheap_new PARAMS ((void)); +extern fibnode_t fibheap_insert PARAMS ((fibheap_t, fibheapkey_t, void *)); +extern int fibheap_empty PARAMS ((fibheap_t)); +extern fibheapkey_t fibheap_min_key PARAMS ((fibheap_t)); +extern fibheapkey_t fibheap_replace_key PARAMS ((fibheap_t, fibnode_t, + fibheapkey_t)); +extern void *fibheap_replace_key_data PARAMS ((fibheap_t, fibnode_t, + fibheapkey_t, void *)); +extern void *fibheap_extract_min PARAMS ((fibheap_t)); +extern void *fibheap_min PARAMS ((fibheap_t)); +extern void *fibheap_replace_data PARAMS ((fibheap_t, fibnode_t, void *)); +extern void *fibheap_delete_node PARAMS ((fibheap_t, fibnode_t)); +extern void fibheap_delete PARAMS ((fibheap_t)); +extern fibheap_t fibheap_union PARAMS ((fibheap_t, fibheap_t)); + +#endif /* _FIBHEAP_H_ */ diff --git a/contrib/gdb/include/filenames.h b/contrib/gdb/include/filenames.h new file mode 100644 index 00000000000..ca9e2732a32 --- /dev/null +++ b/contrib/gdb/include/filenames.h @@ -0,0 +1,51 @@ +/* Macros for taking apart, interpreting and processing file names. + + These are here because some non-Posix (a.k.a. DOSish) systems have + drive letter brain-damage at the beginning of an absolute file name, + use forward- and back-slash in path names interchangeably, and + some of them have case-insensitive file names. + + Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef FILENAMES_H +#define FILENAMES_H + +#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) + +#ifndef HAVE_DOS_BASED_FILE_SYSTEM +#define HAVE_DOS_BASED_FILE_SYSTEM 1 +#endif + +#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') +/* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is + only semi-absolute. This is because the users of IS_ABSOLUTE_PATH + want to know whether to prepend the current working directory to + a file name, which should not be done with a name like d:foo. */ +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':'))) +#define FILENAME_CMP(s1, s2) strcasecmp(s1, s2) + +#else /* not DOSish */ + +#define IS_DIR_SEPARATOR(c) ((c) == '/') +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0])) +#define FILENAME_CMP(s1, s2) strcmp(s1, s2) + +#endif /* not DOSish */ + +#endif /* FILENAMES_H */ diff --git a/contrib/gdb/include/floatformat.h b/contrib/gdb/include/floatformat.h new file mode 100644 index 00000000000..a8244ada5c7 --- /dev/null +++ b/contrib/gdb/include/floatformat.h @@ -0,0 +1,133 @@ +/* IEEE floating point support declarations, for GDB, the GNU Debugger. + Copyright 1991, 1994, 1995, 1997, 2000, 2003 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if !defined (FLOATFORMAT_H) +#define FLOATFORMAT_H 1 + +#include "ansidecl.h" + +/* A floatformat consists of a sign bit, an exponent and a mantissa. Once the + bytes are concatenated according to the byteorder flag, then each of those + fields is contiguous. We number the bits with 0 being the most significant + (i.e. BITS_BIG_ENDIAN type numbering), and specify which bits each field + contains with the *_start and *_len fields. */ + +/* What is the order of the bytes. */ + +enum floatformat_byteorders { + + /* Standard little endian byte order. + EX: 1.2345678e10 => 00 00 80 c5 e0 fe 06 42 */ + + floatformat_little, + + /* Standard big endian byte order. + EX: 1.2345678e10 => 42 06 fe e0 c5 80 00 00 */ + + floatformat_big, + + /* Little endian byte order but big endian word order. + EX: 1.2345678e10 => e0 fe 06 42 00 00 80 c5 */ + + floatformat_littlebyte_bigword + +}; + +enum floatformat_intbit { floatformat_intbit_yes, floatformat_intbit_no }; + +struct floatformat +{ + enum floatformat_byteorders byteorder; + unsigned int totalsize; /* Total size of number in bits */ + + /* Sign bit is always one bit long. 1 means negative, 0 means positive. */ + unsigned int sign_start; + + unsigned int exp_start; + unsigned int exp_len; + /* Bias added to a "true" exponent to form the biased exponent. It + is intentionally signed as, otherwize, -exp_bias can turn into a + very large number (e.g., given the exp_bias of 0x3fff and a 64 + bit long, the equation (long)(1 - exp_bias) evaluates to + 4294950914) instead of -16382). */ + int exp_bias; + /* Exponent value which indicates NaN. This is the actual value stored in + the float, not adjusted by the exp_bias. This usually consists of all + one bits. */ + unsigned int exp_nan; + + unsigned int man_start; + unsigned int man_len; + + /* Is the integer bit explicit or implicit? */ + enum floatformat_intbit intbit; + + /* Internal name for debugging. */ + const char *name; + + /* Validator method. */ + int (*is_valid) PARAMS ((const struct floatformat *fmt, const char *from)); +}; + +/* floatformats for IEEE single and double, big and little endian. */ + +extern const struct floatformat floatformat_ieee_single_big; +extern const struct floatformat floatformat_ieee_single_little; +extern const struct floatformat floatformat_ieee_double_big; +extern const struct floatformat floatformat_ieee_double_little; + +/* floatformat for ARM IEEE double, little endian bytes and big endian words */ + +extern const struct floatformat floatformat_ieee_double_littlebyte_bigword; + +/* floatformats for various extendeds. */ + +extern const struct floatformat floatformat_i387_ext; +extern const struct floatformat floatformat_m68881_ext; +extern const struct floatformat floatformat_i960_ext; +extern const struct floatformat floatformat_m88110_ext; +extern const struct floatformat floatformat_m88110_harris_ext; +extern const struct floatformat floatformat_arm_ext_big; +extern const struct floatformat floatformat_arm_ext_littlebyte_bigword; +/* IA-64 Floating Point register spilt into memory. */ +extern const struct floatformat floatformat_ia64_spill_big; +extern const struct floatformat floatformat_ia64_spill_little; +extern const struct floatformat floatformat_ia64_quad_big; +extern const struct floatformat floatformat_ia64_quad_little; + +/* Convert from FMT to a double. + FROM is the address of the extended float. + Store the double in *TO. */ + +extern void +floatformat_to_double PARAMS ((const struct floatformat *, const char *, double *)); + +/* The converse: convert the double *FROM to FMT + and store where TO points. */ + +extern void +floatformat_from_double PARAMS ((const struct floatformat *, + const double *, char *)); + +/* Return non-zero iff the data at FROM is a valid number in format FMT. */ + +extern int +floatformat_is_valid PARAMS ((const struct floatformat *fmt, const char *from)); + +#endif /* defined (FLOATFORMAT_H) */ diff --git a/contrib/gdb/include/fnmatch.h b/contrib/gdb/include/fnmatch.h new file mode 100644 index 00000000000..37d23ee1b35 --- /dev/null +++ b/contrib/gdb/include/fnmatch.h @@ -0,0 +1,70 @@ +/* Copyright 1991, 1992, 1993, 1996 Free Software Foundation, Inc. + +NOTE: The canonical source of this file is maintained with the GNU C Library. +Bugs can be reported to bug-glibc@prep.ai.mit.edu. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef _FNMATCH_H + +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(args) args +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(args) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch __P ((const char *__pattern, const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/contrib/gdb/include/fopen-bin.h b/contrib/gdb/include/fopen-bin.h new file mode 100644 index 00000000000..b868f63d46d --- /dev/null +++ b/contrib/gdb/include/fopen-bin.h @@ -0,0 +1,27 @@ +/* Macros for the 'type' part of an fopen, freopen or fdopen. + + [Update] + + This version is for "binary" systems, where text and binary files are + different. An example is Mess-Dose. Many Unix systems could also + cope with a "b" in the string, indicating binary files, but some reject this + (and thereby don't conform to ANSI C, but what else is new?). + + This file is designed for inclusion by host-dependent .h files. No + user application should include it directly, since that would make + the application unable to be configured for both "same" and "binary" + variant systems. */ + +#define FOPEN_RB "rb" +#define FOPEN_WB "wb" +#define FOPEN_AB "ab" +#define FOPEN_RUB "r+b" +#define FOPEN_WUB "w+b" +#define FOPEN_AUB "a+b" + +#define FOPEN_RT "r" +#define FOPEN_WT "w" +#define FOPEN_AT "a" +#define FOPEN_RUT "r+" +#define FOPEN_WUT "w+" +#define FOPEN_AUT "a+" diff --git a/contrib/gdb/include/fopen-same.h b/contrib/gdb/include/fopen-same.h new file mode 100644 index 00000000000..0f37529d33e --- /dev/null +++ b/contrib/gdb/include/fopen-same.h @@ -0,0 +1,27 @@ +/* Macros for the 'type' part of an fopen, freopen or fdopen. + + [Update] + + This version is for "same" systems, where text and binary files are + the same. An example is Unix. Many Unix systems could also add a + "b" to the string, indicating binary files, but some reject this + (and thereby don't conform to ANSI C, but what else is new?). + + This file is designed for inclusion by host-dependent .h files. No + user application should include it directly, since that would make + the application unable to be configured for both "same" and "binary" + variant systems. */ + +#define FOPEN_RB "r" +#define FOPEN_WB "w" +#define FOPEN_AB "a" +#define FOPEN_RUB "r+" +#define FOPEN_WUB "w+" +#define FOPEN_AUB "a+" + +#define FOPEN_RT "r" +#define FOPEN_WT "w" +#define FOPEN_AT "a" +#define FOPEN_RUT "r+" +#define FOPEN_WUT "w+" +#define FOPEN_AUT "a+" diff --git a/contrib/gdb/include/fopen-vms.h b/contrib/gdb/include/fopen-vms.h new file mode 100644 index 00000000000..da76b7fb59c --- /dev/null +++ b/contrib/gdb/include/fopen-vms.h @@ -0,0 +1,24 @@ +/* Macros for the 'type' part of an fopen, freopen or fdopen. + + [Update] + + This version is for VMS systems, where text and binary files are + different. + This file is designed for inclusion by host-dependent .h files. No + user application should include it directly, since that would make + the application unable to be configured for both "same" and "binary" + variant systems. */ + +#define FOPEN_RB "rb","rfm=var" +#define FOPEN_WB "wb","rfm=var" +#define FOPEN_AB "ab","rfm=var" +#define FOPEN_RUB "r+b","rfm=var" +#define FOPEN_WUB "w+b","rfm=var" +#define FOPEN_AUB "a+b","rfm=var" + +#define FOPEN_RT "r" +#define FOPEN_WT "w" +#define FOPEN_AT "a" +#define FOPEN_RUT "r+" +#define FOPEN_WUT "w+" +#define FOPEN_AUT "a+" diff --git a/contrib/gdb/include/gdb/callback.h b/contrib/gdb/include/gdb/callback.h new file mode 100644 index 00000000000..3fa419143ae --- /dev/null +++ b/contrib/gdb/include/gdb/callback.h @@ -0,0 +1,272 @@ +/* Remote target system call callback support. + Copyright 1997 Free Software Foundation, Inc. + Contributed by Cygnus Solutions. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This interface isn't intended to be specific to any particular kind + of remote (hardware, simulator, whatever). As such, support for it + (e.g. sim/common/callback.c) should *not* live in the simulator source + tree, nor should it live in the gdb source tree. */ + +/* There are various ways to handle system calls: + + 1) Have a simulator intercept the appropriate trap instruction and + directly perform the system call on behalf of the target program. + This is the typical way of handling system calls for embedded targets. + [Handling system calls for embedded targets isn't that much of an + oxymoron as running compiler testsuites make use of the capability.] + + This method of system call handling is done when STATE_ENVIRONMENT + is ENVIRONMENT_USER. + + 2) Have a simulator emulate the hardware as much as possible. + If the program running on the real hardware communicates with some sort + of target manager, one would want to be able to run this program on the + simulator as well. + + This method of system call handling is done when STATE_ENVIRONMENT + is ENVIRONMENT_OPERATING. +*/ + +#ifndef CALLBACK_H +#define CALLBACK_H + +/* ??? The reason why we check for va_start here should be documented. */ + +#ifndef va_start +#include +#ifdef ANSI_PROTOTYPES +#include +#else +#include +#endif +#endif + +/* Mapping of host/target values. */ +/* ??? For debugging purposes, one might want to add a string of the + name of the symbol. */ + +typedef struct { + int host_val; + int target_val; +} CB_TARGET_DEFS_MAP; + +#define MAX_CALLBACK_FDS 10 + +/* Forward decl for stat/fstat. */ +struct stat; + +typedef struct host_callback_struct host_callback; + +struct host_callback_struct +{ + int (*close) PARAMS ((host_callback *,int)); + int (*get_errno) PARAMS ((host_callback *)); + int (*isatty) PARAMS ((host_callback *, int)); + int (*lseek) PARAMS ((host_callback *, int, long , int)); + int (*open) PARAMS ((host_callback *, const char*, int mode)); + int (*read) PARAMS ((host_callback *,int, char *, int)); + int (*read_stdin) PARAMS (( host_callback *, char *, int)); + int (*rename) PARAMS ((host_callback *, const char *, const char *)); + int (*system) PARAMS ((host_callback *, const char *)); + long (*time) PARAMS ((host_callback *, long *)); + int (*unlink) PARAMS ((host_callback *, const char *)); + int (*write) PARAMS ((host_callback *,int, const char *, int)); + int (*write_stdout) PARAMS ((host_callback *, const char *, int)); + void (*flush_stdout) PARAMS ((host_callback *)); + int (*write_stderr) PARAMS ((host_callback *, const char *, int)); + void (*flush_stderr) PARAMS ((host_callback *)); + int (*stat) PARAMS ((host_callback *, const char *, struct stat *)); + int (*fstat) PARAMS ((host_callback *, int, struct stat *)); + int (*ftruncate) PARAMS ((host_callback *, int, long)); + int (*truncate) PARAMS ((host_callback *, const char *, long)); + + /* When present, call to the client to give it the oportunity to + poll any io devices for a request to quit (indicated by a nonzero + return value). */ + int (*poll_quit) PARAMS ((host_callback *)); + + /* Used when the target has gone away, so we can close open + handles and free memory etc etc. */ + int (*shutdown) PARAMS ((host_callback *)); + int (*init) PARAMS ((host_callback *)); + + /* depreciated, use vprintf_filtered - Talk to the user on a console. */ + void (*printf_filtered) PARAMS ((host_callback *, const char *, ...)); + + /* Talk to the user on a console. */ + void (*vprintf_filtered) PARAMS ((host_callback *, const char *, va_list)); + + /* Same as vprintf_filtered but to stderr. */ + void (*evprintf_filtered) PARAMS ((host_callback *, const char *, va_list)); + + /* Print an error message and "exit". + In the case of gdb "exiting" means doing a longjmp back to the main + command loop. */ + void (*error) PARAMS ((host_callback *, const char *, ...)); + + int last_errno; /* host format */ + + int fdmap[MAX_CALLBACK_FDS]; + char fdopen[MAX_CALLBACK_FDS]; + char alwaysopen[MAX_CALLBACK_FDS]; + + /* System call numbers. */ + CB_TARGET_DEFS_MAP *syscall_map; + /* Errno values. */ + CB_TARGET_DEFS_MAP *errno_map; + /* Flags to the open system call. */ + CB_TARGET_DEFS_MAP *open_map; + /* Signal numbers. */ + CB_TARGET_DEFS_MAP *signal_map; + /* Layout of `stat' struct. + The format is a series of "name,length" pairs separated by colons. + Empty space is indicated with a `name' of "space". + All padding must be explicitly mentioned. + Lengths are in bytes. If this needs to be extended to bits, + use "name.bits". + Example: "st_dev,4:st_ino,4:st_mode,4:..." */ + const char *stat_map; + + /* Marker for those wanting to do sanity checks. + This should remain the last member of this struct to help catch + miscompilation errors. */ +#define HOST_CALLBACK_MAGIC 4705 /* teds constant */ + int magic; +}; + +extern host_callback default_callback; + +/* Canonical versions of system call numbers. + It's not intended to willy-nilly throw every system call ever heard + of in here. Only include those that have an important use. + ??? One can certainly start a discussion over the ones that are currently + here, but that will always be true. */ + +/* These are used by the ANSI C support of libc. */ +#define CB_SYS_exit 1 +#define CB_SYS_open 2 +#define CB_SYS_close 3 +#define CB_SYS_read 4 +#define CB_SYS_write 5 +#define CB_SYS_lseek 6 +#define CB_SYS_unlink 7 +#define CB_SYS_getpid 8 +#define CB_SYS_kill 9 +#define CB_SYS_fstat 10 +/*#define CB_SYS_sbrk 11 - not currently a system call, but reserved. */ + +/* ARGV support. */ +#define CB_SYS_argvlen 12 +#define CB_SYS_argv 13 + +/* These are extras added for one reason or another. */ +#define CB_SYS_chdir 14 +#define CB_SYS_stat 15 +#define CB_SYS_chmod 16 +#define CB_SYS_utime 17 +#define CB_SYS_time 18 + +/* Struct use to pass and return information necessary to perform a + system call. */ +/* FIXME: Need to consider target word size. */ + +typedef struct cb_syscall { + /* The target's value of what system call to perform. */ + int func; + /* The arguments to the syscall. */ + long arg1, arg2, arg3, arg4; + + /* The result. */ + long result; + /* Some system calls have two results. */ + long result2; + /* The target's errno value, or 0 if success. + This is converted to the target's value with host_to_target_errno. */ + int errcode; + + /* Working space to be used by memory read/write callbacks. */ + PTR p1; + PTR p2; + long x1,x2; + + /* Callbacks for reading/writing memory (e.g. for read/write syscalls). + ??? long or unsigned long might be better to use for the `count' + argument here. We mimic sim_{read,write} for now. Be careful to + test any changes with -Wall -Werror, mixed signed comparisons + will get you. */ + int (*read_mem) PARAMS ((host_callback * /*cb*/, struct cb_syscall * /*sc*/, + unsigned long /*taddr*/, char * /*buf*/, + int /*bytes*/)); + int (*write_mem) PARAMS ((host_callback * /*cb*/, struct cb_syscall * /*sc*/, + unsigned long /*taddr*/, const char * /*buf*/, + int /*bytes*/)); + + /* For sanity checking, should be last entry. */ + int magic; +} CB_SYSCALL; + +/* Magic number sanity checker. */ +#define CB_SYSCALL_MAGIC 0x12344321 + +/* Macro to initialize CB_SYSCALL. Called first, before filling in + any fields. */ +#define CB_SYSCALL_INIT(sc) \ +do { \ + memset ((sc), 0, sizeof (*(sc))); \ + (sc)->magic = CB_SYSCALL_MAGIC; \ +} while (0) + +/* Return codes for various interface routines. */ + +typedef enum { + CB_RC_OK = 0, + /* generic error */ + CB_RC_ERR, + /* either file not found or no read access */ + CB_RC_ACCESS, + CB_RC_NO_MEM +} CB_RC; + +/* Read in target values for system call numbers, errno values, signals. */ +CB_RC cb_read_target_syscall_maps PARAMS ((host_callback *, const char *)); + +/* Translate target to host syscall function numbers. */ +int cb_target_to_host_syscall PARAMS ((host_callback *, int)); + +/* Translate host to target errno value. */ +int cb_host_to_target_errno PARAMS ((host_callback *, int)); + +/* Translate target to host open flags. */ +int cb_target_to_host_open PARAMS ((host_callback *, int)); + +/* Translate target signal number to host. */ +int cb_target_to_host_signal PARAMS ((host_callback *, int)); + +/* Translate host signal number to target. */ +int cb_host_to_target_signal PARAMS ((host_callback *, int)); + +/* Translate host stat struct to target. + If stat struct ptr is NULL, just compute target stat struct size. + Result is size of target stat struct or 0 if error. */ +int cb_host_to_target_stat PARAMS ((host_callback *, const struct stat *, PTR)); + +/* Perform a system call. */ +CB_RC cb_syscall PARAMS ((host_callback *, CB_SYSCALL *)); + +#endif diff --git a/contrib/gdb/include/gdb/fileio.h b/contrib/gdb/include/gdb/fileio.h new file mode 100644 index 00000000000..d84478103e2 --- /dev/null +++ b/contrib/gdb/include/gdb/fileio.h @@ -0,0 +1,146 @@ +/* Hosted File I/O interface definitions, for GDB, the GNU Debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef GDB_FILEIO_H_ +#define GDB_FILEIO_H_ + +/* The following flags are defined to be independent of the host + as well as the target side implementation of these constants. + All constants are defined with a leading FILEIO_ in the name + to allow the usage of these constants together with the + corresponding implementation dependent constants in one module. */ + +/* open(2) flags */ +#define FILEIO_O_RDONLY 0x0 +#define FILEIO_O_WRONLY 0x1 +#define FILEIO_O_RDWR 0x2 +#define FILEIO_O_APPEND 0x8 +#define FILEIO_O_CREAT 0x200 +#define FILEIO_O_TRUNC 0x400 +#define FILEIO_O_EXCL 0x800 +#define FILEIO_O_SUPPORTED (FILEIO_O_RDONLY | FILEIO_O_WRONLY| \ + FILEIO_O_RDWR | FILEIO_O_APPEND| \ + FILEIO_O_CREAT | FILEIO_O_TRUNC| \ + FILEIO_O_EXCL) + +/* mode_t bits */ +#define FILEIO_S_IFREG 0100000 +#define FILEIO_S_IFDIR 040000 +#define FILEIO_S_IFCHR 020000 +#define FILEIO_S_IRUSR 0400 +#define FILEIO_S_IWUSR 0200 +#define FILEIO_S_IXUSR 0100 +#define FILEIO_S_IRWXU 0700 +#define FILEIO_S_IRGRP 040 +#define FILEIO_S_IWGRP 020 +#define FILEIO_S_IXGRP 010 +#define FILEIO_S_IRWXG 070 +#define FILEIO_S_IROTH 04 +#define FILEIO_S_IWOTH 02 +#define FILEIO_S_IXOTH 01 +#define FILEIO_S_IRWXO 07 +#define FILEIO_S_SUPPORTED (FILEIO_S_IFREG|FILEIO_S_IFDIR| \ + FILEIO_S_IRWXU|FILEIO_S_IRWXG| \ + FILEIO_S_IRWXO) + +/* lseek(2) flags */ +#define FILEIO_SEEK_SET 0 +#define FILEIO_SEEK_CUR 1 +#define FILEIO_SEEK_END 2 + +/* errno values */ +#define FILEIO_EPERM 1 +#define FILEIO_ENOENT 2 +#define FILEIO_EINTR 4 +#define FILEIO_EIO 5 +#define FILEIO_EBADF 9 +#define FILEIO_EACCES 13 +#define FILEIO_EFAULT 14 +#define FILEIO_EBUSY 16 +#define FILEIO_EEXIST 17 +#define FILEIO_ENODEV 19 +#define FILEIO_ENOTDIR 20 +#define FILEIO_EISDIR 21 +#define FILEIO_EINVAL 22 +#define FILEIO_ENFILE 23 +#define FILEIO_EMFILE 24 +#define FILEIO_EFBIG 27 +#define FILEIO_ENOSPC 28 +#define FILEIO_ESPIPE 29 +#define FILEIO_EROFS 30 +#define FILEIO_ENOSYS 88 +#define FILEIO_ENAMETOOLONG 91 +#define FILEIO_EUNKNOWN 9999 + +/* limits */ +#define FILEIO_INT_MIN -2147483648L +#define FILEIO_INT_MAX 2147483647L +#define FILEIO_UINT_MAX 4294967295UL +#define FILEIO_LONG_MIN -9223372036854775808LL +#define FILEIO_LONG_MAX 9223372036854775807LL +#define FILEIO_ULONG_MAX 18446744073709551615ULL + +/* Integral types as used in protocol. */ +#if 0 +typedef __int32_t fio_int_t; +typedef __uint32_t fio_uint_t, fio_mode_t, fio_time_t; +typedef __int64_t fio_long_t; +typedef __uint64_t fio_ulong_t; +#endif + +#define FIO_INT_LEN 4 +#define FIO_UINT_LEN 4 +#define FIO_MODE_LEN 4 +#define FIO_TIME_LEN 4 +#define FIO_LONG_LEN 8 +#define FIO_ULONG_LEN 8 + +typedef char fio_int_t[FIO_INT_LEN]; +typedef char fio_uint_t[FIO_UINT_LEN]; +typedef char fio_mode_t[FIO_MODE_LEN]; +typedef char fio_time_t[FIO_TIME_LEN]; +typedef char fio_long_t[FIO_LONG_LEN]; +typedef char fio_ulong_t[FIO_ULONG_LEN]; + +/* Struct stat as used in protocol. For complete independence + of host/target systems, it's defined as an array with offsets + to the members. */ + +struct fio_stat { + fio_uint_t fst_dev; + fio_uint_t fst_ino; + fio_mode_t fst_mode; + fio_uint_t fst_nlink; + fio_uint_t fst_uid; + fio_uint_t fst_gid; + fio_uint_t fst_rdev; + fio_ulong_t fst_size; + fio_ulong_t fst_blksize; + fio_ulong_t fst_blocks; + fio_time_t fst_atime; + fio_time_t fst_mtime; + fio_time_t fst_ctime; +}; + +struct fio_timeval { + fio_time_t ftv_sec; + fio_long_t ftv_usec; +}; + +#endif /* GDB_FILEIO_H_ */ diff --git a/contrib/gdb/include/gdb/remote-sim.h b/contrib/gdb/include/gdb/remote-sim.h new file mode 100644 index 00000000000..a49ba1a89e9 --- /dev/null +++ b/contrib/gdb/include/gdb/remote-sim.h @@ -0,0 +1,282 @@ +/* This file defines the interface between the simulator and gdb. + + Copyright 1993, 1994, 1996, 1997, 1998, 2000, 2002 Free Software + Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if !defined (REMOTE_SIM_H) +#define REMOTE_SIM_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This file is used when building stand-alone simulators, so isolate this + file from gdb. */ + +/* Pick up CORE_ADDR_TYPE if defined (from gdb), otherwise use same value as + gdb does (unsigned int - from defs.h). */ + +#ifndef CORE_ADDR_TYPE +typedef unsigned int SIM_ADDR; +#else +typedef CORE_ADDR_TYPE SIM_ADDR; +#endif + + +/* Semi-opaque type used as result of sim_open and passed back to all + other routines. "desc" is short for "descriptor". + It is up to each simulator to define `sim_state'. */ + +typedef struct sim_state *SIM_DESC; + + +/* Values for `kind' arg to sim_open. */ + +typedef enum { + SIM_OPEN_STANDALONE, /* simulator used standalone (run.c) */ + SIM_OPEN_DEBUG /* simulator used by debugger (gdb) */ +} SIM_OPEN_KIND; + + +/* Return codes from various functions. */ + +typedef enum { + SIM_RC_FAIL = 0, + SIM_RC_OK = 1 +} SIM_RC; + + +/* The bfd struct, as an opaque type. */ + +struct bfd; + + +/* Main simulator entry points. */ + + +/* Create a fully initialized simulator instance. + + (This function is called when the simulator is selected from the + gdb command line.) + + KIND specifies how the simulator shall be used. Currently there + are only two kinds: stand-alone and debug. + + CALLBACK specifies a standard host callback (defined in callback.h). + + ABFD, when non NULL, designates a target program. The program is + not loaded. + + ARGV is a standard ARGV pointer such as that passed from the + command line. The syntax of the argument list is is assumed to be + ``SIM-PROG { SIM-OPTION } [ TARGET-PROGRAM { TARGET-OPTION } ]''. + The trailing TARGET-PROGRAM and args are only valid for a + stand-alone simulator. + + On success, the result is a non NULL descriptor that shall be + passed to the other sim_foo functions. While the simulator + configuration can be parameterized by (in decreasing precedence) + ARGV's SIM-OPTION, ARGV's TARGET-PROGRAM and the ABFD argument, the + successful creation of the simulator shall not dependent on the + presence of any of these arguments/options. + + Hardware simulator: The created simulator shall be sufficiently + initialized to handle, with out restrictions any client requests + (including memory reads/writes, register fetch/stores and a + resume). + + Process simulator: that process is not created until a call to + sim_create_inferior. FIXME: What should the state of the simulator + be? */ + +SIM_DESC sim_open PARAMS ((SIM_OPEN_KIND kind, struct host_callback_struct *callback, struct bfd *abfd, char **argv)); + + +/* Destory a simulator instance. + + QUITTING is non-zero if we cannot hang on errors. + + This may involve freeing target memory and closing any open files + and mmap'd areas. You cannot assume sim_kill has already been + called. */ + +void sim_close PARAMS ((SIM_DESC sd, int quitting)); + + +/* Load program PROG into the simulators memory. + + If ABFD is non-NULL, the bfd for the file has already been opened. + The result is a return code indicating success. + + Hardware simulator: Normally, each program section is written into + memory according to that sections LMA using physical (direct) + addressing. The exception being systems, such as PPC/CHRP, which + support more complicated program loaders. A call to this function + should not effect the state of the processor registers. Multiple + calls to this function are permitted and have an accumulative + effect. + + Process simulator: Calls to this function may be ignored. + + FIXME: Most hardware simulators load the image at the VMA using + virtual addressing. + + FIXME: For some hardware targets, before a loaded program can be + executed, it requires the manipulation of VM registers and tables. + Such manipulation should probably (?) occure in + sim_create_inferior. */ + +SIM_RC sim_load PARAMS ((SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)); + + +/* Prepare to run the simulated program. + + ABFD, if not NULL, provides initial processor state information. + ARGV and ENV, if non NULL, are NULL terminated lists of pointers. + + Hardware simulator: This function shall initialize the processor + registers to a known value. The program counter and possibly stack + pointer shall be set using information obtained from ABFD (or + hardware reset defaults). ARGV and ENV, dependant on the target + ABI, may be written to memory. + + Process simulator: After a call to this function, a new process + instance shall exist. The TEXT, DATA, BSS and stack regions shall + all be initialized, ARGV and ENV shall be written to process + address space (according to the applicable ABI) and the program + counter and stack pointer set accordingly. */ + +SIM_RC sim_create_inferior PARAMS ((SIM_DESC sd, struct bfd *abfd, char **argv, char **env)); + + +/* Fetch LENGTH bytes of the simulated program's memory. Start fetch + at virtual address MEM and store in BUF. Result is number of bytes + read, or zero if error. */ + +int sim_read PARAMS ((SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)); + + +/* Store LENGTH bytes from BUF into the simulated program's + memory. Store bytes starting at virtual address MEM. Result is + number of bytes write, or zero if error. */ + +int sim_write PARAMS ((SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)); + + +/* Fetch register REGNO storing its raw (target endian) value in the + LENGTH byte buffer BUF. Return the actual size of the register or + zero if REGNO is not applicable. + + Legacy implementations ignore LENGTH and always return -1. + + If LENGTH does not match the size of REGNO no data is transfered + (the actual register size is still returned). */ + +int sim_fetch_register PARAMS ((SIM_DESC sd, int regno, unsigned char *buf, int length)); + + +/* Store register REGNO from the raw (target endian) value in BUF. + Return the actual size of the register or zero if REGNO is not + applicable. + + Legacy implementations ignore LENGTH and always return -1. + + If LENGTH does not match the size of REGNO no data is transfered + (the actual register size is still returned). */ + +int sim_store_register PARAMS ((SIM_DESC sd, int regno, unsigned char *buf, int length)); + + +/* Print whatever statistics the simulator has collected. + + VERBOSE is currently unused and must always be zero. */ + +void sim_info PARAMS ((SIM_DESC sd, int verbose)); + + +/* Run (or resume) the simulated program. + + STEP, when non-zero indicates that only a single simulator cycle + should be emulated. + + SIGGNAL, if non-zero is a (HOST) SIGRC value indicating the type of + event (hardware interrupt, signal) to be delivered to the simulated + program. + + Hardware simulator: If the SIGRC value returned by + sim_stop_reason() is passed back to the simulator via SIGGNAL then + the hardware simulator shall correctly deliver the hardware event + indicated by that signal. If a value of zero is passed in then the + simulation will continue as if there were no outstanding signal. + The effect of any other SIGGNAL value is is implementation + dependant. + + Process simulator: If SIGRC is non-zero then the corresponding + signal is delivered to the simulated program and execution is then + continued. A zero SIGRC value indicates that the program should + continue as normal. */ + +void sim_resume PARAMS ((SIM_DESC sd, int step, int siggnal)); + + +/* Asynchronous request to stop the simulation. + A nonzero return indicates that the simulator is able to handle + the request */ + +int sim_stop PARAMS ((SIM_DESC sd)); + + +/* Fetch the REASON why the program stopped. + + SIM_EXITED: The program has terminated. SIGRC indicates the target + dependant exit status. + + SIM_STOPPED: The program has stopped. SIGRC uses the host's signal + numbering as a way of identifying the reaon: program interrupted by + user via a sim_stop request (SIGINT); a breakpoint instruction + (SIGTRAP); a completed single step (SIGTRAP); an internal error + condition (SIGABRT); an illegal instruction (SIGILL); Access to an + undefined memory region (SIGSEGV); Mis-aligned memory access + (SIGBUS). For some signals information in addition to the signal + number may be retained by the simulator (e.g. offending address), + that information is not directly accessable via this interface. + + SIM_SIGNALLED: The program has been terminated by a signal. The + simulator has encountered target code that causes the the program + to exit with signal SIGRC. + + SIM_RUNNING, SIM_POLLING: The return of one of these values + indicates a problem internal to the simulator. */ + +enum sim_stop { sim_running, sim_polling, sim_exited, sim_stopped, sim_signalled }; + +void sim_stop_reason PARAMS ((SIM_DESC sd, enum sim_stop *reason, int *sigrc)); + + +/* Passthru for other commands that the simulator might support. + Simulators should be prepared to deal with any combination of NULL + or empty CMD. */ + +void sim_do_command PARAMS ((SIM_DESC sd, char *cmd)); + +#ifdef __cplusplus +} +#endif + +#endif /* !defined (REMOTE_SIM_H) */ diff --git a/contrib/gdb/include/gdb/signals.h b/contrib/gdb/include/gdb/signals.h index 17107504e4a..b6f5d485312 100644 --- a/contrib/gdb/include/gdb/signals.h +++ b/contrib/gdb/include/gdb/signals.h @@ -32,7 +32,8 @@ Since these numbers have actually made it out into other software (stubs, etc.), you mustn't disturb the assigned numbering. If you need to add new signals here, add them to the end of the explicitly - numbered signals. + numbered signals, at the comment marker. Add them unconditionally, + not within any #if or #ifdef. This is based strongly on Unix/POSIX signals for several reasons: (1) This set of signals represents a widely-accepted attempt to @@ -208,15 +209,6 @@ enum target_signal TARGET_SIGNAL_REALTIME_126, TARGET_SIGNAL_REALTIME_127, -#if defined(MACH) || defined(__MACH__) - /* Mach exceptions */ - TARGET_EXC_BAD_ACCESS, - TARGET_EXC_BAD_INSTRUCTION, - TARGET_EXC_ARITHMETIC, - TARGET_EXC_EMULATION, - TARGET_EXC_SOFTWARE, - TARGET_EXC_BREAKPOINT, -#endif TARGET_SIGNAL_INFO, /* Some signal we don't know about. */ @@ -226,6 +218,18 @@ enum target_signal (for passing to proceed and so on). */ TARGET_SIGNAL_DEFAULT, + /* Mach exceptions. In versions of GDB before 5.2, these were just before + TARGET_SIGNAL_INFO if you were compiling on a Mach host (and missing + otherwise). */ + TARGET_EXC_BAD_ACCESS, + TARGET_EXC_BAD_INSTRUCTION, + TARGET_EXC_ARITHMETIC, + TARGET_EXC_EMULATION, + TARGET_EXC_SOFTWARE, + TARGET_EXC_BREAKPOINT, + + /* If you are adding a new signal, add it just above this comment. */ + /* Last and unused enum value, for sizing arrays, etc. */ TARGET_SIGNAL_LAST }; diff --git a/contrib/gdb/include/gdb/sim-arm.h b/contrib/gdb/include/gdb/sim-arm.h new file mode 100644 index 00000000000..5598f73fa8f --- /dev/null +++ b/contrib/gdb/include/gdb/sim-arm.h @@ -0,0 +1,114 @@ +/* This file defines the interface between the Arm simulator and GDB. + + Copyright 2002, 2003 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#if !defined (SIM_ARM_H) +#define SIM_ARM_H + +#ifdef __cplusplus +extern "C" { // } +#endif + +enum sim_arm_regs +{ + SIM_ARM_R0_REGNUM, + SIM_ARM_R1_REGNUM, + SIM_ARM_R2_REGNUM, + SIM_ARM_R3_REGNUM, + SIM_ARM_R4_REGNUM, + SIM_ARM_R5_REGNUM, + SIM_ARM_R6_REGNUM, + SIM_ARM_R7_REGNUM, + SIM_ARM_R8_REGNUM, + SIM_ARM_R9_REGNUM, + SIM_ARM_R10_REGNUM, + SIM_ARM_R11_REGNUM, + SIM_ARM_R12_REGNUM, + SIM_ARM_R13_REGNUM, + SIM_ARM_R14_REGNUM, + SIM_ARM_R15_REGNUM, /* PC */ + SIM_ARM_FP0_REGNUM, + SIM_ARM_FP1_REGNUM, + SIM_ARM_FP2_REGNUM, + SIM_ARM_FP3_REGNUM, + SIM_ARM_FP4_REGNUM, + SIM_ARM_FP5_REGNUM, + SIM_ARM_FP6_REGNUM, + SIM_ARM_FP7_REGNUM, + SIM_ARM_FPS_REGNUM, + SIM_ARM_PS_REGNUM, + SIM_ARM_MAVERIC_COP0R0_REGNUM, + SIM_ARM_MAVERIC_COP0R1_REGNUM, + SIM_ARM_MAVERIC_COP0R2_REGNUM, + SIM_ARM_MAVERIC_COP0R3_REGNUM, + SIM_ARM_MAVERIC_COP0R4_REGNUM, + SIM_ARM_MAVERIC_COP0R5_REGNUM, + SIM_ARM_MAVERIC_COP0R6_REGNUM, + SIM_ARM_MAVERIC_COP0R7_REGNUM, + SIM_ARM_MAVERIC_COP0R8_REGNUM, + SIM_ARM_MAVERIC_COP0R9_REGNUM, + SIM_ARM_MAVERIC_COP0R10_REGNUM, + SIM_ARM_MAVERIC_COP0R11_REGNUM, + SIM_ARM_MAVERIC_COP0R12_REGNUM, + SIM_ARM_MAVERIC_COP0R13_REGNUM, + SIM_ARM_MAVERIC_COP0R14_REGNUM, + SIM_ARM_MAVERIC_COP0R15_REGNUM, + SIM_ARM_MAVERIC_DSPSC_REGNUM, + SIM_ARM_IWMMXT_COP0R0_REGNUM, + SIM_ARM_IWMMXT_COP0R1_REGNUM, + SIM_ARM_IWMMXT_COP0R2_REGNUM, + SIM_ARM_IWMMXT_COP0R3_REGNUM, + SIM_ARM_IWMMXT_COP0R4_REGNUM, + SIM_ARM_IWMMXT_COP0R5_REGNUM, + SIM_ARM_IWMMXT_COP0R6_REGNUM, + SIM_ARM_IWMMXT_COP0R7_REGNUM, + SIM_ARM_IWMMXT_COP0R8_REGNUM, + SIM_ARM_IWMMXT_COP0R9_REGNUM, + SIM_ARM_IWMMXT_COP0R10_REGNUM, + SIM_ARM_IWMMXT_COP0R11_REGNUM, + SIM_ARM_IWMMXT_COP0R12_REGNUM, + SIM_ARM_IWMMXT_COP0R13_REGNUM, + SIM_ARM_IWMMXT_COP0R14_REGNUM, + SIM_ARM_IWMMXT_COP0R15_REGNUM, + SIM_ARM_IWMMXT_COP1R0_REGNUM, + SIM_ARM_IWMMXT_COP1R1_REGNUM, + SIM_ARM_IWMMXT_COP1R2_REGNUM, + SIM_ARM_IWMMXT_COP1R3_REGNUM, + SIM_ARM_IWMMXT_COP1R4_REGNUM, + SIM_ARM_IWMMXT_COP1R5_REGNUM, + SIM_ARM_IWMMXT_COP1R6_REGNUM, + SIM_ARM_IWMMXT_COP1R7_REGNUM, + SIM_ARM_IWMMXT_COP1R8_REGNUM, + SIM_ARM_IWMMXT_COP1R9_REGNUM, + SIM_ARM_IWMMXT_COP1R10_REGNUM, + SIM_ARM_IWMMXT_COP1R11_REGNUM, + SIM_ARM_IWMMXT_COP1R12_REGNUM, + SIM_ARM_IWMMXT_COP1R13_REGNUM, + SIM_ARM_IWMMXT_COP1R14_REGNUM, + SIM_ARM_IWMMXT_COP1R15_REGNUM +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/gdb/include/gdb/sim-d10v.h b/contrib/gdb/include/gdb/sim-d10v.h new file mode 100644 index 00000000000..8294b14858b --- /dev/null +++ b/contrib/gdb/include/gdb/sim-d10v.h @@ -0,0 +1,142 @@ +/* This file defines the interface between the d10v simulator and gdb. + + Copyright 1999, 2002 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if !defined (SIM_D10V_H) +#define SIM_D10V_H + +#ifdef __cplusplus +extern "C" { // } +#endif + +/* GDB interprets addresses as: + + 0x00xxxxxx: Physical unified memory segment (Unified memory) + 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) + 0x02xxxxxx: Physical data memory segment (On-chip data memory) + 0x10xxxxxx: Logical data address segment (DMAP translated memory) + 0x11xxxxxx: Logical instruction address segment (IMAP translated memory) + + The remote d10v board interprets addresses as: + + 0x00xxxxxx: Physical unified memory segment (Unified memory) + 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) + 0x02xxxxxx: Physical data memory segment (On-chip data memory) + + The following translate a virtual DMAP/IMAP offset into a physical + memory segment assigning the translated address to PHYS. Since a + memory access may cross a page boundrary the number of bytes for + which the translation is applicable (or 0 for an invalid virtual + offset) is returned. */ + +enum + { + SIM_D10V_MEMORY_UNIFIED = 0x00000000, + SIM_D10V_MEMORY_INSN = 0x01000000, + SIM_D10V_MEMORY_DATA = 0x02000000, + SIM_D10V_MEMORY_DMAP = 0x10000000, + SIM_D10V_MEMORY_IMAP = 0x11000000 + }; + +extern unsigned long sim_d10v_translate_dmap_addr + (unsigned long offset, + int nr_bytes, + unsigned long *phys, + void *regcache, + unsigned long (*dmap_register) (void *regcache, int reg_nr)); + +extern unsigned long sim_d10v_translate_imap_addr + (unsigned long offset, + int nr_bytes, + unsigned long *phys, + void *regcache, + unsigned long (*imap_register) (void *regcache, int reg_nr)); + +extern unsigned long sim_d10v_translate_addr + (unsigned long vaddr, + int nr_bytes, + unsigned long *phys, + void *regcache, + unsigned long (*dmap_register) (void *regcache, int reg_nr), + unsigned long (*imap_register) (void *regcache, int reg_nr)); + + +/* The simulator makes use of the following register information. */ + +enum sim_d10v_regs +{ + SIM_D10V_R0_REGNUM, + SIM_D10V_R1_REGNUM, + SIM_D10V_R2_REGNUM, + SIM_D10V_R3_REGNUM, + SIM_D10V_R4_REGNUM, + SIM_D10V_R5_REGNUM, + SIM_D10V_R6_REGNUM, + SIM_D10V_R7_REGNUM, + SIM_D10V_R8_REGNUM, + SIM_D10V_R9_REGNUM, + SIM_D10V_R10_REGNUM, + SIM_D10V_R11_REGNUM, + SIM_D10V_R12_REGNUM, + SIM_D10V_R13_REGNUM, + SIM_D10V_R14_REGNUM, + SIM_D10V_R15_REGNUM, + SIM_D10V_CR0_REGNUM, + SIM_D10V_CR1_REGNUM, + SIM_D10V_CR2_REGNUM, + SIM_D10V_CR3_REGNUM, + SIM_D10V_CR4_REGNUM, + SIM_D10V_CR5_REGNUM, + SIM_D10V_CR6_REGNUM, + SIM_D10V_CR7_REGNUM, + SIM_D10V_CR8_REGNUM, + SIM_D10V_CR9_REGNUM, + SIM_D10V_CR10_REGNUM, + SIM_D10V_CR11_REGNUM, + SIM_D10V_CR12_REGNUM, + SIM_D10V_CR13_REGNUM, + SIM_D10V_CR14_REGNUM, + SIM_D10V_CR15_REGNUM, + SIM_D10V_A0_REGNUM, + SIM_D10V_A1_REGNUM, + SIM_D10V_SPI_REGNUM, + SIM_D10V_SPU_REGNUM, + SIM_D10V_IMAP0_REGNUM, + SIM_D10V_IMAP1_REGNUM, + SIM_D10V_DMAP0_REGNUM, + SIM_D10V_DMAP1_REGNUM, + SIM_D10V_DMAP2_REGNUM, + SIM_D10V_DMAP3_REGNUM, + SIM_D10V_TS2_DMAP_REGNUM +}; + +enum +{ + SIM_D10V_NR_R_REGS = 16, + SIM_D10V_NR_A_REGS = 2, + SIM_D10V_NR_IMAP_REGS = 2, + SIM_D10V_NR_DMAP_REGS = 4, + SIM_D10V_NR_CR_REGS = 16 +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/gdb/include/gdb/sim-frv.h b/contrib/gdb/include/gdb/sim-frv.h new file mode 100644 index 00000000000..0a1e0212e52 --- /dev/null +++ b/contrib/gdb/include/gdb/sim-frv.h @@ -0,0 +1,53 @@ +/* This file defines the interface between the FR-V simulator and GDB. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#if !defined (SIM_FRV_H) +#define SIM_FRV_H + +#ifdef __cplusplus +extern "C" { // } +#endif + +enum sim_frv_regs +{ + SIM_FRV_GR0_REGNUM = 0, + SIM_FRV_GR63_REGNUM = 63, + SIM_FRV_FR0_REGNUM = 64, + SIM_FRV_FR63_REGNUM = 127, + SIM_FRV_PC_REGNUM = 128, + + /* An FR-V architecture may have up to 4096 special purpose registers + (SPRs). In order to determine a specific constant used to access + a particular SPR, one of the H_SPR_ prefixed offsets defined in + opcodes/frv-desc.h should be added to SIM_FRV_SPR0_REGNUM. So, + for example, the number that GDB uses to fetch the link register + from the simulator is (SIM_FRV_SPR0_REGNUM + H_SPR_LR). */ + SIM_FRV_SPR0_REGNUM = 129, + SIM_FRV_SPR4095_REGNUM = SIM_FRV_SPR0_REGNUM + 4095 +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/gdb/include/gdb/sim-h8300.h b/contrib/gdb/include/gdb/sim-h8300.h new file mode 100644 index 00000000000..246370aec23 --- /dev/null +++ b/contrib/gdb/include/gdb/sim-h8300.h @@ -0,0 +1,78 @@ +/* This file defines the interface between the h8300 simulator and gdb. + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if !defined (SIM_H8300_H) +#define SIM_H8300_H + +#ifdef __cplusplus +extern "C" { //} +#endif + +/* The simulator makes use of the following register information. */ + + enum sim_h8300_regs + { + /* Registers common to all the H8 variants. */ + /* Start here: */ + SIM_H8300_R0_REGNUM, + SIM_H8300_R1_REGNUM, + SIM_H8300_R2_REGNUM, + SIM_H8300_R3_REGNUM, + SIM_H8300_R4_REGNUM, + SIM_H8300_R5_REGNUM, + SIM_H8300_R6_REGNUM, + SIM_H8300_R7_REGNUM, + + SIM_H8300_CCR_REGNUM, /* Contains processor status */ + SIM_H8300_PC_REGNUM, /* Contains program counter */ + /* End here */ + + SIM_H8300_EXR_REGNUM, /* Contains extended processor status + H8S and higher */ + SIM_H8300_MACL_REGNUM, /* Lower part of MAC register (26xx only)*/ + SIM_H8300_MACH_REGNUM, /* High part of MAC register (26xx only) */ + + SIM_H8300_CYCLE_REGNUM, + SIM_H8300_INST_REGNUM, + SIM_H8300_TICK_REGNUM + }; + + enum + { + SIM_H8300_ARG_FIRST_REGNUM = SIM_H8300_R0_REGNUM, /* first reg in which an arg + may be passed */ + SIM_H8300_ARG_LAST_REGNUM = SIM_H8300_R3_REGNUM, /* last reg in which an arg + may be passed */ + SIM_H8300_FP_REGNUM = SIM_H8300_R6_REGNUM, /* Contain address of executing + stack frame */ + SIM_H8300_SP_REGNUM = SIM_H8300_R7_REGNUM /* Contains address of top of stack */ + }; + + enum + { + SIM_H8300_NUM_COMMON_REGS = 10, + SIM_H8300_S_NUM_REGS = 13, + SIM_H8300_NUM_REGS = 16 + }; + +#ifdef __cplusplus +} +#endif + +#endif /* SIM_H8300_H */ diff --git a/contrib/gdb/include/gdb/sim-sh.h b/contrib/gdb/include/gdb/sim-sh.h new file mode 100644 index 00000000000..ec0d6276b4b --- /dev/null +++ b/contrib/gdb/include/gdb/sim-sh.h @@ -0,0 +1,161 @@ +/* This file defines the interface between the sh simulator and gdb. + Copyright (C) 2000, 2002 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if !defined (SIM_SH_H) +#define SIM_SH_H + +#ifdef __cplusplus +extern "C" { // } +#endif + +/* The simulator makes use of the following register information. */ + +enum +{ + SIM_SH_R0_REGNUM = 0, + SIM_SH_R1_REGNUM, + SIM_SH_R2_REGNUM, + SIM_SH_R3_REGNUM, + SIM_SH_R4_REGNUM, + SIM_SH_R5_REGNUM, + SIM_SH_R6_REGNUM, + SIM_SH_R7_REGNUM, + SIM_SH_R8_REGNUM, + SIM_SH_R9_REGNUM, + SIM_SH_R10_REGNUM, + SIM_SH_R11_REGNUM, + SIM_SH_R12_REGNUM, + SIM_SH_R13_REGNUM, + SIM_SH_R14_REGNUM, + SIM_SH_R15_REGNUM, + SIM_SH_PC_REGNUM, + SIM_SH_PR_REGNUM, + SIM_SH_GBR_REGNUM, + SIM_SH_VBR_REGNUM, + SIM_SH_MACH_REGNUM, + SIM_SH_MACL_REGNUM, + SIM_SH_SR_REGNUM, + SIM_SH_FPUL_REGNUM, + SIM_SH_FPSCR_REGNUM, + SIM_SH_FR0_REGNUM, /* FRn registers: sh3e / sh4 */ + SIM_SH_FR1_REGNUM, + SIM_SH_FR2_REGNUM, + SIM_SH_FR3_REGNUM, + SIM_SH_FR4_REGNUM, + SIM_SH_FR5_REGNUM, + SIM_SH_FR6_REGNUM, + SIM_SH_FR7_REGNUM, + SIM_SH_FR8_REGNUM, + SIM_SH_FR9_REGNUM, + SIM_SH_FR10_REGNUM, + SIM_SH_FR11_REGNUM, + SIM_SH_FR12_REGNUM, + SIM_SH_FR13_REGNUM, + SIM_SH_FR14_REGNUM, + SIM_SH_FR15_REGNUM, + SIM_SH_SSR_REGNUM, /* sh3{,e,-dsp}, sh4 */ + SIM_SH_SPC_REGNUM, /* sh3{,e,-dsp}, sh4 */ + SIM_SH_R0_BANK0_REGNUM, /* SIM_SH_Rn_BANKm_REGNUM: sh3[e] / sh4 */ + SIM_SH_R1_BANK0_REGNUM, + SIM_SH_R2_BANK0_REGNUM, + SIM_SH_R3_BANK0_REGNUM, + SIM_SH_R4_BANK0_REGNUM, + SIM_SH_R5_BANK0_REGNUM, + SIM_SH_R6_BANK0_REGNUM, + SIM_SH_R7_BANK0_REGNUM, + SIM_SH_R0_BANK1_REGNUM, + SIM_SH_R1_BANK1_REGNUM, + SIM_SH_R2_BANK1_REGNUM, + SIM_SH_R3_BANK1_REGNUM, + SIM_SH_R4_BANK1_REGNUM, + SIM_SH_R5_BANK1_REGNUM, + SIM_SH_R6_BANK1_REGNUM, + SIM_SH_R7_BANK1_REGNUM, + SIM_SH_XF0_REGNUM, + SIM_SH_XF1_REGNUM, + SIM_SH_XF2_REGNUM, + SIM_SH_XF3_REGNUM, + SIM_SH_XF4_REGNUM, + SIM_SH_XF5_REGNUM, + SIM_SH_XF6_REGNUM, + SIM_SH_XF7_REGNUM, + SIM_SH_XF8_REGNUM, + SIM_SH_XF9_REGNUM, + SIM_SH_XF10_REGNUM, + SIM_SH_XF11_REGNUM, + SIM_SH_XF12_REGNUM, + SIM_SH_XF13_REGNUM, + SIM_SH_XF14_REGNUM, + SIM_SH_XF15_REGNUM, + SIM_SH_SGR_REGNUM, + SIM_SH_DBR_REGNUM, + SIM_SH4_NUM_REGS, /* 77 */ + + /* sh[3]-dsp */ + SIM_SH_DSR_REGNUM, + SIM_SH_A0G_REGNUM, + SIM_SH_A0_REGNUM, + SIM_SH_A1G_REGNUM, + SIM_SH_A1_REGNUM, + SIM_SH_M0_REGNUM, + SIM_SH_M1_REGNUM, + SIM_SH_X0_REGNUM, + SIM_SH_X1_REGNUM, + SIM_SH_Y0_REGNUM, + SIM_SH_Y1_REGNUM, + SIM_SH_MOD_REGNUM, + SIM_SH_RS_REGNUM, + SIM_SH_RE_REGNUM, + SIM_SH_R0_BANK_REGNUM, + SIM_SH_R1_BANK_REGNUM, + SIM_SH_R2_BANK_REGNUM, + SIM_SH_R3_BANK_REGNUM, + SIM_SH_R4_BANK_REGNUM, + SIM_SH_R5_BANK_REGNUM, + SIM_SH_R6_BANK_REGNUM, + SIM_SH_R7_BANK_REGNUM + /* 100..127: room for expansion. */ +}; + +enum +{ + SIM_SH64_R0_REGNUM = 0, + SIM_SH64_SP_REGNUM = 15, + SIM_SH64_PC_REGNUM = 64, + SIM_SH64_SR_REGNUM = 65, + SIM_SH64_SSR_REGNUM = 66, + SIM_SH64_SPC_REGNUM = 67, + SIM_SH64_TR0_REGNUM = 68, + SIM_SH64_FPCSR_REGNUM = 76, + SIM_SH64_FR0_REGNUM = 77 +}; + +enum +{ + SIM_SH64_NR_REGS = 141, /* total number of architectural registers */ + SIM_SH64_NR_R_REGS = 64, /* number of general registers */ + SIM_SH64_NR_TR_REGS = 8, /* number of target registers */ + SIM_SH64_NR_FP_REGS = 64 /* number of floating point registers */ +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/gdb/include/gdbm.h b/contrib/gdb/include/gdbm.h new file mode 100644 index 00000000000..3ebc26d198a --- /dev/null +++ b/contrib/gdb/include/gdbm.h @@ -0,0 +1,91 @@ +/* GNU DBM - DataBase Manager include file + Copyright 1989, 1991 Free Software Foundation, Inc. + Written by Philip A. Nelson. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* You may contact the author by: + e-mail: phil@wwu.edu + us-mail: Philip A. Nelson + Computer Science Department + Western Washington University + Bellingham, WA 98226 + phone: (206) 676-3035 + +*************************************************************************/ + +/* Parameters to gdbm_open for READERS, WRITERS, and WRITERS who + can create the database. */ +#define GDBM_READER 0 +#define GDBM_WRITER 1 +#define GDBM_WRCREAT 2 +#define GDBM_NEWDB 3 + +/* Parameters to gdbm_store for simple insertion or replacement. */ +#define GDBM_INSERT 0 +#define GDBM_REPLACE 1 + + +/* The data and key structure. This structure is defined for compatibility. */ +typedef struct { + char *dptr; + int dsize; + } datum; + + +/* The file information header. This is good enough for most applications. */ +typedef struct {int dummy[10];} *GDBM_FILE; + + +/* These are the routines! */ + +extern GDBM_FILE gdbm_open (); + +extern void gdbm_close (); + +extern datum gdbm_fetch (); + +extern int gdbm_store (); + +extern int gdbm_delete (); + +extern datum gdbm_firstkey (); + +extern datum gdbm_nextkey (); + +extern int gdbm_reorganize (); + + +/* gdbm sends back the following error codes in the variable gdbm_errno. */ +typedef enum { NO_ERROR, + MALLOC_ERROR, + BLOCK_SIZE_ERROR, + FILE_OPEN_ERROR, + FILE_WRITE_ERROR, + FILE_SEEK_ERROR, + FILE_READ_ERROR, + BAD_MAGIC_NUMBER, + EMPTY_DATABASE, + CANT_BE_READER, + CANT_BE_WRITER, + READER_CANT_RECOVER, + READER_CANT_DELETE, + READER_CANT_STORE, + READER_CANT_REORGANIZE, + UNKNOWN_UPDATE, + ITEM_NOT_FOUND, + REORGANIZE_FAILED, + CANNOT_REPLACE} + gdbm_error; diff --git a/contrib/gdb/include/getopt.h b/contrib/gdb/include/getopt.h new file mode 100644 index 00000000000..a99a2290159 --- /dev/null +++ b/contrib/gdb/include/getopt.h @@ -0,0 +1,144 @@ +/* Declarations for getopt. + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000, + 2002 Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if defined (__STDC__) && __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if defined (__STDC__) && __STDC__ +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is + undefined, we haven't run the autoconf check so provide the + declaration without arguments. If it is 0, we checked and failed + to find the declaration so provide a fully prototyped one. If it + is 1, we found it so don't provide any declaration at all. */ +#if !HAVE_DECL_GETOPT +#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in unistd.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else +#ifndef __cplusplus +extern int getopt (); +#endif /* __cplusplus */ +#endif +#endif /* !HAVE_DECL_GETOPT */ + +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* getopt.h */ diff --git a/contrib/gdb/include/hashtab.h b/contrib/gdb/include/hashtab.h new file mode 100644 index 00000000000..f7bd4ae69d3 --- /dev/null +++ b/contrib/gdb/include/hashtab.h @@ -0,0 +1,195 @@ +/* An expandable hash tables datatype. + Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. + Contributed by Vladimir Makarov (vmakarov@cygnus.com). + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This package implements basic hash table functionality. It is possible + to search for an entry, create an entry and destroy an entry. + + Elements in the table are generic pointers. + + The size of the table is not fixed; if the occupancy of the table + grows too high the hash table will be expanded. + + The abstract data implementation is based on generalized Algorithm D + from Knuth's book "The art of computer programming". Hash table is + expanded by creation of new hash table and transferring elements from + the old table to the new table. */ + +#ifndef __HASHTAB_H__ +#define __HASHTAB_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ansidecl.h" + +#ifndef GTY +#define GTY(X) +#endif + +/* The type for a hash code. */ +typedef unsigned int hashval_t; + +/* Callback function pointer types. */ + +/* Calculate hash of a table entry. */ +typedef hashval_t (*htab_hash) PARAMS ((const void *)); + +/* Compare a table entry with a possible entry. The entry already in + the table always comes first, so the second element can be of a + different type (but in this case htab_find and htab_find_slot + cannot be used; instead the variants that accept a hash value + must be used). */ +typedef int (*htab_eq) PARAMS ((const void *, const void *)); + +/* Cleanup function called whenever a live element is removed from + the hash table. */ +typedef void (*htab_del) PARAMS ((void *)); + +/* Function called by htab_traverse for each live element. The first + arg is the slot of the element (which can be passed to htab_clear_slot + if desired), the second arg is the auxiliary pointer handed to + htab_traverse. Return 1 to continue scan, 0 to stop. */ +typedef int (*htab_trav) PARAMS ((void **, void *)); + +/* Memory-allocation function, with the same functionality as calloc(). + Iff it returns NULL, the hash table implementation will pass an error + code back to the user, so if your code doesn't handle errors, + best if you use xcalloc instead. */ +typedef PTR (*htab_alloc) PARAMS ((size_t, size_t)); + +/* We also need a free() routine. */ +typedef void (*htab_free) PARAMS ((PTR)); + +/* Memory allocation and deallocation; variants which take an extra + argument. */ +typedef PTR (*htab_alloc_with_arg) PARAMS ((void *, size_t, size_t)); +typedef void (*htab_free_with_arg) PARAMS ((void *, void *)); + +/* Hash tables are of the following type. The structure + (implementation) of this type is not needed for using the hash + tables. All work with hash table should be executed only through + functions mentioned below. The size of this structure is subject to + change. */ + +struct htab GTY(()) +{ + /* Pointer to hash function. */ + htab_hash hash_f; + + /* Pointer to comparison function. */ + htab_eq eq_f; + + /* Pointer to cleanup function. */ + htab_del del_f; + + /* Table itself. */ + PTR * GTY ((use_param (""), length ("%h.size"))) entries; + + /* Current size (in entries) of the hash table */ + size_t size; + + /* Current number of elements including also deleted elements */ + size_t n_elements; + + /* Current number of deleted elements in the table */ + size_t n_deleted; + + /* The following member is used for debugging. Its value is number + of all calls of `htab_find_slot' for the hash table. */ + unsigned int searches; + + /* The following member is used for debugging. Its value is number + of collisions fixed for time of work with the hash table. */ + unsigned int collisions; + + /* Pointers to allocate/free functions. */ + htab_alloc alloc_f; + htab_free free_f; + + /* Alternate allocate/free functions, which take an extra argument. */ + PTR GTY((skip (""))) alloc_arg; + htab_alloc_with_arg alloc_with_arg_f; + htab_free_with_arg free_with_arg_f; +}; + +typedef struct htab *htab_t; + +/* An enum saying whether we insert into the hash table or not. */ +enum insert_option {NO_INSERT, INSERT}; + +/* The prototypes of the package functions. */ + +extern htab_t htab_create_alloc PARAMS ((size_t, htab_hash, + htab_eq, htab_del, + htab_alloc, htab_free)); + +extern htab_t htab_create_alloc_ex PARAMS ((size_t, htab_hash, + htab_eq, htab_del, + PTR, htab_alloc_with_arg, + htab_free_with_arg)); + +/* Backward-compatibility functions. */ +extern htab_t htab_create PARAMS ((size_t, htab_hash, htab_eq, htab_del)); +extern htab_t htab_try_create PARAMS ((size_t, htab_hash, htab_eq, htab_del)); + +extern void htab_set_functions_ex PARAMS ((htab_t, htab_hash, + htab_eq, htab_del, + PTR, htab_alloc_with_arg, + htab_free_with_arg)); + +extern void htab_delete PARAMS ((htab_t)); +extern void htab_empty PARAMS ((htab_t)); + +extern PTR htab_find PARAMS ((htab_t, const void *)); +extern PTR *htab_find_slot PARAMS ((htab_t, const void *, + enum insert_option)); +extern PTR htab_find_with_hash PARAMS ((htab_t, const void *, + hashval_t)); +extern PTR *htab_find_slot_with_hash PARAMS ((htab_t, const void *, + hashval_t, + enum insert_option)); +extern void htab_clear_slot PARAMS ((htab_t, void **)); +extern void htab_remove_elt PARAMS ((htab_t, void *)); + +extern void htab_traverse PARAMS ((htab_t, htab_trav, void *)); +extern void htab_traverse_noresize PARAMS ((htab_t, htab_trav, void *)); + +extern size_t htab_size PARAMS ((htab_t)); +extern size_t htab_elements PARAMS ((htab_t)); +extern double htab_collisions PARAMS ((htab_t)); + +/* A hash function for pointers. */ +extern htab_hash htab_hash_pointer; + +/* An equality function for pointers. */ +extern htab_eq htab_eq_pointer; + +/* A hash function for null-terminated strings. */ +extern hashval_t htab_hash_string PARAMS ((const PTR)); + +/* An iterative hash function for arbitrary data. */ +extern hashval_t iterative_hash PARAMS ((const PTR, size_t, hashval_t)); +/* Shorthand for hashing something with an intrinsic size. */ +#define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __HASHTAB_H */ diff --git a/contrib/gdb/include/hp-symtab.h b/contrib/gdb/include/hp-symtab.h new file mode 100644 index 00000000000..6267d5572c4 --- /dev/null +++ b/contrib/gdb/include/hp-symtab.h @@ -0,0 +1,1866 @@ +/* Definitions and structures for reading debug symbols from the + native HP C compiler. + + Written by the Center for Software Science at the University of Utah + and by Cygnus Support. + + Copyright 1994, 1995, 1998, 1999, 2003 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef HP_SYMTAB_INCLUDED +#define HP_SYMTAB_INCLUDED + +/* General information: + + This header file defines and describes only the data structures + necessary to read debug symbols produced by the HP C compiler, + HP ANSI C++ compiler, and HP FORTRAN 90 compiler using the + SOM object file format. + (For a full description of the debug format, ftp hpux-symtab.h from + jaguar.cs.utah.edu:/dist). + + Additional notes (Rich Title) + This file is a reverse-engineered version of a file called + "symtab.h" which exists internal to HP's Computer Languages Organization + in /CLO/Components/DDE/obj/som/symtab.h. Because HP's version of + the file is copyrighted and not distributed, it is necessary for + GDB to use the reverse-engineered version that follows. + Work was done by Cygnus to reverse-engineer the C subset of symtab.h. + The WDB project has extended this to also contain the C++ + symbol definitions, the F90 symbol definitions, + and the DOC (debugging-optimized-code) symbol definitions. + In some cases (the C++ symbol definitions) + I have added internal documentation here that + goes beyond what is supplied in HP's symtab.h. If we someday + unify these files again, the extra comments should be merged back + into HP's symtab.h. + + ------------------------------------------------------------------- + + Debug symbols are contained entirely within an unloadable space called + $DEBUG$. $DEBUG$ contains several subspaces which group related + debug symbols. + + $GNTT$ contains information for global variables, types and contants. + + $LNTT$ contains information for procedures (including nesting), scoping + information, local variables, types, and constants. + + $SLT$ contains source line information so that code addresses may be + mapped to source lines. + + $VT$ contains various strings and constants for named objects (variables, + typedefs, functions, etc). Strings are stored as null-terminated character + lists. Constants always begin on word boundaries. The first byte of + the VT must be zero (a null string). + + $XT$ is not currently used by GDB. + + Many structures within the subspaces point to other structures within + the same subspace, or to structures within a different subspace. These + pointers are represented as a structure index from the beginning of + the appropriate subspace. */ + +/* Used to describe where a constant is stored. */ +enum location_type +{ + LOCATION_IMMEDIATE, + LOCATION_PTR, + LOCATION_VT, +}; + +/* Languages supported by this debug format. Within the data structures + this type is limited to 4 bits for a maximum of 16 languages. */ +enum hp_language +{ + HP_LANGUAGE_UNKNOWN, + HP_LANGUAGE_C, + HP_LANGUAGE_FORTRAN, + HP_LANGUAGE_F77 = HP_LANGUAGE_FORTRAN, + HP_LANGUAGE_PASCAL, + HP_LANGUAGE_MODCAL, + HP_LANGUAGE_COBOL, + HP_LANGUAGE_BASIC, + HP_LANGUAGE_ADA, + HP_LANGUAGE_CPLUSPLUS, + HP_LANGUAGE_DMPASCAL +}; + + +/* Basic data types available in this debug format. Within the data + structures this type is limited to 5 bits for a maximum of 32 basic + data types. */ +enum hp_type +{ + HP_TYPE_UNDEFINED, /* 0 */ + HP_TYPE_BOOLEAN, /* 1 */ + HP_TYPE_CHAR, /* 2 */ + HP_TYPE_INT, /* 3 */ + HP_TYPE_UNSIGNED_INT, /* 4 */ + HP_TYPE_REAL, /* 5 */ + HP_TYPE_COMPLEX, /* 6 */ + HP_TYPE_STRING200, /* 7 */ + HP_TYPE_LONGSTRING200, /* 8 */ + HP_TYPE_TEXT, /* 9 */ + HP_TYPE_FLABEL, /* 10 */ + HP_TYPE_FTN_STRING_SPEC, /* 11 */ + HP_TYPE_MOD_STRING_SPEC, /* 12 */ + HP_TYPE_PACKED_DECIMAL, /* 13 */ + HP_TYPE_REAL_3000, /* 14 */ + HP_TYPE_MOD_STRING_3000, /* 15 */ + HP_TYPE_ANYPOINTER, /* 16 */ + HP_TYPE_GLOBAL_ANYPOINTER, /* 17 */ + HP_TYPE_LOCAL_ANYPOINTER, /* 18 */ + HP_TYPE_COMPLEXS3000, /* 19 */ + HP_TYPE_FTN_STRING_S300_COMPAT, /* 20 */ + HP_TYPE_FTN_STRING_VAX_COMPAT, /* 21 */ + HP_TYPE_BOOLEAN_S300_COMPAT, /* 22 */ + HP_TYPE_BOOLEAN_VAX_COMPAT, /* 23 */ + HP_TYPE_WIDE_CHAR, /* 24 */ + HP_TYPE_LONG, /* 25 */ + HP_TYPE_UNSIGNED_LONG, /* 26 */ + HP_TYPE_DOUBLE, /* 27 */ + HP_TYPE_TEMPLATE_ARG, /* 28 */ + HP_TYPE_VOID /* 29 */ +}; + +/* An immediate name and type table entry. + + extension and immediate will always be one. + global will always be zero. + hp_type is the basic type this entry describes. + bitlength is the length in bits for the basic type. */ +struct dnttp_immediate +{ + unsigned int extension: 1; + unsigned int immediate: 1; + unsigned int global: 1; + unsigned int type: 5; + unsigned int bitlength: 24; +}; + +/* A nonimmediate name and type table entry. + + extension will always be one. + immediate will always be zero. + if global is zero, this entry points into the LNTT + if global is one, this entry points into the GNTT + index is the index within the GNTT or LNTT for this entry. */ +struct dnttp_nonimmediate +{ + unsigned int extension: 1; + unsigned int immediate: 1; + unsigned int global: 1; + unsigned int index: 29; +}; + +/* A pointer to an entry in the GNTT and LNTT tables. It has two + forms depending on the type being described. + + The immediate form is used for simple entries and is one + word. + + The nonimmediate form is used for complex entries and contains + an index into the LNTT or GNTT which describes the entire type. + + If a dnttpointer is -1, then it is a NIL entry. */ + +#define DNTTNIL (-1) +typedef union dnttpointer +{ + struct dnttp_immediate dntti; + struct dnttp_nonimmediate dnttp; + int word; +} dnttpointer; + +/* An index into the source line table. As with dnttpointers, a sltpointer + of -1 indicates a NIL entry. */ +#define SLTNIL (-1) +typedef int sltpointer; + +/* Index into DOC (= "Debugging Optimized Code") line table. */ +#define LTNIL (-1) +typedef int ltpointer; + +/* Index into context table. */ +#define CTXTNIL (-1) +typedef int ctxtpointer; + +/* Unsigned byte offset into the VT. */ +typedef unsigned int vtpointer; + +/* A DNTT entry (used within the GNTT and LNTT). + + DNTT entries are variable sized objects, but are always a multiple + of 3 words (we call each group of 3 words a "block"). + + The first bit in each block is an extension bit. This bit is zero + for the first block of a DNTT entry. If the entry requires more + than one block, then this bit is set to one in all blocks after + the first one. */ + +/* Each DNTT entry describes a particular debug symbol (beginning of + a source file, a function, variables, structures, etc. + + The type of the DNTT entry is stored in the "kind" field within the + DNTT entry itself. */ + +enum dntt_entry_type +{ + DNTT_TYPE_NIL = -1, + DNTT_TYPE_SRCFILE, + DNTT_TYPE_MODULE, + DNTT_TYPE_FUNCTION, + DNTT_TYPE_ENTRY, + DNTT_TYPE_BEGIN, + DNTT_TYPE_END, + DNTT_TYPE_IMPORT, + DNTT_TYPE_LABEL, + DNTT_TYPE_FPARAM, + DNTT_TYPE_SVAR, + DNTT_TYPE_DVAR, + DNTT_TYPE_HOLE1, + DNTT_TYPE_CONST, + DNTT_TYPE_TYPEDEF, + DNTT_TYPE_TAGDEF, + DNTT_TYPE_POINTER, + DNTT_TYPE_ENUM, + DNTT_TYPE_MEMENUM, + DNTT_TYPE_SET, + DNTT_TYPE_SUBRANGE, + DNTT_TYPE_ARRAY, + DNTT_TYPE_STRUCT, + DNTT_TYPE_UNION, + DNTT_TYPE_FIELD, + DNTT_TYPE_VARIANT, + DNTT_TYPE_FILE, + DNTT_TYPE_FUNCTYPE, + DNTT_TYPE_WITH, + DNTT_TYPE_COMMON, + DNTT_TYPE_COBSTRUCT, + DNTT_TYPE_XREF, + DNTT_TYPE_SA, + DNTT_TYPE_MACRO, + DNTT_TYPE_BLOCKDATA, + DNTT_TYPE_CLASS_SCOPE, + DNTT_TYPE_REFERENCE, + DNTT_TYPE_PTRMEM, + DNTT_TYPE_PTRMEMFUNC, + DNTT_TYPE_CLASS, + DNTT_TYPE_GENFIELD, + DNTT_TYPE_VFUNC, + DNTT_TYPE_MEMACCESS, + DNTT_TYPE_INHERITANCE, + DNTT_TYPE_FRIEND_CLASS, + DNTT_TYPE_FRIEND_FUNC, + DNTT_TYPE_MODIFIER, + DNTT_TYPE_OBJECT_ID, + DNTT_TYPE_MEMFUNC, + DNTT_TYPE_TEMPLATE, + DNTT_TYPE_TEMPLATE_ARG, + DNTT_TYPE_FUNC_TEMPLATE, + DNTT_TYPE_LINK, + DNTT_TYPE_DYN_ARRAY_DESC, + DNTT_TYPE_DESC_SUBRANGE, + DNTT_TYPE_BEGIN_EXT, + DNTT_TYPE_INLN, + DNTT_TYPE_INLN_LIST, + DNTT_TYPE_ALIAS, + DNTT_TYPE_DOC_FUNCTION, + DNTT_TYPE_DOC_MEMFUNC, + DNTT_TYPE_MAX +}; + +/* DNTT_TYPE_SRCFILE: + + One DNTT_TYPE_SRCFILE symbol is output for the start of each source + file and at the begin and end of an included file. A DNTT_TYPE_SRCFILE + entry is also output before each DNTT_TYPE_FUNC symbol so that debuggers + can determine what file a function was defined in. + + LANGUAGE describes the source file's language. + + NAME points to an VT entry providing the source file's name. + + Note the name used for DNTT_TYPE_SRCFILE entries are exactly as seen + by the compiler (ie they may be relative or absolute). C include files + via <> inclusion must use absolute paths. + + ADDRESS points to an SLT entry from which line number and code locations + may be determined. */ + +struct dntt_type_srcfile +{ + unsigned int extension: 1; + unsigned int kind: 10; /* DNTT_TYPE_SRCFILE */ + unsigned int language: 4; + unsigned int unused: 17; + vtpointer name; + sltpointer address; +}; + +/* DNTT_TYPE_MODULE: + + A DNTT_TYPE_MODULE symbol is emitted for the start of a pascal + module or C source file. A module indicates a compilation unit + for name-scoping purposes; in that regard there should be + a 1-1 correspondence between GDB "symtab"'s and MODULE symbol records. + + Each DNTT_TYPE_MODULE must have an associated DNTT_TYPE_END symbol. + + NAME points to a VT entry providing the module's name. Note C + source files are considered nameless modules. + + ALIAS point to a VT entry providing a secondary name. + + ADDRESS points to an SLT entry from which line number and code locations + may be determined. */ + +struct dntt_type_module +{ + unsigned int extension: 1; + unsigned int kind: 10; /* DNTT_TYPE_MODULE */ + unsigned int unused: 21; + vtpointer name; + vtpointer alias; + dnttpointer unused2; + sltpointer address; +}; + +/* DNTT_TYPE_FUNCTION, + DNTT_TYPE_ENTRY, + DNTT_TYPE_BLOCKDATA, + DNTT_TYPE_MEMFUNC: + + A DNTT_TYPE_FUNCTION symbol is emitted for each function definition; + a DNTT_TYPE_ENTRY symbols is used for secondary entry points. Both + symbols used the dntt_type_function structure. + A DNTT_TYPE_BLOCKDATA symbol is emitted ...? + A DNTT_TYPE_MEMFUNC symbol is emitted for inlined member functions (C++). + + Each of DNTT_TYPE_FUNCTION must have a matching DNTT_TYPE_END. + + GLOBAL is nonzero if the function has global scope. + + LANGUAGE describes the function's source language. + + OPT_LEVEL describes the optimization level the function was compiled + with. + + VARARGS is nonzero if the function uses varargs. + + NAME points to a VT entry providing the function's name. + + ALIAS points to a VT entry providing a secondary name for the function. + + FIRSTPARAM points to a LNTT entry which describes the parameter list. + + ADDRESS points to an SLT entry from which line number and code locations + may be determined. + + ENTRYADDR is the memory address corresponding the function's entry point + + RETVAL points to a LNTT entry describing the function's return value. + + LOWADDR is the lowest memory address associated with this function. + + HIADDR is the highest memory address associated with this function. */ + +struct dntt_type_function +{ + unsigned int extension: 1; + unsigned int kind: 10; /* DNTT_TYPE_FUNCTION, + DNTT_TYPE_ENTRY, + DNTT_TYPE_BLOCKDATA + or DNTT_TYPE_MEMFUNC */ + unsigned int global: 1; + unsigned int language: 4; + unsigned int nest_level: 5; + unsigned int opt_level: 2; + unsigned int varargs: 1; + unsigned int lang_info: 4; + unsigned int inlined: 1; + unsigned int localalloc: 1; + unsigned int expansion: 1; + unsigned int unused: 1; + vtpointer name; + vtpointer alias; + dnttpointer firstparam; + sltpointer address; + CORE_ADDR entryaddr; + dnttpointer retval; + CORE_ADDR lowaddr; + CORE_ADDR hiaddr; +}; + +/* DNTT_TYPE_BEGIN: + + A DNTT_TYPE_BEGIN symbol is emitted to begin a new nested scope. + Every DNTT_TYPE_BEGIN symbol must have a matching DNTT_TYPE_END symbol. + + CLASSFLAG is nonzero if this is the beginning of a c++ class definition. + + ADDRESS points to an SLT entry from which line number and code locations + may be determined. */ + +struct dntt_type_begin +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int classflag: 1; + unsigned int unused: 20; + sltpointer address; +}; + +/* DNTT_TYPE_END: + + A DNTT_TYPE_END symbol is emitted when closing a scope started by + a DNTT_TYPE_MODULE, DNTT_TYPE_FUNCTION, DNTT_TYPE_WITH, + DNTT_TYPE_COMMON, DNTT_TYPE_BEGIN, and DNTT_TYPE_CLASS_SCOPE symbols. + + ENDKIND describes what type of scope the DNTT_TYPE_END is closing + (one of the above 6 kinds). + + CLASSFLAG is nonzero if this is the end of a c++ class definition. + + ADDRESS points to an SLT entry from which line number and code locations + may be determined. + + BEGINSCOPE points to the LNTT entry which opened the scope. */ + +struct dntt_type_end +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int endkind: 10; + unsigned int classflag: 1; + unsigned int unused: 10; + sltpointer address; + dnttpointer beginscope; +}; + +/* DNTT_TYPE_IMPORT is unused by GDB. */ +/* DNTT_TYPE_LABEL is unused by GDB. */ + +/* DNTT_TYPE_FPARAM: + + A DNTT_TYPE_FPARAM symbol is emitted for a function argument. When + chained together the symbols represent an argument list for a function. + + REGPARAM is nonzero if this parameter was passed in a register. + + INDIRECT is nonzero if this parameter is a pointer to the parameter + (pass by reference or pass by value for large items). + + LONGADDR is nonzero if the parameter is a 64bit pointer. + + NAME is a pointer into the VT for the parameter's name. + + LOCATION describes where the parameter is stored. Depending on the + parameter type LOCATION could be a register number, or an offset + from the stack pointer. + + TYPE points to a NTT entry describing the type of this parameter. + + NEXTPARAM points to the LNTT entry describing the next parameter. */ + +struct dntt_type_fparam +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int regparam: 1; + unsigned int indirect: 1; + unsigned int longaddr: 1; + unsigned int copyparam: 1; + unsigned int dflt: 1; + unsigned int doc_ranges: 1; + unsigned int misc_kind: 1; + unsigned int unused: 14; + vtpointer name; + CORE_ADDR location; + dnttpointer type; + dnttpointer nextparam; + int misc; +}; + +/* DNTT_TYPE_SVAR: + + A DNTT_TYPE_SVAR is emitted to describe a variable in static storage. + + GLOBAL is nonzero if the variable has global scope. + + INDIRECT is nonzero if the variable is a pointer to an object. + + LONGADDR is nonzero if the variable is in long pointer space. + + STATICMEM is nonzero if the variable is a member of a class. + + A_UNION is nonzero if the variable is an anonymous union member. + + NAME is a pointer into the VT for the variable's name. + + LOCATION provides the memory address for the variable. + + TYPE is a pointer into either the GNTT or LNTT which describes + the type of this variable. */ + +struct dntt_type_svar +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int global: 1; + unsigned int indirect: 1; + unsigned int longaddr: 1; + unsigned int staticmem: 1; + unsigned int a_union: 1; + unsigned int unused1: 1; + unsigned int thread_specific: 1; + unsigned int unused2: 14; + vtpointer name; + CORE_ADDR location; + dnttpointer type; + unsigned int offset; + unsigned int displacement; +}; + +/* DNTT_TYPE_DVAR: + + A DNTT_TYPE_DVAR is emitted to describe automatic variables and variables + held in registers. + + GLOBAL is nonzero if the variable has global scope. + + INDIRECT is nonzero if the variable is a pointer to an object. + + REGVAR is nonzero if the variable is in a register. + + A_UNION is nonzero if the variable is an anonymous union member. + + NAME is a pointer into the VT for the variable's name. + + LOCATION provides the memory address or register number for the variable. + + TYPE is a pointer into either the GNTT or LNTT which describes + the type of this variable. */ + +struct dntt_type_dvar +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int global: 1; + unsigned int indirect: 1; + unsigned int regvar: 1; + unsigned int a_union: 1; + unsigned int unused: 17; + vtpointer name; + int location; + dnttpointer type; + unsigned int offset; +}; + +/* DNTT_TYPE_CONST: + + A DNTT_TYPE_CONST symbol is emitted for program constants. + + GLOBAL is nonzero if the constant has global scope. + + INDIRECT is nonzero if the constant is a pointer to an object. + + LOCATION_TYPE describes where to find the constant's value + (in the VT, memory, or embedded in an instruction). + + CLASSMEM is nonzero if the constant is a member of a class. + + NAME is a pointer into the VT for the constant's name. + + LOCATION provides the memory address, register number or pointer + into the VT for the constant's value. + + TYPE is a pointer into either the GNTT or LNTT which describes + the type of this variable. */ + +struct dntt_type_const +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int global: 1; + unsigned int indirect: 1; + unsigned int location_type: 3; + unsigned int classmem: 1; + unsigned int unused: 15; + vtpointer name; + CORE_ADDR location; + dnttpointer type; + unsigned int offset; + unsigned int displacement; +}; + +/* DNTT_TYPE_TYPEDEF and DNTT_TYPE_TAGDEF: + + The same structure is used to describe typedefs and tagdefs. + + DNTT_TYPE_TYPEDEFS are associated with C "typedefs". + + DNTT_TYPE_TAGDEFs are associated with C "struct", "union", and "enum" + tags, which may have the same name as a typedef in the same scope. + Also they are associated with C++ "class" tags, which implicitly have + the same name as the class type. + + GLOBAL is nonzero if the typedef/tagdef has global scope. + + TYPEINFO is used to determine if full type information is available + for a tag. (usually 1, but can be zero for opaque types in C). + + NAME is a pointer into the VT for the constant's name. + + TYPE points to the underlying type for the typedef/tagdef in the + GNTT or LNTT. */ + +struct dntt_type_type +{ + unsigned int extension: 1; + unsigned int kind: 10; /* DNTT_TYPE_TYPEDEF or + DNTT_TYPE_TAGDEF. */ + unsigned int global: 1; + unsigned int typeinfo: 1; + unsigned int unused: 19; + vtpointer name; + dnttpointer type; /* Underlying type, which for TAGDEF's may be + DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, + DNTT_TYPE_ENUM, or DNTT_TYPE_CLASS. + For TYPEDEF's other underlying types + are also possible. */ +}; + +/* DNTT_TYPE_POINTER: + + Used to describe a pointer to an underlying type. + + POINTSTO is a pointer into the GNTT or LNTT for the type which this + pointer points to. + + BITLENGTH is the length of the pointer (not the underlying type). */ + +struct dntt_type_pointer +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int unused: 21; + dnttpointer pointsto; + unsigned int bitlength; +}; + + +/* DNTT_TYPE_ENUM: + + Used to describe enumerated types. + + FIRSTMEM is a pointer to a DNTT_TYPE_MEMENUM in the GNTT/LNTT which + describes the first member (and contains a pointer to the chain of + members). + + BITLENGTH is the number of bits used to hold the values of the enum's + members. */ + +struct dntt_type_enum +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int unused: 21; + dnttpointer firstmem; + unsigned int bitlength; +}; + +/* DNTT_TYPE_MEMENUM + + Used to describe members of an enumerated type. + + CLASSMEM is nonzero if this member is part of a class. + + NAME points into the VT for the name of this member. + + VALUE is the value of this enumeration member. + + NEXTMEM points to the next DNTT_TYPE_MEMENUM in the chain. */ + +struct dntt_type_memenum +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int classmem: 1; + unsigned int unused: 20; + vtpointer name; + unsigned int value; + dnttpointer nextmem; +}; + +/* DNTT_TYPE_SET + + Used to describe PASCAL "set" type. + + DECLARATION describes the bitpacking of the set. + + SUBTYPE points to a DNTT entry describing the type of the members. + + BITLENGTH is the size of the set. */ + +struct dntt_type_set +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int declaration: 2; + unsigned int unused: 19; + dnttpointer subtype; + unsigned int bitlength; +}; + +/* DNTT_TYPE_SUBRANGE + + Used to describe subrange type. + + DYN_LOW describes the lower bound of the subrange: + + 00 for a constant lower bound (found in LOWBOUND). + + 01 for a dynamic lower bound with the lower bound found in the + memory address pointed to by LOWBOUND. + + 10 for a dynamic lower bound described by an variable found in the + DNTT/LNTT (LOWBOUND would be a pointer into the DNTT/LNTT). + + DYN_HIGH is similar to DYN_LOW, except it describes the upper bound. + + SUBTYPE points to the type of the subrange. + + BITLENGTH is the length in bits needed to describe the subrange's + values. */ + +struct dntt_type_subrange +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int dyn_low: 2; + unsigned int dyn_high: 2; + unsigned int unused: 17; + int lowbound; + int highbound; + dnttpointer subtype; + unsigned int bitlength; +}; + +/* DNTT_TYPE_ARRAY + + Used to describe an array type. + + DECLARATION describes the bit packing used in the array. + + ARRAYISBYTES is nonzero if the field in arraylength describes the + length in bytes rather than in bits. A value of zero is used to + describe an array with size 2**32. + + ELEMISBYTES is nonzero if the length if each element in the array + is describes in bytes rather than bits. A value of zero is used + to an element with size 2**32. + + ELEMORDER is nonzero if the elements are indexed in increasing order. + + JUSTIFIED if the elements are left justified to index zero. + + ARRAYLENGTH is the length of the array. + + INDEXTYPE is a DNTT pointer to the type used to index the array. + + ELEMTYPE is a DNTT pointer to the type for the array elements. + + ELEMLENGTH is the length of each element in the array (including + any padding). + + Multi-dimensional arrays are represented by ELEMTYPE pointing to + another DNTT_TYPE_ARRAY. */ + +struct dntt_type_array +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int declaration: 2; + unsigned int dyn_low: 2; + unsigned int dyn_high: 2; + unsigned int arrayisbytes: 1; + unsigned int elemisbytes: 1; + unsigned int elemorder: 1; + unsigned int justified: 1; + unsigned int unused: 11; + unsigned int arraylength; + dnttpointer indextype; + dnttpointer elemtype; + unsigned int elemlength; +}; + +/* DNTT_TYPE_STRUCT + + DNTT_TYPE_STRUCT is used to describe a C structure. + + DECLARATION describes the bitpacking used. + + FIRSTFIELD is a DNTT pointer to the first field of the structure + (each field contains a pointer to the next field, walk the list + to access all fields of the structure). + + VARTAGFIELD and VARLIST are used for Pascal variant records. + + BITLENGTH is the size of the structure in bits. */ + +struct dntt_type_struct +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int declaration: 2; + unsigned int unused: 19; + dnttpointer firstfield; + dnttpointer vartagfield; + dnttpointer varlist; + unsigned int bitlength; +}; + +/* DNTT_TYPE_UNION + + DNTT_TYPE_UNION is used to describe a C union. + + FIRSTFIELD is a DNTT pointer to the beginning of the field chain. + + BITLENGTH is the size of the union in bits. */ + +struct dntt_type_union +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int unused: 21; + dnttpointer firstfield; + unsigned int bitlength; +}; + +/* DNTT_TYPE_FIELD + + DNTT_TYPE_FIELD describes one field in a structure or union + or C++ class. + + VISIBILITY is used to describe the visibility of the field + (for c++. public = 0, protected = 1, private = 2). + + A_UNION is nonzero if this field is a member of an anonymous union. + + STATICMEM is nonzero if this field is a static member of a template. + + NAME is a pointer into the VT for the name of the field. + + BITOFFSET gives the offset of this field in bits from the beginning + of the structure or union this field is a member of. + + TYPE is a DNTT pointer to the type describing this field. + + BITLENGTH is the size of the entry in bits. + + NEXTFIELD is a DNTT pointer to the next field in the chain. */ + +struct dntt_type_field +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int visibility: 2; + unsigned int a_union: 1; + unsigned int staticmem: 1; + unsigned int unused: 17; + vtpointer name; + unsigned int bitoffset; + dnttpointer type; + unsigned int bitlength; + dnttpointer nextfield; +}; + +/* DNTT_TYPE_VARIANT is unused by GDB. */ +/* DNTT_TYPE_FILE is unused by GDB. */ + +/* DNTT_TYPE_FUNCTYPE + + I think this is used to describe a function type (e.g., would + be emitted as part of a function-pointer description). + + VARARGS is nonzero if this function uses varargs. + + FIRSTPARAM is a DNTT pointer to the first entry in the parameter + chain. + + RETVAL is a DNTT pointer to the type of the return value. */ + +struct dntt_type_functype +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int varargs: 1; + unsigned int info: 4; + unsigned int unused: 16; + unsigned int bitlength; + dnttpointer firstparam; + dnttpointer retval; +}; + +/* DNTT_TYPE_WITH is emitted by C++ to indicate "with" scoping semantics. + (Probably also emitted by PASCAL to support "with"...). + + C++ example: Say "memfunc" is a method of class "c", and say + "m" is a data member of class "c". Then from within "memfunc", + it is legal to reference "m" directly (e.g. you don't have to + say "this->m". The symbol table indicates + this by emitting a DNTT_TYPE_WITH symbol within the function "memfunc", + pointing to the type symbol for class "c". + + In GDB, this symbol record is unnecessary, + because GDB's symbol lookup algorithm + infers the "with" semantics when it sees a "this" argument to the member + function. So GDB can safely ignore the DNTT_TYPE_WITH record. + + A DNTT_TYPE_WITH has a matching DNTT_TYPE_END symbol. */ + +struct dntt_type_with +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_WITH */ + unsigned int addrtype: 2; /* 0 => STATTYPE */ + /* 1 => DYNTYPE */ + /* 2 => REGTYPE */ + unsigned int indirect: 1; /* 1 => pointer to object */ + unsigned int longaddr: 1; /* 1 => in long pointer space */ + unsigned int nestlevel: 6; /* # of nesting levels back */ + unsigned int doc_ranges: 1; /* 1 => location is range list */ + unsigned int unused: 10; + long location; /* where stored (allocated) */ + sltpointer address; + dnttpointer type; /* type of with expression */ + vtpointer name; /* name of with expression */ + unsigned long offset; /* byte offset from location */ +}; + +/* DNTT_TYPE_COMMON is unsupported by GDB. */ +/* A DNTT_TYPE_COMMON symbol must have a matching DNTT_TYPE_END symbol */ + +/* DNTT_TYPE_COBSTRUCT is unsupported by GDB. */ +/* DNTT_TYPE_XREF is unsupported by GDB. */ +/* DNTT_TYPE_SA is unsupported by GDB. */ +/* DNTT_TYPE_MACRO is unsupported by GDB */ + +/* DNTT_TYPE_BLOCKDATA has the same structure as DNTT_TYPE_FUNCTION */ + +/* The following are the C++ specific SOM records */ + +/* The purpose of the DNTT_TYPE_CLASS_SCOPE is to bracket C++ methods + and indicate the method name belongs in the "class scope" rather + than in the module they are being defined in. For example: + + class c { + ... + void memfunc(); // member function + }; + + void c::memfunc() // definition of class c's "memfunc" + { + ... + } + + main() + { + ... + } + + In the above, the name "memfunc" is not directly visible from "main". + I.e., you have to say "break c::memfunc". + If it were a normal function (not a method), it would be visible + via the simple "break memfunc". Since "memfunc" otherwise looks + like a normal FUNCTION in the symbol table, the bracketing + CLASS_SCOPE is what is used to indicate it is really a method. + + + A DNTT_TYPE_CLASS_SCOPE symbol must have a matching DNTT_TYPE_END symbol. */ + +struct dntt_type_class_scope +{ + unsigned int extension: 1; /* Always zero. */ + unsigned int kind: 10; /* Always DNTT_TYPE_CLASS_SCOPE. */ + unsigned int unused: 21; + sltpointer address ; /* Pointer to SLT entry. */ + dnttpointer type ; /* Pointer to class type DNTT. */ +}; + +/* C++ reference parameter. + The structure of this record is the same as DNTT_TYPE_POINTER - + refer to struct dntt_type_pointer. */ + +/* The next two describe C++ pointer-to-data-member type, and + pointer-to-member-function type, respectively. + DNTT_TYPE_PTRMEM and DNTT_TYPE_PTRMEMFUNC have the same structure. */ + +struct dntt_type_ptrmem +{ + unsigned int extension: 1; /* Always zero. */ + unsigned int kind: 10; /* Always DNTT_TYPE_PTRMEM. */ + unsigned int unused: 21; + dnttpointer pointsto ; /* Pointer to class DNTT. */ + dnttpointer memtype ; /* Type of member. */ +}; + +struct dntt_type_ptrmemfunc +{ + unsigned int extension: 1; /* Always zero. */ + unsigned int kind: 10; /* Always DNTT_TYPE_PTRMEMFUNC. */ + unsigned int unused: 21; + dnttpointer pointsto ; /* Pointer to class DNTT. */ + dnttpointer memtype ; /* Type of member. */ +}; + +/* The DNTT_TYPE_CLASS symbol is emitted to describe a class type. + "memberlist" points to a chained list of FIELD or GENFIELD records + indicating the class members. "parentlist" points to a chained list + of INHERITANCE records indicating classes from which we inherit + fields. */ + +struct dntt_type_class +{ + unsigned int extension: 1; /* Always zero. */ + unsigned int kind: 10; /* Always DNTT_TYPE_CLASS. */ + unsigned int abstract: 1; /* Is this an abstract class? */ + unsigned int class_decl: 2; /* 0=class,1=union,2=struct. */ + unsigned int expansion: 1; /* 1=template expansion. */ + unsigned int unused: 17; + dnttpointer memberlist ; /* Ptr to chain of [GEN]FIELDs. */ + unsigned long vtbl_loc ; /* Offset in obj of ptr to vtbl. */ + dnttpointer parentlist ; /* Ptr to K_INHERITANCE list. */ + unsigned long bitlength ; /* Total at this level. */ + dnttpointer identlist ; /* Ptr to chain of class ident's. */ + dnttpointer friendlist ; /* Ptr to K_FRIEND list. */ + dnttpointer templateptr ; /* Ptr to template. */ + dnttpointer nextexp ; /* Ptr to next expansion. */ +}; + +/* Class members are indicated via either the FIELD record (for + data members, same as for C struct fields), or by the GENFIELD record + (for member functions). */ + +struct dntt_type_genfield +{ + unsigned int extension: 1; /* Always zero. */ + unsigned int kind: 10; /* Always DNTT_TYPE_GENFIELD. */ + unsigned int visibility: 2; /* Pub = 0, prot = 1, priv = 2. */ + unsigned int a_union: 1; /* 1 => anonymous union member. */ + unsigned int unused: 18; + dnttpointer field ; /* Pointer to field or qualifier. */ + dnttpointer nextfield ; /* Pointer to next field. */ +}; + +/* C++ virtual functions. */ + +struct dntt_type_vfunc +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_VFUNC */ + unsigned int pure: 1; /* pure virtual function ? */ + unsigned int unused: 20; + dnttpointer funcptr ; /* points to FUNCTION symbol */ + unsigned long vtbl_offset ; /* offset into vtbl for virtual */ +}; + +/* Not precisely sure what this is intended for - DDE ignores it. */ + +struct dntt_type_memaccess +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_MEMACCESS */ + unsigned int unused: 21; + dnttpointer classptr ; /* pointer to base class */ + dnttpointer field ; /* pointer field */ +}; + +/* The DNTT_TYPE_INHERITANCE record describes derived classes. + In particular, the "parentlist" field of the CLASS record points + to a list of INHERITANCE records for classes from which we + inherit members. */ + +struct dntt_type_inheritance +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_INHERITANCE */ + unsigned int Virtual: 1; /* virtual base class ? */ + unsigned int visibility: 2; /* pub = 0, prot = 1, priv = 2 */ + unsigned int unused: 18; + dnttpointer classname ; /* first parent class, if any */ + unsigned long offset ; /* offset to start of base class */ + dnttpointer next ; /* pointer to next K_INHERITANCE */ + unsigned long future[2] ; /* padding to 3-word block end */ +}; + +/* C++ "friend" classes ... */ + +struct dntt_type_friend_class +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_FRIEND_CLASS */ + unsigned int unused: 21; + dnttpointer classptr ; /* pointer to class DNTT */ + dnttpointer next ; /* next DNTT_FRIEND */ +}; + +struct dntt_type_friend_func +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_FRIEND_FUNC */ + unsigned int unused: 21; + dnttpointer funcptr ; /* pointer to function */ + dnttpointer classptr ; /* pointer to class DNTT */ + dnttpointer next ; /* next DNTT_FRIEND */ + unsigned long future[2] ; /* padding to 3-word block end */ +}; + +/* DDE appears to ignore the DNTT_TYPE_MODIFIER record. + It could perhaps be used to give better "ptype" output in GDB; + otherwise it is probably safe for GDB to ignore it also. */ + +struct dntt_type_modifier +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_MODIFIER */ + unsigned int m_const: 1; /* const */ + unsigned int m_static: 1; /* static */ + unsigned int m_void: 1; /* void */ + unsigned int m_volatile: 1; /* volatile */ + unsigned int m_duplicate: 1; /* duplicate */ + unsigned int unused: 16; + dnttpointer type ; /* subtype */ + unsigned long future ; /* padding to 3-word block end */ +}; + +/* I'm not sure what this was intended for - DDE ignores it. */ + +struct dntt_type_object_id +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_OBJECT_ID */ + unsigned int indirect: 1; /* Is object_ident addr of addr? */ + unsigned int unused: 20; + unsigned long object_ident ; /* object identifier */ + unsigned long offset ; /* offset to start of base class */ + dnttpointer next ; /* pointer to next K_OBJECT_ID */ + unsigned long segoffset ; /* for linker fixup */ + unsigned long future ; /* padding to 3-word block end */ +}; + +/* No separate dntt_type_memfunc; same as dntt_type_func */ + +/* Symbol records to support templates. These only get used + in DDE's "describe" output (like GDB's "ptype"). */ + +/* The TEMPLATE record is the header for a template-class. + Like the CLASS record, a TEMPLATE record has a memberlist that + points to a list of template members. It also has an arglist + pointing to a list of TEMPLATE_ARG records. */ + +struct dntt_type_template +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_TEMPLATE */ + unsigned int abstract: 1; /* is this an abstract class? */ + unsigned int class_decl: 2; /* 0=class,1=union,2=struct */ + unsigned int unused: 18; + dnttpointer memberlist ; /* ptr to chain of K_[GEN]FIELDs */ + long unused2 ; /* offset in obj of ptr to vtbl */ + dnttpointer parentlist ; /* ptr to K_INHERITANCE list */ + unsigned long bitlength ; /* total at this level */ + dnttpointer identlist ; /* ptr to chain of class ident's */ + dnttpointer friendlist ; /* ptr to K_FRIEND list */ + dnttpointer arglist ; /* ptr to argument list */ + dnttpointer expansions ; /* ptr to expansion list */ +}; + +/* Template-class arguments are a list of TEMPL_ARG records + chained together. The "name" field is the name of the formal. + E.g.: + + template class q { ... }; + + Then "T" is the name of the formal argument. */ + +struct dntt_type_templ_arg +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_TEMPL_ARG */ + unsigned int usagetype: 1; /* 0 type-name 1 expression */ + unsigned int unused: 20; + vtpointer name ; /* name of argument */ + dnttpointer type ; /* for non type arguments */ + dnttpointer nextarg ; /* Next argument if any */ + long future[2] ; /* padding to 3-word block end */ +}; + +/* FUNC_TEMPLATE records are sort of like FUNCTION, but are emitted + for template member functions. E.g., + + template class q + { + ... + void f(); + ... + }; + + Within the list of FIELDs/GENFIELDs defining the member list + of the template "q", "f" would appear as a FUNC_TEMPLATE. + We'll also see instances of FUNCTION "f" records for each + instantiation of the template. */ + +struct dntt_type_func_template +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_FUNC_TEMPLATE */ + unsigned int public: 1; /* 1 => globally visible */ + unsigned int language: 4; /* type of language */ + unsigned int level: 5; /* nesting level (top level = 0)*/ + unsigned int optimize: 2; /* level of optimization */ + unsigned int varargs: 1; /* ellipses. Pascal/800 later */ + unsigned int info: 4; /* lang-specific stuff; F_xxxx */ + unsigned int inlined: 1; + unsigned int localloc: 1; /* 0 at top, 1 at end of block */ + unsigned int unused: 2; + vtpointer name ; /* name of function */ + vtpointer alias ; /* alternate name, if any */ + dnttpointer firstparam ; /* first FPARAM, if any */ + dnttpointer retval ; /* return type, if any */ + dnttpointer arglist ; /* ptr to argument list */ +}; + +/* LINK is apparently intended to link together function template + definitions with their instantiations. However, it is not clear + why this would be needed, except to provide the information on + a "ptype" command. And as far as I can tell, aCC does not + generate this record. */ + +struct dntt_type_link +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* always DNTT_TYPE_LINK */ + unsigned int linkKind: 4; /* always LINK_UNKNOWN */ + unsigned int unused: 17; + long future1 ; /* expansion */ + dnttpointer ptr1 ; /* link from template */ + dnttpointer ptr2 ; /* to expansion */ + long future[2] ; /* padding to 3-word block end */ +}; + +/* end of C++ specific SOM's. */ + +/* DNTT_TYPE_DYN_ARRAY_DESC is unused by GDB */ +/* DNTT_TYPE_DESC_SUBRANGE is unused by GDB */ +/* DNTT_TYPE_BEGIN_EXT is unused by GDB */ +/* DNTT_TYPE_INLN is unused by GDB */ +/* DNTT_TYPE_INLN_LIST is unused by GDB */ +/* DNTT_TYPE_ALIAS is unused by GDB */ + +struct dntt_type_doc_function +{ + unsigned int extension: 1; /* always zero */ + unsigned int kind: 10; /* K_DOC_FUNCTION or */ + /* K_DOC_MEMFUNC */ + unsigned int global: 1; /* 1 => globally visible */ + unsigned int language: 4; /* type of language */ + unsigned int level: 5; /* nesting level (top level = 0)*/ + unsigned int optimize: 2; /* level of optimization */ + unsigned int varargs: 1; /* ellipses. Pascal/800 later */ + unsigned int info: 4; /* lang-specific stuff; F_xxxx */ + unsigned int inlined: 1; + unsigned int localloc: 1; /* 0 at top, 1 at end of block */ + unsigned int expansion: 1; /* 1 = function expansion */ + unsigned int doc_clone: 1; + vtpointer name; /* name of function */ + vtpointer alias; /* alternate name, if any */ + dnttpointer firstparam; /* first FPARAM, if any */ + sltpointer address; /* code and text locations */ + CORE_ADDR entryaddr; /* address of entry point */ + dnttpointer retval; /* return type, if any */ + CORE_ADDR lowaddr; /* lowest address of function */ + CORE_ADDR hiaddr; /* highest address of function */ + dnttpointer inline_list; /* pointer to first inline */ + ltpointer lt_offset; /* start of frag/cp line table */ + ctxtpointer ctxt_offset; /* start of context table for this routine */ +}; + +/* DNTT_TYPE_DOC_MEMFUNC is unused by GDB */ + +/* DNTT_TYPE_GENERIC and DNTT_TYPE_BLOCK are convience structures + so we can examine a DNTT entry in a generic fashion. */ +struct dntt_type_generic +{ + unsigned int word[9]; +}; + +struct dntt_type_block +{ + unsigned int extension: 1; + unsigned int kind: 10; + unsigned int unused: 21; + unsigned int word[2]; +}; + +/* One entry in a DNTT (either the LNTT or GNTT). + This is a union of the above 60 or so structure definitions. */ + +union dnttentry +{ + struct dntt_type_srcfile dsfile; + struct dntt_type_module dmodule; + struct dntt_type_function dfunc; + struct dntt_type_function dentry; + struct dntt_type_begin dbegin; + struct dntt_type_end dend; + struct dntt_type_fparam dfparam; + struct dntt_type_svar dsvar; + struct dntt_type_dvar ddvar; + struct dntt_type_const dconst; + struct dntt_type_type dtype; + struct dntt_type_type dtag; + struct dntt_type_pointer dptr; + struct dntt_type_enum denum; + struct dntt_type_memenum dmember; + struct dntt_type_set dset; + struct dntt_type_subrange dsubr; + struct dntt_type_array darray; + struct dntt_type_struct dstruct; + struct dntt_type_union dunion; + struct dntt_type_field dfield; + struct dntt_type_functype dfunctype; + struct dntt_type_with dwith; + struct dntt_type_function dblockdata; + struct dntt_type_class_scope dclass_scope; + struct dntt_type_pointer dreference; + struct dntt_type_ptrmem dptrmem; + struct dntt_type_ptrmemfunc dptrmemfunc; + struct dntt_type_class dclass; + struct dntt_type_genfield dgenfield; + struct dntt_type_vfunc dvfunc; + struct dntt_type_memaccess dmemaccess; + struct dntt_type_inheritance dinheritance; + struct dntt_type_friend_class dfriend_class; + struct dntt_type_friend_func dfriend_func; + struct dntt_type_modifier dmodifier; + struct dntt_type_object_id dobject_id; + struct dntt_type_template dtemplate; + struct dntt_type_templ_arg dtempl_arg; + struct dntt_type_func_template dfunc_template; + struct dntt_type_link dlink; + struct dntt_type_doc_function ddocfunc; + struct dntt_type_generic dgeneric; + struct dntt_type_block dblock; +}; + +/* Source line entry types. */ +enum slttype +{ + SLT_NORMAL, + SLT_SRCFILE, + SLT_MODULE, + SLT_FUNCTION, + SLT_ENTRY, + SLT_BEGIN, + SLT_END, + SLT_WITH, + SLT_EXIT, + SLT_ASSIST, + SLT_MARKER, + SLT_CLASS_SCOPE, + SLT_INLN, + SLT_NORMAL_OFFSET, +}; + +/* A normal source line entry. Simply provides a mapping of a source + line number to a code address. + + SLTDESC will always be SLT_NORMAL or SLT_EXIT. */ + +struct slt_normal +{ + unsigned int sltdesc: 4; + unsigned int line: 28; + CORE_ADDR address; +}; + +struct slt_normal_off +{ + unsigned int sltdesc: 4; + unsigned int offset: 6; + unsigned int line: 22; + CORE_ADDR address; +}; + +/* A special source line entry. Provides a mapping of a declaration + to a line number. These entries point back into the DNTT which + references them. */ + +struct slt_special +{ + unsigned int sltdesc: 4; + unsigned int line: 28; + dnttpointer backptr; +}; + +/* Used to describe nesting. + + For nested languages, an slt_assist entry must follow each SLT_FUNC + entry in the SLT. The address field will point forward to the + first slt_normal entry within the function's scope. */ + +struct slt_assist +{ + unsigned int sltdesc: 4; + unsigned int unused: 28; + sltpointer address; +}; + +struct slt_generic +{ + unsigned int word[2]; +}; + +union sltentry +{ + struct slt_normal snorm; + struct slt_normal_off snormoff; + struct slt_special sspec; + struct slt_assist sasst; + struct slt_generic sgeneric; +}; + +/* $LINES$ declarations + This is the line table used for optimized code, which is only present + in the new $PROGRAM_INFO$ debug space. */ + +#define DST_LN_ESCAPE_FLAG1 15 +#define DST_LN_ESCAPE_FLAG2 14 +#define DST_LN_CTX_SPEC1 13 +#define DST_LN_CTX_SPEC2 12 + +/* Escape function codes: */ + +typedef enum +{ + dst_ln_pad, /* pad byte */ + dst_ln_escape_1, /* reserved */ + dst_ln_dpc1_dln1, /* 1 byte line delta, 1 byte pc delta */ + dst_ln_dpc2_dln2, /* 2 bytes line delta, 2 bytes pc delta */ + dst_ln_pc4_ln4, /* 4 bytes ABSOLUTE line number, 4 bytes ABSOLUTE pc */ + dst_ln_dpc0_dln1, /* 1 byte line delta, pc delta = 0 */ + dst_ln_ln_off_1, /* statement escape, stmt # = 1 (2nd stmt on line) */ + dst_ln_ln_off, /* statement escape, stmt # = next byte */ + dst_ln_entry, /* entry escape, next byte is entry number */ + dst_ln_exit, /* exit escape */ + dst_ln_stmt_end, /* gap escape, 4 bytes pc delta */ + dst_ln_stmt_cp, /* current stmt is a critical point */ + dst_ln_escape_12, /* reserved */ + dst_ln_escape_13, /* this is an exception site record */ + dst_ln_nxt_byte, /* next byte contains the real escape code */ + dst_ln_end, /* end escape, final entry follows */ + dst_ln_escape1_END_OF_ENUM +} +dst_ln_escape1_t; + +typedef enum +{ + dst_ln_ctx_1, /* next byte describes context switch with 5-bit */ + /* index into the image table and 3-bit run length. */ + /* If run length is 0, end with another cxt specifier or ctx_end */ + dst_ln_ctx_2, /* next 2 bytes switch context: 13 bit index, 3 bit run length */ + dst_ln_ctx_4, /* next 4 bytes switch context: 29 bit index, 3 bit run length */ + dst_ln_ctx_end, /* end current context */ + dst_ln_col_run_1, /* next byte is column position of start of next statement, */ + /* following byte is length of statement */ + dst_ln_col_run_2, /* next 2 bytes is column position of start of next statement, */ + /* following 2 bytes is length of statement */ + dst_ln_init_base1, /* next 4 bytes are absolute PC, followed by 1 byte of line number */ + dst_ln_init_base2, /* next 4 bytes are absolute PC, followed by 2 bytes of line number */ + dst_ln_init_base3, /* next 4 bytes are absolute PC, followed by 3 bytes of line number */ + dst_ln_escape2_END_OF_ENUM +} +dst_ln_escape2_t; + +typedef union +{ + struct + { + unsigned int pc_delta : 4; /* 4 bit pc delta */ + int ln_delta : 4; /* 4 bit line number delta */ + } + delta; + + struct + { + unsigned int esc_flag : 4; /* alias for pc_delta */ + unsigned int esc_code : 4; /* escape function code (dst_ln_escape1_t, or ...2_t */ + } + esc; + + struct + { + unsigned int esc_flag : 4; /* dst_ln_ctx_spec1, or dst_ln_ctx_spec2 */ + unsigned int run_length : 2; + unsigned int ctx_index : 2; /* ...spec2 contains index; ...spec1, index - 4 */ + } + ctx_spec; + + char sdata; /* signed data byte */ + unsigned char udata; /* unsigned data byte */ +} +dst_ln_entry_t, + * dst_ln_entry_ptr_t; + +/* Warning: although the above union occupies only 1 byte the compiler treats + it as having size 2 (the minimum size of a struct). Therefore a sequence of + dst_ln_entry_t's cannot be described as an array, and walking through such a + sequence requires convoluted code such as + ln_ptr = (dst_ln_entry_ptr_t) (char*) ln_ptr + 1 + We regret the inconvenience. */ + +/* Structure for interpreting the byte following a dst_ln_ctx1 entry. */ +typedef struct +{ + unsigned int ctx1_index : 5; /* 5 bit index into context table */ + unsigned int ctx1_run_length : 3; /* 3 bit run length */ +} dst_ln_ctx1_t, + *dst_ln_ctx1_ptr_t; + +/* Structure for interpreting the bytes following a dst_ln_ctx2 entry. */ +typedef struct +{ + unsigned int ctx2_index : 13; /* 13 bit index into context table */ + unsigned int ctx2_run_length : 3; /* 3 bit run length */ +} dst_ln_ctx2_t, + *dst_ln_ctx2_ptr_t; + +/* Structure for interpreting the bytes following a dst_ln_ctx4 entry. */ +typedef struct +{ + unsigned int ctx4_index : 29; /* 29 bit index into context table */ + unsigned int ctx4_run_length : 3; /* 3 bit run length */ +} dst_ln_ctx4_t, + *dst_ln_ctx4_ptr_t; + + +/* PXDB definitions. + + PXDB is a post-processor which takes the executable file + and massages the debug information so that the debugger may + start up and run more efficiently. Some of the tasks + performed by PXDB are: + + o Remove duplicate global type and variable information + from the GNTT, + + o Append the GNTT onto the end of the LNTT and place both + back in the LNTT section, + + o Build quick look-up tables (description follows) for + files, procedures, modules, and paragraphs (for Cobol), + placing these in the GNTT section, + + o Reconstruct the header appearing in the header section + to access this information. + + The "quick look-up" tables are in the $GNTT$ sub-space, in + the following order: + + Procedures -sorted by address + Source files -sorted by address (of the + generated code from routines) + Modules -sorted by address + Classes - + Address Alias -sorted by index + Object IDs -sorted by object identifier + + Most quick entries have (0-based) indices into the LNTT tables to + the full entries for the item it describes. + + The post-PXDB header is in the $HEADER$ sub-space. Alas, it + occurs in different forms, depending on the optimization level + in the compilation step and whether PXDB was run or not. The + worst part is the forms aren't self-describing, so we'll have + to grovel in the bits to figure out what kind we're looking at + (see hp_get_header in hp-psymtab-read.c). */ + +/* PXDB versions. */ + +#define PXDB_VERSION_CPLUSPLUS 1 +#define PXDB_VERSION_7_4 2 +#define PXDB_VERSION_CPP_30 3 +#define PXDB_VERSION_DDE_3_2A 4 +#define PXDB_VERSION_DDE_3_2 5 +#define PXDB_VERSION_DDE_4_0 6 + +#define PXDB_VERSION_2_1 1 + +/* Header version for the case that there is no DOC info + but the executable has been processed by pxdb (the easy + case, from "cc -g"). */ + +typedef struct PXDB_struct +{ + int pd_entries; /* # of entries in function look-up table */ + int fd_entries; /* # of entries in file look-up table */ + int md_entries; /* # of entries in module look-up table */ + unsigned int pxdbed : 1; /* 1 => file has been preprocessed */ + unsigned int bighdr : 1; /* 1 => this header contains 'time' word */ + unsigned int sa_header : 1;/* 1 => created by SA version of pxdb */ + /* used for version check in xdb */ + unsigned int inlined: 1; /* one or more functions have been inlined */ + unsigned int spare:12; + short version; /* pxdb header version */ + int globals; /* index into the DNTT where GNTT begins */ + unsigned int time; /* modify time of file before being pxdbed */ + int pg_entries; /* # of entries in label look-up table */ + int functions; /* actual number of functions */ + int files; /* actual number of files */ + int cd_entries; /* # of entries in class look-up table */ + int aa_entries; /* # of entries in addr alias look-up table */ + int oi_entries; /* # of entries in object id look-up table */ +} PXDB_header, *PXDB_header_ptr; + +/* Header version for the case that there is no DOC info and the + executable has NOT been processed by pxdb. */ + +typedef struct XDB_header_struct +{ + long gntt_length; + long lntt_length; + long slt_length; + long vt_length; + long xt_length; +} XDB_header; + +/* Header version for the case that there is DOC info and the + executable has been processed by pxdb. */ + +typedef struct DOC_info_PXDB_header_struct +{ + unsigned int xdb_header: 1; /* bit set if this is post-3.1 xdb */ + unsigned int doc_header: 1; /* bit set if this is doc-style header */ + unsigned int version: 8; /* version of pxdb see defines + PXDB_VERSION_* in this file. */ + unsigned int reserved_for_flags: 16;/* for future use; -- must be + set to zero. */ + unsigned int has_aux_pd_table: 1; /* $GNTT$ has aux PD table */ + unsigned int has_expr_table: 1; /* space has $EXPR$ */ + unsigned int has_range_table: 1; /* space has $RANGE$ */ + unsigned int has_context_table: 1; /* space has $SRC_CTXT$ */ + unsigned int has_lines_table: 1; /* space contains a $LINES$ + subspace for line tables. */ + unsigned int has_lt_offset_map: 1; /* space contains an lt_offset + subspace for line table mapping. */ + /* The following fields are the same as those in the PXDB_header in $DEBUG$ */ + int pd_entries; /* # of entries in function look-up table */ + int fd_entries; /* # of entries in file look-up table */ + int md_entries; /* # of entries in module look-up table */ + unsigned int pxdbed : 1; /* 1 => file has been preprocessed */ + unsigned int bighdr : 1; /* 1 => this header contains 'time' word */ + unsigned int sa_header : 1;/* 1 => created by SA version of pxdb */ + /* used for version check in xdb */ + unsigned int inlined: 1; /* one or more functions have been inlined */ + unsigned int spare : 28; + int globals; /* index into the DNTT where GNTT begins */ + unsigned int time; /* modify time of file before being pxdbed */ + int pg_entries; /* # of entries in label look-up table */ + int functions; /* actual number of functions */ + int files; /* actual number of files */ + int cd_entries; /* # of entries in class look-up table */ + int aa_entries; /* # of entries in addr alias look-up table */ + int oi_entries; /* # of entries in object id look-up table */ +} DOC_info_PXDB_header; + +/* Header version for the case that there is DOC info and the + executable has NOT been processed by pxdb. */ + +typedef struct DOC_info_header_struct +{ + unsigned int xdb_header: 1; /* bit set if this is post-3.1 xdb */ + unsigned int doc_header: 1; /* bit set if this is doc-style header*/ + unsigned int version: 8; /* version of debug/header + format. For 10.0 the value + will be 1. For "Davis" the value is 2. */ + unsigned int reserved_for_flags: 18; /* for future use; -- must be set to zero. */ + unsigned int has_range_table: 1; /* space contains a $RANGE$ subspace for variable ranges. */ + unsigned int has_context_table: 1; /* space contains a $CTXT$ subspace for context/inline table. */ + unsigned int has_lines_table: 1; /* space contains a $LINES$ subspace for line tables. */ + unsigned int has_lt_offset_map: 1; /* space contains an lt_offset subspace for line table mapping. */ + + long gntt_length; /* same as old header */ + long lntt_length; /* same as old header */ + long slt_length; /* same as old header */ + long vt_length; /* same as old header */ + long xt_length; /* same as old header */ + long ctxt_length; /* present only if version >= 2 */ + long range_length; /* present only if version >= 2 */ + long expr_length; /* present only if version >= 2 */ + +} DOC_info_header; + +typedef union GenericDebugHeader_union +{ + PXDB_header no_doc; + DOC_info_PXDB_header doc; + XDB_header no_pxdb_no_doc; + DOC_info_header no_pxdb_doc; +} GenericDebugHeader; + + +/* Procedure Descriptor: + An element of the procedure quick look-up table. */ + +typedef struct quick_procedure +{ + long isym; /* 0-based index of first symbol + for procedure in $LNTT$, + i.e. the procedure itself. */ + CORE_ADDR adrStart; /* memory adr of start of proc */ + CORE_ADDR adrEnd; /* memory adr of end of proc */ + char *sbAlias; /* alias name of procedure */ + char *sbProc; /* real name of procedure */ + CORE_ADDR adrBp; /* address of entry breakpoint */ + CORE_ADDR adrExitBp; /* address of exit breakpoint */ + int icd; /* member of this class (index) */ + unsigned int ipd; /* index of template for this */ + /* function (index) */ + unsigned int unused: 5; + unsigned int no_lt_offset: 1;/* no entry in lt_offset table */ + unsigned int fTemplate: 1; /* function template */ + unsigned int fExpansion: 1; /* function expansion */ + unsigned int linked : 1; /* linked with other expansions */ + unsigned int duplicate: 1; /* clone of another procedure */ + unsigned int overloaded:1; /* overloaded function */ + unsigned int member: 1; /* class member function */ + unsigned int constructor:1; /* constructor function */ + unsigned int destructor:1; /* destructor function */ + unsigned int Static: 1; /* static function */ + unsigned int Virtual: 1; /* virtual function */ + unsigned int constant: 1; /* constant function */ + unsigned int pure: 1; /* pure (virtual) function */ + unsigned int language: 4; /* procedure's language */ + unsigned int inlined: 1; /* function has been inlined */ + unsigned int Operator: 1; /* operator function */ + unsigned int stub: 1; /* bodyless function */ + unsigned int optimize: 2; /* optimization level */ + unsigned int level: 5; /* nesting level (top=0) */ +} quick_procedure_entry, *quick_procedure_entry_ptr; + +/* Source File Descriptor: + An element of the source file quick look-up table. */ + +typedef struct quick_source +{ + long isym; /* 0-based index in $LNTT$ of + first symbol for this file. */ + CORE_ADDR adrStart; /* mem adr of start of file's code */ + CORE_ADDR adrEnd; /* mem adr of end of file's code */ + char *sbFile; /* name of source file */ + unsigned int fHasDecl: 1; /* do we have a .d file? */ + unsigned int fWarned: 1; /* have warned about age problems? */ + unsigned int fSrcfile: 1; /* 0 => include 1=> source */ + unsigned short ilnMac; /* lines in file (0 if don't know) */ + int ipd; /* 0-based index of first procedure + in this file, in the quick + look-up table of procedures. */ + unsigned int *rgLn; /* line pointer array, if any */ +} quick_file_entry, *quick_file_entry_ptr; + +/* Module Descriptor: + An element of the module quick reference table. */ + +typedef struct quick_module +{ + long isym; /* 0-based index of first + symbol for module. */ + CORE_ADDR adrStart; /* adr of start of mod. */ + CORE_ADDR adrEnd; /* adr of end of mod. */ + char *sbAlias; /* alias name of module */ + char *sbMod; /* real name of module */ + unsigned int imports: 1; /* module have any imports? */ + unsigned int vars_in_front: 1; /* module globals in front? */ + unsigned int vars_in_gaps: 1; /* module globals in gaps? */ + unsigned int language: 4; /* type of language */ + unsigned int unused : 25; + unsigned int unused2; /* space for future stuff */ +} quick_module_entry, *quick_module_entry_ptr; + +/* Auxiliary Procedure Descriptor: + An element of the auxiliary procedure quick look-up table. */ + +typedef struct quick_aux_procedure +{ + long isym_inln; /* start on inline list for proc */ + long spare; +} quick_aux_procedure_entry, *quick_aux_procedure_entry_ptr; + +/* Paragraph Descriptor: + An element of the paragraph quick look-up table. */ + +typedef struct quick_paragraph +{ + long isym; /* first symbol for label (index) */ + CORE_ADDR adrStart; /* memory adr of start of label */ + CORE_ADDR adrEnd; /* memory adr of end of label */ + char *sbLab; /* name of label */ + unsigned int inst; /* Used in xdb to store inst @ bp */ + unsigned int sect: 1; /* true = section, false = parag. */ + unsigned int unused: 31; /* future use */ +} quick_paragraph_entry, *quick_paragraph_entry_ptr; + +/* Class Descriptor: + An element of the class quick look-up table. */ + +typedef struct quick_class +{ + char *sbClass; /* name of class */ + long isym; /* class symbol (tag) */ + unsigned int type : 2; /* 0=class, 1=union, 2=struct */ + unsigned int fTemplate : 1;/* class template */ + unsigned int expansion : 1;/* template expansion */ + unsigned int unused :28; + sltpointer lowscope; /* beginning of defined scope */ + sltpointer hiscope; /* end of defined scope */ +} quick_class_entry, *quick_class_entry_ptr; + +/* Address Alias Entry + An element of the address alias quick look-up table. */ + +typedef struct quick_alias +{ + CORE_ADDR low; + CORE_ADDR high; + int index; + unsigned int unused : 31; + unsigned int alternate : 1; /* alternate unnamed aliases? */ +} quick_alias_entry, *quick_alias_entry_ptr; + +/* Object Identification Entry + An element of the object identification quick look-up table. */ + +typedef struct quick_obj_ID +{ + CORE_ADDR obj_ident; /* class identifier */ + long isym; /* class symbol */ + long offset; /* offset to object start */ +} quick_obj_ID_entry, *quick_obj_ID_entry_ptr; + +#endif /* HP_SYMTAB_INCLUDED */ diff --git a/contrib/gdb/include/ieee.h b/contrib/gdb/include/ieee.h new file mode 100644 index 00000000000..5abc32b62d8 --- /dev/null +++ b/contrib/gdb/include/ieee.h @@ -0,0 +1,165 @@ +/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file + + Copyright 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Contributed by Cygnus Support. */ + +#define N_W_VARIABLES 8 +#define Module_Beginning 0xe0 + +typedef struct ieee_module + { + char *processor; + char *module_name; + } +ieee_module_begin_type; + +#define Address_Descriptor 0xec +typedef struct ieee_address + { + bfd_vma number_of_bits_mau; + bfd_vma number_of_maus_in_address; + + unsigned char byte_order; +#define IEEE_LITTLE 0xcc +#define IEEE_BIG 0xcd + } +ieee_address_descriptor_type; + +typedef union ieee_w_variable + { + file_ptr offset[N_W_VARIABLES]; + + struct + { + file_ptr extension_record; + file_ptr environmental_record; + file_ptr section_part; + file_ptr external_part; + file_ptr debug_information_part; + file_ptr data_part; + file_ptr trailer_part; + file_ptr me_record; + } + r; + } +ieee_w_variable_type; + +typedef enum ieee_record + { + ieee_number_start_enum = 0x00, + ieee_number_end_enum=0x7f, + ieee_number_repeat_start_enum = 0x80, + ieee_number_repeat_end_enum = 0x88, + ieee_number_repeat_4_enum = 0x84, + ieee_number_repeat_3_enum = 0x83, + ieee_number_repeat_2_enum = 0x82, + ieee_number_repeat_1_enum = 0x81, + ieee_module_beginning_enum = 0xe0, + ieee_module_end_enum = 0xe1, + ieee_extension_length_1_enum = 0xde, + ieee_extension_length_2_enum = 0xdf, + ieee_section_type_enum = 0xe6, + ieee_section_alignment_enum = 0xe7, + ieee_external_symbol_enum = 0xe8, + ieee_comma = 0x90, + ieee_external_reference_enum = 0xe9, + ieee_set_current_section_enum = 0xe5, + ieee_address_descriptor_enum = 0xec, + ieee_load_constant_bytes_enum = 0xed, + ieee_load_with_relocation_enum = 0xe4, + + ieee_variable_A_enum = 0xc1, + ieee_variable_B_enum = 0xc2, + ieee_variable_C_enum = 0xc3, + ieee_variable_D_enum = 0xc4, + ieee_variable_E_enum = 0xc5, + ieee_variable_F_enum = 0xc6, + ieee_variable_G_enum = 0xc7, + ieee_variable_H_enum = 0xc8, + ieee_variable_I_enum = 0xc9, + ieee_variable_J_enum = 0xca, + ieee_variable_K_enum = 0xcb, + ieee_variable_L_enum = 0xcc, + ieee_variable_M_enum = 0xcd, + ieee_variable_N_enum = 0xce, + ieee_variable_O_enum = 0xcf, + ieee_variable_P_enum = 0xd0, + ieee_variable_Q_enum = 0xd1, + ieee_variable_R_enum = 0xd2, + ieee_variable_S_enum = 0xd3, + ieee_variable_T_enum = 0xd4, + ieee_variable_U_enum = 0xd5, + ieee_variable_V_enum = 0xd6, + ieee_variable_W_enum = 0xd7, + ieee_variable_X_enum = 0xd8, + ieee_variable_Y_enum = 0xd9, + ieee_variable_Z_enum = 0xda, + ieee_function_plus_enum = 0xa5, + ieee_function_minus_enum = 0xa6, + ieee_function_signed_open_b_enum = 0xba, + ieee_function_signed_close_b_enum = 0xbb, + + ieee_function_unsigned_open_b_enum = 0xbc, + ieee_function_unsigned_close_b_enum = 0xbd, + + ieee_function_either_open_b_enum = 0xbe, + ieee_function_either_close_b_enum = 0xbf, + ieee_record_seperator_enum = 0xdb, + + ieee_e2_first_byte_enum = 0xe2, + ieee_section_size_enum = 0xe2d3, + ieee_physical_region_size_enum = 0xe2c1, + ieee_region_base_address_enum = 0xe2c2, + ieee_mau_size_enum = 0xe2c6, + ieee_m_value_enum = 0xe2cd, + ieee_section_base_address_enum = 0xe2cc, + ieee_asn_record_enum = 0xe2ce, + ieee_section_offset_enum = 0xe2d2, + ieee_value_starting_address_enum = 0xe2c7, + ieee_assign_value_to_variable_enum = 0xe2d7, + ieee_set_current_pc_enum = 0xe2d0, + ieee_value_record_enum = 0xe2c9, + ieee_nn_record = 0xf0, + ieee_at_record_enum = 0xf1, + ieee_ty_record_enum = 0xf2, + ieee_attribute_record_enum = 0xf1c9, + ieee_atn_record_enum = 0xf1ce, + ieee_external_reference_info_record_enum = 0xf1d8, + ieee_weak_external_reference_enum= 0xf4, + ieee_repeat_data_enum = 0xf7, + ieee_bb_record_enum = 0xf8, + ieee_be_record_enum = 0xf9 + } +ieee_record_enum_type; + +typedef struct ieee_section + { + unsigned int section_index; + unsigned int section_type; + char * section_name; + unsigned int parent_section_index; + unsigned int sibling_section_index; + unsigned int context_index; + } +ieee_section_type; + +#define IEEE_REFERENCE_BASE 11 +#define IEEE_PUBLIC_BASE 32 +#define IEEE_SECTION_NUMBER_BASE 1 + diff --git a/contrib/gdb/include/libiberty.h b/contrib/gdb/include/libiberty.h new file mode 100644 index 00000000000..761b2cf060f --- /dev/null +++ b/contrib/gdb/include/libiberty.h @@ -0,0 +1,335 @@ +/* Function declarations for libiberty. + + Copyright 2001, 2002 Free Software Foundation, Inc. + + Note - certain prototypes declared in this header file are for + functions whoes implementation copyright does not belong to the + FSF. Those prototypes are present in this file for reference + purposes only and their presence in this file should not construed + as an indication of ownership by the FSF of the implementation of + those functions in any way or form whatsoever. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Written by Cygnus Support, 1994. + + The libiberty library provides a number of functions which are + missing on some operating systems. We do not declare those here, + to avoid conflicts with the system header files on operating + systems that do support those functions. In this file we only + declare those functions which are specific to libiberty. */ + +#ifndef LIBIBERTY_H +#define LIBIBERTY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ansidecl.h" + +#ifdef ANSI_PROTOTYPES +/* Get a definition for size_t. */ +#include +/* Get a definition for va_list. */ +#include +#endif + +/* Build an argument vector from a string. Allocates memory using + malloc. Use freeargv to free the vector. */ + +extern char **buildargv PARAMS ((const char *)) ATTRIBUTE_MALLOC; + +/* Free a vector returned by buildargv. */ + +extern void freeargv PARAMS ((char **)); + +/* Duplicate an argument vector. Allocates memory using malloc. Use + freeargv to free the vector. */ + +extern char **dupargv PARAMS ((char **)) ATTRIBUTE_MALLOC; + + +/* Return the last component of a path name. Note that we can't use a + prototype here because the parameter is declared inconsistently + across different systems, sometimes as "char *" and sometimes as + "const char *" */ + +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is + undefined, we haven't run the autoconf check so provide the + declaration without arguments. If it is 0, we checked and failed + to find the declaration so provide a fully prototyped one. If it + is 1, we found it so don't provide any declaration at all. */ +#if !HAVE_DECL_BASENAME +#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (HAVE_DECL_BASENAME) +extern char *basename PARAMS ((const char *)); +#else +extern char *basename (); +#endif +#endif + +/* A well-defined basename () that is always compiled in. */ + +extern const char *lbasename PARAMS ((const char *)); + +/* A well-defined realpath () that is always compiled in. */ + +extern char *lrealpath PARAMS ((const char *)); + +/* Concatenate an arbitrary number of strings. You must pass NULL as + the last argument of this function, to terminate the list of + strings. Allocates memory using xmalloc. */ + +extern char *concat PARAMS ((const char *, ...)) ATTRIBUTE_MALLOC; + +/* Concatenate an arbitrary number of strings. You must pass NULL as + the last argument of this function, to terminate the list of + strings. Allocates memory using xmalloc. The first argument is + not one of the strings to be concatenated, but if not NULL is a + pointer to be freed after the new string is created, similar to the + way xrealloc works. */ + +extern char *reconcat PARAMS ((char *, const char *, ...)) ATTRIBUTE_MALLOC; + +/* Determine the length of concatenating an arbitrary number of + strings. You must pass NULL as the last argument of this function, + to terminate the list of strings. */ + +extern unsigned long concat_length PARAMS ((const char *, ...)); + +/* Concatenate an arbitrary number of strings into a SUPPLIED area of + memory. You must pass NULL as the last argument of this function, + to terminate the list of strings. The supplied memory is assumed + to be large enough. */ + +extern char *concat_copy PARAMS ((char *, const char *, ...)); + +/* Concatenate an arbitrary number of strings into a GLOBAL area of + memory. You must pass NULL as the last argument of this function, + to terminate the list of strings. The supplied memory is assumed + to be large enough. */ + +extern char *concat_copy2 PARAMS ((const char *, ...)); + +/* This is the global area used by concat_copy2. */ + +extern char *libiberty_concat_ptr; + +/* Concatenate an arbitrary number of strings. You must pass NULL as + the last argument of this function, to terminate the list of + strings. Allocates memory using alloca. The arguments are + evaluated twice! */ +#define ACONCAT(ACONCAT_PARAMS) \ + (libiberty_concat_ptr = alloca (concat_length ACONCAT_PARAMS + 1), \ + concat_copy2 ACONCAT_PARAMS) + +/* Check whether two file descriptors refer to the same file. */ + +extern int fdmatch PARAMS ((int fd1, int fd2)); + +/* Get the working directory. The result is cached, so don't call + chdir() between calls to getpwd(). */ + +extern char * getpwd PARAMS ((void)); + +/* Get the amount of time the process has run, in microseconds. */ + +extern long get_run_time PARAMS ((void)); + +/* Generate a relocated path to some installation directory. Allocates + return value using malloc. */ + +extern char *make_relative_prefix PARAMS ((const char *, const char *, + const char *)); + +/* Choose a temporary directory to use for scratch files. */ + +extern char *choose_temp_base PARAMS ((void)) ATTRIBUTE_MALLOC; + +/* Return a temporary file name or NULL if unable to create one. */ + +extern char *make_temp_file PARAMS ((const char *)) ATTRIBUTE_MALLOC; + +/* Allocate memory filled with spaces. Allocates using malloc. */ + +extern const char *spaces PARAMS ((int count)); + +/* Return the maximum error number for which strerror will return a + string. */ + +extern int errno_max PARAMS ((void)); + +/* Return the name of an errno value (e.g., strerrno (EINVAL) returns + "EINVAL"). */ + +extern const char *strerrno PARAMS ((int)); + +/* Given the name of an errno value, return the value. */ + +extern int strtoerrno PARAMS ((const char *)); + +/* ANSI's strerror(), but more robust. */ + +extern char *xstrerror PARAMS ((int)); + +/* Return the maximum signal number for which strsignal will return a + string. */ + +extern int signo_max PARAMS ((void)); + +/* Return a signal message string for a signal number + (e.g., strsignal (SIGHUP) returns something like "Hangup"). */ +/* This is commented out as it can conflict with one in system headers. + We still document its existence though. */ + +/*extern const char *strsignal PARAMS ((int));*/ + +/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns + "SIGHUP"). */ + +extern const char *strsigno PARAMS ((int)); + +/* Given the name of a signal, return its number. */ + +extern int strtosigno PARAMS ((const char *)); + +/* Register a function to be run by xexit. Returns 0 on success. */ + +extern int xatexit PARAMS ((void (*fn) (void))); + +/* Exit, calling all the functions registered with xatexit. */ + +extern void xexit PARAMS ((int status)) ATTRIBUTE_NORETURN; + +/* Set the program name used by xmalloc. */ + +extern void xmalloc_set_program_name PARAMS ((const char *)); + +/* Report an allocation failure. */ +extern void xmalloc_failed PARAMS ((size_t)) ATTRIBUTE_NORETURN; + +/* Allocate memory without fail. If malloc fails, this will print a + message to stderr (using the name set by xmalloc_set_program_name, + if any) and then call xexit. */ + +extern PTR xmalloc PARAMS ((size_t)) ATTRIBUTE_MALLOC; + +/* Reallocate memory without fail. This works like xmalloc. Note, + realloc type functions are not suitable for attribute malloc since + they may return the same address across multiple calls. */ + +extern PTR xrealloc PARAMS ((PTR, size_t)); + +/* Allocate memory without fail and set it to zero. This works like + xmalloc. */ + +extern PTR xcalloc PARAMS ((size_t, size_t)) ATTRIBUTE_MALLOC; + +/* Copy a string into a memory buffer without fail. */ + +extern char *xstrdup PARAMS ((const char *)) ATTRIBUTE_MALLOC; + +/* Copy an existing memory buffer to a new memory buffer without fail. */ + +extern PTR xmemdup PARAMS ((const PTR, size_t, size_t)) ATTRIBUTE_MALLOC; + +/* Physical memory routines. Return values are in BYTES. */ +extern double physmem_total PARAMS ((void)); +extern double physmem_available PARAMS ((void)); + +/* hex character manipulation routines */ + +#define _hex_array_size 256 +#define _hex_bad 99 +extern const unsigned char _hex_value[_hex_array_size]; +extern void hex_init PARAMS ((void)); +#define hex_p(c) (hex_value (c) != _hex_bad) +/* If you change this, note well: Some code relies on side effects in + the argument being performed exactly once. */ +#define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)]) + +/* Definitions used by the pexecute routine. */ + +#define PEXECUTE_FIRST 1 +#define PEXECUTE_LAST 2 +#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) +#define PEXECUTE_SEARCH 4 +#define PEXECUTE_VERBOSE 8 + +/* Execute a program. */ + +extern int pexecute PARAMS ((const char *, char * const *, const char *, + const char *, char **, char **, int)); + +/* Wait for pexecute to finish. */ + +extern int pwait PARAMS ((int, int *, int)); + +#if !HAVE_DECL_ASPRINTF +/* Like sprintf but provides a pointer to malloc'd storage, which must + be freed by the caller. */ + +extern int asprintf PARAMS ((char **, const char *, ...)) ATTRIBUTE_PRINTF_2; +#endif + +#if !HAVE_DECL_VASPRINTF +/* Like vsprintf but provides a pointer to malloc'd storage, which + must be freed by the caller. */ + +extern int vasprintf PARAMS ((char **, const char *, va_list)) + ATTRIBUTE_PRINTF(2,0); +#endif + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +/* Drastically simplified alloca configurator. If we're using GCC, + we use __builtin_alloca; otherwise we use the C alloca. The C + alloca is always available. You can override GCC by defining + USE_C_ALLOCA yourself. The canonical autoconf macro C_ALLOCA is + also set/unset as it is often used to indicate whether code needs + to call alloca(0). */ +extern PTR C_alloca PARAMS ((size_t)) ATTRIBUTE_MALLOC; +#undef alloca +#if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA +# define alloca(x) __builtin_alloca(x) +# undef C_ALLOCA +# define ASTRDUP(X) \ + (__extension__ ({ const char *const libiberty_optr = (X); \ + const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \ + char *const libiberty_nptr = alloca (libiberty_len); \ + (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); })) +#else +# define alloca(x) C_alloca(x) +# undef USE_C_ALLOCA +# define USE_C_ALLOCA 1 +# undef C_ALLOCA +# define C_ALLOCA 1 +extern const char *libiberty_optr; +extern char *libiberty_nptr; +extern unsigned long libiberty_len; +# define ASTRDUP(X) \ + (libiberty_optr = (X), \ + libiberty_len = strlen (libiberty_optr) + 1, \ + libiberty_nptr = alloca (libiberty_len), \ + (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len)) +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* ! defined (LIBIBERTY_H) */ diff --git a/contrib/gdb/include/md5.h b/contrib/gdb/include/md5.h new file mode 100644 index 00000000000..ad51f19877a --- /dev/null +++ b/contrib/gdb/include/md5.h @@ -0,0 +1,142 @@ +/* md5.h - Declaration of functions and data types used for MD5 sum + computing library functions. + Copyright 1995, 1996, 2000 Free Software Foundation, Inc. + NOTE: The canonical source of this file is maintained with the GNU C + Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _MD5_H +#define _MD5_H 1 + +#include + +#if defined HAVE_LIMITS_H || _LIBC +# include +#endif + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#ifdef _LIBC +# include +typedef u_int32_t md5_uint32; +#else +# define INT_MAX_32_BITS 2147483647 + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +# ifndef INT_MAX +# define INT_MAX INT_MAX_32_BITS +# endif + +# if INT_MAX == INT_MAX_32_BITS + typedef unsigned int md5_uint32; +# else +# if SHRT_MAX == INT_MAX_32_BITS + typedef unsigned short md5_uint32; +# else +# if LONG_MAX == INT_MAX_32_BITS + typedef unsigned long md5_uint32; +# else + /* The following line is intended to evoke an error. + Using #error is not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +# endif +#endif + +#undef __P +#if defined (__STDC__) && __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; + + md5_uint32 total[2]; + md5_uint32 buflen; + char buffer[128]; +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void md5_init_ctx __P ((struct md5_ctx *ctx)); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void md5_process_block __P ((const void *buffer, size_t len, + struct md5_ctx *ctx)); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md5_process_bytes __P ((const void *buffer, size_t len, + struct md5_ctx *ctx)); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); + + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md5_stream __P ((FILE *stream, void *resblock)); + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); + +#endif diff --git a/contrib/gdb/include/oasys.h b/contrib/gdb/include/oasys.h new file mode 100644 index 00000000000..c8f737a455b --- /dev/null +++ b/contrib/gdb/include/oasys.h @@ -0,0 +1,192 @@ +/* Oasys object format header file for BFD. + + Copyright 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Contributed by Cygnus Support. */ + +#define OASYS_MAX_SEC_COUNT 16 +/* **** */ + +typedef struct oasys_archive_header + { + unsigned int version; + char create_date[12]; + char revision_date[12]; + unsigned int mod_count; + file_ptr mod_tbl_offset; + unsigned int sym_tbl_size; + unsigned int sym_count; + file_ptr sym_tbl_offset; + unsigned int xref_count; + file_ptr xref_lst_offset; + } +oasys_archive_header_type; + +typedef struct oasys_extarchive_header + { + bfd_byte version[4]; + bfd_byte create_date[12]; + bfd_byte revision_date[12]; + bfd_byte mod_count[4]; + bfd_byte mod_tbl_offset[4]; + bfd_byte sym_tbl_size[4]; + bfd_byte sym_count[4]; + bfd_byte sym_tbl_offset[4]; + bfd_byte xref_count[4]; + bfd_byte xref_lst_offset[4]; + } +oasys_extarchive_header_type; + +typedef struct oasys_module_table + { + int mod_number; + char mod_date[12]; + unsigned int mod_size; + unsigned int dep_count; + unsigned int depee_count; + file_ptr file_offset; + unsigned int sect_count; + char *module_name; + unsigned int module_name_size; + } +oasys_module_table_type; + +typedef struct oasys_extmodule_table_a + { + bfd_byte mod_number[4]; + bfd_byte mod_date[12]; + bfd_byte mod_size[4]; + bfd_byte dep_count[4]; + bfd_byte depee_count[4]; + bfd_byte sect_count[4]; + bfd_byte file_offset[4]; + bfd_byte mod_name[32]; + } +oasys_extmodule_table_type_a_type; + +typedef struct oasys_extmodule_table_b + { + bfd_byte mod_number[4]; + bfd_byte mod_date[12]; + bfd_byte mod_size[4]; + bfd_byte dep_count[4]; + bfd_byte depee_count[4]; + bfd_byte sect_count[4]; + bfd_byte file_offset[4]; + bfd_byte mod_name_length[4]; + } +oasys_extmodule_table_type_b_type; + +typedef enum oasys_record + { + oasys_record_is_end_enum = 0, + oasys_record_is_data_enum = 1, + oasys_record_is_symbol_enum = 2, + oasys_record_is_header_enum = 3, + oasys_record_is_named_section_enum = 4, + oasys_record_is_com_enum = 5, + oasys_record_is_debug_enum = 6, + oasys_record_is_section_enum = 7, + oasys_record_is_debug_file_enum = 8, + oasys_record_is_module_enum = 9, + oasys_record_is_local_enum = 10 + } +oasys_record_enum_type; + +typedef struct oasys_record_header + { + unsigned char length; + unsigned char check_sum; + unsigned char type; + unsigned char fill; + } +oasys_record_header_type; + +typedef struct oasys_data_record + { + oasys_record_header_type header; + unsigned char relb; + bfd_byte addr[4]; + /* maximum total size of data record is 255 bytes */ + bfd_byte data[246]; + } +oasys_data_record_type; + +typedef struct oasys_header_record + { + oasys_record_header_type header; + unsigned char version_number; + unsigned char rev_number; + char module_name[26-6]; + char description[64-26]; + } +oasys_header_record_type; + +#define OASYS_VERSION_NUMBER 0 +#define OASYS_REV_NUMBER 0 + +typedef struct oasys_symbol_record + { + oasys_record_header_type header; + unsigned char relb; + bfd_byte value[4]; + bfd_byte refno[2]; + char name[64]; + } +oasys_symbol_record_type; + +#define RELOCATION_PCREL_BIT 0x80 +#define RELOCATION_32BIT_BIT 0x40 +#define RELOCATION_TYPE_BITS 0x30 +#define RELOCATION_TYPE_ABS 0x00 +#define RELOCATION_TYPE_REL 0x10 +#define RELOCATION_TYPE_UND 0x20 +#define RELOCATION_TYPE_COM 0x30 +#define RELOCATION_SECT_BITS 0x0f + +typedef struct oasys_section_record + { + oasys_record_header_type header; + unsigned char relb; + bfd_byte value[4]; + bfd_byte vma[4]; + bfd_byte fill[3]; + } +oasys_section_record_type; + +typedef struct oasys_end_record + { + oasys_record_header_type header; + unsigned char relb; + bfd_byte entry[4]; + bfd_byte fill[2]; + bfd_byte zero; + } +oasys_end_record_type; + +typedef union oasys_record_union + { + oasys_record_header_type header; + oasys_data_record_type data; + oasys_section_record_type section; + oasys_symbol_record_type symbol; + oasys_header_record_type first; + oasys_end_record_type end; + bfd_byte pad[256]; + } +oasys_record_union_type; diff --git a/contrib/gdb/include/objalloc.h b/contrib/gdb/include/objalloc.h new file mode 100644 index 00000000000..c7106478dca --- /dev/null +++ b/contrib/gdb/include/objalloc.h @@ -0,0 +1,115 @@ +/* objalloc.h -- routines to allocate memory for objects + Copyright 1997, 2001 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Cygnus Solutions. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef OBJALLOC_H +#define OBJALLOC_H + +#include "ansidecl.h" + +/* These routines allocate space for an object. The assumption is + that the object will want to allocate space as it goes along, but + will never want to free any particular block. There is a function + to free a block, which also frees all more recently allocated + blocks. There is also a function to free all the allocated space. + + This is essentially a specialization of obstacks. The main + difference is that a block may not be allocated a bit at a time. + Another difference is that these routines are always built on top + of malloc, and always pass an malloc failure back to the caller, + unlike more recent versions of obstacks. */ + +/* This is what an objalloc structure looks like. Callers should not + refer to these fields, nor should they allocate these structure + themselves. Instead, they should only create them via + objalloc_init, and only access them via the functions and macros + listed below. The structure is only defined here so that we can + access it via macros. */ + +struct objalloc +{ + char *current_ptr; + unsigned int current_space; + PTR chunks; +}; + +/* Work out the required alignment. */ + +struct objalloc_align { char x; double d; }; + +#if defined (__STDC__) && __STDC__ +#ifndef offsetof +#include +#endif +#endif +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) +#endif +#define OBJALLOC_ALIGN offsetof (struct objalloc_align, d) + +/* Create an objalloc structure. Returns NULL if malloc fails. */ + +extern struct objalloc *objalloc_create PARAMS ((void)); + +/* Allocate space from an objalloc structure. Returns NULL if malloc + fails. */ + +extern PTR _objalloc_alloc PARAMS ((struct objalloc *, unsigned long)); + +/* The macro version of objalloc_alloc. We only define this if using + gcc, because otherwise we would have to evaluate the arguments + multiple times, or use a temporary field as obstack.h does. */ + +#if defined (__GNUC__) && defined (__STDC__) && __STDC__ + +/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and + does not implement __extension__. But that compiler doesn't define + __GNUC_MINOR__. */ +#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) +#define __extension__ +#endif + +#define objalloc_alloc(o, l) \ + __extension__ \ + ({ struct objalloc *__o = (o); \ + unsigned long __len = (l); \ + if (__len == 0) \ + __len = 1; \ + __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \ + (__len <= __o->current_space \ + ? (__o->current_ptr += __len, \ + __o->current_space -= __len, \ + (PTR) (__o->current_ptr - __len)) \ + : _objalloc_alloc (__o, __len)); }) + +#else /* ! __GNUC__ */ + +#define objalloc_alloc(o, l) _objalloc_alloc ((o), (l)) + +#endif /* ! __GNUC__ */ + +/* Free an entire objalloc structure. */ + +extern void objalloc_free PARAMS ((struct objalloc *)); + +/* Free a block allocated by objalloc_alloc. This also frees all more + recently allocated blocks. */ + +extern void objalloc_free_block PARAMS ((struct objalloc *, PTR)); + +#endif /* OBJALLOC_H */ diff --git a/contrib/gdb/include/obstack.h b/contrib/gdb/include/obstack.h new file mode 100644 index 00000000000..5496ff24071 --- /dev/null +++ b/contrib/gdb/include/obstack.h @@ -0,0 +1,611 @@ +/* obstack.h - object stack macros + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, + 1999, 2000 + Free Software Foundation, Inc. + + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Summary: + +All the apparent functions defined here are macros. The idea +is that you would use these pre-tested macros to solve a +very specific set of problems, and they would run fast. +Caution: no side-effects in arguments please!! They may be +evaluated MANY times!! + +These macros operate a stack of objects. Each object starts life +small, and may grow to maturity. (Consider building a word syllable +by syllable.) An object can move while it is growing. Once it has +been "finished" it never changes address again. So the "top of the +stack" is typically an immature growing object, while the rest of the +stack is of mature, fixed size and fixed address objects. + +These routines grab large chunks of memory, using a function you +supply, called `obstack_chunk_alloc'. On occasion, they free chunks, +by calling `obstack_chunk_free'. You must define them and declare +them before using any obstack macros. + +Each independent stack is represented by a `struct obstack'. +Each of the obstack macros expects a pointer to such a structure +as the first argument. + +One motivation for this package is the problem of growing char strings +in symbol tables. Unless you are "fascist pig with a read-only mind" +--Gosper's immortal quote from HAKMEM item 154, out of context--you +would not like to put any arbitrary upper limit on the length of your +symbols. + +In practice this often means you will build many short symbols and a +few long symbols. At the time you are reading a symbol you don't know +how long it is. One traditional method is to read a symbol into a +buffer, realloc()ating the buffer every time you try to read a symbol +that is longer than the buffer. This is beaut, but you still will +want to copy the symbol from the buffer to a more permanent +symbol-table entry say about half the time. + +With obstacks, you can work differently. Use one obstack for all symbol +names. As you read a symbol, grow the name in the obstack gradually. +When the name is complete, finalize it. Then, if the symbol exists already, +free the newly read name. + +The way we do this is to take a large chunk, allocating memory from +low addresses. When you want to build a symbol in the chunk you just +add chars above the current "high water mark" in the chunk. When you +have finished adding chars, because you got to the end of the symbol, +you know how long the chars are, and you can create a new object. +Mostly the chars will not burst over the highest address of the chunk, +because you would typically expect a chunk to be (say) 100 times as +long as an average object. + +In case that isn't clear, when we have enough chars to make up +the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) +so we just point to it where it lies. No moving of chars is +needed and this is the second win: potentially long strings need +never be explicitly shuffled. Once an object is formed, it does not +change its address during its lifetime. + +When the chars burst over a chunk boundary, we allocate a larger +chunk, and then copy the partly formed object from the end of the old +chunk to the beginning of the new larger chunk. We then carry on +accreting characters to the end of the object as we normally would. + +A special macro is provided to add a single char at a time to a +growing object. This allows the use of register variables, which +break the ordinary 'growth' macro. + +Summary: + We allocate large chunks. + We carve out one object at a time from the current chunk. + Once carved, an object never moves. + We are free to append data of any size to the currently + growing object. + Exactly one object is growing in an obstack at any one time. + You can run one obstack per control block. + You may have as many control blocks as you dare. + Because of the way we do it, you can `unwind' an obstack + back to a previous state. (You may remove objects much + as you would with a stack.) +*/ + + +/* Don't do the contents of this file more than once. */ + +#ifndef _OBSTACK_H +#define _OBSTACK_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* We use subtraction of (char *) 0 instead of casting to int + because on word-addressable machines a simple cast to int + may ignore the byte-within-word field of the pointer. */ + +#ifndef __PTR_TO_INT +# define __PTR_TO_INT(P) ((P) - (char *) 0) +#endif + +#ifndef __INT_TO_PTR +# define __INT_TO_PTR(P) ((P) + (char *) 0) +#endif + +/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is + defined, as with GNU C, use that; that way we don't pollute the + namespace with 's symbols. Otherwise, if is + available, include it and use ptrdiff_t. In traditional C, long is + the best that we can do. */ + +#ifdef __PTRDIFF_TYPE__ +# define PTR_INT_TYPE __PTRDIFF_TYPE__ +#else +# ifdef HAVE_STDDEF_H +# include +# define PTR_INT_TYPE ptrdiff_t +# else +# define PTR_INT_TYPE long +# endif +#endif + +#if defined _LIBC || defined HAVE_STRING_H +# include +# if defined __STDC__ && __STDC__ +# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N)) +# else +# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) +# endif +#else +# ifdef memcpy +# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) +# else +# define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N)) +# endif +#endif + +struct _obstack_chunk /* Lives at front of each chunk. */ +{ + char *limit; /* 1 past end of this chunk */ + struct _obstack_chunk *prev; /* address of prior chunk or NULL */ + char contents[4]; /* objects begin here */ +}; + +struct obstack /* control current object in current chunk */ +{ + long chunk_size; /* preferred size to allocate chunks in */ + struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ + char *object_base; /* address of object we are building */ + char *next_free; /* where to add next char to current object */ + char *chunk_limit; /* address of char after current chunk */ + PTR_INT_TYPE temp; /* Temporary for some macros. */ + int alignment_mask; /* Mask of alignment for each object. */ +#if defined __STDC__ && __STDC__ + /* These prototypes vary based on `use_extra_arg', and we use + casts to the prototypeless function type in all assignments, + but having prototypes here quiets -Wstrict-prototypes. */ + struct _obstack_chunk *(*chunkfun) (void *, long); + void (*freefun) (void *, struct _obstack_chunk *); + void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ +#else + struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ + void (*freefun) (); /* User's function to free a chunk. */ + char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ +#endif + unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ + unsigned maybe_empty_object:1;/* There is a possibility that the current + chunk contains a zero-length object. This + prevents freeing the chunk if we allocate + a bigger chunk to replace it. */ + unsigned alloc_failed:1; /* No longer used, as we now call the failed + handler on error, but retained for binary + compatibility. */ +}; + +/* Declare the external functions we use; they are in obstack.c. */ + +#if defined __STDC__ && __STDC__ +extern void _obstack_newchunk (struct obstack *, int); +extern void _obstack_free (struct obstack *, void *); +extern int _obstack_begin (struct obstack *, int, int, + void *(*) (long), void (*) (void *)); +extern int _obstack_begin_1 (struct obstack *, int, int, + void *(*) (void *, long), + void (*) (void *, void *), void *); +extern int _obstack_memory_used (struct obstack *); +#else +extern void _obstack_newchunk (); +extern void _obstack_free (); +extern int _obstack_begin (); +extern int _obstack_begin_1 (); +extern int _obstack_memory_used (); +#endif + +#if defined __STDC__ && __STDC__ + +/* Do the function-declarations after the structs + but before defining the macros. */ + +void obstack_init (struct obstack *obstack); + +void * obstack_alloc (struct obstack *obstack, int size); + +void * obstack_copy (struct obstack *obstack, void *address, int size); +void * obstack_copy0 (struct obstack *obstack, void *address, int size); + +void obstack_free (struct obstack *obstack, void *block); + +void obstack_blank (struct obstack *obstack, int size); + +void obstack_grow (struct obstack *obstack, void *data, int size); +void obstack_grow0 (struct obstack *obstack, void *data, int size); + +void obstack_1grow (struct obstack *obstack, int data_char); +void obstack_ptr_grow (struct obstack *obstack, void *data); +void obstack_int_grow (struct obstack *obstack, int data); + +void * obstack_finish (struct obstack *obstack); + +int obstack_object_size (struct obstack *obstack); + +int obstack_room (struct obstack *obstack); +void obstack_make_room (struct obstack *obstack, int size); +void obstack_1grow_fast (struct obstack *obstack, int data_char); +void obstack_ptr_grow_fast (struct obstack *obstack, void *data); +void obstack_int_grow_fast (struct obstack *obstack, int data); +void obstack_blank_fast (struct obstack *obstack, int size); + +void * obstack_base (struct obstack *obstack); +void * obstack_next_free (struct obstack *obstack); +int obstack_alignment_mask (struct obstack *obstack); +int obstack_chunk_size (struct obstack *obstack); +int obstack_memory_used (struct obstack *obstack); + +#endif /* __STDC__ */ + +/* Non-ANSI C cannot really support alternative functions for these macros, + so we do not declare them. */ + +/* Error handler called when `obstack_chunk_alloc' failed to allocate + more memory. This can be set to a user defined function. The + default action is to print a message and abort. */ +#if defined __STDC__ && __STDC__ +extern void (*obstack_alloc_failed_handler) (void); +#else +extern void (*obstack_alloc_failed_handler) (); +#endif + +/* Exit value used when `print_and_abort' is used. */ +extern int obstack_exit_failure; + +/* Pointer to beginning of object being allocated or to be allocated next. + Note that this might not be the final address of the object + because a new chunk might be needed to hold the final size. */ + +#define obstack_base(h) ((h)->object_base) + +/* Size for allocating ordinary chunks. */ + +#define obstack_chunk_size(h) ((h)->chunk_size) + +/* Pointer to next byte not yet allocated in current chunk. */ + +#define obstack_next_free(h) ((h)->next_free) + +/* Mask specifying low bits that should be clear in address of an object. */ + +#define obstack_alignment_mask(h) ((h)->alignment_mask) + +/* To prevent prototype warnings provide complete argument list in + standard C version. */ +#if defined __STDC__ && __STDC__ + +# define obstack_init(h) \ + _obstack_begin ((h), 0, 0, \ + (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) + +# define obstack_begin(h, size) \ + _obstack_begin ((h), (size), 0, \ + (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) + +# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ + _obstack_begin ((h), (size), (alignment), \ + (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun)) + +# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ + _obstack_begin_1 ((h), (size), (alignment), \ + (void *(*) (void *, long)) (chunkfun), \ + (void (*) (void *, void *)) (freefun), (arg)) + +# define obstack_chunkfun(h, newchunkfun) \ + ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) + +# define obstack_freefun(h, newfreefun) \ + ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) + +#else + +# define obstack_init(h) \ + _obstack_begin ((h), 0, 0, \ + (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) + +# define obstack_begin(h, size) \ + _obstack_begin ((h), (size), 0, \ + (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) + +# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ + _obstack_begin ((h), (size), (alignment), \ + (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) + +# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ + _obstack_begin_1 ((h), (size), (alignment), \ + (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) + +# define obstack_chunkfun(h, newchunkfun) \ + ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) + +# define obstack_freefun(h, newfreefun) \ + ((h) -> freefun = (void (*)()) (newfreefun)) + +#endif + +#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) + +#define obstack_blank_fast(h,n) ((h)->next_free += (n)) + +#define obstack_memory_used(h) _obstack_memory_used (h) + +#if defined __GNUC__ && defined __STDC__ && __STDC__ +/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and + does not implement __extension__. But that compiler doesn't define + __GNUC_MINOR__. */ +# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) +# define __extension__ +# endif + +/* For GNU C, if not -traditional, + we can define these macros to compute all args only once + without using a global variable. + Also, we can avoid using the `temp' slot, to make faster code. */ + +# define obstack_object_size(OBSTACK) \ + __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + (unsigned) (__o->next_free - __o->object_base); }) + +# define obstack_room(OBSTACK) \ + __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + (unsigned) (__o->chunk_limit - __o->next_free); }) + +# define obstack_make_room(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->chunk_limit - __o->next_free < __len) \ + _obstack_newchunk (__o, __len); \ + (void) 0; }) + +# define obstack_empty_p(OBSTACK) \ + __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); }) + +# define obstack_grow(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->next_free + __len > __o->chunk_limit) \ + _obstack_newchunk (__o, __len); \ + _obstack_memcpy (__o->next_free, (where), __len); \ + __o->next_free += __len; \ + (void) 0; }) + +# define obstack_grow0(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->next_free + __len + 1 > __o->chunk_limit) \ + _obstack_newchunk (__o, __len + 1); \ + _obstack_memcpy (__o->next_free, (where), __len); \ + __o->next_free += __len; \ + *(__o->next_free)++ = 0; \ + (void) 0; }) + +# define obstack_1grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + 1 > __o->chunk_limit) \ + _obstack_newchunk (__o, 1); \ + obstack_1grow_fast (__o, datum); \ + (void) 0; }) + +/* These assume that the obstack alignment is good enough for pointers or ints, + and that the data added so far to the current object + shares that much alignment. */ + +# define obstack_ptr_grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (void *)); \ + obstack_ptr_grow_fast (__o, datum); }) + +# define obstack_int_grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (int) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (int)); \ + obstack_int_grow_fast (__o, datum); }) + +# define obstack_ptr_grow_fast(OBSTACK,aptr) \ +__extension__ \ +({ struct obstack *__o1 = (OBSTACK); \ + *(const void **) __o1->next_free = (aptr); \ + __o1->next_free += sizeof (const void *); \ + (void) 0; }) + +# define obstack_int_grow_fast(OBSTACK,aint) \ +__extension__ \ +({ struct obstack *__o1 = (OBSTACK); \ + *(int *) __o1->next_free = (aint); \ + __o1->next_free += sizeof (int); \ + (void) 0; }) + +# define obstack_blank(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->chunk_limit - __o->next_free < __len) \ + _obstack_newchunk (__o, __len); \ + obstack_blank_fast (__o, __len); \ + (void) 0; }) + +# define obstack_alloc(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_blank (__h, (length)); \ + obstack_finish (__h); }) + +# define obstack_copy(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow (__h, (where), (length)); \ + obstack_finish (__h); }) + +# define obstack_copy0(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow0 (__h, (where), (length)); \ + obstack_finish (__h); }) + +/* The local variable is named __o1 to avoid a name conflict + when obstack_blank is called. */ +# define obstack_finish(OBSTACK) \ +__extension__ \ +({ struct obstack *__o1 = (OBSTACK); \ + void *value; \ + value = (void *) __o1->object_base; \ + if (__o1->next_free == value) \ + __o1->maybe_empty_object = 1; \ + __o1->next_free \ + = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ + & ~ (__o1->alignment_mask)); \ + if (__o1->next_free - (char *)__o1->chunk \ + > __o1->chunk_limit - (char *)__o1->chunk) \ + __o1->next_free = __o1->chunk_limit; \ + __o1->object_base = __o1->next_free; \ + value; }) + +# define obstack_free(OBSTACK, OBJ) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + void *__obj = (OBJ); \ + if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ + __o->next_free = __o->object_base = __obj; \ + else (obstack_free) (__o, __obj); }) + +#else /* not __GNUC__ or not __STDC__ */ + +# define obstack_object_size(h) \ + (unsigned) ((h)->next_free - (h)->object_base) + +# define obstack_room(h) \ + (unsigned) ((h)->chunk_limit - (h)->next_free) + +# define obstack_empty_p(h) \ + ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0) + +/* Note that the call to _obstack_newchunk is enclosed in (..., 0) + so that we can avoid having void expressions + in the arms of the conditional expression. + Casting the third operand to void was tried before, + but some compilers won't accept it. */ + +# define obstack_make_room(h,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0)) + +# define obstack_grow(h,where,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ + _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ + (h)->next_free += (h)->temp) + +# define obstack_grow0(h,where,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ + _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ + (h)->next_free += (h)->temp, \ + *((h)->next_free)++ = 0) + +# define obstack_1grow(h,datum) \ +( (((h)->next_free + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), 1), 0) : 0), \ + obstack_1grow_fast (h, datum)) + +# define obstack_ptr_grow(h,datum) \ +( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ + obstack_ptr_grow_fast (h, datum)) + +# define obstack_int_grow(h,datum) \ +( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ + obstack_int_grow_fast (h, datum)) + +# define obstack_ptr_grow_fast(h,aptr) \ + (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) + +# define obstack_int_grow_fast(h,aint) \ + (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr)) + +# define obstack_blank(h,length) \ +( (h)->temp = (length), \ + (((h)->chunk_limit - (h)->next_free < (h)->temp) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ + obstack_blank_fast (h, (h)->temp)) + +# define obstack_alloc(h,length) \ + (obstack_blank ((h), (length)), obstack_finish ((h))) + +# define obstack_copy(h,where,length) \ + (obstack_grow ((h), (where), (length)), obstack_finish ((h))) + +# define obstack_copy0(h,where,length) \ + (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) + +# define obstack_finish(h) \ +( ((h)->next_free == (h)->object_base \ + ? (((h)->maybe_empty_object = 1), 0) \ + : 0), \ + (h)->temp = __PTR_TO_INT ((h)->object_base), \ + (h)->next_free \ + = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ + & ~ ((h)->alignment_mask)), \ + (((h)->next_free - (char *) (h)->chunk \ + > (h)->chunk_limit - (char *) (h)->chunk) \ + ? ((h)->next_free = (h)->chunk_limit) : 0), \ + (h)->object_base = (h)->next_free, \ + __INT_TO_PTR ((h)->temp)) + +# if defined __STDC__ && __STDC__ +# define obstack_free(h,obj) \ +( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ + (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ + ? (int) ((h)->next_free = (h)->object_base \ + = (h)->temp + (char *) (h)->chunk) \ + : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) +# else +# define obstack_free(h,obj) \ +( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ + (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ + ? (int) ((h)->next_free = (h)->object_base \ + = (h)->temp + (char *) (h)->chunk) \ + : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) +# endif + +#endif /* not __GNUC__ or not __STDC__ */ + +#ifdef __cplusplus +} /* C++ */ +#endif + +#endif /* obstack.h */ diff --git a/contrib/gdb/include/os9k.h b/contrib/gdb/include/os9k.h new file mode 100644 index 00000000000..596f56d5a6a --- /dev/null +++ b/contrib/gdb/include/os9k.h @@ -0,0 +1,181 @@ +/* os9k.h - OS-9000 i386 module header definitions + Copyright 2000 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#if !defined(_MODULE_H) +#define _MODULE_H + +#define _MPF386 + +/* Size of common header less parity field. */ +#define N_M_PARITY (sizeof(mh_com)-sizeof(unisgned short)) +#define OLD_M_PARITY 46 +#define M_PARITY N_M_PARITY + +#ifdef _MPF68K +#define MODSYNC 0x4afc /* Module header sync code for 680x0 processors. */ +#endif + +#ifdef _MPF386 +#define MODSYNC 0x4afc /* Module header sync code for 80386 processors. */ +#endif + +#define MODREV 1 /* Module format revision 1. */ +#define CRCCON 0x800063 /* CRC polynomial constant. */ + +/* Module access permission values. */ +#define MP_OWNER_READ 0x0001 +#define MP_OWNER_WRITE 0x0002 +#define MP_OWNER_EXEC 0x0004 +#define MP_GROUP_READ 0x0010 +#define MP_GROUP_WRITE 0x0020 +#define MP_GROUP_EXEC 0x0040 +#define MP_WORLD_READ 0x0100 +#define MP_WORLD_WRITE 0x0200 +#define MP_WORLD_EXEC 0x0400 +#define MP_WORLD_ACCESS 0x0777 +#define MP_OWNER_MASK 0x000f +#define MP_GROUP_MASK 0x00f0 +#define MP_WORLD_MASK 0x0f00 +#define MP_SYSTM_MASK 0xf000 + +/* Module Type/Language values. */ +#define MT_ANY 0 +#define MT_PROGRAM 0x0001 +#define MT_SUBROUT 0x0002 +#define MT_MULTI 0x0003 +#define MT_DATA 0x0004 +#define MT_TRAPLIB 0x000b +#define MT_SYSTEM 0x000c +#define MT_FILEMAN 0x000d +#define MT_DEVDRVR 0x000e +#define MT_DEVDESC 0x000f +#define MT_MASK 0xff00 + +#define ML_ANY 0 +#define ML_OBJECT 1 +#define ML_ICODE 2 +#define ML_PCODE 3 +#define ML_CCODE 4 +#define ML_CBLCODE 5 +#define ML_FRTNCODE 6 +#define ML_MASK 0x00ff + +#define mktypelang(type, lang) (((type) << 8) | (lang)) + +/* Module Attribute values. */ +#define MA_REENT 0x80 +#define MA_GHOST 0x40 +#define MA_SUPER 0x20 +#define MA_MASK 0xff00 +#define MR_MASK 0x00ff + +#define mkattrevs(attr, revs) (((attr) << 8) | (revs)) + +#define m_user m_owner.grp_usr.usr +#define m_group m_owner.grp_usr.grp +#define m_group_user m_owner.group_user + +/* Macro definitions for accessing module header fields. */ +#define MODNAME(mod) ((u_char*)((u_char*)mod + ((Mh_com)mod)->m_name)) +#if 0 +/* Appears not to be used, and the u_int32 typedef is gone (because it + conflicted with a Mach header. */ +#define MODSIZE(mod) ((u_int32)((Mh_com)mod)->m_size) +#endif /* 0 */ +#define MHCOM_BYTES_SIZE 80 +#define N_BADMAG(a) (((a).a_info) != MODSYNC) + +typedef struct mh_com +{ + /* Sync bytes ($4afc). */ + unsigned char m_sync[2]; + unsigned char m_sysrev[2]; /* System revision check value. */ + unsigned char m_size[4]; /* Module size. */ + unsigned char m_owner[4]; /* Group/user id. */ + unsigned char m_name[4]; /* Offset to module name. */ + unsigned char m_access[2]; /* Access permissions. */ + unsigned char m_tylan[2]; /* Type/lang. */ + unsigned char m_attrev[2]; /* Rev/attr. */ + unsigned char m_edit[2]; /* Edition. */ + unsigned char m_needs[4]; /* Module hardware requirements flags. (reserved). */ + unsigned char m_usage[4]; /* Comment string offset. */ + unsigned char m_symbol[4]; /* Symbol table offset. */ + unsigned char m_exec[4]; /* Offset to execution entry point. */ + unsigned char m_excpt[4]; /* Offset to exception entry point. */ + unsigned char m_data[4]; /* Data storage requirement. */ + unsigned char m_stack[4]; /* Stack size. */ + unsigned char m_idata[4]; /* Offset to initialized data. */ + unsigned char m_idref[4]; /* Offset to data reference lists. */ + unsigned char m_init[4]; /* Initialization routine offset. */ + unsigned char m_term[4]; /* Termination routine offset. */ + unsigned char m_ident[2]; /* Ident code for ident program. */ + char m_spare[8]; /* Reserved bytes. */ + unsigned char m_parity[2]; /* Header parity. */ +} mh_com,*Mh_com; + +/* Executable memory module. */ +typedef mh_com *Mh_exec,mh_exec; + +/* Data memory module. */ +typedef mh_com *Mh_data,mh_data; + +/* File manager memory module. */ +typedef mh_com *Mh_fman,mh_fman; + +/* Device driver module. */ +typedef mh_com *Mh_drvr,mh_drvr; + +/* Trap handler module. */ +typedef mh_com mh_trap, *Mh_trap; + +/* Device descriptor module. */ +typedef mh_com *Mh_dev,mh_dev; + +/* Configuration module. */ +typedef mh_com *Mh_config, mh_config; + +#if 0 + +#if !defined(_MODDIR_H) +/* Go get _os_fmod (and others). */ +#include +#endif + +error_code _os_crc (void *, u_int32, int *); +error_code _os_datmod (char *, u_int32, u_int16 *, u_int16 *, u_int32, void **, mh_data **); +error_code _os_get_moddir (void *, u_int32 *); +error_code _os_initdata (mh_com *, void *); +error_code _os_link (char **, mh_com **, void **, u_int16 *, u_int16 *); +error_code _os_linkm (mh_com *, void **, u_int16 *, u_int16 *); +error_code _os_load (char *, mh_com **, void **, u_int32, u_int16 *, u_int16 *, u_int32); +error_code _os_mkmodule (char *, u_int32, u_int16 *, u_int16 *, u_int32, void **, mh_com **, u_int32); +error_code _os_modaddr (void *, mh_com **); +error_code _os_setcrc (mh_com *); +error_code _os_slink (u_int32, char *, void **, void **, mh_com **); +error_code _os_slinkm (u_int32, mh_com *, void **, void **); +error_code _os_unlink (mh_com *); +error_code _os_unload (char *, u_int32); +error_code _os_tlink (u_int32, char *, void **, mh_trap **, void *, u_int32); +error_code _os_tlinkm (u_int32, mh_com *, void **, void *, u_int32); +error_code _os_iodel (mh_com *); +error_code _os_vmodul (mh_com *, mh_com *, u_int32); +#endif /* 0 */ + +#endif diff --git a/contrib/gdb/include/partition.h b/contrib/gdb/include/partition.h new file mode 100644 index 00000000000..5d3623f716e --- /dev/null +++ b/contrib/gdb/include/partition.h @@ -0,0 +1,85 @@ +/* List implementation of a partition of consecutive integers. + Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This package implements a partition of consecutive integers. The + elements are partitioned into classes. Each class is represented + by one of its elements, the canonical element, which is chosen + arbitrarily from elements in the class. The principal operations + on a partition are FIND, which takes an element, determines its + class, and returns the canonical element for that class, and UNION, + which unites the two classes that contain two given elements into a + single class. + + The list implementation used here provides constant-time finds. By + storing the size of each class with the class's canonical element, + it is able to perform unions over all the classes in the partition + in O (N log N) time. */ + +#ifndef _PARTITION_H +#define _PARTITION_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ansidecl.h" +#include + +struct partition_elem +{ + /* The canonical element that represents the class containing this + element. */ + int class_element; + /* The next element in this class. Elements in each class form a + circular list. */ + struct partition_elem* next; + /* The number of elements in this class. Valid only if this is the + canonical element for its class. */ + unsigned class_count; +}; + +typedef struct partition_def +{ + /* The number of elements in this partition. */ + int num_elements; + /* The elements in the partition. */ + struct partition_elem elements[1]; +} *partition; + +extern partition partition_new PARAMS((int)); +extern void partition_delete PARAMS((partition)); +extern int partition_union PARAMS((partition, + int, + int)); +extern void partition_print PARAMS((partition, + FILE*)); + +/* Returns the canonical element corresponding to the class containing + ELEMENT__ in PARTITION__. */ + +#define partition_find(partition__, element__) \ + ((partition__)->elements[(element__)].class_element) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PARTITION_H */ diff --git a/contrib/gdb/include/progress.h b/contrib/gdb/include/progress.h new file mode 100644 index 00000000000..23b0960078a --- /dev/null +++ b/contrib/gdb/include/progress.h @@ -0,0 +1,37 @@ +/* Default definitions for progress macros. + Copyright 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 +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* The default definitions below are intended to be replaced by real + definitions, if building the tools for an interactive programming + environment. */ + +#ifndef _PROGRESS_H +#define _PROGRESS_H + +#ifndef START_PROGRESS +#define START_PROGRESS(STR,N) +#endif + +#ifndef PROGRESS +#define PROGRESS(X) +#endif + +#ifndef END_PROGRESS +#define END_PROGRESS(STR) +#endif + +#endif /* _PROGRESS_H */ diff --git a/contrib/gdb/include/safe-ctype.h b/contrib/gdb/include/safe-ctype.h new file mode 100644 index 00000000000..69a3f74cc6f --- /dev/null +++ b/contrib/gdb/include/safe-ctype.h @@ -0,0 +1,119 @@ +/* replacement macros. + + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Contributed by Zack Weinberg . + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* This is a compatible replacement of the standard C library's + with the following properties: + + - Implements all isxxx() macros required by C99. + - Also implements some character classes useful when + parsing C-like languages. + - Does not change behavior depending on the current locale. + - Behaves properly for all values in the range of a signed or + unsigned char. + + To avoid conflicts, this header defines the isxxx functions in upper + case, e.g. ISALPHA not isalpha. */ + +#ifndef SAFE_CTYPE_H +#define SAFE_CTYPE_H + +#ifdef isalpha + #error "safe-ctype.h and ctype.h may not be used simultaneously" +#endif + +/* Determine host character set. */ +#define HOST_CHARSET_UNKNOWN 0 +#define HOST_CHARSET_ASCII 1 +#define HOST_CHARSET_EBCDIC 2 + +#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ + && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 +# define HOST_CHARSET HOST_CHARSET_ASCII +#else +# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \ + && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A +# define HOST_CHARSET HOST_CHARSET_EBCDIC +# else +# define HOST_CHARSET HOST_CHARSET_UNKNOWN +# endif +#endif + +/* Categories. */ + +enum { + /* In C99 */ + _sch_isblank = 0x0001, /* space \t */ + _sch_iscntrl = 0x0002, /* nonprinting characters */ + _sch_isdigit = 0x0004, /* 0-9 */ + _sch_islower = 0x0008, /* a-z */ + _sch_isprint = 0x0010, /* any printing character including ' ' */ + _sch_ispunct = 0x0020, /* all punctuation */ + _sch_isspace = 0x0040, /* space \t \n \r \f \v */ + _sch_isupper = 0x0080, /* A-Z */ + _sch_isxdigit = 0x0100, /* 0-9A-Fa-f */ + + /* Extra categories useful to cpplib. */ + _sch_isidst = 0x0200, /* A-Za-z_ */ + _sch_isvsp = 0x0400, /* \n \r */ + _sch_isnvsp = 0x0800, /* space \t \f \v \0 */ + + /* Combinations of the above. */ + _sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */ + _sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */ + _sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */ + _sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */ + _sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */ + _sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C + (plus ` and @) */ +}; + +/* Character classification. */ +extern const unsigned short _sch_istable[256]; + +#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit)) + +#define ISALPHA(c) _sch_test(c, _sch_isalpha) +#define ISALNUM(c) _sch_test(c, _sch_isalnum) +#define ISBLANK(c) _sch_test(c, _sch_isblank) +#define ISCNTRL(c) _sch_test(c, _sch_iscntrl) +#define ISDIGIT(c) _sch_test(c, _sch_isdigit) +#define ISGRAPH(c) _sch_test(c, _sch_isgraph) +#define ISLOWER(c) _sch_test(c, _sch_islower) +#define ISPRINT(c) _sch_test(c, _sch_isprint) +#define ISPUNCT(c) _sch_test(c, _sch_ispunct) +#define ISSPACE(c) _sch_test(c, _sch_isspace) +#define ISUPPER(c) _sch_test(c, _sch_isupper) +#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit) + +#define ISIDNUM(c) _sch_test(c, _sch_isidnum) +#define ISIDST(c) _sch_test(c, _sch_isidst) +#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic) +#define IS_VSPACE(c) _sch_test(c, _sch_isvsp) +#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp) +#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp) + +/* Character transformation. */ +extern const unsigned char _sch_toupper[256]; +extern const unsigned char _sch_tolower[256]; +#define TOUPPER(c) _sch_toupper[(c) & 0xff] +#define TOLOWER(c) _sch_tolower[(c) & 0xff] + +#endif /* SAFE_CTYPE_H */ diff --git a/contrib/gdb/include/sort.h b/contrib/gdb/include/sort.h new file mode 100644 index 00000000000..3f3a92f18f0 --- /dev/null +++ b/contrib/gdb/include/sort.h @@ -0,0 +1,48 @@ +/* Sorting algorithms. + Copyright (C) 2000, 2002 Free Software Foundation, Inc. + Contributed by Mark Mitchell . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef SORT_H +#define SORT_H + +#include /* For size_t */ +#ifdef __STDC__ +#include +#endif /* __STDC__ */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ansidecl.h" + +/* Sort an array of pointers. */ + +extern void sort_pointers PARAMS ((size_t, void **, void **)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SORT_H */ + + + + diff --git a/contrib/gdb/include/splay-tree.h b/contrib/gdb/include/splay-tree.h new file mode 100644 index 00000000000..86707fc1d2f --- /dev/null +++ b/contrib/gdb/include/splay-tree.h @@ -0,0 +1,159 @@ +/* A splay-tree datatype. + Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc. + Contributed by Mark Mitchell (mark@markmitchell.com). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* For an easily readable description of splay-trees, see: + + Lewis, Harry R. and Denenberg, Larry. Data Structures and Their + Algorithms. Harper-Collins, Inc. 1991. + + The major feature of splay trees is that all basic tree operations + are amortized O(log n) time for a tree with n nodes. */ + +#ifndef _SPLAY_TREE_H +#define _SPLAY_TREE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ansidecl.h" + +#ifndef GTY +#define GTY(X) +#endif + +/* Use typedefs for the key and data types to facilitate changing + these types, if necessary. These types should be sufficiently wide + that any pointer or scalar can be cast to these types, and then + cast back, without loss of precision. */ +typedef unsigned long int splay_tree_key; +typedef unsigned long int splay_tree_value; + +/* Forward declaration for a node in the tree. */ +typedef struct splay_tree_node_s *splay_tree_node; + +/* The type of a function which compares two splay-tree keys. The + function should return values as for qsort. */ +typedef int (*splay_tree_compare_fn) PARAMS((splay_tree_key, splay_tree_key)); + +/* The type of a function used to deallocate any resources associated + with the key. */ +typedef void (*splay_tree_delete_key_fn) PARAMS((splay_tree_key)); + +/* The type of a function used to deallocate any resources associated + with the value. */ +typedef void (*splay_tree_delete_value_fn) PARAMS((splay_tree_value)); + +/* The type of a function used to iterate over the tree. */ +typedef int (*splay_tree_foreach_fn) PARAMS((splay_tree_node, void*)); + +/* The type of a function used to allocate memory for tree root and + node structures. The first argument is the number of bytes needed; + the second is a data pointer the splay tree functions pass through + to the allocator. This function must never return zero. */ +typedef PTR (*splay_tree_allocate_fn) PARAMS((int, void *)); + +/* The type of a function used to free memory allocated using the + corresponding splay_tree_allocate_fn. The first argument is the + memory to be freed; the latter is a data pointer the splay tree + functions pass through to the freer. */ +typedef void (*splay_tree_deallocate_fn) PARAMS((void *, void *)); + +/* The nodes in the splay tree. */ +struct splay_tree_node_s GTY(()) +{ + /* The key. */ + splay_tree_key GTY ((use_param1 (""))) key; + + /* The value. */ + splay_tree_value GTY ((use_param2 (""))) value; + + /* The left and right children, respectively. */ + splay_tree_node GTY ((use_params (""))) left; + splay_tree_node GTY ((use_params (""))) right; +}; + +/* The splay tree itself. */ +struct splay_tree_s GTY(()) +{ + /* The root of the tree. */ + splay_tree_node GTY ((use_params (""))) root; + + /* The comparision function. */ + splay_tree_compare_fn comp; + + /* The deallocate-key function. NULL if no cleanup is necessary. */ + splay_tree_delete_key_fn delete_key; + + /* The deallocate-value function. NULL if no cleanup is necessary. */ + splay_tree_delete_value_fn delete_value; + + /* Allocate/free functions, and a data pointer to pass to them. */ + splay_tree_allocate_fn allocate; + splay_tree_deallocate_fn deallocate; + PTR GTY((skip (""))) allocate_data; + +}; +typedef struct splay_tree_s *splay_tree; + +extern splay_tree splay_tree_new PARAMS((splay_tree_compare_fn, + splay_tree_delete_key_fn, + splay_tree_delete_value_fn)); +extern splay_tree splay_tree_new_with_allocator + PARAMS((splay_tree_compare_fn, + splay_tree_delete_key_fn, + splay_tree_delete_value_fn, + splay_tree_allocate_fn, + splay_tree_deallocate_fn, + void *)); +extern void splay_tree_delete PARAMS((splay_tree)); +extern splay_tree_node splay_tree_insert + PARAMS((splay_tree, + splay_tree_key, + splay_tree_value)); +extern void splay_tree_remove PARAMS((splay_tree, + splay_tree_key)); +extern splay_tree_node splay_tree_lookup + PARAMS((splay_tree, + splay_tree_key)); +extern splay_tree_node splay_tree_predecessor + PARAMS((splay_tree, + splay_tree_key)); +extern splay_tree_node splay_tree_successor + PARAMS((splay_tree, + splay_tree_key)); +extern splay_tree_node splay_tree_max + PARAMS((splay_tree)); +extern splay_tree_node splay_tree_min + PARAMS((splay_tree)); +extern int splay_tree_foreach PARAMS((splay_tree, + splay_tree_foreach_fn, + void*)); +extern int splay_tree_compare_ints PARAMS((splay_tree_key, + splay_tree_key)); +extern int splay_tree_compare_pointers PARAMS((splay_tree_key, + splay_tree_key)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SPLAY_TREE_H */ diff --git a/contrib/gdb/include/symcat.h b/contrib/gdb/include/symcat.h new file mode 100644 index 00000000000..61ce1e9b341 --- /dev/null +++ b/contrib/gdb/include/symcat.h @@ -0,0 +1,49 @@ +/* Symbol concatenation utilities. + + Copyright (C) 1998, 2000 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SYM_CAT_H +#define SYM_CAT_H + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define CONCAT2(a,b) a##b +#define CONCAT3(a,b,c) a##b##c +#define CONCAT4(a,b,c,d) a##b##c##d +#define STRINGX(s) #s +#else +/* Note one should never pass extra whitespace to the CONCATn macros, + e.g. CONCAT2(foo, bar) because traditonal C will keep the space between + the two labels instead of concatenating them. Instead, make sure to + write CONCAT2(foo,bar). */ +#define CONCAT2(a,b) a/**/b +#define CONCAT3(a,b,c) a/**/b/**/c +#define CONCAT4(a,b,c,d) a/**/b/**/c/**/d +#define STRINGX(s) "s" +#endif + +#define XCONCAT2(a,b) CONCAT2(a,b) +#define XCONCAT3(a,b,c) CONCAT3(a,b,c) +#define XCONCAT4(a,b,c,d) CONCAT4(a,b,c,d) + +/* Note the layer of indirection here is typically used to allow + stringification of the expansion of macros. I.e. "#define foo + bar", "XSTRING(foo)", to yield "bar". Be aware that this only + works for __STDC__, not for traditional C which will still resolve + to "foo". */ +#define XSTRING(s) STRINGX(s) + +#endif /* SYM_CAT_H */ diff --git a/contrib/gdb/include/ternary.h b/contrib/gdb/include/ternary.h new file mode 100644 index 00000000000..40d442e6223 --- /dev/null +++ b/contrib/gdb/include/ternary.h @@ -0,0 +1,51 @@ +/* ternary.h - Ternary Search Trees + Copyright 2001 Free Software Foundation, Inc. + + Contributed by Daniel Berlin (dan@cgsoftware.com) + + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ +#ifndef TERNARY_H_ +#define TERNARY_H_ +/* Ternary search trees */ + +typedef struct ternary_node_def *ternary_tree; + +typedef struct ternary_node_def +{ + char splitchar; + ternary_tree lokid; + ternary_tree eqkid; + ternary_tree hikid; +} +ternary_node; + +/* Insert string S into tree P, associating it with DATA. + Return the data in the tree associated with the string if it's + already there, and replace is 0. + Otherwise, replaces if it it exists, inserts if it doesn't, and + returns the data you passed in. */ +PTR ternary_insert PARAMS ((ternary_tree *p, const char *s, + PTR data, int replace)); + +/* Delete the ternary search tree rooted at P. + Does NOT delete the data you associated with the strings. */ +void ternary_cleanup PARAMS ((ternary_tree p)); + +/* Search the ternary tree for string S, returning the data associated + with it if found. */ +PTR ternary_search PARAMS ((const ternary_node *p, const char *s)); +#endif diff --git a/contrib/gdb/include/xregex.h b/contrib/gdb/include/xregex.h new file mode 100644 index 00000000000..645195bbceb --- /dev/null +++ b/contrib/gdb/include/xregex.h @@ -0,0 +1,28 @@ +/* This file redefines all regex external names before including + a renamed copy of glibc's regex.h. */ + +#ifndef _XREGEX_H +#define _XREGEX_H 1 + +# define regfree xregfree +# define regexec xregexec +# define regcomp xregcomp +# define regerror xregerror +# define re_set_registers xre_set_registers +# define re_match_2 xre_match_2 +# define re_match xre_match +# define re_search xre_search +# define re_compile_pattern xre_compile_pattern +# define re_set_syntax xre_set_syntax +# define re_search_2 xre_search_2 +# define re_compile_fastmap xre_compile_fastmap +# define re_syntax_options xre_syntax_options +# define re_max_failures xre_max_failures + +# define _REGEX_RE_COMP +# define re_comp xre_comp +# define re_exec xre_exec + +#include "xregex2.h" + +#endif /* xregex.h */ diff --git a/contrib/gdb/include/xregex2.h b/contrib/gdb/include/xregex2.h new file mode 100644 index 00000000000..2991daf9bcf --- /dev/null +++ b/contrib/gdb/include/xregex2.h @@ -0,0 +1,571 @@ +/* Definitions for data structures and routines for the regular + expression library, version 0.12. + Copyright (C) 1985,1989-1993,1995-1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _REGEX_H +#define _REGEX_H 1 + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX says that must be included (by the caller) before + . */ + +#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS +/* VMS doesn't have `size_t' in , even though POSIX says it + should be there. */ +# include +#endif + +/* The following two types have to be signed and unsigned integer type + wide enough to hold a value of a pointer. For most ANSI compilers + ptrdiff_t and size_t should be likely OK. Still size of these two + types is 2 for Microsoft C. Ugh... */ +typedef long int s_reg_t; +typedef unsigned long int active_reg_t; + +/* The following bits are used to determine the regexp syntax we + recognize. The set/not-set meanings are chosen so that Emacs syntax + remains the value 0. The bits are given in alphabetical order, and + the definitions shifted by one from the previous bit; thus, when we + add or remove a bit, only one other definition need change. */ +typedef unsigned long int reg_syntax_t; + +/* If this bit is not set, then \ inside a bracket expression is literal. + If set, then such a \ quotes the following character. */ +#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) + +/* If this bit is not set, then + and ? are operators, and \+ and \? are + literals. + If set, then \+ and \? are operators and + and ? are literals. */ +#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) + +/* If this bit is set, then character classes are supported. They are: + [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], + [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. + If not set, then character classes are not supported. */ +#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) + +/* If this bit is set, then ^ and $ are always anchors (outside bracket + expressions, of course). + If this bit is not set, then it depends: + ^ is an anchor if it is at the beginning of a regular + expression or after an open-group or an alternation operator; + $ is an anchor if it is at the end of a regular expression, or + before a close-group or an alternation operator. + + This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because + POSIX draft 11.2 says that * etc. in leading positions is undefined. + We already implemented a previous draft which made those constructs + invalid, though, so we haven't changed the code back. */ +#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) + +/* If this bit is set, then special characters are always special + regardless of where they are in the pattern. + If this bit is not set, then special characters are special only in + some contexts; otherwise they are ordinary. Specifically, + * + ? and intervals are only special when not after the beginning, + open-group, or alternation operator. */ +#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) + +/* If this bit is set, then *, +, ?, and { cannot be first in an re or + immediately after an alternation or begin-group operator. */ +#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) + +/* If this bit is set, then . matches newline. + If not set, then it doesn't. */ +#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) + +/* If this bit is set, then . doesn't match NUL. + If not set, then it does. */ +#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) + +/* If this bit is set, nonmatching lists [^...] do not match newline. + If not set, they do. */ +#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) + +/* If this bit is set, either \{...\} or {...} defines an + interval, depending on RE_NO_BK_BRACES. + If not set, \{, \}, {, and } are literals. */ +#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) + +/* If this bit is set, +, ? and | aren't recognized as operators. + If not set, they are. */ +#define RE_LIMITED_OPS (RE_INTERVALS << 1) + +/* If this bit is set, newline is an alternation operator. + If not set, newline is literal. */ +#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) + +/* If this bit is set, then `{...}' defines an interval, and \{ and \} + are literals. + If not set, then `\{...\}' defines an interval. */ +#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) + +/* If this bit is set, (...) defines a group, and \( and \) are literals. + If not set, \(...\) defines a group, and ( and ) are literals. */ +#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) + +/* If this bit is set, then \ matches . + If not set, then \ is a back-reference. */ +#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) + +/* If this bit is set, then | is an alternation operator, and \| is literal. + If not set, then \| is an alternation operator, and | is literal. */ +#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) + +/* If this bit is set, then an ending range point collating higher + than the starting range point, as in [z-a], is invalid. + If not set, then when ending range point collates higher than the + starting range point, the range is ignored. */ +#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) + +/* If this bit is set, then an unmatched ) is ordinary. + If not set, then an unmatched ) is invalid. */ +#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) + +/* If this bit is set, succeed as soon as we match the whole pattern, + without further backtracking. */ +#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) + +/* If this bit is set, do not process the GNU regex operators. + If not set, then the GNU regex operators are recognized. */ +#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) + +/* If this bit is set, turn on internal regex debugging. + If not set, and debugging was on, turn it off. + This only works if regex.c is compiled -DDEBUG. + We define this bit always, so that all that's needed to turn on + debugging is to recompile regex.c; the calling code can always have + this bit set, and it won't affect anything in the normal case. */ +#define RE_DEBUG (RE_NO_GNU_OPS << 1) + +/* If this bit is set, a syntactically invalid interval is treated as + a string of ordinary characters. For example, the ERE 'a{1' is + treated as 'a\{1'. */ +#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) + +/* This global variable defines the particular regexp syntax to use (for + some interfaces). When a regexp is compiled, the syntax used is + stored in the pattern buffer, so changing this does not affect + already-compiled regexps. */ +extern reg_syntax_t re_syntax_options; + +/* Define combinations of the above bits for the standard possibilities. + (The [[[ comments delimit what gets put into the Texinfo file, so + don't delete them!) */ +/* [[[begin syntaxes]]] */ +#define RE_SYNTAX_EMACS 0 + +#define RE_SYNTAX_AWK \ + (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ + | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ + | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) + +#define RE_SYNTAX_GNU_AWK \ + ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ + & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS)) + +#define RE_SYNTAX_POSIX_AWK \ + (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ + | RE_INTERVALS | RE_NO_GNU_OPS) + +#define RE_SYNTAX_GREP \ + (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ + | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ + | RE_NEWLINE_ALT) + +#define RE_SYNTAX_EGREP \ + (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ + | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ + | RE_NO_BK_VBAR) + +#define RE_SYNTAX_POSIX_EGREP \ + (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ + | RE_INVALID_INTERVAL_ORD) + +/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ +#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC + +#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC + +/* Syntax bits common to both basic and extended POSIX regex syntax. */ +#define _RE_SYNTAX_POSIX_COMMON \ + (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ + | RE_INTERVALS | RE_NO_EMPTY_RANGES) + +#define RE_SYNTAX_POSIX_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) + +/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes + RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this + isn't minimal, since other operators, such as \`, aren't disabled. */ +#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) + +#define RE_SYNTAX_POSIX_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ + | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) + +/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is + removed and RE_NO_BK_REFS is added. */ +#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) +/* [[[end syntaxes]]] */ + +/* Maximum number of duplicates an interval can allow. Some systems + (erroneously) define this in other header files, but we want our + value, so remove any previous define. */ +#ifdef RE_DUP_MAX +# undef RE_DUP_MAX +#endif +/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ +#define RE_DUP_MAX (0x7fff) + + +/* POSIX `cflags' bits (i.e., information for `regcomp'). */ + +/* If this bit is set, then use extended regular expression syntax. + If not set, then use basic regular expression syntax. */ +#define REG_EXTENDED 1 + +/* If this bit is set, then ignore case when matching. + If not set, then case is significant. */ +#define REG_ICASE (REG_EXTENDED << 1) + +/* If this bit is set, then anchors do not match at newline + characters in the string. + If not set, then anchors do match at newlines. */ +#define REG_NEWLINE (REG_ICASE << 1) + +/* If this bit is set, then report only success or fail in regexec. + If not set, then returns differ between not matching and errors. */ +#define REG_NOSUB (REG_NEWLINE << 1) + + +/* POSIX `eflags' bits (i.e., information for regexec). */ + +/* If this bit is set, then the beginning-of-line operator doesn't match + the beginning of the string (presumably because it's not the + beginning of a line). + If not set, then the beginning-of-line operator does match the + beginning of the string. */ +#define REG_NOTBOL 1 + +/* Like REG_NOTBOL, except for the end-of-line. */ +#define REG_NOTEOL (1 << 1) + + +/* If any error codes are removed, changed, or added, update the + `re_error_msg' table in regex.c. */ +typedef enum +{ +#ifdef _XOPEN_SOURCE + REG_ENOSYS = -1, /* This will never happen for this implementation. */ +#endif + + REG_NOERROR = 0, /* Success. */ + REG_NOMATCH, /* Didn't find a match (for regexec). */ + + /* POSIX regcomp return error codes. (In the order listed in the + standard.) */ + REG_BADPAT, /* Invalid pattern. */ + REG_ECOLLATE, /* Not implemented. */ + REG_ECTYPE, /* Invalid character class name. */ + REG_EESCAPE, /* Trailing backslash. */ + REG_ESUBREG, /* Invalid back reference. */ + REG_EBRACK, /* Unmatched left bracket. */ + REG_EPAREN, /* Parenthesis imbalance. */ + REG_EBRACE, /* Unmatched \{. */ + REG_BADBR, /* Invalid contents of \{\}. */ + REG_ERANGE, /* Invalid range end. */ + REG_ESPACE, /* Ran out of memory. */ + REG_BADRPT, /* No preceding re for repetition op. */ + + /* Error codes we've added. */ + REG_EEND, /* Premature end. */ + REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ + REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ +} reg_errcode_t; + +/* This data structure represents a compiled pattern. Before calling + the pattern compiler, the fields `buffer', `allocated', `fastmap', + `translate', and `no_sub' can be set. After the pattern has been + compiled, the `re_nsub' field is available. All other fields are + private to the regex routines. */ + +#ifndef RE_TRANSLATE_TYPE +# define RE_TRANSLATE_TYPE char * +#endif + +struct re_pattern_buffer +{ +/* [[[begin pattern_buffer]]] */ + /* Space that holds the compiled pattern. It is declared as + `unsigned char *' because its elements are + sometimes used as array indexes. */ + unsigned char *buffer; + + /* Number of bytes to which `buffer' points. */ + unsigned long int allocated; + + /* Number of bytes actually used in `buffer'. */ + unsigned long int used; + + /* Syntax setting with which the pattern was compiled. */ + reg_syntax_t syntax; + + /* Pointer to a fastmap, if any, otherwise zero. re_search uses + the fastmap, if there is one, to skip over impossible + starting points for matches. */ + char *fastmap; + + /* Either a translate table to apply to all characters before + comparing them, or zero for no translation. The translation + is applied to a pattern when it is compiled and to a string + when it is matched. */ + RE_TRANSLATE_TYPE translate; + + /* Number of subexpressions found by the compiler. */ + size_t re_nsub; + + /* Zero if this pattern cannot match the empty string, one else. + Well, in truth it's used only in `re_search_2', to see + whether or not we should use the fastmap, so we don't set + this absolutely perfectly; see `re_compile_fastmap' (the + `duplicate' case). */ + unsigned can_be_null : 1; + + /* If REGS_UNALLOCATED, allocate space in the `regs' structure + for `max (RE_NREGS, re_nsub + 1)' groups. + If REGS_REALLOCATE, reallocate space if necessary. + If REGS_FIXED, use what's there. */ +#define REGS_UNALLOCATED 0 +#define REGS_REALLOCATE 1 +#define REGS_FIXED 2 + unsigned regs_allocated : 2; + + /* Set to zero when `regex_compile' compiles a pattern; set to one + by `re_compile_fastmap' if it updates the fastmap. */ + unsigned fastmap_accurate : 1; + + /* If set, `re_match_2' does not return information about + subexpressions. */ + unsigned no_sub : 1; + + /* If set, a beginning-of-line anchor doesn't match at the + beginning of the string. */ + unsigned not_bol : 1; + + /* Similarly for an end-of-line anchor. */ + unsigned not_eol : 1; + + /* If true, an anchor at a newline matches. */ + unsigned newline_anchor : 1; + +/* [[[end pattern_buffer]]] */ +}; + +typedef struct re_pattern_buffer regex_t; + +/* Type for byte offsets within the string. POSIX mandates this. */ +typedef int regoff_t; + + +/* This is the structure we store register match data in. See + regex.texinfo for a full description of what registers match. */ +struct re_registers +{ + unsigned num_regs; + regoff_t *start; + regoff_t *end; +}; + + +/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, + `re_match_2' returns information about at least this many registers + the first time a `regs' structure is passed. */ +#ifndef RE_NREGS +# define RE_NREGS 30 +#endif + + +/* POSIX specification for registers. Aside from the different names than + `re_registers', POSIX uses an array of structures, instead of a + structure of arrays. */ +typedef struct +{ + regoff_t rm_so; /* Byte offset from string's start to substring's start. */ + regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ +} regmatch_t; + +/* Declarations for routines. */ + +/* To avoid duplicating every routine declaration -- once with a + prototype (if we are ANSI), and once without (if we aren't) -- we + use the following macro to declare argument types. This + unfortunately clutters up the declarations a bit, but I think it's + worth it. */ + +#if __STDC__ + +# define _RE_ARGS(args) args + +#else /* not __STDC__ */ + +# define _RE_ARGS(args) () + +#endif /* not __STDC__ */ + +/* Sets the current default syntax to SYNTAX, and return the old syntax. + You can also simply assign to the `re_syntax_options' variable. */ +extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); + +/* Compile the regular expression PATTERN, with length LENGTH + and syntax given by the global `re_syntax_options', into the buffer + BUFFER. Return NULL if successful, and an error string if not. */ +extern const char *re_compile_pattern + _RE_ARGS ((const char *pattern, size_t length, + struct re_pattern_buffer *buffer)); + + +/* Compile a fastmap for the compiled pattern in BUFFER; used to + accelerate searches. Return 0 if successful and -2 if was an + internal error. */ +extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); + + +/* Search in the string STRING (with length LENGTH) for the pattern + compiled into BUFFER. Start searching at position START, for RANGE + characters. Return the starting position of the match, -1 for no + match, or -2 for an internal error. Also return register + information in REGS (if REGS and BUFFER->no_sub are nonzero). */ +extern int re_search + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, int range, struct re_registers *regs)); + + +/* Like `re_search', but search in the concatenation of STRING1 and + STRING2. Also, stop searching at index START + STOP. */ +extern int re_search_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, int range, struct re_registers *regs, int stop)); + + +/* Like `re_search', but return how many characters in STRING the regexp + in BUFFER matched, starting at position START. */ +extern int re_match + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, struct re_registers *regs)); + + +/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ +extern int re_match_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, struct re_registers *regs, int stop)); + + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using BUFFER and REGS will use this memory + for recording register information. STARTS and ENDS must be + allocated with malloc, and must each be at least `NUM_REGS * sizeof + (regoff_t)' bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ +extern void re_set_registers + _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, + unsigned num_regs, regoff_t *starts, regoff_t *ends)); + +#if defined _REGEX_RE_COMP || defined _LIBC +# ifndef _CRAY +/* 4.2 bsd compatibility. */ +extern char *re_comp _RE_ARGS ((const char *)); +extern int re_exec _RE_ARGS ((const char *)); +# endif +#endif + +/* GCC 2.95 and later have "__restrict"; C99 compilers have + "restrict", and "configure" may have defined "restrict". */ +#ifndef __restrict +# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) +# if defined restrict || 199901L <= __STDC_VERSION__ +# define __restrict restrict +# else +# define __restrict +# endif +# endif +#endif + +/* GCC 3.1 and later support declaring arrays as non-overlapping + using the syntax array_name[restrict] */ +#ifndef __restrict_arr +# if ! (3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) || defined (__GNUG__) +# define __restrict_arr +# else +# define __restrict_arr __restrict +# endif +#endif + +/* POSIX compatibility. */ +extern int regcomp _RE_ARGS ((regex_t *__restrict __preg, + const char *__restrict __pattern, + int __cflags)); + +extern int regexec _RE_ARGS ((const regex_t *__restrict __preg, + const char *__restrict __string, size_t __nmatch, + regmatch_t __pmatch[__restrict_arr], + int __eflags)); + +extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, + char *__errbuf, size_t __errbuf_size)); + +extern void regfree _RE_ARGS ((regex_t *__preg)); + + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* regex.h */ + +/* +Local variables: +make-backup-files: t +version-control: t +trim-versions-without-asking: nil +End: +*/ diff --git a/contrib/gdb/include/xtensa-isa-internal.h b/contrib/gdb/include/xtensa-isa-internal.h new file mode 100644 index 00000000000..7f221eae48e --- /dev/null +++ b/contrib/gdb/include/xtensa-isa-internal.h @@ -0,0 +1,114 @@ +/* Internal definitions for configurable Xtensa ISA support. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Use the statically-linked version for the GNU tools. */ +#define STATIC_LIBISA 1 + +#define ISA_INTERFACE_VERSION 3 + +struct config_struct +{ + char *param_name; + char *param_value; +}; + +/* Encode/decode function types for immediate operands. */ +typedef uint32 (*xtensa_immed_decode_fn) (uint32); +typedef xtensa_encode_result (*xtensa_immed_encode_fn) (uint32 *); + +/* Field accessor function types. */ +typedef uint32 (*xtensa_get_field_fn) (const xtensa_insnbuf); +typedef void (*xtensa_set_field_fn) (xtensa_insnbuf, uint32); + +/* PC-relative relocation function types. */ +typedef uint32 (*xtensa_do_reloc_fn) (uint32, uint32); +typedef uint32 (*xtensa_undo_reloc_fn) (uint32, uint32); + +/* Instruction decode function type. */ +typedef int (*xtensa_insn_decode_fn) (const xtensa_insnbuf); + +/* Instruction encoding template function type (each of these functions + returns a constant template; they exist only to make it easier for the + TIE compiler to generate endian-independent DLLs). */ +typedef xtensa_insnbuf (*xtensa_encoding_template_fn) (void); + + +typedef struct xtensa_operand_internal_struct +{ + char *operand_kind; /* e.g., "a", "f", "i", "l".... */ + char inout; /* '<', '>', or '='. */ + char isPCRelative; /* Is this a PC-relative offset? */ + xtensa_get_field_fn get_field; /* Get encoded value of the field. */ + xtensa_set_field_fn set_field; /* Set field with an encoded value. */ + xtensa_immed_encode_fn encode; /* Encode the operand value. */ + xtensa_immed_decode_fn decode; /* Decode the value from the field. */ + xtensa_do_reloc_fn do_reloc; /* Perform a PC-relative relocation. */ + xtensa_undo_reloc_fn undo_reloc; /* Undo a PC-relative relocation. */ +} xtensa_operand_internal; + + +typedef struct xtensa_iclass_internal_struct +{ + int num_operands; /* Size of "operands" array. */ + xtensa_operand_internal **operands; /* Array of operand structures. */ +} xtensa_iclass_internal; + + +typedef struct xtensa_opcode_internal_struct +{ + const char *name; /* Opcode mnemonic. */ + int length; /* Length in bytes of the insn. */ + xtensa_encoding_template_fn template; /* Fn returning encoding template. */ + xtensa_iclass_internal *iclass; /* Iclass for this opcode. */ +} xtensa_opcode_internal; + + +typedef struct opname_lookup_entry_struct +{ + const char *key; /* Opcode mnemonic. */ + xtensa_opcode opcode; /* Internal opcode number. */ +} opname_lookup_entry; + + +typedef struct xtensa_isa_internal_struct +{ + int is_big_endian; /* Endianness. */ + int insn_size; /* Maximum length in bytes. */ + int insnbuf_size; /* Number of insnbuf_words. */ + int num_opcodes; /* Total number for all modules. */ + xtensa_opcode_internal **opcode_table;/* Indexed by internal opcode #. */ + int num_modules; /* Number of modules (DLLs) loaded. */ + int *module_opcode_base; /* Starting opcode # for each module. */ + xtensa_insn_decode_fn *module_decode_fn; /* Decode fn for each module. */ + opname_lookup_entry *opname_lookup_table; /* Lookup table for each module. */ + struct config_struct *config; /* Table of configuration parameters. */ + int has_density; /* Is density option available? */ +} xtensa_isa_internal; + + +typedef struct xtensa_isa_module_struct +{ + int (*get_num_opcodes_fn) (void); + xtensa_opcode_internal **(*get_opcodes_fn) (void); + int (*decode_insn_fn) (const xtensa_insnbuf); + struct config_struct *(*get_config_table_fn) (void); +} xtensa_isa_module; + +extern xtensa_isa_module xtensa_isa_modules[]; + diff --git a/contrib/gdb/include/xtensa-isa.h b/contrib/gdb/include/xtensa-isa.h new file mode 100644 index 00000000000..54f750c9a1a --- /dev/null +++ b/contrib/gdb/include/xtensa-isa.h @@ -0,0 +1,230 @@ +/* Interface definition for configurable Xtensa ISA support. + Copyright 2003 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef XTENSA_LIBISA_H +#define XTENSA_LIBISA_H + +/* Use the statically-linked version for the GNU tools. */ +#define STATIC_LIBISA 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef uint32 +#define uint32 unsigned int +#endif + +/* This file defines the interface to the Xtensa ISA library. This library + contains most of the ISA-specific information for a particular Xtensa + processor. For example, the set of valid instructions, their opcode + encodings and operand fields are all included here. To support Xtensa's + configurability and user-defined instruction extensions (i.e., TIE), the + library is initialized by loading one or more dynamic libraries; only a + small set of interface code is present in the statically-linked portion + of the library. + + This interface basically defines four abstract data types. + + . an instruction buffer - for holding the raw instruction bits + . ISA info - information about the ISA as a whole + . opcode info - information about individual instructions + . operand info - information about specific instruction operands + + It would be nice to implement these as classes in C++, but the library is + implemented in C to match the expectations of the GNU tools. + Instead, the interface defines a set of functions to access each data + type. With the exception of the instruction buffer, the internal + representations of the data structures are hidden. All accesses must be + made through the functions defined here. */ + +typedef void* xtensa_isa; +typedef void* xtensa_operand; + + +/* Opcodes are represented here using sequential integers beginning with 0. + The specific value used for a particular opcode is only fixed for a + particular instantiation of an xtensa_isa structure, so these values + should only be used internally. */ +typedef int xtensa_opcode; + +/* Define a unique value for undefined opcodes ("static const int" doesn't + seem to work for this because EGCS 1.0.3 on i686-Linux without -O won't + allow it to be used as an initializer). */ +#define XTENSA_UNDEFINED -1 + + +typedef int libisa_module_specifier; + +extern xtensa_isa xtensa_isa_init (void); + + +/* Instruction buffers. */ + +typedef uint32 xtensa_insnbuf_word; +typedef xtensa_insnbuf_word *xtensa_insnbuf; + +/* Get the size in words of the xtensa_insnbuf array. */ +extern int xtensa_insnbuf_size (xtensa_isa); + +/* Allocate (with malloc) an xtensa_insnbuf of the right size. */ +extern xtensa_insnbuf xtensa_insnbuf_alloc (xtensa_isa); + +/* Release (with free) an xtensa_insnbuf of the right size. */ +extern void xtensa_insnbuf_free (xtensa_insnbuf); + +/* Inward and outward conversion from memory images (byte streams) to our + internal instruction representation. */ +extern void xtensa_insnbuf_to_chars (xtensa_isa, const xtensa_insnbuf, + char *); + +extern void xtensa_insnbuf_from_chars (xtensa_isa, xtensa_insnbuf, + const char *); + + +/* ISA information. */ + +/* Load the ISA information from a shared library. If successful, this returns + a value which identifies the ISA for use in subsequent calls to the ISA + library; otherwise, it returns NULL. Multiple ISAs can be loaded to support + heterogeneous multiprocessor systems. */ +extern xtensa_isa xtensa_load_isa (libisa_module_specifier); + +/* Extend an existing set of ISA information by loading an additional shared + library of ISA information. This is primarily intended for loading TIE + extensions. If successful, the return value is non-zero. */ +extern int xtensa_extend_isa (xtensa_isa, libisa_module_specifier); + +/* The default ISA. This variable is set automatically to the ISA most + recently loaded and is provided as a convenience. An exception is the GNU + opcodes library, where there is a fixed interface that does not allow + passing the ISA as a parameter and the ISA must be taken from this global + variable. (Note: Since this variable is just a convenience, it is not + exported when libisa is built as a DLL, due to the hassle of dealing with + declspecs.) */ +extern xtensa_isa xtensa_default_isa; + + +/* Deallocate an xtensa_isa structure. */ +extern void xtensa_isa_free (xtensa_isa); + +/* Get the maximum instruction size in bytes. */ +extern int xtensa_insn_maxlength (xtensa_isa); + +/* Get the total number of opcodes for this processor. */ +extern int xtensa_num_opcodes (xtensa_isa); + +/* Translate a mnemonic name to an opcode. Returns XTENSA_UNDEFINED if + the name is not a valid opcode mnemonic. */ +extern xtensa_opcode xtensa_opcode_lookup (xtensa_isa, const char *); + +/* Decode a binary instruction buffer. Returns the opcode or + XTENSA_UNDEFINED if the instruction is illegal. */ +extern xtensa_opcode xtensa_decode_insn (xtensa_isa, const xtensa_insnbuf); + + +/* Opcode information. */ + +/* Set the opcode field(s) in a binary instruction buffer. The operand + fields are set to zero. */ +extern void xtensa_encode_insn (xtensa_isa, xtensa_opcode, xtensa_insnbuf); + +/* Get the mnemonic name for an opcode. */ +extern const char * xtensa_opcode_name (xtensa_isa, xtensa_opcode); + +/* Find the length (in bytes) of an instruction. */ +extern int xtensa_insn_length (xtensa_isa, xtensa_opcode); + +/* Find the length of an instruction by looking only at the first byte. */ +extern int xtensa_insn_length_from_first_byte (xtensa_isa, char); + +/* Find the number of operands for an instruction. */ +extern int xtensa_num_operands (xtensa_isa, xtensa_opcode); + +/* Get the information about operand number "opnd" of a particular opcode. */ +extern xtensa_operand xtensa_get_operand (xtensa_isa, xtensa_opcode, int); + +/* Operand information. */ + +/* Find the kind of operand. There are three possibilities: + 1) PC-relative immediates (e.g., "l", "L"). These can be identified with + the xtensa_operand_isPCRelative function. + 2) non-PC-relative immediates ("i"). + 3) register-file short names (e.g., "a", "b", "m" and others defined + via TIE). */ +extern char * xtensa_operand_kind (xtensa_operand); + +/* Check if an operand is an input ('<'), output ('>'), or inout ('=') + operand. Note: The output operand of a conditional assignment + (e.g., movnez) appears here as an inout ('=') even if it is declared + in the TIE code as an output ('>'); this allows the compiler to + properly handle register allocation for conditional assignments. */ +extern char xtensa_operand_inout (xtensa_operand); + +/* Get and set the raw (encoded) value of the field for the specified + operand. The "set" function does not check if the value fits in the + field; that is done by the "encode" function below. */ +extern uint32 xtensa_operand_get_field (xtensa_operand, const xtensa_insnbuf); + +extern void xtensa_operand_set_field (xtensa_operand, xtensa_insnbuf, uint32); + + +/* Encode and decode operands. The raw bits in the operand field + may be encoded in a variety of different ways. These functions hide the + details of that encoding. The encode function has a special return type + (xtensa_encode_result) to indicate success or the reason for failure; the + encoded value is returned through the argument pointer. The decode function + has no possibility of failure and returns the decoded value. */ + +typedef enum +{ + xtensa_encode_result_ok, + xtensa_encode_result_align, + xtensa_encode_result_not_in_table, + xtensa_encode_result_too_low, + xtensa_encode_result_too_high, + xtensa_encode_result_not_ok, + xtensa_encode_result_max = xtensa_encode_result_not_ok +} xtensa_encode_result; + +extern xtensa_encode_result xtensa_operand_encode (xtensa_operand, uint32 *); + +extern uint32 xtensa_operand_decode (xtensa_operand, uint32); + + +/* For PC-relative offset operands, the interpretation of the offset may vary + between opcodes, e.g., is it relative to the current PC or that of the next + instruction? The following functions are defined to perform PC-relative + relocations and to undo them (as in the disassembler). The first function + takes the desired address and the PC of the current instruction and returns + the unencoded value to be stored in the offset field. The second function + takes the unencoded offset value and the current PC and returns the address. + Note that these functions do not replace the encode/decode functions; the + operands must be encoded/decoded separately. */ + +extern int xtensa_operand_isPCRelative (xtensa_operand); + +extern uint32 xtensa_operand_do_reloc (xtensa_operand, uint32, uint32); + +extern uint32 xtensa_operand_undo_reloc (xtensa_operand, uint32, uint32); + +#ifdef __cplusplus +} +#endif +#endif /* XTENSA_LIBISA_H */ diff --git a/contrib/gdb/install-sh b/contrib/gdb/install-sh new file mode 100755 index 00000000000..77bc38144f2 --- /dev/null +++ b/contrib/gdb/install-sh @@ -0,0 +1,316 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2004-02-15.20 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename= +transform_arg= +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= + +usage="Usage: $0 [OPTION]... SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 -d DIRECTORIES... + +In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. +In the second, create the directory path DIR. + +Options: +-b=TRANSFORMBASENAME +-c copy source (using $cpprog) instead of moving (using $mvprog). +-d create directories instead of installing files. +-g GROUP $chgrp installed files to GROUP. +-m MODE $chmod installed files to MODE. +-o USER $chown installed files to USER. +-s strip installed files (using $stripprog). +-t=TRANSFORM +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit 0;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + --version) echo "$0 $scriptversion"; exit 0;; + + *) # When -d is used, all remaining arguments are directories to create. + test -n "$dir_arg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + instcmd=: + chmodcmd= + else + instcmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$instcmd $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" || lasterr=$? + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; } + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $instcmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + # If we're going to rename the final executable, determine the name now. + if test -z "$transformarg"; then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename \ + | sed $transformarg`$transformbasename + fi + + # don't allow the sed command to completely eliminate the filename. + test -z "$dstfile" && dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Move or copy the file name to the temp name + $doit $instcmd "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $instcmd $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now remove or move aside any old file at destination location. We + # try this two ways since rm can't unlink itself on some systems and + # the destination file might be busy for other reasons. In this case, + # the final cleanup might fail but the new file should still install + # successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + fi || { (exit 1); exit; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/contrib/gdb/libtool.m4 b/contrib/gdb/libtool.m4 new file mode 100644 index 00000000000..d2e36088dee --- /dev/null +++ b/contrib/gdb/libtool.m4 @@ -0,0 +1,893 @@ +## libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 46 AC_PROG_LIBTOOL +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])])])])])]) + +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +AC_ARG_WITH(pic, + [ --with-pic try to use only PIC/non-PIC objects [default=use both]], + pic_mode="$withval", pic_mode=default) +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + re_direlt=['/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'] + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method=['file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method=["file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"] + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | mips* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] + else + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'] + fi + ;; + +newsos6) + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +[sysv5uw[78]* | sysv4*uw2*)] + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'] + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and INCLTDL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and INCLTDL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +# If this macro is not defined by Autoconf, define it here. +ifdef([AC_PROVIDE_IFELSE], + [], + [define([AC_PROVIDE_IFELSE], + [ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + +# AC_LIBTOOL_CXX - enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_AC_LIBTOOL_CXX])]) + +AC_DEFUN([_AC_LIBTOOL_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=CXX $ac_aux_dir/ltcf-cxx.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +# AC_LIBTOOL_GCJ - enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ],[AC_REQUIRE([_AC_LIBTOOL_GCJ])]) + +AC_DEFUN([_AC_LIBTOOL_GCJ], +[AC_REQUIRE([AC_PROG_LIBTOOL]) +AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-gcj.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$GCJ" CFLAGS="$GCJFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=GCJ $ac_aux_dir/ltcf-gcj.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +dnl old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) diff --git a/contrib/gdb/ltcf-c.sh b/contrib/gdb/ltcf-c.sh new file mode 100644 index 00000000000..d60a3baa19b --- /dev/null +++ b/contrib/gdb/ltcf-c.sh @@ -0,0 +1,824 @@ +#### This script is meant to be sourced by ltconfig. + +# ltcf-c.sh - Create a C compiler specific configuration +# +# Copyright (C) 1996-2000, 2001 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='main(){return(0);}' + +## Linker Characteristics +case $host_os in +cygwin* | mingw*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$with_gcc" != yes; then + with_gnu_ld=no + fi + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //; p; }" -e d < $0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$BUILD_CC" != "x" ; then $BUILD_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + darwin* | rhapsody*) + allow_undefined_flag='-undefined suppress' + archive_cmds='$CC `test .$module = .yes && echo -bundle || echo -dynamiclib` $allow_undefined_flag -o $lib $libobjs $deplibs $linkopts -install_name $rpath/$soname `test -n "$verstring" -a x$verstring != x0.0 && echo $verstring`' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$with_gcc" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + if test "$with_gcc" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + if test $with_gnu_ld = no; then + exp_sym_flag='-Bexport' + no_entry_flag="" + fi + else + # Test if we are trying to use run time linking, or normal AIX style linking. + # If -brtl is somewhere in LDFLAGS, we need to do run time linking. + aix_use_runtimelinking=no + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl" ); then + aix_use_runtimelinking=yes + break + fi + done + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other run time loading flags (-brtl), -berok will + # link without error, but may produce a broken library. + allow_undefined_flag=' ${wl}-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + if test "$host_cpu" = ia64; then + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + fi + else + allow_undefined_flag=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols=yes + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec=' ' + build_libtool_need_lc=yes + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + # This is similar to how AIX traditionally builds it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case "$host_cpu" in + ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' ;; + *) + if test $with_gcc = yes; then + case "$host_os" in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; + esac + else + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + ;; + esac + export_dynamic_flag_spec='${wl}-E' + hardcode_direct=yes + ;; + + irix5* | irix6*) + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # cc supports -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi + +## Compiler Characteristics: PIC flags, static flags, etc +if test "X${ac_cv_prog_cc_pic+set}" = Xset; then + : +else + ac_cv_prog_cc_pic= + ac_cv_prog_cc_shlib= + ac_cv_prog_cc_wl= + ac_cv_prog_cc_static= + ac_cv_prog_cc_no_builtin= + ac_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$with_gcc" = yes; then + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + ac_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + cygwin* | mingw* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + ac_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + ac_cv_prog_cc_pic= + ;; + sysv4*MP*) + if test -d /usr/nec; then + ac_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + ac_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix*) + # All AIX code is PIC. + ac_cv_prog_cc_static="$ac_cv_prog_cc_static ${ac_cv_prog_cc_wl}-lC" + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better ac_cv_prog_cc_static that works with the bundled CC? + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + ac_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6*) + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + ac_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + ac_cv_prog_cc_pic='-KPIC' + ac_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + ac_cv_prog_cc_pic='-Kpic' + ac_cv_prog_cc_static='-dn' + ac_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + ac_cv_prog_cc_pic='-KPIC' + ac_cv_prog_cc_static='-Bstatic' + ac_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + ac_cv_prog_cc_pic='-PIC' + ac_cv_prog_cc_static='-Bstatic' + ac_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + ac_cv_prog_cc_pic='-KPIC' + ac_cv_prog_cc_static='-Bstatic' + ac_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + ac_cv_prog_cc_pic='-pic' + ac_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + ac_cv_prog_cc_pic='-Kconform_pic' + ac_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + ac_cv_prog_cc_can_build_shared=no + ;; + esac + fi + case "$host_os" in + # Platforms which do not suport PIC and -DPIC is meaningless + # on them: + *djgpp*) + ac_cv_prog_cc_pic= + ;; + *) + ac_cv_prog_cc_pic="$ac_cv_prog_cc_pic -DPIC" + ;; + esac +fi + +need_lc=yes +if test "$enable_shared" = yes && test "$with_gcc" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo $ac_n "checking whether -lc should be explicitly linked in... $ac_c" 1>&6 + if eval "test \"`echo '$''{'ac_cv_archive_cmds_needs_lc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + need_lc=$ac_cv_archive_cmds_needs_lc + else + $rm conftest* + echo "static int dummy;" > conftest.$ac_ext + if { (eval echo ltcf-c.sh:need_lc: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + soname=conftest + lib=conftest + libobjs=conftest.$objext + deplibs= + wl=$ac_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo ltcf-c.sh:need_lc: \"$archive_cmds\") 1>&5; (eval $archive_cmds) 2>&1 | grep " -lc " 1>&5 ; }; then + need_lc=no + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + fi + $rm conftest* + echo "$ac_t$need_lc" 1>&6 + ;; + esac +fi +ac_cv_archive_cmds_needs_lc=$need_lc diff --git a/contrib/gdb/ltcf-cxx.sh b/contrib/gdb/ltcf-cxx.sh new file mode 100644 index 00000000000..9059b1a002f --- /dev/null +++ b/contrib/gdb/ltcf-cxx.sh @@ -0,0 +1,1021 @@ +#### This script is meant to be sourced by ltconfig. + +# ltcf-cxx.sh - Create a C++ compiler specific configuration +# +# Copyright (C) 1996-1999, 2000, 2001, 2003 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# Original C++ support by:Gary V. Vaughan +# Alexandre Oliva +# Ossama Othman +# Thomas Thanner +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Source file extension for C++ test sources. +ac_ext=cc + +# Object file extension for compiled C++ test sources. +objext=o + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return (0); }' + +# C++ compiler +CXX=${CXX-c++} + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +CC=${CC-"$CXX"} +CFLAGS=${CFLAGS-"$CXXFLAGS"} + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler=$2 +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# Check if we are using GNU gcc (taken/adapted from configure script) +# We need to check here since "--with-gcc" is set at configure time, +# not ltconfig time! +cat > conftest.$ac_ext <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + with_gcc=yes + + # Set up default GNU C++ configuration + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. The + # assumption here is that the linker is going to be the same as that + # used by the C compiler. For the purposes of GCC, this is ok, but + # if someone uses g++ along with a non-GNU C compiler that doesn't + # use GNU ld, we may lose. This is ok for the toolchain tree, since + # the only users of ltcf-cxx.sh are libstdc++-v3 and libjava, + # anyway, and those use both gcc and g++, so the settings are bound + # to be the same. + + if test "$with_gnu_ld" = yes; then + archive_cmds='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + else + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep "\-L"' + +else + with_gcc=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + aix4* | aix5*) + archive_cmds='' + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + if test "$with_gcc" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + if test $with_gnu_ld = no; then + exp_sym_flag='-Bexport' + no_entry_flag="" + fi + else + # Test if we are trying to use run time linking, or normal AIX style linking. + # If -brtl is somewhere in LDFLAGS, we need to do run time linking. + aix_use_runtimelinking=no + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl" ); then + aix_use_runtimelinking=yes + break + fi + done + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + allow_undefined_flag=' -Wl,-G' + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}-brtl \${wl}$exp_sym_flag:\$export_symbols" + else + if test "$host_cpu" = ia64; then + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + fi + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, -berok will + # link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bnoerok' + allow_undefined_flag=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols=yes + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec=' ' + build_libtool_need_lc=yes + # This is similar to how AIX traditionally builds it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + ghcx) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + ld_shlibs=no + ;; + freebsd*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs=yes + ;; + gnu*) + ;; + hpux*) + if test $with_gnu_ld = no; then + case "$host_cpu" in + ia64*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no ;; + *) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ;; + esac + hardcode_direct=yes + hardcode_libdir_separator=: + export_dynamic_flag_spec='${wl}-E' + fi + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + aCC) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test $with_gcc = yes; then + if test $with_gnu_ld = no; then + case "$host_os" in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) + case "$host_cpu" in + ia64*) + archive_cmds='$LD -b +h $soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ;; + *) + archive_cmds='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; + esac + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs=no + fi + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC) + # SGI C++ + archive_cmds='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$with_gcc" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -o $lib' + fi + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + esac + ;; + linux*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest.so 2>&1 | egrep "ld"`; rm -f libconftest.so; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + hardcode_libdir_flag_spec='${wl}--rpath,$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds='$CC -Bstatic -o $oldlib $oldobjs' + ;; + cxx) + # Compaq C++ + archive_cmds='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='-rpath $libdir' + hardcode_libdir_separator=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | sed "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + mvs*) + case $cc_basename in + cxx) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + esac + ;; + netbsd*) + # NetBSD uses g++ - do we need to do anything? + ;; + osf3*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + hardcode_libdir_separator=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + cxx) + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | sed "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$with_gcc" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep "\-L"' + else + # FIXME: insert proper C++ library support + ld_shlibs=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds='templib=`echo $lib | sed -e "s/\.so\..*/\.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + hardcode_libdir_separator=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + old_archive_cmds='$CC -o $oldlib $oldobjs' + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + cxx) + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $rm $lib.exp' + + hardcode_libdir_flag_spec='-rpath $libdir' + hardcode_libdir_separator=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | sed "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$with_gcc" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep "\-L"' + else + # FIXME: insert proper C++ library support + ld_shlibs=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + sco*) + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + lcc) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + no_undefined_flag=' -zdefs' + archive_cmds='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + link_all_deplibs=yes + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | egrep "\-R|\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds='$CC -xar -o $oldlib $oldobjs' + ;; + gcx) + # Green Hills C++ Compiler + archive_cmds='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$with_gcc" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag=' ${wl}-z ${wl}defs' + if $CC --version | egrep -v '^2\.7' > /dev/null; then + archive_cmds='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | egrep \"\-L\"" + fi + + hardcode_libdir_flag_spec='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + esac + ;; + unixware*) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs=no + ;; +esac + + +## Compiler Characteristics: PIC flags, static flags, etc + +# We don't use cached values here since only the C compiler +# characteristics should be cached. +ac_cv_prog_cc_pic= +ac_cv_prog_cc_shlib= +ac_cv_prog_cc_wl= +ac_cv_prog_cc_static= +ac_cv_prog_cc_no_builtin= +ac_cv_prog_cc_can_build_shared=$can_build_shared + +ac_cv_prog_cc_pic_works= +ac_cv_prog_cc_static_works= + +if test "$with_gcc" = yes; then + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + ac_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + cygwin* | mingw* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + ac_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + ac_cv_prog_cc_pic= + ;; + sysv4*MP*) + if test -d /usr/nec; then + ac_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + ac_cv_prog_cc_pic='-fPIC' + ;; + esac +else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68) + # Green Hills C++ Compiler + # ac_cv_prog_cc_static="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + ac_cv_prog_cc_pic='-KPIC' + ;; + ghcx) + # Green Hills C++ Compiler + ac_cv_prog_cc_pic='-pic' + ;; + *) + ;; + esac + ;; + freebsd*) + # FreeBSD uses GNU C++ + ;; + gnu*) + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC) + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + ac_cv_prog_cc_pic='+Z' + ;; + aCC) + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + ac_cv_prog_cc_pic='+Z' + ;; + *) + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC) + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static='-non_shared' + ac_cv_prog_cc_pic='-KPIC' + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC) + # KAI C++ Compiler + ac_cv_prog_cc_wl='--backend -Wl,' + ac_cv_prog_cc_pic='-fPIC' + ;; + cxx) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + ac_cv_prog_cc_pic= + ac_cv_prog_cc_static='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx) + ac_cv_prog_cc_pic='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC) + ac_cv_prog_cc_wl='--backend -Wl,' + ;; + RCC) + # Rational C++ 2.4.1 + ac_cv_prog_cc_pic='-pic' + ;; + cxx) + # Digital/Compaq C++ + ac_cv_prog_cc_wl='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + ac_cv_prog_cc_pic= + ac_cv_prog_cc_static='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + sco*) + case $cc_basename in + CC) + ac_cv_prog_cc_pic='-fPIC' + ;; + *) + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + ac_cv_prog_cc_pic='-KPIC' + ac_cv_prog_cc_static='-Bstatic' + ac_cv_prog_cc_wl='-Qoption ld ' + ;; + gcx) + # Green Hills C++ Compiler + ac_cv_prog_cc_pic='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + ac_cv_prog_cc_pic='-pic' + ac_cv_prog_cc_static='-Bstatic' + ;; + lcc) + # Lucid + ac_cv_prog_cc_pic='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + ac_cv_prog_cc_pic='-KPIC' + ;; + *) + ;; + esac + ;; + unixware*) + ;; + vxworks*) + ;; + *) + ac_cv_prog_cc_can_build_shared=no + ;; + esac +fi + +case "$host_os" in + # Platforms which do not suport PIC and -DPIC is meaningless + # on them: + *djgpp*) + ac_cv_prog_cc_pic= + ;; + *) + ac_cv_prog_cc_pic="$ac_cv_prog_cc_pic -DPIC" + ;; +esac + + +# Figure out "hidden" C++ library dependencies from verbose +# compiler output whening linking a shared library. +cat > conftest.$ac_ext <&5; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval $output_verbose_link_cmd`; do + + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path"; then + compiler_lib_search_path="${prev}${p}" + else + compiler_lib_search_path="${compiler_lib_search_path} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps"; then + postdeps="${prev}${p}" + else + postdeps="${postdeps} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects"; then + predep_objects="$p" + else + predep_objects="$predep_objects $p" + fi + else + if test -z "$postdep_objects"; then + postdep_objects="$p" + else + postdep_objects="$postdep_objects $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out +else + echo "ltcf-cxx.sh: error: problem compiling test program" +fi + +$rm -f confest.$objext + +case " $postdeps " in +*" -lc "*) need_lc=no ;; +*) need_lc=yes ;; +esac diff --git a/contrib/gdb/ltcf-gcj.sh b/contrib/gdb/ltcf-gcj.sh new file mode 100644 index 00000000000..2d704975c86 --- /dev/null +++ b/contrib/gdb/ltcf-gcj.sh @@ -0,0 +1,651 @@ +#### This script is meant to be sourced by ltconfig. + +# ltcf-gcj.sh - Create a GCJ compiler specific configuration +# +# Copyright (C) 1996-1999, 2000, 2001, 2003 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# Original GCJ support by: +# Alexandre Oliva +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }' + +## Linker Characteristics +case $host_os in +cygwin* | mingw*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$with_gcc" != yes; then + with_gnu_ld=no + fi + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //; p; }" -e d < $0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$BUILD_CC" != "x" ; then $BUILD_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$with_gcc" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + if test "$with_gcc" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + if test $with_gnu_ld = no; then + exp_sym_flag='-Bexport' + no_entry_flag="" + fi + else + # Test if we are trying to use run time linking, or normal AIX style linking. + # If -brtl is somewhere in LDFLAGS, we need to do run time linking. + aix_use_runtimelinking=no + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl" ); then + aix_use_runtimelinking=yes + break + fi + done + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other run time loading flags (-brtl), -berok will + # link without error, but may produce a broken library. + allow_undefined_flag=' ${wl}-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + if test "$host_cpu" = ia64; then + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + fi + else + allow_undefined_flag=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols=yes + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec=' ' + build_libtool_need_lc=yes + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + # This is similar to how AIX traditionally builds it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -nodefaultlibs -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='${wl}-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' ${wl}-z ${wl}defs' + archive_cmds='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmds="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | egrep \"\-L\"" + + hardcode_libdir_flag_spec='${wl}-R $wl$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi + +## Compiler Characteristics: PIC flags, static flags, etc + +# We don't use cached values here since only the C compiler +# characteristics should be cached. + ac_cv_prog_cc_pic= + ac_cv_prog_cc_shlib= + ac_cv_prog_cc_wl= + ac_cv_prog_cc_static= + ac_cv_prog_cc_no_builtin= + ac_cv_prog_cc_can_build_shared=$can_build_shared + + ac_cv_prog_cc_wl='-Wl,' + ac_cv_prog_cc_static='-static' + + case $host_os in + beos* | irix5* | irix6* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # we not sure about C++ programs. + ac_cv_prog_cc_static="$ac_cv_prog_cc_static ${ac_cv_prog_cc_wl}-lC" + ;; + *djgpp*) + # DJGPP does not suppot shared libraries at all + ac_cv_prog_cc_pic= + ;; + cygwin* | mingw* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + ac_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + ac_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + sysv4*MP*) + if test -d /usr/nec; then + ac_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + ac_cv_prog_cc_pic='-fPIC' + ;; + esac + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +need_lc=no + +# All existing releases of GCJ support `-c -o'. +lt_cv_compiler_c_o=yes diff --git a/contrib/gdb/ltconfig b/contrib/gdb/ltconfig new file mode 100755 index 00000000000..0a8c7d2f4c4 --- /dev/null +++ b/contrib/gdb/ltconfig @@ -0,0 +1,2833 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A lot of this script is taken from autoconf-2.10. + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} +echo=echo +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec "$SHELL" "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null`} + case X$UNAME in + *-DOS) PATH_SEPARATOR=';' ;; + *) PATH_SEPARATOR=':' ;; + esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running ltconfig again with it. + ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + + export echo_test_string + exec "${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}}" "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# The name of this program. +progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` + +# Constants: +PROGRAM=ltconfig +PACKAGE=libtool +VERSION=1.4a-GCC3.0 +TIMESTAMP=" (1.641.2.256 2001/05/28 20:09:07 with GCC-local changes)" +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +rm="rm -f" + +help="Try \`$progname --help' for more information." + +# Global variables: +default_ofile=libtool +can_build_shared=yes +enable_shared=yes +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +enable_static=yes +enable_fast_install=yes +enable_dlopen=unknown +enable_win32_dll=no +pic_mode=default +ltmain= +silent= +srcdir= +ac_config_guess= +ac_config_sub= +host= +build=NONE +nonopt=NONE +ofile="$default_ofile" +verify_host=yes +tagname= +with_gcc=no +with_gnu_ld=no +need_locks=yes +ac_ext=c +libext=a +cache_file= +max_cmd_len= + +## Dependencies to place before and after the object being linked: +predep_objects= +postdep_objects= +predeps= +postdeps= +compiler_lib_search_path= + +## Link characteristics: +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +striplib= +old_striplib= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +## Tools: +old_AR="$AR" +old_AR_FLAGS="$AR_FLAGS" +old_CC="$CC" +old_CFLAGS="$CFLAGS" +old_CPPFLAGS="$CPPFLAGS" +old_LDFLAGS="$LDFLAGS" +old_LIBS="$LIBS" +old_MAGIC_CMD="$MAGIC_CMD" +old_LD="$LD" +old_LN_S="$LN_S" +old_LTCC="$LTCC" +old_NM="$NM" +old_RANLIB="$RANLIB" +old_STRIP="$STRIP" +old_AS="$AS" +old_DLLTOOL="$DLLTOOL" +old_OBJDUMP="$OBJDUMP" +old_OBJEXT="$OBJEXT" +old_EXEEXT="$EXEEXT" +old_reload_flag="$reload_flag" +old_deplibs_check_method="$deplibs_check_method" +old_file_magic_cmd="$file_magic_cmd" + +# Parse the command line options. +args= +prev= +for option +do + case $option in + -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$option" + prev= + continue + fi + + case $option in + --help) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + if test -z "$ltmain"; then + ltmain="$option" + elif test -z "$host"; then +# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 +# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then +# echo "$progname: warning \`$option' is not a valid host type" 1>&2 +# fi + host="$option" + else + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac +done + +if test -z "$ltmain"; then + echo "$progname: you must specify a LTMAIN file" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test ! -f "$ltmain"; then + echo "$progname: \`$ltmain' does not exist" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test -n "$tagname"; then + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's/[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]//g'` in + "") ;; + *) + echo "$progname: invalid tag name: $tagname" 1>&2 + exit 1 + ;; + esac + + if grep "^### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$ofile" > /dev/null; then + echo "$progname: tag name $tagname already exists" 1>&2 + exit 1 + fi + + if test ! -f "$ofile"; then + echo "$progname: warning: output file \`$ofile' does not exist" 1>&2 + fi + + if test -z "$LTCC"; then + eval "`$SHELL $ofile --config | grep '^LTCC='`" + if test -z "$LTCC"; then + echo "$progname: warning: output file \`$ofile' does not look like a libtool script" 1>&2 + else + echo "$progname: warning: using \`LTCC=$LTCC', extracted from \`$ofile'" 1>&2 + fi + fi +fi + +# Quote any args containing shell metacharacters. +ltconfig_args= +for arg +do + case $arg in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ltconfig_args="$ltconfig_args '$arg'" ;; + *) ltconfig_args="$ltconfig_args $arg" ;; + esac +done + +# A relevant subset of AC_INIT. + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 compiler messages saved in config.log +# 6 checking for... messages and results +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>>./config.log + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi +if test "X${LANG+set}" = Xset; then LANG=C; export LANG; fi + +if test -n "$cache_file" && test -r "$cache_file" && test -f "$cache_file"; then + echo "loading cache $cache_file within ltconfig" + . $cache_file +fi + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +if test -z "$srcdir"; then + # Assume the source directory is the same one as the path to LTMAIN. + srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` + test "$srcdir" = "$ltmain" && srcdir=. +fi + +trap "$rm conftest*; exit 1" 1 2 15 +if test "$verify_host" = yes; then + # Check for config.guess and config.sub. + ac_aux_dir= + for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/config.guess; then + ac_aux_dir=$ac_dir + break + fi + done + if test -z "$ac_aux_dir"; then + echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 + echo "$help" 1>&2 + exit 1 + fi + ac_config_guess=$ac_aux_dir/config.guess + ac_config_sub=$ac_aux_dir/config.sub + + # Make sure we can run config.sub. + if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : + else + echo "$progname: cannot run $ac_config_sub" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 + + host_alias=$host + case $host_alias in + "") + # Force config.guess to use the C compiler. + # CC_FOR_BUILD overrides the CC variable in config.guess but I had + # problems with it so do it this way for now. + CC="$LTCC" + + if host_alias=`$SHELL $ac_config_guess`; then : + else + echo "$progname: cannot guess host type; you must specify one" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + # Restore the C compiler. + CC="$old_CC" + ;; + esac + host=`$SHELL $ac_config_sub $host_alias` + echo "$ac_t$host" 1>&6 + + # Make sure the host verified. + test -z "$host" && exit 1 + + # Check for the build system type + echo $ac_n "checking build system type... $ac_c" 1>&6 + + build_alias=$build + case $build_alias in + NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; + esac + + build=`$SHELL $ac_config_sub $build_alias` + build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` + build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` + build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + echo "$ac_t""$build" 1>&6 + +elif test -z "$host"; then + echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 + echo "$help" 1>&2 + exit 1 +else + host_alias=$host + build_alias=$host_alias + build=$host +fi + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" +fi + +# Source the script associated with the $tagname tag configuration. +if test -n "$tagname"; then + . $ltmain +else + # FIXME: We should use a variable here + # Configure for a C compiler + . $srcdir/ltcf-c.sh +fi + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$objext" && objext=o + +echo $ac_n "checking for objdir... $ac_c" 1>&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$ac_t$objdir" 1>&6 + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +# We assume here that the value for ac_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 +echo "$progname:678:checking for $compiler option to produce PIC" 1>&5 + +if test -z "$ac_cv_prog_cc_pic"; then + echo "$ac_t"none 1>&6 +else + echo "$ac_t""$ac_cv_prog_cc_pic" 1>&6 + + # Check to make sure the pic_flag actually works. + echo $ac_n "checking if $compiler PIC flag $ac_cv_prog_cc_pic works... $ac_c" 1>&6 + echo "$progname:687:checking that $compiler PIC flag $ac_cv_prog_cc_pic works." 1>&5 + if test "X${ac_cv_prog_cc_pic_works+set}" = Xset && \ + test "X${ac_cv_prog_cc_pic_works}" != X; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + ac_cv_prog_cc_pic_works=yes + $rm conftest* + echo $lt_simple_compile_test_code > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $ac_cv_prog_cc_pic -DPIC" + if { (eval echo $progname:697: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + ac_cv_prog_cc_pic_works=no + ac_cv_prog_cc_can_build_shared=no + ac_cv_prog_cc_pic= + else + ac_cv_prog_cc_pic_works=yes + ac_cv_prog_cc_pic=" $ac_cv_prog_cc_pic" + fi + ;; + *) + ac_cv_prog_cc_pic_works=yes + ac_cv_prog_cc_pic=" $ac_cv_prog_cc_pic" + ;; + esac + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + ac_cv_prog_cc_pic_works=no + ac_cv_prog_cc_can_build_shared=no + ac_cv_prog_cc_pic= + fi + CFLAGS="$save_CFLAGS" + $rm conftest* + fi + # Belt *and* braces to stop my trousers falling down: + if test "X$ac_cv_prog_cc_pic_works" = Xno; then + ac_cv_prog_cc_pic= + ac_cv_prog_cc_can_build_shared=no + fi + echo "$ac_t""$ac_cv_prog_cc_pic_works" 1>&6 +fi + +# Check for any special shared library compilation flags. +if test -n "$ac_cv_prog_cc_shlib"; then + echo "$progname: warning: \`$CC' requires \`$ac_cv_prog_cc_shlib' to build shared libraries" 1>&2 + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$ac_cv_prog_cc_shlib[ ]" >/dev/null; then : + else + echo "$progname: add \`$ac_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" 1>&2 + ac_cv_prog_cc_can_build_shared=no + fi +fi + +echo $ac_n "checking if $compiler static flag $ac_cv_prog_cc_static works... $ac_c" 1>&6 +echo "$progname:749: checking if $compiler static flag $ac_cv_prog_cc_static works" >&5 +if test "X${ac_cv_prog_cc_static_works+set}" = Xset && \ + test "X${ac_cv_prog_cc_static_works}" != X; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + $rm conftest* + echo $lt_simple_link_test_code > conftest.$ac_ext + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $ac_cv_prog_cc_static" + if { (eval echo $progname:758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cc_static_works=yes + else + ac_cv_prog_cc_static_works=no + ac_cv_prog_cc_static= + fi + LDFLAGS="$save_LDFLAGS" + $rm conftest* +fi +# Belt *and* braces to stop my trousers falling down: +if test "X$ac_cv_prog_cc_static_works" = Xno; then + ac_cv_prog_cc_static= +fi +echo "$ac_t""$ac_cv_prog_cc_static_works" 1>&6 +pic_flag="$ac_cv_prog_cc_pic" +special_shlib_compile_flags="$ac_cv_prog_cc_shlib" +wl="$ac_cv_prog_cc_wl" +link_static_flag="$ac_cv_prog_cc_static" +no_builtin_flag="$ac_cv_prog_cc_no_builtin" +can_build_shared="$ac_cv_prog_cc_can_build_shared" + +# find the maximum length of command line arguments +echo "$progname:780: finding the maximum length of command line arguments" 1>&5 +echo $ac_n "finding the maximum length of command line arguments... $ac_c" 1>&6 +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + i=0 + testring="ABCD" + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while test "X"`$CONFIG_SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \ + = "XX$testring" && + new_result=`expr "X$testring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + testring=$testring$testring + done + testring= + # add a significant safety factor because C++ compilers can tack on massive amounts + # of additional arguments before passing them to the linker. 1/4 should be good. + len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len - $len` +fi +echo "$progname:@lineno@: result: $lt_cv_sys_max_cmd_len" 1>&5 +echo "${ac_t}$lt_cv_sys_max_cmd_len" 1>&6 + +if test -n $lt_cv_sys_max_cmd_len ; then + max_cmd_len=$lt_cv_sys_max_cmd_len +else + max_cmd_len=none +fi + +# Check to see if options -o and -c are simultaneously supported by compiler +echo $ac_n "checking if $compiler supports -c -o file.$objext... $ac_c" 1>&6 +if test "${lt_cv_compiler_c_o+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + $rm conftest* + echo $lt_simple_compile_test_code > conftest.$ac_ext + mkdir out + # According to Tom Tromey, Ian Lance Taylor reported there are C compilers + # that will create temporary files in the current directory regardless of + # the output directory. Thus, making CWD read-only will cause this test + # to fail, enabling locking or at least warning the user not to do parallel + # builds. + chmod -w . + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -o out/conftest2.$objext" + echo "$progname:833: checking if $compiler supports -c -o file.$objext" >&5 + if { (eval echo $progname:834: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$objext; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi + else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + lt_cv_compiler_c_o=no + fi + CFLAGS="$save_CFLAGS" + chmod u+w . + $rm conftest* out/* + rmdir out + cd .. + rmdir conftest + $rm -r conftest 2>/dev/null +fi +compiler_c_o=$lt_cv_compiler_c_o +echo "${ac_t}$compiler_c_o" 1>&6 + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$ac_t$hard_links" 1>&6 + $rm conftest* + if test "$hard_links" = no; then + echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 + need_locks=warn + fi +else + need_locks=no +fi + +if test "$with_gcc" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 + $rm conftest* + echo $lt_simple_compile_test_code > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + echo "$progname:887: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + if { (eval echo $progname:888: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_rtti_exceptions=no + else + echo "$ac_t"yes 1>&6 + compiler_rtti_exceptions=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_rtti_exceptions=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi + +fi + +# See if the linker supports building shared libraries. +echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 + +echo "$ac_t$ld_shlibs" 1>&6 +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$ac_t$hardcode_action" 1>&6 + +echo $ac_n "checking whether stripping libraries is possible... $ac_c" 1>&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "${ac_t}yes" 1>&6 +else + echo "${ac_t}no" 1>&6 +fi + +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + # We preserve .a as extension for shared libraries though AIX4.2 + # and later linker supports .so + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so instead of + # lib.a to let people know that these are not typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries though AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | egrep '(GNU)' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + shlibpath_var=LIBPATH + deplibs_check_method=pass_all + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + can_build_shared=no + fi + ;; + esac + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $with_gcc,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll; $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' +;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}.`test .$module = .yes && echo so || echo dylib` ${libname}${release}${major}.$`test .$module = .yes && echo so || echo dylib` ${libname}.`test .$module = .yes && echo so || echo dylib`' + soname_spec='${libname}${release}${major}.`test .$module = .yes && echo so || echo dylib`' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd*-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so${major}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU/FreeBSD ld.so' + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lc=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + if test "$with_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi + version_type=irix + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + need_lib_prefix=no + need_version=no + version_type=sunos + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + need_version=no + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$ac_t$dynamic_linker" 1>&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + symcode='[BCDEGRST]' + ;; +solaris* | sysv5*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + $rm conftest* + cat > conftest.$ac_ext <&5 + if { (eval echo $progname:1432: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then + # Now try to grab the symbols. + nlist=conftest.nm + if { echo "$progname:1435: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$objext conftstm.$objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo $progname:1487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + pipe_works=yes + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + LIBS="$save_LIBS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + $rm conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + global_symbol_pipe= + fi +done +if test "$pipe_works" = yes; then + echo "${ac_t}ok" 1>&6 +else + echo "${ac_t}failed" 1>&6 +fi + +if test -z "$global_symbol_pipe"; then + global_symbol_to_cdecl= +fi + +# Report the final consequences. +echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 + +# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in +# configure.in, otherwise build static only libraries. +case $host_os in +cygwin* | mingw* | pw32* | os2*) + if test x$can_build_shared = xyes; then + test x$enable_win32_dll = xno && can_build_shared=no + echo "checking if package supports dlls... $can_build_shared" 1>&6 + fi +;; +esac + +echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + test "$enable_shared" = yes && enable_static=no + ;; +esac + +echo "$ac_t$enable_shared" 1>&6 + +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes + +echo "checking whether to build static libraries... $enable_static" 1>&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$with_gcc" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# Check whether we must set pic_mode to default +test -z "$pic_flag" && pic_mode=default + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else +if test "X${lt_cv_dlopen+set}" != Xset; then + lt_cv_dlopen=no lt_cv_dlopen_libs= +echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "$progname:1591: checking for dlopen in -ldl" >&5 +if test "X${ac_cv_lib_dl_dlopen+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_lib_dl_dlopen=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lib_dl_dlopen=no +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if test "X$ac_cv_lib_dl_dlopen" = Xyes; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dlopen""... $ac_c" 1>&6 +echo "$progname:1630: checking for dlopen" >&5 +if test "X${ac_cv_func_dlopen+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +dlopen(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:1660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_func_dlopen=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_func_dlopen=no +fi +rm -f conftest* +fi +if test "X$ac_cv_func_dlopen" = Xyes; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6 +echo "$progname:1677: checking for dlopen in -lsvld" >&5 +if test "X${ac_cv_lib_svld_dlopen+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsvld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_lib_svld_dlopen=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lib_svld_dlopen=no +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if test "X$ac_cv_lib_svld_dlopen" = Xyes; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 +echo "$progname:1716: checking for dld_link in -ldld" >&5 +if test "X${ac_cv_lib_dld_dld_link+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_lib_dld_dld_link=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lib_dld_dld_link=no +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if test "X$ac_cv_lib_dld_dld_link" = Xyes; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load""... $ac_c" 1>&6 +echo "$progname:1755: checking for shl_load" >&5 +if test "X${ac_cv_func_shl_load+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +shl_load(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:1785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_func_shl_load=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_func_shl_load=no +fi +rm -f conftest* +fi + +if test "X$ac_cv_func_shl_load" = Xyes; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 +echo "$progname:1803: checking for shl_load in -ldld" >&5 +if test "X${ac_cv_lib_dld_shl_load+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_lib_dld_shl_load=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lib_dld_shl_load=no +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if test "X$ac_cv_lib_dld_shl_load" = Xyes; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +fi + + +fi + + +fi + +fi + +fi + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) +for ac_hdr in dlfcn.h; do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "$progname:1871: checking for $ac_hdr" >&5 +if eval "test \"`echo 'X$''{'ac_cv_header_$ac_safe'+set}'`\" = Xset"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int fnord = 0; +int main () { return(0); } +EOF +ac_try="$ac_compile >/dev/null 2>conftest.out" +{ (eval echo $progname:1882: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +done + + if test "x$ac_cv_header_dlfcn_h" = xyes; then + CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + fi + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:1910: checking whether a program can dlopen itself" >&5 +if test "X${lt_cv_dlopen_self+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self=cross + else + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42; } +int main() { + void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:1965: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self" 1>&6 + + if test "$lt_cv_dlopen_self" = yes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:1984: checking whether a statically linked program can dlopen itself" >&5 +if test "X${lt_cv_dlopen_self_static+set}" = Xset; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self_static=cross + else + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42; } +int main() { + void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self_static=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self_static=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 +fi + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + +# Copy echo and quote the copy, instead of the original, because it is +# used later. +ltecho="$echo" +if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ltecho="$CONFIG_SHELL \$0 --fallback-echo" +fi +LTSHELL="$SHELL" + +LTCONFIG_VERSION="$VERSION" + +# Only quote variables if we're using ltmain.sh. +case $ltmain in +*.sh) + # Now quote all the things that may contain metacharacters. + for var in ltecho old_AR old_AR_FLAGS old_CC old_LTCC old_CFLAGS old_CPPFLAGS \ + old_MAGIC_CMD old_LD old_LDFLAGS old_LIBS \ + old_LN_S old_NM old_RANLIB old_STRIP \ + old_AS old_DLLTOOL old_OBJDUMP \ + old_OBJEXT old_EXEEXT old_reload_flag \ + old_deplibs_check_method old_file_magic_cmd \ + AR AR_FLAGS CC LTCC LD LN_S NM LTSHELL LTCONFIG_VERSION \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + predep_objects postdep_objects predeps postdeps compiler_lib_search_path \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ### testsuite: skip nested quoting test + ;; + *) + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ### testsuite: skip nested quoting test + ;; + esac + done + + case $ltecho in + *'\$0 --fallback-echo"') + ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + + if test -z "$tagname"; then + trap "$rm \"$ofile\"; exit 1" 1 2 15 + echo "creating $ofile" + $rm "$ofile" + cat < "$ofile" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# The names of the tagged configurations supported by this script. +available_tags= + +### BEGIN LIBTOOL CONFIG +EOF + else + echo "appending configuration tag \"$tagname\" to $ofile" + echo "### BEGIN LIBTOOL TAG CONFIG: $tagname" >> "$ofile" + fi + cfgfile="$ofile" + ;; + +*) + # Double-quote the variables that need it (for aesthetics). + for var in old_AR old_AR_FLAGS old_CC old_LTCC old_CFLAGS old_CPPFLAGS \ + old_MAGIC_CMD old_LD old_LDFLAGS old_LIBS \ + old_LN_S old_NM old_RANLIB old_STRIP \ + old_AS old_DLLTOOL old_OBJDUMP \ + old_OBJEXT old_EXEEXT old_reload_flag \ + old_deplibs_check_method old_file_magic_cmd; do + eval "$var=\\\"\$var\\\"" + done + + # Just create a config file. + cfgfile="$ofile.cfg" + if test -z "$tagname"; then + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + echo "creating $cfgfile" + $rm "$cfgfile" + cat < "$cfgfile" +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) + +### BEGIN LIBTOOL CONFIG +EOF + else + echo "appending to $cfgfile" + echo "### BEGIN LIBTOOL TAG CONFIG: $tagname" >> "$ofile" + fi + ;; +esac + +cat <> "$cfgfile" +# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# AR=$old_AR AR_FLAGS=$old_AR_FLAGS LTCC=$old_LTCC CC=$old_CC \\ +# CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ +# MAGIC_CMD=$old_MAGIC_CMD LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ +# LN_S=$old_LN_S NM=$old_NM RANLIB=$old_RANLIB STRIP=$old_STRIP \\ +# AS=$old_AS DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP \\ +# objext=$old_OBJEXT exeext=$old_EXEEXT reload_flag=$old_reload_flag \\ +# deplibs_check_method=$old_deplibs_check_method \\ +# file_magic_cmd=$old_file_magic_cmd \\ +# $0$ltconfig_args +# +# Compiler and other test output produced by $progname, useful for +# debugging $progname, is in ./config.log if it exists. + +# The version of $progname that generated this script. +LTCONFIG_VERSION=$LTCONFIG_VERSION + +# Shell to use when invoking shell scripts. +SHELL=$LTSHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$ltecho + +# The archiver. +AR=$AR +AR_FLAGS=$AR_FLAGS + +# A C compiler. +LTCC=$LTCC + +# A language-specific compiler. +CC=$CC + +# Is the compiler the GNU C compiler? +with_gcc=$with_gcc + +# The linker used to build libraries. +LD=$LD + +# Whether we need hard or soft links. +LN_S=$LN_S + +# A BSD-compatible nm program. +NM=$NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$reload_flag +reload_cmds=$reload_cmds + +# How to pass a linker flag through the compiler. +wl=$wl + +# Object file suffix (normally "o"). +objext="$objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$pic_flag +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$compiler_c_o + +# Must we lock files when doing compilation ? +need_locks=$need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$RANLIB +old_archive_cmds=$old_archive_cmds +old_postinstall_cmds=$old_postinstall_cmds +old_postuninstall_cmds=$old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$archive_cmds +archive_expsym_cmds=$archive_expsym_cmds +postinstall_cmds=$postinstall_cmds +postuninstall_cmds=$postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$old_striplib +striplib=$striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$predep_objects + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$postdep_objects + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$predeps + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$compiler_lib_search_path + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$global_symbol_to_cdecl + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$include_expsyms + +EOF + +if test -z "$tagname"; then + echo '### END LIBTOOL CONFIG' >> "$ofile" +else + echo "### END LIBTOOL TAG CONFIG: $tagname" >> "$ofile" +fi + +case $ltmain in +*.sh) + echo >> "$ofile" + if test -z "$tagname"; then + case $host_os in + aix3*) + cat <<\EOF >> "$ofile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + cat <<'EOF' >> "$ofile" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "$ofile" || (rm -f "$ofile"; exit 1) + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + + chmod +x "$ofile" + fi + ;; + +*) + # Compile the libtool program. + echo "FIXME: would compile $ltmain" + ;; +esac + +# Update the list of available tags. +if test -n "$tagname"; then + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" $ofile | sed -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + # Append the new tag name to the list of available tags. + available_tags="$available_tags $tagname" + + # Now substitute the updated of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' ${ofile} > ${ofile}.new"; then + mv ${ofile}.new ${ofile} + chmod +x "$ofile" + else + rm -f ${ofile}.new + echo "$progname: unable to update list of available tagged configurations." + exit 1 + fi +fi + +# Don't cache tagged configuration! +test -n "$cache_file" && test -z "$tagname" || exit 0 + +# AC_CACHE_SAVE +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/contrib/gdb/ltmain.sh b/contrib/gdb/ltmain.sh new file mode 100644 index 00000000000..c3547e5a561 --- /dev/null +++ b/contrib/gdb/ltmain.sh @@ -0,0 +1,5469 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + echo "$modename: not configured to build any kind of library" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +taglist= + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + echo "$progname: invalid tag name: $tagname" 1>&2 + exit 1 + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + taglist="$taglist $tagname" + ;; + *) + if grep "^### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`sed -n -e '/^### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`" + else + echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + sed -n -e '/^### BEGIN LIBTOOL CONFIG/,/^### END LIBTOOL CONFIG/p' < "$0" + # Now print the configurations for the tags. + for tagname in $taglist; do + sed -n -e "/^### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0" + done + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + --tag) prevopt="--tag" prev=tag ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case $nonopt in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + prev= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + # Accept any command-line options. + case $arg in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + case $user_target in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $lastarg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case $user_target in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + # Infer tagged configuration to use if any are available and + # if one wasn't chosen via the "--tag" command line option. + # Only attempt this if the compiler in the base compile + # command doesn't match the default compiler. + if test -n "$available_tags" && test -z "$tagname"; then + case $base_compile in + "$CC "*) ;; + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when ltconfig was run. + "`$echo $CC` "*) ;; + *) + for z in $available_tags; do + if grep "^### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then + # Evaluate the configuration. + eval "`sed -n -e '/^### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" + case $base_compile in + "$CC "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + "`$echo $CC` "*) + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + echo "$modename: unable to infer tagged configuration" + echo "$modename: specify a tag with \`--tag'" 1>&2 + exit 1 +# else +# echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi + + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "x$output_obj" != "x$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test -n "$output_obj" && test "x$output_obj" != "x$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + base_compile="$base_compile $arg" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit 1 + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit 1 + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit 1 + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n $prev + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit 1 + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit 1 + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Infer tagged configuration to use if any are available and + # if one wasn't chosen via the "--tag" command line option. + # Only attempt this if the compiler in the base link + # command doesn't match the default compiler. + if test -n "$available_tags" && test -z "$tagname"; then + case $base_compile in + "$CC "*) ;; + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when ltconfig was run. + "`$echo $CC` "*) ;; + *) + for z in $available_tags; do + if grep "^### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then + # Evaluate the configuration. + eval "`sed -n -e '/^### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" + case $base_compile in + "$CC "*) + # The compiler in $compile_command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + "`$echo $CC` "*) + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + echo "$modename: unable to infer tagged configuration" + echo "$modename: specify a tag with \`--tag'" 1>&2 + exit 1 +# else +# echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + libs="$libs $deplib" + done + + if test $linkmode = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test $linkmode = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test $linkmode = oldlib && test $linkmode = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test $pass = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test $pass = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test $pass = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: This library needs some functionality provided by $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test $pass != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test $found = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test $linkmode = oldlib && test $linkmode = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test $pass = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + tmp_libs="$tmp_libs $deplib" + done + elif test $linkmode != prog && test $linkmode != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test $pass = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test $pass = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test $linkmode = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test $linkmode = prog && test $pass != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test $linkalldeplibs = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test $linkmode = lib && test $hardcode_into_libs = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + if test $linkmode = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | sed -e 's/^.*\///'` + newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test $linkmode = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test $linkmode = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test $linkmode = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + add="-l$name" + fi + + if test $linkmode = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test $linkmode = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This library needs some functionality provided by $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** Therefore, libtool will create a static module, that should work " + echo "*** as long as the dlopening application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test $linkmode = lib; then + if test -n "$dependency_libs" && + { test $hardcode_into_libs != yes || test $build_old_libs = yes || + test $link_static = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + tmp_libs="$tmp_libs $deplib" + done + + if test $link_all_deplibs != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test $pass = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test $pass != dlopen; then + test $pass != scan && dependency_libs="$newdependency_libs" + if test $pass != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test $linkmode = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix) + major=`expr $current - $age + 1` + verstring="sgi$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="sgi$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'` + deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test $hardcode_into_libs != yes || test $build_old_libs = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test $build_libtool_need_lc = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | sed 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | sed 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + if eval echo \"$potent_lib\" 2>/dev/null \ + | sed 10q \ + | egrep "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test $allow_undefined = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test $hardcode_into_libs = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + test -z "$dlname" && dlname=$soname + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + +# # Ensure that we have .o objects for linkers which dislike .lo +# # (e.g. aix) in case we are running --disable-static +# for obj in $libobjs; do +# xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` +# if test "X$xdir" = "X$obj"; then +# xdir="." +# else +# xdir="$xdir" +# fi +# baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` +# oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` +# if test ! -f $xdir/$oldobj && test "$baseobj" != "$oldobj"; then +# $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" +# $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? +# fi +# done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + if len=`expr "X$cmds" : ".*"` && + test $len -le $max_cmd_len; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$save_output-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*"` && + test $len -le $max_cmd_len; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test $k -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$save_output-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$save_output-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + # Set up a command to remove the reloadale object files + # after they are used. + i=0 + while test $i -lt $k + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$save_output-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~$rm $delfiles\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" +# else +# # Just create a symlink. +# $show $rm $libobj +# $run $rm $libobj +# xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` +# if test "X$xdir" = "X$libobj"; then +# xdir="." +# else +# xdir="$xdir" +# fi +# baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` +# oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` +# $show "(cd $xdir && $LN_S $oldobj $baseobj)" +# $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles="$objs$old_deplibs" + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | sed -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{\ +" + + sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ + -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ + < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr_t) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test $need_relink = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="cd `pwd`; $relink_command" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|sed 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else +# # Ensure that we have .o objects in place in case we decided +# # not to build a shared library, and have fallen back to building +# # static libs even though --disable-static was passed! +# for oldobj in $oldobjs; do +# if test ! -f $oldobj; then +# xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` +# if test "X$xdir" = "X$oldobj"; then +# xdir="." +# else +# xdir="$xdir" +# fi +# baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` +# obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` +# $show "(cd $xdir && ${LN_S} $obj $baseobj)" +# $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? +# fi +# done + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test $len -le $max_cmd_len; then + : + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*"` && + test $len -le $max_cmd_len; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + eval cmds=\"\$concat_cmds~$old_archive_cmds\" + fi + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + tagopts= + for tag in $taglist; do + tagopts="$tagopts --tag $tag" + done + relink_command="(cd `pwd`; $SHELL $0$tagopts --mode=relink $libtool_args)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test $need_relink = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit 1 + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | sed -e 's,.exe$,,'` + ;; + esac + ;; + esac + + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = ":" && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd='"$cmd"$args' + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test $mode = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test $mode = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test $mode = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + # Do a test to see if this is a libtool program. + if test $mode = clean && + (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +### END LIBTOOL TAG CONFIG: disable-shared + +### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/contrib/gdb/md5.sum b/contrib/gdb/md5.sum new file mode 100644 index 00000000000..5348d5f2847 --- /dev/null +++ b/contrib/gdb/md5.sum @@ -0,0 +1,5330 @@ +0636e73ff0215e8d672dc4c32c317bb3 COPYING +f30a9716ef3762e3467a2f62bf790f0a COPYING.LIB +01b56d00067e222fa90de4ad0c8b0bab Makefile.def +a2362771d50b4a6940ed689988368915 Makefile.in +857b2349378408c5f0cf3d4ee6eaed47 Makefile.tpl +07c33a285703b40cd6f93a478e97e03b README +ceab81aa1f02825092808fdafba0239d bfd/COPYING +ddb9e929c08f79992b3cab4a7ef7fd18 bfd/ChangeLog +daabeea83b81f2707d48d2c04dcc37c4 bfd/ChangeLog-0001 +258372f0002edcee47f582f172db1b3c bfd/ChangeLog-0203 +8dcb7ce2e45911e21ceb6e457e69eacf bfd/ChangeLog-9193 +6d37ec6ee5f57a1188a0717f2fa5deb0 bfd/ChangeLog-9495 +b7ad288235bf6a3e015e01cb6096cbe7 bfd/ChangeLog-9697 +dbb0d89c90d6c0ec79eb003a5b63f923 bfd/ChangeLog-9899 +d618facc3e8ce8bf3d02ba452e1be6ab bfd/MAINTAINERS +ae6fc11266155eb05e6b1833c60e8a56 bfd/Makefile.am +c4519eb4e3ebc32fe734e20562e6577e bfd/Makefile.in +6455e3c85b31e588ecb75f7d3c945c8d bfd/PORTING +2d6a5be3f5d1b33251fe9a8570e943d8 bfd/README +cd26654c6eb30680694867e434e40044 bfd/TODO +95b37f5a8b37019a0ae21e25a9df8943 bfd/acinclude.m4 +c2c720e6830eb31a7c9fe961f3708643 bfd/aclocal.m4 +f9c82c819ae27c28980b9b4feaf2bc16 bfd/aix386-core.c +56c6a28898034cf5a2f788b879c058f8 bfd/aix5ppc-core.c +cdfcd10f565dc089740f1767afde4a99 bfd/aout-adobe.c +a086890accd499e2cfcbfdec741e6f0c bfd/aout-arm.c +2d02ebe9d3ccfa281e766434a34dbaf9 bfd/aout-cris.c +5bf71068402124e456fa8e7ce67a2bed bfd/aout-encap.c +6f39a856277e0c7ab9ca3d5e951a20f8 bfd/aout-ns32k.c +e5462c5655e858dd98c46e362a87d39a bfd/aout-sparcle.c +e34f2112b40dfb78b88f6cc36e1f9efd bfd/aout-target.h +9157bbb7045a28e9c75ba785197c95cc bfd/aout-tic30.c +b7d0f371ad6ceb36548dcbad20e17859 bfd/aout0.c +710ff75a0a234773691c069654dd8ba6 bfd/aout32.c +cae169ce11deb6f450104c569c23c853 bfd/aout64.c +7d60016ff69bd848e9dfa548841f835b bfd/aoutf1.h +1ff426e7d0cd60b79f8f42246b5fb5c7 bfd/aoutx.h +b6b8cab99a4e0177241839a45bb85672 bfd/archive.c +06dbd5afe5d36755a172507b6c559fc1 bfd/archive64.c +f36760f48ecda411b5aa7a3a44fe0909 bfd/archures.c +7355fa1829188da840a37bc85c39b737 bfd/armnetbsd.c +c8d8eca8b4e908b100434934502f698c bfd/bfd-in.h +ae3b4128551b1af0da2c464c44f917ba bfd/bfd-in2.h +15ec69d5a6d895f969f58f260b2ec814 bfd/bfd.c +3f968067c77722717f149f143d3f8c19 bfd/bfdio.c +d7491728b7a204e534ab0adb45c46b5a bfd/bfdwin.c +44c3865a37a4a0e66d26f7e560127b74 bfd/binary.c +42b962329287e46ca79d8cb8d53ad7a7 bfd/bout.c +d5aff65092c9d720c4c03894946b12e5 bfd/cache.c +6d3c1b378bc7ed685664fe6eca297523 bfd/cf-i386lynx.c +545c111611d3dddaae8c666293aac89b bfd/cf-m68klynx.c +09a8617f3c790897c5ac230aa7c9e683 bfd/cf-sparclynx.c +70d403922007ecd1e12768a941a1ca4b bfd/cisco-core.c +c5759e7cc48faca87b33154ed1be2240 bfd/coff-a29k.c +24f4ff12b1912cbafaa396ea48ec68a2 bfd/coff-alpha.c +ed5b46a86e1b44f2d30b43a540f2ccca bfd/coff-apollo.c +d29b52a4c23bce50c9acd3e72cb64e8e bfd/coff-arm.c +8059bbea66752b7c96719dd935da545e bfd/coff-aux.c +b7572dbbd820acf00c9d5571af08f2e5 bfd/coff-go32.c +a067a43cc2184b463beda82740386230 bfd/coff-h8300.c +8036e3eb44b0885a377ed963d5a8e2dd bfd/coff-h8500.c +97f4f9ac464fd52d0941811e8e741256 bfd/coff-i386.c +fa6c489482cb4abdede4a60a16e415af bfd/coff-i860.c +e9e0ac6ef4f1b9a6e0c091348a0abc3a bfd/coff-i960.c +3743199a9b010f682e0002fe0896aae8 bfd/coff-ia64.c +37adbd3ad6583bdf182b8c79d0a09497 bfd/coff-m68k.c +e7cd4503d04fbf49fb5283b26f52ebba bfd/coff-m88k.c +08b0ca5de3fb97f57e83d3ab6f7ebb23 bfd/coff-mcore.c +72cbac7f5701cbc2baaa65a5fb7a0eec bfd/coff-mips.c +866c505604722466b2f17d8c81a92b2c bfd/coff-or32.c +0fe98f356a19d05611fa133c217e77e5 bfd/coff-pmac.c +4be03c7038009a13af548604d7ec4bbc bfd/coff-ppc.c +38de8920d47aa9eb553984d60087a293 bfd/coff-rs6000.c +d45c75a567e771e67c4a36a12c9c2b92 bfd/coff-sh.c +e62fbc5f8a3dd5662a059b60adad11c2 bfd/coff-sparc.c +1ed0e24cda15ce0fbc0c907703622d72 bfd/coff-stgo32.c +0a6bcb90289a5f62cb39fb0ec0858560 bfd/coff-svm68k.c +3daee2f40d2b787308e9a1d709aca805 bfd/coff-tic30.c +d1a0fb769c7f69895d7bf8109e72a510 bfd/coff-tic4x.c +6760e615015a480a9d9cc7260e59658b bfd/coff-tic54x.c +cd9a56d38f1a450f4ecdb7cc7bab5aba bfd/coff-tic80.c +f8c6308a039c92faded1d165112668a2 bfd/coff-u68k.c +b8a401b68f742b58596a8fe4e3c0160b bfd/coff-w65.c +61d5c4ba4236dca72fe7a7b04679c548 bfd/coff-we32k.c +f0e47a0c5b5f217148ab8af737e13571 bfd/coff-z8k.c +0a457ba20592d35dd3e5d6f5b5191a23 bfd/coff64-rs6000.c +f2221a9bb0b95569ef24b4655587655f bfd/coffcode.h +31f6379e9b9fef8fa518c46427f19a12 bfd/coffgen.c +4b41f2bf4937575625d75541e86b4652 bfd/cofflink.c +eb4672541cca282f98893fa0e72a9b6d bfd/coffswap.h +f1d700ad46f2ed115e4ddb02a6c15858 bfd/config.bfd +f83ff421796cffa5b1544eec5e6f9cf4 bfd/config.in +0651a21130e58b3884778d44a64281dd bfd/configure +a8485b69f68d81f4ef2f29b51bb36d85 bfd/configure.com +2eda4de56a20d2079c1e2b8fc82fd303 bfd/configure.host +cbe67e4ed47f62019ce9ff884bb5a4a6 bfd/configure.in +ce0b415790c25f1bcfa1008a252bbe76 bfd/corefile.c +5c0d89447ec9068a82206617864bb57c bfd/cpu-a29k.c +a856235ca2eb870387b078ccd1084733 bfd/cpu-alpha.c +38d8b50602f459cf46c67bffc9da2646 bfd/cpu-arc.c +c05b041b2241758f209e9fb3153f7e3d bfd/cpu-arm.c +8670a746d84a73a96a33ea674d44753e bfd/cpu-avr.c +073416090cf1d506b6dd77023836cd5c bfd/cpu-cris.c +6855298754b13705dd165a7f66730b27 bfd/cpu-d10v.c +31a29cb2eb7bf274d02ad6e31bc94ebb bfd/cpu-d30v.c +75333587061ce9eaec79515b6e61b80a bfd/cpu-dlx.c +b0ca824687840d64ed72e95008b6696e bfd/cpu-fr30.c +b340406eb6f6aa43c466d969c9707f2d bfd/cpu-frv.c +d24bc250ce24cdd65be95e1ea80fa02b bfd/cpu-h8300.c +6d8f7e09ca549a791d6e0604cd30bf71 bfd/cpu-h8500.c +ad8dac130e4165ee8da68f554223e615 bfd/cpu-hppa.c +8afc9dfed1753f4e8ddcd59f7ed51bfc bfd/cpu-i370.c +5984ec8fa236636b1c16c555c873c650 bfd/cpu-i386.c +32e8b88620f294fd92d9fa24389458c3 bfd/cpu-i860.c +059eacc0c428a5cc9aa957375599aaab bfd/cpu-i960.c +4a6b4dde5d3182ef76e43d49956e26e2 bfd/cpu-ia64-opc.c +b1b262009e59a8f0c79da9c9289a95fc bfd/cpu-ia64.c +d64dd87b24efe5b86695ffbc4ef85c3e bfd/cpu-ip2k.c +5fc83c8be02e0e57d85d76ac96346f34 bfd/cpu-iq2000.c +55e75d011da4e793fa903eb588e971f5 bfd/cpu-m10200.c +926dba983091df956a20d5ac2d03511c bfd/cpu-m10300.c +1361b70e7b455b0f54fa1b1f172eba7c bfd/cpu-m32r.c +a3600f2fa5f5279c65c53fa9b2071535 bfd/cpu-m68hc11.c +0f263fd8bdf74135b519d82f50f2b954 bfd/cpu-m68hc12.c +5a51d7542ae8054e1ca9fb2c41976ed1 bfd/cpu-m68k.c +13d35f4c96e2d81d61040acb3c89b5e8 bfd/cpu-m88k.c +15675fc1f00d26428fdd5ce42e15cf87 bfd/cpu-mcore.c +3db5c0679216eaa5656974d7c2babbae bfd/cpu-mips.c +dcc2f3d6c61b634e6df985262b698695 bfd/cpu-mmix.c +b44e2935dd2f75d62a7ea83f4f031308 bfd/cpu-msp430.c +2519296ad9ba616914f4795876ebe98d bfd/cpu-ns32k.c +78e0773fce06924c1822036726ea15c1 bfd/cpu-openrisc.c +16969a34418aa358869b6f3b0fc09e03 bfd/cpu-or32.c +fb7ee1fa345060daece22d8cb7e14ebf bfd/cpu-pdp11.c +7945d7fc4016ed304fd38a7427401b9d bfd/cpu-pj.c +61d80887a1a812d2d04870993de06711 bfd/cpu-powerpc.c +86b67838bec7ced639aba6d44b459554 bfd/cpu-rs6000.c +f214ca1c10a452ac3990275a5536364c bfd/cpu-s390.c +ce48f5d9ed1a3c19a57c118a245c204b bfd/cpu-sh.c +1341cb777ccfc53c805e7427a0efb8b2 bfd/cpu-sparc.c +4f3420afcf9cb5665b8f91290f9231c3 bfd/cpu-tic30.c +99abf59d00537ba03be5ff5d6b9c40a9 bfd/cpu-tic4x.c +d3feadb829b55be9f231f5374b4ab0f5 bfd/cpu-tic54x.c +63ca1b136f3eb9e42b387e18ed07ec4d bfd/cpu-tic80.c +03eac88302f1e6b9939e0e70cb6895f6 bfd/cpu-v850.c +cafc0a276c6fe6f77003c66e9d84dfbc bfd/cpu-vax.c +1eba036739554133ab48c605983638e6 bfd/cpu-w65.c +3369bd707089438cb61a399b51712ad6 bfd/cpu-we32k.c +5ea7e7adb4e971a0efa3adcbdc1c511a bfd/cpu-xstormy16.c +f3353acce243bdf49f229f65c80be082 bfd/cpu-xtensa.c +38bdf1a8b5d9eb2381786e747b623e7a bfd/cpu-z8k.c +e03c6141f7dfc11bf97d902b02c543f8 bfd/demo64.c +15ea8c60509b116547b6aa31e81c9613 bfd/dep-in.sed +5a1ea97d362ce577b9d2ed82a25f77e4 bfd/dwarf1.c +b5b58df49cf8d8fdce3120c98a46deae bfd/dwarf2.c +91fbda4c532224d62f59046ba2a4178f bfd/ecoff.c +9e4ddbd6ed8be774ca8f2349e59b1e55 bfd/ecofflink.c +d4ad21eeaea85cd04f9c275a4a524652 bfd/ecoffswap.h +fea84b9c79e99275ad3a20612d264929 bfd/efi-app-ia32.c +87806770ec6a23866701b7662638ba96 bfd/efi-app-ia64.c +14479130d0498e27cdcf14ae8badabfe bfd/elf-bfd.h +f3962ec98ce9fd6bdc301d4b7e398089 bfd/elf-eh-frame.c +8b272d79099e36fc1ee93bbcaee39720 bfd/elf-hppa.h +ff2ff5cb72a156a60fade8e9f9eea2b2 bfd/elf-m10200.c +9e84e766effda7bf3ca1af90500d14c9 bfd/elf-m10300.c +ddd2eade9caa8aca9f1734fc92d82b6e bfd/elf-strtab.c +cf3c4bd4b757f1feab442453a71c4a4b bfd/elf.c +ce6b2e95b1ceecc5174e92b44e04827b bfd/elf32-am33lin.c +fa56312cdca619fd096e4d887aa2c514 bfd/elf32-arc.c +d03e5937a1e3a7313dc58b1b07fa5ace bfd/elf32-arm.h +c780a734b5befa7d38847a91e650d5c3 bfd/elf32-avr.c +2ec1fc1a2a7fbc540102bfaeb2deca6d bfd/elf32-cris.c +6dbc6be073a31d93696922cefbfbe4bf bfd/elf32-d10v.c +4bfbd76fbced7646457d1ab36d17eefd bfd/elf32-d30v.c +35b57cd828093e8808a58a537a2f8bcc bfd/elf32-dlx.c +94bfb2b97c0184e4e245151f666980d6 bfd/elf32-fr30.c +36433103fa4291ea0e429691f1af8aab bfd/elf32-frv.c +9d9a8056e6d01e8196156b8d0d38ec83 bfd/elf32-gen.c +408f8469fdce94d0a70ae1c4c8d2be8e bfd/elf32-h8300.c +fc5f0170bc7016c730e61f0eadfd581b bfd/elf32-hppa.c +31c2c588dfd4812995b742742a1bdc86 bfd/elf32-hppa.h +58469fb57c893c90cbd824b98ec9519a bfd/elf32-i370.c +1057cd88eea1c27f4e1e1b433d23232e bfd/elf32-i386.c +11fcc50089679d494433434b54fb841e bfd/elf32-i860.c +3387b5c4a92adcf7ac7161b71e9d1e0e bfd/elf32-i960.c +c3987c253f3cc62ba059a289b1f6a423 bfd/elf32-ip2k.c +c4d368e7ff252fea7ff6dd5f627b199e bfd/elf32-iq2000.c +b8b9ab48eb6343ec3c398d1a2311de4b bfd/elf32-m32r.c +455f4bae98b6260374be7378e6cf1dc3 bfd/elf32-m68hc11.c +4c2866cc197a16648d83bd1962c0d7b1 bfd/elf32-m68hc12.c +5efc141dabb7c3684ef201dd3e7d8e2d bfd/elf32-m68hc1x.c +db22ff75b4183d38ac0afebd6a852bff bfd/elf32-m68hc1x.h +8ceb93ad1cc7250297d53ca47a391562 bfd/elf32-m68k.c +6d08a2b4a53db400e322f8f712aa9498 bfd/elf32-m88k.c +a57d36b03e78461381dcffaf8f0cd2dd bfd/elf32-mcore.c +e64e3dac81b71cd2474e0727fb2cf7e0 bfd/elf32-mips.c +cf4e6321a70989dc93501a935188f7ae bfd/elf32-msp430.c +e6a216ccbcae2ed24232df82bf3d8768 bfd/elf32-openrisc.c +1f732f2c3af63b47edef956264130b83 bfd/elf32-or32.c +f88946084255132c58a6db634f59bb95 bfd/elf32-pj.c +51d42c9fa470165a7d91cc4a7c9d0a81 bfd/elf32-ppc.c +177ef4609724779d4ed55850cbfa99b1 bfd/elf32-ppc.h +80935d9d1b137a664639c45343b0120e bfd/elf32-s390.c +2474a2d45e8fd8280dab89c0f987dc5b bfd/elf32-sh.c +1af6d1ccf6330e120779a66ecfeaf11b bfd/elf32-sh64-com.c +dc0a382a0c88ec81e2fcc3056387d25f bfd/doc/ChangeLog +42b5ebab441fcbf65e95c2aa31262147 bfd/doc/ChangeLog-9103 +23ef21a07d973a0d6809a8f53bcd1675 bfd/doc/Makefile.am +16f39b337cc1b1f9c5dce2644be9ef9f bfd/doc/Makefile.in +e0e91b07018f1d9722268692f0e7b0ce bfd/doc/bfd.texinfo +0f69cf6ca021b3c9e507ee615c710f9d bfd/doc/bfdint.texi +5ee7f8ae8b0ec33c7baf2e004084aaa1 bfd/doc/bfdsumm.texi +c12d7a1841284def3367de9759831490 bfd/doc/chew.c +e67d8b07516154c4ddbee2e3bab3d75e bfd/doc/doc.str +1cc3fb2ac1b5311b7639908a78232dd6 bfd/doc/fdl.texi +39f61ac0fb56eced56e6894e7bc47cef bfd/doc/header.sed +5fa24958e8a60b2f879af658e615ccc0 bfd/doc/makefile.vms +d7a37304ccd7b245f93df4be02797477 bfd/doc/proto.str +551e63b0eb7692e8b20711d1d2e58982 bfd/doc/aoutx.texi +522217c56d19e9cf9fc34c3afbf64768 bfd/doc/archive.texi +a31779a4ed5b4570221dc7ae178174d4 bfd/doc/archures.texi +fbd9578afabb5003c84523423b06fd02 bfd/doc/bfdt.texi +aaec20ba5c590e39f0f20a658a43dd95 bfd/doc/cache.texi +956d852bf8e50e1e0e44c596568b488d bfd/doc/coffcode.texi +a4d505981c9abe2add4ac13692fac080 bfd/doc/core.texi +edddb27f6970dc93153be948b619b001 bfd/doc/elf.texi +d41d8cd98f00b204e9800998ecf8427e bfd/doc/elfcode.texi +1208bdf175c700f865a7e348583c8ccd bfd/doc/format.texi +4c3b9427f5569a148768b9eb8876806c bfd/doc/libbfd.texi +236e856bb13ee47adc5d7d253037640d bfd/doc/bfdwin.texi +9e85fd141105d249ff2585a08af70761 bfd/doc/bfdio.texi +0efeea0c247a9899aed4cee86e8db2d2 bfd/doc/opncls.texi +c5af7ac43685cae4827cd35aaee9928c bfd/doc/reloc.texi +83c5b66aea72852dcadaf4fcab5cf0d5 bfd/doc/section.texi +f7dc7a07291373d93eeb964dfd84e685 bfd/doc/syms.texi +01bf23430b0c0922024081a024786a86 bfd/doc/targets.texi +72bc7195c38b3f966acfa5b670e47868 bfd/doc/init.texi +f7070c1179b4cf5375fd0a1f3db81ee7 bfd/doc/hash.texi +6db897ac372d7671a8475590413ba311 bfd/doc/linker.texi +4b178141d4ecb16c4fd528a79a4e7d93 bfd/doc/mmo.texi +ebf7ecf4a89ad34d85890ec5feef770e bfd/doc/bfd.info +0004178dcc5a2d50254f54f9ca7ebada bfd/doc/bfd.info-1 +ee5f7054e7e25a79d7c748ffbaf83d49 bfd/doc/bfd.info-2 +c0dcf8d06801e64d94a10e1b36ccb807 bfd/elf32-sh64.c +3f5def74504dc7c1041fb8a5e92129ba bfd/elf32-sh64.h +5344c27413152ec06bd5758c03ff0e19 bfd/elf32-sparc.c +19f878dfaadfb6080770e7b6a6fda1ae bfd/elf32-v850.c +568208c36e302a7543067ff3c912f286 bfd/elf32-vax.c +085619a0523ec49b741a0a69740f5a07 bfd/elf32-xstormy16.c +cbd74477aa0d34ffbbb4899a9b464f15 bfd/elf32-xtensa.c +ed57bd460ee2d4a61a5c445f280f295c bfd/elf32.c +e0abc4acea14de809f1dac79fe0645bc bfd/elf64-alpha.c +e7a6233c4ce3edd549eb0f3edd022ef3 bfd/elf64-gen.c +57dd6dfe24200a3805e56b038192ba0c bfd/elf64-hppa.c +fbf7f46376d56c745331fa9e25e19042 bfd/elf64-hppa.h +a618209156ba8d18f8b3f5b084850d7e bfd/elf64-mips.c +43cf4dee5b53fb37eba7da09e2c15b77 bfd/elf64-mmix.c +e89898b60ed34c8ab64871e23237b8ca bfd/elf64-ppc.c +16f5cffa79d09624ec3d26dfeb961856 bfd/elf64-ppc.h +d30e21349fa2f8da16d4dc65977eb5e6 bfd/elf64-s390.c +4937483eb68671466625dc8f8681182a bfd/elf64-sh64.c +d2b71d2e5c52fe5dc34572d57366056c bfd/elf64-sparc.c +65f166c82b9342fe91fb8412eeecfb98 bfd/elf64-x86-64.c +0df4bff9f99908d451625f14be3dc667 bfd/elf64.c +b1f33b4d5a4c137eb87216b322f40eee bfd/elfarm-nabi.c +68b78b6d8e1ec8c802c17fbcda6c63b4 bfd/elfarm-oabi.c +830469c13c89794aae5473da46704edc bfd/elfcode.h +a9adb9386fb590b64711de5171d959ed bfd/elfcore.h +9f9d828762a67edb0c3c9d53b075cb5a bfd/elflink.c +00d0b8a0438bfd866c4401957a967443 bfd/elflink.h +1a440c3d428972f41eb7c3aed175e11e bfd/elfn32-mips.c +e11a015870d22916b8ac2d760e70a621 bfd/elfxx-ia64.c +f48ef0a2235ce927f5bdad067530dea4 bfd/elfxx-mips.c +4ea9b73a32192a4a8853ae1f9957b451 bfd/elfxx-mips.h +daa35912abef252d7a06c88cc709f877 bfd/elfxx-target.h +5f9b71e52009091cb901280cbe42283c bfd/epoc-pe-arm.c +c9f006f05a9b9f4d6be5fa84dcad8b6a bfd/epoc-pei-arm.c +a05bd2a535bb4cf02f221ec9457b2bd6 bfd/format.c +eefe1c434d60657e776122f5c55c3d8f bfd/freebsd.h +9905ea394a339286cb593f88d7758727 bfd/gen-aout.c +5236b7eff1c5828c67db80d134ff2f66 bfd/genlink.h +663a6979bd331c91d1385445edeca7b0 bfd/go32stub.h +f8f22d70aba0ca01013719e50b137007 bfd/hash.c +fa6b45528f762b75af43bcacc6acd8cb bfd/host-aout.c +531b1bcee0e49314fce6cca36c2f335e bfd/hp300bsd.c +04bdcf12654495a35ac354c0d5c725ff bfd/hp300hpux.c +ade09540811efef1e31ad49819d729fd bfd/hppabsd-core.c +ecd4853d4923d82823d899f0b347bf3a bfd/hpux-core.c +57c936e8a3adfd68e7758aa598e8573d bfd/i386aout.c +5b01cdc5ee8b0e9cd3fa57cfa577d57e bfd/i386bsd.c +28ae231f375a6a503a0c3f82fab60b5f bfd/i386dynix.c +c91f2b6fb802a0bf53bcd57c3faaccbf bfd/i386freebsd.c +15c32e538d1a3d16670aad2de5564617 bfd/i386linux.c +0f869e062010b8d3eeeca4f38753f4c9 bfd/i386lynx.c +30cc7aa91bbf2d13677c1f72369b3f07 bfd/i386mach3.c +c5b5aff9afa6f984a1fc2b3f34f17af9 bfd/i386msdos.c +82991f62026cee0823a00ec99fffafc3 bfd/i386netbsd.c +176197175927b7790a70415b95e63d61 bfd/i386os9k.c +153bdc004a483472e76def7d40c1ae00 bfd/ieee.c +709689da143822546add1d89c869c9e2 bfd/ihex.c +586e6bd414ac178ab785a5f9965551c4 bfd/init.c +180c2cb199d2fc7a407f0b59fa1745fb bfd/irix-core.c +46cbfd585deee91db7dba527d5c0ce24 bfd/libaout.h +0a2d4b73e5f38776396a3f3597bdb02c bfd/libbfd-in.h +7265323cf6099483159852928d7b6fe1 bfd/libbfd.c +2ffd243d372a207ce661e62a0453b665 bfd/libbfd.h +9b9174f2cb9e5133f0deeee1a861bf45 bfd/libcoff-in.h +b4773f89004edf4e1dcf024e6c3fae8f bfd/libcoff.h +0d924fec5779723a72e46e715b8781ee bfd/libecoff.h +bfd2fb804a3974b4e5ced4a16c308396 bfd/libhppa.h +920cd61e1b6eef0bfacc3e6b1bf3057f bfd/libieee.h +ec8a33230f7f0be0d900d2589e63a330 bfd/libnlm.h +c9e76633b8cf7d2a676fbcc1aff5ad28 bfd/liboasys.h +1a35f51f7169ed649b3bfb7708c34e76 bfd/libpei.h +c021a4bf3e31a71731a1e9ac0d683321 bfd/libxcoff.h +825c25c05a5e7de721136b7b7301855b bfd/linker.c +a94e935b575e1815ef7af85f91d336d0 bfd/lynx-core.c +a00d38276fdf8f0a76eb6a1203a8d4ff bfd/m68k4knetbsd.c +6af8fc69de77ea2794e164ca76582751 bfd/m68klinux.c +1c7fc5738825df3c8f55547c24f0e692 bfd/m68klynx.c +f4e07f122ca03610fb6b9d76e2746dfb bfd/m68knetbsd.c +873908a5fd292c77ca7a29e01db780ac bfd/m88kmach3.c +cb4dbe2cce88b787643737cd05084d95 bfd/mach-o-target.c +2a6293df12f54ec979911547a1f8ee35 bfd/mach-o.c +ccfb3c1a456dd4300f25919f0d122f42 bfd/mach-o.h +5de4da6a9169effb512e6ba4d014d420 bfd/makefile.vms +b959394e47b356e8bf9e961ac5b1755d bfd/merge.c +4a47ee157c9cda06a4df2f8d3a271e46 bfd/mipsbsd.c +a53a4d0b7dfea8efc3c820a0a388f94f bfd/mmo.c +5971cd61d7c10702978519aa5ed41474 bfd/mpw-config.in +85bd791a2ac9c9d7c2bea1932665d568 bfd/mpw-make.sed +0a05a7fcb22ce5e250425f7492924449 bfd/netbsd-core.c +8528926a5dcc628f8c7b4a08b5e61f4b bfd/netbsd.h +1581bb81823ec6ac33abb92c51b7b74e bfd/newsos3.c +7a600ebb6dbaf147bdb8161b187a78a7 bfd/nlm-target.h +4e45b4706a1e6ff1bd060647ca0edabe bfd/nlm.c +44b970bb202376a27b0b2563fea16e68 bfd/nlm32-alpha.c +5566bd19ab252ad17a78307d30866b7e bfd/nlm32-i386.c +e05bbe04070cb3c7b5a44904b06805a1 bfd/nlm32-ppc.c +af4856cbf1096e3323103ab5d3d4d45d bfd/nlm32-sparc.c +ad09e68167b48df24f238e874a31a152 bfd/nlm32.c +7d6920efa240ddfe625a9d076cd6510e bfd/nlm64.c +9a7d23c9bbc084616d77314b70af7141 bfd/nlmcode.h +157552f266a8853bdbf87b7c98acf825 bfd/nlmswap.h +7d82893086041edcb2e9d5119d1d4802 bfd/ns32k.h +fcba40f08d811e466c0c8f56bcc1f3dd bfd/ns32knetbsd.c +cdb636036107872f6c4ed9c93db59f2a bfd/oasys.c +d9c18f6831463a22db0e9ea42d17bf1f bfd/opncls.c +64e6fd9c3810466bee8ae998ed68af41 bfd/osf-core.c +280633df6d7c82ef1d0aa89f49c8b6f5 bfd/pc532-mach.c +2b672107aa3308281b6a9d4eb5e379f6 bfd/pdp11.c +8a141c46ec11672e4c3177b0d1fc0a46 bfd/pe-arm.c +b429f4677696b2cd729ecc4dd616d91e bfd/pe-i386.c +b6316514027908b40a8af4eafdbc306d bfd/pe-mcore.c +598c8a8ab601080b5cae8ab42e82602c bfd/pe-mips.c +2408372ef3e1635e1f21849c2df91516 bfd/pe-ppc.c +4634b622d18f05d56e672cdef673dd72 bfd/pe-sh.c +c817336d8f353bd59f38d42140f91050 bfd/peXXigen.c +330199c7b8c4a19b30f2c587cc55ad5a bfd/pef-traceback.h +c870c1b73e15d45920b1a54deafce168 bfd/pef.c +7f525c89ec9a288a9d6b87fa3bb3e1a7 bfd/pef.h +5bd98afdabed67da15460a8a39bed305 bfd/pei-arm.c +cf2fd29cf4e9bc738f7529344c9e1a48 bfd/pei-i386.c +f387c2799ec662d304422d3e67cc364f bfd/pei-mcore.c +22db443681ead074ab0c5161ddf84b77 bfd/pei-mips.c +f15a63befa27efcdbcd3711ecddd89a2 bfd/pei-ppc.c +01f7c14bb6b07af2300c0d321ec8f823 bfd/pei-sh.c +45dd8c3c634f189b212b4cee863b403a bfd/peicode.h +630db51db4ebd32eda4736f14030ab01 bfd/ppcboot.c +310fce924b7b29ebcfdf690e30a2aaf5 bfd/ptrace-core.c +a39af63f63f1fa73a68d51eee08d6f0a bfd/reloc.c +a74f7d6ebb8def3697451372bac9937a bfd/reloc16.c +d774422a7bb83b8aa0433095dc97d304 bfd/riscix.c +2a3e4cae47c61a4584804ea2b2cae49f bfd/rs6000-core.c +867cfe30d33b4386af60d441a2f4d313 bfd/sco5-core.c +38f8ae87bb9a35c262457e00720a782e bfd/section.c +25a737999e92bd117e14b04d84f0ccb2 bfd/simple.c +5cb88edecb2ec76da025658e6b151022 bfd/som.c +9d67c54f60826e90cf939da4b6cbddf6 bfd/som.h +20770d513289ed2f47247910f7789f5e bfd/sparclinux.c +2261db74c28e00f78ce80025a0fcbcd5 bfd/sparclynx.c +daea7ae2be94e245530a7df8f7a4219a bfd/sparcnetbsd.c +ccca11062ee53332a665ecb74ae5434d bfd/srec.c +891289f18ef687556cab8f090331e3fe bfd/stab-syms.c +a9a86441cf4b994d4352f70251664c68 bfd/stabs.c +1ded054093de910d9786c62bc4fe8cc6 bfd/stamp-h.in +44fac4354106eea23189597728665882 bfd/sunos.c +6dd19dd2de9d8006d5bb8cfddeae791c bfd/syms.c +071010ad33a66b97d7f737c46ef8b2ab bfd/sysdep.h +91c7d336f9a0e2beaaf095cc2d8f50ce bfd/targets.c +53357a9b87dd158b90cf790c316fd438 bfd/targmatch.sed +28db0127ebb4ad457152f56ab5cef598 bfd/tekhex.c +00c3b5c6f8709ed54ae5b0d8da305f00 bfd/ticoff.h +cb6bdd284510fdc060d456b9eafdfb68 bfd/trad-core.c +ea8d625b4832344a89641e9b00cd9a2d bfd/vax1knetbsd.c +775c0abfcf0027ff641997024ed1a54c bfd/vaxbsd.c +cf93f1ed7a1b7cb96e2ae5be9c08d149 bfd/vaxnetbsd.c +01ed7ef4d31595c5d9c3f9d7d34de2c0 bfd/versados.c +cfbbe4bd708dfc28786ff0f3b9500dac bfd/version.h +ae350ae719e0b1452519a7319cca467a bfd/vms-gsd.c +baa6a7eb36fb2ab02df90d7f9748ab70 bfd/vms-hdr.c +e1b412047b23b9cb0294448e27e0f0dd bfd/vms-misc.c +3af8b9361012532efa66fe4390faa75c bfd/vms-tir.c +1c1d4b145a89457e8f6c9d30a9229ce8 bfd/vms.c +788714f4de9491b4665248bbd95458b8 bfd/vms.h +ed2169f763a33558e638735d281c3583 bfd/xcoff-target.h +2313eb7efbaabcbb0f15ac7522709306 bfd/xcofflink.c +db3a8b04e6d055712ab5480e68a16406 bfd/xsym.c +aeeb43cb5193b3b8d66b5feeb7a3c763 bfd/xsym.h +f0edc5b6ff0b89fd9805ff2ccdd56ab9 bfd/xtensa-isa.c +d99fd7072f0b4f4832333334bdbe6c62 bfd/xtensa-modules.c +74b9e8377ce5ef7f2ad8914ad5e1dd41 bfd/hosts/alphalinux.h +edf185d0ea2cb0350a58f4224a0d7ccb bfd/hosts/alphavms.h +70e1a59995604c3b804469fa27b92d94 bfd/hosts/decstation.h +7f90b6f7c21bcc67525386bdb9399540 bfd/hosts/delta68.h +5a75f0a8518cdf994c6837632317650a bfd/hosts/dpx2.h +6d9ebd0f91f9085690638821e2ce67e0 bfd/hosts/hp300bsd.h +50735617194ee653f1cf99af40a7dbc9 bfd/hosts/i386bsd.h +c3d90b1a06731c814d89371f91583bb9 bfd/hosts/i386linux.h +90fa9751fedd9623f399b8bcd6a646b3 bfd/hosts/i386mach3.h +09a90ebd4e56bce95e72a93c6274997e bfd/hosts/i386sco.h +1d13cbc7201d1b35dfd2353027122d33 bfd/hosts/i860mach3.h +779197139aaf874e61ef9339cdf7df30 bfd/hosts/m68kaux.h +c40f7966cbdb0fac0b4366c9c61eac06 bfd/hosts/m68klinux.h +2563c4d1fef8234619b1c2007dfdaf90 bfd/hosts/m88kmach3.h +8fbd4bfd38ea85aeedac03e1962242dc bfd/hosts/mipsbsd.h +f61dc4a9a9a665ab9fba6861214bdea3 bfd/hosts/mipsmach3.h +d4e865701ae3a5149a05ff92b2542e94 bfd/hosts/news-mips.h +2a46cd81291f56275932a241e022f567 bfd/hosts/news.h +21af1454d516fbfd996f6d6bc3b8db9b bfd/hosts/pc532mach.h +2440e7cdd4e85ead6516650e1329bd0f bfd/hosts/riscos.h +31fe7c1b8aaaf0174c5fe2ef83298ca9 bfd/hosts/symmetry.h +627775bbea4f1d59b97edfa80e81a259 bfd/hosts/tahoe.h +1214020ec5befbef1dda50900deb4740 bfd/hosts/vaxbsd.h +9b476271b3bc5815a37f6b887c092090 bfd/hosts/vaxult.h +9b476271b3bc5815a37f6b887c092090 bfd/hosts/vaxult2.h +9783b7a5b508bdb3cbbcfd352723873f bfd/po/BLD-POTFILES.in +2268acdca71084336f94fc195d4549ea bfd/po/Make-in +d4344dee14c296d35fe704953ffe9fa1 bfd/po/SRC-POTFILES.in +4f233961e16da13e8aafc02a5d6a5439 bfd/po/bfd.pot +3aae148fb9018854c2d708a4ef931674 bfd/po/da.po +4f5a10257ac1b0141951e913ec332bbd bfd/po/es.po +20247f61a7fd04810374ba60aef37bbe bfd/po/fr.po +73b8653e71ee27028caea3884743f7de bfd/po/ja.po +8fc4e95db5a00f800bc30c65a30f8a8a bfd/po/ro.po +dfe82e26118652583a47b8f4771e7e1c bfd/po/sv.po +95bcedd50b1016d3de8c9f543c6b2bb9 bfd/po/tr.po +759dbab8d78320662dd19d5c9dc5bfa0 bfd/po/zh_CN.po +35a4480c592584b75a828838b20938a0 bfd/po/da.gmo +64ce98e2556430a9301dbe0c1c6caba1 bfd/po/es.gmo +e1d625574ad79a3927294e3689741aa3 bfd/po/fr.gmo +95a86001b071eb80f4745adba10a289a bfd/po/ja.gmo +844c1ea598f9bcc47870ecf122b15e7d bfd/po/ro.gmo +b04862da8728ddf3c4c8a45b18ee35f7 bfd/po/sv.gmo +495dc4f4a2e82ea81d7226370e07294f bfd/po/tr.gmo +ee7366f8bf4f4bca0d82e3143893174d bfd/po/zh_CN.gmo +9866e9425ea31221e3dc5d4410bbf5db config/ChangeLog +1eaed99306a232c1f2579d48c964f565 config/accross.m4 +6c7b0890dc93bdd97ec3e90d8436b384 config/acinclude.m4 +a1b1540fda3bb91674c5ac1ed659b9c8 config/acx.m4 +ed78e916ef1ee530d9e2f35765cbebd8 config/gettext.m4 +9b65dc7f50a7134932aa278ac0378703 config/mh-armpic +7b266c44c8a74cfd3aa47c7408b1d9d5 config/mh-cxux +85f96b330d9ccaefa3b09568acdae202 config/mh-cygwin +1a368defd90f5893cad171786ee20569 config/mh-decstation +8b594c219d32fc33f367d70ea30239a1 config/mh-dgux386 +625bacc09b9992290d94831bd7506bd0 config/mh-djgpp +9b65dc7f50a7134932aa278ac0378703 config/mh-elfalphapic +9b65dc7f50a7134932aa278ac0378703 config/mh-i370pic +740855ebe34cb2d01fba1f1bcb4264cf config/mh-ia64pic +9240a2b84d379e3feff49d8311072dc7 config/mh-interix +4025142ef79311b861a05eed3e417a4a config/mh-lynxrs6k +740855ebe34cb2d01fba1f1bcb4264cf config/mh-m68kpic +d2eccbc26e9ac85d25fad721ba9264aa config/mh-mingw32 +1970cc16887b91d667b9bbfb0f6e67af config/mh-ncr3000 +fb9d7448a6dab87d4da003658fb4d66d config/mh-necv4 +9b65dc7f50a7134932aa278ac0378703 config/mh-papic +9b65dc7f50a7134932aa278ac0378703 config/mh-ppcpic +740855ebe34cb2d01fba1f1bcb4264cf config/mh-s390pic +ecf7a936c35e3c5a0e8d2b0721243b85 config/mh-sco +e4353fd5127f79d601d85fde3925ac76 config/mh-solaris +fa84a282ce7cd6876d1eac368a31a368 config/mh-sparcpic +2415a4da9726792701f226bdb0e5ac3f config/mh-sysv4 +2415a4da9726792701f226bdb0e5ac3f config/mh-sysv5 +740855ebe34cb2d01fba1f1bcb4264cf config/mh-x86pic +3755b5b077053b5de54ff0f781ca9295 config/mt-alphaieee +96289d06809692c31d71e69c4bedb6d7 config/mt-d30v +945f54294ca11fd14c1aaaecde3ce7da config/mt-linux +2067ce86494ccb89791fe169eee8c198 config/mt-netware +5aa8f75c6588d513ce199e2e44c206e2 config/mt-ospace +9c67d61b28da389337cfaba76ac581ee config/mt-v810 +12b3030d3d59526c374c15af4f5944dd config/mt-wince +b963319bdff419a7b32cb107b047433d config/no-executables.m4 +d3cecf02bb97035177818aefbb0e0833 config/progtest.m4 +b1f75000fa90c6bd41148c49280e5dc6 config-ml.in +dd4451f9cdfc36cdb86703965f758ec2 config.guess +d41fc4b87cd95b533ca5abf5b4254969 config.if +6cdae8120da06ebd9981c7a5a813550b config.sub +ba0e4f8aa35567f8f24cddaabf3a854d configure +23d6f11e4cfb005d1003d2d9f5cdcd73 configure.in +62b488e5f959e052d18496e90786ace0 etc/Makefile.in +213e80930c0be010bb250612af54775f etc/configure +e9b828169fe54bf6414ec1f4376af077 etc/configure.in +82ec227ba1633285a14da92fc105067d etc/standards.texi +93a1c838358f13ed5e4bf98d07a173a4 etc/make-stds.texi +ad362ccfa3df560286703d75b5074e3f etc/standards.info +6614900e6bd390888e699c2cb431fb23 etc/configure.texi +2586359a28271600453b7485314dfcbc etc/configure.info +a20b40a0a5d3282f6a97c627be1e38c6 etc/configbuild.ein +570746cd93c4dae506cf2a6153a2a1b3 etc/configbuild.fig +f97ac2d5e05edeb335b73f8b6beef581 etc/configbuild.jin +b2851bb6d77822adc89ffc6d323b5fea etc/configbuild.tin +e67b330b1ad623f1bd3850483cd4666f etc/configdev.ein +c1f7c41d3e596256ab5f5f933a66293f etc/configdev.fig +8e14386548b8da4c5072aa2abea55886 etc/configdev.jin +32fc10cbdbf679bd0ffc8857cf069b43 etc/configdev.tin +97ca8794237456a3774a2d7672b74076 etc/fdl.texi +bb43814657829ae64a1f39d540a262fa etc/texi2pod.pl +8463bc5509db00792972ec6d4773003d gdb/CONTRIBUTE +0636e73ff0215e8d672dc4c32c317bb3 gdb/COPYING +1a6967f096f4e9bf5a6a3fe5961744f1 gdb/ChangeLog +42b9f7c51223e595f66c2210064be682 gdb/ChangeLog-1990 +8f5a03c189727d347a330548f3ea9c98 gdb/ChangeLog-1991 +51d2fa6ce8618d5c87150c7c576f1f6d gdb/ChangeLog-1992 +f971d36e35ec0c3fce64b819d7891f15 gdb/ChangeLog-1993 +526536cf30b137dcebfaaa604fa55615 gdb/ChangeLog-1994 +e5e589fe4f10abb8957a8c2e4cddb7f8 gdb/ChangeLog-1995 +349b188907736d3ac349e30e509f4e37 gdb/ChangeLog-1996 +90e56dea65beb67443d6c83cbc5fed7f gdb/ChangeLog-1997 +5ec8a13039f178b86804ff04e7cbdf99 gdb/ChangeLog-1998 +5052b57de2fd8b3515777bb814bcd394 gdb/ChangeLog-1999 +da71c479b68a4d95a79d36640b93c9c3 gdb/ChangeLog-2000 +c923fbcaa47240f82d7ef756c59c87ba gdb/ChangeLog-2001 +ac17bd8138ae5a3ecabcc1258cdc28e0 gdb/ChangeLog-2002 +5652294b4864dfc7241196198f4a8ad6 gdb/ChangeLog-2003 +1f68d3272b33b380724fe731f1716f7b gdb/ChangeLog-3.x +3ee36d9037c272d3b4f8a7c79961d791 gdb/MAINTAINERS +92d82043d4463360d4c7687cd5ebc83f gdb/Makefile.in +61e0eb782011ddfe4824bb33160fc618 gdb/NEWS +79802c38e98a7dd45ce93d9310655fb1 gdb/PROBLEMS +431713a59d8502901420ff54dc93bdd5 gdb/README +d3ac054697897095f9382b64cb2ad396 gdb/TODO +42b66b05e536cb1d1cd2a9b46005a64b gdb/abug-rom.c +5c083e811564a1e6bad18954c89f60ac gdb/acconfig.h +b9810659c00821aef3adeea8e0e6b45b gdb/acinclude.m4 +343bbe4bc8a62c781b67bd120c518a7c gdb/aclocal.m4 +8d8cf6b043079aff553c873c64088b86 gdb/ada-exp.y +0924104c3a07383c9237c9a42b54f37f gdb/ada-lang.c +abeb4fcd908e052c60f8329227fca1e0 gdb/ada-lang.h +d18719f7e442c781dead5e18311f71fa gdb/ada-lex.l +f74f099fc13ece2e1ca0edcde595948b gdb/ada-tasks.c +779d537bcd45814df5e9b8caff595802 gdb/ada-typeprint.c +67c35223206a86c590a1a2b1c5f481d7 gdb/ada-valprint.c +300a07de612e26f163378c5a43ce0c8b gdb/aix-thread.c +169985b8ca2c692705e792ed2509b2cb gdb/alpha-linux-tdep.c +6ccb822b40ced578f9a0338774bc7451 gdb/alpha-mdebug-tdep.c +3314eab39eb296c34337d42467101d57 gdb/alpha-nat.c +11f936f89f001248ef4ebbaf3083a7ed gdb/alpha-osf1-tdep.c +0968bfe12c4657bd9b4ceb1aa1431518 gdb/alpha-tdep.c +e7db74fa2ed0302b0928e29b68274a52 gdb/alpha-tdep.h +af00914ee90f724a36cd4402c8ba3189 gdb/alphabsd-nat.c +aad2b19c36fa65173adc7b6e50756fc8 gdb/alphabsd-tdep.c +911ada28badf929d485cc5e4ba03e8f7 gdb/alphabsd-tdep.h +8aa4f09d06c4e8138f0eaa340c700652 gdb/alphafbsd-tdep.c +67cc33cc7ef8d7374a017f24ef7032c6 gdb/alphanbsd-tdep.c +26b6eb2b6f053aad600a2d211034982d gdb/amd64-linux-nat.c +d8989251a8151730d86df30792797a4c gdb/amd64-linux-tdep.c +9a61ca201c22e5c4db359e0892263257 gdb/amd64-linux-tdep.h +f382150932d298dbc31c0ee4f36a1921 gdb/amd64-nat.c +d62df996a5b10c3971ca31533ac4b64b gdb/amd64-nat.h +b79fb3c9f6ddca0352dc285721c99886 gdb/amd64-tdep.c +96d3b45edbccb5b14dd27b589a85a430 gdb/amd64-tdep.h +2238f88d8163b0d370ec1d3318120fba gdb/amd64bsd-nat.c +9988606ccc44723efa802889e862ec0e gdb/amd64fbsd-nat.c +527ac8ce55c96ed9131f9a27f5ad8bf4 gdb/amd64fbsd-tdep.c +44610b0d73c81e3e0b17d88f09d4b0a7 gdb/amd64nbsd-nat.c +942e5a6c76a550fadb39180fd66c45fb gdb/amd64nbsd-tdep.c +8c7030f92c0feb837e19e2ad0c2166b6 gdb/amd64obsd-nat.c +85a23a8c5279fa33cc17bd9c9a37190a gdb/amd64obsd-tdep.c +d947a07a440c6946dfdc872eba2d2b72 gdb/annotate.c +080a525c2bda6e56dfa98f8aaebc7eb9 gdb/annotate.h +496fb22cd6c9af90a40c35452bbcf92e gdb/arch-utils.c +a60210afbe81bac521522d2b767fa04a gdb/arch-utils.h +d28d2abc6d1c5bba1488e36ab027f708 gdb/arm-linux-nat.c +9ff54a9d3f32f1899d7f4485620b7f87 gdb/arm-linux-tdep.c +5552cb3bfaba9c9e042a1caaf5b722a8 gdb/arm-tdep.c +ffc980e6bff20197fd797db961026843 gdb/arm-tdep.h +24a8f7f0beb33cc0873360fc6815f7b3 gdb/armnbsd-nat.c +907da3174dbb366e5a0c547986bac6e7 gdb/armnbsd-tdep.c +8b99251c0a8f39e7617ab95b4866d03b gdb/auxv.c +d36b30e423736bb435b84f56db5e7a1b gdb/auxv.h +18ae66b72bfafc474f3e864127c8d894 gdb/avr-tdep.c +918dfebcb630956dfcc8a7d7495a371a gdb/ax-gdb.c +50b7d2540035e5b1329e7f76ec2167c4 gdb/ax-gdb.h +39ce9c9c59340691bf77fa7c2c72b4da gdb/ax-general.c +3e6df9c00077763250cb7c4c38b50ad8 gdb/ax.h +a10ead74084b65b4b0056d5bb80341bc gdb/bcache.c +51af669999ec737922b29d63a2dff65f gdb/bcache.h +fcaf8094d30feefbadaad17974e8595d gdb/bfd-target.c +c8da03b16cfd091e9f0cee9a71f93297 gdb/bfd-target.h +16cb12116f5ec56c2669ed80144fdc9c gdb/block.c +21a82a73866c3ee1264cc17bd9aa8a24 gdb/block.h +05ba3cd3246197775b22bfb2ee352c29 gdb/blockframe.c +8504522d395f5ee8c98aafcee7726994 gdb/breakpoint.c +35a278024cda3db7ec8e0b00e6ceb929 gdb/breakpoint.h +9584e70bf9fb8227eb494dcdcc3f3158 gdb/buildsym.c +714c8ef6870dde58afac072509200ec2 gdb/buildsym.h +f08076d72a8857b31489513946dcd38a gdb/c-exp.y +0471fa9776ad48757851bb7a279a7cd4 gdb/c-lang.c +b0c37bdef2805d541c08d7528fe4c441 gdb/c-lang.h +121e47fb1bf53c273c6eef1c62aa40fe gdb/c-typeprint.c +bffff67b36ca862c51d0ffbef4e99a67 gdb/c-valprint.c +78da04b3aa3a9010d304051aa808b00d gdb/call-cmds.h +d75aa86cecf814fe9f6ec4a81afbf72c gdb/charset.c +7760560f7035893b469ff32a114c8e0a gdb/charset.h +edfd5b651119cf3cddc2183f9d0b2f73 gdb/cli-out.c +a9f3eff8bc4baacbbacaa2cd39bad701 gdb/cli-out.h +ee81ad6502cad17f69623d1b4ed3f8cb gdb/coff-pe-read.c +2dc71de29a7af3cad46244b3b2d88003 gdb/coff-pe-read.h +fe442680d8a2a9d5d0432ffa6139314a gdb/coff-solib.c +64869f1717013ecd514776434c4c02d0 gdb/coff-solib.h +3984c093c64993293dffa24aba37979e gdb/coffread.c +e02c5514545c211221634194c5aa9d65 gdb/command.h +aa8c2b31fbb7d3eb27b04520cf14e558 gdb/complaints.c +bacdc6e898b4a677ff1123b76df1d6d6 gdb/complaints.h +f622b3747d483055dd47962451a44414 gdb/completer.c +90142ed312eb420707d50ccffb2473ac gdb/completer.h +9e399235f2ad0502627ca24f94cf3af4 gdb/config.in +69bf2ed0ce9a6b34872478585c219672 gdb/configure +1bc4fbbae4111ce99ed0e7d3308daae7 gdb/configure.host +c7c1387d7b3c9f02b663912f9dae763c gdb/configure.in +b910553983c5c3045b59a1bb754572a8 gdb/configure.tgt +273edc4b2f644f8bb24cc2b3a34a7df8 gdb/copying.awk +1b2a827eb0fe30e3019f308f1353997f gdb/copying.c +d413a951fd3f4870207304b06cbe5703 gdb/core-aout.c +d29d0ea85c054719b0450da279a1a447 gdb/core-regset.c +e37f359055bafab66b0312cdf05048b5 gdb/corefile.c +02c2cafa9a9fce0ea1b1d0ab1a162f8e gdb/corelow.c +e56628e3066834fb34b59f9a66d7fc36 gdb/cp-abi.c +afa9a50902898ca67d66435238c7d79f gdb/cp-abi.h +83b244ff7b89134d81732dd79296a431 gdb/cp-namespace.c +921cafa61dd4ca25acea0463499e3879 gdb/cp-support.c +3a30a6b6fdc6df3a0218c2c2bd2be92c gdb/cp-support.h +94bfdc0a762a300805427b8e3698e7f3 gdb/cp-valprint.c +85fa3b16a93fdb081021f9588147093d gdb/cpu32bug-rom.c +6a43fc33ed0a9c64a0c925e0e6a246a8 gdb/cris-tdep.c +3fe0a3d794193876e00e2abbc2ec0026 gdb/d10v-tdep.c +92ae08e33851a4045861b7d9bfcaf17e gdb/dbug-rom.c +bcbb7a24b1e8eacc099458e062c23f64 gdb/dbxread.c +17727ead88c17f8c77f56bddc0b5a65e gdb/dcache.c +907d3c67a5640d8d89ac6297256894ed gdb/dcache.h +57a8a71605ae19ab0dcc2615bf95185b gdb/defs.h +6a03fb71e88ce73a42b32052dad06839 gdb/delta68-nat.c +c9402684f3c31e30eec156fcfad53820 gdb/demangle.c +44e93797a20f3781c685eef37fde7657 gdb/dictionary.c +c155ec3df44742ccd79316aae3d48697 gdb/dictionary.h +05c146620d715addfb054b42e60468aa gdb/dink32-rom.c +a382505cdad0d4a3f5ffbeb8c888c4b7 gdb/disasm.c +ae50c8ac449fae0943d5464e4c400b10 gdb/disasm.h +638cc5f08980215141b95ce66e94d0d6 gdb/doublest.c +6a781094fcd994ee60943758adb07c8b gdb/doublest.h +b7a1d94256a83e22f8136e91931ea127 gdb/dpx2-nat.c +347976a1e28c6c46a6631cf54054b9f5 gdb/dsrec.c +3e82183d1ee94c17cac69852f334ecf8 gdb/dummy-frame.c +aae5b04b2db47e36211509cda09eb095 gdb/dummy-frame.h +fe63f2c1e0ace00ef3257758926a8f18 gdb/dve3900-rom.c +b7d5cfeabb5b76e56d9114d44de8f1ab gdb/dwarf2-frame.c +95350d57a9d89084356ffae43165cb1a gdb/dwarf2-frame.h +6d97a1b7597a3d5109a54c6e8d1a23d3 gdb/dwarf2expr.c +75ebfde2fc4299da200aaec76bab66f6 gdb/dwarf2expr.h +afbce3c417497992453f009d6a6c0eab gdb/dwarf2loc.c +85ac8fa77b535fbd2f309f861a5dc163 gdb/dwarf2loc.h +3acaed8ac44beb0fe1d362ca42d87a6a gdb/dwarf2read.c +3b3788b7f1a627ea173adbe2eccffffe gdb/dwarfread.c +db2c46c8c88dc10b52feebc4cf614c47 gdb/elfread.c +f572575eb8f948101aa5b8ad18536f25 gdb/environ.c +49fac9ef419185b288a708448101c3c5 gdb/environ.h +26efb41a66c5cea87a3cf3eb016cd21c gdb/eval.c +c65ecfdd1c3dbf513a8f8f1a88151a13 gdb/event-loop.c +bddeb19b9f2738c6412b19e218e26ada gdb/event-loop.h +2480d54e82c2abbe38cde78c86a51ae3 gdb/event-top.c +21a0616517901e9dc9ef3b95143f44fd gdb/event-top.h +1f6b545be0b6822eca215d0b5f1edfc2 gdb/exc_request.defs +42b0d1c067db44fb387de7719b64e0f1 gdb/exec.c +f62166575e2c70ed616b8cc701f27061 gdb/exec.h +dd780e5e580e52376bc6eee9ba089d18 gdb/expprint.c +24fe7e83215c416f15704f97c3b3e4d0 gdb/expression.h +d950d512defdfc28c6bf7d070a243b5a gdb/f-exp.y +f3a3773cde05de5b06b97158272be5e6 gdb/f-lang.c +114b4d60638829bbea5c8335eb6d4d08 gdb/f-lang.h +7155843f94f03fa187ed1cd8d4440ae6 gdb/f-typeprint.c +63ac2450beec2e1b316fb6ddc69bed55 gdb/f-valprint.c +2482b24563cfc7556a020a44b7ab89c1 gdb/fbsd-proc.c +d65d48a20de6af0c568f859577c2acd9 gdb/findvar.c +b686aed81807a8bf4ac318ed9184b728 gdb/fork-child.c +ac9d1596eab67a46021c0732cec9fda4 gdb/frame-base.c +3caa2317e7af9f690e0bb68c6beed9ae gdb/frame-base.h +bb7cf84507c99d2b91b62fea93fe9d07 gdb/frame-unwind.c +f3a610ae320f9425f477cff2b5bc7044 gdb/frame-unwind.h +4d578eedbd85454937445665fe6b5474 gdb/frame.c +771270e6961d4f26fed2d3f8d2f818cc gdb/frame.h +984455d92c4b8ca102ef881fbb5abfb9 gdb/frv-tdep.c +0515c04e14b22a47bf808d29d8eccd0d gdb/gcore.c +9cde0107eed168d77312fa2def688909 gdb/gdb-events.c +21137e686b6eaa784b595c8b62a01928 gdb/gdb-events.h +60f9576b88f3b5c8ff867cdad5016615 gdb/gdb-events.sh +c2f5f21027e618072b482a31389db3e4 gdb/gdb-stabs.h +cf3fdf014a0f08833a0a6d7ae4c28a5e gdb/gdb.1 +354ff171a08d2f10cca6985ae3da2239 gdb/gdb.c +9198f7b1807c968098814aa2a3901aee gdb/gdb.gdb +21fd8c994041d89aa5d0ad5f6709097f gdb/gdb.h +a13266ccde3d767d10865cdc53dfbb85 gdb/gdb_assert.h +bbe3560e3f9e0593a2607f2a0e6e9b5a gdb/gdb_curses.h +1c2833d25129de84f7bc6d3002d6ba3e gdb/gdb_dirent.h +bd1f7513d1ed0e0a6edf94c2f8ceea31 gdb/gdb_gcore.sh +874997c5f40dd0b01aea3adda5ab511c gdb/gdb_indent.sh +060abcf7a16e4987b4a67be040993f77 gdb/gdb_locale.h +f93e5f98bfebc719a6936c5fc0547e8c gdb/gdb_mbuild.sh +afd4a770044ff9bfa7c94ce88ec3fd70 gdb/gdb_obstack.h +4a59bd462fe6287169b72c6dd0698760 gdb/gdb_proc_service.h +84d0de1de8183237a32e8b0cc1e2243e gdb/gdb_regex.h +99bc97996397a191cdb39c97a0c0e0d1 gdb/gdb_stat.h +0ad71a497d1fafa44f09c9b8b5b73180 gdb/gdb_string.h +aec98c443c614bcf7d145b601446e45f gdb/gdb_thread_db.h +1ec38b798feed7efea6231951fee1a50 gdb/gdb_vfork.h +170beb577d78482306f4d3457a8f2d2b gdb/gdb_wait.h +769abe174e2564863bad3a9717d6b2d0 gdb/gdbarch.c +11de6e151d7d0e2afeeb9acab1b78fd4 gdb/gdbarch.h +17563a5995e010a8e30acd1ff32ac0cb gdb/gdbarch.sh +aad6218245419fa85a80d2ff66610491 gdb/gdbcmd.h +f889ab1048a9dbcf888f2d0bf7d760ee gdb/gdbcore.h +fc3a24041b070e4d007c5847e3ce3b69 gdb/gdbinit.in +03d2757e017543b63e199a7acf020b44 gdb/gdbthread.h +8c2277d74f1af71937df5bc3dd85af2c gdb/gdbtypes.c +3ce6f93cba59430b2cbe20f2468bbf4d gdb/gdbtypes.h +a36a62dde42f59c47ad94c85df72959d gdb/glibc-tdep.c +d20f09fae4a5df7ebaab2d15479517b6 gdb/glibc-tdep.h +0a150bce76ed7ff1c62133e2ee7ee4fa gdb/gnu-nat.c +4cd514c067cb6d8880da54982c095420 gdb/gnu-nat.h +06549dbf519eb86a578c86336d0b6f91 gdb/gnu-v2-abi.c +f4e12a18e9f90a71bdcfaa51a3289d5d gdb/gnu-v3-abi.c +e90212e188e5f2b0a1509fefc2653fef gdb/go32-nat.c +0fc1faa3a7f5f967c3b89fc9a2d2212e gdb/gregset.h +54db1957245091eb1a96155d087dcfa6 gdb/h8300-tdep.c +826b2d1a6bf4c146254cf4531c37659f gdb/hpacc-abi.c +12e30c5c3db3ae0cc433d148a43d3d39 gdb/hppa-hpux-tdep.c +df75f02335289974396d319ecada4749 gdb/hppa-tdep.c +d62e4755fe9dabe0ef0dd0ccba827905 gdb/hppa-tdep.h +c28ce8bd32b2a2dbee2c63fb5ac62cd0 gdb/hppah-nat.c +99b837b524cd3a7b45b7ad585f0f1838 gdb/hpread.c +f501f3dbfc07b203e34a6de331034b09 gdb/hpux-thread.c +06e140e8d95525e8b8da2d139729a4ac gdb/i386-cygwin-tdep.c +c80d8f61d9bf860235e84b600907d964 gdb/i386-interix-nat.c +eeaae0c3595f010dbcc4d76f6fbf23d9 gdb/i386-interix-tdep.c +d5d90be62057c0a6338751e203e24793 gdb/i386-linux-nat.c +dc79662e20e9d19e135809e00764f8c5 gdb/i386-linux-tdep.c +a10884afab61969fd0bb9f650614863d gdb/i386-linux-tdep.h +b652ea6f206738d14681ce628b36555b gdb/i386-nat.c +f6b4f006e51e02b379ba3a66ef36faf6 gdb/i386-nto-tdep.c +678fc40ff8037830756f0992250dbe6b gdb/i386-sol2-tdep.c +2ae1192deecd340023c63facbc29575f gdb/i386-stub.c +a16f64889070df1c4c9eb4cfe4f59540 gdb/i386-tdep.c +fdc1bc51c796d26123a3002539b3bb43 gdb/i386-tdep.h +d301feaeaeecd5fd86144eb4992cc408 gdb/i386bsd-nat.c +e5fdfea78b74261dc52e1159619f45c5 gdb/i386bsd-tdep.c +ef6a4ff12d7339e8f88545199a44a9a8 gdb/i386fbsd-nat.c +bb4d8fc6b41f67597dc83e51197d62ac gdb/i386fbsd-tdep.c +1ef9a1c264c6f4d9d2d18faa0830692f gdb/i386gnu-nat.c +75fcd1cb7bee95046fb866528a48765a gdb/i386gnu-tdep.c +dd0decb51a6e9467e960ab17fb06ca88 gdb/i386ly-tdep.c +a03aa0d03135aac616822a40cb6c26bf gdb/i386nbsd-tdep.c +bb15cc507f5f009b1427b2ce0c931884 gdb/i386obsd-nat.c +307f7aeabacb280dc061aaede78eef4f gdb/i386obsd-tdep.c +9ec28d7590a9c374e709d46e464b9434 gdb/i386v-nat.c +65b54ee8f84e3a9afc00b95a53e2396c gdb/i386v4-nat.c +c69f606c016afd8bdff0f09557de7216 gdb/i387-tdep.c +f6c8381c090fd4c289cf09dc0983387e gdb/i387-tdep.h +f488fd50068bba1f1b91df89a3a99e8b gdb/ia64-aix-nat.c +6cf1eb85fa9d83629ef934c30ff904d0 gdb/ia64-aix-tdep.c +072f3e408251636827f2723f2b8e0eec gdb/ia64-linux-nat.c +a1fbb140749309bf29545ace3b471c1f gdb/ia64-linux-tdep.c +e19155f0dd708d987c7e6b69b5a399c1 gdb/ia64-tdep.c +1bf6328448b1313dd8ebab710ba31d16 gdb/ia64-tdep.h +3de10d3601f67cef85b449e82ad0a443 gdb/inf-loop.c +96d9de3ee8d6fb1af3195714b833933e gdb/inf-loop.h +6678f5c400a7022c73f721bc5c0209ff gdb/infcall.c +28d3925d02b4770c801f2beb106e90b1 gdb/infcall.h +3fe1c83f4a6a0b3d561861ebfb9cca76 gdb/infcmd.c +995b9bb47c5596d16bd225cae0029a31 gdb/inferior.h +99ab08f0f52ec838e35b04731056ee3a gdb/inflow.c +2ad0d8045158a16f23791288757b6c37 gdb/inflow.h +2391ecd084c5ecc588cbebacff721544 gdb/infptrace.c +bbce9f9d3cf52c89bf86a945bc4e9698 gdb/infrun.c +ed57f2a6a77f1c9eab42e00fed1100b0 gdb/inftarg.c +2c5c88bc6ce03d1412303d769b2c8245 gdb/infttrace.c +e75e773b3770b13462872245d00b9dc9 gdb/infttrace.h +4a40492bb34cbfc2a38d8d1cf0866259 gdb/interps.c +8a206faf1ea6622b793f4b0400227ad7 gdb/interps.h +392869faf877bfa089605f270d988257 gdb/irix5-nat.c +865b109e2412c8f1ae6c9252db3ee355 gdb/jv-exp.y +2417ce41bb1ffdcad7fc00455d3fc70d gdb/jv-lang.c +4adf0130b26f3a78f1ee7b24077b4afa gdb/jv-lang.h +1e66971a543ffa60d5fa1e6d80204b0e gdb/jv-typeprint.c +cf88df71a2f52be4c217f2824d96aa32 gdb/jv-valprint.c +a7726a98a2faeb2348eba1c9ef21aa37 gdb/kod-cisco.c +78ad6bd72f281062072ebd5c6d3ba7d4 gdb/kod.c +42348651a6ecef51134f250d60355f83 gdb/kod.h +93522420b27deef6030553c85a6737c7 gdb/language.c +aac3091c153a374ac87d74b346f93080 gdb/language.h +41616334b4883b0c7fec4920b1e91f05 gdb/libunwind-frame.c +d069e6348ffadb62bc0d196fc110310c gdb/libunwind-frame.h +fe88cc70b185192710fa7e58971699e4 gdb/lin-lwp.c +c7dbfa86fc447d387ce5483563b54ec7 gdb/linespec.c +c356ea97db57180abed480346fef1d40 gdb/linespec.h +5a80346cd00551ad30abe88c8dfd3f56 gdb/linux-nat.c +a3035094953016d63e94355efc232720 gdb/linux-nat.h +3383c4bf55250ada0b3cdb8cc26584a4 gdb/linux-proc.c +2e2349fccd86fd34e59f97a5de48a190 gdb/lynx-nat.c +14a3cfede2d11ff5fd90722310523b92 gdb/m2-exp.y +380c2bbce86e0dcf89a4496d2be7bd26 gdb/m2-lang.c +c14f85068d027cb2ef715a4c40699d40 gdb/m2-lang.h +ac8ebee0b47fb44330310532c3bdecbc gdb/m2-typeprint.c +b887d0e70650a9640dbce0eb719c92d2 gdb/m2-valprint.c +bdc88c73de42e1700edca8119acf3297 gdb/m32r-rom.c +250bff7fcef5fcafbefdd52602b5f627 gdb/m32r-stub.c +5c501304f5022c2e9e15e53225d8d635 gdb/m32r-tdep.c +11d584c8e4cf984dc998fda794575be4 gdb/m68hc11-tdep.c +192582fc2dac4ee1295f2703b4534e4d gdb/m68k-stub.c +1303ab976677de3029f5cc810f6fc6b9 gdb/m68k-tdep.c +74c953235236917b262eda77bddeb565 gdb/m68k-tdep.h +7479f3854117994d44d55ed2f25b4c99 gdb/m68klinux-nat.c +a7d30fda1cd80917f19dd204b12c5c26 gdb/m68klinux-tdep.c +7b106221e514d57c7cc8c934c3a6199e gdb/m68knbsd-nat.c +911f50b4fbfb86a77b2412d53c71f204 gdb/m68knbsd-tdep.c +910706b2cb79e83c456c7047c625ca79 gdb/macrocmd.c +823260ea0987d63072a89dc77f152b9f gdb/macroexp.c +fb789cac78fdadd513ca2b7fd37f392a gdb/macroexp.h +d421cb80b3a850b83446897c2d14c592 gdb/macroscope.c +04bc33d129fd0e9d4c9dd0aa29bb7585 gdb/macroscope.h +90941f96f5507924a5154c75233fd91f gdb/macrotab.c +7f5e5cc28b9d115b00b05215909dad67 gdb/macrotab.h +c5923481fc1422789e94037af862fa19 gdb/main.c +61bf476ab86f94245f3db2a7963601a0 gdb/main.h +707ce82520910f2a321b1cacd3ac4495 gdb/maint.c +fd5d2c5aa8fa47de798cee22d53fb0d4 gdb/mcore-rom.c +c634aa9040f4f3c88bc173dc5d32c092 gdb/mcore-tdep.c +eb1296971c86407dbd96b7fe6cf56ae2 gdb/mdebugread.c +cfafa5d41facd4af0d5fd3378eccc74a gdb/mem-break.c +0411a61780dee4de28b74a4b0a7d2a84 gdb/memattr.c +d928e3b5e40aaacbb36ba05218c4fb50 gdb/memattr.h +566d19c75db1535d81afac237fda7aa7 gdb/minimon.h +a4fb9904ebfc7d2d5fa8624f792f1756 gdb/minsyms.c +774b93894f4964d83ab49ee0d481216d gdb/mips-irix-tdep.c +f1382933780d5b4fa14c5ac5601acdd7 gdb/mips-linux-nat.c +c4ee4bc5ede672ed8d428a4e76d1597a gdb/mips-linux-tdep.c +1445cfbf5ee38232d769128a07087610 gdb/mips-nat.c +3ee9695bf13f5b4c136cd4a83ba2c18c gdb/mips-tdep.c +f5b5a9124541aa927c514dcff1d5246d gdb/mips-tdep.h +dbf53f6c90b0c0b5b83addc8c4af66e3 gdb/mipsnbsd-nat.c +d2c1124267f31aa7232736e04e305f68 gdb/mipsnbsd-tdep.c +43d8b62f57b2b9326d43479c35167afa gdb/mipsnbsd-tdep.h +5353ac7561f99790d9bec6547798eb47 gdb/mipsread.c +9babd5eb3dbd3a36bcb651eb04b97dc6 gdb/mipsv4-nat.c +f84bbfd52a850297dd08af9a78a8ef7f gdb/mn10300-tdep.c +0798e2c9cc68b95766d1631644fc0cc2 gdb/monitor.c +b88df05c557430b204873b8a05d865b1 gdb/monitor.h +31c83b4bb1c5c9c771fe8e1ec3f1e9ba gdb/msg.defs +24096aca3294cab3717506c2c69a7272 gdb/msg_reply.defs +dc35c263a6f38a457db45450afbb9a09 gdb/nbsd-tdep.c +b8b1bd58b1faa7b9b31888555534a494 gdb/nbsd-tdep.h +132db48daba54bea91a286e7afa2dc7f gdb/nlmread.c +21b85dc2ed09d1125c8ab4fbdb043c7a gdb/notify.defs +26a45351b32b92da49f9e9e2726b5391 gdb/ns32k-tdep.c +29069f66b7b3ff809855b87fa0f2cb98 gdb/ns32k-tdep.h +4b7e1e69fe47967430d230570f8ea1ad gdb/ns32knbsd-nat.c +a2bb70f9271ecb80d98a489067dfa73c gdb/ns32knbsd-tdep.c +dd57d8a70b7491b3f1d76e42edbd76f0 gdb/nto-procfs.c +4c01cb3bb5a9df040abe0bc7c2fbbf5a gdb/nto-tdep.c +bc9f2bce5d3328d93427842534cc9d81 gdb/nto-tdep.h +93c5ac0c3d4830a121c2b9f3fa0c9afc gdb/objc-exp.y +e58af207f7a2f104c59bd9ec940754ee gdb/objc-lang.c +dcd89a207a844435b4cdab0a6968f993 gdb/objc-lang.h +87540ef1991c4ae015e13916370ba5a4 gdb/objfiles.c +8d8b7fd0d6fb3e07c730fe30ef73b753 gdb/objfiles.h +5f63c6dada2382f82b1d26fdc2afd637 gdb/observer.c +405572b6f0c01f30a5f2c09d3f868c96 gdb/observer.h +ec912b647a8c58b2bbe4543f5d214649 gdb/ocd.c +13cf42994dfddc5421bb7e345d7c1b51 gdb/ocd.h +1ad97893aa4d11a827bec3dd4a5384fe gdb/osabi.c +5e876a14e11342915e66ebdac71b96c9 gdb/osabi.h +4c38d42aa946e8823ac26d053b317a36 gdb/p-exp.y +4fcc79029a6d24fb099615c9ab906790 gdb/p-lang.c +dd0d8c85c017b8ff00efadf81ba9eb7a gdb/p-lang.h +49884673264254a967249a5f6c75e858 gdb/p-typeprint.c +01a4816b69efdc69d68941e9dddc177b gdb/p-valprint.c +1e2220299e2cbf9162b884676817ea98 gdb/pa64solib.c +6f31b3a4e988353b1e3025da46cca145 gdb/pa64solib.h +11cab060bae9f7f8b2a7545160a7ade8 gdb/parse.c +5e31b257dc15d860728dd3a1bb34153f gdb/parser-defs.h +da94147104dca1e2a0d6f1f260dd5a92 gdb/ppc-bdm.c +bf93c68349e5d733d274de5d5ff7d122 gdb/ppc-linux-nat.c +6bf236db3fa067d020fbdde947456988 gdb/ppc-linux-tdep.c +1c928f5cfc6602da66d25a0cc5aea648 gdb/ppc-sysv-tdep.c +5e24b7aa886f2bb2950d1ed0b69ee807 gdb/ppc-tdep.h +be9fffca93b100a02189878657bf0e88 gdb/ppcbug-rom.c +082c00c1b5401650c8ea21fbd431cc22 gdb/ppcnbsd-nat.c +d2dad4af6d4f4a7d62ad4985b2189080 gdb/ppcnbsd-tdep.c +c10a942d68d9fefa3ad15a800e22f409 gdb/ppcnbsd-tdep.h +ef6cbac8c46d2bdaaaf8878c0f298ca3 gdb/printcmd.c +c76afacc2e26c45fe0b376af280ffff4 gdb/proc-api.c +ddff55f35d2b59960074766ec8d194a9 gdb/proc-events.c +628246839371a69134e66a53c142d495 gdb/cli/cli-cmds.c +c8c6f3b4f2ac899a1e5fe3fa3e91a454 gdb/cli/cli-cmds.h +8dc75a05b96f795af14930c75c988488 gdb/cli/cli-decode.c +edcfedad9b28724c7ce9782257a23351 gdb/cli/cli-decode.h +a8f6f4d06c7ceffed082dbeddf8fd95d gdb/cli/cli-dump.c +e4806fcd758cff138b6ad1effadee038 gdb/cli/cli-dump.h +2e98b693111e4aa66c39db3883f24e35 gdb/cli/cli-interp.c +0a815fad0a31e5e03a8c417a374e775d gdb/cli/cli-logging.c +5da58990491fc2c21d7bb8799d871a7c gdb/cli/cli-script.c +351eb45c5d48e6b764f3e088c6479d56 gdb/cli/cli-script.h +b4228836018c2aef413ebb3a13f810ef gdb/cli/cli-setshow.c +e682e9b77099c61581b706e5fe644c81 gdb/cli/cli-setshow.h +2d36fe886cbca38d6ff1b960e340ec5c gdb/cli/cli-utils.c +6a72da1c3d3e1369ac998379dbb03cb1 gdb/cli/cli-utils.h +8ec1a8b253eb4ff4d2be3336f5db3706 gdb/proc-flags.c +d2f4507e12dce5ec102631ae6c05dd03 gdb/proc-service.c +b98c8632ebd98a660263fc0015408372 gdb/proc-utils.h +c6400943b4afe5c80b3c7b4e7c796221 gdb/proc-why.c +1de2e2c8bd6fc22a95d8484cbf584e4d gdb/process_reply.defs +7455e345a20c2d562509f4ec6429bd9b gdb/procfs.c +d673af0d8d0735bbd8347cae9de94419 gdb/regcache.c +e235228cd70475bf00a01e2add0949c5 gdb/regcache.h +aa39d75923e7d5561a2410b0bcaaf4bb gdb/reggroups.c +b5c13145491c4bcb4cf26e3600740909 gdb/reggroups.h +5306cbefc65a620ab6c65ab4ff711772 gdb/regset.h +e9a1198575021d4ee43501c735a87ad2 gdb/remote-e7000.c +b863f547bcbc6fb53bfb231a072c8b01 gdb/remote-est.c +487249ec2bc6a3c65e069bc9c5fb6544 gdb/remote-fileio.c +66be4ab4711a2dc22f0c385ba65c9ea1 gdb/remote-fileio.h +af0f501486512cf57ba080052792db18 gdb/remote-hms.c +09820de56d6433c8a463d334d0a52284 gdb/remote-m32r-sdi.c +a7254bc42efb9846c19d68868a5184fc gdb/remote-mips.c +64d6262412e17a6c1ddae2ee65a87bb8 gdb/remote-rdi.c +a18e1018e436b3a303b5df863c56510f gdb/remote-rdp.c +6090219b2d50d828cb5cf44318597935 gdb/remote-sds.c +f9091e979a4b5b37ffb8f2191092980b gdb/remote-sim.c +35b8dbdb476aa1c56cc1981edde07e64 gdb/remote-st.c +90ff66718c583b664923892d324283b2 gdb/remote-utils.c +0c7f9f249f0aaa5d67ba621a4f54188e gdb/remote-utils.h +3893c10505ff5fedcbdaf4a4e912d056 gdb/remote-vx.c +d2c6758b39b44b2222fe4224b3031ec2 gdb/remote-vx68.c +6a045b5fd0549057a1cca14554ce2bfe gdb/remote-vxmips.c +e7940d51fabcf2ab3da5fa135291ebe7 gdb/remote-vxsparc.c +394d335c712e8e3d3ff863b24de4b50f gdb/remote.c +d5a9b4414f24cdf526521923d96054f1 gdb/remote.h +0b4a7d1a4eddc92eec11f3f255a00762 gdb/reply_mig_hack.awk +cc5e206ff764e2f7cd5f428b2cf560ce gdb/rom68k-rom.c +0704e12e3fffe12ab16b502731dddcd7 gdb/rs6000-nat.c +45c69ed441d84bc3a6d8b6f07e8cd16e gdb/rs6000-tdep.c +10b21b9e9189698191a9f973b3e6e8fb gdb/s390-nat.c +e7136e078430d3fadb6e3ba846a63913 gdb/s390-tdep.c +9c44496d10224f6225654132b5664f6b gdb/s390-tdep.h +2ccbab0b3b9aeaf8a81cd791701d974b gdb/scm-exp.c +28a02e8e9135d23287da61bdc37142c4 gdb/scm-lang.c +0e5cdb3cfd372545d7e234e1c5d80b0a gdb/scm-lang.h +780ab8a36ed44be775dd68f1bda7fd6f gdb/scm-tags.h +c0ebd6063289f2cccf2e8c4de0228c1f gdb/scm-valprint.c +262b4c69f293505043d80a20b402909a gdb/sentinel-frame.c +22b2eb4b470698e93db1b02ceba13a0f gdb/sentinel-frame.h +2aad56f06c4f31f7fd54356cbd5f746e gdb/ser-e7kpc.c +97d850e51e2cc6664a7c8329a921f03c gdb/ser-go32.c +25ba6e488040182afd4f92af49bce66f gdb/ser-pipe.c +fb37b2c7f24281890bdd228131a2d0dd gdb/ser-tcp.c +4530ba6820b4a9da95d241e7513372f6 gdb/ser-unix.c +6e9530daffdd50fd3e511276934a2e79 gdb/ser-unix.h +47f86e9dab60d839e4ce0936ef139cba gdb/serial.c +6c059afcef4d1fc90ec5ca6ca33df26b gdb/serial.h +605bb4f615349c3f37f31b55483ac770 gdb/sh-stub.c +fded98bd4d8c3d38fc7b228b7a730c56 gdb/sh-tdep.c +ac5adba2c4355407492f3543167bb0e7 gdb/sh-tdep.h +04bbe286ddb0c649a7008a9972ceb0ac gdb/sh3-rom.c +8b9bcbb54152560c5e850d233e103a16 gdb/sh64-tdep.c +22b0f594ccc8fd9dce1ad951cd0c6b34 gdb/shnbsd-nat.c +e65c81b386e8e4470c8165a4f4e82801 gdb/shnbsd-tdep.c +bd05f2f8197d7e9c333fc974fcce2536 gdb/shnbsd-tdep.h +64b60e671780f77b2c47d36f10424e3f gdb/sim-regno.h +927dc09d94cabfba09da782aa2b63f70 gdb/sol-thread.c +487afab377d491bc395fc3d7024463b1 gdb/solib-aix5.c +3332c92dc9b9d7f0c48975f55873ee28 gdb/solib-irix.c +7e854a6606ebf32541ba24012343f420 gdb/solib-legacy.c +bdc5383f891022ae5843e534efbaa5f4 gdb/solib-osf.c +5ea4db92a92e6568ac6d413d199e91ee gdb/solib-sunos.c +ae0759fde67f1a9b16041cb6ade5ed4f gdb/solib-svr4.c +ee3cb624f3a8fbdd08825d5d438568fa gdb/solib-svr4.h +340521b0f7aea2d934bcca6ce11de3b6 gdb/solib.c +4f1ea26aca0bf810e04d3d5910897551 gdb/solib.h +09bcfbedbbc35b128a0bdfc1b0dcd436 gdb/solist.h +6a40a0a2d9ef3084942de4e3bda6367e gdb/somread.c +3896d582919d74b02b5500ffff50b08d gdb/somsolib.c +ee24247c676d85624a01a524dc08ecbb gdb/somsolib.h +278b0197bdcfb621ec1f94fe35e8e365 gdb/source.c +9c1ba70f8e1f3f320026aa6ce0993e29 gdb/source.h +fd7d23865272c3063354dcd85254f936 gdb/sparc-linux-tdep.c +cdf63a7c1673e8edc9f839b8b9bcc136 gdb/sparc-nat.c +5b092841f65dd048bbbef11bcbdffe89 gdb/sparc-nat.h +6232b5532b9b311e2460d5b826ffb484 gdb/sparc-sol2-nat.c +5fa7b620c0efcaaba98520846130ccea gdb/sparc-sol2-tdep.c +cb4e0508c08ed0f0a23a7bdf1c673a9e gdb/sparc-stub.c +05f21ef775dd72ecc9d8ab988565459b gdb/sparc-tdep.c +6d7c48a8efd42e9c93fd4a0ba2c53c5b gdb/sparc-tdep.h +da35edc7c976e5979fc9c16c9863a5a1 gdb/sparc64-linux-nat.c +41947626782d4208e3e97687a46832d5 gdb/sparc64-linux-tdep.c +a8cf9a3892a3392d51125fe4aee5ea3e gdb/sparc64-nat.c +409d1405c2037abb568d4d6c4b8736ec gdb/sparc64-sol2-tdep.c +97757548ee1e63f6371a817999aac4d8 gdb/sparc64-tdep.c +cda04cbefebdab0002f02f230e3de7c8 gdb/sparc64-tdep.h +0e5f088019bd0c6f989b0cd35901c588 gdb/sparc64fbsd-nat.c +7bc4c24da60d6330dd4b0e9c8fa11058 gdb/sparc64fbsd-tdep.c +562bf6f4e607b1351ddf09e44f89192b gdb/sparc64nbsd-nat.c +30c7fc268239f09cd7e036e1ac2ca406 gdb/sparc64nbsd-tdep.c +e8e087b1c1fb9d92bc2425dbdad2acef gdb/sparc64obsd-tdep.c +6020c37b57486ca9bd2b9721b64baded gdb/sparcnbsd-nat.c +fabb89710f59311ac29a1a0c3d60e3d4 gdb/sparcnbsd-tdep.c +1b56b88fdd84479997bb8ccb90824b23 gdb/sparcobsd-tdep.c +6743adfecb5d0b244089bd81133b7431 gdb/srec.h +1d0f9beee8d622ec36d178ce19bee00f gdb/stabsread.c +cd70270ea2c0144f5ef29a0837455671 gdb/stabsread.h +c6b842c6ca32bcdb45544a15a924d46b gdb/stack.c +ee70021046bcc1f0deb926d307fba3dc gdb/stack.h +921d0bc71380043118d6e5bdddfb8ddd gdb/standalone.c +02d6bcc267ce960f167ec7559621f544 gdb/std-regs.c +daad9f61b58034d486354eae7307be09 gdb/stop-gdb.c +dd003de6a4c7416507566381253af497 gdb/sun3-nat.c +c0ef27bd3b02ae5fe88645ffcaa31f06 gdb/symfile.c +312d95519b2fa8dd5bae414a507bc2f9 gdb/symfile.h +5b456266b0f4eb84508166c3b5877496 gdb/symmisc.c +f6839b30f1414b0a0d156cb9a95f7740 gdb/symtab.c +743633fd25ed6add79fdd637eb612411 gdb/symtab.h +f1c951f8d36ce608e3231d3f03e531e5 gdb/target.c +c8578de19d41baa6aef2ff6487c84f7d gdb/target.h +1d4841e3a035dd8d3db8afd67684f48a gdb/terminal.h +0cc20bf51afaa586ec69da18280a7621 gdb/thread-db.c +e95f48af185799c82bf6b8de09ad75d8 gdb/thread.c +b63299897ff4d63b0a73706b6a02ba34 gdb/top.c +e7ad0cd2f8fe038f67d6ade745e4ff23 gdb/top.h +9bf0d544fed6a3878f84fa9935ffab6e gdb/tracepoint.c +aa9a293afc99704b0a6ffbf43ef5bf12 gdb/tracepoint.h +90c27d2b417ae4c5b5486b18736b20ed gdb/trad-frame.c +17ce436b755a183707ca37ec442a4f33 gdb/trad-frame.h +ed67464be27a2b6bede1d659edba0cbb gdb/typeprint.c +43bb17504e9f9b98e2d8e477ce63194e gdb/typeprint.h +06a137b1adcfa46bbbc526a80b84d163 gdb/ui-file.c +0ff5068c3ecd7773c3d7228ed65eedff gdb/ui-file.h +4026070bb24e652fdb2770fb2692fd51 gdb/ui-out.c +7ba75f886e93ea5e305ab9b70da63177 gdb/ui-out.h +d95d417b30ab40fefac49eff245b225d gdb/user-regs.c +70eaad1c970cead8936a8655e239af7a gdb/user-regs.h +d18eb22ad4f172b7bc4fd123474d527b gdb/utils.c +a70cc73e2008180a3628b0fb3bfc18fa gdb/uw-thread.c +8aad69becfe351ab7a0d38a1b844e9f7 gdb/v850-tdep.c +a4167e4f7918130f0b9439261d61da69 gdb/v850ice.c +edf9983bd28ae0a49f95675885aa047a gdb/valarith.c +706ffa082188759848e2e1852ff4c5a0 gdb/valops.c +d8eef351317cdcb8a996d692a61daa79 gdb/valprint.c +7d58a37805d3bf14a0578650428751bb gdb/valprint.h +a5bbd7bc433948c3d9298859e3f06a6a gdb/value.h +0baa5a2489aca53a5f431d27fd1d0fe0 gdb/values.c +171330ee095fd7f120cc5dc513f96648 gdb/varobj.c +d9088ad2a3a7fb5d5761dd7414c43872 gdb/varobj.h +ebf85474e0d5c5c3ed23fb3dbc5cd9e1 gdb/vax-tdep.c +427cb114230d6125740b4bed90731fbe gdb/vax-tdep.h +5c5ded2e342d683a80ee1baef14bb084 gdb/version.h +401718b61199e799c9879210e445d03d gdb/version.in +3527601469d3d9a679df93220ace87b0 gdb/win32-nat.c +1a267d78ee44ed553e1482752a74f676 gdb/wince-stub.c +92205b0e2c12af1b9061628692856da8 gdb/wince-stub.h +add34ed008797b0b466c9312219b81d4 gdb/wince.c +89ad2bf4a89e2a139338f8ea9c7608d1 gdb/wrapper.c +b8a2216ebdd88ac3e55877e5776cd4c4 gdb/wrapper.h +471e7c3fff17ccaf36ffd9811d1f6540 gdb/xcoffread.c +e827605916f87a4d36b337ccf3128ee2 gdb/xcoffsolib.c +8e4726e461ff59558bc715a42548303e gdb/xcoffsolib.h +ca1460bc1dd14303a93a3a8e358cd90a gdb/xmodem.c +525a1aaf9520314cbbc806b2752c55c8 gdb/xmodem.h +be6bcbe9ce7b8a53886c04579e2a2bbc gdb/xstormy16-tdep.c +eea89d12926233c778bb18194ad61851 gdb/config/nm-gnu.h +fcc789529f405e860329add77610f7e3 gdb/config/nm-linux.h +6557d38d91a421322da9be5883066253 gdb/config/nm-lynx.h +10a36c3f4009c0343c48fa9c9e221083 gdb/config/nm-nbsd.h +62a433de8fb11884abb9d901115b2a24 gdb/config/nm-nbsdaout.h +341eba9a3c5ef7e0cedf64ab079cee9a gdb/config/nm-sysv4.h +e68e7c1e84ee0bb9cfbdfb5f2fe2f229 gdb/config/tm-linux.h +1eb5850a19e5f45a7ca7078632960855 gdb/config/tm-lynx.h +1d146053290f3a39f9b417b8270f685c gdb/config/tm-nto.h +54e1465797cac5e15d5cd6ed6ad3dc16 gdb/config/tm-sunos.h +b8126f5423809b310764ca3a4afad5b2 gdb/config/tm-sysv4.h +3a35d2c92abe256f9a60b5020115754f gdb/config/tm-vxworks.h +679a32d2142651f89d5306454b2264f9 gdb/config/xm-aix4.h +db14fba7d3f1dc288c44c69e2e45ad11 gdb/config/xm-nbsd.h +3b90af63ffa6d35ce6fc1552150e3f4f gdb/config/xm-sysv4.h +1dd7c70b3aa59ade535903c6ff70659b gdb/config/alpha/alpha-linux.mh +b1d1a3bcd89d9f1aedc5ea2c10c0f852 gdb/config/alpha/alpha-linux.mt +0f69c254ad910566266f4c05da7a2f7d gdb/config/alpha/alpha-osf1.mh +6716d3f8dbf2144370c7c53ee2ba114f gdb/config/alpha/alpha-osf1.mt +7b40623ad554b6b4bdebafd07cd98a25 gdb/config/alpha/alpha-osf2.mh +564d3111dbfdbac990a2ddd48919e59d gdb/config/alpha/alpha-osf3.mh +80b6f424cce3ece0ddac1598ad18d1e1 gdb/config/alpha/alpha.mt +f44c7cb3525e5641bc636a2944871e6d gdb/config/alpha/fbsd.mh +1a9de712b0d4e73d4c5e2ac7d9fbe4c0 gdb/config/alpha/fbsd.mt +99f2372f9fa12271545932d9855bd772 gdb/config/alpha/nbsd.mh +6dc4aebb4ffaaa3789c36b3c4b766c46 gdb/config/alpha/nbsd.mt +6f8e9c4d86a0f9ec0bdf35f891a8654f gdb/config/alpha/nm-fbsd.h +ba68e21924c7482910a4440fdf264322 gdb/config/alpha/nm-linux.h +06ab2c60b749a50e644b2e7ba992d3f6 gdb/config/alpha/nm-nbsd.h +851c1cffed2cfaa83d73a281c3bdf30e gdb/config/alpha/nm-osf.h +1d208e999b97a08db0bce975160c32f1 gdb/config/alpha/nm-osf2.h +52102103f2d448a89cbf63e199c3f7c1 gdb/config/alpha/nm-osf3.h +de34c58734eb68a546435b2a4e02170f gdb/config/alpha/tm-alpha.h +a2eece8be1fd76f49c6cdb66a3bda74f gdb/config/alpha/tm-alphalinux.h +3fa4256777415af5a2e6d0d2fc293ac1 gdb/config/alpha/tm-fbsd.h +41c67a9edcb41c4e35ea82dbdb03f785 gdb/config/alpha/tm-nbsd.h +64e8c7536b0521860ba277d6804ac7ba gdb/config/alpha/xm-alphalinux.h +129f045275e709bb9b900df448d5810f gdb/config/alpha/xm-alphaosf.h +b68f286a110d3dae31fe9835b5147d4d gdb/config/arm/embed.mt +c1c79aa424e3f2bdcbc7c42bfabea61a gdb/config/arm/linux.mh +9cbd2841cc28f459a275bd4d79a4caa4 gdb/config/arm/linux.mt +f002892a12441162402e508d169e7ce5 gdb/config/arm/nbsd.mt +fbb7587bbadd17ba34a228c5db309e2a gdb/config/arm/nbsdaout.mh +d02a4d65adee7c4c31bfab945765530d gdb/config/arm/nbsdelf.mh +8bc8a5abb4aa2a467a53bc2a9ffc820f gdb/config/arm/nm-linux.h +0001241cd3eb272e720af8bed910b83a gdb/config/arm/nm-nbsd.h +b983efa12efc72a63314fd20ff7b9960 gdb/config/arm/nm-nbsdaout.h +463d6ad7488b768119e0a031987bd551 gdb/config/arm/tm-arm.h +16b72f987cde22cfabaee17ee91c35df gdb/config/arm/tm-embed.h +9166eadf8b0023be758145889af10bc9 gdb/config/arm/tm-linux.h +234ccf35cf8e3614e6b35fddeaac0423 gdb/config/arm/tm-nbsd.h +f941ff2e9a95fac9fba6e35af54f70ad gdb/config/arm/tm-wince.h +f4819d225088a1615e9a5d0848d55b2d gdb/config/arm/wince.mt +9ba0b88ee457be15892a48d2dbfdb64d gdb/config/arm/xm-linux.h +cd5c66d79623e661af1a4f82c056931b gdb/config/arm/xm-nbsd.h +bc093ce94c64afb6bb77b0915543e5cf gdb/config/avr/avr.mt +f5af76d1ffa289126d8b13f097f568a9 gdb/config/cris/cris.mt +d1aea4fc41d30c388992384f4b09192b gdb/config/cris/tm-cris.h +63836a0ee92090969839372e8970e058 gdb/config/d10v/d10v.mt +765a75b25b6c1c4c93a38a25bfff3793 gdb/config/djgpp/README +86f542deefe67cd0201ef93406cd7ce0 gdb/config/djgpp/config.sed +0e81c0d814454405b9e032e50363dd3b gdb/config/djgpp/djcheck.sh +5178351d05c57ef7d8148346e6983169 gdb/config/djgpp/djconfig.sh +39021bb1360c16dc2fd500edce3267e5 gdb/config/djgpp/fnchange.lst +3daacc80013b23a9a6c28302fa5082b2 gdb/config/frv/frv.mt +e9933ef58367044d74e6a5d5f6cc05cf gdb/config/frv/tm-frv.h +c950b9ebcb7142942edf3ba6880aa7f4 gdb/config/h8300/h8300.mt +74694e6ae76e15a3b7ab90dc316b0755 gdb/config/h8300/tm-h8300.h +24ac3d5adfc9e224e1c03e501e72d949 gdb/config/i386/cygwin.mh +fa43e7b947b0a3d4d66c7f0d728990dd gdb/config/i386/cygwin.mt +0e437ea51e599fce67d064d0bf681cca gdb/config/i386/embed.mt +cb5c1d2bd308c9911a90c4a16de2d2cc gdb/config/i386/fbsd.mh +238f8c68fa6e69db3da764ba2cdad76f gdb/config/i386/fbsd.mt +19ba68eee29a2ad6ce44e7a64d2290ba gdb/config/i386/fbsd64.mh +4b6ce12a571ad7128a9acc4a3f9a828d gdb/config/i386/fbsd64.mt +12eaf2ad73834ecc9860a0e9cdf68906 gdb/config/i386/go32.mh +0ace5df771303cdf5bf9d618a7137663 gdb/config/i386/go32.mt +5d559a38db40fb10d3049f6598ccb68c gdb/config/i386/i386aout.mt +f44e277d1dba65000f2974939e7c73a6 gdb/config/i386/i386gnu.mh +95990f32fb0da4d988ce9e5d698c4e7d gdb/config/i386/i386gnu.mt +fdc2ef618c4c254d9c43391f8d6bac51 gdb/config/i386/i386lynx.mh +714beb14b44265fa5439faaa1ffa44be gdb/config/i386/i386lynx.mt +9fe88d3bf7ca56123c87cffc2a79b7fb gdb/config/i386/i386nw.mt +1d90a49b33552cbc9ecf8f02d24cc9aa gdb/config/i386/i386sco.mh +be88bd41568cdf03e657a78a90cad6a2 gdb/config/i386/i386sco4.mh +08bbcede7bf9c79a3fea0c22166b4eee gdb/config/i386/i386sco5.mh +636b3be223df6069949df96798af40cd gdb/config/i386/i386sol2.mh +ddf92ff3ece944d0aa602e3e34dd4cfe gdb/config/i386/i386sol2.mt +882e46bf6218ee0a881663ae01341982 gdb/config/i386/i386v.mh +4cc1e882b70a935afbf65a0d04defb58 gdb/config/i386/i386v.mt +ae5fb6952ddd2a9a69a833405a2cf6a9 gdb/config/i386/i386v4.mh +cfdd395736c65c7330b420fb74b891de gdb/config/i386/i386v42mp.mh +13149e07640d87cdb88ca71238fb161d gdb/config/i386/interix.mh +70abed3d38d1d01abc1b9fd6a968ea1e gdb/config/i386/interix.mt +7488da16bf9c4e1815b5ca9c599709c6 gdb/config/i386/linux.mh +b0e1ae3878504e213a4d7cd3544aa9a0 gdb/config/i386/linux.mt +eb2348dc721f0d22a0d5aee54d09eb3f gdb/config/i386/linux64.mh +0142176dc07e508a95fab4287d68a1c4 gdb/config/i386/linux64.mt +1be1185f6b8ed8c41959bb14b08b6994 gdb/config/i386/nbsd.mt +aa4be232902945dd0ce645e262e008f1 gdb/config/i386/nbsd64.mh +5f7313b419d321c7ea278271371d22e9 gdb/config/i386/nbsd64.mt +c1233e56a57afb7b8b23c3adf1d41020 gdb/config/i386/nbsdaout.mh +e7168245a93bc542777524a58fcff82f gdb/config/i386/nbsdelf.mh +09fb6c4d88d0f7c3774dff9bc785cfb0 gdb/config/i386/ncr3000.mh +72be0094aa241133e0fa2761be42e2f1 gdb/config/i386/ncr3000.mt +9025cf2e7f81d8d67741f4fa7dcd58e9 gdb/config/i386/nm-cygwin.h +956c5878668a50ef0a241085d211bc96 gdb/config/i386/nm-fbsd.h +cf7846d89966e4bd70d0eab41ec12844 gdb/config/i386/nm-fbsd64.h +572ba0754bdb619af5344948d355c778 gdb/config/i386/nm-go32.h +b528dce2b9b5779091cac6843f1fc14d gdb/config/i386/nm-i386.h +97a8636eeca3049c5cb1d086d1190c21 gdb/config/i386/nm-i386gnu.h +eb0a2f645c42fe73c6eff14979d52de6 gdb/config/i386/nm-i386lynx.h +9f76883d7b0156740957ef92565db9b7 gdb/config/i386/nm-i386sco.h +759255175d60e8fe29597691f147f09c gdb/config/i386/nm-i386sco4.h +28eb65ba384a288b716a68621d3cb8c2 gdb/config/i386/nm-i386sco5.h +9a76327ae2e7f8bc51a0fa8c8d8f8171 gdb/config/i386/nm-i386sol2.h +8d8f66f817e584bf4f8939d1702d423b gdb/config/i386/nm-i386v.h +dddc55dc8d91151b3d35113d58471e75 gdb/config/i386/nm-i386v4.h +709f612696ee326f1d21162233f9420d gdb/config/i386/nm-i386v42mp.h +1a5ffd5040038ba1f2b23c1c655d4abc gdb/config/i386/nm-interix.h +9abb531ba4b73c917268959c00d8ab2e gdb/config/i386/nm-linux.h +5c9cc1332c47627dda7a4fb5e1309041 gdb/config/i386/nm-linux64.h +be8697001b6eacb19c14a2d1d87ab291 gdb/config/i386/nm-nbsd.h +72ffe8d96dc07f47b32643ea51722e7c gdb/config/i386/nm-nbsdaout.h +ce0aeb4815e6dc09f6ae943cd2de547a gdb/config/i386/nm-nto.h +de21266e849ae26d2b790c4b502c8880 gdb/config/i386/nm-obsd.h +b8b927eaff97eba8b98e581988024a62 gdb/config/i386/nto.mh +cbcc159ad2bc0e00430d62d43c55de90 gdb/config/i386/nto.mt +a370afe5ce52a5c30a2ecc78ac758eb0 gdb/config/i386/obsd.mh +5533a8df6200b0ad63928f7f07e19fbc gdb/config/i386/obsd.mt +a74b09d6f22cdd4eb15ce12e1fc63f30 gdb/config/i386/obsd64.mh +a9d2ef1c7493b0911acd6bd024408020 gdb/config/i386/obsd64.mt +23e9a40999f97ad01a3dd4c67a682345 gdb/config/i386/obsdaout.mh +4e26af8c9b8337f467da9ddbc0642c75 gdb/config/i386/tm-cygwin.h +a9b5c029da51cbd0c1418ed84a100d84 gdb/config/i386/tm-fbsd.h +7aedd62a1ed8a2cce6290476df836155 gdb/config/i386/tm-go32.h +3047bfada1a357df8b052357df6586b0 gdb/config/i386/tm-i386.h +beb84e8e343e3a5c4e18f0e90a14098b gdb/config/i386/tm-i386lynx.h +6f224bcccb0b46fa3b17d91d42b8db39 gdb/config/i386/tm-i386sol2.h +76b01a728d376a572f4ac70aaa973328 gdb/config/i386/tm-linux.h +17caab706ae100df959f22e22e398ad0 gdb/config/i386/tm-linux64.h +76dd1eeea5a9e540d98ee533c94d5642 gdb/config/i386/tm-nbsd.h +7a97bde1be4491fef49596d30ad8d2dd gdb/config/i386/tm-nto.h +b40033e9f233947900ab7bc46b91b5a0 gdb/config/i386/tm-vxworks.h +a4cd737f1731ba01023b05012364fe7c gdb/config/i386/vxworks.mt +fed05ece90644771eeb13fb989fa1eca gdb/config/i386/xm-cygwin.h +4b74de65f19059ebb929cc0cf2f7bcaa gdb/config/i386/xm-go32.h +195e8b0fca2b6c86a86a40c8c60715fc gdb/config/i386/xm-i386.h +146d93d6cc2e0df783b025644f34ad6b gdb/config/i386/xm-i386sco.h +8a06341cfb7265f37123768306a12259 gdb/config/i386/xm-i386v.h +263b8714278f397974d79ca97c69d282 gdb/config/i386/xm-i386v4.h +7b2f297747c69555205a355dc474915e gdb/config/i386/xm-nbsd.h +2b3143cf706d48f938900d65a9c4dc84 gdb/config/ia64/aix.mh +7b9c81f6e8b8f4df5fe019bffc9ec984 gdb/config/ia64/aix.mt +1f5c672e3a2c1726a722b1b65028bfbc gdb/config/ia64/ia64.mt +b9788df4cfab91c3f94320735d667161 gdb/config/ia64/linux.mh +0e60bade33357bab04a939776b3a0874 gdb/config/ia64/linux.mt +77c090800dc7f47e89e5b44dbff8236c gdb/config/ia64/nm-aix.h +aee48cf078aa797f966fbd9badb90759 gdb/config/ia64/nm-linux.h +1876be383903c32c81ff708c0c72ed8a gdb/config/ia64/tm-aix.h +908029f469a619dbb30b799f95eba4c7 gdb/config/ia64/tm-ia64.h +50ecf1d32cb31450cf02f9c470d62a34 gdb/config/ia64/tm-linux.h +612a8247971578c099c8c0e198394486 gdb/config/ia64/xm-aix.h +3e4e58a4b81d30002721a37e50a416e8 gdb/config/ia64/xm-linux.h +678c5f8cbe8c2f93f08a136fd0ddd7e9 gdb/config/m32r/m32r.mt +96353f9ece42e435b490b5cb98669e0a gdb/config/m68hc11/m68hc11.mt +72f9696980c7cd894d2a899c0acb21cf gdb/config/m68k/3b1.mh +40532c0fe8f523d595a82690864c31e6 gdb/config/m68k/3b1.mt +4526194c2be2b2bd87b9b59c1f8f08be gdb/config/m68k/cisco.mt +f69a26f027ef6fcd8ef914be92c8d02f gdb/config/m68k/delta68.mh +57f0f706905ccf7eab0c02ddfd260758 gdb/config/m68k/delta68.mt +1f7ccc2c7369a176445cbc588cc7cabe gdb/config/m68k/dpx2.mh +ed01cd707d3000643e7a915242f44e9e gdb/config/m68k/dpx2.mt +8e0e841b049ec704df629621dffe8d14 gdb/config/m68k/linux.mh +a27516472896d107c389a1515f1720de gdb/config/m68k/linux.mt +150a251eae11e32b195fbc175b64936b gdb/config/m68k/m68klynx.mh +1f26708d50172751551f36affbb13507 gdb/config/m68k/m68klynx.mt +d773bd450b3da20ae5c7bcbe81865e37 gdb/config/m68k/m68kv4.mh +8afe3be53cfb1b04e7efd3c954fe2e44 gdb/config/m68k/m68kv4.mt +03fc208af45cb5161914274fe9447ee7 gdb/config/m68k/monitor.mt +41e49d9f0462e875b3ad2396541c6565 gdb/config/m68k/nbsdaout.mh +beec0846290691fb5e9b0c6a192ce20a gdb/config/m68k/nbsdaout.mt +11a25df41c5cd868de7f110dce49be98 gdb/config/m68k/nm-delta68.h +a30a3423fd949f2d680dc647282a7fea gdb/config/m68k/nm-dpx2.h +5152232d6693147ec13e842c36020831 gdb/config/m68k/nm-linux.h +ac9fcbef3e6be8b052e6a2208613df47 gdb/config/m68k/nm-m68klynx.h +8fbcb211283c186f50b719182fa72957 gdb/config/m68k/nm-nbsd.h +6728f61e40a0f443e8e28d3823018ef3 gdb/config/m68k/nm-nbsdaout.h +49b9707bfd6babf6bcbab7b255928035 gdb/config/m68k/nm-sun2.h +487ded8c623ba0e188dd7007f81e9dcb gdb/config/m68k/nm-sun3.h +de54a558ef51e7b262b7629d85b33010 gdb/config/m68k/nm-sysv4.h +4fe0f38c11786f90906c1edb3e3178ea gdb/config/m68k/os68k.mt +7e1cc3b54949240e629f214781feaf8c gdb/config/m68k/st2000.mt +cf18e6b138cf9494678c275cba992edc gdb/config/m68k/sun2os3.mh +9bf05eb5a714e743e9ed4f08365750ae gdb/config/m68k/sun2os3.mt +214c10b16dee554aaf6c6b33b1d4cc58 gdb/config/m68k/sun2os4.mh +e3efaa99d908d869c22e1eaaade6272b gdb/config/m68k/sun2os4.mt +458da4f888829b318f236f73c9e95957 gdb/config/m68k/sun3os3.mh +10dae17670b7e968e01c6e05c3f2136e gdb/config/m68k/sun3os3.mt +2a5f43a0be2606c7f81264d0ef83115a gdb/config/m68k/sun3os4.mh +b4f53cafa5868d6ed3e5c61665423d5d gdb/config/m68k/sun3os4.mt +45945c00e6727c19b49da3c60e891dcd gdb/config/m68k/tm-3b1.h +3420c7098e19c39f76116240714475c4 gdb/config/m68k/tm-cisco.h +720fff75553cbb65a50e82b78812aa02 gdb/config/m68k/tm-delta68.h +df8a5ae6e1bf101457c9022537712845 gdb/config/m68k/tm-dpx2.h +1dc0fb0f2b18b3b0045c04b0e48d31df gdb/config/m68k/tm-linux.h +02a1c9a29dfca95ba018922268e7cdc0 gdb/config/m68k/tm-m68k.h +e30efcc48d539ea15e63cad700412c12 gdb/config/m68k/tm-m68klynx.h +f75cfd835151e324053931054680c772 gdb/config/m68k/tm-m68kv4.h +1bb79455d3762ade4a185a3aaffc0eeb gdb/config/m68k/tm-monitor.h +ee969651479e3c67ec4cfea3c370b56c gdb/config/m68k/tm-nbsd.h +3290f7a90c158afe710a61e0a922b36c gdb/config/m68k/tm-os68k.h +d18374be0d9f663433b0fc03bb5b2848 gdb/config/m68k/tm-st2000.h +c530307945e0f83a6b9db4aff29b4d4d gdb/config/m68k/tm-sun2.h +0145e30c6cbb41a7c484db8875396115 gdb/config/m68k/tm-sun2os4.h +125d8da91b8c62a17fabe3bb8e7d30c6 gdb/config/m68k/tm-sun3.h +447c31715bf9731f5bd3b358a7a2a670 gdb/config/m68k/tm-sun3os4.h +cf045a209110bcd3f411391404ec24aa gdb/config/m68k/tm-vx68.h +f7f39b06912d7d776f3f4e914da9a94a gdb/config/m68k/vxworks68.mt +3c6734f25427255f8fc6d7a9e5b09af3 gdb/config/m68k/xm-3b1.h +68ba35dcb8c246507681b9c1e859652e gdb/config/m68k/xm-delta68.h +286fee3d35cb6633574eac149e9b46f0 gdb/config/m68k/xm-dpx2.h +6fc3a957ce7cf729b6539f9cc2247584 gdb/config/m68k/xm-linux.h +c18a612e40b7779e223467d9df14ee21 gdb/config/m68k/xm-m68k.h +bd091b9c02266b9f499c27cd1d2c0736 gdb/config/m68k/xm-m68kv4.h +05838b49e57780ad87ad2883d556e156 gdb/config/m68k/xm-nbsd.h +409e32dfd90bfd6f534ac93fb3d12b82 gdb/config/m68k/xm-sun2.h +b77d77b4fd3bf74b21583d6c2228c0d5 gdb/config/m68k/xm-sun3.h +84d66171ac52cb7a273b03db37938205 gdb/config/m68k/xm-sun3os4.h +71aa532725f69af3b80f41c464be5290 gdb/config/mcore/mcore.mt +f8b68218e0f0d503b82da72fd6946654 gdb/config/mips/decstation.mh +1b6971a669fe8e0549febb7b3d307f90 gdb/config/mips/embed.mt +842922f76cb21c5d68171ee96cb93253 gdb/config/mips/irix5.mh +3143ad9c618670f3b66c12d870aa3f92 gdb/config/mips/irix5.mt +e2dc585a9a283ddef1aa7568f09c56d1 gdb/config/mips/irix6.mh +e61f438e2fac9b9e28ef5aaa88870b93 gdb/config/mips/irix6.mt +0d16a6e300459249adc7e6bfea5d4f6a gdb/config/mips/linux.mh +6a28ced965a4da4e04703ce82fe3c17a gdb/config/mips/linux.mt +7421221d6daa27dc14e3b09f7b371765 gdb/config/mips/littlemips.mh +cf472622748e7514e862404df1fcea4b gdb/config/mips/mipsv4.mh +f27fe24905bb8b2f22a2963eb5ca93df gdb/config/mips/mipsv4.mt +f5ed02ea94274da5bb61e10b1b7e3c65 gdb/config/mips/nbsd.mh +0d4e0205fbe4ba67f27864f3ab44b482 gdb/config/mips/nbsd.mt +f82f86577a2f8c6756d0b8060c38823c gdb/config/mips/news-mips.mh +c9085045097978a3c8b03e47cab335e5 gdb/config/mips/nm-irix5.h +6f0115121662686647e35dffb0058686 gdb/config/mips/nm-linux.h +97b35fa0917e824dd0ab7da3fda21c6d gdb/config/mips/nm-mips.h +6026e58d3e70692fe83bb32d32f359c6 gdb/config/mips/nm-nbsd.h +63b7d25f25906c6bec48c8b09cac67b4 gdb/config/mips/nm-news-mips.h +1595b8611c7837a26e36267412aafe26 gdb/config/mips/nm-riscos.h +efa4509c30851bd24fd956af7f4df03f gdb/config/mips/riscos.mh +8e0a0ab66ddcd4ae774b525b66350e4c gdb/config/mips/tm-irix5.h +8b76f43d724ba2ff497e5be9d8613b4b gdb/config/mips/tm-irix6.h +3e0030df1ad2bd521485cad49f8b0a9a gdb/config/mips/tm-linux.h +b84ca5e934807e023830108cf3c030ce gdb/config/mips/tm-mips.h +6b6ef3ec72245ffbbfed6cb6972ee913 gdb/config/mips/tm-mipsv4.h +07fbcbae65ca33ca30aa889fef9c7280 gdb/config/mips/tm-nbsd.h +d974c862b0aae440e8cde554f89a6d82 gdb/config/mips/tm-vxmips.h +edcae62c487b8905850e380e543a3fce gdb/config/mips/tm-wince.h +3cfc3247359e918baebea77620aee126 gdb/config/mips/vxmips.mt +3d16c23c19b724d4379d519fb842e300 gdb/config/mips/wince.mt +1f87dd5333e7917c12465f211aa78fbe gdb/config/mips/xm-irix5.h +3bce32daad8d9cb7b1b811d8325f86ba gdb/config/mips/xm-mips.h +e3678325d7d5f56d2dc61d7e81ba65e3 gdb/config/mips/xm-mipsv4.h +6219c25655021bf26f40ae94dc84a315 gdb/config/mips/xm-riscos.h +96552f44614c69dbc1b02017927dee93 gdb/config/mn10300/mn10300.mt +7151ebfc548ee5c9024cca42ce725314 gdb/config/ns32k/nbsdaout.mh +1e8f917ebe66f6f1228564edf2d39ea0 gdb/config/ns32k/nbsdaout.mt +18c121ccec89069b3660eeaf015f9a80 gdb/config/ns32k/nm-nbsd.h +93112703e43194ec3a5ea06e281b125c gdb/config/ns32k/nm-nbsdaout.h +2d21bfb5946b7a6bcba6d32013cca766 gdb/config/ns32k/tm-ns32k.h +bbdc023335f173dd1d6badcdb3536015 gdb/config/ns32k/xm-nbsd.h +bdf1e1e135b038e3dc97971469f691eb gdb/config/pa/hppa.mt +b3ea8b6e63e406a01edbf74fffcbd51d gdb/config/pa/hppa64.mt +b88ff9689a0e6752a8f82e253690fdc5 gdb/config/pa/hppahpux.mh +bf941a62928e5738c01f9dcc26a476a0 gdb/config/pa/hppahpux.mt +183a9b16fb387937650c7a7c1f5a0626 gdb/config/pa/hpux1020.mh +849c7ff5d1b215e5239dead2360db060 gdb/config/pa/hpux11.mh +81df270fda8075594a3cb945667fc707 gdb/config/pa/hpux11w.mh +204a998c1b37e5c15fa49fa8bbfb1003 gdb/config/pa/nm-hppah.h +2c39dba06539c43d093dca3d316e0da2 gdb/config/pa/nm-hppah11.h +9df66a39943d97846c2864c52c6a6800 gdb/config/pa/tm-hppa.h +3b35c1e5236cdff73fddfa452a1cd821 gdb/config/pa/tm-hppa64.h +f6504cfbb4f40733efda1cb97e5fa89d gdb/config/pa/tm-hppah.h +a08da4715dc7e935dbd54153c60f1484 gdb/config/pa/xm-hppah.h +bd15533c36b749cec68ae84d3583bb63 gdb/config/powerpc/aix.mh +031169bc9b7bea0b2be5a85bd34b9181 gdb/config/powerpc/aix.mt +d5a4d6941fa3ef8240bbb9235dda0491 gdb/config/powerpc/aix432.mh +23e0d267895411879dfab40c9857296a gdb/config/powerpc/linux.mh +2f50519baba5ee996a59d4bfa044f094 gdb/config/powerpc/linux.mt +ffbf544ae166a905192060ad86c524ec gdb/config/powerpc/nbsd.mh +2e925622afcda0e7dc776ac9fa05c55f gdb/config/powerpc/nbsd.mt +375265e55487151128698bdc6b2eae34 gdb/config/powerpc/nm-aix.h +4f51aba02ba960b90db6d3bd5f4650cd gdb/config/powerpc/nm-linux.h +67981886848d4de5a1d8b137979ea414 gdb/config/powerpc/nm-nbsd.h +8870e48577208a5fbf06872a8ed47da2 gdb/config/powerpc/nm-ppc64-linux.h +29f5edb803138c0c270ddaa0a3eb80d1 gdb/config/powerpc/ppc-eabi.mt +02e78a5ad96f597e427eab14b53d18cd gdb/config/powerpc/ppc-sim.mt +8236a1a67ec222b444131de3a8db2364 gdb/config/powerpc/ppc64-linux.mh +6a78567036ea92bd8fffb24de3e4054d gdb/config/powerpc/tm-linux.h +9cc7bb7e239286577bd3c5d6a08ab4cb gdb/config/powerpc/tm-nbsd.h +af516f198e0ecb8c5f5875586c4be19c gdb/config/powerpc/tm-ppc-aix.h +1ef37cf5d676f0a41050c9f6f3bd5610 gdb/config/powerpc/tm-ppc-eabi.h +92a3f29b9c88a4353295351b9b61cb00 gdb/config/powerpc/tm-ppcle-eabi.h +c35fb4f5df5c4139168bfe23ecc0b9d4 gdb/config/powerpc/tm-ppcle-sim.h +a68e950f5078b67c9c222fdbf8045f5b gdb/config/powerpc/tm-vxworks.h +b11247977f2f0f6112f426733889096d gdb/config/powerpc/vxworks.mt +a8f6aa2f32f4d6179ec90f7fe3025db5 gdb/config/powerpc/xm-aix.h +6bd1f25074b27a551534ae44f1412b02 gdb/config/powerpc/xm-linux.h +3dce094cb2c938bb30a33483b8ad27a3 gdb/config/rs6000/aix4.mh +2352f79f2f09cb4fa42d1dcd2aaead6b gdb/config/rs6000/aix4.mt +a3485342495d8666c0f1f819d208ef6d gdb/config/rs6000/nm-rs6000.h +f10402d5958d8319c706aec5391d7ecd gdb/config/rs6000/nm-rs6000ly.h +9ab7aee89e8e2bb6121efbc5d64168b5 gdb/config/rs6000/rs6000.mh +8f4d92a7eae6d315c8a2b0a5849d5df8 gdb/config/rs6000/rs6000.mt +a0b406ad151661f9e7038df6a1eb66ca gdb/config/rs6000/rs6000lynx.mh +e28f9b98281d6bd426f99f6a13c7fa2c gdb/config/rs6000/rs6000lynx.mt +0df3aa94054e7409c6dbcba6503051b8 gdb/config/rs6000/tm-rs6000-aix4.h +e01c9a58ebc977c2bd466bc0835826f7 gdb/config/rs6000/tm-rs6000.h +dfdf2da79fcc37c773984728dcc3b0cf gdb/config/rs6000/tm-rs6000ly.h +d428f3c7d971b58a37b2c35995af7fae gdb/config/rs6000/xm-aix4.h +47f155abe2afabec9b7b6dcde872d269 gdb/config/rs6000/xm-rs6000.h +97b594b7942dfb1edec7a631f0e72473 gdb/config/s390/nm-linux.h +12ef4e7aa6d310d36b260ccd3d058a6f gdb/config/s390/s390.mh +92571fb6f6e5d2e2a67a047770db4ede gdb/config/s390/s390.mt +7de163c76a82cfe89e03fe9a160f5ca2 gdb/config/s390/tm-linux.h +7efc40cd229de32d6657cee07cadd963 gdb/config/sh/embed.mt +5bc230851739a3506e0246b84b219721 gdb/config/sh/linux.mt +07a71b12f6186f3de88f18d7cf33d969 gdb/config/sh/nbsd.mh +fd34f84ba64c99d7ee64d884abcb759c gdb/config/sh/nbsd.mt +669db4870078c12b2ad2d3d57d8bdd9e gdb/config/sh/nm-nbsd.h +ac21dd8d358c4f0126f1d7a9c3c1d8e5 gdb/config/sh/tm-linux.h +6c7ce4d0dc64774369fda86bca23b124 gdb/config/sh/tm-nbsd.h +af93ba3cce05bb99f5a4cefbce0ee488 gdb/config/sh/tm-sh.h +9653759501da51f6a900738a7f4079df gdb/config/sh/tm-wince.h +0cccf0bc91ac31c64feca92b2dfcdbfc gdb/config/sh/wince.mt +f09fa41be0793d611acf58bace9a3d2d gdb/config/sparc/fbsd.mh +e925dcd66379efca9c93fb5d2395e6cf gdb/config/sparc/fbsd.mt +78a61badbdf1d99b799a62dd3b9f9984 gdb/config/sparc/linux.mh +a323cdaa9de5ec0865ac12e0ab9eaab4 gdb/config/sparc/linux.mt +16d4eb0dbd20b9504812113f1f8906c5 gdb/config/sparc/linux64.mh +635b60604bd0d4e728c1c559ae017ad0 gdb/config/sparc/linux64.mt +3cc5fac4e1f7ff5e2cea227e9e060fbf gdb/config/sparc/nbsd.mt +939be582ad6c77b766ada019587640d4 gdb/config/sparc/nbsd64.mh +509891eb35cde77d2d8e3d77a4af554e gdb/config/sparc/nbsd64.mt +00e75d4bcf5c5427ffe88fc3a0c52d48 gdb/config/sparc/nbsdaout.mh +98710ed82086e740b9857f5e07d41d45 gdb/config/sparc/nbsdelf.mh +1445fbb72ead6c6e70a62538ea185ecd gdb/config/sparc/nm-fbsd.h +450a1c44af1d2ab5ae18c1db6da1199e gdb/config/sparc/nm-linux.h +11f9feeadfe4e9bd25e79b150f9e3021 gdb/config/sparc/nm-nbsd.h +c939fda939545e22aeedb8d86ef61a68 gdb/config/sparc/nm-nbsdaout.h +4962783cb7388ac87de703103e1ffa81 gdb/config/sparc/nm-sol2.h +bbd2dc492142df5324326c9a9a9ffa60 gdb/config/sparc/obsd.mt +e298512af5089652484fb7900853b1e9 gdb/config/sparc/obsd64.mt +cfbcbd4f95df88c6c880ae5a8661026b gdb/config/sparc/sol2-64.mt +b0b94f2b012713a411a9adcb895d82f3 gdb/config/sparc/sol2.mh +763a1ea818b1089b3e761600cce4de69 gdb/config/sparc/sol2.mt +e5dcdec0242fe5d99f8d7894001e4857 gdb/config/sparc/sparc.mt +fcab4101a1d511bbafd504bd25528610 gdb/config/sparc/sparc64.mt +a10c94f7ed782adec375144890afd33c gdb/config/sparc/tm-fbsd.h +7d520b5a3ce9829b31384cd85d1c8f3a gdb/config/sparc/tm-linux.h +579f627f455a558c11ec67c96e4a3a18 gdb/config/sparc/tm-nbsd.h +21028109907f896ad9ffaf9cad748bea gdb/config/sparc/tm-nbsd64.h +d0f148da55fdba8384a4041f7864704c gdb/config/sparc/tm-sol2.h +e1895b08602453c9874e528cbd9df36f gdb/config/sparc/tm-vxworks.h +037eb831901f8937ae3c0b2fd6b0a4fc gdb/config/sparc/vxworks.mt +39fe5a891bfc2524ea91063107a129b1 gdb/config/v850/v850.mt +677f6046d6881229c86bb9df56115b06 gdb/config/vax/nm-vax.h +1d9c8d332f92dc2d07b3276f9eab2905 gdb/config/vax/tm-vaxbsd.h +615b909785f30bb1ce5f6bb5505e80ef gdb/config/vax/vax.mt +19c9adb3733ba81f65106841d6641905 gdb/config/vax/vaxbsd.mh +e96b5a3dda05764ee850443d538089e3 gdb/config/vax/vaxult.mh +6b248ab9672c06272946df62d5712977 gdb/config/vax/vaxult2.mh +ea637049a1663067a9e607d754aacf40 gdb/config/vax/xm-vax.h +c1d1a96ae852821d4a09c335e4e36dd4 gdb/config/vax/xm-vaxbsd.h +df9d5cc6576947ae2ea3b59f14a73ebf gdb/config/vax/xm-vaxult.h +1b13ab4adce8924a6b422eb24f936e79 gdb/config/vax/xm-vaxult2.h +26e0262141fc8b59df7148e46140da73 gdb/config/xstormy16/xstormy16.mt +157ab2011d66651a4d4ce98dcf19ac08 gdb/doc/ChangeLog +cde55cb7bff1f00bd1c4b1ec0336c922 gdb/doc/LRS +9af0a707aa6db6fa9c3248ac51fbf71d gdb/doc/Makefile.in +d5d06eaf9b4d44aa442a4a281aa9aea4 gdb/doc/a4rc.sed +03edd134f767997d637c48af564d5fd4 gdb/doc/agentexpr.texi +20980a01b4d2dd320bbe7f9614e34d22 gdb/doc/all-cfg.texi +d9f59b950243f20762364cb59c0349d0 gdb/doc/annotate.texinfo +c85dc4fe72550dbbfb1a4af9013cf5d4 gdb/doc/configure +212f597fd98e318a7cec3a59db82c672 gdb/doc/configure.in +de7610c73bda71d4e1ad08af82989c2f gdb/doc/fdl.texi +78c4d48aefad6520bd1cfaca31e87c9a gdb/doc/gdb.texinfo +ddcf175c8a199b36f81f81bb8ee60d7d gdb/doc/gdbint.texinfo +7f32ddf5cf96243f4927998a92a47475 gdb/doc/gpl.texi +73ec71cd3b2e7f61bc530f19d4b35056 gdb/doc/lpsrc.sed +e5f5af6283e0aa150e569d3e3b48dd1b gdb/doc/observer.texi +8108dd8f906f2654fecc74958cf383db gdb/doc/psrc.sed +fbcc30e4dc903f23065f01d9d1328e4a gdb/doc/refcard.tex +987395a23fca3089964de0f43b44ff5a gdb/doc/stabs.texinfo +c619c0c50e9c49779ca36a1b6a32f84e gdb/doc/gdb.info +2fb19f201b72dffbf29201829de8bc09 gdb/doc/GDBvn.texi +67cd5e3952b99fde483b6d54b8915948 gdb/doc/gdb.info-1 +d6122feae2964f867a91a9d6be8fa378 gdb/doc/gdb.info-2 +dd160b7dd4c3e8e9587915746a46fea1 gdb/doc/gdb.info-3 +24e9218260a77fda7bd3194f94de3be0 gdb/doc/gdbint.info +dc0f4e884b8a90d4ce10096777921db2 gdb/doc/stabs.info +b6eec4de042c13c295d1820e3ea7c9ce gdb/doc/annotate.info +c05455598e50d719af6541096a95dced gdb/gdbserver/ChangeLog +5c2319b6ac70f05d21f74afa311518e8 gdb/gdbserver/Makefile.in +b588b07be2b25b286aa970edb2f756e9 gdb/gdbserver/README +de8ee59fc168a4bc837d9d6dcd6ec68c gdb/gdbserver/acconfig.h +c656d043d3adf90affcacea01d0fbb83 gdb/gdbserver/acinclude.m4 +b540a936ba5cad8663d09573ac386d32 gdb/gdbserver/aclocal.m4 +263114c5eaa19c910a64b178340f9000 gdb/gdbserver/config.in +ae2279e05808bd0915860e412a5faf07 gdb/gdbserver/configure +a47cbe088ef68ee2e1a7a18398b426e4 gdb/gdbserver/configure.in +e7b1f7b19f97ab1d33027b2e9e7bead1 gdb/gdbserver/configure.srv +237971ce6e96771488a57da8c88a0788 gdb/gdbserver/gdbreplay.c +c3c02b21d22cec088d7e185ba23dbb90 gdb/gdbserver/gdbserver.1 +ec54af5eb2a4df38c85e82b8a9e1690e gdb/gdbserver/i387-fp.c +4d2d0ce45180b1b69e6ae97623e7c108 gdb/gdbserver/i387-fp.h +21464336059178040e63418622b0e91a gdb/gdbserver/inferiors.c +39935bc45b8a3693ca779dd541a4cf90 gdb/gdbserver/linux-arm-low.c +035a666c446e2204c40504debfaf4ab6 gdb/gdbserver/linux-i386-low.c +a86bf22ec3ee23729b2cc916beadfea2 gdb/gdbserver/linux-ia64-low.c +66ec921ee12520ac6c4ae7cd86f2df6e gdb/gdbserver/linux-low.c +f9c4bf1877a9b778f71b27fc43c8ac3d gdb/gdbserver/linux-low.h +f45f3678e89a448f8cf0f91f69b85862 gdb/gdbserver/linux-m68k-low.c +7634008a8b75d93b32fd6c3d5ebee456 gdb/gdbserver/linux-mips-low.c +3907cf240adb65ef45d3ad580d7345f3 gdb/gdbserver/linux-ppc-low.c +8a618f2c2dfe4bbaaf91e65a58d30aac gdb/gdbserver/linux-s390-low.c +ab683f9ef601102bb7e5e0dc688b467d gdb/gdbserver/linux-sh-low.c +0e323f92da11b69cdd7694bf5cafeb6a gdb/gdbserver/linux-x86-64-low.c +31f0092435cd3b8d454735f094582f73 gdb/gdbserver/mem-break.c +2b45da328cb71d9f0af8a3cc5f99caac gdb/gdbserver/mem-break.h +4e4000a60ac00275d96647a7be53b88b gdb/gdbserver/proc-service.c +76a62e1693bb2c35774548db3af0fcbb gdb/gdbserver/regcache.c +e33dc5007beb3563c2513d92c6e93079 gdb/gdbserver/regcache.h +2826063f048775b503f4174b632875c0 gdb/gdbserver/remote-utils.c +7ad637799056f5f2752ac0a726e6004d gdb/gdbserver/server.c +262111005195e166b4cca1cc6a9284e3 gdb/gdbserver/server.h +806ae4df8dfd08ddce2c557e2af4fead gdb/gdbserver/target.c +89cbbb9ec4d570435a1ea5e3127d0f7e gdb/gdbserver/target.h +e544c0adfd23a97ed22acd971089fa35 gdb/gdbserver/terminal.h +195788d8df2dce6c60ee2ff7a40a1841 gdb/gdbserver/thread-db.c +e80da11d27b1789f6b61592e849c9497 gdb/gdbserver/utils.c +90b81f951a2351c88c1b4a1fedbb492f gdb/mi/ChangeLog-1999-2003 +7673f1fcadc1356354ac0bf834a32f1f gdb/mi/mi-cmd-break.c +31748546a8c9ada695f75089906fb1b0 gdb/mi/mi-cmd-disas.c +321b6d4c3463ff21850e80195884bbb9 gdb/mi/mi-cmd-env.c +9c45c89b27c23bd1a5e50ab8525bce7f gdb/mi/mi-cmd-file.c +d463f6758c8d257948aa59d8e97fcacb gdb/mi/mi-cmd-stack.c +9c4e5da1a9ffd8fb21198b8e45adcafa gdb/mi/mi-cmd-var.c +e67b53a1d8a7b1fa667c82d7fc260f33 gdb/mi/mi-cmds.c +32563ba48de6b6e4b6347e2d39d6ef79 gdb/mi/mi-cmds.h +6deebccbb622b1ddfe1b72d03d9164ab gdb/mi/mi-console.c +ec733c79189cc33ee80389c366b8ee4d gdb/mi/mi-console.h +876d29d88b9e1915ed7ea0f14f27b5c9 gdb/mi/mi-getopt.c +ac8daeb67a457013cda0be842a0f1559 gdb/mi/mi-getopt.h +d390e6bb89f268062788bc24fc3246ac gdb/mi/mi-interp.c +a1749766ca906651c6e91aaaa7b785a5 gdb/mi/mi-main.c +418106d3921c0aae25d8531598f48aea gdb/mi/mi-main.h +dbeb8553e048c982e6481d9eec2ca416 gdb/mi/mi-out.c +ea1af536fa7008e4cb819442c647d10e gdb/mi/mi-out.h +9f46191fe5c36459769faedf85b1c7bb gdb/mi/mi-parse.c +94825d70f2f9ac43cb9769723dfa4730 gdb/mi/mi-parse.h +afe7ede1e28847e4a2a5db2ceb259a8d gdb/mi/mi-symbol-cmds.c +12254ac99d0cc5ea4d8c6da067b0c8b8 gdb/nlm/Makefile.in +20e829dbd87c5951a051a37f1a848e78 gdb/nlm/configure +ca1cebf34e2612b18ed15be1eb2ce17e gdb/nlm/configure.in +2e47ff727d3f10c0c934dfff78a081d5 gdb/nlm/gdbserve.c +f973c5c42c764609d5cd63925128c869 gdb/nlm/gdbserve.def +2023c3d27a792299427a4592be4fed15 gdb/nlm/i386.c +ec1a5ddfdc20b8668b1c383a2d31d5e3 gdb/nlm/i386.h +af7998b7c344d030d53a0df3c775d52e gdb/nlm/ppc.c +e65cc68e428afd3b24cbf62f52eb5d1f gdb/nlm/ppc.h +192c4bacc20346b4bc0ff02b77a91105 gdb/nlm/prelude.c +912ea9d855fcc23de552c2d674d37812 gdb/osf-share/README +314092b3f105af13bbccc4fc39481123 gdb/osf-share/cma_attr.h +ec11d7d3ff9dbfa4d20d96c6ecea4aea gdb/osf-share/cma_deb_core.h +531f430005d3dfefbbe460e835dd4011 gdb/osf-share/cma_debug_client.h +b2dbbcf3ce19d6aac60aabe2461688f5 gdb/osf-share/cma_errors.h +509c48bb5521057f577d861d34415db0 gdb/osf-share/cma_handle.h +9347ef23e2404f0ee033107934ae0cdb gdb/osf-share/cma_init.h +5c6c1190b6d93f82d69a7c24a243e17d gdb/osf-share/cma_list.h +4e1ef48ceb062c4de2d02498037e7d27 gdb/osf-share/cma_mutex.h +aa4922b22db6dcb97919aefdf6611ff3 gdb/osf-share/cma_sched.h +e543eac7a41953f1de602b9abf91c3b0 gdb/osf-share/cma_semaphore_defs.h +c1f9f7112e573c94a6a72bfef19e8c9a gdb/osf-share/cma_sequence.h +5c6ed620494d12976faee79e8a8be4c9 gdb/osf-share/cma_stack.h +987386e076ca49cc3407fc4ee3a4290e gdb/osf-share/cma_stack_int.h +a51385c695f3a215a2b71e98d6bea995 gdb/osf-share/cma_tcb_defs.h +c20fd87765652ad7ba50f43a0ec95088 gdb/osf-share/cma_util.h +77b2f029b50b47ab8989da00b35b9438 gdb/osf-share/AT386/cma_thread_io.h +7cd3745f37bbbfcd24086735939ead52 gdb/osf-share/HP800/cma_thread_io.h +36cb16e3cf86ddd4609d275a6a3052f5 gdb/osf-share/RIOS/cma_thread_io.h +acbd9a81065b26e61ad48b0b032ed9f9 gdb/rdi-share/Makefile.am +9e4e1f578d17bb99b075896be54200b2 gdb/rdi-share/Makefile.in +14eed8248957fe4acfd7d076e5cc1560 gdb/rdi-share/README.CYGNUS +90a45de863805a37425c7d25f5b6ddd3 gdb/rdi-share/aclocal.m4 +44f827f3c04c4fc3193ae1bcc34e1078 gdb/rdi-share/adp.h +423052688a03ca25efe3031c10c4a2c8 gdb/rdi-share/adperr.h +bfe71729167f48725ae4d507ed7a9605 gdb/rdi-share/angel.h +545fc079550aab5b8a86002db3e288a5 gdb/rdi-share/angel_bytesex.c +f609c420e432a9dccf9bdb3d399bec77 gdb/rdi-share/angel_bytesex.h +e46ae6eb86b7b1f97d31026cba662fcc gdb/rdi-share/angel_endian.h +a23f9550b49e345e3419ad235c681425 gdb/rdi-share/ardi.c +049620066f85205f7a48f60e62ac81e0 gdb/rdi-share/ardi.h +c6d1b9800befce2b67d1c505568608c7 gdb/rdi-share/armdbg.h +303b1ae6381ffb45fc26303c44f51eaa gdb/rdi-share/buffers.h +a87a0b9fab996559c6c656fc33d9d18d gdb/rdi-share/chandefs.h +01c6eac19e7030820c8ddd1a19c42213 gdb/rdi-share/channels.h +c0cbfc17c4553a5a4200bbdd0e4248bc gdb/rdi-share/chanpriv.h +5b6a8ae61ef3b66d9805bc1389cb2d24 gdb/rdi-share/configure +7a1167306adcdd49c1df9249a1614a59 gdb/rdi-share/configure.in +6766f813b65cd8bfdf92cd29da36169a gdb/rdi-share/crc.c +13c90616d2bfe9015c26c1be871a40f1 gdb/rdi-share/crc.h +d6a6c544909c2b8bab64ff2118198141 gdb/rdi-share/dbg_conf.h +c808afaf48e2d8f13a7d94d0ac6a6611 gdb/rdi-share/dbg_cp.h +90785272af227f117b580089656c023b gdb/rdi-share/dbg_hif.h +621ee5352ad5c75e2e0828446c7888ec gdb/rdi-share/dbg_rdi.h +34a6e9e24c5c58b7fdb32e4eccb7e002 gdb/rdi-share/devclnt.h +0bfbeb04620da2fafa9190929ae18d3b gdb/rdi-share/devices.h +0771db2707377b527718bb44a3c18371 gdb/rdi-share/devsw.c +d559914c40c17b6a03e507a4749de879 gdb/rdi-share/devsw.h +f98c9c9ad7cfd0c789a27aee6323eb2b gdb/rdi-share/drivers.c +7645fb2993d1bc3841f45607c38a26cf gdb/rdi-share/drivers.h +4f4f67579a2215d8662698f29a81c61f gdb/rdi-share/etherdrv.c +d8e5f0d8e5e7559b1f30e94b35a7551e gdb/rdi-share/ethernet.h +6c7c85c9d3833b900230854bfb5a81fe gdb/rdi-share/host.h +96fd8e4db2ab0c64317674ec848eb6c4 gdb/rdi-share/hostchan.c +523f95bfa31306e23c377b37c63fa05c gdb/rdi-share/hostchan.h +78948f052f1bff4278717c5d3401fc0d gdb/rdi-share/hsys.c +cc8de9ad50d3a4c5217ff58769cd41fd gdb/rdi-share/hsys.h +3d7d9a085d25a4d27c1ab792a37f17ce gdb/rdi-share/logging.c +466436e31de53162d99197db8cd38ba9 gdb/rdi-share/logging.h +ff3e0cc9714806049673a050ca348941 gdb/rdi-share/msgbuild.c +0e13b39bf04d127519f8ed41f720c6fb gdb/rdi-share/msgbuild.h +b69f395f07fcd91fc575554d1783603b gdb/rdi-share/params.c +a73f6cdd9c937c3b8d30a97fbe0abd50 gdb/rdi-share/params.h +43dbc046859f7d4e50dd071c927081aa gdb/rdi-share/rx.c +46a32878855b8bf2eb8d9023c4b329c7 gdb/rdi-share/rxtx.h +1a0719cca18cb894a3aaca732e2301ff gdb/rdi-share/serdrv.c +72239d1d8af5c802e2971727ae1716d6 gdb/rdi-share/serpardr.c +e7512f7bf4865b638cddfbe97db3d466 gdb/rdi-share/sys.h +4f520646d479207ed538955715caa06b gdb/rdi-share/tx.c +3ff8e0761b4bf62bb5c2d9a8f2c4c634 gdb/rdi-share/unixcomm.c +6002c66173a3c4f6001979896c888e2c gdb/rdi-share/unixcomm.h +9ed735c435a35313ad491c309fd32cf6 gdb/regformats/reg-arm.dat +8936fb07afdc018021e787498e8fbe81 gdb/regformats/reg-i386-linux.dat +22247e6f668678c70523438e2602e99e gdb/regformats/reg-i386.dat +eb508b601fa0e05022067d7a7b48a8b9 gdb/regformats/reg-ia64.dat +767b3762219584b4953a737251b6347f gdb/regformats/reg-m68k.dat +958e700ab062f4ec5a1bec04860033bb gdb/regformats/reg-mips.dat +89725b9eb486c038a497e375ea8aabfd gdb/regformats/reg-ppc.dat +e337d7dff9b66f4ecb3813b1fa8b53f9 gdb/regformats/reg-s390.dat +d3e9824914e44c31e310e78047754192 gdb/regformats/reg-s390x.dat +657ed262c66093acacf0ccf85f97c55c gdb/regformats/reg-sh.dat +8c71b67411765da5ab92789a60f27516 gdb/regformats/reg-x86-64.dat +a15e17e5899c5d3a3ec176bbe8a376f5 gdb/regformats/regdat.sh +cce9a607a770dfe505270736e1a32fa7 gdb/regformats/regdef.h +bf3bd6ad756f2c7ec96759893a0a4517 gdb/signals/signals.c +32b68d52cb813a01f3eac71017f56d2e gdb/testsuite/.gdbinit +25ed8adfefee4cab096fc062bec1f8f2 gdb/testsuite/ChangeLog +8fe4298462566117e49f79e5a5b97a3c gdb/testsuite/Makefile.in +1b9bb551736dbc95577c91620b81fb6c gdb/testsuite/TODO +a4cf76282f558aaf126217a96d77dec6 gdb/testsuite/aclocal.m4 +ef3256f0546af678e3c9a37a6204b3f4 gdb/testsuite/configure +b0ba48010171ad597acb4641ae805961 gdb/testsuite/configure.in +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/abug.exp +fee369d654e97f06fe1c1e5a6680a672 gdb/testsuite/config/arm-ice.exp +32bd0508363fae0bd08a72ded1a1ae0d gdb/testsuite/config/cfdbug.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/cpu32bug.exp +fee369d654e97f06fe1c1e5a6680a672 gdb/testsuite/config/cygmon.exp +13af1823246a3eb438b1b3b019e64615 gdb/testsuite/config/d10v.exp +3584f38640f55d3a6c83e3ae35fb0a82 gdb/testsuite/config/dve.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/est.exp +7bab63ea0812701b5b397cc80f62e894 gdb/testsuite/config/gdbserver.exp +fee369d654e97f06fe1c1e5a6680a672 gdb/testsuite/config/h8300.exp +e3dd7802ac4a65da64353fc27a039fee gdb/testsuite/config/hmsirom.exp +6531bba8668e2c92d81955a13551693b gdb/testsuite/config/hppro.exp +e4708e4b23e4e6ddd07c7245736d37b3 gdb/testsuite/config/i386-bozo.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/i960.exp +50f6a13c0fd1efa871f0b7c0dc273e0d gdb/testsuite/config/m32r-stub.exp +ed9b2866854fb841a339c72ab2fe4807 gdb/testsuite/config/m32r.exp +3b4962b783a530746573abd6b4e2bd9b gdb/testsuite/config/m68k-emc.exp +b768f8929ee37be60d06c5d4bc68338e gdb/testsuite/config/mips-idt.exp +b768f8929ee37be60d06c5d4bc68338e gdb/testsuite/config/mips.exp +3584f38640f55d3a6c83e3ae35fb0a82 gdb/testsuite/config/mn10300-eval.exp +806f817346aa75f71dbe63cbb3181951 gdb/testsuite/config/monitor.exp +b4f7b351e4d72b3f5a7ce57c944a2e43 gdb/testsuite/config/netware.exp +52318b40e559b38730204f551a706cd6 gdb/testsuite/config/nind.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/proelf.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/rom68k.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/sh.exp +f11bbd2b680602eec832c7d9c1c65e15 gdb/testsuite/config/sid.exp +b2359c524273c898f41c76addbe8ec67 gdb/testsuite/config/sim.exp +f3615f8a1eb7b7e32338b7159ad1cdfc gdb/testsuite/config/slite.exp +67a2e8c61a226a4437fd7b94a90d5dae gdb/testsuite/config/sparclet.exp +2bf98b1738dabf1d05965a94c522301e gdb/testsuite/config/udi.exp +e4c58b54d7ff81dbc51d97347e994827 gdb/testsuite/config/unix.exp +6230016d4a95b38beaefc02a190196ac gdb/testsuite/config/unknown.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/vr4300.exp +5778cc39113ae688a315eb482579c9ef gdb/testsuite/config/vr5000.exp +3d29268e9f092c9bd5193a9d4bef9514 gdb/testsuite/config/vx.exp +5d234db137378e9f144ae0b2ef55e31c gdb/testsuite/config/vxworks.exp +2b0a0fbf59c988aa7247e14edb13a1e2 gdb/testsuite/config/vxworks29k.exp +f6c31f326a6a8a5fe922841a22e861cb gdb/testsuite/gdb.arch/Makefile.in +8512d3cf77bca3f120284ed9cfb3f64a gdb/testsuite/gdb.arch/altivec-abi.c +80ebb5a77c62c98d3cba9b8ea837c58e gdb/testsuite/gdb.arch/altivec-abi.exp +a4b44663a9c9d2ac554ea371750489cf gdb/testsuite/gdb.arch/altivec-regs.c +995b547b55190ba6dcfadf1b131e247b gdb/testsuite/gdb.arch/altivec-regs.exp +11389013dfeba005022a1d910728c9d7 gdb/testsuite/gdb.arch/e500-abi.c +f6b0caebb0c552636c28219dd2829b07 gdb/testsuite/gdb.arch/e500-abi.exp +fcd0dd3432e917999e1b351b9467f52f gdb/testsuite/gdb.arch/e500-regs.c +6005db01e75e05b21ee4d173e0657311 gdb/testsuite/gdb.arch/e500-regs.exp +610adaeec31b12d5058382bbb879dffa gdb/testsuite/gdb.arch/gdb1291.exp +894ef9bf1398451f672da587e0de601c gdb/testsuite/gdb.arch/gdb1291.s +77a0d5ff18e4eb9946adfc73e72925e4 gdb/testsuite/gdb.arch/gdb1431.exp +8f138551370f353d62af0a66fd916109 gdb/testsuite/gdb.arch/gdb1431.s +03e1299995e692fd14be6d3074762614 gdb/testsuite/gdb.arch/gdb1558.c +90d03378a7b2da90c619821d2a7024df gdb/testsuite/gdb.arch/gdb1558.exp +a4fdd6dc2a5d5f881b4ebe8165b4f95d gdb/testsuite/gdb.arch/i386-prologue.c +c43757ac618fef5c7ac3d85636830c71 gdb/testsuite/gdb.arch/i386-prologue.exp +805e621a37c4e3d991b51b6f6168ed50 gdb/testsuite/gdb.arch/i386-unwind.c +2fe2a6b0ee998ba93f54e216b58694b5 gdb/testsuite/gdb.arch/i386-unwind.exp +f2e003c28af0ab5d01be9fc57e01b1cb gdb/testsuite/gdb.asm/Makefile.in +5c938c065a5b5c92a9c605397508d57e gdb/testsuite/gdb.asm/alpha.inc +73f28b814430e5f1534678ff549c32cc gdb/testsuite/gdb.asm/arm.inc +93e4d5b2e372c1a0c82b844d252f3027 gdb/testsuite/gdb.asm/asm-source.exp +9aeaf0c0a1892ef0119d1db1bed81ad9 gdb/testsuite/gdb.asm/asmsrc1.s +6d621f0d5b835ebe361d6f72dfd0bf3e gdb/testsuite/gdb.asm/asmsrc2.s +88599ba05a4590c4e5571eb37e80623b gdb/testsuite/gdb.asm/common.inc +b7ffb6852499fbf15bcd68536bec63bd gdb/testsuite/gdb.asm/d10v.inc +b3f11b21e5921c419a43f93720dedf85 gdb/testsuite/gdb.asm/empty.inc +2778e941fd6f043a75d17361362e5c0d gdb/testsuite/gdb.asm/frv.inc +05568e93b7a8ffb65984793527e01bb7 gdb/testsuite/gdb.asm/i386.inc +600540c3b6eda05395ca94bf7d5b10cb gdb/testsuite/gdb.asm/ia64.inc +7aab094990e39f5827eb3942d43a8e8e gdb/testsuite/gdb.asm/m32r.inc +b1f873697325c1c26af06371042e3bf7 gdb/testsuite/gdb.asm/m68hc11.inc +a3b2dce54f8645b4897e0a89118b47ec gdb/testsuite/gdb.asm/m68k.inc +2f0be533d5222ff80ace7e7757d52817 gdb/testsuite/gdb.asm/mips.inc +c4d2ba6404c6cf567a68a9e710a973a0 gdb/testsuite/gdb.asm/netbsd.inc +b0cbb2f3906881df1c592b02c52f33ae gdb/testsuite/gdb.asm/openbsd.inc +7a37c838ea49e38f4542b1ee152de56e gdb/testsuite/gdb.asm/powerpc.inc +c504c2fe18f66d3eda109861b56cb56c gdb/testsuite/gdb.asm/s390.inc +24bf42e27e2b37933c2142f82a790128 gdb/testsuite/gdb.asm/s390x.inc +a90c51629d5c564b1acf32b681850865 gdb/testsuite/gdb.asm/sh.inc +004e3184dcbd00cdedc9969b1a860626 gdb/testsuite/gdb.asm/sparc.inc +bef01819157e0cca7af4ba8058f5eaab gdb/testsuite/gdb.asm/sparc64.inc +e3c5be9e840a34c66a75b0204fe24a05 gdb/testsuite/gdb.asm/v850.inc +d9c5367584eaf2d30d4e55f545cf7d8f gdb/testsuite/gdb.asm/x86_64.inc +425d8b8ae6d12133808165dd066a3f6c gdb/testsuite/gdb.asm/xstormy16.inc +4009b43c0b4ee5a6d0ae5ddcefac64ce gdb/testsuite/gdb.base/Makefile.in +ed3dc8bc6fbc3b7c4f74464eb900f404 gdb/testsuite/gdb.base/a2-run.exp +006e8779c9e23af3419a58591b7eab7e gdb/testsuite/gdb.base/advance.c +b5ccf780e1c1f2f629cabd8750e778ba gdb/testsuite/gdb.base/advance.exp +42d593b5c24fba70246c5cf9c68d3b36 gdb/testsuite/gdb.base/all-bin.exp +7a6a57ab31ce1cf79d80fe6b690ba253 gdb/testsuite/gdb.base/all-types.c +f76f09cd7572a5024b5ec2307f4f7a9b gdb/testsuite/gdb.base/annota1.c +8cd0cd8641afd01f4c935243c1197fc0 gdb/testsuite/gdb.base/annota1.exp +f76f09cd7572a5024b5ec2307f4f7a9b gdb/testsuite/gdb.base/annota3.c +16f403c0b7440c56ef05c4a1232361be gdb/testsuite/gdb.base/annota3.exp +8c75ba989aa918790b50c810f5304737 gdb/testsuite/gdb.base/args.c +9fb653010e52acc3834813932f7e2c24 gdb/testsuite/gdb.base/args.exp +93afdd2e5026fe7727e196f13e02995f gdb/testsuite/gdb.base/arithmet.exp +ee9bc8fb86c00f2a69afa4c2ae0b477a gdb/testsuite/gdb.base/assign.exp +7c164cbba3852ca6d8407f5461733f76 gdb/testsuite/gdb.base/async.c +39b88a45d83998559d429d98912ad249 gdb/testsuite/gdb.base/async.exp +67f370c8661ab05209185c9be1b1266f gdb/testsuite/gdb.base/attach.c +8bfb2ef79095ac2aa2d432b45ef6107c gdb/testsuite/gdb.base/attach.exp +40ea0b637bee041d22c72ad5ce356d17 gdb/testsuite/gdb.base/attach2.c +d8f766041b8c03338b5833d6c37c5008 gdb/testsuite/gdb.base/average.c +872a00e3c46112465087bf0aaaedebfd gdb/testsuite/gdb.base/bang.exp +94c1f1818c9234b5e8e7669b457865c1 gdb/testsuite/gdb.base/bar.c +875a150f7fd4db096ea08b9acd105dae gdb/testsuite/gdb.base/baz.c +3181c808c72953c27e8a29ae3afcf22c gdb/testsuite/gdb.base/bigcore.c +36863f2f42584e542231f41e82d44a84 gdb/testsuite/gdb.base/bigcore.exp +22193e74f9a52aac8fe5375e117ac5de gdb/testsuite/gdb.base/bitfields.c +015fdf4c0afbd372df11c23ffe0c2062 gdb/testsuite/gdb.base/bitfields.exp +3ba4ad95b3f5c2c0b1abedf3b5846c53 gdb/testsuite/gdb.base/bitops.exp +601f4ed2b5be1d234ba175e76d7bba62 gdb/testsuite/gdb.base/branches.c +2072198680ebcf20f2dcbce969384927 gdb/testsuite/gdb.base/break.c +cc466009ba3781ecf76714e2c146bfb5 gdb/testsuite/gdb.base/break.exp +0911aa8f8bd7838fcdca5a823e18d4bc gdb/testsuite/gdb.base/break1.c +00423b6818e5837317fd66f9609d152b gdb/testsuite/gdb.base/call-ar-st.c +50eb8085571c77c0415dded8a60499aa gdb/testsuite/gdb.base/call-ar-st.exp +868c4632e7860280ad3ddd0c7713c819 gdb/testsuite/gdb.base/call-rt-st.c +c6ef05df7be59aa77bb3e56b507978b3 gdb/testsuite/gdb.base/call-rt-st.exp +0903784a2f2f16faef989543e584e31e gdb/testsuite/gdb.base/call-strs.c +824fdfbfe47a90c63cc9de1ea2b578a4 gdb/testsuite/gdb.base/call-strs.exp +fce99e37c5d54bdb6668864d2cd9c1d0 gdb/testsuite/gdb.base/callfuncs.c +7960181a9746bd095d464c0a304d7c43 gdb/testsuite/gdb.base/callfuncs.exp +71babf1dd57d05e9d200883f6ac4bb5d gdb/testsuite/gdb.base/charset.c +938b6e3cfd4d1b2707a937fb516d993a gdb/testsuite/gdb.base/charset.exp +91a9797c36773f25d2961a2478d37c89 gdb/testsuite/gdb.base/chng-syms.c +91dbe3696c7e00c1e504340ef9ff26cd gdb/testsuite/gdb.base/chng-syms.exp +30c83b012547439baf0bdc2e434ca2aa gdb/testsuite/gdb.base/code-expr.exp +00ef696480a9fdcb085cdf98561f29b6 gdb/testsuite/gdb.base/commands.exp +488b024dd9948ec46181a20cb45758dd gdb/testsuite/gdb.base/completion.exp +df7ab9e8669eed8b605d3f815f61c36d gdb/testsuite/gdb.base/complex.c +a63f285778c17a9d453af01b4ff7a973 gdb/testsuite/gdb.base/complex.exp +651119d1f6861763b0af972709fd9698 gdb/testsuite/gdb.base/cond-expr.exp +def4010769f7f492e653c90ba8272b1f gdb/testsuite/gdb.base/condbreak.exp +0a38768b03d77eda97cc0c83af11699d gdb/testsuite/gdb.base/consecutive.c +1130760ccbabb0197daa4e224d88d1d9 gdb/testsuite/gdb.base/consecutive.exp +610d0ec5dc0ae6317e3f9454b8300660 gdb/testsuite/gdb.base/constvars.c +84a7fa577e209a4d4a40453593b16dc1 gdb/testsuite/gdb.base/constvars.exp +50e877cf09415173722b8c21eed9a378 gdb/testsuite/gdb.base/corefile.exp +427760e8de2aab3cd02962aafdb99481 gdb/testsuite/gdb.base/coremaker.c +5b80768aac60f433336ef045b5fe503a gdb/testsuite/gdb.base/coremaker2.c +f92cf37b9849545e7ce2ba344ebd56bb gdb/testsuite/gdb.base/cvexpr.c +66a6cc7779c88715c6aba9beae59086b gdb/testsuite/gdb.base/cvexpr.exp +c8b29ef2ecb662f50ea8aa7966c163f8 gdb/testsuite/gdb.base/d10v.ld +35ce0d1e8a6cc6a278649ec7464d8a1c gdb/testsuite/gdb.base/d10vovly.c +96972aa560dc9ae7bf4aa451089dd652 gdb/testsuite/gdb.base/dbx.exp +58769d0e980e244d5efee1f8f48e88c7 gdb/testsuite/gdb.base/default.exp +d75072033b5aa6a428ecebb54901b110 gdb/testsuite/gdb.base/define.exp +e17c89ad0316df1b06b891ef7a55c2a7 gdb/testsuite/gdb.base/detach.exp +6cd78185592d6b4044a13581688e6cf8 gdb/testsuite/gdb.base/display.c +29a0bfb1ac83eaa5afc10efeedfc413c gdb/testsuite/gdb.base/display.exp +ca9ff510856000f9ee111095ef00f913 gdb/testsuite/gdb.base/dump.c +af920ca32a6573d11568cdac8f4dea88 gdb/testsuite/gdb.base/dump.exp +9075c0d3ec951a0abe5676b1ef96ec48 gdb/testsuite/gdb.base/echo.exp +ecbc80201eeced19112ea5573027f051 gdb/testsuite/gdb.base/ena-dis-br.exp +b9638337fbfa28806436681d540a2311 gdb/testsuite/gdb.base/ending-run.c +fb77ce2f143c4b0f379f1b6252f2258f gdb/testsuite/gdb.base/ending-run.exp +81c3b4c3fcb5a022955c9ef9d469c4b5 gdb/testsuite/gdb.base/environ.exp +211ec4f59e5be497d413e019bcecfc17 gdb/testsuite/gdb.base/eval-skip.exp +fe778e4ca9af81e067b376479c5f876d gdb/testsuite/gdb.base/execd-prog.c +2d5e42c7a5399e6b0e5088388b4cfcc0 gdb/testsuite/gdb.base/exprs.c +55a20d2ea634f35e3a72ce9974c4a70d gdb/testsuite/gdb.base/exprs.exp +0a295f41f0583ed9b21670c4788e416d gdb/testsuite/gdb.base/fileio.c +bb5612c8d001e8144111a9e8ed0eb51c gdb/testsuite/gdb.base/fileio.exp +c91a165e1f3c3fa15a1e255286b8cae5 gdb/testsuite/gdb.base/finish.exp +d7304fcc209574d8e454c348a8fa942f gdb/testsuite/gdb.base/float.exp +5acfdd7a2dd0575778a59acf1e3e899e gdb/testsuite/gdb.base/foll-exec.c +eefd76aaa3fd774ba882caeb8b5a7890 gdb/testsuite/gdb.base/foll-exec.exp +9ab04e56d1356b09f45c460f3338996f gdb/testsuite/gdb.base/foll-fork.c +be056e486518a4e214f569365159a062 gdb/testsuite/gdb.base/foll-fork.exp +a7ea93bfb6e477f12e7a3c6404410b88 gdb/testsuite/gdb.base/foll-vfork.c +97afa991b7f063aa7c46d74a42f92d0c gdb/testsuite/gdb.base/foll-vfork.exp +c6a16edc9359f0384e9bb01cc216272c gdb/testsuite/gdb.base/foo.c +9e1e774f5531e477af9498e0b4a52be5 gdb/testsuite/gdb.base/freebpcmd.c +2ff49eaf4db0985b256e79e03ab8209d gdb/testsuite/gdb.base/freebpcmd.exp +e263d03bb6f3616f05e38769be7a0c5d gdb/testsuite/gdb.base/funcargs.c +1e3db7de8522d3b2cc3c28625c7e7962 gdb/testsuite/gdb.base/funcargs.exp +d9b2a9d592f70524f1b24394c262d9cf gdb/testsuite/gdb.base/gcore.c +e5d420875950e9837bed75520e62aa4f gdb/testsuite/gdb.base/gcore.exp +201b1e7cda5fe07f2ec0588491870476 gdb/testsuite/gdb.base/gdb1056.exp +7354dab51e84c82dbd7e5d8aab734be8 gdb/testsuite/gdb.base/gdb1090.c +f593204485765887caef1fab43b56a3a gdb/testsuite/gdb.base/gdb1090.exp +151b3327206fa8d34e59210f4c9d492f gdb/testsuite/gdb.base/gdb1250.c +8273e1b9b96551105d11fc7c359a24cc gdb/testsuite/gdb.base/gdb1250.exp +9546d8e111806b5ad1889cfc3efdc982 gdb/testsuite/gdb.base/gdb1476.c +1eca46287cacb0a0159271c1af723b9e gdb/testsuite/gdb.base/gdb1476.exp +4232da6d5581c0fa4c44da546289de93 gdb/testsuite/gdb.base/gdb1555-main.c +e3c60ed457773040ca69854ec22ec8bd gdb/testsuite/gdb.base/gdb1555.c +25ff15e1b3a612addb1143b90ecb55a4 gdb/testsuite/gdb.base/gdb1555.exp +a2bfa5dea845c91374b0ca3348d5fe1c gdb/testsuite/gdb.base/gdb_history +bcecd23b18e6167cbe3e0389bfb37fd0 gdb/testsuite/gdb.base/gdbvars.exp +9cd4ef136dfbee149a4056477283fa41 gdb/testsuite/gdb.base/grbx.c +e04603d844309e85e3e34d3b30700027 gdb/testsuite/gdb.base/help.exp +f5084bccca9af02ac220b5399253c9a8 gdb/testsuite/gdb.base/huge.c +8a73e9b5254bf4649fdc49af449ed9b5 gdb/testsuite/gdb.base/huge.exp +f987247ada9c599f12b526ce2f3b6e2e gdb/testsuite/gdb.base/info-proc.exp +55bbb1088e1173143dd23818588c559c gdb/testsuite/gdb.base/int-type.c +57e887f3379fccaae0cdaeb9f2a5a400 gdb/testsuite/gdb.base/interrupt.c +c6643f7d431ab97838867df2a15b28e9 gdb/testsuite/gdb.base/interrupt.exp +5fefadea13c06424265ee8e5dbf68dd6 gdb/testsuite/gdb.base/jump.c +5ded83121a71b46fb6d7eb5430db2d5f gdb/testsuite/gdb.base/jump.exp +2a15b07c2dcc5fa0a53bc4717b0d7b42 gdb/testsuite/gdb.base/langs.exp +a7fcf828c54dbdc1100d525500c41a4c gdb/testsuite/gdb.base/langs0.c +2d0b8bc2c2b4eb4f8a28b7cb39ce5dca gdb/testsuite/gdb.base/langs1.c +823ccdf3ec56d8acb08d21598d0f1d8e gdb/testsuite/gdb.base/langs1.f +c62aebd49fcf2ece63ec68610c644c0e gdb/testsuite/gdb.base/langs2.c +c90e022fb5ef3df8a5639df233f9c350 gdb/testsuite/gdb.base/langs2.cxx +23a9d320d2c8ac0836c97967984bd51d gdb/testsuite/gdb.base/list.exp +e7d4aa964e0ac3b22a0ecfeef466c437 gdb/testsuite/gdb.base/list0.c +d98c219c48dd073b09144e6cdb9de268 gdb/testsuite/gdb.base/list0.h +8b38bf10b14906aeede912d147c23b43 gdb/testsuite/gdb.base/list1.c +b589461aa6a9c9e419c082b7014c237f gdb/testsuite/gdb.base/logical.exp +a54639191cb3e89e3b547b86c0aef0cd gdb/testsuite/gdb.base/long_long.c +23be93503a8f2ef7d0c978d1113f45e8 gdb/testsuite/gdb.base/long_long.exp +d89474265b62f35df0c23a47bf1cc11a gdb/testsuite/gdb.base/m32r.ld +35ce0d1e8a6cc6a278649ec7464d8a1c gdb/testsuite/gdb.base/m32rovly.c +316f3fbf32b8b180129717ecb4633aa1 gdb/testsuite/gdb.base/macscp.exp +3f678def3cc5c8c57803f411fd798d0d gdb/testsuite/gdb.base/macscp1.c +256625bcc48a090ec4e5b85d1affa9bc gdb/testsuite/gdb.base/macscp2.h +bbd68c316d4ba5e21f8aac02eb605fa4 gdb/testsuite/gdb.base/macscp3.h +dc1c7b2d0d97de5e07f0046fca14d586 gdb/testsuite/gdb.base/macscp4.h +bfbb0d654ee247fe755f9ee1be514e8f gdb/testsuite/gdb.base/maint.exp +c779221fb70a0e5b29aa0fffeb4b46b2 gdb/testsuite/gdb.base/mips_pro.c +8fd94258da79333e73ac9ad4faafc5bf gdb/testsuite/gdb.base/mips_pro.exp +643671e20fe8eff654f14011ab332137 gdb/testsuite/gdb.base/miscexprs.c +a53db384f24cc2f13b54641e8484463d gdb/testsuite/gdb.base/miscexprs.exp +b7d340c5410e83eab50f73e499be0759 gdb/testsuite/gdb.base/nodebug.c +96cf7e971da487ba62c8e1c94e8fb60e gdb/testsuite/gdb.base/nodebug.exp +469b90b7b48e01734bee63a6321e2faf gdb/testsuite/gdb.base/opaque.exp +52ba3d967b2b82fff0684a32c9306380 gdb/testsuite/gdb.base/opaque0.c +177d0aa2dc05a0887607543ae7a63ae4 gdb/testsuite/gdb.base/opaque1.c +cc19ee1eb79fe010ad5bab989640c407 gdb/testsuite/gdb.base/overlays.c +faa750cd2900fbbbd609ea743fd1d038 gdb/testsuite/gdb.base/overlays.exp +6fa3516a413a089a2bed7b00775ed95b gdb/testsuite/gdb.base/ovlymgr.c +beb7ddd8ac440e541b4ff7458987281f gdb/testsuite/gdb.base/ovlymgr.h +5fe30c7d9c3428cf65e02db149b3c852 gdb/testsuite/gdb.base/page.exp +0fec50da02e7cd3be0581d9269e8b27b gdb/testsuite/gdb.base/pc-fp.c +acf02b54a7cd478c1f770df64166408a gdb/testsuite/gdb.base/pc-fp.exp +e366a3658e7a4581fd1f0f28b7c689e3 gdb/testsuite/gdb.base/pending.c +3eeab53be35c2e2241520478f2d59a27 gdb/testsuite/gdb.base/pending.exp +e5661fce945960702d34e188dc137490 gdb/testsuite/gdb.base/pendshr.c +8d268468e492f058d3ca8b553a0cfc54 gdb/testsuite/gdb.base/pointers.c +2e3d53cd90ed8564c46f911eeb0763b8 gdb/testsuite/gdb.base/pointers.exp +20a5cda7d951262d0e36cb599fdb8857 gdb/testsuite/gdb.base/printcmds.c +89afc92c569b3f71df27409279a0ea27 gdb/testsuite/gdb.base/printcmds.exp +a0de2136d2a31c14df5ca43acfb185d2 gdb/testsuite/gdb.base/psymtab.exp +b263e085b920ccae2568157fcc33189f gdb/testsuite/gdb.base/psymtab1.c +f356ff50643e59000ef3d9f24089698b gdb/testsuite/gdb.base/psymtab2.c +05524755778cd48d384594d06c45b463 gdb/testsuite/gdb.base/ptype.c +bbea5bb5ba851bfd7b82d3aaa538d4c4 gdb/testsuite/gdb.base/ptype.exp +a7acac6fdc62c0efb806906436a5100d gdb/testsuite/gdb.base/radix.exp +d0af9180f489613bd0f46b425b99bad6 gdb/testsuite/gdb.base/readline.exp +b7c0b9263a943f4e519a0f797e126317 gdb/testsuite/gdb.base/recurse.c +bb51a80d999f218749eebd66efc62524 gdb/testsuite/gdb.base/recurse.exp +2c0669f4c38e5ccfbe2c806e1a753df5 gdb/testsuite/gdb.base/regs.exp +684697d0d7067fdcdfe5d748511e5357 gdb/testsuite/gdb.base/relational.exp +686dfafae5faded4434b5c7aecfeaa14 gdb/testsuite/gdb.base/relocate.c +f02bbbb3fa3f3d014be89bff9acb4bb1 gdb/testsuite/gdb.base/relocate.exp +79696e315e518bcff76ca31d67e55856 gdb/testsuite/gdb.base/remote.c +9d053b91f9b3e58f5a9932be0be0b84b gdb/testsuite/gdb.base/remote.exp +27894b27c524e566e4d42589ade0cf8f gdb/testsuite/gdb.base/reread.exp +b27553d250bc9c1302b8081e241e4630 gdb/testsuite/gdb.base/reread1.c +a3e9015380f0b2b958c6387b733901ab gdb/testsuite/gdb.base/reread2.c +ca133757968b4ebea39a4d1e62aba91f gdb/testsuite/gdb.base/restore.c +e491ec9199c1ed67de25dc40bd92808a gdb/testsuite/gdb.base/restore.exp +a8afc935fcccb233c94780a5db339e1b gdb/testsuite/gdb.base/return.c +13a079a77310dbe445c45c0e621c3f17 gdb/testsuite/gdb.base/return.exp +a083d8d4881ea947f4ec0a7af80e02e8 gdb/testsuite/gdb.base/return2.c +10c8b7f92f911fb4c553fa74cec6cc62 gdb/testsuite/gdb.base/return2.exp +d9eeb3be3ebabd9f01a38401b6df8314 gdb/testsuite/gdb.base/run.c +a2a79551e1b98c1dd032f04465f048dc gdb/testsuite/gdb.base/scope.exp +a2b39c6753b63d36e9076b2bc12609ea gdb/testsuite/gdb.base/scope0.c +f3b699a47e41a789efbd9f2bf3192364 gdb/testsuite/gdb.base/scope1.c +8ff9780c746b7d4d3cb76ac45da56ab6 gdb/testsuite/gdb.base/sect-cmd.exp +2571b152b07c4691f77d64f88958c06c gdb/testsuite/gdb.base/selftest.exp +ba416b5e08382958d4a43c9c20c05472 gdb/testsuite/gdb.base/sepdebug.c +f3d1bfd3b413e34d7b3c8864d370b201 gdb/testsuite/gdb.base/sepdebug.exp +fd21df76b25003cb1b35af07ebac8991 gdb/testsuite/gdb.base/setshow.c +9f41239b45ecde01004ee202981d37e5 gdb/testsuite/gdb.base/setshow.exp +366a61f5feeadf4733e79506ff7f4271 gdb/testsuite/gdb.base/setvar.c +c3d589d2a94dbe7531ce6b4e481ed2a3 gdb/testsuite/gdb.base/setvar.exp +71f6089eec75294622693f43e606af97 gdb/testsuite/gdb.base/shlib-call.exp +4417659f325c1872e097516a2b17a031 gdb/testsuite/gdb.base/shmain.c +ea313b317035fa79cc1ae9bf6ef7d4ca gdb/testsuite/gdb.base/shr1.c +4c06f99b8d9db6a8a11b0e5474c3b5f5 gdb/testsuite/gdb.base/shr2.c +3764973c71d5aa701031b4e66fd276d3 gdb/testsuite/gdb.base/shreloc.c +e432ccf9a88cafdb6d5ed558f6161589 gdb/testsuite/gdb.base/shreloc.exp +3a2a211e5b6d5888758f26dbd9cd9c23 gdb/testsuite/gdb.base/shreloc1.c +3b1d57da2ee4cce1781d966f09f8d7fb gdb/testsuite/gdb.base/shreloc2.c +8ec70b82c42267a8bcdedba8721a7cb3 gdb/testsuite/gdb.base/sigall.c +4b5b5225fcea41cfd8fec72be906dac6 gdb/testsuite/gdb.base/sigall.exp +24ddac9178f2f43b2b0f577c77aef032 gdb/testsuite/gdb.base/signals.c +9d5ecbf1bf101a23d73dcbb63b02344f gdb/testsuite/gdb.base/signals.exp +2d5b486956a7f497ac3e5969bac13c3f gdb/testsuite/gdb.base/sizeof.c +3d77ff8355b4d7ea4d307bb066fc96e1 gdb/testsuite/gdb.base/sizeof.exp +e711a6cfdf17afc08fbd300867145dd6 gdb/testsuite/gdb.base/so-impl-ld.c +9d24453edc5e49b1da84335dc7883779 gdb/testsuite/gdb.base/so-impl-ld.exp +1429ffbb9973f67ebe556228ae4dfc66 gdb/testsuite/gdb.base/so-indr-cl.c +3b86649016dafbeb80fe87007675294e gdb/testsuite/gdb.base/so-indr-cl.exp +0cdb3ac52471574e63518d04e7490c77 gdb/testsuite/gdb.base/solib.c +94b46fe7df64f5ba7e817ffefe6d2359 gdb/testsuite/gdb.base/solib.exp +09b3514ecddad4ca9dd40f06f77ca5cc gdb/testsuite/gdb.base/solib1.c +c08d6d5da171e08cd8bce11e6ee9ffb5 gdb/testsuite/gdb.base/solib2.c +25dd3e940b7f381b4985683b64dff8cf gdb/testsuite/gdb.base/ss.h +d38881228941b667d1352bd915e0a854 gdb/testsuite/gdb.base/step-line.c +71d30ad481f6195760b808b810273e7f gdb/testsuite/gdb.base/step-line.exp +7206edd78b2338b2c8a5ad3c3f2fb791 gdb/testsuite/gdb.base/step-line.inp +9ffc2cd8e384888785a57bd5ed8168d2 gdb/testsuite/gdb.base/step-test.c +fc747038f51e6fd85a5c2eb1b046ef42 gdb/testsuite/gdb.base/step-test.exp +1ea088b852b87134ad1b9038b0dd2204 gdb/testsuite/gdb.base/store.c +7e7d239e7100be5671f2c2990dcf69a3 gdb/testsuite/gdb.base/store.exp +86167fcd80ed0981793214b2d1ebdfd8 gdb/testsuite/gdb.base/structs.c +c1fc09c647ec6559877e7a18b65a106d gdb/testsuite/gdb.base/structs.exp +ea9603592d237a2624d44c1a417ebaef gdb/testsuite/gdb.base/structs2.c +ee778a669792e153b9a3b5c3a5eca548 gdb/testsuite/gdb.base/structs2.exp +f979f053e2cd1a61d9630b75d70607ef gdb/testsuite/gdb.base/sum.c +4b1c9e381a4febb6792520fb20ef6968 gdb/testsuite/gdb.base/term.exp +e230b8767f5ad5901a40b01435d17089 gdb/testsuite/gdb.base/twice.c +d39dd7e6c000d2ea53e26dcbb2c78e0b gdb/testsuite/gdb.base/twice.exp +fc0f0ff540d9196ce79b6bcba912005c gdb/testsuite/gdb.base/until.exp +27120a964678d7be0acda6d1687f65dc gdb/testsuite/gdb.base/varargs.c +669009a810c3d43efbd02fab15f262a9 gdb/testsuite/gdb.base/varargs.exp +1a9fca83cee9e223ab94207b280c403b gdb/testsuite/gdb.base/vforked-prog.c +0bc669172c8943baf91e1891aacce69b gdb/testsuite/gdb.base/volatile.exp +2394ca7c0136f073f6ef282624a651d3 gdb/testsuite/gdb.base/watchpoint.c +d66283988b1fcfbae48c47b6668cdc77 gdb/testsuite/gdb.base/watchpoint.exp +c7fbe8854040a2bb100a7b6a03d3e5e3 gdb/testsuite/gdb.base/whatis-exp.exp +249f024a162cae2c7164d2bf5e5ccd7f gdb/testsuite/gdb.base/whatis.c +c54397df576846b1182483ad4c6fdd39 gdb/testsuite/gdb.base/whatis.exp +e82f0cae062478832763b121dd33f0d7 gdb/testsuite/gdb.cp/Makefile.in +fa88dcd56730da0447f3d14fe40a5cd0 gdb/testsuite/gdb.cp/ambiguous.cc +14555fe9da732a1ca357ef97e1e76635 gdb/testsuite/gdb.cp/ambiguous.exp +2088f98bb23167ea5e0c8b394c560519 gdb/testsuite/gdb.cp/annota2.cc +333672bca861a0abb80d8ba3609ea744 gdb/testsuite/gdb.cp/annota2.exp +2088f98bb23167ea5e0c8b394c560519 gdb/testsuite/gdb.cp/annota3.cc +e9be2b37996566ebbf12562f12b6b39b gdb/testsuite/gdb.cp/annota3.exp +582fe010ae6cfa3c16429c65636bd651 gdb/testsuite/gdb.cp/anon-union.cc +d94735d63db1e1ca15a5cf6eb085bc5b gdb/testsuite/gdb.cp/anon-union.exp +4f2277628f5e85ec03d09f6801009802 gdb/testsuite/gdb.cp/breakpoint.cc +911af0f4d20ff59e21546826d7bff11a gdb/testsuite/gdb.cp/breakpoint.exp +b5fedd23b64d0faeedc3cecdde2e2aca gdb/testsuite/gdb.cp/bs15503.cc +4ceee57add7b8eda3d07cd17394d905c gdb/testsuite/gdb.cp/bs15503.exp +49d31866e1b2029326c237b6d0195eb8 gdb/testsuite/gdb.cp/casts.cc +ea26ef2dff81fff84be88891e0d18f79 gdb/testsuite/gdb.cp/casts.exp +c6c1fa5dbdc1e32d7ffe734df4ab75e3 gdb/testsuite/gdb.cp/class2.cc +5e7b9c69153312095eb652cc4efc5314 gdb/testsuite/gdb.cp/class2.exp +655c2879707d28e377904faba8b7178a gdb/testsuite/gdb.cp/classes.cc +de413434fab02990bebeaa2fea68dbd7 gdb/testsuite/gdb.cp/classes.exp +8b5504ea8f47f041cd1e870dd5674f53 gdb/testsuite/gdb.cp/cplusfuncs.cc +30b00a620bd85c2cb13a184f7b9ac470 gdb/testsuite/gdb.cp/cplusfuncs.exp +823926fd7d8df26269049cb16f78d140 gdb/testsuite/gdb.cp/ctti.exp +71a4a9598ab0c57e27a27859bfe24ef0 gdb/testsuite/gdb.cp/cttiadd.cc +2056b75ba0f6a1dc66b27e84b9971ba5 gdb/testsuite/gdb.cp/cttiadd1.cc +324fece7cfe77f4c98e2a17e5ae75364 gdb/testsuite/gdb.cp/cttiadd2.cc +97dc851f1743b769635112fbbb65ff25 gdb/testsuite/gdb.cp/cttiadd3.cc +1d5c171bb2be3f964e4e8e6e9e08731e gdb/testsuite/gdb.cp/demangle.exp +d4c5d86832a3728253bb6e303dca8814 gdb/testsuite/gdb.cp/derivation.cc +3cd363499769e54bbbf6fee711e897d3 gdb/testsuite/gdb.cp/derivation.exp +9faa8339cfbf015fde876a3e7dc5589f gdb/testsuite/gdb.cp/exception.cc +03f1a2ebe9c4cfbf03e5ec59bf63a82a gdb/testsuite/gdb.cp/exception.exp +dcbaddb5552d4990c58221d1ce771d2d gdb/testsuite/gdb.cp/gdb1355.cc +3ad755aaa7f75e1b7d3c2429689db2f7 gdb/testsuite/gdb.cp/gdb1355.exp +bec5831953699a0daf2274369c6f1ed1 gdb/testsuite/gdb.cp/hang.H +089ad038e3a25cf02e7292e54e7211f2 gdb/testsuite/gdb.cp/hang.exp +22f928abbcff4e8dc10dfac79ea86311 gdb/testsuite/gdb.cp/hang1.C +221eed5a3233c502015a7f69c71eb693 gdb/testsuite/gdb.cp/hang2.C +81270652e911c432e26ef4b3bec6bc66 gdb/testsuite/gdb.cp/hang3.C +149d5a1b17df4ed57efd97702ee6f740 gdb/testsuite/gdb.cp/inherit.exp +584a50069ae4ae90c745978c0bb994db gdb/testsuite/gdb.cp/local.cc +e8a628a9de15f536ce0ff50579b2bc91 gdb/testsuite/gdb.cp/local.exp +010af669f824c8194c82fb921c6c2b2f gdb/testsuite/gdb.cp/m-data.cc +3118b023dfac90244cee1113a7d5c32c gdb/testsuite/gdb.cp/m-data.exp +9e481afa71dc8cf8b2876e7735c4d947 gdb/testsuite/gdb.cp/m-static.cc +2269c827396d7393f1e3c98bbcb32e4a gdb/testsuite/gdb.cp/m-static.exp +5756b206314b4e9b256a54b794fa5366 gdb/testsuite/gdb.cp/m-static.h +7844dbfb63d5ee815db3c14cb769c796 gdb/testsuite/gdb.cp/m-static1.cc +71f85099658141dde529a13d6838dd6f gdb/testsuite/gdb.cp/maint.exp +954cfee559a88d4939199720a0123b9c gdb/testsuite/gdb.cp/member-ptr.cc +05f91f7fd4e90ce55933a0c113dd43e1 gdb/testsuite/gdb.cp/member-ptr.exp +53d65c3b49d4d39b7a1c8ff6d68c8a65 gdb/testsuite/gdb.cp/method.cc +b677bbd497abff0d335c164cab65bf58 gdb/testsuite/gdb.cp/method.exp +ddad9ba3b6f6edd4c639d1788a3d1db8 gdb/testsuite/gdb.cp/misc.cc +9e0aa441f5a8ed6a0ff508d22a2ab375 gdb/testsuite/gdb.cp/misc.exp +593e2413f186870185480c45ed5efe0f gdb/testsuite/gdb.cp/namespace.cc +b136304229591cba0d9f151070142acf gdb/testsuite/gdb.cp/namespace.exp +ea54384eeced12e1450a1347910b6b18 gdb/testsuite/gdb.cp/namespace1.cc +0a0023c3a8cf474ec7e85481879828d0 gdb/testsuite/gdb.cp/overload.cc +3746039ed86f1ae89c5fbad53e5301b2 gdb/testsuite/gdb.cp/overload.exp +1e6ecfe65de278a0c1e062badc9789e3 gdb/testsuite/gdb.cp/ovldbreak.cc +a33a48dcca8228f761a994f345065097 gdb/testsuite/gdb.cp/ovldbreak.exp +0a15a0bc517ee0acca862308c89de14b gdb/testsuite/gdb.cp/pr-1023.cc +cb9d8280a0b7332e8bf9865a42a2a24a gdb/testsuite/gdb.cp/pr-1023.exp +07fa7f618722031893284e4df11fe13e gdb/testsuite/gdb.cp/pr-1210.cc +015ff1129bb4cdb5aad3c5ce626661be gdb/testsuite/gdb.cp/pr-1210.exp +5176d9071bc98b74d5c9cd3d854a7834 gdb/testsuite/gdb.cp/pr-1553.cc +280f5ce2f340829b63877ddc086259fd gdb/testsuite/gdb.cp/pr-1553.exp +6d7e902a5c586f3732cdd94108b06ea7 gdb/testsuite/gdb.cp/pr-574.cc +801f397f557114a002041b4c1dbd991e gdb/testsuite/gdb.cp/pr-574.exp +5cc27b72c30cc6f7662b0bd905b36aed gdb/testsuite/gdb.cp/printmethod.cc +8a50ef2995a84842fd0a9ea5e3484d32 gdb/testsuite/gdb.cp/printmethod.exp +c02d071b4af80b5f7532f378f17c5162 gdb/testsuite/gdb.cp/psmang.exp +65de6792316a7abdebadcf6c0fee17f5 gdb/testsuite/gdb.cp/psmang1.cc +9a48c8c1f04b47004135630c12b9972c gdb/testsuite/gdb.cp/psmang2.cc +511a6f21e5689ee6ce16f02bb8ac8796 gdb/testsuite/gdb.cp/ref-types.cc +ab245824bd92d2075e80b52ebea938a8 gdb/testsuite/gdb.cp/ref-types.exp +6e2f550460a7c84e961017dd97e138dd gdb/testsuite/gdb.cp/rtti.exp +0462d9e14cbb46e835a439262e142259 gdb/testsuite/gdb.cp/rtti.h +b7fb1cc3a40d3500b995bbefdf762fbb gdb/testsuite/gdb.cp/rtti1.cc +222fe0be2dc42d29752bb4a5380a3ff0 gdb/testsuite/gdb.cp/rtti2.cc +1536cc5f65a058b4d13dfcd79fbd8619 gdb/testsuite/gdb.cp/templates.cc +91b661d9234bba678ff4f194ced11f51 gdb/testsuite/gdb.cp/templates.exp +d9543839ad23c15eeddd25f990cd272e gdb/testsuite/gdb.cp/try_catch.cc +4b69b406088f179e7e054cdc95ba1cd6 gdb/testsuite/gdb.cp/try_catch.exp +a4011385276a102ff481ca6b86f2906d gdb/testsuite/gdb.cp/userdef.cc +e27d36723379a94609295daa9d4eabc1 gdb/testsuite/gdb.cp/userdef.exp +945da4ece00b055700a5a322cbee2d19 gdb/testsuite/gdb.cp/virtfunc.cc +3b019a6e209215b722a30bec7d22ad45 gdb/testsuite/gdb.cp/virtfunc.exp +7223f89fe13042a716303a40db766767 gdb/testsuite/gdb.disasm/Makefile.in +357aad7714972445a94a7e58c9743efc gdb/testsuite/gdb.disasm/am33.exp +9d7ec73ab52e55ec1f83ec9e35523702 gdb/testsuite/gdb.disasm/am33.s +bade4ffea198a263af262bf6df3f7b28 gdb/testsuite/gdb.disasm/h8300s.exp +cb76fc798d647b1ee8ba82f8ad9a5584 gdb/testsuite/gdb.disasm/h8300s.s +056d65b937ef90537213d9317bc259b7 gdb/testsuite/gdb.disasm/hppa.exp +1531e9f2d8c5fe8c476a72c8621ac6f5 gdb/testsuite/gdb.disasm/hppa.s +8df48a7abc7ba3009ba5f49d74d3c8f9 gdb/testsuite/gdb.disasm/mn10200.s +5eba2ab369ad9613a6c6f470647f73d6 gdb/testsuite/gdb.disasm/mn10300.exp +e02ce2008b0f7cd2c4bd231e78d46c8c gdb/testsuite/gdb.disasm/mn10300.s +36450ef0babfd3c6f9867a4cf231ddc7 gdb/testsuite/gdb.disasm/sh3.exp +e546b5aa7eb88708555537439de19900 gdb/testsuite/gdb.disasm/sh3.s +f41230f8eff93a371b3faf3209e68cd1 gdb/testsuite/gdb.disasm/t01_mov.exp +73c5cd7ed86e7e6b41d1e576f311eeeb gdb/testsuite/gdb.disasm/t01_mov.s +039f81886ee6faf2dc8a91e833ddd582 gdb/testsuite/gdb.disasm/t02_mova.exp +0acc4aeabf1f5d050371011a1e2db775 gdb/testsuite/gdb.disasm/t02_mova.s +2a5bbcaa4140ee63ebb5661e817a9c11 gdb/testsuite/gdb.disasm/t03_add.exp +5cf6fb959f1de5dbfa41541a8286a01c gdb/testsuite/gdb.disasm/t03_add.s +786174a5e3afabf20b062015a6293f6a gdb/testsuite/gdb.disasm/t04_sub.exp +b9bd060d194d5ce64afbd5c8785b7211 gdb/testsuite/gdb.disasm/t04_sub.s +167810df60d29277de69bcb2a2b23665 gdb/testsuite/gdb.disasm/t05_cmp.exp +131ee421fad26db64b6d6bba8368e5bb gdb/testsuite/gdb.disasm/t05_cmp.s +c372c558382dab5eb7ce6661b054ec96 gdb/testsuite/gdb.disasm/t06_ari2.exp +85ba3783b07c440f998dd13619a094d3 gdb/testsuite/gdb.disasm/t06_ari2.s +1b9b94efa363975f861a60a226160c4a gdb/testsuite/gdb.disasm/t07_ari3.exp +542d50518d01ead485efbb2e32d0f764 gdb/testsuite/gdb.disasm/t07_ari3.s +5235cee2e07163875862f952606eef53 gdb/testsuite/gdb.disasm/t08_or.exp +f4968aeae699c13b7a5a1975b3892a33 gdb/testsuite/gdb.disasm/t08_or.s +217ec8cc6d7588076858dc7f00d8fa83 gdb/testsuite/gdb.disasm/t09_xor.exp +7a1e51f2713793b0b90600f013077211 gdb/testsuite/gdb.disasm/t09_xor.s +e8cb627cdbd6cd1640f0dcd74ff1e915 gdb/testsuite/gdb.disasm/t10_and.exp +d525da6720c1b3b2dcaf13dee122c8e2 gdb/testsuite/gdb.disasm/t10_and.s +7451149a6c0caeedf18515689001351c gdb/testsuite/gdb.disasm/t11_logs.exp +bd2239a841782b7e03adf35c797b9602 gdb/testsuite/gdb.disasm/t11_logs.s +84f6ccde942b89f7cd6af881608ad8a8 gdb/testsuite/gdb.disasm/t12_bit.exp +7007158a552329abb3b6bc7f604e864a gdb/testsuite/gdb.disasm/t12_bit.s +3d7b3b073fdd3356a14ddad76c8e7280 gdb/testsuite/gdb.disasm/t13_otr.exp +d61dbceb528b78f5bb4b4907443afd07 gdb/testsuite/gdb.disasm/t13_otr.s +db06bdc80566cb5adea26e17530d3eab gdb/testsuite/gdb.fortran/exprs.exp +a113f784343dafa68685ad81e88d8865 gdb/testsuite/gdb.fortran/types.exp +484346ad386e8ad232982d613cf683d8 gdb/testsuite/gdb.gdb/complaints.exp +7ce6998752da86eee302cc5d33d5e731 gdb/testsuite/gdb.gdb/observer.exp +bfbd14ddf55fdac9c4b2ffc0166a4a0c gdb/testsuite/gdb.gdb/xfullpath.exp +a904198187ddbad3444244c4ac4352cd gdb/testsuite/gdb.hp/Makefile.in +7e2ad2824dada941c40e183acc7b2a79 gdb/testsuite/gdb.hp/configure +cd31fd392240c25cf69d3d30ae9188de gdb/testsuite/gdb.hp/configure.in +5ea7cc25704c6afa026b129b8211748b gdb/testsuite/gdb.hp/gdb.aCC/Makefile.in +a0bbe53b7c6f846724f86f1465218d9d gdb/testsuite/gdb.hp/gdb.aCC/configure +7cc267fd4fda7efc8fda1744a6851f85 gdb/testsuite/gdb.hp/gdb.aCC/configure.in +45152502f608f30690417f272d8236ed gdb/testsuite/gdb.hp/gdb.aCC/exception.exp +cc53bf59d2a9c47d276d1aac84bd0f50 gdb/testsuite/gdb.hp/gdb.aCC/optimize.c +818ec867f3bdb00145d820ac47686021 gdb/testsuite/gdb.hp/gdb.aCC/optimize.exp +2fefc4288b99b3e947ca1e21a82fc5ce gdb/testsuite/gdb.hp/gdb.aCC/run.c +2ca1a676119f0d65c39ab1b775d33f7f gdb/testsuite/gdb.hp/gdb.aCC/watch-cmd.exp +8428aa0ac90cc1baaec1f80269b59295 gdb/testsuite/gdb.hp/gdb.base-hp/Makefile.in +14c754799fcbf620f6a249cbc446e003 gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.c +2920a0b8e81a481a61a045fbafda7b3a gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.exp +87d7a6ef5b390f5fc337dbf9a98f5995 gdb/testsuite/gdb.hp/gdb.base-hp/configure +df306fb67b5a85d536cc36ede39c7745 gdb/testsuite/gdb.hp/gdb.base-hp/configure.in +aa06298d5aa3e73236eb27c425fa4846 gdb/testsuite/gdb.hp/gdb.base-hp/dollar.c +f0780b29ef92663f1737944650277059 gdb/testsuite/gdb.hp/gdb.base-hp/dollar.exp +d26b78129f6ede5217efccfb06f9d80d gdb/testsuite/gdb.hp/gdb.base-hp/genso-thresh.c +54e77a9296dcc133c8c1e6f11ca3b9e2 gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.c +37909f0c7c10bcdd0ca197885633de61 gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.exp +3dea1b9bc2e3aed256501550bf68d4cb gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.c +0084fbab482e4b55f30175bdb64468c2 gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.exp +d84fd299a458e5895433ae2c3dfbee29 gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.exp +905458dab9cfbee0df58ed9240e14af1 gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.s +ee6a945ab81a974f44ac63d3d49b108f gdb/testsuite/gdb.hp/gdb.base-hp/reg.exp +dead9d35aee1ff308fe3522dabedc3b8 gdb/testsuite/gdb.hp/gdb.base-hp/reg.s +465f43278cc7d0e79520ac7cd4420a02 gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.c +035b3f0d72564c9d97205c559d83de06 gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.exp +0326797e1ef25ac281e335defb13472d gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.exp +826cb85910a25693b5ec8940b9f17f02 gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.mk +484344e9489d51e698048e6a91576363 gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.sh +f3b9253b314a12126d1438b64f607792 gdb/testsuite/gdb.hp/gdb.compat/Makefile.in +00f1943eda306eea1225aa67d0716842 gdb/testsuite/gdb.hp/gdb.compat/average.c +e1c7bd7c6609a38b67e4a9383f5514da gdb/testsuite/gdb.hp/gdb.compat/configure +32b5056c9568e8f49b60a03707bf148e gdb/testsuite/gdb.hp/gdb.compat/configure.in +efdc8ddc5dba749425497347498fc5ab gdb/testsuite/gdb.hp/gdb.compat/sum.c +fbf537e72ce89db0e107c27b0339b49b gdb/testsuite/gdb.hp/gdb.compat/xdb.c +1d6255c634ec5650bf05e168820e52d6 gdb/testsuite/gdb.hp/gdb.compat/xdb0.c +87882e6b6268aeb4258a5d999f17c0fe gdb/testsuite/gdb.hp/gdb.compat/xdb0.h +943ae15521dca9cb0098128efc3b280a gdb/testsuite/gdb.hp/gdb.compat/xdb1.c +475f987590553eed1ed25a9c11ffa17f gdb/testsuite/gdb.hp/gdb.compat/xdb1.exp +58ce17fe6da5f73aef6ec537c2e27d06 gdb/testsuite/gdb.hp/gdb.compat/xdb2.exp +4c9af0ec3ea90b8ed85951b36c7dbf8b gdb/testsuite/gdb.hp/gdb.compat/xdb3.exp +9710952c98dc8eeefe0b4a1bd211af04 gdb/testsuite/gdb.hp/gdb.defects/Makefile.in +db822d6cd121c4db2c5386f1b18327d3 gdb/testsuite/gdb.hp/gdb.defects/bs14602.c +bd2e0786113e62b5acc6ad6291a76f34 gdb/testsuite/gdb.hp/gdb.defects/bs14602.exp +ad5b3374f11b43b9b407e2c12b36771f gdb/testsuite/gdb.hp/gdb.defects/configure +72ec8172adb4263d943d3b1969bd3d10 gdb/testsuite/gdb.hp/gdb.defects/configure.in +408c16c2ba0801d824d0c16563aa93a6 gdb/testsuite/gdb.hp/gdb.defects/solib-d.c +e15e6c68819e675e3152c4d3b89a23a3 gdb/testsuite/gdb.hp/gdb.defects/solib-d.exp +2c0a2c964be9bd822394d4c27d94351f gdb/testsuite/gdb.hp/gdb.defects/solib-d1.c +03f1b83c4f54667b4f0078457b15a52f gdb/testsuite/gdb.hp/gdb.defects/solib-d2.c +fe1cbe605feca5f78a08210252dfed66 gdb/testsuite/gdb.hp/gdb.objdbg/Makefile.in +0687fa8867c6ff62c2868ec1115ad5ba gdb/testsuite/gdb.hp/gdb.objdbg/configure +2b002bd5777ceffd1e2efb38e131fcab gdb/testsuite/gdb.hp/gdb.objdbg/configure.in +59089dac281ef67bda37958f7f255d2e gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01.exp +a96dbc772e2273ff024394cb9ec10b86 gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02.exp +36ee5c5a29d5f2de705b4153dfca881f gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03.exp +dc406239f235baa4ce28b3bc05b48cb3 gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04.exp +c12f8a440f9d7eab2053d5fb263d654f gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x1.cc +64a248fedafc6f5f792d6092a904faaa gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x2.cc +dfae478e1d95497e262872ee20047863 gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.cc +a9b4b350ab56451624e9364e1e2b6738 gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.h +930c3959f1e04319936c5a861682c7d6 gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x1.cc +afaf2237a24a13e7d47ff8dc5358bd2d gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x2.cc +1ac202c7c27f08ce5de62831fe6230fe gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x3.cc +54bba4286fdf72276ee52dba78eeb61e gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x1.cc +b93935b37dba86bc6c49acaae960efa9 gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x2.cc +ab81c17425f162902b2593b2af2965bc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x3.cc +146898361af7f03a16dfcc18ace2a23f gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x.h +48806746c4205bdf0d050b7c3a32210b gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x1.cc +76af0d0b7dd89e3eb8fdd7dd10334d59 gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x2.cc +37540d440cd0e9f5280d7123f3f963ed gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr +4f3c4e1c924d553e18775df711389e81 gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr.pa64 +d1035b543709f23158df094b6d49742b gdb/testsuite/gdb.hp/gdb.objdbg/tools/test-objdbg.cc +8e84c7c14c0bfef46c0aa768c32904bf gdb/testsuite/gdb.hp/tools/odump +ef06d8cfb625aa9c73eff51184bb10fd gdb/testsuite/gdb.java/Makefile.in +f11e6514a4ff5711fe597b249918de83 gdb/testsuite/gdb.java/jmisc.exp +e3a680cfde66129ed9607ad7c20fd6a0 gdb/testsuite/gdb.java/jmisc.java +25196521761500b629e0156f769f9dc5 gdb/testsuite/gdb.java/jmisc1.exp +3962ccaa018569e90a59a8afefffe140 gdb/testsuite/gdb.java/jmisc2.exp +f3ff9a3bfd8a020b5abf078d96fa30e0 gdb/testsuite/gdb.java/jv-exp.exp +347bfda3668dabef6efd1a0230dc328e gdb/testsuite/gdb.java/jv-print.exp +1efe6f6402cbf322cd8aa810521f4b17 gdb/testsuite/gdb.mi/ChangeLog-1999-2003 +a137c3c02589a00e9ec245499b6da025 gdb/testsuite/gdb.mi/Makefile.in +c81900dcf955c63e8a2bd0e32bc501bc gdb/testsuite/gdb.mi/basics.c +06a3204e9a327785ece0a420e35301ee gdb/testsuite/gdb.mi/gdb669.exp +cbd0dd25e371259b7e9b02fdfb5b96c0 gdb/testsuite/gdb.mi/gdb680.exp +5a1ff3ae7b8cd72760f91dfc87b2f43f gdb/testsuite/gdb.mi/gdb701.c +4bec8072c80b8549b6e26560b19d5f1c gdb/testsuite/gdb.mi/gdb701.exp +a57794f9629bee4dc7f3868362e8d4ff gdb/testsuite/gdb.mi/gdb792.cc +f4c04bf208c56622913b190d03602d05 gdb/testsuite/gdb.mi/gdb792.exp +77408052d39d40a80029fb6361c26105 gdb/testsuite/gdb.mi/mi-basics.exp +ec434680f02b054e6de15b2dfa12d795 gdb/testsuite/gdb.mi/mi-break.exp +56f4bd91dcb31e9aa701ab6345931577 gdb/testsuite/gdb.mi/mi-cli.exp +2748c57b9ccc6f5d68d793f547c07d42 gdb/testsuite/gdb.mi/mi-console.c +852f7818afcc5b0f94160fecd71957a7 gdb/testsuite/gdb.mi/mi-console.exp +96c005a83d0f4611ce038a86e0638ab5 gdb/testsuite/gdb.mi/mi-disassemble.exp +712aa7331a203acdcc8a2f316ff1cc1c gdb/testsuite/gdb.mi/mi-eval.exp +81dbb9495eb2c30cd2a251fb8fb373ea gdb/testsuite/gdb.mi/mi-file.exp +2a6ae6e5fdb562fa2615d386ffe239cf gdb/testsuite/gdb.mi/mi-hack-cli.exp +bcf7919688b898c368d037f79e31b0ba gdb/testsuite/gdb.mi/mi-pthreads.exp +d842f3134dbac91b77ca50d320988178 gdb/testsuite/gdb.mi/mi-read-memory.c +92e73d90611f698038c769534fe88756 gdb/testsuite/gdb.mi/mi-read-memory.exp +cd5b04c7b45602e3c3f1d1b22c655b90 gdb/testsuite/gdb.mi/mi-regs.exp +4e856f01c9c7358c981559e35ed57555 gdb/testsuite/gdb.mi/mi-return.exp +99713d622a8ccf747d8b6a7d6eaf02dc gdb/testsuite/gdb.mi/mi-simplerun.exp +1a56becdde5ec4456b0d1c6ca2625d83 gdb/testsuite/gdb.mi/mi-stack.exp +3571e24dbf11aa589734d330f8e3e1f2 gdb/testsuite/gdb.mi/mi-stepi.exp +036a2f4a4024c9519a6cc18dd84201cd gdb/testsuite/gdb.mi/mi-syn-frame.c +c1f5684546323f39985647476425b06b gdb/testsuite/gdb.mi/mi-syn-frame.exp +52c1978545cc7e608343ca81b191f7ee gdb/testsuite/gdb.mi/mi-until.exp +8ccd9f4ad45dd466a138aff23ce22187 gdb/testsuite/gdb.mi/mi-var-block.exp +08c0ef3201d4bfaf31e08b7275945cfb gdb/testsuite/gdb.mi/mi-var-child.exp +a64100dcf41363d68f2a727742b161c2 gdb/testsuite/gdb.mi/mi-var-cmd.exp +79fa7a2cdf3434e7cc7a34647c7db9d5 gdb/testsuite/gdb.mi/mi-var-display.exp +2757c741ba0ab82d7761af397e886824 gdb/testsuite/gdb.mi/mi-watch.exp +7d6e93f3fb3a635d086685aa7ed7bfed gdb/testsuite/gdb.mi/mi2-basics.exp +556c975ba0f9b12cdade84a490152b4f gdb/testsuite/gdb.mi/mi2-break.exp +9f5b20575bf8813fa3c535a12a5bd9fe gdb/testsuite/gdb.mi/mi2-cli.exp +9f0b48701a920ed57300937b8ec25256 gdb/testsuite/gdb.mi/mi2-console.exp +2d9474ff7919077f5b163b059385e024 gdb/testsuite/gdb.mi/mi2-disassemble.exp +48ff58ff1e5b198b9e87a61cc116d2a4 gdb/testsuite/gdb.mi/mi2-eval.exp +76201c65d9bb77d36370f31cbcf503d1 gdb/testsuite/gdb.mi/mi2-file.exp +2fea9eb9b76679539a167ae99fa33943 gdb/testsuite/gdb.mi/mi2-hack-cli.exp +cbd96de463e5cba623acf69215ee28ff gdb/testsuite/gdb.mi/mi2-pthreads.exp +ba4f82681386eb04c7a18f4e342b92a7 gdb/testsuite/gdb.mi/mi2-read-memory.exp +61e4ff81736f537347679ddf7b052dc3 gdb/testsuite/gdb.mi/mi2-regs.exp +9d289c33a4a32e8cf56b8d6338938435 gdb/testsuite/gdb.mi/mi2-return.exp +c4e396245f1a1c5f80db2f917157eaaf gdb/testsuite/gdb.mi/mi2-simplerun.exp +102ae6939db2e76d36cb4e8ac4a8e970 gdb/testsuite/gdb.mi/mi2-stack.exp +2931a5ba1e3ece574c348395f9df3f70 gdb/testsuite/gdb.mi/mi2-stepi.exp +71ccfb19e331ff88802d693f19bdee40 gdb/testsuite/gdb.mi/mi2-syn-frame.exp +7c12e2e2cd169a80b19f6b7aff785915 gdb/testsuite/gdb.mi/mi2-until.exp +f302367430952abb7fd0a71768bf1616 gdb/testsuite/gdb.mi/mi2-var-block.exp +004ef4829935b0bf597e17a509c7726f gdb/testsuite/gdb.mi/mi2-var-child.exp +9245b5569e2ae3062474387c04443017 gdb/testsuite/gdb.mi/mi2-var-cmd.exp +ed64bbeec9814314a73f403ad66a918a gdb/testsuite/gdb.mi/mi2-var-display.exp +a436b3876316ee232b9ae9a81c7a9deb gdb/testsuite/gdb.mi/mi2-watch.exp +c2611277466d0332b71fe3196fa4f29d gdb/testsuite/gdb.mi/pthreads.c +6b58acbe5f1fe573c27b67f2e2a2fee1 gdb/testsuite/gdb.mi/testcmds +e69d1583b75cdf649449a0263d46822f gdb/testsuite/gdb.mi/until.c +70161b7abdf792774c9f7b64639bdb7c gdb/testsuite/gdb.mi/var-cmd.c +2985193fddc2986e50caa3b7b1d62063 gdb/testsuite/gdb.objc/Makefile.in +68c117a857134abb2a5d162b6fc51dba gdb/testsuite/gdb.objc/basicclass.exp +f0f471d0b077ed32873ec23acd184ae2 gdb/testsuite/gdb.objc/basicclass.m +33d7d3f36faecd0017296729aa6c3866 gdb/testsuite/gdb.objc/nondebug.exp +680e14fd32f14cd93c56886bcb05f177 gdb/testsuite/gdb.objc/nondebug.m +05660f61cb4794190fd4693435969d6c gdb/testsuite/gdb.objc/objcdecode.exp +5bf9075727dbd558ccbf123d9e11859a gdb/testsuite/gdb.objc/objcdecode.m +d94fa505fcba6e3a9d0a647b9e6cd938 gdb/testsuite/gdb.stabs/Makefile.in +85d0360ff6db4270acb85d73092c7de9 gdb/testsuite/gdb.stabs/aout.sed +3ab1b76d17414351bc1f309e05355b18 gdb/testsuite/gdb.stabs/configure +f46c99d92567df69af2ff28e2007ce15 gdb/testsuite/gdb.stabs/configure.in +6fb5c366d78fe2c47f31555c035ddcb3 gdb/testsuite/gdb.stabs/ecoff.sed +c616dc41c0e3352e3100cec80c2bab68 gdb/testsuite/gdb.stabs/hppa.sed +2fee77e25d05036cb6fa5a7b28cb6f5e gdb/testsuite/gdb.stabs/weird.def +da50fdfe62ac5283b850b01e1bf1afed gdb/testsuite/gdb.stabs/weird.exp +fc215bfd0d5b89f95282f2bd7f807c55 gdb/testsuite/gdb.stabs/xcoff.sed +5673f18f6ae92e0b3a46e6be53e63362 gdb/testsuite/gdb.threads/Makefile.in +e368d934ffec610b9e0e4206ba4807aa gdb/testsuite/gdb.threads/gcore-thread.exp +62cf43ac0d2bba3a2043b8edbe0cf1e3 gdb/testsuite/gdb.threads/killed.c +b9706515575fac09aec93cb0d82e9aaa gdb/testsuite/gdb.threads/killed.exp +a60f402187882610e3160c4f6c4dd4b1 gdb/testsuite/gdb.threads/linux-dp.c +0906f1c5c67f88b6da8d34e03cf66236 gdb/testsuite/gdb.threads/linux-dp.exp +df82452f754ef15a81d71f46a0892757 gdb/testsuite/gdb.threads/print-threads.c +d6bf303a6ec7a6d5be345f0d1010f239 gdb/testsuite/gdb.threads/print-threads.exp +4ae9d1fb5da571a62fcb13bffe5655ab gdb/testsuite/gdb.threads/pthreads.c +4006f6fc820387c2d4aa8e0c5e6cfe26 gdb/testsuite/gdb.threads/pthreads.exp +42682b6c1fd80503e8379141c00722b6 gdb/testsuite/gdb.threads/schedlock.c +2616f01052187aade4eb85c28d2bdf9e gdb/testsuite/gdb.threads/schedlock.exp +6abe05b4e05fce5d6c228dd5ef8ec9cb gdb/testsuite/gdb.threads/step.c +74a8ea51bc751ee4e098c5c5811259b7 gdb/testsuite/gdb.threads/step.exp +9db30290e91c45e998efe6f61b9ad87e gdb/testsuite/gdb.threads/step2.exp +e5001139f4a6104a95b0e65b8e584edb gdb/testsuite/gdb.threads/switch-threads.c +a04ed86703e7ba05f3aaca57e5d7a2ee gdb/testsuite/gdb.threads/switch-threads.exp +523e1ad1a3f525cff9dab02b701e03f6 gdb/testsuite/gdb.threads/thread-specific.c +c682c53ad502826e407f202a37108138 gdb/testsuite/gdb.threads/thread-specific.exp +0bc37c048361582d53f69d0700501c98 gdb/testsuite/gdb.threads/tls-main.c +ca92dcd6537aed1d73f8b67fdf1f766a gdb/testsuite/gdb.threads/tls-shared.c +d0550fb0da424270aaf5a35874d6a0f1 gdb/testsuite/gdb.threads/tls-shared.exp +c6fe7b489cd5c7c6944dbe27afdb0e3f gdb/testsuite/gdb.threads/tls.c +4ee6d4e534226e30e79d49cc5b98a249 gdb/testsuite/gdb.threads/tls.exp +980f2448cee4484a705fe6a0d292d777 gdb/testsuite/gdb.trace/Makefile.in +51f9a67e86dd3beecb45253c1322782a gdb/testsuite/gdb.trace/actions.c +d6b1c686a9f1affc3995fb37cadbb21c gdb/testsuite/gdb.trace/actions.exp +be14eba4fcaf5b2adc86074a2fba07e9 gdb/testsuite/gdb.trace/backtrace.exp +d2edd9bfb6b15369a5e3296908d0bf6d gdb/testsuite/gdb.trace/circ.c +6ba6686c599d810255f3045d7e889e91 gdb/testsuite/gdb.trace/circ.exp +d22f8c48119d0a899e1e9d6e80f9c016 gdb/testsuite/gdb.trace/collection.c +90b9a6132a75b43999bbb3a72670f01f gdb/testsuite/gdb.trace/collection.exp +e289b698f3ff0299d714d1f9dc5a97b1 gdb/testsuite/gdb.trace/deltrace.exp +b5d2f0e0b4205415517bca254223e8c0 gdb/testsuite/gdb.trace/gdb_c_test.c +219ee52b956a9bfc0796d0236f578f50 gdb/testsuite/gdb.trace/infotrace.exp +08512b1543a9be7aff8ac4bb4b0eaf6e gdb/testsuite/gdb.trace/limits.c +2c15d2c24592ef674906e4dae03c7211 gdb/testsuite/gdb.trace/limits.exp +9a86b5f4bc513a6e347dac4050523658 gdb/testsuite/gdb.trace/packetlen.exp +086b67368f3861038df756c0646788ae gdb/testsuite/gdb.trace/passc-dyn.exp +bc02e63137ee16c4706228cc8041f0e5 gdb/testsuite/gdb.trace/passcount.exp +4b39b9f9a1d575dcc4d2a84a004746bd gdb/testsuite/gdb.trace/report.exp +b24a4b63fe84f3a2a49357b6a9db0012 gdb/testsuite/gdb.trace/save-trace.exp +d8869924fc4b2f20fe8b862603bb9324 gdb/testsuite/gdb.trace/tfind.exp +3f5a164c595f07a01b59515a9669bd97 gdb/testsuite/gdb.trace/tracecmd.exp +bd89b16a83a5835733d7054ec428bccd gdb/testsuite/gdb.trace/while-dyn.exp +5b5cada24d1f1b388c3c70955c7c4d53 gdb/testsuite/gdb.trace/while-stepping.exp +228dd88b0d4a83af3f8e89bb5224dc06 gdb/testsuite/lib/compiler.c +7af2d03dab4c1afb5a5d5c9524b0c81d gdb/testsuite/lib/compiler.cc +48a27665f33817b43a3452988f80966a gdb/testsuite/lib/emc-support.exp +2867e813c29fe0094df46509b194f656 gdb/testsuite/lib/gdb.exp +c404eb2e7dac9c1d08051c678300e501 gdb/testsuite/lib/insight-support.exp +9b7a395721eee00a67d7ed09371fdb34 gdb/testsuite/lib/java.exp +de0bd70b647f1a2d1ce4d1671e2b10ed gdb/testsuite/lib/mi-support.exp +c68e4af9b47de335364e755bc9ad7337 gdb/testsuite/lib/trace-support.exp +0415f3bd7a379430b752618c1e8c7cd4 gdb/tui/ChangeLog-1998-2003 +33164e75763e98ce19ec50c53a214b2a gdb/tui/tui-command.c +c895c5ecb33340f6b4327df90613829c gdb/tui/tui-command.h +b1b03124191dc7ec448a8fa1d362fd7f gdb/tui/tui-data.c +c6de1cc41c5181233532ecad458678e5 gdb/tui/tui-data.h +2853d84f15cf9726363093f05f9caa8a gdb/tui/tui-disasm.c +cfe5137e8a2d365a1d50c372c914478b gdb/tui/tui-disasm.h +31025216449a525a1cc205bdb2bbb2dd gdb/tui/tui-file.c +22ae3985088c25f460e7e0b3a9fdedc4 gdb/tui/tui-file.h +654a7a63d0f1a106a498742ceae9b416 gdb/tui/tui-hooks.c +c8555bcaf6af93bfb94f8c6c14692363 gdb/tui/tui-hooks.h +5871593d222a13b84ce35b2ac2c74c6d gdb/tui/tui-interp.c +6e8fdafeccc72d861a7cbdb5876b99e3 gdb/tui/tui-io.c +3e6ef3e1d320d67eb4a5fbcb41226ce7 gdb/tui/tui-io.h +8a9ee4b0eee3bb5f3ec06464c1546e2a gdb/tui/tui-layout.c +21bdbaab291d83f70a58c5c3054b0537 gdb/tui/tui-layout.h +182a975ab02a3f6d615c6b59806ba9e0 gdb/tui/tui-main.c +f220a48f82394af2c19d90ae46df6c95 gdb/tui/tui-out.c +a87f4748cf7971f7029fb85eb32a9c1c gdb/tui/tui-regs.c +8566417a39c291e1ee287701a3f6a28b gdb/tui/tui-regs.h +2a124218fe08bbb8f7ea024b06d4f036 gdb/tui/tui-source.c +c74464f9d78164df8b31f84480f3d412 gdb/tui/tui-source.h +f2da2056bff10dd8d7b21030b06d6d01 gdb/tui/tui-stack.c +75b39320dd19763fc136733339605bc9 gdb/tui/tui-stack.h +0e9d34efa3814982356122203022c090 gdb/tui/tui-win.c +6bcd65d9971eac6523419e13af86707c gdb/tui/tui-win.h +55b1b6921d777475fd178d858eded301 gdb/tui/tui-windata.c +91cf7f5cf2e3f0974c7a1676944f9a9d gdb/tui/tui-windata.h +b35567d277f1a6334bfb7a70332f3294 gdb/tui/tui-wingeneral.c +11cf633a46f11e5200c90b080de0ddb7 gdb/tui/tui-wingeneral.h +cdc2383e271638a41c2b177622e09fdb gdb/tui/tui-winsource.c +b336fdabe8d77ee65d35cee75beaaf3d gdb/tui/tui-winsource.h +0953404ddeab24f2a3ba8e24c8ac434b gdb/tui/tui.c +9f7875316406233dad7401c23363f3de gdb/tui/tui.h +6fb3c8019cfba5916d9451ab06a8ce3b gdb/vx-share/README +b103381c5207f96ea87a5a8eb4a86b6a gdb/vx-share/dbgRpcLib.h +136aa1c8da429aabbfc60353f4407850 gdb/vx-share/ptrace.h +22567ed471f25a4eccfc1987fb09650f gdb/vx-share/regPacket.h +a1429e76f00e6b2a44c6c65257783f1d gdb/vx-share/vxTypes.h +5a7cd744d3a88136d6ca0a21a7954fbd gdb/vx-share/vxWorks.h +b9e04209ee5ce063aa0dc52778977eb7 gdb/vx-share/wait.h +5e8c8957908c763889c0133d55a9bedd gdb/vx-share/xdr_ld.c +ef74612dedfb30f22c2d42c602197bec gdb/vx-share/xdr_ld.h +117e45abd2330f80c34a5fed2e5e11e4 gdb/vx-share/xdr_ptrace.c +a93ad05f8f19913070dfc6a46c065603 gdb/vx-share/xdr_ptrace.h +3b7388f0ba4c77c764a1d4148850efb5 gdb/vx-share/xdr_rdb.c +68de29665f0b21324a6d6c073e445cfb gdb/vx-share/xdr_rdb.h +a764dcca06e1e38dff79defb0f47b8a7 gdb/objc-exp.c +d0882635bcbba0d196dcb721ac2e3f46 gdb/c-exp.c +2d447ab9a8413958fc768810872c60be gdb/ada-exp.c +cf0faf4a37b21cb2ea0c7c6fb3d624a1 gdb/jv-exp.c +d1ef9e69ab23e83ed06df42b43c1e115 gdb/f-exp.c +19904fe1e3faf83dc2e81a83a4062123 gdb/m2-exp.c +6e6ef60dc77aaf89003328ef3759311b gdb/p-exp.c +451fdc157675a8b7f45de000dc2a6d9c gettext.m4 +94d55d512a9ba36caa9b7df079bae19f include/COPYING +fc1d396ce6abdce8b11f714f0ed603c0 include/ChangeLog +cf08dfc74c6c5dae7b71eb29911c9004 include/ChangeLog-9103 +d618facc3e8ce8bf3d02ba452e1be6ab include/MAINTAINERS +de46742edca3a9276eefa5ae8fdee5eb include/alloca-conf.h +da3682afe5be61c3172bb494398e3b0b include/ansidecl.h +ff45b5560b5b688bc4b6a28ed090df6d include/bfdlink.h +e4247635fdf4b4f00f70e8d0fb756cf7 include/bin-bugs.h +ad23b2f356f60d58833e2256d1601732 include/bout.h +4f78f9a43bf4555a52c77ed7e95cdefb include/demangle.h +adb83f5cdc6f751d68b7c9840239392f include/dis-asm.h +78226edd4be1ddcf9c8e57dae850d449 include/dyn-string.h +4f0d30283cfd45ddbecfd97a84ad1fc4 include/fibheap.h +9bd376fdc680c4801bb7e676aa80b2eb include/filenames.h +41e02028fea8e2eadd52a90caf0376e3 include/floatformat.h +d54eb7868908574db9965575a16c1819 include/fnmatch.h +b2cd17a9267bc2e92df461d3170cb15c include/fopen-bin.h +87444b5c85b3c2bc734f8b86157b15db include/fopen-same.h +2f3ef0265ac665d61a8721a78c47a79f include/fopen-vms.h +7b08d623511997558fcc99b0df47efc5 include/gdbm.h +317b3fc837139b901dfba9292e3576ca include/getopt.h +89612909a51e056f5b5500c7f83965a4 include/hashtab.h +06a970d566cdd88ab8bf3ae1fec0cc3b include/hp-symtab.h +4140d269a4d719013db3beba8f684572 include/ieee.h +1281513e4c64c4cbaaab169b86dc7a1e include/libiberty.h +e1b9929975775d9831fb9d726e48230e include/md5.h +07de9606e88a074c745d5bbcd835c1e2 include/oasys.h +c14e4868200f00ec814858d3f2e6f824 include/objalloc.h +8f2b67fd9a1670669af5e5e07959d797 include/obstack.h +82709f401badc29ca812065155ff60b9 include/os9k.h +b2ec49c538bbc288540fe1fc2bb7517b include/partition.h +d011632065e457c8589b28d0c53e5b04 include/progress.h +2ccf4ca81f396940231fdd26144b9fc2 include/safe-ctype.h +1309f7f8ff9241b427948c8c5761b316 include/sort.h +1f39db48d112270c02ce3e01fbfad9cd include/splay-tree.h +4ebaa58a8bcb2ad62a520447123446ed include/symcat.h +c38b82bb82381011919906bfc101a973 include/ternary.h +9e4da3ee24c6f11a47fa7d5cae9a03d0 include/xregex.h +17eeca2dc8ed2db2505c4aa25bb83cd2 include/xregex2.h +8b2a2337ea32f559beb243b328db15bc include/xtensa-config.h +dd1c74e990a977be8981e116567cc824 include/xtensa-isa-internal.h +b7bdd848ff92c3a8c9f57ab5d923bf30 include/xtensa-isa.h +7b17708b703cedb9015e8e101137d01b include/aout/ChangeLog +cc18d2a17ec338312f00622e1fa4692e include/aout/adobe.h +9efa5517827efca80a9df8a4d20290a0 include/aout/aout64.h +c6b08000298f64bb35885212da785e44 include/aout/ar.h +4e9021e94bceaee219b2319759ebe6ba include/aout/dynix3.h +64818c4cc3aab586e47bc9daa57ed4e2 include/aout/encap.h +d56e5b7b7841033c99960c96365579c4 include/aout/host.h +5d9fed058c072b61553cf62174a8e37e include/aout/hp.h +14c5f23e05dc2b318cd39ac37f3802b7 include/aout/hp300hpux.h +d82993bf02befd5682dcd44b076ad991 include/aout/hppa.h +e91c2c24d9be7b5cbfa6047d799cb850 include/aout/ranlib.h +d06f0176a5098d444f22d53fabc7c2e8 include/aout/reloc.h +94b2d0db8050c1856a7a9448fd0a56bf include/aout/stab.def +4fc8401a176b5d472bc2a60e1a0917ab include/aout/stab_gnu.h +f76759c6246b1e8376e84e0c1d8ef6bc include/aout/sun4.h +dc0a382a0c88ec81e2fcc3056387d25f include/coff/ChangeLog +aeb19b6b14f3013e3bf886497586467d include/coff/ChangeLog-9103 +d6fed07c9bd210c51bbc4099ab6417a7 include/coff/a29k.h +2527181fe68f2013f34bf5cd5917010f include/coff/alpha.h +bd146d9c208a7b158112321b5cbcb37b include/coff/apollo.h +90db700a7b6d1376d77c4477e65f604b include/coff/arm.h +7b2f28b2e4bf9e88bb4a23a3e96e99f6 include/coff/aux-coff.h +661a9f48cd8853a200d2b67027f9017f include/coff/ecoff.h +40bf593c55da6810ccbe70fe53577da8 include/coff/external.h +279bf7cff0288c326b23cafe1acd246f include/coff/go32exe.h +6deb9e4ece7f61956307de311543cb5b include/coff/h8300.h +659ebc0e56c5a7723608b56d826e9f49 include/coff/h8500.h +729f65ea2c44514f59784a9d7ebeb7d3 include/coff/i386.h +6bd9a0f12754e08b8719c7f6330fa3b9 include/coff/i860.h +b20325efd24ad29bb13270c0601b6b8b include/coff/i960.h +c26d4bce0e1a267a01f69162422a0df4 include/coff/ia64.h +f2d49e0cbd8faddd8e00a60f207016c1 include/coff/internal.h +a8f58d50b044d0ca3e3cd06677e9bbfb include/coff/m68k.h +52feae66378c59252549b75ffca1bd84 include/coff/m88k.h +a497f439d8cd07f952caa06c218a4015 include/coff/mcore.h +b9c3382114eeb141d78c0c66e50b3f8f include/coff/mips.h +976edb82f140c4195fc2a811d7ffa7e7 include/coff/mipspe.h +15637f35eba702f98283910b46aab6a7 include/coff/or32.h +ebd1a6cd8ed192b0b3339204ef13e4d0 include/coff/pe.h +7b9f9f5e2557d5f6893af18c00282be4 include/coff/powerpc.h +64baf4a1cc4991a74414804987eca7fc include/coff/rs6000.h +48c3bd2c08c09ea66fe0634dc45f7e51 include/coff/rs6k64.h +51af50b83a45484d395f7fefc0f38e9b include/coff/sh.h +89fa4862f3ed5af9e9cc4aeefdcd2bb2 include/coff/sparc.h +49952fda1e759e5aa659f8f78d7e0ba0 include/coff/sym.h +ac2f6431d01bacf541ecc3e5e8dc5499 include/coff/symconst.h +f2c42cc8e4fb7ffa80e9647bfd555429 include/coff/ti.h +b1c8e1630078781f716118e0428af9f3 include/coff/tic30.h +aac23a54bfc7f1bf13b5aef5d032370f include/coff/tic4x.h +92858e2331c34bba807c9df1080131f2 include/coff/tic54x.h +e2e2417f52b6795a4ba92f192eab08f6 include/coff/tic80.h +8b0324921a2b8a75557c3af66d55305e include/coff/w65.h +12d77371aa5d25ee7004870805fcb42a include/coff/we32k.h +f9ff028d1f9a20ce7a7247f21dde1763 include/coff/xcoff.h +544939a6c1433a4ab78ec38d8c495b95 include/coff/z8k.h +d5177ac59efda29d334e6721a8e2ca4f include/elf/ChangeLog +72bf3f83cf27514f0af979203dea6a0c include/elf/ChangeLog-9103 +ca6ae2abf939f3388c6feb2e2ae8ecd6 include/elf/alpha.h +3bf4ae3474c9c4b8310da4a84aec1dca include/elf/arc.h +fe9b3c5bfe9640c29127aecf95b47aba include/elf/arm.h +58a80a77bf1669d85ca0d6095e6e85b4 include/elf/avr.h +49400f7cefc05b3501c511d6bf078bb5 include/elf/common.h +42ae390b9bf0b8fed1b40894d288c83a include/elf/cris.h +f65a19cb8f5a2d53a4c0f71c90bef0e7 include/elf/d10v.h +e1bbf4eba14b2efe2dd202e9a7038bd1 include/elf/d30v.h +25823df33f36b14970f1e5365e096875 include/elf/dlx.h +d350084ff96d123c4ee539745ed1ef2c include/elf/dwarf.h +260b3f28bbda73b5024f96380af27c3a include/elf/dwarf2.h +08f953e3e1b593c0578e99d791fb00a5 include/elf/external.h +2adb44173bb9ba06c13aef464c4701a3 include/elf/fr30.h +9606b89c1b90c6f32f90bc613602fcd6 include/elf/frv.h +d62b2d0835fb0fa61f2c6b1279c8f354 include/elf/h8.h +0899399867f5ede8459434cb58862e61 include/elf/hppa.h +13e1b1a6be5461690bf6c8f65f27ea22 include/elf/i370.h +311051280ab6de581d85256e3094ecbf include/elf/i386.h +6e10443e0f1746964a6cc3fa883215b5 include/elf/i860.h +4f6c7e8248b9ec284b181a55ff15a17a include/elf/i960.h +229ad1fa29c4dab924b2f695bba0e864 include/elf/ia64.h +1a027e232b7e27c8657bfc80361f92f1 include/elf/internal.h +9742f5458075b7e744b4a9e8ee85a045 include/elf/ip2k.h +cff6c8729fc7fb0e6e935d8b147b7019 include/elf/iq2000.h +28b9e559fee32e782b47f39b7e0811a1 include/elf/m32r.h +152a9c6807959dd25416a2e836006146 include/elf/m68hc11.h +2127fa4130f4d87a62ed8a1ca82a5171 include/elf/m68k.h +97ed3477e1b76ff78e6ae3c361506869 include/elf/mcore.h +abc5acfc5223ece263d32d7ba3b7cf51 include/elf/mips.h +5881ca2cc0cf6477915716a23c77547b include/elf/mmix.h +9090a0078b91916eb138a6e96ba1ffab include/elf/mn10200.h +fe7269fcd0eba251971fbd8f2cbfbb31 include/elf/mn10300.h +1e8e3b4a20f588db47020029fb01b4f7 include/elf/msp430.h +bdb6f615e4b56350793dd72e1c7a700c include/elf/openrisc.h +70eca76b4db6529396e00c375a015bc6 include/elf/or32.h +f9cffe9859496c157656bbd3a7b7459f include/elf/pj.h +d448696d53209fda6c9677a0da9f3969 include/elf/ppc.h +6e05fc6e514274913cf1a89172449e1d include/elf/ppc64.h +cdf5f2196245bc18733cb60fd2a59db3 include/elf/reloc-macros.h +b46937d0253d1e91077686d38a7ca343 include/elf/s390.h +8b4ff2285d6678ba0ef059968ba81a55 include/elf/sh.h +77d6c2fbc2ffd2750986956a68c692c8 include/elf/sparc.h +88bbfabfd790d23969e1a9fab3e90434 include/elf/v850.h +b73d0fb8d195b30eed9e4286a9f957c8 include/elf/vax.h +d7e7ca630e8e306efa53d1de635f4a0d include/elf/x86-64.h +005e2cb5d90ce0496f2fa771216baac3 include/elf/xstormy16.h +3e52ee57589ca3f84d7004a0933930f0 include/elf/xtensa.h +e4a78c6f386502bb68a0f40029f56e93 include/gdb/ChangeLog +4228e8b39bcd17b9df14efc85adf2d28 include/gdb/callback.h +4d601d2080199f02e64fc007082954d0 include/gdb/fileio.h +f82f523d8986bd2629735dc0168d23ac include/gdb/remote-sim.h +cffa1864cac9a521d4e676cbfccaec68 include/gdb/signals.h +ce7a140e30b81d1a5ec659db7c1174a8 include/gdb/sim-arm.h +d20f0550570881a6fe50970fa97c59ef include/gdb/sim-d10v.h +c921d95bb01b346a3eb54ca76d013286 include/gdb/sim-frv.h +afea2e92f0da83e7b29f93cd2d28c2ca include/gdb/sim-h8300.h +0f3d45abefe6dfda74990fc579a50889 include/gdb/sim-sh.h +f455b31f23d018ab96236c2010c67991 include/mpw/ChangeLog +ac05e56eb8acd390d0fa557abc21380d include/mpw/README +d1c1f4e66376b9ef2e8d4c79446503ba include/mpw/dir.h +c293cf9a745465e2371edda6e3f700d5 include/mpw/dirent.h +fd0c0ec6483a6ac794cfe370f323c8e7 include/mpw/fcntl.h +211595cb825444acd3656a8172a3261c include/mpw/grp.h +7a2ba7b6e2b168f335e8d53b1003ab24 include/mpw/mpw.h +32f1e7dc45c3a15418ec5e0998f1f8f3 include/mpw/pwd.h +55d48ac5e6e6ef01dcad00aeb8b33831 include/mpw/spin.h +043c8982bc0ff4fd987727abd7341aa9 include/mpw/stat.h +94cd8a35a9f625ee6a4d19ef2a481042 include/mpw/utime.h +30ab289a4d9376ba8ec961019e3c291c include/mpw/varargs.h +6bc56500657f8c3b71b20af4c69e967f include/mpw/sys/file.h +6bc56500657f8c3b71b20af4c69e967f include/mpw/sys/param.h +5dbb507e309b9fe20c45d16972bfb936 include/mpw/sys/resource.h +745d20e08d92b71d289da383e8a47168 include/mpw/sys/stat.h +99098422e0de596f6a2e552220346da7 include/mpw/sys/time.h +009a0ee881c63ae879dd80dde06daca5 include/mpw/sys/types.h +415adee302eb3a50089ad31b5f2d2350 include/nlm/ChangeLog +ee9fe4c84a50cb6d303eb3848fbd6eba include/nlm/alpha-ext.h +31b2a480636af2ac2923c5f9e52b2f58 include/nlm/common.h +3c99c8ba8f85e2cb10829f35e3223113 include/nlm/external.h +119b651e264af67466b26517fa1ab516 include/nlm/i386-ext.h +b91fb4ecfdaf34a4c7f05f104c3b52a1 include/nlm/internal.h +5446642ff3b9fee027d46b00a0cd9383 include/nlm/ppc-ext.h +12311cd52e4c3cbb45b2f8eb775cc8c4 include/nlm/sparc32-ext.h +71f18763112e99c043a35a66f65708b1 include/opcode/ChangeLog +bfbbfdedaac9b97ae578e51ab45a88db include/opcode/ChangeLog-9103 +47825a7cede13679fa6b9c1e281c015d include/opcode/a29k.h +bbc69c6b56a5cabe2ac8ac814406d723 include/opcode/alpha.h +7fe28d35743fd6eecf215e993561097a include/opcode/arc.h +f51724681cb616b8ddaa4ed0aacb67fb include/opcode/arm.h +4eb7ff859daa08912603fe2cdabfcbdd include/opcode/avr.h +36fa6c54a37fe1436f5fdcb2c4e2ce28 include/opcode/cgen.h +2011e5c005224d59c8eedb55c9d4a1d6 include/opcode/convex.h +2ab1377cac8f960c0bfe679724dea9cc include/opcode/cris.h +fa6f810163a259a07a94af3d8be00aa8 include/opcode/d10v.h +a22eb3dad69e7172716aeac99a842537 include/opcode/d30v.h +97cbeaf0b5fbd006d7ad1444357e8b5f include/opcode/dlx.h +eaf1c4ac7ea402073dd0c52d1d6b46fb include/opcode/h8300.h +8f048cd74eaff64156bf9b282e5bce45 include/opcode/hppa.h +982d6352a8e2b72e658ac3c7be99690a include/opcode/i370.h +83e754a8c45c8607ece9c9e63cb33d15 include/opcode/i386.h +ee665444799a6485e0c8142257f7a7fa include/opcode/i860.h +10654d7ed7402428c40546e33e5f147c include/opcode/i960.h +17a624409de6e3d092e10c80c8f81925 include/opcode/ia64.h +11a62929e192383c726ca7c031e044f3 include/opcode/m68hc11.h +817465d768dd9380765163937b6ce94c include/opcode/m68k.h +e8f007ed9927cfc27a2b5c42a57d3654 include/opcode/m88k.h +b8fedc4a383675a905885935a3f6f4b6 include/opcode/mips.h +5956bcaea67ac09c5f7edf0fe073796a include/opcode/mmix.h +43e315bf6f41c74ceeb8422191c76ffb include/opcode/mn10200.h +9190d2f1c6e5c5ac2a78a0540de7e00e include/opcode/mn10300.h +66ab73f02620a3f0c2e9717c9883da6e include/opcode/msp430.h +f08f60834808b211b5ea9531e53bfd49 include/opcode/np1.h +b42886284f9b9a3794fc43fc272bade9 include/opcode/ns32k.h +a3a09fa7011eda950100d7a7920557ed include/opcode/or32.h +032d2c766087c96dab75773d6f9b9bb4 include/opcode/pdp11.h +283d8af92c87a4bf79b2d1d0a5d47354 include/opcode/pj.h +10a57ede0f7fe1825b0412223edf5852 include/opcode/pn.h +1c5a34568a3da98870404a5b0ac5b9ab include/opcode/ppc.h +57b6865994b962b82214d3e543408f2a include/opcode/pyr.h +44a441c4d2850e0ac0bcd26ab4cb5d9d include/opcode/s390.h +17e20112947bc48d98e321d4a6069a2d include/opcode/sparc.h +c69e19287023c929ac20ee5311acfadc include/opcode/tahoe.h +2b0f365ad336acad633a116537cfd018 include/opcode/tic30.h +2e5f5a11bdf9c436a555d32b21133a75 include/opcode/tic4x.h +7e33091a38654fda36432484a44ac7ae include/opcode/tic54x.h +5b1b9204fac57d73fcb344f2132ee4c5 include/opcode/tic80.h +3e7e117bdef389bf929e60c6d4207575 include/opcode/v850.h +e78acf38376a53ce9ac029cdd1c4d560 include/opcode/vax.h +b32850c3f4cb16b8c66054700970e3a1 install-sh +8e1f8d191230cc972e09c01686be8d84 intl/ChangeLog +e824af0ffcae539e52cac31fa3faf1d5 intl/Makefile.in +ee2ff1244c36ed348643bd1a51001f4f intl/acconfig.h +6e16646448de7fab92862eefbdcca179 intl/aclocal.m4 +0d0f701f3de2b7d66164cd9dfc174378 intl/bindtextdom.c +caa3581b00edb0a7d3811a24a3e46c5c intl/cat-compat.c +bd51dd1c7684c9f15ee4532bfd7bf12f intl/config.in +2f9be0885ee6447a29fd0550b52c40aa intl/configure +eb4685d54a1e3da00cab275a5c3fa6c4 intl/configure.in +cc8f13a4eca50e459ace9fc8dd63febc intl/dcgettext.c +4ef4d731f96a4c2a4901fa03a97abc60 intl/dgettext.c +930994e607ac485929753d7caddcb584 intl/explodename.c +a3604c7c8eb409eb8e9e385096fa099b intl/finddomain.c +07fdb4d82208430fdcf4e9c57799b742 intl/gettext.c +c46b419b2ebd68930fcb8491fae2bd32 intl/gettext.h +2fcb82a7def25bcd2549a394af4cc67d intl/gettextP.h +b23eb0ee50448b24ec0b942ff382da10 intl/hash-string.h +93e4ab4b2eba5d2b8a36e1b2380190c5 intl/intl-compat.c +9e20aa13562136f3fe776fa4ca4485bd intl/intlh.inst.in +dca9627004c526250d47351899faf37f intl/l10nflist.c +cbb38948ae7c116ea7aa981874709e73 intl/libgettext.h +95e38eda6d7e093606d0b73882ddeab4 intl/libintl.glibc +2fe6232fce14414b9404aa5d62edb61a intl/linux-msg.sed +eea45725e2601ab7dd122a20871ecf76 intl/loadinfo.h +2cb45953ee0685f05d4eecf3e5decaec intl/loadmsgcat.c +432350d759a37ec39245d656d83e27cc intl/localealias.c +606344532ffc07b36812c0d04acb1f38 intl/po2tbl.sed.in +9f197f8e4cafdfa82382882bbe04694f intl/textdomain.c +8d9eedf2444a5fd2a47985f2531e9051 intl/xopen-msg.sed +7fbc338309ac38fefcd64b04bb903e34 libiberty/COPYING.LIB +7e107e59465175c57520ece758d226e8 libiberty/ChangeLog +9a00e551ab980f5d7378135d05b8ada4 libiberty/Makefile.in +294191545dc71f5ad13229b0a5bfd7b1 libiberty/README +5b535b62413b3770aeca6d516e0d6325 libiberty/_doprnt.c +20df91b8434474ebfb22c599f0f9d0e4 libiberty/acconfig.h +7205cd3b640330a0caee1bb3d7a7076a libiberty/aclocal.m4 +e9ff099df53462f7df5a268e290f39c2 libiberty/alloca.c +d105d43b25b5a5967d6bdbd3896f3666 libiberty/argv.c +d7dc1f8a85ce158eb03a1caa6dc4544f libiberty/asprintf.c +7f287b3ca15a90be56f7c3a16c173765 libiberty/atexit.c +4c66c13dfbbbb1d40d3df3e372faecc8 libiberty/basename.c +cbdf255d69208be101da878ed2a52d26 libiberty/bcmp.c +cdc3e09fe5ca8e250ef3ab38d77e63fa libiberty/bcopy.c +d09d6a99ec0ae4b43b4f9bd38a65fecf libiberty/bsearch.c +440895d178199c0a1ce1562d7b19cce3 libiberty/bzero.c +99712b511be511b380f9561e8f94f251 libiberty/calloc.c +564e36eb3ffdf2492724309477bdba44 libiberty/choose-temp.c +7af729f41caa18c07461d9894a4e2a28 libiberty/clock.c +db12eb172b1675b0ebbff211b9834735 libiberty/concat.c +fdaf5fdc2a84ff34103604588aea1a3b libiberty/config.h-vms +f03c6febc565b8c67d88e49a6f2c0ba0 libiberty/config.in +556411b44a957219c953a1a61e522b78 libiberty/config.table +a72097c93e1bde1483c8c1c23f0b933f libiberty/configure +cc4bbe63d9fe28b258cf0cf5c00c8a57 libiberty/configure.ac +373c5062b80c1f8c030fcefd5bdc9e6c libiberty/copying-lib.texi +e3dc621adfe4ff6730b6510641537ea4 libiberty/copysign.c +9f2aa8adef0de529dee3c73d55672ff9 libiberty/cp-demangle.c +44cbb9761eb3195ec34ee8e521a9325e libiberty/cp-demangle.h +710711092973e0580e43a93f57d9474e libiberty/cp-demint.c +6d82f8ac3f2b14d73b18aed0b9397a44 libiberty/cplus-dem.c +069562b9bb3712513c7a0b017a12f271 libiberty/dyn-string.c +846c5e5797cff2d03945fdc045c06cd5 libiberty/fdmatch.c +880a3787b2519407b6b6b6138b627c91 libiberty/ffs.c +b1ab4811c02803a3d2ed8bf611d44632 libiberty/fibheap.c +68e7c391a5deb0d1ce33c1832d0567b7 libiberty/floatformat.c +5a0e7522053fc29b178bcd5ee644aaee libiberty/fnmatch.c +30a2550d37938d1e3354632161ac1d0b libiberty/fnmatch.txh +59a3ec37b6a43d649970c642e3175ebc libiberty/functions.texi +372093196abf4e95605e71908a6b1a41 libiberty/gather-docs +81053feb399b85f027c34d3f81f803c2 libiberty/getcwd.c +90ab3f8e537a4a950cb6e33224995e3c libiberty/getopt.c +5fd11388f488b53ec69eeb3e71161636 libiberty/getopt1.c +8ff0eec816410579eaba5f8a7d344d16 libiberty/getpagesize.c +163b78dbb9c54e4309a6e6ad8b75f365 libiberty/getpwd.c +6b1a3bf9f11deb195411cb3a81367aeb libiberty/getruntime.c +1d3400b0979bb6e7ba417586215cd48e libiberty/hashtab.c +b53ab3a588f4bd737eb5dba2b0dbc024 libiberty/hex.c +5d62866e7afd8f107daa8b78e25ffe6f libiberty/index.c +6ed63c8ebf03f39587c4e94168c397e1 libiberty/insque.c +8095916864bd273f9aa6a8ad82835c3e libiberty/lbasename.c +1046e8b23172200b3f1080ba378f3bc8 libiberty/libiberty.texi +894ba8399cde70ceb8ce529ca7298f3a libiberty/lrealpath.c +0fd9f0b3e810378c0119bb0bbfa71418 libiberty/maint-tool +6fc79a46ae7d6d544a8532ad8a240b08 libiberty/make-relative-prefix.c +9d92e1eb73e143f9929e5dd2f206c380 libiberty/make-temp-file.c +e331b31ce1cbf27a44f2fbeb54fa7b17 libiberty/makefile.vms +f4dfb207df40e10bd11308e0ce3ce6a2 libiberty/md5.c +779184f152031d9e89e7a2a9a391d0c2 libiberty/memchr.c +cdbdeda3aa5ead4a36801fadc3f146a8 libiberty/memcmp.c +24195385014105e131223c01a804f443 libiberty/memcpy.c +397993b1bae5f3599d20edfa9a83526d libiberty/memmove.c +b175cc1b085dffa46a41dbe21686ef15 libiberty/mempcpy.c +80908dce1ac75994099637449014ef87 libiberty/memset.c +69914c75c045b40f4c6b0fd0055f3773 libiberty/mkstemps.c +969668698375a7ecf08bc086b9613a31 libiberty/mpw-config.in +54c65d1bafd7d8d29b9d29761d977020 libiberty/mpw-make.sed +9de6f56befd6350286f5a42836a8433a libiberty/mpw.c +7897e43bedd2def4beb6eb73003efa68 libiberty/msdos.c +9fbb504341d8982f9439a168b9ef825e libiberty/objalloc.c +0b098dc2e9bb206f6c642981a8306c60 libiberty/obstack.c +051d336f4d87cf832d5adf343a10cbe0 libiberty/obstacks.texi +087f5237d8b7fff69418811efec227e6 libiberty/partition.c +71ca94bfbf061da54968ac1e57b3b92e libiberty/pex-common.h +316a7c2d1f782c47f715dde7eaa48faf libiberty/pex-djgpp.c +5949dc1e0a5865570a8c462f794bc88c libiberty/pex-mpw.c +9016bdcbb5f2f04001165c88178c0c05 libiberty/pex-msdos.c +dfc59121719c673229b4d57fa6102e7d libiberty/pex-os2.c +61f42ec64c70d61c15baf9cbd418f1b6 libiberty/pex-unix.c +ad9b2b17ade58908793f6296ccc60312 libiberty/pex-win32.c +f45d0f6037219afd14080d7ddd7199f0 libiberty/pexecute.txh +063fdcd29dc11c6e1b9fa27573075f06 libiberty/physmem.c +5925c1d64a6e31ffabbe2fd74d65960b libiberty/putenv.c +504517a55f72370938a142085a4fd57b libiberty/random.c +ea7c6e3ebb80b75fc26117250db67d9d libiberty/regex.c +ae878fdfb59df3c8bfba85bb4487543a libiberty/rename.c +4c0be9f784bf4c61bc89098eebc6e575 libiberty/rindex.c +ad466048c0305c4348d1580f76acc53e libiberty/safe-ctype.c +cf9cc42905f451f49e3a24a45bcb77bc libiberty/setenv.c +56e3dde90b64b261c6ddd7e2da7faeb2 libiberty/sigsetmask.c +d043445f610b855cf628b72e75e0df3e libiberty/snprintf.c +bcd38bbff8e80df6e908d7ee57d7b681 libiberty/sort.c +bef51eff7a41882d4763c4157d06feba libiberty/spaces.c +d0d349e0b153f5dca03db937262a4e2a libiberty/splay-tree.c +e1e2c4f1af5569c3e5c98104737bcf76 libiberty/stpcpy.c +2ebe7af7eb364da1cabfe63fc01100da libiberty/stpncpy.c +3c49bc872649b875bc538b2eba35673a libiberty/strcasecmp.c +215e80e7d6c184653c73bd04ba1353e9 libiberty/strchr.c +6929380bdc5bb0e6c00b6cc71854a3a3 libiberty/strdup.c +fc91137ce892b48522a5efc28a6c97fa libiberty/strerror.c +e4c888912855032c9b8f69d6075f10ee libiberty/strncasecmp.c +7b2896b51c389a6a7d557ea01e8c872a libiberty/strncmp.c +1ee23798a9223ef8947a376a0b3cfea2 libiberty/strrchr.c +f8ad09942d5d4edeadf759c5ace93c6b libiberty/strsignal.c +65f6273a1fb49204f10d98f21904cb90 libiberty/strstr.c +25fbadcc933dbfa07cb1a249ab97e01e libiberty/strtod.c +aee79a74ba6f2ec43325737b7e4e86c2 libiberty/strtol.c +e06d6526f14dcd0834827520331fef16 libiberty/strtoul.c +63c9e635f440ae8e224846d98bb51f4b libiberty/ternary.c +70661957f2bc5c40ea102d97ab0bf5c0 libiberty/tmpnam.c +cda3152399a6665d0e595018d9946ec7 libiberty/vasprintf.c +0ad8bcaf347187c9147577999d73e9cf libiberty/vfork.c +49f0de47280a87bb9f87fe2bf517a2e6 libiberty/vfprintf.c +9a46f8a6bd6b911849f209d09e94b66f libiberty/vmsbuild.com +300e0b92c4a5f271ba217f5077600323 libiberty/vprintf.c +3913f665d742eec8aee40fab6823489d libiberty/vsnprintf.c +947e47f2994c3ece81ff8c57777ef568 libiberty/vsprintf.c +ec0e1274190167f1f05b8b2eed4f4fed libiberty/waitpid.c +2f8818cd4649e4dd9891653f15b8e2fc libiberty/xatexit.c +e416488ce7ad148c9030ed0f54645f30 libiberty/xexit.c +1bdfb937e0df4543c60ea33babbfb453 libiberty/xmalloc.c +f3030e6275b76dd6ea06d80a92ccdc27 libiberty/xmemdup.c +f20e7cc03de67e377c14074ad8117a2d libiberty/xstrdup.c +3dcfd54ed5da2593e413b5505ecd8bf8 libiberty/xstrerror.c +4004fdcde347fda58406b4b84a995c66 libiberty/config/mh-aix +7b65854f594c84e80295173de277b3dc libiberty/config/mh-cxux7 +044204f5b4bcac5eae2face0602129ae libiberty/config/mh-fbsd21 +904bdcd9daf97fa55a9ca8901ffe7435 libiberty/config/mh-openedition +38e76da568ab25260754fdb9d5080513 libiberty/config/mh-windows +27e356fc46c6c1fc7c2a73d2f838de37 libiberty/testsuite/Makefile.in +3d738084dfb24c86b78aa106df02898f libiberty/testsuite/demangle-expected +628910b2c11e4e04d4b8db2c3d77c4c9 libiberty/testsuite/test-demangle.c +ebca3703d9896a180df31bf1b4a24e15 libtool.m4 +16f16299b0d7489afcddbfa8399dfe8a ltcf-c.sh +368ea790e1dfa3d6a2769dbd153fdf19 ltcf-cxx.sh +33d3f8c62fb77577ea816b81c1f8ff00 ltcf-gcj.sh +7e42911d61d47efa2e51f31f237a1b53 ltconfig +37d106abdbbefd48fb089292ac5a5d03 ltmain.sh +0bc137ffee1670b4ec8592f36aa47419 missing +cfbd1f0cc32bb4f6feb804354401e61a mkinstalldirs +55ca817ccb7d5b5b66355690e9abc605 mmalloc/COPYING.LIB +65711a958e0c2034565e85f6f3555861 mmalloc/ChangeLog +1280e10e6a92210081d5ba5cb1e9188b mmalloc/MAINTAINERS +db585eaf26a09e5d92d448a7a1264430 mmalloc/Makefile.in +ec10f79abad1af6310b3dd6174fcacbd mmalloc/TODO +61bf8b84a0ccfeecab43057956f3b13a mmalloc/acinclude.m4 +b233d0f45dacdcf0f5bb150ec45021ea mmalloc/aclocal.m4 +5627bccb1b3584c9c0f5bd29602c2972 mmalloc/attach.c +cad7b1300a3bdcbdc89905966db66878 mmalloc/configure +d401573232b1c7c8f4cc6fb8b434d6da mmalloc/configure.in +d5d546f07de784df3e7c13dd690daec0 mmalloc/detach.c +33f9ea6434117166b57ea7a091242927 mmalloc/keys.c +a06c5f0944c1b49dbecb94ad5f3a6ec8 mmalloc/mcalloc.c +858c164d35deb35b59b7451b656d68b6 mmalloc/mfree.c +8e885ad68e280d567ca59965fe4c3471 mmalloc/mm.c +34ea386cac892f98efd3337445230062 mmalloc/mmalloc.c +071137bbe5812e85ba0a29c605a90e6b mmalloc/mmalloc.h +727b3a53d5fd775f19c429f155da89d8 mmalloc/mmalloc.texi +29639d12cd53c41d1933fff2332b4bb0 mmalloc/mmap-sup.c +52455f0b30fb09643cdcabe08292eb2f mmalloc/mmcheck.c +6ee73cf273416572a9bc2d08d6d79cc9 mmalloc/mmemalign.c +2e0a59b124063082fd795402f1092952 mmalloc/mmprivate.h +3e3f87e1c10130e3d6c0a0289344fc52 mmalloc/mmstats.c +fb806f144f521e1655d829dfccaf7545 mmalloc/mmtrace.awk +04615ddd4b7f7cea0406cd15a4cf8dee mmalloc/mmtrace.c +70ef479544294b49af2a3037bd4f8197 mmalloc/mrealloc.c +261abcbf17ada890e2aee166d9966026 mmalloc/mvalloc.c +f3b9c1696b8503cee637ce6c1ef09018 mmalloc/sbrk-sup.c +2cf257cf8a8f879bed4e69834c871102 mmalloc/mmalloc.info +c71ddf72c059891ca0bd1727f5aa0de1 move-if-change +642459f0a2056219260229c61f154312 opcodes/ChangeLog +1b4b8646bdc7ad5a2f9071d8ac8b024e opcodes/ChangeLog-0001 +83ac14eead5eda1862cc926b82d35cea opcodes/ChangeLog-0203 +568db2b4641150f46a18da55529d8d3b opcodes/ChangeLog-9297 +fc3adcd099179b77d2adb79ada21a89c opcodes/ChangeLog-9899 +d618facc3e8ce8bf3d02ba452e1be6ab opcodes/MAINTAINERS +1bc951e4a53ae1bb7d15b2b251863a11 opcodes/Makefile.am +f8d110e3944f1add5ad62bdcb1dad83f opcodes/Makefile.in +9941095a567267c8af6e2847165ef2fa opcodes/a29k-dis.c +bd5eb3fd0135ccc8fe3f80b61c245322 opcodes/acinclude.m4 +1b00be010221b92771d802cded1643c5 opcodes/aclocal.m4 +d89dfd8cdfd22d6d4e7256cbf738f5e2 opcodes/alpha-dis.c +7c38f89c5e4beaa9274aa39b4c876f67 opcodes/alpha-opc.c +d1237155442eaf073a344b41258ce2b3 opcodes/arc-dis.c +b35daf399df5036ff496742fbc5e08ec opcodes/arc-dis.h +4648d1a5992f62bb1e5991aee8b3c32b opcodes/arc-ext.c +2c085be449e338c2bda530572029c8c9 opcodes/arc-ext.h +2a82fee6975059ddf3eab6e117fb0a49 opcodes/arc-opc.c +5c965aaef476c11de3933e1cc371d382 opcodes/arm-dis.c +5ce02872c6dc3aef7e6b1df4da1a4c44 opcodes/arm-opc.h +a1902cd93726ae865dbb9a7fbcfb83e4 opcodes/avr-dis.c +0ecb944ba144739d1ef2e6b622867b20 opcodes/cgen-asm.c +bc264680d95b812ed5d900a02bc177c1 opcodes/cgen-asm.in +aec02d8fb1ec38e4fca637d214d80c53 opcodes/cgen-dis.c +92603f3a13c3c7719b48c98007149062 opcodes/cgen-dis.in +e29a44fcbb2a2a809cbad8b7d55e643f opcodes/cgen-ibld.in +dd18fcce3992534010714082fb78eaaa opcodes/cgen-opc.c +9c04535abc91223c5325489d9a6c8a62 opcodes/cgen.sh +b024616c6675ea3b85d3ffd3fa19fe1d opcodes/config.in +e7d5b0faa32710121efaff6c45c0b9c0 opcodes/configure +b66bc3aa5d6e8612dc17902a544669d8 opcodes/configure.in +182ea56c55f06e99ee1e627781c7a6a4 opcodes/cris-dis.c +1252380a0061667febf108ef3b0a5d62 opcodes/cris-opc.c +183b99f0d60896fcfdf0ed17d7b1ef93 opcodes/d10v-dis.c +ed98e7b763c115a0d4852607571690b3 opcodes/d10v-opc.c +1fe9373513a310691a268364ed4c8b9d opcodes/d30v-dis.c +0eebf1cce2cfd05039625773a97b8d40 opcodes/d30v-opc.c +4fe57e096bcd0ee0b3843ab8a278be8c opcodes/dep-in.sed +f532bd1f8cae6bd4f17f7f07e6163040 opcodes/dis-buf.c +864f87f3e57622c62d4afb7104cfdcdd opcodes/dis-init.c +d2cbdb1139a1d41efec1239f9f9a54da opcodes/disassemble.c +2f3edb0917f116a080d891784c8bc31a opcodes/dlx-dis.c +f7b2c4299d7afc4687e131fcdb8ba584 opcodes/fr30-asm.c +5d96d8e5329805172cff9d831f65fba7 opcodes/fr30-desc.c +5c57ac35bd0b51d7d568a134b4207110 opcodes/fr30-desc.h +324d6bdc8f167dc9713424102b505247 opcodes/fr30-dis.c +cc7e25fa1a3fc163da561eb7842c8e9b opcodes/fr30-ibld.c +f46a432ee807d8133ecfbf69a88dafa4 opcodes/fr30-opc.c +215e8e76a271bc24182655abd6aff8de opcodes/fr30-opc.h +1dec4acb9d17a72b0ad89372b92606fb opcodes/frv-asm.c +4a5523de1974a11e7e45460d5c6880b2 opcodes/frv-desc.c +448626fb0d55fd5ff8a876d137798b88 opcodes/frv-desc.h +0aac9e6bde02fea5b22126eae1ff5317 opcodes/frv-dis.c +01e78340c1df55a483c7df4f3e0fa338 opcodes/frv-ibld.c +15cd0b128188d5e69f9d9c2f77e67742 opcodes/frv-opc.c +6236547af5b713dae8f0db6912c91691 opcodes/frv-opc.h +9f4edd15383aa1dfd6fd323a1eb78482 opcodes/h8300-dis.c +7de0cc79a8bb601373b521c9abb2c50b opcodes/h8500-dis.c +bf8d2780768d86dd48de48b131352dd9 opcodes/h8500-opc.h +9ed33292bd0f74695dccc2321511c57c opcodes/hppa-dis.c +dd134274fec4021f3fa0ea08f29b70f6 opcodes/i370-dis.c +742a917fde7b34a218ae59add2b14d4c opcodes/i370-opc.c +86a3511bd14324e73e54b2f32ce05873 opcodes/i386-dis.c +8d648de2b1e74276a29c87bed8c5e8a8 opcodes/i860-dis.c +756b20d401d0d3d30cb625f266d10700 opcodes/i960-dis.c +3f26f563c87403a962daa96d396b8aa5 opcodes/ia64-asmtab.c +4c555d2fbf3bb0d7002a8108f7e28656 opcodes/ia64-asmtab.h +bdf30cc415a5bcf5f6dd9ce71ed222b7 opcodes/ia64-dis.c +f8ab0e1c230757e9a42a6396cc3c4ca0 opcodes/ia64-gen.c +e198da32462463104e95744a25f08e22 opcodes/ia64-ic.tbl +cf56cf2b9ebe7e74020f759f1ca45b61 opcodes/ia64-opc-a.c +dffcb60883c34a6fb2a8183a1c9b585e opcodes/ia64-opc-b.c +67d13d9717835aedab217833eabafb7b opcodes/ia64-opc-d.c +b620c60d5d283377e0ef629bad7db4fa opcodes/ia64-opc-f.c +66fa7563d44d579b966b11a4e5fbc25b opcodes/ia64-opc-i.c +7054a1ff1706aa04eae01f17c295f53b opcodes/ia64-opc-m.c +a34fd430a730e8bbd9ddea635bee8b1b opcodes/ia64-opc-x.c +3f84550b5738a724e41a00936e692d7e opcodes/ia64-opc.c +171abf04ed14a4ed85dc9edde796366b opcodes/ia64-opc.h +46d9612952650e995998c7ac0871a29b opcodes/ia64-raw.tbl +b3d7452b4310332b7974b34b09f65a6d opcodes/ia64-war.tbl +51d601d7177a831c629281f0d03ce940 opcodes/ia64-waw.tbl +7fc591cf18bafba8205c7068d78d06eb opcodes/ip2k-asm.c +994a34a1ba1075d6edc6b4d79308394c opcodes/ip2k-desc.c +8b779e435fcc48657d54e406752dec62 opcodes/ip2k-desc.h +403504ca6c271f902b39c818d81e59ee opcodes/ip2k-dis.c +fac15a4271047e78611e6edccc74a1c1 opcodes/ip2k-ibld.c +bfaa18b0964c956b09cd25ab791023f0 opcodes/ip2k-opc.c +b133831e263d7ce73a9fe93311dfaeff opcodes/ip2k-opc.h +769eb6c760554e2a6fc577fc6ce37d75 opcodes/iq2000-asm.c +eaf045cae6f3c85c4690b7f641fb4990 opcodes/iq2000-desc.c +08124940d4a99193203e71c606dd24e0 opcodes/iq2000-desc.h +5260169ee077ca395f86b7103039a183 opcodes/iq2000-dis.c +02fdeb7001d9fa4c2e6faaa4cd6f6c80 opcodes/iq2000-ibld.c +033ac537c90ea096dac4ce6b5f61d93f opcodes/iq2000-opc.c +26ffcca8c6f17dd24768e5f3f217bfdd opcodes/iq2000-opc.h +a9d541dd9eccd3a1ea0415880b9521a7 opcodes/m10200-dis.c +cdf93ebf301a6f4b4072b2dfe4b56083 opcodes/m10200-opc.c +57a4b5cd8b49b400e97d888406bc8877 opcodes/m10300-dis.c +2424a02b42bc7821ff5011e07668b9a9 opcodes/m10300-opc.c +e03c7737880a64accae5f936fc2edffa opcodes/m32r-asm.c +168685cd37eb29cf48a5cd4759b767b0 opcodes/m32r-desc.c +270161b734aa12ec59f781b9d05d7737 opcodes/m32r-desc.h +d464ffe8959f56a13ab10a13aabf9562 opcodes/m32r-dis.c +dc5dee3ebf7d459af0bb26998581f3eb opcodes/m32r-ibld.c +ad227c4897d269bbe7802f1585813e61 opcodes/m32r-opc.c +2cf271ad166f28327121b500a3fb997b opcodes/m32r-opc.h +cf8ed111b3bd970dd219753ea4459da2 opcodes/m32r-opinst.c +74ba2410f78e6818eb633087c73adc64 opcodes/m68hc11-dis.c +8d8c14d71076d2526f26e3c11c329153 opcodes/m68hc11-opc.c +6377e1327ba179a4a4861832bb432c74 opcodes/m68k-dis.c +951a9d1c4fed3d705b00f202761dcad8 opcodes/m68k-opc.c +5f0c42248faa120d97b288f04aeeb04c opcodes/m88k-dis.c +d129eed92c6947db4372b285656ef9a1 opcodes/makefile.vms +c6aca57ee0df93f584726dcaaac26216 opcodes/mcore-dis.c +fe2c622e0af6777567843295dacf4e6c opcodes/mcore-opc.h +395ce519719e84784078b4646fc38726 opcodes/mips-dis.c +008dbfd422e23be983562ba68924e413 opcodes/mips-opc.c +c5f2a79141b09a53e3430582f3559b7b opcodes/mips16-opc.c +008b0311f6fe37664ac553f5710dc7ed opcodes/mmix-dis.c +a28eee1a261085380892b92df39d665e opcodes/mmix-opc.c +5de239a139c71421a7cce634f8deca83 opcodes/mpw-config.in +031902d455df71012bd4603e5d616ca6 opcodes/mpw-make.sed +28d3c329c3f1ab2b7b93742e28100bf7 opcodes/msp430-dis.c +1903d4548455a41e5fc83e0d21eedfab opcodes/ns32k-dis.c +2ba2f33b7280cccf47c76c44bf914ff0 opcodes/openrisc-asm.c +430e137158ed28b1527e25cdab0b1e26 opcodes/openrisc-desc.c +ca0c776c11bff05cf8c220a795fcc956 opcodes/openrisc-desc.h +eee11d50001c32fac10f72d5ec94093e opcodes/openrisc-dis.c +83538c5396ea7f25a94dc92c8c9f4e5d opcodes/openrisc-ibld.c +890207b352e9409eeff8b78588e4de25 opcodes/openrisc-opc.c +b4ba2cc3f10750b1e4784d746954b286 opcodes/openrisc-opc.h +81a682289129e3eefb7cfd6ce9d10d92 opcodes/opintl.h +af4929616baa645c821d8efce131eb93 opcodes/or32-dis.c +42a39b385b3696ae3aeb5ab08b4cb2eb opcodes/or32-opc.c +69b98498d30589d214ade81f37118d85 opcodes/pdp11-dis.c +74c71364986215c40dfc680f1bed9d3a opcodes/pdp11-opc.c +93e9872a6096711dee69bc165d423a7a opcodes/pj-dis.c +371eac8c21b8b61b0d712e0d1c26f787 opcodes/pj-opc.c +8664a25bdbb306d1725bc0cd369f3980 opcodes/ppc-dis.c +1fe03bbdfcea46866df12a7bc875a0bf opcodes/ppc-opc.c +683721e42ee9e905257cd9a6f33f5469 opcodes/s390-dis.c +01aadb0bf281e9519ca1477d127ec543 opcodes/s390-mkopc.c +99f431befa4fe97758c4fd4500b165a2 opcodes/s390-opc.c +2c3ae0790b8580e0b0219cabb3d7e95d opcodes/s390-opc.txt +6b929b1d601cd881be5a6899e9a1fbb2 opcodes/sh-dis.c +afbfe6f26aac30de258db48899a954e7 opcodes/sh-opc.h +cb0eaf60fa736c8bc9f3a4f2de36fa20 opcodes/sh64-dis.c +8cf964f73fe8ad566d49e38ad5190766 opcodes/sh64-opc.c +209cbd91e7a41437384efbe8d415c902 opcodes/sh64-opc.h +941d97333681360e8be260c9e5ce9ced opcodes/sparc-dis.c +2a9dfab313c966db78dbfaf392c49d42 opcodes/sparc-opc.c +1ded054093de910d9786c62bc4fe8cc6 opcodes/stamp-h.in +8e4842844d864baf1d2056cf0651c2df opcodes/sysdep.h +e93af673571bd52b817193b4028189d6 opcodes/tic30-dis.c +b9024a3726fae2c26a9012d11a9f44ab opcodes/tic4x-dis.c +6e9b2946abe59dc713701f1af4835c7c opcodes/tic54x-dis.c +bd458a11b32b47de97d716e0ba2fffbc opcodes/tic54x-opc.c +0bbe03c2f65c1128fd6a0b0916315af3 opcodes/tic80-dis.c +2225052326dd29b94a99ca86fb0086d8 opcodes/tic80-opc.c +1ee4e61506d4fd80d5136fb5fc9e5343 opcodes/v850-dis.c +0617a777a66b4a880bfe6119cfd77151 opcodes/v850-opc.c +11940019b5b3ed9449fa686ec59ec2ab opcodes/vax-dis.c +5617ad435c3e7f05af527ebdf4a610ae opcodes/w65-dis.c +f15e85192b208a59f22ca57220b05728 opcodes/w65-opc.h +02dc9126d5ffeee4bad38f13ec4b0ba0 opcodes/xstormy16-asm.c +d94ab0795694f719427f6716947c27fe opcodes/xstormy16-desc.c +e7464897850f8b7b0f00314d9592e0cd opcodes/xstormy16-desc.h +8dbf20f8d37020891957a0bd3a9c6e0c opcodes/xstormy16-dis.c +f7458878ce311368c04d5b6640861629 opcodes/xstormy16-ibld.c +946fd94dce130ffe83b0d622a878401c opcodes/xstormy16-opc.c +ec7d55feaa68cbfa72b29a25ae4e6209 opcodes/xstormy16-opc.h +f53d3f226374a5dc5ed70b471772c019 opcodes/xtensa-dis.c +5838f65bf6e5688fd32c6214523e7a29 opcodes/z8k-dis.c +2435cbae8d6b4108d00ea2032bc98650 opcodes/z8k-opc.h +2a45485bb48273548e787a52a8fd93dd opcodes/z8kgen.c +d09d0ccd1b7441dcaee9549de0636fd9 opcodes/po/Make-in +0504c0877e7614d5d8be0960ddf552a2 opcodes/po/POTFILES.in +6d3b93858658dada9e01f04ea2aa2155 opcodes/po/da.po +d9c5d53f5447b9fbd27f92ef1ecbbe5f opcodes/po/de.po +1f1049b96cb50d1c0ff450a2edd02f1b opcodes/po/es.po +f4dcff36ed8bf89d518fb09f38f45bc9 opcodes/po/fr.po +195fea77b114bb5405df61cf8bd287db opcodes/po/id.po +dc0c066b6c080aac377af874ee9a3c79 opcodes/po/nl.po +075f999775233d7f2eda59a49b1e1694 opcodes/po/opcodes.pot +30f5fa421474edf39ae99a8985bd42e9 opcodes/po/pt_BR.po +27e9fec6ee5c546b5d5f4afb80b287ed opcodes/po/ro.po +cb5047f27d736d066f07a08e33e44884 opcodes/po/sv.po +8ddcec300546b39bc1d9a13098637b64 opcodes/po/tr.po +bb1c7be180e128c17ef71889d8e21d40 opcodes/po/da.gmo +d03d80c52c4e1c3c4542313a0d1b9f46 opcodes/po/de.gmo +3f4d75b1a4b08db04cd0ce6d14741e5f opcodes/po/es.gmo +a766be305490174f3142d164e0487185 opcodes/po/fr.gmo +b6c960d660ea6c9ef46f51a98cd15d76 opcodes/po/id.gmo +e465c12f6f87300422a7fe4fbda71c49 opcodes/po/nl.gmo +1b79e075af1926ef6736fa317f054702 opcodes/po/pt_BR.gmo +e216f1583ca03a04f8849dfb96b59c3f opcodes/po/ro.gmo +5da56ca1b90b8791c91c7c90f8dfb131 opcodes/po/sv.gmo +179cd41f0e8af51dd577fd5d7ab36c79 opcodes/po/tr.gmo +5b5c55fc05cf189ff544e3ced346c957 readline/CHANGELOG +51ffa89b495619192da06ae4b61df976 readline/CHANGES +03b36fdd84f74b8d8189a202b980b67f readline/COPYING +dacb041f1e903b516baedc76d8df6e02 readline/ChangeLog.gdb +81cc8b4d291fe16825c2a275253c2373 readline/INSTALL +1d32d53ede16b3202c9809fca59e10ae readline/MANIFEST +132c5ded866111a1459bdaf54ecf1e11 readline/Makefile.in +90b0b425dd4cf50f15a89c134fae264a readline/README +0bb4ff5a1ee6f767d0d1b7ded925a8a3 readline/USAGE +49b268e63a5d9dc083249de916f6b3b2 readline/acconfig.h +9e58cd4a908cf2b758e514f71ff09829 readline/aclocal.m4 +5ba16ea9e4b1c5691c974aef544c1061 readline/ansi_stdlib.h +474b1a3a8efaf34838d59ac2f4e5b8c0 readline/bind.c +badedfde8238d051d2f7dfe6a373aece readline/callback.c +ea2d2d0d63c5f6f452ce8cce05e60bf3 readline/chardefs.h +24752ab06bbbee3765f042d37ab9374b readline/compat.c +aa5095ae1fad1a1cbc02c95c684b9806 readline/complete.c +3b524f71b0d544026f63334151451dd9 readline/config.h.bot +33d8f3b83204473497af0729bedf4222 readline/config.h.in +cad0501e2d7070cc935545c8825694d1 readline/configure +a845614b81dedbf7ff96e1d181757584 readline/configure.in +d2681a490715d682a6b6ddac133de296 readline/display.c +26474d92637c5c963787d78a32878850 readline/emacs_keymap.c +c3395fea13acb489044c3e7ecd9249e4 readline/funmap.c +70d07c63277ae5f29f79b8d32fb96df0 readline/histexpand.c +9a5f544413075a2108d45d88c1452221 readline/histfile.c +1cdba3464d48009e931fd4bc5d934213 readline/histlib.h +d1515be9d60aecb01615310b1fd68453 readline/history.c +1264cf101004b819d31d83552f540a3a readline/history.h +54077dfcb93fa93db40e02f5e17542df readline/histsearch.c +989b28bad9b5e3ac889fd149d0092ad2 readline/input.c +85152c4bc582b67e2f07f6e75cc1b9ec readline/isearch.c +ebb0e588ada164c2d80cda2ed9431611 readline/keymaps.c +38d541623817bd4dc2758068330590a0 readline/keymaps.h +9c58c77d5880572966c96a4f229c3f9e readline/kill.c +cb94557483766a522276a98e908cfc04 readline/macro.c +35742ac3b87d5ba0a95bc564a174d90a readline/mbutil.c +d0a5e10d6441eb5f607f25622f5e6f5a readline/misc.c +3bae5c8be4385dc5b157b64fafaf8baf readline/nls.c +aba3c26aaa8e9bb9f9c6a9eda89befb7 readline/parens.c +0a313800eea82b7e5fdf3bcd9fbd2b1c readline/posixdir.h +ba2252d2626050ddb462015bd5598ab9 readline/posixjmp.h +be2d0a8b9d9c3dc679f13e886caf156e readline/posixstat.h +6ead2d0ef06796584a0d4fc1c6b3ddb2 readline/readline.c +28561aeaa84ca63d53135d468a464bb5 readline/readline.h +09e4df265548342608087435161e41de readline/rlconf.h +a36ad9d9f7069428425c841249724132 readline/rldefs.h +15abdb3a635c0bab90b769cd27126cdf readline/rlmbutil.h +3ab9bc286c284f2a5dc0100ebeeae2da readline/rlprivate.h +aa300b9013a81a43e35516f679addd24 readline/rlshell.h +d307cfed49585dc4eb56974ef3255b2d readline/rlstdc.h +0edad865012a7efbf1acad385901144f readline/rltty.c +5d2b6d2d6c4a08a7390c335f49233287 readline/rltty.h +e655c7e47d75825ed3e9c2d75cb3a0b0 readline/rltypedefs.h +e8cb411d7338299f99b64c3f5d49ac55 readline/rlwinsize.h +59fe063aa678e53f24fda098ea6e596b readline/savestring.c +969ab33bb67293ec91fbecdc8407ffb9 readline/search.c +4828f3fe0b8feac6a47dc972c65d948e readline/shell.c +0ed53da6ccd155f67ac28776061766bc readline/signals.c +bb45491aeade9cdfe66512671ca8bafd readline/tcap.h +afe4f32bd26faf3bd8fb250b587afdf0 readline/terminal.c +839b3052dcbc461e2a35259f1f342a17 readline/text.c +4d14b9affde29ad81ba9326e1c367d30 readline/tilde.c +50cbbcb1898420cad1134e7d17c245fe readline/tilde.h +d9bf03dc5238b9729686683bf4ed7612 readline/undo.c +6afe1533692736786bc443756feb40a2 readline/util.c +0f97e33b6f3c4e5373459236089299a1 readline/vi_keymap.c +776e938a01615a461319d87ff619bebf readline/vi_mode.c +75a84e2713d83894f93e2d1e3aa87375 readline/xmalloc.c +b0779f99427cda84ad6a7e60a0b7cd3a readline/xmalloc.h +75ad677f6feb3097e69d1431dafd10e6 readline/cross-build/cygwin.cache +89d9474bb3bfcc8a787cee8b1bc7f965 readline/doc/ChangeLog.gdb +aaf6ca4a30b4ee66cddd2f566514aebf readline/doc/Makefile.in +0eb8066ef9b6067b43fe4f63f8f05b6d readline/doc/hist.texinfo +e41402c08035fee38d1a0dcbce64ca3a readline/doc/history.3 +fa0bb6fd7ff7e1e01e20518c90220d13 readline/doc/hstech.texinfo +2976408e7a59fcd527e60aa87c06c74a readline/doc/hsuser.texinfo +2700e383c705103d1ccd5d4bda1b5cdc readline/doc/inc-hist.texinfo +7b96f5bc113da4b274b809075a090d64 readline/doc/manvers.texinfo +256ec164a76f49cd5829f8ededede57e readline/doc/readline.3 +eeeb7b1ee984909f404c8a6f08bce3e1 readline/doc/rlman.texinfo +211bd33b15863ea255cfe83b34e0b2b1 readline/doc/rltech.texinfo +8be674c1f4df5dfb9a1da1b362515438 readline/doc/rluser.texinfo +932f2a232c4d669be679cb0c403d95a1 readline/doc/rluserman.texinfo +f979d2229c3c82ffdfae760f7b3b55be readline/doc/texi2dvi +1533827bfb0ccf07fdfe9577b4e55a5b readline/doc/texi2html +0bd93deab351b07d124b49424690dcd5 readline/examples/ChangeLog.gdb +587fa73058e332ae6e39ef9ad7428e62 readline/examples/Inputrc +34150954ccffef415dda138b93613b01 readline/examples/Makefile.in +8666715709699f6e24c7d85af2da595d readline/examples/excallback.c +4576f906dff3be5f91f6e301eaee5711 readline/examples/fileman.c +72b51887f790e42c2de9f8f68c8ac87a readline/examples/histexamp.c +fef6c62715bbcb6b842fa69dd1d51558 readline/examples/manexamp.c +24b0a86fbc0c767a55657c0eeffe3a33 readline/examples/readlinebuf.h +633b2c3df52ff11b0807765209fd43fb readline/examples/rl.c +0bb0f61e933a0b1aec80105f48b57bca readline/examples/rlcat.c +a2937a422274f83b43ffebd45c01bd05 readline/examples/rlfe.c +ec131343bdbfe9b79c5cb632965055d8 readline/examples/rltest.c +4056d443b6f0ba68227697190bf1e94a readline/examples/rlversion.c +cf45e737e58ef10a2a668d0fd049a30d readline/shlib/Makefile.in +dd4451f9cdfc36cdb86703965f758ec2 readline/support/config.guess +6cdae8120da06ebd9981c7a5a813550b readline/support/config.sub +f01cade8404f87f796fee1a0a296092d readline/support/install.sh +058be45f92bc8f999144c2c6f5c831a8 readline/support/mkdirs +b52be3f200cba0442c23371ba15f69c6 readline/support/mkdist +4db1470ec37357c83b37eaa1cd370836 readline/support/shlib-install +25de7b51b786eadf4a0a52eccfb12d1b readline/support/shobj-conf +c58f004fea2277f6e472db636b82e46c readline/support/wcwidth.c +d10f7c46cbc1305195ac9e8ef218755e sim/ChangeLog +29600d6c477fd5bcfaf2f36df3374c65 sim/MAINTAINERS +04b3614a3f5a091aaba40cf5cadb10db sim/Makefile.in +72ce537cb34d5416875ebff0eab06b9a sim/README-HACKING +bc96a473e76350011ced3d7488525968 sim/configure +5cf358fe6eb9eabee188809e5b3bb57d sim/configure.in +0636e73ff0215e8d672dc4c32c317bb3 sim/arm/COPYING +7df874753286cf4ab1a6ac86c0303a1e sim/arm/ChangeLog +8e5a715cda46b66ac93298138ec7b383 sim/arm/Makefile.in +a62a77605003de7a8ba75d8247fd77b7 sim/arm/README +c277414b921bc85437478d47aa2ff522 sim/arm/acconfig.h +a2a3fc0e608c6f69b8e0666321afbc88 sim/arm/armcopro.c +5cf6a689e4b982aa60949515cb189093 sim/arm/armdefs.h +f5857e00f91d3042699f269020490ab6 sim/arm/armemu.c +cb6c018553e6cf12c2ab9897538bca58 sim/arm/armemu.h +cfb9aa0befafed612ea127d929477e2e sim/arm/armfpe.h +ceab0c003af7a10826bf9303fb59b598 sim/arm/arminit.c +99b8409868bab08e646650b1bc1e03a8 sim/arm/armopts.h +b3e1f5e0043e1d2c8529d9ae37522c7f sim/arm/armos.c +cfec322e7c65e954b08ea20ff5295807 sim/arm/armos.h +f01353f284481a4da384f118d7a38618 sim/arm/armrdi.c +868d0f1690e5f022ac81b3a7463bbfe9 sim/arm/armsupp.c +fa1897ab0cbb59d7918881acaff8a8d9 sim/arm/armvirt.c +3b672351d98b99dd459d990f0b212e81 sim/arm/bag.c +aadb64e2f25be8caa6edb52cd3fd745f sim/arm/bag.h +92c73b3eb189ddf717d1359b075f1508 sim/arm/communicate.c +cc63fb53e5e7a3d2f4e4b07112a64ad4 sim/arm/communicate.h +298f4e880e70c371bea1db9c6c7cb9eb sim/arm/config.in +f35c5c3e1c83ae0b9262355bc1105720 sim/arm/configure +6ac0cd3e7e8f13839765af8300390afe sim/arm/configure.in +773753e83d24e716712dd6070dab3a91 sim/arm/dbg_conf.h +9d5f53825a2051cc9676f7bd49f50b3e sim/arm/dbg_cp.h +5b0a3e0b5101b09a6df967d3b316946a sim/arm/dbg_hif.h +11c48ea5a82a047f8d6034265697d4cf sim/arm/dbg_rdi.h +fbe3b0248871a2a9dd1bd87b1d4ec563 sim/arm/gdbhost.c +f2ef4758e0de1f324298c8708f79eb5a sim/arm/gdbhost.h +ef872ede1daa8ab5bbc4ddd4018717f5 sim/arm/iwmmxt.c +e8d95d4b5c2e900f87f4e31753c8438b sim/arm/iwmmxt.h +0d7e1d1be5cb8ced0c65e07197918bcc sim/arm/kid.c +fa06c996810697a1c8b708223ce7acad sim/arm/main.c +7a7a08fb0985512b69a606f714ec2e36 sim/arm/maverick.c +84474f96b09a4d9d72f468531e82bc6b sim/arm/parent.c +954e1b0a1dc87a295e02d42020117638 sim/arm/tconfig.in +402810351d9dcedde8fd31599a9a7781 sim/arm/thumbemu.c +1a1eb8229d1e6157e2c5d84823fdaa8f sim/arm/wrapper.c +07a99fac9a503ad3daac45cf885704fd sim/common/ChangeLog +bd57eb33006544376ed00cfe7e82e952 sim/common/Make-common.in +5848803dfb8f7ef2c3e730653a12cdd0 sim/common/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/common/acconfig.h +c484c4152f6aaa63325628d18330fc3a sim/common/aclocal.m4 +335073c5fc3053848d19a323ecdf3548 sim/common/callback.c +794c6e8c2a5a008da07306a22ddf43c8 sim/common/cgen-accfp.c +796ea72133b71977d61ca66375aa2515 sim/common/cgen-cpu.h +847163bd5957b6d67cdc0e44b17b8f59 sim/common/cgen-defs.h +fbe514416cf4b3d5a32f2abfb0bc4c2a sim/common/cgen-engine.h +ed8b05c07d34977e0e69ce33032d809f sim/common/cgen-fpu.c +8149048d71beac8331d23655b2ebe540 sim/common/cgen-fpu.h +cc657a9a86b5f10cedc79e4c04b55513 sim/common/cgen-mem.h +7b6a854c982812d4147e6b093d204e53 sim/common/cgen-ops.h +aee7e5cae33b2ce2c56c813ac182ce4b sim/common/cgen-par.c +a0acc8bc417717e793069bc04a111ce2 sim/common/cgen-par.h +9495d9df0b2acad950762b18e1d758b1 sim/common/cgen-run.c +68ebe20e3bb5031f848fd8183f0104b0 sim/common/cgen-scache.c +1dba6be37e779c52533bc8d4b6353cbb sim/common/cgen-scache.h +58359f7f1aba415b98d7f6c24100ed50 sim/common/cgen-sim.h +8470cfa820c29adcc7eee78039746052 sim/common/cgen-trace.c +7449eed65ac41dcf3dbf85ae91e873e3 sim/common/cgen-trace.h +0b9d8a4f3fd07f013649edb1fdab442d sim/common/cgen-types.h +9b1c68faa1bb5ecc302acb231d5bc575 sim/common/cgen-utils.c +1adaf5a6495421e3864cd820125b6cd0 sim/common/cgen.sh +33ba305973dc63bc7b9cb19afe140f18 sim/common/config.in +151dc3c32e6d985f44296e0bfbee6d30 sim/common/configure +8a66a62b3361b3a1391cbaa9a92b91eb sim/common/configure.in +68104ebc4ba3307ce3dd728c027fde97 sim/common/dv-core.c +c6671ada318d70f09a4ebe0e57d17bac sim/common/dv-glue.c +0d6f766169d902c7d7c4383ef9031110 sim/common/dv-pal.c +959d37acb4b3ff9b0b50f2457fcd9f7e sim/common/dv-sockser.c +554bf1f8ce74270c17c62fdb9e651bf8 sim/common/dv-sockser.h +1a26e2cb381d5bcb0f3f86c52632de4c sim/common/gdbinit.in +459c9ebddd4c5d1baa3cf0db9953591f sim/common/genmloop.sh +e0691ba078ee06b3827945ab5cf5091a sim/common/gennltvals.sh +592084fcb47ee16205a2c64c01451de5 sim/common/gentmap.c +0cd5aec0350eb378abd59b9e9c5050e3 sim/common/gentvals.sh +e7aef002715d1bee10b5d145a296d791 sim/common/hw-alloc.c +7d1a810d7d7dfaadffb977a4d6b8d580 sim/common/hw-alloc.h +d6182737fb9b1f296b342a3bd49c064d sim/common/hw-base.c +69e5e0e61d74b6f8f7b4249d847603e7 sim/common/hw-base.h +db8f0491bdca2927e1561311b371aee7 sim/common/hw-device.c +4fbcbd59f2e8bea7174797f29a5ea57e sim/common/hw-device.h +00eda3381f041509e102ae3342428cce sim/common/hw-events.c +812b4d00d0ca7458f91c906dc6c017a4 sim/common/hw-events.h +3e10d4a6f3b7e4f4a92918e23bde1b0d sim/common/hw-handles.c +9f4f1a3a707f84b94ae27febef75f725 sim/common/hw-handles.h +81589509f9c0c02c217289ebfd0c25a5 sim/common/hw-instances.c +687e80879fb286ae626c85b5d06246fd sim/common/hw-instances.h +c00e933e41dcdff8cff3c78a61c13ac3 sim/common/hw-main.h +42a11c452a78d452155495761f83f921 sim/common/hw-ports.c +b4e7450ec96d4752f9bd767d2dc98cbc sim/common/hw-ports.h +566fa5a5f700a19bc9a510d522403ea3 sim/common/hw-properties.c +178c69ce7f1ba68b00e28f838d3fb71d sim/common/hw-properties.h +b88fe038fe45ef56e644a7cf46e40b29 sim/common/hw-tree.c +399bce7ec8cda497fcc50a571bcab475 sim/common/hw-tree.h +fc555cebdd7df0a92d3b6ec6480a89e6 sim/common/nltvals.def +3d6d1e939796ea34266da3f0a6269924 sim/common/nrun.c +1acd8e76db434b00c9434323a99db3f9 sim/common/run-sim.h +00b96191047c178c25a64b6f2a5a2bf6 sim/common/run.1 +5b5489baed724404431195838ffb51fe sim/common/run.c +01a66f4e9324575922ca374839dd5a19 sim/common/sim-abort.c +985391ccff021449e5b4ddc68217242c sim/common/sim-alu.h +2223ab855959bfbc78e82e2a323a9a77 sim/common/sim-arange.c +628594cf3099409239adbfa20bb04109 sim/common/sim-arange.h +55ab2bf3d55a29097ab9bfff98f934fe sim/common/sim-assert.h +68299281e7b0bbbf0108fcb6dd457399 sim/common/sim-base.h +e7d97119ac19deeaefd313ca9fcee585 sim/common/sim-basics.h +673dccaf72a38ecd3cd9488aca02226d sim/common/sim-bits.c +6dd40057beefb37a3c5c796de50c9beb sim/common/sim-bits.h +1e5bc09ea0041efc859abf8964d521ff sim/common/sim-config.c +fe3d8cb9e21da52b169d5c52d2a62640 sim/common/sim-config.h +7ed410221d79a7e473ff4eb1f8b09750 sim/common/sim-core.c +b9dbe2b2b06b062c0d3919da2c0a272f sim/common/sim-core.h +3058e317795b85385c5436896885960d sim/common/sim-cpu.c +65920de940f14966d09b2f39c250a7cd sim/common/sim-cpu.h +1ff05b42b14c77e725c88fece4d7b9bd sim/common/sim-endian.c +7d1a6502338064ccc5269593434b3ff8 sim/common/sim-endian.h +2744f0bf9f7176264538f86efcd37418 sim/common/sim-engine.c +364af8f73a9fe7593ba325f08b4141ad sim/common/sim-engine.h +e4295595a825f2156a12689482f9d206 sim/common/sim-events.c +6feb23eba7949e90350b2a8a12d8854c sim/common/sim-events.h +943bfbba77db4f72d8f1167ec48ea3ac sim/common/sim-fpu.c +b521b59b541630fd9edb080eb0c3791b sim/common/sim-fpu.h +11f06e8fae65e686b5ecbf62130ea47c sim/common/sim-hload.c +564fb49c60b8c4fb12a05527bb0c9e9f sim/common/sim-hrw.c +1ddeffaf97945a97a1d86d0e0fe7e433 sim/common/sim-hw.c +b1fb1875f15c42d14431b3ba4209c55e sim/common/sim-hw.h +6bcb53779b5e8f7adb2cb8d04c1bad16 sim/common/sim-info.c +07284c1e6b4527c48dc5054d05bc41e2 sim/common/sim-inline.c +ed66c7256d37fba38fc3ed41da6d4d3c sim/common/sim-inline.h +516bcecf5724556662bf6cfb351b9f27 sim/common/sim-io.c +39be718345b9a2b1b1c22a65967e4119 sim/common/sim-io.h +04ec3fa8766ea4560341677e5e7f2f0f sim/common/sim-load.c +dab6fa02993a62bbb936ded846b177f1 sim/common/sim-memopt.c +67077d42d023132fd215a2ab18abb678 sim/common/sim-memopt.h +bf3335ce033f73a5be8c6a0c2a1c47ac sim/common/sim-model.c +f202bc3df8c6fa5f32fef9e89474ed41 sim/common/sim-model.h +99cd899dbc76a45fccfb3e9cee122b32 sim/common/sim-module.c +63de1d375efe9baabfd4f0ef3d8354a1 sim/common/sim-module.h +7d4793bf7213fbf305559bbf57edf52a sim/common/sim-n-bits.h +2bfa51f550fd32b5187d9c4bfb9cf0c9 sim/common/sim-n-core.h +e1db971cf69612cb974822e0b17b3ec9 sim/common/sim-n-endian.h +e52cb23e5353583347c9193c49835ab3 sim/common/sim-options.c +f655fec7cb8fe16cc44000b038c73f72 sim/common/sim-options.h +a46ec8d5aaf717cfe77574f1c27cf4af sim/common/sim-profile.c +65bbec65f34d78d63ed5f69e485dd216 sim/common/sim-profile.h +5a8d9d2d9872f892f48c6240a2baa3c8 sim/common/sim-reason.c +a02f8d2db8c72a0735d8f6834a99b029 sim/common/sim-reg.c +a73f0bf825ef2e4a6b1e57dc2d1e3b74 sim/common/sim-resume.c +582d6b475fc63223ad27ae2837c7cc2e sim/common/sim-run.c +e7ff4729e89d9825ac928aecffa17aa1 sim/common/sim-signal.c +88d73c8c34abed102e684ba12ee6a7f8 sim/common/sim-signal.h +0d956d054dff3624715224315de310cb sim/common/sim-stop.c +a648e4fba65618d182c70da4517c7fdc sim/common/sim-trace.c +f9fe0d16ab70b1d8eb71359a92ac9355 sim/common/sim-trace.h +d70a803dbcc8aee2dbab56ba3c0ab64c sim/common/sim-types.h +021397e35b67a79aebc184abf48b90ef sim/common/sim-utils.c +207113462a2f4e9c4d4f2c074226b978 sim/common/sim-utils.h +de3bb67644b46189eee92ce6a18c31e1 sim/common/sim-watch.c +dc744d214c21a2ecbb2dd79dd6550d3d sim/common/sim-watch.h +6255114f1333311cfd79e063d44030c8 sim/common/syscall.c +bd5c87daaac42725e636fe648650fc7c sim/common/tconfig.in +9446591cbf9a806593440dbde7ab929a sim/d10v/ChangeLog +77f1d02b57f293d82fa85d904df8e962 sim/d10v/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/d10v/acconfig.h +298f4e880e70c371bea1db9c6c7cb9eb sim/d10v/config.in +02ff2e55c3498348dd01b435502490fa sim/d10v/configure +1b124ee210dd1f4e985fc2bfeec1ae84 sim/d10v/configure.in +986e8bfc01b0e0cfe1be748f55d862e3 sim/d10v/d10v_sim.h +7cf4cd44539377c57e6d64f3715397fd sim/d10v/endian.c +4dda487eecd2318dd4c38275683196c8 sim/d10v/gencode.c +ffca0265d94f7ad98cdbf39ae347cec2 sim/d10v/interp.c +be35730e9f08c186e180c980154411b4 sim/d10v/simops.c +09ede79d54bf92b886ad8208e0fbbdf1 sim/d30v/ChangeLog +ef2404e8d17289c06833384009f278e8 sim/d30v/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/d30v/acconfig.h +fda471ff6ffa29239193cabaa5cf4e6c sim/d30v/alu.h +0fee562cbd64803269a981154f5ed55b sim/d30v/config.in +f98ac00175488af8e5a8d313ac7df531 sim/d30v/configure +cf206bfa4486d980ab4d04d88b422d53 sim/d30v/configure.in +f95651449da0fcb00a32f5be636a03e3 sim/d30v/cpu.c +f77cd3e0cdb10162c42af53d2574a1fb sim/d30v/cpu.h +ab753960d5f953b3ede4afe416f774d0 sim/d30v/d30v-insns +57acc8f6d0a309150ec73c71041ad158 sim/d30v/dc-short +a48f0d416bb9c76e245de271cf24da23 sim/d30v/engine.c +409de25b7699f0b304f35d495945493e sim/d30v/ic-d30v +7891551f8f618e441035f8856756b227 sim/d30v/sim-calls.c +c3cd55b40757bd34e29652ada7598e5b sim/d30v/sim-main.h +97ba33b1d7fd99d8cacef0b679271497 sim/d30v/tconfig.in +b000d9b0a089582665216e66f17cca74 sim/erc32/ChangeLog +a85b5a2ccd7d7ff2bd1ad01398864fa9 sim/erc32/Makefile.in +9f2cbd625dfef51b3d1162ba9dbb8a4f sim/erc32/NEWS +72fececbe452af10d0adb31b037040dc sim/erc32/README.erc32 +ce58de7fe1b8736ff94d663cb47bcf4a sim/erc32/README.gdb +8d0b5212c0ce4ec7e01d67b407af3ba8 sim/erc32/README.sis +c277414b921bc85437478d47aa2ff522 sim/erc32/acconfig.h +298f4e880e70c371bea1db9c6c7cb9eb sim/erc32/config.in +9045efc77a4220c0bc9cab5a0ee9d3fc sim/erc32/configure +9c07eff0f5e858ed8377b772941d4808 sim/erc32/configure.in +fb82f2de8f5ca5a041a8f5a0c8536984 sim/erc32/end.c +5f964603ecf383d79bf916cd00e3c524 sim/erc32/erc32.c +1afa3a18ae4d56a3d4cc4127bc5562a7 sim/erc32/exec.c +c70f15cbd85894f4879fd49f1729da79 sim/erc32/float.c +470a781dea42dd4ed60734f97f0fecb8 sim/erc32/func.c +5d55e685281806e6fb65aae7ea51a36e sim/erc32/help.c +68bad97faa11ebff4fb3af241fa9e026 sim/erc32/interf.c +159d7b654fb2fe310e0eced630bb87de sim/erc32/sis.c +4e9b2b2599387377b967a67f46bb6f6a sim/erc32/sis.h +e7a02f18ba69be1512d680e05b4c44da sim/erc32/startsim +91cfdd3b348862331438164115946bee sim/fr30/ChangeLog +6c2955174eb0124514bc5ebe5f282153 sim/fr30/Makefile.in +96a66b845d0fe0898cebd3b18046df90 sim/fr30/README +00d02dc1cfedc02f32f38cfb5cbc548b sim/fr30/TODO +0f339763ce538919da205797dd43de48 sim/fr30/arch.c +e039d8110cd0911f807dbb86ad98e3b7 sim/fr30/arch.h +0fee562cbd64803269a981154f5ed55b sim/fr30/config.in +d41d8cd98f00b204e9800998ecf8427e sim/fr30/configure +affb4771fb6296be9abc2b067ece92f4 sim/fr30/configure.in +1262f25d232f7af7f34dcf938011f83a sim/fr30/cpu.c +1cf92d8d0714e9a4a26c6ebcdb534b79 sim/fr30/cpu.h +c2860e8016eca83676ec4b8d2e496778 sim/fr30/cpuall.h +a3cb9c589585838ed82a99af4ea8846a sim/fr30/decode.c +6e771325f26c31bd5f118b573077af5a sim/fr30/decode.h +a00dde52f6c8e19cbec3d8f73859c216 sim/fr30/devices.c +24a2441a93219b159067c616fbb750c7 sim/fr30/fr30-sim.h +ddd5c7e81605aaec32cca9539124c694 sim/fr30/fr30.c +1280b998340053ea8d1a584cca95c007 sim/fr30/mloop.in +609b9be03755fc679f70f59464cca99e sim/fr30/model.c +c6e2caf669d7ca3783c534b5a7c80ad2 sim/fr30/sem-switch.c +c7ea26d1b17dab34d5399bceaf3adfe8 sim/fr30/sem.c +8201cbf7cfb2640d1161166bed14c305 sim/fr30/sim-if.c +50d18a952ac0f5263155d343355c8b34 sim/fr30/sim-main.h +c956f3357b764d727169600488a06226 sim/fr30/tconfig.in +80843e0199a956021787265617353e34 sim/fr30/traps.c +d94280f664355697d14ba2a5a80315f3 sim/frv/ChangeLog +dcee34352c01725233bcdf8e0b1ea9b8 sim/frv/Makefile.in +1dcb16936dd94db21e5b82f208506a6a sim/frv/README +4327df77a7932a933cf53cd14051fdc0 sim/frv/TODO +a94ca5f528402cd69460f634bf101c86 sim/frv/arch.c +dccfd2d39c96012ca0eae69d6a166409 sim/frv/arch.h +5fd95500bbdf23126eea572fc2e51bfa sim/frv/cache.c +b04caefad8fd5b977599e0466867e3bc sim/frv/cache.h +0fee562cbd64803269a981154f5ed55b sim/frv/config.in +ae0a886300ce47f7d0809da206a68c73 sim/frv/configure +437469979dc814cde94dcd8467f1558e sim/frv/configure.in +54bb3c2594c112dc7f1c94a82cc78b94 sim/frv/cpu.c +31d234984d077def385a98a21c7ae640 sim/frv/cpu.h +79d435f7c81cd606c3fb256a87f31bc9 sim/frv/cpuall.h +a23718ec59d7a54d9612de1337a88313 sim/frv/decode.c +2c327e24e0a2f5f354ee3a1e71552165 sim/frv/decode.h +b88b43b621769c8a9227a9fccfd3367d sim/frv/devices.c +cae334018f11961982bc58933c6a74d0 sim/frv/frv-sim.h +b4263349e06a31fbf63b0bd1e9ea7dd8 sim/frv/frv.c +09c821f59eaae193268ccff81a6e1861 sim/frv/interrupts.c +9baf6c0b70d657aac79520d12e762c55 sim/frv/memory.c +49f6a4904fe580710be329a12b99fa53 sim/frv/mloop.in +67bd1b5a82d0d33db2db7dcd6e01ae15 sim/frv/model.c +58f9f6b71ec446179eef410cd656ce87 sim/frv/options.c +d605a6b470b3d607a5c072c1bef1195e sim/frv/pipeline.c +d6b0002fd07cc49efd90aec3a63f6c74 sim/frv/profile-fr400.c +91665b85808e528cc28e1c554622f952 sim/frv/profile-fr400.h +f03ec9e566dcb0eb931119bfc7fcaee0 sim/frv/profile-fr500.c +0c2c41ea9d45da288d6e9244c74d90e1 sim/frv/profile-fr500.h +93e7866d46241608d3062efe0b87e392 sim/frv/profile-fr550.c +b1ed355936600f58ceb01670202b9853 sim/frv/profile-fr550.h +9282b4d2f7d1f7ee246f3c6a6f7bc5a1 sim/frv/profile.c +b4751634e44ce7a2e04c5ec256d80b19 sim/frv/profile.h +15b3ef525e95048ea1aaa2ae4e4138a9 sim/frv/registers.c +4685f68d96a65710041561c7f4c06a91 sim/frv/registers.h +72e74cb9790325b6ae59ce9a3aa767ae sim/frv/reset.c +8576c5f90e7f8a75513a82135ed896df sim/frv/sem.c +178a4f29d1fe5e63fbe49770786d95f9 sim/frv/sim-if.c +81dd638958b042eec526ec15799a57c7 sim/frv/sim-main.h +87e1b2f71a8938597514fda93676e466 sim/frv/tconfig.in +9fc487c300aac79319bf38f5e2915407 sim/frv/traps.c +14b5ab412536790ba49e1566affa55a3 sim/h8300/ChangeLog +b261a58938986fa4bbd0b26d7c423bb4 sim/h8300/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/h8300/acconfig.h +bbf1890e065354abfec80271ae333444 sim/h8300/compile.c +298f4e880e70c371bea1db9c6c7cb9eb sim/h8300/config.in +f31819458845d3f8eacf97fdae917c13 sim/h8300/configure +323584913b59655b40d8f0efb7e997f2 sim/h8300/configure.in +c5fc0ac18cf227f20bd9e218f219d811 sim/h8300/inst.h +57ddd7ec6dc75f46110af89cca60a0a9 sim/h8300/sim-main.h +f180a66ef231f5eabfe450962b4225cf sim/h8300/tconfig.in +5a198f6b19aed858570b289330bf44f2 sim/h8300/writecode.c +7b6447efdcb1b5c2d72ca3c7405cac78 sim/h8500/ChangeLog +aac6595692b0a6efa78aa1acd59a1b5b sim/h8500/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/h8500/acconfig.h +9e2ecfe208b1e193db410e07891f1f0e sim/h8500/compile.c +298f4e880e70c371bea1db9c6c7cb9eb sim/h8500/config.in +fc41f130bb89e1aaab815985a7d3bc3e sim/h8500/configure +91220a453f328d82b56e45f08827aeb1 sim/h8500/configure.in +d93db14051811ec8ba02a3ae659f26bb sim/h8500/inst.h +9a6f06f52b6a2ba3726019fd216bd80f sim/h8500/tconfig.in +abd42a055894c38591ce543a15212ea0 sim/i960/ChangeLog +3d77563ed40880c9cd05d75ad9345ccf sim/i960/Makefile.in +a40c966863637436fe3a4acf947dd0c7 sim/i960/README +5c175f35c400439178181de5c6c338f0 sim/i960/TODO +c277414b921bc85437478d47aa2ff522 sim/i960/acconfig.h +fdb273abc49f05e945488a5cd1203324 sim/i960/arch.c +4aa5b6c85457d671d9309c160b7463e7 sim/i960/arch.h +0fee562cbd64803269a981154f5ed55b sim/i960/config.in +1a3f8fa5d2e3e5c2d1242ba85a77a872 sim/i960/configure +ca0be5b63820bc94b25fdd8573fbf767 sim/i960/configure.in +43e2d85b7da0385b2251518a04cb9d3a sim/i960/cpu.c +5b477b6ec1ffc3fd9722e52740477c8a sim/i960/cpu.h +5b7427bfa18f5a0d35a203bd49b32e5d sim/i960/cpuall.h +f13eb3aeec4d3e80fea3141cd1569972 sim/i960/decode.c +5d1a31f263c24055175d13520ed777eb sim/i960/decode.h +34553cdaffc67e146207e498fb20198b sim/i960/devices.c +02d782e504f910dae67e743e44f31b88 sim/i960/i960-desc.c +0e4f799fa7e4fcafaca945a4b36c0613 sim/i960/i960-desc.h +7617d8109b7ac5be37716cc44e90f1a9 sim/i960/i960-opc.h +853bede0706d752f3e8805d143a3c1c4 sim/i960/i960-sim.h +c54b8356d84f0cef23b7bcbb40f2e2fe sim/i960/i960.c +f7156af46ba360deaf8cd0c29ff1b5b6 sim/i960/mloop.in +181f7adaae9cc9f684427c87235257f7 sim/i960/model.c +564ad8b94832c643d21ab4a15c0081aa sim/i960/sem-switch.c +95b15bd87786d146f652f9fb83cc0413 sim/i960/sem.c +ae9997acd3cc669b25b97228f62314dc sim/i960/sim-if.c +4cce3e6b82f6216771c14ed404987586 sim/i960/sim-main.h +1c6bda214533fb133515f0ede3f91333 sim/i960/tconfig.in +2e52341ba1ddd648c60fe0991c76e8e2 sim/i960/traps.c +635eaadc1233b6d392e04ce2efc7465c sim/igen/ChangeLog +f3b7b7e50b2f2d0e72dbfca12b85f50a sim/igen/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/igen/acconfig.h +422222ab85ca136ef98c3a169a2bbb00 sim/igen/compare_igen_models +64cf5a0611ad7aee52e1595e54b30841 sim/igen/config.in +3bfb0607c4c2a4d41767a4e54e2d65ec sim/igen/configure +508b72d9370e92ebcc04e8abcd0328da sim/igen/configure.in +a7ddc265e574c9087232ee5d3275c872 sim/igen/filter.c +cdaaeb083244280d583a3d4be956ff69 sim/igen/filter.h +3b6de5be9150ccd04c0095ed082c94f1 sim/igen/filter_host.c +a68bb92496f910da726685db059affd8 sim/igen/filter_host.h +608521d5f029e56b81e5485e4cf3d32e sim/igen/gen-engine.c +8574c19656b4226ab19e22c73a0c079e sim/igen/gen-engine.h +8b643b4143a38545777f14db336bfb8a sim/igen/gen-icache.c +0c15aef6804e5b1a4a8b54f3e24dea30 sim/igen/gen-icache.h +003b2dac367a40fdd0f72787c451aee2 sim/igen/gen-idecode.c +f63a2c52375a861738f06384ff5fb176 sim/igen/gen-idecode.h +19ef018c2d7195c8de65e342ca6e8824 sim/igen/gen-itable.c +07f9217f44da3481a46a6c0d1615a204 sim/igen/gen-itable.h +45542b4586b0c07373f7967595a020d3 sim/igen/gen-model.c +98d3496d6cfb8b9ba44f564e69ff4573 sim/igen/gen-model.h +83768cf0023c15a615cf2595d0da5445 sim/igen/gen-semantics.c +a281210a4d10c43ce6d2843d052354f2 sim/igen/gen-semantics.h +7017d947f77588adc4e7abfcc3f87f57 sim/igen/gen-support.c +dea9d61752587dd0f75fa0bc680c1ce8 sim/igen/gen-support.h +9f9e328d80e735cfa2748b6ef0d257d5 sim/igen/gen.c +e5aa8f4a17d224e9d6244acbd91f851b sim/igen/gen.h +495b00951f547c3ff81f48c707b6158c sim/igen/igen.c +88d6154df5d156bd381fa33f70f94f29 sim/igen/igen.h +fb7d0739d93fcc2c585224dbbc7e986b sim/igen/ld-cache.c +af879a10b93dad0dbc6e27dc7abd3ccb sim/igen/ld-cache.h +278627569fa6d6ab7845ed89e2a906d6 sim/igen/ld-decode.c +718fb888c6f19d9a645ea14b58de84bc sim/igen/ld-decode.h +20bf370217048ec40ba15b58eedc8a21 sim/igen/ld-insn.c +599a98e625372b77ba4439835fd6fa5b sim/igen/ld-insn.h +92dd6c4eabc783c7798b1fc23011d5d8 sim/igen/lf.c +4d29b74cc6459416de9184f8f914f2fe sim/igen/lf.h +3bc79cacd418c1e60e65f917c8e6f23a sim/igen/misc.c +5a63050499dad653f12c11557df3d95a sim/igen/misc.h +e4d2618404646b1897b58a2bb1a61849 sim/igen/table.c +af7e8a2921fdd031e96b3739d0b207e3 sim/igen/table.h +12849a1931782a8730c6ac9b8959e357 sim/m32r/ChangeLog +b40685b2009e7c095fb1321caf74d25d sim/m32r/Makefile.in +23b6e82d29f42c31a097d431b0f73004 sim/m32r/README +7aa7d02d4d195447e0ae6c176fc6ceb4 sim/m32r/TODO +c277414b921bc85437478d47aa2ff522 sim/m32r/acconfig.h +996f52b08c6341a79cb89970a6e9b7a0 sim/m32r/arch.c +c9d7ea4c42bb911f8d21f051bd8bdf44 sim/m32r/arch.h +0fee562cbd64803269a981154f5ed55b sim/m32r/config.in +97f2c88de68238f84990ef1d99ea8aa3 sim/m32r/configure +87bd1b3fdf0bca0ccea3a96c2f506c81 sim/m32r/configure.in +a2e6c9fa39ed2445d3b15fb5486280cb sim/m32r/cpu.c +3f4414a18de15b9f1a6a5a7a40a5440e sim/m32r/cpu.h +5fd78fde39ed741b1e792312bc31c0a4 sim/m32r/cpu2.c +6308de37e93f389b5cea1abdd27333f9 sim/m32r/cpu2.h +a1e6805774e092c6f1674c68b3ab49db sim/m32r/cpuall.h +49e4a17460d576ef9edf9dd7cf8c781e sim/m32r/cpux.c +8889d2dbab2a9b7da7eaea529fbe1af2 sim/m32r/cpux.h +b73750c1798f1ca5a897ac63191c2b65 sim/m32r/decode.c +8539bde44ade91f27698b4b05b014831 sim/m32r/decode.h +1b3f40a25e4cff9f8cba792b0f424437 sim/m32r/decode2.c +5e98e3718b6d6d31b2c60df199483a2f sim/m32r/decode2.h +22b8b4f133923266e8857233e1a393b2 sim/m32r/decodex.c +926c182dd094f306984766b4e1b5707c sim/m32r/decodex.h +7788a7c57f7884be7c37d25bb4d86233 sim/m32r/devices.c +e051bef0f6697dff11f576592b87c470 sim/m32r/m32r-sim.h +3411b3004ac4386c233e19469b0b3fda sim/m32r/m32r.c +a3802a004168beb1299bda0c59693f3a sim/m32r/m32r2.c +4169446d172632a917d4cd0037b1931e sim/m32r/m32rx.c +c34a4a213ae34afbc938148fc40238f1 sim/m32r/mloop.in +896d3c80cfc14d62fd51a094b9ccc13a sim/m32r/mloop2.in +d40cb9b256777840bf815680a1d39ac7 sim/m32r/mloopx.in +587b6177abad21e50044d69348716a0e sim/m32r/model.c +54a4745aa3a167d2693966688bbda455 sim/m32r/model2.c +ff51ea5bf669af6d988ef6be227c912e sim/m32r/modelx.c +6692a9702241b4499f75a4c9d23c7fd2 sim/m32r/sem-switch.c +7bc2814a06f295e62c039afc76c4eb2c sim/m32r/sem.c +f0841e2822cccd6568bab2217274ee80 sim/m32r/sem2-switch.c +6a15a40b8d9f5708faf22b1714dd2408 sim/m32r/semx-switch.c +ffd2718e234371cb2ca2d0b99ff00240 sim/m32r/sim-if.c +a24af2c954c1781817ac3519604b8e37 sim/m32r/sim-main.h +45a0108d5b20ee6c8b06c05f0b2db833 sim/m32r/syscall.h +e962644fafd12290fbf81ebc5bf75941 sim/m32r/tconfig.in +14ca824124e46571c55943993c4fcf5d sim/m32r/traps-linux.c +6cf4831571c7040345069124587f704f sim/m32r/traps.c +c17abb369524f87498fb8098d8554a58 sim/m68hc11/ChangeLog +759275b1a5e4073c82a64eee0290df81 sim/m68hc11/Makefile.in +7216ccc164e27ed244a88fa920621c28 sim/m68hc11/config.in +60312156da8fcfd2b5a43f57888c61e3 sim/m68hc11/configure +a442aff0717d6b743f45c305a56a81b3 sim/m68hc11/configure.in +6306b0d52de502b09c735c8536445869 sim/m68hc11/dv-m68hc11.c +86f7f1ef15e23744e1e12f7189ead722 sim/m68hc11/dv-m68hc11eepr.c +66def3567515023a2623fe6ddbd7ac6c sim/m68hc11/dv-m68hc11sio.c +0eeea9cf3fd07809bdceb3bc2e2f1c7f sim/m68hc11/dv-m68hc11spi.c +5740ce8db5af3406ecd705d9a40dde88 sim/m68hc11/dv-m68hc11tim.c +8af43034356f916cf60db7029715a6c3 sim/m68hc11/dv-nvram.c +e189d6f6562000c5fc7308391ad7bac8 sim/m68hc11/emulos.c +c42b2ba01baca551610c5780831fbb2b sim/m68hc11/gencode.c +faf3881415f9b4ee93601c14782a6f7d sim/m68hc11/interp.c +d8bfc1fce8ff8674776f00d9c247edd9 sim/m68hc11/interrupts.c +dbaa2b61ba2abe66b6456612c3bd24e0 sim/m68hc11/interrupts.h +e116a2ceb1bfdfda286e145b3749ea9b sim/m68hc11/m68hc11_sim.c +8e1e56a9385d767aabd3654ffbef4611 sim/m68hc11/sim-main.h +aea1847f61511e6c88a36e41988a02e3 sim/mcore/ChangeLog +7a419dcb91f3a385263b94390e380373 sim/mcore/Makefile.in +7a0ac25f6a6527e94daf604368008af7 sim/mcore/config.in +8653a595c12f9577cbbf0d1d7a88faa0 sim/mcore/configure +0a4ea962282f282a0cea4091d7853ebc sim/mcore/configure.in +7e402acbcfdb4c9fc7051e273f808f4e sim/mcore/interp.c +f36379389e336917d707165f92b5e0de sim/mcore/sysdep.h +a813810ab5324f4ad1452a88188be363 sim/mips/ChangeLog +07909736600a2df706f59d757b340c11 sim/mips/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/mips/acconfig.h +7216ccc164e27ed244a88fa920621c28 sim/mips/config.in +dfec119316c2c633b516a43e62a4ab65 sim/mips/configure +a08a1d176bf11e53b7d3a753d16af356 sim/mips/configure.in +690bb341293d988336f0a3229858411b sim/mips/cp1.c +cfd93ed6e20f222ba7b8f5cc0a2d1626 sim/mips/cp1.h +48313bab48ed7001558227bb55427cd1 sim/mips/dv-tx3904cpu.c +ea6a03fe8459556b03582d1a047c2b69 sim/mips/dv-tx3904irc.c +ff7aec055766868c712979c75248fcdd sim/mips/dv-tx3904sio.c +7bd6c90f4266d6b5e82db4245fa5b71a sim/mips/dv-tx3904tmr.c +d8dcbd03a41a7be1e765e64539fdb28c sim/mips/interp.c +61566dc2819979301d3d92473a37bbc3 sim/mips/m16.dc +a2b7ff4fd8c66926c4d7f9c908660770 sim/mips/m16.igen +383c97095ceeb7131e415af4e6089bec sim/mips/m16run.c +7904bf22efbdc475cf1594fad60512b6 sim/mips/mdmx.c +016146452a32f25514afbc560f00088a sim/mips/mdmx.igen +0cc85f54d1aaffc21fa0a619b2e23020 sim/mips/mips.dc +dabf74d62cdf37a1ba428aba665426b5 sim/mips/mips.igen +eb2f600f9761977db8d3feea4b65e04e sim/mips/mips3d.igen +a1271a930f1d21b88dba16a50c0ee756 sim/mips/sb1.igen +7dab3d41ec64a57cdc85cba9f9e191a3 sim/mips/sim-main.c +10d59a5c3e8237ac550843a7391c6b65 sim/mips/sim-main.h +926a84abe029a2f84db15716688266ca sim/mips/tconfig.in +e90e73eee445d44f164749dc8d8c0a4d sim/mips/tx.igen +ba62602283b3852a0e0be5ca7c31f6c5 sim/mips/vr.igen +46c8a94f60ac12ff17f7ba9708923223 sim/mn10200/ChangeLog +9f141b8dd47f317190cdc9a3ce984d53 sim/mn10200/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/mn10200/acconfig.h +298f4e880e70c371bea1db9c6c7cb9eb sim/mn10200/config.in +8653a595c12f9577cbbf0d1d7a88faa0 sim/mn10200/configure +0a4ea962282f282a0cea4091d7853ebc sim/mn10200/configure.in +eb1b39921b51cdfb00709c9a18d3b2eb sim/mn10200/gencode.c +a3eb57c673f94a9c483604fb4343c910 sim/mn10200/interp.c +a44842feda9ae70fbbb834eb0680719f sim/mn10200/mn10200_sim.h +479d6c9ea43b90d1a9cd4298c6284f6c sim/mn10200/simops.c +b1f46ec47e1a31623ca0bf87114bb5e9 sim/mn10300/ChangeLog +8b70ca01f08cfd84fb7a1a90870f8ae6 sim/mn10300/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/mn10300/acconfig.h +f2d47ad14aeba7bff0ed3d22edd3b6d2 sim/mn10300/am33.igen +dc553d113147dcc545cf06254dc945cd sim/mn10300/config.in +02eac39f01f8738f31c1a0fd07b580f4 sim/mn10300/configure +1f64f042f45eb08a55952212c2eff45f sim/mn10300/configure.in +c685749cf62929a0240f0e4ae35d609b sim/mn10300/dv-mn103cpu.c +816316050cd0ae95243c95b47663da8f sim/mn10300/dv-mn103int.c +db75cdb54357d705e6bdebdcd9e3811e sim/mn10300/dv-mn103iop.c +bc62aff9064a399af82b70c2666ce058 sim/mn10300/dv-mn103ser.c +0939bc8de505ea9717bd274b9fdfe292 sim/mn10300/dv-mn103tim.c +fbe965d4d693ffae4b0bba1166cde6d4 sim/mn10300/gencode.c +5140f4c6f80e90226f7091e9d3738875 sim/mn10300/interp.c +a02c306411614c8de463bf278aac5d2e sim/mn10300/mn10300.dc +7043e91c23dd572d29fc98541a0cebca sim/mn10300/mn10300.igen +366b67df562313696adbca47a8834a10 sim/mn10300/mn10300_sim.h +3bcdb8235b340516548f0d3c81d46f56 sim/mn10300/op_utils.c +9560a29b6c94d4955a447290ab5d050a sim/mn10300/sim-main.c +b29858ce03067664cc41c6b57c04b31b sim/mn10300/sim-main.h +95c44ccdcd1db369924ac39bce801d5d sim/mn10300/simops.c +a123cfe902117497cd3549ffb9746f78 sim/mn10300/tconfig.in +9386f74bff5fd3a25d4cea3f6cb22bda sim/ppc/.gdbinit +36407106664516616438a622329f6f1c sim/ppc/BUGS +0636e73ff0215e8d672dc4c32c317bb3 sim/ppc/COPYING +55ca817ccb7d5b5b66355690e9abc605 sim/ppc/COPYING.LIB +b7413ba700088e6158067136b005fe8f sim/ppc/ChangeLog +1bad061e853e13647aa63e38a9f1001f sim/ppc/ChangeLog.00 +ecd61aaafc1737616ae87c802cc0a8e1 sim/ppc/INSTALL +9ad182a22baf78b14afadf50a4d026c0 sim/ppc/Makefile.in +851c77c4a526e09ac6fb7a77cba89b89 sim/ppc/README +9b98a3220b34ead882ebd988dec298a4 sim/ppc/RUN +c277414b921bc85437478d47aa2ff522 sim/ppc/acconfig.h +d41d8cd98f00b204e9800998ecf8427e sim/ppc/aclocal.m4 +f3e930efde135708616e46a2d3949bd5 sim/ppc/altivec.igen +b6f5d464f7ec0259af422334dde59abc sim/ppc/altivec_expression.h +c51c1f314cf140ad857550ef88b10470 sim/ppc/altivec_registers.h +9652d7609f72d7caed40808ebe8fb88e sim/ppc/basics.h +65f3366c7c3689220435a25a2ba082cf sim/ppc/bits.c +26ed1de12dff50c6a0519d14c73875eb sim/ppc/bits.h +4cb3d76f0038ed5a17f3309bda545304 sim/ppc/cap.c +8f88189396a532d2824fcef2d85db174 sim/ppc/cap.h +b2463b6e50044deb7e2cb999f38ca027 sim/ppc/config.in +69daa3cbf424c9399a4b2ba771480e41 sim/ppc/configure +2899986c46db4227dac5a1a24fa07ce4 sim/ppc/configure.in +131b92c2bfc60c0a0fa11c7127f01151 sim/ppc/corefile-n.h +29769d29b23530fc8e7468cb63db2338 sim/ppc/corefile.c +2ad9c889b2483dc6b2f700cc50d5b5fb sim/ppc/corefile.h +660e642bfccbe4d4b4b24f8d276f2353 sim/ppc/cpu.c +89dfdf1a4d8b1700564cc4e5f27a8254 sim/ppc/cpu.h +d3057ff75f6c17550e153338da749f6d sim/ppc/dc-complex +7e0b4be2388bf97887228aa76e954bfd sim/ppc/dc-simple +763cc8428117c5c2bd847cfd06bad1d0 sim/ppc/dc-stupid +b055ce44c5462421dd15b911a2062f25 sim/ppc/dc-test.01 +f41d30b6b933ba4acab16757fff79de7 sim/ppc/dc-test.02 +a6d011adc9e4de62790722e892b94c97 sim/ppc/debug.c +40b9eb72287e10011898a3f69ca9a9e8 sim/ppc/debug.h +67401955dff214152654f4bb80fcebaf sim/ppc/device.c +fee7a267accd496b6e2c4650b01c9b3d sim/ppc/device.h +22be58a024fde413f5c3cce2886bb260 sim/ppc/device_table.c +1f064536d367de4ddd18a25453c994ae sim/ppc/device_table.h +c2f21558a815c20612b2ed4f41a34197 sim/ppc/dgen.c +e08cfb709d371ce5e6f9f34d81ac9828 sim/ppc/double.c +26fba4dddf659d490c8183770049d1cb sim/ppc/dp-bit.c +778d7f98fb015b8f96b02a7f188ba18e sim/ppc/e500.igen +101c7fd23d373f9026081875dd7621d1 sim/ppc/e500_expression.h +a2a58098edf9df5967bd766f7c87a4a5 sim/ppc/e500_registers.h +d96be9d476f04a86ff09e0bb56ee943f sim/ppc/emul_bugapi.c +f3d6d8d54f0b5c045c86907af1622bb1 sim/ppc/emul_bugapi.h +ade49d06e52abba4f8ec33a1fe674c90 sim/ppc/emul_chirp.c +9ef23ee673b667efd253b033f899761e sim/ppc/emul_chirp.h +c6d335c965bc9ac0fd8a69490abc036e sim/ppc/emul_generic.c +ed6d07b7f4e68168b0ac37650d30dce0 sim/ppc/emul_generic.h +5a5c562ab31b44fb73f9631530dfc99a sim/ppc/emul_netbsd.c +7b33787dcf41c03863f43b596f3e4a50 sim/ppc/emul_netbsd.h +14b5605c5c067c9fae8edb40686e6b4b sim/ppc/emul_unix.c +3f59054ed73fc405d309edc3c0cd58c0 sim/ppc/emul_unix.h +e0f8bb1f315522473bf26e2561c51239 sim/ppc/events.c +6cbdba37de3215094841c9436c4a706a sim/ppc/events.h +f6e4ee2195d564b95790b8b48423ab68 sim/ppc/filter.c +5d83db32f82407624ef3e44877bfc901 sim/ppc/filter.h +b0e13975e4c92bc339a5db359eeeaa0f sim/ppc/filter_filename.c +e19c72f467811559af2500ff99310762 sim/ppc/filter_filename.h +82c063a4f15c6576229bd0c5a77d0061 sim/ppc/gen-icache.c +de741bee50e72c9eecf54eb31a57ce18 sim/ppc/gen-icache.h +7c88da65d2064ea39325546b703797ee sim/ppc/gen-idecode.c +397ac3ac567e76ac1f4f7eb47f9dfe65 sim/ppc/gen-idecode.h +382f9371a894b71e4ed2afb83f8512f3 sim/ppc/gen-itable.c +31313c242173b2fe764f90edd57ce459 sim/ppc/gen-itable.h +5da7ebf67f12aabf1833e7ada1ac3537 sim/ppc/gen-model.c +d43fa565ffb41b1c78dd6065ae0845f0 sim/ppc/gen-model.h +218fb15b91e0b63886b2f201c703fa1c sim/ppc/gen-semantics.c +dec70a4d4d0f2e04b9eb9c27aa842c79 sim/ppc/gen-semantics.h +8f683225ed38466273adb6e821a62cb5 sim/ppc/gen-support.c +125e5cd58b108f5a52c65544d1ba6638 sim/ppc/gen-support.h +66fff86ce57112322b003c08f8082358 sim/ppc/hw_com.c +54811845fe3d62433b00e07da46dc594 sim/ppc/hw_core.c +5abc6e083931e0d458473da276a7c6a4 sim/ppc/hw_cpu.c +0a5a25a4fecbe3cbbf7f70711c577567 sim/ppc/hw_cpu.h +121bcfcb4285245e045b8596c3a747f8 sim/ppc/hw_disk.c +50a89c1f61bf77a7ff0dcb467a0206a4 sim/ppc/hw_eeprom.c +e6e7b45f07996b30fcddc8e10cae366a sim/ppc/hw_glue.c +a5cf7634bc0d9a09876c14f194f81e80 sim/ppc/hw_htab.c +c2b3a77eb45c504654e71b7e16ea2adf sim/ppc/hw_ide.c +57ecbf831ff4930dcd3b62c09133a427 sim/ppc/hw_init.c +5fc19100c2410b42430334c970b7026b sim/ppc/hw_iobus.c +194c545e87c2f690b8949843bbac306c sim/ppc/hw_memory.c +d4c516dbc656ce6b2b16caf4ee9aebfb sim/ppc/hw_nvram.c +ba5acc7a95cdafcda3aac022b9b6e0e3 sim/ppc/hw_opic.c +e492e3614a6bd470ccf9bc24071c32ec sim/ppc/hw_pal.c +1cfd2049fa85129d72af534948c7244b sim/ppc/hw_phb.c +0782b28bb03134bea2f77d3e21431333 sim/ppc/hw_phb.h +789065ef358a2a3dd227c387d481cd4f sim/ppc/hw_register.c +5d8731168076d37dcd4ad8a2d6b0bcea sim/ppc/hw_trace.c +b6b91adc2188e28630d543be73c728ae sim/ppc/hw_vm.c +8ad4143e2bdd2ef9a398710de5877613 sim/ppc/idecode_branch.h +63e7f1f0dfc6d16de67e47829d6f6750 sim/ppc/idecode_expression.h +a2a6140315cd3e6453fca3098ea6e0ab sim/ppc/idecode_fields.h +c8aed2d71502b4d53e12b87f201953cd sim/ppc/igen.c +1f88347bb2decb1fcd7487967bdca59b sim/ppc/igen.h +52907d4b0d9210c127a37368437d0ddd sim/ppc/inline.c +03137ec9c557c5729790f1bb1563fa34 sim/ppc/inline.h +ae8d0a3696f84324c18d529193e3a0aa sim/ppc/interrupts.c +d36e61a48bbeb0fc22d6a43502618468 sim/ppc/interrupts.h +a2376b46e21317f87a63c93cabab96a3 sim/ppc/ld-cache.c +5c6c90b8dbfdf6f0e8fb8f01a599061b sim/ppc/ld-cache.h +e8ca4a4c2e2662ef78e50e1516e3bc4e sim/ppc/ld-decode.c +c96a0234594399abd61c514cf7885206 sim/ppc/ld-decode.h +ad52b61bb3c6f286d96c54d156a7ea26 sim/ppc/ld-insn.c +593a5550b97ea2cd864a310b6ee04ec1 sim/ppc/ld-insn.h +daebea50f263bbad71ae4a076eb048ef sim/ppc/lf.c +267c9ade5fa517ed0fbc29c776dc3cc9 sim/ppc/lf.h +d04db63c46f629ef831a4e87a08184b0 sim/ppc/main.c +685bbe6ed4a3962eda1f367838cb09cf sim/ppc/misc.c +01dfdfb64f654f8a7501ba41e05a3fa2 sim/ppc/misc.h +213ccd2e7b903475f306cb61e3de7b25 sim/ppc/mon.c +3287b3ce2acbf89f0c76939187857022 sim/ppc/mon.h +af7c9c433b85abb5c5e61673fea77b45 sim/ppc/options.c +39bcc46ecea434624fdb42fae9ce598d sim/ppc/options.h +955e62ba48085a359721fc988df0affe sim/ppc/os_emul.c +ec00d27d9b5b0ee84e478874c7952855 sim/ppc/os_emul.h +dad3b3f6b9a6e1551b7767d567f2814e sim/ppc/pk_disklabel.c +dab52f2f241129432e05f4796eea5397 sim/ppc/ppc-instructions +fea984afca834b59ac7bc3d62d547432 sim/ppc/ppc-spr-table +7ef1469cfb0809ffbafba1a6f43cc98b sim/ppc/ppc.mt +4e00a173c2a1427ee913e8bf184ad402 sim/ppc/psim.c +14dfb8864f8b7f98b5c2a1f2b0cecd7d sim/ppc/psim.h +3451a21ba5941444fe5ee2960d137449 sim/ppc/psim.texinfo +edc5e08e83b415d070176ec878fc1b10 sim/ppc/registers.c +e20c3fefc2cff3ff71658b6cea230773 sim/ppc/registers.h +27f339dcae5a8605568b933ad52ed9c9 sim/ppc/sim-endian-n.h +b4fd27207dfbdd0fa5586a006a50b670 sim/ppc/sim-endian.c +f2864bc7dbfd420dd6bf6ceb87a7e8ac sim/ppc/sim-endian.h +48c6b8643d82c832a08fc5aad6c182c3 sim/ppc/sim-main.h +9cc64e896ca9c264032ec0c23d8c956c sim/ppc/sim_callbacks.h +48e8abc4c6561218b272c232eccce145 sim/ppc/sim_calls.c +2591babcc19cd684b6fdbfcbd6f7e126 sim/ppc/std-config.h +e7451d70081236bfb7163f267c854741 sim/ppc/table.c +393b81b772e44da580c2183af38e50c5 sim/ppc/table.h +fdd3a949d91eeb278b7c6f411c8709b4 sim/ppc/tree.c +23e9a034bf895eb2830a71e52cc4b44a sim/ppc/tree.h +e3af8bab4cb4fccf3b5830b93523c0fb sim/ppc/vm.c +f5e70f8a845ecb64afee001c9d36535c sim/ppc/vm.h +ed994e6b649eff89844e1e09fb217d02 sim/ppc/vm_n.h +0a3e20c2efc205e378d3d55d33929fc6 sim/ppc/words.h +ace334961586ac7e4e727012b0495793 sim/sh/ChangeLog +23602cb5409d20d5cb482a046e2771f3 sim/sh/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/sh/acconfig.h +298f4e880e70c371bea1db9c6c7cb9eb sim/sh/config.in +8653a595c12f9577cbbf0d1d7a88faa0 sim/sh/configure +0a4ea962282f282a0cea4091d7853ebc sim/sh/configure.in +7f048fb4605d9fc88d063e79d1dd0659 sim/sh/gencode.c +4a969caff2c769d43ee468d9f4074af6 sim/sh/interp.c +485762a39054bcf5bf3a3ee2a4de586f sim/sh/syscall.h +d0f4fcd32d377647d675b8d3ef85db09 sim/sh/tconfig.in +132b90d2280f46c299d1b8e39656b451 sim/testsuite/ChangeLog +ddd196390b26fc624f607bfd82ff729a sim/testsuite/Makefile.in +7243c8e0a37d645c04d36b678f902a2c sim/testsuite/configure +c0ccc959de0e4e5d22b54468c77adcac sim/testsuite/configure.in +8b1814b871166305ec8fc7a06cc9a84d sim/testsuite/common/Make-common.in +09db0759c17936e2d8cf6dea6eda8fb1 sim/testsuite/common/Makefile.in +9980219e011c42205bbd14e46d21fc8f sim/testsuite/common/alu-n-tst.h +56912c8f1ff672daf4dbab4a0fb12a54 sim/testsuite/common/alu-tst.c +42cbac0d5c278c9408ec0dca800a01b6 sim/testsuite/common/bits-gen.c +2c97e49ca99e657e07ca12a6fd5d6f69 sim/testsuite/common/bits-tst.c +874ac49fc37d49f2822c8b409d285004 sim/testsuite/common/fpu-tst.c +6f85f5b126eda2839d687ef1b5cc9587 sim/testsuite/config/default.exp +a3578cc8d27475e1226e45a184b1b810 sim/testsuite/d10v-elf/ChangeLog +f2e553ee3b71714955057e9f70b32deb sim/testsuite/d10v-elf/Makefile.in +734efc2fae2a739ad8a8b656f7a46072 sim/testsuite/d10v-elf/configure +288bd7e91ed8182fa32d11f022d738dd sim/testsuite/d10v-elf/configure.in +2092af64ed30dac7b430156bd2387770 sim/testsuite/d10v-elf/exit47.s +df56df219276d06d750e8fb6f6b1581b sim/testsuite/d10v-elf/hello.s +f9e7c86333f37f05849bb0913d84040e sim/testsuite/d10v-elf/loop.s +246424eed873ed649d2a32c1de0a12cb sim/testsuite/d10v-elf/t-ae-ld-d.s +517096aa5ab9c0e44c70c067d41b0536 sim/testsuite/d10v-elf/t-ae-ld-i.s +1d77729ab41b4cc1ef00c09482ec6715 sim/testsuite/d10v-elf/t-ae-ld-id.s +266aa2fe095d30aad29b83c25851971e sim/testsuite/d10v-elf/t-ae-ld-im.s +75cd5a849fb6a73f45b92c5173201ad0 sim/testsuite/d10v-elf/t-ae-ld-ip.s +880e8e02eb0c803c436bfc733723664c sim/testsuite/d10v-elf/t-ae-ld2w-d.s +e407a9027a51a971d55c14a9deac7d15 sim/testsuite/d10v-elf/t-ae-ld2w-i.s +3b139d94efcc709b303318543337cee4 sim/testsuite/d10v-elf/t-ae-ld2w-id.s +94f087c25d14650e94905d367ac781c8 sim/testsuite/d10v-elf/t-ae-ld2w-im.s +d35bfeba95637ae41856f6692744cbdb sim/testsuite/d10v-elf/t-ae-ld2w-ip.s +ccf5bb0090436bc56ae6e5ab152f9be6 sim/testsuite/d10v-elf/t-ae-st-d.s +c52f1cfa2ba8e7eb55aa93e564a0164f sim/testsuite/d10v-elf/t-ae-st-i.s +776264e34418e424ca53627692e3170d sim/testsuite/d10v-elf/t-ae-st-id.s +a25febe699e92863dd860f733c9dd22d sim/testsuite/d10v-elf/t-ae-st-im.s +6a1e686613656c7345b1feb238e31066 sim/testsuite/d10v-elf/t-ae-st-ip.s +7edbadafb83e173b875ef37b4728d3f9 sim/testsuite/d10v-elf/t-ae-st-is.s +f831b90857d7d08faa607a4c5d2fc618 sim/testsuite/d10v-elf/t-ae-st2w-d.s +2c65c61ce821576fd7642ae775e053ee sim/testsuite/d10v-elf/t-ae-st2w-i.s +6e39b3ee1a1f446f2aea2265a13e824e sim/testsuite/d10v-elf/t-ae-st2w-id.s +44c3061ac426dfdcf4a850fe15376b2f sim/testsuite/d10v-elf/t-ae-st2w-im.s +0492a673d4276924c61d9ce568802546 sim/testsuite/d10v-elf/t-ae-st2w-ip.s +670f5bcbd96246bf460d84b57bea1102 sim/testsuite/d10v-elf/t-ae-st2w-is.s +9324e63160953a8b19ec76988361aa95 sim/testsuite/d10v-elf/t-dbt.s +fcab1b7a79a3a82158f92a79f01fc1b6 sim/testsuite/d10v-elf/t-ld-st.s +24adce9358d8640ca6ae226ecbeb41c7 sim/testsuite/d10v-elf/t-mac.s +ace81e2c0d0d2ac060e2172d5fc8e655 sim/testsuite/d10v-elf/t-macros.i +d028e41377d7e4afcdc3b979f9e026d7 sim/testsuite/d10v-elf/t-mod-ld-pre.s +ba2eb8bb4b43be12c27308bebccab16d sim/testsuite/d10v-elf/t-msbu.s +be230dfdf2fc8a9548a086fd285ea00e sim/testsuite/d10v-elf/t-mulxu.s +c61c5fd4a6a85120020dea1782d72d65 sim/testsuite/d10v-elf/t-mvtac.s +744e0ee2abcec900b154f72ccf20434f sim/testsuite/d10v-elf/t-mvtc.s +202b3272059c697b714c5f14d21e8418 sim/testsuite/d10v-elf/t-rac.s +5850459c815d7a2cea95632d02288d93 sim/testsuite/d10v-elf/t-rachi.s +d3f2b6a8713945840267c5b38031db57 sim/testsuite/d10v-elf/t-rdt.s +d68929f5405fbc0fa82b417d61e8389c sim/testsuite/d10v-elf/t-rep.s +c2989be701fa58229f9d2c51d1d89b9a sim/testsuite/d10v-elf/t-rie-xx.s +b318831c796a5daf3c008a72a1bcff77 sim/testsuite/d10v-elf/t-rte.s +2e29d477a767f8c3e7b9806e5061b73a sim/testsuite/d10v-elf/t-sac.s +34070ba49d956128040f988eb91c46b7 sim/testsuite/d10v-elf/t-sachi.s +e8c67bf69426a7db6ecb7c2cafcc0a99 sim/testsuite/d10v-elf/t-sadd.s +ec7bb92d79cec389c2cf4685d0c91150 sim/testsuite/d10v-elf/t-slae.s +655e71f960343e657e230eba7ecb5f61 sim/testsuite/d10v-elf/t-sp.s +67a11da95718e0f31001311302fe7743 sim/testsuite/d10v-elf/t-sub.s +3bf62ddddb5d760ebd4a96790f02efd9 sim/testsuite/d10v-elf/t-sub2w.s +dd04c4735e06d614b03e76a552d4fcb6 sim/testsuite/d10v-elf/t-subi.s +b5b7dcb39e5fe37d20f5fbad5c205b6a sim/testsuite/d10v-elf/t-trap.s +8cba15e47843de592d01561920af7273 sim/testsuite/d30v-elf/ChangeLog +9d207563a57f64272ac6dc2d50b2ca2f sim/testsuite/d30v-elf/Makefile.in +e93542ef6c36b1526d49c88c3a0e7e51 sim/testsuite/d30v-elf/br-bra.S +33307709df7e9e56067a8e0de59bf0d2 sim/testsuite/d30v-elf/br-bratnz.S +7ae79abf0ec5df4ccdd1e6f44d2c6bf7 sim/testsuite/d30v-elf/br-bratzr.S +ae790a1cf27ac88e18036478b7d454e1 sim/testsuite/d30v-elf/br-bsr.S +f27f8166f0e2dccba3841285c579fe0a sim/testsuite/d30v-elf/br-dbra.S +446dd09e9d804c6583d6db8cd8bb0bca sim/testsuite/d30v-elf/br-djmp.S +51897cdfa07463eaaf76a8186dfdf0b7 sim/testsuite/d30v-elf/br-djsr.S +9c6af644b654d2d888e103f33a52ce7b sim/testsuite/d30v-elf/configure +288bd7e91ed8182fa32d11f022d738dd sim/testsuite/d30v-elf/configure.in +57a414d0b27c4465d2362c5a9c1e6171 sim/testsuite/d30v-elf/do-2wordops.S +7bff52c7b4c3536a647a815c787f5362 sim/testsuite/d30v-elf/do-flags.S +22b5ace3a746e6e8185d327a5a9aef30 sim/testsuite/d30v-elf/do-shifts.S +f6a9a0cb828c0a11996c863e3172b9e4 sim/testsuite/d30v-elf/em-e0.S +66042f4711a46f3364fd702877af06f1 sim/testsuite/d30v-elf/em-e47.S +b4367cba1f71ca0a8312a0e25b23d177 sim/testsuite/d30v-elf/em-pchr.S +254c18ad72c944ac250995ce33727a3a sim/testsuite/d30v-elf/em-pstr.S +66042f4711a46f3364fd702877af06f1 sim/testsuite/d30v-elf/exit47.s +a5c24af71ca0b23aac853ea351fb718e sim/testsuite/d30v-elf/hello.s +62e9cffcae3042316f06fb8345d3e8cf sim/testsuite/d30v-elf/loop.s +4d86df9cdd556650520fcb1f8222b5e8 sim/testsuite/d30v-elf/ls-ld2h.S +34a9e7d3b3a4597adafb1065dcdf54bd sim/testsuite/d30v-elf/ls-ld2w.S +027ffff597b497bb8abc27a21e803f89 sim/testsuite/d30v-elf/ls-ld4bh.S +f1c094e548e36239d8ee237be49d6ef1 sim/testsuite/d30v-elf/ls-ld4bhu.S +b663a826ece0596f78181872c56c3c6e sim/testsuite/d30v-elf/ls-ldb.S +536f7ad39f43f6445aeb2f38700857bd sim/testsuite/d30v-elf/ls-ldbu.S +156bf757165f4ca6c2ab93dbca420c5d sim/testsuite/d30v-elf/ls-ldh.S +62c29bd7f7e51bcd18abcf37be94afb4 sim/testsuite/d30v-elf/ls-ldhh.S +30156d1558f7eedd2c0fc05b1a9a6715 sim/testsuite/d30v-elf/ls-ldhu.S +45409a30148cbc3b8e3ec6d053d9c80a sim/testsuite/d30v-elf/ls-ldw.S +147fce0ff6b95d97af80b1c4d676dd3b sim/testsuite/d30v-elf/ls-modaddr.S +e5e9bd185eb0debe74944abf679c172c sim/testsuite/d30v-elf/ls-moddec.S +99e98e937cec5ac83e337ad8a789d0d1 sim/testsuite/d30v-elf/ls-modinc.S +f4741aadd909e9ad323682bcf964e9fe sim/testsuite/d30v-elf/ls-st2h.S +d435cc05cbd9c228a8c170ba64c8fb77 sim/testsuite/d30v-elf/ls-st2w.S +d553332d34db320891f8b982d8aca88f sim/testsuite/d30v-elf/ls-st4hb.S +000107339afefa58336120a39570555a sim/testsuite/d30v-elf/ls-stb.S +1ee1036a06d0b97ca340e25224a98f9d sim/testsuite/d30v-elf/ls-sth.S +c6ee4e543628014104812e4daa3eb965 sim/testsuite/d30v-elf/ls-sthh.S +7f63c22821b1406c7505574fd3f6edb8 sim/testsuite/d30v-elf/ls-stw.S +5720eb7587f98e617d1080075104482b sim/testsuite/d30v-elf/os-dbt.S +d4a3477b80f59ab26730dc52cd482893 sim/testsuite/d30v-elf/tick.s +e8d6ffe1c8ded0f14bc6a7972b3ab68c sim/testsuite/d30v-elf/trap.S +5348180e030d01447f84b2e834599a56 sim/testsuite/fr30-elf/ChangeLog +6f86e172c388289a1e79c3e1cf0f8507 sim/testsuite/fr30-elf/Makefile.in +cd954db176c3c6c49d4c2ed079de0561 sim/testsuite/fr30-elf/configure +288bd7e91ed8182fa32d11f022d738dd sim/testsuite/fr30-elf/configure.in +1b9331844e5edb27a4681212f8a8373d sim/testsuite/fr30-elf/exit47.s +bba20ead85e5cedd8bf70c640d2968eb sim/testsuite/fr30-elf/hello.s +689fc85c7b927bf3ad2ac2f6cbfe2140 sim/testsuite/fr30-elf/loop.s +f7e8fed66f264a2e4fb14d106c435e57 sim/testsuite/frv-elf/ChangeLog +0b48ee82e4c413029db432faf43af83c sim/testsuite/frv-elf/Makefile.in +ad3cb74cb4f5e1145c323d436230b3f4 sim/testsuite/frv-elf/cache.s +9c6af644b654d2d888e103f33a52ce7b sim/testsuite/frv-elf/configure +288bd7e91ed8182fa32d11f022d738dd sim/testsuite/frv-elf/configure.in +70ca72190bc26acee97deb6d5974053f sim/testsuite/frv-elf/exit47.s +e30b4c8b1165f133ffd45b28034a33a7 sim/testsuite/frv-elf/grloop.s +cc16675e19f20d246b81ba1aa64e2c05 sim/testsuite/frv-elf/hello.s +02ebc2d23f1397660d56c21d6a0866c6 sim/testsuite/frv-elf/loop.s +7d589ac801d3f4bea4bbeaa863107860 sim/testsuite/lib/sim-defs.exp +ed9984b92a4b91f7231f26675b5270d4 sim/testsuite/m32r-elf/ChangeLog +f606ee0a98576833f097c79fec2994a7 sim/testsuite/m32r-elf/Makefile.in +cd954db176c3c6c49d4c2ed079de0561 sim/testsuite/m32r-elf/configure +288bd7e91ed8182fa32d11f022d738dd sim/testsuite/m32r-elf/configure.in +fdcd1bf835b2c2a0ce2ec539624e2a6c sim/testsuite/m32r-elf/exit47.s +d855cd1f7a63aa5913126e4c9cbbdca4 sim/testsuite/m32r-elf/hello.s +61aac381a61d722e21e84faa6146d7be sim/testsuite/m32r-elf/loop.s +58dff76723704b72ace4023caa129a54 sim/testsuite/mips64el-elf/ChangeLog +8e706361883bd83f8d6746f201595a45 sim/testsuite/mips64el-elf/Makefile.in +bff3eea383aaf966899c9d6ff0410fec sim/testsuite/mips64el-elf/configure +288bd7e91ed8182fa32d11f022d738dd sim/testsuite/mips64el-elf/configure.in +5477dc224f249d5d847bb14b5809df81 sim/testsuite/sim/arm/adc.cgs +1c290ff406eb9de96060785ccfb36a33 sim/testsuite/sim/arm/add.cgs +a3aa42f1d4d1630a0f42c3e640f6ee0d sim/testsuite/sim/arm/allinsn.exp +58ac8d4d5ea2fe8c946251b4592629c6 sim/testsuite/sim/arm/and.cgs +99933c6f18e0fe8c3cbfeea3222bc270 sim/testsuite/sim/arm/b.cgs +8e130c393453b06b0c4f168915320147 sim/testsuite/sim/arm/bic.cgs +d3676059d440e43421abe9377b45644e sim/testsuite/sim/arm/bl.cgs +d8cbbc37fbab2579e37ca9ed2c82d6e3 sim/testsuite/sim/arm/bx.cgs +d80faf2d614f5b40636508bb03f723ff sim/testsuite/sim/arm/cmn.cgs +514c9855ea49dbd189076992160d290a sim/testsuite/sim/arm/cmp.cgs +5b1a485b23f4ada997bc9c482f4b142d sim/testsuite/sim/arm/eor.cgs +e7ed4d8b65d61b3addaa13b237d5d630 sim/testsuite/sim/arm/hello.ms +7b279b86516c39f3610fd701192e55da sim/testsuite/sim/arm/ldm.cgs +93e27d311dd9c978b5fd3238d8a96ff7 sim/testsuite/sim/arm/ldr.cgs +2f129d54e1238525995fbb61345511b6 sim/testsuite/sim/arm/ldrb.cgs +3d8cacbe82b517293ac2230f4947d142 sim/testsuite/sim/arm/ldrh.cgs +bef5c11ab14ef76a4adf86bdb29f3fa7 sim/testsuite/sim/arm/ldrsb.cgs +b70b6932231ba7b22b55aa6b0dabd2da sim/testsuite/sim/arm/ldrsh.cgs +248009f835f984c6659530b0d8ac3d6b sim/testsuite/sim/arm/misaligned1.ms +e094567de77b483869bfaa906a58c5f0 sim/testsuite/sim/arm/misaligned2.ms +61d1b5a430c450fa09d944dac4f6e9e9 sim/testsuite/sim/arm/misaligned3.ms +c0491db4475978a5556ce7e8d3940329 sim/testsuite/sim/arm/misc.exp +7c8eb7b1180e26892ff171384548e3df sim/testsuite/sim/arm/mla.cgs +cae028721a4860ba721bb0b6a45e28de sim/testsuite/sim/arm/mov.cgs +138b2c1c179325a81f413db374952dda sim/testsuite/sim/arm/mrs.cgs +5f5776bf35261a0924e7314d31bbec74 sim/testsuite/sim/arm/msr.cgs +0ad30943dc3310c090723d102d0c0c72 sim/testsuite/sim/arm/mul.cgs +28a00b5d6dacadae53e6f32c439dd867 sim/testsuite/sim/arm/mvn.cgs +e36fa83cfe6f8c23c2c4a874d15d6bb5 sim/testsuite/sim/arm/orr.cgs +0b54dec83ea8c2148335d0c9411f827a sim/testsuite/sim/arm/rsb.cgs +2db4b0c1e930d96e870724d2ecb71ec1 sim/testsuite/sim/arm/rsc.cgs +24953ef6d2f93fbc574722cfeb6f0508 sim/testsuite/sim/arm/sbc.cgs +424eae0aeb212b99a0423296d92432f9 sim/testsuite/sim/arm/smlal.cgs +5daa27aad0853ba541927ca858d54e0e sim/testsuite/sim/arm/smull.cgs +7caaf16bdd001c1cfdc6d204be0595d5 sim/testsuite/sim/arm/stm.cgs +510262d467a1cf529e9ebf863f5510bc sim/testsuite/sim/arm/str.cgs +bb3da4ab25011ccabcc1c8437f907d7d sim/testsuite/sim/arm/strb.cgs +982a00c19684480239a8d14ca04bd9e5 sim/testsuite/sim/arm/strh.cgs +1be7d9195c233759510ea7aea222287f sim/testsuite/sim/arm/sub.cgs +7853156003daa0909a44ee8c2b159869 sim/testsuite/sim/arm/swi.cgs +05ae9969a70c8f236c50630fd2f7d113 sim/testsuite/sim/arm/swp.cgs +f38f5ed68bbf76a6bb802723f8e111ac sim/testsuite/sim/arm/swpb.cgs +2f52c300639b0dccd15ed3b15bf2949b sim/testsuite/sim/arm/teq.cgs +f0a99de3c5c47c3aa91c95c25879b41f sim/testsuite/sim/arm/testutils.inc +853c04dea43ce219f8fbb2d4dda8f96c sim/testsuite/sim/arm/tst.cgs +a06bb01624f0127d797df273c0f0ae39 sim/testsuite/sim/arm/umlal.cgs +da2138a738648ab058990d5e495fb407 sim/testsuite/sim/arm/umull.cgs +fff690cc3c0b4cab7f417d747f0b6274 sim/testsuite/sim/arm/iwmmxt/iwmmxt.exp +cb91cfc8d87632674bb08655b37257af sim/testsuite/sim/arm/iwmmxt/tbcst.cgs +f0a99de3c5c47c3aa91c95c25879b41f sim/testsuite/sim/arm/iwmmxt/testutils.inc +fd328a7cecef16b062706133bd86a185 sim/testsuite/sim/arm/iwmmxt/textrm.cgs +676c13c4e65bd1da95adcdacc048ee0d sim/testsuite/sim/arm/iwmmxt/tinsr.cgs +27a5dff0fce99446ea9b92149fd87aad sim/testsuite/sim/arm/iwmmxt/tmia.cgs +b87db8b330bbfc39e8cc5c193bfd6752 sim/testsuite/sim/arm/iwmmxt/tmiaph.cgs +7f91c1c6ee07a5fa069f79687e6d3b18 sim/testsuite/sim/arm/iwmmxt/tmiaxy.cgs +e3314ba0fb5456272846893666ca6076 sim/testsuite/sim/arm/iwmmxt/tmovmsk.cgs +7a8797138da5f79dd25a529ca6aafda9 sim/testsuite/sim/arm/iwmmxt/wacc.cgs +aade4be67b5af16a82727edd01ff01a5 sim/testsuite/sim/arm/iwmmxt/wadd.cgs +88c71104de87e83e76badb90eee05b15 sim/testsuite/sim/arm/iwmmxt/waligni.cgs +e40211a7420484d7931c301a38d87629 sim/testsuite/sim/arm/iwmmxt/walignr.cgs +6f34dbce9217355b0034e980065123b2 sim/testsuite/sim/arm/iwmmxt/wand.cgs +1eeac0b2b5efecd25602ca32932a301e sim/testsuite/sim/arm/iwmmxt/wandn.cgs +b468e9e418a1e1a91063cde9f01a5b65 sim/testsuite/sim/arm/iwmmxt/wavg2.cgs +23189fcb39a2352d1f2aebd9fa472b86 sim/testsuite/sim/arm/iwmmxt/wcmpeq.cgs +ade7f421e7229ac22b99232d633506d8 sim/testsuite/sim/arm/iwmmxt/wcmpgt.cgs +f0f803cfe86027c9376da8bd15d603dc sim/testsuite/sim/arm/iwmmxt/wmac.cgs +bf292aeb577d786f1a5d93be72786c39 sim/testsuite/sim/arm/iwmmxt/wmadd.cgs +3d4113ef895254186382634bb9654300 sim/testsuite/sim/arm/iwmmxt/wmax.cgs +154a974a65e03d5b99e084a97aae5048 sim/testsuite/sim/arm/iwmmxt/wmin.cgs +7f2e2adae5b6face7645ef4d178af158 sim/testsuite/sim/arm/iwmmxt/wmov.cgs +7155fabca12e398a7ae30604e6010df6 sim/testsuite/sim/arm/iwmmxt/wmul.cgs +d3866e29becc0eb004bf50d7adcf21bc sim/testsuite/sim/arm/iwmmxt/wor.cgs +7cbe9df76667e549020ee9154febcb84 sim/testsuite/sim/arm/iwmmxt/wpack.cgs +da03e694abbabd2571357cc9ed058c70 sim/testsuite/sim/arm/iwmmxt/wror.cgs +81f8cb5a71451f972f4e040b980f6606 sim/testsuite/sim/arm/iwmmxt/wsad.cgs +538bf57041e5e509121767d9ead1147e sim/testsuite/sim/arm/iwmmxt/wshufh.cgs +182edb4dbe3c5f16e8bbc90c344f5958 sim/testsuite/sim/arm/iwmmxt/wsll.cgs +648dcf66cfd2ce5849d2cbb42c74e3ef sim/testsuite/sim/arm/iwmmxt/wsra.cgs +372409901bb2e34b4370c142151e635c sim/testsuite/sim/arm/iwmmxt/wsrl.cgs +b759e1c2be6dc0fb3b9656e41302b73c sim/testsuite/sim/arm/iwmmxt/wsub.cgs +966e30e2028caa8495f566e530a4e4d2 sim/testsuite/sim/arm/iwmmxt/wunpckeh.cgs +33dad8b13e3c06ffd72fefbae3ae328c sim/testsuite/sim/arm/iwmmxt/wunpckel.cgs +2ece72d7f9fed70851599aeafeb8fd75 sim/testsuite/sim/arm/iwmmxt/wunpckih.cgs +d4cf1dd1687b956976c326aa10e0da93 sim/testsuite/sim/arm/iwmmxt/wunpckil.cgs +37722d747ac7f2623a99bd2d5d04c319 sim/testsuite/sim/arm/iwmmxt/wxor.cgs +7f8a6603491a9bdea9261b3aefecd67a sim/testsuite/sim/arm/iwmmxt/wzero.cgs +f39dfdec26af7f089c85d0156d96f853 sim/testsuite/sim/arm/thumb/adc.cgs +a3a364cbdc5b492650e011da6f9c6de2 sim/testsuite/sim/arm/thumb/add-hd-hs.cgs +0c8a4f0432c4d3abeea38a2f31a8fed2 sim/testsuite/sim/arm/thumb/add-hd-rs.cgs +65de2dbbc1d1963e22a7ed146018c9cf sim/testsuite/sim/arm/thumb/add-rd-hs.cgs +3b1245f3b53f4f2fd1788169d9d1e5a5 sim/testsuite/sim/arm/thumb/add-sp.cgs +44fc3fa4d4212c68997074146cd2081d sim/testsuite/sim/arm/thumb/add.cgs +34994f81445d814b87b6aebce14a53c9 sim/testsuite/sim/arm/thumb/addi.cgs +d9a906c124e9554e0980cc53b336b377 sim/testsuite/sim/arm/thumb/addi8.cgs +7fecc3e47bed5457f394e92e9c496247 sim/testsuite/sim/arm/thumb/allthumb.exp +995d38ff3ed038c4f5cbcad2d78e0207 sim/testsuite/sim/arm/thumb/and.cgs +a1eda67b5040ebb08367e07d0624ee8a sim/testsuite/sim/arm/thumb/asr.cgs +4dd23bc630fc11c4eca7cbea9fc36231 sim/testsuite/sim/arm/thumb/b.cgs +05d4b004a36c86c46a3ba8f3a485c488 sim/testsuite/sim/arm/thumb/bcc.cgs +9679a91ccf07238a1c0161cde847fe85 sim/testsuite/sim/arm/thumb/bcs.cgs +e162af7a697a2fa2e10ecc1a56b45be1 sim/testsuite/sim/arm/thumb/beq.cgs +359c1c1f673e082a73606aea537c22ce sim/testsuite/sim/arm/thumb/bge.cgs +cc9025ac9679ebfbd9e3fc340edbc697 sim/testsuite/sim/arm/thumb/bgt.cgs +244babd31dcba228ef3637cbcca9c16b sim/testsuite/sim/arm/thumb/bhi.cgs +4a2f10cac1edd904293441d716cad0f1 sim/testsuite/sim/arm/thumb/bic.cgs +6ed6d54faafbb0319c1604112b0c16c4 sim/testsuite/sim/arm/thumb/bl-hi.cgs +a8c07a4b4764c4cc4c88cd2633394160 sim/testsuite/sim/arm/thumb/bl-lo.cgs +f25edf66e54fa2c53957abc6aa807d00 sim/testsuite/sim/arm/thumb/ble.cgs +ead31b659b0f0e78ca8054010fc195a9 sim/testsuite/sim/arm/thumb/bls.cgs +b1866a0b3f4e1244f6f32c7890b4623f sim/testsuite/sim/arm/thumb/blt.cgs +ec7f950054226d26fe7c00da759b2c4e sim/testsuite/sim/arm/thumb/bmi.cgs +5ae8870812f676720ebfc69b48c04ebb sim/testsuite/sim/arm/thumb/bne.cgs +03a9889899898201a14082970138178d sim/testsuite/sim/arm/thumb/bpl.cgs +cd68a29c2b8bdaf0c8aed77438819e18 sim/testsuite/sim/arm/thumb/bvc.cgs +5ea6bc2fd59bbd0f3a4bd46fd117a8be sim/testsuite/sim/arm/thumb/bvs.cgs +fcaed4c8608ce095dc4625f37383b515 sim/testsuite/sim/arm/thumb/bx-hs.cgs +23d58ec2e23ff3bed4784642cc48aa06 sim/testsuite/sim/arm/thumb/bx-rs.cgs +2588c865bab15990f4bd3546b3d82fe7 sim/testsuite/sim/arm/thumb/cmn.cgs +189891b42b0a10d5895c36ed13267a7e sim/testsuite/sim/arm/thumb/cmp-hd-hs.cgs +6c4154b82d1b8a3579a0f42b4142aad5 sim/testsuite/sim/arm/thumb/cmp-hd-rs.cgs +bc1c96814fecd239a7955bc76320fae5 sim/testsuite/sim/arm/thumb/cmp-rd-hs.cgs +9e9f7b260681e86c6c0b7e0006cd2154 sim/testsuite/sim/arm/thumb/cmp.cgs +b44832f5d79102e7efeee45f69462a66 sim/testsuite/sim/arm/thumb/eor.cgs +7bceba1198328ea2930942d76eca4da4 sim/testsuite/sim/arm/thumb/lda-pc.cgs +b0b760fd79039fbf1125dc0a526be229 sim/testsuite/sim/arm/thumb/lda-sp.cgs +a25b0fe3d7a82e5a2f7605f685e15f46 sim/testsuite/sim/arm/thumb/ldmia.cgs +3896f647e72d591e262a40e5af29adf9 sim/testsuite/sim/arm/thumb/ldr-imm.cgs +f558e4e07d5886e42d8da753f5adc9c2 sim/testsuite/sim/arm/thumb/ldr-pc.cgs +c41ea1558f80aa2acb0eabcfda617729 sim/testsuite/sim/arm/thumb/ldr-sprel.cgs +4aebea08153a18c59cb89377cd0cd6e6 sim/testsuite/sim/arm/thumb/ldr.cgs +ed9f50e3848ffa46f1f6918df9be8d9e sim/testsuite/sim/arm/thumb/ldrb-imm.cgs +8575173ee07cb511f33d4ba01c67152a sim/testsuite/sim/arm/thumb/ldrb.cgs +4983cedc4b15f2b1ff5dec0e01ec8705 sim/testsuite/sim/arm/thumb/ldrh-imm.cgs +674db4c1215bd277651130d87a64a915 sim/testsuite/sim/arm/thumb/ldrh.cgs +91148c7f6657e7dd4e227a43f6ec7cfc sim/testsuite/sim/arm/thumb/ldsb.cgs +a2f21e7ede5faef4d9cee034a88928ae sim/testsuite/sim/arm/thumb/ldsh.cgs +0054af714a4db9a939abde5126dabe11 sim/testsuite/sim/arm/thumb/lsl.cgs +15cd5436a6e963ccd32b54e22c7a8b21 sim/testsuite/sim/arm/thumb/lsr.cgs +5e5452b3461b69cffd6b8f23f4e7140c sim/testsuite/sim/arm/thumb/mov-hd-hs.cgs +a11035d426ce96b9dd0c5b94664abcc1 sim/testsuite/sim/arm/thumb/mov-hd-rs.cgs +b4f45a3bb387a75a6db056bef516b07b sim/testsuite/sim/arm/thumb/mov-rd-hs.cgs +eb4d0f5b458b6c6e2a847d5c8673e3e6 sim/testsuite/sim/arm/thumb/mov.cgs +13116b55efce4632651233f650d7dc78 sim/testsuite/sim/arm/thumb/mul.cgs +70faca670e6c72adda93fb641c480b1f sim/testsuite/sim/arm/thumb/mvn.cgs +8bcf6d16383ab1c7ef09466857afbc37 sim/testsuite/sim/arm/thumb/neg.cgs +6cf3e8b7ef426b8914b47d8f7ec0a456 sim/testsuite/sim/arm/thumb/orr.cgs +0250cdbde1a106526ec9f3b4861b8d4a sim/testsuite/sim/arm/thumb/pop-pc.cgs +2f5ae83cda2f549b102b57569f78f8d9 sim/testsuite/sim/arm/thumb/pop.cgs +fa00d6fb1a2926732b0eb28ae0c77c47 sim/testsuite/sim/arm/thumb/push-lr.cgs +6656596a7ff9c3b412deae76b7e38624 sim/testsuite/sim/arm/thumb/push.cgs +8c2c133f6c72015561ac976d7438ebe9 sim/testsuite/sim/arm/thumb/ror.cgs +56f88f8627fec54cd96656de2828c1f2 sim/testsuite/sim/arm/thumb/sbc.cgs +e89c8dd1ff6ae4faa4b4dff6b626a850 sim/testsuite/sim/arm/thumb/stmia.cgs +1d8dd64ff6c23b570bbaa4d7afff968e sim/testsuite/sim/arm/thumb/str-imm.cgs +c5c60347531697a069a2800842ee3902 sim/testsuite/sim/arm/thumb/str-sprel.cgs +f9d716a1d842d091c8ed298f1b5b1ae9 sim/testsuite/sim/arm/thumb/str.cgs +06e7eb2e9fd2173cafaaf5cbd62eac9b sim/testsuite/sim/arm/thumb/strb-imm.cgs +10371b41438911cf843b9cec25c67e1d sim/testsuite/sim/arm/thumb/strb.cgs +ca60a519f04c50e1e8b316b49a7e4e9d sim/testsuite/sim/arm/thumb/strh-imm.cgs +62c721a2ca73cdae002eba9841199014 sim/testsuite/sim/arm/thumb/strh.cgs +c1a57f0215877e8992c61e54d2446278 sim/testsuite/sim/arm/thumb/sub-sp.cgs +acb920479677a598ba5544db15addd06 sim/testsuite/sim/arm/thumb/sub.cgs +1e72cd9a9e01d015ac44deadf9a8eb0d sim/testsuite/sim/arm/thumb/subi.cgs +4ed486b285f8dd6272168154f0e7df58 sim/testsuite/sim/arm/thumb/subi8.cgs +84459a09af60b4a3de23776a8bf0adcc sim/testsuite/sim/arm/thumb/swi.cgs +93c6ea09186e29b651ae931a0ba07760 sim/testsuite/sim/arm/thumb/testutils.inc +c45fc39f2f692299fe4bf891668833d8 sim/testsuite/sim/arm/thumb/tst.cgs +f2c30ed356d350356f1edcb1484c6f57 sim/testsuite/sim/arm/xscale/blx.cgs +64304cffe7caf82616cedaf41498ac45 sim/testsuite/sim/arm/xscale/mia.cgs +03c925a228ba4258f15e01eef3fceb5b sim/testsuite/sim/arm/xscale/miaph.cgs +ff267c0f1ed5b05d883ec3584f8bb6f9 sim/testsuite/sim/arm/xscale/miaxy.cgs +0a98c2c1558ae770328e84c180ac3616 sim/testsuite/sim/arm/xscale/mra.cgs +f0a99de3c5c47c3aa91c95c25879b41f sim/testsuite/sim/arm/xscale/testutils.inc +c041e18e1c56fcb743b7e2c2d8ca5ec5 sim/testsuite/sim/arm/xscale/xscale.exp +503d6096668d67d46c257e7895d84d31 sim/testsuite/sim/fr30/add.cgs +692e2c452c77ecbc6b74405fbfb8764f sim/testsuite/sim/fr30/add.ms +726473e3a587a7dc454557dc8b4c43db sim/testsuite/sim/fr30/add2.cgs +ae7aebd1064ea16900d3b009feddd60d sim/testsuite/sim/fr30/addc.cgs +9d0cb44436f746f3c9888587a0705941 sim/testsuite/sim/fr30/addn.cgs +030942418ed8e981370a1d4e1489b9b2 sim/testsuite/sim/fr30/addn2.cgs +8f9d88e4c545aca64898cbd90c3d16a4 sim/testsuite/sim/fr30/addsp.cgs +78fc35acbc4a167797bd863fd991a785 sim/testsuite/sim/fr30/allinsn.exp +8987709e3323037c23eb5559a2a05b79 sim/testsuite/sim/fr30/and.cgs +5948be319fc5808a6b19793d9e5bbc7d sim/testsuite/sim/fr30/andb.cgs +85c3eb5c04a5558fa911df3e30e3679b sim/testsuite/sim/fr30/andccr.cgs +d33f46c321f6a6972442f4bade06656a sim/testsuite/sim/fr30/andh.cgs +3daf2597d21b8195e0c0a1650be412df sim/testsuite/sim/fr30/asr.cgs +6cc8644c6594267688e0cfa178a7bd73 sim/testsuite/sim/fr30/asr2.cgs +63da4dc66d15a7647a2b0612f35a8564 sim/testsuite/sim/fr30/bandh.cgs +3838077d837c2b8656d8a398cbf96482 sim/testsuite/sim/fr30/bandl.cgs +c2961d1998d0f226e73fb2f0c8b37746 sim/testsuite/sim/fr30/bc.cgs +fd0034e39e50a5ad93071dbc6718e3b6 sim/testsuite/sim/fr30/beorh.cgs +0c254917d1438ef4f7cb6dbd5683cf75 sim/testsuite/sim/fr30/beorl.cgs +e76365e82b93ee554e15a75585b0c27c sim/testsuite/sim/fr30/beq.cgs +528b0bd224d9631b14de438842a363c4 sim/testsuite/sim/fr30/bge.cgs +8656edc8211fb004093f703158a7c9ee sim/testsuite/sim/fr30/bgt.cgs +29f7caeaad4350f3f89236f16849b148 sim/testsuite/sim/fr30/bhi.cgs +825b7df0d31175f17fb30a27a90d6f05 sim/testsuite/sim/fr30/ble.cgs +fa428bc4576d35a4d06fe83db66f1e20 sim/testsuite/sim/fr30/bls.cgs +107058d96ac7c888d901300eb006d5c3 sim/testsuite/sim/fr30/blt.cgs +11ca26e18c1fa7c05d9980f28911fc84 sim/testsuite/sim/fr30/bn.cgs +f419d8740920121331afb15e71725c80 sim/testsuite/sim/fr30/bnc.cgs +b4e156196e642664ce263f393a7f53be sim/testsuite/sim/fr30/bne.cgs +78f28bc2aa59a4a6dc4cdd7971e98108 sim/testsuite/sim/fr30/bno.cgs +00ced4e4a8d48e061be334729bcf9972 sim/testsuite/sim/fr30/bnv.cgs +93d8f4110bc336023847d2e425d27fac sim/testsuite/sim/fr30/borh.cgs +51632bbf7fcc2d274e4b7d4ee75b9786 sim/testsuite/sim/fr30/borl.cgs +5f0977ee9d55754ffceaf3dc2242781d sim/testsuite/sim/fr30/bp.cgs +118242b7ecdaa35cdce8a8504e75b4be sim/testsuite/sim/fr30/bra.cgs +50c15ddbc5bfffd5f9b4784313984dd1 sim/testsuite/sim/fr30/btsth.cgs +c0e8ab52947ed9bccc6646be37f2b82e sim/testsuite/sim/fr30/btstl.cgs +b3436c5fa08665c3fd9b9d103bbfd4ca sim/testsuite/sim/fr30/bv.cgs +1fb7a6a1cbbdff7ba6882c47dc8b3071 sim/testsuite/sim/fr30/call.cgs +d5c3720a8d9a8fa88fb45d97681466d2 sim/testsuite/sim/fr30/cmp.cgs +5fc1b6eee6a98d786ad146de39bee17e sim/testsuite/sim/fr30/cmp2.cgs +92b6ed80cfaf734393514a354f558e12 sim/testsuite/sim/fr30/copld.cgs +68e0c1e7bd73024e03d90e17d1b479e7 sim/testsuite/sim/fr30/copop.cgs +d82e1c778335479eb3257be5f4027f60 sim/testsuite/sim/fr30/copst.cgs +8f3d3ac55197c8d27a1bb6022ce7ab9c sim/testsuite/sim/fr30/copsv.cgs +1986f8b31251f3fcfead747f2fbc2067 sim/testsuite/sim/fr30/div.ms +8bca5d07304281074232cf501f58d578 sim/testsuite/sim/fr30/div0s.cgs +9497d9229865b30c86f4e77508a9a406 sim/testsuite/sim/fr30/div0u.cgs +42628131079d04c855f5e218a162c210 sim/testsuite/sim/fr30/div1.cgs +2d45aaaebfe96a478d94442f475255dd sim/testsuite/sim/fr30/div2.cgs +82b175871b9a3802f2b0141fdbd69314 sim/testsuite/sim/fr30/div3.cgs +2ae5a90062cafe57f759112f5b2f3b06 sim/testsuite/sim/fr30/div4s.cgs +18a90aaef63c891698afe734d2152d18 sim/testsuite/sim/fr30/dmov.cgs +55b2418400196e2f3a85b8e6b696a252 sim/testsuite/sim/fr30/dmovb.cgs +1a350c8e3f57a176585fc796b07bfc7d sim/testsuite/sim/fr30/dmovh.cgs +1df39f183df8aeeb7fa41d92384a0ad9 sim/testsuite/sim/fr30/enter.cgs +bc265d868045395c100b7c74d441979a sim/testsuite/sim/fr30/eor.cgs +63ca215997d767d234ca89fcd3e11968 sim/testsuite/sim/fr30/eorb.cgs +9f77138b83e182472a14212e5bb72352 sim/testsuite/sim/fr30/eorh.cgs +67ece84ba59ec30e07e99a8dfb888f56 sim/testsuite/sim/fr30/extsb.cgs +98f0923dc897604e64e47dd027c2fab1 sim/testsuite/sim/fr30/extsh.cgs +006acd8b3fbfdfdc9cf751d3551da65b sim/testsuite/sim/fr30/extub.cgs +6b9b96096efcac0f5ee86ff1b1327da4 sim/testsuite/sim/fr30/extuh.cgs +76cd07dd7c78722fbbfa49bd94b5c61b sim/testsuite/sim/fr30/hello.ms +a447d626d0829c31c4cc72b9aca610bc sim/testsuite/sim/fr30/int.cgs +c7f3e31654d7134dfec197a23c612f8d sim/testsuite/sim/fr30/inte.cgs +a92cc956b699bbdead9c1e8ea21b7d85 sim/testsuite/sim/fr30/jmp.cgs +bd02ed7b7c8470f6853a555a57818cb3 sim/testsuite/sim/fr30/ld.cgs +d9bcff3a1f3a6885615cb81215deb73d sim/testsuite/sim/fr30/ldi20.cgs +5c29b0babb4c478e18950a01250bacdf sim/testsuite/sim/fr30/ldi32.cgs +05c014e0472c8041119ea95bda37df65 sim/testsuite/sim/fr30/ldi8.cgs +291df7a8065e554654d635d4319a6e07 sim/testsuite/sim/fr30/ldm0.cgs +40b06cc66fd096915a199de617efa043 sim/testsuite/sim/fr30/ldm1.cgs +980de17f49e0206c409122a710bd9660 sim/testsuite/sim/fr30/ldres.cgs +cd540be2b820c7304d49a2cd4c804ebc sim/testsuite/sim/fr30/ldub.cgs +7f827594dfa2a9ea9cbdb822808bb96e sim/testsuite/sim/fr30/lduh.cgs +f4b6c297ead375254a31836c88c758db sim/testsuite/sim/fr30/leave.cgs +ff01a6642b097f295e29b8aad506bf20 sim/testsuite/sim/fr30/lsl.cgs +e5b073abade7a63209ab21e8757714e5 sim/testsuite/sim/fr30/lsl2.cgs +fac808112158b0d7c9a972b5c1e51ad9 sim/testsuite/sim/fr30/lsr.cgs +8fb50d3723a8e4fda2cca68f8138fc68 sim/testsuite/sim/fr30/lsr2.cgs +58553f1bced962c2d9f26ff2f53aecfc sim/testsuite/sim/fr30/misc.exp +cd116a2a1dac5e397ecc2f7456053564 sim/testsuite/sim/fr30/mov.cgs +e6e56816b0dcb650c26b46a33cb1ffac sim/testsuite/sim/fr30/mul.cgs +4e62467dd71697f7cf6d64cebf2531e8 sim/testsuite/sim/fr30/mulh.cgs +201ea7a49f59a0a5e628e9b549bfb5b8 sim/testsuite/sim/fr30/mulu.cgs +ee0c0d6979b1682c427b387664c204a8 sim/testsuite/sim/fr30/muluh.cgs +68d1886400abacb8a7f24d72bda2a966 sim/testsuite/sim/fr30/nop.cgs +c8347c5b0effef1e42f0249483e5ac6a sim/testsuite/sim/fr30/or.cgs +2cf5b46fe78a0e966c03c134642e61c6 sim/testsuite/sim/fr30/orb.cgs +d01fa8a22cb8df995a868145d71bbf94 sim/testsuite/sim/fr30/orccr.cgs +8557874b84d96137c9d2163f29a20473 sim/testsuite/sim/fr30/orh.cgs +89bf2353814e13f2d5a94d209ace80f3 sim/testsuite/sim/fr30/ret.cgs +16372b76ce969bd0041202b277ab1aae sim/testsuite/sim/fr30/reti.cgs +ae8fa268a41ffb274a7a89b9f7344ac3 sim/testsuite/sim/fr30/st.cgs +6c4bf429941803c250acd9ed35221ec8 sim/testsuite/sim/fr30/stb.cgs +32b42ce0a2b13161bf8e4d8cab413410 sim/testsuite/sim/fr30/sth.cgs +5e026ff1027b8aa7cb374c51b5c4b9e8 sim/testsuite/sim/fr30/stilm.cgs +fae958eef826c19e4e7640eb0378c0c9 sim/testsuite/sim/fr30/stm0.cgs +5f28ff21c8db4465c66df254b3a6d631 sim/testsuite/sim/fr30/stm1.cgs +546a174bd7aa7dfa4f54ba99e5b2d617 sim/testsuite/sim/fr30/stres.cgs +3ad5b0fdc53e83258fadc664f63c6a82 sim/testsuite/sim/fr30/sub.cgs +f32638a3919a1385e630a7e29518e0ed sim/testsuite/sim/fr30/subc.cgs +da584f1cf2dcd0f85046a64bc5d9ba5e sim/testsuite/sim/fr30/subn.cgs +c174cd3fd5b8667dbc7b7741ec7449e3 sim/testsuite/sim/fr30/testutils.inc +9d0e5f42019df498994f84948f9de403 sim/testsuite/sim/fr30/xchb.cgs +9f35e5c8475a3dce4d3d1f86192b757f sim/testsuite/sim/frv/add.cgs +24091903403ffb172b0b81cfbb3f331e sim/testsuite/sim/frv/add.pcgs +0328850bbb204540e39224902cea7437 sim/testsuite/sim/frv/addcc.cgs +1e7f2deead6fb5c78f146ae3eb2fc6be sim/testsuite/sim/frv/addi.cgs +30964df0b57f2b91f67fc38a30d8e814 sim/testsuite/sim/frv/addicc.cgs +d2ab686875a7fa6635f150cf02ff06f9 sim/testsuite/sim/frv/addx.cgs +0946412ade0a468bd29c482a88af3c60 sim/testsuite/sim/frv/addxcc.cgs +bb0118ec08792d6499ce7742161f206f sim/testsuite/sim/frv/addxi.cgs +02991b6e743da14fcd82acaa74ad2de3 sim/testsuite/sim/frv/addxicc.cgs +72be282014f29ceb549bafd72ca6590c sim/testsuite/sim/frv/allinsn.exp +fe0ecb3cd4f9a5a2a8cd1b994f8e8ae2 sim/testsuite/sim/frv/and.cgs +558c0693de0aa42e5ba756ef35228332 sim/testsuite/sim/frv/andcc.cgs +7436eebb11c6129d8a06aa52d0641d19 sim/testsuite/sim/frv/andcr.cgs +2fdea54dc1608b57111f0b1d657b3daa sim/testsuite/sim/frv/andi.cgs +54e056f54d116cde6e23ee7dee9a9c8b sim/testsuite/sim/frv/andicc.cgs +4a13d5d2947c3543c94581ba88ec7fc4 sim/testsuite/sim/frv/andncr.cgs +cf73edecc782c3ef0b7548f1acb34cd5 sim/testsuite/sim/frv/bar.cgs +b03ca91fbf4d98089e108f2fe411eecb sim/testsuite/sim/frv/bc.cgs +36d2a277daae79b65a1fe73b38c101ba sim/testsuite/sim/frv/bcclr.cgs +4fe0320394ce9fd521b0b903b37a44de sim/testsuite/sim/frv/bceqlr.cgs +17b1b6dc979b707b15d4d415b6a8c50a sim/testsuite/sim/frv/bcgelr.cgs +ad6bad34a15a4f2986566b50e2af52b8 sim/testsuite/sim/frv/bcgtlr.cgs +9b2a570d81405ae96edd05841a00340c sim/testsuite/sim/frv/bchilr.cgs +bd1949fa6a0cbbd0faee3d33a7d2ed7b sim/testsuite/sim/frv/bclelr.cgs +8a77e7659d777d6c0d67e89e341cf17c sim/testsuite/sim/frv/bclr.cgs +e3f8edcf3d2202102c308c006b574282 sim/testsuite/sim/frv/bclslr.cgs +73a5313d89e6d5975be48f3e2522c1a2 sim/testsuite/sim/frv/bcltlr.cgs +62439f50d31a64a7d77bfe8d242d68c2 sim/testsuite/sim/frv/bcnclr.cgs +45750ad0543745a1b21a7b795a774105 sim/testsuite/sim/frv/bcnelr.cgs +5032a5008a230358b8434e010fa7aa66 sim/testsuite/sim/frv/bcnlr.cgs +e9aafacc4f7c85928dd1c32c5c79fc5a sim/testsuite/sim/frv/bcnolr.cgs +b0d3f8840cbd815c5cf1fed7f60b95ac sim/testsuite/sim/frv/bcnvlr.cgs +34c1f1091b4c9bebc5fd6e10d045f570 sim/testsuite/sim/frv/bcplr.cgs +318cb22eb343ae2ba7c0a11ec86755f3 sim/testsuite/sim/frv/bcralr.cgs +93142a00f792c55ff26c67e4495c3ee8 sim/testsuite/sim/frv/bctrlr.cgs +37f80752cbc102b0e3eebab206a7e851 sim/testsuite/sim/frv/bcvlr.cgs +5f883fbcb2224a26bc0e0d7eb91fd2de sim/testsuite/sim/frv/beq.cgs +a49be0c11999c9c5fe7164a2d478236c sim/testsuite/sim/frv/beqlr.cgs +d2ca7d2383745ede57de7cf3a71b250b sim/testsuite/sim/frv/bge.cgs +0d8bd8099d69931cea52745c2fd79b8b sim/testsuite/sim/frv/bgelr.cgs +df584e46e6bbe3d1636c1fbaa73ca746 sim/testsuite/sim/frv/bgt.cgs +7e5adf4d17b96ce4a3b36beea51aadc6 sim/testsuite/sim/frv/bgtlr.cgs +894db98a371eaba135a686990f22f504 sim/testsuite/sim/frv/bhi.cgs +58728788baa01be3e6482ab14b5fde4f sim/testsuite/sim/frv/bhilr.cgs +3da93d4f6c18f18193c0441a79758bcc sim/testsuite/sim/frv/ble.cgs +e54bc9be577ed53f98a7256e02292a9f sim/testsuite/sim/frv/blelr.cgs +313bac7f8246cca4710202da37d93d37 sim/testsuite/sim/frv/bls.cgs +b04e822dac50d26e600e9af54cc86907 sim/testsuite/sim/frv/blslr.cgs +aeccfedc8dc931ff8b70da7c99c2236a sim/testsuite/sim/frv/blt.cgs +b32fc8a8e6bba1b163e798c7a6b2998a sim/testsuite/sim/frv/bltlr.cgs +851005c4ef6143a0dc488d4a100b97f7 sim/testsuite/sim/frv/bn.cgs +a26faa5267491071d341abedcc58aa36 sim/testsuite/sim/frv/bnc.cgs +f91ccc0eb4e839737d94f68601bf130f sim/testsuite/sim/frv/bnclr.cgs +8b544d33708f95c5fe86075bfc046ba3 sim/testsuite/sim/frv/bne.cgs +da1d1539bcb135ec8ce2fa2df168cd18 sim/testsuite/sim/frv/bnelr.cgs +31e7cd50ae42d84c7edbb16ec1824569 sim/testsuite/sim/frv/bnlr.cgs +3014022934a14b3431fdacf8e86dd3eb sim/testsuite/sim/frv/bno.cgs +8f07983738e8be6e8f294385e90a83f1 sim/testsuite/sim/frv/bnolr.cgs +480ed9fb8591ba5cba8c36bbf8fac25b sim/testsuite/sim/frv/bnv.cgs +078c55334418476eb782ff3b071fc106 sim/testsuite/sim/frv/bnvlr.cgs +6e0ed99106e53f1ae7c54bd6a15d2a7d sim/testsuite/sim/frv/bp.cgs +af01f45076997b2efc4cbed1bfbeb90f sim/testsuite/sim/frv/bplr.cgs +7d76bf8128cc9482f2de7d01e2bde23a sim/testsuite/sim/frv/bra.cgs +36ccbee5f8a7659d1403b57bda54a1cf sim/testsuite/sim/frv/bralr.cgs +1faedf52637eb93c36507f38fd31fea3 sim/testsuite/sim/frv/branch.pcgs +67b49f46f325d357092e83a5af86ffe8 sim/testsuite/sim/frv/break.cgs +9868adbc8297b59031bb110c1104e524 sim/testsuite/sim/frv/bv.cgs +1506bd2f46dbdf8b5580412cc36cc631 sim/testsuite/sim/frv/bvlr.cgs +54b2d852374130520e29e72dc46923e0 sim/testsuite/sim/frv/cadd.cgs +9ebd87890c8a7abc680822709889778c sim/testsuite/sim/frv/caddcc.cgs +36b77ec6afe8955468cfc59058d7e96a sim/testsuite/sim/frv/call.cgs +05a1ec4efd6909bce7ced2cff0a0d8c8 sim/testsuite/sim/frv/call.pcgs +6c696a162425d51ed1a198eadc9e8ec6 sim/testsuite/sim/frv/callil.cgs +5900af0d1f33281e6a8d166d3cabe74a sim/testsuite/sim/frv/calll.cgs +6833a0f9a6a97eca6ec71259ea075028 sim/testsuite/sim/frv/cand.cgs +35609b2536c1c21599e2d70a762854f6 sim/testsuite/sim/frv/candcc.cgs +794be640f3ea38845a7fb677c250fe48 sim/testsuite/sim/frv/ccalll.cgs +61d311d36b7dec576d8be1a6a047278d sim/testsuite/sim/frv/cckc.cgs +e7a1ad746f682025747fa48379b5db6f sim/testsuite/sim/frv/cckeq.cgs +21793c07586326f7d5b7caeb20faf21b sim/testsuite/sim/frv/cckge.cgs +511bee637d7a77e1f4ead6e790993d68 sim/testsuite/sim/frv/cckgt.cgs +ad7585e6f6dbc249f1e67deba9847034 sim/testsuite/sim/frv/cckhi.cgs +1f8696a6d62df0c7ee21c40e74d2af30 sim/testsuite/sim/frv/cckle.cgs +2974e1e8788d707888a2c3ff248a0d82 sim/testsuite/sim/frv/cckls.cgs +5393775815f48e4a5a811b3a06ff8503 sim/testsuite/sim/frv/ccklt.cgs +91e3dc0afab2fdfca7731c7e1f37e33f sim/testsuite/sim/frv/cckn.cgs +a659a5c06a90b61548ad0d23636f740b sim/testsuite/sim/frv/ccknc.cgs +40115dcc72d0b6f1b5b4701a63e94c83 sim/testsuite/sim/frv/cckne.cgs +da2ea0628931ee759747b3b1568f9e95 sim/testsuite/sim/frv/cckno.cgs +1516ca30ed3dda235da364d46c38d2a1 sim/testsuite/sim/frv/ccknv.cgs +dd7b86dd559bc919891c419cc5b9eb45 sim/testsuite/sim/frv/cckp.cgs +b0b3ba45dce79cce5d0db607ed12fbfe sim/testsuite/sim/frv/cckra.cgs +0c3aa7b3b5fd1c05678011c190e83144 sim/testsuite/sim/frv/cckv.cgs +999bafc99f41d16b6bd3b925cf296de0 sim/testsuite/sim/frv/ccmp.cgs +ffdac6d343d018ba34d4952027680104 sim/testsuite/sim/frv/cfabss.cgs +7b8111a1958ac7ac0609e3ec19946402 sim/testsuite/sim/frv/cfadds.cgs +a557f55cfe20662991a594673e5a877b sim/testsuite/sim/frv/cfckeq.cgs +ccbed047cb7e704f8caefbf30b21d58e sim/testsuite/sim/frv/cfckge.cgs +7b350a57e6efb69056eeffc36aa0cac4 sim/testsuite/sim/frv/cfckgt.cgs +34a484991db89cb85939b4735fd01d7d sim/testsuite/sim/frv/cfckle.cgs +055fa9b5ef1f3c1f955737457b0f3430 sim/testsuite/sim/frv/cfcklg.cgs +c3fbed74046a3c4d5d74af309a283001 sim/testsuite/sim/frv/cfcklt.cgs +42256da6637466abfe0f07b1103c7139 sim/testsuite/sim/frv/cfckne.cgs +bff6dd1636bea003ff556d16f1e3f843 sim/testsuite/sim/frv/cfckno.cgs +d8c97eebc3c3db0b2962b1d7181cc6c6 sim/testsuite/sim/frv/cfcko.cgs +124ee6149a335aca9a615e6e9e9521ff sim/testsuite/sim/frv/cfckra.cgs +6dd0a3407bccbe944de3004234e1ee11 sim/testsuite/sim/frv/cfcku.cgs +d0ac23eed64316704af3b22028e3e476 sim/testsuite/sim/frv/cfckue.cgs +506b3aaeb2f55f7313b18756c9ea8897 sim/testsuite/sim/frv/cfckug.cgs +c0d65d42e391ceb55e2d6eed4954f643 sim/testsuite/sim/frv/cfckuge.cgs +2dce4079bac9e873cc2f7466bbdbc0bd sim/testsuite/sim/frv/cfckul.cgs +697ec5d0eb83f0aa0c438264e7dacf74 sim/testsuite/sim/frv/cfckule.cgs +4ae9085c410dd43f5a03a680a8ef06f0 sim/testsuite/sim/frv/cfcmps.cgs +255041537a2ba5cddbc94a66463c52ab sim/testsuite/sim/frv/cfdivs.cgs +d8e85f1e2dfaa87480b812c7c03ee19b sim/testsuite/sim/frv/cfitos.cgs +241fa1bef3f4eb4e60aebeaa3a5e5d8e sim/testsuite/sim/frv/cfmadds.cgs +4fa1060d3ea708c05623eaa8fa23a4fd sim/testsuite/sim/frv/cfmas.cgs +b69a810fc6f3f907c57797a5721333fd sim/testsuite/sim/frv/cfmovs.cgs +258db7edbd93cc7f09cde29e3522194e sim/testsuite/sim/frv/cfmss.cgs +8efb2a5d93915406532ba43d46c08545 sim/testsuite/sim/frv/cfmsubs.cgs +ccde36a3a60f282ea7e7581d6ddbe200 sim/testsuite/sim/frv/cfmuls.cgs +0eb9d6f24940fa1b3a290ee7f83529e6 sim/testsuite/sim/frv/cfnegs.cgs +e6cce9c3b04ed7fd801dafb45bcdd866 sim/testsuite/sim/frv/cfsqrts.cgs +654e92ca5c279eff83c44a07b5a4f8bd sim/testsuite/sim/frv/cfstoi.cgs +d6e2c99d07b9c1a5fb5869dd9aecc1a4 sim/testsuite/sim/frv/cfsubs.cgs +11bfcfb4b6f70c5075adaa4f37dca943 sim/testsuite/sim/frv/cjmpl.cgs +e3edb4635dd416fa50ea0e1628a69aea sim/testsuite/sim/frv/ckc.cgs +bd306d227534038e358e212748f86d46 sim/testsuite/sim/frv/ckeq.cgs +6829b406203cc09d6ac699fec2378bad sim/testsuite/sim/frv/ckge.cgs +c32d71a426bc21b198975069f0bc3503 sim/testsuite/sim/frv/ckgt.cgs +8496d10703a6df931f2b4ea768c69356 sim/testsuite/sim/frv/ckhi.cgs +5efca9c9c6f6785859bd2ed1ab619325 sim/testsuite/sim/frv/ckle.cgs +2f2d7f51d4276d8bc6c7a559cf40358f sim/testsuite/sim/frv/ckls.cgs +325a426583fc25d49f02863c763aeb84 sim/testsuite/sim/frv/cklt.cgs +5724440a0342cfb9923003f93f4e9c28 sim/testsuite/sim/frv/ckn.cgs +b0fa5261302915fed6a0abb4165bdb3e sim/testsuite/sim/frv/cknc.cgs +2377457fe2384816953905fda6c3d04b sim/testsuite/sim/frv/ckne.cgs +1cbff10c95fb9390a7cc4d56fef5f794 sim/testsuite/sim/frv/ckno.cgs +ad9476d15f761b15a7243c9030efa135 sim/testsuite/sim/frv/cknv.cgs +6b8470231d2eb04c58135b6a02fd63cb sim/testsuite/sim/frv/ckp.cgs +5c41b0e945d708f91752456b93ca9c8d sim/testsuite/sim/frv/ckra.cgs +d0cadfc6114ffc4c49bd0b7cf87984dc sim/testsuite/sim/frv/ckv.cgs +eedecfb8fe25588cda9c858cec87c9e4 sim/testsuite/sim/frv/cld.cgs +82952c2b9fbbc99ed421717e4ca1e9be sim/testsuite/sim/frv/cldbf.cgs +b61f258f8679789df4df0f96f085ed27 sim/testsuite/sim/frv/cldbfu.cgs +bfc76c12370aafb393d878212832d3e3 sim/testsuite/sim/frv/cldd.cgs +c466ade998b308dc18869d2a2d2f3ae5 sim/testsuite/sim/frv/clddf.cgs +4494a0e9c7fd903a3280a5baec16e6db sim/testsuite/sim/frv/clddfu.cgs +1dbf3b1f587b8fde305387c2a6d7488c sim/testsuite/sim/frv/clddu.cgs +d7fefcc42f8ee556fc3e29e07866f54a sim/testsuite/sim/frv/cldf.cgs +01c147956ed40b80f7f01399bd71f33f sim/testsuite/sim/frv/cldfu.cgs +7f272aa06c9d1d01570e93ccfc3bed5d sim/testsuite/sim/frv/cldhf.cgs +1147cc9e693e642971e9920b10936733 sim/testsuite/sim/frv/cldhfu.cgs +00bb5f98862bbebc770fac0fa658bf27 sim/testsuite/sim/frv/cldq.cgs +cbf21bfce7b3ce694a9a0ffbecdd5edf sim/testsuite/sim/frv/cldqu.cgs +60dfef5c59d307cd1efd15c4403530ad sim/testsuite/sim/frv/cldsb.cgs +2311d8e2e1155bc0747ab69d1d80020c sim/testsuite/sim/frv/cldsbu.cgs +76fcbc22cb7f93f51d833bd012609086 sim/testsuite/sim/frv/cldsh.cgs +218e7bf5cef1de12c72a7b41e0734233 sim/testsuite/sim/frv/cldshu.cgs +91fd679b72e10313567ecee40d839288 sim/testsuite/sim/frv/cldu.cgs +2b92477d71c35dbc5340bf6cf73436c4 sim/testsuite/sim/frv/cldub.cgs +59af60628ef7e7f6c89aa5b2fa0c34c2 sim/testsuite/sim/frv/cldubu.cgs +b3a1a12789fd5e052662744d3bd0a912 sim/testsuite/sim/frv/clduh.cgs +f7adffe89325460b83af4ef27b83a02e sim/testsuite/sim/frv/clduhu.cgs +7640dbf388ab7b7e4462b20d93ca0dca sim/testsuite/sim/frv/clrfa.cgs +1ff43ea60f446681dd0636f4abf0afaf sim/testsuite/sim/frv/clrfr.cgs +1162b46f1c6271d41d44fd0376fd0abd sim/testsuite/sim/frv/clrga.cgs +3a258f66b006c6af176013d28706f114 sim/testsuite/sim/frv/clrgr.cgs +6a19cdc6d3c89ca5145cd888160feea0 sim/testsuite/sim/frv/cmaddhss.cgs +f552807622d2ead6a4c3c72b6ab6ea1c sim/testsuite/sim/frv/cmaddhus.cgs +b0ae2b6d72c1546e70b77d0f906ca816 sim/testsuite/sim/frv/cmand.cgs +054aeba615c6c341369854f1405d85d8 sim/testsuite/sim/frv/cmbtoh.cgs +c006cffe51ad60e2d97bfe726e6efc27 sim/testsuite/sim/frv/cmbtohe.cgs +e322b79b6193bc8b98fdf7d2164e1242 sim/testsuite/sim/frv/cmcpxis.cgs +2d2b7584e0bb578df1f9589e4e90bce6 sim/testsuite/sim/frv/cmcpxiu.cgs +fb274f110b2b0e732c8ab6b0567641da sim/testsuite/sim/frv/cmcpxrs.cgs +2a371679272b85c51ff58344a6870ef8 sim/testsuite/sim/frv/cmcpxru.cgs +f8de97a7353abe4fe732d79898771e06 sim/testsuite/sim/frv/cmexpdhd.cgs +c0b5d47d5b02cc1f2017b7642a70d544 sim/testsuite/sim/frv/cmexpdhw.cgs +031b21c3201bce5ff37ac1d2087209c8 sim/testsuite/sim/frv/cmhtob.cgs +4907fd3e32af4b4b10ed57c593639002 sim/testsuite/sim/frv/cmmachs.cgs +12c4a175cb447af16dd27310f13fe496 sim/testsuite/sim/frv/cmmachu.cgs +f394652f9ebf77a1d90b8a114793c2cb sim/testsuite/sim/frv/cmmulhs.cgs +509ea4a10500e161ed7a4c16dca03eed sim/testsuite/sim/frv/cmmulhu.cgs +fe9af3628dda1a7e0478b27afcb4a903 sim/testsuite/sim/frv/cmnot.cgs +d23dcfb1cdc685b13e28f46e60297128 sim/testsuite/sim/frv/cmor.cgs +c23d94eb48818d1a8830ea6d0edc3260 sim/testsuite/sim/frv/cmov.cgs +50823aeb4369412ff15e1c422ea6d8f7 sim/testsuite/sim/frv/cmovfg.cgs +294f97c82070648f417c81cefbf0d68e sim/testsuite/sim/frv/cmovfgd.cgs +a92e4825d2c41be84a96f2f6db7de29b sim/testsuite/sim/frv/cmovgf.cgs +0772a396d1b99a6fc342b4f3d355d18c sim/testsuite/sim/frv/cmovgfd.cgs +fb9380da5f21f1be28670b94115e7cb2 sim/testsuite/sim/frv/cmp.cgs +bd0fbf9e7faa375603574f1a40665865 sim/testsuite/sim/frv/cmpb.cgs +0b2e49d6ce9f4d51307d7a0c0884c357 sim/testsuite/sim/frv/cmpba.cgs +3b2a2c6753bd7ff55bc524a863d3a3cb sim/testsuite/sim/frv/cmpi.cgs +72215397d3a25089fcadc96d0449fa9d sim/testsuite/sim/frv/cmqmachs.cgs +891b8ae9013d787e9abf3f3980a93682 sim/testsuite/sim/frv/cmqmachu.cgs +7e7ca53ba30cdcc99c94cd76e31edbfd sim/testsuite/sim/frv/cmqmulhs.cgs +9a28ed90097013dbe6c10888f811edec sim/testsuite/sim/frv/cmqmulhu.cgs +a030edea39f27d8535b72eab791a946c sim/testsuite/sim/frv/cmsubhss.cgs +571559015608fda8e86c36266d8aba4c sim/testsuite/sim/frv/cmsubhus.cgs +8b11d75d92bff2f80d736079756072af sim/testsuite/sim/frv/cmxor.cgs +d8c6afc2ab9d2f02351d88640635698f sim/testsuite/sim/frv/cnot.cgs +2521bd2ee748d58fdae65f585b453033 sim/testsuite/sim/frv/commitfa.cgs +9f7ea5df90e576f10d78cdac9cc6ef50 sim/testsuite/sim/frv/commitfr.cgs +122ad6f12a5ab84bec5262e1af02c9f1 sim/testsuite/sim/frv/commitga.cgs +1abb897f3ac03712dcaf0fa415a85bb3 sim/testsuite/sim/frv/commitgr.cgs +d68f7809049059eb9fdbdaef18d03edd sim/testsuite/sim/frv/cop1.cgs +048a96dcaad276073b908e6c8f4d9189 sim/testsuite/sim/frv/cop2.cgs +50daedd569566b5f5fd6030c9c961735 sim/testsuite/sim/frv/cor.cgs +b1bfeba9317d62d449126bee0f7fa720 sim/testsuite/sim/frv/corcc.cgs +ed7de1b15d6c5535e9d56ff902749a49 sim/testsuite/sim/frv/cscan.cgs +7482a3b75fcf89d6eac98c42d36722e9 sim/testsuite/sim/frv/csdiv.cgs +6cc09cbce0f4709083b896f39eb8788b sim/testsuite/sim/frv/csll.cgs +f58b45613ae0cc85e07099e0b176a130 sim/testsuite/sim/frv/csllcc.cgs +0e6828ab5a28105f1606bfcea5961a53 sim/testsuite/sim/frv/csmul.cgs +97562af5611f19959e068464c8b152c0 sim/testsuite/sim/frv/csmulcc.cgs +8916d2cace8900da8a1d671e9a0ea2b7 sim/testsuite/sim/frv/csra.cgs +bff2fec4c10ff1cc52f6708fa1cd9e5a sim/testsuite/sim/frv/csracc.cgs +eb2f7e79db41af0b45c8182f92563397 sim/testsuite/sim/frv/csrl.cgs +d18c2b792211080ccc434210ebb67ba9 sim/testsuite/sim/frv/csrlcc.cgs +05e30ee19e5c52285f897986f1d22634 sim/testsuite/sim/frv/cst.cgs +fea6bcd449bfa45bc4f7811913f3bc14 sim/testsuite/sim/frv/cstb.cgs +29bcdb426188a5bb155dbee07ea1e527 sim/testsuite/sim/frv/cstbf.cgs +699c2363b47a8ac1c7fdd3607503f872 sim/testsuite/sim/frv/cstbfu.cgs +9d42de2773bcddcd37eafe1bf37aba97 sim/testsuite/sim/frv/cstbu.cgs +c0fa479773c62b0865cf7f6646562284 sim/testsuite/sim/frv/cstd.cgs +4dd6b1d7898b43e9ec3d140c49342862 sim/testsuite/sim/frv/cstdf.cgs +785f29fcfbdef6e93f772f32635daec4 sim/testsuite/sim/frv/cstdfu.cgs +91bdb77382d1406d5f98e2331c7a4ff5 sim/testsuite/sim/frv/cstdu.cgs +bc2f5ebb5a8ed58952e9c92d80b5e5ea sim/testsuite/sim/frv/cstf.cgs +4659f8e9e4a139ab3d797621c23c6adf sim/testsuite/sim/frv/cstfu.cgs +46c386b55d7d762b12cf33a832c34e33 sim/testsuite/sim/frv/csth.cgs +d7a05e22c19ec54237285333c21ab720 sim/testsuite/sim/frv/csthf.cgs +c606963198b1685341b32e14a3384700 sim/testsuite/sim/frv/csthfu.cgs +a7939f361fa8a4d7152833d17bf9242f sim/testsuite/sim/frv/csthu.cgs +94b3e5d6bcfbca96e1d45b116852ee46 sim/testsuite/sim/frv/cstq.cgs +bb9428edb53dbe935f3f5d3295c296f6 sim/testsuite/sim/frv/cstu.cgs +4f261153dda57be2acd2d50974b2157a sim/testsuite/sim/frv/csub.cgs +46a9440b74727f04cf647f1904d566fd sim/testsuite/sim/frv/csubcc.cgs +d59526db81b54d2c091ae65e844abba6 sim/testsuite/sim/frv/cswap.cgs +6ff863c8f3f5b0a6c8d4e2ba179e7b46 sim/testsuite/sim/frv/cudiv.cgs +9ca0539cd8fde544f4023712395cfce5 sim/testsuite/sim/frv/cxor.cgs +ce8352f2c405c5128184546ff69e67e3 sim/testsuite/sim/frv/cxorcc.cgs +e045ac944c8eccc986873c525e9996fc sim/testsuite/sim/frv/dcef.cgs +9bd0746e07695fc69099806146e177fd sim/testsuite/sim/frv/dcei.cgs +a1ff6a0459e013e3978913eca23570ca sim/testsuite/sim/frv/dcf.cgs +16483dc53cf562ff67a40716ddad4cee sim/testsuite/sim/frv/dci.cgs +a95c4bac5e72fe8a7d36b1b822acc3c6 sim/testsuite/sim/frv/fabsd.cgs +26c749327e953defb5a5af911e83e615 sim/testsuite/sim/frv/fabss.cgs +9baf3938276561eaa3ae2cd20fcaef2b sim/testsuite/sim/frv/faddd.cgs +c50d08df925d5ebe6235a744f5aa2838 sim/testsuite/sim/frv/fadds.cgs +e82570b7a76dda7f7c8c4c4499b70113 sim/testsuite/sim/frv/fbeq.cgs +9afa238bffc2569cab1b6c55a3dc8719 sim/testsuite/sim/frv/fbeqlr.cgs +bc2783dc8045f8376c62a623d04bc452 sim/testsuite/sim/frv/fbge.cgs +c89a2bf5e53afd9b92868ba2b7233f73 sim/testsuite/sim/frv/fbgelr.cgs +da685784eb930e42a55444b9982c35f1 sim/testsuite/sim/frv/fbgt.cgs +32ab332e05431f49f037d528b657d8e5 sim/testsuite/sim/frv/fbgtlr.cgs +3550e78fee67575b3e364e279299a11e sim/testsuite/sim/frv/fble.cgs +d1c296f375a94a01c76d3ab5d7e095e9 sim/testsuite/sim/frv/fblelr.cgs +bee17829c104e8e5901d5218f8da3030 sim/testsuite/sim/frv/fblg.cgs +0dfa108dc10c10107281add62d6ca5ff sim/testsuite/sim/frv/fblglr.cgs +bb12ea3ce3769e468d058aeacea5e6d6 sim/testsuite/sim/frv/fblt.cgs +8a304334e1341487c78471b20f879ecd sim/testsuite/sim/frv/fbltlr.cgs +0e297dc071234a78bd595a57838d5adc sim/testsuite/sim/frv/fbne.cgs +bf2c13262ac9d57aa021ce80e4dbf5a0 sim/testsuite/sim/frv/fbnelr.cgs +53d642fd09d91db1bfef8cafa2d8c864 sim/testsuite/sim/frv/fbno.cgs +145a02c3e9ec1831696933a5f22aa31d sim/testsuite/sim/frv/fbnolr.cgs +4aabea39aa800e2eab4188a00b9ba7b3 sim/testsuite/sim/frv/fbo.cgs +ce189b743a628565f7ae69ef124e050e sim/testsuite/sim/frv/fbolr.cgs +5f05aa8ededad20eccd884443cd8ee28 sim/testsuite/sim/frv/fbra.cgs +7b12e32c5f9c78b47dec5eb157449ab8 sim/testsuite/sim/frv/fbralr.cgs +f5619a1966d02c7c8e4bd23503a40c49 sim/testsuite/sim/frv/fbu.cgs +e97d9af6760367447c6863fb5e7fb5b0 sim/testsuite/sim/frv/fbue.cgs +119fa9c79d98e20cd89f8deea6e78dd1 sim/testsuite/sim/frv/fbuelr.cgs +2145d16c1548268652bcfdc0a032144b sim/testsuite/sim/frv/fbug.cgs +c8dca0748024ed82b9c614ccd0579c61 sim/testsuite/sim/frv/fbuge.cgs +7b549ad8f8a930a4e61411e41d6df7d0 sim/testsuite/sim/frv/fbugelr.cgs +99c4ae4bd4eb760d9274117748672094 sim/testsuite/sim/frv/fbuglr.cgs +182d8d5e906c1fe63b1ec15953fbbf0a sim/testsuite/sim/frv/fbul.cgs +b6c34d73b6a6bbc7b1547986526a8d60 sim/testsuite/sim/frv/fbule.cgs +9c00d18bfe2d4a8f3c5221ace6ce38bb sim/testsuite/sim/frv/fbulelr.cgs +d1b0b6638a07909bf45f65b454893510 sim/testsuite/sim/frv/fbullr.cgs +3ddb83bbd7a429a77b68790480613591 sim/testsuite/sim/frv/fbulr.cgs +6e5cfae9c6ca85c94d69dd30861553e1 sim/testsuite/sim/frv/fcbeqlr.cgs +e50b5ddbb0d1b0554408f8db8f7da8a4 sim/testsuite/sim/frv/fcbgelr.cgs +d5e28bf29b3ce725457862f002b4ba2d sim/testsuite/sim/frv/fcbgtlr.cgs +f8809a99276af73a606645ea3782eaa4 sim/testsuite/sim/frv/fcblelr.cgs +ef5f527028300499462fd5457798f5f2 sim/testsuite/sim/frv/fcblglr.cgs +da932dece8c1932a8e4b322ae96bb5d0 sim/testsuite/sim/frv/fcbltlr.cgs +2e537bc555c2ad4796ded84bfd87d976 sim/testsuite/sim/frv/fcbnelr.cgs +be2f0506fae9889d33fdeadc7910e5e5 sim/testsuite/sim/frv/fcbnolr.cgs +8811726c9441dd7b9f70a3bf6f8ab4fb sim/testsuite/sim/frv/fcbolr.cgs +ed61ab14ca73c4d78de8d0e432820ff6 sim/testsuite/sim/frv/fcbralr.cgs +90d5802ce49387d77932ca25262923af sim/testsuite/sim/frv/fcbuelr.cgs +719ef7eb905c6a71373cba4137767d8a sim/testsuite/sim/frv/fcbugelr.cgs +a96d3d1ca3ffa9a8c975ff08bcf77a2d sim/testsuite/sim/frv/fcbuglr.cgs +e34e76144ebb7dd885f027a37c38ae79 sim/testsuite/sim/frv/fcbulelr.cgs +8570296a139952dc9cf976d500d2f827 sim/testsuite/sim/frv/fcbullr.cgs +86c530fd6445d3f516387550e7172fa5 sim/testsuite/sim/frv/fcbulr.cgs +956c2a9363667d599f0ad75bd639805b sim/testsuite/sim/frv/fckeq.cgs +fcf411b3b36ddc44d1d61f595d1730f3 sim/testsuite/sim/frv/fckge.cgs +a5c4254bb5fb67e6553d7b4245facb4d sim/testsuite/sim/frv/fckgt.cgs +702fcbc546ef09f48a9809774f8fec26 sim/testsuite/sim/frv/fckle.cgs +8335d3357e6e879a7501b1635ce4f821 sim/testsuite/sim/frv/fcklg.cgs +2fd5797e8c20d9d7b340e095633f2ff6 sim/testsuite/sim/frv/fcklt.cgs +082bcd35a3b7969bc5b37731b9db0243 sim/testsuite/sim/frv/fckne.cgs +e05358b9a392f47c2ab2ccebc1dff681 sim/testsuite/sim/frv/fckno.cgs +09025c57960cb3245c45b229551573d1 sim/testsuite/sim/frv/fcko.cgs +4aa3a5fba828d2c29dff1b6f57d59678 sim/testsuite/sim/frv/fckra.cgs +2ba0a93a9c8332f36a0800263efc0511 sim/testsuite/sim/frv/fcku.cgs +fd10c5f2ffffd0583a7da981ddeca855 sim/testsuite/sim/frv/fckue.cgs +d025a5adc03c1fa97688e776798e6508 sim/testsuite/sim/frv/fckug.cgs +935a9c4cf686aaa2f4c480791181b2c9 sim/testsuite/sim/frv/fckuge.cgs +33411cb293d5fc422c7990104604db74 sim/testsuite/sim/frv/fckul.cgs +334619e30c816f5a6286de42eff58ebf sim/testsuite/sim/frv/fckule.cgs +26a2849fb8c805ffcb118c47ef7bf006 sim/testsuite/sim/frv/fcmpd.cgs +9d2e37d0bea30c9a00cac2518ddd5947 sim/testsuite/sim/frv/fcmps.cgs +ebae9cb1aaa0ceb6dbf6976f06d735c7 sim/testsuite/sim/frv/fdabss.cgs +a1081abe7c71411a62d3f8467141fdbb sim/testsuite/sim/frv/fdadds.cgs +7461f81658de5eada83b19dbf47f1c28 sim/testsuite/sim/frv/fdcmps.cgs +7b12d84395556d02cee66d9a1a5c991a sim/testsuite/sim/frv/fddivs.cgs +41eb8f2c4c39e3f8b7914f9a7910eac7 sim/testsuite/sim/frv/fditos.cgs +66f358e165d3d3c59afa716dc67d1788 sim/testsuite/sim/frv/fdivd.cgs +444fdecb0192342ea5f61cfd80e48b61 sim/testsuite/sim/frv/fdivs.cgs +8d77d790c0894ddb71a64a0a13e2e106 sim/testsuite/sim/frv/fdmadds.cgs +ff1044b90e19b2451b0c3f0233ee3d70 sim/testsuite/sim/frv/fdmas.cgs +fa4d51b6701d40a568e60a35d730a09c sim/testsuite/sim/frv/fdmovs.cgs +d558b5c8f62773391401afa4258ec585 sim/testsuite/sim/frv/fdmss.cgs +50d1ce458d38dfa7f69fd4f3c0b08419 sim/testsuite/sim/frv/fdmulcs.cgs +346e48b77e9a031f3f955ecefbd4019f sim/testsuite/sim/frv/fdmuls.cgs +b4bfdcbeb1d5db33d9166dc9f77da383 sim/testsuite/sim/frv/fdnegs.cgs +0ee8af42152ab4d5632be0dba1c8345d sim/testsuite/sim/frv/fdsads.cgs +60319f32e98f86da38ff2c3c5212d862 sim/testsuite/sim/frv/fdsqrts.cgs +ab9fb811cf16eb0998d83984e0cbc430 sim/testsuite/sim/frv/fdstoi.cgs +42cdb4f8bb24ee39032c4c32ca61b709 sim/testsuite/sim/frv/fdsubs.cgs +694f1d17123f4bb9c03260c1fe669aac sim/testsuite/sim/frv/fdtoi.cgs +c5163110cf891849bed86c0f453b8e02 sim/testsuite/sim/frv/fitod.cgs +6c26a616dd6fed8bd7e159e371fe4fe4 sim/testsuite/sim/frv/fitos.cgs +6ea38598142f8f6d50283bafdaf0a0f7 sim/testsuite/sim/frv/fmad.cgs +82fe9144d5b80fbfd5b4582ca5246df4 sim/testsuite/sim/frv/fmaddd.cgs +b9ae3c5d73a84096df40cbc04f28abbe sim/testsuite/sim/frv/fmadds.cgs +47f01f4c8f9a72792359daab3c1e9212 sim/testsuite/sim/frv/fmas.cgs +f59368c3bae1aa62bdb68b1edf299c9e sim/testsuite/sim/frv/fmovd.cgs +6f5746330962303a04eb519a4b05fa23 sim/testsuite/sim/frv/fmovs.cgs +f423c77b0989e36e0e8829e450d94c74 sim/testsuite/sim/frv/fmsd.cgs +7068101bb16125bf823c54313efc9c88 sim/testsuite/sim/frv/fmss.cgs +38e18b11776fdecb14fcc94311d95b20 sim/testsuite/sim/frv/fmsubd.cgs +a761e98378b236d13867be6741e673bd sim/testsuite/sim/frv/fmsubs.cgs +8dda215c5c85e94e1a385d685127d850 sim/testsuite/sim/frv/fmuld.cgs +3b5c5fa1e5977ed20ec3d4474eb79431 sim/testsuite/sim/frv/fmuls.cgs +0553d530d16ef1a9889895d233bd1a23 sim/testsuite/sim/frv/fnegd.cgs +36024f7e3058972d0b99742ee87119cd sim/testsuite/sim/frv/fnegs.cgs +a2266c24dffd8d4a696b3619a897269f sim/testsuite/sim/frv/fnop.cgs +a1394d82fbbcdc7278c8ff7b0b749317 sim/testsuite/sim/frv/fsqrtd.cgs +09a60ae22f077bfd3491cb02114dc22f sim/testsuite/sim/frv/fsqrts.cgs +64a8de42436fc5c8f2d468e70c54e9aa sim/testsuite/sim/frv/fstoi.cgs +8f0dbbf7ad0b329248d951a35e40a01b sim/testsuite/sim/frv/fsubd.cgs +5761527de2c6413c3f8a07d2189ef92a sim/testsuite/sim/frv/fsubs.cgs +a7085119fedb3ac3d4e31403309293b1 sim/testsuite/sim/frv/fteq.cgs +e3482ddd50c998096e309469d49bf60f sim/testsuite/sim/frv/ftge.cgs +25805dfe75db053034915ba8a5b33ce2 sim/testsuite/sim/frv/ftgt.cgs +16bf5094b2c7a186f0e11fa373625fb8 sim/testsuite/sim/frv/ftieq.cgs +b5a71bd3c822c7000929441e7602c329 sim/testsuite/sim/frv/ftige.cgs +ce965b75b06cd55ef70169b06c863849 sim/testsuite/sim/frv/ftigt.cgs +1951d6a3f5242b6e26d9fdb55b1bf1ca sim/testsuite/sim/frv/ftile.cgs +80d04d00a7e92cc4c32af000081d5cd4 sim/testsuite/sim/frv/ftilg.cgs +e913757697385f676de531dc9055b78d sim/testsuite/sim/frv/ftilt.cgs +f48f14696dde175e869c7c04abc8573b sim/testsuite/sim/frv/ftine.cgs +c2b0345fa9da69b5322eaf83e9506cab sim/testsuite/sim/frv/ftino.cgs +f3562f7c11ed638cffff5fb8afd74b8c sim/testsuite/sim/frv/ftio.cgs +e2bbc311eb90229f9eb63b3ea456aa51 sim/testsuite/sim/frv/ftira.cgs +fbd58be2c1178ffbda7cbe566dda3bb4 sim/testsuite/sim/frv/ftiu.cgs +7aa4b56189a14f023e26984163cb0b4e sim/testsuite/sim/frv/ftiue.cgs +821d3e5a5535a52948ced4d48cf4491d sim/testsuite/sim/frv/ftiug.cgs +bea6c33251489ce5246ed3d6bf5ac702 sim/testsuite/sim/frv/ftiuge.cgs +f60030141346c133b53f259287743291 sim/testsuite/sim/frv/ftiul.cgs +8a5f013616cf1e6db319200b9db548cd sim/testsuite/sim/frv/ftle.cgs +680e346877ec40599ab486d183890983 sim/testsuite/sim/frv/ftlg.cgs +cc345f4d17b80808ee251d600fbbc6b9 sim/testsuite/sim/frv/ftlt.cgs +47b041b440463afa7c2f9adc16bc48db sim/testsuite/sim/frv/ftne.cgs +9ac0ca5fc78d29c5cb125f7f0232ab24 sim/testsuite/sim/frv/ftno.cgs +0cfc1cccecd9264a187a4fde5a4e1b92 sim/testsuite/sim/frv/fto.cgs +7f0e3223aefe0347e86016999b785689 sim/testsuite/sim/frv/ftra.cgs +7e08ead385d09b81452d7e494e24003b sim/testsuite/sim/frv/ftu.cgs +7eb6a791ed88c6c8794db6e2d7d1c4cd sim/testsuite/sim/frv/ftue.cgs +798fee14d0226828590f274a847fb587 sim/testsuite/sim/frv/ftug.cgs +b1b5fbe7e86fcaa6a8cb5246c1105383 sim/testsuite/sim/frv/ftuge.cgs +18c32597076e6690eca21bdaa9b70083 sim/testsuite/sim/frv/ftul.cgs +b38f99b4027aa8bc54b81cd44830ff0c sim/testsuite/sim/frv/ftule.cgs +9b2b24b2080b3778404da0e73b2f4c45 sim/testsuite/sim/frv/icei.cgs +57b3c53e5a537bbcdd2bbd8bda51c584 sim/testsuite/sim/frv/ici.cgs +520e9f58107f1a7407724d2b52bbe214 sim/testsuite/sim/frv/icpl.cgs +28f0887ee88db223fdd12b2024131872 sim/testsuite/sim/frv/icul.cgs +94f5c3abf0cf2118f97e0a95f79f9dd5 sim/testsuite/sim/frv/interrupts.exp +6d82b9a4957b0fefdf4b9bd93f868b12 sim/testsuite/sim/frv/jmpil.cgs +7acb4d8fcf1961a11eb5f86da60a0804 sim/testsuite/sim/frv/jmpl.cgs +5331aae1c37403328b45cbda9aef7b4b sim/testsuite/sim/frv/jmpl.pcgs +fe0935479403ab62bd07f75bc6974752 sim/testsuite/sim/frv/ld.cgs +2a756ad9c98638728516c303deb87eb0 sim/testsuite/sim/frv/ldbf.cgs +7907b41ac563ea2be426de33f8910f66 sim/testsuite/sim/frv/ldbfi.cgs +f77f7688f51f87c5e93a3e56bd0fbc96 sim/testsuite/sim/frv/ldbfu.cgs +3a18c58e47703c059520340b1b1c3051 sim/testsuite/sim/frv/ldc.cgs +dcb10a82d61302543652fed0b13575b2 sim/testsuite/sim/frv/ldcu.cgs +6e3d68aac7b3fc4b6ed2b5e4d847070b sim/testsuite/sim/frv/ldd.cgs +20942fb6996945bf7ea82dc541af0991 sim/testsuite/sim/frv/lddc.cgs +4741f3d629b91d827c5d340249f452c5 sim/testsuite/sim/frv/lddcu.cgs +f30642deec77165f2dec4409e06fb949 sim/testsuite/sim/frv/lddf.cgs +a4e3dae18838ea83a10018cf243b37d9 sim/testsuite/sim/frv/lddfi.cgs +c4fbea8332e5b07b3fd2e18f0fd4fd9f sim/testsuite/sim/frv/lddfu.cgs +4cf840661cd9ed9ad76e658e996fc2fb sim/testsuite/sim/frv/lddi.cgs +117ef9aa94aacbff810bdc764cce2f12 sim/testsuite/sim/frv/lddu.cgs +c613f1a55c9e79f62abbd91eee7fde9d sim/testsuite/sim/frv/ldf.cgs +2426e56c573364d455e06cf511aa1c1f sim/testsuite/sim/frv/ldfi.cgs +873badad1ba22ab85ceded1032e76d7a sim/testsuite/sim/frv/ldfu.cgs +e7c1a6655a0477c4a36ead53e726fb48 sim/testsuite/sim/frv/ldhf.cgs +358001b036e18ae3c266a2d8f245022e sim/testsuite/sim/frv/ldhfi.cgs +26d92ac47d2a85071f1c0c26d721e2cc sim/testsuite/sim/frv/ldhfu.cgs +003fcd3e132470d58c6ceb7177806c5b sim/testsuite/sim/frv/ldi.cgs +e4ece86a7c055e9d7e99ecec010c71ae sim/testsuite/sim/frv/ldq.cgs +1b5c559ac60b1eb35f51ca0e4bb70acf sim/testsuite/sim/frv/ldqc.cgs +b0a584edcb6525f7880b1f45497c9a2e sim/testsuite/sim/frv/ldqcu.cgs +8c87a49e58f46e85f154cc3871f5aff6 sim/testsuite/sim/frv/ldqf.cgs +84cacbc7723416a4ab6bd038d71dac9b sim/testsuite/sim/frv/ldqfi.cgs +747342519c94e5f3d6e4153d144a3774 sim/testsuite/sim/frv/ldqfu.cgs +7f6546bcb393b36f1e1a1f1552c53160 sim/testsuite/sim/frv/ldqi.cgs +90cebd7ff7dc2106afca60b9a5a26bed sim/testsuite/sim/frv/ldqu.cgs +9ba5b89fa11ddec7e98787ca73fa0115 sim/testsuite/sim/frv/ldsb.cgs +91548ae1c6a13b8dcdc27ee53cf2c8cd sim/testsuite/sim/frv/ldsbi.cgs +fe18fae6d95afe023a4f3c12ee809a7d sim/testsuite/sim/frv/ldsbu.cgs +7bff63bb7f11db3619daa65ba575eb4b sim/testsuite/sim/frv/ldsh.cgs +04ebe641dcc2681cb7085e49e4b8787d sim/testsuite/sim/frv/ldshi.cgs +2578eab56c9efe85e875334d9be745a5 sim/testsuite/sim/frv/ldshu.cgs +0fcf16c6304ddf56ba06882bf077c739 sim/testsuite/sim/frv/ldu.cgs +b4281f11b7f00e191f158b23a2115556 sim/testsuite/sim/frv/ldub.cgs +ce9abd48c84d1abd4b05d248d4e9067e sim/testsuite/sim/frv/ldubi.cgs +f3f076fc173ea772baff44f55775ca03 sim/testsuite/sim/frv/ldubu.cgs +c9e8808a1431699f65ca45e1d96ccb40 sim/testsuite/sim/frv/lduh.cgs +6839b4b27f67afcd7af9dcbeba8e54e6 sim/testsuite/sim/frv/lduhi.cgs +e470390ff6d0df7541ce5455d765a606 sim/testsuite/sim/frv/lduhu.cgs +861233cc66075168ec7d72a804bbffae sim/testsuite/sim/frv/lrbranch.pcgs +358b9c46cd5cb979fdaf717f46764b5a sim/testsuite/sim/frv/mabshs.cgs +7174dbd57607dbdc45c4243fb7f02aa7 sim/testsuite/sim/frv/maddhss.cgs +8aa28a7f77fd8f94f1f8d4441330d2de sim/testsuite/sim/frv/maddhus.cgs +2e1fd77e3c7dc410824bb62d86c12fa5 sim/testsuite/sim/frv/mand.cgs +2caa34c2c4802ea92661e98ac6af667f sim/testsuite/sim/frv/maveh.cgs +89a846533bf6d66afa6dc6a610bee4de sim/testsuite/sim/frv/mbtoh.cgs +be7bc8f47af7ec401ae8edc5735ae83f sim/testsuite/sim/frv/mbtohe.cgs +5890a645af954362f462a536301ab07a sim/testsuite/sim/frv/mclracc.cgs +4df2335c339344cb1ab773c28eac7047 sim/testsuite/sim/frv/mcmpsh.cgs +0202236564d839929bc185b5b363483b sim/testsuite/sim/frv/mcmpuh.cgs +75f2c544b8e80d583bfc78a32fce7f9f sim/testsuite/sim/frv/mcop1.cgs +eac5267f2219d176a231a4394b8a7dbe sim/testsuite/sim/frv/mcop2.cgs +0511aebe3ab974e7a9e5fdfa895d9aeb sim/testsuite/sim/frv/mcplhi.cgs +dae087e8f55a8ecbfe85b2476c9267e2 sim/testsuite/sim/frv/mcpli.cgs +40aac5235a3696c45134d86e1e79c5d9 sim/testsuite/sim/frv/mcpxis.cgs +bf8b42298ba9d65e9cbfb7f621ede0df sim/testsuite/sim/frv/mcpxiu.cgs +da93993782224f234cfa217c4c2de3cb sim/testsuite/sim/frv/mcpxrs.cgs +2e3efdb33b16bdf036e34506be43620a sim/testsuite/sim/frv/mcpxru.cgs +2e85d413681ca26660d8f9691a5c9ab2 sim/testsuite/sim/frv/mcut.cgs +6f24d372cfa857010330fd99b9ceaa3f sim/testsuite/sim/frv/mcuti.cgs +58aae8e7b29223770991f01723b7dd98 sim/testsuite/sim/frv/mcutss.cgs +d94022526f601563a7d06cde8c8461d5 sim/testsuite/sim/frv/mcutssi.cgs +c75ed78a7566a8628cf0a0339c5dcf21 sim/testsuite/sim/frv/mdaddaccs.cgs +5034792548b761b0fe9ad80d44958b6e sim/testsuite/sim/frv/mdasaccs.cgs +e81006aee4bbd0e3671448585ab45d5d sim/testsuite/sim/frv/mdcutssi.cgs +4ced60215e6ef89c35488866f38fd3c0 sim/testsuite/sim/frv/mdpackh.cgs +00c2e418966af14d3cc048573279d6fc sim/testsuite/sim/frv/mdrotli.cgs +bbe41f9762adbc1e38c19904af9a4622 sim/testsuite/sim/frv/mdsubaccs.cgs +edb5aa56bcd8e8bca69cf259f36e465f sim/testsuite/sim/frv/mdunpackh.cgs +32dde2fe5a74ba57fb63ca5a91948b13 sim/testsuite/sim/frv/membar.cgs +7351ae1c949d0e80e4c9cac3adb238c0 sim/testsuite/sim/frv/mexpdhd.cgs +8be433c05488391e44e6d0fd1a0663a5 sim/testsuite/sim/frv/mexpdhw.cgs +bfc4a4f409782a01b12aafa73820d4a7 sim/testsuite/sim/frv/mhdseth.cgs +5530ac8f622c5b86676418a439d31062 sim/testsuite/sim/frv/mhdsets.cgs +6e9d7ee79258240c2e9f8490187d2d1b sim/testsuite/sim/frv/mhsethih.cgs +0286e694b02e66084d5fb2649c171379 sim/testsuite/sim/frv/mhsethis.cgs +889eccff241ad187bd577cfe2fcc0ddc sim/testsuite/sim/frv/mhsetloh.cgs +500ddf7a9ca8ca47e62e62cf4257a675 sim/testsuite/sim/frv/mhsetlos.cgs +a861d845633062758e032a27d5fab174 sim/testsuite/sim/frv/mhtob.cgs +e326ecc782170966595a854ea64b2786 sim/testsuite/sim/frv/mmachs.cgs +052b5f3d0e3a1fca5894d9655353d7e3 sim/testsuite/sim/frv/mmachu.cgs +985bedf1c0cc65d298ccc789ebc69179 sim/testsuite/sim/frv/mmrdhs.cgs +cf37e0de21739109f45bc6903faef9ff sim/testsuite/sim/frv/mmrdhu.cgs +b813da728e948bf7f3d0a70e28fd56de sim/testsuite/sim/frv/mmulhs.cgs +20f4895c822bcecaa711c3508043ced9 sim/testsuite/sim/frv/mmulhu.cgs +5970b5e8ca637b383803588fb78206d8 sim/testsuite/sim/frv/mmulxhs.cgs +e6ac3d3a2b75c748d32f1dff04690c18 sim/testsuite/sim/frv/mmulxhu.cgs +73a36ac7ddbc3eb5f02e23e556757534 sim/testsuite/sim/frv/mnop.cgs +d7e3785dd9d822d3c98edf4a7ca1e462 sim/testsuite/sim/frv/mnot.cgs +787ba5a828f2060d5163f4dd6493bdfc sim/testsuite/sim/frv/mor.cgs +e15b13b9790cd957ef7c1174a414fc91 sim/testsuite/sim/frv/mov.cgs +e267cd40e466ef09766bb5af7f3ea525 sim/testsuite/sim/frv/movfg.cgs +1de01bb11a8e27d051b6d84fdf37cbff sim/testsuite/sim/frv/movfgd.cgs +b671fcc6ddd6daa079fd31a468749b0e sim/testsuite/sim/frv/movfgq.cgs +1f93a0d7fca1cd46156bd7a0c7f3c59f sim/testsuite/sim/frv/movgf.cgs +6a708919bfd6e9a6a3b0a1872c48290f sim/testsuite/sim/frv/movgfd.cgs +490b859435e3a616aa2c844b9dbed8d6 sim/testsuite/sim/frv/movgfq.cgs +d2a4394753db3dfcbe7e384ee21e2202 sim/testsuite/sim/frv/movgs.cgs +5df092435661dcba49b26ede1ae30c8d sim/testsuite/sim/frv/movsg.cgs +1e471deced4a3635b4468bd2d1ff88cb sim/testsuite/sim/frv/mpackh.cgs +de1b6d1ff997e66d64111e7a69c3f749 sim/testsuite/sim/frv/mqcpxis.cgs +ddd0fdd0602cb85ada820445cf505820 sim/testsuite/sim/frv/mqcpxiu.cgs +dc5c412a280bacbbb5fd6a56a6fe53ff sim/testsuite/sim/frv/mqcpxrs.cgs +e92162146f80eacb87cc88e02de63d26 sim/testsuite/sim/frv/mqcpxru.cgs +a016768b6c2c21cc9c4354d7cc7f9628 sim/testsuite/sim/frv/mqmachs.cgs +317e00e7d2fc4d994400b3435e38deba sim/testsuite/sim/frv/mqmachu.cgs +bf4cfe49b9af48954b1a4495db0bcb6f sim/testsuite/sim/frv/mqmacxhs.cgs +d79cc37be001047a062fd1b16bf5e34e sim/testsuite/sim/frv/mqmulhs.cgs +26f559df23ae04f9a1576f793e340163 sim/testsuite/sim/frv/mqmulhu.cgs +5c07a1afebe94dfc4e0132d66d8c28ea sim/testsuite/sim/frv/mqmulxhs.cgs +8674ff984bcbe2b1460d51e69db27c7b sim/testsuite/sim/frv/mqmulxhu.cgs +352d41aa9b03ec2820009d90f569a60a sim/testsuite/sim/frv/mqsaths.cgs +b1cf84b60cf3a908c49512b100a3cf65 sim/testsuite/sim/frv/mqxmachs.cgs +48ee9ffc570edbbfe8169afd5f2bacee sim/testsuite/sim/frv/mqxmacxhs.cgs +d3412bc4c0b67f6c78449fd684463b9b sim/testsuite/sim/frv/mrdacc.cgs +cc6399ec148be0f20332c2aeadef5990 sim/testsuite/sim/frv/mrdaccg.cgs +f428dd31a13e708566a12b6eb23e75aa sim/testsuite/sim/frv/mrotli.cgs +a05d5c0d7e028af3383c1e9b237ef156 sim/testsuite/sim/frv/mrotri.cgs +9b134f75e539c10de4195ec1e51ee136 sim/testsuite/sim/frv/msaths.cgs +326669d1c76ef080e2d2ddf8c2ee6e6f sim/testsuite/sim/frv/msathu.cgs +475e50c7c92b7357b020583b574726a8 sim/testsuite/sim/frv/msllhi.cgs +5e7cbd14acb0fd1a1bdc89e068e9803d sim/testsuite/sim/frv/msrahi.cgs +90c1d817bd4dce7d539e4e9dacb35e90 sim/testsuite/sim/frv/msrlhi.cgs +f3f08211769783c8fad2413b5f4419a5 sim/testsuite/sim/frv/msubhss.cgs +c171d116ab1a2be2bd6fe89d40046466 sim/testsuite/sim/frv/msubhus.cgs +6f29112e0458cbb1fe8d3a0403ed85d7 sim/testsuite/sim/frv/mtrap.cgs +80d2065efb7d0769f11b1c4881e20500 sim/testsuite/sim/frv/munpackh.cgs +5f0be0ef1415763840683d1a66cf6b67 sim/testsuite/sim/frv/mwcut.cgs +28b4f2f9ac438caaebbf3d5fe7b8b9f3 sim/testsuite/sim/frv/mwcuti.cgs +68b4157ad30443488a491d75a0ddc05f sim/testsuite/sim/frv/mwtacc.cgs +82d5838a4cbf516a93892bafbf64af95 sim/testsuite/sim/frv/mwtaccg.cgs +754cf046515e94f61db9e81c57bbef98 sim/testsuite/sim/frv/mxor.cgs +ea152c37492f744e98208e25538591cc sim/testsuite/sim/frv/nandcr.cgs +9bd25bbc9331a8a7a764970163f8a3c2 sim/testsuite/sim/frv/nandncr.cgs +5645677fd61cac055a6989382352af7e sim/testsuite/sim/frv/nfadds.cgs +f6656b60bec315c613ad5092d5bba892 sim/testsuite/sim/frv/nfdadds.cgs +6f912abf4768c8b66831a8ce4a5ab658 sim/testsuite/sim/frv/nfdcmps.cgs +f72cfcf1db3b542e40ae4d24754a8648 sim/testsuite/sim/frv/nfddivs.cgs +ac7e485b7fc2228e78885a3580c40684 sim/testsuite/sim/frv/nfditos.cgs +0e30127c5ef9ca2d27a6bf7790128b65 sim/testsuite/sim/frv/nfdivs.cgs +2d6cd85e83c408920463b9e326312c1d sim/testsuite/sim/frv/nfdmadds.cgs +fdd8bd1799f969d718f27d5140c561e1 sim/testsuite/sim/frv/nfdmas.cgs +75d93040b8b11cd80e200e83f9c3b423 sim/testsuite/sim/frv/nfdmss.cgs +9564e9d1067be24d75f69103b57a85dc sim/testsuite/sim/frv/nfdmulcs.cgs +96c1cae5bdbbfd68972a26ded76a6653 sim/testsuite/sim/frv/nfdmuls.cgs +60b73bc5cde0341f993a4d3fa218363f sim/testsuite/sim/frv/nfdsads.cgs +ccf1387db46bf4985328d9b58f89085e sim/testsuite/sim/frv/nfdsqrts.cgs +08bb1af48f043b2ec22ede0e6a2a63c0 sim/testsuite/sim/frv/nfdstoi.cgs +c76e1c140c00dea2137868c13de73686 sim/testsuite/sim/frv/nfdsubs.cgs +4f526f2f27056051f986c47b44c9b1ff sim/testsuite/sim/frv/nfitos.cgs +5c7a02887eb56676fc4f267dff41f169 sim/testsuite/sim/frv/nfmadds.cgs +3de97f087ebc932501f95bc2bd775d5f sim/testsuite/sim/frv/nfmas.cgs +de42c23dfd886e1e9150e93cfa7a0e30 sim/testsuite/sim/frv/nfmss.cgs +c133078967d4e2c08e05c0c211483593 sim/testsuite/sim/frv/nfmsubs.cgs +40981f85eeb4a396327c4e11f7ca792d sim/testsuite/sim/frv/nfmuls.cgs +c73e0f9186dae498050376d33b40c1c6 sim/testsuite/sim/frv/nfsqrts.cgs +a9c95b2f342640586e4acb9faad49772 sim/testsuite/sim/frv/nfstoi.cgs +147619970eca1511cbd9f636e8aaeeb7 sim/testsuite/sim/frv/nfsubs.cgs +849a1c54f6b7fc29b1fea32e1adffb98 sim/testsuite/sim/frv/nld.cgs +cec99b8b35d4fdcdb377d9a66ea62009 sim/testsuite/sim/frv/nldbf.cgs +285f247c378146a1e4a5a8134ab4c06f sim/testsuite/sim/frv/nldbfi.cgs +62fbafc1c264ff3ffa2f95d455138a29 sim/testsuite/sim/frv/nldbfu.cgs +3cf41818d7d43998028a6204c6d3d1cc sim/testsuite/sim/frv/nldd.cgs +484f52adb8fc411974f97082db9d5dbc sim/testsuite/sim/frv/nlddf.cgs +2bb049f287b76c978273eaf5c312a4d1 sim/testsuite/sim/frv/nlddfi.cgs +b21df75a0fc0a38539d562c017b4b670 sim/testsuite/sim/frv/nlddfu.cgs +903edfdf254dfa703f606ad9ccda17ad sim/testsuite/sim/frv/nlddi.cgs +2c42865e66cdf52327e926c6430af676 sim/testsuite/sim/frv/nlddu.cgs +36d1b5e9f74e8641f51abe8a472c6860 sim/testsuite/sim/frv/nldf.cgs +4ee6d04ba074cd859443fa0bf726dc3f sim/testsuite/sim/frv/nldfi.cgs +ae737e209ef8a22261025cd8102d7861 sim/testsuite/sim/frv/nldfu.cgs +4f3c2f0fc2e3ed5b6c87cd135a6bbd00 sim/testsuite/sim/frv/nldhf.cgs +b12b404167348112b47f3650d80a49a1 sim/testsuite/sim/frv/nldhfi.cgs +23dbb5a7d7175564285ef8cbbafdf4d7 sim/testsuite/sim/frv/nldhfu.cgs +323956db2a566de88fcd530490661356 sim/testsuite/sim/frv/nldi.cgs +7e182fb1f729214fcc4e500b45b28c67 sim/testsuite/sim/frv/nldq.cgs +f0900597e5ab5ecf6b5c7a7767e62980 sim/testsuite/sim/frv/nldqf.cgs +ad1fb24311a078779b253206335fb321 sim/testsuite/sim/frv/nldqfi.cgs +6158542e4b6f47593521af161cbefcc4 sim/testsuite/sim/frv/nldqfu.cgs +27c8a87945ccd5906ecb831c022a2cae sim/testsuite/sim/frv/nldqu.cgs +86f2d4d2d5077458a84b7b7717ae2841 sim/testsuite/sim/frv/nldsb.cgs +6cb71382953aaa573377ba9365cf47c8 sim/testsuite/sim/frv/nldsbi.cgs +94382ca860759734f699db2c4030a586 sim/testsuite/sim/frv/nldsbu.cgs +769125b26bae4afc675b0f4ecba3476b sim/testsuite/sim/frv/nldsh.cgs +512f6ab69b17ee51ff97983b35376396 sim/testsuite/sim/frv/nldshi.cgs +288041bebf2361e4e1b14d5487134199 sim/testsuite/sim/frv/nldshu.cgs +fcdd282d23082a3f4baf0861979ef5bb sim/testsuite/sim/frv/nldu.cgs +21e414ff661565b6aa03208928648853 sim/testsuite/sim/frv/nldub.cgs +4dbc3bfa2a0abb00d11e913ffe7dbfdf sim/testsuite/sim/frv/nldubi.cgs +7a14b1a4b9c264ad6fe9fee43a34053c sim/testsuite/sim/frv/nldubu.cgs +606377e169feb767df3ada199efb6756 sim/testsuite/sim/frv/nlduh.cgs +29e215193143b4309c76dec515f0ffb9 sim/testsuite/sim/frv/nlduhi.cgs +8e6934cc5df77f17ded11b0e56344cc1 sim/testsuite/sim/frv/nlduhu.cgs +55a7762fcf4065ee0e1e89c09894296b sim/testsuite/sim/frv/nop.cgs +c82aab8314691de50e4eb1b4d2deee7f sim/testsuite/sim/frv/norcr.cgs +1d754b9b7c803178ecc07bed29a6226c sim/testsuite/sim/frv/norncr.cgs +877b1bf25d820494dfcd5c8e060ee0a5 sim/testsuite/sim/frv/not.cgs +937c6181f24f15a85ce59e24a746f6da sim/testsuite/sim/frv/notcr.cgs +9711b61b6a23527c5cde41eaac4eb112 sim/testsuite/sim/frv/nsdiv.cgs +e7a86181d00e8f0c9684753e86508c74 sim/testsuite/sim/frv/nsdivi.cgs +6b19d157804a7fa854e78b49a095a638 sim/testsuite/sim/frv/nudiv.cgs +da4a0f53d7d03d30ce9cca0bf34a2ece sim/testsuite/sim/frv/nudivi.cgs +371a4f289d0bc38fee546e49ad327952 sim/testsuite/sim/frv/or.cgs +5c2413abe5cf30fb4cdd0d5e3c30dbab sim/testsuite/sim/frv/orcc.cgs +56f5fdf1970e4a477ff5bcd70ad6128d sim/testsuite/sim/frv/orcr.cgs +67bd729e92a8ccbb0ef66f5053e9c7c9 sim/testsuite/sim/frv/ori.cgs +e1e57ef45323b229f0811de476eadaa8 sim/testsuite/sim/frv/oricc.cgs +9fc100ac9932ce7d023e9d73fe027dd7 sim/testsuite/sim/frv/orncr.cgs +6aa3407819f0ab3db9441490901c1c20 sim/testsuite/sim/frv/parallel.exp +54abbae4f460a1ac2f0f979b48cff91f sim/testsuite/sim/frv/ret.cgs +102c16fad8d7c1990921e4b171f62531 sim/testsuite/sim/frv/rett.cgs +dcdd60cb6a74a2fdf05c27542ce87c00 sim/testsuite/sim/frv/scan.cgs +a0d99a5f1ae6d699d7551ec0c91ad1f9 sim/testsuite/sim/frv/scani.cgs +8cfaaa6f7d9be0c7164bd6b95f781486 sim/testsuite/sim/frv/sdiv.cgs +a0bc228cfda1d7113cd087bfc0298020 sim/testsuite/sim/frv/sdivi.cgs +0eaa5642821eed78cc9e2c144fe34a92 sim/testsuite/sim/frv/sethi.cgs +d3a8b5ed0ad285696200a176e326a55b sim/testsuite/sim/frv/sethilo.pcgs +6eafdd537ba1f28305cee77fe68ff5fd sim/testsuite/sim/frv/setlo.cgs +bb74161afeebbd175cc9296446d7ff46 sim/testsuite/sim/frv/setlos.cgs +dc65593014b3881fdcff036075e5dad0 sim/testsuite/sim/frv/sll.cgs +ee34b84c6bf75a9babe137a04ac4b75a sim/testsuite/sim/frv/sllcc.cgs +35c7aae3b090f125993fef390d76906f sim/testsuite/sim/frv/slli.cgs +8700acd6ed03f5cbac0ad536383ed3c8 sim/testsuite/sim/frv/sllicc.cgs +0814d3851a44b4bce8357863eec8e600 sim/testsuite/sim/frv/smul.cgs +8692050bdf66cc6ad2d401c4a4684cef sim/testsuite/sim/frv/smulcc.cgs +89a51e07a40a4e8f76ac296cacbb8363 sim/testsuite/sim/frv/smuli.cgs +2eb6969a0c7a4eb4fff85aac9727721a sim/testsuite/sim/frv/smulicc.cgs +2d31dcb15e8a6877017dd3d148b0bf2b sim/testsuite/sim/frv/sra.cgs +d41729b132c64711d5d230c8be3b4332 sim/testsuite/sim/frv/sracc.cgs +1d5380689e9dae36a5ab8b5436118c9e sim/testsuite/sim/frv/srai.cgs +3ba660d7dcfb108e50618445716bb95b sim/testsuite/sim/frv/sraicc.cgs +204db103ce94f9da0c1f28ed0cd60ba0 sim/testsuite/sim/frv/srl.cgs +5aceef24e6a30dc790c1cd482bfa40f8 sim/testsuite/sim/frv/srlcc.cgs +59498912961c5a2bfe37d5631fc3802c sim/testsuite/sim/frv/srli.cgs +59addb4ff5949cfea9664343d9f81a38 sim/testsuite/sim/frv/srlicc.cgs +cc2f98b9ebe473e853c879e903f2f4bd sim/testsuite/sim/frv/st.cgs +7da5b6117008820095468c44c991bba7 sim/testsuite/sim/frv/stb.cgs +038ed75fefa3a9b991855a5b60b5046c sim/testsuite/sim/frv/stbf.cgs +ddf4ff091a5b6c5cf352c04d236e2fcc sim/testsuite/sim/frv/stbfi.cgs +9fc9892f699a1d3ddc62ae7524e9ce82 sim/testsuite/sim/frv/stbfu.cgs +e038da35c3e2553c4431a03fe542c5dc sim/testsuite/sim/frv/stbi.cgs +fb8002b4e6861b77f536c7629c7bf622 sim/testsuite/sim/frv/stbu.cgs +64efd173f19902d6a2005148cb3d4831 sim/testsuite/sim/frv/stc.cgs +c8327289e084ae64868b9257b8646e11 sim/testsuite/sim/frv/stcu.cgs +791afd243b5e7ed1e6aa29ad1113f218 sim/testsuite/sim/frv/std.cgs +d34e0187f000a733eaf4b2730118ae03 sim/testsuite/sim/frv/std.pcgs +04f8995f9af5c9a6d61eb1ab60b34ba0 sim/testsuite/sim/frv/stdc.cgs +ca358dddc54a8ba43c916ac2a6b45812 sim/testsuite/sim/frv/stdc.pcgs +285195010d47ac9191d9c97aca80f0e6 sim/testsuite/sim/frv/stdcu.cgs +b9b610f3e0c8243a5d9e261844251ed7 sim/testsuite/sim/frv/stdf.cgs +8a296ea605f6ea7504e25318c38b44c4 sim/testsuite/sim/frv/stdf.pcgs +cdb16f4dfab32f15e7a55fba16afd880 sim/testsuite/sim/frv/stdfi.cgs +14194ebf318b1a64b5cbc27e067b5110 sim/testsuite/sim/frv/stdfu.cgs +43e07345873b79b52184a1785a5ce422 sim/testsuite/sim/frv/stdi.cgs +c1916f813f831be331a1dbc2312fd4bb sim/testsuite/sim/frv/stdu.cgs +74d71e1f6d2aa891e6e9cb32cd44e036 sim/testsuite/sim/frv/stf.cgs +8c68b4f09d376aac18a160f70bbb24c0 sim/testsuite/sim/frv/stfi.cgs +ef17532bed029b8034a943091bcc8d3a sim/testsuite/sim/frv/stfu.cgs +c458c9df8008e8b3f7761d31df5e912d sim/testsuite/sim/frv/sth.cgs +8a3789cf60dd4331ea1a6f6e994b76e8 sim/testsuite/sim/frv/sthf.cgs +8bcf588029874b3f33885374cc496306 sim/testsuite/sim/frv/sthfi.cgs +4f069f49b6bc39f94f78adf156ce0f43 sim/testsuite/sim/frv/sthfu.cgs +84ffdd51531190b3f7ab0bd433a36036 sim/testsuite/sim/frv/sthi.cgs +8ccbca9bbf069a03a4d929333916d88c sim/testsuite/sim/frv/sthu.cgs +250d78cd5a5807bcacccc649f4e5d0ad sim/testsuite/sim/frv/sti.cgs +5e9fe07f66519bb28e80b540c91d7270 sim/testsuite/sim/frv/stq.cgs +3a29b1dd11046f8f4dd5c27edc2a8d6f sim/testsuite/sim/frv/stq.pcgs +aa46f6b377cfc62824b0be2e6fc1c326 sim/testsuite/sim/frv/stqc.cgs +73fa8ef52f05985daec1d8a01dbbc29f sim/testsuite/sim/frv/stqc.pcgs +e7569bf70d9017f69182cfa2622ebfbf sim/testsuite/sim/frv/stqcu.cgs +27da4c018deec302d0e3d6b8c89c9909 sim/testsuite/sim/frv/stqf.cgs +244caf04384a0a05c44c7299059e0a1e sim/testsuite/sim/frv/stqf.pcgs +31598ac83baef878c73a4ac875783821 sim/testsuite/sim/frv/stqfi.cgs +099e806e30801140def329d0fc74d8f3 sim/testsuite/sim/frv/stqfu.cgs +01a00c462bcea5bf16545bc7e56ab416 sim/testsuite/sim/frv/stqi.cgs +3664a976c54024aeb5afceea3da50af6 sim/testsuite/sim/frv/stqu.cgs +7a55c30063f85e2d54e1cc2841ee7a63 sim/testsuite/sim/frv/stu.cgs +2faf06039d62d7df322e435075a72433 sim/testsuite/sim/frv/sub.cgs +7844ed84fbc9b4ee3a16338a630a6b99 sim/testsuite/sim/frv/subcc.cgs +8c0c31883700925b3a024a0ef3d6e4db sim/testsuite/sim/frv/subi.cgs +3a686d8663268c0def363c90e28b1376 sim/testsuite/sim/frv/subicc.cgs +87cef6e1007d13b030a257ac5991b6e0 sim/testsuite/sim/frv/subx.cgs +6c55773b2d52d6ed53ba61e9150a8c88 sim/testsuite/sim/frv/subxcc.cgs +ccb0533eb0f55d739ea829ea6061fd7e sim/testsuite/sim/frv/subxi.cgs +0bd2bac2e1c8b477c6ca6c96a9c0d2ec sim/testsuite/sim/frv/subxicc.cgs +8aa6fce072b5f76aed92908d9cb37534 sim/testsuite/sim/frv/swap.cgs +c8282a4995f3299c881dda28d1a95fe6 sim/testsuite/sim/frv/swapi.cgs +23522584d66a3f774c033e074adf7612 sim/testsuite/sim/frv/tc.cgs +7ffb238a56ea272bda7a212d95f41684 sim/testsuite/sim/frv/teq.cgs +2505dee1a39d2cde6c4c38408239b7c0 sim/testsuite/sim/frv/testutils.inc +a7bdf9822718f81fe29124a9f8da86e6 sim/testsuite/sim/frv/tge.cgs +04aeccbcf90bc8f88178560c2910dfc7 sim/testsuite/sim/frv/tgt.cgs +190947262baf5a431a603a9057bd38a6 sim/testsuite/sim/frv/thi.cgs +d62ead6b5942f8e2a83a67ef8db006bf sim/testsuite/sim/frv/tic.cgs +a913dea5c58bfd33d54ec66ebe5abdf3 sim/testsuite/sim/frv/tieq.cgs +6326a374397a88a326f50a1c5bc7ffe2 sim/testsuite/sim/frv/tige.cgs +98be2afbdc22e83e7ed60607d14d3586 sim/testsuite/sim/frv/tigt.cgs +336b596245297750b95b8a77073f7966 sim/testsuite/sim/frv/tihi.cgs +15b4d16b3eae3485cb76eede88794bbe sim/testsuite/sim/frv/tile.cgs +100c61ae3fb0dca4723d52d915d79b03 sim/testsuite/sim/frv/tils.cgs +ce558734ad2bc060917be3c4618d3552 sim/testsuite/sim/frv/tilt.cgs +ca0a7cd8b619ec89e936a27126c5809d sim/testsuite/sim/frv/tin.cgs +49bc7107d499c26ff0c4f28999dc36ed sim/testsuite/sim/frv/tinc.cgs +301a4bafaa39d4e1ab111b7fd38291e9 sim/testsuite/sim/frv/tine.cgs +51afec41d7406196f09ae12d2ec0db03 sim/testsuite/sim/frv/tino.cgs +e85d17ee566b10c9e3caeea7e430922e sim/testsuite/sim/frv/tinv.cgs +4dcd5dd9170ea1b0782fc5ec7bce6e58 sim/testsuite/sim/frv/tip.cgs +a01a5cb5837ff3029820691d608c0fe3 sim/testsuite/sim/frv/tira.cgs +4a3754ff5d07a1bff25b091c6475abad sim/testsuite/sim/frv/tiv.cgs +0852100fd0d41a5575a5d49b4b43537e sim/testsuite/sim/frv/tle.cgs +e77e2e2eb284cae56dede5c4e7b16bbe sim/testsuite/sim/frv/tls.cgs +4a9afe4a49c80157e0738e27bd5f3a52 sim/testsuite/sim/frv/tlt.cgs +eb0c622a60c8bb2159d3a20ddaf72563 sim/testsuite/sim/frv/tn.cgs +a58b7d334a64b2f17d8110d347c1fcbe sim/testsuite/sim/frv/tnc.cgs +ec7dfbef9d8c3fcfbd2a205998b43499 sim/testsuite/sim/frv/tne.cgs +533ecf4107a99d0372bd32229bb091ae sim/testsuite/sim/frv/tno.cgs +cad1a26e6f61be6236cdf19c6f330241 sim/testsuite/sim/frv/tnv.cgs +5702a40a3528f6faf8e82e13564087ac sim/testsuite/sim/frv/tp.cgs +ecca874070d3e9425aeb8088c8a60d30 sim/testsuite/sim/frv/tra.cgs +41358b18cb9bba0fa299b05270c44629 sim/testsuite/sim/frv/tv.cgs +d8ef8851170116f7cc0700416b84aa6a sim/testsuite/sim/frv/udiv.cgs +8cb511e7ba50142c3d082aaedf99e2d4 sim/testsuite/sim/frv/udivi.cgs +9b3fe3689386f452b6a4efa05a509b8c sim/testsuite/sim/frv/umul.cgs +77681bcd415a24cb17bbdf0f77eb260b sim/testsuite/sim/frv/umulcc.cgs +f6e8f7472bf3297a7b540ebaabc0c1f2 sim/testsuite/sim/frv/umuli.cgs +9797e25ce9dc0b46d586cd0d92620735 sim/testsuite/sim/frv/umulicc.cgs +0edd78565b6001f524f716ab9d2d96c0 sim/testsuite/sim/frv/xor.cgs +9be8c0bf0141c153cf179aa9b42ee2d1 sim/testsuite/sim/frv/xorcc.cgs +04132b96881a20ec0effc93a6a586ea9 sim/testsuite/sim/frv/xorcr.cgs +738a395cb2d18169d1b0c2027636cf1b sim/testsuite/sim/frv/xori.cgs +887a01bed2d74acf834781ed7fa9f560 sim/testsuite/sim/frv/xoricc.cgs +3e48a7675e041e56f1aff0fe96c45a4c sim/testsuite/sim/frv/fr400/addss.cgs +072a0a143c04db0a6ce34d56ecc749d8 sim/testsuite/sim/frv/fr400/allinsn.exp +07bb80901aaaa29c4ef20dbef3debb70 sim/testsuite/sim/frv/fr400/csdiv.cgs +dc7862c2d91981e56cddc36314f0c630 sim/testsuite/sim/frv/fr400/maddaccs.cgs +4cc9052cb05275a67396e5ea46d54af6 sim/testsuite/sim/frv/fr400/masaccs.cgs +2039d3b5260700c8371efd1a6ab21552 sim/testsuite/sim/frv/fr400/maveh.cgs +4ac0a330e6fa287d0f2f2f8500453afc sim/testsuite/sim/frv/fr400/mclracc.cgs +285f596d7467307f369b18d453abe1ea sim/testsuite/sim/frv/fr400/mhdseth.cgs +5e1be1e0297eb84b961c6dc29d4cce8c sim/testsuite/sim/frv/fr400/mhdsets.cgs +9bb2a41f38271c359451454b6d2a79dc sim/testsuite/sim/frv/fr400/mhsethih.cgs +dac84369f283aabc0e0c8d6188130e92 sim/testsuite/sim/frv/fr400/mhsethis.cgs +538622163aded8a4e8f1d47d61db8b5c sim/testsuite/sim/frv/fr400/mhsetloh.cgs +a808c8a95fde4532828d00e281c1322c sim/testsuite/sim/frv/fr400/mhsetlos.cgs +a1032b0fb6b6923000282a43d3f85a7a sim/testsuite/sim/frv/fr400/movgs.cgs +0f2cd9ab4e36a741a77488033a0ceeb0 sim/testsuite/sim/frv/fr400/movsg.cgs +e4644c48c06766cd34578d5ce34680dd sim/testsuite/sim/frv/fr400/msubaccs.cgs +ba109065c4434a5d494a8270aaa91e7b sim/testsuite/sim/frv/fr400/scutss.cgs +daad245fe005a9a6394bb569733c9aed sim/testsuite/sim/frv/fr400/sdiv.cgs +b90754c53de9e9744ee927d4993920fc sim/testsuite/sim/frv/fr400/sdivi.cgs +2eba80fdfa94ab8c80ac014b8bce4c94 sim/testsuite/sim/frv/fr400/slass.cgs +b6607c22a2cff244b1720df63e9c149b sim/testsuite/sim/frv/fr400/smass.cgs +7dcecbc0d78a0b067e70fc750c890f49 sim/testsuite/sim/frv/fr400/smsss.cgs +d552b09ce35ed9fb50c5cff2166faf35 sim/testsuite/sim/frv/fr400/smu.cgs +fbfe45803aaf124fcda55a7bea2a97ea sim/testsuite/sim/frv/fr400/subss.cgs +621cd869aa5b032b34294f31f3e4a702 sim/testsuite/sim/frv/fr400/udiv.cgs +146cea8d68ddb592d231ab14478a8d0b sim/testsuite/sim/frv/fr400/udivi.cgs +bf7e8ae5fa9de937c99e7e09f42bbac5 sim/testsuite/sim/frv/fr500/allinsn.exp +9fdc5172e86b3be5621a6faf3f07db74 sim/testsuite/sim/frv/fr500/cmqaddhss.cgs +1de69657638007870281ce9da005db7f sim/testsuite/sim/frv/fr500/cmqaddhus.cgs +76820a559b8411a4ae43b6a383d65b0d sim/testsuite/sim/frv/fr500/cmqsubhss.cgs +dc65c316119a5c8162d829bbd7c0223a sim/testsuite/sim/frv/fr500/cmqsubhus.cgs +16004a850f6c18d31c7430fbab31f79d sim/testsuite/sim/frv/fr500/dcpl.cgs +54a02614046bab2457214898aff37526 sim/testsuite/sim/frv/fr500/dcul.cgs +99e08a053ed3e5abb1c4bf9c6a64fbc1 sim/testsuite/sim/frv/fr500/mclracc.cgs +fe34b6bddc9686a443e9025451c3ac88 sim/testsuite/sim/frv/fr500/mqaddhss.cgs +b113a28c5f41f7ab598d39fab2d5e21f sim/testsuite/sim/frv/fr500/mqaddhus.cgs +35285cc52bbb31d9b25d6144f54fa5b5 sim/testsuite/sim/frv/fr500/mqsubhss.cgs +d5b43c22363018a3259eb6849019a024 sim/testsuite/sim/frv/fr500/mqsubhus.cgs +d35335c0a9a7da8ef8224e724dc95c81 sim/testsuite/sim/frv/fr550/allinsn.exp +091a034f51a640f3113ea17c26e3b296 sim/testsuite/sim/frv/fr550/cmaddhss.cgs +ddaf6b5840f92b8d37a897bac56b86b0 sim/testsuite/sim/frv/fr550/cmaddhus.cgs +c41c0de91e307c8506c8c5275940f7ea sim/testsuite/sim/frv/fr550/cmcpxiu.cgs +9b75556c75c9bfb61102e93aa0b85be4 sim/testsuite/sim/frv/fr550/cmcpxru.cgs +14be5a3d28703927ea3b168b6140855d sim/testsuite/sim/frv/fr550/cmmachs.cgs +df6f7d84607830c79a2f338b8b6160f6 sim/testsuite/sim/frv/fr550/cmmachu.cgs +dea84ff288f50a75076a9c6df51682c6 sim/testsuite/sim/frv/fr550/cmqaddhss.cgs +d20b77015f938e4bcf50ebffae74fc6b sim/testsuite/sim/frv/fr550/cmqaddhus.cgs +d6946f604c4c119692ac621e5cdf0a92 sim/testsuite/sim/frv/fr550/cmqmachs.cgs +c28cd342558f4cc6ad9b33d7c80b45aa sim/testsuite/sim/frv/fr550/cmqmachu.cgs +9f27020e63e8992a63456f9092967d34 sim/testsuite/sim/frv/fr550/cmqsubhss.cgs +b13883bf53e547a18365378a79b4ff9a sim/testsuite/sim/frv/fr550/cmqsubhus.cgs +cae62d22839ef1abf864fd44a1087197 sim/testsuite/sim/frv/fr550/cmsubhss.cgs +1b1c3f8892f5ff1108650006f4f2318a sim/testsuite/sim/frv/fr550/cmsubhus.cgs +f564e7d684efbe7a682ba9aa24cf39ab sim/testsuite/sim/frv/fr550/dcpl.cgs +0bfbdf1314d6a04afa36ce4404a81bf2 sim/testsuite/sim/frv/fr550/dcul.cgs +cd733adfb1ef5d2f7d93d57183587d7a sim/testsuite/sim/frv/fr550/mabshs.cgs +55c8d941be619469d2bf80f7eba5a3cf sim/testsuite/sim/frv/fr550/maddaccs.cgs +269e14aaffa3452b360e1f0ddb12df93 sim/testsuite/sim/frv/fr550/maddhss.cgs +ffbb77202774953b6eb98f6329c3221c sim/testsuite/sim/frv/fr550/maddhus.cgs +aed0b1242d7c5a0eada01cb581ef44ab sim/testsuite/sim/frv/fr550/masaccs.cgs +594c6a9c3278bcc019e98aa44a86c22a sim/testsuite/sim/frv/fr550/mdaddaccs.cgs +7cdef8608795f0ed222e67db1343a635 sim/testsuite/sim/frv/fr550/mdasaccs.cgs +14183fbd685848d558ab84952c1271b1 sim/testsuite/sim/frv/fr550/mdsubaccs.cgs +85c318f9489df3a78af9171868d9e789 sim/testsuite/sim/frv/fr550/mmachs.cgs +7c4ba31a4b54c5449d932fceeeb3aa1d sim/testsuite/sim/frv/fr550/mmachu.cgs +f105b296560b5b75436069679f4d6dfd sim/testsuite/sim/frv/fr550/mmrdhs.cgs +5ade21b6577e4102c74e56fd9ac67d5d sim/testsuite/sim/frv/fr550/mmrdhu.cgs +252cdd83e9dd8de140e437bcc84a45a6 sim/testsuite/sim/frv/fr550/mqaddhss.cgs +4938bf73cdf15f5d4a195ccc1bc1a426 sim/testsuite/sim/frv/fr550/mqaddhus.cgs +7ccfed47ea8ad55515dab94b96d6babf sim/testsuite/sim/frv/fr550/mqmachs.cgs +aef3c4befd6509d86b1532ddbf3fb4a9 sim/testsuite/sim/frv/fr550/mqmachu.cgs +76e79dccff8084f4921e771c099fdbe0 sim/testsuite/sim/frv/fr550/mqmacxhs.cgs +a73a09a1e4d5df6332355e6558054066 sim/testsuite/sim/frv/fr550/mqsubhss.cgs +e3ef857df51606a95b919b802bc62434 sim/testsuite/sim/frv/fr550/mqsubhus.cgs +f7992a1f5e0512afb72f4ea8abf785ed sim/testsuite/sim/frv/fr550/mqxmachs.cgs +1d35c09a8a300edc364a00ba655ca259 sim/testsuite/sim/frv/fr550/mqxmacxhs.cgs +60a0aa6675f9b1d37f0b6b58e04e6aba sim/testsuite/sim/frv/fr550/msubaccs.cgs +26acdfc92872c06ef0f3750cda5f6f75 sim/testsuite/sim/frv/fr550/msubhss.cgs +90677e8af5e1904d14d9bfd3e562fcbb sim/testsuite/sim/frv/fr550/msubhus.cgs +45902a95cfa0b6432a1cbb6db50830b6 sim/testsuite/sim/frv/fr550/mtrap.cgs +57f7099366dbf0b511896d03b5343808 sim/testsuite/sim/frv/fr550/udiv.cgs +55cd07e74cc057a786a2a9c43ed5d8dc sim/testsuite/sim/frv/fr550/udivi.cgs +c6ab746acfbb43a0b62848e6626307be sim/testsuite/sim/frv/interrupts/Ipipe-fr400.cgs +fad5307c32c5fd7792da21d6fa8034a4 sim/testsuite/sim/frv/interrupts/Ipipe-fr500.cgs +1442aef29a1429ad5b417d6e072f0bed sim/testsuite/sim/frv/interrupts/badalign-fr550.cgs +bb56d8cd61856a2eceb509be16a37354 sim/testsuite/sim/frv/interrupts/badalign.cgs +ba84baad2c0fbc0fb425f3042fa91e04 sim/testsuite/sim/frv/interrupts/compound-fr550.cgs +e7920163cd59bc2dd0f5d977fc7566bd sim/testsuite/sim/frv/interrupts/compound.cgs +2a80a2eee2d47ba494278b13a0eae8e7 sim/testsuite/sim/frv/interrupts/data_store_error-fr550.cgs +3b7c9b823a6bdae97b790110baa1cd1b sim/testsuite/sim/frv/interrupts/data_store_error.cgs +dfeabfd77b473aa8a95f7049b362944d sim/testsuite/sim/frv/interrupts/fp_exception-fr550.cgs +26c8314f6b8c8534a84f9a98701aca07 sim/testsuite/sim/frv/interrupts/fp_exception.cgs +9dc2f73112811f25a5a15f53a6be64e2 sim/testsuite/sim/frv/interrupts/illinsn.cgs +be93394d8610eb7a13b316901ad8a9b5 sim/testsuite/sim/frv/interrupts/insn_access_error-fr550.cgs +bc6228cbbffde88aba638f1e9ef39ad5 sim/testsuite/sim/frv/interrupts/insn_access_error.cgs +d3bf79293e8377be411d124f213784e1 sim/testsuite/sim/frv/interrupts/mp_exception.cgs +d78319cc00e420d2ea14a943bacb5b73 sim/testsuite/sim/frv/interrupts/privileged_instruction.cgs +4dcb6ae1f3af2a946fccc0349454555e sim/testsuite/sim/frv/interrupts/regalign.cgs +a03ea7e55879465603afc8e54e656577 sim/testsuite/sim/frv/interrupts/reset.cgs +90377ce05b3a5bfdde34c7349008e3d3 sim/testsuite/sim/frv/interrupts/shadow_regs.cgs +026ab0d2d0845245adbc296619cc9d46 sim/testsuite/sim/frv/interrupts/timer.cgs +7e9bf038c823c2726a964b26f9a4671f sim/testsuite/sim/h8300/ChangeLog +ce415b253063a7fe5cf02f17fb48faab sim/testsuite/sim/h8300/addb.s +399b6e09a2ae39da12b2321cd0965b91 sim/testsuite/sim/h8300/addl.s +2dad02e99bd1422af83cb4353b7e63c0 sim/testsuite/sim/h8300/adds.s +9766c17a5c5cc1408ada3b9cc437ba28 sim/testsuite/sim/h8300/addw.s +8cbc4afc2f6b11b850e0aec04ed1a473 sim/testsuite/sim/h8300/addx.s +1b1082501d2ae954bf8cfe0ef39b83c2 sim/testsuite/sim/h8300/allinsn.exp +90637fa47d75134bb5869022a29f120c sim/testsuite/sim/h8300/andb.s +6fdb213d98f348f1c02d48ffcfd806e5 sim/testsuite/sim/h8300/andl.s +376c12070675b9d7dd2c58e70ee98842 sim/testsuite/sim/h8300/andw.s +6902ac6642088250609f8e019c17c156 sim/testsuite/sim/h8300/band.s +fce577f47862442fa9b2da616615c1d2 sim/testsuite/sim/h8300/bfld.s +363c9b0e04241d42714a73ac65312b9a sim/testsuite/sim/h8300/biand.s +0412ca2321a01a8b7c32897e3f32dd37 sim/testsuite/sim/h8300/bra.s +e2433fc36981757f93eb5bb4f1b039ac sim/testsuite/sim/h8300/brabc.s +c43286a0003746027f1e57893e29b060 sim/testsuite/sim/h8300/bset.s +dd6fabe64292ad56b43ca5532e790417 sim/testsuite/sim/h8300/cmpb.s +5d4de83de24b934dbec418f81b0fbc02 sim/testsuite/sim/h8300/cmpl.s +16151c89821d742e389f60a77a9c4214 sim/testsuite/sim/h8300/cmpw.s +4c711137a90bb2ba4b2f44ad3ef33ba7 sim/testsuite/sim/h8300/daa.s +7032f158ede5e9c1fe95569152aac2a7 sim/testsuite/sim/h8300/das.s +7038c79de7fb4f02cd5ef969e2cffd30 sim/testsuite/sim/h8300/dec.s +882cd22437078ea48acb50bb803cbbd5 sim/testsuite/sim/h8300/div.s +caa5a5b27cbcbfaea63298e864279ae4 sim/testsuite/sim/h8300/extl.s +a159e301d3202b02c3d6ac416aeedcf6 sim/testsuite/sim/h8300/extw.s +388f4ab3999f0a563801fbdec2667f71 sim/testsuite/sim/h8300/inc.s +c5cc1774fded69045dd1d5a31e4eecc7 sim/testsuite/sim/h8300/jmp.s +5745f4f097642a8d3aa1e6f949b20d72 sim/testsuite/sim/h8300/ldc.s +677c2ca0cf5c9c3c593a7a9274859bba sim/testsuite/sim/h8300/ldm.s +63a01cd1ac69acaa0cb441c4f1ef5b89 sim/testsuite/sim/h8300/mac.s +4e839f3223289908cd6e2ba525776dec sim/testsuite/sim/h8300/mova.s +7cf771780ab43e6a7a25ed05f8a17ee7 sim/testsuite/sim/h8300/movb.s +abfa7675b179fc4254e14cec675be772 sim/testsuite/sim/h8300/movl.s +c0f7ecf275c71ba8ba57b2098887abf4 sim/testsuite/sim/h8300/movmd.s +637fafb5b7e807abbb1f528bca9cc697 sim/testsuite/sim/h8300/movsd.s +8bfd3316d1c16f85273138771fdbbbf0 sim/testsuite/sim/h8300/movw.s +4925d8fc7e47b2223de921e76eefc6c0 sim/testsuite/sim/h8300/mul.s +2373f3011c78310592feef6fe9432f0a sim/testsuite/sim/h8300/neg.s +99f82cb39a007343d1a5bd8c71960fcb sim/testsuite/sim/h8300/nop.s +a1ed4f63b96068eaa77495745494ffea sim/testsuite/sim/h8300/not.s +a938731b6a18a4e389d565b373fdb164 sim/testsuite/sim/h8300/orb.s +62d2fe5825e86377f04ad0167a214c62 sim/testsuite/sim/h8300/orl.s +5d42a1f9b287e529549796fef4c879c8 sim/testsuite/sim/h8300/orw.s +b99bd4670fdfe75f10e37ea480d537f0 sim/testsuite/sim/h8300/rotl.s +f75f1bed46894927fbb7773bc84081fc sim/testsuite/sim/h8300/rotr.s +3b4dfe0168e63c6e80583c262c5de759 sim/testsuite/sim/h8300/rotxl.s +4eecc1e3c8c3ef39f35071a0d35c126e sim/testsuite/sim/h8300/rotxr.s +ffef0a19e06ed3716630c870e2c78e97 sim/testsuite/sim/h8300/shal.s +0b8a477e0fbf76499733fc12811aa4c6 sim/testsuite/sim/h8300/shar.s +0f85e20fbab15124e67dde283ee4b159 sim/testsuite/sim/h8300/shll.s +3b3ad8e7276c6719c8adfa92951bef0b sim/testsuite/sim/h8300/shlr.s +e1a2e3252f570905ffbdc48d6a44089d sim/testsuite/sim/h8300/stack.s +ebd21badf420c5cee8b0d88a08868304 sim/testsuite/sim/h8300/stc.s +9b63ff9fbde1e63acd708924198b7242 sim/testsuite/sim/h8300/subb.s +a63920fd12f48e551687aacc6bfae557 sim/testsuite/sim/h8300/subl.s +c55d9e46ef6b31eb575f129340b18dce sim/testsuite/sim/h8300/subs.s +db0176e7c9b6cb42862f2377e55312f5 sim/testsuite/sim/h8300/subw.s +e0e2129ddb10014bc62124746c911369 sim/testsuite/sim/h8300/subx.s +81e2e460e06fcf47b7ed621287bfbafa sim/testsuite/sim/h8300/tas.s +e889ba6121bfc3b32c11372b6d4c9dcd sim/testsuite/sim/h8300/testutils.inc +307b4b54b70c077beb6b886ed1dadc9d sim/testsuite/sim/h8300/xorb.s +8ea8bfb6cddf05ef11ea7fb068e218e6 sim/testsuite/sim/h8300/xorl.s +c2e57a11d5e455cef19248c2a0fb26b0 sim/testsuite/sim/h8300/xorw.s +16834904d188192c7fbb15f488c53087 sim/testsuite/sim/m32r/add.cgs +e9adf1458ab377d5d90d1678d2292bd5 sim/testsuite/sim/m32r/add3.cgs +8cf9213ee7ef813787645bc4c9e12727 sim/testsuite/sim/m32r/addi.cgs +a7b10e6f679c84fe5b2db48164037526 sim/testsuite/sim/m32r/addv.cgs +30cfed398315d692a3de98e4c67f90af sim/testsuite/sim/m32r/addv3.cgs +690ba3d9db8db10a35899c8eac122f65 sim/testsuite/sim/m32r/addx.cgs +787a6f21f2739736e0a79118443e311a sim/testsuite/sim/m32r/allinsn.exp +7d5b3e41f7f293b573606e13d0a5c301 sim/testsuite/sim/m32r/and.cgs +29e08614d0fde06b6322dad1cc619d93 sim/testsuite/sim/m32r/and3.cgs +f57a1ae6784adef83a83d0fc96e627d3 sim/testsuite/sim/m32r/bc24.cgs +b5eba276aa402a66811d04183ae7da9b sim/testsuite/sim/m32r/bc8.cgs +43914dad0473cf29fa8ba7483fcc42a1 sim/testsuite/sim/m32r/beq.cgs +aa647bf776c6497768956dd13b1bc0e6 sim/testsuite/sim/m32r/beqz.cgs +bcd9f3fee3d28ed1096a5ef6514c0538 sim/testsuite/sim/m32r/bgez.cgs +61391eba2b47c3b035c549673a100135 sim/testsuite/sim/m32r/bgtz.cgs +9041e76bd9e52d5245b6485c481ce1e3 sim/testsuite/sim/m32r/bl24.cgs +9be91c4daa50b174585b34804fadde45 sim/testsuite/sim/m32r/bl8.cgs +a38ca2fe69cd52716f929b7be6ee5690 sim/testsuite/sim/m32r/blez.cgs +b30f0ad9c59b0374e5b52f24e549ae36 sim/testsuite/sim/m32r/bltz.cgs +1b3b8a230f2693ae45a566995a0b9775 sim/testsuite/sim/m32r/bnc24.cgs +ae67e7de7ffee3af12ef63c7770eb6be sim/testsuite/sim/m32r/bnc8.cgs +7a9b903b84abb5fead9cdfdde1804492 sim/testsuite/sim/m32r/bne.cgs +2bd489b3cdd376a0a6b2de5f4a26712f sim/testsuite/sim/m32r/bnez.cgs +ae803eba46d3c6a6aa1c741aec2783be sim/testsuite/sim/m32r/bra24.cgs +0ebb2e3161db55a3203b65392361b6bd sim/testsuite/sim/m32r/bra8.cgs +d863c2fc17c8b7509aa0996e8a3f15b4 sim/testsuite/sim/m32r/cmp.cgs +7d8da1455d2cd44a51707b07b4b00977 sim/testsuite/sim/m32r/cmpi.cgs +1e2a8c3e0cc7b5988cef7334bf2e14bf sim/testsuite/sim/m32r/cmpu.cgs +0e4b1ac17d86c08b1d98e90ee379e7c8 sim/testsuite/sim/m32r/cmpui.cgs +42509b9f2bc28c62f815e3094e75f4ea sim/testsuite/sim/m32r/div.cgs +fc14b150efe66c251e584a8490ab411c sim/testsuite/sim/m32r/divu.cgs +f3f4a05a6d442fdb1a2dbe82fbc22d5e sim/testsuite/sim/m32r/hello.ms +62c53b4fa4929b659e1b8f3dce7ed101 sim/testsuite/sim/m32r/hw-trap.ms +72ae1c84434e74d7a53d09e002ab9830 sim/testsuite/sim/m32r/jl.cgs +3f2b2701b3579de8839bd35d25076d03 sim/testsuite/sim/m32r/jmp.cgs +34c7f8c3e919f9ba0f0b3c7caa68f237 sim/testsuite/sim/m32r/ld-d.cgs +e0e5a244234e059b9099534cde98fd29 sim/testsuite/sim/m32r/ld-plus.cgs +dcbcafa8b504f5c1750e3a7f33d06b04 sim/testsuite/sim/m32r/ld.cgs +a1584b288866f94579bbf2981c7d812e sim/testsuite/sim/m32r/ld24.cgs +8e71d37539927768d17f19c43cfe41bf sim/testsuite/sim/m32r/ldb-d.cgs +31a4c374f7d38d4214300cb58342cb7e sim/testsuite/sim/m32r/ldb.cgs +55e96d8c138d454b947b0c627268410a sim/testsuite/sim/m32r/ldh-d.cgs +101e467bd8d9570809bd743b775e657d sim/testsuite/sim/m32r/ldh.cgs +29dd50ce15ab9c0d67791901e45a791d sim/testsuite/sim/m32r/ldi16.cgs +ddcce0a4e903b1df7a8d3f9d07b133b4 sim/testsuite/sim/m32r/ldi8.cgs +5422abf5a05ea36c524bac97c177f79a sim/testsuite/sim/m32r/ldub-d.cgs +b464f9a46248faed5a856867decd109b sim/testsuite/sim/m32r/ldub.cgs +38f45019c0a3b58549b0dba4f6595f20 sim/testsuite/sim/m32r/lduh-d.cgs +d0c711109b91fb82235f2c7de6be93e0 sim/testsuite/sim/m32r/lduh.cgs +17eccc048da153abc362bee34fe42579 sim/testsuite/sim/m32r/lock.cgs +a249bb8bdbaad16488d816dbd85eb1a1 sim/testsuite/sim/m32r/machi.cgs +7d3d647734fda959f3b1e738c2b90222 sim/testsuite/sim/m32r/maclo.cgs +42e2898d542715203fac38dbabe95593 sim/testsuite/sim/m32r/macwhi.cgs +606cf06f01516f620ade2833b6f4272f sim/testsuite/sim/m32r/macwlo.cgs +17924a13af249ae4d0a6df996e622124 sim/testsuite/sim/m32r/misc.exp +497cfa2e1bc18e2fadb92c99fbcadcab sim/testsuite/sim/m32r/mul.cgs +0ea66074ee25fd61d52074d38b4358e6 sim/testsuite/sim/m32r/mulhi.cgs +951d325ba4e7036401fa243439c0f27f sim/testsuite/sim/m32r/mullo.cgs +518d60a9ec3ed23e3da2aff0b1456ac0 sim/testsuite/sim/m32r/mulwhi.cgs +fbed9d4fe93ebbb695228b4a94655dd5 sim/testsuite/sim/m32r/mulwlo.cgs +ecaba0191d387d8875378bf790693bbe sim/testsuite/sim/m32r/mv.cgs +60ce74d2420a29592309f2f3cbf0bb27 sim/testsuite/sim/m32r/mvfachi.cgs +ab51940820c840824c1309f87b0c7430 sim/testsuite/sim/m32r/mvfaclo.cgs +9c2236dea1f22183f110260aac6e7821 sim/testsuite/sim/m32r/mvfacmi.cgs +aa1ec114448f408800129388f774de40 sim/testsuite/sim/m32r/mvfc.cgs +ee8c3058b6a4fc408f0725c7e0027956 sim/testsuite/sim/m32r/mvtachi.cgs +8cfc6346c5ce5f4e7464057b25ec31b7 sim/testsuite/sim/m32r/mvtaclo.cgs +8f0cac941aa884623e680f3e4ac0c8b1 sim/testsuite/sim/m32r/mvtc.cgs +98c363f615a992eebb741216c4b99238 sim/testsuite/sim/m32r/neg.cgs +57368ba4c4be662e4d7e09c2fbf73007 sim/testsuite/sim/m32r/nop.cgs +b0703d4f2678b98efa516375d14989d8 sim/testsuite/sim/m32r/not.cgs +9778769d1c0af0c0fc330032708ff835 sim/testsuite/sim/m32r/or.cgs +4adb31d9941df9283e7d046457611c97 sim/testsuite/sim/m32r/or3.cgs +9171592763b85a01ee783cc5c814c696 sim/testsuite/sim/m32r/rac.cgs +ec2520e6aae9332a6671d4c8a8e5b045 sim/testsuite/sim/m32r/rach.cgs +241464dd5ebda3e9291399db7f07fde6 sim/testsuite/sim/m32r/rem.cgs +79728809577a7966c7f6d3e74eeeab11 sim/testsuite/sim/m32r/remu.cgs +e200d0626a3a782b1ba827d77008622c sim/testsuite/sim/m32r/rte.cgs +966058aa7f21ef4a7874f1a0d9888543 sim/testsuite/sim/m32r/seth.cgs +672b4886a81c13ca0bf05d1df568df5f sim/testsuite/sim/m32r/sll.cgs +37da8b574adf3cb6f65a7119fab322a7 sim/testsuite/sim/m32r/sll3.cgs +8a79f97b82a93537f9d0afd46d1ce63e sim/testsuite/sim/m32r/slli.cgs +b29c344695a538384d37acf2acf3f974 sim/testsuite/sim/m32r/sra.cgs +237457a459b83e66c0a0f95ba0842910 sim/testsuite/sim/m32r/sra3.cgs +c86fb3aef80e809c5161380443aec696 sim/testsuite/sim/m32r/srai.cgs +cda1698f1a6d640498ce3e6cd47add4f sim/testsuite/sim/m32r/srl.cgs +806b43d4fd12897c2b02e9b2f876b308 sim/testsuite/sim/m32r/srl3.cgs +e43074ac62cc10354b7a7759fe2fe869 sim/testsuite/sim/m32r/srli.cgs +15a9f901cebcbc565c224f6c61c07326 sim/testsuite/sim/m32r/st-d.cgs +88d455c342dfa2947283cd4e7b82f3a1 sim/testsuite/sim/m32r/st-minus.cgs +c66238280149c9f42dd1e19852afd136 sim/testsuite/sim/m32r/st-plus.cgs +a79a2f93fa80d613b872cc172ef3e9e8 sim/testsuite/sim/m32r/st.cgs +81e73b1946f04046a562428a766077ec sim/testsuite/sim/m32r/stb-d.cgs +d6a79a79477689d7e9bf45ff48a1d65c sim/testsuite/sim/m32r/stb.cgs +5b9e264b3d7e3e123150e7933e9776bf sim/testsuite/sim/m32r/sth-d.cgs +cc4e95eb280ae19c0d22b639bc9fc601 sim/testsuite/sim/m32r/sth.cgs +faf25008374bb5be6c2d003c079b6b62 sim/testsuite/sim/m32r/sub.cgs +8a180be9e21c1fcadb9dbbc751093bb2 sim/testsuite/sim/m32r/subv.cgs +9bd48d851532a2d84c1edf2872c9a66e sim/testsuite/sim/m32r/subx.cgs +45e6e4177ecd2fe6a1ecde8fcb839662 sim/testsuite/sim/m32r/testutils.inc +54efa34ea2ee72560aa9d26f7f557879 sim/testsuite/sim/m32r/trap.cgs +cfd913f0a5ee4bd41656b5e4283c96d1 sim/testsuite/sim/m32r/unlock.cgs +faf23b2f12b51357e3e72b13e79ecc7c sim/testsuite/sim/m32r/uread16.ms +9c7bdcfc3ad3791fa0248573c2307cf9 sim/testsuite/sim/m32r/uread32.ms +6df2ea19b2030cc2ad6f1631641587a6 sim/testsuite/sim/m32r/uwrite16.ms +749a9149d30e113900b3f089779740ed sim/testsuite/sim/m32r/uwrite32.ms +6f6c3fdb3474157358c545914bf2c510 sim/testsuite/sim/m32r/xor.cgs +3795134a6b03341f5a6480f66e7c29f1 sim/testsuite/sim/m32r/xor3.cgs +2303ec0b7c85c4dae0a176a8fb013a23 sim/testsuite/sim/mips/ChangeLog +db173789cf837f57257b44c19e0b915b sim/testsuite/sim/mips/basic.exp +b19e0c53b685c87920887bc87dba4579 sim/testsuite/sim/mips/sanity.s +457ea0e4004e3c71d5233f89df113f8c sim/testsuite/sim/mips/testutils.inc +39ec50dfc186bd1d1ca11891f351a9bb sim/testsuite/sim/sh/ChangeLog +282a3539572ea760a8d7a480a27800d4 sim/testsuite/sim/sh/add.s +2e32e434523a02fba516046b4cbed5e8 sim/testsuite/sim/sh/allinsn.exp +f8dca2ef83e73c5c462ef000c13478bb sim/testsuite/sim/sh/and.s +69150191761fac26b8276af2f85efd90 sim/testsuite/sim/sh/dmxy.s +e4e686dacc645b9fc1114279b13b460b sim/testsuite/sim/sh/fabs.s +7fcd022e6881b031f0deee8c6816a79a sim/testsuite/sim/sh/fadd.s +22f8beefa505dc232a3593e167d51b2b sim/testsuite/sim/sh/fcmpeq.s +f98492eeeab950ed63e6c2d52a3c57d8 sim/testsuite/sim/sh/fcmpgt.s +45e3b96fa5b2e581805f106c3d99f968 sim/testsuite/sim/sh/fcnvds.s +7f6673539421b7915a57f34826612d75 sim/testsuite/sim/sh/fcnvsd.s +ea612dc8f08a57ade93a63b0b6563e5c sim/testsuite/sim/sh/fdiv.s +f008ac5e491f8ceab68b9f59056e9b16 sim/testsuite/sim/sh/fipr.s +b43309a7445615ae8abafb4900d4f3e7 sim/testsuite/sim/sh/fldi0.s +5fdca3286426034467b63b36d3a3c5e2 sim/testsuite/sim/sh/fldi1.s +47831a2ea8e21901de14ee85de649e42 sim/testsuite/sim/sh/flds.s +47a2df7f664eaff06846045d7e64b5ce sim/testsuite/sim/sh/float.s +04ba23f9a7e46a261c68dc833abac5a3 sim/testsuite/sim/sh/fmac.s +6074ab626f6f749947d90dad804223a8 sim/testsuite/sim/sh/fmov.s +c3b63bb6fbe1f996d7e66e6ed5ef9f32 sim/testsuite/sim/sh/fmul.s +e548ee358487284309e5b5717cabf0f9 sim/testsuite/sim/sh/fneg.s +0b43bcfde07c09c6103965070e9046ae sim/testsuite/sim/sh/fpchg.s +9b040b83149755d82c2328509c12535e sim/testsuite/sim/sh/frchg.s +cd42365d5bc0d1bb4979cdfd320ce433 sim/testsuite/sim/sh/fschg.s +f5d3cc68031f17d500295fbcd18bb1f7 sim/testsuite/sim/sh/fsqrt.s +92f8a202d1e874f537d74831851dba46 sim/testsuite/sim/sh/fsub.s +ed2aa1abfc2026579333e2253c838294 sim/testsuite/sim/sh/ftrc.s +b1d24d30151886ff5bf5bc86758709b1 sim/testsuite/sim/sh/ldrc.s +954b6cdc60b0808db2732f2f65d65983 sim/testsuite/sim/sh/loop.s +d0c8446d0ede1ebe79245b96cb002c8d sim/testsuite/sim/sh/macl.s +48d214fbad43f9efc8c0cc2014239984 sim/testsuite/sim/sh/macw.s +ac143ce8d55a865d8b4946d30368e814 sim/testsuite/sim/sh/movi.s +b07d68ae2523ae371be0b115d5cc9253 sim/testsuite/sim/sh/movli.s +7c4dae24fda79de6de7776bcbe4f21b0 sim/testsuite/sim/sh/movua.s +0c12a523abb2532f2abb3eeeff95cfce sim/testsuite/sim/sh/movxy.s +fcad598d555a1a24eaa76710c494e71b sim/testsuite/sim/sh/pabs.s +d8c8b220768728a015ad5b9fbb9d2c90 sim/testsuite/sim/sh/padd.s +8f6a40a17e345540ee1f269d29aa5d9a sim/testsuite/sim/sh/paddc.s +be1710af076cee30f8262a7bef8685ab sim/testsuite/sim/sh/pand.s +532a7fc5abd000fbfcdfa409da20f0fa sim/testsuite/sim/sh/pclr.s +4152aee3945ac6afc68b16dd206f851a sim/testsuite/sim/sh/pdec.s +c3726f7efa272c1305bc3a7ad9225e5b sim/testsuite/sim/sh/pdmsb.s +6ee03b6e9943d9a05f82c8206ce794cf sim/testsuite/sim/sh/pinc.s +e7a32d44b0b0d9d4309d241eaf991fcf sim/testsuite/sim/sh/pmuls.s +dc3cb25df84ca51ea42371f6a4dec6aa sim/testsuite/sim/sh/prnd.s +e8ca39483f9c71cfdb1b1b03069df2bc sim/testsuite/sim/sh/pshai.s +81c176582a8667af8f6c72a2728737ab sim/testsuite/sim/sh/pshar.s +1f420e9b6f74d6d03ae952bdffbd8799 sim/testsuite/sim/sh/pshli.s +eed4f3e2827f2bdcff0fd693f4be62d0 sim/testsuite/sim/sh/pshlr.s +698d502e8fcf6a8e8193fee2a1274e94 sim/testsuite/sim/sh/psub.s +40b3372c773573dc611cbd9c64efa162 sim/testsuite/sim/sh/pswap.s +73bee7558210c5db604fb0929091597e sim/testsuite/sim/sh/sett.s +19200c14eefed0db8e7e3f7b7df9a7da sim/testsuite/sim/sh/shll.s +c56c6a1871d8e035a8eb50e2c1cb89f0 sim/testsuite/sim/sh/shll16.s +12c9ce87dbd160a77d59f6aa29ddd375 sim/testsuite/sim/sh/shll2.s +bd6af3c86e2f58147320c9b2961781cd sim/testsuite/sim/sh/shll8.s +9c9f493d16eacff7f4315bd95a0c8b18 sim/testsuite/sim/sh/shlr.s +f379912c20dda0ba7cd86cecc19eca47 sim/testsuite/sim/sh/shlr16.s +ddfdbd007dc52a5ecc5e1981dc705462 sim/testsuite/sim/sh/shlr2.s +eff7f8091a30f489f6cf9bb2c8aeac8d sim/testsuite/sim/sh/shlr8.s +5fb60364b4fd1e6b5d37ccdd4c3f4540 sim/testsuite/sim/sh/swap.s +84db70d9d853cc339ac12070acdfb063 sim/testsuite/sim/sh/testutils.inc +33ade97f3bd72f515783037150efae9c sim/v850/ChangeLog +5155b7f1ab78c062f466a9d5462058d4 sim/v850/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/v850/acconfig.h +dc553d113147dcc545cf06254dc945cd sim/v850/config.in +6ab57e58e6db8fa8c9dd7fee520f44eb sim/v850/configure +fa12dcce375574441b85dfd39d7fffd9 sim/v850/configure.in +d8b6b349332fde351e242d3735926144 sim/v850/interp.c +5c6de75cf871f9762d4a7c341dcd4afc sim/v850/sim-main.h +a80e2ec5e4a78870d477bc970b793381 sim/v850/simops.c +bee4a6a9ecb7e78bab13c75961a998e9 sim/v850/simops.h +61a55a15e7ef4e104adb33aaa7f55b66 sim/v850/v850-dc +42de87877c720a7cd8995343b08d549d sim/v850/v850.igen +ec996f52079c4afb02cb86bdd2fd188f sim/v850/v850_sim.h +5df75b029b7d11dbf2a51b9db06a5f73 sim/z8k/ChangeLog +faadde8183eda0d559355f657629b68a sim/z8k/Makefile.in +c277414b921bc85437478d47aa2ff522 sim/z8k/acconfig.h +d364e878ba599e906e2853a08b98d8a6 sim/z8k/comped1.c +9c799b41905ed7c5d0cfae2459460b9a sim/z8k/comped2.c +94d11974a649742abd5ecc2b858349a0 sim/z8k/comped3.c +6c3a315eb92e8aff644d8bbf7a37f20c sim/z8k/compedb3.c +a95a70664e413801a597fa28256576f9 sim/z8k/config.in +8a49a1c85c9396bc86c99d065816d8a1 sim/z8k/configure +b45960de07956b3c81ae57be85df9a7f sim/z8k/configure.in +5f389e133935b7e2861258cb13ad9d8f sim/z8k/iface.c +e0a7f1a5307479cfd2aaf1636797b4d1 sim/z8k/inlines.h +987ebce1db18d972c3ec54932fa4dfec sim/z8k/mem.c +c4853bc5877f542f6cbd6faca324fdc8 sim/z8k/mem.h +ff528a4e4622b0cdd7a063d2c700da80 sim/z8k/quick.c +a9976641e44d799afcf81c16c8a51aeb sim/z8k/sim.h +0db0b761c5d2d2a3c88f26fcd128f783 sim/z8k/support.c +ad0459fe42ddc739f638464c2e247a30 sim/z8k/syscall.h +1b9ee9eab7ed5ca759bce92d8c328ab3 sim/z8k/tconfig.in +96aa639f2f92f44e518dd98789cc024c sim/z8k/tm.h +57df594ab355b7927903348b3e82285a sim/z8k/writecode.c +70672a8bf938cfcb57c23c528341ab88 src-release +e8b74bd777dcff9aa7eaff1cff0208f7 symlink-tree +b97f1c282c19b00608b1680ad02ae227 texinfo/texinfo.tex +05b44465f4af35156e0c7a8488e81a26 utils/ChangeLog +77c78f52a1a36f45522d1ca8abe2d20f utils/Makefile.def +89fd5f3c7be25e891dc0b8e421194f5c utils/Makefile.in +f310368ddfe659241ee0a9521987e2d2 utils/Makefile.tpl +098272ad15083d8dfe61063a7806718b utils/configure +9303c3616d18758b7ea724270d75b842 utils/configure.in +a6c3ed07cc948867dda4df4b54ac95c7 utils/misc/Makefile.in +725839ceb46028560086f2838a0bd721 utils/misc/configure.in +1713db4c79349e46bb17ce622b0a4391 utils/misc/doschk/ChangeLog +b073a668d04466111b835be54a70f94d utils/misc/doschk/Makefile.in +856cd577c4065b6a88bfe22b972f369c utils/misc/doschk/README +8f92e4be8aa509042df8306472702b4a utils/misc/doschk/configure +6d789396da7ce75cf11c71652cc2527e utils/misc/doschk/configure.in +4b947c6ce6448071cd34af078be1bf38 utils/misc/doschk/doschk.c +074fc3e1b6f02aa19f2b2a5000a6c80a utils/sparclite/ChangeLog +a7eab8e0f7767eb222535d3b2be6cb98 utils/sparclite/Makefile.in +cf263682d341fd6fc4ec46522ef82918 utils/sparclite/README +a0d6d909da1925163b08e0c5903f2ac8 utils/sparclite/aload.c +9835dec4cf0cea9d3bdcfc2bcb2842aa utils/sparclite/configure +2e793a5a9ee3ead3235d3fd0597f3025 utils/sparclite/configure.in +0666e31023bf6c528ffc76d10d5e76ec utils/sparclite/eload.c +1332cd1f56dbc282007e210a4604a314 utils/sparclite/Makefile +42a5e31a79435eb362018fa564cd9751 utils/sparclite/config.status +43004c6e4ddfd3c408c5edc905c470b2 utils/spu/ChangeLog +d40779a37117b757874d8e683178f55b utils/spu/Makefile.in +70c7d7e8a8e7afce3c0e579af2b00a1e utils/spu/README +8266b864db4e3050a104f9d7e89e4509 utils/spu/configure +325f4f18f23ec8f6ee7592f9d62e5687 utils/spu/configure.in +57e4dc6faccea960276253043ef8f777 utils/spu/spu.c +e9b8f681b1d1ee9fae2602f84d81f737 utils/wince/ChangeLog +17009faf740fe6a6c16cd11e6e850c75 utils/wince/Makefile.in +beab589fc6063ab45deaec34a4545995 utils/wince/cesetup.c +5ffb0d64070cd6e985ad40841c497c5c utils/wince/configure +d26d2917a7be8a0b4afded813cca167f utils/wince/configure.in +fed14eeefb89ace86cef8e5bb5ddc3c3 utils/wince/config.status +5549a1e050058444e22fbb0a80fd32f0 utils/wince/Makefile +7588c5103af27cc93537977f059f52dc ylwrap diff --git a/contrib/gdb/missing b/contrib/gdb/missing new file mode 100755 index 00000000000..25c96676def --- /dev/null +++ b/contrib/gdb/missing @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/contrib/gdb/mkinstalldirs b/contrib/gdb/mkinstalldirs new file mode 100755 index 00000000000..6fbe5e11762 --- /dev/null +++ b/contrib/gdb/mkinstalldirs @@ -0,0 +1,150 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2004-02-15.20 + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit 0 + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/contrib/gdb/move-if-change b/contrib/gdb/move-if-change new file mode 100755 index 00000000000..ee1b348beeb --- /dev/null +++ b/contrib/gdb/move-if-change @@ -0,0 +1,32 @@ +#!/bin/sh + +# Copyright (C) 1996 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if +test -r $2 +then +if +cmp $1 $2 > /dev/null +then +echo $2 is unchanged +rm -f $1 +else +mv -f $1 $2 +fi +else +mv -f $1 $2 +fi diff --git a/contrib/gdb/src-release b/contrib/gdb/src-release new file mode 100644 index 00000000000..42d5c205ee3 --- /dev/null +++ b/contrib/gdb/src-release @@ -0,0 +1,336 @@ +# Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, +# 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# This Makefile contains release scripts for gdb, binutils, and other +# packages which live in src. It used to be part of the top level Makefile, +# but that turned out to be very messy and hard to maintain. + +# This stuff really ought to be cleaned up and turned into something other +# than a Makefile. As it is it's heavily recursive. + +# This is the name of this script (!). Needed due to horrible recursion. +SELF = src-release + +SHELL = /bin/sh + +BZIPPROG = bzip2 +MD5PROG = md5sum + +# pwd command to use. Allow user to override default by setting PWDCMD in +# the environment to account for automounters. The make variable must not +# be called PWDCMD, otherwise the value set here is passed to make +# subprocesses and overrides the setting from the user's environment. +PWD = $${PWDCMD-pwd} + +# +# Support for building net releases + +# Files in devo used in any net release. +# ChangeLog omitted because it may refer to files which are not in this +# distribution (perhaps it would be better to include it anyway). +DEVO_SUPPORT= README Makefile.in configure configure.in \ + config.guess config.if config.sub config move-if-change \ + COPYING COPYING.LIB install-sh config-ml.in symlink-tree \ + mkinstalldirs ltconfig ltmain.sh missing ylwrap \ + libtool.m4 gettext.m4 ltcf-c.sh ltcf-cxx.sh ltcf-gcj.sh \ + Makefile.def Makefile.tpl src-release + +# Files in devo/etc used in any net release. +# ChangeLog omitted because it may refer to files which are not in this +# distribution (perhaps it would be better to include it anyway). +ETC_SUPPORT= Makefile.in configure configure.in standards.texi \ + make-stds.texi standards.info* configure.texi configure.info* \ + configbuild.* configdev.* fdl.texi texi2pod.pl + + +# When you use `make setup-dirs' or `make taz' you should always redefine +# this macro. +SUPPORT_FILES = list-of-support-files-for-tool-in-question + +# NOTE: No double quotes in the below. It is used within shell script +# as VER="$(VER)" +VER = ` if grep 'AM_INIT_AUTOMAKE.*BFD_VERSION' $(TOOL)/configure.in >/dev/null 2>&1; then \ + sed < bfd/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'; \ + elif grep AM_INIT_AUTOMAKE $(TOOL)/configure.in >/dev/null 2>&1; then \ + sed < $(TOOL)/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'; \ + elif test -f $(TOOL)/version.in; then \ + head -1 $(TOOL)/version.in; \ + elif grep VERSION $(TOOL)/Makefile.in > /dev/null 2>&1; then \ + sed < $(TOOL)/Makefile.in -n 's/^VERSION *= *//p'; \ + else \ + echo VERSION; \ + fi` +PACKAGE = $(TOOL) + +.PHONY: taz +taz: $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex + $(MAKE) -f $(SELF) do-proto-toplev \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + $(MAKE) -f $(SELF) do-md5sum \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + $(MAKE) -f $(SELF) do-tar \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + $(MAKE) -f $(SELF) do-bz2 \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + +.PHONY: gdb-tar +gdb-tar: $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex + $(MAKE) -f $(SELF) do-proto-toplev \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + $(MAKE) -f $(SELF) do-md5sum \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + $(MAKE) -f $(SELF) do-djunpack \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + $(MAKE) -f $(SELF) do-tar \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + +.PHONY: gdb-taz +gdb-taz: gdb-tar $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex + $(MAKE) -f $(SELF) gdb-tar \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + $(MAKE) -f $(SELF) do-bz2 \ + TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(SUPPORT_FILES)" + +.PHONY: do-proto-toplev +do-proto-toplev: $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex + echo "==> Making $(PACKAGE)-$(VER)/" + # Take out texinfo from a few places. + sed -e '/^all\.normal: /s/\all-texinfo //' \ + -e '/^ install-texinfo /d' \ + tmp + mv -f tmp Makefile.in + # + ./configure i686-pc-linux-gnu + $(MAKE) configure-host configure-target \ + ALL_GCC="" ALL_GCC_C="" ALL_GCC_CXX="" \ + CC_FOR_TARGET="$(CC)" CXX_FOR_TARGET="$(CXX)" + # Make links, and run "make diststuff" or "make info" when needed. + rm -rf proto-toplev ; mkdir proto-toplev + set -e ; dirs="$(TOOL) $(DEVO_SUPPORT) $(SUPPORT_FILES)" ; \ + for d in $$dirs ; do \ + if [ -d $$d ]; then \ + if [ ! -f $$d/Makefile ] ; then true ; \ + elif grep '^diststuff:' $$d/Makefile >/dev/null ; then \ + (cd $$d ; $(MAKE) diststuff ) || exit 1 ; \ + elif grep '^info:' $$d/Makefile >/dev/null ; then \ + (cd $$d ; $(MAKE) info ) || exit 1 ; \ + fi ; \ + if [ -d $$d/proto-$$d.dir ]; then \ + ln -s ../$$d/proto-$$d.dir proto-toplev/$$d ; \ + else \ + ln -s ../$$d proto-toplev/$$d ; \ + fi ; \ + else ln -s ../$$d proto-toplev/$$d ; fi ; \ + done + cd etc && $(MAKE) info + $(MAKE) distclean + # Kludge for pr gdb/708. 'configure' configures in + # dejagnu/example/calc, but 'make distclean' does not clean in + # dejagnu/example. Someday somebody might fix this in dejagnu, + # and then import a new dejagnu into sourceware. Right now, a + # couple of 'rm' commands will get the gdb snapshots working + # again. -- chastain 2003-08-15 + rm -f dejagnu/example/calc/config.status + rm -f dejagnu/example/calc/config.log + # Kludge for pr gdb/857. intl/Makefile.in lacks a couple + # of files in the distclean rule. Zack W is planning to make + # the gcc version of intl/ the master version and then push + # that version to src soon. See: + # http://sources.redhat.com/ml/binutils/2003-07/msg00032.html + # After the src version of intl/ is upgraded, we can look at + # moving this logic into intl/Makefile.in distclean rule + # if it is still needed. -- chastain 2003-09-12 + rm -f intl/config.cache + rm -f intl/config.status + rm -f intl/config.h + rm -f intl/stamp-h + # + mkdir proto-toplev/etc + (cd proto-toplev/etc; \ + for i in $(ETC_SUPPORT); do \ + ln -s ../../etc/$$i . ; \ + done) + # + # Take out texinfo from configurable dirs + rm proto-toplev/configure.in + sed -e '/^host_tools=/s/texinfo //' \ + proto-toplev/configure.in + # + mkdir proto-toplev/texinfo + ln -s ../../texinfo/texinfo.tex proto-toplev/texinfo/ + if test -r texinfo/util/tex3patch ; then \ + mkdir proto-toplev/texinfo/util && \ + ln -s ../../../texinfo/util/tex3patch proto-toplev/texinfo/util ; \ + else true; fi + chmod -R og=u . || chmod og=u `find . -print` + # + # Create .gmo files from .po files. + for f in `find . -name '*.po' -type f -print`; do \ + msgfmt -o `echo $$f | sed -e 's/\.po$$/.gmo/'` $$f ; \ + done + # + -rm -f $(PACKAGE)-$(VER) + ln -s proto-toplev $(PACKAGE)-$(VER) + +CVS_NAMES= \( -name CVS -o -name '.cvsignore' \) + +.PHONY: do-tar +do-tar: + echo "==> Making $(PACKAGE)-$(VER).tar" + -rm -f $(PACKAGE)-$(VER).tar + find $(PACKAGE)-$(VER) -follow $(CVS_NAMES) -prune \ + -o -type f -print \ + | tar cTfh - $(PACKAGE)-$(VER).tar + +.PHONY: do-bz2 +do-bz2: + echo "==> Bzipping $(PACKAGE)-$(VER).tar.bz2" + -rm -f $(PACKAGE)-$(VER).tar.bz2 + $(BZIPPROG) -v -9 $(PACKAGE)-$(VER).tar + +.PHONY: do-md5sum +do-md5sum: + echo "==> Adding md5 checksum to top-level directory" + cd proto-toplev && find * -follow $(CVS_NAMES) -prune \ + -o -type f -print \ + | xargs $(MD5PROG) > ../md5.sum + mv md5.sum proto-toplev + +.PHONY: do-djunpack +do-djunpack: + echo "==> Adding updated djunpack.bat to top-level directory" + echo - 's /gdb-[0-9\.]*/$(PACKAGE)-'"$(VER)"'/' + sed < djunpack.bat > djunpack.new \ + -e 's/gdb-[0-9][0-9\.]*/$(PACKAGE)-'"$(VER)"'/' + mv djunpack.new djunpack.bat + -rm -f proto-toplev/djunpack.bat + ln -s ../djunpack.bat proto-toplev/djunpack.bat + +TEXINFO_SUPPORT= texinfo/texinfo.tex +DIST_SUPPORT= $(DEVO_SUPPORT) $(TEXINFO_SUPPORT) + +.PHONY: gas.tar.bz2 +GAS_SUPPORT_DIRS= bfd include libiberty opcodes intl setup.com makefile.vms mkdep +gas.tar.bz2: $(DIST_SUPPORT) $(GAS_SUPPORT_DIRS) gas + $(MAKE) -f $(SELF) taz TOOL=gas \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(GAS_SUPPORT_DIRS)" + +# The FSF "binutils" release includes gprof and ld. +.PHONY: binutils.tar.bz2 +BINUTILS_SUPPORT_DIRS= bfd gas include libiberty opcodes ld gprof intl setup.com makefile.vms mkdep cpu +binutils.tar.bz2: $(DIST_SUPPORT) $(BINUTILS_SUPPORT_DIRS) binutils + $(MAKE) -f $(SELF) taz TOOL=binutils \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(BINUTILS_SUPPORT_DIRS)" + +.PHONY: gas+binutils.tar.bz2 +GASB_SUPPORT_DIRS= $(GAS_SUPPORT_DIRS) binutils ld gprof +gas+binutils.tar.bz2: $(DIST_SUPPORT) $(GASB_SUPPORT_DIRS) gas + $(MAKE) -f $(SELF) taz TOOL=gas \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(GASB_SUPPORT_DIRS)" + +GNATS_SUPPORT_DIRS=include libiberty send-pr +gnats.tar.bz2: $(DIST_SUPPORT) $(GNATS_SUPPORT_DIRS) gnats + $(MAKE) -f $(SELF) taz TOOL=gnats \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(GNATS_SUPPORT_DIRS)" + +.PHONY: gdb.tar.bz2 +GDB_SUPPORT_DIRS= bfd include libiberty mmalloc opcodes readline sim utils intl +gdb.tar.bz2: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-taz TOOL=gdb \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(GDB_SUPPORT_DIRS)" +.PHONY: gdb.tar +gdb.tar: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-tar TOOL=gdb \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(GDB_SUPPORT_DIRS)" + +DEJAGNU_SUPPORT_DIRS= tcl expect libiberty +.PHONY: dejagnu.tar.bz2 +dejagnu.tar.bz2: $(DIST_SUPPORT) $(DEJAGNU_SUPPORT_DIRS) dejagnu + $(MAKE) -f $(SELF) gdb-taz TOOL=dejagnu \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(DEJAGNU_SUPPORT_DIRS)" +.PHONY: dejagnu.tar +dejagnu.tar: $(DIST_SUPPORT) $(DEJAGNU_SUPPORT_DIRS) dejagnu + $(MAKE) -f $(SELF) gdb-tar TOOL=dejagnu \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(DEJAGNU_SUPPORT_DIRS)" + +.PHONY: gdb+dejagnu.tar.bz2 +GDBD_SUPPORT_DIRS= $(GDB_SUPPORT_DIRS) tcl expect dejagnu +gdb+dejagnu.tar.bz2: $(DIST_SUPPORT) $(GDBD_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-taz TOOL=gdb PACKAGE=gdb+dejagnu \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(GDBD_SUPPORT_DIRS)" +.PHONY: gdb+dejagnu.tar +gdb+dejagnu.tar: $(DIST_SUPPORT) $(GDBD_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-tar TOOL=gdb PACKAGE=gdb+dejagnu \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(GDBD_SUPPORT_DIRS)" + +.PHONY: insight.tar.bz2 +INSIGHT_SUPPORT_DIRS= $(GDB_SUPPORT_DIRS) tcl tk itcl tix libgui +insight.tar.bz2: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-taz TOOL=gdb PACKAGE=insight \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(INSIGHT_SUPPORT_DIRS)" +.PHONY: insight.tar +insight.tar: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-tar TOOL=gdb PACKAGE=insight \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(INSIGHT_SUPPORT_DIRS)" + +.PHONY: insight+dejagnu.tar.bz2 +INSIGHTD_SUPPORT_DIRS= $(INSIGHT_SUPPORT_DIRS) expect dejagnu +insight+dejagnu.tar.bz2: $(DIST_SUPPORT) $(INSIGHTD_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-taz TOOL=gdb PACKAGE="insight+dejagnu" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(INSIGHTD_SUPPORT_DIRS)" +.PHONY: insight+dejagnu.tar +insight+dejagnu.tar: $(DIST_SUPPORT) $(INSIGHTD_SUPPORT_DIRS) gdb + $(MAKE) -f $(SELF) gdb-tar TOOL=gdb PACKAGE="insight+dejagnu" \ + MD5PROG="$(MD5PROG)" \ + SUPPORT_FILES="$(INSIGHTD_SUPPORT_DIRS)" + +.NOEXPORT: +MAKEOVERRIDES= diff --git a/contrib/gdb/symlink-tree b/contrib/gdb/symlink-tree new file mode 100755 index 00000000000..22132c76afd --- /dev/null +++ b/contrib/gdb/symlink-tree @@ -0,0 +1,78 @@ +#!/bin/sh +# Create a symlink tree. +# +# Copyright (C) 1995, 2000, 2003 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Please report bugs to +# and send patches to . + +# Syntax: symlink-tree srcdir "ignore1 ignore2 ..." +# +# where srcdir is the directory to create a symlink tree to, +# and "ignoreN" is a list of files/directories to ignore. + +prog=$0 +srcdir=$1 +ignore="$2" + +if test $# -lt 1; then + echo "symlink-tree error: Usage: symlink-tree srcdir \"ignore1 ignore2 ...\"" + exit 1 +fi + +ignore_additional=". .. CVS" + +# If we were invoked with a relative path name, adjust ${prog} to work +# in subdirs. +case ${prog} in +/* | [A-Za-z]:[\\/]*) ;; +*) prog=../${prog} ;; +esac + +# Set newsrcdir to something subdirectories can use. +case ${srcdir} in +/* | [A-Za-z]:[\\/]*) newsrcdir=${srcdir} ;; +*) newsrcdir=../${srcdir} ;; +esac + +for f in `ls -a ${srcdir}`; do + if [ -d ${srcdir}/$f ]; then + found= + for i in ${ignore} ${ignore_additional}; do + if [ "$f" = "$i" ]; then + found=yes + fi + done + if [ -z "${found}" ]; then + echo "$f ..working in" + if [ -d $f ]; then true; else mkdir $f; fi + (cd $f; ${prog} ${newsrcdir}/$f "${ignore}") + fi + else + echo "$f ..linked" + rm -f $f + ln -s ${srcdir}/$f . + fi +done + +exit 0 diff --git a/contrib/gdb/ylwrap b/contrib/gdb/ylwrap new file mode 100755 index 00000000000..2288ccde3ac --- /dev/null +++ b/contrib/gdb/ylwrap @@ -0,0 +1,123 @@ +#! /bin/sh +# ylwrap - wrapper for lex/yacc invocations. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Usage: +# ylwrap PROGRAM INPUT [OUTPUT DESIRED]... -- [ARGS]... +# * PROGRAM is program to run. +# * INPUT is the input file +# * OUTPUT is file PROG generates +# * DESIRED is file we actually want +# * ARGS are passed to PROG +# Any number of OUTPUT,DESIRED pairs may be used. + +# The program to run. +prog="$1" +shift +# Make any relative path in $prog absolute. +case "$prog" in + /* | [A-Za-z]:\\*) ;; + */*) prog="`pwd`/$prog" ;; +esac + +# The input. +input="$1" +shift +case "$input" in + /* | [A-Za-z]:\\*) + # Absolute path; do nothing. + ;; + *) + # Relative path. Make it absolute. Why? Because otherwise any + # debugging info in the generated file will point to the wrong + # place. This is really gross. + input="`pwd`/$input" + ;; +esac + +# We don't want to use the absolute path if the input in the current +# directory like when making a tar ball. +input_base=`echo $input | sed -e 's|.*/||'` +if test -f $input_base && cmp $input_base $input >/dev/null 2>&1; then + input=$input_base +fi + +pairlist= +while test "$#" -ne 0; do + if test "$1" = "--"; then + shift + break + fi + pairlist="$pairlist $1" + shift +done + +# FIXME: add hostname here for parallel makes that run commands on +# other machines. But that might take us over the 14-char limit. +dirname=ylwrap$$ +trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15 +mkdir $dirname || exit 1 + +cd $dirname +case "$input" in + /* | [A-Za-z]:\\*) + # Absolute path; do nothing. + ;; + *) + # Make a symbolic link, hard link or hardcopy. + ln -s ../"$input" . > /dev/null 2>&1 || ln ../"$input" . > /dev/null 2>&1 || cp ../"$input" . + ;; +esac +$prog ${1+"$@"} "$input" +status=$? + +if test $status -eq 0; then + set X $pairlist + shift + first=yes + while test "$#" -ne 0; do + if test -f "$1"; then + # If $2 is an absolute path name, then just use that, + # otherwise prepend `../'. + case "$2" in + /* | [A-Za-z]:\\*) target="$2";; + *) target="../$2";; + esac + mv "$1" "$target" || status=$? + else + # A missing file is only an error for the first file. This + # is a blatant hack to let us support using "yacc -d". If -d + # is not specified, we don't want an error when the header + # file is "missing". + if test $first = yes; then + status=1 + fi + fi + shift + shift + first=no + done +else + status=$? +fi + +# Remove the directory. +cd .. +rm -rf $dirname + +exit $status